summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-09-20 13:18:24 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-09-20 13:18:24 +0000
commit0653e08efd039a5905f3fa4f6e9cef9f5d2f799c (patch)
tree4dcc884cf6d81db44adae4aa99f8ec1233a41f55
parent744144d28e3e7fddc117924fef88de5d9674fe4c (diff)
downloadgitlab-ce-14.3.0-rc42.tar.gz
Add latest changes from gitlab-org/gitlab@14-3-stable-eev14.3.0-rc42
-rw-r--r--.codeclimate.yml1
-rw-r--r--.eslintignore1
-rw-r--r--.gitignore2
-rw-r--r--.gitlab-ci.yml2
-rw-r--r--.gitlab/CODEOWNERS30
-rw-r--r--.gitlab/changelog_config.yml4
-rw-r--r--.gitlab/ci/docs.gitlab-ci.yml16
-rw-r--r--.gitlab/ci/frontend.gitlab-ci.yml71
-rw-r--r--.gitlab/ci/global.gitlab-ci.yml12
-rw-r--r--.gitlab/ci/pages.gitlab-ci.yml2
-rw-r--r--.gitlab/ci/qa.gitlab-ci.yml1
-rw-r--r--.gitlab/ci/rails.gitlab-ci.yml143
-rw-r--r--.gitlab/ci/reports.gitlab-ci.yml5
-rw-r--r--.gitlab/ci/review.gitlab-ci.yml2
-rw-r--r--.gitlab/ci/rules.gitlab-ci.yml105
-rw-r--r--.gitlab/ci/setup.gitlab-ci.yml11
-rw-r--r--.gitlab/ci/static-analysis.gitlab-ci.yml42
-rw-r--r--.gitlab/ci/test-metadata.gitlab-ci.yml1
-rw-r--r--.gitlab/ci/workhorse.gitlab-ci.yml8
-rw-r--r--.gitlab/ci/yaml.gitlab-ci.yml4
-rw-r--r--.gitlab/issue_templates/Actionable Insight.md6
-rw-r--r--.gitlab/issue_templates/Experiment Rollout.md109
-rw-r--r--.gitlab/issue_templates/Feature Flag Roll Out.md17
-rw-r--r--.gitlab/issue_templates/Feature proposal - detailed.md2
-rw-r--r--.gitlab/issue_templates/Geo Replicate a new Git repository type.md2
-rw-r--r--.gitlab/issue_templates/Geo Replicate a new blob type.md2
-rw-r--r--.gitlab/issue_templates/InfraDev.md56
-rw-r--r--.gitlab/issue_templates/Navigation - Left Sidebar Proposals.md15
-rw-r--r--.gitlab/issue_templates/Security developer workflow.md1
-rw-r--r--.gitlab/issue_templates/Technical Evaluation.md7
-rw-r--r--.gitlab/issue_templates/experiment_tracking_template.md95
-rw-r--r--.gitlab/merge_request_templates/Documentation.md16
-rw-r--r--.gitlab/merge_request_templates/Quarantine End to End Test.md4
-rw-r--r--.gitlab/merge_request_templates/Security Release.md2
-rw-r--r--.gitpod.yml4
-rw-r--r--.rubocop.yml15
-rw-r--r--.rubocop_manual_todo.yml302
-rw-r--r--.rubocop_todo.yml1
-rw-r--r--.ruby-version2
-rw-r--r--CHANGELOG.md55
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--GITLAB_KAS_VERSION2
-rw-r--r--GITLAB_PAGES_VERSION2
-rw-r--r--GITLAB_SHELL_VERSION2
-rw-r--r--Gemfile16
-rw-r--r--Gemfile.lock49
-rw-r--r--README.md2
-rw-r--r--app/assets/images/learn_gitlab/code_owners_enabled.svg5
-rw-r--r--app/assets/images/learn_gitlab/git_write.svg16
-rw-r--r--app/assets/images/learn_gitlab/issue_created.svg65
-rw-r--r--app/assets/images/learn_gitlab/merge_request_created.svg107
-rw-r--r--app/assets/images/learn_gitlab/pipeline_created.svg38
-rw-r--r--app/assets/images/learn_gitlab/required_mr_approvals_enabled.svg70
-rw-r--r--app/assets/images/learn_gitlab/security_scan_enabled.svg36
-rw-r--r--app/assets/images/learn_gitlab/trial_started.svg9
-rw-r--r--app/assets/images/learn_gitlab/user_added.svg4
-rw-r--r--app/assets/javascripts/alert_management/list.js1
-rw-r--r--app/assets/javascripts/analytics/shared/utils.js5
-rw-r--r--app/assets/javascripts/analytics/usage_trends/index.js2
-rw-r--r--app/assets/javascripts/api.js8
-rw-r--r--app/assets/javascripts/api/projects_api.js8
-rw-r--r--app/assets/javascripts/authentication/two_factor_auth/components/recovery_codes.vue2
-rw-r--r--app/assets/javascripts/autosave.js2
-rw-r--r--app/assets/javascripts/badges/components/badge_form.vue11
-rw-r--r--app/assets/javascripts/batch_comments/components/draft_note.vue3
-rw-r--r--app/assets/javascripts/batch_comments/components/review_bar.vue10
-rw-r--r--app/assets/javascripts/batch_comments/constants.js2
-rw-r--r--app/assets/javascripts/batch_comments/index.js13
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/playable.js40
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/keybindings.js2
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.vue2
-rw-r--r--app/assets/javascripts/blob/blob_file_dropzone.js1
-rw-r--r--app/assets/javascripts/blob/notebook/index.js3
-rw-r--r--app/assets/javascripts/blob/notebook/notebook_viewer.vue6
-rw-r--r--app/assets/javascripts/blob/pipeline_tour_success_modal.vue4
-rw-r--r--app/assets/javascripts/blob/suggest_gitlab_ci_yml/components/popover.vue2
-rw-r--r--app/assets/javascripts/boards/boards_util.js12
-rw-r--r--app/assets/javascripts/boards/components/board_add_new_column.vue32
-rw-r--r--app/assets/javascripts/boards/components/board_app.vue29
-rw-r--r--app/assets/javascripts/boards/components/board_card_deprecated.vue61
-rw-r--r--app/assets/javascripts/boards/components/board_card_inner.vue9
-rw-r--r--app/assets/javascripts/boards/components/board_card_layout_deprecated.vue101
-rw-r--r--app/assets/javascripts/boards/components/board_column_deprecated.vue112
-rw-r--r--app/assets/javascripts/boards/components/board_content.vue31
-rw-r--r--app/assets/javascripts/boards/components/board_content_sidebar.vue2
-rw-r--r--app/assets/javascripts/boards/components/board_form.vue19
-rw-r--r--app/assets/javascripts/boards/components/board_list.vue4
-rw-r--r--app/assets/javascripts/boards/components/board_list_deprecated.vue459
-rw-r--r--app/assets/javascripts/boards/components/board_list_header.vue2
-rw-r--r--app/assets/javascripts/boards/components/board_list_header_deprecated.vue361
-rw-r--r--app/assets/javascripts/boards/components/board_new_issue_deprecated.vue138
-rw-r--r--app/assets/javascripts/boards/components/board_settings_sidebar.vue53
-rw-r--r--app/assets/javascripts/boards/components/board_sidebar.js115
-rw-r--r--app/assets/javascripts/boards/components/boards_selector_deprecated.vue360
-rw-r--r--app/assets/javascripts/boards/components/config_toggle.vue8
-rw-r--r--app/assets/javascripts/boards/components/issue_board_filtered_search.vue47
-rw-r--r--app/assets/javascripts/boards/components/issue_card_inner_deprecated.vue247
-rw-r--r--app/assets/javascripts/boards/components/issue_time_estimate_deprecated.vue48
-rw-r--r--app/assets/javascripts/boards/components/new_list_dropdown.js119
-rw-r--r--app/assets/javascripts/boards/components/project_select_deprecated.vue146
-rw-r--r--app/assets/javascripts/boards/config_toggle.js3
-rw-r--r--app/assets/javascripts/boards/constants.js5
-rw-r--r--app/assets/javascripts/boards/ee_functions.js4
-rw-r--r--app/assets/javascripts/boards/filtered_search_boards.js15
-rw-r--r--app/assets/javascripts/boards/graphql/group_board_iterations.query.graphql10
-rw-r--r--app/assets/javascripts/boards/graphql/issue.fragment.graphql1
-rw-r--r--app/assets/javascripts/boards/graphql/project_board_iterations.query.graphql10
-rw-r--r--app/assets/javascripts/boards/graphql/project_milestones.query.graphql2
-rw-r--r--app/assets/javascripts/boards/index.js344
-rw-r--r--app/assets/javascripts/boards/models/assignee.js13
-rw-r--r--app/assets/javascripts/boards/models/issue.js99
-rw-r--r--app/assets/javascripts/boards/models/iteration.js9
-rw-r--r--app/assets/javascripts/boards/models/label.js11
-rw-r--r--app/assets/javascripts/boards/models/list.js182
-rw-r--r--app/assets/javascripts/boards/models/milestone.js15
-rw-r--r--app/assets/javascripts/boards/models/project.js7
-rw-r--r--app/assets/javascripts/boards/mount_multiple_boards_switcher.js15
-rw-r--r--app/assets/javascripts/boards/stores/actions.js74
-rw-r--r--app/assets/javascripts/boards/stores/boards_store.js883
-rw-r--r--app/assets/javascripts/boards/stores/boards_store_ee.js5
-rw-r--r--app/assets/javascripts/boards/stores/getters.js6
-rw-r--r--app/assets/javascripts/boards/stores/mutation_types.js4
-rw-r--r--app/assets/javascripts/boards/stores/mutations.js18
-rw-r--r--app/assets/javascripts/boards/stores/state.js2
-rw-r--r--app/assets/javascripts/captcha/init_recaptcha_script.js2
-rw-r--r--app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue2
-rw-r--r--app/assets/javascripts/ci_variable_list/constants.js2
-rw-r--r--app/assets/javascripts/clusters/clusters_bundle.js8
-rw-r--r--app/assets/javascripts/clusters/components/remove_cluster_confirmation.vue3
-rw-r--r--app/assets/javascripts/clusters_list/components/clusters.vue2
-rw-r--r--app/assets/javascripts/commit/image_file.js7
-rw-r--r--app/assets/javascripts/commit/pipelines/pipelines_bundle.js9
-rw-r--r--app/assets/javascripts/commit/pipelines/utils.js11
-rw-r--r--app/assets/javascripts/confidential_merge_request/components/project_form_group.vue37
-rw-r--r--app/assets/javascripts/content_editor/components/content_editor.vue6
-rw-r--r--app/assets/javascripts/content_editor/components/formatting_bubble_menu.vue6
-rw-r--r--app/assets/javascripts/content_editor/components/wrappers/image.vue1
-rw-r--r--app/assets/javascripts/content_editor/components/wrappers/table_cell_base.vue142
-rw-r--r--app/assets/javascripts/content_editor/components/wrappers/table_cell_body.vue23
-rw-r--r--app/assets/javascripts/content_editor/components/wrappers/table_cell_header.vue23
-rw-r--r--app/assets/javascripts/content_editor/constants.js4
-rw-r--r--app/assets/javascripts/content_editor/content_editor.stories.js27
-rw-r--r--app/assets/javascripts/content_editor/extensions/audio.js9
-rw-r--r--app/assets/javascripts/content_editor/extensions/blockquote.js34
-rw-r--r--app/assets/javascripts/content_editor/extensions/bullet_list.js20
-rw-r--r--app/assets/javascripts/content_editor/extensions/code_block_highlight.js6
-rw-r--r--app/assets/javascripts/content_editor/extensions/description_item.js49
-rw-r--r--app/assets/javascripts/content_editor/extensions/description_list.js23
-rw-r--r--app/assets/javascripts/content_editor/extensions/division.js17
-rw-r--r--app/assets/javascripts/content_editor/extensions/emoji.js18
-rw-r--r--app/assets/javascripts/content_editor/extensions/figure.js16
-rw-r--r--app/assets/javascripts/content_editor/extensions/figure_caption.js16
-rw-r--r--app/assets/javascripts/content_editor/extensions/html_marks.js66
-rw-r--r--app/assets/javascripts/content_editor/extensions/image.js23
-rw-r--r--app/assets/javascripts/content_editor/extensions/inline_diff.js6
-rw-r--r--app/assets/javascripts/content_editor/extensions/link.js16
-rw-r--r--app/assets/javascripts/content_editor/extensions/ordered_list.js16
-rw-r--r--app/assets/javascripts/content_editor/extensions/playable.js66
-rw-r--r--app/assets/javascripts/content_editor/extensions/reference.js41
-rw-r--r--app/assets/javascripts/content_editor/extensions/subscript.js10
-rw-r--r--app/assets/javascripts/content_editor/extensions/superscript.js10
-rw-r--r--app/assets/javascripts/content_editor/extensions/table_cell.js9
-rw-r--r--app/assets/javascripts/content_editor/extensions/table_header.js8
-rw-r--r--app/assets/javascripts/content_editor/extensions/task_item.js6
-rw-r--r--app/assets/javascripts/content_editor/extensions/task_list.js28
-rw-r--r--app/assets/javascripts/content_editor/extensions/video.js10
-rw-r--r--app/assets/javascripts/content_editor/services/create_content_editor.js16
-rw-r--r--app/assets/javascripts/content_editor/services/feature_flags.js3
-rw-r--r--app/assets/javascripts/content_editor/services/mark_utils.js17
-rw-r--r--app/assets/javascripts/content_editor/services/markdown_serializer.js163
-rw-r--r--app/assets/javascripts/content_editor/services/markdown_sourcemap.js40
-rw-r--r--app/assets/javascripts/content_editor/services/serialization_helpers.js345
-rw-r--r--app/assets/javascripts/create_cluster/eks_cluster/components/service_credentials_form.vue74
-rw-r--r--app/assets/javascripts/create_cluster/eks_cluster/constants.js4
-rw-r--r--app/assets/javascripts/cycle_analytics/components/banner.vue54
-rw-r--r--app/assets/javascripts/cycle_analytics/components/base.vue57
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_table.vue13
-rw-r--r--app/assets/javascripts/cycle_analytics/components/value_stream_filters.vue47
-rw-r--r--app/assets/javascripts/cycle_analytics/index.js14
-rw-r--r--app/assets/javascripts/cycle_analytics/store/actions.js15
-rw-r--r--app/assets/javascripts/cycle_analytics/store/getters.js17
-rw-r--r--app/assets/javascripts/cycle_analytics/store/mutations.js18
-rw-r--r--app/assets/javascripts/cycle_analytics/store/state.js3
-rw-r--r--app/assets/javascripts/deploy_freeze/components/deploy_freeze_table.vue63
-rw-r--r--app/assets/javascripts/deploy_freeze/store/actions.js16
-rw-r--r--app/assets/javascripts/deploy_freeze/store/mutation_types.js4
-rw-r--r--app/assets/javascripts/deploy_freeze/store/mutations.js33
-rw-r--r--app/assets/javascripts/deprecated_jquery_dropdown/render.js2
-rw-r--r--app/assets/javascripts/deprecated_notes.js1746
-rw-r--r--app/assets/javascripts/design_management/components/design_notes/design_reply_form.vue2
-rw-r--r--app/assets/javascripts/design_management/components/design_scaler.vue18
-rw-r--r--app/assets/javascripts/design_management/components/design_sidebar.vue2
-rw-r--r--app/assets/javascripts/design_management/components/image.vue22
-rw-r--r--app/assets/javascripts/design_management/graphql/fragments/version.fragment.graphql7
-rw-r--r--app/assets/javascripts/design_management/graphql/mutations/upload_design.mutation.graphql6
-rw-r--r--app/assets/javascripts/design_management/pages/design/index.vue12
-rw-r--r--app/assets/javascripts/design_management/pages/index.vue3
-rw-r--r--app/assets/javascripts/design_management/utils/design_management_utils.js7
-rw-r--r--app/assets/javascripts/design_management/utils/error_messages.js1
-rw-r--r--app/assets/javascripts/diffs/components/app.vue113
-rw-r--r--app/assets/javascripts/diffs/components/commit_item.vue10
-rw-r--r--app/assets/javascripts/diffs/components/diff_file.vue5
-rw-r--r--app/assets/javascripts/diffs/components/diff_file_header.vue4
-rw-r--r--app/assets/javascripts/diffs/components/diff_row.vue5
-rw-r--r--app/assets/javascripts/diffs/components/diff_view.vue5
-rw-r--r--app/assets/javascripts/diffs/components/pre_renderer.vue1
-rw-r--r--app/assets/javascripts/diffs/constants.js5
-rw-r--r--app/assets/javascripts/diffs/index.js96
-rw-r--r--app/assets/javascripts/diffs/store/actions.js22
-rw-r--r--app/assets/javascripts/diffs/store/getters.js3
-rw-r--r--app/assets/javascripts/diffs/store/modules/diff_state.js6
-rw-r--r--app/assets/javascripts/diffs/store/mutation_types.js2
-rw-r--r--app/assets/javascripts/diffs/store/mutations.js4
-rw-r--r--app/assets/javascripts/diffs/utils/preferences.js13
-rw-r--r--app/assets/javascripts/dropzone_input.js8
-rw-r--r--app/assets/javascripts/due_date_select.js191
-rw-r--r--app/assets/javascripts/emoji/index.js5
-rw-r--r--app/assets/javascripts/emoji/support/unicode_support_map.js2
-rw-r--r--app/assets/javascripts/environments/components/container.vue6
-rw-r--r--app/assets/javascripts/environments/components/edit_environment.vue2
-rw-r--r--app/assets/javascripts/environments/components/environment_form.vue15
-rw-r--r--app/assets/javascripts/environments/components/environment_item.vue50
-rw-r--r--app/assets/javascripts/environments/components/environments_app.vue41
-rw-r--r--app/assets/javascripts/environments/components/environments_detail_header.vue8
-rw-r--r--app/assets/javascripts/environments/components/environments_table.vue7
-rw-r--r--app/assets/javascripts/environments/constants.js2
-rw-r--r--app/assets/javascripts/environments/folder/environments_folder_bundle.js3
-rw-r--r--app/assets/javascripts/environments/folder/environments_folder_view.vue5
-rw-r--r--app/assets/javascripts/environments/index.js4
-rw-r--r--app/assets/javascripts/environments/mount_show.js1
-rw-r--r--app/assets/javascripts/error_tracking/components/error_tracking_list.vue2
-rw-r--r--app/assets/javascripts/error_tracking/components/stacktrace_entry.vue3
-rw-r--r--app/assets/javascripts/error_tracking/store/list/mutations.js4
-rw-r--r--app/assets/javascripts/error_tracking_settings/components/app.vue79
-rw-r--r--app/assets/javascripts/error_tracking_settings/index.js11
-rw-r--r--app/assets/javascripts/error_tracking_settings/store/actions.js4
-rw-r--r--app/assets/javascripts/error_tracking_settings/store/mutation_types.js1
-rw-r--r--app/assets/javascripts/error_tracking_settings/store/mutations.js14
-rw-r--r--app/assets/javascripts/error_tracking_settings/store/state.js1
-rw-r--r--app/assets/javascripts/error_tracking_settings/utils.js10
-rw-r--r--app/assets/javascripts/experimentation/utils.js25
-rw-r--r--app/assets/javascripts/feature_flags/components/edit_feature_flag.vue2
-rw-r--r--app/assets/javascripts/feature_flags/components/feature_flags_table.vue2
-rw-r--r--app/assets/javascripts/filtered_search/services/recent_searches_service.js2
-rw-r--r--app/assets/javascripts/frequent_items/components/app.vue2
-rw-r--r--app/assets/javascripts/frequent_items/components/frequent_items_list_item.vue4
-rw-r--r--app/assets/javascripts/frequent_items/store/actions.js2
-rw-r--r--app/assets/javascripts/graphql_shared/constants.js4
-rw-r--r--app/assets/javascripts/groups/components/app.vue2
-rw-r--r--app/assets/javascripts/groups/components/groups.vue8
-rw-r--r--app/assets/javascripts/groups/components/invite_members_banner.vue18
-rw-r--r--app/assets/javascripts/groups/components/item_stats.vue11
-rw-r--r--app/assets/javascripts/groups/init_invite_members_banner.js13
-rw-r--r--app/assets/javascripts/header_search/components/app.vue83
-rw-r--r--app/assets/javascripts/header_search/components/header_search_default_items.vue42
-rw-r--r--app/assets/javascripts/header_search/components/header_search_scoped_items.vue31
-rw-r--r--app/assets/javascripts/header_search/constants.js17
-rw-r--r--app/assets/javascripts/header_search/index.js26
-rw-r--r--app/assets/javascripts/header_search/store/actions.js5
-rw-r--r--app/assets/javascripts/header_search/store/getters.js135
-rw-r--r--app/assets/javascripts/header_search/store/index.js18
-rw-r--r--app/assets/javascripts/header_search/store/mutation_types.js1
-rw-r--r--app/assets/javascripts/header_search/store/mutations.js7
-rw-r--r--app/assets/javascripts/header_search/store/state.js8
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/success_message.vue3
-rw-r--r--app/assets/javascripts/ide/components/error_message.vue8
-rw-r--r--app/assets/javascripts/ide/components/jobs/detail.vue3
-rw-r--r--app/assets/javascripts/ide/services/terminals.js4
-rw-r--r--app/assets/javascripts/ide/utils.js5
-rw-r--r--app/assets/javascripts/import_entities/import_groups/components/import_actions_cell.vue69
-rw-r--r--app/assets/javascripts/import_entities/import_groups/components/import_source_cell.vue53
-rw-r--r--app/assets/javascripts/import_entities/import_groups/components/import_table.vue76
-rw-r--r--app/assets/javascripts/import_entities/import_groups/components/import_target_cell.vue57
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/client_factory.js89
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/fragments/bulk_import_source_group_item.fragment.graphql4
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/mutations/set_import_progress.mutation.graphql18
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/services/source_groups_manager.js24
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/typedefs.graphql13
-rw-r--r--app/assets/javascripts/import_entities/import_groups/utils.js9
-rw-r--r--app/assets/javascripts/import_entities/import_projects/components/import_projects_table.vue4
-rw-r--r--app/assets/javascripts/import_entities/import_projects/store/actions.js4
-rw-r--r--app/assets/javascripts/import_entities/import_projects/store/mutations.js17
-rw-r--r--app/assets/javascripts/incidents/list.js2
-rw-r--r--app/assets/javascripts/init_changes_dropdown.js12
-rw-r--r--app/assets/javascripts/init_deprecated_notes.js10
-rw-r--r--app/assets/javascripts/init_diff_stats_dropdown.js30
-rw-r--r--app/assets/javascripts/init_issuable_sidebar.js10
-rw-r--r--app/assets/javascripts/init_notes.js10
-rw-r--r--app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue4
-rw-r--r--app/assets/javascripts/invite_members/components/import_a_project_modal.vue157
-rw-r--r--app/assets/javascripts/invite_members/components/invite_members_trigger.vue2
-rw-r--r--app/assets/javascripts/invite_members/components/project_select.vue143
-rw-r--r--app/assets/javascripts/invite_members/init_import_a_project_modal.js23
-rw-r--r--app/assets/javascripts/issuable/components/csv_export_modal.vue4
-rw-r--r--app/assets/javascripts/issuable_list/components/issuable_item.vue9
-rw-r--r--app/assets/javascripts/issue_show/components/app.vue19
-rw-r--r--app/assets/javascripts/issue_show/components/description.vue3
-rw-r--r--app/assets/javascripts/issue_show/components/locked_warning.vue6
-rw-r--r--app/assets/javascripts/issues_list/components/issuable.vue2
-rw-r--r--app/assets/javascripts/issues_list/components/issues_list_app.vue131
-rw-r--r--app/assets/javascripts/issues_list/constants.js22
-rw-r--r--app/assets/javascripts/issues_list/index.js22
-rw-r--r--app/assets/javascripts/issues_list/queries/get_issues.query.graphql35
-rw-r--r--app/assets/javascripts/issues_list/queries/get_issues_count.query.graphql30
-rw-r--r--app/assets/javascripts/issues_list/queries/get_issues_counts.query.graphql105
-rw-r--r--app/assets/javascripts/issues_list/queries/issue.fragment.graphql1
-rw-r--r--app/assets/javascripts/issues_list/queries/iteration.fragment.graphql4
-rw-r--r--app/assets/javascripts/issues_list/queries/label.fragment.graphql6
-rw-r--r--app/assets/javascripts/issues_list/queries/milestone.fragment.graphql4
-rw-r--r--app/assets/javascripts/issues_list/queries/reorder_issues.mutation.graphql8
-rw-r--r--app/assets/javascripts/issues_list/queries/search_iterations.query.graphql18
-rw-r--r--app/assets/javascripts/issues_list/queries/search_labels.query.graphql18
-rw-r--r--app/assets/javascripts/issues_list/queries/search_milestones.query.graphql16
-rw-r--r--app/assets/javascripts/issues_list/queries/search_users.query.graphql20
-rw-r--r--app/assets/javascripts/issues_list/queries/user.fragment.graphql6
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/utils.js4
-rw-r--r--app/assets/javascripts/jobs/components/job_app.vue8
-rw-r--r--app/assets/javascripts/jobs/components/table/cells/actions_cell.vue183
-rw-r--r--app/assets/javascripts/jobs/components/table/constants.js23
-rw-r--r--app/assets/javascripts/jobs/components/table/event_hub.js3
-rw-r--r--app/assets/javascripts/jobs/components/table/graphql/fragments/job.fragment.graphql3
-rw-r--r--app/assets/javascripts/jobs/components/table/graphql/mutations/job_cancel.mutation.graphql10
-rw-r--r--app/assets/javascripts/jobs/components/table/graphql/mutations/job_play.mutation.graphql10
-rw-r--r--app/assets/javascripts/jobs/components/table/graphql/mutations/job_retry.mutation.graphql10
-rw-r--r--app/assets/javascripts/jobs/components/table/graphql/mutations/job_unschedule.mutation.graphql10
-rw-r--r--app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs.query.graphql1
-rw-r--r--app/assets/javascripts/jobs/components/table/index.js5
-rw-r--r--app/assets/javascripts/jobs/components/table/jobs_table.vue2
-rw-r--r--app/assets/javascripts/jobs/components/table/jobs_table_app.vue10
-rw-r--r--app/assets/javascripts/labels_select.js52
-rw-r--r--app/assets/javascripts/learn_gitlab/track_learn_gitlab.js10
-rw-r--r--app/assets/javascripts/lib/apollo/instrumentation_link.js29
-rw-r--r--app/assets/javascripts/lib/dompurify.js6
-rw-r--r--app/assets/javascripts/lib/graphql.js20
-rw-r--r--app/assets/javascripts/lib/logger/hello.js16
-rw-r--r--app/assets/javascripts/lib/logger/hello_deferred.js5
-rw-r--r--app/assets/javascripts/lib/logger/index.js6
-rw-r--r--app/assets/javascripts/lib/utils/accessor.js28
-rw-r--r--app/assets/javascripts/lib/utils/common_utils.js11
-rw-r--r--app/assets/javascripts/lib/utils/datetime/date_format_utility.js105
-rw-r--r--app/assets/javascripts/lib/utils/dom_utils.js12
-rw-r--r--app/assets/javascripts/lib/utils/number_utils.js9
-rw-r--r--app/assets/javascripts/lib/utils/text_markdown.js4
-rw-r--r--app/assets/javascripts/lib/utils/url_utility.js37
-rw-r--r--app/assets/javascripts/main.js37
-rw-r--r--app/assets/javascripts/main_jh.js1
-rw-r--r--app/assets/javascripts/merge_request.js29
-rw-r--r--app/assets/javascripts/merge_request_tabs.js71
-rw-r--r--app/assets/javascripts/milestone_select.js118
-rw-r--r--app/assets/javascripts/milestones/components/milestone_combobox.vue3
-rw-r--r--app/assets/javascripts/milestones/stores/mutations.js4
-rw-r--r--app/assets/javascripts/monitoring/components/charts/empty_chart.vue3
-rw-r--r--app/assets/javascripts/mr_notes/index.js36
-rw-r--r--app/assets/javascripts/notebook/cells/markdown.vue16
-rw-r--r--app/assets/javascripts/notebook/cells/output/html.vue9
-rw-r--r--app/assets/javascripts/notes.js1744
-rw-r--r--app/assets/javascripts/notes/components/comment_form.vue85
-rw-r--r--app/assets/javascripts/notes/components/comment_type_dropdown.vue114
-rw-r--r--app/assets/javascripts/notes/components/diff_with_note.vue7
-rw-r--r--app/assets/javascripts/notes/components/discussion_counter.vue6
-rw-r--r--app/assets/javascripts/notes/components/discussion_resolve_with_issue_button.vue2
-rw-r--r--app/assets/javascripts/notes/components/note_actions/reply_button.vue2
-rw-r--r--app/assets/javascripts/notes/components/note_body.vue7
-rw-r--r--app/assets/javascripts/notes/components/note_form.vue3
-rw-r--r--app/assets/javascripts/notes/components/note_header.vue3
-rw-r--r--app/assets/javascripts/notes/stores/actions.js1
-rw-r--r--app/assets/javascripts/packages/details/components/package_history.vue1
-rw-r--r--app/assets/javascripts/packages/shared/constants.js1
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/additional_metadata.vue105
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/metadata/composer.vue55
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/metadata/conan.vue32
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/metadata/maven.vue42
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/metadata/nuget.vue46
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/metadata/pypi.vue34
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/package_history.vue1
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue17
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/list/package_search.vue57
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/list/package_title.vue47
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/list/packages_list.vue129
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/list/packages_list_app.vue132
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/list/tokens/package_type_token.vue26
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/constants.js1
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/pages/list.js16
-rw-r--r--app/assets/javascripts/packages_and_registries/settings/project/components/registry_settings_app.vue2
-rw-r--r--app/assets/javascripts/pages/dashboard/projects/index/components/customize_homepage_banner.vue2
-rw-r--r--app/assets/javascripts/pages/groups/issues/index.js34
-rw-r--r--app/assets/javascripts/pages/groups/new/index.js3
-rw-r--r--app/assets/javascripts/pages/groups/new/toggle_invite_members.js14
-rw-r--r--app/assets/javascripts/pages/projects/blob/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/commit/show/index.js8
-rw-r--r--app/assets/javascripts/pages/projects/compare/show/index.js4
-rw-r--r--app/assets/javascripts/pages/projects/issues/show.js2
-rw-r--r--app/assets/javascripts/pages/projects/issues/show/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue (renamed from app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_a.vue)0
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_b.vue116
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_link.vue2
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/index/index.js10
-rw-r--r--app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js13
-rw-r--r--app/assets/javascripts/pages/projects/merge_requests/show/index.js11
-rw-r--r--app/assets/javascripts/pages/projects/new/components/new_project_url_select.vue98
-rw-r--r--app/assets/javascripts/pages/projects/new/index.js40
-rw-r--r--app/assets/javascripts/pages/projects/new/queries/search_namespaces_where_user_can_create_projects.query.graphql14
-rw-r--r--app/assets/javascripts/pages/projects/packages/packages/show/index.js14
-rw-r--r--app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue4
-rw-r--r--app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/pipeline_schedules_callout.vue2
-rw-r--r--app/assets/javascripts/pages/projects/project_members/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/usage_quotas/index.js23
-rw-r--r--app/assets/javascripts/pages/projects/wikis/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/work_items/index/index.js3
-rw-r--r--app/assets/javascripts/pages/sessions/new/signin_tabs_memoizer.js2
-rw-r--r--app/assets/javascripts/performance_bar/components/performance_bar_app.vue8
-rw-r--r--app/assets/javascripts/performance_bar/components/request_selector.vue12
-rw-r--r--app/assets/javascripts/performance_bar/components/request_warning.vue9
-rw-r--r--app/assets/javascripts/pipeline_editor/components/commit/commit_section.vue18
-rw-r--r--app/assets/javascripts/pipeline_editor/components/editor/text_editor.vue12
-rw-r--r--app/assets/javascripts/pipeline_editor/components/file_nav/branch_switcher.vue4
-rw-r--r--app/assets/javascripts/pipeline_editor/components/file_nav/pipeline_editor_file_nav.vue9
-rw-r--r--app/assets/javascripts/pipeline_editor/components/header/pipeline_editor_header.vue11
-rw-r--r--app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue23
-rw-r--r--app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue7
-rw-r--r--app/assets/javascripts/pipeline_editor/components/ui/pipeline_editor_empty_state.vue5
-rw-r--r--app/assets/javascripts/pipeline_editor/constants.js2
-rw-r--r--app/assets/javascripts/pipeline_editor/graphql/mutations/update_commit_sha.mutation.graphql3
-rw-r--r--app/assets/javascripts/pipeline_editor/graphql/queries/client/commit_sha.graphql3
-rw-r--r--app/assets/javascripts/pipeline_editor/graphql/queries/latest_commit_sha.query.graphql11
-rw-r--r--app/assets/javascripts/pipeline_editor/graphql/resolvers.js9
-rw-r--r--app/assets/javascripts/pipeline_editor/index.js15
-rw-r--r--app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue61
-rw-r--r--app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue14
-rw-r--r--app/assets/javascripts/pipeline_new/components/pipeline_new_form.vue10
-rw-r--r--app/assets/javascripts/pipelines/components/graph/accessors.js25
-rw-r--r--app/assets/javascripts/pipelines/components/graph/constants.js3
-rw-r--r--app/assets/javascripts/pipelines/components/graph/job_group_dropdown.vue8
-rw-r--r--app/assets/javascripts/pipelines/components/graph/job_item.vue20
-rw-r--r--app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue32
-rw-r--r--app/assets/javascripts/pipelines/components/graph/linked_pipelines_column.vue4
-rw-r--r--app/assets/javascripts/pipelines/components/graph/stage_column_component.vue24
-rw-r--r--app/assets/javascripts/pipelines/components/header_component.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/parsing_utils.js78
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipeline_multi_actions.vue3
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipeline_stop_modal.vue3
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipelines_filtered_search.vue13
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue1
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/tokens/constants.js52
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_source_token.vue71
-rw-r--r--app/assets/javascripts/pipelines/pipeline_details_bundle.js60
-rw-r--r--app/assets/javascripts/pipelines/pipeline_details_graph.js2
-rw-r--r--app/assets/javascripts/pipelines/pipeline_test_details.js34
-rw-r--r--app/assets/javascripts/pipelines/utils.js52
-rw-r--r--app/assets/javascripts/popovers/components/popovers.vue21
-rw-r--r--app/assets/javascripts/project_select_combo_button.js2
-rw-r--r--app/assets/javascripts/projects/commit_box/info/components/commit_box_pipeline_mini_graph.vue1
-rw-r--r--app/assets/javascripts/projects/commit_box/info/graphql/queries/get_linked_pipelines.query.graphql1
-rw-r--r--app/assets/javascripts/projects/commit_box/info/init_commit_pipeline_mini_graph.js7
-rw-r--r--app/assets/javascripts/projects/pipelines/charts/components/pipeline_charts.vue12
-rw-r--r--app/assets/javascripts/projects/pipelines/charts/index.js2
-rw-r--r--app/assets/javascripts/projects/project_new.js22
-rw-r--r--app/assets/javascripts/projects/settings/components/shared_runners_toggle.vue5
-rw-r--r--app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue54
-rw-r--r--app/assets/javascripts/projects/storage_counter/components/app.vue106
-rw-r--r--app/assets/javascripts/projects/storage_counter/components/storage_table.vue78
-rw-r--r--app/assets/javascripts/projects/storage_counter/constants.js61
-rw-r--r--app/assets/javascripts/projects/storage_counter/index.js51
-rw-r--r--app/assets/javascripts/projects/storage_counter/queries/project_storage.query.graphql16
-rw-r--r--app/assets/javascripts/projects/storage_counter/utils.js40
-rw-r--r--app/assets/javascripts/projects/terraform_notification/components/terraform_notification.vue53
-rw-r--r--app/assets/javascripts/projects/terraform_notification/constants.js3
-rw-r--r--app/assets/javascripts/projects/terraform_notification/index.js14
-rw-r--r--app/assets/javascripts/prometheus_alerts/components/reset_key.vue3
-rw-r--r--app/assets/javascripts/protected_branches/protected_branch_create.js2
-rw-r--r--app/assets/javascripts/ref/components/ref_selector.vue3
-rw-r--r--app/assets/javascripts/releases/components/release_block.vue6
-rw-r--r--app/assets/javascripts/reports/components/issue_body.js16
-rw-r--r--app/assets/javascripts/reports/components/report_item.vue6
-rw-r--r--app/assets/javascripts/repository/components/blob_content_viewer.vue6
-rw-r--r--app/assets/javascripts/repository/components/blob_viewers/image_viewer.vue19
-rw-r--r--app/assets/javascripts/repository/components/blob_viewers/index.js6
-rw-r--r--app/assets/javascripts/repository/components/last_commit.vue10
-rw-r--r--app/assets/javascripts/repository/components/preview/index.vue7
-rw-r--r--app/assets/javascripts/repository/components/table/index.vue4
-rw-r--r--app/assets/javascripts/repository/components/table/row.vue7
-rw-r--r--app/assets/javascripts/repository/components/tree_content.vue21
-rw-r--r--app/assets/javascripts/repository/constants.js2
-rw-r--r--app/assets/javascripts/repository/mixins/preload.js3
-rw-r--r--app/assets/javascripts/repository/pages/blob.vue15
-rw-r--r--app/assets/javascripts/rest_api.js2
-rw-r--r--app/assets/javascripts/right_sidebar.js7
-rw-r--r--app/assets/javascripts/runner/admin_runners/admin_runners_app.vue32
-rw-r--r--app/assets/javascripts/runner/components/runner_filtered_search_bar.vue88
-rw-r--r--app/assets/javascripts/runner/components/runner_update_form.vue2
-rw-r--r--app/assets/javascripts/runner/components/search_tokens/status_token_config.js32
-rw-r--r--app/assets/javascripts/runner/components/search_tokens/tag_token.vue1
-rw-r--r--app/assets/javascripts/runner/components/search_tokens/tag_token_config.js12
-rw-r--r--app/assets/javascripts/runner/components/search_tokens/type_token_config.js20
-rw-r--r--app/assets/javascripts/runner/constants.js6
-rw-r--r--app/assets/javascripts/runner/graphql/get_group_runners.query.graphql35
-rw-r--r--app/assets/javascripts/runner/group_runners/group_runners_app.vue137
-rw-r--r--app/assets/javascripts/runner/group_runners/index.js11
-rw-r--r--app/assets/javascripts/runner/runner_search_utils.js1
-rw-r--r--app/assets/javascripts/search/highlight_blob_search_result.js2
-rw-r--r--app/assets/javascripts/search/store/actions.js2
-rw-r--r--app/assets/javascripts/search/store/utils.js4
-rw-r--r--app/assets/javascripts/security_configuration/components/constants.js15
-rw-r--r--app/assets/javascripts/sentry/sentry_config.js1
-rw-r--r--app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue8
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/assignee_title.vue2
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue3
-rw-r--r--app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue5
-rw-r--r--app/assets/javascripts/sidebar/components/lock/issuable_lock_form.vue2
-rw-r--r--app/assets/javascripts/sidebar/components/participants/sidebar_participants_widget.vue6
-rw-r--r--app/assets/javascripts/sidebar/components/reviewers/reviewer_title.vue2
-rw-r--r--app/assets/javascripts/sidebar/components/sidebar_dropdown_widget.vue1
-rw-r--r--app/assets/javascripts/sidebar/components/sidebar_editable_item.vue2
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/spent_only_pane.vue3
-rw-r--r--app/assets/javascripts/sidebar/mount_sidebar.js58
-rw-r--r--app/assets/javascripts/sidebar/services/sidebar_service.js5
-rw-r--r--app/assets/javascripts/sidebar/sidebar_bundle.js6
-rw-r--r--app/assets/javascripts/sidebar/sidebar_mediator.js17
-rw-r--r--app/assets/javascripts/sidebar/stores/sidebar_store.js14
-rw-r--r--app/assets/javascripts/sidebar/track_invite_members.js6
-rw-r--r--app/assets/javascripts/snippet/snippet_show.js4
-rw-r--r--app/assets/javascripts/snippets/components/snippet_description_view.vue6
-rw-r--r--app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_identifier_instance_text.js2
-rw-r--r--app/assets/javascripts/tracking/constants.js4
-rw-r--r--app/assets/javascripts/tracking/index.js7
-rw-r--r--app/assets/javascripts/tracking/tracking.js40
-rw-r--r--app/assets/javascripts/tracking/utils.js24
-rw-r--r--app/assets/javascripts/user_popovers.js4
-rw-r--r--app/assets/javascripts/users_select/index.js5
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.vue12
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_suggest_pipeline.vue4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/review_app_link.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/commits_header.vue7
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/merge_checks_failed.vue75
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue3
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/new_ready_to_merge.vue49
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue9
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue21
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/terraform/terraform_plan.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/constants.js2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/index.js7
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js8
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue20
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/queries/states/new_ready_to_merge.query.graphql9
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/get_state_key.js6
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js9
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/state_maps.js2
-rw-r--r--app/assets/javascripts/vue_shared/alert_details/components/system_notes/system_note.vue3
-rw-r--r--app/assets/javascripts/vue_shared/components/awards_list.vue11
-rw-r--r--app/assets/javascripts/vue_shared/components/blob_viewers/simple_viewer.vue5
-rw-r--r--app/assets/javascripts/vue_shared/components/code_block.vue7
-rw-r--r--app/assets/javascripts/vue_shared/components/color_picker/color_picker.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/commit.vue28
-rw-r--r--app/assets/javascripts/vue_shared/components/content_viewer/viewers/markdown_viewer.vue7
-rw-r--r--app/assets/javascripts/vue_shared/components/diff_stats_dropdown.vue159
-rw-r--r--app/assets/javascripts/vue_shared/components/filtered_search_bar/constants.js17
-rw-r--r--app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_utils.js11
-rw-r--r--app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue12
-rw-r--r--app/assets/javascripts/vue_shared/components/header_ci_component.vue21
-rw-r--r--app/assets/javascripts/vue_shared/components/issuable/init_issuable_header_warning.js12
-rw-r--r--app/assets/javascripts/vue_shared/components/issuable/issuable_header_warnings.vue24
-rw-r--r--app/assets/javascripts/vue_shared/components/issue/related_issuable_item.vue7
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/field.vue22
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/suggestion_diff_header.vue3
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/toolbar.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/notes/noteable_warning.vue5
-rw-r--r--app/assets/javascripts/vue_shared/components/notes/system_note.vue7
-rw-r--r--app/assets/javascripts/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs.vue15
-rw-r--r--app/assets/javascripts/vue_shared/components/project_selector/project_list_item.vue3
-rw-r--r--app/assets/javascripts/vue_shared/components/registry/title_area.vue21
-rw-r--r--app/assets/javascripts/vue_shared/components/runner_aws_deployments/runner_aws_deployments_modal.vue8
-rw-r--r--app/assets/javascripts/vue_shared/components/settings/settings_block.stories.js26
-rw-r--r--app/assets/javascripts/vue_shared/components/settings/settings_block.vue84
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_value.vue6
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/label_item.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_button.vue42
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue132
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue29
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue145
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_title.vue40
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_value.vue13
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/graphql/create_label.mutation.graphql2
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/label_item.vue83
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue278
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/actions.js12
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/getters.js52
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/index.js12
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutation_types.js8
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutations.js50
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/state.js28
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/utils.js22
-rw-r--r--app/assets/javascripts/vue_shared/components/storage_counter/usage_graph.stories.js38
-rw-r--r--app/assets/javascripts/vue_shared/components/storage_counter/usage_graph.vue148
-rw-r--r--app/assets/javascripts/vue_shared/components/timezone_dropdown.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/user_popover/user_popover.vue23
-rw-r--r--app/assets/javascripts/vue_shared/security_reports/constants.js1
-rw-r--r--app/assets/javascripts/vue_shared/security_reports/store/modules/sast/state.js2
-rw-r--r--app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/state.js2
-rw-r--r--app/assets/javascripts/webpack_non_compiled_placeholder.js22
-rw-r--r--app/assets/javascripts/whats_new/components/feature.vue6
-rw-r--r--app/assets/javascripts/work_items/components/app.vue9
-rw-r--r--app/assets/javascripts/work_items/graphql/typedefs.graphql0
-rw-r--r--app/assets/javascripts/work_items/index.js13
-rw-r--r--app/assets/stylesheets/application_dark.scss11
-rw-r--r--app/assets/stylesheets/components/content_editor.scss20
-rw-r--r--app/assets/stylesheets/errors.scss1
-rw-r--r--app/assets/stylesheets/framework/blocks.scss8
-rw-r--r--app/assets/stylesheets/framework/diffs.scss43
-rw-r--r--app/assets/stylesheets/framework/filters.scss9
-rw-r--r--app/assets/stylesheets/framework/icons.scss1
-rw-r--r--app/assets/stylesheets/framework/typography.scss21
-rw-r--r--app/assets/stylesheets/framework/variables.scss2
-rw-r--r--app/assets/stylesheets/mailer.scss1
-rw-r--r--app/assets/stylesheets/page_bundles/_pipeline_mixins.scss12
-rw-r--r--app/assets/stylesheets/page_bundles/boards.scss15
-rw-r--r--app/assets/stylesheets/page_bundles/cycle_analytics.scss289
-rw-r--r--app/assets/stylesheets/page_bundles/escalation_policies.scss25
-rw-r--r--app/assets/stylesheets/page_bundles/merge_requests.scss2
-rw-r--r--app/assets/stylesheets/page_bundles/new_namespace.scss4
-rw-r--r--app/assets/stylesheets/page_bundles/pipeline.scss310
-rw-r--r--app/assets/stylesheets/page_bundles/reports.scss5
-rw-r--r--app/assets/stylesheets/page_bundles/signup.scss30
-rw-r--r--app/assets/stylesheets/pages/commits.scss4
-rw-r--r--app/assets/stylesheets/pages/issuable.scss5
-rw-r--r--app/assets/stylesheets/pages/login.scss5
-rw-r--r--app/assets/stylesheets/pages/note_form.scss2
-rw-r--r--app/assets/stylesheets/pages/profile.scss8
-rw-r--r--app/assets/stylesheets/pages/search.scss19
-rw-r--r--app/assets/stylesheets/pages/tree.scss1
-rw-r--r--app/assets/stylesheets/startup/startup-dark.scss85
-rw-r--r--app/assets/stylesheets/startup/startup-general.scss35
-rw-r--r--app/assets/stylesheets/startup/startup-signin.scss10
-rw-r--r--app/assets/stylesheets/themes/_dark.scss28
-rw-r--r--app/assets/stylesheets/themes/theme_helper.scss30
-rw-r--r--app/assets/stylesheets/themes/theme_light.scss10
-rw-r--r--app/assets/stylesheets/utilities.scss25
-rw-r--r--app/controllers/admin/applications_controller.rb16
-rw-r--r--app/controllers/admin/background_migrations_controller.rb9
-rw-r--r--app/controllers/admin/runner_projects_controller.rb4
-rw-r--r--app/controllers/admin/users_controller.rb2
-rw-r--r--app/controllers/application_controller.rb6
-rw-r--r--app/controllers/boards/issues_controller.rb4
-rw-r--r--app/controllers/concerns/integrations/params.rb7
-rw-r--r--app/controllers/concerns/issuable_collections.rb8
-rw-r--r--app/controllers/concerns/issuable_collections_action.rb4
-rw-r--r--app/controllers/concerns/oauth_applications.rb10
-rw-r--r--app/controllers/concerns/project_unauthorized.rb2
-rw-r--r--app/controllers/concerns/renders_projects_list.rb3
-rw-r--r--app/controllers/concerns/routable_actions.rb8
-rw-r--r--app/controllers/concerns/sessionless_authentication.rb1
-rw-r--r--app/controllers/dashboard/projects_controller.rb2
-rw-r--r--app/controllers/explore/projects_controller.rb7
-rw-r--r--app/controllers/groups/application_controller.rb2
-rw-r--r--app/controllers/groups/boards_controller.rb1
-rw-r--r--app/controllers/groups/clusters/integrations_controller.rb2
-rw-r--r--app/controllers/groups/clusters_controller.rb2
-rw-r--r--app/controllers/groups/runners_controller.rb4
-rw-r--r--app/controllers/groups/settings/applications_controller.rb15
-rw-r--r--app/controllers/groups/settings/ci_cd_controller.rb2
-rw-r--r--app/controllers/groups_controller.rb16
-rw-r--r--app/controllers/import/bitbucket_controller.rb6
-rw-r--r--app/controllers/import/bitbucket_server_controller.rb14
-rw-r--r--app/controllers/import/bulk_imports_controller.rb2
-rw-r--r--app/controllers/import/fogbugz_controller.rb8
-rw-r--r--app/controllers/import/github_controller.rb4
-rw-r--r--app/controllers/import/gitlab_controller.rb8
-rw-r--r--app/controllers/import/manifest_controller.rb14
-rw-r--r--app/controllers/invites_controller.rb7
-rw-r--r--app/controllers/jira_connect/installations_controller.rb31
-rw-r--r--app/controllers/members/mailgun/permanent_failures_controller.rb65
-rw-r--r--app/controllers/oauth/applications_controller.rb12
-rw-r--r--app/controllers/profiles/groups_controller.rb2
-rw-r--r--app/controllers/profiles/two_factor_auths_controller.rb13
-rw-r--r--app/controllers/profiles_controller.rb12
-rw-r--r--app/controllers/projects/analytics/cycle_analytics/summary_controller.rb2
-rw-r--r--app/controllers/projects/application_controller.rb2
-rw-r--r--app/controllers/projects/boards_controller.rb1
-rw-r--r--app/controllers/projects/ci/pipeline_editor_controller.rb1
-rw-r--r--app/controllers/projects/clusters/integrations_controller.rb2
-rw-r--r--app/controllers/projects/clusters_controller.rb2
-rw-r--r--app/controllers/projects/environments_controller.rb8
-rw-r--r--app/controllers/projects/feature_flags_controller.rb15
-rw-r--r--app/controllers/projects/issues_controller.rb11
-rw-r--r--app/controllers/projects/learn_gitlab_controller.rb4
-rw-r--r--app/controllers/projects/merge_requests/diffs_controller.rb2
-rw-r--r--app/controllers/projects/merge_requests_controller.rb14
-rw-r--r--app/controllers/projects/packages/packages_controller.rb2
-rw-r--r--app/controllers/projects/pipeline_schedules_controller.rb4
-rw-r--r--app/controllers/projects/pipelines_controller.rb9
-rw-r--r--app/controllers/projects/runner_projects_controller.rb4
-rw-r--r--app/controllers/projects/service_desk_controller.rb33
-rw-r--r--app/controllers/projects/services_controller.rb20
-rw-r--r--app/controllers/projects/settings/operations_controller.rb1
-rw-r--r--app/controllers/projects/tree_controller.rb4
-rw-r--r--app/controllers/projects/usage_quotas_controller.rb28
-rw-r--r--app/controllers/projects/wikis_controller.rb4
-rw-r--r--app/controllers/projects/work_items_controller.rb13
-rw-r--r--app/controllers/projects_controller.rb1
-rw-r--r--app/controllers/registrations/experience_levels_controller.rb44
-rw-r--r--app/controllers/registrations/welcome_controller.rb2
-rw-r--r--app/controllers/registrations_controller.rb10
-rw-r--r--app/controllers/search_controller.rb25
-rw-r--r--app/controllers/user_callouts_controller.rb10
-rw-r--r--app/controllers/users/group_callouts_controller.rb17
-rw-r--r--app/controllers/users/terms_controller.rb2
-rw-r--r--app/controllers/users_controller.rb2
-rw-r--r--app/experiments/combined_registration_experiment.rb23
-rw-r--r--app/experiments/security_reports_mr_widget_prompt_experiment.rb14
-rw-r--r--app/experiments/templates/new_project_readme_content/readme_advanced.md.tt2
-rw-r--r--app/finders/branches_finder.rb4
-rw-r--r--app/finders/ci/pipelines_finder.rb15
-rw-r--r--app/finders/ci/pipelines_for_merge_request_finder.rb24
-rw-r--r--app/finders/ci/runners_finder.rb18
-rw-r--r--app/finders/error_tracking/errors_finder.rb14
-rw-r--r--app/finders/groups/user_groups_finder.rb60
-rw-r--r--app/finders/issuable_finder.rb63
-rw-r--r--app/finders/issuable_finder/params.rb32
-rw-r--r--app/finders/issuables/label_filter.rb155
-rw-r--r--app/finders/issues_finder.rb7
-rw-r--r--app/finders/issues_finder/params.rb4
-rw-r--r--app/finders/packages/helm/package_files_finder.rb2
-rw-r--r--app/finders/packages/helm/packages_finder.rb30
-rw-r--r--app/finders/packages/npm/package_finder.rb17
-rw-r--r--app/finders/projects_finder.rb10
-rw-r--r--app/finders/repositories/tree_finder.rb61
-rw-r--r--app/graphql/mutations/admin/sidekiq_queues/delete_jobs.rb9
-rw-r--r--app/graphql/mutations/custom_emoji/destroy.rb36
-rw-r--r--app/graphql/mutations/customer_relations/organizations/create.rb53
-rw-r--r--app/graphql/mutations/customer_relations/organizations/update.rb52
-rw-r--r--app/graphql/mutations/dependency_proxy/image_ttl_group_policy/update.rb54
-rw-r--r--app/graphql/queries/repository/files.query.graphql1
-rw-r--r--app/graphql/queries/repository/paginated_tree.query.graphql54
-rw-r--r--app/graphql/queries/repository/path_last_commit.query.graphql1
-rw-r--r--app/graphql/queries/repository/permissions.query.graphql1
-rw-r--r--app/graphql/resolvers/base_resolver.rb10
-rw-r--r--app/graphql/resolvers/board_list_issues_resolver.rb18
-rw-r--r--app/graphql/resolvers/ci/group_runners_resolver.rb26
-rw-r--r--app/graphql/resolvers/ci/runners_resolver.rb15
-rw-r--r--app/graphql/resolvers/concerns/issue_resolver_arguments.rb5
-rw-r--r--app/graphql/resolvers/concerns/resolves_pipelines.rb7
-rw-r--r--app/graphql/resolvers/labels_resolver.rb2
-rw-r--r--app/graphql/resolvers/merge_requests_resolver.rb2
-rw-r--r--app/graphql/resolvers/milestones_resolver.rb6
-rw-r--r--app/graphql/resolvers/package_details_resolver.rb2
-rw-r--r--app/graphql/resolvers/paginated_tree_resolver.rb4
-rw-r--r--app/graphql/resolvers/release_resolver.rb2
-rw-r--r--app/graphql/resolvers/repository_branch_names_resolver.rb6
-rw-r--r--app/graphql/resolvers/snippets_resolver.rb6
-rw-r--r--app/graphql/resolvers/todo_resolver.rb19
-rw-r--r--app/graphql/resolvers/tree_resolver.rb4
-rw-r--r--app/graphql/resolvers/users/groups_resolver.rb44
-rw-r--r--app/graphql/resolvers/users/snippets_resolver.rb2
-rw-r--r--app/graphql/types/admin/analytics/usage_trends/measurement_type.rb4
-rw-r--r--app/graphql/types/admin/sidekiq_queues/delete_jobs_response_type.rb4
-rw-r--r--app/graphql/types/alert_management/alert_type.rb8
-rw-r--r--app/graphql/types/award_emojis/award_emoji_type.rb12
-rw-r--r--app/graphql/types/base_field.rb1
-rw-r--r--app/graphql/types/boards/board_issuable_input_base_type.rb2
-rw-r--r--app/graphql/types/boards/board_issue_input_base_type.rb4
-rw-r--r--app/graphql/types/ci/config/job_restriction_type.rb2
-rw-r--r--app/graphql/types/ci/config/status_enum.rb4
-rw-r--r--app/graphql/types/ci/job_type.rb3
-rw-r--r--app/graphql/types/ci/pipeline_type.rb2
-rw-r--r--app/graphql/types/ci/runner_membership_filter_enum.rb18
-rw-r--r--app/graphql/types/ci/stage_type.rb25
-rw-r--r--app/graphql/types/ci_configuration/sast/ui_component_size_enum.rb6
-rw-r--r--app/graphql/types/commit_action_type.rb2
-rw-r--r--app/graphql/types/container_repository_cleanup_status_enum.rb8
-rw-r--r--app/graphql/types/container_repository_tag_type.rb2
-rw-r--r--app/graphql/types/container_repository_type.rb2
-rw-r--r--app/graphql/types/custom_emoji_type.rb6
-rw-r--r--app/graphql/types/customer_relations/contact_type.rb55
-rw-r--r--app/graphql/types/customer_relations/organization_type.rb41
-rw-r--r--app/graphql/types/dependency_proxy/blob_type.rb16
-rw-r--r--app/graphql/types/dependency_proxy/group_setting_type.rb13
-rw-r--r--app/graphql/types/dependency_proxy/image_ttl_group_policy_type.rb16
-rw-r--r--app/graphql/types/dependency_proxy/manifest_type.rb22
-rw-r--r--app/graphql/types/design_management/design_at_version_type.rb4
-rw-r--r--app/graphql/types/design_management/design_fields.rb16
-rw-r--r--app/graphql/types/diff_paths_input_type.rb4
-rw-r--r--app/graphql/types/environment_type.rb4
-rw-r--r--app/graphql/types/eventable_type.rb2
-rw-r--r--app/graphql/types/group_type.rb73
-rw-r--r--app/graphql/types/issue_sort_enum.rb2
-rw-r--r--app/graphql/types/issue_type.rb7
-rw-r--r--app/graphql/types/issues/negated_issue_filter_input_type.rb6
-rw-r--r--app/graphql/types/merge_request_type.rb6
-rw-r--r--app/graphql/types/metadata/kas_type.rb2
-rw-r--r--app/graphql/types/milestone_wildcard_id_enum.rb6
-rw-r--r--app/graphql/types/mutation_type.rb10
-rw-r--r--app/graphql/types/namespace_type.rb2
-rw-r--r--app/graphql/types/negated_milestone_wildcard_id_enum.rb4
-rw-r--r--app/graphql/types/notes/note_type.rb4
-rw-r--r--app/graphql/types/notes/position_type_enum.rb2
-rw-r--r--app/graphql/types/packages/composer/json_type.rb8
-rw-r--r--app/graphql/types/packages/package_details_type.rb2
-rw-r--r--app/graphql/types/packages/package_file_type.rb4
-rw-r--r--app/graphql/types/packages/package_tag_type.rb8
-rw-r--r--app/graphql/types/packages/package_type.rb2
-rw-r--r--app/graphql/types/permission_types/custom_emoji.rb2
-rw-r--r--app/graphql/types/permission_types/group.rb2
-rw-r--r--app/graphql/types/permission_types/group_enum.rb12
-rw-r--r--app/graphql/types/project_statistics_type.rb2
-rw-r--r--app/graphql/types/project_type.rb10
-rw-r--r--app/graphql/types/prometheus_alert_type.rb2
-rw-r--r--app/graphql/types/query_type.rb12
-rw-r--r--app/graphql/types/range_input_type.rb4
-rw-r--r--app/graphql/types/release_asset_link_shared_input_arguments.rb2
-rw-r--r--app/graphql/types/release_assets_input_type.rb2
-rw-r--r--app/graphql/types/release_type.rb2
-rw-r--r--app/graphql/types/repository/blob_type.rb6
-rw-r--r--app/graphql/types/root_storage_statistics_type.rb18
-rw-r--r--app/graphql/types/snippet_type.rb4
-rw-r--r--app/graphql/types/snippets/blob_type.rb2
-rw-r--r--app/graphql/types/snippets/visibility_scopes_enum.rb6
-rw-r--r--app/graphql/types/terraform/state_type.rb4
-rw-r--r--app/graphql/types/terraform/state_version_type.rb5
-rw-r--r--app/graphql/types/timelog_type.rb12
-rw-r--r--app/graphql/types/todo_state_enum.rb4
-rw-r--r--app/graphql/types/todo_target_enum.rb10
-rw-r--r--app/graphql/types/todo_type.rb4
-rw-r--r--app/graphql/types/user_interface.rb10
-rw-r--r--app/graphql/types/user_merge_request_interaction_type.rb2
-rw-r--r--app/graphql/types/user_state_enum.rb6
-rw-r--r--app/helpers/analytics/cycle_analytics_helper.rb18
-rw-r--r--app/helpers/application_settings_helper.rb30
-rw-r--r--app/helpers/blob_helper.rb4
-rw-r--r--app/helpers/ci/pipeline_editor_helper.rb1
-rw-r--r--app/helpers/ci/runners_helper.rb9
-rw-r--r--app/helpers/diff_helper.rb21
-rw-r--r--app/helpers/environment_helper.rb1
-rw-r--r--app/helpers/gitlab_routing_helper.rb1
-rw-r--r--app/helpers/groups_helper.rb87
-rw-r--r--app/helpers/invite_members_helper.rb8
-rw-r--r--app/helpers/issuables_helper.rb29
-rw-r--r--app/helpers/issues_helper.rb51
-rw-r--r--app/helpers/learn_gitlab_helper.rb18
-rw-r--r--app/helpers/nav/new_dropdown_helper.rb18
-rw-r--r--app/helpers/nav/top_nav_helper.rb4
-rw-r--r--app/helpers/notify_helper.rb17
-rw-r--r--app/helpers/packages_helper.rb3
-rw-r--r--app/helpers/profiles_helper.rb20
-rw-r--r--app/helpers/projects_helper.rb2
-rw-r--r--app/helpers/recaptcha_helper.rb2
-rw-r--r--app/helpers/routing/pseudonymization_helper.rb58
-rw-r--r--app/helpers/search_helper.rb4
-rw-r--r--app/helpers/sessions_helper.rb16
-rw-r--r--app/helpers/sidebars_helper.rb3
-rw-r--r--app/helpers/sorting_helper.rb9
-rw-r--r--app/helpers/sorting_titles_values_helper.rb12
-rw-r--r--app/helpers/system_note_helper.rb3
-rw-r--r--app/helpers/user_callouts_helper.rb49
-rw-r--r--app/mailers/emails/admin_notification.rb4
-rw-r--r--app/mailers/emails/members.rb35
-rw-r--r--app/mailers/emails/profile.rb20
-rw-r--r--app/models/analytics/cycle_analytics/issue_stage_event.rb11
-rw-r--r--app/models/analytics/cycle_analytics/merge_request_stage_event.rb11
-rw-r--r--app/models/application_record.rb36
-rw-r--r--app/models/application_setting.rb102
-rw-r--r--app/models/application_setting_implementation.rb17
-rw-r--r--app/models/award_emoji.rb2
-rw-r--r--app/models/bulk_imports/entity.rb24
-rw-r--r--app/models/bulk_imports/tracker.rb4
-rw-r--r--app/models/ci/application_record.rb1
-rw-r--r--app/models/ci/bridge.rb18
-rw-r--r--app/models/ci/build.rb43
-rw-r--r--app/models/ci/build_trace_chunks/fog.rb10
-rw-r--r--app/models/ci/build_trace_metadata.rb45
-rw-r--r--app/models/ci/job_artifact.rb15
-rw-r--r--app/models/ci/pending_build.rb82
-rw-r--r--app/models/ci/pipeline.rb29
-rw-r--r--app/models/ci/pipeline_variable.rb2
-rw-r--r--app/models/ci/runner.rb40
-rw-r--r--app/models/ci/sources/pipeline.rb3
-rw-r--r--app/models/clusters/agent.rb6
-rw-r--r--app/models/clusters/agents/group_authorization.rb16
-rw-r--r--app/models/clusters/agents/implicit_authorization.rb20
-rw-r--r--app/models/clusters/agents/project_authorization.rb14
-rw-r--r--app/models/clusters/cluster.rb1
-rw-r--r--app/models/clusters/clusters_hierarchy.rb2
-rw-r--r--app/models/clusters/platforms/kubernetes.rb16
-rw-r--r--app/models/commit_status.rb10
-rw-r--r--app/models/compare.rb10
-rw-r--r--app/models/concerns/approvable_base.rb4
-rw-r--r--app/models/concerns/cache_markdown_field.rb33
-rw-r--r--app/models/concerns/calloutable.rb15
-rw-r--r--app/models/concerns/ci/contextable.rb4
-rw-r--r--app/models/concerns/cron_schedulable.rb8
-rw-r--r--app/models/concerns/enums/ci/commit_status.rb1
-rw-r--r--app/models/concerns/featurable.rb21
-rw-r--r--app/models/concerns/has_repository.rb4
-rw-r--r--app/models/concerns/integrations/has_data_fields.rb1
-rw-r--r--app/models/concerns/issuable.rb17
-rw-r--r--app/models/concerns/loose_foreign_key.rb95
-rw-r--r--app/models/concerns/mentionable.rb11
-rw-r--r--app/models/concerns/optimized_issuable_label_filter.rb121
-rw-r--r--app/models/concerns/partitioned_table.rb2
-rw-r--r--app/models/concerns/relative_positioning.rb12
-rw-r--r--app/models/concerns/sanitizable.rb52
-rw-r--r--app/models/concerns/sortable_title.rb21
-rw-r--r--app/models/concerns/taggable_queries.rb10
-rw-r--r--app/models/customer_relations/contact.rb33
-rw-r--r--app/models/customer_relations/organization.rb10
-rw-r--r--app/models/dependency_proxy/blob.rb3
-rw-r--r--app/models/dependency_proxy/image_ttl_group_policy.rb11
-rw-r--r--app/models/dependency_proxy/manifest.rb3
-rw-r--r--app/models/deploy_keys_project.rb1
-rw-r--r--app/models/design_management/action.rb2
-rw-r--r--app/models/diff_note.rb28
-rw-r--r--app/models/environment.rb73
-rw-r--r--app/models/environment_status.rb10
-rw-r--r--app/models/error_tracking/client_key.rb6
-rw-r--r--app/models/error_tracking/error.rb25
-rw-r--r--app/models/error_tracking/project_error_tracking_setting.rb2
-rw-r--r--app/models/event.rb3
-rw-r--r--app/models/group.rb50
-rw-r--r--app/models/hooks/web_hook.rb2
-rw-r--r--app/models/instance_configuration.rb17
-rw-r--r--app/models/integration.rb6
-rw-r--r--app/models/integrations/base_chat_notification.rb2
-rw-r--r--app/models/integrations/datadog.rb2
-rw-r--r--app/models/integrations/prometheus.rb2
-rw-r--r--app/models/integrations/slack_slash_commands.rb2
-rw-r--r--app/models/integrations/zentao.rb78
-rw-r--r--app/models/integrations/zentao_tracker_data.rb23
-rw-r--r--app/models/internal_id.rb209
-rw-r--r--app/models/issue.rb23
-rw-r--r--app/models/issue/metrics.rb39
-rw-r--r--app/models/loose_foreign_keys.rb7
-rw-r--r--app/models/loose_foreign_keys/deleted_record.rb49
-rw-r--r--app/models/member.rb7
-rw-r--r--app/models/members/project_member.rb2
-rw-r--r--app/models/merge_request.rb79
-rw-r--r--app/models/merge_request/metrics.rb19
-rw-r--r--app/models/merge_request_diff.rb17
-rw-r--r--app/models/milestone.rb30
-rw-r--r--app/models/namespace.rb60
-rw-r--r--app/models/namespace_setting.rb14
-rw-r--r--app/models/namespaces/project_namespace.rb13
-rw-r--r--app/models/namespaces/traversal/linear.rb5
-rw-r--r--app/models/namespaces/traversal/linear_scopes.rb51
-rw-r--r--app/models/namespaces/traversal/recursive.rb8
-rw-r--r--app/models/namespaces/traversal/recursive_scopes.rb16
-rw-r--r--app/models/namespaces/user_namespace.rb11
-rw-r--r--app/models/note.rb17
-rw-r--r--app/models/onboarding_progress.rb2
-rw-r--r--app/models/operations/feature_flag.rb6
-rw-r--r--app/models/operations/feature_flag_scope.rb4
-rw-r--r--app/models/packages/package.rb9
-rw-r--r--app/models/packages/package_file.rb22
-rw-r--r--app/models/pages_deployment.rb7
-rw-r--r--app/models/postgresql/detached_partition.rb2
-rw-r--r--app/models/preloaders/commit_status_preloader.rb29
-rw-r--r--app/models/preloaders/merge_requests_preloader.rb19
-rw-r--r--app/models/preloaders/user_max_access_level_in_groups_preloader.rb27
-rw-r--r--app/models/project.rb137
-rw-r--r--app/models/project_feature.rb16
-rw-r--r--app/models/project_team.rb2
-rw-r--r--app/models/projects/project_topic.rb8
-rw-r--r--app/models/projects/topic.rb10
-rw-r--r--app/models/protected_branch.rb4
-rw-r--r--app/models/push_event_payload.rb3
-rw-r--r--app/models/release.rb1
-rw-r--r--app/models/repository.rb62
-rw-r--r--app/models/service_desk_setting.rb12
-rw-r--r--app/models/shard.rb6
-rw-r--r--app/models/user.rb181
-rw-r--r--app/models/user_callout.rb9
-rw-r--r--app/models/user_detail.rb17
-rw-r--r--app/models/user_preference.rb2
-rw-r--r--app/models/users/group_callout.rb25
-rw-r--r--app/models/work_item/type.rb24
-rw-r--r--app/models/zoom_meeting.rb2
-rw-r--r--app/policies/ci/runner_policy.rb6
-rw-r--r--app/policies/custom_emoji_policy.rb10
-rw-r--r--app/policies/customer_relations/contact_policy.rb6
-rw-r--r--app/policies/customer_relations/organization_policy.rb6
-rw-r--r--app/policies/dependency_proxy/blob_policy.rb6
-rw-r--r--app/policies/dependency_proxy/group_setting_policy.rb6
-rw-r--r--app/policies/dependency_proxy/image_ttl_group_policy_policy.rb6
-rw-r--r--app/policies/dependency_proxy/manifest_policy.rb6
-rw-r--r--app/policies/group_policy.rb15
-rw-r--r--app/policies/issue_policy.rb8
-rw-r--r--app/policies/user_policy.rb1
-rw-r--r--app/presenters/ci/build_presenter.rb8
-rw-r--r--app/presenters/ci/build_runner_presenter.rb2
-rw-r--r--app/presenters/ci/legacy_stage_presenter.rb13
-rw-r--r--app/presenters/ci/stage_presenter.rb15
-rw-r--r--app/presenters/commit_status_presenter.rb3
-rw-r--r--app/presenters/packages/helm/index_presenter.rb23
-rw-r--r--app/presenters/packages/npm/package_presenter.rb23
-rw-r--r--app/presenters/project_presenter.rb18
-rw-r--r--app/presenters/projects/import_export/project_export_presenter.rb1
-rw-r--r--app/presenters/snippet_blob_presenter.rb6
-rw-r--r--app/serializers/group_child_entity.rb14
-rw-r--r--app/serializers/group_entity.rb4
-rw-r--r--app/serializers/issuable_sidebar_extras_entity.rb17
-rw-r--r--app/services/auth/container_registry_authentication_service.rb18
-rw-r--r--app/services/base_container_service.rb10
-rw-r--r--app/services/base_group_service.rb12
-rw-r--r--app/services/base_service.rb1
-rw-r--r--app/services/boards/issues/list_service.rb8
-rw-r--r--app/services/ci/after_requeue_job_service.rb13
-rw-r--r--app/services/ci/archive_trace_service.rb9
-rw-r--r--app/services/ci/drop_pipeline_service.rb8
-rw-r--r--app/services/ci/external_pull_requests/create_pipeline_service.rb10
-rw-r--r--app/services/ci/pipeline_schedules/calculate_next_run_service.rb1
-rw-r--r--app/services/ci/pipelines/add_job_service.rb4
-rw-r--r--app/services/ci/queue/build_queue_service.rb36
-rw-r--r--app/services/ci/queue/builds_table_strategy.rb8
-rw-r--r--app/services/ci/queue/pending_builds_strategy.rb22
-rw-r--r--app/services/ci/register_job_service.rb63
-rw-r--r--app/services/ci/stuck_builds/drop_helpers.rb58
-rw-r--r--app/services/ci/stuck_builds/drop_service.rb62
-rw-r--r--app/services/ci/update_build_queue_service.rb14
-rw-r--r--app/services/ci/update_pending_build_service.rb45
-rw-r--r--app/services/clusters/agents/refresh_authorization_service.rb106
-rw-r--r--app/services/concerns/members/bulk_create_users.rb76
-rw-r--r--app/services/customer_relations/organizations/base_service.rb17
-rw-r--r--app/services/customer_relations/organizations/create_service.rb30
-rw-r--r--app/services/customer_relations/organizations/update_service.rb24
-rw-r--r--app/services/dependency_proxy/image_ttl_group_policies/update_service.rb41
-rw-r--r--app/services/design_management/delete_designs_service.rb1
-rw-r--r--app/services/draft_notes/publish_service.rb20
-rw-r--r--app/services/emails/destroy_service.rb6
-rw-r--r--app/services/environments/auto_stop_service.rb12
-rw-r--r--app/services/environments/stop_service.rb16
-rw-r--r--app/services/error_tracking/collect_error_service.rb32
-rw-r--r--app/services/error_tracking/list_issues_service.rb4
-rw-r--r--app/services/feature_flags/base_service.rb9
-rw-r--r--app/services/feature_flags/create_service.rb4
-rw-r--r--app/services/feature_flags/update_service.rb38
-rw-r--r--app/services/git/base_hooks_service.rb10
-rw-r--r--app/services/git/branch_hooks_service.rb37
-rw-r--r--app/services/git/tag_hooks_service.rb6
-rw-r--r--app/services/groups/open_issues_count_service.rb27
-rw-r--r--app/services/groups/update_shared_runners_service.rb9
-rw-r--r--app/services/issuable/bulk_update_service.rb19
-rw-r--r--app/services/issuable_base_service.rb5
-rw-r--r--app/services/issue_rebalancing_service.rb136
-rw-r--r--app/services/issues/base_service.rb10
-rw-r--r--app/services/issues/build_service.rb13
-rw-r--r--app/services/issues/relative_position_rebalancing_service.rb193
-rw-r--r--app/services/issues/update_service.rb70
-rw-r--r--app/services/members/create_service.rb17
-rw-r--r--app/services/members/creator_service.rb64
-rw-r--r--app/services/members/groups/bulk_creator_service.rb9
-rw-r--r--app/services/members/invite_service.rb2
-rw-r--r--app/services/members/mailgun.rb8
-rw-r--r--app/services/members/mailgun/process_webhook_service.rb39
-rw-r--r--app/services/members/projects/bulk_creator_service.rb9
-rw-r--r--app/services/merge_requests/merge_to_ref_service.rb8
-rw-r--r--app/services/merge_requests/mergeability_check_service.rb4
-rw-r--r--app/services/merge_requests/squash_service.rb17
-rw-r--r--app/services/packages/composer/version_parser_service.rb11
-rw-r--r--app/services/packages/create_package_service.rb6
-rw-r--r--app/services/packages/generic/create_package_file_service.rb3
-rw-r--r--app/services/packages/maven/find_or_create_package_service.rb2
-rw-r--r--app/services/packages/nuget/update_package_from_metadata_service.rb33
-rw-r--r--app/services/pages/delete_service.rb3
-rw-r--r--app/services/pages/legacy_storage_lease.rb19
-rw-r--r--app/services/pages/migrate_legacy_storage_to_deployment_service.rb15
-rw-r--r--app/services/projects/batch_count_service.rb16
-rw-r--r--app/services/projects/batch_forks_count_service.rb23
-rw-r--r--app/services/projects/count_service.rb2
-rw-r--r--app/services/projects/create_service.rb19
-rw-r--r--app/services/projects/fork_service.rb3
-rw-r--r--app/services/projects/forks_count_service.rb2
-rw-r--r--app/services/projects/group_links/destroy_service.rb20
-rw-r--r--app/services/projects/move_deploy_keys_projects_service.rb2
-rw-r--r--app/services/projects/move_forks_service.rb2
-rw-r--r--app/services/projects/move_lfs_objects_projects_service.rb2
-rw-r--r--app/services/projects/move_notification_settings_service.rb2
-rw-r--r--app/services/projects/move_project_authorizations_service.rb2
-rw-r--r--app/services/projects/move_project_group_links_service.rb2
-rw-r--r--app/services/projects/move_project_members_service.rb2
-rw-r--r--app/services/projects/move_users_star_projects_service.rb2
-rw-r--r--app/services/projects/open_issues_count_service.rb98
-rw-r--r--app/services/projects/operations/update_service.rb1
-rw-r--r--app/services/projects/transfer_service.rb23
-rw-r--r--app/services/projects/update_pages_service.rb104
-rw-r--r--app/services/projects/update_service.rb11
-rw-r--r--app/services/protected_branches/api_service.rb2
-rw-r--r--app/services/protected_branches/base_service.rb17
-rw-r--r--app/services/protected_branches/create_service.rb2
-rw-r--r--app/services/protected_branches/destroy_service.rb2
-rw-r--r--app/services/protected_branches/update_service.rb10
-rw-r--r--app/services/repositories/changelog_service.rb2
-rw-r--r--app/services/search/global_service.rb2
-rw-r--r--app/services/service_ping/submit_service.rb17
-rw-r--r--app/services/suggestions/apply_service.rb2
-rw-r--r--app/services/suggestions/create_service.rb2
-rw-r--r--app/services/system_note_service.rb4
-rw-r--r--app/services/system_notes/issuables_service.rb6
-rw-r--r--app/services/todos/destroy/design_service.rb28
-rw-r--r--app/services/users/ban_service.rb4
-rw-r--r--app/services/users/banned_user_base_service.rb5
-rw-r--r--app/services/users/dismiss_group_callout_service.rb11
-rw-r--r--app/services/users/dismiss_user_callout_service.rb10
-rw-r--r--app/services/users/migrate_to_ghost_user_service.rb29
-rw-r--r--app/services/users/reject_service.rb6
-rw-r--r--app/services/users/unban_service.rb6
-rw-r--r--app/services/wiki_pages/event_create_service.rb6
-rw-r--r--app/validators/gitlab/utils/zoom_url_validator.rb22
-rw-r--r--app/validators/gitlab/zoom_url_validator.rb22
-rw-r--r--app/validators/json_schemas/cluster_agent_authorization_configuration.json6
-rw-r--r--app/validators/json_schemas/dast_profile_schedule_cadence.json31
-rw-r--r--app/validators/json_schemas/error_tracking_event_payload.json148
-rw-r--r--app/views/admin/application_settings/_ci_cd.html.haml2
-rw-r--r--app/views/admin/application_settings/_eks.html.haml10
-rw-r--r--app/views/admin/application_settings/_email.html.haml8
-rw-r--r--app/views/admin/application_settings/_external_authorization_service_form.html.haml2
-rw-r--r--app/views/admin/application_settings/_files_limits.html.haml34
-rw-r--r--app/views/admin/application_settings/_floc.html.haml2
-rw-r--r--app/views/admin/application_settings/_git_lfs_limits.html.haml21
-rw-r--r--app/views/admin/application_settings/_gitpod.html.haml2
-rw-r--r--app/views/admin/application_settings/_import_export_limits.html.haml18
-rw-r--r--app/views/admin/application_settings/_initial_branch_name.html.haml2
-rw-r--r--app/views/admin/application_settings/_ip_limits.html.haml85
-rw-r--r--app/views/admin/application_settings/_issue_limits.html.haml2
-rw-r--r--app/views/admin/application_settings/_mailgun.html.haml2
-rw-r--r--app/views/admin/application_settings/_note_limits.html.haml7
-rw-r--r--app/views/admin/application_settings/_outbound.html.haml2
-rw-r--r--app/views/admin/application_settings/_package_registry_limits.html.haml21
-rw-r--r--app/views/admin/application_settings/_protected_paths.html.haml2
-rw-r--r--app/views/admin/application_settings/_sidekiq_job_limits.html.haml21
-rw-r--r--app/views/admin/application_settings/network.html.haml43
-rw-r--r--app/views/admin/application_settings/preferences.html.haml14
-rw-r--r--app/views/admin/applications/_form.html.haml8
-rw-r--r--app/views/admin/applications/edit.html.haml3
-rw-r--r--app/views/admin/background_migrations/_migration.html.haml4
-rw-r--r--app/views/admin/deploy_keys/new.html.haml2
-rw-r--r--app/views/admin/identities/edit.html.haml4
-rw-r--r--app/views/admin/identities/index.html.haml2
-rw-r--r--app/views/admin/identities/new.html.haml6
-rw-r--r--app/views/admin/impersonation_tokens/index.html.haml2
-rw-r--r--app/views/admin/projects/index.html.haml21
-rw-r--r--app/views/admin/runners/show.html.haml14
-rw-r--r--app/views/ci/group_variables/_variable_header.html.haml6
-rw-r--r--app/views/ci/variables/_index.html.haml2
-rw-r--r--app/views/devise/mailer/unlock_instructions.html.haml4
-rw-r--r--app/views/devise/mailer/unlock_instructions.text.erb4
-rw-r--r--app/views/devise/shared/_footer.html.haml2
-rw-r--r--app/views/devise/shared/_omniauth_box.html.haml4
-rw-r--r--app/views/devise/shared/_signup_box.html.haml1
-rw-r--r--app/views/devise/shared/_tabs_normal.html.haml2
-rw-r--r--app/views/errors/access_denied.html.haml2
-rw-r--r--app/views/groups/_group_admin_settings.html.haml4
-rw-r--r--app/views/groups/_home_panel.html.haml6
-rw-r--r--app/views/groups/_new_group_fields.html.haml5
-rw-r--r--app/views/groups/_personalize.html.haml27
-rw-r--r--app/views/groups/dependency_proxies/_url.html.haml2
-rw-r--r--app/views/groups/issues.html.haml47
-rw-r--r--app/views/groups/new.html.haml2
-rw-r--r--app/views/groups/runners/_runner.html.haml3
-rw-r--r--app/views/groups/runners/index.html.haml2
-rw-r--r--app/views/groups/settings/_membership.html.haml6
-rw-r--r--app/views/groups/settings/_permissions.html.haml5
-rw-r--r--app/views/groups/settings/_two_factor_auth.html.haml2
-rw-r--r--app/views/groups/settings/ci_cd/show.html.haml6
-rw-r--r--app/views/groups/settings/repository/_initial_branch_name.html.haml2
-rw-r--r--app/views/groups/show.html.haml6
-rw-r--r--app/views/help/instance_configuration.html.haml2
-rw-r--r--app/views/help/instance_configuration/_gitlab_ci.html.haml24
-rw-r--r--app/views/help/instance_configuration/_gitlab_pages.html.haml5
-rw-r--r--app/views/help/instance_configuration/_size_limits.html.haml40
-rw-r--r--app/views/issues/_issue.atom.builder39
-rw-r--r--app/views/layouts/_page.html.haml2
-rw-r--r--app/views/layouts/_search.html.haml2
-rw-r--r--app/views/layouts/_snowplow.html.haml3
-rw-r--r--app/views/layouts/header/_default.html.haml20
-rw-r--r--app/views/layouts/header/_new_dropdown.html.haml2
-rw-r--r--app/views/layouts/nav/sidebar/_group.html.haml2
-rw-r--r--app/views/layouts/nav/sidebar/_group_menus.html.haml3
-rw-r--r--app/views/notify/member_invited_email.html.haml5
-rw-r--r--app/views/profiles/_email_settings.html.haml2
-rw-r--r--app/views/profiles/emails/index.html.haml8
-rw-r--r--app/views/profiles/keys/show.html.haml2
-rw-r--r--app/views/profiles/notifications/_email_settings.html.haml2
-rw-r--r--app/views/profiles/show.html.haml5
-rw-r--r--app/views/projects/_commit_button.html.haml2
-rw-r--r--app/views/projects/_home_panel.html.haml6
-rw-r--r--app/views/projects/_import_project_pane.html.haml2
-rw-r--r--app/views/projects/_invite_members_empty_project.html.haml2
-rw-r--r--app/views/projects/_new_project_fields.html.haml34
-rw-r--r--app/views/projects/blob/_new_dir.html.haml2
-rw-r--r--app/views/projects/blob/_remove.html.haml2
-rw-r--r--app/views/projects/blob/show.html.haml2
-rw-r--r--app/views/projects/blob/viewers/_notebook.html.haml2
-rw-r--r--app/views/projects/branches/new.html.haml4
-rw-r--r--app/views/projects/ci/builds/_build.html.haml6
-rw-r--r--app/views/projects/cycle_analytics/show.html.haml4
-rw-r--r--app/views/projects/diffs/_stats.html.haml42
-rw-r--r--app/views/projects/error_tracking/details.html.haml2
-rw-r--r--app/views/projects/hooks/edit.html.haml2
-rw-r--r--app/views/projects/imports/new.html.haml2
-rw-r--r--app/views/projects/issues/_issue.html.haml4
-rw-r--r--app/views/projects/issues/_nav_btns.html.haml2
-rw-r--r--app/views/projects/issues/index.html.haml4
-rw-r--r--app/views/projects/jobs/index.html.haml3
-rw-r--r--app/views/projects/labels/edit.html.haml2
-rw-r--r--app/views/projects/labels/new.html.haml2
-rw-r--r--app/views/projects/mattermosts/_team_selection.html.haml2
-rw-r--r--app/views/projects/merge_requests/_merge_request.atom.builder8
-rw-r--r--app/views/projects/merge_requests/_merge_requests.html.haml2
-rw-r--r--app/views/projects/merge_requests/_nav_btns.html.haml3
-rw-r--r--app/views/projects/merge_requests/_widget.html.haml2
-rw-r--r--app/views/projects/merge_requests/creations/_new_compare.html.haml2
-rw-r--r--app/views/projects/merge_requests/creations/_new_submit.html.haml2
-rw-r--r--app/views/projects/merge_requests/index.atom.builder11
-rw-r--r--app/views/projects/merge_requests/index.html.haml5
-rw-r--r--app/views/projects/merge_requests/show.html.haml7
-rw-r--r--app/views/projects/packages/packages/show.html.haml5
-rw-r--r--app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml2
-rw-r--r--app/views/projects/pipeline_schedules/new.html.haml2
-rw-r--r--app/views/projects/pipelines/_with_tabs.html.haml2
-rw-r--r--app/views/projects/pipelines/show.html.haml2
-rw-r--r--app/views/projects/project_members/index.html.haml7
-rw-r--r--app/views/projects/project_templates/_template.html.haml4
-rw-r--r--app/views/projects/services/slack_slash_commands/_help.html.haml23
-rw-r--r--app/views/projects/settings/ci_cd/show.html.haml2
-rw-r--r--app/views/projects/settings/operations/_error_tracking.html.haml1
-rw-r--r--app/views/projects/tags/releases/edit.html.haml4
-rw-r--r--app/views/projects/usage_quotas/index.html.haml19
-rw-r--r--app/views/projects/work_items/index.html.haml3
-rw-r--r--app/views/registrations/experience_levels/show.html.haml29
-rw-r--r--app/views/search/_category.html.haml8
-rw-r--r--app/views/search/results/_blob_data.html.haml4
-rw-r--r--app/views/search/results/_commit.html.haml2
-rw-r--r--app/views/search/results/_issuable.html.haml2
-rw-r--r--app/views/search/results/_milestone.html.haml2
-rw-r--r--app/views/search/results/_note.html.haml2
-rw-r--r--app/views/search/results/_wiki_blob.html.haml2
-rw-r--r--app/views/shared/_check_recovery_settings.html.haml11
-rw-r--r--app/views/shared/_help_dropdown_forum_link.html.haml2
-rw-r--r--app/views/shared/_two_factor_auth_recovery_settings_check.html.haml11
-rw-r--r--app/views/shared/_visibility_level.html.haml2
-rw-r--r--app/views/shared/_visibility_radios.html.haml2
-rw-r--r--app/views/shared/access_tokens/_table.html.haml2
-rw-r--r--app/views/shared/boards/_show.html.haml8
-rw-r--r--app/views/shared/boards/components/_sidebar.html.haml27
-rw-r--r--app/views/shared/boards/components/sidebar/_assignee.html.haml10
-rw-r--r--app/views/shared/boards/components/sidebar/_due_date.html.haml31
-rw-r--r--app/views/shared/boards/components/sidebar/_labels.html.haml34
-rw-r--r--app/views/shared/boards/components/sidebar/_milestone.html.haml29
-rw-r--r--app/views/shared/boards/components/sidebar/_notifications.html.haml5
-rw-r--r--app/views/shared/boards/components/sidebar/_time_tracker.html.haml6
-rw-r--r--app/views/shared/deploy_tokens/_form.html.haml2
-rw-r--r--app/views/shared/deploy_tokens/_table.html.haml2
-rw-r--r--app/views/shared/doorkeeper/applications/_form.html.haml6
-rw-r--r--app/views/shared/empty_states/_merge_requests.html.haml4
-rw-r--r--app/views/shared/issuable/_board_create_list_dropdown.html.haml8
-rw-r--r--app/views/shared/issuable/_feed_buttons.html.haml10
-rw-r--r--app/views/shared/issuable/_form.html.haml2
-rw-r--r--app/views/shared/issuable/_issuable.atom.builder38
-rw-r--r--app/views/shared/issuable/_search_bar.html.haml5
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml2
-rw-r--r--app/views/shared/issuable/_sidebar_user_dropdown.html.haml2
-rw-r--r--app/views/shared/issuable/_sort_dropdown.html.haml1
-rw-r--r--app/views/shared/issuable/form/_metadata.html.haml66
-rw-r--r--app/views/shared/issuable/form/_type_selector.html.haml2
-rw-r--r--app/views/shared/issue_type/_details_header.html.haml2
-rw-r--r--app/views/shared/labels/_form.html.haml4
-rw-r--r--app/views/shared/members/_access_request_links.html.haml8
-rw-r--r--app/views/shared/runners/_runner_details.html.haml2
-rw-r--r--app/views/shared/wikis/pages.html.haml2
-rw-r--r--app/views/sherlock/queries/_backtrace.html.haml2
-rw-r--r--app/views/sherlock/queries/_general.html.haml2
-rw-r--r--app/views/users/_middle_dot_divider.html.haml5
-rw-r--r--app/views/users/_profile_basic_info.html.haml6
-rw-r--r--app/views/users/show.html.haml53
-rw-r--r--app/views/users/terms/index.html.haml4
-rw-r--r--app/workers/all_queues.yml307
-rw-r--r--app/workers/analytics/usage_trends/count_job_trigger_worker.rb1
-rw-r--r--app/workers/analytics/usage_trends/counter_job_worker.rb1
-rw-r--r--app/workers/approve_blocked_pending_approval_users_worker.rb1
-rw-r--r--app/workers/authorized_project_update/user_refresh_from_replica_worker.rb15
-rw-r--r--app/workers/background_migration_worker.rb23
-rw-r--r--app/workers/build_success_worker.rb2
-rw-r--r--app/workers/bulk_import_worker.rb14
-rw-r--r--app/workers/bulk_imports/entity_worker.rb1
-rw-r--r--app/workers/bulk_imports/pipeline_worker.rb1
-rw-r--r--app/workers/bulk_imports/relation_export_worker.rb1
-rw-r--r--app/workers/ci/delete_objects_worker.rb1
-rw-r--r--app/workers/ci/drop_pipeline_worker.rb2
-rw-r--r--app/workers/ci/external_pull_requests/create_pipeline_worker.rb40
-rw-r--r--app/workers/ci/merge_requests/add_todo_when_build_fails_worker.rb1
-rw-r--r--app/workers/ci/pipeline_artifacts/create_quality_report_worker.rb1
-rw-r--r--app/workers/ci/pipeline_artifacts/expire_artifacts_worker.rb1
-rw-r--r--app/workers/ci/schedule_delete_objects_cron_worker.rb1
-rw-r--r--app/workers/ci/test_failure_history_worker.rb2
-rw-r--r--app/workers/concerns/application_worker.rb10
-rw-r--r--app/workers/concerns/chaos_queue.rb1
-rw-r--r--app/workers/concerns/worker_attributes.rb13
-rw-r--r--app/workers/container_expiration_policies/cleanup_container_repository_worker.rb1
-rw-r--r--app/workers/database/batched_background_migration_worker.rb1
-rw-r--r--app/workers/database/partition_management_worker.rb2
-rw-r--r--app/workers/deployments/drop_older_deployments_worker.rb1
-rw-r--r--app/workers/deployments/finished_worker.rb24
-rw-r--r--app/workers/deployments/forward_deployment_worker.rb20
-rw-r--r--app/workers/deployments/hooks_worker.rb2
-rw-r--r--app/workers/deployments/success_worker.rb25
-rw-r--r--app/workers/design_management/copy_design_collection_worker.rb1
-rw-r--r--app/workers/destroy_pages_deployments_worker.rb1
-rw-r--r--app/workers/disallow_two_factor_for_group_worker.rb1
-rw-r--r--app/workers/disallow_two_factor_for_subgroups_worker.rb1
-rw-r--r--app/workers/email_receiver_worker.rb2
-rw-r--r--app/workers/environments/auto_stop_worker.rb18
-rw-r--r--app/workers/environments/canary_ingress/update_worker.rb1
-rw-r--r--app/workers/experiments/record_conversion_event_worker.rb1
-rw-r--r--app/workers/expire_job_cache_worker.rb12
-rw-r--r--app/workers/expire_pipeline_cache_worker.rb2
-rw-r--r--app/workers/flush_counter_increments_worker.rb1
-rw-r--r--app/workers/gitlab/github_import/import_pull_request_merged_by_worker.rb1
-rw-r--r--app/workers/gitlab/github_import/import_pull_request_review_worker.rb1
-rw-r--r--app/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker.rb28
-rw-r--r--app/workers/gitlab/github_import/stage/import_notes_worker.rb24
-rw-r--r--app/workers/gitlab/github_import/stage/import_pull_requests_merged_by_worker.rb2
-rw-r--r--app/workers/gitlab/github_import/stage/import_pull_requests_reviews_worker.rb2
-rw-r--r--app/workers/gitlab_performance_bar_stats_worker.rb1
-rw-r--r--app/workers/group_destroy_worker.rb1
-rw-r--r--app/workers/hashed_storage/migrator_worker.rb5
-rw-r--r--app/workers/hashed_storage/project_migrate_worker.rb5
-rw-r--r--app/workers/hashed_storage/project_rollback_worker.rb5
-rw-r--r--app/workers/hashed_storage/rollbacker_worker.rb5
-rw-r--r--app/workers/incident_management/add_severity_system_note_worker.rb1
-rw-r--r--app/workers/issue_rebalancing_worker.rb9
-rw-r--r--app/workers/jira_connect/sync_builds_worker.rb1
-rw-r--r--app/workers/jira_connect/sync_deployments_worker.rb1
-rw-r--r--app/workers/jira_connect/sync_feature_flags_worker.rb1
-rw-r--r--app/workers/jira_connect/sync_project_worker.rb1
-rw-r--r--app/workers/member_invitation_reminder_emails_worker.rb1
-rw-r--r--app/workers/merge_request_cleanup_refs_worker.rb1
-rw-r--r--app/workers/metrics/dashboard/sync_dashboards_worker.rb1
-rw-r--r--app/workers/namespaces/in_product_marketing_emails_worker.rb1
-rw-r--r--app/workers/namespaces/onboarding_issue_created_worker.rb1
-rw-r--r--app/workers/namespaces/onboarding_pipeline_created_worker.rb1
-rw-r--r--app/workers/namespaces/onboarding_progress_worker.rb1
-rw-r--r--app/workers/namespaces/onboarding_user_added_worker.rb1
-rw-r--r--app/workers/packages/composer/cache_cleanup_worker.rb1
-rw-r--r--app/workers/packages/composer/cache_update_worker.rb1
-rw-r--r--app/workers/packages/debian/process_changes_worker.rb8
-rw-r--r--app/workers/packages/go/sync_packages_worker.rb1
-rw-r--r--app/workers/packages/helm/extraction_worker.rb4
-rw-r--r--app/workers/packages/maven/metadata/sync_worker.rb1
-rw-r--r--app/workers/packages/rubygems/extraction_worker.rb1
-rw-r--r--app/workers/pages_domain_ssl_renewal_worker.rb1
-rw-r--r--app/workers/pages_domain_verification_worker.rb1
-rw-r--r--app/workers/pages_remove_worker.rb8
-rw-r--r--app/workers/pages_transfer_worker.rb1
-rw-r--r--app/workers/pages_update_configuration_worker.rb1
-rw-r--r--app/workers/pages_worker.rb1
-rw-r--r--app/workers/personal_access_tokens/expired_notification_worker.rb1
-rw-r--r--app/workers/post_receive.rb4
-rw-r--r--app/workers/project_destroy_worker.rb1
-rw-r--r--app/workers/projects/git_garbage_collect_worker.rb2
-rw-r--r--app/workers/projects/post_creation_worker.rb1
-rw-r--r--app/workers/propagate_integration_group_worker.rb1
-rw-r--r--app/workers/propagate_integration_inherit_descendant_worker.rb1
-rw-r--r--app/workers/propagate_integration_inherit_worker.rb1
-rw-r--r--app/workers/propagate_integration_project_worker.rb1
-rw-r--r--app/workers/purge_dependency_proxy_cache_worker.rb2
-rw-r--r--app/workers/releases/create_evidence_worker.rb1
-rw-r--r--app/workers/releases/manage_evidence_worker.rb1
-rw-r--r--app/workers/remove_unaccepted_member_invites_worker.rb1
-rw-r--r--app/workers/schedule_merge_request_cleanup_refs_worker.rb1
-rw-r--r--app/workers/service_desk_email_receiver_worker.rb3
-rw-r--r--app/workers/ssh_keys/expired_notification_worker.rb1
-rw-r--r--app/workers/ssh_keys/expiring_soon_notification_worker.rb1
-rw-r--r--app/workers/stuck_ci_jobs_worker.rb95
-rw-r--r--app/workers/todos_destroyer/destroyed_designs_worker.rb18
-rw-r--r--app/workers/todos_destroyer/destroyed_issuable_worker.rb2
-rw-r--r--app/workers/user_status_cleanup/batch_worker.rb1
-rw-r--r--app/workers/users/deactivate_dormant_users_worker.rb1
-rw-r--r--app/workers/web_hooks/destroy_worker.rb1
-rw-r--r--app/workers/web_hooks/log_execution_worker.rb2
-rw-r--r--app/workers/wikis/git_garbage_collect_worker.rb2
-rw-r--r--babel.config.js2
-rwxr-xr-xbin/background_jobs83
-rwxr-xr-xbin/background_jobs_sk67
-rwxr-xr-xbin/background_jobs_sk_cluster76
-rwxr-xr-xbin/bundle4
-rwxr-xr-xbin/pngquant64
-rwxr-xr-xbin/rspec2
-rwxr-xr-xbin/rspec-stackprof2
-rw-r--r--changelogs/README.md12
-rw-r--r--config/application.rb9
-rw-r--r--config/boot.rb5
-rw-r--r--config/bundler_setup.rb24
-rw-r--r--config/database.yml.decomposed-postgresql47
-rw-r--r--config/database.yml.postgresql80
-rw-r--r--config/events/20210915205037_alert_integrations_view_alert_integrations_list.yml21
-rw-r--r--config/events/20210915205038_default_click_button.yml21
-rw-r--r--config/events/20210915205039_default_copy_keyboard_shortcut.yml21
-rw-r--r--config/events/20210915205040_default_generic.yml21
-rw-r--r--config/events/20210915205041_default_generic.yml21
-rw-r--r--config/events/20210915205050_code_quality_walkthrough_commit_ci_file_dismissed.yml21
-rw-r--r--config/events/20210915205051_code_quality_walkthrough_commit_ci_file_displayed.yml21
-rw-r--r--config/events/20210915205052_code_quality_walkthrough_commit_created.yml21
-rw-r--r--config/events/20210915205053_code_quality_walkthrough_cta_clicked.yml21
-rw-r--r--config/events/20210915205054_code_quality_walkthrough_failed_pipeline_displayed.yml21
-rw-r--r--config/events/20210915205055_code_quality_walkthrough_failed_pipeline_view_logs.yml21
-rw-r--r--config/events/20210915205056_code_quality_walkthrough_running_pipeline_dismissed.yml21
-rw-r--r--config/events/20210915205057_code_quality_walkthrough_running_pipeline_displayed.yml21
-rw-r--r--config/events/20210915205058_code_quality_walkthrough_success_pipeline_displayed.yml21
-rw-r--r--config/events/20210915205059_code_quality_walkthrough_success_pipeline_view_logs.yml21
-rw-r--r--config/events/20210915205100_default_execute_toolbar_control.yml21
-rw-r--r--config/events/20210915205101_default_execute_keyboard_shortcut.yml21
-rw-r--r--config/events/20210915205102_default_execute_input_rule.yml21
-rw-r--r--config/events/20210915205103_default_execute_bubble_menu_control.yml21
-rw-r--r--config/events/20210915205107_default_click_link.yml21
-rw-r--r--config/events/20210915205108_default_type_search_query.yml21
-rw-r--r--config/events/20210915205109_default_invite_members_banner_button_clicked.yml21
-rw-r--r--config/events/20210915205110_default_invite_members_banner_dismissed.yml21
-rw-r--r--config/events/20210915205111_default_change_discussion_sort_direction.yml21
-rw-r--r--config/events/20210915205112_packages_delete_package.yml21
-rw-r--r--config/events/20210915205113_packages_request_delete_package_file.yml21
-rw-r--r--config/events/20210915205114_packages_delete_package_file.yml21
-rw-r--r--config/events/20210915205115_packages_pull_package.yml21
-rw-r--r--config/events/20210915205116_packages_cancel_delete_package.yml21
-rw-r--r--config/events/20210915205117_packages_cancel_delete_package_file.yml21
-rw-r--r--config/events/20210915205118_default_copy_composer_registry_include_command.yml21
-rw-r--r--config/events/20210915205119_default_copy_composer_package_include_command.yml21
-rw-r--r--config/events/20210915205125_default_copy_gradle_install_command.yml21
-rw-r--r--config/events/20210915205126_default_copy_gradle_add_to_source_command.yml21
-rw-r--r--config/events/20210915205127_default_copy_kotlin_install_command.yml21
-rw-r--r--config/events/20210915205128_default_copy_kotlin_add_to_source_command.yml21
-rw-r--r--config/events/20210915205140_default_reset_form.yml21
-rw-r--r--config/events/20210915205141_default_submit_form.yml21
-rw-r--r--config/events/20210915205142_default_click_dismiss.yml21
-rw-r--r--config/events/20210915205143_default_show_home_page_banner.yml21
-rw-r--r--config/events/20210915205145_default_content_editor_loaded.yml21
-rw-r--r--config/events/20210915205146_default_saved_using_content_editor.yml21
-rw-r--r--config/events/20210915205147_default_browse_templates.yml21
-rw-r--r--config/events/20210915205148_default_template_clicked.yml21
-rw-r--r--config/events/20210915205149_default_dismiss_banner.yml21
-rw-r--r--config/events/20210915205150_default_click_button.yml21
-rw-r--r--config/events/20210915205151_default_click_dropdown.yml21
-rw-r--r--config/events/20210915205152_default_click_copy_login.yml21
-rw-r--r--config/events/20210915205153_default_click_copy_build.yml21
-rw-r--r--config/events/20210915205154_default_click_copy_push.yml21
-rw-r--r--config/events/20210915205155_default_click_button.yml21
-rw-r--r--config/events/20210915205156_default_confirm_delete.yml21
-rw-r--r--config/events/20210915205157_default_cancel_delete.yml21
-rw-r--r--config/events/20210915205158_default_click_button.yml21
-rw-r--r--config/events/20210915205159_default_confirm_delete.yml21
-rw-r--r--config/events/20210915205200_default_cancel_delete.yml21
-rw-r--r--config/events/20210915205202_default_generic.yml21
-rw-r--r--config/events/20210915205203_default_click_tab.yml21
-rw-r--r--config/events/20210915205204_default_click_whats_new_drawer.yml21
-rw-r--r--config/events/20210915205207_default_click_dropdown.yml21
-rw-r--r--config/feature_categories.yml3
-rw-r--r--config/feature_flags/development/add_namespace_and_project_to_snowplow_tracking.yml8
-rw-r--r--config/feature_flags/development/additional_snowplow_tracking.yml2
-rw-r--r--config/feature_flags/development/between_uses_list_commits.yml8
-rw-r--r--config/feature_flags/development/board_new_list.yml8
-rw-r--r--config/feature_flags/development/bulk_import.yml2
-rw-r--r--config/feature_flags/development/bulk_import_projects.yml8
-rw-r--r--config/feature_flags/development/cache_merge_to_ref_calls.yml8
-rw-r--r--config/feature_flags/development/cached_encoding_detection.yml8
-rw-r--r--config/feature_flags/development/cached_issues_state_count.yml8
-rw-r--r--config/feature_flags/development/changes_batch_commits.yml8
-rw-r--r--config/feature_flags/development/ci_build_tags_limit.yml8
-rw-r--r--config/feature_flags/development/ci_create_external_pr_pipeline_async.yml8
-rw-r--r--config/feature_flags/development/ci_daily_limit_for_pipeline_schedules.yml8
-rw-r--r--config/feature_flags/development/ci_fix_commit_status_retried.yml8
-rw-r--r--config/feature_flags/development/ci_idempotent_pipeline_process_worker.yml2
-rw-r--r--config/feature_flags/development/ci_include_rules.yml2
-rw-r--r--config/feature_flags/development/ci_job_trace_force_encode.yml8
-rw-r--r--config/feature_flags/development/ci_modified_paths_of_external_prs.yml8
-rw-r--r--config/feature_flags/development/ci_new_artifact_file_reader.yml2
-rw-r--r--config/feature_flags/development/ci_new_query_for_pending_stuck_jobs.yml8
-rw-r--r--config/feature_flags/development/ci_pending_builds_maintain_namespace_traversal_ids.yml8
-rw-r--r--config/feature_flags/development/ci_pending_builds_maintain_tags_data.yml8
-rw-r--r--config/feature_flags/development/ci_pending_builds_project_runners_decoupling.yml8
-rw-r--r--config/feature_flags/development/ci_pipeline_add_job_with_lock.yml2
-rw-r--r--config/feature_flags/development/ci_queueing_builds_enabled_checks.yml8
-rw-r--r--config/feature_flags/development/ci_queueing_denormalize_namespace_traversal_ids.yml8
-rw-r--r--config/feature_flags/development/ci_queueing_denormalize_tags_information.yml8
-rw-r--r--config/feature_flags/development/ci_remove_update_retried_from_process_pipeline.yml2
-rw-r--r--config/feature_flags/development/ci_reset_bridge_with_subsequent_jobs.yml8
-rw-r--r--config/feature_flags/development/ci_same_stage_job_needs.yml8
-rw-r--r--config/feature_flags/development/ci_yaml_limit_size.yml2
-rw-r--r--config/feature_flags/development/content_editor_block_tables.yml8
-rw-r--r--config/feature_flags/development/create_vulnerabilities_via_api.yml8
-rw-r--r--config/feature_flags/development/customer_relations.yml8
-rw-r--r--config/feature_flags/development/dast_meta_tag_validation.yml8
-rw-r--r--config/feature_flags/development/dast_profile_disable_joins.yml8
-rw-r--r--config/feature_flags/development/dast_runner_site_validation.yml8
-rw-r--r--config/feature_flags/development/dast_scanner_profile_disable_joins.yml8
-rw-r--r--config/feature_flags/development/dast_site_profile_disable_joins.yml8
-rw-r--r--config/feature_flags/development/dast_view_scans.yml8
-rw-r--r--config/feature_flags/development/delete_branch_confirmation_modals.yml4
-rw-r--r--config/feature_flags/development/diffs_batch_render_cached.yml8
-rw-r--r--config/feature_flags/development/ensure_verified_primary_email_for_2fa.yml8
-rw-r--r--config/feature_flags/development/environment_last_visible_pipeline_disable_joins.yml8
-rw-r--r--config/feature_flags/development/files_api_throttling.yml8
-rw-r--r--config/feature_flags/development/find_tag_via_gitaly.yml8
-rw-r--r--config/feature_flags/development/generate_iids_without_explicit_locking.yml8
-rw-r--r--config/feature_flags/development/get_tag_signatures.yml8
-rw-r--r--config/feature_flags/development/gitaly_pack_objects_hook_with_sidechannel.yml8
-rw-r--r--config/feature_flags/development/gitaly_tags_finder.yml8
-rw-r--r--config/feature_flags/development/graphql_board_lists.yml8
-rw-r--r--config/feature_flags/development/group_authorized_agents.yml8
-rw-r--r--config/feature_flags/development/group_level_protected_environments.yml8
-rw-r--r--config/feature_flags/development/groups_tokens_optional_encryption.yml2
-rw-r--r--config/feature_flags/development/infinitely_collapsible_sections.yml2
-rw-r--r--config/feature_flags/development/integrated_error_tracking.yml8
-rw-r--r--config/feature_flags/development/issue_rebalancing_optimization.yml8
-rw-r--r--config/feature_flags/development/issue_rebalancing_with_retry.yml8
-rw-r--r--config/feature_flags/development/keyset_pagination_for_groups_api.yml8
-rw-r--r--config/feature_flags/development/linear_application_settings_elasticsearch_limited_namespaces.yml8
-rw-r--r--config/feature_flags/development/linear_group_including_descendants_by.yml8
-rw-r--r--config/feature_flags/development/linear_groups_template_finder_extended_group_search.yml8
-rw-r--r--config/feature_flags/development/linear_user_groups_with_developer_maintainer_project_access.yml8
-rw-r--r--config/feature_flags/development/linear_user_manageable_groups.yml8
-rw-r--r--config/feature_flags/development/linear_user_membership_groups.yml8
-rw-r--r--config/feature_flags/development/load_balancing_for_deployments_hooks_worker.yml8
-rw-r--r--config/feature_flags/development/local_file_reviews.yml8
-rw-r--r--config/feature_flags/development/mailgun_events_receiver.yml8
-rw-r--r--config/feature_flags/development/merge_request_show_render_cached.yml8
-rw-r--r--config/feature_flags/development/milestone_reference_pattern.yml8
-rw-r--r--config/feature_flags/development/new_header_search.yml8
-rw-r--r--config/feature_flags/development/new_route_storage_purchase.yml8
-rw-r--r--config/feature_flags/development/optimize_safe_find_or_create_by.yml8
-rw-r--r--config/feature_flags/development/optimized_issuable_label_filter.yml8
-rw-r--r--config/feature_flags/development/other_storage_tab.yml8
-rw-r--r--config/feature_flags/development/package_details_apollo.yml8
-rw-r--r--config/feature_flags/development/packages_nuget_new_package_file_updater.yml8
-rw-r--r--config/feature_flags/development/paginatable_namespace_drop_down_for_project_creation.yml8
-rw-r--r--config/feature_flags/development/permitted_attributes_for_import_export.yml8
-rw-r--r--config/feature_flags/development/pipeline_editor_branch_switcher.yml8
-rw-r--r--config/feature_flags/development/pipeline_source_filter.yml8
-rw-r--r--config/feature_flags/development/preserve_latest_wal_locations_for_idempotent_jobs.yml8
-rw-r--r--config/feature_flags/development/product_analytics.yml2
-rw-r--r--config/feature_flags/development/project_storage_ui.yml8
-rw-r--r--config/feature_flags/development/projects_tokens_optional_encryption.yml2
-rw-r--r--config/feature_flags/development/query_project_ci_feature_usages_for_coverage.yml8
-rw-r--r--config/feature_flags/development/redirect_to_latest_template_jobs_build.yml8
-rw-r--r--config/feature_flags/development/repository_tree_gitaly_pagination.yml8
-rw-r--r--config/feature_flags/development/restructured_mr_widget.yml8
-rw-r--r--config/feature_flags/development/runner_detailed_view_vue_ui.yml8
-rw-r--r--config/feature_flags/development/runner_graphql_query.yml8
-rw-r--r--config/feature_flags/development/security_orchestration_policies_configuration.yml2
-rw-r--r--config/feature_flags/development/set_full_path.yml8
-rw-r--r--config/feature_flags/development/skip_pages_deploy_to_legacy_storage.yml8
-rw-r--r--config/feature_flags/development/sort_by_project_users_by_project_authorizations_user_id.yml2
-rw-r--r--config/feature_flags/development/store_mentions_without_subtransaction.yml8
-rw-r--r--config/feature_flags/development/track_epic_boards_activity.yml2
-rw-r--r--config/feature_flags/development/track_unique_visits.yml8
-rw-r--r--config/feature_flags/development/usage_data_design_action.yml8
-rw-r--r--config/feature_flags/development/usage_data_i_testing_load_performance_widget_total.yml8
-rw-r--r--config/feature_flags/development/usage_data_i_testing_metrics_report_widget_total.yml8
-rw-r--r--config/feature_flags/development/usage_data_i_testing_web_performance_widget_total.yml8
-rw-r--r--config/feature_flags/development/use_specialized_worker_for_project_auth_recalculation.yml8
-rw-r--r--config/feature_flags/development/use_traversal_ids_for_ancestor_scopes.yml8
-rw-r--r--config/feature_flags/development/use_upsert_query_for_mr_metrics.yml8
-rw-r--r--config/feature_flags/development/user_refresh_from_replica_worker_uses_replica_db.yml8
-rw-r--r--config/feature_flags/development/vuln_report_new_project_filter.yml4
-rw-r--r--config/feature_flags/development/vulnerability_flags.yml8
-rw-r--r--config/feature_flags/development/work_items.yml8
-rw-r--r--config/feature_flags/experiment/combined_registration.yml8
-rw-r--r--config/feature_flags/experiment/invite_email_from.yml8
-rw-r--r--config/feature_flags/experiment/learn_gitlab_a_experiment_percentage.yml8
-rw-r--r--config/feature_flags/experiment/learn_gitlab_b_experiment_percentage.yml8
-rw-r--r--config/feature_flags/experiment/repo_integrations_link.yml8
-rw-r--r--config/feature_flags/experiment/security_reports_mr_widget_prompt.yml8
-rw-r--r--config/feature_flags/ops/active_record_subtransactions_counter.yml8
-rw-r--r--config/feature_flags/ops/ci_pipeline_creation_step_duration_tracking.yml8
-rw-r--r--config/feature_flags/ops/disable_anonymous_project_search.yml8
-rw-r--r--config/feature_flags/ops/disable_anonymous_search.yml8
-rw-r--r--config/feature_flags/ops/github_importer_lower_per_page_limit.yml8
-rw-r--r--config/feature_flags/ops/github_importer_single_endpoint_notes_import.yml8
-rw-r--r--config/feature_flags/ops/global_search_code_tab.yml8
-rw-r--r--config/feature_flags/ops/global_search_commits_tab.yml8
-rw-r--r--config/feature_flags/ops/global_search_issues_tab.yml8
-rw-r--r--config/feature_flags/ops/global_search_merge_requests_tab.yml8
-rw-r--r--config/feature_flags/ops/global_search_wiki_tab.yml8
-rw-r--r--config/feature_flags/ops/lower_relation_max_count_limit.yml8
-rw-r--r--config/feature_flags/ops/mask_page_urls.yml8
-rw-r--r--config/feature_flags/ops/product_analytics_tracking.yml2
-rw-r--r--config/gitlab.yml.example25
-rw-r--r--config/helpers/incremental_webpack_compiler.js131
-rw-r--r--config/helpers/incremental_webpack_compiler/compiler.js117
-rw-r--r--config/helpers/incremental_webpack_compiler/history.js176
-rw-r--r--config/helpers/incremental_webpack_compiler/index.js17
-rw-r--r--config/helpers/incremental_webpack_compiler/log.js3
-rw-r--r--config/initializers/00_active_record_gitlab_schema.rb10
-rw-r--r--config/initializers/0_acts_as_taggable.rb4
-rw-r--r--config/initializers/0_inject_enterprise_edition_module.rb34
-rw-r--r--config/initializers/0_marginalia.rb2
-rw-r--r--config/initializers/1_settings.rb2
-rw-r--r--config/initializers/action_cable.rb3
-rw-r--r--config/initializers/active_record_build_select.rb24
-rw-r--r--config/initializers/active_record_migrations.rb3
-rw-r--r--config/initializers/database_config.rb2
-rw-r--r--config/initializers/doorkeeper.rb7
-rw-r--r--config/initializers/doorkeeper_openid_connect.rb3
-rw-r--r--config/initializers/kaminari_active_record_relation_methods_with_limit.rb4
-rw-r--r--config/initializers/peek.rb2
-rw-r--r--config/initializers/postgres_partitioning.rb17
-rw-r--r--config/initializers/session_store.rb2
-rw-r--r--config/initializers/static_files.rb4
-rw-r--r--config/initializers/validate_database_config.rb31
-rw-r--r--config/initializers/zz_metrics.rb39
-rw-r--r--config/initializers_before_autoloader/000_inflections.rb1
-rw-r--r--config/initializers_before_autoloader/001_fast_gettext.rb31
-rw-r--r--config/initializers_before_autoloader/grape_entity_patch.rb27
-rw-r--r--config/karma.config.js203
-rw-r--r--config/known_invalid_graphql_queries.yml1
-rw-r--r--config/metrics/aggregates/code_review.yml2
-rw-r--r--config/metrics/counts_28d/20210201124930_deployments.yml2
-rw-r--r--config/metrics/counts_28d/20210216174910_analytics_unique_visits_for_any_target_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216174933_p_analytics_pipelines_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216174941_p_analytics_valuestream_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216174956_i_analytics_cohorts_monthly.yml13
-rw-r--r--config/metrics/counts_28d/20210216175000_i_analytics_dev_ops_score_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216175004_g_analytics_merge_request_monthly.yml7
-rw-r--r--config/metrics/counts_28d/20210216175012_i_analytics_instance_statistics_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216175016_analytics_total_unique_counts_monthly.yml41
-rw-r--r--config/metrics/counts_28d/20210216175055_merge_requests.yml3
-rw-r--r--config/metrics/counts_28d/20210216175057_projects_with_disable_overriding_approvers_per_merge_request.yml6
-rw-r--r--config/metrics/counts_28d/20210216175059_projects_without_disable_overriding_approvers_per_merge_request.yml6
-rw-r--r--config/metrics/counts_28d/20210216175101_merge_requests_users.yml3
-rw-r--r--config/metrics/counts_28d/20210216175109_suggestions.yml6
-rw-r--r--config/metrics/counts_28d/20210216175113_merge_request_action_monthly.yml3
-rw-r--r--config/metrics/counts_28d/20210216175117_i_source_code_code_intelligence_monthly.yml3
-rw-r--r--config/metrics/counts_28d/20210216175120_i_code_review_mr_diffs_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216175124_i_code_review_user_single_file_diffs_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216175128_i_code_review_mr_single_file_diffs_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216175132_i_code_review_user_create_mr_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216175136_i_code_review_user_close_mr_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216175140_i_code_review_user_reopen_mr_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216175144_i_code_review_user_merge_mr_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216175148_i_code_review_user_create_mr_comment_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216175152_i_code_review_user_edit_mr_comment_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216175156_i_code_review_user_remove_mr_comment_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216175159_i_code_review_user_add_suggestion_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216175203_i_code_review_user_apply_suggestion_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216175405_clusters_applications_cert_managers.yml10
-rw-r--r--config/metrics/counts_28d/20210216175407_clusters_applications_helm.yml10
-rw-r--r--config/metrics/counts_28d/20210216175409_clusters_applications_ingress.yml10
-rw-r--r--config/metrics/counts_28d/20210216175411_clusters_applications_knative.yml10
-rw-r--r--config/metrics/counts_28d/20210216175413_clusters_management_project.yml8
-rw-r--r--config/metrics/counts_28d/20210216175415_clusters_disabled.yml10
-rw-r--r--config/metrics/counts_28d/20210216175417_clusters_enabled.yml10
-rw-r--r--config/metrics/counts_28d/20210216175419_clusters_platforms_gke.yml10
-rw-r--r--config/metrics/counts_28d/20210216175420_clusters_platforms_eks.yml10
-rw-r--r--config/metrics/counts_28d/20210216175422_clusters_platforms_user.yml10
-rw-r--r--config/metrics/counts_28d/20210216175424_instance_clusters_disabled.yml10
-rw-r--r--config/metrics/counts_28d/20210216175426_instance_clusters_enabled.yml10
-rw-r--r--config/metrics/counts_28d/20210216175428_group_clusters_disabled.yml10
-rw-r--r--config/metrics/counts_28d/20210216175430_group_clusters_enabled.yml10
-rw-r--r--config/metrics/counts_28d/20210216175432_project_clusters_disabled.yml10
-rw-r--r--config/metrics/counts_28d/20210216175434_project_clusters_enabled.yml10
-rw-r--r--config/metrics/counts_28d/20210216175542_ci_builds.yml3
-rw-r--r--config/metrics/counts_28d/20210216175544_ci_external_pipelines.yml3
-rw-r--r--config/metrics/counts_28d/20210216175546_ci_internal_pipelines.yml3
-rw-r--r--config/metrics/counts_28d/20210216175548_ci_pipeline_config_auto_devops.yml3
-rw-r--r--config/metrics/counts_28d/20210216175550_ci_pipeline_config_repository.yml3
-rw-r--r--config/metrics/counts_28d/20210216175552_ci_pipeline_schedules.yml3
-rw-r--r--config/metrics/counts_28d/20210216175554_ci_pipelines.yml5
-rw-r--r--config/metrics/counts_28d/20210216175556_ci_triggers.yml3
-rw-r--r--config/metrics/counts_28d/20210216180308_personal_snippets.yml3
-rw-r--r--config/metrics/counts_28d/20210216180310_project_snippets.yml3
-rw-r--r--config/metrics/counts_28d/20210216180312_snippets.yml3
-rw-r--r--config/metrics/counts_28d/20210216180317_snippets.yml3
-rw-r--r--config/metrics/counts_28d/20210216180319_action_monthly_active_users_web_ide_edit.yml3
-rw-r--r--config/metrics/counts_28d/20210216180321_action_monthly_active_users_sfe_edit.yml3
-rw-r--r--config/metrics/counts_28d/20210216180323_action_monthly_active_users_snippet_editor_edit.yml3
-rw-r--r--config/metrics/counts_28d/20210216180325_action_monthly_active_users_sse_edit.yml3
-rw-r--r--config/metrics/counts_28d/20210216180327_action_monthly_active_users_ide_edit.yml3
-rw-r--r--config/metrics/counts_28d/20210216180330_g_edit_by_web_ide_monthly.yml3
-rw-r--r--config/metrics/counts_28d/20210216180334_g_edit_by_sfe_monthly.yml3
-rw-r--r--config/metrics/counts_28d/20210216180338_g_edit_by_snippet_ide_monthly.yml3
-rw-r--r--config/metrics/counts_28d/20210216180341_ide_edit_total_unique_counts_monthly.yml3
-rw-r--r--config/metrics/counts_28d/20210216180424_i_search_total_monthly.yml3
-rw-r--r--config/metrics/counts_28d/20210216180431_search_total_unique_counts_monthly.yml8
-rw-r--r--config/metrics/counts_28d/20210216180509_incident_management_alerts_total_unique_counts.yml3
-rw-r--r--config/metrics/counts_28d/20210216180511_incident_management_incidents_total_unique_counts.yml3
-rw-r--r--config/metrics/counts_28d/20210216180524_projects_with_incidents.yml5
-rw-r--r--config/metrics/counts_28d/20210216180526_projects_with_alert_incidents.yml7
-rw-r--r--config/metrics/counts_28d/20210216180530_incident_management_alert_status_changed_monthly.yml7
-rw-r--r--config/metrics/counts_28d/20210216180533_incident_management_alert_assigned_monthly.yml7
-rw-r--r--config/metrics/counts_28d/20210216180537_incident_management_alert_todo_monthly.yml7
-rw-r--r--config/metrics/counts_28d/20210216180541_incident_management_incident_created_monthly.yml7
-rw-r--r--config/metrics/counts_28d/20210216180545_incident_management_incident_reopened_monthly.yml7
-rw-r--r--config/metrics/counts_28d/20210216180548_incident_management_incident_closed_monthly.yml7
-rw-r--r--config/metrics/counts_28d/20210216180552_incident_management_incident_assigned_monthly.yml7
-rw-r--r--config/metrics/counts_28d/20210216180556_incident_management_incident_todo_monthly.yml7
-rw-r--r--config/metrics/counts_28d/20210216180559_incident_management_incident_comment_monthly.yml7
-rw-r--r--config/metrics/counts_28d/20210216180603_incident_management_incident_zoom_meeting_monthly.yml7
-rw-r--r--config/metrics/counts_28d/20210216180611_incident_management_incident_relate_monthly.yml10
-rw-r--r--config/metrics/counts_28d/20210216180614_incident_management_incident_unrelate_monthly.yml7
-rw-r--r--config/metrics/counts_28d/20210216180618_incident_management_incident_change_confidential_monthly.yml7
-rw-r--r--config/metrics/counts_28d/20210216180622_incident_management_total_unique_counts_monthly.yml33
-rw-r--r--config/metrics/counts_28d/20210216180625_incident_management_alert_create_incident_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216180731_projects_imported_from_github.yml3
-rw-r--r--config/metrics/counts_28d/20210216180745_action_monthly_active_users_design_management.yml3
-rw-r--r--config/metrics/counts_28d/20210216180747_action_monthly_active_users_wiki_repo.yml3
-rw-r--r--config/metrics/counts_28d/20210216180814_events.yml14
-rw-r--r--config/metrics/counts_28d/20210216180816_groups.yml3
-rw-r--r--config/metrics/counts_28d/20210216180818_users_created.yml3
-rw-r--r--config/metrics/counts_28d/20210216180955_projects_with_prometheus_alerts.yml3
-rw-r--r--config/metrics/counts_28d/20210216180956_clusters.yml5
-rw-r--r--config/metrics/counts_28d/20210216180958_clusters_applications_prometheus.yml5
-rw-r--r--config/metrics/counts_28d/20210216181000_operations_dashboard_default_dashboard.yml5
-rw-r--r--config/metrics/counts_28d/20210216181002_projects_with_tracing_enabled.yml5
-rw-r--r--config/metrics/counts_28d/20210216181004_projects_with_error_tracking_enabled.yml5
-rw-r--r--config/metrics/counts_28d/20210216181006_operations_dashboard_users_with_projects_added.yml5
-rw-r--r--config/metrics/counts_28d/20210216181050_packages.yml3
-rw-r--r--config/metrics/counts_28d/20210216181057_projects_with_packages.yml3
-rw-r--r--config/metrics/counts_28d/20210216181139_issues.yml3
-rw-r--r--config/metrics/counts_28d/20210216181141_notes.yml3
-rw-r--r--config/metrics/counts_28d/20210216181143_projects.yml3
-rw-r--r--config/metrics/counts_28d/20210216181145_todos.yml3
-rw-r--r--config/metrics/counts_28d/20210216181147_service_desk_enabled_projects.yml7
-rw-r--r--config/metrics/counts_28d/20210216181148_service_desk_issues.yml5
-rw-r--r--config/metrics/counts_28d/20210216181150_projects_jira_active.yml5
-rw-r--r--config/metrics/counts_28d/20210216181152_projects_jira_dvcs_cloud_active.yml6
-rw-r--r--config/metrics/counts_28d/20210216181154_projects_jira_dvcs_server_active.yml7
-rw-r--r--config/metrics/counts_28d/20210216181158_epics.yml6
-rw-r--r--config/metrics/counts_28d/20210216181200_label_lists.yml3
-rw-r--r--config/metrics/counts_28d/20210216181304_g_project_management_issue_title_changed_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181308_g_project_management_issue_description_changed_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181311_g_project_management_issue_assignee_changed_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181315_g_project_management_issue_made_confidential_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181319_g_project_management_issue_made_visible_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181323_g_project_management_issue_created_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181326_g_project_management_issue_closed_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181330_g_project_management_issue_reopened_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181334_g_project_management_issue_label_changed_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181337_g_project_management_issue_milestone_changed_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181348_g_project_management_issue_cross_referenced_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181352_g_project_management_issue_moved_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181356_g_project_management_issue_related_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181400_g_project_management_issue_unrelated_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181403_g_project_management_issue_marked_as_duplicate_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181407_g_project_management_issue_locked_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181411_g_project_management_issue_unlocked_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181424_g_project_management_issue_designs_added_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181427_g_project_management_issue_designs_modified_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181431_g_project_management_issue_designs_removed_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181435_g_project_management_issue_due_date_changed_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181438_g_project_management_issue_time_estimate_changed_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181442_g_project_management_issue_time_spent_changed_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181446_g_project_management_issue_comment_added_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181450_g_project_management_issue_comment_edited_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181453_g_project_management_issue_comment_removed_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181501_g_project_management_issue_cloned_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181504_issues_edit_total_unique_counts_monthly.yml69
-rw-r--r--config/metrics/counts_28d/20210216181508_i_quickactions_approve_monthly.yml9
-rw-r--r--config/metrics/counts_28d/20210216181512_i_quickactions_assign_single_monthly.yml12
-rw-r--r--config/metrics/counts_28d/20210216181519_i_quickactions_assign_self_monthly.yml10
-rw-r--r--config/metrics/counts_28d/20210216181523_i_quickactions_assign_reviewer_monthly.yml12
-rw-r--r--config/metrics/counts_28d/20210216181527_i_quickactions_award_monthly.yml10
-rw-r--r--config/metrics/counts_28d/20210216181530_i_quickactions_board_move_monthly.yml7
-rw-r--r--config/metrics/counts_28d/20210216181541_i_quickactions_clone_monthly.yml7
-rw-r--r--config/metrics/counts_28d/20210216181545_i_quickactions_close_monthly.yml9
-rw-r--r--config/metrics/counts_28d/20210216181549_i_quickactions_confidential_monthly.yml12
-rw-r--r--config/metrics/counts_28d/20210216181553_i_quickactions_copy_metadata_merge_request_monthly.yml7
-rw-r--r--config/metrics/counts_28d/20210216181556_i_quickactions_copy_metadata_issue_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216181600_i_quickactions_create_merge_request_monthly.yml14
-rw-r--r--config/metrics/counts_28d/20210216181604_i_quickactions_done_monthly.yml9
-rw-r--r--config/metrics/counts_28d/20210216181607_i_quickactions_draft_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216181611_i_quickactions_due_monthly.yml12
-rw-r--r--config/metrics/counts_28d/20210216181615_i_quickactions_duplicate_monthly.yml14
-rw-r--r--config/metrics/counts_28d/20210216181622_i_quickactions_estimate_monthly.yml14
-rw-r--r--config/metrics/counts_28d/20210216181629_i_quickactions_label_monthly.yml9
-rw-r--r--config/metrics/counts_28d/20210216181633_i_quickactions_lock_monthly.yml13
-rw-r--r--config/metrics/counts_28d/20210216181637_i_quickactions_merge_monthly.yml9
-rw-r--r--config/metrics/counts_28d/20210216181641_i_quickactions_milestone_monthly.yml13
-rw-r--r--config/metrics/counts_28d/20210216181644_i_quickactions_move_monthly.yml7
-rw-r--r--config/metrics/counts_28d/20210216181659_i_quickactions_reassign_monthly.yml9
-rw-r--r--config/metrics/counts_28d/20210216181703_i_quickactions_reassign_reviewer_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216181707_i_quickactions_rebase_monthly.yml13
-rw-r--r--config/metrics/counts_28d/20210216181710_i_quickactions_relabel_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216181714_i_quickactions_relate_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216181721_i_quickactions_remove_due_date_monthly.yml9
-rw-r--r--config/metrics/counts_28d/20210216181729_i_quickactions_remove_estimate_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216181736_i_quickactions_remove_milestone_monthly.yml13
-rw-r--r--config/metrics/counts_28d/20210216181744_i_quickactions_remove_time_spent_monthly.yml7
-rw-r--r--config/metrics/counts_28d/20210216181747_i_quickactions_remove_zoom_monthly.yml15
-rw-r--r--config/metrics/counts_28d/20210216181751_i_quickactions_reopen_monthly.yml9
-rw-r--r--config/metrics/counts_28d/20210216181755_i_quickactions_shrug_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216181758_i_quickactions_spend_subtract_monthly.yml15
-rw-r--r--config/metrics/counts_28d/20210216181802_i_quickactions_spend_add_monthly.yml13
-rw-r--r--config/metrics/counts_28d/20210216181806_i_quickactions_submit_review_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216181809_i_quickactions_subscribe_monthly.yml13
-rw-r--r--config/metrics/counts_28d/20210216181813_i_quickactions_tableflip_monthly.yml15
-rw-r--r--config/metrics/counts_28d/20210216181817_i_quickactions_tag_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216181821_i_quickactions_target_branch_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216181824_i_quickactions_title_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216181828_i_quickactions_todo_monthly.yml13
-rw-r--r--config/metrics/counts_28d/20210216181832_i_quickactions_unassign_specific_monthly.yml9
-rw-r--r--config/metrics/counts_28d/20210216181835_i_quickactions_unassign_all_monthly.yml7
-rw-r--r--config/metrics/counts_28d/20210216181839_i_quickactions_unassign_reviewer_monthly.yml14
-rw-r--r--config/metrics/counts_28d/20210216181843_i_quickactions_unlabel_specific_monthly.yml12
-rw-r--r--config/metrics/counts_28d/20210216181846_i_quickactions_unlabel_all_monthly.yml9
-rw-r--r--config/metrics/counts_28d/20210216181850_i_quickactions_unlock_monthly.yml9
-rw-r--r--config/metrics/counts_28d/20210216181854_i_quickactions_unsubscribe_monthly.yml9
-rw-r--r--config/metrics/counts_28d/20210216181901_i_quickactions_wip_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216181905_i_quickactions_zoom_monthly.yml13
-rw-r--r--config/metrics/counts_28d/20210216181923_successful_deployments.yml4
-rw-r--r--config/metrics/counts_28d/20210216181924_failed_deployments.yml4
-rw-r--r--config/metrics/counts_28d/20210216181935_deployments.yml4
-rw-r--r--config/metrics/counts_28d/20210216181937_failed_deployments.yml4
-rw-r--r--config/metrics/counts_28d/20210216181939_releases.yml4
-rw-r--r--config/metrics/counts_28d/20210216181941_successful_deployments.yml4
-rw-r--r--config/metrics/counts_28d/20210216181951_clusters_applications_runner.yml6
-rw-r--r--config/metrics/counts_28d/20210216181956_user_unique_users_all_secure_scanners.yml19
-rw-r--r--config/metrics/counts_28d/20210216182034_deploy_keys.yml3
-rw-r--r--config/metrics/counts_28d/20210216182036_keys.yml3
-rw-r--r--config/metrics/counts_28d/20210216182038_remote_mirrors.yml6
-rw-r--r--config/metrics/counts_28d/20210216182040_action_monthly_active_users_project_repo.yml3
-rw-r--r--config/metrics/counts_28d/20210216182041_action_monthly_active_users_git_write.yml3
-rw-r--r--config/metrics/counts_28d/20210216182051_protected_branches.yml6
-rw-r--r--config/metrics/counts_28d/20210216182102_wiki_action_monthly.yml3
-rw-r--r--config/metrics/counts_28d/20210216182106_design_action_monthly.yml3
-rw-r--r--config/metrics/counts_28d/20210216182109_project_action_monthly.yml6
-rw-r--r--config/metrics/counts_28d/20210216182125_user_sast_jobs.yml3
-rw-r--r--config/metrics/counts_28d/20210216182127_user_secret_detection_jobs.yml3
-rw-r--r--config/metrics/counts_28d/20210216182129_sast_pipeline.yml3
-rw-r--r--config/metrics/counts_28d/20210216182131_secret_detection_pipeline.yml3
-rw-r--r--config/metrics/counts_28d/20210216182136_i_testing_test_case_parsed_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216183159_projects_with_alerts_created.yml5
-rw-r--r--config/metrics/counts_28d/20210216183627_omniauth_providers.yml3
-rw-r--r--config/metrics/counts_28d/20210216183629_two-factor.yml18
-rw-r--r--config/metrics/counts_28d/20210216183631_two-factor-via-u2f-device.yml18
-rw-r--r--config/metrics/counts_28d/20210216183633_two-factor-via-webauthn-device.yml18
-rw-r--r--config/metrics/counts_28d/20210216183634_standard.yml19
-rw-r--r--config/metrics/counts_28d/20210216183636_google_oauth2.yml19
-rw-r--r--config/metrics/counts_28d/20210216183638_unique_users_all_imports.yml3
-rw-r--r--config/metrics/counts_28d/20210216183640_gitlab.yml1
-rw-r--r--config/metrics/counts_28d/20210216183642_gitlab_v1.yml3
-rw-r--r--config/metrics/counts_28d/20210216183644_gitlab_project.yml3
-rw-r--r--config/metrics/counts_28d/20210216183646_gitlab.yml3
-rw-r--r--config/metrics/counts_28d/20210216183648_github.yml3
-rw-r--r--config/metrics/counts_28d/20210216183650_bitbucket.yml3
-rw-r--r--config/metrics/counts_28d/20210216183652_bitbucket_server.yml3
-rw-r--r--config/metrics/counts_28d/20210216183653_gitea.yml3
-rw-r--r--config/metrics/counts_28d/20210216183655_git.yml3
-rw-r--r--config/metrics/counts_28d/20210216183657_manifest.yml3
-rw-r--r--config/metrics/counts_28d/20210216183659_gitlab_migration.yml3
-rw-r--r--config/metrics/counts_28d/20210216183701_jira.yml3
-rw-r--r--config/metrics/counts_28d/20210216183703_fogbugz.yml3
-rw-r--r--config/metrics/counts_28d/20210216183705_phabricator.yml3
-rw-r--r--config/metrics/counts_28d/20210216183707_csv.yml3
-rw-r--r--config/metrics/counts_28d/20210216183709_group_import.yml13
-rw-r--r--config/metrics/counts_28d/20210216183711_gitlab_migration.yml3
-rw-r--r--config/metrics/counts_28d/20210216183712_total.yml1
-rw-r--r--config/metrics/counts_28d/20210216183714_gitlab_project.yml1
-rw-r--r--config/metrics/counts_28d/20210216183716_gitlab.yml1
-rw-r--r--config/metrics/counts_28d/20210216183718_github.yml1
-rw-r--r--config/metrics/counts_28d/20210216183720_bitbucket.yml1
-rw-r--r--config/metrics/counts_28d/20210216183722_bitbucket_server.yml1
-rw-r--r--config/metrics/counts_28d/20210216183724_gitea.yml1
-rw-r--r--config/metrics/counts_28d/20210216183726_git.yml1
-rw-r--r--config/metrics/counts_28d/20210216183728_manifest.yml1
-rw-r--r--config/metrics/counts_28d/20210216183730_jira.yml1
-rw-r--r--config/metrics/counts_28d/20210216183731_fogbugz.yml1
-rw-r--r--config/metrics/counts_28d/20210216183733_phabricator.yml1
-rw-r--r--config/metrics/counts_28d/20210216183735_csv.yml1
-rw-r--r--config/metrics/counts_28d/20210216183737_groups_imported.yml1
-rw-r--r--config/metrics/counts_28d/20210216183826_sast_scans.yml18
-rw-r--r--config/metrics/counts_28d/20210216183830_container_scanning_scans.yml18
-rw-r--r--config/metrics/counts_28d/20210216183834_secret_detection_scans.yml18
-rw-r--r--config/metrics/counts_28d/20210216183922_search_unique_visits_for_any_target_monthly.yml14
-rw-r--r--config/metrics/counts_28d/20210216184024_g_edit_by_sse_monthly.yml3
-rw-r--r--config/metrics/counts_28d/20210216184047_git_write_action_monthly.yml3
-rw-r--r--config/metrics/counts_28d/20210216184140_testing_total_unique_counts_monthly.yml33
-rw-r--r--config/metrics/counts_28d/20210216184255_i_snippets_show_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216184259_p_terraform_state_api_unique_users_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216184303_o_pipeline_authoring_unique_users_committing_ciconfigfile_monthly.yml8
-rw-r--r--config/metrics/counts_28d/20210216184312_i_code_review_user_toggled_task_item_status_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216184322_i_code_review_user_approve_mr_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216184326_i_code_review_user_unapprove_mr_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216184330_i_code_review_user_resolve_thread_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216184334_i_code_review_user_unresolve_thread_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216184338_i_code_review_edit_mr_title_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216184342_i_code_review_edit_mr_desc_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216184353_i_code_review_user_create_review_note_monthly.yml8
-rw-r--r--config/metrics/counts_28d/20210216184357_i_code_review_user_publish_review_monthly.yml8
-rw-r--r--config/metrics/counts_28d/20210216184401_i_code_review_user_create_multiline_mr_comment_monthly.yml8
-rw-r--r--config/metrics/counts_28d/20210216184405_i_code_review_user_edit_multiline_mr_comment_monthly.yml8
-rw-r--r--config/metrics/counts_28d/20210216184409_i_code_review_user_remove_multiline_mr_comment_monthly.yml14
-rw-r--r--config/metrics/counts_28d/20210216184418_i_code_review_user_assigned_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216184422_i_code_review_user_marked_as_draft_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216184426_i_code_review_user_unmarked_as_draft_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216184430_i_code_review_user_review_requested_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216184434_i_code_review_user_approval_rule_added_monthly.yml11
-rw-r--r--config/metrics/counts_28d/20210216184438_i_code_review_user_approval_rule_deleted_monthly.yml14
-rw-r--r--config/metrics/counts_28d/20210216184442_i_code_review_user_approval_rule_edited_monthly.yml14
-rw-r--r--config/metrics/counts_28d/20210216184446_i_code_review_user_vs_code_api_request_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216184450_i_code_review_user_create_mr_from_issue_monthly.yml15
-rw-r--r--config/metrics/counts_28d/20210216184454_code_review_total_unique_counts_monthly.yml115
-rw-r--r--config/metrics/counts_28d/20210216184458_p_ci_templates_implicit_auto_devops_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216184502_p_ci_templates_implicit_auto_devops_build_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216184506_p_ci_templates_implicit_auto_devops_deploy_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216184510_p_ci_templates_implicit_security_sast_monthly.yml19
-rw-r--r--config/metrics/counts_28d/20210216184513_p_ci_templates_implicit_security_secret_detection_monthly.yml19
-rw-r--r--config/metrics/counts_28d/20210216184517_p_ci_templates_5_min_production_app_monthly.yml7
-rw-r--r--config/metrics/counts_28d/20210216184523_p_ci_templates_auto_devops_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216184526_p_ci_templates_aws_cf_deploy_ec2_monthly.yml10
-rw-r--r--config/metrics/counts_28d/20210216184530_p_ci_templates_aws_deploy_ecs_monthly.yml10
-rw-r--r--config/metrics/counts_28d/20210216184534_p_ci_templates_auto_devops_build_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216184538_p_ci_templates_auto_devops_deploy_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216184542_p_ci_templates_auto_devops_deploy_latest_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216184546_p_ci_templates_security_sast_monthly.yml19
-rw-r--r--config/metrics/counts_28d/20210216184551_p_ci_templates_security_secret_detection_monthly.yml19
-rw-r--r--config/metrics/counts_28d/20210216184555_p_ci_templates_terraform_base_latest_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216184559_ci_templates_total_unique_counts_monthly.yml163
-rw-r--r--config/metrics/counts_28d/20210216184803_quickactions_total_unique_counts_monthly.yml149
-rw-r--r--config/metrics/counts_28d/20210216184806_i_package_composer_deploy_token_monthly.yml8
-rw-r--r--config/metrics/counts_28d/20210216184810_i_package_conan_deploy_token_monthly.yml8
-rw-r--r--config/metrics/counts_28d/20210216184814_i_package_container_deploy_token_monthly.yml6
-rw-r--r--config/metrics/counts_28d/20210216184818_i_package_debian_deploy_token_monthly.yml6
-rw-r--r--config/metrics/counts_28d/20210216184822_i_package_generic_deploy_token_monthly.yml6
-rw-r--r--config/metrics/counts_28d/20210216184826_i_package_golang_deploy_token_monthly.yml6
-rw-r--r--config/metrics/counts_28d/20210216184830_i_package_maven_deploy_token_monthly.yml8
-rw-r--r--config/metrics/counts_28d/20210216184834_i_package_npm_deploy_token_monthly.yml8
-rw-r--r--config/metrics/counts_28d/20210216184838_i_package_nuget_deploy_token_monthly.yml8
-rw-r--r--config/metrics/counts_28d/20210216184842_i_package_pypi_deploy_token_monthly.yml8
-rw-r--r--config/metrics/counts_28d/20210216184846_i_package_tag_deploy_token_monthly.yml6
-rw-r--r--config/metrics/counts_28d/20210216184850_deploy_token_packages_total_unique_counts_monthly.yml34
-rw-r--r--config/metrics/counts_28d/20210216184854_i_package_composer_user_monthly.yml8
-rw-r--r--config/metrics/counts_28d/20210216184858_i_package_conan_user_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216184902_i_package_container_user_monthly.yml6
-rw-r--r--config/metrics/counts_28d/20210216184906_i_package_debian_user_monthly.yml6
-rw-r--r--config/metrics/counts_28d/20210216184910_i_package_generic_user_monthly.yml6
-rw-r--r--config/metrics/counts_28d/20210216184913_i_package_golang_user_monthly.yml3
-rw-r--r--config/metrics/counts_28d/20210216184917_i_package_maven_user_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216184921_i_package_npm_user_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216184925_i_package_nuget_user_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216184929_i_package_pypi_user_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216184933_i_package_tag_user_monthly.yml3
-rw-r--r--config/metrics/counts_28d/20210216184937_user_packages_total_unique_counts_monthly.yml31
-rw-r--r--config/metrics/counts_28d/20210216184941_i_ecosystem_jira_service_close_issue_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216184945_i_ecosystem_jira_service_cross_reference_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20210216184957_ecosystem_total_unique_counts_monthly.yml30
-rw-r--r--config/metrics/counts_28d/20210222041219_i_quickactions_invite_email_single_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210222041235_i_quickactions_invite_email_multiple_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210301102134_i_code_review_user_time_estimate_changed_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210301102204_i_code_review_user_time_spent_changed_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210301103859_i_code_review_user_mr_discussion_locked_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210301103925_i_code_review_user_mr_discussion_unlocked_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210301144228_o_pipeline_authoring_unique_users_pushing_mr_ciconfigfile_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210302110520_i_code_review_user_milestone_changed_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210302110607_i_code_review_user_labels_changed_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210302114145_i_code_review_user_assignees_changed_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210302114219_i_code_review_user_reviewers_changed_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210303150507_i_ecosystem_slack_service_issue_notification_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210303150654_i_ecosystem_slack_service_push_notification_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210303150912_i_ecosystem_slack_service_deployment_notification_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210303151609_i_ecosystem_slack_service_wiki_page_notification_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210303151831_i_ecosystem_slack_service_merge_request_notification_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210303151946_i_ecosystem_slack_service_note_notification_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210303152049_i_ecosystem_slack_service_tag_push_notification_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210303152144_i_ecosystem_slack_service_confidential_note_notification_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210303152233_i_ecosystem_slack_service_confidential_issue_notification_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210303154626_i_package_rubygems_deploy_token_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210303154654_i_package_rubygems_user_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210409095855_users_expanding_secure_security_report_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210409100451_users_expanding_testing_code_quality_report_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210409100628_users_expanding_testing_accessibility_report_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210410012206_i_package_terraform_module_deploy_token_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210410012208_i_package_terraform_module_user_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210413205507_i_testing_summary_widget_total_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210421144352_i_code_review_click_single_file_mode_setting_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210421145818_i_code_review_click_file_browser_setting_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210421145945_i_code_review_click_whitespace_setting_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210422101516_i_code_review_diff_view_inline_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210422101613_i_code_review_diff_view_parallel_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210422101753_i_code_review_file_browser_tree_view_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210422101852_i_code_review_file_browser_list_view_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210422101928_i_code_review_diff_show_whitespace_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210422102010_i_code_review_diff_hide_whitespace_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210422102121_i_code_review_diff_single_file_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210422102202_i_code_review_diff_multiple_files_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210427102618_code_review_category_monthly_active_users.yml15
-rw-r--r--config/metrics/counts_28d/20210427103010_code_review_extension_category_monthly_active_users.yml16
-rw-r--r--config/metrics/counts_28d/20210427103119_code_review_group_monthly_active_users.yml16
-rw-r--r--config/metrics/counts_28d/20210427105033_pipeline_authoring_total_unique_counts_monthly.yml14
-rw-r--r--config/metrics/counts_28d/20210427213346_geo_secondary_web_oauth_users.yml26
-rw-r--r--config/metrics/counts_28d/20210514013545_i_code_review_user_resolve_conflict_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210514013549_i_code_review_user_load_conflict_ui_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210514141518_monthly_projects_creation.yml2
-rw-r--r--config/metrics/counts_28d/20210517074859_i_package_helm_deploy_token_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210517075259_i_package_helm_user_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210520111133_total.yml2
-rw-r--r--config/metrics/counts_28d/20210607113556_i_code_review_click_diff_view_setting_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210720144005_i_code_review_user_searches_diff_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210721042227_i_quickactions_severity_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210816143831_i_code_review_total_suggestions_added_monthly.yml27
-rw-r--r--config/metrics/counts_28d/20210816144453_i_code_review_total_suggestions_applied_monthly.yml27
-rw-r--r--config/metrics/counts_28d/20210901221242_p_ci_templates_terraform_base_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221251_p_ci_templates_dotnet_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221300_p_ci_templates_nodejs_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221308_p_ci_templates_openshift_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221317_p_ci_templates_bash_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221326_p_ci_templates_rust_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221335_p_ci_templates_elixir_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221343_p_ci_templates_clojure_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221352_p_ci_templates_crystal_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221401_p_ci_templates_getting_started_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221410_p_ci_templates_code_quality_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221418_p_ci_templates_verify_load_performance_testing_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221427_p_ci_templates_verify_accessibility_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221436_p_ci_templates_verify_failfast_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221445_p_ci_templates_verify_browser_performance_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221454_p_ci_templates_verify_browser_performance_latest_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221503_p_ci_templates_grails_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221511_p_ci_templates_security_dast_runner_validation_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221520_p_ci_templates_security_dast_on_demand_scan_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221529_p_ci_templates_security_license_scanning_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221538_p_ci_templates_security_coverage_fuzzing_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221547_p_ci_templates_security_api_fuzzing_latest_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221556_p_ci_templates_security_secure_binaries_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221605_p_ci_templates_security_dast_api_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221614_p_ci_templates_security_container_scanning_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221623_p_ci_templates_security_dast_latest_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221632_p_ci_templates_security_dependency_scanning_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221641_p_ci_templates_security_api_fuzzing_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221650_p_ci_templates_security_dast_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221659_p_ci_templates_security_cluster_image_scanning_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221708_p_ci_templates_ios_fastlane_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221717_p_ci_templates_composer_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221726_p_ci_templates_c_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221735_p_ci_templates_python_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221744_p_ci_templates_android_fastlane_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221754_p_ci_templates_django_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221803_p_ci_templates_maven_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221812_p_ci_templates_flutter_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221822_p_ci_templates_workflows_branch_pipelines_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221831_p_ci_templates_workflows_mergerequest_pipelines_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221840_p_ci_templates_laravel_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221849_p_ci_templates_managed_cluster_applications_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221857_p_ci_templates_php_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221906_p_ci_templates_packer_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221915_p_ci_templates_terraform_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221923_p_ci_templates_mono_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221932_p_ci_templates_serverless_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221941_p_ci_templates_go_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221950_p_ci_templates_scala_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901221958_p_ci_templates_latex_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222007_p_ci_templates_android_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222016_p_ci_templates_indeni_cloudrail_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222025_p_ci_templates_deploy_ecs_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222033_p_ci_templates_aws_cf_provision_and_deploy_ec2_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222042_p_ci_templates_gradle_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222051_p_ci_templates_chef_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222100_p_ci_templates_jobs_dast_default_branch_deploy_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222108_p_ci_templates_jobs_load_performance_testing_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222117_p_ci_templates_jobs_helm_2to3_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222126_p_ci_templates_jobs_sast_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222135_p_ci_templates_jobs_secret_detection_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222144_p_ci_templates_jobs_code_intelligence_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222153_p_ci_templates_jobs_code_quality_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222202_p_ci_templates_jobs_deploy_ecs_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222211_p_ci_templates_jobs_deploy_ec2_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222220_p_ci_templates_jobs_deploy_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222229_p_ci_templates_jobs_build_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222237_p_ci_templates_jobs_browser_performance_testing_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222246_p_ci_templates_jobs_test_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222256_p_ci_templates_jobs_deploy_latest_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222304_p_ci_templates_jobs_browser_performance_testing_latest_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222313_p_ci_templates_jobs_cf_provision_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222322_p_ci_templates_jobs_build_latest_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222331_p_ci_templates_terraform_latest_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222341_p_ci_templates_swift_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222707_p_ci_templates_pages_jekyll_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901222742_p_ci_templates_pages_harp_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223200_p_ci_templates_pages_octopress_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223210_p_ci_templates_pages_brunch_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223219_p_ci_templates_pages_doxygen_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223227_p_ci_templates_pages_hyde_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223236_p_ci_templates_pages_lektor_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223244_p_ci_templates_pages_jbake_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223253_p_ci_templates_pages_hexo_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223302_p_ci_templates_pages_middleman_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223311_p_ci_templates_pages_hugo_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223319_p_ci_templates_pages_pelican_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223328_p_ci_templates_pages_nanoc_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223337_p_ci_templates_pages_swaggerui_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223346_p_ci_templates_pages_jigsaw_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223354_p_ci_templates_pages_metalsmith_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223403_p_ci_templates_pages_gatsby_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223412_p_ci_templates_pages_html_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223421_p_ci_templates_dart_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223430_p_ci_templates_docker_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223439_p_ci_templates_julia_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223447_p_ci_templates_npm_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223456_p_ci_templates_dotnet_core_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223505_p_ci_templates_5_minute_production_app_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223514_p_ci_templates_ruby_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223523_p_ci_templates_implicit_jobs_dast_default_branch_deploy_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223532_p_ci_templates_implicit_jobs_load_performance_testing_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223541_p_ci_templates_implicit_jobs_helm_2to3_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223550_p_ci_templates_implicit_jobs_sast_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223559_p_ci_templates_implicit_jobs_secret_detection_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223608_p_ci_templates_implicit_jobs_code_intelligence_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223617_p_ci_templates_implicit_jobs_code_quality_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223626_p_ci_templates_implicit_jobs_deploy_ecs_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223635_p_ci_templates_implicit_jobs_deploy_ec2_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223644_p_ci_templates_implicit_jobs_browser_performance_testing_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223653_p_ci_templates_implicit_jobs_test_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223702_p_ci_templates_implicit_jobs_browser_performance_testing_latest_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223711_p_ci_templates_implicit_jobs_cf_provision_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223721_p_ci_templates_implicit_jobs_build_latest_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223730_p_ci_templates_implicit_security_dast_runner_validation_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223739_p_ci_templates_implicit_security_dast_on_demand_scan_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223748_p_ci_templates_implicit_security_license_scanning_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223758_p_ci_templates_implicit_security_coverage_fuzzing_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223806_p_ci_templates_implicit_security_api_fuzzing_latest_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223815_p_ci_templates_implicit_security_secure_binaries_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223824_p_ci_templates_implicit_security_dast_api_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223832_p_ci_templates_implicit_security_container_scanning_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223841_p_ci_templates_implicit_security_dast_latest_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223850_p_ci_templates_implicit_security_dependency_scanning_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223858_p_ci_templates_implicit_security_api_fuzzing_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223907_p_ci_templates_implicit_security_dast_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210901223916_p_ci_templates_implicit_security_cluster_image_scanning_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210902000813_p_ci_templates_implicit_auto_devops_deploy_latest_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210902191057_i_quickactions_unapprove_monthly.yml28
-rw-r--r--config/metrics/counts_28d/20210908093509_p_ci_templates_android_latest_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20210908150458_i_code_review_user_resolve_thread_in_issue_monthly.yml27
-rw-r--r--config/metrics/counts_28d/20210910132229_user_auth_by_provider.yml24
-rw-r--r--config/metrics/counts_28d/20210916080405_promoted_issues.yml23
-rw-r--r--config/metrics/counts_7d/20210201124931_g_project_management_issue_title_changed_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210216175010_i_analytics_instance_statistics_weekly.yml14
-rw-r--r--config/metrics/counts_7d/20210216175014_analytics_total_unique_counts_weekly.yml46
-rw-r--r--config/metrics/counts_7d/20210216175111_merge_request_action_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216175114_i_source_code_code_intelligence_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216175118_i_code_review_mr_diffs_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216175122_i_code_review_user_single_file_diffs_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216175126_i_code_review_mr_single_file_diffs_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216175130_i_code_review_user_create_mr_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216175134_i_code_review_user_close_mr_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216175138_i_code_review_user_reopen_mr_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216175142_i_code_review_user_merge_mr_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216175146_i_code_review_user_create_mr_comment_weekly.yml9
-rw-r--r--config/metrics/counts_7d/20210216175150_i_code_review_user_edit_mr_comment_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216175154_i_code_review_user_remove_mr_comment_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216175158_i_code_review_user_add_suggestion_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216175201_i_code_review_user_apply_suggestion_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216180328_g_edit_by_web_ide_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216180332_g_edit_by_sfe_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216180336_g_edit_by_snippet_ide_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216180339_ide_edit_total_unique_counts_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216180422_i_search_total_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216180429_search_total_unique_counts_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216180513_incident_management_alerts_total_unique_counts.yml3
-rw-r--r--config/metrics/counts_7d/20210216180515_incident_management_incidents_total_unique_counts.yml3
-rw-r--r--config/metrics/counts_7d/20210216180528_incident_management_alert_status_changed_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216180532_incident_management_alert_assigned_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216180535_incident_management_alert_todo_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216180539_incident_management_incident_created_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216180543_incident_management_incident_reopened_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216180546_incident_management_incident_closed_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216180550_incident_management_incident_assigned_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216180554_incident_management_incident_todo_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216180558_incident_management_incident_comment_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216180601_incident_management_incident_zoom_meeting_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216180609_incident_management_incident_relate_weekly.yml8
-rw-r--r--config/metrics/counts_7d/20210216180612_incident_management_incident_unrelate_weekly.yml8
-rw-r--r--config/metrics/counts_7d/20210216180616_incident_management_incident_change_confidential_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216180620_incident_management_total_unique_counts_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216180623_incident_management_alert_create_incident_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181306_g_project_management_issue_description_changed_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181310_g_project_management_issue_assignee_changed_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181313_g_project_management_issue_made_confidential_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181317_g_project_management_issue_made_visible_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181321_g_project_management_issue_created_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181324_g_project_management_issue_closed_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181328_g_project_management_issue_reopened_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181332_g_project_management_issue_label_changed_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181336_g_project_management_issue_milestone_changed_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181347_g_project_management_issue_cross_referenced_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181350_g_project_management_issue_moved_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181354_g_project_management_issue_related_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181358_g_project_management_issue_unrelated_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181401_g_project_management_issue_marked_as_duplicate_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181405_g_project_management_issue_locked_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181409_g_project_management_issue_unlocked_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181422_g_project_management_issue_designs_added_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181425_g_project_management_issue_designs_modified_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181429_g_project_management_issue_designs_removed_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181433_g_project_management_issue_due_date_changed_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181437_g_project_management_issue_time_estimate_changed_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181440_g_project_management_issue_time_spent_changed_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181444_g_project_management_issue_comment_added_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181448_g_project_management_issue_comment_edited_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181451_g_project_management_issue_comment_removed_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181459_g_project_management_issue_cloned_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181503_issues_edit_total_unique_counts_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216181506_i_quickactions_approve_weekly.yml9
-rw-r--r--config/metrics/counts_7d/20210216181510_i_quickactions_assign_single_weekly.yml13
-rw-r--r--config/metrics/counts_7d/20210216181517_i_quickactions_assign_self_weekly.yml12
-rw-r--r--config/metrics/counts_7d/20210216181521_i_quickactions_assign_reviewer_weekly.yml13
-rw-r--r--config/metrics/counts_7d/20210216181525_i_quickactions_award_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216181529_i_quickactions_board_move_weekly.yml7
-rw-r--r--config/metrics/counts_7d/20210216181540_i_quickactions_clone_weekly.yml7
-rw-r--r--config/metrics/counts_7d/20210216181543_i_quickactions_close_weekly.yml9
-rw-r--r--config/metrics/counts_7d/20210216181547_i_quickactions_confidential_weekly.yml12
-rw-r--r--config/metrics/counts_7d/20210216181551_i_quickactions_copy_metadata_merge_request_weekly.yml8
-rw-r--r--config/metrics/counts_7d/20210216181554_i_quickactions_copy_metadata_issue_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216181558_i_quickactions_create_merge_request_weekly.yml14
-rw-r--r--config/metrics/counts_7d/20210216181602_i_quickactions_done_weekly.yml9
-rw-r--r--config/metrics/counts_7d/20210216181605_i_quickactions_draft_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216181609_i_quickactions_due_weekly.yml13
-rw-r--r--config/metrics/counts_7d/20210216181613_i_quickactions_duplicate_weekly.yml14
-rw-r--r--config/metrics/counts_7d/20210216181620_i_quickactions_estimate_weekly.yml16
-rw-r--r--config/metrics/counts_7d/20210216181628_i_quickactions_label_weekly.yml9
-rw-r--r--config/metrics/counts_7d/20210216181631_i_quickactions_lock_weekly.yml15
-rw-r--r--config/metrics/counts_7d/20210216181635_i_quickactions_merge_weekly.yml9
-rw-r--r--config/metrics/counts_7d/20210216181639_i_quickactions_milestone_weekly.yml13
-rw-r--r--config/metrics/counts_7d/20210216181642_i_quickactions_move_weekly.yml7
-rw-r--r--config/metrics/counts_7d/20210216181657_i_quickactions_reassign_weekly.yml9
-rw-r--r--config/metrics/counts_7d/20210216181701_i_quickactions_reassign_reviewer_weekly.yml6
-rw-r--r--config/metrics/counts_7d/20210216181705_i_quickactions_rebase_weekly.yml13
-rw-r--r--config/metrics/counts_7d/20210216181708_i_quickactions_relabel_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216181712_i_quickactions_relate_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216181719_i_quickactions_remove_due_date_weekly.yml9
-rw-r--r--config/metrics/counts_7d/20210216181727_i_quickactions_remove_estimate_weekly.yml13
-rw-r--r--config/metrics/counts_7d/20210216181734_i_quickactions_remove_milestone_weekly.yml14
-rw-r--r--config/metrics/counts_7d/20210216181742_i_quickactions_remove_time_spent_weekly.yml7
-rw-r--r--config/metrics/counts_7d/20210216181745_i_quickactions_remove_zoom_weekly.yml15
-rw-r--r--config/metrics/counts_7d/20210216181749_i_quickactions_reopen_weekly.yml9
-rw-r--r--config/metrics/counts_7d/20210216181753_i_quickactions_shrug_weekly.yml12
-rw-r--r--config/metrics/counts_7d/20210216181756_i_quickactions_spend_subtract_weekly.yml13
-rw-r--r--config/metrics/counts_7d/20210216181800_i_quickactions_spend_add_weekly.yml14
-rw-r--r--config/metrics/counts_7d/20210216181804_i_quickactions_submit_review_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216181808_i_quickactions_subscribe_weekly.yml14
-rw-r--r--config/metrics/counts_7d/20210216181811_i_quickactions_tableflip_weekly.yml13
-rw-r--r--config/metrics/counts_7d/20210216181815_i_quickactions_tag_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216181819_i_quickactions_target_branch_weekly.yml13
-rw-r--r--config/metrics/counts_7d/20210216181822_i_quickactions_title_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216181826_i_quickactions_todo_weekly.yml13
-rw-r--r--config/metrics/counts_7d/20210216181830_i_quickactions_unassign_specific_weekly.yml9
-rw-r--r--config/metrics/counts_7d/20210216181833_i_quickactions_unassign_all_weekly.yml9
-rw-r--r--config/metrics/counts_7d/20210216181837_i_quickactions_unassign_reviewer_weekly.yml14
-rw-r--r--config/metrics/counts_7d/20210216181841_i_quickactions_unlabel_specific_weekly.yml12
-rw-r--r--config/metrics/counts_7d/20210216181845_i_quickactions_unlabel_all_weekly.yml10
-rw-r--r--config/metrics/counts_7d/20210216181848_i_quickactions_unlock_weekly.yml9
-rw-r--r--config/metrics/counts_7d/20210216181852_i_quickactions_unsubscribe_weekly.yml9
-rw-r--r--config/metrics/counts_7d/20210216181859_i_quickactions_wip_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216181903_i_quickactions_zoom_weekly.yml15
-rw-r--r--config/metrics/counts_7d/20210216182100_wiki_action_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216182104_design_action_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216182107_project_action_weekly.yml6
-rw-r--r--config/metrics/counts_7d/20210216182134_i_testing_test_case_parsed_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216184022_g_edit_by_sse_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216184045_git_write_action_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216184253_i_snippets_show_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216184257_p_terraform_state_api_unique_users_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210216184301_o_pipeline_authoring_unique_users_committing_ciconfigfile_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216184310_i_code_review_user_toggled_task_item_status_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216184320_i_code_review_user_approve_mr_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216184324_i_code_review_user_unapprove_mr_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216184328_i_code_review_user_resolve_thread_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216184332_i_code_review_user_unresolve_thread_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216184336_i_code_review_edit_mr_title_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216184340_i_code_review_edit_mr_desc_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216184351_i_code_review_user_create_review_note_weekly.yml8
-rw-r--r--config/metrics/counts_7d/20210216184355_i_code_review_user_publish_review_weekly.yml8
-rw-r--r--config/metrics/counts_7d/20210216184359_i_code_review_user_create_multiline_mr_comment_weekly.yml8
-rw-r--r--config/metrics/counts_7d/20210216184403_i_code_review_user_edit_multiline_mr_comment_weekly.yml8
-rw-r--r--config/metrics/counts_7d/20210216184407_i_code_review_user_remove_multiline_mr_comment_weekly.yml14
-rw-r--r--config/metrics/counts_7d/20210216184416_i_code_review_user_assigned_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216184420_i_code_review_user_marked_as_draft_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216184424_i_code_review_user_unmarked_as_draft_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216184428_i_code_review_user_review_requested_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216184432_i_code_review_user_approval_rule_added_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216184436_i_code_review_user_approval_rule_deleted_weekly.yml14
-rw-r--r--config/metrics/counts_7d/20210216184440_i_code_review_user_approval_rule_edited_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216184444_i_code_review_user_vs_code_api_request_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216184448_i_code_review_user_create_mr_from_issue_weekly.yml11
-rw-r--r--config/metrics/counts_7d/20210216184452_code_review_total_unique_counts_weekly.yml115
-rw-r--r--config/metrics/counts_7d/20210216184456_p_ci_templates_implicit_auto_devops_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210216184500_p_ci_templates_implicit_auto_devops_build_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210216184504_p_ci_templates_implicit_auto_devops_deploy_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210216184508_p_ci_templates_implicit_security_sast_weekly.yml26
-rw-r--r--config/metrics/counts_7d/20210216184512_p_ci_templates_implicit_security_secret_detection_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210216184515_p_ci_templates_5_min_production_app_weekly.yml8
-rw-r--r--config/metrics/counts_7d/20210216184520_p_ci_templates_auto_devops_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210216184524_p_ci_templates_aws_cf_deploy_ec2_weekly.yml10
-rw-r--r--config/metrics/counts_7d/20210216184528_p_ci_templates_aws_deploy_ecs_weekly.yml10
-rw-r--r--config/metrics/counts_7d/20210216184536_p_ci_templates_auto_devops_deploy_weekly.yml27
-rw-r--r--config/metrics/counts_7d/20210216184540_p_ci_templates_auto_devops_deploy_latest_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210216184544_p_ci_templates_security_sast_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210216184549_p_ci_templates_security_secret_detection_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210216184553_p_ci_templates_terraform_base_latest_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210216184557_ci_templates_total_unique_counts_weekly.yml163
-rw-r--r--config/metrics/counts_7d/20210216184801_quickactions_total_unique_counts_weekly.yml92
-rw-r--r--config/metrics/counts_7d/20210216184805_i_package_composer_deploy_token_weekly.yml6
-rw-r--r--config/metrics/counts_7d/20210216184808_i_package_conan_deploy_token_weekly.yml8
-rw-r--r--config/metrics/counts_7d/20210216184812_i_package_container_deploy_token_weekly.yml6
-rw-r--r--config/metrics/counts_7d/20210216184816_i_package_debian_deploy_token_weekly.yml6
-rw-r--r--config/metrics/counts_7d/20210216184820_i_package_generic_deploy_token_weekly.yml8
-rw-r--r--config/metrics/counts_7d/20210216184824_i_package_golang_deploy_token_weekly.yml6
-rw-r--r--config/metrics/counts_7d/20210216184828_i_package_maven_deploy_token_weekly.yml8
-rw-r--r--config/metrics/counts_7d/20210216184832_i_package_npm_deploy_token_weekly.yml8
-rw-r--r--config/metrics/counts_7d/20210216184836_i_package_nuget_deploy_token_weekly.yml8
-rw-r--r--config/metrics/counts_7d/20210216184840_i_package_pypi_deploy_token_weekly.yml8
-rw-r--r--config/metrics/counts_7d/20210216184844_i_package_tag_deploy_token_weekly.yml6
-rw-r--r--config/metrics/counts_7d/20210216184848_deploy_token_packages_total_unique_counts_weekly.yml31
-rw-r--r--config/metrics/counts_7d/20210216184852_i_package_composer_user_weekly.yml8
-rw-r--r--config/metrics/counts_7d/20210216184856_i_package_conan_user_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216184900_i_package_container_user_weekly.yml6
-rw-r--r--config/metrics/counts_7d/20210216184904_i_package_debian_user_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216184908_i_package_generic_user_weekly.yml6
-rw-r--r--config/metrics/counts_7d/20210216184911_i_package_golang_user_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20210216184916_i_package_maven_user_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216184919_i_package_npm_user_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216184923_i_package_nuget_user_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216184927_i_package_pypi_user_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216184931_i_package_tag_user_weekly.yml6
-rw-r--r--config/metrics/counts_7d/20210216184935_user_packages_total_unique_counts_weekly.yml31
-rw-r--r--config/metrics/counts_7d/20210216184939_i_ecosystem_jira_service_close_issue_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216184943_i_ecosystem_jira_service_cross_reference_weekly.yml5
-rw-r--r--config/metrics/counts_7d/20210216184955_ecosystem_total_unique_counts_weekly.yml29
-rw-r--r--config/metrics/counts_7d/20210301144209_o_pipeline_authoring_unique_users_pushing_mr_ciconfigfile_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210302103002_i_ecosystem_slack_service_issue_notification_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210302103539_i_code_review_user_time_estimate_changed_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210302103615_i_code_review_user_time_spent_changed_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210302103629_i_ecosystem_slack_service_push_notification_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210302103755_i_ecosystem_slack_service_deployment_notification_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210302103907_i_ecosystem_slack_service_wiki_page_notification_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210302104007_i_ecosystem_slack_service_merge_request_notification_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210302104047_i_ecosystem_slack_service_note_notification_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210302104144_i_ecosystem_slack_service_tag_push_notification_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210302104556_i_ecosystem_slack_service_confidential_note_notification_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210302104814_i_ecosystem_slack_service_confidential_issue_notification_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210302105258_i_code_review_user_mr_discussion_unlocked_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210302105318_i_code_review_user_mr_discussion_locked_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210302110403_i_code_review_user_milestone_changed_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210302110548_i_code_review_user_labels_changed_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210302114202_i_code_review_user_assignees_changed_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210302114235_i_code_review_user_reviewers_changed_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210303154557_i_quickactions_invite_email_single_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210303154600_i_quickactions_invite_email_multiple_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210303154624_i_package_rubygems_deploy_token_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210303154652_i_package_rubygems_user_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210409095855_users_expanding_secure_security_report_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210409100451_users_expanding_testing_code_quality_report_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210409100628_users_expanding_testing_accessibility_report_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210410012207_i_package_terraform_module_deploy_token_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210410012209_i_package_terraform_module_user_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210413205507_i_testing_summary_widget_total_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210421144349_i_code_review_click_single_file_mode_setting_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210421145814_i_code_review_click_file_browser_setting_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210421145942_i_code_review_click_whitespace_setting_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210422101512_i_code_review_diff_view_inline_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210422101609_i_code_review_diff_view_parallel_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210422101750_i_code_review_file_browser_tree_view_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210422101849_i_code_review_file_browser_list_view_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210422101925_i_code_review_diff_show_whitespace_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210422102007_i_code_review_diff_hide_whitespace_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210422102118_i_code_review_diff_single_file_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210422102159_i_code_review_diff_multiple_files_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210427103328_code_review_group_monthly_active_users.yml16
-rw-r--r--config/metrics/counts_7d/20210427103407_code_review_category_monthly_active_users.yml17
-rw-r--r--config/metrics/counts_7d/20210427103452_code_review_extension_category_monthly_active_users.yml14
-rw-r--r--config/metrics/counts_7d/20210427105030_pipeline_authoring_total_unique_counts_weekly.yml14
-rw-r--r--config/metrics/counts_7d/20210514013544_i_code_review_user_load_conflict_ui_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210514013545_i_code_review_user_resolve_conflict_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210517074851_i_package_helm_deploy_token_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210517075252_i_package_helm_user_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210607113552_i_code_review_click_diff_view_setting_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210720144005_i_code_review_user_searches_diff_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210721042223_i_quickactions_severity_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210816144119_i_code_review_total_suggestions_added_weekly.yml27
-rw-r--r--config/metrics/counts_7d/20210816144247_i_code_review_total_suggestions_applied_weekly.yml27
-rw-r--r--config/metrics/counts_7d/20210901221237_p_ci_templates_terraform_base_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221246_p_ci_templates_dotnet_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221255_p_ci_templates_nodejs_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221304_p_ci_templates_openshift_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221313_p_ci_templates_bash_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221322_p_ci_templates_rust_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221330_p_ci_templates_elixir_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221339_p_ci_templates_clojure_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221348_p_ci_templates_crystal_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221357_p_ci_templates_getting_started_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221405_p_ci_templates_code_quality_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221414_p_ci_templates_verify_load_performance_testing_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221423_p_ci_templates_verify_accessibility_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221432_p_ci_templates_verify_failfast_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221440_p_ci_templates_verify_browser_performance_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221449_p_ci_templates_verify_browser_performance_latest_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221458_p_ci_templates_grails_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221507_p_ci_templates_security_dast_runner_validation_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221516_p_ci_templates_security_dast_on_demand_scan_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221525_p_ci_templates_security_license_scanning_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221534_p_ci_templates_security_coverage_fuzzing_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221542_p_ci_templates_security_api_fuzzing_latest_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221551_p_ci_templates_security_secure_binaries_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221600_p_ci_templates_security_dast_api_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221609_p_ci_templates_security_container_scanning_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221618_p_ci_templates_security_dast_latest_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221627_p_ci_templates_security_dependency_scanning_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221636_p_ci_templates_security_api_fuzzing_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221645_p_ci_templates_security_dast_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221654_p_ci_templates_security_cluster_image_scanning_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221703_p_ci_templates_ios_fastlane_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221712_p_ci_templates_composer_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221722_p_ci_templates_c_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221731_p_ci_templates_python_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221740_p_ci_templates_android_fastlane_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221749_p_ci_templates_django_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221758_p_ci_templates_maven_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221807_p_ci_templates_flutter_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221817_p_ci_templates_workflows_branch_pipelines_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221826_p_ci_templates_workflows_mergerequest_pipelines_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221836_p_ci_templates_laravel_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221844_p_ci_templates_managed_cluster_applications_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221853_p_ci_templates_php_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221902_p_ci_templates_packer_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221910_p_ci_templates_terraform_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221919_p_ci_templates_mono_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221928_p_ci_templates_serverless_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221936_p_ci_templates_go_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221945_p_ci_templates_scala_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901221954_p_ci_templates_latex_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222003_p_ci_templates_android_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222011_p_ci_templates_indeni_cloudrail_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222020_p_ci_templates_deploy_ecs_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222029_p_ci_templates_aws_cf_provision_and_deploy_ec2_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222038_p_ci_templates_gradle_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222046_p_ci_templates_chef_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222055_p_ci_templates_jobs_dast_default_branch_deploy_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222104_p_ci_templates_jobs_load_performance_testing_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222113_p_ci_templates_jobs_helm_2to3_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222122_p_ci_templates_jobs_sast_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222131_p_ci_templates_jobs_secret_detection_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222139_p_ci_templates_jobs_code_intelligence_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222148_p_ci_templates_jobs_code_quality_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222157_p_ci_templates_jobs_deploy_ecs_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222206_p_ci_templates_jobs_deploy_ec2_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222215_p_ci_templates_jobs_deploy_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222224_p_ci_templates_jobs_build_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222233_p_ci_templates_jobs_browser_performance_testing_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222242_p_ci_templates_jobs_test_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222251_p_ci_templates_jobs_deploy_latest_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222300_p_ci_templates_jobs_browser_performance_testing_latest_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222309_p_ci_templates_jobs_cf_provision_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222318_p_ci_templates_jobs_build_latest_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222327_p_ci_templates_terraform_latest_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222336_p_ci_templates_swift_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222703_p_ci_templates_pages_jekyll_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901222719_p_ci_templates_pages_harp_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223156_p_ci_templates_pages_octopress_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223206_p_ci_templates_pages_brunch_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223215_p_ci_templates_pages_doxygen_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223223_p_ci_templates_pages_hyde_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223232_p_ci_templates_pages_lektor_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223240_p_ci_templates_pages_jbake_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223249_p_ci_templates_pages_hexo_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223257_p_ci_templates_pages_middleman_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223306_p_ci_templates_pages_hugo_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223315_p_ci_templates_pages_pelican_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223324_p_ci_templates_pages_nanoc_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223332_p_ci_templates_pages_swaggerui_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223341_p_ci_templates_pages_jigsaw_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223350_p_ci_templates_pages_metalsmith_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223359_p_ci_templates_pages_gatsby_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223408_p_ci_templates_pages_html_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223416_p_ci_templates_dart_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223425_p_ci_templates_docker_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223434_p_ci_templates_julia_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223443_p_ci_templates_npm_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223452_p_ci_templates_dotnet_core_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223501_p_ci_templates_5_minute_production_app_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223510_p_ci_templates_ruby_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223519_p_ci_templates_implicit_jobs_dast_default_branch_deploy_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223528_p_ci_templates_implicit_jobs_load_performance_testing_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223537_p_ci_templates_implicit_jobs_helm_2to3_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223546_p_ci_templates_implicit_jobs_sast_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223554_p_ci_templates_implicit_jobs_secret_detection_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223603_p_ci_templates_implicit_jobs_code_intelligence_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223612_p_ci_templates_implicit_jobs_code_quality_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223621_p_ci_templates_implicit_jobs_deploy_ecs_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223630_p_ci_templates_implicit_jobs_deploy_ec2_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223639_p_ci_templates_implicit_jobs_browser_performance_testing_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223649_p_ci_templates_implicit_jobs_test_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223658_p_ci_templates_implicit_jobs_browser_performance_testing_latest_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223707_p_ci_templates_implicit_jobs_cf_provision_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223716_p_ci_templates_implicit_jobs_build_latest_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223725_p_ci_templates_implicit_security_dast_runner_validation_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223735_p_ci_templates_implicit_security_dast_on_demand_scan_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223744_p_ci_templates_implicit_security_license_scanning_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223753_p_ci_templates_implicit_security_coverage_fuzzing_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223802_p_ci_templates_implicit_security_api_fuzzing_latest_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223811_p_ci_templates_implicit_security_secure_binaries_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223819_p_ci_templates_implicit_security_dast_api_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223828_p_ci_templates_implicit_security_container_scanning_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223837_p_ci_templates_implicit_security_dast_latest_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223845_p_ci_templates_implicit_security_dependency_scanning_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223854_p_ci_templates_implicit_security_api_fuzzing_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223903_p_ci_templates_implicit_security_dast_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210901223912_p_ci_templates_implicit_security_cluster_image_scanning_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210902000809_p_ci_templates_implicit_auto_devops_deploy_latest_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210902191054_i_quickactions_unapprove_weekly.yml28
-rw-r--r--config/metrics/counts_7d/20210908093503_p_ci_templates_android_latest_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20210908151645_i_code_review_user_resolve_thread_in_issue_weekly.yml27
-rw-r--r--config/metrics/counts_all/20210201124934_deployments.yml2
-rw-r--r--config/metrics/counts_all/20210204124930_servers.yml17
-rw-r--r--config/metrics/counts_all/20210204124932_clusters.yml17
-rw-r--r--config/metrics/counts_all/20210216174832_cycle_analytics_views.yml5
-rw-r--r--config/metrics/counts_all/20210216174846_p_analytics_pipelines.yml9
-rw-r--r--config/metrics/counts_all/20210216174850_p_analytics_valuestream.yml9
-rw-r--r--config/metrics/counts_all/20210216174856_p_analytics_repo.yml9
-rw-r--r--config/metrics/counts_all/20210216174858_i_analytics_cohorts.yml9
-rw-r--r--config/metrics/counts_all/20210216174900_i_analytics_dev_ops_score.yml9
-rw-r--r--config/metrics/counts_all/20210216174902_g_analytics_merge_request.yml6
-rw-r--r--config/metrics/counts_all/20210216174906_i_analytics_instance_statistics.yml9
-rw-r--r--config/metrics/counts_all/20210216174908_analytics_unique_visits_for_any_target.yml11
-rw-r--r--config/metrics/counts_all/20210216175019_projects_with_prometheus_alerts.yml5
-rw-r--r--config/metrics/counts_all/20210216175021_pod_logs_usages_total.yml5
-rw-r--r--config/metrics/counts_all/20210216175024_service_desk_enabled_projects.yml3
-rw-r--r--config/metrics/counts_all/20210216175026_service_desk_issues.yml3
-rw-r--r--config/metrics/counts_all/20210216175037_suggestions.yml3
-rw-r--r--config/metrics/counts_all/20210216175039_merge_requests.yml3
-rw-r--r--config/metrics/counts_all/20210216175041_merge_request_comment.yml3
-rw-r--r--config/metrics/counts_all/20210216175043_merge_request_create.yml3
-rw-r--r--config/metrics/counts_all/20210216175045_merge_requests.yml3
-rw-r--r--config/metrics/counts_all/20210216175053_suggestions.yml3
-rw-r--r--config/metrics/counts_all/20210216175206_merged_merge_requests_using_approval_rules.yml7
-rw-r--r--config/metrics/counts_all/20210216175229_auto_devops_enabled.yml6
-rw-r--r--config/metrics/counts_all/20210216175231_auto_devops_disabled.yml9
-rw-r--r--config/metrics/counts_all/20210216175232_clusters.yml6
-rw-r--r--config/metrics/counts_all/20210216175234_clusters_enabled.yml3
-rw-r--r--config/metrics/counts_all/20210216175236_project_clusters_enabled.yml6
-rw-r--r--config/metrics/counts_all/20210216175238_group_clusters_enabled.yml6
-rw-r--r--config/metrics/counts_all/20210216175240_instance_clusters_enabled.yml6
-rw-r--r--config/metrics/counts_all/20210216175242_clusters_disabled.yml3
-rw-r--r--config/metrics/counts_all/20210216175244_project_clusters_disabled.yml6
-rw-r--r--config/metrics/counts_all/20210216175246_group_clusters_disabled.yml6
-rw-r--r--config/metrics/counts_all/20210216175248_instance_clusters_disabled.yml6
-rw-r--r--config/metrics/counts_all/20210216175250_clusters_platforms_eks.yml6
-rw-r--r--config/metrics/counts_all/20210216175251_clusters_platforms_gke.yml6
-rw-r--r--config/metrics/counts_all/20210216175253_clusters_platforms_user.yml6
-rw-r--r--config/metrics/counts_all/20210216175255_clusters_applications_helm.yml6
-rw-r--r--config/metrics/counts_all/20210216175257_clusters_applications_ingress.yml6
-rw-r--r--config/metrics/counts_all/20210216175259_clusters_applications_cert_managers.yml6
-rw-r--r--config/metrics/counts_all/20210216175301_clusters_applications_crossplane.yml6
-rw-r--r--config/metrics/counts_all/20210216175303_clusters_applications_prometheus.yml6
-rw-r--r--config/metrics/counts_all/20210216175305_clusters_applications_runner.yml3
-rw-r--r--config/metrics/counts_all/20210216175307_clusters_applications_knative.yml6
-rw-r--r--config/metrics/counts_all/20210216175309_clusters_applications_elastic_stack.yml6
-rw-r--r--config/metrics/counts_all/20210216175310_clusters_applications_jupyter.yml6
-rw-r--r--config/metrics/counts_all/20210216175312_clusters_applications_cilium.yml6
-rw-r--r--config/metrics/counts_all/20210216175314_clusters_management_project.yml6
-rw-r--r--config/metrics/counts_all/20210216175320_projects_with_terraform_reports.yml3
-rw-r--r--config/metrics/counts_all/20210216175322_projects_with_terraform_states.yml3
-rw-r--r--config/metrics/counts_all/20210216175324_terraform_reports.yml5
-rw-r--r--config/metrics/counts_all/20210216175326_terraform_states.yml3
-rw-r--r--config/metrics/counts_all/20210216175329_clusters_applications_cert_managers.yml8
-rw-r--r--config/metrics/counts_all/20210216175331_clusters_applications_helm.yml8
-rw-r--r--config/metrics/counts_all/20210216175333_clusters_applications_ingress.yml8
-rw-r--r--config/metrics/counts_all/20210216175335_clusters_applications_knative.yml8
-rw-r--r--config/metrics/counts_all/20210216175337_clusters_management_project.yml8
-rw-r--r--config/metrics/counts_all/20210216175339_clusters_disabled.yml8
-rw-r--r--config/metrics/counts_all/20210216175341_clusters_enabled.yml8
-rw-r--r--config/metrics/counts_all/20210216175343_clusters_platforms_gke.yml8
-rw-r--r--config/metrics/counts_all/20210216175345_clusters_platforms_eks.yml8
-rw-r--r--config/metrics/counts_all/20210216175346_clusters_platforms_user.yml8
-rw-r--r--config/metrics/counts_all/20210216175348_instance_clusters_disabled.yml8
-rw-r--r--config/metrics/counts_all/20210216175350_instance_clusters_enabled.yml8
-rw-r--r--config/metrics/counts_all/20210216175352_group_clusters_disabled.yml8
-rw-r--r--config/metrics/counts_all/20210216175354_group_clusters_enabled.yml8
-rw-r--r--config/metrics/counts_all/20210216175356_project_clusters_disabled.yml8
-rw-r--r--config/metrics/counts_all/20210216175358_project_clusters_enabled.yml8
-rw-r--r--config/metrics/counts_all/20210216175403_projects_with_prometheus_alerts.yml6
-rw-r--r--config/metrics/counts_all/20210216175442_ingress_modsecurity_packets_processed.yml1
-rw-r--r--config/metrics/counts_all/20210216175444_ingress_modsecurity_packets_anomalous.yml1
-rw-r--r--config/metrics/counts_all/20210216175446_network_policy_forwards.yml3
-rw-r--r--config/metrics/counts_all/20210216175448_network_policy_drops.yml3
-rw-r--r--config/metrics/counts_all/20210216175450_ingress_modsecurity_logging.yml1
-rw-r--r--config/metrics/counts_all/20210216175452_ingress_modsecurity_blocking.yml1
-rw-r--r--config/metrics/counts_all/20210216175454_ingress_modsecurity_disabled.yml1
-rw-r--r--config/metrics/counts_all/20210216175456_ingress_modsecurity_not_installed.yml1
-rw-r--r--config/metrics/counts_all/20210216175510_ci_builds.yml3
-rw-r--r--config/metrics/counts_all/20210216175512_ci_internal_pipelines.yml3
-rw-r--r--config/metrics/counts_all/20210216175514_ci_external_pipelines.yml3
-rw-r--r--config/metrics/counts_all/20210216175516_ci_pipeline_config_auto_devops.yml3
-rw-r--r--config/metrics/counts_all/20210216175518_ci_pipeline_config_repository.yml3
-rw-r--r--config/metrics/counts_all/20210216175520_ci_runners.yml3
-rw-r--r--config/metrics/counts_all/20210216175521_ci_triggers.yml3
-rw-r--r--config/metrics/counts_all/20210216175523_ci_pipeline_schedules.yml3
-rw-r--r--config/metrics/counts_all/20210216175525_ci_builds.yml3
-rw-r--r--config/metrics/counts_all/20210216175527_ci_external_pipelines.yml3
-rw-r--r--config/metrics/counts_all/20210216175529_ci_internal_pipelines.yml3
-rw-r--r--config/metrics/counts_all/20210216175531_ci_pipeline_config_auto_devops.yml3
-rw-r--r--config/metrics/counts_all/20210216175533_ci_pipeline_config_repository.yml4
-rw-r--r--config/metrics/counts_all/20210216175535_ci_pipeline_schedules.yml3
-rw-r--r--config/metrics/counts_all/20210216175537_ci_pipelines.yml3
-rw-r--r--config/metrics/counts_all/20210216175539_ci_triggers.yml3
-rw-r--r--config/metrics/counts_all/20210216175621_web_hooks.yml11
-rw-r--r--config/metrics/counts_all/20210216175623_projects_asana_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175625_groups_asana_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175627_templates_asana_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175628_instances_asana_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175630_projects_inheriting_asana_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175632_groups_inheriting_asana_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175634_projects_assembla_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175636_groups_assembla_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175638_templates_assembla_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175640_instances_assembla_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175642_projects_inheriting_assembla_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175644_groups_inheriting_assembla_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175645_projects_bamboo_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175647_groups_bamboo_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175649_templates_bamboo_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175651_instances_bamboo_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175653_projects_inheriting_bamboo_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175655_groups_inheriting_bamboo_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175657_projects_bugzilla_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175659_groups_bugzilla_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175701_templates_bugzilla_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175702_instances_bugzilla_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175704_projects_inheriting_bugzilla_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175706_groups_inheriting_bugzilla_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175708_projects_buildkite_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175710_groups_buildkite_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175712_templates_buildkite_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175714_instances_buildkite_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175716_projects_inheriting_buildkite_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175717_groups_inheriting_buildkite_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175719_projects_campfire_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175721_groups_campfire_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175723_templates_campfire_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175725_instances_campfire_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175727_projects_inheriting_campfire_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175729_groups_inheriting_campfire_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175731_projects_confluence_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175733_groups_confluence_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175734_templates_confluence_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175736_instances_confluence_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175738_projects_inheriting_confluence_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175740_groups_inheriting_confluence_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175742_projects_custom_issue_tracker_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175744_groups_custom_issue_tracker_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175745_templates_custom_issue_tracker_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175747_instances_custom_issue_tracker_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175749_projects_inheriting_custom_issue_tracker_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175751_groups_inheriting_custom_issue_tracker_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175753_projects_discord_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175755_groups_discord_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175756_templates_discord_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175758_instances_discord_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175800_projects_inheriting_discord_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175802_groups_inheriting_discord_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175804_projects_drone_ci_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175806_groups_drone_ci_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175807_templates_drone_ci_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175809_instances_drone_ci_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175811_projects_inheriting_drone_ci_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175813_groups_inheriting_drone_ci_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175815_projects_emails_on_push_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175817_groups_emails_on_push_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175818_templates_emails_on_push_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175820_instances_emails_on_push_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175822_projects_inheriting_emails_on_push_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175824_groups_inheriting_emails_on_push_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175826_projects_external_wiki_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175828_groups_external_wiki_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175829_templates_external_wiki_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175831_instances_external_wiki_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175833_projects_inheriting_external_wiki_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175835_groups_inheriting_external_wiki_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175837_projects_flowdock_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175839_groups_flowdock_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175840_templates_flowdock_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175842_instances_flowdock_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175844_projects_inheriting_flowdock_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175846_groups_inheriting_flowdock_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175859_projects_hangouts_chat_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175901_groups_hangouts_chat_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175902_templates_hangouts_chat_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175904_instances_hangouts_chat_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175906_projects_inheriting_hangouts_chat_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175908_groups_inheriting_hangouts_chat_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175910_projects_hipchat_active.yml1
-rw-r--r--config/metrics/counts_all/20210216175912_groups_hipchat_active.yml1
-rw-r--r--config/metrics/counts_all/20210216175913_templates_hipchat_active.yml1
-rw-r--r--config/metrics/counts_all/20210216175915_instances_hipchat_active.yml1
-rw-r--r--config/metrics/counts_all/20210216175917_projects_inheriting_hipchat_active.yml1
-rw-r--r--config/metrics/counts_all/20210216175919_groups_inheriting_hipchat_active.yml1
-rw-r--r--config/metrics/counts_all/20210216175921_projects_irker_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175923_groups_irker_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175924_templates_irker_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175926_instances_irker_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175928_projects_inheriting_irker_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175930_groups_inheriting_irker_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175932_projects_jenkins_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175934_groups_jenkins_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175935_templates_jenkins_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175937_instances_jenkins_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175939_projects_inheriting_jenkins_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175941_groups_inheriting_jenkins_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175943_projects_jira_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175945_groups_jira_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175946_templates_jira_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175948_instances_jira_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175950_projects_inheriting_jira_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175952_groups_inheriting_jira_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175954_projects_mattermost_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175956_groups_mattermost_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175957_templates_mattermost_active.yml3
-rw-r--r--config/metrics/counts_all/20210216175959_instances_mattermost_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180001_projects_inheriting_mattermost_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180003_groups_inheriting_mattermost_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180005_projects_mattermost_slash_commands_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180006_groups_mattermost_slash_commands_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180008_templates_mattermost_slash_commands_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180010_instances_mattermost_slash_commands_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180012_projects_inheriting_mattermost_slash_commands_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180014_groups_inheriting_mattermost_slash_commands_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180016_projects_microsoft_teams_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180018_groups_microsoft_teams_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180019_templates_microsoft_teams_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180021_instances_microsoft_teams_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180023_projects_inheriting_microsoft_teams_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180025_groups_inheriting_microsoft_teams_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180027_projects_packagist_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180029_groups_packagist_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180030_templates_packagist_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180032_instances_packagist_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180034_projects_inheriting_packagist_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180036_groups_inheriting_packagist_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180038_projects_pipelines_email_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180040_groups_pipelines_email_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180041_templates_pipelines_email_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180043_instances_pipelines_email_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180045_projects_inheriting_pipelines_email_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180047_groups_inheriting_pipelines_email_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180049_projects_pivotaltracker_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180051_groups_pivotaltracker_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180052_templates_pivotaltracker_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180054_instances_pivotaltracker_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180056_projects_inheriting_pivotaltracker_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180058_groups_inheriting_pivotaltracker_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180100_projects_pushover_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180102_groups_pushover_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180104_templates_pushover_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180105_instances_pushover_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180107_projects_inheriting_pushover_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180109_groups_inheriting_pushover_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180111_projects_redmine_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180113_groups_redmine_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180115_templates_redmine_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180116_instances_redmine_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180118_projects_inheriting_redmine_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180120_groups_inheriting_redmine_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180122_projects_slack_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180124_groups_slack_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180126_templates_slack_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180127_instances_slack_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180129_projects_inheriting_slack_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180131_groups_inheriting_slack_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180133_projects_slack_slash_commands_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180135_groups_slack_slash_commands_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180137_templates_slack_slash_commands_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180138_instances_slack_slash_commands_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180140_projects_inheriting_slack_slash_commands_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180142_groups_inheriting_slack_slash_commands_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180144_projects_teamcity_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180146_groups_teamcity_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180148_templates_teamcity_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180149_instances_teamcity_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180151_projects_inheriting_teamcity_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180153_groups_inheriting_teamcity_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180155_projects_unify_circuit_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180157_groups_unify_circuit_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180159_templates_unify_circuit_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180201_instances_unify_circuit_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180203_projects_inheriting_unify_circuit_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180204_groups_inheriting_unify_circuit_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180206_projects_webex_teams_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180208_groups_webex_teams_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180210_templates_webex_teams_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180212_instances_webex_teams_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180214_projects_inheriting_webex_teams_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180215_groups_inheriting_webex_teams_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180217_projects_youtrack_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180219_groups_youtrack_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180221_templates_youtrack_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180223_instances_youtrack_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180225_projects_inheriting_youtrack_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180226_groups_inheriting_youtrack_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180228_projects_jira_server_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180230_projects_jira_cloud_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180232_projects_jira_dvcs_cloud_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180234_projects_jira_dvcs_server_active.yml3
-rw-r--r--config/metrics/counts_all/20210216180239_personal_snippets.yml3
-rw-r--r--config/metrics/counts_all/20210216180241_project_snippets.yml3
-rw-r--r--config/metrics/counts_all/20210216180242_web_ide_commits.yml3
-rw-r--r--config/metrics/counts_all/20210216180244_web_ide_views.yml3
-rw-r--r--config/metrics/counts_all/20210216180246_web_ide_merge_requests.yml3
-rw-r--r--config/metrics/counts_all/20210216180248_web_ide_previews.yml3
-rw-r--r--config/metrics/counts_all/20210216180250_web_ide_terminals.yml3
-rw-r--r--config/metrics/counts_all/20210216180252_web_ide_pipelines.yml3
-rw-r--r--config/metrics/counts_all/20210216180253_snippet_comment.yml3
-rw-r--r--config/metrics/counts_all/20210216180255_snippet_create.yml3
-rw-r--r--config/metrics/counts_all/20210216180257_snippet_update.yml3
-rw-r--r--config/metrics/counts_all/20210216180259_static_site_editor_views.yml3
-rw-r--r--config/metrics/counts_all/20210216180301_static_site_editor_commits.yml3
-rw-r--r--config/metrics/counts_all/20210216180303_static_site_editor_merge_requests.yml3
-rw-r--r--config/metrics/counts_all/20210216180304_user_preferences_user_gitpod_enabled.yml3
-rw-r--r--config/metrics/counts_all/20210216180306_snippets.yml3
-rw-r--r--config/metrics/counts_all/20210216180316_snippets.yml3
-rw-r--r--config/metrics/counts_all/20210216180410_pool_repositories.yml4
-rw-r--r--config/metrics/counts_all/20210216180413_all_searches.yml3
-rw-r--r--config/metrics/counts_all/20210216180414_navbar_searches.yml6
-rw-r--r--config/metrics/counts_all/20210216180416_i_search_total.yml3
-rw-r--r--config/metrics/counts_all/20210216180434_issues_created_from_gitlab_error_tracking_ui.yml3
-rw-r--r--config/metrics/counts_all/20210216180436_issues_with_associated_zoom_link.yml3
-rw-r--r--config/metrics/counts_all/20210216180438_issues_using_zoom_quick_actions.yml3
-rw-r--r--config/metrics/counts_all/20210216180440_issues_with_embedded_grafana_charts_approx.yml3
-rw-r--r--config/metrics/counts_all/20210216180441_issues_created_from_alerts.yml3
-rw-r--r--config/metrics/counts_all/20210216180443_issues_created_gitlab_alerts.yml3
-rw-r--r--config/metrics/counts_all/20210216180445_issues_created_manually_from_alerts.yml3
-rw-r--r--config/metrics/counts_all/20210216180447_incident_issues.yml3
-rw-r--r--config/metrics/counts_all/20210216180449_alert_bot_incident_issues.yml3
-rw-r--r--config/metrics/counts_all/20210216180451_incident_labeled_issues.yml3
-rw-r--r--config/metrics/counts_all/20210216180453_projects_creating_incidents.yml3
-rw-r--r--config/metrics/counts_all/20210216180454_projects_with_error_tracking_enabled.yml3
-rw-r--r--config/metrics/counts_all/20210216180456_projects_with_alerts_service_enabled.yml1
-rw-r--r--config/metrics/counts_all/20210216180458_projects_with_alerts_created.yml3
-rw-r--r--config/metrics/counts_all/20210216180500_projects_with_enabled_alert_integrations.yml3
-rw-r--r--config/metrics/counts_all/20210216180517_projects_with_error_tracking_enabled.yml3
-rw-r--r--config/metrics/counts_all/20210216180518_projects_with_incidents.yml3
-rw-r--r--config/metrics/counts_all/20210216180520_projects_with_alert_incidents.yml3
-rw-r--r--config/metrics/counts_all/20210216180628_projects_imported_from_github.yml3
-rw-r--r--config/metrics/counts_all/20210216180630_projects_imported_from_github.yml3
-rw-r--r--config/metrics/counts_all/20210216180632_unique_users_all_imports.yml3
-rw-r--r--config/metrics/counts_all/20210216180634_gitlab.yml1
-rw-r--r--config/metrics/counts_all/20210216180636_gitlab_v1.yml3
-rw-r--r--config/metrics/counts_all/20210216180638_gitlab_project.yml3
-rw-r--r--config/metrics/counts_all/20210216180639_gitlab.yml3
-rw-r--r--config/metrics/counts_all/20210216180641_github.yml3
-rw-r--r--config/metrics/counts_all/20210216180643_bitbucket.yml3
-rw-r--r--config/metrics/counts_all/20210216180645_bitbucket_server.yml3
-rw-r--r--config/metrics/counts_all/20210216180647_gitea.yml3
-rw-r--r--config/metrics/counts_all/20210216180649_git.yml3
-rw-r--r--config/metrics/counts_all/20210216180650_manifest.yml3
-rw-r--r--config/metrics/counts_all/20210216180652_gitlab_migration.yml3
-rw-r--r--config/metrics/counts_all/20210216180654_jira.yml3
-rw-r--r--config/metrics/counts_all/20210216180656_fogbugz.yml3
-rw-r--r--config/metrics/counts_all/20210216180658_phabricator.yml3
-rw-r--r--config/metrics/counts_all/20210216180700_csv.yml3
-rw-r--r--config/metrics/counts_all/20210216180702_group_import.yml3
-rw-r--r--config/metrics/counts_all/20210216180703_gitlab_migration.yml3
-rw-r--r--config/metrics/counts_all/20210216180705_total.yml1
-rw-r--r--config/metrics/counts_all/20210216180707_gitlab_project.yml3
-rw-r--r--config/metrics/counts_all/20210216180709_gitlab.yml3
-rw-r--r--config/metrics/counts_all/20210216180711_github.yml1
-rw-r--r--config/metrics/counts_all/20210216180713_bitbucket.yml3
-rw-r--r--config/metrics/counts_all/20210216180715_bitbucket_server.yml3
-rw-r--r--config/metrics/counts_all/20210216180716_gitea.yml3
-rw-r--r--config/metrics/counts_all/20210216180718_git.yml3
-rw-r--r--config/metrics/counts_all/20210216180720_manifest.yml3
-rw-r--r--config/metrics/counts_all/20210216180722_jira.yml1
-rw-r--r--config/metrics/counts_all/20210216180724_fogbugz.yml3
-rw-r--r--config/metrics/counts_all/20210216180726_phabricator.yml1
-rw-r--r--config/metrics/counts_all/20210216180727_csv.yml1
-rw-r--r--config/metrics/counts_all/20210216180729_groups_imported.yml1
-rw-r--r--config/metrics/counts_all/20210216180734_wiki_pages_create.yml3
-rw-r--r--config/metrics/counts_all/20210216180736_wiki_pages_update.yml3
-rw-r--r--config/metrics/counts_all/20210216180738_wiki_pages_delete.yml3
-rw-r--r--config/metrics/counts_all/20210216180740_design_management_designs_create.yml3
-rw-r--r--config/metrics/counts_all/20210216180741_design_management_designs_update.yml3
-rw-r--r--config/metrics/counts_all/20210216180743_design_management_designs_delete.yml3
-rw-r--r--config/metrics/counts_all/20210216180750_groups.yml3
-rw-r--r--config/metrics/counts_all/20210216180752_keys.yml3
-rw-r--r--config/metrics/counts_all/20210216180754_events.yml3
-rw-r--r--config/metrics/counts_all/20210216180756_groups.yml3
-rw-r--r--config/metrics/counts_all/20210216180758_users_created.yml3
-rw-r--r--config/metrics/counts_all/20210216180927_grafana_integrated_projects.yml8
-rw-r--r--config/metrics/counts_all/20210216180929_projects_with_tracing_enabled.yml5
-rw-r--r--config/metrics/counts_all/20210216180931_projects_prometheus_active.yml5
-rw-r--r--config/metrics/counts_all/20210216180933_groups_prometheus_active.yml5
-rw-r--r--config/metrics/counts_all/20210216180934_templates_prometheus_active.yml5
-rw-r--r--config/metrics/counts_all/20210216180936_instances_prometheus_active.yml5
-rw-r--r--config/metrics/counts_all/20210216180938_projects_inheriting_prometheus_active.yml5
-rw-r--r--config/metrics/counts_all/20210216180940_groups_inheriting_prometheus_active.yml6
-rw-r--r--config/metrics/counts_all/20210216180942_operations_dashboard_default_dashboard.yml5
-rw-r--r--config/metrics/counts_all/20210216180944_operations_dashboard_users_with_projects_added.yml5
-rw-r--r--config/metrics/counts_all/20210216180945_clusters.yml15
-rw-r--r--config/metrics/counts_all/20210216180947_clusters_applications_prometheus.yml15
-rw-r--r--config/metrics/counts_all/20210216180949_operations_dashboard_default_dashboard.yml13
-rw-r--r--config/metrics/counts_all/20210216180951_projects_with_tracing_enabled.yml15
-rw-r--r--config/metrics/counts_all/20210216180953_operations_dashboard_users_with_projects_added.yml15
-rw-r--r--config/metrics/counts_all/20210216181009_lfs_objects.yml11
-rw-r--r--config/metrics/counts_all/20210216181011_projects_with_packages.yml3
-rw-r--r--config/metrics/counts_all/20210216181012_packages.yml3
-rw-r--r--config/metrics/counts_all/20210216181014_projects_with_expiration_policy_disabled.yml3
-rw-r--r--config/metrics/counts_all/20210216181016_projects_with_expiration_policy_enabled.yml3
-rw-r--r--config/metrics/counts_all/20210216181018_projects_with_expiration_policy_enabled_with_keep_n_set_to_1.yml3
-rw-r--r--config/metrics/counts_all/20210216181020_projects_with_expiration_policy_enabled_with_keep_n_set_to_5.yml3
-rw-r--r--config/metrics/counts_all/20210216181022_projects_with_expiration_policy_enabled_with_keep_n_set_to_10.yml3
-rw-r--r--config/metrics/counts_all/20210216181024_projects_with_expiration_policy_enabled_with_keep_n_set_to_25.yml3
-rw-r--r--config/metrics/counts_all/20210216181025_projects_with_expiration_policy_enabled_with_keep_n_set_to_50.yml3
-rw-r--r--config/metrics/counts_all/20210216181027_projects_with_expiration_policy_enabled_with_keep_n_set_to_100.yml3
-rw-r--r--config/metrics/counts_all/20210216181029_projects_with_expiration_policy_enabled_with_cadence_set_to_1d.yml3
-rw-r--r--config/metrics/counts_all/20210216181031_projects_with_expiration_policy_enabled_with_cadence_set_to_7d.yml3
-rw-r--r--config/metrics/counts_all/20210216181033_projects_with_expiration_policy_enabled_with_cadence_set_to_14d.yml3
-rw-r--r--config/metrics/counts_all/20210216181035_projects_with_expiration_policy_enabled_with_cadence_set_to_1month.yml3
-rw-r--r--config/metrics/counts_all/20210216181037_projects_with_expiration_policy_enabled_with_cadence_set_to_3month.yml3
-rw-r--r--config/metrics/counts_all/20210216181038_projects_with_expiration_policy_enabled_with_older_than_set_to_7d.yml6
-rw-r--r--config/metrics/counts_all/20210216181040_projects_with_expiration_policy_enabled_with_older_than_set_to_14d.yml6
-rw-r--r--config/metrics/counts_all/20210216181042_projects_with_expiration_policy_enabled_with_older_than_set_to_30d.yml6
-rw-r--r--config/metrics/counts_all/20210216181044_projects_with_expiration_policy_enabled_with_older_than_set_to_90d.yml6
-rw-r--r--config/metrics/counts_all/20210216181046_projects_with_expiration_policy_enabled_with_keep_n_unset.yml6
-rw-r--r--config/metrics/counts_all/20210216181048_projects_with_expiration_policy_enabled_with_older_than_unset.yml6
-rw-r--r--config/metrics/counts_all/20210216181051_vendor.yml6
-rw-r--r--config/metrics/counts_all/20210216181055_projects_with_packages.yml3
-rw-r--r--config/metrics/counts_all/20210216181102_issues.yml5
-rw-r--r--config/metrics/counts_all/20210216181104_label_lists.yml3
-rw-r--r--config/metrics/counts_all/20210216181108_milestones.yml3
-rw-r--r--config/metrics/counts_all/20210216181109_uploads.yml3
-rw-r--r--config/metrics/counts_all/20210216181111_labels.yml3
-rw-r--r--config/metrics/counts_all/20210216181113_notes.yml3
-rw-r--r--config/metrics/counts_all/20210216181115_issues.yml3
-rw-r--r--config/metrics/counts_all/20210216181117_notes.yml3
-rw-r--r--config/metrics/counts_all/20210216181119_projects.yml3
-rw-r--r--config/metrics/counts_all/20210216181121_todos.yml3
-rw-r--r--config/metrics/counts_all/20210216181122_service_desk_enabled_projects.yml5
-rw-r--r--config/metrics/counts_all/20210216181124_service_desk_issues.yml5
-rw-r--r--config/metrics/counts_all/20210216181126_projects_jira_active.yml3
-rw-r--r--config/metrics/counts_all/20210216181128_projects_jira_dvcs_cloud_active.yml6
-rw-r--r--config/metrics/counts_all/20210216181130_projects_jira_dvcs_server_active.yml6
-rw-r--r--config/metrics/counts_all/20210216181134_epics.yml6
-rw-r--r--config/metrics/counts_all/20210216181135_label_lists.yml3
-rw-r--r--config/metrics/counts_all/20210216181249_feature_flags.yml3
-rw-r--r--config/metrics/counts_all/20210216181252_boards.yml3
-rw-r--r--config/metrics/counts_all/20210216181254_projects.yml3
-rw-r--r--config/metrics/counts_all/20210216181256_todos.yml3
-rw-r--r--config/metrics/counts_all/20210216181258_jira_imports_total_imported_count.yml3
-rw-r--r--config/metrics/counts_all/20210216181259_jira_imports_projects_count.yml3
-rw-r--r--config/metrics/counts_all/20210216181301_jira_imports_total_imported_issues_count.yml3
-rw-r--r--config/metrics/counts_all/20210216181908_deploy_keys.yml3
-rw-r--r--config/metrics/counts_all/20210216181911_successful_deployments.yml3
-rw-r--r--config/metrics/counts_all/20210216181912_failed_deployments.yml3
-rw-r--r--config/metrics/counts_all/20210216181914_environments.yml3
-rw-r--r--config/metrics/counts_all/20210216181916_in_review_folder.yml3
-rw-r--r--config/metrics/counts_all/20210216181918_releases.yml3
-rw-r--r--config/metrics/counts_all/20210216181926_deployments.yml3
-rw-r--r--config/metrics/counts_all/20210216181928_failed_deployments.yml3
-rw-r--r--config/metrics/counts_all/20210216181930_releases.yml3
-rw-r--r--config/metrics/counts_all/20210216181932_successful_deployments.yml3
-rw-r--r--config/metrics/counts_all/20210216181946_pages_domains.yml3
-rw-r--r--config/metrics/counts_all/20210216181949_clusters_applications_runner.yml5
-rw-r--r--config/metrics/counts_all/20210216181954_user_unique_users_all_secure_scanners.yml17
-rw-r--r--config/metrics/counts_all/20210216182002_remote_mirrors.yml3
-rw-r--r--config/metrics/counts_all/20210216182004_commit_comment.yml3
-rw-r--r--config/metrics/counts_all/20210216182006_source_code_pushes.yml3
-rw-r--r--config/metrics/counts_all/20210216182010_deploy_keys.yml3
-rw-r--r--config/metrics/counts_all/20210216182012_keys.yml3
-rw-r--r--config/metrics/counts_all/20210216182014_projects_with_disable_overriding_approvers_per_merge_request.yml6
-rw-r--r--config/metrics/counts_all/20210216182015_projects_without_disable_overriding_approvers_per_merge_request.yml6
-rw-r--r--config/metrics/counts_all/20210216182017_remote_mirrors.yml3
-rw-r--r--config/metrics/counts_all/20210216182112_sast_jobs.yml3
-rw-r--r--config/metrics/counts_all/20210216182114_secret_detection_jobs.yml3
-rw-r--r--config/metrics/counts_all/20210216182116_user_sast_jobs.yml3
-rw-r--r--config/metrics/counts_all/20210216182118_user_secret_detection_jobs.yml3
-rw-r--r--config/metrics/counts_all/20210216182454_protected_branches_except_default.yml3
-rw-r--r--config/metrics/counts_all/20210216182547_projects_datadog_active.yml5
-rw-r--r--config/metrics/counts_all/20210216182549_groups_datadog_active.yml3
-rw-r--r--config/metrics/counts_all/20210216182551_templates_datadog_active.yml3
-rw-r--r--config/metrics/counts_all/20210216182553_instances_datadog_active.yml3
-rw-r--r--config/metrics/counts_all/20210216182555_projects_inheriting_datadog_active.yml3
-rw-r--r--config/metrics/counts_all/20210216182557_groups_inheriting_datadog_active.yml3
-rw-r--r--config/metrics/counts_all/20210216182614_projects_ewm_active.yml5
-rw-r--r--config/metrics/counts_all/20210216182616_groups_ewm_active.yml3
-rw-r--r--config/metrics/counts_all/20210216182618_templates_ewm_active.yml3
-rw-r--r--config/metrics/counts_all/20210216182620_instances_ewm_active.yml3
-rw-r--r--config/metrics/counts_all/20210216182622_projects_inheriting_ewm_active.yml3
-rw-r--r--config/metrics/counts_all/20210216182623_groups_inheriting_ewm_active.yml3
-rw-r--r--config/metrics/counts_all/20210216182722_projects_mock_ci_active.yml1
-rw-r--r--config/metrics/counts_all/20210216182724_groups_mock_ci_active.yml1
-rw-r--r--config/metrics/counts_all/20210216182726_templates_mock_ci_active.yml1
-rw-r--r--config/metrics/counts_all/20210216182728_instances_mock_ci_active.yml1
-rw-r--r--config/metrics/counts_all/20210216182730_projects_inheriting_mock_ci_active.yml1
-rw-r--r--config/metrics/counts_all/20210216182732_groups_inheriting_mock_ci_active.yml1
-rw-r--r--config/metrics/counts_all/20210216182734_projects_mock_monitoring_active.yml1
-rw-r--r--config/metrics/counts_all/20210216182736_groups_mock_monitoring_active.yml1
-rw-r--r--config/metrics/counts_all/20210216182738_templates_mock_monitoring_active.yml1
-rw-r--r--config/metrics/counts_all/20210216182739_instances_mock_monitoring_active.yml1
-rw-r--r--config/metrics/counts_all/20210216182741_projects_inheriting_mock_monitoring_active.yml1
-rw-r--r--config/metrics/counts_all/20210216182743_groups_inheriting_mock_monitoring_active.yml1
-rw-r--r--config/metrics/counts_all/20210216182855_package_events_i_package_composer_delete_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182857_package_events_i_package_composer_pull_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182859_package_events_i_package_composer_push_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182901_package_events_i_package_conan_delete_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182903_package_events_i_package_conan_pull_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182905_package_events_i_package_conan_push_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182907_package_events_i_package_container_delete_package.yml1
-rw-r--r--config/metrics/counts_all/20210216182909_package_events_i_package_container_pull_package.yml1
-rw-r--r--config/metrics/counts_all/20210216182911_package_events_i_package_container_push_package.yml1
-rw-r--r--config/metrics/counts_all/20210216182913_package_events_i_package_debian_delete_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182915_package_events_i_package_debian_pull_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182917_package_events_i_package_debian_push_package.yml1
-rw-r--r--config/metrics/counts_all/20210216182919_package_events_i_package_delete_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182921_package_events_i_package_delete_package_by_deploy_token.yml3
-rw-r--r--config/metrics/counts_all/20210216182923_package_events_i_package_delete_package_by_guest.yml3
-rw-r--r--config/metrics/counts_all/20210216182925_package_events_i_package_delete_package_by_user.yml3
-rw-r--r--config/metrics/counts_all/20210216182927_package_events_i_package_generic_delete_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182929_package_events_i_package_generic_pull_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182931_package_events_i_package_generic_push_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182933_package_events_i_package_golang_delete_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182934_package_events_i_package_golang_pull_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182936_package_events_i_package_golang_push_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182938_package_events_i_package_maven_delete_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182940_package_events_i_package_maven_pull_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182942_package_events_i_package_maven_push_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182944_package_events_i_package_npm_delete_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182946_package_events_i_package_npm_pull_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182948_package_events_i_package_npm_push_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182950_package_events_i_package_nuget_delete_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182952_package_events_i_package_nuget_pull_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182954_package_events_i_package_nuget_push_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182956_package_events_i_package_pull_package.yml3
-rw-r--r--config/metrics/counts_all/20210216182958_package_events_i_package_pull_package_by_deploy_token.yml6
-rw-r--r--config/metrics/counts_all/20210216183000_package_events_i_package_pull_package_by_guest.yml6
-rw-r--r--config/metrics/counts_all/20210216183002_package_events_i_package_pull_package_by_user.yml6
-rw-r--r--config/metrics/counts_all/20210216183004_package_events_i_package_push_package.yml3
-rw-r--r--config/metrics/counts_all/20210216183005_package_events_i_package_push_package_by_deploy_token.yml6
-rw-r--r--config/metrics/counts_all/20210216183007_package_events_i_package_push_package_by_guest.yml6
-rw-r--r--config/metrics/counts_all/20210216183009_package_events_i_package_push_package_by_user.yml6
-rw-r--r--config/metrics/counts_all/20210216183011_package_events_i_package_pypi_delete_package.yml3
-rw-r--r--config/metrics/counts_all/20210216183013_package_events_i_package_pypi_pull_package.yml6
-rw-r--r--config/metrics/counts_all/20210216183015_package_events_i_package_pypi_push_package.yml3
-rw-r--r--config/metrics/counts_all/20210216183017_package_events_i_package_tag_delete_package.yml1
-rw-r--r--config/metrics/counts_all/20210216183019_package_events_i_package_tag_pull_package.yml1
-rw-r--r--config/metrics/counts_all/20210216183021_package_events_i_package_tag_push_package.yml1
-rw-r--r--config/metrics/counts_all/20210216183023_wiki_pages_view.yml21
-rw-r--r--config/metrics/counts_all/20210216183400_omniauth_providers.yml3
-rw-r--r--config/metrics/counts_all/20210216183402_two-factor.yml18
-rw-r--r--config/metrics/counts_all/20210216183404_two-factor-via-u2f-device.yml18
-rw-r--r--config/metrics/counts_all/20210216183406_two-factor-via-webauthn-device.yml18
-rw-r--r--config/metrics/counts_all/20210216183408_standard.yml18
-rw-r--r--config/metrics/counts_all/20210216183410_google_oauth2.yml18
-rw-r--r--config/metrics/counts_all/20210303153000_package_events_i_package_rubygems_delete_package.yml2
-rw-r--r--config/metrics/counts_all/20210303153002_package_events_i_package_rubygems_pull_package.yml2
-rw-r--r--config/metrics/counts_all/20210303153004_package_events_i_package_rubygems_push_package.yml4
-rw-r--r--config/metrics/counts_all/20210309165717_projects_with_enabled_alert_integrations_histogram.yml2
-rw-r--r--config/metrics/counts_all/20210410012200_package_events_i_package_terraform_module_delete_package.yml2
-rw-r--r--config/metrics/counts_all/20210410012202_package_events_i_package_terraform_module_pull_package.yml2
-rw-r--r--config/metrics/counts_all/20210410012204_package_events_i_package_terraform_module_push_package.yml2
-rw-r--r--config/metrics/counts_all/20210423005644_i_analytics_dev_ops_adoption.yml25
-rw-r--r--config/metrics/counts_all/20210427212450_geo_secondary_web_oauth_users.yml23
-rw-r--r--config/metrics/counts_all/20210428142406_users_viewing_analytics_group_devops_adoption.yml16
-rw-r--r--config/metrics/counts_all/20210502045402_ci_runners_instance_type_active.yml2
-rw-r--r--config/metrics/counts_all/20210502050341_ci_runners_group_type_active.yml2
-rw-r--r--config/metrics/counts_all/20210502050834_ci_runners_project_type_active.yml2
-rw-r--r--config/metrics/counts_all/20210502050942_ci_runners_online.yml2
-rw-r--r--config/metrics/counts_all/20210502051651_ci_runners_instance_type_active_online.yml2
-rw-r--r--config/metrics/counts_all/20210502051922_ci_runners_group_type_active_online.yml2
-rw-r--r--config/metrics/counts_all/20210502052036_ci_runners_project_type_active_online.yml2
-rw-r--r--config/metrics/counts_all/20210510201537_in_product_marketing_email_create_0_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510201919_in_product_marketing_email_create_0_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210510202148_in_product_marketing_email_create_1_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510202356_in_product_marketing_email_create_1_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210510202604_in_product_marketing_email_create_2_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510202724_in_product_marketing_email_create_2_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210510202807_in_product_marketing_email_verify_0_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510202943_in_product_marketing_email_verify_0_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210510202955_in_product_marketing_email_verify_1_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510203005_in_product_marketing_email_verify_1_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210510203015_in_product_marketing_email_verify_2_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510203025_in_product_marketing_email_verify_2_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210510203035_in_product_marketing_email_trial_0_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510203044_in_product_marketing_email_trial_0_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210510203054_in_product_marketing_email_trial_1_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510203104_in_product_marketing_email_trial_1_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210510203114_in_product_marketing_email_trial_2_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510203124_in_product_marketing_email_trial_2_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210510203134_in_product_marketing_email_team_0_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510203143_in_product_marketing_email_team_0_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210510203153_in_product_marketing_email_team_1_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510203203_in_product_marketing_email_team_1_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210510203213_in_product_marketing_email_team_2_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510203223_in_product_marketing_email_team_2_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210514141520_project_imports_total.yml2
-rw-r--r--config/metrics/counts_all/20210517073546_package_events_i_package_helm_pull_package.yml2
-rw-r--r--config/metrics/counts_all/20210518081225_in_product_marketing_email_experience_0_sent.yml2
-rw-r--r--config/metrics/counts_all/20210625095025_package_events_i_package_helm_push_package.yml2
-rw-r--r--config/metrics/counts_all/20210709191135_package_events_i_package_nuget_pull_symbol_package.yml2
-rw-r--r--config/metrics/counts_all/20210709191829_package_events_i_package_nuget_push_symbol_package.yml2
-rw-r--r--config/metrics/counts_all/20210709210941_package_events_i_package_pull_symbol_package.yml2
-rw-r--r--config/metrics/counts_all/20210709211058_package_events_i_package_pull_symbol_package_by_deploy_token.yml2
-rw-r--r--config/metrics/counts_all/20210709211248_package_events_i_package_pull_symbol_package_by_guest.yml2
-rw-r--r--config/metrics/counts_all/20210709211341_package_events_i_package_pull_symbol_package_by_user.yml2
-rw-r--r--config/metrics/counts_all/20210709211439_package_events_i_package_push_symbol_package.yml2
-rw-r--r--config/metrics/counts_all/20210709211636_package_events_i_package_push_symbol_package_by_deploy_token.yml2
-rw-r--r--config/metrics/counts_all/20210709211731_package_events_i_package_push_symbol_package_by_guest.yml2
-rw-r--r--config/metrics/counts_all/20210709211831_package_events_i_package_push_symbol_package_by_user.yml2
-rw-r--r--config/metrics/counts_all/20210723075525_diff_searches.yml2
-rw-r--r--config/metrics/counts_all/20210727095918_in_product_marketing_email_team_short_0_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210727095923_in_product_marketing_email_team_short_0_sent.yml2
-rw-r--r--config/metrics/counts_all/20210727170553_in_product_marketing_email_trial_short_0_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210727170558_in_product_marketing_email_trial_short_0_sent.yml2
-rw-r--r--config/metrics/counts_all/20210729140021_in_product_marketing_email_admin_verify_0_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210729140423_in_product_marketing_email_admin_verify_0_sent.yml2
-rw-r--r--config/metrics/counts_all/20210910132001_user_auth_by_provider.yml24
-rw-r--r--config/metrics/license/20210201124932_recorded_at.yml2
-rw-r--r--config/metrics/license/20210201124933_uuid.yml2
-rw-r--r--config/metrics/license/20210204124827_hostname.yml3
-rw-r--r--config/metrics/license/20210204124829_active_user_count.yml3
-rw-r--r--config/metrics/license/20210204124928_version.yml15
-rw-r--r--config/metrics/license/20210204124936_pages_version.yml3
-rw-r--r--config/metrics/license/20210204124938_recording_ce_finished_at.yml4
-rw-r--r--config/metrics/license/20210216175601_version.yml4
-rw-r--r--config/metrics/license/20210216175602_installation_type.yml4
-rw-r--r--config/metrics/license/20210216181053_version.yml3
-rw-r--r--config/metrics/license/20210216183237_version.yml3
-rw-r--r--config/metrics/objects_schemas/user_auth_by_provider.json16
-rw-r--r--config/metrics/schema.json8
-rw-r--r--config/metrics/settings/20210201124935_database_adapter.yml7
-rw-r--r--config/metrics/settings/20210204124856_instance_auto_devops_enabled.yml3
-rw-r--r--config/metrics/settings/20210204124858_container_registry_enabled.yml3
-rw-r--r--config/metrics/settings/20210204124900_dependency_proxy_enabled.yml3
-rw-r--r--config/metrics/settings/20210204124902_gitlab_shared_runners_enabled.yml3
-rw-r--r--config/metrics/settings/20210204124904_gravatar_enabled.yml3
-rw-r--r--config/metrics/settings/20210204124906_ldap_enabled.yml15
-rw-r--r--config/metrics/settings/20210204124908_mattermost_enabled.yml3
-rw-r--r--config/metrics/settings/20210204124910_omniauth_enabled.yml15
-rw-r--r--config/metrics/settings/20210204124912_prometheus_enabled.yml3
-rw-r--r--config/metrics/settings/20210204124914_prometheus_metrics_enabled.yml3
-rw-r--r--config/metrics/settings/20210204124916_reply_by_email_enabled.yml3
-rw-r--r--config/metrics/settings/20210204124918_signup_enabled.yml4
-rw-r--r--config/metrics/settings/20210204124920_web_ide_clientside_preview_enabled.yml3
-rw-r--r--config/metrics/settings/20210204124922_grafana_link_enabled.yml3
-rw-r--r--config/metrics/settings/20210204124934_pages_enabled.yml3
-rw-r--r--config/metrics/settings/20210216174829_smtp_server.yml3
-rw-r--r--config/metrics/settings/20210216175459_ingress_modsecurity_enabled.yml1
-rw-r--r--config/metrics/settings/20210216175604_edition.yml3
-rw-r--r--config/metrics/settings/20210216175606_ldap_encrypted_secrets_enabled.yml3
-rw-r--r--config/metrics/settings/20210216175609_version.yml3
-rw-r--r--config/metrics/settings/20210216180314_gitpod_enabled.yml3
-rw-r--r--config/metrics/settings/20210216180836_enabled.yml3
-rw-r--r--config/metrics/settings/20210216180838_enabled.yml3
-rw-r--r--config/metrics/settings/20210216180840_direct_upload.yml3
-rw-r--r--config/metrics/settings/20210216180841_background_upload.yml3
-rw-r--r--config/metrics/settings/20210216180843_provider.yml3
-rw-r--r--config/metrics/settings/20210216180845_enabled.yml3
-rw-r--r--config/metrics/settings/20210216180847_enabled.yml3
-rw-r--r--config/metrics/settings/20210216180849_direct_upload.yml3
-rw-r--r--config/metrics/settings/20210216180851_background_upload.yml3
-rw-r--r--config/metrics/settings/20210216180852_provider.yml3
-rw-r--r--config/metrics/settings/20210216180854_enabled.yml3
-rw-r--r--config/metrics/settings/20210216180856_enabled.yml3
-rw-r--r--config/metrics/settings/20210216180858_direct_upload.yml3
-rw-r--r--config/metrics/settings/20210216180900_background_upload.yml3
-rw-r--r--config/metrics/settings/20210216180902_provider.yml3
-rw-r--r--config/metrics/settings/20210216180903_enabled.yml3
-rw-r--r--config/metrics/settings/20210216180905_enabled.yml3
-rw-r--r--config/metrics/settings/20210216180907_direct_upload.yml3
-rw-r--r--config/metrics/settings/20210216180909_background_upload.yml3
-rw-r--r--config/metrics/settings/20210216180911_provider.yml3
-rw-r--r--config/metrics/settings/20210216180913_enabled.yml3
-rw-r--r--config/metrics/settings/20210216180915_enabled.yml3
-rw-r--r--config/metrics/settings/20210216180916_direct_upload.yml3
-rw-r--r--config/metrics/settings/20210216180918_background_upload.yml3
-rw-r--r--config/metrics/settings/20210216180920_provider.yml3
-rw-r--r--config/metrics/settings/20210216183241_filesystems.yml20
-rw-r--r--config/metrics/settings/20210216183248_pg_system_id.yml9
-rw-r--r--config/metrics/settings/20210225045628_operating_system.yml2
-rw-r--r--config/metrics/settings/20210321224827_gitaly_apdex.yml2
-rw-r--r--config/metrics/settings/20210323120839_topology.yml2
-rw-r--r--config/metrics/settings/20210702140138_collected_data_categories.yml2
-rw-r--r--config/metrics/settings/20210812202137_smtp_encrypted_secrets_enabled.yml2
-rw-r--r--config/metrics/settings/20210915152326_service_ping_features_enabled.yml23
-rw-r--r--config/pseudonymizer.yml1
-rw-r--r--config/routes.rb8
-rw-r--r--config/routes/admin.rb1
-rw-r--r--config/routes/jira_connect.rb6
-rw-r--r--config/routes/members.rb7
-rw-r--r--config/routes/project.rb5
-rw-r--r--config/routes/user.rb38
-rw-r--r--config/sidekiq_queues.yml9
-rw-r--r--config/webpack.config.js29
-rw-r--r--config/webpack.vendor.config.js2
-rw-r--r--danger/documentation/Dangerfile2
-rw-r--r--danger/karma/Dangerfile51
-rw-r--r--danger/metadata/Dangerfile8
-rw-r--r--data/deprecations/14-3-database-deprecate-legacy-database-conf.yml13
-rw-r--r--data/deprecations/14-3-repository-push-audit-events.yml14
-rw-r--r--data/deprecations/deprecation_omniauth-kerberos_gem.yml15
-rw-r--r--data/deprecations/distribution_deprecations_14-3.yml8
-rw-r--r--data/deprecations/serverless.yml13
-rw-r--r--data/deprecations/templates/_deprecation_template.md.erb32
-rw-r--r--data/deprecations/templates/example.yml33
-rw-r--r--db/fixtures/development/001_create_base_work_item_types.rb5
-rw-r--r--db/fixtures/development/31_error_tracking.rb5
-rw-r--r--db/fixtures/production/003_create_base_work_item_types.rb5
-rw-r--r--db/migrate/20201029144444_create_vulnerability_finding_links.rb4
-rw-r--r--db/migrate/20210531053916_rename_instance_statistics_measurements.rb4
-rw-r--r--db/migrate/20210621043337_rename_services_to_integrations.rb5
-rw-r--r--db/migrate/20210707113056_add_tags_array_to_ci_pending_builds.rb17
-rw-r--r--db/migrate/20210707163659_add_vulnerability_events_to_integrations.rb9
-rw-r--r--db/migrate/20210708011425_rename_ci_builds_metadata_foreign_key.rb28
-rw-r--r--db/migrate/20210729081351_create_topics.rb16
-rw-r--r--db/migrate/20210729081739_create_project_topics.rb16
-rw-r--r--db/migrate/20210729125641_add_foreign_key_to_project_on_project_topic.rb17
-rw-r--r--db/migrate/20210729125659_add_foreign_key_to_topic_on_project_topic.rb17
-rw-r--r--db/migrate/20210730194555_create_incident_management_pending_issue_escalations.rb33
-rw-r--r--db/migrate/20210807101446_add_cadence_to_dast_profile_schedules.rb7
-rw-r--r--db/migrate/20210807101621_add_timezone_to_dast_profile_schedules.rb26
-rw-r--r--db/migrate/20210807102004_add_starts_at_to_dast_profile_schedules.rb7
-rw-r--r--db/migrate/20210809014850_create_agent_group_authorizations.rb16
-rw-r--r--db/migrate/20210809014918_add_agent_group_authorizations_foreign_keys.rb22
-rw-r--r--db/migrate/20210811120204_create_customer_relations_contacts.rb31
-rw-r--r--db/migrate/20210813131313_create_foreign_key_on_contacts_group_id.rb22
-rw-r--r--db/migrate/20210816095826_add_unique_index_on_dast_profile_to_dast_profile_schedules.rb38
-rw-r--r--db/migrate/20210816192041_add_invites_email_success_to_member.rb13
-rw-r--r--db/migrate/20210817130415_add_project_id_name_version_id_to_npm_packages.rb17
-rw-r--r--db/migrate/20210817172214_add_yaml_limits_application_setting.rb10
-rw-r--r--db/migrate/20210818061156_remove_project_profile_compound_index_from_dast_profile_schedules.rb30
-rw-r--r--db/migrate/20210818115613_add_index_project_id_on_dast_profile_schedule.rb13
-rw-r--r--db/migrate/20210818175949_update_integrations_trigger_type_new_on_insert.rb79
-rw-r--r--db/migrate/20210818185548_add_tag_ids_index_to_ci_pending_build.rb17
-rw-r--r--db/migrate/20210818193008_add_file_template_project_to_service_desk_settings.rb9
-rw-r--r--db/migrate/20210818200455_add_file_template_project_foreign_key_to_service_desk_settings.rb22
-rw-r--r--db/migrate/20210818220234_add_default_project_approval_rules_vuln_allowed.rb24
-rw-r--r--db/migrate/20210819120243_add_throttle_files_api_columns.rb13
-rw-r--r--db/migrate/20210819152723_remove_tmp_index_approval_project_rules_scanners.rb17
-rw-r--r--db/migrate/20210819153805_set_default_job_token_scope_true.rb17
-rw-r--r--db/migrate/20210819162047_add_columns_to_namespace_settings.rb21
-rw-r--r--db/migrate/20210820171834_add_foreign_keys_for_pending_issue_escalations.rb22
-rw-r--r--db/migrate/20210823172643_create_user_group_callout.rb19
-rw-r--r--db/migrate/20210823213417_create_dependency_proxy_image_ttl_group_policies.rb22
-rw-r--r--db/migrate/20210824055322_add_project_namespace_id_to_project.rb21
-rw-r--r--db/migrate/20210824105038_add_timestamp_columns_to_ci_build_trace_metadata.rb8
-rw-r--r--db/migrate/20210824160459_add_notification_level_to_ci_namespace_monthly_usages.rb7
-rw-r--r--db/migrate/20210825104558_change_description_limit_error_tracking_event.rb17
-rw-r--r--db/migrate/20210825104656_create_analytics_cycle_analytics_merge_request_stage_events.rb28
-rw-r--r--db/migrate/20210825110016_create_analytics_cycle_analytics_issue_stage_events.rb28
-rw-r--r--db/migrate/20210825190458_add_user_deactivation_email_option_to_application_settings.rb10
-rw-r--r--db/migrate/20210825193448_add_iteration_cadence_id_to_issue_boards.rb9
-rw-r--r--db/migrate/20210826120834_add_locked_to_ci_job_artifacts.rb22
-rw-r--r--db/migrate/20210826122748_create_loose_foreign_keys_deleted_records.rb26
-rw-r--r--db/migrate/20210826124311_add_index_to_error_tracking_error.rb23
-rw-r--r--db/migrate/20210826145509_add_function_for_inserting_deleted_records.rb27
-rw-r--r--db/migrate/20210826170902_add_throttle_unauthenticated_api_columns.rb10
-rw-r--r--db/migrate/20210830085837_add_throttle_authenticated_git_lfs_columns.rb23
-rw-r--r--db/migrate/20210830140524_add_state_to_member.rb21
-rw-r--r--db/migrate/20210830154358_add_yaml_limit_constraints.rb25
-rw-r--r--db/migrate/20210831134840_add_package_file_id_channel_idx_to_packages_helm_file_metadata.rb17
-rw-r--r--db/migrate/20210831135249_add_installable_helm_pkgs_idx_to_packages.rb17
-rw-r--r--db/migrate/20210831203408_upsert_base_work_item_types.rb31
-rw-r--r--db/migrate/20210901065504_add_index_on_name_and_id_to_public_groups.rb17
-rw-r--r--db/migrate/20210902171406_add_latest_column_into_the_security_scans_table.rb13
-rw-r--r--db/migrate/20210902171808_set_default_job_token_scope_false.rb17
-rw-r--r--db/migrate/20210902184334_add_expire_access_tokens_to_doorkeeper_application.rb7
-rw-r--r--db/migrate/20210903054158_recreate_stage_issue_events_table_with_bigints.rb45
-rw-r--r--db/migrate/20210906100021_delete_project_namespace_trigger.rb31
-rw-r--r--db/migrate/20210907182337_add_group_id_fkey_for_user_group_callout.rb15
-rw-r--r--db/migrate/20210907182359_add_user_id_fkey_for_user_group_callout.rb15
-rw-r--r--db/migrate/20210908060951_add_dast_schedules_to_plan_limits.rb7
-rw-r--r--db/migrate/20210908061132_insert_dast_profile_schedules_plan_limits.rb27
-rw-r--r--db/migrate/20210908100810_add_jobs_per_stage_page_size_to_application_settings.rb7
-rw-r--r--db/migrate/20210908140437_add_sidekiq_limits_to_application_settings.rb21
-rw-r--r--db/migrate/20210908185736_add_status_to_dependency_proxy_manifests.rb7
-rw-r--r--db/migrate/20210908185754_add_status_to_dependency_proxy_blobs.rb7
-rw-r--r--db/migrate/20210909184349_add_index_package_id_id_on_package_files.rb17
-rw-r--r--db/migrate/20210910141043_change_ci_minutes_additional_pack_text_limit.rb15
-rw-r--r--db/migrate/20210913010411_create_agent_project_authorizations.rb14
-rw-r--r--db/migrate/20210913010432_add_agent_project_authorizations_foreign_keys.rb20
-rw-r--r--db/migrate/20210913122457_add_namespace_traversal_ids_to_ci_pending_builds.rb9
-rw-r--r--db/post_migrate/20201106134950_deduplicate_epic_iids.rb2
-rw-r--r--db/post_migrate/20210622045705_finalize_events_bigint_conversion.rb86
-rw-r--r--db/post_migrate/20210701141346_finalize_ci_builds_stage_id_bigint_conversion.rb65
-rw-r--r--db/post_migrate/20210706112800_remove_cloud_license_enabled_from_application_settings.rb19
-rw-r--r--db/post_migrate/20210708011426_finalize_ci_builds_metadata_bigint_conversion.rb113
-rw-r--r--db/post_migrate/20210721122840_remove_seat_link_enabled_from_application_settings.rb11
-rw-r--r--db/post_migrate/20210730104800_schedule_extract_project_topics_into_separate_table.rb37
-rw-r--r--db/post_migrate/20210731132939_backfill_stage_event_hash.rb115
-rw-r--r--db/post_migrate/20210806131706_finalize_taggins_bigint_conversion.rb88
-rw-r--r--db/post_migrate/20210813151908_replace_external_wiki_triggers.rb66
-rw-r--r--db/post_migrate/20210817024335_prepare_indexes_for_events_bigint_conversion.rb24
-rw-r--r--db/post_migrate/20210818185845_backfill_projects_with_coverage.rb32
-rw-r--r--db/post_migrate/20210819145000_drop_temporary_columns_and_triggers_for_ci_builds_runner_session.rb28
-rw-r--r--db/post_migrate/20210823113259_steal_merge_request_diff_commit_users_migration.rb28
-rw-r--r--db/post_migrate/20210823132600_remove_duplicate_dast_site_tokens.rb33
-rw-r--r--db/post_migrate/20210823142036_drop_temporary_trigger_for_ci_job_artifacts.rb30
-rw-r--r--db/post_migrate/20210823193234_remove_allow_editing_commit_messages_from_project_settings.rb19
-rw-r--r--db/post_migrate/20210824102624_add_project_namespace_index_to_project.rb17
-rw-r--r--db/post_migrate/20210824102750_add_project_namespace_foreign_key_to_project.rb19
-rw-r--r--db/post_migrate/20210824174615_prepare_ci_builds_metadata_and_ci_build_async_indexes.rb55
-rw-r--r--db/post_migrate/20210825150212_cleanup_remaining_orphan_invites.rb27
-rw-r--r--db/post_migrate/20210825182303_remove_duplicate_dast_site_tokens_with_same_token.rb23
-rw-r--r--db/post_migrate/20210825193548_add_fk_to_iteration_cadence_id_on_boards.rb19
-rw-r--r--db/post_migrate/20210825193652_backfill_cadence_id_for_boards_scoped_to_iteration.rb49
-rw-r--r--db/post_migrate/20210826110839_prepare_indexes_for_ci_job_artifacts_expire_at_unlocked.rb16
-rw-r--r--db/post_migrate/20210826171758_initialize_throttle_unauthenticated_api_columns.rb23
-rw-r--r--db/post_migrate/20210826193907_add_unique_index_dast_site_token_project_id_and_url.rb19
-rw-r--r--db/post_migrate/20210830104800_reschedule_extract_project_topics_into_separate_table.rb18
-rw-r--r--db/post_migrate/20210831123008_drop_temporary_trigger_for_ci_sources_pipelines.rb28
-rw-r--r--db/post_migrate/20210901044202_push_event_payloads_bigint_conversion_remove_triggers.rb28
-rw-r--r--db/post_migrate/20210901044237_events_bigint_conversion_remove_triggers.rb26
-rw-r--r--db/post_migrate/20210901153324_slice_merge_request_diff_commit_migrations.rb59
-rw-r--r--db/post_migrate/20210901184511_prepare_async_indexes_for_ci_builds.rb80
-rw-r--r--db/post_migrate/20210902144144_drop_temporary_columns_and_triggers_for_ci_build_needs.rb26
-rw-r--r--db/post_migrate/20210906100316_drop_temporary_columns_and_triggers_for_ci_build_trace_chunks.rb20
-rw-r--r--db/post_migrate/20210907021940_cleanup_bigint_conversion_for_ci_stages.rb19
-rw-r--r--db/post_migrate/20210907033745_cleanup_bigint_conversion_for_deployments.rb19
-rw-r--r--db/post_migrate/20210907041000_cleanup_bigint_conversion_for_geo_job_artifact_deleted_events.rb19
-rw-r--r--db/post_migrate/20210907211557_finalize_ci_builds_bigint_conversion.rb222
-rw-r--r--db/post_migrate/20210908132335_disable_job_token_scope_when_unused.rb52
-rw-r--r--db/post_migrate/20210909104800_reschedule_extract_project_topics_into_separate_table_2.rb16
-rw-r--r--db/post_migrate/20210909152027_remove_container_registry_enabled.rb17
-rw-r--r--db/post_migrate/20210914094840_add_gin_index_on_pending_builds_namespace_traversal_ids.rb15
-rw-r--r--db/post_migrate/20210915202900_prepare_index_resource_group_status_commit_id_for_ci_builds.rb15
-rw-r--r--db/schema_migrations/202106220457051
-rw-r--r--db/schema_migrations/202107011413461
-rw-r--r--db/schema_migrations/202107061128001
-rw-r--r--db/schema_migrations/202107071130561
-rw-r--r--db/schema_migrations/202107071636591
-rw-r--r--db/schema_migrations/202107080114251
-rw-r--r--db/schema_migrations/202107080114261
-rw-r--r--db/schema_migrations/202107211228401
-rw-r--r--db/schema_migrations/202107290813511
-rw-r--r--db/schema_migrations/202107290817391
-rw-r--r--db/schema_migrations/202107291256411
-rw-r--r--db/schema_migrations/202107291256591
-rw-r--r--db/schema_migrations/202107301048001
-rw-r--r--db/schema_migrations/202107301945551
-rw-r--r--db/schema_migrations/202107311329391
-rw-r--r--db/schema_migrations/202108061317061
-rw-r--r--db/schema_migrations/202108071014461
-rw-r--r--db/schema_migrations/202108071016211
-rw-r--r--db/schema_migrations/202108071020041
-rw-r--r--db/schema_migrations/202108090148501
-rw-r--r--db/schema_migrations/202108090149181
-rw-r--r--db/schema_migrations/202108111202041
-rw-r--r--db/schema_migrations/202108131313131
-rw-r--r--db/schema_migrations/202108131519081
-rw-r--r--db/schema_migrations/202108160958261
-rw-r--r--db/schema_migrations/202108161920411
-rw-r--r--db/schema_migrations/202108170243351
-rw-r--r--db/schema_migrations/202108171304151
-rw-r--r--db/schema_migrations/202108171722141
-rw-r--r--db/schema_migrations/202108180611561
-rw-r--r--db/schema_migrations/202108181156131
-rw-r--r--db/schema_migrations/202108181759491
-rw-r--r--db/schema_migrations/202108181855481
-rw-r--r--db/schema_migrations/202108181858451
-rw-r--r--db/schema_migrations/202108181930081
-rw-r--r--db/schema_migrations/202108182004551
-rw-r--r--db/schema_migrations/202108182202341
-rw-r--r--db/schema_migrations/202108191202431
-rw-r--r--db/schema_migrations/202108191450001
-rw-r--r--db/schema_migrations/202108191527231
-rw-r--r--db/schema_migrations/202108191538051
-rw-r--r--db/schema_migrations/202108191620471
-rw-r--r--db/schema_migrations/202108201718341
-rw-r--r--db/schema_migrations/202108231132591
-rw-r--r--db/schema_migrations/202108231326001
-rw-r--r--db/schema_migrations/202108231420361
-rw-r--r--db/schema_migrations/202108231726431
-rw-r--r--db/schema_migrations/202108231932341
-rw-r--r--db/schema_migrations/202108232134171
-rw-r--r--db/schema_migrations/202108240553221
-rw-r--r--db/schema_migrations/202108241026241
-rw-r--r--db/schema_migrations/202108241027501
-rw-r--r--db/schema_migrations/202108241050381
-rw-r--r--db/schema_migrations/202108241604591
-rw-r--r--db/schema_migrations/202108241746151
-rw-r--r--db/schema_migrations/202108251045581
-rw-r--r--db/schema_migrations/202108251046561
-rw-r--r--db/schema_migrations/202108251100161
-rw-r--r--db/schema_migrations/202108251502121
-rw-r--r--db/schema_migrations/202108251823031
-rw-r--r--db/schema_migrations/202108251904581
-rw-r--r--db/schema_migrations/202108251934481
-rw-r--r--db/schema_migrations/202108251935481
-rw-r--r--db/schema_migrations/202108251936521
-rw-r--r--db/schema_migrations/202108261108391
-rw-r--r--db/schema_migrations/202108261208341
-rw-r--r--db/schema_migrations/202108261227481
-rw-r--r--db/schema_migrations/202108261243111
-rw-r--r--db/schema_migrations/202108261455091
-rw-r--r--db/schema_migrations/202108261709021
-rw-r--r--db/schema_migrations/202108261717581
-rw-r--r--db/schema_migrations/202108261939071
-rw-r--r--db/schema_migrations/202108300858371
-rw-r--r--db/schema_migrations/202108301048001
-rw-r--r--db/schema_migrations/202108301405241
-rw-r--r--db/schema_migrations/202108301543581
-rw-r--r--db/schema_migrations/202108311230081
-rw-r--r--db/schema_migrations/202108311348401
-rw-r--r--db/schema_migrations/202108311352491
-rw-r--r--db/schema_migrations/202108312034081
-rw-r--r--db/schema_migrations/202109010442021
-rw-r--r--db/schema_migrations/202109010442371
-rw-r--r--db/schema_migrations/202109010655041
-rw-r--r--db/schema_migrations/202109011533241
-rw-r--r--db/schema_migrations/202109011845111
-rw-r--r--db/schema_migrations/202109021441441
-rw-r--r--db/schema_migrations/202109021714061
-rw-r--r--db/schema_migrations/202109021718081
-rw-r--r--db/schema_migrations/202109021843341
-rw-r--r--db/schema_migrations/202109030541581
-rw-r--r--db/schema_migrations/202109061000211
-rw-r--r--db/schema_migrations/202109061003161
-rw-r--r--db/schema_migrations/202109070219401
-rw-r--r--db/schema_migrations/202109070337451
-rw-r--r--db/schema_migrations/202109070410001
-rw-r--r--db/schema_migrations/202109071823371
-rw-r--r--db/schema_migrations/202109071823591
-rw-r--r--db/schema_migrations/202109072115571
-rw-r--r--db/schema_migrations/202109080609511
-rw-r--r--db/schema_migrations/202109080611321
-rw-r--r--db/schema_migrations/202109081008101
-rw-r--r--db/schema_migrations/202109081323351
-rw-r--r--db/schema_migrations/202109081404371
-rw-r--r--db/schema_migrations/202109081857361
-rw-r--r--db/schema_migrations/202109081857541
-rw-r--r--db/schema_migrations/202109091048001
-rw-r--r--db/schema_migrations/202109091520271
-rw-r--r--db/schema_migrations/202109091843491
-rw-r--r--db/schema_migrations/202109101410431
-rw-r--r--db/schema_migrations/202109130104111
-rw-r--r--db/schema_migrations/202109130104321
-rw-r--r--db/schema_migrations/202109131224571
-rw-r--r--db/schema_migrations/202109140948401
-rw-r--r--db/schema_migrations/202109152029001
-rw-r--r--db/structure.sql1739
-rw-r--r--doc/.vale/gitlab/Acronyms.yml1
-rw-r--r--doc/.vale/gitlab/BadgeCapitalization.yml3
-rw-r--r--doc/.vale/gitlab/CurlStringsQuoted.yml2
-rw-r--r--doc/.vale/gitlab/ElementDescriptors.yml14
-rw-r--r--doc/.vale/gitlab/HeaderGerunds.yml14
-rw-r--r--doc/.vale/gitlab/InternalLinkExtension.yml2
-rw-r--r--doc/.vale/gitlab/InternalLinkFormat.yml2
-rw-r--r--doc/.vale/gitlab/OutdatedVersions.yml2
-rw-r--r--doc/.vale/gitlab/ReadingLevel.yml1
-rw-r--r--doc/.vale/gitlab/SubstitutionSuggestions.yml2
-rw-r--r--doc/.vale/gitlab/UnclearAntecedent.yml22
-rw-r--r--doc/.vale/gitlab/VersionText.yml8
-rw-r--r--doc/.vale/gitlab/spelling-exceptions.txt10
-rw-r--r--doc/administration/audit_events.md22
-rw-r--r--doc/administration/auditor_users.md2
-rw-r--r--doc/administration/auth/atlassian.md2
-rw-r--r--doc/administration/auth/ldap/google_secure_ldap.md4
-rw-r--r--doc/administration/auth/ldap/index.md64
-rw-r--r--doc/administration/auth/ldap/ldap-troubleshooting.md20
-rw-r--r--doc/administration/auth/smartcard.md6
-rw-r--r--doc/administration/cicd.md75
-rw-r--r--doc/administration/clusters/kas.md22
-rw-r--r--doc/administration/compliance.md1
-rw-r--r--doc/administration/configure.md2
-rw-r--r--doc/administration/consul.md2
-rw-r--r--doc/administration/database_load_balancing.md8
-rw-r--r--doc/administration/encrypted_configuration.md6
-rw-r--r--doc/administration/geo/disaster_recovery/background_verification.md10
-rw-r--r--doc/administration/geo/disaster_recovery/planned_failover.md10
-rw-r--r--doc/administration/geo/disaster_recovery/runbooks/planned_failover_multi_node.md8
-rw-r--r--doc/administration/geo/disaster_recovery/runbooks/planned_failover_single_node.md6
-rw-r--r--doc/administration/geo/index.md14
-rw-r--r--doc/administration/geo/replication/configuration.md8
-rw-r--r--doc/administration/geo/replication/datatypes.md16
-rw-r--r--doc/administration/geo/replication/disable_geo.md2
-rw-r--r--doc/administration/geo/replication/docker_registry.md2
-rw-r--r--doc/administration/geo/replication/faq.md2
-rw-r--r--doc/administration/geo/replication/object_storage.md16
-rw-r--r--doc/administration/geo/replication/remove_geo_site.md2
-rw-r--r--doc/administration/geo/replication/troubleshooting.md6
-rw-r--r--doc/administration/geo/replication/tuning.md2
-rw-r--r--doc/administration/geo/replication/updating_the_geo_nodes.md53
-rw-r--r--doc/administration/geo/replication/updating_the_geo_sites.md54
-rw-r--r--doc/administration/geo/replication/usage.md12
-rw-r--r--doc/administration/geo/replication/version_specific_updates.md39
-rw-r--r--doc/administration/geo/setup/database.md77
-rw-r--r--doc/administration/geo/setup/external_database.md2
-rw-r--r--doc/administration/get_started.md6
-rw-r--r--doc/administration/git_protocol.md2
-rw-r--r--doc/administration/gitaly/configure_gitaly.md11
-rw-r--r--doc/administration/gitaly/index.md79
-rw-r--r--doc/administration/gitaly/praefect.md34
-rw-r--r--doc/administration/gitaly/troubleshooting.md8
-rw-r--r--doc/administration/housekeeping.md10
-rw-r--r--doc/administration/incoming_email.md6
-rw-r--r--doc/administration/index.md8
-rw-r--r--doc/administration/instance_limits.md99
-rw-r--r--doc/administration/instance_review.md2
-rw-r--r--doc/administration/integration/kroki.md2
-rw-r--r--doc/administration/integration/mailgun.md41
-rw-r--r--doc/administration/integration/plantuml.md4
-rw-r--r--doc/administration/integration/terminal.md2
-rw-r--r--doc/administration/job_artifacts.md21
-rw-r--r--doc/administration/job_logs.md4
-rw-r--r--doc/administration/logs.md24
-rw-r--r--doc/administration/maintenance_mode/index.md8
-rw-r--r--doc/administration/merge_request_diffs.md6
-rw-r--r--doc/administration/monitoring/gitlab_self_monitoring_project/index.md6
-rw-r--r--doc/administration/monitoring/performance/gitlab_configuration.md2
-rw-r--r--doc/administration/monitoring/performance/grafana_configuration.md4
-rw-r--r--doc/administration/monitoring/performance/performance_bar.md4
-rw-r--r--doc/administration/monitoring/prometheus/gitlab_exporter.md7
-rw-r--r--doc/administration/monitoring/prometheus/gitlab_metrics.md16
-rw-r--r--doc/administration/monitoring/prometheus/index.md8
-rw-r--r--doc/administration/object_storage.md15
-rw-r--r--doc/administration/operations/cleaning_up_redis_sessions.md65
-rw-r--r--doc/administration/operations/extra_sidekiq_processes.md2
-rw-r--r--doc/administration/operations/extra_sidekiq_routing.md31
-rw-r--r--doc/administration/operations/fast_ssh_key_lookup.md2
-rw-r--r--doc/administration/operations/index.md5
-rw-r--r--doc/administration/operations/moving_repositories.md5
-rw-r--r--doc/administration/operations/puma.md50
-rw-r--r--doc/administration/operations/sidekiq_memory_killer.md2
-rw-r--r--doc/administration/operations/ssh_certificates.md3
-rw-r--r--doc/administration/operations/unicorn.md9
-rw-r--r--doc/administration/package_information/defaults.md72
-rw-r--r--doc/administration/package_information/deprecated_os.md82
-rw-r--r--doc/administration/package_information/deprecation_policy.md95
-rw-r--r--doc/administration/package_information/index.md101
-rw-r--r--doc/administration/package_information/licensing.md79
-rw-r--r--doc/administration/package_information/omnibus_packages.md115
-rw-r--r--doc/administration/package_information/postgresql_versions.md42
-rw-r--r--doc/administration/package_information/signed_packages.md25
-rw-r--r--doc/administration/packages/container_registry.md78
-rw-r--r--doc/administration/packages/dependency_proxy.md2
-rw-r--r--doc/administration/packages/img/gitlab-registry-architecture.pngbin0 -> 31003 bytes
-rw-r--r--doc/administration/packages/index.md27
-rw-r--r--doc/administration/pages/index.md124
-rw-r--r--doc/administration/pages/source.md2
-rw-r--r--doc/administration/polling.md2
-rw-r--r--doc/administration/postgresql/pgbouncer.md2
-rw-r--r--doc/administration/postgresql/replication_and_failover.md16
-rw-r--r--doc/administration/pseudonymizer.md2
-rw-r--r--doc/administration/raketasks/check.md25
-rw-r--r--doc/administration/raketasks/github_import.md2
-rw-r--r--doc/administration/raketasks/ldap.md5
-rw-r--r--doc/administration/raketasks/praefect.md2
-rw-r--r--doc/administration/raketasks/project_import_export.md2
-rw-r--r--doc/administration/raketasks/storage.md2
-rw-r--r--doc/administration/redis/replication_and_failover_external.md2
-rw-r--r--doc/administration/redis/troubleshooting.md2
-rw-r--r--doc/administration/reference_architectures/10k_users.md4
-rw-r--r--doc/administration/reference_architectures/1k_users.md2
-rw-r--r--doc/administration/reference_architectures/25k_users.md2
-rw-r--r--doc/administration/reference_architectures/2k_users.md2
-rw-r--r--doc/administration/reference_architectures/3k_users.md2
-rw-r--r--doc/administration/reference_architectures/50k_users.md2
-rw-r--r--doc/administration/reference_architectures/5k_users.md2
-rw-r--r--doc/administration/reference_architectures/index.md4
-rw-r--r--doc/administration/reference_architectures/troubleshooting.md2
-rw-r--r--doc/administration/repository_checks.md6
-rw-r--r--doc/administration/repository_storage_paths.md2
-rw-r--r--doc/administration/repository_storage_types.md2
-rw-r--r--doc/administration/static_objects_external_storage.md4
-rw-r--r--doc/administration/troubleshooting/diagnostics_tools.md5
-rw-r--r--doc/administration/troubleshooting/elasticsearch.md2
-rw-r--r--doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md21
-rw-r--r--doc/administration/troubleshooting/log_parsing.md6
-rw-r--r--doc/administration/troubleshooting/postgresql.md6
-rw-r--r--doc/administration/troubleshooting/tracing_correlation_id.md10
-rw-r--r--doc/administration/uploads.md4
-rw-r--r--doc/administration/whats-new.md2
-rw-r--r--doc/api/access_requests.md2
-rw-r--r--doc/api/admin_sidekiq_queues.md19
-rw-r--r--doc/api/api_resources.md6
-rw-r--r--doc/api/applications.md2
-rw-r--r--doc/api/avatar.md2
-rw-r--r--doc/api/award_emoji.md2
-rw-r--r--doc/api/boards.md2
-rw-r--r--doc/api/branches.md6
-rw-r--r--doc/api/broadcast_messages.md4
-rw-r--r--doc/api/bulk_imports.md2
-rw-r--r--doc/api/commits.md6
-rw-r--r--doc/api/container_registry.md4
-rw-r--r--doc/api/custom_attributes.md2
-rw-r--r--doc/api/dependency_proxy.md7
-rw-r--r--doc/api/deploy_keys.md15
-rw-r--r--doc/api/deploy_tokens.md4
-rw-r--r--doc/api/deployments.md2
-rw-r--r--doc/api/discussions.md205
-rw-r--r--doc/api/dora/metrics.md4
-rw-r--r--doc/api/dora4_project_analytics.md2
-rw-r--r--doc/api/environments.md4
-rw-r--r--doc/api/epic_links.md2
-rw-r--r--doc/api/error_tracking.md86
-rw-r--r--doc/api/events.md8
-rw-r--r--doc/api/feature_flag_specs.md2
-rw-r--r--doc/api/features.md2
-rw-r--r--doc/api/freeze_periods.md2
-rw-r--r--doc/api/geo_nodes.md27
-rw-r--r--doc/api/graphql/audit_report.md2
-rw-r--r--doc/api/graphql/custom_emoji.md4
-rw-r--r--doc/api/graphql/index.md2
-rw-r--r--doc/api/graphql/reference/index.md1891
-rw-r--r--doc/api/graphql/removed_items.md4
-rw-r--r--doc/api/graphql/users_example.md2
-rw-r--r--doc/api/group_activity_analytics.md2
-rw-r--r--doc/api/group_badges.md2
-rw-r--r--doc/api/group_boards.md14
-rw-r--r--doc/api/group_import_export.md2
-rw-r--r--doc/api/group_labels.md4
-rw-r--r--doc/api/group_level_variables.md2
-rw-r--r--doc/api/group_milestones.md2
-rw-r--r--doc/api/group_protected_environments.md14
-rw-r--r--doc/api/group_relations_export.md2
-rw-r--r--doc/api/group_wikis.md2
-rw-r--r--doc/api/groups.md19
-rw-r--r--doc/api/index.md160
-rw-r--r--doc/api/instance_clusters.md2
-rw-r--r--doc/api/instance_level_ci_variables.md2
-rw-r--r--doc/api/issue_links.md2
-rw-r--r--doc/api/issues.md73
-rw-r--r--doc/api/job_artifacts.md10
-rw-r--r--doc/api/jobs.md2
-rw-r--r--doc/api/labels.md4
-rw-r--r--doc/api/lint.md4
-rw-r--r--doc/api/members.md6
-rw-r--r--doc/api/merge_request_approvals.md4
-rw-r--r--doc/api/merge_requests.md28
-rw-r--r--doc/api/metrics_dashboard_annotations.md2
-rw-r--r--doc/api/metrics_user_starred_dashboards.md2
-rw-r--r--doc/api/milestones.md2
-rw-r--r--doc/api/notification_settings.md2
-rw-r--r--doc/api/oauth2.md44
-rw-r--r--doc/api/packages.md2
-rw-r--r--doc/api/packages/composer.md15
-rw-r--r--doc/api/packages/conan.md2
-rw-r--r--doc/api/packages/go_proxy.md2
-rw-r--r--doc/api/packages/helm.md10
-rw-r--r--doc/api/packages/maven.md2
-rw-r--r--doc/api/packages/npm.md12
-rw-r--r--doc/api/packages/nuget.md4
-rw-r--r--doc/api/packages/pypi.md10
-rw-r--r--doc/api/packages/rubygems.md2
-rw-r--r--doc/api/pages.md2
-rw-r--r--doc/api/pages_domains.md2
-rw-r--r--doc/api/personal_access_tokens.md10
-rw-r--r--doc/api/pipeline_triggers.md3
-rw-r--r--doc/api/pipelines.md6
-rw-r--r--doc/api/plan_limits.md2
-rw-r--r--doc/api/project_aliases.md2
-rw-r--r--doc/api/project_clusters.md2
-rw-r--r--doc/api/project_level_variables.md2
-rw-r--r--doc/api/project_vulnerabilities.md2
-rw-r--r--doc/api/projects.md18
-rw-r--r--doc/api/protected_environments.md2
-rw-r--r--doc/api/releases/index.md36
-rw-r--r--doc/api/releases/links.md2
-rw-r--r--doc/api/repositories.md20
-rw-r--r--doc/api/resource_access_tokens.md2
-rw-r--r--doc/api/resource_label_events.md2
-rw-r--r--doc/api/runners.md57
-rw-r--r--doc/api/scim.md2
-rw-r--r--doc/api/services.md14
-rw-r--r--doc/api/settings.md22
-rw-r--r--doc/api/statistics.md2
-rw-r--r--doc/api/status_checks.md12
-rw-r--r--doc/api/system_hooks.md4
-rw-r--r--doc/api/templates/dockerfiles.md2
-rw-r--r--doc/api/templates/gitignores.md2
-rw-r--r--doc/api/templates/gitlab_ci_ymls.md2
-rw-r--r--doc/api/templates/licenses.md2
-rw-r--r--doc/api/usage_data.md4
-rw-r--r--doc/api/users.md105
-rw-r--r--doc/api/v3_to_v4.md2
-rw-r--r--doc/api/version.md2
-rw-r--r--doc/api/vulnerabilities.md2
-rw-r--r--doc/api/vulnerability_exports.md4
-rw-r--r--doc/api/vulnerability_findings.md2
-rw-r--r--doc/architecture/blueprints/composable_codebase_using_rails_engines/index.md3
-rw-r--r--doc/architecture/blueprints/container_registry_metadata_database/index.md44
-rw-r--r--doc/architecture/blueprints/database/scalability/patterns/img/db_terminology_v14_2.pngbin51264 -> 0 bytes
-rw-r--r--doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_licenses_calls_v14_2.pngbin157824 -> 50040 bytes
-rw-r--r--doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_licenses_fixed_v14_2.pngbin85790 -> 33505 bytes
-rw-r--r--doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_readwriteratio_v14_2.pngbin93291 -> 26819 bytes
-rw-r--r--doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_subscriptions_reads_v14_2.pngbin60703 -> 22800 bytes
-rw-r--r--doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_subscriptions_writes_v14_2.pngbin52727 -> 22380 bytes
-rw-r--r--doc/ci/caching/index.md10
-rw-r--r--doc/ci/chatops/index.md4
-rw-r--r--doc/ci/ci_cd_for_external_repos/github_integration.md4
-rw-r--r--doc/ci/ci_cd_for_external_repos/index.md4
-rw-r--r--doc/ci/cloud_deployment/index.md2
-rw-r--r--doc/ci/directed_acyclic_graph/index.md2
-rw-r--r--doc/ci/docker/using_docker_build.md2
-rw-r--r--doc/ci/enable_or_disable_ci.md79
-rw-r--r--doc/ci/environments/deployment_safety.md4
-rw-r--r--doc/ci/environments/environments_dashboard.md2
-rw-r--r--doc/ci/environments/incremental_rollouts.md4
-rw-r--r--doc/ci/environments/index.md53
-rw-r--r--doc/ci/environments/protected_environments.md35
-rw-r--r--doc/ci/examples/end_to_end_testing_webdriverio/index.md4
-rw-r--r--doc/ci/examples/index.md21
-rw-r--r--doc/ci/index.md71
-rw-r--r--doc/ci/interactive_web_terminal/index.md5
-rw-r--r--doc/ci/jobs/ci_job_token.md165
-rw-r--r--doc/ci/jobs/img/job_group_v12_10.pngbin5436 -> 0 bytes
-rw-r--r--doc/ci/jobs/img/pipeline_delayed_job_v14_2.pngbin0 -> 27591 bytes
-rw-r--r--doc/ci/jobs/img/pipeline_grouped_jobs_v14_2.pngbin0 -> 38540 bytes
-rw-r--r--doc/ci/jobs/img/pipeline_incremental_rollout.pngbin4794 -> 0 bytes
-rw-r--r--doc/ci/jobs/img/pipelines_grouped.pngbin12888 -> 0 bytes
-rw-r--r--doc/ci/jobs/index.md10
-rw-r--r--doc/ci/jobs/job_control.md35
-rw-r--r--doc/ci/large_repositories/index.md9
-rw-r--r--doc/ci/lint.md7
-rw-r--r--doc/ci/migration/circleci.md12
-rw-r--r--doc/ci/migration/jenkins.md8
-rw-r--r--doc/ci/pipeline_editor/index.md2
-rw-r--r--doc/ci/pipelines/img/manual_pipeline_v14_2.pngbin0 -> 24536 bytes
-rw-r--r--doc/ci/pipelines/img/pipelines.pngbin6298 -> 0 bytes
-rw-r--r--doc/ci/pipelines/img/pipelines_graph_stage_view_v13_12.pngbin25204 -> 0 bytes
-rw-r--r--doc/ci/pipelines/img/pipelines_graph_stage_view_v14_2.pngbin0 -> 29978 bytes
-rw-r--r--doc/ci/pipelines/index.md29
-rw-r--r--doc/ci/pipelines/multi_project_pipelines.md2
-rw-r--r--doc/ci/pipelines/parent_child_pipelines.md9
-rw-r--r--doc/ci/pipelines/pipeline_efficiency.md1
-rw-r--r--doc/ci/pipelines/settings.md3
-rw-r--r--doc/ci/quick_start/index.md23
-rw-r--r--doc/ci/review_apps/index.md2
-rw-r--r--doc/ci/runners/build_cloud/macos/environment.md6
-rw-r--r--doc/ci/runners/build_cloud/macos_build_cloud.md4
-rw-r--r--doc/ci/runners/configure_runners.md70
-rw-r--r--doc/ci/runners/index.md2
-rw-r--r--doc/ci/runners/runners_scope.md8
-rw-r--r--doc/ci/secrets/index.md2
-rw-r--r--doc/ci/services/gitlab.md9
-rw-r--r--doc/ci/services/index.md58
-rw-r--r--doc/ci/services/mysql.md14
-rw-r--r--doc/ci/services/postgres.md24
-rw-r--r--doc/ci/services/redis.md2
-rw-r--r--doc/ci/triggers/index.md75
-rw-r--r--doc/ci/troubleshooting.md4
-rw-r--r--doc/ci/variables/index.md37
-rw-r--r--doc/ci/variables/predefined_variables.md7
-rw-r--r--doc/ci/variables/where_variables_can_be_used.md35
-rw-r--r--doc/ci/yaml/gitlab_ci_yaml.md2
-rw-r--r--doc/ci/yaml/includes.md187
-rw-r--r--doc/ci/yaml/index.md306
-rw-r--r--doc/ci/yaml/script.md2
-rw-r--r--doc/development/adding_service_component.md3
-rw-r--r--doc/development/api_graphql_styleguide.md6
-rw-r--r--doc/development/application_limits.md4
-rw-r--r--doc/development/architecture.md6
-rw-r--r--doc/development/avoiding_downtime_in_migrations.md24
-rw-r--r--doc/development/background_migrations.md21
-rw-r--r--doc/development/cascading_settings.md4
-rw-r--r--doc/development/changelog.md1
-rw-r--r--doc/development/cicd/cicd_reference_documentation_guide.md2
-rw-r--r--doc/development/cicd/index.md8
-rw-r--r--doc/development/cicd/templates.md14
-rw-r--r--doc/development/code_intelligence/index.md2
-rw-r--r--doc/development/code_review.md92
-rw-r--r--doc/development/contributing/community_roles.md4
-rw-r--r--doc/development/contributing/design.md18
-rw-r--r--doc/development/contributing/issue_workflow.md31
-rw-r--r--doc/development/contributing/merge_request_workflow.md37
-rw-r--r--doc/development/contributing/style_guides.md9
-rw-r--r--doc/development/database/add_foreign_key_to_existing_column.md34
-rw-r--r--doc/development/database/constraint_naming_convention.md5
-rw-r--r--doc/development/database/database_reviewer_guidelines.md4
-rw-r--r--doc/development/database/efficient_in_operator_queries.md949
-rw-r--r--doc/development/database/index.md1
-rw-r--r--doc/development/database/keyset_pagination.md29
-rw-r--r--doc/development/database/multiple_databases.md236
-rw-r--r--doc/development/database/not_null_constraints.md16
-rw-r--r--doc/development/database/pagination_guidelines.md2
-rw-r--r--doc/development/database/rename_database_tables.md4
-rw-r--r--doc/development/database/strings_and_the_text_data_type.md53
-rw-r--r--doc/development/database/table_partitioning.md6
-rw-r--r--doc/development/database/transaction_guidelines.md2
-rw-r--r--doc/development/database_debugging.md36
-rw-r--r--doc/development/database_review.md4
-rw-r--r--doc/development/deprecation_guidelines/index.md2
-rw-r--r--doc/development/documentation/feature_flags.md27
-rw-r--r--doc/development/documentation/index.md203
-rw-r--r--doc/development/documentation/redirects.md155
-rw-r--r--doc/development/documentation/review_apps.md101
-rw-r--r--doc/development/documentation/site_architecture/index.md11
-rw-r--r--doc/development/documentation/styleguide/index.md204
-rw-r--r--doc/development/documentation/styleguide/word_list.md348
-rw-r--r--doc/development/documentation/testing.md34
-rw-r--r--doc/development/elasticsearch.md7
-rw-r--r--doc/development/experiment_guide/experimentation.md2
-rw-r--r--doc/development/experiment_guide/index.md30
-rw-r--r--doc/development/fe_guide/accessibility.md4
-rw-r--r--doc/development/fe_guide/axios.md2
-rw-r--r--doc/development/fe_guide/content_editor.md376
-rw-r--r--doc/development/fe_guide/development_process.md2
-rw-r--r--doc/development/fe_guide/graphql.md44
-rw-r--r--doc/development/fe_guide/img/content_editor_highlevel_diagram.pngbin47794 -> 0 bytes
-rw-r--r--doc/development/fe_guide/index.md2
-rw-r--r--doc/development/fe_guide/source_editor.md2
-rw-r--r--doc/development/github_importer.md13
-rw-r--r--doc/development/go_guide/dependencies.md2
-rw-r--r--doc/development/go_guide/index.md6
-rw-r--r--doc/development/gotchas.md70
-rw-r--r--doc/development/graphql_guide/graphql_pro.md4
-rw-r--r--doc/development/graphql_guide/index.md4
-rw-r--r--doc/development/graphql_guide/pagination.md4
-rw-r--r--doc/development/i18n/externalization.md63
-rw-r--r--doc/development/i18n/proofreader.md5
-rw-r--r--doc/development/img/elasticsearch_architecture.svg2
-rw-r--r--doc/development/import_project.md2
-rw-r--r--doc/development/integrations/jenkins.md4
-rw-r--r--doc/development/integrations/jira_connect.md2
-rw-r--r--doc/development/integrations/secure.md8
-rw-r--r--doc/development/internal_api.md54
-rw-r--r--doc/development/issue_types.md5
-rw-r--r--doc/development/migration_style_guide.md161
-rw-r--r--doc/development/multi_version_compatibility.md4
-rw-r--r--doc/development/packages.md2
-rw-r--r--doc/development/pipelines.md54
-rw-r--r--doc/development/prometheus_metrics.md4
-rw-r--r--doc/development/query_recorder.md8
-rw-r--r--doc/development/rake_tasks.md12
-rw-r--r--doc/development/secure_coding_guidelines.md2
-rw-r--r--doc/development/service_ping/implement.md862
-rw-r--r--doc/development/service_ping/index.md849
-rw-r--r--doc/development/service_ping/metrics_dictionary.md18
-rw-r--r--doc/development/service_ping/metrics_instrumentation.md4
-rw-r--r--doc/development/service_ping/metrics_lifecycle.md4
-rw-r--r--doc/development/service_ping/review_guidelines.md2
-rw-r--r--doc/development/sidekiq_style_guide.md6
-rw-r--r--doc/development/single_table_inheritance.md4
-rw-r--r--doc/development/snowplow/index.md47
-rw-r--r--doc/development/snowplow/review_guidelines.md4
-rw-r--r--doc/development/sql.md4
-rw-r--r--doc/development/stage_group_dashboards.md2
-rw-r--r--doc/development/testing_guide/best_practices.md86
-rw-r--r--doc/development/testing_guide/end_to_end/beginners_guide.md4
-rw-r--r--doc/development/testing_guide/end_to_end/best_practices.md106
-rw-r--r--doc/development/testing_guide/end_to_end/index.md39
-rw-r--r--doc/development/testing_guide/end_to_end/rspec_metadata_tests.md1
-rw-r--r--doc/development/testing_guide/frontend_testing.md193
-rw-r--r--doc/development/testing_guide/index.md4
-rw-r--r--doc/development/testing_guide/review_apps.md2
-rw-r--r--doc/development/testing_guide/testing_levels.md13
-rw-r--r--doc/development/transient/prevention-patterns.md2
-rw-r--r--doc/development/understanding_explain_plans.md2
-rw-r--r--doc/development/work_items.md196
-rw-r--r--doc/downgrade_ee_to_ce/index.md93
-rw-r--r--doc/install/aws/eks_clusters_aws.md53
-rw-r--r--doc/install/aws/gitlab_hybrid_on_aws.md362
-rw-r--r--doc/install/aws/gitlab_sre_for_aws.md59
-rw-r--r--doc/install/aws/index.md866
-rw-r--r--doc/install/aws/manual_install_aws.md850
-rw-r--r--doc/install/azure/index.md2
-rw-r--r--doc/install/docker.md8
-rw-r--r--doc/install/installation.md6
-rw-r--r--doc/install/next_steps.md2
-rw-r--r--doc/install/requirements.md20
-rw-r--r--doc/integration/akismet.md4
-rw-r--r--doc/integration/auth0.md4
-rw-r--r--doc/integration/azure.md48
-rw-r--r--doc/integration/bitbucket.md4
-rw-r--r--doc/integration/cas.md6
-rw-r--r--doc/integration/datadog.md4
-rw-r--r--doc/integration/elasticsearch.md191
-rw-r--r--doc/integration/facebook.md18
-rw-r--r--doc/integration/github.md2
-rw-r--r--doc/integration/gitlab.md2
-rw-r--r--doc/integration/gitpod.md6
-rw-r--r--doc/integration/gmail_action_buttons_for_gitlab.md5
-rw-r--r--doc/integration/google.md18
-rw-r--r--doc/integration/jenkins.md2
-rw-r--r--doc/integration/jenkins_deprecated.md5
-rw-r--r--doc/integration/jira/configure.md2
-rw-r--r--doc/integration/jira/connect-app.md28
-rw-r--r--doc/integration/jira/development_panel.md8
-rw-r--r--doc/integration/jira/dvcs.md44
-rw-r--r--doc/integration/jira/index.md13
-rw-r--r--doc/integration/jira/jira_cloud_configuration.md6
-rw-r--r--doc/integration/jira/jira_server_configuration.md2
-rw-r--r--doc/integration/kerberos.md14
-rw-r--r--doc/integration/mattermost/gitlab-mattermost.msc28
-rw-r--r--doc/integration/mattermost/img/gitlab-mattermost.pngbin0 -> 88419 bytes
-rw-r--r--doc/integration/mattermost/index.md495
-rw-r--r--doc/integration/oauth_provider.md16
-rw-r--r--doc/integration/omniauth.md207
-rw-r--r--doc/integration/openid_connect_provider.md5
-rw-r--r--doc/integration/recaptcha.md14
-rw-r--r--doc/integration/saml.md98
-rw-r--r--doc/integration/slash_commands.md40
-rw-r--r--doc/integration/sourcegraph.md4
-rw-r--r--doc/integration/trello_power_up.md2
-rw-r--r--doc/integration/twitter.md5
-rw-r--r--doc/integration/vault.md2
-rw-r--r--doc/intro/index.md50
-rw-r--r--doc/operations/error_tracking.md53
-rw-r--r--doc/operations/img/error_tracking_setting_v14_3.pngbin0 -> 27537 bytes
-rw-r--r--doc/operations/metrics/alerts.md2
-rw-r--r--doc/policy/alpha-beta-support.md40
-rw-r--r--doc/policy/maintenance.md4
-rw-r--r--doc/public_access/public_access.md24
-rw-r--r--doc/push_rules/push_rules.md8
-rw-r--r--doc/raketasks/backup_restore.md103
-rw-r--r--doc/raketasks/cleanup.md4
-rw-r--r--doc/raketasks/features.md5
-rw-r--r--doc/security/password_length_limits.md2
-rw-r--r--doc/security/rack_attack.md2
-rw-r--r--doc/security/rate_limits.md1
-rw-r--r--doc/security/ssh_keys_restrictions.md14
-rw-r--r--doc/security/token_overview.md6
-rw-r--r--doc/security/two_factor_authentication.md57
-rw-r--r--doc/security/user_email_confirmation.md2
-rw-r--r--doc/security/webhooks.md8
-rw-r--r--doc/ssh/index.md4
-rw-r--r--doc/subscriptions/bronze_starter.md10
-rw-r--r--doc/subscriptions/gitlab_com/index.md29
-rw-r--r--doc/subscriptions/quarterly_reconciliation.md28
-rw-r--r--doc/subscriptions/self_managed/index.md10
-rw-r--r--doc/system_hooks/system_hooks.md4
-rw-r--r--doc/tools/email.md4
-rw-r--r--doc/topics/authentication/index.md6
-rw-r--r--doc/topics/autodevops/customize.md11
-rw-r--r--doc/topics/autodevops/index.md45
-rw-r--r--doc/topics/autodevops/prepare_deployment.md4
-rw-r--r--doc/topics/autodevops/quick_start_guide.md3
-rw-r--r--doc/topics/autodevops/requirements.md12
-rw-r--r--doc/topics/autodevops/stages.md9
-rw-r--r--doc/topics/autodevops/upgrading_auto_deploy_dependencies.md4
-rw-r--r--doc/topics/git/cherry_picking.md55
-rw-r--r--doc/topics/git/git_rebase.md9
-rw-r--r--doc/topics/git/index.md6
-rw-r--r--doc/topics/git/lfs/migrate_to_git_lfs.md5
-rw-r--r--doc/topics/git/numerous_undo_possibilities_in_git/index.md3
-rw-r--r--doc/topics/gitlab_flow.md171
-rw-r--r--doc/topics/img/gitlab_flow.pngbin46844 -> 0 bytes
-rw-r--r--doc/topics/img/gitlab_flow_ci_mr.pngbin12024 -> 0 bytes
-rw-r--r--doc/topics/img/gitlab_flow_close_issue_mr.pngbin42108 -> 0 bytes
-rw-r--r--doc/topics/img/gitlab_flow_environment_branches.pngbin12354 -> 0 bytes
-rw-r--r--doc/topics/img/gitlab_flow_four_stages.pngbin7124 -> 0 bytes
-rw-r--r--doc/topics/img/gitlab_flow_git_pull.pngbin28701 -> 0 bytes
-rw-r--r--doc/topics/img/gitlab_flow_github_flow.pngbin6173 -> 0 bytes
-rw-r--r--doc/topics/img/gitlab_flow_good_commit.pngbin8740 -> 0 bytes
-rw-r--r--doc/topics/img/gitlab_flow_merge_commits.pngbin7564 -> 0 bytes
-rw-r--r--doc/topics/img/gitlab_flow_merge_request.pngbin47225 -> 0 bytes
-rw-r--r--doc/topics/img/gitlab_flow_messy_flow.pngbin11663 -> 0 bytes
-rw-r--r--doc/topics/img/gitlab_flow_production_branch.pngbin7262 -> 0 bytes
-rw-r--r--doc/topics/img/gitlab_flow_rebase.pngbin28939 -> 0 bytes
-rw-r--r--doc/topics/img/gitlab_flow_release_branches.pngbin12736 -> 0 bytes
-rw-r--r--doc/topics/offline/index.md2
-rw-r--r--doc/topics/offline/quick_start_guide.md2
-rw-r--r--doc/update/deprecations.md67
-rw-r--r--doc/update/index.md144
-rw-r--r--doc/update/package/convert_to_ee.md118
-rw-r--r--doc/update/package/downgrade.md83
-rw-r--r--doc/update/package/index.md278
-rw-r--r--doc/update/patch_versions.md2
-rw-r--r--doc/update/plan_your_upgrade.md180
-rw-r--r--doc/update/upgrading_from_ce_to_ee.md2
-rw-r--r--doc/update/upgrading_from_source.md14
-rw-r--r--doc/update/zero_downtime.md942
-rw-r--r--doc/user/admin_area/analytics/dev_ops_report.md7
-rw-r--r--doc/user/admin_area/analytics/img/admin_devops_adoption_v14_2.pngbin67833 -> 25280 bytes
-rw-r--r--doc/user/admin_area/analytics/index.md4
-rw-r--r--doc/user/admin_area/analytics/usage_trends.md2
-rw-r--r--doc/user/admin_area/appearance.md4
-rw-r--r--doc/user/admin_area/broadcast_messages.md6
-rw-r--r--doc/user/admin_area/credentials_inventory.md2
-rw-r--r--doc/user/admin_area/diff_limits.md4
-rw-r--r--doc/user/admin_area/geo_nodes.md4
-rw-r--r--doc/user/admin_area/index.md44
-rw-r--r--doc/user/admin_area/license.md10
-rw-r--r--doc/user/admin_area/merge_requests_approvals.md4
-rw-r--r--doc/user/admin_area/moderate_users.md33
-rw-r--r--doc/user/admin_area/monitoring/health_check.md4
-rw-r--r--doc/user/admin_area/review_abuse_reports.md4
-rw-r--r--doc/user/admin_area/settings/account_and_limit_settings.md48
-rw-r--r--doc/user/admin_area/settings/continuous_integration.md28
-rw-r--r--doc/user/admin_area/settings/email.md20
-rw-r--r--doc/user/admin_area/settings/external_authorization.md4
-rw-r--r--doc/user/admin_area/settings/floc.md4
-rw-r--r--doc/user/admin_area/settings/git_lfs_rate_limits.md35
-rw-r--r--doc/user/admin_area/settings/gitaly_timeouts.md2
-rw-r--r--doc/user/admin_area/settings/help_page.md15
-rw-r--r--doc/user/admin_area/settings/img/domain_denylist_v14_1.pngbin49389 -> 31473 bytes
-rw-r--r--doc/user/admin_area/settings/img/import_export_rate_limits_v13_2.pngbin18320 -> 0 bytes
-rw-r--r--doc/user/admin_area/settings/img/rate_limit_on_issues_creation_v14_2.pngbin29368 -> 10102 bytes
-rw-r--r--doc/user/admin_area/settings/img/user_and_ip_rate_limits.pngbin36909 -> 0 bytes
-rw-r--r--doc/user/admin_area/settings/import_export_rate_limits.md34
-rw-r--r--doc/user/admin_area/settings/index.md15
-rw-r--r--doc/user/admin_area/settings/instance_template_repository.md6
-rw-r--r--doc/user/admin_area/settings/package_registry_rate_limits.md53
-rw-r--r--doc/user/admin_area/settings/project_integration_management.md12
-rw-r--r--doc/user/admin_area/settings/push_event_activities_limit.md4
-rw-r--r--doc/user/admin_area/settings/rate_limit_on_issues_creation.md2
-rw-r--r--doc/user/admin_area/settings/rate_limit_on_notes_creation.md10
-rw-r--r--doc/user/admin_area/settings/rate_limits_on_raw_endpoints.md4
-rw-r--r--doc/user/admin_area/settings/sidekiq_job_limits.md36
-rw-r--r--doc/user/admin_area/settings/sign_in_restrictions.md8
-rw-r--r--doc/user/admin_area/settings/sign_up_restrictions.md28
-rw-r--r--doc/user/admin_area/settings/terms.md4
-rw-r--r--doc/user/admin_area/settings/third_party_offers.md2
-rw-r--r--doc/user/admin_area/settings/usage_statistics.md7
-rw-r--r--doc/user/admin_area/settings/user_and_ip_rate_limits.md85
-rw-r--r--doc/user/admin_area/settings/visibility_and_access_controls.md56
-rw-r--r--doc/user/admin_area/user_cohorts.md4
-rw-r--r--doc/user/analytics/index.md10
-rw-r--r--doc/user/analytics/issue_analytics.md7
-rw-r--r--doc/user/analytics/merge_request_analytics.md9
-rw-r--r--doc/user/analytics/productivity_analytics.md6
-rw-r--r--doc/user/analytics/value_stream_analytics.md4
-rw-r--r--doc/user/application_security/api_fuzzing/index.md17
-rw-r--r--doc/user/application_security/configuration/index.md65
-rw-r--r--doc/user/application_security/container_scanning/index.md70
-rw-r--r--doc/user/application_security/coverage_fuzzing/index.md21
-rw-r--r--doc/user/application_security/dast/browser_based.md2
-rw-r--r--doc/user/application_security/dast/dast_troubleshooting.md4
-rw-r--r--doc/user/application_security/dast/index.md157
-rw-r--r--doc/user/application_security/dast_api/index.md2
-rw-r--r--doc/user/application_security/dependency_list/index.md8
-rw-r--r--doc/user/application_security/dependency_scanning/index.md34
-rw-r--r--doc/user/application_security/img/mr_security_scanning_results_v14_3.pngbin0 -> 32391 bytes
-rw-r--r--doc/user/application_security/index.md19
-rw-r--r--doc/user/application_security/offline_deployments/index.md2
-rw-r--r--doc/user/application_security/policies/img/container_policy_rule_mode_v14_3.pngbin0 -> 39343 bytes
-rw-r--r--doc/user/application_security/policies/img/container_policy_yaml_mode_v14_3.pngbin0 -> 50096 bytes
-rw-r--r--doc/user/application_security/policies/img/policies_list_v14_3.pngbin0 -> 34232 bytes
-rw-r--r--doc/user/application_security/policies/img/scan_execution_policy_yaml_mode_v14_3.pngbin0 -> 23658 bytes
-rw-r--r--doc/user/application_security/policies/img/security_policy_project_v14_3.pngbin0 -> 29763 bytes
-rw-r--r--doc/user/application_security/policies/index.md281
-rw-r--r--doc/user/application_security/sast/analyzers.md4
-rw-r--r--doc/user/application_security/sast/index.md29
-rw-r--r--doc/user/application_security/secret_detection/index.md7
-rw-r--r--doc/user/application_security/security_dashboard/img/pipeline_security_dashboard_v14_2.pngbin83851 -> 46428 bytes
-rw-r--r--doc/user/application_security/security_dashboard/index.md35
-rw-r--r--doc/user/application_security/terminology/index.md12
-rw-r--r--doc/user/application_security/threat_monitoring/img/threat_monitoring_policy_alert_list_v13_12.pngbin22929 -> 0 bytes
-rw-r--r--doc/user/application_security/threat_monitoring/img/threat_monitoring_policy_alert_list_v14_3.pngbin0 -> 17296 bytes
-rw-r--r--doc/user/application_security/threat_monitoring/index.md152
-rw-r--r--doc/user/application_security/vulnerabilities/index.md4
-rw-r--r--doc/user/application_security/vulnerability_report/img/group_vulnerability_report_v14_2.pngbin109933 -> 65346 bytes
-rw-r--r--doc/user/application_security/vulnerability_report/img/project_security_dashboard_status_change_v14_2.pngbin63558 -> 37318 bytes
-rw-r--r--doc/user/application_security/vulnerability_report/index.md22
-rw-r--r--doc/user/clusters/agent/ci_cd_tunnel.md46
-rw-r--r--doc/user/clusters/agent/index.md48
-rw-r--r--doc/user/clusters/agent/repository.md35
-rw-r--r--doc/user/clusters/applications.md12
-rw-r--r--doc/user/clusters/environments.md2
-rw-r--r--doc/user/clusters/img/advanced-settings-cluster-management-project-v12_5.pngbin37271 -> 0 bytes
-rw-r--r--doc/user/clusters/integrations.md3
-rw-r--r--doc/user/clusters/management_project.md26
-rw-r--r--doc/user/clusters/management_project_template.md92
-rw-r--r--doc/user/clusters/migrating_from_gma_to_project_template.md49
-rw-r--r--doc/user/compliance/compliance_report/index.md54
-rw-r--r--doc/user/compliance/license_compliance/index.md46
-rw-r--r--doc/user/discussions/img/btn_new_issue_for_all_threads.pngbin12468 -> 0 bytes
-rw-r--r--doc/user/discussions/img/create-new-issue_v14_3.pngbin0 -> 4358 bytes
-rw-r--r--doc/user/discussions/img/new-issue-one-thread_v14_3.pngbin0 -> 3752 bytes
-rw-r--r--doc/user/discussions/img/new_issue_for_thread.pngbin11820 -> 0 bytes
-rw-r--r--doc/user/discussions/index.md51
-rw-r--r--doc/user/gitlab_com/index.md18
-rw-r--r--doc/user/group/devops_adoption/img/group_devops_adoption_v14_2.pngbin59733 -> 22069 bytes
-rw-r--r--doc/user/group/devops_adoption/index.md1
-rw-r--r--doc/user/group/epics/epic_boards.md4
-rw-r--r--doc/user/group/epics/index.md2
-rw-r--r--doc/user/group/import/index.md2
-rw-r--r--doc/user/group/index.md24
-rw-r--r--doc/user/group/issues_analytics/index.md2
-rw-r--r--doc/user/group/iterations/index.md12
-rw-r--r--doc/user/group/repositories_analytics/index.md6
-rw-r--r--doc/user/group/roadmap/img/epics_state_dropdown_v12_10.pngbin8092 -> 0 bytes
-rw-r--r--doc/user/group/roadmap/img/epics_state_dropdown_v14_3.pngbin0 -> 6994 bytes
-rw-r--r--doc/user/group/roadmap/img/roadmap_view_v13_2.pngbin53200 -> 0 bytes
-rw-r--r--doc/user/group/roadmap/img/roadmap_view_v14_3.pngbin0 -> 67558 bytes
-rw-r--r--doc/user/group/roadmap/index.md38
-rw-r--r--doc/user/group/saml_sso/index.md158
-rw-r--r--doc/user/group/saml_sso/scim_setup.md38
-rw-r--r--doc/user/group/settings/import_export.md6
-rw-r--r--doc/user/group/subgroups/index.md2
-rw-r--r--doc/user/group/value_stream_analytics/index.md9
-rw-r--r--doc/user/index.md6
-rw-r--r--doc/user/infrastructure/clusters/connect/index.md126
-rw-r--r--doc/user/infrastructure/clusters/connect/new_gke_cluster.md2
-rw-r--r--doc/user/infrastructure/clusters/manage/management_project_applications/certmanager.md17
-rw-r--r--doc/user/infrastructure/clusters/manage/management_project_applications/cilium.md6
-rw-r--r--doc/user/infrastructure/clusters/manage/management_project_applications/elasticstack.md5
-rw-r--r--doc/user/infrastructure/clusters/manage/management_project_applications/falco.md6
-rw-r--r--doc/user/infrastructure/clusters/manage/management_project_applications/fluentd.md6
-rw-r--r--doc/user/infrastructure/clusters/manage/management_project_applications/ingress.md5
-rw-r--r--doc/user/infrastructure/clusters/manage/management_project_applications/prometheus.md5
-rw-r--r--doc/user/infrastructure/clusters/manage/management_project_applications/runner.md12
-rw-r--r--doc/user/infrastructure/clusters/manage/management_project_applications/sentry.md6
-rw-r--r--doc/user/infrastructure/clusters/manage/management_project_applications/vault.md6
-rw-r--r--doc/user/infrastructure/iac/img/terraform_list_view_v13_8.png (renamed from doc/user/infrastructure/img/terraform_list_view_v13_8.png)bin74877 -> 74877 bytes
-rw-r--r--doc/user/infrastructure/iac/img/terraform_plan_log_v13_0.png (renamed from doc/user/infrastructure/img/terraform_plan_log_v13_0.png)bin23683 -> 23683 bytes
-rw-r--r--doc/user/infrastructure/iac/img/terraform_plan_widget_v13_2.png (renamed from doc/user/infrastructure/img/terraform_plan_widget_v13_2.png)bin33916 -> 33916 bytes
-rw-r--r--doc/user/infrastructure/iac/index.md4
-rw-r--r--doc/user/infrastructure/iac/mr_integration.md210
-rw-r--r--doc/user/infrastructure/iac/terraform_state.md446
-rw-r--r--doc/user/infrastructure/index.md41
-rw-r--r--doc/user/infrastructure/mr_integration.md211
-rw-r--r--doc/user/infrastructure/terraform_state.md432
-rw-r--r--doc/user/instance/clusters/index.md4
-rw-r--r--doc/user/packages/conan_repository/index.md3
-rw-r--r--doc/user/packages/container_registry/index.md16
-rw-r--r--doc/user/packages/debian_repository/index.md4
-rw-r--r--doc/user/packages/dependency_proxy/index.md12
-rw-r--r--doc/user/packages/generic_packages/index.md6
-rw-r--r--doc/user/packages/helm_repository/index.md42
-rw-r--r--doc/user/packages/terraform_module_registry/index.md8
-rw-r--r--doc/user/permissions.md140
-rw-r--r--doc/user/profile/account/create_accounts.md2
-rw-r--r--doc/user/profile/account/delete_account.md4
-rw-r--r--doc/user/profile/account/two_factor_authentication.md26
-rw-r--r--doc/user/profile/active_sessions.md4
-rw-r--r--doc/user/profile/img/notification_group_settings_v12_8.pngbin36922 -> 0 bytes
-rw-r--r--doc/user/profile/img/notification_project_settings_v12_8.pngbin39303 -> 0 bytes
-rw-r--r--doc/user/profile/index.md16
-rw-r--r--doc/user/profile/notifications.md202
-rw-r--r--doc/user/profile/personal_access_tokens.md25
-rw-r--r--doc/user/project/canary_deployments.md18
-rw-r--r--doc/user/project/clusters/add_eks_clusters.md8
-rw-r--r--doc/user/project/clusters/add_existing_cluster.md13
-rw-r--r--doc/user/project/clusters/add_gke_clusters.md4
-rw-r--r--doc/user/project/clusters/add_remove_clusters.md43
-rw-r--r--doc/user/project/clusters/deploy_to_cluster.md8
-rw-r--r--doc/user/project/clusters/index.md70
-rw-r--r--doc/user/project/clusters/kubernetes_pod_logs.md6
-rw-r--r--doc/user/project/clusters/protect/container_network_security/quick_start_guide.md4
-rw-r--r--doc/user/project/clusters/runbooks/index.md2
-rw-r--r--doc/user/project/clusters/serverless/index.md7
-rw-r--r--doc/user/project/deploy_boards.md26
-rw-r--r--doc/user/project/deploy_keys/index.md2
-rw-r--r--doc/user/project/deploy_tokens/index.md2
-rw-r--r--doc/user/project/description_templates.md2
-rw-r--r--doc/user/project/import/bitbucket.md18
-rw-r--r--doc/user/project/import/github.md88
-rw-r--r--doc/user/project/import/index.md2
-rw-r--r--doc/user/project/import/jira.md2
-rw-r--r--doc/user/project/index.md10
-rw-r--r--doc/user/project/integrations/github.md2
-rw-r--r--doc/user/project/integrations/img/slack_setup.pngbin86314 -> 65156 bytes
-rw-r--r--doc/user/project/integrations/img/zentao_product_id.pngbin0 -> 40486 bytes
-rw-r--r--doc/user/project/integrations/index.md4
-rw-r--r--doc/user/project/integrations/mattermost_slash_commands.md4
-rw-r--r--doc/user/project/integrations/overview.md7
-rw-r--r--doc/user/project/integrations/services_templates.md9
-rw-r--r--doc/user/project/integrations/slack.md104
-rw-r--r--doc/user/project/integrations/slack_slash_commands.md41
-rw-r--r--doc/user/project/integrations/webex_teams.md2
-rw-r--r--doc/user/project/integrations/zentao.md40
-rw-r--r--doc/user/project/issue_board.md77
-rw-r--r--doc/user/project/issues/crosslinking_issues.md12
-rw-r--r--doc/user/project/issues/index.md4
-rw-r--r--doc/user/project/issues/issue_data_and_actions.md2
-rw-r--r--doc/user/project/issues/managing_issues.md8
-rw-r--r--doc/user/project/issues/sorting_issue_lists.md1
-rw-r--r--doc/user/project/members/share_project_with_groups.md2
-rw-r--r--doc/user/project/merge_requests/approvals/index.md4
-rw-r--r--doc/user/project/merge_requests/changes.md26
-rw-r--r--doc/user/project/merge_requests/cherry_pick_changes.md6
-rw-r--r--doc/user/project/merge_requests/code_quality.md11
-rw-r--r--doc/user/project/merge_requests/fail_fast_testing.md2
-rw-r--r--doc/user/project/merge_requests/fast_forward_merge.md8
-rw-r--r--doc/user/project/merge_requests/getting_started.md32
-rw-r--r--doc/user/project/merge_requests/index.md21
-rw-r--r--doc/user/project/merge_requests/load_performance_testing.md2
-rw-r--r--doc/user/project/merge_requests/revert_changes.md6
-rw-r--r--doc/user/project/merge_requests/reviews/index.md45
-rw-r--r--doc/user/project/merge_requests/reviews/suggestions.md2
-rw-r--r--doc/user/project/merge_requests/squash_and_merge.md6
-rw-r--r--doc/user/project/merge_requests/status_checks.md2
-rw-r--r--doc/user/project/merge_requests/test_coverage_visualization.md13
-rw-r--r--doc/user/project/merge_requests/versions.md4
-rw-r--r--doc/user/project/pages/index.md2
-rw-r--r--doc/user/project/pages/pages_access_control.md2
-rw-r--r--doc/user/project/pages/redirects.md264
-rw-r--r--doc/user/project/quick_actions.md1
-rw-r--r--doc/user/project/releases/img/deploy_freeze_v13_10.pngbin15902 -> 0 bytes
-rw-r--r--doc/user/project/releases/img/deploy_freeze_v14_3.pngbin0 -> 13557 bytes
-rw-r--r--doc/user/project/releases/index.md16
-rw-r--r--doc/user/project/repository/branches/default.md12
-rw-r--r--doc/user/project/repository/gpg_signed_commits/index.md11
-rw-r--r--doc/user/project/repository/index.md6
-rw-r--r--doc/user/project/repository/repository_mirroring.md12
-rw-r--r--doc/user/project/repository/x509_signed_commits/index.md356
-rw-r--r--doc/user/project/service_desk.md4
-rw-r--r--doc/user/project/settings/import_export.md14
-rw-r--r--doc/user/project/settings/index.md100
-rw-r--r--doc/user/project/settings/project_access_tokens.md34
-rw-r--r--doc/user/project/time_tracking.md2
-rw-r--r--doc/user/project/web_ide/img/open_web_ide.pngbin28571 -> 0 bytes
-rw-r--r--doc/user/project/web_ide/index.md25
-rw-r--r--doc/user/project/wiki/index.md28
-rw-r--r--doc/user/project/working_with_projects.md46
-rw-r--r--doc/user/search/advanced_search.md21
-rw-r--r--doc/user/search/index.md42
-rw-r--r--doc/user/workspace/img/hardware_settings.pngbin76085 -> 29457 bytes
-rw-r--r--doc/user/workspace/index.md18
-rw-r--r--generator_templates/active_record/migration/migration.rb5
-rw-r--r--generator_templates/post_deployment_migration/post_deployment_migration/migration.rb10
-rw-r--r--generator_templates/usage_metric_definition/metric_definition.yml2
-rw-r--r--jest.config.base.js22
-rw-r--r--jest.config.integration.js4
-rw-r--r--jest.config.js12
-rw-r--r--lib/api/admin/sidekiq.rb4
-rw-r--r--lib/api/api.rb1
-rw-r--r--lib/api/ci/pipelines.rb27
-rw-r--r--lib/api/ci/runners.rb50
-rw-r--r--lib/api/commits.rb2
-rw-r--r--lib/api/dependency_proxy.rb4
-rw-r--r--lib/api/entities/application_setting.rb8
-rw-r--r--lib/api/entities/basic_project_details.rb10
-rw-r--r--lib/api/entities/blob.rb2
-rw-r--r--lib/api/entities/ci/pipeline_basic.rb4
-rw-r--r--lib/api/entities/ci/reset_registration_token_result.rb11
-rw-r--r--lib/api/entities/clusters/agent_authorization.rb13
-rw-r--r--lib/api/entities/commit_note.rb2
-rw-r--r--lib/api/entities/compare.rb4
-rw-r--r--lib/api/entities/error_tracking.rb7
-rw-r--r--lib/api/entities/global_notification_setting.rb2
-rw-r--r--lib/api/entities/project.rb19
-rw-r--r--lib/api/entities/user.rb10
-rw-r--r--lib/api/entities/user_public.rb2
-rw-r--r--lib/api/environments.rb3
-rw-r--r--lib/api/error_tracking.rb28
-rw-r--r--lib/api/error_tracking_client_keys.rb50
-rw-r--r--lib/api/error_tracking_collector.rb50
-rw-r--r--lib/api/feature_flags.rb4
-rw-r--r--lib/api/files.rb15
-rw-r--r--lib/api/generic_packages.rb4
-rw-r--r--lib/api/group_variables.rb2
-rw-r--r--lib/api/groups.rb16
-rw-r--r--lib/api/helm_packages.rb11
-rw-r--r--lib/api/helpers/issues_helpers.rb18
-rw-r--r--lib/api/helpers/members_helpers.rb44
-rw-r--r--lib/api/helpers/packages/npm.rb6
-rw-r--r--lib/api/helpers/pagination_strategies.rb36
-rw-r--r--lib/api/helpers/settings_helpers.rb16
-rw-r--r--lib/api/internal/kubernetes.rb17
-rw-r--r--lib/api/issues.rb11
-rw-r--r--lib/api/lint.rb15
-rw-r--r--lib/api/members.rb32
-rw-r--r--lib/api/merge_requests.rb2
-rw-r--r--lib/api/npm_project_packages.rb3
-rw-r--r--lib/api/projects.rb46
-rw-r--r--lib/api/projects_relation_builder.rb25
-rw-r--r--lib/api/repositories.rb18
-rw-r--r--lib/api/settings.rb11
-rw-r--r--lib/api/templates.rb2
-rw-r--r--lib/api/users.rb48
-rw-r--r--lib/backup/gitaly_backup.rb4
-rw-r--r--lib/backup/manager.rb36
-rw-r--r--lib/backup/pages.rb6
-rw-r--r--lib/banzai/filter/playable_link_filter.rb14
-rw-r--r--lib/banzai/filter/references/label_reference_filter.rb3
-rw-r--r--lib/banzai/filter/references/milestone_reference_filter.rb7
-rw-r--r--lib/banzai/filter/references/reference_cache.rb55
-rw-r--r--lib/banzai/reference_parser/base_parser.rb3
-rw-r--r--lib/bulk_imports/common/pipelines/entity_finisher.rb49
-rw-r--r--lib/bulk_imports/groups/graphql/get_projects_query.rb50
-rw-r--r--lib/bulk_imports/groups/pipelines/entity_finisher.rb49
-rw-r--r--lib/bulk_imports/groups/pipelines/project_entities_pipeline.rb28
-rw-r--r--lib/bulk_imports/groups/stage.rb65
-rw-r--r--lib/bulk_imports/pipeline.rb2
-rw-r--r--lib/bulk_imports/projects/graphql/get_project_query.rb50
-rw-r--r--lib/bulk_imports/projects/pipelines/project_pipeline.rb29
-rw-r--r--lib/bulk_imports/projects/stage.rb24
-rw-r--r--lib/bulk_imports/projects/transformers/project_attributes_transformer.rb24
-rw-r--r--lib/bulk_imports/stage.rb54
-rw-r--r--lib/error_tracking/collector/dsn.rb30
-rw-r--r--lib/gem_extensions/active_record/association.rb4
-rw-r--r--lib/gem_extensions/active_record/disable_joins/associations/association_scope.rb2
-rw-r--r--lib/gitlab/action_cable/request_store_callbacks.rb21
-rw-r--r--lib/gitlab/auth/auth_finders.rb4
-rw-r--r--lib/gitlab/auth/o_auth/user.rb2
-rw-r--r--lib/gitlab/background_migration/backfill_design_internal_ids.rb2
-rw-r--r--lib/gitlab/background_migration/backfill_iteration_cadence_id_for_boards.rb13
-rw-r--r--lib/gitlab/background_migration/backfill_project_repositories.rb2
-rw-r--r--lib/gitlab/background_migration/backfill_projects_with_coverage.rb41
-rw-r--r--lib/gitlab/background_migration/extract_project_topics_into_separate_table.rb63
-rw-r--r--lib/gitlab/background_migration/mailers/unconfirm_mailer.rb2
-rw-r--r--lib/gitlab/background_migration/migrate_merge_request_diff_commit_users.rb11
-rw-r--r--lib/gitlab/background_migration/steal_migrate_merge_request_diff_commit_users.rb33
-rw-r--r--lib/gitlab/bitbucket_server_import/importer.rb2
-rw-r--r--lib/gitlab/branch_push_merge_commit_analyzer.rb2
-rw-r--r--lib/gitlab/cache/import/caching.rb4
-rw-r--r--lib/gitlab/changelog/config.rb22
-rw-r--r--lib/gitlab/changelog/release.rb1
-rw-r--r--lib/gitlab/changelog/template.tpl2
-rw-r--r--lib/gitlab/checks/base_single_checker.rb2
-rw-r--r--lib/gitlab/checks/changes_access.rb38
-rw-r--r--lib/gitlab/ci/artifact_file_reader.rb2
-rw-r--r--lib/gitlab/ci/config/entry/default.rb2
-rw-r--r--lib/gitlab/ci/config/entry/job.rb2
-rw-r--r--lib/gitlab/ci/config/entry/processable.rb3
-rw-r--r--lib/gitlab/ci/config/entry/tags.rb30
-rw-r--r--lib/gitlab/ci/cron_parser.rb36
-rw-r--r--lib/gitlab/ci/lint.rb2
-rw-r--r--lib/gitlab/ci/parsers/security/common.rb14
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schema_validator.rb2
-rw-r--r--lib/gitlab/ci/pipeline/chain/build.rb28
-rw-r--r--lib/gitlab/ci/pipeline/chain/build/associations.rb59
-rw-r--r--lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb25
-rw-r--r--lib/gitlab/ci/pipeline/chain/command.rb7
-rw-r--r--lib/gitlab/ci/pipeline/chain/config/content/external_project.rb20
-rw-r--r--lib/gitlab/ci/pipeline/chain/sequence.rb7
-rw-r--r--lib/gitlab/ci/pipeline/metrics.rb13
-rw-r--r--lib/gitlab/ci/pipeline/seed/build.rb9
-rw-r--r--lib/gitlab/ci/pipeline/seed/processable/resource_group.rb11
-rw-r--r--lib/gitlab/ci/queue/metrics.rb13
-rw-r--r--lib/gitlab/ci/reports/security/finding.rb5
-rw-r--r--lib/gitlab/ci/reports/security/flag.rb34
-rw-r--r--lib/gitlab/ci/status/build/failed.rb3
-rw-r--r--lib/gitlab/ci/templates/Android.latest.gitlab-ci.yml87
-rw-r--r--lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml5
-rw-r--r--lib/gitlab/ci/templates/Jobs/Build.latest.gitlab-ci.yml41
-rw-r--r--lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml5
-rw-r--r--lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml15
-rw-r--r--lib/gitlab/ci/templates/Jobs/Helm-2to3.gitlab-ci.yml6
-rw-r--r--lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml1
-rw-r--r--lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml9
-rw-r--r--lib/gitlab/ci/templates/dotNET.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/trace.rb30
-rw-r--r--lib/gitlab/ci/trace/backoff.rb55
-rw-r--r--lib/gitlab/ci/trace/stream.rb1
-rw-r--r--lib/gitlab/ci/variables/collection.rb15
-rw-r--r--lib/gitlab/ci/variables/collection/sort.rb2
-rw-r--r--lib/gitlab/ci/yaml_processor.rb16
-rw-r--r--lib/gitlab/config/entry/validators.rb12
-rw-r--r--lib/gitlab/config/loader/yaml.rb7
-rw-r--r--lib/gitlab/contributions_calendar.rb1
-rw-r--r--lib/gitlab/cycle_analytics/summary/base.rb4
-rw-r--r--lib/gitlab/cycle_analytics/summary/deploy.rb2
-rw-r--r--lib/gitlab/database.rb66
-rw-r--r--lib/gitlab/database/async_indexes/migration_helpers.rb7
-rw-r--r--lib/gitlab/database/background_migration/batched_job.rb1
-rw-r--r--lib/gitlab/database/background_migration/batched_migration.rb11
-rw-r--r--lib/gitlab/database/connection.rb53
-rw-r--r--lib/gitlab/database/load_balancing.rb97
-rw-r--r--lib/gitlab/database/load_balancing/action_cable_callbacks.rb26
-rw-r--r--lib/gitlab/database/load_balancing/configuration.rb85
-rw-r--r--lib/gitlab/database/load_balancing/connection_proxy.rb29
-rw-r--r--lib/gitlab/database/load_balancing/host.rb14
-rw-r--r--lib/gitlab/database/load_balancing/host_list.rb6
-rw-r--r--lib/gitlab/database/load_balancing/load_balancer.rb38
-rw-r--r--lib/gitlab/database/load_balancing/primary_host.rb81
-rw-r--r--lib/gitlab/database/load_balancing/service_discovery.rb55
-rw-r--r--lib/gitlab/database/load_balancing/sidekiq_client_middleware.rb27
-rw-r--r--lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb44
-rw-r--r--lib/gitlab/database/migration.rb53
-rw-r--r--lib/gitlab/database/migration_helpers.rb111
-rw-r--r--lib/gitlab/database/migration_helpers/cascading_namespace_settings.rb12
-rw-r--r--lib/gitlab/database/migration_helpers/loose_foreign_key_helpers.rb32
-rw-r--r--lib/gitlab/database/migration_helpers/v2.rb112
-rw-r--r--lib/gitlab/database/migrations/lock_retry_mixin.rb43
-rw-r--r--lib/gitlab/database/partitioning.rb19
-rw-r--r--lib/gitlab/database/partitioning/monthly_strategy.rb10
-rw-r--r--lib/gitlab/database/partitioning/multi_database_partition_manager.rb37
-rw-r--r--lib/gitlab/database/partitioning/partition_manager.rb72
-rw-r--r--lib/gitlab/database/partitioning/partition_monitoring.rb2
-rw-r--r--lib/gitlab/database/partitioning/time_partition.rb4
-rw-r--r--lib/gitlab/database/partitioning_migration_helpers/foreign_key_helpers.rb4
-rw-r--r--lib/gitlab/database/partitioning_migration_helpers/index_helpers.rb6
-rw-r--r--lib/gitlab/database/partitioning_migration_helpers/table_management_helpers.rb2
-rw-r--r--lib/gitlab/database/postgres_foreign_key.rb2
-rw-r--r--lib/gitlab/database/postgres_partition.rb2
-rw-r--r--lib/gitlab/database/postgres_partitioned_table.rb2
-rw-r--r--lib/gitlab/database/postgresql_adapter/dump_schema_versions_mixin.rb2
-rw-r--r--lib/gitlab/database/rename_table_helpers.rb8
-rw-r--r--lib/gitlab/database/schema_migrations/context.rb4
-rw-r--r--lib/gitlab/database/shared_model.rb39
-rw-r--r--lib/gitlab/database/transaction/context.rb45
-rw-r--r--lib/gitlab/database/transaction/observer.rb3
-rw-r--r--lib/gitlab/database/with_lock_retries.rb16
-rw-r--r--lib/gitlab/database_importers/work_items/base_type_importer.rb15
-rw-r--r--lib/gitlab/devise_failure.rb8
-rw-r--r--lib/gitlab/diff/highlight_cache.rb2
-rw-r--r--lib/gitlab/email/handler/create_issue_handler.rb2
-rw-r--r--lib/gitlab/email/handler/service_desk_handler.rb2
-rw-r--r--lib/gitlab/email/message/in_product_marketing/team.rb2
-rw-r--r--lib/gitlab/encoding_helper.rb10
-rw-r--r--lib/gitlab/experimentation.rb18
-rw-r--r--lib/gitlab/experimentation/controller_concern.rb14
-rw-r--r--lib/gitlab/experimentation/experiment.rb3
-rw-r--r--lib/gitlab/git.rb1
-rw-r--r--lib/gitlab/git/commit.rb19
-rw-r--r--lib/gitlab/git/repository.rb60
-rw-r--r--lib/gitlab/git/rugged_impl/tree.rb43
-rw-r--r--lib/gitlab/git/user.rb2
-rw-r--r--lib/gitlab/gitaly_client/blob_service.rb5
-rw-r--r--lib/gitlab/gitaly_client/commit_service.rb6
-rw-r--r--lib/gitlab/gitaly_client/ref_service.rb76
-rw-r--r--lib/gitlab/gitaly_client/repository_service.rb36
-rw-r--r--lib/gitlab/github_import.rb9
-rw-r--r--lib/gitlab/github_import/client.rb4
-rw-r--r--lib/gitlab/github_import/importer/diff_note_importer.rb3
-rw-r--r--lib/gitlab/github_import/importer/single_endpoint_diff_notes_importer.rb54
-rw-r--r--lib/gitlab/github_import/importer/single_endpoint_issue_notes_importer.rb54
-rw-r--r--lib/gitlab/github_import/importer/single_endpoint_merge_request_notes_importer.rb54
-rw-r--r--lib/gitlab/github_import/issuable_finder.rb12
-rw-r--r--lib/gitlab/github_import/parallel_scheduling.rb2
-rw-r--r--lib/gitlab/github_import/representation/diff_note.rb3
-rw-r--r--lib/gitlab/github_import/single_endpoint_notes_importing.rb85
-rw-r--r--lib/gitlab/github_import/user_finder.rb12
-rw-r--r--lib/gitlab/gon_helper.rb4
-rw-r--r--lib/gitlab/graphql/authorize/connection_filter_extension.rb15
-rw-r--r--lib/gitlab/graphql/loaders/full_path_model_loader.rb5
-rw-r--r--lib/gitlab/graphql/todos_project_permission_preloader/field_extension.rb26
-rw-r--r--lib/gitlab/i18n.rb20
-rw-r--r--lib/gitlab/import_export/attributes_permitter.rb26
-rw-r--r--lib/gitlab/import_export/base/relation_factory.rb16
-rw-r--r--lib/gitlab/import_export/project/import_export.yml43
-rw-r--r--lib/gitlab/import_export/relation_tree_restorer.rb4
-rw-r--r--lib/gitlab/instrumentation/redis_interceptor.rb5
-rw-r--r--lib/gitlab/integrations/sti_type.rb2
-rw-r--r--lib/gitlab/issuables_count_for_state.rb47
-rw-r--r--lib/gitlab/issues/rebalancing/state.rb154
-rw-r--r--lib/gitlab/kas/client.rb12
-rw-r--r--lib/gitlab/kubernetes/cilium_network_policy.rb30
-rw-r--r--lib/gitlab/marginalia/comment.rb4
-rw-r--r--lib/gitlab/metrics/instrumentation.rb5
-rw-r--r--lib/gitlab/metrics/subscribers/rack_attack.rb4
-rw-r--r--lib/gitlab/middleware/sidekiq_web_static.rb24
-rw-r--r--lib/gitlab/object_hierarchy.rb24
-rw-r--r--lib/gitlab/pagination/cursor_based_keyset.rb27
-rw-r--r--lib/gitlab/pagination/gitaly_keyset_pager.rb34
-rw-r--r--lib/gitlab/pagination/keyset/column_order_definition.rb12
-rw-r--r--lib/gitlab/pagination/keyset/cursor_based_request_context.rb35
-rw-r--r--lib/gitlab/pagination/keyset/cursor_pager.rb38
-rw-r--r--lib/gitlab/pagination/keyset/in_operator_optimization/array_scope_columns.rb59
-rw-r--r--lib/gitlab/pagination/keyset/in_operator_optimization/column_data.rb39
-rw-r--r--lib/gitlab/pagination/keyset/in_operator_optimization/order_by_columns.rb76
-rw-r--r--lib/gitlab/pagination/keyset/in_operator_optimization/query_builder.rb290
-rw-r--r--lib/gitlab/pagination/keyset/iterator.rb21
-rw-r--r--lib/gitlab/pagination/keyset/order.rb23
-rw-r--r--lib/gitlab/pagination/offset_pagination.rb10
-rw-r--r--lib/gitlab/patch/legacy_database_config.rb56
-rw-r--r--lib/gitlab/path_regex.rb4
-rw-r--r--lib/gitlab/quick_actions/issue_actions.rb2
-rw-r--r--lib/gitlab/quick_actions/merge_request_actions.rb14
-rw-r--r--lib/gitlab/rack_attack.rb44
-rw-r--r--lib/gitlab/rack_attack/request.rb48
-rw-r--r--lib/gitlab/reference_extractor.rb25
-rw-r--r--lib/gitlab/regex.rb3
-rw-r--r--lib/gitlab/repository_cache/preloader.rb40
-rw-r--r--lib/gitlab/repository_cache_adapter.rb4
-rw-r--r--lib/gitlab/saas.rb16
-rw-r--r--lib/gitlab/search_results.rb2
-rw-r--r--lib/gitlab/seeder.rb36
-rw-r--r--lib/gitlab/sidekiq_cluster/cli.rb5
-rw-r--r--lib/gitlab/sidekiq_logging/structured_logger.rb1
-rw-r--r--lib/gitlab/sidekiq_middleware.rb10
-rw-r--r--lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb97
-rw-r--r--lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/deduplicates_when_scheduling.rb10
-rw-r--r--lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executed.rb7
-rw-r--r--lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing.rb6
-rw-r--r--lib/gitlab/sidekiq_middleware/size_limiter/validator.rb52
-rw-r--r--lib/gitlab/sidekiq_queue.rb15
-rw-r--r--lib/gitlab/signed_tag.rb24
-rw-r--r--lib/gitlab/slash_commands/issue_close.rb2
-rw-r--r--lib/gitlab/slash_commands/issue_move.rb4
-rw-r--r--lib/gitlab/slash_commands/issue_new.rb2
-rw-r--r--lib/gitlab/subscription_portal.rb32
-rw-r--r--lib/gitlab/template/gitlab_ci_yml_template.rb1
-rw-r--r--lib/gitlab/throttle.rb47
-rw-r--r--lib/gitlab/timeless.rb3
-rw-r--r--lib/gitlab/tracking.rb2
-rw-r--r--lib/gitlab/tracking/standard_context.rb22
-rw-r--r--lib/gitlab/url_builder.rb8
-rw-r--r--lib/gitlab/usage/metrics/instrumentations/service_ping_features_metric.rb15
-rw-r--r--lib/gitlab/usage_data.rb7
-rw-r--r--lib/gitlab/usage_data_counters/ci_template_unique_counter.rb24
-rw-r--r--lib/gitlab/usage_data_counters/hll_redis_counter.rb20
-rw-r--r--lib/gitlab/usage_data_counters/known_events/analytics.yml17
-rw-r--r--lib/gitlab/usage_data_counters/known_events/ci_templates.yml557
-rw-r--r--lib/gitlab/usage_data_counters/known_events/code_review_events.yml12
-rw-r--r--lib/gitlab/usage_data_counters/known_events/common.yml9
-rw-r--r--lib/gitlab/usage_data_counters/known_events/quickactions.yml4
-rw-r--r--lib/gitlab/usage_data_counters/merge_request_activity_unique_counter.rb31
-rw-r--r--lib/gitlab/zentao/client.rb73
-rw-r--r--lib/object_storage/config.rb7
-rw-r--r--lib/sidebars/concerns/has_pill.rb4
-rw-r--r--lib/sidebars/groups/menus/ci_cd_menu.rb5
-rw-r--r--lib/sidebars/groups/menus/group_information_menu.rb5
-rw-r--r--lib/sidebars/groups/menus/issues_menu.rb7
-rw-r--r--lib/sidebars/groups/menus/merge_requests_menu.rb2
-rw-r--r--lib/sidebars/groups/menus/packages_registries_menu.rb5
-rw-r--r--lib/sidebars/groups/menus/settings_menu.rb5
-rw-r--r--lib/sidebars/groups/panel.rb5
-rw-r--r--lib/sidebars/menu.rb3
-rw-r--r--lib/sidebars/projects/menus/analytics_menu.rb2
-rw-r--r--lib/sidebars/projects/menus/ci_cd_menu.rb5
-rw-r--r--lib/sidebars/projects/menus/deployments_menu.rb5
-rw-r--r--lib/sidebars/projects/menus/infrastructure_menu.rb5
-rw-r--r--lib/sidebars/projects/menus/issues_menu.rb5
-rw-r--r--lib/sidebars/projects/menus/learn_gitlab_menu.rb7
-rw-r--r--lib/sidebars/projects/menus/monitor_menu.rb5
-rw-r--r--lib/sidebars/projects/menus/packages_registries_menu.rb5
-rw-r--r--lib/sidebars/projects/menus/project_information_menu.rb5
-rw-r--r--lib/sidebars/projects/menus/repository_menu.rb5
-rw-r--r--lib/sidebars/projects/menus/security_compliance_menu.rb5
-rw-r--r--lib/sidebars/projects/menus/settings_menu.rb19
-rw-r--r--lib/support/logrotate/gitlab1
-rw-r--r--lib/system_check/incoming_email_check.rb8
-rw-r--r--lib/tasks/gitlab/db.rake8
-rw-r--r--lib/tasks/gitlab/docs/compile_deprecations.rake29
-rw-r--r--lib/tasks/gitlab/gitaly.rake5
-rw-r--r--lib/tasks/gitlab/graphql.rake4
-rw-r--r--lib/tasks/gitlab/product_intelligence.rake24
-rw-r--r--lib/tasks/gitlab/sidekiq.rake5
-rw-r--r--lib/tasks/gitlab/usage_data.rake28
-rw-r--r--lib/tasks/karma.rake19
-rw-r--r--lib/tasks/pngquant.rake55
-rw-r--r--lib/tasks/rubocop.rake17
-rw-r--r--locale/am_ET/gitlab.po867
-rw-r--r--locale/ar_SA/gitlab.po883
-rw-r--r--locale/as_IN/gitlab.po855
-rw-r--r--locale/az_AZ/gitlab.po855
-rw-r--r--locale/ba_RU/gitlab.po848
-rw-r--r--locale/bg/gitlab.po855
-rw-r--r--locale/bn_BD/gitlab.po855
-rw-r--r--locale/bn_IN/gitlab.po855
-rw-r--r--locale/br_FR/gitlab.po876
-rw-r--r--locale/bs_BA/gitlab.po862
-rw-r--r--locale/ca_ES/gitlab.po859
-rw-r--r--locale/cs_CZ/gitlab.po885
-rw-r--r--locale/cy_GB/gitlab.po895
-rw-r--r--locale/da_DK/gitlab.po12663
-rw-r--r--locale/de/gitlab.po877
-rw-r--r--locale/el_GR/gitlab.po855
-rw-r--r--locale/eo/gitlab.po857
-rw-r--r--locale/es/gitlab.po3409
-rw-r--r--locale/et_EE/gitlab.po855
-rw-r--r--locale/fa_IR/gitlab.po855
-rw-r--r--locale/fi_FI/gitlab.po855
-rw-r--r--locale/fil_PH/gitlab.po855
-rw-r--r--locale/fr/gitlab.po871
-rw-r--r--locale/gitlab.pot1318
-rw-r--r--locale/gl_ES/gitlab.po855
-rw-r--r--locale/he_IL/gitlab.po1171
-rw-r--r--locale/hi_IN/gitlab.po855
-rw-r--r--locale/hr_HR/gitlab.po862
-rw-r--r--locale/hu_HU/gitlab.po855
-rw-r--r--locale/hy_AM/gitlab.po855
-rw-r--r--locale/id_ID/gitlab.po848
-rw-r--r--locale/ig_NG/gitlab.po848
-rw-r--r--locale/is_IS/gitlab.po855
-rw-r--r--locale/it/gitlab.po881
-rw-r--r--locale/ja/gitlab.po880
-rw-r--r--locale/ka_GE/gitlab.po855
-rw-r--r--locale/kab/gitlab.po855
-rw-r--r--locale/ko/gitlab.po914
-rw-r--r--locale/ku_TR/gitlab.po855
-rw-r--r--locale/ky_KG/gitlab.po855
-rw-r--r--locale/lt_LT/gitlab.po869
-rw-r--r--locale/mk_MK/gitlab.po855
-rw-r--r--locale/mn_MN/gitlab.po855
-rw-r--r--locale/nb_NO/gitlab.po883
-rw-r--r--locale/nl_NL/gitlab.po859
-rw-r--r--locale/pa_IN/gitlab.po855
-rw-r--r--locale/pl_PL/gitlab.po885
-rw-r--r--locale/pt_BR/gitlab.po4033
-rw-r--r--locale/pt_PT/gitlab.po865
-rw-r--r--locale/ro_RO/gitlab.po6754
-rw-r--r--locale/ru/gitlab.po1067
-rw-r--r--locale/si_LK/gitlab.po855
-rw-r--r--locale/sk_SK/gitlab.po869
-rw-r--r--locale/sl_SI/gitlab.po869
-rw-r--r--locale/sq_AL/gitlab.po855
-rw-r--r--locale/sr_CS/gitlab.po862
-rw-r--r--locale/sr_SP/gitlab.po862
-rw-r--r--locale/sv_SE/gitlab.po857
-rw-r--r--locale/sw_KE/gitlab.po855
-rw-r--r--locale/ta_IN/gitlab.po855
-rw-r--r--locale/tr_TR/gitlab.po987
-rw-r--r--locale/uk/gitlab.po1029
-rw-r--r--locale/ur_PK/gitlab.po855
-rw-r--r--locale/uz_UZ/gitlab.po855
-rw-r--r--locale/vi_VN/gitlab.po848
-rw-r--r--locale/zh_CN/gitlab.po4800
-rw-r--r--locale/zh_HK/gitlab.po860
-rw-r--r--locale/zh_TW/gitlab.po850
-rw-r--r--package.json103
-rw-r--r--qa/Dockerfile1
-rw-r--r--qa/Gemfile13
-rw-r--r--qa/Gemfile.lock20
-rw-r--r--qa/README.md2
-rw-r--r--qa/knapsack/master_report.json124
-rw-r--r--qa/qa.rb723
-rw-r--r--qa/qa/ce/strategy.rb4
-rw-r--r--qa/qa/flow/login.rb18
-rw-r--r--qa/qa/flow/saml.rb2
-rw-r--r--qa/qa/git/repository.rb1
-rw-r--r--qa/qa/page/admin/settings/component/ip_limits.rb10
-rw-r--r--qa/qa/page/component/note.rb5
-rw-r--r--qa/qa/page/component/wiki_page_form.rb1
-rw-r--r--qa/qa/page/dashboard/snippet/index.rb6
-rw-r--r--qa/qa/page/group/bulk_import.rb5
-rw-r--r--qa/qa/page/group/menu.rb17
-rw-r--r--qa/qa/page/group/settings/group_deploy_tokens.rb68
-rw-r--r--qa/qa/page/group/settings/repository.rb23
-rw-r--r--qa/qa/page/main/login.rb2
-rw-r--r--qa/qa/page/main/menu.rb11
-rw-r--r--qa/qa/page/merge_request/show.rb19
-rw-r--r--qa/qa/page/project/monitor/metrics/show.rb2
-rw-r--r--qa/qa/page/project/settings/ci_cd.rb4
-rw-r--r--qa/qa/page/project/settings/deploy_tokens.rb4
-rw-r--r--qa/qa/page/view.rb2
-rw-r--r--qa/qa/resource/api_fabricator.rb2
-rw-r--r--qa/qa/resource/ci_variable.rb2
-rw-r--r--qa/qa/resource/deploy_token.rb2
-rw-r--r--qa/qa/resource/group_base.rb16
-rw-r--r--qa/qa/resource/group_deploy_token.rb51
-rw-r--r--qa/qa/resource/group_milestone.rb67
-rw-r--r--qa/qa/resource/issue.rb9
-rw-r--r--qa/qa/resource/kubernetes_cluster/base.rb2
-rw-r--r--qa/qa/resource/label_base.rb6
-rw-r--r--qa/qa/resource/members.rb4
-rw-r--r--qa/qa/resource/merge_request.rb4
-rw-r--r--qa/qa/resource/merge_request_from_fork.rb2
-rw-r--r--qa/qa/resource/package.rb2
-rw-r--r--qa/qa/resource/project.rb2
-rw-r--r--qa/qa/resource/project_imported_from_github.rb4
-rw-r--r--qa/qa/resource/project_imported_from_url.rb2
-rw-r--r--qa/qa/resource/project_issue_note.rb2
-rw-r--r--qa/qa/resource/protected_branch.rb2
-rw-r--r--qa/qa/resource/registry_repository.rb2
-rw-r--r--qa/qa/resource/repository/project_push.rb2
-rw-r--r--qa/qa/resource/repository/push.rb3
-rw-r--r--qa/qa/resource/runner.rb2
-rw-r--r--qa/qa/resource/ssh_key.rb2
-rw-r--r--qa/qa/resource/user.rb19
-rw-r--r--qa/qa/resource/wiki/group_page.rb2
-rw-r--r--qa/qa/runtime/allure_report.rb11
-rw-r--r--qa/qa/runtime/api/client.rb28
-rw-r--r--qa/qa/runtime/api/repository_storage_moves.rb2
-rw-r--r--qa/qa/runtime/application_settings.rb4
-rw-r--r--qa/qa/runtime/browser.rb23
-rw-r--r--qa/qa/runtime/env.rb5
-rw-r--r--qa/qa/runtime/feature.rb6
-rw-r--r--qa/qa/runtime/fixtures.rb2
-rw-r--r--qa/qa/runtime/ip_address.rb4
-rw-r--r--qa/qa/runtime/release.rb4
-rw-r--r--qa/qa/runtime/search.rb10
-rw-r--r--qa/qa/runtime/user.rb2
-rw-r--r--qa/qa/service/docker_run/gitlab_runner.rb1
-rw-r--r--qa/qa/service/kubernetes_cluster.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/bulk_import_group_spec.rb113
-rw-r--r--qa/qa/specs/features/api/1_manage/import_github_repo_spec.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb41
-rw-r--r--qa/qa/specs/features/api/1_manage/project_access_token_spec.rb8
-rw-r--r--qa/qa/specs/features/api/1_manage/rate_limits_spec.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb6
-rw-r--r--qa/qa/specs/features/api/1_manage/users_spec.rb6
-rw-r--r--qa/qa/specs/features/api/2_plan/closes_issue_via_pushing_a_commit_spec.rb4
-rw-r--r--qa/qa/specs/features/api/3_create/gitaly/automatic_failover_and_recovery_spec.rb4
-rw-r--r--qa/qa/specs/features/api/3_create/gitaly/backend_node_recovery_spec.rb2
-rw-r--r--qa/qa/specs/features/api/3_create/gitaly/changing_repository_storage_spec.rb4
-rw-r--r--qa/qa/specs/features/api/3_create/gitaly/distributed_reads_spec.rb4
-rw-r--r--qa/qa/specs/features/api/3_create/gitaly/gitaly_mtls_spec.rb2
-rw-r--r--qa/qa/specs/features/api/3_create/gitaly/praefect_replication_queue_spec.rb2
-rw-r--r--qa/qa/specs/features/api/3_create/merge_request/push_options_labels_spec.rb4
-rw-r--r--qa/qa/specs/features/api/3_create/merge_request/push_options_mwps_spec.rb4
-rw-r--r--qa/qa/specs/features/api/3_create/merge_request/push_options_remove_source_branch_spec.rb2
-rw-r--r--qa/qa/specs/features/api/3_create/merge_request/push_options_target_branch_spec.rb2
-rw-r--r--qa/qa/specs/features/api/3_create/merge_request/push_options_title_description_spec.rb2
-rw-r--r--qa/qa/specs/features/api/3_create/repository/default_branch_name_setting_spec.rb6
-rw-r--r--qa/qa/specs/features/api/3_create/repository/files_spec.rb5
-rw-r--r--qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb5
-rw-r--r--qa/qa/specs/features/api/3_create/repository/push_postreceive_idempotent_spec.rb4
-rw-r--r--qa/qa/specs/features/api/3_create/snippet/snippet_repository_storage_move_spec.rb2
-rw-r--r--qa/qa/specs/features/api/4_verify/cancel_pipeline_when_block_user_spec.rb2
-rw-r--r--qa/qa/specs/features/api/5_package/container_registry_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/group/bulk_import_group_spec.rb14
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/group/create_group_with_mattermost_team_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/group/transfer_group_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/2fa_ssh_recovery_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/login_via_instance_wide_saml_sso_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/maintain_log_in_mixed_env_spec.rb39
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/dashboard_images_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/user/user_access_termination_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/collapse_comments_in_discussions_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/comment_issue_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/custom_issue_template_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/export_as_csv_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/jira_issue_import_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/real_time_assignee_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue_boards/focus_mode_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/milestone/create_group_milestone_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/milestone/create_project_milestone_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/related_issues/related_issues_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/transient/comment_on_discussion_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/design_management/add_design_content_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/design_management/archive_design_content_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/design_management/modify_design_content_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/jenkins/jenkins_build_status_spec.rb3
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/jira/jira_basic_integration_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_a_merge_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb5
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb22
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/revert/reverting_merge_request_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/batch_suggestion_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/custom_commit_suggestion_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_diff_patch_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_merge_ref_diff_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/file/create_file_via_web_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/file/delete_file_via_web_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/file/edit_file_via_web_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/file/file_with_unusual_name_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/user_views_commit_diff_patch_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_with_multiple_files_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_with_multiple_files_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/share_snippet_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/wiki/content_editor_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/wiki/project_based_content_creation_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/wiki/project_based_content_manipulation_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/wiki/project_based_directory_management_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/wiki/project_based_list_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/wiki/project_based_page_deletion_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/ci_variable/pipeline_with_protected_variable_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/include_local_config_file_paths_with_wildcard_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/include_multiple_files_from_a_project_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/locked_artifacts_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/merge_mr_when_pipline_is_blocked_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/mr_event_rule_pipeline_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/pass_dotenv_variables_to_downstream_via_bridge_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_branch_switcher_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/trigger_child_pipeline_with_manual_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/trigger_matrix_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/testing/view_code_coverage_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/composer_registry_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/conan_repository_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/container_registry_omnibus_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/container_registry_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/dependency_proxy_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/generic_repository_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/maven_gradle_repository_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/maven_repository_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/npm_registry_spec.rb171
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/nuget_repository_spec.rb258
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/online_garbage_collection_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/pypi_repository_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/rubygems_registry_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/pages/pages_pipeline_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_dependent_relationship_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/7_configure/kubernetes/kubernetes_integration_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb12
-rw-r--r--qa/qa/specs/features/browser_ui/non_devops/performance_bar_spec.rb2
-rw-r--r--qa/qa/specs/helpers/context_formatter.rb68
-rw-r--r--qa/qa/specs/helpers/quarantine_formatter.rb45
-rw-r--r--qa/qa/specs/helpers/rspec.rb15
-rw-r--r--qa/qa/specs/runner.rb1
-rw-r--r--qa/qa/support/allure_metadata_formatter.rb37
-rw-r--r--qa/qa/support/api.rb4
-rw-r--r--qa/qa/support/formatters/allure_metadata_formatter.rb33
-rw-r--r--qa/qa/support/formatters/context_formatter.rb65
-rw-r--r--qa/qa/support/formatters/formatters.rb11
-rw-r--r--qa/qa/support/formatters/quarantine_formatter.rb42
-rw-r--r--qa/qa/support/formatters/test_stats_formatter.rb156
-rw-r--r--qa/qa/support/helpers/stub_env.rb46
-rw-r--r--qa/qa/support/matchers/eventually_matcher.rb138
-rw-r--r--qa/qa/support/matchers/have_matcher.rb36
-rw-r--r--qa/qa/support/matchers/have_text.rb52
-rw-r--r--qa/qa/tools/delete_projects.rb2
-rw-r--r--qa/qa/tools/delete_subgroups.rb2
-rw-r--r--qa/qa/tools/delete_test_ssh_keys.rb2
-rw-r--r--qa/qa/tools/generate_perf_testdata.rb4
-rw-r--r--qa/qa/vendor/jira/jira_api.rb2
-rw-r--r--qa/qa/vendor/saml_idp/page/base.rb2
-rw-r--r--qa/qa/vendor/saml_idp/page/login.rb2
-rw-r--r--qa/spec/git/repository_spec.rb2
-rw-r--r--qa/spec/page/logging_spec.rb1
-rw-r--r--qa/spec/qa_deprecation_toolkit_env.rb2
-rw-r--r--qa/spec/resource/base_spec.rb2
-rw-r--r--qa/spec/runtime/api/client_spec.rb2
-rw-r--r--qa/spec/runtime/env_spec.rb2
-rw-r--r--qa/spec/runtime/namespace_spec.rb2
-rw-r--r--qa/spec/runtime/release_spec.rb19
-rw-r--r--qa/spec/spec_helper.rb21
-rw-r--r--qa/spec/specs/allure_report_spec.rb7
-rw-r--r--qa/spec/specs/helpers/context_selector_spec.rb4
-rw-r--r--qa/spec/specs/helpers/quarantine_spec.rb4
-rw-r--r--qa/spec/specs/parallel_runner_spec.rb2
-rw-r--r--qa/spec/support/allure_metadata_formatter_spec.rb46
-rw-r--r--qa/spec/support/formatters/allure_metadata_formatter_spec.rb45
-rw-r--r--qa/spec/support/formatters/test_stats_formatter_spec.rb171
-rw-r--r--qa/spec/support/helpers/stub_env.rb42
-rw-r--r--qa/spec/support/matchers/eventually_matcher.rb133
-rw-r--r--qa/spec/support/matchers/have_matcher.rb30
-rw-r--r--qa/spec/support/matchers/have_text.rb48
-rw-r--r--qa/spec/support/repeater_spec.rb2
-rw-r--r--qa/spec/support/retrier_spec.rb3
-rw-r--r--qa/spec/support/waiter_spec.rb2
-rw-r--r--rubocop/cop/gitlab/mark_used_feature_flags.rb29
-rw-r--r--rubocop/cop/migration/add_limit_to_text_columns.rb27
-rw-r--r--rubocop/cop/migration/prevent_index_creation.rb33
-rw-r--r--rubocop/cop/migration/versioned_migration_class.rb56
-rw-r--r--rubocop/cop/performance/active_record_subtransaction_methods.rb29
-rw-r--r--rubocop/cop/performance/active_record_subtransactions.rb30
-rw-r--r--rubocop/cop/sidekiq_load_balancing/worker_data_consistency.rb65
-rw-r--r--rubocop/cop/sidekiq_load_balancing/worker_data_consistency_with_deduplication.rb154
-rw-r--r--rubocop/cop/worker_data_consistency.rb63
-rw-r--r--rubocop/rubocop-migrations.yml1
-rwxr-xr-xscripts/frontend/check_no_partial_karma_jest.sh44
-rwxr-xr-xscripts/frontend/file_test_coverage.js2
-rw-r--r--scripts/frontend/startup_css/constants.js1
-rw-r--r--scripts/prepare_build.sh7
-rwxr-xr-xscripts/review_apps/automated_cleanup.rb40
-rw-r--r--scripts/review_apps/base-config.yaml3
-rwxr-xr-xscripts/review_apps/review-apps.sh7
-rw-r--r--scripts/rspec_helpers.sh62
-rwxr-xr-xscripts/setup-test-env2
-rwxr-xr-xscripts/static-analysis145
-rwxr-xr-xscripts/used-feature-flags1
-rw-r--r--scripts/utils.sh3
-rw-r--r--spec/bin/sidekiq_cluster_spec.rb31
-rw-r--r--spec/config/grape_entity_patch_spec.rb21
-rw-r--r--spec/controllers/admin/integrations_controller_spec.rb8
-rw-r--r--spec/controllers/admin/runners_controller_spec.rb28
-rw-r--r--spec/controllers/admin/users_controller_spec.rb4
-rw-r--r--spec/controllers/boards/issues_controller_spec.rb10
-rw-r--r--spec/controllers/explore/projects_controller_spec.rb63
-rw-r--r--spec/controllers/groups/children_controller_spec.rb4
-rw-r--r--spec/controllers/groups/runners_controller_spec.rb13
-rw-r--r--spec/controllers/groups/settings/integrations_controller_spec.rb15
-rw-r--r--spec/controllers/groups_controller_spec.rb51
-rw-r--r--spec/controllers/import/manifest_controller_spec.rb10
-rw-r--r--spec/controllers/invites_controller_spec.rb26
-rw-r--r--spec/controllers/omniauth_callbacks_controller_spec.rb4
-rw-r--r--spec/controllers/profiles/two_factor_auths_controller_spec.rb52
-rw-r--r--spec/controllers/projects/analytics/cycle_analytics/summary_controller_spec.rb36
-rw-r--r--spec/controllers/projects/environments_controller_spec.rb10
-rw-r--r--spec/controllers/projects/feature_flags_controller_spec.rb270
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb20
-rw-r--r--spec/controllers/projects/jobs_controller_spec.rb33
-rw-r--r--spec/controllers/projects/learn_gitlab_controller_spec.rb13
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb9
-rw-r--r--spec/controllers/projects/pipelines_controller_spec.rb69
-rw-r--r--spec/controllers/projects/services_controller_spec.rb12
-rw-r--r--spec/controllers/registrations/experience_levels_controller_spec.rb159
-rw-r--r--spec/controllers/registrations_controller_spec.rb54
-rw-r--r--spec/controllers/search_controller_spec.rb31
-rw-r--r--spec/controllers/user_callouts_controller_spec.rb11
-rw-r--r--spec/db/development/create_base_work_item_types_spec.rb9
-rw-r--r--spec/db/production/create_base_work_item_types_spec.rb9
-rw-r--r--spec/db/schema_spec.rb3
-rw-r--r--spec/deprecation_toolkit_env.rb7
-rw-r--r--spec/experiments/security_reports_mr_widget_prompt_experiment_spec.rb15
-rw-r--r--spec/factories/ci/build_trace_metadata.rb7
-rw-r--r--spec/factories/ci/builds.rb8
-rw-r--r--spec/factories/ci/pending_builds.rb1
-rw-r--r--spec/factories/ci/reports/security/flags.rb15
-rw-r--r--spec/factories/clusters/agents.rb1
-rw-r--r--spec/factories/clusters/agents/group_authorizations.rb10
-rw-r--r--spec/factories/clusters/agents/project_authorizations.rb10
-rw-r--r--spec/factories/compares.rb22
-rw-r--r--spec/factories/customer_relations/contacts.rb14
-rw-r--r--spec/factories/dependency_proxy.rb2
-rw-r--r--spec/factories/dependency_proxy/image_ttl_group_policies.rb10
-rw-r--r--spec/factories/integration_data.rb10
-rw-r--r--spec/factories/integrations.rb32
-rw-r--r--spec/factories/issues.rb2
-rw-r--r--spec/factories/namespaces/project_namespaces.rb12
-rw-r--r--spec/factories/operations/feature_flag_scopes.rb10
-rw-r--r--spec/factories/operations/feature_flags.rb8
-rw-r--r--spec/factories/packages.rb10
-rw-r--r--spec/factories/packages/helm/file_metadatum.rb10
-rw-r--r--spec/factories/packages/package_file.rb3
-rw-r--r--spec/factories/plan_limits.rb2
-rw-r--r--spec/factories/project_topics.rb8
-rw-r--r--spec/factories/topics.rb7
-rw-r--r--spec/factories/users.rb4
-rw-r--r--spec/factories/users/group_user_callouts.rb10
-rw-r--r--spec/factories/work_item/work_item_types.rb11
-rw-r--r--spec/factories_spec.rb1
-rw-r--r--spec/fast_spec_helper.rb2
-rw-r--r--spec/features/admin/admin_runners_spec.rb4
-rw-r--r--spec/features/admin/admin_sees_background_migrations_spec.rb39
-rw-r--r--spec/features/admin/admin_settings_spec.rb87
-rw-r--r--spec/features/admin/admin_users_impersonation_tokens_spec.rb10
-rw-r--r--spec/features/atom/dashboard_issues_spec.rb16
-rw-r--r--spec/features/atom/issues_spec.rb94
-rw-r--r--spec/features/atom/merge_requests_spec.rb88
-rw-r--r--spec/features/boards/multi_select_spec.rb4
-rw-r--r--spec/features/boards/sidebar_labels_spec.rb3
-rw-r--r--spec/features/boards/user_adds_lists_to_board_spec.rb67
-rw-r--r--spec/features/clusters/cluster_health_dashboard_spec.rb4
-rw-r--r--spec/features/commit_spec.rb2
-rw-r--r--spec/features/cycle_analytics_spec.rb99
-rw-r--r--spec/features/global_search_spec.rb70
-rw-r--r--spec/features/groups/board_sidebar_spec.rb26
-rw-r--r--spec/features/groups/issues_spec.rb39
-rw-r--r--spec/features/groups/members/request_access_spec.rb2
-rw-r--r--spec/features/groups/packages_spec.rb8
-rw-r--r--spec/features/groups/settings/packages_and_registries_spec.rb5
-rw-r--r--spec/features/groups/settings/repository_spec.rb2
-rw-r--r--spec/features/groups/show_spec.rb167
-rw-r--r--spec/features/ics/dashboard_issues_spec.rb16
-rw-r--r--spec/features/ics/group_issues_spec.rb16
-rw-r--r--spec/features/ics/project_issues_spec.rb16
-rw-r--r--spec/features/incidents/user_views_incident_spec.rb2
-rw-r--r--spec/features/invites_spec.rb24
-rw-r--r--spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb10
-rw-r--r--spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb2
-rw-r--r--spec/features/issues/csv_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/filter_issues_spec.rb9
-rw-r--r--spec/features/issues/filtered_search/search_bar_spec.rb4
-rw-r--r--spec/features/issues/filtered_search/visual_tokens_spec.rb3
-rw-r--r--spec/features/issues/issue_detail_spec.rb15
-rw-r--r--spec/features/issues/issue_sidebar_spec.rb2
-rw-r--r--spec/features/issues/resource_label_events_spec.rb2
-rw-r--r--spec/features/issues/rss_spec.rb39
-rw-r--r--spec/features/issues/user_edits_issue_spec.rb1
-rw-r--r--spec/features/issues/user_views_issue_spec.rb2
-rw-r--r--spec/features/issues/user_views_issues_spec.rb6
-rw-r--r--spec/features/labels_hierarchy_spec.rb124
-rw-r--r--spec/features/merge_request/batch_comments_spec.rb4
-rw-r--r--spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb2
-rw-r--r--spec/features/merge_requests/rss_spec.rb46
-rw-r--r--spec/features/merge_requests/user_sees_empty_state_spec.rb21
-rw-r--r--spec/features/profiles/personal_access_tokens_spec.rb14
-rw-r--r--spec/features/profiles/user_edit_profile_spec.rb29
-rw-r--r--spec/features/projects/ci/editor_spec.rb4
-rw-r--r--spec/features/projects/commits/user_browses_commits_spec.rb8
-rw-r--r--spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb16
-rw-r--r--spec/features/projects/import_export/import_file_spec.rb1
-rw-r--r--spec/features/projects/jobs/permissions_spec.rb2
-rw-r--r--spec/features/projects/jobs/user_browses_job_spec.rb2
-rw-r--r--spec/features/projects/members/user_requests_access_spec.rb2
-rw-r--r--spec/features/projects/new_project_spec.rb4
-rw-r--r--spec/features/projects/package_files_spec.rb14
-rw-r--r--spec/features/projects/packages_spec.rb8
-rw-r--r--spec/features/projects/services/user_activates_slack_slash_command_spec.rb4
-rw-r--r--spec/features/projects/settings/access_tokens_spec.rb14
-rw-r--r--spec/features/projects/settings/monitor_settings_spec.rb27
-rw-r--r--spec/features/projects/settings/repository_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/service_desk_setting_spec.rb1
-rw-r--r--spec/features/projects/settings/user_manages_project_members_spec.rb11
-rw-r--r--spec/features/projects/user_creates_project_spec.rb1
-rw-r--r--spec/features/registrations/experience_level_spec.rb44
-rw-r--r--spec/features/users/anonymous_sessions_spec.rb24
-rw-r--r--spec/features/users/login_spec.rb13
-rw-r--r--spec/features/users/show_spec.rb59
-rw-r--r--spec/finders/branches_finder_spec.rb7
-rw-r--r--spec/finders/ci/pipelines_finder_spec.rb37
-rw-r--r--spec/finders/ci/runners_finder_spec.rb126
-rw-r--r--spec/finders/error_tracking/errors_finder_spec.rb18
-rw-r--r--spec/finders/feature_flags_finder_spec.rb8
-rw-r--r--spec/finders/groups/user_groups_finder_spec.rb106
-rw-r--r--spec/finders/issues_finder/params_spec.rb49
-rw-r--r--spec/finders/issues_finder_spec.rb429
-rw-r--r--spec/finders/merge_requests_finder_spec.rb96
-rw-r--r--spec/finders/packages/helm/package_files_finder_spec.rb35
-rw-r--r--spec/finders/packages/helm/packages_finder_spec.rb74
-rw-r--r--spec/finders/packages/npm/package_finder_spec.rb61
-rw-r--r--spec/finders/projects_finder_spec.rb28
-rw-r--r--spec/finders/repositories/tree_finder_spec.rb95
-rw-r--r--spec/fixtures/api/schemas/feature_flag.json7
-rw-r--r--spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric.yml2
-rw-r--r--spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_ee.yml2
-rw-r--r--spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_name_suggestions.yml2
-rw-r--r--spec/frontend/__helpers__/emoji.js5
-rw-r--r--spec/frontend/__helpers__/local_storage_helper.js4
-rw-r--r--spec/frontend/__helpers__/mock_window_location_helper.js4
-rw-r--r--spec/frontend/__helpers__/test_apollo_link.js46
-rw-r--r--spec/frontend/alerts_settings/components/__snapshots__/alerts_form_spec.js.snap4
-rw-r--r--spec/frontend/api/projects_api_spec.js62
-rw-r--r--spec/frontend/authentication/two_factor_auth/components/recovery_codes_spec.js2
-rw-r--r--spec/frontend/autosave_spec.js8
-rw-r--r--spec/frontend/batch_comments/components/review_bar_spec.js42
-rw-r--r--spec/frontend/batch_comments/create_batch_comments_store.js15
-rw-r--r--spec/frontend/blob/notebook/notebook_viever_spec.js3
-rw-r--r--spec/frontend/boards/board_card_inner_spec.js33
-rw-r--r--spec/frontend/boards/board_list_deprecated_spec.js274
-rw-r--r--spec/frontend/boards/board_new_issue_deprecated_spec.js211
-rw-r--r--spec/frontend/boards/boards_store_spec.js1013
-rw-r--r--spec/frontend/boards/components/board_add_new_column_spec.js1
-rw-r--r--spec/frontend/boards/components/board_app_spec.js54
-rw-r--r--spec/frontend/boards/components/board_card_deprecated_spec.js219
-rw-r--r--spec/frontend/boards/components/board_card_layout_deprecated_spec.js158
-rw-r--r--spec/frontend/boards/components/board_column_deprecated_spec.js106
-rw-r--r--spec/frontend/boards/components/board_content_spec.js75
-rw-r--r--spec/frontend/boards/components/board_filtered_search_spec.js22
-rw-r--r--spec/frontend/boards/components/board_list_header_deprecated_spec.js174
-rw-r--r--spec/frontend/boards/components/board_settings_sidebar_spec.js142
-rw-r--r--spec/frontend/boards/components/boards_selector_deprecated_spec.js214
-rw-r--r--spec/frontend/boards/components/issue_time_estimate_deprecated_spec.js64
-rw-r--r--spec/frontend/boards/issue_card_deprecated_spec.js332
-rw-r--r--spec/frontend/boards/issue_spec.js162
-rw-r--r--spec/frontend/boards/list_spec.js230
-rw-r--r--spec/frontend/boards/mock_data.js89
-rw-r--r--spec/frontend/boards/project_select_deprecated_spec.js263
-rw-r--r--spec/frontend/boards/stores/actions_spec.js23
-rw-r--r--spec/frontend/boards/stores/getters_spec.js16
-rw-r--r--spec/frontend/boards/stores/mutations_spec.js6
-rw-r--r--spec/frontend/clusters/components/__snapshots__/remove_cluster_confirmation_spec.js.snap18
-rw-r--r--spec/frontend/confidential_merge_request/components/__snapshots__/project_form_group_spec.js.snap26
-rw-r--r--spec/frontend/confidential_merge_request/components/project_form_group_spec.js42
-rw-r--r--spec/frontend/content_editor/components/__snapshots__/toolbar_link_button_spec.js.snap9
-rw-r--r--spec/frontend/content_editor/components/content_editor_spec.js10
-rw-r--r--spec/frontend/content_editor/components/wrappers/table_cell_base_spec.js193
-rw-r--r--spec/frontend/content_editor/components/wrappers/table_cell_body_spec.js37
-rw-r--r--spec/frontend/content_editor/components/wrappers/table_cell_header_spec.js37
-rw-r--r--spec/frontend/content_editor/extensions/attachment_spec.js112
-rw-r--r--spec/frontend/content_editor/extensions/blockquote_spec.js19
-rw-r--r--spec/frontend/content_editor/extensions/code_block_highlight_spec.js17
-rw-r--r--spec/frontend/content_editor/markdown_processing_examples.js9
-rw-r--r--spec/frontend/content_editor/markdown_processing_spec.js5
-rw-r--r--spec/frontend/content_editor/services/mark_utils_spec.js38
-rw-r--r--spec/frontend/content_editor/services/markdown_serializer_spec.js1008
-rw-r--r--spec/frontend/content_editor/services/markdown_sourcemap_spec.js81
-rw-r--r--spec/frontend/content_editor/test_utils.js4
-rw-r--r--spec/frontend/cycle_analytics/banner_spec.js47
-rw-r--r--spec/frontend/cycle_analytics/base_spec.js28
-rw-r--r--spec/frontend/cycle_analytics/stage_table_spec.js19
-rw-r--r--spec/frontend/cycle_analytics/store/actions_spec.js61
-rw-r--r--spec/frontend/cycle_analytics/store/mutations_spec.js11
-rw-r--r--spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js26
-rw-r--r--spec/frontend/deploy_freeze/helpers.js2
-rw-r--r--spec/frontend/deploy_freeze/store/actions_spec.js45
-rw-r--r--spec/frontend/deploy_freeze/store/mutations_spec.js6
-rw-r--r--spec/frontend/deprecated_jquery_dropdown_spec.js2
-rw-r--r--spec/frontend/design_management/components/design_notes/__snapshots__/design_reply_form_spec.js.snap4
-rw-r--r--spec/frontend/design_management/components/design_scaler_spec.js20
-rw-r--r--spec/frontend/design_management/components/upload/__snapshots__/design_version_dropdown_spec.js.snap8
-rw-r--r--spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap8
-rw-r--r--spec/frontend/design_management/pages/design/index_spec.js27
-rw-r--r--spec/frontend/design_management/pages/index_spec.js17
-rw-r--r--spec/frontend/design_management/utils/design_management_utils_spec.js8
-rw-r--r--spec/frontend/diffs/components/app_spec.js22
-rw-r--r--spec/frontend/diffs/components/diff_file_spec.js38
-rw-r--r--spec/frontend/diffs/create_diffs_store.js6
-rw-r--r--spec/frontend/diffs/store/actions_spec.js7
-rw-r--r--spec/frontend/diffs/store/mutations_spec.js6
-rw-r--r--spec/frontend/diffs/utils/preferences_spec.js32
-rw-r--r--spec/frontend/dropzone_input_spec.js48
-rw-r--r--spec/frontend/emoji/index_spec.js13
-rw-r--r--spec/frontend/emoji/support/unicode_support_map_spec.js6
-rw-r--r--spec/frontend/environments/edit_environment_spec.js52
-rw-r--r--spec/frontend/environments/environment_form_spec.js48
-rw-r--r--spec/frontend/environments/environment_item_spec.js7
-rw-r--r--spec/frontend/environments/environment_table_spec.js11
-rw-r--r--spec/frontend/environments/environments_app_spec.js51
-rw-r--r--spec/frontend/environments/environments_detail_header_spec.js8
-rw-r--r--spec/frontend/environments/environments_folder_view_spec.js1
-rw-r--r--spec/frontend/environments/folder/environments_folder_view_spec.js1
-rw-r--r--spec/frontend/error_tracking_settings/components/app_spec.js80
-rw-r--r--spec/frontend/error_tracking_settings/mock.js4
-rw-r--r--spec/frontend/error_tracking_settings/store/actions_spec.js6
-rw-r--r--spec/frontend/error_tracking_settings/store/mutation_spec.js8
-rw-r--r--spec/frontend/error_tracking_settings/utils_spec.js2
-rw-r--r--spec/frontend/experimentation/utils_spec.js44
-rw-r--r--spec/frontend/filtered_search/services/recent_searches_service_spec.js6
-rw-r--r--spec/frontend/fixtures/api_markdown.yml114
-rw-r--r--spec/frontend/fixtures/freeze_period.rb9
-rw-r--r--spec/frontend/fixtures/runner.rb47
-rw-r--r--spec/frontend/fixtures/startup_css.rb15
-rw-r--r--spec/frontend/fixtures/static/pipeline_graph.html24
-rw-r--r--spec/frontend/fixtures/timezones.rb22
-rw-r--r--spec/frontend/frequent_items/store/actions_spec.js2
-rw-r--r--spec/frontend/groups/components/app_spec.js7
-rw-r--r--spec/frontend/groups/components/groups_spec.js13
-rw-r--r--spec/frontend/groups/components/invite_members_banner_spec.js77
-rw-r--r--spec/frontend/groups/components/item_stats_spec.js30
-rw-r--r--spec/frontend/header_search/components/app_spec.js159
-rw-r--r--spec/frontend/header_search/components/header_search_default_items_spec.js81
-rw-r--r--spec/frontend/header_search/components/header_search_scoped_items_spec.js61
-rw-r--r--spec/frontend/header_search/mock_data.js83
-rw-r--r--spec/frontend/header_search/store/actions_spec.js28
-rw-r--r--spec/frontend/header_search/store/getters_spec.js211
-rw-r--r--spec/frontend/header_search/store/mutations_spec.js20
-rw-r--r--spec/frontend/header_spec.js4
-rw-r--r--spec/frontend/ide/components/repo_editor_spec.js33
-rw-r--r--spec/frontend/ide/services/terminals_spec.js51
-rw-r--r--spec/frontend/ide/utils_spec.js8
-rw-r--r--spec/frontend/import_entities/import_groups/components/import_actions_cell_spec.js90
-rw-r--r--spec/frontend/import_entities/import_groups/components/import_source_cell_spec.js59
-rw-r--r--spec/frontend/import_entities/import_groups/components/import_table_spec.js8
-rw-r--r--spec/frontend/import_entities/import_groups/components/import_target_cell_spec.js29
-rw-r--r--spec/frontend/import_entities/import_groups/graphql/client_factory_spec.js38
-rw-r--r--spec/frontend/import_entities/import_groups/graphql/fixtures.js4
-rw-r--r--spec/frontend/import_entities/import_groups/graphql/services/source_groups_manager_spec.js2
-rw-r--r--spec/frontend/import_entities/import_projects/store/actions_spec.js29
-rw-r--r--spec/frontend/invite_members/components/import_a_project_modal_spec.js167
-rw-r--r--spec/frontend/invite_members/components/invite_members_trigger_spec.js4
-rw-r--r--spec/frontend/invite_members/components/project_select_spec.js105
-rw-r--r--spec/frontend/invite_members/mock_data/api_response_data.js13
-rw-r--r--spec/frontend/issue_show/components/app_spec.js44
-rw-r--r--spec/frontend/issues_list/components/issues_list_app_spec.js137
-rw-r--r--spec/frontend/issues_list/mock_data.js11
-rw-r--r--spec/frontend/jira_import/components/__snapshots__/jira_import_form_spec.js.snap36
-rw-r--r--spec/frontend/jobs/components/job_app_spec.js4
-rw-r--r--spec/frontend/jobs/components/table/cells/actions_cell_spec.js126
-rw-r--r--spec/frontend/jobs/components/table/cells/duration_cell_spec.js (renamed from spec/frontend/jobs/components/table/cells.vue/duration_cell_spec.js)0
-rw-r--r--spec/frontend/jobs/components/table/cells/job_cell_spec.js (renamed from spec/frontend/jobs/components/table/cells.vue/job_cell_spec.js)0
-rw-r--r--spec/frontend/jobs/components/table/cells/pipeline_cell_spec.js (renamed from spec/frontend/jobs/components/table/cells.vue/pipeline_cell_spec.js)0
-rw-r--r--spec/frontend/jobs/mock_data.js182
-rw-r--r--spec/frontend/learn_gitlab/track_learn_gitlab_spec.js21
-rw-r--r--spec/frontend/lib/apollo/instrumentation_link_spec.js54
-rw-r--r--spec/frontend/lib/dompurify_spec.js25
-rw-r--r--spec/frontend/lib/logger/__snapshots__/hello_spec.js.snap16
-rw-r--r--spec/frontend/lib/logger/hello_deferred_spec.js17
-rw-r--r--spec/frontend/lib/logger/hello_spec.js20
-rw-r--r--spec/frontend/lib/logger/index_spec.js23
-rw-r--r--spec/frontend/lib/utils/accessor_spec.js65
-rw-r--r--spec/frontend/lib/utils/datetime/date_format_utility_spec.js120
-rw-r--r--spec/frontend/lib/utils/dom_utils_spec.js15
-rw-r--r--spec/frontend/lib/utils/text_markdown_spec.js19
-rw-r--r--spec/frontend/lib/utils/url_utility_spec.js23
-rw-r--r--spec/frontend/members/components/modals/leave_modal_spec.js8
-rw-r--r--spec/frontend/merge_request_tabs_spec.js82
-rw-r--r--spec/frontend/milestones/stores/mutations_spec.js58
-rw-r--r--spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap4
-rw-r--r--spec/frontend/notebook/cells/markdown_spec.js140
-rw-r--r--spec/frontend/notebook/cells/output/html_sanitize_fixtures.js3
-rw-r--r--spec/frontend/notebook/index_spec.js31
-rw-r--r--spec/frontend/notes/components/comment_form_spec.js13
-rw-r--r--spec/frontend/notes/components/comment_type_dropdown_spec.js64
-rw-r--r--spec/frontend/notes/deprecated_notes_spec.js997
-rw-r--r--spec/frontend/notes/old_notes_spec.js998
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/package_title_spec.js.snap9
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/additional_metadata_spec.js86
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/metadata/composer_spec.js58
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/metadata/conan_spec.js48
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/metadata/maven_spec.js52
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/metadata/nuget_spec.js55
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/metadata/pypi_spec.js48
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/package_title_spec.js20
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/list/__snapshots__/packages_list_app_spec.js.snap68
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/list/packages_list_app_spec.js273
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/list/packages_list_spec.js217
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/list/packages_search_spec.js128
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/list/packages_title_spec.js71
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/list/tokens/package_type_token_spec.js48
-rw-r--r--spec/frontend/packages_and_registries/package_registry/mock_data.js4
-rw-r--r--spec/frontend/pages/dashboard/projects/index/components/customize_homepage_banner_spec.js2
-rw-r--r--spec/frontend/pages/projects/graphs/__snapshots__/code_coverage_spec.js.snap4
-rw-r--r--spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_a_spec.js.snap371
-rw-r--r--spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_b_spec.js.snap604
-rw-r--r--spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_spec.js.snap371
-rw-r--r--spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_a_spec.js38
-rw-r--r--spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_b_spec.js38
-rw-r--r--spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js38
-rw-r--r--spec/frontend/pages/projects/new/components/new_project_url_select_spec.js122
-rw-r--r--spec/frontend/pages/projects/pipeline_schedules/shared/components/interval_pattern_input_spec.js5
-rw-r--r--spec/frontend/pages/sessions/new/signin_tabs_memoizer_spec.js4
-rw-r--r--spec/frontend/pipeline_editor/components/commit/commit_section_spec.js19
-rw-r--r--spec/frontend/pipeline_editor/components/editor/text_editor_spec.js9
-rw-r--r--spec/frontend/pipeline_editor/components/file-nav/branch_switcher_spec.js9
-rw-r--r--spec/frontend/pipeline_editor/components/file-nav/pipeline_editor_file_nav_spec.js18
-rw-r--r--spec/frontend/pipeline_editor/components/header/pipeline_status_spec.js8
-rw-r--r--spec/frontend/pipeline_editor/components/ui/pipeline_editor_empty_state_spec.js13
-rw-r--r--spec/frontend/pipeline_editor/mock_data.js51
-rw-r--r--spec/frontend/pipeline_editor/pipeline_editor_app_spec.js132
-rw-r--r--spec/frontend/pipeline_new/components/pipeline_new_form_spec.js17
-rw-r--r--spec/frontend/pipelines/__snapshots__/utils_spec.js.snap (renamed from spec/frontend/pipelines/__snapshots__/parsing_utils_spec.js.snap)0
-rw-r--r--spec/frontend/pipelines/components/pipelines_filtered_search_spec.js2
-rw-r--r--spec/frontend/pipelines/graph/graph_component_spec.js5
-rw-r--r--spec/frontend/pipelines/graph/job_item_spec.js36
-rw-r--r--spec/frontend/pipelines/graph/linked_pipeline_spec.js44
-rw-r--r--spec/frontend/pipelines/graph/linked_pipelines_column_spec.js4
-rw-r--r--spec/frontend/pipelines/graph/linked_pipelines_mock_data.js3812
-rw-r--r--spec/frontend/pipelines/header_component_spec.js2
-rw-r--r--spec/frontend/pipelines/parsing_utils_spec.js161
-rw-r--r--spec/frontend/pipelines/pipeline_multi_actions_spec.js12
-rw-r--r--spec/frontend/pipelines/pipelines_spec.js2
-rw-r--r--spec/frontend/pipelines/tokens/pipeline_source_token_spec.js3
-rw-r--r--spec/frontend/pipelines/utils_spec.js161
-rw-r--r--spec/frontend/pipelines_spec.js17
-rw-r--r--spec/frontend/popovers/components/popovers_spec.js25
-rw-r--r--spec/frontend/projects/pipelines/charts/components/pipeline_charts_spec.js2
-rw-r--r--spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js23
-rw-r--r--spec/frontend/projects/storage_counter/components/app_spec.js150
-rw-r--r--spec/frontend/projects/storage_counter/components/storage_table_spec.js62
-rw-r--r--spec/frontend/projects/storage_counter/mock_data.js109
-rw-r--r--spec/frontend/projects/storage_counter/utils_spec.js17
-rw-r--r--spec/frontend/projects/terraform_notification/terraform_notification_spec.js70
-rw-r--r--spec/frontend/repository/components/blob_content_viewer_spec.js24
-rw-r--r--spec/frontend/repository/components/blob_viewers/image_viewer_spec.js25
-rw-r--r--spec/frontend/repository/components/tree_content_spec.js7
-rw-r--r--spec/frontend/runner/admin_runners/admin_runners_app_spec.js97
-rw-r--r--spec/frontend/runner/components/runner_filtered_search_bar_spec.js33
-rw-r--r--spec/frontend/runner/components/runner_list_spec.js2
-rw-r--r--spec/frontend/runner/components/runner_update_form_spec.js14
-rw-r--r--spec/frontend/runner/group_runners/group_runners_app_spec.js239
-rw-r--r--spec/frontend/runner/mock_data.js16
-rw-r--r--spec/frontend/search/highlight_blob_search_result_spec.js2
-rw-r--r--spec/frontend/search/store/actions_spec.js8
-rw-r--r--spec/frontend/search/store/utils_spec.js2
-rw-r--r--spec/frontend/shortcuts_spec.js3
-rw-r--r--spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js2
-rw-r--r--spec/frontend/sidebar/components/participants/sidebar_participants_widget_spec.js10
-rw-r--r--spec/frontend/sidebar/sidebar_labels_spec.js2
-rw-r--r--spec/frontend/sidebar/sidebar_mediator_spec.js17
-rw-r--r--spec/frontend/sidebar/sidebar_store_spec.js39
-rw-r--r--spec/frontend/sidebar/track_invite_members_spec.js2
-rw-r--r--spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap1
-rw-r--r--spec/frontend/tracking_spec.js149
-rw-r--r--spec/frontend/vue_mr_widget/components/states/__snapshots__/new_ready_to_merge_spec.js.snap37
-rw-r--r--spec/frontend/vue_mr_widget/components/states/merge_checks_failed_spec.js49
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_unresolved_discussions_spec.js4
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_wip_spec.js2
-rw-r--r--spec/frontend/vue_mr_widget/components/states/new_ready_to_merge_spec.js31
-rw-r--r--spec/frontend/vue_shared/components/__snapshots__/clone_dropdown_spec.js.snap4
-rw-r--r--spec/frontend/vue_shared/components/__snapshots__/code_block_spec.js.snap4
-rw-r--r--spec/frontend/vue_shared/components/__snapshots__/memory_graph_spec.js.snap1
-rw-r--r--spec/frontend/vue_shared/components/__snapshots__/split_button_spec.js.snap4
-rw-r--r--spec/frontend/vue_shared/components/commit_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/diff_stats_dropdown_spec.js176
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_utils_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/milestone_token_spec.js22
-rw-r--r--spec/frontend/vue_shared/components/header_ci_component_spec.js32
-rw-r--r--spec/frontend/vue_shared/components/issuable/issuable_header_warnings_spec.js74
-rw-r--r--spec/frontend/vue_shared/components/markdown/field_spec.js13
-rw-r--r--spec/frontend/vue_shared/components/registry/title_area_spec.js11
-rw-r--r--spec/frontend/vue_shared/components/runner_aws_deployments/runner_aws_deployments_modal_spec.js1
-rw-r--r--spec/frontend/vue_shared/components/settings/__snapshots__/settings_block_spec.js.snap23
-rw-r--r--spec/frontend/vue_shared/components/settings/settings_block_spec.js54
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_value_spec.js18
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/mock_data.js12
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_button_spec.js91
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js15
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js79
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js152
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_title_spec.js61
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_value_spec.js8
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/label_item_spec.js48
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js189
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js8
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/actions_spec.js85
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/getters_spec.js59
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/mutations_spec.js115
-rw-r--r--spec/frontend/vue_shared/components/storage_counter/usage_graph_spec.js137
-rw-r--r--spec/frontend/vue_shared/components/user_popover/user_popover_spec.js17
-rw-r--r--spec/frontend/zen_mode_spec.js6
-rw-r--r--spec/frontend_integration/README.md27
-rw-r--r--spec/frontend_integration/fly_out_nav_browser_spec.js363
-rw-r--r--spec/frontend_integration/lib/utils/browser_spec.js94
-rw-r--r--spec/graphql/mutations/custom_emoji/destroy_spec.rb79
-rw-r--r--spec/graphql/mutations/customer_relations/organizations/create_spec.rb74
-rw-r--r--spec/graphql/mutations/customer_relations/organizations/update_spec.rb74
-rw-r--r--spec/graphql/mutations/dependency_proxy/image_ttl_group_policy/update_spec.rb110
-rw-r--r--spec/graphql/resolvers/board_list_issues_resolver_spec.rb41
-rw-r--r--spec/graphql/resolvers/ci/group_runners_resolver_spec.rb94
-rw-r--r--spec/graphql/resolvers/ci/runners_resolver_spec.rb209
-rw-r--r--spec/graphql/resolvers/concerns/resolves_pipelines_spec.rb26
-rw-r--r--spec/graphql/resolvers/group_resolver_spec.rb7
-rw-r--r--spec/graphql/resolvers/issues_resolver_spec.rb48
-rw-r--r--spec/graphql/resolvers/merge_requests_resolver_spec.rb10
-rw-r--r--spec/graphql/resolvers/project_resolver_spec.rb5
-rw-r--r--spec/graphql/resolvers/users/groups_resolver_spec.rb106
-rw-r--r--spec/graphql/types/ci/job_type_spec.rb1
-rw-r--r--spec/graphql/types/customer_relations/contact_type_spec.rb11
-rw-r--r--spec/graphql/types/customer_relations/organization_type_spec.rb11
-rw-r--r--spec/graphql/types/dependency_proxy/blob_type_spec.rb13
-rw-r--r--spec/graphql/types/dependency_proxy/group_setting_type_spec.rb13
-rw-r--r--spec/graphql/types/dependency_proxy/image_ttl_group_policy_type_spec.rb17
-rw-r--r--spec/graphql/types/dependency_proxy/manifest_type_spec.rb13
-rw-r--r--spec/graphql/types/group_type_spec.rb6
-rw-r--r--spec/graphql/types/issue_type_spec.rb52
-rw-r--r--spec/graphql/types/merge_requests/reviewer_type_spec.rb1
-rw-r--r--spec/graphql/types/project_statistics_type_spec.rb2
-rw-r--r--spec/graphql/types/terraform/state_version_type_spec.rb58
-rw-r--r--spec/graphql/types/user_type_spec.rb1
-rw-r--r--spec/helpers/analytics/cycle_analytics_helper_spec.rb61
-rw-r--r--spec/helpers/application_settings_helper_spec.rb6
-rw-r--r--spec/helpers/blob_helper_spec.rb24
-rw-r--r--spec/helpers/ci/pipeline_editor_helper_spec.rb5
-rw-r--r--spec/helpers/ci/runners_helper_spec.rb13
-rw-r--r--spec/helpers/environment_helper_spec.rb1
-rw-r--r--spec/helpers/groups_helper_spec.rb134
-rw-r--r--spec/helpers/issuables_description_templates_helper_spec.rb21
-rw-r--r--spec/helpers/issuables_helper_spec.rb37
-rw-r--r--spec/helpers/issues_helper_spec.rb92
-rw-r--r--spec/helpers/learn_gitlab_helper_spec.rb56
-rw-r--r--spec/helpers/nav/new_dropdown_helper_spec.rb24
-rw-r--r--spec/helpers/nav/top_nav_helper_spec.rb4
-rw-r--r--spec/helpers/notify_helper_spec.rb49
-rw-r--r--spec/helpers/packages_helper_spec.rb32
-rw-r--r--spec/helpers/profiles_helper_spec.rb33
-rw-r--r--spec/helpers/projects_helper_spec.rb2
-rw-r--r--spec/helpers/recaptcha_helper_spec.rb4
-rw-r--r--spec/helpers/routing/pseudonymization_helper_spec.rb141
-rw-r--r--spec/helpers/user_callouts_helper_spec.rb93
-rw-r--r--spec/initializers/validate_database_config_spec.rb166
-rw-r--r--spec/javascripts/.eslintrc.yml39
-rw-r--r--spec/javascripts/fixtures/.gitignore2
-rw-r--r--spec/javascripts/fly_out_nav_browser_spec.js334
-rw-r--r--spec/javascripts/lib/utils/browser_spec.js69
-rw-r--r--spec/javascripts/lib/utils/mock_data.js1
-rw-r--r--spec/javascripts/test_bundle.js145
-rw-r--r--spec/javascripts/test_constants.js1
-rw-r--r--spec/lib/api/entities/clusters/agent_authorization_spec.rb17
-rw-r--r--spec/lib/backup/gitaly_backup_spec.rb15
-rw-r--r--spec/lib/backup/manager_spec.rb71
-rw-r--r--spec/lib/banzai/filter/audio_link_filter_spec.rb16
-rw-r--r--spec/lib/banzai/filter/video_link_filter_spec.rb16
-rw-r--r--spec/lib/banzai/reference_parser/base_parser_spec.rb12
-rw-r--r--spec/lib/banzai/reference_parser/mentioned_group_parser_spec.rb6
-rw-r--r--spec/lib/banzai/reference_parser/mentioned_project_parser_spec.rb6
-rw-r--r--spec/lib/banzai/reference_parser/mentioned_user_parser_spec.rb6
-rw-r--r--spec/lib/banzai/reference_parser/project_parser_spec.rb8
-rw-r--r--spec/lib/bulk_imports/common/pipelines/entity_finisher_spec.rb57
-rw-r--r--spec/lib/bulk_imports/groups/graphql/get_projects_query_spec.rb43
-rw-r--r--spec/lib/bulk_imports/groups/pipelines/entity_finisher_spec.rb57
-rw-r--r--spec/lib/bulk_imports/groups/pipelines/project_entities_pipeline_spec.rb69
-rw-r--r--spec/lib/bulk_imports/groups/stage_spec.rb39
-rw-r--r--spec/lib/bulk_imports/projects/pipelines/project_pipeline_spec.rb95
-rw-r--r--spec/lib/bulk_imports/projects/stage_spec.rb18
-rw-r--r--spec/lib/bulk_imports/projects/transformers/project_attributes_transformer_spec.rb83
-rw-r--r--spec/lib/bulk_imports/stage_spec.rb36
-rw-r--r--spec/lib/error_tracking/collector/dsn_spec.rb26
-rw-r--r--spec/lib/gitlab/action_cable/request_store_callbacks_spec.rb20
-rw-r--r--spec/lib/gitlab/background_migration/backfill_projects_with_coverage_spec.rb94
-rw-r--r--spec/lib/gitlab/background_migration/extract_project_topics_into_separate_table_spec.rb45
-rw-r--r--spec/lib/gitlab/background_migration/migrate_merge_request_diff_commit_users_spec.rb12
-rw-r--r--spec/lib/gitlab/background_migration/migrate_pages_metadata_spec.rb14
-rw-r--r--spec/lib/gitlab/background_migration/steal_migrate_merge_request_diff_commit_users_spec.rb50
-rw-r--r--spec/lib/gitlab/changelog/config_spec.rb110
-rw-r--r--spec/lib/gitlab/changelog/release_spec.rb24
-rw-r--r--spec/lib/gitlab/chat/command_spec.rb2
-rw-r--r--spec/lib/gitlab/checks/changes_access_spec.rb153
-rw-r--r--spec/lib/gitlab/ci/config/entry/job_spec.rb103
-rw-r--r--spec/lib/gitlab/ci/config/entry/rules_spec.rb8
-rw-r--r--spec/lib/gitlab/ci/config/entry/tags_spec.rb63
-rw-r--r--spec/lib/gitlab/ci/cron_parser_spec.rb61
-rw-r--r--spec/lib/gitlab/ci/parsers/security/common_spec.rb20
-rw-r--r--spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb3
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/build/associations_spec.rb108
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/build_spec.rb101
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb8
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/command_spec.rb36
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb21
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb15
-rw-r--r--spec/lib/gitlab/ci/pipeline/metrics_spec.rb27
-rw-r--r--spec/lib/gitlab/ci/pipeline/seed/build_spec.rb21
-rw-r--r--spec/lib/gitlab/ci/pipeline/seed/pipeline_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/reports/security/flag_spec.rb33
-rw-r--r--spec/lib/gitlab/ci/trace/backoff_spec.rb62
-rw-r--r--spec/lib/gitlab/ci/trace_spec.rb14
-rw-r--r--spec/lib/gitlab/ci/variables/collection/sort_spec.rb44
-rw-r--r--spec/lib/gitlab/ci/variables/collection_spec.rb99
-rw-r--r--spec/lib/gitlab/ci/yaml_processor_spec.rb24
-rw-r--r--spec/lib/gitlab/config/loader/yaml_spec.rb18
-rw-r--r--spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb117
-rw-r--r--spec/lib/gitlab/database/async_indexes/migration_helpers_spec.rb17
-rw-r--r--spec/lib/gitlab/database/background_migration/batched_migration_spec.rb36
-rw-r--r--spec/lib/gitlab/database/connection_spec.rb81
-rw-r--r--spec/lib/gitlab/database/load_balancing/action_cable_callbacks_spec.rb30
-rw-r--r--spec/lib/gitlab/database/load_balancing/configuration_spec.rb175
-rw-r--r--spec/lib/gitlab/database/load_balancing/connection_proxy_spec.rb40
-rw-r--r--spec/lib/gitlab/database/load_balancing/host_list_spec.rb7
-rw-r--r--spec/lib/gitlab/database/load_balancing/host_spec.rb7
-rw-r--r--spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb46
-rw-r--r--spec/lib/gitlab/database/load_balancing/primary_host_spec.rb126
-rw-r--r--spec/lib/gitlab/database/load_balancing/service_discovery_spec.rb108
-rw-r--r--spec/lib/gitlab/database/load_balancing/sidekiq_client_middleware_spec.rb71
-rw-r--r--spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb37
-rw-r--r--spec/lib/gitlab/database/load_balancing_spec.rb233
-rw-r--r--spec/lib/gitlab/database/migration_helpers/loose_foreign_key_helpers_spec.rb58
-rw-r--r--spec/lib/gitlab/database/migration_helpers/v2_spec.rb104
-rw-r--r--spec/lib/gitlab/database/migration_helpers_spec.rb105
-rw-r--r--spec/lib/gitlab/database/migration_spec.rb68
-rw-r--r--spec/lib/gitlab/database/migrations/lock_retry_mixin_spec.rb129
-rw-r--r--spec/lib/gitlab/database/partitioning/monthly_strategy_spec.rb29
-rw-r--r--spec/lib/gitlab/database/partitioning/multi_database_partition_manager_spec.rb36
-rw-r--r--spec/lib/gitlab/database/partitioning/partition_manager_spec.rb80
-rw-r--r--spec/lib/gitlab/database/partitioning_migration_helpers/foreign_key_helpers_spec.rb11
-rw-r--r--spec/lib/gitlab/database/partitioning_migration_helpers/index_helpers_spec.rb21
-rw-r--r--spec/lib/gitlab/database/partitioning_spec.rb36
-rw-r--r--spec/lib/gitlab/database/postgresql_adapter/dump_schema_versions_mixin_spec.rb8
-rw-r--r--spec/lib/gitlab/database/schema_migrations/context_spec.rb8
-rw-r--r--spec/lib/gitlab/database/shared_model_spec.rb55
-rw-r--r--spec/lib/gitlab/database/transaction/context_spec.rb42
-rw-r--r--spec/lib/gitlab/database/transaction/observer_spec.rb3
-rw-r--r--spec/lib/gitlab/database/with_lock_retries_spec.rb54
-rw-r--r--spec/lib/gitlab/database_importers/work_items/base_type_importer_spec.rb9
-rw-r--r--spec/lib/gitlab/database_spec.rb50
-rw-r--r--spec/lib/gitlab/devise_failure_spec.rb35
-rw-r--r--spec/lib/gitlab/diff/highlight_cache_spec.rb9
-rw-r--r--spec/lib/gitlab/email/handler/service_desk_handler_spec.rb9
-rw-r--r--spec/lib/gitlab/encoding_helper_spec.rb30
-rw-r--r--spec/lib/gitlab/experimentation/controller_concern_spec.rb20
-rw-r--r--spec/lib/gitlab/experimentation/experiment_spec.rb1
-rw-r--r--spec/lib/gitlab/experimentation_spec.rb103
-rw-r--r--spec/lib/gitlab/git/commit_spec.rb36
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb288
-rw-r--r--spec/lib/gitlab/git/tag_spec.rb14
-rw-r--r--spec/lib/gitlab/git/tree_spec.rb107
-rw-r--r--spec/lib/gitlab/gitaly_client/blob_service_spec.rb23
-rw-r--r--spec/lib/gitlab/gitaly_client/commit_service_spec.rb35
-rw-r--r--spec/lib/gitlab/gitaly_client/ref_service_spec.rb63
-rw-r--r--spec/lib/gitlab/gitaly_client/repository_service_spec.rb13
-rw-r--r--spec/lib/gitlab/github_import/importer/diff_note_importer_spec.rb7
-rw-r--r--spec/lib/gitlab/github_import/importer/diff_notes_importer_spec.rb1
-rw-r--r--spec/lib/gitlab/github_import/importer/single_endpoint_diff_notes_importer_spec.rb75
-rw-r--r--spec/lib/gitlab/github_import/importer/single_endpoint_issue_notes_importer_spec.rb74
-rw-r--r--spec/lib/gitlab/github_import/importer/single_endpoint_merge_request_notes_importer_spec.rb75
-rw-r--r--spec/lib/gitlab/github_import/issuable_finder_spec.rb66
-rw-r--r--spec/lib/gitlab/github_import/representation/diff_note_spec.rb4
-rw-r--r--spec/lib/gitlab/github_import/sequential_importer_spec.rb2
-rw-r--r--spec/lib/gitlab/github_import/user_finder_spec.rb12
-rw-r--r--spec/lib/gitlab/github_import_spec.rb49
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml13
-rw-r--r--spec/lib/gitlab/import_export/attributes_permitter_spec.rb69
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml2
-rw-r--r--spec/lib/gitlab/instrumentation/redis_interceptor_spec.rb26
-rw-r--r--spec/lib/gitlab/instrumentation/redis_spec.rb7
-rw-r--r--spec/lib/gitlab/issuables_count_for_state_spec.rb102
-rw-r--r--spec/lib/gitlab/issues/rebalancing/state_spec.rb223
-rw-r--r--spec/lib/gitlab/kas/client_spec.rb27
-rw-r--r--spec/lib/gitlab/middleware/sidekiq_web_static_spec.rb40
-rw-r--r--spec/lib/gitlab/pagination/cursor_based_keyset_spec.rb48
-rw-r--r--spec/lib/gitlab/pagination/gitaly_keyset_pager_spec.rb3
-rw-r--r--spec/lib/gitlab/pagination/keyset/column_order_definition_spec.rb21
-rw-r--r--spec/lib/gitlab/pagination/keyset/cursor_based_request_context_spec.rb68
-rw-r--r--spec/lib/gitlab/pagination/keyset/cursor_pager_spec.rb63
-rw-r--r--spec/lib/gitlab/pagination/keyset/in_operator_optimization/array_scope_columns_spec.rb19
-rw-r--r--spec/lib/gitlab/pagination/keyset/in_operator_optimization/column_data_spec.rb23
-rw-r--r--spec/lib/gitlab/pagination/keyset/in_operator_optimization/order_by_columns_spec.rb37
-rw-r--r--spec/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder_spec.rb225
-rw-r--r--spec/lib/gitlab/pagination/keyset/order_spec.rb41
-rw-r--r--spec/lib/gitlab/pagination/offset_pagination_spec.rb37
-rw-r--r--spec/lib/gitlab/patch/legacy_database_config_spec.rb123
-rw-r--r--spec/lib/gitlab/path_regex_spec.rb10
-rw-r--r--spec/lib/gitlab/rack_attack/request_spec.rb16
-rw-r--r--spec/lib/gitlab/rack_attack_spec.rb26
-rw-r--r--spec/lib/gitlab/reference_extractor_spec.rb55
-rw-r--r--spec/lib/gitlab/regex_spec.rb21
-rw-r--r--spec/lib/gitlab/repository_cache/preloader_spec.rb54
-rw-r--r--spec/lib/gitlab/search_results_spec.rb4
-rw-r--r--spec/lib/gitlab/seeder_spec.rb33
-rw-r--r--spec/lib/gitlab/sidekiq_cluster/cli_spec.rb12
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job_spec.rb252
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executed_spec.rb4
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing_spec.rb4
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/size_limiter/validator_spec.rb103
-rw-r--r--spec/lib/gitlab/sidekiq_middleware_spec.rb8
-rw-r--r--spec/lib/gitlab/sidekiq_queue_spec.rb30
-rw-r--r--spec/lib/gitlab/tracking/snowplow_schema_validation_spec.rb33
-rw-r--r--spec/lib/gitlab/tracking/standard_context_spec.rb22
-rw-r--r--spec/lib/gitlab/tracking_spec.rb8
-rw-r--r--spec/lib/gitlab/url_builder_spec.rb21
-rw-r--r--spec/lib/gitlab/usage/metric_definition_spec.rb11
-rw-r--r--spec/lib/gitlab/usage/metric_spec.rb2
-rw-r--r--spec/lib/gitlab/usage/metrics/instrumentations/service_ping_features_metric_spec.rb20
-rw-r--r--spec/lib/gitlab/usage_data_counters/ci_template_unique_counter_spec.rb17
-rw-r--r--spec/lib/gitlab/usage_data_counters/code_review_events_spec.rb2
-rw-r--r--spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb2
-rw-r--r--spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb30
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb9
-rw-r--r--spec/lib/gitlab/x509/tag_spec.rb18
-rw-r--r--spec/lib/gitlab/zentao/client_spec.rb105
-rw-r--r--spec/lib/marginalia_spec.rb36
-rw-r--r--spec/lib/object_storage/config_spec.rb4
-rw-r--r--spec/lib/sidebars/menu_spec.rb23
-rw-r--r--spec/lib/sidebars/projects/menus/learn_gitlab_menu_spec.rb11
-rw-r--r--spec/lib/sidebars/projects/menus/monitor_menu_spec.rb19
-rw-r--r--spec/lib/sidebars/projects/menus/settings_menu_spec.rb26
-rw-r--r--spec/lib/system_check/incoming_email_check_spec.rb54
-rw-r--r--spec/mailers/emails/in_product_marketing_spec.rb2
-rw-r--r--spec/mailers/notify_spec.rb66
-rw-r--r--spec/migrations/20210804150320_create_base_work_item_types_spec.rb10
-rw-r--r--spec/migrations/20210818185845_backfill_projects_with_coverage_spec.rb71
-rw-r--r--spec/migrations/20210819145000_drop_temporary_columns_and_triggers_for_ci_builds_runner_session_spec.rb21
-rw-r--r--spec/migrations/20210831203408_upsert_base_work_item_types_spec.rb54
-rw-r--r--spec/migrations/20210902144144_drop_temporary_columns_and_triggers_for_ci_build_needs_spec.rb21
-rw-r--r--spec/migrations/20210906100316_drop_temporary_columns_and_triggers_for_ci_build_trace_chunks_spec.rb21
-rw-r--r--spec/migrations/active_record/schema_spec.rb2
-rw-r--r--spec/migrations/add_default_project_approval_rules_vuln_allowed_spec.rb35
-rw-r--r--spec/migrations/add_triggers_to_integrations_type_new_spec.rb14
-rw-r--r--spec/migrations/backfill_cadence_id_for_boards_scoped_to_iteration_spec.rb109
-rw-r--r--spec/migrations/backfill_stage_event_hash_spec.rb103
-rw-r--r--spec/migrations/cleanup_remaining_orphan_invites_spec.rb37
-rw-r--r--spec/migrations/disable_job_token_scope_when_unused_spec.rb44
-rw-r--r--spec/migrations/remove_duplicate_dast_site_tokens_spec.rb53
-rw-r--r--spec/migrations/remove_duplicate_dast_site_tokens_with_same_token_spec.rb53
-rw-r--r--spec/migrations/replace_external_wiki_triggers_spec.rb132
-rw-r--r--spec/migrations/set_default_job_token_scope_true_spec.rb33
-rw-r--r--spec/migrations/slice_merge_request_diff_commit_migrations_spec.rb69
-rw-r--r--spec/migrations/steal_merge_request_diff_commit_users_migration_spec.rb29
-rw-r--r--spec/migrations/update_integrations_trigger_type_new_on_insert_spec.rb102
-rw-r--r--spec/migrations/update_minimum_password_length_spec.rb2
-rw-r--r--spec/models/analytics/cycle_analytics/issue_stage_event_spec.rb11
-rw-r--r--spec/models/analytics/cycle_analytics/merge_request_stage_event_spec.rb11
-rw-r--r--spec/models/application_record_spec.rb81
-rw-r--r--spec/models/application_setting_spec.rb31
-rw-r--r--spec/models/bulk_imports/entity_spec.rb53
-rw-r--r--spec/models/bulk_imports/tracker_spec.rb4
-rw-r--r--spec/models/ci/bridge_spec.rb8
-rw-r--r--spec/models/ci/build_spec.rb57
-rw-r--r--spec/models/ci/build_trace_chunks/fog_spec.rb42
-rw-r--r--spec/models/ci/build_trace_metadata_spec.rb124
-rw-r--r--spec/models/ci/pending_build_spec.rb111
-rw-r--r--spec/models/ci/pipeline_schedule_spec.rb44
-rw-r--r--spec/models/ci/pipeline_spec.rb77
-rw-r--r--spec/models/ci/pipeline_variable_spec.rb2
-rw-r--r--spec/models/ci/runner_spec.rb4
-rw-r--r--spec/models/clusters/agent_spec.rb4
-rw-r--r--spec/models/clusters/agents/group_authorization_spec.rb10
-rw-r--r--spec/models/clusters/agents/implicit_authorization_spec.rb14
-rw-r--r--spec/models/clusters/agents/project_authorization_spec.rb10
-rw-r--r--spec/models/clusters/cluster_spec.rb14
-rw-r--r--spec/models/commit_status_spec.rb9
-rw-r--r--spec/models/concerns/approvable_base_spec.rb28
-rw-r--r--spec/models/concerns/calloutable_spec.rb26
-rw-r--r--spec/models/concerns/featurable_spec.rb5
-rw-r--r--spec/models/concerns/issuable_spec.rb17
-rw-r--r--spec/models/concerns/loose_foreign_key_spec.rb83
-rw-r--r--spec/models/concerns/partitioned_table_spec.rb6
-rw-r--r--spec/models/concerns/sanitizable_spec.rb101
-rw-r--r--spec/models/concerns/taggable_queries_spec.rb9
-rw-r--r--spec/models/customer_relations/contact_spec.rb37
-rw-r--r--spec/models/customer_relations/organization_spec.rb2
-rw-r--r--spec/models/dependency_proxy/blob_spec.rb3
-rw-r--r--spec/models/dependency_proxy/image_ttl_group_policy_spec.rb23
-rw-r--r--spec/models/dependency_proxy/manifest_spec.rb3
-rw-r--r--spec/models/design_management/action_spec.rb60
-rw-r--r--spec/models/diff_note_spec.rb27
-rw-r--r--spec/models/environment_spec.rb245
-rw-r--r--spec/models/error_tracking/error_spec.rb56
-rw-r--r--spec/models/error_tracking/project_error_tracking_setting_spec.rb11
-rw-r--r--spec/models/group_spec.rb92
-rw-r--r--spec/models/hooks/web_hook_spec.rb30
-rw-r--r--spec/models/instance_configuration_spec.rb44
-rw-r--r--spec/models/integration_spec.rb16
-rw-r--r--spec/models/integrations/datadog_spec.rb6
-rw-r--r--spec/models/integrations/pipelines_email_spec.rb2
-rw-r--r--spec/models/integrations/prometheus_spec.rb2
-rw-r--r--spec/models/integrations/zentao_spec.rb53
-rw-r--r--spec/models/integrations/zentao_tracker_data_spec.rb21
-rw-r--r--spec/models/internal_id_spec.rb309
-rw-r--r--spec/models/issue/metrics_spec.rb17
-rw-r--r--spec/models/issue_spec.rb57
-rw-r--r--spec/models/loose_foreign_keys/deleted_record_spec.rb56
-rw-r--r--spec/models/member_spec.rb10
-rw-r--r--spec/models/merge_request_spec.rb37
-rw-r--r--spec/models/milestone_spec.rb9
-rw-r--r--spec/models/namespace_setting_spec.rb10
-rw-r--r--spec/models/namespace_spec.rb117
-rw-r--r--spec/models/namespaces/project_namespace_spec.rb27
-rw-r--r--spec/models/note_spec.rb60
-rw-r--r--spec/models/operations/feature_flag_scope_spec.rb391
-rw-r--r--spec/models/operations/feature_flag_spec.rb118
-rw-r--r--spec/models/packages/package_file_spec.rb67
-rw-r--r--spec/models/packages/package_spec.rb43
-rw-r--r--spec/models/preloaders/commit_status_preloader_spec.rb41
-rw-r--r--spec/models/preloaders/merge_requests_preloader_spec.rb42
-rw-r--r--spec/models/preloaders/user_max_access_level_in_groups_preloader_spec.rb51
-rw-r--r--spec/models/project_ci_cd_setting_spec.rb6
-rw-r--r--spec/models/project_feature_spec.rb17
-rw-r--r--spec/models/project_spec.rb259
-rw-r--r--spec/models/projects/project_topic_spec.rb16
-rw-r--r--spec/models/projects/topic_spec.rb22
-rw-r--r--spec/models/protected_branch_spec.rb24
-rw-r--r--spec/models/repository_spec.rb213
-rw-r--r--spec/models/shard_spec.rb20
-rw-r--r--spec/models/user_callout_spec.rb19
-rw-r--r--spec/models/user_detail_spec.rb25
-rw-r--r--spec/models/user_spec.rb537
-rw-r--r--spec/models/users/group_callout_spec.rb27
-rw-r--r--spec/models/work_item/type_spec.rb6
-rw-r--r--spec/policies/custom_emoji_policy_spec.rb73
-rw-r--r--spec/policies/group_policy_spec.rb59
-rw-r--r--spec/policies/issue_policy_spec.rb149
-rw-r--r--spec/policies/user_policy_spec.rb46
-rw-r--r--spec/presenters/packages/helm/index_presenter_spec.rb80
-rw-r--r--spec/presenters/packages/npm/package_presenter_spec.rb65
-rw-r--r--spec/presenters/project_presenter_spec.rb38
-rw-r--r--spec/presenters/snippet_blob_presenter_spec.rb3
-rw-r--r--spec/rake_helper.rb2
-rw-r--r--spec/requests/admin/background_migrations_controller_spec.rb45
-rw-r--r--spec/requests/api/admin/sidekiq_spec.rb2
-rw-r--r--spec/requests/api/ci/pipelines_spec.rb81
-rw-r--r--spec/requests/api/ci/runners_reset_registration_token_spec.rb149
-rw-r--r--spec/requests/api/commit_statuses_spec.rb36
-rw-r--r--spec/requests/api/commits_spec.rb20
-rw-r--r--spec/requests/api/dependency_proxy_spec.rb74
-rw-r--r--spec/requests/api/error_tracking_client_keys_spec.rb86
-rw-r--r--spec/requests/api/error_tracking_collector_spec.rb97
-rw-r--r--spec/requests/api/feature_flags_spec.rb121
-rw-r--r--spec/requests/api/files_spec.rb13
-rw-r--r--spec/requests/api/generic_packages_spec.rb10
-rw-r--r--spec/requests/api/go_proxy_spec.rb2
-rw-r--r--spec/requests/api/graphql/boards/board_list_issues_query_spec.rb14
-rw-r--r--spec/requests/api/graphql/ci/stages_spec.rb46
-rw-r--r--spec/requests/api/graphql/current_user/groups_query_spec.rb112
-rw-r--r--spec/requests/api/graphql/group/dependency_proxy_blobs_spec.rb127
-rw-r--r--spec/requests/api/graphql/group/dependency_proxy_group_setting_spec.rb78
-rw-r--r--spec/requests/api/graphql/group/dependency_proxy_image_ttl_policy_spec.rb77
-rw-r--r--spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb119
-rw-r--r--spec/requests/api/graphql/mutations/admin/sidekiq_queues/delete_jobs_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/custom_emoji/destroy_spec.rb73
-rw-r--r--spec/requests/api/graphql/mutations/dependency_proxy/image_ttl_group_policy/update_spec.rb70
-rw-r--r--spec/requests/api/graphql/mutations/issues/create_spec.rb5
-rw-r--r--spec/requests/api/graphql/mutations/issues/update_spec.rb13
-rw-r--r--spec/requests/api/graphql/project/error_tracking/sentry_errors_request_spec.rb53
-rw-r--r--spec/requests/api/graphql/project/issues_spec.rb28
-rw-r--r--spec/requests/api/graphql/project/pipeline_spec.rb12
-rw-r--r--spec/requests/api/groups_spec.rb121
-rw-r--r--spec/requests/api/helm_packages_spec.rb24
-rw-r--r--spec/requests/api/internal/kubernetes_spec.rb42
-rw-r--r--spec/requests/api/issues/get_group_issues_spec.rb25
-rw-r--r--spec/requests/api/issues/issues_spec.rb128
-rw-r--r--spec/requests/api/lint_spec.rb1
-rw-r--r--spec/requests/api/maven_packages_spec.rb2
-rw-r--r--spec/requests/api/members_spec.rb84
-rw-r--r--spec/requests/api/merge_requests_spec.rb2
-rw-r--r--spec/requests/api/notification_settings_spec.rb2
-rw-r--r--spec/requests/api/npm_project_packages_spec.rb34
-rw-r--r--spec/requests/api/pages/pages_spec.rb7
-rw-r--r--spec/requests/api/project_attributes.yml3
-rw-r--r--spec/requests/api/projects_spec.rb17
-rw-r--r--spec/requests/api/pypi_packages_spec.rb2
-rw-r--r--spec/requests/api/releases_spec.rb2
-rw-r--r--spec/requests/api/repositories_spec.rb27
-rw-r--r--spec/requests/api/rubygem_packages_spec.rb2
-rw-r--r--spec/requests/api/settings_spec.rb57
-rw-r--r--spec/requests/api/terraform/modules/v1/packages_spec.rb2
-rw-r--r--spec/requests/api/unleash_spec.rb19
-rw-r--r--spec/requests/api/users_spec.rb461
-rw-r--r--spec/requests/git_http_spec.rb8
-rw-r--r--spec/requests/jira_connect/installations_controller_spec.rb95
-rw-r--r--spec/requests/members/mailgun/permanent_failure_spec.rb128
-rw-r--r--spec/requests/oauth_tokens_spec.rb24
-rw-r--r--spec/requests/openid_connect_spec.rb28
-rw-r--r--spec/requests/projects/merge_requests_discussions_spec.rb11
-rw-r--r--spec/requests/projects/usage_quotas_spec.rb63
-rw-r--r--spec/requests/rack_attack_global_spec.rb540
-rw-r--r--spec/requests/users/group_callouts_spec.rb58
-rw-r--r--spec/rubocop/cop/gitlab/mark_used_feature_flags_spec.rb1
-rw-r--r--spec/rubocop/cop/migration/add_limit_to_text_columns_spec.rb36
-rw-r--r--spec/rubocop/cop/migration/prevent_index_creation_spec.rb86
-rw-r--r--spec/rubocop/cop/migration/versioned_migration_class_spec.rb81
-rw-r--r--spec/rubocop/cop/performance/active_record_subtransaction_methods_spec.rb29
-rw-r--r--spec/rubocop/cop/performance/active_record_subtransactions_spec.rb62
-rw-r--r--spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_spec.rb50
-rw-r--r--spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_with_deduplication_spec.rb166
-rw-r--r--spec/rubocop/cop/worker_data_consistency_spec.rb50
-rw-r--r--spec/serializers/group_child_entity_spec.rb36
-rw-r--r--spec/serializers/issuable_sidebar_extras_entity_spec.rb8
-rw-r--r--spec/serializers/pipeline_serializer_spec.rb2
-rw-r--r--spec/services/application_settings/update_service_spec.rb71
-rw-r--r--spec/services/auth/container_registry_authentication_service_spec.rb31
-rw-r--r--spec/services/boards/issues/list_service_spec.rb47
-rw-r--r--spec/services/ci/after_requeue_job_service_spec.rb10
-rw-r--r--spec/services/ci/archive_trace_service_spec.rb62
-rw-r--r--spec/services/ci/create_pipeline_service/parent_child_pipeline_spec.rb26
-rw-r--r--spec/services/ci/create_pipeline_service/tags_spec.rb38
-rw-r--r--spec/services/ci/create_pipeline_service_spec.rb99
-rw-r--r--spec/services/ci/external_pull_requests/create_pipeline_service_spec.rb67
-rw-r--r--spec/services/ci/job_artifacts/destroy_all_expired_service_spec.rb134
-rw-r--r--spec/services/ci/pipeline_processing/shared_processing_service.rb33
-rw-r--r--spec/services/ci/pipeline_trigger_service_spec.rb22
-rw-r--r--spec/services/ci/pipelines/add_job_service_spec.rb12
-rw-r--r--spec/services/ci/register_job_service_spec.rb84
-rw-r--r--spec/services/ci/stuck_builds/drop_service_spec.rb284
-rw-r--r--spec/services/ci/update_pending_build_service_spec.rb82
-rw-r--r--spec/services/clusters/agents/refresh_authorization_service_spec.rb132
-rw-r--r--spec/services/customer_relations/organizations/create_service_spec.rb33
-rw-r--r--spec/services/customer_relations/organizations/update_service_spec.rb56
-rw-r--r--spec/services/dependency_proxy/image_ttl_group_policies/update_service_spec.rb119
-rw-r--r--spec/services/design_management/delete_designs_service_spec.rb12
-rw-r--r--spec/services/draft_notes/publish_service_spec.rb27
-rw-r--r--spec/services/environments/auto_stop_service_spec.rb11
-rw-r--r--spec/services/environments/stop_service_spec.rb54
-rw-r--r--spec/services/error_tracking/collect_error_service_spec.rb26
-rw-r--r--spec/services/feature_flags/create_service_spec.rb16
-rw-r--r--spec/services/git/base_hooks_service_spec.rb6
-rw-r--r--spec/services/git/branch_hooks_service_spec.rb38
-rw-r--r--spec/services/groups/group_links/create_service_spec.rb18
-rw-r--r--spec/services/groups/open_issues_count_service_spec.rb64
-rw-r--r--spec/services/groups/update_shared_runners_service_spec.rb38
-rw-r--r--spec/services/issue_rebalancing_service_spec.rb173
-rw-r--r--spec/services/issues/build_service_spec.rb52
-rw-r--r--spec/services/issues/close_service_spec.rb9
-rw-r--r--spec/services/issues/create_service_spec.rb15
-rw-r--r--spec/services/issues/relative_position_rebalancing_service_spec.rb166
-rw-r--r--spec/services/issues/reopen_service_spec.rb7
-rw-r--r--spec/services/issues/update_service_spec.rb37
-rw-r--r--spec/services/members/groups/bulk_creator_service_spec.rb10
-rw-r--r--spec/services/members/mailgun/process_webhook_service_spec.rb42
-rw-r--r--spec/services/members/projects/bulk_creator_service_spec.rb10
-rw-r--r--spec/services/merge_requests/merge_service_spec.rb15
-rw-r--r--spec/services/merge_requests/merge_to_ref_service_spec.rb32
-rw-r--r--spec/services/merge_requests/mergeability_check_service_spec.rb9
-rw-r--r--spec/services/merge_requests/squash_service_spec.rb17
-rw-r--r--spec/services/notification_service_spec.rb2
-rw-r--r--spec/services/packages/composer/version_parser_service_spec.rb1
-rw-r--r--spec/services/packages/generic/create_package_file_service_spec.rb31
-rw-r--r--spec/services/packages/maven/find_or_create_package_service_spec.rb13
-rw-r--r--spec/services/packages/nuget/update_package_from_metadata_service_spec.rb341
-rw-r--r--spec/services/pages/delete_service_spec.rb21
-rw-r--r--spec/services/pages/legacy_storage_lease_spec.rb65
-rw-r--r--spec/services/pages/migrate_legacy_storage_to_deployment_service_spec.rb8
-rw-r--r--spec/services/projects/batch_open_issues_count_service_spec.rb45
-rw-r--r--spec/services/projects/create_service_spec.rb24
-rw-r--r--spec/services/projects/fork_service_spec.rb4
-rw-r--r--spec/services/projects/group_links/destroy_service_spec.rb60
-rw-r--r--spec/services/projects/open_issues_count_service_spec.rb109
-rw-r--r--spec/services/projects/operations/update_service_spec.rb4
-rw-r--r--spec/services/projects/transfer_service_spec.rb33
-rw-r--r--spec/services/projects/update_pages_service_spec.rb158
-rw-r--r--spec/services/projects/update_service_spec.rb24
-rw-r--r--spec/services/quick_actions/interpret_service_spec.rb72
-rw-r--r--spec/services/repositories/changelog_service_spec.rb2
-rw-r--r--spec/services/service_ping/submit_service_ping_service_spec.rb28
-rw-r--r--spec/services/suggestions/apply_service_spec.rb16
-rw-r--r--spec/services/suggestions/create_service_spec.rb2
-rw-r--r--spec/services/system_note_service_spec.rb12
-rw-r--r--spec/services/system_notes/issuables_service_spec.rb12
-rw-r--r--spec/services/todos/destroy/design_service_spec.rb40
-rw-r--r--spec/services/users/ban_service_spec.rb2
-rw-r--r--spec/services/users/dismiss_group_callout_service_spec.rb25
-rw-r--r--spec/services/users/dismiss_user_callout_service_spec.rb25
-rw-r--r--spec/services/users/migrate_to_ghost_user_service_spec.rb18
-rw-r--r--spec/services/users/reject_service_spec.rb4
-rw-r--r--spec/services/users/unban_service_spec.rb2
-rw-r--r--spec/services/wiki_pages/event_create_service_spec.rb4
-rw-r--r--spec/spec_helper.rb16
-rw-r--r--spec/support/database/ci_tables.rb22
-rw-r--r--spec/support/database/cross-join-allowlist.yml196
-rw-r--r--spec/support/database/gitlab_schema.rb25
-rw-r--r--spec/support/database/multiple_databases.rb9
-rw-r--r--spec/support/database/prevent_cross_database_modification.rb10
-rw-r--r--spec/support/database/prevent_cross_joins.rb57
-rw-r--r--spec/support/database_cleaner.rb4
-rw-r--r--spec/support/database_load_balancing.rb5
-rw-r--r--spec/support/db_cleaner.rb2
-rw-r--r--spec/support/helpers/bare_repo_operations.rb20
-rw-r--r--spec/support/helpers/cycle_analytics_helpers.rb31
-rw-r--r--spec/support/helpers/email_helpers.rb4
-rw-r--r--spec/support/helpers/features/members_helpers.rb (renamed from spec/support/helpers/features/members_table_helpers.rb)0
-rw-r--r--spec/support/helpers/javascript_fixtures_helpers.rb9
-rw-r--r--spec/support/helpers/live_debugger.rb2
-rw-r--r--spec/support/helpers/migrations_helpers.rb2
-rw-r--r--spec/support/helpers/reference_parser_helpers.rb5
-rw-r--r--spec/support/helpers/session_helpers.rb26
-rw-r--r--spec/support/helpers/stub_gitlab_calls.rb4
-rw-r--r--spec/support/helpers/stub_gitlab_data.rb7
-rw-r--r--spec/support/helpers/test_env.rb4
-rw-r--r--spec/support/services/migrate_to_ghost_user_service_shared_examples.rb31
-rw-r--r--spec/support/shared_contexts/email_shared_context.rb9
-rw-r--r--spec/support/shared_contexts/finders/packages/npm/package_finder_shared_context.rb14
-rw-r--r--spec/support/shared_contexts/graphql/resolvers/runners_resolver_shared_context.rb22
-rw-r--r--spec/support/shared_contexts/issuable/merge_request_shared_context.rb2
-rw-r--r--spec/support/shared_contexts/navbar_structure_context.rb3
-rw-r--r--spec/support/shared_contexts/pages_zip_with_spoofed_size_shared_context.rb41
-rw-r--r--spec/support/shared_contexts/requests/api/npm_packages_shared_context.rb10
-rw-r--r--spec/support/shared_contexts/services/service_ping/stubbed_service_ping_metrics_definitions_shared_context.rb17
-rw-r--r--spec/support/shared_examples/boards/multiple_issue_boards_shared_examples.rb14
-rw-r--r--spec/support/shared_examples/controllers/concerns/integrations_actions_shared_examples.rb59
-rw-r--r--spec/support/shared_examples/controllers/githubish_import_controller_shared_examples.rb10
-rw-r--r--spec/support/shared_examples/controllers/import_controller_status_shared_examples.rb10
-rw-r--r--spec/support/shared_examples/controllers/issuable_anonymous_search_disabled_examples.rb55
-rw-r--r--spec/support/shared_examples/features/atom/issuable_shared_examples.rb12
-rw-r--r--spec/support/shared_examples/features/content_editor_shared_examples.rb14
-rw-r--r--spec/support/shared_examples/features/deploy_token_shared_examples.rb23
-rw-r--r--spec/support/shared_examples/features/discussion_comments_shared_example.rb6
-rw-r--r--spec/support/shared_examples/features/issuable_invite_members_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/features/manage_applications_shared_examples.rb4
-rw-r--r--spec/support/shared_examples/features/rss_shared_examples.rb20
-rw-r--r--spec/support/shared_examples/features/wiki/user_updates_wiki_page_shared_examples.rb8
-rw-r--r--spec/support/shared_examples/features/wiki/user_views_wiki_page_shared_examples.rb6
-rw-r--r--spec/support/shared_examples/lib/gitlab/cycle_analytics/deployment_metrics.rb124
-rw-r--r--spec/support/shared_examples/lib/gitlab/sidekiq_middleware/strategy_shared_examples.rb52
-rw-r--r--spec/support/shared_examples/mailers/notify_shared_examples.rb6
-rw-r--r--spec/support/shared_examples/models/concerns/featurable_shared_examples.rb12
-rw-r--r--spec/support/shared_examples/models/concerns/sanitizable_shared_examples.rb41
-rw-r--r--spec/support/shared_examples/models/member_shared_examples.rb56
-rw-r--r--spec/support/shared_examples/models/mentionable_shared_examples.rb36
-rw-r--r--spec/support/shared_examples/namespaces/traversal_scope_examples.rb125
-rw-r--r--spec/support/shared_examples/requests/api/helm_packages_shared_examples.rb21
-rw-r--r--spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb15
-rw-r--r--spec/support/shared_examples/requests/api/packages_shared_examples.rb12
-rw-r--r--spec/support/shared_examples/requests/rack_attack_shared_examples.rb202
-rw-r--r--spec/support/shared_examples/services/dependency_proxy_ttl_policies_shared_examples.rb34
-rw-r--r--spec/support/shared_examples/services/incident_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/services/users/dismiss_user_callout_service_shared_examples.rb37
-rw-r--r--spec/support/shared_examples/work_item_base_types_importer.rb10
-rw-r--r--spec/support_specs/database/prevent_cross_database_modification_spec.rb27
-rw-r--r--spec/support_specs/database/prevent_cross_joins_spec.rb28
-rw-r--r--spec/tasks/gitlab/db_rake_spec.rb7
-rw-r--r--spec/tasks/gitlab/product_intelligence_rake_spec.rb80
-rw-r--r--spec/tooling/danger/project_helper_spec.rb4
-rw-r--r--spec/tooling/graphql/docs/renderer_spec.rb4
-rw-r--r--spec/validators/gitlab/utils/zoom_url_validator_spec.rb36
-rw-r--r--spec/validators/gitlab/zoom_url_validator_spec.rb36
-rw-r--r--spec/views/groups/group_members/index.html.haml_spec.rb68
-rw-r--r--spec/views/help/instance_configuration.html.haml_spec.rb9
-rw-r--r--spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb30
-rw-r--r--spec/views/profiles/notifications/show.html.haml_spec.rb29
-rw-r--r--spec/views/projects/diffs/_stats.html.haml_spec.rb58
-rw-r--r--spec/views/projects/empty.html.haml_spec.rb2
-rw-r--r--spec/views/projects/merge_requests/_commits.html.haml_spec.rb8
-rw-r--r--spec/views/projects/project_members/index.html.haml_spec.rb96
-rw-r--r--spec/views/search/_results.html.haml_spec.rb8
-rw-r--r--spec/views/shared/access_tokens/_table.html.haml_spec.rb2
-rw-r--r--spec/workers/authorized_project_update/user_refresh_from_replica_worker_spec.rb15
-rw-r--r--spec/workers/background_migration_worker_spec.rb22
-rw-r--r--spec/workers/bulk_import_worker_spec.rb19
-rw-r--r--spec/workers/bulk_imports/pipeline_worker_spec.rb20
-rw-r--r--spec/workers/ci/external_pull_requests/create_pipeline_worker_spec.rb69
-rw-r--r--spec/workers/concerns/worker_attributes_spec.rb44
-rw-r--r--spec/workers/database/partition_management_worker_spec.rb6
-rw-r--r--spec/workers/deployments/finished_worker_spec.rb65
-rw-r--r--spec/workers/deployments/hooks_worker_spec.rb1
-rw-r--r--spec/workers/deployments/success_worker_spec.rb38
-rw-r--r--spec/workers/environments/auto_stop_worker_spec.rb71
-rw-r--r--spec/workers/every_sidekiq_worker_spec.rb2
-rw-r--r--spec/workers/expire_job_cache_worker_spec.rb41
-rw-r--r--spec/workers/expire_pipeline_cache_worker_spec.rb17
-rw-r--r--spec/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker_spec.rb43
-rw-r--r--spec/workers/gitlab/github_import/stage/import_notes_worker_spec.rb60
-rw-r--r--spec/workers/issue_rebalancing_worker_spec.rb28
-rw-r--r--spec/workers/namespaceless_project_destroy_worker_spec.rb6
-rw-r--r--spec/workers/packages/helm/extraction_worker_spec.rb14
-rw-r--r--spec/workers/pages_remove_worker_spec.rb22
-rw-r--r--spec/workers/post_receive_spec.rb10
-rw-r--r--spec/workers/purge_dependency_proxy_cache_worker_spec.rb17
-rw-r--r--spec/workers/stuck_ci_jobs_worker_spec.rb299
-rw-r--r--spec/workers/todos_destroyer/destroyed_designs_worker_spec.rb14
-rw-r--r--storybook/config/preview.js10
-rw-r--r--storybook/package.json4
-rwxr-xr-xtooling/bin/find_changes21
-rwxr-xr-xtooling/bin/find_tests16
-rw-r--r--tooling/danger/product_intelligence.rb2
-rw-r--r--tooling/danger/project_helper.rb51
-rw-r--r--tooling/deprecations/docs.rb37
-rw-r--r--tooling/graphql/docs/helper.rb4
-rw-r--r--vendor/assets/javascripts/jasmine-jquery.js854
-rw-r--r--vendor/aws/cloudformation/eks_cluster.yaml14
-rw-r--r--vendor/project_templates/cluster_management.tar.gzbin12981 -> 14062 bytes
-rw-r--r--workhorse/Makefile7
-rw-r--r--workhorse/authorization_test.go2
-rw-r--r--workhorse/doc/architecture/channel.md2
-rw-r--r--workhorse/go.mod5
-rw-r--r--workhorse/go.sum11
-rw-r--r--workhorse/internal/artifacts/artifacts_upload_test.go2
-rw-r--r--workhorse/internal/filestore/file_handler.go2
-rw-r--r--workhorse/internal/filestore/file_handler_test.go2
-rw-r--r--workhorse/internal/imageresizer/image_resizer.go4
-rw-r--r--workhorse/internal/secret/jwt.go2
-rw-r--r--workhorse/internal/testhelper/testhelper.go2
-rw-r--r--workhorse/internal/upload/accelerate.go2
-rw-r--r--workhorse/internal/upload/body_uploader_test.go2
-rw-r--r--workhorse/internal/upload/saved_file_tracker_test.go2
-rw-r--r--workhorse/internal/upstream/roundtripper/roundtripper.go10
-rw-r--r--workhorse/internal/upstream/roundtripper/roundtripper_test.go56
-rw-r--r--workhorse/internal/upstream/routes.go2
-rw-r--r--workhorse/upload_test.go2
-rw-r--r--yarn.lock2242
5909 files changed, 152896 insertions, 84143 deletions
diff --git a/.codeclimate.yml b/.codeclimate.yml
index ccc09fcc775..c479454285e 100644
--- a/.codeclimate.yml
+++ b/.codeclimate.yml
@@ -36,6 +36,5 @@ exclude_paths:
- webpack-report/
- log/
- backups/
- - coverage-javascript/
- plugins/
- file_hooks/
diff --git a/.eslintignore b/.eslintignore
index 7ca59654678..d5f89284b53 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -2,7 +2,6 @@
/builds/
/coverage/
/coverage-frontend/
-/coverage-javascript/
/node_modules/
/public/
/tmp/
diff --git a/.gitignore b/.gitignore
index d1d2bfde1aa..f753a247563 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@
*.mo
*.edit.po
*.rej
+.dir-locals.el
.DS_Store
.bundle
.chef
@@ -49,7 +50,6 @@ eslint-report.html
/config/sidekiq.yml
/config/registry.key
/coverage/*
-/coverage-javascript/
/db/*.sqlite3
/db/*.sqlite3-journal
/db/data.yml
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b5a8e8e6d73..891551cd41e 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -17,7 +17,7 @@ stages:
# in cases where jobs require Docker-in-Docker, the job
# definition must be extended with `.use-docker-in-docker`
default:
- image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.2.patched-golang-1.14-git-2.31-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-11-graphicsmagick-1.3.36"
+ image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.patched-golang-1.16-git-2.31-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-11-graphicsmagick-1.3.36"
tags:
- gitlab-org
# All jobs are interruptible by default
diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS
index ae697582623..095601ba825 100644
--- a/.gitlab/CODEOWNERS
+++ b/.gitlab/CODEOWNERS
@@ -13,7 +13,6 @@
/doc/.vale/ @marcel.amirault @eread @aqualls @cnorris
/doc/administration/geo/ @axil
/doc/administration/gitaly/ @eread
-/doc/administration/integration/ @aqualls
/doc/administration/lfs/ @aqualls
/doc/administration/monitoring/ @ngaskill
/doc/administration/operations/ @axil @eread @marcia
@@ -25,6 +24,8 @@
/doc/administration/reference_architectures/ @axil
/doc/administration/snippets/ @aqualls
/doc/administration/troubleshooting @axil @marcia @eread
+/doc/api/graphql/ @msedlakjakubowski @kpaizee
+/doc/api/graphql/reference/ @kpaizee
/doc/api/group_activity_analytics.md @msedlakjakubowski
/doc/ci/ @marcel.amirault @sselhorn
/doc/ci/environments/ @axil
@@ -34,18 +35,19 @@
/doc/development/documentation/ @cnorris
/doc/development/i18n/ @ngaskill
/doc/development/value_stream_analytics.md @msedlakjakubowski
-/doc/gitlab-basics/ @marcia
+/doc/gitlab-basics/ @aqualls
/doc/install/ @axil
-/doc/integration/ @aqualls @eread
/doc/operations/ @ngaskill @axil
/doc/push_rules/ @aqualls
/doc/ssh/ @eread
/doc/subscriptions/ @sselhorn
-/doc/topics/autodevops/ @ngaskill @marcia
+/doc/topics/autodevops/ @marcia
/doc/topics/git/ @aqualls
/doc/update/ @axil @marcia
/doc/user/analytics/ @msedlakjakubowski @ngaskill
-/doc/user/application_security @rdickenson
+/doc/user/application_security/ @rdickenson
+/doc/user/application_security/container_scanning/ @ngaskill
+/doc/user/application_security/cluster_image_scanning/ @ngaskill
/doc/user/clusters/ @marcia
/doc/user/compliance/ @rdickenson @eread
/doc/user/group/ @msedlakjakubowski
@@ -57,12 +59,12 @@
/doc/user/group/value_stream_analytics/ @msedlakjakubowski
/doc/user/infrastructure/ @marcia
/doc/user/packages/ @ngaskill
+/doc/user/packages/infrastructure_registry/ @marcia
+/doc/user/packages/terraform_module_registry/ @marcia
/doc/user/profile/ @msedlakjakubowski @eread
/doc/user/project/ @aqualls @axil @eread @msedlakjakubowski @ngaskill
-/doc/user/project/clusters/ @ngaskill
+/doc/user/project/clusters/ @marcia
/doc/user/project/import/ @ngaskill @msedlakjakubowski
-/doc/user/project/integrations/ @aqualls
-/doc/user/project/integrations/prometheus_library/ @ngaskill
/doc/user/project/issues/ @msedlakjakubowski
/doc/user/project/merge_requests/ @aqualls @eread
/doc/user/project/milestones/ @msedlakjakubowski
@@ -138,6 +140,12 @@
/doc/user/project/settings/import_export.md @aqualls
/doc/user/snippets.md @aqualls
+[Docs Ecosystem]
+/doc/administration/integration/ @kpaizee
+/doc/integration/ @kpaizee
+/doc/user/project/integrations/ @kpaizee
+/doc/user/project/integrations/prometheus_library/ @ngaskill
+
[Docs Growth]
/doc/administration/instance_review.md @kpaizee
/doc/api/invitations.md @kpaizee
@@ -152,8 +160,6 @@
*.js @gitlab-org/maintainers/frontend
/app/assets/ @gitlab-org/maintainers/frontend
/ee/app/assets/ @gitlab-org/maintainers/frontend
-/spec/javascripts/ @gitlab-org/maintainers/frontend
-/ee/spec/javascripts/ @gitlab-org/maintainers/frontend
/spec/frontend/ @gitlab-org/maintainers/frontend
/ee/spec/frontend/ @gitlab-org/maintainers/frontend
/spec/frontend_integration/ @gitlab-org/maintainers/frontend
@@ -201,9 +207,9 @@ Dangerfile @gl-quality/eng-prod
/lib/gitlab/auth/ldap/ @dblessing @mkozono
[Templates]
-/lib/gitlab/ci/templates/ @nolith @shinya.maeda @matteeyah
+/lib/gitlab/ci/templates/ @gitlab-org/maintainers/cicd-templates
/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml @DylanGriffith @mayra-cabrera @tkuah
-/lib/gitlab/ci/templates/Security/ @gonzoyumo @twoodham @sethgitlab @thiagocsf
+/lib/gitlab/ci/templates/Security/ @gonzoyumo @twoodham @sethgitlab @thiagocsf
/lib/gitlab/ci/templates/Security/Container-Scanning.*.yml @gitlab-org/protect/container-security-backend
[Project Alias]
diff --git a/.gitlab/changelog_config.yml b/.gitlab/changelog_config.yml
index 6069cd17a08..f6a041cced9 100644
--- a/.gitlab/changelog_config.yml
+++ b/.gitlab/changelog_config.yml
@@ -11,6 +11,8 @@ categories:
security: Security
performance: Performance
other: Other
+include_groups:
+ - gitlab-org/gitlab-core-team/community-members
template: |
{% if categories %}
{% each categories %}
@@ -18,7 +20,7 @@ template: |
{% each entries %}
- [{{ title }}]({{ commit.reference }})\
- {% if author.contributor %} by {{ author.reference }}{% end %}\
+ {% if author.credit %} by {{ author.reference }}{% end %}\
{% if commit.trailers.MR %}\
([merge request]({{ commit.trailers.MR }}))\
{% else %}\
diff --git a/.gitlab/ci/docs.gitlab-ci.yml b/.gitlab/ci/docs.gitlab-ci.yml
index ea3e3ac450b..c585047f916 100644
--- a/.gitlab/ci/docs.gitlab-ci.yml
+++ b/.gitlab/ci/docs.gitlab-ci.yml
@@ -53,7 +53,7 @@ docs-lint markdown:
docs-lint links:
extends:
- .docs:rules:docs-lint
- image: registry.gitlab.com/gitlab-org/gitlab-docs/lint-html:alpine-3.13-ruby-2.7.2-d2b92621
+ image: registry.gitlab.com/gitlab-org/gitlab-docs/lint-html:alpine-3.14-ruby-2.7.4-db71f027
stage: test
needs: []
script:
@@ -75,3 +75,17 @@ ui-docs-links lint:
needs: []
script:
- bundle exec haml-lint -i DocumentationLinks
+
+deprecations-doc check:
+ variables:
+ SETUP_DB: "false"
+ extends:
+ - .default-retry
+ - .rails-cache
+ - .default-before_script
+ - .docs:rules:deprecations
+ stage: test
+ needs: []
+ script:
+ - bundle exec rake gitlab:docs:check_deprecations
+ allow_failure: true
diff --git a/.gitlab/ci/frontend.gitlab-ci.yml b/.gitlab/ci/frontend.gitlab-ci.yml
index bfc38e73bb5..48f85219ff4 100644
--- a/.gitlab/ci/frontend.gitlab-ci.yml
+++ b/.gitlab/ci/frontend.gitlab-ci.yml
@@ -11,7 +11,7 @@
- .default-retry
- .default-before_script
- .assets-compile-cache
- image: registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.2-git-2.31-lfs-2.9-node-14.15-yarn-1.22-graphicsmagick-1.3.36
+ image: registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7-git-2.31-lfs-2.9-node-14.15-yarn-1.22-graphicsmagick-1.3.36
variables:
SETUP_DB: "false"
WEBPACK_VENDOR_DLL: "true"
@@ -132,6 +132,7 @@ rspec frontend_fixture:
extends:
- .frontend-fixtures-base
- .frontend:rules:default-frontend-jobs
+ parallel: 2
rspec frontend_fixture as-if-foss:
extends:
@@ -171,6 +172,8 @@ graphql-schema-dump:
# Disable warnings in browserslist which can break on backports
# https://github.com/browserslist/browserslist/blob/a287ec6/node.js#L367-L384
BROWSERSLIST_IGNORE_OLD_DATA: "true"
+ before_script:
+ - *yarn-install
stage: test
eslint-as-if-foss:
@@ -180,55 +183,19 @@ eslint-as-if-foss:
- .as-if-foss
needs: []
script:
- - *yarn-install
- run_timed_command "yarn run lint:eslint:all"
-.karma-base:
- extends: .frontend-test-base
- script:
- - export BABEL_ENV=coverage CHROME_LOG_FILE=chrome_debug.log
- - *yarn-install
- - run_timed_command "yarn karma"
-
-karma:
- extends:
- - .karma-base
- - .frontend:rules:default-frontend-jobs
- needs:
- - job: "rspec frontend_fixture"
- - job: "rspec-ee frontend_fixture"
- optional: true
- coverage: '/^Statements *: (\d+\.\d+%)/'
- artifacts:
- name: coverage-javascript
- expire_in: 31d
- when: always
- paths:
- - chrome_debug.log
- - coverage-javascript/
- - tmp/tests/frontend/
- reports:
- junit: junit_karma.xml
- cobertura: coverage-javascript/cobertura-coverage.xml
-
-karma-as-if-foss:
- extends:
- - .karma-base
- - .frontend:rules:default-frontend-jobs-as-if-foss
- - .as-if-foss
- needs: ["rspec frontend_fixture as-if-foss"]
-
.jest-base:
extends: .frontend-test-base
script:
- - *yarn-install
- - run_timed_command "yarn jest --ci --coverage --testSequencer ./scripts/frontend/parallel_ci_sequencer.js"
+ - run_timed_command "yarn jest:ci"
jest:
extends:
- .jest-base
- - .frontend:rules:default-frontend-jobs
+ - .frontend:rules:jest
needs:
+ - job: "detect-tests"
- job: "rspec frontend_fixture"
- job: "rspec-ee frontend_fixture"
optional: true
@@ -244,12 +211,18 @@ jest:
junit: junit_jest.xml
parallel: 5
+jest minimal:
+ extends:
+ - jest
+ - .frontend:rules:jest:minimal
+ script:
+ - run_timed_command "yarn jest:ci:minimal"
+
jest-integration:
extends:
- .frontend-test-base
- .frontend:rules:default-frontend-jobs
script:
- - *yarn-install
- run_timed_command "yarn jest:integration --ci"
needs:
- job: "rspec frontend_fixture"
@@ -270,7 +243,11 @@ coverage-frontend:
- .default-retry
- .yarn-cache
- .frontend:rules:ee-mr-and-default-branch-only
- needs: ["jest"]
+ needs:
+ - job: "jest"
+ optional: true
+ - job: "jest minimal"
+ optional: true
stage: post-test
before_script:
- *yarn-install
@@ -298,9 +275,13 @@ coverage-frontend:
- *yarn-install
- run_timed_command "retry yarn run webpack-prod"
-qa-frontend-node:10:
+qa-frontend-node:12:
+ extends: .qa-frontend-node
+ image: ${GITLAB_DEPENDENCY_PROXY}node:12
+
+qa-frontend-node:14:
extends: .qa-frontend-node
- image: ${GITLAB_DEPENDENCY_PROXY}node:dubnium
+ image: ${GITLAB_DEPENDENCY_PROXY}node:14
qa-frontend-node:latest:
extends:
@@ -351,7 +332,6 @@ bundle-size-review:
extends:
- .frontend-test-base
script:
- - *yarn-install
- run_timed_command "yarn generate:startup_css"
- yarn check:startup_css
@@ -379,7 +359,6 @@ startup-css-check as-if-foss:
- .frontend-test-base
- .storybook-yarn-cache
script:
- - *yarn-install # storybook depends on the global webpack config, so we must install global deps.
- *storybook-yarn-install
- yarn run storybook:build
diff --git a/.gitlab/ci/global.gitlab-ci.yml b/.gitlab/ci/global.gitlab-ci.yml
index 860397b9437..d9978a44ffb 100644
--- a/.gitlab/ci/global.gitlab-ci.yml
+++ b/.gitlab/ci/global.gitlab-ci.yml
@@ -200,7 +200,7 @@
- *storybook-node-modules-cache-push
.use-pg11:
- image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.2.patched-golang-1.16-git-2.31-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-11-graphicsmagick-1.3.36"
+ image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.patched-golang-1.16-git-2.31-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-11-graphicsmagick-1.3.36"
services:
- name: postgres:11.6
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
@@ -209,7 +209,7 @@
POSTGRES_HOST_AUTH_METHOD: trust
.use-pg12:
- image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.2.patched-golang-1.16-git-2.31-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-12-graphicsmagick-1.3.36"
+ image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.patched-golang-1.16-git-2.31-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-12-graphicsmagick-1.3.36"
services:
- name: postgres:12
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
@@ -218,7 +218,7 @@
POSTGRES_HOST_AUTH_METHOD: trust
.use-pg13:
- image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.2.patched-golang-1.16-git-2.31-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-13-graphicsmagick-1.3.36"
+ image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.patched-golang-1.16-git-2.31-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-13-graphicsmagick-1.3.36"
services:
- name: postgres:13
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
@@ -227,7 +227,7 @@
POSTGRES_HOST_AUTH_METHOD: trust
.use-pg11-ee:
- image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.2.patched-golang-1.16-git-2.31-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-11-graphicsmagick-1.3.36"
+ image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.patched-golang-1.16-git-2.31-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-11-graphicsmagick-1.3.36"
services:
- name: postgres:11.6
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
@@ -238,7 +238,7 @@
POSTGRES_HOST_AUTH_METHOD: trust
.use-pg12-ee:
- image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.2.patched-golang-1.16-git-2.31-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-12-graphicsmagick-1.3.36"
+ image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.patched-golang-1.16-git-2.31-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-12-graphicsmagick-1.3.36"
services:
- name: postgres:12
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
@@ -249,7 +249,7 @@
POSTGRES_HOST_AUTH_METHOD: trust
.use-pg13-ee:
- image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.2.patched-golang-1.16-git-2.31-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-13-graphicsmagick-1.3.36"
+ image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.patched-golang-1.16-git-2.31-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-13-graphicsmagick-1.3.36"
services:
- name: postgres:13
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
diff --git a/.gitlab/ci/pages.gitlab-ci.yml b/.gitlab/ci/pages.gitlab-ci.yml
index 2f43e974cf6..6f96d84b8e3 100644
--- a/.gitlab/ci/pages.gitlab-ci.yml
+++ b/.gitlab/ci/pages.gitlab-ci.yml
@@ -12,7 +12,6 @@ pages:
needs:
- job: "rspec:coverage"
- job: "coverage-frontend"
- - job: "karma"
- job: "compile-production-assets"
- job: "compile-storybook"
# `update-tests-metadata` only runs on GitLab.com's EE schedules pipelines
@@ -27,7 +26,6 @@ pages:
- mkdir -p public/$(dirname "$KNAPSACK_RSPEC_SUITE_REPORT_PATH") public/$(dirname "$FLAKY_RSPEC_SUITE_REPORT_PATH") public/$(dirname "$RSPEC_PACKED_TESTS_MAPPING_PATH")
- mv coverage/ public/coverage-ruby/ || true
- mv coverage-frontend/ public/coverage-frontend/ || true
- - mv coverage-javascript/ public/coverage-javascript/ || true
- mv storybook/public public/storybook || true
- cp .public/assets/application-*.css public/application.css || true
- mv $KNAPSACK_RSPEC_SUITE_REPORT_PATH public/$KNAPSACK_RSPEC_SUITE_REPORT_PATH || true
diff --git a/.gitlab/ci/qa.gitlab-ci.yml b/.gitlab/ci/qa.gitlab-ci.yml
index c3e6de76894..88e732c2e75 100644
--- a/.gitlab/ci/qa.gitlab-ci.yml
+++ b/.gitlab/ci/qa.gitlab-ci.yml
@@ -7,6 +7,7 @@
variables:
USE_BUNDLE_INSTALL: "false"
SETUP_DB: "false"
+ QA_EXPORT_TEST_METRICS: "false"
before_script:
- !reference [.default-before_script, before_script]
- cd qa/
diff --git a/.gitlab/ci/rails.gitlab-ci.yml b/.gitlab/ci/rails.gitlab-ci.yml
index f4b001ed1ba..00f65ab7ca8 100644
--- a/.gitlab/ci/rails.gitlab-ci.yml
+++ b/.gitlab/ci/rails.gitlab-ci.yml
@@ -23,6 +23,10 @@
variables:
RSPEC_TESTS_MAPPING_ENABLED: "true"
+.decomposed-database-rspec:
+ variables:
+ DECOMPOSED_DB: "true"
+
.rspec-base:
extends: .rails-job-base
stage: test
@@ -225,65 +229,6 @@ update-gitaly-binaries-cache:
SETUP_DB: "false"
USE_BUNDLE_INSTALL: "false"
-.static-analysis-base:
- extends:
- - .default-retry
- - .default-before_script
- - .static-analysis-cache
- needs: []
- variables:
- SETUP_DB: "false"
- ENABLE_SPRING: "1"
- # Disable warnings in browserslist which can break on backports
- # https://github.com/browserslist/browserslist/blob/a287ec6/node.js#L367-L384
- BROWSERSLIST_IGNORE_OLD_DATA: "true"
-
-update-static-analysis-cache:
- extends:
- - .static-analysis-base
- - .static-analysis-cache-push
- - .shared:rules:update-cache
- stage: prepare
- script:
- - run_timed_command "bundle exec rubocop --parallel" # For the moment we only cache `tmp/rubocop_cache` so we don't need to run all the tasks.
-
-static-analysis:
- extends:
- - .static-analysis-base
- - .static-analysis:rules:ee-and-foss
- stage: test
- parallel: 4
- script:
- - run_timed_command "retry yarn install --frozen-lockfile"
- - scripts/static-analysis
- artifacts:
- expire_in: 31d
- when: always
- paths:
- - tmp/feature_flags/
-
-static-analysis as-if-foss:
- extends:
- - static-analysis
- - .static-analysis:rules:as-if-foss
- - .as-if-foss
-
-zeitwerk-check:
- extends:
- - .rails-cache
- - .default-before_script
- - .rails:rules:ee-and-foss-unit
- variables:
- BUNDLE_WITHOUT: ""
- SETUP_DB: "false"
- needs: []
- stage: test
- script:
- - sed -i -e "s/config\.autoloader = :classic/config\.autoloader = :zeitwerk/" config/application.rb
- - RAILS_ENV=test bundle exec rake zeitwerk:check
- - RAILS_ENV=development bundle exec rake zeitwerk:check
- - RAILS_ENV=production bundle exec rake zeitwerk:check
-
rspec migration pg12:
extends:
- .rspec-base-pg12
@@ -296,6 +241,12 @@ rspec migration pg12 minimal:
- .minimal-rspec-tests
- .rails:rules:ee-and-foss-migration:minimal
+rspec migration pg12 decomposed:
+ extends:
+ - rspec migration pg12
+ - .decomposed-database-rspec
+ - .rails:rules:decomposed-databases
+
rspec unit pg12:
extends:
- .rspec-base-pg12
@@ -308,6 +259,12 @@ rspec unit pg12 minimal:
- .minimal-rspec-tests
- .rails:rules:ee-and-foss-unit:minimal
+rspec unit pg12 decomposed:
+ extends:
+ - rspec unit pg12
+ - .decomposed-database-rspec
+ - .rails:rules:decomposed-databases
+
rspec integration pg12:
extends:
- .rspec-base-pg12
@@ -320,6 +277,12 @@ rspec integration pg12 minimal:
- .minimal-rspec-tests
- .rails:rules:ee-and-foss-integration:minimal
+rspec integration pg12 decomposed:
+ extends:
+ - rspec integration pg12
+ - .decomposed-database-rspec
+ - .rails:rules:decomposed-databases
+
rspec system pg12:
extends:
- .rspec-base-pg12
@@ -332,6 +295,12 @@ rspec system pg12 minimal:
- .minimal-rspec-tests
- .rails:rules:ee-and-foss-system:minimal
+rspec system pg12 decomposed:
+ extends:
+ - rspec system pg12
+ - .decomposed-database-rspec
+ - .rails:rules:decomposed-databases
+
# Dedicated job to test DB library code against PG11.
# Note that these are already tested against PG12 in the `rspec unit pg12` / `rspec-ee unit pg12` jobs.
rspec db-library-code pg11:
@@ -382,18 +351,12 @@ db:migrate-from-previous-major-version:
USE_BUNDLE_INSTALL: "false"
SETUP_DB: "false"
PROJECT_TO_CHECKOUT: "gitlab-foss"
- TAG_TO_CHECKOUT: "v12.10.14"
+ TAG_TO_CHECKOUT: "v13.12.9"
script:
- '[[ -d "ee/" ]] || export PROJECT_TO_CHECKOUT="gitlab"'
- '[[ -d "ee/" ]] || export TAG_TO_CHECKOUT="${TAG_TO_CHECKOUT}-ee"'
- retry 'git fetch https://gitlab.com/gitlab-org/$PROJECT_TO_CHECKOUT.git $TAG_TO_CHECKOUT'
- git checkout -f FETCH_HEAD
- # Patch Gemfile of the previous major version for compatibility.
- - sed -i -e "s/gem 'grpc', '~> 1.24.0'/gem 'grpc', '~> 1.30.2'/" Gemfile # Update gRPC for Ruby 2.7
- - sed -i -e "s/gem 'google-protobuf', '~> 3.8.0'/gem 'google-protobuf', '~> 3.12'/" Gemfile
- - sed -i -e "s/gem 'nokogiri', '~> 1.10.5'/gem 'nokogiri', '~> 1.11.0'/" Gemfile
- - sed -i -e "s/gem 'mimemagic', '~> 0.3.2'/gem 'ruby-magic', '~> 0.4.0'/" Gemfile
- - run_timed_command "bundle update --bundler google-protobuf nokogiri grpc mimemagic bootsnap"
- SETUP_DB=false USE_BUNDLE_INSTALL=true bash scripts/prepare_build.sh
- run_timed_command "bundle exec rake db:drop db:create db:structure:load db:migrate db:seed_fu"
- git checkout -f $CI_COMMIT_SHA
@@ -554,6 +517,12 @@ rspec migration pg12-as-if-foss minimal:
- .minimal-rspec-tests
- .rails:rules:as-if-foss-migration:minimal
+rspec migration pg12-as-if-foss decomposed:
+ extends:
+ - rspec migration pg12-as-if-foss
+ - .decomposed-database-rspec
+ - .rails:rules:decomposed-databases
+
rspec unit pg12-as-if-foss:
extends:
- .rspec-base-pg12-as-if-foss
@@ -566,6 +535,12 @@ rspec unit pg12-as-if-foss minimal:
- .minimal-rspec-tests
- .rails:rules:as-if-foss-unit:minimal
+rspec unit pg12-as-if-foss decomposed:
+ extends:
+ - rspec unit pg12-as-if-foss
+ - .decomposed-database-rspec
+ - .rails:rules:decomposed-databases
+
rspec integration pg12-as-if-foss:
extends:
- .rspec-base-pg12-as-if-foss
@@ -578,6 +553,12 @@ rspec integration pg12-as-if-foss minimal:
- .minimal-rspec-tests
- .rails:rules:as-if-foss-integration:minimal
+rspec integration pg12-as-if-foss decomposed:
+ extends:
+ - rspec integration pg12-as-if-foss
+ - .decomposed-database-rspec
+ - .rails:rules:decomposed-databases
+
rspec system pg12-as-if-foss:
extends:
- .rspec-base-pg12-as-if-foss
@@ -590,6 +571,12 @@ rspec system pg12-as-if-foss minimal:
- .minimal-rspec-tests
- .rails:rules:as-if-foss-system:minimal
+rspec system pg12-as-if-foss decomposed:
+ extends:
+ - rspec system pg12-as-if-foss
+ - .decomposed-database-rspec
+ - .rails:rules:decomposed-databases
+
rspec-ee migration pg12:
extends:
- .rspec-ee-base-pg12
@@ -603,6 +590,12 @@ rspec-ee migration pg12 minimal:
- .minimal-rspec-tests
- .rails:rules:ee-only-migration:minimal
+rspec-ee migration pg12 decomposed:
+ extends:
+ - rspec-ee migration pg12
+ - .decomposed-database-rspec
+ - .rails:rules:decomposed-databases
+
rspec-ee unit pg12:
extends:
- .rspec-ee-base-pg12
@@ -615,6 +608,12 @@ rspec-ee unit pg12 minimal:
- .minimal-rspec-tests
- .rails:rules:ee-only-unit:minimal
+rspec-ee unit pg12 decomposed:
+ extends:
+ - rspec-ee unit pg12
+ - .decomposed-database-rspec
+ - .rails:rules:decomposed-databases
+
rspec-ee integration pg12:
extends:
- .rspec-ee-base-pg12
@@ -627,6 +626,12 @@ rspec-ee integration pg12 minimal:
- .minimal-rspec-tests
- .rails:rules:ee-only-integration:minimal
+rspec-ee integration pg12 decomposed:
+ extends:
+ - rspec-ee integration pg12
+ - .decomposed-database-rspec
+ - .rails:rules:decomposed-databases
+
rspec-ee system pg12:
extends:
- .rspec-ee-base-pg12
@@ -639,6 +644,12 @@ rspec-ee system pg12 minimal:
- .minimal-rspec-tests
- .rails:rules:ee-only-system:minimal
+rspec-ee system pg12 decomposed:
+ extends:
+ - rspec-ee system pg12
+ - .decomposed-database-rspec
+ - .rails:rules:decomposed-databases
+
rspec-ee unit pg12 geo:
extends:
- .rspec-ee-base-geo-pg12
diff --git a/.gitlab/ci/reports.gitlab-ci.yml b/.gitlab/ci/reports.gitlab-ci.yml
index 7fb4e54c4d6..a5403073e1b 100644
--- a/.gitlab/ci/reports.gitlab-ci.yml
+++ b/.gitlab/ci/reports.gitlab-ci.yml
@@ -27,14 +27,11 @@ code_quality:
variables:
SAST_BRAKEMAN_LEVEL: 2 # GitLab-specific
SAST_EXCLUDED_PATHS: "qa, spec, doc, ee/spec, config/gitlab.yml.example, tmp" # GitLab-specific
- SAST_EXCLUDED_ANALYZERS: bandit, flawfinder, phpcs-security-audit, pmd-apex, security-code-scan, spotbugs
+ SAST_EXCLUDED_ANALYZERS: bandit, flawfinder, phpcs-security-audit, pmd-apex, security-code-scan, spotbugs, eslint
brakeman-sast:
rules: !reference [".reports:rules:sast", rules]
-eslint-sast:
- rules: !reference [".reports:rules:sast", rules]
-
nodejs-scan-sast:
rules: !reference [".reports:rules:sast", rules]
diff --git a/.gitlab/ci/review.gitlab-ci.yml b/.gitlab/ci/review.gitlab-ci.yml
index c22b468d674..f20f3276867 100644
--- a/.gitlab/ci/review.gitlab-ci.yml
+++ b/.gitlab/ci/review.gitlab-ci.yml
@@ -46,7 +46,7 @@ review-build-cng:
variables:
HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}"
DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}"
- GITLAB_HELM_CHART_REF: "v5.1.0"
+ GITLAB_HELM_CHART_REF: "v5.2.1"
environment:
name: review/${CI_COMMIT_REF_SLUG}${FREQUENCY}
url: https://gitlab-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}
diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml
index 53420dfe31a..a4a932c7dd0 100644
--- a/.gitlab/ci/rules.gitlab-ci.yml
+++ b/.gitlab/ci/rules.gitlab-ci.yml
@@ -46,6 +46,12 @@
.if-merge-request-title-run-all-rspec: &if-merge-request-title-run-all-rspec
if: '$CI_MERGE_REQUEST_LABELS =~ /pipeline:run-all-rspec/'
+.if-merge-request-title-run-all-jest: &if-merge-request-title-run-all-jest
+ if: '$CI_MERGE_REQUEST_LABELS =~ /pipeline:run-all-jest/'
+
+.if-merge-request-run-decomposed: &if-merge-request-run-decomposed
+ if: '$CI_MERGE_REQUEST_LABELS =~ /pipeline:run-decomposed/'
+
.if-security-merge-request: &if-security-merge-request
if: '$CI_PROJECT_NAMESPACE == "gitlab-org/security" && $CI_MERGE_REQUEST_IID'
@@ -117,6 +123,7 @@
- "scripts/review_apps/base-config.yaml"
- "scripts/review_apps/review-apps.sh"
- "scripts/trigger-build"
+ - "{,ee/,jh/}{bin,config}/**/*.rb"
.ci-qa-patterns: &ci-qa-patterns
- ".gitlab-ci.yml"
@@ -136,7 +143,6 @@
- ".gitlab-ci.yml"
- ".gitlab/ci/**/*.yml"
- "lib/gitlab/ci/templates/**/*.yml"
- - "{,ee/,jh/}changelogs/**/*.yml"
.docs-patterns: &docs-patterns
- ".gitlab/route-map.yml"
@@ -144,6 +150,13 @@
- ".markdownlint.yml"
- "scripts/lint-doc.sh"
+.docs-deprecations-patterns: &docs-deprecations-patterns
+ - "doc/deprecations/index.md"
+ - "data/deprecations/*.yml"
+ - "data/deprecations/templates/_deprecation_template.md.erb"
+ - "lib/tasks/gitlab/docs/compile_deprecations.rake"
+ - "tooling/deprecations/docs.rb"
+
.bundler-patterns: &bundler-patterns
- '{Gemfile.lock,*/Gemfile.lock,*/*/Gemfile.lock}'
@@ -197,7 +210,7 @@
- "{,ee/,jh/}app/assets/stylesheets/startup/**/*"
.backend-patterns: &backend-patterns
- - "Gemfile{,.lock}"
+ - "{,jh/}Gemfile{,.lock}"
- "Rakefile"
- "config.ru"
# List explicitly all the app/ dirs that are backend (i.e. all except app/assets).
@@ -216,6 +229,7 @@
- "{,ee/,jh/}{,spec/}lib/{,ee/,jh/}gitlab/background_migration/**/*"
- "{,ee/,jh/}{,spec/}lib/{,ee/,jh/}gitlab/background_migration{,_spec}.rb"
- "{,ee/,jh/}spec/support/helpers/database/**/*"
+ - "lib/gitlab/markdown_cache/active_record/**/*"
- "config/prometheus/common_metrics.yml" # Used by Gitlab::DatabaseImporters::CommonMetrics::Importer
- "{,ee/,jh/}app/models/project_statistics.rb" # Used to calculate sizes in migration specs
- "GITALY_SERVER_VERSION" # Has interactions with background migrations:https://gitlab.com/gitlab-org/gitlab/-/issues/336538
@@ -250,7 +264,7 @@
- ".{eslintignore,gitattributes,nvmrc,prettierrc,stylelintrc,yamllint}"
- ".{codeclimate,eslintrc,gitlab-ci,haml-lint,haml-lint_todo,rubocop,rubocop_todo,rubocop_manual_todo}.yml"
- "*_VERSION"
- - "Gemfile{,.lock}"
+ - "{,jh/}Gemfile{,.lock}"
- "Rakefile"
- "tests.yml"
- "config.ru"
@@ -276,7 +290,7 @@
- ".{eslintignore,gitattributes,nvmrc,prettierrc,stylelintrc,yamllint}"
- ".{codeclimate,eslintrc,gitlab-ci,haml-lint,haml-lint_todo,rubocop,rubocop_todo,rubocop_manual_todo}.yml"
- "*_VERSION"
- - "Gemfile{,.lock}"
+ - "{,jh/}Gemfile{,.lock}"
- "Rakefile"
- "tests.yml"
- "config.ru"
@@ -305,7 +319,7 @@
- ".{eslintignore,gitattributes,nvmrc,prettierrc,stylelintrc,yamllint}"
- ".{codeclimate,eslintrc,gitlab-ci,haml-lint,haml-lint_todo,rubocop,rubocop_todo,rubocop_manual_todo}.yml"
- "*_VERSION"
- - "Gemfile{,.lock}"
+ - "{,jh/}Gemfile{,.lock}"
- "Rakefile"
- "tests.yml"
- "config.ru"
@@ -330,7 +344,7 @@
- ".{eslintignore,gitattributes,nvmrc,prettierrc,stylelintrc,yamllint}"
- ".{codeclimate,eslintrc,gitlab-ci,haml-lint,haml-lint_todo,rubocop,rubocop_todo,rubocop_manual_todo}.yml"
- "*_VERSION"
- - "Gemfile{,.lock}"
+ - "{,jh/}Gemfile{,.lock}"
- "Rakefile"
- "tests.yml"
- "config.ru"
@@ -354,6 +368,14 @@
- "danger/**/*"
- "tooling/danger/**/*"
+.core-frontend-patterns: &core-frontend-patterns
+ - "{package.json,yarn.lock}"
+ - "babel.config.js"
+ - "jest.config.{base,integration,unit}.js"
+ - "config/helpers/**/*.js"
+ - "vendor/assets/javascripts/**/*"
+ - "{,ee/,jh/}app/assets/**/*.graphql"
+
################
# Shared rules #
################
@@ -449,6 +471,12 @@
changes: *docs-patterns
when: on_success
+.docs:rules:deprecations:
+ rules:
+ - <<: *if-default-refs
+ changes: *docs-deprecations-patterns
+ when: on_success
+
##################
# GraphQL rules #
##################
@@ -480,8 +508,8 @@
rules:
- <<: *if-not-ee
when: never
- - <<: *if-merge-request # Always run for MRs since `compile-test-assets as-if-foss` is either needed by `rspec foss-impact` or the `rspec * as-if-foss` jobs.
- changes: *code-backstage-qa-patterns
+ - changes: *code-backstage-qa-patterns
+ - <<: *if-merge-request-title-run-all-rspec
.frontend:rules:default-frontend-jobs:
rules:
@@ -508,6 +536,42 @@
- <<: *if-merge-request
changes: *ci-patterns
+.frontend:rules:jest:
+ rules:
+ - <<: *if-merge-request-title-run-all-jest
+ - <<: *if-default-refs
+ changes: *core-frontend-patterns
+ - <<: *if-merge-request
+ changes: *ci-patterns
+ - <<: *if-automated-merge-request
+ changes: *code-backstage-patterns
+ - <<: *if-default-refs
+ changes: *backend-patterns
+ - <<: *if-merge-request-not-approved
+ when: never
+ - <<: *if-default-refs
+ changes: *code-backstage-patterns
+
+.frontend:rules:jest:minimal:
+ rules:
+ - <<: *if-merge-request-approved
+ when: never
+ - <<: *if-automated-merge-request
+ when: never
+ - <<: *if-merge-request-title-run-all-jest
+ when: never
+ - <<: *if-default-refs
+ changes: *core-frontend-patterns
+ when: never
+ - <<: *if-default-refs
+ changes: *backend-patterns
+ when: never
+ - <<: *if-merge-request
+ changes: *ci-patterns
+ when: never
+ - <<: *if-merge-request
+ changes: *code-backstage-patterns
+
.frontend:rules:eslint-as-if-foss:
rules:
- <<: *if-not-ee
@@ -607,11 +671,18 @@
###############
# Rails rules #
###############
+.rails:rules:decomposed-databases:
+ rules:
+ - <<: *if-merge-request-run-decomposed
+ allow_failure: true
+
.rails:rules:ee-and-foss-migration:
rules:
- <<: *if-merge-request-title-run-all-rspec
- <<: *if-merge-request
changes: *ci-patterns
+ - <<: *if-merge-request
+ changes: *db-patterns
- <<: *if-automated-merge-request
changes: *db-patterns
- <<: *if-merge-request-not-approved
@@ -631,6 +702,7 @@
when: never
- <<: *if-merge-request
changes: *db-patterns
+ when: never
.rails:rules:ee-and-foss-mr-with-migration:
rules:
@@ -758,6 +830,8 @@
- <<: *if-merge-request-title-run-all-rspec
- <<: *if-merge-request
changes: *ci-patterns
+ - <<: *if-merge-request
+ changes: *db-patterns
- <<: *if-automated-merge-request
changes: *db-patterns
- <<: *if-merge-request-not-approved
@@ -779,6 +853,7 @@
when: never
- <<: *if-merge-request
changes: *db-patterns
+ when: never
.rails:rules:ee-only-unit:
rules:
@@ -874,14 +949,14 @@
- <<: *if-merge-request-title-run-all-rspec
- <<: *if-merge-request
changes: *ci-patterns
- - <<: *if-automated-merge-request
- changes: *db-patterns
- - <<: *if-merge-request-not-approved
- when: never
- <<: *if-security-merge-request
changes: *db-patterns
- <<: *if-merge-request-title-as-if-foss
changes: *db-patterns
+ - <<: *if-automated-merge-request
+ changes: *db-patterns
+ - <<: *if-merge-request-not-approved
+ when: never
.rails:rules:as-if-foss-migration:minimal:
rules:
@@ -896,8 +971,10 @@
when: never
- <<: *if-security-merge-request
changes: *db-patterns
+ when: never
- <<: *if-merge-request-title-as-if-foss
changes: *db-patterns
+ when: never
.rails:rules:as-if-foss-unit:
rules:
@@ -1212,7 +1289,7 @@
rules:
- if: '$DAST_DISABLED || $GITLAB_FEATURES !~ /\bdast\b/'
when: never
- - <<: *if-default-branch-schedule-nightly
+ - <<: *if-dot-com-ee-nightly-schedule
allow_failure: true
.reports:rules:package_hunter-yarn:
@@ -1405,8 +1482,6 @@
changes: *code-qa-patterns
when: manual
allow_failure: true
- - <<: *if-dot-com-gitlab-org-schedule
- allow_failure: true
.review:rules:danger:
rules:
diff --git a/.gitlab/ci/setup.gitlab-ci.yml b/.gitlab/ci/setup.gitlab-ci.yml
index f2d5d872d64..60a1ad54cff 100644
--- a/.gitlab/ci/setup.gitlab-ci.yml
+++ b/.gitlab/ci/setup.gitlab-ci.yml
@@ -70,11 +70,16 @@ verify-tests-yml:
- install_gitlab_gem
- install_tff_gem
- retrieve_tests_mapping
- - 'if [ -n "$CI_MERGE_REQUEST_IID" ]; then tooling/bin/find_tests ${MATCHED_TESTS_FILE}; fi'
- - 'if [ -n "$CI_MERGE_REQUEST_IID" ]; then echo "test files affected: $(cat $MATCHED_TESTS_FILE)"; fi'
+ - |
+ if [ -n "$CI_MERGE_REQUEST_IID" ]; then
+ tooling/bin/find_changes ${CHANGES_FILE};
+ tooling/bin/find_tests ${CHANGES_FILE} ${MATCHED_TESTS_FILE};
+ echo "related rspec tests: $(cat $MATCHED_TESTS_FILE)";
+ fi
artifacts:
expire_in: 7d
paths:
+ - ${CHANGES_FILE}
- ${MATCHED_TESTS_FILE}
detect-tests:
@@ -83,6 +88,7 @@ detect-tests:
- .rails:rules:detect-tests
variables:
RSPEC_TESTS_MAPPING_ENABLED: "true"
+ CHANGES_FILE: tmp/changed_files.txt
MATCHED_TESTS_FILE: tmp/matching_tests.txt
detect-tests as-if-foss:
@@ -91,6 +97,7 @@ detect-tests as-if-foss:
- .rails:rules:detect-tests
- .as-if-foss
variables:
+ CHANGES_FILE: tmp/changed_foss_files.txt
MATCHED_TESTS_FILE: tmp/matching_foss_tests.txt
before_script:
- '[ "$FOSS_ONLY" = "1" ] && rm -rf ee/ qa/spec/ee/ qa/qa/specs/features/ee/ qa/qa/ee/ qa/qa/ee.rb'
diff --git a/.gitlab/ci/static-analysis.gitlab-ci.yml b/.gitlab/ci/static-analysis.gitlab-ci.yml
new file mode 100644
index 00000000000..1394085b6e4
--- /dev/null
+++ b/.gitlab/ci/static-analysis.gitlab-ci.yml
@@ -0,0 +1,42 @@
+.static-analysis-base:
+ extends:
+ - .default-retry
+ - .default-before_script
+ - .static-analysis-cache
+ needs: []
+ variables:
+ SETUP_DB: "false"
+ ENABLE_SPRING: "1"
+ # Disable warnings in browserslist which can break on backports
+ # https://github.com/browserslist/browserslist/blob/a287ec6/node.js#L367-L384
+ BROWSERSLIST_IGNORE_OLD_DATA: "true"
+
+update-static-analysis-cache:
+ extends:
+ - .static-analysis-base
+ - .static-analysis-cache-push
+ - .shared:rules:update-cache
+ stage: prepare
+ script:
+ - run_timed_command "bundle exec rubocop --parallel" # For the moment we only cache `tmp/rubocop_cache` so we don't need to run all the tasks.
+
+static-analysis:
+ extends:
+ - .static-analysis-base
+ - .static-analysis:rules:ee-and-foss
+ stage: test
+ parallel: 4
+ script:
+ - run_timed_command "retry yarn install --frozen-lockfile"
+ - scripts/static-analysis
+ artifacts:
+ expire_in: 31d
+ when: always
+ paths:
+ - tmp/feature_flags/
+
+static-analysis as-if-foss:
+ extends:
+ - static-analysis
+ - .static-analysis:rules:as-if-foss
+ - .as-if-foss
diff --git a/.gitlab/ci/test-metadata.gitlab-ci.yml b/.gitlab/ci/test-metadata.gitlab-ci.yml
index 135bf8b6a8c..ac719977975 100644
--- a/.gitlab/ci/test-metadata.gitlab-ci.yml
+++ b/.gitlab/ci/test-metadata.gitlab-ci.yml
@@ -26,6 +26,7 @@ update-tests-metadata:
- .test-metadata:rules:update-tests-metadata
stage: post-test
dependencies:
+ - retrieve-tests-metadata
- setup-test-env
- rspec migration pg12
- rspec frontend_fixture
diff --git a/.gitlab/ci/workhorse.gitlab-ci.yml b/.gitlab/ci/workhorse.gitlab-ci.yml
index ba4523f3bf7..0da0a334699 100644
--- a/.gitlab/ci/workhorse.gitlab-ci.yml
+++ b/.gitlab/ci/workhorse.gitlab-ci.yml
@@ -23,10 +23,10 @@ workhorse:verify:
- apt-get update && apt-get -y install libimage-exiftool-perl
- make -C workhorse test
-workhorse:test using go 1.15:
- extends: .workhorse:test
- image: ${GITLAB_DEPENDENCY_PROXY}golang:1.15
-
workhorse:test using go 1.16:
extends: .workhorse:test
image: ${GITLAB_DEPENDENCY_PROXY}golang:1.16
+
+workhorse:test using go 1.17:
+ extends: .workhorse:test
+ image: ${GITLAB_DEPENDENCY_PROXY}golang:1.17
diff --git a/.gitlab/ci/yaml.gitlab-ci.yml b/.gitlab/ci/yaml.gitlab-ci.yml
index a0961866465..b25ad55e0ce 100644
--- a/.gitlab/ci/yaml.gitlab-ci.yml
+++ b/.gitlab/ci/yaml.gitlab-ci.yml
@@ -1,4 +1,4 @@
-# Yamllint of CI-related yaml and changelogs.
+# Yamllint of CI-related yaml.
# This uses rules from project root `.yamllint`.
lint-yaml:
extends:
@@ -8,6 +8,6 @@ lint-yaml:
stage: test
needs: []
variables:
- LINT_PATHS: .gitlab-ci.yml .gitlab/ci lib/gitlab/ci/templates changelogs
+ LINT_PATHS: .gitlab-ci.yml .gitlab/ci lib/gitlab/ci/templates
script:
- yamllint -f colored $LINT_PATHS
diff --git a/.gitlab/issue_templates/Actionable Insight.md b/.gitlab/issue_templates/Actionable Insight.md
index df519f81799..f4724d66a1b 100644
--- a/.gitlab/issue_templates/Actionable Insight.md
+++ b/.gitlab/issue_templates/Actionable Insight.md
@@ -1,4 +1,4 @@
-<!-- Actionable insights must recommend an action that needs to take place. An actionable insight both defines the insight and clearly calls out action or next step required to improve based on the result of the research observation or data. Actionable insights are tracked over time and will include follow-up. Learn more in the handbook here: https://about.gitlab.com/handbook/engineering/ux/ux-research-training/research-insights/#actionable-insights -->
+<!-- Actionable insights must recommend an action that needs to take place. An actionable insight both defines the insight and clearly calls out action or next step required to improve based on the result of the research observation or data. Actionable insights are tracked over time and will include follow-up. Please follow the tasks outlined in this issue for best results. Learn more in the handbook here: https://about.gitlab.com/handbook/engineering/ux/ux-research-training/research-insights/#actionable-insights -->
### Insight
<!-- Describe the insight itself: often the problem, finding, or observation. -->
@@ -17,12 +17,14 @@
- :footprints: [Follow-up issue or epic](Paste URL for follow-up issue or epic here)
### Tasks
+ <!--Fill out these tasks in order to consider an Actionable Insight complete. Actionable Insights are created as confidential by default, but can be made non-confidential if the insight does not include information about competitors from a Competitor Evaluation or any other confidential information. -->
- [ ] Assign this issue to the appropriate Product Manager, Product Designer, or UX Researcher.
- [ ] Add the appropriate `Group` (such as `~"group::source code"`) label to the issue. This helps identify and track actionable insights at the group level.
- [ ] Link this issue back to the original research issue in the GitLab UX Research project and the Dovetail project.
+- [ ] Adjust confidentiality of this issue if applicable
-
+/confidential
/label ~"Actionable Insight"
diff --git a/.gitlab/issue_templates/Experiment Rollout.md b/.gitlab/issue_templates/Experiment Rollout.md
new file mode 100644
index 00000000000..c5fdc739943
--- /dev/null
+++ b/.gitlab/issue_templates/Experiment Rollout.md
@@ -0,0 +1,109 @@
+<!-- Title suggestion: [Experiment Rollout] experiment-key - description of experiment -->
+
+## Summary
+
+This issue tracks the rollout and status of an experiment through to removal.
+
+1. Experiment key / feature flag name: `<experiment-key>`
+1. Epic or issue link: `<issue or epic link>`
+
+This is an experiment rollout issue
+using the scoped [experiment label](https://about.gitlab.com/handbook/engineering/development/growth/experimentation/#experiment-rollout-issue).
+As well as defining the experiment rollout and cleanup, this issue incorporates the relevant
+[`Feature Flag Roll Out`](https://gitlab.com/gitlab-org/gitlab/-/edit/master/.gitlab/issue_templates/Feature%20Flag%20Roll%20Out.md) steps.
+
+## Owners
+
+- Team: `group::TEAM_NAME`
+- Most appropriate slack channel to reach out to: `#g_TEAM_NAME`
+- Best individual to reach out to: NAME
+- Product manager (PM): NAME
+
+### Stakeholders
+
+<!--
+Are there any other stages or teams involved that need to be kept in the loop?
+
+- PM: Name
+- Group: `group::TEAM_NAME`
+- The Support Team
+- The Delivery Team
+-->
+
+## Expectations
+
+### What are we expecting to happen?
+
+<!-- Describe the expected outcome when rolling out this experiment. -->
+
+### What might happen if this goes wrong?
+
+<!-- Any MRs that need to be rolled back? Communication that needs to happen? What are some things you can think of that could go wrong - data loss or broken pages? -->
+
+### What can we monitor to detect problems with this?
+
+<!-- Which dashboards from https://dashboards.gitlab.net are most relevant? -->
+
+## Tracked data
+<!-- brief description or link to issue or Sisense dashboard -->
+
+Note: you can use the [CXL calculator](https://cxl.com/ab-test-calculator/) to determine if your experiment has reached significance. The calculator includes an estimate for how much longer an experiment must run for before reaching significance.
+
+## Rollout plan
+<!-- Add an overview and method for modifying the feature flag -->
+
+- Runtime in days, or until we expect to reach statistical significance: `30`
+- We will roll this out behind a feature flag and expose this to `<rollout-percentage>`% of actors to start then ramp it up from there.
+
+`/chatops run feature set <experiment-key> <rollout-percentage> --actors`
+
+### Status
+
+
+#### Preferred workflow
+
+The issue should be assigned to the Product manager (PM) or Engineer (Eng) as follows:
+
+1. PM determines and manages the status of the experiment (assign this issue to the PM)
+1. PM asks for initial rollout on production, or changes to the status (assign to an Eng)
+1. Eng changes the status using `chatops` (reassign to the PM)
+1. When concluded, PM updates the 'Roll Out Steps' and adds a milestone (assigns to an Eng)
+
+The current status and history can be viewed using the:
+
+- [API](https://gitlab.com/api/v4/experiments) (GitLab team members)
+- [Feature flag log](https://gitlab.com/gitlab-com/gl-infra/feature-flag-log/-/issues?scope=all&utf8=%E2%9C%93&state=all) (GitLab team members)
+- [Experiment rollout board](https://gitlab.com/groups/gitlab-org/-/boards/1352542)
+
+In this rollout issue, ensure the scoped `experiment::` label is kept accurate.
+
+### Experiment Results
+<!-- update when experiment in/validated, set the scoped `~experiment::` status accordingly -->
+
+## Roll Out Steps
+
+- [ ] Confirm that QA tests pass with the feature flag enabled (if you're unsure how, contact the relevant [stable counterpart in the Quality department](https://about.gitlab.com/handbook/engineering/quality/#individual-contributors))
+- [ ] Enable on staging (`/chatops run feature set <experiment-key> true --staging`)
+- [ ] Test on staging
+- [ ] Ensure that documentation has been updated
+- [ ] Enable on GitLab.com for individual groups/projects listed above and verify behaviour (`/chatops run feature set --project=gitlab-org/gitlab feature_name true`)
+- [ ] Coordinate a time to enable the flag with the SRE oncall and release managers
+ - In `#production` mention `@sre-oncall` and `@release-managers`. Once an SRE on call and Release Manager on call confirm, you can proceed with the rollout
+- [ ] Announce on the issue an estimated time this will be enabled on GitLab.com
+- [ ] Enable on GitLab.com by running chatops command in `#production` (`/chatops run feature set feature_name true`)
+- [ ] Cross post chatops Slack command to `#support_gitlab-com` ([more guidance when this is necessary in the dev docs](https://docs.gitlab.com/ee/development/feature_flags/controls.html#where-to-run-commands)) and in your team channel
+- [ ] Announce on the issue that the flag has been enabled
+- [ ] Remove experiment code and feature flag and add changelog entry - a separate [cleanup issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new?issuable_template=Experiment%20Successful%20Cleanup) might be required
+- [ ] After the flag removal is deployed, [clean up the feature flag](https://docs.gitlab.com/ee/development/feature_flags/controls.html#cleaning-up) by running chatops command in `#production` channel
+- [ ] Assign to the product manager to update the [knowledge base](https://about.gitlab.com/direction/growth/#growth-insights-knowledge-base) (if applicable)
+
+## Rollback Steps
+
+- [ ] This feature can be disabled by running the following Chatops command:
+
+```
+/chatops run feature set <experiment-key> false
+```
+
+/label ~"feature flag" ~"devops::growth" ~"growth experiment" ~"experiment-rollout" ~Engineering ~"workflow::scheduling" ~"experiment::pending"
+/milestone %"Next 1-3 releases"
diff --git a/.gitlab/issue_templates/Feature Flag Roll Out.md b/.gitlab/issue_templates/Feature Flag Roll Out.md
index ec6e5dfd7d4..1576f6e8f53 100644
--- a/.gitlab/issue_templates/Feature Flag Roll Out.md
+++ b/.gitlab/issue_templates/Feature Flag Roll Out.md
@@ -38,6 +38,8 @@ Are there any other stages or teams involved that need to be kept in the loop?
<!-- If applicable, any groups/projects that are happy to have this feature turned on early. Some organizations may wish to test big changes they are interested in with a small subset of users ahead of time for example. -->
- `gitlab-org/gitlab` project
+- `gitlab-org/gitlab-foss` project
+- `gitlab-com/www-gitlab-com` project
- `gitlab-org`/`gitlab-com` groups
- ...
@@ -79,19 +81,24 @@ Are there any other stages or teams involved that need to be kept in the loop?
- [ ] Ensure that documentation has been updated ([More info](https://docs.gitlab.com/ee/development/documentation/feature_flags.html#features-that-became-enabled-by-default)).
- [ ] Announce on [the feature issue](ISSUE LINK) an estimated time this will be enabled on GitLab.com.
- [ ] If the feature might impact the user experience, notify `#support_gitlab-com` and your team channel ([more guidance when this is necessary in the dev docs](https://docs.gitlab.com/ee/development/feature_flags/controls.html#communicate-the-change)).
-- [ ] If the feature flag in code has [an actor](https://docs.gitlab.com/ee/development/feature_flags/#feature-actors), enable it on GitLab.com for [testing groups/projects](#testing-groupsprojectsusers).
- - [ ] `/chatops run feature set --<actor-type>=<actor> <feature-flag-name> true`
-- [ ] Verify that the feature works as expected. Posting the QA result in this issue is preferable.
### Global rollout on production
+All `/chatops` commands that target production should be done in the `#production` slack channel for visibility.
+
+- [ ] Confirm the feature flag is enabled on `staging` without incident
+- [ ] Roll out the feature to targeted testing projects/groups first
+ - [ ] `/chatops run feature set --project=gitlab-org/gitlab <feature-flag-name> true`
+ - [ ] `/chatops run feature set --project=gitlab-org/gitlab-foss <feature-flag-name> true`
+ - [ ] `/chatops run feature set --project=gitlab-com/www-gitlab-com <feature-flag-name> true`
+
- [ ] [Incrementally roll out](https://docs.gitlab.com/ee/development/feature_flags/controls.html#process) the feature.
- If the feature flag in code has [an actor](https://docs.gitlab.com/ee/development/feature_flags/#feature-actors), perform **actor-based** rollout.
- [ ] `/chatops run feature set <feature-flag-name> <rollout-percentage> --actors`
- If the feature flag in code does **NOT** have [an actor](https://docs.gitlab.com/ee/development/feature_flags/#feature-actors), perform time-based rollout (**random** rollout).
- [ ] `/chatops run feature set <feature-flag-name> <rollout-percentage>`
- - Enable the feature globally on production environment.
- - [ ] `/chatops run feature set <feature-flag-name> true`
+- [ ] Verify the change has the desired outcome with the limited rollout before enabling the feature globally on production.
+- [ ] Enable the feature globally on production environment. `/chatops run feature set <feature-flag-name> true`
- [ ] Announce on [the feature issue](ISSUE LINK) that the feature has been globally enabled.
- [ ] Wait for [at least one day for the verification term](https://about.gitlab.com/handbook/product-development-flow/feature-flag-lifecycle/#including-a-feature-behind-feature-flag-in-the-final-release).
diff --git a/.gitlab/issue_templates/Feature proposal - detailed.md b/.gitlab/issue_templates/Feature proposal - detailed.md
index 9b72ed5a01c..9759bb7e2dc 100644
--- a/.gitlab/issue_templates/Feature proposal - detailed.md
+++ b/.gitlab/issue_templates/Feature proposal - detailed.md
@@ -91,7 +91,7 @@ See the test engineering planning process and reach out to your counterpart Soft
<!--
Define both the success metrics and acceptance criteria. Note that success metrics indicate the desired business outcomes, while acceptance criteria indicate when the solution is working correctly. If there is no way to measure success, link to an issue that will implement a way to measure this.
-Create tracking issue using the the Snowplow event tracking template. See https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/issue_templates/Snowplow%20event%20tracking.md
+Create tracking issue using the Snowplow event tracking template. See https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/issue_templates/Snowplow%20event%20tracking.md
-->
### What is the type of buyer?
diff --git a/.gitlab/issue_templates/Geo Replicate a new Git repository type.md b/.gitlab/issue_templates/Geo Replicate a new Git repository type.md
index 73233644d37..476ee14a632 100644
--- a/.gitlab/issue_templates/Geo Replicate a new Git repository type.md
+++ b/.gitlab/issue_templates/Geo Replicate a new Git repository type.md
@@ -826,5 +826,7 @@ Individual Cool Widget replication and verification data should now be available
feature_flag: :geo_cool_widget_replication # REMOVE THIS LINE
```
+- [ ] Run `bundle exec rake gitlab:graphql:compile_docs` after the step above to regenerate the GraphQL docs.
+
- [ ] Add a row for Cool Widgets to the `Data types` table in [Geo data types support](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/administration/geo/replication/datatypes.md#data-types)
- [ ] Add a row for Cool Widgets to the `Limitations on replication/verification` table in [Geo data types support](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/administration/geo/replication/datatypes.md#limitations-on-replicationverification). If the row already exists, then update it to show that Replication and Verification is released in the current version.
diff --git a/.gitlab/issue_templates/Geo Replicate a new blob type.md b/.gitlab/issue_templates/Geo Replicate a new blob type.md
index cc5a606d68b..aef983f6495 100644
--- a/.gitlab/issue_templates/Geo Replicate a new blob type.md
+++ b/.gitlab/issue_templates/Geo Replicate a new blob type.md
@@ -794,5 +794,7 @@ Individual Cool Widget replication and verification data should now be available
feature_flag: :geo_cool_widget_replication # REMOVE THIS LINE
```
+- [ ] Run `bundle exec rake gitlab:graphql:compile_docs` after the step above to regenerate the GraphQL docs.
+
- [ ] Add a row for Cool Widgets to the `Data types` table in [Geo data types support](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/administration/geo/replication/datatypes.md#data-types)
- [ ] Add a row for Cool Widgets to the `Limitations on replication/verification` table in [Geo data types support](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/administration/geo/replication/datatypes.md#limitations-on-replicationverification). If the row already exists, then update it to show that Replication and Verification is released in the current version.
diff --git a/.gitlab/issue_templates/InfraDev.md b/.gitlab/issue_templates/InfraDev.md
new file mode 100644
index 00000000000..bc0e65c3c22
--- /dev/null
+++ b/.gitlab/issue_templates/InfraDev.md
@@ -0,0 +1,56 @@
+<!--
+Triage of infradev Issues is desired to occur asynchronously.
+For maximum efficiency, please ensure the following, so that your infradev issues can gain maximum traction.
+
+https://about.gitlab.com/handbook/engineering/workflow/#a-guide-to-creating-effective-infradev-issues
+-->
+
+## Summary
+<!--
+Clearly state the scope of the problem, and how it affects GitLab.com
+-->
+
+
+## Impact
+<!--
+- Quantify the effect of the problem to help ensure that correct prioritization occurs.
+- Include costs to availability. The Incident Budget Explorer dashboard can help here.
+- Include the number of times alerts have fired owing to the problem, how much time was spent dealing with the problem, and how many people were involved.
+- Link to affected incidents, and cross-reference them as related issues.
+- Include screenshots of visualization from Grafana or Kibana.
+- Always include a permalink to the source of the screenshot so that others can investigate further.
+-->
+
+
+## Recommendation
+<!--
+Provide a clear, unambiguous, self-contained solution to the problem.
+-->
+
+
+## Verification
+<!--
+Provide a method for validating that the original issue still exists.
+
+Having a way of checking validity can save on a great deal of back-and-forth discussion between Infradev Triage participants including Engineering Managers, Directors and Product Managers and make space for other non-resolved issues to get scheduled sooner.
+
+Ideally, provide a link to a Thanos query or an ELK query and clear instructions on how to interpret the results to determine whether the problem is still occurring.
+-->
+
+
+<!--
+Workflow and other relevant labels
+
+/label ~"severity::"
+/label ~"priority::"
+/label ~"group::"
+/label ~"devops::"
+
+See also:
+- https://about.gitlab.com/handbook/engineering/quality/issue-triage/#availability
+- https://about.gitlab.com/handbook/product/categories/
+- https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/stages.yml
+-->
+
+/label ~"infradev"
+/label ~"bug"
diff --git a/.gitlab/issue_templates/Navigation - Left Sidebar Proposals.md b/.gitlab/issue_templates/Navigation - Left Sidebar Proposals.md
new file mode 100644
index 00000000000..57d6d12267c
--- /dev/null
+++ b/.gitlab/issue_templates/Navigation - Left Sidebar Proposals.md
@@ -0,0 +1,15 @@
+<!-- This template is used for proposing changes to the left sidebar contextual navigation. This could include additions, removals, or general changes to overall hierarchy.-->
+
+### Proposal
+
+<!-- Use this section to explain the proposed changes, including details around usage and business drivers. -->
+
+### Checklist
+
+- [ ] If your proposal includes changes to the top-level menu items within the left sidebar, engage the [Foundations Product Design Manager](https://about.gitlab.com/handbook/product/categories/#foundations-group) for approval. The Foundations DRI will work with UX partners in product design, research, and technical writing, as applicable.
+- [ ] Follow the [product development workflow](https://about.gitlab.com/handbook/product-development-flow/#validation-phase-2-problem-validation) validation process to ensure you are solving a well understood problem and that the proposed change is understandable and non-disruptive to users. Navigation-specific research is strongly encouraged.
+- [ ] Engage the [Editor](https://about.gitlab.com/handbook/engineering/development/dev/create-editor/) team to ensure your proposal is in alignment with holistic changes happening to the left side bar.
+- [ ] Consider whether you need to communicate the change somehow, or if you will have an interim period in the UI where your nav item will live in more than one place.
+- [ ] Once implemented, update this [navigation map in Mural](https://app.mural.co/t/gitlab2474/m/gitlab2474/1589571490215/261462d0beb3043979374623710d3f2d6cfec1cb) with your navigation change.
+
+/label ~UX ~"UI text" ~"documentation" ~"documentation" ~"Category:Navigation & Settings" ~"Category:Foundations" ~navigation
diff --git a/.gitlab/issue_templates/Security developer workflow.md b/.gitlab/issue_templates/Security developer workflow.md
index 51e8ec378b2..7f2c54f4f49 100644
--- a/.gitlab/issue_templates/Security developer workflow.md
+++ b/.gitlab/issue_templates/Security developer workflow.md
@@ -29,6 +29,7 @@ After your merge request has been approved according to our [approval guidelines
## Backports
- [ ] Once the MR is ready to be merged, create MRs targeting the latest 3 stable branches
+ * The 3 stable branches correspond to the versions in the title of the Security Release Tracking Issue.
* At this point, it might be easy to squash the commits from the MR into one
* You can use the script `bin/secpick` instead of the following steps, to help you cherry-picking. See the [secpick documentation]
- [ ] Create each MR targeting the stable branch `X-Y-stable`, using the [Security Release merge request template].
diff --git a/.gitlab/issue_templates/Technical Evaluation.md b/.gitlab/issue_templates/Technical Evaluation.md
index 533a1343820..cf939725a78 100644
--- a/.gitlab/issue_templates/Technical Evaluation.md
+++ b/.gitlab/issue_templates/Technical Evaluation.md
@@ -5,6 +5,13 @@
<!-- Describe the related issue and challenge we need to establish a proof of concept for-->
* [Link to other Issue](link)
+### Tasks prior to evaluation
+
+<!-- Pre-evaluation tasks are critical and should be completed or confirmed by product managers if available -->
+
+- [ ] Clearly document the topic to evaluated in this issue description
+- [ ] Determine specific scope including time-bounds for investigation
+
### Tasks to Evaluate
<!-- Outline the tasks with issues that you need to evaluate as a part of the implementation issue -->
diff --git a/.gitlab/issue_templates/experiment_tracking_template.md b/.gitlab/issue_templates/experiment_tracking_template.md
deleted file mode 100644
index c653a3a2d40..00000000000
--- a/.gitlab/issue_templates/experiment_tracking_template.md
+++ /dev/null
@@ -1,95 +0,0 @@
-<!-- Title suggestion: [Experiment Tracking] experiment-key - description of experiment -->
-
-## What
-
-Track the status of an experiment through to removal.
-
-1. Experiment key: `<experiment-key>`
-1. Framework: `experimentation.rb` | `gitlab_experiment`
-1. Feature flag name: <experiment-key>_experiment_percentage` | `<experiment-key>`
-
-This is an experiment tracking issue for: `<issue or epic link>`
-using the scoped [experiment label](https://about.gitlab.com/handbook/engineering/development/growth/#experiment-tracking-issue).
-
-As well as defining the experiment rollout and cleanup, this issue incorporates the relevant
-[`Feature Flag Roll Out`](https://gitlab.com/gitlab-org/gitlab/-/edit/master/.gitlab/issue_templates/Feature%20Flag%20Roll%20Out.md) steps.
-
-## Owners
-
-- Team: `group::TEAM_NAME`
-- Most appropriate slack channel to reach out to: `#g_TEAM_NAME`
-- Best individual to reach out to: NAME
-
-## Expectations
-
-### What are we expecting to happen?
-
-### What might happen if this goes wrong?
-
-### What can we monitor to detect problems with this?
-<!-- Which dashboards from https://dashboards.gitlab.net are most relevant? Sentry errors reports can also be useful to review -->
-
-### Tracked data
-<!-- brief description or link to issue or Sisense dashboard -->
-
- Note: you can utilize [CXL calculator](https://cxl.com/ab-test-calculator/) to determine if your experiment has reached signifigance, it also includes an estimate for how much longer an experiment will need to run for before reaching signifigance.
-
-### Staging Test
-<!-- For experiments using `experimentation.rb`: To force this experiment on staging use `?force_experiment=<experiment-key>` -->
-<!-- list any steps required to setup this experiment, and link to a separate Staging environment test issue is applicable -->
-
-<!-- uncomment if testing with specific groups/projects on GitLab.com
-## Beta groups/projects
-
-If applicable, any groups/projects that are happy to have this feature turned on early. Some organizations may wish to test big changes they are interested in with a small subset of users ahead of time for example.
-
-- `gitlab-org/gitlab` project
-- `gitlab-org`/`gitlab-com` groups
-- ...
--->
-
-### Experiment tracking log
-<!-- Add an overview and method for modifying the feature flag
-
-* Runtime: 30 days or until we reach statistical significance
-* We will roll this out behind a feature flag and expose this to 20% of users to start then ramp it up from there.
-* feature flag based on experiment key `<experiment-key>` (see `experimentation.rb` in GitLab, append '_experiment_percentage')
-
-`/chatops run feature set <experiment-key>_experiment_percentage <INITIAL_PERCENTAGE>`
--->
-<!-- Add bullet points to track changes to the rollout of this experiment (feature flag changes)
-
-* YYYY-MM-DD UTC - initial rollout to 20% of users
-* TBD - review - increase to 50% of users
--->
-
-### Experiment Results
-<!-- update when experiment in/validated, set the scoped `~experiment::` status accordingly -->
-
-## Roll Out Steps
-
-- [ ] Confirm that QA tests pass with the feature flag enabled (if you're unsure how, contact the relevant [stable counterpart in the Quality department](https://about.gitlab.com/handbook/engineering/quality/#individual-contributors))
-- [ ] Enable on staging (`/chatops run feature set feature_name true --staging`)
-- [ ] Test on staging
-- [ ] Ensure that documentation has been updated
-- [ ] Enable on GitLab.com for individual groups/projects listed above and verify behaviour (`/chatops run feature set --project=gitlab-org/gitlab feature_name true`)
-- [ ] Coordinate a time to enable the flag with the SRE oncall and release managers
- - In `#production` mention `@sre-oncall` and `@release-managers`. Once an SRE on call and Release Manager on call confirm, you can proceed with the rollout
-- [ ] Announce on the issue an estimated time this will be enabled on GitLab.com
-- [ ] Enable on GitLab.com by running chatops command in `#production` (`/chatops run feature set feature_name true`)
-- [ ] Cross post chatops Slack command to `#support_gitlab-com` ([more guidance when this is necessary in the dev docs](https://docs.gitlab.com/ee/development/feature_flags/controls.html#where-to-run-commands)) and in your team channel
-- [ ] Announce on the issue that the flag has been enabled
-- [ ] Remove experiment code and feature flag and add changelog entry - a separate [cleanup issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new?issuable_template=Experiment%20Successful%20Cleanup) might be required
-- [ ] After the flag removal is deployed, [clean up the feature flag](https://docs.gitlab.com/ee/development/feature_flags/controls.html#cleaning-up) by running chatops command in `#production` channel
-- [ ] Assign to the product manager to update the [knowledge base](https://about.gitlab.com/direction/growth/#growth-insights-knowledge-base) (if applicable)
-
-## Rollback Steps
-
-- [ ] This feature can be disabled by running the following Chatops command:
-
-```
-/chatops run feature set feature_name false
-```
-
-/label ~"feature flag" ~"devops::growth" ~"growth experiment" ~"experiment tracking" ~Engineering ~"workflow::scheduling" ~"experiment::pending"
-
diff --git a/.gitlab/merge_request_templates/Documentation.md b/.gitlab/merge_request_templates/Documentation.md
index e97ae9a0c43..66c1eff412b 100644
--- a/.gitlab/merge_request_templates/Documentation.md
+++ b/.gitlab/merge_request_templates/Documentation.md
@@ -1,13 +1,3 @@
-<!--
- Follow the documentation workflow https://docs.gitlab.com/ee/development/documentation/workflow.html
- Additional information is located at https://docs.gitlab.com/ee/development/documentation/
- To find the designated Tech Writer for the stage/group, see
- https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
-
- Mention "documentation" or "docs" in the MR title
- For changing documentation location use the Change Documentation Location.md template
--->
-
## What does this MR do?
<!-- Briefly describe what this MR is about. -->
@@ -18,11 +8,13 @@
## Author's checklist
+- [ ] Consider taking [the GitLab Technical Writing Fundamentals course](https://gitlab.edcast.com/pathways/ECL-02528ee2-c334-4e16-abf3-e9d8b8260de4)
- [ ] Follow the:
- - [Documentation Guidelines](https://docs.gitlab.com/ee/development/documentation/).
+ - [Documentation process](https://docs.gitlab.com/ee/development/documentation/workflow.html).
+ - [Documentation guidelines](https://docs.gitlab.com/ee/development/documentation/).
- [Style Guide](https://docs.gitlab.com/ee/development/documentation/styleguide/).
- [ ] Ensure that the [product tier badge](https://docs.gitlab.com/ee/development/documentation/styleguide/index.html#product-tier-badges) is added to topic's `h1`.
-- [ ] [Request a review](https://docs.gitlab.com/ee/development/code_review.html#dogfooding-the-reviewers-feature) based on the:
+- [ ] [Request a review](https://docs.gitlab.com/ee/development/code_review.html#dogfooding-the-reviewers-feature) based on:
- The documentation page's [metadata](https://docs.gitlab.com/ee/development/documentation/#metadata).
- The [associated Technical Writer](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments).
diff --git a/.gitlab/merge_request_templates/Quarantine End to End Test.md b/.gitlab/merge_request_templates/Quarantine End to End Test.md
index 772167af3e9..4edfd2a8c8e 100644
--- a/.gitlab/merge_request_templates/Quarantine End to End Test.md
+++ b/.gitlab/merge_request_templates/Quarantine End to End Test.md
@@ -22,6 +22,7 @@ the noise (due to constantly failing tests, flaky tests, and so on) so that new
- [ ] Follow the [Quarantining Tests guide](https://about.gitlab.com/handbook/engineering/quality/guidelines/debugging-qa-test-failures/#quarantining-tests).
- [ ] Confirm the test has a [`quarantine:` tag with the specified quarantine type](https://about.gitlab.com/handbook/engineering/quality/guidelines/debugging-qa-test-failures/#quarantined-test-types).
- [ ] Note if the test should be [quarantined for a specific environment](https://docs.gitlab.com/ee/development/testing_guide/end_to_end/execution_context_selection.html#quarantine-a-test-for-a-specific-environment).
+ - [ ] (Optionally) In case of an emergency (e.g. blocked deployments), consider adding labels to pick into auto-deploy (~"Pick into auto-deploy" ~"priority::1" ~"severity::1").
- [ ] Dequarantine test check-list
- [ ] Follow the [Dequarantining Tests guide](https://about.gitlab.com/handbook/engineering/quality/guidelines/debugging-qa-test-failures/#dequarantining-tests).
- [ ] Confirm the test consistently passes on the target GitLab environment(s).
@@ -31,9 +32,6 @@ the noise (due to constantly failing tests, flaky tests, and so on) so that new
<!-- Base labels. -->
/label ~"Quality" ~"QA" ~"feature" ~"feature::maintenance"
-<!-- Labels to pick into auto-deploy. -->
-/label ~"Pick into auto-deploy" ~"priority::1" ~"severity::1"
-
<!--
Choose the stage that appears in the test path, e.g. ~"devops::create" for
`qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb`.
diff --git a/.gitlab/merge_request_templates/Security Release.md b/.gitlab/merge_request_templates/Security Release.md
index 33c0a5b98a8..7684546b91c 100644
--- a/.gitlab/merge_request_templates/Security Release.md
+++ b/.gitlab/merge_request_templates/Security Release.md
@@ -14,7 +14,6 @@ See [the general developer security release guidelines](https://gitlab.com/gitla
- [ ] **On "Related issues" section, write down the [GitLab Security] issue it belongs to (i.e. `Related to <issue_id>`).**
- [ ] Merge request targets `master`, or a versioned stable branch (`X-Y-stable-ee`).
-- [ ] Milestone is set for the version this merge request applies to. A closed milestone can be assigned via [quick actions].
- [ ] Title of this merge request is the same as for all backports.
- [ ] A [CHANGELOG entry] has been included, with `Changelog` trailer set to `security`.
- [ ] For the MR targeting `master`:
@@ -24,6 +23,7 @@ See [the general developer security release guidelines](https://gitlab.com/gitla
- Please see the security release [Code reviews and Approvals](https://gitlab.com/gitlab-org/release/docs/blob/master/general/security/developer.md#code-reviews-and-approvals) documentation for details on which AppSec team member to ping for approval.
- Trigger the [`package-and-qa` build]. The docker image generated will be used by the AppSec engineer to validate the security vulnerability has been remediated.
- [ ] For a backport MR targeting a versioned stable branch (`X-Y-stable-ee`)
+ - [ ] Milestone is set to the version this backport applies to. A closed milestone can be assigned via [quick actions].
- [ ] Ensure it's approved by a maintainer.
**Note:** Reviewer/maintainer should not be a Release Manager
diff --git a/.gitpod.yml b/.gitpod.yml
index 6b77ee18e1e..e9cc798ed19 100644
--- a/.gitpod.yml
+++ b/.gitpod.yml
@@ -16,6 +16,10 @@ tasks:
# GitLab
[[ -d /workspace/gitlab ]] && ln -fs /workspace/gitlab /workspace/gitlab-development-kit/gitlab
mv /workspace/gitlab-development-kit/secrets.yml /workspace/gitlab-development-kit/gitlab/config
+ # update gdk.yml
+ gdk config set gitlab.rails.hostname $(gp url 3000 | sed -e 's+^http[s]*://++')
+ gdk config set gitlab.rails.port 443
+ gdk config set gitlab.rails.https.enabled true
# reconfigure GDK
echo "$(date) – Reconfiguring GDK" | tee -a /workspace/startup.log
gdk reconfigure
diff --git a/.rubocop.yml b/.rubocop.yml
index 7b2b8ca70f5..141ba874b21 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -38,8 +38,9 @@ AllCops:
- 'workhorse/**/*'
- 'spec/support/*.git/**/*' # e.g. spec/support/gitlab-git-test.git
- 'db/ci_migrate/*.rb' # since the `db/ci_migrate` is a symlinked to `db/migrate`
- CacheRootDirectory: tmp
- MaxFilesInCache: 25000
+ # Use absolute path to avoid orphan directories with changed workspace root.
+ CacheRootDirectory: <%= Dir.getwd %>/tmp
+ MaxFilesInCache: 30000
Cop/AvoidKeywordArgumentsInSidekiqWorkers:
Enabled: true
@@ -711,3 +712,13 @@ QA/SelectorUsage:
- 'ee/spec/**/*.rb'
Exclude:
- 'spec/rubocop/**/*_spec.rb'
+
+Performance/ActiveRecordSubtransactions:
+ Exclude:
+ - 'spec/**/*.rb'
+ - 'ee/spec/**/*.rb'
+
+Performance/ActiveRecordSubtransactionMethods:
+ Exclude:
+ - 'spec/**/*.rb'
+ - 'ee/spec/**/*.rb'
diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml
index 647d5e4c5ac..2cbfeec1048 100644
--- a/.rubocop_manual_todo.yml
+++ b/.rubocop_manual_todo.yml
@@ -10,191 +10,6 @@
# - guidelines for use found in
# https://docs.gitlab.com/ee/development/contributing/style_guides.html#resolving-rubocop-exceptions.
-# WIP See https://gitlab.com/gitlab-org/gitlab/-/issues/337596
-Graphql/Descriptions:
- Exclude:
- - 'ee/app/graphql/types/iteration_state_enum.rb'
- - 'ee/app/graphql/types/requirements_management/requirement_state_enum.rb'
- - 'ee/app/graphql/types/requirements_management/test_report_state_enum.rb'
- - 'ee/app/graphql/types/security_scanner_type_enum.rb'
- - 'ee/app/graphql/types/vulnerability/issue_link_type_enum.rb'
- - 'ee/app/graphql/types/vulnerability_grade_enum.rb'
- - 'ee/app/graphql/types/vulnerability_report_type_enum.rb'
- - 'ee/app/graphql/types/vulnerability_severity_enum.rb'
- - 'ee/app/graphql/types/vulnerability_state_enum.rb'
- - 'ee/app/graphql/types/vulnerability_confidence_enum.rb'
- - 'app/graphql/resolvers/labels_resolver.rb'
- - 'app/graphql/resolvers/merge_requests_resolver.rb'
- - 'app/graphql/resolvers/milestones_resolver.rb'
- - 'app/graphql/resolvers/package_details_resolver.rb'
- - 'app/graphql/resolvers/paginated_tree_resolver.rb'
- - 'app/graphql/resolvers/release_resolver.rb'
- - 'app/graphql/resolvers/repository_branch_names_resolver.rb'
- - 'app/graphql/resolvers/snippets_resolver.rb'
- - 'app/graphql/resolvers/todo_resolver.rb'
- - 'app/graphql/resolvers/tree_resolver.rb'
- - 'app/graphql/resolvers/users/snippets_resolver.rb'
- - 'app/graphql/types/admin/analytics/usage_trends/measurement_type.rb'
- - 'app/graphql/types/admin/sidekiq_queues/delete_jobs_response_type.rb'
- - 'app/graphql/types/alert_management/alert_type.rb'
- - 'app/graphql/types/award_emojis/award_emoji_type.rb'
- - 'app/graphql/types/ci/config/job_restriction_type.rb'
- - 'app/graphql/types/ci/config/status_enum.rb'
- - 'app/graphql/types/ci/pipeline_type.rb'
- - 'app/graphql/types/ci_configuration/sast/ui_component_size_enum.rb'
- - 'app/graphql/types/commit_action_type.rb'
- - 'app/graphql/types/container_repository_cleanup_status_enum.rb'
- - 'app/graphql/types/container_repository_tag_type.rb'
- - 'app/graphql/types/container_repository_type.rb'
- - 'app/graphql/types/custom_emoji_type.rb'
- - 'app/graphql/types/design_management/design_at_version_type.rb'
- - 'app/graphql/types/design_management/design_fields.rb'
- - 'app/graphql/types/diff_paths_input_type.rb'
- - 'app/graphql/types/environment_type.rb'
- - 'app/graphql/types/eventable_type.rb'
- - 'app/graphql/types/group_type.rb'
- - 'app/graphql/types/merge_request_type.rb'
- - 'app/graphql/types/metadata/kas_type.rb'
- - 'app/graphql/types/milestone_wildcard_id_enum.rb'
- - 'app/graphql/types/namespace_type.rb'
- - 'app/graphql/types/notes/note_type.rb'
- - 'app/graphql/types/notes/position_type_enum.rb'
- - 'app/graphql/types/packages/composer/json_type.rb'
- - 'app/graphql/types/packages/package_details_type.rb'
- - 'app/graphql/types/packages/package_file_type.rb'
- - 'app/graphql/types/packages/package_tag_type.rb'
- - 'app/graphql/types/packages/package_type.rb'
- - 'app/graphql/types/project_type.rb'
- - 'app/graphql/types/prometheus_alert_type.rb'
- - 'app/graphql/types/query_type.rb'
- - 'app/graphql/types/range_input_type.rb'
- - 'app/graphql/types/release_asset_link_shared_input_arguments.rb'
- - 'app/graphql/types/release_assets_input_type.rb'
- - 'app/graphql/types/release_type.rb'
- - 'app/graphql/types/repository/blob_type.rb'
- - 'app/graphql/types/root_storage_statistics_type.rb'
- - 'app/graphql/types/snippet_type.rb'
- - 'app/graphql/types/snippets/blob_type.rb'
- - 'app/graphql/types/snippets/visibility_scopes_enum.rb'
- - 'app/graphql/types/terraform/state_type.rb'
- - 'app/graphql/types/terraform/state_version_type.rb'
- - 'app/graphql/types/timelog_type.rb'
- - 'app/graphql/types/todo_state_enum.rb'
- - 'app/graphql/types/todo_target_enum.rb'
- - 'app/graphql/types/todo_type.rb'
- - 'app/graphql/types/user_interface.rb'
- - 'app/graphql/types/user_merge_request_interaction_type.rb'
- - 'app/graphql/types/user_state_enum.rb'
- - 'ee/app/graphql/ee/mutations/alert_management/http_integration/create.rb'
- - 'ee/app/graphql/ee/mutations/alert_management/http_integration/update.rb'
- - 'ee/app/graphql/ee/mutations/boards/issues/issue_move_list.rb'
- - 'ee/app/graphql/ee/mutations/issues/create.rb'
- - 'ee/app/graphql/ee/mutations/issues/update.rb'
- - 'ee/app/graphql/ee/types/alert_management/http_integration_type.rb'
- - 'ee/app/graphql/ee/types/board_list_type.rb'
- - 'ee/app/graphql/ee/types/board_type.rb'
- - 'ee/app/graphql/ee/types/group_type.rb'
- - 'ee/app/graphql/ee/types/project_type.rb'
- - 'ee/app/graphql/ee/types/query_type.rb'
- - 'ee/app/graphql/mutations/app_sec/fuzzing/api/ci_configuration/create.rb'
- - 'ee/app/graphql/mutations/boards/epic_boards/create.rb'
- - 'ee/app/graphql/mutations/boards/epic_boards/epic_move_list.rb'
- - 'ee/app/graphql/mutations/boards/epic_boards/update.rb'
- - 'ee/app/graphql/mutations/boards/epic_lists/destroy.rb'
- - 'ee/app/graphql/mutations/boards/lists/update_limit_metrics.rb'
- - 'ee/app/graphql/mutations/boards/update_epic_user_preferences.rb'
- - 'ee/app/graphql/mutations/compliance_management/frameworks/create.rb'
- - 'ee/app/graphql/mutations/compliance_management/frameworks/destroy.rb'
- - 'ee/app/graphql/mutations/compliance_management/frameworks/update.rb'
- - 'ee/app/graphql/mutations/concerns/mutations/shared_epic_arguments.rb'
- - 'ee/app/graphql/mutations/dast/profiles/create.rb'
- - 'ee/app/graphql/mutations/dast/profiles/update.rb'
- - 'ee/app/graphql/mutations/dast_on_demand_scans/create.rb'
- - 'ee/app/graphql/mutations/dast_scanner_profiles/create.rb'
- - 'ee/app/graphql/mutations/dast_scanner_profiles/update.rb'
- - 'ee/app/graphql/mutations/dast_site_profiles/create.rb'
- - 'ee/app/graphql/mutations/dast_site_profiles/delete.rb'
- - 'ee/app/graphql/mutations/dast_site_profiles/update.rb'
- - 'ee/app/graphql/mutations/dast_site_tokens/create.rb'
- - 'ee/app/graphql/mutations/dast_site_validations/create.rb'
- - 'ee/app/graphql/mutations/dast_site_validations/revoke.rb'
- - 'ee/app/graphql/mutations/epic_tree/reorder.rb'
- - 'ee/app/graphql/mutations/epics/add_issue.rb'
- - 'ee/app/graphql/mutations/epics/base.rb'
- - 'ee/app/graphql/mutations/epics/create.rb'
- - 'ee/app/graphql/mutations/epics/set_subscription.rb'
- - 'ee/app/graphql/mutations/gitlab_subscriptions/activate.rb'
- - 'ee/app/graphql/mutations/incident_management/escalation_policy/base.rb'
- - 'ee/app/graphql/mutations/incident_management/escalation_policy/create.rb'
- - 'ee/app/graphql/mutations/incident_management/escalation_policy/destroy.rb'
- - 'ee/app/graphql/mutations/incident_management/escalation_policy/update.rb'
- - 'ee/app/graphql/mutations/incident_management/oncall_rotation/base.rb'
- - 'ee/app/graphql/mutations/incident_management/oncall_rotation/create.rb'
- - 'ee/app/graphql/mutations/incident_management/oncall_rotation/destroy.rb'
- - 'ee/app/graphql/mutations/incident_management/oncall_rotation/update.rb'
- - 'ee/app/graphql/mutations/incident_management/oncall_schedule/create.rb'
- - 'ee/app/graphql/mutations/incident_management/oncall_schedule/destroy.rb'
- - 'ee/app/graphql/mutations/incident_management/oncall_schedule/oncall_schedule_base.rb'
- - 'ee/app/graphql/mutations/incident_management/oncall_schedule/update.rb'
- - 'ee/app/graphql/mutations/issues/common_ee_mutation_arguments.rb'
- - 'ee/app/graphql/mutations/issues/promote_to_epic.rb'
- - 'ee/app/graphql/mutations/issues/set_iteration.rb'
- - 'ee/app/graphql/mutations/iterations/cadences/create.rb'
- - 'ee/app/graphql/mutations/iterations/cadences/update.rb'
- - 'ee/app/graphql/mutations/iterations/create.rb'
- - 'ee/app/graphql/mutations/namespaces/base.rb'
- - 'ee/app/graphql/mutations/quality_management/test_cases/create.rb'
- - 'ee/app/graphql/mutations/requirements_management/update_requirement.rb'
- - 'ee/app/graphql/mutations/vulnerabilities/confirm.rb'
- - 'ee/app/graphql/mutations/vulnerabilities/create_external_issue_link.rb'
- - 'ee/app/graphql/mutations/vulnerabilities/destroy_external_issue_link.rb'
- - 'ee/app/graphql/mutations/vulnerabilities/dismiss.rb'
- - 'ee/app/graphql/mutations/vulnerabilities/resolve.rb'
- - 'ee/app/graphql/mutations/vulnerabilities/revert_to_detected.rb'
- - 'ee/app/graphql/resolvers/dora_metrics_resolver.rb'
- - 'ee/app/graphql/resolvers/geo/geo_node_resolver.rb'
- - 'ee/app/graphql/resolvers/network_policy_resolver.rb'
- - 'ee/app/graphql/resolvers/requirements_management/requirements_resolver.rb'
- - 'ee/app/graphql/types/alert_management/payload_alert_field_input_type.rb'
- - 'ee/app/graphql/types/alert_management/payload_alert_mapping_field_type.rb'
- - 'ee/app/graphql/types/analytics/devops_adoption/snapshot_type.rb'
- - 'ee/app/graphql/types/app_sec/fuzzing/api/scan_profile_type.rb'
- - 'ee/app/graphql/types/ci/code_quality_degradation_type.rb'
- - 'ee/app/graphql/types/ci/minutes/namespace_monthly_usage_type.rb'
- - 'ee/app/graphql/types/ci/minutes/project_monthly_usage_type.rb'
- - 'ee/app/graphql/types/clusters/agent_token_type.rb'
- - 'ee/app/graphql/types/clusters/agent_type.rb'
- - 'ee/app/graphql/types/dast/profile_branch_type.rb'
- - 'ee/app/graphql/types/dast/profile_type.rb'
- - 'ee/app/graphql/types/dast/site_profile_auth_input_type.rb'
- - 'ee/app/graphql/types/dast/site_profile_auth_type.rb'
- - 'ee/app/graphql/types/dast_scanner_profile_type.rb'
- - 'ee/app/graphql/types/dast_site_profile_type.rb'
- - 'ee/app/graphql/types/epic_tree/epic_tree_node_input_type.rb'
- - 'ee/app/graphql/types/epic_type.rb'
- - 'ee/app/graphql/types/geo/geo_node_type.rb'
- - 'ee/app/graphql/types/incident_management/escalation_policy_type.rb'
- - 'ee/app/graphql/types/incident_management/escalation_rule_input_type.rb'
- - 'ee/app/graphql/types/incident_management/escalation_rule_type.rb'
- - 'ee/app/graphql/types/incident_management/oncall_participant_type.rb'
- - 'ee/app/graphql/types/incident_management/oncall_rotation_active_period_input_type.rb'
- - 'ee/app/graphql/types/incident_management/oncall_rotation_active_period_type.rb'
- - 'ee/app/graphql/types/incident_management/oncall_rotation_date_input_type.rb'
- - 'ee/app/graphql/types/incident_management/oncall_rotation_length_input_type.rb'
- - 'ee/app/graphql/types/incident_management/oncall_user_input_type.rb'
- - 'ee/app/graphql/types/move_type_enum.rb'
- - 'ee/app/graphql/types/network_policy_kind_enum.rb'
- - 'ee/app/graphql/types/path_lock_type.rb'
- - 'ee/app/graphql/types/pipeline_security_report_finding_type.rb'
- - 'ee/app/graphql/types/scanned_resource_type.rb'
- - 'ee/app/graphql/types/security_report_summary_section_type.rb'
- - 'ee/app/graphql/types/timebox_metrics_type.rb'
- - 'ee/app/graphql/types/vulnerability/issue_link_type.rb'
- - 'ee/app/graphql/types/vulnerability_details/commit_type.rb'
- - 'ee/app/graphql/types/vulnerability_type.rb'
- - 'ee/app/graphql/types/vulnerable_dependency_type.rb'
- - 'ee/app/graphql/types/vulnerable_package_type.rb'
-
# WIP: See https://gitlab.com/gitlab-org/gitlab/-/issues/220040
Rails/SaveBang:
Exclude:
@@ -939,7 +754,6 @@ RSpec/AnyInstanceOf:
- 'spec/requests/api/ci/runner/runners_verify_post_spec.rb'
- 'spec/requests/api/graphql/gitlab_schema_spec.rb'
- 'spec/requests/api/graphql/project/error_tracking/sentry_detailed_error_request_spec.rb'
- - 'spec/requests/api/graphql/project/error_tracking/sentry_errors_request_spec.rb'
- 'spec/requests/api/graphql_spec.rb'
- 'spec/requests/api/helpers_spec.rb'
- 'spec/requests/api/internal/base_spec.rb'
@@ -2137,6 +1951,7 @@ Gitlab/NamespacedClass:
- 'ee/app/models/weight_note.rb'
- 'ee/app/policies/approval_merge_request_rule_policy.rb'
- 'ee/app/policies/approval_project_rule_policy.rb'
+ - 'ee/app/policies/approval_state_policy.rb'
- 'ee/app/policies/dast_scanner_profile_policy.rb'
- 'ee/app/policies/dast_site_profile_policy.rb'
- 'ee/app/policies/dast_site_validation_policy.rb'
@@ -2572,8 +2387,6 @@ Gitlab/FeatureAvailableUsage:
- 'ee/app/views/projects/settings/operations/_status_page.html.haml'
- 'ee/app/views/projects/settings/repository/_protected_branches.html.haml'
- 'ee/app/views/projects/sidebar/_repository_locked_files.html.haml'
- - 'ee/app/views/shared/issuable/_board_create_list_dropdown.html.haml'
- - 'ee/app/views/shared/issuable/_board_create_list_dropdown.html.haml'
- 'ee/app/views/shared/issuable/_group_bulk_update_sidebar.html.haml'
- 'ee/app/views/shared/issuable/form/_default_templates.html.haml'
- 'ee/app/views/shared/labels/_create_label_help_text.html.haml'
@@ -2688,3 +2501,116 @@ Database/MultipleDatabases:
- 'spec/support/helpers/usage_data_helpers.rb'
- 'spec/tasks/gitlab/backup_rake_spec.rb'
- 'spec/tasks/gitlab/db_rake_spec.rb'
+
+# WIP: https://gitlab.com/gitlab-org/gitlab/-/issues/339787
+Performance/ActiveRecordSubtransactionMethods:
+ Exclude:
+ - 'app/controllers/clusters/clusters_controller.rb'
+ - 'app/controllers/repositories/lfs_storage_controller.rb'
+ - 'app/controllers/search_controller.rb'
+ - 'app/models/application_record.rb'
+ - 'app/models/ci/ref.rb'
+ - 'app/models/container_repository.rb'
+ - 'app/models/design_management/design_collection.rb'
+ - 'app/models/error_tracking/error.rb'
+ - 'app/models/external_pull_request.rb'
+ - 'app/models/gpg_signature.rb'
+ - 'app/models/merge_request.rb'
+ - 'app/models/plan.rb'
+ - 'app/models/project.rb'
+ - 'app/models/shard.rb'
+ - 'app/models/x509_certificate.rb'
+ - 'app/models/x509_commit_signature.rb'
+ - 'app/models/x509_issuer.rb'
+ - 'app/services/bulk_imports/relation_export_service.rb'
+ - 'app/services/ci/update_build_state_service.rb'
+ - 'app/services/event_create_service.rb'
+ - 'app/services/groups/import_export/import_service.rb'
+ - 'app/services/lfs/file_transformer.rb'
+ - 'app/services/merge_requests/approval_service.rb'
+ - 'app/services/namespaces/statistics_refresher_service.rb'
+ - 'app/services/packages/rubygems/create_dependencies_service.rb'
+ - 'app/services/packages/rubygems/metadata_extraction_service.rb'
+ - 'app/services/projects/create_service.rb'
+ - 'app/services/projects/lfs_pointers/lfs_download_service.rb'
+ - 'app/services/service_desk_settings/update_service.rb'
+ - 'app/services/service_ping/submit_service.rb'
+ - 'app/services/terraform/remote_state_handler.rb'
+ - 'app/workers/namespaces/schedule_aggregation_worker.rb'
+ - 'app/workers/project_export_worker.rb'
+ - 'db/migrate/20200212014653_rename_security_dashboard_feature_flag_to_instance_security_dashboard.rb'
+ - 'db/post_migrate/20200214034836_remove_security_dashboard_feature_flag.rb'
+ - 'db/post_migrate/20210824174615_prepare_ci_builds_metadata_and_ci_build_async_indexes.rb'
+ - 'ee/app/models/ci/minutes/namespace_monthly_usage.rb'
+ - 'ee/app/models/ci/minutes/project_monthly_usage.rb'
+ - 'ee/app/models/concerns/deprecated_approvals_before_merge.rb'
+ - 'ee/app/models/ee/iteration.rb'
+ - 'ee/app/models/ee/plan.rb'
+ - 'ee/app/models/elastic/index_setting.rb'
+ - 'ee/app/models/gitlab_subscription.rb'
+ - 'ee/app/models/software_license.rb'
+ - 'ee/app/services/boards/user_preferences/update_service.rb'
+ - 'ee/app/services/ci/minutes/update_project_and_namespace_usage_service.rb'
+ - 'ee/app/services/ee/analytics/cycle_analytics/stages/base_service.rb'
+ - 'ee/app/services/security/store_report_service.rb'
+ - 'ee/app/services/security/store_scan_service.rb'
+ - 'ee/app/workers/import_software_licenses_worker.rb'
+ - 'ee/db/fixtures/production/027_plans.rb'
+ - 'ee/lib/ee/gitlab/background_migration/migrate_approver_to_approval_rules.rb'
+ - 'ee/lib/gitlab/elastic/indexer.rb'
+ - 'lib/gitlab/ci/pipeline/seed/environment.rb'
+ - 'lib/gitlab/ci/pipeline/seed/processable/resource_group.rb'
+ - 'lib/gitlab/ci/trace/chunked_io.rb'
+ - 'lib/gitlab/composer/cache.rb'
+ - 'lib/gitlab/database/async_indexes/migration_helpers.rb'
+ - 'lib/gitlab/issuables_count_for_state.rb'
+
+# WIP: https://gitlab.com/gitlab-org/gitlab/-/issues/340567
+Rails/IncludeUrlHelper:
+ Exclude:
+ - 'app/models/integrations/asana.rb'
+ - 'app/models/integrations/bamboo.rb'
+ - 'app/models/integrations/bugzilla.rb'
+ - 'app/models/integrations/campfire.rb'
+ - 'app/models/integrations/confluence.rb'
+ - 'app/models/integrations/custom_issue_tracker.rb'
+ - 'app/models/integrations/datadog.rb'
+ - 'app/models/integrations/discord.rb'
+ - 'app/models/integrations/ewm.rb'
+ - 'app/models/integrations/external_wiki.rb'
+ - 'app/models/integrations/flowdock.rb'
+ - 'app/models/integrations/hangouts_chat.rb'
+ - 'app/models/integrations/irker.rb'
+ - 'app/models/integrations/jenkins.rb'
+ - 'app/models/integrations/mattermost.rb'
+ - 'app/models/integrations/pivotaltracker.rb'
+ - 'app/models/integrations/redmine.rb'
+ - 'app/models/integrations/webex_teams.rb'
+ - 'app/models/integrations/youtrack.rb'
+ - 'app/presenters/alert_management/alert_presenter.rb'
+ - 'app/presenters/ci/pipeline_presenter.rb'
+ - 'app/presenters/clusters/cluster_presenter.rb'
+ - 'app/presenters/environment_presenter.rb'
+ - 'app/presenters/gitlab/blame_presenter.rb'
+ - 'app/presenters/group_clusterable_presenter.rb'
+ - 'app/presenters/instance_clusterable_presenter.rb'
+ - 'app/presenters/merge_request_presenter.rb'
+ - 'app/presenters/project_clusterable_presenter.rb'
+ - 'app/presenters/project_presenter.rb'
+ - 'app/presenters/prometheus_alert_presenter.rb'
+ - 'app/presenters/release_presenter.rb'
+ - 'app/presenters/releases/evidence_presenter.rb'
+ - 'ee/app/helpers/license_helper.rb'
+ - 'ee/app/models/integrations/github.rb'
+ - 'ee/app/presenters/merge_request_approver_presenter.rb'
+ - 'ee/spec/helpers/ee/projects/security/configuration_helper_spec.rb'
+ - 'ee/spec/lib/banzai/filter/cross_project_issuable_information_filter_spec.rb'
+ - 'ee/spec/lib/banzai/filter/issuable_state_filter_spec.rb'
+ - 'lib/gitlab/ci/badge/metadata.rb'
+ - 'lib/gitlab/email/message/in_product_marketing/helper.rb'
+ - 'spec/helpers/merge_requests_helper_spec.rb'
+ - 'spec/helpers/nav/top_nav_helper_spec.rb'
+ - 'spec/helpers/notify_helper_spec.rb'
+ - 'spec/lib/banzai/filter/issuable_state_filter_spec.rb'
+ - 'spec/lib/banzai/filter/reference_redactor_filter_spec.rb'
+ - 'spec/lib/banzai/reference_redactor_spec.rb'
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index 09aa4471a4c..b329c9df0f9 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -315,7 +315,6 @@ Performance/MethodObjectAsBlock:
# Configuration parameters: AutoCorrect.
Performance/StringInclude:
Exclude:
- - 'app/helpers/groups_helper.rb'
- 'app/models/snippet_repository.rb'
- 'config/initializers/macos.rb'
- 'config/spring.rb'
diff --git a/.ruby-version b/.ruby-version
index 37c2961c243..a4dd9dba4fb 100644
--- a/.ruby-version
+++ b/.ruby-version
@@ -1 +1 @@
-2.7.2
+2.7.4
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3e5cd774ede..283dbf2aec4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -593,6 +593,25 @@ entry.
- [Add helpful text to URL group validation and limit text](gitlab-org/gitlab@59a5a6266cb0d5434596170ffa36e4e74b8d2c2c) ([merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65369)) **GitLab Enterprise Edition**
- [Refactor external storage admin area configuration UI and docs](gitlab-org/gitlab@497ba4fc8f4ec1d234c9f5f1ec5c69712b8c7cb3) ([merge request](gitlab-org/gitlab!66219))
+## 14.1.5 (2021-09-02)
+
+### Fixed (1 change)
+
+- [Geo: Replicate multi-arch containers](gitlab-org/gitlab@4f74fe9fb6f53cd877d8f793e2ef74c4177006d1) ([merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67624)) **GitLab Enterprise Edition**
+
+## 14.1.4 (2021-08-31)
+
+### Security (8 changes)
+
+- [Update apollo_upload_server dependency](gitlab-org/security/gitlab@34e7e3b7590fd76d0f618091551651e8065edfd2) ([merge request](gitlab-org/security/gitlab!1700))
+- [Ensure shared group members lose project access after group deletion](gitlab-org/security/gitlab@4a7b8203776b719c06186c1b189a8cf21572fcd4) ([merge request](gitlab-org/security/gitlab!1684))
+- [Fix stored XSS vulnerability in Datadog settings form](gitlab-org/security/gitlab@0906814af604e7fcab54a96bccadcba11207387d) ([merge request](gitlab-org/security/gitlab!1671))
+- [Inherit user external status while creating project bots](gitlab-org/security/gitlab@d5a26c4145d917b5b49e207e03669d2b7e4ee617) ([merge request](gitlab-org/security/gitlab!1665))
+- [Escape issue reference and title for Jira issues](gitlab-org/security/gitlab@4153444b76421ddf3a7fd21f1fc0500700a4e263) ([merge request](gitlab-org/security/gitlab!1662)) **GitLab Enterprise Edition**
+- [Require sign in for .keys endpoint on non-public instances](gitlab-org/security/gitlab@b090b3f6dee6d21d93595c5e46e6c5c7fc30f1fb) ([merge request](gitlab-org/security/gitlab!1658))
+- [Only create jira connect NS subscriptions for admins](gitlab-org/security/gitlab@3f2040c0e2c90f3fcafdbf0f86bd2591bd458dff) ([merge request](gitlab-org/security/gitlab!1648))
+- [Prevent non-admins from configuring Jira connect app](gitlab-org/security/gitlab@fa864c0a2eaf450033f4c594cea07d9f24144cd6) ([merge request](gitlab-org/security/gitlab!1644))
+
## 14.1.3 (2021-08-17)
### Fixed (2 changes)
@@ -1211,6 +1230,38 @@ entry.
- [Remove diffs gradual load feature flag](gitlab-org/gitlab@027d7c4327b5b6205a84281239027273517bf81b) ([merge request](gitlab-org/gitlab!55478))
- [Remove partial index for Hashed Storage migration](gitlab-org/gitlab@3ed017a1023d7b0941a7606b69e6caee8d22f15c) ([merge request](gitlab-org/gitlab!62920))
+## 14.0.10 (2021-09-02)
+
+No changes.
+
+## 14.0.9 (2021-08-31)
+
+### Security (9 changes)
+
+- [Update apollo_upload_server dependency](gitlab-org/security/gitlab@ced741d93fa664f0c152f524949258bf969b7667) ([merge request](gitlab-org/security/gitlab!1701))
+- [Ensure shared group members lose project access after group deletion](gitlab-org/security/gitlab@3a41f4e29c01188aaaf01ab5e3deec2a9eeed18e) ([merge request](gitlab-org/security/gitlab!1685))
+- [Fix stored XSS vulnerability in Datadog settings form](gitlab-org/security/gitlab@269e5bf96b5e97c3b8e6f6b8b3f593d958de2ecb) ([merge request](gitlab-org/security/gitlab!1672))
+- [Inherit user external status while creating project bots](gitlab-org/security/gitlab@5bae4e53bd4c363270b2fc2e308b81d2a2a388a6) ([merge request](gitlab-org/security/gitlab!1666))
+- [Escape issue reference and title for Jira issues](gitlab-org/security/gitlab@0397f2b393d563559c49c39c0ba1d192d08a10d7) ([merge request](gitlab-org/security/gitlab!1663)) **GitLab Enterprise Edition**
+- [Require sign in for .keys endpoint on non-public instances](gitlab-org/security/gitlab@13a7f6001f663b3745159fa37b518ba4a43355bd) ([merge request](gitlab-org/security/gitlab!1659))
+- [Update Import/Export to use public email when mapping users](gitlab-org/security/gitlab@f3d1b800af55986cef83aeaf4df1312e3070f0c5) ([merge request](gitlab-org/security/gitlab!1654)) **GitLab Enterprise Edition**
+- [Only create jira connect NS subscriptions for admins](gitlab-org/security/gitlab@34bdcd45f24eaa051702834fb6c3568e45721004) ([merge request](gitlab-org/security/gitlab!1647))
+- [Prevent non-admins from configuring Jira connect app](gitlab-org/security/gitlab@4af692246224b1cd1e2fe3c6d0ac2613c0f8fe39) ([merge request](gitlab-org/security/gitlab!1643))
+
+## 14.0.8 (2021-08-25)
+
+### Fixed (1 change)
+
+- [Fix: Sidekiq workers delete each other's metrics](gitlab-org/gitlab@98a85fcbcdf2f8dfef83e552a850591e8952c057) ([merge request](gitlab-org/gitlab!68761))
+
+### Changed (1 change)
+
+- [Resolve "operator does not exist: integer[] || bigint in...](gitlab-org/gitlab@273cc43f7928e89fd11237b58fdfdfb8a24e5493) ([merge request](gitlab-org/gitlab!68761))
+
+### Other (1 change)
+
+- [Revert backfill on ci_build_trace_sections](gitlab-org/gitlab@10a5ad9dce9014eb8af6493402dcdd1658dbd62a) ([merge request](gitlab-org/gitlab!68761))
+
## 14.0.7 (2021-08-03)
### Security (18 changes)
@@ -1944,6 +1995,10 @@ entry.
- [Add missing metrics information](gitlab-org/gitlab@89cd7fe3b95323e635b2d73e08549b2e6153dc4d) ([merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61772/edit))
- [Track usage of the resolve UI](gitlab-org/gitlab@35c8e30fce288cecefcf2f7c0077d4608e696519) ([merge request](gitlab-org/gitlab!61654))
+## 13.12.11 (2021-09-02)
+
+No changes.
+
## 13.12.10 (2021-08-10)
### Fixed (2 changes)
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 7ffbcaae4c6..2ec6b8c1965 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-14.2.4 \ No newline at end of file
+ccd8ea3e1436d6464ac5f67e6bebd1ae317f4d50
diff --git a/GITLAB_KAS_VERSION b/GITLAB_KAS_VERSION
index e4eccd4e6cd..f84a4218283 100644
--- a/GITLAB_KAS_VERSION
+++ b/GITLAB_KAS_VERSION
@@ -1 +1 @@
-14.2.2
+14.3.2
diff --git a/GITLAB_PAGES_VERSION b/GITLAB_PAGES_VERSION
index a50908ca3da..372cf402c73 100644
--- a/GITLAB_PAGES_VERSION
+++ b/GITLAB_PAGES_VERSION
@@ -1 +1 @@
-1.42.0
+1.44.0
diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION
index bf4ba6520ea..9dafbf994eb 100644
--- a/GITLAB_SHELL_VERSION
+++ b/GITLAB_SHELL_VERSION
@@ -1 +1 @@
-13.19.1
+13.21.0
diff --git a/Gemfile b/Gemfile
index ecb1e526e4d..39e61564968 100644
--- a/Gemfile
+++ b/Gemfile
@@ -18,7 +18,7 @@ gem 'default_value_for', '~> 3.4.0'
gem 'pg', '~> 1.1'
gem 'rugged', '~> 1.1'
-gem 'grape-path-helpers', '~> 1.6.3'
+gem 'grape-path-helpers', '~> 1.7.0'
gem 'faraday', '~> 1.0'
gem 'marginalia', '~> 1.10.0'
@@ -32,7 +32,7 @@ gem 'bcrypt', '~> 3.1', '>= 3.1.14'
gem 'doorkeeper', '~> 5.5.0.rc2'
gem 'doorkeeper-openid_connect', '~> 1.7.5'
gem 'rexml', '~> 3.2.5'
-gem 'ruby-saml', '~> 1.12.1'
+gem 'ruby-saml', '~> 1.13.0'
gem 'omniauth', '~> 1.8'
gem 'omniauth-auth0', '~> 2.0.0'
gem 'omniauth-azure-activedirectory-v2', '~> 1.0'
@@ -120,7 +120,7 @@ gem 'carrierwave', '~> 1.3'
gem 'mini_magick', '~> 4.10.1'
# for backups
-gem 'fog-aws', '~> 3.9'
+gem 'fog-aws', '~> 3.12'
# Locked until fog-google resolves https://github.com/fog/fog-google/issues/421.
# Also see config/initializers/fog_core_patch.rb.
gem 'fog-core', '= 2.1.0'
@@ -233,7 +233,7 @@ gem 'redis', '~> 4.1.4'
gem 'connection_pool', '~> 2.0'
# Redis session store
-gem 'redis-rails', '~> 5.0.2'
+gem 'redis-actionpack', '~> 5.2.0'
# Discord integration
gem 'discordrb-webhooks', '~> 3.4', require: false
@@ -333,7 +333,7 @@ gem 'snowplow-tracker', '~> 0.6.1'
# Metrics
gem 'method_source', '~> 1.0', require: false
gem 'webrick', '~> 1.6.1', require: false
-gem 'prometheus-client-mmap', '~> 0.12.0', require: 'prometheus/client'
+gem 'prometheus-client-mmap', '~> 0.15.0', require: 'prometheus/client'
gem 'warning', '~> 1.2.0'
@@ -372,7 +372,7 @@ group :development, :test do
gem 'spring', '~> 2.1.0'
gem 'spring-commands-rspec', '~> 1.0.4'
- gem 'gitlab-styles', '~> 6.2.0', require: false
+ gem 'gitlab-styles', '~> 6.3.0', require: false
gem 'haml_lint', '~> 0.36.0', require: false
gem 'bundler-audit', '~> 0.7.0.1', require: false
@@ -474,7 +474,7 @@ end
gem 'spamcheck', '~> 0.1.0'
# Gitaly GRPC protocol definitions
-gem 'gitaly', '~> 14.2.0.pre.rc2'
+gem 'gitaly', '~> 14.3.0.pre.rc1'
# KAS GRPC protocol definitions
gem 'kas-grpc', '~> 0.0.2'
@@ -522,7 +522,7 @@ gem 'lockbox', '~> 0.6.2'
gem 'valid_email', '~> 0.1'
# JSON
-gem 'json', '~> 2.3.0'
+gem 'json', '~> 2.5.1'
gem 'json_schemer', '~> 0.2.18'
gem 'oj', '~> 3.10.6'
gem 'multi_json', '~> 1.14.1'
diff --git a/Gemfile.lock b/Gemfile.lock
index 3ff3f6ca76f..d62e948e636 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -372,7 +372,7 @@ GEM
faraday_middleware
multi_json
fast_blank (1.0.0)
- fast_gettext (1.6.0)
+ fast_gettext (2.1.0)
ffaker (2.10.0)
ffi (1.15.3)
ffi-compiler (1.0.1)
@@ -395,7 +395,7 @@ GEM
fog-json
ipaddress (~> 0.8)
xml-simple (~> 1.1)
- fog-aws (3.9.0)
+ fog-aws (3.12.0)
fog-core (~> 2.1)
fog-json (~> 1.1)
fog-xml (~> 0.1)
@@ -453,7 +453,7 @@ GEM
rails (>= 3.2.0)
git (1.7.0)
rchardet (~> 1.8)
- gitaly (14.2.0.pre.rc2)
+ gitaly (14.3.0.pre.rc1)
grpc (~> 1.0)
github-markup (1.7.0)
gitlab (4.16.1)
@@ -493,7 +493,7 @@ GEM
openid_connect (~> 1.2)
gitlab-sidekiq-fetcher (0.5.6)
sidekiq (~> 5)
- gitlab-styles (6.2.0)
+ gitlab-styles (6.3.0)
rubocop (~> 0.91, >= 0.91.1)
rubocop-gitlab-security (~> 0.1.1)
rubocop-performance (~> 1.9.2)
@@ -546,7 +546,7 @@ GEM
grape-entity (0.9.0)
activesupport (>= 3.0.0)
multi_json (>= 1.3.2)
- grape-path-helpers (1.6.3)
+ grape-path-helpers (1.7.0)
activesupport
grape (~> 1.3)
rake (> 12)
@@ -657,7 +657,7 @@ GEM
character_set (~> 1.4)
regexp_parser (~> 2.1)
regexp_property_values (~> 1.0)
- json (2.3.0)
+ json (2.5.1)
json-jwt (1.13.0)
activesupport (>= 4.2)
aes_key_wrap
@@ -728,7 +728,7 @@ GEM
activesupport (>= 4)
railties (>= 4)
request_store (~> 1.0)
- loofah (2.11.0)
+ loofah (2.12.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
lru_redux (1.1.0)
@@ -900,7 +900,7 @@ GEM
orm_adapter (0.5.0)
os (1.1.1)
parallel (1.20.1)
- parser (3.0.0.0)
+ parser (3.0.2.0)
ast (~> 2.4.1)
parslet (1.8.2)
pastel (0.8.0)
@@ -925,7 +925,7 @@ GEM
coderay
parser
unparser
- prometheus-client-mmap (0.12.0)
+ prometheus-client-mmap (0.15.0)
pry (0.13.1)
coderay (~> 1.1)
method_source (~> 1.0)
@@ -989,7 +989,7 @@ GEM
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
- rails-html-sanitizer (1.3.0)
+ rails-html-sanitizer (1.4.2)
loofah (~> 2.3)
rails-i18n (6.0.0)
i18n (>= 0.7, < 2)
@@ -1023,19 +1023,12 @@ GEM
actionpack (>= 5, < 7)
redis-rack (>= 2.1.0, < 3)
redis-store (>= 1.1.0, < 2)
- redis-activesupport (5.2.0)
- activesupport (>= 3, < 7)
- redis-store (>= 1.3, < 2)
redis-namespace (1.8.1)
redis (>= 3.0.4)
- redis-rack (2.1.2)
+ redis-rack (2.1.3)
rack (>= 2.0.8, < 3)
redis-store (>= 1.2, < 2)
- redis-rails (5.0.2)
- redis-actionpack (>= 5.0, < 6)
- redis-activesupport (>= 5.0, < 6)
- redis-store (>= 1.2, < 2)
- redis-store (1.8.1)
+ redis-store (1.9.0)
redis (>= 4, < 5)
regexp_parser (2.1.1)
regexp_property_values (1.0.0)
@@ -1131,7 +1124,7 @@ GEM
mini_portile2 (~> 2.5.0)
ruby-prof (1.3.1)
ruby-progressbar (1.11.0)
- ruby-saml (1.12.1)
+ ruby-saml (1.13.0)
nokogiri (>= 1.10.5)
rexml
ruby-statistics (2.1.2)
@@ -1459,7 +1452,7 @@ DEPENDENCIES
flipper-active_support_cache_store (~> 0.21.0)
flowdock (~> 0.7)
fog-aliyun (~> 0.3)
- fog-aws (~> 3.9)
+ fog-aws (~> 3.12)
fog-core (= 2.1.0)
fog-google (~> 1.15)
fog-local (~> 0.6)
@@ -1471,7 +1464,7 @@ DEPENDENCIES
gettext (~> 3.3)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.3)
- gitaly (~> 14.2.0.pre.rc2)
+ gitaly (~> 14.3.0.pre.rc1)
github-markup (~> 1.7.0)
gitlab-chronic (~> 0.10.5)
gitlab-dangerfiles (~> 2.3.0)
@@ -1484,7 +1477,7 @@ DEPENDENCIES
gitlab-net-dns (~> 0.9.1)
gitlab-omniauth-openid-connect (~> 0.8.0)
gitlab-sidekiq-fetcher (= 0.5.6)
- gitlab-styles (~> 6.2.0)
+ gitlab-styles (~> 6.3.0)
gitlab_chronic_duration (~> 0.10.6.2)
gitlab_omniauth-ldap (~> 2.1.1)
gon (~> 6.4.0)
@@ -1493,7 +1486,7 @@ DEPENDENCIES
gpgme (~> 2.0.19)
grape (~> 1.5.2)
grape-entity (~> 0.9.0)
- grape-path-helpers (~> 1.6.3)
+ grape-path-helpers (~> 1.7.0)
grape_logging (~> 1.7)
graphiql-rails (~> 1.4.10)
graphlient (~> 0.4.0)
@@ -1516,7 +1509,7 @@ DEPENDENCIES
ipaddress (~> 0.8.3)
jira-ruby (~> 2.1.4)
js_regex (~> 3.7)
- json (~> 2.3.0)
+ json (~> 2.5.1)
json_schemer (~> 0.2.18)
jwt (~> 2.1.0)
kaminari (~> 1.0)
@@ -1574,7 +1567,7 @@ DEPENDENCIES
pg_query (~> 2.1)
png_quantizator (~> 0.2.1)
premailer-rails (~> 1.10.3)
- prometheus-client-mmap (~> 0.12.0)
+ prometheus-client-mmap (~> 0.15.0)
pry-byebug
pry-rails (~> 0.3.9)
pry-shell (~> 0.4.0)
@@ -1596,8 +1589,8 @@ DEPENDENCIES
re2 (~> 1.2.0)
recaptcha (~> 4.11)
redis (~> 4.1.4)
+ redis-actionpack (~> 5.2.0)
redis-namespace (~> 1.8.1)
- redis-rails (~> 5.0.2)
request_store (~> 1.5)
responders (~> 3.0)
retriable (~> 3.1.2)
@@ -1613,7 +1606,7 @@ DEPENDENCIES
ruby-magic (~> 0.4)
ruby-prof (~> 1.3.0)
ruby-progressbar (~> 1.10)
- ruby-saml (~> 1.12.1)
+ ruby-saml (~> 1.13.0)
ruby_parser (~> 3.15)
rubyzip (~> 2.0.0)
rugged (~> 1.1)
diff --git a/README.md b/README.md
index f8eb17cf855..ee7eef9aa2d 100644
--- a/README.md
+++ b/README.md
@@ -80,7 +80,7 @@ Instructions on how to start GitLab and how to run the tests can be found in the
GitLab is a Ruby on Rails application that runs on the following software:
- Ubuntu/Debian/CentOS/RHEL/OpenSUSE
-- Ruby (MRI) 2.7.2
+- Ruby (MRI) 2.7.4
- Git 2.31+
- Redis 5.0+
- PostgreSQL 12+
diff --git a/app/assets/images/learn_gitlab/code_owners_enabled.svg b/app/assets/images/learn_gitlab/code_owners_enabled.svg
deleted file mode 100644
index 019d74c64cc..00000000000
--- a/app/assets/images/learn_gitlab/code_owners_enabled.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="26" height="26" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path d="M13 25C19.6274 25 25 19.6274 25 13C25 6.37258 19.6274 1 13 1C6.37258 1 1 6.37258 1 13C1 19.6274 6.37258 25 13 25Z" fill="white" stroke="#C2B7E6" stroke-width="2"/>
-<path d="M1.16748 12.3359C2.88075 11.7701 4.4618 10.8635 5.81545 9.67055C7.16911 8.47763 8.26738 7.02313 9.04415 5.39461M6.94481 2.60461C9.28681 6.43995 13.5115 8.99995 18.3335 8.99995C20.2715 8.99995 22.1135 8.58661 23.7748 7.84261L6.94481 2.60461Z" stroke="#C2B7E6"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M10.1176 15.8941H15.7647C15.7647 17.447 14.4941 18.7176 12.9412 18.7176C11.3882 18.7176 10.1176 17.447 10.1176 15.8941ZM9.05882 15.1882C8.47294 15.1882 8 14.7153 8 14.1294C8 13.5435 8.47294 13.0706 9.05882 13.0706C9.64471 13.0706 10.1176 13.5435 10.1176 14.1294C10.1176 14.7153 9.64471 15.1882 9.05882 15.1882ZM16.8235 15.1882C16.2376 15.1882 15.7647 14.7153 15.7647 14.1294C15.7647 13.5435 16.2376 13.0706 16.8235 13.0706C17.4094 13.0706 17.8824 13.5435 17.8824 14.1294C17.8824 14.7153 17.4094 15.1882 16.8235 15.1882Z" fill="#6B4FBB"/>
-</svg>
diff --git a/app/assets/images/learn_gitlab/git_write.svg b/app/assets/images/learn_gitlab/git_write.svg
deleted file mode 100644
index ad87b3f3b12..00000000000
--- a/app/assets/images/learn_gitlab/git_write.svg
+++ /dev/null
@@ -1,16 +0,0 @@
-<svg width="40" height="39" viewBox="0 0 40 39" fill="none" xmlns="http://www.w3.org/2000/svg">
-<g clip-path="url(#clip0)">
-<path d="M32.2886 3.99573H37.8624C38.1834 3.99573 38.4435 4.25587 38.4435 4.57679V33.9598C38.4435 34.2808 38.1834 34.5409 37.8624 34.5409H32.2886V3.99573Z" fill="#F0F0F0" stroke="#DBDBDB" stroke-width="2"/>
-<path d="M10.757 9.4011L10.7363 4.92686C10.7337 4.35386 11.1491 3.86447 11.7148 3.77395L30.908 0.703095C31.614 0.590124 32.2537 1.13556 32.2537 1.85062V37.0106C32.2537 37.723 31.6184 38.2678 30.9143 38.1591L11.8555 35.2171C11.2908 35.13 10.8733 34.6453 10.8707 34.074L10.8502 29.6368" stroke="#DBDBDB" stroke-width="2"/>
-<path d="M11.2195 29.7561C16.877 29.7561 21.4634 25.1698 21.4634 19.5122C21.4634 13.8547 16.877 9.26831 11.2195 9.26831C5.56194 9.26831 0.975586 13.8547 0.975586 19.5122C0.975586 25.1698 5.56194 29.7561 11.2195 29.7561Z" stroke="#6E49CB"/>
-<path d="M11.2194 27.8048C15.7994 27.8048 19.5121 24.0921 19.5121 19.5122C19.5121 14.9322 15.7994 11.2195 11.2194 11.2195C6.63952 11.2195 2.92676 14.9322 2.92676 19.5122C2.92676 24.0921 6.63952 27.8048 11.2194 27.8048Z" fill="#6E49CB"/>
-<path d="M11.2194 27.8048C15.7994 27.8048 19.5121 24.0921 19.5121 19.5122C19.5121 14.9322 15.7994 11.2195 11.2194 11.2195C6.63952 11.2195 2.92676 14.9322 2.92676 19.5122C2.92676 24.0921 6.63952 27.8048 11.2194 27.8048Z" fill="white" fill-opacity="0.9"/>
-<path d="M10.8843 23.4146V16.276" stroke="#6E49CB" stroke-linecap="round"/>
-<path d="M7.31689 19.6609H14.634" stroke="#6E49CB" stroke-linecap="round"/>
-</g>
-<defs>
-<clipPath id="clip0">
-<rect width="40" height="39.0244" fill="white"/>
-</clipPath>
-</defs>
-</svg>
diff --git a/app/assets/images/learn_gitlab/issue_created.svg b/app/assets/images/learn_gitlab/issue_created.svg
deleted file mode 100644
index 01652b97fc0..00000000000
--- a/app/assets/images/learn_gitlab/issue_created.svg
+++ /dev/null
@@ -1,65 +0,0 @@
-<svg width="81" height="48" viewBox="0 0 81 48" fill="none" xmlns="http://www.w3.org/2000/svg">
-<g clip-path="url(#clip0)">
-<path fill-rule="evenodd" clip-rule="evenodd" d="M42.9799 11.6386C42.9688 11.7501 42.955 11.8786 42.9384 12.0222C42.8865 12.4687 42.8257 12.9142 42.756 13.3582C42.7493 13.3954 42.7501 13.4335 42.7584 13.4704C42.7667 13.5072 42.7822 13.542 42.8041 13.5728C42.826 13.6035 42.8538 13.6296 42.8859 13.6495C42.918 13.6693 42.9538 13.6826 42.9911 13.6884C43.0284 13.6943 43.0664 13.6926 43.1031 13.6835C43.1397 13.6745 43.1742 13.6582 43.2045 13.6356C43.2347 13.613 43.2602 13.5847 43.2793 13.5521C43.2985 13.5196 43.3109 13.4835 43.316 13.4461C43.3915 12.9637 43.4531 12.506 43.5015 12.0874C43.5221 11.9092 43.5408 11.7308 43.5577 11.5522C43.5609 11.5151 43.5568 11.4777 43.5456 11.4422C43.5343 11.4067 43.5162 11.3738 43.4923 11.3453C43.4684 11.3168 43.439 11.2933 43.406 11.2761C43.373 11.2589 43.3369 11.2484 43.2998 11.2452C43.2627 11.242 43.2253 11.2461 43.1898 11.2573C43.1543 11.2685 43.1214 11.2866 43.0929 11.3106C43.0644 11.3345 43.0409 11.3638 43.0237 11.3969C43.0065 11.4299 42.996 11.466 42.9928 11.5031C42.9909 11.5263 42.9866 11.572 42.9799 11.6386ZM41.9287 16.9968C41.9171 17.0322 41.9127 17.0695 41.9156 17.1066C41.9185 17.1438 41.9287 17.1799 41.9456 17.2131C41.9624 17.2463 41.9857 17.2758 42.014 17.3C42.0423 17.3242 42.0751 17.3426 42.1105 17.3542C42.1459 17.3657 42.1832 17.3701 42.2203 17.3672C42.2574 17.3643 42.2936 17.3541 42.3268 17.3373C42.36 17.3204 42.3895 17.2971 42.4137 17.2688C42.4379 17.2405 42.4563 17.2078 42.4678 17.1724C42.6521 16.606 42.8172 15.985 42.9645 15.321C42.9734 15.2843 42.975 15.2462 42.9691 15.2089C42.9631 15.1716 42.9498 15.1359 42.9299 15.1039C42.91 15.0718 42.8839 15.044 42.8531 15.0222C42.8223 15.0004 42.7874 14.9849 42.7506 14.9767C42.7137 14.9686 42.6756 14.9678 42.6385 14.9746C42.6013 14.9813 42.5659 14.9954 42.5343 15.016C42.5027 15.0367 42.4755 15.0634 42.4543 15.0947C42.4332 15.1259 42.4185 15.1611 42.4111 15.1981C42.2675 15.8456 42.1069 16.4491 41.9287 16.9968ZM40.0489 19.874C40.0136 19.8862 39.981 19.9053 39.9531 19.9302C39.9252 19.955 39.9025 19.9852 39.8863 20.0189C39.8701 20.0526 39.8607 20.0891 39.8587 20.1265C39.8566 20.1638 39.862 20.2012 39.8745 20.2364C39.887 20.2716 39.9063 20.3041 39.9313 20.3318C39.9564 20.3596 39.9867 20.3821 40.0205 20.3981C40.0543 20.4141 40.0909 20.4232 40.1283 20.425C40.1656 20.4267 40.2029 20.4211 40.2381 20.4084C40.8012 20.209 41.2854 19.713 41.7083 18.9671C41.7454 18.9017 41.755 18.8242 41.735 18.7517C41.715 18.6792 41.667 18.6177 41.6016 18.5806C41.5362 18.5435 41.4587 18.5339 41.3862 18.554C41.3137 18.574 41.2522 18.622 41.2151 18.6874C40.8532 19.3257 40.4601 19.7283 40.0489 19.874ZM36.3662 20.7087C36.3319 20.7231 36.3007 20.7442 36.2746 20.7706C36.2484 20.7971 36.2277 20.8285 36.2136 20.863C36.1996 20.8974 36.1925 20.9343 36.1927 20.9716C36.1929 21.0088 36.2004 21.0456 36.2149 21.0799C36.2293 21.1142 36.2504 21.1454 36.2769 21.1715C36.3033 21.1977 36.3347 21.2184 36.3692 21.2324C36.4037 21.2465 36.4406 21.2536 36.4778 21.2534C36.515 21.2532 36.5518 21.2456 36.5861 21.2312C37.1757 20.9829 37.7714 20.792 38.3357 20.6679C38.4091 20.6517 38.4731 20.607 38.5136 20.5437C38.5541 20.4803 38.5677 20.4035 38.5516 20.3301C38.5354 20.2566 38.4907 20.1926 38.4274 20.1521C38.364 20.1117 38.2872 20.098 38.2138 20.1142C37.6153 20.2459 36.9871 20.4473 36.3662 20.7087ZM33.1143 22.7955C33.0607 22.8475 33.0298 22.9186 33.0283 22.9932C33.0267 23.0678 33.0547 23.1401 33.1061 23.1942C33.1576 23.2483 33.2282 23.28 33.3029 23.2823C33.3775 23.2846 33.45 23.2574 33.5047 23.2066C33.9359 22.7967 34.4242 22.42 34.9553 22.0829C35.0187 22.0426 35.0636 21.9788 35.08 21.9054C35.0964 21.832 35.083 21.7551 35.0427 21.6916C35.0024 21.6282 34.9385 21.5833 34.8651 21.5669C34.7918 21.5505 34.7149 21.5639 34.6514 21.6042C34.0901 21.9605 33.5729 22.3598 33.1143 22.7955ZM31.0777 26.1259C31.0686 26.162 31.0667 26.1995 31.0721 26.2364C31.0776 26.2732 31.0902 26.3086 31.1093 26.3406C31.1284 26.3725 31.1536 26.4004 31.1835 26.4226C31.2134 26.4448 31.2474 26.4609 31.2835 26.47C31.3196 26.4791 31.3571 26.481 31.3939 26.4755C31.4308 26.4701 31.4662 26.4575 31.4981 26.4384C31.5301 26.4193 31.558 26.394 31.5802 26.3642C31.6024 26.3343 31.6185 26.3003 31.6276 26.2642C31.7727 25.6871 32.0133 25.1347 32.3419 24.611C32.3799 24.5474 32.3915 24.4715 32.3742 24.3994C32.3569 24.3274 32.3121 24.265 32.2493 24.2256C32.1866 24.1862 32.1109 24.1729 32.0385 24.1886C31.9661 24.2043 31.9027 24.2478 31.8619 24.3096C31.5023 24.8826 31.2379 25.4896 31.0777 26.1259ZM31.0276 29.9893C31.0322 30.0262 31.0441 30.0619 31.0626 30.0943C31.081 30.1266 31.1056 30.155 31.135 30.1778C31.1644 30.2007 31.1981 30.2175 31.234 30.2273C31.2699 30.2371 31.3074 30.2398 31.3443 30.2352C31.3813 30.2305 31.4169 30.2186 31.4493 30.2002C31.4816 30.1818 31.51 30.1571 31.5328 30.1277C31.5557 30.0983 31.5725 30.0647 31.5823 30.0288C31.5922 29.9929 31.5948 29.9554 31.5902 29.9184C31.5208 29.3685 31.4806 28.7587 31.4683 28.0633C31.467 27.9881 31.4358 27.9165 31.3817 27.8643C31.3276 27.8121 31.255 27.7835 31.1798 27.7848C31.1046 27.7861 31.0331 27.8173 30.9808 27.8714C30.9286 27.9255 30.9 27.9981 30.9014 28.0733C30.914 28.7882 30.9556 29.418 31.0276 29.9893ZM32.2028 33.6691C32.238 33.7355 32.2981 33.7853 32.37 33.8074C32.4418 33.8295 32.5195 33.8222 32.586 33.7871C32.6524 33.7519 32.7022 33.6918 32.7243 33.6199C32.7465 33.5481 32.7392 33.4704 32.704 33.4039C32.3876 32.8064 32.1554 32.271 31.9768 31.7139C31.9539 31.6423 31.9034 31.5828 31.8365 31.5484C31.7697 31.514 31.6919 31.5075 31.6203 31.5305C31.5487 31.5535 31.4892 31.6039 31.4548 31.6708C31.4204 31.7376 31.414 31.8154 31.4369 31.887C31.6265 32.4779 31.8719 33.0435 32.2028 33.6691ZM33.6326 36.0823C33.8058 36.3634 33.9778 36.6453 34.1485 36.9279C34.1874 36.9923 34.2502 37.0386 34.3233 37.0567C34.3963 37.0747 34.4734 37.063 34.5378 37.0241C34.6022 36.9853 34.6485 36.9224 34.6665 36.8494C34.6846 36.7764 34.6729 36.6992 34.634 36.6348C34.4623 36.351 34.2895 36.0678 34.1155 35.7854C34.1306 35.81 33.7462 35.1858 33.6457 35.0219C33.6264 34.9897 33.601 34.9617 33.5709 34.9394C33.5407 34.9171 33.5065 34.901 33.4701 34.892C33.4337 34.8831 33.3958 34.8814 33.3588 34.8872C33.3217 34.8929 33.2862 34.906 33.2542 34.9256C33.2222 34.9451 33.1945 34.9709 33.1725 35.0013C33.1506 35.0317 33.1349 35.0661 33.1263 35.1026C33.1177 35.1391 33.1165 35.177 33.1227 35.2139C33.1289 35.2509 33.1423 35.2863 33.1623 35.3181C33.2632 35.4825 33.6481 36.1076 33.6326 36.0825V36.0823ZM35.3062 40.3242C35.3067 40.3615 35.3145 40.3982 35.3292 40.4324C35.3439 40.4666 35.3652 40.4976 35.3918 40.5236C35.4185 40.5496 35.45 40.57 35.4846 40.5838C35.5192 40.5976 35.5561 40.6045 35.5933 40.604C35.6306 40.6035 35.6673 40.5957 35.7015 40.581C35.7357 40.5663 35.7667 40.545 35.7927 40.5184C35.8187 40.4917 35.8392 40.4602 35.853 40.4256C35.8668 40.391 35.8736 40.3541 35.8731 40.3169C35.8648 39.6518 35.7475 38.9926 35.526 38.3655C35.4998 38.2962 35.4474 38.2399 35.3802 38.2087C35.313 38.1775 35.2363 38.1738 35.1664 38.1985C35.0966 38.2232 35.0392 38.2743 35.0065 38.3407C34.9738 38.4072 34.9684 38.4839 34.9915 38.5543C35.1924 39.1231 35.2987 39.721 35.3062 40.3242ZM34.27 43.7311C34.2299 43.7937 34.216 43.8695 34.2313 43.9422C34.2466 44.015 34.2898 44.0788 34.3517 44.12C34.4135 44.1612 34.4891 44.1764 34.5621 44.1624C34.6351 44.1484 34.6997 44.1063 34.7419 44.0452C35.109 43.4961 35.3947 42.8967 35.59 42.2658C35.6121 42.1939 35.6048 42.1162 35.5696 42.0497C35.5344 41.9833 35.4743 41.9335 35.4024 41.9114C35.3305 41.8893 35.2528 41.8967 35.1864 41.9319C35.1199 41.9671 35.0702 42.0272 35.0481 42.0991C34.8689 42.6778 34.6068 43.2275 34.27 43.7311Z" fill="#FDE5D8"/>
-<path d="M60.8446 31.6803L53.1713 38.2926M49.7697 32.4009L59.3328 29.0618L49.7697 32.4009Z" stroke="#FDE5D8" stroke-linecap="round"/>
-<path d="M60.2631 30.4887C60.3987 30.4104 60.4451 30.237 60.3668 30.1014C60.2886 29.9659 60.1152 29.9194 59.9796 29.9977L54.1288 33.3756C53.9932 33.4539 53.9468 33.6273 54.0251 33.7629C54.1033 33.8984 54.2767 33.9449 54.4123 33.8666L60.2631 30.4887Z" fill="#FDE5D8"/>
-<path d="M63.2421 30.9507L61.2578 27.5138C61.1535 27.3331 60.9223 27.2711 60.7415 27.3755L59.9327 27.8425C59.752 27.9468 59.69 28.178 59.7944 28.3588L61.7786 31.7956C61.883 31.9764 62.1142 32.0383 62.2949 31.9339L63.1037 31.467C63.2845 31.3626 63.3464 31.1314 63.2421 30.9507Z" fill="white" stroke="#FDE5D8"/>
-<path d="M69.8124 20.1746L73.8754 27.2119L63.7936 33.0326L59.7306 25.9953L69.8124 20.1746Z" stroke="#FDE5D8"/>
-<path d="M68.6454 29.795L68.3599 32.8374C68.35 32.9411 68.2766 33.0767 68.1935 33.1419L64.4623 36.0762C64.2994 36.2045 64.2327 36.1536 64.3133 35.9633L65.268 33.7089L65.5559 31.5788" stroke="#FDE5D8"/>
-<path d="M64.9604 23.4123L62.1829 22.1385C62.088 22.0951 61.934 22.0911 61.836 22.1302L57.4292 23.8944C57.2367 23.9715 57.2473 24.0546 57.4525 24.08L59.8823 24.3805L61.8709 25.1962" stroke="#FDE5D8"/>
-<path d="M69.8126 20.1746L76.321 20.7344C76.6326 20.7612 76.778 21.0118 76.645 21.2955L73.8758 27.2118" stroke="#FDE5D8"/>
-<path d="M62.0503 27.3839C62.1285 27.5195 62.3012 27.5663 62.4359 27.4886C62.5705 27.4108 62.6163 27.2379 62.538 27.1023C62.4597 26.9667 62.2871 26.9198 62.1524 26.9976C62.0177 27.0754 61.972 27.2483 62.0503 27.3839Z" fill="#FC8A51"/>
-<path d="M62.6173 28.3658C62.6955 28.5014 62.8682 28.5483 63.0028 28.4705C63.1375 28.3928 63.1832 28.2198 63.105 28.0842C63.0267 27.9487 62.8541 27.9018 62.7194 27.9795C62.5847 28.0573 62.539 28.2302 62.6173 28.3658Z" fill="#FC8A51"/>
-<path d="M63.1841 29.3476C63.2624 29.4832 63.435 29.5301 63.5697 29.4523C63.7044 29.3746 63.7501 29.2016 63.6718 29.066C63.5935 28.9305 63.4209 28.8836 63.2862 28.9613C63.1516 29.0391 63.1058 29.212 63.1841 29.3476Z" fill="#FC8A51"/>
-<path d="M63.7511 30.3297C63.8294 30.4653 64.002 30.5121 64.1367 30.4344C64.2714 30.3566 64.3171 30.1837 64.2388 30.0481C64.1605 29.9125 63.9879 29.8656 63.8532 29.9434C63.7186 30.0212 63.6728 30.1941 63.7511 30.3297Z" fill="#FC8A51"/>
-<path d="M65.9899 27.0731C66.5378 28.0221 67.7464 28.3501 68.6894 27.8057C69.6324 27.2612 69.9527 26.0505 69.4048 25.1015C68.8568 24.1524 67.6482 23.8244 66.7052 24.3689C65.7622 24.9133 65.4419 26.124 65.9899 27.0731Z" stroke="#FDE5D8"/>
-<path d="M66.8032 26.6036C67.0902 27.1008 67.7233 27.2726 68.2173 26.9874C68.7113 26.7022 68.879 26.068 68.592 25.5709C68.305 25.0738 67.6719 24.902 67.1779 25.1872C66.684 25.4723 66.5162 26.1065 66.8032 26.6036Z" stroke="#FDE5D8"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M18.5279 7.40988C18.4991 7.72887 18.5432 8.13101 18.7163 8.57152C18.7364 8.61656 18.7731 8.65211 18.8188 8.6708C18.8645 8.68948 18.9156 8.68987 18.9615 8.67188C19.0075 8.65389 19.0447 8.61891 19.0656 8.57418C19.0864 8.52945 19.0892 8.47842 19.0734 8.43167C18.924 8.05108 18.8863 7.70752 18.91 7.44408C18.9119 7.42254 18.9137 7.40893 18.9145 7.40421C18.9193 7.37911 18.9189 7.35331 18.9136 7.32834C18.9082 7.30336 18.8979 7.2797 18.8833 7.25876C18.8687 7.23781 18.85 7.22 18.8284 7.20637C18.8068 7.19273 18.7827 7.18355 18.7575 7.17936C18.7323 7.17517 18.7065 7.17605 18.6817 7.18196C18.6568 7.18787 18.6334 7.19868 18.6128 7.21376C18.5922 7.22885 18.5748 7.2479 18.5616 7.26979C18.5485 7.29169 18.5398 7.31599 18.5362 7.34128C18.5326 7.36404 18.5298 7.38692 18.5279 7.40988ZM20.6986 10.3736C20.7914 10.4189 20.9061 10.3855 20.9547 10.2991C21.0033 10.213 20.9675 10.1064 20.8746 10.061C20.5219 9.88963 20.2211 9.69933 19.9686 9.49278C19.9299 9.46178 19.8811 9.44626 19.8316 9.44923C19.7822 9.4522 19.7355 9.47344 19.7008 9.50884C19.6845 9.52574 19.6719 9.5459 19.6638 9.568C19.6557 9.59009 19.6524 9.61364 19.654 9.63711C19.6556 9.66058 19.6622 9.68344 19.6732 9.70422C19.6842 9.725 19.6995 9.74323 19.718 9.75772C19.9936 9.98298 20.3195 10.1892 20.6988 10.3738L20.6986 10.3736ZM23.1801 11.5188C23.2048 11.5264 23.2308 11.5289 23.2565 11.5263C23.2822 11.5238 23.3072 11.5161 23.3299 11.5038C23.3527 11.4915 23.3727 11.4748 23.389 11.4546C23.4052 11.4345 23.4172 11.4113 23.4244 11.3865C23.4399 11.3362 23.435 11.2819 23.4107 11.2352C23.3865 11.1886 23.3448 11.1533 23.2948 11.1371C22.9212 11.0216 22.5486 10.903 22.177 10.7814C22.1524 10.7735 22.1264 10.7705 22.1007 10.7727C22.0749 10.7749 22.0498 10.7822 22.0269 10.7941C22.004 10.8061 21.9837 10.8225 21.9672 10.8425C21.9507 10.8624 21.9383 10.8854 21.9308 10.9101C21.9146 10.9602 21.9187 11.0146 21.9423 11.0616C21.966 11.1087 22.0072 11.1445 22.057 11.1614C22.3837 11.269 22.606 11.3391 23.1801 11.5188ZM25.4353 12.2611C25.5204 12.3076 25.6285 12.2796 25.6772 12.1987C25.6887 12.1795 25.6962 12.158 25.6991 12.1358C25.7021 12.1135 25.7004 12.0909 25.6943 12.0692C25.6882 12.0476 25.6777 12.0275 25.6635 12.0101C25.6493 11.9927 25.6318 11.9784 25.6118 11.968C25.3295 11.8132 25.0086 11.676 24.6165 11.5381C24.5246 11.5059 24.4228 11.5507 24.389 11.6382C24.3549 11.7259 24.4022 11.823 24.4938 11.8554C24.8688 11.9871 25.1723 12.1169 25.4353 12.2611ZM27.2083 14.2457C27.247 14.3391 27.3614 14.3859 27.4632 14.3504C27.5653 14.3149 27.6163 14.2106 27.5776 14.1172C27.4169 13.7302 27.2274 13.3999 27.0036 13.1147C26.94 13.0336 26.8166 13.0151 26.7279 13.0735C26.6393 13.1317 26.6193 13.2447 26.6829 13.3258C26.8859 13.5843 27.0594 13.887 27.2083 14.2457ZM27.7057 16.8237C27.7091 16.9282 27.813 17.0108 27.9378 17.008C28.0625 17.005 28.1607 16.9178 28.1575 16.8133C28.1437 16.3968 28.1065 16.0185 28.04 15.6568C28.0209 15.5534 27.9054 15.4824 27.782 15.4984C27.6588 15.5143 27.5742 15.6113 27.5932 15.7146C27.6567 16.0595 27.6925 16.4224 27.7057 16.8237Z" fill="#EEEEEE"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M27.6172 18.4687C27.6047 18.7996 27.5957 19.1305 27.5903 19.4616C27.589 19.5661 27.6652 19.6521 27.7608 19.6536C27.8564 19.6551 27.9352 19.5718 27.9365 19.4675C27.9403 19.1902 27.9471 18.9608 27.9634 18.4827L27.9683 18.3378C27.9717 18.2334 27.897 18.1458 27.8016 18.142C27.706 18.1382 27.6257 18.2195 27.6221 18.324L27.6172 18.4687ZM27.7678 22.1483C27.7905 22.2513 27.895 22.3168 28.0014 22.2951C28.1076 22.2732 28.1754 22.1721 28.1529 22.0691C28.0741 21.71 28.0187 21.3434 27.9834 20.9609C27.9736 20.8562 27.878 20.7788 27.7697 20.7882C27.6614 20.7977 27.5815 20.8903 27.5911 20.995C27.6279 21.3922 27.6856 21.7737 27.7678 22.1483ZM28.7232 24.4772C28.7792 24.563 28.9033 24.5925 29.0005 24.543C29.0976 24.4937 29.1309 24.3841 29.0751 24.2983C28.8775 23.9966 28.7013 23.6814 28.5479 23.3551C28.505 23.2634 28.3863 23.22 28.2827 23.2578C28.1792 23.2956 28.1297 23.4004 28.1728 23.4919C28.333 23.8328 28.5169 24.1621 28.7232 24.4772ZM29.633 25.9325C29.8392 26.1713 30.063 26.3944 30.3025 26.5998C30.3398 26.6315 30.3877 26.6478 30.4366 26.6455C30.4855 26.6432 30.5317 26.6224 30.5658 26.5873C30.5821 26.5704 30.5948 26.5503 30.603 26.5282C30.6113 26.5062 30.6149 26.4827 30.6136 26.4592C30.6124 26.4357 30.6063 26.4127 30.5958 26.3916C30.5853 26.3706 30.5706 26.3519 30.5525 26.3368C30.3268 26.1431 30.1158 25.9329 29.9214 25.7078C29.8848 25.6652 29.8485 25.6222 29.8125 25.579C29.7807 25.5418 29.7359 25.5182 29.6872 25.5129C29.6386 25.5075 29.5897 25.5209 29.5506 25.5502C29.5315 25.5641 29.5156 25.5818 29.5036 25.6021C29.4917 25.6224 29.4841 25.645 29.4812 25.6684C29.4784 25.6918 29.4804 25.7155 29.4871 25.7381C29.4939 25.7607 29.5052 25.7816 29.5204 25.7997C29.5574 25.8439 29.5948 25.8883 29.633 25.9325ZM32.6235 28.1392C32.7142 28.1849 32.8223 28.1424 32.8647 28.0445C32.907 27.9463 32.8677 27.8299 32.777 27.7841C32.4527 27.6215 32.1381 27.4403 31.8347 27.2414C31.7491 27.1851 31.6375 27.2142 31.5853 27.3066C31.5331 27.3988 31.5602 27.5194 31.6458 27.5757C31.9605 27.7823 32.287 27.9704 32.6235 28.1392Z" fill="#E5E5E5"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M35.2883 29.0967C35.3928 29.1234 35.4977 29.054 35.5225 28.9418C35.5472 28.8293 35.4828 28.7165 35.3783 28.6898C35.0044 28.5945 34.6348 28.4834 34.2703 28.3567C34.1683 28.3212 34.0587 28.3812 34.0254 28.4912C33.9923 28.601 34.0483 28.7189 34.1505 28.7545C34.5248 28.8846 34.9044 28.9987 35.2883 29.0965V29.0967ZM37.7828 29.48C37.8875 29.4875 37.9775 29.3959 37.9841 29.2753C37.9907 29.1545 37.9111 29.0508 37.8066 29.0432C37.4321 29.0161 37.0589 28.9735 36.6879 28.9155C36.584 28.8992 36.4885 28.9831 36.4744 29.1028C36.4604 29.2226 36.5329 29.3327 36.6369 29.349C37.0169 29.4085 37.3993 29.4522 37.783 29.48H37.7828ZM40.464 29.2169C40.568 29.2065 40.6417 29.1305 40.6286 29.0468C40.6158 28.9635 40.5211 28.9041 40.4174 28.9145C40.0551 28.9508 39.6817 28.975 39.3005 28.9867C39.1958 28.9899 39.1144 29.0608 39.1185 29.1449C39.1225 29.229 39.2105 29.2946 39.3151 29.2912C39.6988 29.2795 40.082 29.2548 40.464 29.2169ZM43.156 28.7148C43.2562 28.6732 43.3026 28.5606 43.2599 28.4631C43.2385 28.4159 43.1995 28.379 43.1513 28.3601C43.1031 28.3412 43.0494 28.3419 43.0016 28.362C42.6464 28.5079 42.2817 28.6294 41.9099 28.7254C41.8852 28.7315 41.862 28.7424 41.8416 28.7575C41.8212 28.7727 41.804 28.7918 41.7911 28.8136C41.7781 28.8355 41.7696 28.8597 41.7662 28.8849C41.7627 28.9101 41.7643 28.9357 41.7708 28.9603C41.7991 29.0627 41.9071 29.1234 42.0121 29.0958C42.4018 28.9951 42.784 28.8678 43.1562 28.7148H43.156ZM45.326 26.9135C45.3812 26.8313 45.354 26.7234 45.2656 26.6721C45.1767 26.6211 45.0601 26.6461 45.0049 26.7283C44.8241 26.9974 44.5845 27.2449 44.2899 27.4691C44.2709 27.4827 44.255 27.5003 44.2433 27.5205C44.2316 27.5407 44.2242 27.5632 44.2218 27.5864C44.2193 27.6097 44.2218 27.6332 44.229 27.6554C44.2362 27.6777 44.2481 27.6981 44.2638 27.7155C44.3299 27.7903 44.449 27.8011 44.5299 27.7397C44.8555 27.4921 45.1225 27.216 45.326 26.9135ZM46.8046 25.0747C46.8407 25.0429 46.8628 24.998 46.866 24.9499C46.8692 24.9018 46.8532 24.8544 46.8216 24.8181C46.8059 24.8001 46.7869 24.7854 46.7655 24.7748C46.7441 24.7642 46.7209 24.758 46.6971 24.7564C46.6733 24.7548 46.6494 24.7579 46.6268 24.7656C46.6043 24.7733 46.5834 24.7853 46.5655 24.8011C46.2859 25.0458 46.0227 25.3086 45.7775 25.5878C45.7458 25.6241 45.7297 25.6716 45.7329 25.7197C45.736 25.7678 45.7581 25.8127 45.7943 25.8446C45.8122 25.8604 45.833 25.8724 45.8556 25.8801C45.8781 25.8878 45.902 25.891 45.9257 25.8894C45.9495 25.8878 45.9728 25.8816 45.9941 25.871C46.0155 25.8604 46.0345 25.8458 46.0502 25.8278C46.2849 25.5606 46.5368 25.309 46.8044 25.0747H46.8046ZM49.036 23.5975C49.126 23.5489 49.1602 23.4354 49.1125 23.3439C49.1015 23.3222 49.0862 23.303 49.0676 23.2873C49.049 23.2716 49.0275 23.2598 49.0043 23.2526C48.9811 23.2453 48.9566 23.2428 48.9324 23.2451C48.9082 23.2474 48.8847 23.2545 48.8633 23.266C48.5322 23.4443 48.2091 23.6372 47.8952 23.8441C47.8099 23.9004 47.7856 24.0167 47.8409 24.1036C47.8965 24.1905 48.0106 24.2151 48.096 24.1588C48.4009 23.9579 48.7145 23.7706 49.036 23.5975ZM51.454 22.4735C51.5579 22.4415 51.6148 22.3367 51.581 22.239C51.5471 22.1411 51.4354 22.0878 51.3315 22.1195C50.9508 22.236 50.5742 22.3654 50.2024 22.5077C50.1011 22.5464 50.0523 22.6551 50.0935 22.7501C50.1347 22.8454 50.2504 22.8911 50.3517 22.8524C50.7147 22.7135 51.0823 22.5872 51.454 22.4735Z" fill="#EEEEEE"/>
-<path d="M27.7796 18.3307C28.3014 18.3307 28.7244 17.9076 28.7244 17.3858C28.7244 16.864 28.3014 16.4409 27.7796 16.4409C27.2577 16.4409 26.8347 16.864 26.8347 17.3858C26.8347 17.9076 27.2577 18.3307 27.7796 18.3307Z" fill="white" stroke="#EEEEEE"/>
-<path d="M45.3543 27.4016C45.8761 27.4016 46.2992 26.9786 46.2992 26.4567C46.2992 25.9349 45.8761 25.5118 45.3543 25.5118C44.8325 25.5118 44.4094 25.9349 44.4094 26.4567C44.4094 26.9786 44.8325 27.4016 45.3543 27.4016Z" fill="white" stroke="#EEEEEE"/>
-<path d="M4.16876 10.9607C4.16876 10.9607 0.867338 17.1969 1.90104 20.9764C2.93474 24.756 5.11364 27.0237 9.08214 29.2914C13.0506 31.5591 15.2125 28.3465 20.5984 30.4253C25.9842 32.504 26.0787 38.5513 26.0787 38.5513" stroke="#B5A7DD" stroke-width="0.4" stroke-linecap="round" stroke-dasharray="8 10"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M49.8898 47.6221C49.8898 39.5857 43.375 33.0709 35.3386 33.0709C27.3022 33.0709 20.7874 39.5857 20.7874 47.6221" fill="white"/>
-<path d="M49.8898 47.6221C49.8898 39.5857 43.375 33.0709 35.3386 33.0709C27.3022 33.0709 20.7874 39.5857 20.7874 47.6221" stroke="#EEEEEE" stroke-linecap="round"/>
-<path d="M41.1969 43.8425C42.8668 43.8425 44.2205 42.4888 44.2205 40.8189C44.2205 39.149 42.8668 37.7953 41.1969 37.7953C39.527 37.7953 38.1732 39.149 38.1732 40.8189C38.1732 42.4888 39.527 43.8425 41.1969 43.8425Z" stroke="#EEEEEE"/>
-<path d="M28.8189 40.441C29.7061 40.441 30.4252 39.7218 30.4252 38.8347C30.4252 37.9476 29.7061 37.2284 28.8189 37.2284C27.9318 37.2284 27.2126 37.9476 27.2126 38.8347C27.2126 39.7218 27.9318 40.441 28.8189 40.441Z" stroke="#EEEEEE"/>
-<path d="M24.9449 44.9764C25.4667 44.9764 25.8898 44.5534 25.8898 44.0316C25.8898 43.5097 25.4667 43.0867 24.9449 43.0867C24.423 43.0867 24 43.5097 24 44.0316C24 44.5534 24.423 44.9764 24.9449 44.9764Z" stroke="#EEEEEE"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M45.703 3.43286L46.1389 3.54966C46.346 2.7768 47.1318 2.3159 47.8939 2.5201L48.0123 2.078C47.0096 1.80933 45.9757 2.416 45.7032 3.43291L45.703 3.43286Z" fill="#FC8A51"/>
-<path d="M47.9471 2.61347C48.1478 2.66723 48.3546 2.54588 48.4091 2.34244C48.4636 2.139 48.3452 1.93051 48.1445 1.87675C47.9439 1.823 47.7371 1.94434 47.6826 2.14778C47.6281 2.35122 47.7465 2.55972 47.9471 2.61347Z" fill="#FC8A51"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M45.412 3.35511L44.9761 3.23831C45.1832 2.46545 44.7332 1.67342 43.9711 1.46921L44.0896 1.02711C45.0922 1.29577 45.6843 2.33814 45.4119 3.35506L45.412 3.35511Z" fill="#FC8A51"/>
-<path d="M43.8787 1.52354C43.6781 1.46979 43.5597 1.26129 43.6142 1.05785C43.6687 0.854411 43.8755 0.733068 44.0761 0.786823C44.2768 0.840578 44.3952 1.04908 44.3407 1.25252C44.2862 1.45596 44.0794 1.5773 43.8787 1.52354Z" fill="#FC8A51"/>
-<path d="M47.8422 7.79545L46.7544 7.50399C46.6536 7.47698 46.55 7.5368 46.523 7.63762C46.496 7.73843 46.5558 7.84205 46.6566 7.86907L47.7444 8.16052C47.8452 8.18754 47.9488 8.12771 47.9758 8.0269C48.0028 7.92608 47.943 7.82246 47.8422 7.79545Z" fill="#FC8A51"/>
-<path d="M47.4759 9.27595L46.5007 8.7129C46.4103 8.66071 46.2947 8.69168 46.2425 8.78207C46.1904 8.87245 46.2213 8.98803 46.3117 9.04021L47.287 9.60327C47.3773 9.65545 47.4929 9.62448 47.5451 9.5341C47.5973 9.44371 47.5663 9.32813 47.4759 9.27595Z" fill="#FC8A51"/>
-<path d="M48.1795 6.35876L47.0534 6.35876C46.949 6.35876 46.8644 6.44337 46.8644 6.54774C46.8644 6.65211 46.949 6.73671 47.0534 6.73671L48.1795 6.73671C48.2839 6.73671 48.3685 6.6521 48.3685 6.54774C48.3685 6.44337 48.2839 6.35876 48.1795 6.35876Z" fill="#FC8A51"/>
-<path d="M41.3783 6.06356L42.4661 6.35502C42.5669 6.38203 42.6267 6.48565 42.5997 6.58647C42.5727 6.68728 42.469 6.74711 42.3682 6.72009L41.2805 6.42863C41.1797 6.40162 41.1198 6.298 41.1469 6.19719C41.1739 6.09637 41.2775 6.03655 41.3783 6.06356Z" fill="#FC8A51"/>
-<path d="M40.9549 7.52856L42.081 7.52856C42.1854 7.52856 42.27 7.61317 42.27 7.71754C42.27 7.82191 42.1854 7.90651 42.081 7.90651L40.9549 7.90651C40.8506 7.90651 40.7659 7.8219 40.7659 7.71754C40.7659 7.61317 40.8505 7.52856 40.9549 7.52856Z" fill="#FC8A51"/>
-<path d="M41.8041 4.65032L42.7794 5.21337C42.8698 5.26556 42.9007 5.38113 42.8485 5.47152C42.7964 5.5619 42.6808 5.59287 42.5904 5.54069L41.6151 4.97763C41.5248 4.92545 41.4938 4.80987 41.546 4.71949C41.5982 4.6291 41.7137 4.59813 41.8041 4.65032Z" fill="#FC8A51"/>
-<path d="M47.3515 6.28652C47.7063 4.96254 46.9206 3.60168 45.5967 3.24693C44.2728 2.89219 42.912 3.6779 42.5572 5.00187L42.1051 6.68907C41.7504 8.01304 42.536 9.3739 43.86 9.72865C45.1839 10.0834 46.5447 9.29768 46.8995 7.97371L47.3515 6.28652Z" stroke="#FC8A51"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M42.7135 5.00037L47.0721 6.16826L46.9254 6.71587L42.5668 5.54798L42.7135 5.00037Z" fill="#FC8A51"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M17.4662 2.50359L17.1869 2.57842C17.1557 2.46241 17.1019 2.35369 17.0286 2.25847C16.9554 2.16325 16.8641 2.0834 16.7599 2.02348C16.6558 1.96355 16.5409 1.92474 16.4217 1.90924C16.3026 1.89374 16.1816 1.90187 16.0656 1.93316L15.9909 1.6546C16.634 1.48229 17.2944 1.86252 17.4662 2.50359Z" fill="#EEEEEE"/>
-<path d="M16.0312 1.99224C15.9025 2.02671 15.7704 1.95069 15.736 1.82246C15.7017 1.69423 15.7781 1.56233 15.9067 1.52786C16.0354 1.4934 16.1675 1.56941 16.2019 1.69764C16.2362 1.82587 16.1598 1.95777 16.0312 1.99224Z" fill="#EEEEEE"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M17.6526 2.45366L17.9318 2.37883C17.9009 2.26274 17.8931 2.14169 17.909 2.02259C17.9248 1.9035 17.964 1.78869 18.0242 1.68473C18.0844 1.58076 18.1645 1.48969 18.2599 1.4167C18.3554 1.3437 18.4642 1.29023 18.5804 1.25932L18.5057 0.980773C17.8626 1.15308 17.4808 1.81259 17.6526 2.45366Z" fill="#EEEEEE"/>
-<path d="M18.6393 1.29344C18.7679 1.25898 18.8444 1.12708 18.81 0.998847C18.7756 0.870613 18.6435 0.794601 18.5149 0.82907C18.3862 0.863538 18.3098 0.995433 18.3442 1.12367C18.3785 1.2519 18.5107 1.32791 18.6393 1.29344Z" fill="#EEEEEE"/>
-<path d="M16.1505 5.24482L16.7167 5.0931C16.8175 5.06609 16.9211 5.12591 16.9481 5.22673C16.9752 5.32754 16.9153 5.43116 16.8145 5.45817L16.2483 5.60989C16.1475 5.63691 16.0439 5.57708 16.0168 5.47627C15.9898 5.37546 16.0497 5.27183 16.1505 5.24482Z" fill="#EEEEEE"/>
-<path d="M16.3578 6.1703L16.8655 5.8772C16.9559 5.82502 17.0714 5.85599 17.1236 5.94637C17.1758 6.03676 17.1448 6.15233 17.0545 6.20452L16.5468 6.49762C16.4564 6.5498 16.3408 6.51883 16.2886 6.42845C16.2365 6.33806 16.2674 6.22249 16.3578 6.1703Z" fill="#EEEEEE"/>
-<path d="M15.9573 4.35278L16.5435 4.35278C16.6479 4.35278 16.7325 4.43739 16.7325 4.54176C16.7325 4.64613 16.6479 4.73074 16.5435 4.73074L15.9573 4.73074C15.853 4.73074 15.7684 4.64613 15.7684 4.54176C15.7684 4.43739 15.853 4.35278 15.9573 4.35278Z" fill="#EEEEEE"/>
-<path d="M20.1626 4.16985L19.5964 4.32157C19.4956 4.34859 19.4357 4.45221 19.4628 4.55302C19.4898 4.65383 19.5934 4.71366 19.6942 4.68665L20.2604 4.53493C20.3612 4.50791 20.4211 4.40429 20.3941 4.30348C20.367 4.20267 20.2634 4.14284 20.1626 4.16985Z" fill="#EEEEEE"/>
-<path d="M20.4451 5.07507L19.8589 5.07507C19.7545 5.07507 19.6699 5.15968 19.6699 5.26405C19.6699 5.36842 19.7545 5.45303 19.8589 5.45303L20.4451 5.45303C20.5494 5.45303 20.634 5.36842 20.634 5.26405C20.634 5.15968 20.5494 5.07507 20.4451 5.07507Z" fill="#EEEEEE"/>
-<path d="M19.8834 3.30076L19.3757 3.59387C19.2853 3.64605 19.2543 3.76163 19.3065 3.85201C19.3587 3.9424 19.4743 3.97337 19.5647 3.92118L20.0723 3.62808C20.1627 3.5759 20.1937 3.46032 20.1415 3.36993C20.0893 3.27955 19.9737 3.24858 19.8834 3.30076Z" fill="#EEEEEE"/>
-<path d="M17.5341 2.38566L17.5343 2.38561C18.3829 2.15821 19.2552 2.66184 19.4826 3.51048L19.7541 4.52356C19.9815 5.3722 19.4778 6.24449 18.6292 6.47189L18.629 6.47193C17.7804 6.69933 16.9081 6.19571 16.6807 5.34707L16.4092 4.33398C16.1819 3.48534 16.6855 2.61305 17.5341 2.38566Z" stroke="#EEEEEE"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M19.3759 3.48474L16.582 4.23337L16.6798 4.59844L19.4737 3.84982L19.3759 3.48474Z" fill="#EEEEEE"/>
-<path d="M1.98426 23.0551C2.87139 23.0551 3.59056 22.336 3.59056 21.4488C3.59056 20.5617 2.87139 19.8425 1.98426 19.8425C1.09712 19.8425 0.37796 20.5617 0.37796 21.4488C0.37796 22.336 1.09712 23.0551 1.98426 23.0551Z" fill="white" stroke="#B5A7DD" stroke-width="0.4"/>
-<path d="M32.7874 24.9449C33.4658 24.9449 34.0158 24.3949 34.0158 23.7165C34.0158 23.0381 33.4658 22.4882 32.7874 22.4882C32.109 22.4882 31.5591 23.0381 31.5591 23.7165C31.5591 24.3949 32.109 24.9449 32.7874 24.9449Z" fill="white"/>
-<path d="M10.1102 31.9371C11.4148 31.9371 12.4724 30.8795 12.4724 29.5749C12.4724 28.2702 11.4148 27.2126 10.1102 27.2126C8.80561 27.2126 7.74802 28.2702 7.74802 29.5749C7.74802 30.8795 8.80561 31.9371 10.1102 31.9371Z" fill="white" stroke="#6B4FBB"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M9.77635 29.759L9.44262 29.4251C9.38944 29.3719 9.31732 29.3421 9.24211 29.3421C9.16691 29.3421 9.09479 29.3719 9.04161 29.4251C8.98843 29.4783 8.95856 29.5504 8.95856 29.6256C8.95856 29.7008 8.98843 29.773 9.04161 29.8261L9.57566 30.3602H9.57585V30.3604C9.68734 30.4719 9.86592 30.4713 9.97629 30.3609L11.1801 29.1572C11.2328 29.1038 11.2623 29.0319 11.2622 28.9569C11.2621 28.8819 11.2324 28.8101 11.1795 28.7569C11.1533 28.7305 11.1222 28.7095 11.0879 28.6952C11.0535 28.6808 11.0167 28.6734 10.9795 28.6733C10.9423 28.6733 10.9055 28.6805 10.8711 28.6948C10.8368 28.709 10.8055 28.7298 10.7792 28.7561L9.77635 29.759Z" fill="#FC8A51"/>
-<path d="M32.7874 24.7559C33.4658 24.7559 34.0158 24.2059 34.0158 23.5275C34.0158 22.8491 33.4658 22.2992 32.7874 22.2992C32.109 22.2992 31.5591 22.8491 31.5591 23.5275C31.5591 24.2059 32.109 24.7559 32.7874 24.7559Z" fill="white" stroke="#FC8A51"/>
-<path d="M4.53541 11.3386C5.16162 11.3386 5.66926 10.831 5.66926 10.2048C5.66926 9.57857 5.16162 9.07092 4.53541 9.07092C3.9092 9.07092 3.40155 9.57857 3.40155 10.2048C3.40155 10.831 3.9092 11.3386 4.53541 11.3386Z" fill="white" stroke="#B5A7DD" stroke-width="0.4"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M35.9339 27.1363C37.5787 25.6725 38.0151 23.182 36.8527 21.1688C35.5261 18.8708 32.6187 18.0654 30.3591 19.3701C28.0993 20.6748 27.343 23.5953 28.6698 25.8932C29.8483 27.9342 32.2732 28.7978 34.3841 28.0513L36.4437 31.619C36.563 31.8259 36.7596 31.9769 36.9903 32.0389C37.2209 32.1008 37.4667 32.0686 37.6736 31.9493C37.8802 31.8297 38.0309 31.6329 38.0926 31.4023C38.1542 31.1716 38.1218 30.9259 38.0024 30.7191L35.9339 27.1363ZM34.34 26.2653C35.8248 25.4081 36.3218 23.4889 35.4499 21.9788C34.5782 20.4686 32.6676 19.9395 31.1828 20.7967C29.6978 21.6541 29.2008 23.5733 30.0726 25.0834C30.9445 26.5934 32.8551 27.1227 34.34 26.2653Z" fill="white" stroke="#B5A7DD" stroke-width="0.5"/>
-</g>
-<defs>
-<clipPath id="clip0">
-<rect width="80.315" height="48" fill="white"/>
-</clipPath>
-</defs>
-</svg>
diff --git a/app/assets/images/learn_gitlab/merge_request_created.svg b/app/assets/images/learn_gitlab/merge_request_created.svg
deleted file mode 100644
index b8137a60f06..00000000000
--- a/app/assets/images/learn_gitlab/merge_request_created.svg
+++ /dev/null
@@ -1,107 +0,0 @@
-<svg width="79" height="47" viewBox="0 0 79 47" fill="none" xmlns="http://www.w3.org/2000/svg">
-<g clip-path="url(#clip0)">
-<path d="M27.0655 1.96289H5.80354C4.48549 1.96289 3.41699 3.03139 3.41699 4.34944C3.41699 5.6675 4.48549 6.73599 5.80354 6.73599H27.0655C28.3836 6.73599 29.4521 5.6675 29.4521 4.34944C29.4521 3.03139 28.3836 1.96289 27.0655 1.96289Z" fill="#F9F9F9"/>
-<path d="M23.1603 11.5092H-0.705247C-2.0233 11.5092 -3.0918 12.5776 -3.0918 13.8957C-3.0918 15.2138 -2.0233 16.2823 -0.705247 16.2823H23.1603C24.4783 16.2823 25.5468 15.2138 25.5468 13.8957C25.5468 12.5776 24.4783 11.5092 23.1603 11.5092Z" fill="#F9F9F9"/>
-<path d="M80.8713 16.2822H44.4222C43.1041 16.2822 42.0356 17.3507 42.0356 18.6688C42.0356 19.9868 43.1041 21.0553 44.4222 21.0553H80.8713C82.1894 21.0553 83.2579 19.9868 83.2579 18.6688C83.2579 17.3507 82.1894 16.2822 80.8713 16.2822Z" fill="#F9F9F9"/>
-<path d="M56.789 44.7039H27.2825C25.9645 44.7039 24.896 45.7724 24.896 47.0904C24.896 48.4085 25.9645 49.477 27.2825 49.477H56.789C58.107 49.477 59.1755 48.4085 59.1755 47.0904C59.1755 45.7724 58.107 44.7039 56.789 44.7039Z" fill="#F9F9F9"/>
-<path d="M43.1205 35.3746H13.6141C12.296 35.3746 11.2275 36.4431 11.2275 37.7612C11.2275 39.0792 12.296 40.1477 13.6141 40.1477H43.1205C44.4386 40.1477 45.5071 39.0792 45.5071 37.7612C45.5071 36.4431 44.4386 35.3746 43.1205 35.3746Z" fill="#F9F9F9"/>
-<path d="M77.1829 25.8284H6.02034C4.70228 25.8284 3.63379 26.8969 3.63379 28.2149C3.63379 29.533 4.70228 30.6015 6.02034 30.6015H77.1829C78.501 30.6015 79.5695 29.533 79.5695 28.2149C79.5695 26.8969 78.501 25.8284 77.1829 25.8284Z" fill="#F9F9F9"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M30.103 6.73596H1.46436H6.12898C7.43073 6.73596 8.51553 7.82076 8.51553 9.12251C8.51553 10.4243 7.43073 11.5091 6.12898 11.5091H1.46436H30.103H22.1839C20.8822 11.5091 19.7974 10.4243 19.7974 9.12251C19.7974 7.82076 20.8822 6.73596 22.1839 6.73596H30.103ZM84.7766 21.0553H59.3924H67.3114C68.6132 21.0553 69.698 22.1401 69.698 23.4418C69.698 24.7436 68.6132 25.8284 67.3114 25.8284H59.3924H84.7766H76.8576C75.5559 25.8284 74.4711 24.7436 74.4711 23.4418C74.4711 22.1401 75.5559 21.0553 76.8576 21.0553H84.7766ZM31.8386 30.6015H6.45441H14.3734C15.6752 30.6015 16.76 31.6862 16.76 32.988C16.76 34.2898 15.6752 35.3746 14.3734 35.3746H6.45441H31.8386H23.9196C22.6179 35.3746 21.5331 34.2898 21.5331 32.988C21.5331 31.6862 22.6179 30.6015 23.9196 30.6015H31.8386ZM48.1106 40.1477H22.7263H27.391C28.6927 40.1477 29.7775 41.2324 29.7775 42.5342C29.7775 43.836 28.6927 44.9207 27.391 44.9207H22.7263H48.1106H36.9372C35.6354 44.9207 34.5506 43.836 34.5506 42.5342C34.5506 41.2324 35.6354 40.1477 36.9372 40.1477H48.1106Z" fill="#F9F9F9"/>
-<path d="M68.0708 4.78333H12.0954C10.8971 4.78333 9.92578 5.75468 9.92578 6.95292V41.4494C9.92578 42.6476 10.8971 43.619 12.0954 43.619H68.0708C69.269 43.619 70.2404 42.6476 70.2404 41.4494V6.95292C70.2404 5.75468 69.269 4.78333 68.0708 4.78333Z" fill="white" stroke="#EEEEEE" stroke-width="2"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M10.7935 11.0751H69.5894V11.9429H10.7935V11.0751Z" fill="#EEEEEE"/>
-<path d="M18.387 18.0178H17.5192C17.3994 18.0178 17.3022 18.115 17.3022 18.2348C17.3022 18.3546 17.3994 18.4517 17.5192 18.4517H18.387C18.5069 18.4517 18.604 18.3546 18.604 18.2348C18.604 18.115 18.5069 18.0178 18.387 18.0178Z" fill="#B5A7DD"/>
-<path d="M23.3771 17.8009H20.9906C20.7509 17.8009 20.5566 17.9952 20.5566 18.2348C20.5566 18.4745 20.7509 18.6687 20.9906 18.6687H23.3771C23.6167 18.6687 23.811 18.4745 23.811 18.2348C23.811 17.9952 23.6167 17.8009 23.3771 17.8009Z" fill="#EEEEEE"/>
-<path d="M35.7438 17.8009H33.3573C33.1176 17.8009 32.9233 17.9952 32.9233 18.2348C32.9233 18.4745 33.1176 18.6687 33.3573 18.6687H35.7438C35.9835 18.6687 36.1777 18.4745 36.1777 18.2348C36.1777 17.9952 35.9835 17.8009 35.7438 17.8009Z" fill="#EEEEEE"/>
-<path d="M28.5841 22.574H26.1976C25.9579 22.574 25.7637 22.7682 25.7637 23.0079C25.7637 23.2475 25.9579 23.4418 26.1976 23.4418H28.5841C28.8238 23.4418 29.0181 23.2475 29.0181 23.0079C29.0181 22.7682 28.8238 22.574 28.5841 22.574Z" fill="#EEEEEE"/>
-<path d="M31.6217 20.1875H29.2352C28.9955 20.1875 28.8013 20.3818 28.8013 20.6214C28.8013 20.8611 28.9955 21.0553 29.2352 21.0553H31.6217C31.8614 21.0553 32.0557 20.8611 32.0557 20.6214C32.0557 20.3818 31.8614 20.1875 31.6217 20.1875Z" fill="#FC6D26"/>
-<path opacity="0.5" d="M31.6216 17.8009H28.1502C27.9106 17.8009 27.7163 17.9952 27.7163 18.2348C27.7163 18.4745 27.9106 18.6687 28.1502 18.6687H31.6216C31.8612 18.6687 32.0555 18.4745 32.0555 18.2348C32.0555 17.9952 31.8612 17.8009 31.6216 17.8009Z" fill="#FC6D26"/>
-<path d="M24.4619 22.574H20.9906C20.7509 22.574 20.5566 22.7682 20.5566 23.0079C20.5566 23.2475 20.7509 23.4418 20.9906 23.4418H24.4619C24.7016 23.4418 24.8958 23.2475 24.8958 23.0079C24.8958 22.7682 24.7016 22.574 24.4619 22.574Z" fill="#EEEEEE"/>
-<path d="M27.4995 20.1875H24.0282C23.7885 20.1875 23.5942 20.3818 23.5942 20.6214C23.5942 20.8611 23.7885 21.0553 24.0282 21.0553H27.4995C27.7392 21.0553 27.9334 20.8611 27.9334 20.6214C27.9334 20.3818 27.7392 20.1875 27.4995 20.1875Z" fill="#EEEEEE"/>
-<path d="M26.4144 17.8009H25.1126C24.873 17.8009 24.6787 17.9952 24.6787 18.2348C24.6787 18.4745 24.873 18.6687 25.1126 18.6687H26.4144C26.654 18.6687 26.8483 18.4745 26.8483 18.2348C26.8483 17.9952 26.654 17.8009 26.4144 17.8009Z" fill="#FC6D26"/>
-<path d="M22.2923 20.1875H20.9906C20.7509 20.1875 20.5566 20.3818 20.5566 20.6214C20.5566 20.8611 20.7509 21.0553 20.9906 21.0553H22.2923C22.532 21.0553 22.7262 20.8611 22.7262 20.6214C22.7262 20.3818 22.532 20.1875 22.2923 20.1875Z" fill="#EEEEEE"/>
-<path d="M18.387 20.4044H17.5192C17.3994 20.4044 17.3022 20.5016 17.3022 20.6214C17.3022 20.7412 17.3994 20.8383 17.5192 20.8383H18.387C18.5069 20.8383 18.604 20.7412 18.604 20.6214C18.604 20.5016 18.5069 20.4044 18.387 20.4044Z" fill="#B5A7DD"/>
-<path d="M18.387 22.791H17.5192C17.3994 22.791 17.3022 22.8882 17.3022 23.008C17.3022 23.1278 17.3994 23.2249 17.5192 23.2249H18.387C18.5069 23.2249 18.604 23.1278 18.604 23.008C18.604 22.8882 18.5069 22.791 18.387 22.791Z" fill="#B5A7DD"/>
-<path d="M18.387 25.1774H17.5192C17.3994 25.1774 17.3022 25.2745 17.3022 25.3943C17.3022 25.5142 17.3994 25.6113 17.5192 25.6113H18.387C18.5069 25.6113 18.604 25.5142 18.604 25.3943C18.604 25.2745 18.5069 25.1774 18.387 25.1774Z" fill="#B5A7DD"/>
-<path d="M23.3771 24.9604H20.9906C20.7509 24.9604 20.5566 25.1547 20.5566 25.3944C20.5566 25.634 20.7509 25.8283 20.9906 25.8283H23.3771C23.6167 25.8283 23.811 25.634 23.811 25.3944C23.811 25.1547 23.6167 24.9604 23.3771 24.9604Z" fill="#FC6D26"/>
-<path d="M35.7438 24.9604H33.3573C33.1176 24.9604 32.9233 25.1547 32.9233 25.3944C32.9233 25.634 33.1176 25.8283 33.3573 25.8283H35.7438C35.9835 25.8283 36.1777 25.634 36.1777 25.3944C36.1777 25.1547 35.9835 24.9604 35.7438 24.9604Z" fill="#EEEEEE"/>
-<path opacity="0.5" d="M28.5841 29.7335H26.1976C25.9579 29.7335 25.7637 29.9278 25.7637 30.1674C25.7637 30.4071 25.9579 30.6014 26.1976 30.6014H28.5841C28.8238 30.6014 29.0181 30.4071 29.0181 30.1674C29.0181 29.9278 28.8238 29.7335 28.5841 29.7335Z" fill="#FC6D26"/>
-<path d="M31.6217 27.347H29.2352C28.9955 27.347 28.8013 27.5413 28.8013 27.781C28.8013 28.0206 28.9955 28.2149 29.2352 28.2149H31.6217C31.8614 28.2149 32.0557 28.0206 32.0557 27.781C32.0557 27.5413 31.8614 27.347 31.6217 27.347Z" fill="#EEEEEE"/>
-<path d="M31.6216 24.9604H28.1502C27.9106 24.9604 27.7163 25.1547 27.7163 25.3944C27.7163 25.634 27.9106 25.8283 28.1502 25.8283H31.6216C31.8612 25.8283 32.0555 25.634 32.0555 25.3944C32.0555 25.1547 31.8612 24.9604 31.6216 24.9604Z" fill="#FC6D26"/>
-<path d="M24.4619 29.7335H20.9906C20.7509 29.7335 20.5566 29.9278 20.5566 30.1674C20.5566 30.4071 20.7509 30.6014 20.9906 30.6014H24.4619C24.7016 30.6014 24.8958 30.4071 24.8958 30.1674C24.8958 29.9278 24.7016 29.7335 24.4619 29.7335Z" fill="#FC6D26"/>
-<path d="M27.4995 27.347H24.0282C23.7885 27.347 23.5942 27.5413 23.5942 27.781C23.5942 28.0206 23.7885 28.2149 24.0282 28.2149H27.4995C27.7392 28.2149 27.9334 28.0206 27.9334 27.781C27.9334 27.5413 27.7392 27.347 27.4995 27.347Z" fill="#EEEEEE"/>
-<path opacity="0.5" d="M26.4144 24.9604H25.1126C24.873 24.9604 24.6787 25.1547 24.6787 25.3944C24.6787 25.634 24.873 25.8283 25.1126 25.8283H26.4144C26.654 25.8283 26.8483 25.634 26.8483 25.3944C26.8483 25.1547 26.654 24.9604 26.4144 24.9604Z" fill="#FC6D26"/>
-<path d="M22.2923 27.347H20.9906C20.7509 27.347 20.5566 27.5413 20.5566 27.781C20.5566 28.0206 20.7509 28.2149 20.9906 28.2149H22.2923C22.532 28.2149 22.7262 28.0206 22.7262 27.781C22.7262 27.5413 22.532 27.347 22.2923 27.347Z" fill="#EEEEEE"/>
-<path d="M18.387 27.564H17.5192C17.3994 27.564 17.3022 27.6611 17.3022 27.7809C17.3022 27.9007 17.3994 27.9979 17.5192 27.9979H18.387C18.5069 27.9979 18.604 27.9007 18.604 27.7809C18.604 27.6611 18.5069 27.564 18.387 27.564Z" fill="#B5A7DD"/>
-<path d="M18.387 29.9506H17.5192C17.3994 29.9506 17.3022 30.0477 17.3022 30.1675C17.3022 30.2873 17.3994 30.3845 17.5192 30.3845H18.387C18.5069 30.3845 18.604 30.2873 18.604 30.1675C18.604 30.0477 18.5069 29.9506 18.387 29.9506Z" fill="#B5A7DD"/>
-<path d="M18.387 32.337H17.5192C17.3994 32.337 17.3022 32.4342 17.3022 32.554C17.3022 32.6738 17.3994 32.771 17.5192 32.771H18.387C18.5069 32.771 18.604 32.6738 18.604 32.554C18.604 32.4342 18.5069 32.337 18.387 32.337Z" fill="#B5A7DD"/>
-<path d="M23.3771 32.1201H20.9906C20.7509 32.1201 20.5566 32.3144 20.5566 32.554C20.5566 32.7937 20.7509 32.988 20.9906 32.988H23.3771C23.6167 32.988 23.811 32.7937 23.811 32.554C23.811 32.3144 23.6167 32.1201 23.3771 32.1201Z" fill="#EEEEEE"/>
-<path d="M35.7438 32.1201H33.3573C33.1176 32.1201 32.9233 32.3144 32.9233 32.554C32.9233 32.7937 33.1176 32.988 33.3573 32.988H35.7438C35.9835 32.988 36.1777 32.7937 36.1777 32.554C36.1777 32.3144 35.9835 32.1201 35.7438 32.1201Z" fill="#EEEEEE"/>
-<path d="M28.5841 36.8932H26.1976C25.9579 36.8932 25.7637 37.0875 25.7637 37.3271C25.7637 37.5668 25.9579 37.761 26.1976 37.761H28.5841C28.8238 37.761 29.0181 37.5668 29.0181 37.3271C29.0181 37.0875 28.8238 36.8932 28.5841 36.8932Z" fill="#EEEEEE"/>
-<path d="M31.6217 34.5067H29.2352C28.9955 34.5067 28.8013 34.701 28.8013 34.9406C28.8013 35.1803 28.9955 35.3745 29.2352 35.3745H31.6217C31.8614 35.3745 32.0557 35.1803 32.0557 34.9406C32.0557 34.701 31.8614 34.5067 31.6217 34.5067Z" fill="#EEEEEE"/>
-<path d="M31.6216 32.1201H28.1502C27.9106 32.1201 27.7163 32.3144 27.7163 32.554C27.7163 32.7937 27.9106 32.988 28.1502 32.988H31.6216C31.8612 32.988 32.0555 32.7937 32.0555 32.554C32.0555 32.3144 31.8612 32.1201 31.6216 32.1201Z" fill="#FC6D26"/>
-<path d="M24.4619 36.8932H20.9906C20.7509 36.8932 20.5566 37.0875 20.5566 37.3271C20.5566 37.5668 20.7509 37.761 20.9906 37.761H24.4619C24.7016 37.761 24.8958 37.5668 24.8958 37.3271C24.8958 37.0875 24.7016 36.8932 24.4619 36.8932Z" fill="#EEEEEE"/>
-<path d="M27.4995 34.5067H24.0282C23.7885 34.5067 23.5942 34.701 23.5942 34.9406C23.5942 35.1803 23.7885 35.3745 24.0282 35.3745H27.4995C27.7392 35.3745 27.9334 35.1803 27.9334 34.9406C27.9334 34.701 27.7392 34.5067 27.4995 34.5067Z" fill="#EEEEEE"/>
-<path opacity="0.5" d="M26.4144 32.1201H25.1126C24.873 32.1201 24.6787 32.3144 24.6787 32.554C24.6787 32.7937 24.873 32.988 25.1126 32.988H26.4144C26.654 32.988 26.8483 32.7937 26.8483 32.554C26.8483 32.3144 26.654 32.1201 26.4144 32.1201Z" fill="#FC6D26"/>
-<path d="M22.2923 34.5067H20.9906C20.7509 34.5067 20.5566 34.701 20.5566 34.9406C20.5566 35.1803 20.7509 35.3745 20.9906 35.3745H22.2923C22.532 35.3745 22.7262 35.1803 22.7262 34.9406C22.7262 34.701 22.532 34.5067 22.2923 34.5067Z" fill="#EEEEEE"/>
-<path d="M18.387 34.7236H17.5192C17.3994 34.7236 17.3022 34.8208 17.3022 34.9406C17.3022 35.0604 17.3994 35.1575 17.5192 35.1575H18.387C18.5069 35.1575 18.604 35.0604 18.604 34.9406C18.604 34.8208 18.5069 34.7236 18.387 34.7236Z" fill="#B5A7DD"/>
-<path d="M18.387 37.1102H17.5192C17.3994 37.1102 17.3022 37.2074 17.3022 37.3272C17.3022 37.447 17.3994 37.5442 17.5192 37.5442H18.387C18.5069 37.5442 18.604 37.447 18.604 37.3272C18.604 37.2074 18.5069 37.1102 18.387 37.1102Z" fill="#B5A7DD"/>
-<path d="M45.073 17.8008H44.2052C44.0854 17.8008 43.9883 17.8979 43.9883 18.0177C43.9883 18.1376 44.0854 18.2347 44.2052 18.2347H45.073C45.1929 18.2347 45.29 18.1376 45.29 18.0177C45.29 17.8979 45.1929 17.8008 45.073 17.8008Z" fill="#FDE5D8"/>
-<path d="M50.0631 17.5839H47.6766C47.4369 17.5839 47.2427 17.7781 47.2427 18.0178C47.2427 18.2574 47.4369 18.4517 47.6766 18.4517H50.0631C50.3028 18.4517 50.4971 18.2574 50.4971 18.0178C50.4971 17.7781 50.3028 17.5839 50.0631 17.5839Z" fill="#EEEEEE"/>
-<path d="M62.4299 17.5839H60.0433C59.8036 17.5839 59.6094 17.7781 59.6094 18.0178C59.6094 18.2574 59.8036 18.4517 60.0433 18.4517H62.4299C62.6695 18.4517 62.8638 18.2574 62.8638 18.0178C62.8638 17.7781 62.6695 17.5839 62.4299 17.5839Z" fill="#EEEEEE"/>
-<path opacity="0.5" d="M55.2702 22.3569H52.8836C52.644 22.3569 52.4497 22.5512 52.4497 22.7909C52.4497 23.0305 52.644 23.2248 52.8836 23.2248H55.2702C55.5098 23.2248 55.7041 23.0305 55.7041 22.7909C55.7041 22.5512 55.5098 22.3569 55.2702 22.3569Z" fill="#6B4FBB"/>
-<path d="M58.3078 19.9705H55.9212C55.6816 19.9705 55.4873 20.1647 55.4873 20.4044C55.4873 20.644 55.6816 20.8383 55.9212 20.8383H58.3078C58.5474 20.8383 58.7417 20.644 58.7417 20.4044C58.7417 20.1647 58.5474 19.9705 58.3078 19.9705Z" fill="#6B4FBB"/>
-<path opacity="0.5" d="M58.3076 17.5839H54.8363C54.5966 17.5839 54.4023 17.7781 54.4023 18.0178C54.4023 18.2574 54.5966 18.4517 54.8363 18.4517H58.3076C58.5473 18.4517 58.7415 18.2574 58.7415 18.0178C58.7415 17.7781 58.5473 17.5839 58.3076 17.5839Z" fill="#6B4FBB"/>
-<path d="M51.1479 22.3569H47.6766C47.4369 22.3569 47.2427 22.5512 47.2427 22.7909C47.2427 23.0305 47.4369 23.2248 47.6766 23.2248H51.1479C51.3876 23.2248 51.5819 23.0305 51.5819 22.7909C51.5819 22.5512 51.3876 22.3569 51.1479 22.3569Z" fill="#6B4FBB"/>
-<path d="M54.1855 19.9705H50.7142C50.4745 19.9705 50.2803 20.1647 50.2803 20.4044C50.2803 20.644 50.4745 20.8383 50.7142 20.8383H54.1855C54.4252 20.8383 54.6195 20.644 54.6195 20.4044C54.6195 20.1647 54.4252 19.9705 54.1855 19.9705Z" fill="#EEEEEE"/>
-<path d="M53.1004 17.5839H51.7987C51.559 17.5839 51.3647 17.7781 51.3647 18.0178C51.3647 18.2574 51.559 18.4517 51.7987 18.4517H53.1004C53.3401 18.4517 53.5343 18.2574 53.5343 18.0178C53.5343 17.7781 53.3401 17.5839 53.1004 17.5839Z" fill="#6B4FBB"/>
-<path d="M48.9783 19.9705H47.6766C47.4369 19.9705 47.2427 20.1647 47.2427 20.4044C47.2427 20.644 47.4369 20.8383 47.6766 20.8383H48.9783C49.218 20.8383 49.4123 20.644 49.4123 20.4044C49.4123 20.1647 49.218 19.9705 48.9783 19.9705Z" fill="#EEEEEE"/>
-<path d="M45.073 20.1874H44.2052C44.0854 20.1874 43.9883 20.2845 43.9883 20.4043C43.9883 20.5242 44.0854 20.6213 44.2052 20.6213H45.073C45.1929 20.6213 45.29 20.5242 45.29 20.4043C45.29 20.2845 45.1929 20.1874 45.073 20.1874Z" fill="#FDE5D8"/>
-<path d="M45.073 22.574H44.2052C44.0854 22.574 43.9883 22.6711 43.9883 22.7909C43.9883 22.9108 44.0854 23.0079 44.2052 23.0079H45.073C45.1929 23.0079 45.29 22.9108 45.29 22.7909C45.29 22.6711 45.1929 22.574 45.073 22.574Z" fill="#FDE5D8"/>
-<path d="M45.073 24.9604H44.2052C44.0854 24.9604 43.9883 25.0576 43.9883 25.1774C43.9883 25.2972 44.0854 25.3944 44.2052 25.3944H45.073C45.1929 25.3944 45.29 25.2972 45.29 25.1774C45.29 25.0576 45.1929 24.9604 45.073 24.9604Z" fill="#FDE5D8"/>
-<path d="M50.0631 24.7435H47.6766C47.4369 24.7435 47.2427 24.9378 47.2427 25.1774C47.2427 25.4171 47.4369 25.6114 47.6766 25.6114H50.0631C50.3028 25.6114 50.4971 25.4171 50.4971 25.1774C50.4971 24.9378 50.3028 24.7435 50.0631 24.7435Z" fill="#EEEEEE"/>
-<path d="M59.3922 22.3569H57.0057C56.766 22.3569 56.5718 22.5512 56.5718 22.7909C56.5718 23.0305 56.766 23.2248 57.0057 23.2248H59.3922C59.6319 23.2248 59.8262 23.0305 59.8262 22.7909C59.8262 22.5512 59.6319 22.3569 59.3922 22.3569Z" fill="#EEEEEE"/>
-<path opacity="0.5" d="M55.2702 29.5166H52.8836C52.644 29.5166 52.4497 29.7109 52.4497 29.9505C52.4497 30.1902 52.644 30.3844 52.8836 30.3844H55.2702C55.5098 30.3844 55.7041 30.1902 55.7041 29.9505C55.7041 29.7109 55.5098 29.5166 55.2702 29.5166Z" fill="#6B4FBB"/>
-<path d="M53.1007 27.1301H50.7142C50.4745 27.1301 50.2803 27.3244 50.2803 27.564C50.2803 27.8037 50.4745 27.998 50.7142 27.998H53.1007C53.3404 27.998 53.5347 27.8037 53.5347 27.564C53.5347 27.3244 53.3404 27.1301 53.1007 27.1301Z" fill="#6B4FBB"/>
-<path d="M58.3076 24.7435H54.8363C54.5966 24.7435 54.4023 24.9378 54.4023 25.1774C54.4023 25.4171 54.5966 25.6114 54.8363 25.6114H58.3076C58.5473 25.6114 58.7415 25.4171 58.7415 25.1774C58.7415 24.9378 58.5473 24.7435 58.3076 24.7435Z" fill="#6B4FBB"/>
-<path d="M51.1479 29.5166H47.6766C47.4369 29.5166 47.2427 29.7109 47.2427 29.9505C47.2427 30.1902 47.4369 30.3844 47.6766 30.3844H51.1479C51.3876 30.3844 51.5819 30.1902 51.5819 29.9505C51.5819 29.7109 51.3876 29.5166 51.1479 29.5166Z" fill="#EEEEEE"/>
-<path d="M53.1004 24.7435H51.7987C51.559 24.7435 51.3647 24.9378 51.3647 25.1774C51.3647 25.4171 51.559 25.6114 51.7987 25.6114H53.1004C53.3401 25.6114 53.5343 25.4171 53.5343 25.1774C53.5343 24.9378 53.3401 24.7435 53.1004 24.7435Z" fill="#EEEEEE"/>
-<path d="M48.9783 27.1301H47.6766C47.4369 27.1301 47.2427 27.3244 47.2427 27.564C47.2427 27.8037 47.4369 27.998 47.6766 27.998H48.9783C49.218 27.998 49.4123 27.8037 49.4123 27.564C49.4123 27.3244 49.218 27.1301 48.9783 27.1301Z" fill="#EEEEEE"/>
-<path d="M56.138 27.1301H54.8363C54.5966 27.1301 54.4023 27.3244 54.4023 27.564C54.4023 27.8037 54.5966 27.998 54.8363 27.998H56.138C56.3777 27.998 56.5719 27.8037 56.5719 27.564C56.5719 27.3244 56.3777 27.1301 56.138 27.1301Z" fill="#EEEEEE"/>
-<path d="M59.1756 27.1301H57.8739C57.6342 27.1301 57.4399 27.3244 57.4399 27.564C57.4399 27.8037 57.6342 27.998 57.8739 27.998H59.1756C59.4153 27.998 59.6095 27.8037 59.6095 27.564C59.6095 27.3244 59.4153 27.1301 59.1756 27.1301Z" fill="#EEEEEE"/>
-<path d="M62.43 22.3569H61.1283C60.8886 22.3569 60.6943 22.5512 60.6943 22.7909C60.6943 23.0305 60.8886 23.2248 61.1283 23.2248H62.43C62.6697 23.2248 62.8639 23.0305 62.8639 22.7909C62.8639 22.5512 62.6697 22.3569 62.43 22.3569Z" fill="#EEEEEE"/>
-<path d="M45.073 27.347H44.2052C44.0854 27.347 43.9883 27.4442 43.9883 27.564C43.9883 27.6838 44.0854 27.781 44.2052 27.781H45.073C45.1929 27.781 45.29 27.6838 45.29 27.564C45.29 27.4442 45.1929 27.347 45.073 27.347Z" fill="#FDE5D8"/>
-<path d="M45.073 29.7335H44.2052C44.0854 29.7335 43.9883 29.8307 43.9883 29.9505C43.9883 30.0703 44.0854 30.1674 44.2052 30.1674H45.073C45.1929 30.1674 45.29 30.0703 45.29 29.9505C45.29 29.8307 45.1929 29.7335 45.073 29.7335Z" fill="#FDE5D8"/>
-<path d="M45.073 32.1201H44.2052C44.0854 32.1201 43.9883 32.2173 43.9883 32.3371C43.9883 32.4569 44.0854 32.554 44.2052 32.554H45.073C45.1929 32.554 45.29 32.4569 45.29 32.3371C45.29 32.2173 45.1929 32.1201 45.073 32.1201Z" fill="#FDE5D8"/>
-<path d="M50.0631 31.9032H47.6766C47.4369 31.9032 47.2427 32.0975 47.2427 32.3371C47.2427 32.5768 47.4369 32.771 47.6766 32.771H50.0631C50.3028 32.771 50.4971 32.5768 50.4971 32.3371C50.4971 32.0975 50.3028 31.9032 50.0631 31.9032Z" fill="#6B4FBB"/>
-<path d="M55.2702 36.6763H52.8836C52.644 36.6763 52.4497 36.8705 52.4497 37.1102C52.4497 37.3498 52.644 37.5441 52.8836 37.5441H55.2702C55.5098 37.5441 55.7041 37.3498 55.7041 37.1102C55.7041 36.8705 55.5098 36.6763 55.2702 36.6763Z" fill="#EEEEEE"/>
-<path opacity="0.5" d="M58.3078 34.2897H55.9212C55.6816 34.2897 55.4873 34.4839 55.4873 34.7236C55.4873 34.9632 55.6816 35.1575 55.9212 35.1575H58.3078C58.5474 35.1575 58.7417 34.9632 58.7417 34.7236C58.7417 34.4839 58.5474 34.2897 58.3078 34.2897Z" fill="#6B4FBB"/>
-<path d="M51.1479 36.6763H47.6766C47.4369 36.6763 47.2427 36.8705 47.2427 37.1102C47.2427 37.3498 47.4369 37.5441 47.6766 37.5441H51.1479C51.3876 37.5441 51.5819 37.3498 51.5819 37.1102C51.5819 36.8705 51.3876 36.6763 51.1479 36.6763Z" fill="#EEEEEE"/>
-<path d="M54.1855 34.2897H50.7142C50.4745 34.2897 50.2803 34.4839 50.2803 34.7236C50.2803 34.9632 50.4745 35.1575 50.7142 35.1575H54.1855C54.4252 35.1575 54.6195 34.9632 54.6195 34.7236C54.6195 34.4839 54.4252 34.2897 54.1855 34.2897Z" fill="#6B4FBB"/>
-<path d="M53.1004 31.9032H51.7987C51.559 31.9032 51.3647 32.0975 51.3647 32.3371C51.3647 32.5768 51.559 32.771 51.7987 32.771H53.1004C53.3401 32.771 53.5343 32.5768 53.5343 32.3371C53.5343 32.0975 53.3401 31.9032 53.1004 31.9032Z" fill="#EEEEEE"/>
-<path d="M61.3451 34.2897H60.0433C59.8036 34.2897 59.6094 34.4839 59.6094 34.7236C59.6094 34.9632 59.8036 35.1575 60.0433 35.1575H61.3451C61.5847 35.1575 61.779 34.9632 61.779 34.7236C61.779 34.4839 61.5847 34.2897 61.3451 34.2897Z" fill="#EEEEEE"/>
-<path d="M48.9783 34.2897H47.6766C47.4369 34.2897 47.2427 34.4839 47.2427 34.7236C47.2427 34.9632 47.4369 35.1575 47.6766 35.1575H48.9783C49.218 35.1575 49.4123 34.9632 49.4123 34.7236C49.4123 34.4839 49.218 34.2897 48.9783 34.2897Z" fill="#EEEEEE"/>
-<path d="M45.073 34.5067H44.2052C44.0854 34.5067 43.9883 34.6039 43.9883 34.7237C43.9883 34.8435 44.0854 34.9406 44.2052 34.9406H45.073C45.1929 34.9406 45.29 34.8435 45.29 34.7237C45.29 34.6039 45.1929 34.5067 45.073 34.5067Z" fill="#FDE5D8"/>
-<path d="M45.073 36.8932H44.2052C44.0854 36.8932 43.9883 36.9903 43.9883 37.1101C43.9883 37.23 44.0854 37.3271 44.2052 37.3271H45.073C45.1929 37.3271 45.29 37.23 45.29 37.1101C45.29 36.9903 45.1929 36.8932 45.073 36.8932Z" fill="#FDE5D8"/>
-<path d="M66.0312 11.2921H75.4472C76.6405 11.2921 77.6168 10.3158 77.6168 9.12254V2.83072C77.6168 1.63745 76.6405 0.661133 75.4472 0.661133H65.2502C64.0569 0.661133 63.0806 1.63745 63.0806 2.83072V11.943C63.0806 13.1363 63.7748 13.4617 64.6427 12.5939L66.0312 11.2921Z" fill="white" stroke="#FDE5D8" stroke-width="2"/>
-<path d="M72.0845 3.69861H66.4436C66.2639 3.69861 66.1182 3.84431 66.1182 4.02405C66.1182 4.20378 66.2639 4.34949 66.4436 4.34949H72.0845C72.2643 4.34949 72.41 4.20378 72.41 4.02405C72.41 3.84431 72.2643 3.69861 72.0845 3.69861Z" fill="#FDB692"/>
-<path d="M74.2541 5.65125H66.4436C66.2639 5.65125 66.1182 5.79695 66.1182 5.97668C66.1182 6.15642 66.2639 6.30212 66.4436 6.30212H74.2541C74.4339 6.30212 74.5796 6.15642 74.5796 5.97668C74.5796 5.79695 74.4339 5.65125 74.2541 5.65125Z" fill="#FDB692"/>
-<path d="M72.0845 7.60388H66.4436C66.2639 7.60388 66.1182 7.74959 66.1182 7.92932C66.1182 8.10906 66.2639 8.25476 66.4436 8.25476H72.0845C72.2643 8.25476 72.41 8.10906 72.41 7.92932C72.41 7.74959 72.2643 7.60388 72.0845 7.60388Z" fill="#FDB692"/>
-<path d="M64.1655 21.0553C65.9629 21.0553 67.4199 19.5982 67.4199 17.8009C67.4199 16.0035 65.9629 14.5465 64.1655 14.5465C62.3682 14.5465 60.9111 16.0035 60.9111 17.8009C60.9111 19.5982 62.3682 21.0553 64.1655 21.0553Z" fill="#FFF7F4" stroke="#FC6D26"/>
-<path d="M62.3867 15.1974C63.0376 16.1303 64.079 16.7161 65.2506 16.7161C65.9665 16.7161 66.6174 16.4991 67.2032 16.1303" stroke="#FC6D26" stroke-width="0.5"/>
-<path d="M62.9724 18.6687C63.1521 18.6687 63.2979 18.523 63.2979 18.3433C63.2979 18.1635 63.1521 18.0178 62.9724 18.0178C62.7927 18.0178 62.647 18.1635 62.647 18.3433C62.647 18.523 62.7927 18.6687 62.9724 18.6687Z" fill="#FC6D26"/>
-<path d="M65.3591 18.6687C65.5389 18.6687 65.6846 18.523 65.6846 18.3433C65.6846 18.1635 65.5389 18.0178 65.3591 18.0178C65.1794 18.0178 65.0337 18.1635 65.0337 18.3433C65.0337 18.523 65.1794 18.6687 65.3591 18.6687Z" fill="#FC6D26"/>
-<path d="M16.0005 39.7137C17.7978 39.7137 19.2549 38.2567 19.2549 36.4593C19.2549 34.662 17.7978 33.205 16.0005 33.205C14.2031 33.205 12.7461 34.662 12.7461 36.4593C12.7461 38.2567 14.2031 39.7137 16.0005 39.7137Z" fill="#F4F1FA" stroke="#6B4FBB"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M18.1701 34.5068H18.7559C18.1701 33.5955 17.1721 32.988 16.0005 32.988C14.8289 32.988 13.8309 33.5955 13.2451 34.5068H13.8309L14.3733 33.8559L14.9157 34.5068L15.4581 33.8559L16.0005 34.5068L16.5429 33.8559L17.0853 34.5068L17.6277 33.8559L18.1701 34.5068Z" fill="#6B4FBB"/>
-<path d="M14.8074 37.1102C14.9871 37.1102 15.1328 36.9645 15.1328 36.7848C15.1328 36.6051 14.9871 36.4594 14.8074 36.4594C14.6276 36.4594 14.4819 36.6051 14.4819 36.7848C14.4819 36.9645 14.6276 37.1102 14.8074 37.1102Z" fill="#6B4FBB"/>
-<path d="M17.1936 37.1102C17.3733 37.1102 17.519 36.9645 17.519 36.7848C17.519 36.6051 17.3733 36.4594 17.1936 36.4594C17.0139 36.4594 16.8682 36.6051 16.8682 36.7848C16.8682 36.9645 17.0139 37.1102 17.1936 37.1102Z" fill="#6B4FBB"/>
-<path d="M13.0498 29.7336H3.63382C2.44055 29.7336 1.46423 28.7573 1.46423 27.5641V21.2722C1.46423 20.079 2.44055 19.1027 3.63382 19.1027H13.8309C15.0242 19.1027 16.0005 20.079 16.0005 21.2722V30.3845C16.0005 31.5778 15.3062 31.9032 14.4384 31.0354L13.0498 29.7336Z" fill="white" stroke="#E2DCF2" stroke-width="2"/>
-<path opacity="0.5" d="M4.82708 22.1401H10.468C10.6478 22.1401 10.7935 22.2858 10.7935 22.4656C10.7935 22.6453 10.6478 22.791 10.468 22.791H4.82708C4.64735 22.791 4.50164 22.6453 4.50164 22.4656C4.50164 22.2858 4.64735 22.1401 4.82708 22.1401Z" fill="#6B4FBB"/>
-<path opacity="0.5" d="M4.82724 24.0928H8.29859C8.47832 24.0928 8.62402 24.2385 8.62402 24.4182C8.62402 24.5979 8.47832 24.7437 8.29859 24.7437H4.82724C4.64751 24.7437 4.50181 24.5979 4.50181 24.4182C4.50181 24.2385 4.64751 24.0928 4.82724 24.0928Z" fill="#6B4FBB"/>
-<path opacity="0.5" d="M4.82724 26.0454H8.29859C8.47832 26.0454 8.62402 26.1911 8.62402 26.3708C8.62402 26.5506 8.47832 26.6963 8.29859 26.6963H4.82724C4.64751 26.6963 4.50181 26.5506 4.50181 26.3708C4.50181 26.1911 4.64751 26.0454 4.82724 26.0454Z" fill="#6B4FBB"/>
-</g>
-<defs>
-<clipPath id="clip0">
-<rect width="83.5292" height="48.8158" fill="white" transform="translate(-2.44092 0.661133)"/>
-</clipPath>
-</defs>
-</svg>
diff --git a/app/assets/images/learn_gitlab/pipeline_created.svg b/app/assets/images/learn_gitlab/pipeline_created.svg
deleted file mode 100644
index 91c716be475..00000000000
--- a/app/assets/images/learn_gitlab/pipeline_created.svg
+++ /dev/null
@@ -1,38 +0,0 @@
-<svg width="52" height="48" viewBox="0 0 52 48" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path d="M32.1404 11.789L45.6109 14.1173C47.0988 14.3744 48.0923 15.7653 47.8299 17.2237L44.9797 33.0687C44.7173 34.5272 43.2985 35.5011 41.8106 35.2439L28.34 32.9157C26.8521 32.6585 25.8586 31.2677 26.121 29.8092L28.9712 13.9642C29.2336 12.5057 30.6525 11.5318 32.1404 11.789Z" fill="white"/>
-<path d="M31.9504 12.8453C31.0576 12.691 30.2063 13.2754 30.0489 14.1505L27.1986 29.9955C27.0412 30.8705 27.6373 31.705 28.5301 31.8593L42.0006 34.1876C42.8933 34.3419 43.7446 33.7576 43.9021 32.8825L46.7523 17.0375C46.9097 16.1624 46.3136 15.3279 45.4209 15.1736L31.9504 12.8453ZM32.1404 11.789L45.6109 14.1173C47.0988 14.3744 48.0923 15.7653 47.8299 17.2237L44.9797 33.0687C44.7173 34.5272 43.2985 35.5011 41.8106 35.2439L28.34 32.9157C26.8521 32.6585 25.8586 31.2677 26.121 29.8092L28.9712 13.9642C29.2336 12.5057 30.6525 11.5318 32.1404 11.789Z" fill="#E1D8F9"/>
-<path d="M39.2265 9.7425L25.6003 8.57392C24.0951 8.44485 22.7683 9.53622 22.6366 11.0116L21.206 27.0398C21.0743 28.5151 22.1877 29.8158 23.6928 29.9449L37.3191 31.1134C38.8242 31.2425 40.1511 30.1511 40.2828 28.6758L41.7133 12.6476C41.845 11.1722 40.7316 9.87157 39.2265 9.7425Z" fill="black" fill-opacity="0.03"/>
-<path d="M34.477 47.7322H41.0349C46.4986 47.5866 50.8833 43.2004 50.8833 37.8104C50.8833 32.3306 46.3517 27.8886 40.7614 27.8886C40.4897 27.8886 40.2205 27.8993 39.9544 27.9197C38.6002 24.003 34.8187 21.1847 30.3659 21.1847C28.9201 21.1826 27.4908 21.4853 26.1748 22.0723C24.3556 19.4336 21.2753 17.6986 17.7818 17.6986C12.1915 17.6986 7.65986 22.1406 7.65986 27.6204C7.65986 27.8081 7.66533 27.995 7.67572 28.1803C3.26748 29.253 0 33.1573 0 37.8104C0 43.2902 4.53163 47.7322 10.122 47.7322C10.2106 47.7322 10.2987 47.7311 10.3868 47.729L34.477 47.7322Z" fill="#F4F0FF"/>
-<path d="M40.1486 9.42187L26.547 8.27441C25.0446 8.14767 23.718 9.24259 23.5839 10.72L22.1275 26.7704C21.9934 28.2478 23.1027 29.5482 24.6051 29.6749L38.2068 30.8224C39.7092 30.9491 41.0358 29.8542 41.1698 28.3768L42.6262 12.3264C42.7603 10.849 41.651 9.54862 40.1486 9.42187Z" fill="white"/>
-<path d="M26.4499 9.34444C25.5485 9.26839 24.7525 9.92534 24.6721 10.8118L23.2156 26.8622C23.1352 27.7486 23.8007 28.5288 24.7022 28.6049L38.3038 29.7523C39.2053 29.8284 40.0013 29.1714 40.0817 28.285L41.5381 12.2346C41.6185 11.3482 40.953 10.5679 40.0516 10.4919L26.4499 9.34444ZM26.547 8.27441L40.1486 9.42187C41.651 9.54862 42.7603 10.849 42.6262 12.3264L41.1698 28.3768C41.0358 29.8542 39.7092 30.9491 38.2068 30.8224L24.6051 29.6749C23.1027 29.5482 21.9934 28.2478 22.1275 26.7704L23.5839 10.72C23.718 9.24259 25.0446 8.14767 26.547 8.27441Z" fill="#E1D8F9"/>
-<path d="M28.8145 13.3182L27.7253 13.2263C27.4245 13.2009 27.1589 13.4202 27.1321 13.7161C27.1052 14.012 27.3273 14.2725 27.6281 14.2979L28.7173 14.3898C29.018 14.4152 29.2836 14.1959 29.3105 13.9C29.3373 13.6041 29.1152 13.3436 28.8145 13.3182Z" fill="#FC6D26"/>
-<path d="M33.2417 19.0816L32.1525 18.9897C31.8517 18.9643 31.5862 19.1836 31.5593 19.4795C31.5325 19.7755 31.7545 20.0359 32.0553 20.0613L33.1445 20.1533C33.4453 20.1787 33.7109 19.9593 33.7377 19.6634C33.7645 19.3675 33.5425 19.107 33.2417 19.0816Z" fill="#E1DBF1"/>
-<path d="M36.5464 22.0571L35.4572 21.9652C35.1564 21.9398 34.8908 22.1591 34.864 22.455C34.8372 22.7509 35.0592 23.0114 35.36 23.0368L36.4492 23.1287C36.75 23.1541 37.0155 22.9348 37.0424 22.6389C37.0692 22.343 36.8472 22.0825 36.5464 22.0571Z" fill="#FEE1D3"/>
-<path d="M36.5127 19.3624L35.4235 19.2705C35.1227 19.2451 34.8571 19.4644 34.8303 19.7603C34.8035 20.0562 35.0255 20.3167 35.3263 20.3421L36.4155 20.434C36.7163 20.4594 36.9819 20.2401 37.0087 19.9442C37.0355 19.6483 36.8135 19.3878 36.5127 19.3624Z" fill="#FEF0E8"/>
-<path d="M33.1744 13.6912L30.9954 13.5071C30.6946 13.4817 30.4289 13.7012 30.4021 13.9975C30.3752 14.2938 30.5974 14.5545 30.8982 14.58L33.0772 14.764C33.378 14.7895 33.6437 14.5699 33.6705 14.2736C33.6974 13.9774 33.4752 13.7166 33.1744 13.6912Z" fill="#EFEDF8"/>
-<path d="M27.8257 21.3098L27.2813 21.2638C26.9806 21.2385 26.7151 21.4576 26.6882 21.7534C26.6614 22.0491 26.8834 22.3094 27.1841 22.3348L27.7286 22.3807C28.0293 22.4061 28.2948 22.1869 28.3216 21.8912C28.3484 21.5955 28.1264 21.3351 27.8257 21.3098Z" fill="#FEF0E8"/>
-<path d="M30.5513 21.5437L30.0069 21.4977C29.7062 21.4723 29.4407 21.6915 29.4138 21.9873C29.387 22.283 29.609 22.5433 29.9097 22.5687L30.4541 22.6146C30.7548 22.64 31.0203 22.4208 31.0472 22.1251C31.074 21.8293 30.852 21.569 30.5513 21.5437Z" fill="#FC6D26"/>
-<path d="M33.2764 21.7772L32.732 21.7312C32.4313 21.7059 32.1657 21.925 32.1389 22.2208C32.1121 22.5165 32.3341 22.7768 32.6348 22.8022L33.1792 22.8481C33.4799 22.8735 33.7455 22.6543 33.7723 22.3586C33.7991 22.0629 33.5771 21.8025 33.2764 21.7772Z" fill="#E1D8F9"/>
-<path d="M29.6651 16.0818L27.4861 15.8977C27.1853 15.8723 26.9196 16.0919 26.8928 16.3881C26.866 16.6844 27.0881 16.9452 27.3889 16.9706L29.5679 17.1547C29.8688 17.1801 30.1344 16.9605 30.1613 16.6643C30.1881 16.368 29.966 16.1072 29.6651 16.0818Z" fill="#E1D8F9"/>
-<path d="M37.126 24.7972L34.9471 24.6132C34.6462 24.5877 34.3806 24.8073 34.3537 25.1036C34.3269 25.3998 34.549 25.6606 34.8499 25.686L37.0288 25.8701C37.3297 25.8955 37.5953 25.676 37.6222 25.3797C37.649 25.0834 37.4269 24.8227 37.126 24.7972Z" fill="#6B4FBB"/>
-<path d="M37.8406 16.7796L31.8467 16.2719C31.5457 16.2464 31.28 16.4666 31.2531 16.7638C31.2263 17.0609 31.4485 17.3225 31.7494 17.348L37.7434 17.8558C38.0443 17.8812 38.3101 17.661 38.3369 17.3638C38.3638 17.0667 38.1416 16.8051 37.8406 16.7796Z" fill="#C3B8E3"/>
-<path d="M33.0379 24.4431L27.0439 23.9353C26.743 23.9098 26.4773 24.1301 26.4504 24.4272C26.4235 24.7244 26.6457 24.986 26.9467 25.0114L32.9407 25.5192C33.2416 25.5447 33.5073 25.3245 33.5342 25.0273C33.5611 24.7301 33.3389 24.4686 33.0379 24.4431Z" fill="#FEE1D3"/>
-<path d="M38.0793 14.1112L35.3553 13.881C35.0545 13.8556 34.7888 14.0753 34.7619 14.3717C34.7351 14.6681 34.9572 14.929 35.2581 14.9544L37.982 15.1847C38.2829 15.2101 38.5486 14.9904 38.5754 14.694C38.6023 14.3976 38.3801 14.1367 38.0793 14.1112Z" fill="#E1DBF1"/>
-<path d="M29.9723 18.7993L27.2484 18.5691C26.9475 18.5437 26.6818 18.7634 26.655 19.0598C26.6282 19.3562 26.8503 19.6171 27.1512 19.6426L29.8751 19.8728C30.176 19.8982 30.4417 19.6785 30.4685 19.3821C30.4953 19.0857 30.2732 18.8248 29.9723 18.7993Z" fill="#6B4FBB"/>
-<path d="M35.2983 48H41.8562C47.3199 47.8544 51.7046 43.4682 51.7046 38.0782C51.7046 32.5984 47.173 28.1564 41.5827 28.1564C41.311 28.1564 41.0418 28.1671 40.7757 28.1875C39.4215 24.2708 35.64 21.4525 31.1871 21.4525C29.7414 21.4504 28.3121 21.7532 26.9961 22.3401C25.1769 19.7014 22.0965 17.9664 18.6031 17.9664C13.0128 17.9664 8.48115 22.4085 8.48115 27.8882C8.48115 28.076 8.48662 28.2629 8.49701 28.4482C4.08877 29.5208 0.821289 33.4252 0.821289 38.0782C0.821289 43.558 5.35292 48 10.9432 48C11.0319 48 11.12 47.999 11.2081 47.9968L35.2983 48Z" fill="white"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M35.2976 47.4637H41.8407C47.0193 47.3258 51.1567 43.1667 51.1567 38.0782C51.1567 32.8947 46.87 28.6927 41.5819 28.6927C41.3259 28.6927 41.0712 28.7026 40.8179 28.7222L40.3936 28.7549L40.2568 28.3596C38.9505 24.5818 35.3216 21.9887 31.1864 21.9887C29.8189 21.9868 28.4669 22.2731 27.2222 22.8283L26.8009 23.0163L26.5418 22.6406C24.7718 20.0727 21.8233 18.5027 18.6024 18.5027C13.3143 18.5027 9.02753 22.7047 9.02753 27.8882C9.02753 28.0654 9.03246 28.2422 9.04258 28.4183L9.06775 28.8616L8.62813 28.9686C4.39332 29.9986 1.36768 33.7413 1.36768 38.0782C1.36768 43.2616 5.65446 47.4637 10.9425 47.4637C11.0262 47.4637 11.1099 47.4626 11.2073 47.4604L35.2976 47.4637Z" fill="white"/>
-<path d="M41.5827 28.1564C47.1729 28.1564 51.7046 32.5985 51.7046 38.0782C51.7046 43.4542 47.3344 47.854 41.8415 48H35.2983L11.2203 47.9967C11.1169 47.999 11.0296 48 10.9432 48C5.35303 48 0.821289 43.5579 0.821289 38.0782C0.821289 33.5134 3.99981 29.542 8.49703 28.4481C8.48641 28.2631 8.48115 28.0765 8.48115 27.8882C8.48115 22.4086 13.0129 17.9664 18.6031 17.9664C21.9832 17.9664 25.1114 19.6064 26.9958 22.3403C28.3124 21.7532 29.742 21.4504 31.1871 21.4525C35.535 21.4525 39.3871 24.1716 40.7757 28.1874C41.0441 28.1668 41.3131 28.1564 41.5827 28.1564ZM41.8266 46.9276C46.7122 46.7976 50.6104 42.873 50.6104 38.0782C50.6104 33.1909 46.5685 29.229 41.5827 29.229C41.3418 29.229 41.1015 29.2383 40.8615 29.2569L40.4372 29.2896C40.1876 29.3088 39.9566 29.1596 39.8762 28.9272L39.7393 28.5318C38.501 24.9504 35.0651 22.5251 31.1863 22.5251C29.8973 22.5232 28.6228 22.7932 27.4496 23.3165L27.0283 23.5045C26.7852 23.6129 26.4979 23.5336 26.3483 23.3167L26.0892 22.9409C24.4075 20.5012 21.6186 19.0391 18.6031 19.0391C13.6172 19.0391 9.57541 23.001 9.57541 27.8882C9.57541 28.0567 9.58012 28.2233 9.58961 28.3886L9.61478 28.8319C9.62938 29.089 9.45538 29.3201 9.20034 29.3822L8.76063 29.4892C4.75075 30.4645 1.91555 34.007 1.91555 38.0782C1.91555 42.9655 5.95738 46.9274 10.9432 46.9274C11.0209 46.9274 11.1001 46.9264 11.2081 46.9242L35.2984 46.9274L41.8266 46.9276Z" fill="#E1D8F9"/>
-<path d="M19.2501 27.9907C19.8019 27.7404 20.3915 27.5821 20.9945 27.5223L21.1208 27.0649C21.3387 26.2755 22.1656 25.8045 22.9613 26.0114L23.7546 26.2177C24.1383 26.3176 24.4646 26.564 24.6618 26.9026C24.8589 27.2412 24.9107 27.6443 24.8057 28.0231L24.6794 28.4806C25.1755 28.8277 25.6031 29.2528 25.9488 29.7327L26.4143 29.6081C27.2149 29.3942 28.0346 29.8574 28.2469 30.6437L28.4563 31.4252C28.5574 31.8033 28.5015 32.2068 28.3009 32.5468C28.1003 32.8869 27.7714 33.1356 27.3867 33.2383L26.9221 33.3629C26.892 33.6548 26.8373 33.9481 26.7564 34.241C26.6755 34.5339 26.5718 34.8144 26.4475 35.0819L26.7857 35.4149C27.3682 35.9895 27.3647 36.9241 26.7779 37.5044L26.1939 38.0796C25.9113 38.3577 25.5291 38.5148 25.1313 38.5162C24.7336 38.5176 24.3529 38.3633 24.0732 38.0871L23.7343 37.7533C23.1824 38.0036 22.5929 38.1619 21.9899 38.2217L21.8636 38.6791C21.6457 39.4685 20.8188 39.9395 20.0231 39.7326L19.2298 39.5263C18.8461 39.4264 18.5198 39.18 18.3226 38.8414C18.1255 38.5028 18.0737 38.0997 18.1787 37.7209L18.3049 37.2634C17.8136 36.919 17.3846 36.4958 17.0356 36.0113L16.5701 36.1359C15.7695 36.3498 14.9498 35.8866 14.7374 35.1003L14.5281 34.3188C14.427 33.9407 14.4829 33.5372 14.6835 33.1972C14.8841 32.8571 15.2129 32.6084 15.5977 32.5057L16.0623 32.3812C16.0929 32.0847 16.1484 31.791 16.228 31.503C16.3089 31.2101 16.4126 30.9296 16.5369 30.6622L16.1986 30.3291C15.6162 29.7545 15.6197 28.8199 16.2065 28.2397L16.7905 27.6645C17.073 27.3863 17.4553 27.2292 17.853 27.2278C18.2508 27.2264 18.6314 27.3807 18.9112 27.6569L19.2501 27.9907Z" fill="white"/>
-<path d="M20.9944 27.5222L21.121 27.0643C21.3393 26.2769 22.1613 25.806 22.9613 26.0114L23.7546 26.2177C24.5536 26.4255 25.0238 27.2335 24.8057 28.0232L24.6796 28.4802C25.1712 28.8248 25.6002 29.2481 25.9491 29.7327L26.4148 29.6079C27.2147 29.3945 28.0336 29.8569 28.247 30.6437L28.4564 31.4256C28.5575 31.8038 28.5014 32.2073 28.3006 32.5474C28.0999 32.8874 27.7708 33.136 27.3868 33.2383L26.9221 33.3628C26.8918 33.6578 26.8364 33.9512 26.7564 34.241C26.6764 34.5306 26.5733 34.8113 26.4475 35.0819L26.7861 35.4156C27.3676 35.9897 27.3645 36.9229 26.7779 37.5044L26.1937 38.0798C25.911 38.358 25.5287 38.515 25.1308 38.5163C24.733 38.5175 24.3523 38.363 24.0733 38.0872L23.7342 37.7533C23.1825 38.0036 22.593 38.1619 21.99 38.2218L21.8635 38.6797C21.6451 39.4672 20.8231 39.938 20.0231 39.7326L19.2298 39.5263C18.4308 39.3185 17.9606 38.5106 18.1787 37.7209L18.3049 37.2638C17.8132 36.9192 17.3842 36.496 17.0353 36.0114L16.5696 36.1361C15.7697 36.3495 14.9509 35.8871 14.7374 35.1003L14.528 34.3184C14.4269 33.9403 14.483 33.5367 14.6838 33.1967C14.8846 32.8566 15.2136 32.608 15.5977 32.5057L16.0623 32.3813C16.0926 32.0862 16.148 31.7928 16.2279 31.5033C16.3073 31.2153 16.4106 30.9341 16.537 30.6621L16.1983 30.3284C15.6168 29.7543 15.62 28.8211 16.2065 28.2396L16.7907 27.6643C17.0734 27.3861 17.4558 27.229 17.8536 27.2278C18.2515 27.2265 18.6321 27.3811 18.9111 27.6568L19.2501 27.9906C19.8125 27.7376 20.3968 27.5816 20.9944 27.5222ZM19.3541 29.1231C19.1465 29.2172 18.9024 29.1749 18.742 29.0169L18.1356 28.4197C18.0595 28.3445 17.956 28.3025 17.8477 28.3028C17.7395 28.3032 17.6354 28.3459 17.5587 28.4214L16.976 28.9953C16.8161 29.1539 16.8152 29.4089 16.9737 29.5654L17.5783 30.1611C17.7385 30.3189 17.7816 30.5589 17.6864 30.7633L17.5285 31.1027C17.4273 31.3204 17.3445 31.5458 17.2808 31.7768C17.2166 32.0096 17.1723 32.2446 17.148 32.4805L17.1099 32.8514C17.087 33.0746 16.926 33.2615 16.706 33.3205L15.8747 33.5432C15.77 33.5711 15.6805 33.6387 15.6258 33.7312C15.5712 33.8237 15.556 33.9335 15.5834 34.0361L15.7923 34.816C15.8505 35.0306 16.0743 35.1569 16.2923 35.0987L17.124 34.876C17.3443 34.817 17.5775 34.8987 17.7088 35.0811L17.927 35.3841C18.2062 35.7718 18.5493 36.1104 18.942 36.3857L19.2494 36.6007C19.4343 36.7301 19.5173 36.9598 19.4573 37.1768L19.2315 37.9947C19.1719 38.2106 19.2997 38.4302 19.5168 38.4867L20.3085 38.6926C20.5267 38.7486 20.7513 38.6199 20.8108 38.4054L21.0366 37.5874C21.0965 37.3706 21.2864 37.212 21.5131 37.1895L21.89 37.1522C22.3723 37.1043 22.8438 36.9776 23.2856 36.7771L23.6306 36.6208C23.8382 36.5268 24.082 36.5692 24.2424 36.7271L24.8488 37.3243C24.9249 37.3995 25.0285 37.4416 25.1367 37.4412C25.2449 37.4409 25.349 37.3981 25.4257 37.3226L26.0084 36.7487C26.1683 36.5901 26.1692 36.3351 26.0107 36.1786L25.4061 35.5829C25.2459 35.4251 25.2028 35.1851 25.298 34.9807L25.456 34.6412C25.5567 34.4246 25.6393 34.1998 25.7036 33.9672C25.7678 33.7345 25.8122 33.4995 25.8364 33.2636L25.8745 32.8927C25.8974 32.6695 26.0584 32.4825 26.2784 32.4236L27.1097 32.2009C27.2144 32.173 27.3039 32.1053 27.3586 32.0128C27.4132 31.9203 27.4284 31.8105 27.401 31.708L27.1921 30.928C27.1339 30.7135 26.9101 30.5871 26.6921 30.6453L25.8604 30.868C25.6401 30.9271 25.4069 30.8453 25.2756 30.663L25.0574 30.3599C24.7783 29.9722 24.4351 29.6336 24.0427 29.3586L23.7353 29.1438C23.5501 29.0145 23.4671 28.7847 23.527 28.5675L23.7529 27.7494C23.8125 27.5334 23.6847 27.3138 23.4676 27.2573L22.6759 27.0514C22.4578 26.9954 22.2332 27.1241 22.1736 27.3387L21.9478 28.1566C21.8879 28.3735 21.698 28.5321 21.4713 28.5545L21.0944 28.5918C20.6121 28.6397 20.1406 28.7665 19.6992 28.9668C19.696 28.9682 19.5809 29.0203 19.3541 29.1231Z" fill="#7B58CF"/>
-<path d="M19.4256 36.6322C20.4661 37.2185 21.8046 36.8571 22.4152 35.825C23.0258 34.7929 22.6774 33.4808 21.6369 32.8945C20.5964 32.3082 19.2579 32.6696 18.6473 33.7017C18.0367 34.7339 18.3851 36.0459 19.4256 36.6322Z" fill="white"/>
-<path d="M20.2669 34.8677C19.2265 34.2814 18.878 32.9693 19.4886 31.9372C20.0992 30.9051 21.4377 30.5437 22.4782 31.13C23.5187 31.7163 23.8671 33.0283 23.2565 34.0605C22.6459 35.0926 21.3074 35.454 20.2669 34.8677ZM20.8198 33.9333C21.34 34.2264 22.0092 34.0457 22.3145 33.5297C22.6199 33.0136 22.4456 32.3576 21.9254 32.0644C21.4051 31.7713 20.7359 31.952 20.4306 32.468C20.1253 32.9841 20.2995 33.6401 20.8198 33.9333Z" fill="#6B4FBB"/>
-<path d="M30.889 35.0709C31.3313 34.8678 31.8035 34.7389 32.2863 34.6895L32.3883 34.3201C32.5643 33.6826 33.2272 33.3008 33.8637 33.4663L34.4983 33.6313C34.8053 33.7113 35.066 33.9096 35.2232 34.1825C35.3803 34.4555 35.421 34.7807 35.3362 35.0867L35.2342 35.4561C35.6306 35.7354 35.972 36.0777 36.2478 36.4644L36.6207 36.3629C37.262 36.1888 37.9173 36.5612 38.0857 37.1955L38.2517 37.8259C38.3319 38.1309 38.2864 38.4566 38.1251 38.7315C37.9638 39.0063 37.7001 39.2077 37.3919 39.2913L37.0198 39.3927C36.9951 39.6284 36.9507 39.8652 36.8854 40.1018C36.82 40.3384 36.7365 40.565 36.6364 40.7811L36.9065 41.0493C37.3717 41.512 37.367 42.2664 36.8961 42.7358L36.4275 43.2012C36.2007 43.4262 35.8945 43.5537 35.5761 43.5556C35.2577 43.5575 34.9532 43.4336 34.7299 43.2112L34.4592 42.9424C34.017 43.1455 33.5447 43.2744 33.0619 43.3238L32.9599 43.6932C32.7839 44.3307 32.1211 44.7125 31.4845 44.547L30.8499 44.3819C30.543 44.302 30.2822 44.1037 30.1251 43.8308C29.9679 43.5578 29.9273 43.2326 30.0121 42.9266L30.1141 42.5572C29.7214 42.2801 29.3788 41.9393 29.1004 41.5488L28.7276 41.6503C28.0863 41.8245 27.431 41.4521 27.2626 40.8178L27.0965 40.1874C27.0163 39.8824 27.0619 39.5566 27.2231 39.2818C27.3844 39.007 27.6481 38.8056 27.9563 38.722L28.3285 38.6206C28.3536 38.3812 28.3986 38.144 28.4629 37.9115C28.5282 37.6749 28.6118 37.4483 28.7118 37.2322L28.4417 36.964C27.9766 36.5013 27.9813 35.7469 28.4522 35.2775L28.9207 34.8121C29.1475 34.5871 29.4538 34.4595 29.7722 34.4577C30.0906 34.4558 30.395 34.5797 30.6184 34.802L30.889 35.0709Z" fill="white"/>
-<path d="M32.1998 34.5947L32.2833 34.2923C32.4746 33.6024 33.1919 33.1869 33.8914 33.3665L34.526 33.5315C35.2246 33.7132 35.6326 34.4223 35.4416 35.1142L35.3583 35.4159C35.7153 35.6768 36.0302 35.9898 36.2925 36.3444L36.5904 36.2633C37.2909 36.0733 38.0069 36.4799 38.1913 37.1715L38.3575 37.8023C38.4444 38.133 38.3949 38.4857 38.2201 38.7834C38.045 39.0816 37.7581 39.3004 37.423 39.3911L37.1204 39.4735C37.0938 39.6938 37.0505 39.9128 36.9908 40.1294C36.931 40.3458 36.8557 40.5563 36.7651 40.7602L36.9851 40.9788C37.4903 41.4818 37.4856 42.298 36.9752 42.8081L36.5064 43.2737C36.2596 43.5186 35.9255 43.6575 35.5775 43.6595C35.2288 43.6614 34.8954 43.5256 34.6519 43.2828L34.4357 43.0682C34.026 43.2479 33.5922 43.3661 33.1486 43.4189L33.0651 43.7214C32.8738 44.4113 32.1565 44.8267 31.457 44.6472L30.8224 44.4821C30.1238 44.3005 29.7158 43.5913 29.9068 42.8994L29.9901 42.5978C29.6331 42.3368 29.3182 42.0238 29.0559 41.6693L28.758 41.7504C28.0575 41.9403 27.3415 41.5338 27.1571 40.8421L26.9909 40.2114C26.9041 39.8807 26.9535 39.5279 27.1283 39.2303C27.3034 38.9321 27.5903 38.7132 27.9254 38.6225L28.228 38.5401C28.2546 38.3199 28.2979 38.1009 28.3576 37.8845C28.417 37.6691 28.4924 37.4583 28.5833 37.2535L28.3633 37.0348C27.8581 36.5319 27.8628 35.7157 28.3732 35.2055L28.842 34.74C29.0888 34.4951 29.4229 34.3561 29.7709 34.3542C30.1196 34.3522 30.453 34.4881 30.6965 34.7308L30.9127 34.9455C31.3224 34.7658 31.7562 34.6475 32.1998 34.5947ZM31.0182 36.0782C30.8094 36.1741 30.5632 36.1315 30.4022 35.9716L29.9178 35.4906C29.878 35.4508 29.8241 35.4289 29.7676 35.4292C29.7105 35.4295 29.6548 35.4527 29.6133 35.4939L29.1459 35.958C29.057 36.0469 29.0562 36.1897 29.1419 36.275L29.6246 36.7547C29.7833 36.9124 29.8259 37.151 29.7315 37.3546L29.6044 37.6287C29.5253 37.7997 29.4605 37.9767 29.4105 38.1581C29.36 38.3408 29.3251 38.5252 29.3058 38.7103L29.2745 39.0097C29.2514 39.2318 29.0916 39.4178 28.8729 39.4774L28.2068 39.6588C28.1506 39.674 28.1018 39.7112 28.0716 39.7626C28.0411 39.8146 28.0325 39.8763 28.0474 39.9333L28.2131 40.5621C28.2441 40.6786 28.3616 40.7453 28.4764 40.7142L29.1425 40.5328C29.3644 40.4725 29.5996 40.555 29.731 40.7394L29.9051 40.9836C30.1208 41.2862 30.3862 41.5502 30.6899 41.7646L30.9355 41.9376C31.1195 42.0672 31.2018 42.2962 31.142 42.5126L30.9597 43.1732C30.9264 43.2936 30.995 43.4128 31.1094 43.4425L31.7424 43.6071C31.8578 43.6367 31.9794 43.5663 32.0125 43.447L32.1949 42.7864C32.2546 42.5701 32.4437 42.4117 32.6697 42.3887L32.9714 42.3578C33.3452 42.3195 33.711 42.2196 34.054 42.0621L34.3305 41.9353C34.5392 41.8396 34.7853 41.8823 34.9462 42.0421L35.4306 42.5231C35.4704 42.5628 35.5243 42.5848 35.5808 42.5845C35.6379 42.5841 35.6936 42.561 35.7352 42.5197L36.2025 42.0556C36.2914 41.9668 36.2922 41.8239 36.2065 41.7387L35.7238 41.259C35.5651 41.1013 35.5225 40.8626 35.6169 40.6591L35.7441 40.3847C35.8228 40.2147 35.8875 40.0382 35.9379 39.8556C35.9884 39.6728 36.0233 39.4884 36.0427 39.3034L36.0739 39.0039C36.097 38.7819 36.2568 38.5958 36.4755 38.5363L37.1416 38.3549C37.1978 38.3397 37.2466 38.3025 37.2768 38.2511C37.3073 38.1991 37.3159 38.1373 37.301 38.0803L37.1353 37.4515C37.1043 37.335 36.9868 37.2683 36.872 37.2995L36.2059 37.4808C35.9841 37.5412 35.7488 37.4586 35.6174 37.2743L35.4433 37.0301C35.2276 36.7274 34.9622 36.4634 34.6588 36.2493L34.4132 36.0765C34.2289 35.947 34.1465 35.7178 34.2063 35.5012L34.3888 34.8404C34.422 34.7201 34.3534 34.6009 34.239 34.5711L33.606 34.4065C33.4907 34.3769 33.369 34.4473 33.3359 34.5666L33.1535 35.2272C33.0938 35.4435 32.9047 35.6019 32.6788 35.625L32.377 35.6558C32.0032 35.6941 31.6374 35.794 31.2948 35.9514C31.2919 35.9528 31.1997 35.995 31.0182 36.0782Z" fill="#FC6D26"/>
-<path d="M31.0067 42.0443C31.839 42.5134 32.9136 42.2178 33.4068 41.3841C33.9 40.5504 33.6251 39.4944 32.7928 39.0253C31.9604 38.5563 30.8858 38.8519 30.3926 39.6855C29.8994 40.5192 30.1743 41.5753 31.0067 42.0443Z" fill="white"/>
-<path d="M31.6893 40.6162C30.8561 40.1466 30.5815 39.0919 31.073 38.2611C31.5645 37.4302 32.6378 37.135 33.471 37.6045C34.3042 38.074 34.5788 39.1288 34.0873 39.9596C33.5957 40.7905 32.5225 41.0857 31.6893 40.6162ZM32.1315 39.8686C32.5469 40.1027 33.0855 39.9546 33.3337 39.535C33.5819 39.1154 33.4441 38.5861 33.0288 38.3521C32.6134 38.118 32.0748 38.2661 31.8266 38.6857C31.5783 39.1053 31.7162 39.6346 32.1315 39.8686Z" fill="#FC6D26"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M16.8736 10.2573C16.9313 9.88553 16.9613 9.50478 16.9613 9.11717C16.9613 4.97039 13.5319 1.60876 9.30146 1.60876C5.07104 1.60876 1.6416 4.97039 1.6416 9.11717C1.6416 13.2639 5.07104 16.6256 9.30146 16.6256C11.7125 16.6256 13.8633 15.5337 15.2674 13.8269L17.582 13.5753C17.637 13.5693 17.6908 13.5552 17.7414 13.5334C18.0182 13.4145 18.1442 13.0982 18.0228 12.8269L16.8736 10.2573Z" fill="#F4F0FF"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M17.42 9.18492C17.4777 8.81314 17.5077 8.43239 17.5077 8.04478C17.5077 3.898 14.0783 0.536377 9.84784 0.536377C5.61742 0.536377 2.18799 3.898 2.18799 8.04478C2.18799 12.1916 5.61742 15.5532 9.84784 15.5532C12.2588 15.5532 14.4097 14.4613 15.8138 12.7545L18.1284 12.5029C18.1834 12.4969 18.2371 12.4828 18.2878 12.461C18.5646 12.3421 18.6905 12.0258 18.5692 11.7545L17.42 9.18492Z" fill="white"/>
-<path d="M19.0711 11.5391C19.3137 12.0817 19.0617 12.7143 18.5082 12.9522C18.4069 12.9957 18.2994 13.0239 18.1895 13.0359L16.0945 13.2636C14.5478 15.0412 12.2855 16.0894 9.84859 16.0894C5.31599 16.0894 1.6416 12.4877 1.6416 8.04471C1.6416 3.60174 5.31599 0 9.84859 0C14.3812 0 18.0556 3.60174 18.0556 8.04471C18.0556 8.40289 18.0317 8.75827 17.9843 9.10926L19.0711 11.5391ZM16.8798 9.10409C16.9339 8.75583 16.9613 8.40206 16.9613 8.04471C16.9613 4.19414 13.7768 1.07263 9.84859 1.07263C5.92034 1.07263 2.73587 4.19414 2.73587 8.04471C2.73587 11.8953 5.92034 15.0168 9.84859 15.0168C12.0288 15.0168 14.0459 14.0499 15.3886 12.4178L15.5301 12.2457L18.0689 11.9698L16.9196 9.4002L16.8559 9.2578L16.8798 9.10409Z" fill="#E1D8F9"/>
-<path d="M9.98471 11.9331C7.8695 11.9331 6.15479 10.2523 6.15479 8.17888C6.15479 6.1055 7.8695 4.42468 9.98471 4.42468C12.0999 4.42468 13.8146 6.1055 13.8146 8.17888C13.8146 10.2523 12.0999 11.9331 9.98471 11.9331ZM9.98471 11.1286C11.6467 11.1286 12.9939 9.80798 12.9939 8.17888C12.9939 6.54979 11.6467 5.22915 9.98471 5.22915C8.32276 5.22915 6.97548 6.54979 6.97548 8.17888C6.97548 9.80798 8.32276 11.1286 9.98471 11.1286Z" fill="#31AF64"/>
-<path d="M9.62376 8.52988L9.09523 8.0118C8.93843 7.85825 8.68438 7.85825 8.52758 8.0118C8.4521 8.08542 8.40967 8.1855 8.40967 8.28987C8.40967 8.39425 8.4521 8.49433 8.52758 8.56795L9.31408 9.33864C9.31836 9.34303 9.32274 9.34732 9.32721 9.35151C9.47767 9.499 9.71841 9.49873 9.86751 9.35285L11.4564 7.79539C11.5279 7.725 11.5679 7.62964 11.5677 7.53031C11.5674 7.43098 11.5269 7.33582 11.455 7.26578C11.3837 7.19514 11.2866 7.15528 11.1851 7.15503C11.0837 7.15478 10.9864 7.19415 10.9147 7.26444L9.62376 8.52988Z" fill="#31AF64"/>
-</svg>
diff --git a/app/assets/images/learn_gitlab/required_mr_approvals_enabled.svg b/app/assets/images/learn_gitlab/required_mr_approvals_enabled.svg
deleted file mode 100644
index 027767368a6..00000000000
--- a/app/assets/images/learn_gitlab/required_mr_approvals_enabled.svg
+++ /dev/null
@@ -1,70 +0,0 @@
-<svg width="80" height="56" viewBox="0 0 80 56" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path d="M11.1567 40.6485C16.4079 40.6485 20.6649 36.3891 20.6649 31.135C20.6649 25.8808 16.4079 21.6215 11.1567 21.6215C5.9055 21.6215 1.64856 25.8808 1.64856 31.135C1.64856 36.3891 5.9055 40.6485 11.1567 40.6485Z" fill="#F9F9F9"/>
-<path d="M19.0163 30.4864C19.0163 35.1888 15.2065 38.9999 10.5081 38.9999C5.80976 38.9999 2 35.1888 2 30.4864C2 25.784 5.80976 21.9729 10.5081 21.9729C15.2065 21.9729 19.0163 25.784 19.0163 30.4864Z" fill="white" stroke="#EEEEEE" stroke-width="2"/>
-<path d="M10.5075 39.5674C15.52 39.5674 19.5834 35.5017 19.5834 30.4863C19.5834 25.471 15.52 21.4053 10.5075 21.4053C5.49496 21.4053 1.43152 25.471 1.43152 30.4863C1.43152 35.5017 5.49496 39.5674 10.5075 39.5674Z" stroke="#EEEEEE"/>
-<path d="M8.43196 33.0239C8.57802 32.9204 8.75259 32.8648 8.93158 32.8648H13.1009C13.817 32.8648 14.3975 32.284 14.3975 31.5675V28.5405C14.3975 27.824 13.817 27.2432 13.1009 27.2432H8.34686C7.63078 27.2432 7.05029 27.824 7.05029 28.5405V34.0031L8.43196 33.0239ZM8.93158 33.7296L7.20891 34.9505C7.09937 35.0282 6.96844 35.0699 6.8342 35.0699C6.47616 35.0699 6.18591 34.7795 6.18591 34.4212V28.5405C6.18591 27.3463 7.1534 26.3783 8.34686 26.3783H13.1009C14.2944 26.3783 15.2619 27.3463 15.2619 28.5405V31.5675C15.2619 32.7616 14.2944 33.7296 13.1009 33.7296H8.93158Z" fill="#FEE1D3"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M9.21191 29.6217C9.4506 29.6217 9.6441 29.8153 9.6441 30.0541C9.6441 30.293 9.4506 30.4866 9.21191 30.4866C8.97322 30.4866 8.77972 30.293 8.77972 30.0541C8.77972 29.8153 8.97322 29.6217 9.21191 29.6217ZM10.7246 29.6217C10.9633 29.6217 11.1568 29.8153 11.1568 30.0541C11.1568 30.293 10.9633 30.4866 10.7246 30.4866C10.4859 30.4866 10.2924 30.293 10.2924 30.0541C10.2924 29.8153 10.4859 29.6217 10.7246 29.6217ZM12.2372 29.6217C12.4759 29.6217 12.6694 29.8153 12.6694 30.0541C12.6694 30.293 12.4759 30.4866 12.2372 30.4866C11.9985 30.4866 11.805 30.293 11.805 30.0541C11.805 29.8153 11.9985 29.6217 12.2372 29.6217Z" fill="#FC6D26"/>
-<path d="M18.0716 14.0539C21.7713 14.0539 24.7705 11.0531 24.7705 7.35125C24.7705 3.64946 21.7713 0.64856 18.0716 0.64856C14.3719 0.64856 11.3727 3.64946 11.3727 7.35125C11.3727 11.0531 14.3719 14.0539 18.0716 14.0539Z" fill="#F9F9F9"/>
-<path d="M17.423 13.4054C21.1228 13.4054 24.122 10.4045 24.122 6.70269C24.122 3.0009 21.1228 0 17.423 0C13.7233 0 10.7241 3.0009 10.7241 6.70269C10.7241 10.4045 13.7233 13.4054 17.423 13.4054Z" fill="white"/>
-<path d="M19.1525 6.27026H15.6949C15.4563 6.27026 15.2628 6.46387 15.2628 6.7027C15.2628 6.94152 15.4563 7.13513 15.6949 7.13513H19.1525C19.3911 7.13513 19.5846 6.94152 19.5846 6.7027C19.5846 6.46387 19.3911 6.27026 19.1525 6.27026Z" fill="#6B4FBB"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M49.7467 48.0001H20.8808C19.4486 48.0001 18.2877 46.8384 18.2877 45.4055V12.5406C18.2877 11.1077 19.4486 9.94604 20.8808 9.94604H65.3962C66.8284 9.94604 67.9893 11.1077 67.9893 12.5406V16.5187C69.077 15.9128 70.3297 15.5677 71.6629 15.5677C75.84 15.5677 79.2262 18.9558 79.2262 23.1352C79.2262 27.3147 75.84 30.7028 71.6629 30.7028C70.3297 30.7028 69.077 30.3576 67.9893 29.7517V45.4055C67.9893 46.8384 66.8284 48.0001 65.3962 48.0001H62.8938C62.9761 48.4198 63.0192 48.8535 63.0192 49.2974C63.0192 52.9991 60.02 56 56.3202 56C52.6205 56 49.6213 52.9991 49.6213 49.2974C49.6213 48.8535 49.6644 48.4198 49.7467 48.0001Z" fill="#F9F9F9"/>
-<path d="M71.0139 30.0543C75.191 30.0543 78.5772 26.6662 78.5772 22.4868C78.5772 18.3073 75.191 14.9192 71.0139 14.9192C66.8368 14.9192 63.4506 18.3073 63.4506 22.4868C63.4506 26.6662 66.8368 30.0543 71.0139 30.0543Z" fill="white"/>
-<path d="M71.0148 29.6218C74.9532 29.6218 78.1459 26.4273 78.1459 22.4867C78.1459 18.5461 74.9532 15.3516 71.0148 15.3516C67.0764 15.3516 63.8837 18.5461 63.8837 22.4867C63.8837 26.4273 67.0764 29.6218 71.0148 29.6218Z" stroke="#EEEEEE" stroke-width="2"/>
-<path d="M71.014 25.7303C72.8042 25.7303 74.2554 24.2782 74.2554 22.487C74.2554 20.6958 72.8042 19.2438 71.014 19.2438C69.2238 19.2438 67.7726 20.6958 67.7726 22.487C67.7726 24.2782 69.2238 25.7303 71.014 25.7303Z" fill="#F4F1FA" stroke="#6B4FBB"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M71.9682 20.5401L71.9667 20.5401L71.4366 19.8925L70.9063 20.5404L70.9051 20.5404L70.3748 19.8925L69.8443 20.5407L69.8436 20.5407L69.3131 19.8925L68.7823 20.541L68.2041 20.5411C68.7671 19.6321 69.7666 19.0276 70.9057 19.0276C72.0443 19.0276 73.0433 19.6315 73.6065 20.5397L73.0282 20.5399L72.4983 19.8925L71.9682 20.5401Z" fill="#6B4FBB"/>
-<path d="M69.8258 23.1357C70.0048 23.1357 70.1499 22.9905 70.1499 22.8114C70.1499 22.6323 70.0048 22.4871 69.8258 22.4871C69.6468 22.4871 69.5016 22.6323 69.5016 22.8114C69.5016 22.9905 69.6468 23.1357 69.8258 23.1357Z" fill="#6B4FBB"/>
-<path d="M72.2021 23.1357C72.3811 23.1357 72.5263 22.9905 72.5263 22.8114C72.5263 22.6323 72.3811 22.4871 72.2021 22.4871C72.0231 22.4871 71.878 22.6323 71.878 22.8114C71.878 22.9905 72.0231 23.1357 72.2021 23.1357Z" fill="#6B4FBB"/>
-<path d="M65.1797 9.29712H19.7999C18.6064 9.29712 17.6389 10.2652 17.6389 11.4593V45.189C17.6389 46.3831 18.6064 47.3511 19.7999 47.3511H65.1797C66.3731 47.3511 67.3406 46.3831 67.3406 45.189V11.4593C67.3406 10.2652 66.3731 9.29712 65.1797 9.29712Z" fill="white"/>
-<path d="M64.7466 9.72986H20.2311C19.0377 9.72986 18.0702 10.6979 18.0702 11.892V44.7568C18.0702 45.951 19.0377 46.919 20.2311 46.919H64.7466C65.94 46.919 66.9075 45.951 66.9075 44.7568V11.892C66.9075 10.6979 65.94 9.72986 64.7466 9.72986Z" stroke="#EEEEEE" stroke-width="2"/>
-<path d="M25.6338 18.8108C25.6338 18.572 25.4403 18.3784 25.2016 18.3784C24.9629 18.3784 24.7694 18.572 24.7694 18.8108V44.3243C24.7694 44.5632 24.9629 44.7568 25.2016 44.7568C25.4403 44.7568 25.6338 44.5632 25.6338 44.3243V18.8108Z" fill="#EEEEEE"/>
-<path d="M22.177 22.0541H20.8804C20.6417 22.0541 20.4482 22.2477 20.4482 22.4865C20.4482 22.7253 20.6417 22.9189 20.8804 22.9189H22.177C22.4157 22.9189 22.6092 22.7253 22.6092 22.4865C22.6092 22.2477 22.4157 22.0541 22.177 22.0541Z" fill="#FEE1D3"/>
-<path d="M22.177 24.6486H20.8804C20.6417 24.6486 20.4482 24.8422 20.4482 25.081C20.4482 25.3198 20.6417 25.5134 20.8804 25.5134H22.177C22.4157 25.5134 22.6092 25.3198 22.6092 25.081C22.6092 24.8422 22.4157 24.6486 22.177 24.6486Z" fill="#F0EDF8"/>
-<path d="M22.177 27.2432H20.8804C20.6417 27.2432 20.4482 27.4368 20.4482 27.6756C20.4482 27.9144 20.6417 28.108 20.8804 28.108H22.177C22.4157 28.108 22.6092 27.9144 22.6092 27.6756C22.6092 27.4368 22.4157 27.2432 22.177 27.2432Z" fill="#FEF0E9"/>
-<path d="M22.177 29.8379H20.8804C20.6417 29.8379 20.4482 30.0315 20.4482 30.2703C20.4482 30.5091 20.6417 30.7028 20.8804 30.7028H22.177C22.4157 30.7028 22.6092 30.5091 22.6092 30.2703C22.6092 30.0315 22.4157 29.8379 22.177 29.8379Z" fill="#FEE1D3"/>
-<path d="M22.177 32.4324H20.8804C20.6417 32.4324 20.4482 32.626 20.4482 32.8648C20.4482 33.1036 20.6417 33.2972 20.8804 33.2972H22.177C22.4157 33.2972 22.6092 33.1036 22.6092 32.8648C22.6092 32.626 22.4157 32.4324 22.177 32.4324Z" fill="#E1DBF1"/>
-<path d="M22.177 35.027H20.8804C20.6417 35.027 20.4482 35.2206 20.4482 35.4594C20.4482 35.6982 20.6417 35.8918 20.8804 35.8918H22.177C22.4157 35.8918 22.6092 35.6982 22.6092 35.4594C22.6092 35.2206 22.4157 35.027 22.177 35.027Z" fill="#F0EDF8"/>
-<path d="M22.177 37.6216H20.8804C20.6417 37.6216 20.4482 37.8152 20.4482 38.054C20.4482 38.2928 20.6417 38.4864 20.8804 38.4864H22.177C22.4157 38.4864 22.6092 38.2928 22.6092 38.054C22.6092 37.8152 22.4157 37.6216 22.177 37.6216Z" fill="#FEF0E9"/>
-<path d="M22.177 40.2161H20.8804C20.6417 40.2161 20.4482 40.4097 20.4482 40.6485C20.4482 40.8873 20.6417 41.0809 20.8804 41.0809H22.177C22.4157 41.0809 22.6092 40.8873 22.6092 40.6485C22.6092 40.4097 22.4157 40.2161 22.177 40.2161Z" fill="#FEE1D3"/>
-<path d="M32.1164 22.0538H29.9555C29.7168 22.0538 29.5233 22.2474 29.5233 22.4863C29.5233 22.7251 29.7168 22.9187 29.9555 22.9187H32.1164C32.3551 22.9187 32.5486 22.7251 32.5486 22.4863C32.5486 22.2474 32.3551 22.0538 32.1164 22.0538Z" fill="#6B4FBB"/>
-<path d="M36.439 22.0537H34.278C34.0393 22.0537 33.8458 22.2473 33.8458 22.4861C33.8458 22.725 34.0393 22.9186 34.278 22.9186H36.439C36.6776 22.9186 36.8711 22.725 36.8711 22.4861C36.8711 22.2473 36.6776 22.0537 36.439 22.0537Z" fill="#F0EDF8"/>
-<path d="M40.7601 22.0537H38.5992C38.3605 22.0537 38.167 22.2473 38.167 22.4861C38.167 22.725 38.3605 22.9186 38.5992 22.9186H40.7601C40.9988 22.9186 41.1923 22.725 41.1923 22.4861C41.1923 22.2473 40.9988 22.0537 40.7601 22.0537Z" fill="#FEF0E9"/>
-<path d="M32.1161 24.6484H29.9551C29.7164 24.6484 29.5229 24.842 29.5229 25.0809C29.5229 25.3197 29.7164 25.5133 29.9551 25.5133H32.1161C32.3548 25.5133 32.5483 25.3197 32.5483 25.0809C32.5483 24.842 32.3548 24.6484 32.1161 24.6484Z" fill="#F0EDF8"/>
-<path d="M40.7601 27.243H38.5992C38.3605 27.243 38.167 27.4366 38.167 27.6755C38.167 27.9143 38.3605 28.1079 38.5992 28.1079H40.7601C40.9988 28.1079 41.1923 27.9143 41.1923 27.6755C41.1923 27.4366 40.9988 27.243 40.7601 27.243Z" fill="#FEF0E9"/>
-<path d="M32.1161 32.4323H29.9551C29.7164 32.4323 29.5229 32.6259 29.5229 32.8647C29.5229 33.1035 29.7164 33.2971 29.9551 33.2971H32.1161C32.3548 33.2971 32.5483 33.1035 32.5483 32.8647C32.5483 32.6259 32.3548 32.4323 32.1161 32.4323Z" fill="#E1DBF1"/>
-<path d="M40.7601 29.8378H38.5992C38.3605 29.8378 38.167 30.0314 38.167 30.2702C38.167 30.509 38.3605 30.7026 38.5992 30.7026H40.7601C40.9988 30.7026 41.1923 30.509 41.1923 30.2702C41.1923 30.0314 40.9988 29.8378 40.7601 29.8378Z" fill="#FEF0E9"/>
-<path d="M34.9263 24.6484H34.278C34.0393 24.6484 33.8458 24.842 33.8458 25.0809C33.8458 25.3197 34.0393 25.5133 34.278 25.5133H34.9263C35.165 25.5133 35.3585 25.3197 35.3585 25.0809C35.3585 24.842 35.165 24.6484 34.9263 24.6484Z" fill="#FEE1D3"/>
-<path d="M36.4379 29.8378H35.7896C35.5509 29.8378 35.3574 30.0314 35.3574 30.2702C35.3574 30.509 35.5509 30.7026 35.7896 30.7026H36.4379C36.6766 30.7026 36.8701 30.509 36.8701 30.2702C36.8701 30.0314 36.6766 29.8378 36.4379 29.8378Z" fill="#6B4FBB"/>
-<path d="M34.9263 32.4323H34.278C34.0393 32.4323 33.8458 32.6259 33.8458 32.8647C33.8458 33.1035 34.0393 33.2971 34.278 33.2971H34.9263C35.165 33.2971 35.3585 33.1035 35.3585 32.8647C35.3585 32.6259 35.165 32.4323 34.9263 32.4323Z" fill="#FEE1D3"/>
-<path d="M30.6034 27.243H29.9551C29.7164 27.243 29.5229 27.4366 29.5229 27.6755C29.5229 27.9143 29.7164 28.1079 29.9551 28.1079H30.6034C30.8421 28.1079 31.0356 27.9143 31.0356 27.6755C31.0356 27.4366 30.8421 27.243 30.6034 27.243Z" fill="#FC6D26"/>
-<path d="M36.4383 27.243H32.7647C32.526 27.243 32.3325 27.4366 32.3325 27.6755C32.3325 27.9143 32.526 28.1079 32.7647 28.1079H36.4383C36.677 28.1079 36.8705 27.9143 36.8705 27.6755C36.8705 27.4366 36.677 27.243 36.4383 27.243Z" fill="#E1DBF1"/>
-<path d="M33.6287 29.8378H29.9551C29.7164 29.8378 29.5229 30.0314 29.5229 30.2702C29.5229 30.509 29.7164 30.7026 29.9551 30.7026H33.6287C33.8674 30.7026 34.0609 30.509 34.0609 30.2702C34.0609 30.0314 33.8674 29.8378 33.6287 29.8378Z" fill="#EEEEEE"/>
-<path d="M37.7342 24.6484H37.0859C36.8472 24.6484 36.6537 24.842 36.6537 25.0809C36.6537 25.3197 36.8472 25.5133 37.0859 25.5133H37.7342C37.9728 25.5133 38.1663 25.3197 38.1663 25.0809C38.1663 24.842 37.9728 24.6484 37.7342 24.6484Z" fill="#6B4FBB"/>
-<path d="M53.2933 22.054H51.1323C50.8936 22.054 50.7001 22.2476 50.7001 22.4864C50.7001 22.7252 50.8936 22.9188 51.1323 22.9188H53.2933C53.532 22.9188 53.7254 22.7252 53.7254 22.4864C53.7254 22.2476 53.532 22.054 53.2933 22.054Z" fill="#FEE1D3"/>
-<path d="M57.6143 22.054H55.4533C55.2146 22.054 55.0211 22.2476 55.0211 22.4864C55.0211 22.7252 55.2146 22.9188 55.4533 22.9188H57.6143C57.8529 22.9188 58.0464 22.7252 58.0464 22.4864C58.0464 22.2476 57.8529 22.054 57.6143 22.054Z" fill="#F0EDF8"/>
-<path d="M61.9367 22.054H59.7758C59.5371 22.054 59.3436 22.2476 59.3436 22.4864C59.3436 22.7252 59.5371 22.9188 59.7758 22.9188H61.9367C62.1754 22.9188 62.3689 22.7252 62.3689 22.4864C62.3689 22.2476 62.1754 22.054 61.9367 22.054Z" fill="#FC6D26"/>
-<path d="M53.2931 24.6486H51.1321C50.8934 24.6486 50.7 24.8422 50.7 25.081C50.7 25.3198 50.8934 25.5134 51.1321 25.5134H53.2931C53.5318 25.5134 53.7253 25.3198 53.7253 25.081C53.7253 24.8422 53.5318 24.6486 53.2931 24.6486Z" fill="#FEF0E9"/>
-<path d="M61.9367 27.2432H59.7758C59.5371 27.2432 59.3436 27.4368 59.3436 27.6756C59.3436 27.9144 59.5371 28.108 59.7758 28.108H61.9367C62.1754 28.108 62.3689 27.9144 62.3689 27.6756C62.3689 27.4368 62.1754 27.2432 61.9367 27.2432Z" fill="#E1DBF1"/>
-<path d="M53.2931 32.4324H51.1321C50.8934 32.4324 50.7 32.626 50.7 32.8648C50.7 33.1036 50.8934 33.2972 51.1321 33.2972H53.2931C53.5318 33.2972 53.7253 33.1036 53.7253 32.8648C53.7253 32.626 53.5318 32.4324 53.2931 32.4324Z" fill="#F0EDF8"/>
-<path d="M61.9367 29.8378H59.7758C59.5371 29.8378 59.3436 30.0314 59.3436 30.2702C59.3436 30.509 59.5371 30.7026 59.7758 30.7026H61.9367C62.1754 30.7026 62.3689 30.509 62.3689 30.2702C62.3689 30.0314 62.1754 29.8378 61.9367 29.8378Z" fill="#FEE1D3"/>
-<path d="M56.1016 24.6486H55.4533C55.2146 24.6486 55.0211 24.8422 55.0211 25.081C55.0211 25.3198 55.2146 25.5134 55.4533 25.5134H56.1016C56.3403 25.5134 56.5338 25.3198 56.5338 25.081C56.5338 24.8422 56.3403 24.6486 56.1016 24.6486Z" fill="#FC6D26"/>
-<path d="M57.6149 29.8378H56.9666C56.7279 29.8378 56.5344 30.0314 56.5344 30.2702C56.5344 30.509 56.7279 30.7026 56.9666 30.7026H57.6149C57.8536 30.7026 58.0471 30.509 58.0471 30.2702C58.0471 30.0314 57.8536 29.8378 57.6149 29.8378Z" fill="#6B4FBB"/>
-<path d="M56.1016 32.4324H55.4533C55.2146 32.4324 55.0211 32.626 55.0211 32.8648C55.0211 33.1036 55.2146 33.2972 55.4533 33.2972H56.1016C56.3403 33.2972 56.5338 33.1036 56.5338 32.8648C56.5338 32.626 56.3403 32.4324 56.1016 32.4324Z" fill="#FC6D26"/>
-<path d="M51.7804 27.2432H51.1321C50.8934 27.2432 50.7 27.4368 50.7 27.6756C50.7 27.9144 50.8934 28.108 51.1321 28.108H51.7804C52.0191 28.108 52.2126 27.9144 52.2126 27.6756C52.2126 27.4368 52.0191 27.2432 51.7804 27.2432Z" fill="#6B4FBB"/>
-<path d="M57.6153 27.2432H53.9417C53.703 27.2432 53.5095 27.4368 53.5095 27.6756C53.5095 27.9144 53.703 28.108 53.9417 28.108H57.6153C57.854 28.108 58.0475 27.9144 58.0475 27.6756C58.0475 27.4368 57.854 27.2432 57.6153 27.2432Z" fill="#FEE1D3"/>
-<path d="M54.8057 29.8378H51.1321C50.8934 29.8378 50.7 30.0314 50.7 30.2702C50.7 30.509 50.8934 30.7026 51.1321 30.7026H54.8057C55.0444 30.7026 55.2379 30.509 55.2379 30.2702C55.2379 30.0314 55.0444 29.8378 54.8057 29.8378Z" fill="#FEF0E9"/>
-<path d="M58.9112 24.6486H58.2629C58.0242 24.6486 57.8307 24.8422 57.8307 25.081C57.8307 25.3198 58.0242 25.5134 58.2629 25.5134H58.9112C59.1499 25.5134 59.3433 25.3198 59.3433 25.081C59.3433 24.8422 59.1499 24.6486 58.9112 24.6486Z" fill="#6B4FBB"/>
-<path d="M32.1163 35.027H29.9553C29.7166 35.027 29.5231 35.2206 29.5231 35.4594C29.5231 35.6982 29.7166 35.8918 29.9553 35.8918H32.1163C32.355 35.8918 32.5484 35.6982 32.5484 35.4594C32.5484 35.2206 32.355 35.027 32.1163 35.027Z" fill="#F0EDF8"/>
-<path d="M36.4372 35.027H34.2763C34.0376 35.027 33.8441 35.2206 33.8441 35.4594C33.8441 35.6982 34.0376 35.8918 34.2763 35.8918H36.4372C36.6759 35.8918 36.8694 35.6982 36.8694 35.4594C36.8694 35.2206 36.6759 35.027 36.4372 35.027Z" fill="#6B4FBB"/>
-<path d="M40.7597 35.027H38.5988C38.3601 35.027 38.1666 35.2206 38.1666 35.4594C38.1666 35.6982 38.3601 35.8918 38.5988 35.8918H40.7597C40.9984 35.8918 41.1919 35.6982 41.1919 35.4594C41.1919 35.2206 40.9984 35.027 40.7597 35.027Z" fill="#E1DBF1"/>
-<path d="M32.1161 37.6216H29.9551C29.7164 37.6216 29.5229 37.8152 29.5229 38.054C29.5229 38.2928 29.7164 38.4864 29.9551 38.4864H32.1161C32.3548 38.4864 32.5483 38.2928 32.5483 38.054C32.5483 37.8152 32.3548 37.6216 32.1161 37.6216Z" fill="#FEF0E9"/>
-<path d="M40.7597 40.2161H38.5988C38.3601 40.2161 38.1666 40.4097 38.1666 40.6485C38.1666 40.8873 38.3601 41.0809 38.5988 41.0809H40.7597C40.9984 41.0809 41.1919 40.8873 41.1919 40.6485C41.1919 40.4097 40.9984 40.2161 40.7597 40.2161Z" fill="#FEE1D3"/>
-<path d="M34.9246 37.6216H34.2763C34.0376 37.6216 33.8441 37.8152 33.8441 38.054C33.8441 38.2928 34.0376 38.4864 34.2763 38.4864H34.9246C35.1633 38.4864 35.3568 38.2928 35.3568 38.054C35.3568 37.8152 35.1633 37.6216 34.9246 37.6216Z" fill="#EEEEEE"/>
-<path d="M30.6034 40.2161H29.9551C29.7164 40.2161 29.5229 40.4097 29.5229 40.6485C29.5229 40.8873 29.7164 41.0809 29.9551 41.0809H30.6034C30.8421 41.0809 31.0356 40.8873 31.0356 40.6485C31.0356 40.4097 30.8421 40.2161 30.6034 40.2161Z" fill="#6B4FBB"/>
-<path d="M36.4383 40.2161H32.7647C32.526 40.2161 32.3325 40.4097 32.3325 40.6485C32.3325 40.8873 32.526 41.0809 32.7647 41.0809H36.4383C36.677 41.0809 36.8705 40.8873 36.8705 40.6485C36.8705 40.4097 36.677 40.2161 36.4383 40.2161Z" fill="#FEF0E9"/>
-<path d="M37.7342 37.6216H37.0859C36.8472 37.6216 36.6537 37.8152 36.6537 38.054C36.6537 38.2928 36.8472 38.4864 37.0859 38.4864H37.7342C37.9728 38.4864 38.1663 38.2928 38.1663 38.054C38.1663 37.8152 37.9728 37.6216 37.7342 37.6216Z" fill="#FC6D26"/>
-<path d="M46.3791 25.2972C46.3791 25.0584 46.1856 24.8647 45.947 24.8647C45.7083 24.8647 45.5148 25.0584 45.5148 25.2972V38.0539C45.5148 38.2927 45.7083 38.4863 45.947 38.4863C46.1856 38.4863 46.3791 38.2927 46.3791 38.0539V25.2972Z" fill="#EEEEEE"/>
-<path d="M66.9082 15.135H18.0709C17.8322 15.135 17.6387 15.3286 17.6387 15.5674C17.6387 15.8063 17.8322 15.9999 18.0709 15.9999H66.9082C67.1469 15.9999 67.3404 15.8063 67.3404 15.5674C67.3404 15.3286 67.1469 15.135 66.9082 15.135Z" fill="#EEEEEE"/>
-<path d="M55.8884 55.3513C59.5881 55.3513 62.5874 52.3504 62.5874 48.6486C62.5874 44.9468 59.5881 41.9459 55.8884 41.9459C52.1887 41.9459 49.1895 44.9468 49.1895 48.6486C49.1895 52.3504 52.1887 55.3513 55.8884 55.3513Z" fill="white"/>
-<path d="M55.8878 54.9188C59.3489 54.9188 62.1546 52.1115 62.1546 48.6486C62.1546 45.1856 59.3489 42.3783 55.8878 42.3783C52.4268 42.3783 49.6211 45.1856 49.6211 48.6486C49.6211 52.1115 52.4268 54.9188 55.8878 54.9188Z" stroke="#EEEEEE" stroke-width="2"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M55.457 48.2161V46.9188C55.457 46.6799 55.6505 46.4863 55.8892 46.4863C56.1278 46.4863 56.3213 46.6799 56.3213 46.9188V48.2161H57.6179C57.8566 48.2161 58.0501 48.4097 58.0501 48.6485C58.0501 48.8873 57.8566 49.0809 57.6179 49.0809H56.3213V50.3782C56.3213 50.617 56.1278 50.8106 55.8892 50.8106C55.6505 50.8106 55.457 50.617 55.457 50.3782V49.0809H54.1604C53.9217 49.0809 53.7282 48.8873 53.7282 48.6485C53.7282 48.4097 53.9217 48.2161 54.1604 48.2161H55.457Z" fill="#FC6D26"/>
-</svg>
diff --git a/app/assets/images/learn_gitlab/security_scan_enabled.svg b/app/assets/images/learn_gitlab/security_scan_enabled.svg
deleted file mode 100644
index eea0693484c..00000000000
--- a/app/assets/images/learn_gitlab/security_scan_enabled.svg
+++ /dev/null
@@ -1,36 +0,0 @@
-<svg width="47" height="47" viewBox="0 0 47 47" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path d="M23.0588 47C35.7939 47 46.1176 36.6762 46.1176 23.9411C46.1176 11.2061 35.7939 0.882324 23.0588 0.882324C10.3238 0.882324 0 11.2061 0 23.9411C0 36.6762 10.3238 47 23.0588 47Z" fill="#EEEEEE"/>
-<path d="M23.0588 45.1176C34.7542 45.1176 44.2353 35.6366 44.2353 23.9411C44.2353 12.2457 34.7542 2.76465 23.0588 2.76465C11.3634 2.76465 1.88232 12.2457 1.88232 23.9411C1.88232 35.6366 11.3634 45.1176 23.0588 45.1176Z" fill="white"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M16.3292 14.5295H16.9802C17.4786 14.5295 17.8827 14.9336 17.8827 15.432V16.8825C17.8827 17.4023 17.4613 17.8237 16.9415 17.8237H13.6556C13.1683 17.8237 12.7732 17.4286 12.7732 16.9413C12.7732 16.6257 12.9419 16.334 13.2155 16.1766L15.8598 14.655C16.0026 14.5728 16.1644 14.5295 16.3292 14.5295ZM12.2356 23.0001H16.9415C17.4613 23.0001 17.8827 23.4215 17.8827 23.9413V25.3531C17.8827 25.8729 17.4613 26.2942 16.9415 26.2942H12.2356C11.7158 26.2942 11.2944 25.8729 11.2944 25.3531V23.9413C11.2944 23.4215 11.7158 23.0001 12.2356 23.0001Z" fill="#EFEDF8"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M6.11793 18.7649H10.8238C11.3436 18.7649 11.765 19.1863 11.765 19.7061V21.1178C11.765 21.6376 11.3436 22.059 10.8238 22.059H6.11793C5.59814 22.059 5.17676 21.6376 5.17676 21.1178V19.7061C5.17676 19.1863 5.59814 18.7649 6.11793 18.7649Z" fill="#F9E2D5"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M40.4709 18.7649H35.765C35.2452 18.7649 34.8239 19.1863 34.8239 19.7061V21.1178C34.8239 21.6376 35.2452 22.059 35.765 22.059H40.4709C40.9907 22.059 41.4121 21.6376 41.4121 21.1178V19.7061C41.4121 19.1863 40.9907 18.7649 40.4709 18.7649Z" fill="#F9E2D5"/>
-<path d="M16.9415 31.0002H12.2356C11.7158 31.0002 11.2944 31.4216 11.2944 31.9414V33.3532C11.2944 33.873 11.7158 34.2944 12.2356 34.2944H16.9415C17.4613 34.2944 17.8827 33.873 17.8827 33.3532V31.9414C17.8827 31.4216 17.4613 31.0002 16.9415 31.0002Z" fill="#F9E2D5"/>
-<path d="M29.6474 31.0002H34.3533C34.8731 31.0002 35.2944 31.4216 35.2944 31.9414V33.3532C35.2944 33.873 34.8731 34.2944 34.3533 34.2944H29.6474C29.1276 34.2944 28.7062 33.873 28.7062 33.3532V31.9414C28.7062 31.4216 29.1276 31.0002 29.6474 31.0002Z" fill="#F9E2D5"/>
-<path d="M9.41202 31.0002H8.00026C7.48046 31.0002 7.05908 31.4216 7.05908 31.9414V33.3532C7.05908 33.873 7.48046 34.2944 8.00026 34.2944H9.41202C9.93182 34.2944 10.3532 33.873 10.3532 33.3532V31.9414C10.3532 31.4216 9.93182 31.0002 9.41202 31.0002Z" fill="#F9E2D5"/>
-<path d="M37.1768 31.0002H38.5886C39.1084 31.0002 39.5298 31.4216 39.5298 31.9414V33.3532C39.5298 33.873 39.1084 34.2944 38.5886 34.2944H37.1768C36.657 34.2944 36.2357 33.873 36.2357 33.3532V31.9414C36.2357 31.4216 36.657 31.0002 37.1768 31.0002Z" fill="#F9E2D5"/>
-<path d="M9.41202 23.0002H8.00026C7.48046 23.0002 7.05908 23.4216 7.05908 23.9414V25.3532C7.05908 25.873 7.48046 26.2944 8.00026 26.2944H9.41202C9.93182 26.2944 10.3532 25.873 10.3532 25.3532V23.9414C10.3532 23.4216 9.93182 23.0002 9.41202 23.0002Z" fill="#F9E2D5"/>
-<path d="M37.1768 23.0002H38.5886C39.1084 23.0002 39.5298 23.4216 39.5298 23.9414V25.3532C39.5298 25.873 39.1084 26.2944 38.5886 26.2944H37.1768C36.657 26.2944 36.2357 25.873 36.2357 25.3532V23.9414C36.2357 23.4216 36.657 23.0002 37.1768 23.0002Z" fill="#F9E2D5"/>
-<path d="M9.41202 14.5295H8.00026C7.48046 14.5295 7.05908 14.9509 7.05908 15.4707V16.8825C7.05908 17.4023 7.48046 17.8237 8.00026 17.8237H9.41202C9.93182 17.8237 10.3532 17.4023 10.3532 16.8825V15.4707C10.3532 14.9509 9.93182 14.5295 9.41202 14.5295Z" fill="#F9E2D5"/>
-<path d="M37.1768 14.5295H38.5886C39.1084 14.5295 39.5298 14.9509 39.5298 15.4707V16.8825C39.5298 17.4023 39.1084 17.8237 38.5886 17.8237H37.1768C36.657 17.8237 36.2357 17.4023 36.2357 16.8825V15.4707C36.2357 14.9509 36.657 14.5295 37.1768 14.5295Z" fill="#F9E2D5"/>
-<path d="M10.8238 26.7649H6.11793C5.59814 26.7649 5.17676 27.1863 5.17676 27.7061V29.1178C5.17676 29.6376 5.59814 30.059 6.11793 30.059H10.8238C11.3436 30.059 11.765 29.6376 11.765 29.1178V27.7061C11.765 27.1863 11.3436 26.7649 10.8238 26.7649Z" fill="#F9E2D5"/>
-<path d="M35.765 26.7649H40.4709C40.9907 26.7649 41.4121 27.1863 41.4121 27.7061V29.1178C41.4121 29.6376 40.9907 30.059 40.4709 30.059H35.765C35.2452 30.059 34.8239 29.6376 34.8239 29.1178V27.7061C34.8239 27.1863 35.2452 26.7649 35.765 26.7649Z" fill="#F9E2D5"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M12.2356 14.5295H16.9415C17.4613 14.5295 17.8827 14.9509 17.8827 15.4707V16.8825C17.8827 17.4023 17.4613 17.8237 16.9415 17.8237H12.2356C11.7158 17.8237 11.2944 17.4023 11.2944 16.8825V15.4707C11.2944 14.9509 11.7158 14.5295 12.2356 14.5295Z" fill="#EFEDF8"/>
-<path d="M28.2354 14.5295H23.5296C23.0098 14.5295 22.5884 14.9509 22.5884 15.4707V16.8825C22.5884 17.4023 23.0098 17.8237 23.5296 17.8237H28.2354C28.7552 17.8237 29.1766 17.4023 29.1766 16.8825V15.4707C29.1766 14.9509 28.7552 14.5295 28.2354 14.5295Z" fill="#EFEDF8"/>
-<path d="M28.2354 23.0002H23.5296C23.0098 23.0002 22.5884 23.4216 22.5884 23.9414V25.3532C22.5884 25.873 23.0098 26.2944 23.5296 26.2944H28.2354C28.7552 26.2944 29.1766 25.873 29.1766 25.3532V23.9414C29.1766 23.4216 28.7552 23.0002 28.2354 23.0002Z" fill="#EFEDF8"/>
-<path d="M32.0002 26.7649H29.6472C29.1274 26.7649 28.7061 27.1863 28.7061 27.7061V29.1178C28.7061 29.6376 29.1274 30.059 29.6472 30.059H32.0002C32.52 30.059 32.9413 29.6376 32.9413 29.1178V27.7061C32.9413 27.1863 32.52 26.7649 32.0002 26.7649Z" fill="#EFEDF8"/>
-<path d="M22.5885 18.7649H17.8826C17.3628 18.7649 16.9414 19.1863 16.9414 19.7061V21.1178C16.9414 21.6376 17.3628 22.059 17.8826 22.059H22.5885C23.1083 22.059 23.5296 21.6376 23.5296 21.1178V19.7061C23.5296 19.1863 23.1083 18.7649 22.5885 18.7649Z" fill="#EFEDF8"/>
-<path d="M21.1767 14.5295H19.7649C19.2451 14.5295 18.8237 14.9509 18.8237 15.4707V16.8825C18.8237 17.4023 19.2451 17.8237 19.7649 17.8237H21.1767C21.6965 17.8237 22.1178 17.4023 22.1178 16.8825V15.4707C22.1178 14.9509 21.6965 14.5295 21.1767 14.5295Z" fill="#EFEDF8"/>
-<path d="M21.1767 23.0002H19.7649C19.2451 23.0002 18.8237 23.4216 18.8237 23.9414V25.3532C18.8237 25.873 19.2451 26.2944 19.7649 26.2944H21.1767C21.6965 26.2944 22.1178 25.873 22.1178 25.3532V23.9414C22.1178 23.4216 21.6965 23.0002 21.1767 23.0002Z" fill="#EFEDF8"/>
-<path d="M15.059 26.7649H13.6472C13.1274 26.7649 12.7061 27.1863 12.7061 27.7061V29.1178C12.7061 29.6376 13.1274 30.059 13.6472 30.059H15.059C15.5788 30.059 16.0002 29.6376 16.0002 29.1178V27.7061C16.0002 27.1863 15.5788 26.7649 15.059 26.7649Z" fill="#EFEDF8"/>
-<path d="M21.1767 31.0002H19.7649C19.2451 31.0002 18.8237 31.4216 18.8237 31.9414V33.3532C18.8237 33.873 19.2451 34.2944 19.7649 34.2944H21.1767C21.6965 34.2944 22.1178 33.873 22.1178 33.3532V31.9414C22.1178 31.4216 21.6965 31.0002 21.1767 31.0002Z" fill="#EFEDF8"/>
-<path d="M32.4706 23.0002H31.0589C30.5391 23.0002 30.1177 23.4216 30.1177 23.9414V25.3532C30.1177 25.873 30.5391 26.2944 31.0589 26.2944H32.4706C32.9904 26.2944 33.4118 25.873 33.4118 25.3532V23.9414C33.4118 23.4216 32.9904 23.0002 32.4706 23.0002Z" fill="#EFEDF8"/>
-<path d="M15.059 18.7649H13.6472C13.1274 18.7649 12.7061 19.1863 12.7061 19.7061V21.1178C12.7061 21.6376 13.1274 22.059 13.6472 22.059H15.059C15.5788 22.059 16.0002 21.6376 16.0002 21.1178V19.7061C16.0002 19.1863 15.5788 18.7649 15.059 18.7649Z" fill="#EFEDF8"/>
-<path d="M26.8241 18.7649H25.4124C24.8926 18.7649 24.4712 19.1863 24.4712 19.7061V21.1178C24.4712 21.6376 24.8926 22.059 25.4124 22.059H26.8241C27.3439 22.059 27.7653 21.6376 27.7653 21.1178V19.7061C27.7653 19.1863 27.3439 18.7649 26.8241 18.7649Z" fill="#EFEDF8"/>
-<path d="M32.4706 14.5295H31.0589C30.5391 14.5295 30.1177 14.9509 30.1177 15.4707V16.8825C30.1177 17.4023 30.5391 17.8237 31.0589 17.8237H32.4706C32.9904 17.8237 33.4118 17.4023 33.4118 16.8825V15.4707C33.4118 14.9509 32.9904 14.5295 32.4706 14.5295Z" fill="#EFEDF8"/>
-<path d="M34.3531 18.7649H29.6472C29.1274 18.7649 28.7061 19.1863 28.7061 19.7061V21.1178C28.7061 21.6376 29.1274 22.059 29.6472 22.059H34.3531C34.8729 22.059 35.2943 21.6376 35.2943 21.1178V19.7061C35.2943 19.1863 34.8729 18.7649 34.3531 18.7649Z" fill="#EFEDF8"/>
-<path d="M22.5885 26.7649H17.8826C17.3628 26.7649 16.9414 27.1863 16.9414 27.7061V29.1178C16.9414 29.6376 17.3628 30.059 17.8826 30.059H22.5885C23.1083 30.059 23.5296 29.6376 23.5296 29.1178V27.7061C23.5296 27.1863 23.1083 26.7649 22.5885 26.7649Z" fill="#EFEDF8"/>
-<path d="M28.2354 31.0002H23.5296C23.0098 31.0002 22.5884 31.4216 22.5884 31.9414V33.3532C22.5884 33.873 23.0098 34.2944 23.5296 34.2944H28.2354C28.7552 34.2944 29.1766 33.873 29.1766 33.3532V31.9414C29.1766 31.4216 28.7552 31.0002 28.2354 31.0002Z" fill="#EFEDF8"/>
-<path d="M26.8241 26.7649H25.4124C24.8926 26.7649 24.4712 27.1863 24.4712 27.7061V29.1178C24.4712 29.6376 24.8926 30.059 25.4124 30.059H26.8241C27.3439 30.059 27.7653 29.6376 27.7653 29.1178V27.7061C27.7653 27.1863 27.3439 26.7649 26.8241 26.7649Z" fill="#EFEDF8"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M23.5516 10.3323L36.0222 13.8791C36.4267 13.9942 36.7059 14.3638 36.7059 14.7844V21.1043C36.7059 25.151 35.0909 29.032 32.2166 31.8933L23.9581 40.1143C23.5909 40.4798 22.9973 40.4798 22.6301 40.1143L14.3717 31.8933C11.4972 29.032 9.88232 25.151 9.88232 21.1043V14.7844C9.88232 14.3638 10.1614 13.9942 10.566 13.8791L23.0366 10.3323C23.2049 10.2844 23.3833 10.2844 23.5516 10.3323ZM23.1301 12.4046L11.9603 15.5579C11.7575 15.6151 11.6175 15.8001 11.6175 16.0108V20.6639C11.6175 24.3243 13.0892 27.8348 15.7088 30.4231L22.9272 37.5553C23.1105 37.7364 23.4054 37.7364 23.5887 37.5553L30.807 30.4231C33.4268 27.8348 34.8983 24.3243 34.8983 20.6639V16.0108C34.8983 15.8001 34.7583 15.6151 34.5556 15.5579L23.3858 12.4046C23.3022 12.381 23.2137 12.381 23.1301 12.4046Z" fill="white"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M23.3165 11.7436L34.14 14.8206C34.5447 14.9356 34.8238 15.3052 34.8238 15.7259V21.1793C34.8238 24.7274 33.4072 28.1301 30.8859 30.6389L23.723 37.7659C23.3558 38.1312 22.7625 38.1312 22.3953 37.7659L15.2325 30.6389C12.711 28.1301 11.2944 24.7274 11.2944 21.1793V15.7259C11.2944 15.3052 11.5736 14.9356 11.9782 14.8206L22.8018 11.7436C22.97 11.6958 23.1483 11.6958 23.3165 11.7436ZM22.8996 13.5561L13.1593 16.3045C12.9566 16.3617 12.8166 16.5467 12.8166 16.7574V20.7932C12.8166 24.0026 14.1075 27.0805 16.4054 29.3498L22.6968 35.5631C22.88 35.7442 23.1748 35.7442 23.3581 35.5631L29.6494 29.3498C31.9474 27.0805 33.2383 24.0026 33.2383 20.7932V16.7574C33.2383 16.5467 33.0983 16.3617 32.8955 16.3045L23.1552 13.5561C23.0717 13.5325 22.9832 13.5325 22.8996 13.5561Z" fill="#6E49CB"/>
-</svg>
diff --git a/app/assets/images/learn_gitlab/trial_started.svg b/app/assets/images/learn_gitlab/trial_started.svg
deleted file mode 100644
index 42d6fb6c013..00000000000
--- a/app/assets/images/learn_gitlab/trial_started.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="32" height="30" viewBox="0 0 32 30" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path fill-rule="evenodd" clip-rule="evenodd" d="M15.9653 29.8263L21.8368 11.6285H10.0933L15.9653 29.8263Z" fill="#E38800"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M15.9656 29.8263L10.0936 11.6285H1.86475L15.9656 29.8263Z" fill="#F7980A"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M1.86441 11.6285L0.0800968 17.1586C-0.0826524 17.663 0.0955967 18.2156 0.521693 18.5273L15.9652 29.8261L1.86441 11.6285Z" fill="#FCA326"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M1.86426 11.6286H10.0933L6.55678 0.668335C6.37489 0.104294 5.58257 0.104447 5.40067 0.668335L1.86426 11.6286Z" fill="#E38800"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M15.9653 29.8263L21.8369 11.6285H30.0658L15.9653 29.8263Z" fill="#F7980A"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M30.0662 11.6285L31.8505 17.1586C32.0132 17.663 31.835 18.2156 31.4089 18.5273L15.9653 29.8261L30.0662 11.6285Z" fill="#FCA326"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M30.066 11.6286H21.8369L25.3735 0.668335C25.5554 0.104294 26.3477 0.104447 26.5296 0.668335L30.066 11.6286Z" fill="#E38800"/>
-</svg>
diff --git a/app/assets/images/learn_gitlab/user_added.svg b/app/assets/images/learn_gitlab/user_added.svg
deleted file mode 100644
index efbccff0bbb..00000000000
--- a/app/assets/images/learn_gitlab/user_added.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-<svg width="38" height="24" viewBox="0 0 38 24" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path d="M33.6353 7.51765H33.8824L32.4706 5.80941L31.0588 7.50353L29.6471 5.80941L28.2353 7.50353L26.8235 5.80941L25.4118 7.50353L24 5.80941L22.5882 7.51765H23.1318C23.6965 8.89412 24 10.4118 24 12C24 14.0047 23.5059 15.8824 22.6447 17.5482C24.0353 19.1576 26.0541 20.1176 28.2353 20.1176C32.3294 20.1176 35.6471 16.7718 35.6471 12.6353C35.6471 10.6588 34.8847 8.85177 33.6353 7.51765ZM22.0094 5.36471C23.7035 3.88235 25.9059 3.03529 28.2353 3.03529C33.5012 3.03529 37.7647 7.34118 37.7647 12.6353C37.7647 17.9294 33.5012 22.2353 28.2353 22.2353C25.6376 22.2353 23.2235 21.1765 21.4588 19.3835C19.2706 22.1929 15.84 24 12 24C5.36471 24 0 18.6353 0 12C0 5.36471 5.36471 0 12 0C14.2729 0 16.3976 0.635295 18.2118 1.72941C19.7153 2.64706 21.0141 3.88235 22.0094 5.37177V5.36471ZM3.52941 8.47059C3.07059 9.55765 2.82353 10.7506 2.82353 12C2.82353 17.0682 6.93177 21.1765 12 21.1765C17.0682 21.1765 21.1765 17.0682 21.1765 12C21.1765 10.7506 20.9294 9.55765 20.4706 8.47059H14.1176C13.7435 8.47059 13.3835 8.32941 13.1294 8.04706L12 6.94588L10.8706 8.06118C10.6165 8.34353 10.2565 8.48471 9.88235 8.48471H3.52941V8.47059ZM18.6212 5.64706C16.9271 3.88235 14.5553 2.82353 12 2.82353C9.44471 2.82353 7.07294 3.88235 5.37882 5.64706H9.29647L11.0047 3.95294C11.5271 3.38824 12.4165 3.38824 12.9812 3.95294L14.6753 5.64706H18.5859H18.6212Z" fill="#E1DBF2"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M25.1292 14.3435C24.6633 14.3435 24.2821 13.9623 24.2821 13.4964C24.2821 13.0164 24.6633 12.6353 25.1292 12.6353C25.5951 12.6353 25.9762 13.0164 25.9762 13.4823C25.9762 13.9623 25.5951 14.3435 25.1292 14.3435ZM31.3409 14.3435C30.8751 14.3435 30.4939 13.9623 30.4939 13.4964C30.4939 13.0164 30.8751 12.6353 31.3409 12.6353C31.8068 12.6353 32.188 13.0164 32.188 13.4823C32.188 13.9623 31.8068 14.3435 31.3409 14.3435ZM9.17624 15.5294H14.8233C14.8233 17.0823 13.5527 18.3529 11.9998 18.3529C10.4468 18.3529 9.17624 17.0823 9.17624 15.5294ZM8.11742 14.8235C7.53153 14.8235 7.05859 14.3505 7.05859 13.7647C7.05859 13.1788 7.53153 12.7058 8.11742 12.7058C8.7033 12.7058 9.17624 13.1788 9.17624 13.7647C9.17624 14.3505 8.7033 14.8235 8.11742 14.8235ZM15.8821 14.8235C15.2962 14.8235 14.8233 14.3505 14.8233 13.7647C14.8233 13.1788 15.2962 12.7058 15.8821 12.7058C16.468 12.7058 16.9409 13.1788 16.9409 13.7647C16.9409 14.3505 16.468 14.8235 15.8821 14.8235Z" fill="#6B4FBB"/>
-</svg>
diff --git a/app/assets/javascripts/alert_management/list.js b/app/assets/javascripts/alert_management/list.js
index e9d19f18ab5..57d1f135606 100644
--- a/app/assets/javascripts/alert_management/list.js
+++ b/app/assets/javascripts/alert_management/list.js
@@ -39,6 +39,7 @@ export default () => {
return defaultDataIdFromObject(object);
},
},
+ assumeImmutableResults: true,
},
),
});
diff --git a/app/assets/javascripts/analytics/shared/utils.js b/app/assets/javascripts/analytics/shared/utils.js
index 84189b675f2..52901d4c5bb 100644
--- a/app/assets/javascripts/analytics/shared/utils.js
+++ b/app/assets/javascripts/analytics/shared/utils.js
@@ -1,4 +1,9 @@
+import dateFormat from 'dateformat';
+import { dateFormats } from './constants';
+
export const filterBySearchTerm = (data = [], searchTerm = '', filterByKey = 'name') => {
if (!searchTerm?.length) return data;
return data.filter((item) => item[filterByKey].toLowerCase().includes(searchTerm.toLowerCase()));
};
+
+export const toYmd = (date) => dateFormat(date, dateFormats.isoDate);
diff --git a/app/assets/javascripts/analytics/usage_trends/index.js b/app/assets/javascripts/analytics/usage_trends/index.js
index d1880b09f15..3e85832edcf 100644
--- a/app/assets/javascripts/analytics/usage_trends/index.js
+++ b/app/assets/javascripts/analytics/usage_trends/index.js
@@ -6,7 +6,7 @@ import UsageTrendsApp from './components/app.vue';
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
- defaultClient: createDefaultClient(),
+ defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
});
export default () => {
diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js
index 84a5d5ae4b3..01e463c1965 100644
--- a/app/assets/javascripts/api.js
+++ b/app/assets/javascripts/api.js
@@ -870,6 +870,14 @@ const Api = {
return axios.put(url, freezePeriod);
},
+ deleteFreezePeriod(id, freezePeriodId) {
+ const url = Api.buildUrl(this.freezePeriodPath)
+ .replace(':id', encodeURIComponent(id))
+ .replace(':freeze_period_id', encodeURIComponent(freezePeriodId));
+
+ return axios.delete(url);
+ },
+
trackRedisCounterEvent(event) {
if (!gon.features?.usageDataApi) {
return null;
diff --git a/app/assets/javascripts/api/projects_api.js b/app/assets/javascripts/api/projects_api.js
index 1cd7fb0b954..b018db9a02d 100644
--- a/app/assets/javascripts/api/projects_api.js
+++ b/app/assets/javascripts/api/projects_api.js
@@ -3,6 +3,7 @@ import axios from '../lib/utils/axios_utils';
import { buildApiUrl } from './api_utils';
const PROJECTS_PATH = '/api/:version/projects.json';
+const PROJECT_IMPORT_MEMBERS_PATH = '/api/:version/projects/:id/import_project_members/:project_id';
export function getProjects(query, options, callback = () => {}) {
const url = buildApiUrl(PROJECTS_PATH);
@@ -25,3 +26,10 @@ export function getProjects(query, options, callback = () => {}) {
return { data, headers };
});
}
+
+export function importProjectMembers(sourceId, targetId) {
+ const url = buildApiUrl(PROJECT_IMPORT_MEMBERS_PATH)
+ .replace(':id', sourceId)
+ .replace(':project_id', targetId);
+ return axios.post(url);
+}
diff --git a/app/assets/javascripts/authentication/two_factor_auth/components/recovery_codes.vue b/app/assets/javascripts/authentication/two_factor_auth/components/recovery_codes.vue
index f89600fbed3..fe801cd460f 100644
--- a/app/assets/javascripts/authentication/two_factor_auth/components/recovery_codes.vue
+++ b/app/assets/javascripts/authentication/two_factor_auth/components/recovery_codes.vue
@@ -165,7 +165,7 @@ export default {
:title="$options.i18n.proceedButton"
variant="confirm"
data-qa-selector="proceed_button"
- data-track-event="click_button"
+ data-track-action="click_button"
:data-track-label="`${$options.trackingLabelPrefix}proceed_button`"
>{{ $options.i18n.proceedButton }}</gl-button
>
diff --git a/app/assets/javascripts/autosave.js b/app/assets/javascripts/autosave.js
index 0a05e0d44ce..8381dcec9c3 100644
--- a/app/assets/javascripts/autosave.js
+++ b/app/assets/javascripts/autosave.js
@@ -6,7 +6,7 @@ export default class Autosave {
constructor(field, key, fallbackKey, lockVersion) {
this.field = field;
- this.isLocalStorageAvailable = AccessorUtilities.isLocalStorageAccessSafe();
+ this.isLocalStorageAvailable = AccessorUtilities.canUseLocalStorage();
if (key.join != null) {
key = key.join('/');
}
diff --git a/app/assets/javascripts/badges/components/badge_form.vue b/app/assets/javascripts/badges/components/badge_form.vue
index 7e605099655..2c7e878f044 100644
--- a/app/assets/javascripts/badges/components/badge_form.vue
+++ b/app/assets/javascripts/badges/components/badge_form.vue
@@ -1,6 +1,5 @@
<script>
-/* eslint-disable vue/no-v-html */
-import { GlLoadingIcon, GlFormInput, GlFormGroup, GlButton } from '@gitlab/ui';
+import { GlLoadingIcon, GlFormInput, GlFormGroup, GlButton, GlSafeHtmlDirective } from '@gitlab/ui';
import { escape, debounce } from 'lodash';
import { mapActions, mapState } from 'vuex';
import createFlash from '~/flash';
@@ -19,6 +18,9 @@ export default {
GlFormInput,
GlFormGroup,
},
+ directives: {
+ SafeHtml: GlSafeHtmlDirective,
+ },
props: {
isEditing: {
type: Boolean,
@@ -168,6 +170,7 @@ export default {
});
},
},
+ safeHtmlConfig: { ALLOW_TAGS: ['a', 'code'] },
};
</script>
@@ -184,7 +187,7 @@ export default {
<div class="form-group">
<label for="badge-link-url" class="label-bold">{{ s__('Badges|Link') }}</label>
- <p v-html="helpText"></p>
+ <p v-safe-html:[$options.safeHtmlConfig]="helpText"></p>
<input
id="badge-link-url"
v-model="linkUrl"
@@ -199,7 +202,7 @@ export default {
<div class="form-group">
<label for="badge-image-url" class="label-bold">{{ s__('Badges|Badge image URL') }}</label>
- <p v-html="helpText"></p>
+ <p v-safe-html:[$options.safeHtmlConfig]="helpText"></p>
<input
id="badge-image-url"
v-model="imageUrl"
diff --git a/app/assets/javascripts/batch_comments/components/draft_note.vue b/app/assets/javascripts/batch_comments/components/draft_note.vue
index 96c3b8276ee..f5e3bab6ff0 100644
--- a/app/assets/javascripts/batch_comments/components/draft_note.vue
+++ b/app/assets/javascripts/batch_comments/components/draft_note.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { GlButton } from '@gitlab/ui';
import { mapActions, mapGetters, mapState } from 'vuex';
import NoteableNote from '~/notes/components/noteable_note.vue';
@@ -106,7 +105,7 @@ export default {
<div
v-if="draftCommands"
class="referenced-commands draft-note-commands"
- v-html="draftCommands"
+ v-html="draftCommands /* eslint-disable-line vue/no-v-html */"
></div>
<p class="draft-note-actions d-flex">
diff --git a/app/assets/javascripts/batch_comments/components/review_bar.vue b/app/assets/javascripts/batch_comments/components/review_bar.vue
index 080a5543e53..bce13751448 100644
--- a/app/assets/javascripts/batch_comments/components/review_bar.vue
+++ b/app/assets/javascripts/batch_comments/components/review_bar.vue
@@ -1,5 +1,6 @@
<script>
import { mapActions, mapGetters } from 'vuex';
+import { REVIEW_BAR_VISIBLE_CLASS_NAME } from '../constants';
import PreviewDropdown from './preview_dropdown.vue';
import PublishButton from './publish_button.vue';
@@ -10,7 +11,6 @@ export default {
},
computed: {
...mapGetters(['isNotesFetched']),
- ...mapGetters('batchComments', ['draftsCount']),
},
watch: {
isNotesFetched() {
@@ -19,13 +19,19 @@ export default {
}
},
},
+ mounted() {
+ document.body.classList.add(REVIEW_BAR_VISIBLE_CLASS_NAME);
+ },
+ beforeDestroy() {
+ document.body.classList.remove(REVIEW_BAR_VISIBLE_CLASS_NAME);
+ },
methods: {
...mapActions('batchComments', ['expandAllDiscussions']),
},
};
</script>
<template>
- <div v-show="draftsCount > 0">
+ <div>
<nav class="review-bar-component" data-testid="review_bar_component">
<div
class="review-bar-content d-flex gl-justify-content-end"
diff --git a/app/assets/javascripts/batch_comments/constants.js b/app/assets/javascripts/batch_comments/constants.js
index b309c339fc8..5e026251e0b 100644
--- a/app/assets/javascripts/batch_comments/constants.js
+++ b/app/assets/javascripts/batch_comments/constants.js
@@ -1,3 +1,5 @@
export const CHANGES_TAB = 'diffs';
export const DISCUSSION_TAB = 'notes';
export const SHOW_TAB = 'show';
+
+export const REVIEW_BAR_VISIBLE_CLASS_NAME = 'review-bar-visible';
diff --git a/app/assets/javascripts/batch_comments/index.js b/app/assets/javascripts/batch_comments/index.js
index 9c763e70d63..65fd34dcb00 100644
--- a/app/assets/javascripts/batch_comments/index.js
+++ b/app/assets/javascripts/batch_comments/index.js
@@ -1,7 +1,6 @@
import Vue from 'vue';
-import { mapActions } from 'vuex';
+import { mapActions, mapGetters } from 'vuex';
import store from '~/mr_notes/stores';
-import ReviewBar from './components/review_bar.vue';
export const initReviewBar = () => {
const el = document.getElementById('js-review-bar');
@@ -10,6 +9,12 @@ export const initReviewBar = () => {
new Vue({
el,
store,
+ components: {
+ ReviewBar: () => import('./components/review_bar.vue'),
+ },
+ computed: {
+ ...mapGetters('batchComments', ['draftsCount']),
+ },
mounted() {
this.fetchDrafts();
},
@@ -17,7 +22,9 @@ export const initReviewBar = () => {
...mapActions('batchComments', ['fetchDrafts']),
},
render(createElement) {
- return createElement(ReviewBar);
+ if (this.draftsCount === 0) return null;
+
+ return createElement('review-bar');
},
});
};
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/playable.js b/app/assets/javascripts/behaviors/markdown/nodes/playable.js
index 33bb6e0c31c..2b667aba2d6 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/playable.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/playable.js
@@ -3,7 +3,6 @@
import { defaultMarkdownSerializer } from 'prosemirror-markdown';
import { Node } from 'tiptap';
-import { HIGHER_PARSE_RULE_PRIORITY } from '../constants';
/**
* Abstract base class for playable media, like video and audio.
@@ -33,33 +32,33 @@ export default class Playable extends Node {
const parseDOM = [
{
tag: `.${this.mediaType}-container`,
- skip: true,
- },
- {
- tag: `.${this.mediaType}-container p`,
- priority: HIGHER_PARSE_RULE_PRIORITY,
- ignore: true,
- },
- {
- tag: `${this.mediaType}[src]`,
- getAttrs: (el) => ({ src: el.src, alt: el.dataset.title }),
+ getAttrs: (el) => ({
+ src: el.querySelector(this.mediaType).src,
+ alt: el.querySelector(this.mediaType).dataset.title,
+ }),
},
];
const toDOM = (node) => [
- this.mediaType,
- {
- src: node.attrs.src,
- controls: true,
- 'data-setup': '{}',
- 'data-title': node.attrs.alt,
- ...this.extraElementAttrs,
- },
+ 'span',
+ { class: `media-container ${this.mediaType}-container` },
+ [
+ this.mediaType,
+ {
+ src: node.attrs.src,
+ controls: true,
+ 'data-setup': '{}',
+ 'data-title': node.attrs.alt,
+ ...this.extraElementAttrs,
+ },
+ ],
+ ['a', { href: node.attrs.src }, node.attrs.alt],
];
return {
attrs,
- group: 'block',
+ group: 'inline',
+ inline: true,
draggable: true,
parseDOM,
toDOM,
@@ -68,6 +67,5 @@ export default class Playable extends Node {
toMarkdown(state, node) {
defaultMarkdownSerializer.nodes.image(state, node);
- state.closeBlock(node);
}
}
diff --git a/app/assets/javascripts/behaviors/shortcuts/keybindings.js b/app/assets/javascripts/behaviors/shortcuts/keybindings.js
index 005ef103ded..ebf2ab0381e 100644
--- a/app/assets/javascripts/behaviors/shortcuts/keybindings.js
+++ b/app/assets/javascripts/behaviors/shortcuts/keybindings.js
@@ -19,7 +19,7 @@ export const LOCAL_STORAGE_KEY = 'gl-keyboard-shortcuts-customizations';
*/
export const getCustomizations = memoize(() => {
let parsedCustomizations = {};
- const localStorageIsSafe = AccessorUtilities.isLocalStorageAccessSafe();
+ const localStorageIsSafe = AccessorUtilities.canUseLocalStorage();
if (localStorageIsSafe) {
try {
diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.vue b/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.vue
index 8f1518a1c9c..cf7a71d4206 100644
--- a/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.vue
+++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.vue
@@ -13,7 +13,7 @@ export default {
},
data() {
return {
- localStorageUsable: AccessorUtilities.isLocalStorageAccessSafe(),
+ localStorageUsable: AccessorUtilities.canUseLocalStorage(),
shortcutsEnabled: !shouldDisableShortcuts(),
};
},
diff --git a/app/assets/javascripts/blob/blob_file_dropzone.js b/app/assets/javascripts/blob/blob_file_dropzone.js
index 470c679b8ba..387d6043315 100644
--- a/app/assets/javascripts/blob/blob_file_dropzone.js
+++ b/app/assets/javascripts/blob/blob_file_dropzone.js
@@ -31,7 +31,6 @@ export default class BlobFileDropzone {
autoProcessQueue: false,
url: form.attr('action'),
// Rails uses a hidden input field for PUT
- // http://stackoverflow.com/questions/21056482/how-to-set-method-put-in-form-tag-in-rails
method,
clickable: true,
uploadMultiple: false,
diff --git a/app/assets/javascripts/blob/notebook/index.js b/app/assets/javascripts/blob/notebook/index.js
index a8c94b6263e..25fe29c4fbe 100644
--- a/app/assets/javascripts/blob/notebook/index.js
+++ b/app/assets/javascripts/blob/notebook/index.js
@@ -6,6 +6,9 @@ export default () => {
return new Vue({
el,
+ provide: {
+ relativeRawPath: el.dataset.relativeRawPath,
+ },
render(createElement) {
return createElement(NotebookViewer, {
props: {
diff --git a/app/assets/javascripts/blob/notebook/notebook_viewer.vue b/app/assets/javascripts/blob/notebook/notebook_viewer.vue
index 02f93e14219..d2a841c88f1 100644
--- a/app/assets/javascripts/blob/notebook/notebook_viewer.vue
+++ b/app/assets/javascripts/blob/notebook/notebook_viewer.vue
@@ -77,3 +77,9 @@ export default {
</p>
</div>
</template>
+
+<style>
+.output img {
+ min-width: 0; /* https://www.w3.org/TR/css-flexbox-1/#min-size-auto */
+}
+</style>
diff --git a/app/assets/javascripts/blob/pipeline_tour_success_modal.vue b/app/assets/javascripts/blob/pipeline_tour_success_modal.vue
index fdaa4b082f7..a3278f8bde2 100644
--- a/app/assets/javascripts/blob/pipeline_tour_success_modal.vue
+++ b/app/assets/javascripts/blob/pipeline_tour_success_modal.vue
@@ -124,7 +124,7 @@ export default {
:href="goToMergeRequestPath"
:data-track-property="humanAccess"
:data-track-value="$options.goToTrackValueMergeRequest"
- :data-track-event="$options.trackEvent"
+ :data-track-action="$options.trackEvent"
:data-track-label="trackLabel"
>
{{ $options.i18n.mergeRequestButton }}
@@ -135,7 +135,7 @@ export default {
variant="success"
:data-track-property="humanAccess"
:data-track-value="$options.goToTrackValuePipelines"
- :data-track-event="$options.trackEvent"
+ :data-track-action="$options.trackEvent"
:data-track-label="trackLabel"
>
{{ $options.i18n.pipelinesButton }}
diff --git a/app/assets/javascripts/blob/suggest_gitlab_ci_yml/components/popover.vue b/app/assets/javascripts/blob/suggest_gitlab_ci_yml/components/popover.vue
index aee8bf15e44..e0b0857f7b4 100644
--- a/app/assets/javascripts/blob/suggest_gitlab_ci_yml/components/popover.vue
+++ b/app/assets/javascripts/blob/suggest_gitlab_ci_yml/components/popover.vue
@@ -121,7 +121,7 @@ export default {
icon="close"
:data-track-property="humanAccess"
:data-track-value="$options.dismissTrackValue"
- :data-track-event="$options.clickTrackValue"
+ :data-track-action="$options.clickTrackValue"
:data-track-label="trackLabel"
@click="onDismiss"
/>
diff --git a/app/assets/javascripts/boards/boards_util.js b/app/assets/javascripts/boards/boards_util.js
index 3219d74f85f..d113a1d39d8 100644
--- a/app/assets/javascripts/boards/boards_util.js
+++ b/app/assets/javascripts/boards/boards_util.js
@@ -1,6 +1,5 @@
import { sortBy, cloneDeep } from 'lodash';
-import { getIdFromGraphQLId } from '~/graphql_shared/utils';
-import { ListType } from './constants';
+import { ListType, MilestoneIDs } from './constants';
export function getMilestone() {
return null;
@@ -49,12 +48,10 @@ export function formatListIssues(listIssues) {
return {
...map,
[list.id]: sortedIssues.map((i) => {
- const id = getIdFromGraphQLId(i.id);
+ const { id } = i;
const listIssue = {
...i,
- id,
- fullId: i.id,
labels: i.labels?.nodes || [],
assignees: i.assignees?.nodes || [],
};
@@ -108,7 +105,10 @@ export function formatIssueInput(issueInput, boardConfig) {
return {
...issueInput,
- milestoneId: milestoneId ? fullMilestoneId(milestoneId) : null,
+ milestoneId:
+ milestoneId && milestoneId !== MilestoneIDs.ANY
+ ? fullMilestoneId(milestoneId)
+ : issueInput?.milestoneId,
labelIds: [...labelIds, ...(labels?.map((l) => fullLabelId(l)) || [])],
assigneeIds: [...assigneeIds, ...(assigneeId ? [fullUserId(assigneeId)] : [])],
};
diff --git a/app/assets/javascripts/boards/components/board_add_new_column.vue b/app/assets/javascripts/boards/components/board_add_new_column.vue
index d4b559add6e..22ad619e76b 100644
--- a/app/assets/javascripts/boards/components/board_add_new_column.vue
+++ b/app/assets/javascripts/boards/components/board_add_new_column.vue
@@ -2,9 +2,6 @@
import { GlFormRadio, GlFormRadioGroup, GlTooltipDirective as GlTooltip } from '@gitlab/ui';
import { mapActions, mapGetters, mapState } from 'vuex';
import BoardAddNewColumnForm from '~/boards/components/board_add_new_column_form.vue';
-import { ListType } from '~/boards/constants';
-import boardsStore from '~/boards/stores/boards_store';
-import { getIdFromGraphQLId } from '~/graphql_shared/utils';
export default {
components: {
@@ -24,7 +21,7 @@ export default {
},
computed: {
...mapState(['labels', 'labelsLoading']),
- ...mapGetters(['getListByLabelId', 'shouldUseGraphQL']),
+ ...mapGetters(['getListByLabelId']),
columnForSelected() {
return this.getListByLabelId(this.selectedId);
},
@@ -34,17 +31,6 @@ export default {
},
methods: {
...mapActions(['createList', 'fetchLabels', 'highlightList', 'setAddColumnFormVisibility']),
- highlight(listId) {
- if (this.shouldUseGraphQL) {
- this.highlightList(listId);
- } else {
- const list = boardsStore.state.lists.find(({ id }) => id === listId);
- list.highlighted = true;
- setTimeout(() => {
- list.highlighted = false;
- }, 2000);
- }
- },
addList() {
if (!this.selectedLabel) {
return;
@@ -54,23 +40,11 @@ export default {
if (this.columnForSelected) {
const listId = this.columnForSelected.id;
- this.highlight(listId);
+ this.highlightList(listId);
return;
}
- if (this.shouldUseGraphQL) {
- this.createList({ labelId: this.selectedId });
- } else {
- const listObj = {
- labelId: getIdFromGraphQLId(this.selectedId),
- title: this.selectedLabel.title,
- position: boardsStore.state.lists.length - 2,
- list_type: ListType.label,
- label: this.selectedLabel,
- };
-
- boardsStore.new(listObj);
- }
+ this.createList({ labelId: this.selectedId });
},
filterItems(searchTerm) {
diff --git a/app/assets/javascripts/boards/components/board_app.vue b/app/assets/javascripts/boards/components/board_app.vue
new file mode 100644
index 00000000000..28f4a267077
--- /dev/null
+++ b/app/assets/javascripts/boards/components/board_app.vue
@@ -0,0 +1,29 @@
+<script>
+import { mapActions, mapGetters } from 'vuex';
+import BoardContent from '~/boards/components/board_content.vue';
+import BoardSettingsSidebar from '~/boards/components/board_settings_sidebar.vue';
+
+export default {
+ components: {
+ BoardContent,
+ BoardSettingsSidebar,
+ },
+ inject: ['disabled'],
+ computed: {
+ ...mapGetters(['isSidebarOpen']),
+ },
+ mounted() {
+ this.performSearch();
+ },
+ methods: {
+ ...mapActions(['performSearch']),
+ },
+};
+</script>
+
+<template>
+ <div class="boards-app gl-relative" :class="{ 'is-compact': isSidebarOpen }">
+ <board-content :disabled="disabled" />
+ <board-settings-sidebar />
+ </div>
+</template>
diff --git a/app/assets/javascripts/boards/components/board_card_deprecated.vue b/app/assets/javascripts/boards/components/board_card_deprecated.vue
deleted file mode 100644
index e12a2836f67..00000000000
--- a/app/assets/javascripts/boards/components/board_card_deprecated.vue
+++ /dev/null
@@ -1,61 +0,0 @@
-<script>
-// This component is being replaced in favor of './board_card.vue' for GraphQL boards
-import sidebarEventHub from '~/sidebar/event_hub';
-import eventHub from '../eventhub';
-import boardsStore from '../stores/boards_store';
-import BoardCardLayoutDeprecated from './board_card_layout_deprecated.vue';
-
-export default {
- components: {
- BoardCardLayout: BoardCardLayoutDeprecated,
- },
- props: {
- list: {
- type: Object,
- default: () => ({}),
- required: false,
- },
- issue: {
- type: Object,
- default: () => ({}),
- required: false,
- },
- },
- methods: {
- // These are methods instead of computed's, because boardsStore is not reactive.
- isActive() {
- return this.getActiveId() === this.issue.id;
- },
- getActiveId() {
- return boardsStore.detail?.issue?.id;
- },
- showIssue({ isMultiSelect }) {
- // If no issues are opened, close all sidebars first
- if (!this.getActiveId()) {
- sidebarEventHub.$emit('sidebar.closeAll');
- }
- if (this.isActive()) {
- eventHub.$emit('clearDetailIssue', isMultiSelect);
-
- if (isMultiSelect) {
- eventHub.$emit('newDetailIssue', this.issue, isMultiSelect);
- }
- } else {
- eventHub.$emit('newDetailIssue', this.issue, isMultiSelect);
- boardsStore.setListDetail(this.list);
- }
- },
- },
-};
-</script>
-
-<template>
- <board-card-layout
- data-qa-selector="board_card"
- :issue="issue"
- :list="list"
- :is-active="isActive()"
- v-bind="$attrs"
- @show="showIssue"
- />
-</template>
diff --git a/app/assets/javascripts/boards/components/board_card_inner.vue b/app/assets/javascripts/boards/components/board_card_inner.vue
index 5658a34e9a6..db80d48239b 100644
--- a/app/assets/javascripts/boards/components/board_card_inner.vue
+++ b/app/assets/javascripts/boards/components/board_card_inner.vue
@@ -214,10 +214,19 @@ export default {
class="confidential-icon gl-mr-2"
:aria-label="__('Confidential')"
/>
+ <gl-icon
+ v-if="item.hidden"
+ v-gl-tooltip
+ name="spam"
+ :title="__('This issue is hidden because its author has been banned')"
+ class="gl-mr-2 hidden-icon"
+ data-testid="hidden-icon"
+ />
<a
:href="item.path || item.webUrl || ''"
:title="item.title"
:class="{ 'gl-text-gray-400!': item.isLoading }"
+ class="js-no-trigger"
@mousemove.stop
>{{ item.title }}</a
>
diff --git a/app/assets/javascripts/boards/components/board_card_layout_deprecated.vue b/app/assets/javascripts/boards/components/board_card_layout_deprecated.vue
deleted file mode 100644
index 3381e4c3a7d..00000000000
--- a/app/assets/javascripts/boards/components/board_card_layout_deprecated.vue
+++ /dev/null
@@ -1,101 +0,0 @@
-<script>
-import { mapActions, mapGetters } from 'vuex';
-import { ISSUABLE } from '~/boards/constants';
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
-import boardsStore from '../stores/boards_store';
-import IssueCardInnerDeprecated from './issue_card_inner_deprecated.vue';
-
-export default {
- name: 'BoardCardLayout',
- components: {
- IssueCardInner: IssueCardInnerDeprecated,
- },
- mixins: [glFeatureFlagMixin()],
- props: {
- list: {
- type: Object,
- default: () => ({}),
- required: false,
- },
- issue: {
- type: Object,
- default: () => ({}),
- required: false,
- },
- disabled: {
- type: Boolean,
- default: false,
- required: false,
- },
- index: {
- type: Number,
- default: 0,
- required: false,
- },
- isActive: {
- type: Boolean,
- required: false,
- default: false,
- },
- },
- data() {
- return {
- showDetail: false,
- multiSelect: boardsStore.multiSelect,
- };
- },
- computed: {
- ...mapGetters(['isSwimlanesOn']),
- multiSelectVisible() {
- return this.multiSelect.list.findIndex((issue) => issue.id === this.issue.id) > -1;
- },
- },
- methods: {
- ...mapActions(['setActiveId']),
- mouseDown() {
- this.showDetail = true;
- },
- mouseMove() {
- this.showDetail = false;
- },
- showIssue(e) {
- // Don't do anything if this happened on a no trigger element
- if (e.target.classList.contains('js-no-trigger')) return;
-
- if (this.glFeatures.graphqlBoardLists || this.isSwimlanesOn) {
- this.setActiveId({ id: this.issue.id, sidebarType: ISSUABLE });
- return;
- }
-
- const isMultiSelect = e.ctrlKey || e.metaKey;
-
- if (this.showDetail || isMultiSelect) {
- this.showDetail = false;
- this.$emit('show', { event: e, isMultiSelect });
- }
- },
- },
-};
-</script>
-
-<template>
- <li
- :class="{
- 'multi-select': multiSelectVisible,
- 'user-can-drag': !disabled && issue.id,
- 'is-disabled': disabled || !issue.id,
- 'is-active': isActive,
- }"
- :index="index"
- :data-issue-id="issue.id"
- :data-issue-iid="issue.iid"
- :data-issue-path="issue.referencePath"
- data-testid="board_card"
- class="board-card gl-p-5 gl-rounded-base"
- @mousedown="mouseDown"
- @mousemove="mouseMove"
- @mouseup="showIssue($event)"
- >
- <issue-card-inner :list="list" :issue="issue" :update-filters="true" />
- </li>
-</template>
diff --git a/app/assets/javascripts/boards/components/board_column_deprecated.vue b/app/assets/javascripts/boards/components/board_column_deprecated.vue
deleted file mode 100644
index 7c090dfaa53..00000000000
--- a/app/assets/javascripts/boards/components/board_column_deprecated.vue
+++ /dev/null
@@ -1,112 +0,0 @@
-<script>
-// This component is being replaced in favor of './board_column.vue' for GraphQL boards
-import Sortable from 'sortablejs';
-import BoardListHeader from 'ee_else_ce/boards/components/board_list_header_deprecated.vue';
-import { getBoardSortableDefaultOptions, sortableEnd } from '../mixins/sortable_default_options';
-import boardsStore from '../stores/boards_store';
-import BoardList from './board_list_deprecated.vue';
-
-export default {
- components: {
- BoardListHeader,
- BoardList,
- },
- inject: {
- boardId: {
- default: '',
- },
- },
- props: {
- list: {
- type: Object,
- default: () => ({}),
- required: false,
- },
- disabled: {
- type: Boolean,
- required: true,
- },
- },
- data() {
- return {
- detailIssue: boardsStore.detail,
- filter: boardsStore.filter,
- };
- },
- computed: {
- listIssues() {
- return this.list.issues;
- },
- },
- watch: {
- filter: {
- handler() {
- // eslint-disable-next-line vue/no-mutating-props
- this.list.page = 1;
- this.list.getIssues(true).catch(() => {
- // TODO: handle request error
- });
- },
- deep: true,
- },
- 'list.highlighted': {
- handler(highlighted) {
- if (highlighted) {
- this.$nextTick(() => {
- this.$el.scrollIntoView({ behavior: 'smooth', block: 'start' });
- });
- }
- },
- immediate: true,
- },
- },
- mounted() {
- const instance = this;
-
- const sortableOptions = getBoardSortableDefaultOptions({
- disabled: this.disabled,
- group: 'boards',
- draggable: '.is-draggable',
- handle: '.js-board-handle',
- onEnd(e) {
- sortableEnd();
-
- const sortable = this;
-
- if (e.newIndex !== undefined && e.oldIndex !== e.newIndex) {
- const order = sortable.toArray();
- const list = boardsStore.findList('id', parseInt(e.item.dataset.id, 10));
-
- instance.$nextTick(() => {
- boardsStore.moveList(list, order);
- });
- }
- },
- });
-
- Sortable.create(this.$el.parentNode, sortableOptions);
- },
-};
-</script>
-
-<template>
- <div
- :class="{
- 'is-draggable': !list.preset,
- 'is-expandable': list.isExpandable,
- 'is-collapsed': !list.isExpanded,
- 'board-type-assignee': list.type === 'assignee',
- }"
- :data-id="list.id"
- class="board gl-display-inline-block gl-h-full gl-px-3 gl-vertical-align-top gl-white-space-normal"
- data-qa-selector="board_list"
- >
- <div
- class="board-inner gl-display-flex gl-flex-direction-column gl-relative gl-h-full gl-rounded-base"
- :class="{ 'board-column-highlighted': list.highlighted }"
- >
- <board-list-header :list="list" :disabled="disabled" />
- <board-list ref="board-list" :disabled="disabled" :issues="listIssues" :list="list" />
- </div>
- </div>
-</template>
diff --git a/app/assets/javascripts/boards/components/board_content.vue b/app/assets/javascripts/boards/components/board_content.vue
index 4df6ff75249..27ea2e7a608 100644
--- a/app/assets/javascripts/boards/components/board_content.vue
+++ b/app/assets/javascripts/boards/components/board_content.vue
@@ -5,31 +5,22 @@ import Draggable from 'vuedraggable';
import { mapState, mapGetters, mapActions } from 'vuex';
import BoardAddNewColumn from 'ee_else_ce/boards/components/board_add_new_column.vue';
import defaultSortableConfig from '~/sortable/sortable_config';
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { DraggableItemTypes } from '../constants';
import BoardColumn from './board_column.vue';
-import BoardColumnDeprecated from './board_column_deprecated.vue';
export default {
draggableItemTypes: DraggableItemTypes,
components: {
BoardAddNewColumn,
BoardColumn,
- BoardColumnDeprecated,
BoardContentSidebar: () => import('~/boards/components/board_content_sidebar.vue'),
EpicBoardContentSidebar: () =>
import('ee_component/boards/components/epic_board_content_sidebar.vue'),
EpicsSwimlanes: () => import('ee_component/boards/components/epics_swimlanes.vue'),
GlAlert,
},
- mixins: [glFeatureFlagMixin()],
inject: ['canAdminList'],
props: {
- lists: {
- type: Array,
- required: false,
- default: () => [],
- },
disabled: {
type: Boolean,
required: true,
@@ -37,20 +28,15 @@ export default {
},
computed: {
...mapState(['boardLists', 'error', 'addColumnForm']),
- ...mapGetters(['isSwimlanesOn', 'isEpicBoard']),
- useNewBoardColumnComponent() {
- return this.glFeatures.graphqlBoardLists || this.isSwimlanesOn || this.isEpicBoard;
- },
+ ...mapGetters(['isSwimlanesOn', 'isEpicBoard', 'isIssueBoard']),
addColumnFormVisible() {
return this.addColumnForm?.visible;
},
boardListsToUse() {
- return this.useNewBoardColumnComponent
- ? sortBy([...Object.values(this.boardLists)], 'position')
- : this.lists;
+ return sortBy([...Object.values(this.boardLists)], 'position');
},
canDragColumns() {
- return (this.isEpicBoard || this.glFeatures.graphqlBoardLists) && this.canAdminList;
+ return this.canAdminList;
},
boardColumnWrapper() {
return this.canDragColumns ? Draggable : 'div';
@@ -68,9 +54,6 @@ export default {
return this.canDragColumns ? options : {};
},
- boardColumnComponent() {
- return this.useNewBoardColumnComponent ? BoardColumn : BoardColumnDeprecated;
- },
},
methods: {
...mapActions(['moveList', 'unsetError']),
@@ -95,8 +78,7 @@ export default {
class="boards-list gl-w-full gl-py-5 gl-px-3 gl-white-space-nowrap"
@end="moveList"
>
- <component
- :is="boardColumnComponent"
+ <board-column
v-for="(list, index) in boardListsToUse"
:key="index"
ref="board"
@@ -118,10 +100,7 @@ export default {
:disabled="disabled"
/>
- <board-content-sidebar
- v-if="isSwimlanesOn || glFeatures.graphqlBoardLists"
- data-testid="issue-boards-sidebar"
- />
+ <board-content-sidebar v-if="isIssueBoard" data-testid="issue-boards-sidebar" />
<epic-board-content-sidebar v-else-if="isEpicBoard" data-testid="epic-boards-sidebar" />
</div>
diff --git a/app/assets/javascripts/boards/components/board_content_sidebar.vue b/app/assets/javascripts/boards/components/board_content_sidebar.vue
index 7a936e75676..e0105d63d99 100644
--- a/app/assets/javascripts/boards/components/board_content_sidebar.vue
+++ b/app/assets/javascripts/boards/components/board_content_sidebar.vue
@@ -96,7 +96,7 @@ export default {
<template #header>
<sidebar-todo-widget
class="gl-mt-3"
- :issuable-id="activeBoardItem.fullId"
+ :issuable-id="activeBoardItem.id"
:issuable-iid="activeBoardItem.iid"
:full-path="fullPath"
:issuable-type="issuableType"
diff --git a/app/assets/javascripts/boards/components/board_form.vue b/app/assets/javascripts/boards/components/board_form.vue
index a89f71504a9..e939f0c0ebe 100644
--- a/app/assets/javascripts/boards/components/board_form.vue
+++ b/app/assets/javascripts/boards/components/board_form.vue
@@ -1,8 +1,7 @@
<script>
import { GlModal, GlAlert } from '@gitlab/ui';
import { mapGetters, mapActions, mapState } from 'vuex';
-import ListLabel from '~/boards/models/label';
-import { TYPE_ITERATION, TYPE_MILESTONE } from '~/graphql_shared/constants';
+import { TYPE_USER, TYPE_ITERATION, TYPE_MILESTONE } from '~/graphql_shared/constants';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import { getParameterByName, visitUrl } from '~/lib/utils/url_utility';
import { __, s__ } from '~/locale';
@@ -189,7 +188,9 @@ export default {
issueBoardScopeMutationVariables() {
return {
weight: this.board.weight,
- assigneeId: this.board.assignee?.id || null,
+ assigneeId: this.board.assignee?.id
+ ? convertToGraphQLId(TYPE_USER, this.board.assignee.id)
+ : null,
milestoneId: this.board.milestone?.id
? convertToGraphQLId(TYPE_MILESTONE, this.board.milestone.id)
: null,
@@ -289,14 +290,10 @@ export default {
setBoardLabels(labels) {
labels.forEach((label) => {
if (label.set && !this.board.labels.find((l) => l.id === label.id)) {
- this.board.labels.push(
- new ListLabel({
- id: label.id,
- title: label.title,
- color: label.color,
- textColor: label.text_color,
- }),
- );
+ this.board.labels.push({
+ ...label,
+ textColor: label.text_color,
+ });
} else if (!label.set) {
this.board.labels = this.board.labels.filter((selected) => selected.id !== label.id);
}
diff --git a/app/assets/javascripts/boards/components/board_list.vue b/app/assets/javascripts/boards/components/board_list.vue
index 849492effab..47dffc985aa 100644
--- a/app/assets/javascripts/boards/components/board_list.vue
+++ b/app/assets/javascripts/boards/components/board_list.vue
@@ -208,7 +208,7 @@ export default {
newIndex = children.length;
}
- const getItemId = (el) => Number(el.dataset.itemId);
+ const getItemId = (el) => el.dataset.itemId;
// If item is being moved within the same list
if (from === to) {
@@ -234,7 +234,7 @@ export default {
}
this.moveItem({
- itemId: Number(itemId),
+ itemId,
itemIid,
itemPath,
fromListId: from.dataset.listId,
diff --git a/app/assets/javascripts/boards/components/board_list_deprecated.vue b/app/assets/javascripts/boards/components/board_list_deprecated.vue
deleted file mode 100644
index fabaf7a85f5..00000000000
--- a/app/assets/javascripts/boards/components/board_list_deprecated.vue
+++ /dev/null
@@ -1,459 +0,0 @@
-<script>
-import { GlLoadingIcon } from '@gitlab/ui';
-import { Sortable, MultiDrag } from 'sortablejs';
-import createFlash from '~/flash';
-import { BV_HIDE_TOOLTIP } from '~/lib/utils/constants';
-import { sprintf, __ } from '~/locale';
-import eventHub from '../eventhub';
-import {
- getBoardSortableDefaultOptions,
- sortableStart,
- sortableEnd,
-} from '../mixins/sortable_default_options';
-import boardsStore from '../stores/boards_store';
-import boardCard from './board_card_deprecated.vue';
-import boardNewIssue from './board_new_issue_deprecated.vue';
-
-// This component is being replaced in favor of './board_list.vue' for GraphQL boards
-
-Sortable.mount(new MultiDrag());
-
-export default {
- name: 'BoardList',
- components: {
- boardCard,
- boardNewIssue,
- GlLoadingIcon,
- },
- props: {
- disabled: {
- type: Boolean,
- required: true,
- },
- list: {
- type: Object,
- required: true,
- },
- issues: {
- type: Array,
- required: true,
- },
- },
- data() {
- return {
- scrollOffset: 250,
- filters: boardsStore.state.filters,
- showCount: false,
- showIssueForm: false,
- };
- },
- computed: {
- paginatedIssueText() {
- return sprintf(__('Showing %{pageSize} of %{total} issues'), {
- pageSize: this.list.issues.length,
- total: this.list.issuesSize,
- });
- },
- issuesSizeExceedsMax() {
- return this.list.maxIssueCount > 0 && this.list.issuesSize > this.list.maxIssueCount;
- },
- loading() {
- return this.list.loading;
- },
- },
- watch: {
- filters: {
- handler() {
- // eslint-disable-next-line vue/no-mutating-props
- this.list.loadingMore = false;
- this.$refs.list.scrollTop = 0;
- },
- deep: true,
- },
- issues() {
- this.$nextTick(() => {
- if (
- this.scrollHeight() <= this.listHeight() &&
- this.list.issuesSize > this.list.issues.length &&
- this.list.isExpanded
- ) {
- // eslint-disable-next-line vue/no-mutating-props
- this.list.page += 1;
- this.list.getIssues(false).catch(() => {
- // TODO: handle request error
- });
- }
-
- if (this.scrollHeight() > Math.ceil(this.listHeight())) {
- this.showCount = true;
- } else {
- this.showCount = false;
- }
- });
- },
- 'list.id': {
- handler(id) {
- if (id) {
- eventHub.$on(`toggle-issue-form-${this.list.id}`, this.toggleForm);
- }
- },
- },
- },
- created() {
- eventHub.$on(`toggle-issue-form-${this.list.id}`, this.toggleForm);
- eventHub.$on(`scroll-board-list-${this.list.id}`, this.scrollToTop);
- },
- mounted() {
- const multiSelectOpts = {
- multiDrag: true,
- selectedClass: 'js-multi-select',
- animation: 500,
- };
-
- const options = getBoardSortableDefaultOptions({
- scroll: true,
- disabled: this.disabled,
- filter: '.board-list-count, .is-disabled',
- dataIdAttr: 'data-issue-id',
- removeCloneOnHide: false,
- ...multiSelectOpts,
- group: {
- name: 'issues',
- /**
- * Dynamically determine between which containers
- * items can be moved or copied as
- * Assignee lists (EE feature) require this behavior
- */
- pull: (to, from, dragEl, e) => {
- // As per Sortable's docs, `to` should provide
- // reference to exact sortable container on which
- // we're trying to drag element, but either it is
- // a library's bug or our markup structure is too complex
- // that `to` never points to correct container
- // See https://github.com/RubaXa/Sortable/issues/1037
- //
- // So we use `e.target` which is always accurate about
- // which element we're currently dragging our card upon
- // So from there, we can get reference to actual container
- // and thus the container type to enable Copy or Move
- if (e.target) {
- const containerEl =
- e.target.closest('.js-board-list') || e.target.querySelector('.js-board-list');
- const toBoardType = containerEl.dataset.boardType;
- const cloneActions = {
- label: ['milestone', 'assignee', 'iteration'],
- assignee: ['milestone', 'label', 'iteration'],
- milestone: ['label', 'assignee', 'iteration'],
- iteration: ['label', 'assignee', 'milestone'],
- };
-
- if (toBoardType) {
- const fromBoardType = this.list.type;
- // For each list we check if the destination list is
- // a the list were we should clone the issue
- const shouldClone = Object.entries(cloneActions).some(
- (entry) => fromBoardType === entry[0] && entry[1].includes(toBoardType),
- );
-
- if (shouldClone) {
- return 'clone';
- }
- }
- }
-
- return true;
- },
- revertClone: true,
- },
- onStart: (e) => {
- const card = this.$refs.issue[e.oldIndex];
-
- card.showDetail = false;
-
- const { list } = card;
-
- const issue = list.findIssue(Number(e.item.dataset.issueId));
-
- boardsStore.startMoving(list, issue);
-
- this.$root.$emit(BV_HIDE_TOOLTIP);
-
- sortableStart();
- },
- onAdd: (e) => {
- const { items = [], newIndicies = [] } = e;
- if (items.length) {
- // Not using e.newIndex here instead taking a min of all
- // the newIndicies. Basically we have to find that during
- // a drop what is the index we're going to start putting
- // all the dropped elements from.
- const newIndex = Math.min(...newIndicies.map((obj) => obj.index).filter((i) => i !== -1));
- const issues = items.map((item) =>
- boardsStore.moving.list.findIssue(Number(item.dataset.issueId)),
- );
-
- boardsStore.moveMultipleIssuesToList({
- listFrom: boardsStore.moving.list,
- listTo: this.list,
- issues,
- newIndex,
- });
- } else {
- boardsStore.moveIssueToList(
- boardsStore.moving.list,
- this.list,
- boardsStore.moving.issue,
- e.newIndex,
- );
- this.$nextTick(() => {
- e.item.remove();
- });
- }
- },
- onUpdate: (e) => {
- const sortedArray = this.sortable.toArray().filter((id) => id !== '-1');
-
- const { items = [], newIndicies = [], oldIndicies = [] } = e;
- if (items.length) {
- const newIndex = Math.min(...newIndicies.map((obj) => obj.index));
- const issues = items.map((item) =>
- boardsStore.moving.list.findIssue(Number(item.dataset.issueId)),
- );
- boardsStore.moveMultipleIssuesInList({
- list: this.list,
- issues,
- oldIndicies: oldIndicies.map((obj) => obj.index),
- newIndex,
- idArray: sortedArray,
- });
- e.items.forEach((el) => {
- Sortable.utils.deselect(el);
- });
- boardsStore.clearMultiSelect();
- return;
- }
-
- boardsStore.moveIssueInList(
- this.list,
- boardsStore.moving.issue,
- e.oldIndex,
- e.newIndex,
- sortedArray,
- );
- },
- onEnd: (e) => {
- const { items = [], clones = [], to } = e;
-
- // This is not a multi select operation
- if (!items.length && !clones.length) {
- sortableEnd();
- return;
- }
-
- let toList;
- if (to) {
- const containerEl = to.closest('.js-board-list');
- toList = boardsStore.findList('id', Number(containerEl.dataset.board));
- }
-
- /**
- * onEnd is called irrespective if the cards were moved in the
- * same list or the other list. Don't remove items if it's same list.
- */
- const isSameList = toList && toList.id === this.list.id;
- if (toList && !isSameList && boardsStore.shouldRemoveIssue(this.list, toList)) {
- const issues = items.map((item) => this.list.findIssue(Number(item.dataset.issueId)));
- if (
- issues.filter(Boolean).length &&
- !boardsStore.issuesAreContiguous(this.list, issues)
- ) {
- const indexes = [];
- const ids = this.list.issues.map((i) => i.id);
- issues.forEach((issue) => {
- const index = ids.indexOf(issue.id);
- if (index > -1) {
- indexes.push(index);
- }
- });
-
- // Descending sort because splice would cause index discrepancy otherwise
- const sortedIndexes = indexes.sort((a, b) => (a < b ? 1 : -1));
-
- sortedIndexes.forEach((i) => {
- /**
- * **setTimeout and splice each element one-by-one in a loop
- * is intended.**
- *
- * The problem here is all the indexes are in the list but are
- * non-contiguous. Due to that, when we splice all the indexes,
- * at once, Vue -- during a re-render -- is unable to find reference
- * nodes and the entire app crashes.
- *
- * If the indexes are contiguous, this piece of code is not
- * executed. If it is, this is a possible regression. Only when
- * issue indexes are far apart, this logic should ever kick in.
- */
- setTimeout(() => {
- // eslint-disable-next-line vue/no-mutating-props
- this.list.issues.splice(i, 1);
- }, 0);
- });
- }
- }
-
- if (!toList) {
- createFlash({
- message: __('Something went wrong while performing the action.'),
- });
- }
-
- if (!isSameList) {
- boardsStore.clearMultiSelect();
-
- // Since Vue's list does not re-render the same keyed item, we'll
- // remove `multi-select` class to express it's unselected
- if (clones && clones.length) {
- clones.forEach((el) => el.classList.remove('multi-select'));
- }
-
- // Due to some bug which I am unable to figure out
- // Sortable does not deselect some pending items from the
- // source list.
- // We'll just do it forcefully here.
- Array.from(document.querySelectorAll('.js-multi-select') || []).forEach((item) => {
- Sortable.utils.deselect(item);
- });
-
- /**
- * SortableJS leaves all the moving items "as is" on the DOM.
- * Vue picks up and rehydrates the DOM, but we need to explicity
- * remove the "trash" items from the DOM.
- *
- * This is in parity to the logic on single item move from a list/in
- * a list. For reference, look at the implementation of onAdd method.
- */
- this.$nextTick(() => {
- if (items && items.length) {
- items.forEach((item) => {
- item.remove();
- });
- }
- });
- }
- sortableEnd();
- },
- onMove(e) {
- return !e.related.classList.contains('board-list-count');
- },
- onSelect(e) {
- const {
- item: { classList },
- } = e;
-
- if (
- classList &&
- classList.contains('js-multi-select') &&
- !classList.contains('multi-select')
- ) {
- Sortable.utils.deselect(e.item);
- }
- },
- onDeselect: (e) => {
- const {
- item: { dataset, classList },
- } = e;
-
- if (
- classList &&
- classList.contains('multi-select') &&
- !classList.contains('js-multi-select')
- ) {
- const issue = this.list.findIssue(Number(dataset.issueId));
- boardsStore.toggleMultiSelect(issue);
- }
- },
- });
-
- this.sortable = Sortable.create(this.$refs.list, options);
-
- // Scroll event on list to load more
- this.$refs.list.addEventListener('scroll', this.onScroll);
- },
- beforeDestroy() {
- eventHub.$off(`toggle-issue-form-${this.list.id}`, this.toggleForm);
- eventHub.$off(`scroll-board-list-${this.list.id}`, this.scrollToTop);
- this.$refs.list.removeEventListener('scroll', this.onScroll);
- },
- methods: {
- listHeight() {
- return this.$refs.list.getBoundingClientRect().height;
- },
- scrollHeight() {
- return this.$refs.list.scrollHeight;
- },
- scrollTop() {
- return this.$refs.list.scrollTop + this.listHeight();
- },
- scrollToTop() {
- this.$refs.list.scrollTop = 0;
- },
- loadNextPage() {
- const getIssues = this.list.nextPage();
- const loadingDone = () => {
- // eslint-disable-next-line vue/no-mutating-props
- this.list.loadingMore = false;
- };
-
- if (getIssues) {
- // eslint-disable-next-line vue/no-mutating-props
- this.list.loadingMore = true;
- getIssues.then(loadingDone).catch(loadingDone);
- }
- },
- toggleForm() {
- this.showIssueForm = !this.showIssueForm;
- },
- onScroll() {
- if (!this.list.loadingMore && this.scrollTop() > this.scrollHeight() - this.scrollOffset) {
- this.loadNextPage();
- }
- },
- },
-};
-</script>
-
-<template>
- <div
- :class="{ 'd-none': !list.isExpanded, 'd-flex flex-column': list.isExpanded }"
- class="board-list-component position-relative h-100"
- data-qa-selector="board_list_cards_area"
- >
- <div v-if="loading" class="board-list-loading text-center" :aria-label="__('Loading issues')">
- <gl-loading-icon size="sm" />
- </div>
- <board-new-issue v-if="list.type !== 'closed' && showIssueForm" :list="list" />
- <ul
- v-show="!loading"
- ref="list"
- :data-board="list.id"
- :data-board-type="list.type"
- :class="{ 'is-smaller': showIssueForm, 'bg-danger-100': issuesSizeExceedsMax }"
- class="board-list w-100 h-100 list-unstyled mb-0 p-1 js-board-list"
- >
- <board-card
- v-for="(issue, index) in issues"
- ref="issue"
- :key="issue.id"
- :index="index"
- :list="list"
- :issue="issue"
- :disabled="disabled"
- />
- <li v-if="showCount" class="board-list-count text-center" data-issue-id="-1">
- <gl-loading-icon v-show="list.loadingMore" size="sm" label="Loading more issues" />
- <span v-if="list.issues.length === list.issuesSize">{{ __('Showing all issues') }}</span>
- <span v-else>{{ paginatedIssueText }}</span>
- </li>
- </ul>
- </div>
-</template>
diff --git a/app/assets/javascripts/boards/components/board_list_header.vue b/app/assets/javascripts/boards/components/board_list_header.vue
index 8d5f0f7eb89..dc5313b1bf6 100644
--- a/app/assets/javascripts/boards/components/board_list_header.vue
+++ b/app/assets/javascripts/boards/components/board_list_header.vue
@@ -201,7 +201,7 @@ export default {
});
},
addToLocalStorage() {
- if (AccessorUtilities.isLocalStorageAccessSafe()) {
+ if (AccessorUtilities.canUseLocalStorage()) {
localStorage.setItem(`${this.uniqueKey}.collapsed`, this.list.collapsed);
}
},
diff --git a/app/assets/javascripts/boards/components/board_list_header_deprecated.vue b/app/assets/javascripts/boards/components/board_list_header_deprecated.vue
deleted file mode 100644
index bc29728fc55..00000000000
--- a/app/assets/javascripts/boards/components/board_list_header_deprecated.vue
+++ /dev/null
@@ -1,361 +0,0 @@
-<script>
-import {
- GlButton,
- GlButtonGroup,
- GlLabel,
- GlTooltip,
- GlIcon,
- GlSprintf,
- GlTooltipDirective,
-} from '@gitlab/ui';
-import { mapActions, mapState } from 'vuex';
-import { isScopedLabel } from '~/lib/utils/common_utils';
-import { BV_HIDE_TOOLTIP } from '~/lib/utils/constants';
-import { n__, s__ } from '~/locale';
-import sidebarEventHub from '~/sidebar/event_hub';
-import AccessorUtilities from '../../lib/utils/accessor';
-import { inactiveId, LIST, ListType } from '../constants';
-import eventHub from '../eventhub';
-import boardsStore from '../stores/boards_store';
-import IssueCount from './item_count.vue';
-
-// This component is being replaced in favor of './board_list_header.vue' for GraphQL boards
-
-export default {
- components: {
- GlButtonGroup,
- GlButton,
- GlLabel,
- GlTooltip,
- GlIcon,
- GlSprintf,
- IssueCount,
- },
- directives: {
- GlTooltip: GlTooltipDirective,
- },
- inject: {
- currentUserId: {
- default: null,
- },
- boardId: {
- default: '',
- },
- },
- props: {
- list: {
- type: Object,
- default: () => ({}),
- required: false,
- },
- disabled: {
- type: Boolean,
- required: true,
- },
- isSwimlanesHeader: {
- type: Boolean,
- required: false,
- default: false,
- },
- },
- data() {
- return {
- weightFeatureAvailable: false,
- };
- },
- computed: {
- ...mapState(['activeId']),
- isLoggedIn() {
- return Boolean(this.currentUserId);
- },
- listType() {
- return this.list.type;
- },
- listAssignee() {
- return this.list?.assignee?.username || '';
- },
- listTitle() {
- return this.list?.label?.description || this.list.title || '';
- },
- showListHeaderButton() {
- return !this.disabled && this.listType !== ListType.closed;
- },
- showMilestoneListDetails() {
- return this.list.type === 'milestone' && this.list.milestone && this.showListDetails;
- },
- showAssigneeListDetails() {
- return this.list.type === 'assignee' && this.showListDetails;
- },
- showIterationListDetails() {
- return this.listType === ListType.iteration && this.showListDetails;
- },
- showListDetails() {
- return this.list.isExpanded || !this.isSwimlanesHeader;
- },
- showListHeaderActions() {
- if (this.isLoggedIn) {
- return this.isNewIssueShown || this.isSettingsShown;
- }
- return false;
- },
- issuesCount() {
- return this.list.issuesSize;
- },
- issuesTooltipLabel() {
- return n__(`%d issue`, `%d issues`, this.issuesCount);
- },
- chevronTooltip() {
- return this.list.isExpanded ? s__('Boards|Collapse') : s__('Boards|Expand');
- },
- chevronIcon() {
- return this.list.isExpanded ? 'chevron-right' : 'chevron-down';
- },
- isNewIssueShown() {
- return this.listType === ListType.backlog || this.showListHeaderButton;
- },
- isSettingsShown() {
- return (
- this.listType !== ListType.backlog && this.showListHeaderButton && this.list.isExpanded
- );
- },
- uniqueKey() {
- // eslint-disable-next-line @gitlab/require-i18n-strings
- return `boards.${this.boardId}.${this.listType}.${this.list.id}`;
- },
- collapsedTooltipTitle() {
- return this.listTitle || this.listAssignee;
- },
- },
- methods: {
- ...mapActions(['setActiveId']),
- openSidebarSettings() {
- if (this.activeId === inactiveId) {
- sidebarEventHub.$emit('sidebar.closeAll');
- }
-
- this.setActiveId({ id: this.list.id, sidebarType: LIST });
- },
- showScopedLabels(label) {
- return boardsStore.scopedLabels.enabled && isScopedLabel(label);
- },
-
- showNewIssueForm() {
- eventHub.$emit(`toggle-issue-form-${this.list.id}`);
- },
- toggleExpanded() {
- // eslint-disable-next-line vue/no-mutating-props
- this.list.isExpanded = !this.list.isExpanded;
-
- if (!this.isLoggedIn) {
- this.addToLocalStorage();
- } else {
- this.updateListFunction();
- }
-
- // When expanding/collapsing, the tooltip on the caret button sometimes stays open.
- // Close all tooltips manually to prevent dangling tooltips.
- this.$root.$emit(BV_HIDE_TOOLTIP);
- },
- addToLocalStorage() {
- if (AccessorUtilities.isLocalStorageAccessSafe()) {
- localStorage.setItem(`${this.uniqueKey}.expanded`, this.list.isExpanded);
- }
- },
- updateListFunction() {
- this.list.update();
- },
- },
-};
-</script>
-
-<template>
- <header
- :class="{
- 'has-border': list.label && list.label.color,
- 'gl-h-full': !list.isExpanded,
- 'board-inner gl-rounded-top-left-base gl-rounded-top-right-base': isSwimlanesHeader,
- }"
- :style="{ borderTopColor: list.label && list.label.color ? list.label.color : null }"
- class="board-header gl-relative"
- data-qa-selector="board_list_header"
- data-testid="board-list-header"
- >
- <h3
- :class="{
- 'user-can-drag': !disabled && !list.preset,
- 'gl-py-3 gl-h-full': !list.isExpanded && !isSwimlanesHeader,
- 'gl-border-b-0': !list.isExpanded || isSwimlanesHeader,
- 'gl-py-2': !list.isExpanded && isSwimlanesHeader,
- 'gl-flex-direction-column': !list.isExpanded,
- }"
- class="board-title gl-m-0 gl-display-flex gl-align-items-center gl-font-base gl-px-3 js-board-handle"
- >
- <gl-button
- v-if="list.isExpandable"
- v-gl-tooltip.hover
- :aria-label="chevronTooltip"
- :title="chevronTooltip"
- :icon="chevronIcon"
- class="board-title-caret no-drag gl-cursor-pointer"
- category="tertiary"
- size="small"
- @click="toggleExpanded"
- />
- <!-- The following is only true in EE and if it is a milestone -->
- <span
- v-if="showMilestoneListDetails"
- aria-hidden="true"
- class="milestone-icon"
- :class="{
- 'gl-mt-3 gl-rotate-90': !list.isExpanded,
- 'gl-mr-2': list.isExpanded,
- }"
- >
- <gl-icon name="timer" />
- </span>
-
- <span
- v-if="showIterationListDetails"
- aria-hidden="true"
- :class="{
- 'gl-mt-3 gl-rotate-90': !list.isExpanded,
- 'gl-mr-2': list.isExpanded,
- }"
- >
- <gl-icon name="iteration" />
- </span>
-
- <a
- v-if="showAssigneeListDetails"
- :href="list.assignee.path"
- class="user-avatar-link js-no-trigger"
- :class="{
- 'gl-mt-3 gl-rotate-90': !list.isExpanded,
- }"
- >
- <img
- v-gl-tooltip.hover.bottom
- :title="listAssignee"
- :alt="list.assignee.name"
- :src="list.assignee.avatar"
- class="avatar s20"
- height="20"
- width="20"
- />
- </a>
- <div
- class="board-title-text"
- :class="{
- 'gl-display-none': !list.isExpanded && isSwimlanesHeader,
- 'gl-flex-grow-0 gl-my-3 gl-mx-0': !list.isExpanded,
- 'gl-flex-grow-1': list.isExpanded,
- }"
- >
- <span
- v-if="list.type !== 'label'"
- v-gl-tooltip.hover
- :class="{
- 'gl-display-block': !list.isExpanded || list.type === 'milestone',
- }"
- :title="listTitle"
- class="board-title-main-text gl-text-truncate"
- >
- {{ list.title }}
- </span>
- <span
- v-if="list.type === 'assignee'"
- class="gl-ml-2 gl-font-weight-normal gl-text-gray-500"
- :class="{ 'gl-display-none': !list.isExpanded }"
- >
- @{{ listAssignee }}
- </span>
- <gl-label
- v-if="list.type === 'label'"
- v-gl-tooltip.hover.bottom
- :background-color="list.label.color"
- :description="list.label.description"
- :scoped="showScopedLabels(list.label)"
- :size="!list.isExpanded ? 'sm' : ''"
- :title="list.label.title"
- />
- </div>
-
- <span
- v-if="isSwimlanesHeader && !list.isExpanded"
- ref="collapsedInfo"
- aria-hidden="true"
- class="board-header-collapsed-info-icon gl-mt-2 gl-cursor-pointer gl-text-gray-500"
- >
- <gl-icon name="information" />
- </span>
- <gl-tooltip v-if="isSwimlanesHeader && !list.isExpanded" :target="() => $refs.collapsedInfo">
- <div class="gl-font-weight-bold gl-pb-2">{{ collapsedTooltipTitle }}</div>
- <div v-if="list.maxIssueCount !== 0">
- &#8226;
- <gl-sprintf :message="__('%{issuesSize} with a limit of %{maxIssueCount}')">
- <template #issuesSize>{{ issuesTooltipLabel }}</template>
- <template #maxIssueCount>{{ list.maxIssueCount }}</template>
- </gl-sprintf>
- </div>
- <div v-else>&#8226; {{ issuesTooltipLabel }}</div>
- <div v-if="weightFeatureAvailable">
- &#8226;
- <gl-sprintf :message="__('%{totalWeight} total weight')">
- <template #totalWeight>{{ list.totalWeight }}</template>
- </gl-sprintf>
- </div>
- </gl-tooltip>
-
- <div
- class="issue-count-badge gl-display-inline-flex gl-pr-0 no-drag text-secondary"
- :class="{
- 'gl-display-none!': !list.isExpanded && isSwimlanesHeader,
- 'gl-p-0': !list.isExpanded,
- }"
- >
- <span class="gl-display-inline-flex">
- <gl-tooltip :target="() => $refs.issueCount" :title="issuesTooltipLabel" />
- <span ref="issueCount" class="issue-count-badge-count">
- <gl-icon class="gl-mr-2" name="issues" />
- <issue-count :items-size="issuesCount" :max-issue-count="list.maxIssueCount" />
- </span>
- <!-- The following is only true in EE. -->
- <template v-if="weightFeatureAvailable">
- <gl-tooltip :target="() => $refs.weightTooltip" :title="weightCountToolTip" />
- <span ref="weightTooltip" class="gl-display-inline-flex gl-ml-3">
- <gl-icon class="gl-mr-2" name="weight" />
- {{ list.totalWeight }}
- </span>
- </template>
- </span>
- </div>
- <gl-button-group v-if="showListHeaderActions" class="board-list-button-group pl-2">
- <gl-button
- v-if="isNewIssueShown"
- ref="newIssueBtn"
- v-gl-tooltip.hover
- :class="{
- 'gl-display-none': !list.isExpanded,
- }"
- :aria-label="__('New issue')"
- :title="__('New issue')"
- class="issue-count-badge-add-button no-drag"
- icon="plus"
- @click="showNewIssueForm"
- />
-
- <gl-button
- v-if="isSettingsShown"
- ref="settingsBtn"
- v-gl-tooltip.hover
- :aria-label="__('List settings')"
- class="no-drag js-board-settings-button"
- :title="__('List settings')"
- icon="settings"
- @click="openSidebarSettings"
- />
- <gl-tooltip :target="() => $refs.settingsBtn">{{ __('List settings') }}</gl-tooltip>
- </gl-button-group>
- </h3>
- </header>
-</template>
diff --git a/app/assets/javascripts/boards/components/board_new_issue_deprecated.vue b/app/assets/javascripts/boards/components/board_new_issue_deprecated.vue
deleted file mode 100644
index a25b436b8de..00000000000
--- a/app/assets/javascripts/boards/components/board_new_issue_deprecated.vue
+++ /dev/null
@@ -1,138 +0,0 @@
-<script>
-import { GlButton } from '@gitlab/ui';
-import { mapGetters } from 'vuex';
-import { getMilestone } from 'ee_else_ce/boards/boards_util';
-import ListIssue from 'ee_else_ce/boards/models/issue';
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
-import eventHub from '../eventhub';
-import boardsStore from '../stores/boards_store';
-import ProjectSelect from './project_select_deprecated.vue';
-
-// This component is being replaced in favor of './board_new_issue.vue' for GraphQL boards
-
-export default {
- name: 'BoardNewIssueDeprecated',
- components: {
- ProjectSelect,
- GlButton,
- },
- mixins: [glFeatureFlagMixin()],
- inject: ['groupId'],
- props: {
- list: {
- type: Object,
- required: true,
- },
- },
- data() {
- return {
- title: '',
- error: false,
- selectedProject: {},
- };
- },
- computed: {
- ...mapGetters(['isGroupBoard']),
- disabled() {
- if (this.isGroupBoard) {
- return this.title === '' || !this.selectedProject.name;
- }
- return this.title === '';
- },
- },
- mounted() {
- this.$refs.input.focus();
- eventHub.$on('setSelectedProject', this.setSelectedProject);
- },
- methods: {
- submit(e) {
- e.preventDefault();
- if (this.title.trim() === '') return Promise.resolve();
-
- this.error = false;
-
- const labels = this.list.label ? [this.list.label] : [];
- const assignees = this.list.assignee ? [this.list.assignee] : [];
- const milestone = getMilestone(this.list);
-
- const { weightFeatureAvailable } = boardsStore;
- const { weight } = weightFeatureAvailable ? boardsStore.state.currentBoard : {};
-
- const issue = new ListIssue({
- title: this.title,
- labels,
- subscribed: true,
- assignees,
- milestone,
- project_id: this.selectedProject.id,
- weight,
- });
-
- eventHub.$emit(`scroll-board-list-${this.list.id}`);
- this.cancel();
-
- return this.list
- .newIssue(issue)
- .then(() => {
- boardsStore.setIssueDetail(issue);
- boardsStore.setListDetail(this.list);
- })
- .catch(() => {
- this.list.removeIssue(issue);
-
- // Show error message
- this.error = true;
- });
- },
- cancel() {
- this.title = '';
- eventHub.$emit(`toggle-issue-form-${this.list.id}`);
- },
- setSelectedProject(selectedProject) {
- this.selectedProject = selectedProject;
- },
- },
-};
-</script>
-
-<template>
- <div class="board-new-issue-form">
- <div class="board-card position-relative p-3 rounded">
- <form @submit="submit($event)">
- <div v-if="error" class="flash-container">
- <div class="flash-alert">{{ __('An error occurred. Please try again.') }}</div>
- </div>
- <label :for="list.id + '-title'" class="label-bold">{{ __('Title') }}</label>
- <input
- :id="list.id + '-title'"
- ref="input"
- v-model="title"
- class="form-control"
- type="text"
- name="issue_title"
- autocomplete="off"
- />
- <project-select v-if="isGroupBoard" :group-id="groupId" :list="list" />
- <div class="clearfix gl-mt-3">
- <gl-button
- ref="submitButton"
- :disabled="disabled"
- class="float-left js-no-auto-disable"
- variant="success"
- category="primary"
- type="submit"
- >{{ __('Create issue') }}</gl-button
- >
- <gl-button
- ref="cancelButton"
- class="float-right"
- type="button"
- variant="default"
- @click="cancel"
- >{{ __('Cancel') }}</gl-button
- >
- </div>
- </form>
- </div>
- </div>
-</template>
diff --git a/app/assets/javascripts/boards/components/board_settings_sidebar.vue b/app/assets/javascripts/boards/components/board_settings_sidebar.vue
index c089a6a39af..6b7c08d05a5 100644
--- a/app/assets/javascripts/boards/components/board_settings_sidebar.vue
+++ b/app/assets/javascripts/boards/components/board_settings_sidebar.vue
@@ -3,7 +3,6 @@ import { GlButton, GlDrawer, GlLabel } from '@gitlab/ui';
import { MountingPortal } from 'portal-vue';
import { mapActions, mapState, mapGetters } from 'vuex';
import { LIST, ListType, ListTypeTitles } from '~/boards/constants';
-import boardsStore from '~/boards/stores/boards_store';
import { isScopedLabel } from '~/lib/utils/common_utils';
import { __ } from '~/locale';
import eventHub from '~/sidebar/event_hub';
@@ -23,7 +22,7 @@ export default {
import('ee_component/boards/components/board_settings_list_types.vue'),
},
mixins: [glFeatureFlagMixin(), Tracking.mixin()],
- inject: ['canAdminList'],
+ inject: ['canAdminList', 'scopedLabelsAvailable'],
inheritAttrs: false,
data() {
return {
@@ -31,20 +30,13 @@ export default {
};
},
computed: {
- ...mapGetters(['isSidebarOpen', 'shouldUseGraphQL', 'isEpicBoard']),
+ ...mapGetters(['isSidebarOpen', 'isEpicBoard']),
...mapState(['activeId', 'sidebarType', 'boardLists']),
isWipLimitsOn() {
return this.glFeatures.wipLimits && !this.isEpicBoard;
},
activeList() {
- /*
- Warning: Though a computed property it is not reactive because we are
- referencing a List Model class. Reactivity only applies to plain JS objects
- */
- if (this.shouldUseGraphQL || this.isEpicBoard) {
- return this.boardLists[this.activeId];
- }
- return boardsStore.state.lists.find(({ id }) => id === this.activeId);
+ return this.boardLists[this.activeId] || {};
},
activeListLabel() {
return this.activeList.label;
@@ -68,17 +60,13 @@ export default {
methods: {
...mapActions(['unsetActiveId', 'removeList']),
showScopedLabels(label) {
- return boardsStore.scopedLabels.enabled && isScopedLabel(label);
+ return this.scopedLabelsAvailable && isScopedLabel(label);
},
deleteBoard() {
// eslint-disable-next-line no-alert
if (window.confirm(__('Are you sure you want to remove this list?'))) {
- if (this.shouldUseGraphQL || this.isEpicBoard) {
- this.track('click_button', { label: 'remove_list' });
- this.removeList(this.activeId);
- } else {
- this.activeList.destroy();
- }
+ this.track('click_button', { label: 'remove_list' });
+ this.removeList(this.activeId);
this.unsetActiveId();
}
},
@@ -93,9 +81,26 @@ export default {
v-bind="$attrs"
class="js-board-settings-sidebar gl-absolute"
:open="isSidebarOpen"
+ variant="sidebar"
@close="unsetActiveId"
>
- <template #title>{{ $options.listSettingsText }}</template>
+ <template #title>
+ <h2 class="gl-my-0 gl-font-size-h2 gl-line-height-24">
+ {{ $options.listSettingsText }}
+ </h2>
+ </template>
+ <template #header>
+ <div v-if="canAdminList && activeList.id" class="gl-mt-3">
+ <gl-button
+ variant="danger"
+ category="secondary"
+ size="small"
+ data-testid="remove-list"
+ @click.stop="deleteBoard"
+ >{{ __('Remove list') }}
+ </gl-button>
+ </div>
+ </template>
<template v-if="isSidebarOpen">
<div v-if="boardListType === ListType.label">
<label class="js-list-label gl-display-block">{{ listTypeTitle }}</label>
@@ -115,16 +120,6 @@ export default {
v-if="isWipLimitsOn"
:max-issue-count="activeList.maxIssueCount"
/>
- <div v-if="canAdminList && !activeList.preset && activeList.id" class="gl-mt-4">
- <gl-button
- variant="danger"
- category="secondary"
- icon="remove"
- data-testid="remove-list"
- @click.stop="deleteBoard"
- >{{ __('Remove list') }}
- </gl-button>
- </div>
</template>
</gl-drawer>
</mounting-portal>
diff --git a/app/assets/javascripts/boards/components/board_sidebar.js b/app/assets/javascripts/boards/components/board_sidebar.js
deleted file mode 100644
index 21a34182369..00000000000
--- a/app/assets/javascripts/boards/components/board_sidebar.js
+++ /dev/null
@@ -1,115 +0,0 @@
-// This is a true violation of @gitlab/no-runtime-template-compiler, as it
-// relies on app/views/shared/boards/components/_sidebar.html.haml for its
-// template.
-/* eslint-disable no-new, @gitlab/no-runtime-template-compiler */
-
-import { GlLabel } from '@gitlab/ui';
-import $ from 'jquery';
-import Vue from 'vue';
-import DueDateSelectors from '~/due_date_select';
-import IssuableContext from '~/issuable_context';
-import LabelsSelect from '~/labels_select';
-import { isScopedLabel } from '~/lib/utils/common_utils';
-import { sprintf, __ } from '~/locale';
-import MilestoneSelect from '~/milestone_select';
-import Sidebar from '~/right_sidebar';
-import AssigneeTitle from '~/sidebar/components/assignees/assignee_title.vue';
-import Assignees from '~/sidebar/components/assignees/assignees.vue';
-import SidebarAssigneesWidget from '~/sidebar/components/assignees/sidebar_assignees_widget.vue';
-import Subscriptions from '~/sidebar/components/subscriptions/subscriptions.vue';
-import TimeTracker from '~/sidebar/components/time_tracking/time_tracker.vue';
-import eventHub from '~/sidebar/event_hub';
-import boardsStore from '../stores/boards_store';
-
-export default Vue.extend({
- components: {
- AssigneeTitle,
- Assignees,
- GlLabel,
- SidebarEpicsSelect: () =>
- import('ee_component/sidebar/components/sidebar_item_epics_select.vue'),
- Subscriptions,
- TimeTracker,
- SidebarAssigneesWidget,
- },
- props: {
- currentUser: {
- type: Object,
- default: () => ({}),
- required: false,
- },
- },
- data() {
- return {
- detail: boardsStore.detail,
- issue: {},
- list: {},
- loadingAssignees: false,
- timeTrackingLimitToHours: boardsStore.timeTracking.limitToHours,
- };
- },
- computed: {
- showSidebar() {
- return Object.keys(this.issue).length;
- },
- milestoneTitle() {
- return this.issue.milestone ? this.issue.milestone.title : __('No milestone');
- },
- canRemove() {
- return !this.list?.preset;
- },
- hasLabels() {
- return this.issue.labels && this.issue.labels.length;
- },
- labelDropdownTitle() {
- return this.hasLabels
- ? sprintf(__('%{firstLabel} +%{labelCount} more'), {
- firstLabel: this.issue.labels[0].title,
- labelCount: this.issue.labels.length - 1,
- })
- : __('Label');
- },
- selectedLabels() {
- return this.hasLabels ? this.issue.labels.map((l) => l.title).join(',') : '';
- },
- },
- watch: {
- detail: {
- handler() {
- if (this.issue.id !== this.detail.issue.id) {
- $('.js-issue-board-sidebar', this.$el).each((i, el) => {
- $(el).data('deprecatedJQueryDropdown').clearMenu();
- });
- }
-
- this.issue = this.detail.issue;
- this.list = this.detail.list;
- },
- deep: true,
- },
- },
- created() {
- eventHub.$on('sidebar.closeAll', this.closeSidebar);
- },
- beforeDestroy() {
- eventHub.$off('sidebar.closeAll', this.closeSidebar);
- },
- mounted() {
- new IssuableContext(this.currentUser);
- new MilestoneSelect();
- new DueDateSelectors();
- new LabelsSelect();
- new Sidebar();
- },
- methods: {
- closeSidebar() {
- this.detail.issue = {};
- },
- setAssignees({ assignees }) {
- boardsStore.detail.issue.setAssignees(assignees);
- },
- showScopedLabels(label) {
- return boardsStore.scopedLabels.enabled && isScopedLabel(label);
- },
- },
-});
diff --git a/app/assets/javascripts/boards/components/boards_selector_deprecated.vue b/app/assets/javascripts/boards/components/boards_selector_deprecated.vue
deleted file mode 100644
index c1536dff2c6..00000000000
--- a/app/assets/javascripts/boards/components/boards_selector_deprecated.vue
+++ /dev/null
@@ -1,360 +0,0 @@
-<script>
-import {
- GlLoadingIcon,
- GlSearchBoxByType,
- GlDropdown,
- GlDropdownDivider,
- GlDropdownSectionHeader,
- GlDropdownItem,
- GlModalDirective,
-} from '@gitlab/ui';
-import { throttle } from 'lodash';
-import { mapGetters, mapState } from 'vuex';
-
-import { getIdFromGraphQLId } from '~/graphql_shared/utils';
-import httpStatusCodes from '~/lib/utils/http_status';
-
-import groupQuery from '../graphql/group_boards.query.graphql';
-import projectQuery from '../graphql/project_boards.query.graphql';
-
-import boardsStore from '../stores/boards_store';
-import BoardForm from './board_form.vue';
-
-const MIN_BOARDS_TO_VIEW_RECENT = 10;
-
-export default {
- name: 'BoardsSelector',
- components: {
- BoardForm,
- GlLoadingIcon,
- GlSearchBoxByType,
- GlDropdown,
- GlDropdownDivider,
- GlDropdownSectionHeader,
- GlDropdownItem,
- },
- directives: {
- GlModalDirective,
- },
- props: {
- currentBoard: {
- type: Object,
- required: true,
- },
- throttleDuration: {
- type: Number,
- default: 200,
- required: false,
- },
- boardBaseUrl: {
- type: String,
- required: true,
- },
- hasMissingBoards: {
- type: Boolean,
- required: true,
- },
- canAdminBoard: {
- type: Boolean,
- required: true,
- },
- multipleIssueBoardsAvailable: {
- type: Boolean,
- required: true,
- },
- labelsPath: {
- type: String,
- required: true,
- },
- labelsWebUrl: {
- type: String,
- required: true,
- },
- projectId: {
- type: Number,
- required: true,
- },
- groupId: {
- type: Number,
- required: true,
- },
- scopedIssueBoardFeatureEnabled: {
- type: Boolean,
- required: true,
- },
- weights: {
- type: Array,
- required: true,
- },
- enabledScopedLabels: {
- type: Boolean,
- required: false,
- default: false,
- },
- },
- data() {
- return {
- hasScrollFade: false,
- loadingBoards: 0,
- loadingRecentBoards: false,
- scrollFadeInitialized: false,
- boards: [],
- recentBoards: [],
- state: boardsStore.state,
- throttledSetScrollFade: throttle(this.setScrollFade, this.throttleDuration),
- contentClientHeight: 0,
- maxPosition: 0,
- store: boardsStore,
- filterTerm: '',
- };
- },
- computed: {
- ...mapState(['boardType']),
- ...mapGetters(['isGroupBoard']),
- parentType() {
- return this.boardType;
- },
- loading() {
- return this.loadingRecentBoards || Boolean(this.loadingBoards);
- },
- currentPage() {
- return this.state.currentPage;
- },
- filteredBoards() {
- return this.boards.filter((board) =>
- board.name.toLowerCase().includes(this.filterTerm.toLowerCase()),
- );
- },
- board() {
- return this.state.currentBoard;
- },
- showDelete() {
- return this.boards.length > 1;
- },
- scrollFadeClass() {
- return {
- 'fade-out': !this.hasScrollFade,
- };
- },
- showRecentSection() {
- return (
- this.recentBoards.length &&
- this.boards.length > MIN_BOARDS_TO_VIEW_RECENT &&
- !this.filterTerm.length
- );
- },
- },
- watch: {
- filteredBoards() {
- this.scrollFadeInitialized = false;
- this.$nextTick(this.setScrollFade);
- },
- },
- created() {
- boardsStore.setCurrentBoard(this.currentBoard);
- },
- methods: {
- showPage(page) {
- boardsStore.showPage(page);
- },
- cancel() {
- this.showPage('');
- },
- loadBoards(toggleDropdown = true) {
- if (toggleDropdown && this.boards.length > 0) {
- return;
- }
-
- this.$apollo.addSmartQuery('boards', {
- variables() {
- return { fullPath: this.state.endpoints.fullPath };
- },
- query() {
- return this.isGroupBoard ? groupQuery : projectQuery;
- },
- loadingKey: 'loadingBoards',
- update(data) {
- if (!data?.[this.parentType]) {
- return [];
- }
- return data[this.parentType].boards.edges.map(({ node }) => ({
- id: getIdFromGraphQLId(node.id),
- name: node.name,
- }));
- },
- });
-
- this.loadingRecentBoards = true;
- boardsStore
- .recentBoards()
- .then((res) => {
- this.recentBoards = res.data;
- })
- .catch((err) => {
- /**
- * If user is unauthorized we'd still want to resolve the
- * request to display all boards.
- */
- if (err?.response?.status === httpStatusCodes.UNAUTHORIZED) {
- this.recentBoards = []; // recent boards are empty
- return;
- }
- throw err;
- })
- .then(() => this.$nextTick()) // Wait for boards list in DOM
- .then(() => {
- this.setScrollFade();
- })
- .catch(() => {})
- .finally(() => {
- this.loadingRecentBoards = false;
- });
- },
- isScrolledUp() {
- const { content } = this.$refs;
-
- if (!content) {
- return false;
- }
-
- const currentPosition = this.contentClientHeight + content.scrollTop;
-
- return currentPosition < this.maxPosition;
- },
- initScrollFade() {
- const { content } = this.$refs;
-
- if (!content) {
- return;
- }
-
- this.scrollFadeInitialized = true;
-
- this.contentClientHeight = content.clientHeight;
- this.maxPosition = content.scrollHeight;
- },
- setScrollFade() {
- if (!this.scrollFadeInitialized) this.initScrollFade();
-
- this.hasScrollFade = this.isScrolledUp();
- },
- },
-};
-</script>
-
-<template>
- <div class="boards-switcher js-boards-selector gl-mr-3">
- <span class="boards-selector-wrapper js-boards-selector-wrapper">
- <gl-dropdown
- data-qa-selector="boards_dropdown"
- toggle-class="dropdown-menu-toggle js-dropdown-toggle"
- menu-class="flex-column dropdown-extended-height"
- :text="board.name"
- @show="loadBoards"
- >
- <p class="gl-new-dropdown-header-top" @mousedown.prevent>
- {{ s__('IssueBoards|Switch board') }}
- </p>
- <gl-search-box-by-type ref="searchBox" v-model="filterTerm" class="m-2" />
-
- <div
- v-if="!loading"
- ref="content"
- data-qa-selector="boards_dropdown_content"
- class="dropdown-content flex-fill"
- @scroll.passive="throttledSetScrollFade"
- >
- <gl-dropdown-item
- v-show="filteredBoards.length === 0"
- class="gl-pointer-events-none text-secondary"
- >
- {{ s__('IssueBoards|No matching boards found') }}
- </gl-dropdown-item>
-
- <gl-dropdown-section-header v-if="showRecentSection">
- {{ __('Recent') }}
- </gl-dropdown-section-header>
-
- <template v-if="showRecentSection">
- <gl-dropdown-item
- v-for="recentBoard in recentBoards"
- :key="`recent-${recentBoard.id}`"
- class="js-dropdown-item"
- :href="`${boardBaseUrl}/${recentBoard.id}`"
- >
- {{ recentBoard.name }}
- </gl-dropdown-item>
- </template>
-
- <gl-dropdown-divider v-if="showRecentSection" />
-
- <gl-dropdown-section-header v-if="showRecentSection">
- {{ __('All') }}
- </gl-dropdown-section-header>
-
- <gl-dropdown-item
- v-for="otherBoard in filteredBoards"
- :key="otherBoard.id"
- class="js-dropdown-item"
- :href="`${boardBaseUrl}/${otherBoard.id}`"
- >
- {{ otherBoard.name }}
- </gl-dropdown-item>
-
- <gl-dropdown-item v-if="hasMissingBoards" class="no-pointer-events">
- {{
- s__(
- 'IssueBoards|Some of your boards are hidden, activate a license to see them again.',
- )
- }}
- </gl-dropdown-item>
- </div>
-
- <div
- v-show="filteredBoards.length > 0"
- class="dropdown-content-faded-mask"
- :class="scrollFadeClass"
- ></div>
-
- <gl-loading-icon v-if="loading" size="sm" />
-
- <div v-if="canAdminBoard">
- <gl-dropdown-divider />
-
- <gl-dropdown-item
- v-if="multipleIssueBoardsAvailable"
- v-gl-modal-directive="'board-config-modal'"
- data-qa-selector="create_new_board_button"
- @click.prevent="showPage('new')"
- >
- {{ s__('IssueBoards|Create new board') }}
- </gl-dropdown-item>
-
- <gl-dropdown-item
- v-if="showDelete"
- v-gl-modal-directive="'board-config-modal'"
- class="text-danger js-delete-board"
- @click.prevent="showPage('delete')"
- >
- {{ s__('IssueBoards|Delete board') }}
- </gl-dropdown-item>
- </div>
- </gl-dropdown>
-
- <board-form
- v-if="currentPage"
- :labels-path="labelsPath"
- :labels-web-url="labelsWebUrl"
- :project-id="projectId"
- :group-id="groupId"
- :can-admin-board="canAdminBoard"
- :scoped-issue-board-feature-enabled="scopedIssueBoardFeatureEnabled"
- :weights="weights"
- :enable-scoped-labels="enabledScopedLabels"
- :current-board="currentBoard"
- :current-page="state.currentPage"
- @cancel="cancel"
- />
- </span>
- </div>
-</template>
diff --git a/app/assets/javascripts/boards/components/config_toggle.vue b/app/assets/javascripts/boards/components/config_toggle.vue
index 30e304b8a65..f39e4d90357 100644
--- a/app/assets/javascripts/boards/components/config_toggle.vue
+++ b/app/assets/javascripts/boards/components/config_toggle.vue
@@ -15,11 +15,6 @@ export default {
},
mixins: [Tracking.mixin()],
props: {
- boardsStore: {
- type: Object,
- required: false,
- default: null,
- },
canAdminList: {
type: Boolean,
required: true,
@@ -41,9 +36,6 @@ export default {
showPage() {
this.track('click_button', { label: 'edit_board' });
eventHub.$emit('showBoardModal', formType.edit);
- if (this.boardsStore) {
- this.boardsStore.showPage(formType.edit);
- }
},
},
};
diff --git a/app/assets/javascripts/boards/components/issue_board_filtered_search.vue b/app/assets/javascripts/boards/components/issue_board_filtered_search.vue
index 5206db05410..b6c5ef955c6 100644
--- a/app/assets/javascripts/boards/components/issue_board_filtered_search.vue
+++ b/app/assets/javascripts/boards/components/issue_board_filtered_search.vue
@@ -6,6 +6,7 @@ import issueBoardFilters from '~/boards/issue_board_filters';
import { TYPE_USER } from '~/graphql_shared/constants';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import { __ } from '~/locale';
+import { DEFAULT_MILESTONES_GRAPHQL } from '~/vue_shared/components/filtered_search_bar/constants';
import AuthorToken from '~/vue_shared/components/filtered_search_bar/tokens/author_token.vue';
import LabelToken from '~/vue_shared/components/filtered_search_bar/tokens/label_token.vue';
import MilestoneToken from '~/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue';
@@ -63,17 +64,17 @@ export default {
return [
{
- icon: 'labels',
- title: label,
- type: 'label_name',
+ icon: 'user',
+ title: assignee,
+ type: 'assignee_username',
operators: [
{ value: '=', description: is },
{ value: '!=', description: isNot },
],
- token: LabelToken,
- unique: false,
- symbol: '~',
- fetchLabels,
+ token: AuthorToken,
+ unique: true,
+ fetchAuthors,
+ preloadedAuthors: this.preloadedAuthors(),
},
{
icon: 'pencil',
@@ -90,17 +91,27 @@ export default {
preloadedAuthors: this.preloadedAuthors(),
},
{
- icon: 'user',
- title: assignee,
- type: 'assignee_username',
+ icon: 'labels',
+ title: label,
+ type: 'label_name',
operators: [
{ value: '=', description: is },
{ value: '!=', description: isNot },
],
- token: AuthorToken,
+ token: LabelToken,
+ unique: false,
+ symbol: '~',
+ fetchLabels,
+ },
+ {
+ type: 'milestone_title',
+ title: milestone,
+ icon: 'clock',
+ symbol: '%',
+ token: MilestoneToken,
unique: true,
- fetchAuthors,
- preloadedAuthors: this.preloadedAuthors(),
+ defaultMilestones: DEFAULT_MILESTONES_GRAPHQL,
+ fetchMilestones: this.fetchMilestones,
},
{
icon: 'issues',
@@ -115,16 +126,6 @@ export default {
],
},
{
- type: 'milestone_title',
- title: milestone,
- icon: 'clock',
- symbol: '%',
- token: MilestoneToken,
- unique: true,
- defaultMilestones: [], // todo: https://gitlab.com/gitlab-org/gitlab/-/issues/337044#note_640010094
- fetchMilestones: this.fetchMilestones,
- },
- {
type: 'weight',
title: weight,
icon: 'weight',
diff --git a/app/assets/javascripts/boards/components/issue_card_inner_deprecated.vue b/app/assets/javascripts/boards/components/issue_card_inner_deprecated.vue
deleted file mode 100644
index 6e90731cc2f..00000000000
--- a/app/assets/javascripts/boards/components/issue_card_inner_deprecated.vue
+++ /dev/null
@@ -1,247 +0,0 @@
-<script>
-import { GlLabel, GlTooltipDirective, GlIcon } from '@gitlab/ui';
-import { sortBy } from 'lodash';
-import { mapState } from 'vuex';
-import boardCardInner from 'ee_else_ce/boards/mixins/board_card_inner';
-import { isScopedLabel } from '~/lib/utils/common_utils';
-import { sprintf, __, n__ } from '~/locale';
-import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue';
-import UserAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
-import boardsStore from '../stores/boards_store';
-import IssueDueDate from './issue_due_date.vue';
-import IssueTimeEstimate from './issue_time_estimate_deprecated.vue';
-
-export default {
- components: {
- GlLabel,
- GlIcon,
- UserAvatarLink,
- TooltipOnTruncate,
- IssueDueDate,
- IssueTimeEstimate,
- IssueCardWeight: () => import('ee_component/boards/components/issue_card_weight.vue'),
- },
- directives: {
- GlTooltip: GlTooltipDirective,
- },
- mixins: [boardCardInner],
- inject: ['groupId', 'rootPath'],
- props: {
- issue: {
- type: Object,
- required: true,
- },
- list: {
- type: Object,
- required: false,
- default: () => ({}),
- },
- updateFilters: {
- type: Boolean,
- required: false,
- default: false,
- },
- },
- data() {
- return {
- limitBeforeCounter: 2,
- maxRender: 3,
- maxCounter: 99,
- };
- },
- computed: {
- ...mapState(['isShowingLabels']),
- numberOverLimit() {
- return this.issue.assignees.length - this.limitBeforeCounter;
- },
- assigneeCounterTooltip() {
- const { numberOverLimit, maxCounter } = this;
- const count = numberOverLimit > maxCounter ? maxCounter : numberOverLimit;
- return sprintf(__('%{count} more assignees'), { count });
- },
- assigneeCounterLabel() {
- if (this.numberOverLimit > this.maxCounter) {
- return `${this.maxCounter}+`;
- }
-
- return `+${this.numberOverLimit}`;
- },
- shouldRenderCounter() {
- if (this.issue.assignees.length <= this.maxRender) {
- return false;
- }
-
- return this.issue.assignees.length > this.numberOverLimit;
- },
- issueId() {
- if (this.issue.iid) {
- return `#${this.issue.iid}`;
- }
- return false;
- },
- showLabelFooter() {
- return this.isShowingLabels && this.issue.labels.find(this.showLabel);
- },
- issueReferencePath() {
- const { referencePath, groupId } = this.issue;
- return !groupId ? referencePath.split('#')[0] : null;
- },
- orderedLabels() {
- return sortBy(this.issue.labels.filter(this.isNonListLabel), 'title');
- },
- blockedLabel() {
- if (this.issue.blockedByCount) {
- return n__(`Blocked by %d issue`, `Blocked by %d issues`, this.issue.blockedByCount);
- }
- return __('Blocked issue');
- },
- assignees() {
- return this.issue.assignees.filter((_, index) => this.shouldRenderAssignee(index));
- },
- },
- methods: {
- isIndexLessThanlimit(index) {
- return index < this.limitBeforeCounter;
- },
- shouldRenderAssignee(index) {
- // Eg. maxRender is 4,
- // Render up to all 4 assignees if there are only 4 assigness
- // Otherwise render up to the limitBeforeCounter
- if (this.issue.assignees.length <= this.maxRender) {
- return index < this.maxRender;
- }
-
- return index < this.limitBeforeCounter;
- },
- assigneeUrl(assignee) {
- if (!assignee) return '';
- return `${this.rootPath}${assignee.username}`;
- },
- avatarUrlTitle(assignee) {
- return sprintf(__(`Avatar for %{assigneeName}`), { assigneeName: assignee.name });
- },
- showLabel(label) {
- if (!label.id) return false;
- return true;
- },
- isNonListLabel(label) {
- return label.id && !(this.list.type === 'label' && this.list.title === label.title);
- },
- filterByLabel(label) {
- if (!this.updateFilters) return;
- const labelTitle = encodeURIComponent(label.title);
- const filter = `label_name[]=${labelTitle}`;
-
- boardsStore.toggleFilter(filter);
- },
- showScopedLabel(label) {
- return boardsStore.scopedLabels.enabled && isScopedLabel(label);
- },
- },
-};
-</script>
-<template>
- <div>
- <div class="gl-display-flex" dir="auto">
- <h4 class="board-card-title gl-mb-0 gl-mt-0">
- <gl-icon
- v-if="issue.blocked"
- v-gl-tooltip
- name="issue-block"
- :title="blockedLabel"
- class="issue-blocked-icon gl-mr-2"
- :aria-label="blockedLabel"
- data-testid="issue-blocked-icon"
- />
- <gl-icon
- v-if="issue.confidential"
- v-gl-tooltip
- name="eye-slash"
- :title="__('Confidential')"
- class="confidential-icon gl-mr-2"
- :aria-label="__('Confidential')"
- />
- <a
- :href="issue.path || issue.webUrl || ''"
- :title="issue.title"
- class="js-no-trigger"
- @mousemove.stop
- >{{ issue.title }}</a
- >
- </h4>
- </div>
- <div v-if="showLabelFooter" class="board-card-labels gl-mt-2 gl-display-flex gl-flex-wrap">
- <template v-for="label in orderedLabels">
- <gl-label
- :key="label.id"
- :background-color="label.color"
- :title="label.title"
- :description="label.description"
- size="sm"
- :scoped="showScopedLabel(label)"
- @click="filterByLabel(label)"
- />
- </template>
- </div>
- <div
- class="board-card-footer gl-display-flex gl-justify-content-space-between gl-align-items-flex-end"
- >
- <div
- class="gl-display-flex align-items-start flex-wrap-reverse board-card-number-container gl-overflow-hidden js-board-card-number-container"
- >
- <span
- v-if="issue.referencePath"
- class="board-card-number gl-overflow-hidden gl-display-flex gl-mr-3 gl-mt-3"
- >
- <tooltip-on-truncate
- v-if="issueReferencePath"
- :title="issueReferencePath"
- placement="bottom"
- class="board-issue-path gl-text-truncate gl-font-weight-bold"
- >{{ issueReferencePath }}</tooltip-on-truncate
- >
- #{{ issue.iid }}
- </span>
- <span class="board-info-items gl-mt-3 gl-display-inline-block">
- <issue-due-date
- v-if="issue.dueDate"
- :date="issue.dueDate"
- :closed="issue.closed || Boolean(issue.closedAt)"
- />
- <issue-time-estimate v-if="issue.timeEstimate" :estimate="issue.timeEstimate" />
- <issue-card-weight
- v-if="validIssueWeight(issue)"
- :weight="issue.weight"
- @click="filterByWeight(issue.weight)"
- />
- </span>
- </div>
- <div class="board-card-assignee gl-display-flex">
- <user-avatar-link
- v-for="assignee in assignees"
- :key="assignee.id"
- :link-href="assigneeUrl(assignee)"
- :img-alt="avatarUrlTitle(assignee)"
- :img-src="assignee.avatarUrl || assignee.avatar || assignee.avatar_url"
- :img-size="24"
- class="js-no-trigger"
- tooltip-placement="bottom"
- >
- <span class="js-assignee-tooltip">
- <span class="gl-font-weight-bold gl-display-block">{{ __('Assignee') }}</span>
- {{ assignee.name }}
- <span class="text-white-50">@{{ assignee.username }}</span>
- </span>
- </user-avatar-link>
- <span
- v-if="shouldRenderCounter"
- v-gl-tooltip
- :title="assigneeCounterTooltip"
- class="avatar-counter"
- data-placement="bottom"
- >{{ assigneeCounterLabel }}</span
- >
- </div>
- </div>
- </div>
-</template>
diff --git a/app/assets/javascripts/boards/components/issue_time_estimate_deprecated.vue b/app/assets/javascripts/boards/components/issue_time_estimate_deprecated.vue
deleted file mode 100644
index 8ddf50cb357..00000000000
--- a/app/assets/javascripts/boards/components/issue_time_estimate_deprecated.vue
+++ /dev/null
@@ -1,48 +0,0 @@
-<script>
-import { GlTooltip, GlIcon } from '@gitlab/ui';
-import { parseSeconds, stringifyTime } from '~/lib/utils/datetime_utility';
-import boardsStore from '../stores/boards_store';
-
-export default {
- components: {
- GlIcon,
- GlTooltip,
- },
- props: {
- estimate: {
- type: [Number, String],
- required: true,
- },
- },
- data() {
- return {
- limitToHours: boardsStore.timeTracking.limitToHours,
- };
- },
- computed: {
- title() {
- return stringifyTime(parseSeconds(this.estimate, { limitToHours: this.limitToHours }), true);
- },
- timeEstimate() {
- return stringifyTime(parseSeconds(this.estimate, { limitToHours: this.limitToHours }));
- },
- },
-};
-</script>
-
-<template>
- <span>
- <span ref="issueTimeEstimate" class="board-card-info card-number">
- <gl-icon name="hourglass" class="board-card-info-icon" /><time class="board-card-info-text">{{
- timeEstimate
- }}</time>
- </span>
- <gl-tooltip
- :target="() => $refs.issueTimeEstimate"
- placement="bottom"
- class="js-issue-time-estimate"
- >
- <span class="bold d-block">{{ __('Time estimate') }}</span> {{ title }}
- </gl-tooltip>
- </span>
-</template>
diff --git a/app/assets/javascripts/boards/components/new_list_dropdown.js b/app/assets/javascripts/boards/components/new_list_dropdown.js
deleted file mode 100644
index 6eb1dbfb46a..00000000000
--- a/app/assets/javascripts/boards/components/new_list_dropdown.js
+++ /dev/null
@@ -1,119 +0,0 @@
-/* eslint-disable func-names, no-new */
-
-import $ from 'jquery';
-import store from '~/boards/stores';
-import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
-import createFlash from '~/flash';
-import { getIdFromGraphQLId } from '~/graphql_shared/utils';
-import axios from '~/lib/utils/axios_utils';
-import { __ } from '~/locale';
-import CreateLabelDropdown from '../../create_label';
-import { fullLabelId } from '../boards_util';
-import boardsStore from '../stores/boards_store';
-
-function shouldCreateListGraphQL(label) {
- return store.getters.shouldUseGraphQL && !store.getters.getListByLabelId(fullLabelId(label));
-}
-
-// eslint-disable-next-line @gitlab/no-global-event-off
-$(document)
- .off('created.label')
- .on('created.label', (e, label, addNewList) => {
- if (!addNewList) {
- return;
- }
-
- if (shouldCreateListGraphQL(label)) {
- store.dispatch('createList', { labelId: fullLabelId(label) });
- } else {
- boardsStore.new({
- title: label.title,
- position: boardsStore.state.lists.length - 2,
- list_type: 'label',
- label: {
- id: label.id,
- title: label.title,
- color: label.color,
- },
- });
- }
- });
-
-export default function initNewListDropdown() {
- $('.js-new-board-list').each(function () {
- const $dropdownToggle = $(this);
- const $dropdown = $dropdownToggle.closest('.dropdown');
- new CreateLabelDropdown(
- $dropdown.find('.dropdown-new-label'),
- $dropdownToggle.data('namespacePath'),
- $dropdownToggle.data('projectPath'),
- );
-
- initDeprecatedJQueryDropdown($dropdownToggle, {
- data(term, callback) {
- const reqFailed = () => {
- $dropdownToggle.data('bs.dropdown').hide();
- createFlash({
- message: __('Error fetching labels.'),
- });
- };
-
- if (store.getters.shouldUseGraphQL) {
- store
- .dispatch('fetchLabels')
- .then((data) => callback(data))
- .catch(reqFailed);
- } else {
- axios
- .get($dropdownToggle.attr('data-list-labels-path'))
- .then(({ data }) => callback(data))
- .catch(reqFailed);
- }
- },
- renderRow(label) {
- const active = store.getters.shouldUseGraphQL
- ? store.getters.getListByLabelId(label.id)
- : boardsStore.findListByLabelId(label.id);
- const $li = $('<li />');
- const $a = $('<a />', {
- class: active ? `is-active js-board-list-${getIdFromGraphQLId(active.id)}` : '',
- text: label.title,
- href: '#',
- });
- const $labelColor = $('<span />', {
- class: 'dropdown-label-box',
- style: `background-color: ${label.color}`,
- });
-
- return $li.append($a.prepend($labelColor));
- },
- search: {
- fields: ['title'],
- },
- filterable: true,
- selectable: true,
- multiSelect: true,
- containerSelector: '.js-tab-container-labels .dropdown-page-one .dropdown-content',
- clicked(options) {
- const { e } = options;
- const label = options.selectedObj;
- e.preventDefault();
-
- if (shouldCreateListGraphQL(label)) {
- store.dispatch('createList', { labelId: label.id });
- } else if (!boardsStore.findListByLabelId(label.id)) {
- boardsStore.new({
- title: label.title,
- position: boardsStore.state.lists.length - 2,
- list_type: 'label',
- label: {
- id: label.id,
- title: label.title,
- color: label.color,
- },
- });
- }
- },
- });
- });
-}
diff --git a/app/assets/javascripts/boards/components/project_select_deprecated.vue b/app/assets/javascripts/boards/components/project_select_deprecated.vue
deleted file mode 100644
index fc95ba0461d..00000000000
--- a/app/assets/javascripts/boards/components/project_select_deprecated.vue
+++ /dev/null
@@ -1,146 +0,0 @@
-<script>
-import {
- GlDropdown,
- GlDropdownItem,
- GlDropdownText,
- GlSearchBoxByType,
- GlLoadingIcon,
-} from '@gitlab/ui';
-import { s__ } from '~/locale';
-import { featureAccessLevel } from '~/pages/projects/shared/permissions/constants';
-import Api from '../../api';
-import { ListType } from '../constants';
-import eventHub from '../eventhub';
-
-export default {
- name: 'ProjectSelect',
- i18n: {
- headerTitle: s__(`BoardNewIssue|Projects`),
- dropdownText: s__(`BoardNewIssue|Select a project`),
- searchPlaceholder: s__(`BoardNewIssue|Search projects`),
- emptySearchResult: s__(`BoardNewIssue|No matching results`),
- },
- defaultFetchOptions: {
- with_issues_enabled: true,
- with_shared: false,
- include_subgroups: true,
- order_by: 'similarity',
- archived: false,
- },
- components: {
- GlLoadingIcon,
- GlDropdown,
- GlDropdownItem,
- GlDropdownText,
- GlSearchBoxByType,
- },
- inject: ['groupId'],
- props: {
- list: {
- type: Object,
- required: true,
- },
- },
- data() {
- return {
- initialLoading: true,
- isFetching: false,
- projects: [],
- selectedProject: {},
- searchTerm: '',
- };
- },
- computed: {
- selectedProjectName() {
- return this.selectedProject.name || this.$options.i18n.dropdownText;
- },
- fetchOptions() {
- const additionalAttrs = {};
- if (this.list.type && this.list.type !== ListType.backlog) {
- additionalAttrs.min_access_level = featureAccessLevel.EVERYONE;
- }
-
- return {
- ...this.$options.defaultFetchOptions,
- ...additionalAttrs,
- };
- },
- isFetchResultEmpty() {
- return this.projects.length === 0;
- },
- },
- watch: {
- searchTerm() {
- this.fetchProjects();
- },
- },
- async mounted() {
- await this.fetchProjects();
-
- this.initialLoading = false;
- },
- methods: {
- async fetchProjects() {
- this.isFetching = true;
- try {
- const projects = await Api.groupProjects(this.groupId, this.searchTerm, this.fetchOptions);
-
- this.projects = projects.map((project) => {
- return {
- id: project.id,
- name: project.name,
- namespacedName: project.name_with_namespace,
- path: project.path_with_namespace,
- };
- });
- } catch (err) {
- /* Handled in Api.groupProjects */
- } finally {
- this.isFetching = false;
- }
- },
- selectProject(projectId) {
- this.selectedProject = this.projects.find((project) => project.id === projectId);
-
- eventHub.$emit('setSelectedProject', this.selectedProject);
- },
- },
-};
-</script>
-
-<template>
- <div>
- <label class="gl-font-weight-bold gl-mt-3" data-testid="header-label">{{
- $options.i18n.headerTitle
- }}</label>
- <gl-dropdown
- data-testid="project-select-dropdown"
- :text="selectedProjectName"
- :header-text="$options.i18n.headerTitle"
- block
- menu-class="gl-w-full!"
- :loading="initialLoading"
- >
- <gl-search-box-by-type
- v-model.trim="searchTerm"
- debounce="250"
- :placeholder="$options.i18n.searchPlaceholder"
- />
- <gl-dropdown-item
- v-for="project in projects"
- v-show="!isFetching"
- :key="project.id"
- :name="project.name"
- @click="selectProject(project.id)"
- >
- {{ project.namespacedName }}
- </gl-dropdown-item>
- <gl-dropdown-text v-show="isFetching" data-testid="dropdown-text-loading-icon">
- <gl-loading-icon class="gl-mx-auto" size="sm" />
- </gl-dropdown-text>
- <gl-dropdown-text v-if="isFetchResultEmpty && !isFetching" data-testid="empty-result-message">
- <span class="gl-text-gray-500">{{ $options.i18n.emptySearchResult }}</span>
- </gl-dropdown-text>
- </gl-dropdown>
- </div>
-</template>
diff --git a/app/assets/javascripts/boards/config_toggle.js b/app/assets/javascripts/boards/config_toggle.js
index 41938d8e284..945a508c55d 100644
--- a/app/assets/javascripts/boards/config_toggle.js
+++ b/app/assets/javascripts/boards/config_toggle.js
@@ -2,7 +2,7 @@ import Vue from 'vue';
import { parseBoolean } from '~/lib/utils/common_utils';
import ConfigToggle from './components/config_toggle.vue';
-export default (boardsStore = undefined) => {
+export default () => {
const el = document.querySelector('.js-board-config');
if (!el) {
@@ -15,7 +15,6 @@ export default (boardsStore = undefined) => {
render(h) {
return h(ConfigToggle, {
props: {
- boardsStore,
canAdminList: parseBoolean(el.dataset.canAdminList),
hasScope: parseBoolean(el.dataset.hasScope),
},
diff --git a/app/assets/javascripts/boards/constants.js b/app/assets/javascripts/boards/constants.js
index 16fb4596726..391e0d1fb0a 100644
--- a/app/assets/javascripts/boards/constants.js
+++ b/app/assets/javascripts/boards/constants.js
@@ -119,6 +119,11 @@ export const DraggableItemTypes = {
list: 'list',
};
+export const MilestoneIDs = {
+ NONE: 0,
+ ANY: -1,
+};
+
export default {
BoardType,
ListType,
diff --git a/app/assets/javascripts/boards/ee_functions.js b/app/assets/javascripts/boards/ee_functions.js
deleted file mode 100644
index 62a0d930ec0..00000000000
--- a/app/assets/javascripts/boards/ee_functions.js
+++ /dev/null
@@ -1,4 +0,0 @@
-export const setWeightFetchingState = () => {};
-export const setEpicFetchingState = () => {};
-
-export const getMilestoneTitle = () => ({});
diff --git a/app/assets/javascripts/boards/filtered_search_boards.js b/app/assets/javascripts/boards/filtered_search_boards.js
index c6040f1e4aa..72586970008 100644
--- a/app/assets/javascripts/boards/filtered_search_boards.js
+++ b/app/assets/javascripts/boards/filtered_search_boards.js
@@ -4,7 +4,6 @@ import IssuableFilteredSearchTokenKeys from 'ee_else_ce/filtered_search/issuable
import { updateHistory } from '~/lib/utils/url_utility';
import FilteredSearchContainer from '../filtered_search/container';
import vuexstore from './stores';
-import boardsStore from './stores/boards_store';
export default class FilteredSearchBoards extends FilteredSearchManager {
constructor(store, updateUrl = false, cantEdit = []) {
@@ -26,7 +25,7 @@ export default class FilteredSearchBoards extends FilteredSearchManager {
this.cantEdit = cantEdit.filter((i) => typeof i === 'string');
this.cantEditWithValue = cantEdit.filter((i) => typeof i === 'object');
- if (vuexstore.getters.shouldUseGraphQL && vuexstore.state.boardConfig) {
+ if (vuexstore.state.boardConfig) {
const boardConfigPath = transformBoardConfig(vuexstore.state.boardConfig);
// TODO Refactor: https://gitlab.com/gitlab-org/gitlab/-/issues/329274
// here we are using "window.location.search" as a temporary store
@@ -45,14 +44,10 @@ export default class FilteredSearchBoards extends FilteredSearchManager {
const groupByParam = new URLSearchParams(window.location.search).get('group_by');
this.store.path = `${path.substr(1)}${groupByParam ? `&group_by=${groupByParam}` : ''}`;
- if (vuexstore.getters.shouldUseGraphQL) {
- updateHistory({
- url: `?${path.substr(1)}${groupByParam ? `&group_by=${groupByParam}` : ''}`,
- });
- vuexstore.dispatch('performSearch');
- } else if (this.updateUrl) {
- boardsStore.updateFiltersUrl();
- }
+ updateHistory({
+ url: `?${path.substr(1)}${groupByParam ? `&group_by=${groupByParam}` : ''}`,
+ });
+ vuexstore.dispatch('performSearch');
}
removeTokens() {
diff --git a/app/assets/javascripts/boards/graphql/group_board_iterations.query.graphql b/app/assets/javascripts/boards/graphql/group_board_iterations.query.graphql
new file mode 100644
index 00000000000..1c382c4747b
--- /dev/null
+++ b/app/assets/javascripts/boards/graphql/group_board_iterations.query.graphql
@@ -0,0 +1,10 @@
+query GroupBoardIterations($fullPath: ID!, $title: String) {
+ group(fullPath: $fullPath) {
+ iterations(includeAncestors: true, title: $title) {
+ nodes {
+ id
+ title
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/boards/graphql/issue.fragment.graphql b/app/assets/javascripts/boards/graphql/issue.fragment.graphql
index 0ff70703e1a..1b14396fb5c 100644
--- a/app/assets/javascripts/boards/graphql/issue.fragment.graphql
+++ b/app/assets/javascripts/boards/graphql/issue.fragment.graphql
@@ -12,6 +12,7 @@ fragment IssueNode on Issue {
humanTotalTimeSpent
emailsDisabled
confidential
+ hidden
webUrl
relativePosition
assignees {
diff --git a/app/assets/javascripts/boards/graphql/project_board_iterations.query.graphql b/app/assets/javascripts/boards/graphql/project_board_iterations.query.graphql
new file mode 100644
index 00000000000..078151a275a
--- /dev/null
+++ b/app/assets/javascripts/boards/graphql/project_board_iterations.query.graphql
@@ -0,0 +1,10 @@
+query ProjectBoardIterations($fullPath: ID!, $title: String) {
+ project(fullPath: $fullPath) {
+ iterations(includeAncestors: true, title: $title) {
+ nodes {
+ id
+ title
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/boards/graphql/project_milestones.query.graphql b/app/assets/javascripts/boards/graphql/project_milestones.query.graphql
index 776530ebb83..724b7f5a34c 100644
--- a/app/assets/javascripts/boards/graphql/project_milestones.query.graphql
+++ b/app/assets/javascripts/boards/graphql/project_milestones.query.graphql
@@ -1,4 +1,4 @@
-query groupMilestones(
+query projectMilestones(
$fullPath: ID!
$state: MilestoneStateEnum
$includeAncestors: Boolean
diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js
index de7c8a3bd6b..21c1bb23dc6 100644
--- a/app/assets/javascripts/boards/index.js
+++ b/app/assets/javascripts/boards/index.js
@@ -2,41 +2,20 @@ import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
import PortalVue from 'portal-vue';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
-import { mapActions, mapGetters } from 'vuex';
-import 'ee_else_ce/boards/models/issue';
-import 'ee_else_ce/boards/models/list';
-import BoardSidebar from 'ee_else_ce/boards/components/board_sidebar';
-import initNewListDropdown from 'ee_else_ce/boards/components/new_list_dropdown';
-import {
- setWeightFetchingState,
- setEpicFetchingState,
- getMilestoneTitle,
-} from 'ee_else_ce/boards/ee_functions';
import toggleEpicsSwimlanes from 'ee_else_ce/boards/toggle_epics_swimlanes';
import toggleLabels from 'ee_else_ce/boards/toggle_labels';
import BoardAddNewColumnTrigger from '~/boards/components/board_add_new_column_trigger.vue';
-import BoardContent from '~/boards/components/board_content.vue';
-import './models/label';
-import './models/assignee';
-import '~/boards/models/milestone';
-import '~/boards/models/project';
+import BoardApp from '~/boards/components/board_app.vue';
import '~/boards/filters/due_date_filters';
import { issuableTypes } from '~/boards/constants';
import eventHub from '~/boards/eventhub';
import FilteredSearchBoards from '~/boards/filtered_search_boards';
import initBoardsFilteredSearch from '~/boards/mount_filtered_search_issue_boards';
import store from '~/boards/stores';
-import boardsStore from '~/boards/stores/boards_store';
import toggleFocusMode from '~/boards/toggle_focus';
import createDefaultClient from '~/lib/graphql';
-import {
- NavigationType,
- convertObjectPropsToCamelCase,
- parseBoolean,
-} from '~/lib/utils/common_utils';
-import { __ } from '~/locale';
-import sidebarEventHub from '~/sidebar/event_hub';
+import { NavigationType, parseBoolean } from '~/lib/utils/common_utils';
import introspectionQueryResultData from '~/sidebar/fragmentTypes.json';
import { fullBoardId } from './boards_util';
import boardConfigToggle from './config_toggle';
@@ -61,10 +40,75 @@ const apolloProvider = new VueApollo({
),
});
-let issueBoardsApp;
+function mountBoardApp(el) {
+ const { boardId, groupId, fullPath, rootPath } = el.dataset;
+
+ store.dispatch('setInitialBoardData', {
+ boardId,
+ fullBoardId: fullBoardId(boardId),
+ fullPath,
+ boardType: el.dataset.parent,
+ disabled: parseBoolean(el.dataset.disabled) || true,
+ issuableType: issuableTypes.issue,
+ boardConfig: {
+ milestoneId: parseInt(el.dataset.boardMilestoneId, 10),
+ milestoneTitle: el.dataset.boardMilestoneTitle || '',
+ iterationId: parseInt(el.dataset.boardIterationId, 10),
+ iterationTitle: el.dataset.boardIterationTitle || '',
+ assigneeId: el.dataset.boardAssigneeId,
+ assigneeUsername: el.dataset.boardAssigneeUsername,
+ labels: el.dataset.labels ? JSON.parse(el.dataset.labels) : [],
+ labelIds: el.dataset.labelIds ? JSON.parse(el.dataset.labelIds) : [],
+ weight: el.dataset.boardWeight ? parseInt(el.dataset.boardWeight, 10) : null,
+ },
+ });
+
+ if (!gon?.features?.issueBoardsFilteredSearch) {
+ // Warning: FilteredSearchBoards has an implicit dependency on the Vuex state 'boardConfig'
+ // Improve this situation in the future.
+ const filterManager = new FilteredSearchBoards({ path: '' }, true, []);
+ filterManager.setup();
+
+ eventHub.$on('updateTokens', () => {
+ filterManager.updateTokens();
+ });
+ }
+
+ // eslint-disable-next-line no-new
+ new Vue({
+ el,
+ store,
+ apolloProvider,
+ provide: {
+ disabled: parseBoolean(el.dataset.disabled),
+ boardId,
+ groupId: Number(groupId),
+ rootPath,
+ currentUserId: gon.current_user_id || null,
+ canUpdate: parseBoolean(el.dataset.canUpdate),
+ canAdminList: parseBoolean(el.dataset.canAdminList),
+ labelsManagePath: el.dataset.labelsManagePath,
+ labelsFilterBasePath: el.dataset.labelsFilterBasePath,
+ timeTrackingLimitToHours: parseBoolean(el.dataset.timeTrackingLimitToHours),
+ multipleAssigneesFeatureAvailable: parseBoolean(el.dataset.multipleAssigneesFeatureAvailable),
+ epicFeatureAvailable: parseBoolean(el.dataset.epicFeatureAvailable),
+ iterationFeatureAvailable: parseBoolean(el.dataset.iterationFeatureAvailable),
+ weightFeatureAvailable: parseBoolean(el.dataset.weightFeatureAvailable),
+ boardWeight: el.dataset.boardWeight ? parseInt(el.dataset.boardWeight, 10) : null,
+ scopedLabelsAvailable: parseBoolean(el.dataset.scopedLabels),
+ milestoneListsAvailable: parseBoolean(el.dataset.milestoneListsAvailable),
+ assigneeListsAvailable: parseBoolean(el.dataset.assigneeListsAvailable),
+ iterationListsAvailable: parseBoolean(el.dataset.iterationListsAvailable),
+ issuableType: issuableTypes.issue,
+ emailsDisabled: parseBoolean(el.dataset.emailsDisabled),
+ },
+ render: (createComponent) => createComponent(BoardApp),
+ });
+}
export default () => {
- const $boardApp = document.getElementById('board-app');
+ const $boardApp = document.getElementById('js-issuable-board-app');
+
// check for browser back and trigger a hard reload to circumvent browser caching.
window.addEventListener('pageshow', (event) => {
const isNavTypeBackForward =
@@ -75,257 +119,11 @@ export default () => {
}
});
- if (issueBoardsApp) {
- issueBoardsApp.$destroy(true);
- }
-
if (gon?.features?.issueBoardsFilteredSearch) {
initBoardsFilteredSearch(apolloProvider);
}
- if (!gon?.features?.graphqlBoardLists) {
- boardsStore.create();
- boardsStore.setTimeTrackingLimitToHours($boardApp.dataset.timeTrackingLimitToHours);
- }
-
- // eslint-disable-next-line @gitlab/no-runtime-template-compiler
- issueBoardsApp = new Vue({
- el: $boardApp,
- components: {
- BoardContent,
- BoardSidebar,
- BoardSettingsSidebar: () => import('~/boards/components/board_settings_sidebar.vue'),
- },
- provide: {
- boardId: $boardApp.dataset.boardId,
- groupId: Number($boardApp.dataset.groupId),
- rootPath: $boardApp.dataset.rootPath,
- currentUserId: gon.current_user_id || null,
- canUpdate: parseBoolean($boardApp.dataset.canUpdate),
- canAdminList: parseBoolean($boardApp.dataset.canAdminList),
- labelsManagePath: $boardApp.dataset.labelsManagePath,
- labelsFilterBasePath: $boardApp.dataset.labelsFilterBasePath,
- timeTrackingLimitToHours: parseBoolean($boardApp.dataset.timeTrackingLimitToHours),
- multipleAssigneesFeatureAvailable: parseBoolean(
- $boardApp.dataset.multipleAssigneesFeatureAvailable,
- ),
- epicFeatureAvailable: parseBoolean($boardApp.dataset.epicFeatureAvailable),
- iterationFeatureAvailable: parseBoolean($boardApp.dataset.iterationFeatureAvailable),
- weightFeatureAvailable: parseBoolean($boardApp.dataset.weightFeatureAvailable),
- boardWeight: $boardApp.dataset.boardWeight
- ? parseInt($boardApp.dataset.boardWeight, 10)
- : null,
- scopedLabelsAvailable: parseBoolean($boardApp.dataset.scopedLabels),
- milestoneListsAvailable: parseBoolean($boardApp.dataset.milestoneListsAvailable),
- assigneeListsAvailable: parseBoolean($boardApp.dataset.assigneeListsAvailable),
- iterationListsAvailable: parseBoolean($boardApp.dataset.iterationListsAvailable),
- issuableType: issuableTypes.issue,
- emailsDisabled: parseBoolean($boardApp.dataset.emailsDisabled),
- },
- store,
- apolloProvider,
- data() {
- return {
- state: boardsStore.state,
- loading: 0,
- boardsEndpoint: $boardApp.dataset.boardsEndpoint,
- recentBoardsEndpoint: $boardApp.dataset.recentBoardsEndpoint,
- listsEndpoint: $boardApp.dataset.listsEndpoint,
- disabled: parseBoolean($boardApp.dataset.disabled),
- bulkUpdatePath: $boardApp.dataset.bulkUpdatePath,
- detailIssue: boardsStore.detail,
- parent: $boardApp.dataset.parent,
- };
- },
- computed: {
- ...mapGetters(['shouldUseGraphQL']),
- detailIssueVisible() {
- return Object.keys(this.detailIssue.issue).length;
- },
- },
- created() {
- this.setInitialBoardData({
- boardId: $boardApp.dataset.boardId,
- fullBoardId: fullBoardId($boardApp.dataset.boardId),
- fullPath: $boardApp.dataset.fullPath,
- boardType: this.parent,
- disabled: this.disabled,
- issuableType: issuableTypes.issue,
- boardConfig: {
- milestoneId: parseInt($boardApp.dataset.boardMilestoneId, 10),
- milestoneTitle: $boardApp.dataset.boardMilestoneTitle || '',
- iterationId: parseInt($boardApp.dataset.boardIterationId, 10),
- iterationTitle: $boardApp.dataset.boardIterationTitle || '',
- assigneeId: $boardApp.dataset.boardAssigneeId,
- assigneeUsername: $boardApp.dataset.boardAssigneeUsername,
- labels: $boardApp.dataset.labels ? JSON.parse($boardApp.dataset.labels) : [],
- labelIds: $boardApp.dataset.labelIds ? JSON.parse($boardApp.dataset.labelIds) : [],
- weight: $boardApp.dataset.boardWeight
- ? parseInt($boardApp.dataset.boardWeight, 10)
- : null,
- },
- });
- boardsStore.setEndpoints({
- boardsEndpoint: this.boardsEndpoint,
- recentBoardsEndpoint: this.recentBoardsEndpoint,
- listsEndpoint: this.listsEndpoint,
- bulkUpdatePath: this.bulkUpdatePath,
- boardId: $boardApp.dataset.boardId,
- fullPath: $boardApp.dataset.fullPath,
- });
- boardsStore.rootPath = this.boardsEndpoint;
-
- eventHub.$on('updateTokens', this.updateTokens);
- eventHub.$on('newDetailIssue', this.updateDetailIssue);
- eventHub.$on('clearDetailIssue', this.clearDetailIssue);
- sidebarEventHub.$on('toggleSubscription', this.toggleSubscription);
- eventHub.$on('initialBoardLoad', this.initialBoardLoad);
- },
- beforeDestroy() {
- eventHub.$off('updateTokens', this.updateTokens);
- eventHub.$off('newDetailIssue', this.updateDetailIssue);
- eventHub.$off('clearDetailIssue', this.clearDetailIssue);
- sidebarEventHub.$off('toggleSubscription', this.toggleSubscription);
- eventHub.$off('initialBoardLoad', this.initialBoardLoad);
- },
- mounted() {
- if (!gon?.features?.issueBoardsFilteredSearch) {
- this.filterManager = new FilteredSearchBoards(
- boardsStore.filter,
- true,
- boardsStore.cantEdit,
- );
- this.filterManager.setup();
- }
-
- this.performSearch();
-
- boardsStore.disabled = this.disabled;
-
- if (!this.shouldUseGraphQL) {
- this.initialBoardLoad();
- }
- },
- methods: {
- ...mapActions(['setInitialBoardData', 'performSearch', 'setError']),
- initialBoardLoad() {
- boardsStore
- .all()
- .then((res) => res.data)
- .then((lists) => {
- lists.forEach((list) => boardsStore.addList(list));
- this.loading = false;
- })
- .catch((error) => {
- this.setError({
- error,
- message: __('An error occurred while fetching the board lists. Please try again.'),
- });
- });
- },
- updateTokens() {
- this.filterManager.updateTokens();
- },
- updateDetailIssue(newIssue, multiSelect = false) {
- const { sidebarInfoEndpoint } = newIssue;
- if (sidebarInfoEndpoint && newIssue.subscribed === undefined) {
- newIssue.setFetchingState('subscriptions', true);
- setWeightFetchingState(newIssue, true);
- setEpicFetchingState(newIssue, true);
- boardsStore
- .getIssueInfo(sidebarInfoEndpoint)
- .then((res) => res.data)
- .then((data) => {
- const {
- subscribed,
- totalTimeSpent,
- timeEstimate,
- humanTimeEstimate,
- humanTotalTimeSpent,
- weight,
- epic,
- assignees,
- } = convertObjectPropsToCamelCase(data);
-
- newIssue.setFetchingState('subscriptions', false);
- setWeightFetchingState(newIssue, false);
- setEpicFetchingState(newIssue, false);
- newIssue.updateData({
- humanTimeSpent: humanTotalTimeSpent,
- timeSpent: totalTimeSpent,
- humanTimeEstimate,
- timeEstimate,
- subscribed,
- weight,
- epic,
- assignees,
- });
- })
- .catch(() => {
- newIssue.setFetchingState('subscriptions', false);
- setWeightFetchingState(newIssue, false);
- this.setError({ message: __('An error occurred while fetching sidebar data') });
- });
- }
-
- if (multiSelect) {
- boardsStore.toggleMultiSelect(newIssue);
-
- if (boardsStore.detail.issue) {
- boardsStore.clearDetailIssue();
- return;
- }
-
- return;
- }
-
- boardsStore.setIssueDetail(newIssue);
- },
- clearDetailIssue(multiSelect = false) {
- if (multiSelect) {
- boardsStore.clearMultiSelect();
- }
- boardsStore.clearDetailIssue();
- },
- toggleSubscription(id) {
- const { issue } = boardsStore.detail;
- if (issue.id === id && issue.toggleSubscriptionEndpoint) {
- issue.setFetchingState('subscriptions', true);
- boardsStore
- .toggleIssueSubscription(issue.toggleSubscriptionEndpoint)
- .then(() => {
- issue.setFetchingState('subscriptions', false);
- issue.updateData({
- subscribed: !issue.subscribed,
- });
- })
- .catch(() => {
- issue.setFetchingState('subscriptions', false);
- this.setError({
- message: __('An error occurred when toggling the notification subscription'),
- });
- });
- }
- },
- getNodes(data) {
- return data[this.parent]?.board?.lists.nodes;
- },
- },
- });
-
- // eslint-disable-next-line no-new, @gitlab/no-runtime-template-compiler
- new Vue({
- el: document.getElementById('js-add-list'),
- data() {
- return {
- filters: boardsStore.state.filters,
- ...getMilestoneTitle($boardApp),
- };
- },
- mounted() {
- initNewListDropdown();
- },
- });
+ mountBoardApp($boardApp);
const createColumnTriggerEl = document.querySelector('.js-create-column-trigger');
if (createColumnTriggerEl) {
@@ -342,7 +140,7 @@ export default () => {
});
}
- boardConfigToggle(boardsStore);
+ boardConfigToggle();
toggleFocusMode();
toggleLabels();
diff --git a/app/assets/javascripts/boards/models/assignee.js b/app/assets/javascripts/boards/models/assignee.js
deleted file mode 100644
index 1e822d06bfd..00000000000
--- a/app/assets/javascripts/boards/models/assignee.js
+++ /dev/null
@@ -1,13 +0,0 @@
-export default class ListAssignee {
- constructor(obj) {
- this.id = obj.id;
- this.name = obj.name;
- this.username = obj.username;
- this.avatar = obj.avatarUrl || obj.avatar_url || obj.avatar || gon.default_avatar_url;
- this.path = obj.path;
- this.state = obj.state;
- this.webUrl = obj.web_url || obj.webUrl;
- }
-}
-
-window.ListAssignee = ListAssignee;
diff --git a/app/assets/javascripts/boards/models/issue.js b/app/assets/javascripts/boards/models/issue.js
deleted file mode 100644
index 46d1239457d..00000000000
--- a/app/assets/javascripts/boards/models/issue.js
+++ /dev/null
@@ -1,99 +0,0 @@
-/* eslint-disable no-unused-vars */
-/* global ListLabel */
-/* global ListMilestone */
-/* global ListAssignee */
-
-import axios from '~/lib/utils/axios_utils';
-import './label';
-import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
-import boardsStore from '../stores/boards_store';
-import IssueProject from './project';
-
-class ListIssue {
- constructor(obj) {
- this.subscribed = obj.subscribed;
- this.labels = [];
- this.assignees = [];
- this.selected = false;
- this.position = obj.position || obj.relative_position || obj.relativePosition || Infinity;
- this.isFetching = {
- subscriptions: true,
- };
- this.closed = obj.closed;
- this.isLoading = {};
-
- this.refreshData(obj);
- }
-
- refreshData(obj) {
- boardsStore.refreshIssueData(this, obj);
- }
-
- addLabel(label) {
- boardsStore.addIssueLabel(this, label);
- }
-
- findLabel(findLabel) {
- return boardsStore.findIssueLabel(this, findLabel);
- }
-
- removeLabel(removeLabel) {
- boardsStore.removeIssueLabel(this, removeLabel);
- }
-
- removeLabels(labels) {
- boardsStore.removeIssueLabels(this, labels);
- }
-
- addAssignee(assignee) {
- boardsStore.addIssueAssignee(this, assignee);
- }
-
- findAssignee(findAssignee) {
- return boardsStore.findIssueAssignee(this, findAssignee);
- }
-
- setAssignees(assignees) {
- boardsStore.setIssueAssignees(this, assignees);
- }
-
- removeAssignee(removeAssignee) {
- boardsStore.removeIssueAssignee(this, removeAssignee);
- }
-
- removeAllAssignees() {
- boardsStore.removeAllIssueAssignees(this);
- }
-
- addMilestone(milestone) {
- boardsStore.addIssueMilestone(this, milestone);
- }
-
- removeMilestone(removeMilestone) {
- boardsStore.removeIssueMilestone(this, removeMilestone);
- }
-
- getLists() {
- return boardsStore.state.lists.filter((list) => list.findIssue(this.id));
- }
-
- updateData(newData) {
- boardsStore.updateIssueData(this, newData);
- }
-
- setFetchingState(key, value) {
- boardsStore.setIssueFetchingState(this, key, value);
- }
-
- setLoadingState(key, value) {
- boardsStore.setIssueLoadingState(this, key, value);
- }
-
- update() {
- return boardsStore.updateIssue(this);
- }
-}
-
-window.ListIssue = ListIssue;
-
-export default ListIssue;
diff --git a/app/assets/javascripts/boards/models/iteration.js b/app/assets/javascripts/boards/models/iteration.js
deleted file mode 100644
index b7bdc204f7c..00000000000
--- a/app/assets/javascripts/boards/models/iteration.js
+++ /dev/null
@@ -1,9 +0,0 @@
-export default class ListIteration {
- constructor(obj) {
- this.id = obj.id;
- this.title = obj.title;
- this.state = obj.state;
- this.webUrl = obj.web_url || obj.webUrl;
- this.description = obj.description;
- }
-}
diff --git a/app/assets/javascripts/boards/models/label.js b/app/assets/javascripts/boards/models/label.js
deleted file mode 100644
index cd2a2c0137f..00000000000
--- a/app/assets/javascripts/boards/models/label.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
-
-export default class ListLabel {
- constructor(obj) {
- Object.assign(this, convertObjectPropsToCamelCase(obj, { dropKeys: ['priority'] }), {
- priority: obj.priority !== null ? obj.priority : Infinity,
- });
- }
-}
-
-window.ListLabel = ListLabel;
diff --git a/app/assets/javascripts/boards/models/list.js b/app/assets/javascripts/boards/models/list.js
deleted file mode 100644
index ab24532d87f..00000000000
--- a/app/assets/javascripts/boards/models/list.js
+++ /dev/null
@@ -1,182 +0,0 @@
-/* eslint-disable class-methods-use-this */
-import createFlash from '~/flash';
-import { __ } from '~/locale';
-import boardsStore from '../stores/boards_store';
-import ListAssignee from './assignee';
-import ListIteration from './iteration';
-import ListLabel from './label';
-import ListMilestone from './milestone';
-import 'ee_else_ce/boards/models/issue';
-
-const TYPES = {
- backlog: {
- isPreset: true,
- isExpandable: true,
- isBlank: false,
- },
- closed: {
- isPreset: true,
- isExpandable: true,
- isBlank: false,
- },
- blank: {
- isPreset: true,
- isExpandable: false,
- isBlank: true,
- },
- default: {
- // includes label, assignee, and milestone lists
- isPreset: false,
- isExpandable: true,
- isBlank: false,
- },
-};
-
-class List {
- constructor(obj) {
- this.id = obj.id;
- this.position = obj.position;
- this.title = obj.title;
- this.type = obj.list_type || obj.listType;
-
- const typeInfo = this.getTypeInfo(this.type);
- this.preset = Boolean(typeInfo.isPreset);
- this.isExpandable = Boolean(typeInfo.isExpandable);
- this.isExpanded = !obj.collapsed;
- this.page = 1;
- this.highlighted = obj.highlighted;
- this.loading = true;
- this.loadingMore = false;
- this.issues = obj.issues || [];
- this.issuesSize = obj.issuesSize || obj.issuesCount || 0;
- this.maxIssueCount = obj.maxIssueCount || obj.max_issue_count || 0;
-
- if (obj.label) {
- this.label = new ListLabel(obj.label);
- } else if (obj.user || obj.assignee) {
- this.assignee = new ListAssignee(obj.user || obj.assignee);
- this.title = this.assignee.name;
- } else if (IS_EE && obj.milestone) {
- this.milestone = new ListMilestone(obj.milestone);
- this.title = this.milestone.title;
- } else if (IS_EE && obj.iteration) {
- this.iteration = new ListIteration(obj.iteration);
- this.title = this.iteration.title;
- }
-
- // doNotFetchIssues is a temporary workaround until issues are fetched using GraphQL on issue boards
- // Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/229416
- if (!typeInfo.isBlank && this.id && !obj.doNotFetchIssues) {
- this.getIssues().catch(() => {
- // TODO: handle request error
- });
- }
- }
-
- guid() {
- const s4 = () =>
- Math.floor((1 + Math.random()) * 0x10000)
- .toString(16)
- .substring(1);
- return `${s4()}${s4()}-${s4()}-${s4()}-${s4()}-${s4()}${s4()}${s4()}`;
- }
-
- save() {
- return boardsStore.saveList(this);
- }
-
- destroy() {
- boardsStore.destroy(this);
- }
-
- update() {
- return boardsStore.updateListFunc(this);
- }
-
- nextPage() {
- return boardsStore.goToNextPage(this);
- }
-
- getIssues(emptyIssues = true) {
- return boardsStore.getListIssues(this, emptyIssues);
- }
-
- newIssue(issue) {
- return boardsStore.newListIssue(this, issue);
- }
-
- addMultipleIssues(issues, listFrom, newIndex) {
- boardsStore.addMultipleListIssues(this, issues, listFrom, newIndex);
- }
-
- addIssue(issue, listFrom, newIndex) {
- boardsStore.addListIssue(this, issue, listFrom, newIndex);
- }
-
- moveIssue(issue, oldIndex, newIndex, moveBeforeId, moveAfterId) {
- boardsStore.moveListIssues(this, issue, oldIndex, newIndex, moveBeforeId, moveAfterId);
- }
-
- moveMultipleIssues({ issues, oldIndicies, newIndex, moveBeforeId, moveAfterId }) {
- boardsStore
- .moveListMultipleIssues({
- list: this,
- issues,
- oldIndicies,
- newIndex,
- moveBeforeId,
- moveAfterId,
- })
- .catch(() =>
- createFlash({
- message: __('Something went wrong while moving issues.'),
- }),
- );
- }
-
- updateIssueLabel(issue, listFrom, moveBeforeId, moveAfterId) {
- boardsStore.moveIssue(issue.id, listFrom.id, this.id, moveBeforeId, moveAfterId).catch(() => {
- // TODO: handle request error
- });
- }
-
- updateMultipleIssues(issues, listFrom, moveBeforeId, moveAfterId) {
- boardsStore
- .moveMultipleIssues({
- ids: issues.map((issue) => issue.id),
- fromListId: listFrom.id,
- toListId: this.id,
- moveBeforeId,
- moveAfterId,
- })
- .catch(() =>
- createFlash({
- message: __('Something went wrong while moving issues.'),
- }),
- );
- }
-
- findIssue(id) {
- return boardsStore.findListIssue(this, id);
- }
-
- removeMultipleIssues(removeIssues) {
- return boardsStore.removeListMultipleIssues(this, removeIssues);
- }
-
- removeIssue(removeIssue) {
- return boardsStore.removeListIssues(this, removeIssue);
- }
-
- getTypeInfo(type) {
- return TYPES[type] || TYPES.default;
- }
-
- onNewIssueResponse(issue, data) {
- boardsStore.onNewListIssueResponse(this, issue, data);
- }
-}
-
-window.List = List;
-
-export default List;
diff --git a/app/assets/javascripts/boards/models/milestone.js b/app/assets/javascripts/boards/models/milestone.js
deleted file mode 100644
index 7201b6e91f5..00000000000
--- a/app/assets/javascripts/boards/models/milestone.js
+++ /dev/null
@@ -1,15 +0,0 @@
-export default class ListMilestone {
- constructor(obj) {
- this.id = obj.id;
- this.title = obj.title;
-
- if (IS_EE) {
- this.path = obj.path;
- this.state = obj.state;
- this.webUrl = obj.web_url || obj.webUrl;
- this.description = obj.description;
- }
- }
-}
-
-window.ListMilestone = ListMilestone;
diff --git a/app/assets/javascripts/boards/models/project.js b/app/assets/javascripts/boards/models/project.js
deleted file mode 100644
index 9468a02856e..00000000000
--- a/app/assets/javascripts/boards/models/project.js
+++ /dev/null
@@ -1,7 +0,0 @@
-export default class IssueProject {
- constructor(obj) {
- this.id = obj.id;
- this.path = obj.path;
- this.fullPath = obj.path_with_namespace;
- }
-}
diff --git a/app/assets/javascripts/boards/mount_multiple_boards_switcher.js b/app/assets/javascripts/boards/mount_multiple_boards_switcher.js
index 7d6179a8547..a3a8ad06c43 100644
--- a/app/assets/javascripts/boards/mount_multiple_boards_switcher.js
+++ b/app/assets/javascripts/boards/mount_multiple_boards_switcher.js
@@ -1,12 +1,9 @@
import Vue from 'vue';
import VueApollo from 'vue-apollo';
-import { mapGetters } from 'vuex';
import BoardsSelector from 'ee_else_ce/boards/components/boards_selector.vue';
-import BoardsSelectorDeprecated from '~/boards/components/boards_selector_deprecated.vue';
import store from '~/boards/stores';
import createDefaultClient from '~/lib/graphql';
import { parseBoolean } from '~/lib/utils/common_utils';
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
Vue.use(VueApollo);
@@ -25,9 +22,7 @@ export default (params = {}) => {
el: boardsSwitcherElement,
components: {
BoardsSelector,
- BoardsSelectorDeprecated,
},
- mixins: [glFeatureFlagMixin()],
apolloProvider,
store,
provide: {
@@ -52,16 +47,8 @@ export default (params = {}) => {
return { boardsSelectorProps };
},
- computed: {
- ...mapGetters(['shouldUseGraphQL', 'isEpicBoard']),
- },
render(createElement) {
- if (this.shouldUseGraphQL || this.isEpicBoard) {
- return createElement(BoardsSelector, {
- props: this.boardsSelectorProps,
- });
- }
- return createElement(BoardsSelectorDeprecated, {
+ return createElement(BoardsSelector, {
props: this.boardsSelectorProps,
});
},
diff --git a/app/assets/javascripts/boards/stores/actions.js b/app/assets/javascripts/boards/stores/actions.js
index 970d00841bd..dc06b62cebb 100644
--- a/app/assets/javascripts/boards/stores/actions.js
+++ b/app/assets/javascripts/boards/stores/actions.js
@@ -36,11 +36,13 @@ import {
filterVariables,
} from '../boards_util';
import boardLabelsQuery from '../graphql/board_labels.query.graphql';
+import groupBoardIterationsQuery from '../graphql/group_board_iterations.query.graphql';
import groupBoardMilestonesQuery from '../graphql/group_board_milestones.query.graphql';
import groupProjectsQuery from '../graphql/group_projects.query.graphql';
import issueCreateMutation from '../graphql/issue_create.mutation.graphql';
import issueSetLabelsMutation from '../graphql/issue_set_labels.mutation.graphql';
import listsIssuesQuery from '../graphql/lists_issues.query.graphql';
+import projectBoardIterationsQuery from '../graphql/project_board_iterations.query.graphql';
import projectBoardMilestonesQuery from '../graphql/project_board_milestones.query.graphql';
import * as types from './mutation_types';
@@ -82,11 +84,8 @@ export default {
'setFilters',
convertObjectPropsToCamelCase(queryToObject(window.location.search, { gatherArrays: true })),
);
-
- if (gon.features.graphqlBoardLists) {
- dispatch('fetchLists');
- dispatch('resetIssues');
- }
+ dispatch('fetchLists');
+ dispatch('resetIssues');
},
fetchLists: ({ commit, state, dispatch }) => {
@@ -182,7 +181,7 @@ export default {
});
},
- fetchLabels: ({ state, commit, getters }, searchTerm) => {
+ fetchLabels: ({ state, commit }, searchTerm) => {
const { fullPath, boardType } = state;
const variables = {
@@ -200,14 +199,7 @@ export default {
variables,
})
.then(({ data }) => {
- let labels = data[boardType]?.labels.nodes;
-
- if (!getters.shouldUseGraphQL && !getters.isEpicBoard) {
- labels = labels.map((label) => ({
- ...label,
- id: getIdFromGraphQLId(label.id),
- }));
- }
+ const labels = data[boardType]?.labels.nodes;
commit(types.RECEIVE_LABELS_SUCCESS, labels);
return labels;
@@ -218,6 +210,52 @@ export default {
});
},
+ fetchIterations({ state, commit }, title) {
+ commit(types.RECEIVE_ITERATIONS_REQUEST);
+
+ const { fullPath, boardType } = state;
+
+ const variables = {
+ fullPath,
+ title,
+ };
+
+ let query;
+ if (boardType === BoardType.project) {
+ query = projectBoardIterationsQuery;
+ }
+ if (boardType === BoardType.group) {
+ query = groupBoardIterationsQuery;
+ }
+
+ if (!query) {
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ throw new Error('Unknown board type');
+ }
+
+ return gqlClient
+ .query({
+ query,
+ variables,
+ })
+ .then(({ data }) => {
+ const errors = data[boardType]?.errors;
+ const iterations = data[boardType]?.iterations.nodes;
+
+ if (errors?.[0]) {
+ throw new Error(errors[0]);
+ }
+
+ commit(types.RECEIVE_ITERATIONS_SUCCESS, iterations);
+
+ return iterations;
+ })
+ .catch((e) => {
+ commit(types.RECEIVE_ITERATIONS_FAILURE);
+ throw e;
+ });
+ },
+
fetchMilestones({ state, commit }, searchTerm) {
commit(types.RECEIVE_MILESTONES_REQUEST);
@@ -536,8 +574,8 @@ export default {
boardId: fullBoardId,
fromListId: getIdFromGraphQLId(fromListId),
toListId: getIdFromGraphQLId(toListId),
- moveBeforeId,
- moveAfterId,
+ moveBeforeId: moveBeforeId ? getIdFromGraphQLId(moveBeforeId) : undefined,
+ moveAfterId: moveAfterId ? getIdFromGraphQLId(moveAfterId) : undefined,
// 'mutationVariables' allows EE code to pass in extra parameters.
...mutationVariables,
},
@@ -604,7 +642,7 @@ export default {
}
const rawIssue = data.createIssue?.issue;
- const formattedIssue = formatIssue({ ...rawIssue, id: getIdFromGraphQLId(rawIssue.id) });
+ const formattedIssue = formatIssue(rawIssue);
dispatch('removeListItem', { listId: list.id, itemId: placeholderId });
dispatch('addListItem', { list, item: formattedIssue, position: 0 });
})
@@ -640,7 +678,7 @@ export default {
}
commit(types.UPDATE_BOARD_ITEM_BY_ID, {
- itemId: getIdFromGraphQLId(data.updateIssue?.issue?.id) || activeBoardItem.id,
+ itemId: data.updateIssue?.issue?.id || activeBoardItem.id,
prop: 'labels',
value: data.updateIssue.issue.labels.nodes,
});
diff --git a/app/assets/javascripts/boards/stores/boards_store.js b/app/assets/javascripts/boards/stores/boards_store.js
deleted file mode 100644
index 857b0912c57..00000000000
--- a/app/assets/javascripts/boards/stores/boards_store.js
+++ /dev/null
@@ -1,883 +0,0 @@
-/* eslint-disable no-shadow, no-param-reassign,consistent-return */
-/* global List */
-/* global ListIssue */
-import { sortBy } from 'lodash';
-import Vue from 'vue';
-import BoardsStoreEE from 'ee_else_ce/boards/stores/boards_store_ee';
-import { getIdFromGraphQLId } from '~/graphql_shared/utils';
-import createDefaultClient from '~/lib/graphql';
-import axios from '~/lib/utils/axios_utils';
-import { parseBoolean, convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
-import { mergeUrlParams, queryToObject, getUrlParamsArray } from '~/lib/utils/url_utility';
-import { ListType, flashAnimationDuration } from '../constants';
-import eventHub from '../eventhub';
-import ListAssignee from '../models/assignee';
-import ListLabel from '../models/label';
-import ListMilestone from '../models/milestone';
-import IssueProject from '../models/project';
-
-const PER_PAGE = 20;
-export const gqlClient = createDefaultClient();
-
-const boardsStore = {
- disabled: false,
- timeTracking: {
- limitToHours: false,
- },
- scopedLabels: {
- enabled: false,
- },
- filter: {
- path: '',
- },
- state: {
- currentBoard: {
- labels: [],
- },
- currentPage: '',
- endpoints: {},
- },
- detail: {
- issue: {},
- list: {},
- },
- moving: {
- issue: {},
- list: {},
- },
- multiSelect: { list: [] },
-
- setEndpoints({
- boardsEndpoint,
- listsEndpoint,
- bulkUpdatePath,
- boardId,
- recentBoardsEndpoint,
- fullPath,
- }) {
- const listsEndpointGenerate = `${listsEndpoint}/generate.json`;
- this.state.endpoints = {
- boardsEndpoint,
- boardId,
- listsEndpoint,
- listsEndpointGenerate,
- bulkUpdatePath,
- fullPath,
- recentBoardsEndpoint: `${recentBoardsEndpoint}.json`,
- };
- },
- create() {
- this.state.lists = [];
- this.filter.path = getUrlParamsArray().join('&');
- this.detail = {
- issue: {},
- list: {},
- };
- },
- showPage(page) {
- this.state.currentPage = page;
- },
- updateListPosition(listObj) {
- const listType = listObj.listType || listObj.list_type;
- let { position } = listObj;
- if (listType === ListType.closed) {
- position = Infinity;
- } else if (listType === ListType.backlog) {
- position = -1;
- }
-
- const list = new List({ ...listObj, position });
- return list;
- },
- addList(listObj) {
- const list = this.updateListPosition(listObj);
- this.state.lists = sortBy([...this.state.lists, list], 'position');
- return list;
- },
- new(listObj) {
- const list = this.addList(listObj);
- const backlogList = this.findList('type', 'backlog');
-
- list
- .save()
- .then(() => {
- list.highlighted = true;
- setTimeout(() => {
- list.highlighted = false;
- }, flashAnimationDuration);
-
- // Remove any new issues from the backlog
- // as they will be visible in the new list
- list.issues.forEach(backlogList.removeIssue.bind(backlogList));
- this.state.lists = sortBy(this.state.lists, 'position');
- })
- .catch(() => {
- // https://gitlab.com/gitlab-org/gitlab-foss/issues/30821
- });
- },
-
- updateNewListDropdown(listId) {
- document
- .querySelector(`.js-board-list-${getIdFromGraphQLId(listId)}`)
- ?.classList.remove('is-active');
- },
-
- findIssueLabel(issue, findLabel) {
- return issue.labels.find((label) => label.id === findLabel.id);
- },
-
- goToNextPage(list) {
- if (list.issuesSize > list.issues.length) {
- if (list.issues.length / PER_PAGE >= 1) {
- list.page += 1;
- }
-
- return list.getIssues(false);
- }
- },
-
- addListIssue(list, issue, listFrom, newIndex) {
- let moveBeforeId = null;
- let moveAfterId = null;
-
- if (!list.findIssue(issue.id)) {
- if (newIndex !== undefined) {
- list.issues.splice(newIndex, 0, issue);
-
- if (list.issues[newIndex - 1]) {
- moveBeforeId = list.issues[newIndex - 1].id;
- }
-
- if (list.issues[newIndex + 1]) {
- moveAfterId = list.issues[newIndex + 1].id;
- }
- } else {
- list.issues.push(issue);
- }
-
- if (list.label) {
- issue.addLabel(list.label);
- }
-
- if (list.assignee) {
- if (listFrom && listFrom.type === 'assignee') {
- issue.removeAssignee(listFrom.assignee);
- }
- issue.addAssignee(list.assignee);
- }
-
- if (IS_EE && list.milestone) {
- if (listFrom && listFrom.type === 'milestone') {
- issue.removeMilestone(listFrom.milestone);
- }
- issue.addMilestone(list.milestone);
- }
-
- if (listFrom) {
- list.issuesSize += 1;
-
- list.updateIssueLabel(issue, listFrom, moveBeforeId, moveAfterId);
- }
- }
- },
- findListIssue(list, id) {
- return list.issues.find((issue) => issue.id === id);
- },
-
- removeList(id) {
- const list = this.findList('id', id);
-
- if (!list) return;
-
- this.state.lists = this.state.lists.filter((list) => list.id !== id);
- },
- moveList(listFrom, orderLists) {
- orderLists.forEach((id, i) => {
- const list = this.findList('id', parseInt(id, 10));
-
- list.position = i;
- });
- listFrom.update();
- },
-
- addMultipleListIssues(list, issues, listFrom, newIndex) {
- let moveBeforeId = null;
- let moveAfterId = null;
-
- const listHasIssues = issues.every((issue) => list.findIssue(issue.id));
-
- if (!listHasIssues) {
- if (newIndex !== undefined) {
- if (list.issues[newIndex - 1]) {
- moveBeforeId = list.issues[newIndex - 1].id;
- }
-
- if (list.issues[newIndex]) {
- moveAfterId = list.issues[newIndex].id;
- }
-
- list.issues.splice(newIndex, 0, ...issues);
- } else {
- list.issues.push(...issues);
- }
-
- if (list.label) {
- issues.forEach((issue) => issue.addLabel(list.label));
- }
-
- if (list.assignee) {
- if (listFrom && listFrom.type === 'assignee') {
- issues.forEach((issue) => issue.removeAssignee(listFrom.assignee));
- }
- issues.forEach((issue) => issue.addAssignee(list.assignee));
- }
-
- if (IS_EE && list.milestone) {
- if (listFrom && listFrom.type === 'milestone') {
- issues.forEach((issue) => issue.removeMilestone(listFrom.milestone));
- }
- issues.forEach((issue) => issue.addMilestone(list.milestone));
- }
-
- if (listFrom) {
- list.issuesSize += issues.length;
-
- list.updateMultipleIssues(issues, listFrom, moveBeforeId, moveAfterId);
- }
- }
- },
-
- removeListIssues(list, removeIssue) {
- list.issues = list.issues.filter((issue) => {
- const matchesRemove = removeIssue.id === issue.id;
-
- if (matchesRemove) {
- list.issuesSize -= 1;
- issue.removeLabel(list.label);
- }
-
- return !matchesRemove;
- });
- },
- removeListMultipleIssues(list, removeIssues) {
- const ids = removeIssues.map((issue) => issue.id);
-
- list.issues = list.issues.filter((issue) => {
- const matchesRemove = ids.includes(issue.id);
-
- if (matchesRemove) {
- list.issuesSize -= 1;
- issue.removeLabel(list.label);
- }
-
- return !matchesRemove;
- });
- },
-
- startMoving(list, issue) {
- Object.assign(this.moving, { list, issue });
- },
-
- onNewListIssueResponse(list, issue, data) {
- issue.refreshData(data);
-
- if (list.issues.length > 1) {
- const moveBeforeId = list.issues[1].id;
- this.moveIssue(issue.id, null, null, null, moveBeforeId);
- }
- },
-
- moveMultipleIssuesToList({ listFrom, listTo, issues, newIndex }) {
- const issueTo = issues.map((issue) => listTo.findIssue(issue.id));
- const issueLists = issues.map((issue) => issue.getLists()).flat();
- const listLabels = issueLists.map((list) => list.label);
- const hasMoveableIssues = issueTo.filter(Boolean).length > 0;
-
- if (!hasMoveableIssues) {
- // Check if target list assignee is already present in this issue
- if (
- listTo.type === ListType.assignee &&
- listFrom.type === ListType.assignee &&
- issues.some((issue) => issue.findAssignee(listTo.assignee))
- ) {
- const targetIssues = issues.map((issue) => listTo.findIssue(issue.id));
- targetIssues.forEach((targetIssue) => targetIssue.removeAssignee(listFrom.assignee));
- } else if (listTo.type === 'milestone') {
- const currentMilestones = issues.map((issue) => issue.milestone);
- const currentLists = this.state.lists
- .filter((list) => list.type === 'milestone' && list.id !== listTo.id)
- .filter((list) =>
- list.issues.some((listIssue) => issues.some((issue) => listIssue.id === issue.id)),
- );
-
- issues.forEach((issue) => {
- currentMilestones.forEach((milestone) => {
- issue.removeMilestone(milestone);
- });
- });
-
- issues.forEach((issue) => {
- issue.addMilestone(listTo.milestone);
- });
-
- currentLists.forEach((currentList) => {
- issues.forEach((issue) => {
- currentList.removeIssue(issue);
- });
- });
-
- listTo.addMultipleIssues(issues, listFrom, newIndex);
- } else {
- // Add to new lists issues if it doesn't already exist
- listTo.addMultipleIssues(issues, listFrom, newIndex);
- }
- } else {
- listTo.updateMultipleIssues(issues, listFrom);
- issues.forEach((issue) => {
- issue.removeLabel(listFrom.label);
- });
- }
-
- if (listTo.type === ListType.closed && listFrom.type !== ListType.backlog) {
- issueLists.forEach((list) => {
- issues.forEach((issue) => {
- list.removeIssue(issue);
- });
- });
-
- issues.forEach((issue) => {
- issue.removeLabels(listLabels);
- });
- } else if (listTo.type === ListType.backlog && listFrom.type === ListType.assignee) {
- issues.forEach((issue) => {
- issue.removeAssignee(listFrom.assignee);
- });
- issueLists.forEach((list) => {
- issues.forEach((issue) => {
- list.removeIssue(issue);
- });
- });
- } else if (listTo.type === ListType.backlog && listFrom.type === ListType.milestone) {
- issues.forEach((issue) => {
- issue.removeMilestone(listFrom.milestone);
- });
- issueLists.forEach((list) => {
- issues.forEach((issue) => {
- list.removeIssue(issue);
- });
- });
- } else if (
- this.shouldRemoveIssue(listFrom, listTo) &&
- this.issuesAreContiguous(listFrom, issues)
- ) {
- listFrom.removeMultipleIssues(issues);
- }
- },
-
- issuesAreContiguous(list, issues) {
- // When there's only 1 issue selected, we can return early.
- if (issues.length === 1) return true;
-
- // Create list of ids for issues involved.
- const listIssueIds = list.issues.map((issue) => issue.id);
- const movedIssueIds = issues.map((issue) => issue.id);
-
- // Check if moved issue IDs is sub-array
- // of source list issue IDs (i.e. contiguous selection).
- return listIssueIds.join('|').includes(movedIssueIds.join('|'));
- },
-
- moveIssueToList(listFrom, listTo, issue, newIndex) {
- const issueTo = listTo.findIssue(issue.id);
- const issueLists = issue.getLists();
- const listLabels = issueLists.map((listIssue) => listIssue.label);
-
- if (!issueTo) {
- // Check if target list assignee is already present in this issue
- if (
- listTo.type === 'assignee' &&
- listFrom.type === 'assignee' &&
- issue.findAssignee(listTo.assignee)
- ) {
- const targetIssue = listTo.findIssue(issue.id);
- targetIssue.removeAssignee(listFrom.assignee);
- } else if (listTo.type === 'milestone') {
- const currentMilestone = issue.milestone;
- const currentLists = this.state.lists
- .filter((list) => list.type === 'milestone' && list.id !== listTo.id)
- .filter((list) => list.issues.some((listIssue) => issue.id === listIssue.id));
-
- issue.removeMilestone(currentMilestone);
- issue.addMilestone(listTo.milestone);
- currentLists.forEach((currentList) => currentList.removeIssue(issue));
- listTo.addIssue(issue, listFrom, newIndex);
- } else {
- // Add to new lists issues if it doesn't already exist
- listTo.addIssue(issue, listFrom, newIndex);
- }
- } else {
- listTo.updateIssueLabel(issue, listFrom);
- issueTo.removeLabel(listFrom.label);
- }
-
- if (listTo.type === 'closed' && listFrom.type !== 'backlog') {
- issueLists.forEach((list) => {
- list.removeIssue(issue);
- });
- issue.removeLabels(listLabels);
- } else if (listTo.type === 'backlog' && listFrom.type === 'assignee') {
- issue.removeAssignee(listFrom.assignee);
- listFrom.removeIssue(issue);
- } else if (listTo.type === 'backlog' && listFrom.type === 'milestone') {
- issue.removeMilestone(listFrom.milestone);
- listFrom.removeIssue(issue);
- } else if (this.shouldRemoveIssue(listFrom, listTo)) {
- listFrom.removeIssue(issue);
- }
- },
- shouldRemoveIssue(listFrom, listTo) {
- return (
- (listTo.type !== 'label' && listFrom.type === 'assignee') ||
- (listTo.type !== 'assignee' && listFrom.type === 'label') ||
- listFrom.type === 'backlog' ||
- listFrom.type === 'closed'
- );
- },
- moveIssueInList(list, issue, oldIndex, newIndex, idArray) {
- const beforeId = parseInt(idArray[newIndex - 1], 10) || null;
- const afterId = parseInt(idArray[newIndex + 1], 10) || null;
-
- list.moveIssue(issue, oldIndex, newIndex, beforeId, afterId);
- },
- moveMultipleIssuesInList({ list, issues, oldIndicies, newIndex, idArray }) {
- const beforeId = parseInt(idArray[newIndex - 1], 10) || null;
- const afterId = parseInt(idArray[newIndex + issues.length], 10) || null;
- list.moveMultipleIssues({
- issues,
- oldIndicies,
- newIndex,
- moveBeforeId: beforeId,
- moveAfterId: afterId,
- });
- },
- findList(key, val) {
- return this.state.lists.find((list) => list[key] === val);
- },
- findListByLabelId(id) {
- return this.state.lists.find((list) => list.type === 'label' && list.label.id === id);
- },
-
- toggleFilter(filter) {
- const filterPath = this.filter.path.split('&');
- const filterIndex = filterPath.indexOf(filter);
-
- if (filterIndex === -1) {
- filterPath.push(filter);
- } else {
- filterPath.splice(filterIndex, 1);
- }
-
- this.filter.path = filterPath.join('&');
-
- this.updateFiltersUrl();
-
- eventHub.$emit('updateTokens');
- },
-
- setListDetail(newList) {
- this.detail.list = newList;
- },
-
- updateFiltersUrl() {
- window.history.pushState(null, null, `?${this.filter.path}`);
- },
-
- clearDetailIssue() {
- this.setIssueDetail({});
- },
-
- setIssueDetail(issueDetail) {
- this.detail.issue = issueDetail;
- },
-
- setTimeTrackingLimitToHours(limitToHours) {
- this.timeTracking.limitToHours = parseBoolean(limitToHours);
- },
-
- generateBoardGid(boardId) {
- return `gid://gitlab/Board/${boardId}`;
- },
-
- generateBoardsPath(id) {
- return `${this.state.endpoints.boardsEndpoint}${id ? `/${id}` : ''}.json`;
- },
-
- generateIssuesPath(id) {
- return `${this.state.endpoints.listsEndpoint}${id ? `/${id}` : ''}/issues`;
- },
-
- generateIssuePath(boardId, id) {
- return `${gon.relative_url_root}/-/boards/${boardId ? `${boardId}` : ''}/issues${
- id ? `/${id}` : ''
- }`;
- },
-
- generateMultiDragPath(boardId) {
- return `${gon.relative_url_root}/-/boards/${boardId ? `${boardId}` : ''}/issues/bulk_move`;
- },
-
- all() {
- return axios.get(this.state.endpoints.listsEndpoint);
- },
-
- createList(entityId, entityType) {
- const list = {
- [entityType]: entityId,
- };
-
- return axios.post(this.state.endpoints.listsEndpoint, {
- list,
- });
- },
-
- updateList(id, position, collapsed) {
- return axios.put(`${this.state.endpoints.listsEndpoint}/${id}`, {
- list: {
- position,
- collapsed,
- },
- });
- },
-
- updateListFunc(list) {
- const collapsed = !list.isExpanded;
- return this.updateList(list.id, list.position, collapsed).catch(() => {
- // TODO: handle request error
- });
- },
-
- destroyList(id) {
- return axios.delete(`${this.state.endpoints.listsEndpoint}/${id}`);
- },
- destroy(list) {
- const index = this.state.lists.indexOf(list);
- this.state.lists.splice(index, 1);
- this.updateNewListDropdown(list.id);
-
- this.destroyList(list.id).catch(() => {
- // TODO: handle request error
- });
- },
-
- saveList(list) {
- const entity = list.label || list.assignee || list.milestone || list.iteration;
- let entityType = '';
- if (list.label) {
- entityType = 'label_id';
- } else if (list.assignee) {
- entityType = 'assignee_id';
- } else if (IS_EE && list.milestone) {
- entityType = 'milestone_id';
- } else if (IS_EE && list.iteration) {
- entityType = 'iteration_id';
- }
-
- return this.createList(entity.id, entityType)
- .then((res) => res.data)
- .then((data) => {
- list.id = data.id;
- list.type = data.list_type;
- list.position = data.position;
- list.label = data.label;
-
- return list.getIssues();
- });
- },
-
- getListIssues(list, emptyIssues = true) {
- const data = {
- ...queryToObject(this.filter.path, { gatherArrays: true }),
- page: list.page,
- };
-
- if (list.label && data.label_name) {
- data.label_name = data.label_name.filter((label) => label !== list.label.title);
- }
-
- if (emptyIssues) {
- list.loading = true;
- }
-
- return this.getIssuesForList(list.id, data)
- .then((res) => res.data)
- .then((data) => {
- list.loading = false;
- list.issuesSize = data.size;
-
- if (emptyIssues) {
- list.issues = [];
- }
-
- data.issues.forEach((issueObj) => {
- list.addIssue(new ListIssue(issueObj));
- });
-
- return data;
- });
- },
-
- getIssuesForList(id, filter = {}) {
- const data = { id };
- Object.keys(filter).forEach((key) => {
- data[key] = filter[key];
- });
-
- return axios.get(mergeUrlParams(data, this.generateIssuesPath(id)));
- },
-
- moveIssue(id, fromListId = null, toListId = null, moveBeforeId = null, moveAfterId = null) {
- return axios.put(this.generateIssuePath(this.state.endpoints.boardId, id), {
- from_list_id: fromListId,
- to_list_id: toListId,
- move_before_id: moveBeforeId,
- move_after_id: moveAfterId,
- });
- },
-
- moveListIssues(list, issue, oldIndex, newIndex, moveBeforeId, moveAfterId) {
- list.issues.splice(oldIndex, 1);
- list.issues.splice(newIndex, 0, issue);
-
- this.moveIssue(issue.id, null, null, moveBeforeId, moveAfterId).catch(() => {
- // TODO: handle request error
- });
- },
-
- moveMultipleIssues({ ids, fromListId, toListId, moveBeforeId, moveAfterId }) {
- return axios.put(this.generateMultiDragPath(this.state.endpoints.boardId), {
- from_list_id: fromListId,
- to_list_id: toListId,
- move_before_id: moveBeforeId,
- move_after_id: moveAfterId,
- ids,
- });
- },
-
- moveListMultipleIssues({ list, issues, oldIndicies, newIndex, moveBeforeId, moveAfterId }) {
- oldIndicies.reverse().forEach((index) => {
- list.issues.splice(index, 1);
- });
- list.issues.splice(newIndex, 0, ...issues);
-
- return this.moveMultipleIssues({
- ids: issues.map((issue) => issue.id),
- fromListId: null,
- toListId: null,
- moveBeforeId,
- moveAfterId,
- });
- },
-
- newIssue(id, issue) {
- if (typeof id === 'string') {
- id = getIdFromGraphQLId(id);
- }
-
- return axios.post(this.generateIssuesPath(id), {
- issue,
- });
- },
-
- newListIssue(list, issue) {
- list.addIssue(issue, null, 0);
- list.issuesSize += 1;
- let listId = list.id;
- if (typeof listId === 'string') {
- listId = getIdFromGraphQLId(listId);
- }
-
- return this.newIssue(list.id, issue)
- .then((res) => res.data)
- .then((data) => list.onNewIssueResponse(issue, data));
- },
-
- getBacklog(data) {
- return axios.get(
- mergeUrlParams(
- data,
- `${gon.relative_url_root}/-/boards/${this.state.endpoints.boardId}/issues.json`,
- ),
- );
- },
- removeIssueLabel(issue, removeLabel) {
- if (removeLabel) {
- issue.labels = issue.labels.filter((label) => removeLabel.id !== label.id);
- }
- },
-
- addIssueAssignee(issue, assignee) {
- if (!issue.findAssignee(assignee)) {
- issue.assignees.push(new ListAssignee(assignee));
- }
- },
-
- setIssueAssignees(issue, assignees) {
- issue.assignees = [...assignees];
- },
-
- removeIssueLabels(issue, labels) {
- labels.forEach(issue.removeLabel.bind(issue));
- },
-
- bulkUpdate(issueIds, extraData = {}) {
- const data = {
- update: Object.assign(extraData, {
- issuable_ids: issueIds.join(','),
- }),
- };
-
- return axios.post(this.state.endpoints.bulkUpdatePath, data);
- },
-
- getIssueInfo(endpoint) {
- return axios.get(endpoint);
- },
-
- toggleIssueSubscription(endpoint) {
- return axios.post(endpoint);
- },
-
- recentBoards() {
- return axios.get(this.state.endpoints.recentBoardsEndpoint);
- },
-
- setCurrentBoard(board) {
- this.state.currentBoard = board;
- },
-
- toggleMultiSelect(issue) {
- const selectedIssueIds = this.multiSelect.list.map((issue) => issue.id);
- const index = selectedIssueIds.indexOf(issue.id);
-
- if (index === -1) {
- this.multiSelect.list.push(issue);
- return;
- }
-
- this.multiSelect.list = [
- ...this.multiSelect.list.slice(0, index),
- ...this.multiSelect.list.slice(index + 1),
- ];
- },
- removeIssueAssignee(issue, removeAssignee) {
- if (removeAssignee) {
- issue.assignees = issue.assignees.filter((assignee) => assignee.id !== removeAssignee.id);
- }
- },
-
- findIssueAssignee(issue, findAssignee) {
- return issue.assignees.find((assignee) => assignee.id === findAssignee.id);
- },
-
- clearMultiSelect() {
- this.multiSelect.list = [];
- },
-
- removeAllIssueAssignees(issue) {
- issue.assignees = [];
- },
-
- addIssueMilestone(issue, milestone) {
- const miletoneId = issue.milestone ? issue.milestone.id : null;
- if (IS_EE && milestone.id !== miletoneId) {
- issue.milestone = new ListMilestone(milestone);
- }
- },
-
- setIssueLoadingState(issue, key, value) {
- issue.isLoading[key] = value;
- },
-
- updateIssueData(issue, newData) {
- Object.assign(issue, newData);
- },
-
- setIssueFetchingState(issue, key, value) {
- issue.isFetching[key] = value;
- },
-
- removeIssueMilestone(issue, removeMilestone) {
- if (IS_EE && removeMilestone && removeMilestone.id === issue.milestone.id) {
- issue.milestone = {};
- }
- },
-
- refreshIssueData(issue, obj) {
- const convertedObj = convertObjectPropsToCamelCase(obj, {
- dropKeys: ['issue_sidebar_endpoint', 'real_path', 'webUrl'],
- });
- convertedObj.sidebarInfoEndpoint = obj.issue_sidebar_endpoint;
- issue.path = obj.real_path || obj.webUrl;
- issue.project_id = obj.project_id;
- Object.assign(issue, convertedObj);
-
- if (obj.project) {
- issue.project = new IssueProject(obj.project);
- }
-
- if (obj.milestone) {
- issue.milestone = new ListMilestone(obj.milestone);
- issue.milestone_id = obj.milestone.id;
- }
-
- if (obj.labels) {
- issue.labels = obj.labels.map((label) => new ListLabel(label));
- }
-
- if (obj.assignees) {
- issue.assignees = obj.assignees.map((a) => new ListAssignee(a));
- }
- },
- addIssueLabel(issue, label) {
- if (!issue.findLabel(label)) {
- issue.labels.push(new ListLabel(label));
- }
- },
- updateIssue(issue) {
- const data = {
- issue: {
- milestone_id: issue.milestone ? issue.milestone.id : null,
- due_date: issue.dueDate,
- assignee_ids: issue.assignees.length > 0 ? issue.assignees.map(({ id }) => id) : [0],
- label_ids: issue.labels.length > 0 ? issue.labels.map(({ id }) => id) : [''],
- },
- };
-
- return axios.patch(`${issue.path}.json`, data).then(({ data: body = {} } = {}) => {
- /**
- * Since post implementation of Scoped labels, server can reject
- * same key-ed labels. To keep the UI and server Model consistent,
- * we're just assigning labels that server echo's back to us when we
- * PATCH the said object.
- */
- if (body) {
- issue.labels = convertObjectPropsToCamelCase(body.labels, { deep: true });
- }
- });
- },
-};
-
-BoardsStoreEE.initEESpecific(boardsStore);
-
-// hacks added in order to allow milestone_select to function properly
-// TODO: remove these
-
-export function boardStoreIssueSet(...args) {
- Vue.set(boardsStore.detail.issue, ...args);
-}
-
-export function boardStoreIssueDelete(...args) {
- Vue.delete(boardsStore.detail.issue, ...args);
-}
-
-export default boardsStore;
diff --git a/app/assets/javascripts/boards/stores/boards_store_ee.js b/app/assets/javascripts/boards/stores/boards_store_ee.js
deleted file mode 100644
index 2a289ce5d0a..00000000000
--- a/app/assets/javascripts/boards/stores/boards_store_ee.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// this is just to make ee_else_ce happy and will be cleaned up in https://gitlab.com/gitlab-org/gitlab-foss/issues/59807
-
-export default {
- initEESpecific() {},
-};
diff --git a/app/assets/javascripts/boards/stores/getters.js b/app/assets/javascripts/boards/stores/getters.js
index 140c9ef7ac4..cb31eb4b008 100644
--- a/app/assets/javascripts/boards/stores/getters.js
+++ b/app/assets/javascripts/boards/stores/getters.js
@@ -16,7 +16,7 @@ export default {
},
activeBoardItem: (state) => {
- return state.boardItems[state.activeId] || { iid: '', id: '', fullId: '' };
+ return state.boardItems[state.activeId] || { iid: '', id: '' };
},
groupPathForActiveIssue: (_, getters) => {
@@ -51,8 +51,4 @@ export default {
isEpicBoard: () => {
return false;
},
-
- shouldUseGraphQL: () => {
- return gon?.features?.graphqlBoardLists;
- },
};
diff --git a/app/assets/javascripts/boards/stores/mutation_types.js b/app/assets/javascripts/boards/stores/mutation_types.js
index 31b78014525..928cece19f7 100644
--- a/app/assets/javascripts/boards/stores/mutation_types.js
+++ b/app/assets/javascripts/boards/stores/mutation_types.js
@@ -41,3 +41,7 @@ export const ADD_LIST_TO_HIGHLIGHTED_LISTS = 'ADD_LIST_TO_HIGHLIGHTED_LISTS';
export const REMOVE_LIST_FROM_HIGHLIGHTED_LISTS = 'REMOVE_LIST_FROM_HIGHLIGHTED_LISTS';
export const RESET_BOARD_ITEM_SELECTION = 'RESET_BOARD_ITEM_SELECTION';
export const SET_ERROR = 'SET_ERROR';
+
+export const RECEIVE_ITERATIONS_REQUEST = 'RECEIVE_ITERATIONS_REQUEST';
+export const RECEIVE_ITERATIONS_SUCCESS = 'RECEIVE_ITERATIONS_SUCCESS';
+export const RECEIVE_ITERATIONS_FAILURE = 'RECEIVE_ITERATIONS_FAILURE';
diff --git a/app/assets/javascripts/boards/stores/mutations.js b/app/assets/javascripts/boards/stores/mutations.js
index 668a3dbaa7e..ef5b84b4575 100644
--- a/app/assets/javascripts/boards/stores/mutations.js
+++ b/app/assets/javascripts/boards/stores/mutations.js
@@ -1,6 +1,5 @@
import { cloneDeep, pull, union } from 'lodash';
import Vue from 'vue';
-import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { s__, __ } from '~/locale';
import { formatIssue } from '../boards_util';
import { issuableTypes } from '../constants';
@@ -65,6 +64,20 @@ export default {
);
},
+ [mutationTypes.RECEIVE_ITERATIONS_REQUEST](state) {
+ state.iterationsLoading = true;
+ },
+
+ [mutationTypes.RECEIVE_ITERATIONS_SUCCESS](state, iterations) {
+ state.iterations = iterations;
+ state.iterationsLoading = false;
+ },
+
+ [mutationTypes.RECEIVE_ITERATIONS_FAILURE](state) {
+ state.iterationsLoading = false;
+ state.error = __('Failed to load iterations.');
+ },
+
[mutationTypes.SET_ACTIVE_ID](state, { id, sidebarType }) {
state.activeId = id;
state.sidebarType = sidebarType;
@@ -187,8 +200,7 @@ export default {
},
[mutationTypes.MUTATE_ISSUE_SUCCESS]: (state, { issue }) => {
- const issueId = getIdFromGraphQLId(issue.id);
- Vue.set(state.boardItems, issueId, formatIssue({ ...issue, id: issueId }));
+ Vue.set(state.boardItems, issue.id, formatIssue(issue));
},
[mutationTypes.ADD_BOARD_ITEM_TO_LIST]: (
diff --git a/app/assets/javascripts/boards/stores/state.js b/app/assets/javascripts/boards/stores/state.js
index 264a03ff39d..80c51c966d2 100644
--- a/app/assets/javascripts/boards/stores/state.js
+++ b/app/assets/javascripts/boards/stores/state.js
@@ -31,6 +31,8 @@ export default () => ({
},
selectedProject: {},
error: undefined,
+ iterations: [],
+ iterationsLoading: false,
addColumnForm: {
visible: false,
columnType: ListType.label,
diff --git a/app/assets/javascripts/captcha/init_recaptcha_script.js b/app/assets/javascripts/captcha/init_recaptcha_script.js
index f546eef7d84..28aef22873d 100644
--- a/app/assets/javascripts/captcha/init_recaptcha_script.js
+++ b/app/assets/javascripts/captcha/init_recaptcha_script.js
@@ -1,7 +1,7 @@
// NOTE: This module will be used in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52044
import { memoize } from 'lodash';
-export const RECAPTCHA_API_URL_PREFIX = 'https://www.google.com/recaptcha/api.js';
+export const RECAPTCHA_API_URL_PREFIX = window.gon.recaptcha_api_server_url;
export const RECAPTCHA_ONLOAD_CALLBACK_NAME = 'recaptchaOnloadCallback';
/**
diff --git a/app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue b/app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue
index 03fd600e493..8e527e2bff6 100644
--- a/app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue
+++ b/app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue
@@ -337,7 +337,7 @@ export default {
</gl-collapse>
<gl-alert
v-if="containsVariableReference"
- :title="__('Value may contain a variable reference')"
+ :title="__('Value might contain a variable reference')"
:dismissible="false"
variant="warning"
data-testid="contains-variable-reference"
diff --git a/app/assets/javascripts/ci_variable_list/constants.js b/app/assets/javascripts/ci_variable_list/constants.js
index f4002537f79..4ebbf05814b 100644
--- a/app/assets/javascripts/ci_variable_list/constants.js
+++ b/app/assets/javascripts/ci_variable_list/constants.js
@@ -26,5 +26,5 @@ export const AWS_SECRET_ACCESS_KEY = 'AWS_SECRET_ACCESS_KEY';
export const AWS_TOKEN_CONSTANTS = [AWS_ACCESS_KEY_ID, AWS_DEFAULT_REGION, AWS_SECRET_ACCESS_KEY];
export const CONTAINS_VARIABLE_REFERENCE_MESSAGE = __(
- 'Variable references indicated by %{codeStart}$%{codeEnd} may be expanded. If this is not what you want, consider %{docsLinkStart}using a workaround to prevent expansion%{docsLinkEnd}.',
+ 'Values that contain the %{codeStart}$%{codeEnd} character can be considered a variable reference and expanded. %{docsLinkStart}Learn more.%{docsLinkEnd}',
);
diff --git a/app/assets/javascripts/clusters/clusters_bundle.js b/app/assets/javascripts/clusters/clusters_bundle.js
index c2c035963f4..8dcab55ac61 100644
--- a/app/assets/javascripts/clusters/clusters_bundle.js
+++ b/app/assets/javascripts/clusters/clusters_bundle.js
@@ -218,14 +218,14 @@ export default class Clusters {
}
setBannerDismissedState(status, isDismissed) {
- if (AccessorUtilities.isLocalStorageAccessSafe()) {
+ if (AccessorUtilities.canUseLocalStorage()) {
window.localStorage.setItem(this.clusterBannerDismissedKey, `${status}_${isDismissed}`);
}
}
isBannerDismissed(status) {
let bannerState;
- if (AccessorUtilities.isLocalStorageAccessSafe()) {
+ if (AccessorUtilities.canUseLocalStorage()) {
bannerState = window.localStorage.getItem(this.clusterBannerDismissedKey);
}
@@ -233,7 +233,7 @@ export default class Clusters {
}
setClusterNewlyCreated(state) {
- if (AccessorUtilities.isLocalStorageAccessSafe()) {
+ if (AccessorUtilities.canUseLocalStorage()) {
window.localStorage.setItem(this.clusterNewlyCreatedKey, Boolean(state));
}
}
@@ -242,7 +242,7 @@ export default class Clusters {
// once this is true, it will always be true for a given page load
if (!this.isNewlyCreated) {
let newlyCreated;
- if (AccessorUtilities.isLocalStorageAccessSafe()) {
+ if (AccessorUtilities.canUseLocalStorage()) {
newlyCreated = window.localStorage.getItem(this.clusterNewlyCreatedKey);
}
diff --git a/app/assets/javascripts/clusters/components/remove_cluster_confirmation.vue b/app/assets/javascripts/clusters/components/remove_cluster_confirmation.vue
index b9c55409330..0da7be4040f 100644
--- a/app/assets/javascripts/clusters/components/remove_cluster_confirmation.vue
+++ b/app/assets/javascripts/clusters/components/remove_cluster_confirmation.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { GlModal, GlButton, GlFormInput } from '@gitlab/ui';
import { escape } from 'lodash';
import csrf from '~/lib/utils/csrf';
@@ -141,7 +140,7 @@ export default {
<!-- eslint-enable @gitlab/vue-require-i18n-strings -->
</ul>
</div>
- <strong v-html="confirmationTextLabel"></strong>
+ <strong v-html="confirmationTextLabel /* eslint-disable-line vue/no-v-html */"></strong>
<form ref="form" :action="clusterPath" method="post" class="gl-mb-5">
<input ref="method" type="hidden" name="_method" value="delete" />
<input :value="csrfToken" type="hidden" name="authenticity_token" />
diff --git a/app/assets/javascripts/clusters_list/components/clusters.vue b/app/assets/javascripts/clusters_list/components/clusters.vue
index 8f81d967126..0d1534d20e0 100644
--- a/app/assets/javascripts/clusters_list/components/clusters.vue
+++ b/app/assets/javascripts/clusters_list/components/clusters.vue
@@ -205,6 +205,8 @@ export default {
:items="clusters"
:fields="fields"
stacked="md"
+ head-variant="white"
+ thead-class="gl-border-b-solid gl-border-b-1 gl-border-b-gray-100"
class="qa-clusters-table"
data-testid="cluster_list_table"
>
diff --git a/app/assets/javascripts/commit/image_file.js b/app/assets/javascripts/commit/image_file.js
index 5f24a3c370a..580db871f5f 100644
--- a/app/assets/javascripts/commit/image_file.js
+++ b/app/assets/javascripts/commit/image_file.js
@@ -1,7 +1,6 @@
/* eslint-disable func-names, consistent-return, one-var, no-return-assign */
import $ from 'jquery';
-import 'jquery.waitforimages';
// Width where images must fits in, for 2-up this gets divided by 2
const availWidth = 900;
@@ -16,11 +15,7 @@ export default class ImageFile {
// Load two-up view after images are loaded
// so that we can display the correct width and height information
- const $images = $('.two-up.view img', this.file);
-
- $images.waitForImages(() => {
- this.initView('two-up');
- });
+ this.initView('two-up');
}),
);
}
diff --git a/app/assets/javascripts/commit/pipelines/pipelines_bundle.js b/app/assets/javascripts/commit/pipelines/pipelines_bundle.js
index 8d88b682df2..2109aecdf03 100644
--- a/app/assets/javascripts/commit/pipelines/pipelines_bundle.js
+++ b/app/assets/javascripts/commit/pipelines/pipelines_bundle.js
@@ -1,4 +1,5 @@
import Vue from 'vue';
+import { initPipelineCountListener } from './utils';
/**
* Used in:
@@ -12,13 +13,7 @@ export default () => {
if (pipelineTableViewEl) {
// Update MR and Commits tabs
- pipelineTableViewEl.addEventListener('update-pipelines-count', (event) => {
- if (event.detail.pipelineCount) {
- const badge = document.querySelector('.js-pipelines-mr-count');
-
- badge.textContent = event.detail.pipelineCount;
- }
- });
+ initPipelineCountListener(pipelineTableViewEl);
if (pipelineTableViewEl.dataset.disableInitialization === undefined) {
const table = new Vue({
diff --git a/app/assets/javascripts/commit/pipelines/utils.js b/app/assets/javascripts/commit/pipelines/utils.js
new file mode 100644
index 00000000000..52cbe52fa9b
--- /dev/null
+++ b/app/assets/javascripts/commit/pipelines/utils.js
@@ -0,0 +1,11 @@
+export function initPipelineCountListener(el) {
+ if (!el) return;
+
+ el.addEventListener('update-pipelines-count', (event) => {
+ if (event.detail.pipelineCount) {
+ const badge = document.querySelector('.js-pipelines-mr-count');
+
+ badge.textContent = event.detail.pipelineCount;
+ }
+ });
+}
diff --git a/app/assets/javascripts/confidential_merge_request/components/project_form_group.vue b/app/assets/javascripts/confidential_merge_request/components/project_form_group.vue
index 5f778af1dbb..59066162960 100644
--- a/app/assets/javascripts/confidential_merge_request/components/project_form_group.vue
+++ b/app/assets/javascripts/confidential_merge_request/components/project_form_group.vue
@@ -96,12 +96,23 @@ export default {
}
},
},
+ i18n: {
+ project: __('Project'),
+ privateForkSelected: __(
+ "To protect this issue's confidentiality, a private fork of this project was selected.",
+ ),
+ noForks: __('No forks are available to you.'),
+ forkTheProject: __(
+ `To protect this issue's confidentiality, %{linkStart}fork this project%{linkEnd} and set the fork's visibility to private.`,
+ ),
+ readMore: __('Read more'),
+ },
};
</script>
<template>
<div class="confidential-merge-request-fork-group form-group">
- <label>{{ __('Project') }}</label>
+ <label>{{ $options.i18n.project }}</label>
<div>
<dropdown
v-if="projects.length"
@@ -111,25 +122,13 @@ export default {
/>
<p class="text-muted mt-1 mb-0">
<template v-if="projects.length">
- {{
- __(
- "To protect this issue's confidentiality, a private fork of this project was selected.",
- )
- }}
+ {{ $options.i18n.privateForkSelected }}
</template>
<template v-else>
- {{ __('No forks are available to you.') }}<br />
- <gl-sprintf
- :message="
- __(
- `To protect this issue's confidentiality, %{forkLink} and set the fork's visibility to private.`,
- )
- "
- >
- <template #forkLink>
- <a :href="newForkPath" target="_blank" class="help-link">{{
- __('fork this project')
- }}</a>
+ {{ $options.i18n.noForks }}<br />
+ <gl-sprintf :message="$options.i18n.forkTheProject">
+ <template #link="{ content }">
+ <a :href="newForkPath" target="_blank" class="help-link">{{ content }}</a>
</template>
</gl-sprintf>
</template>
@@ -138,7 +137,7 @@ export default {
class="w-auto p-0 d-inline-block text-primary bg-transparent"
target="_blank"
>
- <span class="sr-only">{{ __('Read more') }}</span>
+ <span class="sr-only">{{ $options.i18n.readMore }}</span>
<gl-icon name="question-o" />
</gl-link>
</p>
diff --git a/app/assets/javascripts/content_editor/components/content_editor.vue b/app/assets/javascripts/content_editor/components/content_editor.vue
index a372233e543..02ab34447ca 100644
--- a/app/assets/javascripts/content_editor/components/content_editor.vue
+++ b/app/assets/javascripts/content_editor/components/content_editor.vue
@@ -100,11 +100,13 @@ export default {
:class="{ 'is-focused': focused }"
>
<top-toolbar ref="toolbar" class="gl-mb-4" />
- <formatting-bubble-menu />
<div v-if="isLoadingContent" class="gl-w-full gl-display-flex gl-justify-content-center">
<gl-loading-icon size="sm" />
</div>
- <tiptap-editor-content v-else class="md" :editor="contentEditor.tiptapEditor" />
+ <template v-else>
+ <formatting-bubble-menu />
+ <tiptap-editor-content class="md" :editor="contentEditor.tiptapEditor" />
+ </template>
</div>
</div>
</content-editor-provider>
diff --git a/app/assets/javascripts/content_editor/components/formatting_bubble_menu.vue b/app/assets/javascripts/content_editor/components/formatting_bubble_menu.vue
index 6c00480b87e..14a553ff30b 100644
--- a/app/assets/javascripts/content_editor/components/formatting_bubble_menu.vue
+++ b/app/assets/javascripts/content_editor/components/formatting_bubble_menu.vue
@@ -20,7 +20,11 @@ export default {
};
</script>
<template>
- <bubble-menu class="gl-shadow gl-rounded-base" :editor="tiptapEditor">
+ <bubble-menu
+ data-testid="formatting-bubble-menu"
+ class="gl-shadow gl-rounded-base"
+ :editor="tiptapEditor"
+ >
<gl-button-group>
<toolbar-button
data-testid="bold"
diff --git a/app/assets/javascripts/content_editor/components/wrappers/image.vue b/app/assets/javascripts/content_editor/components/wrappers/image.vue
index 3762324a431..5b81e5fddcc 100644
--- a/app/assets/javascripts/content_editor/components/wrappers/image.vue
+++ b/app/assets/javascripts/content_editor/components/wrappers/image.vue
@@ -22,6 +22,7 @@ export default {
<img
data-testid="image"
class="gl-max-w-full gl-h-auto"
+ :title="node.attrs.title"
:class="{ 'gl-opacity-5': node.attrs.uploading }"
:src="node.attrs.src"
/>
diff --git a/app/assets/javascripts/content_editor/components/wrappers/table_cell_base.vue b/app/assets/javascripts/content_editor/components/wrappers/table_cell_base.vue
new file mode 100644
index 00000000000..c44e8145982
--- /dev/null
+++ b/app/assets/javascripts/content_editor/components/wrappers/table_cell_base.vue
@@ -0,0 +1,142 @@
+<script>
+import { GlDropdown, GlDropdownItem, GlDropdownDivider } from '@gitlab/ui';
+import { NodeViewWrapper, NodeViewContent } from '@tiptap/vue-2';
+import { selectedRect as getSelectedRect } from 'prosemirror-tables';
+import { __ } from '~/locale';
+
+const TABLE_CELL_HEADER = 'th';
+const TABLE_CELL_BODY = 'td';
+
+export default {
+ name: 'TableCellBaseWrapper',
+ components: {
+ NodeViewWrapper,
+ NodeViewContent,
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownDivider,
+ },
+ props: {
+ cellType: {
+ type: String,
+ validator: (type) => [TABLE_CELL_HEADER, TABLE_CELL_BODY].includes(type),
+ required: true,
+ },
+ editor: {
+ type: Object,
+ required: true,
+ },
+ getPos: {
+ type: Function,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ displayActionsDropdown: false,
+ preventHide: true,
+ selectedRect: null,
+ };
+ },
+ computed: {
+ totalRows() {
+ return this.selectedRect?.map.height;
+ },
+ totalCols() {
+ return this.selectedRect?.map.width;
+ },
+ isTableBodyCell() {
+ return this.cellType === TABLE_CELL_BODY;
+ },
+ },
+ mounted() {
+ this.editor.on('selectionUpdate', this.handleSelectionUpdate);
+ this.handleSelectionUpdate();
+ },
+ beforeDestroy() {
+ this.editor.off('selectionUpdate', this.handleSelectionUpdate);
+ },
+ methods: {
+ handleSelectionUpdate() {
+ const { state } = this.editor;
+ const { $cursor } = state.selection;
+
+ this.displayActionsDropdown = $cursor?.pos - $cursor?.parentOffset - 1 === this.getPos();
+ if (this.displayActionsDropdown) {
+ this.selectedRect = getSelectedRect(state);
+ }
+ },
+ runCommand(command) {
+ this.editor.chain()[command]().run();
+ this.hideDropdown();
+ },
+ handleHide($event) {
+ if (this.preventHide) {
+ $event.preventDefault();
+ }
+ this.preventHide = true;
+ },
+ hideDropdown() {
+ this.preventHide = false;
+ this.$refs.dropdown?.hide();
+ },
+ },
+ i18n: {
+ insertColumnBefore: __('Insert column before'),
+ insertColumnAfter: __('Insert column after'),
+ insertRowBefore: __('Insert row before'),
+ insertRowAfter: __('Insert row after'),
+ deleteRow: __('Delete row'),
+ deleteColumn: __('Delete column'),
+ deleteTable: __('Delete table'),
+ editTableActions: __('Edit table'),
+ },
+};
+</script>
+<template>
+ <node-view-wrapper
+ class="gl-relative gl-padding-5 gl-min-w-10"
+ :as="cellType"
+ @click="hideDropdown"
+ >
+ <span v-if="displayActionsDropdown" class="gl-absolute gl-right-0 gl-top-0">
+ <gl-dropdown
+ ref="dropdown"
+ dropup
+ icon="chevron-down"
+ size="small"
+ category="tertiary"
+ boundary="viewport"
+ no-caret
+ text-sr-only
+ :text="$options.i18n.editTableActions"
+ :popper-opts="{ positionFixed: true }"
+ @hide="handleHide($event)"
+ >
+ <gl-dropdown-item @click="runCommand('addColumnBefore')">
+ {{ $options.i18n.insertColumnBefore }}
+ </gl-dropdown-item>
+ <gl-dropdown-item @click="runCommand('addColumnAfter')">
+ {{ $options.i18n.insertColumnAfter }}
+ </gl-dropdown-item>
+ <gl-dropdown-item v-if="isTableBodyCell" @click="runCommand('addRowBefore')">
+ {{ $options.i18n.insertRowBefore }}
+ </gl-dropdown-item>
+ <gl-dropdown-item @click="runCommand('addRowAfter')">
+ {{ $options.i18n.insertRowAfter }}
+ </gl-dropdown-item>
+ <gl-dropdown-divider />
+ <gl-dropdown-item v-if="totalRows > 2 && isTableBodyCell" @click="runCommand('deleteRow')">
+ {{ $options.i18n.deleteRow }}
+ </gl-dropdown-item>
+ <gl-dropdown-item v-if="totalCols > 1" @click="runCommand('deleteColumn')">
+ {{ $options.i18n.deleteColumn }}
+ </gl-dropdown-item>
+ <gl-dropdown-item @click="runCommand('deleteTable')">
+ {{ $options.i18n.deleteTable }}
+ </gl-dropdown-item>
+ </gl-dropdown>
+ </span>
+ <node-view-content />
+ </node-view-wrapper>
+</template>
diff --git a/app/assets/javascripts/content_editor/components/wrappers/table_cell_body.vue b/app/assets/javascripts/content_editor/components/wrappers/table_cell_body.vue
new file mode 100644
index 00000000000..6b4343dd5b8
--- /dev/null
+++ b/app/assets/javascripts/content_editor/components/wrappers/table_cell_body.vue
@@ -0,0 +1,23 @@
+<script>
+import TableCellBase from './table_cell_base.vue';
+
+export default {
+ name: 'TableCellBody',
+ components: {
+ TableCellBase,
+ },
+ props: {
+ editor: {
+ type: Object,
+ required: true,
+ },
+ getPos: {
+ type: Function,
+ required: true,
+ },
+ },
+};
+</script>
+<template>
+ <table-cell-base cell-type="td" v-bind="$props" />
+</template>
diff --git a/app/assets/javascripts/content_editor/components/wrappers/table_cell_header.vue b/app/assets/javascripts/content_editor/components/wrappers/table_cell_header.vue
new file mode 100644
index 00000000000..5f9889374f6
--- /dev/null
+++ b/app/assets/javascripts/content_editor/components/wrappers/table_cell_header.vue
@@ -0,0 +1,23 @@
+<script>
+import TableCellBase from './table_cell_base.vue';
+
+export default {
+ name: 'TableCellHeader',
+ components: {
+ TableCellBase,
+ },
+ props: {
+ editor: {
+ type: Object,
+ required: true,
+ },
+ getPos: {
+ type: Function,
+ required: true,
+ },
+ },
+};
+</script>
+<template>
+ <table-cell-base cell-type="th" v-bind="$props" />
+</template>
diff --git a/app/assets/javascripts/content_editor/constants.js b/app/assets/javascripts/content_editor/constants.js
index f277508f628..4af9dc8e405 100644
--- a/app/assets/javascripts/content_editor/constants.js
+++ b/app/assets/javascripts/content_editor/constants.js
@@ -45,3 +45,7 @@ export const TEXT_STYLE_DROPDOWN_ITEMS = [
export const LOADING_CONTENT_EVENT = 'loadingContent';
export const LOADING_SUCCESS_EVENT = 'loadingSuccess';
export const LOADING_ERROR_EVENT = 'loadingError';
+
+export const PARSE_HTML_PRIORITY_LOWEST = 1;
+export const PARSE_HTML_PRIORITY_DEFAULT = 50;
+export const PARSE_HTML_PRIORITY_HIGHEST = 100;
diff --git a/app/assets/javascripts/content_editor/content_editor.stories.js b/app/assets/javascripts/content_editor/content_editor.stories.js
new file mode 100644
index 00000000000..8f2ce8feb5d
--- /dev/null
+++ b/app/assets/javascripts/content_editor/content_editor.stories.js
@@ -0,0 +1,27 @@
+import { ContentEditor } from './index';
+
+export default {
+ component: ContentEditor,
+ title: 'Components/Content Editor',
+};
+
+const Template = (_, { argTypes }) => ({
+ components: { ContentEditor },
+ props: Object.keys(argTypes),
+ template: '<content-editor v-bind="$props" @initialized="loadContent" />',
+ methods: {
+ loadContent(contentEditor) {
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ contentEditor.setSerializedContent('Hello content editor');
+ },
+ },
+});
+
+export const Default = Template.bind({});
+
+Default.args = {
+ renderMarkdown: () => '<p>Hello content editor</p>',
+ uploadsPath: '/uploads/',
+ serializerConfig: {},
+ extensions: [],
+};
diff --git a/app/assets/javascripts/content_editor/extensions/audio.js b/app/assets/javascripts/content_editor/extensions/audio.js
new file mode 100644
index 00000000000..25d4068c93f
--- /dev/null
+++ b/app/assets/javascripts/content_editor/extensions/audio.js
@@ -0,0 +1,9 @@
+import Playable from './playable';
+
+export default Playable.extend({
+ name: 'audio',
+ defaultOptions: {
+ ...Playable.options,
+ mediaType: 'audio',
+ },
+});
diff --git a/app/assets/javascripts/content_editor/extensions/blockquote.js b/app/assets/javascripts/content_editor/extensions/blockquote.js
index 45f53fe230b..4512ead44bc 100644
--- a/app/assets/javascripts/content_editor/extensions/blockquote.js
+++ b/app/assets/javascripts/content_editor/extensions/blockquote.js
@@ -1 +1,33 @@
-export { Blockquote as default } from '@tiptap/extension-blockquote';
+import { Blockquote } from '@tiptap/extension-blockquote';
+import { wrappingInputRule } from 'prosemirror-inputrules';
+import { getParents } from '~/lib/utils/dom_utils';
+import { getMarkdownSource } from '../services/markdown_sourcemap';
+
+export const multilineInputRegex = /^\s*>>>\s$/gm;
+
+export default Blockquote.extend({
+ addAttributes() {
+ return {
+ ...this.parent?.(),
+
+ multiline: {
+ default: false,
+ parseHTML: (element) => {
+ const source = getMarkdownSource(element);
+ const parentsIncludeBlockquote = getParents(element).some(
+ (p) => p.nodeName.toLowerCase() === 'blockquote',
+ );
+
+ return source && !source.startsWith('>') && !parentsIncludeBlockquote;
+ },
+ },
+ };
+ },
+
+ addInputRules() {
+ return [
+ ...this.parent?.(),
+ wrappingInputRule(multilineInputRegex, this.type, () => ({ multiline: true })),
+ ];
+ },
+});
diff --git a/app/assets/javascripts/content_editor/extensions/bullet_list.js b/app/assets/javascripts/content_editor/extensions/bullet_list.js
index 01ead571fe1..8d0faf7a9fe 100644
--- a/app/assets/javascripts/content_editor/extensions/bullet_list.js
+++ b/app/assets/javascripts/content_editor/extensions/bullet_list.js
@@ -1 +1,19 @@
-export { BulletList as default } from '@tiptap/extension-bullet-list';
+import { BulletList } from '@tiptap/extension-bullet-list';
+import { getMarkdownSource } from '../services/markdown_sourcemap';
+
+export default BulletList.extend({
+ addAttributes() {
+ return {
+ ...this.parent?.(),
+
+ bullet: {
+ default: '*',
+ parseHTML(element) {
+ const bullet = getMarkdownSource(element)?.charAt(0);
+
+ return '*+-'.includes(bullet) ? bullet : '*';
+ },
+ },
+ };
+ },
+});
diff --git a/app/assets/javascripts/content_editor/extensions/code_block_highlight.js b/app/assets/javascripts/content_editor/extensions/code_block_highlight.js
index c6d32fb8547..25f5837d2a6 100644
--- a/app/assets/javascripts/content_editor/extensions/code_block_highlight.js
+++ b/app/assets/javascripts/content_editor/extensions/code_block_highlight.js
@@ -8,11 +8,7 @@ export default CodeBlockLowlight.extend({
return {
language: {
default: null,
- parseHTML: (element) => {
- return {
- language: extractLanguage(element),
- };
- },
+ parseHTML: (element) => extractLanguage(element),
},
class: {
default: 'code highlight js-syntax-highlight',
diff --git a/app/assets/javascripts/content_editor/extensions/description_item.js b/app/assets/javascripts/content_editor/extensions/description_item.js
new file mode 100644
index 00000000000..957fdede27b
--- /dev/null
+++ b/app/assets/javascripts/content_editor/extensions/description_item.js
@@ -0,0 +1,49 @@
+import { Node, mergeAttributes } from '@tiptap/core';
+
+export default Node.create({
+ name: 'descriptionItem',
+ content: 'block+',
+ defining: true,
+
+ addAttributes() {
+ return {
+ isTerm: {
+ default: true,
+ parseHTML: (element) => element.tagName.toLowerCase() === 'dt',
+ },
+ };
+ },
+
+ parseHTML() {
+ return [{ tag: 'dt' }, { tag: 'dd' }];
+ },
+
+ renderHTML({ HTMLAttributes: { isTerm, ...HTMLAttributes } }) {
+ return [
+ 'li',
+ mergeAttributes(HTMLAttributes, { class: isTerm ? 'dl-term' : 'dl-description' }),
+ 0,
+ ];
+ },
+
+ addKeyboardShortcuts() {
+ return {
+ Enter: () => {
+ return this.editor.commands.splitListItem('descriptionItem');
+ },
+ Tab: () => {
+ const { isTerm } = this.editor.getAttributes('descriptionItem');
+ if (isTerm)
+ return this.editor.commands.updateAttributes('descriptionItem', { isTerm: !isTerm });
+
+ return false;
+ },
+ 'Shift-Tab': () => {
+ const { isTerm } = this.editor.getAttributes('descriptionItem');
+ if (isTerm) return this.editor.commands.liftListItem('descriptionItem');
+
+ return this.editor.commands.updateAttributes('descriptionItem', { isTerm: true });
+ },
+ };
+ },
+});
diff --git a/app/assets/javascripts/content_editor/extensions/description_list.js b/app/assets/javascripts/content_editor/extensions/description_list.js
new file mode 100644
index 00000000000..a516dfad2b8
--- /dev/null
+++ b/app/assets/javascripts/content_editor/extensions/description_list.js
@@ -0,0 +1,23 @@
+import { Node, mergeAttributes } from '@tiptap/core';
+import { wrappingInputRule } from 'prosemirror-inputrules';
+
+export const inputRegex = /^\s*(<dl>)$/;
+
+export default Node.create({
+ name: 'descriptionList',
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ group: 'block list',
+ content: 'descriptionItem+',
+
+ parseHTML() {
+ return [{ tag: 'dl' }];
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ return ['ul', mergeAttributes(HTMLAttributes, { class: 'dl-content' }), 0];
+ },
+
+ addInputRules() {
+ return [wrappingInputRule(inputRegex, this.type)];
+ },
+});
diff --git a/app/assets/javascripts/content_editor/extensions/division.js b/app/assets/javascripts/content_editor/extensions/division.js
new file mode 100644
index 00000000000..c70d1700941
--- /dev/null
+++ b/app/assets/javascripts/content_editor/extensions/division.js
@@ -0,0 +1,17 @@
+import { Node } from '@tiptap/core';
+import { PARSE_HTML_PRIORITY_LOWEST } from '../constants';
+
+export default Node.create({
+ name: 'division',
+ content: 'block*',
+ group: 'block',
+ defining: true,
+
+ parseHTML() {
+ return [{ tag: 'div', priority: PARSE_HTML_PRIORITY_LOWEST }];
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ return ['div', HTMLAttributes, 0];
+ },
+});
diff --git a/app/assets/javascripts/content_editor/extensions/emoji.js b/app/assets/javascripts/content_editor/extensions/emoji.js
index d88b9f92215..de608c3aaa2 100644
--- a/app/assets/javascripts/content_editor/extensions/emoji.js
+++ b/app/assets/javascripts/content_editor/extensions/emoji.js
@@ -17,30 +17,18 @@ export default Node.create({
return {
moji: {
default: null,
- parseHTML: (element) => {
- return {
- moji: element.textContent,
- };
- },
+ parseHTML: (element) => element.textContent,
},
name: {
default: null,
- parseHTML: (element) => {
- return {
- name: element.dataset.name,
- };
- },
+ parseHTML: (element) => element.dataset.name,
},
title: {
default: null,
},
unicodeVersion: {
default: '6.0',
- parseHTML: (element) => {
- return {
- unicodeVersion: element.dataset.unicodeVersion,
- };
- },
+ parseHTML: (element) => element.dataset.unicodeVersion,
},
};
},
diff --git a/app/assets/javascripts/content_editor/extensions/figure.js b/app/assets/javascripts/content_editor/extensions/figure.js
new file mode 100644
index 00000000000..b2076894412
--- /dev/null
+++ b/app/assets/javascripts/content_editor/extensions/figure.js
@@ -0,0 +1,16 @@
+import { Node } from '@tiptap/core';
+
+export default Node.create({
+ name: 'figure',
+ content: 'block+',
+ group: 'block',
+ defining: true,
+
+ parseHTML() {
+ return [{ tag: 'figure' }];
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ return ['figure', HTMLAttributes, 0];
+ },
+});
diff --git a/app/assets/javascripts/content_editor/extensions/figure_caption.js b/app/assets/javascripts/content_editor/extensions/figure_caption.js
new file mode 100644
index 00000000000..ffd1b474f03
--- /dev/null
+++ b/app/assets/javascripts/content_editor/extensions/figure_caption.js
@@ -0,0 +1,16 @@
+import { Node } from '@tiptap/core';
+
+export default Node.create({
+ name: 'figureCaption',
+ content: 'inline*',
+ group: 'block',
+ defining: true,
+
+ parseHTML() {
+ return [{ tag: 'figcaption' }];
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ return ['figcaption', HTMLAttributes, 0];
+ },
+});
diff --git a/app/assets/javascripts/content_editor/extensions/html_marks.js b/app/assets/javascripts/content_editor/extensions/html_marks.js
new file mode 100644
index 00000000000..54adb9efa0c
--- /dev/null
+++ b/app/assets/javascripts/content_editor/extensions/html_marks.js
@@ -0,0 +1,66 @@
+import { Mark, mergeAttributes, markInputRule } from '@tiptap/core';
+import { PARSE_HTML_PRIORITY_LOWEST } from '../constants';
+import { markInputRegex, extractMarkAttributesFromMatch } from '../services/mark_utils';
+
+const marks = [
+ 'ins',
+ 'abbr',
+ 'bdo',
+ 'cite',
+ 'dfn',
+ 'mark',
+ 'small',
+ 'span',
+ 'time',
+ 'kbd',
+ 'q',
+ 'samp',
+ 'var',
+ 'ruby',
+ 'rp',
+ 'rt',
+];
+
+const attrs = {
+ time: ['datetime'],
+ abbr: ['title'],
+ span: ['dir'],
+ bdo: ['dir'],
+};
+
+export default marks.map((name) =>
+ Mark.create({
+ name,
+
+ inclusive: false,
+
+ defaultOptions: {
+ HTMLAttributes: {},
+ },
+
+ addAttributes() {
+ return (attrs[name] || []).reduce(
+ (acc, attr) => ({
+ ...acc,
+ [attr]: {
+ default: null,
+ parseHTML: (element) => element.getAttribute(attr),
+ },
+ }),
+ {},
+ );
+ },
+
+ parseHTML() {
+ return [{ tag: name, priority: PARSE_HTML_PRIORITY_LOWEST }];
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ return [name, mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
+ },
+
+ addInputRules() {
+ return [markInputRule(markInputRegex(name), this.type, extractMarkAttributesFromMatch)];
+ },
+ }),
+);
diff --git a/app/assets/javascripts/content_editor/extensions/image.js b/app/assets/javascripts/content_editor/extensions/image.js
index c9e8dfa4ad9..837fab0585f 100644
--- a/app/assets/javascripts/content_editor/extensions/image.js
+++ b/app/assets/javascripts/content_editor/extensions/image.js
@@ -1,6 +1,7 @@
import { Image } from '@tiptap/extension-image';
import { VueNodeViewRenderer } from '@tiptap/vue-2';
import ImageWrapper from '../components/wrappers/image.vue';
+import { PARSE_HTML_PRIORITY_HIGHEST } from '../constants';
const resolveImageEl = (element) =>
element.nodeName === 'IMG' ? element : element.querySelector('img');
@@ -27,27 +28,27 @@ export default Image.extend({
parseHTML: (element) => {
const img = resolveImageEl(element);
- return {
- src: img.dataset.src || img.getAttribute('src'),
- };
+ return img.dataset.src || img.getAttribute('src');
},
},
canonicalSrc: {
default: null,
+ parseHTML: (element) => element.dataset.canonicalSrc,
+ },
+ alt: {
+ default: null,
parseHTML: (element) => {
- return {
- canonicalSrc: element.dataset.canonicalSrc,
- };
+ const img = resolveImageEl(element);
+
+ return img.getAttribute('alt');
},
},
- alt: {
+ title: {
default: null,
parseHTML: (element) => {
const img = resolveImageEl(element);
- return {
- alt: img.getAttribute('alt'),
- };
+ return img.getAttribute('title');
},
},
};
@@ -55,7 +56,7 @@ export default Image.extend({
parseHTML() {
return [
{
- priority: 100,
+ priority: PARSE_HTML_PRIORITY_HIGHEST,
tag: 'a.no-attachment-icon',
},
{
diff --git a/app/assets/javascripts/content_editor/extensions/inline_diff.js b/app/assets/javascripts/content_editor/extensions/inline_diff.js
index 9471d324764..3bd328958df 100644
--- a/app/assets/javascripts/content_editor/extensions/inline_diff.js
+++ b/app/assets/javascripts/content_editor/extensions/inline_diff.js
@@ -14,11 +14,7 @@ export default Mark.create({
return {
type: {
default: 'addition',
- parseHTML: (element) => {
- return {
- type: element.classList.contains('deletion') ? 'deletion' : 'addition',
- };
- },
+ parseHTML: (element) => (element.classList.contains('deletion') ? 'deletion' : 'addition'),
},
};
},
diff --git a/app/assets/javascripts/content_editor/extensions/link.js b/app/assets/javascripts/content_editor/extensions/link.js
index 53104fe07a3..fc0f38e6935 100644
--- a/app/assets/javascripts/content_editor/extensions/link.js
+++ b/app/assets/javascripts/content_editor/extensions/link.js
@@ -36,19 +36,15 @@ export default Link.extend({
...this.parent?.(),
href: {
default: null,
- parseHTML: (element) => {
- return {
- href: element.getAttribute('href'),
- };
- },
+ parseHTML: (element) => element.getAttribute('href'),
+ },
+ title: {
+ title: null,
+ parseHTML: (element) => element.getAttribute('title'),
},
canonicalSrc: {
default: null,
- parseHTML: (element) => {
- return {
- canonicalSrc: element.dataset.canonicalSrc,
- };
- },
+ parseHTML: (element) => element.dataset.canonicalSrc,
},
};
},
diff --git a/app/assets/javascripts/content_editor/extensions/ordered_list.js b/app/assets/javascripts/content_editor/extensions/ordered_list.js
index 9a79187d9c1..57d5bd6ebf8 100644
--- a/app/assets/javascripts/content_editor/extensions/ordered_list.js
+++ b/app/assets/javascripts/content_editor/extensions/ordered_list.js
@@ -1 +1,15 @@
-export { OrderedList as default } from '@tiptap/extension-ordered-list';
+import { OrderedList } from '@tiptap/extension-ordered-list';
+import { getMarkdownSource } from '../services/markdown_sourcemap';
+
+export default OrderedList.extend({
+ addAttributes() {
+ return {
+ ...this.parent?.(),
+
+ parens: {
+ default: false,
+ parseHTML: (element) => /^[0-9]+\)/.test(getMarkdownSource(element)),
+ },
+ };
+ },
+});
diff --git a/app/assets/javascripts/content_editor/extensions/playable.js b/app/assets/javascripts/content_editor/extensions/playable.js
new file mode 100644
index 00000000000..0062bc563db
--- /dev/null
+++ b/app/assets/javascripts/content_editor/extensions/playable.js
@@ -0,0 +1,66 @@
+/* eslint-disable @gitlab/require-i18n-strings */
+
+import { Node } from '@tiptap/core';
+
+const queryPlayableElement = (element, mediaType) => element.querySelector(mediaType);
+
+export default Node.create({
+ group: 'inline',
+ inline: true,
+ draggable: true,
+
+ addAttributes() {
+ return {
+ src: {
+ default: null,
+ parseHTML: (element) => {
+ const playable = queryPlayableElement(element, this.options.mediaType);
+
+ return playable.src;
+ },
+ },
+ canonicalSrc: {
+ default: null,
+ parseHTML: (element) => {
+ const playable = queryPlayableElement(element, this.options.mediaType);
+
+ return playable.dataset.canonicalSrc;
+ },
+ },
+ alt: {
+ default: null,
+ parseHTML: (element) => {
+ const playable = queryPlayableElement(element, this.options.mediaType);
+
+ return playable.dataset.title;
+ },
+ },
+ };
+ },
+
+ parseHTML() {
+ return [
+ {
+ tag: `.${this.options.mediaType}-container`,
+ },
+ ];
+ },
+
+ renderHTML({ node }) {
+ return [
+ 'span',
+ { class: `media-container ${this.options.mediaType}-container` },
+ [
+ this.options.mediaType,
+ {
+ src: node.attrs.src,
+ controls: true,
+ 'data-setup': '{}',
+ 'data-title': node.attrs.alt,
+ ...this.extraElementAttrs,
+ },
+ ],
+ ['a', { href: node.attrs.src }, node.attrs.alt],
+ ];
+ },
+});
diff --git a/app/assets/javascripts/content_editor/extensions/reference.js b/app/assets/javascripts/content_editor/extensions/reference.js
index 5f4484af9c8..5e459e65de2 100644
--- a/app/assets/javascripts/content_editor/extensions/reference.js
+++ b/app/assets/javascripts/content_editor/extensions/reference.js
@@ -1,4 +1,10 @@
import { Node } from '@tiptap/core';
+import { PARSE_HTML_PRIORITY_HIGHEST } from '../constants';
+
+const getAnchor = (element) => {
+ if (element.nodeName === 'A') return element;
+ return element.querySelector('a');
+};
export default Node.create({
name: 'reference',
@@ -13,43 +19,23 @@ export default Node.create({
return {
className: {
default: null,
- parseHTML: (element) => {
- return {
- className: element.className,
- };
- },
+ parseHTML: (element) => getAnchor(element).className,
},
referenceType: {
default: null,
- parseHTML: (element) => {
- return {
- referenceType: element.dataset.referenceType,
- };
- },
+ parseHTML: (element) => getAnchor(element).dataset.referenceType,
},
originalText: {
default: null,
- parseHTML: (element) => {
- return {
- originalText: element.dataset.original,
- };
- },
+ parseHTML: (element) => getAnchor(element).dataset.original,
},
href: {
default: null,
- parseHTML: (element) => {
- return {
- href: element.getAttribute('href'),
- };
- },
+ parseHTML: (element) => getAnchor(element).getAttribute('href'),
},
text: {
default: null,
- parseHTML: (element) => {
- return {
- text: element.textContent,
- };
- },
+ parseHTML: (element) => getAnchor(element).textContent,
},
};
},
@@ -58,7 +44,10 @@ export default Node.create({
return [
{
tag: 'a.gfm:not([data-link=true])',
- priority: 51,
+ priority: PARSE_HTML_PRIORITY_HIGHEST,
+ },
+ {
+ tag: 'span.gl-label',
},
];
},
diff --git a/app/assets/javascripts/content_editor/extensions/subscript.js b/app/assets/javascripts/content_editor/extensions/subscript.js
index 4bf89796efe..d0766f42308 100644
--- a/app/assets/javascripts/content_editor/extensions/subscript.js
+++ b/app/assets/javascripts/content_editor/extensions/subscript.js
@@ -1 +1,9 @@
-export { Subscript as default } from '@tiptap/extension-subscript';
+import { markInputRule } from '@tiptap/core';
+import { Subscript } from '@tiptap/extension-subscript';
+import { markInputRegex, extractMarkAttributesFromMatch } from '../services/mark_utils';
+
+export default Subscript.extend({
+ addInputRules() {
+ return [markInputRule(markInputRegex('sub'), this.type, extractMarkAttributesFromMatch)];
+ },
+});
diff --git a/app/assets/javascripts/content_editor/extensions/superscript.js b/app/assets/javascripts/content_editor/extensions/superscript.js
index 3eb7d86d90d..6cd814977ea 100644
--- a/app/assets/javascripts/content_editor/extensions/superscript.js
+++ b/app/assets/javascripts/content_editor/extensions/superscript.js
@@ -1 +1,9 @@
-export { Superscript as default } from '@tiptap/extension-superscript';
+import { markInputRule } from '@tiptap/core';
+import { Superscript } from '@tiptap/extension-superscript';
+import { markInputRegex, extractMarkAttributesFromMatch } from '../services/mark_utils';
+
+export default Superscript.extend({
+ addInputRules() {
+ return [markInputRule(markInputRegex('sup'), this.type, extractMarkAttributesFromMatch)];
+ },
+});
diff --git a/app/assets/javascripts/content_editor/extensions/table_cell.js b/app/assets/javascripts/content_editor/extensions/table_cell.js
index 5bdc39231a1..befc33e669f 100644
--- a/app/assets/javascripts/content_editor/extensions/table_cell.js
+++ b/app/assets/javascripts/content_editor/extensions/table_cell.js
@@ -1,5 +1,12 @@
import { TableCell } from '@tiptap/extension-table-cell';
+import { VueNodeViewRenderer } from '@tiptap/vue-2';
+import TableCellBodyWrapper from '../components/wrappers/table_cell_body.vue';
+import { isBlockTablesFeatureEnabled } from '../services/feature_flags';
export default TableCell.extend({
- content: 'inline*',
+ content: isBlockTablesFeatureEnabled() ? 'block+' : 'inline*',
+
+ addNodeView() {
+ return VueNodeViewRenderer(TableCellBodyWrapper);
+ },
});
diff --git a/app/assets/javascripts/content_editor/extensions/table_header.js b/app/assets/javascripts/content_editor/extensions/table_header.js
index 23509706e4b..829b06fc14b 100644
--- a/app/assets/javascripts/content_editor/extensions/table_header.js
+++ b/app/assets/javascripts/content_editor/extensions/table_header.js
@@ -1,5 +1,11 @@
import { TableHeader } from '@tiptap/extension-table-header';
+import { VueNodeViewRenderer } from '@tiptap/vue-2';
+import TableCellHeaderWrapper from '../components/wrappers/table_cell_header.vue';
+import { isBlockTablesFeatureEnabled } from '../services/feature_flags';
export default TableHeader.extend({
- content: 'inline*',
+ content: isBlockTablesFeatureEnabled() ? 'block+' : 'inline*',
+ addNodeView() {
+ return VueNodeViewRenderer(TableCellHeaderWrapper);
+ },
});
diff --git a/app/assets/javascripts/content_editor/extensions/task_item.js b/app/assets/javascripts/content_editor/extensions/task_item.js
index 6163c0e043b..9b050edcb28 100644
--- a/app/assets/javascripts/content_editor/extensions/task_item.js
+++ b/app/assets/javascripts/content_editor/extensions/task_item.js
@@ -1,4 +1,5 @@
import { TaskItem } from '@tiptap/extension-task-item';
+import { PARSE_HTML_PRIORITY_HIGHEST } from '../constants';
export default TaskItem.extend({
defaultOptions: {
@@ -12,7 +13,8 @@ export default TaskItem.extend({
default: false,
parseHTML: (element) => {
const checkbox = element.querySelector('input[type=checkbox].task-list-item-checkbox');
- return { checked: checkbox?.checked };
+
+ return checkbox?.checked;
},
renderHTML: (attributes) => ({
'data-checked': attributes.checked,
@@ -26,7 +28,7 @@ export default TaskItem.extend({
return [
{
tag: 'li.task-list-item',
- priority: 100,
+ priority: PARSE_HTML_PRIORITY_HIGHEST,
},
];
},
diff --git a/app/assets/javascripts/content_editor/extensions/task_list.js b/app/assets/javascripts/content_editor/extensions/task_list.js
index b7f6c857bc7..72c6e020102 100644
--- a/app/assets/javascripts/content_editor/extensions/task_list.js
+++ b/app/assets/javascripts/content_editor/extensions/task_list.js
@@ -1,16 +1,24 @@
import { mergeAttributes } from '@tiptap/core';
import { TaskList } from '@tiptap/extension-task-list';
+import { PARSE_HTML_PRIORITY_HIGHEST } from '../constants';
+import { getMarkdownSource } from '../services/markdown_sourcemap';
export default TaskList.extend({
addAttributes() {
return {
- type: {
- default: 'ul',
- parseHTML: (element) => {
- return {
- type: element.tagName.toLowerCase() === 'ol' ? 'ol' : 'ul',
- };
- },
+ numeric: {
+ default: false,
+ parseHTML: (element) => element.tagName.toLowerCase() === 'ol',
+ },
+ start: {
+ default: 1,
+ parseHTML: (element) =>
+ element.hasAttribute('start') ? parseInt(element.getAttribute('start') || '', 10) : 1,
+ },
+
+ parens: {
+ default: false,
+ parseHTML: (element) => /^[0-9]+\)/.test(getMarkdownSource(element)),
},
};
},
@@ -19,12 +27,12 @@ export default TaskList.extend({
return [
{
tag: '.task-list',
- priority: 100,
+ priority: PARSE_HTML_PRIORITY_HIGHEST,
},
];
},
- renderHTML({ HTMLAttributes: { type, ...HTMLAttributes } }) {
- return [type, mergeAttributes(HTMLAttributes, { 'data-type': 'taskList' }), 0];
+ renderHTML({ HTMLAttributes: { numeric, ...HTMLAttributes } }) {
+ return [numeric ? 'ol' : 'ul', mergeAttributes(HTMLAttributes, { 'data-type': 'taskList' }), 0];
},
});
diff --git a/app/assets/javascripts/content_editor/extensions/video.js b/app/assets/javascripts/content_editor/extensions/video.js
new file mode 100644
index 00000000000..9923b7c04cd
--- /dev/null
+++ b/app/assets/javascripts/content_editor/extensions/video.js
@@ -0,0 +1,10 @@
+import Playable from './playable';
+
+export default Playable.extend({
+ name: 'video',
+ defaultOptions: {
+ ...Playable.options,
+ mediaType: 'video',
+ extraElementAttrs: { width: '400' },
+ },
+});
diff --git a/app/assets/javascripts/content_editor/services/create_content_editor.js b/app/assets/javascripts/content_editor/services/create_content_editor.js
index 8997960203a..9b2d4c9a062 100644
--- a/app/assets/javascripts/content_editor/services/create_content_editor.js
+++ b/app/assets/javascripts/content_editor/services/create_content_editor.js
@@ -2,19 +2,26 @@ import { Editor } from '@tiptap/vue-2';
import { isFunction } from 'lodash';
import { PROVIDE_SERIALIZER_OR_RENDERER_ERROR } from '../constants';
import Attachment from '../extensions/attachment';
+import Audio from '../extensions/audio';
import Blockquote from '../extensions/blockquote';
import Bold from '../extensions/bold';
import BulletList from '../extensions/bullet_list';
import Code from '../extensions/code';
import CodeBlockHighlight from '../extensions/code_block_highlight';
+import DescriptionItem from '../extensions/description_item';
+import DescriptionList from '../extensions/description_list';
+import Division from '../extensions/division';
import Document from '../extensions/document';
import Dropcursor from '../extensions/dropcursor';
import Emoji from '../extensions/emoji';
+import Figure from '../extensions/figure';
+import FigureCaption from '../extensions/figure_caption';
import Gapcursor from '../extensions/gapcursor';
import HardBreak from '../extensions/hard_break';
import Heading from '../extensions/heading';
import History from '../extensions/history';
import HorizontalRule from '../extensions/horizontal_rule';
+import HTMLMarks from '../extensions/html_marks';
import Image from '../extensions/image';
import InlineDiff from '../extensions/inline_diff';
import Italic from '../extensions/italic';
@@ -34,6 +41,7 @@ import TableRow from '../extensions/table_row';
import TaskItem from '../extensions/task_item';
import TaskList from '../extensions/task_list';
import Text from '../extensions/text';
+import Video from '../extensions/video';
import { ContentEditor } from './content_editor';
import createMarkdownSerializer from './markdown_serializer';
import trackInputRulesAndShortcuts from './track_input_rules_and_shortcuts';
@@ -62,19 +70,26 @@ export const createContentEditor = ({
const builtInContentEditorExtensions = [
Attachment.configure({ uploadsPath, renderMarkdown }),
+ Audio,
Blockquote,
Bold,
BulletList,
Code,
CodeBlockHighlight,
+ DescriptionItem,
+ DescriptionList,
Document,
+ Division,
Dropcursor,
Emoji,
+ Figure,
+ FigureCaption,
Gapcursor,
HardBreak,
Heading,
History,
HorizontalRule,
+ ...HTMLMarks,
Image,
InlineDiff,
Italic,
@@ -94,6 +109,7 @@ export const createContentEditor = ({
TaskItem,
TaskList,
Text,
+ Video,
];
const allExtensions = [...builtInContentEditorExtensions, ...extensions];
diff --git a/app/assets/javascripts/content_editor/services/feature_flags.js b/app/assets/javascripts/content_editor/services/feature_flags.js
new file mode 100644
index 00000000000..5f7a4595938
--- /dev/null
+++ b/app/assets/javascripts/content_editor/services/feature_flags.js
@@ -0,0 +1,3 @@
+export function isBlockTablesFeatureEnabled() {
+ return gon.features?.contentEditorBlockTables;
+}
diff --git a/app/assets/javascripts/content_editor/services/mark_utils.js b/app/assets/javascripts/content_editor/services/mark_utils.js
new file mode 100644
index 00000000000..6ccfed7810a
--- /dev/null
+++ b/app/assets/javascripts/content_editor/services/mark_utils.js
@@ -0,0 +1,17 @@
+export const markInputRegex = (tag) =>
+ new RegExp(`(<(${tag})((?: \\w+=".+?")+)?>([^<]+)</${tag}>)$`, 'gm');
+
+export const extractMarkAttributesFromMatch = ([, , , attrsString]) => {
+ const attrRegex = /(\w+)="(.+?)"/g;
+ const attrs = {};
+
+ let key;
+ let value;
+
+ do {
+ [, key, value] = attrRegex.exec(attrsString) || [];
+ if (key) attrs[key] = value;
+ } while (key);
+
+ return attrs;
+};
diff --git a/app/assets/javascripts/content_editor/services/markdown_serializer.js b/app/assets/javascripts/content_editor/services/markdown_serializer.js
index df4d31c3d7f..bc6d98511f9 100644
--- a/app/assets/javascripts/content_editor/services/markdown_serializer.js
+++ b/app/assets/javascripts/content_editor/services/markdown_serializer.js
@@ -3,15 +3,22 @@ import {
defaultMarkdownSerializer,
} from 'prosemirror-markdown/src/to_markdown';
import { DOMParser as ProseMirrorDOMParser } from 'prosemirror-model';
+import Audio from '../extensions/audio';
import Blockquote from '../extensions/blockquote';
import Bold from '../extensions/bold';
import BulletList from '../extensions/bullet_list';
import Code from '../extensions/code';
import CodeBlockHighlight from '../extensions/code_block_highlight';
+import DescriptionItem from '../extensions/description_item';
+import DescriptionList from '../extensions/description_list';
+import Division from '../extensions/division';
import Emoji from '../extensions/emoji';
+import Figure from '../extensions/figure';
+import FigureCaption from '../extensions/figure_caption';
import HardBreak from '../extensions/hard_break';
import Heading from '../extensions/heading';
import HorizontalRule from '../extensions/horizontal_rule';
+import HTMLMarks from '../extensions/html_marks';
import Image from '../extensions/image';
import InlineDiff from '../extensions/inline_diff';
import Italic from '../extensions/italic';
@@ -30,6 +37,20 @@ import TableRow from '../extensions/table_row';
import TaskItem from '../extensions/task_item';
import TaskList from '../extensions/task_list';
import Text from '../extensions/text';
+import Video from '../extensions/video';
+import {
+ isPlainURL,
+ renderHardBreak,
+ renderTable,
+ renderTableCell,
+ renderTableRow,
+ openTag,
+ closeTag,
+ renderOrderedList,
+ renderImage,
+ renderPlayable,
+ renderHTMLNode,
+} from './serialization_helpers';
const defaultSerializerConfig = {
marks: {
@@ -48,14 +69,15 @@ const defaultSerializerConfig = {
},
},
[Link.name]: {
- open() {
- return '[';
+ open(state, mark, parent, index) {
+ return isPlainURL(mark, parent, index, 1) ? '<' : '[';
},
- close(state, mark) {
+ close(state, mark, parent, index) {
const href = mark.attrs.canonicalSrc || mark.attrs.href;
- return `](${state.esc(href)}${
- mark.attrs.title ? ` ${state.quote(mark.attrs.title)}` : ''
- })`;
+
+ return isPlainURL(mark, parent, index, -1)
+ ? '>'
+ : `](${state.esc(href)}${mark.attrs.title ? ` ${state.quote(mark.attrs.title)}` : ''})`;
},
},
[Strike.name]: {
@@ -64,9 +86,35 @@ const defaultSerializerConfig = {
mixable: true,
expelEnclosingWhitespace: true,
},
+ ...HTMLMarks.reduce(
+ (acc, { name }) => ({
+ ...acc,
+ [name]: {
+ mixable: true,
+ open(state, node) {
+ return openTag(name, node.attrs);
+ },
+ close: closeTag(name),
+ },
+ }),
+ {},
+ ),
},
+
nodes: {
- [Blockquote.name]: defaultMarkdownSerializer.nodes.blockquote,
+ [Audio.name]: renderPlayable,
+ [Blockquote.name]: (state, node) => {
+ if (node.attrs.multiline) {
+ state.write('>>>');
+ state.ensureNewLine();
+ state.renderContent(node);
+ state.ensureNewLine();
+ state.write('>>>');
+ state.closeBlock(node);
+ } else {
+ state.wrapBlock('> ', null, node, () => state.renderContent(node));
+ }
+ },
[BulletList.name]: defaultMarkdownSerializer.nodes.bullet_list,
[CodeBlockHighlight.name]: (state, node) => {
state.write(`\`\`\`${node.attrs.language || ''}\n`);
@@ -75,94 +123,47 @@ const defaultSerializerConfig = {
state.write('```');
state.closeBlock(node);
},
+ [Division.name]: renderHTMLNode('div'),
+ [DescriptionList.name]: renderHTMLNode('dl', true),
+ [DescriptionItem.name]: (state, node, parent, index) => {
+ if (index === 1) state.ensureNewLine();
+ renderHTMLNode(node.attrs.isTerm ? 'dt' : 'dd')(state, node);
+ if (index === parent.childCount - 1) state.ensureNewLine();
+ },
[Emoji.name]: (state, node) => {
const { name } = node.attrs;
state.write(`:${name}:`);
},
- [HardBreak.name]: defaultMarkdownSerializer.nodes.hard_break,
+ [Figure.name]: renderHTMLNode('figure'),
+ [FigureCaption.name]: renderHTMLNode('figcaption'),
+ [HardBreak.name]: renderHardBreak,
[Heading.name]: defaultMarkdownSerializer.nodes.heading,
[HorizontalRule.name]: defaultMarkdownSerializer.nodes.horizontal_rule,
- [Image.name]: (state, node) => {
- const { alt, canonicalSrc, src, title } = node.attrs;
- const quotedTitle = title ? ` ${state.quote(title)}` : '';
-
- state.write(`![${state.esc(alt || '')}](${state.esc(canonicalSrc || src)}${quotedTitle})`);
- },
+ [Image.name]: renderImage,
[ListItem.name]: defaultMarkdownSerializer.nodes.list_item,
- [OrderedList.name]: defaultMarkdownSerializer.nodes.ordered_list,
+ [OrderedList.name]: renderOrderedList,
[Paragraph.name]: defaultMarkdownSerializer.nodes.paragraph,
[Reference.name]: (state, node) => {
state.write(node.attrs.originalText || node.attrs.text);
},
- [Table.name]: (state, node) => {
- state.renderContent(node);
- },
- [TableCell.name]: (state, node) => {
- state.renderInline(node);
- },
- [TableHeader.name]: (state, node) => {
- state.renderInline(node);
- },
- [TableRow.name]: (state, node) => {
- const isHeaderRow = node.child(0).type.name === 'tableHeader';
-
- const renderRow = () => {
- const cellWidths = [];
-
- state.flushClose(1);
-
- state.write('| ');
- node.forEach((cell, _, i) => {
- if (i) state.write(' | ');
-
- const { length } = state.out;
- state.render(cell, node, i);
- cellWidths.push(state.out.length - length);
- });
- state.write(' |');
-
- state.closeBlock(node);
-
- return cellWidths;
- };
-
- const renderHeaderRow = (cellWidths) => {
- state.flushClose(1);
-
- state.write('|');
- node.forEach((cell, _, i) => {
- if (i) state.write('|');
-
- state.write(cell.attrs.align === 'center' ? ':' : '-');
- state.write(state.repeat('-', cellWidths[i]));
- state.write(cell.attrs.align === 'center' || cell.attrs.align === 'right' ? ':' : '-');
- });
- state.write('|');
-
- state.closeBlock(node);
- };
-
- if (isHeaderRow) {
- renderHeaderRow(renderRow());
- } else {
- renderRow();
- }
- },
+ [Table.name]: renderTable,
+ [TableCell.name]: renderTableCell,
+ [TableHeader.name]: renderTableCell,
+ [TableRow.name]: renderTableRow,
[TaskItem.name]: (state, node) => {
state.write(`[${node.attrs.checked ? 'x' : ' '}] `);
state.renderContent(node);
},
[TaskList.name]: (state, node) => {
- if (node.attrs.type === 'ul') defaultMarkdownSerializer.nodes.bullet_list(state, node);
- else defaultMarkdownSerializer.nodes.ordered_list(state, node);
+ if (node.attrs.numeric) renderOrderedList(state, node);
+ else defaultMarkdownSerializer.nodes.bullet_list(state, node);
},
[Text.name]: defaultMarkdownSerializer.nodes.text,
+ [Video.name]: renderPlayable,
},
};
-const wrapHtmlPayload = (payload) => `<div>${payload}</div>`;
-
/**
* A markdown serializer converts arbitrary Markdown content
* into a ProseMirror document and viceversa. To convert Markdown
@@ -175,7 +176,7 @@ const wrapHtmlPayload = (payload) => `<div>${payload}</div>`;
* that parses the Markdown and converts it into HTML.
* @returns a markdown serializer
*/
-export default ({ render = () => null, serializerConfig }) => ({
+export default ({ render = () => null, serializerConfig = {} } = {}) => ({
/**
* Converts a Markdown string into a ProseMirror JSONDocument based
* on a ProseMirror schema.
@@ -187,15 +188,15 @@ export default ({ render = () => null, serializerConfig }) => ({
deserialize: async ({ schema, content }) => {
const html = await render(content);
- if (!html) {
- return null;
- }
+ if (!html) return null;
const parser = new DOMParser();
- const {
- body: { firstElementChild },
- } = parser.parseFromString(wrapHtmlPayload(html), 'text/html');
- const state = ProseMirrorDOMParser.fromSchema(schema).parse(firstElementChild);
+ const { body } = parser.parseFromString(html, 'text/html');
+
+ // append original source as a comment that nodes can access
+ body.append(document.createComment(content));
+
+ const state = ProseMirrorDOMParser.fromSchema(schema).parse(body);
return state.toJSON();
},
diff --git a/app/assets/javascripts/content_editor/services/markdown_sourcemap.js b/app/assets/javascripts/content_editor/services/markdown_sourcemap.js
new file mode 100644
index 00000000000..a1199589c9b
--- /dev/null
+++ b/app/assets/javascripts/content_editor/services/markdown_sourcemap.js
@@ -0,0 +1,40 @@
+const getFullSource = (element) => {
+ const commentNode = element.ownerDocument.body.lastChild;
+
+ if (commentNode.nodeName === '#comment') {
+ return commentNode.textContent.split('\n');
+ }
+
+ return [];
+};
+
+const getRangeFromSourcePos = (sourcePos) => {
+ const [start, end] = sourcePos.split('-');
+ const [startRow, startCol] = start.split(':');
+ const [endRow, endCol] = end.split(':');
+
+ return {
+ start: { row: Number(startRow) - 1, col: Number(startCol) - 1 },
+ end: { row: Number(endRow) - 1, col: Number(endCol) - 1 },
+ };
+};
+
+export const getMarkdownSource = (element) => {
+ if (!element.dataset.sourcepos) return undefined;
+
+ const source = getFullSource(element);
+ const range = getRangeFromSourcePos(element.dataset.sourcepos);
+ let elSource = '';
+
+ for (let i = range.start.row; i <= range.end.row; i += 1) {
+ if (i === range.start.row) {
+ elSource += source[i]?.substring(range.start.col);
+ } else if (i === range.end.row) {
+ elSource += `\n${source[i]?.substring(0, range.start.col)}`;
+ } else {
+ elSource += `\n${source[i]}` || '';
+ }
+ }
+
+ return elSource.trim();
+};
diff --git a/app/assets/javascripts/content_editor/services/serialization_helpers.js b/app/assets/javascripts/content_editor/services/serialization_helpers.js
new file mode 100644
index 00000000000..b2327555b45
--- /dev/null
+++ b/app/assets/javascripts/content_editor/services/serialization_helpers.js
@@ -0,0 +1,345 @@
+import { uniq } from 'lodash';
+import { isBlockTablesFeatureEnabled } from './feature_flags';
+
+const defaultAttrs = {
+ td: { colspan: 1, rowspan: 1, colwidth: null },
+ th: { colspan: 1, rowspan: 1, colwidth: null },
+};
+
+const ignoreAttrs = {
+ dd: ['isTerm'],
+ dt: ['isTerm'],
+};
+
+const tableMap = new WeakMap();
+
+// Source taken from
+// prosemirror-markdown/src/to_markdown.js
+export function isPlainURL(link, parent, index, side) {
+ if (link.attrs.title || !/^\w+:/.test(link.attrs.href)) return false;
+ const content = parent.child(index + (side < 0 ? -1 : 0));
+ if (
+ !content.isText ||
+ content.text !== link.attrs.href ||
+ content.marks[content.marks.length - 1] !== link
+ )
+ return false;
+ if (index === (side < 0 ? 1 : parent.childCount - 1)) return true;
+ const next = parent.child(index + (side < 0 ? -2 : 1));
+ return !link.isInSet(next.marks);
+}
+
+function containsOnlyText(node) {
+ if (node.childCount === 1) {
+ const child = node.child(0);
+ return child.isText && child.marks.length === 0;
+ }
+
+ return false;
+}
+
+function containsParagraphWithOnlyText(cell) {
+ if (cell.childCount === 1) {
+ const child = cell.child(0);
+ if (child.type.name === 'paragraph') {
+ return containsOnlyText(child);
+ }
+ }
+
+ return false;
+}
+
+function getRowsAndCells(table) {
+ const cells = [];
+ const rows = [];
+ table.descendants((n) => {
+ if (n.type.name === 'tableCell' || n.type.name === 'tableHeader') {
+ cells.push(n);
+ return false;
+ }
+
+ if (n.type.name === 'tableRow') {
+ rows.push(n);
+ }
+
+ return true;
+ });
+ return { rows, cells };
+}
+
+function getChildren(node) {
+ const children = [];
+ for (let i = 0; i < node.childCount; i += 1) {
+ children.push(node.child(i));
+ }
+ return children;
+}
+
+function shouldRenderHTMLTable(table) {
+ const { rows, cells } = getRowsAndCells(table);
+
+ const cellChildCount = Math.max(...cells.map((cell) => cell.childCount));
+ const maxColspan = Math.max(...cells.map((cell) => cell.attrs.colspan));
+ const maxRowspan = Math.max(...cells.map((cell) => cell.attrs.rowspan));
+
+ const rowChildren = rows.map((row) => uniq(getChildren(row).map((cell) => cell.type.name)));
+ const cellTypeInFirstRow = rowChildren[0];
+ const cellTypesInOtherRows = uniq(rowChildren.slice(1).map(([type]) => type));
+
+ // if the first row has headers, and there are no headers anywhere else, render markdown table
+ if (
+ !(
+ cellTypeInFirstRow.length === 1 &&
+ cellTypeInFirstRow[0] === 'tableHeader' &&
+ cellTypesInOtherRows.length === 1 &&
+ cellTypesInOtherRows[0] === 'tableCell'
+ )
+ ) {
+ return true;
+ }
+
+ if (cellChildCount === 1 && maxColspan === 1 && maxRowspan === 1) {
+ // if all rows contain only one paragraph each and no rowspan/colspan, render markdown table
+ const children = uniq(cells.map((cell) => cell.child(0).type.name));
+ if (children.length === 1 && children[0] === 'paragraph') {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+function htmlEncode(str = '') {
+ return str
+ .replace(/&/g, '&amp;')
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;')
+ .replace(/'/g, '&#39;')
+ .replace(/"/g, '&#34;');
+}
+
+export function openTag(tagName, attrs) {
+ let str = `<${tagName}`;
+
+ str += Object.entries(attrs || {})
+ .map(([key, value]) => {
+ if ((ignoreAttrs[tagName] || []).includes(key) || defaultAttrs[tagName]?.[key] === value)
+ return '';
+
+ return ` ${key}="${htmlEncode(value?.toString())}"`;
+ })
+ .join('');
+
+ return `${str}>`;
+}
+
+export function closeTag(tagName) {
+ return `</${tagName}>`;
+}
+
+function isInBlockTable(node) {
+ return tableMap.get(node);
+}
+
+function isInTable(node) {
+ return tableMap.has(node);
+}
+
+function setIsInBlockTable(table, value) {
+ tableMap.set(table, value);
+
+ const { rows, cells } = getRowsAndCells(table);
+ rows.forEach((row) => tableMap.set(row, value));
+ cells.forEach((cell) => {
+ tableMap.set(cell, value);
+ if (cell.childCount && cell.child(0).type.name === 'paragraph')
+ tableMap.set(cell.child(0), value);
+ });
+}
+
+function unsetIsInBlockTable(table) {
+ tableMap.delete(table);
+
+ const { rows, cells } = getRowsAndCells(table);
+ rows.forEach((row) => tableMap.delete(row));
+ cells.forEach((cell) => {
+ tableMap.delete(cell);
+ if (cell.childCount) tableMap.delete(cell.child(0));
+ });
+}
+
+function renderTagOpen(state, tagName, attrs) {
+ state.ensureNewLine();
+ state.write(openTag(tagName, attrs));
+}
+
+function renderTagClose(state, tagName, insertNewline = true) {
+ state.write(closeTag(tagName));
+ if (insertNewline) state.ensureNewLine();
+}
+
+function renderTableHeaderRowAsMarkdown(state, node, cellWidths) {
+ state.flushClose(1);
+
+ state.write('|');
+ node.forEach((cell, _, i) => {
+ if (i) state.write('|');
+
+ state.write(cell.attrs.align === 'center' ? ':' : '-');
+ state.write(state.repeat('-', cellWidths[i]));
+ state.write(cell.attrs.align === 'center' || cell.attrs.align === 'right' ? ':' : '-');
+ });
+ state.write('|');
+
+ state.closeBlock(node);
+}
+
+function renderTableRowAsMarkdown(state, node, isHeaderRow = false) {
+ const cellWidths = [];
+
+ state.flushClose(1);
+
+ state.write('| ');
+ node.forEach((cell, _, i) => {
+ if (i) state.write(' | ');
+
+ const { length } = state.out;
+ state.render(cell, node, i);
+ cellWidths.push(state.out.length - length);
+ });
+ state.write(' |');
+
+ state.closeBlock(node);
+
+ if (isHeaderRow) renderTableHeaderRowAsMarkdown(state, node, cellWidths);
+}
+
+function renderTableRowAsHTML(state, node) {
+ renderTagOpen(state, 'tr');
+
+ node.forEach((cell, _, i) => {
+ const tag = cell.type.name === 'tableHeader' ? 'th' : 'td';
+
+ renderTagOpen(state, tag, cell.attrs);
+
+ if (!containsParagraphWithOnlyText(cell)) {
+ state.closeBlock(node);
+ state.flushClose();
+ }
+
+ state.render(cell, node, i);
+ state.flushClose(1);
+
+ renderTagClose(state, tag);
+ });
+
+ renderTagClose(state, 'tr');
+}
+
+export function renderContent(state, node, forceRenderInline) {
+ if (node.type.inlineContent) {
+ if (containsOnlyText(node)) {
+ state.renderInline(node);
+ } else {
+ state.closeBlock(node);
+ state.flushClose();
+ state.renderInline(node);
+ state.closeBlock(node);
+ state.flushClose();
+ }
+ } else {
+ const renderInline = forceRenderInline || containsParagraphWithOnlyText(node);
+ if (!renderInline) {
+ state.closeBlock(node);
+ state.flushClose();
+ state.renderContent(node);
+ state.ensureNewLine();
+ } else {
+ state.renderInline(forceRenderInline ? node : node.child(0));
+ }
+ }
+}
+
+export function renderHTMLNode(tagName, forceRenderInline = false) {
+ return (state, node) => {
+ renderTagOpen(state, tagName, node.attrs);
+ renderContent(state, node, forceRenderInline);
+ renderTagClose(state, tagName, false);
+ };
+}
+
+export function renderOrderedList(state, node) {
+ const { parens } = node.attrs;
+ const start = node.attrs.start || 1;
+ const maxW = String(start + node.childCount - 1).length;
+ const space = state.repeat(' ', maxW + 2);
+ const delimiter = parens ? ')' : '.';
+
+ state.renderList(node, space, (i) => {
+ const nStr = String(start + i);
+ return `${state.repeat(' ', maxW - nStr.length) + nStr}${delimiter} `;
+ });
+}
+
+export function renderTableCell(state, node) {
+ if (!isBlockTablesFeatureEnabled()) {
+ state.renderInline(node);
+ return;
+ }
+
+ if (!isInBlockTable(node) || containsParagraphWithOnlyText(node)) {
+ state.renderInline(node.child(0));
+ } else {
+ state.renderContent(node);
+ }
+}
+
+export function renderTableRow(state, node) {
+ if (isInBlockTable(node)) {
+ renderTableRowAsHTML(state, node);
+ } else {
+ renderTableRowAsMarkdown(state, node, node.child(0).type.name === 'tableHeader');
+ }
+}
+
+export function renderTable(state, node) {
+ if (isBlockTablesFeatureEnabled()) {
+ setIsInBlockTable(node, shouldRenderHTMLTable(node));
+ }
+
+ if (isInBlockTable(node)) renderTagOpen(state, 'table');
+
+ state.renderContent(node);
+
+ if (isInBlockTable(node)) renderTagClose(state, 'table');
+
+ // ensure at least one blank line after any table
+ state.closeBlock(node);
+ state.flushClose();
+
+ if (isBlockTablesFeatureEnabled()) {
+ unsetIsInBlockTable(node);
+ }
+}
+
+export function renderHardBreak(state, node, parent, index) {
+ const br = isInTable(parent) ? '<br>' : '\\\n';
+
+ for (let i = index + 1; i < parent.childCount; i += 1) {
+ if (parent.child(i).type !== node.type) {
+ state.write(br);
+ return;
+ }
+ }
+}
+
+export function renderImage(state, node) {
+ const { alt, canonicalSrc, src, title } = node.attrs;
+ const quotedTitle = title ? ` ${state.quote(title)}` : '';
+
+ state.write(`![${state.esc(alt || '')}](${state.esc(canonicalSrc || src)}${quotedTitle})`);
+}
+
+export function renderPlayable(state, node) {
+ renderImage(state, node);
+}
diff --git a/app/assets/javascripts/create_cluster/eks_cluster/components/service_credentials_form.vue b/app/assets/javascripts/create_cluster/eks_cluster/components/service_credentials_form.vue
index 45c886978f1..004c2e26c4e 100644
--- a/app/assets/javascripts/create_cluster/eks_cluster/components/service_credentials_form.vue
+++ b/app/assets/javascripts/create_cluster/eks_cluster/components/service_credentials_form.vue
@@ -1,9 +1,7 @@
<script>
-/* eslint-disable vue/no-v-html */
import { GlButton, GlFormGroup, GlFormInput, GlIcon, GlLink, GlSprintf, GlAlert } from '@gitlab/ui';
-import { escape } from 'lodash';
import { mapState, mapActions } from 'vuex';
-import { sprintf, s__, __ } from '~/locale';
+import { s__, __ } from '~/locale';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import { DEFAULT_REGION } from '../constants';
@@ -38,6 +36,9 @@ export default {
regionHelpText: s__(
'ClusterIntegration|Select the region you want to create the new cluster in. Make sure you have access to this region for your role to be able to authenticate. If no region is selected, we will use %{codeStart}DEFAULT_REGION%{codeEnd}. Learn more about %{linkStart}Regions%{linkEnd}.',
),
+ accountAndExternalIdsHelpText: s__(
+ 'ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{awsLinkStart}Amazon Web Services %{awsLinkEnd} using the above account and external IDs. %{moreInfoStart}More information%{moreInfoEnd}',
+ ),
regionHelpTextDefaultRegion: DEFAULT_REGION,
},
data() {
@@ -56,39 +57,8 @@ export default {
? __('Authenticating')
: s__('ClusterIntegration|Authenticate with AWS');
},
- accountAndExternalIdsHelpText() {
- const escapedUrl = escape(this.accountAndExternalIdsHelpPath);
-
- return sprintf(
- s__(
- 'ClusterIntegration|Create a provision role on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the account and external ID above. %{startMoreInfoLink}More information%{endLink}',
- ),
- {
- startAwsLink:
- '<a href="https://console.aws.amazon.com/iam/home?#roles" target="_blank" rel="noopener noreferrer">',
- startMoreInfoLink: `<a href="${escapedUrl}" target="_blank" rel="noopener noreferrer">`,
- externalLinkIcon: this.externalLinkIcon,
- endLink: '</a>',
- },
- false,
- );
- },
- provisionRoleArnHelpText() {
- const escapedUrl = escape(this.createRoleArnHelpPath);
-
- return sprintf(
- s__(
- 'ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}',
- ),
- {
- startAwsLink:
- '<a href="https://console.aws.amazon.com/iam/home?#roles" target="_blank" rel="noopener noreferrer">',
- startMoreInfoLink: `<a href="${escapedUrl}" target="_blank" rel="noopener noreferrer">`,
- externalLinkIcon: this.externalLinkIcon,
- endLink: '</a>',
- },
- false,
- );
+ awsHelpLink() {
+ return 'https://console.aws.amazon.com/iam/home?#roles';
},
},
methods: {
@@ -142,13 +112,41 @@ export default {
</div>
</div>
<div class="col-12 mb-3 mt-n3">
- <p class="form-text text-muted" v-html="accountAndExternalIdsHelpText"></p>
+ <p class="form-text text-muted">
+ <gl-sprintf :message="$options.i18n.accountAndExternalIdsHelpText">
+ <template #awsLink="{ content }">
+ <gl-link :href="awsHelpLink" target="_blank">
+ {{ content }}
+ <gl-icon name="external-link" class="gl-vertical-align-middle" />
+ </gl-link>
+ </template>
+ <template #moreInfo="{ content }">
+ <gl-link :href="accountAndExternalIdsHelpPath" target="_blank">
+ {{ content }}
+ </gl-link>
+ </template>
+ </gl-sprintf>
+ </p>
</div>
</div>
<div class="form-group">
<label for="eks-provision-role-arn">{{ s__('ClusterIntegration|Provision Role ARN') }}</label>
<gl-form-input id="eks-provision-role-arn" v-model="roleArn" />
- <p class="form-text text-muted" v-html="provisionRoleArnHelpText"></p>
+ <p class="form-text text-muted">
+ <gl-sprintf :message="$options.i18n.accountAndExternalIdsHelpText">
+ <template #awsLink="{ content }">
+ <gl-link :href="awsHelpLink" target="_blank">
+ {{ content }}
+ <gl-icon name="external-link" class="gl-vertical-align-middle" />
+ </gl-link>
+ </template>
+ <template #moreInfo="{ content }">
+ <gl-link :href="accountAndExternalIdsHelpPath" target="_blank">
+ {{ content }}
+ </gl-link>
+ </template>
+ </gl-sprintf>
+ </p>
</div>
<gl-form-group :label="$options.i18n.regionInputLabel">
diff --git a/app/assets/javascripts/create_cluster/eks_cluster/constants.js b/app/assets/javascripts/create_cluster/eks_cluster/constants.js
index 1c698cc2796..3ed0f050301 100644
--- a/app/assets/javascripts/create_cluster/eks_cluster/constants.js
+++ b/app/assets/javascripts/create_cluster/eks_cluster/constants.js
@@ -1,9 +1,9 @@
export const DEFAULT_REGION = 'us-east-2';
export const KUBERNETES_VERSIONS = [
- { name: '1.15', value: '1.15' },
{ name: '1.16', value: '1.16' },
{ name: '1.17', value: '1.17' },
{ name: '1.18', value: '1.18' },
- { name: '1.19', value: '1.19', default: true },
+ { name: '1.19', value: '1.19' },
+ { name: '1.20', value: '1.20', default: true },
];
diff --git a/app/assets/javascripts/cycle_analytics/components/banner.vue b/app/assets/javascripts/cycle_analytics/components/banner.vue
deleted file mode 100644
index cf4c35ef12b..00000000000
--- a/app/assets/javascripts/cycle_analytics/components/banner.vue
+++ /dev/null
@@ -1,54 +0,0 @@
-<script>
-/* eslint-disable vue/no-v-html */
-import { GlIcon } from '@gitlab/ui';
-import iconCycleAnalyticsSplash from 'icons/_icon_cycle_analytics_splash.svg';
-
-export default {
- components: {
- GlIcon,
- },
- props: {
- documentationLink: {
- type: String,
- required: true,
- },
- },
- computed: {
- iconCycleAnalyticsSplash() {
- return iconCycleAnalyticsSplash;
- },
- },
- methods: {
- dismissOverviewDialog() {
- this.$emit('dismiss-overview-dialog');
- },
- },
-};
-</script>
-<template>
- <div class="landing content-block">
- <button
- :aria-label="__('Dismiss Value Stream Analytics introduction box')"
- class="js-ca-dismiss-button dismiss-button"
- type="button"
- @click="dismissOverviewDialog"
- >
- <gl-icon name="close" />
- </button>
- <div class="svg-container" v-html="iconCycleAnalyticsSplash"></div>
- <div class="inner-content">
- <h4>{{ __('Introducing Value Stream Analytics') }}</h4>
- <p>
- {{
- __(`Value Stream Analytics gives an overview
-of how much time it takes to go from idea to production in your project.`)
- }}
- </p>
- <p>
- <a :href="documentationLink" target="_blank" rel="nofollow" class="btn">
- {{ __('Read more') }}
- </a>
- </p>
- </div>
- </div>
-</template>
diff --git a/app/assets/javascripts/cycle_analytics/components/base.vue b/app/assets/javascripts/cycle_analytics/components/base.vue
index c9ecac6829b..ae78ce33263 100644
--- a/app/assets/javascripts/cycle_analytics/components/base.vue
+++ b/app/assets/javascripts/cycle_analytics/components/base.vue
@@ -1,9 +1,10 @@
<script>
-import { GlIcon, GlLoadingIcon, GlSprintf } from '@gitlab/ui';
+import { GlLoadingIcon } from '@gitlab/ui';
import Cookies from 'js-cookie';
import { mapActions, mapState, mapGetters } from 'vuex';
import PathNavigation from '~/cycle_analytics/components/path_navigation.vue';
import StageTable from '~/cycle_analytics/components/stage_table.vue';
+import ValueStreamFilters from '~/cycle_analytics/components/value_stream_filters.vue';
import ValueStreamMetrics from '~/cycle_analytics/components/value_stream_metrics.vue';
import { __ } from '~/locale';
import { SUMMARY_METRICS_REQUEST, METRICS_REQUESTS } from '../constants';
@@ -13,11 +14,10 @@ const OVERVIEW_DIALOG_COOKIE = 'cycle_analytics_help_dismissed';
export default {
name: 'CycleAnalytics',
components: {
- GlIcon,
GlLoadingIcon,
- GlSprintf,
PathNavigation,
StageTable,
+ ValueStreamFilters,
ValueStreamMetrics,
},
props: {
@@ -45,11 +45,12 @@ export default {
'selectedStageError',
'stages',
'summary',
- 'daysInPast',
'permissions',
'stageCounts',
'endpoints',
'features',
+ 'createdBefore',
+ 'createdAfter',
]),
...mapGetters(['pathNavigationData', 'filterParams']),
displayStageEvents() {
@@ -98,14 +99,12 @@ export default {
},
},
methods: {
- ...mapActions([
- 'fetchCycleAnalyticsData',
- 'fetchStageData',
- 'setSelectedStage',
- 'setDateRange',
- ]),
- handleDateSelect(daysInPast) {
- this.setDateRange(daysInPast);
+ ...mapActions(['fetchStageData', 'setSelectedStage', 'setDateRange']),
+ onSetDateRange({ startDate, endDate }) {
+ this.setDateRange({
+ createdAfter: new Date(startDate),
+ createdBefore: new Date(endDate),
+ });
},
onSelectStage(stage) {
this.setSelectedStage(stage);
@@ -133,35 +132,22 @@ export default {
<div class="gl-display-flex gl-flex-direction-column gl-md-flex-direction-row">
<path-navigation
v-if="displayPathNavigation"
- class="js-path-navigation gl-w-full gl-pb-2"
+ data-testid="vsa-path-navigation"
+ class="gl-w-full gl-pb-2"
:loading="isLoading || isLoadingStage"
:stages="pathNavigationData"
:selected-stage="selectedStage"
@selected="onSelectStage"
/>
- <div class="gl-flex-grow gl-align-self-end">
- <div class="js-ca-dropdown dropdown inline">
- <!-- eslint-disable-next-line @gitlab/vue-no-data-toggle -->
- <button class="dropdown-menu-toggle" data-toggle="dropdown" type="button">
- <span class="dropdown-label">
- <gl-sprintf :message="$options.i18n.dropdownText">
- <template #days>{{ daysInPast }}</template>
- </gl-sprintf>
- <gl-icon name="chevron-down" class="dropdown-menu-toggle-icon gl-top-3" />
- </span>
- </button>
- <ul class="dropdown-menu dropdown-menu-right">
- <li v-for="days in $options.dayRangeOptions" :key="`day-range-${days}`">
- <a href="#" @click.prevent="handleDateSelect(days)">
- <gl-sprintf :message="$options.i18n.dropdownText">
- <template #days>{{ days }}</template>
- </gl-sprintf>
- </a>
- </li>
- </ul>
- </div>
- </div>
</div>
+ <value-stream-filters
+ :group-id="endpoints.groupId"
+ :group-path="endpoints.groupPath"
+ :has-project-filter="false"
+ :start-date="createdAfter"
+ :end-date="createdBefore"
+ @setDateRange="onSetDateRange"
+ />
<value-stream-metrics
:request-path="endpoints.fullPath"
:request-params="filterParams"
@@ -178,6 +164,7 @@ export default {
:empty-state-message="emptyStageText"
:no-data-svg-path="noDataSvgPath"
:pagination="null"
+ :sortable="false"
/>
</div>
</template>
diff --git a/app/assets/javascripts/cycle_analytics/components/stage_table.vue b/app/assets/javascripts/cycle_analytics/components/stage_table.vue
index 0c47838c773..8a2667a4ab1 100644
--- a/app/assets/javascripts/cycle_analytics/components/stage_table.vue
+++ b/app/assets/javascripts/cycle_analytics/components/stage_table.vue
@@ -23,8 +23,8 @@ import TotalTime from './total_time_component.vue';
const DEFAULT_WORKFLOW_TITLE_PROPERTIES = {
thClass: 'gl-w-half',
key: PAGINATION_SORT_FIELD_END_EVENT,
- sortable: true,
};
+
const WORKFLOW_COLUMN_TITLES = {
issues: { ...DEFAULT_WORKFLOW_TITLE_PROPERTIES, label: __('Issues') },
jobs: { ...DEFAULT_WORKFLOW_TITLE_PROPERTIES, label: __('Jobs') },
@@ -84,6 +84,11 @@ export default {
required: false,
default: null,
},
+ sortable: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
},
data() {
if (this.pagination) {
@@ -122,9 +127,11 @@ export default {
key: PAGINATION_SORT_FIELD_DURATION,
label: __('Time'),
thClass: 'gl-w-half',
- sortable: true,
},
- ];
+ ].map((field) => ({
+ ...field,
+ sortable: this.sortable,
+ }));
},
prevPage() {
return Math.max(this.pagination.page - 1, 0);
diff --git a/app/assets/javascripts/cycle_analytics/components/value_stream_filters.vue b/app/assets/javascripts/cycle_analytics/components/value_stream_filters.vue
index 6b1e537dc77..8610dfc2b03 100644
--- a/app/assets/javascripts/cycle_analytics/components/value_stream_filters.vue
+++ b/app/assets/javascripts/cycle_analytics/components/value_stream_filters.vue
@@ -61,33 +61,38 @@ export default {
<template>
<div class="gl-mt-3 gl-py-2 gl-px-3 bg-gray-light border-top border-bottom">
<filter-bar
- class="js-filter-bar filtered-search-box gl-display-flex gl-mb-2 gl-mr-3 gl-border-none"
+ data-testid="vsa-filter-bar"
+ class="filtered-search-box gl-display-flex gl-mb-2 gl-mr-3 gl-border-none"
:group-path="groupPath"
/>
<div
v-if="hasDateRangeFilter || hasProjectFilter"
class="gl-display-flex gl-flex-direction-column gl-lg-flex-direction-row gl-justify-content-space-between"
>
- <projects-dropdown-filter
- v-if="hasProjectFilter"
- :key="groupId"
- class="js-projects-dropdown-filter project-select gl-mb-2 gl-lg-mb-0"
- :group-id="groupId"
- :group-namespace="groupPath"
- :query-params="projectsQueryParams"
- :multi-select="$options.multiProjectSelect"
- :default-projects="selectedProjects"
- @selected="$emit('selectProject', $event)"
- />
- <date-range
- v-if="hasDateRangeFilter"
- :start-date="startDate"
- :end-date="endDate"
- :max-date-range="$options.maxDateRange"
- :include-selected-date="true"
- class="js-daterange-picker"
- @change="$emit('setDateRange', $event)"
- />
+ <div>
+ <projects-dropdown-filter
+ v-if="hasProjectFilter"
+ :key="groupId"
+ class="js-projects-dropdown-filter project-select gl-mb-2 gl-lg-mb-0"
+ :group-id="groupId"
+ :group-namespace="groupPath"
+ :query-params="projectsQueryParams"
+ :multi-select="$options.multiProjectSelect"
+ :default-projects="selectedProjects"
+ @selected="$emit('selectProject', $event)"
+ />
+ </div>
+ <div>
+ <date-range
+ v-if="hasDateRangeFilter"
+ :start-date="startDate"
+ :end-date="endDate"
+ :max-date-range="$options.maxDateRange"
+ :include-selected-date="true"
+ class="js-daterange-picker"
+ @change="$emit('setDateRange', $event)"
+ />
+ </div>
</div>
</div>
</template>
diff --git a/app/assets/javascripts/cycle_analytics/index.js b/app/assets/javascripts/cycle_analytics/index.js
index 3827db4d9b2..620da0104e0 100644
--- a/app/assets/javascripts/cycle_analytics/index.js
+++ b/app/assets/javascripts/cycle_analytics/index.js
@@ -1,7 +1,9 @@
import Vue from 'vue';
import Translate from '../vue_shared/translate';
import CycleAnalytics from './components/base.vue';
+import { DEFAULT_DAYS_TO_DISPLAY } from './constants';
import createStore from './store';
+import { calculateFormattedDayInPast } from './utils';
Vue.use(Translate);
@@ -14,19 +16,29 @@ export default () => {
requestPath,
fullPath,
projectId,
+ groupId,
groupPath,
+ labelsPath,
+ milestonesPath,
} = el.dataset;
+ const { now, past } = calculateFormattedDayInPast(DEFAULT_DAYS_TO_DISPLAY);
+
store.dispatch('initializeVsa', {
projectId: parseInt(projectId, 10),
- groupPath,
endpoints: {
requestPath,
fullPath,
+ labelsPath,
+ milestonesPath,
+ groupId: parseInt(groupId, 10),
+ groupPath,
},
features: {
cycleAnalyticsForGroups: Boolean(gon?.licensed_features?.cycleAnalyticsForGroups),
},
+ createdBefore: new Date(now),
+ createdAfter: new Date(past),
});
// eslint-disable-next-line no-new
diff --git a/app/assets/javascripts/cycle_analytics/store/actions.js b/app/assets/javascripts/cycle_analytics/store/actions.js
index a7a2c8ea9d3..e39cd224199 100644
--- a/app/assets/javascripts/cycle_analytics/store/actions.js
+++ b/app/assets/javascripts/cycle_analytics/store/actions.js
@@ -163,6 +163,7 @@ const refetchStageData = (dispatch) => {
dispatch('fetchCycleAnalyticsData'),
dispatch('fetchStageData'),
dispatch('fetchStageMedians'),
+ dispatch('fetchStageCountValues'),
]),
)
.finally(() => dispatch('setLoading', false));
@@ -170,14 +171,24 @@ const refetchStageData = (dispatch) => {
export const setFilters = ({ dispatch }) => refetchStageData(dispatch);
-export const setDateRange = ({ dispatch, commit }, daysInPast) => {
- commit(types.SET_DATE_RANGE, daysInPast);
+export const setDateRange = ({ dispatch, commit }, { createdAfter, createdBefore }) => {
+ commit(types.SET_DATE_RANGE, { createdAfter, createdBefore });
return refetchStageData(dispatch);
};
export const initializeVsa = ({ commit, dispatch }, initialData = {}) => {
commit(types.INITIALIZE_VSA, initialData);
+ const {
+ endpoints: { fullPath, groupPath, milestonesPath = '', labelsPath = '' },
+ } = initialData;
+ dispatch('filters/setEndpoints', {
+ labelsEndpoint: labelsPath,
+ milestonesEndpoint: milestonesPath,
+ groupEndpoint: groupPath,
+ projectEndpoint: fullPath,
+ });
+
return dispatch('setLoading', true)
.then(() => dispatch('fetchValueStreams'))
.finally(() => dispatch('setLoading', false));
diff --git a/app/assets/javascripts/cycle_analytics/store/getters.js b/app/assets/javascripts/cycle_analytics/store/getters.js
index 9faccabcaad..77c285f5ce0 100644
--- a/app/assets/javascripts/cycle_analytics/store/getters.js
+++ b/app/assets/javascripts/cycle_analytics/store/getters.js
@@ -1,5 +1,6 @@
import dateFormat from 'dateformat';
import { dateFormats } from '~/analytics/shared/constants';
+import { filterToQueryObject } from '~/vue_shared/components/filtered_search_bar/filtered_search_utils';
import { transformStagesForPathNavigation, filterStagesByHiddenStatus } from '../utils';
export const pathNavigationData = ({ stages, medians, stageCounts, selectedStage }) => {
@@ -20,6 +21,21 @@ export const requestParams = (state) => {
return { requestPath: fullPath, valueStreamId, stageId };
};
+const filterBarParams = ({ filters }) => {
+ const {
+ authors: { selected: selectedAuthor },
+ milestones: { selected: selectedMilestone },
+ assignees: { selectedList: selectedAssigneeList },
+ labels: { selectedList: selectedLabelList },
+ } = filters;
+ return filterToQueryObject({
+ milestone_title: selectedMilestone,
+ author_username: selectedAuthor,
+ label_name: selectedLabelList,
+ assignee_username: selectedAssigneeList,
+ });
+};
+
const dateRangeParams = ({ createdAfter, createdBefore }) => ({
created_after: createdAfter ? dateFormat(createdAfter, dateFormats.isoDate) : null,
created_before: createdBefore ? dateFormat(createdBefore, dateFormats.isoDate) : null,
@@ -33,6 +49,7 @@ export const legacyFilterParams = ({ daysInPast }) => {
export const filterParams = (state) => {
return {
+ ...filterBarParams(state),
...dateRangeParams(state),
};
};
diff --git a/app/assets/javascripts/cycle_analytics/store/mutations.js b/app/assets/javascripts/cycle_analytics/store/mutations.js
index e41de85c1fa..301e7d95f8c 100644
--- a/app/assets/javascripts/cycle_analytics/store/mutations.js
+++ b/app/assets/javascripts/cycle_analytics/store/mutations.js
@@ -1,14 +1,12 @@
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
-import { DEFAULT_DAYS_TO_DISPLAY } from '../constants';
-import { formatMedianValues, calculateFormattedDayInPast } from '../utils';
+import { formatMedianValues } from '../utils';
import * as types from './mutation_types';
export default {
- [types.INITIALIZE_VSA](state, { endpoints, features }) {
+ [types.INITIALIZE_VSA](state, { endpoints, features, createdBefore, createdAfter }) {
state.endpoints = endpoints;
- const { now, past } = calculateFormattedDayInPast(DEFAULT_DAYS_TO_DISPLAY);
- state.createdBefore = now;
- state.createdAfter = past;
+ state.createdBefore = createdBefore;
+ state.createdAfter = createdAfter;
state.features = features;
},
[types.SET_LOADING](state, loadingState) {
@@ -20,11 +18,9 @@ export default {
[types.SET_SELECTED_STAGE](state, stage) {
state.selectedStage = stage;
},
- [types.SET_DATE_RANGE](state, daysInPast) {
- state.daysInPast = daysInPast;
- const { now, past } = calculateFormattedDayInPast(daysInPast);
- state.createdBefore = now;
- state.createdAfter = past;
+ [types.SET_DATE_RANGE](state, { createdAfter, createdBefore }) {
+ state.createdBefore = createdBefore;
+ state.createdAfter = createdAfter;
},
[types.REQUEST_VALUE_STREAMS](state) {
state.valueStreams = [];
diff --git a/app/assets/javascripts/cycle_analytics/store/state.js b/app/assets/javascripts/cycle_analytics/store/state.js
index e6da3f609b2..0882db51218 100644
--- a/app/assets/javascripts/cycle_analytics/store/state.js
+++ b/app/assets/javascripts/cycle_analytics/store/state.js
@@ -1,10 +1,7 @@
-import { DEFAULT_DAYS_TO_DISPLAY } from '../constants';
-
export default () => ({
id: null,
features: {},
endpoints: {},
- daysInPast: DEFAULT_DAYS_TO_DISPLAY,
createdAfter: null,
createdBefore: null,
stages: [],
diff --git a/app/assets/javascripts/deploy_freeze/components/deploy_freeze_table.vue b/app/assets/javascripts/deploy_freeze/components/deploy_freeze_table.vue
index 8282f1d910a..77767456f76 100644
--- a/app/assets/javascripts/deploy_freeze/components/deploy_freeze_table.vue
+++ b/app/assets/javascripts/deploy_freeze/components/deploy_freeze_table.vue
@@ -1,5 +1,5 @@
<script>
-import { GlTable, GlButton, GlModalDirective, GlSprintf } from '@gitlab/ui';
+import { GlTable, GlButton, GlModal, GlModalDirective, GlSprintf } from '@gitlab/ui';
import { mapState, mapActions } from 'vuex';
import { s__ } from '~/locale';
@@ -21,21 +21,42 @@ export default {
key: 'edit',
label: s__('DeployFreeze|Edit'),
},
+ {
+ key: 'delete',
+ label: s__('DeployFreeze|Delete'),
+ },
],
translations: {
addDeployFreeze: s__('DeployFreeze|Add deploy freeze'),
+ deleteDeployFreezeTitle: s__('DeployFreeze|Delete deploy freeze?'),
+ deleteDeployFreezeMessage: s__(
+ 'DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?',
+ ),
emptyStateText: s__(
'DeployFreeze|No deploy freezes exist for this project. To add one, select %{strongStart}Add deploy freeze%{strongEnd}',
),
},
+ modal: {
+ id: 'deleteFreezePeriodModal',
+ actionPrimary: {
+ text: s__('DeployFreeze|Delete freeze period'),
+ attributes: { variant: 'danger', 'data-testid': 'modal-confirm' },
+ },
+ },
components: {
GlTable,
GlButton,
+ GlModal,
GlSprintf,
},
directives: {
GlModal: GlModalDirective,
},
+ data() {
+ return {
+ freezePeriodToDelete: null,
+ };
+ },
computed: {
...mapState(['freezePeriods']),
tableIsNotEmpty() {
@@ -46,7 +67,14 @@ export default {
this.fetchFreezePeriods();
},
methods: {
- ...mapActions(['fetchFreezePeriods', 'setFreezePeriod']),
+ ...mapActions(['fetchFreezePeriods', 'setFreezePeriod', 'deleteFreezePeriod']),
+ handleDeleteFreezePeriod(freezePeriod) {
+ this.freezePeriodToDelete = freezePeriod;
+ },
+ confirmDeleteFreezePeriod() {
+ this.deleteFreezePeriod(this.freezePeriodToDelete);
+ this.freezePeriodToDelete = null;
+ },
},
};
</script>
@@ -72,6 +100,18 @@ export default {
@click="setFreezePeriod(item)"
/>
</template>
+ <template #cell(delete)="{ item }">
+ <gl-button
+ v-gl-modal="$options.modal.id"
+ category="secondary"
+ variant="danger"
+ icon="remove"
+ :aria-label="$options.modal.actionPrimary.text"
+ :loading="item.isDeleting"
+ data-testid="delete-deploy-freeze"
+ @click="handleDeleteFreezePeriod(item)"
+ />
+ </template>
<template #empty>
<p data-testid="empty-freeze-periods" class="gl-text-center text-plain">
<gl-sprintf :message="$options.translations.emptyStateText">
@@ -90,5 +130,24 @@ export default {
>
{{ $options.translations.addDeployFreeze }}
</gl-button>
+ <gl-modal
+ :title="$options.translations.deleteDeployFreezeTitle"
+ :modal-id="$options.modal.id"
+ :action-primary="$options.modal.actionPrimary"
+ static
+ @primary="confirmDeleteFreezePeriod"
+ >
+ <template v-if="freezePeriodToDelete">
+ <gl-sprintf :message="$options.translations.deleteDeployFreezeMessage">
+ <template #start>
+ <code>{{ freezePeriodToDelete.freezeStart }}</code>
+ </template>
+ <template #end>
+ <code>{{ freezePeriodToDelete.freezeEnd }}</code>
+ </template>
+ <template #timezone>{{ freezePeriodToDelete.cronTimezone.formattedTimezone }}</template>
+ </gl-sprintf>
+ </template>
+ </gl-modal>
</div>
</template>
diff --git a/app/assets/javascripts/deploy_freeze/store/actions.js b/app/assets/javascripts/deploy_freeze/store/actions.js
index fed80b46eda..1ac6781a0e3 100644
--- a/app/assets/javascripts/deploy_freeze/store/actions.js
+++ b/app/assets/javascripts/deploy_freeze/store/actions.js
@@ -1,5 +1,6 @@
import Api from '~/api';
import createFlash from '~/flash';
+import { logError } from '~/lib/logger';
import { __ } from '~/locale';
import * as types from './mutation_types';
@@ -52,6 +53,21 @@ export const updateFreezePeriod = (store) =>
}),
);
+export const deleteFreezePeriod = ({ state, commit }, { id }) => {
+ commit(types.REQUEST_DELETE_FREEZE_PERIOD, id);
+
+ return Api.deleteFreezePeriod(state.projectId, id)
+ .then(() => commit(types.RECEIVE_DELETE_FREEZE_PERIOD_SUCCESS, id))
+ .catch((e) => {
+ createFlash({
+ message: __('Error: Unable to delete deploy freeze'),
+ });
+ commit(types.RECEIVE_DELETE_FREEZE_PERIOD_ERROR, id);
+
+ logError(`Unable to delete deploy freeze`, e);
+ });
+};
+
export const fetchFreezePeriods = ({ commit, state }) => {
commit(types.REQUEST_FREEZE_PERIODS);
diff --git a/app/assets/javascripts/deploy_freeze/store/mutation_types.js b/app/assets/javascripts/deploy_freeze/store/mutation_types.js
index 8e6fdfd4443..0fec96e2e4c 100644
--- a/app/assets/javascripts/deploy_freeze/store/mutation_types.js
+++ b/app/assets/javascripts/deploy_freeze/store/mutation_types.js
@@ -10,4 +10,8 @@ export const SET_SELECTED_ID = 'SET_SELECTED_ID';
export const SET_FREEZE_START_CRON = 'SET_FREEZE_START_CRON';
export const SET_FREEZE_END_CRON = 'SET_FREEZE_END_CRON';
+export const REQUEST_DELETE_FREEZE_PERIOD = 'REQUEST_DELETE_FREEZE_PERIOD';
+export const RECEIVE_DELETE_FREEZE_PERIOD_SUCCESS = 'RECEIVE_DELETE_FREEZE_PERIOD_SUCCESS';
+export const RECEIVE_DELETE_FREEZE_PERIOD_ERROR = 'RECEIVE_DELETE_FREEZE_PERIOD_ERROR';
+
export const RESET_MODAL = 'RESET_MODAL';
diff --git a/app/assets/javascripts/deploy_freeze/store/mutations.js b/app/assets/javascripts/deploy_freeze/store/mutations.js
index fdd1ea6e32e..151f7f39f5a 100644
--- a/app/assets/javascripts/deploy_freeze/store/mutations.js
+++ b/app/assets/javascripts/deploy_freeze/store/mutations.js
@@ -1,15 +1,28 @@
+import Vue from 'vue';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
+import { secondsToHours } from '~/lib/utils/datetime_utility';
import * as types from './mutation_types';
-const formatTimezoneName = (freezePeriod, timezoneList) =>
- convertObjectPropsToCamelCase({
+const formatTimezoneName = (freezePeriod, timezoneList) => {
+ const tz = timezoneList.find((timezone) => timezone.identifier === freezePeriod.cron_timezone);
+ return convertObjectPropsToCamelCase({
...freezePeriod,
cron_timezone: {
- formattedTimezone: timezoneList.find((tz) => tz.identifier === freezePeriod.cron_timezone)
- ?.name,
+ formattedTimezone: tz && `[UTC ${secondsToHours(tz.offset)}] ${tz.name}`,
identifier: freezePeriod.cron_timezone,
},
});
+};
+
+const setFreezePeriodIsDeleting = (state, id, isDeleting) => {
+ const freezePeriod = state.freezePeriods.find((f) => f.id === id);
+
+ if (!freezePeriod) {
+ return;
+ }
+
+ Vue.set(freezePeriod, 'isDeleting', isDeleting);
+};
export default {
[types.REQUEST_FREEZE_PERIODS](state) {
@@ -53,6 +66,18 @@ export default {
state.selectedId = id;
},
+ [types.REQUEST_DELETE_FREEZE_PERIOD](state, id) {
+ setFreezePeriodIsDeleting(state, id, true);
+ },
+
+ [types.RECEIVE_DELETE_FREEZE_PERIOD_SUCCESS](state, id) {
+ state.freezePeriods = state.freezePeriods.filter((f) => f.id !== id);
+ },
+
+ [types.RECEIVE_DELETE_FREEZE_PERIOD_ERROR](state, id) {
+ setFreezePeriodIsDeleting(state, id, false);
+ },
+
[types.RESET_MODAL](state) {
state.freezeStartCron = '';
state.freezeEndCron = '';
diff --git a/app/assets/javascripts/deprecated_jquery_dropdown/render.js b/app/assets/javascripts/deprecated_jquery_dropdown/render.js
index 167bc4c286e..37287b9d981 100644
--- a/app/assets/javascripts/deprecated_jquery_dropdown/render.js
+++ b/app/assets/javascripts/deprecated_jquery_dropdown/render.js
@@ -107,7 +107,7 @@ function createLink(data, selected, options, index) {
}
if (options.trackSuggestionClickedLabel) {
- link.setAttribute('data-track-event', 'click_text');
+ link.setAttribute('data-track-action', 'click_text');
link.setAttribute('data-track-label', options.trackSuggestionClickedLabel);
link.setAttribute('data-track-value', index);
link.setAttribute('data-track-property', slugify(data.category || 'no-category'));
diff --git a/app/assets/javascripts/deprecated_notes.js b/app/assets/javascripts/deprecated_notes.js
new file mode 100644
index 00000000000..a42b50edb8a
--- /dev/null
+++ b/app/assets/javascripts/deprecated_notes.js
@@ -0,0 +1,1746 @@
+/* eslint-disable no-restricted-properties, babel/camelcase,
+no-unused-expressions, default-case,
+consistent-return, no-alert, no-param-reassign,
+no-shadow, no-useless-escape,
+class-methods-use-this */
+
+/* global ResolveService */
+
+/*
+deprecated_notes_spec.js is the spec for the legacy, jQuery notes application. It has nothing to do with the new, fancy Vue notes app.
+ */
+
+import { GlDeprecatedSkeletonLoading as GlSkeletonLoading } from '@gitlab/ui';
+import Autosize from 'autosize';
+import $ from 'jquery';
+import Cookies from 'js-cookie';
+import { escape, uniqueId } from 'lodash';
+import Vue from 'vue';
+import '~/lib/utils/jquery_at_who';
+import AjaxCache from '~/lib/utils/ajax_cache';
+import syntaxHighlight from '~/syntax_highlight';
+import Autosave from './autosave';
+import loadAwardsHandler from './awards_handler';
+import CommentTypeToggle from './comment_type_toggle';
+import createFlash from './flash';
+import { defaultAutocompleteConfig } from './gfm_auto_complete';
+import GLForm from './gl_form';
+import axios from './lib/utils/axios_utils';
+import {
+ isInViewport,
+ getPagePath,
+ scrollToElement,
+ isMetaKey,
+ isInMRPage,
+} from './lib/utils/common_utils';
+import { localTimeAgo } from './lib/utils/datetime_utility';
+import { getLocationHash } from './lib/utils/url_utility';
+import { sprintf, s__, __ } from './locale';
+import TaskList from './task_list';
+
+window.autosize = Autosize;
+
+function normalizeNewlines(str) {
+ return str.replace(/\r\n/g, '\n');
+}
+
+const MAX_VISIBLE_COMMIT_LIST_COUNT = 3;
+const REGEX_QUICK_ACTIONS = /^\/\w+.*$/gm;
+
+export default class Notes {
+ static initialize(notes_url, note_ids, last_fetched_at, view, enableGFM) {
+ if (!this.instance) {
+ this.instance = new Notes(notes_url, note_ids, last_fetched_at, view, enableGFM);
+ }
+ }
+
+ static getInstance() {
+ return this.instance;
+ }
+
+ constructor(notes_url, note_ids, last_fetched_at, view, enableGFM = defaultAutocompleteConfig) {
+ this.updateTargetButtons = this.updateTargetButtons.bind(this);
+ this.updateComment = this.updateComment.bind(this);
+ this.visibilityChange = this.visibilityChange.bind(this);
+ this.cancelDiscussionForm = this.cancelDiscussionForm.bind(this);
+ this.onAddDiffNote = this.onAddDiffNote.bind(this);
+ this.onAddImageDiffNote = this.onAddImageDiffNote.bind(this);
+ this.setupDiscussionNoteForm = this.setupDiscussionNoteForm.bind(this);
+ this.onReplyToDiscussionNote = this.onReplyToDiscussionNote.bind(this);
+ this.removeNote = this.removeNote.bind(this);
+ this.cancelEdit = this.cancelEdit.bind(this);
+ this.updateNote = this.updateNote.bind(this);
+ this.addDiscussionNote = this.addDiscussionNote.bind(this);
+ this.addNoteError = this.addNoteError.bind(this);
+ this.addNote = this.addNote.bind(this);
+ this.resetMainTargetForm = this.resetMainTargetForm.bind(this);
+ this.refresh = this.refresh.bind(this);
+ this.keydownNoteText = this.keydownNoteText.bind(this);
+ this.toggleCommitList = this.toggleCommitList.bind(this);
+ this.postComment = this.postComment.bind(this);
+ this.clearFlashWrapper = this.clearFlash.bind(this);
+ this.onHashChange = this.onHashChange.bind(this);
+
+ this.notes_url = notes_url;
+ this.note_ids = note_ids;
+ this.enableGFM = enableGFM;
+ // Used to keep track of updated notes while people are editing things
+ this.updatedNotesTrackingMap = {};
+ this.last_fetched_at = last_fetched_at;
+ this.noteable_url = document.URL;
+ this.notesCountBadge ||
+ (this.notesCountBadge = $('.issuable-details').find('.notes-tab .badge'));
+ this.basePollingInterval = 15000;
+ this.maxPollingSteps = 4;
+
+ this.$wrapperEl = isInMRPage() ? $(document).find('.diffs') : $(document);
+ this.cleanBinding();
+ this.addBinding();
+ this.setPollingInterval();
+ this.setupMainTargetNoteForm(enableGFM);
+ this.taskList = new TaskList({
+ dataType: 'note',
+ fieldName: 'note',
+ selector: '.notes',
+ });
+ this.collapseLongCommitList();
+ this.setViewType(view);
+
+ // We are in the merge requests page so we need another edit form for Changes tab
+ if (getPagePath(1) === 'merge_requests') {
+ $('.note-edit-form').clone().addClass('mr-note-edit-form').insertAfter('.note-edit-form');
+ }
+
+ const hash = getLocationHash();
+ const $anchor = hash && document.getElementById(hash);
+
+ if ($anchor) {
+ this.loadLazyDiff({ currentTarget: $anchor });
+ }
+ }
+
+ setViewType(view) {
+ this.view = Cookies.get('diff_view') || view;
+ }
+
+ addBinding() {
+ // Edit note link
+ this.$wrapperEl.on('click', '.js-note-edit', this.showEditForm.bind(this));
+ this.$wrapperEl.on('click', '.note-edit-cancel', this.cancelEdit);
+ // Reopen and close actions for Issue/MR combined with note form submit
+ this.$wrapperEl.on('click', '.js-comment-submit-button', this.postComment);
+ this.$wrapperEl.on('click', '.js-comment-save-button', this.updateComment);
+ this.$wrapperEl.on('keyup input', '.js-note-text', this.updateTargetButtons);
+ // resolve a discussion
+ this.$wrapperEl.on('click', '.js-comment-resolve-button', this.postComment);
+ // remove a note (in general)
+ this.$wrapperEl.on('click', '.js-note-delete', this.removeNote);
+ // delete note attachment
+ this.$wrapperEl.on('click', '.js-note-attachment-delete', this.removeAttachment);
+ // update the file name when an attachment is selected
+ this.$wrapperEl.on('change', '.js-note-attachment-input', this.updateFormAttachment);
+ // reply to diff/discussion notes
+ this.$wrapperEl.on('click', '.js-discussion-reply-button', this.onReplyToDiscussionNote);
+ // add diff note
+ this.$wrapperEl.on('click', '.js-add-diff-note-button', this.onAddDiffNote);
+ // add diff note for images
+ this.$wrapperEl.on('click', '.js-add-image-diff-note-button', this.onAddImageDiffNote);
+ // hide diff note form
+ this.$wrapperEl.on('click', '.js-close-discussion-note-form', this.cancelDiscussionForm);
+ // toggle commit list
+ this.$wrapperEl.on('click', '.system-note-commit-list-toggler', this.toggleCommitList);
+
+ this.$wrapperEl.on('click', '.js-toggle-lazy-diff', this.loadLazyDiff);
+ this.$wrapperEl.on(
+ 'click',
+ '.js-toggle-lazy-diff-retry-button',
+ this.onClickRetryLazyLoad.bind(this),
+ );
+
+ // fetch notes when tab becomes visible
+ this.$wrapperEl.on('visibilitychange', this.visibilityChange);
+ // when issue status changes, we need to refresh data
+ this.$wrapperEl.on('issuable:change', this.refresh);
+ // ajax:events that happen on Form when actions like Reopen, Close are performed on Issues and MRs.
+ this.$wrapperEl.on('ajax:success', '.js-main-target-form', this.addNote);
+ this.$wrapperEl.on('ajax:success', '.js-discussion-note-form', this.addDiscussionNote);
+ this.$wrapperEl.on('ajax:success', '.js-main-target-form', this.resetMainTargetForm);
+ this.$wrapperEl.on(
+ 'ajax:complete',
+ '.js-main-target-form',
+ this.reenableTargetFormSubmitButton,
+ );
+ // when a key is clicked on the notes
+ this.$wrapperEl.on('keydown', '.js-note-text', this.keydownNoteText);
+ // When the URL fragment/hash has changed, `#note_xxx`
+ $(window).on('hashchange', this.onHashChange);
+ }
+
+ cleanBinding() {
+ this.$wrapperEl.off('click', '.js-note-edit');
+ this.$wrapperEl.off('click', '.note-edit-cancel');
+ this.$wrapperEl.off('click', '.js-note-delete');
+ this.$wrapperEl.off('click', '.js-note-attachment-delete');
+ this.$wrapperEl.off('click', '.js-discussion-reply-button');
+ this.$wrapperEl.off('click', '.js-add-diff-note-button');
+ this.$wrapperEl.off('click', '.js-add-image-diff-note-button');
+ // eslint-disable-next-line @gitlab/no-global-event-off
+ this.$wrapperEl.off('visibilitychange');
+ this.$wrapperEl.off('keyup input', '.js-note-text');
+ this.$wrapperEl.off('click', '.js-note-target-reopen');
+ this.$wrapperEl.off('click', '.js-note-target-close');
+ this.$wrapperEl.off('keydown', '.js-note-text');
+ this.$wrapperEl.off('click', '.js-comment-resolve-button');
+ this.$wrapperEl.off('click', '.system-note-commit-list-toggler');
+ this.$wrapperEl.off('click', '.js-toggle-lazy-diff');
+ this.$wrapperEl.off('click', '.js-toggle-lazy-diff-retry-button');
+ this.$wrapperEl.off('ajax:success', '.js-main-target-form');
+ this.$wrapperEl.off('ajax:success', '.js-discussion-note-form');
+ this.$wrapperEl.off('ajax:complete', '.js-main-target-form');
+ $(window).off('hashchange', this.onHashChange);
+ }
+
+ static initCommentTypeToggle(form) {
+ const dropdownTrigger = form.querySelector('.js-comment-type-dropdown .dropdown-toggle');
+ const dropdownList = form.querySelector('.js-comment-type-dropdown .dropdown-menu');
+ const noteTypeInput = form.querySelector('#note_type');
+ const submitButton = form.querySelector('.js-comment-type-dropdown .js-comment-submit-button');
+ const closeButton = form.querySelector('.js-note-target-close');
+ const reopenButton = form.querySelector('.js-note-target-reopen');
+
+ const commentTypeToggle = new CommentTypeToggle({
+ dropdownTrigger,
+ dropdownList,
+ noteTypeInput,
+ submitButton,
+ closeButton,
+ reopenButton,
+ });
+
+ commentTypeToggle.initDroplab();
+ }
+
+ keydownNoteText(e) {
+ let discussionNoteForm;
+ let editNote;
+ let myLastNote;
+ let myLastNoteEditBtn;
+ let newText;
+ let originalText;
+
+ if (isMetaKey(e)) {
+ return;
+ }
+
+ const $textarea = $(e.target);
+ // Edit previous note when UP arrow is hit
+ switch (e.which) {
+ case 38:
+ if ($textarea.val() !== '') {
+ return;
+ }
+ myLastNote = $(
+ `li.note[data-author-id='${gon.current_user_id}'][data-editable]:last`,
+ $textarea.closest('.note, .notes_holder, #notes'),
+ );
+ if (myLastNote.length) {
+ myLastNoteEditBtn = myLastNote.find('.js-note-edit');
+ return myLastNoteEditBtn.trigger('click', [true, myLastNote]);
+ }
+ break;
+ // Cancel creating diff note or editing any note when ESCAPE is hit
+ case 27:
+ discussionNoteForm = $textarea.closest('.js-discussion-note-form');
+ if (discussionNoteForm.length) {
+ if ($textarea.val() !== '') {
+ if (!window.confirm(__('Your comment will be discarded.'))) {
+ return;
+ }
+ }
+ this.removeDiscussionNoteForm(discussionNoteForm);
+ return;
+ }
+ editNote = $textarea.closest('.note');
+ if (editNote.length) {
+ originalText = $textarea.closest('form').data('originalNote');
+ newText = $textarea.val();
+ if (originalText !== newText) {
+ if (!window.confirm(__('Are you sure you want to discard this comment?'))) {
+ return;
+ }
+ }
+ return this.removeNoteEditForm(editNote);
+ }
+ }
+ }
+
+ initRefresh() {
+ if (Notes.interval) {
+ clearInterval(Notes.interval);
+ }
+ Notes.interval = setInterval(() => this.refresh(), this.pollingInterval);
+ }
+
+ refresh() {
+ if (!document.hidden) {
+ return this.getContent();
+ }
+ }
+
+ getContent() {
+ if (this.refreshing) {
+ return;
+ }
+
+ this.refreshing = true;
+
+ axios
+ .get(`${this.notes_url}?html=true`, {
+ headers: {
+ 'X-Last-Fetched-At': this.last_fetched_at,
+ },
+ })
+ .then(({ data }) => {
+ const { notes } = data;
+ this.last_fetched_at = data.last_fetched_at;
+ this.setPollingInterval(data.notes.length);
+ $.each(notes, (i, note) => this.renderNote(note));
+
+ this.refreshing = false;
+ })
+ .catch(() => {
+ this.refreshing = false;
+ });
+ }
+
+ /**
+ * Increase @pollingInterval up to 120 seconds on every function call,
+ * if `shouldReset` has a truthy value, 'null' or 'undefined' the variable
+ * will reset to @basePollingInterval.
+ *
+ * Note: this function is used to gradually increase the polling interval
+ * if there aren't new notes coming from the server
+ */
+ setPollingInterval(shouldReset) {
+ if (shouldReset == null) {
+ shouldReset = true;
+ }
+ const nthInterval = this.basePollingInterval * Math.pow(2, this.maxPollingSteps - 1);
+ if (shouldReset) {
+ this.pollingInterval = this.basePollingInterval;
+ } else if (this.pollingInterval < nthInterval) {
+ this.pollingInterval *= 2;
+ }
+ return this.initRefresh();
+ }
+
+ handleQuickActions(noteEntity) {
+ let votesBlock;
+ if (noteEntity.commands_changes) {
+ if ('merge' in noteEntity.commands_changes) {
+ Notes.checkMergeRequestStatus();
+ }
+
+ if ('emoji_award' in noteEntity.commands_changes) {
+ votesBlock = $('.js-awards-block').eq(0);
+
+ loadAwardsHandler()
+ .then((awardsHandler) => {
+ awardsHandler.addAwardToEmojiBar(votesBlock, noteEntity.commands_changes.emoji_award);
+ awardsHandler.scrollToAwards();
+ })
+ .catch(() => {
+ // ignore
+ });
+ }
+ }
+ }
+
+ setupNewNote($note) {
+ // Update datetime format on the recent note
+ localTimeAgo($note.find('.js-timeago').get(), false);
+
+ this.collapseLongCommitList();
+ this.taskList.init();
+
+ // This stops the note highlight, #note_xxx`, from being removed after real time update
+ // The `:target` selector does not re-evaluate after we replace element in the DOM
+ Notes.updateNoteTargetSelector($note);
+ this.$noteToCleanHighlight = $note;
+ }
+
+ onHashChange() {
+ if (this.$noteToCleanHighlight) {
+ Notes.updateNoteTargetSelector(this.$noteToCleanHighlight);
+ }
+
+ this.$noteToCleanHighlight = null;
+ }
+
+ static updateNoteTargetSelector($note) {
+ const hash = getLocationHash();
+ // Needs to be an explicit true/false for the jQuery `toggleClass(force)`
+ const addTargetClass = Boolean(hash && $note.filter(`#${hash}`).length > 0);
+ $note.toggleClass('target', addTargetClass);
+ }
+
+ /**
+ * Render note in main comments area.
+ *
+ * Note: for rendering inline notes use renderDiscussionNote
+ */
+ renderNote(noteEntity, $form, $notesList = $('.main-notes-list')) {
+ if (noteEntity.discussion_html) {
+ return this.renderDiscussionNote(noteEntity, $form);
+ }
+
+ if (!noteEntity.valid) {
+ if (noteEntity.errors && noteEntity.errors.commands_only) {
+ if (noteEntity.commands_changes && Object.keys(noteEntity.commands_changes).length > 0) {
+ $notesList.find('.system-note.being-posted').remove();
+ }
+ this.addFlash({
+ message: noteEntity.errors.commands_only,
+ type: 'notice',
+ parent: this.parentTimeline.get(0),
+ });
+ this.refresh();
+ }
+ return;
+ }
+
+ const $note = $notesList.find(`#note_${noteEntity.id}`);
+ if (Notes.isNewNote(noteEntity, this.note_ids)) {
+ if (isInMRPage()) {
+ return;
+ }
+
+ this.note_ids.push(noteEntity.id);
+
+ if ($notesList.length) {
+ $notesList.find('.system-note.being-posted').remove();
+ }
+ const $newNote = Notes.animateAppendNote(noteEntity.html, $notesList);
+
+ this.setupNewNote($newNote);
+ this.refresh();
+ return this.updateNotesCount(1);
+ } else if (Notes.isUpdatedNote(noteEntity, $note)) {
+ // The server can send the same update multiple times so we need to make sure to only update once per actual update.
+ const isEditing = $note.hasClass('is-editing');
+ const initialContent = normalizeNewlines($note.find('.original-note-content').text().trim());
+ const $textarea = $note.find('.js-note-text');
+ const currentContent = $textarea.val();
+ // There can be CRLF vs LF mismatches if we don't sanitize and compare the same way
+ const sanitizedNoteNote = normalizeNewlines(noteEntity.note);
+ const isTextareaUntouched =
+ currentContent === initialContent || currentContent === sanitizedNoteNote;
+
+ if (isEditing && isTextareaUntouched) {
+ $textarea.val(noteEntity.note);
+ this.updatedNotesTrackingMap[noteEntity.id] = noteEntity;
+ } else if (isEditing && !isTextareaUntouched) {
+ this.putConflictEditWarningInPlace(noteEntity, $note);
+ this.updatedNotesTrackingMap[noteEntity.id] = noteEntity;
+ } else {
+ const $updatedNote = Notes.animateUpdateNote(noteEntity.html, $note);
+ this.setupNewNote($updatedNote);
+ }
+ }
+ }
+
+ isParallelView() {
+ return Cookies.get('diff_view') === 'parallel';
+ }
+
+ /**
+ * Render note in discussion area. To render inline notes use renderDiscussionNote.
+ */
+ renderDiscussionNote(noteEntity, $form) {
+ let discussionContainer;
+ let row;
+
+ if (!Notes.isNewNote(noteEntity, this.note_ids)) {
+ return;
+ }
+ this.note_ids.push(noteEntity.id);
+
+ const form =
+ $form || $(`.js-discussion-note-form[data-discussion-id="${noteEntity.discussion_id}"]`);
+ row =
+ form.length || !noteEntity.discussion_line_code
+ ? form.closest('tr')
+ : $(`#${noteEntity.discussion_line_code}`);
+
+ if (noteEntity.on_image) {
+ row = form;
+ }
+
+ // is this the first note of discussion?
+ discussionContainer = $(`.notes[data-discussion-id="${noteEntity.discussion_id}"]`);
+ if (!discussionContainer.length) {
+ discussionContainer = form.closest('.discussion').find('.notes');
+ }
+ if (discussionContainer.length === 0) {
+ if (noteEntity.diff_discussion_html) {
+ const $discussion = $(noteEntity.diff_discussion_html).renderGFM();
+
+ if (!this.isParallelView() || row.hasClass('js-temp-notes-holder') || noteEntity.on_image) {
+ // insert the note and the reply button after the temp row
+ row.after($discussion);
+ } else {
+ // Merge new discussion HTML in
+ const $notes = $discussion.find(
+ `.notes[data-discussion-id="${noteEntity.discussion_id}"]`,
+ );
+ const contentContainerClass = $notes
+ .closest('.notes-content')
+ .attr('class')
+ .split(' ')
+ .join('.');
+
+ row
+ .find(`.${contentContainerClass} .content`)
+ .append($notes.closest('.content').children());
+ }
+ } else {
+ Notes.animateAppendNote(noteEntity.discussion_html, $('.main-notes-list'));
+ }
+ } else {
+ // append new note to all matching discussions
+ Notes.animateAppendNote(noteEntity.html, discussionContainer);
+ }
+
+ localTimeAgo(document.querySelectorAll('.js-timeago'), false);
+ Notes.checkMergeRequestStatus();
+ return this.updateNotesCount(1);
+ }
+
+ getLineHolder(changesDiscussionContainer) {
+ return $(changesDiscussionContainer)
+ .closest('.notes_holder')
+ .prevAll('.line_holder')
+ .first()
+ .get(0);
+ }
+
+ /**
+ * Called in response the main target form has been successfully submitted.
+ *
+ * Removes any errors.
+ * Resets text and preview.
+ * Resets buttons.
+ */
+ resetMainTargetForm(e) {
+ const form = $('.js-main-target-form');
+ // remove validation errors
+ form.find('.js-errors').remove();
+ // reset text and preview
+ form.find('.js-md-write-button').click();
+ form.find('.js-note-text').val('').trigger('input');
+ form.find('.js-note-text').data('autosave').reset();
+
+ const event = document.createEvent('Event');
+ event.initEvent('autosize:update', true, false);
+ form.find('.js-autosize')[0].dispatchEvent(event);
+
+ this.updateTargetButtons(e);
+ }
+
+ reenableTargetFormSubmitButton() {
+ const form = $('.js-main-target-form');
+ return form.find('.js-note-text').trigger('input');
+ }
+
+ /**
+ * Shows the main form and does some setup on it.
+ *
+ * Sets some hidden fields in the form.
+ */
+ setupMainTargetNoteForm(enableGFM) {
+ // find the form
+ const form = $('.js-new-note-form');
+ // Set a global clone of the form for later cloning
+ this.formClone = form.clone();
+ // show the form
+ this.setupNoteForm(form, enableGFM);
+ // fix classes
+ form.removeClass('js-new-note-form');
+ form.addClass('js-main-target-form');
+ form.find('#note_line_code').remove();
+ form.find('#note_position').remove();
+ form.find('#note_type').val('');
+ form.find('#note_project_id').remove();
+ form.find('#in_reply_to_discussion_id').remove();
+ this.parentTimeline = form.parents('.timeline');
+
+ if (form.length) {
+ Notes.initCommentTypeToggle(form.get(0));
+ }
+ }
+
+ /**
+ * General note form setup.
+ *
+ * deactivates the submit button when text is empty
+ * hides the preview button when text is empty
+ * set up GFM auto complete
+ * show the form
+ */
+ setupNoteForm(form, enableGFM = defaultAutocompleteConfig) {
+ this.glForm = new GLForm(form, enableGFM);
+ const textarea = form.find('.js-note-text');
+ const key = [
+ s__('NoteForm|Note'),
+ form.find('#note_noteable_type').val(),
+ form.find('#note_noteable_id').val(),
+ form.find('#note_commit_id').val(),
+ form.find('#note_type').val(),
+ form.find('#note_project_id').val(),
+ form.find('#in_reply_to_discussion_id').val(),
+
+ // LegacyDiffNote
+ form.find('#note_line_code').val(),
+
+ // DiffNote
+ form.find('#note_position').val(),
+ ];
+ return new Autosave(textarea, key);
+ }
+
+ /**
+ * Called in response to the new note form being submitted
+ *
+ * Adds new note to list.
+ */
+ addNote($form, note) {
+ return this.renderNote(note);
+ }
+
+ addNoteError($form) {
+ let formParentTimeline;
+ if ($form.hasClass('js-main-target-form')) {
+ formParentTimeline = $form.parents('.timeline');
+ } else if ($form.hasClass('js-discussion-note-form')) {
+ formParentTimeline = $form.closest('.discussion-notes').find('.notes');
+ }
+ return this.addFlash({
+ message: __(
+ 'Your comment could not be submitted! Please check your network connection and try again.',
+ ),
+ parent: formParentTimeline.get(0),
+ });
+ }
+
+ updateNoteError() {
+ createFlash({
+ message: __(
+ 'Your comment could not be updated! Please check your network connection and try again.',
+ ),
+ });
+ }
+
+ /**
+ * Called in response to the new note form being submitted
+ *
+ * Adds new note to list.
+ */
+ addDiscussionNote($form, note, isNewDiffComment) {
+ if ($form.attr('data-resolve-all') != null) {
+ const discussionId = $form.data('discussionId');
+ const mergeRequestId = $form.data('noteableIid');
+
+ if (ResolveService != null) {
+ ResolveService.toggleResolveForDiscussion(mergeRequestId, discussionId);
+ }
+ }
+
+ this.renderNote(note, $form);
+ // cleanup after successfully creating a diff/discussion note
+ if (isNewDiffComment) {
+ this.removeDiscussionNoteForm($form);
+ }
+ }
+
+ /**
+ * Called in response to the edit note form being submitted
+ *
+ * Updates the current note field.
+ */
+ updateNote(noteEntity, $targetNote) {
+ // Convert returned HTML to a jQuery object so we can modify it further
+ const $noteEntityEl = $(noteEntity.html);
+ const $noteAvatar = $noteEntityEl.find('.image-diff-avatar-link');
+ const $targetNoteBadge = $targetNote.find('.badge');
+
+ $noteAvatar.append($targetNoteBadge);
+ this.revertNoteEditForm($targetNote);
+ $noteEntityEl.renderGFM();
+ // Find the note's `li` element by ID and replace it with the updated HTML
+ const $note_li = $(`.note-row-${noteEntity.id}`);
+
+ $note_li.replaceWith($noteEntityEl);
+ this.setupNewNote($noteEntityEl);
+ }
+
+ checkContentToAllowEditing($el) {
+ const initialContent = $el.find('.original-note-content').text().trim();
+ const currentContent = $el.find('.js-note-text').val();
+ let isAllowed = true;
+
+ if (currentContent === initialContent) {
+ this.removeNoteEditForm($el);
+ } else {
+ const isWidgetVisible = isInViewport($el.get(0));
+
+ if (!isWidgetVisible) {
+ scrollToElement($el);
+ }
+
+ $el.find('.js-finish-edit-warning').show();
+ isAllowed = false;
+ }
+
+ return isAllowed;
+ }
+
+ /**
+ * Called in response to clicking the edit note link
+ *
+ * Replaces the note text with the note edit form
+ * Adds a data attribute to the form with the original content of the note for cancellations
+ */
+ showEditForm(e) {
+ e.preventDefault();
+
+ const $target = $(e.target);
+ const $editForm = $(this.getEditFormSelector($target));
+ const $note = $target.closest('.note');
+ const $currentlyEditing = $('.note.is-editing:visible');
+
+ if ($currentlyEditing.length) {
+ const isEditAllowed = this.checkContentToAllowEditing($currentlyEditing);
+
+ if (!isEditAllowed) {
+ return;
+ }
+ }
+
+ $note.find('.js-note-attachment-delete').show();
+ $editForm.addClass('current-note-edit-form');
+ $note.addClass('is-editing');
+ this.putEditFormInPlace($target);
+ }
+
+ /**
+ * Called in response to clicking the edit note link
+ *
+ * Hides edit form and restores the original note text to the editor textarea.
+ */
+ cancelEdit(e) {
+ e.preventDefault();
+ const $target = $(e.target);
+ const $note = $target.closest('.note');
+ const noteId = $note.attr('data-note-id');
+
+ this.revertNoteEditForm($target);
+
+ if (this.updatedNotesTrackingMap[noteId]) {
+ const $newNote = $(this.updatedNotesTrackingMap[noteId].html);
+ $note.replaceWith($newNote);
+ this.setupNewNote($newNote);
+ // Now that we have taken care of the update, clear it out
+ delete this.updatedNotesTrackingMap[noteId];
+ } else {
+ $note.find('.js-finish-edit-warning').hide();
+ this.removeNoteEditForm($note);
+ }
+ }
+
+ revertNoteEditForm($target) {
+ $target = $target || $('.note.is-editing:visible');
+ const selector = this.getEditFormSelector($target);
+ const $editForm = $(selector);
+
+ $editForm.insertBefore('.diffs');
+ $editForm.find('.js-comment-save-button').enable();
+ $editForm.find('.js-finish-edit-warning').hide();
+ }
+
+ getEditFormSelector($el) {
+ let selector = '.note-edit-form:not(.mr-note-edit-form)';
+
+ if ($el.parents('#diffs').length) {
+ selector = '.note-edit-form.mr-note-edit-form';
+ }
+
+ return selector;
+ }
+
+ removeNoteEditForm($note) {
+ const form = $note.find('.diffs .current-note-edit-form');
+
+ $note.removeClass('is-editing');
+ form.removeClass('current-note-edit-form');
+ form.find('.js-finish-edit-warning').hide();
+ // Replace markdown textarea text with original note text.
+ return form.find('.js-note-text').val(form.find('form.edit-note').data('originalNote'));
+ }
+
+ /**
+ * Called in response to deleting a note of any kind.
+ *
+ * Removes the actual note from view.
+ * Removes the whole discussion if the last note is being removed.
+ */
+ removeNote(e) {
+ const $note = $(e.currentTarget).closest('.note');
+ const noteElId = $note.attr('id');
+ $(`.note[id="${noteElId}"]`).each((i, el) => {
+ // A same note appears in the "Discussion" and in the "Changes" tab, we have
+ // to remove all. Using $('.note[id='noteId']') ensure we get all the notes,
+ // where $('#noteId') would return only one.
+ const $note = $(el);
+ const $notes = $note.closest('.discussion-notes');
+ const discussionId = $('.notes', $notes).data('discussionId');
+
+ $note.remove();
+
+ // check if this is the last note for this line
+ if ($notes.find('.note').length === 0) {
+ const notesTr = $notes.closest('tr');
+
+ // "Discussions" tab
+ $notes.closest('.timeline-entry').remove();
+
+ $(`.js-diff-avatars-${discussionId}`).trigger('remove.vue');
+
+ // The notes tr can contain multiple lists of notes, like on the parallel diff
+ // notesTr does not exist for image diffs
+ if (notesTr.find('.discussion-notes').length > 1 || notesTr.length === 0) {
+ const $diffFile = $notes.closest('.diff-file');
+ if ($diffFile.length > 0) {
+ const removeBadgeEvent = new CustomEvent('removeBadge.imageDiff', {
+ detail: {
+ // badgeNumber's start with 1 and index starts with 0
+ badgeNumber: $notes.index() + 1,
+ },
+ });
+
+ $diffFile[0].dispatchEvent(removeBadgeEvent);
+ }
+
+ $notes.remove();
+ } else if (notesTr.length > 0) {
+ notesTr.remove();
+ }
+ }
+ });
+
+ Notes.checkMergeRequestStatus();
+ return this.updateNotesCount(-1);
+ }
+
+ /**
+ * Called in response to clicking the delete attachment link
+ *
+ * Removes the attachment wrapper view, including image tag if it exists
+ * Resets the note editing form
+ */
+ removeAttachment() {
+ const $note = $(this).closest('.note');
+ $note.find('.note-attachment').remove();
+ $note.find('.note-body > .note-text').show();
+ $note.find('.note-header').show();
+ return $note.find('.diffs .current-note-edit-form').remove();
+ }
+
+ /**
+ * Called when clicking on the "reply" button for a diff line.
+ *
+ * Shows the note form below the notes.
+ */
+ onReplyToDiscussionNote(e) {
+ this.replyToDiscussionNote(e.target);
+ }
+
+ replyToDiscussionNote(target) {
+ const form = this.cleanForm(this.formClone.clone());
+ const replyLink = $(target).closest('.js-discussion-reply-button');
+ // insert the form after the button
+ replyLink.closest('.discussion-reply-holder').hide().after(form);
+ // show the form
+ return this.setupDiscussionNoteForm(replyLink, form);
+ }
+
+ /**
+ * Shows the diff or discussion form and does some setup on it.
+ *
+ * Sets some hidden fields in the form.
+ *
+ * Note: dataHolder must have the "discussionId" and "lineCode" data attributes set.
+ */
+ setupDiscussionNoteForm(dataHolder, form) {
+ // set up note target
+ let diffFileData = dataHolder.closest('.text-file');
+
+ if (diffFileData.length === 0) {
+ diffFileData = dataHolder.closest('.image');
+ }
+
+ const discussionID = dataHolder.data('discussionId');
+
+ if (discussionID) {
+ form.attr('data-discussion-id', discussionID);
+ form.find('#in_reply_to_discussion_id').val(discussionID);
+ }
+
+ form.find('#note_project_id').val(dataHolder.data('discussionProjectId'));
+
+ form.attr('data-line-code', dataHolder.data('lineCode'));
+ form.find('#line_type').val(dataHolder.data('lineType'));
+
+ form.find('#note_noteable_type').val(diffFileData.data('noteableType'));
+ form.find('#note_noteable_id').val(diffFileData.data('noteableId'));
+ form.find('#note_commit_id').val(diffFileData.data('commitId'));
+
+ form.find('#note_type').val(dataHolder.data('noteType'));
+
+ // LegacyDiffNote
+ form.find('#note_line_code').val(dataHolder.data('lineCode'));
+
+ // DiffNote
+ form.find('#note_position').val(dataHolder.attr('data-position'));
+
+ form.append('</div>').find('.js-close-discussion-note-form').show().removeClass('hide');
+ form.find('.js-note-target-close').remove();
+ form.find('.js-note-new-discussion').remove();
+ this.setupNoteForm(form);
+
+ form.removeClass('js-main-target-form').addClass('discussion-form js-discussion-note-form');
+
+ form.find('.js-note-text').focus();
+ form.find('.js-comment-resolve-button').attr('data-discussion-id', discussionID);
+ }
+
+ /**
+ * Called when clicking on the "add a comment" button on the side of a diff line.
+ *
+ * Inserts a temporary row for the form below the line.
+ * Sets up the form and shows it.
+ */
+ onAddDiffNote(e) {
+ e.preventDefault();
+ const link = e.currentTarget || e.target;
+ const $link = $(link);
+ const showReplyInput = !$link.hasClass('js-diff-comment-avatar');
+ this.toggleDiffNote({
+ target: $link,
+ lineType: link.dataset.lineType,
+ showReplyInput,
+ currentUsername: gon.current_username,
+ currentUserAvatar: gon.current_user_avatar_url,
+ currentUserFullname: gon.current_user_fullname,
+ });
+ }
+
+ onAddImageDiffNote(e) {
+ const $link = $(e.currentTarget || e.target);
+ const $diffFile = $link.closest('.diff-file');
+
+ const clickEvent = new CustomEvent('click.imageDiff', {
+ detail: e,
+ });
+
+ $diffFile[0].dispatchEvent(clickEvent);
+
+ // Set up comment form
+ let newForm;
+ const $noteContainer = $link.closest('.diff-viewer').find('.note-container');
+ const $form = $noteContainer.find('> .discussion-form');
+
+ if ($form.length === 0) {
+ newForm = this.cleanForm(this.formClone.clone());
+ newForm.appendTo($noteContainer);
+ } else {
+ newForm = $form;
+ }
+
+ this.setupDiscussionNoteForm($link, newForm);
+ }
+
+ toggleDiffNote({ target, lineType, forceShow, showReplyInput = false }) {
+ let addForm;
+ let newForm;
+ let noteForm;
+ let replyButton;
+ let rowCssToAdd;
+ const $link = $(target);
+ const row = $link.closest('tr');
+ const nextRow = row.next();
+ let targetRow = row;
+ if (nextRow.is('.notes_holder')) {
+ targetRow = nextRow;
+ }
+
+ const hasNotes = nextRow.is('.notes_holder');
+ addForm = false;
+ let lineTypeSelector = '';
+ rowCssToAdd =
+ '<tr class="notes_holder js-temp-notes-holder"><td class="notes-content" colspan="3"><div class="content"></div></td></tr>';
+ // In parallel view, look inside the correct left/right pane
+ if (this.isParallelView()) {
+ lineTypeSelector = `.${lineType}`;
+ rowCssToAdd =
+ '<tr class="notes_holder js-temp-notes-holder"><td class="notes_line old"></td><td class="notes-content parallel old"><div class="content"></div></td><td class="notes_line new"></td><td class="notes-content parallel new"><div class="content"></div></td></tr>';
+ }
+ const notesContentSelector = `.notes-content${lineTypeSelector} .content`;
+ let notesContent = targetRow.find(notesContentSelector);
+
+ if (hasNotes && showReplyInput) {
+ targetRow.show();
+ notesContent = targetRow.find(notesContentSelector);
+ if (notesContent.length) {
+ notesContent.show();
+ replyButton = notesContent.find('.js-discussion-reply-button:visible');
+ if (replyButton.length) {
+ this.replyToDiscussionNote(replyButton[0]);
+ } else {
+ // In parallel view, the form may not be present in one of the panes
+ noteForm = notesContent.find('.js-discussion-note-form');
+ if (noteForm.length === 0) {
+ addForm = true;
+ }
+ }
+ }
+ } else if (showReplyInput) {
+ // add a notes row and insert the form
+ row.after(rowCssToAdd);
+ targetRow = row.next();
+ notesContent = targetRow.find(notesContentSelector);
+ addForm = true;
+ } else {
+ const isCurrentlyShown = targetRow.find('.content:not(:empty)').is(':visible');
+ const isForced = forceShow === true || forceShow === false;
+ const showNow = forceShow === true || (!isCurrentlyShown && !isForced);
+
+ targetRow.toggleClass('hide', !showNow);
+ notesContent.toggleClass('hide', !showNow);
+ }
+
+ if (addForm) {
+ newForm = this.cleanForm(this.formClone.clone());
+ newForm.appendTo(notesContent);
+ // show the form
+ return this.setupDiscussionNoteForm($link, newForm);
+ }
+ }
+
+ /**
+ * Called in response to "cancel" on a diff note form.
+ *
+ * Shows the reply button again.
+ * Removes the form and if necessary it's temporary row.
+ */
+ removeDiscussionNoteForm(form) {
+ const row = form.closest('tr');
+ const glForm = form.data('glForm');
+ glForm.destroy();
+ form.find('.js-note-text').data('autosave').reset();
+ // show the reply button (will only work for replies)
+ form.prev('.discussion-reply-holder').show();
+ if (row.is('.js-temp-notes-holder')) {
+ // remove temporary row for diff lines
+ return row.remove();
+ }
+ // only remove the form
+ return form.remove();
+ }
+
+ cancelDiscussionForm(e) {
+ e.preventDefault();
+ const $form = $(e.target).closest('.js-discussion-note-form');
+ const $discussionNote = $(e.target).closest('.discussion-notes');
+
+ if ($discussionNote.length === 0) {
+ // Only send blur event when the discussion form
+ // is not part of a discussion note
+ const $diffFile = $form.closest('.diff-file');
+
+ if ($diffFile.length > 0) {
+ const blurEvent = new CustomEvent('blur.imageDiff', {
+ detail: e,
+ });
+
+ $diffFile[0].dispatchEvent(blurEvent);
+ }
+ }
+
+ return this.removeDiscussionNoteForm($form);
+ }
+
+ /**
+ * Called after an attachment file has been selected.
+ *
+ * Updates the file name for the selected attachment.
+ */
+ updateFormAttachment() {
+ const form = $(this).closest('form');
+ // get only the basename
+ const filename = $(this)
+ .val()
+ .replace(/^.*[\\\/]/, '');
+ return form.find('.js-attachment-filename').text(filename);
+ }
+
+ /**
+ * Called when the tab visibility changes
+ */
+ visibilityChange() {
+ return this.refresh();
+ }
+
+ updateTargetButtons(e) {
+ let closetext;
+ let reopentext;
+ const textarea = $(e.target);
+ const form = textarea.parents('form');
+ const reopenbtn = form.find('.js-note-target-reopen');
+ const closebtn = form.find('.js-note-target-close');
+
+ if (textarea.val().trim().length > 0) {
+ reopentext = reopenbtn.attr('data-alternative-text');
+ closetext = closebtn.attr('data-alternative-text');
+ if (reopenbtn.text() !== reopentext) {
+ reopenbtn.text(reopentext);
+ }
+ if (closebtn.text() !== closetext) {
+ closebtn.text(closetext);
+ }
+ if (reopenbtn.is(':not(.btn-comment-and-reopen)')) {
+ reopenbtn.addClass('btn-comment-and-reopen');
+ }
+ if (closebtn.is(':not(.btn-comment-and-close)')) {
+ closebtn.addClass('btn-comment-and-close');
+ }
+ } else {
+ reopentext = reopenbtn.data('originalText');
+ closetext = closebtn.data('originalText');
+ if (reopenbtn.text() !== reopentext) {
+ reopenbtn.text(reopentext);
+ }
+ if (closebtn.text() !== closetext) {
+ closebtn.text(closetext);
+ }
+ if (reopenbtn.is('.btn-comment-and-reopen')) {
+ reopenbtn.removeClass('btn-comment-and-reopen');
+ }
+ if (closebtn.is('.btn-comment-and-close')) {
+ closebtn.removeClass('btn-comment-and-close');
+ }
+ }
+ }
+
+ putEditFormInPlace($el) {
+ const $editForm = $(this.getEditFormSelector($el));
+ const $note = $el.closest('.note');
+
+ $editForm.insertAfter($note.find('.note-text'));
+
+ const $originalContentEl = $note.find('.original-note-content');
+ const originalContent = $originalContentEl.text().trim();
+ const postUrl = $originalContentEl.data('postUrl');
+ const targetId = $originalContentEl.data('targetId');
+ const targetType = $originalContentEl.data('targetType');
+
+ this.glForm = new GLForm($editForm.find('form'), this.enableGFM);
+
+ $editForm.find('form').attr('action', `${postUrl}?html=true`).attr('data-remote', 'true');
+ $editForm.find('.js-form-target-id').val(targetId);
+ $editForm.find('.js-form-target-type').val(targetType);
+ $editForm.find('.js-note-text').focus().val(originalContent);
+ $editForm.find('.js-md-write-button').trigger('click');
+ $editForm.find('.referenced-users').hide();
+ }
+
+ putConflictEditWarningInPlace(noteEntity, $note) {
+ if ($note.find('.js-conflict-edit-warning').length === 0) {
+ const open_link = `<a href="#note_${noteEntity.id}" target="_blank" rel="noopener noreferrer">`;
+ const $alert = $(`<div class="js-conflict-edit-warning alert alert-danger">
+ ${sprintf(
+ s__(
+ 'Notes|This comment has changed since you started editing, please review the %{open_link}updated comment%{close_link} to ensure information is not lost',
+ ),
+ {
+ open_link,
+ close_link: '</a>',
+ },
+ )}
+ </div>`);
+ $alert.insertAfter($note.find('.note-text'));
+ }
+ }
+
+ updateNotesCount(updateCount) {
+ return this.notesCountBadge.text(parseInt(this.notesCountBadge.text(), 10) + updateCount);
+ }
+
+ static renderPlaceholderComponent($container) {
+ const el = $container.find('.js-code-placeholder').get(0);
+ // eslint-disable-next-line no-new
+ new Vue({
+ el,
+ components: {
+ GlSkeletonLoading,
+ },
+ render(createElement) {
+ return createElement('gl-skeleton-loading');
+ },
+ });
+ }
+
+ static renderDiffContent($container, data) {
+ const { discussion_html } = data;
+ const lines = $(discussion_html).find('.line_holder');
+ lines.addClass('fade-in');
+ $container.find('.diff-content > table > tbody').prepend(lines);
+ const fileHolder = $container.find('.file-holder');
+ $container.find('.line-holder-placeholder').remove();
+ syntaxHighlight(fileHolder);
+ }
+
+ onClickRetryLazyLoad(e) {
+ const $retryButton = $(e.currentTarget);
+
+ $retryButton.prop('disabled', true);
+
+ return this.loadLazyDiff(e).then(() => {
+ $retryButton.prop('disabled', false);
+ });
+ }
+
+ loadLazyDiff(e) {
+ const $container = $(e.currentTarget).closest('.js-toggle-container');
+ Notes.renderPlaceholderComponent($container);
+
+ $container.find('.js-toggle-lazy-diff').removeClass('js-toggle-lazy-diff');
+
+ const $tableEl = $container.find('tbody');
+ if ($tableEl.length === 0) return;
+
+ const fileHolder = $container.find('.file-holder');
+ const url = fileHolder.data('linesPath');
+
+ const $errorContainer = $container.find('.js-error-lazy-load-diff');
+ const $successContainer = $container.find('.js-success-lazy-load');
+
+ /**
+ * We only fetch resolved discussions.
+ * Unresolved discussions don't have an endpoint being provided.
+ */
+ if (url) {
+ return axios
+ .get(url)
+ .then(({ data }) => {
+ // Reset state in case last request returned error
+ $successContainer.removeClass('hidden');
+ $errorContainer.addClass('hidden');
+
+ Notes.renderDiffContent($container, data);
+ })
+ .catch(() => {
+ $successContainer.addClass('hidden');
+ $errorContainer.removeClass('hidden');
+ });
+ }
+ return Promise.resolve();
+ }
+
+ toggleCommitList(e) {
+ const $element = $(e.currentTarget);
+ const $closestSystemCommitList = $element.siblings('.system-note-commit-list');
+ const $svgChevronUpElement = $element.find('svg.js-chevron-up');
+ const $svgChevronDownElement = $element.find('svg.js-chevron-down');
+
+ $svgChevronUpElement.toggleClass('gl-display-none');
+ $svgChevronDownElement.toggleClass('gl-display-none');
+
+ $closestSystemCommitList.toggleClass('hide-shade');
+ }
+
+ /**
+ * Scans system notes with `ul` elements in system note body
+ * then collapse long commit list pushed by user to make it less
+ * intrusive.
+ */
+ collapseLongCommitList() {
+ const systemNotes = $('#notes-list').find('li.system-note').has('ul');
+
+ $.each(systemNotes, (index, systemNote) => {
+ const $systemNote = $(systemNote);
+ const headerMessage = $systemNote
+ .find('.note-text')
+ .find('p')
+ .first()
+ .text()
+ .replace(':', '');
+
+ $systemNote.find('.note-header .system-note-message').html(headerMessage);
+
+ if ($systemNote.find('li').length > MAX_VISIBLE_COMMIT_LIST_COUNT) {
+ $systemNote.find('.note-text').addClass('system-note-commit-list');
+ $systemNote.find('.system-note-commit-list-toggler').show();
+ } else {
+ $systemNote.find('.note-text').addClass('system-note-commit-list hide-shade');
+ }
+ });
+ }
+
+ addFlash(...flashParams) {
+ this.flashContainer = createFlash(...flashParams);
+ }
+
+ clearFlash() {
+ if (this.flashContainer) {
+ this.flashContainer.style.display = 'none';
+ this.flashContainer = null;
+ }
+ }
+
+ cleanForm($form) {
+ // Remove JS classes that are not needed here
+ $form.find('.js-comment-type-dropdown').removeClass('btn-group');
+
+ // Remove dropdown
+ $form.find('.dropdown-menu').remove();
+
+ return $form;
+ }
+
+ /**
+ * Check if note does not exist on page
+ */
+ static isNewNote(noteEntity, noteIds) {
+ return $.inArray(noteEntity.id, noteIds) === -1;
+ }
+
+ /**
+ * Check if $note already contains the `noteEntity` content
+ */
+ static isUpdatedNote(noteEntity, $note) {
+ // There can be CRLF vs LF mismatches if we don't sanitize and compare the same way
+ const sanitizedNoteEntityText = normalizeNewlines(noteEntity.note.trim());
+ const currentNoteText = normalizeNewlines(
+ $note.find('.original-note-content').first().text().trim(),
+ );
+ return sanitizedNoteEntityText !== currentNoteText;
+ }
+
+ static checkMergeRequestStatus() {
+ if (getPagePath(1) === 'merge_requests' && gl.mrWidget) {
+ gl.mrWidget.checkStatus();
+ }
+ }
+
+ static animateAppendNote(noteHtml, $notesList) {
+ const $note = $(noteHtml);
+
+ $note.addClass('fade-in-full').renderGFM();
+ $notesList.append($note);
+ return $note;
+ }
+
+ static animateUpdateNote(noteHtml, $note) {
+ const $updatedNote = $(noteHtml);
+
+ $updatedNote.addClass('fade-in').renderGFM();
+ $note.replaceWith($updatedNote);
+ return $updatedNote;
+ }
+
+ /**
+ * Get data from Form attributes to use for saving/submitting comment.
+ */
+ getFormData($form) {
+ const content = $form.find('.js-note-text').val();
+ return {
+ // eslint-disable-next-line no-jquery/no-serialize
+ formData: $form.serialize(),
+ formContent: escape(content),
+ formAction: $form.attr('action'),
+ formContentOriginal: content,
+ };
+ }
+
+ /**
+ * Identify if comment has any quick actions
+ */
+ hasQuickActions(formContent) {
+ return REGEX_QUICK_ACTIONS.test(formContent);
+ }
+
+ /**
+ * Remove quick actions and leave comment with pure message
+ */
+ stripQuickActions(formContent) {
+ return formContent.replace(REGEX_QUICK_ACTIONS, '').trim();
+ }
+
+ /**
+ * Gets appropriate description from quick actions found in provided `formContent`
+ */
+ getQuickActionDescription(formContent, availableQuickActions = []) {
+ let tempFormContent;
+
+ // Identify executed quick actions from `formContent`
+ const executedCommands = availableQuickActions.filter((command) => {
+ const commandRegex = new RegExp(`/${command.name}`);
+ return commandRegex.test(formContent);
+ });
+
+ if (executedCommands && executedCommands.length) {
+ if (executedCommands.length > 1) {
+ tempFormContent = __('Applying multiple commands');
+ } else {
+ const commandDescription = executedCommands[0].description.toLowerCase();
+ tempFormContent = sprintf(__('Applying command to %{commandDescription}'), {
+ commandDescription,
+ });
+ }
+ } else {
+ tempFormContent = __('Applying command');
+ }
+
+ return tempFormContent;
+ }
+
+ /**
+ * Create placeholder note DOM element populated with comment body
+ * that we will show while comment is being posted.
+ * Once comment is _actually_ posted on server, we will have final element
+ * in response that we will show in place of this temporary element.
+ */
+ createPlaceholderNote({
+ formContent,
+ uniqueId,
+ isDiscussionNote,
+ currentUsername,
+ currentUserFullname,
+ currentUserAvatar,
+ }) {
+ const discussionClass = isDiscussionNote ? 'discussion' : '';
+ const $tempNote = $(
+ `<li id="${uniqueId}" class="note being-posted fade-in-half timeline-entry">
+ <div class="timeline-entry-inner">
+ <div class="timeline-icon">
+ <a href="/${escape(currentUsername)}">
+ <img class="avatar s40" src="${currentUserAvatar}" />
+ </a>
+ </div>
+ <div class="timeline-content ${discussionClass}">
+ <div class="note-header">
+ <div class="note-header-info">
+ <a href="/${escape(currentUsername)}">
+ <span class="d-none d-sm-inline-block bold">${escape(currentUsername)}</span>
+ <span class="note-headline-light">${escape(currentUsername)}</span>
+ </a>
+ </div>
+ </div>
+ <div class="note-body">
+ <div class="note-text">
+ <p>${formContent}</p>
+ </div>
+ </div>
+ </div>
+ </div>
+ </li>`,
+ );
+
+ $tempNote.find('.d-none.d-sm-inline-block').text(escape(currentUserFullname));
+ $tempNote.find('.note-headline-light').text(`@${escape(currentUsername)}`);
+
+ return $tempNote;
+ }
+
+ /**
+ * Create Placeholder System Note DOM element populated with quick action description
+ */
+ createPlaceholderSystemNote({ formContent, uniqueId }) {
+ const $tempNote = $(
+ `<li id="${uniqueId}" class="note system-note timeline-entry being-posted fade-in-half">
+ <div class="timeline-entry-inner">
+ <div class="timeline-content">
+ <i>${formContent}</i>
+ </div>
+ </div>
+ </li>`,
+ );
+
+ return $tempNote;
+ }
+
+ /**
+ * This method does following tasks step-by-step whenever a new comment
+ * is submitted by user (both main thread comments as well as discussion comments).
+ *
+ * 1) Get Form metadata
+ * 2) Identify comment type; a) Main thread b) Discussion thread c) Discussion resolve
+ * 3) Build temporary placeholder element (using `createPlaceholderNote`)
+ * 4) Show placeholder note on UI
+ * 5) Perform network request to submit the note using `axios.post`
+ * a) If request is successfully completed
+ * 1. Remove placeholder element
+ * 2. Show submitted Note element
+ * 3. Perform post-submit errands
+ * a. Mark discussion as resolved if comment submission was for resolve.
+ * b. Reset comment form to original state.
+ * b) If request failed
+ * 1. Remove placeholder element
+ * 2. Show error Flash message about failure
+ */
+ postComment(e) {
+ e.preventDefault();
+
+ // Get Form metadata
+ const $submitBtn = $(e.target);
+ $submitBtn.prop('disabled', true);
+ let $form = $submitBtn.parents('form');
+ const $closeBtn = $form.find('.js-note-target-close');
+ const isDiscussionNote =
+ $submitBtn.parent().find('li.droplab-item-selected').attr('id') === 'discussion';
+ const isMainForm = $form.hasClass('js-main-target-form');
+ const isDiscussionForm = $form.hasClass('js-discussion-note-form');
+ const isDiscussionResolve = $submitBtn.hasClass('js-comment-resolve-button');
+ const { formData, formContent, formAction, formContentOriginal } = this.getFormData($form);
+ let noteUniqueId;
+ let systemNoteUniqueId;
+ let hasQuickActions = false;
+ let $notesContainer;
+ let tempFormContent;
+
+ // Get reference to notes container based on type of comment
+ if (isDiscussionForm) {
+ $notesContainer = $form.parent('.discussion-notes').find('.notes');
+ } else if (isMainForm) {
+ $notesContainer = $('ul.main-notes-list');
+ }
+
+ // If comment is to resolve discussion, disable submit buttons while
+ // comment posting is finished.
+ if (isDiscussionResolve) {
+ $form.find('.js-comment-submit-button').disable();
+ }
+
+ tempFormContent = formContent;
+ if (this.glForm.supportsQuickActions && this.hasQuickActions(formContent)) {
+ tempFormContent = this.stripQuickActions(formContent);
+ hasQuickActions = true;
+ }
+
+ // Show placeholder note
+ if (tempFormContent) {
+ noteUniqueId = uniqueId('tempNote_');
+ $notesContainer.append(
+ this.createPlaceholderNote({
+ formContent: tempFormContent,
+ uniqueId: noteUniqueId,
+ isDiscussionNote,
+ currentUsername: gon.current_username,
+ currentUserFullname: gon.current_user_fullname,
+ currentUserAvatar: gon.current_user_avatar_url,
+ }),
+ );
+ }
+
+ // Show placeholder system note
+ if (hasQuickActions) {
+ systemNoteUniqueId = uniqueId('tempSystemNote_');
+ $notesContainer.append(
+ this.createPlaceholderSystemNote({
+ formContent: this.getQuickActionDescription(
+ formContent,
+ AjaxCache.get(gl.GfmAutoComplete.dataSources.commands),
+ ),
+ uniqueId: systemNoteUniqueId,
+ }),
+ );
+ }
+
+ // Clear the form textarea
+ if ($notesContainer.length) {
+ if (isMainForm) {
+ this.resetMainTargetForm(e);
+ } else if (isDiscussionForm) {
+ this.removeDiscussionNoteForm($form);
+ }
+ }
+
+ $closeBtn.text($closeBtn.data('originalText'));
+
+ // Make request to submit comment on server
+ return axios
+ .post(`${formAction}?html=true`, formData)
+ .then((res) => {
+ const note = res.data;
+
+ $submitBtn.prop('disabled', false);
+ // Submission successful! remove placeholder
+ $notesContainer.find(`#${noteUniqueId}`).remove();
+
+ const $diffFile = $form.closest('.diff-file');
+ if ($diffFile.length > 0) {
+ const blurEvent = new CustomEvent('blur.imageDiff', {
+ detail: e,
+ });
+
+ $diffFile[0].dispatchEvent(blurEvent);
+ }
+
+ // Reset cached commands list when command is applied
+ if (hasQuickActions) {
+ $form.find('textarea.js-note-text').trigger('clear-commands-cache.atwho');
+ }
+
+ // Clear previous form errors
+ this.clearFlashWrapper();
+
+ // Check if this was discussion comment
+ if (isDiscussionForm) {
+ // Remove flash-container
+ $notesContainer.find('.flash-container').remove();
+
+ // If comment intends to resolve discussion, do the same.
+ if (isDiscussionResolve) {
+ $form
+ .attr('data-discussion-id', $submitBtn.data('discussionId'))
+ .attr('data-resolve-all', 'true')
+ .attr('data-project-path', $submitBtn.data('projectPath'));
+ }
+
+ // Show final note element on UI
+ const isNewDiffComment = $notesContainer.length === 0;
+ this.addDiscussionNote($form, note, isNewDiffComment);
+
+ if (isNewDiffComment) {
+ // Add image badge, avatar badge and toggle discussion badge for new image diffs
+ const notePosition = $form.find('#note_position').val();
+ if ($diffFile.length > 0 && notePosition.length > 0) {
+ const { x, y, width, height } = JSON.parse(notePosition);
+ const addBadgeEvent = new CustomEvent('addBadge.imageDiff', {
+ detail: {
+ x,
+ y,
+ width,
+ height,
+ noteId: `note_${note.id}`,
+ discussionId: note.discussion_id,
+ },
+ });
+
+ $diffFile[0].dispatchEvent(addBadgeEvent);
+ }
+ }
+
+ // append flash-container to the Notes list
+ if ($notesContainer.length) {
+ $notesContainer.append('<div class="flash-container" style="display: none;"></div>');
+ }
+ } else if (isMainForm) {
+ // Check if this was main thread comment
+ // Show final note element on UI and perform form and action buttons cleanup
+ this.addNote($form, note);
+ this.reenableTargetFormSubmitButton(e);
+ }
+
+ if (note.commands_changes) {
+ this.handleQuickActions(note);
+ }
+
+ $form.trigger('ajax:success', [note]);
+ })
+ .catch(() => {
+ // Submission failed, remove placeholder note and show Flash error message
+ $notesContainer.find(`#${noteUniqueId}`).remove();
+ $submitBtn.prop('disabled', false);
+ const blurEvent = new CustomEvent('blur.imageDiff', {
+ detail: e,
+ });
+
+ const closestDiffFile = $form.closest('.diff-file');
+
+ if (closestDiffFile.length) {
+ closestDiffFile[0].dispatchEvent(blurEvent);
+ }
+
+ if (hasQuickActions) {
+ $notesContainer.find(`#${systemNoteUniqueId}`).remove();
+ }
+
+ // Show form again on UI on failure
+ if (isDiscussionForm && $notesContainer.length) {
+ const replyButton = $notesContainer.parent().find('.js-discussion-reply-button');
+ this.replyToDiscussionNote(replyButton[0]);
+ $form = $notesContainer.parent().find('form');
+ }
+
+ $form.find('.js-note-text').val(formContentOriginal);
+ this.reenableTargetFormSubmitButton(e);
+ this.addNoteError($form);
+ });
+ }
+
+ /**
+ * This method does following tasks step-by-step whenever an existing comment
+ * is updated by user (both main thread comments as well as discussion comments).
+ *
+ * 1) Get Form metadata
+ * 2) Update note element with new content
+ * 3) Perform network request to submit the updated note using `axios.post`
+ * a) If request is successfully completed
+ * 1. Show submitted Note element
+ * b) If request failed
+ * 1. Revert Note element to original content
+ * 2. Show error Flash message about failure
+ */
+ updateComment(e) {
+ e.preventDefault();
+
+ // Get Form metadata
+ const $submitBtn = $(e.target);
+ const $form = $submitBtn.parents('form');
+ const $closeBtn = $form.find('.js-note-target-close');
+ const $editingNote = $form.parents('.note.is-editing');
+ const $noteBody = $editingNote.find('.js-task-list-container');
+ const $noteBodyText = $noteBody.find('.note-text');
+ const { formData, formContent, formAction } = this.getFormData($form);
+
+ // Cache original comment content
+ const cachedNoteBodyText = $noteBodyText.html();
+
+ // Show updated comment content temporarily
+ $noteBodyText.html(formContent);
+ $editingNote.removeClass('is-editing fade-in-full').addClass('being-posted fade-in-half');
+ $editingNote
+ .find('.note-headline-meta a')
+ .html('<span class="spinner align-text-bottom"></span>');
+
+ // Make request to update comment on server
+ axios
+ .post(`${formAction}?html=true`, formData)
+ .then(({ data }) => {
+ // Submission successful! render final note element
+ this.updateNote(data, $editingNote);
+ })
+ .catch(() => {
+ // Submission failed, revert back to original note
+ $noteBodyText.html(escape(cachedNoteBodyText));
+ $editingNote.removeClass('being-posted fade-in');
+ $editingNote.find('.gl-spinner').remove();
+
+ // Show Flash message about failure
+ this.updateNoteError();
+ });
+
+ return $closeBtn.text($closeBtn.data('originalText'));
+ }
+}
diff --git a/app/assets/javascripts/design_management/components/design_notes/design_reply_form.vue b/app/assets/javascripts/design_management/components/design_notes/design_reply_form.vue
index 336ce714a05..818299e36bd 100644
--- a/app/assets/javascripts/design_management/components/design_notes/design_reply_form.vue
+++ b/app/assets/javascripts/design_management/components/design_notes/design_reply_form.vue
@@ -123,7 +123,7 @@ export default {
category="primary"
variant="confirm"
type="submit"
- data-track-event="click_button"
+ data-track-action="click_button"
data-qa-selector="save_comment_button"
@click="$emit('submit-form')"
>
diff --git a/app/assets/javascripts/design_management/components/design_scaler.vue b/app/assets/javascripts/design_management/components/design_scaler.vue
index c9273f97bed..af3d4453a6a 100644
--- a/app/assets/javascripts/design_management/components/design_scaler.vue
+++ b/app/assets/javascripts/design_management/components/design_scaler.vue
@@ -1,16 +1,21 @@
<script>
import { GlButtonGroup, GlButton } from '@gitlab/ui';
-const SCALE_STEP_SIZE = 0.2;
const DEFAULT_SCALE = 1;
const MIN_SCALE = 1;
-const MAX_SCALE = 2;
+const ZOOM_LEVELS = 5;
export default {
components: {
GlButtonGroup,
GlButton,
},
+ props: {
+ maxScale: {
+ type: Number,
+ required: true,
+ },
+ },
data() {
return {
scale: DEFAULT_SCALE,
@@ -24,7 +29,10 @@ export default {
return this.scale === DEFAULT_SCALE;
},
disableIncrease() {
- return this.scale >= MAX_SCALE;
+ return this.scale >= this.maxScale;
+ },
+ stepSize() {
+ return (this.maxScale - MIN_SCALE) / ZOOM_LEVELS;
},
},
methods: {
@@ -37,10 +45,10 @@ export default {
this.$emit('scale', this.scale);
},
incrementScale() {
- this.setScale(this.scale + SCALE_STEP_SIZE);
+ this.setScale(Math.min(this.scale + this.stepSize, this.maxScale));
},
decrementScale() {
- this.setScale(this.scale - SCALE_STEP_SIZE);
+ this.setScale(Math.max(this.scale - this.stepSize, MIN_SCALE));
},
resetScale() {
this.setScale(DEFAULT_SCALE);
diff --git a/app/assets/javascripts/design_management/components/design_sidebar.vue b/app/assets/javascripts/design_management/components/design_sidebar.vue
index efa1ef2107a..ced76eb4843 100644
--- a/app/assets/javascripts/design_management/components/design_sidebar.vue
+++ b/app/assets/javascripts/design_management/components/design_sidebar.vue
@@ -202,7 +202,7 @@ export default {
data-testid="resolved-discussion"
@error="$emit('onDesignDiscussionError', $event)"
@updateNoteError="$emit('updateNoteError', $event)"
- @openForm="updateDiscussionWithOpenForm"
+ @open-form="updateDiscussionWithOpenForm"
@click.native.stop="updateActiveDiscussion(discussion.notes[0].id)"
/>
</gl-collapse>
diff --git a/app/assets/javascripts/design_management/components/image.vue b/app/assets/javascripts/design_management/components/image.vue
index 8ab94cd2c4b..5354c7756f5 100644
--- a/app/assets/javascripts/design_management/components/image.vue
+++ b/app/assets/javascripts/design_management/components/image.vue
@@ -57,6 +57,7 @@ export default {
methods: {
onImgLoad() {
requestIdleCallback(this.setBaseImageSize, { timeout: 1000 });
+ requestIdleCallback(this.setImageNaturalScale, { timeout: 1000 });
performanceMarkAndMeasure({
measures: [
{
@@ -79,6 +80,27 @@ export default {
};
this.onResize({ width: this.baseImageSize.width, height: this.baseImageSize.height });
},
+ setImageNaturalScale() {
+ const { contentImg } = this.$refs;
+
+ if (!contentImg) {
+ return;
+ }
+
+ const { naturalHeight, naturalWidth } = contentImg;
+
+ // In case image 404s
+ if (naturalHeight === 0 || naturalWidth === 0) {
+ return;
+ }
+
+ const { height, width } = this.baseImageSize;
+
+ this.$parent.$emit(
+ 'setMaxScale',
+ Math.round(((height + width) / (naturalHeight + naturalWidth)) * 100) / 100,
+ );
+ },
onResize({ width, height }) {
this.$emit('resize', { width, height });
},
diff --git a/app/assets/javascripts/design_management/graphql/fragments/version.fragment.graphql b/app/assets/javascripts/design_management/graphql/fragments/version.fragment.graphql
index 7eb40b12f51..b715633a9f2 100644
--- a/app/assets/javascripts/design_management/graphql/fragments/version.fragment.graphql
+++ b/app/assets/javascripts/design_management/graphql/fragments/version.fragment.graphql
@@ -1,4 +1,11 @@
fragment VersionListItem on DesignVersion {
id
sha
+ createdAt
+ author {
+ __typename
+ id
+ name
+ avatarUrl
+ }
}
diff --git a/app/assets/javascripts/design_management/graphql/mutations/upload_design.mutation.graphql b/app/assets/javascripts/design_management/graphql/mutations/upload_design.mutation.graphql
index 84aeb374351..111f5ac18a7 100644
--- a/app/assets/javascripts/design_management/graphql/mutations/upload_design.mutation.graphql
+++ b/app/assets/javascripts/design_management/graphql/mutations/upload_design.mutation.graphql
@@ -1,13 +1,15 @@
#import "../fragments/design.fragment.graphql"
+#import "../fragments/version.fragment.graphql"
mutation uploadDesign($files: [Upload!]!, $projectPath: ID!, $iid: ID!) {
designManagementUpload(input: { projectPath: $projectPath, iid: $iid, files: $files }) {
designs {
...DesignItem
versions {
+ __typename
nodes {
- id
- sha
+ __typename
+ ...VersionListItem
}
}
}
diff --git a/app/assets/javascripts/design_management/pages/design/index.vue b/app/assets/javascripts/design_management/pages/design/index.vue
index 48ee7068809..38ea5406c02 100644
--- a/app/assets/javascripts/design_management/pages/design/index.vue
+++ b/app/assets/javascripts/design_management/pages/design/index.vue
@@ -46,6 +46,7 @@ import {
import { trackDesignDetailView, servicePingDesignDetailView } from '../../utils/tracking';
const DEFAULT_SCALE = 1;
+const DEFAULT_MAX_SCALE = 2;
export default {
components: {
@@ -96,6 +97,7 @@ export default {
scale: DEFAULT_SCALE,
resolvedDiscussionsExpanded: false,
prevCurrentUserTodos: null,
+ maxScale: DEFAULT_MAX_SCALE,
};
},
apollo: {
@@ -309,9 +311,7 @@ export default {
this.isLatestVersion,
);
- if (this.glFeatures.usageDataDesignAction) {
- servicePingDesignDetailView();
- }
+ servicePingDesignDetailView();
},
updateActiveDiscussion(id, source = ACTIVE_DISCUSSION_SOURCE_TYPES.discussion) {
this.$apollo.mutate({
@@ -330,6 +330,9 @@ export default {
toggleResolvedComments() {
this.resolvedDiscussionsExpanded = !this.resolvedDiscussionsExpanded;
},
+ setMaxScale(event) {
+ this.maxScale = 1 / event;
+ },
},
createImageDiffNoteMutation,
DESIGNS_ROUTE_NAME,
@@ -378,12 +381,13 @@ export default {
@openCommentForm="openCommentForm"
@closeCommentForm="closeCommentForm"
@moveNote="onMoveNote"
+ @setMaxScale="setMaxScale"
/>
<div
class="design-scaler-wrapper gl-absolute gl-mb-6 gl-display-flex gl-justify-content-center gl-align-items-center"
>
- <design-scaler @scale="scale = $event" />
+ <design-scaler :max-scale="maxScale" @scale="scale = $event" />
</div>
</div>
<design-sidebar
diff --git a/app/assets/javascripts/design_management/pages/index.vue b/app/assets/javascripts/design_management/pages/index.vue
index ad557f64ce4..e66ae822a34 100644
--- a/app/assets/javascripts/design_management/pages/index.vue
+++ b/app/assets/javascripts/design_management/pages/index.vue
@@ -140,6 +140,9 @@ export default {
this.$el.scrollIntoView();
}
},
+ beforeDestroy() {
+ document.removeEventListener('paste', this.onDesignPaste);
+ },
methods: {
resetFilesToBeSaved() {
this.filesToBeSaved = [];
diff --git a/app/assets/javascripts/design_management/utils/design_management_utils.js b/app/assets/javascripts/design_management/utils/design_management_utils.js
index 05b220801f2..7470f3d259b 100644
--- a/app/assets/javascripts/design_management/utils/design_management_utils.js
+++ b/app/assets/javascripts/design_management/utils/design_management_utils.js
@@ -85,6 +85,13 @@ export const designUploadOptimisticResponse = (files) => {
__typename: 'DesignVersion',
id: -uniqueId(),
sha: -uniqueId(),
+ createdAt: '',
+ author: {
+ __typename: 'UserCore',
+ id: -uniqueId(),
+ name: '',
+ avatarUrl: '',
+ },
},
},
}));
diff --git a/app/assets/javascripts/design_management/utils/error_messages.js b/app/assets/javascripts/design_management/utils/error_messages.js
index e7b2c814bb3..afee7e81791 100644
--- a/app/assets/javascripts/design_management/utils/error_messages.js
+++ b/app/assets/javascripts/design_management/utils/error_messages.js
@@ -1,3 +1,4 @@
+/* eslint-disable @gitlab/require-string-literal-i18n-helpers */
import { __, s__, n__, sprintf } from '~/locale';
export const ADD_DISCUSSION_COMMENT_ERROR = s__(
diff --git a/app/assets/javascripts/diffs/components/app.vue b/app/assets/javascripts/diffs/components/app.vue
index d03b5cbc26b..a2ea42e963c 100644
--- a/app/assets/javascripts/diffs/components/app.vue
+++ b/app/assets/javascripts/diffs/components/app.vue
@@ -1,9 +1,8 @@
<script>
-import { GlLoadingIcon, GlPagination, GlSprintf } from '@gitlab/ui';
+import { GlLoadingIcon, GlPagination, GlSprintf, GlAlert } from '@gitlab/ui';
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
import Mousetrap from 'mousetrap';
import { mapState, mapGetters, mapActions } from 'vuex';
-import { DynamicScroller, DynamicScrollerItem } from 'vendor/vue-virtual-scroller';
import api from '~/api';
import {
keysFor,
@@ -47,7 +46,6 @@ import {
import diffsEventHub from '../event_hub';
import { reviewStatuses } from '../utils/file_reviews';
import { diffsApp } from '../utils/performance';
-import { fileByFile } from '../utils/preferences';
import { queueRedisHllEvents } from '../utils/queue_events';
import CollapsedFilesWarning from './collapsed_files_warning.vue';
import CommitWidget from './commit_widget.vue';
@@ -55,13 +53,18 @@ import CompareVersions from './compare_versions.vue';
import DiffFile from './diff_file.vue';
import HiddenFilesWarning from './hidden_files_warning.vue';
import NoChanges from './no_changes.vue';
-import PreRenderer from './pre_renderer.vue';
import TreeList from './tree_list.vue';
-import VirtualScrollerScrollSync from './virtual_scroller_scroll_sync';
export default {
name: 'DiffsApp',
components: {
+ DynamicScroller: () =>
+ import('vendor/vue-virtual-scroller').then(({ DynamicScroller }) => DynamicScroller),
+ DynamicScrollerItem: () =>
+ import('vendor/vue-virtual-scroller').then(({ DynamicScrollerItem }) => DynamicScrollerItem),
+ PreRenderer: () => import('./pre_renderer.vue').then((PreRenderer) => PreRenderer),
+ VirtualScrollerScrollSync: () =>
+ import('./virtual_scroller_scroll_sync').then((VSSSync) => VSSSync),
CompareVersions,
DiffFile,
NoChanges,
@@ -73,11 +76,8 @@ export default {
PanelResizer,
GlPagination,
GlSprintf,
- DynamicScroller,
- DynamicScrollerItem,
- PreRenderer,
- VirtualScrollerScrollSync,
MrWidgetHowToMergeModal,
+ GlAlert,
},
alerts: {
ALERT_OVERFLOW_HIDDEN,
@@ -189,25 +189,24 @@ export default {
treeWidth,
diffFilesLength: 0,
virtualScrollCurrentIndex: -1,
+ subscribedToVirtualScrollingEvents: false,
};
},
computed: {
- ...mapState({
- isLoading: (state) => state.diffs.isLoading,
- isBatchLoading: (state) => state.diffs.isBatchLoading,
- diffFiles: (state) => state.diffs.diffFiles,
- diffViewType: (state) => state.diffs.diffViewType,
- commit: (state) => state.diffs.commit,
- renderOverflowWarning: (state) => state.diffs.renderOverflowWarning,
- numTotalFiles: (state) => state.diffs.realSize,
- numVisibleFiles: (state) => state.diffs.size,
- plainDiffPath: (state) => state.diffs.plainDiffPath,
- emailPatchPath: (state) => state.diffs.emailPatchPath,
- retrievingBatches: (state) => state.diffs.retrievingBatches,
+ ...mapState('diffs', {
+ numTotalFiles: 'realSize',
+ numVisibleFiles: 'size',
}),
...mapState('diffs', [
'showTreeList',
'isLoading',
+ 'diffFiles',
+ 'diffViewType',
+ 'commit',
+ 'renderOverflowWarning',
+ 'plainDiffPath',
+ 'emailPatchPath',
+ 'retrievingBatches',
'startVersion',
'latestDiff',
'currentDiffFileId',
@@ -227,8 +226,9 @@ export default {
'isParallelView',
'currentDiffIndex',
'isVirtualScrollingEnabled',
+ 'isBatchLoading',
+ 'isBatchLoadingError',
]),
- ...mapGetters('batchComments', ['draftsCount']),
...mapGetters(['isNotesFetched', 'getNoteableData']),
diffs() {
if (!this.viewDiffsFileByFile) {
@@ -316,6 +316,7 @@ export default {
}
this.adjustView();
+ this.subscribeToVirtualScrollingEvents();
},
isLoading: 'adjustView',
renderFileTree: 'adjustView',
@@ -330,7 +331,7 @@ export default {
projectPath: this.projectPath,
dismissEndpoint: this.dismissEndpoint,
showSuggestPopover: this.showSuggestPopover,
- viewDiffsFileByFile: fileByFile(this.fileByFileUserPreference),
+ viewDiffsFileByFile: this.fileByFileUserPreference || false,
defaultSuggestionCommitMessage: this.defaultSuggestionCommitMessage,
mrReviews: this.rehydratedMrReviews,
});
@@ -349,11 +350,6 @@ export default {
this.setHighlightedRow(id.split('diff-content').pop().slice(1));
}
- if (window.gon?.features?.diffsVirtualScrolling) {
- diffsEventHub.$on('scrollToFileHash', this.scrollVirtualScrollerToFileHash);
- diffsEventHub.$on('scrollToIndex', this.scrollVirtualScrollerToIndex);
- }
-
if (window.gon?.features?.diffSettingsUsageData) {
const events = [];
@@ -383,6 +379,8 @@ export default {
queueRedisHllEvents(events);
}
+
+ this.subscribeToVirtualScrollingEvents();
},
beforeCreate() {
diffsApp.instrument();
@@ -611,6 +609,21 @@ export default {
}
}
},
+ subscribeToVirtualScrollingEvents() {
+ if (
+ window.gon?.features?.diffsVirtualScrolling &&
+ this.shouldShow &&
+ !this.subscribedToVirtualScrollingEvents
+ ) {
+ diffsEventHub.$on('scrollToFileHash', this.scrollVirtualScrollerToFileHash);
+ diffsEventHub.$on('scrollToIndex', this.scrollVirtualScrollerToIndex);
+
+ this.subscribedToVirtualScrollingEvents = true;
+ }
+ },
+ reloadPage() {
+ window.location.reload();
+ },
},
minTreeWidth: MIN_TREE_WIDTH,
maxTreeWidth: MAX_TREE_WIDTH,
@@ -629,17 +642,19 @@ export default {
:diff-files-count-text="numTotalFiles"
/>
- <hidden-files-warning
- v-if="visibleWarning == $options.alerts.ALERT_OVERFLOW_HIDDEN"
- :visible="numVisibleFiles"
- :total="numTotalFiles"
- :plain-diff-path="plainDiffPath"
- :email-patch-path="emailPatchPath"
- />
- <collapsed-files-warning
- v-if="visibleWarning == $options.alerts.ALERT_COLLAPSED_FILES"
- :limited="isLimitedContainer"
- />
+ <template v-if="!isBatchLoadingError">
+ <hidden-files-warning
+ v-if="visibleWarning == $options.alerts.ALERT_OVERFLOW_HIDDEN"
+ :visible="numVisibleFiles"
+ :total="numTotalFiles"
+ :plain-diff-path="plainDiffPath"
+ :email-patch-path="emailPatchPath"
+ />
+ <collapsed-files-warning
+ v-if="visibleWarning == $options.alerts.ALERT_COLLAPSED_FILES"
+ :limited="isLimitedContainer"
+ />
+ </template>
<div
:data-can-create-note="getNoteableData.current_user.can_create_note"
@@ -648,7 +663,6 @@ export default {
<div
v-if="renderFileTree"
:style="{ width: `${treeWidth}px` }"
- :class="{ 'review-bar-visible': draftsCount > 0 }"
class="diff-tree-list js-diff-tree-list px-3 pr-md-0"
>
<panel-resizer
@@ -668,11 +682,21 @@ export default {
}"
>
<commit-widget v-if="commit" :commit="commit" :collapsible="false" />
- <div v-if="isBatchLoading" class="loading"><gl-loading-icon size="lg" /></div>
+ <gl-alert
+ v-if="isBatchLoadingError"
+ variant="danger"
+ :dismissible="false"
+ :primary-button-text="__('Reload page')"
+ @primaryAction="reloadPage"
+ >
+ {{ __("Error: Couldn't load some or all of the changes.") }}
+ </gl-alert>
+ <div v-if="isBatchLoading && !isBatchLoadingError" class="loading">
+ <gl-loading-icon size="lg" />
+ </div>
<template v-else-if="renderDiffFiles">
<dynamic-scroller
v-if="isVirtualScrollingEnabled"
- ref="virtualScroller"
:items="diffs"
:min-item-size="70"
:buffer="1000"
@@ -745,7 +769,10 @@ export default {
</div>
<gl-loading-icon v-else-if="retrievingBatches" size="lg" />
</template>
- <no-changes v-else :changes-empty-state-illustration="changesEmptyStateIllustration" />
+ <no-changes
+ v-else-if="!isBatchLoadingError"
+ :changes-empty-state-illustration="changesEmptyStateIllustration"
+ />
</div>
</div>
<mr-widget-how-to-merge-modal
diff --git a/app/assets/javascripts/diffs/components/commit_item.vue b/app/assets/javascripts/diffs/components/commit_item.vue
index 820c64a9502..4435a533591 100644
--- a/app/assets/javascripts/diffs/components/commit_item.vue
+++ b/app/assets/javascripts/diffs/components/commit_item.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { GlButtonGroup, GlButton, GlTooltipDirective } from '@gitlab/ui';
import CommitPipelineStatus from '~/projects/tree/components/commit_pipeline_status_component.vue';
@@ -100,7 +99,10 @@ export default {
<div
class="commit-actions flex-row d-none d-sm-flex align-items-start flex-wrap justify-content-end"
>
- <div v-if="commit.signature_html" v-html="commit.signature_html"></div>
+ <div
+ v-if="commit.signature_html"
+ v-html="commit.signature_html /* eslint-disable-line vue/no-v-html */"
+ ></div>
<commit-pipeline-status
v-if="commit.pipeline_status_path"
:endpoint="commit.pipeline_status_path"
@@ -142,7 +144,7 @@ export default {
<a
:href="commit.commit_url"
class="commit-row-message item-title"
- v-html="commit.title_html"
+ v-html="commit.title_html /* eslint-disable-line vue/no-v-html */"
></a>
<span class="commit-row-message d-block d-sm-none">&middot; {{ commit.short_id }}</span>
@@ -174,7 +176,7 @@ export default {
v-if="commit.description_html"
:class="{ 'js-toggle-content': collapsible, 'd-block': !collapsible }"
class="commit-row-description gl-mb-3 gl-text-body"
- v-html="commitDescription"
+ v-html="commitDescription /* eslint-disable-line vue/no-v-html */"
></pre>
</div>
</li>
diff --git a/app/assets/javascripts/diffs/components/diff_file.vue b/app/assets/javascripts/diffs/components/diff_file.vue
index 933891d698c..d09cc064b2c 100644
--- a/app/assets/javascripts/diffs/components/diff_file.vue
+++ b/app/assets/javascripts/diffs/components/diff_file.vue
@@ -170,10 +170,7 @@ export default {
return !this.isCollapsed && !this.isFileTooLarge;
},
showLocalFileReviews() {
- const loggedIn = Boolean(gon.current_user_id);
- const featureOn = this.glFeatures.localFileReviews;
-
- return loggedIn && featureOn;
+ return Boolean(gon.current_user_id);
},
codequalityDiffForFile() {
return this.codequalityDiff?.files?.[this.file.file_path] || [];
diff --git a/app/assets/javascripts/diffs/components/diff_file_header.vue b/app/assets/javascripts/diffs/components/diff_file_header.vue
index 667b8745f7b..4bcb99424db 100644
--- a/app/assets/javascripts/diffs/components/diff_file_header.vue
+++ b/app/assets/javascripts/diffs/components/diff_file_header.vue
@@ -341,7 +341,7 @@ export default {
:gfm="gfmCopyText"
data-testid="diff-file-copy-clipboard"
category="tertiary"
- data-track-event="click_copy_file_button"
+ data-track-action="click_copy_file_button"
data-track-label="diff_copy_file_path_button"
data-track-property="diff_copy_file"
/>
@@ -382,7 +382,7 @@ export default {
:title="externalUrlLabel"
:aria-label="externalUrlLabel"
target="_blank"
- data-track-event="click_toggle_external_button"
+ data-track-action="click_toggle_external_button"
data-track-label="diff_toggle_external_button"
data-track-property="diff_toggle_external"
icon="external-link"
diff --git a/app/assets/javascripts/diffs/components/diff_row.vue b/app/assets/javascripts/diffs/components/diff_row.vue
index db3ad074d2f..737c4d8f33c 100644
--- a/app/assets/javascripts/diffs/components/diff_row.vue
+++ b/app/assets/javascripts/diffs/components/diff_row.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { memoize } from 'lodash';
import { isLoggedIn } from '~/lib/utils/common_utils';
import {
@@ -268,7 +267,7 @@ export default {
]"
class="diff-td line_content with-coverage left-side"
data-testid="left-content"
- v-html="$options.lineContent(props.line.left)"
+ v-html="$options.lineContent(props.line.left) /* eslint-disable-line vue/no-v-html */"
></div>
</template>
<template
@@ -390,7 +389,7 @@ export default {
},
]"
class="diff-td line_content with-coverage right-side parallel"
- v-html="$options.lineContent(props.line.right)"
+ v-html="$options.lineContent(props.line.right) /* eslint-disable-line vue/no-v-html */"
></div>
</template>
<template v-else>
diff --git a/app/assets/javascripts/diffs/components/diff_view.vue b/app/assets/javascripts/diffs/components/diff_view.vue
index 5cf242b4ddd..64ded1ca8ca 100644
--- a/app/assets/javascripts/diffs/components/diff_view.vue
+++ b/app/assets/javascripts/diffs/components/diff_view.vue
@@ -133,7 +133,10 @@ export default {
<template>
<div
- :class="[$options.userColorScheme, { inline, 'with-codequality': hasCodequalityChanges }]"
+ :class="[
+ $options.userColorScheme,
+ { 'inline-diff-view': inline, 'with-codequality': hasCodequalityChanges },
+ ]"
:data-commit-id="commitId"
class="diff-grid diff-table code diff-wrap-lines js-syntax-highlight text-file"
@mousedown="handleParallelLineMouseDown"
diff --git a/app/assets/javascripts/diffs/components/pre_renderer.vue b/app/assets/javascripts/diffs/components/pre_renderer.vue
index c357aa2d924..e4320c40d2c 100644
--- a/app/assets/javascripts/diffs/components/pre_renderer.vue
+++ b/app/assets/javascripts/diffs/components/pre_renderer.vue
@@ -17,7 +17,6 @@ export default {
},
mounted() {
this.width = this.$el.parentNode.offsetWidth;
- window.test = this;
this.$_itemsWithSizeWatcher = this.$watch('vscrollParent.itemsWithSize', async () => {
await this.$nextTick();
diff --git a/app/assets/javascripts/diffs/constants.js b/app/assets/javascripts/diffs/constants.js
index 8dda5eadb16..93961b07e2e 100644
--- a/app/assets/javascripts/diffs/constants.js
+++ b/app/assets/javascripts/diffs/constants.js
@@ -72,11 +72,6 @@ export const ALERT_COLLAPSED_FILES = 'collapsed';
export const DIFF_FILE_AUTOMATIC_COLLAPSE = 'automatic';
export const DIFF_FILE_MANUAL_COLLAPSE = 'manual';
-// Diff view single file mode
-export const DIFF_FILE_BY_FILE_COOKIE_NAME = 'fileViewMode';
-export const DIFF_VIEW_FILE_BY_FILE = 'single';
-export const DIFF_VIEW_ALL_FILES = 'all';
-
// State machine states
export const STATE_IDLING = 'idle';
export const STATE_LOADING = 'loading';
diff --git a/app/assets/javascripts/diffs/index.js b/app/assets/javascripts/diffs/index.js
index bddc28c4758..1b1ab59b2b4 100644
--- a/app/assets/javascripts/diffs/index.js
+++ b/app/assets/javascripts/diffs/index.js
@@ -3,7 +3,6 @@ import Vue from 'vue';
import { mapActions, mapState, mapGetters } from 'vuex';
import { parseBoolean } from '~/lib/utils/common_utils';
import { getParameterValues } from '~/lib/utils/url_utility';
-import FindFile from '~/vue_shared/components/file_finder/index.vue';
import eventHub from '../notes/event_hub';
import diffsApp from './components/app.vue';
@@ -12,51 +11,7 @@ import { getReviewsForMergeRequest } from './utils/file_reviews';
import { getDerivedMergeRequestInformation } from './utils/merge_request';
export default function initDiffsApp(store) {
- const fileFinderEl = document.getElementById('js-diff-file-finder');
-
- if (fileFinderEl) {
- // eslint-disable-next-line no-new
- new Vue({
- el: fileFinderEl,
- store,
- computed: {
- ...mapState('diffs', ['fileFinderVisible', 'isLoading']),
- ...mapGetters('diffs', ['flatBlobsList']),
- },
- watch: {
- fileFinderVisible(newVal, oldVal) {
- if (newVal && !oldVal && !this.flatBlobsList.length) {
- eventHub.$emit('fetchDiffData');
- }
- },
- },
- methods: {
- ...mapActions('diffs', ['toggleFileFinder', 'scrollToFile']),
- openFile(file) {
- window.mrTabs.tabShown('diffs');
- this.scrollToFile(file.path);
- },
- },
- render(createElement) {
- return createElement(FindFile, {
- props: {
- files: this.flatBlobsList,
- visible: this.fileFinderVisible,
- loading: this.isLoading,
- showDiffStats: true,
- clearSearchOnClose: false,
- },
- on: {
- toggle: this.toggleFileFinder,
- click: this.openFile,
- },
- class: ['diff-file-finder'],
- });
- },
- });
- }
-
- return new Vue({
+ const vm = new Vue({
el: '#js-diffs-app',
name: 'MergeRequestDiffs',
components: {
@@ -157,4 +112,53 @@ export default function initDiffsApp(store) {
});
},
});
+
+ const fileFinderEl = document.getElementById('js-diff-file-finder');
+
+ if (fileFinderEl) {
+ // eslint-disable-next-line no-new
+ new Vue({
+ el: fileFinderEl,
+ store,
+ components: {
+ FindFile: () => import('~/vue_shared/components/file_finder/index.vue'),
+ },
+ computed: {
+ ...mapState('diffs', ['fileFinderVisible', 'isLoading']),
+ ...mapGetters('diffs', ['flatBlobsList']),
+ },
+ watch: {
+ fileFinderVisible(newVal, oldVal) {
+ if (newVal && !oldVal && !this.flatBlobsList.length) {
+ eventHub.$emit('fetchDiffData');
+ }
+ },
+ },
+ methods: {
+ ...mapActions('diffs', ['toggleFileFinder', 'scrollToFile']),
+ openFile(file) {
+ window.mrTabs.tabShown('diffs');
+ this.scrollToFile(file.path);
+ },
+ },
+ render(createElement) {
+ return createElement('find-file', {
+ props: {
+ files: this.flatBlobsList,
+ visible: this.fileFinderVisible,
+ loading: this.isLoading,
+ showDiffStats: true,
+ clearSearchOnClose: false,
+ },
+ on: {
+ toggle: this.toggleFileFinder,
+ click: this.openFile,
+ },
+ class: ['diff-file-finder'],
+ });
+ },
+ });
+ }
+
+ return vm;
}
diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js
index f7bdbe94bac..5c94c6b803b 100644
--- a/app/assets/javascripts/diffs/store/actions.js
+++ b/app/assets/javascripts/diffs/store/actions.js
@@ -29,9 +29,6 @@ import {
EVT_PERF_MARK_FILE_TREE_START,
EVT_PERF_MARK_FILE_TREE_END,
EVT_PERF_MARK_DIFF_FILES_START,
- DIFF_VIEW_FILE_BY_FILE,
- DIFF_VIEW_ALL_FILES,
- DIFF_FILE_BY_FILE_COOKIE_NAME,
TRACKING_CLICK_DIFF_VIEW_SETTING,
TRACKING_DIFF_VIEW_INLINE,
TRACKING_DIFF_VIEW_PARALLEL,
@@ -104,7 +101,7 @@ export const fetchDiffFilesBatch = ({ commit, state, dispatch }) => {
let totalLoaded = 0;
let scrolledVirtualScroller = false;
- commit(types.SET_BATCH_LOADING, true);
+ commit(types.SET_BATCH_LOADING_STATE, 'loading');
commit(types.SET_RETRIEVING_BATCHES, true);
eventHub.$emit(EVT_PERF_MARK_DIFF_FILES_START);
@@ -115,7 +112,7 @@ export const fetchDiffFilesBatch = ({ commit, state, dispatch }) => {
totalLoaded += diff_files.length;
commit(types.SET_DIFF_DATA_BATCH, { diff_files });
- commit(types.SET_BATCH_LOADING, false);
+ commit(types.SET_BATCH_LOADING_STATE, 'loaded');
if (window.gon?.features?.diffsVirtualScrolling && !scrolledVirtualScroller) {
const index = state.diffFiles.findIndex(
@@ -130,7 +127,7 @@ export const fetchDiffFilesBatch = ({ commit, state, dispatch }) => {
}
if (!isNoteLink && !state.currentDiffFileId) {
- commit(types.VIEW_DIFF_FILE, diff_files[0].file_hash);
+ commit(types.VIEW_DIFF_FILE, diff_files[0]?.file_hash);
}
if (isNoteLink) {
@@ -182,11 +179,14 @@ export const fetchDiffFilesBatch = ({ commit, state, dispatch }) => {
return null;
})
- .catch(() => commit(types.SET_RETRIEVING_BATCHES, false));
+ .catch(() => {
+ commit(types.SET_RETRIEVING_BATCHES, false);
+ commit(types.SET_BATCH_LOADING_STATE, 'error');
+ });
- return getBatch()
- .then(() => !window.gon?.features?.diffsVirtualScrolling && handleLocationHash())
- .catch(() => null);
+ return getBatch().then(
+ () => !window.gon?.features?.diffsVirtualScrolling && handleLocationHash(),
+ );
};
export const fetchDiffFilesMeta = ({ commit, state }) => {
@@ -816,9 +816,7 @@ export const navigateToDiffFileIndex = ({ commit, state }, index) => {
};
export const setFileByFile = ({ state, commit }, { fileByFile }) => {
- const fileViewMode = fileByFile ? DIFF_VIEW_FILE_BY_FILE : DIFF_VIEW_ALL_FILES;
commit(types.SET_FILE_BY_FILE, fileByFile);
- Cookies.set(DIFF_FILE_BY_FILE_COOKIE_NAME, fileViewMode);
if (window.gon?.features?.diffSettingsUsageData) {
const events = [TRACKING_CLICK_SINGLE_FILE_SETTING];
diff --git a/app/assets/javascripts/diffs/store/getters.js b/app/assets/javascripts/diffs/store/getters.js
index 18bd8e5f1d8..ca85be5d829 100644
--- a/app/assets/javascripts/diffs/store/getters.js
+++ b/app/assets/javascripts/diffs/store/getters.js
@@ -191,3 +191,6 @@ export const isVirtualScrollingEnabled = (state) => {
getParameterValues('virtual_scrolling')[0] === 'true')
);
};
+
+export const isBatchLoading = (state) => state.batchLoadingState === 'loading';
+export const isBatchLoadingError = (state) => state.batchLoadingState === 'error';
diff --git a/app/assets/javascripts/diffs/store/modules/diff_state.js b/app/assets/javascripts/diffs/store/modules/diff_state.js
index d76361513d4..a5b1a577a78 100644
--- a/app/assets/javascripts/diffs/store/modules/diff_state.js
+++ b/app/assets/javascripts/diffs/store/modules/diff_state.js
@@ -2,8 +2,6 @@ import Cookies from 'js-cookie';
import { getParameterValues } from '~/lib/utils/url_utility';
import { INLINE_DIFF_VIEW_TYPE, DIFF_VIEW_COOKIE_NAME } from '../../constants';
-import { fileByFile } from '../../utils/preferences';
-
const getViewTypeFromQueryString = () => getParameterValues('view')[0];
const viewTypeFromCookie = Cookies.get(DIFF_VIEW_COOKIE_NAME);
@@ -12,7 +10,7 @@ const defaultViewType = INLINE_DIFF_VIEW_TYPE;
export default () => ({
isLoading: true,
isTreeLoaded: false,
- isBatchLoading: false,
+ batchLoadingState: null,
retrievingBatches: false,
addedLines: null,
removedLines: null,
@@ -36,7 +34,7 @@ export default () => ({
highlightedRow: null,
renderTreeList: true,
showWhitespace: true,
- viewDiffsFileByFile: fileByFile(),
+ viewDiffsFileByFile: false,
fileFinderVisible: false,
dismissEndpoint: '',
showSuggestPopover: true,
diff --git a/app/assets/javascripts/diffs/store/mutation_types.js b/app/assets/javascripts/diffs/store/mutation_types.js
index 2c370221f40..60836f747f5 100644
--- a/app/assets/javascripts/diffs/store/mutation_types.js
+++ b/app/assets/javascripts/diffs/store/mutation_types.js
@@ -1,6 +1,6 @@
export const SET_BASE_CONFIG = 'SET_BASE_CONFIG';
export const SET_LOADING = 'SET_LOADING';
-export const SET_BATCH_LOADING = 'SET_BATCH_LOADING';
+export const SET_BATCH_LOADING_STATE = 'SET_BATCH_LOADING_STATE';
export const SET_RETRIEVING_BATCHES = 'SET_RETRIEVING_BATCHES';
export const SET_DIFF_METADATA = 'SET_DIFF_METADATA';
diff --git a/app/assets/javascripts/diffs/store/mutations.js b/app/assets/javascripts/diffs/store/mutations.js
index 1aa83453bf7..6bc927b9d1f 100644
--- a/app/assets/javascripts/diffs/store/mutations.js
+++ b/app/assets/javascripts/diffs/store/mutations.js
@@ -60,8 +60,8 @@ export default {
Object.assign(state, { isLoading });
},
- [types.SET_BATCH_LOADING](state, isBatchLoading) {
- Object.assign(state, { isBatchLoading });
+ [types.SET_BATCH_LOADING_STATE](state, batchLoadingState) {
+ Object.assign(state, { batchLoadingState });
},
[types.SET_RETRIEVING_BATCHES](state, retrievingBatches) {
diff --git a/app/assets/javascripts/diffs/utils/preferences.js b/app/assets/javascripts/diffs/utils/preferences.js
deleted file mode 100644
index 6b4aaf45937..00000000000
--- a/app/assets/javascripts/diffs/utils/preferences.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import Cookies from 'js-cookie';
-import { DIFF_FILE_BY_FILE_COOKIE_NAME, DIFF_VIEW_FILE_BY_FILE } from '../constants';
-
-export function fileByFile(pref = false) {
- const cookie = Cookies.get(DIFF_FILE_BY_FILE_COOKIE_NAME);
-
- // use the cookie first, if it exists
- if (cookie) {
- return cookie === DIFF_VIEW_FILE_BY_FILE;
- }
-
- return pref;
-}
diff --git a/app/assets/javascripts/dropzone_input.js b/app/assets/javascripts/dropzone_input.js
index 337f7ae2757..f98f63529fc 100644
--- a/app/assets/javascripts/dropzone_input.js
+++ b/app/assets/javascripts/dropzone_input.js
@@ -4,6 +4,7 @@ import { escape } from 'lodash';
import './behaviors/preview_markdown';
import { spriteIcon } from '~/lib/utils/common_utils';
import { getFilename } from '~/lib/utils/file_upload';
+import { truncate } from '~/lib/utils/text_utility';
import { n__, __ } from '~/locale';
import PasteMarkdownTable from './behaviors/markdown/paste_markdown_table';
import axios from './lib/utils/axios_utils';
@@ -189,10 +190,13 @@ export default function dropzoneInput(form, config = { parallelUploads: 2 }) {
if (image) {
event.preventDefault();
+ const MAX_FILE_NAME_LENGTH = 246;
const filename = getFilename(pasteEvent) || 'image.png';
- const text = `{{${filename}}}`;
+ const truncateFilename = truncate(filename, MAX_FILE_NAME_LENGTH);
+ const text = `{{${truncateFilename}}}`;
pasteText(text);
- return uploadFile(image.getAsFile(), filename);
+
+ return uploadFile(image.getAsFile(), truncateFilename);
}
}
}
diff --git a/app/assets/javascripts/due_date_select.js b/app/assets/javascripts/due_date_select.js
deleted file mode 100644
index aa223270f2c..00000000000
--- a/app/assets/javascripts/due_date_select.js
+++ /dev/null
@@ -1,191 +0,0 @@
-/* eslint-disable max-classes-per-file */
-import dateFormat from 'dateformat';
-import $ from 'jquery';
-import Pikaday from 'pikaday';
-import initDatePicker from '~/behaviors/date_picker';
-import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
-import { __ } from '~/locale';
-import boardsStore from './boards/stores/boards_store';
-import axios from './lib/utils/axios_utils';
-import { timeFor, parsePikadayDate, pikadayToString } from './lib/utils/datetime_utility';
-
-class DueDateSelect {
- constructor({ $dropdown, $loading } = {}) {
- const $dropdownParent = $dropdown.closest('.dropdown');
- const $block = $dropdown.closest('.block');
- this.$loading = $loading;
- this.$dropdown = $dropdown;
- this.$dropdownParent = $dropdownParent;
- this.$datePicker = $dropdownParent.find('.js-due-date-calendar');
- this.$block = $block;
- this.$sidebarCollapsedValue = $block.find('.sidebar-collapsed-icon');
- this.$selectbox = $dropdown.closest('.selectbox');
- this.$value = $block.find('.value');
- this.$valueContent = $block.find('.value-content');
- this.$sidebarValue = $('.js-due-date-sidebar-value', $block);
- this.fieldName = $dropdown.data('fieldName');
- this.abilityName = $dropdown.data('abilityName');
- this.issueUpdateURL = $dropdown.data('issueUpdate');
-
- this.rawSelectedDate = null;
- this.displayedDate = null;
- this.datePayload = null;
-
- this.initGlDropdown();
- this.initRemoveDueDate();
- this.initDatePicker();
- }
-
- initGlDropdown() {
- initDeprecatedJQueryDropdown(this.$dropdown, {
- opened: () => {
- const calendar = this.$datePicker.data('pikaday');
- calendar.show();
- },
- hidden: () => {
- this.$selectbox.hide();
- this.$value.css('display', '');
- },
- shouldPropagate: false,
- });
- }
-
- initDatePicker() {
- const $dueDateInput = $(`input[name='${this.fieldName}']`);
- const calendar = new Pikaday({
- field: $dueDateInput.get(0),
- theme: 'gitlab-theme',
- format: 'yyyy-mm-dd',
- parse: (dateString) => parsePikadayDate(dateString),
- toString: (date) => pikadayToString(date),
- onSelect: (dateText) => {
- $dueDateInput.val(calendar.toString(dateText));
-
- if (this.$dropdown.hasClass('js-issue-boards-due-date')) {
- boardsStore.detail.issue.dueDate = $dueDateInput.val();
- this.updateIssueBoardIssue();
- } else {
- this.saveDueDate(true);
- }
- },
- firstDay: gon.first_day_of_week,
- });
-
- calendar.setDate(parsePikadayDate($dueDateInput.val()));
- this.$datePicker.append(calendar.el);
- this.$datePicker.data('pikaday', calendar);
- }
-
- initRemoveDueDate() {
- this.$block.on('click', '.js-remove-due-date', (e) => {
- const calendar = this.$datePicker.data('pikaday');
- e.preventDefault();
-
- calendar.setDate(null);
-
- if (this.$dropdown.hasClass('js-issue-boards-due-date')) {
- boardsStore.detail.issue.dueDate = '';
- this.updateIssueBoardIssue();
- } else {
- $(`input[name='${this.fieldName}']`).val('');
- this.saveDueDate(false);
- }
- });
- }
-
- saveDueDate(isDropdown) {
- this.parseSelectedDate();
- this.prepSelectedDate();
- this.submitSelectedDate(isDropdown);
- }
-
- parseSelectedDate() {
- this.rawSelectedDate = $(`input[name='${this.fieldName}']`).val();
-
- if (this.rawSelectedDate.length) {
- // Construct Date object manually to avoid buggy dateString support within Date constructor
- const dateArray = this.rawSelectedDate.split('-').map((v) => parseInt(v, 10));
- const dateObj = new Date(dateArray[0], dateArray[1] - 1, dateArray[2]);
- this.displayedDate = dateFormat(dateObj, 'mmm d, yyyy');
- } else {
- this.displayedDate = __('None');
- }
- }
-
- prepSelectedDate() {
- const datePayload = {};
- datePayload[this.abilityName] = {};
- datePayload[this.abilityName].due_date = this.rawSelectedDate;
- this.datePayload = datePayload;
- }
-
- updateIssueBoardIssue() {
- this.$loading.removeClass('gl-display-none');
- this.$dropdown.trigger('loading.gl.dropdown');
- this.$selectbox.hide();
- this.$value.css('display', '');
- const hideLoader = () => {
- this.$loading.addClass('gl-display-none');
- };
-
- boardsStore.detail.issue
- .update(this.$dropdown.attr('data-issue-update'))
- .then(hideLoader)
- .catch(hideLoader);
- }
-
- submitSelectedDate(isDropdown) {
- const selectedDateValue = this.datePayload[this.abilityName].due_date;
- const hasDueDate = this.displayedDate !== __('None');
- const displayedDateStyle = hasDueDate ? 'bold' : 'no-value';
-
- this.$loading.removeClass('gl-display-none');
-
- if (isDropdown) {
- this.$dropdown.trigger('loading.gl.dropdown');
- this.$selectbox.hide();
- }
-
- this.$value.css('display', '');
- this.$valueContent.html(`<span class='${displayedDateStyle}'>${this.displayedDate}</span>`);
- this.$sidebarValue.html(this.displayedDate);
-
- $('.js-remove-due-date-holder').toggleClass('hidden', selectedDateValue.length);
-
- return axios.put(this.issueUpdateURL, this.datePayload).then(() => {
- const tooltipText = hasDueDate
- ? `${__('Due date')}<br />${selectedDateValue} (${timeFor(selectedDateValue)})`
- : __('Due date');
- if (isDropdown) {
- this.$dropdown.trigger('loaded.gl.dropdown');
- this.$dropdown.dropdown('toggle');
- }
- this.$sidebarCollapsedValue.attr('data-original-title', tooltipText);
-
- return this.$loading.addClass('gl-display-none');
- });
- }
-}
-
-export default class DueDateSelectors {
- constructor() {
- initDatePicker();
- this.initIssuableSelect();
- }
- // eslint-disable-next-line class-methods-use-this
- initIssuableSelect() {
- const $loading = $('.js-issuable-update .due_date')
- .find('.block-loading')
- .removeClass('hidden')
- .addClass('gl-display-none');
-
- $('.js-due-date-select').each((i, dropdown) => {
- const $dropdown = $(dropdown);
- // eslint-disable-next-line no-new
- new DueDateSelect({
- $dropdown,
- $loading,
- });
- });
- }
-}
diff --git a/app/assets/javascripts/emoji/index.js b/app/assets/javascripts/emoji/index.js
index 7faf0fe5f08..7672151af2a 100644
--- a/app/assets/javascripts/emoji/index.js
+++ b/app/assets/javascripts/emoji/index.js
@@ -1,5 +1,6 @@
import { escape, minBy } from 'lodash';
import emojiAliases from 'emojis/aliases.json';
+import { sanitize } from '~/lib/dompurify';
import AccessorUtilities from '../lib/utils/accessor';
import axios from '../lib/utils/axios_utils';
import { CATEGORY_ICON_MAP, FREQUENTLY_USED_KEY } from './constants';
@@ -10,7 +11,7 @@ export const FALLBACK_EMOJI_KEY = 'grey_question';
export const EMOJI_VERSION = '1';
-const isLocalStorageAvailable = AccessorUtilities.isLocalStorageAccessSafe();
+const isLocalStorageAvailable = AccessorUtilities.canUseLocalStorage();
async function loadEmoji() {
if (
@@ -34,7 +35,7 @@ async function loadEmoji() {
async function loadEmojiWithNames() {
return Object.entries(await loadEmoji()).reduce((acc, [key, value]) => {
- acc[key] = { ...value, name: key };
+ acc[key] = { ...value, name: key, e: sanitize(value.e) };
return acc;
}, {});
diff --git a/app/assets/javascripts/emoji/support/unicode_support_map.js b/app/assets/javascripts/emoji/support/unicode_support_map.js
index fe3bc75f9fd..d90a774c293 100644
--- a/app/assets/javascripts/emoji/support/unicode_support_map.js
+++ b/app/assets/javascripts/emoji/support/unicode_support_map.js
@@ -141,7 +141,7 @@ function generateUnicodeSupportMap(testMap) {
}
export default function getUnicodeSupportMap() {
- const isLocalStorageAvailable = AccessorUtilities.isLocalStorageAccessSafe();
+ const isLocalStorageAvailable = AccessorUtilities.canUseLocalStorage();
let glEmojiVersionFromCache;
let userAgentFromCache;
diff --git a/app/assets/javascripts/environments/components/container.vue b/app/assets/javascripts/environments/components/container.vue
index 9e058af56c4..cec53869aa8 100644
--- a/app/assets/javascripts/environments/components/container.vue
+++ b/app/assets/javascripts/environments/components/container.vue
@@ -22,10 +22,6 @@ export default {
type: Object,
required: true,
},
- canReadEnvironment: {
- type: Boolean,
- required: true,
- },
},
methods: {
onChangePage(page) {
@@ -42,7 +38,7 @@ export default {
<slot name="empty-state"></slot>
<div v-if="!isLoading && environments.length > 0" class="table-holder">
- <environment-table :environments="environments" :can-read-environment="canReadEnvironment" />
+ <environment-table :environments="environments" />
<table-pagination
v-if="pagination && pagination.totalPages > 1"
diff --git a/app/assets/javascripts/environments/components/edit_environment.vue b/app/assets/javascripts/environments/components/edit_environment.vue
index 1cd960d7cd6..96742a11ebb 100644
--- a/app/assets/javascripts/environments/components/edit_environment.vue
+++ b/app/assets/javascripts/environments/components/edit_environment.vue
@@ -18,6 +18,7 @@ export default {
data() {
return {
formEnvironment: {
+ id: this.environment.id,
name: this.environment.name,
externalUrl: this.environment.external_url,
},
@@ -33,7 +34,6 @@ export default {
axios
.put(this.updateEnvironmentPath, {
id: this.environment.id,
- name: this.formEnvironment.name,
external_url: this.formEnvironment.externalUrl,
})
.then(({ data: { path } }) => visitUrl(path))
diff --git a/app/assets/javascripts/environments/components/environment_form.vue b/app/assets/javascripts/environments/components/environment_form.vue
index 6db8fe24e72..1d1d8d61b66 100644
--- a/app/assets/javascripts/environments/components/environment_form.vue
+++ b/app/assets/javascripts/environments/components/environment_form.vue
@@ -39,12 +39,17 @@ export default {
),
nameLabel: __('Name'),
nameFeedback: __('This field is required'),
+ nameDisabledHelp: __("You cannot rename an environment after it's created."),
+ nameDisabledLinkText: __('How do I rename an environment?'),
urlLabel: __('External URL'),
urlFeedback: __('The URL should start with http:// or https://'),
save: __('Save'),
cancel: __('Cancel'),
},
helpPagePath: helpPagePath('ci/environments/index.md'),
+ renamingDisabledHelpPagePath: helpPagePath('ci/environments/index.md', {
+ anchor: 'rename-an-environment',
+ }),
data() {
return {
visited: {
@@ -54,6 +59,9 @@ export default {
};
},
computed: {
+ isNameDisabled() {
+ return Boolean(this.environment.id);
+ },
valid() {
return {
name: this.visited.name && this.environment.name !== '',
@@ -102,10 +110,17 @@ export default {
:state="valid.name"
:invalid-feedback="$options.i18n.nameFeedback"
>
+ <template v-if="isNameDisabled" #description>
+ {{ $options.i18n.nameDisabledHelp }}
+ <gl-link :href="$options.renamingDisabledHelpPagePath" target="_blank">
+ {{ $options.i18n.nameDisabledLinkText }}
+ </gl-link>
+ </template>
<gl-form-input
id="environment_name"
:value="environment.name"
:state="valid.name"
+ :disabled="isNameDisabled"
name="environment[name]"
required
@input="onChange({ ...environment, name: $event })"
diff --git a/app/assets/javascripts/environments/components/environment_item.vue b/app/assets/javascripts/environments/components/environment_item.vue
index 897f6ce393e..d12863ee742 100644
--- a/app/assets/javascripts/environments/components/environment_item.vue
+++ b/app/assets/javascripts/environments/components/environment_item.vue
@@ -1,6 +1,5 @@
<script>
-/* eslint-disable @gitlab/vue-require-i18n-strings */
-import { GlTooltipDirective, GlIcon, GlLink } from '@gitlab/ui';
+import { GlTooltipDirective, GlIcon, GlLink, GlSprintf } from '@gitlab/ui';
import { isEmpty } from 'lodash';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { __, s__, sprintf } from '~/locale';
@@ -32,6 +31,7 @@ export default {
ExternalUrlComponent,
GlIcon,
GlLink,
+ GlSprintf,
MonitoringButtonComponent,
PinComponent,
DeleteComponent,
@@ -48,12 +48,6 @@ export default {
mixins: [timeagoMixin],
props: {
- canReadEnvironment: {
- type: Boolean,
- required: false,
- default: false,
- },
-
model: {
type: Object,
required: true,
@@ -647,14 +641,17 @@ export default {
</span>
<span v-if="!isFolder && deploymentHasUser" class="text-break-word">
- by
- <user-avatar-link
- :link-href="deploymentUser.web_url"
- :img-src="deploymentUser.avatar_url"
- :img-alt="userImageAltDescription"
- :tooltip-text="deploymentUser.username"
- class="js-deploy-user-container float-none"
- />
+ <gl-sprintf :message="s__('Environments|by %{avatar}')">
+ <template #avatar>
+ <user-avatar-link
+ :link-href="deploymentUser.web_url"
+ :img-src="deploymentUser.avatar_url"
+ :img-alt="userImageAltDescription"
+ :tooltip-text="deploymentUser.username"
+ class="js-deploy-user-container float-none"
+ />
+ </template>
+ </gl-sprintf>
</span>
<div v-if="showNoDeployments" class="commit-title table-mobile-content">
@@ -743,13 +740,16 @@ export default {
</div>
<div class="gl-display-flex">
<span v-if="upcomingDeployment.user" class="text-break-word">
- by
- <user-avatar-link
- :link-href="upcomingDeployment.user.web_url"
- :img-src="upcomingDeployment.user.avatar_url"
- :img-alt="upcomingDeploymentUserImageAltDescription"
- :tooltip-text="upcomingDeployment.user.username"
- />
+ <gl-sprintf :message="s__('Environments|by %{avatar}')">
+ <template #avatar>
+ <user-avatar-link
+ :link-href="upcomingDeployment.user.web_url"
+ :img-src="upcomingDeployment.user.avatar_url"
+ :img-alt="upcomingDeploymentUserImageAltDescription"
+ :tooltip-text="upcomingDeployment.user.username"
+ />
+ </template>
+ </gl-sprintf>
</span>
</div>
</div>
@@ -784,14 +784,14 @@ export default {
/>
<external-url-component
- v-if="externalURL && canReadEnvironment"
+ v-if="externalURL"
:external-url="externalURL"
data-track-action="click_button"
data-track-label="environment_url"
/>
<monitoring-button-component
- v-if="monitoringUrl && canReadEnvironment"
+ v-if="monitoringUrl"
:monitoring-url="monitoringUrl"
data-track-action="click_button"
data-track-label="environment_monitoring"
diff --git a/app/assets/javascripts/environments/components/environments_app.vue b/app/assets/javascripts/environments/components/environments_app.vue
index 105315dcf51..acc16ecd874 100644
--- a/app/assets/javascripts/environments/components/environments_app.vue
+++ b/app/assets/javascripts/environments/components/environments_app.vue
@@ -1,9 +1,7 @@
<script>
-import { GlBadge, GlButton, GlModalDirective, GlTab, GlTabs, GlAlert } from '@gitlab/ui';
+import { GlBadge, GlButton, GlModalDirective, GlTab, GlTabs } from '@gitlab/ui';
import createFlash from '~/flash';
-import { setCookie, getCookie, parseBoolean } from '~/lib/utils/common_utils';
import { s__ } from '~/locale';
-import { ENVIRONMENTS_SURVEY_DISMISSED_COOKIE_NAME } from '../constants';
import eventHub from '../event_hub';
import environmentsMixin from '../mixins/environments_mixin';
import EnvironmentsPaginationApiMixin from '../mixins/environments_pagination_api_mixin';
@@ -17,12 +15,6 @@ export default {
i18n: {
newEnvironmentButtonLabel: s__('Environments|New environment'),
reviewAppButtonLabel: s__('Environments|Enable review app'),
- surveyAlertTitle: s__('Environments|Help us improve environments'),
- surveyAlertText: s__(
- 'Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card.',
- ),
- surveyAlertButtonLabel: s__('Environments|Take the survey'),
- surveyDismissButtonLabel: s__('Environments|Dismiss'),
},
modal: {
id: 'enable-review-app-info',
@@ -33,7 +25,6 @@ export default {
EnableReviewAppModal,
GlBadge,
GlButton,
- GlAlert,
GlTab,
GlTabs,
StopEnvironmentModal,
@@ -52,10 +43,6 @@ export default {
type: Boolean,
required: true,
},
- canReadEnvironment: {
- type: Boolean,
- required: true,
- },
newEnvironmentPath: {
type: String,
required: true,
@@ -65,13 +52,6 @@ export default {
required: true,
},
},
- data() {
- return {
- environmentsSurveyAlertDismissed: parseBoolean(
- getCookie(ENVIRONMENTS_SURVEY_DISMISSED_COOKIE_NAME),
- ),
- };
- },
created() {
eventHub.$on('toggleFolder', this.toggleFolder);
@@ -121,11 +101,6 @@ export default {
openFolders.forEach((folder) => this.fetchChildEnvironments(folder));
}
},
-
- onSurveyAlertDismiss() {
- setCookie(ENVIRONMENTS_SURVEY_DISMISSED_COOKIE_NAME, 'true');
- this.environmentsSurveyAlertDismissed = true;
- },
},
};
</script>
@@ -156,19 +131,6 @@ export default {
>{{ $options.i18n.newEnvironmentButtonLabel }}</gl-button
>
</div>
- <gl-alert
- v-if="!environmentsSurveyAlertDismissed"
- class="gl-my-4"
- :title="$options.i18n.surveyAlertTitle"
- :primary-button-text="$options.i18n.surveyAlertButtonLabel"
- variant="info"
- dismissible
- :dismiss-label="$options.i18n.surveyDismissButtonLabel"
- primary-button-link="https://gitlab.fra1.qualtrics.com/jfe/form/SV_a2xyFsAA4D0w0Jg"
- @dismiss="onSurveyAlertDismiss"
- >
- {{ $options.i18n.surveyAlertText }}
- </gl-alert>
<gl-tabs :value="activeTab" content-class="gl-display-none">
<gl-tab
v-for="(tab, idx) in tabs"
@@ -210,7 +172,6 @@ export default {
:is-loading="isLoading"
:environments="state.environments"
:pagination="state.paginationInformation"
- :can-read-environment="canReadEnvironment"
@onChangePage="onChangePage"
>
<template v-if="!isLoading && state.environments.length === 0" #empty-state>
diff --git a/app/assets/javascripts/environments/components/environments_detail_header.vue b/app/assets/javascripts/environments/components/environments_detail_header.vue
index 467c89fd8b8..d71b553a878 100644
--- a/app/assets/javascripts/environments/components/environments_detail_header.vue
+++ b/app/assets/javascripts/environments/components/environments_detail_header.vue
@@ -27,10 +27,6 @@ export default {
type: Object,
required: true,
},
- canReadEnvironment: {
- type: Boolean,
- required: true,
- },
canAdminEnvironment: {
type: Boolean,
required: true,
@@ -84,7 +80,7 @@ export default {
return this.environment.isAvailable && Boolean(this.environment.autoStopAt);
},
shouldShowExternalUrlButton() {
- return this.canReadEnvironment && Boolean(this.environment.externalUrl);
+ return Boolean(this.environment.externalUrl);
},
shouldShowStopButton() {
return this.canStopEnvironment && this.environment.isAvailable;
@@ -138,7 +134,7 @@ export default {
>{{ $options.i18n.externalButtonText }}</gl-button
>
<gl-button
- v-if="canReadEnvironment"
+ v-if="shouldShowExternalUrlButton"
data-testid="metrics-button"
:href="metricsPath"
:title="$options.i18n.metricsButtonTitle"
diff --git a/app/assets/javascripts/environments/components/environments_table.vue b/app/assets/javascripts/environments/components/environments_table.vue
index 61438872afc..f1c728b84fd 100644
--- a/app/assets/javascripts/environments/components/environments_table.vue
+++ b/app/assets/javascripts/environments/components/environments_table.vue
@@ -23,11 +23,6 @@ export default {
required: true,
default: () => [],
},
- canReadEnvironment: {
- type: Boolean,
- required: false,
- default: false,
- },
},
data() {
return {
@@ -155,7 +150,6 @@ export default {
<environment-item
:key="`environment-item-${i}`"
:model="model"
- :can-read-environment="canReadEnvironment"
:table-data="tableData"
data-qa-selector="environment_item"
/>
@@ -191,7 +185,6 @@ export default {
<environment-item
:key="`environment-row-${i}-${index}`"
:model="child"
- :can-read-environment="canReadEnvironment"
:table-data="tableData"
data-qa-selector="environment_item"
/>
diff --git a/app/assets/javascripts/environments/constants.js b/app/assets/javascripts/environments/constants.js
index a02e72dfa72..6d427bef4e6 100644
--- a/app/assets/javascripts/environments/constants.js
+++ b/app/assets/javascripts/environments/constants.js
@@ -38,5 +38,3 @@ export const CANARY_STATUS = {
};
export const CANARY_UPDATE_MODAL = 'confirm-canary-change';
-
-export const ENVIRONMENTS_SURVEY_DISMISSED_COOKIE_NAME = 'environments_survey_alert_dismissed';
diff --git a/app/assets/javascripts/environments/folder/environments_folder_bundle.js b/app/assets/javascripts/environments/folder/environments_folder_bundle.js
index 1be9a4608cb..206381e0b7e 100644
--- a/app/assets/javascripts/environments/folder/environments_folder_bundle.js
+++ b/app/assets/javascripts/environments/folder/environments_folder_bundle.js
@@ -1,7 +1,6 @@
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
-import { parseBoolean } from '../../lib/utils/common_utils';
import Translate from '../../vue_shared/translate';
import environmentsFolderApp from './environments_folder_view.vue';
@@ -31,7 +30,6 @@ export default () => {
endpoint: environmentsData.environmentsDataEndpoint,
folderName: environmentsData.environmentsDataFolderName,
cssContainerClass: environmentsData.cssClass,
- canReadEnvironment: parseBoolean(environmentsData.environmentsDataCanReadEnvironment),
};
},
render(createElement) {
@@ -40,7 +38,6 @@ export default () => {
endpoint: this.endpoint,
folderName: this.folderName,
cssContainerClass: this.cssContainerClass,
- canReadEnvironment: this.canReadEnvironment,
},
});
},
diff --git a/app/assets/javascripts/environments/folder/environments_folder_view.vue b/app/assets/javascripts/environments/folder/environments_folder_view.vue
index 8070f3f12f8..3c608ad0ba9 100644
--- a/app/assets/javascripts/environments/folder/environments_folder_view.vue
+++ b/app/assets/javascripts/environments/folder/environments_folder_view.vue
@@ -30,10 +30,6 @@ export default {
required: false,
default: '',
},
- canReadEnvironment: {
- type: Boolean,
- required: true,
- },
},
methods: {
successCallback(resp) {
@@ -72,7 +68,6 @@ export default {
:is-loading="isLoading"
:environments="state.environments"
:pagination="state.paginationInformation"
- :can-read-environment="canReadEnvironment"
@onChangePage="onChangePage"
/>
</div>
diff --git a/app/assets/javascripts/environments/index.js b/app/assets/javascripts/environments/index.js
index b99872f7a6c..5e33923d518 100644
--- a/app/assets/javascripts/environments/index.js
+++ b/app/assets/javascripts/environments/index.js
@@ -9,7 +9,7 @@ Vue.use(Translate);
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
- defaultClient: createDefaultClient(),
+ defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
});
export default () => {
@@ -32,7 +32,6 @@ export default () => {
newEnvironmentPath: environmentsData.newEnvironmentPath,
helpPagePath: environmentsData.helpPagePath,
canCreateEnvironment: parseBoolean(environmentsData.canCreateEnvironment),
- canReadEnvironment: parseBoolean(environmentsData.canReadEnvironment),
};
},
render(createElement) {
@@ -42,7 +41,6 @@ export default () => {
newEnvironmentPath: this.newEnvironmentPath,
helpPagePath: this.helpPagePath,
canCreateEnvironment: this.canCreateEnvironment,
- canReadEnvironment: this.canReadEnvironment,
},
});
},
diff --git a/app/assets/javascripts/environments/mount_show.js b/app/assets/javascripts/environments/mount_show.js
index f1c2dfec94b..6df4fad83f2 100644
--- a/app/assets/javascripts/environments/mount_show.js
+++ b/app/assets/javascripts/environments/mount_show.js
@@ -36,7 +36,6 @@ export const initHeader = () => {
environment: this.environment,
canDestroyEnvironment: dataset.canDestroyEnvironment,
canUpdateEnvironment: dataset.canUpdateEnvironment,
- canReadEnvironment: dataset.canReadEnvironment,
canStopEnvironment: dataset.canStopEnvironment,
canAdminEnvironment: dataset.canAdminEnvironment,
cancelAutoStopPath: dataset.environmentCancelAutoStopPath,
diff --git a/app/assets/javascripts/error_tracking/components/error_tracking_list.vue b/app/assets/javascripts/error_tracking/components/error_tracking_list.vue
index 2e27f51b71f..5db8c8cf8d3 100644
--- a/app/assets/javascripts/error_tracking/components/error_tracking_list.vue
+++ b/app/assets/javascripts/error_tracking/components/error_tracking_list.vue
@@ -118,7 +118,7 @@ export default {
required: true,
},
},
- hasLocalStorage: AccessorUtils.isLocalStorageAccessSafe(),
+ hasLocalStorage: AccessorUtils.canUseLocalStorage(),
data() {
return {
errorSearchQuery: '',
diff --git a/app/assets/javascripts/error_tracking/components/stacktrace_entry.vue b/app/assets/javascripts/error_tracking/components/stacktrace_entry.vue
index 68b4438831e..2b8a31da50f 100644
--- a/app/assets/javascripts/error_tracking/components/stacktrace_entry.vue
+++ b/app/assets/javascripts/error_tracking/components/stacktrace_entry.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { GlTooltip, GlSprintf, GlIcon } from '@gitlab/ui';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import FileIcon from '~/vue_shared/components/file_icon.vue';
@@ -132,7 +131,7 @@ export default {
<td
class="line_content"
:class="{ old: isHighlighted(lineNum(line)) }"
- v-html="lineCode(line)"
+ v-html="lineCode(line) /* eslint-disable-line vue/no-v-html */"
></td>
</tr>
</template>
diff --git a/app/assets/javascripts/error_tracking/store/list/mutations.js b/app/assets/javascripts/error_tracking/store/list/mutations.js
index d92a64947ad..523861363d7 100644
--- a/app/assets/javascripts/error_tracking/store/list/mutations.js
+++ b/app/assets/javascripts/error_tracking/store/list/mutations.js
@@ -22,7 +22,7 @@ export default {
// only keep the last 5
state.recentSearches = recentSearches.slice(0, 5);
- if (AccessorUtils.isLocalStorageAccessSafe()) {
+ if (AccessorUtils.canUseLocalStorage()) {
localStorage.setItem(
`recent-searches${state.indexPath}`,
JSON.stringify(state.recentSearches),
@@ -31,7 +31,7 @@ export default {
},
[types.CLEAR_RECENT_SEARCHES](state) {
state.recentSearches = [];
- if (AccessorUtils.isLocalStorageAccessSafe()) {
+ if (AccessorUtils.canUseLocalStorage()) {
localStorage.removeItem(`recent-searches${state.indexPath}`);
}
},
diff --git a/app/assets/javascripts/error_tracking_settings/components/app.vue b/app/assets/javascripts/error_tracking_settings/components/app.vue
index d188574e721..e12d9cc2b07 100644
--- a/app/assets/javascripts/error_tracking_settings/components/app.vue
+++ b/app/assets/javascripts/error_tracking_settings/components/app.vue
@@ -1,5 +1,5 @@
<script>
-import { GlButton, GlFormGroup, GlFormCheckbox } from '@gitlab/ui';
+import { GlButton, GlFormGroup, GlFormCheckbox, GlFormRadioGroup, GlFormRadio } from '@gitlab/ui';
import { mapActions, mapGetters, mapState } from 'vuex';
import ErrorTrackingForm from './error_tracking_form.vue';
import ProjectDropdown from './project_dropdown.vue';
@@ -10,6 +10,8 @@ export default {
GlButton,
GlFormCheckbox,
GlFormGroup,
+ GlFormRadioGroup,
+ GlFormRadio,
ProjectDropdown,
},
props: {
@@ -22,6 +24,10 @@ export default {
type: String,
required: true,
},
+ initialIntegrated: {
+ type: String,
+ required: true,
+ },
initialProject: {
type: String,
required: false,
@@ -49,12 +55,20 @@ export default {
'isProjectInvalid',
'projectSelectionLabel',
]),
- ...mapState(['enabled', 'projects', 'selectedProject', 'settingsLoading', 'token']),
+ ...mapState([
+ 'enabled',
+ 'integrated',
+ 'projects',
+ 'selectedProject',
+ 'settingsLoading',
+ 'token',
+ ]),
},
created() {
this.setInitialState({
apiHost: this.initialApiHost,
enabled: this.initialEnabled,
+ integrated: this.initialIntegrated,
project: this.initialProject,
token: this.initialToken,
listProjectsEndpoint: this.listProjectsEndpoint,
@@ -62,7 +76,13 @@ export default {
});
},
methods: {
- ...mapActions(['setInitialState', 'updateEnabled', 'updateSelectedProject', 'updateSettings']),
+ ...mapActions([
+ 'setInitialState',
+ 'updateEnabled',
+ 'updateIntegrated',
+ 'updateSelectedProject',
+ 'updateSettings',
+ ]),
handleSubmit() {
this.updateSettings();
},
@@ -76,27 +96,44 @@ export default {
:label="s__('ErrorTracking|Enable error tracking')"
label-for="error-tracking-enabled"
>
- <gl-form-checkbox
- id="error-tracking-enabled"
- :checked="enabled"
- @change="updateEnabled($event)"
- >
+ <gl-form-checkbox id="error-tracking-enabled" :checked="enabled" @change="updateEnabled">
{{ s__('ErrorTracking|Active') }}
</gl-form-checkbox>
</gl-form-group>
- <error-tracking-form />
- <div class="form-group">
- <project-dropdown
- :has-projects="hasProjects"
- :invalid-project-label="invalidProjectLabel"
- :is-project-invalid="isProjectInvalid"
- :dropdown-label="dropdownLabel"
- :project-selection-label="projectSelectionLabel"
- :projects="projects"
- :selected-project="selectedProject"
- :token="token"
- @select-project="updateSelectedProject"
- />
+ <gl-form-group
+ :label="s__('ErrorTracking|Error tracking backend')"
+ data-testid="tracking-backend-settings"
+ >
+ <gl-form-radio-group name="explicit" :checked="integrated" @change="updateIntegrated">
+ <gl-form-radio name="error-tracking-integrated" :value="false">
+ {{ __('Sentry') }}
+ <template #help>
+ {{ __('Requires you to deploy or set up cloud-hosted Sentry.') }}
+ </template>
+ </gl-form-radio>
+ <gl-form-radio name="error-tracking-integrated" :value="true">
+ {{ __('GitLab') }}
+ <template #help>
+ {{ __('Uses GitLab as a lightweight alternative to Sentry.') }}
+ </template>
+ </gl-form-radio>
+ </gl-form-radio-group>
+ </gl-form-group>
+ <div v-if="!integrated" class="js-sentry-setting-form" data-testid="sentry-setting-form">
+ <error-tracking-form />
+ <div class="form-group">
+ <project-dropdown
+ :has-projects="hasProjects"
+ :invalid-project-label="invalidProjectLabel"
+ :is-project-invalid="isProjectInvalid"
+ :dropdown-label="dropdownLabel"
+ :project-selection-label="projectSelectionLabel"
+ :projects="projects"
+ :selected-project="selectedProject"
+ :token="token"
+ @select-project="updateSelectedProject"
+ />
+ </div>
</div>
<gl-button
:disabled="settingsLoading"
diff --git a/app/assets/javascripts/error_tracking_settings/index.js b/app/assets/javascripts/error_tracking_settings/index.js
index ce315963723..324b3292834 100644
--- a/app/assets/javascripts/error_tracking_settings/index.js
+++ b/app/assets/javascripts/error_tracking_settings/index.js
@@ -5,7 +5,15 @@ import createStore from './store';
export default () => {
const formContainerEl = document.querySelector('.js-error-tracking-form');
const {
- dataset: { apiHost, enabled, project, token, listProjectsEndpoint, operationsSettingsEndpoint },
+ dataset: {
+ apiHost,
+ enabled,
+ integrated,
+ project,
+ token,
+ listProjectsEndpoint,
+ operationsSettingsEndpoint,
+ },
} = formContainerEl;
return new Vue({
@@ -16,6 +24,7 @@ export default () => {
props: {
initialApiHost: apiHost,
initialEnabled: enabled,
+ initialIntegrated: integrated,
initialProject: project,
initialToken: token,
listProjectsEndpoint,
diff --git a/app/assets/javascripts/error_tracking_settings/store/actions.js b/app/assets/javascripts/error_tracking_settings/store/actions.js
index d402d0336d9..972ad58c617 100644
--- a/app/assets/javascripts/error_tracking_settings/store/actions.js
+++ b/app/assets/javascripts/error_tracking_settings/store/actions.js
@@ -79,6 +79,10 @@ export const updateEnabled = ({ commit }, enabled) => {
commit(types.UPDATE_ENABLED, enabled);
};
+export const updateIntegrated = ({ commit }, integrated) => {
+ commit(types.UPDATE_INTEGRATED, integrated);
+};
+
export const updateToken = ({ commit }, token) => {
commit(types.UPDATE_TOKEN, token);
commit(types.RESET_CONNECT);
diff --git a/app/assets/javascripts/error_tracking_settings/store/mutation_types.js b/app/assets/javascripts/error_tracking_settings/store/mutation_types.js
index bf3df383ddc..2cfa14c9b64 100644
--- a/app/assets/javascripts/error_tracking_settings/store/mutation_types.js
+++ b/app/assets/javascripts/error_tracking_settings/store/mutation_types.js
@@ -6,6 +6,7 @@ export const UPDATE_API_HOST = 'UPDATE_API_HOST';
export const UPDATE_CONNECT_ERROR = 'UPDATE_CONNECT_ERROR';
export const UPDATE_CONNECT_SUCCESS = 'UPDATE_CONNECT_SUCCESS';
export const UPDATE_ENABLED = 'UPDATE_ENABLED';
+export const UPDATE_INTEGRATED = 'UPDATE_INTEGRATED';
export const UPDATE_SELECTED_PROJECT = 'UPDATE_SELECTED_PROJECT';
export const UPDATE_SETTINGS_LOADING = 'UPDATE_SETTINGS_LOADING';
export const UPDATE_TOKEN = 'UPDATE_TOKEN';
diff --git a/app/assets/javascripts/error_tracking_settings/store/mutations.js b/app/assets/javascripts/error_tracking_settings/store/mutations.js
index 2242169aa1e..a1b43ccaaee 100644
--- a/app/assets/javascripts/error_tracking_settings/store/mutations.js
+++ b/app/assets/javascripts/error_tracking_settings/store/mutations.js
@@ -20,9 +20,18 @@ export default {
},
[types.SET_INITIAL_STATE](
state,
- { apiHost, enabled, project, token, listProjectsEndpoint, operationsSettingsEndpoint },
+ {
+ apiHost,
+ enabled,
+ integrated,
+ project,
+ token,
+ listProjectsEndpoint,
+ operationsSettingsEndpoint,
+ },
) {
state.enabled = parseBoolean(enabled);
+ state.integrated = parseBoolean(integrated);
state.apiHost = apiHost;
state.token = token;
state.listProjectsEndpoint = listProjectsEndpoint;
@@ -38,6 +47,9 @@ export default {
[types.UPDATE_ENABLED](state, enabled) {
state.enabled = enabled;
},
+ [types.UPDATE_INTEGRATED](state, integrated) {
+ state.integrated = integrated;
+ },
[types.UPDATE_TOKEN](state, token) {
state.token = token;
},
diff --git a/app/assets/javascripts/error_tracking_settings/store/state.js b/app/assets/javascripts/error_tracking_settings/store/state.js
index ab616f11e83..ee5597abeb3 100644
--- a/app/assets/javascripts/error_tracking_settings/store/state.js
+++ b/app/assets/javascripts/error_tracking_settings/store/state.js
@@ -1,6 +1,7 @@
export default () => ({
apiHost: '',
enabled: false,
+ integrated: false,
token: '',
projects: [],
isLoadingProjects: false,
diff --git a/app/assets/javascripts/error_tracking_settings/utils.js b/app/assets/javascripts/error_tracking_settings/utils.js
index 5d18ac8e802..7ef5f7bbd34 100644
--- a/app/assets/javascripts/error_tracking_settings/utils.js
+++ b/app/assets/javascripts/error_tracking_settings/utils.js
@@ -1,6 +1,12 @@
export const projectKeys = ['name', 'organizationName', 'organizationSlug', 'slug'];
-export const transformFrontendSettings = ({ apiHost, enabled, token, selectedProject }) => {
+export const transformFrontendSettings = ({
+ apiHost,
+ enabled,
+ integrated,
+ token,
+ selectedProject,
+}) => {
const project = selectedProject
? {
slug: selectedProject.slug,
@@ -10,7 +16,7 @@ export const transformFrontendSettings = ({ apiHost, enabled, token, selectedPro
}
: null;
- return { api_host: apiHost || null, enabled, token: token || null, project };
+ return { api_host: apiHost || null, enabled, integrated, token: token || null, project };
};
export const getDisplayName = (project) => `${project.organizationName} | ${project.slug}`;
diff --git a/app/assets/javascripts/experimentation/utils.js b/app/assets/javascripts/experimentation/utils.js
index e572280a62c..9079c238169 100644
--- a/app/assets/javascripts/experimentation/utils.js
+++ b/app/assets/javascripts/experimentation/utils.js
@@ -1,18 +1,27 @@
// This file only applies to use of experiments through https://gitlab.com/gitlab-org/gitlab-experiment
-import { get } from 'lodash';
+import { get, pick } from 'lodash';
import { DEFAULT_VARIANT, CANDIDATE_VARIANT, TRACKING_CONTEXT_SCHEMA } from './constants';
+function getExperimentsData() {
+ return get(window, ['gon', 'experiment'], {});
+}
+
+function convertExperimentDataToExperimentContext(experimentData) {
+ return { schema: TRACKING_CONTEXT_SCHEMA, data: experimentData };
+}
+
export function getExperimentData(experimentName) {
- return get(window, ['gon', 'experiment', experimentName]);
+ return getExperimentsData()[experimentName];
}
export function getExperimentContexts(...experimentNames) {
- return experimentNames
- .map((name) => {
- const data = getExperimentData(name);
- return data && { schema: TRACKING_CONTEXT_SCHEMA, data };
- })
- .filter((context) => context);
+ return Object.values(pick(getExperimentsData(), experimentNames)).map(
+ convertExperimentDataToExperimentContext,
+ );
+}
+
+export function getAllExperimentContexts() {
+ return Object.values(getExperimentsData()).map(convertExperimentDataToExperimentContext);
}
export function isExperimentVariant(experimentName, variantName) {
diff --git a/app/assets/javascripts/feature_flags/components/edit_feature_flag.vue b/app/assets/javascripts/feature_flags/components/edit_feature_flag.vue
index dde021b67be..05d557db942 100644
--- a/app/assets/javascripts/feature_flags/components/edit_feature_flag.vue
+++ b/app/assets/javascripts/feature_flags/components/edit_feature_flag.vue
@@ -48,7 +48,7 @@ export default {
<gl-toggle
:value="active"
data-testid="feature-flag-status-toggle"
- data-track-event="click_button"
+ data-track-action="click_button"
data-track-label="feature_flag_toggle"
class="gl-mr-4"
:label="__('Feature flag status')"
diff --git a/app/assets/javascripts/feature_flags/components/feature_flags_table.vue b/app/assets/javascripts/feature_flags/components/feature_flags_table.vue
index cfd838bf5a1..f8a8bed2467 100644
--- a/app/assets/javascripts/feature_flags/components/feature_flags_table.vue
+++ b/app/assets/javascripts/feature_flags/components/feature_flags_table.vue
@@ -115,7 +115,7 @@ export default {
:label="$options.i18n.toggleLabel"
label-position="hidden"
data-testid="feature-flag-status-toggle"
- data-track-event="click_button"
+ data-track-action="click_button"
data-track-label="feature_flag_toggle"
@change="toggleFeatureFlag(featureFlag)"
/>
diff --git a/app/assets/javascripts/filtered_search/services/recent_searches_service.js b/app/assets/javascripts/filtered_search/services/recent_searches_service.js
index 56824977a43..c3514198ad9 100644
--- a/app/assets/javascripts/filtered_search/services/recent_searches_service.js
+++ b/app/assets/javascripts/filtered_search/services/recent_searches_service.js
@@ -33,7 +33,7 @@ class RecentSearchesService {
}
static isAvailable() {
- return AccessorUtilities.isLocalStorageAccessSafe();
+ return AccessorUtilities.canUseLocalStorage();
}
}
diff --git a/app/assets/javascripts/frequent_items/components/app.vue b/app/assets/javascripts/frequent_items/components/app.vue
index dd405893e43..8ad9eeaa266 100644
--- a/app/assets/javascripts/frequent_items/components/app.vue
+++ b/app/assets/javascripts/frequent_items/components/app.vue
@@ -84,7 +84,7 @@ export default {
logItemAccess(storageKey, unsanitizedItem) {
const item = sanitizeItem(unsanitizedItem);
- if (!AccessorUtilities.isLocalStorageAccessSafe()) {
+ if (!AccessorUtilities.canUseLocalStorage()) {
return false;
}
diff --git a/app/assets/javascripts/frequent_items/components/frequent_items_list_item.vue b/app/assets/javascripts/frequent_items/components/frequent_items_list_item.vue
index 1137951ccfc..2f451e8353b 100644
--- a/app/assets/javascripts/frequent_items/components/frequent_items_list_item.vue
+++ b/app/assets/javascripts/frequent_items/components/frequent_items_list_item.vue
@@ -1,5 +1,5 @@
<script>
-/* eslint-disable vue/require-default-prop, vue/no-v-html */
+/* eslint-disable vue/require-default-prop */
import { GlButton } from '@gitlab/ui';
import highlight from '~/lib/utils/highlight';
import { truncateNamespace } from '~/lib/utils/text_utility';
@@ -75,7 +75,7 @@ export default {
ref="frequentItemsItemTitle"
:title="itemName"
class="frequent-items-item-title"
- v-html="highlightedItemName"
+ v-html="highlightedItemName /* eslint-disable-line vue/no-v-html */"
></div>
<div
v-if="namespace"
diff --git a/app/assets/javascripts/frequent_items/store/actions.js b/app/assets/javascripts/frequent_items/store/actions.js
index 65a762f54ad..babc2ef2e32 100644
--- a/app/assets/javascripts/frequent_items/store/actions.js
+++ b/app/assets/javascripts/frequent_items/store/actions.js
@@ -25,7 +25,7 @@ export const receiveFrequentItemsError = ({ commit }) => {
export const fetchFrequentItems = ({ state, dispatch }) => {
dispatch('requestFrequentItems');
- if (AccessorUtilities.isLocalStorageAccessSafe()) {
+ if (AccessorUtilities.canUseLocalStorage()) {
const storedFrequentItems = JSON.parse(localStorage.getItem(state.storageKey));
dispatch(
diff --git a/app/assets/javascripts/graphql_shared/constants.js b/app/assets/javascripts/graphql_shared/constants.js
index 312dd0c88dd..692de9dcb88 100644
--- a/app/assets/javascripts/graphql_shared/constants.js
+++ b/app/assets/javascripts/graphql_shared/constants.js
@@ -1,3 +1,5 @@
+export const MINIMUM_SEARCH_LENGTH = 3;
+
export const TYPE_CI_RUNNER = 'Ci::Runner';
export const TYPE_EPIC = 'Epic';
export const TYPE_GROUP = 'Group';
@@ -11,3 +13,5 @@ export const TYPE_SCANNER_PROFILE = 'DastScannerProfile';
export const TYPE_SITE_PROFILE = 'DastSiteProfile';
export const TYPE_USER = 'User';
export const TYPE_VULNERABILITY = 'Vulnerability';
+export const TYPE_NOTE = 'Note';
+export const TYPE_DISCUSSION = 'Discussion';
diff --git a/app/assets/javascripts/groups/components/app.vue b/app/assets/javascripts/groups/components/app.vue
index 2a95b242510..a1ec5942d64 100644
--- a/app/assets/javascripts/groups/components/app.vue
+++ b/app/assets/javascripts/groups/components/app.vue
@@ -136,7 +136,7 @@ export default {
this.updateGroups(res, Boolean(filterGroupsBy));
});
},
- fetchPage(page, filterGroupsBy, sortBy, archived) {
+ fetchPage({ page, filterGroupsBy, sortBy, archived }) {
this.isLoading = true;
return this.fetchGroups({
diff --git a/app/assets/javascripts/groups/components/groups.vue b/app/assets/javascripts/groups/components/groups.vue
index 59a37b2a1d5..18a6d487703 100644
--- a/app/assets/javascripts/groups/components/groups.vue
+++ b/app/assets/javascripts/groups/components/groups.vue
@@ -32,10 +32,10 @@ export default {
},
methods: {
change(page) {
- const filterGroupsParam = getParameterByName('filter');
- const sortParam = getParameterByName('sort');
- const archivedParam = getParameterByName('archived');
- eventHub.$emit(`${this.action}fetchPage`, page, filterGroupsParam, sortParam, archivedParam);
+ const filterGroupsBy = getParameterByName('filter');
+ const sortBy = getParameterByName('sort');
+ const archived = getParameterByName('archived');
+ eventHub.$emit(`${this.action}fetchPage`, { page, filterGroupsBy, sortBy, archived });
},
},
};
diff --git a/app/assets/javascripts/groups/components/invite_members_banner.vue b/app/assets/javascripts/groups/components/invite_members_banner.vue
index 402d9a07c53..dfc1549fb4a 100644
--- a/app/assets/javascripts/groups/components/invite_members_banner.vue
+++ b/app/assets/javascripts/groups/components/invite_members_banner.vue
@@ -1,7 +1,7 @@
<script>
import { GlBanner } from '@gitlab/ui';
import eventHub from '~/invite_members/event_hub';
-import { parseBoolean, setCookie, getCookie } from '~/lib/utils/common_utils';
+import axios from '~/lib/utils/axios_utils';
import { s__ } from '~/locale';
import Tracking from '~/tracking';
@@ -12,10 +12,10 @@ export default {
GlBanner,
},
mixins: [trackingMixin],
- inject: ['svgPath', 'isDismissedKey', 'trackLabel'],
+ inject: ['svgPath', 'trackLabel', 'calloutsPath', 'calloutsFeatureId', 'groupId'],
data() {
return {
- isDismissed: parseBoolean(getCookie(this.isDismissedKey)),
+ isDismissed: false,
tracking: {
label: this.trackLabel,
},
@@ -26,7 +26,16 @@ export default {
},
methods: {
handleClose() {
- setCookie(this.isDismissedKey, true);
+ axios
+ .post(this.calloutsPath, {
+ feature_name: this.calloutsFeatureId,
+ group_id: this.groupId,
+ })
+ .catch((e) => {
+ // eslint-disable-next-line @gitlab/require-i18n-strings, no-console
+ console.error('Failed to dismiss banner.', e);
+ });
+
this.isDismissed = true;
this.track(this.$options.dismissEvent);
},
@@ -61,6 +70,7 @@ export default {
<gl-banner
v-if="!isDismissed"
ref="banner"
+ data-testid="invite-members-banner"
:title="$options.i18n.title"
:button-text="$options.i18n.button_text"
:svg-path="svgPath"
diff --git a/app/assets/javascripts/groups/components/item_stats.vue b/app/assets/javascripts/groups/components/item_stats.vue
index 7a37d1eb93d..46e9d2bec99 100644
--- a/app/assets/javascripts/groups/components/item_stats.vue
+++ b/app/assets/javascripts/groups/components/item_stats.vue
@@ -40,24 +40,31 @@ export default {
return this.item.type === ITEM_TYPE.GROUP;
},
},
+ methods: {
+ displayValue(value) {
+ return this.isGroup && value !== undefined;
+ },
+ },
};
</script>
<template>
<div class="stats gl-text-gray-500">
<item-stats-value
- v-if="isGroup"
+ v-if="displayValue(item.subgroupCount)"
:title="__('Subgroups')"
:value="item.subgroupCount"
css-class="number-subgroups gl-ml-5"
icon-name="folder-o"
+ data-testid="subgroups-count"
/>
<item-stats-value
- v-if="isGroup"
+ v-if="displayValue(item.projectCount)"
:title="__('Projects')"
:value="item.projectCount"
css-class="number-projects gl-ml-5"
icon-name="bookmark"
+ data-testid="projects-count"
/>
<item-stats-value
v-if="isGroup"
diff --git a/app/assets/javascripts/groups/init_invite_members_banner.js b/app/assets/javascripts/groups/init_invite_members_banner.js
index 2052dd6ac8c..38ab4122dab 100644
--- a/app/assets/javascripts/groups/init_invite_members_banner.js
+++ b/app/assets/javascripts/groups/init_invite_members_banner.js
@@ -8,15 +8,24 @@ export default function initInviteMembersBanner() {
return false;
}
- const { svgPath, inviteMembersPath, isDismissedKey, trackLabel } = el.dataset;
+ const {
+ svgPath,
+ inviteMembersPath,
+ trackLabel,
+ calloutsPath,
+ calloutsFeatureId,
+ groupId,
+ } = el.dataset;
return new Vue({
el,
provide: {
svgPath,
inviteMembersPath,
- isDismissedKey,
trackLabel,
+ calloutsPath,
+ calloutsFeatureId,
+ groupId,
},
render: (createElement) => createElement(InviteMembersBanner),
});
diff --git a/app/assets/javascripts/header_search/components/app.vue b/app/assets/javascripts/header_search/components/app.vue
new file mode 100644
index 00000000000..580c27f6c61
--- /dev/null
+++ b/app/assets/javascripts/header_search/components/app.vue
@@ -0,0 +1,83 @@
+<script>
+import { GlSearchBoxByType, GlOutsideDirective as Outside } from '@gitlab/ui';
+import { mapState, mapActions, mapGetters } from 'vuex';
+import { visitUrl } from '~/lib/utils/url_utility';
+import { __ } from '~/locale';
+import HeaderSearchDefaultItems from './header_search_default_items.vue';
+import HeaderSearchScopedItems from './header_search_scoped_items.vue';
+
+export default {
+ name: 'HeaderSearchApp',
+ i18n: {
+ searchPlaceholder: __('Search or jump to...'),
+ },
+ directives: { Outside },
+ components: {
+ GlSearchBoxByType,
+ HeaderSearchDefaultItems,
+ HeaderSearchScopedItems,
+ },
+ data() {
+ return {
+ showDropdown: false,
+ };
+ },
+ computed: {
+ ...mapState(['search']),
+ ...mapGetters(['searchQuery']),
+ searchText: {
+ get() {
+ return this.search;
+ },
+ set(value) {
+ this.setSearch(value);
+ },
+ },
+ showSearchDropdown() {
+ return this.showDropdown && gon?.current_username;
+ },
+ showDefaultItems() {
+ return !this.searchText;
+ },
+ },
+ methods: {
+ ...mapActions(['setSearch']),
+ openDropdown() {
+ this.showDropdown = true;
+ },
+ closeDropdown() {
+ this.showDropdown = false;
+ },
+ submitSearch() {
+ return visitUrl(this.searchQuery);
+ },
+ },
+};
+</script>
+
+<template>
+ <section v-outside="closeDropdown" class="header-search gl-relative">
+ <gl-search-box-by-type
+ v-model="searchText"
+ :debounce="500"
+ autocomplete="off"
+ :placeholder="$options.i18n.searchPlaceholder"
+ @focus="openDropdown"
+ @click="openDropdown"
+ @keydown.enter="submitSearch"
+ @keydown.esc="closeDropdown"
+ />
+ <div
+ v-if="showSearchDropdown"
+ data-testid="header-search-dropdown-menu"
+ class="header-search-dropdown-menu gl-overflow-y-auto gl-absolute gl-left-0 gl-z-index-1 gl-w-full gl-bg-white gl-border-1 gl-rounded-base gl-border-solid gl-border-gray-200 gl-shadow-x0-y2-b4-s0"
+ >
+ <div class="header-search-dropdown-content gl-overflow-y-auto gl-py-2">
+ <header-search-default-items v-if="showDefaultItems" />
+ <template v-else>
+ <header-search-scoped-items />
+ </template>
+ </div>
+ </div>
+ </section>
+</template>
diff --git a/app/assets/javascripts/header_search/components/header_search_default_items.vue b/app/assets/javascripts/header_search/components/header_search_default_items.vue
new file mode 100644
index 00000000000..2871937ed3a
--- /dev/null
+++ b/app/assets/javascripts/header_search/components/header_search_default_items.vue
@@ -0,0 +1,42 @@
+<script>
+import { GlDropdownItem, GlDropdownSectionHeader } from '@gitlab/ui';
+import { mapState, mapGetters } from 'vuex';
+import { __ } from '~/locale';
+
+export default {
+ name: 'HeaderSearchDefaultItems',
+ i18n: {
+ allGitLab: __('All GitLab'),
+ },
+ components: {
+ GlDropdownSectionHeader,
+ GlDropdownItem,
+ },
+ computed: {
+ ...mapState(['searchContext']),
+ ...mapGetters(['defaultSearchOptions']),
+ sectionHeader() {
+ return (
+ this.searchContext.project?.name ||
+ this.searchContext.group?.name ||
+ this.$options.i18n.allGitLab
+ );
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <gl-dropdown-section-header>{{ sectionHeader }}</gl-dropdown-section-header>
+ <gl-dropdown-item
+ v-for="(option, index) in defaultSearchOptions"
+ :id="`default-${index}`"
+ :key="index"
+ tabindex="-1"
+ :href="option.url"
+ >
+ {{ option.title }}
+ </gl-dropdown-item>
+ </div>
+</template>
diff --git a/app/assets/javascripts/header_search/components/header_search_scoped_items.vue b/app/assets/javascripts/header_search/components/header_search_scoped_items.vue
new file mode 100644
index 00000000000..645eba05148
--- /dev/null
+++ b/app/assets/javascripts/header_search/components/header_search_scoped_items.vue
@@ -0,0 +1,31 @@
+<script>
+import { GlDropdownItem } from '@gitlab/ui';
+import { mapState, mapGetters } from 'vuex';
+
+export default {
+ name: 'HeaderSearchScopedItems',
+ components: {
+ GlDropdownItem,
+ },
+ computed: {
+ ...mapState(['search']),
+ ...mapGetters(['scopedSearchOptions']),
+ },
+};
+</script>
+
+<template>
+ <div>
+ <gl-dropdown-item
+ v-for="(option, index) in scopedSearchOptions"
+ :id="`scoped-${index}`"
+ :key="index"
+ tabindex="-1"
+ :href="option.url"
+ >
+ "<span class="gl-font-weight-bold">{{ search }}</span
+ >" {{ option.description }}
+ <span v-if="option.scope" class="gl-font-style-italic">{{ option.scope }}</span>
+ </gl-dropdown-item>
+ </div>
+</template>
diff --git a/app/assets/javascripts/header_search/constants.js b/app/assets/javascripts/header_search/constants.js
new file mode 100644
index 00000000000..fffed7bcbdb
--- /dev/null
+++ b/app/assets/javascripts/header_search/constants.js
@@ -0,0 +1,17 @@
+import { __ } from '~/locale';
+
+export const MSG_ISSUES_ASSIGNED_TO_ME = __('Issues assigned to me');
+
+export const MSG_ISSUES_IVE_CREATED = __("Issues I've created");
+
+export const MSG_MR_ASSIGNED_TO_ME = __('Merge requests assigned to me');
+
+export const MSG_MR_IM_REVIEWER = __("Merge requests that I'm a reviewer");
+
+export const MSG_MR_IVE_CREATED = __("Merge requests I've created");
+
+export const MSG_IN_ALL_GITLAB = __('in all GitLab');
+
+export const MSG_IN_GROUP = __('in group');
+
+export const MSG_IN_PROJECT = __('in project');
diff --git a/app/assets/javascripts/header_search/index.js b/app/assets/javascripts/header_search/index.js
new file mode 100644
index 00000000000..2d37ee137fc
--- /dev/null
+++ b/app/assets/javascripts/header_search/index.js
@@ -0,0 +1,26 @@
+import Vue from 'vue';
+import Translate from '~/vue_shared/translate';
+import HeaderSearchApp from './components/app.vue';
+import createStore from './store';
+
+Vue.use(Translate);
+
+export const initHeaderSearchApp = () => {
+ const el = document.getElementById('js-header-search');
+
+ if (!el) {
+ return false;
+ }
+
+ const { searchPath, issuesPath, mrPath } = el.dataset;
+ let { searchContext } = el.dataset;
+ searchContext = JSON.parse(searchContext);
+
+ return new Vue({
+ el,
+ store: createStore({ searchPath, issuesPath, mrPath, searchContext }),
+ render(createElement) {
+ return createElement(HeaderSearchApp);
+ },
+ });
+};
diff --git a/app/assets/javascripts/header_search/store/actions.js b/app/assets/javascripts/header_search/store/actions.js
new file mode 100644
index 00000000000..841aee04029
--- /dev/null
+++ b/app/assets/javascripts/header_search/store/actions.js
@@ -0,0 +1,5 @@
+import * as types from './mutation_types';
+
+export const setSearch = ({ commit }, value) => {
+ commit(types.SET_SEARCH, value);
+};
diff --git a/app/assets/javascripts/header_search/store/getters.js b/app/assets/javascripts/header_search/store/getters.js
new file mode 100644
index 00000000000..d1e1fc8ad73
--- /dev/null
+++ b/app/assets/javascripts/header_search/store/getters.js
@@ -0,0 +1,135 @@
+import { objectToQuery } from '~/lib/utils/url_utility';
+
+import {
+ MSG_ISSUES_ASSIGNED_TO_ME,
+ MSG_ISSUES_IVE_CREATED,
+ MSG_MR_ASSIGNED_TO_ME,
+ MSG_MR_IM_REVIEWER,
+ MSG_MR_IVE_CREATED,
+ MSG_IN_PROJECT,
+ MSG_IN_GROUP,
+ MSG_IN_ALL_GITLAB,
+} from '../constants';
+
+export const searchQuery = (state) => {
+ const query = {
+ search: state.search,
+ nav_source: 'navbar',
+ project_id: state.searchContext.project?.id,
+ group_id: state.searchContext.group?.id,
+ scope: state.searchContext.scope,
+ };
+
+ return `${state.searchPath}?${objectToQuery(query)}`;
+};
+
+export const scopedIssuesPath = (state) => {
+ return (
+ state.searchContext.project_metadata?.issues_path ||
+ state.searchContext.group_metadata?.issues_path ||
+ state.issuesPath
+ );
+};
+
+export const scopedMRPath = (state) => {
+ return (
+ state.searchContext.project_metadata?.mr_path ||
+ state.searchContext.group_metadata?.mr_path ||
+ state.mrPath
+ );
+};
+
+export const defaultSearchOptions = (state, getters) => {
+ const userName = gon.current_username;
+
+ return [
+ {
+ title: MSG_ISSUES_ASSIGNED_TO_ME,
+ url: `${getters.scopedIssuesPath}/?assignee_username=${userName}`,
+ },
+ {
+ title: MSG_ISSUES_IVE_CREATED,
+ url: `${getters.scopedIssuesPath}/?author_username=${userName}`,
+ },
+ {
+ title: MSG_MR_ASSIGNED_TO_ME,
+ url: `${getters.scopedMRPath}/?assignee_username=${userName}`,
+ },
+ {
+ title: MSG_MR_IM_REVIEWER,
+ url: `${getters.scopedMRPath}/?reviewer_username=${userName}`,
+ },
+ {
+ title: MSG_MR_IVE_CREATED,
+ url: `${getters.scopedMRPath}/?author_username=${userName}`,
+ },
+ ];
+};
+
+export const projectUrl = (state) => {
+ if (!state.searchContext.project || !state.searchContext.group) {
+ return null;
+ }
+
+ const query = {
+ search: state.search,
+ nav_source: 'navbar',
+ project_id: state.searchContext.project.id,
+ group_id: state.searchContext.group.id,
+ scope: state.searchContext.scope,
+ };
+
+ return `${state.searchPath}?${objectToQuery(query)}`;
+};
+
+export const groupUrl = (state) => {
+ if (!state.searchContext.group) {
+ return null;
+ }
+
+ const query = {
+ search: state.search,
+ nav_source: 'navbar',
+ group_id: state.searchContext.group.id,
+ scope: state.searchContext.scope,
+ };
+
+ return `${state.searchPath}?${objectToQuery(query)}`;
+};
+
+export const allUrl = (state) => {
+ const query = {
+ search: state.search,
+ nav_source: 'navbar',
+ scope: state.searchContext.scope,
+ };
+
+ return `${state.searchPath}?${objectToQuery(query)}`;
+};
+
+export const scopedSearchOptions = (state, getters) => {
+ const options = [];
+
+ if (state.searchContext.project) {
+ options.push({
+ scope: state.searchContext.project.name,
+ description: MSG_IN_PROJECT,
+ url: getters.projectUrl,
+ });
+ }
+
+ if (state.searchContext.group) {
+ options.push({
+ scope: state.searchContext.group.name,
+ description: MSG_IN_GROUP,
+ url: getters.groupUrl,
+ });
+ }
+
+ options.push({
+ description: MSG_IN_ALL_GITLAB,
+ url: getters.allUrl,
+ });
+
+ return options;
+};
diff --git a/app/assets/javascripts/header_search/store/index.js b/app/assets/javascripts/header_search/store/index.js
new file mode 100644
index 00000000000..8b74f8662a5
--- /dev/null
+++ b/app/assets/javascripts/header_search/store/index.js
@@ -0,0 +1,18 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import * as actions from './actions';
+import * as getters from './getters';
+import mutations from './mutations';
+import createState from './state';
+
+Vue.use(Vuex);
+
+export const getStoreConfig = ({ searchPath, issuesPath, mrPath, searchContext }) => ({
+ actions,
+ getters,
+ mutations,
+ state: createState({ searchPath, issuesPath, mrPath, searchContext }),
+});
+
+const createStore = (config) => new Vuex.Store(getStoreConfig(config));
+export default createStore;
diff --git a/app/assets/javascripts/header_search/store/mutation_types.js b/app/assets/javascripts/header_search/store/mutation_types.js
new file mode 100644
index 00000000000..0bc94ae055f
--- /dev/null
+++ b/app/assets/javascripts/header_search/store/mutation_types.js
@@ -0,0 +1 @@
+export const SET_SEARCH = 'SET_SEARCH';
diff --git a/app/assets/javascripts/header_search/store/mutations.js b/app/assets/javascripts/header_search/store/mutations.js
new file mode 100644
index 00000000000..5b1438929d4
--- /dev/null
+++ b/app/assets/javascripts/header_search/store/mutations.js
@@ -0,0 +1,7 @@
+import * as types from './mutation_types';
+
+export default {
+ [types.SET_SEARCH](state, value) {
+ state.search = value;
+ },
+};
diff --git a/app/assets/javascripts/header_search/store/state.js b/app/assets/javascripts/header_search/store/state.js
new file mode 100644
index 00000000000..fb2c83dbbe3
--- /dev/null
+++ b/app/assets/javascripts/header_search/store/state.js
@@ -0,0 +1,8 @@
+const createState = ({ searchPath, issuesPath, mrPath, searchContext }) => ({
+ searchPath,
+ issuesPath,
+ mrPath,
+ searchContext,
+ search: '',
+});
+export default createState;
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/success_message.vue b/app/assets/javascripts/ide/components/commit_sidebar/success_message.vue
index 977efb0ca22..5a7d7917f8a 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/success_message.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/success_message.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { mapState } from 'vuex';
export default {
@@ -17,7 +16,7 @@ export default {
<div class="gl-mr-3 gl-ml-3">
<div class="text-content text-center">
<h4>{{ __('All changes are committed') }}</h4>
- <p v-html="lastCommitMsg"></p>
+ <p v-html="lastCommitMsg /* eslint-disable-line vue/no-v-html */"></p>
</div>
</div>
</div>
diff --git a/app/assets/javascripts/ide/components/error_message.vue b/app/assets/javascripts/ide/components/error_message.vue
index 2b75d10f659..67eedc6b37f 100644
--- a/app/assets/javascripts/ide/components/error_message.vue
+++ b/app/assets/javascripts/ide/components/error_message.vue
@@ -1,6 +1,5 @@
<script>
-/* eslint-disable vue/no-v-html */
-import { GlAlert, GlLoadingIcon } from '@gitlab/ui';
+import { GlAlert, GlLoadingIcon, GlSafeHtmlDirective } from '@gitlab/ui';
import { mapActions } from 'vuex';
export default {
@@ -8,6 +7,9 @@ export default {
GlAlert,
GlLoadingIcon,
},
+ directives: {
+ SafeHtml: GlSafeHtmlDirective,
+ },
props: {
message: {
type: Object,
@@ -56,7 +58,7 @@ export default {
@dismiss="dismiss"
@primaryAction="doAction"
>
- <span v-html="message.text"></span>
+ <span v-safe-html="message.text"></span>
<gl-loading-icon v-show="isLoading" size="sm" inline class="vertical-align-middle ml-1" />
</gl-alert>
</template>
diff --git a/app/assets/javascripts/ide/components/jobs/detail.vue b/app/assets/javascripts/ide/components/jobs/detail.vue
index 8e611503cb4..c142992a9d1 100644
--- a/app/assets/javascripts/ide/components/jobs/detail.vue
+++ b/app/assets/javascripts/ide/components/jobs/detail.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { GlTooltipDirective, GlButton, GlIcon } from '@gitlab/ui';
import { throttle } from 'lodash';
import { mapActions, mapState } from 'vuex';
@@ -102,7 +101,7 @@ export default {
<code
v-show="!detailJob.isLoading"
class="bash"
- v-html="jobOutput"
+ v-html="jobOutput /* eslint-disable-line vue/no-v-html */"
>
</code>
<div
diff --git a/app/assets/javascripts/ide/services/terminals.js b/app/assets/javascripts/ide/services/terminals.js
index ea54733baa4..99121948196 100644
--- a/app/assets/javascripts/ide/services/terminals.js
+++ b/app/assets/javascripts/ide/services/terminals.js
@@ -1,6 +1,8 @@
import axios from '~/lib/utils/axios_utils';
+import { joinPaths } from '~/lib/utils/url_utility';
-export const baseUrl = (projectPath) => `/${projectPath}/ide_terminals`;
+export const baseUrl = (projectPath) =>
+ joinPaths(gon.relative_url_root || '', `/${projectPath}/ide_terminals`);
export const checkConfig = (projectPath, branch) =>
axios.post(`${baseUrl(projectPath)}/check_config`, {
diff --git a/app/assets/javascripts/ide/utils.js b/app/assets/javascripts/ide/utils.js
index 275fecc5a32..ec3630cc5eb 100644
--- a/app/assets/javascripts/ide/utils.js
+++ b/app/assets/javascripts/ide/utils.js
@@ -43,7 +43,10 @@ const KNOWN_TYPES = [
},
];
-export function isTextFile({ name, raw, content, mimeType = '' }) {
+export function isTextFile({ name, raw, binary, content, mimeType = '' }) {
+ // some file objects already have a `binary` property set on them. If so, use it first
+ if (typeof binary === 'boolean') return !binary;
+
const knownType = KNOWN_TYPES.find((type) => type.isMatch(mimeType, name));
if (knownType) return knownType.isText;
diff --git a/app/assets/javascripts/import_entities/import_groups/components/import_actions_cell.vue b/app/assets/javascripts/import_entities/import_groups/components/import_actions_cell.vue
new file mode 100644
index 00000000000..104c84173fc
--- /dev/null
+++ b/app/assets/javascripts/import_entities/import_groups/components/import_actions_cell.vue
@@ -0,0 +1,69 @@
+<script>
+import { GlButton, GlIcon, GlTooltipDirective as GlTooltip } from '@gitlab/ui';
+import { joinPaths } from '~/lib/utils/url_utility';
+import { isFinished, isInvalid, isAvailableForImport } from '../utils';
+
+export default {
+ components: {
+ GlIcon,
+ GlButton,
+ },
+ directives: {
+ GlTooltip,
+ },
+ props: {
+ group: {
+ type: Object,
+ required: true,
+ },
+ groupPathRegex: {
+ type: RegExp,
+ required: true,
+ },
+ },
+ computed: {
+ fullLastImportPath() {
+ return this.group.last_import_target
+ ? `${this.group.last_import_target.target_namespace}/${this.group.last_import_target.new_name}`
+ : null;
+ },
+ absoluteLastImportPath() {
+ return joinPaths(gon.relative_url_root || '/', this.fullLastImportPath);
+ },
+ isAvailableForImport() {
+ return isAvailableForImport(this.group);
+ },
+ isFinished() {
+ return isFinished(this.group);
+ },
+ isInvalid() {
+ return isInvalid(this.group, this.groupPathRegex);
+ },
+ },
+};
+</script>
+
+<template>
+ <span class="gl-white-space-nowrap gl-inline-flex gl-align-items-center">
+ <gl-button
+ v-if="isAvailableForImport"
+ :disabled="isInvalid"
+ variant="confirm"
+ category="secondary"
+ data-qa-selector="import_group_button"
+ @click="$emit('import-group')"
+ >
+ {{ isFinished ? __('Re-import') : __('Import') }}
+ </gl-button>
+ <gl-icon
+ v-if="isFinished"
+ v-gl-tooltip
+ :size="16"
+ name="information-o"
+ :title="
+ s__('BulkImports|Re-import creates a new group. It does not sync with the existing group.')
+ "
+ class="gl-ml-3"
+ />
+ </span>
+</template>
diff --git a/app/assets/javascripts/import_entities/import_groups/components/import_source_cell.vue b/app/assets/javascripts/import_entities/import_groups/components/import_source_cell.vue
new file mode 100644
index 00000000000..2de9bd4f868
--- /dev/null
+++ b/app/assets/javascripts/import_entities/import_groups/components/import_source_cell.vue
@@ -0,0 +1,53 @@
+<script>
+import { GlLink, GlSprintf, GlIcon } from '@gitlab/ui';
+import { joinPaths } from '~/lib/utils/url_utility';
+import { isFinished } from '../utils';
+
+export default {
+ components: {
+ GlLink,
+ GlSprintf,
+ GlIcon,
+ },
+ props: {
+ group: {
+ type: Object,
+ required: true,
+ },
+ },
+ computed: {
+ fullLastImportPath() {
+ return this.group.last_import_target
+ ? `${this.group.last_import_target.target_namespace}/${this.group.last_import_target.new_name}`
+ : null;
+ },
+ absoluteLastImportPath() {
+ return joinPaths(gon.relative_url_root || '/', this.fullLastImportPath);
+ },
+ isFinished() {
+ return isFinished(this.group);
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <gl-link
+ :href="group.web_url"
+ target="_blank"
+ class="gl-display-inline-flex gl-align-items-center gl-h-7"
+ >
+ {{ group.full_path }} <gl-icon name="external-link" />
+ </gl-link>
+ <div v-if="isFinished && fullLastImportPath" class="gl-font-sm">
+ <gl-sprintf :message="s__('BulkImport|Last imported to %{link}')">
+ <template #link>
+ <gl-link :href="absoluteLastImportPath" class="gl-font-sm" target="_blank">{{
+ fullLastImportPath
+ }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/import_entities/import_groups/components/import_table.vue b/app/assets/javascripts/import_entities/import_groups/components/import_table.vue
index db44be2bcd7..04b037ecc2b 100644
--- a/app/assets/javascripts/import_entities/import_groups/components/import_table.vue
+++ b/app/assets/javascripts/import_entities/import_groups/components/import_table.vue
@@ -9,19 +9,19 @@ import {
GlLoadingIcon,
GlSearchBoxByClick,
GlSprintf,
- GlSafeHtmlDirective as SafeHtml,
GlTable,
GlFormCheckbox,
} from '@gitlab/ui';
import { s__, __, n__ } from '~/locale';
import PaginationLinks from '~/vue_shared/components/pagination_links.vue';
-import ImportStatus from '../../components/import_status.vue';
-import { STATUSES } from '../../constants';
+import ImportStatusCell from '../../components/import_status.vue';
import importGroupsMutation from '../graphql/mutations/import_groups.mutation.graphql';
import setImportTargetMutation from '../graphql/mutations/set_import_target.mutation.graphql';
import availableNamespacesQuery from '../graphql/queries/available_namespaces.query.graphql';
import bulkImportSourceGroupsQuery from '../graphql/queries/bulk_import_source_groups.query.graphql';
-import { isInvalid } from '../utils';
+import { isInvalid, isFinished, isAvailableForImport } from '../utils';
+import ImportActionsCell from './import_actions_cell.vue';
+import ImportSourceCell from './import_source_cell.vue';
import ImportTargetCell from './import_target_cell.vue';
const PAGE_SIZES = [20, 50, 100];
@@ -43,13 +43,12 @@ export default {
GlFormCheckbox,
GlSprintf,
GlTable,
- ImportStatus,
+ ImportSourceCell,
ImportTargetCell,
+ ImportStatusCell,
+ ImportActionsCell,
PaginationLinks,
},
- directives: {
- SafeHtml,
- },
props: {
sourceUrl: {
@@ -136,7 +135,7 @@ export default {
},
availableGroupsForImport() {
- return this.groups.filter((g) => g.progress.status === STATUSES.NONE && !this.isInvalid(g));
+ return this.groups.filter((g) => isAvailableForImport(g) && !this.isInvalid(g));
},
humanizedTotal() {
@@ -190,6 +189,24 @@ export default {
},
methods: {
+ isUnselectable(group) {
+ return !this.isAvailableForImport(group) || this.isInvalid(group);
+ },
+
+ rowClasses(group) {
+ const DEFAULT_CLASSES = [
+ 'gl-border-gray-200',
+ 'gl-border-0',
+ 'gl-border-b-1',
+ 'gl-border-solid',
+ ];
+ const result = [...DEFAULT_CLASSES];
+ if (this.isUnselectable(group)) {
+ result.push('gl-cursor-default!');
+ }
+ return result;
+ },
+
qaRowAttributes(group, type) {
if (type === 'row') {
return {
@@ -201,10 +218,8 @@ export default {
return {};
},
- isAlreadyImported(group) {
- return group.progress.status !== STATUSES.NONE;
- },
-
+ isAvailableForImport,
+ isFinished,
isInvalid(group) {
return isInvalid(group, this.groupPathRegex);
},
@@ -253,7 +268,7 @@ export default {
const table = this.getTableRef();
this.groups.forEach((group, idx) => {
- if (table.isRowSelected(idx) && (this.isAlreadyImported(group) || this.isInvalid(group))) {
+ if (table.isRowSelected(idx) && this.isUnselectable(group)) {
table.unselectRow(idx);
}
});
@@ -291,7 +306,7 @@ export default {
<strong>{{ filter }}</strong>
</template>
<template #link>
- <gl-link class="gl-display-inline-block" :href="sourceUrl" target="_blank">
+ <gl-link :href="sourceUrl" target="_blank">
{{ sourceUrl }} <gl-icon name="external-link" class="vertical-align-middle" />
</gl-link>
</template>
@@ -338,7 +353,7 @@ export default {
ref="table"
class="gl-w-full"
data-qa-selector="import_table"
- tbody-tr-class="gl-border-gray-200 gl-border-0 gl-border-b-1 gl-border-solid"
+ :tbody-tr-class="rowClasses"
:tbody-tr-attr="qaRowAttributes"
:items="groups"
:fields="$options.fields"
@@ -360,18 +375,12 @@ export default {
<gl-form-checkbox
class="gl-h-7 gl-pt-3"
:checked="rowSelected"
- :disabled="isAlreadyImported(group) || isInvalid(group)"
+ :disabled="!isAvailableForImport(group) || isInvalid(group)"
@change="rowSelected ? unselectRow() : selectRow()"
/>
</template>
- <template #cell(web_url)="{ value: web_url, item: { full_path } }">
- <gl-link
- :href="web_url"
- target="_blank"
- class="gl-display-inline-flex gl-align-items-center gl-h-7"
- >
- {{ full_path }} <gl-icon name="external-link" />
- </gl-link>
+ <template #cell(web_url)="{ item: group }">
+ <import-source-cell :group="group" />
</template>
<template #cell(import_target)="{ item: group }">
<import-target-cell
@@ -388,19 +397,14 @@ export default {
/>
</template>
<template #cell(progress)="{ value: { status } }">
- <import-status :status="status" class="gl-line-height-32" />
+ <import-status-cell :status="status" class="gl-line-height-32" />
</template>
<template #cell(actions)="{ item: group }">
- <gl-button
- v-if="!isAlreadyImported(group)"
- :disabled="isInvalid(group)"
- variant="confirm"
- category="secondary"
- data-qa-selector="import_group_button"
- @click="importGroups([group.id])"
- >
- {{ __('Import') }}
- </gl-button>
+ <import-actions-cell
+ :group="group"
+ :group-path-regex="groupPathRegex"
+ @import-group="importGroups([group.id])"
+ />
</template>
</gl-table>
<div v-if="hasGroups" class="gl-display-flex gl-mt-3 gl-align-items-center">
diff --git a/app/assets/javascripts/import_entities/import_groups/components/import_target_cell.vue b/app/assets/javascripts/import_entities/import_groups/components/import_target_cell.vue
index 7359d4f239e..daced740c94 100644
--- a/app/assets/javascripts/import_entities/import_groups/components/import_target_cell.vue
+++ b/app/assets/javascripts/import_entities/import_groups/components/import_target_cell.vue
@@ -3,14 +3,16 @@ import {
GlDropdownDivider,
GlDropdownItem,
GlDropdownSectionHeader,
- GlLink,
GlFormInput,
} from '@gitlab/ui';
-import { joinPaths } from '~/lib/utils/url_utility';
import { s__ } from '~/locale';
import ImportGroupDropdown from '../../components/group_dropdown.vue';
-import { STATUSES } from '../../constants';
-import { isInvalid, getInvalidNameValidationMessage, isNameValid } from '../utils';
+import {
+ isInvalid,
+ getInvalidNameValidationMessage,
+ isNameValid,
+ isAvailableForImport,
+} from '../utils';
export default {
components: {
@@ -18,7 +20,6 @@ export default {
GlDropdownDivider,
GlDropdownItem,
GlDropdownSectionHeader,
- GlLink,
GlFormInput,
},
props: {
@@ -61,20 +62,8 @@ export default {
return isNameValid(this.group, this.groupPathRegex);
},
- isAlreadyImported() {
- return this.group.progress.status !== STATUSES.NONE;
- },
-
- isFinished() {
- return this.group.progress.status === STATUSES.FINISHED;
- },
-
- fullPath() {
- return `${this.importTarget.target_namespace}/${this.importTarget.new_name}`;
- },
-
- absolutePath() {
- return joinPaths(gon.relative_url_root || '/', this.fullPath);
+ isAvailableForImport() {
+ return isAvailableForImport(this.group);
},
},
@@ -85,25 +74,11 @@ export default {
</script>
<template>
- <gl-link
- v-if="isFinished"
- class="gl-display-inline-flex gl-align-items-center gl-h-7"
- :href="absolutePath"
- >
- {{ fullPath }}
- </gl-link>
-
- <div
- v-else
- class="gl-display-flex gl-align-items-stretch"
- :class="{
- disabled: isAlreadyImported,
- }"
- >
+ <div class="gl-display-flex gl-align-items-stretch">
<import-group-dropdown
#default="{ namespaces }"
:text="importTarget.target_namespace"
- :disabled="isAlreadyImported"
+ :disabled="!isAvailableForImport"
:namespaces="availableNamespaceNames"
toggle-class="gl-rounded-top-right-none! gl-rounded-bottom-right-none!"
class="gl-h-7 gl-flex-grow-1"
@@ -131,8 +106,8 @@ export default {
<div
class="gl-h-7 gl-px-3 gl-display-flex gl-align-items-center gl-border-solid gl-border-0 gl-border-t-1 gl-border-b-1 gl-bg-gray-10"
:class="{
- 'gl-text-gray-400 gl-border-gray-100': isAlreadyImported,
- 'gl-border-gray-200': !isAlreadyImported,
+ 'gl-text-gray-400 gl-border-gray-100': !isAvailableForImport,
+ 'gl-border-gray-200': isAvailableForImport,
}"
>
/
@@ -141,11 +116,11 @@ export default {
<gl-form-input
class="gl-rounded-top-left-none gl-rounded-bottom-left-none"
:class="{
- 'gl-inset-border-1-gray-200!': !isAlreadyImported,
- 'gl-inset-border-1-gray-100!': isAlreadyImported,
- 'is-invalid': isInvalid && !isAlreadyImported,
+ 'gl-inset-border-1-gray-200!': isAvailableForImport,
+ 'gl-inset-border-1-gray-100!': !isAvailableForImport,
+ 'is-invalid': isInvalid && isAvailableForImport,
}"
- :disabled="isAlreadyImported"
+ :disabled="!isAvailableForImport"
:value="importTarget.new_name"
@input="$emit('update-new-name', $event)"
/>
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/client_factory.js b/app/assets/javascripts/import_entities/import_groups/graphql/client_factory.js
index 57188441158..c08cf909a00 100644
--- a/app/assets/javascripts/import_entities/import_groups/graphql/client_factory.js
+++ b/app/assets/javascripts/import_entities/import_groups/graphql/client_factory.js
@@ -5,10 +5,13 @@ import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils';
import { s__ } from '~/locale';
import { STATUSES } from '../../constants';
import { i18n, NEW_NAME_FIELD } from '../constants';
+import { isAvailableForImport } from '../utils';
import bulkImportSourceGroupItemFragment from './fragments/bulk_import_source_group_item.fragment.graphql';
+import bulkImportSourceGroupProgressFragment from './fragments/bulk_import_source_group_progress.fragment.graphql';
import addValidationErrorMutation from './mutations/add_validation_error.mutation.graphql';
import removeValidationErrorMutation from './mutations/remove_validation_error.mutation.graphql';
import setImportProgressMutation from './mutations/set_import_progress.mutation.graphql';
+import setImportTargetMutation from './mutations/set_import_target.mutation.graphql';
import updateImportStatusMutation from './mutations/update_import_status.mutation.graphql';
import availableNamespacesQuery from './queries/available_namespaces.query.graphql';
import bulkImportSourceGroupQuery from './queries/bulk_import_source_group.query.graphql';
@@ -34,6 +37,7 @@ function makeGroup(data) {
};
const NESTED_OBJECT_FIELDS = {
import_target: clientTypenames.BulkImportTarget,
+ last_import_target: clientTypenames.BulkImportTarget,
progress: clientTypenames.BulkImportProgress,
};
@@ -55,6 +59,7 @@ async function checkImportTargetIsValid({ client, newName, targetNamespace, sour
data: { existingGroup, existingProject },
} = await client.query({
query: groupAndProjectQuery,
+ fetchPolicy: 'no-cache',
variables: {
fullPath: `${targetNamespace}/${newName}`,
},
@@ -82,6 +87,7 @@ async function checkImportTargetIsValid({ client, newName, targetNamespace, sour
}
const localProgressId = (id) => `not-started-${id}`;
+const nextName = (name) => `${name}-1`;
export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGroupsManager }) {
const groupsManager = new GroupsManager({
@@ -140,17 +146,28 @@ export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGr
const { jobId, importState: cachedImportState } =
groupsManager.getImportStateFromStorageByGroupId(group.id) ?? {};
+ const status = cachedImportState?.status ?? STATUSES.NONE;
+
+ const importTarget =
+ status === STATUSES.FINISHED && cachedImportState.importTarget
+ ? {
+ target_namespace: cachedImportState.importTarget.target_namespace,
+ new_name: nextName(cachedImportState.importTarget.new_name),
+ }
+ : cachedImportState?.importTarget ?? {
+ new_name: group.full_path,
+ target_namespace: availableNamespaces[0]?.full_path ?? '',
+ };
+
return makeGroup({
...group,
validation_errors: [],
progress: {
id: jobId ?? localProgressId(group.id),
- status: cachedImportState?.status ?? STATUSES.NONE,
- },
- import_target: cachedImportState?.importTarget ?? {
- new_name: group.full_path,
- target_namespace: availableNamespaces[0]?.full_path ?? '',
+ status,
},
+ import_target: importTarget,
+ last_import_target: cachedImportState?.importTarget ?? null,
});
}),
pageInfo: {
@@ -161,7 +178,7 @@ export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGr
setTimeout(() => {
response.nodes.forEach((group) => {
- if (group.progress.status === STATUSES.NONE) {
+ if (isAvailableForImport(group)) {
checkImportTargetIsValid({
client,
newName: group.import_target.new_name,
@@ -193,32 +210,18 @@ export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGr
targetNamespace,
newName,
});
+
return makeGroup({
id: sourceGroupId,
import_target: {
target_namespace: targetNamespace,
new_name: newName,
+ id: sourceGroupId,
},
});
},
- setTargetNamespace: (_, { targetNamespace, sourceGroupId }) =>
- makeGroup({
- id: sourceGroupId,
- import_target: {
- target_namespace: targetNamespace,
- },
- }),
-
- setNewName: (_, { newName, sourceGroupId }) =>
- makeGroup({
- id: sourceGroupId,
- import_target: {
- new_name: newName,
- },
- }),
-
- async setImportProgress(_, { sourceGroupId, status, jobId }) {
+ async setImportProgress(_, { sourceGroupId, status, jobId, importTarget }) {
if (jobId) {
groupsManager.updateImportProgress(jobId, status);
}
@@ -229,16 +232,46 @@ export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGr
id: jobId ?? localProgressId(sourceGroupId),
status,
},
+ last_import_target: {
+ __typename: clientTypenames.BulkImportTarget,
+ ...importTarget,
+ },
});
},
- async updateImportStatus(_, { id, status }) {
- groupsManager.updateImportProgress(id, status);
+ async updateImportStatus(_, { id, status: newStatus }, { client, getCacheKey }) {
+ groupsManager.updateImportProgress(id, newStatus);
+
+ const progressItem = client.readFragment({
+ fragment: bulkImportSourceGroupProgressFragment,
+ fragmentName: 'BulkImportSourceGroupProgress',
+ id: getCacheKey({
+ __typename: clientTypenames.BulkImportProgress,
+ id,
+ }),
+ });
+
+ const isInProgress = Boolean(progressItem);
+ const { status: currentStatus } = progressItem ?? {};
+ if (newStatus === STATUSES.FINISHED && isInProgress && currentStatus !== newStatus) {
+ const groups = groupsManager.getImportedGroupsByJobId(id);
+
+ groups.forEach(async ({ id: groupId, importTarget }) => {
+ client.mutate({
+ mutation: setImportTargetMutation,
+ variables: {
+ sourceGroupId: groupId,
+ targetNamespace: importTarget.target_namespace,
+ newName: nextName(importTarget.new_name),
+ },
+ });
+ });
+ }
return {
__typename: clientTypenames.BulkImportProgress,
id,
- status,
+ status: newStatus,
};
},
@@ -327,10 +360,10 @@ export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGr
return { status: STATUSES.NONE };
})
.then((newStatus) =>
- sourceGroupIds.forEach((sourceGroupId) =>
+ sourceGroupIds.forEach((sourceGroupId, idx) =>
client.mutate({
mutation: setImportProgressMutation,
- variables: { sourceGroupId, ...newStatus },
+ variables: { sourceGroupId, ...newStatus, importTarget: groups[idx].import_target },
}),
),
)
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/fragments/bulk_import_source_group_item.fragment.graphql b/app/assets/javascripts/import_entities/import_groups/graphql/fragments/bulk_import_source_group_item.fragment.graphql
index 47675cd1bd0..089340b3c48 100644
--- a/app/assets/javascripts/import_entities/import_groups/graphql/fragments/bulk_import_source_group_item.fragment.graphql
+++ b/app/assets/javascripts/import_entities/import_groups/graphql/fragments/bulk_import_source_group_item.fragment.graphql
@@ -12,6 +12,10 @@ fragment BulkImportSourceGroupItem on ClientBulkImportSourceGroup {
target_namespace
new_name
}
+ last_import_target {
+ target_namespace
+ new_name
+ }
validation_errors {
field
message
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/mutations/set_import_progress.mutation.graphql b/app/assets/javascripts/import_entities/import_groups/graphql/mutations/set_import_progress.mutation.graphql
index 2ec1269932a..43301554de3 100644
--- a/app/assets/javascripts/import_entities/import_groups/graphql/mutations/set_import_progress.mutation.graphql
+++ b/app/assets/javascripts/import_entities/import_groups/graphql/mutations/set_import_progress.mutation.graphql
@@ -1,9 +1,23 @@
-mutation setImportProgress($status: String!, $sourceGroupId: String!, $jobId: String) {
- setImportProgress(status: $status, sourceGroupId: $sourceGroupId, jobId: $jobId) @client {
+mutation setImportProgress(
+ $status: String!
+ $sourceGroupId: String!
+ $jobId: String
+ $importTarget: ImportTargetInput!
+) {
+ setImportProgress(
+ status: $status
+ sourceGroupId: $sourceGroupId
+ jobId: $jobId
+ importTarget: $importTarget
+ ) @client {
id
progress {
id
status
}
+ last_import_target {
+ target_namespace
+ new_name
+ }
}
}
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/services/source_groups_manager.js b/app/assets/javascripts/import_entities/import_groups/graphql/services/source_groups_manager.js
index 97dbdbf518a..7caa37d9ad4 100644
--- a/app/assets/javascripts/import_entities/import_groups/graphql/services/source_groups_manager.js
+++ b/app/assets/javascripts/import_entities/import_groups/graphql/services/source_groups_manager.js
@@ -35,15 +35,18 @@ export class SourceGroupsManager {
}
createImportState(importId, jobConfig) {
- this.importStates[this.getStorageKey(importId)] = {
+ this.importStates[importId] = {
status: jobConfig.status,
- groups: jobConfig.groups.map((g) => ({ importTarget: g.import_target, id: g.id })),
+ groups: jobConfig.groups.map((g) => ({
+ importTarget: { ...g.import_target },
+ id: g.id,
+ })),
};
this.saveImportStatesToStorage();
}
updateImportProgress(importId, status) {
- const currentState = this.importStates[this.getStorageKey(importId)];
+ const currentState = this.importStates[importId];
if (!currentState) {
return;
}
@@ -52,12 +55,15 @@ export class SourceGroupsManager {
this.saveImportStatesToStorage();
}
+ getImportedGroupsByJobId(jobId) {
+ return this.importStates[jobId]?.groups ?? [];
+ }
+
getImportStateFromStorageByGroupId(groupId) {
- const PREFIX = this.getStorageKey('');
const [jobId, importState] =
- Object.entries(this.importStates).find(
- ([key, state]) => key.startsWith(PREFIX) && state.groups.some((g) => g.id === groupId),
- ) ?? [];
+ Object.entries(this.importStates)
+ .reverse()
+ .find(([, state]) => state.groups.some((g) => g.id === groupId)) ?? [];
if (!jobId) {
return null;
@@ -67,10 +73,6 @@ export class SourceGroupsManager {
return { jobId, importState: { ...group, status: importState.status } };
}
- getStorageKey(importId) {
- return `${this.sourceUrl}|${importId}`;
- }
-
saveImportStatesToStorage = debounce(() => {
try {
// storage might be changed in other tab so fetch first
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/typedefs.graphql b/app/assets/javascripts/import_entities/import_groups/graphql/typedefs.graphql
index c830aaa75e6..6ef4bbafec0 100644
--- a/app/assets/javascripts/import_entities/import_groups/graphql/typedefs.graphql
+++ b/app/assets/javascripts/import_entities/import_groups/graphql/typedefs.graphql
@@ -30,6 +30,7 @@ type ClientBulkImportSourceGroup {
full_name: String!
progress: ClientBulkImportProgress!
import_target: ClientBulkImportTarget!
+ last_import_target: ClientBulkImportTarget
validation_errors: [ClientBulkImportValidationError!]!
}
@@ -50,11 +51,21 @@ extend type Query {
availableNamespaces: [ClientBulkImportAvailableNamespace!]!
}
+input InputTargetInput {
+ target_namespace: String!
+ new_name: String!
+}
+
extend type Mutation {
setNewName(newName: String, sourceGroupId: ID!): ClientBulkImportSourceGroup!
setTargetNamespace(targetNamespace: String, sourceGroupId: ID!): ClientBulkImportSourceGroup!
importGroups(sourceGroupIds: [ID!]!): [ClientBulkImportSourceGroup!]!
- setImportProgress(id: ID, status: String!): ClientBulkImportSourceGroup!
+ setImportProgress(
+ id: ID
+ status: String!
+ jobId: String
+ importTarget: ImportTargetInput!
+ ): ClientBulkImportSourceGroup!
updateImportProgress(id: ID, status: String!): ClientBulkImportProgress
addValidationError(
sourceGroupId: ID!
diff --git a/app/assets/javascripts/import_entities/import_groups/utils.js b/app/assets/javascripts/import_entities/import_groups/utils.js
index b451008b6f9..a1baeaf39dd 100644
--- a/app/assets/javascripts/import_entities/import_groups/utils.js
+++ b/app/assets/javascripts/import_entities/import_groups/utils.js
@@ -1,3 +1,4 @@
+import { STATUSES } from '../constants';
import { NEW_NAME_FIELD } from './constants';
export function isNameValid(group, validationRegex) {
@@ -11,3 +12,11 @@ export function getInvalidNameValidationMessage(group) {
export function isInvalid(group, validationRegex) {
return Boolean(!isNameValid(group, validationRegex) || getInvalidNameValidationMessage(group));
}
+
+export function isFinished(group) {
+ return group.progress.status === STATUSES.FINISHED;
+}
+
+export function isAvailableForImport(group) {
+ return [STATUSES.NONE, STATUSES.FINISHED].some((status) => group.progress.status === status);
+}
diff --git a/app/assets/javascripts/import_entities/import_projects/components/import_projects_table.vue b/app/assets/javascripts/import_entities/import_projects/components/import_projects_table.vue
index 14d08caef34..0cd3519bcec 100644
--- a/app/assets/javascripts/import_entities/import_projects/components/import_projects_table.vue
+++ b/app/assets/javascripts/import_entities/import_projects/components/import_projects_table.vue
@@ -32,7 +32,7 @@ export default {
},
computed: {
- ...mapState(['filter', 'repositories', 'namespaces', 'defaultTargetNamespace']),
+ ...mapState(['filter', 'repositories', 'namespaces', 'defaultTargetNamespace', 'pageInfo']),
...mapGetters([
'isLoading',
'isImportingAnyRepo',
@@ -43,7 +43,7 @@ export default {
]),
pagePaginationStateKey() {
- return `${this.filter}-${this.repositories.length}`;
+ return `${this.filter}-${this.repositories.length}-${this.pageInfo.page}`;
},
availableNamespaces() {
diff --git a/app/assets/javascripts/import_entities/import_projects/store/actions.js b/app/assets/javascripts/import_entities/import_projects/store/actions.js
index 5cbc6e85bf3..92be028b8a9 100644
--- a/app/assets/javascripts/import_entities/import_projects/store/actions.js
+++ b/app/assets/javascripts/import_entities/import_projects/store/actions.js
@@ -53,7 +53,6 @@ const importAll = ({ state, dispatch }) => {
const fetchReposFactory = ({ reposPath = isRequired() }) => ({ state, commit }) => {
const nextPage = state.pageInfo.page + 1;
- commit(types.SET_PAGE, nextPage);
commit(types.REQUEST_REPOS);
const { provider, filter } = state;
@@ -67,11 +66,10 @@ const fetchReposFactory = ({ reposPath = isRequired() }) => ({ state, commit })
}),
)
.then(({ data }) => {
+ commit(types.SET_PAGE, nextPage);
commit(types.RECEIVE_REPOS_SUCCESS, convertObjectPropsToCamelCase(data, { deep: true }));
})
.catch((e) => {
- commit(types.SET_PAGE, nextPage - 1);
-
if (hasRedirectInError(e)) {
redirectToUrlInError(e);
} else if (tooManyRequests(e)) {
diff --git a/app/assets/javascripts/import_entities/import_projects/store/mutations.js b/app/assets/javascripts/import_entities/import_projects/store/mutations.js
index c5e1922597a..45f7a684161 100644
--- a/app/assets/javascripts/import_entities/import_projects/store/mutations.js
+++ b/app/assets/javascripts/import_entities/import_projects/store/mutations.js
@@ -9,7 +9,7 @@ const makeNewImportedProject = (importedProject) => ({
sanitizedName: importedProject.name,
providerLink: importedProject.providerLink,
},
- importedProject,
+ importedProject: { ...importedProject },
});
const makeNewIncompatibleProject = (project) => ({
@@ -63,15 +63,16 @@ export default {
factory: makeNewIncompatibleProject,
});
- state.repositories = [
- ...newImportedProjects,
- ...state.repositories,
- ...repositories.providerRepos.map((project) => ({
+ const existingProjects = [...newImportedProjects, ...state.repositories];
+ const existingProjectNames = new Set(existingProjects.map((p) => p.importSource.fullName));
+ const newProjects = repositories.providerRepos
+ .filter((project) => !existingProjectNames.has(project.fullName))
+ .map((project) => ({
importSource: project,
importedProject: null,
- })),
- ...newIncompatibleProjects,
- ];
+ }));
+
+ state.repositories = [...existingProjects, ...newProjects, ...newIncompatibleProjects];
if (incompatibleRepos.length === 0 && repositories.providerRepos.length === 0) {
state.pageInfo.page -= 1;
diff --git a/app/assets/javascripts/incidents/list.js b/app/assets/javascripts/incidents/list.js
index 8644ff3a249..6e6461cd7a9 100644
--- a/app/assets/javascripts/incidents/list.js
+++ b/app/assets/javascripts/incidents/list.js
@@ -24,7 +24,7 @@ export default () => {
} = domEl.dataset;
const apolloProvider = new VueApollo({
- defaultClient: createDefaultClient(),
+ defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
});
return new Vue({
diff --git a/app/assets/javascripts/init_changes_dropdown.js b/app/assets/javascripts/init_changes_dropdown.js
deleted file mode 100644
index b42264c870b..00000000000
--- a/app/assets/javascripts/init_changes_dropdown.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import $ from 'jquery';
-import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
-import { stickyMonitor } from './lib/utils/sticky';
-
-export default (stickyTop) => {
- stickyMonitor(document.querySelector('.js-diff-files-changed'), stickyTop);
-
- initDeprecatedJQueryDropdown($('.js-diff-stats-dropdown'), {
- filterable: true,
- remoteFilter: false,
- });
-};
diff --git a/app/assets/javascripts/init_deprecated_notes.js b/app/assets/javascripts/init_deprecated_notes.js
new file mode 100644
index 00000000000..5f918b0d2f5
--- /dev/null
+++ b/app/assets/javascripts/init_deprecated_notes.js
@@ -0,0 +1,10 @@
+import Notes from './deprecated_notes';
+
+export default () => {
+ const dataEl = document.querySelector('.js-notes-data');
+ const { notesUrl, notesIds, now, diffView, enableGFM } = JSON.parse(dataEl.innerHTML);
+
+ // Create a singleton so that we don't need to assign
+ // into the window object, we can just access the current isntance with Notes.instance
+ Notes.initialize(notesUrl, notesIds, now, diffView, enableGFM);
+};
diff --git a/app/assets/javascripts/init_diff_stats_dropdown.js b/app/assets/javascripts/init_diff_stats_dropdown.js
new file mode 100644
index 00000000000..27df761a103
--- /dev/null
+++ b/app/assets/javascripts/init_diff_stats_dropdown.js
@@ -0,0 +1,30 @@
+import Vue from 'vue';
+import DiffStatsDropdown from '~/vue_shared/components/diff_stats_dropdown.vue';
+import { stickyMonitor } from './lib/utils/sticky';
+
+export const initDiffStatsDropdown = (stickyTop) => {
+ if (stickyTop) {
+ stickyMonitor(document.querySelector('.js-diff-files-changed'), stickyTop);
+ }
+
+ const el = document.querySelector('.js-diff-stats-dropdown');
+
+ if (!el) {
+ return false;
+ }
+
+ const { changed, added, deleted, files } = el.dataset;
+
+ return new Vue({
+ el,
+ render: (createElement) =>
+ createElement(DiffStatsDropdown, {
+ props: {
+ changed: parseInt(changed, 10),
+ added: parseInt(added, 10),
+ deleted: parseInt(deleted, 10),
+ files: JSON.parse(files),
+ },
+ }),
+ });
+};
diff --git a/app/assets/javascripts/init_issuable_sidebar.js b/app/assets/javascripts/init_issuable_sidebar.js
index 17c73fdf1c3..7a70d893008 100644
--- a/app/assets/javascripts/init_issuable_sidebar.js
+++ b/app/assets/javascripts/init_issuable_sidebar.js
@@ -1,9 +1,7 @@
/* eslint-disable no-new */
-import { mountSidebarLabels, getSidebarOptions } from '~/sidebar/mount_sidebar';
+import { getSidebarOptions } from '~/sidebar/mount_sidebar';
import IssuableContext from './issuable_context';
-import LabelsSelect from './labels_select';
-import MilestoneSelect from './milestone_select';
import Sidebar from './right_sidebar';
export default () => {
@@ -13,12 +11,6 @@ export default () => {
const sidebarOptions = getSidebarOptions(sidebarOptEl);
- new MilestoneSelect({
- full_path: sidebarOptions.fullPath,
- });
- new LabelsSelect();
new IssuableContext(sidebarOptions.currentUser);
Sidebar.initialize();
-
- mountSidebarLabels();
};
diff --git a/app/assets/javascripts/init_notes.js b/app/assets/javascripts/init_notes.js
deleted file mode 100644
index a77828e8cf2..00000000000
--- a/app/assets/javascripts/init_notes.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import Notes from './notes';
-
-export default () => {
- const dataEl = document.querySelector('.js-notes-data');
- const { notesUrl, notesIds, now, diffView, enableGFM } = JSON.parse(dataEl.innerHTML);
-
- // Create a singleton so that we don't need to assign
- // into the window object, we can just access the current isntance with Notes.instance
- Notes.initialize(notesUrl, notesIds, now, diffView, enableGFM);
-};
diff --git a/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue b/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue
index 11e9b25f9a3..1cc5a185f03 100644
--- a/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue
+++ b/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue
@@ -37,7 +37,7 @@ const issueTransitionOptions = [
help: s__(
'JiraService|Automatically transitions Jira issues to the "Done" category. %{linkStart}Learn more%{linkEnd}',
),
- link: helpPagePath('integration/jira/index.html', {
+ link: helpPagePath('integration/jira/issues.html', {
anchor: 'automatic-issue-transitions',
}),
},
@@ -47,7 +47,7 @@ const issueTransitionOptions = [
help: s__(
'JiraService|Set a custom final state by using transition IDs. %{linkStart}Learn about transition IDs%{linkEnd}',
),
- link: helpPagePath('integration/jira/index.html', {
+ link: helpPagePath('integration/jira/issues.html', {
anchor: 'custom-issue-transitions',
}),
},
diff --git a/app/assets/javascripts/invite_members/components/import_a_project_modal.vue b/app/assets/javascripts/invite_members/components/import_a_project_modal.vue
new file mode 100644
index 00000000000..d71468284ca
--- /dev/null
+++ b/app/assets/javascripts/invite_members/components/import_a_project_modal.vue
@@ -0,0 +1,157 @@
+<script>
+import { GlButton, GlFormGroup, GlModal, GlModalDirective, GlSprintf } from '@gitlab/ui';
+import { uniqueId } from 'lodash';
+import { importProjectMembers } from '~/api/projects_api';
+import { s__, __, sprintf } from '~/locale';
+import ProjectSelect from './project_select.vue';
+
+export default {
+ components: {
+ GlButton,
+ GlFormGroup,
+ GlModal,
+ GlSprintf,
+ ProjectSelect,
+ },
+ directives: {
+ GlModal: GlModalDirective,
+ },
+ props: {
+ projectId: {
+ type: String,
+ required: true,
+ },
+ projectName: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ projectToBeImported: {},
+ invalidFeedbackMessage: '',
+ isLoading: false,
+ };
+ },
+ computed: {
+ modalIntro() {
+ return sprintf(this.$options.i18n.modalIntro, {
+ name: this.projectName,
+ });
+ },
+ importDisabled() {
+ return Object.keys(this.projectToBeImported).length === 0;
+ },
+ validationState() {
+ return this.invalidFeedbackMessage === '' ? null : false;
+ },
+ },
+ methods: {
+ submitImport() {
+ this.isLoading = true;
+ return importProjectMembers(this.projectId, this.projectToBeImported.id)
+ .then(this.showToastMessage)
+ .catch(this.showErrorAlert)
+ .finally(() => {
+ this.isLoading = false;
+ this.projectToBeImported = {};
+ });
+ },
+ closeModal() {
+ this.invalidFeedbackMessage = '';
+
+ this.$refs.modal.hide();
+ },
+ showToastMessage() {
+ this.$toast.show(this.$options.i18n.successMessage, this.$options.toastOptions);
+
+ this.closeModal();
+ },
+ showErrorAlert() {
+ this.invalidFeedbackMessage = this.$options.i18n.defaultError;
+ },
+ },
+ toastOptions() {
+ return {
+ onComplete: () => {
+ this.projectToBeImported = {};
+ },
+ };
+ },
+ i18n: {
+ buttonText: s__('ImportAProjectModal|Import from a project'),
+ projectLabel: __('Project'),
+ modalTitle: s__('ImportAProjectModal|Import members from another project'),
+ modalIntro: s__(
+ "ImportAProjectModal|You're importing members to the %{strongStart}%{name}%{strongEnd} project.",
+ ),
+ modalHelpText: s__(
+ 'ImportAProjectModal|Only project members (not group members) are imported, and they get the same permissions as the project you import from.',
+ ),
+ modalPrimaryButton: s__('ImportAProjectModal|Import project members'),
+ modalCancelButton: __('Cancel'),
+ defaultError: s__('ImportAProjectModal|Unable to import project members'),
+ successMessage: s__('ImportAProjectModal|Successfully imported'),
+ },
+ projectSelectLabelId: 'project-select',
+ modalId: uniqueId('import-a-project-modal-'),
+ formClasses: 'gl-mt-3 gl-sm-w-auto gl-w-full',
+ buttonClasses: 'gl-w-full',
+};
+</script>
+
+<template>
+ <form :class="$options.formClasses">
+ <gl-button v-gl-modal="$options.modalId" :class="$options.buttonClasses" variant="default">{{
+ $options.i18n.buttonText
+ }}</gl-button>
+
+ <gl-modal
+ ref="modal"
+ :modal-id="$options.modalId"
+ size="sm"
+ :title="$options.i18n.modalTitle"
+ ok-variant="danger"
+ footer-class="gl-bg-gray-10 gl-p-5"
+ >
+ <div>
+ <p ref="modalIntro">
+ <gl-sprintf :message="modalIntro">
+ <template #strong="{ content }">
+ <strong>{{ content }}</strong>
+ </template>
+ </gl-sprintf>
+ </p>
+ <gl-form-group
+ :invalid-feedback="invalidFeedbackMessage"
+ :state="validationState"
+ data-testid="form-group"
+ >
+ <label :id="$options.projectSelectLabelId" class="col-form-label">{{
+ $options.i18n.projectLabel
+ }}</label>
+ <project-select v-model="projectToBeImported" />
+ </gl-form-group>
+ <p>{{ $options.i18n.modalHelpText }}</p>
+ </div>
+ <template #modal-footer>
+ <div
+ class="gl-display-flex gl-flex-direction-row gl-justify-content-end gl-flex-wrap gl-m-0"
+ >
+ <gl-button data-testid="cancel-button" @click="closeModal">
+ {{ $options.i18n.modalCancelButton }}
+ </gl-button>
+ <div class="gl-mr-3"></div>
+ <gl-button
+ :disabled="importDisabled"
+ :loading="isLoading"
+ variant="success"
+ data-testid="import-button"
+ @click="submitImport"
+ >{{ $options.i18n.modalPrimaryButton }}</gl-button
+ >
+ </div>
+ </template>
+ </gl-modal>
+ </form>
+</template>
diff --git a/app/assets/javascripts/invite_members/components/invite_members_trigger.vue b/app/assets/javascripts/invite_members/components/invite_members_trigger.vue
index ec7d466336e..05be427742c 100644
--- a/app/assets/javascripts/invite_members/components/invite_members_trigger.vue
+++ b/app/assets/javascripts/invite_members/components/invite_members_trigger.vue
@@ -65,7 +65,7 @@ export default {
if (this.event && this.label) {
return {
...baseAttributes,
- 'data-track-event': this.event,
+ 'data-track-action': this.event,
'data-track-label': this.label,
};
}
diff --git a/app/assets/javascripts/invite_members/components/project_select.vue b/app/assets/javascripts/invite_members/components/project_select.vue
new file mode 100644
index 00000000000..b7a3918813b
--- /dev/null
+++ b/app/assets/javascripts/invite_members/components/project_select.vue
@@ -0,0 +1,143 @@
+<script>
+import {
+ GlAvatarLabeled,
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownText,
+ GlSearchBoxByType,
+} from '@gitlab/ui';
+import { debounce } from 'lodash';
+import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
+import { s__ } from '~/locale';
+import { getProjects } from '~/rest_api';
+import { SEARCH_DELAY, GROUP_FILTERS } from '../constants';
+
+export default {
+ name: 'ProjectSelect',
+ components: {
+ GlAvatarLabeled,
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownText,
+ GlSearchBoxByType,
+ },
+ model: {
+ prop: 'selectedProject',
+ },
+ props: {
+ groupsFilter: {
+ type: String,
+ required: false,
+ default: GROUP_FILTERS.ALL,
+ validator: (value) => Object.values(GROUP_FILTERS).includes(value),
+ },
+ parentGroupId: {
+ type: Number,
+ required: false,
+ default: 0,
+ },
+ },
+ data() {
+ return {
+ isFetching: false,
+ projects: [],
+ selectedProject: {},
+ searchTerm: '',
+ errorMessage: '',
+ };
+ },
+ computed: {
+ selectedProjectName() {
+ return this.selectedProject.name || this.$options.i18n.dropdownText;
+ },
+ isFetchResultEmpty() {
+ return this.projects.length === 0 && !this.isFetching;
+ },
+ },
+ watch: {
+ searchTerm() {
+ this.retrieveProjects();
+ },
+ },
+ mounted() {
+ this.retrieveProjects();
+ },
+ methods: {
+ retrieveProjects: debounce(function debouncedRetrieveProjects() {
+ this.isFetching = true;
+ this.errorMessage = '';
+ return this.fetchProjects()
+ .then((response) => {
+ this.projects = response.data.map((project) => ({
+ ...convertObjectPropsToCamelCase(project),
+ name: project.name_with_namespace,
+ }));
+ })
+ .catch(() => {
+ this.errorMessage = this.$options.i18n.errorFetchingProjects;
+ })
+ .finally(() => {
+ this.isFetching = false;
+ });
+ }, SEARCH_DELAY),
+ fetchProjects() {
+ return getProjects(this.searchTerm, this.$options.defaultFetchOptions);
+ },
+ selectProject(project) {
+ this.selectedProject = project;
+
+ this.$emit('input', this.selectedProject);
+ },
+ },
+ i18n: {
+ dropdownText: s__('ProjectSelect|Select a project'),
+ searchPlaceholder: s__('ProjectSelect|Search projects'),
+ emptySearchResult: s__('ProjectSelect|No matching results'),
+ errorFetchingProjects: s__(
+ 'ProjectSelect|There was an error fetching the projects. Please try again.',
+ ),
+ },
+ defaultFetchOptions: {
+ exclude_internal: true,
+ active: true,
+ },
+};
+</script>
+<template>
+ <div>
+ <gl-dropdown
+ data-testid="project-select-dropdown"
+ :text="selectedProjectName"
+ toggle-class="gl-mb-2"
+ block
+ menu-class="gl-w-full!"
+ >
+ <gl-search-box-by-type
+ v-model="searchTerm"
+ :is-loading="isFetching"
+ :placeholder="$options.i18n.searchPlaceholder"
+ data-qa-selector="project_select_dropdown_search_field"
+ />
+ <gl-dropdown-item
+ v-for="project in projects"
+ :key="project.id"
+ :name="project.name"
+ @click="selectProject(project)"
+ >
+ <gl-avatar-labeled
+ :label="project.name"
+ :src="project.avatarUrl"
+ :entity-id="project.id"
+ :entity-name="project.name"
+ :size="32"
+ />
+ </gl-dropdown-item>
+ <gl-dropdown-text v-if="errorMessage" data-testid="error-message">
+ <span class="gl-text-gray-500">{{ errorMessage }}</span>
+ </gl-dropdown-text>
+ <gl-dropdown-text v-else-if="isFetchResultEmpty" data-testid="empty-result-message">
+ <span class="gl-text-gray-500">{{ $options.i18n.emptySearchResult }}</span>
+ </gl-dropdown-text>
+ </gl-dropdown>
+ </div>
+</template>
diff --git a/app/assets/javascripts/invite_members/init_import_a_project_modal.js b/app/assets/javascripts/invite_members/init_import_a_project_modal.js
new file mode 100644
index 00000000000..954347467de
--- /dev/null
+++ b/app/assets/javascripts/invite_members/init_import_a_project_modal.js
@@ -0,0 +1,23 @@
+import Vue from 'vue';
+import ImportAProjectModal from '~/invite_members/components/import_a_project_modal.vue';
+
+export default function initImportAProjectModal() {
+ const el = document.querySelector('.js-import-a-project-modal');
+
+ if (!el) {
+ return false;
+ }
+
+ const { projectId, projectName } = el.dataset;
+
+ return new Vue({
+ el,
+ render: (createElement) =>
+ createElement(ImportAProjectModal, {
+ props: {
+ projectId,
+ projectName,
+ },
+ }),
+ });
+}
diff --git a/app/assets/javascripts/issuable/components/csv_export_modal.vue b/app/assets/javascripts/issuable/components/csv_export_modal.vue
index 5c880cbfad8..1c88f8dfdca 100644
--- a/app/assets/javascripts/issuable/components/csv_export_modal.vue
+++ b/app/assets/javascripts/issuable/components/csv_export_modal.vue
@@ -63,7 +63,7 @@ export default {
</gl-sprintf>
<gl-sprintf
v-else
- :message="n__('1 merge request selected', '%d merge request selected', issuableCount)"
+ :message="n__('1 merge request selected', '%d merge requests selected', issuableCount)"
>
<template #issuableCount>{{ issuableCount }}</template>
</gl-sprintf>
@@ -89,7 +89,7 @@ export default {
:href="exportCsvPath"
data-method="post"
:data-qa-selector="`export_${issuableType}_button`"
- data-track-event="click_button"
+ data-track-action="click_button"
:data-track-label="`export_${issuableType}_csv`"
>
<gl-sprintf :message="__('Export %{name}')">
diff --git a/app/assets/javascripts/issuable_list/components/issuable_item.vue b/app/assets/javascripts/issuable_list/components/issuable_item.vue
index 29dd0b7fed5..df9d5c86a4b 100644
--- a/app/assets/javascripts/issuable_list/components/issuable_item.vue
+++ b/app/assets/javascripts/issuable_list/components/issuable_item.vue
@@ -69,6 +69,9 @@ export default {
isIssuableUrlExternal() {
return isExternal(this.webUrl);
},
+ reference() {
+ return this.issuable.reference || `${this.issuableSymbol}${this.issuable.iid}`;
+ },
labels() {
return this.issuable.labels?.nodes || this.issuable.labels || [];
},
@@ -201,9 +204,9 @@ export default {
</div>
<div class="issuable-info">
<slot v-if="hasSlotContents('reference')" name="reference"></slot>
- <span v-else data-testid="issuable-reference" class="issuable-reference"
- >{{ issuableSymbol }}{{ issuable.iid }}</span
- >
+ <span v-else data-testid="issuable-reference" class="issuable-reference">
+ {{ reference }}
+ </span>
<span class="issuable-authored gl-display-none gl-sm-display-inline-block! gl-mr-3">
<span aria-hidden="true">&middot;</span>
<span
diff --git a/app/assets/javascripts/issue_show/components/app.vue b/app/assets/javascripts/issue_show/components/app.vue
index b7e24a8b17e..2c9a512acdb 100644
--- a/app/assets/javascripts/issue_show/components/app.vue
+++ b/app/assets/javascripts/issue_show/components/app.vue
@@ -1,5 +1,5 @@
<script>
-import { GlIcon, GlIntersectionObserver } from '@gitlab/ui';
+import { GlIcon, GlIntersectionObserver, GlTooltipDirective } from '@gitlab/ui';
import Visibility from 'visibilityjs';
import createFlash from '~/flash';
import Poll from '~/lib/utils/poll';
@@ -32,6 +32,9 @@ export default {
formComponent,
PinnedLinks,
},
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
props: {
endpoint: {
required: true,
@@ -183,6 +186,11 @@ export default {
required: false,
default: true,
},
+ isHidden: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
data() {
const store = new Store({
@@ -508,6 +516,15 @@ export default {
<span v-if="isConfidential" data-testid="confidential" class="issuable-warning-icon">
<gl-icon name="eye-slash" :aria-label="__('Confidential')" />
</span>
+ <span
+ v-if="isHidden"
+ v-gl-tooltip
+ :title="__('This issue is hidden because its author has been banned')"
+ data-testid="hidden"
+ class="issuable-warning-icon"
+ >
+ <gl-icon name="spam" />
+ </span>
<p
class="gl-font-weight-bold gl-overflow-hidden gl-white-space-nowrap gl-text-overflow-ellipsis gl-my-0"
:title="state.titleText"
diff --git a/app/assets/javascripts/issue_show/components/description.vue b/app/assets/javascripts/issue_show/components/description.vue
index 0812392f804..4c6a1478e95 100644
--- a/app/assets/javascripts/issue_show/components/description.vue
+++ b/app/assets/javascripts/issue_show/components/description.vue
@@ -123,6 +123,7 @@ export default {
}
},
},
+ safeHtmlConfig: { ADD_TAGS: ['gl-emoji'] },
};
</script>
@@ -136,7 +137,7 @@ export default {
>
<div
ref="gfm-content"
- v-safe-html="descriptionHtml"
+ v-safe-html:[$options.safeHtmlConfig]="descriptionHtml"
:class="{
'issue-realtime-pre-pulse': preAnimation,
'issue-realtime-trigger-pulse': pulseAnimation,
diff --git a/app/assets/javascripts/issue_show/components/locked_warning.vue b/app/assets/javascripts/issue_show/components/locked_warning.vue
index 96f5a7c88e0..f3c2a31bd5b 100644
--- a/app/assets/javascripts/issue_show/components/locked_warning.vue
+++ b/app/assets/javascripts/issue_show/components/locked_warning.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { __, sprintf } from '~/locale';
export default {
@@ -24,5 +23,8 @@ export default {
</script>
<template>
- <div class="alert alert-danger" v-html="alertMessage"></div>
+ <div
+ class="alert alert-danger"
+ v-html="alertMessage /* eslint-disable-line vue/no-v-html */"
+ ></div>
</template>
diff --git a/app/assets/javascripts/issues_list/components/issuable.vue b/app/assets/javascripts/issues_list/components/issuable.vue
index 60b01a6d37f..6dc7460b037 100644
--- a/app/assets/javascripts/issues_list/components/issuable.vue
+++ b/app/assets/javascripts/issues_list/components/issuable.vue
@@ -315,7 +315,7 @@ export default {
<span
v-if="isJiraIssue"
v-safe-html="jiraLogo"
- class="svg-container jira-logo-container"
+ class="svg-container logo-container"
data-testid="jira-logo"
></span>
{{ referencePath }}
diff --git a/app/assets/javascripts/issues_list/components/issues_list_app.vue b/app/assets/javascripts/issues_list/components/issues_list_app.vue
index ee0429c0432..8e37339fca6 100644
--- a/app/assets/javascripts/issues_list/components/issues_list_app.vue
+++ b/app/assets/javascripts/issues_list/components/issues_list_app.vue
@@ -9,11 +9,12 @@ import {
GlTooltipDirective,
} from '@gitlab/ui';
import fuzzaldrinPlus from 'fuzzaldrin-plus';
-import { cloneDeep } from 'lodash';
import getIssuesQuery from 'ee_else_ce/issues_list/queries/get_issues.query.graphql';
+import getIssuesCountsQuery from 'ee_else_ce/issues_list/queries/get_issues_counts.query.graphql';
import createFlash from '~/flash';
import { TYPE_USER } from '~/graphql_shared/constants';
import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils';
+import { ITEM_TYPE } from '~/groups/constants';
import CsvImportExportButtons from '~/issuable/components/csv_import_export_buttons.vue';
import IssuableByEmail from '~/issuable/components/issuable_by_email.vue';
import IssuableList from '~/issuable_list/components/issuable_list_root.vue';
@@ -21,7 +22,6 @@ import { IssuableListTabs, IssuableStates } from '~/issuable_list/constants';
import {
CREATED_DESC,
i18n,
- issuesCountSmartQueryBase,
MAX_LIST_SIZE,
PAGE_SIZE,
PARAM_DUE_DATE,
@@ -117,9 +117,15 @@ export default {
exportCsvPath: {
default: '',
},
+ fullPath: {
+ default: '',
+ },
groupEpicsPath: {
default: '',
},
+ hasAnyIssues: {
+ default: false,
+ },
hasBlockedIssuesFeature: {
default: false,
},
@@ -132,17 +138,14 @@ export default {
hasMultipleIssueAssigneesFeature: {
default: false,
},
- hasProjectIssues: {
- default: false,
- },
initialEmail: {
default: '',
},
- isSignedIn: {
+ isProject: {
default: false,
},
- issuesPath: {
- default: '',
+ isSignedIn: {
+ default: false,
},
jiraIntegrationPath: {
default: '',
@@ -150,9 +153,6 @@ export default {
newIssuePath: {
default: '',
},
- projectPath: {
- default: '',
- },
rssPath: {
default: '',
},
@@ -164,18 +164,16 @@ export default {
},
},
data() {
- const filterTokens = getFilterTokens(window.location.search);
const state = getParameterByName(PARAM_STATE);
const sortKey = getSortKey(getParameterByName(PARAM_SORT));
const defaultSortKey = state === IssuableStates.Closed ? UPDATED_DESC : CREATED_DESC;
- this.initialFilterTokens = cloneDeep(filterTokens);
-
return {
dueDateFilter: getDueDateValue(getParameterByName(PARAM_DUE_DATE)),
exportCsvPathWithQuery: this.getExportCsvPathWithQuery(),
- filterTokens,
+ filterTokens: getFilterTokens(window.location.search),
issues: [],
+ issuesCounts: {},
pageInfo: {},
pageParams: getInitialPageParams(sortKey),
showBulkEditSidebar: false,
@@ -189,61 +187,47 @@ export default {
variables() {
return this.queryVariables;
},
- update: ({ project }) => project?.issues.nodes ?? [],
+ update(data) {
+ return data[this.namespace]?.issues.nodes ?? [];
+ },
result({ data }) {
- this.pageInfo = data.project?.issues.pageInfo ?? {};
+ this.pageInfo = data[this.namespace]?.issues.pageInfo ?? {};
this.exportCsvPathWithQuery = this.getExportCsvPathWithQuery();
},
error(error) {
createFlash({ message: this.$options.i18n.errorFetchingIssues, captureError: true, error });
},
skip() {
- return !this.hasProjectIssues;
+ return !this.hasAnyIssues;
},
debounce: 200,
},
- countOpened: {
- ...issuesCountSmartQueryBase,
+ issuesCounts: {
+ query: getIssuesCountsQuery,
variables() {
- return {
- ...this.queryVariables,
- state: IssuableStates.Opened,
- };
+ return this.queryVariables;
},
- skip() {
- return !this.hasProjectIssues;
+ update(data) {
+ return data[this.namespace] ?? {};
},
- },
- countClosed: {
- ...issuesCountSmartQueryBase,
- variables() {
- return {
- ...this.queryVariables,
- state: IssuableStates.Closed,
- };
+ error(error) {
+ createFlash({ message: this.$options.i18n.errorFetchingCounts, captureError: true, error });
},
skip() {
- return !this.hasProjectIssues;
+ return !this.hasAnyIssues;
},
- },
- countAll: {
- ...issuesCountSmartQueryBase,
- variables() {
- return {
- ...this.queryVariables,
- state: IssuableStates.All,
- };
- },
- skip() {
- return !this.hasProjectIssues;
+ debounce: 200,
+ context: {
+ isSingleRequest: true,
},
},
},
computed: {
queryVariables() {
return {
+ fullPath: this.fullPath,
+ isProject: this.isProject,
isSignedIn: this.isSignedIn,
- projectPath: this.projectPath,
search: this.searchQuery,
sort: this.sortKey,
state: this.state,
@@ -251,6 +235,9 @@ export default {
...this.apiFilterParams,
};
},
+ namespace() {
+ return this.isProject ? ITEM_TYPE.PROJECT : ITEM_TYPE.GROUP;
+ },
hasSearch() {
return this.searchQuery || Object.keys(this.urlFilterParams).length;
},
@@ -263,6 +250,9 @@ export default {
isOpenTab() {
return this.state === IssuableStates.Opened;
},
+ showCsvButtons() {
+ return this.isProject && this.isSignedIn;
+ },
apiFilterParams() {
return convertToApiParams(this.filterTokens);
},
@@ -405,10 +395,11 @@ export default {
return getSortOptions(this.hasIssueWeightsFeature, this.hasBlockedIssuesFeature);
},
tabCounts() {
+ const { openedIssues, closedIssues, allIssues } = this.issuesCounts;
return {
- [IssuableStates.Opened]: this.countOpened,
- [IssuableStates.Closed]: this.countClosed,
- [IssuableStates.All]: this.countAll,
+ [IssuableStates.Opened]: openedIssues?.count,
+ [IssuableStates.Closed]: closedIssues?.count,
+ [IssuableStates.All]: allIssues?.count,
};
},
currentTabCount() {
@@ -465,39 +456,41 @@ export default {
return this.$apollo
.query({
query: searchLabelsQuery,
- variables: { projectPath: this.projectPath, search },
+ variables: { fullPath: this.fullPath, search, isProject: this.isProject },
})
- .then(({ data }) => data.project.labels.nodes);
+ .then(({ data }) => data[this.namespace]?.labels.nodes);
},
fetchMilestones(search) {
return this.$apollo
.query({
query: searchMilestonesQuery,
- variables: { projectPath: this.projectPath, search },
+ variables: { fullPath: this.fullPath, search, isProject: this.isProject },
})
- .then(({ data }) => data.project.milestones.nodes);
+ .then(({ data }) => data[this.namespace]?.milestones.nodes);
},
fetchIterations(search) {
const id = Number(search);
const variables =
!search || Number.isNaN(id)
- ? { projectPath: this.projectPath, search }
- : { projectPath: this.projectPath, id };
+ ? { fullPath: this.fullPath, search, isProject: this.isProject }
+ : { fullPath: this.fullPath, id, isProject: this.isProject };
return this.$apollo
.query({
query: searchIterationsQuery,
variables,
})
- .then(({ data }) => data.project.iterations.nodes);
+ .then(({ data }) => data[this.namespace]?.iterations.nodes);
},
fetchUsers(search) {
return this.$apollo
.query({
query: searchUsersQuery,
- variables: { projectPath: this.projectPath, search },
+ variables: { fullPath: this.fullPath, search, isProject: this.isProject },
})
- .then(({ data }) => data.project.projectMembers.nodes.map((member) => member.user));
+ .then(({ data }) =>
+ data[this.namespace]?.[`${this.namespace}Members`].nodes.map((member) => member.user),
+ );
},
getExportCsvPathWithQuery() {
return `${this.exportCsvPath}${window.location.search}`;
@@ -578,19 +571,20 @@ export default {
}
return axios
- .put(joinPaths(this.issuesPath, issueToMove.iid, 'reorder'), {
+ .put(joinPaths(issueToMove.webPath, 'reorder'), {
move_before_id: isMovingToBeginning ? null : getIdFromGraphQLId(moveBeforeId),
move_after_id: isMovingToEnd ? null : getIdFromGraphQLId(moveAfterId),
+ group_full_path: this.isProject ? undefined : this.fullPath,
})
.then(() => {
const serializedVariables = JSON.stringify(this.queryVariables);
- this.$apollo.mutate({
+ return this.$apollo.mutate({
mutation: reorderIssuesMutation,
- variables: { oldIndex, newIndex, serializedVariables },
+ variables: { oldIndex, newIndex, namespace: this.namespace, serializedVariables },
});
})
- .catch(() => {
- createFlash({ message: this.$options.i18n.reorderError });
+ .catch((error) => {
+ createFlash({ message: this.$options.i18n.reorderError, captureError: true, error });
});
},
handleSort(sortKey) {
@@ -607,13 +601,13 @@ export default {
</script>
<template>
- <div v-if="hasProjectIssues">
+ <div v-if="hasAnyIssues">
<issuable-list
- :namespace="projectPath"
+ :namespace="fullPath"
recent-searches-storage-key="issues"
:search-input-placeholder="$options.i18n.searchPlaceholder"
:search-tokens="searchTokens"
- :initial-filter-value="initialFilterTokens"
+ :initial-filter-value="filterTokens"
:sort-options="sortOptions"
:initial-sort-by="sortKey"
:issuables="issues"
@@ -653,7 +647,7 @@ export default {
:aria-label="$options.i18n.calendarLabel"
/>
<csv-import-export-buttons
- v-if="isSignedIn"
+ v-if="showCsvButtons"
class="gl-md-mr-3"
:export-csv-path="exportCsvPathWithQuery"
:issuable-count="currentTabCount"
@@ -766,6 +760,7 @@ export default {
{{ $options.i18n.newIssueLabel }}
</gl-button>
<csv-import-export-buttons
+ v-if="showCsvButtons"
class="gl-mr-3"
:export-csv-path="exportCsvPathWithQuery"
:issuable-count="currentTabCount"
diff --git a/app/assets/javascripts/issues_list/constants.js b/app/assets/javascripts/issues_list/constants.js
index 3f5b0d1feb5..5bdc1bd9f90 100644
--- a/app/assets/javascripts/issues_list/constants.js
+++ b/app/assets/javascripts/issues_list/constants.js
@@ -1,5 +1,3 @@
-import getIssuesCountQuery from 'ee_else_ce/issues_list/queries/get_issues_count.query.graphql';
-import createFlash from '~/flash';
import { __, s__ } from '~/locale';
import {
FILTER_ANY,
@@ -22,6 +20,7 @@ const MILESTONE_DUE = 'milestone_due';
const POPULARITY = 'popularity';
const WEIGHT = 'weight';
const LABEL_PRIORITY = 'label_priority';
+const TITLE = 'title';
export const RELATIVE_POSITION = 'relative_position';
export const LOADING_LIST_ITEMS_LENGTH = 8;
export const PAGE_SIZE = 20;
@@ -43,6 +42,8 @@ export const sortOrderMap = {
relative_position: { order_by: RELATIVE_POSITION, sort: ASC },
weight_desc: { order_by: WEIGHT, sort: DESC },
weight: { order_by: WEIGHT, sort: ASC },
+ title: { order_by: TITLE, sort: ASC },
+ title_desc: { order_by: TITLE, sort: DESC },
};
export const availableSortOptionsJira = [
@@ -146,6 +147,8 @@ export const POPULARITY_DESC = 'POPULARITY_DESC';
export const PRIORITY_ASC = 'PRIORITY_ASC';
export const PRIORITY_DESC = 'PRIORITY_DESC';
export const RELATIVE_POSITION_ASC = 'RELATIVE_POSITION_ASC';
+export const TITLE_ASC = 'TITLE_ASC';
+export const TITLE_DESC = 'TITLE_DESC';
export const UPDATED_ASC = 'UPDATED_ASC';
export const UPDATED_DESC = 'UPDATED_DESC';
export const WEIGHT_ASC = 'WEIGHT_ASC';
@@ -163,6 +166,7 @@ const LABEL_PRIORITY_ASC_SORT = 'label_priority_asc';
const POPULARITY_ASC_SORT = 'popularity_asc';
const WEIGHT_DESC_SORT = 'weight_desc';
const BLOCKING_ISSUES_DESC_SORT = 'blocking_issues_desc';
+const TITLE_DESC_SORT = 'title_desc';
export const urlSortParams = {
[PRIORITY_ASC]: PRIORITY_ASC_SORT,
@@ -183,6 +187,8 @@ export const urlSortParams = {
[WEIGHT_ASC]: WEIGHT,
[WEIGHT_DESC]: WEIGHT_DESC_SORT,
[BLOCKING_ISSUES_DESC]: BLOCKING_ISSUES_DESC_SORT,
+ [TITLE_ASC]: TITLE,
+ [TITLE_DESC]: TITLE_DESC_SORT,
};
export const MAX_LIST_SIZE = 10;
@@ -351,15 +357,3 @@ export const filters = {
},
},
};
-
-export const issuesCountSmartQueryBase = {
- query: getIssuesCountQuery,
- context: {
- isSingleRequest: true,
- },
- update: ({ project }) => project?.issues.count,
- error(error) {
- createFlash({ message: i18n.errorFetchingCounts, captureError: true, error });
- },
- debounce: 200,
-};
diff --git a/app/assets/javascripts/issues_list/index.js b/app/assets/javascripts/issues_list/index.js
index dcc7ee72273..e89e3e8e681 100644
--- a/app/assets/javascripts/issues_list/index.js
+++ b/app/assets/javascripts/issues_list/index.js
@@ -85,17 +85,17 @@ export function mountIssuesListApp() {
const resolvers = {
Mutation: {
- reorderIssues: (_, { oldIndex, newIndex, serializedVariables }, { cache }) => {
+ reorderIssues: (_, { oldIndex, newIndex, namespace, serializedVariables }, { cache }) => {
const variables = JSON.parse(serializedVariables);
const sourceData = cache.readQuery({ query: getIssuesQuery, variables });
const data = produce(sourceData, (draftData) => {
- const issues = draftData.project.issues.nodes.slice();
+ const issues = draftData[namespace].issues.nodes.slice();
const issueToMove = issues[oldIndex];
issues.splice(oldIndex, 1);
issues.splice(newIndex, 0, issueToMove);
- draftData.project.issues.nodes = issues;
+ draftData[namespace].issues.nodes = issues;
});
cache.writeQuery({ query: getIssuesQuery, variables, data });
@@ -118,23 +118,23 @@ export function mountIssuesListApp() {
emailsHelpPagePath,
emptyStateSvgPath,
exportCsvPath,
+ fullPath,
groupEpicsPath,
+ hasAnyIssues,
hasBlockedIssuesFeature,
hasIssuableHealthStatusFeature,
hasIssueWeightsFeature,
hasIterationsFeature,
hasMultipleIssueAssigneesFeature,
- hasProjectIssues,
importCsvIssuesPath,
initialEmail,
+ isProject,
isSignedIn,
- issuesPath,
jiraIntegrationPath,
markdownHelpPath,
maxAttachmentSize,
newIssuePath,
projectImportJiraPath,
- projectPath,
quickActionsHelpPath,
resetPath,
rssPath,
@@ -150,18 +150,18 @@ export function mountIssuesListApp() {
calendarPath,
canBulkUpdate: parseBoolean(canBulkUpdate),
emptyStateSvgPath,
+ fullPath,
groupEpicsPath,
+ hasAnyIssues: parseBoolean(hasAnyIssues),
hasBlockedIssuesFeature: parseBoolean(hasBlockedIssuesFeature),
hasIssuableHealthStatusFeature: parseBoolean(hasIssuableHealthStatusFeature),
hasIssueWeightsFeature: parseBoolean(hasIssueWeightsFeature),
hasIterationsFeature: parseBoolean(hasIterationsFeature),
hasMultipleIssueAssigneesFeature: parseBoolean(hasMultipleIssueAssigneesFeature),
- hasProjectIssues: parseBoolean(hasProjectIssues),
+ isProject: parseBoolean(isProject),
isSignedIn: parseBoolean(isSignedIn),
- issuesPath,
jiraIntegrationPath,
newIssuePath,
- projectPath,
rssPath,
showNewIssueLink: parseBoolean(showNewIssueLink),
signInPath,
@@ -172,9 +172,9 @@ export function mountIssuesListApp() {
importCsvIssuesPath,
maxAttachmentSize,
projectImportJiraPath,
- showExportButton: parseBoolean(hasProjectIssues),
+ showExportButton: parseBoolean(hasAnyIssues),
showImportButton: parseBoolean(canImportIssues),
- showLabel: !parseBoolean(hasProjectIssues),
+ showLabel: !parseBoolean(hasAnyIssues),
// For IssuableByEmail component
emailsHelpPagePath,
initialEmail,
diff --git a/app/assets/javascripts/issues_list/queries/get_issues.query.graphql b/app/assets/javascripts/issues_list/queries/get_issues.query.graphql
index 30a01b4c3b0..6df72cf6596 100644
--- a/app/assets/javascripts/issues_list/queries/get_issues.query.graphql
+++ b/app/assets/javascripts/issues_list/queries/get_issues.query.graphql
@@ -1,9 +1,10 @@
#import "~/graphql_shared/fragments/pageInfo.fragment.graphql"
#import "./issue.fragment.graphql"
-query getProjectIssues(
+query getIssues(
+ $isProject: Boolean = false
$isSignedIn: Boolean = false
- $projectPath: ID!
+ $fullPath: ID!
$search: String
$sort: IssueSort
$state: IssuableState
@@ -20,7 +21,35 @@ query getProjectIssues(
$firstPageSize: Int
$lastPageSize: Int
) {
- project(fullPath: $projectPath) {
+ group(fullPath: $fullPath) @skip(if: $isProject) {
+ issues(
+ includeSubgroups: true
+ search: $search
+ sort: $sort
+ state: $state
+ assigneeId: $assigneeId
+ assigneeUsernames: $assigneeUsernames
+ authorUsername: $authorUsername
+ labelName: $labelName
+ milestoneTitle: $milestoneTitle
+ milestoneWildcardId: $milestoneWildcardId
+ types: $types
+ not: $not
+ before: $beforeCursor
+ after: $afterCursor
+ first: $firstPageSize
+ last: $lastPageSize
+ ) {
+ pageInfo {
+ ...PageInfo
+ }
+ nodes {
+ ...IssueFragment
+ reference(full: true)
+ }
+ }
+ }
+ project(fullPath: $fullPath) @include(if: $isProject) {
issues(
search: $search
sort: $sort
diff --git a/app/assets/javascripts/issues_list/queries/get_issues_count.query.graphql b/app/assets/javascripts/issues_list/queries/get_issues_count.query.graphql
deleted file mode 100644
index e6896131da9..00000000000
--- a/app/assets/javascripts/issues_list/queries/get_issues_count.query.graphql
+++ /dev/null
@@ -1,30 +0,0 @@
-query getProjectIssuesCount(
- $projectPath: ID!
- $search: String
- $state: IssuableState
- $assigneeId: String
- $assigneeUsernames: [String!]
- $authorUsername: String
- $labelName: [String]
- $milestoneTitle: [String]
- $milestoneWildcardId: MilestoneWildcardId
- $types: [IssueType!]
- $not: NegatedIssueFilterInput
-) {
- project(fullPath: $projectPath) {
- issues(
- search: $search
- state: $state
- assigneeId: $assigneeId
- assigneeUsernames: $assigneeUsernames
- authorUsername: $authorUsername
- labelName: $labelName
- milestoneTitle: $milestoneTitle
- milestoneWildcardId: $milestoneWildcardId
- types: $types
- not: $not
- ) {
- count
- }
- }
-}
diff --git a/app/assets/javascripts/issues_list/queries/get_issues_counts.query.graphql b/app/assets/javascripts/issues_list/queries/get_issues_counts.query.graphql
new file mode 100644
index 00000000000..7bcdbbb28fc
--- /dev/null
+++ b/app/assets/javascripts/issues_list/queries/get_issues_counts.query.graphql
@@ -0,0 +1,105 @@
+query getIssuesCount(
+ $isProject: Boolean = false
+ $fullPath: ID!
+ $search: String
+ $assigneeId: String
+ $assigneeUsernames: [String!]
+ $authorUsername: String
+ $labelName: [String]
+ $milestoneTitle: [String]
+ $milestoneWildcardId: MilestoneWildcardId
+ $types: [IssueType!]
+ $not: NegatedIssueFilterInput
+) {
+ group(fullPath: $fullPath) @skip(if: $isProject) {
+ openedIssues: issues(
+ includeSubgroups: true
+ state: opened
+ search: $search
+ assigneeId: $assigneeId
+ assigneeUsernames: $assigneeUsernames
+ authorUsername: $authorUsername
+ labelName: $labelName
+ milestoneTitle: $milestoneTitle
+ milestoneWildcardId: $milestoneWildcardId
+ types: $types
+ not: $not
+ ) {
+ count
+ }
+ closedIssues: issues(
+ includeSubgroups: true
+ state: closed
+ search: $search
+ assigneeId: $assigneeId
+ assigneeUsernames: $assigneeUsernames
+ authorUsername: $authorUsername
+ labelName: $labelName
+ milestoneTitle: $milestoneTitle
+ milestoneWildcardId: $milestoneWildcardId
+ types: $types
+ not: $not
+ ) {
+ count
+ }
+ allIssues: issues(
+ includeSubgroups: true
+ state: all
+ search: $search
+ assigneeId: $assigneeId
+ assigneeUsernames: $assigneeUsernames
+ authorUsername: $authorUsername
+ labelName: $labelName
+ milestoneTitle: $milestoneTitle
+ milestoneWildcardId: $milestoneWildcardId
+ types: $types
+ not: $not
+ ) {
+ count
+ }
+ }
+ project(fullPath: $fullPath) @include(if: $isProject) {
+ openedIssues: issues(
+ state: opened
+ search: $search
+ assigneeId: $assigneeId
+ assigneeUsernames: $assigneeUsernames
+ authorUsername: $authorUsername
+ labelName: $labelName
+ milestoneTitle: $milestoneTitle
+ milestoneWildcardId: $milestoneWildcardId
+ types: $types
+ not: $not
+ ) {
+ count
+ }
+ closedIssues: issues(
+ state: closed
+ search: $search
+ assigneeId: $assigneeId
+ assigneeUsernames: $assigneeUsernames
+ authorUsername: $authorUsername
+ labelName: $labelName
+ milestoneTitle: $milestoneTitle
+ milestoneWildcardId: $milestoneWildcardId
+ types: $types
+ not: $not
+ ) {
+ count
+ }
+ allIssues: issues(
+ state: all
+ search: $search
+ assigneeId: $assigneeId
+ assigneeUsernames: $assigneeUsernames
+ authorUsername: $authorUsername
+ labelName: $labelName
+ milestoneTitle: $milestoneTitle
+ milestoneWildcardId: $milestoneWildcardId
+ types: $types
+ not: $not
+ ) {
+ count
+ }
+ }
+}
diff --git a/app/assets/javascripts/issues_list/queries/issue.fragment.graphql b/app/assets/javascripts/issues_list/queries/issue.fragment.graphql
index 633b06eced8..9c46cb3ef64 100644
--- a/app/assets/javascripts/issues_list/queries/issue.fragment.graphql
+++ b/app/assets/javascripts/issues_list/queries/issue.fragment.graphql
@@ -13,6 +13,7 @@ fragment IssueFragment on Issue {
updatedAt
upvotes
userDiscussionsCount @include(if: $isSignedIn)
+ webPath
webUrl
assignees {
nodes {
diff --git a/app/assets/javascripts/issues_list/queries/iteration.fragment.graphql b/app/assets/javascripts/issues_list/queries/iteration.fragment.graphql
new file mode 100644
index 00000000000..78a368089a8
--- /dev/null
+++ b/app/assets/javascripts/issues_list/queries/iteration.fragment.graphql
@@ -0,0 +1,4 @@
+fragment Iteration on Iteration {
+ id
+ title
+}
diff --git a/app/assets/javascripts/issues_list/queries/label.fragment.graphql b/app/assets/javascripts/issues_list/queries/label.fragment.graphql
new file mode 100644
index 00000000000..bb1d8f1ac9b
--- /dev/null
+++ b/app/assets/javascripts/issues_list/queries/label.fragment.graphql
@@ -0,0 +1,6 @@
+fragment Label on Label {
+ id
+ color
+ textColor
+ title
+}
diff --git a/app/assets/javascripts/issues_list/queries/milestone.fragment.graphql b/app/assets/javascripts/issues_list/queries/milestone.fragment.graphql
new file mode 100644
index 00000000000..3cdf69bf585
--- /dev/null
+++ b/app/assets/javascripts/issues_list/queries/milestone.fragment.graphql
@@ -0,0 +1,4 @@
+fragment Milestone on Milestone {
+ id
+ title
+}
diff --git a/app/assets/javascripts/issues_list/queries/reorder_issues.mutation.graphql b/app/assets/javascripts/issues_list/queries/reorder_issues.mutation.graphql
index 5927e3e83c7..160026a4742 100644
--- a/app/assets/javascripts/issues_list/queries/reorder_issues.mutation.graphql
+++ b/app/assets/javascripts/issues_list/queries/reorder_issues.mutation.graphql
@@ -1,7 +1,13 @@
-mutation reorderIssues($oldIndex: Int, $newIndex: Int, $serializedVariables: String) {
+mutation reorderIssues(
+ $oldIndex: Int
+ $newIndex: Int
+ $namespace: String
+ $serializedVariables: String
+) {
reorderIssues(
oldIndex: $oldIndex
newIndex: $newIndex
+ namespace: $namespace
serializedVariables: $serializedVariables
) @client
}
diff --git a/app/assets/javascripts/issues_list/queries/search_iterations.query.graphql b/app/assets/javascripts/issues_list/queries/search_iterations.query.graphql
index 11d9dcea573..93600c62905 100644
--- a/app/assets/javascripts/issues_list/queries/search_iterations.query.graphql
+++ b/app/assets/javascripts/issues_list/queries/search_iterations.query.graphql
@@ -1,9 +1,17 @@
-query searchIterations($projectPath: ID!, $search: String, $id: ID) {
- project(fullPath: $projectPath) {
- iterations(title: $search, id: $id) {
+#import "./iteration.fragment.graphql"
+
+query searchIterations($fullPath: ID!, $search: String, $id: ID, $isProject: Boolean = false) {
+ group(fullPath: $fullPath) @skip(if: $isProject) {
+ iterations(title: $search, id: $id, includeAncestors: true) {
nodes {
- id
- title
+ ...Iteration
+ }
+ }
+ }
+ project(fullPath: $fullPath) @include(if: $isProject) {
+ iterations(title: $search, id: $id, includeAncestors: true) {
+ nodes {
+ ...Iteration
}
}
}
diff --git a/app/assets/javascripts/issues_list/queries/search_labels.query.graphql b/app/assets/javascripts/issues_list/queries/search_labels.query.graphql
index de884e1221c..1515bd91da3 100644
--- a/app/assets/javascripts/issues_list/queries/search_labels.query.graphql
+++ b/app/assets/javascripts/issues_list/queries/search_labels.query.graphql
@@ -1,11 +1,17 @@
-query searchLabels($projectPath: ID!, $search: String) {
- project(fullPath: $projectPath) {
+#import "./label.fragment.graphql"
+
+query searchLabels($fullPath: ID!, $search: String, $isProject: Boolean = false) {
+ group(fullPath: $fullPath) @skip(if: $isProject) {
+ labels(searchTerm: $search, includeAncestorGroups: true, includeDescendantGroups: true) {
+ nodes {
+ ...Label
+ }
+ }
+ }
+ project(fullPath: $fullPath) @include(if: $isProject) {
labels(searchTerm: $search, includeAncestorGroups: true) {
nodes {
- id
- color
- textColor
- title
+ ...Label
}
}
}
diff --git a/app/assets/javascripts/issues_list/queries/search_milestones.query.graphql b/app/assets/javascripts/issues_list/queries/search_milestones.query.graphql
index 91f74fd220b..8c6c50e9dc2 100644
--- a/app/assets/javascripts/issues_list/queries/search_milestones.query.graphql
+++ b/app/assets/javascripts/issues_list/queries/search_milestones.query.graphql
@@ -1,9 +1,17 @@
-query searchMilestones($projectPath: ID!, $search: String) {
- project(fullPath: $projectPath) {
+#import "./milestone.fragment.graphql"
+
+query searchMilestones($fullPath: ID!, $search: String, $isProject: Boolean = false) {
+ group(fullPath: $fullPath) @skip(if: $isProject) {
+ milestones(searchTitle: $search, includeAncestors: true, includeDescendants: true) {
+ nodes {
+ ...Milestone
+ }
+ }
+ }
+ project(fullPath: $fullPath) @include(if: $isProject) {
milestones(searchTitle: $search, includeAncestors: true) {
nodes {
- id
- title
+ ...Milestone
}
}
}
diff --git a/app/assets/javascripts/issues_list/queries/search_users.query.graphql b/app/assets/javascripts/issues_list/queries/search_users.query.graphql
index 953157cfe3a..0211fc66235 100644
--- a/app/assets/javascripts/issues_list/queries/search_users.query.graphql
+++ b/app/assets/javascripts/issues_list/queries/search_users.query.graphql
@@ -1,12 +1,20 @@
-query searchUsers($projectPath: ID!, $search: String) {
- project(fullPath: $projectPath) {
+#import "./user.fragment.graphql"
+
+query searchUsers($fullPath: ID!, $search: String, $isProject: Boolean = false) {
+ group(fullPath: $fullPath) @skip(if: $isProject) {
+ groupMembers(search: $search) {
+ nodes {
+ user {
+ ...User
+ }
+ }
+ }
+ }
+ project(fullPath: $fullPath) @include(if: $isProject) {
projectMembers(search: $search) {
nodes {
user {
- id
- avatarUrl
- name
- username
+ ...User
}
}
}
diff --git a/app/assets/javascripts/issues_list/queries/user.fragment.graphql b/app/assets/javascripts/issues_list/queries/user.fragment.graphql
new file mode 100644
index 00000000000..3e5bc0f7b93
--- /dev/null
+++ b/app/assets/javascripts/issues_list/queries/user.fragment.graphql
@@ -0,0 +1,6 @@
+fragment User on User {
+ id
+ avatarUrl
+ name
+ username
+}
diff --git a/app/assets/javascripts/jira_connect/subscriptions/utils.js b/app/assets/javascripts/jira_connect/subscriptions/utils.js
index ecd1a31339a..ed7a9484a81 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/utils.js
+++ b/app/assets/javascripts/jira_connect/subscriptions/utils.js
@@ -7,7 +7,7 @@ const isFunction = (fn) => typeof fn === 'function';
* Persist alert data to localStorage.
*/
export const persistAlert = ({ title, message, linkUrl, variant } = {}) => {
- if (!AccessorUtilities.isLocalStorageAccessSafe()) {
+ if (!AccessorUtilities.canUseLocalStorage()) {
return;
}
@@ -19,7 +19,7 @@ export const persistAlert = ({ title, message, linkUrl, variant } = {}) => {
* Return alert data from localStorage.
*/
export const retrieveAlert = () => {
- if (!AccessorUtilities.isLocalStorageAccessSafe()) {
+ if (!AccessorUtilities.canUseLocalStorage()) {
return null;
}
diff --git a/app/assets/javascripts/jobs/components/job_app.vue b/app/assets/javascripts/jobs/components/job_app.vue
index fa9ee56c049..059772e8cb9 100644
--- a/app/assets/javascripts/jobs/components/job_app.vue
+++ b/app/assets/javascripts/jobs/components/job_app.vue
@@ -5,7 +5,7 @@ import { throttle, isEmpty } from 'lodash';
import { mapGetters, mapState, mapActions } from 'vuex';
import CodeQualityWalkthrough from '~/code_quality_walkthrough/components/step.vue';
import { isScrolledToBottom } from '~/lib/utils/scroll_utils';
-import { sprintf } from '~/locale';
+import { __, sprintf } from '~/locale';
import CiHeader from '~/vue_shared/components/header_ci_component.vue';
import delayedJobMixin from '../mixins/delayed_job_mixin';
import EmptyState from './empty_state.vue';
@@ -126,6 +126,9 @@ export default {
shouldRenderCodeQualityWalkthrough() {
return this.job.status.group === 'failed-with-warnings';
},
+ itemName() {
+ return sprintf(__('Job %{jobName}'), { jobName: this.job.name });
+ },
},
watch: {
// Once the job log is loaded,
@@ -205,12 +208,11 @@ export default {
<div class="build-header top-area">
<ci-header
:status="job.status"
- :item-id="job.id"
:time="headerTime"
:user="job.user"
:has-sidebar-button="true"
:should-render-triggered-label="shouldRenderTriggeredLabel"
- :item-name="__('Job')"
+ :item-name="itemName"
@clickedSidebarButton="toggleSidebar"
/>
</div>
diff --git a/app/assets/javascripts/jobs/components/table/cells/actions_cell.vue b/app/assets/javascripts/jobs/components/table/cells/actions_cell.vue
index 376482b0319..6b3a4424a5b 100644
--- a/app/assets/javascripts/jobs/components/table/cells/actions_cell.vue
+++ b/app/assets/javascripts/jobs/components/table/cells/actions_cell.vue
@@ -1,14 +1,195 @@
<script>
+import { GlButton, GlButtonGroup, GlModal, GlModalDirective, GlSprintf } from '@gitlab/ui';
+import GlCountdown from '~/vue_shared/components/gl_countdown.vue';
+import {
+ ACTIONS_DOWNLOAD_ARTIFACTS,
+ ACTIONS_START_NOW,
+ ACTIONS_UNSCHEDULE,
+ ACTIONS_PLAY,
+ ACTIONS_RETRY,
+ CANCEL,
+ GENERIC_ERROR,
+ JOB_SCHEDULED,
+ PLAY_JOB_CONFIRMATION_MESSAGE,
+ RUN_JOB_NOW_HEADER_TITLE,
+} from '../constants';
+import eventHub from '../event_hub';
+import cancelJobMutation from '../graphql/mutations/job_cancel.mutation.graphql';
+import playJobMutation from '../graphql/mutations/job_play.mutation.graphql';
+import retryJobMutation from '../graphql/mutations/job_retry.mutation.graphql';
+import unscheduleJobMutation from '../graphql/mutations/job_unschedule.mutation.graphql';
+
export default {
+ ACTIONS_DOWNLOAD_ARTIFACTS,
+ ACTIONS_START_NOW,
+ ACTIONS_UNSCHEDULE,
+ ACTIONS_PLAY,
+ ACTIONS_RETRY,
+ CANCEL,
+ GENERIC_ERROR,
+ PLAY_JOB_CONFIRMATION_MESSAGE,
+ RUN_JOB_NOW_HEADER_TITLE,
+ jobRetry: 'jobRetry',
+ jobCancel: 'jobCancel',
+ jobPlay: 'jobPlay',
+ jobUnschedule: 'jobUnschedule',
+ playJobModalId: 'play-job-modal',
+ components: {
+ GlButton,
+ GlButtonGroup,
+ GlCountdown,
+ GlModal,
+ GlSprintf,
+ },
+ directives: {
+ GlModalDirective,
+ },
+ inject: {
+ admin: {
+ default: false,
+ },
+ },
props: {
job: {
type: Object,
required: true,
},
},
+ computed: {
+ artifactDownloadPath() {
+ return this.job.artifacts?.nodes[0]?.downloadPath;
+ },
+ canReadJob() {
+ return this.job.userPermissions?.readBuild;
+ },
+ isActive() {
+ return this.job.active;
+ },
+ manualJobPlayable() {
+ return this.job.playable && !this.admin && this.job.manualJob;
+ },
+ isRetryable() {
+ return this.job.retryable;
+ },
+ isScheduled() {
+ return this.job.status === JOB_SCHEDULED;
+ },
+ scheduledAt() {
+ return this.job.scheduledAt;
+ },
+ currentJobActionPath() {
+ return this.job.detailedStatus?.action?.path;
+ },
+ currentJobMethod() {
+ return this.job.detailedStatus?.action?.method;
+ },
+ shouldDisplayArtifacts() {
+ return this.job.userPermissions?.readJobArtifacts && this.job.artifacts?.nodes.length > 0;
+ },
+ },
+ methods: {
+ async postJobAction(name, mutation) {
+ try {
+ const {
+ data: {
+ [name]: { errors },
+ },
+ } = await this.$apollo.mutate({
+ mutation,
+ variables: { id: this.job.id },
+ });
+ if (errors.length > 0) {
+ this.reportFailure();
+ } else {
+ eventHub.$emit('jobActionPerformed');
+ }
+ } catch {
+ this.reportFailure();
+ }
+ },
+ reportFailure() {
+ const toastProps = {
+ text: this.$options.GENERIC_ERROR,
+ variant: 'danger',
+ };
+
+ this.$toast.show(toastProps.text, {
+ variant: toastProps.variant,
+ });
+ },
+ cancelJob() {
+ this.postJobAction(this.$options.jobCancel, cancelJobMutation);
+ },
+ retryJob() {
+ this.postJobAction(this.$options.jobRetry, retryJobMutation);
+ },
+ playJob() {
+ this.postJobAction(this.$options.jobPlay, playJobMutation);
+ },
+ unscheduleJob() {
+ this.postJobAction(this.$options.jobUnschedule, unscheduleJobMutation);
+ },
+ },
};
</script>
<template>
- <div></div>
+ <gl-button-group>
+ <template v-if="canReadJob">
+ <gl-button v-if="isActive" icon="cancel" :title="$options.CANCEL" @click="cancelJob()" />
+ <template v-else-if="isScheduled">
+ <gl-button icon="planning" disabled data-testid="countdown">
+ <gl-countdown :end-date-string="scheduledAt" />
+ </gl-button>
+ <gl-button
+ v-gl-modal-directive="$options.playJobModalId"
+ icon="play"
+ :title="$options.ACTIONS_START_NOW"
+ data-testid="play-scheduled"
+ />
+ <gl-modal
+ :modal-id="$options.playJobModalId"
+ :title="$options.RUN_JOB_NOW_HEADER_TITLE"
+ @primary="playJob()"
+ >
+ <gl-sprintf :message="$options.PLAY_JOB_CONFIRMATION_MESSAGE">
+ <template #job_name>{{ job.name }}</template>
+ </gl-sprintf>
+ </gl-modal>
+ <gl-button
+ icon="time-out"
+ :title="$options.ACTIONS_UNSCHEDULE"
+ data-testid="unschedule"
+ @click="unscheduleJob()"
+ />
+ </template>
+ <template v-else>
+ <!--Note: This is the manual job play button -->
+ <gl-button
+ v-if="manualJobPlayable"
+ icon="play"
+ :title="$options.ACTIONS_PLAY"
+ data-testid="play"
+ @click="playJob()"
+ />
+ <gl-button
+ v-else-if="isRetryable"
+ icon="repeat"
+ :title="$options.ACTIONS_RETRY"
+ :method="currentJobMethod"
+ data-testid="retry"
+ @click="retryJob()"
+ />
+ </template>
+ </template>
+ <gl-button
+ v-if="shouldDisplayArtifacts"
+ icon="download"
+ :title="$options.ACTIONS_DOWNLOAD_ARTIFACTS"
+ :href="artifactDownloadPath"
+ rel="nofollow"
+ download
+ data-testid="download-artifacts"
+ />
+ </gl-button-group>
</template>
diff --git a/app/assets/javascripts/jobs/components/table/constants.js b/app/assets/javascripts/jobs/components/table/constants.js
index 7e973a34e5c..e5d1bc01cbf 100644
--- a/app/assets/javascripts/jobs/components/table/constants.js
+++ b/app/assets/javascripts/jobs/components/table/constants.js
@@ -1,3 +1,5 @@
+import { s__, __ } from '~/locale';
+
export const GRAPHQL_PAGE_SIZE = 30;
export const initialPaginationState = {
@@ -7,3 +9,24 @@ export const initialPaginationState = {
first: GRAPHQL_PAGE_SIZE,
last: null,
};
+
+/* Error constants */
+export const POST_FAILURE = 'post_failure';
+export const DEFAULT = 'default';
+
+/* Job Status Constants */
+export const JOB_SCHEDULED = 'SCHEDULED';
+
+/* i18n */
+export const ACTIONS_DOWNLOAD_ARTIFACTS = __('Download artifacts');
+export const ACTIONS_START_NOW = s__('DelayedJobs|Start now');
+export const ACTIONS_UNSCHEDULE = s__('DelayedJobs|Unschedule');
+export const ACTIONS_PLAY = __('Play');
+export const ACTIONS_RETRY = __('Retry');
+
+export const CANCEL = __('Cancel');
+export const GENERIC_ERROR = __('An error occurred while making the request.');
+export const PLAY_JOB_CONFIRMATION_MESSAGE = s__(
+ `DelayedJobs|Are you sure you want to run %{job_name} immediately? This job will run automatically after its timer finishes.`,
+);
+export const RUN_JOB_NOW_HEADER_TITLE = s__('DelayedJobs|Run the delayed job now?');
diff --git a/app/assets/javascripts/jobs/components/table/event_hub.js b/app/assets/javascripts/jobs/components/table/event_hub.js
new file mode 100644
index 00000000000..e31806ad199
--- /dev/null
+++ b/app/assets/javascripts/jobs/components/table/event_hub.js
@@ -0,0 +1,3 @@
+import createEventHub from '~/helpers/event_hub_factory';
+
+export default createEventHub();
diff --git a/app/assets/javascripts/jobs/components/table/graphql/fragments/job.fragment.graphql b/app/assets/javascripts/jobs/components/table/graphql/fragments/job.fragment.graphql
new file mode 100644
index 00000000000..06b065a86ce
--- /dev/null
+++ b/app/assets/javascripts/jobs/components/table/graphql/fragments/job.fragment.graphql
@@ -0,0 +1,3 @@
+fragment Job on CiJob {
+ id
+}
diff --git a/app/assets/javascripts/jobs/components/table/graphql/mutations/job_cancel.mutation.graphql b/app/assets/javascripts/jobs/components/table/graphql/mutations/job_cancel.mutation.graphql
new file mode 100644
index 00000000000..20935514d51
--- /dev/null
+++ b/app/assets/javascripts/jobs/components/table/graphql/mutations/job_cancel.mutation.graphql
@@ -0,0 +1,10 @@
+#import "../fragments/job.fragment.graphql"
+
+mutation cancelJob($id: CiBuildID!) {
+ jobCancel(input: { id: $id }) {
+ job {
+ ...Job
+ }
+ errors
+ }
+}
diff --git a/app/assets/javascripts/jobs/components/table/graphql/mutations/job_play.mutation.graphql b/app/assets/javascripts/jobs/components/table/graphql/mutations/job_play.mutation.graphql
new file mode 100644
index 00000000000..c94b045ac40
--- /dev/null
+++ b/app/assets/javascripts/jobs/components/table/graphql/mutations/job_play.mutation.graphql
@@ -0,0 +1,10 @@
+#import "../fragments/job.fragment.graphql"
+
+mutation playJob($id: CiBuildID!) {
+ jobPlay(input: { id: $id }) {
+ job {
+ ...Job
+ }
+ errors
+ }
+}
diff --git a/app/assets/javascripts/jobs/components/table/graphql/mutations/job_retry.mutation.graphql b/app/assets/javascripts/jobs/components/table/graphql/mutations/job_retry.mutation.graphql
new file mode 100644
index 00000000000..6e51f9a20fa
--- /dev/null
+++ b/app/assets/javascripts/jobs/components/table/graphql/mutations/job_retry.mutation.graphql
@@ -0,0 +1,10 @@
+#import "../fragments/job.fragment.graphql"
+
+mutation retryJob($id: CiBuildID!) {
+ jobRetry(input: { id: $id }) {
+ job {
+ ...Job
+ }
+ errors
+ }
+}
diff --git a/app/assets/javascripts/jobs/components/table/graphql/mutations/job_unschedule.mutation.graphql b/app/assets/javascripts/jobs/components/table/graphql/mutations/job_unschedule.mutation.graphql
new file mode 100644
index 00000000000..8be8c42f3c3
--- /dev/null
+++ b/app/assets/javascripts/jobs/components/table/graphql/mutations/job_unschedule.mutation.graphql
@@ -0,0 +1,10 @@
+#import "../fragments/job.fragment.graphql"
+
+mutation unscheduleJob($id: CiBuildID!) {
+ jobUnschedule(input: { id: $id }) {
+ job {
+ ...Job
+ }
+ errors
+ }
+}
diff --git a/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs.query.graphql b/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs.query.graphql
index 68c6584cda6..c8763d4767e 100644
--- a/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs.query.graphql
+++ b/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs.query.graphql
@@ -69,6 +69,7 @@ query getJobs(
stuck
userPermissions {
readBuild
+ readJobArtifacts
}
}
}
diff --git a/app/assets/javascripts/jobs/components/table/index.js b/app/assets/javascripts/jobs/components/table/index.js
index 05d6ebfd6d6..f24daf90815 100644
--- a/app/assets/javascripts/jobs/components/table/index.js
+++ b/app/assets/javascripts/jobs/components/table/index.js
@@ -1,9 +1,12 @@
+import { GlToast } from '@gitlab/ui';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import JobsTableApp from '~/jobs/components/table/jobs_table_app.vue';
import createDefaultClient from '~/lib/graphql';
+import { parseBoolean } from '~/lib/utils/common_utils';
Vue.use(VueApollo);
+Vue.use(GlToast);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(),
@@ -22,6 +25,7 @@ export default (containerId = 'js-jobs-table') => {
jobStatuses,
pipelineEditorPath,
emptyStateSvgPath,
+ admin,
} = containerEl.dataset;
return new Vue({
@@ -33,6 +37,7 @@ export default (containerId = 'js-jobs-table') => {
pipelineEditorPath,
jobStatuses: JSON.parse(jobStatuses),
jobCounts: JSON.parse(jobCounts),
+ admin: parseBoolean(admin),
},
render(createElement) {
return createElement(JobsTableApp);
diff --git a/app/assets/javascripts/jobs/components/table/jobs_table.vue b/app/assets/javascripts/jobs/components/table/jobs_table.vue
index 076c0e78b11..298c99c4162 100644
--- a/app/assets/javascripts/jobs/components/table/jobs_table.vue
+++ b/app/assets/javascripts/jobs/components/table/jobs_table.vue
@@ -141,7 +141,7 @@ export default {
</template>
<template #cell(actions)="{ item }">
- <actions-cell :job="item" />
+ <actions-cell class="gl-float-right" :job="item" />
</template>
</gl-table>
</template>
diff --git a/app/assets/javascripts/jobs/components/table/jobs_table_app.vue b/app/assets/javascripts/jobs/components/table/jobs_table_app.vue
index 2061b1f1eb2..c786d35ac68 100644
--- a/app/assets/javascripts/jobs/components/table/jobs_table_app.vue
+++ b/app/assets/javascripts/jobs/components/table/jobs_table_app.vue
@@ -2,6 +2,7 @@
import { GlAlert, GlPagination, GlSkeletonLoader } from '@gitlab/ui';
import { __ } from '~/locale';
import { GRAPHQL_PAGE_SIZE, initialPaginationState } from './constants';
+import eventHub from './event_hub';
import GetJobs from './graphql/queries/get_jobs.query.graphql';
import JobsTable from './jobs_table.vue';
import JobsTableEmptyState from './jobs_table_empty_state.vue';
@@ -74,7 +75,16 @@ export default {
return Boolean(this.prevPage || this.nextPage) && !this.$apollo.loading;
},
},
+ mounted() {
+ eventHub.$on('jobActionPerformed', this.handleJobAction);
+ },
+ beforeDestroy() {
+ eventHub.$off('jobActionPerformed', this.handleJobAction);
+ },
methods: {
+ handleJobAction() {
+ this.$apollo.queries.jobs.refetch({ statuses: this.scope });
+ },
fetchJobsByStatus(scope) {
this.scope = scope;
diff --git a/app/assets/javascripts/labels_select.js b/app/assets/javascripts/labels_select.js
index a62ab301227..68019a35dbb 100644
--- a/app/assets/javascripts/labels_select.js
+++ b/app/assets/javascripts/labels_select.js
@@ -1,13 +1,11 @@
/* eslint-disable func-names, no-underscore-dangle, no-new, consistent-return, no-shadow, no-param-reassign, no-lonely-if, no-empty */
/* global Issuable */
-/* global ListLabel */
import $ from 'jquery';
import { difference, isEqual, escape, sortBy, template, union } from 'lodash';
import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
import IssuableBulkUpdateActions from '~/issuable_bulk_update_sidebar/issuable_bulk_update_actions';
import { isScopedLabel } from '~/lib/utils/common_utils';
-import boardsStore from './boards/stores/boards_store';
import CreateLabelDropdown from './create_label';
import createFlash from './flash';
import axios from './lib/utils/axios_utils';
@@ -43,7 +41,6 @@ export default class LabelsSelect {
const $form = $dropdown.closest('form, .js-issuable-update');
const $sidebarCollapsedValue = $block.find('.sidebar-collapsed-icon span');
const $value = $block.find('.value');
- const $dropdownMenu = $dropdown.parent().find('.dropdown-menu');
const $loading = $block.find('.block-loading').addClass('gl-display-none');
const fieldName = $dropdown.data('fieldName');
let initialSelected = $selectbox
@@ -341,15 +338,11 @@ export default class LabelsSelect {
}
},
multiSelect: $dropdown.hasClass('js-multiselect'),
- vue: $dropdown.hasClass('js-issue-board-sidebar'),
+ vue: false,
clicked(clickEvent) {
- const { $el, e, isMarking } = clickEvent;
+ const { e, isMarking } = clickEvent;
const label = clickEvent.selectedObj;
- const hideLoader = () => {
- $loading.addClass('gl-display-none');
- };
-
const page = $('body').attr('data-page');
const isIssueIndex = page === 'projects:issues:index';
const isMRIndex = page === 'projects:merge_requests:index';
@@ -375,40 +368,6 @@ export default class LabelsSelect {
}
} else if ($dropdown.hasClass('js-filter-submit')) {
return $dropdown.closest('form').submit();
- } else if ($dropdown.hasClass('js-issue-board-sidebar')) {
- if ($el.hasClass('is-active')) {
- boardsStore.detail.issue.labels.push(
- new ListLabel({
- id: label.id,
- title: label.title,
- color: label.color,
- textColor: '#fff',
- }),
- );
- } else {
- let { labels } = boardsStore.detail.issue;
- labels = labels.filter((selectedLabel) => selectedLabel.id !== label.id);
- boardsStore.detail.issue.labels = labels;
- }
-
- $loading.removeClass('gl-display-none');
- const oldLabels = boardsStore.detail.issue.labels;
-
- boardsStore.detail.issue
- .update($dropdown.attr('data-issue-update'))
- .then(() => {
- if (isScopedLabel(label)) {
- const prevIds = oldLabels.map((label) => label.id);
- const newIds = boardsStore.detail.issue.labels.map((label) => label.id);
- const differentIds = prevIds.filter((x) => !newIds.includes(x));
- $dropdown.data('marked', newIds);
- $dropdownMenu
- .find(differentIds.map((id) => `[data-label-id="${id}"]`).join(','))
- .removeClass('is-active');
- }
- })
- .then(hideLoader)
- .catch(hideLoader);
} else if (handleClick) {
e.preventDefault();
handleClick(label);
@@ -419,13 +378,6 @@ export default class LabelsSelect {
}
}
},
- opened() {
- if ($dropdown.hasClass('js-issue-board-sidebar')) {
- const previousSelection = $dropdown.attr('data-selected');
- this.selected = previousSelection ? previousSelection.split(',') : [];
- $dropdown.data('deprecatedJQueryDropdown').updateLabel();
- }
- },
preserveContext: true,
});
diff --git a/app/assets/javascripts/learn_gitlab/track_learn_gitlab.js b/app/assets/javascripts/learn_gitlab/track_learn_gitlab.js
deleted file mode 100644
index 305d130f10c..00000000000
--- a/app/assets/javascripts/learn_gitlab/track_learn_gitlab.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import Tracking from '~/tracking';
-
-export default function trackLearnGitlab(learnGitlabA) {
- Tracking.event('projects:learn_gitlab:index', 'page_init', {
- label: 'learn_gitlab',
- property: learnGitlabA
- ? 'Growth::Conversion::Experiment::LearnGitLabA'
- : 'Growth::Activation::Experiment::LearnGitLabB',
- });
-}
diff --git a/app/assets/javascripts/lib/apollo/instrumentation_link.js b/app/assets/javascripts/lib/apollo/instrumentation_link.js
new file mode 100644
index 00000000000..2ab364557b8
--- /dev/null
+++ b/app/assets/javascripts/lib/apollo/instrumentation_link.js
@@ -0,0 +1,29 @@
+import { ApolloLink } from 'apollo-link';
+import { memoize } from 'lodash';
+
+export const FEATURE_CATEGORY_HEADER = 'x-gitlab-feature-category';
+
+/**
+ * Returns the ApolloLink (or null) used to add instrumentation metadata to the GraphQL request.
+ *
+ * - The result will be null if the `feature_category` cannot be found.
+ * - The result is memoized since the `feature_category` is the same for the entire page.
+ */
+export const getInstrumentationLink = memoize(() => {
+ const { feature_category: featureCategory } = gon;
+
+ if (!featureCategory) {
+ return null;
+ }
+
+ return new ApolloLink((operation, forward) => {
+ operation.setContext(({ headers = {} }) => ({
+ headers: {
+ ...headers,
+ [FEATURE_CATEGORY_HEADER]: featureCategory,
+ },
+ }));
+
+ return forward(operation);
+ });
+});
diff --git a/app/assets/javascripts/lib/dompurify.js b/app/assets/javascripts/lib/dompurify.js
index a026f76e51b..d421d66981e 100644
--- a/app/assets/javascripts/lib/dompurify.js
+++ b/app/assets/javascripts/lib/dompurify.js
@@ -3,7 +3,7 @@ import { getBaseURL, relativePathToAbsolute } from '~/lib/utils/url_utility';
const defaultConfig = {
// Safely allow SVG <use> tags
- ADD_TAGS: ['use'],
+ ADD_TAGS: ['use', 'gl-emoji'],
// Prevent possible XSS attacks with data-* attributes used by @rails/ujs
// See https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1421
FORBID_ATTR: ['data-remote', 'data-url', 'data-type', 'data-method'],
@@ -16,7 +16,7 @@ const getAllowedIconUrls = (gon = window.gon) =>
const isUrlAllowed = (url) => getAllowedIconUrls().some((allowedUrl) => url.startsWith(allowedUrl));
const isHrefSafe = (url) =>
- isUrlAllowed(url) || isUrlAllowed(relativePathToAbsolute(url, getBaseURL()));
+ isUrlAllowed(url) || isUrlAllowed(relativePathToAbsolute(url, getBaseURL())) || url.match(/^#/);
const removeUnsafeHref = (node, attr) => {
if (!node.hasAttribute(attr)) {
@@ -52,4 +52,4 @@ addHook('afterSanitizeAttributes', (node) => {
}
});
-export const sanitize = (val, config = defaultConfig) => dompurifySanitize(val, config);
+export const sanitize = (val, config) => dompurifySanitize(val, { ...defaultConfig, ...config });
diff --git a/app/assets/javascripts/lib/graphql.js b/app/assets/javascripts/lib/graphql.js
index 0804213cafa..b96a55fe116 100644
--- a/app/assets/javascripts/lib/graphql.js
+++ b/app/assets/javascripts/lib/graphql.js
@@ -10,6 +10,7 @@ import { StartupJSLink } from '~/lib/utils/apollo_startup_js_link';
import csrf from '~/lib/utils/csrf';
import { objectToQuery, queryToObject } from '~/lib/utils/url_utility';
import PerformanceBarService from '~/performance_bar/services/performance_bar_service';
+import { getInstrumentationLink } from './apollo/instrumentation_link';
export const fetchPolicies = {
CACHE_FIRST: 'cache-first',
@@ -140,14 +141,17 @@ export default (resolvers = {}, config = {}) => {
const appLink = ApolloLink.split(
hasSubscriptionOperation,
new ActionCableLink(),
- ApolloLink.from([
- requestCounterLink,
- performanceBarLink,
- new StartupJSLink(),
- apolloCaptchaLink,
- uploadsLink,
- requestLink,
- ]),
+ ApolloLink.from(
+ [
+ getInstrumentationLink(),
+ requestCounterLink,
+ performanceBarLink,
+ new StartupJSLink(),
+ apolloCaptchaLink,
+ uploadsLink,
+ requestLink,
+ ].filter(Boolean),
+ ),
);
return new ApolloClient({
diff --git a/app/assets/javascripts/lib/logger/hello.js b/app/assets/javascripts/lib/logger/hello.js
new file mode 100644
index 00000000000..18fa35ab55b
--- /dev/null
+++ b/app/assets/javascripts/lib/logger/hello.js
@@ -0,0 +1,16 @@
+const HANDSHAKE = String.fromCodePoint(0x1f91d);
+const MAG = String.fromCodePoint(0x1f50e);
+
+export const logHello = () => {
+ // eslint-disable-next-line no-console
+ console.log(
+ `%cWelcome to GitLab!%c
+
+Does this page need fixes or improvements? Open an issue or contribute a merge request to help make GitLab more lovable. At GitLab, everyone can contribute!
+
+${HANDSHAKE} Contribute to GitLab: https://about.gitlab.com/community/contribute/
+${MAG} Create a new GitLab issue: https://gitlab.com/gitlab-org/gitlab/-/issues/new`,
+ `padding-top: 0.5em; font-size: 2em;`,
+ 'padding-bottom: 0.5em;',
+ );
+};
diff --git a/app/assets/javascripts/lib/logger/hello_deferred.js b/app/assets/javascripts/lib/logger/hello_deferred.js
new file mode 100644
index 00000000000..ce1dd91cb37
--- /dev/null
+++ b/app/assets/javascripts/lib/logger/hello_deferred.js
@@ -0,0 +1,5 @@
+export const logHelloDeferred = async () => {
+ const { logHello } = await import(/* webpackChunkName: 'hello' */ './hello');
+
+ logHello();
+};
diff --git a/app/assets/javascripts/lib/logger/index.js b/app/assets/javascripts/lib/logger/index.js
new file mode 100644
index 00000000000..0f5353fcbed
--- /dev/null
+++ b/app/assets/javascripts/lib/logger/index.js
@@ -0,0 +1,6 @@
+/* eslint-disable no-console */
+export const LOG_PREFIX = '[gitlab]';
+
+export const logError = (message = '', ...args) => {
+ console.error(LOG_PREFIX, `${message}\n`, ...args);
+};
diff --git a/app/assets/javascripts/lib/utils/accessor.js b/app/assets/javascripts/lib/utils/accessor.js
index 39cffedcac6..d4a6d70c62c 100644
--- a/app/assets/javascripts/lib/utils/accessor.js
+++ b/app/assets/javascripts/lib/utils/accessor.js
@@ -1,4 +1,4 @@
-function isPropertyAccessSafe(base, property) {
+function canAccessProperty(base, property) {
let safe;
try {
@@ -10,7 +10,7 @@ function isPropertyAccessSafe(base, property) {
return safe;
}
-function isFunctionCallSafe(base, functionName, ...args) {
+function canCallFunction(base, functionName, ...args) {
let safe = true;
try {
@@ -22,16 +22,28 @@ function isFunctionCallSafe(base, functionName, ...args) {
return safe;
}
-function isLocalStorageAccessSafe() {
+/**
+ * Determines if `window.localStorage` is available and
+ * can be written to and read from.
+ *
+ * Important: This is not a guarantee that
+ * `localStorage.setItem` will work in all cases.
+ *
+ * `setItem` can still throw exceptions and should be
+ * surrounded with a try/catch where used.
+ *
+ * See: https://developer.mozilla.org/en-US/docs/Web/API/Storage/setItem#exceptions
+ */
+function canUseLocalStorage() {
let safe;
- const TEST_KEY = 'isLocalStorageAccessSafe';
+ const TEST_KEY = 'canUseLocalStorage';
const TEST_VALUE = 'true';
- safe = isPropertyAccessSafe(window, 'localStorage');
+ safe = canAccessProperty(window, 'localStorage');
if (!safe) return safe;
- safe = isFunctionCallSafe(window.localStorage, 'setItem', TEST_KEY, TEST_VALUE);
+ safe = canCallFunction(window.localStorage, 'setItem', TEST_KEY, TEST_VALUE);
if (safe) window.localStorage.removeItem(TEST_KEY);
@@ -39,9 +51,7 @@ function isLocalStorageAccessSafe() {
}
const AccessorUtilities = {
- isPropertyAccessSafe,
- isFunctionCallSafe,
- isLocalStorageAccessSafe,
+ canUseLocalStorage,
};
export default AccessorUtilities;
diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js
index 8f86fd55d6e..fd9629499b0 100644
--- a/app/assets/javascripts/lib/utils/common_utils.js
+++ b/app/assets/javascripts/lib/utils/common_utils.js
@@ -117,7 +117,6 @@ export const handleLocationHash = () => {
};
// Check if element scrolled into viewport from above or below
-// Courtesy http://stackoverflow.com/a/7557433/414749
export const isInViewport = (el, offset = {}) => {
const rect = el.getBoundingClientRect();
const { top, left } = offset;
@@ -560,11 +559,9 @@ export const addSelectOnFocusBehaviour = (selector = '.js-select-on-focus') => {
* Method to round of values with decimal places
* with provided precision.
*
- * Taken from https://stackoverflow.com/a/7343013/414749
- *
* Eg; roundOffFloat(3.141592, 3) = 3.142
*
- * Refer to spec/javascripts/lib/utils/common_utils_spec.js for
+ * Refer to spec/frontend/lib/utils/common_utils_spec.js for
* more supported examples.
*
* @param {Float} number
@@ -581,7 +578,7 @@ export const roundOffFloat = (number, precision = 0) => {
*
* Eg; roundToNearestHalf(3.141592) = 3, roundToNearestHalf(3.41592) = 3.5
*
- * Refer to spec/javascripts/lib/utils/common_utils_spec.js for
+ * Refer to spec/frontend/lib/utils/common_utils_spec.js for
* more supported examples.
*
* @param {Float} number
@@ -595,7 +592,7 @@ export const roundToNearestHalf = (num) => Math.round(num * 2).toFixed() / 2;
*
* Eg; roundDownFloat(3.141592, 3) = 3.141
*
- * Refer to spec/javascripts/lib/utils/common_utils_spec.js for
+ * Refer to spec/frontend/lib/utils/common_utils_spec.js for
* more supported examples.
*
* @param {Float} number
@@ -645,7 +642,7 @@ export const NavigationType = {
* matched with our query.
*
* You can learn more about behaviour of this method by referring to tests
- * within `spec/javascripts/lib/utils/common_utils_spec.js`.
+ * within `spec/frontend/lib/utils/common_utils_spec.js`.
*
* @param {string} query String to search for
* @param {object} searchSpace Object containing properties to search in for `query`
diff --git a/app/assets/javascripts/lib/utils/datetime/date_format_utility.js b/app/assets/javascripts/lib/utils/datetime/date_format_utility.js
index 246f290a90a..0a35efb0ac8 100644
--- a/app/assets/javascripts/lib/utils/datetime/date_format_utility.js
+++ b/app/assets/javascripts/lib/utils/datetime/date_format_utility.js
@@ -1,5 +1,5 @@
import dateFormat from 'dateformat';
-import { isString, mapValues, reduce } from 'lodash';
+import { isString, mapValues, reduce, isDate } from 'lodash';
import { s__, n__, __ } from '../../../locale';
/**
@@ -258,3 +258,106 @@ export const parseSeconds = (
return periodCount;
});
};
+
+/**
+ * Pads given items with zeros to reach a length of 2 characters.
+ *
+ * @param {...any} args Items to be padded.
+ * @returns {Array<String>} Padded items.
+ */
+export const padWithZeros = (...args) => args.map((arg) => `${arg}`.padStart(2, '0'));
+
+/**
+ * This removes the timezone from an ISO date string.
+ * This can be useful when populating date/time fields along with a distinct timezone selector, in
+ * which case we'd want to ignore the timezone's offset when populating the date and time.
+ *
+ * Examples:
+ * stripTimezoneFromISODate('2021-08-16T00:00:00.000-02:00') => '2021-08-16T00:00:00.000'
+ * stripTimezoneFromISODate('2021-08-16T00:00:00.000Z') => '2021-08-16T00:00:00.000'
+ *
+ * @param {String} date The ISO date string representation.
+ * @returns {String} The ISO date string without the timezone.
+ */
+export const stripTimezoneFromISODate = (date) => {
+ if (Number.isNaN(Date.parse(date))) {
+ return null;
+ }
+ return date.replace(/(Z|[+-]\d{2}:\d{2})$/, '');
+};
+
+/**
+ * Extracts the year, month and day from a Date instance and returns them in an object.
+ * For example:
+ * dateToYearMonthDate(new Date('2021-08-16')) => { year: '2021', month: '08', day: '16' }
+ *
+ * @param {Date} date The date to be parsed
+ * @returns {Object} An object containing the extracted year, month and day.
+ */
+export const dateToYearMonthDate = (date) => {
+ if (!isDate(date)) {
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ throw new Error('Argument should be a Date instance');
+ }
+ const [month, day] = padWithZeros(date.getMonth() + 1, date.getDate());
+ return {
+ year: `${date.getFullYear()}`,
+ month,
+ day,
+ };
+};
+
+/**
+ * Extracts the hours and minutes from a string representing a time.
+ * For example:
+ * timeToHoursMinutes('12:46') => { hours: '12', minutes: '46' }
+ *
+ * @param {String} time The time to be parsed in the form HH:MM.
+ * @returns {Object} An object containing the hours and minutes.
+ */
+export const timeToHoursMinutes = (time = '') => {
+ if (!time || !time.match(/\d{1,2}:\d{1,2}/)) {
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ throw new Error('Invalid time provided');
+ }
+ const [hours, minutes] = padWithZeros(...time.split(':'));
+ return { hours, minutes };
+};
+
+/**
+ * This combines a date and a time and returns the computed Date's ISO string representation.
+ *
+ * @param {Date} date Date object representing the base date.
+ * @param {String} time String representing the time to be used, in the form HH:MM.
+ * @param {String} offset An optional Date-compatible offset.
+ * @returns {String} The combined Date's ISO string representation.
+ */
+export const dateAndTimeToISOString = (date, time, offset = '') => {
+ const { year, month, day } = dateToYearMonthDate(date);
+ const { hours, minutes } = timeToHoursMinutes(time);
+ const dateString = `${year}-${month}-${day}T${hours}:${minutes}:00.000${offset || 'Z'}`;
+ if (Number.isNaN(Date.parse(dateString))) {
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ throw new Error('Could not initialize date');
+ }
+ return dateString;
+};
+
+/**
+ * Converts a Date instance to time input-compatible value consisting in a 2-digits hours and
+ * minutes, separated by a semi-colon, in the 24-hours format.
+ *
+ * @param {Date} date Date to be converted
+ * @returns {String} time input-compatible string in the form HH:MM.
+ */
+export const dateToTimeInputValue = (date) => {
+ if (!isDate(date)) {
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ throw new Error('Argument should be a Date instance');
+ }
+ return date.toLocaleTimeString([], {
+ hour: '2-digit',
+ minute: '2-digit',
+ hour12: false,
+ });
+};
diff --git a/app/assets/javascripts/lib/utils/dom_utils.js b/app/assets/javascripts/lib/utils/dom_utils.js
index f11c7658a88..f7687a929de 100644
--- a/app/assets/javascripts/lib/utils/dom_utils.js
+++ b/app/assets/javascripts/lib/utils/dom_utils.js
@@ -77,3 +77,15 @@ export const isElementVisible = (element) =>
* @returns {Boolean} `true` if the element is currently hidden, otherwise false
*/
export const isElementHidden = (element) => !isElementVisible(element);
+
+export const getParents = (element) => {
+ const parents = [];
+ let parent = element.parentNode;
+
+ do {
+ parents.push(parent);
+ parent = parent.parentNode;
+ } while (parent);
+
+ return parents;
+};
diff --git a/app/assets/javascripts/lib/utils/number_utils.js b/app/assets/javascripts/lib/utils/number_utils.js
index f3dedb7726a..f46263c0e4d 100644
--- a/app/assets/javascripts/lib/utils/number_utils.js
+++ b/app/assets/javascripts/lib/utils/number_utils.js
@@ -69,19 +69,20 @@ export function bytesToGiB(number) {
* representation (e.g., giving it 1500 yields 1.5 KB).
*
* @param {Number} size
+ * @param {Number} digits - The number of digits to appear after the decimal point
* @returns {String}
*/
-export function numberToHumanSize(size) {
+export function numberToHumanSize(size, digits = 2) {
const abs = Math.abs(size);
if (abs < BYTES_IN_KIB) {
return sprintf(__('%{size} bytes'), { size });
} else if (abs < BYTES_IN_KIB ** 2) {
- return sprintf(__('%{size} KiB'), { size: bytesToKiB(size).toFixed(2) });
+ return sprintf(__('%{size} KiB'), { size: bytesToKiB(size).toFixed(digits) });
} else if (abs < BYTES_IN_KIB ** 3) {
- return sprintf(__('%{size} MiB'), { size: bytesToMiB(size).toFixed(2) });
+ return sprintf(__('%{size} MiB'), { size: bytesToMiB(size).toFixed(digits) });
}
- return sprintf(__('%{size} GiB'), { size: bytesToGiB(size).toFixed(2) });
+ return sprintf(__('%{size} GiB'), { size: bytesToGiB(size).toFixed(digits) });
}
/**
diff --git a/app/assets/javascripts/lib/utils/text_markdown.js b/app/assets/javascripts/lib/utils/text_markdown.js
index 6ff2af47dd8..0804d792631 100644
--- a/app/assets/javascripts/lib/utils/text_markdown.js
+++ b/app/assets/javascripts/lib/utils/text_markdown.js
@@ -232,7 +232,9 @@ export function insertMarkdownText({
.join('\n');
}
} else if (tag.indexOf(textPlaceholder) > -1) {
- textToInsert = tag.replace(textPlaceholder, () => selected.replace(/\\n/g, '\n'));
+ textToInsert = tag.replace(textPlaceholder, () =>
+ selected.replace(/\\n/g, '\n').replace('%br', '\\n'),
+ );
} else {
textToInsert = String(startChar) + tag + selected + (wrap ? tag : '');
}
diff --git a/app/assets/javascripts/lib/utils/url_utility.js b/app/assets/javascripts/lib/utils/url_utility.js
index e9772232eaf..bca0e45d98d 100644
--- a/app/assets/javascripts/lib/utils/url_utility.js
+++ b/app/assets/javascripts/lib/utils/url_utility.js
@@ -418,43 +418,6 @@ export const urlParamsToArray = (path = '') =>
export const getUrlParamsArray = () => urlParamsToArray(window.location.search);
/**
- * Accepts encoding string which includes query params being
- * sent to URL.
- *
- * @param {string} path Query param string
- *
- * @returns {object} Query params object containing key-value pairs
- * with both key and values decoded into plain string.
- *
- * @deprecated Please use `queryToObject(query, { gatherArrays: true });` instead. See https://gitlab.com/gitlab-org/gitlab/-/issues/328845
- */
-export const urlParamsToObject = (path = '') =>
- splitPath(path).reduce((dataParam, filterParam) => {
- if (filterParam === '') {
- return dataParam;
- }
-
- const data = dataParam;
- let [key, value] = filterParam.split('=');
- key = /%\w+/g.test(key) ? decodeURIComponent(key) : key;
- const isArray = key.includes('[]');
- key = key.replace('[]', '');
- value = decodeURIComponent(value.replace(/\+/g, ' '));
-
- if (isArray) {
- if (!data[key]) {
- data[key] = [];
- }
-
- data[key].push(value);
- } else {
- data[key] = value;
- }
-
- return data;
- }, {});
-
-/**
* Convert search query into an object
*
* @param {String} query from "document.location.search"
diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js
index 1aaefcaa13b..b96a2607552 100644
--- a/app/assets/javascripts/main.js
+++ b/app/assets/javascripts/main.js
@@ -19,6 +19,7 @@ import initAlertHandler from './alert_handler';
import { removeFlashClickListener } from './flash';
import initTodoToggle from './header';
import initLayoutNav from './layout_nav';
+import { logHelloDeferred } from './lib/logger/hello_deferred';
import { handleLocationHash, addSelectOnFocusBehaviour } from './lib/utils/common_utils';
import { localTimeAgo } from './lib/utils/datetime/timeago_utility';
import { getLocationHash, visitUrl } from './lib/utils/url_utility';
@@ -35,8 +36,12 @@ import GlFieldErrors from './gl_field_errors';
import initUserPopovers from './user_popovers';
import initBroadcastNotifications from './broadcast_notification';
import { initTopNav } from './nav';
+import { initHeaderSearchApp } from '~/header_search';
import 'ee_else_ce/main_ee';
+import 'jh_else_ce/main_jh';
+
+logHelloDeferred();
applyGitLabUIConfig();
@@ -94,20 +99,24 @@ function deferredInitialisation() {
initDefaultTrackers();
initFeatureHighlight();
- const search = document.querySelector('#search');
- if (search) {
- search.addEventListener(
- 'focus',
- () => {
- import(/* webpackChunkName: 'globalSearch' */ './search_autocomplete')
- .then(({ default: initSearchAutocomplete }) => {
- const searchDropdown = initSearchAutocomplete();
- searchDropdown.onSearchInputFocus();
- })
- .catch(() => {});
- },
- { once: true },
- );
+ if (gon.features?.newHeaderSearch) {
+ initHeaderSearchApp();
+ } else {
+ const search = document.querySelector('#search');
+ if (search) {
+ search.addEventListener(
+ 'focus',
+ () => {
+ import(/* webpackChunkName: 'globalSearch' */ './search_autocomplete')
+ .then(({ default: initSearchAutocomplete }) => {
+ const searchDropdown = initSearchAutocomplete();
+ searchDropdown.onSearchInputFocus();
+ })
+ .catch(() => {});
+ },
+ { once: true },
+ );
+ }
}
addSelectOnFocusBehaviour('.js-select-on-focus');
diff --git a/app/assets/javascripts/main_jh.js b/app/assets/javascripts/main_jh.js
new file mode 100644
index 00000000000..13a6b8f3d3d
--- /dev/null
+++ b/app/assets/javascripts/main_jh.js
@@ -0,0 +1 @@
+// This is an empty file to satisfy jh_else_ce import for the JH main entry point
diff --git a/app/assets/javascripts/merge_request.js b/app/assets/javascripts/merge_request.js
index 0ddb2c2334c..ed32f26583e 100644
--- a/app/assets/javascripts/merge_request.js
+++ b/app/assets/javascripts/merge_request.js
@@ -19,11 +19,9 @@ function MergeRequest(opts) {
this.opts = opts != null ? opts : {};
this.submitNoteForm = this.submitNoteForm.bind(this);
this.$el = $('.merge-request');
- this.$('.show-all-commits').on('click', () => this.showAllCommits());
this.initTabs();
this.initMRBtnListeners();
- this.initCommitMessageListeners();
if ($('.description.js-task-list-container').length) {
this.taskList = new TaskList({
@@ -59,11 +57,6 @@ MergeRequest.prototype.initTabs = function () {
window.mrTabs = new MergeRequestTabs(this.opts);
};
-MergeRequest.prototype.showAllCommits = function () {
- this.$('.first-commits').remove();
- return this.$('.all-commits').removeClass('hide');
-};
-
MergeRequest.prototype.initMRBtnListeners = function () {
const _this = this;
const draftToggles = document.querySelectorAll('.js-draft-toggle-button');
@@ -128,26 +121,6 @@ MergeRequest.prototype.submitNoteForm = function (form, $button) {
}
};
-MergeRequest.prototype.initCommitMessageListeners = function () {
- $(document).on('click', 'a.js-with-description-link', (e) => {
- const textarea = $('textarea.js-commit-message');
- e.preventDefault();
-
- textarea.val(textarea.data('messageWithDescription'));
- $('.js-with-description-hint').hide();
- $('.js-without-description-hint').show();
- });
-
- $(document).on('click', 'a.js-without-description-link', (e) => {
- const textarea = $('textarea.js-commit-message');
- e.preventDefault();
-
- textarea.val(textarea.data('messageWithoutDescription'));
- $('.js-with-description-hint').show();
- $('.js-without-description-hint').hide();
- });
-};
-
MergeRequest.decreaseCounter = function (by = 1) {
const $el = $('.js-merge-counter');
const count = Math.max(parseInt($el.text().replace(/[^\d]/, ''), 10) - by, 0);
@@ -164,7 +137,7 @@ MergeRequest.hideCloseButton = function () {
MergeRequest.toggleDraftStatus = function (title, isReady) {
if (isReady) {
createFlash({
- message: __('The merge request can now be merged.'),
+ message: __('Marked as ready. Merging is now allowed.'),
type: 'notice',
});
}
diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js
index 14e5e96d7b0..a40caea1223 100644
--- a/app/assets/javascripts/merge_request_tabs.js
+++ b/app/assets/javascripts/merge_request_tabs.js
@@ -7,20 +7,17 @@ import createEventHub from '~/helpers/event_hub_factory';
import BlobForkSuggestion from './blob/blob_fork_suggestion';
import Diff from './diff';
import createFlash from './flash';
-import initChangesDropdown from './init_changes_dropdown';
+import { initDiffStatsDropdown } from './init_diff_stats_dropdown';
import axios from './lib/utils/axios_utils';
import {
parseUrlPathname,
- handleLocationHash,
isMetaClick,
parseBoolean,
scrollToElement,
} from './lib/utils/common_utils';
import { localTimeAgo } from './lib/utils/datetime_utility';
import { isInVueNoteablePage } from './lib/utils/dom_utils';
-import { getLocationHash } from './lib/utils/url_utility';
import { __ } from './locale';
-import Notes from './notes';
import syntaxHighlight from './syntax_highlight';
// MergeRequestTabs
@@ -67,6 +64,8 @@ import syntaxHighlight from './syntax_highlight';
// </div>
//
+// <100ms is typically indistinguishable from "instant" for users, but allows for re-rendering
+const FAST_DELAY_FOR_RERENDER = 75;
// Store the `location` object, allowing for easier stubbing in tests
let { location } = window;
@@ -86,6 +85,8 @@ export default class MergeRequestTabs {
this.peek = document.getElementById('js-peek');
this.paddingTop = 16;
+ this.scrollPositions = {};
+
this.commitsTab = document.querySelector('.tab-content .commits.tab-pane');
this.currentTab = null;
@@ -139,11 +140,30 @@ export default class MergeRequestTabs {
}
}
+ storeScroll() {
+ if (this.currentTab) {
+ this.scrollPositions[this.currentTab] = document.documentElement.scrollTop;
+ }
+ }
+ recallScroll(action) {
+ const storedPosition = this.scrollPositions[action];
+
+ setTimeout(() => {
+ window.scrollTo({
+ top: storedPosition && storedPosition > 0 ? storedPosition : 0,
+ left: 0,
+ behavior: 'auto',
+ });
+ }, FAST_DELAY_FOR_RERENDER);
+ }
+
clickTab(e) {
if (e.currentTarget) {
e.stopImmediatePropagation();
e.preventDefault();
+ this.storeScroll();
+
const { action } = e.currentTarget.dataset || {};
if (isMetaClick(e)) {
@@ -193,6 +213,14 @@ export default class MergeRequestTabs {
this.destroyPipelinesView();
} else if (this.isDiffAction(action)) {
if (!isInVueNoteablePage()) {
+ /*
+ for pages where we have not yet converted to the new vue
+ implementation we load the diff tab content the old way,
+ inserting html rendered by the backend.
+
+ in practice, this only occurs when comparing commits in
+ the new merge request form page.
+ */
this.loadDiff(href);
}
if (bp.getBreakpointSize() !== 'xl') {
@@ -205,8 +233,14 @@ export default class MergeRequestTabs {
this.resetViewContainer();
this.mountPipelinesView();
} else {
- this.mergeRequestTabPanes.querySelector('#notes').style.display = 'block';
- this.mergeRequestTabs.querySelector('.notes-tab').classList.add('active');
+ const notesTab = this.mergeRequestTabs.querySelector('.notes-tab');
+ const notesPane = this.mergeRequestTabPanes.querySelector('#notes');
+ if (notesPane) {
+ notesPane.style.display = 'block';
+ }
+ if (notesTab) {
+ notesTab.classList.add('active');
+ }
if (bp.getBreakpointSize() !== 'xs') {
this.expandView();
@@ -216,6 +250,8 @@ export default class MergeRequestTabs {
}
$('.detail-page-description').renderGFM();
+
+ this.recallScroll(action);
} else if (action === this.currentAction) {
// ContentTop is used to handle anything at the top of the page before the main content
const mainContentContainer = document.querySelector('.content-wrapper');
@@ -379,6 +415,7 @@ export default class MergeRequestTabs {
pipelineTableViewEl.appendChild(this.commitPipelinesTable.$el);
}
+ // load the diff tab content from the backend
loadDiff(source) {
if (this.diffsLoaded) {
document.dispatchEvent(new CustomEvent('scroll'));
@@ -396,8 +433,7 @@ export default class MergeRequestTabs {
.then(({ data }) => {
const $container = $('#diffs');
$container.html(data.html);
-
- initChangesDropdown(this.stickyTop);
+ initDiffStatsDropdown(this.stickyTop);
localTimeAgo(document.querySelectorAll('#diffs .js-timeago'));
syntaxHighlight($('#diffs .js-syntax-highlight'));
@@ -420,25 +456,6 @@ export default class MergeRequestTabs {
}).init();
});
- // Scroll any linked note into view
- // Similar to `toggler_behavior` in the discussion tab
- const hash = getLocationHash();
- const anchor = hash && $container.find(`.note[id="${hash}"]`);
- if (anchor && anchor.length > 0) {
- const notesContent = anchor.closest('.notes-content');
- const lineType = notesContent.hasClass('new') ? 'new' : 'old';
- Notes.instance.toggleDiffNote({
- target: anchor,
- lineType,
- forceShow: true,
- });
- anchor[0].scrollIntoView();
- handleLocationHash();
- // We have multiple elements on the page with `#note_xxx`
- // (discussion and diff tabs) and `:target` only applies to the first
- anchor.addClass('target');
- }
-
this.toggleLoading(false);
})
.catch(() => {
diff --git a/app/assets/javascripts/milestone_select.js b/app/assets/javascripts/milestone_select.js
index 0d9a2eef01a..aa8a40b6a87 100644
--- a/app/assets/javascripts/milestone_select.js
+++ b/app/assets/javascripts/milestone_select.js
@@ -1,6 +1,5 @@
/* eslint-disable one-var, no-self-compare, consistent-return, no-param-reassign, no-shadow */
/* global Issuable */
-/* global ListMilestone */
import $ from 'jquery';
import { template, escape } from 'lodash';
@@ -8,10 +7,6 @@ import Api from '~/api';
import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
import { __, sprintf } from '~/locale';
import { sortMilestonesByDueDate } from '~/milestones/milestone_utils';
-import boardsStore, {
- boardStoreIssueSet,
- boardStoreIssueDelete,
-} from './boards/stores/boards_store';
import axios from './lib/utils/axios_utils';
import { timeFor, parsePikadayDate, dateInWords } from './lib/utils/datetime_utility';
@@ -186,18 +181,17 @@ export default class MilestoneSelect {
},
opened: (e) => {
const $el = $(e.currentTarget);
- if ($dropdown.hasClass('js-issue-board-sidebar') || options.handleClick) {
+ if (options.handleClick) {
selectedMilestone = $dropdown[0].dataset.selected || selectedMilestoneDefault;
}
$('a.is-active', $el).removeClass('is-active');
$(`[data-milestone-id="${selectedMilestone}"] > a`, $el).addClass('is-active');
},
- vue: $dropdown.hasClass('js-issue-board-sidebar'),
+ vue: false,
clicked: (clickEvent) => {
const { e } = clickEvent;
let selected = clickEvent.selectedObj;
- let data;
if (!selected) return;
if (options.handleClick) {
@@ -224,76 +218,52 @@ export default class MilestoneSelect {
return Issuable.filterResults($dropdown.closest('form'));
} else if ($dropdown.hasClass('js-filter-submit')) {
return $dropdown.closest('form').submit();
- } else if ($dropdown.hasClass('js-issue-board-sidebar')) {
- if (selected.id !== -1 && isSelecting) {
- boardStoreIssueSet(
- 'milestone',
- new ListMilestone({
- id: selected.id,
- title: selected.name,
- }),
- );
- } else {
- boardStoreIssueDelete('milestone');
- }
+ }
- $dropdown.trigger('loading.gl.dropdown');
- $loading.removeClass('gl-display-none');
+ selected = $selectBox.find('input[type="hidden"]').val();
- boardsStore.detail.issue
- .update($dropdown.attr('data-issue-update'))
- .then(() => {
- $dropdown.trigger('loaded.gl.dropdown');
- $loading.addClass('gl-display-none');
- })
- .catch(() => {
- $loading.addClass('gl-display-none');
- });
- } else {
- selected = $selectBox.find('input[type="hidden"]').val();
- data = {};
- data[abilityName] = {};
- data[abilityName].milestone_id = selected != null ? selected : null;
- $loading.removeClass('gl-display-none');
- $dropdown.trigger('loading.gl.dropdown');
- return axios
- .put(issueUpdateURL, data)
- .then(({ data }) => {
- $dropdown.trigger('loaded.gl.dropdown');
- $loading.addClass('gl-display-none');
- $selectBox.hide();
- $value.css('display', '');
- if (data.milestone != null) {
- data.milestone.remaining = timeFor(data.milestone.due_date);
- data.milestone.name = data.milestone.title;
- $value.html(
- data.milestone.expired
- ? milestoneExpiredLinkTemplate({
- ...data.milestone,
- remaining: sprintf(__('%{due_date} (Past due)'), {
- due_date: dateInWords(parsePikadayDate(data.milestone.due_date)),
- }),
- })
- : milestoneLinkTemplate(data.milestone),
- );
- return $sidebarCollapsedValue
- .attr(
- 'data-original-title',
- `${data.milestone.name}<br />${data.milestone.remaining}`,
- )
- .find('span')
- .text(data.milestone.title);
- }
- $value.html(milestoneLinkNoneTemplate);
+ const data = {};
+ data[abilityName] = {};
+ data[abilityName].milestone_id = selected != null ? selected : null;
+ $loading.removeClass('gl-display-none');
+ $dropdown.trigger('loading.gl.dropdown');
+ return axios
+ .put(issueUpdateURL, data)
+ .then(({ data }) => {
+ $dropdown.trigger('loaded.gl.dropdown');
+ $loading.addClass('gl-display-none');
+ $selectBox.hide();
+ $value.css('display', '');
+ if (data.milestone != null) {
+ data.milestone.remaining = timeFor(data.milestone.due_date);
+ data.milestone.name = data.milestone.title;
+ $value.html(
+ data.milestone.expired
+ ? milestoneExpiredLinkTemplate({
+ ...data.milestone,
+ remaining: sprintf(__('%{due_date} (Past due)'), {
+ due_date: dateInWords(parsePikadayDate(data.milestone.due_date)),
+ }),
+ })
+ : milestoneLinkTemplate(data.milestone),
+ );
return $sidebarCollapsedValue
- .attr('data-original-title', __('Milestone'))
+ .attr(
+ 'data-original-title',
+ `${data.milestone.name}<br />${data.milestone.remaining}`,
+ )
.find('span')
- .text(__('None'));
- })
- .catch(() => {
- $loading.addClass('gl-display-none');
- });
- }
+ .text(data.milestone.title);
+ }
+ $value.html(milestoneLinkNoneTemplate);
+ return $sidebarCollapsedValue
+ .attr('data-original-title', __('Milestone'))
+ .find('span')
+ .text(__('None'));
+ })
+ .catch(() => {
+ $loading.addClass('gl-display-none');
+ });
},
});
});
diff --git a/app/assets/javascripts/milestones/components/milestone_combobox.vue b/app/assets/javascripts/milestones/components/milestone_combobox.vue
index e8499015210..a840e696386 100644
--- a/app/assets/javascripts/milestones/components/milestone_combobox.vue
+++ b/app/assets/javascripts/milestones/components/milestone_combobox.vue
@@ -125,8 +125,7 @@ export default {
// This method is defined here instead of in `methods`
// because we need to access the .cancel() method
// lodash attaches to the function, which is
- // made inaccessible by Vue. More info:
- // https://stackoverflow.com/a/52988020/1063392
+ // made inaccessible by Vue.
this.debouncedSearch = debounce(function search() {
this.search(this.searchQuery);
}, SEARCH_DEBOUNCE_MS);
diff --git a/app/assets/javascripts/milestones/stores/mutations.js b/app/assets/javascripts/milestones/stores/mutations.js
index 3a7babf6fa0..1f88c0a1ea6 100644
--- a/app/assets/javascripts/milestones/stores/mutations.js
+++ b/app/assets/javascripts/milestones/stores/mutations.js
@@ -38,7 +38,7 @@ export default {
[types.RECEIVE_PROJECT_MILESTONES_SUCCESS](state, response) {
state.matches.projectMilestones = {
list: response.data.map(({ title }) => ({ title })),
- totalCount: parseInt(response.headers['x-total'], 10),
+ totalCount: parseInt(response.headers['x-total'], 10) || response.data.length,
error: null,
};
},
@@ -52,7 +52,7 @@ export default {
[types.RECEIVE_GROUP_MILESTONES_SUCCESS](state, response) {
state.matches.groupMilestones = {
list: response.data.map(({ title }) => ({ title })),
- totalCount: parseInt(response.headers['x-total'], 10),
+ totalCount: parseInt(response.headers['x-total'], 10) || response.data.length,
error: null,
};
},
diff --git a/app/assets/javascripts/monitoring/components/charts/empty_chart.vue b/app/assets/javascripts/monitoring/components/charts/empty_chart.vue
index 446ca8e5090..4b54cffe231 100644
--- a/app/assets/javascripts/monitoring/components/charts/empty_chart.vue
+++ b/app/assets/javascripts/monitoring/components/charts/empty_chart.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import chartEmptyStateIllustration from '@gitlab/svgs/dist/illustrations/chart-empty-state.svg';
import { chartHeight } from '../../constants';
@@ -26,7 +25,7 @@ export default {
<div
class="gl-mt-3 svg-w-100 d-flex align-items-center"
:style="svgContainerStyle"
- v-html="chartEmptyStateIllustration"
+ v-html="chartEmptyStateIllustration /* eslint-disable-line vue/no-v-html */"
></div>
<h5 class="text-center gl-mt-3">{{ __('No data to display') }}</h5>
</div>
diff --git a/app/assets/javascripts/mr_notes/index.js b/app/assets/javascripts/mr_notes/index.js
index a7696a716d0..ea3e4e5604c 100644
--- a/app/assets/javascripts/mr_notes/index.js
+++ b/app/assets/javascripts/mr_notes/index.js
@@ -19,6 +19,7 @@ export default function initMrNotes() {
action: mrShowNode.dataset.mrAction,
});
+ initDiffsApp(store);
initNotesApp();
document.addEventListener('merged:UpdateActions', () => {
@@ -26,20 +27,25 @@ export default function initMrNotes() {
initCherryPickCommitModal();
});
- // eslint-disable-next-line no-new
- new Vue({
- el: '#js-vue-discussion-counter',
- name: 'DiscussionCounter',
- components: {
- discussionCounter,
- },
- store,
- render(createElement) {
- return createElement('discussion-counter');
- },
- });
+ requestIdleCallback(() => {
+ const el = document.getElementById('js-vue-discussion-counter');
- initDiscussionFilters(store);
- initSortDiscussions(store);
- initDiffsApp(store);
+ if (el) {
+ // eslint-disable-next-line no-new
+ new Vue({
+ el,
+ name: 'DiscussionCounter',
+ components: {
+ discussionCounter,
+ },
+ store,
+ render(createElement) {
+ return createElement('discussion-counter');
+ },
+ });
+ }
+
+ initDiscussionFilters(store);
+ initSortDiscussions(store);
+ });
}
diff --git a/app/assets/javascripts/notebook/cells/markdown.vue b/app/assets/javascripts/notebook/cells/markdown.vue
index 0f4cec67ce8..1384c9c40b3 100644
--- a/app/assets/javascripts/notebook/cells/markdown.vue
+++ b/app/assets/javascripts/notebook/cells/markdown.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import katex from 'katex';
import marked from 'marked';
import { sanitize } from '~/lib/dompurify';
@@ -95,7 +94,16 @@ renderer.image = function image(href, title, text) {
const attachmentHeader = `attachment:`; // eslint-disable-line @gitlab/require-i18n-strings
if (!this.attachments || !href.startsWith(attachmentHeader)) {
- return this.originalImage(href, title, text);
+ let relativeHref = href;
+
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ if (!(href.startsWith('http') || href.startsWith('data:'))) {
+ // These are images within the repo. This will only work if the image
+ // is relative to the path where the file is located
+ relativeHref = this.relativeRawPath + href;
+ }
+
+ return this.originalImage(relativeHref, title, text);
}
let img = ``;
@@ -130,6 +138,7 @@ export default {
components: {
prompt: Prompt,
},
+ inject: ['relativeRawPath'],
props: {
cell: {
type: Object,
@@ -139,6 +148,7 @@ export default {
computed: {
markdown() {
renderer.attachments = this.cell.attachments;
+ renderer.relativeRawPath = this.relativeRawPath;
return sanitize(marked(this.cell.source.join('').replace(/\\/g, '\\\\')), markdownConfig);
},
@@ -149,7 +159,7 @@ export default {
<template>
<div class="cell text-cell">
<prompt />
- <div class="markdown" v-html="markdown"></div>
+ <div class="markdown" v-html="markdown /* eslint-disable-line vue/no-v-html */"></div>
</div>
</template>
diff --git a/app/assets/javascripts/notebook/cells/output/html.vue b/app/assets/javascripts/notebook/cells/output/html.vue
index dc5b2b66348..ca02ee18dd1 100644
--- a/app/assets/javascripts/notebook/cells/output/html.vue
+++ b/app/assets/javascripts/notebook/cells/output/html.vue
@@ -1,6 +1,5 @@
<script>
import { GlSafeHtmlDirective } from '@gitlab/ui';
-import { sanitize } from '~/lib/dompurify';
import Prompt from '../prompt.vue';
export default {
@@ -25,19 +24,19 @@ export default {
},
},
computed: {
- sanitizedOutput() {
- return sanitize(this.rawCode);
- },
showOutput() {
return this.index === 0;
},
},
+ safeHtmlConfig: {
+ ADD_TAGS: ['use'], // to support icon SVGs
+ },
};
</script>
<template>
<div class="output">
<prompt type="Out" :count="count" :show-output="showOutput" />
- <div v-safe-html="sanitizedOutput" class="gl-overflow-auto"></div>
+ <div v-safe-html:[$options.safeHtmlConfig]="rawCode" class="gl-overflow-auto"></div>
</div>
</template>
diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js
deleted file mode 100644
index ef51587734d..00000000000
--- a/app/assets/javascripts/notes.js
+++ /dev/null
@@ -1,1744 +0,0 @@
-/* eslint-disable no-restricted-properties, babel/camelcase,
-no-unused-expressions, default-case,
-consistent-return, no-alert, no-param-reassign,
-no-shadow, no-useless-escape,
-class-methods-use-this */
-
-/* global ResolveService */
-
-/*
-old_notes_spec.js is the spec for the legacy, jQuery notes application. It has nothing to do with the new, fancy Vue notes app.
- */
-
-import { GlDeprecatedSkeletonLoading as GlSkeletonLoading } from '@gitlab/ui';
-import Autosize from 'autosize';
-import $ from 'jquery';
-import Cookies from 'js-cookie';
-import { escape, uniqueId } from 'lodash';
-import Vue from 'vue';
-import '~/lib/utils/jquery_at_who';
-import AjaxCache from '~/lib/utils/ajax_cache';
-import syntaxHighlight from '~/syntax_highlight';
-import Autosave from './autosave';
-import loadAwardsHandler from './awards_handler';
-import CommentTypeToggle from './comment_type_toggle';
-import createFlash from './flash';
-import { defaultAutocompleteConfig } from './gfm_auto_complete';
-import GLForm from './gl_form';
-import axios from './lib/utils/axios_utils';
-import {
- isInViewport,
- getPagePath,
- scrollToElement,
- isMetaKey,
- isInMRPage,
-} from './lib/utils/common_utils';
-import { localTimeAgo } from './lib/utils/datetime_utility';
-import { getLocationHash } from './lib/utils/url_utility';
-import { sprintf, s__, __ } from './locale';
-import TaskList from './task_list';
-
-window.autosize = Autosize;
-
-function normalizeNewlines(str) {
- return str.replace(/\r\n/g, '\n');
-}
-
-const MAX_VISIBLE_COMMIT_LIST_COUNT = 3;
-const REGEX_QUICK_ACTIONS = /^\/\w+.*$/gm;
-
-export default class Notes {
- static initialize(notes_url, note_ids, last_fetched_at, view, enableGFM) {
- if (!this.instance) {
- this.instance = new Notes(notes_url, note_ids, last_fetched_at, view, enableGFM);
- }
- }
-
- static getInstance() {
- return this.instance;
- }
-
- constructor(notes_url, note_ids, last_fetched_at, view, enableGFM = defaultAutocompleteConfig) {
- this.updateTargetButtons = this.updateTargetButtons.bind(this);
- this.updateComment = this.updateComment.bind(this);
- this.visibilityChange = this.visibilityChange.bind(this);
- this.cancelDiscussionForm = this.cancelDiscussionForm.bind(this);
- this.onAddDiffNote = this.onAddDiffNote.bind(this);
- this.onAddImageDiffNote = this.onAddImageDiffNote.bind(this);
- this.setupDiscussionNoteForm = this.setupDiscussionNoteForm.bind(this);
- this.onReplyToDiscussionNote = this.onReplyToDiscussionNote.bind(this);
- this.removeNote = this.removeNote.bind(this);
- this.cancelEdit = this.cancelEdit.bind(this);
- this.updateNote = this.updateNote.bind(this);
- this.addDiscussionNote = this.addDiscussionNote.bind(this);
- this.addNoteError = this.addNoteError.bind(this);
- this.addNote = this.addNote.bind(this);
- this.resetMainTargetForm = this.resetMainTargetForm.bind(this);
- this.refresh = this.refresh.bind(this);
- this.keydownNoteText = this.keydownNoteText.bind(this);
- this.toggleCommitList = this.toggleCommitList.bind(this);
- this.postComment = this.postComment.bind(this);
- this.clearFlashWrapper = this.clearFlash.bind(this);
- this.onHashChange = this.onHashChange.bind(this);
-
- this.notes_url = notes_url;
- this.note_ids = note_ids;
- this.enableGFM = enableGFM;
- // Used to keep track of updated notes while people are editing things
- this.updatedNotesTrackingMap = {};
- this.last_fetched_at = last_fetched_at;
- this.noteable_url = document.URL;
- this.notesCountBadge ||
- (this.notesCountBadge = $('.issuable-details').find('.notes-tab .badge'));
- this.basePollingInterval = 15000;
- this.maxPollingSteps = 4;
-
- this.$wrapperEl = isInMRPage() ? $(document).find('.diffs') : $(document);
- this.cleanBinding();
- this.addBinding();
- this.setPollingInterval();
- this.setupMainTargetNoteForm(enableGFM);
- this.taskList = new TaskList({
- dataType: 'note',
- fieldName: 'note',
- selector: '.notes',
- });
- this.collapseLongCommitList();
- this.setViewType(view);
-
- // We are in the merge requests page so we need another edit form for Changes tab
- if (getPagePath(1) === 'merge_requests') {
- $('.note-edit-form').clone().addClass('mr-note-edit-form').insertAfter('.note-edit-form');
- }
-
- const hash = getLocationHash();
- const $anchor = hash && document.getElementById(hash);
-
- if ($anchor) {
- this.loadLazyDiff({ currentTarget: $anchor });
- }
- }
-
- setViewType(view) {
- this.view = Cookies.get('diff_view') || view;
- }
-
- addBinding() {
- // Edit note link
- this.$wrapperEl.on('click', '.js-note-edit', this.showEditForm.bind(this));
- this.$wrapperEl.on('click', '.note-edit-cancel', this.cancelEdit);
- // Reopen and close actions for Issue/MR combined with note form submit
- this.$wrapperEl.on('click', '.js-comment-submit-button', this.postComment);
- this.$wrapperEl.on('click', '.js-comment-save-button', this.updateComment);
- this.$wrapperEl.on('keyup input', '.js-note-text', this.updateTargetButtons);
- // resolve a discussion
- this.$wrapperEl.on('click', '.js-comment-resolve-button', this.postComment);
- // remove a note (in general)
- this.$wrapperEl.on('click', '.js-note-delete', this.removeNote);
- // delete note attachment
- this.$wrapperEl.on('click', '.js-note-attachment-delete', this.removeAttachment);
- // update the file name when an attachment is selected
- this.$wrapperEl.on('change', '.js-note-attachment-input', this.updateFormAttachment);
- // reply to diff/discussion notes
- this.$wrapperEl.on('click', '.js-discussion-reply-button', this.onReplyToDiscussionNote);
- // add diff note
- this.$wrapperEl.on('click', '.js-add-diff-note-button', this.onAddDiffNote);
- // add diff note for images
- this.$wrapperEl.on('click', '.js-add-image-diff-note-button', this.onAddImageDiffNote);
- // hide diff note form
- this.$wrapperEl.on('click', '.js-close-discussion-note-form', this.cancelDiscussionForm);
- // toggle commit list
- this.$wrapperEl.on('click', '.system-note-commit-list-toggler', this.toggleCommitList);
-
- this.$wrapperEl.on('click', '.js-toggle-lazy-diff', this.loadLazyDiff);
- this.$wrapperEl.on(
- 'click',
- '.js-toggle-lazy-diff-retry-button',
- this.onClickRetryLazyLoad.bind(this),
- );
-
- // fetch notes when tab becomes visible
- this.$wrapperEl.on('visibilitychange', this.visibilityChange);
- // when issue status changes, we need to refresh data
- this.$wrapperEl.on('issuable:change', this.refresh);
- // ajax:events that happen on Form when actions like Reopen, Close are performed on Issues and MRs.
- this.$wrapperEl.on('ajax:success', '.js-main-target-form', this.addNote);
- this.$wrapperEl.on('ajax:success', '.js-discussion-note-form', this.addDiscussionNote);
- this.$wrapperEl.on('ajax:success', '.js-main-target-form', this.resetMainTargetForm);
- this.$wrapperEl.on(
- 'ajax:complete',
- '.js-main-target-form',
- this.reenableTargetFormSubmitButton,
- );
- // when a key is clicked on the notes
- this.$wrapperEl.on('keydown', '.js-note-text', this.keydownNoteText);
- // When the URL fragment/hash has changed, `#note_xxx`
- $(window).on('hashchange', this.onHashChange);
- }
-
- cleanBinding() {
- this.$wrapperEl.off('click', '.js-note-edit');
- this.$wrapperEl.off('click', '.note-edit-cancel');
- this.$wrapperEl.off('click', '.js-note-delete');
- this.$wrapperEl.off('click', '.js-note-attachment-delete');
- this.$wrapperEl.off('click', '.js-discussion-reply-button');
- this.$wrapperEl.off('click', '.js-add-diff-note-button');
- this.$wrapperEl.off('click', '.js-add-image-diff-note-button');
- // eslint-disable-next-line @gitlab/no-global-event-off
- this.$wrapperEl.off('visibilitychange');
- this.$wrapperEl.off('keyup input', '.js-note-text');
- this.$wrapperEl.off('click', '.js-note-target-reopen');
- this.$wrapperEl.off('click', '.js-note-target-close');
- this.$wrapperEl.off('keydown', '.js-note-text');
- this.$wrapperEl.off('click', '.js-comment-resolve-button');
- this.$wrapperEl.off('click', '.system-note-commit-list-toggler');
- this.$wrapperEl.off('click', '.js-toggle-lazy-diff');
- this.$wrapperEl.off('click', '.js-toggle-lazy-diff-retry-button');
- this.$wrapperEl.off('ajax:success', '.js-main-target-form');
- this.$wrapperEl.off('ajax:success', '.js-discussion-note-form');
- this.$wrapperEl.off('ajax:complete', '.js-main-target-form');
- $(window).off('hashchange', this.onHashChange);
- }
-
- static initCommentTypeToggle(form) {
- const dropdownTrigger = form.querySelector('.js-comment-type-dropdown .dropdown-toggle');
- const dropdownList = form.querySelector('.js-comment-type-dropdown .dropdown-menu');
- const noteTypeInput = form.querySelector('#note_type');
- const submitButton = form.querySelector('.js-comment-type-dropdown .js-comment-submit-button');
- const closeButton = form.querySelector('.js-note-target-close');
- const reopenButton = form.querySelector('.js-note-target-reopen');
-
- const commentTypeToggle = new CommentTypeToggle({
- dropdownTrigger,
- dropdownList,
- noteTypeInput,
- submitButton,
- closeButton,
- reopenButton,
- });
-
- commentTypeToggle.initDroplab();
- }
-
- keydownNoteText(e) {
- let discussionNoteForm;
- let editNote;
- let myLastNote;
- let myLastNoteEditBtn;
- let newText;
- let originalText;
-
- if (isMetaKey(e)) {
- return;
- }
-
- const $textarea = $(e.target);
- // Edit previous note when UP arrow is hit
- switch (e.which) {
- case 38:
- if ($textarea.val() !== '') {
- return;
- }
- myLastNote = $(
- `li.note[data-author-id='${gon.current_user_id}'][data-editable]:last`,
- $textarea.closest('.note, .notes_holder, #notes'),
- );
- if (myLastNote.length) {
- myLastNoteEditBtn = myLastNote.find('.js-note-edit');
- return myLastNoteEditBtn.trigger('click', [true, myLastNote]);
- }
- break;
- // Cancel creating diff note or editing any note when ESCAPE is hit
- case 27:
- discussionNoteForm = $textarea.closest('.js-discussion-note-form');
- if (discussionNoteForm.length) {
- if ($textarea.val() !== '') {
- if (!window.confirm(__('Your comment will be discarded.'))) {
- return;
- }
- }
- this.removeDiscussionNoteForm(discussionNoteForm);
- return;
- }
- editNote = $textarea.closest('.note');
- if (editNote.length) {
- originalText = $textarea.closest('form').data('originalNote');
- newText = $textarea.val();
- if (originalText !== newText) {
- if (!window.confirm(__('Are you sure you want to discard this comment?'))) {
- return;
- }
- }
- return this.removeNoteEditForm(editNote);
- }
- }
- }
-
- initRefresh() {
- if (Notes.interval) {
- clearInterval(Notes.interval);
- }
- Notes.interval = setInterval(() => this.refresh(), this.pollingInterval);
- }
-
- refresh() {
- if (!document.hidden) {
- return this.getContent();
- }
- }
-
- getContent() {
- if (this.refreshing) {
- return;
- }
-
- this.refreshing = true;
-
- axios
- .get(`${this.notes_url}?html=true`, {
- headers: {
- 'X-Last-Fetched-At': this.last_fetched_at,
- },
- })
- .then(({ data }) => {
- const { notes } = data;
- this.last_fetched_at = data.last_fetched_at;
- this.setPollingInterval(data.notes.length);
- $.each(notes, (i, note) => this.renderNote(note));
-
- this.refreshing = false;
- })
- .catch(() => {
- this.refreshing = false;
- });
- }
-
- /**
- * Increase @pollingInterval up to 120 seconds on every function call,
- * if `shouldReset` has a truthy value, 'null' or 'undefined' the variable
- * will reset to @basePollingInterval.
- *
- * Note: this function is used to gradually increase the polling interval
- * if there aren't new notes coming from the server
- */
- setPollingInterval(shouldReset) {
- if (shouldReset == null) {
- shouldReset = true;
- }
- const nthInterval = this.basePollingInterval * Math.pow(2, this.maxPollingSteps - 1);
- if (shouldReset) {
- this.pollingInterval = this.basePollingInterval;
- } else if (this.pollingInterval < nthInterval) {
- this.pollingInterval *= 2;
- }
- return this.initRefresh();
- }
-
- handleQuickActions(noteEntity) {
- let votesBlock;
- if (noteEntity.commands_changes) {
- if ('merge' in noteEntity.commands_changes) {
- Notes.checkMergeRequestStatus();
- }
-
- if ('emoji_award' in noteEntity.commands_changes) {
- votesBlock = $('.js-awards-block').eq(0);
-
- loadAwardsHandler()
- .then((awardsHandler) => {
- awardsHandler.addAwardToEmojiBar(votesBlock, noteEntity.commands_changes.emoji_award);
- awardsHandler.scrollToAwards();
- })
- .catch(() => {
- // ignore
- });
- }
- }
- }
-
- setupNewNote($note) {
- // Update datetime format on the recent note
- localTimeAgo($note.find('.js-timeago').get(), false);
-
- this.collapseLongCommitList();
- this.taskList.init();
-
- // This stops the note highlight, #note_xxx`, from being removed after real time update
- // The `:target` selector does not re-evaluate after we replace element in the DOM
- Notes.updateNoteTargetSelector($note);
- this.$noteToCleanHighlight = $note;
- }
-
- onHashChange() {
- if (this.$noteToCleanHighlight) {
- Notes.updateNoteTargetSelector(this.$noteToCleanHighlight);
- }
-
- this.$noteToCleanHighlight = null;
- }
-
- static updateNoteTargetSelector($note) {
- const hash = getLocationHash();
- // Needs to be an explicit true/false for the jQuery `toggleClass(force)`
- const addTargetClass = Boolean(hash && $note.filter(`#${hash}`).length > 0);
- $note.toggleClass('target', addTargetClass);
- }
-
- /**
- * Render note in main comments area.
- *
- * Note: for rendering inline notes use renderDiscussionNote
- */
- renderNote(noteEntity, $form, $notesList = $('.main-notes-list')) {
- if (noteEntity.discussion_html) {
- return this.renderDiscussionNote(noteEntity, $form);
- }
-
- if (!noteEntity.valid) {
- if (noteEntity.errors && noteEntity.errors.commands_only) {
- if (noteEntity.commands_changes && Object.keys(noteEntity.commands_changes).length > 0) {
- $notesList.find('.system-note.being-posted').remove();
- }
- this.addFlash({
- message: noteEntity.errors.commands_only,
- type: 'notice',
- parent: this.parentTimeline.get(0),
- });
- this.refresh();
- }
- return;
- }
-
- const $note = $notesList.find(`#note_${noteEntity.id}`);
- if (Notes.isNewNote(noteEntity, this.note_ids)) {
- if (isInMRPage()) {
- return;
- }
-
- this.note_ids.push(noteEntity.id);
-
- if ($notesList.length) {
- $notesList.find('.system-note.being-posted').remove();
- }
- const $newNote = Notes.animateAppendNote(noteEntity.html, $notesList);
-
- this.setupNewNote($newNote);
- this.refresh();
- return this.updateNotesCount(1);
- } else if (Notes.isUpdatedNote(noteEntity, $note)) {
- // The server can send the same update multiple times so we need to make sure to only update once per actual update.
- const isEditing = $note.hasClass('is-editing');
- const initialContent = normalizeNewlines($note.find('.original-note-content').text().trim());
- const $textarea = $note.find('.js-note-text');
- const currentContent = $textarea.val();
- // There can be CRLF vs LF mismatches if we don't sanitize and compare the same way
- const sanitizedNoteNote = normalizeNewlines(noteEntity.note);
- const isTextareaUntouched =
- currentContent === initialContent || currentContent === sanitizedNoteNote;
-
- if (isEditing && isTextareaUntouched) {
- $textarea.val(noteEntity.note);
- this.updatedNotesTrackingMap[noteEntity.id] = noteEntity;
- } else if (isEditing && !isTextareaUntouched) {
- this.putConflictEditWarningInPlace(noteEntity, $note);
- this.updatedNotesTrackingMap[noteEntity.id] = noteEntity;
- } else {
- const $updatedNote = Notes.animateUpdateNote(noteEntity.html, $note);
- this.setupNewNote($updatedNote);
- }
- }
- }
-
- isParallelView() {
- return Cookies.get('diff_view') === 'parallel';
- }
-
- /**
- * Render note in discussion area. To render inline notes use renderDiscussionNote.
- */
- renderDiscussionNote(noteEntity, $form) {
- let discussionContainer;
- let row;
-
- if (!Notes.isNewNote(noteEntity, this.note_ids)) {
- return;
- }
- this.note_ids.push(noteEntity.id);
-
- const form =
- $form || $(`.js-discussion-note-form[data-discussion-id="${noteEntity.discussion_id}"]`);
- row =
- form.length || !noteEntity.discussion_line_code
- ? form.closest('tr')
- : $(`#${noteEntity.discussion_line_code}`);
-
- if (noteEntity.on_image) {
- row = form;
- }
-
- // is this the first note of discussion?
- discussionContainer = $(`.notes[data-discussion-id="${noteEntity.discussion_id}"]`);
- if (!discussionContainer.length) {
- discussionContainer = form.closest('.discussion').find('.notes');
- }
- if (discussionContainer.length === 0) {
- if (noteEntity.diff_discussion_html) {
- const $discussion = $(noteEntity.diff_discussion_html).renderGFM();
-
- if (!this.isParallelView() || row.hasClass('js-temp-notes-holder') || noteEntity.on_image) {
- // insert the note and the reply button after the temp row
- row.after($discussion);
- } else {
- // Merge new discussion HTML in
- const $notes = $discussion.find(
- `.notes[data-discussion-id="${noteEntity.discussion_id}"]`,
- );
- const contentContainerClass = $notes
- .closest('.notes-content')
- .attr('class')
- .split(' ')
- .join('.');
-
- row
- .find(`.${contentContainerClass} .content`)
- .append($notes.closest('.content').children());
- }
- } else {
- Notes.animateAppendNote(noteEntity.discussion_html, $('.main-notes-list'));
- }
- } else {
- // append new note to all matching discussions
- Notes.animateAppendNote(noteEntity.html, discussionContainer);
- }
-
- localTimeAgo(document.querySelectorAll('.js-timeago'), false);
- Notes.checkMergeRequestStatus();
- return this.updateNotesCount(1);
- }
-
- getLineHolder(changesDiscussionContainer) {
- return $(changesDiscussionContainer)
- .closest('.notes_holder')
- .prevAll('.line_holder')
- .first()
- .get(0);
- }
-
- /**
- * Called in response the main target form has been successfully submitted.
- *
- * Removes any errors.
- * Resets text and preview.
- * Resets buttons.
- */
- resetMainTargetForm(e) {
- const form = $('.js-main-target-form');
- // remove validation errors
- form.find('.js-errors').remove();
- // reset text and preview
- form.find('.js-md-write-button').click();
- form.find('.js-note-text').val('').trigger('input');
- form.find('.js-note-text').data('autosave').reset();
-
- const event = document.createEvent('Event');
- event.initEvent('autosize:update', true, false);
- form.find('.js-autosize')[0].dispatchEvent(event);
-
- this.updateTargetButtons(e);
- }
-
- reenableTargetFormSubmitButton() {
- const form = $('.js-main-target-form');
- return form.find('.js-note-text').trigger('input');
- }
-
- /**
- * Shows the main form and does some setup on it.
- *
- * Sets some hidden fields in the form.
- */
- setupMainTargetNoteForm(enableGFM) {
- // find the form
- const form = $('.js-new-note-form');
- // Set a global clone of the form for later cloning
- this.formClone = form.clone();
- // show the form
- this.setupNoteForm(form, enableGFM);
- // fix classes
- form.removeClass('js-new-note-form');
- form.addClass('js-main-target-form');
- form.find('#note_line_code').remove();
- form.find('#note_position').remove();
- form.find('#note_type').val('');
- form.find('#note_project_id').remove();
- form.find('#in_reply_to_discussion_id').remove();
- this.parentTimeline = form.parents('.timeline');
-
- if (form.length) {
- Notes.initCommentTypeToggle(form.get(0));
- }
- }
-
- /**
- * General note form setup.
- *
- * deactivates the submit button when text is empty
- * hides the preview button when text is empty
- * set up GFM auto complete
- * show the form
- */
- setupNoteForm(form, enableGFM = defaultAutocompleteConfig) {
- this.glForm = new GLForm(form, enableGFM);
- const textarea = form.find('.js-note-text');
- const key = [
- s__('NoteForm|Note'),
- form.find('#note_noteable_type').val(),
- form.find('#note_noteable_id').val(),
- form.find('#note_commit_id').val(),
- form.find('#note_type').val(),
- form.find('#note_project_id').val(),
- form.find('#in_reply_to_discussion_id').val(),
-
- // LegacyDiffNote
- form.find('#note_line_code').val(),
-
- // DiffNote
- form.find('#note_position').val(),
- ];
- return new Autosave(textarea, key);
- }
-
- /**
- * Called in response to the new note form being submitted
- *
- * Adds new note to list.
- */
- addNote($form, note) {
- return this.renderNote(note);
- }
-
- addNoteError($form) {
- let formParentTimeline;
- if ($form.hasClass('js-main-target-form')) {
- formParentTimeline = $form.parents('.timeline');
- } else if ($form.hasClass('js-discussion-note-form')) {
- formParentTimeline = $form.closest('.discussion-notes').find('.notes');
- }
- return this.addFlash({
- message: __(
- 'Your comment could not be submitted! Please check your network connection and try again.',
- ),
- parent: formParentTimeline.get(0),
- });
- }
-
- updateNoteError() {
- createFlash({
- message: __(
- 'Your comment could not be updated! Please check your network connection and try again.',
- ),
- });
- }
-
- /**
- * Called in response to the new note form being submitted
- *
- * Adds new note to list.
- */
- addDiscussionNote($form, note, isNewDiffComment) {
- if ($form.attr('data-resolve-all') != null) {
- const discussionId = $form.data('discussionId');
- const mergeRequestId = $form.data('noteableIid');
-
- if (ResolveService != null) {
- ResolveService.toggleResolveForDiscussion(mergeRequestId, discussionId);
- }
- }
-
- this.renderNote(note, $form);
- // cleanup after successfully creating a diff/discussion note
- if (isNewDiffComment) {
- this.removeDiscussionNoteForm($form);
- }
- }
-
- /**
- * Called in response to the edit note form being submitted
- *
- * Updates the current note field.
- */
- updateNote(noteEntity, $targetNote) {
- // Convert returned HTML to a jQuery object so we can modify it further
- const $noteEntityEl = $(noteEntity.html);
- this.revertNoteEditForm($targetNote);
- $noteEntityEl.renderGFM();
- // Find the note's `li` element by ID and replace it with the updated HTML
- const $note_li = $(`.note-row-${noteEntity.id}`);
-
- $note_li.replaceWith($noteEntityEl);
- this.setupNewNote($noteEntityEl);
- }
-
- checkContentToAllowEditing($el) {
- const initialContent = $el.find('.original-note-content').text().trim();
- const currentContent = $el.find('.js-note-text').val();
- let isAllowed = true;
-
- if (currentContent === initialContent) {
- this.removeNoteEditForm($el);
- } else {
- const isWidgetVisible = isInViewport($el.get(0));
-
- if (!isWidgetVisible) {
- scrollToElement($el);
- }
-
- $el.find('.js-finish-edit-warning').show();
- isAllowed = false;
- }
-
- return isAllowed;
- }
-
- /**
- * Called in response to clicking the edit note link
- *
- * Replaces the note text with the note edit form
- * Adds a data attribute to the form with the original content of the note for cancellations
- */
- showEditForm(e) {
- e.preventDefault();
-
- const $target = $(e.target);
- const $editForm = $(this.getEditFormSelector($target));
- const $note = $target.closest('.note');
- const $currentlyEditing = $('.note.is-editing:visible');
-
- if ($currentlyEditing.length) {
- const isEditAllowed = this.checkContentToAllowEditing($currentlyEditing);
-
- if (!isEditAllowed) {
- return;
- }
- }
-
- $note.find('.js-note-attachment-delete').show();
- $editForm.addClass('current-note-edit-form');
- $note.addClass('is-editing');
- this.putEditFormInPlace($target);
- }
-
- /**
- * Called in response to clicking the edit note link
- *
- * Hides edit form and restores the original note text to the editor textarea.
- */
- cancelEdit(e) {
- e.preventDefault();
- const $target = $(e.target);
- const $note = $target.closest('.note');
- const noteId = $note.attr('data-note-id');
-
- this.revertNoteEditForm($target);
-
- if (this.updatedNotesTrackingMap[noteId]) {
- const $newNote = $(this.updatedNotesTrackingMap[noteId].html);
- $note.replaceWith($newNote);
- this.setupNewNote($newNote);
- // Now that we have taken care of the update, clear it out
- delete this.updatedNotesTrackingMap[noteId];
- } else {
- $note.find('.js-finish-edit-warning').hide();
- this.removeNoteEditForm($note);
- }
- }
-
- revertNoteEditForm($target) {
- $target = $target || $('.note.is-editing:visible');
- const selector = this.getEditFormSelector($target);
- const $editForm = $(selector);
-
- $editForm.insertBefore('.diffs');
- $editForm.find('.js-comment-save-button').enable();
- $editForm.find('.js-finish-edit-warning').hide();
- }
-
- getEditFormSelector($el) {
- let selector = '.note-edit-form:not(.mr-note-edit-form)';
-
- if ($el.parents('#diffs').length) {
- selector = '.note-edit-form.mr-note-edit-form';
- }
-
- return selector;
- }
-
- removeNoteEditForm($note) {
- const form = $note.find('.diffs .current-note-edit-form');
-
- $note.removeClass('is-editing');
- form.removeClass('current-note-edit-form');
- form.find('.js-finish-edit-warning').hide();
- // Replace markdown textarea text with original note text.
- return form.find('.js-note-text').val(form.find('form.edit-note').data('originalNote'));
- }
-
- /**
- * Called in response to deleting a note of any kind.
- *
- * Removes the actual note from view.
- * Removes the whole discussion if the last note is being removed.
- */
- removeNote(e) {
- const $note = $(e.currentTarget).closest('.note');
- const noteElId = $note.attr('id');
- $(`.note[id="${noteElId}"]`).each((i, el) => {
- // A same note appears in the "Discussion" and in the "Changes" tab, we have
- // to remove all. Using $('.note[id='noteId']') ensure we get all the notes,
- // where $('#noteId') would return only one.
- const $note = $(el);
- const $notes = $note.closest('.discussion-notes');
- const discussionId = $('.notes', $notes).data('discussionId');
-
- $note.remove();
-
- // check if this is the last note for this line
- if ($notes.find('.note').length === 0) {
- const notesTr = $notes.closest('tr');
-
- // "Discussions" tab
- $notes.closest('.timeline-entry').remove();
-
- $(`.js-diff-avatars-${discussionId}`).trigger('remove.vue');
-
- // The notes tr can contain multiple lists of notes, like on the parallel diff
- // notesTr does not exist for image diffs
- if (notesTr.find('.discussion-notes').length > 1 || notesTr.length === 0) {
- const $diffFile = $notes.closest('.diff-file');
- if ($diffFile.length > 0) {
- const removeBadgeEvent = new CustomEvent('removeBadge.imageDiff', {
- detail: {
- // badgeNumber's start with 1 and index starts with 0
- badgeNumber: $notes.index() + 1,
- },
- });
-
- $diffFile[0].dispatchEvent(removeBadgeEvent);
- }
-
- $notes.remove();
- } else if (notesTr.length > 0) {
- notesTr.remove();
- }
- }
- });
-
- Notes.checkMergeRequestStatus();
- return this.updateNotesCount(-1);
- }
-
- /**
- * Called in response to clicking the delete attachment link
- *
- * Removes the attachment wrapper view, including image tag if it exists
- * Resets the note editing form
- */
- removeAttachment() {
- const $note = $(this).closest('.note');
- $note.find('.note-attachment').remove();
- $note.find('.note-body > .note-text').show();
- $note.find('.note-header').show();
- return $note.find('.diffs .current-note-edit-form').remove();
- }
-
- /**
- * Called when clicking on the "reply" button for a diff line.
- *
- * Shows the note form below the notes.
- */
- onReplyToDiscussionNote(e) {
- this.replyToDiscussionNote(e.target);
- }
-
- replyToDiscussionNote(target) {
- const form = this.cleanForm(this.formClone.clone());
- const replyLink = $(target).closest('.js-discussion-reply-button');
- // insert the form after the button
- replyLink.closest('.discussion-reply-holder').hide().after(form);
- // show the form
- return this.setupDiscussionNoteForm(replyLink, form);
- }
-
- /**
- * Shows the diff or discussion form and does some setup on it.
- *
- * Sets some hidden fields in the form.
- *
- * Note: dataHolder must have the "discussionId" and "lineCode" data attributes set.
- */
- setupDiscussionNoteForm(dataHolder, form) {
- // set up note target
- let diffFileData = dataHolder.closest('.text-file');
-
- if (diffFileData.length === 0) {
- diffFileData = dataHolder.closest('.image');
- }
-
- const discussionID = dataHolder.data('discussionId');
-
- if (discussionID) {
- form.attr('data-discussion-id', discussionID);
- form.find('#in_reply_to_discussion_id').val(discussionID);
- }
-
- form.find('#note_project_id').val(dataHolder.data('discussionProjectId'));
-
- form.attr('data-line-code', dataHolder.data('lineCode'));
- form.find('#line_type').val(dataHolder.data('lineType'));
-
- form.find('#note_noteable_type').val(diffFileData.data('noteableType'));
- form.find('#note_noteable_id').val(diffFileData.data('noteableId'));
- form.find('#note_commit_id').val(diffFileData.data('commitId'));
-
- form.find('#note_type').val(dataHolder.data('noteType'));
-
- // LegacyDiffNote
- form.find('#note_line_code').val(dataHolder.data('lineCode'));
-
- // DiffNote
- form.find('#note_position').val(dataHolder.attr('data-position'));
-
- form.append('</div>').find('.js-close-discussion-note-form').show().removeClass('hide');
- form.find('.js-note-target-close').remove();
- form.find('.js-note-new-discussion').remove();
- this.setupNoteForm(form);
-
- form.removeClass('js-main-target-form').addClass('discussion-form js-discussion-note-form');
-
- form.find('.js-note-text').focus();
- form.find('.js-comment-resolve-button').attr('data-discussion-id', discussionID);
- }
-
- /**
- * Called when clicking on the "add a comment" button on the side of a diff line.
- *
- * Inserts a temporary row for the form below the line.
- * Sets up the form and shows it.
- */
- onAddDiffNote(e) {
- e.preventDefault();
- const link = e.currentTarget || e.target;
- const $link = $(link);
- const showReplyInput = !$link.hasClass('js-diff-comment-avatar');
- this.toggleDiffNote({
- target: $link,
- lineType: link.dataset.lineType,
- showReplyInput,
- currentUsername: gon.current_username,
- currentUserAvatar: gon.current_user_avatar_url,
- currentUserFullname: gon.current_user_fullname,
- });
- }
-
- onAddImageDiffNote(e) {
- const $link = $(e.currentTarget || e.target);
- const $diffFile = $link.closest('.diff-file');
-
- const clickEvent = new CustomEvent('click.imageDiff', {
- detail: e,
- });
-
- $diffFile[0].dispatchEvent(clickEvent);
-
- // Set up comment form
- let newForm;
- const $noteContainer = $link.closest('.diff-viewer').find('.note-container');
- const $form = $noteContainer.find('> .discussion-form');
-
- if ($form.length === 0) {
- newForm = this.cleanForm(this.formClone.clone());
- newForm.appendTo($noteContainer);
- } else {
- newForm = $form;
- }
-
- this.setupDiscussionNoteForm($link, newForm);
- }
-
- toggleDiffNote({ target, lineType, forceShow, showReplyInput = false }) {
- let addForm;
- let newForm;
- let noteForm;
- let replyButton;
- let rowCssToAdd;
- const $link = $(target);
- const row = $link.closest('tr');
- const nextRow = row.next();
- let targetRow = row;
- if (nextRow.is('.notes_holder')) {
- targetRow = nextRow;
- }
-
- const hasNotes = nextRow.is('.notes_holder');
- addForm = false;
- let lineTypeSelector = '';
- rowCssToAdd =
- '<tr class="notes_holder js-temp-notes-holder"><td class="notes-content" colspan="3"><div class="content"></div></td></tr>';
- // In parallel view, look inside the correct left/right pane
- if (this.isParallelView()) {
- lineTypeSelector = `.${lineType}`;
- rowCssToAdd =
- '<tr class="notes_holder js-temp-notes-holder"><td class="notes_line old"></td><td class="notes-content parallel old"><div class="content"></div></td><td class="notes_line new"></td><td class="notes-content parallel new"><div class="content"></div></td></tr>';
- }
- const notesContentSelector = `.notes-content${lineTypeSelector} .content`;
- let notesContent = targetRow.find(notesContentSelector);
-
- if (hasNotes && showReplyInput) {
- targetRow.show();
- notesContent = targetRow.find(notesContentSelector);
- if (notesContent.length) {
- notesContent.show();
- replyButton = notesContent.find('.js-discussion-reply-button:visible');
- if (replyButton.length) {
- this.replyToDiscussionNote(replyButton[0]);
- } else {
- // In parallel view, the form may not be present in one of the panes
- noteForm = notesContent.find('.js-discussion-note-form');
- if (noteForm.length === 0) {
- addForm = true;
- }
- }
- }
- } else if (showReplyInput) {
- // add a notes row and insert the form
- row.after(rowCssToAdd);
- targetRow = row.next();
- notesContent = targetRow.find(notesContentSelector);
- addForm = true;
- } else {
- const isCurrentlyShown = targetRow.find('.content:not(:empty)').is(':visible');
- const isForced = forceShow === true || forceShow === false;
- const showNow = forceShow === true || (!isCurrentlyShown && !isForced);
-
- targetRow.toggleClass('hide', !showNow);
- notesContent.toggleClass('hide', !showNow);
- }
-
- if (addForm) {
- newForm = this.cleanForm(this.formClone.clone());
- newForm.appendTo(notesContent);
- // show the form
- return this.setupDiscussionNoteForm($link, newForm);
- }
- }
-
- /**
- * Called in response to "cancel" on a diff note form.
- *
- * Shows the reply button again.
- * Removes the form and if necessary it's temporary row.
- */
- removeDiscussionNoteForm(form) {
- const row = form.closest('tr');
- const glForm = form.data('glForm');
- glForm.destroy();
- form.find('.js-note-text').data('autosave').reset();
- // show the reply button (will only work for replies)
- form.prev('.discussion-reply-holder').show();
- if (row.is('.js-temp-notes-holder')) {
- // remove temporary row for diff lines
- return row.remove();
- }
- // only remove the form
- return form.remove();
- }
-
- cancelDiscussionForm(e) {
- e.preventDefault();
- const $form = $(e.target).closest('.js-discussion-note-form');
- const $discussionNote = $(e.target).closest('.discussion-notes');
-
- if ($discussionNote.length === 0) {
- // Only send blur event when the discussion form
- // is not part of a discussion note
- const $diffFile = $form.closest('.diff-file');
-
- if ($diffFile.length > 0) {
- const blurEvent = new CustomEvent('blur.imageDiff', {
- detail: e,
- });
-
- $diffFile[0].dispatchEvent(blurEvent);
- }
- }
-
- return this.removeDiscussionNoteForm($form);
- }
-
- /**
- * Called after an attachment file has been selected.
- *
- * Updates the file name for the selected attachment.
- */
- updateFormAttachment() {
- const form = $(this).closest('form');
- // get only the basename
- const filename = $(this)
- .val()
- .replace(/^.*[\\\/]/, '');
- return form.find('.js-attachment-filename').text(filename);
- }
-
- /**
- * Called when the tab visibility changes
- */
- visibilityChange() {
- return this.refresh();
- }
-
- updateTargetButtons(e) {
- let closetext;
- let reopentext;
- const textarea = $(e.target);
- const form = textarea.parents('form');
- const reopenbtn = form.find('.js-note-target-reopen');
- const closebtn = form.find('.js-note-target-close');
-
- if (textarea.val().trim().length > 0) {
- reopentext = reopenbtn.attr('data-alternative-text');
- closetext = closebtn.attr('data-alternative-text');
- if (reopenbtn.text() !== reopentext) {
- reopenbtn.text(reopentext);
- }
- if (closebtn.text() !== closetext) {
- closebtn.text(closetext);
- }
- if (reopenbtn.is(':not(.btn-comment-and-reopen)')) {
- reopenbtn.addClass('btn-comment-and-reopen');
- }
- if (closebtn.is(':not(.btn-comment-and-close)')) {
- closebtn.addClass('btn-comment-and-close');
- }
- } else {
- reopentext = reopenbtn.data('originalText');
- closetext = closebtn.data('originalText');
- if (reopenbtn.text() !== reopentext) {
- reopenbtn.text(reopentext);
- }
- if (closebtn.text() !== closetext) {
- closebtn.text(closetext);
- }
- if (reopenbtn.is('.btn-comment-and-reopen')) {
- reopenbtn.removeClass('btn-comment-and-reopen');
- }
- if (closebtn.is('.btn-comment-and-close')) {
- closebtn.removeClass('btn-comment-and-close');
- }
- }
- }
-
- putEditFormInPlace($el) {
- const $editForm = $(this.getEditFormSelector($el));
- const $note = $el.closest('.note');
-
- $editForm.insertAfter($note.find('.note-text'));
-
- const $originalContentEl = $note.find('.original-note-content');
- const originalContent = $originalContentEl.text().trim();
- const postUrl = $originalContentEl.data('postUrl');
- const targetId = $originalContentEl.data('targetId');
- const targetType = $originalContentEl.data('targetType');
-
- this.glForm = new GLForm($editForm.find('form'), this.enableGFM);
-
- $editForm.find('form').attr('action', `${postUrl}?html=true`).attr('data-remote', 'true');
- $editForm.find('.js-form-target-id').val(targetId);
- $editForm.find('.js-form-target-type').val(targetType);
- $editForm.find('.js-note-text').focus().val(originalContent);
- $editForm.find('.js-md-write-button').trigger('click');
- $editForm.find('.referenced-users').hide();
- }
-
- putConflictEditWarningInPlace(noteEntity, $note) {
- if ($note.find('.js-conflict-edit-warning').length === 0) {
- const open_link = `<a href="#note_${noteEntity.id}" target="_blank" rel="noopener noreferrer">`;
- const $alert = $(`<div class="js-conflict-edit-warning alert alert-danger">
- ${sprintf(
- s__(
- 'Notes|This comment has changed since you started editing, please review the %{open_link}updated comment%{close_link} to ensure information is not lost',
- ),
- {
- open_link,
- close_link: '</a>',
- },
- )}
- </div>`);
- $alert.insertAfter($note.find('.note-text'));
- }
- }
-
- updateNotesCount(updateCount) {
- return this.notesCountBadge.text(parseInt(this.notesCountBadge.text(), 10) + updateCount);
- }
-
- static renderPlaceholderComponent($container) {
- const el = $container.find('.js-code-placeholder').get(0);
- // eslint-disable-next-line no-new
- new Vue({
- el,
- components: {
- GlSkeletonLoading,
- },
- render(createElement) {
- return createElement('gl-skeleton-loading');
- },
- });
- }
-
- static renderDiffContent($container, data) {
- const { discussion_html } = data;
- const lines = $(discussion_html).find('.line_holder');
- lines.addClass('fade-in');
- $container.find('.diff-content > table > tbody').prepend(lines);
- const fileHolder = $container.find('.file-holder');
- $container.find('.line-holder-placeholder').remove();
- syntaxHighlight(fileHolder);
- }
-
- onClickRetryLazyLoad(e) {
- const $retryButton = $(e.currentTarget);
-
- $retryButton.prop('disabled', true);
-
- return this.loadLazyDiff(e).then(() => {
- $retryButton.prop('disabled', false);
- });
- }
-
- loadLazyDiff(e) {
- const $container = $(e.currentTarget).closest('.js-toggle-container');
- Notes.renderPlaceholderComponent($container);
-
- $container.find('.js-toggle-lazy-diff').removeClass('js-toggle-lazy-diff');
-
- const $tableEl = $container.find('tbody');
- if ($tableEl.length === 0) return;
-
- const fileHolder = $container.find('.file-holder');
- const url = fileHolder.data('linesPath');
-
- const $errorContainer = $container.find('.js-error-lazy-load-diff');
- const $successContainer = $container.find('.js-success-lazy-load');
-
- /**
- * We only fetch resolved discussions.
- * Unresolved discussions don't have an endpoint being provided.
- */
- if (url) {
- return axios
- .get(url)
- .then(({ data }) => {
- // Reset state in case last request returned error
- $successContainer.removeClass('hidden');
- $errorContainer.addClass('hidden');
-
- Notes.renderDiffContent($container, data);
- })
- .catch(() => {
- $successContainer.addClass('hidden');
- $errorContainer.removeClass('hidden');
- });
- }
- return Promise.resolve();
- }
-
- toggleCommitList(e) {
- const $element = $(e.currentTarget);
- const $closestSystemCommitList = $element.siblings('.system-note-commit-list');
- const $svgChevronUpElement = $element.find('svg.js-chevron-up');
- const $svgChevronDownElement = $element.find('svg.js-chevron-down');
-
- $svgChevronUpElement.toggleClass('gl-display-none');
- $svgChevronDownElement.toggleClass('gl-display-none');
-
- $closestSystemCommitList.toggleClass('hide-shade');
- }
-
- /**
- * Scans system notes with `ul` elements in system note body
- * then collapse long commit list pushed by user to make it less
- * intrusive.
- */
- collapseLongCommitList() {
- const systemNotes = $('#notes-list').find('li.system-note').has('ul');
-
- $.each(systemNotes, (index, systemNote) => {
- const $systemNote = $(systemNote);
- const headerMessage = $systemNote
- .find('.note-text')
- .find('p')
- .first()
- .text()
- .replace(':', '');
-
- $systemNote.find('.note-header .system-note-message').html(headerMessage);
-
- if ($systemNote.find('li').length > MAX_VISIBLE_COMMIT_LIST_COUNT) {
- $systemNote.find('.note-text').addClass('system-note-commit-list');
- $systemNote.find('.system-note-commit-list-toggler').show();
- } else {
- $systemNote.find('.note-text').addClass('system-note-commit-list hide-shade');
- }
- });
- }
-
- addFlash(...flashParams) {
- this.flashContainer = createFlash(...flashParams);
- }
-
- clearFlash() {
- if (this.flashContainer) {
- this.flashContainer.style.display = 'none';
- this.flashContainer = null;
- }
- }
-
- cleanForm($form) {
- // Remove JS classes that are not needed here
- $form.find('.js-comment-type-dropdown').removeClass('btn-group');
-
- // Remove dropdown
- $form.find('.dropdown-menu').remove();
-
- return $form;
- }
-
- /**
- * Check if note does not exist on page
- */
- static isNewNote(noteEntity, noteIds) {
- return $.inArray(noteEntity.id, noteIds) === -1;
- }
-
- /**
- * Check if $note already contains the `noteEntity` content
- */
- static isUpdatedNote(noteEntity, $note) {
- // There can be CRLF vs LF mismatches if we don't sanitize and compare the same way
- const sanitizedNoteEntityText = normalizeNewlines(noteEntity.note.trim());
- const currentNoteText = normalizeNewlines(
- $note.find('.original-note-content').first().text().trim(),
- );
- return sanitizedNoteEntityText !== currentNoteText;
- }
-
- static checkMergeRequestStatus() {
- if (getPagePath(1) === 'merge_requests' && gl.mrWidget) {
- gl.mrWidget.checkStatus();
- }
- }
-
- static animateAppendNote(noteHtml, $notesList) {
- const $note = $(noteHtml);
-
- $note.addClass('fade-in-full').renderGFM();
- $notesList.append($note);
- return $note;
- }
-
- static animateUpdateNote(noteHtml, $note) {
- const $updatedNote = $(noteHtml);
-
- $updatedNote.addClass('fade-in').renderGFM();
- $note.replaceWith($updatedNote);
- return $updatedNote;
- }
-
- /**
- * Get data from Form attributes to use for saving/submitting comment.
- */
- getFormData($form) {
- const content = $form.find('.js-note-text').val();
- return {
- // eslint-disable-next-line no-jquery/no-serialize
- formData: $form.serialize(),
- formContent: escape(content),
- formAction: $form.attr('action'),
- formContentOriginal: content,
- };
- }
-
- /**
- * Identify if comment has any quick actions
- */
- hasQuickActions(formContent) {
- return REGEX_QUICK_ACTIONS.test(formContent);
- }
-
- /**
- * Remove quick actions and leave comment with pure message
- */
- stripQuickActions(formContent) {
- return formContent.replace(REGEX_QUICK_ACTIONS, '').trim();
- }
-
- /**
- * Gets appropriate description from quick actions found in provided `formContent`
- */
- getQuickActionDescription(formContent, availableQuickActions = []) {
- let tempFormContent;
-
- // Identify executed quick actions from `formContent`
- const executedCommands = availableQuickActions.filter((command) => {
- const commandRegex = new RegExp(`/${command.name}`);
- return commandRegex.test(formContent);
- });
-
- if (executedCommands && executedCommands.length) {
- if (executedCommands.length > 1) {
- tempFormContent = __('Applying multiple commands');
- } else {
- const commandDescription = executedCommands[0].description.toLowerCase();
- tempFormContent = sprintf(__('Applying command to %{commandDescription}'), {
- commandDescription,
- });
- }
- } else {
- tempFormContent = __('Applying command');
- }
-
- return tempFormContent;
- }
-
- /**
- * Create placeholder note DOM element populated with comment body
- * that we will show while comment is being posted.
- * Once comment is _actually_ posted on server, we will have final element
- * in response that we will show in place of this temporary element.
- */
- createPlaceholderNote({
- formContent,
- uniqueId,
- isDiscussionNote,
- currentUsername,
- currentUserFullname,
- currentUserAvatar,
- }) {
- const discussionClass = isDiscussionNote ? 'discussion' : '';
- const $tempNote = $(
- `<li id="${uniqueId}" class="note being-posted fade-in-half timeline-entry">
- <div class="timeline-entry-inner">
- <div class="timeline-icon">
- <a href="/${escape(currentUsername)}">
- <img class="avatar s40" src="${currentUserAvatar}" />
- </a>
- </div>
- <div class="timeline-content ${discussionClass}">
- <div class="note-header">
- <div class="note-header-info">
- <a href="/${escape(currentUsername)}">
- <span class="d-none d-sm-inline-block bold">${escape(currentUsername)}</span>
- <span class="note-headline-light">${escape(currentUsername)}</span>
- </a>
- </div>
- </div>
- <div class="note-body">
- <div class="note-text">
- <p>${formContent}</p>
- </div>
- </div>
- </div>
- </div>
- </li>`,
- );
-
- $tempNote.find('.d-none.d-sm-inline-block').text(escape(currentUserFullname));
- $tempNote.find('.note-headline-light').text(`@${escape(currentUsername)}`);
-
- return $tempNote;
- }
-
- /**
- * Create Placeholder System Note DOM element populated with quick action description
- */
- createPlaceholderSystemNote({ formContent, uniqueId }) {
- const $tempNote = $(
- `<li id="${uniqueId}" class="note system-note timeline-entry being-posted fade-in-half">
- <div class="timeline-entry-inner">
- <div class="timeline-content">
- <i>${formContent}</i>
- </div>
- </div>
- </li>`,
- );
-
- return $tempNote;
- }
-
- /**
- * This method does following tasks step-by-step whenever a new comment
- * is submitted by user (both main thread comments as well as discussion comments).
- *
- * 1) Get Form metadata
- * 2) Identify comment type; a) Main thread b) Discussion thread c) Discussion resolve
- * 3) Build temporary placeholder element (using `createPlaceholderNote`)
- * 4) Show placeholder note on UI
- * 5) Perform network request to submit the note using `axios.post`
- * a) If request is successfully completed
- * 1. Remove placeholder element
- * 2. Show submitted Note element
- * 3. Perform post-submit errands
- * a. Mark discussion as resolved if comment submission was for resolve.
- * b. Reset comment form to original state.
- * b) If request failed
- * 1. Remove placeholder element
- * 2. Show error Flash message about failure
- */
- postComment(e) {
- e.preventDefault();
-
- // Get Form metadata
- const $submitBtn = $(e.target);
- $submitBtn.prop('disabled', true);
- let $form = $submitBtn.parents('form');
- const $closeBtn = $form.find('.js-note-target-close');
- const isDiscussionNote =
- $submitBtn.parent().find('li.droplab-item-selected').attr('id') === 'discussion';
- const isMainForm = $form.hasClass('js-main-target-form');
- const isDiscussionForm = $form.hasClass('js-discussion-note-form');
- const isDiscussionResolve = $submitBtn.hasClass('js-comment-resolve-button');
- const { formData, formContent, formAction, formContentOriginal } = this.getFormData($form);
- let noteUniqueId;
- let systemNoteUniqueId;
- let hasQuickActions = false;
- let $notesContainer;
- let tempFormContent;
-
- // Get reference to notes container based on type of comment
- if (isDiscussionForm) {
- $notesContainer = $form.parent('.discussion-notes').find('.notes');
- } else if (isMainForm) {
- $notesContainer = $('ul.main-notes-list');
- }
-
- // If comment is to resolve discussion, disable submit buttons while
- // comment posting is finished.
- if (isDiscussionResolve) {
- $form.find('.js-comment-submit-button').disable();
- }
-
- tempFormContent = formContent;
- if (this.glForm.supportsQuickActions && this.hasQuickActions(formContent)) {
- tempFormContent = this.stripQuickActions(formContent);
- hasQuickActions = true;
- }
-
- // Show placeholder note
- if (tempFormContent) {
- noteUniqueId = uniqueId('tempNote_');
- $notesContainer.append(
- this.createPlaceholderNote({
- formContent: tempFormContent,
- uniqueId: noteUniqueId,
- isDiscussionNote,
- currentUsername: gon.current_username,
- currentUserFullname: gon.current_user_fullname,
- currentUserAvatar: gon.current_user_avatar_url,
- }),
- );
- }
-
- // Show placeholder system note
- if (hasQuickActions) {
- systemNoteUniqueId = uniqueId('tempSystemNote_');
- $notesContainer.append(
- this.createPlaceholderSystemNote({
- formContent: this.getQuickActionDescription(
- formContent,
- AjaxCache.get(gl.GfmAutoComplete.dataSources.commands),
- ),
- uniqueId: systemNoteUniqueId,
- }),
- );
- }
-
- // Clear the form textarea
- if ($notesContainer.length) {
- if (isMainForm) {
- this.resetMainTargetForm(e);
- } else if (isDiscussionForm) {
- this.removeDiscussionNoteForm($form);
- }
- }
-
- $closeBtn.text($closeBtn.data('originalText'));
-
- // Make request to submit comment on server
- return axios
- .post(`${formAction}?html=true`, formData)
- .then((res) => {
- const note = res.data;
-
- $submitBtn.prop('disabled', false);
- // Submission successful! remove placeholder
- $notesContainer.find(`#${noteUniqueId}`).remove();
-
- const $diffFile = $form.closest('.diff-file');
- if ($diffFile.length > 0) {
- const blurEvent = new CustomEvent('blur.imageDiff', {
- detail: e,
- });
-
- $diffFile[0].dispatchEvent(blurEvent);
- }
-
- // Reset cached commands list when command is applied
- if (hasQuickActions) {
- $form.find('textarea.js-note-text').trigger('clear-commands-cache.atwho');
- }
-
- // Clear previous form errors
- this.clearFlashWrapper();
-
- // Check if this was discussion comment
- if (isDiscussionForm) {
- // Remove flash-container
- $notesContainer.find('.flash-container').remove();
-
- // If comment intends to resolve discussion, do the same.
- if (isDiscussionResolve) {
- $form
- .attr('data-discussion-id', $submitBtn.data('discussionId'))
- .attr('data-resolve-all', 'true')
- .attr('data-project-path', $submitBtn.data('projectPath'));
- }
-
- // Show final note element on UI
- const isNewDiffComment = $notesContainer.length === 0;
- this.addDiscussionNote($form, note, isNewDiffComment);
-
- if (isNewDiffComment) {
- // Add image badge, avatar badge and toggle discussion badge for new image diffs
- const notePosition = $form.find('#note_position').val();
- if ($diffFile.length > 0 && notePosition.length > 0) {
- const { x, y, width, height } = JSON.parse(notePosition);
- const addBadgeEvent = new CustomEvent('addBadge.imageDiff', {
- detail: {
- x,
- y,
- width,
- height,
- noteId: `note_${note.id}`,
- discussionId: note.discussion_id,
- },
- });
-
- $diffFile[0].dispatchEvent(addBadgeEvent);
- }
- }
-
- // append flash-container to the Notes list
- if ($notesContainer.length) {
- $notesContainer.append('<div class="flash-container" style="display: none;"></div>');
- }
- } else if (isMainForm) {
- // Check if this was main thread comment
- // Show final note element on UI and perform form and action buttons cleanup
- this.addNote($form, note);
- this.reenableTargetFormSubmitButton(e);
- }
-
- if (note.commands_changes) {
- this.handleQuickActions(note);
- }
-
- $form.trigger('ajax:success', [note]);
- })
- .catch(() => {
- // Submission failed, remove placeholder note and show Flash error message
- $notesContainer.find(`#${noteUniqueId}`).remove();
- $submitBtn.prop('disabled', false);
- const blurEvent = new CustomEvent('blur.imageDiff', {
- detail: e,
- });
-
- const closestDiffFile = $form.closest('.diff-file');
-
- if (closestDiffFile.length) {
- closestDiffFile[0].dispatchEvent(blurEvent);
- }
-
- if (hasQuickActions) {
- $notesContainer.find(`#${systemNoteUniqueId}`).remove();
- }
-
- // Show form again on UI on failure
- if (isDiscussionForm && $notesContainer.length) {
- const replyButton = $notesContainer.parent().find('.js-discussion-reply-button');
- this.replyToDiscussionNote(replyButton[0]);
- $form = $notesContainer.parent().find('form');
- }
-
- $form.find('.js-note-text').val(formContentOriginal);
- this.reenableTargetFormSubmitButton(e);
- this.addNoteError($form);
- });
- }
-
- /**
- * This method does following tasks step-by-step whenever an existing comment
- * is updated by user (both main thread comments as well as discussion comments).
- *
- * 1) Get Form metadata
- * 2) Update note element with new content
- * 3) Perform network request to submit the updated note using `axios.post`
- * a) If request is successfully completed
- * 1. Show submitted Note element
- * b) If request failed
- * 1. Revert Note element to original content
- * 2. Show error Flash message about failure
- */
- updateComment(e) {
- e.preventDefault();
-
- // Get Form metadata
- const $submitBtn = $(e.target);
- const $form = $submitBtn.parents('form');
- const $closeBtn = $form.find('.js-note-target-close');
- const $editingNote = $form.parents('.note.is-editing');
- const $noteBody = $editingNote.find('.js-task-list-container');
- const $noteBodyText = $noteBody.find('.note-text');
- const { formData, formContent, formAction } = this.getFormData($form);
-
- // Cache original comment content
- const cachedNoteBodyText = $noteBodyText.html();
-
- // Show updated comment content temporarily
- $noteBodyText.html(formContent);
- $editingNote.removeClass('is-editing fade-in-full').addClass('being-posted fade-in-half');
- $editingNote
- .find('.note-headline-meta a')
- .html('<span class="spinner align-text-bottom"></span>');
-
- // Make request to update comment on server
- axios
- .post(`${formAction}?html=true`, formData)
- .then(({ data }) => {
- // Submission successful! render final note element
- this.updateNote(data, $editingNote);
- })
- .catch(() => {
- // Submission failed, revert back to original note
- $noteBodyText.html(escape(cachedNoteBodyText));
- $editingNote.removeClass('being-posted fade-in');
- $editingNote.find('.gl-spinner').remove();
-
- // Show Flash message about failure
- this.updateNoteError();
- });
-
- return $closeBtn.text($closeBtn.data('originalText'));
- }
-}
-
-window.Notes = Notes;
diff --git a/app/assets/javascripts/notes/components/comment_form.vue b/app/assets/javascripts/notes/components/comment_form.vue
index 2ebebd76e1e..4e31fdcd4f0 100644
--- a/app/assets/javascripts/notes/components/comment_form.vue
+++ b/app/assets/javascripts/notes/components/comment_form.vue
@@ -1,14 +1,5 @@
<script>
-import {
- GlAlert,
- GlButton,
- GlIcon,
- GlFormCheckbox,
- GlTooltipDirective,
- GlDropdown,
- GlDropdownItem,
- GlDropdownDivider,
-} from '@gitlab/ui';
+import { GlAlert, GlButton, GlIcon, GlFormCheckbox, GlTooltipDirective } from '@gitlab/ui';
import Autosize from 'autosize';
import $ from 'jquery';
import { mapActions, mapGetters, mapState } from 'vuex';
@@ -34,6 +25,7 @@ import { COMMENT_FORM } from '../i18n';
import issuableStateMixin from '../mixins/issuable_state';
import CommentFieldLayout from './comment_field_layout.vue';
+import CommentTypeDropdown from './comment_type_dropdown.vue';
import discussionLockedWidget from './discussion_locked_widget.vue';
import noteSignedOutWidget from './note_signed_out_widget.vue';
@@ -42,8 +34,6 @@ const { UNPROCESSABLE_ENTITY } = httpStatusCodes;
export default {
name: 'CommentForm',
i18n: COMMENT_FORM,
- noteTypeComment: constants.COMMENT,
- noteTypeDiscussion: constants.DISCUSSION,
components: {
noteSignedOutWidget,
discussionLockedWidget,
@@ -53,10 +43,8 @@ export default {
TimelineEntryItem,
GlIcon,
CommentFieldLayout,
+ CommentTypeDropdown,
GlFormCheckbox,
- GlDropdown,
- GlDropdownItem,
- GlDropdownDivider,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -88,12 +76,6 @@ export default {
'hasDrafts',
]),
...mapState(['isToggleStateButtonLoading']),
- isNoteTypeComment() {
- return this.noteType === constants.COMMENT;
- },
- isNoteTypeDiscussion() {
- return this.noteType === constants.DISCUSSION;
- },
noteableDisplayName() {
return splitCamelCase(this.noteableType).toLowerCase();
},
@@ -105,15 +87,8 @@ export default {
? this.$options.i18n.comment
: this.$options.i18n.startThread;
},
- startDiscussionDescription() {
- return this.getNoteableData.noteableType === constants.MERGE_REQUEST_NOTEABLE_TYPE
- ? this.$options.i18n.discussionThatNeedsResolution
- : this.$options.i18n.discussion;
- },
- commentDescription() {
- return sprintf(this.$options.i18n.submitButton.commentHelp, {
- noteableDisplayName: this.noteableDisplayName,
- });
+ discussionsRequireResolution() {
+ return this.getNoteableData.noteableType === constants.MERGE_REQUEST_NOTEABLE_TYPE;
},
isOpen() {
return this.openState === constants.OPENED || this.openState === constants.REOPENED;
@@ -314,15 +289,6 @@ export default {
this.autosave.reset();
},
- setNoteType(type) {
- this.noteType = type;
- },
- setNoteTypeToComment() {
- this.setNoteType(constants.COMMENT);
- },
- setNoteTypeToDiscussion() {
- this.setNoteType(constants.DISCUSSION);
- },
editCurrentUserLastNote() {
if (this.note === '') {
const lastNote = this.getCurrentUserLastNote;
@@ -448,40 +414,15 @@ export default {
class="gl-text-gray-500"
/>
</gl-form-checkbox>
- <gl-dropdown
- split
- :text="commentButtonTitle"
- class="gl-mr-3 js-comment-button js-comment-submit-button comment-type-dropdown"
- category="primary"
- variant="confirm"
+ <comment-type-dropdown
+ v-model="noteType"
+ class="gl-mr-3"
:disabled="disableSubmitButton"
- data-testid="comment-button"
- data-qa-selector="comment_button"
- :data-track-label="trackingLabel"
- data-track-event="click_button"
- @click="handleSave()"
- >
- <gl-dropdown-item
- is-check-item
- :is-checked="isNoteTypeComment"
- :selected="isNoteTypeComment"
- @click="setNoteTypeToComment"
- >
- <strong>{{ $options.i18n.submitButton.comment }}</strong>
- <p class="gl-m-0">{{ commentDescription }}</p>
- </gl-dropdown-item>
- <gl-dropdown-divider />
- <gl-dropdown-item
- is-check-item
- :is-checked="isNoteTypeDiscussion"
- :selected="isNoteTypeDiscussion"
- data-qa-selector="discussion_menu_item"
- @click="setNoteTypeToDiscussion"
- >
- <strong>{{ $options.i18n.submitButton.startThread }}</strong>
- <p class="gl-m-0">{{ startDiscussionDescription }}</p>
- </gl-dropdown-item>
- </gl-dropdown>
+ :tracking-label="trackingLabel"
+ :noteable-display-name="noteableDisplayName"
+ :discussions-require-resolution="discussionsRequireResolution"
+ @click="handleSave"
+ />
</template>
<gl-button
v-if="canToggleIssueState"
diff --git a/app/assets/javascripts/notes/components/comment_type_dropdown.vue b/app/assets/javascripts/notes/components/comment_type_dropdown.vue
new file mode 100644
index 00000000000..663a912999d
--- /dev/null
+++ b/app/assets/javascripts/notes/components/comment_type_dropdown.vue
@@ -0,0 +1,114 @@
+<script>
+import { GlDropdown, GlDropdownItem, GlDropdownDivider } from '@gitlab/ui';
+
+import { sprintf } from '~/locale';
+import { COMMENT_FORM } from '~/notes/i18n';
+import * as constants from '../constants';
+
+export default {
+ i18n: COMMENT_FORM,
+ components: {
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownDivider,
+ },
+ model: {
+ prop: 'noteType',
+ event: 'change',
+ },
+ props: {
+ disabled: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ trackingLabel: {
+ type: String,
+ required: false,
+ default: undefined,
+ },
+ discussionsRequireResolution: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ noteableDisplayName: {
+ type: String,
+ required: true,
+ },
+ noteType: {
+ type: String,
+ required: true,
+ },
+ },
+ computed: {
+ isNoteTypeComment() {
+ return this.noteType === constants.COMMENT;
+ },
+ isNoteTypeDiscussion() {
+ return this.noteType === constants.DISCUSSION;
+ },
+ commentButtonTitle() {
+ return this.noteType === constants.COMMENT
+ ? this.$options.i18n.comment
+ : this.$options.i18n.startThread;
+ },
+ startDiscussionDescription() {
+ return this.discussionsRequireResolution
+ ? this.$options.i18n.discussionThatNeedsResolution
+ : this.$options.i18n.discussion;
+ },
+ commentDescription() {
+ return sprintf(this.$options.i18n.submitButton.commentHelp, {
+ noteableDisplayName: this.noteableDisplayName,
+ });
+ },
+ },
+ methods: {
+ handleClick() {
+ this.$emit('click');
+ },
+ setNoteTypeToComment() {
+ if (this.noteType !== constants.COMMENT) {
+ this.$emit('change', constants.COMMENT);
+ }
+ },
+ setNoteTypeToDiscussion() {
+ if (this.noteType !== constants.DISCUSSION) {
+ this.$emit('change', constants.DISCUSSION);
+ }
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-dropdown
+ split
+ :text="commentButtonTitle"
+ class="gl-mr-3 js-comment-button js-comment-submit-button comment-type-dropdown"
+ category="primary"
+ variant="confirm"
+ :disabled="disabled"
+ data-testid="comment-button"
+ data-qa-selector="comment_button"
+ :data-track-label="trackingLabel"
+ data-track-action="click_button"
+ @click="$emit('click')"
+ >
+ <gl-dropdown-item is-check-item :is-checked="isNoteTypeComment" @click="setNoteTypeToComment">
+ <strong>{{ $options.i18n.submitButton.comment }}</strong>
+ <p class="gl-m-0">{{ commentDescription }}</p>
+ </gl-dropdown-item>
+ <gl-dropdown-divider />
+ <gl-dropdown-item
+ is-check-item
+ :is-checked="isNoteTypeDiscussion"
+ data-qa-selector="discussion_menu_item"
+ @click="setNoteTypeToDiscussion"
+ >
+ <strong>{{ $options.i18n.submitButton.startThread }}</strong>
+ <p class="gl-m-0">{{ startDiscussionDescription }}</p>
+ </gl-dropdown-item>
+ </gl-dropdown>
+</template>
diff --git a/app/assets/javascripts/notes/components/diff_with_note.vue b/app/assets/javascripts/notes/components/diff_with_note.vue
index e96e1204f76..b04aa74d46e 100644
--- a/app/assets/javascripts/notes/components/diff_with_note.vue
+++ b/app/assets/javascripts/notes/components/diff_with_note.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { GlDeprecatedSkeletonLoading as GlSkeletonLoading } from '@gitlab/ui';
import { mapState, mapActions } from 'vuex';
import DiffFileHeader from '~/diffs/components/diff_file_header.vue';
@@ -93,7 +92,11 @@ export default {
>
<td :class="line.type" class="diff-line-num old_line">{{ line.old_line }}</td>
<td :class="line.type" class="diff-line-num new_line">{{ line.new_line }}</td>
- <td :class="line.type" class="line_content" v-html="trimChar(line.rich_text)"></td>
+ <td
+ :class="line.type"
+ class="line_content"
+ v-html="trimChar(line.rich_text) /* eslint-disable-line vue/no-v-html */"
+ ></td>
</tr>
</template>
<tr v-if="!hasTruncatedDiffLines" class="line_holder line-holder-placeholder">
diff --git a/app/assets/javascripts/notes/components/discussion_counter.vue b/app/assets/javascripts/notes/components/discussion_counter.vue
index 55cf75132a9..831e6dd8f92 100644
--- a/app/assets/javascripts/notes/components/discussion_counter.vue
+++ b/app/assets/javascripts/notes/components/discussion_counter.vue
@@ -78,8 +78,8 @@ export default {
v-if="resolveAllDiscussionsIssuePath && !allResolved"
v-gl-tooltip
:href="resolveAllDiscussionsIssuePath"
- :title="s__('Resolve all threads in new issue')"
- :aria-label="s__('Resolve all threads in new issue')"
+ :title="s__('Create issue to resolve all threads')"
+ :aria-label="s__('Create issue to resolve all threads')"
class="new-issue-for-discussion discussion-create-issue-btn"
icon="issue-new"
/>
@@ -89,7 +89,7 @@ export default {
:title="__('Jump to next unresolved thread')"
:aria-label="__('Jump to next unresolved thread')"
class="discussion-next-btn"
- data-track-event="click_button"
+ data-track-action="click_button"
data-track-label="mr_next_unresolved_thread"
data-track-property="click_next_unresolved_thread_top"
icon="comment-next"
diff --git a/app/assets/javascripts/notes/components/discussion_resolve_with_issue_button.vue b/app/assets/javascripts/notes/components/discussion_resolve_with_issue_button.vue
index 9119d319d72..4ccba011014 100644
--- a/app/assets/javascripts/notes/components/discussion_resolve_with_issue_button.vue
+++ b/app/assets/javascripts/notes/components/discussion_resolve_with_issue_button.vue
@@ -4,7 +4,7 @@ import { s__ } from '~/locale';
export default {
i18n: {
- buttonLabel: s__('MergeRequests|Resolve this thread in a new issue'),
+ buttonLabel: s__('MergeRequests|Create issue to resolve thread'),
},
name: 'ResolveWithIssueButton',
components: {
diff --git a/app/assets/javascripts/notes/components/note_actions/reply_button.vue b/app/assets/javascripts/notes/components/note_actions/reply_button.vue
index 0cd2afcf8a0..8c8cc7984b1 100644
--- a/app/assets/javascripts/notes/components/note_actions/reply_button.vue
+++ b/app/assets/javascripts/notes/components/note_actions/reply_button.vue
@@ -19,7 +19,7 @@ export default {
<template>
<gl-button
v-gl-tooltip
- data-track-event="click_button"
+ data-track-action="click_button"
data-track-label="reply_comment_button"
category="tertiary"
icon="comment"
diff --git a/app/assets/javascripts/notes/components/note_body.vue b/app/assets/javascripts/notes/components/note_body.vue
index 9864e91c009..93f71276120 100644
--- a/app/assets/javascripts/notes/components/note_body.vue
+++ b/app/assets/javascripts/notes/components/note_body.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import $ from 'jquery';
import { escape } from 'lodash';
import { mapActions, mapGetters, mapState } from 'vuex';
@@ -163,7 +162,11 @@ export default {
@addToBatch="addSuggestionToBatch"
@removeFromBatch="removeSuggestionFromBatch"
/>
- <div v-else class="note-text md" v-html="note.note_html"></div>
+ <div
+ v-else
+ class="note-text md"
+ v-html="note.note_html /* eslint-disable-line vue/no-v-html */"
+ ></div>
<note-form
v-if="isEditing"
ref="noteForm"
diff --git a/app/assets/javascripts/notes/components/note_form.vue b/app/assets/javascripts/notes/components/note_form.vue
index f2336e1b6f5..a4f06a8d9f5 100644
--- a/app/assets/javascripts/notes/components/note_form.vue
+++ b/app/assets/javascripts/notes/components/note_form.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { GlButton } from '@gitlab/ui';
import { mapGetters, mapActions, mapState } from 'vuex';
import { getDraft, updateDraft } from '~/lib/utils/autosave';
@@ -322,7 +321,7 @@ export default {
<div
v-if="conflictWhileEditing"
class="js-conflict-edit-warning alert alert-danger"
- v-html="changedCommentText"
+ v-html="changedCommentText /* eslint-disable-line vue/no-v-html */"
></div>
<div class="flash-container timeline-content"></div>
<form :data-line-code="lineCode" class="edit-note common-note-form js-quick-submit gfm-form">
diff --git a/app/assets/javascripts/notes/components/note_header.vue b/app/assets/javascripts/notes/components/note_header.vue
index 1a4a6c137a6..4e686ce8719 100644
--- a/app/assets/javascripts/notes/components/note_header.vue
+++ b/app/assets/javascripts/notes/components/note_header.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { GlIcon, GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui';
import { mapActions } from 'vuex';
import timeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
@@ -169,7 +168,7 @@ export default {
v-on="
authorStatusHasTooltip ? { mouseenter: removeEmojiTitle, mouseleave: addEmojiTitle } : {}
"
- v-html="authorStatus"
+ v-html="authorStatus /* eslint-disable-line vue/no-v-html */"
></span>
<span class="text-nowrap author-username">
<a
diff --git a/app/assets/javascripts/notes/stores/actions.js b/app/assets/javascripts/notes/stores/actions.js
index 6a4a3263e4a..656591e0c32 100644
--- a/app/assets/javascripts/notes/stores/actions.js
+++ b/app/assets/javascripts/notes/stores/actions.js
@@ -1,3 +1,4 @@
+/* eslint-disable @gitlab/require-string-literal-i18n-helpers */
import $ from 'jquery';
import Visibility from 'visibilityjs';
import Vue from 'vue';
diff --git a/app/assets/javascripts/packages/details/components/package_history.vue b/app/assets/javascripts/packages/details/components/package_history.vue
index 0d7a73c12f1..27d2f208a42 100644
--- a/app/assets/javascripts/packages/details/components/package_history.vue
+++ b/app/assets/javascripts/packages/details/components/package_history.vue
@@ -1,4 +1,5 @@
<script>
+/* eslint-disable @gitlab/require-string-literal-i18n-helpers */
import { GlLink, GlSprintf } from '@gitlab/ui';
import { first } from 'lodash';
import { truncateSha } from '~/lib/utils/text_utility';
diff --git a/app/assets/javascripts/packages/shared/constants.js b/app/assets/javascripts/packages/shared/constants.js
index b4cdca34d92..f15c31b85c1 100644
--- a/app/assets/javascripts/packages/shared/constants.js
+++ b/app/assets/javascripts/packages/shared/constants.js
@@ -1,3 +1,4 @@
+/* eslint-disable @gitlab/require-string-literal-i18n-helpers */
import { __, s__ } from '~/locale';
export const PackageType = {
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/additional_metadata.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/additional_metadata.vue
index 4d6a1d5462b..74c0cb44c51 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/additional_metadata.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/additional_metadata.vue
@@ -1,25 +1,24 @@
<script>
-import { GlLink, GlSprintf } from '@gitlab/ui';
-import { s__ } from '~/locale';
+import Composer from '~/packages_and_registries/package_registry/components/details/metadata/composer.vue';
+import Conan from '~/packages_and_registries/package_registry/components/details/metadata/conan.vue';
+import Maven from '~/packages_and_registries/package_registry/components/details/metadata/maven.vue';
+import Nuget from '~/packages_and_registries/package_registry/components/details/metadata/nuget.vue';
+import Pypi from '~/packages_and_registries/package_registry/components/details/metadata/pypi.vue';
import {
- PACKAGE_TYPE_NUGET,
+ PACKAGE_TYPE_COMPOSER,
PACKAGE_TYPE_CONAN,
PACKAGE_TYPE_MAVEN,
+ PACKAGE_TYPE_NUGET,
+ PACKAGE_TYPE_PYPI,
} from '~/packages_and_registries/package_registry/constants';
-import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
export default {
- i18n: {
- sourceText: s__('PackageRegistry|Source project located at %{link}'),
- licenseText: s__('PackageRegistry|License information located at %{link}'),
- recipeText: s__('PackageRegistry|Recipe: %{recipe}'),
- appGroup: s__('PackageRegistry|App group: %{group}'),
- appName: s__('PackageRegistry|App name: %{name}'),
- },
components: {
- DetailsRow,
- GlLink,
- GlSprintf,
+ Composer,
+ Conan,
+ Maven,
+ Nuget,
+ Pypi,
},
props: {
packageEntity: {
@@ -28,21 +27,17 @@ export default {
},
},
computed: {
- showMetadata() {
- return (
- [PACKAGE_TYPE_NUGET, PACKAGE_TYPE_CONAN, PACKAGE_TYPE_MAVEN].includes(
- this.packageEntity.packageType,
- ) && this.packageEntity.metadata
- );
- },
- showNugetMetadata() {
- return this.packageEntity.packageType === PACKAGE_TYPE_NUGET;
+ metadataComponent() {
+ return {
+ [PACKAGE_TYPE_COMPOSER]: Composer,
+ [PACKAGE_TYPE_CONAN]: Conan,
+ [PACKAGE_TYPE_MAVEN]: Maven,
+ [PACKAGE_TYPE_NUGET]: Nuget,
+ [PACKAGE_TYPE_PYPI]: Pypi,
+ }[this.packageEntity.packageType];
},
- showConanMetadata() {
- return this.packageEntity.packageType === PACKAGE_TYPE_CONAN;
- },
- showMavenMetadata() {
- return this.packageEntity.packageType === PACKAGE_TYPE_MAVEN;
+ showMetadata() {
+ return this.metadataComponent && this.packageEntity.metadata;
},
},
};
@@ -51,56 +46,12 @@ export default {
<template>
<div v-if="showMetadata">
<h3 class="gl-font-lg" data-testid="title">{{ __('Additional Metadata') }}</h3>
-
<div class="gl-bg-gray-50 gl-inset-border-1-gray-100 gl-rounded-base" data-testid="main">
- <template v-if="showNugetMetadata">
- <details-row icon="project" padding="gl-p-4" dashed data-testid="nuget-source">
- <gl-sprintf :message="$options.i18n.sourceText">
- <template #link>
- <gl-link :href="packageEntity.metadata.projectUrl" target="_blank">{{
- packageEntity.metadata.projectUrl
- }}</gl-link>
- </template>
- </gl-sprintf>
- </details-row>
- <details-row icon="license" padding="gl-p-4" data-testid="nuget-license">
- <gl-sprintf :message="$options.i18n.licenseText">
- <template #link>
- <gl-link :href="packageEntity.metadata.licenseUrl" target="_blank">{{
- packageEntity.metadata.licenseUrl
- }}</gl-link>
- </template>
- </gl-sprintf>
- </details-row>
- </template>
-
- <details-row
- v-else-if="showConanMetadata"
- icon="information-o"
- padding="gl-p-4"
- data-testid="conan-recipe"
- >
- <gl-sprintf :message="$options.i18n.recipeText">
- <template #recipe>{{ packageEntity.metadata.recipe }}</template>
- </gl-sprintf>
- </details-row>
-
- <template v-else-if="showMavenMetadata">
- <details-row icon="information-o" padding="gl-p-4" dashed data-testid="maven-app">
- <gl-sprintf :message="$options.i18n.appName">
- <template #name>
- <strong>{{ packageEntity.metadata.appName }}</strong>
- </template>
- </gl-sprintf>
- </details-row>
- <details-row icon="information-o" padding="gl-p-4" data-testid="maven-group">
- <gl-sprintf :message="$options.i18n.appGroup">
- <template #group>
- <strong>{{ packageEntity.metadata.appGroup }}</strong>
- </template>
- </gl-sprintf>
- </details-row>
- </template>
+ <component
+ :is="metadataComponent"
+ :package-entity="packageEntity"
+ data-testid="component-is"
+ />
</div>
</div>
</template>
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/metadata/composer.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/metadata/composer.vue
new file mode 100644
index 00000000000..b6a36a0b00f
--- /dev/null
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/metadata/composer.vue
@@ -0,0 +1,55 @@
+<script>
+import { GlSprintf } from '@gitlab/ui';
+import { s__ } from '~/locale';
+import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
+import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
+
+export default {
+ i18n: {
+ targetShaCopyButton: s__('PackageRegistry|Copy target SHA'),
+ targetSha: s__('PackageRegistry|Target SHA: %{sha}'),
+ composerJson: s__(
+ 'PackageRegistry|Composer.json with license: %{license} and version: %{version}',
+ ),
+ },
+ components: {
+ DetailsRow,
+ GlSprintf,
+ ClipboardButton,
+ },
+ props: {
+ packageEntity: {
+ type: Object,
+ required: true,
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <details-row icon="information-o" padding="gl-p-4" dashed data-testid="composer-target-sha">
+ <gl-sprintf :message="$options.i18n.targetSha">
+ <template #sha>
+ <strong>{{ packageEntity.metadata.targetSha }}</strong>
+ <clipboard-button
+ :title="$options.i18n.targetShaCopyButton"
+ :text="packageEntity.metadata.targetSha"
+ category="tertiary"
+ css-class="gl-p-0!"
+ />
+ </template>
+ </gl-sprintf>
+ </details-row>
+ <details-row icon="information-o" padding="gl-p-4" data-testid="composer-json">
+ <gl-sprintf :message="$options.i18n.composerJson">
+ <template #license>
+ <strong>{{ packageEntity.metadata.composerJson.license }}</strong>
+ </template>
+ <template #version>
+ <strong>{{ packageEntity.metadata.composerJson.version }}</strong>
+ </template>
+ </gl-sprintf>
+ </details-row>
+ </div>
+</template>
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/metadata/conan.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/metadata/conan.vue
new file mode 100644
index 00000000000..10797d74acf
--- /dev/null
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/metadata/conan.vue
@@ -0,0 +1,32 @@
+<script>
+import { GlSprintf } from '@gitlab/ui';
+import { s__ } from '~/locale';
+
+import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
+
+export default {
+ i18n: {
+ recipeText: s__('PackageRegistry|Recipe: %{recipe}'),
+ },
+ components: {
+ DetailsRow,
+ GlSprintf,
+ },
+ props: {
+ packageEntity: {
+ type: Object,
+ required: true,
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <details-row icon="information-o" padding="gl-p-4" data-testid="conan-recipe">
+ <gl-sprintf :message="$options.i18n.recipeText">
+ <template #recipe>{{ packageEntity.metadata.recipe }}</template>
+ </gl-sprintf>
+ </details-row>
+ </div>
+</template>
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/metadata/maven.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/metadata/maven.vue
new file mode 100644
index 00000000000..fd9fb49a9f2
--- /dev/null
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/metadata/maven.vue
@@ -0,0 +1,42 @@
+<script>
+import { GlSprintf } from '@gitlab/ui';
+import { s__ } from '~/locale';
+
+import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
+
+export default {
+ i18n: {
+ appGroup: s__('PackageRegistry|App group: %{group}'),
+ appName: s__('PackageRegistry|App name: %{name}'),
+ },
+ components: {
+ DetailsRow,
+ GlSprintf,
+ },
+ props: {
+ packageEntity: {
+ type: Object,
+ required: true,
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <details-row icon="information-o" padding="gl-p-4" dashed data-testid="maven-app">
+ <gl-sprintf :message="$options.i18n.appName">
+ <template #name>
+ <strong>{{ packageEntity.metadata.appName }}</strong>
+ </template>
+ </gl-sprintf>
+ </details-row>
+ <details-row icon="information-o" padding="gl-p-4" data-testid="maven-group">
+ <gl-sprintf :message="$options.i18n.appGroup">
+ <template #group>
+ <strong>{{ packageEntity.metadata.appGroup }}</strong>
+ </template>
+ </gl-sprintf>
+ </details-row>
+ </div>
+</template>
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/metadata/nuget.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/metadata/nuget.vue
new file mode 100644
index 00000000000..f0da7db6c91
--- /dev/null
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/metadata/nuget.vue
@@ -0,0 +1,46 @@
+<script>
+import { GlLink, GlSprintf } from '@gitlab/ui';
+import { s__ } from '~/locale';
+import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
+
+export default {
+ i18n: {
+ sourceText: s__('PackageRegistry|Source project located at %{link}'),
+ licenseText: s__('PackageRegistry|License information located at %{link}'),
+ },
+ components: {
+ DetailsRow,
+ GlLink,
+ GlSprintf,
+ },
+ props: {
+ packageEntity: {
+ type: Object,
+ required: true,
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <details-row icon="project" padding="gl-p-4" dashed data-testid="nuget-source">
+ <gl-sprintf :message="$options.i18n.sourceText">
+ <template #link>
+ <gl-link :href="packageEntity.metadata.projectUrl" target="_blank">{{
+ packageEntity.metadata.projectUrl
+ }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </details-row>
+ <details-row icon="license" padding="gl-p-4" data-testid="nuget-license">
+ <gl-sprintf :message="$options.i18n.licenseText">
+ <template #link>
+ <gl-link :href="packageEntity.metadata.licenseUrl" target="_blank">{{
+ packageEntity.metadata.licenseUrl
+ }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </details-row>
+ </div>
+</template>
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/metadata/pypi.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/metadata/pypi.vue
new file mode 100644
index 00000000000..6534eef532c
--- /dev/null
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/metadata/pypi.vue
@@ -0,0 +1,34 @@
+<script>
+import { GlSprintf } from '@gitlab/ui';
+import { s__ } from '~/locale';
+
+import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
+
+export default {
+ i18n: {
+ requiredPython: s__('PackageRegistry|Required Python: %{pythonVersion}'),
+ },
+ components: {
+ DetailsRow,
+ GlSprintf,
+ },
+ props: {
+ packageEntity: {
+ type: Object,
+ required: true,
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <details-row icon="information-o" padding="gl-p-4" data-testid="pypi-required-python">
+ <gl-sprintf :message="$options.i18n.requiredPython">
+ <template #pythonVersion>
+ <strong>{{ packageEntity.metadata.requiredPython }}</strong>
+ </template>
+ </gl-sprintf>
+ </details-row>
+ </div>
+</template>
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_history.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_history.vue
index af4a984add4..408bd2e3dfe 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_history.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_history.vue
@@ -1,4 +1,5 @@
<script>
+/* eslint-disable @gitlab/require-string-literal-i18n-helpers */
import { GlLink, GlSprintf } from '@gitlab/ui';
import { first } from 'lodash';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue
index 65547af3913..44d7807639d 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue
@@ -1,5 +1,5 @@
<script>
-import { GlIcon, GlSprintf, GlBadge } from '@gitlab/ui';
+import { GlIcon, GlSprintf, GlBadge, GlResizeObserverDirective } from '@gitlab/ui';
import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
import { numberToHumanSize } from '~/lib/utils/number_utils';
import { __ } from '~/locale';
@@ -21,6 +21,9 @@ export default {
GlBadge,
TimeAgoTooltip,
},
+ directives: {
+ GlResizeObserver: GlResizeObserverDirective,
+ },
i18n: {
packageInfo: __('v%{version} published %{timeAgo}'),
},
@@ -60,18 +63,26 @@ export default {
},
},
mounted() {
- this.isDesktop = GlBreakpointInstance.isDesktop();
+ this.checkBreakpoints();
},
methods: {
dynamicSlotName(index) {
return `metadata-tag${index}`;
},
+ checkBreakpoints() {
+ this.isDesktop = GlBreakpointInstance.isDesktop();
+ },
},
};
</script>
<template>
- <title-area :title="packageEntity.name" :avatar="packageIcon" data-qa-selector="package_title">
+ <title-area
+ v-gl-resize-observer="checkBreakpoints"
+ :title="packageEntity.name"
+ :avatar="packageIcon"
+ data-qa-selector="package_title"
+ >
<template #sub-header>
<gl-icon name="eye" class="gl-mr-3" />
<span data-testid="sub-header">
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/list/package_search.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/list/package_search.vue
new file mode 100644
index 00000000000..280d292ce0b
--- /dev/null
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/list/package_search.vue
@@ -0,0 +1,57 @@
+<script>
+import { mapState, mapActions } from 'vuex';
+import { s__ } from '~/locale';
+import { sortableFields } from '~/packages/list/utils';
+import { OPERATOR_IS_ONLY } from '~/vue_shared/components/filtered_search_bar/constants';
+import RegistrySearch from '~/vue_shared/components/registry/registry_search.vue';
+import UrlSync from '~/vue_shared/components/url_sync.vue';
+import PackageTypeToken from './tokens/package_type_token.vue';
+
+export default {
+ tokens: [
+ {
+ type: 'type',
+ icon: 'package',
+ title: s__('PackageRegistry|Type'),
+ unique: true,
+ token: PackageTypeToken,
+ operators: OPERATOR_IS_ONLY,
+ },
+ ],
+ components: { RegistrySearch, UrlSync },
+ computed: {
+ ...mapState({
+ isGroupPage: (state) => state.config.isGroupPage,
+ sorting: (state) => state.sorting,
+ filter: (state) => state.filter,
+ }),
+ sortableFields() {
+ return sortableFields(this.isGroupPage);
+ },
+ },
+ methods: {
+ ...mapActions(['setSorting', 'setFilter']),
+ updateSorting(newValue) {
+ this.setSorting(newValue);
+ this.$emit('update');
+ },
+ },
+};
+</script>
+
+<template>
+ <url-sync>
+ <template #default="{ updateQuery }">
+ <registry-search
+ :filter="filter"
+ :sorting="sorting"
+ :tokens="$options.tokens"
+ :sortable-fields="sortableFields"
+ @sorting:changed="updateSorting"
+ @filter:changed="setFilter"
+ @filter:submit="$emit('update')"
+ @query:changed="updateQuery"
+ />
+ </template>
+ </url-sync>
+</template>
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/list/package_title.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/list/package_title.vue
new file mode 100644
index 00000000000..6e00a48586e
--- /dev/null
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/list/package_title.vue
@@ -0,0 +1,47 @@
+<script>
+import { n__ } from '~/locale';
+import { LIST_INTRO_TEXT, LIST_TITLE_TEXT } from '~/packages/list/constants';
+import MetadataItem from '~/vue_shared/components/registry/metadata_item.vue';
+import TitleArea from '~/vue_shared/components/registry/title_area.vue';
+
+export default {
+ name: 'PackageTitle',
+ components: {
+ TitleArea,
+ MetadataItem,
+ },
+ props: {
+ count: {
+ type: Number,
+ required: false,
+ default: null,
+ },
+ helpUrl: {
+ type: String,
+ required: true,
+ },
+ },
+ computed: {
+ showPackageCount() {
+ return Number.isInteger(this.count);
+ },
+ packageAmountText() {
+ return n__(`%d Package`, `%d Packages`, this.count);
+ },
+ infoMessages() {
+ return [{ text: LIST_INTRO_TEXT, link: this.helpUrl }];
+ },
+ },
+ i18n: {
+ LIST_TITLE_TEXT,
+ },
+};
+</script>
+
+<template>
+ <title-area :title="$options.i18n.LIST_TITLE_TEXT" :info-messages="infoMessages">
+ <template #metadata-amount>
+ <metadata-item v-if="showPackageCount" icon="package" :text="packageAmountText" />
+ </template>
+ </title-area>
+</template>
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/list/packages_list.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/list/packages_list.vue
new file mode 100644
index 00000000000..25bac687dbf
--- /dev/null
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/list/packages_list.vue
@@ -0,0 +1,129 @@
+<script>
+import { GlPagination, GlModal, GlSprintf } from '@gitlab/ui';
+import { mapState, mapGetters } from 'vuex';
+import { s__ } from '~/locale';
+import PackagesListRow from '~/packages/shared/components/package_list_row.vue';
+import PackagesListLoader from '~/packages/shared/components/packages_list_loader.vue';
+import { TrackingActions } from '~/packages/shared/constants';
+import { packageTypeToTrackCategory } from '~/packages/shared/utils';
+import Tracking from '~/tracking';
+
+export default {
+ components: {
+ GlPagination,
+ GlModal,
+ GlSprintf,
+ PackagesListLoader,
+ PackagesListRow,
+ },
+ mixins: [Tracking.mixin()],
+ data() {
+ return {
+ itemToBeDeleted: null,
+ };
+ },
+ computed: {
+ ...mapState({
+ perPage: (state) => state.pagination.perPage,
+ totalItems: (state) => state.pagination.total,
+ page: (state) => state.pagination.page,
+ isGroupPage: (state) => state.config.isGroupPage,
+ isLoading: 'isLoading',
+ }),
+ ...mapGetters({ list: 'getList' }),
+ currentPage: {
+ get() {
+ return this.page;
+ },
+ set(value) {
+ this.$emit('page:changed', value);
+ },
+ },
+ isListEmpty() {
+ return !this.list || this.list.length === 0;
+ },
+ modalAction() {
+ return s__('PackageRegistry|Delete package');
+ },
+ deletePackageName() {
+ return this.itemToBeDeleted?.name ?? '';
+ },
+ tracking() {
+ const category = this.itemToBeDeleted
+ ? packageTypeToTrackCategory(this.itemToBeDeleted.package_type)
+ : undefined;
+ return {
+ category,
+ };
+ },
+ },
+ methods: {
+ setItemToBeDeleted(item) {
+ this.itemToBeDeleted = { ...item };
+ this.track(TrackingActions.REQUEST_DELETE_PACKAGE);
+ this.$refs.packageListDeleteModal.show();
+ },
+ deleteItemConfirmation() {
+ this.$emit('package:delete', this.itemToBeDeleted);
+ this.track(TrackingActions.DELETE_PACKAGE);
+ this.itemToBeDeleted = null;
+ },
+ deleteItemCanceled() {
+ this.track(TrackingActions.CANCEL_DELETE_PACKAGE);
+ this.itemToBeDeleted = null;
+ },
+ },
+ i18n: {
+ deleteModalContent: s__(
+ 'PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?',
+ ),
+ },
+};
+</script>
+
+<template>
+ <div class="gl-display-flex gl-flex-direction-column">
+ <slot v-if="isListEmpty && !isLoading" name="empty-state"></slot>
+
+ <div v-else-if="isLoading">
+ <packages-list-loader />
+ </div>
+
+ <template v-else>
+ <div data-qa-selector="packages-table">
+ <packages-list-row
+ v-for="packageEntity in list"
+ :key="packageEntity.id"
+ :package-entity="packageEntity"
+ :package-link="packageEntity._links.web_path"
+ :is-group="isGroupPage"
+ @packageToDelete="setItemToBeDeleted"
+ />
+ </div>
+
+ <gl-pagination
+ v-model="currentPage"
+ :per-page="perPage"
+ :total-items="totalItems"
+ align="center"
+ class="gl-w-full gl-mt-3"
+ />
+
+ <gl-modal
+ ref="packageListDeleteModal"
+ modal-id="confirm-delete-pacakge"
+ ok-variant="danger"
+ @ok="deleteItemConfirmation"
+ @cancel="deleteItemCanceled"
+ >
+ <template #modal-title>{{ modalAction }}</template>
+ <template #modal-ok>{{ modalAction }}</template>
+ <gl-sprintf :message="$options.i18n.deleteModalContent">
+ <template #name>
+ <strong>{{ deletePackageName }}</strong>
+ </template>
+ </gl-sprintf>
+ </gl-modal>
+ </template>
+ </div>
+</template>
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/list/packages_list_app.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/list/packages_list_app.vue
new file mode 100644
index 00000000000..75fbdb80192
--- /dev/null
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/list/packages_list_app.vue
@@ -0,0 +1,132 @@
+<script>
+import { GlEmptyState, GlLink, GlSprintf } from '@gitlab/ui';
+import { mapActions, mapState } from 'vuex';
+import createFlash from '~/flash';
+import { historyReplaceState } from '~/lib/utils/common_utils';
+import { s__ } from '~/locale';
+import { DELETE_PACKAGE_SUCCESS_MESSAGE } from '~/packages/list/constants';
+import { SHOW_DELETE_SUCCESS_ALERT } from '~/packages/shared/constants';
+import { FILTERED_SEARCH_TERM } from '~/packages_and_registries/shared/constants';
+import { getQueryParams, extractFilterAndSorting } from '~/packages_and_registries/shared/utils';
+import PackageList from './packages_list.vue';
+
+export default {
+ components: {
+ GlEmptyState,
+ GlLink,
+ GlSprintf,
+ PackageList,
+ PackageTitle: () =>
+ import(/* webpackChunkName: 'package_registry_components' */ './package_title.vue'),
+ PackageSearch: () =>
+ import(/* webpackChunkName: 'package_registry_components' */ './package_search.vue'),
+ InfrastructureTitle: () =>
+ import(
+ /* webpackChunkName: 'infrastructure_registry_components' */ '~/packages_and_registries/infrastructure_registry/components/infrastructure_title.vue'
+ ),
+ InfrastructureSearch: () =>
+ import(
+ /* webpackChunkName: 'infrastructure_registry_components' */ '~/packages_and_registries/infrastructure_registry/components/infrastructure_search.vue'
+ ),
+ },
+ inject: {
+ titleComponent: {
+ from: 'titleComponent',
+ default: 'PackageTitle',
+ },
+ searchComponent: {
+ from: 'searchComponent',
+ default: 'PackageSearch',
+ },
+ emptyPageTitle: {
+ from: 'emptyPageTitle',
+ default: s__('PackageRegistry|There are no packages yet'),
+ },
+ noResultsText: {
+ from: 'noResultsText',
+ default: s__(
+ 'PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab.',
+ ),
+ },
+ },
+ computed: {
+ ...mapState({
+ emptyListIllustration: (state) => state.config.emptyListIllustration,
+ emptyListHelpUrl: (state) => state.config.emptyListHelpUrl,
+ filter: (state) => state.filter,
+ selectedType: (state) => state.selectedType,
+ packageHelpUrl: (state) => state.config.packageHelpUrl,
+ packagesCount: (state) => state.pagination?.total,
+ }),
+ emptySearch() {
+ return (
+ this.filter.filter((f) => f.type !== FILTERED_SEARCH_TERM || f.value?.data).length === 0
+ );
+ },
+
+ emptyStateTitle() {
+ return this.emptySearch
+ ? this.emptyPageTitle
+ : s__('PackageRegistry|Sorry, your filter produced no results');
+ },
+ },
+ mounted() {
+ const queryParams = getQueryParams(window.document.location.search);
+ const { sorting, filters } = extractFilterAndSorting(queryParams);
+ this.setSorting(sorting);
+ this.setFilter(filters);
+ this.requestPackagesList();
+ this.checkDeleteAlert();
+ },
+ methods: {
+ ...mapActions([
+ 'requestPackagesList',
+ 'requestDeletePackage',
+ 'setSelectedType',
+ 'setSorting',
+ 'setFilter',
+ ]),
+ onPageChanged(page) {
+ return this.requestPackagesList({ page });
+ },
+ onPackageDeleteRequest(item) {
+ return this.requestDeletePackage(item);
+ },
+ checkDeleteAlert() {
+ const urlParams = new URLSearchParams(window.location.search);
+ const showAlert = urlParams.get(SHOW_DELETE_SUCCESS_ALERT);
+ if (showAlert) {
+ // to be refactored to use gl-alert
+ createFlash({ message: DELETE_PACKAGE_SUCCESS_MESSAGE, type: 'notice' });
+ const cleanUrl = window.location.href.split('?')[0];
+ historyReplaceState(cleanUrl);
+ }
+ },
+ },
+ i18n: {
+ widenFilters: s__('PackageRegistry|To widen your search, change or remove the filters above.'),
+ },
+};
+</script>
+
+<template>
+ <div>
+ <component :is="titleComponent" :help-url="packageHelpUrl" :count="packagesCount" />
+ <component :is="searchComponent" @update="requestPackagesList" />
+
+ <package-list @page:changed="onPageChanged" @package:delete="onPackageDeleteRequest">
+ <template #empty-state>
+ <gl-empty-state :title="emptyStateTitle" :svg-path="emptyListIllustration">
+ <template #description>
+ <gl-sprintf v-if="!emptySearch" :message="$options.i18n.widenFilters" />
+ <gl-sprintf v-else :message="noResultsText">
+ <template #noPackagesLink="{ content }">
+ <gl-link :href="emptyListHelpUrl" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </template>
+ </gl-empty-state>
+ </template>
+ </package-list>
+ </div>
+</template>
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/list/tokens/package_type_token.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/list/tokens/package_type_token.vue
new file mode 100644
index 00000000000..529a7893dfc
--- /dev/null
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/list/tokens/package_type_token.vue
@@ -0,0 +1,26 @@
+<script>
+import { GlFilteredSearchToken, GlFilteredSearchSuggestion } from '@gitlab/ui';
+import { PACKAGE_TYPES } from '~/packages/list/constants';
+
+export default {
+ components: {
+ GlFilteredSearchToken,
+ GlFilteredSearchSuggestion,
+ },
+ PACKAGE_TYPES,
+};
+</script>
+
+<template>
+ <gl-filtered-search-token v-bind="{ ...$attrs }" v-on="$listeners">
+ <template #suggestions>
+ <gl-filtered-search-suggestion
+ v-for="(type, index) in $options.PACKAGE_TYPES"
+ :key="index"
+ :value="type.type"
+ >
+ {{ type.title }}
+ </gl-filtered-search-suggestion>
+ </template>
+ </gl-filtered-search-token>
+</template>
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/constants.js b/app/assets/javascripts/packages_and_registries/package_registry/constants.js
index aad888b4433..f023b4481a0 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/constants.js
+++ b/app/assets/javascripts/packages_and_registries/package_registry/constants.js
@@ -1,3 +1,4 @@
+/* eslint-disable @gitlab/require-string-literal-i18n-helpers */
import { __, s__ } from '~/locale';
export const PACKAGE_TYPE_CONAN = 'CONAN';
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/pages/list.js b/app/assets/javascripts/packages_and_registries/package_registry/pages/list.js
new file mode 100644
index 00000000000..1e01b75aabc
--- /dev/null
+++ b/app/assets/javascripts/packages_and_registries/package_registry/pages/list.js
@@ -0,0 +1,16 @@
+import Vue from 'vue';
+import Translate from '~/vue_shared/translate';
+import PackagesListApp from '../components/list/packages_list_app.vue';
+
+Vue.use(Translate);
+
+export default () => {
+ const el = document.getElementById('js-vue-packages-list');
+
+ return new Vue({
+ el,
+ render(createElement) {
+ return createElement(PackagesListApp);
+ },
+ });
+};
diff --git a/app/assets/javascripts/packages_and_registries/settings/project/components/registry_settings_app.vue b/app/assets/javascripts/packages_and_registries/settings/project/components/registry_settings_app.vue
index 6da2e3a47e8..bf286c84d5f 100644
--- a/app/assets/javascripts/packages_and_registries/settings/project/components/registry_settings_app.vue
+++ b/app/assets/javascripts/packages_and_registries/settings/project/components/registry_settings_app.vue
@@ -88,7 +88,7 @@ export default {
<template>
<section data-testid="registry-settings-app">
<cleanup-policy-enabled-alert v-if="showCleanupPolicyOnAlert" :project-path="projectPath" />
- <settings-block default-expanded>
+ <settings-block :collapsible="false">
<template #title> {{ __('Clean up image tags') }}</template>
<template #description>
<span data-testid="description">
diff --git a/app/assets/javascripts/pages/dashboard/projects/index/components/customize_homepage_banner.vue b/app/assets/javascripts/pages/dashboard/projects/index/components/customize_homepage_banner.vue
index d17c37e9e1a..99461475af0 100644
--- a/app/assets/javascripts/pages/dashboard/projects/index/components/customize_homepage_banner.vue
+++ b/app/assets/javascripts/pages/dashboard/projects/index/components/customize_homepage_banner.vue
@@ -77,7 +77,7 @@ export default {
);
if (button) {
- button.setAttribute('data-track-event', 'click_go_to_preferences');
+ button.setAttribute('data-track-action', 'click_go_to_preferences');
button.setAttribute('data-track-label', this.trackLabel);
}
},
diff --git a/app/assets/javascripts/pages/groups/issues/index.js b/app/assets/javascripts/pages/groups/issues/index.js
index 342c054471d..8c9f23732aa 100644
--- a/app/assets/javascripts/pages/groups/issues/index.js
+++ b/app/assets/javascripts/pages/groups/issues/index.js
@@ -1,26 +1,30 @@
import IssuableFilteredSearchTokenKeys from 'ee_else_ce/filtered_search/issuable_filtered_search_token_keys';
import issuableInitBulkUpdateSidebar from '~/issuable_bulk_update_sidebar/issuable_init_bulk_update_sidebar';
-import { mountIssuablesListApp } from '~/issues_list';
+import { mountIssuablesListApp, mountIssuesListApp } from '~/issues_list';
import initManualOrdering from '~/manual_ordering';
import { FILTERED_SEARCH } from '~/pages/constants';
import initFilteredSearch from '~/pages/search/init_filtered_search';
import projectSelect from '~/project_select';
-const ISSUE_BULK_UPDATE_PREFIX = 'issue_';
+if (gon.features?.vueIssuesList) {
+ mountIssuesListApp();
+} else {
+ const ISSUE_BULK_UPDATE_PREFIX = 'issue_';
-IssuableFilteredSearchTokenKeys.addExtraTokensForIssues();
-IssuableFilteredSearchTokenKeys.removeTokensForKeys('release');
-issuableInitBulkUpdateSidebar.init(ISSUE_BULK_UPDATE_PREFIX);
+ IssuableFilteredSearchTokenKeys.addExtraTokensForIssues();
+ IssuableFilteredSearchTokenKeys.removeTokensForKeys('release');
+ issuableInitBulkUpdateSidebar.init(ISSUE_BULK_UPDATE_PREFIX);
-initFilteredSearch({
- page: FILTERED_SEARCH.ISSUES,
- isGroupDecendent: true,
- useDefaultState: true,
- filteredSearchTokenKeys: IssuableFilteredSearchTokenKeys,
-});
-projectSelect();
-initManualOrdering();
+ initFilteredSearch({
+ page: FILTERED_SEARCH.ISSUES,
+ isGroupDecendent: true,
+ useDefaultState: true,
+ filteredSearchTokenKeys: IssuableFilteredSearchTokenKeys,
+ });
+ projectSelect();
+ initManualOrdering();
-if (gon.features?.vueIssuablesList) {
- mountIssuablesListApp();
+ if (gon.features?.vueIssuablesList) {
+ mountIssuablesListApp();
+ }
}
diff --git a/app/assets/javascripts/pages/groups/new/index.js b/app/assets/javascripts/pages/groups/new/index.js
index 7557edb1b49..7b0418e1ad5 100644
--- a/app/assets/javascripts/pages/groups/new/index.js
+++ b/app/assets/javascripts/pages/groups/new/index.js
@@ -5,6 +5,7 @@ import Group from '~/group';
import { parseBoolean } from '~/lib/utils/common_utils';
import NewGroupCreationApp from './components/app.vue';
import GroupPathValidator from './group_path_validator';
+import initToggleInviteMembers from './toggle_invite_members';
new GroupPathValidator(); // eslint-disable-line no-new
@@ -31,3 +32,5 @@ function initNewGroupCreation(el) {
const el = document.querySelector('.js-new-group-creation');
initNewGroupCreation(el);
+
+initToggleInviteMembers();
diff --git a/app/assets/javascripts/pages/groups/new/toggle_invite_members.js b/app/assets/javascripts/pages/groups/new/toggle_invite_members.js
new file mode 100644
index 00000000000..ffb4964cf7d
--- /dev/null
+++ b/app/assets/javascripts/pages/groups/new/toggle_invite_members.js
@@ -0,0 +1,14 @@
+import { parseBoolean } from '~/lib/utils/common_utils';
+
+export default function initToggleInviteMembers() {
+ const inviteMembersSection = document.querySelector('.js-invite-members-section');
+ const setupForCompanyRadios = document.querySelectorAll('input[name="group[setup_for_company]"]');
+
+ if (inviteMembersSection && setupForCompanyRadios.length) {
+ setupForCompanyRadios.forEach((el) => {
+ el.addEventListener('change', (event) => {
+ inviteMembersSection.classList.toggle('hidden', !parseBoolean(event.target.value));
+ });
+ });
+ }
+}
diff --git a/app/assets/javascripts/pages/projects/blob/show/index.js b/app/assets/javascripts/pages/projects/blob/show/index.js
index b365e039191..80bcbefab46 100644
--- a/app/assets/javascripts/pages/projects/blob/show/index.js
+++ b/app/assets/javascripts/pages/projects/blob/show/index.js
@@ -14,7 +14,7 @@ import '~/sourcegraph/load';
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
- defaultClient: createDefaultClient(),
+ defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
});
const viewBlobEl = document.querySelector('#js-view-blob-app');
diff --git a/app/assets/javascripts/pages/projects/commit/show/index.js b/app/assets/javascripts/pages/projects/commit/show/index.js
index e3b30560fef..c6a76df7bde 100644
--- a/app/assets/javascripts/pages/projects/commit/show/index.js
+++ b/app/assets/javascripts/pages/projects/commit/show/index.js
@@ -4,8 +4,8 @@ import loadAwardsHandler from '~/awards_handler';
import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import Diff from '~/diff';
import createFlash from '~/flash';
-import initChangesDropdown from '~/init_changes_dropdown';
-import initNotes from '~/init_notes';
+import initDeprecatedNotes from '~/init_deprecated_notes';
+import { initDiffStatsDropdown } from '~/init_diff_stats_dropdown';
import axios from '~/lib/utils/axios_utils';
import { handleLocationHash } from '~/lib/utils/common_utils';
import { __ } from '~/locale';
@@ -17,13 +17,13 @@ import '~/sourcegraph/load';
const hasPerfBar = document.querySelector('.with-performance-bar');
const performanceHeight = hasPerfBar ? 35 : 0;
-initChangesDropdown(document.querySelector('.navbar-gitlab').offsetHeight + performanceHeight);
+initDiffStatsDropdown(document.querySelector('.navbar-gitlab').offsetHeight + performanceHeight);
new ZenMode();
new ShortcutsNavigation();
initCommitBoxInfo();
-initNotes();
+initDeprecatedNotes();
const filesContainer = $('.js-diffs-batch');
diff --git a/app/assets/javascripts/pages/projects/compare/show/index.js b/app/assets/javascripts/pages/projects/compare/show/index.js
index 5edaa7f7e51..b74f7d1cf57 100644
--- a/app/assets/javascripts/pages/projects/compare/show/index.js
+++ b/app/assets/javascripts/pages/projects/compare/show/index.js
@@ -1,11 +1,11 @@
import Diff from '~/diff';
import GpgBadges from '~/gpg_badges';
-import initChangesDropdown from '~/init_changes_dropdown';
+import { initDiffStatsDropdown } from '~/init_diff_stats_dropdown';
import initCompareSelector from '~/projects/compare';
initCompareSelector();
new Diff(); // eslint-disable-line no-new
const paddingTop = 16;
-initChangesDropdown(document.querySelector('.navbar-gitlab').offsetHeight - paddingTop);
+initDiffStatsDropdown(document.querySelector('.navbar-gitlab').offsetHeight - paddingTop);
GpgBadges.fetch();
diff --git a/app/assets/javascripts/pages/projects/issues/show.js b/app/assets/javascripts/pages/projects/issues/show.js
index e365f51567d..62aa5df888f 100644
--- a/app/assets/javascripts/pages/projects/issues/show.js
+++ b/app/assets/javascripts/pages/projects/issues/show.js
@@ -6,7 +6,7 @@ import Issue from '~/issue';
import initIncidentApp from '~/issue_show/incident';
import { initIssuableApp, initIssueHeaderActions } from '~/issue_show/issue';
import { parseIssuableData } from '~/issue_show/utils/parse_data';
-import initNotesApp from '~/notes/index';
+import initNotesApp from '~/notes';
import { store } from '~/notes/stores';
import initRelatedMergeRequestsApp from '~/related_merge_requests';
import initSentryErrorStackTraceApp from '~/sentry_error_stack_trace';
diff --git a/app/assets/javascripts/pages/projects/issues/show/index.js b/app/assets/javascripts/pages/projects/issues/show/index.js
index e4f99d1e7fd..1282d2aa303 100644
--- a/app/assets/javascripts/pages/projects/issues/show/index.js
+++ b/app/assets/javascripts/pages/projects/issues/show/index.js
@@ -1,7 +1,8 @@
+import { store } from '~/notes/stores';
import initRelatedIssues from '~/related_issues';
import initSidebarBundle from '~/sidebar/sidebar_bundle';
import initShow from '../show';
initShow();
-initSidebarBundle();
+initSidebarBundle(store);
initRelatedIssues();
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_a.vue b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue
index 51980b2d971..51980b2d971 100644
--- a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_a.vue
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_b.vue b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_b.vue
deleted file mode 100644
index 8f92ce95dbf..00000000000
--- a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_b.vue
+++ /dev/null
@@ -1,116 +0,0 @@
-<script>
-import { GlProgressBar, GlSprintf } from '@gitlab/ui';
-import { pick } from 'lodash';
-import { s__ } from '~/locale';
-import { ACTION_LABELS } from '../constants';
-import LearnGitlabInfoCard from './learn_gitlab_info_card.vue';
-
-export default {
- components: { LearnGitlabInfoCard, GlProgressBar, GlSprintf },
- i18n: {
- title: s__('LearnGitLab|Learn GitLab'),
- description: s__(
- 'LearnGitLab|Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project.',
- ),
- percentageCompleted: s__(`LearnGitLab|%{percentage}%{percentSymbol} completed`),
- workspace: {
- title: s__('LearnGitLab|Set up your workspace'),
- description: s__(
- "LearnGitLab|Complete these tasks first so you can enjoy GitLab's features to their fullest:",
- ),
- },
- plan: {
- title: s__('LearnGitLab|Plan and execute'),
- description: s__(
- 'LearnGitLab|Create a workflow for your new workspace, and learn how GitLab features work together:',
- ),
- },
- deploy: {
- title: s__('LearnGitLab|Deploy'),
- description: s__(
- 'LearnGitLab|Use your new GitLab workflow to deploy your application, monitor its health, and keep it secure:',
- ),
- },
- },
- props: {
- actions: {
- required: true,
- type: Object,
- },
- },
- maxValue: Object.keys(ACTION_LABELS).length,
- methods: {
- infoProps(action) {
- return {
- ...this.actions[action],
- ...pick(ACTION_LABELS[action], ['title', 'actionLabel', 'description', 'trialRequired']),
- };
- },
- progressValue() {
- return Object.values(this.actions).filter((a) => a.completed).length;
- },
- progressPercentage() {
- return Math.round((this.progressValue() / this.$options.maxValue) * 100);
- },
- },
-};
-</script>
-<template>
- <div>
- <div class="row">
- <div class="gl-mb-7 col-md-8 col-lg-7">
- <h1 class="gl-font-size-h1">{{ $options.i18n.title }}</h1>
- <p class="gl-text-gray-700 gl-mb-0">{{ $options.i18n.description }}</p>
- </div>
- </div>
-
- <div class="gl-mb-3">
- <p class="gl-text-gray-500 gl-mb-2" data-testid="completion-percentage">
- <gl-sprintf :message="$options.i18n.percentageCompleted">
- <template #percentage>{{ progressPercentage() }}</template>
- <template #percentSymbol>%</template>
- </gl-sprintf>
- </p>
- <gl-progress-bar :value="progressValue()" :max="$options.maxValue" />
- </div>
-
- <h2 class="gl-font-lg gl-mb-3">{{ $options.i18n.workspace.title }}</h2>
- <p class="gl-text-gray-700 gl-mb-6">{{ $options.i18n.workspace.description }}</p>
-
- <div class="row row-cols-2 row-cols-md-3 row-cols-lg-4">
- <div class="col gl-mb-6"><learn-gitlab-info-card v-bind="infoProps('userAdded')" /></div>
- <div class="col gl-mb-6"><learn-gitlab-info-card v-bind="infoProps('gitWrite')" /></div>
- <div class="col gl-mb-6">
- <learn-gitlab-info-card v-bind="infoProps('pipelineCreated')" />
- </div>
- <div class="col gl-mb-6"><learn-gitlab-info-card v-bind="infoProps('trialStarted')" /></div>
- <div class="col gl-mb-6">
- <learn-gitlab-info-card v-bind="infoProps('codeOwnersEnabled')" />
- </div>
- <div class="col gl-mb-6">
- <learn-gitlab-info-card v-bind="infoProps('requiredMrApprovalsEnabled')" />
- </div>
- </div>
-
- <h2 class="gl-font-lg gl-mb-3">{{ $options.i18n.plan.title }}</h2>
- <p class="gl-text-gray-700 gl-mb-6">{{ $options.i18n.plan.description }}</p>
-
- <div class="row row-cols-2 row-cols-md-3 row-cols-lg-4">
- <div class="col gl-mb-6">
- <learn-gitlab-info-card v-bind="infoProps('issueCreated')" />
- </div>
- <div class="col gl-mb-6">
- <learn-gitlab-info-card v-bind="infoProps('mergeRequestCreated')" />
- </div>
- </div>
-
- <h2 class="gl-font-lg gl-mb-3">{{ $options.i18n.deploy.title }}</h2>
- <p class="gl-text-gray-700 gl-mb-6">{{ $options.i18n.deploy.description }}</p>
-
- <div class="row row-cols-2 row-cols-lg-4 g-2 g-lg-3">
- <div class="col gl-mb-6">
- <learn-gitlab-info-card v-bind="infoProps('securityScanEnabled')" />
- </div>
- </div>
- </div>
-</template>
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_link.vue b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_link.vue
index 3d31ac6c267..69fb5878f5c 100644
--- a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_link.vue
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_link.vue
@@ -39,7 +39,7 @@ export default {
:href="value.url"
data-track-action="click_link"
:data-track-label="$options.i18n.ACTION_LABELS[action].title"
- data-track-property="Growth::Conversion::Experiment::LearnGitLabA"
+ data-track-property="Growth::Conversion::Experiment::LearnGitLab"
>
{{ $options.i18n.ACTION_LABELS[action].title }}
</gl-link>
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/index/index.js b/app/assets/javascripts/pages/projects/learn_gitlab/index/index.js
index ac7c94bdd9e..6da0a8fd212 100644
--- a/app/assets/javascripts/pages/projects/learn_gitlab/index/index.js
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/index/index.js
@@ -1,8 +1,6 @@
import Vue from 'vue';
-import trackLearnGitlab from '~/learn_gitlab/track_learn_gitlab';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
-import LearnGitlabA from '../components/learn_gitlab_a.vue';
-import LearnGitlabB from '../components/learn_gitlab_b.vue';
+import LearnGitlab from '../components/learn_gitlab.vue';
function initLearnGitlab() {
const el = document.getElementById('js-learn-gitlab-app');
@@ -14,14 +12,10 @@ function initLearnGitlab() {
const actions = convertObjectPropsToCamelCase(JSON.parse(el.dataset.actions));
const sections = convertObjectPropsToCamelCase(JSON.parse(el.dataset.sections));
- const { learnGitlabA } = gon.experiments;
-
- trackLearnGitlab(learnGitlabA);
-
return new Vue({
el,
render(createElement) {
- return createElement(learnGitlabA ? LearnGitlabA : LearnGitlabB, {
+ return createElement(LearnGitlab, {
props: { actions, sections },
});
},
diff --git a/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js b/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js
index d6b6c9fe06a..dadf0988582 100644
--- a/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js
+++ b/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js
@@ -2,11 +2,10 @@ import Vue from 'vue';
import VueApollo from 'vue-apollo';
import loadAwardsHandler from '~/awards_handler';
import ShortcutsIssuable from '~/behaviors/shortcuts/shortcuts_issuable';
-import initPipelines from '~/commit/pipelines/pipelines_bundle';
+import { initPipelineCountListener } from '~/commit/pipelines/utils';
import initIssuableSidebar from '~/init_issuable_sidebar';
import StatusBox from '~/issuable/components/status_box.vue';
import createDefaultClient from '~/lib/graphql';
-import { handleLocationHash } from '~/lib/utils/common_utils';
import initSourcegraph from '~/sourcegraph';
import ZenMode from '~/zen_mode';
import getStateQuery from './queries/get_state.query.graphql';
@@ -15,11 +14,10 @@ export default function initMergeRequestShow() {
const awardEmojiEl = document.getElementById('js-vue-awards-block');
new ZenMode(); // eslint-disable-line no-new
- initIssuableSidebar();
- initPipelines();
+ initPipelineCountListener(document.querySelector('#commit-pipeline-table-view'));
new ShortcutsIssuable(true); // eslint-disable-line no-new
- handleLocationHash();
initSourcegraph();
+ initIssuableSidebar();
if (awardEmojiEl) {
import('~/emoji/awards_app')
.then((m) => m.default(awardEmojiEl))
@@ -29,7 +27,10 @@ export default function initMergeRequestShow() {
}
const el = document.querySelector('.js-mr-status-box');
- const apolloProvider = new VueApollo({ defaultClient: createDefaultClient() });
+ const apolloProvider = new VueApollo({
+ assumeImmutableResults: true,
+ defaultClient: createDefaultClient(),
+ });
// eslint-disable-next-line no-new
new Vue({
el,
diff --git a/app/assets/javascripts/pages/projects/merge_requests/show/index.js b/app/assets/javascripts/pages/projects/merge_requests/show/index.js
index 546fa66eda6..25dede33880 100644
--- a/app/assets/javascripts/pages/projects/merge_requests/show/index.js
+++ b/app/assets/javascripts/pages/projects/merge_requests/show/index.js
@@ -5,8 +5,11 @@ import initSidebarBundle from '~/sidebar/sidebar_bundle';
import initIssuableHeaderWarning from '~/vue_shared/components/issuable/init_issuable_header_warning';
import initShow from '../init_merge_request_show';
-initShow();
-initSidebarBundle();
initMrNotes();
-initReviewBar();
-initIssuableHeaderWarning(store);
+initShow();
+
+requestIdleCallback(() => {
+ initSidebarBundle(store);
+ initReviewBar();
+ initIssuableHeaderWarning(store);
+});
diff --git a/app/assets/javascripts/pages/projects/new/components/new_project_url_select.vue b/app/assets/javascripts/pages/projects/new/components/new_project_url_select.vue
new file mode 100644
index 00000000000..ba8858c985a
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/new/components/new_project_url_select.vue
@@ -0,0 +1,98 @@
+<script>
+import {
+ GlButton,
+ GlButtonGroup,
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownSectionHeader,
+ GlLoadingIcon,
+ GlSearchBoxByType,
+} from '@gitlab/ui';
+import { MINIMUM_SEARCH_LENGTH } from '~/graphql_shared/constants';
+import { getIdFromGraphQLId } from '~/graphql_shared/utils';
+import Tracking from '~/tracking';
+import { DEBOUNCE_DELAY } from '~/vue_shared/components/filtered_search_bar/constants';
+import searchNamespacesWhereUserCanCreateProjectsQuery from '../queries/search_namespaces_where_user_can_create_projects.query.graphql';
+
+export default {
+ components: {
+ GlButton,
+ GlButtonGroup,
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownSectionHeader,
+ GlLoadingIcon,
+ GlSearchBoxByType,
+ },
+ mixins: [Tracking.mixin()],
+ apollo: {
+ currentUser: {
+ query: searchNamespacesWhereUserCanCreateProjectsQuery,
+ variables() {
+ return {
+ search: this.search,
+ };
+ },
+ skip() {
+ return this.search.length > 0 && this.search.length < MINIMUM_SEARCH_LENGTH;
+ },
+ debounce: DEBOUNCE_DELAY,
+ },
+ },
+ inject: ['namespaceFullPath', 'namespaceId', 'rootUrl', 'trackLabel'],
+ data() {
+ return {
+ currentUser: {},
+ search: '',
+ selectedNamespace: {
+ id: this.namespaceId,
+ fullPath: this.namespaceFullPath,
+ },
+ };
+ },
+ computed: {
+ userGroups() {
+ return this.currentUser.groups?.nodes || [];
+ },
+ userNamespace() {
+ return this.currentUser.namespace || {};
+ },
+ },
+ methods: {
+ handleClick({ id, fullPath }) {
+ this.selectedNamespace = {
+ id: getIdFromGraphQLId(id),
+ fullPath,
+ };
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-button-group class="gl-w-full">
+ <gl-button label>{{ rootUrl }}</gl-button>
+ <gl-dropdown
+ class="gl-w-full"
+ :text="selectedNamespace.fullPath"
+ toggle-class="gl-rounded-top-right-base! gl-rounded-bottom-right-base!"
+ data-qa-selector="select_namespace_dropdown"
+ @show="track('activate_form_input', { label: trackLabel, property: 'project_path' })"
+ >
+ <gl-search-box-by-type v-model.trim="search" />
+ <gl-loading-icon v-if="$apollo.queries.currentUser.loading" />
+ <template v-else>
+ <gl-dropdown-section-header>{{ __('Groups') }}</gl-dropdown-section-header>
+ <gl-dropdown-item v-for="group of userGroups" :key="group.id" @click="handleClick(group)">
+ {{ group.fullPath }}
+ </gl-dropdown-item>
+ <gl-dropdown-section-header>{{ __('Users') }}</gl-dropdown-section-header>
+ <gl-dropdown-item @click="handleClick(userNamespace)">
+ {{ userNamespace.fullPath }}
+ </gl-dropdown-item>
+ </template>
+ </gl-dropdown>
+
+ <input type="hidden" name="project[namespace_id]" :value="selectedNamespace.id" />
+ </gl-button-group>
+</template>
diff --git a/app/assets/javascripts/pages/projects/new/index.js b/app/assets/javascripts/pages/projects/new/index.js
index f469c56e808..ed816e3be95 100644
--- a/app/assets/javascripts/pages/projects/new/index.js
+++ b/app/assets/javascripts/pages/projects/new/index.js
@@ -1,13 +1,15 @@
import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import createDefaultClient from '~/lib/graphql';
import { parseBoolean } from '~/lib/utils/common_utils';
import initProjectVisibilitySelector from '../../../project_visibility';
import initProjectNew from '../../../projects/project_new';
import NewProjectCreationApp from './components/app.vue';
+import NewProjectUrlSelect from './components/new_project_url_select.vue';
-initProjectVisibilitySelector();
-initProjectNew.bindEvents();
+function initNewProjectCreation() {
+ const el = document.querySelector('.js-new-project-creation');
-function initNewProjectCreation(el) {
const {
pushToCreateProjectCommand,
workingWithProjectsHelpPath,
@@ -29,9 +31,6 @@ function initNewProjectCreation(el) {
return new Vue({
el,
- components: {
- NewProjectCreationApp,
- },
provide,
render(h) {
return h(NewProjectCreationApp, { props });
@@ -39,6 +38,31 @@ function initNewProjectCreation(el) {
});
}
-const el = document.querySelector('.js-new-project-creation');
+function initNewProjectUrlSelect() {
+ const el = document.querySelector('.js-vue-new-project-url-select');
+
+ if (!el) {
+ return undefined;
+ }
-initNewProjectCreation(el);
+ Vue.use(VueApollo);
+
+ return new Vue({
+ el,
+ apolloProvider: new VueApollo({
+ defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
+ }),
+ provide: {
+ namespaceFullPath: el.dataset.namespaceFullPath,
+ namespaceId: el.dataset.namespaceId,
+ rootUrl: el.dataset.rootUrl,
+ trackLabel: el.dataset.trackLabel,
+ },
+ render: (createElement) => createElement(NewProjectUrlSelect),
+ });
+}
+
+initProjectVisibilitySelector();
+initProjectNew.bindEvents();
+initNewProjectCreation();
+initNewProjectUrlSelect();
diff --git a/app/assets/javascripts/pages/projects/new/queries/search_namespaces_where_user_can_create_projects.query.graphql b/app/assets/javascripts/pages/projects/new/queries/search_namespaces_where_user_can_create_projects.query.graphql
new file mode 100644
index 00000000000..e16fe5dde49
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/new/queries/search_namespaces_where_user_can_create_projects.query.graphql
@@ -0,0 +1,14 @@
+query searchNamespacesWhereUserCanCreateProjects($search: String) {
+ currentUser {
+ groups(permissionScope: CREATE_PROJECTS, search: $search) {
+ nodes {
+ id
+ fullPath
+ }
+ }
+ namespace {
+ id
+ fullPath
+ }
+ }
+}
diff --git a/app/assets/javascripts/pages/projects/packages/packages/show/index.js b/app/assets/javascripts/pages/projects/packages/packages/show/index.js
index ee06f247ddc..2dee87985cb 100644
--- a/app/assets/javascripts/pages/projects/packages/packages/show/index.js
+++ b/app/assets/javascripts/pages/projects/packages/packages/show/index.js
@@ -1,11 +1,3 @@
-(async function initPackage() {
- let app;
- if (document.getElementById('js-vue-packages-detail-new')) {
- app = await import(
- /* webpackChunkName: 'new_package_app' */ `~/packages_and_registries/package_registry/pages/details.js`
- );
- } else {
- app = await import('~/packages/details/');
- }
- app.default();
-})();
+import initPackageDetails from '~/packages_and_registries/package_registry/pages/details';
+
+initPackageDetails();
diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue
index d0ec5668d21..0e646e8c505 100644
--- a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue
+++ b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue
@@ -141,9 +141,7 @@ export default {
return Math.floor(Math.random() * 28);
},
showDailyLimitMessage({ value }) {
- return (
- value === KEY_CUSTOM && this.glFeatures.ciDailyLimitForPipelineSchedules && this.dailyLimit
- );
+ return value === KEY_CUSTOM && this.dailyLimit;
},
},
};
diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/pipeline_schedules_callout.vue b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/pipeline_schedules_callout.vue
index 92b2bc9644b..42b08bcaa7b 100644
--- a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/pipeline_schedules_callout.vue
+++ b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/pipeline_schedules_callout.vue
@@ -53,7 +53,7 @@ Those scheduled pipelines will inherit limited project access based on their ass
<p>
{{ __('Learn more in the') }}
<a :href="docsUrl" target="_blank" rel="nofollow">
- {{ s__('Learn more in the|pipeline schedules documentation') }}</a
+ {{ __('pipeline schedules documentation') }}</a
>.
<!-- oneline to prevent extra space before period -->
</p>
diff --git a/app/assets/javascripts/pages/projects/project_members/index.js b/app/assets/javascripts/pages/projects/project_members/index.js
index fb0be31834d..0b662c945c6 100644
--- a/app/assets/javascripts/pages/projects/project_members/index.js
+++ b/app/assets/javascripts/pages/projects/project_members/index.js
@@ -1,4 +1,5 @@
import groupsSelect from '~/groups_select';
+import initImportAProjectModal from '~/invite_members/init_import_a_project_modal';
import initInviteGroupTrigger from '~/invite_members/init_invite_group_trigger';
import initInviteMembersForm from '~/invite_members/init_invite_members_form';
import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
@@ -14,6 +15,7 @@ import UsersSelect from '~/users_select';
groupsSelect();
memberExpirationDate();
memberExpirationDate('.js-access-expiration-date-groups');
+initImportAProjectModal();
initInviteMembersModal();
initInviteMembersTrigger();
initInviteGroupTrigger();
diff --git a/app/assets/javascripts/pages/projects/usage_quotas/index.js b/app/assets/javascripts/pages/projects/usage_quotas/index.js
new file mode 100644
index 00000000000..9cd80b85c8a
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/usage_quotas/index.js
@@ -0,0 +1,23 @@
+import LinkedTabs from '~/lib/utils/bootstrap_linked_tabs';
+import storageCounter from '~/projects/storage_counter';
+import initSearchSettings from '~/search_settings';
+
+const initLinkedTabs = () => {
+ if (!document.querySelector('.js-usage-quota-tabs')) {
+ return false;
+ }
+
+ return new LinkedTabs({
+ defaultAction: '#storage-quota-tab',
+ parentEl: '.js-usage-quota-tabs',
+ hashedTabs: true,
+ });
+};
+
+const initVueApp = () => {
+ storageCounter('js-project-storage-count-app');
+};
+
+initVueApp();
+initLinkedTabs();
+initSearchSettings();
diff --git a/app/assets/javascripts/pages/projects/wikis/index.js b/app/assets/javascripts/pages/projects/wikis/index.js
index dead61cf358..2c1f9e634ab 100644
--- a/app/assets/javascripts/pages/projects/wikis/index.js
+++ b/app/assets/javascripts/pages/projects/wikis/index.js
@@ -1,3 +1,5 @@
+import { initDiffStatsDropdown } from '~/init_diff_stats_dropdown';
import initWikis from '~/pages/shared/wikis';
initWikis();
+initDiffStatsDropdown();
diff --git a/app/assets/javascripts/pages/projects/work_items/index/index.js b/app/assets/javascripts/pages/projects/work_items/index/index.js
new file mode 100644
index 00000000000..11c257611f0
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/work_items/index/index.js
@@ -0,0 +1,3 @@
+import { initWorkItemsRoot } from '~/work_items/index';
+
+initWorkItemsRoot();
diff --git a/app/assets/javascripts/pages/sessions/new/signin_tabs_memoizer.js b/app/assets/javascripts/pages/sessions/new/signin_tabs_memoizer.js
index 1e7c29aefaa..7e646125331 100644
--- a/app/assets/javascripts/pages/sessions/new/signin_tabs_memoizer.js
+++ b/app/assets/javascripts/pages/sessions/new/signin_tabs_memoizer.js
@@ -8,7 +8,7 @@ export default class SigninTabsMemoizer {
constructor({ currentTabKey = 'current_signin_tab', tabSelector = 'ul.new-session-tabs' } = {}) {
this.currentTabKey = currentTabKey;
this.tabSelector = tabSelector;
- this.isLocalStorageAvailable = AccessorUtilities.isLocalStorageAccessSafe();
+ this.isLocalStorageAvailable = AccessorUtilities.canUseLocalStorage();
// sets selected tab if given as hash tag
if (window.location.hash) {
this.saveData(window.location.hash);
diff --git a/app/assets/javascripts/performance_bar/components/performance_bar_app.vue b/app/assets/javascripts/performance_bar/components/performance_bar_app.vue
index 670b0535ca3..f204f0ebfaa 100644
--- a/app/assets/javascripts/performance_bar/components/performance_bar_app.vue
+++ b/app/assets/javascripts/performance_bar/components/performance_bar_app.vue
@@ -1,5 +1,5 @@
<script>
-/* eslint-disable vue/no-v-html */
+import { GlSafeHtmlDirective } from '@gitlab/ui';
import { glEmojiTag } from '~/emoji';
import { s__ } from '~/locale';
@@ -13,6 +13,9 @@ export default {
DetailedMetric,
RequestSelector,
},
+ directives: {
+ SafeHtml: GlSafeHtmlDirective,
+ },
props: {
store: {
type: Object,
@@ -129,6 +132,7 @@ export default {
this.currentRequest = newRequestId;
},
},
+ safeHtmlConfig: { ADD_TAGS: ['gl-emoji'] },
};
</script>
<template>
@@ -144,7 +148,7 @@ export default {
class="current-host"
:class="{ canary: currentRequest.details.host.canary }"
>
- <span v-html="birdEmoji"></span>
+ <span v-safe-html:[$options.safeHtmlConfig]="birdEmoji"></span>
{{ currentRequest.details.host.hostname }}
</span>
</div>
diff --git a/app/assets/javascripts/performance_bar/components/request_selector.vue b/app/assets/javascripts/performance_bar/components/request_selector.vue
index 75fb7bbc5c5..a46ac620f48 100644
--- a/app/assets/javascripts/performance_bar/components/request_selector.vue
+++ b/app/assets/javascripts/performance_bar/components/request_selector.vue
@@ -1,6 +1,5 @@
<script>
-/* eslint-disable vue/no-v-html */
-import { GlPopover } from '@gitlab/ui';
+import { GlPopover, GlSafeHtmlDirective } from '@gitlab/ui';
import { glEmojiTag } from '~/emoji';
import { n__ } from '~/locale';
@@ -8,6 +7,9 @@ export default {
components: {
GlPopover,
},
+ directives: {
+ SafeHtml: GlSafeHtmlDirective,
+ },
props: {
currentRequest: {
type: Object,
@@ -43,6 +45,7 @@ export default {
methods: {
glEmojiTag,
},
+ safeHtmlConfig: { ADD_TAGS: ['gl-emoji'] },
};
</script>
<template>
@@ -59,7 +62,10 @@ export default {
</option>
</select>
<span v-if="requestsWithWarnings.length" class="gl-cursor-default">
- <span id="performance-bar-request-selector-warning" v-html="glEmojiTag('warning')"></span>
+ <span
+ id="performance-bar-request-selector-warning"
+ v-safe-html:[$options.safeHtmlConfig]="glEmojiTag('warning')"
+ ></span>
<gl-popover
placement="bottom"
target="performance-bar-request-selector-warning"
diff --git a/app/assets/javascripts/performance_bar/components/request_warning.vue b/app/assets/javascripts/performance_bar/components/request_warning.vue
index 7fe6b088ebb..3ebd222029b 100644
--- a/app/assets/javascripts/performance_bar/components/request_warning.vue
+++ b/app/assets/javascripts/performance_bar/components/request_warning.vue
@@ -1,12 +1,14 @@
<script>
-/* eslint-disable vue/no-v-html */
-import { GlPopover } from '@gitlab/ui';
+import { GlPopover, GlSafeHtmlDirective } from '@gitlab/ui';
import { glEmojiTag } from '~/emoji';
export default {
components: {
GlPopover,
},
+ directives: {
+ SafeHtml: GlSafeHtmlDirective,
+ },
props: {
htmlId: {
type: String,
@@ -32,11 +34,12 @@ export default {
methods: {
glEmojiTag,
},
+ safeHtmlConfig: { ADD_TAGS: ['gl-emoji'] },
};
</script>
<template>
<span v-if="hasWarnings" class="gl-cursor-default">
- <span :id="htmlId" v-html="glEmojiTag('warning')"></span>
+ <span :id="htmlId" v-safe-html:[$options.safeHtmlConfig]="glEmojiTag('warning')"></span>
<gl-popover placement="bottom" :target="htmlId" :content="warningMessage" />
</span>
</template>
diff --git a/app/assets/javascripts/pipeline_editor/components/commit/commit_section.vue b/app/assets/javascripts/pipeline_editor/components/commit/commit_section.vue
index 8f4894a0bde..0308cd9c565 100644
--- a/app/assets/javascripts/pipeline_editor/components/commit/commit_section.vue
+++ b/app/assets/javascripts/pipeline_editor/components/commit/commit_section.vue
@@ -10,7 +10,6 @@ import {
import commitCIFile from '../../graphql/mutations/commit_ci_file.mutation.graphql';
import updateCurrentBranchMutation from '../../graphql/mutations/update_current_branch.mutation.graphql';
import updateLastCommitBranchMutation from '../../graphql/mutations/update_last_commit_branch.mutation.graphql';
-import getCommitSha from '../../graphql/queries/client/commit_sha.graphql';
import getCurrentBranch from '../../graphql/queries/client/current_branch.graphql';
import getIsNewCiConfigFile from '../../graphql/queries/client/is_new_ci_config_file.graphql';
import getPipelineEtag from '../../graphql/queries/client/pipeline_etag.graphql';
@@ -37,6 +36,11 @@ export default {
type: String,
required: true,
},
+ commitSha: {
+ type: String,
+ required: false,
+ default: '',
+ },
},
data() {
return {
@@ -49,9 +53,6 @@ export default {
isNewCiConfigFile: {
query: getIsNewCiConfigFile,
},
- commitSha: {
- query: getCommitSha,
- },
currentBranch: {
query: getCurrentBranch,
},
@@ -96,13 +97,7 @@ export default {
lastCommitId: this.commitSha,
},
update(store, { data }) {
- const commitSha = data?.commitCreate?.commit?.sha;
const pipelineEtag = data?.commitCreate?.commit?.commitPipelinePath;
-
- if (commitSha) {
- store.writeQuery({ query: getCommitSha, data: { commitSha } });
- }
-
if (pipelineEtag) {
store.writeQuery({ query: getPipelineEtag, data: { pipelineEtag } });
}
@@ -117,6 +112,9 @@ export default {
this.$emit('commit', { type: COMMIT_SUCCESS });
this.updateLastCommitBranch(targetBranch);
this.updateCurrentBranch(targetBranch);
+ if (this.currentBranch === targetBranch) {
+ this.$emit('updateCommitSha');
+ }
}
} catch (error) {
this.$emit('showError', { type: COMMIT_FAILURE, reasons: [error?.message] });
diff --git a/app/assets/javascripts/pipeline_editor/components/editor/text_editor.vue b/app/assets/javascripts/pipeline_editor/components/editor/text_editor.vue
index 77ede396496..f2a0f474bc4 100644
--- a/app/assets/javascripts/pipeline_editor/components/editor/text_editor.vue
+++ b/app/assets/javascripts/pipeline_editor/components/editor/text_editor.vue
@@ -3,7 +3,6 @@ import { EDITOR_READY_EVENT } from '~/editor/constants';
import { CiSchemaExtension } from '~/editor/extensions/source_editor_ci_schema_ext';
import SourceEditor from '~/vue_shared/components/source_editor.vue';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
-import getCommitSha from '../../graphql/queries/client/commit_sha.graphql';
export default {
components: {
@@ -12,14 +11,11 @@ export default {
mixins: [glFeatureFlagMixin()],
inject: ['ciConfigPath', 'projectPath', 'projectNamespace', 'defaultBranch'],
inheritAttrs: false,
- data() {
- return {
- commitSha: '',
- };
- },
- apollo: {
+ props: {
commitSha: {
- query: getCommitSha,
+ type: String,
+ required: false,
+ default: '',
},
},
methods: {
diff --git a/app/assets/javascripts/pipeline_editor/components/file_nav/branch_switcher.vue b/app/assets/javascripts/pipeline_editor/components/file_nav/branch_switcher.vue
index 9a6eed50fbe..68065cc3c73 100644
--- a/app/assets/javascripts/pipeline_editor/components/file_nav/branch_switcher.vue
+++ b/app/assets/javascripts/pipeline_editor/components/file_nav/branch_switcher.vue
@@ -158,11 +158,9 @@ export default {
const updatedPath = setUrlParams({ branch_name: newBranch });
historyPushState(updatedPath);
- this.$emit('updateCommitSha', { newBranch });
-
// refetching the content will cause a lot of components to re-render,
// including the text editor which uses the commit sha to register the CI schema
- // so we need to make sure the commit sha is updated first
+ // so we need to make sure the currentBranch (and consequently, the commitSha) are updated first
await this.$nextTick();
this.$emit('refetchContent');
},
diff --git a/app/assets/javascripts/pipeline_editor/components/file_nav/pipeline_editor_file_nav.vue b/app/assets/javascripts/pipeline_editor/components/file_nav/pipeline_editor_file_nav.vue
index ebe73bdcec3..551a0430fbf 100644
--- a/app/assets/javascripts/pipeline_editor/components/file_nav/pipeline_editor_file_nav.vue
+++ b/app/assets/javascripts/pipeline_editor/components/file_nav/pipeline_editor_file_nav.vue
@@ -1,21 +1,14 @@
<script>
-import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import BranchSwitcher from './branch_switcher.vue';
export default {
components: {
BranchSwitcher,
},
- mixins: [glFeatureFlagsMixin()],
- computed: {
- showBranchSwitcher() {
- return this.glFeatures.pipelineEditorBranchSwitcher;
- },
- },
};
</script>
<template>
<div class="gl-mb-4">
- <branch-switcher v-if="showBranchSwitcher" v-on="$listeners" />
+ <branch-switcher v-on="$listeners" />
</div>
</template>
diff --git a/app/assets/javascripts/pipeline_editor/components/header/pipeline_editor_header.vue b/app/assets/javascripts/pipeline_editor/components/header/pipeline_editor_header.vue
index 24bca04e115..fcc31f087ff 100644
--- a/app/assets/javascripts/pipeline_editor/components/header/pipeline_editor_header.vue
+++ b/app/assets/javascripts/pipeline_editor/components/header/pipeline_editor_header.vue
@@ -33,6 +33,11 @@ export default {
type: Object,
required: true,
},
+ commitSha: {
+ type: String,
+ required: false,
+ default: '',
+ },
isNewCiConfigFile: {
type: Boolean,
required: true,
@@ -54,7 +59,11 @@ export default {
</script>
<template>
<div class="gl-mb-5">
- <pipeline-status v-if="showPipelineStatus" :class="$options.pipelineStatusClasses" />
+ <pipeline-status
+ v-if="showPipelineStatus"
+ :commit-sha="commitSha"
+ :class="$options.pipelineStatusClasses"
+ />
<validation-segment :class="validationStyling" :ci-config="ciConfigData" />
</div>
</template>
diff --git a/app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue b/app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue
index 46f6f4a28c1..ec240854be5 100644
--- a/app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue
+++ b/app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue
@@ -3,7 +3,6 @@ import { GlButton, GlIcon, GlLink, GlLoadingIcon, GlSprintf } from '@gitlab/ui';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { truncateSha } from '~/lib/utils/text_utility';
import { s__ } from '~/locale';
-import getCommitSha from '~/pipeline_editor/graphql/queries/client/commit_sha.graphql';
import getPipelineQuery from '~/pipeline_editor/graphql/queries/client/pipeline.graphql';
import getPipelineEtag from '~/pipeline_editor/graphql/queries/client/pipeline_etag.graphql';
import {
@@ -33,10 +32,14 @@ export default {
GlSprintf,
},
inject: ['projectFullPath'],
- apollo: {
+ props: {
commitSha: {
- query: getCommitSha,
+ type: String,
+ required: false,
+ default: '',
},
+ },
+ apollo: {
pipelineEtag: {
query: getPipelineEtag,
},
@@ -51,7 +54,7 @@ export default {
sha: this.commitSha,
};
},
- update: (data) => {
+ update(data) {
const { id, commitPath = '', detailedStatus = {} } = data.project?.pipeline || {};
return {
@@ -60,6 +63,11 @@ export default {
detailedStatus,
};
},
+ result(res) {
+ if (res.data?.project?.pipeline) {
+ this.hasError = false;
+ }
+ },
error() {
this.hasError = true;
},
@@ -68,7 +76,6 @@ export default {
},
data() {
return {
- commitSha: '',
hasError: false,
};
},
@@ -84,7 +91,11 @@ export default {
// (e.g. pipeline is null during fetch when the pipeline hasn't been
// triggered yet), we can just show the loading state until the pipeline
// details are ready to be fetched
- return this.$apollo.queries.pipeline.loading || (!this.hasPipelineData && !this.hasError);
+ return (
+ this.$apollo.queries.pipeline.loading ||
+ this.commitSha.length === 0 ||
+ (!this.hasPipelineData && !this.hasError)
+ );
},
shortSha() {
return truncateSha(this.commitSha);
diff --git a/app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue b/app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue
index e463fcf379d..f7c9f10ea46 100644
--- a/app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue
+++ b/app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue
@@ -69,6 +69,11 @@ export default {
type: String,
required: true,
},
+ commitSha: {
+ type: String,
+ required: false,
+ default: '',
+ },
},
apollo: {
appStatus: {
@@ -110,7 +115,7 @@ export default {
@click="setCurrentTab($options.tabConstants.CREATE_TAB)"
>
<ci-editor-header />
- <text-editor :value="ciFileContent" v-on="$listeners" />
+ <text-editor :commit-sha="commitSha" :value="ciFileContent" v-on="$listeners" />
</editor-tab>
<editor-tab
class="gl-mb-3"
diff --git a/app/assets/javascripts/pipeline_editor/components/ui/pipeline_editor_empty_state.vue b/app/assets/javascripts/pipeline_editor/components/ui/pipeline_editor_empty_state.vue
index 0ac4a40ff4a..fbb66231f16 100644
--- a/app/assets/javascripts/pipeline_editor/components/ui/pipeline_editor_empty_state.vue
+++ b/app/assets/javascripts/pipeline_editor/components/ui/pipeline_editor_empty_state.vue
@@ -24,9 +24,6 @@ export default {
},
},
computed: {
- showFileNav() {
- return this.glFeatures.pipelineEditorBranchSwitcher;
- },
showCTAButton() {
return this.glFeatures.pipelineEditorEmptyStateAction;
},
@@ -40,7 +37,7 @@ export default {
</script>
<template>
<div>
- <pipeline-editor-file-nav v-if="showFileNav" v-on="$listeners" />
+ <pipeline-editor-file-nav v-on="$listeners" />
<div class="gl-display-flex gl-flex-direction-column gl-align-items-center gl-mt-11">
<img :src="emptyStateIllustrationPath" />
<h1 class="gl-font-size-h1">{{ $options.i18n.title }}</h1>
diff --git a/app/assets/javascripts/pipeline_editor/constants.js b/app/assets/javascripts/pipeline_editor/constants.js
index d05b06d16db..bb03fa126a5 100644
--- a/app/assets/javascripts/pipeline_editor/constants.js
+++ b/app/assets/javascripts/pipeline_editor/constants.js
@@ -43,3 +43,5 @@ export const pipelineEditorTrackingOptions = {
export const TEMPLATE_REPOSITORY_URL =
'https://gitlab.com/gitlab-org/gitlab-foss/tree/master/lib/gitlab/ci/templates';
+
+export const COMMIT_SHA_POLL_INTERVAL = 1000;
diff --git a/app/assets/javascripts/pipeline_editor/graphql/mutations/update_commit_sha.mutation.graphql b/app/assets/javascripts/pipeline_editor/graphql/mutations/update_commit_sha.mutation.graphql
deleted file mode 100644
index dce17cad808..00000000000
--- a/app/assets/javascripts/pipeline_editor/graphql/mutations/update_commit_sha.mutation.graphql
+++ /dev/null
@@ -1,3 +0,0 @@
-mutation updateCommitSha($commitSha: String) {
- updateCommitSha(commitSha: $commitSha) @client
-}
diff --git a/app/assets/javascripts/pipeline_editor/graphql/queries/client/commit_sha.graphql b/app/assets/javascripts/pipeline_editor/graphql/queries/client/commit_sha.graphql
deleted file mode 100644
index 6c7635887ec..00000000000
--- a/app/assets/javascripts/pipeline_editor/graphql/queries/client/commit_sha.graphql
+++ /dev/null
@@ -1,3 +0,0 @@
-query getCommitSha {
- commitSha @client
-}
diff --git a/app/assets/javascripts/pipeline_editor/graphql/queries/latest_commit_sha.query.graphql b/app/assets/javascripts/pipeline_editor/graphql/queries/latest_commit_sha.query.graphql
index 219c23bb22b..02d49507947 100644
--- a/app/assets/javascripts/pipeline_editor/graphql/queries/latest_commit_sha.query.graphql
+++ b/app/assets/javascripts/pipeline_editor/graphql/queries/latest_commit_sha.query.graphql
@@ -1,11 +1,10 @@
query getLatestCommitSha($projectPath: ID!, $ref: String) {
project(fullPath: $projectPath) {
- pipelines(ref: $ref) {
- nodes {
- id
- sha
- path
- commitPath
+ repository {
+ tree(ref: $ref) {
+ lastCommit {
+ sha
+ }
}
}
}
diff --git a/app/assets/javascripts/pipeline_editor/graphql/resolvers.js b/app/assets/javascripts/pipeline_editor/graphql/resolvers.js
index 2bec2006e95..a34652b1495 100644
--- a/app/assets/javascripts/pipeline_editor/graphql/resolvers.js
+++ b/app/assets/javascripts/pipeline_editor/graphql/resolvers.js
@@ -1,6 +1,5 @@
import produce from 'immer';
import axios from '~/lib/utils/axios_utils';
-import getCommitShaQuery from './queries/client/commit_sha.graphql';
import getCurrentBranchQuery from './queries/client/current_branch.graphql';
import getLastCommitBranchQuery from './queries/client/last_commit_branch.query.graphql';
@@ -32,14 +31,6 @@ export const resolvers = {
__typename: 'CiLintContent',
}));
},
- updateCommitSha: (_, { commitSha }, { cache }) => {
- cache.writeQuery({
- query: getCommitShaQuery,
- data: produce(cache.readQuery({ query: getCommitShaQuery }), (draftData) => {
- draftData.commitSha = commitSha;
- }),
- });
- },
updateCurrentBranch: (_, { currentBranch }, { cache }) => {
cache.writeQuery({
query: getCurrentBranchQuery,
diff --git a/app/assets/javascripts/pipeline_editor/index.js b/app/assets/javascripts/pipeline_editor/index.js
index e0f8d889cad..89b9091e6f9 100644
--- a/app/assets/javascripts/pipeline_editor/index.js
+++ b/app/assets/javascripts/pipeline_editor/index.js
@@ -4,7 +4,6 @@ import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
import { resetServiceWorkersPublicPath } from '../lib/utils/webpack';
import { CODE_SNIPPET_SOURCE_SETTINGS } from './components/code_snippet_alert/constants';
-import getCommitSha from './graphql/queries/client/commit_sha.graphql';
import getCurrentBranch from './graphql/queries/client/current_branch.graphql';
import getLastCommitBranchQuery from './graphql/queries/client/last_commit_branch.query.graphql';
import getPipelineEtag from './graphql/queries/client/pipeline_etag.graphql';
@@ -26,7 +25,6 @@ export const initPipelineEditor = (selector = '#js-pipeline-editor') => {
const {
// Add to apollo cache as it can be updated by future queries
- commitSha,
initialBranchName,
pipelineEtag,
// Add to provide/inject API for static values
@@ -58,7 +56,11 @@ export const initPipelineEditor = (selector = '#js-pipeline-editor') => {
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
- defaultClient: createDefaultClient(resolvers, { typeDefs, useGet: true }),
+ defaultClient: createDefaultClient(resolvers, {
+ typeDefs,
+ useGet: true,
+ assumeImmutableResults: true,
+ }),
});
const { cache } = apolloProvider.clients.defaultClient;
@@ -70,13 +72,6 @@ export const initPipelineEditor = (selector = '#js-pipeline-editor') => {
});
cache.writeQuery({
- query: getCommitSha,
- data: {
- commitSha,
- },
- });
-
- cache.writeQuery({
query: getPipelineEtag,
data: {
pipelineEtag,
diff --git a/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue b/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
index 0e8a6805a59..e70417145ab 100644
--- a/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
+++ b/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
@@ -10,17 +10,16 @@ import ConfirmUnsavedChangesDialog from './components/ui/confirm_unsaved_changes
import PipelineEditorEmptyState from './components/ui/pipeline_editor_empty_state.vue';
import PipelineEditorMessages from './components/ui/pipeline_editor_messages.vue';
import {
+ COMMIT_SHA_POLL_INTERVAL,
EDITOR_APP_STATUS_EMPTY,
EDITOR_APP_STATUS_ERROR,
EDITOR_APP_STATUS_LOADING,
LOAD_FAILURE_UNKNOWN,
STARTER_TEMPLATE_NAME,
} from './constants';
-import updateCommitShaMutation from './graphql/mutations/update_commit_sha.mutation.graphql';
import getBlobContent from './graphql/queries/blob_content.graphql';
import getCiConfigData from './graphql/queries/ci_config.graphql';
import getAppStatus from './graphql/queries/client/app_status.graphql';
-import getCommitSha from './graphql/queries/client/commit_sha.graphql';
import getCurrentBranch from './graphql/queries/client/current_branch.graphql';
import getIsNewCiConfigFile from './graphql/queries/client/is_new_ci_config_file.graphql';
import getTemplate from './graphql/queries/get_starter_template.query.graphql';
@@ -50,6 +49,7 @@ export default {
failureType: null,
failureReasons: [],
initialCiFileContent: '',
+ isFetchingCommitSha: false,
isNewCiConfigFile: false,
lastCommittedContent: '',
currentCiFileContent: '',
@@ -136,7 +136,7 @@ export default {
update(data) {
const { ciConfig } = data || {};
const stageNodes = ciConfig?.stages?.nodes || [];
- const stages = unwrapStagesWithNeeds(stageNodes);
+ const stages = unwrapStagesWithNeeds(JSON.parse(JSON.stringify(stageNodes)));
return { ...ciConfig, stages };
},
@@ -156,7 +156,25 @@ export default {
query: getAppStatus,
},
commitSha: {
- query: getCommitSha,
+ query: getLatestCommitShaQuery,
+ variables() {
+ return {
+ projectPath: this.projectFullPath,
+ ref: this.currentBranch,
+ };
+ },
+ update(data) {
+ const latestCommitSha = data.project?.repository?.tree?.lastCommit?.sha;
+
+ if (this.isFetchingCommitSha && latestCommitSha === this.commitSha) {
+ this.$apollo.queries.commitSha.startPolling(COMMIT_SHA_POLL_INTERVAL);
+ return this.commitSha;
+ }
+
+ this.isFetchingCommitSha = false;
+ this.$apollo.queries.commitSha.stopPolling();
+ return latestCommitSha;
+ },
},
currentBranch: {
query: getCurrentBranch,
@@ -257,37 +275,9 @@ export default {
updateCiConfig(ciFileContent) {
this.currentCiFileContent = ciFileContent;
},
- async updateCommitSha({ newBranch }) {
- let fetchResults;
-
- try {
- fetchResults = await this.$apollo.query({
- query: getLatestCommitShaQuery,
- variables: {
- projectPath: this.projectFullPath,
- ref: newBranch,
- },
- });
- } catch {
- this.showFetchError();
- return;
- }
-
- if (fetchResults.errors?.length > 0) {
- this.showFetchError();
- return;
- }
-
- const pipelineNodes = fetchResults?.data?.project?.pipelines?.nodes ?? [];
- if (pipelineNodes.length === 0) {
- return;
- }
-
- const commitSha = pipelineNodes[0].sha;
- this.$apollo.mutate({
- mutation: updateCommitShaMutation,
- variables: { commitSha },
- });
+ updateCommitSha() {
+ this.isFetchingCommitSha = true;
+ this.$apollo.queries.commitSha.refetch();
},
updateOnCommit({ type }) {
this.reportSuccess(type);
@@ -336,6 +326,7 @@ export default {
:ci-config-data="ciConfigData"
:ci-file-content="currentCiFileContent"
:is-new-ci-config-file="isNewCiConfigFile"
+ :commit-sha="commitSha"
@commit="updateOnCommit"
@resetContent="resetContent"
@showError="showErrorAlert"
diff --git a/app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue b/app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue
index dfe9c82b912..4324c64ab3b 100644
--- a/app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue
+++ b/app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue
@@ -25,6 +25,11 @@ export default {
type: String,
required: true,
},
+ commitSha: {
+ type: String,
+ required: false,
+ default: '',
+ },
isNewCiConfigFile: {
type: Boolean,
required: true,
@@ -56,15 +61,22 @@ export default {
<pipeline-editor-file-nav v-on="$listeners" />
<pipeline-editor-header
:ci-config-data="ciConfigData"
+ :commit-sha="commitSha"
:is-new-ci-config-file="isNewCiConfigFile"
/>
<pipeline-editor-tabs
:ci-config-data="ciConfigData"
:ci-file-content="ciFileContent"
+ :commit-sha="commitSha"
v-on="$listeners"
@set-current-tab="setCurrentTab"
/>
- <commit-section v-if="showCommitForm" :ci-file-content="ciFileContent" v-on="$listeners" />
+ <commit-section
+ v-if="showCommitForm"
+ :ci-file-content="ciFileContent"
+ :commit-sha="commitSha"
+ v-on="$listeners"
+ />
<pipeline-editor-drawer v-if="showPipelineDrawer" />
</div>
</template>
diff --git a/app/assets/javascripts/pipeline_new/components/pipeline_new_form.vue b/app/assets/javascripts/pipeline_new/components/pipeline_new_form.vue
index 5472e51445a..d74b6e8edf6 100644
--- a/app/assets/javascripts/pipeline_new/components/pipeline_new_form.vue
+++ b/app/assets/javascripts/pipeline_new/components/pipeline_new_form.vue
@@ -123,6 +123,7 @@ export default {
isWarningDismissed: false,
isLoading: false,
submitted: false,
+ ccAlertDismissed: false,
};
},
computed: {
@@ -151,7 +152,7 @@ export default {
return this.form[this.refFullName]?.descriptions ?? {};
},
ccRequiredError() {
- return this.error === CC_VALIDATION_REQUIRED_ERROR;
+ return this.error === CC_VALIDATION_REQUIRED_ERROR && !this.ccAlertDismissed;
},
},
watch: {
@@ -292,6 +293,7 @@ export default {
},
createPipeline() {
this.submitted = true;
+ this.ccAlertDismissed = false;
return axios
.post(this.pipelinesPath, {
@@ -333,13 +335,17 @@ export default {
this.warnings = warnings;
this.totalWarnings = totalWarnings;
},
+ dismissError() {
+ this.ccAlertDismissed = true;
+ this.error = null;
+ },
},
};
</script>
<template>
<gl-form @submit.prevent="createPipeline">
- <cc-validation-required-alert v-if="ccRequiredError" class="gl-pb-5" />
+ <cc-validation-required-alert v-if="ccRequiredError" class="gl-pb-5" @dismiss="dismissError" />
<gl-alert
v-else-if="error"
:title="errorTitle"
diff --git a/app/assets/javascripts/pipelines/components/graph/accessors.js b/app/assets/javascripts/pipelines/components/graph/accessors.js
deleted file mode 100644
index 6ece855bcd8..00000000000
--- a/app/assets/javascripts/pipelines/components/graph/accessors.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import { get } from 'lodash';
-import { REST, GRAPHQL } from './constants';
-
-const accessors = {
- [REST]: {
- detailsPath: 'details_path',
- groupId: 'id',
- hasDetails: 'has_details',
- pipelineStatus: ['details', 'status'],
- sourceJob: ['source_job', 'name'],
- },
- [GRAPHQL]: {
- detailsPath: 'detailsPath',
- groupId: 'name',
- hasDetails: 'hasDetails',
- pipelineStatus: 'status',
- sourceJob: ['sourceJob', 'name'],
- },
-};
-
-const accessValue = (dataMethod, prop, item) => {
- return get(item, accessors[dataMethod][prop]);
-};
-
-export { accessors, accessValue };
diff --git a/app/assets/javascripts/pipelines/components/graph/constants.js b/app/assets/javascripts/pipelines/components/graph/constants.js
index dd9cdae518f..0b59612b25c 100644
--- a/app/assets/javascripts/pipelines/components/graph/constants.js
+++ b/app/assets/javascripts/pipelines/components/graph/constants.js
@@ -8,9 +8,6 @@ export const UPSTREAM = 'upstream';
*/
export const ONE_COL_WIDTH = 180;
-export const REST = 'rest';
-export const GRAPHQL = 'graphql';
-
export const STAGE_VIEW = 'stage';
export const LAYER_VIEW = 'layer';
export const VIEW_TYPE_KEY = 'pipeline_graph_view_type';
diff --git a/app/assets/javascripts/pipelines/components/graph/job_group_dropdown.vue b/app/assets/javascripts/pipelines/components/graph/job_group_dropdown.vue
index b2a3f27e079..6f4360649ff 100644
--- a/app/assets/javascripts/pipelines/components/graph/job_group_dropdown.vue
+++ b/app/assets/javascripts/pipelines/components/graph/job_group_dropdown.vue
@@ -23,6 +23,11 @@ export default {
required: false,
default: -1,
},
+ cssClassJobName: {
+ type: [String, Array],
+ required: false,
+ default: '',
+ },
stageName: {
type: String,
required: false,
@@ -59,7 +64,8 @@ export default {
type="button"
data-toggle="dropdown"
data-display="static"
- class="dropdown-menu-toggle build-content gl-build-content gl-pipeline-job-width! gl-pr-4!"
+ :class="cssClassJobName"
+ class="dropdown-menu-toggle gl-pipeline-job-width! gl-pr-4!"
>
<div class="gl-display-flex gl-align-items-center gl-justify-content-space-between">
<job-item
diff --git a/app/assets/javascripts/pipelines/components/graph/job_item.vue b/app/assets/javascripts/pipelines/components/graph/job_item.vue
index 6584d89d87c..fd40ca0b9c9 100644
--- a/app/assets/javascripts/pipelines/components/graph/job_item.vue
+++ b/app/assets/javascripts/pipelines/components/graph/job_item.vue
@@ -7,8 +7,7 @@ import CiIcon from '~/vue_shared/components/ci_icon.vue';
import { reportToSentry } from '../../utils';
import ActionComponent from '../jobs_shared/action_component.vue';
import JobNameComponent from '../jobs_shared/job_name_component.vue';
-import { accessValue } from './accessors';
-import { REST, SINGLE_JOB } from './constants';
+import { SINGLE_JOB } from './constants';
/**
* Renders the badge for the pipeline graph and the job's dropdown.
@@ -47,18 +46,13 @@ export default {
GlTooltip: GlTooltipDirective,
},
mixins: [delayedJobMixin],
- inject: {
- dataMethod: {
- default: REST,
- },
- },
props: {
job: {
type: Object,
required: true,
},
cssClassJobName: {
- type: String,
+ type: [String, Array],
required: false,
default: '',
},
@@ -111,10 +105,10 @@ export default {
return this.pipelineId > -1 ? `${this.job.name}-${this.pipelineId}` : '';
},
detailsPath() {
- return accessValue(this.dataMethod, 'detailsPath', this.status);
+ return this.status.detailsPath;
},
hasDetails() {
- return accessValue(this.dataMethod, 'hasDetails', this.status);
+ return this.status.hasDetails;
},
isSingleItem() {
return this.type === SINGLE_JOB;
@@ -189,7 +183,7 @@ export default {
if (this.isSingleItem) {
/*
This is so the jobDropdown still toggles. Issue to refactor:
- https://gitlab.com/gitlab-org/gitlab/-/issues/267117
+ https://gitlab.com/gitlab-org/gitlab/-/issues/267117
*/
evt.stopPropagation();
}
@@ -226,11 +220,11 @@ export default {
<div class="ci-job-name-component gl-display-flex gl-align-items-center">
<ci-icon :size="24" :status="job.status" class="gl-line-height-0" />
<div class="gl-pl-3 gl-display-flex gl-flex-direction-column gl-w-full">
- <div class="gl-text-truncate mw-70p gl-line-height-normal">{{ job.name }}</div>
+ <div class="gl-text-truncate gl-w-70p gl-line-height-normal">{{ job.name }}</div>
<div
v-if="showStageName"
data-testid="stage-name-in-job"
- class="gl-text-truncate mw-70p gl-font-sm gl-text-gray-500 gl-line-height-normal"
+ class="gl-text-truncate gl-w-70p gl-font-sm gl-text-gray-500 gl-line-height-normal"
>
{{ stageName }}
</div>
diff --git a/app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue b/app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue
index dd8a354511a..be47799868b 100644
--- a/app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue
+++ b/app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue
@@ -4,8 +4,7 @@ import { BV_HIDE_TOOLTIP } from '~/lib/utils/constants';
import { __, sprintf } from '~/locale';
import CiStatus from '~/vue_shared/components/ci_icon.vue';
import { reportToSentry } from '../../utils';
-import { accessValue } from './accessors';
-import { DOWNSTREAM, REST, UPSTREAM } from './constants';
+import { DOWNSTREAM, UPSTREAM } from './constants';
export default {
directives: {
@@ -18,11 +17,6 @@ export default {
GlLoadingIcon,
GlBadge,
},
- inject: {
- dataMethod: {
- default: REST,
- },
- },
props: {
columnTitle: {
type: String,
@@ -40,20 +34,9 @@ export default {
type: String,
required: true,
},
- /*
- The next two props will be removed or required
- once the graph transition is done.
- See: https://gitlab.com/gitlab-org/gitlab/-/issues/291043
- */
isLoading: {
type: Boolean,
- required: false,
- default: false,
- },
- projectId: {
- type: Number,
- required: false,
- default: -1,
+ required: true,
},
},
computed: {
@@ -65,7 +48,7 @@ export default {
return `js-linked-pipeline-${this.pipeline.id}`;
},
pipelineStatus() {
- return accessValue(this.dataMethod, 'pipelineStatus', this.pipeline);
+ return this.pipeline.status;
},
projectName() {
return this.pipeline.project.name;
@@ -97,12 +80,10 @@ export default {
return this.type === UPSTREAM;
},
isSameProject() {
- return this.projectId > -1
- ? this.projectId === this.pipeline.project.id
- : !this.pipeline.multiproject;
+ return !this.pipeline.multiproject;
},
sourceJobName() {
- return accessValue(this.dataMethod, 'sourceJob', this.pipeline);
+ return this.pipeline.sourceJob?.name ?? '';
},
sourceJobInfo() {
return this.isDownstream ? sprintf(__('Created by %{job}'), { job: this.sourceJobName }) : '';
@@ -143,9 +124,8 @@ export default {
<div
ref="linkedPipeline"
v-gl-tooltip
- class="linked-pipeline build gl-pipeline-job-width"
+ class="gl-pipeline-job-width"
:title="tooltipText"
- :class="{ 'downstream-pipeline': isDownstream }"
data-qa-selector="child_pipeline"
@mouseover="onDownstreamHovered"
@mouseleave="onDownstreamHoverLeave"
diff --git a/app/assets/javascripts/pipelines/components/graph/linked_pipelines_column.vue b/app/assets/javascripts/pipelines/components/graph/linked_pipelines_column.vue
index d251e0d8bd8..3c1208afbf0 100644
--- a/app/assets/javascripts/pipelines/components/graph/linked_pipelines_column.vue
+++ b/app/assets/javascripts/pipelines/components/graph/linked_pipelines_column.vue
@@ -195,7 +195,7 @@ export default {
<template>
<div class="gl-display-flex">
<div :class="columnClass" class="linked-pipelines-column">
- <div data-testid="linked-column-title" class="stage-name" :class="computedTitleClasses">
+ <div data-testid="linked-column-title" :class="computedTitleClasses">
{{ columnTitle }}
</div>
<ul class="gl-pl-0">
@@ -224,7 +224,7 @@ export default {
<pipeline-graph
v-if="isExpanded(pipeline.id)"
:type="type"
- class="d-inline-block gl-mt-n2"
+ class="gl-inline-block gl-mt-n2"
:config-paths="configPaths"
:pipeline="currentPipeline"
:computed-pipeline-info="getPipelineLayers(pipeline.id)"
diff --git a/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue b/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue
index d34ae8036ed..b0f375c9aeb 100644
--- a/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue
+++ b/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue
@@ -4,8 +4,6 @@ import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { reportToSentry } from '../../utils';
import MainGraphWrapper from '../graph_shared/main_graph_wrapper.vue';
import ActionComponent from '../jobs_shared/action_component.vue';
-import { accessValue } from './accessors';
-import { GRAPHQL } from './constants';
import JobGroupDropdown from './job_group_dropdown.vue';
import JobItem from './job_item.vue';
@@ -65,6 +63,21 @@ export default {
required: true,
},
},
+ jobClasses: [
+ 'gl-py-3',
+ 'gl-px-4',
+ 'gl-border-gray-100',
+ 'gl-border-solid',
+ 'gl-border-1',
+ 'gl-bg-white',
+ 'gl-rounded-7',
+ 'gl-hover-bg-gray-50',
+ 'gl-focus-bg-gray-50',
+ 'gl-hover-text-gray-900',
+ 'gl-focus-text-gray-900',
+ 'gl-hover-border-gray-200',
+ 'gl-focus-border-gray-200',
+ ],
titleClasses: [
'gl-font-weight-bold',
'gl-pipeline-job-width',
@@ -97,7 +110,7 @@ export default {
},
methods: {
getGroupId(group) {
- return accessValue(GRAPHQL, 'groupId', group);
+ return group.name;
},
groupId(group) {
return `ci-badge-${escape(group.name)}`;
@@ -134,7 +147,7 @@ export default {
:action-icon="action.icon"
:tooltip-text="action.title"
:link="action.path"
- class="js-stage-action stage-action rounded"
+ class="js-stage-action"
@pipelineActionRequestComplete="$emit('refreshPipelineGraph')"
/>
</div>
@@ -157,7 +170,7 @@ export default {
:pipeline-expanded="pipelineExpanded"
:pipeline-id="pipelineId"
:stage-name="showStageName ? group.stageName : ''"
- css-class-job-name="gl-build-content"
+ :css-class-job-name="$options.jobClasses"
:class="[
{ 'gl-opacity-3': isFadedOut(group.name) },
'gl-transition-duration-slow gl-transition-timing-function-ease',
@@ -169,6 +182,7 @@ export default {
:group="group"
:stage-name="showStageName ? group.stageName : ''"
:pipeline-id="pipelineId"
+ :css-class-job-name="$options.jobClasses"
/>
</div>
</div>
diff --git a/app/assets/javascripts/pipelines/components/header_component.vue b/app/assets/javascripts/pipelines/components/header_component.vue
index 5db2b604956..4db6a3c9fd8 100644
--- a/app/assets/javascripts/pipelines/components/header_component.vue
+++ b/app/assets/javascripts/pipelines/components/header_component.vue
@@ -218,7 +218,7 @@ export default {
:status="pipeline.detailedStatus"
:time="pipeline.createdAt"
:user="pipeline.user"
- :item-id="Number(pipelineId)"
+ :item-id="pipelineId"
item-name="Pipeline"
>
<gl-button
diff --git a/app/assets/javascripts/pipelines/components/parsing_utils.js b/app/assets/javascripts/pipelines/components/parsing_utils.js
index 7e7f0572faf..fa7330ce890 100644
--- a/app/assets/javascripts/pipelines/components/parsing_utils.js
+++ b/app/assets/javascripts/pipelines/components/parsing_utils.js
@@ -1,55 +1,18 @@
import { memoize } from 'lodash';
+import { createNodeDict } from '../utils';
import { createSankey } from './dag/drawing_utils';
/*
- The following functions are the main engine in transforming the data as
- received from the endpoint into the format the d3 graph expects.
-
- Input is of the form:
- [nodes]
- nodes: [{category, name, jobs, size}]
- category is the stage name
- name is a group name; in the case that the group has one job, it is
- also the job name
- size is the number of parallel jobs
- jobs: [{ name, needs}]
- job name is either the same as the group name or group x/y
- needs: [job-names]
- needs is an array of job-name strings
-
- Output is of the form:
- { nodes: [node], links: [link] }
- node: { name, category }, + unused info passed through
- link: { source, target, value }, with source & target being node names
- and value being a constant
-
- We create nodes in the GraphQL update function, and then here we create the node dictionary,
- then create links, and then dedupe the links, so that in the case where
- job 4 depends on job 1 and job 2, and job 2 depends on job 1, we show only a single link
- from job 1 to job 2 then another from job 2 to job 4.
-
- CREATE LINKS
- nodes.name -> target
- nodes.name.needs.each -> source (source is the name of the group, not the parallel job)
- 10 -> value (constant)
- */
-
-export const createNodeDict = (nodes) => {
- return nodes.reduce((acc, node) => {
- const newNode = {
- ...node,
- needs: node.jobs.map((job) => job.needs || []).flat(),
- };
-
- if (node.size > 1) {
- node.jobs.forEach((job) => {
- acc[job.name] = newNode;
- });
- }
+ A peformant alternative to lodash's isEqual. Because findIndex always finds
+ the first instance of a match, if the found index is not the first, we know
+ it is in fact a duplicate.
+*/
+const deduplicate = (item, itemIndex, arr) => {
+ const foundIdx = arr.findIndex((test) => {
+ return test.source === item.source && test.target === item.target;
+ });
- acc[node.name] = newNode;
- return acc;
- }, {});
+ return foundIdx === itemIndex;
};
export const makeLinksFromNodes = (nodes, nodeDict) => {
@@ -83,7 +46,8 @@ export const getAllAncestors = (nodes, nodeDict) => {
return nodeDict[node]?.needs || '';
})
.flat()
- .filter(Boolean);
+ .filter(Boolean)
+ .filter(deduplicate);
if (needs.length) {
return [...needs, ...getAllAncestors(needs, nodeDict)];
@@ -108,29 +72,15 @@ export const filterByAncestors = (links, nodeDict) =>
const targetNode = target;
const targetNodeNeeds = nodeDict[targetNode].needs;
const targetNodeNeedsMinusSource = targetNodeNeeds.filter((need) => need !== source);
-
const allAncestors = getAllAncestors(targetNodeNeedsMinusSource, nodeDict);
return !allAncestors.includes(source);
});
-/*
- A peformant alternative to lodash's isEqual. Because findIndex always finds
- the first instance of a match, if the found index is not the first, we know
- it is in fact a duplicate.
-*/
-const deduplicate = (item, itemIndex, arr) => {
- const foundIdx = arr.findIndex((test) => {
- return test.source === item.source && test.target === item.target;
- });
-
- return foundIdx === itemIndex;
-};
-
export const parseData = (nodes) => {
const nodeDict = createNodeDict(nodes);
const allLinks = makeLinksFromNodes(nodes, nodeDict);
- const filteredLinks = filterByAncestors(allLinks, nodeDict);
- const links = filteredLinks.filter(deduplicate);
+ const filteredLinks = allLinks.filter(deduplicate);
+ const links = filterByAncestors(filteredLinks, nodeDict);
return { nodes, links };
};
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_multi_actions.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_multi_actions.vue
index 40ee071f1f5..3470c963ade 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_multi_actions.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_multi_actions.vue
@@ -100,7 +100,7 @@ export default {
<gl-loading-icon v-if="isLoading" size="sm" />
- <gl-dropdown-item v-if="!artifacts.length" data-testid="artifacts-empty-message">
+ <gl-dropdown-item v-if="!artifacts.length && !isLoading" data-testid="artifacts-empty-message">
{{ $options.i18n.emptyArtifactsMessage }}
</gl-dropdown-item>
@@ -110,6 +110,7 @@ export default {
:href="artifact.path"
rel="nofollow"
download
+ class="gl-word-break-word"
data-testid="artifact-item"
>
<gl-sprintf :message="$options.i18n.downloadArtifact">
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_stop_modal.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_stop_modal.vue
index 24b5c85c9d6..3bd149fc782 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_stop_modal.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_stop_modal.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { GlLink, GlModal } from '@gitlab/ui';
import { isEmpty } from 'lodash';
import { __, s__, sprintf } from '~/locale';
@@ -72,7 +71,7 @@ export default {
:action-cancel="cancelProps"
@primary="emitSubmit($event)"
>
- <p v-html="modalText"></p>
+ <p v-html="modalText /* eslint-disable-line vue/no-v-html */"></p>
<p v-if="pipeline">
<ci-icon
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_filtered_search.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_filtered_search.vue
index 0b70e74b8ff..2dfdaa0ea28 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_filtered_search.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_filtered_search.vue
@@ -39,7 +39,7 @@ export default {
return this.value.map((i) => i.type);
},
tokens() {
- const tokens = [
+ return [
{
type: this.$options.userType,
icon: 'user',
@@ -77,20 +77,15 @@ export default {
token: PipelineStatusToken,
operators: OPERATOR_IS_ONLY,
},
- ];
-
- if (gon.features.pipelineSourceFilter) {
- tokens.push({
+ {
type: this.$options.sourceType,
icon: 'trigger-source',
title: s__('Pipeline|Source'),
unique: true,
token: PipelineSourceToken,
operators: OPERATOR_IS_ONLY,
- });
- }
-
- return tokens;
+ },
+ ];
},
parsedParams() {
return map(this.params, (val, key) => ({
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue
index 2475d958e3c..12ee82f0390 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue
@@ -212,6 +212,7 @@ export default {
<linked-pipelines-mini-list
v-if="item.triggered.length"
:triggered="item.triggered"
+ :pipeline-path="item.path"
data-testid="mini-graph-downstream"
/>
</div>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/tokens/constants.js b/app/assets/javascripts/pipelines/components/pipelines_list/tokens/constants.js
new file mode 100644
index 00000000000..02baa76f627
--- /dev/null
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/tokens/constants.js
@@ -0,0 +1,52 @@
+import { s__ } from '~/locale';
+
+export const PIPELINE_SOURCES = [
+ {
+ text: s__('Pipeline|Source|Push'),
+ value: 'push',
+ },
+ {
+ text: s__('Pipeline|Source|Web'),
+ value: 'web',
+ },
+ {
+ text: s__('Pipeline|Source|Trigger'),
+ value: 'trigger',
+ },
+ {
+ text: s__('Pipeline|Source|Schedule'),
+ value: 'schedule',
+ },
+ {
+ text: s__('Pipeline|Source|API'),
+ value: 'api',
+ },
+ {
+ text: s__('Pipeline|Source|External'),
+ value: 'external',
+ },
+ {
+ text: s__('Pipeline|Source|Pipeline'),
+ value: 'pipeline',
+ },
+ {
+ text: s__('Pipeline|Source|Chat'),
+ value: 'chat',
+ },
+ {
+ text: s__('Pipeline|Source|Web IDE'),
+ value: 'webide',
+ },
+ {
+ text: s__('Pipeline|Source|Merge Request'),
+ value: 'merge_request_event',
+ },
+ {
+ text: s__('Pipeline|Source|External Pull Request'),
+ value: 'external_pull_request_event',
+ },
+ {
+ text: s__('Pipeline|Source|Parent Pipeline'),
+ value: 'parent_pipeline',
+ },
+];
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_source_token.vue b/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_source_token.vue
index 71efa8b2ab4..9643ddfbd21 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_source_token.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_source_token.vue
@@ -1,8 +1,9 @@
<script>
import { GlFilteredSearchToken, GlFilteredSearchSuggestion } from '@gitlab/ui';
-import { s__ } from '~/locale';
+import { PIPELINE_SOURCES } from 'ee_else_ce/pipelines/components/pipelines_list/tokens/constants';
export default {
+ PIPELINE_SOURCES,
components: {
GlFilteredSearchToken,
GlFilteredSearchSuggestion,
@@ -18,68 +19,8 @@ export default {
},
},
computed: {
- sources() {
- return [
- {
- text: s__('Pipeline|Source|Push'),
- value: 'push',
- },
- {
- text: s__('Pipeline|Source|Web'),
- value: 'web',
- },
- {
- text: s__('Pipeline|Source|Trigger'),
- value: 'trigger',
- },
- {
- text: s__('Pipeline|Source|Schedule'),
- value: 'schedule',
- },
- {
- text: s__('Pipeline|Source|API'),
- value: 'api',
- },
- {
- text: s__('Pipeline|Source|External'),
- value: 'external',
- },
- {
- text: s__('Pipeline|Source|Pipeline'),
- value: 'pipeline',
- },
- {
- text: s__('Pipeline|Source|Chat'),
- value: 'chat',
- },
- {
- text: s__('Pipeline|Source|Web IDE'),
- value: 'webide',
- },
- {
- text: s__('Pipeline|Source|Merge Request'),
- value: 'merge_request_event',
- },
- {
- text: s__('Pipeline|Source|External Pull Request'),
- value: 'external_pull_request_event',
- },
- {
- text: s__('Pipeline|Source|Parent Pipeline'),
- value: 'parent_pipeline',
- },
- {
- text: s__('Pipeline|Source|On-Demand DAST Scan'),
- value: 'ondemand_dast_scan',
- },
- {
- text: s__('Pipeline|Source|On-Demand DAST Validation'),
- value: 'ondemand_dast_validation',
- },
- ];
- },
- findActiveSource() {
- return this.sources.find((source) => source.value === this.value.data);
+ activeSource() {
+ return PIPELINE_SOURCES.find((source) => source.value === this.value.data);
},
},
};
@@ -89,13 +30,13 @@ export default {
<gl-filtered-search-token v-bind="{ ...$props, ...$attrs }" v-on="$listeners">
<template #view>
<div class="gl-display-flex gl-align-items-center">
- <span>{{ findActiveSource.text }}</span>
+ <span>{{ activeSource.text }}</span>
</div>
</template>
<template #suggestions>
<gl-filtered-search-suggestion
- v-for="source in sources"
+ v-for="source in $options.PIPELINE_SOURCES"
:key="source.value"
:value="source.value"
>
diff --git a/app/assets/javascripts/pipelines/pipeline_details_bundle.js b/app/assets/javascripts/pipelines/pipeline_details_bundle.js
index c6e767d5424..ee9560e36c4 100644
--- a/app/assets/javascripts/pipelines/pipeline_details_bundle.js
+++ b/app/assets/javascripts/pipelines/pipeline_details_bundle.js
@@ -1,16 +1,10 @@
-import Vue from 'vue';
import createFlash from '~/flash';
-import { parseBoolean } from '~/lib/utils/common_utils';
import { __ } from '~/locale';
-import Translate from '~/vue_shared/translate';
-import TestReports from './components/test_reports/test_reports.vue';
import createDagApp from './pipeline_details_dag';
import { createPipelinesDetailApp } from './pipeline_details_graph';
import { createPipelineHeaderApp } from './pipeline_details_header';
import { apolloProvider } from './pipeline_shared_client';
-import createTestReportsStore from './stores/test_reports';
-
-Vue.use(Translate);
+import { createTestDetails } from './pipeline_test_details';
const SELECTORS = {
PIPELINE_DETAILS: '.js-pipeline-details-vue',
@@ -19,33 +13,6 @@ const SELECTORS = {
PIPELINE_TESTS: '#js-pipeline-tests-detail',
};
-const createTestDetails = () => {
- const el = document.querySelector(SELECTORS.PIPELINE_TESTS);
- const { blobPath, emptyStateImagePath, hasTestReport, summaryEndpoint, suiteEndpoint } =
- el?.dataset || {};
- const testReportsStore = createTestReportsStore({
- blobPath,
- summaryEndpoint,
- suiteEndpoint,
- });
-
- // eslint-disable-next-line no-new
- new Vue({
- el,
- components: {
- TestReports,
- },
- provide: {
- emptyStateImagePath,
- hasTestReport: parseBoolean(hasTestReport),
- },
- store: testReportsStore,
- render(createElement) {
- return createElement('test-reports');
- },
- });
-};
-
export default async function initPipelineDetailsBundle() {
const { dataset } = document.querySelector(SELECTORS.PIPELINE_DETAILS);
@@ -65,6 +32,27 @@ export default async function initPipelineDetailsBundle() {
});
}
- createDagApp(apolloProvider);
- createTestDetails();
+ try {
+ createPipelineHeaderApp(SELECTORS.PIPELINE_HEADER, apolloProvider, dataset.graphqlResourceEtag);
+ } catch {
+ createFlash({
+ message: __('An error occurred while loading a section of this page.'),
+ });
+ }
+
+ try {
+ createDagApp(apolloProvider);
+ } catch {
+ createFlash({
+ message: __('An error occurred while loading the Needs tab.'),
+ });
+ }
+
+ try {
+ createTestDetails(SELECTORS.PIPELINE_TESTS);
+ } catch {
+ createFlash({
+ message: __('An error occurred while loading the Test Reports tab.'),
+ });
+ }
}
diff --git a/app/assets/javascripts/pipelines/pipeline_details_graph.js b/app/assets/javascripts/pipelines/pipeline_details_graph.js
index 39c3c2ea5c5..9dd5cd7b281 100644
--- a/app/assets/javascripts/pipelines/pipeline_details_graph.js
+++ b/app/assets/javascripts/pipelines/pipeline_details_graph.js
@@ -1,6 +1,5 @@
import Vue from 'vue';
import VueApollo from 'vue-apollo';
-import { GRAPHQL } from './components/graph/constants';
import PipelineGraphWrapper from './components/graph/graph_component_wrapper.vue';
import { reportToSentry } from './utils';
@@ -23,7 +22,6 @@ const createPipelinesDetailApp = (
pipelineProjectPath,
pipelineIid,
graphqlResourceEtag,
- dataMethod: GRAPHQL,
},
errorCaptured(err, _vm, info) {
reportToSentry('pipeline_details_graph', `error: ${err}, info: ${info}`);
diff --git a/app/assets/javascripts/pipelines/pipeline_test_details.js b/app/assets/javascripts/pipelines/pipeline_test_details.js
new file mode 100644
index 00000000000..46c7ec07d03
--- /dev/null
+++ b/app/assets/javascripts/pipelines/pipeline_test_details.js
@@ -0,0 +1,34 @@
+import Vue from 'vue';
+import { parseBoolean } from '~/lib/utils/common_utils';
+import Translate from '~/vue_shared/translate';
+import TestReports from './components/test_reports/test_reports.vue';
+import createTestReportsStore from './stores/test_reports';
+
+Vue.use(Translate);
+
+export const createTestDetails = (selector) => {
+ const el = document.querySelector(selector);
+ const { blobPath, emptyStateImagePath, hasTestReport, summaryEndpoint, suiteEndpoint } =
+ el?.dataset || {};
+ const testReportsStore = createTestReportsStore({
+ blobPath,
+ summaryEndpoint,
+ suiteEndpoint,
+ });
+
+ // eslint-disable-next-line no-new
+ new Vue({
+ el,
+ components: {
+ TestReports,
+ },
+ provide: {
+ emptyStateImagePath,
+ hasTestReport: parseBoolean(hasTestReport),
+ },
+ store: testReportsStore,
+ render(createElement) {
+ return createElement('test-reports');
+ },
+ });
+};
diff --git a/app/assets/javascripts/pipelines/utils.js b/app/assets/javascripts/pipelines/utils.js
index 02a9e5b7fc6..e28eb74fb1b 100644
--- a/app/assets/javascripts/pipelines/utils.js
+++ b/app/assets/javascripts/pipelines/utils.js
@@ -1,8 +1,58 @@
import * as Sentry from '@sentry/browser';
import { pickBy } from 'lodash';
-import { createNodeDict } from './components/parsing_utils';
import { SUPPORTED_FILTER_PARAMETERS } from './constants';
+/*
+ The following functions are the main engine in transforming the data as
+ received from the endpoint into the format the d3 graph expects.
+
+ Input is of the form:
+ [nodes]
+ nodes: [{category, name, jobs, size}]
+ category is the stage name
+ name is a group name; in the case that the group has one job, it is
+ also the job name
+ size is the number of parallel jobs
+ jobs: [{ name, needs}]
+ job name is either the same as the group name or group x/y
+ needs: [job-names]
+ needs is an array of job-name strings
+
+ Output is of the form:
+ { nodes: [node], links: [link] }
+ node: { name, category }, + unused info passed through
+ link: { source, target, value }, with source & target being node names
+ and value being a constant
+
+ We create nodes in the GraphQL update function, and then here we create the node dictionary,
+ then create links, and then dedupe the links, so that in the case where
+ job 4 depends on job 1 and job 2, and job 2 depends on job 1, we show only a single link
+ from job 1 to job 2 then another from job 2 to job 4.
+
+ CREATE LINKS
+ nodes.name -> target
+ nodes.name.needs.each -> source (source is the name of the group, not the parallel job)
+ 10 -> value (constant)
+ */
+
+export const createNodeDict = (nodes) => {
+ return nodes.reduce((acc, node) => {
+ const newNode = {
+ ...node,
+ needs: node.jobs.map((job) => job.needs || []).flat(),
+ };
+
+ if (node.size > 1) {
+ node.jobs.forEach((job) => {
+ acc[job.name] = newNode;
+ });
+ }
+
+ acc[node.name] = newNode;
+ return acc;
+ }, {});
+};
+
export const validateParams = (params) => {
return pickBy(params, (val, key) => SUPPORTED_FILTER_PARAMETERS.includes(key) && val);
};
diff --git a/app/assets/javascripts/popovers/components/popovers.vue b/app/assets/javascripts/popovers/components/popovers.vue
index 05a209a97ad..a758503b56b 100644
--- a/app/assets/javascripts/popovers/components/popovers.vue
+++ b/app/assets/javascripts/popovers/components/popovers.vue
@@ -1,11 +1,5 @@
<script>
-// We can't use v-safe-html here as the popover's title or content might contains SVGs that would
-// be stripped by the directive's sanitizer. Instead, we fallback on v-html and we use GitLab's
-// dompurify config that lets SVGs be rendered properly.
-// Context: https://gitlab.com/gitlab-org/gitlab/-/issues/247207
-/* eslint-disable vue/no-v-html */
-import { GlPopover } from '@gitlab/ui';
-import { sanitize } from '~/lib/dompurify';
+import { GlPopover, GlSafeHtmlDirective } from '@gitlab/ui';
const newPopover = (element) => {
const { content, html, placement, title, triggers = 'focus' } = element.dataset;
@@ -24,6 +18,9 @@ export default {
components: {
GlPopover,
},
+ directives: {
+ SafeHtml: GlSafeHtmlDirective,
+ },
data() {
return {
popovers: [],
@@ -71,9 +68,9 @@ export default {
popoverExists(element) {
return this.popovers.some((popover) => popover.target === element);
},
- getSafeHtml(html) {
- return sanitize(html);
- },
+ },
+ safeHtmlConfig: {
+ ADD_TAGS: ['use'], // to support icon SVGs
},
};
</script>
@@ -82,10 +79,10 @@ export default {
<div>
<gl-popover v-for="(popover, index) in popovers" :key="index" v-bind="popover">
<template #title>
- <span v-if="popover.html" v-html="getSafeHtml(popover.title)"></span>
+ <span v-if="popover.html" v-safe-html:[$options.safeHtmlConfig]="popover.title"></span>
<span v-else>{{ popover.title }}</span>
</template>
- <span v-if="popover.html" v-html="getSafeHtml(popover.content)"></span>
+ <span v-if="popover.html" v-safe-html:[$options.safeHtmlConfig]="popover.content"></span>
<span v-else>{{ popover.content }}</span>
</gl-popover>
</div>
diff --git a/app/assets/javascripts/project_select_combo_button.js b/app/assets/javascripts/project_select_combo_button.js
index 4b14df21f05..fd45d643ecc 100644
--- a/app/assets/javascripts/project_select_combo_button.js
+++ b/app/assets/javascripts/project_select_combo_button.js
@@ -30,7 +30,7 @@ export default class ProjectSelectComboButton {
}
initLocalStorage() {
- const localStorageIsSafe = AccessorUtilities.isLocalStorageAccessSafe();
+ const localStorageIsSafe = AccessorUtilities.canUseLocalStorage();
if (localStorageIsSafe) {
this.localStorageKey = [
diff --git a/app/assets/javascripts/projects/commit_box/info/components/commit_box_pipeline_mini_graph.vue b/app/assets/javascripts/projects/commit_box/info/components/commit_box_pipeline_mini_graph.vue
index a4a1cb5584d..da14b1e8470 100644
--- a/app/assets/javascripts/projects/commit_box/info/components/commit_box_pipeline_mini_graph.vue
+++ b/app/assets/javascripts/projects/commit_box/info/components/commit_box_pipeline_mini_graph.vue
@@ -87,6 +87,7 @@ export default {
<linked-pipelines-mini-list
v-if="hasDownstream"
:triggered="downstreamPipelines"
+ :pipeline-path="pipeline.path"
data-testid="commit-box-mini-graph-downstream"
/>
</div>
diff --git a/app/assets/javascripts/projects/commit_box/info/graphql/queries/get_linked_pipelines.query.graphql b/app/assets/javascripts/projects/commit_box/info/graphql/queries/get_linked_pipelines.query.graphql
index f7e930bb3f2..ee18c70b6fd 100644
--- a/app/assets/javascripts/projects/commit_box/info/graphql/queries/get_linked_pipelines.query.graphql
+++ b/app/assets/javascripts/projects/commit_box/info/graphql/queries/get_linked_pipelines.query.graphql
@@ -1,6 +1,7 @@
query getLinkedPipelines($fullPath: ID!, $iid: ID!) {
project(fullPath: $fullPath) {
pipeline(iid: $iid) {
+ path
downstream {
nodes {
id
diff --git a/app/assets/javascripts/projects/commit_box/info/init_commit_pipeline_mini_graph.js b/app/assets/javascripts/projects/commit_box/info/init_commit_pipeline_mini_graph.js
index 1d4ec4c110b..2505c47147f 100644
--- a/app/assets/javascripts/projects/commit_box/info/init_commit_pipeline_mini_graph.js
+++ b/app/assets/javascripts/projects/commit_box/info/init_commit_pipeline_mini_graph.js
@@ -5,7 +5,12 @@ import createDefaultClient from '~/lib/graphql';
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
- defaultClient: createDefaultClient(),
+ defaultClient: createDefaultClient(
+ {},
+ {
+ assumeImmutableResults: true,
+ },
+ ),
});
export const initCommitPipelineMiniGraph = async (selector = '.js-commit-pipeline-mini-graph') => {
diff --git a/app/assets/javascripts/projects/pipelines/charts/components/pipeline_charts.vue b/app/assets/javascripts/projects/pipelines/charts/components/pipeline_charts.vue
index d3cadcd2bd5..ecd2288eb2f 100644
--- a/app/assets/javascripts/projects/pipelines/charts/components/pipeline_charts.vue
+++ b/app/assets/javascripts/projects/pipelines/charts/components/pipeline_charts.vue
@@ -199,6 +199,16 @@ export default {
},
];
},
+ chartOptions() {
+ return {
+ ...this.$options.timesChartOptions,
+ yAxis: {
+ axisLabel: {
+ formatter: (value) => value,
+ },
+ },
+ };
+ },
},
methods: {
hideAlert() {
@@ -314,7 +324,7 @@ export default {
<strong>{{ __('Pipeline durations for the last 30 commits') }}</strong>
<gl-column-chart
:height="$options.chartContainerHeight"
- :option="$options.timesChartOptions"
+ :option="chartOptions"
:bars="timesChartTransformedData"
:y-axis-title="__('Minutes')"
:x-axis-title="__('Commit')"
diff --git a/app/assets/javascripts/projects/pipelines/charts/index.js b/app/assets/javascripts/projects/pipelines/charts/index.js
index 5f5ee44c204..f7ea89068a0 100644
--- a/app/assets/javascripts/projects/pipelines/charts/index.js
+++ b/app/assets/javascripts/projects/pipelines/charts/index.js
@@ -7,7 +7,7 @@ import ProjectPipelinesCharts from './components/app.vue';
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
- defaultClient: createDefaultClient(),
+ defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
});
const mountPipelineChartsApp = (el) => {
diff --git a/app/assets/javascripts/projects/project_new.js b/app/assets/javascripts/projects/project_new.js
index ee02f446795..ebd20583a1c 100644
--- a/app/assets/javascripts/projects/project_new.js
+++ b/app/assets/javascripts/projects/project_new.js
@@ -71,6 +71,17 @@ const deriveProjectPathFromUrl = ($projectImportUrl) => {
}
};
+const bindHowToImport = () => {
+ $('.how_to_import_link').on('click', (e) => {
+ e.preventDefault();
+ $(e.currentTarget).next('.modal').show();
+ });
+
+ $('.modal-header .close').on('click', () => {
+ $('.modal').hide();
+ });
+};
+
const bindEvents = () => {
const $newProjectForm = $('#new_project');
const $projectImportUrl = $('#project_import_url');
@@ -88,14 +99,7 @@ const bindEvents = () => {
return;
}
- $('.how_to_import_link').on('click', (e) => {
- e.preventDefault();
- $(e.currentTarget).next('.modal').show();
- });
-
- $('.modal-header .close').on('click', () => {
- $('.modal').hide();
- });
+ bindHowToImport();
$('.btn_import_gitlab_project').on('click', () => {
const importHref = $('a.btn_import_gitlab_project').attr('href');
@@ -174,3 +178,5 @@ export default {
onProjectNameChange,
onProjectPathChange,
};
+
+export { bindHowToImport };
diff --git a/app/assets/javascripts/projects/settings/components/shared_runners_toggle.vue b/app/assets/javascripts/projects/settings/components/shared_runners_toggle.vue
index e4edb950a1e..91d8fca0487 100644
--- a/app/assets/javascripts/projects/settings/components/shared_runners_toggle.vue
+++ b/app/assets/javascripts/projects/settings/components/shared_runners_toggle.vue
@@ -43,6 +43,7 @@ export default {
isSharedRunnerEnabled: this.isEnabled,
errorMessage: null,
successfulValidation: false,
+ ccAlertDismissed: false,
};
},
computed: {
@@ -50,7 +51,8 @@ export default {
return (
this.isCreditCardValidationRequired &&
!this.isSharedRunnerEnabled &&
- !this.successfulValidation
+ !this.successfulValidation &&
+ !this.ccAlertDismissed
);
},
},
@@ -89,6 +91,7 @@ export default {
class="gl-pb-5"
:custom-message="$options.i18n.REQUIRES_VALIDATION_TEXT"
@verifiedCreditCard="creditCardValidated"
+ @dismiss="ccAlertDismissed = true"
/>
<gl-toggle
diff --git a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue
index 34d53e2de0c..fe2d376f1da 100644
--- a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue
+++ b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue
@@ -1,5 +1,13 @@
<script>
-import { GlButton, GlFormSelect, GlToggle, GlLoadingIcon, GlSprintf } from '@gitlab/ui';
+import {
+ GlButton,
+ GlFormSelect,
+ GlToggle,
+ GlLoadingIcon,
+ GlSprintf,
+ GlFormInput,
+ GlLink,
+} from '@gitlab/ui';
import { __ } from '~/locale';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
@@ -14,6 +22,8 @@ export default {
GlToggle,
GlLoadingIcon,
GlSprintf,
+ GlFormInput,
+ GlLink,
},
props: {
isEnabled: {
@@ -148,17 +158,37 @@ export default {
<span class="sr-only">{{ __('Fetching incoming email') }}</span>
</template>
- <template v-if="hasProjectKeySupport">
- <label for="service-desk-project-suffix" class="mt-3">
- {{ __('Project name suffix') }}
- </label>
- <input id="service-desk-project-suffix" v-model.trim="projectKey" class="form-control" />
- <span class="form-text text-muted">
- {{
- __('A string appended to the project path to form the Service Desk email address.')
- }}
- </span>
- </template>
+ <label for="service-desk-project-suffix" class="mt-3">
+ {{ __('Project name suffix') }}
+ </label>
+ <gl-form-input
+ v-if="hasProjectKeySupport"
+ id="service-desk-project-suffix"
+ v-model.trim="projectKey"
+ data-testid="project-suffix"
+ class="form-control"
+ />
+ <span v-if="hasProjectKeySupport" class="form-text text-muted">
+ {{ __('A string appended to the project path to form the Service Desk email address.') }}
+ </span>
+ <span v-else class="form-text text-muted">
+ <gl-sprintf
+ :message="
+ __(
+ 'To add a custom suffix, set up a Service Desk email address. %{linkStart}Learn more.%{linkEnd}',
+ )
+ "
+ >
+ <template #link="{ content }">
+ <gl-link
+ href="https://docs.gitlab.com/ee/user/project/service_desk.html#using-a-custom-email-address"
+ target="_blank"
+ class="gl-text-blue-600 font-size-inherit"
+ >{{ content }}
+ </gl-link>
+ </template>
+ </gl-sprintf>
+ </span>
<label for="service-desk-template-select" class="mt-3">
{{ __('Template to append to all Service Desk issues') }}
diff --git a/app/assets/javascripts/projects/storage_counter/components/app.vue b/app/assets/javascripts/projects/storage_counter/components/app.vue
new file mode 100644
index 00000000000..1a911ea3d9b
--- /dev/null
+++ b/app/assets/javascripts/projects/storage_counter/components/app.vue
@@ -0,0 +1,106 @@
+<script>
+import { GlAlert, GlLink, GlLoadingIcon } from '@gitlab/ui';
+import { sprintf } from '~/locale';
+import UsageGraph from '~/vue_shared/components/storage_counter/usage_graph.vue';
+import {
+ ERROR_MESSAGE,
+ LEARN_MORE_LABEL,
+ USAGE_QUOTAS_LABEL,
+ TOTAL_USAGE_TITLE,
+ TOTAL_USAGE_SUBTITLE,
+ TOTAL_USAGE_DEFAULT_TEXT,
+ HELP_LINK_ARIA_LABEL,
+} from '../constants';
+import getProjectStorageCount from '../queries/project_storage.query.graphql';
+import { parseGetProjectStorageResults } from '../utils';
+import StorageTable from './storage_table.vue';
+
+export default {
+ name: 'StorageCounterApp',
+ components: {
+ GlAlert,
+ GlLink,
+ GlLoadingIcon,
+ StorageTable,
+ UsageGraph,
+ },
+ inject: ['projectPath', 'helpLinks'],
+ apollo: {
+ project: {
+ query: getProjectStorageCount,
+ variables() {
+ return {
+ fullPath: this.projectPath,
+ };
+ },
+ update(data) {
+ return parseGetProjectStorageResults(data, this.helpLinks);
+ },
+ error() {
+ this.error = ERROR_MESSAGE;
+ },
+ },
+ },
+ data() {
+ return {
+ project: {},
+ error: '',
+ };
+ },
+ computed: {
+ totalUsage() {
+ return this.project?.storage?.totalUsage || TOTAL_USAGE_DEFAULT_TEXT;
+ },
+ storageTypes() {
+ return this.project?.storage?.storageTypes || [];
+ },
+ },
+ methods: {
+ clearError() {
+ this.error = '';
+ },
+ helpLinkAriaLabel(linkTitle) {
+ return sprintf(HELP_LINK_ARIA_LABEL, {
+ linkTitle,
+ });
+ },
+ },
+ LEARN_MORE_LABEL,
+ USAGE_QUOTAS_LABEL,
+ TOTAL_USAGE_TITLE,
+ TOTAL_USAGE_SUBTITLE,
+};
+</script>
+<template>
+ <gl-loading-icon v-if="$apollo.queries.project.loading" class="gl-mt-5" size="md" />
+ <gl-alert v-else-if="error" variant="danger" @dismiss="clearError">
+ {{ error }}
+ </gl-alert>
+ <div v-else>
+ <div class="gl-pt-5 gl-px-3">
+ <div class="gl-display-flex gl-justify-content-space-between gl-align-items-center">
+ <div>
+ <p class="gl-m-0 gl-font-lg gl-font-weight-bold">{{ $options.TOTAL_USAGE_TITLE }}</p>
+ <p class="gl-m-0 gl-text-gray-400">
+ {{ $options.TOTAL_USAGE_SUBTITLE }}
+ <gl-link
+ :href="helpLinks.usageQuotasHelpPagePath"
+ target="_blank"
+ :aria-label="helpLinkAriaLabel($options.USAGE_QUOTAS_LABEL)"
+ data-testid="usage-quotas-help-link"
+ >
+ {{ $options.LEARN_MORE_LABEL }}
+ </gl-link>
+ </p>
+ </div>
+ <p class="gl-m-0 gl-font-size-h-display gl-font-weight-bold" data-testid="total-usage">
+ {{ totalUsage }}
+ </p>
+ </div>
+ </div>
+ <div v-if="project.statistics" class="gl-w-full">
+ <usage-graph :root-storage-statistics="project.statistics" :limit="0" />
+ </div>
+ <storage-table :storage-types="storageTypes" />
+ </div>
+</template>
diff --git a/app/assets/javascripts/projects/storage_counter/components/storage_table.vue b/app/assets/javascripts/projects/storage_counter/components/storage_table.vue
new file mode 100644
index 00000000000..7047fd925fb
--- /dev/null
+++ b/app/assets/javascripts/projects/storage_counter/components/storage_table.vue
@@ -0,0 +1,78 @@
+<script>
+import { GlLink, GlIcon, GlTable, GlSprintf } from '@gitlab/ui';
+import { numberToHumanSize } from '~/lib/utils/number_utils';
+import { thWidthClass } from '~/lib/utils/table_utility';
+import { sprintf } from '~/locale';
+import { PROJECT_TABLE_LABELS, HELP_LINK_ARIA_LABEL } from '../constants';
+
+export default {
+ name: 'StorageTable',
+ components: {
+ GlLink,
+ GlIcon,
+ GlTable,
+ GlSprintf,
+ },
+ props: {
+ storageTypes: {
+ type: Array,
+ required: true,
+ },
+ },
+ methods: {
+ helpLinkAriaLabel(linkTitle) {
+ return sprintf(HELP_LINK_ARIA_LABEL, {
+ linkTitle,
+ });
+ },
+ },
+ projectTableFields: [
+ {
+ key: 'storageType',
+ label: PROJECT_TABLE_LABELS.STORAGE_TYPE,
+ thClass: thWidthClass(90),
+ sortable: true,
+ },
+ {
+ key: 'value',
+ label: PROJECT_TABLE_LABELS.VALUE,
+ thClass: thWidthClass(10),
+ sortable: true,
+ formatter: (value) => {
+ return numberToHumanSize(value, 1);
+ },
+ },
+ ],
+};
+</script>
+<template>
+ <gl-table :items="storageTypes" :fields="$options.projectTableFields">
+ <template #cell(storageType)="{ item }">
+ <p class="gl-font-weight-bold gl-mb-0" :data-testid="`${item.storageType.id}-name`">
+ {{ item.storageType.name }}
+ <gl-link
+ v-if="item.storageType.helpPath"
+ :href="item.storageType.helpPath"
+ target="_blank"
+ :aria-label="helpLinkAriaLabel(item.storageType.name)"
+ :data-testid="`${item.storageType.id}-help-link`"
+ >
+ <gl-icon name="question" :size="12" />
+ </gl-link>
+ </p>
+ <p class="gl-mb-0" :data-testid="`${item.storageType.id}-description`">
+ {{ item.storageType.description }}
+ </p>
+ <p v-if="item.storageType.warningMessage" class="gl-mb-0 gl-font-sm">
+ <gl-icon name="warning" :size="12" />
+ <gl-sprintf :message="item.storageType.warningMessage">
+ <template #warningLink="{ content }">
+ <gl-link :href="item.storageType.warningLink" target="_blank" class="gl-font-sm">{{
+ content
+ }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </p>
+ </template>
+ </gl-table>
+</template>
diff --git a/app/assets/javascripts/projects/storage_counter/constants.js b/app/assets/javascripts/projects/storage_counter/constants.js
new file mode 100644
index 00000000000..d9b28abfbe7
--- /dev/null
+++ b/app/assets/javascripts/projects/storage_counter/constants.js
@@ -0,0 +1,61 @@
+import { s__, __ } from '~/locale';
+
+export const PROJECT_STORAGE_TYPES = [
+ {
+ id: 'buildArtifactsSize',
+ name: s__('UsageQuota|Artifacts'),
+ description: s__('UsageQuota|Pipeline artifacts and job artifacts, created with CI/CD.'),
+ warningMessage: s__(
+ 'UsageQuota|There is a known issue with Artifact storage where the total could be incorrect for some projects. More details and progress are available in %{warningLinkStart}the epic%{warningLinkEnd}.',
+ ),
+ warningLink: 'https://gitlab.com/groups/gitlab-org/-/epics/5380',
+ },
+ {
+ id: 'lfsObjectsSize',
+ name: s__('UsageQuota|LFS Storage'),
+ description: s__('UsageQuota|Audio samples, videos, datasets, and graphics.'),
+ },
+ {
+ id: 'packagesSize',
+ name: s__('UsageQuota|Packages'),
+ description: s__('UsageQuota|Code packages and container images.'),
+ },
+ {
+ id: 'repositorySize',
+ name: s__('UsageQuota|Repository'),
+ description: s__('UsageQuota|Git repository, managed by the Gitaly service.'),
+ },
+ {
+ id: 'snippetsSize',
+ name: s__('UsageQuota|Snippets'),
+ description: s__('UsageQuota|Shared bits of code and text.'),
+ },
+ {
+ id: 'uploadsSize',
+ name: s__('UsageQuota|Uploads'),
+ description: s__('UsageQuota|File attachments and smaller design graphics.'),
+ },
+ {
+ id: 'wikiSize',
+ name: s__('UsageQuota|Wiki'),
+ description: s__('UsageQuota|Wiki content.'),
+ },
+];
+
+export const PROJECT_TABLE_LABELS = {
+ STORAGE_TYPE: s__('UsageQuota|Storage type'),
+ VALUE: s__('UsageQuota|Usage'),
+};
+
+export const ERROR_MESSAGE = s__(
+ 'UsageQuota|Something went wrong while fetching project storage statistics',
+);
+
+export const LEARN_MORE_LABEL = s__('Learn more.');
+export const USAGE_QUOTAS_LABEL = s__('UsageQuota|Usage Quotas');
+export const HELP_LINK_ARIA_LABEL = s__('UsageQuota|%{linkTitle} help link');
+export const TOTAL_USAGE_DEFAULT_TEXT = __('N/A');
+export const TOTAL_USAGE_TITLE = s__('UsageQuota|Usage Breakdown');
+export const TOTAL_USAGE_SUBTITLE = s__(
+ 'UsageQuota|Includes project registry, artifacts, packages, wiki, uploads and other items.',
+);
diff --git a/app/assets/javascripts/projects/storage_counter/index.js b/app/assets/javascripts/projects/storage_counter/index.js
new file mode 100644
index 00000000000..10668f08402
--- /dev/null
+++ b/app/assets/javascripts/projects/storage_counter/index.js
@@ -0,0 +1,51 @@
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import createDefaultClient from '~/lib/graphql';
+import StorageCounterApp from './components/app.vue';
+
+Vue.use(VueApollo);
+
+export default (containerId = 'js-project-storage-count-app') => {
+ const el = document.getElementById(containerId);
+
+ if (!el) {
+ return false;
+ }
+
+ const {
+ projectPath,
+ usageQuotasHelpPagePath,
+ buildArtifactsHelpPagePath,
+ lfsObjectsHelpPagePath,
+ packagesHelpPagePath,
+ repositoryHelpPagePath,
+ snippetsHelpPagePath,
+ uploadsHelpPagePath,
+ wikiHelpPagePath,
+ } = el.dataset;
+
+ const apolloProvider = new VueApollo({
+ defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
+ });
+
+ return new Vue({
+ el,
+ apolloProvider,
+ provide: {
+ projectPath,
+ helpLinks: {
+ usageQuotasHelpPagePath,
+ buildArtifactsHelpPagePath,
+ lfsObjectsHelpPagePath,
+ packagesHelpPagePath,
+ repositoryHelpPagePath,
+ snippetsHelpPagePath,
+ uploadsHelpPagePath,
+ wikiHelpPagePath,
+ },
+ },
+ render(createElement) {
+ return createElement(StorageCounterApp);
+ },
+ });
+};
diff --git a/app/assets/javascripts/projects/storage_counter/queries/project_storage.query.graphql b/app/assets/javascripts/projects/storage_counter/queries/project_storage.query.graphql
new file mode 100644
index 00000000000..a4f2c529522
--- /dev/null
+++ b/app/assets/javascripts/projects/storage_counter/queries/project_storage.query.graphql
@@ -0,0 +1,16 @@
+query getProjectStorageCount($fullPath: ID!) {
+ project(fullPath: $fullPath) {
+ id
+ statistics {
+ buildArtifactsSize
+ pipelineArtifactsSize
+ lfsObjectsSize
+ packagesSize
+ repositorySize
+ snippetsSize
+ storageSize
+ uploadsSize
+ wikiSize
+ }
+ }
+}
diff --git a/app/assets/javascripts/projects/storage_counter/utils.js b/app/assets/javascripts/projects/storage_counter/utils.js
new file mode 100644
index 00000000000..cb26603fff5
--- /dev/null
+++ b/app/assets/javascripts/projects/storage_counter/utils.js
@@ -0,0 +1,40 @@
+import { numberToHumanSize } from '~/lib/utils/number_utils';
+import { PROJECT_STORAGE_TYPES } from './constants';
+
+/**
+ * This method parses the results from `getProjectStorageCount` call.
+ *
+ * @param {Object} data graphql result
+ * @returns {Object}
+ */
+export const parseGetProjectStorageResults = (data, helpLinks) => {
+ const projectStatistics = data?.project?.statistics;
+ if (!projectStatistics) {
+ return {};
+ }
+ const { storageSize, ...storageStatistics } = projectStatistics;
+ const storageTypes = PROJECT_STORAGE_TYPES.reduce((types, currentType) => {
+ if (!storageStatistics[currentType.id]) {
+ return types;
+ }
+
+ const helpPathKey = currentType.id.replace(`Size`, `HelpPagePath`);
+ const helpPath = helpLinks[helpPathKey];
+
+ return types.concat({
+ storageType: {
+ ...currentType,
+ helpPath,
+ },
+ value: storageStatistics[currentType.id],
+ });
+ }, []);
+
+ return {
+ storage: {
+ totalUsage: numberToHumanSize(storageSize, 1),
+ storageTypes,
+ },
+ statistics: projectStatistics,
+ };
+};
diff --git a/app/assets/javascripts/projects/terraform_notification/components/terraform_notification.vue b/app/assets/javascripts/projects/terraform_notification/components/terraform_notification.vue
index 02e31d6fbb3..668cc10c454 100644
--- a/app/assets/javascripts/projects/terraform_notification/components/terraform_notification.vue
+++ b/app/assets/javascripts/projects/terraform_notification/components/terraform_notification.vue
@@ -1,8 +1,12 @@
<script>
import { GlBanner } from '@gitlab/ui';
import { helpPagePath } from '~/helpers/help_page_helper';
-import { setCookie } from '~/lib/utils/common_utils';
import { s__ } from '~/locale';
+import Tracking from '~/tracking';
+import UserCalloutDismisser from '~/vue_shared/components/user_callout_dismisser.vue';
+import { EVENT_LABEL, DISMISS_EVENT, CLICK_EVENT } from '../constants';
+
+const trackingMixin = Tracking.mixin({ label: EVENT_LABEL });
export default {
name: 'TerraformNotification',
@@ -15,37 +19,42 @@ export default {
},
components: {
GlBanner,
+ UserCalloutDismisser,
},
- inject: ['terraformImagePath', 'bannerDismissedKey'],
- data() {
- return {
- isVisible: true,
- };
- },
+ mixins: [trackingMixin],
+ inject: ['terraformImagePath'],
computed: {
docsUrl() {
- return helpPagePath('user/infrastructure/terraform_state');
+ return helpPagePath('user/infrastructure/iac/terraform_state.md');
},
},
methods: {
handleClose() {
- setCookie(this.bannerDismissedKey, true);
- this.isVisible = false;
+ this.track(DISMISS_EVENT);
+ this.$refs.calloutDismisser.dismiss();
+ },
+ buttonClick() {
+ this.track(CLICK_EVENT);
},
},
};
</script>
<template>
- <div v-if="isVisible" class="gl-py-5">
- <gl-banner
- :title="$options.i18n.title"
- :button-text="$options.i18n.buttonText"
- :button-link="docsUrl"
- :svg-path="terraformImagePath"
- variant="promotion"
- @close="handleClose"
- >
- <p>{{ $options.i18n.description }}</p>
- </gl-banner>
- </div>
+ <user-callout-dismisser ref="calloutDismisser" feature-name="terraform_notification_dismissed">
+ <template #default="{ shouldShowCallout }">
+ <div v-if="shouldShowCallout" class="gl-py-5">
+ <gl-banner
+ :title="$options.i18n.title"
+ :button-text="$options.i18n.buttonText"
+ :button-link="docsUrl"
+ :svg-path="terraformImagePath"
+ variant="promotion"
+ @primary="buttonClick"
+ @close="handleClose"
+ >
+ <p>{{ $options.i18n.description }}</p>
+ </gl-banner>
+ </div>
+ </template>
+ </user-callout-dismisser>
</template>
diff --git a/app/assets/javascripts/projects/terraform_notification/constants.js b/app/assets/javascripts/projects/terraform_notification/constants.js
new file mode 100644
index 00000000000..029f40b2ab2
--- /dev/null
+++ b/app/assets/javascripts/projects/terraform_notification/constants.js
@@ -0,0 +1,3 @@
+export const EVENT_LABEL = 'terraform_banner';
+export const DISMISS_EVENT = 'dismiss_banner';
+export const CLICK_EVENT = 'click_button';
diff --git a/app/assets/javascripts/projects/terraform_notification/index.js b/app/assets/javascripts/projects/terraform_notification/index.js
index 0a273247930..362e71ed902 100644
--- a/app/assets/javascripts/projects/terraform_notification/index.js
+++ b/app/assets/javascripts/projects/terraform_notification/index.js
@@ -1,12 +1,18 @@
import Vue from 'vue';
-import { parseBoolean, getCookie } from '~/lib/utils/common_utils';
+import VueApollo from 'vue-apollo';
+import createDefaultClient from '~/lib/graphql';
import TerraformNotification from './components/terraform_notification.vue';
+Vue.use(VueApollo);
+
+const apolloProvider = new VueApollo({
+ defaultClient: createDefaultClient(),
+});
+
export default () => {
const el = document.querySelector('.js-terraform-notification');
- const bannerDismissedKey = 'terraform_notification_dismissed';
- if (!el || parseBoolean(getCookie(bannerDismissedKey))) {
+ if (!el) {
return false;
}
@@ -14,9 +20,9 @@ export default () => {
return new Vue({
el,
+ apolloProvider,
provide: {
terraformImagePath,
- bannerDismissedKey,
},
render: (createElement) => createElement(TerraformNotification),
});
diff --git a/app/assets/javascripts/prometheus_alerts/components/reset_key.vue b/app/assets/javascripts/prometheus_alerts/components/reset_key.vue
index c1dae75801e..eecb3573046 100644
--- a/app/assets/javascripts/prometheus_alerts/components/reset_key.vue
+++ b/app/assets/javascripts/prometheus_alerts/components/reset_key.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { GlButton, GlFormGroup, GlFormInput, GlModal, GlModalDirective } from '@gitlab/ui';
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
@@ -85,7 +84,7 @@ export default {
</p>
</div>
<div class="col-lg-9">
- <p v-html="sectionDescription"></p>
+ <p v-html="sectionDescription /* eslint-disable-line vue/no-v-html */"></p>
<gl-form-group :label="__('URL')" label-for="notify-url" label-class="label-bold">
<div class="input-group">
<gl-form-input id="notify-url" :readonly="true" :value="notifyUrl" />
diff --git a/app/assets/javascripts/protected_branches/protected_branch_create.js b/app/assets/javascripts/protected_branches/protected_branch_create.js
index d0d2c1400a7..d4b52860261 100644
--- a/app/assets/javascripts/protected_branches/protected_branch_create.js
+++ b/app/assets/javascripts/protected_branches/protected_branch_create.js
@@ -12,7 +12,7 @@ export default class ProtectedBranchCreate {
this.hasLicense = options.hasLicense;
this.$form = $('.js-new-protected-branch');
- this.isLocalStorageAvailable = AccessorUtilities.isLocalStorageAccessSafe();
+ this.isLocalStorageAvailable = AccessorUtilities.canUseLocalStorage();
this.currentProjectUserDefaults = {};
this.buildDropdowns();
this.$forcePushToggle = this.$form.find('.js-force-push-toggle');
diff --git a/app/assets/javascripts/ref/components/ref_selector.vue b/app/assets/javascripts/ref/components/ref_selector.vue
index 82963fe98fd..ce781c64006 100644
--- a/app/assets/javascripts/ref/components/ref_selector.vue
+++ b/app/assets/javascripts/ref/components/ref_selector.vue
@@ -149,8 +149,7 @@ export default {
// This method is defined here instead of in `methods`
// because we need to access the .cancel() method
// lodash attaches to the function, which is
- // made inaccessible by Vue. More info:
- // https://stackoverflow.com/a/52988020/1063392
+ // made inaccessible by Vue.
this.debouncedSearch = debounce(function search() {
this.search();
}, SEARCH_DEBOUNCE_MS);
diff --git a/app/assets/javascripts/releases/components/release_block.vue b/app/assets/javascripts/releases/components/release_block.vue
index 68bca2fc6b9..3201ca1f443 100644
--- a/app/assets/javascripts/releases/components/release_block.vue
+++ b/app/assets/javascripts/releases/components/release_block.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import $ from 'jquery';
import { isEmpty } from 'lodash';
import { scrollToElement } from '~/lib/utils/common_utils';
@@ -103,7 +102,10 @@ export default {
<evidence-block v-if="hasEvidence" :release="release" />
<div ref="gfm-content" class="card-text gl-mt-3">
- <div class="md" v-html="release.descriptionHtml"></div>
+ <div
+ class="md"
+ v-html="release.descriptionHtml /* eslint-disable-line vue/no-v-html */"
+ ></div>
</div>
</div>
diff --git a/app/assets/javascripts/reports/components/issue_body.js b/app/assets/javascripts/reports/components/issue_body.js
index 6014d9d6ad8..04e72809e62 100644
--- a/app/assets/javascripts/reports/components/issue_body.js
+++ b/app/assets/javascripts/reports/components/issue_body.js
@@ -1,18 +1,16 @@
import IssueStatusIcon from '~/reports/components/issue_status_icon.vue';
-import AccessibilityIssueBody from '../accessibility_report/components/accessibility_issue_body.vue';
-import CodequalityIssueBody from '../codequality_report/components/codequality_issue_body.vue';
-import TestIssueBody from '../grouped_test_report/components/test_issue_body.vue';
export const components = {
- AccessibilityIssueBody,
- CodequalityIssueBody,
- TestIssueBody,
+ AccessibilityIssueBody: () =>
+ import('../accessibility_report/components/accessibility_issue_body.vue'),
+ CodequalityIssueBody: () => import('../codequality_report/components/codequality_issue_body.vue'),
+ TestIssueBody: () => import('../grouped_test_report/components/test_issue_body.vue'),
};
export const componentNames = {
- AccessibilityIssueBody: AccessibilityIssueBody.name,
- CodequalityIssueBody: CodequalityIssueBody.name,
- TestIssueBody: TestIssueBody.name,
+ AccessibilityIssueBody: 'AccessibilityIssueBody',
+ CodequalityIssueBody: 'CodequalityIssueBody',
+ TestIssueBody: 'TestIssueBody',
};
export const iconComponents = {
diff --git a/app/assets/javascripts/reports/components/report_item.vue b/app/assets/javascripts/reports/components/report_item.vue
index 8871da8fbd7..918263bfb5c 100644
--- a/app/assets/javascripts/reports/components/report_item.vue
+++ b/app/assets/javascripts/reports/components/report_item.vue
@@ -53,11 +53,7 @@ export default {
};
</script>
<template>
- <li
- :class="{ 'is-dismissed': issue.isDismissed }"
- class="report-block-list-issue align-items-center"
- data-qa-selector="report_item_row"
- >
+ <li class="report-block-list-issue align-items-center" data-qa-selector="report_item_row">
<component
:is="iconComponent"
v-if="showReportSectionStatusIcon"
diff --git a/app/assets/javascripts/repository/components/blob_content_viewer.vue b/app/assets/javascripts/repository/components/blob_content_viewer.vue
index 665b0698cc0..1d79818cbe8 100644
--- a/app/assets/javascripts/repository/components/blob_content_viewer.vue
+++ b/app/assets/javascripts/repository/components/blob_content_viewer.vue
@@ -118,7 +118,7 @@ export default {
return this.$apollo.queries.project.loading || this.isLoadingLegacyViewer;
},
isBinaryFileType() {
- return this.isBinary || this.viewer.fileType === 'download';
+ return this.isBinary || this.blobInfo.simpleViewer?.fileType !== 'text';
},
blobInfo() {
const nodes = this.project?.repository?.blobs?.nodes || [];
@@ -180,7 +180,7 @@ export default {
<div v-if="blobInfo && !isLoading" class="file-holder">
<blob-header
:blob="blobInfo"
- :hide-viewer-switcher="!hasRichViewer || isBinary"
+ :hide-viewer-switcher="!hasRichViewer || isBinaryFileType"
:is-binary="isBinaryFileType"
:active-viewer-type="viewer.type"
:has-render-error="hasRenderError"
@@ -188,7 +188,7 @@ export default {
>
<template #actions>
<blob-edit
- :show-edit-button="!isBinary"
+ :show-edit-button="!isBinaryFileType"
:edit-path="blobInfo.editBlobPath"
:web-ide-path="blobInfo.ideEditPath"
/>
diff --git a/app/assets/javascripts/repository/components/blob_viewers/image_viewer.vue b/app/assets/javascripts/repository/components/blob_viewers/image_viewer.vue
new file mode 100644
index 00000000000..83d36209bb3
--- /dev/null
+++ b/app/assets/javascripts/repository/components/blob_viewers/image_viewer.vue
@@ -0,0 +1,19 @@
+<script>
+export default {
+ props: {
+ url: {
+ type: String,
+ required: true,
+ },
+ alt: {
+ type: String,
+ required: true,
+ },
+ },
+};
+</script>
+<template>
+ <div class="gl-text-center gl-p-7 gl-bg-gray-50">
+ <img :src="url" :alt="alt" data-testid="image" />
+ </div>
+</template>
diff --git a/app/assets/javascripts/repository/components/blob_viewers/index.js b/app/assets/javascripts/repository/components/blob_viewers/index.js
index 4e16b16041f..3b4f4eb51fe 100644
--- a/app/assets/javascripts/repository/components/blob_viewers/index.js
+++ b/app/assets/javascripts/repository/components/blob_viewers/index.js
@@ -6,6 +6,8 @@ export const loadViewer = (type) => {
return () => import(/* webpackChunkName: 'blob_text_viewer' */ './text_viewer.vue');
case 'download':
return () => import(/* webpackChunkName: 'blob_download_viewer' */ './download_viewer.vue');
+ case 'image':
+ return () => import(/* webpackChunkName: 'blob_image_viewer' */ './image_viewer.vue');
default:
return null;
}
@@ -23,5 +25,9 @@ export const viewerProps = (type, blob) => {
filePath: blob.rawPath,
fileSize: blob.rawSize,
},
+ image: {
+ url: blob.rawPath,
+ alt: blob.name,
+ },
}[type];
};
diff --git a/app/assets/javascripts/repository/components/last_commit.vue b/app/assets/javascripts/repository/components/last_commit.vue
index a7176853819..5c713796bd6 100644
--- a/app/assets/javascripts/repository/components/last_commit.vue
+++ b/app/assets/javascripts/repository/components/last_commit.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { GlTooltipDirective, GlLink, GlButton, GlButtonGroup, GlLoadingIcon } from '@gitlab/ui';
import defaultAvatarUrl from 'images/no_avatar.png';
import pathLastCommitQuery from 'shared_queries/repository/path_last_commit.query.graphql';
@@ -125,7 +124,7 @@ export default {
:href="commit.webPath"
:class="{ 'font-italic': !commit.message }"
class="commit-row-message item-title"
- v-html="commit.titleHtml"
+ v-html="commit.titleHtml /* eslint-disable-line vue/no-v-html */"
/>
<gl-button
v-if="commit.descriptionHtml"
@@ -153,11 +152,14 @@ export default {
v-if="commitDescription"
:class="{ 'd-block': showDescription }"
class="commit-row-description gl-mb-3"
- v-html="commitDescription"
+ v-html="commitDescription /* eslint-disable-line vue/no-v-html */"
></pre>
</div>
<div class="commit-actions flex-row">
- <div v-if="commit.signatureHtml" v-html="commit.signatureHtml"></div>
+ <div
+ v-if="commit.signatureHtml"
+ v-html="commit.signatureHtml /* eslint-disable-line vue/no-v-html */"
+ ></div>
<div v-if="commit.pipeline" class="ci-status-link">
<gl-link
v-gl-tooltip.left
diff --git a/app/assets/javascripts/repository/components/preview/index.vue b/app/assets/javascripts/repository/components/preview/index.vue
index b74c2333148..54e67c5ab5c 100644
--- a/app/assets/javascripts/repository/components/preview/index.vue
+++ b/app/assets/javascripts/repository/components/preview/index.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { GlIcon, GlLink, GlLoadingIcon } from '@gitlab/ui';
import $ from 'jquery';
import '~/behaviors/markdown/render_gfm';
@@ -60,7 +59,11 @@ export default {
</div>
<div class="blob-viewer" data-qa-selector="blob_viewer_content" itemprop="about">
<gl-loading-icon v-if="loading > 0" size="md" color="dark" class="my-4 mx-auto" />
- <div v-else-if="readme" ref="readme" v-html="readme.html"></div>
+ <div
+ v-else-if="readme"
+ ref="readme"
+ v-html="readme.html /* eslint-disable-line vue/no-v-html */"
+ ></div>
</div>
</article>
</template>
diff --git a/app/assets/javascripts/repository/components/table/index.vue b/app/assets/javascripts/repository/components/table/index.vue
index 69eefc807d7..10a30bd44b1 100644
--- a/app/assets/javascripts/repository/components/table/index.vue
+++ b/app/assets/javascripts/repository/components/table/index.vue
@@ -100,9 +100,9 @@ export default {
/>
<template v-for="val in entries">
<table-row
- v-for="entry in val"
+ v-for="(entry, index) in val"
:id="entry.id"
- :key="`${entry.flatPath}-${entry.id}`"
+ :key="`${entry.flatPath}-${entry.id}-${index}`"
:sha="entry.sha"
:project-path="projectPath"
:current-path="path"
diff --git a/app/assets/javascripts/repository/components/table/row.vue b/app/assets/javascripts/repository/components/table/row.vue
index fa358a75cc1..009dd19b4a5 100644
--- a/app/assets/javascripts/repository/components/table/row.vue
+++ b/app/assets/javascripts/repository/components/table/row.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import {
GlBadge,
GlLink,
@@ -11,6 +10,7 @@ import {
} from '@gitlab/ui';
import { escapeRegExp } from 'lodash';
import filesQuery from 'shared_queries/repository/files.query.graphql';
+import paginatedTreeQuery from 'shared_queries/repository/paginated_tree.query.graphql';
import { escapeFileUrl } from '~/lib/utils/url_utility';
import { TREE_PAGE_SIZE } from '~/repository/constants';
import FileIcon from '~/vue_shared/components/file_icon.vue';
@@ -154,7 +154,8 @@ export default {
return this.isFolder ? this.loadFolder() : this.loadBlob();
},
loadFolder() {
- this.apolloQuery(filesQuery, {
+ const query = this.glFeatures.paginatedTreeGraphqlQuery ? paginatedTreeQuery : filesQuery;
+ this.apolloQuery(query, {
projectPath: this.projectPath,
ref: this.ref,
path: this.path,
@@ -230,7 +231,7 @@ export default {
:href="commit.commitPath"
:title="commit.message"
class="str-truncated-100 tree-commit-link"
- v-html="commit.titleHtml"
+ v-html="commit.titleHtml /* eslint-disable-line vue/no-v-html */"
/>
<gl-skeleton-loading v-else :lines="1" class="h-auto" />
</td>
diff --git a/app/assets/javascripts/repository/components/tree_content.vue b/app/assets/javascripts/repository/components/tree_content.vue
index c861fb8dd06..5a8ead9ae8f 100644
--- a/app/assets/javascripts/repository/components/tree_content.vue
+++ b/app/assets/javascripts/repository/components/tree_content.vue
@@ -1,5 +1,6 @@
<script>
import filesQuery from 'shared_queries/repository/files.query.graphql';
+import paginatedTreeQuery from 'shared_queries/repository/paginated_tree.query.graphql';
import createFlash from '~/flash';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { __ } from '../../locale';
@@ -69,6 +70,9 @@ export default {
hasShowMore() {
return !this.clickedShowMore && this.pageLimitReached;
},
+ paginatedTreeEnabled() {
+ return this.glFeatures.paginatedTreeGraphqlQuery;
+ },
},
watch: {
@@ -91,7 +95,7 @@ export default {
return this.$apollo
.query({
- query: filesQuery,
+ query: this.paginatedTreeEnabled ? paginatedTreeQuery : filesQuery,
variables: {
projectPath: this.projectPath,
ref: this.ref,
@@ -104,13 +108,20 @@ export default {
if (data.errors) throw data.errors;
if (!data?.project?.repository || originalPath !== (this.path || '/')) return;
- const pageInfo = this.hasNextPage(data.project.repository.tree);
+ const pageInfo = this.paginatedTreeEnabled
+ ? data.project.repository.paginatedTree.pageInfo
+ : this.hasNextPage(data.project.repository.tree);
this.isLoadingFiles = false;
this.entries = Object.keys(this.entries).reduce(
(acc, key) => ({
...acc,
- [key]: this.normalizeData(key, data.project.repository.tree[key].edges),
+ [key]: this.normalizeData(
+ key,
+ this.paginatedTreeEnabled
+ ? data.project.repository.paginatedTree.nodes[0][key]
+ : data.project.repository.tree[key].edges,
+ ),
}),
{},
);
@@ -132,7 +143,9 @@ export default {
});
},
normalizeData(key, data) {
- return this.entries[key].concat(data.map(({ node }) => node));
+ return this.entries[key].concat(
+ this.paginatedTreeEnabled ? data.nodes : data.map(({ node }) => node),
+ );
},
hasNextPage(data) {
return []
diff --git a/app/assets/javascripts/repository/constants.js b/app/assets/javascripts/repository/constants.js
index b536bcb1875..93032bf17e2 100644
--- a/app/assets/javascripts/repository/constants.js
+++ b/app/assets/javascripts/repository/constants.js
@@ -11,3 +11,5 @@ export const TOGGLE_CREATE_MR_LABEL = __('Start a new merge request with these c
export const COMMIT_MESSAGE_SUBJECT_MAX_LENGTH = 52;
export const COMMIT_MESSAGE_BODY_MAX_LENGTH = 72;
+
+export const LIMITED_CONTAINER_WIDTH_CLASS = 'limit-container-width';
diff --git a/app/assets/javascripts/repository/mixins/preload.js b/app/assets/javascripts/repository/mixins/preload.js
index ffc260ec84f..a2ddcbf0e4c 100644
--- a/app/assets/javascripts/repository/mixins/preload.js
+++ b/app/assets/javascripts/repository/mixins/preload.js
@@ -1,4 +1,5 @@
import filesQuery from 'shared_queries/repository/files.query.graphql';
+import paginatedTreeQuery from 'shared_queries/repository/paginated_tree.query.graphql';
import projectPathQuery from '../queries/project_path.query.graphql';
import getRefMixin from './get_ref';
@@ -21,7 +22,7 @@ export default {
return this.$apollo
.query({
- query: filesQuery,
+ query: gon.features.paginatedTreeGraphqlQuery ? paginatedTreeQuery : filesQuery,
variables: {
projectPath: this.projectPath,
ref: this.ref,
diff --git a/app/assets/javascripts/repository/pages/blob.vue b/app/assets/javascripts/repository/pages/blob.vue
index 2645b294096..c09e2133936 100644
--- a/app/assets/javascripts/repository/pages/blob.vue
+++ b/app/assets/javascripts/repository/pages/blob.vue
@@ -3,11 +3,25 @@
// https://gitlab.com/gitlab-org/gitlab/-/issues/323200
import BlobContentViewer from '../components/blob_content_viewer.vue';
+import { LIMITED_CONTAINER_WIDTH_CLASS } from '../constants';
export default {
components: {
BlobContentViewer,
},
+ beforeRouteEnter(to, from, next) {
+ next(({ $options }) => {
+ $options.limitedContainerElements.forEach((el) =>
+ el.classList.remove(LIMITED_CONTAINER_WIDTH_CLASS),
+ );
+ });
+ },
+ beforeRouteLeave(to, from, next) {
+ this.$options.limitedContainerElements.forEach((el) =>
+ el.classList.add(LIMITED_CONTAINER_WIDTH_CLASS),
+ );
+ next();
+ },
props: {
path: {
type: String,
@@ -18,6 +32,7 @@ export default {
required: true,
},
},
+ limitedContainerElements: document.querySelectorAll(`.${LIMITED_CONTAINER_WIDTH_CLASS}`),
};
</script>
diff --git a/app/assets/javascripts/rest_api.js b/app/assets/javascripts/rest_api.js
index 3e9e3e6f265..61fe89f4f7e 100644
--- a/app/assets/javascripts/rest_api.js
+++ b/app/assets/javascripts/rest_api.js
@@ -4,7 +4,7 @@ export * from './api/user_api';
export * from './api/markdown_api';
// Note: It's not possible to spy on methods imported from this file in
-// Jest tests. See https://stackoverflow.com/a/53307822/1063392.
+// Jest tests.
// As a workaround, in Jest tests, import the methods from the file
// in which they are defined:
//
diff --git a/app/assets/javascripts/right_sidebar.js b/app/assets/javascripts/right_sidebar.js
index 36f5e6f4ce1..23254fcc2eb 100644
--- a/app/assets/javascripts/right_sidebar.js
+++ b/app/assets/javascripts/right_sidebar.js
@@ -2,7 +2,7 @@
import $ from 'jquery';
import Cookies from 'js-cookie';
-import { hide } from '~/tooltips';
+import { hide, fixTitle } from '~/tooltips';
import createFlash from './flash';
import axios from './lib/utils/axios_utils';
import { sprintf, s__, __ } from './locale';
@@ -75,6 +75,9 @@ Sidebar.prototype.sidebarToggleClicked = function (e, triggered) {
}
$this.attr('data-original-title', tooltipLabel);
+ $this.attr('title', tooltipLabel);
+ fixTitle($this);
+ hide($this);
if (!triggered) {
Cookies.set('collapsed_gutter', $('.right-sidebar').hasClass('right-sidebar-collapsed'));
@@ -99,7 +102,7 @@ Sidebar.prototype.toggleTodo = function (e) {
})
.catch(() =>
createFlash({
- message: sprintf(__('There was an error %{message} todo.'), {
+ message: sprintf(__('There was an error %{message} to-do item.'), {
message:
ajaxType === 'post' ? s__('RightSidebar|adding a') : s__('RightSidebar|deleting the'),
}),
diff --git a/app/assets/javascripts/runner/admin_runners/admin_runners_app.vue b/app/assets/javascripts/runner/admin_runners/admin_runners_app.vue
index 23ecee449a4..fedd2519958 100644
--- a/app/assets/javascripts/runner/admin_runners/admin_runners_app.vue
+++ b/app/assets/javascripts/runner/admin_runners/admin_runners_app.vue
@@ -2,12 +2,16 @@
import createFlash from '~/flash';
import { fetchPolicies } from '~/lib/graphql';
import { updateHistory } from '~/lib/utils/url_utility';
+import { formatNumber, sprintf, __ } from '~/locale';
import RunnerFilteredSearchBar from '../components/runner_filtered_search_bar.vue';
import RunnerList from '../components/runner_list.vue';
import RunnerManualSetupHelp from '../components/runner_manual_setup_help.vue';
import RunnerPagination from '../components/runner_pagination.vue';
import RunnerTypeHelp from '../components/runner_type_help.vue';
-import { INSTANCE_TYPE, I18N_FETCH_ERROR } from '../constants';
+import { statusTokenConfig } from '../components/search_tokens/status_token_config';
+import { tagTokenConfig } from '../components/search_tokens/tag_token_config';
+import { typeTokenConfig } from '../components/search_tokens/type_token_config';
+import { ADMIN_FILTERED_SEARCH_NAMESPACE, INSTANCE_TYPE, I18N_FETCH_ERROR } from '../constants';
import getRunnersQuery from '../graphql/get_runners.query.graphql';
import {
fromUrlQueryToSearch,
@@ -78,6 +82,21 @@ export default {
noRunnersFound() {
return !this.runnersLoading && !this.runners.items.length;
},
+ activeRunnersMessage() {
+ return sprintf(__('Runners currently online: %{active_runners_count}'), {
+ active_runners_count: formatNumber(this.activeRunnersCount),
+ });
+ },
+ searchTokens() {
+ return [
+ statusTokenConfig,
+ typeTokenConfig,
+ {
+ ...tagTokenConfig,
+ recentTokenValuesStorageKey: `${this.$options.filteredSearchNamespace}-recent-tags`,
+ },
+ ];
+ },
},
watch: {
search: {
@@ -99,6 +118,7 @@ export default {
captureException({ error, component: this.$options.name });
},
},
+ filteredSearchNamespace: ADMIN_FILTERED_SEARCH_NAMESPACE,
INSTANCE_TYPE,
};
</script>
@@ -118,9 +138,13 @@ export default {
<runner-filtered-search-bar
v-model="search"
- namespace="admin_runners"
- :active-runners-count="activeRunnersCount"
- />
+ :tokens="searchTokens"
+ :namespace="$options.filteredSearchNamespace"
+ >
+ <template #runner-count>
+ {{ activeRunnersMessage }}
+ </template>
+ </runner-filtered-search-bar>
<div v-if="noRunnersFound" class="gl-text-center gl-p-5">
{{ __('No runners found') }}
diff --git a/app/assets/javascripts/runner/components/runner_filtered_search_bar.vue b/app/assets/javascripts/runner/components/runner_filtered_search_bar.vue
index e14b3b17fa8..e04ca8ddca0 100644
--- a/app/assets/javascripts/runner/components/runner_filtered_search_bar.vue
+++ b/app/assets/javascripts/runner/components/runner_filtered_search_bar.vue
@@ -1,27 +1,8 @@
<script>
import { cloneDeep } from 'lodash';
-import { formatNumber, sprintf, __, s__ } from '~/locale';
-import { OPERATOR_IS_ONLY } from '~/vue_shared/components/filtered_search_bar/constants';
+import { __ } from '~/locale';
import FilteredSearch from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
-import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue';
-import {
- STATUS_ACTIVE,
- STATUS_PAUSED,
- STATUS_ONLINE,
- STATUS_OFFLINE,
- STATUS_NOT_CONNECTED,
- INSTANCE_TYPE,
- GROUP_TYPE,
- PROJECT_TYPE,
- CREATED_DESC,
- CREATED_ASC,
- CONTACTED_DESC,
- CONTACTED_ASC,
- PARAM_KEY_STATUS,
- PARAM_KEY_RUNNER_TYPE,
- PARAM_KEY_TAG,
-} from '../constants';
-import TagToken from './search_tokens/tag_token.vue';
+import { CREATED_DESC, CREATED_ASC, CONTACTED_DESC, CONTACTED_ASC } from '../constants';
const sortOptions = [
{
@@ -58,10 +39,6 @@ export default {
type: String,
required: true,
},
- activeRunnersCount: {
- type: Number,
- required: true,
- },
},
data() {
// filtered_search_bar_root.vue may mutate the inital
@@ -73,62 +50,6 @@ export default {
initialSortBy: sort,
};
},
- computed: {
- searchTokens() {
- return [
- {
- icon: 'status',
- title: __('Status'),
- type: PARAM_KEY_STATUS,
- token: BaseToken,
- unique: true,
- options: [
- { value: STATUS_ACTIVE, title: s__('Runners|Active') },
- { value: STATUS_PAUSED, title: s__('Runners|Paused') },
- { value: STATUS_ONLINE, title: s__('Runners|Online') },
- { value: STATUS_OFFLINE, title: s__('Runners|Offline') },
-
- // Added extra quotes in this title to avoid splitting this value:
- // see: https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1438
- { value: STATUS_NOT_CONNECTED, title: `"${s__('Runners|Not connected')}"` },
- ],
- // TODO In principle we could support more complex search rules,
- // this can be added to a separate issue.
- operators: OPERATOR_IS_ONLY,
- },
-
- {
- icon: 'file-tree',
- title: __('Type'),
- type: PARAM_KEY_RUNNER_TYPE,
- token: BaseToken,
- unique: true,
- options: [
- { value: INSTANCE_TYPE, title: s__('Runners|instance') },
- { value: GROUP_TYPE, title: s__('Runners|group') },
- { value: PROJECT_TYPE, title: s__('Runners|project') },
- ],
- // TODO We should support more complex search rules,
- // search for multiple states (OR) or have NOT operators
- operators: OPERATOR_IS_ONLY,
- },
-
- {
- icon: 'tag',
- title: s__('Runners|Tags'),
- type: PARAM_KEY_TAG,
- token: TagToken,
- recentTokenValuesStorageKey: `${this.namespace}-recent-tags`,
- operators: OPERATOR_IS_ONLY,
- },
- ];
- },
- activeRunnersMessage() {
- return sprintf(__('Runners currently online: %{active_runners_count}'), {
- active_runners_count: formatNumber(this.activeRunnersCount),
- });
- },
- },
methods: {
onFilter(filters) {
const { sort } = this.value;
@@ -161,12 +82,13 @@ export default {
:sort-options="$options.sortOptions"
:initial-filter-value="initialFilterValue"
:initial-sort-by="initialSortBy"
- :tokens="searchTokens"
:search-input-placeholder="__('Search or filter results...')"
data-testid="runners-filtered-search"
@onFilter="onFilter"
@onSort="onSort"
/>
- <div class="gl-text-right" data-testid="active-runners-message">{{ activeRunnersMessage }}</div>
+ <div class="gl-text-right" data-testid="runner-count">
+ <slot name="runner-count"></slot>
+ </div>
</div>
</template>
diff --git a/app/assets/javascripts/runner/components/runner_update_form.vue b/app/assets/javascripts/runner/components/runner_update_form.vue
index a5bc1680852..9a6fc07f6dd 100644
--- a/app/assets/javascripts/runner/components/runner_update_form.vue
+++ b/app/assets/javascripts/runner/components/runner_update_form.vue
@@ -135,9 +135,9 @@ export default {
</gl-form-checkbox>
<gl-form-checkbox
+ v-if="canBeLockedToProject"
v-model="model.locked"
data-testid="runner-field-locked"
- :disabled="!canBeLockedToProject"
>
{{ __('Lock to current projects') }}
<template #help>
diff --git a/app/assets/javascripts/runner/components/search_tokens/status_token_config.js b/app/assets/javascripts/runner/components/search_tokens/status_token_config.js
new file mode 100644
index 00000000000..03dff5e61a5
--- /dev/null
+++ b/app/assets/javascripts/runner/components/search_tokens/status_token_config.js
@@ -0,0 +1,32 @@
+import { __, s__ } from '~/locale';
+import { OPERATOR_IS_ONLY } from '~/vue_shared/components/filtered_search_bar/constants';
+import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue';
+import {
+ STATUS_ACTIVE,
+ STATUS_PAUSED,
+ STATUS_ONLINE,
+ STATUS_OFFLINE,
+ STATUS_NOT_CONNECTED,
+ PARAM_KEY_STATUS,
+} from '../../constants';
+
+export const statusTokenConfig = {
+ icon: 'status',
+ title: __('Status'),
+ type: PARAM_KEY_STATUS,
+ token: BaseToken,
+ unique: true,
+ options: [
+ { value: STATUS_ACTIVE, title: s__('Runners|Active') },
+ { value: STATUS_PAUSED, title: s__('Runners|Paused') },
+ { value: STATUS_ONLINE, title: s__('Runners|Online') },
+ { value: STATUS_OFFLINE, title: s__('Runners|Offline') },
+
+ // Added extra quotes in this title to avoid splitting this value:
+ // see: https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1438
+ { value: STATUS_NOT_CONNECTED, title: `"${s__('Runners|Not connected')}"` },
+ ],
+ // TODO In principle we could support more complex search rules,
+ // this can be added to a separate issue.
+ operators: OPERATOR_IS_ONLY,
+};
diff --git a/app/assets/javascripts/runner/components/search_tokens/tag_token.vue b/app/assets/javascripts/runner/components/search_tokens/tag_token.vue
index 51fae60b6b7..ab67ac608e2 100644
--- a/app/assets/javascripts/runner/components/search_tokens/tag_token.vue
+++ b/app/assets/javascripts/runner/components/search_tokens/tag_token.vue
@@ -33,6 +33,7 @@ export default {
// The API should
// 1) scope to the rights of the user
// 2) stay up to date to the removal of old tags
+ // 3) consider the scope of search, like searching within the tags of a group
// See: https://gitlab.com/gitlab-org/gitlab/-/issues/333796
return axios
.get(TAG_SUGGESTIONS_PATH, {
diff --git a/app/assets/javascripts/runner/components/search_tokens/tag_token_config.js b/app/assets/javascripts/runner/components/search_tokens/tag_token_config.js
new file mode 100644
index 00000000000..fdeba714385
--- /dev/null
+++ b/app/assets/javascripts/runner/components/search_tokens/tag_token_config.js
@@ -0,0 +1,12 @@
+import { s__ } from '~/locale';
+import { OPERATOR_IS_ONLY } from '~/vue_shared/components/filtered_search_bar/constants';
+import { PARAM_KEY_TAG } from '../../constants';
+import TagToken from './tag_token.vue';
+
+export const tagTokenConfig = {
+ icon: 'tag',
+ title: s__('Runners|Tags'),
+ type: PARAM_KEY_TAG,
+ token: TagToken,
+ operators: OPERATOR_IS_ONLY,
+};
diff --git a/app/assets/javascripts/runner/components/search_tokens/type_token_config.js b/app/assets/javascripts/runner/components/search_tokens/type_token_config.js
new file mode 100644
index 00000000000..1da61c53386
--- /dev/null
+++ b/app/assets/javascripts/runner/components/search_tokens/type_token_config.js
@@ -0,0 +1,20 @@
+import { __, s__ } from '~/locale';
+import { OPERATOR_IS_ONLY } from '~/vue_shared/components/filtered_search_bar/constants';
+import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue';
+import { INSTANCE_TYPE, GROUP_TYPE, PROJECT_TYPE, PARAM_KEY_RUNNER_TYPE } from '../../constants';
+
+export const typeTokenConfig = {
+ icon: 'file-tree',
+ title: __('Type'),
+ type: PARAM_KEY_RUNNER_TYPE,
+ token: BaseToken,
+ unique: true,
+ options: [
+ { value: INSTANCE_TYPE, title: s__('Runners|instance') },
+ { value: GROUP_TYPE, title: s__('Runners|group') },
+ { value: PROJECT_TYPE, title: s__('Runners|project') },
+ ],
+ // TODO We should support more complex search rules,
+ // search for multiple states (OR) or have NOT operators
+ operators: OPERATOR_IS_ONLY,
+};
diff --git a/app/assets/javascripts/runner/constants.js b/app/assets/javascripts/runner/constants.js
index 2822882e0cc..46e55b322c7 100644
--- a/app/assets/javascripts/runner/constants.js
+++ b/app/assets/javascripts/runner/constants.js
@@ -2,6 +2,7 @@ import { s__ } from '~/locale';
export const RUNNER_PAGE_SIZE = 20;
export const RUNNER_JOB_COUNT_LIMIT = 1000;
+export const GROUP_RUNNER_COUNT_LIMIT = 1000;
export const I18N_FETCH_ERROR = s__('Runners|Something went wrong while fetching runner data.');
export const I18N_DETAILS_TITLE = s__('Runners|Runner #%{runner_id}');
@@ -50,3 +51,8 @@ export const CONTACTED_DESC = 'CONTACTED_DESC'; // TODO Add this to the API
export const CONTACTED_ASC = 'CONTACTED_ASC';
export const DEFAULT_SORT = CREATED_DESC;
+
+// Local storage namespaces
+
+export const ADMIN_FILTERED_SEARCH_NAMESPACE = 'admin_runners';
+export const GROUP_FILTERED_SEARCH_NAMESPACE = 'group_runners';
diff --git a/app/assets/javascripts/runner/graphql/get_group_runners.query.graphql b/app/assets/javascripts/runner/graphql/get_group_runners.query.graphql
new file mode 100644
index 00000000000..a601ee8d611
--- /dev/null
+++ b/app/assets/javascripts/runner/graphql/get_group_runners.query.graphql
@@ -0,0 +1,35 @@
+#import "~/runner/graphql/runner_node.fragment.graphql"
+#import "~/graphql_shared/fragments/pageInfo.fragment.graphql"
+
+query getGroupRunners(
+ $groupFullPath: ID!
+ $before: String
+ $after: String
+ $first: Int
+ $last: Int
+ $status: CiRunnerStatus
+ $type: CiRunnerType
+ $search: String
+ $sort: CiRunnerSort
+) {
+ group(fullPath: $groupFullPath) {
+ runners(
+ membership: DESCENDANTS
+ before: $before
+ after: $after
+ first: $first
+ last: $last
+ status: $status
+ type: $type
+ search: $search
+ sort: $sort
+ ) {
+ nodes {
+ ...RunnerNode
+ }
+ pageInfo {
+ ...PageInfo
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/runner/group_runners/group_runners_app.vue b/app/assets/javascripts/runner/group_runners/group_runners_app.vue
index 07bbf60c453..42e1a9e1de9 100644
--- a/app/assets/javascripts/runner/group_runners/group_runners_app.vue
+++ b/app/assets/javascripts/runner/group_runners/group_runners_app.vue
@@ -1,18 +1,135 @@
<script>
+import createFlash from '~/flash';
+import { fetchPolicies } from '~/lib/graphql';
+import { updateHistory } from '~/lib/utils/url_utility';
+import { formatNumber, sprintf, s__ } from '~/locale';
+import RunnerFilteredSearchBar from '../components/runner_filtered_search_bar.vue';
+import RunnerList from '../components/runner_list.vue';
import RunnerManualSetupHelp from '../components/runner_manual_setup_help.vue';
+import RunnerPagination from '../components/runner_pagination.vue';
import RunnerTypeHelp from '../components/runner_type_help.vue';
-import { GROUP_TYPE } from '../constants';
+import { statusTokenConfig } from '../components/search_tokens/status_token_config';
+import { typeTokenConfig } from '../components/search_tokens/type_token_config';
+import {
+ I18N_FETCH_ERROR,
+ GROUP_FILTERED_SEARCH_NAMESPACE,
+ GROUP_TYPE,
+ GROUP_RUNNER_COUNT_LIMIT,
+} from '../constants';
+import getGroupRunnersQuery from '../graphql/get_group_runners.query.graphql';
+import {
+ fromUrlQueryToSearch,
+ fromSearchToUrl,
+ fromSearchToVariables,
+} from '../runner_search_utils';
+import { captureException } from '../sentry_utils';
export default {
+ name: 'GroupRunnersApp',
components: {
+ RunnerFilteredSearchBar,
+ RunnerList,
RunnerManualSetupHelp,
RunnerTypeHelp,
+ RunnerPagination,
},
props: {
registrationToken: {
type: String,
required: true,
},
+ groupFullPath: {
+ type: String,
+ required: true,
+ },
+ groupRunnersLimitedCount: {
+ type: Number,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ search: fromUrlQueryToSearch(),
+ runners: {
+ items: [],
+ pageInfo: {},
+ },
+ };
+ },
+ apollo: {
+ runners: {
+ query: getGroupRunnersQuery,
+ // Runners can be updated by users directly in this list.
+ // A "cache and network" policy prevents outdated filtered
+ // results.
+ fetchPolicy: fetchPolicies.CACHE_AND_NETWORK,
+ variables() {
+ return this.variables;
+ },
+ update(data) {
+ const { runners } = data?.group || {};
+ return {
+ items: runners?.nodes || [],
+ pageInfo: runners?.pageInfo || {},
+ };
+ },
+ error(error) {
+ createFlash({ message: I18N_FETCH_ERROR });
+
+ this.reportToSentry(error);
+ },
+ },
+ },
+ computed: {
+ variables() {
+ return {
+ ...fromSearchToVariables(this.search),
+ groupFullPath: this.groupFullPath,
+ };
+ },
+ runnersLoading() {
+ return this.$apollo.queries.runners.loading;
+ },
+ noRunnersFound() {
+ return !this.runnersLoading && !this.runners.items.length;
+ },
+ groupRunnersCount() {
+ if (this.groupRunnersLimitedCount > GROUP_RUNNER_COUNT_LIMIT) {
+ return `${formatNumber(GROUP_RUNNER_COUNT_LIMIT)}+`;
+ }
+ return formatNumber(this.groupRunnersLimitedCount);
+ },
+ runnerCountMessage() {
+ return sprintf(s__('Runners|Runners in this group: %{groupRunnersCount}'), {
+ groupRunnersCount: this.groupRunnersCount,
+ });
+ },
+ searchTokens() {
+ return [statusTokenConfig, typeTokenConfig];
+ },
+ filteredSearchNamespace() {
+ return `${GROUP_FILTERED_SEARCH_NAMESPACE}/${this.groupFullPath}`;
+ },
+ },
+ watch: {
+ search: {
+ deep: true,
+ handler() {
+ // TODO Implement back button reponse using onpopstate
+ updateHistory({
+ url: fromSearchToUrl(this.search),
+ title: document.title,
+ });
+ },
+ },
+ },
+ errorCaptured(error) {
+ this.reportToSentry(error);
+ },
+ methods: {
+ reportToSentry(error) {
+ captureException({ error, component: this.$options.name });
+ },
},
GROUP_TYPE,
};
@@ -31,5 +148,23 @@ export default {
/>
</div>
</div>
+
+ <runner-filtered-search-bar
+ v-model="search"
+ :tokens="searchTokens"
+ :namespace="filteredSearchNamespace"
+ >
+ <template #runner-count>
+ {{ runnerCountMessage }}
+ </template>
+ </runner-filtered-search-bar>
+
+ <div v-if="noRunnersFound" class="gl-text-center gl-p-5">
+ {{ __('No runners found') }}
+ </div>
+ <template v-else>
+ <runner-list :runners="runners.items" :loading="runnersLoading" />
+ <runner-pagination v-model="search.pagination" :page-info="runners.pageInfo" />
+ </template>
</div>
</template>
diff --git a/app/assets/javascripts/runner/group_runners/index.js b/app/assets/javascripts/runner/group_runners/index.js
index e14c583d73e..9545764c68d 100644
--- a/app/assets/javascripts/runner/group_runners/index.js
+++ b/app/assets/javascripts/runner/group_runners/index.js
@@ -12,7 +12,13 @@ export const initGroupRunners = (selector = '#js-group-runners') => {
return null;
}
- const { registrationToken, groupId } = el.dataset;
+ const {
+ registrationToken,
+ runnerInstallHelpPage,
+ groupId,
+ groupFullPath,
+ groupRunnersLimitedCount,
+ } = el.dataset;
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(
@@ -27,12 +33,15 @@ export const initGroupRunners = (selector = '#js-group-runners') => {
el,
apolloProvider,
provide: {
+ runnerInstallHelpPage,
groupId,
},
render(h) {
return h(GroupRunnersApp, {
props: {
registrationToken,
+ groupFullPath,
+ groupRunnersLimitedCount: parseInt(groupRunnersLimitedCount, 10),
},
});
},
diff --git a/app/assets/javascripts/runner/runner_search_utils.js b/app/assets/javascripts/runner/runner_search_utils.js
index 65f75eb11ac..0a817ea0acf 100644
--- a/app/assets/javascripts/runner/runner_search_utils.js
+++ b/app/assets/javascripts/runner/runner_search_utils.js
@@ -43,7 +43,6 @@ export const fromUrlQueryToSearch = (query = window.location.search) => {
urlQueryToFilter(query, {
filterNamesAllowList: [PARAM_KEY_STATUS, PARAM_KEY_RUNNER_TYPE, PARAM_KEY_TAG],
filteredSearchTermKey: PARAM_KEY_SEARCH,
- legacySpacesDecode: false,
}),
),
sort: params[PARAM_KEY_SORT] || DEFAULT_SORT,
diff --git a/app/assets/javascripts/search/highlight_blob_search_result.js b/app/assets/javascripts/search/highlight_blob_search_result.js
index c553d5b14a0..07967434f37 100644
--- a/app/assets/javascripts/search/highlight_blob_search_result.js
+++ b/app/assets/javascripts/search/highlight_blob_search_result.js
@@ -2,7 +2,7 @@ export default (search = '') => {
const highlightLineClass = 'hll';
const contentBody = document.getElementById('content-body');
const searchTerm = search.toLowerCase();
- const blobs = contentBody.querySelectorAll('.blob-result');
+ const blobs = contentBody.querySelectorAll('.js-blob-result');
blobs.forEach((blob) => {
const lines = blob.querySelectorAll('.line');
diff --git a/app/assets/javascripts/search/store/actions.js b/app/assets/javascripts/search/store/actions.js
index ee5e778f63d..be64a9278e3 100644
--- a/app/assets/javascripts/search/store/actions.js
+++ b/app/assets/javascripts/search/store/actions.js
@@ -40,7 +40,7 @@ export const fetchProjects = ({ commit, state }, search) => {
);
} else {
// The .catch() is due to the API method not handling a rejection properly
- Api.projects(search, { order_by: 'id' }, callback).catch(() => {
+ Api.projects(search, { order_by: 'similarity' }, callback).catch(() => {
callback();
});
}
diff --git a/app/assets/javascripts/search/store/utils.js b/app/assets/javascripts/search/store/utils.js
index b7d97213594..b00b9bb0f2e 100644
--- a/app/assets/javascripts/search/store/utils.js
+++ b/app/assets/javascripts/search/store/utils.js
@@ -6,7 +6,7 @@ function extractKeys(object, keyList) {
}
export const loadDataFromLS = (key) => {
- if (!AccessorUtilities.isLocalStorageAccessSafe()) {
+ if (!AccessorUtilities.canUseLocalStorage()) {
return [];
}
@@ -20,7 +20,7 @@ export const loadDataFromLS = (key) => {
};
export const setFrequentItemToLS = (key, data, itemData) => {
- if (!AccessorUtilities.isLocalStorageAccessSafe()) {
+ if (!AccessorUtilities.canUseLocalStorage()) {
return [];
}
diff --git a/app/assets/javascripts/security_configuration/components/constants.js b/app/assets/javascripts/security_configuration/components/constants.js
index ebe0138f046..6a282df99bf 100644
--- a/app/assets/javascripts/security_configuration/components/constants.js
+++ b/app/assets/javascripts/security_configuration/components/constants.js
@@ -10,6 +10,7 @@ import {
REPORT_TYPE_CONTAINER_SCANNING,
REPORT_TYPE_CLUSTER_IMAGE_SCANNING,
REPORT_TYPE_COVERAGE_FUZZING,
+ REPORT_TYPE_CORPUS_MANAGEMENT,
REPORT_TYPE_API_FUZZING,
REPORT_TYPE_LICENSE_COMPLIANCE,
} from '~/vue_shared/security_reports/constants';
@@ -104,6 +105,12 @@ export const COVERAGE_FUZZING_CONFIG_HELP_PATH = helpPagePath(
{ anchor: 'configuration' },
);
+export const CORPUS_MANAGEMENT_NAME = __('Corpus Management');
+export const CORPUS_MANAGEMENT_DESCRIPTION = s__(
+ 'SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing.',
+);
+export const CORPUS_MANAGEMENT_CONFIG_TEXT = s__('SecurityConfiguration|Manage corpus');
+
export const API_FUZZING_NAME = __('API Fuzzing');
export const API_FUZZING_DESCRIPTION = __('Find bugs in your code with API fuzzing.');
export const API_FUZZING_HELP_PATH = helpPagePath('user/application_security/api_fuzzing/index');
@@ -202,6 +209,14 @@ export const securityFeatures = [
helpPath: COVERAGE_FUZZING_HELP_PATH,
configurationHelpPath: COVERAGE_FUZZING_CONFIG_HELP_PATH,
type: REPORT_TYPE_COVERAGE_FUZZING,
+ secondary: gon?.features?.corpusManagement
+ ? {
+ type: REPORT_TYPE_CORPUS_MANAGEMENT,
+ name: CORPUS_MANAGEMENT_NAME,
+ description: CORPUS_MANAGEMENT_DESCRIPTION,
+ configurationText: CORPUS_MANAGEMENT_CONFIG_TEXT,
+ }
+ : {},
},
];
diff --git a/app/assets/javascripts/sentry/sentry_config.js b/app/assets/javascripts/sentry/sentry_config.js
index a3a2c794a67..8f3c4c644bf 100644
--- a/app/assets/javascripts/sentry/sentry_config.js
+++ b/app/assets/javascripts/sentry/sentry_config.js
@@ -19,7 +19,6 @@ const IGNORE_ERRORS = [
'fb_xd_fragment',
// ISP "optimizing" proxy - `Cache-Control: no-transform` seems to
// reduce this. (thanks @acdha)
- // See http://stackoverflow.com/questions/4113268
'bmi_SafeAddOnload',
'EBCallBackMessageReceived',
// See http://toolbar.conduit.com/Developer/HtmlAndGadget/Methods/JSInjection.aspx
diff --git a/app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue b/app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue
index e522e3ff408..b1c8f6ef22e 100644
--- a/app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue
+++ b/app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import {
GlToast,
GlModal,
@@ -8,6 +7,7 @@ import {
GlFormCheckbox,
GlDropdown,
GlDropdownItem,
+ GlSafeHtmlDirective,
} from '@gitlab/ui';
import $ from 'jquery';
import Vue from 'vue';
@@ -49,6 +49,7 @@ export default {
},
directives: {
GlTooltip: GlTooltipDirective,
+ SafeHtml: GlSafeHtmlDirective,
},
mixins: [glFeatureFlagsMixin()],
props: {
@@ -234,6 +235,7 @@ export default {
},
},
statusTimeRanges,
+ safeHtmlConfig: { ADD_TAGS: ['gl-emoji'] },
};
</script>
@@ -267,7 +269,7 @@ export default {
@click="setEmoji"
>
<template #button-content>
- <span v-html="emojiTag"></span>
+ <span v-safe-html:[$options.safeHtmlConfig]="emojiTag"></span>
<span
v-show="noEmoji"
class="js-no-emoji-placeholder no-emoji-placeholder position-relative"
@@ -289,7 +291,7 @@ export default {
class="js-toggle-emoji-menu emoji-menu-toggle-button btn"
@click="showEmojiMenu"
>
- <span v-html="emojiTag"></span>
+ <span v-safe-html:[$options.safeHtmlConfig]="emojiTag"></span>
<span
v-show="noEmoji"
class="js-no-emoji-placeholder no-emoji-placeholder position-relative"
diff --git a/app/assets/javascripts/sidebar/components/assignees/assignee_title.vue b/app/assets/javascripts/sidebar/components/assignees/assignee_title.vue
index d9c5edc91f1..f98aa0dc77d 100644
--- a/app/assets/javascripts/sidebar/components/assignees/assignee_title.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/assignee_title.vue
@@ -53,7 +53,7 @@ export default {
class="js-sidebar-dropdown-toggle edit-link btn gl-text-gray-900! gl-ml-auto hide-collapsed btn-default btn-sm gl-button btn-default-tertiary float-right"
href="#"
data-test-id="edit-link"
- data-track-event="click_edit_button"
+ data-track-action="click_edit_button"
data-track-label="right_sidebar"
data-track-property="assignee"
>
diff --git a/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue b/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue
index 1dd05d3886e..1b28ba2afd1 100644
--- a/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue
@@ -3,7 +3,6 @@ import { GlDropdownItem } from '@gitlab/ui';
import { cloneDeep } from 'lodash';
import Vue from 'vue';
import createFlash from '~/flash';
-import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { IssuableType } from '~/issue_show/constants';
import { __, n__ } from '~/locale';
import SidebarAssigneesRealtime from '~/sidebar/components/assignees/assignees_realtime.vue';
@@ -173,7 +172,7 @@ export default {
})
.then(({ data }) => {
this.$emit('assignees-updated', {
- id: getIdFromGraphQLId(data.issuableSetAssignees.issuable.id),
+ id: data.issuableSetAssignees.issuable.id,
assignees: data.issuableSetAssignees.issuable.assignees.nodes,
});
return data;
diff --git a/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue b/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue
index 55179947756..9fdf941579d 100644
--- a/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue
+++ b/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue
@@ -144,16 +144,11 @@ export default {
v-if="glFeatures.labelsWidget"
class="block labels js-labels-block"
:allow-label-remove="allowLabelEdit"
- :allow-label-create="allowLabelCreate"
- :allow-label-edit="allowLabelEdit"
:allow-multiselect="true"
- :allow-scoped-labels="allowScopedLabels"
:footer-create-label-title="__('Create project label')"
:footer-manage-label-title="__('Manage project labels')"
:labels-create-title="__('Create project label')"
- :labels-fetch-path="labelsFetchPath"
:labels-filter-base-path="projectIssuesPath"
- :labels-manage-path="labelsManagePath"
:labels-select-in-progress="isLabelsSelectInProgress"
:selected-labels="selectedLabels"
:variant="$options.variant"
diff --git a/app/assets/javascripts/sidebar/components/lock/issuable_lock_form.vue b/app/assets/javascripts/sidebar/components/lock/issuable_lock_form.vue
index 19543d0927a..cb49f329f7e 100644
--- a/app/assets/javascripts/sidebar/components/lock/issuable_lock_form.vue
+++ b/app/assets/javascripts/sidebar/components/lock/issuable_lock_form.vue
@@ -93,7 +93,7 @@ export default {
class="float-right lock-edit btn gl-text-gray-900! gl-ml-auto hide-collapsed btn-default btn-sm gl-button btn-default-tertiary gl-mr-n2"
href="#"
data-testid="edit-link"
- data-track-event="click_edit_button"
+ data-track-action="click_edit_button"
data-track-label="right_sidebar"
data-track-property="lock_issue"
@click.prevent="toggleForm"
diff --git a/app/assets/javascripts/sidebar/components/participants/sidebar_participants_widget.vue b/app/assets/javascripts/sidebar/components/participants/sidebar_participants_widget.vue
index 39f72b251c7..a09138a708b 100644
--- a/app/assets/javascripts/sidebar/components/participants/sidebar_participants_widget.vue
+++ b/app/assets/javascripts/sidebar/components/participants/sidebar_participants_widget.vue
@@ -56,6 +56,11 @@ export default {
return this.$apollo.queries.participants.loading;
},
},
+ methods: {
+ toggleSidebar() {
+ this.$emit('toggleSidebar');
+ },
+ },
};
</script>
@@ -66,5 +71,6 @@ export default {
:number-of-less-participants="7"
:lazy="false"
class="block participants"
+ @toggleSidebar="toggleSidebar"
/>
</template>
diff --git a/app/assets/javascripts/sidebar/components/reviewers/reviewer_title.vue b/app/assets/javascripts/sidebar/components/reviewers/reviewer_title.vue
index 1243603805a..367dcdb961b 100644
--- a/app/assets/javascripts/sidebar/components/reviewers/reviewer_title.vue
+++ b/app/assets/javascripts/sidebar/components/reviewers/reviewer_title.vue
@@ -40,7 +40,7 @@ export default {
v-if="editable"
class="js-sidebar-dropdown-toggle edit-link btn gl-text-gray-900! gl-ml-auto hide-collapsed btn-default btn-sm gl-button btn-default-tertiary float-right"
href="#"
- data-track-event="click_edit_button"
+ data-track-action="click_edit_button"
data-track-label="right_sidebar"
data-track-property="reviewer"
>
diff --git a/app/assets/javascripts/sidebar/components/sidebar_dropdown_widget.vue b/app/assets/javascripts/sidebar/components/sidebar_dropdown_widget.vue
index 8ccc0102c3d..8f4d5406da8 100644
--- a/app/assets/javascripts/sidebar/components/sidebar_dropdown_widget.vue
+++ b/app/assets/javascripts/sidebar/components/sidebar_dropdown_widget.vue
@@ -369,6 +369,7 @@ export default {
:text="dropdownText"
:loading="loading"
class="gl-w-full"
+ toggle-class="gl-max-w-100"
@shown="setFocus"
>
<gl-search-box-by-type ref="search" v-model="searchTerm" />
diff --git a/app/assets/javascripts/sidebar/components/sidebar_editable_item.vue b/app/assets/javascripts/sidebar/components/sidebar_editable_item.vue
index 89aa03fd954..22adbd79ef6 100644
--- a/app/assets/javascripts/sidebar/components/sidebar_editable_item.vue
+++ b/app/assets/javascripts/sidebar/components/sidebar_editable_item.vue
@@ -136,7 +136,7 @@ export default {
size="small"
class="gl-text-gray-900! gl-ml-auto hide-collapsed gl-mr-n2"
data-testid="edit-button"
- :data-track-event="tracking.event"
+ :data-track-action="tracking.event"
:data-track-label="tracking.label"
:data-track-property="tracking.property"
data-qa-selector="edit_link"
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/spent_only_pane.vue b/app/assets/javascripts/sidebar/components/time_tracking/spent_only_pane.vue
index 33c6ac6e2ba..db2197ec65e 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/spent_only_pane.vue
+++ b/app/assets/javascripts/sidebar/components/time_tracking/spent_only_pane.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { sprintf, s__ } from '~/locale';
export default {
@@ -27,5 +26,5 @@ export default {
</script>
<template>
- <div data-testid="spentOnlyPane" v-html="timeSpent"></div>
+ <div data-testid="spentOnlyPane" v-html="timeSpent /* eslint-disable-line vue/no-v-html */"></div>
</template>
diff --git a/app/assets/javascripts/sidebar/mount_sidebar.js b/app/assets/javascripts/sidebar/mount_sidebar.js
index 031472a7d20..10ab80f4ec2 100644
--- a/app/assets/javascripts/sidebar/mount_sidebar.js
+++ b/app/assets/javascripts/sidebar/mount_sidebar.js
@@ -1,7 +1,6 @@
import $ from 'jquery';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
-import createFlash from '~/flash';
import { TYPE_ISSUE, TYPE_MERGE_REQUEST } from '~/graphql_shared/constants';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
@@ -13,7 +12,6 @@ import {
isInIncidentPage,
parseBoolean,
} from '~/lib/utils/common_utils';
-import { __ } from '~/locale';
import CollapsedAssigneeList from '~/sidebar/components/assignees/collapsed_assignee_list.vue';
import SidebarAssigneesWidget from '~/sidebar/components/assignees/sidebar_assignees_widget.vue';
import SidebarConfidentialityWidget from '~/sidebar/components/confidential/sidebar_confidentiality_widget.vue';
@@ -258,6 +256,8 @@ export function mountSidebarLabels() {
allowScopedLabels: parseBoolean(el.dataset.allowScopedLabels),
initiallySelectedLabels: JSON.parse(el.dataset.selectedLabels),
variant: DropdownVariant.Sidebar,
+ canUpdate: parseBoolean(el.dataset.canEdit),
+ isClassicSidebar: true,
},
render: (createElement) => createElement(SidebarLabels),
});
@@ -361,10 +361,10 @@ function mountReferenceComponent() {
});
}
-function mountLockComponent() {
+function mountLockComponent(store) {
const el = document.getElementById('js-lock-entry-point');
- if (!el) {
+ if (!el || !store) {
return;
}
@@ -373,37 +373,20 @@ function mountLockComponent() {
const dataNode = document.getElementById('js-lock-issue-data');
const initialData = JSON.parse(dataNode.innerHTML);
- let importStore;
- if (isInIssuePage() || isInIncidentPage()) {
- importStore = import(/* webpackChunkName: 'notesStore' */ '~/notes/stores').then(
- ({ store }) => store,
- );
- } else {
- importStore = import(/* webpackChunkName: 'mrNotesStore' */ '~/mr_notes/stores').then(
- (store) => store.default,
- );
- }
-
- importStore
- .then(
- (store) =>
- new Vue({
- el,
- store,
- provide: {
- fullPath,
- },
- render: (createElement) =>
- createElement(IssuableLockForm, {
- props: {
- isEditable: initialData.is_editable,
- },
- }),
- }),
- )
- .catch(() => {
- createFlash({ message: __('Failed to load sidebar lock status') });
- });
+ // eslint-disable-next-line no-new
+ new Vue({
+ el,
+ store,
+ provide: {
+ fullPath,
+ },
+ render: (createElement) =>
+ createElement(IssuableLockForm, {
+ props: {
+ isEditable: initialData.is_editable,
+ },
+ }),
+ });
}
function mountParticipantsComponent() {
@@ -535,7 +518,7 @@ function mountCopyEmailComponent() {
const isAssigneesWidgetShown =
(isInIssuePage() || isInDesignPage()) && gon.features.issueAssigneesWidget;
-export function mountSidebar(mediator) {
+export function mountSidebar(mediator, store) {
initInviteMembersModal();
initInviteMembersTrigger();
@@ -546,11 +529,12 @@ export function mountSidebar(mediator) {
mountAssigneesComponentDeprecated(mediator);
}
mountReviewersComponent(mediator);
+ mountSidebarLabels();
mountMilestoneSelect();
mountConfidentialComponent(mediator);
mountDueDateComponent(mediator);
mountReferenceComponent(mediator);
- mountLockComponent();
+ mountLockComponent(store);
mountParticipantsComponent();
mountSubscriptionsComponent();
mountCopyEmailComponent();
diff --git a/app/assets/javascripts/sidebar/services/sidebar_service.js b/app/assets/javascripts/sidebar/services/sidebar_service.js
index ace2a163adc..cea26acd101 100644
--- a/app/assets/javascripts/sidebar/services/sidebar_service.js
+++ b/app/assets/javascripts/sidebar/services/sidebar_service.js
@@ -22,7 +22,6 @@ export default class SidebarService {
constructor(endpointMap) {
if (!SidebarService.singleton) {
this.endpoint = endpointMap.endpoint;
- this.toggleSubscriptionEndpoint = endpointMap.toggleSubscriptionEndpoint;
this.moveIssueEndpoint = endpointMap.moveIssueEndpoint;
this.projectsAutocompleteEndpoint = endpointMap.projectsAutocompleteEndpoint;
this.fullPath = endpointMap.fullPath;
@@ -75,10 +74,6 @@ export default class SidebarService {
});
}
- toggleSubscription() {
- return axios.post(this.toggleSubscriptionEndpoint);
- }
-
moveIssue(moveToProjectId) {
return axios.post(this.moveIssueEndpoint, {
move_to_project_id: moveToProjectId,
diff --git a/app/assets/javascripts/sidebar/sidebar_bundle.js b/app/assets/javascripts/sidebar/sidebar_bundle.js
index 063e3313a3c..1be670f7590 100644
--- a/app/assets/javascripts/sidebar/sidebar_bundle.js
+++ b/app/assets/javascripts/sidebar/sidebar_bundle.js
@@ -1,9 +1,9 @@
-import { mountSidebar, getSidebarOptions } from './mount_sidebar';
+import { mountSidebar, getSidebarOptions } from 'ee_else_ce/sidebar/mount_sidebar';
import Mediator from './sidebar_mediator';
-export default () => {
+export default (store) => {
const mediator = new Mediator(getSidebarOptions());
mediator.fetch();
- mountSidebar(mediator);
+ mountSidebar(mediator, store);
};
diff --git a/app/assets/javascripts/sidebar/sidebar_mediator.js b/app/assets/javascripts/sidebar/sidebar_mediator.js
index 0a5e44a9b95..9144e3b08db 100644
--- a/app/assets/javascripts/sidebar/sidebar_mediator.js
+++ b/app/assets/javascripts/sidebar/sidebar_mediator.js
@@ -17,7 +17,6 @@ export default class SidebarMediator {
this.store = new Store(options);
this.service = new Service({
endpoint: options.endpoint,
- toggleSubscriptionEndpoint: options.toggleSubscriptionEndpoint,
moveIssueEndpoint: options.moveIssueEndpoint,
projectsAutocompleteEndpoint: options.projectsAutocompleteEndpoint,
fullPath: options.fullPath,
@@ -85,22 +84,6 @@ export default class SidebarMediator {
this.store.setAssigneeData(data);
this.store.setReviewerData(data);
this.store.setTimeTrackingData(data);
- this.store.setParticipantsData(data);
- this.store.setSubscriptionsData(data);
- }
-
- toggleSubscription() {
- this.store.setFetchingState('subscriptions', true);
- return this.service
- .toggleSubscription()
- .then(() => {
- this.store.setSubscribedState(!this.store.subscribed);
- this.store.setFetchingState('subscriptions', false);
- })
- .catch((err) => {
- this.store.setFetchingState('subscriptions', false);
- throw err;
- });
}
fetchAutocompleteProjects(searchTerm) {
diff --git a/app/assets/javascripts/sidebar/stores/sidebar_store.js b/app/assets/javascripts/sidebar/stores/sidebar_store.js
index 3c108b06eab..94c54fc0980 100644
--- a/app/assets/javascripts/sidebar/stores/sidebar_store.js
+++ b/app/assets/javascripts/sidebar/stores/sidebar_store.js
@@ -22,8 +22,6 @@ export default class SidebarStore {
this.isFetching = {
assignees: true,
reviewers: true,
- participants: true,
- subscriptions: true,
};
this.isLoading = {};
this.autocompleteProjects = [];
@@ -63,18 +61,6 @@ export default class SidebarStore {
this.humanTotalTimeSpent = data.human_total_time_spent;
}
- setParticipantsData(data) {
- this.isFetching.participants = false;
- this.participants = data.participants || [];
- }
-
- setSubscriptionsData(data) {
- this.projectEmailsDisabled = data.project_emails_disabled || false;
- this.subscribeDisabledDescription = data.subscribe_disabled_description;
- this.isFetching.subscriptions = false;
- this.subscribed = data.subscribed || false;
- }
-
setFetchingState(key, value) {
this.isFetching[key] = value;
}
diff --git a/app/assets/javascripts/sidebar/track_invite_members.js b/app/assets/javascripts/sidebar/track_invite_members.js
index eab15578f0f..45a3366197b 100644
--- a/app/assets/javascripts/sidebar/track_invite_members.js
+++ b/app/assets/javascripts/sidebar/track_invite_members.js
@@ -2,10 +2,12 @@ import $ from 'jquery';
import Tracking from '~/tracking';
export default function initTrackInviteMembers(userDropdown) {
- const { trackEvent, trackLabel } = userDropdown.querySelector('.js-invite-members-track').dataset;
+ const { trackAction, trackLabel } = userDropdown.querySelector(
+ '.js-invite-members-track',
+ ).dataset;
$(userDropdown).on('shown.bs.dropdown', () => {
- Tracking.event(undefined, trackEvent, {
+ Tracking.event(undefined, trackAction, {
label: trackLabel,
});
});
diff --git a/app/assets/javascripts/snippet/snippet_show.js b/app/assets/javascripts/snippet/snippet_show.js
index 22dffa90cef..6d0e4770e1c 100644
--- a/app/assets/javascripts/snippet/snippet_show.js
+++ b/app/assets/javascripts/snippet/snippet_show.js
@@ -1,12 +1,12 @@
import loadAwardsHandler from '~/awards_handler';
-import initNotes from '~/init_notes';
+import initDeprecatedNotes from '~/init_deprecated_notes';
import SnippetsAppFactory from '~/snippets';
import SnippetsShow from '~/snippets/components/show.vue';
import ZenMode from '~/zen_mode';
SnippetsAppFactory(document.getElementById('js-snippet-view'), SnippetsShow);
-initNotes();
+initDeprecatedNotes();
loadAwardsHandler();
// eslint-disable-next-line no-new
diff --git a/app/assets/javascripts/snippets/components/snippet_description_view.vue b/app/assets/javascripts/snippets/components/snippet_description_view.vue
index e462f20535b..62d95a650da 100644
--- a/app/assets/javascripts/snippets/components/snippet_description_view.vue
+++ b/app/assets/javascripts/snippets/components/snippet_description_view.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import MarkdownFieldView from '~/vue_shared/components/markdown/field_view.vue';
export default {
@@ -17,6 +16,9 @@ export default {
</script>
<template>
<markdown-field-view class="snippet-description" data-qa-selector="snippet_description_content">
- <div class="md js-snippet-description" v-html="description"></div>
+ <div
+ class="md js-snippet-description"
+ v-html="description /* eslint-disable-line vue/no-v-html */"
+ ></div>
</markdown-field-view>
</template>
diff --git a/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_identifier_instance_text.js b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_identifier_instance_text.js
index d770dd18d7f..e41dc51457a 100644
--- a/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_identifier_instance_text.js
+++ b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_identifier_instance_text.js
@@ -18,7 +18,7 @@ Regexp notes:
const identifierInstanceRegex = /((?:\[.+?\]){1}(?:\[\]|\[.+?\])?(?!:))/g;
const isIdentifierInstance = (literal) => {
- // Reset lastIndex as global flag in regexp are stateful (https://stackoverflow.com/a/11477448)
+ // Reset lastIndex as global flag in regexp are stateful
identifierInstanceRegex.lastIndex = 0;
return identifierInstanceRegex.test(literal);
};
diff --git a/app/assets/javascripts/tracking/constants.js b/app/assets/javascripts/tracking/constants.js
index 598111e4086..062a3404355 100644
--- a/app/assets/javascripts/tracking/constants.js
+++ b/app/assets/javascripts/tracking/constants.js
@@ -24,3 +24,7 @@ export const LOAD_ACTION_ATTR_SELECTOR = '[data-track-action="render"]';
export const DEPRECATED_EVENT_ATTR_SELECTOR = '[data-track-event]';
export const DEPRECATED_LOAD_EVENT_ATTR_SELECTOR = '[data-track-event="render"]';
+
+export const URLS_CACHE_STORAGE_KEY = 'gl-snowplow-pseudonymized-urls';
+
+export const REFERRER_TTL = 24 * 60 * 60 * 1000;
diff --git a/app/assets/javascripts/tracking/index.js b/app/assets/javascripts/tracking/index.js
index 5417e2d969b..7e99ecb4f4e 100644
--- a/app/assets/javascripts/tracking/index.js
+++ b/app/assets/javascripts/tracking/index.js
@@ -1,3 +1,4 @@
+import { getAllExperimentContexts } from '~/experimentation/utils';
import { DEFAULT_SNOWPLOW_OPTIONS } from './constants';
import getStandardContext from './get_standard_context';
import Tracking from './tracking';
@@ -38,10 +39,14 @@ export function initDefaultTrackers() {
const opts = { ...DEFAULT_SNOWPLOW_OPTIONS, ...window.snowplowOptions };
+ // must be before initializing the trackers
+ Tracking.setAnonymousUrls();
+
window.snowplow('enableActivityTracking', 30, 30);
// must be after enableActivityTracking
const standardContext = getStandardContext();
- window.snowplow('trackPageView', null, [standardContext]);
+ const experimentContexts = getAllExperimentContexts();
+ window.snowplow('trackPageView', null, [standardContext, ...experimentContexts]);
if (window.snowplowOptions.formTracking) {
Tracking.enableFormTracking(opts.formTrackingConfig);
diff --git a/app/assets/javascripts/tracking/tracking.js b/app/assets/javascripts/tracking/tracking.js
index a1f745bc172..657e0a79911 100644
--- a/app/assets/javascripts/tracking/tracking.js
+++ b/app/assets/javascripts/tracking/tracking.js
@@ -1,7 +1,14 @@
import { LOAD_ACTION_ATTR_SELECTOR, DEPRECATED_LOAD_EVENT_ATTR_SELECTOR } from './constants';
import { dispatchSnowplowEvent } from './dispatch_snowplow_event';
import getStandardContext from './get_standard_context';
-import { getEventHandlers, createEventPayload, renameKey, addExperimentContext } from './utils';
+import {
+ getEventHandlers,
+ createEventPayload,
+ renameKey,
+ addExperimentContext,
+ getReferrersCache,
+ addReferrersCacheEntry,
+} from './utils';
export default class Tracking {
static queuedEvents = [];
@@ -159,6 +166,37 @@ export default class Tracking {
}
/**
+ * Replaces the URL and referrer for the default web context
+ * if the replacements are available.
+ *
+ * @returns {undefined}
+ */
+ static setAnonymousUrls() {
+ const { snowplowPseudonymizedPageUrl: pageUrl } = window.gl;
+
+ if (!pageUrl) {
+ return;
+ }
+
+ const referrers = getReferrersCache();
+ const pageLinks = Object.seal({ url: '', referrer: '', originalUrl: window.location.href });
+
+ pageLinks.url = `${pageUrl}${window.location.hash}`;
+ window.snowplow('setCustomUrl', pageLinks.url);
+
+ if (document.referrer) {
+ const node = referrers.find((links) => links.originalUrl === document.referrer);
+
+ if (node) {
+ pageLinks.referrer = node.url;
+ window.snowplow('setReferrerUrl', pageLinks.referrer);
+ }
+ }
+
+ addReferrersCacheEntry(referrers, pageLinks);
+ }
+
+ /**
* Returns an implementation of this class in the form of
* a Vue mixin.
*
diff --git a/app/assets/javascripts/tracking/utils.js b/app/assets/javascripts/tracking/utils.js
index 1189b2168ad..3507872b511 100644
--- a/app/assets/javascripts/tracking/utils.js
+++ b/app/assets/javascripts/tracking/utils.js
@@ -6,6 +6,8 @@ import {
LOAD_ACTION_ATTR_SELECTOR,
DEPRECATED_EVENT_ATTR_SELECTOR,
DEPRECATED_LOAD_EVENT_ATTR_SELECTOR,
+ URLS_CACHE_STORAGE_KEY,
+ REFERRER_TTL,
} from './constants';
export const addExperimentContext = (opts) => {
@@ -100,3 +102,25 @@ export const renameKey = (o, oldKey, newKey) => {
return ret;
};
+
+export const filterOldReferrersCacheEntries = (cache) => {
+ const now = Date.now();
+
+ return cache.filter((entry) => entry.timestamp && entry.timestamp > now - REFERRER_TTL);
+};
+
+export const getReferrersCache = () => {
+ try {
+ const referrers = JSON.parse(window.localStorage.getItem(URLS_CACHE_STORAGE_KEY) || '[]');
+
+ return filterOldReferrersCacheEntries(referrers);
+ } catch {
+ return [];
+ }
+};
+
+export const addReferrersCacheEntry = (cache, entry) => {
+ const referrers = JSON.stringify([{ ...entry, timestamp: Date.now() }, ...cache]);
+
+ window.localStorage.setItem(URLS_CACHE_STORAGE_KEY, referrers);
+};
diff --git a/app/assets/javascripts/user_popovers.js b/app/assets/javascripts/user_popovers.js
index 0e25f71fe05..7a7518bcf83 100644
--- a/app/assets/javascripts/user_popovers.js
+++ b/app/assets/javascripts/user_popovers.js
@@ -1,7 +1,4 @@
import Vue from 'vue';
-
-import { sanitize } from '~/lib/dompurify';
-
import UsersCache from './lib/utils/users_cache';
import UserPopover from './vue_shared/components/user_popover/user_popover.vue';
@@ -41,7 +38,6 @@ const populateUserInfo = (user) => {
name: userData.name,
location: userData.location,
bio: userData.bio,
- bioHtml: sanitize(userData.bio_html),
workInformation: userData.work_information,
websiteUrl: userData.website_url,
pronouns: userData.pronouns,
diff --git a/app/assets/javascripts/users_select/index.js b/app/assets/javascripts/users_select/index.js
index 7c17ce85cc6..69b3c27173f 100644
--- a/app/assets/javascripts/users_select/index.js
+++ b/app/assets/javascripts/users_select/index.js
@@ -536,9 +536,6 @@ function UsersSelect(currentUser, els, options = {}) {
opened(e) {
const $el = $(e.currentTarget);
const selected = getSelected();
- if ($dropdown.hasClass('js-issue-board-sidebar') && selected.length === 0) {
- this.addInput($dropdown.data('fieldName'), 0, {});
- }
$el.find('.is-active').removeClass('is-active');
function highlightSelected(id) {
@@ -547,8 +544,6 @@ function UsersSelect(currentUser, els, options = {}) {
if (selected.length > 0) {
getSelected().forEach((selectedId) => highlightSelected(selectedId));
- } else if ($dropdown.hasClass('js-issue-board-sidebar')) {
- highlightSelected(0);
} else {
highlightSelected(selectedId);
}
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.vue
index ac6368a3025..306026072a3 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { s__, n__ } from '~/locale';
export default {
@@ -32,11 +31,16 @@ export default {
</script>
<template>
<section class="mr-info-list gl-ml-7 gl-pb-5">
- <p v-if="relatedLinks.closing">{{ closesText }} <span v-html="relatedLinks.closing"></span></p>
+ <p v-if="relatedLinks.closing">
+ {{ closesText }}
+ <span v-html="relatedLinks.closing /* eslint-disable-line vue/no-v-html */"></span>
+ </p>
<p v-if="relatedLinks.mentioned">
{{ n__('mrWidget|Mentions issue', 'mrWidget|Mentions issues', relatedLinks.mentionedCount) }}
- <span v-html="relatedLinks.mentioned"></span>
+ <span v-html="relatedLinks.mentioned /* eslint-disable-line vue/no-v-html */"></span>
+ </p>
+ <p v-if="relatedLinks.assignToMe">
+ <span v-html="relatedLinks.assignToMe /* eslint-disable-line vue/no-v-html */"></span>
</p>
- <p v-if="relatedLinks.assignToMe"><span v-html="relatedLinks.assignToMe"></span></p>
</section>
</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_suggest_pipeline.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_suggest_pipeline.vue
index d2581f57837..f3673005c45 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_suggest_pipeline.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_suggest_pipeline.vue
@@ -98,7 +98,7 @@ export default {
data-testid="add-pipeline-link"
:data-track-property="humanAccess"
:data-track-value="$options.SP_LINK_TRACK_VALUE"
- :data-track-event="$options.SP_LINK_TRACK_EVENT"
+ :data-track-action="$options.SP_LINK_TRACK_EVENT"
:data-track-label="$options.SP_TRACK_LABEL"
>
{{ content }}
@@ -139,7 +139,7 @@ export default {
:href="pipelinePath"
:data-track-property="humanAccess"
:data-track-value="$options.SP_SHOW_TRACK_VALUE"
- :data-track-event="$options.SP_SHOW_TRACK_EVENT"
+ :data-track-action="$options.SP_SHOW_TRACK_EVENT"
:data-track-label="$options.SP_TRACK_LABEL"
>
{{ __('Show me how to add a pipeline') }}
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/review_app_link.vue b/app/assets/javascripts/vue_merge_request_widget/components/review_app_link.vue
index ebd2b5cd22d..e31e69d0f3a 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/review_app_link.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/review_app_link.vue
@@ -39,7 +39,7 @@ export default {
target="_blank"
rel="noopener noreferrer nofollow"
:class="cssClass"
- data-track-event="open_review_app"
+ data-track-action="open_review_app"
data-track-label="review_app"
>
{{ display.text }} <gl-icon class="fgray" name="external-link" />
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/commits_header.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/commits_header.vue
index d331f1690f5..a55dba92e16 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/commits_header.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/commits_header.vue
@@ -1,5 +1,5 @@
<script>
-/* eslint-disable vue/no-v-html */
+/* eslint-disable @gitlab/require-string-literal-i18n-helpers */
import { GlButton } from '@gitlab/ui';
import { escape } from 'lodash';
import { __, n__, sprintf, s__ } from '~/locale';
@@ -89,7 +89,10 @@ export default {
/>
<span v-if="expanded">{{ __('Collapse') }}</span>
<span v-else>
- <span class="vertical-align-middle" v-html="message"></span>
+ <span
+ class="vertical-align-middle"
+ v-html="message /* eslint-disable-line vue/no-v-html */"
+ ></span>
<gl-button variant="link" class="modify-message-button">
{{ modifyLinkMessage }}
</gl-button>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/merge_checks_failed.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/merge_checks_failed.vue
new file mode 100644
index 00000000000..503ddf8a396
--- /dev/null
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/merge_checks_failed.vue
@@ -0,0 +1,75 @@
+<script>
+import { GlButton } from '@gitlab/ui';
+import { s__ } from '~/locale';
+import notesEventHub from '~/notes/event_hub';
+import StatusIcon from '../mr_widget_status_icon.vue';
+
+export default {
+ i18n: {
+ pipelineFailed: s__(
+ 'mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure.',
+ ),
+ approvalNeeded: s__('mrWidget|You can only merge once this merge request is approved.'),
+ unresolvedDiscussions: s__('mrWidget|Merge blocked: all threads must be resolved.'),
+ },
+ components: {
+ StatusIcon,
+ GlButton,
+ },
+ props: {
+ mr: {
+ type: Object,
+ required: true,
+ },
+ },
+ computed: {
+ failedText() {
+ if (this.mr.isPipelineFailed) {
+ return this.$options.i18n.pipelineFailed;
+ } else if (this.mr.approvals && !this.mr.isApproved) {
+ return this.$options.i18n.approvalNeeded;
+ } else if (this.mr.hasMergeableDiscussionsState) {
+ return this.$options.i18n.unresolvedDiscussions;
+ }
+
+ return null;
+ },
+ },
+ methods: {
+ jumpToFirstUnresolvedDiscussion() {
+ notesEventHub.$emit('jumpToFirstUnresolvedDiscussion');
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="mr-widget-body media gl-flex-wrap">
+ <status-icon status="warning" />
+ <p class="media-body gl-m-0! gl-font-weight-bold gl-text-black-normal!">
+ {{ failedText }}
+ <template v-if="failedText == $options.i18n.unresolvedDiscussions">
+ <gl-button
+ class="gl-ml-3"
+ size="small"
+ variant="confirm"
+ data-testid="jumpToUnresolved"
+ @click="jumpToFirstUnresolvedDiscussion"
+ >
+ {{ s__('mrWidget|Jump to first unresolved thread') }}
+ </gl-button>
+ <gl-button
+ v-if="mr.createIssueToResolveDiscussionsPath"
+ :href="mr.createIssueToResolveDiscussionsPath"
+ class="gl-ml-3"
+ size="small"
+ variant="confirm"
+ category="secondary"
+ data-testid="resolveIssue"
+ >
+ {{ s__('mrWidget|Create issue to resolve all threads') }}
+ </gl-button>
+ </template>
+ </p>
+ </div>
+</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue
index 22f41b43095..1976d3639a6 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { GlButton, GlSkeletonLoader } from '@gitlab/ui';
import { escape } from 'lodash';
import createFlash from '~/flash';
@@ -171,7 +170,7 @@ export default {
v-if="!rebaseInProgress && !canPushToSourceBranch"
class="gl-font-weight-bold gl-ml-0!"
data-testid="rebase-message"
- v-html="fastForwardMergeText"
+ v-html="fastForwardMergeText /* eslint-disable-line vue/no-v-html */"
></span>
<div
v-if="!rebaseInProgress && canPushToSourceBranch && !isMakingRequest"
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/new_ready_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/new_ready_to_merge.vue
new file mode 100644
index 00000000000..9a7743348ff
--- /dev/null
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/new_ready_to_merge.vue
@@ -0,0 +1,49 @@
+<script>
+import mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_variables';
+import readyToMergeQuery from '../../queries/states/new_ready_to_merge.query.graphql';
+import StatusIcon from '../mr_widget_status_icon.vue';
+
+export default {
+ apollo: {
+ canMerge: {
+ query: readyToMergeQuery,
+ skip() {
+ return !this.mr || !window.gon?.features?.mergeRequestWidgetGraphql;
+ },
+ variables() {
+ return this.mergeRequestQueryVariables;
+ },
+ update: (data) => data?.project?.mergeRequest?.userPermissions?.canMerge,
+ },
+ },
+ components: {
+ StatusIcon,
+ },
+ mixins: [mergeRequestQueryVariablesMixin],
+ props: {
+ mr: {
+ type: Object,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ canMerge: null,
+ };
+ },
+};
+</script>
+
+<template>
+ <div class="mr-widget-body media">
+ <status-icon status="success" />
+ <p class="media-body gl-m-0! gl-font-weight-bold">
+ <template v-if="canMerge">
+ {{ __('Ready to merge!') }}
+ </template>
+ <template v-else>
+ {{ __('Ready to merge by members who can write to the target branch.') }}
+ </template>
+ </p>
+ </div>
+</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue
index 01e0b91bd4a..7827c79cd31 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue
@@ -1,6 +1,5 @@
<script>
-/* eslint-disable vue/no-v-html */
-import { GlButton, GlSprintf, GlLink } from '@gitlab/ui';
+import { GlButton, GlSprintf, GlLink, GlSafeHtmlDirective } from '@gitlab/ui';
import emptyStateSVG from 'icons/_mr_widget_empty_state.svg';
import { helpPagePath } from '~/helpers/help_page_helper';
@@ -11,6 +10,9 @@ export default {
GlSprintf,
GlLink,
},
+ directives: {
+ SafeHtml: GlSafeHtmlDirective,
+ },
props: {
mr: {
type: Object,
@@ -21,6 +23,7 @@ export default {
return { emptyStateSVG };
},
ciHelpPage: helpPagePath('/ci/quick_start/index.html'),
+ safeHtmlConfig: { ADD_TAGS: ['use'] },
};
</script>
@@ -30,7 +33,7 @@ export default {
<div
class="artwork col-md-5 order-md-last col-12 text-center d-flex justify-content-center align-items-center"
>
- <span v-html="emptyStateSVG"></span>
+ <span v-safe-html:[$options.safeHtmlConfig]="emptyStateSVG"></span>
</div>
<div class="text col-md-7 order-md-first col-12">
<p class="highlight">
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue
index f33f4d3fda0..7df65e995a5 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue
@@ -28,6 +28,7 @@ import {
CONFIRM,
WARNING,
MT_MERGE_STRATEGY,
+ PIPELINE_FAILED_STATE,
} from '../../constants';
import eventHub from '../../event_hub';
import mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_variables';
@@ -39,7 +40,6 @@ import CommitsHeader from './commits_header.vue';
import SquashBeforeMerge from './squash_before_merge.vue';
const PIPELINE_RUNNING_STATE = 'running';
-const PIPELINE_FAILED_STATE = 'failed';
const PIPELINE_PENDING_STATE = 'pending';
const PIPELINE_SUCCESS_STATE = 'success';
@@ -105,6 +105,10 @@ export default {
import(
'ee_component/vue_merge_request_widget/components/merge_immediately_confirmation_dialog.vue'
),
+ MergeTrainFailedPipelineConfirmationDialog: () =>
+ import(
+ 'ee_component/vue_merge_request_widget/components/merge_train_failed_pipeline_confirmation_dialog.vue'
+ ),
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -125,6 +129,7 @@ export default {
squashBeforeMerge: this.mr.squashIsSelected,
isSquashReadOnly: this.mr.squashIsReadonly,
squashCommitMessage: this.mr.squashCommitMessage,
+ isPipelineFailedModalVisible: false,
};
},
computed: {
@@ -327,7 +332,12 @@ export default {
: this.mr.commitMessageWithDescription;
this.commitMessage = includeDescription ? commitMessageWithDescription : commitMessage;
},
- handleMergeButtonClick(useAutoMerge, mergeImmediately = false) {
+ handleMergeButtonClick(useAutoMerge, mergeImmediately = false, confirmationClicked = false) {
+ if (this.showFailedPipelineModal && !confirmationClicked) {
+ this.isPipelineFailedModalVisible = true;
+ return;
+ }
+
if (mergeImmediately) {
this.isMergingImmediately = true;
}
@@ -386,7 +396,7 @@ export default {
}
},
onMergeImmediatelyConfirmation() {
- this.handleMergeButtonClick(false, true);
+ this.handleMergeButtonClick(false, true, true);
},
initiateMergePolling() {
simplePoll(
@@ -522,6 +532,11 @@ export default {
@mergeImmediately="onMergeImmediatelyConfirmation"
/>
</gl-dropdown>
+ <merge-train-failed-pipeline-confirmation-dialog
+ :visible="isPipelineFailedModalVisible"
+ @startMergeTrain="onStartMergeTrainConfirmation"
+ @cancel="isPipelineFailedModalVisible = false"
+ />
</gl-button-group>
<div
v-if="shouldShowMergeControls"
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue
index c6ce29acb09..69e4df0ca11 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue
@@ -46,7 +46,7 @@ export default {
size="small"
icon="issue-new"
>
- {{ s__('mrWidget|Resolve all threads in new issue') }}
+ {{ s__('mrWidget|Create issue to resolve all threads') }}
</gl-button>
</div>
</div>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue
index a1eb77479bd..393c599c7e8 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue
@@ -124,7 +124,7 @@ export default {
},
}) => {
createFlash({
- message: __('The merge request can now be merged.'),
+ message: __('Marked as ready. Merging is now allowed.'),
type: 'notice',
});
$('.merge-request .detail-page-description .title').text(title);
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/terraform/terraform_plan.vue b/app/assets/javascripts/vue_merge_request_widget/components/terraform/terraform_plan.vue
index 427ab0842ea..87a310efe78 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/terraform/terraform_plan.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/terraform/terraform_plan.vue
@@ -104,7 +104,7 @@ export default {
:href="plan.job_path"
target="_blank"
data-testid="terraform-report-link"
- data-track-event="click_terraform_mr_plan_button"
+ data-track-action="click_terraform_mr_plan_button"
data-track-label="mr_widget_terraform_mr_plan_button"
data-track-property="terraform_mr_plan_button"
class="btn btn-sm"
diff --git a/app/assets/javascripts/vue_merge_request_widget/constants.js b/app/assets/javascripts/vue_merge_request_widget/constants.js
index d067e531fad..f5710f46b7e 100644
--- a/app/assets/javascripts/vue_merge_request_widget/constants.js
+++ b/app/assets/javascripts/vue_merge_request_widget/constants.js
@@ -10,6 +10,8 @@ export const MWPS_MERGE_STRATEGY = 'merge_when_pipeline_succeeds';
export const MTWPS_MERGE_STRATEGY = 'add_to_merge_train_when_pipeline_succeeds';
export const MT_MERGE_STRATEGY = 'merge_train';
+export const PIPELINE_FAILED_STATE = 'failed';
+
export const AUTO_MERGE_STRATEGIES = [MWPS_MERGE_STRATEGY, MTWPS_MERGE_STRATEGY, MT_MERGE_STRATEGY];
// SP - "Suggest Pipelines"
diff --git a/app/assets/javascripts/vue_merge_request_widget/index.js b/app/assets/javascripts/vue_merge_request_widget/index.js
index 3a3a1329483..f5dbcec7dbe 100644
--- a/app/assets/javascripts/vue_merge_request_widget/index.js
+++ b/app/assets/javascripts/vue_merge_request_widget/index.js
@@ -6,9 +6,8 @@ import Vue from 'vue';
import VueApollo from 'vue-apollo';
import MrWidgetOptions from 'ee_else_ce/vue_merge_request_widget/mr_widget_options.vue';
import createDefaultClient from '~/lib/graphql';
+import { parseBoolean } from '~/lib/utils/common_utils';
import Translate from '../vue_shared/translate';
-import { registerExtension } from './components/extensions';
-import issueExtension from './extensions/issues';
Vue.use(Translate);
Vue.use(VueApollo);
@@ -28,13 +27,13 @@ export default () => {
gl.mrWidgetData.gitlabLogo = gon.gitlab_logo;
gl.mrWidgetData.defaultAvatarUrl = gon.default_avatar_url;
- registerExtension(issueExtension);
-
const vm = new Vue({
el: '#js-vue-mr-widget',
provide: {
artifactsEndpoint: gl.mrWidgetData.artifacts_endpoint,
artifactsEndpointPlaceholder: gl.mrWidgetData.artifacts_endpoint_placeholder,
+ falsePositiveDocUrl: gl.mrWidgetData.false_positive_doc_url,
+ canViewFalsePositive: parseBoolean(gl.mrWidgetData.can_view_false_positive),
},
...MrWidgetOptions,
apolloProvider,
diff --git a/app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js b/app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js
index 23215982e6e..9d8e5d12d58 100644
--- a/app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js
+++ b/app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js
@@ -38,5 +38,13 @@ export default {
pipelineId() {
return this.pipeline.id;
},
+ showFailedPipelineModal() {
+ return false;
+ },
+ },
+ methods: {
+ onStartMergeTrainConfirmation() {
+ return false;
+ },
},
};
diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
index a8a9df598f5..78aa3941bfe 100644
--- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
@@ -12,9 +12,6 @@ import { sprintf, s__, __ } from '~/locale';
import Project from '~/pages/projects/project';
import SmartInterval from '~/smart_interval';
import { setFaviconOverlay } from '../lib/utils/favicon';
-import GroupedAccessibilityReportsApp from '../reports/accessibility_report/grouped_accessibility_reports_app.vue';
-import GroupedCodequalityReportsApp from '../reports/codequality_report/grouped_codequality_reports_app.vue';
-import GroupedTestReportsApp from '../reports/grouped_test_report/grouped_test_reports_app.vue';
import Loading from './components/loading.vue';
import MrWidgetAlertMessage from './components/mr_widget_alert_message.vue';
import WidgetHeader from './components/mr_widget_header.vue';
@@ -42,7 +39,6 @@ import ShaMismatch from './components/states/sha_mismatch.vue';
import UnresolvedDiscussionsState from './components/states/unresolved_discussions.vue';
import WorkInProgressState from './components/states/work_in_progress.vue';
// import ExtensionsContainer from './components/extensions/container';
-import TerraformPlan from './components/terraform/mr_widget_terraform_container.vue';
import eventHub from './event_hub';
import mergeRequestQueryVariablesMixin from './mixins/merge_request_query_variables';
import getStateQuery from './queries/get_state.query.graphql';
@@ -72,7 +68,9 @@ export default {
'mr-widget-nothing-to-merge': NothingToMergeState,
'mr-widget-not-allowed': NotAllowedState,
'mr-widget-missing-branch': MissingBranchState,
- 'mr-widget-ready-to-merge': ReadyToMergeState,
+ 'mr-widget-ready-to-merge': window.gon?.features?.restructuredMrWidget
+ ? () => import('./components/states/new_ready_to_merge.vue')
+ : ReadyToMergeState,
'sha-mismatch': ShaMismatch,
'mr-widget-checking': CheckingState,
'mr-widget-unresolved-discussions': UnresolvedDiscussionsState,
@@ -82,12 +80,16 @@ export default {
'mr-widget-auto-merge-failed': AutoMergeFailed,
'mr-widget-rebase': RebaseState,
SourceBranchRemovalStatus,
- GroupedCodequalityReportsApp,
- GroupedTestReportsApp,
- TerraformPlan,
- GroupedAccessibilityReportsApp,
+ GroupedCodequalityReportsApp: () =>
+ import('../reports/codequality_report/grouped_codequality_reports_app.vue'),
+ GroupedTestReportsApp: () =>
+ import('../reports/grouped_test_report/grouped_test_reports_app.vue'),
+ TerraformPlan: () => import('./components/terraform/mr_widget_terraform_container.vue'),
+ GroupedAccessibilityReportsApp: () =>
+ import('../reports/accessibility_report/grouped_accessibility_reports_app.vue'),
MrWidgetApprovals,
SecurityReportsApp: () => import('~/vue_shared/security_reports/security_reports_app.vue'),
+ MergeChecksFailed: () => import('./components/states/merge_checks_failed.vue'),
},
apollo: {
state: {
diff --git a/app/assets/javascripts/vue_merge_request_widget/queries/states/new_ready_to_merge.query.graphql b/app/assets/javascripts/vue_merge_request_widget/queries/states/new_ready_to_merge.query.graphql
new file mode 100644
index 00000000000..3b34be73c15
--- /dev/null
+++ b/app/assets/javascripts/vue_merge_request_widget/queries/states/new_ready_to_merge.query.graphql
@@ -0,0 +1,9 @@
+query readyToMergeQuery($projectPath: ID!, $iid: String!) {
+ project(fullPath: $projectPath) {
+ mergeRequest(iid: $iid) {
+ userPermissions {
+ canMerge
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/get_state_key.js b/app/assets/javascripts/vue_merge_request_widget/stores/get_state_key.js
index 04800cf43f0..65d78fc283c 100644
--- a/app/assets/javascripts/vue_merge_request_widget/stores/get_state_key.js
+++ b/app/assets/javascripts/vue_merge_request_widget/stores/get_state_key.js
@@ -1,7 +1,9 @@
import { stateKey } from './state_maps';
export default function deviseState() {
- if (this.projectArchived) {
+ if (this.hasMergeChecksFailed) {
+ return stateKey.mergeChecksFailed;
+ } else if (this.projectArchived) {
return stateKey.archived;
} else if (this.branchMissing) {
return stateKey.missingBranch;
@@ -25,7 +27,7 @@ export default function deviseState() {
return stateKey.shaMismatch;
} else if (this.autoMergeEnabled && !this.mergeError) {
return stateKey.autoMergeEnabled;
- } else if (!this.canMerge) {
+ } else if (!this.canMerge && !window.gon?.features?.restructuredMrWidget) {
return stateKey.notAllowedToMerge;
} else if (this.canBeMerged) {
return stateKey.readyToMerge;
diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
index 8979fe621ac..29e0c867f6b 100644
--- a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
+++ b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
@@ -347,4 +347,13 @@ export default class MergeRequestStore {
this.approvals = data;
this.isApproved = data.approved || false;
}
+
+ get hasMergeChecksFailed() {
+ if (!window.gon?.features?.restructuredMrWidget) return false;
+
+ return (
+ this.hasMergeableDiscussionsState ||
+ (this.onlyAllowMergeIfPipelineSucceeds && this.isPipelineFailed)
+ );
+ }
}
diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/state_maps.js b/app/assets/javascripts/vue_merge_request_widget/stores/state_maps.js
index 28507bba3e5..04454882666 100644
--- a/app/assets/javascripts/vue_merge_request_widget/stores/state_maps.js
+++ b/app/assets/javascripts/vue_merge_request_widget/stores/state_maps.js
@@ -18,6 +18,7 @@ const stateToComponentMap = {
autoMergeFailed: 'mr-widget-auto-merge-failed',
shaMismatch: 'sha-mismatch',
rebase: 'mr-widget-rebase',
+ mergeChecksFailed: 'mergeChecksFailed',
};
const statesToShowHelpWidget = [
@@ -50,6 +51,7 @@ export const stateKey = {
readyToMerge: 'readyToMerge',
rebase: 'rebase',
merged: 'merged',
+ mergeChecksFailed: 'mergeChecksFailed',
};
export default {
diff --git a/app/assets/javascripts/vue_shared/alert_details/components/system_notes/system_note.vue b/app/assets/javascripts/vue_shared/alert_details/components/system_notes/system_note.vue
index 3705e36a579..f8f1613879f 100644
--- a/app/assets/javascripts/vue_shared/alert_details/components/system_notes/system_note.vue
+++ b/app/assets/javascripts/vue_shared/alert_details/components/system_notes/system_note.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { GlIcon } from '@gitlab/ui';
import NoteHeader from '~/notes/components/note_header.vue';
@@ -40,7 +39,7 @@ export default {
<div class="note-header">
<note-header :author="noteAuthor" :created-at="note.createdAt" :note-id="note.id">
- <span v-html="note.bodyHtml"></span>
+ <span v-html="note.bodyHtml /* eslint-disable-line vue/no-v-html */"></span>
</note-header>
</div>
</div>
diff --git a/app/assets/javascripts/vue_shared/components/awards_list.vue b/app/assets/javascripts/vue_shared/components/awards_list.vue
index f4c73d12923..82a28d4cb5f 100644
--- a/app/assets/javascripts/vue_shared/components/awards_list.vue
+++ b/app/assets/javascripts/vue_shared/components/awards_list.vue
@@ -1,6 +1,5 @@
<script>
-/* eslint-disable vue/no-v-html */
-import { GlIcon, GlButton, GlTooltipDirective } from '@gitlab/ui';
+import { GlIcon, GlButton, GlTooltipDirective, GlSafeHtmlDirective } from '@gitlab/ui';
import { groupBy } from 'lodash';
import EmojiPicker from '~/emoji/components/picker.vue';
import { __, sprintf } from '~/locale';
@@ -18,6 +17,7 @@ export default {
},
directives: {
GlTooltip: GlTooltipDirective,
+ SafeHtml: GlSafeHtmlDirective,
},
mixins: [glFeatureFlagsMixin()],
props: {
@@ -164,6 +164,7 @@ export default {
this.isMenuOpen = menuOpen;
},
},
+ safeHtmlConfig: { ADD_TAGS: ['gl-emoji'] },
};
</script>
@@ -180,7 +181,11 @@ export default {
@click="handleAward(awardList.name)"
>
<template #emoji>
- <span class="award-emoji-block" data-testid="award-html" v-html="awardList.html"></span>
+ <span
+ v-safe-html:[$options.safeHtmlConfig]="awardList.html"
+ class="award-emoji-block"
+ data-testid="award-html"
+ ></span>
</template>
<span class="js-counter">{{ awardList.list.length }}</span>
</gl-button>
diff --git a/app/assets/javascripts/vue_shared/components/blob_viewers/simple_viewer.vue b/app/assets/javascripts/vue_shared/components/blob_viewers/simple_viewer.vue
index 0589b47edbd..84770dbac6f 100644
--- a/app/assets/javascripts/vue_shared/components/blob_viewers/simple_viewer.vue
+++ b/app/assets/javascripts/vue_shared/components/blob_viewers/simple_viewer.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { GlIcon } from '@gitlab/ui';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { HIGHLIGHT_CLASS_NAME } from './constants';
@@ -75,7 +74,9 @@ export default {
</a>
</div>
<div class="blob-content">
- <pre class="code highlight"><code :data-blob-hash="blobHash" v-html="content"></code></pre>
+ <pre
+ class="code highlight"
+ ><code :data-blob-hash="blobHash" v-html="content /* eslint-disable-line vue/no-v-html */"></code></pre>
</div>
</div>
</div>
diff --git a/app/assets/javascripts/vue_shared/components/code_block.vue b/app/assets/javascripts/vue_shared/components/code_block.vue
index 1928bf6dac5..9856f35c7f6 100644
--- a/app/assets/javascripts/vue_shared/components/code_block.vue
+++ b/app/assets/javascripts/vue_shared/components/code_block.vue
@@ -24,8 +24,13 @@ export default {
return isScrollable ? scrollableStyles : null;
},
},
+ userColorScheme: window.gon.user_color_scheme,
};
</script>
<template>
- <pre class="code-block rounded" :style="styleObject"><code class="d-block">{{ code }}</code></pre>
+ <pre
+ class="code-block rounded code"
+ :class="$options.userColorScheme"
+ :style="styleObject"
+ ><code class="d-block">{{ code }}</code></pre>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/color_picker/color_picker.vue b/app/assets/javascripts/vue_shared/components/color_picker/color_picker.vue
index 0ff33e462b4..3c21b14894b 100644
--- a/app/assets/javascripts/vue_shared/components/color_picker/color_picker.vue
+++ b/app/assets/javascripts/vue_shared/components/color_picker/color_picker.vue
@@ -110,7 +110,7 @@ export default {
<div :class="previewColorClasses" :style="previewColor" data-testid="color-preview">
<gl-form-input
type="color"
- class="gl-absolute gl-top-0 gl-left-0 gl-h-full! gl-p-0! gl-m-0! gl-cursor-pointer gl-opacity-0"
+ class="gl-absolute gl-top-0 gl-left-0 gl-h-full! gl-p-0! gl-m-0! gl-opacity-0"
tabindex="-1"
:value="value"
@input="handleColorChange"
diff --git a/app/assets/javascripts/vue_shared/components/commit.vue b/app/assets/javascripts/vue_shared/components/commit.vue
index d1eee62683b..5f50a699034 100644
--- a/app/assets/javascripts/vue_shared/components/commit.vue
+++ b/app/assets/javascripts/vue_shared/components/commit.vue
@@ -136,6 +136,9 @@ export default {
refUrl() {
return this.commitRef.ref_url || this.commitRef.path;
},
+ tooltipTitle() {
+ return this.mergeRequestRef ? this.mergeRequestRef.title : this.commitRef.name;
+ },
},
};
</script>
@@ -148,23 +151,14 @@ export default {
<gl-icon v-else name="branch" />
</div>
- <gl-link
- v-if="mergeRequestRef"
- v-gl-tooltip
- :href="mergeRequestRef.path"
- :title="mergeRequestRef.title"
- class="ref-name"
- >{{ mergeRequestRef.iid }}</gl-link
- >
- <gl-link
- v-else
- v-gl-tooltip
- :href="refUrl"
- :title="commitRef.name"
- class="ref-name"
- data-testid="ref-name"
- >{{ commitRef.name }}</gl-link
- >
+ <tooltip-on-truncate :title="tooltipTitle" truncate-target="child" placement="top">
+ <gl-link v-if="mergeRequestRef" :href="mergeRequestRef.path" class="ref-name">
+ {{ mergeRequestRef.iid }}
+ </gl-link>
+ <gl-link v-else :href="refUrl" class="ref-name" data-testid="ref-name">
+ {{ commitRef.name }}
+ </gl-link>
+ </tooltip-on-truncate>
</template>
<gl-icon name="commit" class="commit-icon js-commit-icon" />
diff --git a/app/assets/javascripts/vue_shared/components/content_viewer/viewers/markdown_viewer.vue b/app/assets/javascripts/vue_shared/components/content_viewer/viewers/markdown_viewer.vue
index 3790a509f26..7b88b36aa0f 100644
--- a/app/assets/javascripts/vue_shared/components/content_viewer/viewers/markdown_viewer.vue
+++ b/app/assets/javascripts/vue_shared/components/content_viewer/viewers/markdown_viewer.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { GlDeprecatedSkeletonLoading as GlSkeletonLoading } from '@gitlab/ui';
import $ from 'jquery';
import '~/behaviors/markdown/render_gfm';
@@ -110,6 +109,10 @@ export default {
<template>
<div ref="markdownPreview" class="md-previewer" data-testid="md-previewer">
<gl-skeleton-loading v-if="isLoading" />
- <div v-else class="md gl-ml-auto gl-mr-auto" v-html="previewContent"></div>
+ <div
+ v-else
+ class="md gl-ml-auto gl-mr-auto"
+ v-html="previewContent /* eslint-disable-line vue/no-v-html */"
+ ></div>
</div>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/diff_stats_dropdown.vue b/app/assets/javascripts/vue_shared/components/diff_stats_dropdown.vue
new file mode 100644
index 00000000000..56e6399a1b7
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/diff_stats_dropdown.vue
@@ -0,0 +1,159 @@
+<script>
+import {
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownText,
+ GlSearchBoxByType,
+ GlSprintf,
+} from '@gitlab/ui';
+import fuzzaldrinPlus from 'fuzzaldrin-plus';
+import { __, n__, s__, sprintf } from '~/locale';
+
+export const i18n = {
+ messageAdditionsDeletions: s__('Diffs|with %{additions} and %{deletions}'),
+ noFilesFound: __('No files found.'),
+ noFileNameAvailable: s__('Diffs|No file name available'),
+ searchFiles: __('Search files'),
+};
+
+export default {
+ i18n,
+ components: {
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownText,
+ GlSearchBoxByType,
+ GlSprintf,
+ },
+ props: {
+ changed: {
+ type: Number,
+ required: true,
+ },
+ added: {
+ type: Number,
+ required: true,
+ },
+ deleted: {
+ type: Number,
+ required: true,
+ },
+ files: {
+ type: Array,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ search: '',
+ };
+ },
+ computed: {
+ filteredFiles() {
+ return this.search.length > 0
+ ? fuzzaldrinPlus.filter(this.files, this.search, { key: 'name' })
+ : this.files;
+ },
+ messageChanged() {
+ return sprintf(
+ n__(
+ 'Diffs|Showing %{dropdownStart}%{count} changed file%{dropdownEnd}',
+ 'Diffs|Showing %{dropdownStart}%{count} changed files%{dropdownEnd}',
+ this.changed,
+ ),
+ { count: this.changed },
+ );
+ },
+
+ additionsText() {
+ return n__('Diffs|%d addition', 'Diffs|%d additions', this.added);
+ },
+ deletionsText() {
+ return n__('Diffs|%d deletion', 'Diffs|%d deletions', this.deleted);
+ },
+ },
+ methods: {
+ jumpToFile(fileHash) {
+ window.location.hash = fileHash;
+ },
+ focusInput() {
+ this.$refs.search.focusInput();
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <gl-sprintf :message="messageChanged">
+ <template #dropdown="{ content: dropdownText }">
+ <gl-dropdown
+ category="tertiary"
+ variant="confirm"
+ :text="dropdownText"
+ data-testid="diff-stats-dropdown"
+ class="gl-vertical-align-baseline"
+ toggle-class="gl-px-0! gl-font-weight-bold!"
+ menu-class="gl-w-auto!"
+ no-flip
+ @shown="focusInput"
+ >
+ <template #header>
+ <gl-search-box-by-type
+ ref="search"
+ v-model.trim="search"
+ :placeholder="$options.i18n.searchFiles"
+ />
+ </template>
+ <gl-dropdown-item
+ v-for="file in filteredFiles"
+ :key="file.href"
+ :icon-name="file.icon"
+ :icon-color="file.iconColor"
+ @click="jumpToFile(file.href)"
+ >
+ <div class="gl-display-flex">
+ <span v-if="file.name" class="gl-font-weight-bold gl-mr-3 gl-text-truncate">{{
+ file.name
+ }}</span>
+ <span v-else class="gl-mr-3 gl-font-weight-bold gl-font-style-italic gl-gray-400">{{
+ $options.i18n.noFileNameAvailable
+ }}</span>
+ <span class="gl-ml-auto gl-white-space-nowrap">
+ <span class="gl-text-green-600">+{{ file.added }}</span>
+ <span class="gl-text-red-500">-{{ file.removed }}</span>
+ </span>
+ </div>
+ <div class="gl-text-gray-700 gl-overflow-hidden gl-text-overflow-ellipsis">
+ {{ file.path }}
+ </div>
+ </gl-dropdown-item>
+ <gl-dropdown-text v-if="!filteredFiles.length">
+ {{ $options.i18n.noFilesFound }}
+ </gl-dropdown-text>
+ </gl-dropdown>
+ </template>
+ </gl-sprintf>
+ <span
+ class="diff-stats-additions-deletions-expanded"
+ data-testid="diff-stats-additions-deletions-expanded"
+ >
+ <gl-sprintf :message="$options.i18n.messageAdditionsDeletions">
+ <template #additions>
+ <span class="gl-text-green-600 gl-font-weight-bold">{{ additionsText }}</span>
+ </template>
+ <template #deletions>
+ <span class="gl-text-red-500 gl-font-weight-bold">{{ deletionsText }}</span>
+ </template>
+ </gl-sprintf>
+ </span>
+
+ <div
+ class="diff-stats-additions-deletions-collapsed gl-float-right gl-display-none"
+ data-testid="diff-stats-additions-deletions-collapsed"
+ >
+ <span class="gl-text-green-600 gl-font-weight-bold">+{{ added }}</span>
+ <span class="gl-text-red-500 gl-font-weight-bold">-{{ deleted }}</span>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/constants.js b/app/assets/javascripts/vue_shared/components/filtered_search_bar/constants.js
index 2e9634819a0..1df65d0a666 100644
--- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/constants.js
+++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/constants.js
@@ -20,19 +20,26 @@ export const OPERATOR_IS_ONLY = [{ value: OPERATOR_IS, description: OPERATOR_IS_
export const OPERATOR_IS_NOT_ONLY = [{ value: OPERATOR_IS_NOT, description: OPERATOR_IS_NOT_TEXT }];
export const OPERATOR_IS_AND_IS_NOT = [...OPERATOR_IS_ONLY, ...OPERATOR_IS_NOT_ONLY];
-export const DEFAULT_LABEL_NONE = { value: FILTER_NONE, text: __(FILTER_NONE) };
-export const DEFAULT_LABEL_ANY = { value: FILTER_ANY, text: __(FILTER_ANY) };
+export const DEFAULT_LABEL_NONE = { value: FILTER_NONE, text: __('None'), title: __('None') };
+export const DEFAULT_LABEL_ANY = { value: FILTER_ANY, text: __('Any'), title: __('Any') };
export const DEFAULT_NONE_ANY = [DEFAULT_LABEL_NONE, DEFAULT_LABEL_ANY];
export const DEFAULT_ITERATIONS = DEFAULT_NONE_ANY.concat([
- { value: FILTER_CURRENT, text: __(FILTER_CURRENT) },
+ { value: FILTER_CURRENT, text: __('Current') },
]);
export const DEFAULT_MILESTONES = DEFAULT_NONE_ANY.concat([
- { value: FILTER_UPCOMING, text: __(FILTER_UPCOMING) },
- { value: FILTER_STARTED, text: __(FILTER_STARTED) },
+ { value: FILTER_UPCOMING, text: __('Upcoming'), title: __('Upcoming') },
+ { value: FILTER_STARTED, text: __('Started'), title: __('Started') },
]);
+export const DEFAULT_MILESTONES_GRAPHQL = [
+ { value: 'any', text: __('Any'), title: __('Any') },
+ { value: 'none', text: __('None'), title: __('None') },
+ { value: '#upcoming', text: __('Upcoming'), title: __('Upcoming') },
+ { value: '#started', text: __('Started'), title: __('Started') },
+];
+
export const SortDirection = {
descending: 'descending',
ascending: 'ascending',
diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_utils.js b/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_utils.js
index 6573f366b52..5cc96471aef 100644
--- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_utils.js
+++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_utils.js
@@ -177,13 +177,10 @@ function filteredSearchTermValue(value) {
* @param {Object} options
* @param {String} [options.filteredSearchTermKey] if set, a FILTERED_SEARCH_TERM filter is created to this parameter. `'search'` is suggested
* @param {String[]} [options.filterNamesAllowList] if set, only this list of filters names is mapped
- * @param {Boolean} [options.legacySpacesDecode] if set, plus symbols (+) are not encoded as spaces. `false` is suggested
* @return {Object} filter object with filter names and their values
*/
-export function urlQueryToFilter(query = '', options = {}) {
- const { filteredSearchTermKey, filterNamesAllowList, legacySpacesDecode = true } = options;
-
- const filters = queryToObject(query, { gatherArrays: true, legacySpacesDecode });
+export function urlQueryToFilter(query = '', { filteredSearchTermKey, filterNamesAllowList } = {}) {
+ const filters = queryToObject(query, { gatherArrays: true });
return Object.keys(filters).reduce((memo, key) => {
const value = filters[key];
if (!value) {
@@ -222,7 +219,7 @@ export function urlQueryToFilter(query = '', options = {}) {
*/
export function getRecentlyUsedSuggestions(recentSuggestionsStorageKey) {
let recentlyUsedSuggestions = [];
- if (AccessorUtilities.isLocalStorageAccessSafe()) {
+ if (AccessorUtilities.canUseLocalStorage()) {
recentlyUsedSuggestions = JSON.parse(localStorage.getItem(recentSuggestionsStorageKey)) || [];
}
return recentlyUsedSuggestions;
@@ -240,7 +237,7 @@ export function setTokenValueToRecentlyUsed(recentSuggestionsStorageKey, tokenVa
recentlyUsedSuggestions.splice(0, 0, { ...tokenValue });
- if (AccessorUtilities.isLocalStorageAccessSafe()) {
+ if (AccessorUtilities.canUseLocalStorage()) {
localStorage.setItem(
recentSuggestionsStorageKey,
JSON.stringify(uniqWith(recentlyUsedSuggestions, isEqual).slice(0, MAX_RECENT_TOKENS_SIZE)),
diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue
index 4b9ad6d8f91..523438f459c 100644
--- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue
+++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue
@@ -39,8 +39,16 @@ export default {
},
methods: {
getActiveMilestone(milestones, data) {
- return milestones.find(
- (milestone) => milestone.title.toLowerCase() === stripQuotes(data).toLowerCase(),
+ /* We need to check default milestones against the value not the
+ * title because there is a discrepancy between the value graphql
+ * accepts and the title.
+ * https://gitlab.com/gitlab-org/gitlab/-/issues/337687#note_648058797
+ */
+
+ return (
+ milestones.find(
+ (milestone) => milestone.title.toLowerCase() === stripQuotes(data).toLowerCase(),
+ ) || this.defaultMilestones.find(({ value }) => value === data)
);
},
fetchMilestones(searchTerm) {
diff --git a/app/assets/javascripts/vue_shared/components/header_ci_component.vue b/app/assets/javascripts/vue_shared/components/header_ci_component.vue
index f169921d8a6..41613bb3307 100644
--- a/app/assets/javascripts/vue_shared/components/header_ci_component.vue
+++ b/app/assets/javascripts/vue_shared/components/header_ci_component.vue
@@ -1,6 +1,5 @@
<script>
-/* eslint-disable vue/no-v-html */
-import { GlTooltipDirective, GlLink, GlButton, GlTooltip } from '@gitlab/ui';
+import { GlTooltipDirective, GlLink, GlButton, GlTooltip, GlSafeHtmlDirective } from '@gitlab/ui';
import { glEmojiTag } from '../../emoji';
import { __, sprintf } from '../../locale';
import CiIconBadge from './ci_badge_link.vue';
@@ -25,6 +24,7 @@ export default {
},
directives: {
GlTooltip: GlTooltipDirective,
+ SafeHtml: GlSafeHtmlDirective,
},
EMOJI_REF: 'EMOJI_REF',
props: {
@@ -37,8 +37,9 @@ export default {
required: true,
},
itemId: {
- type: Number,
- required: true,
+ type: String,
+ required: false,
+ default: '',
},
time: {
type: String,
@@ -86,6 +87,13 @@ export default {
message() {
return this.user?.status?.message;
},
+ item() {
+ if (this.itemId) {
+ return `${this.itemName} #${this.itemId}`;
+ }
+
+ return this.itemName;
+ },
},
methods: {
@@ -93,6 +101,7 @@ export default {
this.$emit('clickedSidebarButton');
},
},
+ safeHtmlConfig: { ADD_TAGS: ['gl-emoji'] },
};
</script>
@@ -105,7 +114,7 @@ export default {
<section class="header-main-content gl-mr-3">
<ci-icon-badge :status="status" />
- <strong data-testid="ci-header-item-text"> {{ itemName }} #{{ itemId }} </strong>
+ <strong data-testid="ci-header-item-text">{{ item }}</strong>
<template v-if="shouldRenderTriggeredLabel">{{ __('triggered') }}</template>
<template v-else>{{ __('created') }}</template>
@@ -130,8 +139,8 @@ export default {
<span
v-if="statusTooltipHTML"
:ref="$options.EMOJI_REF"
+ v-safe-html:[$options.safeHtmlConfig]="statusTooltipHTML"
:data-testid="message"
- v-html="statusTooltipHTML"
></span>
</template>
</section>
diff --git a/app/assets/javascripts/vue_shared/components/issuable/init_issuable_header_warning.js b/app/assets/javascripts/vue_shared/components/issuable/init_issuable_header_warning.js
index 18bfcc268dc..28aa93d6680 100644
--- a/app/assets/javascripts/vue_shared/components/issuable/init_issuable_header_warning.js
+++ b/app/assets/javascripts/vue_shared/components/issuable/init_issuable_header_warning.js
@@ -1,10 +1,20 @@
import Vue from 'vue';
+import { parseBoolean } from '~/lib/utils/common_utils';
import IssuableHeaderWarnings from './issuable_header_warnings.vue';
export default function issuableHeaderWarnings(store) {
+ const el = document.getElementById('js-issuable-header-warnings');
+
+ if (!el) {
+ return false;
+ }
+
+ const { hidden } = el.dataset;
+
return new Vue({
- el: document.getElementById('js-issuable-header-warnings'),
+ el,
store,
+ provide: { hidden: parseBoolean(hidden) },
render(createElement) {
return createElement(IssuableHeaderWarnings);
},
diff --git a/app/assets/javascripts/vue_shared/components/issuable/issuable_header_warnings.vue b/app/assets/javascripts/vue_shared/components/issuable/issuable_header_warnings.vue
index 56adbe8c606..82223ab9ef4 100644
--- a/app/assets/javascripts/vue_shared/components/issuable/issuable_header_warnings.vue
+++ b/app/assets/javascripts/vue_shared/components/issuable/issuable_header_warnings.vue
@@ -1,11 +1,16 @@
<script>
-import { GlIcon } from '@gitlab/ui';
+import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
import { mapGetters } from 'vuex';
+import { __ } from '~/locale';
export default {
components: {
GlIcon,
},
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
+ inject: ['hidden'],
computed: {
...mapGetters(['getNoteableData']),
isLocked() {
@@ -26,6 +31,12 @@ export default {
visible: this.isConfidential,
dataTestId: 'confidential',
},
+ {
+ iconName: 'spam',
+ visible: this.hidden,
+ dataTestId: 'hidden',
+ tooltip: __('This issue is hidden because its author has been banned'),
+ },
];
},
},
@@ -35,8 +46,15 @@ export default {
<template>
<div class="gl-display-inline-block">
<template v-for="meta in warningIconsMeta">
- <div v-if="meta.visible" :key="meta.iconName" class="issuable-warning-icon inline">
- <gl-icon :name="meta.iconName" :data-testid="meta.dataTestId" class="icon" />
+ <div
+ v-if="meta.visible"
+ :key="meta.iconName"
+ v-gl-tooltip
+ :data-testid="meta.dataTestId"
+ :title="meta.tooltip || null"
+ class="issuable-warning-icon inline"
+ >
+ <gl-icon :name="meta.iconName" class="icon" />
</div>
</template>
</div>
diff --git a/app/assets/javascripts/vue_shared/components/issue/related_issuable_item.vue b/app/assets/javascripts/vue_shared/components/issue/related_issuable_item.vue
index ccdb47e3144..095d1854c8b 100644
--- a/app/assets/javascripts/vue_shared/components/issue/related_issuable_item.vue
+++ b/app/assets/javascripts/vue_shared/components/issue/related_issuable_item.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import '~/commons/bootstrap';
import { GlIcon, GlTooltip, GlTooltipDirective, GlButton } from '@gitlab/ui';
import IssueDueDate from '~/boards/components/issue_due_date.vue';
@@ -72,7 +71,7 @@ export default {
class="item-contents gl-display-flex gl-align-items-center gl-flex-wrap gl-flex-grow-1 flex-xl-nowrap gl-min-h-7"
>
<!-- Title area: Status icon (XL) and title -->
- <div class="item-title d-flex align-items-xl-center mb-xl-0">
+ <div class="item-title d-flex align-items-xl-center mb-xl-0 gl-min-w-0">
<div ref="iconElementXL">
<gl-icon
v-if="hasState"
@@ -85,7 +84,7 @@ export default {
/>
</div>
<gl-tooltip :target="() => $refs.iconElementXL">
- <span v-html="stateTitle"></span>
+ <span v-html="stateTitle /* eslint-disable-line vue/no-v-html */"></span>
</gl-tooltip>
<gl-icon
v-if="confidential"
@@ -111,7 +110,7 @@ export default {
class="item-path-area item-path-id d-flex align-items-center mr-2 mt-2 mt-xl-0 ml-xl-2"
>
<gl-tooltip :target="() => this.$refs.iconElement">
- <span v-html="stateTitle"></span>
+ <span v-html="stateTitle /* eslint-disable-line vue/no-v-html */"></span>
</gl-tooltip>
<span v-gl-tooltip :title="itemPath" class="path-id-text d-inline-block">{{
itemPath
diff --git a/app/assets/javascripts/vue_shared/components/markdown/field.vue b/app/assets/javascripts/vue_shared/components/markdown/field.vue
index 9ea48050079..77730ada9bb 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/field.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/field.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { GlIcon } from '@gitlab/ui';
import $ from 'jquery';
import '~/behaviors/markdown/render_gfm';
@@ -15,6 +14,10 @@ import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import MarkdownHeader from './header.vue';
import MarkdownToolbar from './toolbar.vue';
+function cleanUpLine(content) {
+ return unescape(stripHtml(content).replace(/\\n/g, '%br').replace(/\n/g, ''));
+}
+
export default {
components: {
GfmAutocomplete,
@@ -129,7 +132,7 @@ export default {
return text;
}
- return unescape(stripHtml(richText).replace(/\n/g, ''));
+ return cleanUpLine(richText);
})
.join('\\n');
}
@@ -141,7 +144,7 @@ export default {
return text;
}
- return unescape(stripHtml(richText).replace(/\n/g, ''));
+ return cleanUpLine(richText);
}
return '';
@@ -272,6 +275,7 @@ export default {
:can-suggest="canSuggest"
:show-suggest-popover="showSuggestPopover"
:suggestion-start-index="suggestionsStartIndex"
+ data-testid="markdownHeader"
@preview-markdown="showPreviewTab"
@write-markdown="showWriteTab"
@handleSuggestDismissed="() => $emit('handleSuggestDismissed')"
@@ -319,14 +323,20 @@ export default {
v-show="previewMarkdown"
ref="markdown-preview"
class="js-vue-md-preview md md-preview-holder"
- v-html="markdownPreview"
+ v-html="markdownPreview /* eslint-disable-line vue/no-v-html */"
></div>
</template>
<template v-if="previewMarkdown && !markdownPreviewLoading">
- <div v-if="referencedCommands" class="referenced-commands" v-html="referencedCommands"></div>
+ <div
+ v-if="referencedCommands"
+ class="referenced-commands"
+ v-html="referencedCommands /* eslint-disable-line vue/no-v-html */"
+ ></div>
<div v-if="shouldShowReferencedUsers" class="referenced-users">
<gl-icon name="warning-solid" />
- <span v-html="addMultipleToDiscussionWarning"></span>
+ <span
+ v-html="addMultipleToDiscussionWarning /* eslint-disable-line vue/no-v-html */"
+ ></span>
</div>
</template>
</div>
diff --git a/app/assets/javascripts/vue_shared/components/markdown/suggestion_diff_header.vue b/app/assets/javascripts/vue_shared/components/markdown/suggestion_diff_header.vue
index 065d9b1b5dd..5fdef0b1a23 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/suggestion_diff_header.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/suggestion_diff_header.vue
@@ -39,7 +39,8 @@ export default {
},
defaultCommitMessage: {
type: String,
- required: true,
+ required: false,
+ default: null,
},
inapplicableReason: {
type: String,
diff --git a/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue b/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
index 7112295fa57..912aa8ce294 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
@@ -75,7 +75,7 @@ export default {
variant="link"
:track-experiment="$options.inviteMembersInComment"
:trigger-source="$options.inviteMembersInComment"
- data-track-event="comment_invite_click"
+ data-track-action="comment_invite_click"
/>
<span class="uploading-progress-container hide">
<gl-icon name="media" />
diff --git a/app/assets/javascripts/vue_shared/components/notes/noteable_warning.vue b/app/assets/javascripts/vue_shared/components/notes/noteable_warning.vue
index ad6f6e0e2e3..0b302f22062 100644
--- a/app/assets/javascripts/vue_shared/components/notes/noteable_warning.vue
+++ b/app/assets/javascripts/vue_shared/components/notes/noteable_warning.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { GlLink, GlIcon } from '@gitlab/ui';
import { escape } from 'lodash';
import { __, sprintf } from '~/locale';
@@ -92,7 +91,9 @@ export default {
<gl-icon v-if="!isLockedAndConfidential" :name="warningIcon" :size="16" class="icon inline" />
<span v-if="isLockedAndConfidential" ref="lockedAndConfidential">
- <span v-html="confidentialAndLockedDiscussionText"></span>
+ <span
+ v-html="confidentialAndLockedDiscussionText /* eslint-disable-line vue/no-v-html */"
+ ></span>
{{
__("People without permission will never get a notification and won't be able to comment.")
}}
diff --git a/app/assets/javascripts/vue_shared/components/notes/system_note.vue b/app/assets/javascripts/vue_shared/components/notes/system_note.vue
index c3d861d74bc..755e6f1f224 100644
--- a/app/assets/javascripts/vue_shared/components/notes/system_note.vue
+++ b/app/assets/javascripts/vue_shared/components/notes/system_note.vue
@@ -1,6 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
-
/**
* Common component to render a system note, icon and user information.
*
@@ -97,6 +95,9 @@ export default {
methods: {
...mapActions(['fetchDescriptionVersion', 'softDeleteDescriptionVersion']),
},
+ safeHtmlConfig: {
+ ADD_TAGS: ['use'], // to support icon SVGs
+ },
};
</script>
@@ -106,7 +107,7 @@ export default {
:class="{ target: isTargetNote, 'pr-0': shouldShowDescriptionVersion }"
class="note system-note note-wrapper"
>
- <div class="timeline-icon" v-html="iconHtml"></div>
+ <div v-safe-html:[$options.safeHtmlConfig]="iconHtml" class="timeline-icon"></div>
<div class="timeline-content">
<div class="note-header">
<note-header :author="note.author" :created-at="note.created_at" :note-id="note.id">
diff --git a/app/assets/javascripts/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs.vue b/app/assets/javascripts/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs.vue
index 8a67754993d..6867b5a75e3 100644
--- a/app/assets/javascripts/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs.vue
+++ b/app/assets/javascripts/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs.vue
@@ -1,5 +1,12 @@
<script>
-import { GlAlert, GlBadge, GlPagination, GlTab, GlTabs } from '@gitlab/ui';
+import {
+ GlAlert,
+ GlBadge,
+ GlPagination,
+ GlTab,
+ GlTabs,
+ GlSafeHtmlDirective as SafeHtml,
+} from '@gitlab/ui';
import Api from '~/api';
import { updateHistory, setUrlParams } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
@@ -20,6 +27,9 @@ export default {
GlTab,
FilteredSearchBar,
},
+ directives: {
+ SafeHtml,
+ },
inject: {
projectPath: {
default: '',
@@ -265,8 +275,7 @@ export default {
<template>
<div class="incident-management-list">
<gl-alert v-if="showErrorMsg" variant="danger" @dismiss="$emit('error-alert-dismissed')">
- <!-- eslint-disable-next-line vue/no-v-html -->
- <p v-html="serverErrorMessage || i18n.errorMsg"></p>
+ <p v-safe-html="serverErrorMessage || i18n.errorMsg"></p>
</gl-alert>
<div
diff --git a/app/assets/javascripts/vue_shared/components/project_selector/project_list_item.vue b/app/assets/javascripts/vue_shared/components/project_selector/project_list_item.vue
index 69f43c9e464..36d3696ec36 100644
--- a/app/assets/javascripts/vue_shared/components/project_selector/project_list_item.vue
+++ b/app/assets/javascripts/vue_shared/components/project_selector/project_list_item.vue
@@ -1,5 +1,4 @@
<script>
-/* eslint-disable vue/no-v-html */
import { GlButton, GlIcon } from '@gitlab/ui';
import { isString } from 'lodash';
import highlight from '~/lib/utils/highlight';
@@ -61,7 +60,7 @@ export default {
<div
:title="project.name"
class="js-project-name text-truncate"
- v-html="highlightedProjectName"
+ v-html="highlightedProjectName /* eslint-disable-line vue/no-v-html */"
></div>
</div>
</gl-button>
diff --git a/app/assets/javascripts/vue_shared/components/registry/title_area.vue b/app/assets/javascripts/vue_shared/components/registry/title_area.vue
index c63d91b78d3..4b21ec0330a 100644
--- a/app/assets/javascripts/vue_shared/components/registry/title_area.vue
+++ b/app/assets/javascripts/vue_shared/components/registry/title_area.vue
@@ -1,5 +1,6 @@
<script>
import { GlAvatar, GlSprintf, GlLink, GlSkeletonLoader } from '@gitlab/ui';
+import { isEqual } from 'lodash';
export default {
name: 'TitleArea',
@@ -36,13 +37,21 @@ export default {
metadataSlots: [],
};
},
- async mounted() {
- const METADATA_PREFIX = 'metadata-';
- this.metadataSlots = Object.keys(this.$slots).filter((k) => k.startsWith(METADATA_PREFIX));
+ mounted() {
+ this.recalculateMetadataSlots();
+ },
+ updated() {
+ this.recalculateMetadataSlots();
+ },
+ methods: {
+ recalculateMetadataSlots() {
+ const METADATA_PREFIX = 'metadata-';
+ const metadataSlots = Object.keys(this.$slots).filter((k) => k.startsWith(METADATA_PREFIX));
- // we need to wait for next tick to ensure that dynamic names slots are picked up
- await this.$nextTick();
- this.metadataSlots = Object.keys(this.$slots).filter((k) => k.startsWith(METADATA_PREFIX));
+ if (!isEqual(metadataSlots, this.metadataSlots)) {
+ this.metadataSlots = metadataSlots;
+ }
+ },
},
};
</script>
diff --git a/app/assets/javascripts/vue_shared/components/runner_aws_deployments/runner_aws_deployments_modal.vue b/app/assets/javascripts/vue_shared/components/runner_aws_deployments/runner_aws_deployments_modal.vue
index f21dea468cb..57cc25caa25 100644
--- a/app/assets/javascripts/vue_shared/components/runner_aws_deployments/runner_aws_deployments_modal.vue
+++ b/app/assets/javascripts/vue_shared/components/runner_aws_deployments/runner_aws_deployments_modal.vue
@@ -1,5 +1,6 @@
<script>
import { GlModal, GlSprintf, GlLink } from '@gitlab/ui';
+import awsCloudFormationImageUrl from 'images/aws-cloud-formation.png';
import ExperimentTracking from '~/experimentation/experiment_tracking';
import { getBaseURL, objectToQuery } from '~/lib/utils/url_utility';
import { __, s__ } from '~/locale';
@@ -22,6 +23,11 @@ export default {
type: String,
required: true,
},
+ imgSrc: {
+ type: String,
+ required: false,
+ default: awsCloudFormationImageUrl,
+ },
},
methods: {
easyButtonUrl(easyButton) {
@@ -76,7 +82,7 @@ export default {
<img
:title="easyButton.stackName"
:alt="easyButton.stackName"
- src="/assets/aws-cloud-formation.png"
+ :src="imgSrc"
width="46"
height="46"
class="gl-mt-2 gl-mr-5 gl-mb-6"
diff --git a/app/assets/javascripts/vue_shared/components/settings/settings_block.stories.js b/app/assets/javascripts/vue_shared/components/settings/settings_block.stories.js
new file mode 100644
index 00000000000..5242743ad30
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/settings/settings_block.stories.js
@@ -0,0 +1,26 @@
+import SettingsBlock from './settings_block.vue';
+
+export default {
+ component: SettingsBlock,
+ title: 'vue_shared/components/settings/settings_block',
+};
+
+const Template = (args, { argTypes }) => ({
+ components: { SettingsBlock },
+ props: Object.keys(argTypes),
+ template: `
+ <settings-block v-bind="$props">
+ <template #title>Settings section title</template>
+ <template #description>Settings section description</template>
+ <template #default>
+ <p>Content</p>
+ <p>More content</p>
+ <p>Content</p>
+ <p>More content...</p>
+ <p>Content</p>
+ </template>
+ </settings-block>
+ `,
+});
+
+export const Default = Template.bind({});
diff --git a/app/assets/javascripts/vue_shared/components/settings/settings_block.vue b/app/assets/javascripts/vue_shared/components/settings/settings_block.vue
index 92ae4575c52..e75fedbb1d7 100644
--- a/app/assets/javascripts/vue_shared/components/settings/settings_block.vue
+++ b/app/assets/javascripts/vue_shared/components/settings/settings_block.vue
@@ -1,5 +1,7 @@
<script>
import { GlButton } from '@gitlab/ui';
+import { uniqueId } from 'lodash';
+
import { __ } from '~/locale';
export default {
@@ -15,35 +17,99 @@ export default {
default: false,
required: false,
},
+ collapsible: {
+ type: Boolean,
+ default: true,
+ required: false,
+ },
},
data() {
return {
- sectionExpanded: false,
+ // Non-collapsible sections should always be expanded.
+ // For collapsible sections, fall back to defaultExpanded.
+ sectionExpanded: !this.collapsible || this.defaultExpanded,
};
},
computed: {
- expanded() {
- return this.defaultExpanded || this.sectionExpanded;
- },
toggleText() {
- return this.expanded ? __('Collapse') : __('Expand');
+ const { collapseText, expandText } = this.$options.i18n;
+ return this.sectionExpanded ? collapseText : expandText;
+ },
+ settingsContentId() {
+ return uniqueId('settings_content_');
},
+ settingsLabelId() {
+ return uniqueId('settings_label_');
+ },
+ toggleButtonAriaLabel() {
+ const { collapseAriaLabel, expandAriaLabel } = this.$options.i18n;
+ return this.sectionExpanded ? collapseAriaLabel : expandAriaLabel;
+ },
+ ariaExpanded() {
+ return String(this.sectionExpanded);
+ },
+ },
+ methods: {
+ toggleSectionExpanded() {
+ this.sectionExpanded = !this.sectionExpanded;
+
+ if (this.sectionExpanded) {
+ this.$refs.settingsContent.focus();
+ }
+ },
+ },
+ i18n: {
+ collapseText: __('Collapse'),
+ expandText: __('Expand'),
+ collapseAriaLabel: __('Collapse settings section'),
+ expandAriaLabel: __('Expand settings section'),
},
};
</script>
<template>
- <section class="settings" :class="{ 'no-animate': !slideAnimated, expanded }">
+ <section class="settings" :class="{ 'no-animate': !slideAnimated, expanded: sectionExpanded }">
<div class="settings-header">
- <h4><slot name="title"></slot></h4>
- <gl-button @click="sectionExpanded = !sectionExpanded">
+ <h4>
+ <span
+ v-if="collapsible"
+ :id="settingsLabelId"
+ role="button"
+ tabindex="0"
+ class="gl-cursor-pointer"
+ :aria-controls="settingsContentId"
+ :aria-expanded="ariaExpanded"
+ data-testid="section-title-button"
+ @click="toggleSectionExpanded"
+ @keydown.enter.space="toggleSectionExpanded"
+ >
+ <slot name="title"></slot>
+ </span>
+ <template v-else>
+ <slot name="title"></slot>
+ </template>
+ </h4>
+ <gl-button
+ v-if="collapsible"
+ :aria-controls="settingsContentId"
+ :aria-expanded="ariaExpanded"
+ :aria-label="toggleButtonAriaLabel"
+ @click="toggleSectionExpanded"
+ >
{{ toggleText }}
</gl-button>
<p>
<slot name="description"></slot>
</p>
</div>
- <div class="settings-content">
+ <div
+ :id="settingsContentId"
+ ref="settingsContent"
+ :aria-labelledby="settingsLabelId"
+ tabindex="-1"
+ role="region"
+ class="settings-content"
+ >
<slot></slot>
</div>
</section>
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_value.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_value.vue
index 46ccb9470e5..35ac9ef8565 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_value.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_value.vue
@@ -1,5 +1,6 @@
<script>
import { GlLabel } from '@gitlab/ui';
+import { sortBy } from 'lodash';
import { mapState } from 'vuex';
import { isScopedLabel } from '~/lib/utils/common_utils';
@@ -23,6 +24,9 @@ export default {
'labelsFilterBasePath',
'labelsFilterParam',
]),
+ sortedSelectedLabels() {
+ return sortBy(this.selectedLabels, (label) => (isScopedLabel(label) ? 0 : 1));
+ },
},
methods: {
labelFilterUrl(label) {
@@ -47,7 +51,7 @@ export default {
<span v-if="!selectedLabels.length" class="text-secondary">
<slot></slot>
</span>
- <template v-for="label in selectedLabels" v-else>
+ <template v-for="label in sortedSelectedLabels" v-else>
<gl-label
:key="label.id"
data-qa-selector="selected_label_content"
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/label_item.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/label_item.vue
index e8fdf4bb0c2..dd40add6376 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/label_item.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/label_item.vue
@@ -56,7 +56,7 @@ export default {
const labelLink = h(
GlLink,
{
- class: 'gl-display-flex gl-align-items-center label-item gl-text-black-normal',
+ class: 'gl-display-flex gl-align-items-center label-item gl-text-body',
on: {
click: () => {
listeners.clickLabel(label);
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_button.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_button.vue
deleted file mode 100644
index 60111210f5d..00000000000
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_button.vue
+++ /dev/null
@@ -1,42 +0,0 @@
-<script>
-import { GlButton, GlIcon } from '@gitlab/ui';
-import { mapActions, mapGetters } from 'vuex';
-
-export default {
- components: {
- GlButton,
- GlIcon,
- },
- computed: {
- ...mapGetters([
- 'dropdownButtonText',
- 'isDropdownVariantStandalone',
- 'isDropdownVariantEmbedded',
- ]),
- },
- methods: {
- ...mapActions(['toggleDropdownContents']),
- handleButtonClick(e) {
- if (this.isDropdownVariantStandalone || this.isDropdownVariantEmbedded) {
- this.toggleDropdownContents();
- }
-
- if (this.isDropdownVariantStandalone) {
- e.stopPropagation();
- }
- },
- },
-};
-</script>
-
-<template>
- <gl-button
- class="labels-select-dropdown-button js-dropdown-button w-100 text-left"
- @click="handleButtonClick"
- >
- <span class="dropdown-toggle-text gl-pointer-events-none flex-fill">
- {{ dropdownButtonText }}
- </span>
- <gl-icon name="chevron-down" class="gl-pointer-events-none float-right" />
- </gl-button>
-</template>
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue
index 6694e349b6e..0fcc67c0ffa 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue
@@ -1,22 +1,21 @@
<script>
-import { GlButton } from '@gitlab/ui';
-import { mapActions, mapGetters, mapState } from 'vuex';
+import { GlButton, GlDropdown, GlDropdownItem, GlLink } from '@gitlab/ui';
import DropdownContentsCreateView from './dropdown_contents_create_view.vue';
import DropdownContentsLabelsView from './dropdown_contents_labels_view.vue';
+import { isDropdownVariantSidebar, isDropdownVariantEmbedded } from './utils';
export default {
components: {
DropdownContentsLabelsView,
DropdownContentsCreateView,
GlButton,
+ GlDropdown,
+ GlDropdownItem,
+ GlLink,
},
+ inject: ['allowLabelCreate', 'labelsManagePath'],
props: {
- renderOnTop: {
- type: Boolean,
- required: false,
- default: false,
- },
labelsCreateTitle: {
type: String,
required: true,
@@ -33,6 +32,10 @@ export default {
type: String,
required: true,
},
+ dropdownButtonText: {
+ type: String,
+ required: true,
+ },
footerCreateLabelTitle: {
type: String,
required: true,
@@ -41,70 +44,105 @@ export default {
type: String,
required: true,
},
+ variant: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ showDropdownContentsCreateView: false,
+ };
},
computed: {
- ...mapState(['showDropdownContentsCreateView']),
- ...mapGetters(['isDropdownVariantSidebar', 'isDropdownVariantEmbedded']),
dropdownContentsView() {
if (this.showDropdownContentsCreateView) {
return 'dropdown-contents-create-view';
}
return 'dropdown-contents-labels-view';
},
- directionStyle() {
- const bottom = this.isDropdownVariantSidebar ? '3rem' : '2rem';
- return this.renderOnTop ? { bottom } : {};
- },
dropdownTitle() {
return this.showDropdownContentsCreateView ? this.labelsCreateTitle : this.labelsListTitle;
},
+ showDropdownFooter() {
+ return (
+ !this.showDropdownContentsCreateView &&
+ (this.isDropdownVariantSidebar(this.variant) ||
+ this.isDropdownVariantEmbedded(this.variant))
+ );
+ },
},
methods: {
- ...mapActions(['toggleDropdownContentsCreateView', 'toggleDropdownContents']),
+ showDropdown() {
+ this.$refs.dropdown.show();
+ },
+ toggleDropdownContentsCreateView() {
+ this.showDropdownContentsCreateView = !this.showDropdownContentsCreateView;
+ },
+ toggleDropdownContent() {
+ this.toggleDropdownContentsCreateView();
+ // Required to recalculate dropdown position as its size changes
+ this.$refs.dropdown.$refs.dropdown.$_popper.scheduleUpdate();
+ },
+ isDropdownVariantSidebar,
+ isDropdownVariantEmbedded,
},
};
</script>
<template>
- <div
- class="labels-select-dropdown-contents gl-w-full gl-my-2 gl-py-3 gl-rounded-base gl-absolute"
+ <gl-dropdown
+ ref="dropdown"
+ :text="dropdownButtonText"
+ class="gl-w-full gl-mt-2"
data-qa-selector="labels_dropdown_content"
- :style="directionStyle"
>
- <div
- v-if="isDropdownVariantSidebar || isDropdownVariantEmbedded"
- class="dropdown-title gl-display-flex gl-align-items-center gl-pt-0 gl-pb-3!"
- data-testid="dropdown-title"
- >
- <gl-button
- v-if="showDropdownContentsCreateView"
- :aria-label="__('Go back')"
- variant="link"
- size="small"
- class="js-btn-back dropdown-header-button p-0"
- icon="arrow-left"
- @click="toggleDropdownContentsCreateView"
- />
- <span class="flex-grow-1">{{ dropdownTitle }}</span>
- <gl-button
- :aria-label="__('Close')"
- variant="link"
- size="small"
- class="dropdown-header-button gl-p-0!"
- icon="close"
- @click="toggleDropdownContents"
- />
- </div>
+ <template #header>
+ <div
+ v-if="isDropdownVariantSidebar(variant) || isDropdownVariantEmbedded(variant)"
+ class="dropdown-title gl-display-flex gl-align-items-center gl-pt-0 gl-pb-3!"
+ >
+ <gl-button
+ v-if="showDropdownContentsCreateView"
+ :aria-label="__('Go back')"
+ variant="link"
+ size="small"
+ class="js-btn-back dropdown-header-button gl-p-0"
+ icon="arrow-left"
+ data-testid="go-back-button"
+ @click.stop="toggleDropdownContent"
+ />
+ <span class="gl-flex-grow-1">{{ dropdownTitle }}</span>
+ <gl-button
+ :aria-label="__('Close')"
+ variant="link"
+ size="small"
+ class="dropdown-header-button gl-p-0!"
+ icon="close"
+ @click="$emit('closeDropdown')"
+ />
+ </div>
+ </template>
<component
:is="dropdownContentsView"
:selected-labels="selectedLabels"
:allow-multiselect="allowMultiselect"
- :labels-list-title="labelsListTitle"
- :footer-create-label-title="footerCreateLabelTitle"
- :footer-manage-label-title="footerManageLabelTitle"
@hideCreateView="toggleDropdownContentsCreateView"
- @closeDropdown="$emit('closeDropdown', $event)"
- @toggleDropdownContentsCreateView="toggleDropdownContentsCreateView"
+ @setLabels="$emit('setLabels', $event)"
/>
- </div>
+ <template #footer>
+ <div v-if="showDropdownFooter" data-testid="dropdown-footer">
+ <gl-dropdown-item
+ v-if="allowLabelCreate"
+ data-testid="create-label-button"
+ @click.native.capture.stop="toggleDropdownContent"
+ >
+ {{ footerCreateLabelTitle }}
+ </gl-dropdown-item>
+ <gl-dropdown-item :href="labelsManagePath" @click.native.capture.stop>
+ {{ footerManageLabelTitle }}
+ </gl-dropdown-item>
+ </div>
+ </template>
+ </gl-dropdown>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue
index 4651e7a1576..2e31b386fdd 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue
@@ -1,8 +1,10 @@
<script>
import { GlTooltipDirective, GlButton, GlFormInput, GlLink, GlLoadingIcon } from '@gitlab/ui';
+import produce from 'immer';
import createFlash from '~/flash';
import { __ } from '~/locale';
import createLabelMutation from './graphql/create_label.mutation.graphql';
+import projectLabelsQuery from './graphql/project_labels.query.graphql';
const errorMessage = __('Error creating label.');
@@ -47,6 +49,25 @@ export default {
handleColorClick(color) {
this.selectedColor = this.getColorCode(color);
},
+ updateLabelsInCache(store, label) {
+ const sourceData = store.readQuery({
+ query: projectLabelsQuery,
+ variables: { fullPath: this.projectPath, searchTerm: '' },
+ });
+
+ const collator = new Intl.Collator('en');
+ const data = produce(sourceData, (draftData) => {
+ const { nodes } = draftData.workspace.labels;
+ nodes.push(label);
+ nodes.sort((a, b) => collator.compare(a.title, b.title));
+ });
+
+ store.writeQuery({
+ query: projectLabelsQuery,
+ variables: { fullPath: this.projectPath, searchTerm: '' },
+ data,
+ });
+ },
async createLabel() {
this.labelCreateInProgress = true;
try {
@@ -59,6 +80,14 @@ export default {
color: this.selectedColor,
projectPath: this.projectPath,
},
+ update: (
+ store,
+ {
+ data: {
+ labelCreate: { label },
+ },
+ },
+ ) => this.updateLabelsInCache(store, label),
});
if (labelCreate.errors.length) {
createFlash({ message: errorMessage });
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue
index ffa37424c2c..857367a0721 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue
@@ -1,24 +1,23 @@
<script>
-import { GlLoadingIcon, GlSearchBoxByType, GlLink } from '@gitlab/ui';
+import { GlDropdownForm, GlDropdownItem, GlLoadingIcon, GlSearchBoxByType } from '@gitlab/ui';
import fuzzaldrinPlus from 'fuzzaldrin-plus';
import { debounce } from 'lodash';
import createFlash from '~/flash';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
-import { UP_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESC_KEY_CODE } from '~/lib/utils/keycodes';
import { __ } from '~/locale';
-import { DropdownVariant } from './constants';
import projectLabelsQuery from './graphql/project_labels.query.graphql';
import LabelItem from './label_item.vue';
export default {
components: {
+ GlDropdownForm,
+ GlDropdownItem,
GlLoadingIcon,
GlSearchBoxByType,
- GlLink,
LabelItem,
},
- inject: ['projectPath', 'allowLabelCreate', 'labelsManagePath', 'variant'],
+ inject: ['projectPath'],
props: {
selectedLabels: {
type: Array,
@@ -28,24 +27,11 @@ export default {
type: Boolean,
required: true,
},
- labelsListTitle: {
- type: String,
- required: true,
- },
- footerCreateLabelTitle: {
- type: String,
- required: true,
- },
- footerManageLabelTitle: {
- type: String,
- required: true,
- },
},
data() {
return {
searchKey: '',
labels: [],
- currentHighlightItem: -1,
localSelectedLabels: [...this.selectedLabels],
};
},
@@ -74,12 +60,6 @@ export default {
},
},
computed: {
- isDropdownVariantSidebar() {
- return this.variant === DropdownVariant.Sidebar;
- },
- isDropdownVariantEmbedded() {
- return this.variant === DropdownVariant.Embedded;
- },
labelsFetchInProgress() {
return this.$apollo.queries.labels.loading;
},
@@ -98,21 +78,11 @@ export default {
return Boolean(this.searchKey) && this.visibleLabels.length === 0;
},
},
- watch: {
- searchKey(value) {
- // When there is search string present
- // and there are matching results,
- // highlight first item by default.
- if (value && this.visibleLabels.length) {
- this.currentHighlightItem = 0;
- }
- },
- },
created() {
this.debouncedSearchKeyUpdate = debounce(this.setSearchKey, DEFAULT_DEBOUNCE_AND_THROTTLE_MS);
},
beforeDestroy() {
- this.$emit('closeDropdown', this.localSelectedLabels);
+ this.$emit('setLabels', this.localSelectedLabels);
this.debouncedSearchKeyUpdate.cancel();
},
methods: {
@@ -150,33 +120,6 @@ export default {
});
}
},
- /**
- * This method enables keyboard navigation support for
- * the dropdown.
- */
- handleKeyDown(e) {
- if (e.keyCode === UP_KEY_CODE && this.currentHighlightItem > 0) {
- this.currentHighlightItem -= 1;
- } else if (
- e.keyCode === DOWN_KEY_CODE &&
- this.currentHighlightItem < this.visibleLabels.length - 1
- ) {
- this.currentHighlightItem += 1;
- } else if (e.keyCode === ENTER_KEY_CODE && this.currentHighlightItem > -1) {
- this.updateSelectedLabels(this.visibleLabels[this.currentHighlightItem]);
- this.searchKey = '';
- } else if (e.keyCode === ESC_KEY_CODE) {
- this.$emit('closeDropdown', this.localSelectedLabels);
- }
-
- if (e.keyCode !== ESC_KEY_CODE) {
- // Scroll the list only after highlighting
- // styles are rendered completely.
- this.$nextTick(() => {
- this.scrollIntoViewIfNeeded();
- });
- }
- },
handleLabelClick(label) {
this.updateSelectedLabels(label);
if (!this.allowMultiselect) {
@@ -191,69 +134,41 @@ export default {
</script>
<template>
- <div
- class="labels-select-contents-list js-labels-list"
- data-testid="dropdown-wrapper"
- @keydown="handleKeyDown"
- >
- <div class="dropdown-input" @click.stop="() => {}">
- <gl-search-box-by-type
- ref="searchInput"
- :value="searchKey"
- :disabled="labelsFetchInProgress"
- data-qa-selector="dropdown_input_field"
- data-testid="dropdown-input-field"
- @input="debouncedSearchKeyUpdate"
- />
- </div>
- <div ref="labelsListContainer" class="dropdown-content" data-testid="dropdown-content">
+ <gl-dropdown-form class="labels-select-contents-list js-labels-list">
+ <gl-search-box-by-type
+ ref="searchInput"
+ :value="searchKey"
+ :disabled="labelsFetchInProgress"
+ data-qa-selector="dropdown_input_field"
+ data-testid="dropdown-input-field"
+ @input="debouncedSearchKeyUpdate"
+ />
+ <div ref="labelsListContainer" data-testid="dropdown-content">
<gl-loading-icon
v-if="labelsFetchInProgress"
class="labels-fetch-loading gl-align-items-center gl-w-full gl-h-full"
size="md"
/>
- <ul v-else class="list-unstyled gl-mb-0 gl-word-break-word" data-testid="labels-list">
- <label-item
- v-for="(label, index) in visibleLabels"
+ <template v-else>
+ <gl-dropdown-item
+ v-for="label in visibleLabels"
:key="label.id"
- :label="label"
- :is-label-set="isLabelSelected(label)"
- :highlight="index === currentHighlightItem"
- @clickLabel="handleLabelClick(label)"
- />
- <li
+ :is-checked="isLabelSelected(label)"
+ :is-check-centered="true"
+ :is-check-item="true"
+ data-testid="labels-list"
+ @click.native.capture.stop="handleLabelClick(label)"
+ >
+ <label-item :label="label" />
+ </gl-dropdown-item>
+ <gl-dropdown-item
v-show="showNoMatchingResultsMessage"
class="gl-p-3 gl-text-center"
data-testid="no-results"
>
{{ __('No matching results') }}
- </li>
- </ul>
- </div>
- <div
- v-if="isDropdownVariantSidebar || isDropdownVariantEmbedded"
- class="dropdown-footer"
- data-testid="dropdown-footer"
- >
- <ul class="list-unstyled">
- <li v-if="allowLabelCreate">
- <gl-link
- class="gl-display-flex gl-flex-direction-row gl-w-full gl-overflow-break-word label-item"
- data-testid="create-label-button"
- @click="$emit('toggleDropdownContentsCreateView')"
- >
- {{ footerCreateLabelTitle }}
- </gl-link>
- </li>
- <li>
- <gl-link
- :href="labelsManagePath"
- class="gl-display-flex gl-flex-direction-row gl-w-full gl-overflow-break-word label-item"
- >
- {{ footerManageLabelTitle }}
- </gl-link>
- </li>
- </ul>
+ </gl-dropdown-item>
+ </template>
</div>
- </div>
+ </gl-dropdown-form>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_title.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_title.vue
deleted file mode 100644
index 46edfa1c42a..00000000000
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_title.vue
+++ /dev/null
@@ -1,40 +0,0 @@
-<script>
-import { GlButton, GlLoadingIcon } from '@gitlab/ui';
-import { mapState, mapActions } from 'vuex';
-
-export default {
- components: {
- GlButton,
- GlLoadingIcon,
- },
- props: {
- labelsSelectInProgress: {
- type: Boolean,
- required: true,
- },
- },
- computed: {
- ...mapState(['allowLabelEdit', 'labelsFetchInProgress']),
- },
- methods: {
- ...mapActions(['toggleDropdownContents']),
- },
-};
-</script>
-
-<template>
- <div class="title hide-collapsed gl-mb-3">
- {{ __('Labels') }}
- <template v-if="allowLabelEdit">
- <gl-loading-icon v-show="labelsSelectInProgress" size="sm" inline />
- <gl-button
- category="tertiary"
- size="small"
- class="float-right js-sidebar-dropdown-toggle gl-mr-n2"
- data-qa-selector="labels_edit_button"
- @click="toggleDropdownContents"
- >{{ __('Edit') }}</gl-button
- >
- </template>
- </div>
-</template>
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_value.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_value.vue
index 58a940bca3b..71d3d87cce5 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_value.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_value.vue
@@ -1,5 +1,6 @@
<script>
import { GlLabel } from '@gitlab/ui';
+import { sortBy } from 'lodash';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { isScopedLabel } from '~/lib/utils/common_utils';
@@ -7,6 +8,7 @@ export default {
components: {
GlLabel,
},
+ inject: ['allowScopedLabels'],
props: {
disableLabels: {
type: Boolean,
@@ -21,10 +23,6 @@ export default {
type: Boolean,
required: true,
},
- allowScopedLabels: {
- type: Boolean,
- required: true,
- },
labelsFilterBasePath: {
type: String,
required: true,
@@ -34,6 +32,11 @@ export default {
required: true,
},
},
+ computed: {
+ sortedSelectedLabels() {
+ return sortBy(this.selectedLabels, (label) => (isScopedLabel(label) ? 0 : 1));
+ },
+ },
methods: {
labelFilterUrl(label) {
return `${this.labelsFilterBasePath}?${this.labelsFilterParam}[]=${encodeURIComponent(
@@ -63,7 +66,7 @@ export default {
</span>
<template v-else>
<gl-label
- v-for="label in selectedLabels"
+ v-for="label in sortedSelectedLabels"
:key="label.id"
data-qa-selector="selected_label_content"
:data-qa-label-name="label.title"
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/graphql/create_label.mutation.graphql b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/graphql/create_label.mutation.graphql
index 9aa4f5d165e..eb478645a03 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/graphql/create_label.mutation.graphql
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/graphql/create_label.mutation.graphql
@@ -6,9 +6,7 @@ mutation createLabel($title: String!, $color: String, $projectPath: ID, $groupPa
id
color
description
- descriptionHtml
title
- textColor
}
errors
}
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/label_item.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/label_item.vue
index e8fdf4bb0c2..f27f0b4e34c 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/label_item.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/label_item.vue
@@ -1,82 +1,21 @@
<script>
-import { GlLink, GlIcon } from '@gitlab/ui';
-
export default {
- functional: true,
props: {
label: {
type: Object,
required: true,
},
- isLabelSet: {
- type: Boolean,
- required: true,
- },
- highlight: {
- type: Boolean,
- required: false,
- default: false,
- },
- },
- render(h, { props, listeners }) {
- const { label, highlight, isLabelSet } = props;
-
- const labelColorBox = h('span', {
- class: 'dropdown-label-box gl-flex-shrink-0 gl-top-0 gl-mr-3',
- style: {
- backgroundColor: label.color,
- },
- attrs: {
- 'data-testid': 'label-color-box',
- },
- });
-
- const checkedIcon = h(GlIcon, {
- class: {
- 'gl-mr-3 gl-flex-shrink-0': true,
- hidden: !isLabelSet,
- },
- props: {
- name: 'mobile-issue-close',
- },
- });
-
- const noIcon = h('span', {
- class: {
- 'gl-mr-5 gl-pr-3': true,
- hidden: isLabelSet,
- },
- attrs: {
- 'data-testid': 'no-icon',
- },
- });
-
- const labelTitle = h('span', label.title);
-
- const labelLink = h(
- GlLink,
- {
- class: 'gl-display-flex gl-align-items-center label-item gl-text-black-normal',
- on: {
- click: () => {
- listeners.clickLabel(label);
- },
- },
- },
- [noIcon, checkedIcon, labelColorBox, labelTitle],
- );
-
- return h(
- 'li',
- {
- class: {
- 'gl-display-block': true,
- 'gl-text-left': true,
- 'is-focused': highlight,
- },
- },
- [labelLink],
- );
},
};
</script>
+
+<template>
+ <div>
+ <span
+ class="dropdown-label-box gl-flex-shrink-0 gl-top-0 gl-mr-3"
+ :style="{ 'background-color': label.color }"
+ data-testid="label-color-box"
+ ></span>
+ <span>{{ label.title }}</span>
+ </div>
+</template>
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue
index 0499dfe468f..3c834770563 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue
@@ -1,57 +1,40 @@
<script>
-import $ from 'jquery';
import Vue from 'vue';
-import Vuex, { mapState, mapActions, mapGetters } from 'vuex';
-import { isInViewport } from '~/lib/utils/common_utils';
+import Vuex from 'vuex';
import { __ } from '~/locale';
-
+import SidebarEditableItem from '~/sidebar/components/sidebar_editable_item.vue';
import { DropdownVariant } from './constants';
-import DropdownButton from './dropdown_button.vue';
import DropdownContents from './dropdown_contents.vue';
-import DropdownTitle from './dropdown_title.vue';
import DropdownValue from './dropdown_value.vue';
import DropdownValueCollapsed from './dropdown_value_collapsed.vue';
import issueLabelsQuery from './graphql/issue_labels.query.graphql';
-import labelsSelectModule from './store';
+import {
+ isDropdownVariantSidebar,
+ isDropdownVariantStandalone,
+ isDropdownVariantEmbedded,
+} from './utils';
Vue.use(Vuex);
export default {
- store: new Vuex.Store(labelsSelectModule()),
components: {
- DropdownTitle,
DropdownValue,
- DropdownButton,
DropdownContents,
DropdownValueCollapsed,
+ SidebarEditableItem,
},
- inject: ['iid', 'projectPath'],
+ inject: ['iid', 'projectPath', 'allowLabelEdit'],
props: {
allowLabelRemove: {
type: Boolean,
required: false,
default: false,
},
- allowLabelEdit: {
- type: Boolean,
- required: false,
- default: false,
- },
- allowLabelCreate: {
- type: Boolean,
- required: false,
- default: false,
- },
allowMultiselect: {
type: Boolean,
required: false,
default: false,
},
- allowScopedLabels: {
- type: Boolean,
- required: false,
- default: false,
- },
variant: {
type: String,
required: false,
@@ -67,16 +50,6 @@ export default {
required: false,
default: false,
},
- labelsFetchPath: {
- type: String,
- required: false,
- default: '',
- },
- labelsManagePath: {
- type: String,
- required: false,
- default: '',
- },
labelsFilterBasePath: {
type: String,
required: false,
@@ -138,149 +111,25 @@ export default {
},
},
},
- computed: {
- ...mapState(['showDropdownButton', 'showDropdownContents']),
- ...mapGetters([
- 'isDropdownVariantSidebar',
- 'isDropdownVariantStandalone',
- 'isDropdownVariantEmbedded',
- ]),
- dropdownButtonVisible() {
- return this.isDropdownVariantSidebar ? this.showDropdownButton : true;
- },
- },
- watch: {
- selectedLabels(selectedLabels) {
- this.setInitialState({
- selectedLabels,
- });
- },
- showDropdownContents(showDropdownContents) {
- this.setContentIsOnViewport(showDropdownContents);
- },
- isEditing(newVal) {
- if (newVal) {
- this.toggleDropdownContents();
- }
- },
- },
- mounted() {
- this.setInitialState({
- variant: this.variant,
- allowLabelRemove: this.allowLabelRemove,
- allowLabelEdit: this.allowLabelEdit,
- allowLabelCreate: this.allowLabelCreate,
- allowMultiselect: this.allowMultiselect,
- allowScopedLabels: this.allowScopedLabels,
- dropdownButtonText: this.dropdownButtonText,
- selectedLabels: this.selectedLabels,
- labelsFetchPath: this.labelsFetchPath,
- labelsManagePath: this.labelsManagePath,
- labelsFilterBasePath: this.labelsFilterBasePath,
- labelsFilterParam: this.labelsFilterParam,
- labelsListTitle: this.labelsListTitle,
- footerCreateLabelTitle: this.footerCreateLabelTitle,
- footerManageLabelTitle: this.footerManageLabelTitle,
- });
-
- this.$store.subscribeAction({
- after: this.handleVuexActionDispatch,
- });
-
- document.addEventListener('mousedown', this.handleDocumentMousedown);
- document.addEventListener('click', this.handleDocumentClick);
- },
- beforeDestroy() {
- document.removeEventListener('mousedown', this.handleDocumentMousedown);
- document.removeEventListener('click', this.handleDocumentClick);
- },
methods: {
- ...mapActions(['setInitialState', 'toggleDropdownContents']),
- /**
- * This method stores a mousedown event's target.
- * Required by the click listener because the click
- * event itself has no reference to this element.
- */
- handleDocumentMousedown({ target }) {
- this.mousedownTarget = target;
- },
- /**
- * This method listens for document-wide click event
- * and toggle dropdown if user clicks anywhere outside
- * the dropdown while dropdown is visible.
- */
- handleDocumentClick({ target }) {
- // We also perform the toggle exception check for the
- // last mousedown event's target to avoid hiding the
- // box when the mousedown happened inside the box and
- // only the mouseup did not.
- if (
- this.showDropdownContents &&
- !this.preventDropdownToggleOnClick(target) &&
- !this.preventDropdownToggleOnClick(this.mousedownTarget)
- ) {
- this.toggleDropdownContents();
- }
- },
- /**
- * This method checks whether a given click target
- * should prevent the dropdown from being toggled.
- */
- preventDropdownToggleOnClick(target) {
- // This approach of element detection is needed
- // as the dropdown wrapper is not using `GlDropdown` as
- // it will also require us to use `BDropdownForm`
- // which is yet to be implemented in GitLab UI.
- const hasExceptionClass = [
- 'js-dropdown-button',
- 'js-btn-cancel-create',
- 'js-sidebar-dropdown-toggle',
- ].some(
- (className) =>
- target?.classList.contains(className) ||
- target?.parentElement?.classList.contains(className),
- );
-
- const hasExceptionParent = ['.js-btn-back', '.js-labels-list'].some(
- (className) => $(target).parents(className).length,
- );
-
- const isInDropdownButtonCollapsed = this.$refs.dropdownButtonCollapsed?.$el.contains(target);
-
- const isInDropdownContents = this.$refs.dropdownContents?.$el.contains(target);
-
- return (
- hasExceptionClass ||
- hasExceptionParent ||
- isInDropdownButtonCollapsed ||
- isInDropdownContents
- );
- },
handleDropdownClose(labels) {
- // Only emit label updates if there are any labels to update
- // on UI.
- if (this.showDropdownContents) {
- this.toggleDropdownContents();
- }
if (labels.length) this.$emit('updateSelectedLabels', labels);
this.$emit('onDropdownClose');
},
+ collapseDropdown() {
+ this.$refs.editable.collapse();
+ },
handleCollapsedValueClick() {
this.$emit('toggleCollapse');
},
- setContentIsOnViewport(showDropdownContents) {
- if (!showDropdownContents) {
- this.contentIsOnViewport = true;
-
- return;
- }
-
+ showDropdown() {
this.$nextTick(() => {
- if (this.$refs.dropdownContents) {
- this.contentIsOnViewport = isInViewport(this.$refs.dropdownContents.$el);
- }
+ this.$refs.dropdownContents.showDropdown();
});
},
+ isDropdownVariantSidebar,
+ isDropdownVariantStandalone,
+ isDropdownVariantEmbedded,
},
};
</script>
@@ -289,58 +138,63 @@ export default {
<div
class="labels-select-wrapper position-relative"
:class="{
- 'is-standalone': isDropdownVariantStandalone,
- 'is-embedded': isDropdownVariantEmbedded,
+ 'is-standalone': isDropdownVariantStandalone(variant),
+ 'is-embedded': isDropdownVariantEmbedded(variant),
}"
>
- <template v-if="isDropdownVariantSidebar">
+ <template v-if="isDropdownVariantSidebar(variant)">
<dropdown-value-collapsed
ref="dropdownButtonCollapsed"
:labels="issueLabels"
@onValueClick="handleCollapsedValueClick"
/>
- <dropdown-title
- :allow-label-edit="allowLabelEdit"
- :labels-select-in-progress="labelsSelectInProgress"
- />
- <dropdown-value
- :disable-labels="labelsSelectInProgress"
- :selected-labels="issueLabels"
- :allow-label-remove="allowLabelRemove"
- :allow-scoped-labels="allowScopedLabels"
- :labels-filter-base-path="labelsFilterBasePath"
- :labels-filter-param="labelsFilterParam"
- @onLabelRemove="$emit('onLabelRemove', $event)"
+ <sidebar-editable-item
+ ref="editable"
+ :title="__('Labels')"
+ :loading="labelsSelectInProgress"
+ :can-edit="allowLabelEdit"
+ @open="showDropdown"
>
- <slot></slot>
- </dropdown-value>
- <dropdown-button v-show="dropdownButtonVisible" class="gl-mt-2" />
- <dropdown-contents
- v-if="dropdownButtonVisible && showDropdownContents"
- ref="dropdownContents"
- :allow-multiselect="allowMultiselect"
- :labels-list-title="labelsListTitle"
- :footer-create-label-title="footerCreateLabelTitle"
- :footer-manage-label-title="footerManageLabelTitle"
- :render-on-top="!contentIsOnViewport"
- :labels-create-title="labelsCreateTitle"
- :selected-labels="selectedLabels"
- @closeDropdown="handleDropdownClose"
- />
- </template>
- <template v-if="isDropdownVariantStandalone || isDropdownVariantEmbedded">
- <dropdown-button v-show="dropdownButtonVisible" />
- <dropdown-contents
- v-if="dropdownButtonVisible && showDropdownContents"
- ref="dropdownContents"
- :allow-multiselect="allowMultiselect"
- :labels-list-title="labelsListTitle"
- :footer-create-label-title="footerCreateLabelTitle"
- :footer-manage-label-title="footerManageLabelTitle"
- :render-on-top="!contentIsOnViewport"
- :selected-labels="selectedLabels"
- @closeDropdown="handleDropdownClose"
- />
+ <template #collapsed>
+ <dropdown-value
+ :disable-labels="labelsSelectInProgress"
+ :selected-labels="issueLabels"
+ :allow-label-remove="allowLabelRemove"
+ :labels-filter-base-path="labelsFilterBasePath"
+ :labels-filter-param="labelsFilterParam"
+ @onLabelRemove="$emit('onLabelRemove', $event)"
+ >
+ <slot></slot>
+ </dropdown-value>
+ </template>
+ <template #default="{ edit }">
+ <dropdown-value
+ :disable-labels="labelsSelectInProgress"
+ :selected-labels="issueLabels"
+ :allow-label-remove="allowLabelRemove"
+ :labels-filter-base-path="labelsFilterBasePath"
+ :labels-filter-param="labelsFilterParam"
+ class="gl-mb-2"
+ @onLabelRemove="$emit('onLabelRemove', $event)"
+ >
+ <slot></slot>
+ </dropdown-value>
+ <dropdown-contents
+ v-if="edit"
+ ref="dropdownContents"
+ :dropdown-button-text="dropdownButtonText"
+ :allow-multiselect="allowMultiselect"
+ :labels-list-title="labelsListTitle"
+ :footer-create-label-title="footerCreateLabelTitle"
+ :footer-manage-label-title="footerManageLabelTitle"
+ :labels-create-title="labelsCreateTitle"
+ :selected-labels="selectedLabels"
+ :variant="variant"
+ @closeDropdown="collapseDropdown"
+ @setLabels="handleDropdownClose"
+ />
+ </template>
+ </sidebar-editable-item>
</template>
</div>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/actions.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/actions.js
deleted file mode 100644
index b3d4a204a81..00000000000
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/actions.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import * as types from './mutation_types';
-
-export const setInitialState = ({ commit }, props) => commit(types.SET_INITIAL_STATE, props);
-
-export const toggleDropdownButton = ({ commit }) => commit(types.TOGGLE_DROPDOWN_BUTTON);
-export const toggleDropdownContents = ({ commit }) => commit(types.TOGGLE_DROPDOWN_CONTENTS);
-
-export const toggleDropdownContentsCreateView = ({ commit }) =>
- commit(types.TOGGLE_DROPDOWN_CONTENTS_CREATE_VIEW);
-
-export const updateSelectedLabels = ({ commit }, labels) =>
- commit(types.UPDATE_SELECTED_LABELS, { labels });
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/getters.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/getters.js
deleted file mode 100644
index d14f96720b7..00000000000
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/getters.js
+++ /dev/null
@@ -1,52 +0,0 @@
-import { __, s__, sprintf } from '~/locale';
-import { DropdownVariant } from '../constants';
-
-/**
- * Returns string representing current labels
- * selection on dropdown button.
- *
- * @param {object} state
- */
-export const dropdownButtonText = (state, getters) => {
- const selectedLabels = getters.isDropdownVariantSidebar
- ? state.labels.filter((label) => label.set)
- : state.selectedLabels;
-
- if (!selectedLabels.length) {
- return state.dropdownButtonText || __('Label');
- } else if (selectedLabels.length > 1) {
- return sprintf(s__('LabelSelect|%{firstLabelName} +%{remainingLabelCount} more'), {
- firstLabelName: selectedLabels[0].title,
- remainingLabelCount: selectedLabels.length - 1,
- });
- }
- return selectedLabels[0].title;
-};
-
-/**
- * Returns array containing only label IDs from
- * selectedLabels array.
- * @param {object} state
- */
-export const selectedLabelsList = (state) => state.selectedLabels.map((label) => label.id);
-
-/**
- * Returns boolean representing whether dropdown variant
- * is `sidebar`
- * @param {object} state
- */
-export const isDropdownVariantSidebar = (state) => state.variant === DropdownVariant.Sidebar;
-
-/**
- * Returns boolean representing whether dropdown variant
- * is `standalone`
- * @param {object} state
- */
-export const isDropdownVariantStandalone = (state) => state.variant === DropdownVariant.Standalone;
-
-/**
- * Returns boolean representing whether dropdown variant
- * is `embedded`
- * @param {object} state
- */
-export const isDropdownVariantEmbedded = (state) => state.variant === DropdownVariant.Embedded;
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/index.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/index.js
deleted file mode 100644
index 5f61cb732c8..00000000000
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/index.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import * as actions from './actions';
-import * as getters from './getters';
-import mutations from './mutations';
-import state from './state';
-
-export default () => ({
- namespaced: true,
- state: state(),
- actions,
- getters,
- mutations,
-});
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutation_types.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutation_types.js
deleted file mode 100644
index bd71c3b85f1..00000000000
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutation_types.js
+++ /dev/null
@@ -1,8 +0,0 @@
-export const SET_INITIAL_STATE = 'SET_INITIAL_STATE';
-
-export const TOGGLE_DROPDOWN_BUTTON = 'TOGGLE_DROPDOWN_VISIBILITY';
-export const TOGGLE_DROPDOWN_CONTENTS = 'TOGGLE_DROPDOWN_CONTENTS';
-
-export const UPDATE_SELECTED_LABELS = 'UPDATE_SELECTED_LABELS';
-
-export const TOGGLE_DROPDOWN_CONTENTS_CREATE_VIEW = 'TOGGLE_DROPDOWN_CONTENTS_CREATE_VIEW';
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutations.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutations.js
deleted file mode 100644
index 45ec4d7ae04..00000000000
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutations.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import { isScopedLabel, scopedLabelKey } from '~/lib/utils/common_utils';
-import { DropdownVariant } from '../constants';
-import * as types from './mutation_types';
-
-export default {
- [types.SET_INITIAL_STATE](state, props) {
- Object.assign(state, { ...props });
- },
-
- [types.TOGGLE_DROPDOWN_BUTTON](state) {
- state.showDropdownButton = !state.showDropdownButton;
- },
-
- [types.TOGGLE_DROPDOWN_CONTENTS](state) {
- if (state.variant === DropdownVariant.Sidebar) {
- state.showDropdownButton = !state.showDropdownButton;
- }
- state.showDropdownContents = !state.showDropdownContents;
- // Ensure that Create View is hidden by default
- // when dropdown contents are revealed.
- if (state.showDropdownContents) {
- state.showDropdownContentsCreateView = false;
- }
- },
-
- [types.TOGGLE_DROPDOWN_CONTENTS_CREATE_VIEW](state) {
- state.showDropdownContentsCreateView = !state.showDropdownContentsCreateView;
- },
- [types.UPDATE_SELECTED_LABELS](state, { labels }) {
- // Find the label to update from all the labels
- // and change `set` prop value to represent their current state.
- const labelId = labels.pop()?.id;
- const candidateLabel = state.labels.find((label) => labelId === label.id);
- if (candidateLabel) {
- candidateLabel.touched = true;
- candidateLabel.set = !candidateLabel.set;
- }
-
- if (isScopedLabel(candidateLabel)) {
- const scopedBase = scopedLabelKey(candidateLabel);
- const currentActiveScopedLabel = state.labels.find(
- ({ title }) => title.indexOf(scopedBase) === 0 && title !== candidateLabel.title,
- );
-
- if (currentActiveScopedLabel) {
- currentActiveScopedLabel.set = false;
- }
- }
- },
-};
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/state.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/state.js
deleted file mode 100644
index 220bab05ed2..00000000000
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/state.js
+++ /dev/null
@@ -1,28 +0,0 @@
-export default () => ({
- // Initial Data
- labels: [],
- selectedLabels: [],
- labelsListTitle: '',
- footerCreateLabelTitle: '',
- footerManageLabelTitle: '',
- dropdownButtonText: '',
-
- // Paths
- namespace: '',
- labelsFetchPath: '',
- labelsFilterBasePath: '',
-
- // UI Flags
- variant: '',
- allowLabelRemove: false,
- allowLabelCreate: false,
- allowLabelEdit: false,
- allowScopedLabels: false,
- allowMultiselect: false,
- showDropdownButton: false,
- showDropdownContents: false,
- showDropdownContentsCreateView: false,
- labelsFetchInProgress: false,
- labelCreateInProgress: false,
- selectedLabelsUpdated: false,
-});
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/utils.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/utils.js
new file mode 100644
index 00000000000..b5cd946a189
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/utils.js
@@ -0,0 +1,22 @@
+import { DropdownVariant } from './constants';
+
+/**
+ * Returns boolean representing whether dropdown variant
+ * is `sidebar`
+ * @param {string} variant
+ */
+export const isDropdownVariantSidebar = (variant) => variant === DropdownVariant.Sidebar;
+
+/**
+ * Returns boolean representing whether dropdown variant
+ * is `standalone`
+ * @param {string} variant
+ */
+export const isDropdownVariantStandalone = (variant) => variant === DropdownVariant.Standalone;
+
+/**
+ * Returns boolean representing whether dropdown variant
+ * is `embedded`
+ * @param {string} variant
+ */
+export const isDropdownVariantEmbedded = (variant) => variant === DropdownVariant.Embedded;
diff --git a/app/assets/javascripts/vue_shared/components/storage_counter/usage_graph.stories.js b/app/assets/javascripts/vue_shared/components/storage_counter/usage_graph.stories.js
new file mode 100644
index 00000000000..00aa5519ec6
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/storage_counter/usage_graph.stories.js
@@ -0,0 +1,38 @@
+/* eslint-disable @gitlab/require-i18n-strings */
+import '@gitlab/ui/dist/utility_classes.css';
+import UsageGraph from './usage_graph.vue';
+
+export default {
+ component: UsageGraph,
+ title: 'vue_shared/components/storage_counter/usage_graph',
+};
+
+const Template = (args, { argTypes }) => ({
+ components: { UsageGraph },
+ props: Object.keys(argTypes),
+ template: '<usage-graph v-bind="$props" />',
+});
+
+export const Default = Template.bind({});
+Default.argTypes = {
+ rootStorageStatistics: {
+ description: 'The statistics object with all its fields',
+ type: { name: 'object', required: true },
+ defaultValue: {
+ buildArtifactsSize: 400000,
+ pipelineArtifactsSize: 38000,
+ lfsObjectsSize: 4800000,
+ packagesSize: 3800000,
+ repositorySize: 39000000,
+ snippetsSize: 2000112,
+ storageSize: 39930000,
+ uploadsSize: 7000,
+ wikiSize: 300000,
+ },
+ },
+ limit: {
+ description:
+ 'When a limit is set, users will see how much of their storage usage (limit) is used. In case the limit is 0 or the current usage exceeds the limit, it just renders the distribution',
+ defaultValue: 0,
+ },
+};
diff --git a/app/assets/javascripts/vue_shared/components/storage_counter/usage_graph.vue b/app/assets/javascripts/vue_shared/components/storage_counter/usage_graph.vue
new file mode 100644
index 00000000000..c33d065ff4b
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/storage_counter/usage_graph.vue
@@ -0,0 +1,148 @@
+<script>
+import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
+import { numberToHumanSize } from '~/lib/utils/number_utils';
+import { s__ } from '~/locale';
+
+export default {
+ components: {
+ GlIcon,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
+ props: {
+ rootStorageStatistics: {
+ required: true,
+ type: Object,
+ },
+ limit: {
+ required: true,
+ type: Number,
+ },
+ },
+ computed: {
+ storageTypes() {
+ const {
+ buildArtifactsSize,
+ pipelineArtifactsSize,
+ lfsObjectsSize,
+ packagesSize,
+ repositorySize,
+ storageSize,
+ wikiSize,
+ snippetsSize,
+ uploadsSize,
+ } = this.rootStorageStatistics;
+ const artifactsSize = buildArtifactsSize + pipelineArtifactsSize;
+
+ if (storageSize === 0) {
+ return null;
+ }
+
+ return [
+ {
+ name: s__('UsageQuota|Repositories'),
+ style: this.usageStyle(this.barRatio(repositorySize)),
+ class: 'gl-bg-data-viz-blue-500',
+ size: repositorySize,
+ },
+ {
+ name: s__('UsageQuota|LFS Objects'),
+ style: this.usageStyle(this.barRatio(lfsObjectsSize)),
+ class: 'gl-bg-data-viz-orange-600',
+ size: lfsObjectsSize,
+ },
+ {
+ name: s__('UsageQuota|Packages'),
+ style: this.usageStyle(this.barRatio(packagesSize)),
+ class: 'gl-bg-data-viz-aqua-500',
+ size: packagesSize,
+ },
+ {
+ name: s__('UsageQuota|Artifacts'),
+ style: this.usageStyle(this.barRatio(artifactsSize)),
+ class: 'gl-bg-data-viz-green-600',
+ size: artifactsSize,
+ tooltip: s__('UsageQuota|Artifacts is a sum of build and pipeline artifacts.'),
+ },
+ {
+ name: s__('UsageQuota|Wikis'),
+ style: this.usageStyle(this.barRatio(wikiSize)),
+ class: 'gl-bg-data-viz-magenta-500',
+ size: wikiSize,
+ },
+ {
+ name: s__('UsageQuota|Snippets'),
+ style: this.usageStyle(this.barRatio(snippetsSize)),
+ class: 'gl-bg-data-viz-orange-800',
+ size: snippetsSize,
+ },
+ {
+ name: s__('UsageQuota|Uploads'),
+ style: this.usageStyle(this.barRatio(uploadsSize)),
+ class: 'gl-bg-data-viz-aqua-700',
+ size: uploadsSize,
+ },
+ ]
+ .filter((data) => data.size !== 0)
+ .sort((a, b) => b.size - a.size);
+ },
+ },
+ methods: {
+ formatSize(size) {
+ return numberToHumanSize(size);
+ },
+ usageStyle(ratio) {
+ return { flex: ratio };
+ },
+ barRatio(size) {
+ let max = this.rootStorageStatistics.storageSize;
+
+ if (this.limit !== 0 && max <= this.limit) {
+ max = this.limit;
+ }
+
+ return size / max;
+ },
+ },
+};
+</script>
+<template>
+ <div v-if="storageTypes" class="gl-display-flex gl-flex-direction-column w-100">
+ <div class="gl-h-6 gl-my-5 gl-bg-gray-50 gl-rounded-base gl-display-flex">
+ <div
+ v-for="storageType in storageTypes"
+ :key="storageType.name"
+ class="storage-type-usage gl-h-full gl-display-inline-block"
+ :class="storageType.class"
+ :style="storageType.style"
+ data-testid="storage-type-usage"
+ ></div>
+ </div>
+ <div class="row py-0">
+ <div
+ v-for="storageType in storageTypes"
+ :key="storageType.name"
+ class="col-md-auto gl-display-flex gl-align-items-center"
+ data-testid="storage-type-legend"
+ >
+ <div class="gl-h-2 gl-w-5 gl-mr-2 gl-display-inline-block" :class="storageType.class"></div>
+ <span class="gl-mr-2 gl-font-weight-bold gl-font-sm">
+ {{ storageType.name }}
+ </span>
+ <span class="gl-text-gray-500 gl-font-sm">
+ {{ formatSize(storageType.size) }}
+ </span>
+ <span
+ v-if="storageType.tooltip"
+ v-gl-tooltip
+ :title="storageType.tooltip"
+ :aria-label="storageType.tooltip"
+ class="gl-ml-2"
+ >
+ <gl-icon name="question" :size="12" />
+ </span>
+ </div>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/vue_shared/components/timezone_dropdown.vue b/app/assets/javascripts/vue_shared/components/timezone_dropdown.vue
index b9ee74d6a03..42334d80eec 100644
--- a/app/assets/javascripts/vue_shared/components/timezone_dropdown.vue
+++ b/app/assets/javascripts/vue_shared/components/timezone_dropdown.vue
@@ -66,7 +66,7 @@ export default {
};
</script>
<template>
- <gl-dropdown :text="selectedTimezoneLabel" block lazy menu-class="gl-w-full!">
+ <gl-dropdown :text="selectedTimezoneLabel" block lazy menu-class="gl-w-full!" v-bind="$attrs">
<gl-search-box-by-type v-model.trim="searchTerm" v-autofocusonshow autofocus />
<gl-dropdown-item
v-for="timezone in filteredResults"
diff --git a/app/assets/javascripts/vue_shared/components/user_popover/user_popover.vue b/app/assets/javascripts/vue_shared/components/user_popover/user_popover.vue
index f387f8ca128..74616763f8f 100644
--- a/app/assets/javascripts/vue_shared/components/user_popover/user_popover.vue
+++ b/app/assets/javascripts/vue_shared/components/user_popover/user_popover.vue
@@ -1,6 +1,12 @@
<script>
-/* eslint-disable vue/no-v-html */
-import { GlPopover, GlLink, GlSkeletonLoader, GlIcon } from '@gitlab/ui';
+import {
+ GlPopover,
+ GlLink,
+ GlSkeletonLoader,
+ GlIcon,
+ GlSafeHtmlDirective,
+ GlSprintf,
+} from '@gitlab/ui';
import UserNameWithStatus from '~/sidebar/components/assignees/user_name_with_status.vue';
import { glEmojiTag } from '../../../emoji';
import UserAvatarImage from '../user_avatar/user_avatar_image.vue';
@@ -17,6 +23,10 @@ export default {
GlSkeletonLoader,
UserAvatarImage,
UserNameWithStatus,
+ GlSprintf,
+ },
+ directives: {
+ SafeHtml: GlSafeHtmlDirective,
},
props: {
target: {
@@ -50,6 +60,7 @@ export default {
return this.user?.status?.availability || '';
},
},
+ safeHtmlConfig: { ADD_TAGS: ['gl-emoji'] },
};
</script>
@@ -83,7 +94,7 @@ export default {
<div class="gl-text-gray-500">
<div v-if="user.bio" class="gl-display-flex gl-mb-2">
<gl-icon name="profile" class="gl-text-gray-400 gl-flex-shrink-0" />
- <span ref="bio" class="gl-ml-2 gl-overflow-hidden" v-html="user.bioHtml"></span>
+ <span ref="bio" class="gl-ml-2 gl-overflow-hidden">{{ user.bio }}</span>
</div>
<div v-if="user.workInformation" class="gl-display-flex gl-mb-2">
<gl-icon name="work" class="gl-text-gray-400 gl-flex-shrink-0" />
@@ -95,12 +106,14 @@ export default {
<span class="gl-ml-2">{{ user.location }}</span>
</div>
<div v-if="statusHtml" class="js-user-status gl-mt-3">
- <span v-html="statusHtml"></span>
+ <span v-safe-html:[$options.safeHtmlConfig]="statusHtml"></span>
</div>
<div v-if="user.bot" class="gl-text-blue-500">
<gl-icon name="question" />
<gl-link data-testid="user-popover-bot-docs-link" :href="user.websiteUrl">
- {{ sprintf(__('Learn more about %{username}'), { username: user.name }) }}
+ <gl-sprintf :message="__('Learn more about %{username}')">
+ <template #username>{{ user.name }}</template>
+ </gl-sprintf>
</gl-link>
</div>
</template>
diff --git a/app/assets/javascripts/vue_shared/security_reports/constants.js b/app/assets/javascripts/vue_shared/security_reports/constants.js
index 4a50dfbd82f..b024e92bd0e 100644
--- a/app/assets/javascripts/vue_shared/security_reports/constants.js
+++ b/app/assets/javascripts/vue_shared/security_reports/constants.js
@@ -24,6 +24,7 @@ export const REPORT_TYPE_DEPENDENCY_SCANNING = 'dependency_scanning';
export const REPORT_TYPE_CONTAINER_SCANNING = 'container_scanning';
export const REPORT_TYPE_CLUSTER_IMAGE_SCANNING = 'cluster_image_scanning';
export const REPORT_TYPE_COVERAGE_FUZZING = 'coverage_fuzzing';
+export const REPORT_TYPE_CORPUS_MANAGEMENT = 'corpus_management';
export const REPORT_TYPE_LICENSE_COMPLIANCE = 'license_scanning';
export const REPORT_TYPE_API_FUZZING = 'api_fuzzing';
diff --git a/app/assets/javascripts/vue_shared/security_reports/store/modules/sast/state.js b/app/assets/javascripts/vue_shared/security_reports/store/modules/sast/state.js
index e860e3af924..c1b3f546431 100644
--- a/app/assets/javascripts/vue_shared/security_reports/store/modules/sast/state.js
+++ b/app/assets/javascripts/vue_shared/security_reports/store/modules/sast/state.js
@@ -1,7 +1,5 @@
export default () => ({
paths: {
- head: null,
- base: null,
diffEndpoint: null,
},
diff --git a/app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/state.js b/app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/state.js
index e860e3af924..c1b3f546431 100644
--- a/app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/state.js
+++ b/app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/state.js
@@ -1,7 +1,5 @@
export default () => ({
paths: {
- head: null,
- base: null,
diffEndpoint: null,
},
diff --git a/app/assets/javascripts/webpack_non_compiled_placeholder.js b/app/assets/javascripts/webpack_non_compiled_placeholder.js
index 8cd1d2eb2ca..55ac2f0be6a 100644
--- a/app/assets/javascripts/webpack_non_compiled_placeholder.js
+++ b/app/assets/javascripts/webpack_non_compiled_placeholder.js
@@ -8,7 +8,7 @@ Object.assign(div.style, {
left: 0,
'z-index': 100000,
background: 'rgba(0,0,0,0.9)',
- 'font-size': '25px',
+ 'font-size': '20px',
'font-family': 'monospace',
color: 'white',
padding: '2.5em',
@@ -16,9 +16,23 @@ Object.assign(div.style, {
});
div.innerHTML = `
-<h1 style="color:white">🧙 Webpack is doing its magic 🧙</h1>
-<p>If you use Hot Module reloading, the page will reload in a few seconds.</p>
-<p>If you do not use Hot Module reloading, please <a href="">reload the page manually in a few seconds</a></p>
+<!-- https://github.com/webpack/media/blob/master/logo/icon-square-big.svg -->
+<svg height="50" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 1200">
+ <path fill="#FFF" d="M600 0l530.3 300v600L600 1200 69.7 900V300z"/>
+ <path fill="#8ED6FB" class="st1" d="M1035.6 879.3l-418.1 236.5V931.6L878 788.3l157.6 91zm28.6-25.9V358.8l-153 88.3V765l153 88.4zm-901.5 25.9l418.1 236.5V931.6L320.3 788.3l-157.6 91zm-28.6-25.9V358.8l153 88.3V765l-153 88.4zM152 326.8L580.8 84.2v178.1L306.1 413.4l-2.1 1.2-152-87.8zm894.3 0L617.5 84.2v178.1l274.7 151.1 2.1 1.2 152-87.8z"/>
+ <path fill="#1C78C0" d="M580.8 889.7l-257-141.3v-280l257 148.4v272.9zm36.7 0l257-141.3v-280l-257 148.4v272.9zm-18.3-283.6zM341.2 436l258-141.9 258 141.9-258 149-258-149z"/>
+</svg>
+
+<h1 style="color:white">✨ webpack is compiling frontend assets ✨</h1>
+<p>
+ To reduce GDK memory consumption, incremental on-demand compiling is on by default.<br />
+ You can disable this within gdk.yml.
+ Learn more <a href="https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/configuration.md#webpack-settings">here</a>.
+</p>
+<p>
+ If you have live_reload enabled, the page will reload automatically when complete.<br />
+ Otherwise, please <a href="">reload the page manually in a few seconds</a>
+</p>
`;
document.body.append(div);
diff --git a/app/assets/javascripts/whats_new/components/feature.vue b/app/assets/javascripts/whats_new/components/feature.vue
index 11096b08032..a93bda326de 100644
--- a/app/assets/javascripts/whats_new/components/feature.vue
+++ b/app/assets/javascripts/whats_new/components/feature.vue
@@ -40,7 +40,7 @@ export default {
:href="feature.url"
target="_blank"
class="gl-display-block"
- data-track-event="click_whats_new_item"
+ data-track-action="click_whats_new_item"
:data-track-label="feature.title"
:data-track-property="feature.url"
>
@@ -55,7 +55,7 @@ export default {
:href="feature.url"
target="_blank"
class="whats-new-item-title-link gl-display-block gl-mt-4 gl-mb-1"
- data-track-event="click_whats_new_item"
+ data-track-action="click_whats_new_item"
:data-track-label="feature.title"
:data-track-property="feature.url"
>
@@ -79,7 +79,7 @@ export default {
<gl-button
:href="feature.url"
target="_blank"
- data-track-event="click_whats_new_item"
+ data-track-action="click_whats_new_item"
:data-track-label="feature.title"
:data-track-property="feature.url"
>
diff --git a/app/assets/javascripts/work_items/components/app.vue b/app/assets/javascripts/work_items/components/app.vue
new file mode 100644
index 00000000000..93de17d1e43
--- /dev/null
+++ b/app/assets/javascripts/work_items/components/app.vue
@@ -0,0 +1,9 @@
+<script>
+export default {
+ name: 'WorkItemRoot',
+};
+</script>
+
+<template>
+ <div></div>
+</template>
diff --git a/app/assets/javascripts/work_items/graphql/typedefs.graphql b/app/assets/javascripts/work_items/graphql/typedefs.graphql
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/app/assets/javascripts/work_items/graphql/typedefs.graphql
diff --git a/app/assets/javascripts/work_items/index.js b/app/assets/javascripts/work_items/index.js
new file mode 100644
index 00000000000..a635d43776d
--- /dev/null
+++ b/app/assets/javascripts/work_items/index.js
@@ -0,0 +1,13 @@
+import Vue from 'vue';
+import App from './components/app.vue';
+
+export const initWorkItemsRoot = () => {
+ const el = document.querySelector('#js-work-items');
+
+ return new Vue({
+ el,
+ render(createElement) {
+ return createElement(App);
+ },
+ });
+};
diff --git a/app/assets/stylesheets/application_dark.scss b/app/assets/stylesheets/application_dark.scss
index 7d6ccc40278..dae0cd72a8f 100644
--- a/app/assets/stylesheets/application_dark.scss
+++ b/app/assets/stylesheets/application_dark.scss
@@ -44,6 +44,17 @@ body.gl-dark {
}
}
+ .header-search {
+ background-color: var(--gray-100) !important;
+ box-shadow: inset 0 0 0 1px var(--border-color) !important;
+
+ &:active,
+ &:hover {
+ background-color: var(--gray-100) !important;
+ box-shadow: inset 0 0 0 1px var(--blue-200) !important;
+ }
+ }
+
.search {
form {
background-color: var(--gray-100);
diff --git a/app/assets/stylesheets/components/content_editor.scss b/app/assets/stylesheets/components/content_editor.scss
index 64abf5574fa..a013d971efb 100644
--- a/app/assets/stylesheets/components/content_editor.scss
+++ b/app/assets/stylesheets/components/content_editor.scss
@@ -1,8 +1,10 @@
.ProseMirror {
td,
th,
- li {
- :only-child {
+ li,
+ dd,
+ dt {
+ :first-child {
margin-bottom: 0 !important;
}
}
@@ -34,6 +36,20 @@
}
}
}
+
+ .dl-content {
+ width: 100%;
+
+ > li {
+ list-style-type: none;
+ margin-left: $gl-spacing-scale-5;
+
+ &.dl-term {
+ margin: 0;
+ font-weight: 600;
+ }
+ }
+ }
}
.table-creator-grid-item {
diff --git a/app/assets/stylesheets/errors.scss b/app/assets/stylesheets/errors.scss
index f4519841ce3..dc08c816d7d 100644
--- a/app/assets/stylesheets/errors.scss
+++ b/app/assets/stylesheets/errors.scss
@@ -91,6 +91,7 @@ a {
.field {
margin-bottom: 0;
margin-right: 0.5em;
+ flex: 1;
}
}
}
diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss
index 264373451d5..a0682eabf01 100644
--- a/app/assets/stylesheets/framework/blocks.scss
+++ b/app/assets/stylesheets/framework/blocks.scss
@@ -154,12 +154,6 @@
}
}
- .cover-desc {
- &.username:last-child {
- padding-bottom: $gl-padding;
- }
- }
-
.cover-controls {
@include media-breakpoint-up(sm) {
position: absolute;
@@ -343,8 +337,6 @@
}
.code-block {
- background: $black;
- color: $gray-darkest;
white-space: pre;
overflow-x: auto;
font-size: 12px;
diff --git a/app/assets/stylesheets/framework/diffs.scss b/app/assets/stylesheets/framework/diffs.scss
index 61a20c7a8fd..568182ad796 100644
--- a/app/assets/stylesheets/framework/diffs.scss
+++ b/app/assets/stylesheets/framework/diffs.scss
@@ -613,7 +613,7 @@ table.code {
grid-template-columns: 1fr 1fr;
}
- &.inline {
+ &.inline-diff-view {
.diff-grid-comments {
display: grid;
grid-template-columns: 1fr;
@@ -682,26 +682,6 @@ table.code {
max-height: 50vh;
}
-.diff-stats-summary-toggler {
- padding: 0;
- background-color: transparent;
- border: 0;
- color: $blue-600;
- font-weight: $gl-font-weight-bold;
-
- &:hover,
- &:focus {
- outline: none;
- color: $blue-800;
- }
-
- .caret-icon {
- position: relative;
- top: 2px;
- left: -1px;
- }
-}
-
// Mobile
@media (max-width: 480px) {
.diff-title {
@@ -853,21 +833,14 @@ table.code {
.diff-files-changed {
.inline-parallel-buttons {
- position: relative;
+ @include gl-relative;
z-index: 1;
}
- .commit-stat-summary {
- @include media-breakpoint-up(sm) {
- background-color: $white;
- }
- }
-
@include media-breakpoint-up(sm) {
- position: -webkit-sticky;
- position: sticky;
+ @include gl-sticky;
top: $header-height + $mr-tabs-height;
- background-color: $white;
+ @include gl-bg-white;
z-index: 200;
.with-performance-bar & {
@@ -875,14 +848,13 @@ table.code {
}
&.is-stuck {
- padding-top: 0;
- padding-bottom: 0;
+ @include gl-py-0;
border-top: 1px solid $white-dark;
border-bottom: 1px solid $white-dark;
.diff-stats-additions-deletions-expanded,
.inline-parallel-buttons {
- display: none !important;
+ @include gl-display-none;
}
}
}
@@ -890,12 +862,13 @@ table.code {
@include media-breakpoint-up(lg) {
&.is-stuck {
.diff-stats-additions-deletions-collapsed {
- display: block !important;
+ @include gl-display-block;
}
}
}
}
+
.diff-file-changes {
max-width: 560px;
width: 100%;
diff --git a/app/assets/stylesheets/framework/filters.scss b/app/assets/stylesheets/framework/filters.scss
index f76101d92b1..5dd71cec8d1 100644
--- a/app/assets/stylesheets/framework/filters.scss
+++ b/app/assets/stylesheets/framework/filters.scss
@@ -386,15 +386,6 @@
}
}
}
-
- .boards-add-list > .btn {
- text-align: left;
-
- > svg {
- position: absolute;
- right: 6px;
- }
- }
}
.droplab-dropdown .dropdown-menu .filter-dropdown-item {
diff --git a/app/assets/stylesheets/framework/icons.scss b/app/assets/stylesheets/framework/icons.scss
index 222e10f51ad..0aeb7208c59 100644
--- a/app/assets/stylesheets/framework/icons.scss
+++ b/app/assets/stylesheets/framework/icons.scss
@@ -36,6 +36,7 @@
}
}
+.ci-status-icon-notification,
.ci-status-icon-preparing,
.ci-status-icon-created,
.ci-status-icon-skipped,
diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss
index 603b05efe10..aeb3bb2286f 100644
--- a/app/assets/stylesheets/framework/typography.scss
+++ b/app/assets/stylesheets/framework/typography.scss
@@ -41,6 +41,12 @@
}
}
+ .media-container {
+ display: inline-flex;
+ flex-direction: column;
+ margin-bottom: $gl-spacing-scale-2;
+ }
+
img:not(.emoji) {
margin: 0 0 8px;
}
@@ -549,17 +555,12 @@
margin: 0;
font-size: $gl-font-size-small;
}
+ }
- ul.dropdown-menu {
- margin-top: 4px;
- margin-bottom: 24px;
- padding: 8px 0;
-
- li {
- margin: 0;
- padding: 0 1px;
- }
- }
+ .gl-new-dropdown-item {
+ margin: 0;
+ padding: 0;
+ line-height: 1rem;
}
/* AsciiDoc(tor) built-in alignment roles */
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index 726f8e28efe..099dfa28b9f 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -505,7 +505,7 @@ $line-removed-dark: #fac5cd !default;
* would hide other layers (selected text, matching brackets).
*
* When the transparent colors get layered on white background, they create their
- * full opacity counterparts (computed with https://stackoverflow.com/a/12228643/606571):
+ * full opacity counterparts:
*
* - white + $line-added-transparent = $line-added
* - white + $line-added-transparent + $line-added-dark-transparent = $line-added-dark
diff --git a/app/assets/stylesheets/mailer.scss b/app/assets/stylesheets/mailer.scss
index 9d889f111dd..3220510775c 100644
--- a/app/assets/stylesheets/mailer.scss
+++ b/app/assets/stylesheets/mailer.scss
@@ -1,7 +1,6 @@
@import 'framework/variables';
// Do not use 3-letter hex codes, bgcolor vs css background-color is problematic in emails
-// See https://stackoverflow.com/questions/28551981/why-are-3-digit-hex-color-code-values-interpreted-differently-in-internet-explor
//
// stylelint-disable color-hex-length
diff --git a/app/assets/stylesheets/page_bundles/_pipeline_mixins.scss b/app/assets/stylesheets/page_bundles/_pipeline_mixins.scss
index 2f8602a212d..8794acd3c78 100644
--- a/app/assets/stylesheets/page_bundles/_pipeline_mixins.scss
+++ b/app/assets/stylesheets/page_bundles/_pipeline_mixins.scss
@@ -1,15 +1,3 @@
-@mixin flat-connector-before($length: 44px) {
- &::before {
- content: '';
- position: absolute;
- top: 48%;
- left: -$length;
- border-top: 2px solid var(--border-color, $border-color);
- width: $length;
- height: 1px;
- }
-}
-
@mixin build-content($border-radius: 30px) {
display: inline-block;
padding: 8px 10px 9px;
diff --git a/app/assets/stylesheets/page_bundles/boards.scss b/app/assets/stylesheets/page_bundles/boards.scss
index 10183f774b1..4806f4b054b 100644
--- a/app/assets/stylesheets/page_bundles/boards.scss
+++ b/app/assets/stylesheets/page_bundles/boards.scss
@@ -15,14 +15,6 @@
}
}
-.dropdown-menu-issues-board-new {
- width: 320px;
-
- .dropdown-content {
- max-height: 140px;
- }
-}
-
.issue-board-dropdown-content {
margin: 0;
padding: $gl-padding-4 $gl-padding $gl-padding;
@@ -256,7 +248,8 @@
margin-right: 4px;
}
- .confidential-icon {
+ .confidential-icon,
+ .hidden-icon {
color: var(--orange-500, $orange-500);
cursor: help;
}
@@ -437,6 +430,10 @@
height: $input-height;
}
+.issue-boards-content {
+ isolation: isolate;
+}
+
.issue-boards-content.is-focused {
position: fixed;
width: 100%;
diff --git a/app/assets/stylesheets/page_bundles/cycle_analytics.scss b/app/assets/stylesheets/page_bundles/cycle_analytics.scss
index 2248d95ae24..5d42ece32c9 100644
--- a/app/assets/stylesheets/page_bundles/cycle_analytics.scss
+++ b/app/assets/stylesheets/page_bundles/cycle_analytics.scss
@@ -3,293 +3,4 @@
.cycle-analytics {
margin: 24px auto 0;
position: relative;
-
- .landing {
- margin-top: 0;
-
- .inner-content {
- white-space: normal;
-
- h4,
- p {
- margin: 7px 0 0;
- max-width: 480px;
- padding: 0 $gl-padding;
-
- @include media-breakpoint-down(sm) {
- margin: 0 auto;
- }
- }
- }
-
- .svg-container svg {
- width: 136px;
- height: 136px;
- }
- }
-
- .col-headers {
- ul {
- margin: 0;
- padding: 0;
- }
-
- li {
- line-height: 50px;
- }
- }
-
- .card {
- .content-block {
- padding: 24px 0;
- border-bottom: 0;
- position: relative;
-
- @include media-breakpoint-down(xs) {
- padding: 6px 0 24px;
- }
- }
-
- .column {
- text-align: center;
-
- @include media-breakpoint-down(xs) {
- padding: 15px 0;
- }
-
- .header {
- font-size: 30px;
- line-height: 38px;
- font-weight: $gl-font-weight-normal;
- margin: 0;
- }
-
- .text {
- color: var(--gray-500, $gray-500);
- margin: 0;
- }
-
- &:last-child {
- @include media-breakpoint-down(xs) {
- text-align: center;
- }
- }
- }
- }
-
- .stage-panel-body {
- display: flex;
- flex-wrap: wrap;
- }
-
- .stage-nav,
- .stage-entries {
- display: flex;
- vertical-align: top;
- font-size: $gl-font-size;
- }
-
- .stage-nav {
- width: 40%;
- margin-bottom: 0;
-
- ul {
- padding: 0;
- margin: 0;
- width: 100%;
- }
-
- li {
- list-style-type: none;
- }
-
- .stage-nav-item {
- line-height: 65px;
-
- &.active {
- background: var(--blue-50, $blue-50);
- border-color: var(--blue-300, $blue-300);
- box-shadow: inset 4px 0 0 0 var(--blue-500, $blue-500);
- }
-
- &:hover:not(.active) {
- background-color: var(--gray-10, $gray-10);
- box-shadow: inset 2px 0 0 0 var(--border-color, $border-color);
- cursor: pointer;
- }
-
- .stage-nav-item-cell.stage-name {
- width: 44.5%;
- }
-
- .stage-nav-item-cell.stage-median {
- min-width: 43%;
- }
-
- .stage-empty,
- .not-available {
- color: var(--gray-500, $gray-500);
- }
- }
- }
-
- .stage-panel-container {
- width: 100%;
- overflow: auto;
- }
-
- .stage-panel {
- min-width: 968px;
-
- .card-header {
- padding: 0;
- background-color: transparent;
- }
-
- .events-description {
- line-height: 65px;
- }
-
- .events-info {
- color: var(--gray-500, $gray-500);
- }
- }
-
- .stage-events {
- min-height: 467px;
- }
-
- .stage-event-list {
- margin: 0;
- padding: 0;
- }
-
- .stage-event-item {
- @include clearfix;
- list-style-type: none;
- padding-bottom: $gl-padding;
- margin-bottom: $gl-padding;
- border-bottom: 1px solid var(--gray-50, $gray-50);
-
- &:last-child {
- border-bottom: 0;
- margin-bottom: 0;
- }
-
- .item-details,
- .item-time {
- float: left;
- }
-
- .item-details {
- width: 75%;
- }
-
- .item-title {
- margin: 0 0 2px;
-
- &.issue-title,
- &.commit-title,
- &.merge-request-title {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- max-width: 100%;
- display: block;
-
- a {
- color: var(--gl-text-color, $gl-text-color);
- }
- }
- }
-
- .item-time {
- width: 25%;
- text-align: right;
- }
-
- .total-time {
- font-size: $cycle-analytics-big-font;
- color: var(--gl-text-color, $gl-text-color);
-
- span {
- color: var(--gl-text-color, $gl-text-color);
- font-size: $gl-font-size;
- }
- }
-
- .issue-date,
- .build-date {
- color: var(--gl-text-color, $gl-text-color);
- }
-
- .mr-link,
- .issue-link,
- .commit-author-link,
- .issue-author-link {
- color: var(--gl-text-color, $gl-text-color);
- }
-
- // Custom CSS for components
- .item-conmmit-component {
- .commit-icon {
- svg {
- display: inline-block;
- width: 20px;
- height: 20px;
- vertical-align: bottom;
- }
- }
- }
-
- .merge-request-branch {
- a {
- max-width: 180px;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- display: inline-block;
- vertical-align: bottom;
- }
- }
- }
-
- // Custom Styles for stage items
- .item-build-component {
- .item-title {
- .icon-build-status {
- float: left;
- margin-right: 5px;
- position: relative;
- top: 2px;
- }
-
- .item-build-name {
- color: var(--gl-text-color, $gl-text-color);
- }
-
- .pipeline-id {
- color: var(--gl-text-color, $gl-text-color);
- padding: 0 3px 0 0;
- }
-
- .ref-name {
- color: var(--gray-900, $gray-900);
- display: inline-block;
- max-width: 180px;
- text-overflow: ellipsis;
- overflow: hidden;
- white-space: nowrap;
- line-height: 1.3;
- vertical-align: top;
- }
-
- .commit-sha {
- color: var(--blue-600, $blue-600);
- line-height: 1.3;
- vertical-align: top;
- font-weight: $gl-font-weight-normal;
- }
- }
- }
}
diff --git a/app/assets/stylesheets/page_bundles/escalation_policies.scss b/app/assets/stylesheets/page_bundles/escalation_policies.scss
index f188dde1183..6f3873fea0c 100644
--- a/app/assets/stylesheets/page_bundles/escalation_policies.scss
+++ b/app/assets/stylesheets/page_bundles/escalation_policies.scss
@@ -16,9 +16,6 @@ $stroke-size: 1px;
.right-arrow {
@include gl-relative;
- @include gl-mx-5;
- @include gl-display-inline-block;
- @include gl-vertical-align-middle;
height: $stroke-size;
background-color: var(--gray-900, $gray-900);
min-width: $gl-spacing-scale-7;
@@ -27,7 +24,6 @@ $stroke-size: 1px;
@include gl-absolute;
top: -2*$stroke-size;
left: calc(100% - #{5*$stroke-size});
- @include gl-display-inline-block;
@include gl-p-1;
@include gl-border-solid;
border-width: 0 $stroke-size $stroke-size 0;
@@ -35,3 +31,24 @@ $stroke-size: 1px;
transform: rotate(-45deg);
}
}
+
+.escalation-rule-row {
+ @media (max-width: $breakpoint-lg) {
+ @include gl-flex-wrap;
+ }
+}
+
+.rule-condition {
+ @media (min-width: $breakpoint-lg) {
+ flex-basis: 25%;
+ flex-shrink: 0;
+ }
+
+ @media (max-width: $breakpoint-lg) {
+ @include gl-w-full;
+ }
+}
+
+.rule-action {
+ min-width: 0;
+}
diff --git a/app/assets/stylesheets/page_bundles/merge_requests.scss b/app/assets/stylesheets/page_bundles/merge_requests.scss
index 6a20ff3b3fa..28354b83856 100644
--- a/app/assets/stylesheets/page_bundles/merge_requests.scss
+++ b/app/assets/stylesheets/page_bundles/merge_requests.scss
@@ -40,7 +40,7 @@
position: -webkit-sticky;
position: sticky;
- // Unitless zero values are not allowed in calculations https://stackoverflow.com/a/55391061
+ // Unitless zero values are not allowed in calculations
// stylelint-disable-next-line length-zero-no-unit
top: calc(#{$top-pos} + var(--system-header-height, 0px) + var(--performance-bar-height, 0px));
// stylelint-disable-next-line length-zero-no-unit
diff --git a/app/assets/stylesheets/page_bundles/new_namespace.scss b/app/assets/stylesheets/page_bundles/new_namespace.scss
index 189f010bdb2..37a1231ec6b 100644
--- a/app/assets/stylesheets/page_bundles/new_namespace.scss
+++ b/app/assets/stylesheets/page_bundles/new_namespace.scss
@@ -17,10 +17,10 @@ $new-namespace-panel-height: 240px;
.new-namespace-panel {
&:hover {
- background-color: $gray-10;
+ background-color: var(--gray-50, $gray-10);
}
- color: $purple-700;
+ color: var(--purple-700, $purple-700);
min-height: $new-namespace-panel-height;
text-align: center;
@include media-breakpoint-up(lg) {
diff --git a/app/assets/stylesheets/page_bundles/pipeline.scss b/app/assets/stylesheets/page_bundles/pipeline.scss
index c9171eb4fc7..206c2eb09d0 100644
--- a/app/assets/stylesheets/page_bundles/pipeline.scss
+++ b/app/assets/stylesheets/page_bundles/pipeline.scss
@@ -120,17 +120,10 @@
}
}
-.pipeline-tab-content {
- display: flex;
- width: 100%;
- min-height: $dropdown-max-height-lg;
- background-color: var(--gray-50, $gray-50);
- padding: $gl-padding 0;
- overflow: auto;
-}
-// These are single-value classes to use with utility-class style CSS
-// but to still access this variable. Do not add other styles.
+// These are single-value classes to use with utility-class style CSS.
+// They are here to still access a variable or because they use magic values.
+// scoped to the graph. Do not add other styles.
.gl-pipeline-min-h {
min-height: $dropdown-max-height-lg;
}
@@ -147,22 +140,6 @@
padding-right: 120px;
}
-.gl-build-content {
- display: inline-block;
- padding: 8px 10px 9px;
- width: 100%;
- border: 1px solid var(--border-color, $border-color);
- border-radius: 30px;
- background-color: var(--white, $white);
-
- &:hover,
- &:focus {
- background-color: var(--gray-50, $gray-50);
- border: 1px solid $dropdown-toggle-active-border-color;
- color: var(--gl-text-color, $gl-text-color);
- }
-}
-
.gl-ci-action-icon-container {
position: absolute;
right: 5px;
@@ -180,259 +157,6 @@
}
}
-// Pipeline graph, used at
-// app/assets/javascripts/pipelines/components/graph/graph_component.vue
-.pipeline-graph {
- white-space: nowrap;
- transition: max-height 0.3s, padding 0.3s;
-
- .stage-column-list,
- .builds-container > ul {
- padding: 0;
- }
-
- a {
- text-decoration: none;
- color: var(--gl-text-color, $gl-text-color);
- }
-
- svg {
- vertical-align: middle;
- }
-
- .stage-column {
- display: inline-block;
- vertical-align: top;
-
- &.left-margin {
- &:not(:first-child) {
- margin-left: 44px;
-
- .left-connector {
- @include flat-connector-before;
- }
- }
- }
-
- &.no-margin {
- margin: 0;
- }
-
- li {
- list-style: none;
- }
-
- // when downstream pipelines are present, the last stage isn't the last column
- &:last-child:not(.has-downstream) {
- .build {
- // Remove right connecting horizontal line from first build in last stage
- &:first-child::after {
- border: 0;
- }
- // Remove right curved connectors from all builds in last stage
- &:not(:first-child)::after {
- border: 0;
- }
- // Remove opposite curve
- .curve::before {
- display: none;
- }
- }
- }
-
- // when upstream pipelines are present, the first stage isn't the first column
- &:first-child:not(.has-upstream) {
- .build {
- // Remove left curved connectors from all builds in first stage
- &:not(:first-child)::before {
- border: 0;
- }
- // Remove opposite curve
- .curve::after {
- display: none;
- }
- }
- }
-
- // Curve first child connecting lines in opposite direction
- .curve {
- display: none;
-
- &::before,
- &::after {
- content: '';
- width: 21px;
- height: 25px;
- position: absolute;
- top: -31px;
- border-top: 2px solid var(--border-color, $border-color);
- }
-
- &::after {
- left: -44px;
- border-right: 2px solid var(--border-color, $border-color);
- border-radius: 0 20px;
- }
-
- &::before {
- right: -44px;
- border-left: 2px solid var(--border-color, $border-color);
- border-radius: 20px 0 0;
- }
- }
- }
-
- .stage-name {
- margin: 0 0 15px 10px;
- font-weight: $gl-font-weight-bold;
- width: 176px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- line-height: 2.2em;
- }
-
- .build {
- position: relative;
- width: 186px;
- margin-bottom: 10px;
- white-space: normal;
-
- .ci-job-dropdown-container {
- // override dropdown.scss
- .dropdown-menu li button {
- padding: 0;
- text-align: center;
- }
- }
-
- .ci-status-icon svg {
- height: 24px;
- width: 24px;
- }
-
- .dropdown-menu-toggle {
- background-color: transparent;
- border: 0;
- padding: 0;
-
- &:focus {
- outline: none;
- }
- }
-
- .build-content {
- @include build-content();
- }
-
- .ci-job-dropdown-container:hover .build-content,
- a.build-content:hover,
- button.build-content:hover {
- background-color: var(--gray-100, $gray-100);
- border: 1px solid $dropdown-toggle-active-border-color;
- }
-
- // Connect first build in each stage with right horizontal line
- &:first-child {
- &::after {
- content: '';
- position: absolute;
- top: 48%;
- right: -48px;
- border-top: 2px solid var(--border-color, $border-color);
- width: 48px;
- height: 1px;
- }
- }
-
- // Connect each build (except for first) with curved lines
- &:not(:first-child) {
- &::after,
- &::before {
- content: '';
- top: -49px;
- position: absolute;
- border-bottom: 2px solid var(--border-color, $border-color);
- width: 25px;
- height: 69px;
- }
-
- // Right connecting curves
- &::after {
- right: -25px;
- border-right: 2px solid var(--border-color, $border-color);
- border-radius: 0 0 20px;
- }
-
- // Left connecting curves
- &::before {
- left: -25px;
- border-left: 2px solid var(--border-color, $border-color);
- border-radius: 0 0 0 20px;
- }
- }
-
- // Connect second build to first build with smaller curved line
- &:nth-child(2) {
- &::after,
- &::before {
- height: 29px;
- top: -9px;
- }
-
- .curve {
- display: block;
- }
- }
- }
-
- .ci-action-icon-container {
- position: absolute;
- right: 5px;
- top: 50%;
- transform: translateY(-50%);
-
- // Action Icons in big pipeline-graph nodes
- &.ci-action-icon-wrapper {
- height: 30px;
- width: 30px;
- border-radius: 100%;
- display: block;
- padding: 0;
- line-height: 0;
-
- svg {
- fill: var(--gray-500, $gray-500);
- }
-
- .gl-spinner {
- top: 2px;
- }
-
- &.play {
- svg {
- left: 1px;
- top: 1px;
- }
- }
- }
- }
-
- .stage-action svg {
- left: 1px;
- top: -2px;
- }
-}
-
-// Triggers the dropdown in the big pipeline graph
-.dropdown-counter-badge {
- font-weight: 100;
- font-size: 15px;
- position: absolute;
- right: 13px;
- top: 8px;
-}
-
.split-report-section {
border-bottom: 1px solid var(--gray-50, $gray-50);
@@ -480,34 +204,6 @@
left: 100%;
top: -10px;
box-shadow: 0 1px 5px $black-transparent;
-
- /**
- * Top arrow in the dropdown in the big pipeline graph
- */
- &::before,
- &::after {
- content: '';
- display: inline-block;
- position: absolute;
- width: 0;
- height: 0;
- border-color: transparent;
- border-style: solid;
- top: 18px;
- }
-
- &::before {
- left: -6px;
- margin-top: 3px;
- border-width: 7px 5px 7px 0;
- border-right-color: var(--border-color, $border-color);
- }
-
- &::after {
- left: -5px;
- border-width: 10px 7px 10px 0;
- border-right-color: var(--white, $white);
- }
}
.codequality-report {
diff --git a/app/assets/stylesheets/page_bundles/reports.scss b/app/assets/stylesheets/page_bundles/reports.scss
index ce91988cb8a..d0748779f47 100644
--- a/app/assets/stylesheets/page_bundles/reports.scss
+++ b/app/assets/stylesheets/page_bundles/reports.scss
@@ -49,11 +49,6 @@
display: flex;
}
-.is-dismissed .report-block-list-issue-description,
-.is-dismissed .vulnerability-name-button {
- text-decoration: line-through;
-}
-
.report-block-list-issue-description-text::after {
content: '\00a0';
}
diff --git a/app/assets/stylesheets/page_bundles/signup.scss b/app/assets/stylesheets/page_bundles/signup.scss
index d6c3a3ff5da..57e5d2411d1 100644
--- a/app/assets/stylesheets/page_bundles/signup.scss
+++ b/app/assets/stylesheets/page_bundles/signup.scss
@@ -39,36 +39,6 @@
}
}
-.signup-page[data-page^='registrations:experience_levels'] {
- $card-shadow-color: rgba(var(--black, $black), 0.2);
-
- .page-wrap {
- background-color: var(--white, $white);
- }
-
- .card-deck {
- max-width: 828px;
- }
-
- .card {
- transition: box-shadow 0.3s ease-in-out;
- }
-
- .card:hover {
- box-shadow: 0 $gl-spacing-scale-3 $gl-spacing-scale-5 $card-shadow-color;
- }
-
- @media (min-width: $breakpoint-sm) {
- .card-deck .card {
- margin: 0 $gl-spacing-scale-3;
- }
- }
-
- .stretched-link:hover {
- text-decoration: none;
- }
-}
-
.edit-profile {
max-width: 460px;
}
diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss
index 5173aeb824e..bc4dbf695cf 100644
--- a/app/assets/stylesheets/pages/commits.scss
+++ b/app/assets/stylesheets/pages/commits.scss
@@ -250,6 +250,10 @@
.commit-row-description {
display: none;
flex: 1;
+
+ a {
+ color: $blue-600;
+ }
}
&.inline-commit {
diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss
index ee97e8af296..94912b1c641 100644
--- a/app/assets/stylesheets/pages/issuable.scss
+++ b/app/assets/stylesheets/pages/issuable.scss
@@ -7,6 +7,7 @@
text-align: center;
margin-right: $issuable-warning-icon-margin;
line-height: $gl-line-height-24;
+ flex: 0 0 auto;
}
.limit-container-width {
@@ -121,7 +122,9 @@
.right-sidebar {
position: fixed;
top: $header-height;
- bottom: 0;
+ // Default value for CSS var must contain a unit
+ // stylelint-disable-next-line length-zero-no-unit
+ bottom: var(--review-bar-height, 0px);
right: 0;
transition: width $sidebar-transition-duration;
background: $gray-light;
diff --git a/app/assets/stylesheets/pages/login.scss b/app/assets/stylesheets/pages/login.scss
index b537a46a6f2..773935f4c76 100644
--- a/app/assets/stylesheets/pages/login.scss
+++ b/app/assets/stylesheets/pages/login.scss
@@ -96,15 +96,10 @@
}
form {
- width: 48%;
padding: 0;
border: 0;
background: none;
margin-bottom: $gl-padding;
-
- @include media-breakpoint-down(md) {
- width: 100%;
- }
}
.omniauth-btn {
diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss
index 34a03a07405..3c0f10eb5cb 100644
--- a/app/assets/stylesheets/pages/note_form.scss
+++ b/app/assets/stylesheets/pages/note_form.scss
@@ -37,7 +37,7 @@
.note-textarea {
display: block;
- padding: 10px 0;
+ padding: 10px 1px;
color: $gl-text-color;
font-family: $regular-font;
border: 0;
diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss
index b52a3c445b5..de9e0c6f705 100644
--- a/app/assets/stylesheets/pages/profile.scss
+++ b/app/assets/stylesheets/pages/profile.scss
@@ -70,14 +70,6 @@
}
}
-.profile-link-holder {
- display: inline;
-
- a:not(.text-link) {
- text-decoration: none;
- }
-}
-
// Middle dot divider between each element in a list of items.
.middle-dot-divider {
@include middle-dot-divider;
diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss
index 8f5de73365b..2e6c6a021f8 100644
--- a/app/assets/stylesheets/pages/search.scss
+++ b/app/assets/stylesheets/pages/search.scss
@@ -37,6 +37,25 @@ input[type='checkbox']:hover {
0 0 0 1px lighten($dropdown-input-focus-shadow, 20%);
}
+.header-search {
+ width: 320px;
+
+ input,
+ svg {
+ transition: border-color ease-in-out $default-transition-duration,
+ background-color ease-in-out $default-transition-duration;
+ }
+}
+
+.header-search-dropdown-menu {
+ max-height: $dropdown-max-height;
+ top: $header-height;
+}
+
+.header-search-dropdown-content {
+ max-height: $dropdown-max-height;
+}
+
.search {
margin: 0 8px;
diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss
index c6198315606..5765156f26c 100644
--- a/app/assets/stylesheets/pages/tree.scss
+++ b/app/assets/stylesheets/pages/tree.scss
@@ -102,7 +102,6 @@
.tree-table {
margin-bottom: 0;
- table-layout: fixed;
tr {
border-bottom: 1px solid $white-normal;
diff --git a/app/assets/stylesheets/startup/startup-dark.scss b/app/assets/stylesheets/startup/startup-dark.scss
index a90751f772e..b7958cdf4a3 100644
--- a/app/assets/stylesheets/startup/startup-dark.scss
+++ b/app/assets/stylesheets/startup/startup-dark.scss
@@ -11,6 +11,7 @@ body.gl-dark {
--green-700: #91d4a8;
--blue-400: #1f75cb;
--orange-400: #ab6100;
+ --purple-100: #2f2a6b;
--gl-text-color: #fafafa;
--border-color: #4f4f4f;
--black: #fff;
@@ -374,6 +375,38 @@ h1 {
.m-auto {
margin: auto !important;
}
+.gl-form-input,
+.gl-form-input.form-control {
+ background-color: #333;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
+ "Noto Sans", Ubuntu, Cantarell, "Helvetica Neue", sans-serif,
+ "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+ font-size: 0.875rem;
+ line-height: 1rem;
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+ padding-left: 0.75rem;
+ padding-right: 0.75rem;
+ height: auto;
+ color: #fafafa;
+ box-shadow: inset 0 0 0 1px #868686;
+ border-style: none;
+ appearance: none;
+ -moz-appearance: none;
+}
+.gl-form-input:disabled,
+.gl-form-input:not(.form-control-plaintext):not([type="color"]):read-only,
+.gl-form-input.form-control:disabled,
+.gl-form-input.form-control:not(.form-control-plaintext):not([type="color"]):read-only {
+ background-color: #1f1f1f;
+ color: #868686;
+ box-shadow: inset 0 0 0 1px #404040;
+ cursor: not-allowed;
+}
+.gl-form-input::placeholder,
+.gl-form-input.form-control::placeholder {
+ color: #868686;
+}
.gl-button {
display: inline-flex;
}
@@ -1237,7 +1270,7 @@ input {
.nav-sidebar-inner-scroll > div.context-header a .avatar-container {
font-weight: 400;
flex: none;
- box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08);
}
.nav-sidebar-inner-scroll > div.context-header a .avatar-container.rect-avatar {
border-style: none;
@@ -1247,7 +1280,7 @@ input {
a
.avatar-container.rect-avatar
.avatar.s32 {
- box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08);
}
.sidebar-top-level-items {
margin-top: 0.25rem;
@@ -1261,7 +1294,7 @@ input {
.sidebar-top-level-items .context-header a .avatar-container {
font-weight: 400;
flex: none;
- box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08);
}
.sidebar-top-level-items .context-header a .avatar-container.rect-avatar {
border-style: none;
@@ -1271,7 +1304,7 @@ input {
a
.avatar-container.rect-avatar
.avatar.s32 {
- box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08);
}
.sidebar-top-level-items > li .badge.badge-pill {
border-radius: 0.5rem;
@@ -1409,6 +1442,9 @@ svg.s12 {
svg.s16 {
vertical-align: -3px;
}
+.header-search {
+ width: 320px;
+}
.search {
margin: 0 8px;
}
@@ -1479,7 +1515,7 @@ svg.s16 {
float: left;
margin-right: 16px;
border-radius: 50%;
- border: 1px solid rgba(255, 255, 255, 0.08);
+ border: 1px solid rgba(0, 0, 0, 0.08);
}
.avatar.s16,
.avatar-container.s16 {
@@ -1524,7 +1560,7 @@ svg.s16 {
background-color: #660e00;
}
.identicon.bg2 {
- background-color: #f4f0ff;
+ background-color: #232150;
}
.identicon.bg3 {
background-color: #f1f1ff;
@@ -1635,6 +1671,22 @@ body.gl-dark
.notification-dot {
background-color: #fafafa;
}
+body.gl-dark .header-search {
+ background-color: rgba(250, 250, 250, 0.2) !important;
+}
+body.gl-dark .header-search svg {
+ color: rgba(250, 250, 250, 0.8) !important;
+}
+body.gl-dark .header-search input {
+ background-color: transparent;
+ color: rgba(250, 250, 250, 0.8);
+}
+body.gl-dark .header-search input::placeholder {
+ color: rgba(250, 250, 250, 0.8);
+}
+body.gl-dark .header-search input:active::placeholder {
+ color: #fafafa;
+}
body.gl-dark .search form {
background-color: rgba(250, 250, 250, 0.2);
}
@@ -1651,7 +1703,7 @@ body.gl-dark .nav-sidebar li.active > a {
body.gl-dark .nav-sidebar .fly-out-top-item a,
body.gl-dark .nav-sidebar .fly-out-top-item.active a,
body.gl-dark .nav-sidebar .fly-out-top-item .fly-out-top-item-container {
- background-color: #2f2a6b;
+ background-color: var(--purple-100, #e1d8f9);
color: var(--black, #333);
}
body.gl-dark .logo-text svg {
@@ -1668,6 +1720,14 @@ body.gl-dark .navbar-gitlab .navbar-nav li.active > button {
color: var(--gl-text-color);
background-color: var(--gray-200);
}
+body.gl-dark .navbar-gitlab .header-search {
+ background-color: var(--gray-100) !important;
+ box-shadow: inset 0 0 0 1px var(--border-color) !important;
+}
+body.gl-dark .navbar-gitlab .header-search:active {
+ background-color: var(--gray-100) !important;
+ box-shadow: inset 0 0 0 1px var(--blue-200) !important;
+}
body.gl-dark .navbar-gitlab .search form {
background-color: var(--gray-100);
box-shadow: inset 0 0 0 1px var(--border-color);
@@ -1746,6 +1806,17 @@ body.gl-dark {
--indigo-900: #ebebfa;
--indigo-950: #f7f7ff;
--indigo-900-alpha-008: rgba(235, 235, 250, 0.08);
+ --purple-50: #232150;
+ --purple-100: #2f2a6b;
+ --purple-200: #453894;
+ --purple-300: #5943b6;
+ --purple-400: #694cc0;
+ --purple-500: #7b58cf;
+ --purple-600: #9475db;
+ --purple-700: #ac93e6;
+ --purple-800: #cbbbf2;
+ --purple-900: #e1d8f9;
+ --purple-950: #f4f0ff;
--gl-text-color: #fafafa;
--border-color: #4f4f4f;
--white: #333;
diff --git a/app/assets/stylesheets/startup/startup-general.scss b/app/assets/stylesheets/startup/startup-general.scss
index 0b2d34b6f5d..2c79b819899 100644
--- a/app/assets/stylesheets/startup/startup-general.scss
+++ b/app/assets/stylesheets/startup/startup-general.scss
@@ -355,6 +355,38 @@ h1 {
.m-auto {
margin: auto !important;
}
+.gl-form-input,
+.gl-form-input.form-control {
+ background-color: #fff;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
+ "Noto Sans", Ubuntu, Cantarell, "Helvetica Neue", sans-serif,
+ "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+ font-size: 0.875rem;
+ line-height: 1rem;
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+ padding-left: 0.75rem;
+ padding-right: 0.75rem;
+ height: auto;
+ color: #303030;
+ box-shadow: inset 0 0 0 1px #868686;
+ border-style: none;
+ appearance: none;
+ -moz-appearance: none;
+}
+.gl-form-input:disabled,
+.gl-form-input:not(.form-control-plaintext):not([type="color"]):read-only,
+.gl-form-input.form-control:disabled,
+.gl-form-input.form-control:not(.form-control-plaintext):not([type="color"]):read-only {
+ background-color: #fafafa;
+ color: #868686;
+ box-shadow: inset 0 0 0 1px #dbdbdb;
+ cursor: not-allowed;
+}
+.gl-form-input::placeholder,
+.gl-form-input.form-control::placeholder {
+ color: #868686;
+}
.gl-button {
display: inline-flex;
}
@@ -1390,6 +1422,9 @@ svg.s12 {
svg.s16 {
vertical-align: -3px;
}
+.header-search {
+ width: 320px;
+}
.search {
margin: 0 8px;
}
diff --git a/app/assets/stylesheets/startup/startup-signin.scss b/app/assets/stylesheets/startup/startup-signin.scss
index 070ab36e0b3..013ad3fac87 100644
--- a/app/assets/stylesheets/startup/startup-signin.scss
+++ b/app/assets/stylesheets/startup/startup-signin.scss
@@ -315,9 +315,9 @@ fieldset:disabled a.btn {
-moz-appearance: none;
}
.gl-form-input:disabled,
-.gl-form-input:not(.form-control-plaintext):read-only,
+.gl-form-input:not(.form-control-plaintext):not([type="color"]):read-only,
.gl-form-input.form-control:disabled,
-.gl-form-input.form-control:not(.form-control-plaintext):read-only {
+.gl-form-input.form-control:not(.form-control-plaintext):not([type="color"]):read-only {
background-color: #fafafa;
color: #868686;
box-shadow: inset 0 0 0 1px #dbdbdb;
@@ -634,17 +634,11 @@ svg {
margin: 0;
}
.login-page .omniauth-container form {
- width: 48%;
padding: 0;
border: 0;
background: none;
margin-bottom: 16px;
}
-@media (max-width: 991.98px) {
- .login-page .omniauth-container form {
- width: 100%;
- }
-}
.login-page .omniauth-container .omniauth-btn {
width: 100%;
}
diff --git a/app/assets/stylesheets/themes/_dark.scss b/app/assets/stylesheets/themes/_dark.scss
index 8e1438eaf8a..f12b2ee2591 100644
--- a/app/assets/stylesheets/themes/_dark.scss
+++ b/app/assets/stylesheets/themes/_dark.scss
@@ -72,6 +72,18 @@ $indigo-900: #ebebfa;
$indigo-950: #f7f7ff;
$indigo-900-alpha-008: rgba($indigo-900, 0.08);
+$purple-50: #232150;
+$purple-100: #2f2a6b;
+$purple-200: #453894;
+$purple-300: #5943b6;
+$purple-400: #694cc0;
+$purple-500: #7b58cf;
+$purple-600: #9475db;
+$purple-700: #ac93e6;
+$purple-800: #cbbbf2;
+$purple-900: #e1d8f9;
+$purple-950: #f4f0ff;
+
$gray-lightest: #222;
$gray-light: $gray-50;
$gray-lighter: #303030;
@@ -163,6 +175,18 @@ body.gl-dark {
--indigo-950: #{$indigo-950};
--indigo-900-alpha-008: #{$indigo-900-alpha-008};
+ --purple-50: #{$purple-50};
+ --purple-100: #{$purple-100};
+ --purple-200: #{$purple-200};
+ --purple-300: #{$purple-300};
+ --purple-400: #{$purple-400};
+ --purple-500: #{$purple-500};
+ --purple-600: #{$purple-600};
+ --purple-700: #{$purple-700};
+ --purple-800: #{$purple-800};
+ --purple-900: #{$purple-900};
+ --purple-950: #{$purple-950};
+
--gl-text-color: #{$gray-900};
--border-color: #{$border-color};
@@ -252,6 +276,10 @@ $well-inner-border: $gray-200;
color: $gray-900;
}
+.gl-label-text-dark.gl-label-text-dark {
+ color: $gray-10;
+}
+
// This applies to "gl-labels" from "gitlab-ui"
.gl-label.gl-label-scoped.gl-label-text-dark,
.gl-label.gl-label-scoped.gl-label-text-light {
diff --git a/app/assets/stylesheets/themes/theme_helper.scss b/app/assets/stylesheets/themes/theme_helper.scss
index a94169ab494..a9e8b238d78 100644
--- a/app/assets/stylesheets/themes/theme_helper.scss
+++ b/app/assets/stylesheets/themes/theme_helper.scss
@@ -140,6 +140,34 @@
}
}
+ .header-search {
+ background-color: rgba($search-and-nav-links, 0.2) !important;
+
+ &:hover {
+ background-color: rgba($search-and-nav-links, 0.3) !important;
+ }
+
+ svg {
+ color: rgba($search-and-nav-links, 0.8) !important;
+ }
+
+ input {
+ background-color: transparent;
+ color: rgba($search-and-nav-links, 0.8);
+
+ &::placeholder {
+ color: rgba($search-and-nav-links, 0.8);
+ }
+
+ &:focus,
+ &:active {
+ &::placeholder {
+ color: $search-and-nav-links;
+ }
+ }
+ }
+ }
+
.search {
form {
background-color: rgba($search-and-nav-links, 0.2);
@@ -184,7 +212,7 @@
a:hover,
&.active a,
.fly-out-top-item-container {
- background-color: $purple-900;
+ background-color: var(--purple-100, $purple-900);
color: var(--black, $white);
}
}
diff --git a/app/assets/stylesheets/themes/theme_light.scss b/app/assets/stylesheets/themes/theme_light.scss
index b41377475c5..4c3bc1b2298 100644
--- a/app/assets/stylesheets/themes/theme_light.scss
+++ b/app/assets/stylesheets/themes/theme_light.scss
@@ -45,6 +45,16 @@ body {
}
}
+ .header-search {
+ background-color: $white !important;
+ box-shadow: inset 0 0 0 1px $border-color !important;
+
+ &:hover {
+ background-color: $white !important;
+ box-shadow: inset 0 0 0 1px $blue-200 !important;
+ }
+ }
+
.search {
form {
background-color: $white;
diff --git a/app/assets/stylesheets/utilities.scss b/app/assets/stylesheets/utilities.scss
index ccad503c1ed..ec70926b418 100644
--- a/app/assets/stylesheets/utilities.scss
+++ b/app/assets/stylesheets/utilities.scss
@@ -245,11 +245,16 @@ $gl-line-height-42: px-to-rem(42px);
width: $grid-size * 28;
}
-// Will be moved to @gitlab/ui by https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1491
+// Will be removed after https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/2347 is merged
.gl-min-w-8 {
min-width: $gl-spacing-scale-8;
}
+// Will be removed after https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/2347 is merged
+.gl-min-w-10 {
+ min-width: $gl-spacing-scale-10;
+}
+
// Will both be moved to @gitlab/ui by https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1526
.gl-opacity-6 {
opacity: 0.6;
@@ -258,3 +263,21 @@ $gl-line-height-42: px-to-rem(42px);
.gl-opacity-7 {
opacity: 0.7;
}
+
+/**
+ Note: ::-webkit-scrollbar is a non-standard rule only
+ supported by webkit browsers.
+
+ It is added here to migrate components that use
+ scrolling-links() mixin from `app/assets/stylesheets/framework/mixins.scss`.
+
+ It should not be used elsewhere: it may impact accessibility as well as
+ add browser compatibility issues.
+
+ See: https://developer.mozilla.org/en-US/docs/Web/CSS/::-webkit-scrollbar
+**/
+.gl-webkit-scrollbar-display-none {
+ &::-webkit-scrollbar {
+ display: none;
+ }
+}
diff --git a/app/controllers/admin/applications_controller.rb b/app/controllers/admin/applications_controller.rb
index 449aa90b0e6..ce7d64336c8 100644
--- a/app/controllers/admin/applications_controller.rb
+++ b/app/controllers/admin/applications_controller.rb
@@ -18,7 +18,10 @@ class Admin::ApplicationsController < Admin::ApplicationController
end
def new
- @application = Doorkeeper::Application.new
+ # Default access tokens to expire. This preserves backward compatibility
+ # with existing applications. This will be removed in 15.0.
+ # Removal issue: https://gitlab.com/gitlab-org/gitlab/-/issues/340848
+ @application = Doorkeeper::Application.new(expire_access_tokens: true)
end
def edit
@@ -55,10 +58,13 @@ class Admin::ApplicationsController < Admin::ApplicationController
@application = ApplicationsFinder.new(id: params[:id]).execute
end
- # Only allow a trusted parameter "white list" through.
+ def permitted_params
+ super << :trusted
+ end
+
def application_params
- params
- .require(:doorkeeper_application)
- .permit(:name, :redirect_uri, :trusted, :scopes, :confidential)
+ super.tap do |params|
+ params[:owner] = nil
+ end
end
end
diff --git a/app/controllers/admin/background_migrations_controller.rb b/app/controllers/admin/background_migrations_controller.rb
index 65b47308e4c..e21e6fd2dcb 100644
--- a/app/controllers/admin/background_migrations_controller.rb
+++ b/app/controllers/admin/background_migrations_controller.rb
@@ -29,9 +29,16 @@ class Admin::BackgroundMigrationsController < Admin::ApplicationController
redirect_back fallback_location: { action: 'index' }
end
+ def retry
+ migration = batched_migration_class.find(params[:id])
+ migration.retry_failed_jobs! if migration.failed?
+
+ redirect_back fallback_location: { action: 'index' }
+ end
+
private
def batched_migration_class
- Gitlab::Database::BackgroundMigration::BatchedMigration
+ @batched_migration_class ||= Gitlab::Database::BackgroundMigration::BatchedMigration
end
end
diff --git a/app/controllers/admin/runner_projects_controller.rb b/app/controllers/admin/runner_projects_controller.rb
index 3b408de5f01..fdf681de9ef 100644
--- a/app/controllers/admin/runner_projects_controller.rb
+++ b/app/controllers/admin/runner_projects_controller.rb
@@ -9,7 +9,7 @@ class Admin::RunnerProjectsController < Admin::ApplicationController
@runner = Ci::Runner.find(params[:runner_project][:runner_id])
if @runner.assign_to(@project, current_user)
- redirect_to admin_runner_path(@runner)
+ redirect_to admin_runner_path(@runner), notice: s_('Runners|Runner assigned to project.')
else
redirect_to admin_runner_path(@runner), alert: 'Failed adding runner to project'
end
@@ -20,7 +20,7 @@ class Admin::RunnerProjectsController < Admin::ApplicationController
runner = rp.runner
rp.destroy
- redirect_to admin_runner_path(runner), status: :found
+ redirect_to admin_runner_path(runner), status: :found, notice: s_('Runners|Runner unassigned from project.')
end
private
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 3801906635f..9c556d16913 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -307,7 +307,7 @@ class Admin::UsersController < Admin::ApplicationController
end
def user
- @user ||= find_routable!(User, params[:id], request.path_info)
+ @user ||= find_routable!(User, params[:id], request.fullpath)
end
def build_canonical_path(user)
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 34bad74a9fc..a83458f3260 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -42,6 +42,7 @@ class ApplicationController < ActionController::Base
# Make sure the `auth_user` is memoized so it can be logged, we do this after
# all other before filters that could have set the user.
before_action :auth_user
+ before_action :limit_session_time, if: -> { !current_user }
prepend_around_action :set_current_context
@@ -51,7 +52,7 @@ class ApplicationController < ActionController::Base
around_action :set_current_admin
after_action :set_page_title_header, if: :json_request?
- after_action :limit_session_time, if: -> { !current_user }
+ after_action :ensure_authenticated_session_time, if: -> { current_user }
protect_from_forgery with: :exception, prepend: true
@@ -62,7 +63,8 @@ class ApplicationController < ActionController::Base
:bitbucket_import_enabled?, :bitbucket_import_configured?,
:bitbucket_server_import_enabled?, :fogbugz_import_enabled?,
:git_import_enabled?, :gitlab_project_import_enabled?,
- :manifest_import_enabled?, :phabricator_import_enabled?
+ :manifest_import_enabled?, :phabricator_import_enabled?,
+ :masked_page_url
# Adds `no-store` to the DEFAULT_CACHE_CONTROL, to prevent security
# concerns due to caching private data.
diff --git a/app/controllers/boards/issues_controller.rb b/app/controllers/boards/issues_controller.rb
index f0f074792ed..7dea6191fa4 100644
--- a/app/controllers/boards/issues_controller.rb
+++ b/app/controllers/boards/issues_controller.rb
@@ -27,9 +27,7 @@ module Boards
list_service = Boards::Issues::ListService.new(board_parent, current_user, filter_params)
issues = issues_from(list_service)
- if Gitlab::Database.read_write? && !board.disabled_for?(current_user)
- Issue.move_nulls_to_end(issues)
- end
+ ::Boards::Issues::ListService.initialize_relative_positions(board, current_user, issues)
render_issues(issues, list_service.metadata)
end
diff --git a/app/controllers/concerns/integrations/params.rb b/app/controllers/concerns/integrations/params.rb
index 10122b4c77b..62585ab95af 100644
--- a/app/controllers/concerns/integrations/params.rb
+++ b/app/controllers/concerns/integrations/params.rb
@@ -77,18 +77,15 @@ module Integrations
:webhook
].freeze
- # Parameters to ignore if no value is specified
- FILTER_BLANK_PARAMS = [:password].freeze
-
def integration_params
- dynamic_params = @integration.event_channel_names + @integration.event_names # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ dynamic_params = integration.event_channel_names + integration.event_names
allowed = allowed_integration_params + dynamic_params
return_value = params.permit(:id, integration: allowed, service: allowed)
return_value[:integration] ||= return_value.delete(:service)
param_values = return_value[:integration]
if param_values.is_a?(ActionController::Parameters)
- FILTER_BLANK_PARAMS.each do |param|
+ integration.password_fields.each do |param|
param_values.delete(param) if param_values[param].blank?
end
end
diff --git a/app/controllers/concerns/issuable_collections.rb b/app/controllers/concerns/issuable_collections.rb
index d2d2e656af8..4841225de08 100644
--- a/app/controllers/concerns/issuable_collections.rb
+++ b/app/controllers/concerns/issuable_collections.rb
@@ -13,8 +13,16 @@ module IssuableCollections
private
+ def show_alert_if_search_is_disabled
+ return if current_user || params[:search].blank? || !html_request? || Feature.disabled?(:disable_anonymous_search, type: :ops)
+
+ flash.now[:notice] = _('You must sign in to search for specific terms.')
+ end
+
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def set_issuables_index
+ show_alert_if_search_is_disabled
+
@issuables = issuables_collection
unless pagination_disabled?
diff --git a/app/controllers/concerns/issuable_collections_action.rb b/app/controllers/concerns/issuable_collections_action.rb
index ca2979a5a29..b68db0e3f9f 100644
--- a/app/controllers/concerns/issuable_collections_action.rb
+++ b/app/controllers/concerns/issuable_collections_action.rb
@@ -7,6 +7,8 @@ module IssuableCollectionsAction
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def issues
+ show_alert_if_search_is_disabled
+
@issues = issuables_collection
.non_archived
.page(params[:page])
@@ -20,6 +22,8 @@ module IssuableCollectionsAction
end
def merge_requests
+ show_alert_if_search_is_disabled
+
@merge_requests = issuables_collection.page(params[:page])
@issuable_meta_data = Gitlab::IssuableMetadata.new(current_user, @merge_requests).data
diff --git a/app/controllers/concerns/oauth_applications.rb b/app/controllers/concerns/oauth_applications.rb
index d97e22df472..d2c746db12d 100644
--- a/app/controllers/concerns/oauth_applications.rb
+++ b/app/controllers/concerns/oauth_applications.rb
@@ -18,4 +18,14 @@ module OauthApplications
def load_scopes
@scopes ||= Doorkeeper.configuration.scopes
end
+
+ def permitted_params
+ %i{name redirect_uri scopes confidential expire_access_tokens}
+ end
+
+ def application_params
+ params
+ .require(:doorkeeper_application)
+ .permit(*permitted_params)
+ end
end
diff --git a/app/controllers/concerns/project_unauthorized.rb b/app/controllers/concerns/project_unauthorized.rb
index b58f6589f9b..563d6b6273b 100644
--- a/app/controllers/concerns/project_unauthorized.rb
+++ b/app/controllers/concerns/project_unauthorized.rb
@@ -3,7 +3,7 @@
module ProjectUnauthorized
module ControllerActions
def self.on_routable_not_found
- lambda do |routable, path_info|
+ lambda do |routable, full_path|
return unless routable.is_a?(Project)
label = routable.external_authorization_classification_label
diff --git a/app/controllers/concerns/renders_projects_list.rb b/app/controllers/concerns/renders_projects_list.rb
index be45c676ad6..05bd9972ee7 100644
--- a/app/controllers/concerns/renders_projects_list.rb
+++ b/app/controllers/concerns/renders_projects_list.rb
@@ -4,9 +4,10 @@ module RendersProjectsList
def prepare_projects_for_rendering(projects)
preload_max_member_access_for_collection(Project, projects)
- # Call the forks count method on every project, so the BatchLoader would load them all at
+ # Call the count methods on every project, so the BatchLoader would load them all at
# once when the entities are rendered
projects.each(&:forks_count)
+ projects.each(&:open_issues_count)
projects
end
diff --git a/app/controllers/concerns/routable_actions.rb b/app/controllers/concerns/routable_actions.rb
index 57108369c64..e34d6b09c24 100644
--- a/app/controllers/concerns/routable_actions.rb
+++ b/app/controllers/concerns/routable_actions.rb
@@ -3,13 +3,13 @@
module RoutableActions
extend ActiveSupport::Concern
- def find_routable!(routable_klass, routable_full_path, path_info, extra_authorization_proc: nil)
+ def find_routable!(routable_klass, routable_full_path, full_path, extra_authorization_proc: nil)
routable = routable_klass.find_by_full_path(routable_full_path, follow_redirects: request.get?)
if routable_authorized?(routable, extra_authorization_proc)
ensure_canonical_path(routable, routable_full_path)
routable
else
- perform_not_found_actions(routable, not_found_actions, path_info)
+ perform_not_found_actions(routable, not_found_actions, full_path)
route_not_found unless performed?
@@ -21,11 +21,11 @@ module RoutableActions
[ProjectUnauthorized::ControllerActions.on_routable_not_found]
end
- def perform_not_found_actions(routable, actions, path_info)
+ def perform_not_found_actions(routable, actions, full_path)
actions.each do |action|
break if performed?
- instance_exec(routable, path_info, &action)
+ instance_exec(routable, full_path, &action)
end
end
diff --git a/app/controllers/concerns/sessionless_authentication.rb b/app/controllers/concerns/sessionless_authentication.rb
index 3c8a683439a..58e65ba20e2 100644
--- a/app/controllers/concerns/sessionless_authentication.rb
+++ b/app/controllers/concerns/sessionless_authentication.rb
@@ -8,7 +8,6 @@ module SessionlessAuthentication
# This filter handles personal access tokens, atom requests with rss tokens, and static object tokens
def authenticate_sessionless_user!(request_format)
user = request_authenticator.find_sessionless_user(request_format)
-
sessionless_sign_in(user) if user
end
diff --git a/app/controllers/dashboard/projects_controller.rb b/app/controllers/dashboard/projects_controller.rb
index d861ef646f8..74ad78ff4c1 100644
--- a/app/controllers/dashboard/projects_controller.rb
+++ b/app/controllers/dashboard/projects_controller.rb
@@ -36,7 +36,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController
# rubocop: disable CodeReuse/ActiveRecord
def starred
@projects = load_projects(params.merge(starred: true))
- .includes(:forked_from_project, :topics)
+ .includes(:forked_from_project, :topics, :topics_acts_as_taggable)
@groups = []
diff --git a/app/controllers/explore/projects_controller.rb b/app/controllers/explore/projects_controller.rb
index e0973b0f3b4..3dc6a16cbc1 100644
--- a/app/controllers/explore/projects_controller.rb
+++ b/app/controllers/explore/projects_controller.rb
@@ -26,6 +26,7 @@ class Explore::ProjectsController < Explore::ApplicationController
feature_category :projects
def index
+ show_alert_if_search_is_disabled
@projects = load_projects
respond_to do |format|
@@ -120,6 +121,12 @@ class Explore::ProjectsController < Explore::ApplicationController
end
end
end
+
+ def show_alert_if_search_is_disabled
+ return if current_user || params[:name].blank? && params[:search].blank? || !html_request? || Feature.disabled?(:disable_anonymous_project_search, type: :ops)
+
+ flash.now[:notice] = _('You must sign in to search for specific projects.')
+ end
end
Explore::ProjectsController.prepend_mod_with('Explore::ProjectsController')
diff --git a/app/controllers/groups/application_controller.rb b/app/controllers/groups/application_controller.rb
index aa0d49902c3..ab67a007bd9 100644
--- a/app/controllers/groups/application_controller.rb
+++ b/app/controllers/groups/application_controller.rb
@@ -16,7 +16,7 @@ class Groups::ApplicationController < ApplicationController
private
def group
- @group ||= find_routable!(Group, params[:group_id] || params[:id], request.path_info)
+ @group ||= find_routable!(Group, params[:group_id] || params[:id], request.fullpath)
end
def group_projects
diff --git a/app/controllers/groups/boards_controller.rb b/app/controllers/groups/boards_controller.rb
index 96a3b38669d..60708c13b85 100644
--- a/app/controllers/groups/boards_controller.rb
+++ b/app/controllers/groups/boards_controller.rb
@@ -7,7 +7,6 @@ class Groups::BoardsController < Groups::ApplicationController
before_action :assign_endpoint_vars
before_action do
- push_frontend_feature_flag(:graphql_board_lists, group, default_enabled: :yaml)
push_frontend_feature_flag(:issue_boards_filtered_search, group, default_enabled: :yaml)
push_frontend_feature_flag(:board_multi_select, group, default_enabled: :yaml)
push_frontend_feature_flag(:swimlanes_buffered_rendering, group, default_enabled: :yaml)
diff --git a/app/controllers/groups/clusters/integrations_controller.rb b/app/controllers/groups/clusters/integrations_controller.rb
index 61b308f7d1b..4ab8c021ee2 100644
--- a/app/controllers/groups/clusters/integrations_controller.rb
+++ b/app/controllers/groups/clusters/integrations_controller.rb
@@ -13,6 +13,6 @@ class Groups::Clusters::IntegrationsController < Clusters::IntegrationsControlle
end
def group
- @group ||= find_routable!(Group, params[:group_id] || params[:id], request.path_info)
+ @group ||= find_routable!(Group, params[:group_id] || params[:id], request.fullpath)
end
end
diff --git a/app/controllers/groups/clusters_controller.rb b/app/controllers/groups/clusters_controller.rb
index 6f3eecf8296..666a96d6fc0 100644
--- a/app/controllers/groups/clusters_controller.rb
+++ b/app/controllers/groups/clusters_controller.rb
@@ -15,7 +15,7 @@ class Groups::ClustersController < Clusters::ClustersController
end
def group
- @group ||= find_routable!(Group, params[:group_id] || params[:id], request.path_info)
+ @group ||= find_routable!(Group, params[:group_id] || params[:id], request.fullpath)
end
def metrics_dashboard_params
diff --git a/app/controllers/groups/runners_controller.rb b/app/controllers/groups/runners_controller.rb
index dbbfdd76fe8..f37c08da22a 100644
--- a/app/controllers/groups/runners_controller.rb
+++ b/app/controllers/groups/runners_controller.rb
@@ -10,6 +10,8 @@ class Groups::RunnersController < Groups::ApplicationController
feature_category :runner
def index
+ finder = Ci::RunnersFinder.new(current_user: current_user, params: { group: @group })
+ @group_runners_limited_count = finder.execute.except(:limit, :offset).page.total_count_with_limit(:all, limit: 1000)
end
def runner_list_group_view_vue_ui_enabled
@@ -59,7 +61,7 @@ class Groups::RunnersController < Groups::ApplicationController
private
def runner
- @runner ||= Ci::RunnersFinder.new(current_user: current_user, group: @group, params: {}).execute
+ @runner ||= Ci::RunnersFinder.new(current_user: current_user, params: { group: @group }).execute
.except(:limit, :offset)
.find(params[:id])
end
diff --git a/app/controllers/groups/settings/applications_controller.rb b/app/controllers/groups/settings/applications_controller.rb
index cefb5425867..f05a96d7810 100644
--- a/app/controllers/groups/settings/applications_controller.rb
+++ b/app/controllers/groups/settings/applications_controller.rb
@@ -54,8 +54,10 @@ module Groups
# https://gitlab.com/gitlab-org/gitlab/-/issues/324187
@applications = @group.oauth_applications.limit(100)
- # Don't overwrite a value possibly set by `create`
- @application ||= Doorkeeper::Application.new
+ # Default access tokens to expire. This preserves backward compatibility
+ # with existing applications. This will be removed in 15.0.
+ # Removal issue: https://gitlab.com/gitlab-org/gitlab/-/issues/340848
+ @application ||= Doorkeeper::Application.new(expire_access_tokens: true)
end
def set_application
@@ -63,12 +65,9 @@ module Groups
end
def application_params
- params
- .require(:doorkeeper_application)
- .permit(:name, :redirect_uri, :scopes, :confidential)
- .tap do |params|
- params[:owner] = @group
- end
+ super.tap do |params|
+ params[:owner] = @group
+ end
end
end
end
diff --git a/app/controllers/groups/settings/ci_cd_controller.rb b/app/controllers/groups/settings/ci_cd_controller.rb
index 0f40c9bfd2c..a290ef9b5e7 100644
--- a/app/controllers/groups/settings/ci_cd_controller.rb
+++ b/app/controllers/groups/settings/ci_cd_controller.rb
@@ -17,7 +17,7 @@ module Groups
NUMBER_OF_RUNNERS_PER_PAGE = 4
def show
- runners_finder = Ci::RunnersFinder.new(current_user: current_user, group: @group, params: params)
+ runners_finder = Ci::RunnersFinder.new(current_user: current_user, params: params.merge({ group: @group }))
# We need all runners for count
@all_group_runners = runners_finder.execute.except(:limit, :offset)
@group_runners = runners_finder.execute.page(params[:page]).per(NUMBER_OF_RUNNERS_PER_PAGE)
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 2796760fbe1..a419171039e 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -33,6 +33,7 @@ class GroupsController < Groups::ApplicationController
before_action do
push_frontend_feature_flag(:vue_issuables_list, @group)
+ push_frontend_feature_flag(:vue_issues_list, @group, default_enabled: :yaml)
push_frontend_feature_flag(:iteration_cadences, @group, default_enabled: :yaml)
end
@@ -64,6 +65,7 @@ class GroupsController < Groups::ApplicationController
def new
@group = Group.new(params.permit(:parent_id))
+ @group.build_namespace_settings
end
def create
@@ -269,7 +271,9 @@ class GroupsController < Groups::ApplicationController
:default_branch_name,
:allow_mfa_for_subgroups,
:resource_access_token_creation_allowed,
- :prevent_sharing_groups_outside_hierarchy
+ :prevent_sharing_groups_outside_hierarchy,
+ :setup_for_company,
+ :jobs_to_be_done
]
end
@@ -342,7 +346,15 @@ class GroupsController < Groups::ApplicationController
render action: 'new'
end
- def successful_creation_hooks; end
+ def successful_creation_hooks
+ update_user_role_and_setup_for_company
+ end
+
+ def update_user_role_and_setup_for_company
+ user_params = params.fetch(:user, {}).permit(:role)
+ user_params[:setup_for_company] = @group.setup_for_company if !@group.setup_for_company.nil? && current_user.setup_for_company.nil?
+ Users::UpdateService.new(current_user, user_params.merge(user: current_user)).execute if user_params.present?
+ end
def groups
if @group.supports_events?
diff --git a/app/controllers/import/bitbucket_controller.rb b/app/controllers/import/bitbucket_controller.rb
index 57bd39bbe06..d32755dbd94 100644
--- a/app/controllers/import/bitbucket_controller.rb
+++ b/app/controllers/import/bitbucket_controller.rb
@@ -62,14 +62,10 @@ class Import::BitbucketController < Import::BaseController
protected
- # rubocop: disable CodeReuse/ActiveRecord
override :importable_repos
def importable_repos
- already_added_projects_names = already_added_projects.map(&:import_source)
-
- bitbucket_repos.reject { |repo| already_added_projects_names.include?(repo.full_name) || !repo.valid? }
+ bitbucket_repos.filter { |repo| repo.valid? }
end
- # rubocop: enable CodeReuse/ActiveRecord
override :incompatible_repos
def incompatible_repos
diff --git a/app/controllers/import/bitbucket_server_controller.rb b/app/controllers/import/bitbucket_server_controller.rb
index 1846b1e0cec..31e9694ca1d 100644
--- a/app/controllers/import/bitbucket_server_controller.rb
+++ b/app/controllers/import/bitbucket_server_controller.rb
@@ -62,16 +62,10 @@ class Import::BitbucketServerController < Import::BaseController
protected
- # rubocop: disable CodeReuse/ActiveRecord
override :importable_repos
def importable_repos
- # Use the import URL to filter beyond what BaseService#find_already_added_projects
- already_added_projects = filter_added_projects('bitbucket_server', bitbucket_repos.map(&:browse_url))
- already_added_projects_names = already_added_projects.map(&:import_source)
-
- bitbucket_repos.reject { |repo| already_added_projects_names.include?(repo.browse_url) || !repo.valid? }
+ bitbucket_repos.filter { |repo| repo.valid? }
end
- # rubocop: enable CodeReuse/ActiveRecord
override :incompatible_repos
def incompatible_repos
@@ -90,12 +84,6 @@ class Import::BitbucketServerController < Import::BaseController
private
- # rubocop: disable CodeReuse/ActiveRecord
- def filter_added_projects(import_type, import_sources)
- current_user.created_projects.where(import_type: import_type, import_source: import_sources).with_import_state
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
def client
@client ||= BitbucketServer::Client.new(credentials)
end
diff --git a/app/controllers/import/bulk_imports_controller.rb b/app/controllers/import/bulk_imports_controller.rb
index e99b8cfa0c7..da936215ad4 100644
--- a/app/controllers/import/bulk_imports_controller.rb
+++ b/app/controllers/import/bulk_imports_controller.rb
@@ -112,7 +112,7 @@ class Import::BulkImportsController < ApplicationController
end
def ensure_group_import_enabled
- render_404 unless Feature.enabled?(:bulk_import)
+ render_404 unless Feature.enabled?(:bulk_import, default_enabled: :yaml)
end
def access_token_key
diff --git a/app/controllers/import/fogbugz_controller.rb b/app/controllers/import/fogbugz_controller.rb
index 9f91f3a1e1c..377292d47d8 100644
--- a/app/controllers/import/fogbugz_controller.rb
+++ b/app/controllers/import/fogbugz_controller.rb
@@ -74,16 +74,10 @@ class Import::FogbugzController < Import::BaseController
protected
- # rubocop: disable CodeReuse/ActiveRecord
override :importable_repos
def importable_repos
- repos = client.repos
-
- already_added_projects_names = already_added_projects.map(&:import_source)
-
- repos.reject { |repo| already_added_projects_names.include? repo.name }
+ client.repos
end
- # rubocop: enable CodeReuse/ActiveRecord
override :incompatible_repos
def incompatible_repos
diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb
index 22bcd14d664..d7aebd25432 100644
--- a/app/controllers/import/github_controller.rb
+++ b/app/controllers/import/github_controller.rb
@@ -64,9 +64,7 @@ class Import::GithubController < Import::BaseController
# rubocop: disable CodeReuse/ActiveRecord
override :importable_repos
def importable_repos
- already_added_projects_names = already_added_projects.pluck(:import_source)
-
- client_repos.reject { |repo| already_added_projects_names.include?(repo.full_name) }
+ client_repos.to_a
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/controllers/import/gitlab_controller.rb b/app/controllers/import/gitlab_controller.rb
index cc68eb02741..662b02010ba 100644
--- a/app/controllers/import/gitlab_controller.rb
+++ b/app/controllers/import/gitlab_controller.rb
@@ -39,16 +39,10 @@ class Import::GitlabController < Import::BaseController
protected
- # rubocop: disable CodeReuse/ActiveRecord
override :importable_repos
def importable_repos
- repos = client.projects(starting_page: 1, page_limit: MAX_PROJECT_PAGES, per_page: PER_PAGE_PROJECTS)
-
- already_added_projects_names = already_added_projects.map(&:import_source)
-
- repos.reject { |repo| already_added_projects_names.include? repo["path_with_namespace"] }
+ client.projects(starting_page: 1, page_limit: MAX_PROJECT_PAGES, per_page: PER_PAGE_PROJECTS)
end
- # rubocop: enable CodeReuse/ActiveRecord
override :incompatible_repos
def incompatible_repos
diff --git a/app/controllers/import/manifest_controller.rb b/app/controllers/import/manifest_controller.rb
index 8497e15c07c..956d0c9a2ae 100644
--- a/app/controllers/import/manifest_controller.rb
+++ b/app/controllers/import/manifest_controller.rb
@@ -41,7 +41,7 @@ class Import::ManifestController < Import::BaseController
end
def create
- repository = repositories.find do |project|
+ repository = importable_repos.find do |project|
project[:id] == params[:repo_id].to_i
end
@@ -56,14 +56,10 @@ class Import::ManifestController < Import::BaseController
protected
- # rubocop: disable CodeReuse/ActiveRecord
override :importable_repos
def importable_repos
- already_added_projects_names = already_added_projects.pluck(:import_url)
-
- repositories.reject { |repo| already_added_projects_names.include?(repo[:url]) }
+ @importable_repos ||= manifest_import_metadata.repositories
end
- # rubocop: enable CodeReuse/ActiveRecord
override :incompatible_repos
def incompatible_repos
@@ -88,7 +84,7 @@ class Import::ManifestController < Import::BaseController
private
def ensure_import_vars
- unless group && repositories.present?
+ unless group && importable_repos.present?
redirect_to(new_import_manifest_path)
end
end
@@ -103,10 +99,6 @@ class Import::ManifestController < Import::BaseController
@manifest_import_status ||= Gitlab::ManifestImport::Metadata.new(current_user, fallback: session)
end
- def repositories
- @repositories ||= manifest_import_metadata.repositories
- end
-
def find_jobs
find_already_added_projects.to_json(only: [:id], methods: [:import_status])
end
diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb
index 7f5750d2011..4242f918ea0 100644
--- a/app/controllers/invites_controller.rb
+++ b/app/controllers/invites_controller.rb
@@ -77,7 +77,12 @@ class InvitesController < ApplicationController
def track_invite_join_click
return unless member && initial_invite_email?
- experiment(:invite_email_preview_text, actor: member).track(:join_clicked) if params[:experiment_name] == 'invite_email_preview_text'
+ if params[:experiment_name] == 'invite_email_preview_text'
+ experiment(:invite_email_preview_text, actor: member).track(:join_clicked)
+ elsif params[:experiment_name] == 'invite_email_from'
+ experiment(:invite_email_from, actor: member).track(:join_clicked)
+ end
+
Gitlab::Tracking.event(self.class.name, 'join_clicked', label: 'invite_email', property: member.id.to_s)
end
diff --git a/app/controllers/jira_connect/installations_controller.rb b/app/controllers/jira_connect/installations_controller.rb
new file mode 100644
index 00000000000..401bc4f9c87
--- /dev/null
+++ b/app/controllers/jira_connect/installations_controller.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+class JiraConnect::InstallationsController < JiraConnect::ApplicationController
+ def index
+ render json: installation_json(current_jira_installation)
+ end
+
+ def update
+ if current_jira_installation.update(installation_params)
+ render json: installation_json(current_jira_installation)
+ else
+ render(
+ json: { errors: current_jira_installation.errors },
+ status: :unprocessable_entity
+ )
+ end
+ end
+
+ private
+
+ def installation_json(installation)
+ {
+ gitlab_com: installation.instance_url.blank?,
+ instance_url: installation.instance_url
+ }
+ end
+
+ def installation_params
+ params.require(:installation).permit(:instance_url)
+ end
+end
diff --git a/app/controllers/members/mailgun/permanent_failures_controller.rb b/app/controllers/members/mailgun/permanent_failures_controller.rb
new file mode 100644
index 00000000000..685faa34694
--- /dev/null
+++ b/app/controllers/members/mailgun/permanent_failures_controller.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+module Members
+ module Mailgun
+ class PermanentFailuresController < ApplicationController
+ respond_to :json
+
+ skip_before_action :authenticate_user!
+ skip_before_action :verify_authenticity_token
+
+ before_action :ensure_feature_enabled!
+ before_action :authenticate_signature!
+ before_action :validate_invite_email!
+
+ feature_category :authentication_and_authorization
+
+ def create
+ webhook_processor.execute
+
+ head :ok
+ end
+
+ private
+
+ def ensure_feature_enabled!
+ render_406 unless Gitlab::CurrentSettings.mailgun_events_enabled?
+ end
+
+ def authenticate_signature!
+ access_denied! unless valid_signature?
+ end
+
+ def valid_signature?
+ return false if Gitlab::CurrentSettings.mailgun_signing_key.blank?
+
+ # per this guide: https://documentation.mailgun.com/en/latest/user_manual.html#webhooks
+ digest = OpenSSL::Digest.new('SHA256')
+ data = [params.dig(:signature, :timestamp), params.dig(:signature, :token)].join
+
+ hmac_digest = OpenSSL::HMAC.hexdigest(digest, Gitlab::CurrentSettings.mailgun_signing_key, data)
+
+ ActiveSupport::SecurityUtils.secure_compare(params.dig(:signature, :signature), hmac_digest)
+ end
+
+ def validate_invite_email!
+ # permanent_failures webhook does not provide a way to filter failures, so we'll get them all on this endpoint
+ # and we only care about our invite_emails
+ render_406 unless payload[:tags]&.include?(::Members::Mailgun::INVITE_EMAIL_TAG)
+ end
+
+ def webhook_processor
+ ::Members::Mailgun::ProcessWebhookService.new(payload)
+ end
+
+ def payload
+ @payload ||= params.permit!['event-data']
+ end
+
+ def render_406
+ # failure to stop retries per https://documentation.mailgun.com/en/latest/user_manual.html#webhooks
+ head :not_acceptable
+ end
+ end
+ end
+end
diff --git a/app/controllers/oauth/applications_controller.rb b/app/controllers/oauth/applications_controller.rb
index 8158db282fb..81f188256ba 100644
--- a/app/controllers/oauth/applications_controller.rb
+++ b/app/controllers/oauth/applications_controller.rb
@@ -25,7 +25,7 @@ class Oauth::ApplicationsController < Doorkeeper::ApplicationsController
end
def create
- @application = Applications::CreateService.new(current_user, create_application_params).execute(request)
+ @application = Applications::CreateService.new(current_user, application_params).execute(request)
if @application.persisted?
flash[:notice] = I18n.t(:notice, scope: [:doorkeeper, :flash, :applications, :create])
@@ -51,8 +51,10 @@ class Oauth::ApplicationsController < Doorkeeper::ApplicationsController
@authorized_anonymous_tokens = @authorized_tokens.reject(&:application)
@authorized_apps = @authorized_tokens.map(&:application).uniq.reject(&:nil?)
- # Don't overwrite a value possibly set by `create`
- @application ||= Doorkeeper::Application.new
+ # Default access tokens to expire. This preserves backward compatibility
+ # with existing applications. This will be removed in 15.0.
+ # Removal issue: https://gitlab.com/gitlab-org/gitlab/-/issues/340848
+ @application ||= Doorkeeper::Application.new(expire_access_tokens: true)
end
# Override Doorkeeper to scope to the current user
@@ -64,8 +66,8 @@ class Oauth::ApplicationsController < Doorkeeper::ApplicationsController
render "errors/not_found", layout: "errors", status: :not_found
end
- def create_application_params
- application_params.tap do |params|
+ def application_params
+ super.tap do |params|
params[:owner] = current_user
end
end
diff --git a/app/controllers/profiles/groups_controller.rb b/app/controllers/profiles/groups_controller.rb
index 2571e92e071..5962b10c44b 100644
--- a/app/controllers/profiles/groups_controller.rb
+++ b/app/controllers/profiles/groups_controller.rb
@@ -6,7 +6,7 @@ class Profiles::GroupsController < Profiles::ApplicationController
feature_category :users
def update
- group = find_routable!(Group, params[:id], request.path_info)
+ group = find_routable!(Group, params[:id], request.fullpath)
notification_setting = current_user.notification_settings_for(group)
if notification_setting.update(update_params)
diff --git a/app/controllers/profiles/two_factor_auths_controller.rb b/app/controllers/profiles/two_factor_auths_controller.rb
index effd3514c1b..5eb46421583 100644
--- a/app/controllers/profiles/two_factor_auths_controller.rb
+++ b/app/controllers/profiles/two_factor_auths_controller.rb
@@ -2,6 +2,7 @@
class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
skip_before_action :check_two_factor_requirement
+ before_action :ensure_verified_primary_email, only: [:show, :create]
before_action do
push_frontend_feature_flag(:webauthn)
end
@@ -57,7 +58,7 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
@codes = user.generate_otp_backup_codes!
end
- helpers.dismiss_account_recovery_regular_check
+ helpers.dismiss_two_factor_auth_recovery_settings_check
render 'create'
else
@@ -108,7 +109,7 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
Users::UpdateService.new(current_user, user: current_user).execute! do |user|
@codes = user.generate_otp_backup_codes!
- helpers.dismiss_account_recovery_regular_check
+ helpers.dismiss_two_factor_auth_recovery_settings_check
end
end
@@ -218,4 +219,12 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
s_(%{The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}.})
.html_safe % { group_links: group_links.html_safe, leave_group_links: leave_group_links.html_safe }
end
+
+ def ensure_verified_primary_email
+ return unless Feature.enabled?(:ensure_verified_primary_email_for_2fa, default_enabled: :yaml)
+
+ unless current_user.two_factor_enabled? || current_user.primary_email_verified?
+ redirect_to profile_emails_path, notice: s_('You need to verify your primary email first before enabling Two-Factor Authentication.')
+ end
+ end
end
diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb
index 6cc602fec88..29ae268ef67 100644
--- a/app/controllers/profiles_controller.rb
+++ b/app/controllers/profiles_controller.rb
@@ -103,8 +103,8 @@ class ProfilesController < Profiles::ApplicationController
@username_param ||= user_params.require(:username)
end
- def user_params
- @user_params ||= params.require(:user).permit(
+ def user_params_attributes
+ [
:avatar,
:bio,
:email,
@@ -130,6 +130,12 @@ class ProfilesController < Profiles::ApplicationController
:pronouns,
:pronunciation,
status: [:emoji, :message, :availability]
- )
+ ]
+ end
+
+ def user_params
+ @user_params ||= params.require(:user).permit(user_params_attributes)
end
end
+
+ProfilesController.prepend_mod
diff --git a/app/controllers/projects/analytics/cycle_analytics/summary_controller.rb b/app/controllers/projects/analytics/cycle_analytics/summary_controller.rb
index c51a5ac7b88..bf8742bf6e8 100644
--- a/app/controllers/projects/analytics/cycle_analytics/summary_controller.rb
+++ b/app/controllers/projects/analytics/cycle_analytics/summary_controller.rb
@@ -20,7 +20,7 @@ class Projects::Analytics::CycleAnalytics::SummaryController < Projects::Applica
end
def allowed_params
- params.permit(:created_after, :created_before)
+ request_params.to_data_collector_params
end
end
diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb
index cf2ecb0673e..7a03e7b84b7 100644
--- a/app/controllers/projects/application_controller.rb
+++ b/app/controllers/projects/application_controller.rb
@@ -26,7 +26,7 @@ class Projects::ApplicationController < ApplicationController
path = File.join(params[:namespace_id], params[:project_id] || params[:id])
auth_proc = ->(project) { !project.pending_delete? }
- @project = find_routable!(Project, path, request.path_info, extra_authorization_proc: auth_proc)
+ @project = find_routable!(Project, path, request.fullpath, extra_authorization_proc: auth_proc)
end
def build_canonical_path(project)
diff --git a/app/controllers/projects/boards_controller.rb b/app/controllers/projects/boards_controller.rb
index 035b76abfd6..316582f3994 100644
--- a/app/controllers/projects/boards_controller.rb
+++ b/app/controllers/projects/boards_controller.rb
@@ -8,7 +8,6 @@ class Projects::BoardsController < Projects::ApplicationController
before_action :assign_endpoint_vars
before_action do
push_frontend_feature_flag(:swimlanes_buffered_rendering, project, default_enabled: :yaml)
- push_frontend_feature_flag(:graphql_board_lists, project, default_enabled: :yaml)
push_frontend_feature_flag(:issue_boards_filtered_search, project, default_enabled: :yaml)
push_frontend_feature_flag(:board_multi_select, project, default_enabled: :yaml)
push_frontend_feature_flag(:iteration_cadences, project&.group, default_enabled: :yaml)
diff --git a/app/controllers/projects/ci/pipeline_editor_controller.rb b/app/controllers/projects/ci/pipeline_editor_controller.rb
index ed1d5ca9594..550877548e1 100644
--- a/app/controllers/projects/ci/pipeline_editor_controller.rb
+++ b/app/controllers/projects/ci/pipeline_editor_controller.rb
@@ -4,7 +4,6 @@ class Projects::Ci::PipelineEditorController < Projects::ApplicationController
before_action :check_can_collaborate!
before_action do
push_frontend_feature_flag(:pipeline_editor_empty_state_action, @project, default_enabled: :yaml)
- push_frontend_feature_flag(:pipeline_editor_branch_switcher, @project, default_enabled: :yaml)
push_frontend_feature_flag(:pipeline_editor_drawer, @project, default_enabled: :yaml)
push_frontend_feature_flag(:schema_linting, @project, default_enabled: :yaml)
end
diff --git a/app/controllers/projects/clusters/integrations_controller.rb b/app/controllers/projects/clusters/integrations_controller.rb
index eed6c1dccc4..77314d19469 100644
--- a/app/controllers/projects/clusters/integrations_controller.rb
+++ b/app/controllers/projects/clusters/integrations_controller.rb
@@ -10,6 +10,6 @@ class Projects::Clusters::IntegrationsController < ::Clusters::IntegrationsContr
end
def project
- @project ||= find_routable!(Project, File.join(params[:namespace_id], params[:project_id]), request.path_info)
+ @project ||= find_routable!(Project, File.join(params[:namespace_id], params[:project_id]), request.fullpath)
end
end
diff --git a/app/controllers/projects/clusters_controller.rb b/app/controllers/projects/clusters_controller.rb
index 0aef497d28d..8f45fa1cb9f 100644
--- a/app/controllers/projects/clusters_controller.rb
+++ b/app/controllers/projects/clusters_controller.rb
@@ -17,7 +17,7 @@ class Projects::ClustersController < Clusters::ClustersController
end
def project
- @project ||= find_routable!(Project, File.join(params[:namespace_id], params[:project_id]), request.path_info)
+ @project ||= find_routable!(Project, File.join(params[:namespace_id], params[:project_id]), request.fullpath)
end
def repository
diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb
index cac0aa9d513..23dabd885c8 100644
--- a/app/controllers/projects/environments_controller.rb
+++ b/app/controllers/projects/environments_controller.rb
@@ -213,8 +213,14 @@ class Projects::EnvironmentsController < Projects::ApplicationController
end
end
+ def allowed_environment_attributes
+ attributes = [:external_url]
+ attributes << :name if action_name == "create"
+ attributes
+ end
+
def environment_params
- params.require(:environment).permit(:name, :external_url)
+ params.require(:environment).permit(allowed_environment_attributes)
end
def environment
diff --git a/app/controllers/projects/feature_flags_controller.rb b/app/controllers/projects/feature_flags_controller.rb
index b99c233411a..7c0da8f8a24 100644
--- a/app/controllers/projects/feature_flags_controller.rb
+++ b/app/controllers/projects/feature_flags_controller.rb
@@ -10,9 +10,6 @@ class Projects::FeatureFlagsController < Projects::ApplicationController
before_action :feature_flag, only: [:edit, :update, :destroy]
- before_action :ensure_flag_writable!, only: [:update]
- before_action :exclude_legacy_flags_check, only: [:edit]
-
feature_category :feature_flags
def index
@@ -98,18 +95,6 @@ class Projects::FeatureFlagsController < Projects::ApplicationController
@feature_flag ||= @noteable = project.operations_feature_flags.find_by_iid!(params[:iid])
end
- def ensure_flag_writable!
- if feature_flag.legacy_flag?
- render_error_json(['Legacy feature flags are read-only'])
- end
- end
-
- def exclude_legacy_flags_check
- if feature_flag.legacy_flag?
- not_found
- end
- end
-
def create_params
params.require(:operations_feature_flag)
.permit(:name, :description, :active, :version,
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index bdfaaf2b143..f885ff9b45b 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -42,9 +42,8 @@ class Projects::IssuesController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:tribute_autocomplete, @project)
push_frontend_feature_flag(:vue_issuables_list, project)
- push_frontend_feature_flag(:usage_data_design_action, project, default_enabled: true)
push_frontend_feature_flag(:improved_emoji_picker, project, default_enabled: :yaml)
- push_frontend_feature_flag(:vue_issues_list, project)
+ push_frontend_feature_flag(:vue_issues_list, project&.group, default_enabled: :yaml)
push_frontend_feature_flag(:iteration_cadences, project&.group, default_enabled: :yaml)
end
@@ -118,7 +117,11 @@ class Projects::IssuesController < Projects::ApplicationController
@issue = @noteable = service.execute
@merge_request_to_resolve_discussions_of = service.merge_request_to_resolve_discussions_of
- @discussion_to_resolve = service.discussions_to_resolve.first if params[:discussion_to_resolve]
+
+ if params[:discussion_to_resolve]
+ Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter.track_resolve_thread_in_issue_action(user: current_user)
+ @discussion_to_resolve = service.discussions_to_resolve.first
+ end
respond_with(@issue)
end
@@ -228,7 +231,7 @@ class Projects::IssuesController < Projects::ApplicationController
IssuableExportCsvWorker.perform_async(:issue, current_user.id, project.id, finder_options.to_h) # rubocop:disable CodeReuse/Worker
index_path = project_issues_path(project)
- message = _('Your CSV export has started. It will be emailed to %{email} when complete.') % { email: current_user.notification_email }
+ message = _('Your CSV export has started. It will be emailed to %{email} when complete.') % { email: current_user.notification_email_or_default }
redirect_to(index_path, notice: message)
end
diff --git a/app/controllers/projects/learn_gitlab_controller.rb b/app/controllers/projects/learn_gitlab_controller.rb
index 162ba9bd5cb..91a43c5f03f 100644
--- a/app/controllers/projects/learn_gitlab_controller.rb
+++ b/app/controllers/projects/learn_gitlab_controller.rb
@@ -7,13 +7,11 @@ class Projects::LearnGitlabController < Projects::ApplicationController
feature_category :users
def index
- push_frontend_experiment(:learn_gitlab_a, subject: current_user)
- push_frontend_experiment(:learn_gitlab_b, subject: current_user)
end
private
def check_experiment_enabled?
- return access_denied! unless helpers.learn_gitlab_experiment_enabled?(project)
+ return access_denied! unless helpers.learn_gitlab_enabled?(project)
end
end
diff --git a/app/controllers/projects/merge_requests/diffs_controller.rb b/app/controllers/projects/merge_requests/diffs_controller.rb
index 8ccc658dfe7..1188aec24a8 100644
--- a/app/controllers/projects/merge_requests/diffs_controller.rb
+++ b/app/controllers/projects/merge_requests/diffs_controller.rb
@@ -42,7 +42,7 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
allow_tree_conflicts: display_merge_conflicts_in_diff?
}
- if diff_options_hash[:paths].blank? && Feature.enabled?(:diffs_batch_render_cached, project, default_enabled: :yaml)
+ if diff_options_hash[:paths].blank?
# NOTE: Any variables that would affect the resulting json needs to be added to the cache_context to avoid stale cache issues.
cache_context = [
current_user&.cache_key,
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 8b3f2df69df..cb68aaf4583 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -13,6 +13,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
include DiffHelper
include Gitlab::Cache::Helpers
+ prepend_before_action(only: [:index]) { authenticate_sessionless_user!(:rss) }
skip_before_action :merge_request, only: [:index, :bulk_update, :export_csv]
before_action :apply_diff_view_cookie!, only: [:show]
before_action :disable_query_limiting, only: [:assign_related_issues, :update]
@@ -34,12 +35,12 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:merge_request_widget_graphql, @project, default_enabled: :yaml)
push_frontend_feature_flag(:default_merge_ref_for_diffs, @project, default_enabled: :yaml)
push_frontend_feature_flag(:core_security_mr_widget_counts, @project)
- push_frontend_feature_flag(:local_file_reviews, default_enabled: :yaml)
push_frontend_feature_flag(:paginated_notes, @project, default_enabled: :yaml)
push_frontend_feature_flag(:confidential_notes, @project, default_enabled: :yaml)
push_frontend_feature_flag(:usage_data_i_testing_summary_widget_total, @project, default_enabled: :yaml)
push_frontend_feature_flag(:improved_emoji_picker, project, default_enabled: :yaml)
push_frontend_feature_flag(:diffs_virtual_scrolling, project, default_enabled: :yaml)
+ push_frontend_feature_flag(:restructured_mr_widget, project, default_enabled: :yaml)
# Usage data feature flags
push_frontend_feature_flag(:users_expanding_widgets_usage_data, @project, default_enabled: :yaml)
@@ -85,6 +86,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
respond_to do |format|
format.html
+ format.atom { render layout: 'xml.atom' }
format.json do
render json: {
html: view_to_html_string("projects/merge_requests/_merge_requests")
@@ -124,13 +126,17 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
set_pipeline_variables
+ ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336891') do
+ @number_of_pipelines = @pipelines.size
+ end
+
render
end
format.json do
Gitlab::PollingInterval.set_header(response, interval: 10_000)
- if params[:serializer] == 'sidebar_extras' && Feature.enabled?(:merge_request_show_render_cached, @project, default_enabled: :yaml)
+ if params[:serializer] == 'sidebar_extras'
cache_context = [
params[:serializer],
current_user&.cache_key,
@@ -173,7 +179,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
# or from cache if already merged
@commits =
set_commits_for_rendering(
- @merge_request.recent_commits.with_latest_pipeline(@merge_request.source_branch).with_markdown_cache,
+ @merge_request.recent_commits(load_from_gitaly: true).with_latest_pipeline(@merge_request.source_branch).with_markdown_cache,
commits_count: @merge_request.commits_count
)
@@ -372,7 +378,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
IssuableExportCsvWorker.perform_async(:merge_request, current_user.id, project.id, finder_options.to_h) # rubocop:disable CodeReuse/Worker
index_path = project_merge_requests_path(project)
- message = _('Your CSV export has started. It will be emailed to %{email} when complete.') % { email: current_user.notification_email }
+ message = _('Your CSV export has started. It will be emailed to %{email} when complete.') % { email: current_user.notification_email_or_default }
redirect_to(index_path, notice: message)
end
diff --git a/app/controllers/projects/packages/packages_controller.rb b/app/controllers/projects/packages/packages_controller.rb
index 15dc11f5df8..5de71466c10 100644
--- a/app/controllers/projects/packages/packages_controller.rb
+++ b/app/controllers/projects/packages/packages_controller.rb
@@ -9,8 +9,6 @@ module Projects
def show
@package = project.packages.find(params[:id])
- @package_files = @package.package_files.recent
- @maven_metadatum = @package.maven_metadatum
end
end
end
diff --git a/app/controllers/projects/pipeline_schedules_controller.rb b/app/controllers/projects/pipeline_schedules_controller.rb
index 006cb8a2201..4af7508b935 100644
--- a/app/controllers/projects/pipeline_schedules_controller.rb
+++ b/app/controllers/projects/pipeline_schedules_controller.rb
@@ -10,10 +10,6 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController
before_action :authorize_update_pipeline_schedule!, except: [:index, :new, :create, :play]
before_action :authorize_admin_pipeline_schedule!, only: [:destroy]
- before_action do
- push_frontend_feature_flag(:ci_daily_limit_for_pipeline_schedules, @project, default_enabled: :yaml)
- end
-
feature_category :continuous_integration
# rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index a411264b350..a2312484a9b 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -14,10 +14,6 @@ class Projects::PipelinesController < Projects::ApplicationController
before_action :authorize_update_pipeline!, only: [:retry, :cancel]
before_action :ensure_pipeline, only: [:show, :downloadable_artifacts]
- before_action do
- push_frontend_feature_flag(:pipeline_source_filter, project, type: :development, default_enabled: :yaml)
- end
-
# Will be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/225596
before_action :redirect_for_legacy_scope_filter, only: [:index], if: -> { request.format.html? }
@@ -195,7 +191,8 @@ class Projects::PipelinesController < Projects::ApplicationController
def config_variables
respond_to do |format|
format.json do
- result = Ci::ListConfigVariablesService.new(@project, current_user).execute(params[:sha])
+ project = @project.uses_external_project_ci_config? ? @project.ci_config_external_project : @project
+ result = Ci::ListConfigVariablesService.new(project, current_user).execute(params[:sha])
result.nil? ? head(:no_content) : render(json: result)
end
@@ -297,7 +294,7 @@ class Projects::PipelinesController < Projects::ApplicationController
end
def index_params
- params.permit(:scope, :username, :ref, :status)
+ params.permit(:scope, :username, :ref, :status, :source)
end
def enable_code_quality_walkthrough_experiment
diff --git a/app/controllers/projects/runner_projects_controller.rb b/app/controllers/projects/runner_projects_controller.rb
index 5da81045e02..39db7618db0 100644
--- a/app/controllers/projects/runner_projects_controller.rb
+++ b/app/controllers/projects/runner_projects_controller.rb
@@ -15,7 +15,7 @@ class Projects::RunnerProjectsController < Projects::ApplicationController
path = project_runners_path(project)
if @runner.assign_to(project, current_user)
- redirect_to path
+ redirect_to path, notice: s_('Runners|Runner assigned to project.')
else
assign_to_messages = @runner.errors.messages[:assign_to]
alert = assign_to_messages&.join(',') || 'Failed adding runner to project'
@@ -28,6 +28,6 @@ class Projects::RunnerProjectsController < Projects::ApplicationController
runner_project = project.runner_projects.find(params[:id])
runner_project.destroy
- redirect_to project_runners_path(project), status: :found
+ redirect_to project_runners_path(project), status: :found, notice: s_('Runners|Runner unassigned from project.')
end
end
diff --git a/app/controllers/projects/service_desk_controller.rb b/app/controllers/projects/service_desk_controller.rb
index f7c0a54fb9e..1fb07c3a903 100644
--- a/app/controllers/projects/service_desk_controller.rb
+++ b/app/controllers/projects/service_desk_controller.rb
@@ -24,24 +24,31 @@ class Projects::ServiceDeskController < Projects::ApplicationController
private
def setting_params
- params.permit(:issue_template_key, :outgoing_name, :project_key)
+ params.permit(*allowed_update_attributes)
+ end
+
+ def allowed_update_attributes
+ %i(issue_template_key outgoing_name project_key)
+ end
+
+ def service_desk_attributes
+ service_desk_settings = project.service_desk_setting
+
+ {
+ service_desk_address: project.service_desk_address,
+ service_desk_enabled: project.service_desk_enabled,
+ issue_template_key: service_desk_settings&.issue_template_key,
+ template_file_missing: service_desk_settings&.issue_template_missing?,
+ outgoing_name: service_desk_settings&.outgoing_name,
+ project_key: service_desk_settings&.project_key
+ }
end
def json_response
respond_to do |format|
- service_desk_settings = project.service_desk_setting
-
- service_desk_attributes =
- {
- service_desk_address: project.service_desk_address,
- service_desk_enabled: project.service_desk_enabled,
- issue_template_key: service_desk_settings&.issue_template_key,
- template_file_missing: service_desk_settings&.issue_template_missing?,
- outgoing_name: service_desk_settings&.outgoing_name,
- project_key: service_desk_settings&.project_key
- }
-
format.json { render json: service_desk_attributes }
end
end
end
+
+Projects::ServiceDeskController.prepend_mod
diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb
index 0dcaab7160b..c42d382c4bb 100644
--- a/app/controllers/projects/services_controller.rb
+++ b/app/controllers/projects/services_controller.rb
@@ -26,15 +26,15 @@ class Projects::ServicesController < Projects::ApplicationController
attributes = integration_params[:integration]
if use_inherited_settings?(attributes)
- @integration.inherit_from_id = default_integration.id
+ integration.inherit_from_id = default_integration.id
- if saved = @integration.save(context: :manual_change)
- BulkUpdateIntegrationService.new(default_integration, [@integration]).execute
+ if saved = integration.save(context: :manual_change)
+ BulkUpdateIntegrationService.new(default_integration, [integration]).execute
end
else
attributes[:inherit_from_id] = nil
- @integration.attributes = attributes
- saved = @integration.save(context: :manual_change)
+ integration.attributes = attributes
+ saved = integration.save(context: :manual_change)
end
respond_to do |format|
@@ -65,15 +65,15 @@ class Projects::ServicesController < Projects::ApplicationController
private
def redirect_path
- safe_redirect_path(params[:redirect_to]).presence || edit_project_service_path(@project, @integration)
+ safe_redirect_path(params[:redirect_to]).presence || edit_project_service_path(project, integration)
end
def service_test_response
- unless @integration.update(integration_params[:integration])
- return { error: true, message: _('Validations failed.'), service_response: @integration.errors.full_messages.join(','), test_failed: false }
+ unless integration.update(integration_params[:integration])
+ return { error: true, message: _('Validations failed.'), service_response: integration.errors.full_messages.join(','), test_failed: false }
end
- result = ::Integrations::Test::ProjectService.new(@integration, current_user, params[:event]).execute
+ result = ::Integrations::Test::ProjectService.new(integration, current_user, params[:event]).execute
unless result[:success]
return { error: true, message: s_('Integrations|Connection failed. Please check your settings.'), service_response: result[:message].to_s, test_failed: true }
@@ -93,7 +93,7 @@ class Projects::ServicesController < Projects::ApplicationController
end
def integration
- @integration ||= @project.find_or_initialize_integration(params[:id])
+ @integration ||= project.find_or_initialize_integration(params[:id])
end
alias_method :service, :integration
diff --git a/app/controllers/projects/settings/operations_controller.rb b/app/controllers/projects/settings/operations_controller.rb
index e32815b6239..56e201c592f 100644
--- a/app/controllers/projects/settings/operations_controller.rb
+++ b/app/controllers/projects/settings/operations_controller.rb
@@ -136,6 +136,7 @@ module Projects
error_tracking_setting_attributes: [
:enabled,
+ :integrated,
:api_host,
:token,
project: [:slug, :name, :organization_slug, :organization_name]
diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb
index 475c9de2503..6fd4c632dd3 100644
--- a/app/controllers/projects/tree_controller.rb
+++ b/app/controllers/projects/tree_controller.rb
@@ -15,6 +15,10 @@ class Projects::TreeController < Projects::ApplicationController
before_action :authorize_download_code!
before_action :authorize_edit_tree!, only: [:create_dir]
+ before_action do
+ push_frontend_feature_flag(:paginated_tree_graphql_query, @project, default_enabled: :yaml)
+ end
+
feature_category :source_code_management
def show
diff --git a/app/controllers/projects/usage_quotas_controller.rb b/app/controllers/projects/usage_quotas_controller.rb
new file mode 100644
index 00000000000..179c7fc8db1
--- /dev/null
+++ b/app/controllers/projects/usage_quotas_controller.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+class Projects::UsageQuotasController < Projects::ApplicationController
+ before_action :authorize_admin_project!
+ before_action :verify_usage_quotas_enabled!
+
+ layout "project_settings"
+
+ feature_category :utilization
+
+ def index
+ @storage_app_data = {
+ project_path: @project.full_path,
+ usage_quotas_help_page_path: help_page_path('user/usage_quotas'),
+ build_artifacts_help_page_path: help_page_path('ci/pipelines/job_artifacts', anchor: 'when-job-artifacts-are-deleted'),
+ packages_help_page_path: help_page_path('user/packages/package_registry/index.md', anchor: 'delete-a-package'),
+ repository_help_page_path: help_page_path('user/project/repository/reducing_the_repo_size_using_git'),
+ snippets_help_page_path: help_page_path('user/snippets', anchor: 'reduce-snippets-repository-size'),
+ wiki_help_page_path: help_page_path('administration/wikis/index.md', anchor: 'reduce-wiki-repository-size')
+ }
+ end
+
+ private
+
+ def verify_usage_quotas_enabled!
+ render_404 unless Feature.enabled?(:project_storage_ui, project&.group, default_enabled: :yaml)
+ end
+end
diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb
index d1486f765e4..9ee8847004e 100644
--- a/app/controllers/projects/wikis_controller.rb
+++ b/app/controllers/projects/wikis_controller.rb
@@ -5,5 +5,9 @@ class Projects::WikisController < Projects::ApplicationController
alias_method :container, :project
+ before_action do
+ push_frontend_feature_flag(:content_editor_block_tables, @project, default_enabled: :yaml)
+ end
+
feature_category :wiki
end
diff --git a/app/controllers/projects/work_items_controller.rb b/app/controllers/projects/work_items_controller.rb
new file mode 100644
index 00000000000..1bd2762f277
--- /dev/null
+++ b/app/controllers/projects/work_items_controller.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class Projects::WorkItemsController < Projects::ApplicationController
+ before_action do
+ push_frontend_feature_flag(:work_items, project, default_enabled: :yaml)
+ end
+
+ feature_category :not_owned
+
+ def index
+ render_404 unless Feature.enabled?(:work_items, project, default_enabled: :yaml)
+ end
+end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index bdb645e1934..d7c1d87ae4b 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -34,6 +34,7 @@ class ProjectsController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:refactor_blob_viewer, @project, default_enabled: :yaml)
push_frontend_feature_flag(:increase_page_size_exponentially, @project, default_enabled: :yaml)
+ push_frontend_feature_flag(:paginated_tree_graphql_query, @project, default_enabled: :yaml)
end
layout :determine_layout
diff --git a/app/controllers/registrations/experience_levels_controller.rb b/app/controllers/registrations/experience_levels_controller.rb
deleted file mode 100644
index 3c94bce126c..00000000000
--- a/app/controllers/registrations/experience_levels_controller.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# frozen_string_literal: true
-
-module Registrations
- class ExperienceLevelsController < ApplicationController
- layout 'minimal'
-
- before_action :ensure_namespace_path_param
-
- feature_category :onboarding
-
- def update
- current_user.experience_level = params[:experience_level]
-
- if current_user.save
- hide_advanced_issues
-
- if learn_gitlab.available?
- redirect_to namespace_project_board_path(params[:namespace_path], learn_gitlab.project, learn_gitlab.board)
- else
- redirect_to group_path(params[:namespace_path])
- end
- else
- render :show
- end
- end
-
- private
-
- def ensure_namespace_path_param
- redirect_to root_path unless params[:namespace_path].present?
- end
-
- def hide_advanced_issues
- return unless current_user.user_preference.novice?
- return unless learn_gitlab.available?
-
- Boards::UpdateService.new(learn_gitlab.project, current_user, label_ids: [learn_gitlab.label.id]).execute(learn_gitlab.board)
- end
-
- def learn_gitlab
- @learn_gitlab ||= LearnGitlab::Project.new(current_user)
- end
- end
-end
diff --git a/app/controllers/registrations/welcome_controller.rb b/app/controllers/registrations/welcome_controller.rb
index ced21b8f291..416bbf43464 100644
--- a/app/controllers/registrations/welcome_controller.rb
+++ b/app/controllers/registrations/welcome_controller.rb
@@ -16,7 +16,7 @@ module Registrations
result = ::Users::SignupService.new(current_user, update_params).execute
if result[:status] == :success
- return redirect_to new_users_sign_up_group_path(trial_params) if show_signup_onboarding?
+ return redirect_to experiment(:combined_registration, user: current_user).redirect_path(trial_params) if show_signup_onboarding?
members = current_user.members
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index cc985e84542..fe800de5dd8 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -21,9 +21,10 @@ class RegistrationsController < Devise::RegistrationsController
def create
set_user_state
- accept_pending_invitations
super do |new_user|
+ accept_pending_invitations if new_user.persisted?
+
persist_accepted_terms_if_required(new_user)
set_role_required(new_user)
@@ -146,8 +147,12 @@ class RegistrationsController < Devise::RegistrationsController
resource.persisted? && resource.blocked_pending_approval?
end
+ def sign_up_params_attributes
+ [:username, :email, :name, :first_name, :last_name, :password]
+ end
+
def sign_up_params
- params.require(:user).permit(:username, :email, :name, :first_name, :last_name, :password)
+ params.require(:user).permit(sign_up_params_attributes)
end
def resource_name
@@ -201,6 +206,7 @@ class RegistrationsController < Devise::RegistrationsController
experiment_name = session.delete(:invite_email_experiment_name)
experiment(:invite_email_preview_text, actor: member).track(:accepted) if experiment_name == 'invite_email_preview_text'
+ experiment(:invite_email_from, actor: member).track(:accepted) if experiment_name == 'invite_email_from'
Gitlab::Tracking.event(self.class.name, 'accepted', label: 'invite_email', property: member.id.to_s)
end
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index dbddb35d358..5f1b3750e41 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -11,7 +11,7 @@ class SearchController < ApplicationController
around_action :allow_gitaly_ref_name_caching
- before_action :block_anonymous_global_searches, except: :opensearch
+ before_action :block_anonymous_global_searches, :check_scope_global_search_enabled, except: :opensearch
skip_before_action :authenticate_user!
requires_cross_project_access if: -> do
search_term_present = params[:search].present? || params[:term].present?
@@ -156,6 +156,29 @@ class SearchController < ApplicationController
redirect_to new_user_session_path, alert: _('You must be logged in to search across all of GitLab')
end
+ def check_scope_global_search_enabled
+ return if params[:project_id].present? || params[:group_id].present?
+
+ search_allowed = case params[:scope]
+ when 'blobs'
+ Feature.enabled?(:global_search_code_tab, current_user, type: :ops, default_enabled: true)
+ when 'commits'
+ Feature.enabled?(:global_search_commits_tab, current_user, type: :ops, default_enabled: true)
+ when 'issues'
+ Feature.enabled?(:global_search_issues_tab, current_user, type: :ops, default_enabled: true)
+ when 'merge_requests'
+ Feature.enabled?(:global_search_merge_requests_tab, current_user, type: :ops, default_enabled: true)
+ when 'wiki_blobs'
+ Feature.enabled?(:global_search_wiki_tab, current_user, type: :ops, default_enabled: true)
+ else
+ true
+ end
+
+ return if search_allowed
+
+ redirect_to search_path, alert: _('Global Search is disabled for this scope')
+ end
+
def render_timeout(exception)
raise exception unless action_name.to_sym.in?(RESCUE_FROM_TIMEOUT_ACTIONS)
diff --git a/app/controllers/user_callouts_controller.rb b/app/controllers/user_callouts_controller.rb
index df3e2425e9f..f52a09adf5a 100644
--- a/app/controllers/user_callouts_controller.rb
+++ b/app/controllers/user_callouts_controller.rb
@@ -4,10 +4,6 @@ class UserCalloutsController < ApplicationController
feature_category :navigation
def create
- callout = Users::DismissUserCalloutService.new(
- container: nil, current_user: current_user, params: { feature_name: feature_name }
- ).execute
-
if callout.persisted?
respond_to do |format|
format.json { head :ok }
@@ -21,6 +17,12 @@ class UserCalloutsController < ApplicationController
private
+ def callout
+ Users::DismissUserCalloutService.new(
+ container: nil, current_user: current_user, params: { feature_name: feature_name }
+ ).execute
+ end
+
def feature_name
params.require(:feature_name)
end
diff --git a/app/controllers/users/group_callouts_controller.rb b/app/controllers/users/group_callouts_controller.rb
new file mode 100644
index 00000000000..cc27452e6a3
--- /dev/null
+++ b/app/controllers/users/group_callouts_controller.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Users
+ class GroupCalloutsController < UserCalloutsController
+ private
+
+ def callout
+ Users::DismissGroupCalloutService.new(
+ container: nil, current_user: current_user, params: callout_params
+ ).execute
+ end
+
+ def callout_params
+ params.permit(:group_id).merge(feature_name: feature_name)
+ end
+ end
+end
diff --git a/app/controllers/users/terms_controller.rb b/app/controllers/users/terms_controller.rb
index be670658048..7fbf0faa68b 100644
--- a/app/controllers/users/terms_controller.rb
+++ b/app/controllers/users/terms_controller.rb
@@ -77,3 +77,5 @@ module Users
end
end
end
+
+Users::TermsController.prepend_mod
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 30ccceec1af..26f56307862 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -167,7 +167,7 @@ class UsersController < ApplicationController
private
def user
- @user ||= find_routable!(User, params[:username], request.path_info)
+ @user ||= find_routable!(User, params[:username], request.fullpath)
end
def personal_projects
diff --git a/app/experiments/combined_registration_experiment.rb b/app/experiments/combined_registration_experiment.rb
new file mode 100644
index 00000000000..da699449d77
--- /dev/null
+++ b/app/experiments/combined_registration_experiment.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class CombinedRegistrationExperiment < ApplicationExperiment # rubocop:disable Gitlab/NamespacedClass
+ include Rails.application.routes.url_helpers
+
+ def key_for(source, _ = nil)
+ super(source, 'force_company_trial')
+ end
+
+ def redirect_path(trial_params)
+ @trial_params = trial_params
+
+ run
+ end
+
+ def control_behavior
+ new_users_sign_up_group_path(@trial_params)
+ end
+
+ def candidate_behavior
+ new_users_sign_up_groups_project_path
+ end
+end
diff --git a/app/experiments/security_reports_mr_widget_prompt_experiment.rb b/app/experiments/security_reports_mr_widget_prompt_experiment.rb
new file mode 100644
index 00000000000..fa0ba8e24d4
--- /dev/null
+++ b/app/experiments/security_reports_mr_widget_prompt_experiment.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class SecurityReportsMrWidgetPromptExperiment < ApplicationExperiment # rubocop:disable Gitlab/NamespacedClass
+ def publish(_result = nil)
+ super
+
+ publish_to_database
+ end
+
+ # This is a purely client side experiment, and since we don't have a nicer
+ # way to define variants yet, we define them here.
+ def candidate_behavior
+ end
+end
diff --git a/app/experiments/templates/new_project_readme_content/readme_advanced.md.tt b/app/experiments/templates/new_project_readme_content/readme_advanced.md.tt
index 70a32ba6f03..bbe8271386f 100644
--- a/app/experiments/templates/new_project_readme_content/readme_advanced.md.tt
+++ b/app/experiments/templates/new_project_readme_content/readme_advanced.md.tt
@@ -38,6 +38,8 @@ Use the built-in continuous integration in GitLab.
- [ ] [Get started with GitLab CI/CD](<%= redirect("https://docs.gitlab.com/ee/ci/quick_start/index.html") %>)
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](<%= redirect("https://docs.gitlab.com/ee/user/application_security/sast/") %>)
+- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](<%= redirect("https://docs.gitlab.com/ee/topics/autodevops/requirements.html") %>)
+- [ ] [Use pull-based deployments for improved Kubernetes management](<%= redirect("https://docs.gitlab.com/ee/user/clusters/agent/") %>)
***
diff --git a/app/finders/branches_finder.rb b/app/finders/branches_finder.rb
index 157c454183a..a62d47071d4 100644
--- a/app/finders/branches_finder.rb
+++ b/app/finders/branches_finder.rb
@@ -15,6 +15,10 @@ class BranchesFinder < GitRefsFinder
end
end
+ def total
+ repository.branch_count
+ end
+
private
def names
diff --git a/app/finders/ci/pipelines_finder.rb b/app/finders/ci/pipelines_finder.rb
index a79840216da..39355853d88 100644
--- a/app/finders/ci/pipelines_finder.rb
+++ b/app/finders/ci/pipelines_finder.rb
@@ -25,12 +25,10 @@ module Ci
items = by_status(items)
items = by_ref(items)
items = by_sha(items)
- items = by_name(items)
items = by_username(items)
items = by_yaml_errors(items)
items = by_updated_at(items)
-
- items = by_source(items) if Feature.enabled?(:pipeline_source_filter, project, default_enabled: :yaml)
+ items = by_source(items)
sort_items(items)
end
@@ -116,17 +114,6 @@ module Ci
end
# rubocop: enable CodeReuse/ActiveRecord
- # This method is deprecated and will be removed in 14.3
- # rubocop: disable CodeReuse/ActiveRecord
- def by_name(items)
- if params[:name].present?
- items.joins(:user).where(users: { name: params[:name] })
- else
- items
- end
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
# rubocop: disable CodeReuse/ActiveRecord
def by_username(items)
return items unless params[:username].present?
diff --git a/app/finders/ci/pipelines_for_merge_request_finder.rb b/app/finders/ci/pipelines_for_merge_request_finder.rb
index f769da03738..5d794c0903a 100644
--- a/app/finders/ci/pipelines_for_merge_request_finder.rb
+++ b/app/finders/ci/pipelines_for_merge_request_finder.rb
@@ -29,17 +29,19 @@ module Ci
# Fetch all pipelines without permission check.
def all
- strong_memoize(:all_pipelines) do
- next Ci::Pipeline.none unless source_project
-
- pipelines =
- if merge_request.persisted?
- pipelines_using_cte
- else
- triggered_for_branch.for_sha(commit_shas)
- end
-
- sort(pipelines)
+ ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336891') do
+ strong_memoize(:all_pipelines) do
+ next Ci::Pipeline.none unless source_project
+
+ pipelines =
+ if merge_request.persisted?
+ pipelines_using_cte
+ else
+ triggered_for_branch.for_sha(commit_shas)
+ end
+
+ sort(pipelines)
+ end
end
end
diff --git a/app/finders/ci/runners_finder.rb b/app/finders/ci/runners_finder.rb
index d34b3202433..8bc2a47a024 100644
--- a/app/finders/ci/runners_finder.rb
+++ b/app/finders/ci/runners_finder.rb
@@ -7,9 +7,9 @@ module Ci
ALLOWED_SORTS = %w[contacted_asc contacted_desc created_at_asc created_at_desc created_date].freeze
DEFAULT_SORT = 'created_at_desc'
- def initialize(current_user:, group: nil, params:)
+ def initialize(current_user:, params:)
@params = params
- @group = group
+ @group = params.delete(:group)
@current_user = current_user
end
@@ -48,10 +48,16 @@ module Ci
def group_runners
raise Gitlab::Access::AccessDeniedError unless can?(@current_user, :admin_group, @group)
- # Getting all runners from the group itself and all its descendants
- descendant_projects = Project.for_group_and_its_subgroups(@group)
-
- @runners = Ci::Runner.belonging_to_group_or_project(@group.self_and_descendants, descendant_projects)
+ @runners = case @params[:membership]
+ when :direct
+ Ci::Runner.belonging_to_group(@group.id)
+ when :descendants, nil
+ # Getting all runners from the group itself and all its descendant groups/projects
+ descendant_projects = Project.for_group_and_its_subgroups(@group)
+ Ci::Runner.belonging_to_group_or_project(@group.self_and_descendants, descendant_projects)
+ else
+ raise ArgumentError, 'Invalid membership filter'
+ end
end
def filter_by_status!
diff --git a/app/finders/error_tracking/errors_finder.rb b/app/finders/error_tracking/errors_finder.rb
index fb2d4b14dfa..d83a0c487e6 100644
--- a/app/finders/error_tracking/errors_finder.rb
+++ b/app/finders/error_tracking/errors_finder.rb
@@ -13,9 +13,10 @@ module ErrorTracking
collection = project.error_tracking_errors
collection = by_status(collection)
+ collection = sort(collection)
- # Limit collection until pagination implemented
- collection.limit(20)
+ # Limit collection until pagination implemented.
+ limit(collection)
end
private
@@ -33,5 +34,14 @@ module ErrorTracking
def authorized?
Ability.allowed?(current_user, :read_sentry_issue, project)
end
+
+ def sort(collection)
+ params[:sort] ? collection.sort_by_attribute(params[:sort]) : collection.order_id_desc
+ end
+
+ def limit(collection)
+ # Restrict the maximum limit at 100 records.
+ collection.limit([(params[:limit] || 20).to_i, 100].min)
+ end
end
end
diff --git a/app/finders/groups/user_groups_finder.rb b/app/finders/groups/user_groups_finder.rb
new file mode 100644
index 00000000000..5946e3a8933
--- /dev/null
+++ b/app/finders/groups/user_groups_finder.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+# Groups::UserGroupsFinder
+#
+# Used to filter Groups where a user is member
+#
+# Arguments:
+# current_user - user requesting group info on target user
+# target_user - user for which groups will be found
+# params:
+# permissions: string (see Types::Groups::UserPermissionsEnum)
+# search: string used for search on path and group name
+#
+# Initially created to filter user groups and descendants where the user can create projects
+module Groups
+ class UserGroupsFinder
+ def initialize(current_user, target_user, params = {})
+ @current_user = current_user
+ @target_user = target_user
+ @params = params
+ end
+
+ def execute
+ return Group.none unless current_user&.can?(:read_user_groups, target_user)
+ return Group.none if target_user.blank?
+
+ items = by_permission_scope
+ items = by_search(items)
+
+ sort(items)
+ end
+
+ private
+
+ attr_reader :current_user, :target_user, :params
+
+ def sort(items)
+ items.order(path: :asc, id: :asc) # rubocop: disable CodeReuse/ActiveRecord
+ end
+
+ def by_search(items)
+ return items if params[:search].blank?
+
+ items.search(params[:search])
+ end
+
+ def by_permission_scope
+ if permission_scope_create_projects?
+ target_user.manageable_groups(include_groups_with_developer_maintainer_access: true)
+ else
+ target_user.groups
+ end
+ end
+
+ def permission_scope_create_projects?
+ params[:permission_scope] == :create_projects &&
+ Feature.enabled?(:paginatable_namespace_drop_down_for_project_creation, current_user, default_enabled: :yaml)
+ end
+ end
+end
diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb
index 9f3ca385d93..cf706a8f98e 100644
--- a/app/finders/issuable_finder.rb
+++ b/app/finders/issuable_finder.rb
@@ -41,7 +41,6 @@ class IssuableFinder
include FinderMethods
include CreatedAtFilter
include Gitlab::Utils::StrongMemoize
- prepend OptimizedIssuableLabelFilter
requires_cross_project_access unless: -> { params.project? }
@@ -149,7 +148,6 @@ class IssuableFinder
# Negates all params found in `negatable_params`
def filter_negated_items(items)
- items = by_negated_label(items)
items = by_negated_milestone(items)
items = by_negated_release(items)
items = by_negated_my_reaction_emoji(items)
@@ -172,29 +170,19 @@ class IssuableFinder
count_params = params.merge(state: nil, sort: nil, force_cte: true)
finder = self.class.new(current_user, count_params)
+ state_counts = finder
+ .execute
+ .reorder(nil)
+ .group(:state_id)
+ .count
+
counts = Hash.new(0)
- # Searching by label includes a GROUP BY in the query, but ours will be last
- # because it is added last. Searching by multiple labels also includes a row
- # per issuable, so we have to count those in Ruby - which is bad, but still
- # better than performing multiple queries.
- #
- # This does not apply when we are using a CTE for the search, as the labels
- # GROUP BY is inside the subquery in that case, so we set labels_count to 1.
- #
- # Groups and projects have separate feature flags to suggest the use
- # of a CTE. The CTE will not be used if the sort doesn't support it,
- # but will always be used for the counts here as we ignore sorting
- # anyway.
- labels_count = params.label_names.any? ? params.label_names.count : 1
- labels_count = 1 if use_cte_for_search?
-
- finder.execute.reorder(nil).group(:state_id).count.each do |key, value|
- counts[count_key(key)] += value / labels_count
+ state_counts.each do |key, value|
+ counts[count_key(key)] += value
end
counts[:all] = counts.values.sum
-
counts.with_indifferent_access
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -332,6 +320,7 @@ class IssuableFinder
def by_search(items)
return items unless search
return items if items.is_a?(ActiveRecord::NullRelation)
+ return items if Feature.enabled?(:disable_anonymous_search, type: :ops) && current_user.nil?
if use_cte_for_search?
cte = Gitlab::SQL::CTE.new(klass.table_name, items)
@@ -359,7 +348,7 @@ class IssuableFinder
def sort(items)
# Ensure we always have an explicit sort order (instead of inheriting
# multiple orders when combining ActiveRecord::Relation objects).
- params[:sort] ? items.sort_by_attribute(params[:sort], excluded_labels: params.label_names) : items.reorder(id: :desc)
+ params[:sort] ? items.sort_by_attribute(params[:sort], excluded_labels: label_filter.label_names_excluded_from_priority_sort) : items.reorder(id: :desc)
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -383,6 +372,20 @@ class IssuableFinder
end
end
+ def by_label(items)
+ label_filter.filter(items)
+ end
+
+ def label_filter
+ strong_memoize(:label_filter) do
+ Issuables::LabelFilter.new(
+ params: original_params,
+ project: params.project,
+ group: params.group
+ )
+ end
+ end
+
# rubocop: disable CodeReuse/ActiveRecord
def by_milestone(items)
return items unless params.milestones?
@@ -435,24 +438,6 @@ class IssuableFinder
items.without_particular_release(not_params[:release_tag], not_params[:project_id])
end
- def by_label(items)
- return items unless params.labels?
-
- if params.filter_by_no_label?
- items.without_label
- elsif params.filter_by_any_label?
- items.any_label(params[:sort])
- else
- items.with_label(params.label_names, params[:sort])
- end
- end
-
- def by_negated_label(items)
- return items unless not_params.labels?
-
- items.without_particular_labels(not_params.label_names)
- end
-
def by_my_reaction_emoji(items)
return items unless params[:my_reaction_emoji] && current_user
diff --git a/app/finders/issuable_finder/params.rb b/app/finders/issuable_finder/params.rb
index 595f4e4cf8a..359a56bd39b 100644
--- a/app/finders/issuable_finder/params.rb
+++ b/app/finders/issuable_finder/params.rb
@@ -29,20 +29,6 @@ class IssuableFinder
params.present?
end
- def filter_by_no_label?
- downcased = label_names.map(&:downcase)
-
- downcased.include?(FILTER_NONE)
- end
-
- def filter_by_any_label?
- label_names.map(&:downcase).include?(FILTER_ANY)
- end
-
- def labels?
- params[:label_name].present?
- end
-
def milestones?
params[:milestone_title].present? || params[:milestone_wildcard_id].present?
end
@@ -160,24 +146,6 @@ class IssuableFinder
end
end
- def label_names
- if labels?
- params[:label_name].is_a?(String) ? params[:label_name].split(',') : params[:label_name]
- else
- []
- end
- end
-
- def labels
- strong_memoize(:labels) do
- if labels? && !filter_by_no_label?
- LabelsFinder.new(current_user, project_ids: projects, title: label_names).execute(skip_authorization: true) # rubocop: disable CodeReuse/Finder
- else
- Label.none
- end
- end
- end
-
def milestones
strong_memoize(:milestones) do
if milestones?
diff --git a/app/finders/issuables/label_filter.rb b/app/finders/issuables/label_filter.rb
new file mode 100644
index 00000000000..2bbc963aa90
--- /dev/null
+++ b/app/finders/issuables/label_filter.rb
@@ -0,0 +1,155 @@
+# frozen_string_literal: true
+
+module Issuables
+ class LabelFilter < BaseFilter
+ include Gitlab::Utils::StrongMemoize
+ extend Gitlab::Cache::RequestCache
+
+ def initialize(project:, group:, **kwargs)
+ @project = project
+ @group = group
+
+ super(**kwargs)
+ end
+
+ def filter(issuables)
+ filtered = by_label(issuables)
+ by_negated_label(filtered)
+ end
+
+ def label_names_excluded_from_priority_sort
+ label_names_from_params
+ end
+
+ private
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def by_label(issuables)
+ return issuables unless label_names_from_params.present?
+
+ target_model = issuables.model
+
+ if filter_by_no_label?
+ issuables.where(label_link_query(target_model).arel.exists.not)
+ elsif filter_by_any_label?
+ issuables.where(label_link_query(target_model).arel.exists)
+ else
+ issuables_with_selected_labels(issuables, label_names_from_params)
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ def by_negated_label(issuables)
+ return issuables unless label_names_from_not_params.present?
+
+ issuables_without_selected_labels(issuables, label_names_from_not_params)
+ end
+
+ def filter_by_no_label?
+ label_names_from_params.map(&:downcase).include?(FILTER_NONE)
+ end
+
+ def filter_by_any_label?
+ label_names_from_params.map(&:downcase).include?(FILTER_ANY)
+ end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def issuables_with_selected_labels(issuables, label_names)
+ target_model = issuables.model
+
+ if root_namespace
+ all_label_ids = find_label_ids(label_names)
+ # Found less labels in the DB than we were searching for. Return nothing.
+ return issuables.none if all_label_ids.size != label_names.size
+
+ all_label_ids.each do |label_ids|
+ issuables = issuables.where(label_link_query(target_model, label_ids: label_ids).arel.exists)
+ end
+ else
+ label_names.each do |label_name|
+ issuables = issuables.where(label_link_query(target_model, label_names: label_name).arel.exists)
+ end
+ end
+
+ issuables
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def issuables_without_selected_labels(issuables, label_names)
+ target_model = issuables.model
+
+ if root_namespace
+ label_ids = find_label_ids(label_names).flatten(1)
+
+ issuables.where(label_link_query(target_model, label_ids: label_ids).arel.exists.not)
+ else
+ issuables.where(label_link_query(target_model, label_names: label_names).arel.exists.not)
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def find_label_ids(label_names)
+ group_labels = Label
+ .where(project_id: nil)
+ .where(title: label_names)
+ .where(group_id: root_namespace.self_and_descendant_ids)
+
+ project_labels = Label
+ .where(group_id: nil)
+ .where(title: label_names)
+ .where(project_id: Project.select(:id).where(namespace_id: root_namespace.self_and_descendant_ids))
+
+ Label
+ .from_union([group_labels, project_labels], remove_duplicates: false)
+ .reorder(nil)
+ .pluck(:title, :id)
+ .group_by(&:first)
+ .values
+ .map { |labels| labels.map(&:last) }
+ end
+ # Avoid repeating label queries times when the finder is instantiated multiple times during the request.
+ request_cache(:find_label_ids) { root_namespace.id }
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def label_link_query(target_model, label_ids: nil, label_names: nil)
+ relation = LabelLink
+ .where(target_type: target_model.name)
+ .where(LabelLink.arel_table['target_id'].eq(target_model.arel_table['id']))
+
+ relation = relation.where(label_id: label_ids) if label_ids
+ relation = relation.joins(:label).where(labels: { name: label_names }) if label_names
+
+ relation
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ def label_names_from_params
+ return if params[:label_name].blank?
+
+ strong_memoize(:label_names_from_params) do
+ split_label_names(params[:label_name])
+ end
+ end
+
+ def label_names_from_not_params
+ return if not_params.blank? || not_params[:label_name].blank?
+
+ strong_memoize(:label_names_from_not_params) do
+ split_label_names(not_params[:label_name])
+ end
+ end
+
+ def split_label_names(label_name_param)
+ label_name_param.is_a?(String) ? label_name_param.split(',') : label_name_param
+ end
+
+ def root_namespace
+ strong_memoize(:root_namespace) do
+ (@project || @group)&.root_ancestor
+ end
+ end
+ end
+end
diff --git a/app/finders/issues_finder.rb b/app/finders/issues_finder.rb
index 7595b1c7a15..abf0c180d6b 100644
--- a/app/finders/issues_finder.rb
+++ b/app/finders/issues_finder.rb
@@ -20,6 +20,7 @@
# sort: string
# my_reaction_emoji: string
# public_only: boolean
+# include_hidden: boolean
# due_date: date or '0', '', 'overdue', 'week', or 'month'
# created_after: datetime
# created_before: datetime
@@ -47,8 +48,6 @@ class IssuesFinder < IssuableFinder
# rubocop: disable CodeReuse/ActiveRecord
def with_confidentiality_access_check
- return Issue.all if params.user_can_see_all_issues?
-
# Only admins can see hidden issues, so for non-admins, we filter out any hidden issues
issues = Issue.without_hidden
@@ -76,7 +75,9 @@ class IssuesFinder < IssuableFinder
private
def init_collection
- if params.public_only?
+ if params.include_hidden?
+ Issue.all
+ elsif params.public_only?
Issue.public_only
else
with_confidentiality_access_check
diff --git a/app/finders/issues_finder/params.rb b/app/finders/issues_finder/params.rb
index 2edd8a6f099..02b89f08f9e 100644
--- a/app/finders/issues_finder/params.rb
+++ b/app/finders/issues_finder/params.rb
@@ -6,6 +6,10 @@ class IssuesFinder
params.fetch(:public_only, false)
end
+ def include_hidden?
+ user_can_see_all_issues?
+ end
+
def filter_by_no_due_date?
due_date? && params[:due_date] == Issue::NoDueDate.name
end
diff --git a/app/finders/packages/helm/package_files_finder.rb b/app/finders/packages/helm/package_files_finder.rb
index ba400b27554..c6504d09dce 100644
--- a/app/finders/packages/helm/package_files_finder.rb
+++ b/app/finders/packages/helm/package_files_finder.rb
@@ -6,6 +6,8 @@ module Packages
DEFAULT_PACKAGE_FILES_COUNT = 20
MAX_PACKAGE_FILES_COUNT = 1000
+ delegate :most_recent!, to: :execute
+
def initialize(project, channel, params = {})
@project = project
@channel = channel
diff --git a/app/finders/packages/helm/packages_finder.rb b/app/finders/packages/helm/packages_finder.rb
new file mode 100644
index 00000000000..c58d9292e9f
--- /dev/null
+++ b/app/finders/packages/helm/packages_finder.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module Packages
+ module Helm
+ class PackagesFinder
+ include ::Packages::FinderHelper
+
+ MAX_PACKAGES_COUNT = 300
+
+ def initialize(project, channel)
+ @project = project
+ @channel = channel
+ end
+
+ def execute
+ if @channel.blank? || @project.blank?
+ return ::Packages::Package.none
+ end
+
+ pkg_files = ::Packages::PackageFile.for_helm_with_channel(@project, @channel)
+
+ # we use a subquery to get unique packages and at the same time
+ # order + limit them.
+ ::Packages::Package
+ .limit_recent(MAX_PACKAGES_COUNT)
+ .id_in(pkg_files.select(:package_id))
+ end
+ end
+ end
+end
diff --git a/app/finders/packages/npm/package_finder.rb b/app/finders/packages/npm/package_finder.rb
index 92ceac297ee..a367fda37de 100644
--- a/app/finders/packages/npm/package_finder.rb
+++ b/app/finders/packages/npm/package_finder.rb
@@ -5,18 +5,23 @@ module Packages
delegate :find_by_version, to: :execute
delegate :last, to: :execute
- def initialize(package_name, project: nil, namespace: nil)
+ # /!\ CAUTION: don't use last_of_each_version: false with find_by_version. Ordering is not
+ # guaranteed!
+ def initialize(package_name, project: nil, namespace: nil, last_of_each_version: true)
@package_name = package_name
@project = project
@namespace = namespace
+ @last_of_each_version = last_of_each_version
end
def execute
- base.npm
- .with_name(@package_name)
- .installable
- .last_of_each_version
- .preload_files
+ result = base.npm
+ .with_name(@package_name)
+ .installable
+
+ return result unless @last_of_each_version
+
+ result.last_of_each_version
end
private
diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb
index dca3d12f3c9..5537058cc79 100644
--- a/app/finders/projects_finder.rb
+++ b/app/finders/projects_finder.rb
@@ -180,12 +180,20 @@ class ProjectsFinder < UnionFinder
# rubocop: enable CodeReuse/ActiveRecord
def by_topics(items)
- params[:topic].present? ? items.tagged_with(params[:topic]) : items
+ return items unless params[:topic].present?
+
+ topics = params[:topic].instance_of?(String) ? params[:topic].strip.split(/\s*,\s*/) : params[:topic]
+ topics.each do |topic|
+ items = items.with_topic(topic)
+ end
+
+ items
end
def by_search(items)
params[:search] ||= params[:name]
+ return items if Feature.enabled?(:disable_anonymous_project_search, type: :ops) && current_user.nil?
return items.none if params[:search].present? && params[:minimum_search_length].present? && params[:search].length < params[:minimum_search_length].to_i
items.optionally_search(params[:search], include_namespace: params[:search_namespaces].present?)
diff --git a/app/finders/repositories/tree_finder.rb b/app/finders/repositories/tree_finder.rb
new file mode 100644
index 00000000000..2ea5a8856ec
--- /dev/null
+++ b/app/finders/repositories/tree_finder.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+module Repositories
+ class TreeFinder < GitRefsFinder
+ attr_reader :user_project
+
+ CommitMissingError = Class.new(StandardError)
+
+ def initialize(user_project, params = {})
+ super(user_project.repository, params)
+
+ @user_project = user_project
+ end
+
+ def execute(gitaly_pagination: false)
+ raise CommitMissingError unless commit_exists?
+
+ request_params = { recursive: recursive }
+ request_params[:pagination_params] = pagination_params if gitaly_pagination
+ tree = user_project.repository.tree(commit.id, path, **request_params)
+
+ tree.sorted_entries
+ end
+
+ def total
+ # This is inefficient and we'll look at replacing this implementation
+ Gitlab::Cache.fetch_once([user_project, repository.commit, :tree_size, commit.id, path, recursive]) do
+ user_project.repository.tree(commit.id, path, recursive: recursive).entries.size
+ end
+ end
+
+ def commit_exists?
+ commit.present?
+ end
+
+ private
+
+ def commit
+ @commit ||= user_project.commit(ref)
+ end
+
+ def ref
+ params[:ref] || user_project.default_branch
+ end
+
+ def path
+ params[:path]
+ end
+
+ def recursive
+ params[:recursive]
+ end
+
+ def pagination_params
+ {
+ limit: params[:per_page] || Kaminari.config.default_per_page,
+ page_token: params[:page_token]
+ }
+ end
+ end
+end
diff --git a/app/graphql/mutations/admin/sidekiq_queues/delete_jobs.rb b/app/graphql/mutations/admin/sidekiq_queues/delete_jobs.rb
index d943816089f..c4f91d0c15c 100644
--- a/app/graphql/mutations/admin/sidekiq_queues/delete_jobs.rb
+++ b/app/graphql/mutations/admin/sidekiq_queues/delete_jobs.rb
@@ -8,13 +8,18 @@ module Mutations
ADMIN_MESSAGE = 'You must be an admin to use this mutation'
- Gitlab::ApplicationContext::KNOWN_KEYS.each do |key|
+ ::Gitlab::ApplicationContext::KNOWN_KEYS.each do |key|
argument key,
GraphQL::Types::String,
required: false,
- description: "Delete jobs matching #{key} in the context metadata"
+ description: "Delete jobs matching #{key} in the context metadata."
end
+ argument ::Gitlab::SidekiqQueue::WORKER_KEY,
+ GraphQL::Types::String,
+ required: false,
+ description: 'Delete jobs with the given worker class.'
+
argument :queue_name,
GraphQL::Types::String,
required: true,
diff --git a/app/graphql/mutations/custom_emoji/destroy.rb b/app/graphql/mutations/custom_emoji/destroy.rb
new file mode 100644
index 00000000000..863b8152cc7
--- /dev/null
+++ b/app/graphql/mutations/custom_emoji/destroy.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module Mutations
+ module CustomEmoji
+ class Destroy < BaseMutation
+ graphql_name 'DestroyCustomEmoji'
+
+ authorize :delete_custom_emoji
+
+ field :custom_emoji,
+ Types::CustomEmojiType,
+ null: true,
+ description: 'Deleted custom emoji.'
+
+ argument :id, ::Types::GlobalIDType[::CustomEmoji],
+ required: true,
+ description: 'Global ID of the custom emoji to destroy.'
+
+ def resolve(id:)
+ custom_emoji = authorized_find!(id: id)
+
+ custom_emoji.destroy!
+
+ {
+ custom_emoji: custom_emoji
+ }
+ end
+
+ private
+
+ def find_object(id:)
+ GitlabSchema.object_from_id(id, expected_type: ::CustomEmoji)
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/customer_relations/organizations/create.rb b/app/graphql/mutations/customer_relations/organizations/create.rb
new file mode 100644
index 00000000000..3fa7b0327ca
--- /dev/null
+++ b/app/graphql/mutations/customer_relations/organizations/create.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+module Mutations
+ module CustomerRelations
+ module Organizations
+ class Create < BaseMutation
+ include ResolvesIds
+ include Gitlab::Graphql::Authorize::AuthorizeResource
+
+ graphql_name 'CustomerRelationsOrganizationCreate'
+
+ field :organization,
+ Types::CustomerRelations::OrganizationType,
+ null: true,
+ description: 'Organization after the mutation.'
+
+ argument :group_id, ::Types::GlobalIDType[::Group],
+ required: true,
+ description: 'Group for the organization.'
+
+ argument :name,
+ GraphQL::Types::String,
+ required: true,
+ description: 'Name of the organization.'
+
+ argument :default_rate,
+ GraphQL::Types::Float,
+ required: false,
+ description: 'Standard billing rate for the organization.'
+
+ argument :description,
+ GraphQL::Types::String,
+ required: false,
+ description: 'Description or notes for the organization.'
+
+ authorize :admin_organization
+
+ def resolve(args)
+ group = authorized_find!(id: args[:group_id])
+
+ raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'Feature disabled' unless Feature.enabled?(:customer_relations, group, default_enabled: :yaml)
+
+ result = ::CustomerRelations::Organizations::CreateService.new(group: group, current_user: current_user, params: args).execute
+ { organization: result.payload, errors: result.errors }
+ end
+
+ def find_object(id:)
+ GitlabSchema.object_from_id(id, expected_type: ::Group)
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/customer_relations/organizations/update.rb b/app/graphql/mutations/customer_relations/organizations/update.rb
new file mode 100644
index 00000000000..c6ae62193f9
--- /dev/null
+++ b/app/graphql/mutations/customer_relations/organizations/update.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+module Mutations
+ module CustomerRelations
+ module Organizations
+ class Update < Mutations::BaseMutation
+ include ResolvesIds
+
+ graphql_name 'CustomerRelationsOrganizationUpdate'
+
+ authorize :admin_organization
+
+ field :organization,
+ Types::CustomerRelations::OrganizationType,
+ null: false,
+ description: 'Organization after the mutation.'
+
+ argument :id, ::Types::GlobalIDType[::CustomerRelations::Organization],
+ required: true,
+ description: 'Global ID of the organization.'
+
+ argument :name,
+ GraphQL::Types::String,
+ required: false,
+ description: 'Name of the organization.'
+
+ argument :default_rate,
+ GraphQL::Types::Float,
+ required: false,
+ description: 'Standard billing rate for the organization.'
+
+ argument :description,
+ GraphQL::Types::String,
+ required: false,
+ description: 'Description or notes for the organization.'
+
+ def resolve(args)
+ organization = ::Gitlab::Graphql::Lazy.force(GitlabSchema.object_from_id(args.delete(:id), expected_type: ::CustomerRelations::Organization))
+ raise_resource_not_available_error! unless organization
+
+ group = organization.group
+ raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'Feature disabled' unless Feature.enabled?(:customer_relations, group, default_enabled: :yaml)
+
+ authorize!(group)
+
+ result = ::CustomerRelations::Organizations::UpdateService.new(group: group, current_user: current_user, params: args).execute(organization)
+ { organization: result.payload, errors: result.errors }
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/dependency_proxy/image_ttl_group_policy/update.rb b/app/graphql/mutations/dependency_proxy/image_ttl_group_policy/update.rb
new file mode 100644
index 00000000000..a5eb114b2da
--- /dev/null
+++ b/app/graphql/mutations/dependency_proxy/image_ttl_group_policy/update.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+module Mutations
+ module DependencyProxy
+ module ImageTtlGroupPolicy
+ class Update < Mutations::BaseMutation
+ include Mutations::ResolvesGroup
+
+ graphql_name 'UpdateDependencyProxyImageTtlGroupPolicy'
+
+ authorize :admin_dependency_proxy
+
+ argument :group_path,
+ GraphQL::Types::ID,
+ required: true,
+ description: 'Group path for the group dependency proxy image TTL policy.'
+
+ argument :enabled,
+ GraphQL::Types::Boolean,
+ required: false,
+ description: copy_field_description(Types::DependencyProxy::ImageTtlGroupPolicyType, :enabled)
+
+ argument :ttl,
+ GraphQL::Types::Int,
+ required: false,
+ description: copy_field_description(Types::DependencyProxy::ImageTtlGroupPolicyType, :ttl)
+
+ field :dependency_proxy_image_ttl_policy,
+ Types::DependencyProxy::ImageTtlGroupPolicyType,
+ null: true,
+ description: 'Group image TTL policy after mutation.'
+
+ def resolve(group_path:, **args)
+ group = authorized_find!(group_path: group_path)
+
+ result = ::DependencyProxy::ImageTtlGroupPolicies::UpdateService
+ .new(container: group, current_user: current_user, params: args)
+ .execute
+
+ {
+ dependency_proxy_image_ttl_policy: result.payload[:dependency_proxy_image_ttl_policy],
+ errors: result.errors
+ }
+ end
+
+ private
+
+ def find_object(group_path:)
+ resolve_group(full_path: group_path)
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/queries/repository/files.query.graphql b/app/graphql/queries/repository/files.query.graphql
index 232d98a932c..a83880ce696 100644
--- a/app/graphql/queries/repository/files.query.graphql
+++ b/app/graphql/queries/repository/files.query.graphql
@@ -23,6 +23,7 @@ query getFiles(
$nextPageCursor: String
) {
project(fullPath: $projectPath) {
+ id
__typename
repository {
__typename
diff --git a/app/graphql/queries/repository/paginated_tree.query.graphql b/app/graphql/queries/repository/paginated_tree.query.graphql
new file mode 100644
index 00000000000..e82bc6d0734
--- /dev/null
+++ b/app/graphql/queries/repository/paginated_tree.query.graphql
@@ -0,0 +1,54 @@
+fragment TreeEntry on Entry {
+ __typename
+ id
+ sha
+ name
+ flatPath
+ type
+}
+
+query getPaginatedTree($projectPath: ID!, $path: String, $ref: String!, $nextPageCursor: String) {
+ project(fullPath: $projectPath) {
+ id
+ __typename
+ repository {
+ __typename
+ paginatedTree(path: $path, ref: $ref, after: $nextPageCursor) {
+ __typename
+ pageInfo {
+ __typename
+ endCursor
+ startCursor
+ hasNextPage
+ }
+ nodes {
+ __typename
+ trees {
+ __typename
+ nodes {
+ ...TreeEntry
+ webPath
+ }
+ }
+ submodules {
+ __typename
+ nodes {
+ ...TreeEntry
+ webUrl
+ treeUrl
+ }
+ }
+ blobs {
+ __typename
+ nodes {
+ ...TreeEntry
+ mode
+ webPath
+ lfsOid
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/app/graphql/queries/repository/path_last_commit.query.graphql b/app/graphql/queries/repository/path_last_commit.query.graphql
index d845f7c6224..b5c5f653429 100644
--- a/app/graphql/queries/repository/path_last_commit.query.graphql
+++ b/app/graphql/queries/repository/path_last_commit.query.graphql
@@ -1,5 +1,6 @@
query pathLastCommit($projectPath: ID!, $path: String, $ref: String!) {
project(fullPath: $projectPath) {
+ id
__typename
repository {
__typename
diff --git a/app/graphql/queries/repository/permissions.query.graphql b/app/graphql/queries/repository/permissions.query.graphql
index c0262a882cd..6d2ae362e31 100644
--- a/app/graphql/queries/repository/permissions.query.graphql
+++ b/app/graphql/queries/repository/permissions.query.graphql
@@ -1,5 +1,6 @@
query getPermissions($projectPath: ID!) {
project(fullPath: $projectPath) {
+ id
__typename
userPermissions {
__typename
diff --git a/app/graphql/resolvers/base_resolver.rb b/app/graphql/resolvers/base_resolver.rb
index 48563633d11..20ed089d159 100644
--- a/app/graphql/resolvers/base_resolver.rb
+++ b/app/graphql/resolvers/base_resolver.rb
@@ -124,6 +124,16 @@ module Resolvers
[args[:iid], args[:iids]].any? ? 0 : 0.01
end
+ def self.before_connection_authorization(&block)
+ @before_connection_authorization_block = block
+ end
+
+ # rubocop: disable Style/TrivialAccessors
+ def self.before_connection_authorization_block
+ @before_connection_authorization_block
+ end
+ # rubocop: enable Style/TrivialAccessors
+
def offset_pagination(relation)
::Gitlab::Graphql::Pagination::OffsetPaginatedRelation.new(relation)
end
diff --git a/app/graphql/resolvers/board_list_issues_resolver.rb b/app/graphql/resolvers/board_list_issues_resolver.rb
index 25fb35ec74b..7c85dd8fb9b 100644
--- a/app/graphql/resolvers/board_list_issues_resolver.rb
+++ b/app/graphql/resolvers/board_list_issues_resolver.rb
@@ -13,15 +13,29 @@ module Resolvers
alias_method :list, :object
def resolve(**args)
- filter_params = item_filters(args[:filters]).merge(board_id: list.board.id, id: list.id)
+ filters = item_filters(args[:filters])
+ mutually_exclusive_milestone_args!(filters)
+
+ filter_params = filters.merge(board_id: list.board.id, id: list.id)
service = ::Boards::Issues::ListService.new(list.board.resource_parent, context[:current_user], filter_params)
+ pagination_connections = Gitlab::Graphql::Pagination::Keyset::Connection.new(service.execute)
+
+ ::Boards::Issues::ListService.initialize_relative_positions(list.board, current_user, pagination_connections.items)
- service.execute
+ pagination_connections
end
# https://gitlab.com/gitlab-org/gitlab/-/issues/235681
def self.complexity_multiplier(args)
0.005
end
+
+ private
+
+ def mutually_exclusive_milestone_args!(filters)
+ if filters[:milestone_title] && filters[:milestone_wildcard_id]
+ raise ::Gitlab::Graphql::Errors::ArgumentError, 'Incompatible arguments: milestoneTitle, milestoneWildcardId.'
+ end
+ end
end
end
diff --git a/app/graphql/resolvers/ci/group_runners_resolver.rb b/app/graphql/resolvers/ci/group_runners_resolver.rb
new file mode 100644
index 00000000000..e9c399d3855
--- /dev/null
+++ b/app/graphql/resolvers/ci/group_runners_resolver.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module Ci
+ class GroupRunnersResolver < RunnersResolver
+ type Types::Ci::RunnerType.connection_type, null: true
+
+ argument :membership, ::Types::Ci::RunnerMembershipFilterEnum,
+ required: false,
+ default_value: :descendants,
+ description: 'Control which runners to include in the results.'
+
+ protected
+
+ def runners_finder_params(params)
+ super(params).merge(membership: params[:membership])
+ end
+
+ def parent_param
+ raise 'Expected group missing' unless parent.is_a?(Group)
+
+ { group: parent }
+ end
+ end
+ end
+end
diff --git a/app/graphql/resolvers/ci/runners_resolver.rb b/app/graphql/resolvers/ci/runners_resolver.rb
index 1957c4ec058..07105701daa 100644
--- a/app/graphql/resolvers/ci/runners_resolver.rb
+++ b/app/graphql/resolvers/ci/runners_resolver.rb
@@ -34,7 +34,7 @@ module Resolvers
.execute)
end
- private
+ protected
def runners_finder_params(params)
{
@@ -47,6 +47,19 @@ module Resolvers
tag_name: node_selection&.selects?(:tag_list)
}
}.compact
+ .merge(parent_param)
+ end
+
+ def parent_param
+ return {} unless parent
+
+ raise "Unexpected parent type: #{parent.class}"
+ end
+
+ private
+
+ def parent
+ object.respond_to?(:sync) ? object.sync : object
end
end
end
diff --git a/app/graphql/resolvers/concerns/issue_resolver_arguments.rb b/app/graphql/resolvers/concerns/issue_resolver_arguments.rb
index 8d77c0f3a8d..9de36b5b7d1 100644
--- a/app/graphql/resolvers/concerns/issue_resolver_arguments.rb
+++ b/app/graphql/resolvers/concerns/issue_resolver_arguments.rb
@@ -30,7 +30,7 @@ module IssueResolverArguments
description: 'Usernames of users assigned to the issue.'
argument :assignee_id, GraphQL::Types::String,
required: false,
- description: 'ID of a user assigned to the issues, "none" and "any" values are supported.'
+ description: 'ID of a user assigned to the issues. Wildcard values "NONE" and "ANY" are supported.'
argument :created_before, Types::TimeType,
required: false,
description: 'Issues created before this date.'
@@ -59,6 +59,9 @@ module IssueResolverArguments
argument :milestone_wildcard_id, ::Types::MilestoneWildcardIdEnum,
required: false,
description: 'Filter issues by milestone ID wildcard.'
+ argument :my_reaction_emoji, GraphQL::Types::String,
+ required: false,
+ description: 'Filter by reaction emoji applied by the current user. Wildcard values "NONE" and "ANY" are supported.'
argument :not, Types::Issues::NegatedIssueFilterInputType,
description: 'Negated arguments.',
prepare: ->(negated_args, ctx) { negated_args.to_h },
diff --git a/app/graphql/resolvers/concerns/resolves_pipelines.rb b/app/graphql/resolvers/concerns/resolves_pipelines.rb
index 77f2105db7c..7fb0852b11e 100644
--- a/app/graphql/resolvers/concerns/resolves_pipelines.rb
+++ b/app/graphql/resolvers/concerns/resolves_pipelines.rb
@@ -17,6 +17,11 @@ module ResolvesPipelines
GraphQL::Types::String,
required: false,
description: "Filter pipelines by the sha of the commit they are run for."
+
+ argument :source,
+ GraphQL::Types::String,
+ required: false,
+ description: "Filter pipelines by their source. Will be ignored if `dast_view_scans` feature flag is disabled."
end
class_methods do
@@ -30,6 +35,8 @@ module ResolvesPipelines
end
def resolve_pipelines(project, params = {})
+ params.delete(:source) unless Feature.enabled?(:dast_view_scans, project, default_enabled: :yaml)
+
Ci::PipelinesFinder.new(project, context[:current_user], params).execute
end
end
diff --git a/app/graphql/resolvers/labels_resolver.rb b/app/graphql/resolvers/labels_resolver.rb
index 505d1dff8d2..f0e099e8fb2 100644
--- a/app/graphql/resolvers/labels_resolver.rb
+++ b/app/graphql/resolvers/labels_resolver.rb
@@ -10,7 +10,7 @@ module Resolvers
argument :search_term, GraphQL::Types::String,
required: false,
- description: 'A search term to find labels with.'
+ description: 'Search term to find labels with.'
argument :include_ancestor_groups, GraphQL::Types::Boolean,
required: false,
diff --git a/app/graphql/resolvers/merge_requests_resolver.rb b/app/graphql/resolvers/merge_requests_resolver.rb
index 8f2c7847a2e..c0dd61078c6 100644
--- a/app/graphql/resolvers/merge_requests_resolver.rb
+++ b/app/graphql/resolvers/merge_requests_resolver.rb
@@ -49,7 +49,7 @@ module Resolvers
argument :state, ::Types::MergeRequestStateEnum,
required: false,
- description: 'A merge request state. If provided, all resolved merge requests will have this state.'
+ description: 'Merge request state. If provided, all resolved merge requests will have this state.'
argument :labels, [GraphQL::Types::String],
required: false,
diff --git a/app/graphql/resolvers/milestones_resolver.rb b/app/graphql/resolvers/milestones_resolver.rb
index 84f7d66ec19..dc6d781f584 100644
--- a/app/graphql/resolvers/milestones_resolver.rb
+++ b/app/graphql/resolvers/milestones_resolver.rb
@@ -15,15 +15,15 @@ module Resolvers
argument :title, GraphQL::Types::String,
required: false,
- description: 'The title of the milestone.'
+ description: 'Title of the milestone.'
argument :search_title, GraphQL::Types::String,
required: false,
- description: 'A search string for the title.'
+ description: 'Search string for the title.'
argument :containing_date, Types::TimeType,
required: false,
- description: 'A date that the milestone contains.'
+ description: 'Date the milestone contains.'
argument :sort, Types::MilestoneSortEnum,
description: 'Sort milestones by this criteria.',
diff --git a/app/graphql/resolvers/package_details_resolver.rb b/app/graphql/resolvers/package_details_resolver.rb
index 89d79747732..42cb23e701d 100644
--- a/app/graphql/resolvers/package_details_resolver.rb
+++ b/app/graphql/resolvers/package_details_resolver.rb
@@ -6,7 +6,7 @@ module Resolvers
argument :id, ::Types::GlobalIDType[::Packages::Package],
required: true,
- description: 'The global ID of the package.'
+ description: 'Global ID of the package.'
def ready?(**args)
context[self.class] ||= { executions: 0 }
diff --git a/app/graphql/resolvers/paginated_tree_resolver.rb b/app/graphql/resolvers/paginated_tree_resolver.rb
index d1b4e75169c..6c0545d26de 100644
--- a/app/graphql/resolvers/paginated_tree_resolver.rb
+++ b/app/graphql/resolvers/paginated_tree_resolver.rb
@@ -10,11 +10,11 @@ module Resolvers
argument :path, GraphQL::Types::String,
required: false,
default_value: '', # root of the repository
- description: 'The path to get the tree for. Default value is the root of the repository.'
+ description: 'Path to get the tree for. Default value is the root of the repository.'
argument :ref, GraphQL::Types::String,
required: false,
default_value: :head,
- description: 'The commit ref to get the tree for. Default value is HEAD.'
+ description: 'Commit ref to get the tree for. Default value is HEAD.'
argument :recursive, GraphQL::Types::Boolean,
required: false,
default_value: false,
diff --git a/app/graphql/resolvers/release_resolver.rb b/app/graphql/resolvers/release_resolver.rb
index 0374a1103de..82b5647615e 100644
--- a/app/graphql/resolvers/release_resolver.rb
+++ b/app/graphql/resolvers/release_resolver.rb
@@ -6,7 +6,7 @@ module Resolvers
argument :tag_name, GraphQL::Types::String,
required: true,
- description: 'The name of the tag associated to the release.'
+ description: 'Name of the tag associated to the release.'
alias_method :project, :object
diff --git a/app/graphql/resolvers/repository_branch_names_resolver.rb b/app/graphql/resolvers/repository_branch_names_resolver.rb
index e9aacda2652..96550bce32f 100644
--- a/app/graphql/resolvers/repository_branch_names_resolver.rb
+++ b/app/graphql/resolvers/repository_branch_names_resolver.rb
@@ -8,15 +8,15 @@ module Resolvers
argument :search_pattern, GraphQL::Types::String,
required: true,
- description: 'The pattern to search for branch names by.'
+ description: 'Pattern to search for branch names by.'
argument :offset, GraphQL::Types::Int,
required: true,
- description: 'The number of branch names to skip.'
+ description: 'Number of branch names to skip.'
argument :limit, GraphQL::Types::Int,
required: true,
- description: 'The number of branch names to return.'
+ description: 'Number of branch names to return.'
def resolve(search_pattern:, offset:, limit:)
Repositories::BranchNamesFinder.new(object, offset: offset, limit: limit, search: search_pattern).execute
diff --git a/app/graphql/resolvers/snippets_resolver.rb b/app/graphql/resolvers/snippets_resolver.rb
index 7d18c9c6fea..149bd8fa1ce 100644
--- a/app/graphql/resolvers/snippets_resolver.rb
+++ b/app/graphql/resolvers/snippets_resolver.rb
@@ -12,15 +12,15 @@ module Resolvers
argument :author_id, ::Types::GlobalIDType[::User],
required: false,
- description: 'The ID of an author.'
+ description: 'ID of an author.'
argument :project_id, ::Types::GlobalIDType[::Project],
required: false,
- description: 'The ID of a project.'
+ description: 'ID of a project.'
argument :type, Types::Snippets::TypeEnum,
required: false,
- description: 'The type of snippet.'
+ description: 'Type of snippet.'
argument :explore,
GraphQL::Types::Boolean,
diff --git a/app/graphql/resolvers/todo_resolver.rb b/app/graphql/resolvers/todo_resolver.rb
index 263b190c74e..f0be1b6e9a5 100644
--- a/app/graphql/resolvers/todo_resolver.rb
+++ b/app/graphql/resolvers/todo_resolver.rb
@@ -8,27 +8,34 @@ module Resolvers
argument :action, [Types::TodoActionEnum],
required: false,
- description: 'The action to be filtered.'
+ description: 'Action to be filtered.'
argument :author_id, [GraphQL::Types::ID],
required: false,
- description: 'The ID of an author.'
+ description: 'ID of an author.'
argument :project_id, [GraphQL::Types::ID],
required: false,
- description: 'The ID of a project.'
+ description: 'ID of a project.'
argument :group_id, [GraphQL::Types::ID],
required: false,
- description: 'The ID of a group.'
+ description: 'ID of a group.'
argument :state, [Types::TodoStateEnum],
required: false,
- description: 'The state of the todo.'
+ description: 'State of the todo.'
argument :type, [Types::TodoTargetEnum],
required: false,
- description: 'The type of the todo.'
+ description: 'Type of the todo.'
+
+ before_connection_authorization do |nodes, current_user|
+ Preloaders::UserMaxAccessLevelInProjectsPreloader.new(
+ nodes.map(&:project).compact,
+ current_user
+ ).execute
+ end
def resolve(**args)
return Todo.none unless current_user.present? && target.present?
diff --git a/app/graphql/resolvers/tree_resolver.rb b/app/graphql/resolvers/tree_resolver.rb
index 70b4d81845c..8d6ece0956e 100644
--- a/app/graphql/resolvers/tree_resolver.rb
+++ b/app/graphql/resolvers/tree_resolver.rb
@@ -9,11 +9,11 @@ module Resolvers
argument :path, GraphQL::Types::String,
required: false,
default_value: '',
- description: 'The path to get the tree for. Default value is the root of the repository.'
+ description: 'Path to get the tree for. Default value is the root of the repository.'
argument :ref, GraphQL::Types::String,
required: false,
default_value: :head,
- description: 'The commit ref to get the tree for. Default value is HEAD.'
+ description: 'Commit ref to get the tree for. Default value is HEAD.'
argument :recursive, GraphQL::Types::Boolean,
required: false,
default_value: false,
diff --git a/app/graphql/resolvers/users/groups_resolver.rb b/app/graphql/resolvers/users/groups_resolver.rb
new file mode 100644
index 00000000000..0899b08e19c
--- /dev/null
+++ b/app/graphql/resolvers/users/groups_resolver.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module Users
+ class GroupsResolver < BaseResolver
+ include Gitlab::Graphql::Authorize::AuthorizeResource
+ include LooksAhead
+
+ type Types::GroupType.connection_type, null: true
+
+ authorize :read_user_groups
+ authorizes_object!
+
+ argument :search, GraphQL::Types::String,
+ required: false,
+ description: 'Search by group name or path.'
+ argument :permission_scope,
+ ::Types::PermissionTypes::GroupEnum,
+ required: false,
+ description: 'Filter by permissions the user has on groups.'
+
+ before_connection_authorization do |nodes, current_user|
+ Preloaders::UserMaxAccessLevelInGroupsPreloader.new(nodes, current_user).execute
+ end
+
+ def resolve_with_lookahead(**args)
+ return unless Feature.enabled?(:paginatable_namespace_drop_down_for_project_creation, current_user, default_enabled: :yaml)
+
+ apply_lookahead(Groups::UserGroupsFinder.new(current_user, object, args).execute)
+ end
+
+ private
+
+ def preloads
+ {
+ path: [:route],
+ full_path: [:route]
+ }
+ end
+ end
+ end
+end
+
+Resolvers::Users::GroupsResolver.prepend_mod_with('Resolvers::Users::GroupsResolver')
diff --git a/app/graphql/resolvers/users/snippets_resolver.rb b/app/graphql/resolvers/users/snippets_resolver.rb
index ee1727aadbe..75bba8debab 100644
--- a/app/graphql/resolvers/users/snippets_resolver.rb
+++ b/app/graphql/resolvers/users/snippets_resolver.rb
@@ -11,7 +11,7 @@ module Resolvers
argument :type, Types::Snippets::TypeEnum,
required: false,
- description: 'The type of snippet.'
+ description: 'Type of snippet.'
private
diff --git a/app/graphql/types/admin/analytics/usage_trends/measurement_type.rb b/app/graphql/types/admin/analytics/usage_trends/measurement_type.rb
index c54c938402d..8276549ddcc 100644
--- a/app/graphql/types/admin/analytics/usage_trends/measurement_type.rb
+++ b/app/graphql/types/admin/analytics/usage_trends/measurement_type.rb
@@ -12,13 +12,13 @@ module Types
authorize :read_usage_trends_measurement
field :recorded_at, Types::TimeType, null: true,
- description: 'The time the measurement was recorded.'
+ description: 'Time the measurement was recorded.'
field :count, GraphQL::Types::Int, null: false,
description: 'Object count.'
field :identifier, Types::Admin::Analytics::UsageTrends::MeasurementIdentifierEnum, null: false,
- description: 'The type of objects being measured.'
+ description: 'Type of objects being measured.'
end
end
end
diff --git a/app/graphql/types/admin/sidekiq_queues/delete_jobs_response_type.rb b/app/graphql/types/admin/sidekiq_queues/delete_jobs_response_type.rb
index cc6e3db007b..4f31e2f783a 100644
--- a/app/graphql/types/admin/sidekiq_queues/delete_jobs_response_type.rb
+++ b/app/graphql/types/admin/sidekiq_queues/delete_jobs_response_type.rb
@@ -17,12 +17,12 @@ module Types
field :deleted_jobs,
GraphQL::Types::Int,
null: true,
- description: 'The number of matching jobs deleted.'
+ description: 'Number of matching jobs deleted.'
field :queue_size,
GraphQL::Types::Int,
null: true,
- description: 'The queue size after processing.'
+ description: 'Queue size after processing.'
end
end
end
diff --git a/app/graphql/types/alert_management/alert_type.rb b/app/graphql/types/alert_management/alert_type.rb
index bdfdd2c5886..7495d46179c 100644
--- a/app/graphql/types/alert_management/alert_type.rb
+++ b/app/graphql/types/alert_management/alert_type.rb
@@ -115,19 +115,17 @@ module Types
null: true,
description: 'Runbook for the alert as defined in alert details.'
- field :todos, description: 'To-do items of the current user for the alert.', resolver: Resolvers::TodoResolver do
- extension(::Gitlab::Graphql::TodosProjectPermissionPreloader::FieldExtension)
- end
+ field :todos, description: 'To-do items of the current user for the alert.', resolver: Resolvers::TodoResolver
field :details_url,
GraphQL::Types::String,
null: false,
- description: 'The URL of the alert detail page.'
+ description: 'URL of the alert detail page.'
field :prometheus_alert,
Types::PrometheusAlertType,
null: true,
- description: 'The alert condition for Prometheus.'
+ description: 'Alert condition for Prometheus.'
def notes
object.ordered_notes
diff --git a/app/graphql/types/award_emojis/award_emoji_type.rb b/app/graphql/types/award_emojis/award_emoji_type.rb
index 1f6f0badcac..76415afc6c1 100644
--- a/app/graphql/types/award_emojis/award_emoji_type.rb
+++ b/app/graphql/types/award_emojis/award_emoji_type.rb
@@ -13,32 +13,32 @@ module Types
field :name,
GraphQL::Types::String,
null: false,
- description: 'The emoji name.'
+ description: 'Emoji name.'
field :description,
GraphQL::Types::String,
null: false,
- description: 'The emoji description.'
+ description: 'Emoji description.'
field :unicode,
GraphQL::Types::String,
null: false,
- description: 'The emoji in Unicode.'
+ description: 'Emoji in Unicode.'
field :emoji,
GraphQL::Types::String,
null: false,
- description: 'The emoji as an icon.'
+ description: 'Emoji as an icon.'
field :unicode_version,
GraphQL::Types::String,
null: false,
- description: 'The Unicode version for this emoji.'
+ description: 'Unicode version for this emoji.'
field :user,
Types::UserType,
null: false,
- description: 'The user who awarded the emoji.'
+ description: 'User who awarded the emoji.'
def user
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.user_id).find
diff --git a/app/graphql/types/base_field.rb b/app/graphql/types/base_field.rb
index 75fdb41ceb6..9c27f0f8138 100644
--- a/app/graphql/types/base_field.rb
+++ b/app/graphql/types/base_field.rb
@@ -9,6 +9,7 @@ module Types
DEFAULT_COMPLEXITY = 1
attr_reader :deprecation, :doc_reference
+ attr_writer :max_page_size # Can be removed with :performance_roadmap feature flag: https://gitlab.com/gitlab-org/gitlab/-/issues/337198
def initialize(**kwargs, &block)
@calls_gitaly = !!kwargs.delete(:calls_gitaly)
diff --git a/app/graphql/types/boards/board_issuable_input_base_type.rb b/app/graphql/types/boards/board_issuable_input_base_type.rb
index 326f73846d0..81dd21aebec 100644
--- a/app/graphql/types/boards/board_issuable_input_base_type.rb
+++ b/app/graphql/types/boards/board_issuable_input_base_type.rb
@@ -14,7 +14,7 @@ module Types
argument :my_reaction_emoji, GraphQL::Types::String,
required: false,
- description: 'Filter by reaction emoji applied by the current user.'
+ description: 'Filter by reaction emoji applied by the current user. Wildcard values "NONE" and "ANY" are supported.'
end
end
end
diff --git a/app/graphql/types/boards/board_issue_input_base_type.rb b/app/graphql/types/boards/board_issue_input_base_type.rb
index 82db1802b81..e12ed32a250 100644
--- a/app/graphql/types/boards/board_issue_input_base_type.rb
+++ b/app/graphql/types/boards/board_issue_input_base_type.rb
@@ -24,6 +24,10 @@ module Types
as: :issue_types,
description: 'Filter by the given issue types.',
required: false
+
+ argument :milestone_wildcard_id, ::Types::MilestoneWildcardIdEnum,
+ required: false,
+ description: 'Filter by milestone ID wildcard.'
end
end
end
diff --git a/app/graphql/types/ci/config/job_restriction_type.rb b/app/graphql/types/ci/config/job_restriction_type.rb
index 891ba18dacc..8cf0e210def 100644
--- a/app/graphql/types/ci/config/job_restriction_type.rb
+++ b/app/graphql/types/ci/config/job_restriction_type.rb
@@ -8,7 +8,7 @@ module Types
graphql_name 'CiConfigJobRestriction'
field :refs, [GraphQL::Types::String], null: true,
- description: 'The Git refs the job restriction applies to.'
+ description: 'Git refs the job restriction applies to.'
end
end
end
diff --git a/app/graphql/types/ci/config/status_enum.rb b/app/graphql/types/ci/config/status_enum.rb
index 1ba207531b8..dbb560c93c3 100644
--- a/app/graphql/types/ci/config/status_enum.rb
+++ b/app/graphql/types/ci/config/status_enum.rb
@@ -7,8 +7,8 @@ module Types
graphql_name 'CiConfigStatus'
description 'Values for YAML processor result'
- value 'VALID', 'The configuration file is valid.', value: :valid
- value 'INVALID', 'The configuration file is not valid.', value: :invalid
+ value 'VALID', 'Configuration file is valid.', value: :valid
+ value 'INVALID', 'Configuration file is not valid.', value: :invalid
end
end
end
diff --git a/app/graphql/types/ci/job_type.rb b/app/graphql/types/ci/job_type.rb
index 4a3518e1865..48bd91bfc5b 100644
--- a/app/graphql/types/ci/job_type.rb
+++ b/app/graphql/types/ci/job_type.rb
@@ -2,9 +2,10 @@
module Types
module Ci
+ # rubocop: disable Graphql/AuthorizeTypes
+ # The permission is presented through `StageType` that has its own authorization
class JobType < BaseObject
graphql_name 'CiJob'
- authorize :read_commit_status
connection_type_class(Types::CountableConnectionType)
diff --git a/app/graphql/types/ci/pipeline_type.rb b/app/graphql/types/ci/pipeline_type.rb
index 0375257eb7b..493ce188d9b 100644
--- a/app/graphql/types/ci/pipeline_type.rb
+++ b/app/graphql/types/ci/pipeline_type.rb
@@ -97,7 +97,7 @@ module Types
type: ::Types::Ci::JobType,
null: true,
authorize: :read_commit_status,
- description: 'A specific job in this pipeline, either by name or ID.' do
+ description: 'Specific job in this pipeline, either by name or ID.' do
argument :id,
type: ::Types::GlobalIDType[::CommitStatus],
required: false,
diff --git a/app/graphql/types/ci/runner_membership_filter_enum.rb b/app/graphql/types/ci/runner_membership_filter_enum.rb
new file mode 100644
index 00000000000..2e1051b2151
--- /dev/null
+++ b/app/graphql/types/ci/runner_membership_filter_enum.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module Types
+ module Ci
+ class RunnerMembershipFilterEnum < BaseEnum
+ graphql_name 'RunnerMembershipFilter'
+ description 'Values for filtering runners in namespaces.'
+
+ value 'DIRECT',
+ description: "Include runners that have a direct relationship.",
+ value: :direct
+
+ value 'DESCENDANTS',
+ description: "Include runners that have either a direct relationship or a relationship with descendants. These can be project runners or group runners (in the case where group is queried).",
+ value: :descendants
+ end
+ end
+end
diff --git a/app/graphql/types/ci/stage_type.rb b/app/graphql/types/ci/stage_type.rb
index 63357e2345b..c0d931b3d31 100644
--- a/app/graphql/types/ci/stage_type.rb
+++ b/app/graphql/types/ci/stage_type.rb
@@ -15,9 +15,8 @@ module Types
description: 'Group of jobs for the stage.'
field :detailed_status, Types::Ci::DetailedStatusType, null: true,
description: 'Detailed status of the stage.'
- field :jobs, Ci::JobType.connection_type, null: true,
- description: 'Jobs for the stage.',
- method: 'latest_statuses'
+ field :jobs, Types::Ci::JobType.connection_type, null: true,
+ description: 'Jobs for the stage.'
field :status, GraphQL::Types::String,
null: true,
description: 'Status of the pipeline stage.'
@@ -48,19 +47,25 @@ module Types
end
end
+ def jobs
+ GraphQL::Pagination::ActiveRecordRelationConnection.new(
+ object.latest_statuses,
+ max_page_size: Gitlab::CurrentSettings.current_application_settings.jobs_per_stage_page_size
+ )
+ end
+
private
# rubocop: disable CodeReuse/ActiveRecord
def jobs_for_pipeline(pipeline, stage_ids, include_needs)
- builds_results = pipeline.latest_builds.where(stage_id: stage_ids).preload(:job_artifacts, :project)
- bridges_results = pipeline.bridges.where(stage_id: stage_ids).preload(:project)
- builds_results = builds_results.preload(:needs) if include_needs
- bridges_results = bridges_results.preload(:needs) if include_needs
- commit_status_results = pipeline.latest_statuses.where(stage_id: stage_ids)
+ jobs = pipeline.statuses.latest.where(stage_id: stage_ids)
+
+ preloaded_relations = [:project, :metadata, :job_artifacts, :downstream_pipeline]
+ preloaded_relations << :needs if include_needs
- results = builds_results | bridges_results | commit_status_results
+ Preloaders::CommitStatusPreloader.new(jobs).execute(preloaded_relations)
- results.group_by(&:stage_id)
+ jobs.group_by(&:stage_id)
end
# rubocop: enable CodeReuse/ActiveRecord
end
diff --git a/app/graphql/types/ci_configuration/sast/ui_component_size_enum.rb b/app/graphql/types/ci_configuration/sast/ui_component_size_enum.rb
index 76d2a314c13..62bd3e9b2ca 100644
--- a/app/graphql/types/ci_configuration/sast/ui_component_size_enum.rb
+++ b/app/graphql/types/ci_configuration/sast/ui_component_size_enum.rb
@@ -7,9 +7,9 @@ module Types
graphql_name 'SastUiComponentSize'
description 'Size of UI component in SAST configuration page'
- value 'SMALL', description: "The size of UI component in SAST configuration page is small."
- value 'MEDIUM', description: "The size of UI component in SAST configuration page is medium."
- value 'LARGE', description: "The size of UI component in SAST configuration page is large."
+ value 'SMALL', description: "Size of UI component in SAST configuration page is small."
+ value 'MEDIUM', description: "Size of UI component in SAST configuration page is medium."
+ value 'LARGE', description: "Size of UI component in SAST configuration page is large."
end
end
end
diff --git a/app/graphql/types/commit_action_type.rb b/app/graphql/types/commit_action_type.rb
index b170134b388..6f6d6a418dc 100644
--- a/app/graphql/types/commit_action_type.rb
+++ b/app/graphql/types/commit_action_type.rb
@@ -3,7 +3,7 @@
module Types
class CommitActionType < BaseInputObject
argument :action, type: Types::CommitActionModeEnum, required: true,
- description: 'The action to perform, create, delete, move, update, chmod.'
+ description: 'Action to perform: create, delete, move, update, or chmod.'
argument :file_path, type: GraphQL::Types::String, required: true,
description: 'Full path to the file.'
argument :content, type: GraphQL::Types::String, required: false,
diff --git a/app/graphql/types/container_repository_cleanup_status_enum.rb b/app/graphql/types/container_repository_cleanup_status_enum.rb
index 6e654e65360..e9ccb8adec8 100644
--- a/app/graphql/types/container_repository_cleanup_status_enum.rb
+++ b/app/graphql/types/container_repository_cleanup_status_enum.rb
@@ -5,9 +5,9 @@ module Types
graphql_name 'ContainerRepositoryCleanupStatus'
description 'Status of the tags cleanup of a container repository'
- value 'UNSCHEDULED', value: 'cleanup_unscheduled', description: 'The tags cleanup is not scheduled. This is the default state.'
- value 'SCHEDULED', value: 'cleanup_scheduled', description: 'The tags cleanup is scheduled and is going to be executed shortly.'
- value 'UNFINISHED', value: 'cleanup_unfinished', description: 'The tags cleanup has been partially executed. There are still remaining tags to delete.'
- value 'ONGOING', value: 'cleanup_ongoing', description: 'The tags cleanup is ongoing.'
+ value 'UNSCHEDULED', value: 'cleanup_unscheduled', description: 'Tags cleanup is not scheduled. This is the default state.'
+ value 'SCHEDULED', value: 'cleanup_scheduled', description: 'Tags cleanup is scheduled and is going to be executed shortly.'
+ value 'UNFINISHED', value: 'cleanup_unfinished', description: 'Tags cleanup has been partially executed. There are still remaining tags to delete.'
+ value 'ONGOING', value: 'cleanup_ongoing', description: 'Tags cleanup is ongoing.'
end
end
diff --git a/app/graphql/types/container_repository_tag_type.rb b/app/graphql/types/container_repository_tag_type.rb
index b6b65bce421..206d6a3426c 100644
--- a/app/graphql/types/container_repository_tag_type.rb
+++ b/app/graphql/types/container_repository_tag_type.rb
@@ -14,7 +14,7 @@ module Types
field :digest, GraphQL::Types::String, null: true, description: 'Digest of the tag.'
field :revision, GraphQL::Types::String, null: true, description: 'Revision of the tag.'
field :short_revision, GraphQL::Types::String, null: true, description: 'Short revision of the tag.'
- field :total_size, GraphQL::Types::BigInt, null: true, description: 'The size of the tag.'
+ field :total_size, GraphQL::Types::BigInt, null: true, description: 'Size of the tag.'
field :created_at, Types::TimeType, null: true, description: 'Timestamp when the tag was created.'
field :can_delete, GraphQL::Types::Boolean, null: false, description: 'Can the current user delete this tag.'
diff --git a/app/graphql/types/container_repository_type.rb b/app/graphql/types/container_repository_type.rb
index 91a65053131..67093f57862 100644
--- a/app/graphql/types/container_repository_type.rb
+++ b/app/graphql/types/container_repository_type.rb
@@ -15,7 +15,7 @@ module Types
field :created_at, Types::TimeType, null: false, description: 'Timestamp when the container repository was created.'
field :updated_at, Types::TimeType, null: false, description: 'Timestamp when the container repository was updated.'
field :expiration_policy_started_at, Types::TimeType, null: true, description: 'Timestamp when the cleanup done by the expiration policy was started on the container repository.'
- field :expiration_policy_cleanup_status, Types::ContainerRepositoryCleanupStatusEnum, null: true, description: 'The tags cleanup status for the container repository.'
+ field :expiration_policy_cleanup_status, Types::ContainerRepositoryCleanupStatusEnum, null: true, description: 'Tags cleanup status for the container repository.'
field :status, Types::ContainerRepositoryStatusEnum, null: true, description: 'Status of the container repository.'
field :tags_count, GraphQL::Types::Int, null: false, description: 'Number of tags associated with this image.'
field :can_delete, GraphQL::Types::Boolean, null: false, description: 'Can the current user delete the container repository.'
diff --git a/app/graphql/types/custom_emoji_type.rb b/app/graphql/types/custom_emoji_type.rb
index 64381b3ee1e..379a0c44d67 100644
--- a/app/graphql/types/custom_emoji_type.rb
+++ b/app/graphql/types/custom_emoji_type.rb
@@ -9,16 +9,16 @@ module Types
field :id, ::Types::GlobalIDType[::CustomEmoji],
null: false,
- description: 'The ID of the emoji.'
+ description: 'ID of the emoji.'
field :name, GraphQL::Types::String,
null: false,
- description: 'The name of the emoji.'
+ description: 'Name of the emoji.'
field :url, GraphQL::Types::String,
null: false,
method: :file,
- description: 'The link to file of the emoji.'
+ description: 'Link to file of the emoji.'
field :external, GraphQL::Types::Boolean,
null: false,
diff --git a/app/graphql/types/customer_relations/contact_type.rb b/app/graphql/types/customer_relations/contact_type.rb
new file mode 100644
index 00000000000..35b5bf45698
--- /dev/null
+++ b/app/graphql/types/customer_relations/contact_type.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+module Types
+ module CustomerRelations
+ class ContactType < BaseObject
+ graphql_name 'CustomerRelationsContact'
+
+ authorize :read_contact
+
+ field :id,
+ GraphQL::Types::ID,
+ null: false,
+ description: 'Internal ID of the contact.'
+
+ field :organization, Types::CustomerRelations::OrganizationType,
+ null: true,
+ description: "Organization of the contact."
+
+ field :first_name,
+ GraphQL::Types::String,
+ null: false,
+ description: 'First name of the contact.'
+
+ field :last_name,
+ GraphQL::Types::String,
+ null: false,
+ description: 'Last name of the contact.'
+
+ field :phone,
+ GraphQL::Types::String,
+ null: true,
+ description: 'Phone number of the contact.'
+
+ field :email,
+ GraphQL::Types::String,
+ null: true,
+ description: 'Email address of the contact.'
+
+ field :description,
+ GraphQL::Types::String,
+ null: true,
+ description: 'Description or notes for the contact.'
+
+ field :created_at,
+ Types::TimeType,
+ null: false,
+ description: 'Timestamp the contact was created.'
+
+ field :updated_at,
+ Types::TimeType,
+ null: false,
+ description: 'Timestamp the contact was last updated.'
+ end
+ end
+end
diff --git a/app/graphql/types/customer_relations/organization_type.rb b/app/graphql/types/customer_relations/organization_type.rb
new file mode 100644
index 00000000000..0e091d4a9a3
--- /dev/null
+++ b/app/graphql/types/customer_relations/organization_type.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module Types
+ module CustomerRelations
+ class OrganizationType < BaseObject
+ graphql_name 'CustomerRelationsOrganization'
+
+ authorize :read_organization
+
+ field :id,
+ GraphQL::Types::ID,
+ null: false,
+ description: 'Internal ID of the organization.'
+
+ field :name,
+ GraphQL::Types::String,
+ null: false,
+ description: 'Name of the organization.'
+
+ field :default_rate,
+ GraphQL::Types::Float,
+ null: true,
+ description: 'Standard billing rate for the organization.'
+
+ field :description,
+ GraphQL::Types::String,
+ null: true,
+ description: 'Description or notes for the organization.'
+
+ field :created_at,
+ Types::TimeType,
+ null: false,
+ description: 'Timestamp the organization was created.'
+
+ field :updated_at,
+ Types::TimeType,
+ null: false,
+ description: 'Timestamp the organization was last updated.'
+ end
+ end
+end
diff --git a/app/graphql/types/dependency_proxy/blob_type.rb b/app/graphql/types/dependency_proxy/blob_type.rb
new file mode 100644
index 00000000000..f5a78fbb3ba
--- /dev/null
+++ b/app/graphql/types/dependency_proxy/blob_type.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Types
+ class DependencyProxy::BlobType < BaseObject
+ graphql_name 'DependencyProxyBlob'
+
+ description 'Dependency proxy blob'
+
+ authorize :read_dependency_proxy
+
+ field :created_at, Types::TimeType, null: false, description: 'Date of creation.'
+ field :updated_at, Types::TimeType, null: false, description: 'Date of most recent update.'
+ field :file_name, GraphQL::Types::String, null: false, description: 'Name of the blob.'
+ field :size, GraphQL::Types::String, null: false, description: 'Size of the blob file.'
+ end
+end
diff --git a/app/graphql/types/dependency_proxy/group_setting_type.rb b/app/graphql/types/dependency_proxy/group_setting_type.rb
new file mode 100644
index 00000000000..8b8b8572aa9
--- /dev/null
+++ b/app/graphql/types/dependency_proxy/group_setting_type.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Types
+ class DependencyProxy::GroupSettingType < BaseObject
+ graphql_name 'DependencyProxySetting'
+
+ description 'Group-level Dependency Proxy settings'
+
+ authorize :read_dependency_proxy
+
+ field :enabled, GraphQL::Types::Boolean, null: false, description: 'Indicates whether the dependency proxy is enabled for the group.'
+ end
+end
diff --git a/app/graphql/types/dependency_proxy/image_ttl_group_policy_type.rb b/app/graphql/types/dependency_proxy/image_ttl_group_policy_type.rb
new file mode 100644
index 00000000000..29bba7122d0
--- /dev/null
+++ b/app/graphql/types/dependency_proxy/image_ttl_group_policy_type.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Types
+ class DependencyProxy::ImageTtlGroupPolicyType < BaseObject
+ graphql_name 'DependencyProxyImageTtlGroupPolicy'
+
+ description 'Group-level Dependency Proxy TTL policy settings'
+
+ authorize :read_dependency_proxy
+
+ field :enabled, GraphQL::Types::Boolean, null: false, description: 'Indicates whether the policy is enabled or disabled.'
+ field :ttl, GraphQL::Types::Int, null: true, description: 'Number of days to retain a cached image file.'
+ field :created_at, Types::TimeType, null: true, description: 'Timestamp of creation.'
+ field :updated_at, Types::TimeType, null: true, description: 'Timestamp of the most recent update.'
+ end
+end
diff --git a/app/graphql/types/dependency_proxy/manifest_type.rb b/app/graphql/types/dependency_proxy/manifest_type.rb
new file mode 100644
index 00000000000..9aa62266ef7
--- /dev/null
+++ b/app/graphql/types/dependency_proxy/manifest_type.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module Types
+ class DependencyProxy::ManifestType < BaseObject
+ graphql_name 'DependencyProxyManifest'
+
+ description 'Dependency proxy manifest'
+
+ authorize :read_dependency_proxy
+
+ field :created_at, Types::TimeType, null: false, description: 'Date of creation.'
+ field :updated_at, Types::TimeType, null: false, description: 'Date of most recent update.'
+ field :file_name, GraphQL::Types::String, null: false, description: 'Name of the manifest.'
+ field :image_name, GraphQL::Types::String, null: false, description: 'Name of the image.'
+ field :size, GraphQL::Types::String, null: false, description: 'Size of the manifest file.'
+ field :digest, GraphQL::Types::String, null: false, description: 'Digest of the manifest.'
+
+ def image_name
+ object.file_name.chomp(File.extname(object.file_name))
+ end
+ end
+end
diff --git a/app/graphql/types/design_management/design_at_version_type.rb b/app/graphql/types/design_management/design_at_version_type.rb
index 4240b8f3aae..0dc93072e4f 100644
--- a/app/graphql/types/design_management/design_at_version_type.rb
+++ b/app/graphql/types/design_management/design_at_version_type.rb
@@ -18,12 +18,12 @@ module Types
field :version,
Types::DesignManagement::VersionType,
null: false,
- description: 'The version this design-at-versions is pinned to.'
+ description: 'Version this design-at-versions is pinned to.'
field :design,
Types::DesignManagement::DesignType,
null: false,
- description: 'The underlying design.'
+ description: 'Underlying design.'
def cached_stateful_version(_parent)
version
diff --git a/app/graphql/types/design_management/design_fields.rb b/app/graphql/types/design_management/design_fields.rb
index 7779c3f1bcb..75f1aaa8c60 100644
--- a/app/graphql/types/design_management/design_fields.rb
+++ b/app/graphql/types/design_management/design_fields.rb
@@ -7,12 +7,12 @@ module Types
field_class Types::BaseField
- field :id, GraphQL::Types::ID, description: 'The ID of this design.', null: false
- field :project, Types::ProjectType, null: false, description: 'The project the design belongs to.'
- field :issue, Types::IssueType, null: false, description: 'The issue the design belongs to.'
- field :filename, GraphQL::Types::String, null: false, description: 'The filename of the design.'
- field :full_path, GraphQL::Types::String, null: false, description: 'The full path to the design file.'
- field :image, GraphQL::Types::String, null: false, extras: [:parent], description: 'The URL of the full-sized image.'
+ field :id, GraphQL::Types::ID, description: 'ID of this design.', null: false
+ field :project, Types::ProjectType, null: false, description: 'Project the design belongs to.'
+ field :issue, Types::IssueType, null: false, description: 'Issue the design belongs to.'
+ field :filename, GraphQL::Types::String, null: false, description: 'Filename of the design.'
+ field :full_path, GraphQL::Types::String, null: false, description: 'Full path to the design file.'
+ field :image, GraphQL::Types::String, null: false, extras: [:parent], description: 'URL of the full-sized image.'
field :image_v432x230, GraphQL::Types::String, null: true, extras: [:parent],
description: 'The URL of the design resized to fit within the bounds of 432x230. ' \
'This will be `null` if the image has not been generated'
@@ -20,7 +20,7 @@ module Types
null: false,
calls_gitaly: true,
extras: [:parent],
- description: 'The diff refs for this design.'
+ description: 'Diff refs for this design.'
field :event, Types::DesignManagement::DesignVersionEventEnum,
null: false,
extras: [:parent],
@@ -29,7 +29,7 @@ module Types
GraphQL::Types::Int,
null: false,
method: :user_notes_count,
- description: 'The total count of user-created notes for this design.'
+ description: 'Total count of user-created notes for this design.'
def diff_refs(parent:)
version = cached_stateful_version(parent)
diff --git a/app/graphql/types/diff_paths_input_type.rb b/app/graphql/types/diff_paths_input_type.rb
index e1d3d58411c..cdcff1a7e34 100644
--- a/app/graphql/types/diff_paths_input_type.rb
+++ b/app/graphql/types/diff_paths_input_type.rb
@@ -3,8 +3,8 @@
module Types
class DiffPathsInputType < BaseInputObject
argument :old_path, GraphQL::Types::String, required: false,
- description: 'The path of the file on the start sha.'
+ description: 'Path of the file on the start SHA.'
argument :new_path, GraphQL::Types::String, required: false,
- description: 'The path of the file on the head sha.'
+ description: 'Path of the file on the HEAD SHA.'
end
end
diff --git a/app/graphql/types/environment_type.rb b/app/graphql/types/environment_type.rb
index 267ca944198..aba83f559fa 100644
--- a/app/graphql/types/environment_type.rb
+++ b/app/graphql/types/environment_type.rb
@@ -19,7 +19,7 @@ module Types
description: 'State of the environment, for example: available/stopped.'
field :path, GraphQL::Types::String, null: false,
- description: 'The path to the environment.'
+ description: 'Path to the environment.'
field :metrics_dashboard, Types::Metrics::DashboardType, null: true,
description: 'Metrics dashboard schema for the environment.',
@@ -28,6 +28,6 @@ module Types
field :latest_opened_most_severe_alert,
Types::AlertManagement::AlertType,
null: true,
- description: 'The most severe open alert for the environment. If multiple alerts have equal severity, the most recent is returned.'
+ description: 'Most severe open alert for the environment. If multiple alerts have equal severity, the most recent is returned.'
end
end
diff --git a/app/graphql/types/eventable_type.rb b/app/graphql/types/eventable_type.rb
index eba2154e7fa..9a02079b7ab 100644
--- a/app/graphql/types/eventable_type.rb
+++ b/app/graphql/types/eventable_type.rb
@@ -4,6 +4,6 @@ module Types
module EventableType
include Types::BaseInterface
- field :events, Types::EventType.connection_type, null: true, description: 'A list of events associated with the object.'
+ field :events, Types::EventType.connection_type, null: true, description: 'List of events associated with the object.'
end
end
diff --git a/app/graphql/types/group_type.rb b/app/graphql/types/group_type.rb
index fbf0084cd0e..8fe4ba557ea 100644
--- a/app/graphql/types/group_type.rb
+++ b/app/graphql/types/group_type.rb
@@ -33,12 +33,12 @@ module Types
type: GraphQL::Types::String,
null: true,
method: :project_creation_level_str,
- description: 'The permission level required to create projects in the group.'
+ description: 'Permission level required to create projects in the group.'
field :subgroup_creation_level,
type: GraphQL::Types::String,
null: true,
method: :subgroup_creation_level_str,
- description: 'The permission level required to create subgroups within the group.'
+ description: 'Permission level required to create subgroups within the group.'
field :require_two_factor_authentication,
type: GraphQL::Types::Boolean,
@@ -101,7 +101,7 @@ module Types
field :label,
Types::LabelType,
null: true,
- description: 'A label available on this group.' do
+ description: 'Label available on this group.' do
argument :title,
type: GraphQL::Types::String,
required: true,
@@ -128,6 +128,46 @@ module Types
description: 'Packages of the group.',
resolver: Resolvers::GroupPackagesResolver
+ field :dependency_proxy_setting,
+ Types::DependencyProxy::GroupSettingType,
+ null: true,
+ description: 'Dependency Proxy settings for the group.'
+
+ field :dependency_proxy_manifests,
+ Types::DependencyProxy::ManifestType.connection_type,
+ null: true,
+ description: 'Dependency Proxy manifests.'
+
+ field :dependency_proxy_blobs,
+ Types::DependencyProxy::BlobType.connection_type,
+ null: true,
+ description: 'Dependency Proxy blobs.'
+
+ field :dependency_proxy_image_count,
+ GraphQL::Types::Int,
+ null: false,
+ description: 'Number of dependency proxy images cached in the group.'
+
+ field :dependency_proxy_blob_count,
+ GraphQL::Types::Int,
+ null: false,
+ description: 'Number of dependency proxy blobs cached in the group.'
+
+ field :dependency_proxy_total_size,
+ GraphQL::Types::String,
+ null: false,
+ description: 'Total size of the dependency proxy cached images.'
+
+ field :dependency_proxy_image_prefix,
+ GraphQL::Types::String,
+ null: false,
+ description: 'Prefix for pulling images when using the dependency proxy.'
+
+ field :dependency_proxy_image_ttl_policy,
+ Types::DependencyProxy::ImageTtlGroupPolicyType,
+ null: true,
+ description: 'Dependency proxy TTL policy for the group.'
+
def label(title:)
BatchLoader::GraphQL.for(title).batch(key: group) do |titles, loader, args|
LabelsFinder
@@ -155,6 +195,19 @@ module Types
complexity: 5,
resolver: Resolvers::GroupsResolver
+ field :runners, Types::Ci::RunnerType.connection_type,
+ null: true,
+ resolver: Resolvers::Ci::GroupRunnersResolver,
+ description: "Find runners visible to the current user."
+
+ field :organizations, Types::CustomerRelations::OrganizationType.connection_type,
+ null: true,
+ description: "Find organizations of this group."
+
+ field :contacts, Types::CustomerRelations::ContactType.connection_type,
+ null: true,
+ description: "Find contacts of this group."
+
def avatar_url
object.avatar_url(only_path: false)
end
@@ -167,6 +220,20 @@ module Types
group.container_repositories.size
end
+ def dependency_proxy_image_count
+ group.dependency_proxy_manifests.count
+ end
+
+ def dependency_proxy_blob_count
+ group.dependency_proxy_blobs.count
+ end
+
+ def dependency_proxy_total_size
+ ActiveSupport::NumberHelper.number_to_human_size(
+ group.dependency_proxy_manifests.sum(:size) + group.dependency_proxy_blobs.sum(:size)
+ )
+ end
+
private
def group
diff --git a/app/graphql/types/issue_sort_enum.rb b/app/graphql/types/issue_sort_enum.rb
index a2390ff01fe..f8825ff6c46 100644
--- a/app/graphql/types/issue_sort_enum.rb
+++ b/app/graphql/types/issue_sort_enum.rb
@@ -10,6 +10,8 @@ module Types
value 'RELATIVE_POSITION_ASC', 'Relative position by ascending order.', value: :relative_position_asc
value 'SEVERITY_ASC', 'Severity from less critical to more critical.', value: :severity_asc
value 'SEVERITY_DESC', 'Severity from more critical to less critical.', value: :severity_desc
+ value 'TITLE_ASC', 'Title by ascending order.', value: :title_asc
+ value 'TITLE_DESC', 'Title by descending order.', value: :title_desc
value 'POPULARITY_ASC', 'Number of upvotes (awarded "thumbs up" emoji) by ascending order.', value: :popularity_asc
value 'POPULARITY_DESC', 'Number of upvotes (awarded "thumbs up" emoji) by descending order.', value: :popularity_desc
end
diff --git a/app/graphql/types/issue_type.rb b/app/graphql/types/issue_type.rb
index 42feb8a8076..c8db2b84ff2 100644
--- a/app/graphql/types/issue_type.rb
+++ b/app/graphql/types/issue_type.rb
@@ -53,6 +53,9 @@ module Types
description: 'Due date of the issue.'
field :confidential, GraphQL::Types::Boolean, null: false,
description: 'Indicates the issue is confidential.'
+ field :hidden, GraphQL::Types::Boolean, null: true, resolver_method: :hidden?,
+ description: 'Indicates the issue is hidden because the author has been banned. ' \
+ 'Will always return `null` if `ban_user_feature_flag` feature flag is disabled.'
field :discussion_locked, GraphQL::Types::Boolean, null: false,
description: 'Indicates discussion is locked on the issue.'
@@ -156,6 +159,10 @@ module Types
def create_note_email
object.creatable_note_email_address(context[:current_user])
end
+
+ def hidden?
+ object.hidden? if Feature.enabled?(:ban_user_feature_flag)
+ end
end
end
diff --git a/app/graphql/types/issues/negated_issue_filter_input_type.rb b/app/graphql/types/issues/negated_issue_filter_input_type.rb
index e5125c554a4..4f620a5b3d9 100644
--- a/app/graphql/types/issues/negated_issue_filter_input_type.rb
+++ b/app/graphql/types/issues/negated_issue_filter_input_type.rb
@@ -14,6 +14,9 @@ module Types
argument :milestone_title, [GraphQL::Types::String],
required: false,
description: 'Milestone not applied to this issue.'
+ argument :author_username, GraphQL::Types::String,
+ required: false,
+ description: "Username of a user who didn't author the issue."
argument :assignee_usernames, [GraphQL::Types::String],
required: false,
description: 'Usernames of users not assigned to the issue.'
@@ -23,6 +26,9 @@ module Types
argument :milestone_wildcard_id, ::Types::NegatedMilestoneWildcardIdEnum,
required: false,
description: 'Filter by negated milestone wildcard values.'
+ argument :my_reaction_emoji, GraphQL::Types::String,
+ required: false,
+ description: 'Filter by reaction emoji applied by the current user.'
end
end
end
diff --git a/app/graphql/types/merge_request_type.rb b/app/graphql/types/merge_request_type.rb
index 8e6b5421ede..004ac364487 100644
--- a/app/graphql/types/merge_request_type.rb
+++ b/app/graphql/types/merge_request_type.rb
@@ -64,7 +64,7 @@ module Types
description: 'Diff head SHA of the merge request.'
field :diff_stats, [Types::DiffStatsType], null: true, calls_gitaly: true,
description: 'Details about which files were changed in this merge request.' do
- argument :path, GraphQL::Types::String, required: false, description: 'A specific file-path.'
+ argument :path, GraphQL::Types::String, required: false, description: 'Specific file path.'
end
field :diff_stats_summary, Types::DiffStatsSummaryType, null: true, calls_gitaly: true,
@@ -129,14 +129,14 @@ module Types
description: 'Number of downvotes for the merge request.'
field :head_pipeline, Types::Ci::PipelineType, null: true, method: :actual_head_pipeline,
- description: 'The pipeline running on the branch HEAD of the merge request.'
+ description: 'Pipeline running on the branch HEAD of the merge request.'
field :pipelines,
null: true,
description: 'Pipelines for the merge request. Note: for performance reasons, no more than the most recent 500 pipelines will be returned.',
resolver: Resolvers::MergeRequestPipelinesResolver
field :milestone, Types::MilestoneType, null: true,
- description: 'The milestone of the merge request.'
+ description: 'Milestone of the merge request.'
field :assignees,
type: Types::MergeRequests::AssigneeType.connection_type,
null: true,
diff --git a/app/graphql/types/metadata/kas_type.rb b/app/graphql/types/metadata/kas_type.rb
index a947986fa60..54a8a6ec40d 100644
--- a/app/graphql/types/metadata/kas_type.rb
+++ b/app/graphql/types/metadata/kas_type.rb
@@ -12,7 +12,7 @@ module Types
field :version, GraphQL::Types::String, null: true,
description: 'KAS version.'
field :external_url, GraphQL::Types::String, null: true,
- description: 'The URL used by the Agents to communicate with KAS.'
+ description: 'URL used by the Agents to communicate with KAS.'
end
end
end
diff --git a/app/graphql/types/milestone_wildcard_id_enum.rb b/app/graphql/types/milestone_wildcard_id_enum.rb
index b5b339b1e5b..12e8e07fb05 100644
--- a/app/graphql/types/milestone_wildcard_id_enum.rb
+++ b/app/graphql/types/milestone_wildcard_id_enum.rb
@@ -6,8 +6,8 @@ module Types
description 'Milestone ID wildcard values'
value 'NONE', 'No milestone is assigned.'
- value 'ANY', 'A milestone is assigned.'
- value 'STARTED', 'An open, started milestone (start date <= today).'
- value 'UPCOMING', 'An open milestone due in the future (due date >= today).'
+ value 'ANY', 'Milestone is assigned.'
+ value 'STARTED', 'Milestone assigned is open and started (start date <= today).'
+ value 'UPCOMING', 'Milestone assigned is due closest in the future (due date > today).'
end
end
diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb
index 293d19d068a..ea50af1c554 100644
--- a/app/graphql/types/mutation_type.rb
+++ b/app/graphql/types/mutation_type.rb
@@ -33,7 +33,11 @@ module Types
mount_mutation Mutations::Branches::Create, calls_gitaly: true
mount_mutation Mutations::Commits::Create, calls_gitaly: true
mount_mutation Mutations::CustomEmoji::Create, feature_flag: :custom_emoji
+ mount_mutation Mutations::CustomEmoji::Destroy, feature_flag: :custom_emoji
+ mount_mutation Mutations::CustomerRelations::Organizations::Create
+ mount_mutation Mutations::CustomerRelations::Organizations::Update
mount_mutation Mutations::Discussions::ToggleResolve
+ mount_mutation Mutations::DependencyProxy::ImageTtlGroupPolicy::Update
mount_mutation Mutations::Environments::CanaryIngress::Update
mount_mutation Mutations::Issues::Create
mount_mutation Mutations::Issues::SetAssignees
@@ -103,9 +107,9 @@ module Types
mount_mutation Mutations::Ci::Job::Unschedule
mount_mutation Mutations::Ci::JobTokenScope::AddProject
mount_mutation Mutations::Ci::JobTokenScope::RemoveProject
- mount_mutation Mutations::Ci::Runner::Update, feature_flag: :runner_graphql_query
- mount_mutation Mutations::Ci::Runner::Delete, feature_flag: :runner_graphql_query
- mount_mutation Mutations::Ci::RunnersRegistrationToken::Reset, feature_flag: :runner_graphql_query
+ mount_mutation Mutations::Ci::Runner::Update
+ mount_mutation Mutations::Ci::Runner::Delete
+ mount_mutation Mutations::Ci::RunnersRegistrationToken::Reset
mount_mutation Mutations::Namespace::PackageSettings::Update
mount_mutation Mutations::Groups::Update
mount_mutation Mutations::UserCallouts::Create
diff --git a/app/graphql/types/namespace_type.rb b/app/graphql/types/namespace_type.rb
index 4cc543f477a..3c5994ac559 100644
--- a/app/graphql/types/namespace_type.rb
+++ b/app/graphql/types/namespace_type.rb
@@ -40,7 +40,7 @@ module Types
field :package_settings,
Types::Namespace::PackageSettingsType,
null: true,
- description: 'The package settings for the namespace.'
+ description: 'Package settings for the namespace.'
field :shared_runners_setting,
Types::Namespace::SharedRunnersSettingEnum,
diff --git a/app/graphql/types/negated_milestone_wildcard_id_enum.rb b/app/graphql/types/negated_milestone_wildcard_id_enum.rb
index ca27a6c7b6e..9e9f561677a 100644
--- a/app/graphql/types/negated_milestone_wildcard_id_enum.rb
+++ b/app/graphql/types/negated_milestone_wildcard_id_enum.rb
@@ -5,7 +5,7 @@ module Types
graphql_name 'NegatedMilestoneWildcardId'
description 'Negated Milestone ID wildcard values'
- value 'STARTED', 'An open, started milestone (start date <= today).'
- value 'UPCOMING', 'An open milestone due in the future (due date >= today).'
+ value 'STARTED', 'Milestone assigned is open and yet to be started (start date > today).'
+ value 'UPCOMING', 'Milestone assigned is open but due in the past (due date <= today).'
end
end
diff --git a/app/graphql/types/notes/note_type.rb b/app/graphql/types/notes/note_type.rb
index fa33428114c..da6ea83401d 100644
--- a/app/graphql/types/notes/note_type.rb
+++ b/app/graphql/types/notes/note_type.rb
@@ -40,9 +40,9 @@ module Types
field :updated_at, Types::TimeType, null: false,
description: "Timestamp of the note's last activity."
field :discussion, Types::Notes::DiscussionType, null: true,
- description: 'The discussion this note is a part of.'
+ description: 'Discussion this note is a part of.'
field :position, Types::Notes::DiffPositionType, null: true,
- description: 'The position of this note on a diff.'
+ description: 'Position of this note on a diff.'
field :confidential, GraphQL::Types::Boolean, null: true,
description: 'Indicates if this note is confidential.',
method: :confidential?
diff --git a/app/graphql/types/notes/position_type_enum.rb b/app/graphql/types/notes/position_type_enum.rb
index 18934636670..157b0b4b884 100644
--- a/app/graphql/types/notes/position_type_enum.rb
+++ b/app/graphql/types/notes/position_type_enum.rb
@@ -6,7 +6,7 @@ module Types
graphql_name 'DiffPositionType'
description 'Type of file the position refers to'
- value 'text', description: "A text file."
+ value 'text', description: "Text file."
value 'image', description: "An image."
end
end
diff --git a/app/graphql/types/packages/composer/json_type.rb b/app/graphql/types/packages/composer/json_type.rb
index d2bd62ca74d..6c121043301 100644
--- a/app/graphql/types/packages/composer/json_type.rb
+++ b/app/graphql/types/packages/composer/json_type.rb
@@ -8,10 +8,10 @@ module Types
graphql_name 'PackageComposerJsonType'
description 'Represents a composer JSON file'
- field :name, GraphQL::Types::String, null: true, description: 'The name set in the Composer JSON file.'
- field :type, GraphQL::Types::String, null: true, description: 'The type set in the Composer JSON file.'
- field :license, GraphQL::Types::String, null: true, description: 'The license set in the Composer JSON file.'
- field :version, GraphQL::Types::String, null: true, description: 'The version set in the Composer JSON file.'
+ field :name, GraphQL::Types::String, null: true, description: 'Name set in the Composer JSON file.'
+ field :type, GraphQL::Types::String, null: true, description: 'Type set in the Composer JSON file.'
+ field :license, GraphQL::Types::String, null: true, description: 'License set in the Composer JSON file.'
+ field :version, GraphQL::Types::String, null: true, description: 'Version set in the Composer JSON file.'
end
end
end
diff --git a/app/graphql/types/packages/package_details_type.rb b/app/graphql/types/packages/package_details_type.rb
index f52b1f02519..59a4885e87e 100644
--- a/app/graphql/types/packages/package_details_type.rb
+++ b/app/graphql/types/packages/package_details_type.rb
@@ -8,7 +8,7 @@ module Types
authorize :read_package
field :versions, ::Types::Packages::PackageType.connection_type, null: true,
- description: 'The other versions of the package.'
+ description: 'Other versions of the package.'
field :package_files, Types::Packages::PackageFileType.connection_type, null: true, description: 'Package files.'
diff --git a/app/graphql/types/packages/package_file_type.rb b/app/graphql/types/packages/package_file_type.rb
index f77c40de8d8..8cc0f9b984a 100644
--- a/app/graphql/types/packages/package_file_type.rb
+++ b/app/graphql/types/packages/package_file_type.rb
@@ -8,8 +8,8 @@ module Types
authorize :read_package
field :id, ::Types::GlobalIDType[::Packages::PackageFile], null: false, description: 'ID of the file.'
- field :created_at, Types::TimeType, null: false, description: 'The created date.'
- field :updated_at, Types::TimeType, null: false, description: 'The updated date.'
+ field :created_at, Types::TimeType, null: false, description: 'Created date.'
+ field :updated_at, Types::TimeType, null: false, description: 'Updated date.'
field :size, GraphQL::Types::String, null: false, description: 'Size of the package file.'
field :file_name, GraphQL::Types::String, null: false, description: 'Name of the package file.'
field :download_path, GraphQL::Types::String, null: false, description: 'Download path of the package file.'
diff --git a/app/graphql/types/packages/package_tag_type.rb b/app/graphql/types/packages/package_tag_type.rb
index 450f3fc8e9c..f1f96c42e27 100644
--- a/app/graphql/types/packages/package_tag_type.rb
+++ b/app/graphql/types/packages/package_tag_type.rb
@@ -7,10 +7,10 @@ module Types
description 'Represents a package tag'
authorize :read_package
- field :id, GraphQL::Types::ID, null: false, description: 'The ID of the tag.'
- field :name, GraphQL::Types::String, null: false, description: 'The name of the tag.'
- field :created_at, Types::TimeType, null: false, description: 'The created date.'
- field :updated_at, Types::TimeType, null: false, description: 'The updated date.'
+ field :id, GraphQL::Types::ID, null: false, description: 'ID of the tag.'
+ field :name, GraphQL::Types::String, null: false, description: 'Name of the tag.'
+ field :created_at, Types::TimeType, null: false, description: 'Created date.'
+ field :updated_at, Types::TimeType, null: false, description: 'Updated date.'
end
end
end
diff --git a/app/graphql/types/packages/package_type.rb b/app/graphql/types/packages/package_type.rb
index b8654ebd2c6..f3fa79cc08c 100644
--- a/app/graphql/types/packages/package_type.rb
+++ b/app/graphql/types/packages/package_type.rb
@@ -23,7 +23,7 @@ module Types
field :metadata, Types::Packages::MetadataType, null: true,
description: 'Package metadata.'
field :versions, ::Types::Packages::PackageType.connection_type, null: true,
- description: 'The other versions of the package.',
+ description: 'Other versions of the package.',
deprecated: { reason: 'This field is now only returned in the PackageDetailsType', milestone: '13.11' }
field :status, Types::Packages::PackageStatusEnum, null: false, description: 'Package status.'
diff --git a/app/graphql/types/permission_types/custom_emoji.rb b/app/graphql/types/permission_types/custom_emoji.rb
index 0b2e7da44f5..61ff85f665d 100644
--- a/app/graphql/types/permission_types/custom_emoji.rb
+++ b/app/graphql/types/permission_types/custom_emoji.rb
@@ -5,7 +5,7 @@ module Types
class CustomEmoji < BasePermissionType
graphql_name 'CustomEmojiPermissions'
- abilities :create_custom_emoji, :read_custom_emoji
+ abilities :create_custom_emoji, :read_custom_emoji, :delete_custom_emoji
end
end
end
diff --git a/app/graphql/types/permission_types/group.rb b/app/graphql/types/permission_types/group.rb
index 29833993ce6..6a1031e2532 100644
--- a/app/graphql/types/permission_types/group.rb
+++ b/app/graphql/types/permission_types/group.rb
@@ -5,7 +5,7 @@ module Types
class Group < BasePermissionType
graphql_name 'GroupPermissions'
- abilities :read_group
+ abilities :read_group, :create_projects
end
end
end
diff --git a/app/graphql/types/permission_types/group_enum.rb b/app/graphql/types/permission_types/group_enum.rb
new file mode 100644
index 00000000000..cc4f5e9f1f0
--- /dev/null
+++ b/app/graphql/types/permission_types/group_enum.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Types
+ module PermissionTypes
+ class GroupEnum < BaseEnum
+ graphql_name 'GroupPermission'
+ description 'User permission on groups'
+
+ value 'CREATE_PROJECTS', value: :create_projects, description: 'Groups where the user can create projects.'
+ end
+ end
+end
diff --git a/app/graphql/types/project_statistics_type.rb b/app/graphql/types/project_statistics_type.rb
index ee8476f50de..60a3d5ce06b 100644
--- a/app/graphql/types/project_statistics_type.rb
+++ b/app/graphql/types/project_statistics_type.rb
@@ -23,6 +23,8 @@ module Types
description: 'Wiki size of the project in bytes.'
field :snippets_size, GraphQL::FLOAT_TYPE, null: true,
description: 'Snippets size of the project in bytes.'
+ field :pipeline_artifacts_size, GraphQL::FLOAT_TYPE, null: true,
+ description: 'CI Pipeline artifacts size in bytes.'
field :uploads_size, GraphQL::FLOAT_TYPE, null: true,
description: 'Uploads size of the project in bytes.'
end
diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb
index af1f1c54ec2..aef46a05a2f 100644
--- a/app/graphql/types/project_type.rb
+++ b/app/graphql/types/project_type.rb
@@ -118,7 +118,7 @@ module Types
field :autoclose_referenced_issues, GraphQL::Types::Boolean, null: true,
description: 'Indicates if issues referenced by merge requests and commits within the default branch are closed automatically.'
field :suggestion_commit_message, GraphQL::Types::String, null: true,
- description: 'The commit message used to apply merge request suggestions.'
+ description: 'Commit message used to apply merge request suggestions.'
field :squash_read_only, GraphQL::Types::Boolean, null: false, method: :squash_readonly?,
description: 'Indicates if `squashReadOnly` is enabled.'
@@ -310,7 +310,7 @@ module Types
field :container_expiration_policy,
Types::ContainerExpirationPolicyType,
null: true,
- description: 'The container expiration policy of the project.'
+ description: 'Container expiration policy of the project.'
field :container_repositories,
Types::ContainerRepositoryType.connection_type,
@@ -324,7 +324,7 @@ module Types
field :label,
Types::LabelType,
null: true,
- description: 'A label available on this project.' do
+ description: 'Label available on this project.' do
argument :title, GraphQL::Types::String,
required: true,
description: 'Title of the label.'
@@ -406,6 +406,10 @@ module Types
object.topic_list
end
+ def topics
+ object.topic_list
+ end
+
private
def project
diff --git a/app/graphql/types/prometheus_alert_type.rb b/app/graphql/types/prometheus_alert_type.rb
index 8327848032a..789f1d6eb5f 100644
--- a/app/graphql/types/prometheus_alert_type.rb
+++ b/app/graphql/types/prometheus_alert_type.rb
@@ -15,6 +15,6 @@ module Types
field :humanized_text,
GraphQL::Types::String,
null: false,
- description: 'The human-readable text of the alert condition.'
+ description: 'Human-readable text of the alert condition.'
end
end
diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb
index 7e9cd615719..e02191fbf3e 100644
--- a/app/graphql/types/query_type.rb
+++ b/app/graphql/types/query_type.rb
@@ -62,7 +62,7 @@ module Types
argument :id,
type: ::Types::GlobalIDType[::ContainerRepository],
required: true,
- description: 'The global ID of the container repository.'
+ description: 'Global ID of the container repository.'
end
field :package,
@@ -84,13 +84,13 @@ module Types
field :issue, Types::IssueType,
null: true,
description: 'Find an issue.' do
- argument :id, ::Types::GlobalIDType[::Issue], required: true, description: 'The global ID of the issue.'
+ argument :id, ::Types::GlobalIDType[::Issue], required: true, description: 'Global ID of the issue.'
end
field :merge_request, Types::MergeRequestType,
null: true,
description: 'Find a merge request.' do
- argument :id, ::Types::GlobalIDType[::MergeRequest], required: true, description: 'The global ID of the merge request.'
+ argument :id, ::Types::GlobalIDType[::MergeRequest], required: true, description: 'Global ID of the merge request.'
end
field :instance_statistics_measurements,
@@ -120,14 +120,12 @@ module Types
null: true,
resolver: Resolvers::Ci::RunnerResolver,
extras: [:lookahead],
- description: "Find a runner.",
- feature_flag: :runner_graphql_query
+ description: "Find a runner."
field :runners, Types::Ci::RunnerType.connection_type,
null: true,
resolver: Resolvers::Ci::RunnersResolver,
- description: "Find runners visible to the current user.",
- feature_flag: :runner_graphql_query
+ description: "Find runners visible to the current user."
field :ci_config, resolver: Resolvers::Ci::ConfigResolver, complexity: 126 # AUTHENTICATED_MAX_COMPLEXITY / 2 + 1
diff --git a/app/graphql/types/range_input_type.rb b/app/graphql/types/range_input_type.rb
index e31b8ecd811..9580b37d6c0 100644
--- a/app/graphql/types/range_input_type.rb
+++ b/app/graphql/types/range_input_type.rb
@@ -8,11 +8,11 @@ module Types
@subtypes[[type, closed]] ||= Class.new(self) do
argument :start, type,
required: closed,
- description: 'The start of the range.'
+ description: 'Start of the range.'
argument :end, type,
required: closed,
- description: 'The end of the range.'
+ description: 'End of the range.'
end
end
diff --git a/app/graphql/types/release_asset_link_shared_input_arguments.rb b/app/graphql/types/release_asset_link_shared_input_arguments.rb
index 37a6cdd55c9..f622a11deea 100644
--- a/app/graphql/types/release_asset_link_shared_input_arguments.rb
+++ b/app/graphql/types/release_asset_link_shared_input_arguments.rb
@@ -19,7 +19,7 @@ module Types
argument :link_type, Types::ReleaseAssetLinkTypeEnum,
required: false, default_value: 'other',
- description: 'The type of the asset link.'
+ description: 'Type of the asset link.'
end
end
end
diff --git a/app/graphql/types/release_assets_input_type.rb b/app/graphql/types/release_assets_input_type.rb
index 2c8d3de3495..0e591dd3742 100644
--- a/app/graphql/types/release_assets_input_type.rb
+++ b/app/graphql/types/release_assets_input_type.rb
@@ -7,6 +7,6 @@ module Types
argument :links, [Types::ReleaseAssetLinkInputType],
required: false,
- description: 'A list of asset links to associate to the release.'
+ description: 'List of asset links to associate to the release.'
end
end
diff --git a/app/graphql/types/release_type.rb b/app/graphql/types/release_type.rb
index 5e8f00b2b0a..6dda93c7329 100644
--- a/app/graphql/types/release_type.rb
+++ b/app/graphql/types/release_type.rb
@@ -49,7 +49,7 @@ module Types
field :commit, Types::CommitType, null: true,
complexity: 10, calls_gitaly: true,
- description: 'The commit associated with the release.'
+ description: 'Commit associated with the release.'
def commit
return if release.sha.nil?
diff --git a/app/graphql/types/repository/blob_type.rb b/app/graphql/types/repository/blob_type.rb
index b6a1a91fd7a..ef7f535212f 100644
--- a/app/graphql/types/repository/blob_type.rb
+++ b/app/graphql/types/repository/blob_type.rb
@@ -48,10 +48,10 @@ module Types
description: 'Size (in bytes) of the blob, or the blob target if stored externally.'
field :raw_blob, GraphQL::Types::String, null: true, method: :data,
- description: 'The raw content of the blob.'
+ description: 'Raw content of the blob.'
field :raw_text_blob, GraphQL::Types::String, null: true, method: :text_only_data,
- description: 'The raw content of the blob, if the blob is text data.'
+ description: 'Raw content of the blob, if the blob is text data.'
field :stored_externally, GraphQL::Types::Boolean, null: true, method: :stored_externally?,
description: "Whether the blob's content is stored externally (for instance, in LFS)."
@@ -69,7 +69,7 @@ module Types
description: 'Web path to replace the blob content.'
field :file_type, GraphQL::Types::String, null: true,
- description: 'The expected format of the blob based on the extension.'
+ description: 'Expected format of the blob based on the extension.'
field :simple_viewer, type: Types::BlobViewerType,
description: 'Blob content simple viewer.',
diff --git a/app/graphql/types/root_storage_statistics_type.rb b/app/graphql/types/root_storage_statistics_type.rb
index 102639f19d9..47ca195cc4b 100644
--- a/app/graphql/types/root_storage_statistics_type.rb
+++ b/app/graphql/types/root_storage_statistics_type.rb
@@ -6,14 +6,14 @@ module Types
authorize :read_statistics
- field :storage_size, GraphQL::FLOAT_TYPE, null: false, description: 'The total storage in bytes.'
- field :repository_size, GraphQL::FLOAT_TYPE, null: false, description: 'The Git repository size in bytes.'
- field :lfs_objects_size, GraphQL::FLOAT_TYPE, null: false, description: 'The LFS objects size in bytes.'
- field :build_artifacts_size, GraphQL::FLOAT_TYPE, null: false, description: 'The CI artifacts size in bytes.'
- field :packages_size, GraphQL::FLOAT_TYPE, null: false, description: 'The packages size in bytes.'
- field :wiki_size, GraphQL::FLOAT_TYPE, null: false, description: 'The wiki size in bytes.'
- field :snippets_size, GraphQL::FLOAT_TYPE, null: false, description: 'The snippets size in bytes.'
- field :pipeline_artifacts_size, GraphQL::FLOAT_TYPE, null: false, description: 'The CI pipeline artifacts size in bytes.'
- field :uploads_size, GraphQL::FLOAT_TYPE, null: false, description: 'The uploads size in bytes.'
+ field :storage_size, GraphQL::FLOAT_TYPE, null: false, description: 'Total storage in bytes.'
+ field :repository_size, GraphQL::FLOAT_TYPE, null: false, description: 'Git repository size in bytes.'
+ field :lfs_objects_size, GraphQL::FLOAT_TYPE, null: false, description: 'LFS objects size in bytes.'
+ field :build_artifacts_size, GraphQL::FLOAT_TYPE, null: false, description: 'CI artifacts size in bytes.'
+ field :packages_size, GraphQL::FLOAT_TYPE, null: false, description: 'Packages size in bytes.'
+ field :wiki_size, GraphQL::FLOAT_TYPE, null: false, description: 'Wiki size in bytes.'
+ field :snippets_size, GraphQL::FLOAT_TYPE, null: false, description: 'Snippets size in bytes.'
+ field :pipeline_artifacts_size, GraphQL::FLOAT_TYPE, null: false, description: 'CI pipeline artifacts size in bytes.'
+ field :uploads_size, GraphQL::FLOAT_TYPE, null: false, description: 'Uploads size in bytes.'
end
end
diff --git a/app/graphql/types/snippet_type.rb b/app/graphql/types/snippet_type.rb
index c345aea08bd..7b96cc34941 100644
--- a/app/graphql/types/snippet_type.rb
+++ b/app/graphql/types/snippet_type.rb
@@ -22,7 +22,7 @@ module Types
null: false
field :project, Types::ProjectType,
- description: 'The project the snippet is associated with.',
+ description: 'Project the snippet is associated with.',
null: true,
authorize: :read_project
@@ -30,7 +30,7 @@ module Types
# when the admin setting restricted visibility
# level is set to public
field :author, Types::UserType,
- description: 'The owner of the snippet.',
+ description: 'Owner of the snippet.',
null: true
field :file_name, GraphQL::Types::String,
diff --git a/app/graphql/types/snippets/blob_type.rb b/app/graphql/types/snippets/blob_type.rb
index d5da271d936..2b9b76a6194 100644
--- a/app/graphql/types/snippets/blob_type.rb
+++ b/app/graphql/types/snippets/blob_type.rb
@@ -17,7 +17,7 @@ module Types
null: true
field :raw_plain_data, GraphQL::Types::String,
- description: 'The raw content of the blob, if the blob is text data.',
+ description: 'Raw content of the blob, if the blob is text data.',
null: true
field :raw_path, GraphQL::Types::String,
diff --git a/app/graphql/types/snippets/visibility_scopes_enum.rb b/app/graphql/types/snippets/visibility_scopes_enum.rb
index ddcc005eaf2..b2c1d5cf06b 100644
--- a/app/graphql/types/snippets/visibility_scopes_enum.rb
+++ b/app/graphql/types/snippets/visibility_scopes_enum.rb
@@ -3,9 +3,9 @@
module Types
module Snippets
class VisibilityScopesEnum < BaseEnum
- value 'private', description: 'The snippet is visible only to the snippet creator.', value: 'are_private'
- value 'internal', description: 'The snippet is visible for any logged in user except external users.', value: 'are_internal'
- value 'public', description: 'The snippet can be accessed without any authentication.', value: 'are_public'
+ value 'private', description: 'Snippet is visible only to the snippet creator.', value: 'are_private'
+ value 'internal', description: 'Snippet is visible for any logged in user except external users.', value: 'are_internal'
+ value 'public', description: 'Snippet can be accessed without any authentication.', value: 'are_public'
end
end
end
diff --git a/app/graphql/types/terraform/state_type.rb b/app/graphql/types/terraform/state_type.rb
index cbd5aeaeef9..bce34a85f85 100644
--- a/app/graphql/types/terraform/state_type.rb
+++ b/app/graphql/types/terraform/state_type.rb
@@ -19,7 +19,7 @@ module Types
field :locked_by_user, Types::UserType,
null: true,
- description: 'The user currently holding a lock on the Terraform state.'
+ description: 'User currently holding a lock on the Terraform state.'
field :locked_at, Types::TimeType,
null: true,
@@ -28,7 +28,7 @@ module Types
field :latest_version, Types::Terraform::StateVersionType,
complexity: 3,
null: true,
- description: 'The latest version of the Terraform state.'
+ description: 'Latest version of the Terraform state.'
field :created_at, Types::TimeType,
null: false,
diff --git a/app/graphql/types/terraform/state_version_type.rb b/app/graphql/types/terraform/state_version_type.rb
index 545b3c0044d..bf1af4565bc 100644
--- a/app/graphql/types/terraform/state_version_type.rb
+++ b/app/graphql/types/terraform/state_version_type.rb
@@ -15,7 +15,7 @@ module Types
field :created_by_user, Types::UserType,
null: true,
- description: 'The user that created this version.'
+ description: 'User that created this version.'
field :download_path, GraphQL::Types::String,
null: true,
@@ -23,7 +23,8 @@ module Types
field :job, Types::Ci::JobType,
null: true,
- description: 'The job that created this version.'
+ description: 'Job that created this version.',
+ authorize: :read_commit_status
field :serial, GraphQL::Types::Int,
null: true,
diff --git a/app/graphql/types/timelog_type.rb b/app/graphql/types/timelog_type.rb
index 206aabbada3..d348fa698fa 100644
--- a/app/graphql/types/timelog_type.rb
+++ b/app/graphql/types/timelog_type.rb
@@ -14,31 +14,31 @@ module Types
field :time_spent,
GraphQL::Types::Int,
null: false,
- description: 'The time spent displayed in seconds.'
+ description: 'Time spent displayed in seconds.'
field :user,
Types::UserType,
null: false,
- description: 'The user that logged the time.'
+ description: 'User that logged the time.'
field :issue,
Types::IssueType,
null: true,
- description: 'The issue that logged time was added to.'
+ description: 'Issue that logged time was added to.'
field :merge_request,
Types::MergeRequestType,
null: true,
- description: 'The merge request that logged time was added to.'
+ description: 'Merge request that logged time was added to.'
field :note,
Types::Notes::NoteType,
null: true,
- description: 'The note where the quick action to add the logged time was executed.'
+ description: 'Note where the quick action was executed to add the logged time.'
field :summary, GraphQL::Types::String,
null: true,
- description: 'The summary of how the time was spent.'
+ description: 'Summary of how the time was spent.'
def user
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.user_id).find
diff --git a/app/graphql/types/todo_state_enum.rb b/app/graphql/types/todo_state_enum.rb
index 604e2a62f70..e6fc8867a80 100644
--- a/app/graphql/types/todo_state_enum.rb
+++ b/app/graphql/types/todo_state_enum.rb
@@ -2,7 +2,7 @@
module Types
class TodoStateEnum < BaseEnum
- value 'pending', description: "The state of the todo is pending."
- value 'done', description: "The state of the todo is done."
+ value 'pending', description: "State of the todo is pending."
+ value 'done', description: "State of the todo is done."
end
end
diff --git a/app/graphql/types/todo_target_enum.rb b/app/graphql/types/todo_target_enum.rb
index ce61bc8a926..dbf7b42ffcc 100644
--- a/app/graphql/types/todo_target_enum.rb
+++ b/app/graphql/types/todo_target_enum.rb
@@ -2,11 +2,11 @@
module Types
class TodoTargetEnum < BaseEnum
- value 'COMMIT', value: 'Commit', description: 'A Commit.'
- value 'ISSUE', value: 'Issue', description: 'An Issue.'
- value 'MERGEREQUEST', value: 'MergeRequest', description: 'A MergeRequest.'
- value 'DESIGN', value: 'DesignManagement::Design', description: 'A Design.'
- value 'ALERT', value: 'AlertManagement::Alert', description: 'An Alert.'
+ value 'COMMIT', value: 'Commit', description: 'Commit.'
+ value 'ISSUE', value: 'Issue', description: 'Issue.'
+ value 'MERGEREQUEST', value: 'MergeRequest', description: 'Merge request.'
+ value 'DESIGN', value: 'DesignManagement::Design', description: 'Design.'
+ value 'ALERT', value: 'AlertManagement::Alert', description: 'Alert.'
end
end
diff --git a/app/graphql/types/todo_type.rb b/app/graphql/types/todo_type.rb
index 24c110ce09b..34ba2c75b5f 100644
--- a/app/graphql/types/todo_type.rb
+++ b/app/graphql/types/todo_type.rb
@@ -14,7 +14,7 @@ module Types
null: false
field :project, Types::ProjectType,
- description: 'The project this to-do item is associated with.',
+ description: 'Project this to-do item is associated with.',
null: true,
authorize: :read_project
@@ -24,7 +24,7 @@ module Types
authorize: :read_group
field :author, Types::UserType,
- description: 'The author of this to-do item.',
+ description: 'Author of this to-do item.',
null: false
field :action, Types::TodoActionEnum,
diff --git a/app/graphql/types/user_interface.rb b/app/graphql/types/user_interface.rb
index 71c6b7f3019..8c67275eb73 100644
--- a/app/graphql/types/user_interface.rb
+++ b/app/graphql/types/user_interface.rb
@@ -59,6 +59,10 @@ module Types
type: Types::GroupMemberType.connection_type,
null: true,
description: 'Group memberships of the user.'
+ field :groups,
+ resolver: Resolvers::Users::GroupsResolver,
+ description: 'Groups where the user has access. Will always return `null` if ' \
+ '`paginatable_namespace_drop_down_for_project_creation` feature flag is disabled.'
field :group_count,
resolver: Resolvers::Users::GroupCountResolver,
description: 'Group count for the user.'
@@ -69,7 +73,7 @@ module Types
field :location,
type: ::GraphQL::Types::String,
null: true,
- description: 'The location of the user.'
+ description: 'Location of the user.'
field :project_memberships,
type: Types::ProjectMemberType.connection_type,
null: true,
@@ -82,9 +86,7 @@ module Types
null: true,
description: 'Personal namespace of the user.'
- field :todos, resolver: Resolvers::TodoResolver, description: 'To-do items of the user.' do
- extension(::Gitlab::Graphql::TodosProjectPermissionPreloader::FieldExtension)
- end
+ field :todos, resolver: Resolvers::TodoResolver, description: 'To-do items of the user.'
# Merge request field: MRs can be authored, assigned, or assigned-for-review:
field :authored_merge_requests,
diff --git a/app/graphql/types/user_merge_request_interaction_type.rb b/app/graphql/types/user_merge_request_interaction_type.rb
index ff6e83efbb2..06e318be5c6 100644
--- a/app/graphql/types/user_merge_request_interaction_type.rb
+++ b/app/graphql/types/user_merge_request_interaction_type.rb
@@ -28,7 +28,7 @@ module Types
field :review_state,
::Types::MergeRequestReviewStateEnum,
null: true,
- description: 'The state of the review by this user.'
+ description: 'State of the review by this user.'
field :reviewed,
type: ::GraphQL::Types::Boolean,
diff --git a/app/graphql/types/user_state_enum.rb b/app/graphql/types/user_state_enum.rb
index 5adec17672e..de15fc19682 100644
--- a/app/graphql/types/user_state_enum.rb
+++ b/app/graphql/types/user_state_enum.rb
@@ -5,8 +5,8 @@ module Types
graphql_name 'UserState'
description 'Possible states of a user'
- value 'active', 'The user is active and is able to use the system.', value: 'active'
- value 'blocked', 'The user has been blocked and is prevented from using the system.', value: 'blocked'
- value 'deactivated', 'The user is no longer active and is unable to use the system.', value: 'deactivated'
+ value 'active', 'User is active and is able to use the system.', value: 'active'
+ value 'blocked', 'User has been blocked and is prevented from using the system.', value: 'blocked'
+ value 'deactivated', 'User is no longer active and is unable to use the system.', value: 'deactivated'
end
end
diff --git a/app/helpers/analytics/cycle_analytics_helper.rb b/app/helpers/analytics/cycle_analytics_helper.rb
index c43ac545bf8..35a5d4f469d 100644
--- a/app/helpers/analytics/cycle_analytics_helper.rb
+++ b/app/helpers/analytics/cycle_analytics_helper.rb
@@ -7,5 +7,23 @@ module Analytics
Analytics::CycleAnalytics::StagePresenter.new(stage_params)
end
end
+
+ def cycle_analytics_initial_data(project, group = nil)
+ base_data = { project_id: project.id, group_path: project.group&.path, request_path: project_cycle_analytics_path(project), full_path: project.full_path }
+ svgs = { empty_state_svg_path: image_path("illustrations/analytics/cycle-analytics-empty-chart.svg"), no_data_svg_path: image_path("illustrations/analytics/cycle-analytics-empty-chart.svg"), no_access_svg_path: image_path("illustrations/analytics/no-access.svg") }
+ api_paths = group.present? ? cycle_analytics_group_api_paths(group) : cycle_analytics_project_api_paths(project)
+
+ base_data.merge(svgs, api_paths)
+ end
+
+ private
+
+ def cycle_analytics_group_api_paths(group)
+ { milestones_path: group_milestones_path(group, format: :json), labels_path: group_labels_path(group, format: :json), group_path: group_path(group), group_id: group&.id }
+ end
+
+ def cycle_analytics_project_api_paths(project)
+ { milestones_path: project_milestones_path(project, format: :json), labels_path: project_labels_path(project, format: :json), group_path: project.parent&.path, group_id: project.parent&.id }
+ end
end
end
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index 2447a731167..cf15433f2e5 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -176,6 +176,16 @@ module ApplicationSettingsHelper
"and the value is encrypted at rest.")
end
+ def sidekiq_job_limiter_mode_help_text
+ _("How the job limiter handles jobs exceeding the thresholds specified below. "\
+ "The 'track' mode only logs the jobs. The 'compress' mode compresses the jobs and "\
+ "raises an exception if the compressed size exceeds the limit.")
+ end
+
+ def sidekiq_job_limiter_modes_for_select
+ ApplicationSetting.sidekiq_job_limiter_modes.keys.map { |mode| [mode.humanize, mode] }
+ end
+
def visible_attributes
[
:abuse_notification_email,
@@ -263,6 +273,8 @@ module ApplicationSettingsHelper
:max_attachment_size,
:max_import_size,
:max_pages_size,
+ :max_yaml_size_bytes,
+ :max_yaml_depth,
:metrics_method_call_threshold,
:minimum_password_length,
:mirror_available,
@@ -309,18 +321,30 @@ module ApplicationSettingsHelper
:throttle_authenticated_api_enabled,
:throttle_authenticated_api_period_in_seconds,
:throttle_authenticated_api_requests_per_period,
+ :throttle_authenticated_git_lfs_enabled,
+ :throttle_authenticated_git_lfs_period_in_seconds,
+ :throttle_authenticated_git_lfs_requests_per_period,
:throttle_authenticated_web_enabled,
:throttle_authenticated_web_period_in_seconds,
:throttle_authenticated_web_requests_per_period,
:throttle_authenticated_packages_api_enabled,
:throttle_authenticated_packages_api_period_in_seconds,
:throttle_authenticated_packages_api_requests_per_period,
+ :throttle_authenticated_files_api_enabled,
+ :throttle_authenticated_files_api_period_in_seconds,
+ :throttle_authenticated_files_api_requests_per_period,
+ :throttle_unauthenticated_api_enabled,
+ :throttle_unauthenticated_api_period_in_seconds,
+ :throttle_unauthenticated_api_requests_per_period,
:throttle_unauthenticated_enabled,
:throttle_unauthenticated_period_in_seconds,
:throttle_unauthenticated_requests_per_period,
:throttle_unauthenticated_packages_api_enabled,
:throttle_unauthenticated_packages_api_period_in_seconds,
:throttle_unauthenticated_packages_api_requests_per_period,
+ :throttle_unauthenticated_files_api_enabled,
+ :throttle_unauthenticated_files_api_period_in_seconds,
+ :throttle_unauthenticated_files_api_requests_per_period,
:throttle_protected_paths_enabled,
:throttle_protected_paths_period_in_seconds,
:throttle_protected_paths_requests_per_period,
@@ -372,7 +396,11 @@ module ApplicationSettingsHelper
:container_registry_expiration_policies_worker_capacity,
:container_registry_cleanup_tags_service_max_list_size,
:keep_latest_artifact,
- :whats_new_variant
+ :whats_new_variant,
+ :user_deactivation_emails_enabled,
+ :sidekiq_job_limiter_mode,
+ :sidekiq_job_limiter_compression_threshold_bytes,
+ :sidekiq_job_limiter_limit_bytes
].tap do |settings|
settings << :deactivate_dormant_users unless Gitlab.com?
end
diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb
index c1a33794b50..f0e8ff7778e 100644
--- a/app/helpers/blob_helper.rb
+++ b/app/helpers/blob_helper.rb
@@ -183,6 +183,10 @@ module BlobHelper
blob_raw_url(**kwargs, only_path: true)
end
+ def parent_dir_raw_path
+ blob_raw_path.rpartition("/").first + "/"
+ end
+
# SVGs can contain malicious JavaScript; only include whitelisted
# elements and attributes. Note that this whitelist is by no means complete
# and may omit some elements.
diff --git a/app/helpers/ci/pipeline_editor_helper.rb b/app/helpers/ci/pipeline_editor_helper.rb
index 4dfe136c206..9bbc326a750 100644
--- a/app/helpers/ci/pipeline_editor_helper.rb
+++ b/app/helpers/ci/pipeline_editor_helper.rb
@@ -16,7 +16,6 @@ module Ci
"ci-config-path": project.ci_config_path_or_default,
"ci-examples-help-page-path" => help_page_path('ci/examples/index'),
"ci-help-page-path" => help_page_path('ci/index'),
- "commit-sha" => commit_sha,
"default-branch" => project.default_branch_or_main,
"empty-state-illustration-path" => image_path('illustrations/empty-state/empty-dag-md.svg'),
"initial-branch-name" => initial_branch,
diff --git a/app/helpers/ci/runners_helper.rb b/app/helpers/ci/runners_helper.rb
index 550fa4de2c5..c9231a4eff3 100644
--- a/app/helpers/ci/runners_helper.rb
+++ b/app/helpers/ci/runners_helper.rb
@@ -65,6 +65,15 @@ module Ci
}
end
+ def group_runners_data_attributes(group)
+ {
+ registration_token: group.runners_token,
+ group_id: group.id,
+ group_full_path: group.full_path,
+ runner_install_help_page: 'https://docs.gitlab.com/runner/install/'
+ }
+ end
+
def toggle_shared_runners_settings_data(project)
{
is_enabled: "#{project.shared_runners_enabled?}",
diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb
index 40d7eab584c..ca5fe38576e 100644
--- a/app/helpers/diff_helper.rb
+++ b/app/helpers/diff_helper.rb
@@ -183,9 +183,9 @@ module DiffHelper
def diff_file_changed_icon_color(diff_file)
if diff_file.deleted_file?
- "cred"
+ "danger"
elsif diff_file.new_file?
- "cgreen"
+ "success"
end
end
@@ -248,6 +248,23 @@ module DiffHelper
toggle_whitespace_link(url, options)
end
+ def diff_files_data(diff_files)
+ diffs_map = diff_files.map do |f|
+ {
+ href: "##{hexdigest(f.file_path)}",
+ title: f.new_path,
+ name: f.file_path,
+ path: diff_file_path_text(f),
+ icon: diff_file_changed_icon(f),
+ iconColor: "#{diff_file_changed_icon_color(f)}",
+ added: f.added_lines,
+ removed: f.removed_lines
+ }
+ end
+
+ diffs_map.to_json
+ end
+
def hide_whitespace?
params[:w] == '1'
end
diff --git a/app/helpers/environment_helper.rb b/app/helpers/environment_helper.rb
index 3f23f73eed7..f57bb600527 100644
--- a/app/helpers/environment_helper.rb
+++ b/app/helpers/environment_helper.rb
@@ -73,7 +73,6 @@ module EnvironmentHelper
external_url: environment.external_url,
can_update_environment: can?(current_user, :update_environment, environment),
can_destroy_environment: can_destroy_environment?(environment),
- can_read_environment: can?(current_user, :read_environment, environment),
can_stop_environment: can?(current_user, :stop_environment, environment),
can_admin_environment: can?(current_user, :admin_environment, project),
environment_metrics_path: environment_metrics_path(environment),
diff --git a/app/helpers/gitlab_routing_helper.rb b/app/helpers/gitlab_routing_helper.rb
index 0f835e6881e..1be395437ea 100644
--- a/app/helpers/gitlab_routing_helper.rb
+++ b/app/helpers/gitlab_routing_helper.rb
@@ -16,6 +16,7 @@ module GitlabRoutingHelper
include ::Routing::SnippetsHelper
include ::Routing::WikiHelper
include ::Routing::GraphqlHelper
+ include ::Routing::PseudonymizationHelper
included do
Gitlab::Routing.includes_helpers(self)
end
diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb
index 0e4aeaae20d..a24776eb2e4 100644
--- a/app/helpers/groups_helper.rb
+++ b/app/helpers/groups_helper.rb
@@ -1,14 +1,6 @@
# frozen_string_literal: true
module GroupsHelper
- def group_sidebar_links
- @group_sidebar_links ||= get_group_sidebar_links
- end
-
- def group_sidebar_link?(link)
- group_sidebar_links.include?(link)
- end
-
def can_change_group_visibility_level?(group)
can?(current_user, :change_visibility_level, group)
end
@@ -33,29 +25,6 @@ module GroupsHelper
Ability.allowed?(current_user, :admin_group_member, group)
end
- def group_issues_count(state:)
- IssuesFinder
- .new(current_user, group_id: @group.id, state: state, non_archived: true, include_subgroups: true)
- .execute
- .count
- end
-
- def group_merge_requests_count(state:)
- MergeRequestsFinder
- .new(current_user, group_id: @group.id, state: state, non_archived: true, include_subgroups: true)
- .execute
- .count
- end
-
- def group_dependency_proxy_image_prefix(group)
- # The namespace path can include uppercase letters, which
- # Docker doesn't allow. The proxy expects it to be downcased.
- url = "#{group_url(group).downcase}#{DependencyProxy::URL_SUFFIX}"
-
- # Docker images do not include the protocol
- url.partition('//').last
- end
-
def group_icon_url(group, options = {})
if group.is_a?(String)
group = Group.find_by_full_path(group)
@@ -153,12 +122,6 @@ module GroupsHelper
groups.to_json
end
- def show_invite_banner?(group)
- can?(current_user, :admin_group, group) &&
- !just_created? &&
- !multiple_members?(group)
- end
-
def render_setting_to_allow_project_access_token_creation?(group)
group.root? && current_user.can?(:admin_setting_to_allow_project_access_token_creation, group)
end
@@ -173,44 +136,6 @@ module GroupsHelper
private
- def just_created?
- flash[:notice] =~ /successfully created/
- end
-
- def multiple_members?(group)
- group.member_count > 1 || group.members_with_parents.count > 1
- end
-
- def get_group_sidebar_links
- links = [:overview, :group_members]
-
- resources = [:activity, :issues, :boards, :labels, :milestones,
- :merge_requests]
- links += resources.select do |resource|
- can?(current_user, "read_group_#{resource}".to_sym, @group)
- end
-
- # TODO Proper policies, such as `read_group_runners, should be implemented per
- # See https://gitlab.com/gitlab-org/gitlab/-/issues/334802
- if can?(current_user, :admin_group, @group) && Feature.enabled?(:runner_list_group_view_vue_ui, @group, default_enabled: :yaml)
- links << :runners
- end
-
- if can?(current_user, :read_cluster, @group)
- links << :kubernetes
- end
-
- if can?(current_user, :admin_group, @group)
- links << :settings
- end
-
- if can?(current_user, :read_wiki, @group)
- links << :wiki
- end
-
- links
- end
-
def group_title_link(group, hidable: false, show_avatar: false, for_dropdown: false)
link_to(group_path(group), class: "group-path #{'breadcrumb-item-text' unless for_dropdown} js-breadcrumb-item-text #{'hidable' if hidable}") do
icon = group_icon(group, class: "avatar-tile", width: 15, height: 15) if (group.try(:avatar_url) || show_avatar) && !Rails.env.test?
@@ -271,6 +196,18 @@ module GroupsHelper
def group_url_error_message
s_('GroupSettings|Please choose a group URL with no special characters or spaces.')
end
+
+ # Maps `jobs_to_be_done` values to option texts
+ def localized_jobs_to_be_done_choices
+ {
+ basics: _('I want to learn the basics of Git'),
+ move_repository: _('I want to move my repository to GitLab from somewhere else'),
+ code_storage: _('I want to store my code'),
+ exploring: _('I want to explore GitLab to see if it’s worth switching to'),
+ ci: _('I want to use GitLab CI with my existing repository'),
+ other: _('A different reason')
+ }.with_indifferent_access.freeze
+ end
end
GroupsHelper.prepend_mod_with('GroupsHelper')
diff --git a/app/helpers/invite_members_helper.rb b/app/helpers/invite_members_helper.rb
index 5134b484249..d9bd64f4c2e 100644
--- a/app/helpers/invite_members_helper.rb
+++ b/app/helpers/invite_members_helper.rb
@@ -9,14 +9,6 @@ module InviteMembersHelper
Feature.enabled?(:invite_members_group_modal, project.group) && can?(current_user, :admin_project_member, project)
end
- def can_invite_group_for_project?(project)
- # do not use the can_admin_project_member? helper here due to structure of the view and how membership_locked?
- # is leveraged for inviting groups
- Feature.enabled?(:invite_members_group_modal, project.group) &&
- can?(current_user, :admin_project_member, project) &&
- project.allowed_to_share_with_group?
- end
-
def invite_accepted_notice(member)
case member.source
when Project
diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb
index d8ba530f3f6..f3cc46216e5 100644
--- a/app/helpers/issuables_helper.rb
+++ b/app/helpers/issuables_helper.rb
@@ -3,6 +3,7 @@
module IssuablesHelper
include GitlabRoutingHelper
include IssuablesDescriptionTemplatesHelper
+ include ::Sidebars::Concerns::HasPill
def sidebar_gutter_toggle_icon
content_tag(:span, class: 'js-sidebar-toggle-container', data: { is_expanded: !sidebar_gutter_collapsed? }) do
@@ -187,19 +188,18 @@ module IssuablesHelper
end
def issuables_state_counter_text(issuable_type, state, display_count)
- titles = {
- opened: "Open"
- }
-
+ titles = { opened: "Open" }
state_title = titles[state] || state.to_s.humanize
html = content_tag(:span, state_title)
return html.html_safe unless display_count
count = issuables_count_for_state(issuable_type, state)
-
if count != -1
- html << " " << content_tag(:span, number_with_delimiter(count), class: 'badge badge-muted badge-pill gl-badge gl-tab-counter-badge sm')
+ html << " " << content_tag(:span,
+ format_count(issuable_type, count, Gitlab::IssuablesCountForState::THRESHOLD),
+ class: 'badge badge-muted badge-pill gl-badge gl-tab-counter-badge sm'
+ )
end
html.html_safe
@@ -256,7 +256,8 @@ module IssuablesHelper
issueType: issuable.issue_type,
zoomMeetingUrl: ZoomMeeting.canonical_meeting_url(issuable),
sentryIssueIdentifier: SentryIssue.find_by(issue: issuable)&.sentry_issue_identifier, # rubocop:disable CodeReuse/ActiveRecord
- iid: issuable.iid.to_s
+ iid: issuable.iid.to_s,
+ isHidden: issue_hidden?(issuable)
}
end
@@ -283,7 +284,9 @@ module IssuablesHelper
end
def issuables_count_for_state(issuable_type, state)
- Gitlab::IssuablesCountForState.new(finder)[state]
+ store_in_cache = parent.is_a?(Group) ? parent.cached_issues_state_count_enabled? : false
+
+ Gitlab::IssuablesCountForState.new(finder, store_in_redis_cache: store_in_cache)[state]
end
def close_issuable_path(issuable)
@@ -370,7 +373,7 @@ module IssuablesHelper
is_collapsed: is_collapsed,
track_label: "right_sidebar",
track_property: "update_todo",
- track_event: "click_button",
+ track_action: "click_button",
track_value: ""
}
end
@@ -437,6 +440,14 @@ module IssuablesHelper
def parent
@project || @group
end
+
+ def format_count(issuable_type, count, threshold)
+ if issuable_type == :issues && parent.is_a?(Group) && parent.cached_issues_state_count_enabled?
+ format_cached_count(threshold, count)
+ else
+ number_with_delimiter(count)
+ end
+ end
end
IssuablesHelper.prepend_mod_with('IssuablesHelper')
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index bbafdac9a7f..40e86b4623c 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -60,8 +60,16 @@ module IssuesHelper
sprite_icon('eye-slash', css_class: 'gl-vertical-align-text-bottom') if issue.confidential?
end
+ def issue_hidden?(issue)
+ Feature.enabled?(:ban_user_feature_flag) && issue.hidden?
+ end
+
def hidden_issue_icon(issue)
- sprite_icon('spam', css_class: 'gl-vertical-align-text-bottom') if issue.hidden?
+ return unless issue_hidden?(issue)
+
+ content_tag(:span, class: 'has-tooltip', title: _('This issue is hidden because its author has been banned')) do
+ sprite_icon('spam', css_class: 'gl-vertical-align-text-bottom')
+ end
end
def award_user_list(awards, current_user, limit: 10)
@@ -174,7 +182,11 @@ module IssuesHelper
end
def issue_header_actions_data(project, issuable, current_user)
- new_issuable_params = ({ issuable_template: 'incident', issue: { issue_type: 'incident' } } if issuable.incident?)
+ new_issuable_params = { issue: { description: _('Related to #%{issue_id}.') % { issue_id: issuable.iid } + "\n\n" } }
+ if issuable.incident?
+ new_issuable_params[:issuable_template] = 'incident'
+ new_issuable_params[:issue][:issue_type] = 'incident'
+ end
{
can_create_issue: show_new_issue_link?(project).to_s,
@@ -191,34 +203,45 @@ module IssuesHelper
}
end
- def issues_list_data(project, current_user, finder)
+ def common_issues_list_data(namespace, current_user)
{
autocomplete_award_emojis_path: autocomplete_award_emojis_path,
calendar_path: url_for(safe_params.merge(calendar_url_options)),
+ empty_state_svg_path: image_path('illustrations/issues.svg'),
+ full_path: namespace.full_path,
+ is_signed_in: current_user.present?.to_s,
+ jira_integration_path: help_page_url('integration/jira/issues', anchor: 'view-jira-issues'),
+ rss_path: url_for(safe_params.merge(rss_url_options)),
+ sign_in_path: new_user_session_path
+ }
+ end
+
+ def project_issues_list_data(project, current_user, finder)
+ common_issues_list_data(project, current_user).merge(
can_bulk_update: can?(current_user, :admin_issue, project).to_s,
can_edit: can?(current_user, :admin_project, project).to_s,
can_import_issues: can?(current_user, :import_issues, @project).to_s,
- email: current_user&.notification_email,
+ email: current_user&.notification_email_or_default,
emails_help_page_path: help_page_path('development/emails', anchor: 'email-namespace'),
- empty_state_svg_path: image_path('illustrations/issues.svg'),
export_csv_path: export_csv_project_issues_path(project),
- has_project_issues: project_issues(project).exists?.to_s,
+ has_any_issues: project_issues(project).exists?.to_s,
import_csv_issues_path: import_csv_namespace_project_issues_path,
initial_email: project.new_issuable_address(current_user, 'issue'),
- is_signed_in: current_user.present?.to_s,
- issues_path: project_issues_path(project),
- jira_integration_path: help_page_url('integration/jira/issues', anchor: 'view-jira-issues'),
+ is_project: true.to_s,
markdown_help_path: help_page_path('user/markdown'),
max_attachment_size: number_to_human_size(Gitlab::CurrentSettings.max_attachment_size.megabytes),
new_issue_path: new_project_issue_path(project, issue: { milestone_id: finder.milestones.first.try(:id) }),
project_import_jira_path: project_import_jira_path(project),
- project_path: project.full_path,
quick_actions_help_path: help_page_path('user/project/quick_actions'),
reset_path: new_issuable_address_project_path(project, issuable_type: 'issue'),
- rss_path: url_for(safe_params.merge(rss_url_options)),
- show_new_issue_link: show_new_issue_link?(project).to_s,
- sign_in_path: new_user_session_path
- }
+ show_new_issue_link: show_new_issue_link?(project).to_s
+ )
+ end
+
+ def group_issues_list_data(group, current_user, issues)
+ common_issues_list_data(group, current_user).merge(
+ has_any_issues: issues.to_a.any?.to_s
+ )
end
# Overridden in EE
diff --git a/app/helpers/learn_gitlab_helper.rb b/app/helpers/learn_gitlab_helper.rb
index a3a8a275f67..4fb7a05a0e9 100644
--- a/app/helpers/learn_gitlab_helper.rb
+++ b/app/helpers/learn_gitlab_helper.rb
@@ -1,23 +1,12 @@
# frozen_string_literal: true
module LearnGitlabHelper
- def learn_gitlab_experiment_enabled?(project)
+ def learn_gitlab_enabled?(project)
return false unless current_user
- return false unless continous_onboarding_experiment_enabled_for_user?
learn_gitlab_onboarding_available?(project)
end
- def learn_gitlab_experiment_tracking_category
- return unless current_user
-
- if Gitlab::Experimentation.in_experiment_group?(:learn_gitlab_a, subject: current_user)
- Gitlab::Experimentation.get_experiment(:learn_gitlab_a).tracking_category
- elsif Gitlab::Experimentation.in_experiment_group?(:learn_gitlab_b, subject: current_user)
- Gitlab::Experimentation.get_experiment(:learn_gitlab_b).tracking_category
- end
- end
-
def onboarding_actions_data(project)
attributes = onboarding_progress(project).attributes.symbolize_keys
@@ -31,11 +20,6 @@ module LearnGitlabHelper
end
end
- def continous_onboarding_experiment_enabled_for_user?
- Gitlab::Experimentation.in_experiment_group?(:learn_gitlab_a, subject: current_user) ||
- Gitlab::Experimentation.in_experiment_group?(:learn_gitlab_b, subject: current_user)
- end
-
def onboarding_sections_data
{
workspace: {
diff --git a/app/helpers/nav/new_dropdown_helper.rb b/app/helpers/nav/new_dropdown_helper.rb
index 0384f82f1f1..e7d69c38a54 100644
--- a/app/helpers/nav/new_dropdown_helper.rb
+++ b/app/helpers/nav/new_dropdown_helper.rb
@@ -32,7 +32,7 @@ module Nav
id: 'new_project',
title: _('New project/repository'),
href: new_project_path(namespace_id: group.id),
- data: { track_event: 'click_link_new_project_group', track_label: 'plus_menu_dropdown' }
+ data: { track_action: 'click_link_new_project_group', track_label: 'plus_menu_dropdown' }
)
)
end
@@ -43,7 +43,7 @@ module Nav
id: 'new_subgroup',
title: _('New subgroup'),
href: new_group_path(parent_id: group.id),
- data: { track_event: 'click_link_new_subgroup', track_label: 'plus_menu_dropdown' }
+ data: { track_action: 'click_link_new_subgroup', track_label: 'plus_menu_dropdown' }
)
)
end
@@ -74,7 +74,7 @@ module Nav
id: 'new_issue',
title: _('New issue'),
href: new_project_issue_path(project),
- data: { track_event: 'click_link_new_issue', track_label: 'plus_menu_dropdown', qa_selector: 'new_issue_link' }
+ data: { track_action: 'click_link_new_issue', track_label: 'plus_menu_dropdown', qa_selector: 'new_issue_link' }
)
)
end
@@ -85,7 +85,7 @@ module Nav
id: 'new_mr',
title: _('New merge request'),
href: project_new_merge_request_path(merge_project),
- data: { track_event: 'click_link_new_mr', track_label: 'plus_menu_dropdown' }
+ data: { track_action: 'click_link_new_mr', track_label: 'plus_menu_dropdown' }
)
)
end
@@ -96,7 +96,7 @@ module Nav
id: 'new_snippet',
title: _('New snippet'),
href: new_project_snippet_path(project),
- data: { track_event: 'click_link_new_snippet_project', track_label: 'plus_menu_dropdown' }
+ data: { track_action: 'click_link_new_snippet_project', track_label: 'plus_menu_dropdown' }
)
)
end
@@ -124,7 +124,7 @@ module Nav
id: 'general_new_project',
title: _('New project/repository'),
href: new_project_path,
- data: { track_event: 'click_link_new_project', track_label: 'plus_menu_dropdown', qa_selector: 'global_new_project_link' }
+ data: { track_action: 'click_link_new_project', track_label: 'plus_menu_dropdown', qa_selector: 'global_new_project_link' }
)
)
end
@@ -135,7 +135,7 @@ module Nav
id: 'general_new_group',
title: _('New group'),
href: new_group_path,
- data: { track_event: 'click_link_new_group', track_label: 'plus_menu_dropdown' }
+ data: { track_action: 'click_link_new_group', track_label: 'plus_menu_dropdown' }
)
)
end
@@ -146,7 +146,7 @@ module Nav
id: 'general_new_snippet',
title: _('New snippet'),
href: new_snippet_path,
- data: { track_event: 'click_link_new_snippet_parent', track_label: 'plus_menu_dropdown', qa_selector: 'global_new_snippet_link' }
+ data: { track_action: 'click_link_new_snippet_parent', track_label: 'plus_menu_dropdown', qa_selector: 'global_new_snippet_link' }
)
)
end
@@ -164,7 +164,7 @@ module Nav
emoji: ('shaking_hands' if experiment_enabled?(:invite_members_new_dropdown)),
href: href,
data: {
- track_event: 'click_link',
+ track_action: 'click_link',
track_label: tracking_label,
track_property: experiment_tracking_category_and_group(:invite_members_new_dropdown)
}
diff --git a/app/helpers/nav/top_nav_helper.rb b/app/helpers/nav/top_nav_helper.rb
index 052b8339ebd..3055ad57b80 100644
--- a/app/helpers/nav/top_nav_helper.rb
+++ b/app/helpers/nav/top_nav_helper.rb
@@ -98,7 +98,7 @@ module Nav
builder.add_primary_menu_item_with_shortcut(
active: nav == 'project' || active_nav_link?(path: %w[root#index projects#trending projects#starred dashboard/projects#index]),
css_class: 'qa-projects-dropdown',
- data: { track_label: "projects_dropdown", track_event: "click_dropdown" },
+ data: { track_label: "projects_dropdown", track_action: "click_dropdown" },
view: PROJECTS_VIEW,
shortcut_href: dashboard_projects_path,
**projects_menu_item_attrs
@@ -112,7 +112,7 @@ module Nav
builder.add_primary_menu_item_with_shortcut(
active: nav == 'group' || active_nav_link?(path: %w[dashboard/groups explore/groups]),
css_class: 'qa-groups-dropdown',
- data: { track_label: "groups_dropdown", track_event: "click_dropdown" },
+ data: { track_label: "groups_dropdown", track_action: "click_dropdown" },
view: GROUPS_VIEW,
shortcut_href: dashboard_groups_path,
**groups_menu_item_attrs
diff --git a/app/helpers/notify_helper.rb b/app/helpers/notify_helper.rb
index c0ba93f4a30..ed96f3cef4f 100644
--- a/app/helpers/notify_helper.rb
+++ b/app/helpers/notify_helper.rb
@@ -20,4 +20,21 @@ module NotifyHelper
(source.description || default_description).truncate(200, separator: ' ')
end
+
+ def invited_join_url(token, member)
+ additional_params = { invite_type: Emails::Members::INITIAL_INVITE }
+
+ # order important below to our scheduled testing of these
+ # `from` experiment will be after the `text` on, but we may not cleanup
+ # from the `text` one by the time we run the `from` experiment,
+ # therefore we want to support `text` being fully enabled
+ # but if `from` is also enabled, then we only care about `from`
+ if experiment(:invite_email_from, actor: member).enabled?
+ additional_params[:experiment_name] = 'invite_email_from'
+ elsif experiment(:invite_email_preview_text, actor: member).enabled?
+ additional_params[:experiment_name] = 'invite_email_preview_text'
+ end
+
+ invite_url(token, additional_params)
+ end
end
diff --git a/app/helpers/packages_helper.rb b/app/helpers/packages_helper.rb
index 1a466c9d170..ebf30fb3538 100644
--- a/app/helpers/packages_helper.rb
+++ b/app/helpers/packages_helper.rb
@@ -64,9 +64,8 @@ module PackagesHelper
project.container_repositories.exists?
end
- def package_details_data(project, package, use_presenter = false)
+ def package_details_data(project, package)
{
- package: use_presenter ? package_from_presenter(package) : nil,
package_id: package.id,
can_delete: can?(current_user, :destroy_package, project).to_s,
svg_path: image_path('illustrations/no-packages.svg'),
diff --git a/app/helpers/profiles_helper.rb b/app/helpers/profiles_helper.rb
index f6ed567c9ea..09fc1ab9d50 100644
--- a/app/helpers/profiles_helper.rb
+++ b/app/helpers/profiles_helper.rb
@@ -6,15 +6,12 @@ module ProfilesHelper
verified_emails = user.verified_emails - [private_email]
[
+ [s_('Use primary email (%{email})') % { email: user.email }, ''],
[s_("Profiles|Use a private email - %{email}").html_safe % { email: private_email }, Gitlab::PrivateCommitEmail::TOKEN],
*verified_emails
]
end
- def selected_commit_email(user)
- user.read_attribute(:commit_email) || user.commit_email
- end
-
def attribute_provider_label(attribute)
user_synced_attributes_metadata = current_user.user_synced_attributes_metadata
if user_synced_attributes_metadata&.synced?(attribute)
@@ -38,6 +35,21 @@ module ProfilesHelper
status&.availability == availability_values[:busy]
end
+ def middle_dot_divider_classes(stacking, breakpoint)
+ ['gl-mb-3'].tap do |classes|
+ if stacking
+ classes.concat(%w(middle-dot-divider-sm gl-display-block gl-sm-display-inline-block))
+ else
+ classes << 'gl-display-inline-block'
+ classes << if breakpoint.nil?
+ 'middle-dot-divider'
+ else
+ "middle-dot-divider-#{breakpoint}"
+ end
+ end
+ end
+ end
+
# Overridden in EE::ProfilesHelper#ssh_key_expiration_tooltip
def ssh_key_expiration_tooltip(key)
return key.errors.full_messages.join(', ') if key.errors.full_messages.any?
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index f30223f6f1e..d7f1cd505e9 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -435,7 +435,7 @@ module ProjectsHelper
def git_user_email
if current_user
- current_user.commit_email
+ current_user.commit_email_or_default
else
"your@email.com"
end
diff --git a/app/helpers/recaptcha_helper.rb b/app/helpers/recaptcha_helper.rb
index 4ebac1d5b7f..0df62f7b715 100644
--- a/app/helpers/recaptcha_helper.rb
+++ b/app/helpers/recaptcha_helper.rb
@@ -5,3 +5,5 @@ module RecaptchaHelper
!!Gitlab::Recaptcha.enabled?
end
end
+
+RecaptchaHelper.prepend_mod
diff --git a/app/helpers/routing/pseudonymization_helper.rb b/app/helpers/routing/pseudonymization_helper.rb
new file mode 100644
index 00000000000..1d9320f0106
--- /dev/null
+++ b/app/helpers/routing/pseudonymization_helper.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module Routing
+ module PseudonymizationHelper
+ def masked_page_url
+ return unless Feature.enabled?(:mask_page_urls, type: :ops)
+
+ mask_params(Rails.application.routes.recognize_path(request.original_fullpath))
+ rescue ActionController::RoutingError, URI::InvalidURIError
+ nil
+ end
+
+ private
+
+ def mask_params(request_params)
+ return if request_params[:action] == 'new'
+
+ namespace_type = request_params[:controller].split('/')[1]
+
+ namespace_type.present? ? url_with_namespace_type(request_params, namespace_type) : url_without_namespace_type(request_params)
+ end
+
+ def url_without_namespace_type(request_params)
+ masked_url = "#{request.protocol}#{request.host_with_port}"
+
+ masked_url += case request_params[:controller]
+ when 'groups'
+ "/namespace:#{group.id}"
+ when 'projects'
+ "/namespace:#{project.namespace.id}/project:#{project.id}"
+ when 'root'
+ ''
+ else
+ "#{request.path}"
+ end
+
+ masked_url += request.query_string.present? ? "?#{request.query_string}" : ''
+
+ masked_url
+ end
+
+ def url_with_namespace_type(request_params, namespace_type)
+ masked_url = "#{request.protocol}#{request.host_with_port}"
+
+ if request_params.has_key?(:project_id)
+ masked_url += "/namespace:#{project.namespace.id}/project:#{project.id}/-/#{namespace_type}"
+ end
+
+ if request_params.has_key?(:id)
+ masked_url += namespace_type == 'blob' ? '/:repository_path' : "/#{request_params[:id]}"
+ end
+
+ masked_url += request.query_string.present? ? "?#{request.query_string}" : ''
+
+ masked_url
+ end
+ end
+end
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index 409a3e65fe3..b8e58e3afb1 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -443,6 +443,10 @@ module SearchHelper
_("Open")
end
end
+
+ def feature_flag_tab_enabled?(flag)
+ @group || Feature.enabled?(flag, current_user, type: :ops, default_enabled: true)
+ end
end
SearchHelper.prepend_mod_with('SearchHelper')
diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb
index 117f662fec6..e9466a9e97e 100644
--- a/app/helpers/sessions_helper.rb
+++ b/app/helpers/sessions_helper.rb
@@ -22,11 +22,21 @@ module SessionsHelper
# creates a new session after login, so the short TTL doesn't even need to
# be extended.
def limit_session_time
+ set_session_time(Settings.gitlab['unauthenticated_session_expire_delay'])
+ end
+
+ def ensure_authenticated_session_time
+ set_session_time(nil)
+ end
+
+ def set_session_time(expiry_s)
# Rack sets this header, but not all tests may have it: https://github.com/rack/rack/blob/fdcd03a3c5a1c51d1f96fc97f9dfa1a9deac0c77/lib/rack/session/abstract/id.rb#L251-L259
return unless request.env['rack.session.options']
- # This works because Rack uses these options every time a request is handled:
- # https://github.com/rack/rack/blob/fdcd03a3c5a1c51d1f96fc97f9dfa1a9deac0c77/lib/rack/session/abstract/id.rb#L342
- request.env['rack.session.options'][:expire_after] = Settings.gitlab['unauthenticated_session_expire_delay']
+ # This works because Rack uses these options every time a request is handled, and redis-store
+ # uses the Rack setting first:
+ # 1. https://github.com/rack/rack/blob/fdcd03a3c5a1c51d1f96fc97f9dfa1a9deac0c77/lib/rack/session/abstract/id.rb#L342
+ # 2. https://github.com/redis-store/redis-store/blob/3acfa95f4eb6260c714fdb00a3d84be8eedc13b2/lib/redis/store/ttl.rb#L32
+ request.env['rack.session.options'][:expire_after] = expiry_s
end
end
diff --git a/app/helpers/sidebars_helper.rb b/app/helpers/sidebars_helper.rb
index 77af6e37099..9002fdda128 100644
--- a/app/helpers/sidebars_helper.rb
+++ b/app/helpers/sidebars_helper.rb
@@ -87,8 +87,7 @@ module SidebarsHelper
{
current_user: user,
container: project,
- learn_gitlab_experiment_enabled: learn_gitlab_experiment_enabled?(project),
- learn_gitlab_experiment_tracking_category: learn_gitlab_experiment_tracking_category,
+ learn_gitlab_enabled: learn_gitlab_enabled?(project),
current_ref: current_ref,
jira_issues_integration: project_jira_issues_integration?,
can_view_pipeline_editor: can_view_pipeline_editor?(project),
diff --git a/app/helpers/sorting_helper.rb b/app/helpers/sorting_helper.rb
index 7fa85d143f7..b28e5ff39b2 100644
--- a/app/helpers/sorting_helper.rb
+++ b/app/helpers/sorting_helper.rb
@@ -37,7 +37,8 @@ module SortingHelper
sort_value_contacted_date => sort_title_contacted_date,
sort_value_relative_position => sort_title_relative_position,
sort_value_size => sort_title_size,
- sort_value_expire_date => sort_title_expire_date
+ sort_value_expire_date => sort_title_expire_date,
+ sort_value_title => sort_title_title
}
end
# rubocop: enable Metrics/AbcSize
@@ -188,7 +189,8 @@ module SortingHelper
sort_value_due_date_later => sort_value_due_date,
sort_value_merged_recently => sort_value_merged_date,
sort_value_closed_recently => sort_value_closed_date,
- sort_value_least_popular => sort_value_popularity
+ sort_value_least_popular => sort_value_popularity,
+ sort_value_title_desc => sort_value_title
}
end
@@ -205,7 +207,8 @@ module SortingHelper
sort_value_closed_date => sort_value_closed_recently,
sort_value_closed_earlier => sort_value_closed_recently,
sort_value_popularity => sort_value_least_popular,
- sort_value_most_popular => sort_value_least_popular
+ sort_value_most_popular => sort_value_least_popular,
+ sort_value_title => sort_value_title_desc
}.merge(issuable_sort_option_overrides)
end
diff --git a/app/helpers/sorting_titles_values_helper.rb b/app/helpers/sorting_titles_values_helper.rb
index f4117d690f3..75ba6e8a153 100644
--- a/app/helpers/sorting_titles_values_helper.rb
+++ b/app/helpers/sorting_titles_values_helper.rb
@@ -138,6 +138,10 @@ module SortingTitlesValuesHelper
s_('SortOptions|Start soon')
end
+ def sort_title_title
+ s_('SortOptions|Title')
+ end
+
def sort_title_upvotes
s_('SortOptions|Most popular')
end
@@ -307,6 +311,14 @@ module SortingTitlesValuesHelper
'start_date_asc'
end
+ def sort_value_title
+ 'title_asc'
+ end
+
+ def sort_value_title_desc
+ 'title_desc'
+ end
+
def sort_value_upvotes
'upvotes_desc'
end
diff --git a/app/helpers/system_note_helper.rb b/app/helpers/system_note_helper.rb
index 521423fbb94..1d8b657025c 100644
--- a/app/helpers/system_note_helper.rb
+++ b/app/helpers/system_note_helper.rb
@@ -39,7 +39,8 @@ module SystemNoteHelper
'alert_issue_added' => 'issues',
'new_alert_added' => 'warning',
'severity' => 'information-o',
- 'cloned' => 'documents'
+ 'cloned' => 'documents',
+ 'issue_type' => 'pencil-square'
}.freeze
def system_note_icon_name(note)
diff --git a/app/helpers/user_callouts_helper.rb b/app/helpers/user_callouts_helper.rb
index f5a74a3f57d..2c3dc243d85 100644
--- a/app/helpers/user_callouts_helper.rb
+++ b/app/helpers/user_callouts_helper.rb
@@ -9,6 +9,7 @@ module UserCalloutsHelper
FEATURE_FLAGS_NEW_VERSION = 'feature_flags_new_version'
REGISTRATION_ENABLED_CALLOUT = 'registration_enabled_callout'
UNFINISHED_TAG_CLEANUP_CALLOUT = 'unfinished_tag_cleanup_callout'
+ INVITE_MEMBERS_BANNER = 'invite_members_banner'
def show_gke_cluster_integration_callout?(project)
active_nav_link?(controller: sidebar_operations_paths) &&
@@ -27,7 +28,7 @@ module UserCalloutsHelper
def render_dashboard_ultimate_trial(user)
end
- def render_account_recovery_regular_check
+ def render_two_factor_auth_recovery_settings_check
end
def show_suggest_popover?
@@ -53,7 +54,14 @@ module UserCalloutsHelper
!user_dismissed?(REGISTRATION_ENABLED_CALLOUT)
end
- def dismiss_account_recovery_regular_check
+ def dismiss_two_factor_auth_recovery_settings_check
+ end
+
+ def show_invite_banner?(group)
+ Ability.allowed?(current_user, :admin_group, group) &&
+ !just_created? &&
+ !user_dismissed_for_group(INVITE_MEMBERS_BANNER, group) &&
+ !multiple_members?(group)
end
private
@@ -63,6 +71,43 @@ module UserCalloutsHelper
current_user.dismissed_callout?(feature_name: feature_name, ignore_dismissal_earlier_than: ignore_dismissal_earlier_than)
end
+
+ def user_dismissed_for_group(feature_name, group, ignore_dismissal_earlier_than = nil)
+ return false unless current_user
+
+ set_dismissed_from_cookie(group)
+
+ current_user.dismissed_callout_for_group?(feature_name: feature_name,
+ group: group,
+ ignore_dismissal_earlier_than: ignore_dismissal_earlier_than)
+ end
+
+ def set_dismissed_from_cookie(group)
+ # bridge function for one milestone to try and not annoy users who might have already dismissed this alert
+ # remove in 14.4 or 14.5? https://gitlab.com/gitlab-org/gitlab/-/issues/340322
+ dismissed_key = "invite_#{group.id}_#{current_user.id}"
+
+ if cookies[dismissed_key].present?
+ params = {
+ feature_name: INVITE_MEMBERS_BANNER,
+ group_id: group.id
+ }
+
+ Users::DismissGroupCalloutService.new(
+ container: nil, current_user: current_user, params: params
+ ).execute
+
+ cookies.delete dismissed_key
+ end
+ end
+
+ def just_created?
+ flash[:notice]&.include?('successfully created')
+ end
+
+ def multiple_members?(group)
+ group.member_count > 1 || group.members_with_parents.count > 1
+ end
end
UserCalloutsHelper.prepend_mod
diff --git a/app/mailers/emails/admin_notification.rb b/app/mailers/emails/admin_notification.rb
index f4540ef81a5..e11f06d8fc9 100644
--- a/app/mailers/emails/admin_notification.rb
+++ b/app/mailers/emails/admin_notification.rb
@@ -4,7 +4,7 @@ module Emails
module AdminNotification
def send_admin_notification(user_id, subject, body)
user = User.find(user_id)
- email = user.notification_email
+ email = user.notification_email_or_default
@unsubscribe_url = unsubscribe_url(email: Base64.urlsafe_encode64(email))
@body = body
mail to: email, subject: subject
@@ -12,7 +12,7 @@ module Emails
def send_unsubscribed_notification(user_id)
user = User.find(user_id)
- email = user.notification_email
+ email = user.notification_email_or_default
mail to: email, subject: "Unsubscribed from GitLab administrator notifications"
end
end
diff --git a/app/mailers/emails/members.rb b/app/mailers/emails/members.rb
index fe2d2891547..6954fd46850 100644
--- a/app/mailers/emails/members.rb
+++ b/app/mailers/emails/members.rb
@@ -57,7 +57,7 @@ module Emails
Gitlab::Tracking.event(self.class.name, 'invite_email_sent', label: 'invite_email', property: member_id.to_s)
- mail(to: member.invite_email, subject: invite_email_subject, **invite_email_headers) do |format|
+ mail(to: member.invite_email, subject: invite_email_subject, **invite_email_headers.merge(additional_invite_settings)) do |format|
format.html { render layout: 'unknown_user_mailer' }
format.text { render layout: 'unknown_user_mailer' }
end
@@ -147,23 +147,48 @@ module Emails
def invite_email_subject
if member.created_by
- subject(s_("MemberInviteEmail|%{member_name} invited you to join GitLab") % { member_name: member.created_by.name })
+ experiment(:invite_email_from, actor: member) do |experiment_instance|
+ experiment_instance.use do
+ subject(s_("MemberInviteEmail|%{member_name} invited you to join GitLab") % { member_name: member.created_by.name })
+ end
+
+ experiment_instance.candidate do
+ subject(s_("MemberInviteEmail|I've invited you to join me in GitLab"))
+ end
+
+ experiment_instance.run
+ end
else
subject(s_("MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}") % { project_or_group: member_source.human_name, project_or_group_name: member_source.model_name.singular })
end
end
def invite_email_headers
- if Gitlab.dev_env_or_com?
+ if Gitlab::CurrentSettings.mailgun_events_enabled?
{
- 'X-Mailgun-Tag' => 'invite_email',
- 'X-Mailgun-Variables' => { 'invite_token' => @token }.to_json
+ 'X-Mailgun-Tag' => ::Members::Mailgun::INVITE_EMAIL_TAG,
+ 'X-Mailgun-Variables' => { ::Members::Mailgun::INVITE_EMAIL_TOKEN_KEY => @token }.to_json
}
else
{}
end
end
+ def additional_invite_settings
+ return {} unless member.created_by
+
+ experiment(:invite_email_from, actor: member) do |experiment_instance|
+ experiment_instance.use { {} }
+ experiment_instance.candidate do
+ {
+ from: "#{member.created_by.name} <#{member.created_by.email}>"
+ }
+ end
+
+ experiment_instance.run
+ end
+ end
+
def member_exists?
Gitlab::AppLogger.info("Tried to send an email invitation for a deleted group. Member id: #{@member_id}") if member.blank?
member.present?
diff --git a/app/mailers/emails/profile.rb b/app/mailers/emails/profile.rb
index a8affb34f62..592c394bb48 100644
--- a/app/mailers/emails/profile.rb
+++ b/app/mailers/emails/profile.rb
@@ -6,7 +6,7 @@ module Emails
@current_user = @user = User.find(user_id)
@target_url = user_url(@user)
@token = token
- mail(to: @user.notification_email, subject: subject("Account was created for you"))
+ mail(to: @user.notification_email_or_default, subject: subject("Account was created for you"))
end
def instance_access_request_email(user, recipient)
@@ -14,7 +14,7 @@ module Emails
@recipient = recipient
profile_email_with_layout(
- to: recipient.notification_email,
+ to: recipient.notification_email_or_default,
subject: subject(_("GitLab Account Request")))
end
@@ -42,7 +42,7 @@ module Emails
@current_user = @user = @key.user
@target_url = user_url(@user)
- mail(to: @user.notification_email, subject: subject("SSH key was added to your account"))
+ mail(to: @user.notification_email_or_default, subject: subject("SSH key was added to your account"))
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -54,7 +54,7 @@ module Emails
@current_user = @user = @gpg_key.user
@target_url = user_url(@user)
- mail(to: @user.notification_email, subject: subject("GPG key was added to your account"))
+ mail(to: @user.notification_email_or_default, subject: subject("GPG key was added to your account"))
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -67,7 +67,7 @@ module Emails
@days_to_expire = PersonalAccessToken::DAYS_TO_EXPIRE
Gitlab::I18n.with_locale(@user.preferred_language) do
- mail(to: @user.notification_email, subject: subject(_("Your personal access tokens will expire in %{days_to_expire} days or less") % { days_to_expire: @days_to_expire }))
+ mail(to: @user.notification_email_or_default, subject: subject(_("Your personal access tokens will expire in %{days_to_expire} days or less") % { days_to_expire: @days_to_expire }))
end
end
@@ -78,7 +78,7 @@ module Emails
@target_url = profile_personal_access_tokens_url
Gitlab::I18n.with_locale(@user.preferred_language) do
- mail(to: @user.notification_email, subject: subject(_("Your personal access token has expired")))
+ mail(to: @user.notification_email_or_default, subject: subject(_("Your personal access token has expired")))
end
end
@@ -90,7 +90,7 @@ module Emails
@target_url = profile_keys_url
Gitlab::I18n.with_locale(@user.preferred_language) do
- mail(to: @user.notification_email, subject: subject(_("Your SSH key has expired")))
+ mail(to: @user.notification_email_or_default, subject: subject(_("Your SSH key has expired")))
end
end
@@ -102,7 +102,7 @@ module Emails
@target_url = profile_keys_url
Gitlab::I18n.with_locale(@user.preferred_language) do
- mail(to: @user.notification_email, subject: subject(_("Your SSH key is expiring soon.")))
+ mail(to: @user.notification_email_or_default, subject: subject(_("Your SSH key is expiring soon.")))
end
end
@@ -114,7 +114,7 @@ module Emails
Gitlab::I18n.with_locale(@user.preferred_language) do
profile_email_with_layout(
- to: @user.notification_email,
+ to: @user.notification_email_or_default,
subject: subject(_("%{host} sign-in from new location") % { host: Gitlab.config.gitlab.host }))
end
end
@@ -125,7 +125,7 @@ module Emails
@user = user
Gitlab::I18n.with_locale(@user.preferred_language) do
- mail(to: @user.notification_email, subject: subject(_("Two-factor authentication disabled")))
+ mail(to: @user.notification_email_or_default, subject: subject(_("Two-factor authentication disabled")))
end
end
diff --git a/app/models/analytics/cycle_analytics/issue_stage_event.rb b/app/models/analytics/cycle_analytics/issue_stage_event.rb
new file mode 100644
index 00000000000..1da8973ff21
--- /dev/null
+++ b/app/models/analytics/cycle_analytics/issue_stage_event.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module Analytics
+ module CycleAnalytics
+ class IssueStageEvent < ApplicationRecord
+ extend SuppressCompositePrimaryKeyWarning
+
+ validates(*%i[stage_event_hash_id issue_id group_id project_id start_event_timestamp], presence: true)
+ end
+ end
+end
diff --git a/app/models/analytics/cycle_analytics/merge_request_stage_event.rb b/app/models/analytics/cycle_analytics/merge_request_stage_event.rb
new file mode 100644
index 00000000000..d2f899ae933
--- /dev/null
+++ b/app/models/analytics/cycle_analytics/merge_request_stage_event.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module Analytics
+ module CycleAnalytics
+ class MergeRequestStageEvent < ApplicationRecord
+ extend SuppressCompositePrimaryKeyWarning
+
+ validates(*%i[stage_event_hash_id merge_request_id group_id project_id start_event_timestamp], presence: true)
+ end
+ end
+end
diff --git a/app/models/application_record.rb b/app/models/application_record.rb
index d9375b55e89..d2757d8c17d 100644
--- a/app/models/application_record.rb
+++ b/app/models/application_record.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
class ApplicationRecord < ActiveRecord::Base
+ self.gitlab_schema = :gitlab_main
self.abstract_class = true
alias_method :reset, :reload
@@ -30,7 +31,7 @@ class ApplicationRecord < ActiveRecord::Base
end
def self.safe_ensure_unique(retries: 0)
- transaction(requires_new: true) do
+ transaction(requires_new: true) do # rubocop:disable Performance/ActiveRecordSubtransactions
yield
end
rescue ActiveRecord::RecordNotUnique
@@ -54,7 +55,7 @@ class ApplicationRecord < ActiveRecord::Base
# currently one third of the default 15-second timeout
def self.with_fast_read_statement_timeout(timeout_ms = 5000)
::Gitlab::Database::LoadBalancing::Session.current.fallback_to_replicas_for_ambiguous_queries do
- transaction(requires_new: true) do
+ transaction(requires_new: true) do # rubocop:disable Performance/ActiveRecordSubtransactions
connection.exec_query("SET LOCAL statement_timeout = #{timeout_ms}")
yield
@@ -63,14 +64,6 @@ class ApplicationRecord < ActiveRecord::Base
end
def self.safe_find_or_create_by(*args, &block)
- return optimized_safe_find_or_create_by(*args, &block) if Feature.enabled?(:optimize_safe_find_or_create_by, default_enabled: :yaml)
-
- safe_ensure_unique(retries: 1) do
- find_or_create_by(*args, &block)
- end
- end
-
- def self.optimized_safe_find_or_create_by(*args, &block)
record = find_by(*args)
return record if record.present?
@@ -79,7 +72,7 @@ class ApplicationRecord < ActiveRecord::Base
#
# When calling this method on an association, just calling `self.create` would call `ActiveRecord::Persistence.create`
# and that skips some code that adds the newly created record to the association.
- transaction(requires_new: true) { all.create(*args, &block) }
+ transaction(requires_new: true) { all.create(*args, &block) } # rubocop:disable Performance/ActiveRecordSubtransactions
rescue ActiveRecord::RecordNotUnique
find_by(*args)
end
@@ -103,23 +96,18 @@ class ApplicationRecord < ActiveRecord::Base
enum(enum_mod.key => values)
end
- def self.transaction(**options, &block)
- if options[:requires_new] && track_subtransactions?
- ::Gitlab::Database::Metrics.subtransactions_increment(self.name)
- end
-
- super(**options, &block)
- end
-
- def self.track_subtransactions?
- ::Feature.enabled?(:active_record_subtransactions_counter, type: :ops, default_enabled: :yaml) &&
- connection.transaction_open?
- end
-
def self.cached_column_list
self.column_names.map { |column_name| self.arel_table[column_name] }
end
+ def self.default_select_columns
+ if ignored_columns.any?
+ cached_column_list
+ else
+ arel_table[Arel.star]
+ end
+ end
+
def readable_by?(user)
Ability.allowed?(user, "read_#{to_ability_name}".to_sym, self)
end
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index c4b6bcb9395..5f16b990d01 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -6,6 +6,7 @@ class ApplicationSetting < ApplicationRecord
include TokenAuthenticatable
include ChronicDurationAttribute
include IgnorableColumns
+ include Sanitizable
ignore_columns %i[elasticsearch_shards elasticsearch_replicas], remove_with: '14.4', remove_after: '2021-09-22'
ignore_column :seat_link_enabled, remove_with: '14.4', remove_after: '2021-09-22'
@@ -32,6 +33,8 @@ class ApplicationSetting < ApplicationRecord
alias_attribute :instance_group_id, :instance_administrators_group_id
alias_attribute :instance_administrators_group, :instance_group
+ sanitizes! :default_branch_name
+
def self.kroki_formats_attributes
{
blockdiag: {
@@ -204,6 +207,10 @@ class ApplicationSetting < ApplicationRecord
numericality: { only_integer: true, greater_than_or_equal_to: 0,
less_than: ::Gitlab::Pages::MAX_SIZE / 1.megabyte }
+ validates :jobs_per_stage_page_size,
+ presence: true,
+ numericality: { only_integer: true, greater_than_or_equal_to: 0 }
+
validates :default_artifacts_expire_in, presence: true, duration: true
validates :container_expiration_policies_enable_historic_entries,
@@ -343,6 +350,8 @@ class ApplicationSetting < ApplicationRecord
validates :snippet_size_limit, numericality: { only_integer: true, greater_than: 0 }
validates :wiki_page_max_content_bytes, numericality: { only_integer: true, greater_than_or_equal_to: 1.kilobytes }
+ validates :max_yaml_size_bytes, numericality: { only_integer: true, greater_than: 0 }, presence: true
+ validates :max_yaml_depth, numericality: { only_integer: true, greater_than: 0 }, presence: true
validates :email_restrictions, untrusted_regexp: true
@@ -463,53 +472,28 @@ class ApplicationSetting < ApplicationRecord
length: { maximum: 255, message: _('is too long (maximum is %{count} characters)') },
allow_blank: true
- validates :throttle_unauthenticated_requests_per_period,
- presence: true,
- numericality: { only_integer: true, greater_than: 0 }
-
- validates :throttle_unauthenticated_period_in_seconds,
- presence: true,
- numericality: { only_integer: true, greater_than: 0 }
-
- validates :throttle_unauthenticated_packages_api_requests_per_period,
- presence: true,
- numericality: { only_integer: true, greater_than: 0 }
-
- validates :throttle_unauthenticated_packages_api_period_in_seconds,
- presence: true,
- numericality: { only_integer: true, greater_than: 0 }
-
- validates :throttle_authenticated_api_requests_per_period,
- presence: true,
- numericality: { only_integer: true, greater_than: 0 }
-
- validates :throttle_authenticated_api_period_in_seconds,
- presence: true,
- numericality: { only_integer: true, greater_than: 0 }
-
- validates :throttle_authenticated_web_requests_per_period,
- presence: true,
- numericality: { only_integer: true, greater_than: 0 }
-
- validates :throttle_authenticated_web_period_in_seconds,
- presence: true,
- numericality: { only_integer: true, greater_than: 0 }
-
- validates :throttle_authenticated_packages_api_requests_per_period,
- presence: true,
- numericality: { only_integer: true, greater_than: 0 }
-
- validates :throttle_authenticated_packages_api_period_in_seconds,
- presence: true,
- numericality: { only_integer: true, greater_than: 0 }
-
- validates :throttle_protected_paths_requests_per_period,
- presence: true,
- numericality: { only_integer: true, greater_than: 0 }
-
- validates :throttle_protected_paths_period_in_seconds,
- presence: true,
- numericality: { only_integer: true, greater_than: 0 }
+ with_options(presence: true, numericality: { only_integer: true, greater_than: 0 }) do
+ validates :throttle_unauthenticated_api_requests_per_period
+ validates :throttle_unauthenticated_api_period_in_seconds
+ validates :throttle_unauthenticated_requests_per_period
+ validates :throttle_unauthenticated_period_in_seconds
+ validates :throttle_unauthenticated_packages_api_requests_per_period
+ validates :throttle_unauthenticated_packages_api_period_in_seconds
+ validates :throttle_unauthenticated_files_api_requests_per_period
+ validates :throttle_unauthenticated_files_api_period_in_seconds
+ validates :throttle_authenticated_api_requests_per_period
+ validates :throttle_authenticated_api_period_in_seconds
+ validates :throttle_authenticated_git_lfs_requests_per_period
+ validates :throttle_authenticated_git_lfs_period_in_seconds
+ validates :throttle_authenticated_web_requests_per_period
+ validates :throttle_authenticated_web_period_in_seconds
+ validates :throttle_authenticated_packages_api_requests_per_period
+ validates :throttle_authenticated_packages_api_period_in_seconds
+ validates :throttle_authenticated_files_api_requests_per_period
+ validates :throttle_authenticated_files_api_period_in_seconds
+ validates :throttle_protected_paths_requests_per_period
+ validates :throttle_protected_paths_period_in_seconds
+ end
validates :notes_create_limit,
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
@@ -534,6 +518,18 @@ class ApplicationSetting < ApplicationRecord
validates :floc_enabled,
inclusion: { in: [true, false], message: _('must be a boolean value') }
+ enum sidekiq_job_limiter_mode: {
+ Gitlab::SidekiqMiddleware::SizeLimiter::Validator::TRACK_MODE => 0,
+ Gitlab::SidekiqMiddleware::SizeLimiter::Validator::COMPRESS_MODE => 1 # The default
+ }
+
+ validates :sidekiq_job_limiter_mode,
+ inclusion: { in: self.sidekiq_job_limiter_modes }
+ validates :sidekiq_job_limiter_compression_threshold_bytes,
+ numericality: { only_integer: true, greater_than_or_equal_to: 0 }
+ validates :sidekiq_job_limiter_limit_bytes,
+ numericality: { only_integer: true, greater_than_or_equal_to: 0 }
+
attr_encrypted :asset_proxy_secret_key,
mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_truncated,
@@ -573,7 +569,7 @@ class ApplicationSetting < ApplicationRecord
before_validation :ensure_uuid!
before_validation :coerce_repository_storages_weighted, if: :repository_storages_weighted_changed?
- before_validation :sanitize_default_branch_name
+ before_validation :normalize_default_branch_name
before_save :ensure_runners_registration_token
before_save :ensure_health_check_access_token
@@ -603,12 +599,8 @@ class ApplicationSetting < ApplicationRecord
!!(sourcegraph_url =~ %r{\Ahttps://(www\.)?sourcegraph\.com})
end
- def sanitize_default_branch_name
- self.default_branch_name = if default_branch_name.blank?
- nil
- else
- Sanitize.fragment(self.default_branch_name)
- end
+ def normalize_default_branch_name
+ self.default_branch_name = default_branch_name.presence
end
def instance_review_permitted?
@@ -622,7 +614,7 @@ class ApplicationSetting < ApplicationRecord
def self.create_from_defaults
check_schema!
- transaction(requires_new: true) do
+ transaction(requires_new: true) do # rubocop:disable Performance/ActiveRecordSubtransactions
super
end
rescue ActiveRecord::RecordNotUnique
diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb
index 060c831a11b..612fda158d3 100644
--- a/app/models/application_setting_implementation.rb
+++ b/app/models/application_setting_implementation.rb
@@ -109,6 +109,8 @@ module ApplicationSettingImplementation
max_artifacts_size: Settings.artifacts['max_size'],
max_attachment_size: Settings.gitlab['max_attachment_size'],
max_import_size: 0,
+ max_yaml_size_bytes: 1.megabyte,
+ max_yaml_depth: 100,
minimum_password_length: DEFAULT_MINIMUM_PASSWORD_LENGTH,
mirror_available: true,
notes_create_limit: 300,
@@ -161,24 +163,36 @@ module ApplicationSettingImplementation
throttle_authenticated_api_enabled: false,
throttle_authenticated_api_period_in_seconds: 3600,
throttle_authenticated_api_requests_per_period: 7200,
+ throttle_authenticated_git_lfs_enabled: false,
+ throttle_authenticated_git_lfs_period_in_seconds: 60,
+ throttle_authenticated_git_lfs_requests_per_period: 1000,
throttle_authenticated_web_enabled: false,
throttle_authenticated_web_period_in_seconds: 3600,
throttle_authenticated_web_requests_per_period: 7200,
throttle_authenticated_packages_api_enabled: false,
throttle_authenticated_packages_api_period_in_seconds: 15,
throttle_authenticated_packages_api_requests_per_period: 1000,
+ throttle_authenticated_files_api_enabled: false,
+ throttle_authenticated_files_api_period_in_seconds: 15,
+ throttle_authenticated_files_api_requests_per_period: 500,
throttle_incident_management_notification_enabled: false,
throttle_incident_management_notification_per_period: 3600,
throttle_incident_management_notification_period_in_seconds: 3600,
throttle_protected_paths_enabled: false,
throttle_protected_paths_in_seconds: 10,
throttle_protected_paths_per_period: 60,
+ throttle_unauthenticated_api_enabled: false,
+ throttle_unauthenticated_api_period_in_seconds: 3600,
+ throttle_unauthenticated_api_requests_per_period: 3600,
throttle_unauthenticated_enabled: false,
throttle_unauthenticated_period_in_seconds: 3600,
throttle_unauthenticated_requests_per_period: 3600,
throttle_unauthenticated_packages_api_enabled: false,
throttle_unauthenticated_packages_api_period_in_seconds: 15,
throttle_unauthenticated_packages_api_requests_per_period: 800,
+ throttle_unauthenticated_files_api_enabled: false,
+ throttle_unauthenticated_files_api_period_in_seconds: 15,
+ throttle_unauthenticated_files_api_requests_per_period: 125,
time_tracking_limit_to_hours: false,
two_factor_grace_period: 48,
unique_ips_limit_enabled: false,
@@ -197,7 +211,8 @@ module ApplicationSettingImplementation
kroki_url: nil,
kroki_formats: { blockdiag: false, bpmn: false, excalidraw: false },
rate_limiting_response_text: nil,
- whats_new_variant: 0
+ whats_new_variant: 0,
+ user_deactivation_emails_enabled: true
}
end
diff --git a/app/models/award_emoji.rb b/app/models/award_emoji.rb
index c8f6b9aaedb..d251b0adbd3 100644
--- a/app/models/award_emoji.rb
+++ b/app/models/award_emoji.rb
@@ -66,3 +66,5 @@ class AwardEmoji < ApplicationRecord
awardable.try(:update_upvotes_count) if upvote?
end
end
+
+AwardEmoji.prepend_mod_with('AwardEmoji')
diff --git a/app/models/bulk_imports/entity.rb b/app/models/bulk_imports/entity.rb
index 24f86b44841..ab5d248ff8c 100644
--- a/app/models/bulk_imports/entity.rb
+++ b/app/models/bulk_imports/entity.rb
@@ -78,6 +78,30 @@ class BulkImports::Entity < ApplicationRecord
ERB::Util.url_encode(source_full_path)
end
+ def pipelines
+ @pipelines ||= case source_type
+ when 'group_entity'
+ BulkImports::Groups::Stage.pipelines
+ when 'project_entity'
+ BulkImports::Projects::Stage.pipelines
+ end
+ end
+
+ def pipeline_exists?(name)
+ pipelines.any? { |_, pipeline| pipeline.to_s == name.to_s }
+ end
+
+ def create_pipeline_trackers!
+ self.class.transaction do
+ pipelines.each do |stage, pipeline|
+ trackers.create!(
+ stage: stage,
+ pipeline_name: pipeline
+ )
+ end
+ end
+ end
+
private
def validate_parent_is_a_group
diff --git a/app/models/bulk_imports/tracker.rb b/app/models/bulk_imports/tracker.rb
index 1b108d5c042..c185470b1c2 100644
--- a/app/models/bulk_imports/tracker.rb
+++ b/app/models/bulk_imports/tracker.rb
@@ -34,8 +34,8 @@ class BulkImports::Tracker < ApplicationRecord
end
def pipeline_class
- unless BulkImports::Stage.pipeline_exists?(pipeline_name)
- raise NameError, "'#{pipeline_name}' is not a valid BulkImport Pipeline"
+ unless entity.pipeline_exists?(pipeline_name)
+ raise BulkImports::Error, "'#{pipeline_name}' is not a valid BulkImport Pipeline"
end
pipeline_name.constantize
diff --git a/app/models/ci/application_record.rb b/app/models/ci/application_record.rb
index 9d4a8f0648e..913e7a62c66 100644
--- a/app/models/ci/application_record.rb
+++ b/app/models/ci/application_record.rb
@@ -2,6 +2,7 @@
module Ci
class ApplicationRecord < ::ApplicationRecord
+ self.gitlab_schema = :gitlab_ci
self.abstract_class = true
def self.table_name_prefix
diff --git a/app/models/ci/bridge.rb b/app/models/ci/bridge.rb
index 577bca282ef..97fb8233d34 100644
--- a/app/models/ci/bridge.rb
+++ b/app/models/ci/bridge.rb
@@ -28,10 +28,10 @@ module Ci
state_machine :status do
after_transition [:created, :manual, :waiting_for_resource] => :pending do |bridge|
- next unless bridge.downstream_project
+ next unless bridge.triggers_downstream_pipeline?
bridge.run_after_commit do
- bridge.schedule_downstream_pipeline!
+ ::Ci::CreateCrossProjectPipelineWorker.perform_async(bridge.id)
end
end
@@ -64,12 +64,6 @@ module Ci
)
end
- def schedule_downstream_pipeline!
- raise InvalidBridgeTypeError unless downstream_project
-
- ::Ci::CreateCrossProjectPipelineWorker.perform_async(self.id)
- end
-
def inherit_status_from_downstream!(pipeline)
case pipeline.status
when 'success'
@@ -112,10 +106,18 @@ module Ci
pipeline if triggers_child_pipeline?
end
+ def triggers_downstream_pipeline?
+ triggers_child_pipeline? || triggers_cross_project_pipeline?
+ end
+
def triggers_child_pipeline?
yaml_for_downstream.present?
end
+ def triggers_cross_project_pipeline?
+ downstream_project_path.present?
+ end
+
def tags
[:bridge]
end
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 1ca291a659b..e2e24247679 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -90,6 +90,10 @@ module Ci
end
end
+ def persisted_environment=(environment)
+ strong_memoize(:persisted_environment) { environment }
+ end
+
serialize :options # rubocop:disable Cop/ActiveRecordSerialize
serialize :yaml_variables, Gitlab::Serializer::Ci::Variables # rubocop:disable Cop/ActiveRecordSerialize
@@ -166,8 +170,6 @@ module Ci
scope :with_stale_live_trace, -> { with_live_trace.finished_before(12.hours.ago) }
scope :finished_before, -> (date) { finished.where('finished_at < ?', date) }
- scope :with_secure_reports_from_options, -> (job_type) { where('options like :job_type', job_type: "%:artifacts:%:reports:%:#{job_type}:%") }
-
scope :with_secure_reports_from_config_options, -> (job_types) do
joins(:metadata).where("ci_builds_metadata.config_options -> 'artifacts' -> 'reports' ?| array[:job_types]", job_types: job_types)
end
@@ -306,7 +308,9 @@ module Ci
end
after_transition pending: :running do |build|
- build.deployment&.run
+ Gitlab::Database.allow_cross_database_modification_within_transaction(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338867') do
+ build.deployment&.run
+ end
build.run_after_commit do
build.pipeline.persistent_ref.create
@@ -328,7 +332,9 @@ module Ci
end
after_transition any => [:success] do |build|
- build.deployment&.succeed
+ Gitlab::Database.allow_cross_database_modification_within_transaction(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338867') do
+ build.deployment&.succeed
+ end
build.run_after_commit do
BuildSuccessWorker.perform_async(id)
@@ -341,7 +347,9 @@ module Ci
next unless build.deployment
begin
- build.deployment.drop!
+ Gitlab::Database.allow_cross_database_modification_within_transaction(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338867') do
+ build.deployment.drop!
+ end
rescue StandardError => e
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e, build_id: build.id)
end
@@ -362,10 +370,12 @@ module Ci
end
after_transition any => [:skipped, :canceled] do |build, transition|
- if transition.to_name == :skipped
- build.deployment&.skip
- else
- build.deployment&.cancel
+ Gitlab::Database.allow_cross_database_modification_within_transaction(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338867') do
+ if transition.to_name == :skipped
+ build.deployment&.skip
+ else
+ build.deployment&.cancel
+ end
end
end
end
@@ -712,6 +722,10 @@ module Ci
update_column(:trace, nil)
end
+ def ensure_trace_metadata!
+ Ci::BuildTraceMetadata.find_or_upsert_for!(id)
+ end
+
def artifacts_expose_as
options.dig(:artifacts, :expose_as)
end
@@ -748,7 +762,9 @@ module Ci
def any_runners_available?
cache_for_available_runners do
- project.active_runners.exists?
+ ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/339937') do
+ project.active_runners.exists?
+ end
end
end
@@ -1013,9 +1029,10 @@ module Ci
# Consider this object to have a structural integrity problems
def doom!
- update_columns(
- status: :failed,
- failure_reason: :data_integrity_failure)
+ transaction do
+ update_columns(status: :failed, failure_reason: :data_integrity_failure)
+ all_queuing_entries.delete_all
+ end
end
def degradation_threshold
diff --git a/app/models/ci/build_trace_chunks/fog.rb b/app/models/ci/build_trace_chunks/fog.rb
index 3bfac2b33c0..1cae2279434 100644
--- a/app/models/ci/build_trace_chunks/fog.rb
+++ b/app/models/ci/build_trace_chunks/fog.rb
@@ -80,12 +80,10 @@ module Ci
private
def append_strings(old_data, new_data)
- if Feature.enabled?(:ci_job_trace_force_encode, default_enabled: :yaml)
- # When object storage is in use, old_data may be retrieved in UTF-8.
- old_data = old_data.force_encoding(Encoding::ASCII_8BIT)
- # new_data should already be in ASCII-8BIT, but just in case it isn't, do this.
- new_data = new_data.force_encoding(Encoding::ASCII_8BIT)
- end
+ # When object storage is in use, old_data may be retrieved in UTF-8.
+ old_data = old_data.force_encoding(Encoding::ASCII_8BIT)
+ # new_data should already be in ASCII-8BIT, but just in case it isn't, do this.
+ new_data = new_data.force_encoding(Encoding::ASCII_8BIT)
old_data + new_data
end
diff --git a/app/models/ci/build_trace_metadata.rb b/app/models/ci/build_trace_metadata.rb
index 05bdb3d8b7b..901b84ceec6 100644
--- a/app/models/ci/build_trace_metadata.rb
+++ b/app/models/ci/build_trace_metadata.rb
@@ -2,6 +2,7 @@
module Ci
class BuildTraceMetadata < Ci::ApplicationRecord
+ MAX_ATTEMPTS = 5
self.table_name = 'ci_build_trace_metadata'
self.primary_key = :build_id
@@ -9,5 +10,49 @@ module Ci
belongs_to :trace_artifact, class_name: 'Ci::JobArtifact'
validates :build, presence: true
+ validates :archival_attempts, presence: true
+
+ def self.find_or_upsert_for!(build_id)
+ record = find_by(build_id: build_id)
+ return record if record
+
+ upsert({ build_id: build_id }, unique_by: :build_id)
+ find_by!(build_id: build_id)
+ end
+
+ # The job is retried around 5 times during the 7 days retention period for
+ # trace chunks as defined in `Ci::BuildTraceChunks::RedisBase::CHUNK_REDIS_TTL`
+ def can_attempt_archival_now?
+ return false unless archival_attempts_available?
+ return true unless last_archival_attempt_at
+
+ last_archival_attempt_at + backoff < Time.current
+ end
+
+ def archival_attempts_available?
+ archival_attempts <= MAX_ATTEMPTS
+ end
+
+ def increment_archival_attempts!
+ increment!(:archival_attempts, touch: :last_archival_attempt_at)
+ end
+
+ def track_archival!(trace_artifact_id)
+ update!(trace_artifact_id: trace_artifact_id, archived_at: Time.current)
+ end
+
+ def archival_attempts_message
+ if archival_attempts_available?
+ 'The job can not be archived right now.'
+ else
+ 'The job is out of archival attempts.'
+ end
+ end
+
+ private
+
+ def backoff
+ ::Gitlab::Ci::Trace::Backoff.new(archival_attempts).value_with_jitter
+ end
end
end
diff --git a/app/models/ci/job_artifact.rb b/app/models/ci/job_artifact.rb
index 1f0da4345f2..ad3e867f9d5 100644
--- a/app/models/ci/job_artifact.rb
+++ b/app/models/ci/job_artifact.rb
@@ -10,6 +10,9 @@ module Ci
include Artifactable
include FileStoreMounter
include EachBatch
+ include IgnorableColumns
+
+ ignore_columns %i[id_convert_to_bigint job_id_convert_to_bigint], remove_with: '14.5', remove_after: '2021-11-22'
TEST_REPORT_FILE_TYPES = %w[junit].freeze
COVERAGE_REPORT_FILE_TYPES = %w[cobertura].freeze
@@ -182,7 +185,6 @@ module Ci
scope :order_expired_desc, -> { order(expire_at: :desc) }
scope :with_destroy_preloads, -> { includes(project: [:route, :statistics]) }
- scope :scoped_project, -> { where('ci_job_artifacts.project_id = projects.id') }
scope :for_project, ->(project) { where(project_id: project) }
scope :created_in_time_range, ->(from: nil, to: nil) { where(created_at: from..to) }
@@ -232,6 +234,17 @@ module Ci
hashed_path: 2
}
+ # `locked` will be populated from the source of truth on Ci::Pipeline
+ # in order to clean up expired job artifacts in a performant way.
+ # The values should be the same as `Ci::Pipeline.lockeds` with the
+ # additional value of `unknown` to indicate rows that have not
+ # yet been populated from the parent Ci::Pipeline
+ enum locked: {
+ unlocked: 0,
+ artifacts_locked: 1,
+ unknown: 2
+ }, _prefix: :artifact
+
def validate_file_format!
unless TYPE_AND_FORMAT_PAIRS[self.file_type&.to_sym] == self.file_format&.to_sym
errors.add(:base, _('Invalid file format with specified file type'))
diff --git a/app/models/ci/pending_build.rb b/app/models/ci/pending_build.rb
index 7cf3a387516..ccad6290fac 100644
--- a/app/models/ci/pending_build.rb
+++ b/app/models/ci/pending_build.rb
@@ -2,6 +2,8 @@
module Ci
class PendingBuild < Ci::ApplicationRecord
+ include EachBatch
+
belongs_to :project
belongs_to :build, class_name: 'Ci::Build'
belongs_to :namespace, inverse_of: :pending_builds, class_name: 'Namespace'
@@ -11,52 +13,62 @@ module Ci
scope :ref_protected, -> { where(protected: true) }
scope :queued_before, ->(time) { where(arel_table[:created_at].lt(time)) }
scope :with_instance_runners, -> { where(instance_runners_enabled: true) }
+ scope :for_tags, ->(tag_ids) do
+ if tag_ids.present?
+ where('ci_pending_builds.tag_ids <@ ARRAY[?]::int[]', Array.wrap(tag_ids))
+ else
+ where("ci_pending_builds.tag_ids = '{}'")
+ end
+ end
- def self.upsert_from_build!(build)
- entry = self.new(args_from_build(build))
+ class << self
+ def upsert_from_build!(build)
+ entry = self.new(args_from_build(build))
- entry.validate!
+ entry.validate!
- self.upsert(entry.attributes.compact, returning: %w[build_id], unique_by: :build_id)
- end
+ self.upsert(entry.attributes.compact, returning: %w[build_id], unique_by: :build_id)
+ end
- def self.args_from_build(build)
- args = {
- build: build,
- project: build.project,
- protected: build.protected?,
- namespace: build.project.namespace
- }
+ private
+
+ def args_from_build(build)
+ project = build.project
+
+ args = {
+ build: build,
+ project: project,
+ protected: build.protected?,
+ namespace: project.namespace
+ }
+
+ if Feature.enabled?(:ci_pending_builds_maintain_tags_data, type: :development, default_enabled: :yaml)
+ args.store(:tag_ids, build.tags_ids)
+ end
+
+ if Feature.enabled?(:ci_pending_builds_maintain_shared_runners_data, type: :development, default_enabled: :yaml)
+ args.store(:instance_runners_enabled, shared_runners_enabled?(project))
+ end
+
+ if Feature.enabled?(:ci_pending_builds_maintain_namespace_traversal_ids, type: :development, default_enabled: :yaml)
+ args.store(:namespace_traversal_ids, project.namespace.traversal_ids) if group_runners_enabled?(project)
+ end
- if Feature.enabled?(:ci_pending_builds_maintain_shared_runners_data, type: :development, default_enabled: :yaml)
- args.merge(instance_runners_enabled: shareable?(build))
- else
args
end
- end
- private_class_method :args_from_build
-
- def self.shareable?(build)
- shared_runner_enabled?(build) &&
- builds_access_level?(build) &&
- project_not_removed?(build)
- end
- private_class_method :shareable?
- def self.shared_runner_enabled?(build)
- build.project.shared_runners.exists?
- end
- private_class_method :shared_runner_enabled?
+ def shared_runners_enabled?(project)
+ builds_enabled?(project) && project.shared_runners_enabled?
+ end
- def self.project_not_removed?(build)
- !build.project.pending_delete?
- end
- private_class_method :project_not_removed?
+ def group_runners_enabled?(project)
+ builds_enabled?(project) && project.group_runners_enabled?
+ end
- def self.builds_access_level?(build)
- build.project.project_feature.builds_access_level.nil? || build.project.project_feature.builds_access_level > 0
+ def builds_enabled?(project)
+ project.builds_enabled? && !project.pending_delete?
+ end
end
- private_class_method :builds_access_level?
end
end
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 70e67953e31..1a0cec3c935 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -66,6 +66,7 @@ module Ci
has_many :processables, class_name: 'Ci::Processable', foreign_key: :commit_id, inverse_of: :pipeline
has_many :bridges, class_name: 'Ci::Bridge', foreign_key: :commit_id, inverse_of: :pipeline
has_many :builds, foreign_key: :commit_id, inverse_of: :pipeline
+ has_many :generic_commit_statuses, foreign_key: :commit_id, inverse_of: :pipeline, class_name: 'GenericCommitStatus'
has_many :job_artifacts, through: :builds
has_many :trigger_requests, dependent: :destroy, foreign_key: :commit_id # rubocop:disable Cop/ActiveRecordDependent
has_many :variables, class_name: 'Ci::PipelineVariable'
@@ -307,6 +308,7 @@ module Ci
scope :ci_and_parent_sources, -> { where(source: Enums::Ci::Pipeline.ci_and_parent_sources.values) }
scope :for_user, -> (user) { where(user: user) }
scope :for_sha, -> (sha) { where(sha: sha) }
+ scope :where_not_sha, -> (sha) { where.not(sha: sha) }
scope :for_source_sha, -> (source_sha) { where(source_sha: source_sha) }
scope :for_sha_or_source_sha, -> (sha) { for_sha(sha).or(for_source_sha(sha)) }
scope :for_ref, -> (ref) { where(ref: ref) }
@@ -317,7 +319,6 @@ module Ci
scope :created_after, -> (time) { where('ci_pipelines.created_at > ?', time) }
scope :created_before_id, -> (id) { where('ci_pipelines.id < ?', id) }
scope :before_pipeline, -> (pipeline) { created_before_id(pipeline.id).outside_pipeline_family(pipeline) }
- scope :eager_load_project, -> { eager_load(project: [:route, { namespace: :route }]) }
scope :with_pipeline_source, -> (source) { where(source: source)}
scope :outside_pipeline_family, ->(pipeline) do
@@ -588,13 +589,11 @@ module Ci
end
def cancel_running(retries: 1)
- commit_status_relations = [:project, :pipeline]
- ci_build_relations = [:deployment, :taggings]
+ preloaded_relations = [:project, :pipeline, :deployment, :taggings]
retry_lock(cancelable_statuses, retries, name: 'ci_pipeline_cancel_running') do |cancelables|
cancelables.find_in_batches do |batch|
- ActiveRecord::Associations::Preloader.new.preload(batch, commit_status_relations)
- ActiveRecord::Associations::Preloader.new.preload(batch.select { |job| job.is_a?(Ci::Build) }, ci_build_relations)
+ Preloaders::CommitStatusPreloader.new(batch).execute(preloaded_relations)
batch.each do |job|
yield(job) if block_given?
@@ -1108,7 +1107,7 @@ module Ci
merge_request.modified_paths
elsif branch_updated?
push_details.modified_paths
- elsif external_pull_request? && ::Feature.enabled?(:ci_modified_paths_of_external_prs, project, default_enabled: :yaml)
+ elsif external_pull_request?
external_pull_request.modified_paths
end
end
@@ -1220,24 +1219,12 @@ module Ci
self.ci_ref = Ci::Ref.ensure_for(self)
end
- # We need `base_and_ancestors` in a specific order to "break" when needed.
- # If we use `find_each`, then the order is broken.
- # rubocop:disable Rails/FindEach
def reset_source_bridge!(current_user)
- if ::Feature.enabled?(:ci_reset_bridge_with_subsequent_jobs, project, default_enabled: :yaml)
- return unless bridge_waiting?
+ return unless bridge_waiting?
- source_bridge.pending!
- Ci::AfterRequeueJobService.new(project, current_user).execute(source_bridge) # rubocop:disable CodeReuse/ServiceClass
- else
- self_and_upstreams.includes(:source_bridge).each do |pipeline|
- break unless pipeline.bridge_waiting?
-
- pipeline.source_bridge.pending!
- end
- end
+ source_bridge.pending!
+ Ci::AfterRequeueJobService.new(project, current_user).execute(source_bridge) # rubocop:disable CodeReuse/ServiceClass
end
- # rubocop:enable Rails/FindEach
# EE-only
def merge_train_pipeline?
diff --git a/app/models/ci/pipeline_variable.rb b/app/models/ci/pipeline_variable.rb
index a0e8886414b..3dca77af051 100644
--- a/app/models/ci/pipeline_variable.rb
+++ b/app/models/ci/pipeline_variable.rb
@@ -8,7 +8,7 @@ module Ci
alias_attribute :secret_value, :value
- validates :key, uniqueness: { scope: :pipeline_id }
+ validates :key, presence: true
def hook_attrs
{ key: key, value: value }
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index 432c3a408a9..4aa232ad26b 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -208,16 +208,18 @@ module Ci
Arel.sql("(#{arel_tag_names_array.to_sql})")
]
- group(*unique_params).pluck('array_agg(ci_runners.id)', *unique_params).map do |values|
- Gitlab::Ci::Matching::RunnerMatcher.new({
- runner_ids: values[0],
- runner_type: values[1],
- public_projects_minutes_cost_factor: values[2],
- private_projects_minutes_cost_factor: values[3],
- run_untagged: values[4],
- access_level: values[5],
- tag_list: values[6]
- })
+ ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/339621') do
+ group(*unique_params).pluck('array_agg(ci_runners.id)', *unique_params).map do |values|
+ Gitlab::Ci::Matching::RunnerMatcher.new({
+ runner_ids: values[0],
+ runner_type: values[1],
+ public_projects_minutes_cost_factor: values[2],
+ private_projects_minutes_cost_factor: values[3],
+ run_untagged: values[4],
+ access_level: values[5],
+ tag_list: values[6]
+ })
+ end
end
end
@@ -385,6 +387,12 @@ module Ci
read_attribute(:contacted_at)
end
+ def namespace_ids
+ strong_memoize(:namespace_ids) do
+ runner_namespaces.pluck(:namespace_id).compact
+ end
+ end
+
private
def cleanup_runner_queue
@@ -420,14 +428,18 @@ module Ci
end
def no_projects
- if projects.any?
- errors.add(:runner, 'cannot have projects assigned')
+ ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338659') do
+ if projects.any?
+ errors.add(:runner, 'cannot have projects assigned')
+ end
end
end
def no_groups
- if groups.any?
- errors.add(:runner, 'cannot have groups assigned')
+ ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338659') do
+ if groups.any?
+ errors.add(:runner, 'cannot have groups assigned')
+ end
end
end
diff --git a/app/models/ci/sources/pipeline.rb b/app/models/ci/sources/pipeline.rb
index f78caf710a6..95842d944f9 100644
--- a/app/models/ci/sources/pipeline.rb
+++ b/app/models/ci/sources/pipeline.rb
@@ -4,6 +4,9 @@ module Ci
module Sources
class Pipeline < Ci::ApplicationRecord
include Ci::NamespacedModelName
+ include IgnorableColumns
+
+ ignore_columns 'source_job_id_convert_to_bigint', remove_with: '14.5', remove_after: '2021-11-22'
self.table_name = "ci_sources_pipelines"
diff --git a/app/models/clusters/agent.rb b/app/models/clusters/agent.rb
index 9fb8cd024c5..cf6d95fc6df 100644
--- a/app/models/clusters/agent.rb
+++ b/app/models/clusters/agent.rb
@@ -10,6 +10,12 @@ module Clusters
has_many :agent_tokens, class_name: 'Clusters::AgentToken'
has_many :last_used_agent_tokens, -> { order_last_used_at_desc }, class_name: 'Clusters::AgentToken', inverse_of: :agent
+ has_many :group_authorizations, class_name: 'Clusters::Agents::GroupAuthorization'
+ has_many :authorized_groups, class_name: '::Group', through: :group_authorizations, source: :group
+
+ has_many :project_authorizations, class_name: 'Clusters::Agents::ProjectAuthorization'
+ has_many :authorized_projects, class_name: '::Project', through: :project_authorizations, source: :project
+
scope :ordered_by_name, -> { order(:name) }
scope :with_name, -> (name) { where(name: name) }
diff --git a/app/models/clusters/agents/group_authorization.rb b/app/models/clusters/agents/group_authorization.rb
new file mode 100644
index 00000000000..74c0cec3b7e
--- /dev/null
+++ b/app/models/clusters/agents/group_authorization.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Clusters
+ module Agents
+ class GroupAuthorization < ApplicationRecord
+ self.table_name = 'agent_group_authorizations'
+
+ belongs_to :agent, class_name: 'Clusters::Agent', optional: false
+ belongs_to :group, class_name: '::Group', optional: false
+
+ validates :config, json_schema: { filename: 'cluster_agent_authorization_configuration' }
+
+ delegate :project, to: :agent
+ end
+ end
+end
diff --git a/app/models/clusters/agents/implicit_authorization.rb b/app/models/clusters/agents/implicit_authorization.rb
new file mode 100644
index 00000000000..967cc686045
--- /dev/null
+++ b/app/models/clusters/agents/implicit_authorization.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module Clusters
+ module Agents
+ class ImplicitAuthorization
+ attr_reader :agent
+
+ delegate :id, to: :agent, prefix: true
+ delegate :project, to: :agent
+
+ def initialize(agent:)
+ @agent = agent
+ end
+
+ def config
+ nil
+ end
+ end
+ end
+end
diff --git a/app/models/clusters/agents/project_authorization.rb b/app/models/clusters/agents/project_authorization.rb
new file mode 100644
index 00000000000..1c71a0a432a
--- /dev/null
+++ b/app/models/clusters/agents/project_authorization.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module Clusters
+ module Agents
+ class ProjectAuthorization < ApplicationRecord
+ self.table_name = 'agent_project_authorizations'
+
+ belongs_to :agent, class_name: 'Clusters::Agent', optional: false
+ belongs_to :project, class_name: '::Project', optional: false
+
+ validates :config, json_schema: { filename: 'cluster_agent_authorization_configuration' }
+ end
+ end
+end
diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb
index 2fff0a69a26..feac7bbc363 100644
--- a/app/models/clusters/cluster.rb
+++ b/app/models/clusters/cluster.rb
@@ -148,6 +148,7 @@ module Clusters
scope :with_management_project, -> { where.not(management_project: nil) }
scope :for_project_namespace, -> (namespace_id) { joins(:projects).where(projects: { namespace_id: namespace_id }) }
+ scope :with_name, -> (name) { where(name: name) }
# with_application_prometheus scope is deprecated, and scheduled for removal
# in %14.0. See https://gitlab.com/groups/gitlab-org/-/epics/4280
diff --git a/app/models/clusters/clusters_hierarchy.rb b/app/models/clusters/clusters_hierarchy.rb
index 162a1a3290d..9435d258d67 100644
--- a/app/models/clusters/clusters_hierarchy.rb
+++ b/app/models/clusters/clusters_hierarchy.rb
@@ -83,7 +83,7 @@ module Clusters
project_id: clusterable.id
}
- model.sanitize_sql_array([Arel.sql(order), values])
+ Arel.sql(model.sanitize_sql_array([Arel.sql(order), values]))
end
def group_clusters_base_query
diff --git a/app/models/clusters/platforms/kubernetes.rb b/app/models/clusters/platforms/kubernetes.rb
index 7f5f87e3e36..7ec614b048c 100644
--- a/app/models/clusters/platforms/kubernetes.rb
+++ b/app/models/clusters/platforms/kubernetes.rb
@@ -137,6 +137,14 @@ module Clusters
kubeclient.patch_ingress(ingress.name, data, namespace)
end
+ def kubeconfig(namespace)
+ to_kubeconfig(
+ url: api_url,
+ namespace: namespace,
+ token: token,
+ ca_pem: ca_pem)
+ end
+
private
def default_namespace(project, environment_name:)
@@ -154,14 +162,6 @@ module Clusters
).execute
end
- def kubeconfig(namespace)
- to_kubeconfig(
- url: api_url,
- namespace: namespace,
- token: token,
- ca_pem: ca_pem)
- end
-
def read_pods(namespace)
kubeclient.get_pods(namespace: namespace).as_json
rescue Kubeclient::ResourceNotFoundError
diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb
index b34d64de101..8cba3d04502 100644
--- a/app/models/commit_status.rb
+++ b/app/models/commit_status.rb
@@ -56,15 +56,19 @@ class CommitStatus < Ci::ApplicationRecord
scope :for_ref, -> (ref) { where(ref: ref) }
scope :by_name, -> (name) { where(name: name) }
scope :in_pipelines, ->(pipelines) { where(pipeline: pipelines) }
- scope :eager_load_pipeline, -> { eager_load(:pipeline, project: { namespace: :route }) }
scope :with_pipeline, -> { joins(:pipeline) }
- scope :updated_at_before, ->(date) { where('updated_at < ?', date) }
+ scope :updated_at_before, ->(date) { where('ci_builds.updated_at < ?', date) }
+ scope :created_at_before, ->(date) { where('ci_builds.created_at < ?', date) }
scope :updated_before, ->(lookback:, timeout:) {
where('(ci_builds.created_at BETWEEN ? AND ?) AND (ci_builds.updated_at BETWEEN ? AND ?)', lookback, timeout, lookback, timeout)
}
+ # The scope applies `pluck` to split the queries. Use with care.
scope :for_project_paths, -> (paths) do
- where(project: Project.where_full_path_in(Array(paths)))
+ # Pluck is used to split this query. Splitting the query is required for database decomposition for `ci_*` tables.
+ # https://docs.gitlab.com/ee/development/database/transaction_guidelines.html#database-decomposition-and-sharding
+ project_ids = Project.where_full_path_in(Array(paths)).pluck(:id)
+ where(project: project_ids)
end
scope :with_preloads, -> do
diff --git a/app/models/compare.rb b/app/models/compare.rb
index 2eaaf98c260..f1b0bf19c11 100644
--- a/app/models/compare.rb
+++ b/app/models/compare.rb
@@ -25,6 +25,16 @@ class Compare
@straight = straight
end
+ # Return a Hash of parameters for passing to a URL helper
+ #
+ # See `namespace_project_compare_url`
+ def to_param
+ {
+ from: @straight ? start_commit_sha : base_commit_sha,
+ to: head_commit_sha
+ }
+ end
+
def cache_key
[@project, :compare, diff_refs.hash]
end
diff --git a/app/models/concerns/approvable_base.rb b/app/models/concerns/approvable_base.rb
index ef7ba7b1089..8240f9bd6ea 100644
--- a/app/models/concerns/approvable_base.rb
+++ b/app/models/concerns/approvable_base.rb
@@ -54,4 +54,8 @@ module ApprovableBase
def can_be_approved_by?(user)
user && !approved_by?(user) && user.can?(:approve_merge_request, self)
end
+
+ def can_be_unapproved_by?(user)
+ user && approved_by?(user) && user.can?(:approve_merge_request, self)
+ end
end
diff --git a/app/models/concerns/cache_markdown_field.rb b/app/models/concerns/cache_markdown_field.rb
index 44d9beff27e..9414d16beef 100644
--- a/app/models/concerns/cache_markdown_field.rb
+++ b/app/models/concerns/cache_markdown_field.rb
@@ -160,39 +160,6 @@ module CacheMarkdownField
# We can only store mentions if the mentionable is a database object
return unless self.is_a?(ApplicationRecord)
- return store_mentions_without_subtransaction! if Feature.enabled?(:store_mentions_without_subtransaction, default_enabled: :yaml)
-
- refs = all_references(self.author)
-
- references = {}
- references[:mentioned_users_ids] = refs.mentioned_user_ids.presence
- references[:mentioned_groups_ids] = refs.mentioned_group_ids.presence
- references[:mentioned_projects_ids] = refs.mentioned_project_ids.presence
-
- # One retry is enough as next time `model_user_mention` should return the existing mention record,
- # that threw the `ActiveRecord::RecordNotUnique` exception in first place.
- self.class.safe_ensure_unique(retries: 1) do
- user_mention = model_user_mention
-
- # this may happen due to notes polymorphism, so noteable_id may point to a record
- # that no longer exists as we cannot have FK on noteable_id
- break if user_mention.blank?
-
- user_mention.mentioned_users_ids = references[:mentioned_users_ids]
- user_mention.mentioned_groups_ids = references[:mentioned_groups_ids]
- user_mention.mentioned_projects_ids = references[:mentioned_projects_ids]
-
- if user_mention.has_mentions?
- user_mention.save!
- else
- user_mention.destroy!
- end
- end
-
- true
- end
-
- def store_mentions_without_subtransaction!
identifier = user_mention_identifier
# this may happen due to notes polymorphism, so noteable_id may point to a record
diff --git a/app/models/concerns/calloutable.rb b/app/models/concerns/calloutable.rb
new file mode 100644
index 00000000000..8b9cfae6a32
--- /dev/null
+++ b/app/models/concerns/calloutable.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Calloutable
+ extend ActiveSupport::Concern
+
+ included do
+ belongs_to :user
+
+ validates :user, presence: true
+ end
+
+ def dismissed_after?(dismissed_after)
+ dismissed_at > dismissed_after
+ end
+end
diff --git a/app/models/concerns/ci/contextable.rb b/app/models/concerns/ci/contextable.rb
index bdba2d3e251..27a704c1de0 100644
--- a/app/models/concerns/ci/contextable.rb
+++ b/app/models/concerns/ci/contextable.rb
@@ -33,13 +33,13 @@ module Ci
#
def simple_variables
strong_memoize(:simple_variables) do
- scoped_variables(environment: nil).to_runner_variables
+ scoped_variables(environment: nil)
end
end
def simple_variables_without_dependencies
strong_memoize(:variables_without_dependencies) do
- scoped_variables(environment: nil, dependencies: false).to_runner_variables
+ scoped_variables(environment: nil, dependencies: false)
end
end
diff --git a/app/models/concerns/cron_schedulable.rb b/app/models/concerns/cron_schedulable.rb
index 48605ecc3d7..d5b86db2640 100644
--- a/app/models/concerns/cron_schedulable.rb
+++ b/app/models/concerns/cron_schedulable.rb
@@ -14,12 +14,10 @@ module CronSchedulable
# The `next_run_at` column is set to the actual execution date of worker that
# triggers the schedule. This way, a schedule like `*/1 * * * *` won't be triggered
# in a short interval when the worker runs irregularly by Sidekiq Memory Killer.
- def calculate_next_run_at
- now = Time.zone.now
+ def calculate_next_run_at(start_time = Time.zone.now)
+ ideal_next_run = ideal_next_run_from(start_time)
- ideal_next_run = ideal_next_run_from(now)
-
- if ideal_next_run == cron_worker_next_run_from(now)
+ if ideal_next_run == cron_worker_next_run_from(start_time)
ideal_next_run
else
cron_worker_next_run_from(ideal_next_run)
diff --git a/app/models/concerns/enums/ci/commit_status.rb b/app/models/concerns/enums/ci/commit_status.rb
index 16dec5fb081..7f46e44697e 100644
--- a/app/models/concerns/enums/ci/commit_status.rb
+++ b/app/models/concerns/enums/ci/commit_status.rb
@@ -26,6 +26,7 @@ module Enums
pipeline_loop_detected: 17,
no_matching_runner: 18, # not used anymore, but cannot be deleted because of old data
trace_size_exceeded: 19,
+ builds_disabled: 20,
insufficient_bridge_permissions: 1_001,
downstream_bridge_project_not_found: 1_002,
invalid_bridge_trigger: 1_003,
diff --git a/app/models/concerns/featurable.rb b/app/models/concerns/featurable.rb
index ed9bce87da1..70d67fc7559 100644
--- a/app/models/concerns/featurable.rb
+++ b/app/models/concerns/featurable.rb
@@ -83,6 +83,10 @@ module Featurable
end
end
+ included do
+ validate :allowed_access_levels
+ end
+
def access_level(feature)
public_send(self.class.access_level_attribute(feature)) # rubocop:disable GitlabSecurity/PublicSend
end
@@ -94,4 +98,21 @@ module Featurable
def string_access_level(feature)
self.class.str_from_access_level(access_level(feature))
end
+
+ private
+
+ def allowed_access_levels
+ validator = lambda do |field|
+ level = public_send(field) || ENABLED # rubocop:disable GitlabSecurity/PublicSend
+ not_allowed = level > ENABLED
+ self.errors.add(field, "cannot have public visibility level") if not_allowed
+ end
+
+ (self.class.available_features - feature_validation_exclusion).each {|f| validator.call("#{f}_access_level")}
+ end
+
+ # Features that we should exclude from the validation
+ def feature_validation_exclusion
+ []
+ end
end
diff --git a/app/models/concerns/has_repository.rb b/app/models/concerns/has_repository.rb
index 1b4c590694a..9218ba47d20 100644
--- a/app/models/concerns/has_repository.rb
+++ b/app/models/concerns/has_repository.rb
@@ -122,4 +122,8 @@ module HasRepository
def after_repository_change_head
reload_default_branch
end
+
+ def after_change_head_branch_does_not_exist(branch)
+ # No-op (by default)
+ end
end
diff --git a/app/models/concerns/integrations/has_data_fields.rb b/app/models/concerns/integrations/has_data_fields.rb
index e9aaaac8226..1709b56080e 100644
--- a/app/models/concerns/integrations/has_data_fields.rb
+++ b/app/models/concerns/integrations/has_data_fields.rb
@@ -46,6 +46,7 @@ module Integrations
has_one :issue_tracker_data, autosave: true, inverse_of: :integration, foreign_key: :service_id, class_name: 'Integrations::IssueTrackerData'
has_one :jira_tracker_data, autosave: true, inverse_of: :integration, foreign_key: :service_id, class_name: 'Integrations::JiraTrackerData'
has_one :open_project_tracker_data, autosave: true, inverse_of: :integration, foreign_key: :service_id, class_name: 'Integrations::OpenProjectTrackerData'
+ has_one :zentao_tracker_data, autosave: true, inverse_of: :integration, foreign_key: :integration_id, class_name: 'Integrations::ZentaoTrackerData'
def data_fields
raise NotImplementedError
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index 8d0f8b01d64..5c307158a9a 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -26,6 +26,7 @@ module Issuable
include UpdatedAtFilterable
include ClosedAtFilterable
include VersionedDescription
+ include SortableTitle
TITLE_LENGTH_MAX = 255
TITLE_HTML_LENGTH_MAX = 800
@@ -116,20 +117,6 @@ module Issuable
end
# rubocop:enable GitlabSecurity/SqlInjection
- scope :without_particular_labels, ->(label_names) do
- labels_table = Label.arel_table
- label_links_table = LabelLink.arel_table
- issuables_table = klass.arel_table
- inner_query = label_links_table.project('true')
- .join(labels_table, Arel::Nodes::InnerJoin).on(labels_table[:id].eq(label_links_table[:label_id]))
- .where(label_links_table[:target_type].eq(name)
- .and(label_links_table[:target_id].eq(issuables_table[:id]))
- .and(labels_table[:title].in(label_names)))
- .exists.not
-
- where(inner_query)
- end
-
scope :without_label, -> { joins("LEFT OUTER JOIN label_links ON label_links.target_type = '#{name}' AND label_links.target_id = #{table_name}.id").where(label_links: { id: nil }) }
scope :with_label_ids, ->(label_ids) { joins(:label_links).where(label_links: { label_id: label_ids }) }
scope :join_project, -> { joins(:project) }
@@ -293,6 +280,8 @@ module Issuable
when 'popularity', 'popularity_desc', 'upvotes_desc' then order_upvotes_desc
when 'priority', 'priority_asc' then order_due_date_and_labels_priority(excluded_labels: excluded_labels)
when 'priority_desc' then order_due_date_and_labels_priority('DESC', excluded_labels: excluded_labels)
+ when 'title_asc' then order_title_asc.with_order_id_desc
+ when 'title_desc' then order_title_desc.with_order_id_desc
else order_by(method)
end
diff --git a/app/models/concerns/loose_foreign_key.rb b/app/models/concerns/loose_foreign_key.rb
new file mode 100644
index 00000000000..4e822a04869
--- /dev/null
+++ b/app/models/concerns/loose_foreign_key.rb
@@ -0,0 +1,95 @@
+# frozen_string_literal: true
+
+module LooseForeignKey
+ extend ActiveSupport::Concern
+
+ # This concern adds loose foreign key support to ActiveRecord models.
+ # Loose foreign keys allow delayed processing of associated database records
+ # with similar guarantees than a database foreign key.
+ #
+ # TODO: finalize this later once the async job is in place
+ #
+ # Prerequisites:
+ #
+ # To start using the concern, you'll need to install a database trigger to the parent
+ # table in a standard DB migration (not post-migration).
+ #
+ # > add_loose_foreign_key_support(:projects, :gitlab_main)
+ #
+ # Usage:
+ #
+ # > class Ci::Build < ApplicationRecord
+ # >
+ # > loose_foreign_key :security_scans, :build_id, on_delete: :async_delete, gitlab_schema: :gitlab_main
+ # >
+ # > # associations can be still defined, the dependent options is no longer necessary:
+ # > has_many :security_scans, class_name: 'Security::Scan'
+ # >
+ # > end
+ #
+ # Options for on_delete:
+ #
+ # - :async_delete - deletes the children rows via an asynchronous process.
+ # - :async_nullify - sets the foreign key column to null via an asynchronous process.
+ #
+ # Options for gitlab_schema:
+ #
+ # - :gitlab_ci
+ # - :gitlab_main
+ #
+ # The value can be determined by calling `Model.gitlab_schema` where the Model represents
+ # the model for the child table.
+ #
+ # How it works:
+ #
+ # When adding loose foreign key support to the table, a DELETE trigger is installed
+ # which tracks the record deletions (stores primary key value of the deleted row) in
+ # a database table.
+ #
+ # These deletion records are processed asynchronously and records are cleaned up
+ # according to the loose foreign key definitions described in the model.
+ #
+ # The cleanup happens in batches, which reduces the likelyhood of statement timeouts.
+ #
+ # When all associations related to the deleted record are cleaned up, the record itself
+ # is deleted.
+ included do
+ class_attribute :loose_foreign_key_definitions, default: []
+ end
+
+ class_methods do
+ def loose_foreign_key(to_table, column, options)
+ symbolized_options = options.symbolize_keys
+
+ unless base_class?
+ raise <<~MSG
+ loose_foreign_key can be only used on base classes, inherited classes are not supported.
+ Please define the loose_foreign_key on the #{base_class.name} class.
+ MSG
+ end
+
+ on_delete_options = %i[async_delete async_nullify]
+ gitlab_schema_options = [ApplicationRecord.gitlab_schema, Ci::ApplicationRecord.gitlab_schema]
+
+ unless on_delete_options.include?(symbolized_options[:on_delete]&.to_sym)
+ raise "Invalid on_delete option given: #{symbolized_options[:on_delete]}. Valid options: #{on_delete_options.join(', ')}"
+ end
+
+ unless gitlab_schema_options.include?(symbolized_options[:gitlab_schema]&.to_sym)
+ raise "Invalid gitlab_schema option given: #{symbolized_options[:gitlab_schema]}. Valid options: #{gitlab_schema_options.join(', ')}"
+ end
+
+ definition = ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(
+ table_name.to_s,
+ to_table.to_s,
+ {
+ column: column.to_s,
+ on_delete: symbolized_options[:on_delete].to_sym,
+ gitlab_schema: symbolized_options[:gitlab_schema].to_sym
+ }
+ )
+
+ self.loose_foreign_key_definitions += [definition]
+ end
+ end
+end
diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb
index 4df9e32d8ec..a0ea5ac8012 100644
--- a/app/models/concerns/mentionable.rb
+++ b/app/models/concerns/mentionable.rb
@@ -217,17 +217,6 @@ module Mentionable
def user_mention_association
association(:user_mentions).reflection
end
-
- # User mention that is parsed from model description rather then its related notes.
- # Models that have a description attribute like Issue, MergeRequest, Epic, Snippet may have such a user mention.
- # Other mentionable models like Commit, DesignManagement::Design, will never have such record as those do not have
- # a description attribute.
- #
- # Using this method followed by a call to *save* may result in *ActiveRecord::RecordNotUnique* exception
- # in a multi-threaded environment. Make sure to use it within a *safe_ensure_unique* block.
- def model_user_mention
- user_mentions.where(note_id: nil).first_or_initialize
- end
end
Mentionable.prepend_mod_with('Mentionable')
diff --git a/app/models/concerns/optimized_issuable_label_filter.rb b/app/models/concerns/optimized_issuable_label_filter.rb
deleted file mode 100644
index 19d2ac620f3..00000000000
--- a/app/models/concerns/optimized_issuable_label_filter.rb
+++ /dev/null
@@ -1,121 +0,0 @@
-# frozen_string_literal: true
-
-module OptimizedIssuableLabelFilter
- extend ActiveSupport::Concern
-
- prepended do
- extend Gitlab::Cache::RequestCache
-
- # Avoid repeating label queries times when the finder is instantiated multiple times during the request.
- request_cache(:find_label_ids) { [root_namespace.id, params.label_names] }
- end
-
- def by_label(items)
- return items unless params.labels?
-
- return super if Feature.disabled?(:optimized_issuable_label_filter, default_enabled: :yaml)
-
- target_model = items.model
-
- if params.filter_by_no_label?
- items.where('NOT EXISTS (?)', optimized_any_label_query(target_model))
- elsif params.filter_by_any_label?
- items.where('EXISTS (?)', optimized_any_label_query(target_model))
- else
- issuables_with_selected_labels(items, target_model)
- end
- end
-
- # Taken from IssuableFinder
- def count_by_state
- return super if Feature.disabled?(:optimized_issuable_label_filter, default_enabled: :yaml)
-
- count_params = params.merge(state: nil, sort: nil, force_cte: true)
- finder = self.class.new(current_user, count_params)
-
- state_counts = finder
- .execute
- .reorder(nil)
- .group(:state_id)
- .count
-
- counts = Hash.new(0)
-
- state_counts.each do |key, value|
- counts[count_key(key)] += value
- end
-
- counts[:all] = counts.values.sum
- counts.with_indifferent_access
- end
-
- private
-
- def issuables_with_selected_labels(items, target_model)
- if root_namespace
- all_label_ids = find_label_ids
- # Found less labels in the DB than we were searching for. Return nothing.
- return items.none if all_label_ids.size != params.label_names.size
-
- all_label_ids.each do |label_ids|
- items = items.where('EXISTS (?)', optimized_label_query_by_label_ids(target_model, label_ids))
- end
- else
- params.label_names.each do |label_name|
- items = items.where('EXISTS (?)', optimized_label_query_by_label_name(target_model, label_name))
- end
- end
-
- items
- end
-
- def find_label_ids
- group_labels = Label
- .where(project_id: nil)
- .where(title: params.label_names)
- .where(group_id: root_namespace.self_and_descendants.select(:id))
-
- project_labels = Label
- .where(group_id: nil)
- .where(title: params.label_names)
- .where(project_id: Project.select(:id).where(namespace_id: root_namespace.self_and_descendants.select(:id)))
-
- Label
- .from_union([group_labels, project_labels], remove_duplicates: false)
- .reorder(nil)
- .pluck(:title, :id)
- .group_by(&:first)
- .values
- .map { |labels| labels.map(&:last) }
- end
-
- def root_namespace
- strong_memoize(:root_namespace) do
- (params.project || params.group)&.root_ancestor
- end
- end
-
- def optimized_any_label_query(target_model)
- LabelLink
- .where(target_type: target_model.name)
- .where(LabelLink.arel_table['target_id'].eq(target_model.arel_table['id']))
- .limit(1)
- end
-
- def optimized_label_query_by_label_ids(target_model, label_ids)
- LabelLink
- .where(target_type: target_model.name)
- .where(LabelLink.arel_table['target_id'].eq(target_model.arel_table['id']))
- .where(label_id: label_ids)
- .limit(1)
- end
-
- def optimized_label_query_by_label_name(target_model, label_name)
- LabelLink
- .joins(:label)
- .where(target_type: target_model.name)
- .where(LabelLink.arel_table['target_id'].eq(target_model.arel_table['id']))
- .where(labels: { name: label_name })
- .limit(1)
- end
-end
diff --git a/app/models/concerns/partitioned_table.rb b/app/models/concerns/partitioned_table.rb
index eab5d4c35bb..23d2d00b346 100644
--- a/app/models/concerns/partitioned_table.rb
+++ b/app/models/concerns/partitioned_table.rb
@@ -14,8 +14,6 @@ module PartitionedTable
strategy_class = PARTITIONING_STRATEGIES[strategy.to_sym] || raise(ArgumentError, "Unknown partitioning strategy: #{strategy}")
@partitioning_strategy = strategy_class.new(self, partitioning_key, **kwargs)
-
- Gitlab::Database::Partitioning::PartitionManager.register(self)
end
end
end
diff --git a/app/models/concerns/relative_positioning.rb b/app/models/concerns/relative_positioning.rb
index 75dfed6d58f..c32e499c329 100644
--- a/app/models/concerns/relative_positioning.rb
+++ b/app/models/concerns/relative_positioning.rb
@@ -135,21 +135,21 @@ module RelativePositioning
before, after = [before, after].sort_by(&:relative_position) if before && after
RelativePositioning.mover.move(self, before, after)
- rescue ActiveRecord::QueryCanceled, NoSpaceLeft => e
+ rescue NoSpaceLeft => e
could_not_move(e)
raise e
end
def move_after(before = self)
RelativePositioning.mover.move(self, before, nil)
- rescue ActiveRecord::QueryCanceled, NoSpaceLeft => e
+ rescue NoSpaceLeft => e
could_not_move(e)
raise e
end
def move_before(after = self)
RelativePositioning.mover.move(self, nil, after)
- rescue ActiveRecord::QueryCanceled, NoSpaceLeft => e
+ rescue NoSpaceLeft => e
could_not_move(e)
raise e
end
@@ -159,9 +159,6 @@ module RelativePositioning
rescue NoSpaceLeft => e
could_not_move(e)
self.relative_position = MAX_POSITION
- rescue ActiveRecord::QueryCanceled => e
- could_not_move(e)
- raise e
end
def move_to_start
@@ -169,9 +166,6 @@ module RelativePositioning
rescue NoSpaceLeft => e
could_not_move(e)
self.relative_position = MIN_POSITION
- rescue ActiveRecord::QueryCanceled => e
- could_not_move(e)
- raise e
end
# This method is used during rebalancing - override it to customise the update
diff --git a/app/models/concerns/sanitizable.rb b/app/models/concerns/sanitizable.rb
new file mode 100644
index 00000000000..05756beb404
--- /dev/null
+++ b/app/models/concerns/sanitizable.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+# == Sanitizable concern
+#
+# This concern adds HTML sanitization and validation to models. The intention is
+# to help prevent XSS attacks in the event of a by-pass in the frontend
+# sanitizer due to a configuration issue or a vulnerability in the sanitizer.
+# This approach is commonly referred to as defense-in-depth.
+#
+# Example:
+#
+# module Dast
+# class Profile < ApplicationRecord
+# include Sanitizable
+#
+# sanitizes! :name, :description
+
+module Sanitizable
+ extend ActiveSupport::Concern
+
+ class_methods do
+ def sanitize(input)
+ return unless input
+
+ # We return the input unchanged to avoid escaping pre-escaped HTML fragments.
+ # Please see gitlab-org/gitlab#293634 for an example.
+ return input unless input == CGI.unescapeHTML(input.to_s)
+
+ CGI.unescapeHTML(Sanitize.fragment(input))
+ end
+
+ def sanitizes!(*attrs)
+ instance_eval do
+ before_validation do
+ attrs.each do |attr|
+ input = public_send(attr) # rubocop: disable GitlabSecurity/PublicSend
+
+ public_send("#{attr}=", self.class.sanitize(input)) # rubocop: disable GitlabSecurity/PublicSend
+ end
+ end
+
+ validates_each(*attrs) do |record, attr, input|
+ # We reject pre-escaped HTML fragments as invalid to avoid saving them
+ # to the database.
+ unless input.to_s == CGI.unescapeHTML(input.to_s)
+ record.errors.add(attr, 'cannot contain escaped HTML entities')
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/app/models/concerns/sortable_title.rb b/app/models/concerns/sortable_title.rb
new file mode 100644
index 00000000000..7c5cad17f4c
--- /dev/null
+++ b/app/models/concerns/sortable_title.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module SortableTitle
+ extend ActiveSupport::Concern
+
+ included do
+ scope :order_title_asc, -> { reorder(Arel::Nodes::Ascending.new(arel_table[:title].lower)) }
+ scope :order_title_desc, -> { reorder(Arel::Nodes::Descending.new(arel_table[:title].lower)) }
+ end
+
+ class_methods do
+ def simple_sorts
+ super.merge(
+ {
+ 'title_asc' => -> { order_title_asc },
+ 'title_desc' => -> { order_title_desc }
+ }
+ )
+ end
+ end
+end
diff --git a/app/models/concerns/taggable_queries.rb b/app/models/concerns/taggable_queries.rb
index cba2e93a86d..06799f0a9f4 100644
--- a/app/models/concerns/taggable_queries.rb
+++ b/app/models/concerns/taggable_queries.rb
@@ -3,6 +3,10 @@
module TaggableQueries
extend ActiveSupport::Concern
+ MAX_TAGS_IDS = 50
+
+ TooManyTagsError = Class.new(StandardError)
+
class_methods do
# context is a name `acts_as_taggable context`
def arel_tag_names_array(context = :tags)
@@ -34,4 +38,10 @@ module TaggableQueries
where("EXISTS (?)", matcher)
end
end
+
+ def tags_ids
+ tags.limit(MAX_TAGS_IDS).order('id ASC').pluck(:id).tap do |ids|
+ raise TooManyTagsError if ids.size >= MAX_TAGS_IDS
+ end
+ end
end
diff --git a/app/models/customer_relations/contact.rb b/app/models/customer_relations/contact.rb
new file mode 100644
index 00000000000..aaa7e2ae175
--- /dev/null
+++ b/app/models/customer_relations/contact.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+class CustomerRelations::Contact < ApplicationRecord
+ include StripAttribute
+
+ self.table_name = "customer_relations_contacts"
+
+ belongs_to :group, -> { where(type: 'Group') }, foreign_key: 'group_id'
+ belongs_to :organization, optional: true
+
+ strip_attributes! :phone, :first_name, :last_name
+
+ enum state: {
+ inactive: 0,
+ active: 1
+ }
+
+ validates :group, presence: true
+ validates :phone, length: { maximum: 32 }
+ validates :first_name, presence: true, length: { maximum: 255 }
+ validates :last_name, presence: true, length: { maximum: 255 }
+ validates :email, length: { maximum: 255 }
+ validates :description, length: { maximum: 1024 }
+ validate :validate_email_format
+
+ private
+
+ def validate_email_format
+ return unless email
+
+ self.errors.add(:email, I18n.t(:invalid, scope: 'valid_email.validations.email')) unless ValidateEmail.valid?(self.email)
+ end
+end
diff --git a/app/models/customer_relations/organization.rb b/app/models/customer_relations/organization.rb
index caf1cd68cc5..a18d3ab8148 100644
--- a/app/models/customer_relations/organization.rb
+++ b/app/models/customer_relations/organization.rb
@@ -1,11 +1,13 @@
# frozen_string_literal: true
class CustomerRelations::Organization < ApplicationRecord
+ include StripAttribute
+
self.table_name = "customer_relations_organizations"
belongs_to :group, -> { where(type: 'Group') }, foreign_key: 'group_id'
- before_validation :strip_whitespace!
+ strip_attributes! :name
enum state: {
inactive: 0,
@@ -22,10 +24,4 @@ class CustomerRelations::Organization < ApplicationRecord
where(group: group_id)
.where('LOWER(name) = LOWER(?)', name)
end
-
- private
-
- def strip_whitespace!
- name&.strip!
- end
end
diff --git a/app/models/dependency_proxy/blob.rb b/app/models/dependency_proxy/blob.rb
index 3a81112340a..5de6b1cf28f 100644
--- a/app/models/dependency_proxy/blob.rb
+++ b/app/models/dependency_proxy/blob.rb
@@ -8,6 +8,9 @@ class DependencyProxy::Blob < ApplicationRecord
validates :group, presence: true
validates :file, presence: true
validates :file_name, presence: true
+ validates :status, presence: true
+
+ enum status: { default: 0, expired: 1 }
mount_file_store_uploader DependencyProxy::FileUploader
diff --git a/app/models/dependency_proxy/image_ttl_group_policy.rb b/app/models/dependency_proxy/image_ttl_group_policy.rb
new file mode 100644
index 00000000000..5a1b8cb8f1f
--- /dev/null
+++ b/app/models/dependency_proxy/image_ttl_group_policy.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class DependencyProxy::ImageTtlGroupPolicy < ApplicationRecord
+ self.primary_key = :group_id
+
+ belongs_to :group
+
+ validates :group, presence: true
+ validates :enabled, inclusion: { in: [true, false] }
+ validates :ttl, numericality: { greater_than: 0 }, allow_nil: true
+end
diff --git a/app/models/dependency_proxy/manifest.rb b/app/models/dependency_proxy/manifest.rb
index d613d5708f0..15e5137b50a 100644
--- a/app/models/dependency_proxy/manifest.rb
+++ b/app/models/dependency_proxy/manifest.rb
@@ -9,6 +9,9 @@ class DependencyProxy::Manifest < ApplicationRecord
validates :file, presence: true
validates :file_name, presence: true
validates :digest, presence: true
+ validates :status, presence: true
+
+ enum status: { default: 0, expired: 1 }
mount_file_store_uploader DependencyProxy::FileUploader
diff --git a/app/models/deploy_keys_project.rb b/app/models/deploy_keys_project.rb
index 40c66d5bc4c..363ef0b1c9a 100644
--- a/app/models/deploy_keys_project.rb
+++ b/app/models/deploy_keys_project.rb
@@ -3,7 +3,6 @@
class DeployKeysProject < ApplicationRecord
belongs_to :project, inverse_of: :deploy_keys_projects
belongs_to :deploy_key, inverse_of: :deploy_keys_projects
- scope :without_project_deleted, -> { joins(:project).where(projects: { pending_delete: false }) }
scope :in_project, ->(project) { where(project: project) }
scope :with_write_access, -> { where(can_push: true) }
diff --git a/app/models/design_management/action.rb b/app/models/design_management/action.rb
index ecd7973a523..b9df2873a73 100644
--- a/app/models/design_management/action.rb
+++ b/app/models/design_management/action.rb
@@ -17,6 +17,8 @@ module DesignManagement
# we assume sequential ordering.
scope :ordered, -> { order(version_id: :asc) }
+ scope :by_design, -> (design) { where(design: design) }
+ scope :by_event, -> (event) { where(event: event) }
# For each design, only select the most recent action
scope :most_recent, -> do
diff --git a/app/models/diff_note.rb b/app/models/diff_note.rb
index c8a0773cc5b..6ebac6384bc 100644
--- a/app/models/diff_note.rb
+++ b/app/models/diff_note.rb
@@ -22,7 +22,7 @@ class DiffNote < Note
validate :verify_supported, unless: :importing?
before_validation :set_line_code, if: :on_text?, unless: :importing?
- after_save :keep_around_commits, unless: :importing?
+ after_save :keep_around_commits, unless: -> { importing? || skip_keep_around_commits }
NoteDiffFileCreationError = Class.new(StandardError)
@@ -115,6 +115,20 @@ class DiffNote < Note
position&.multiline?
end
+ def shas
+ [
+ self.original_position.base_sha,
+ self.original_position.start_sha,
+ self.original_position.head_sha
+ ].tap do |a|
+ if self.position != self.original_position
+ a << self.position.base_sha
+ a << self.position.start_sha
+ a << self.position.head_sha
+ end
+ end
+ end
+
private
def enqueue_diff_file_creation_job
@@ -173,18 +187,6 @@ class DiffNote < Note
end
def keep_around_commits
- shas = [
- self.original_position.base_sha,
- self.original_position.start_sha,
- self.original_position.head_sha
- ]
-
- if self.position != self.original_position
- shas << self.position.base_sha
- shas << self.position.start_sha
- shas << self.position.head_sha
- end
-
repository.keep_around(*shas)
end
diff --git a/app/models/environment.rb b/app/models/environment.rb
index 963249c018a..48522a23068 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -27,11 +27,10 @@ class Environment < ApplicationRecord
has_many :alert_management_alerts, class_name: 'AlertManagement::Alert', inverse_of: :environment
has_one :last_deployment, -> { success.distinct_on_environment }, class_name: 'Deployment', inverse_of: :environment
- has_one :last_deployable, through: :last_deployment, source: 'deployable', source_type: 'CommitStatus'
- has_one :last_pipeline, through: :last_deployable, source: 'pipeline'
has_one :last_visible_deployment, -> { visible.distinct_on_environment }, inverse_of: :environment, class_name: 'Deployment'
- has_one :last_visible_deployable, through: :last_visible_deployment, source: 'deployable', source_type: 'CommitStatus'
- has_one :last_visible_pipeline, through: :last_visible_deployable, source: 'pipeline'
+ has_one :last_visible_deployable, through: :last_visible_deployment, source: 'deployable', source_type: 'CommitStatus', disable_joins: -> { ::Feature.enabled?(:environment_last_visible_pipeline_disable_joins, default_enabled: :yaml) }
+ has_one :last_visible_pipeline, through: :last_visible_deployable, source: 'pipeline', disable_joins: -> { ::Feature.enabled?(:environment_last_visible_pipeline_disable_joins, default_enabled: :yaml) }
+
has_one :upcoming_deployment, -> { running.distinct_on_environment }, class_name: 'Deployment', inverse_of: :environment
has_one :latest_opened_most_severe_alert, -> { order_severity_with_open_prometheus_alert }, class_name: 'AlertManagement::Alert', inverse_of: :environment
@@ -77,6 +76,7 @@ class Environment < ApplicationRecord
scope :in_review_folder, -> { where(environment_type: "review") }
scope :for_name, -> (name) { where(name: name) }
scope :preload_cluster, -> { preload(last_deployment: :cluster) }
+ scope :preload_project, -> { preload(:project) }
scope :auto_stoppable, -> (limit) { available.where('auto_stop_at < ?', Time.zone.now).limit(limit) }
scope :auto_deletable, -> (limit) { stopped.where('auto_delete_at < ?', Time.zone.now).limit(limit) }
@@ -132,6 +132,10 @@ class Environment < ApplicationRecord
state :available
state :stopped
+ before_transition any => :stopped do |environment|
+ environment.auto_stop_at = nil
+ end
+
after_transition do |environment|
environment.expire_etag_cache
end
@@ -168,33 +172,6 @@ class Environment < ApplicationRecord
end
class << self
- ##
- # This method returns stop actions (jobs) for multiple environments within one
- # query. It's useful to avoid N+1 problem.
- #
- # NOTE: The count of environments should be small~medium (e.g. < 5000)
- def stop_actions
- cte = cte_for_deployments_with_stop_action
- ci_builds = Ci::Build.arel_table
-
- inner_join_stop_actions = ci_builds.join(cte.table).on(
- ci_builds[:project_id].eq(cte.table[:project_id])
- .and(ci_builds[:ref].eq(cte.table[:ref]))
- .and(ci_builds[:name].eq(cte.table[:on_stop]))
- ).join_sources
-
- pipeline_ids = ci_builds.join(cte.table).on(
- ci_builds[:id].eq(cte.table[:deployable_id])
- ).project(:commit_id)
-
- Ci::Build.joins(inner_join_stop_actions)
- .with(cte.to_arel)
- .where(ci_builds[:commit_id].in(pipeline_ids))
- .where(status: Ci::HasStatus::BLOCKED_STATUS)
- .preload_project_and_pipeline_project
- .preload(:user, :metadata, :deployment)
- end
-
def count_by_state
environments_count_by_state = group(:state).count
@@ -202,15 +179,35 @@ class Environment < ApplicationRecord
count_hash[state] = environments_count_by_state[state.to_s] || 0
end
end
+ end
+
+ def last_deployable
+ last_deployment&.deployable
+ end
- private
+ # NOTE: Below assocation overrides is a workaround for issue https://gitlab.com/gitlab-org/gitlab/-/issues/339908
+ # It helps to avoid cross joins with the CI database.
+ # Caveat: It also overrides and losses the default AR caching mechanism.
+ # Read - https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68870#note_677227727
- def cte_for_deployments_with_stop_action
- Gitlab::SQL::CTE.new(:deployments_with_stop_action,
- Deployment.where(environment_id: select(:id))
- .distinct_on_environment
- .stoppable)
- end
+ # NOTE: Association Preloads does not use the overriden definitions below.
+ # Association Preloads when preloading uses the original definitions from the relationships above.
+ # https://github.com/rails/rails/blob/75ac626c4e21129d8296d4206a1960563cc3d4aa/activerecord/lib/active_record/associations/preloader.rb#L158
+ # But after preloading, when they are called it is using the overriden methods below.
+ # So we are checking for `association_cached?(:association_name)` in the overridden methods and calling `super` which inturn fetches the preloaded values.
+
+ # Overriding association
+ def last_visible_deployable
+ return super if association_cached?(:last_visible_deployable) || ::Feature.disabled?(:environment_last_visible_pipeline_disable_joins, default_enabled: :yaml)
+
+ last_visible_deployment&.deployable
+ end
+
+ # Overriding association
+ def last_visible_pipeline
+ return super if association_cached?(:last_visible_pipeline) || ::Feature.disabled?(:environment_last_visible_pipeline_disable_joins, default_enabled: :yaml)
+
+ last_visible_deployable&.pipeline
end
def clear_prometheus_reactive_cache!(query_name)
diff --git a/app/models/environment_status.rb b/app/models/environment_status.rb
index 07c0983f239..3be7af2e4bf 100644
--- a/app/models/environment_status.rb
+++ b/app/models/environment_status.rb
@@ -100,11 +100,13 @@ class EnvironmentStatus
def self.build_environments_status(mr, user, pipeline)
return [] unless pipeline
- pipeline.environments_in_self_and_descendants.includes(:project).available.map do |environment|
- next unless Ability.allowed?(user, :read_environment, environment)
+ ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/340781') do
+ pipeline.environments_in_self_and_descendants.includes(:project).available.map do |environment|
+ next unless Ability.allowed?(user, :read_environment, environment)
- EnvironmentStatus.new(pipeline.project, environment, mr, pipeline.sha)
- end.compact
+ EnvironmentStatus.new(pipeline.project, environment, mr, pipeline.sha)
+ end.compact
+ end
end
private_class_method :build_environments_status
end
diff --git a/app/models/error_tracking/client_key.rb b/app/models/error_tracking/client_key.rb
index 9d12c0ed6f1..8e59f6f9ecb 100644
--- a/app/models/error_tracking/client_key.rb
+++ b/app/models/error_tracking/client_key.rb
@@ -14,9 +14,13 @@ class ErrorTracking::ClientKey < ApplicationRecord
find_by(public_key: key)
end
+ def sentry_dsn
+ @sentry_dsn ||= ErrorTracking::Collector::Dsn.build_url(public_key, project_id)
+ end
+
private
def generate_key
- self.public_key = "glet_#{SecureRandom.hex}"
+ self.public_key ||= "glet_#{SecureRandom.hex}"
end
end
diff --git a/app/models/error_tracking/error.rb b/app/models/error_tracking/error.rb
index 32932c4d045..39ecc487806 100644
--- a/app/models/error_tracking/error.rb
+++ b/app/models/error_tracking/error.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
class ErrorTracking::Error < ApplicationRecord
+ include Sortable
+
belongs_to :project
has_many :events, class_name: 'ErrorTracking::ErrorEvent'
@@ -22,11 +24,28 @@ class ErrorTracking::Error < ApplicationRecord
def self.report_error(name:, description:, actor:, platform:, timestamp:)
safe_find_or_create_by(
name: name,
- description: description,
actor: actor,
platform: platform
- ) do |error|
- error.update!(last_seen_at: timestamp)
+ ).tap do |error|
+ error.update!(
+ # Description can contain object id, so it can't be
+ # used as a group criteria for similar errors.
+ description: description,
+ last_seen_at: timestamp
+ )
+ end
+ end
+
+ def self.sort_by_attribute(method)
+ case method.to_s
+ when 'last_seen'
+ order(last_seen_at: :desc)
+ when 'first_seen'
+ order(first_seen_at: :desc)
+ when 'frequency'
+ order(events_count: :desc)
+ else
+ order_id_desc
end
end
diff --git a/app/models/error_tracking/project_error_tracking_setting.rb b/app/models/error_tracking/project_error_tracking_setting.rb
index c5a77427588..dd5ce9f7387 100644
--- a/app/models/error_tracking/project_error_tracking_setting.rb
+++ b/app/models/error_tracking/project_error_tracking_setting.rb
@@ -51,7 +51,7 @@ module ErrorTracking
end
def integrated_client?
- integrated && ::Feature.enabled?(:integrated_error_tracking, project)
+ integrated
end
def api_url=(value)
diff --git a/app/models/event.rb b/app/models/event.rb
index f6174589a84..d6588699d27 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -9,6 +9,9 @@ class Event < ApplicationRecord
include Gitlab::Utils::StrongMemoize
include UsageStatistics
include ShaAttribute
+ include IgnorableColumns
+
+ ignore_columns :id_convert_to_bigint, remove_with: '14.5', remove_after: '2021-10-22'
default_scope { reorder(nil) } # rubocop:disable Cop/DefaultScope
diff --git a/app/models/group.rb b/app/models/group.rb
index f6b45a755e4..437c750afa6 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -18,6 +18,10 @@ class Group < Namespace
include EachBatch
include BulkMemberAccessLoad
+ def self.sti_name
+ 'Group'
+ end
+
has_many :all_group_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source, class_name: 'GroupMember' # rubocop:disable Cop/ActiveRecordDependent
has_many :group_members, -> { where(requested_at: nil).where.not(members: { access_level: Gitlab::Access::MINIMAL_ACCESS }) }, dependent: :destroy, as: :source # rubocop:disable Cop/ActiveRecordDependent
alias_method :members, :group_members
@@ -74,13 +78,16 @@ class Group < Namespace
has_many :oauth_applications, class_name: 'Doorkeeper::Application', as: :owner, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
has_one :dependency_proxy_setting, class_name: 'DependencyProxy::GroupSetting'
+ has_one :dependency_proxy_image_ttl_policy, class_name: 'DependencyProxy::ImageTtlGroupPolicy'
has_many :dependency_proxy_blobs, class_name: 'DependencyProxy::Blob'
has_many :dependency_proxy_manifests, class_name: 'DependencyProxy::Manifest'
# debian_distributions and associated component_files must be destroyed by ruby code in order to properly remove carrierwave uploads
has_many :debian_distributions, class_name: 'Packages::Debian::GroupDistribution', dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
- delegate :prevent_sharing_groups_outside_hierarchy, :new_user_signups_cap, to: :namespace_settings
+ has_many :group_callouts, class_name: 'Users::GroupCallout', foreign_key: :group_id
+
+ delegate :prevent_sharing_groups_outside_hierarchy, :new_user_signups_cap, :setup_for_company, :jobs_to_be_done, to: :namespace_settings
accepts_nested_attributes_for :variables, allow_destroy: true
@@ -260,6 +267,15 @@ class Group < Namespace
Gitlab::UrlBuilder.build(self, only_path: only_path)
end
+ def dependency_proxy_image_prefix
+ # The namespace path can include uppercase letters, which
+ # Docker doesn't allow. The proxy expects it to be downcased.
+ url = "#{web_url.downcase}#{DependencyProxy::URL_SUFFIX}"
+
+ # Docker images do not include the protocol
+ url.partition('//').last
+ end
+
def human_name
full_name
end
@@ -296,7 +312,7 @@ class Group < Namespace
end
def add_users(users, access_level, current_user: nil, expires_at: nil)
- Members::Groups::CreatorService.add_users( # rubocop:disable CodeReuse/ServiceClass
+ Members::Groups::BulkCreatorService.add_users( # rubocop:disable CodeReuse/ServiceClass
self,
users,
access_level,
@@ -642,6 +658,10 @@ class Group < Namespace
members.owners.connected_to_user.order_recent_sign_in.limit(Member::ACCESS_REQUEST_APPROVERS_TO_BE_NOTIFIED_LIMIT)
end
+ def membership_locked?
+ false # to support project and group calling this as 'source'
+ end
+
def supports_events?
false
end
@@ -734,6 +754,22 @@ class Group < Namespace
Timelog.in_group(self)
end
+ def cached_issues_state_count_enabled?
+ Feature.enabled?(:cached_issues_state_count, self, default_enabled: :yaml)
+ end
+
+ def organizations
+ ::CustomerRelations::Organization.where(group_id: self.id)
+ end
+
+ def contacts
+ ::CustomerRelations::Contact.where(group_id: self.id)
+ end
+
+ def dependency_proxy_image_ttl_policy
+ super || build_dependency_proxy_image_ttl_policy
+ end
+
private
def max_member_access(user_ids)
@@ -822,9 +858,15 @@ class Group < Namespace
end
def self.groups_including_descendants_by(group_ids)
- Gitlab::ObjectHierarchy
- .new(Group.where(id: group_ids))
+ groups = Group.where(id: group_ids)
+
+ if Feature.enabled?(:linear_group_including_descendants_by, default_enabled: :yaml)
+ groups.self_and_descendants
+ else
+ Gitlab::ObjectHierarchy
+ .new(groups)
.base_and_descendants
+ end
end
def disable_shared_runners!
diff --git a/app/models/hooks/web_hook.rb b/app/models/hooks/web_hook.rb
index 9a78fe3971c..cb5c1ac48cd 100644
--- a/app/models/hooks/web_hook.rb
+++ b/app/models/hooks/web_hook.rb
@@ -80,6 +80,8 @@ class WebHook < ApplicationRecord
end
def backoff!
+ return if backoff_count >= MAX_FAILURES && disabled_until && disabled_until > Time.current
+
assign_attributes(disabled_until: next_backoff.from_now, backoff_count: backoff_count.succ.clamp(0, MAX_FAILURES))
save(validate: false)
end
diff --git a/app/models/instance_configuration.rb b/app/models/instance_configuration.rb
index 09a60e9dd10..9565dae08b5 100644
--- a/app/models/instance_configuration.rb
+++ b/app/models/instance_configuration.rb
@@ -13,7 +13,7 @@ class InstanceConfiguration
{ ssh_algorithms_hashes: ssh_algorithms_hashes,
host: host,
gitlab_pages: gitlab_pages,
- gitlab_ci: gitlab_ci,
+ size_limits: size_limits,
package_file_size_limits: package_file_size_limits,
rate_limits: rate_limits }.deep_symbolize_keys
end
@@ -38,11 +38,16 @@ class InstanceConfiguration
rescue Resolv::ResolvError
end
- def gitlab_ci
- Settings.gitlab_ci
- .to_h
- .merge(artifacts_max_size: { value: Gitlab::CurrentSettings.max_artifacts_size.megabytes,
- default: 100.megabytes })
+ def size_limits
+ {
+ max_attachment_size: application_settings[:max_attachment_size].megabytes,
+ receive_max_input_size: application_settings[:receive_max_input_size]&.megabytes,
+ max_import_size: application_settings[:max_import_size] > 0 ? application_settings[:max_import_size].megabytes : nil,
+ diff_max_patch_bytes: application_settings[:diff_max_patch_bytes].bytes,
+ max_artifacts_size: application_settings[:max_artifacts_size].megabytes,
+ max_pages_size: application_settings[:max_pages_size] > 0 ? application_settings[:max_pages_size].megabytes : nil,
+ snippet_size_limit: application_settings[:snippet_size_limit]&.bytes
+ }
end
def package_file_size_limits
diff --git a/app/models/integration.rb b/app/models/integration.rb
index a9c865569d0..158764bb783 100644
--- a/app/models/integration.rb
+++ b/app/models/integration.rb
@@ -274,7 +274,7 @@ class Integration < ApplicationRecord
end
def self.closest_group_integration(type, scope)
- group_ids = scope.ancestors(hierarchy_order: :asc).select(:id)
+ group_ids = scope.ancestors(hierarchy_order: :asc).reselect(:id)
array = group_ids.to_sql.present? ? "array(#{group_ids.to_sql})" : 'ARRAY[]'
where(type: type, group_id: group_ids, inherit_from_id: nil)
@@ -357,6 +357,10 @@ class Integration < ApplicationRecord
[]
end
+ def password_fields
+ fields.select { |f| f[:type] == 'password' }.pluck(:name)
+ end
+
# Expose a list of fields in the JSON endpoint.
#
# This list is used in `Integration#as_json(only: json_fields)`.
diff --git a/app/models/integrations/base_chat_notification.rb b/app/models/integrations/base_chat_notification.rb
index 5eae8bce92a..c6335782b5e 100644
--- a/app/models/integrations/base_chat_notification.rb
+++ b/app/models/integrations/base_chat_notification.rb
@@ -253,3 +253,5 @@ module Integrations
end
end
end
+
+Integrations::BaseChatNotification.prepend_mod_with('Integrations::BaseChatNotification')
diff --git a/app/models/integrations/datadog.rb b/app/models/integrations/datadog.rb
index 6422f6bddab..72e0ca22ac2 100644
--- a/app/models/integrations/datadog.rb
+++ b/app/models/integrations/datadog.rb
@@ -7,7 +7,7 @@ module Integrations
extend Gitlab::Utils::Override
DEFAULT_DOMAIN = 'datadoghq.com'
- URL_TEMPLATE = 'https://webhooks-http-intake.logs.%{datadog_domain}/api/v2/webhook'
+ URL_TEMPLATE = 'https://webhook-intake.%{datadog_domain}/api/v2/webhook'
URL_API_KEYS_DOCS = "https://docs.#{DEFAULT_DOMAIN}/account_management/api-app-keys/"
SUPPORTED_EVENTS = %w[
diff --git a/app/models/integrations/prometheus.rb b/app/models/integrations/prometheus.rb
index 54cb823d606..5746343c31c 100644
--- a/app/models/integrations/prometheus.rb
+++ b/app/models/integrations/prometheus.rb
@@ -76,7 +76,7 @@ module Integrations
name: 'google_iap_audience_client_id',
title: 'Google IAP Audience Client ID',
placeholder: s_('PrometheusService|IAP_CLIENT_ID.apps.googleusercontent.com'),
- help: s_('PrometheusService|PrometheusService|The ID of the IAP-secured resource.'),
+ help: s_('PrometheusService|The ID of the IAP-secured resource.'),
autocomplete: 'off',
required: false
},
diff --git a/app/models/integrations/slack_slash_commands.rb b/app/models/integrations/slack_slash_commands.rb
index ff1f806df45..72e3c4a8cbc 100644
--- a/app/models/integrations/slack_slash_commands.rb
+++ b/app/models/integrations/slack_slash_commands.rb
@@ -9,7 +9,7 @@ module Integrations
end
def description
- "Perform common operations in Slack"
+ "Perform common operations in Slack."
end
def self.to_param
diff --git a/app/models/integrations/zentao.rb b/app/models/integrations/zentao.rb
new file mode 100644
index 00000000000..68c02f54c61
--- /dev/null
+++ b/app/models/integrations/zentao.rb
@@ -0,0 +1,78 @@
+# frozen_string_literal: true
+
+module Integrations
+ class Zentao < Integration
+ data_field :url, :api_url, :api_token, :zentao_product_xid
+
+ validates :url, public_url: true, presence: true, if: :activated?
+ validates :api_url, public_url: true, allow_blank: true
+ validates :api_token, presence: true, if: :activated?
+ validates :zentao_product_xid, presence: true, if: :activated?
+
+ def data_fields
+ zentao_tracker_data || self.build_zentao_tracker_data
+ end
+
+ def title
+ self.class.name.demodulize
+ end
+
+ def description
+ s_("ZentaoIntegration|Use Zentao as this project's issue tracker.")
+ end
+
+ def self.to_param
+ name.demodulize.downcase
+ end
+
+ def test(*_args)
+ client.ping
+ end
+
+ def self.supported_events
+ %w()
+ end
+
+ def self.supported_event_actions
+ %w()
+ end
+
+ def fields
+ [
+ {
+ type: 'text',
+ name: 'url',
+ title: s_('ZentaoIntegration|Zentao Web URL'),
+ placeholder: 'https://www.zentao.net',
+ help: s_('ZentaoIntegration|Base URL of the Zentao instance.'),
+ required: true
+ },
+ {
+ type: 'text',
+ name: 'api_url',
+ title: s_('ZentaoIntegration|Zentao API URL (optional)'),
+ help: s_('ZentaoIntegration|If different from Web URL.')
+ },
+ {
+ type: 'password',
+ name: 'api_token',
+ title: s_('ZentaoIntegration|Zentao API token'),
+ non_empty_password_title: s_('ZentaoIntegration|Enter API token'),
+ required: true
+ },
+ {
+ type: 'text',
+ name: 'zentao_product_xid',
+ title: s_('ZentaoIntegration|Zentao Product ID'),
+ required: true
+ }
+ ]
+ end
+
+ private
+
+ def client
+ @client ||= ::Gitlab::Zentao::Client.new(self)
+ end
+ end
+end
diff --git a/app/models/integrations/zentao_tracker_data.rb b/app/models/integrations/zentao_tracker_data.rb
new file mode 100644
index 00000000000..468e4e5d7d7
--- /dev/null
+++ b/app/models/integrations/zentao_tracker_data.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Integrations
+ class ZentaoTrackerData < ApplicationRecord
+ belongs_to :integration, inverse_of: :zentao_tracker_data, foreign_key: :integration_id
+ delegate :activated?, to: :integration
+ validates :integration, presence: true
+
+ scope :encryption_options, -> do
+ {
+ key: Settings.attr_encrypted_db_key_base_32,
+ encode: true,
+ mode: :per_attribute_iv,
+ algorithm: 'aes-256-gcm'
+ }
+ end
+
+ attr_encrypted :url, encryption_options
+ attr_encrypted :api_url, encryption_options
+ attr_encrypted :zentao_product_xid, encryption_options
+ attr_encrypted :api_token, encryption_options
+ end
+end
diff --git a/app/models/internal_id.rb b/app/models/internal_id.rb
index a54de3c82d1..10d24ab50b2 100644
--- a/app/models/internal_id.rb
+++ b/app/models/internal_id.rb
@@ -4,7 +4,7 @@
# generated for a given scope and usage.
#
# The monotone sequence may be broken if an ID is explicitly provided
-# to `.track_greatest_and_save!` or `#track_greatest`.
+# to `#track_greatest`.
#
# For example, issues use their project to scope internal ids:
# In that sense, scope is "project" and usage is "issues".
@@ -29,32 +29,6 @@ class InternalId < ApplicationRecord
where(**scope, usage: usage)
end
- # Increments #last_value and saves the record
- #
- # The operation locks the record and gathers a `ROW SHARE` lock (in PostgreSQL).
- # As such, the increment is atomic and safe to be called concurrently.
- def increment_and_save!
- update_and_save { self.last_value = (last_value || 0) + 1 }
- end
-
- # Increments #last_value with new_value if it is greater than the current,
- # and saves the record
- #
- # The operation locks the record and gathers a `ROW SHARE` lock (in PostgreSQL).
- # As such, the increment is atomic and safe to be called concurrently.
- def track_greatest_and_save!(new_value)
- update_and_save { self.last_value = [last_value || 0, new_value].max }
- end
-
- private
-
- def update_and_save(&block)
- lock!
- yield
- save!
- last_value
- end
-
class << self
def track_greatest(subject, scope, usage, new_value, init)
build_generator(subject, scope, usage, init).track_greatest(new_value)
@@ -99,132 +73,7 @@ class InternalId < ApplicationRecord
private
def build_generator(subject, scope, usage, init = nil)
- if Feature.enabled?(:generate_iids_without_explicit_locking)
- ImplicitlyLockingInternalIdGenerator.new(subject, scope, usage, init)
- else
- InternalIdGenerator.new(subject, scope, usage, init)
- end
- end
- end
-
- class InternalIdGenerator
- # Generate next internal id for a given scope and usage.
- #
- # For currently supported usages, see #usage enum.
- #
- # The method implements a locking scheme that has the following properties:
- # 1) Generated sequence of internal ids is unique per (scope and usage)
- # 2) The method is thread-safe and may be used in concurrent threads/processes.
- # 3) The generated sequence is gapless.
- # 4) In the absence of a record in the internal_ids table, one will be created
- # and last_value will be calculated on the fly.
- #
- # subject: The instance or class we're generating an internal id for.
- # scope: Attributes that define the scope for id generation.
- # Valid keys are `project/project_id` and `namespace/namespace_id`.
- # usage: Symbol to define the usage of the internal id, see InternalId.usages
- # init: Proc that accepts the subject and the scope and returns Integer|NilClass
- attr_reader :subject, :scope, :scope_attrs, :usage, :init
-
- def initialize(subject, scope, usage, init = nil)
- @subject = subject
- @scope = scope
- @usage = usage
- @init = init
-
- raise ArgumentError, 'Scope is not well-defined, need at least one column for scope (given: 0)' if scope.empty?
-
- unless InternalId.usages.has_key?(usage.to_s)
- raise ArgumentError, "Usage '#{usage}' is unknown. Supported values are #{InternalId.usages.keys} from InternalId.usages"
- end
- end
-
- # Generates next internal id and returns it
- # init: Block that gets called to initialize InternalId record if not present
- # Make sure to not throw exceptions in the absence of records (if this is expected).
- def generate
- InternalId.internal_id_transactions_increment(operation: :generate, usage: usage)
-
- subject.transaction do
- # Create a record in internal_ids if one does not yet exist
- # and increment its last value
- #
- # Note this will acquire a ROW SHARE lock on the InternalId record
- record.increment_and_save!
- end
- end
-
- # Reset tries to rewind to `value-1`. This will only succeed,
- # if `value` stored in database is equal to `last_value`.
- # value: The expected last_value to decrement
- def reset(value)
- return false unless value
-
- InternalId.internal_id_transactions_increment(operation: :reset, usage: usage)
-
- updated =
- InternalId
- .where(**scope, usage: usage_value)
- .where(last_value: value)
- .update_all('last_value = last_value - 1')
-
- updated > 0
- end
-
- # Create a record in internal_ids if one does not yet exist
- # and set its new_value if it is higher than the current last_value
- #
- # Note this will acquire a ROW SHARE lock on the InternalId record
-
- def track_greatest(new_value)
- InternalId.internal_id_transactions_increment(operation: :track_greatest, usage: usage)
-
- subject.transaction do
- record.track_greatest_and_save!(new_value)
- end
- end
-
- def record
- @record ||= (lookup || create_record)
- end
-
- def with_lock(&block)
- InternalId.internal_id_transactions_increment(operation: :with_lock, usage: usage)
-
- record.with_lock(&block)
- end
-
- private
-
- # Retrieve InternalId record for (project, usage) combination, if it exists
- def lookup
- InternalId.find_by(**scope, usage: usage_value)
- end
-
- def usage_value
- @usage_value ||= InternalId.usages[usage.to_s]
- end
-
- # Create InternalId record for (scope, usage) combination, if it doesn't exist
- #
- # We blindly insert without synchronization. If another process
- # was faster in doing this, we'll realize once we hit the unique key constraint
- # violation. We can safely roll-back the nested transaction and perform
- # a lookup instead to retrieve the record.
- def create_record
- raise ArgumentError, 'Cannot initialize without init!' unless init
-
- instance = subject.is_a?(::Class) ? nil : subject
-
- subject.transaction(requires_new: true) do
- InternalId.create!(
- **scope,
- usage: usage_value,
- last_value: init.call(instance, scope) || 0
- )
- end
- rescue ActiveRecord::RecordNotUnique
- lookup
+ ImplicitlyLockingInternalIdGenerator.new(subject, scope, usage, init)
end
end
@@ -247,6 +96,8 @@ class InternalId < ApplicationRecord
# init: Proc that accepts the subject and the scope and returns Integer|NilClass
attr_reader :subject, :scope, :scope_attrs, :usage, :init
+ RecordAlreadyExists = Class.new(StandardError)
+
def initialize(subject, scope, usage, init = nil)
@subject = subject
@scope = scope
@@ -270,10 +121,8 @@ class InternalId < ApplicationRecord
return next_iid if next_iid
- create_record!(subject, scope, usage, init) do |iid|
- iid.last_value += 1
- end
- rescue ActiveRecord::RecordNotUnique
+ create_record!(subject, scope, usage, initial_value(subject, scope) + 1)
+ rescue RecordAlreadyExists
retry
end
@@ -302,10 +151,8 @@ class InternalId < ApplicationRecord
next_iid = update_record!(subject, scope, usage, function)
return next_iid if next_iid
- create_record!(subject, scope, usage, init) do |object|
- object.last_value = [object.last_value, new_value].max
- end
- rescue ActiveRecord::RecordNotUnique
+ create_record!(subject, scope, usage, [initial_value(subject, scope), new_value].max)
+ rescue RecordAlreadyExists
retry
end
@@ -317,27 +164,45 @@ class InternalId < ApplicationRecord
stmt.set(arel_table[:last_value] => new_value)
stmt.wheres = InternalId.filter_by(scope, usage).arel.constraints
- ActiveRecord::Base.connection.insert(stmt, 'Update InternalId', 'last_value') # rubocop: disable Database/MultipleDatabases
+ InternalId.connection.insert(stmt, 'Update InternalId', 'last_value')
end
- def create_record!(subject, scope, usage, init)
- raise ArgumentError, 'Cannot initialize without init!' unless init
+ def create_record!(subject, scope, usage, value)
+ scope[:project].save! if scope[:project] && !scope[:project].persisted?
+ scope[:namespace].save! if scope[:namespace] && !scope[:namespace].persisted?
- instance = subject.is_a?(::Class) ? nil : subject
+ attributes = {
+ project_id: scope[:project]&.id || scope[:project_id],
+ namespace_id: scope[:namespace]&.id || scope[:namespace_id],
+ usage: usage_value,
+ last_value: value
+ }
- subject.transaction(requires_new: true) do
- last_value = init.call(instance, scope) || 0
+ result = InternalId.insert(attributes)
- internal_id = InternalId.create!(**scope, usage: usage, last_value: last_value) do |subject|
- yield subject if block_given?
- end
+ raise RecordAlreadyExists if result.empty?
- internal_id.last_value
- end
+ value
end
def arel_table
InternalId.arel_table
end
+
+ def initial_value(subject, scope)
+ raise ArgumentError, 'Cannot initialize without init!' unless init
+
+ # `init` computes the maximum based on actual records. We use the
+ # primary to make sure we have up to date results
+ Gitlab::Database::LoadBalancing::Session.current.use_primary do
+ instance = subject.is_a?(::Class) ? nil : subject
+
+ init.call(instance, scope) || 0
+ end
+ end
+
+ def usage_value
+ @usage_value ||= InternalId.usages[usage.to_s]
+ end
end
end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 48e3fdd51e9..e0b0c352c22 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -128,13 +128,15 @@ class Issue < ApplicationRecord
}
scope :with_issue_type, ->(types) { where(issue_type: types) }
- scope :public_only, -> { where(confidential: false) }
+ scope :public_only, -> {
+ without_hidden.where(confidential: false)
+ }
+
scope :confidential_only, -> { where(confidential: true) }
scope :without_hidden, -> {
if Feature.enabled?(:ban_user_feature_flag)
- where(id: joins('LEFT JOIN banned_users ON banned_users.user_id = issues.author_id WHERE banned_users.user_id IS NULL')
- .select('issues.id'))
+ where('NOT EXISTS (?)', Users::BannedUser.select(1).where('issues.author_id = banned_users.user_id'))
else
all
end
@@ -323,6 +325,13 @@ class Issue < ApplicationRecord
)
end
+ def self.column_order_id_asc
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: 'id',
+ order_expression: arel_table[:id].asc
+ )
+ end
+
def self.to_branch_name(*args)
branch_name = args.map(&:to_s).each_with_index.map do |arg, i|
arg.parameterize(preserve_case: i == 0).presence
@@ -584,15 +593,9 @@ class Issue < ApplicationRecord
confidential_changed?(from: true, to: false)
end
- # Ensure that the metrics association is safely created and respecting the unique constraint on issue_id
override :ensure_metrics
def ensure_metrics
- if !association(:metrics).loaded? || metrics.blank?
- metrics_record = Issue::Metrics.safe_find_or_create_by(issue: self)
- self.metrics = metrics_record
- end
-
- metrics.record!
+ Issue::Metrics.record!(self)
end
def record_create_action
diff --git a/app/models/issue/metrics.rb b/app/models/issue/metrics.rb
index 86523bbd023..25afd9bf58d 100644
--- a/app/models/issue/metrics.rb
+++ b/app/models/issue/metrics.rb
@@ -9,25 +9,30 @@ class Issue::Metrics < ApplicationRecord
.or(where(arel_table['first_mentioned_in_commit_at'].gteq(timestamp)))
}
- def record!
- if issue.milestone_id.present? && self.first_associated_with_milestone_at.blank?
- self.first_associated_with_milestone_at = Time.current
+ class << self
+ def record!(issue)
+ now = connection.quote(Time.current)
+ first_associated_with_milestone_at = issue.milestone_id.present? ? now : 'NULL'
+ first_added_to_board_at = issue_assigned_to_list_label?(issue) ? now : 'NULL'
+
+ sql = <<~SQL
+ INSERT INTO #{self.table_name} (issue_id, first_associated_with_milestone_at, first_added_to_board_at, created_at, updated_at)
+ VALUES (#{issue.id}, #{first_associated_with_milestone_at}, #{first_added_to_board_at}, NOW(), NOW())
+ ON CONFLICT (issue_id)
+ DO UPDATE SET
+ first_associated_with_milestone_at = LEAST(#{self.table_name}.first_associated_with_milestone_at, EXCLUDED.first_associated_with_milestone_at),
+ first_added_to_board_at = LEAST(#{self.table_name}.first_added_to_board_at, EXCLUDED.first_added_to_board_at),
+ updated_at = NOW()
+ RETURNING id
+ SQL
+
+ connection.execute(sql)
end
- if issue_assigned_to_list_label? && self.first_added_to_board_at.blank?
- self.first_added_to_board_at = Time.current
- end
-
- self.save
- end
+ private
- private
-
- def issue_assigned_to_list_label?
- # Avoid another DB lookup when issue.labels are empty by adding a guard clause here
- # We can't use issue.labels.empty? because that will cause a `Label Exists?` DB lookup
- return false if issue.labels.length == 0 # rubocop:disable Style/ZeroLengthPredicate
-
- issue.labels.includes(:lists).any? { |label| label.lists.present? }
+ def issue_assigned_to_list_label?(issue)
+ issue.labels.joins(:lists).exists?
+ end
end
end
diff --git a/app/models/loose_foreign_keys.rb b/app/models/loose_foreign_keys.rb
new file mode 100644
index 00000000000..0f45c0b5568
--- /dev/null
+++ b/app/models/loose_foreign_keys.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+module LooseForeignKeys
+ def self.table_name_prefix
+ 'loose_foreign_keys_'
+ end
+end
diff --git a/app/models/loose_foreign_keys/deleted_record.rb b/app/models/loose_foreign_keys/deleted_record.rb
new file mode 100644
index 00000000000..a39d88b2e49
--- /dev/null
+++ b/app/models/loose_foreign_keys/deleted_record.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+class LooseForeignKeys::DeletedRecord < ApplicationRecord
+ extend SuppressCompositePrimaryKeyWarning
+ include PartitionedTable
+
+ partitioned_by :created_at, strategy: :monthly, retain_for: 3.months, retain_non_empty_partitions: true
+
+ scope :ordered_by_primary_keys, -> { order(:created_at, :deleted_table_name, :deleted_table_primary_key_value) }
+
+ def self.load_batch(batch_size)
+ ordered_by_primary_keys
+ .limit(batch_size)
+ .to_a
+ end
+
+ # Because the table has composite primary keys, the delete_all or delete methods are not going to work.
+ # This method implements deletion that benefits from the primary key index, example:
+ #
+ # > DELETE
+ # > FROM "loose_foreign_keys_deleted_records"
+ # > WHERE (created_at,
+ # > deleted_table_name,
+ # > deleted_table_primary_key_value) IN
+ # > (SELECT created_at::TIMESTAMP WITH TIME ZONE,
+ # > deleted_table_name,
+ # > deleted_table_primary_key_value
+ # > FROM (VALUES (LIST_OF_VALUES)) AS primary_key_values (created_at, deleted_table_name, deleted_table_primary_key_value))
+ def self.delete_records(records)
+ values = records.pluck(:created_at, :deleted_table_name, :deleted_table_primary_key_value)
+
+ primary_keys = connection.primary_keys(table_name).join(', ')
+
+ primary_keys_with_type_cast = [
+ Arel.sql('created_at::timestamp with time zone'),
+ Arel.sql('deleted_table_name'),
+ Arel.sql('deleted_table_primary_key_value')
+ ]
+
+ value_list = Arel::Nodes::ValuesList.new(values)
+
+ # (SELECT primary keys FROM VALUES)
+ inner_query = Arel::SelectManager.new
+ inner_query.from("#{Arel::Nodes::Grouping.new([value_list]).as('primary_key_values').to_sql} (#{primary_keys})")
+ inner_query.projections = primary_keys_with_type_cast
+
+ where(Arel::Nodes::Grouping.new([Arel.sql(primary_keys)]).in(inner_query)).delete_all
+ end
+end
diff --git a/app/models/member.rb b/app/models/member.rb
index 397e60be3a8..beb4c05f2a6 100644
--- a/app/models/member.rb
+++ b/app/models/member.rb
@@ -147,7 +147,6 @@ class Member < ApplicationRecord
scope :owners, -> { active.where(access_level: OWNER) }
scope :owners_and_maintainers, -> { active.where(access_level: [OWNER, MAINTAINER]) }
scope :with_user, -> (user) { where(user: user) }
- scope :with_user_by_email, -> (email) { left_join_users.where(users: { email: email } ) }
scope :preload_user_and_notification_settings, -> { preload(user: :notification_settings) }
@@ -278,12 +277,14 @@ class Member < ApplicationRecord
def accept_invite!(new_user)
return false unless invite?
+ return false unless new_user
+
+ self.user = new_user
+ return false unless self.user.save
self.invite_token = nil
self.invite_accepted_at = Time.current.utc
- self.user = new_user
-
saved = self.save
after_accept_invite if saved
diff --git a/app/models/members/project_member.rb b/app/models/members/project_member.rb
index b45c0b6a0cc..72cb831cc88 100644
--- a/app/models/members/project_member.rb
+++ b/app/models/members/project_member.rb
@@ -44,7 +44,7 @@ class ProjectMember < Member
project_ids.each do |project_id|
project = Project.find(project_id)
- Members::Projects::CreatorService.add_users( # rubocop:disable CodeReuse/ServiceClass
+ Members::Projects::BulkCreatorService.add_users( # rubocop:disable CodeReuse/ServiceClass
project,
users,
access_level,
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index a090ac87cc9..db49ec6f412 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -615,8 +615,8 @@ class MergeRequest < ApplicationRecord
context_commits.count
end
- def commits(limit: nil)
- return merge_request_diff.commits(limit: limit) if merge_request_diff.persisted?
+ def commits(limit: nil, load_from_gitaly: false)
+ return merge_request_diff.commits(limit: limit, load_from_gitaly: load_from_gitaly) if merge_request_diff.persisted?
commits_arr = if compare_commits
reversed_commits = compare_commits.reverse
@@ -628,8 +628,8 @@ class MergeRequest < ApplicationRecord
CommitCollection.new(source_project, commits_arr, source_branch)
end
- def recent_commits
- commits(limit: MergeRequestDiff::COMMITS_SAFE_SIZE)
+ def recent_commits(load_from_gitaly: false)
+ commits(limit: MergeRequestDiff::COMMITS_SAFE_SIZE, load_from_gitaly: load_from_gitaly)
end
def commits_count
@@ -1349,7 +1349,9 @@ class MergeRequest < ApplicationRecord
def has_ci?
return false if has_no_commits?
- !!(head_pipeline_id || all_pipelines.any? || source_project&.ci_integration)
+ ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336891') do
+ !!(head_pipeline_id || all_pipelines.any? || source_project&.ci_integration)
+ end
end
def branch_missing?
@@ -1835,15 +1837,10 @@ class MergeRequest < ApplicationRecord
Ability.allowed?(user, :push_code, source_project)
end
- def squash_in_progress?
- # The source project can be deleted
- return false unless source_project
-
- source_project.repository.squash_in_progress?(id)
- end
-
def find_actual_head_pipeline
- all_pipelines.for_sha_or_source_sha(diff_head_sha).first
+ ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336891') do
+ all_pipelines.for_sha_or_source_sha(diff_head_sha).first
+ end
end
def etag_caching_enabled?
@@ -1860,25 +1857,29 @@ class MergeRequest < ApplicationRecord
override :ensure_metrics
def ensure_metrics
- # Backward compatibility: some merge request metrics records will not have target_project_id filled in.
- # In that case the first `safe_find_or_create_by` will return false.
- # The second finder call will be eliminated in https://gitlab.com/gitlab-org/gitlab/-/issues/233507
- metrics_record = MergeRequest::Metrics.safe_find_or_create_by(merge_request_id: id, target_project_id: target_project_id) || MergeRequest::Metrics.safe_find_or_create_by(merge_request_id: id)
-
- metrics_record.tap do |metrics_record|
- # Make sure we refresh the loaded association object with the newly created/loaded item.
- # This is needed in order to have the exact functionality than before.
- #
- # Example:
- #
- # merge_request.metrics.destroy
- # merge_request.ensure_metrics
- # merge_request.metrics # should return the metrics record and not nil
- # merge_request.metrics.merge_request # should return the same MR record
-
- metrics_record.target_project_id = target_project_id
- metrics_record.association(:merge_request).target = self
- association(:metrics).target = metrics_record
+ if Feature.enabled?(:use_upsert_query_for_mr_metrics)
+ MergeRequest::Metrics.record!(self)
+ else
+ # Backward compatibility: some merge request metrics records will not have target_project_id filled in.
+ # In that case the first `safe_find_or_create_by` will return false.
+ # The second finder call will be eliminated in https://gitlab.com/gitlab-org/gitlab/-/issues/233507
+ metrics_record = MergeRequest::Metrics.safe_find_or_create_by(merge_request_id: id, target_project_id: target_project_id) || MergeRequest::Metrics.safe_find_or_create_by(merge_request_id: id)
+
+ metrics_record.tap do |metrics_record|
+ # Make sure we refresh the loaded association object with the newly created/loaded item.
+ # This is needed in order to have the exact functionality than before.
+ #
+ # Example:
+ #
+ # merge_request.metrics.destroy
+ # merge_request.ensure_metrics
+ # merge_request.metrics # should return the metrics record and not nil
+ # merge_request.metrics.merge_request # should return the same MR record
+
+ metrics_record.target_project_id = target_project_id
+ metrics_record.association(:merge_request).target = self
+ association(:metrics).target = metrics_record
+ end
end
end
@@ -1917,6 +1918,20 @@ class MergeRequest < ApplicationRecord
end
end
+ def lazy_upvotes_count
+ BatchLoader.for(id).batch(default_value: 0) do |ids, loader|
+ counts = AwardEmoji
+ .where(awardable_id: ids)
+ .upvotes
+ .group(:awardable_id)
+ .count
+
+ counts.each do |id, count|
+ loader.call(id, count)
+ end
+ end
+ end
+
private
def set_draft_status
diff --git a/app/models/merge_request/metrics.rb b/app/models/merge_request/metrics.rb
index b9460afa8e7..b984228eb13 100644
--- a/app/models/merge_request/metrics.rb
+++ b/app/models/merge_request/metrics.rb
@@ -14,8 +14,23 @@ class MergeRequest::Metrics < ApplicationRecord
scope :with_valid_time_to_merge, -> { where(arel_table[:merged_at].gt(arel_table[:created_at])) }
scope :by_target_project, ->(project) { where(target_project_id: project) }
- def self.time_to_merge_expression
- Arel.sql('EXTRACT(epoch FROM SUM(AGE(merge_request_metrics.merged_at, merge_request_metrics.created_at)))')
+ class << self
+ def time_to_merge_expression
+ Arel.sql('EXTRACT(epoch FROM SUM(AGE(merge_request_metrics.merged_at, merge_request_metrics.created_at)))')
+ end
+
+ def record!(mr)
+ sql = <<~SQL
+ INSERT INTO #{self.table_name} (merge_request_id, target_project_id, updated_at, created_at)
+ VALUES (#{mr.id}, #{mr.target_project_id}, NOW(), NOW())
+ ON CONFLICT (merge_request_id)
+ DO UPDATE SET
+ target_project_id = EXCLUDED.target_project_id,
+ updated_at = NOW()
+ SQL
+
+ connection.execute(sql)
+ end
end
private
diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb
index bea75927b2c..d2b3ca753b1 100644
--- a/app/models/merge_request_diff.rb
+++ b/app/models/merge_request_diff.rb
@@ -288,9 +288,9 @@ class MergeRequestDiff < ApplicationRecord
end
end
- def commits(limit: nil)
- strong_memoize(:"commits_#{limit || 'all'}") do
- load_commits(limit: limit)
+ def commits(limit: nil, load_from_gitaly: false)
+ strong_memoize(:"commits_#{limit || 'all'}_#{load_from_gitaly}") do
+ load_commits(limit: limit, load_from_gitaly: load_from_gitaly)
end
end
@@ -700,9 +700,14 @@ class MergeRequestDiff < ApplicationRecord
end
end
- def load_commits(limit: nil)
- commits = merge_request_diff_commits.with_users.limit(limit)
- .map { |commit| Commit.from_hash(commit.to_hash, project) }
+ def load_commits(limit: nil, load_from_gitaly: false)
+ if load_from_gitaly
+ commits = Gitlab::Git::Commit.batch_by_oid(repository, merge_request_diff_commits.limit(limit).map(&:sha))
+ commits = Commit.decorate(commits, project)
+ else
+ commits = merge_request_diff_commits.with_users.limit(limit)
+ .map { |commit| Commit.from_hash(commit.to_hash, project) }
+ end
CommitCollection
.new(merge_request.source_project, commits, merge_request.source_branch)
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index 0e2842c3c11..868bee9961b 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -61,18 +61,10 @@ class Milestone < ApplicationRecord
end
def self.reference_pattern
- if Feature.enabled?(:milestone_reference_pattern, default_enabled: :yaml)
- new_reference_pattern
- else
- old_reference_pattern
- end
- end
-
- def self.new_reference_pattern
# NOTE: The iid pattern only matches when all characters on the expression
# are digits, so it will match %2 but not %2.1 because that's probably a
# milestone name and we want it to be matched as such.
- @new_reference_pattern ||= %r{
+ @reference_pattern ||= %r{
(#{Project.reference_pattern})?
#{Regexp.escape(reference_prefix)}
(?:
@@ -87,26 +79,6 @@ class Milestone < ApplicationRecord
}x
end
- # Deprecated: https://gitlab.com/gitlab-org/gitlab/-/issues/336268
- def self.old_reference_pattern
- # NOTE: The iid pattern only matches when all characters on the expression
- # are digits, so it will match %2 but not %2.1 because that's probably a
- # milestone name and we want it to be matched as such.
- @old_reference_pattern ||= %r{
- (#{Project.reference_pattern})?
- #{Regexp.escape(reference_prefix)}
- (?:
- (?<milestone_iid>
- \d+(?!\S\w)\b # Integer-based milestone iid, or
- ) |
- (?<milestone_name>
- [^"\s]+\b | # String-based single-word milestone title, or
- "[^"]+" # String-based multi-word milestone surrounded in quotes
- )
- )
- }x
- end
-
def self.link_reference_pattern
@link_reference_pattern ||= super("milestones", /(?<milestone>\d+)/)
end
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index 261639a4ec1..0c160cedb4d 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -18,6 +18,11 @@ class Namespace < ApplicationRecord
ignore_column :delayed_project_removal, remove_with: '14.1', remove_after: '2021-05-22'
+ # Tells ActiveRecord not to store the full class name, in order to space some space
+ # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69794
+ self.store_full_sti_class = false
+ self.store_full_class_name = false
+
# Prevent users from creating unreasonably deep level of nesting.
# The number 20 was taken based on maximum nesting level of
# Android repo (15) + some extra backup.
@@ -52,7 +57,7 @@ class Namespace < ApplicationRecord
has_one :admin_note, inverse_of: :namespace
accepts_nested_attributes_for :admin_note, update_only: true
- validates :owner, presence: true, unless: ->(n) { n.type == "Group" }
+ validates :owner, presence: true, if: ->(n) { n.owner_required? }
validates :name,
presence: true,
length: { maximum: 255 }
@@ -131,6 +136,21 @@ class Namespace < ApplicationRecord
attr_writer :root_ancestor, :emails_disabled_memoized
class << self
+ def sti_class_for(type_name)
+ case type_name
+ when 'Group'
+ Group
+ when 'Project'
+ Namespaces::ProjectNamespace
+ when 'User'
+ # TODO: We create a normal Namespace until
+ # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68894 is ready
+ Namespace
+ else
+ Namespace
+ end
+ end
+
def by_path(path)
find_by('lower(path) = :value', value: path.downcase)
end
@@ -227,15 +247,27 @@ class Namespace < ApplicationRecord
end
def kind
- type == 'Group' ? 'group' : 'user'
+ return 'group' if group?
+ return 'project' if project?
+
+ 'user' # defaults to user
+ end
+
+ def group?
+ type == Group.sti_name
+ end
+
+ def project?
+ type == Namespaces::ProjectNamespace.sti_name
end
def user?
- kind == 'user'
+ # That last bit ensures we're considered a user namespace as a default
+ type.nil? || type == Namespaces::UserNamespace.sti_name || !(group? || project?)
end
- def group?
- type == 'Group'
+ def owner_required?
+ user?
end
def find_fork_of(project)
@@ -498,17 +530,27 @@ class Namespace < ApplicationRecord
def nesting_level_allowed
if ancestors.count > Group::NUMBER_OF_ANCESTORS_ALLOWED
- errors.add(:parent_id, 'has too deep level of nesting')
+ errors.add(:parent_id, _('has too deep level of nesting'))
end
end
def validate_parent_type
- return unless has_parent?
+ unless has_parent?
+ if project?
+ errors.add(:parent_id, _('must be set for a project namespace'))
+ end
+
+ return
+ end
+
+ if parent.project?
+ errors.add(:parent_id, _('project namespace cannot be the parent of another namespace'))
+ end
if user?
- errors.add(:parent_id, 'a user namespace cannot have a parent')
+ errors.add(:parent_id, _('cannot not be used for user namespace'))
elsif group?
- errors.add(:parent_id, 'a group cannot have a user namespace as its parent') if parent.user?
+ errors.add(:parent_id, _('user namespace cannot be the parent of another namespace')) if parent.user?
end
end
diff --git a/app/models/namespace_setting.rb b/app/models/namespace_setting.rb
index 4a39bfebda0..170b29e9e21 100644
--- a/app/models/namespace_setting.rb
+++ b/app/models/namespace_setting.rb
@@ -2,6 +2,7 @@
class NamespaceSetting < ApplicationRecord
include CascadingNamespaceSettingAttribute
+ include Sanitizable
cascading_attr :delayed_project_removal
@@ -16,12 +17,17 @@ class NamespaceSetting < ApplicationRecord
before_validation :normalize_default_branch_name
+ enum jobs_to_be_done: { basics: 0, move_repository: 1, code_storage: 2, exploring: 3, ci: 4, other: 5 }, _suffix: true
+
NAMESPACE_SETTINGS_PARAMS = [:default_branch_name, :delayed_project_removal,
:lock_delayed_project_removal, :resource_access_token_creation_allowed,
- :prevent_sharing_groups_outside_hierarchy, :new_user_signups_cap].freeze
+ :prevent_sharing_groups_outside_hierarchy, :new_user_signups_cap,
+ :setup_for_company, :jobs_to_be_done].freeze
self.primary_key = :namespace_id
+ sanitizes! :default_branch_name
+
def prevent_sharing_groups_outside_hierarchy
return super if namespace.root?
@@ -31,11 +37,7 @@ class NamespaceSetting < ApplicationRecord
private
def normalize_default_branch_name
- self.default_branch_name = if default_branch_name.blank?
- nil
- else
- Sanitize.fragment(self.default_branch_name)
- end
+ self.default_branch_name = default_branch_name.presence
end
def default_branch_name_content
diff --git a/app/models/namespaces/project_namespace.rb b/app/models/namespaces/project_namespace.rb
new file mode 100644
index 00000000000..d1806c1c088
--- /dev/null
+++ b/app/models/namespaces/project_namespace.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Namespaces
+ class ProjectNamespace < Namespace
+ has_one :project, foreign_key: :project_namespace_id, inverse_of: :project_namespace
+
+ validates :project, presence: true
+
+ def self.sti_name
+ 'Project'
+ end
+ end
+end
diff --git a/app/models/namespaces/traversal/linear.rb b/app/models/namespaces/traversal/linear.rb
index 33e8c3e5172..d7130322ed1 100644
--- a/app/models/namespaces/traversal/linear.rb
+++ b/app/models/namespaces/traversal/linear.rb
@@ -74,7 +74,7 @@ module Namespaces
return super unless use_traversal_ids_for_root_ancestor?
strong_memoize(:root_ancestor) do
- if parent.nil?
+ if parent_id.nil?
self
else
Namespace.find_by(id: traversal_ids.first)
@@ -176,13 +176,14 @@ module Namespaces
# if you are walking up the ancestors or down the descendants.
if hierarchy_order
depth_sql = "ABS(#{traversal_ids.count} - array_length(traversal_ids, 1))"
- skope = skope.select(skope.arel_table[Arel.star], "#{depth_sql} as depth")
+ skope = skope.select(skope.default_select_columns, "#{depth_sql} as depth")
# The SELECT includes an extra depth attribute. We wrap the SQL in a
# standard SELECT to avoid mismatched attribute errors when trying to
# chain future ActiveRelation commands, and retain the ordering.
skope = self.class
.without_sti_condition
.from(skope, self.class.table_name)
+ .select(skope.arel_table[Arel.star])
.order(depth: hierarchy_order)
end
diff --git a/app/models/namespaces/traversal/linear_scopes.rb b/app/models/namespaces/traversal/linear_scopes.rb
index 90fae8ef35d..2da0e48c2da 100644
--- a/app/models/namespaces/traversal/linear_scopes.rb
+++ b/app/models/namespaces/traversal/linear_scopes.rb
@@ -15,6 +15,28 @@ module Namespaces
select('namespaces.traversal_ids[array_length(namespaces.traversal_ids, 1)] AS id')
end
+ def self_and_ancestors(include_self: true, hierarchy_order: nil)
+ return super unless use_traversal_ids_for_ancestor_scopes?
+
+ records = unscoped
+ .without_sti_condition
+ .where(id: without_sti_condition.select('unnest(traversal_ids)'))
+ .order_by_depth(hierarchy_order)
+ .normal_select
+
+ if include_self
+ records
+ else
+ records.where.not(id: all.as_ids)
+ end
+ end
+
+ def self_and_ancestor_ids(include_self: true)
+ return super unless use_traversal_ids_for_ancestor_scopes?
+
+ self_and_ancestors(include_self: include_self).as_ids
+ end
+
def self_and_descendants(include_self: true)
return super unless use_traversal_ids?
@@ -22,11 +44,7 @@ module Namespaces
distinct = records.select('DISTINCT on(namespaces.id) namespaces.*')
- # Produce a query of the form: SELECT * FROM namespaces;
- #
- # When we have queries that break this SELECT * format we can run in to errors.
- # For example `SELECT DISTINCT on(...)` will fail when we chain a `.count` c
- unscoped.without_sti_condition.from(distinct, :namespaces)
+ distinct.normal_select
end
def self_and_descendant_ids(include_self: true)
@@ -42,12 +60,35 @@ module Namespaces
unscope(where: :type)
end
+ def order_by_depth(hierarchy_order)
+ return all unless hierarchy_order
+
+ depth_order = hierarchy_order == :asc ? :desc : :asc
+
+ all
+ .select(Arel.star, 'array_length(traversal_ids, 1) as depth')
+ .order(depth: depth_order, id: :asc)
+ end
+
+ # Produce a query of the form: SELECT * FROM namespaces;
+ #
+ # When we have queries that break this SELECT * format we can run in to errors.
+ # For example `SELECT DISTINCT on(...)` will fail when we chain a `.count` c
+ def normal_select
+ unscoped.without_sti_condition.from(all, :namespaces)
+ end
+
private
def use_traversal_ids?
Feature.enabled?(:use_traversal_ids, default_enabled: :yaml)
end
+ def use_traversal_ids_for_ancestor_scopes?
+ Feature.enabled?(:use_traversal_ids_for_ancestor_scopes, default_enabled: :yaml) &&
+ use_traversal_ids?
+ end
+
def self_and_descendants_with_duplicates(include_self: true)
base_ids = select(:id)
diff --git a/app/models/namespaces/traversal/recursive.rb b/app/models/namespaces/traversal/recursive.rb
index c1ada715d6d..8d2c5d3be5a 100644
--- a/app/models/namespaces/traversal/recursive.rb
+++ b/app/models/namespaces/traversal/recursive.rb
@@ -7,12 +7,12 @@ module Namespaces
include RecursiveScopes
def root_ancestor
- return self if parent.nil?
-
- if persisted?
+ if persisted? && !parent_id.nil?
strong_memoize(:root_ancestor) do
- recursive_self_and_ancestors.reorder(nil).find_by(parent_id: nil)
+ recursive_ancestors.reorder(nil).find_by(parent_id: nil)
end
+ elsif parent.nil?
+ self
else
parent.root_ancestor
end
diff --git a/app/models/namespaces/traversal/recursive_scopes.rb b/app/models/namespaces/traversal/recursive_scopes.rb
index be49d5d9d55..6659cefe095 100644
--- a/app/models/namespaces/traversal/recursive_scopes.rb
+++ b/app/models/namespaces/traversal/recursive_scopes.rb
@@ -10,6 +10,22 @@ module Namespaces
select('id')
end
+ def self_and_ancestors(include_self: true, hierarchy_order: nil)
+ records = Gitlab::ObjectHierarchy.new(all).base_and_ancestors(hierarchy_order: hierarchy_order)
+
+ if include_self
+ records
+ else
+ records.where.not(id: all.as_ids)
+ end
+ end
+ alias_method :recursive_self_and_ancestors, :self_and_ancestors
+
+ def self_and_ancestor_ids(include_self: true)
+ self_and_ancestors(include_self: include_self).as_ids
+ end
+ alias_method :recursive_self_and_ancestor_ids, :self_and_ancestor_ids
+
def descendant_ids
recursive_descendants.as_ids
end
diff --git a/app/models/namespaces/user_namespace.rb b/app/models/namespaces/user_namespace.rb
new file mode 100644
index 00000000000..517d68b118d
--- /dev/null
+++ b/app/models/namespaces/user_namespace.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+# TODO: currently not created/mapped in the database, will be done in another issue
+# https://gitlab.com/gitlab-org/gitlab/-/issues/337102
+module Namespaces
+ class UserNamespace < Namespace
+ def self.sti_name
+ 'User'
+ end
+ end
+end
diff --git a/app/models/note.rb b/app/models/note.rb
index 34ffd7c91af..a8f5c305d9b 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -48,6 +48,9 @@ class Note < ApplicationRecord
# Attribute used to store the attributes that have been changed by quick actions.
attr_accessor :commands_changes
+ # Attribute used to determine whether keep_around_commits will be skipped for diff notes.
+ attr_accessor :skip_keep_around_commits
+
default_value_for :system, false
attr_mentionable :note, pipeline: :note
@@ -112,7 +115,6 @@ class Note < ApplicationRecord
scope :updated_after, ->(time) { where('updated_at > ?', time) }
scope :with_updated_at, ->(time) { where(updated_at: time) }
scope :with_suggestions, -> { joins(:suggestions) }
- scope :inc_author_project, -> { includes(:project, :author) }
scope :inc_author, -> { includes(:author) }
scope :with_api_entity_associations, -> { preload(:note_diff_file, :author) }
scope :inc_relations_for_view, -> do
@@ -579,7 +581,8 @@ class Note < ApplicationRecord
end
def post_processed_cache_key
- cache_key_items = [cache_key, author.cache_key]
+ cache_key_items = [cache_key, author&.cache_key]
+ cache_key_items << project.team.human_max_access(author&.id) if author.present?
cache_key_items << Digest::SHA1.hexdigest(redacted_note_html) if redacted_note_html.present?
cache_key_items.join(':')
@@ -603,14 +606,6 @@ class Note < ApplicationRecord
private
- # Using this method followed by a call to *save* may result in *ActiveRecord::RecordNotUnique* exception
- # in a multi-threaded environment. Make sure to use it within a *safe_ensure_unique* block.
- def model_user_mention
- return if user_mentions.is_a?(ActiveRecord::NullRelation)
-
- user_mentions.first_or_initialize
- end
-
def system_note_viewable_by?(user)
return true unless system_note_metadata
@@ -648,7 +643,7 @@ class Note < ApplicationRecord
user_visible_reference_count > 0 && user_visible_reference_count == total_reference_count
else
refs = all_references(user)
- refs.all.any? && refs.stateful_not_visible_counter == 0
+ refs.all.any? && refs.all_visible?
end
end
diff --git a/app/models/onboarding_progress.rb b/app/models/onboarding_progress.rb
index 9185547d7cd..c12309d1852 100644
--- a/app/models/onboarding_progress.rb
+++ b/app/models/onboarding_progress.rb
@@ -45,7 +45,7 @@ class OnboardingProgress < ApplicationRecord
def onboard(namespace)
return unless root_namespace?(namespace)
- safe_find_or_create_by(namespace: namespace)
+ create(namespace: namespace)
end
def onboarding?(namespace)
diff --git a/app/models/operations/feature_flag.rb b/app/models/operations/feature_flag.rb
index 450a5970ad8..46810749b18 100644
--- a/app/models/operations/feature_flag.rb
+++ b/app/models/operations/feature_flag.rb
@@ -17,6 +17,7 @@ module Operations
has_internal_id :iid, scope: :project
default_value_for :active, true
+ default_value_for :version, :new_version_flag
# scopes exists only for the first version
has_many :scopes, class_name: 'Operations::FeatureFlagScope'
@@ -39,8 +40,6 @@ module Operations
validate :first_default_scope, on: :create, if: :has_scopes?
validate :version_associations
- before_create :build_default_scope, if: -> { legacy_flag? && scopes.none? }
-
accepts_nested_attributes_for :scopes, allow_destroy: true
accepts_nested_attributes_for :strategies, allow_destroy: true
@@ -52,7 +51,6 @@ module Operations
scope :new_version_only, -> { where(version: :new_version_flag)}
enum version: {
- legacy_flag: 1,
new_version_flag: 2
}
@@ -127,8 +125,6 @@ module Operations
def version_associations
if new_version_flag? && scopes.any?
errors.add(:version_associations, 'version 2 feature flags may not have scopes')
- elsif legacy_flag? && strategies.any?
- errors.add(:version_associations, 'version 1 feature flags may not have strategies')
end
end
diff --git a/app/models/operations/feature_flag_scope.rb b/app/models/operations/feature_flag_scope.rb
index 78be29f2531..9068ca0f588 100644
--- a/app/models/operations/feature_flag_scope.rb
+++ b/app/models/operations/feature_flag_scope.rb
@@ -1,5 +1,9 @@
# frozen_string_literal: true
+# All of the legacy flags have been removed in 14.1, including all of the
+# `operations_feature_flag_scopes` rows. Therefore, this model and the database
+# table are unused and should be removed.
+
module Operations
class FeatureFlagScope < ApplicationRecord
prepend HasEnvironmentScope
diff --git a/app/models/packages/package.rb b/app/models/packages/package.rb
index 4ea127fc222..34eae6ab5dc 100644
--- a/app/models/packages/package.rb
+++ b/app/models/packages/package.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
class Packages::Package < ApplicationRecord
+ include EachBatch
include Sortable
include Gitlab::SQL::Pattern
include UsageStatistics
@@ -104,6 +105,7 @@ class Packages::Package < ApplicationRecord
scope :including_build_info, -> { includes(pipelines: :user) }
scope :including_project_route, -> { includes(project: { namespace: :route }) }
scope :including_tags, -> { includes(:tags) }
+ scope :including_dependency_links, -> { includes(dependency_links: :dependency) }
scope :with_conan_channel, ->(package_channel) do
joins(:conan_metadatum).where(packages_conan_metadata: { package_channel: package_channel })
@@ -291,6 +293,13 @@ class Packages::Package < ApplicationRecord
::Packages::Maven::Metadata::SyncWorker.perform_async(user.id, project.id, name)
end
+ def create_build_infos!(build)
+ return unless build&.pipeline
+
+ # TODO: use an upsert call when https://gitlab.com/gitlab-org/gitlab/-/issues/339093 is implemented
+ build_infos.find_or_create_by!(pipeline: build.pipeline)
+ end
+
private
def composer_tag_version?
diff --git a/app/models/packages/package_file.rb b/app/models/packages/package_file.rb
index 8aa19397086..14701b8a800 100644
--- a/app/models/packages/package_file.rb
+++ b/app/models/packages/package_file.rb
@@ -77,6 +77,10 @@ class Packages::PackageFile < ApplicationRecord
.where(packages_conan_file_metadata: { conan_package_reference: conan_package_reference })
end
+ def self.most_recent!
+ recent.first!
+ end
+
mount_file_store_uploader Packages::PackageFileUploader
update_project_statistics project_statistics_name: :packages_size
@@ -89,6 +93,24 @@ class Packages::PackageFile < ApplicationRecord
skip_callback :commit, :after, :remove_previously_stored_file, if: :execute_move_in_object_storage?
after_commit :move_in_object_storage, if: :execute_move_in_object_storage?
+ # Returns the most recent package files for *each* of the given packages.
+ # The order is not guaranteed.
+ def self.most_recent_for(packages, extra_join: nil, extra_where: nil)
+ cte_name = :packages_cte
+ cte = Gitlab::SQL::CTE.new(cte_name, packages.select(:id))
+
+ package_files = ::Packages::PackageFile.limit_recent(1)
+ .where(arel_table[:package_id].eq(Arel.sql("#{cte_name}.id")))
+
+ package_files = package_files.joins(extra_join) if extra_join
+ package_files = package_files.where(extra_where) if extra_where
+
+ query = select('finder.*')
+ .from([Arel.sql(cte_name.to_s), package_files.arel.lateral.as('finder')])
+
+ query.with(cte.to_arel)
+ end
+
def download_path
Gitlab::Routing.url_helpers.download_project_package_file_path(project, self)
end
diff --git a/app/models/pages_deployment.rb b/app/models/pages_deployment.rb
index 294a4e85d1f..da6ef035c54 100644
--- a/app/models/pages_deployment.rb
+++ b/app/models/pages_deployment.rb
@@ -16,6 +16,7 @@ class PagesDeployment < ApplicationRecord
scope :migrated_from_legacy_storage, -> { where(file: MIGRATED_FILE_NAME) }
scope :with_files_stored_locally, -> { where(file_store: ::ObjectStorage::Store::LOCAL) }
scope :with_files_stored_remotely, -> { where(file_store: ::ObjectStorage::Store::REMOTE) }
+ scope :project_id_in, ->(ids) { where(project_id: ids) }
validates :file, presence: true
validates :file_store, presence: true, inclusion: { in: ObjectStorage::SUPPORTED_STORES }
@@ -27,10 +28,6 @@ class PagesDeployment < ApplicationRecord
mount_file_store_uploader ::Pages::DeploymentUploader
- def log_geo_deleted_event
- # this is to be adressed in https://gitlab.com/groups/gitlab-org/-/epics/589
- end
-
def migrated?
file.filename == MIGRATED_FILE_NAME
end
@@ -41,3 +38,5 @@ class PagesDeployment < ApplicationRecord
self.size = file.size
end
end
+
+PagesDeployment.prepend_mod
diff --git a/app/models/postgresql/detached_partition.rb b/app/models/postgresql/detached_partition.rb
index 76b299ff9d4..12b48895e0c 100644
--- a/app/models/postgresql/detached_partition.rb
+++ b/app/models/postgresql/detached_partition.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Postgresql
- class DetachedPartition < ApplicationRecord
+ class DetachedPartition < ::Gitlab::Database::SharedModel
scope :ready_to_drop, -> { where('drop_after < ?', Time.current) }
end
end
diff --git a/app/models/preloaders/commit_status_preloader.rb b/app/models/preloaders/commit_status_preloader.rb
new file mode 100644
index 00000000000..535dd24ba6b
--- /dev/null
+++ b/app/models/preloaders/commit_status_preloader.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module Preloaders
+ class CommitStatusPreloader
+ CLASSES = [::Ci::Build, ::Ci::Bridge, ::GenericCommitStatus].freeze
+
+ def initialize(statuses)
+ @statuses = statuses
+ end
+
+ def execute(relations)
+ preloader = ActiveRecord::Associations::Preloader.new
+
+ CLASSES.each do |klass|
+ preloader.preload(objects(klass), associations(klass, relations))
+ end
+ end
+
+ private
+
+ def objects(klass)
+ @statuses.select { |job| job.is_a?(klass) }
+ end
+
+ def associations(klass, relations)
+ klass.reflections.keys.map(&:to_sym) & relations.map(&:to_sym)
+ end
+ end
+end
diff --git a/app/models/preloaders/merge_requests_preloader.rb b/app/models/preloaders/merge_requests_preloader.rb
new file mode 100644
index 00000000000..cefe8408cab
--- /dev/null
+++ b/app/models/preloaders/merge_requests_preloader.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Preloaders
+ class MergeRequestsPreloader
+ attr_reader :merge_requests
+
+ def initialize(merge_requests)
+ @merge_requests = merge_requests
+ end
+
+ def execute
+ preloader = ActiveRecord::Associations::Preloader.new
+ preloader.preload(merge_requests, { target_project: [:project_feature] })
+ merge_requests.each do |merge_request|
+ merge_request.lazy_upvotes_count
+ end
+ end
+ end
+end
diff --git a/app/models/preloaders/user_max_access_level_in_groups_preloader.rb b/app/models/preloaders/user_max_access_level_in_groups_preloader.rb
new file mode 100644
index 00000000000..14f1d271572
--- /dev/null
+++ b/app/models/preloaders/user_max_access_level_in_groups_preloader.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module Preloaders
+ # This class preloads the max access level (role) for the user within the given groups and
+ # stores the values in requests store.
+ # Will only be able to preload max access level for groups where the user is a direct member
+ class UserMaxAccessLevelInGroupsPreloader
+ include BulkMemberAccessLoad
+
+ def initialize(groups, user)
+ @groups = groups
+ @user = user
+ end
+
+ def execute
+ group_memberships = GroupMember.active_without_invites_and_requests
+ .non_minimal_access
+ .where(user: @user, source_id: @groups)
+ .group(:source_id)
+ .maximum(:access_level)
+
+ group_memberships.each do |group_id, max_access_level|
+ merge_value_to_request_store(User, @user.id, group_id, max_access_level)
+ end
+ end
+ end
+end
diff --git a/app/models/project.rb b/app/models/project.rb
index 81b04e1316c..74ffeef797e 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -103,6 +103,8 @@ class Project < ApplicationRecord
after_save :create_import_state, if: ->(project) { project.import? && project.import_state.nil? }
+ after_save :save_topics
+
after_create -> { create_or_load_association(:project_feature) }
after_create -> { create_or_load_association(:ci_cd_settings) }
@@ -118,7 +120,6 @@ class Project < ApplicationRecord
use_fast_destroy :build_trace_chunks
- after_destroy -> { run_after_commit { legacy_remove_pages } }
after_destroy :remove_exports
after_validation :check_pending_delete
@@ -127,12 +128,31 @@ class Project < ApplicationRecord
after_initialize :use_hashed_storage
after_create :check_repository_absence!
+ # Required during the `ActsAsTaggableOn::Tag -> Topic` migration
+ # TODO: remove 'acts_as_ordered_taggable_on' and ':topics_acts_as_taggable' in the further process of the migration
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/335946
acts_as_ordered_taggable_on :topics
+ has_many :topics_acts_as_taggable, -> { order("#{ActsAsTaggableOn::Tagging.table_name}.id") },
+ class_name: 'ActsAsTaggableOn::Tag',
+ through: :topic_taggings,
+ source: :tag
+
+ has_many :project_topics, -> { order(:id) }, class_name: 'Projects::ProjectTopic'
+ has_many :topics, through: :project_topics, class_name: 'Projects::Topic'
+
+ # Required during the `ActsAsTaggableOn::Tag -> Topic` migration
+ # TODO: remove 'topics' in the further process of the migration
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/335946
+ alias_method :topics_new, :topics
+ def topics
+ self.topics_acts_as_taggable + self.topics_new
+ end
attr_accessor :old_path_with_namespace
attr_accessor :template_name
attr_writer :pipeline_status
attr_accessor :skip_disk_validation
+ attr_writer :topic_list
alias_attribute :title, :name
@@ -141,6 +161,9 @@ class Project < ApplicationRecord
belongs_to :creator, class_name: 'User'
belongs_to :group, -> { where(type: 'Group') }, foreign_key: 'namespace_id'
belongs_to :namespace
+ # Sync deletion via DB Trigger to ensure we do not have
+ # a project without a project_namespace (or vice-versa)
+ belongs_to :project_namespace, class_name: 'Namespaces::ProjectNamespace', foreign_key: 'project_namespace_id', inverse_of: :project
alias_method :parent, :namespace
alias_attribute :parent_id, :namespace_id
@@ -188,6 +211,7 @@ class Project < ApplicationRecord
has_one :unify_circuit_integration, class_name: 'Integrations::UnifyCircuit'
has_one :webex_teams_integration, class_name: 'Integrations::WebexTeams'
has_one :youtrack_integration, class_name: 'Integrations::Youtrack'
+ has_one :zentao_integration, class_name: 'Integrations::Zentao'
has_one :root_of_fork_network,
foreign_key: 'root_project_id',
@@ -317,6 +341,7 @@ class Project < ApplicationRecord
# build traces. Currently there's no efficient way of removing this data in
# bulk that doesn't involve loading the rows into memory. As a result we're
# still using `dependent: :destroy` here.
+ has_many :pending_builds, class_name: 'Ci::PendingBuild'
has_many :builds, class_name: 'Ci::Build', inverse_of: :project, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
has_many :processables, class_name: 'Ci::Processable', inverse_of: :project
has_many :build_trace_chunks, class_name: 'Ci::BuildTraceChunk', through: :builds, source: :trace_chunks
@@ -355,6 +380,7 @@ class Project < ApplicationRecord
has_many :jira_imports, -> { order 'jira_imports.created_at' }, class_name: 'JiraImportState', inverse_of: :project
has_many :daily_build_group_report_results, class_name: 'Ci::DailyBuildGroupReportResult'
+ has_many :ci_feature_usages, class_name: 'Projects::CiFeatureUsage'
has_many :repository_storage_moves, class_name: 'Projects::RepositoryStorageMove', inverse_of: :container
@@ -503,6 +529,7 @@ class Project < ApplicationRecord
scope :sorted_by_stars_desc, -> { reorder(self.arel_table['star_count'].desc) }
scope :sorted_by_stars_asc, -> { reorder(self.arel_table['star_count'].asc) }
# Sometimes queries (e.g. using CTEs) require explicit disambiguation with table name
+ scope :projects_order_id_asc, -> { reorder(self.arel_table['id'].asc) }
scope :projects_order_id_desc, -> { reorder(self.arel_table['id'].desc) }
scope :sorted_by_similarity_desc, -> (search, include_in_select: false) do
@@ -623,6 +650,19 @@ class Project < ApplicationRecord
joins(:service_desk_setting).where('service_desk_settings.project_key' => key)
end
+ scope :with_topic, ->(topic_name) do
+ topic = Projects::Topic.find_by_name(topic_name)
+ acts_as_taggable_on_topic = ActsAsTaggableOn::Tag.find_by_name(topic_name)
+
+ return none unless topic || acts_as_taggable_on_topic
+
+ relations = []
+ relations << where(id: topic.project_topics.select(:project_id)) if topic
+ relations << where(id: acts_as_taggable_on_topic.taggings.select(:taggable_id)) if acts_as_taggable_on_topic
+
+ Project.from_union(relations)
+ end
+
enum auto_cancel_pending_pipelines: { disabled: 0, enabled: 1 }
chronic_duration_attr :build_timeout_human_readable, :build_timeout,
@@ -638,7 +678,7 @@ class Project < ApplicationRecord
mount_uploader :bfg_object_map, AttachmentUploader
def self.with_api_entity_associations
- preload(:project_feature, :route, :topics, :group, :timelogs, namespace: [:route, :owner])
+ preload(:project_feature, :route, :topics, :topics_acts_as_taggable, :group, :timelogs, namespace: [:route, :owner])
end
def self.with_web_entity_associations
@@ -1421,7 +1461,7 @@ class Project < ApplicationRecord
end
def disabled_integrations
- []
+ [:zentao]
end
def find_or_initialize_integration(name)
@@ -1640,6 +1680,10 @@ class Project < ApplicationRecord
end
end
+ def membership_locked?
+ false
+ end
+
def bots
users.project_bot
end
@@ -1747,6 +1791,9 @@ class Project < ApplicationRecord
Ci::Runner.from_union([runners, group_runners, available_shared_runners])
end
+ # Once issue 339937 is fixed, please search for all mentioned of
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/339937,
+ # and remove the allow_cross_joins_across_databases.
def active_runners
strong_memoize(:active_runners) do
all_available_runners.active
@@ -1754,7 +1801,9 @@ class Project < ApplicationRecord
end
def any_online_runners?(&block)
- online_runners_with_tags.any?(&block)
+ ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/339937') do
+ online_runners_with_tags.any?(&block)
+ end
end
def valid_runners_token?(token)
@@ -1763,7 +1812,15 @@ class Project < ApplicationRecord
# rubocop: disable CodeReuse/ServiceClass
def open_issues_count(current_user = nil)
- Projects::OpenIssuesCountService.new(self, current_user).count
+ return Projects::OpenIssuesCountService.new(self, current_user).count unless current_user.nil?
+
+ BatchLoader.for(self).batch(replace_methods: false) do |projects, loader|
+ issues_count_per_project = ::Projects::BatchOpenIssuesCountService.new(projects).refresh_cache_and_retrieve_data
+
+ issues_count_per_project.each do |project, count|
+ loader.call(project, count)
+ end
+ end
end
# rubocop: enable CodeReuse/ServiceClass
@@ -1849,27 +1906,6 @@ class Project < ApplicationRecord
.delete_all
end
- # TODO: remove this method https://gitlab.com/gitlab-org/gitlab/-/issues/320775
- # rubocop: disable CodeReuse/ServiceClass
- def legacy_remove_pages
- return unless ::Settings.pages.local_store.enabled
-
- # Projects with a missing namespace cannot have their pages removed
- return unless namespace
-
- mark_pages_as_not_deployed unless destroyed?
-
- # 1. We rename pages to temporary directory
- # 2. We wait 5 minutes, due to NFS caching
- # 3. We asynchronously remove pages with force
- temp_path = "#{path}.#{SecureRandom.hex}.deleted"
-
- if Gitlab::PagesTransfer.new.rename_project(path, temp_path, namespace.full_path)
- PagesWorker.perform_in(5.minutes, :remove, namespace.full_path, temp_path)
- end
- end
- # rubocop: enable CodeReuse/ServiceClass
-
def mark_pages_as_deployed(artifacts_archive: nil)
ensure_pages_metadatum.update!(deployed: true, artifacts_archive: artifacts_archive)
end
@@ -2093,6 +2129,10 @@ class Project < ApplicationRecord
# Docker doesn't allow. The proxy expects it to be downcased.
value: "#{Gitlab.host_with_port}/#{namespace.root_ancestor.path.downcase}#{DependencyProxy::URL_SUFFIX}"
)
+ variables.append(
+ key: 'CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX',
+ value: "#{Gitlab.host_with_port}/#{namespace.full_path.downcase}#{DependencyProxy::URL_SUFFIX}"
+ )
end
end
@@ -2239,7 +2279,7 @@ class Project < ApplicationRecord
# rubocop: disable CodeReuse/ServiceClass
def forks_count
- BatchLoader.for(self).batch do |projects, loader|
+ BatchLoader.for(self).batch(replace_methods: false) do |projects, loader|
fork_count_per_project = ::Projects::BatchForksCountService.new(projects).refresh_cache_and_retrieve_data
fork_count_per_project.each do |project, count|
@@ -2491,6 +2531,10 @@ class Project < ApplicationRecord
ci_config_path.blank? || ci_config_path == Gitlab::FileDetector::PATTERNS[:gitlab_ci]
end
+ def uses_external_project_ci_config?
+ !!(ci_config_path =~ %r{@.+/.+})
+ end
+
def limited_protected_branches(limit)
protected_branches.limit(limit)
end
@@ -2599,6 +2643,10 @@ class Project < ApplicationRecord
repository.gitlab_ci_yml_for(sha, ci_config_path_or_default)
end
+ def ci_config_external_project
+ Project.find_by_full_path(ci_config_path.split('@', 2).last)
+ end
+
def enabled_group_deploy_keys
return GroupDeployKey.none unless group
@@ -2669,8 +2717,37 @@ class Project < ApplicationRecord
ci_cd_settings.group_runners_enabled?
end
+ def topic_list
+ self.topics.map(&:name)
+ end
+
+ override :after_change_head_branch_does_not_exist
+ def after_change_head_branch_does_not_exist(branch)
+ self.errors.add(:base, _("Could not change HEAD: branch '%{branch}' does not exist") % { branch: branch })
+ end
+
private
+ def save_topics
+ return if @topic_list.nil?
+
+ @topic_list = @topic_list.split(',') if @topic_list.instance_of?(String)
+ @topic_list = @topic_list.map(&:strip).uniq.reject(&:empty?)
+
+ if @topic_list != self.topic_list || self.topics_acts_as_taggable.any?
+ self.topics_new.delete_all
+ self.topics = @topic_list.map { |topic| Projects::Topic.find_or_create_by(name: topic) }
+
+ # Remove old topics (ActsAsTaggableOn::Tag)
+ # Required during the `ActsAsTaggableOn::Tag -> Topic` migration
+ # TODO: remove in the further process of the migration
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/335946
+ self.topic_taggings.clear
+ end
+
+ @topic_list = nil
+ end
+
def find_integration(integrations, name)
integrations.find { _1.to_param == name }
end
@@ -2832,12 +2909,8 @@ class Project < ApplicationRecord
update_column(:has_external_issue_tracker, integrations.external_issue_trackers.any?) if Gitlab::Database.read_write?
end
- def active_runners_with_tags
- @active_runners_with_tags ||= active_runners.with_tags
- end
-
def online_runners_with_tags
- @online_runners_with_tags ||= active_runners_with_tags.online
+ @online_runners_with_tags ||= active_runners.with_tags.online
end
end
diff --git a/app/models/project_feature.rb b/app/models/project_feature.rb
index aea8abecd74..676c28d5e1b 100644
--- a/app/models/project_feature.rb
+++ b/app/models/project_feature.rb
@@ -54,7 +54,6 @@ class ProjectFeature < ApplicationRecord
validates :project, presence: true
validate :repository_children_level
- validate :allowed_access_levels
default_value_for :builds_access_level, value: ENABLED, allows_nil: false
default_value_for :issues_access_level, value: ENABLED, allows_nil: false
@@ -110,17 +109,6 @@ class ProjectFeature < ApplicationRecord
%i(merge_requests_access_level builds_access_level).each(&validator)
end
- # Validates access level for other than pages cannot be PUBLIC
- def allowed_access_levels
- validator = lambda do |field|
- level = public_send(field) || ENABLED # rubocop:disable GitlabSecurity/PublicSend
- not_allowed = level > ENABLED
- self.errors.add(field, "cannot have public visibility level") if not_allowed
- end
-
- (FEATURES - %i(pages)).each {|f| validator.call("#{f}_access_level")}
- end
-
def get_permission(user, feature)
case access_level(feature)
when DISABLED
@@ -142,6 +130,10 @@ class ProjectFeature < ApplicationRecord
project.team.member?(user, ProjectFeature.required_minimum_access_level(feature))
end
+
+ def feature_validation_exclusion
+ %i(pages)
+ end
end
ProjectFeature.prepend_mod_with('ProjectFeature')
diff --git a/app/models/project_team.rb b/app/models/project_team.rb
index 4ae3bc01a01..774d81156b7 100644
--- a/app/models/project_team.rb
+++ b/app/models/project_team.rb
@@ -42,7 +42,7 @@ class ProjectTeam
end
def add_users(users, access_level, current_user: nil, expires_at: nil)
- Members::Projects::CreatorService.add_users( # rubocop:disable CodeReuse/ServiceClass
+ Members::Projects::BulkCreatorService.add_users( # rubocop:disable CodeReuse/ServiceClass
project,
users,
access_level,
diff --git a/app/models/projects/project_topic.rb b/app/models/projects/project_topic.rb
new file mode 100644
index 00000000000..d4b456ef482
--- /dev/null
+++ b/app/models/projects/project_topic.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+module Projects
+ class ProjectTopic < ApplicationRecord
+ belongs_to :project
+ belongs_to :topic
+ end
+end
diff --git a/app/models/projects/topic.rb b/app/models/projects/topic.rb
new file mode 100644
index 00000000000..a17aa550edb
--- /dev/null
+++ b/app/models/projects/topic.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+module Projects
+ class Topic < ApplicationRecord
+ validates :name, presence: true, uniqueness: true, length: { maximum: 255 }
+
+ has_many :project_topics, class_name: 'Projects::ProjectTopic'
+ has_many :projects, through: :project_topics
+ end
+end
diff --git a/app/models/protected_branch.rb b/app/models/protected_branch.rb
index 3df8fe31826..3d32144e0f8 100644
--- a/app/models/protected_branch.rb
+++ b/app/models/protected_branch.rb
@@ -26,7 +26,9 @@ class ProtectedBranch < ApplicationRecord
def self.protected?(project, ref_name)
return true if project.empty_repo? && project.default_branch_protected?
- self.matching(ref_name, protected_refs: protected_refs(project)).present?
+ Rails.cache.fetch("protected_ref-#{ref_name}-#{project.cache_key}") do
+ self.matching(ref_name, protected_refs: protected_refs(project)).present?
+ end
end
def self.allow_force_push?(project, ref_name)
diff --git a/app/models/push_event_payload.rb b/app/models/push_event_payload.rb
index 8358be35470..441b94e1855 100644
--- a/app/models/push_event_payload.rb
+++ b/app/models/push_event_payload.rb
@@ -2,6 +2,9 @@
class PushEventPayload < ApplicationRecord
extend SuppressCompositePrimaryKeyWarning
+ include IgnorableColumns
+
+ ignore_columns :event_id_convert_to_bigint, remove_with: '14.4', remove_after: '2021-10-22'
include ShaAttribute
diff --git a/app/models/release.rb b/app/models/release.rb
index aad1cbeabdb..0dd71c6ebfb 100644
--- a/app/models/release.rb
+++ b/app/models/release.rb
@@ -33,7 +33,6 @@ class Release < ApplicationRecord
includes(:author, :evidences, :milestones, :links, :sorted_links,
project: [:project_feature, :route, { namespace: :route }])
}
- scope :with_project_and_namespace, -> { includes(project: :namespace) }
scope :recent, -> { sorted.limit(MAX_NUMBER_TO_DISPLAY) }
scope :without_evidence, -> { left_joins(:evidences).where(::Releases::Evidence.arel_table[:id].eq(nil)) }
scope :released_within_2hrs, -> { where(released_at: Time.zone.now - 1.hour..Time.zone.now + 1.hour) }
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 0164d6fed93..f20b306c806 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -161,8 +161,8 @@ class Repository
CommitCollection.new(container, commits, ref)
end
- def commits_between(from, to)
- commits = Gitlab::Git::Commit.between(raw_repository, from, to)
+ def commits_between(from, to, limit: nil)
+ commits = Gitlab::Git::Commit.between(raw_repository, from, to, limit: limit)
commits = Commit.decorate(commits, container) if commits.present?
commits
end
@@ -191,7 +191,11 @@ class Repository
end
def find_tag(name)
- tags.find { |tag| tag.name == name }
+ if @tags.blank? && Feature.enabled?(:find_tag_via_gitaly, project, default_enabled: :yaml)
+ raw_repository.find_tag(name)
+ else
+ tags.find { |tag| tag.name == name }
+ end
end
def ambiguous_ref?(ref)
@@ -627,7 +631,14 @@ class Repository
def license
return unless license_key
- Licensee::License.new(license_key)
+ licensee_object = Licensee::License.new(license_key)
+
+ return if licensee_object.name.blank?
+
+ licensee_object
+ rescue Licensee::InvalidLicense => ex
+ Gitlab::ErrorTracking.track_exception(ex)
+ nil
end
memoize_method :license
@@ -721,18 +732,9 @@ class Repository
end
def tags_sorted_by(value)
- case value
- when 'name_asc'
- VersionSorter.sort(tags) { |tag| tag.name }
- when 'name_desc'
- VersionSorter.rsort(tags) { |tag| tag.name }
- when 'updated_desc'
- tags_sorted_by_committed_date.reverse
- when 'updated_asc'
- tags_sorted_by_committed_date
- else
- tags
- end
+ return raw_repository.tags(sort_by: value) if Feature.enabled?(:gitaly_tags_finder, project, default_enabled: :yaml)
+
+ tags_ruby_sort(value)
end
# Params:
@@ -1125,11 +1127,16 @@ class Repository
copy_gitattributes(branch)
after_change_head
else
- container.errors.add(:base, _("Could not change HEAD: branch '%{branch}' does not exist") % { branch: branch })
+ container.after_change_head_branch_does_not_exist(branch)
+
false
end
end
+ def cache
+ @cache ||= Gitlab::RepositoryCache.new(self)
+ end
+
private
# TODO Genericize finder, later split this on finders by Ref or Oid
@@ -1144,10 +1151,6 @@ class Repository
::Commit.new(commit, container) if commit
end
- def cache
- @cache ||= Gitlab::RepositoryCache.new(self)
- end
-
def redis_set_cache
@redis_set_cache ||= Gitlab::RepositorySetCache.new(self)
end
@@ -1160,6 +1163,23 @@ class Repository
@request_store_cache ||= Gitlab::RepositoryCache.new(self, backend: Gitlab::SafeRequestStore)
end
+ # Deprecated: https://gitlab.com/gitlab-org/gitlab/-/issues/339741
+ def tags_ruby_sort(value)
+ case value
+ when 'name_asc'
+ VersionSorter.sort(tags) { |tag| tag.name }
+ when 'name_desc'
+ VersionSorter.rsort(tags) { |tag| tag.name }
+ when 'updated_desc'
+ tags_sorted_by_committed_date.reverse
+ when 'updated_asc'
+ tags_sorted_by_committed_date
+ else
+ tags
+ end
+ end
+
+ # Deprecated: https://gitlab.com/gitlab-org/gitlab/-/issues/339741
def tags_sorted_by_committed_date
# Annotated tags can point to any object (e.g. a blob), but generally
# tags point to a commit. If we don't have a commit, then just default
diff --git a/app/models/service_desk_setting.rb b/app/models/service_desk_setting.rb
index 1c854cc9941..6dd7415d928 100644
--- a/app/models/service_desk_setting.rb
+++ b/app/models/service_desk_setting.rb
@@ -19,7 +19,11 @@ class ServiceDeskSetting < ApplicationRecord
strong_memoize(:issue_template_content) do
next unless issue_template_key.present?
- Gitlab::Template::IssueTemplate.find(issue_template_key, project).content
+ TemplateFinder.new(
+ :issues, project,
+ name: issue_template_key,
+ source_template_project: source_template_project
+ ).execute.content
rescue ::Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError
end
end
@@ -42,6 +46,10 @@ class ServiceDeskSetting < ApplicationRecord
private
+ def source_template_project
+ nil
+ end
+
def projects_with_same_slug_and_key_exists?
return false unless project_key
@@ -53,3 +61,5 @@ class ServiceDeskSetting < ApplicationRecord
end
end
end
+
+ServiceDeskSetting.prepend_mod
diff --git a/app/models/shard.rb b/app/models/shard.rb
index 335a279c6aa..9f0039d8bf9 100644
--- a/app/models/shard.rb
+++ b/app/models/shard.rb
@@ -18,10 +18,6 @@ class Shard < ApplicationRecord
end
def self.by_name(name)
- transaction(requires_new: true) do
- find_or_create_by(name: name)
- end
- rescue ActiveRecord::RecordNotUnique
- retry
+ safe_find_or_create_by(name: name)
end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index cb0f15c04cb..b5f0251f639 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -39,6 +39,12 @@ class User < ApplicationRecord
MAX_USERNAME_LENGTH = 255
MIN_USERNAME_LENGTH = 2
+ SECONDARY_EMAIL_ATTRIBUTES = [
+ :commit_email,
+ :notification_email,
+ :public_email
+ ].freeze
+
add_authentication_token_field :incoming_email_token, token_generator: -> { SecureRandom.hex.to_i(16).to_s(36) }
add_authentication_token_field :feed_token
add_authentication_token_field :static_object_token
@@ -181,7 +187,7 @@ class User < ApplicationRecord
has_many :todos
has_many :notification_settings
has_many :award_emoji, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
- has_many :triggers, dependent: :destroy, class_name: 'Ci::Trigger', foreign_key: :owner_id # rubocop:disable Cop/ActiveRecordDependent
+ has_many :triggers, class_name: 'Ci::Trigger', foreign_key: :owner_id
has_many :issue_assignees, inverse_of: :assignee
has_many :merge_request_assignees, inverse_of: :assignee
@@ -194,6 +200,7 @@ class User < ApplicationRecord
has_many :custom_attributes, class_name: 'UserCustomAttribute'
has_many :callouts, class_name: 'UserCallout'
+ has_many :group_callouts, class_name: 'Users::GroupCallout'
has_many :term_agreements
belongs_to :accepted_term, class_name: 'ApplicationSetting::Term'
@@ -222,10 +229,9 @@ class User < ApplicationRecord
validates :first_name, length: { maximum: 127 }
validates :last_name, length: { maximum: 127 }
validates :email, confirmation: true
- validates :notification_email, presence: true
- validates :notification_email, devise_email: true, if: ->(user) { user.notification_email != user.email }
+ validates :notification_email, devise_email: true, allow_blank: true, if: ->(user) { user.notification_email != user.email }
validates :public_email, uniqueness: true, devise_email: true, allow_blank: true
- validates :commit_email, devise_email: true, allow_nil: true, if: ->(user) { user.commit_email != user.email }
+ validates :commit_email, devise_email: true, allow_blank: true, if: ->(user) { user.commit_email != user.email && user.commit_email != Gitlab::PrivateCommitEmail::TOKEN }
validates :projects_limit,
presence: true,
numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: Gitlab::Database::MAX_INT_VALUE }
@@ -247,12 +253,10 @@ class User < ApplicationRecord
validates :color_scheme_id, allow_nil: true, inclusion: { in: Gitlab::ColorSchemes.valid_ids,
message: _("%{placeholder} is not a valid color scheme") % { placeholder: '%{value}' } }
+ validates :website_url, allow_blank: true, url: true, if: :website_url_changed?
+
before_validation :sanitize_attrs
- before_validation :set_public_email, if: :public_email_changed?
- before_validation :set_commit_email, if: :commit_email_changed?
before_save :default_private_profile_to_false
- before_save :set_public_email, if: :public_email_changed? # in case validation is skipped
- before_save :set_commit_email, if: :commit_email_changed? # in case validation is skipped
before_save :ensure_incoming_email_token
before_save :ensure_user_rights_and_limits, if: ->(user) { user.new_record? || user.external_changed? }
before_save :skip_reconfirmation!, if: ->(user) { user.email_changed? && user.read_only_attribute?(:email) }
@@ -302,14 +306,13 @@ class User < ApplicationRecord
:gitpod_enabled, :gitpod_enabled=,
:setup_for_company, :setup_for_company=,
:render_whitespace_in_code, :render_whitespace_in_code=,
- :experience_level, :experience_level=,
:markdown_surround_selection, :markdown_surround_selection=,
to: :user_preference
delegate :path, to: :namespace, allow_nil: true, prefix: true
delegate :job_title, :job_title=, to: :user_detail, allow_nil: true
delegate :other_role, :other_role=, to: :user_detail, allow_nil: true
- delegate :bio, :bio=, :bio_html, to: :user_detail, allow_nil: true
+ delegate :bio, :bio=, to: :user_detail, allow_nil: true
delegate :webauthn_xid, :webauthn_xid=, to: :user_detail, allow_nil: true
delegate :pronouns, :pronouns=, to: :user_detail, allow_nil: true
delegate :pronunciation, :pronunciation=, to: :user_detail, allow_nil: true
@@ -347,6 +350,10 @@ class User < ApplicationRecord
transition active: :banned
end
+ event :unban do
+ transition banned: :active
+ end
+
event :deactivate do
# Any additional changes to this event should be also
# reflected in app/workers/users/deactivate_dormant_users_worker.rb
@@ -374,7 +381,9 @@ class User < ApplicationRecord
end
after_transition any => :deactivated do |user|
- NotificationService.new.user_deactivated(user.name, user.notification_email)
+ next unless Gitlab::CurrentSettings.user_deactivation_emails_enabled
+
+ NotificationService.new.user_deactivated(user.name, user.notification_email_or_default)
end
# rubocop: enable CodeReuse/ServiceClass
@@ -922,51 +931,18 @@ class User < ApplicationRecord
end
end
- def notification_email_verified
- return if read_attribute(:notification_email).blank? || temp_oauth_email?
-
- errors.add(:notification_email, _("must be an email you have verified")) unless verified_emails.include?(notification_email)
- end
-
- def public_email_verified
- return if public_email.blank?
-
- errors.add(:public_email, _("must be an email you have verified")) unless verified_emails.include?(public_email)
- end
-
- def commit_email_verified
- return if read_attribute(:commit_email).blank?
-
- errors.add(:commit_email, _("must be an email you have verified")) unless verified_emails.include?(commit_email)
- end
-
- # Define commit_email-related attribute methods explicitly instead of relying
- # on ActiveRecord to provide them. Some of the specs use the current state of
- # the model code but an older database schema, so we need to guard against the
- # possibility of the commit_email column not existing.
-
- def commit_email
- return self.email unless has_attribute?(:commit_email)
-
- if super == Gitlab::PrivateCommitEmail::TOKEN
+ def commit_email_or_default
+ if self.commit_email == Gitlab::PrivateCommitEmail::TOKEN
return private_commit_email
end
# The commit email is the same as the primary email if undefined
- super.presence || self.email
+ self.commit_email.presence || self.email
end
- def commit_email=(email)
- super if has_attribute?(:commit_email)
- end
-
- def commit_email_changed?
- has_attribute?(:commit_email) && super
- end
-
- def notification_email
+ def notification_email_or_default
# The notification email is the same as the primary email if undefined
- super.presence || self.email
+ self.notification_email.presence || self.email
end
def private_commit_email
@@ -1009,7 +985,11 @@ class User < ApplicationRecord
# Returns the groups a user is a member of, either directly or through a parent group
def membership_groups
- Gitlab::ObjectHierarchy.new(groups).base_and_descendants
+ if Feature.enabled?(:linear_user_membership_groups, self, default_enabled: :yaml)
+ groups.self_and_descendants
+ else
+ Gitlab::ObjectHierarchy.new(groups).base_and_descendants
+ end
end
# Returns a relation of groups the user has access to, including their parent
@@ -1292,29 +1272,15 @@ class User < ApplicationRecord
self.name = self.name.gsub(%r{</?[^>]*>}, '')
end
- def set_notification_email
- if notification_email.blank? || all_emails.exclude?(notification_email)
- self.notification_email = email
- end
- end
-
- def set_public_email
- if public_email.blank? || all_emails.exclude?(public_email)
- self.public_email = ''
- end
- end
-
- def set_commit_email
- if commit_email.blank? || verified_emails.exclude?(commit_email)
- self.commit_email = nil
+ def unset_secondary_emails_matching_deleted_email!(deleted_email)
+ secondary_email_attribute_changed = false
+ SECONDARY_EMAIL_ATTRIBUTES.each do |attribute|
+ if read_attribute(attribute) == deleted_email
+ self.write_attribute(attribute, nil)
+ secondary_email_attribute_changed = true
+ end
end
- end
-
- def update_secondary_emails!
- set_notification_email
- set_public_email
- set_commit_email
- save if notification_email_changed? || public_email_changed? || commit_email_changed?
+ save if secondary_email_attribute_changed
end
def admin_unsubscribe!
@@ -1569,7 +1535,11 @@ class User < ApplicationRecord
end
def manageable_groups(include_groups_with_developer_maintainer_access: false)
- owned_and_maintainer_group_hierarchy = Gitlab::ObjectHierarchy.new(owned_or_maintainers_groups).base_and_descendants
+ owned_and_maintainer_group_hierarchy = if Feature.enabled?(:linear_user_manageable_groups, self, default_enabled: :yaml)
+ owned_or_maintainers_groups.self_and_descendants
+ else
+ Gitlab::ObjectHierarchy.new(owned_or_maintainers_groups).base_and_descendants
+ end
if include_groups_with_developer_maintainer_access
union_sql = ::Gitlab::SQL::Union.new(
@@ -1628,6 +1598,8 @@ class User < ApplicationRecord
true
end
+ # TODO Please check all callers and remove allow_cross_joins_across_databases,
+ # when https://gitlab.com/gitlab-org/gitlab/-/issues/336436 is done.
def ci_owned_runners
@ci_owned_runners ||= begin
project_runners = Ci::RunnerProject
@@ -1644,9 +1616,15 @@ class User < ApplicationRecord
end
end
+ def owns_runner?(runner)
+ ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336436') do
+ ci_owned_runners.exists?(runner.id)
+ end
+ end
+
def notification_email_for(notification_group)
# Return group-specific email address if present, otherwise return global notification email address
- notification_group&.notification_email_for(self) || notification_email
+ notification_group&.notification_email_for(self) || notification_email_or_default
end
def notification_settings_for(source, inherit: false)
@@ -1935,10 +1913,14 @@ class User < ApplicationRecord
def dismissed_callout?(feature_name:, ignore_dismissal_earlier_than: nil)
callout = callouts_by_feature_name[feature_name]
- return false unless callout
- return callout.dismissed_after?(ignore_dismissal_earlier_than) if ignore_dismissal_earlier_than
+ callout_dismissed?(callout, ignore_dismissal_earlier_than)
+ end
- true
+ def dismissed_callout_for_group?(feature_name:, group:, ignore_dismissal_earlier_than: nil)
+ source_feature_name = "#{feature_name}_#{group.id}"
+ callout = group_callouts_by_feature_name[source_feature_name]
+
+ callout_dismissed?(callout, ignore_dismissal_earlier_than)
end
# Load the current highest access by looking directly at the user's memberships
@@ -1962,6 +1944,11 @@ class User < ApplicationRecord
callouts.find_or_initialize_by(feature_name: ::UserCallout.feature_names[feature_name])
end
+ def find_or_initialize_group_callout(feature_name, group_id)
+ group_callouts
+ .find_or_initialize_by(feature_name: ::Users::GroupCallout.feature_names[feature_name], group_id: group_id)
+ end
+
def can_trigger_notifications?
confirmed? && !blocked? && !ghost?
end
@@ -2015,10 +2002,39 @@ class User < ApplicationRecord
private
+ def notification_email_verified
+ return if notification_email.blank? || temp_oauth_email?
+
+ errors.add(:notification_email, _("must be an email you have verified")) unless verified_emails.include?(notification_email_or_default)
+ end
+
+ def public_email_verified
+ return if public_email.blank?
+
+ errors.add(:public_email, _("must be an email you have verified")) unless verified_emails.include?(public_email)
+ end
+
+ def commit_email_verified
+ return if commit_email.blank?
+
+ errors.add(:commit_email, _("must be an email you have verified")) unless verified_emails.include?(commit_email_or_default)
+ end
+
+ def callout_dismissed?(callout, ignore_dismissal_earlier_than)
+ return false unless callout
+ return callout.dismissed_after?(ignore_dismissal_earlier_than) if ignore_dismissal_earlier_than
+
+ true
+ end
+
def callouts_by_feature_name
@callouts_by_feature_name ||= callouts.index_by(&:feature_name)
end
+ def group_callouts_by_feature_name
+ @group_callouts_by_feature_name ||= group_callouts.index_by(&:source_feature_name)
+ end
+
def authorized_groups_without_shared_membership
Group.from_union([
groups.select(Namespace.arel_table[Arel.star]),
@@ -2080,7 +2096,7 @@ class User < ApplicationRecord
def check_username_format
return if username.blank? || Mime::EXTENSION_LOOKUP.keys.none? { |type| username.end_with?(".#{type}") }
- errors.add(:username, _('ending with MIME type format is not allowed.'))
+ errors.add(:username, _('ending with a file extension is not allowed.'))
end
def groups_with_developer_maintainer_project_access
@@ -2090,9 +2106,12 @@ class User < ApplicationRecord
project_creation_levels << nil
end
- developer_groups_hierarchy = ::Gitlab::ObjectHierarchy.new(developer_groups).base_and_descendants
- ::Group.where(id: developer_groups_hierarchy.select(:id),
- project_creation_level: project_creation_levels)
+ if Feature.enabled?(:linear_user_groups_with_developer_maintainer_project_access, self, default_enabled: :yaml)
+ developer_groups.self_and_descendants.where(project_creation_level: project_creation_levels)
+ else
+ developer_groups_hierarchy = ::Gitlab::ObjectHierarchy.new(developer_groups).base_and_descendants
+ ::Group.where(id: developer_groups_hierarchy.select(:id), project_creation_level: project_creation_levels)
+ end
end
def no_recent_activity?
diff --git a/app/models/user_callout.rb b/app/models/user_callout.rb
index 1172b2ee5e8..04bc29755f8 100644
--- a/app/models/user_callout.rb
+++ b/app/models/user_callout.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
class UserCallout < ApplicationRecord
- belongs_to :user
+ include Calloutable
enum feature_name: {
gke_cluster_integration: 1,
@@ -15,7 +15,7 @@ class UserCallout < ApplicationRecord
suggest_popover_dismissed: 9,
tabs_position_highlight: 10,
threat_monitoring_info: 11, # EE-only
- account_recovery_regular_check: 12, # EE-only
+ two_factor_auth_recovery_settings_check: 12, # EE-only
web_ide_alert_dismissed: 16, # no longer in use
active_user_count_threshold: 18, # EE-only
buy_pipeline_minutes_notification_dot: 19, # EE-only
@@ -39,13 +39,8 @@ class UserCallout < ApplicationRecord
terraform_notification_dismissed: 38
}
- validates :user, presence: true
validates :feature_name,
presence: true,
uniqueness: { scope: :user_id },
inclusion: { in: UserCallout.feature_names.keys }
-
- def dismissed_after?(dismissed_after)
- dismissed_at > dismissed_after
- end
end
diff --git a/app/models/user_detail.rb b/app/models/user_detail.rb
index b3cca1e0cc0..c41cff67864 100644
--- a/app/models/user_detail.rb
+++ b/app/models/user_detail.rb
@@ -2,7 +2,8 @@
class UserDetail < ApplicationRecord
extend ::Gitlab::Utils::Override
- include CacheMarkdownField
+ include IgnorableColumns
+ ignore_columns %i[bio_html cached_markdown_version], remove_with: '13.6', remove_after: '2021-10-22'
belongs_to :user
@@ -13,20 +14,6 @@ class UserDetail < ApplicationRecord
before_save :prevent_nil_bio
- cache_markdown_field :bio
-
- def bio_html
- read_attribute(:bio_html) || bio
- end
-
- # For backward compatibility.
- # Older migrations (and their tests) reference the `User.migration_bot` where the `bio` attribute is set.
- # Here we disable writing the markdown cache when the `bio_html` column does not exist.
- override :invalidated_markdown_cache?
- def invalidated_markdown_cache?
- self.class.column_names.include?('bio_html') && super
- end
-
private
def prevent_nil_bio
diff --git a/app/models/user_preference.rb b/app/models/user_preference.rb
index 2735e169b5f..337ae7125f3 100644
--- a/app/models/user_preference.rb
+++ b/app/models/user_preference.rb
@@ -20,7 +20,7 @@ class UserPreference < ApplicationRecord
less_than_or_equal_to: Gitlab::TabWidth::MAX
}
- enum experience_level: { novice: 0, experienced: 1 }
+ ignore_columns :experience_level, remove_with: '14.10', remove_after: '2021-03-22'
default_value_for :tab_width, value: Gitlab::TabWidth::DEFAULT, allows_nil: false
default_value_for :timezone, value: Time.zone.tzinfo.name, allows_nil: false
diff --git a/app/models/users/group_callout.rb b/app/models/users/group_callout.rb
new file mode 100644
index 00000000000..540d1a1d242
--- /dev/null
+++ b/app/models/users/group_callout.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Users
+ class GroupCallout < ApplicationRecord
+ include Calloutable
+
+ self.table_name = 'user_group_callouts'
+
+ belongs_to :group
+
+ enum feature_name: {
+ invite_members_banner: 1
+ }
+
+ validates :group, presence: true
+ validates :feature_name,
+ presence: true,
+ uniqueness: { scope: [:user_id, :group_id] },
+ inclusion: { in: GroupCallout.feature_names.keys }
+
+ def source_feature_name
+ "#{feature_name}_#{group_id}"
+ end
+ end
+end
diff --git a/app/models/work_item/type.rb b/app/models/work_item/type.rb
index 16cb7a8be45..7038beadd62 100644
--- a/app/models/work_item/type.rb
+++ b/app/models/work_item/type.rb
@@ -9,14 +9,18 @@ class WorkItem::Type < ApplicationRecord
include CacheMarkdownField
+ # Base types need to exist on the DB on app startup
+ # This constant is used by the DB seeder
+ BASE_TYPES = {
+ issue: { name: 'Issue', icon_name: 'issue-type-issue', enum_value: 0 },
+ incident: { name: 'Incident', icon_name: 'issue-type-incident', enum_value: 1 },
+ test_case: { name: 'Test Case', icon_name: 'issue-type-test-case', enum_value: 2 }, ## EE-only
+ requirement: { name: 'Requirement', icon_name: 'issue-type-requirements', enum_value: 3 } ## EE-only
+ }.freeze
+
cache_markdown_field :description, pipeline: :single_line
- enum base_type: {
- issue: 0,
- incident: 1,
- test_case: 2, ## EE-only
- requirement: 3 ## EE-only
- }
+ enum base_type: BASE_TYPES.transform_values { |value| value[:enum_value] }
belongs_to :namespace, optional: true
has_many :work_items, class_name: 'Issue', foreign_key: :work_item_type_id, inverse_of: :work_item_type
@@ -30,6 +34,14 @@ class WorkItem::Type < ApplicationRecord
validates :name, length: { maximum: 255 }
validates :icon_name, length: { maximum: 255 }
+ def self.default_by_type(type)
+ find_by(namespace_id: nil, base_type: type)
+ end
+
+ def self.default_issue_type
+ default_by_type(:issue)
+ end
+
private
def strip_whitespace
diff --git a/app/models/zoom_meeting.rb b/app/models/zoom_meeting.rb
index f684f9e6fe0..dd230b46d4b 100644
--- a/app/models/zoom_meeting.rb
+++ b/app/models/zoom_meeting.rb
@@ -10,7 +10,7 @@ class ZoomMeeting < ApplicationRecord
validates :project, presence: true, unless: :importing?
validates :issue, presence: true, unless: :importing?
- validates :url, presence: true, length: { maximum: 255 }, 'gitlab/utils/zoom_url': true
+ validates :url, presence: true, length: { maximum: 255 }, 'gitlab/zoom_url': true
validates :issue, same_project_association: true, unless: :importing?
enum issue_status: {
diff --git a/app/policies/ci/runner_policy.rb b/app/policies/ci/runner_policy.rb
index de76b7b2b5b..43478cf36c2 100644
--- a/app/policies/ci/runner_policy.rb
+++ b/app/policies/ci/runner_policy.rb
@@ -5,9 +5,9 @@ module Ci
with_options scope: :subject, score: 0
condition(:locked, scope: :subject) { @subject.locked? }
- # rubocop: disable CodeReuse/ActiveRecord
- condition(:owned_runner) { @user.ci_owned_runners.exists?(@subject.id) }
- # rubocop: enable CodeReuse/ActiveRecord
+ condition(:owned_runner) do
+ @user.owns_runner?(@subject)
+ end
rule { anonymous }.prevent_all
diff --git a/app/policies/custom_emoji_policy.rb b/app/policies/custom_emoji_policy.rb
index ba73b9a3782..98d1ab737ee 100644
--- a/app/policies/custom_emoji_policy.rb
+++ b/app/policies/custom_emoji_policy.rb
@@ -2,4 +2,14 @@
class CustomEmojiPolicy < BasePolicy
delegate { @subject.group }
+
+ condition(:author) { @subject.creator == @user }
+
+ rule { can?(:maintainer_access) }.policy do
+ enable :delete_custom_emoji
+ end
+
+ rule { author & can?(:create_custom_emoji) }.policy do
+ enable :delete_custom_emoji
+ end
end
diff --git a/app/policies/customer_relations/contact_policy.rb b/app/policies/customer_relations/contact_policy.rb
new file mode 100644
index 00000000000..8367649b50c
--- /dev/null
+++ b/app/policies/customer_relations/contact_policy.rb
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+module CustomerRelations
+ class ContactPolicy < BasePolicy
+ delegate { @subject.group }
+ end
+end
diff --git a/app/policies/customer_relations/organization_policy.rb b/app/policies/customer_relations/organization_policy.rb
new file mode 100644
index 00000000000..7bf8d6ff4cb
--- /dev/null
+++ b/app/policies/customer_relations/organization_policy.rb
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+module CustomerRelations
+ class OrganizationPolicy < BasePolicy
+ delegate { @subject.group }
+ end
+end
diff --git a/app/policies/dependency_proxy/blob_policy.rb b/app/policies/dependency_proxy/blob_policy.rb
new file mode 100644
index 00000000000..42e023952d0
--- /dev/null
+++ b/app/policies/dependency_proxy/blob_policy.rb
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+module DependencyProxy
+ class BlobPolicy < BasePolicy
+ delegate { @subject.group }
+ end
+end
diff --git a/app/policies/dependency_proxy/group_setting_policy.rb b/app/policies/dependency_proxy/group_setting_policy.rb
new file mode 100644
index 00000000000..71de3cf93bd
--- /dev/null
+++ b/app/policies/dependency_proxy/group_setting_policy.rb
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+module DependencyProxy
+ class GroupSettingPolicy < BasePolicy
+ delegate { @subject.group }
+ end
+end
diff --git a/app/policies/dependency_proxy/image_ttl_group_policy_policy.rb b/app/policies/dependency_proxy/image_ttl_group_policy_policy.rb
new file mode 100644
index 00000000000..cf7e1ded137
--- /dev/null
+++ b/app/policies/dependency_proxy/image_ttl_group_policy_policy.rb
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+module DependencyProxy
+ class ImageTtlGroupPolicyPolicy < BasePolicy
+ delegate { @subject.group }
+ end
+end
diff --git a/app/policies/dependency_proxy/manifest_policy.rb b/app/policies/dependency_proxy/manifest_policy.rb
new file mode 100644
index 00000000000..f2e91e45327
--- /dev/null
+++ b/app/policies/dependency_proxy/manifest_policy.rb
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+module DependencyProxy
+ class ManifestPolicy < BasePolicy
+ delegate { @subject.group }
+ end
+end
diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb
index 1d0aa54c1c0..7abffd2c352 100644
--- a/app/policies/group_policy.rb
+++ b/app/policies/group_policy.rb
@@ -89,6 +89,7 @@ class GroupPolicy < BasePolicy
rule { guest }.policy do
enable :read_group
enable :upload_file
+ enable :guest_access
end
rule { admin }.policy do
@@ -111,8 +112,13 @@ class GroupPolicy < BasePolicy
enable :read_issue_board
enable :read_group_member
enable :read_custom_emoji
+ enable :read_counts
+ enable :read_organization
+ enable :read_contact
end
+ rule { ~public_group & ~has_access }.prevent :read_counts
+
rule { ~can?(:read_group) }.policy do
prevent :read_design_activity
end
@@ -127,6 +133,7 @@ class GroupPolicy < BasePolicy
enable :create_custom_emoji
enable :create_package
enable :create_package_settings
+ enable :developer_access
end
rule { reporter }.policy do
@@ -140,6 +147,7 @@ class GroupPolicy < BasePolicy
enable :read_prometheus
enable :read_package
enable :read_package_settings
+ enable :admin_organization
end
rule { maintainer }.policy do
@@ -155,6 +163,7 @@ class GroupPolicy < BasePolicy
enable :read_deploy_token
enable :create_jira_connect_subscription
enable :update_runners_registration_token
+ enable :maintainer_access
end
rule { owner }.policy do
@@ -170,6 +179,7 @@ class GroupPolicy < BasePolicy
enable :update_default_branch_protection
enable :create_deploy_token
enable :destroy_deploy_token
+ enable :owner_access
end
rule { can?(:read_nested_project_resources) }.policy do
@@ -223,8 +233,9 @@ class GroupPolicy < BasePolicy
rule { dependency_proxy_access_allowed & dependency_proxy_available }
.enable :read_dependency_proxy
- rule { developer & dependency_proxy_available }
- .enable :admin_dependency_proxy
+ rule { developer & dependency_proxy_available }.policy do
+ enable :admin_dependency_proxy
+ end
rule { can?(:admin_group) & resource_access_token_feature_available }.policy do
enable :read_resource_access_tokens
diff --git a/app/policies/issue_policy.rb b/app/policies/issue_policy.rb
index 74bed6b6c4e..575e532c615 100644
--- a/app/policies/issue_policy.rb
+++ b/app/policies/issue_policy.rb
@@ -69,6 +69,14 @@ class IssuePolicy < IssuablePolicy
rule { persisted & can?(:admin_issue) }.policy do
enable :set_issue_metadata
end
+
+ rule { can?(:set_issue_metadata) }.policy do
+ enable :set_confidentiality
+ end
+
+ rule { ~persisted & can?(:create_issue) }.policy do
+ enable :set_confidentiality
+ end
end
IssuePolicy.prepend_mod_with('IssuePolicy')
diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb
index 067f0f6a9d2..018c061af9f 100644
--- a/app/policies/user_policy.rb
+++ b/app/policies/user_policy.rb
@@ -25,6 +25,7 @@ class UserPolicy < BasePolicy
enable :update_user_status
enable :read_user_personal_access_tokens
enable :read_group_count
+ enable :read_user_groups
end
rule { default }.enable :read_user_profile
diff --git a/app/presenters/ci/build_presenter.rb b/app/presenters/ci/build_presenter.rb
index 384cb3285fc..06ed6791bb7 100644
--- a/app/presenters/ci/build_presenter.rb
+++ b/app/presenters/ci/build_presenter.rb
@@ -12,11 +12,11 @@ module Ci
erased_by.name if erased_by_user?
end
- def status_title
+ def status_title(status = detailed_status)
if auto_canceled?
"Job is redundant and is auto-canceled by Pipeline ##{auto_canceled_by_id}"
else
- tooltip_for_badge
+ tooltip_for_badge(status)
end
end
@@ -41,8 +41,8 @@ module Ci
private
- def tooltip_for_badge
- detailed_status.badge_tooltip.capitalize
+ def tooltip_for_badge(status)
+ status.badge_tooltip.capitalize
end
def detailed_status
diff --git a/app/presenters/ci/build_runner_presenter.rb b/app/presenters/ci/build_runner_presenter.rb
index 0baee614568..b0066e2d7f0 100644
--- a/app/presenters/ci/build_runner_presenter.rb
+++ b/app/presenters/ci/build_runner_presenter.rb
@@ -33,7 +33,7 @@ module Ci
end
def runner_variables
- if Feature.enabled?(:variable_inside_variable, project)
+ if Feature.enabled?(:variable_inside_variable, project, default_enabled: :yaml)
variables.sort_and_expand_all(project, keep_undefined: true).to_runner_variables
else
variables.to_runner_variables
diff --git a/app/presenters/ci/legacy_stage_presenter.rb b/app/presenters/ci/legacy_stage_presenter.rb
index 56e268cff9f..d5c21baba28 100644
--- a/app/presenters/ci/legacy_stage_presenter.rb
+++ b/app/presenters/ci/legacy_stage_presenter.rb
@@ -15,18 +15,9 @@ module Ci
private
def preload_statuses(statuses)
- loaded_statuses = statuses.load
- statuses.tap do |statuses|
- # rubocop: disable CodeReuse/ActiveRecord
- ActiveRecord::Associations::Preloader.new.preload(preloadable_statuses(loaded_statuses), %w[tags job_artifacts_archive metadata])
- # rubocop: enable CodeReuse/ActiveRecord
- end
- end
+ Preloaders::CommitStatusPreloader.new(statuses).execute(Ci::StagePresenter::PRELOADED_RELATIONS)
- def preloadable_statuses(statuses)
- statuses.reject do |status|
- status.instance_of?(::GenericCommitStatus) || status.instance_of?(::Ci::Bridge)
- end
+ statuses
end
end
end
diff --git a/app/presenters/ci/stage_presenter.rb b/app/presenters/ci/stage_presenter.rb
index 9ec3f8d153a..21bda86cded 100644
--- a/app/presenters/ci/stage_presenter.rb
+++ b/app/presenters/ci/stage_presenter.rb
@@ -4,6 +4,8 @@ module Ci
class StagePresenter < Gitlab::View::Presenter::Delegated
presents :stage
+ PRELOADED_RELATIONS = [:pipeline, :metadata, :tags, :job_artifacts_archive, :downstream_pipeline].freeze
+
def latest_ordered_statuses
preload_statuses(stage.statuses.latest_ordered)
end
@@ -15,18 +17,9 @@ module Ci
private
def preload_statuses(statuses)
- loaded_statuses = statuses.load
- statuses.tap do |statuses|
- # rubocop: disable CodeReuse/ActiveRecord
- ActiveRecord::Associations::Preloader.new.preload(preloadable_statuses(loaded_statuses), %w[pipeline tags job_artifacts_archive metadata])
- # rubocop: enable CodeReuse/ActiveRecord
- end
- end
+ Preloaders::CommitStatusPreloader.new(statuses).execute(PRELOADED_RELATIONS)
- def preloadable_statuses(statuses)
- statuses.reject do |status|
- status.instance_of?(::GenericCommitStatus) || status.instance_of?(::Ci::Bridge)
- end
+ statuses
end
end
end
diff --git a/app/presenters/commit_status_presenter.rb b/app/presenters/commit_status_presenter.rb
index 5f5bbf13f92..3c39470b730 100644
--- a/app/presenters/commit_status_presenter.rb
+++ b/app/presenters/commit_status_presenter.rb
@@ -27,7 +27,8 @@ class CommitStatusPresenter < Gitlab::View::Presenter::Delegated
user_blocked: 'The user who created this job is blocked',
ci_quota_exceeded: 'No more CI minutes available',
no_matching_runner: 'No matching runner available',
- trace_size_exceeded: 'The job log size limit was reached'
+ trace_size_exceeded: 'The job log size limit was reached',
+ builds_disabled: 'The CI/CD is disabled for this project'
}.freeze
private_constant :CALLOUT_FAILURE_MESSAGES
diff --git a/app/presenters/packages/helm/index_presenter.rb b/app/presenters/packages/helm/index_presenter.rb
index a6cfc61c94d..e85a4f248cf 100644
--- a/app/presenters/packages/helm/index_presenter.rb
+++ b/app/presenters/packages/helm/index_presenter.rb
@@ -8,11 +8,12 @@ module Packages
API_VERSION = 'v1'
CHANNEL = 'channel'
INDEX_YAML_SUFFIX = "/#{CHANNEL}/index.yaml"
+ EMPTY_HASH = {}.freeze
- def initialize(project, project_id_param, package_files)
- @project = project
+ def initialize(project_id_param, channel, packages)
@project_id_param = project_id_param
- @package_files = package_files
+ @channel = channel
+ @packages = packages
end
def api_version
@@ -20,10 +21,12 @@ module Packages
end
def entries
- files = @package_files.preload_helm_file_metadata
+ return EMPTY_HASH unless @channel.present?
+
result = Hash.new { |h, k| h[k] = [] }
- files.find_each do |package_file|
+ # this .each is safe as we have max 300 objects
+ most_recent_package_files.each do |package_file|
name = package_file.helm_metadata['name']
result[name] << package_file.helm_metadata.merge({
'created' => package_file.created_at.utc.strftime('%Y-%m-%dT%H:%M:%S.%NZ'),
@@ -48,6 +51,16 @@ module Packages
'contextPath' => path.delete_suffix(INDEX_YAML_SUFFIX)
}
end
+
+ private
+
+ def most_recent_package_files
+ ::Packages::PackageFile.most_recent_for(
+ @packages,
+ extra_join: :helm_file_metadatum,
+ extra_where: { packages_helm_file_metadata: { channel: @channel } }
+ ).preload_helm_file_metadata
+ end
end
end
end
diff --git a/app/presenters/packages/npm/package_presenter.rb b/app/presenters/packages/npm/package_presenter.rb
index 4e147b4739e..b9595eb6647 100644
--- a/app/presenters/packages/npm/package_presenter.rb
+++ b/app/presenters/packages/npm/package_presenter.rb
@@ -7,8 +7,6 @@ module Packages
attr_reader :name, :packages
- NPM_VALID_DEPENDENCY_TYPES = %i[dependencies devDependencies bundleDependencies peerDependencies].freeze
-
def initialize(name, packages)
@name = name
@packages = packages
@@ -17,12 +15,16 @@ module Packages
def versions
package_versions = {}
- packages.each do |package|
- package_file = package.package_files.last
+ packages.each_batch do |relation|
+ relation.including_dependency_links
+ .preload_files
+ .each do |package|
+ package_file = package.package_files.last
- next unless package_file
+ next unless package_file
- package_versions[package.version] = build_package_version(package, package_file)
+ package_versions[package.version] = build_package_version(package, package_file)
+ end
end
package_versions
@@ -59,11 +61,8 @@ module Packages
def build_package_dependencies(package)
dependencies = Hash.new { |h, key| h[key] = {} }
- dependency_links = package.dependency_links
- .with_dependency_type(NPM_VALID_DEPENDENCY_TYPES)
- .includes_dependency
- dependency_links.find_each do |dependency_link|
+ package.dependency_links.each do |dependency_link|
dependency = dependency_link.dependency
dependencies[dependency_link.dependency_type][dependency.name] = dependency.version_pattern
end
@@ -72,13 +71,13 @@ module Packages
end
def sorted_versions
- versions = packages.map(&:version).compact
+ versions = packages.pluck_versions.compact
VersionSorter.sort(versions)
end
def package_tags
Packages::Tag.for_packages(packages)
- .preload_package
+ .preload_package
end
end
end
diff --git a/app/presenters/project_presenter.rb b/app/presenters/project_presenter.rb
index 80a8ee5cb3c..066f4786cff 100644
--- a/app/presenters/project_presenter.rb
+++ b/app/presenters/project_presenter.rb
@@ -431,22 +431,10 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
private
def integrations_anchor_data
- experiment(:repo_integrations_link, project: project) do |e|
- e.exclude! unless can?(current_user, :admin_project, project)
-
- e.use {} # nil control
- e.try do
- label = statistic_icon('settings') + _('Configure Integrations')
- AnchorData.new(false, label, project_settings_integrations_path(project), nil, nil, nil, {
- 'track-event': 'click',
- 'track-experiment': e.name
- })
- end
-
- e.run # call run so the return value will be the AnchorData (or nil)
+ return unless can?(current_user, :admin_project, project)
- e.track(:view, value: project.id) # track an event for the view, with project id
- end
+ label = statistic_icon('settings') + _('Configure Integrations')
+ AnchorData.new(false, label, project_settings_integrations_path(project), nil, nil, nil)
end
def cicd_missing?
diff --git a/app/presenters/projects/import_export/project_export_presenter.rb b/app/presenters/projects/import_export/project_export_presenter.rb
index 611294ddfd8..f56760b55df 100644
--- a/app/presenters/projects/import_export/project_export_presenter.rb
+++ b/app/presenters/projects/import_export/project_export_presenter.rb
@@ -34,7 +34,6 @@ module Projects
# We need `.connected_to_user` here otherwise when a group has an
# invitee, it would make the following query return 0 rows since a NULL
# user_id would be present in the subquery
- # See http://stackoverflow.com/questions/129077/not-in-clause-and-null-values
non_null_user_ids = project.project_members.connected_to_user.select(:user_id)
GroupMembersFinder.new(project.group).execute.where.not(user_id: non_null_user_ids)
end
diff --git a/app/presenters/snippet_blob_presenter.rb b/app/presenters/snippet_blob_presenter.rb
index 0003a13a7bc..ab8fc0f905b 100644
--- a/app/presenters/snippet_blob_presenter.rb
+++ b/app/presenters/snippet_blob_presenter.rb
@@ -17,6 +17,10 @@ class SnippetBlobPresenter < BlobPresenter
snippet_blob_raw_route
end
+ def raw_directory
+ raw_path.rpartition("/").first + "/"
+ end
+
def raw_plain_data
blob.data unless blob.binary?
end
@@ -33,7 +37,7 @@ class SnippetBlobPresenter < BlobPresenter
def render_rich_partial
renderer.render("projects/blob/viewers/_#{blob.rich_viewer.partial_name}",
- locals: { viewer: blob.rich_viewer, blob: blob, blob_raw_path: raw_path, blob_raw_url: raw_url },
+ locals: { viewer: blob.rich_viewer, blob: blob, blob_raw_path: raw_path, blob_raw_url: raw_url, parent_dir_raw_path: raw_directory },
layout: false)
end
diff --git a/app/serializers/group_child_entity.rb b/app/serializers/group_child_entity.rb
index 619ca0b5f82..0ca6e7b40d9 100644
--- a/app/serializers/group_child_entity.rb
+++ b/app/serializers/group_child_entity.rb
@@ -37,9 +37,13 @@ class GroupChildEntity < Grape::Entity
if: lambda { |_instance, _options| project? }
# Group only attributes
- expose :children_count, :parent_id, :project_count, :subgroup_count,
+ expose :children_count, :parent_id,
unless: lambda { |_instance, _options| project? }
+ expose :subgroup_count, if: lambda { |group| access_group_counts?(group) }
+
+ expose :project_count, if: lambda { |group| access_group_counts?(group) }
+
expose :leave_path, unless: lambda { |_instance, _options| project? } do |instance|
leave_group_members_path(instance)
end
@@ -52,10 +56,6 @@ class GroupChildEntity < Grape::Entity
end
end
- expose :number_projects_with_delimiter, unless: lambda { |_instance, _options| project? } do |instance|
- number_with_delimiter(instance.project_count)
- end
-
expose :number_users_with_delimiter, unless: lambda { |_instance, _options| project? } do |instance|
number_with_delimiter(instance.member_count)
end
@@ -66,6 +66,10 @@ class GroupChildEntity < Grape::Entity
private
+ def access_group_counts?(group)
+ !project? && can?(request.current_user, :read_counts, group)
+ end
+
# rubocop: disable CodeReuse/ActiveRecord
def membership
return unless request.current_user
diff --git a/app/serializers/group_entity.rb b/app/serializers/group_entity.rb
index 0e1bc9a6b3d..66919c49320 100644
--- a/app/serializers/group_entity.rb
+++ b/app/serializers/group_entity.rb
@@ -40,10 +40,6 @@ class GroupEntity < Grape::Entity
GroupsFinder.new(request.current_user, parent: group).execute.any?
end
- expose :number_projects_with_delimiter do |group|
- number_with_delimiter(GroupProjectsFinder.new(group: group, current_user: request.current_user).execute.count)
- end
-
expose :number_users_with_delimiter do |group|
number_with_delimiter(group.users.count)
end
diff --git a/app/serializers/issuable_sidebar_extras_entity.rb b/app/serializers/issuable_sidebar_extras_entity.rb
index 77f2e34fa5d..68c71cd5cf3 100644
--- a/app/serializers/issuable_sidebar_extras_entity.rb
+++ b/app/serializers/issuable_sidebar_extras_entity.rb
@@ -3,23 +3,6 @@
class IssuableSidebarExtrasEntity < Grape::Entity
include RequestAwareEntity
include TimeTrackableEntity
- include NotificationsHelper
-
- expose :participants, using: ::API::Entities::UserBasic do |issuable|
- issuable.participants(request.current_user)
- end
-
- expose :project_emails_disabled do |issuable|
- issuable.project.emails_disabled?
- end
-
- expose :subscribe_disabled_description do |issuable|
- notification_description(:owner_disabled)
- end
-
- expose :subscribed do |issuable|
- issuable.subscribed?(request.current_user, issuable.project)
- end
expose :assignees, using: ::API::Entities::UserBasic
end
diff --git a/app/services/auth/container_registry_authentication_service.rb b/app/services/auth/container_registry_authentication_service.rb
index a2683647c72..bc734465750 100644
--- a/app/services/auth/container_registry_authentication_service.rb
+++ b/app/services/auth/container_registry_authentication_service.rb
@@ -45,7 +45,12 @@ module Auth
token.expire_time = token_expire_at
token[:access] = names.map do |name|
- { type: 'repository', name: name, actions: actions }
+ {
+ type: 'repository',
+ name: name,
+ actions: actions,
+ migration_eligible: migration_eligible(repository_path: name)
+ }.compact
end
token.encoded
@@ -119,13 +124,20 @@ module Auth
type: type,
name: path.to_s,
actions: authorized_actions,
- migration_eligible: migration_eligible(requested_project, authorized_actions)
+ migration_eligible: self.class.migration_eligible(project: requested_project)
}.compact
end
- def migration_eligible(project, actions)
+ def self.migration_eligible(project: nil, repository_path: nil)
return unless Feature.enabled?(:container_registry_migration_phase1)
+ # project has precedence over repository_path. If only the latter is provided, we find the corresponding Project.
+ unless project
+ return unless repository_path
+
+ project = ContainerRegistry::Path.new(repository_path).repository_project
+ end
+
# The migration process will start by allowing only specific test and gitlab-org projects using the
# `container_registry_migration_phase1_allow` FF. We'll then move on to a percentage rollout using this same FF.
# To remove the risk of impacting enterprise customers that rely heavily on the registry during the percentage
diff --git a/app/services/base_container_service.rb b/app/services/base_container_service.rb
index 8492b3ce92c..190d159e7f1 100644
--- a/app/services/base_container_service.rb
+++ b/app/services/base_container_service.rb
@@ -2,12 +2,12 @@
# Base class, scoped by container (project or group).
#
-# New or existing services which only require project as a container
-# should subclass BaseProjectService.
+# New or existing services which only require a project or group container
+# should subclass BaseProjectService or BaseGroupService.
#
-# If you require a different but specific, non-polymorphic container (such
-# as group), consider creating a new subclass such as BaseGroupService,
-# and update the related comment at the top of the original BaseService.
+# If you require a different but specific, non-polymorphic container
+# consider creating a new subclass, and update the related comment at
+# the top of the original BaseService.
class BaseContainerService
include BaseServiceUtility
diff --git a/app/services/base_group_service.rb b/app/services/base_group_service.rb
new file mode 100644
index 00000000000..c95b6f5af60
--- /dev/null
+++ b/app/services/base_group_service.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+# Base class, scoped by group
+class BaseGroupService < ::BaseContainerService # rubocop:disable Gitlab/NamespacedClass
+ attr_accessor :group
+
+ def initialize(group:, current_user: nil, params: {})
+ super(container: group, current_user: current_user, params: params)
+
+ @group = group
+ end
+end
diff --git a/app/services/base_service.rb b/app/services/base_service.rb
index 3030287e035..275ebcc7bcd 100644
--- a/app/services/base_service.rb
+++ b/app/services/base_service.rb
@@ -10,6 +10,7 @@
#
# - BaseContainerService for services scoped by container (project or group)
# - BaseProjectService for services scoped to projects
+# - BaseGroupService for services scoped to groups
#
# or, create a new base class and update this comment.
class BaseService
diff --git a/app/services/boards/issues/list_service.rb b/app/services/boards/issues/list_service.rb
index 8806e6788ff..9a3e3bc3bdb 100644
--- a/app/services/boards/issues/list_service.rb
+++ b/app/services/boards/issues/list_service.rb
@@ -9,6 +9,14 @@ module Boards
IssuesFinder.valid_params
end
+ # It is a class method because we cannot apply it
+ # prior to knowing how many items should be fetched for a list.
+ def self.initialize_relative_positions(board, current_user, issues)
+ if Gitlab::Database.read_write? && !board.disabled_for?(current_user)
+ Issue.move_nulls_to_end(issues)
+ end
+ end
+
private
def order(items)
diff --git a/app/services/ci/after_requeue_job_service.rb b/app/services/ci/after_requeue_job_service.rb
index f717dd0862c..9101ae91967 100644
--- a/app/services/ci/after_requeue_job_service.rb
+++ b/app/services/ci/after_requeue_job_service.rb
@@ -10,16 +10,9 @@ module Ci
private
def process_subsequent_jobs(processable)
- if Feature.enabled?(:ci_same_stage_job_needs, processable.project, default_enabled: :yaml)
- (stage_dependent_jobs(processable) | needs_dependent_jobs(processable))
- .each do |processable|
- process(processable)
- end
- else
- skipped_jobs(processable).after_stage(processable.stage_idx)
- .find_each do |job|
- process(job)
- end
+ (stage_dependent_jobs(processable) | needs_dependent_jobs(processable))
+ .each do |processable|
+ process(processable)
end
end
diff --git a/app/services/ci/archive_trace_service.rb b/app/services/ci/archive_trace_service.rb
index bc3219fbd79..995b58c6882 100644
--- a/app/services/ci/archive_trace_service.rb
+++ b/app/services/ci/archive_trace_service.rb
@@ -3,6 +3,13 @@
module Ci
class ArchiveTraceService
def execute(job, worker_name:)
+ unless job.trace.can_attempt_archival_now?
+ Sidekiq.logger.warn(class: worker_name,
+ message: job.trace.archival_attempts_message,
+ job_id: job.id)
+ return
+ end
+
# TODO: Remove this logging once we confirmed new live trace architecture is functional.
# See https://gitlab.com/gitlab-com/gl-infra/infrastructure/issues/4667.
unless job.has_live_trace?
@@ -25,6 +32,8 @@ module Ci
rescue ::Gitlab::Ci::Trace::AlreadyArchivedError
# It's already archived, thus we can safely ignore this exception.
rescue StandardError => e
+ job.trace.increment_archival_attempts!
+
# Tracks this error with application logs, Sentry, and Prometheus.
# If `archive!` keeps failing for over a week, that could incur data loss.
# (See more https://docs.gitlab.com/ee/administration/job_logs.html#new-incremental-logging-architecture)
diff --git a/app/services/ci/drop_pipeline_service.rb b/app/services/ci/drop_pipeline_service.rb
index 16d3abcbfa0..5772ab8f29c 100644
--- a/app/services/ci/drop_pipeline_service.rb
+++ b/app/services/ci/drop_pipeline_service.rb
@@ -2,8 +2,7 @@
module Ci
class DropPipelineService
- PRELOADED_COMMIT_STATUS_RELATIONS = [:project, :pipeline].freeze
- PRELOADED_CI_BUILD_RELATIONS = [:metadata, :deployment, :taggings].freeze
+ PRELOADED_RELATIONS = [:project, :pipeline, :metadata, :deployment, :taggings].freeze
# execute service asynchronously for each cancelable pipeline
def execute_async_for_all(pipelines, failure_reason, context_user)
@@ -30,11 +29,8 @@ module Ci
private
- # rubocop: disable CodeReuse/ActiveRecord
def preload_associations_for_drop(commit_status_batch)
- ActiveRecord::Associations::Preloader.new.preload(commit_status_batch, PRELOADED_COMMIT_STATUS_RELATIONS)
- ActiveRecord::Associations::Preloader.new.preload(commit_status_batch.select { |job| job.is_a?(Ci::Build) }, PRELOADED_CI_BUILD_RELATIONS)
+ Preloaders::CommitStatusPreloader.new(commit_status_batch).execute(PRELOADED_RELATIONS)
end
- # rubocop: enable CodeReuse/ActiveRecord
end
end
diff --git a/app/services/ci/external_pull_requests/create_pipeline_service.rb b/app/services/ci/external_pull_requests/create_pipeline_service.rb
index 83499524a8e..dd93ca4708e 100644
--- a/app/services/ci/external_pull_requests/create_pipeline_service.rb
+++ b/app/services/ci/external_pull_requests/create_pipeline_service.rb
@@ -16,8 +16,14 @@ module Ci
private
def create_pipeline_for(pull_request)
- Ci::CreatePipelineService.new(project, current_user, create_params(pull_request))
- .execute(:external_pull_request_event, external_pull_request: pull_request)
+ if ::Feature.enabled?(:ci_create_external_pr_pipeline_async, project, default_enabled: :yaml)
+ Ci::ExternalPullRequests::CreatePipelineWorker.perform_async(
+ project.id, current_user.id, pull_request.id
+ )
+ else
+ Ci::CreatePipelineService.new(project, current_user, create_params(pull_request))
+ .execute(:external_pull_request_event, external_pull_request: pull_request)
+ end
end
def create_params(pull_request)
diff --git a/app/services/ci/pipeline_schedules/calculate_next_run_service.rb b/app/services/ci/pipeline_schedules/calculate_next_run_service.rb
index 9c8f6b47288..6c8ccb017e9 100644
--- a/app/services/ci/pipeline_schedules/calculate_next_run_service.rb
+++ b/app/services/ci/pipeline_schedules/calculate_next_run_service.rb
@@ -8,7 +8,6 @@ module Ci
def execute(schedule, fallback_method:)
@schedule = schedule
- return fallback_method.call unless ::Feature.enabled?(:ci_daily_limit_for_pipeline_schedules, project, default_enabled: :yaml)
return fallback_method.call unless plan_cron&.cron_valid?
now = Time.zone.now
diff --git a/app/services/ci/pipelines/add_job_service.rb b/app/services/ci/pipelines/add_job_service.rb
index 41f9903e48c..53536b6fdf9 100644
--- a/app/services/ci/pipelines/add_job_service.rb
+++ b/app/services/ci/pipelines/add_job_service.rb
@@ -21,14 +21,14 @@ module Ci
Ci::Pipeline.transaction do
yield(job)
- job.update_older_statuses_retried! if Feature.enabled?(:ci_fix_commit_status_retried, pipeline.project, default_enabled: :yaml)
+ job.update_older_statuses_retried!
end
end
else
Ci::Pipeline.transaction do
yield(job)
- job.update_older_statuses_retried! if Feature.enabled?(:ci_fix_commit_status_retried, pipeline.project, default_enabled: :yaml)
+ job.update_older_statuses_retried!
end
end
diff --git a/app/services/ci/queue/build_queue_service.rb b/app/services/ci/queue/build_queue_service.rb
index 99408d529b2..3276c427923 100644
--- a/app/services/ci/queue/build_queue_service.rb
+++ b/app/services/ci/queue/build_queue_service.rb
@@ -24,26 +24,30 @@ module Ci
# rubocop:disable CodeReuse/ActiveRecord
def builds_for_group_runner
- # Workaround for weird Rails bug, that makes `runner.groups.to_sql` to return `runner_id = NULL`
- groups = ::Group.joins(:runner_namespaces).merge(runner.runner_namespaces)
+ if strategy.use_denormalized_namespace_traversal_ids?
+ strategy.builds_for_group_runner
+ else
+ # Workaround for weird Rails bug, that makes `runner.groups.to_sql` to return `runner_id = NULL`
+ groups = ::Group.joins(:runner_namespaces).merge(runner.runner_namespaces)
- hierarchy_groups = Gitlab::ObjectHierarchy
- .new(groups)
- .base_and_descendants
+ hierarchy_groups = Gitlab::ObjectHierarchy
+ .new(groups)
+ .base_and_descendants
- projects = Project.where(namespace_id: hierarchy_groups)
- .with_group_runners_enabled
- .with_builds_enabled
- .without_deleted
+ projects = Project.where(namespace_id: hierarchy_groups)
+ .with_group_runners_enabled
+ .with_builds_enabled
+ .without_deleted
- relation = new_builds.where(project: projects)
+ relation = new_builds.where(project: projects)
- order(relation)
+ order(relation)
+ end
end
def builds_for_project_runner
relation = new_builds
- .where(project: runner.projects.without_deleted.with_builds_enabled)
+ .where(project: runner_projects_relation)
order(relation)
end
@@ -83,6 +87,14 @@ module Ci
end
end
end
+
+ def runner_projects_relation
+ if ::Feature.enabled?(:ci_pending_builds_project_runners_decoupling, runner, default_enabled: :yaml)
+ runner.runner_projects.select(:project_id)
+ else
+ runner.projects.without_deleted.with_builds_enabled
+ end
+ end
end
end
end
diff --git a/app/services/ci/queue/builds_table_strategy.rb b/app/services/ci/queue/builds_table_strategy.rb
index d0a343cb9d4..ac449a5289e 100644
--- a/app/services/ci/queue/builds_table_strategy.rb
+++ b/app/services/ci/queue/builds_table_strategy.rb
@@ -31,6 +31,10 @@ module Ci
end
end
+ def builds_for_group_runner
+ raise NotImplementedError
+ end
+
def builds_matching_tag_ids(relation, ids)
# pick builds that does not have other tags than runner's one
relation.matches_tag_ids(ids)
@@ -61,6 +65,10 @@ module Ci
false
end
+ def use_denormalized_namespace_traversal_ids?
+ false
+ end
+
private
def running_builds_for_shared_runners
diff --git a/app/services/ci/queue/pending_builds_strategy.rb b/app/services/ci/queue/pending_builds_strategy.rb
index efe3a981d3a..7a913e47df4 100644
--- a/app/services/ci/queue/pending_builds_strategy.rb
+++ b/app/services/ci/queue/pending_builds_strategy.rb
@@ -16,12 +16,26 @@ module Ci
builds_ordered_for_shared_runners(shared_builds)
end
+ def builds_for_group_runner
+ return new_builds.none if runner.namespace_ids.empty?
+
+ new_builds.where('ci_pending_builds.namespace_traversal_ids && ARRAY[?]::int[]', runner.namespace_ids)
+ end
+
def builds_matching_tag_ids(relation, ids)
- relation.merge(CommitStatus.matches_tag_ids(ids, table: 'ci_pending_builds', column: 'build_id'))
+ if ::Feature.enabled?(:ci_queueing_denormalize_tags_information, runner, default_enabled: :yaml)
+ relation.for_tags(runner.tags_ids)
+ else
+ relation.merge(CommitStatus.matches_tag_ids(ids, table: 'ci_pending_builds', column: 'build_id'))
+ end
end
def builds_with_any_tags(relation)
- relation.merge(CommitStatus.with_any_tags(table: 'ci_pending_builds', column: 'build_id'))
+ if ::Feature.enabled?(:ci_queueing_denormalize_tags_information, runner, default_enabled: :yaml)
+ relation.where('cardinality(tag_ids) > 0')
+ else
+ relation.merge(CommitStatus.with_any_tags(table: 'ci_pending_builds', column: 'build_id'))
+ end
end
def order(relation)
@@ -44,6 +58,10 @@ module Ci
::Feature.enabled?(:ci_queueing_denormalize_ci_minutes_information, runner, type: :development, default_enabled: :yaml)
end
+ def use_denormalized_namespace_traversal_ids?
+ ::Feature.enabled?(:ci_queueing_denormalize_namespace_traversal_ids, runner, type: :development, default_enabled: :yaml)
+ end
+
private
def builds_available_for_shared_runners
diff --git a/app/services/ci/register_job_service.rb b/app/services/ci/register_job_service.rb
index dc046e1d164..c46ddd22558 100644
--- a/app/services/ci/register_job_service.rb
+++ b/app/services/ci/register_job_service.rb
@@ -103,40 +103,42 @@ module Ci
# rubocop: disable CodeReuse/ActiveRecord
def each_build(params, &blk)
- queue = ::Ci::Queue::BuildQueueService.new(runner)
-
- builds = begin
- if runner.instance_type?
- queue.builds_for_shared_runner
- elsif runner.group_type?
- queue.builds_for_group_runner
- else
- queue.builds_for_project_runner
+ ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/339429') do
+ queue = ::Ci::Queue::BuildQueueService.new(runner)
+
+ builds = begin
+ if runner.instance_type?
+ queue.builds_for_shared_runner
+ elsif runner.group_type?
+ queue.builds_for_group_runner
+ else
+ queue.builds_for_project_runner
+ end
end
- end
- if runner.ref_protected?
- builds = queue.builds_for_protected_runner(builds)
- end
+ if runner.ref_protected?
+ builds = queue.builds_for_protected_runner(builds)
+ end
- # pick builds that does not have other tags than runner's one
- builds = queue.builds_matching_tag_ids(builds, runner.tags.ids)
+ # pick builds that does not have other tags than runner's one
+ builds = queue.builds_matching_tag_ids(builds, runner.tags.ids)
- # pick builds that have at least one tag
- unless runner.run_untagged?
- builds = queue.builds_with_any_tags(builds)
- end
+ # pick builds that have at least one tag
+ unless runner.run_untagged?
+ builds = queue.builds_with_any_tags(builds)
+ end
- # pick builds that older than specified age
- if params.key?(:job_age)
- builds = queue.builds_queued_before(builds, params[:job_age].seconds.ago)
- end
+ # pick builds that older than specified age
+ if params.key?(:job_age)
+ builds = queue.builds_queued_before(builds, params[:job_age].seconds.ago)
+ end
- build_ids = retrieve_queue(-> { queue.execute(builds) })
+ build_ids = retrieve_queue(-> { queue.execute(builds) })
- @metrics.observe_queue_size(-> { build_ids.size }, @runner.runner_type)
+ @metrics.observe_queue_size(-> { build_ids.size }, @runner.runner_type)
- build_ids.each { |build_id| yield Ci::Build.find(build_id) }
+ build_ids.each { |build_id| yield Ci::Build.find(build_id) }
+ end
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -269,6 +271,15 @@ module Ci
missing_dependency_failure: -> (build, _) { !build.has_valid_build_dependencies? },
runner_unsupported: -> (build, params) { !build.supported_runner?(params.dig(:info, :features)) },
archived_failure: -> (build, _) { build.archived? }
+ }.merge(builds_enabled_checks)
+ end
+
+ def builds_enabled_checks
+ return {} unless ::Feature.enabled?(:ci_queueing_builds_enabled_checks, runner, default_enabled: :yaml)
+
+ {
+ project_deleted: -> (build, _) { build.project.pending_delete? },
+ builds_disabled: -> (build, _) { !build.project.builds_enabled? }
}
end
end
diff --git a/app/services/ci/stuck_builds/drop_helpers.rb b/app/services/ci/stuck_builds/drop_helpers.rb
new file mode 100644
index 00000000000..f79b805c23d
--- /dev/null
+++ b/app/services/ci/stuck_builds/drop_helpers.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module Ci
+ module StuckBuilds
+ module DropHelpers
+ def drop(builds, failure_reason:)
+ fetch(builds) do |build|
+ drop_build :outdated, build, failure_reason
+ end
+ end
+
+ def drop_stuck(builds, failure_reason:)
+ fetch(builds) do |build|
+ break unless build.stuck?
+
+ drop_build :stuck, build, failure_reason
+ end
+ end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def fetch(builds)
+ loop do
+ jobs = builds.includes(:tags, :runner, project: [:namespace, :route])
+ .limit(100)
+ .to_a
+
+ break if jobs.empty?
+
+ jobs.each do |job|
+ Gitlab::ApplicationContext.with_context(project: job.project) { yield(job) }
+ end
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ def drop_build(type, build, reason)
+ Gitlab::AppLogger.info "#{self.class}: Dropping #{type} build #{build.id} for runner #{build.runner_id} (status: #{build.status}, failure_reason: #{reason})"
+ Gitlab::OptimisticLocking.retry_lock(build, 3, name: 'stuck_ci_jobs_worker_drop_build') do |b|
+ b.drop(reason)
+ end
+ rescue StandardError => ex
+ build.doom!
+
+ track_exception_for_build(ex, build)
+ end
+
+ def track_exception_for_build(ex, build)
+ Gitlab::ErrorTracking.track_exception(ex,
+ build_id: build.id,
+ build_name: build.name,
+ build_stage: build.stage,
+ pipeline_id: build.pipeline_id,
+ project_id: build.project_id
+ )
+ end
+ end
+ end
+end
diff --git a/app/services/ci/stuck_builds/drop_service.rb b/app/services/ci/stuck_builds/drop_service.rb
new file mode 100644
index 00000000000..3fee9a94381
--- /dev/null
+++ b/app/services/ci/stuck_builds/drop_service.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+module Ci
+ module StuckBuilds
+ class DropService
+ include DropHelpers
+
+ BUILD_RUNNING_OUTDATED_TIMEOUT = 1.hour
+ BUILD_PENDING_OUTDATED_TIMEOUT = 1.day
+ BUILD_SCHEDULED_OUTDATED_TIMEOUT = 1.hour
+ BUILD_PENDING_STUCK_TIMEOUT = 1.hour
+ BUILD_LOOKBACK = 5.days
+
+ def execute
+ Gitlab::AppLogger.info "#{self.class}: Cleaning stuck builds"
+
+ drop(running_timed_out_builds, failure_reason: :stuck_or_timeout_failure)
+
+ drop(
+ pending_builds(BUILD_PENDING_OUTDATED_TIMEOUT.ago),
+ failure_reason: :stuck_or_timeout_failure
+ )
+
+ drop(scheduled_timed_out_builds, failure_reason: :stale_schedule)
+
+ drop_stuck(
+ pending_builds(BUILD_PENDING_STUCK_TIMEOUT.ago),
+ failure_reason: :stuck_or_timeout_failure
+ )
+ end
+
+ private
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ # We're adding the ordering clause by `created_at` and `project_id`
+ # because we want to force the query planner to use the
+ # `ci_builds_gitlab_monitor_metrics` index all the time.
+ def pending_builds(timeout)
+ if Feature.enabled?(:ci_new_query_for_pending_stuck_jobs)
+ Ci::Build.pending.created_at_before(timeout).updated_at_before(timeout).order(created_at: :asc, project_id: :asc)
+ else
+ Ci::Build.pending.updated_before(lookback: BUILD_LOOKBACK.ago, timeout: timeout)
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ def scheduled_timed_out_builds
+ Ci::Build.where(status: :scheduled).where( # rubocop: disable CodeReuse/ActiveRecord
+ 'ci_builds.scheduled_at IS NOT NULL AND ci_builds.scheduled_at < ?',
+ BUILD_SCHEDULED_OUTDATED_TIMEOUT.ago
+ )
+ end
+
+ def running_timed_out_builds
+ Ci::Build.running.where( # rubocop: disable CodeReuse/ActiveRecord
+ 'ci_builds.updated_at < ?',
+ BUILD_RUNNING_OUTDATED_TIMEOUT.ago
+ )
+ end
+ end
+ end
+end
diff --git a/app/services/ci/update_build_queue_service.rb b/app/services/ci/update_build_queue_service.rb
index eea09e9ac67..c1cbf031ca1 100644
--- a/app/services/ci/update_build_queue_service.rb
+++ b/app/services/ci/update_build_queue_service.rb
@@ -99,15 +99,17 @@ module Ci
private
def tick_for(build, runners)
- runners = runners.with_recent_runner_queue
- runners = runners.with_tags if Feature.enabled?(:ci_preload_runner_tags, default_enabled: :yaml)
+ ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/339937') do
+ runners = runners.with_recent_runner_queue
+ runners = runners.with_tags if Feature.enabled?(:ci_preload_runner_tags, default_enabled: :yaml)
- metrics.observe_active_runners(-> { runners.to_a.size })
+ metrics.observe_active_runners(-> { runners.to_a.size })
- runners.each do |runner|
- metrics.increment_runner_tick(runner)
+ runners.each do |runner|
+ metrics.increment_runner_tick(runner)
- runner.pick_build!(build)
+ runner.pick_build!(build)
+ end
end
end
diff --git a/app/services/ci/update_pending_build_service.rb b/app/services/ci/update_pending_build_service.rb
new file mode 100644
index 00000000000..dcba06e60bf
--- /dev/null
+++ b/app/services/ci/update_pending_build_service.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+module Ci
+ class UpdatePendingBuildService
+ VALID_PARAMS = %i[instance_runners_enabled].freeze
+
+ InvalidParamsError = Class.new(StandardError)
+ InvalidModelError = Class.new(StandardError)
+
+ def initialize(model, update_params)
+ @model = model
+ @update_params = update_params
+
+ validations!
+ end
+
+ def execute
+ return unless ::Feature.enabled?(:ci_pending_builds_maintain_shared_runners_data, @model, default_enabled: :yaml)
+
+ @model.pending_builds.each_batch do |relation|
+ relation.update_all(@update_params)
+ end
+ end
+
+ private
+
+ def validations!
+ validate_model! && validate_params!
+ end
+
+ def validate_model!
+ raise InvalidModelError unless @model.is_a?(::Project) || @model.is_a?(::Group)
+
+ true
+ end
+
+ def validate_params!
+ extra_params = @update_params.keys - VALID_PARAMS
+
+ raise InvalidParamsError, "Unvalid params: #{extra_params.join(', ')}" unless extra_params.empty?
+
+ true
+ end
+ end
+end
diff --git a/app/services/clusters/agents/refresh_authorization_service.rb b/app/services/clusters/agents/refresh_authorization_service.rb
new file mode 100644
index 00000000000..a9e3340dbf5
--- /dev/null
+++ b/app/services/clusters/agents/refresh_authorization_service.rb
@@ -0,0 +1,106 @@
+# frozen_string_literal: true
+
+module Clusters
+ module Agents
+ class RefreshAuthorizationService
+ include Gitlab::Utils::StrongMemoize
+
+ AUTHORIZED_ENTITY_LIMIT = 100
+
+ delegate :project, to: :agent, private: true
+ delegate :root_ancestor, to: :project, private: true
+
+ def initialize(agent, config:)
+ @agent = agent
+ @config = config
+ end
+
+ def execute
+ refresh_projects!
+ refresh_groups!
+
+ true
+ end
+
+ private
+
+ attr_reader :agent, :config
+
+ def refresh_projects!
+ if allowed_project_configurations.present?
+ project_ids = allowed_project_configurations.map { |config| config.fetch(:project_id) }
+
+ agent.with_lock do
+ agent.project_authorizations.upsert_all(allowed_project_configurations, unique_by: [:agent_id, :project_id])
+ agent.project_authorizations.where.not(project_id: project_ids).delete_all # rubocop: disable CodeReuse/ActiveRecord
+ end
+ else
+ agent.project_authorizations.delete_all(:delete_all)
+ end
+ end
+
+ def refresh_groups!
+ if allowed_group_configurations.present?
+ group_ids = allowed_group_configurations.map { |config| config.fetch(:group_id) }
+
+ agent.with_lock do
+ agent.group_authorizations.upsert_all(allowed_group_configurations, unique_by: [:agent_id, :group_id])
+ agent.group_authorizations.where.not(group_id: group_ids).delete_all # rubocop: disable CodeReuse/ActiveRecord
+ end
+ else
+ agent.group_authorizations.delete_all(:delete_all)
+ end
+ end
+
+ def allowed_project_configurations
+ strong_memoize(:allowed_project_configurations) do
+ project_entries = extract_config_entries(entity: 'projects')
+
+ if project_entries
+ allowed_projects.where_full_path_in(project_entries.keys).map do |project|
+ { project_id: project.id, config: project_entries[project.full_path] }
+ end
+ end
+ end
+ end
+
+ def allowed_group_configurations
+ strong_memoize(:allowed_group_configurations) do
+ group_entries = extract_config_entries(entity: 'groups')
+
+ if group_entries
+ allowed_groups.where_full_path_in(group_entries.keys).map do |group|
+ { group_id: group.id, config: group_entries[group.full_path] }
+ end
+ end
+ end
+ end
+
+ def extract_config_entries(entity:)
+ config.dig('ci_access', entity)
+ &.first(AUTHORIZED_ENTITY_LIMIT)
+ &.index_by { |config| config.delete('id') }
+ end
+
+ def allowed_projects
+ if group_root_ancestor?
+ root_ancestor.all_projects
+ else
+ ::Project.none
+ end
+ end
+
+ def allowed_groups
+ if group_root_ancestor?
+ root_ancestor.self_and_descendants
+ else
+ ::Group.none
+ end
+ end
+
+ def group_root_ancestor?
+ root_ancestor.group?
+ end
+ end
+ end
+end
diff --git a/app/services/concerns/members/bulk_create_users.rb b/app/services/concerns/members/bulk_create_users.rb
new file mode 100644
index 00000000000..4498f40c396
--- /dev/null
+++ b/app/services/concerns/members/bulk_create_users.rb
@@ -0,0 +1,76 @@
+# frozen_string_literal: true
+
+module Members
+ module BulkCreateUsers
+ extend ActiveSupport::Concern
+
+ included do
+ class << self
+ def add_users(source, users, access_level, current_user: nil, expires_at: nil)
+ return [] unless users.present?
+
+ emails, users, existing_members = parse_users_list(source, users)
+
+ Member.transaction do
+ (emails + users).map! do |user|
+ new(source,
+ user,
+ access_level,
+ existing_members: existing_members,
+ current_user: current_user,
+ expires_at: expires_at)
+ .execute
+ end
+ end
+ end
+
+ private
+
+ def parse_users_list(source, list)
+ emails = []
+ user_ids = []
+ users = []
+ existing_members = {}
+
+ list.each do |item|
+ case item
+ when User
+ users << item
+ when Integer
+ user_ids << item
+ when /\A\d+\Z/
+ user_ids << item.to_i
+ when Devise.email_regexp
+ emails << item
+ end
+ end
+
+ if user_ids.present?
+ # the below will automatically discard invalid user_ids
+ users.concat(User.id_in(user_ids))
+ # helps not have to perform another query per user id to see if the member exists later on when fetching
+ existing_members = source.members_and_requesters.where(user_id: user_ids).index_by(&:user_id) # rubocop:disable CodeReuse/ActiveRecord
+ end
+
+ users.uniq! # de-duplicate just in case as there is no controlling if user records and ids are sent multiple times
+
+ [emails, users, existing_members]
+ end
+ end
+ end
+
+ def initialize(source, user, access_level, **args)
+ super
+
+ @existing_members = args[:existing_members] || (raise ArgumentError, "existing_members must be included in the args hash")
+ end
+
+ private
+
+ attr_reader :existing_members
+
+ def find_or_initialize_member_by_user
+ existing_members[user.id] || source.members.build(user_id: user.id)
+ end
+ end
+end
diff --git a/app/services/customer_relations/organizations/base_service.rb b/app/services/customer_relations/organizations/base_service.rb
new file mode 100644
index 00000000000..63261534b37
--- /dev/null
+++ b/app/services/customer_relations/organizations/base_service.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module CustomerRelations
+ module Organizations
+ class BaseService < ::BaseGroupService
+ private
+
+ def allowed?
+ current_user&.can?(:admin_organization, group)
+ end
+
+ def error(message)
+ ServiceResponse.error(message: message)
+ end
+ end
+ end
+end
diff --git a/app/services/customer_relations/organizations/create_service.rb b/app/services/customer_relations/organizations/create_service.rb
new file mode 100644
index 00000000000..9c223796eaf
--- /dev/null
+++ b/app/services/customer_relations/organizations/create_service.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module CustomerRelations
+ module Organizations
+ class CreateService < BaseService
+ # returns the created organization
+ def execute
+ return error_no_permissions unless allowed?
+
+ params[:group_id] = group.id
+
+ organization = Organization.create(params)
+
+ return error_creating(organization) unless organization.persisted?
+
+ ServiceResponse.success(payload: organization)
+ end
+
+ private
+
+ def error_no_permissions
+ error('You have insufficient permissions to create an organization for this group')
+ end
+
+ def error_creating(organization)
+ error(organization&.errors&.full_messages || 'Failed to create organization')
+ end
+ end
+ end
+end
diff --git a/app/services/customer_relations/organizations/update_service.rb b/app/services/customer_relations/organizations/update_service.rb
new file mode 100644
index 00000000000..9d8f908db14
--- /dev/null
+++ b/app/services/customer_relations/organizations/update_service.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module CustomerRelations
+ module Organizations
+ class UpdateService < BaseService
+ def execute(organization)
+ return error_no_permissions unless allowed?
+ return error_updating(organization) unless organization.update(params)
+
+ ServiceResponse.success(payload: organization)
+ end
+
+ private
+
+ def error_no_permissions
+ error('You have insufficient permissions to update an organization for this group')
+ end
+
+ def error_updating(organization)
+ error(organization&.errors&.full_messages || 'Failed to update organization')
+ end
+ end
+ end
+end
diff --git a/app/services/dependency_proxy/image_ttl_group_policies/update_service.rb b/app/services/dependency_proxy/image_ttl_group_policies/update_service.rb
new file mode 100644
index 00000000000..3c0b6412dc5
--- /dev/null
+++ b/app/services/dependency_proxy/image_ttl_group_policies/update_service.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module DependencyProxy
+ module ImageTtlGroupPolicies
+ class UpdateService < BaseContainerService
+ include Gitlab::Utils::StrongMemoize
+
+ ALLOWED_ATTRIBUTES = %i[enabled ttl].freeze
+
+ def execute
+ return ServiceResponse.error(message: 'Access Denied', http_status: 403) unless allowed?
+ return ServiceResponse.error(message: 'Dependency proxy image TTL Policy not found', http_status: 404) unless dependency_proxy_image_ttl_policy
+
+ if dependency_proxy_image_ttl_policy.update(dependency_proxy_image_ttl_policy_params)
+ ServiceResponse.success(payload: { dependency_proxy_image_ttl_policy: dependency_proxy_image_ttl_policy })
+ else
+ ServiceResponse.error(
+ message: dependency_proxy_image_ttl_policy.errors.full_messages.to_sentence || 'Bad request',
+ http_status: 400
+ )
+ end
+ end
+
+ private
+
+ def dependency_proxy_image_ttl_policy
+ strong_memoize(:dependency_proxy_image_ttl_policy) do
+ container.dependency_proxy_image_ttl_policy
+ end
+ end
+
+ def allowed?
+ Ability.allowed?(current_user, :admin_dependency_proxy, container)
+ end
+
+ def dependency_proxy_image_ttl_policy_params
+ params.slice(*ALLOWED_ATTRIBUTES)
+ end
+ end
+ end
+end
diff --git a/app/services/design_management/delete_designs_service.rb b/app/services/design_management/delete_designs_service.rb
index 7f76bcc5626..9ed03a994c4 100644
--- a/app/services/design_management/delete_designs_service.rb
+++ b/app/services/design_management/delete_designs_service.rb
@@ -17,6 +17,7 @@ module DesignManagement
version = delete_designs!
EventCreateService.new.destroy_designs(designs, current_user)
Gitlab::UsageDataCounters::IssueActivityUniqueCounter.track_issue_designs_removed_action(author: current_user)
+ TodosDestroyer::DestroyedDesignsWorker.perform_async(designs.map(&:id))
success(version: version)
end
diff --git a/app/services/draft_notes/publish_service.rb b/app/services/draft_notes/publish_service.rb
index 3a1db16aaf4..a82a6e22a5a 100644
--- a/app/services/draft_notes/publish_service.rb
+++ b/app/services/draft_notes/publish_service.rb
@@ -34,22 +34,24 @@ module DraftNotes
created_notes = draft_notes.map do |draft_note|
draft_note.review = review
- create_note_from_draft(draft_note, skip_capture_diff_note_position: true)
+ create_note_from_draft(draft_note, skip_capture_diff_note_position: true, skip_keep_around_commits: true)
end
capture_diff_note_positions(created_notes)
+ keep_around_commits(created_notes)
draft_notes.delete_all
set_reviewed
notification_service.async.new_review(review)
MergeRequests::ResolvedDiscussionNotificationService.new(project: project, current_user: current_user).execute(merge_request)
end
- def create_note_from_draft(draft, skip_capture_diff_note_position: false)
+ def create_note_from_draft(draft, skip_capture_diff_note_position: false, skip_keep_around_commits: false)
# Make sure the diff file is unfolded in order to find the correct line
# codes.
draft.diff_file&.unfold_diff_lines(draft.original_position)
- note = Notes::CreateService.new(draft.project, draft.author, draft.publish_params).execute(
+ note_params = draft.publish_params.merge(skip_keep_around_commits: skip_keep_around_commits)
+ note = Notes::CreateService.new(draft.project, draft.author, note_params).execute(
skip_capture_diff_note_position: skip_capture_diff_note_position
)
@@ -86,5 +88,17 @@ module DraftNotes
capture_service.execute(note.discussion) if note.diff_note? && note.start_of_discussion?
end
end
+
+ def keep_around_commits(notes)
+ shas = notes.flat_map do |note|
+ note.shas if note.diff_note?
+ end.uniq
+
+ # We are allowing this since gitaly call will be created for each sha and
+ # even though they're unique, there will still be multiple Gitaly calls.
+ Gitlab::GitalyClient.allow_n_plus_1_calls do
+ project.repository.keep_around(*shas)
+ end
+ end
end
end
diff --git a/app/services/emails/destroy_service.rb b/app/services/emails/destroy_service.rb
index 288bee84ef7..d10833e66cb 100644
--- a/app/services/emails/destroy_service.rb
+++ b/app/services/emails/destroy_service.rb
@@ -3,14 +3,14 @@
module Emails
class DestroyService < ::Emails::BaseService
def execute(email)
- email.destroy && update_secondary_emails!
+ email.destroy && update_secondary_emails!(email.email)
end
private
- def update_secondary_emails!
+ def update_secondary_emails!(deleted_email)
result = ::Users::UpdateService.new(@current_user, user: @user).execute do |user|
- user.update_secondary_emails!
+ user.unset_secondary_emails_matching_deleted_email!(deleted_email)
end
result[:status] == :success
diff --git a/app/services/environments/auto_stop_service.rb b/app/services/environments/auto_stop_service.rb
index 4e3aec64283..686ba050326 100644
--- a/app/services/environments/auto_stop_service.rb
+++ b/app/services/environments/auto_stop_service.rb
@@ -28,11 +28,17 @@ module Environments
private
def stop_in_batch
- environments = Environment.auto_stoppable(BATCH_SIZE)
+ environments = Environment.preload_project.select(:id, :project_id).auto_stoppable(BATCH_SIZE)
- return false unless environments.exists?
+ return false if environments.empty?
- Environments::StopService.execute_in_batch(environments)
+ Environments::AutoStopWorker.bulk_perform_async_with_contexts(
+ environments,
+ arguments_proc: -> (environment) { environment.id },
+ context_proc: -> (environment) { { project: environment.project } }
+ )
+
+ true
end
end
end
diff --git a/app/services/environments/stop_service.rb b/app/services/environments/stop_service.rb
index 089aea11296..d9c66bd13fe 100644
--- a/app/services/environments/stop_service.rb
+++ b/app/services/environments/stop_service.rb
@@ -22,22 +22,6 @@ module Environments
merge_request.environments.each { |environment| execute(environment) }
end
- ##
- # This method is for stopping multiple environments in a batch style.
- # The maximum acceptable count of environments is roughly 5000. Please
- # apply acceptable `LIMIT` clause to the `environments` relation.
- def self.execute_in_batch(environments)
- stop_actions = environments.stop_actions.load
-
- environments.update_all(auto_stop_at: nil, state: 'stopped')
-
- stop_actions.each do |stop_action|
- stop_action.play(stop_action.user)
- rescue StandardError => e
- Gitlab::ErrorTracking.track_exception(e, deployable_id: stop_action.id)
- end
- end
-
private
def environments
diff --git a/app/services/error_tracking/collect_error_service.rb b/app/services/error_tracking/collect_error_service.rb
index bc1f238d81f..477453a693e 100644
--- a/app/services/error_tracking/collect_error_service.rb
+++ b/app/services/error_tracking/collect_error_service.rb
@@ -9,18 +9,18 @@ module ErrorTracking
error = project.error_tracking_errors.report_error(
name: exception['type'], # Example: ActionView::MissingTemplate
description: exception['value'], # Example: Missing template posts/show in...
- actor: event['transaction'], # Example: PostsController#show
+ actor: actor, # Example: PostsController#show
platform: event['platform'], # Example: ruby
- timestamp: event['timestamp']
+ timestamp: timestamp
)
# The payload field contains all the data on error including stacktrace in jsonb.
# Together with occured_at these are 2 main attributes that we need to save here.
error.events.create!(
environment: event['environment'],
- description: exception['type'],
+ description: exception['value'],
level: event['level'],
- occurred_at: event['timestamp'],
+ occurred_at: timestamp,
payload: event
)
end
@@ -34,5 +34,29 @@ module ErrorTracking
def exception
event['exception']['values'].first
end
+
+ def actor
+ return event['transaction'] if event['transaction']
+
+ # Some SDK do not have transaction attribute.
+ # So we build it by combining function name and module name from
+ # the last item in stacktrace.
+ last_line = exception.dig('stacktrace', 'frames').last
+
+ "#{last_line['function']}(#{last_line['module']})"
+ end
+
+ def timestamp
+ return @timestamp if @timestamp
+
+ @timestamp = (event['timestamp'] || Time.zone.now)
+
+ # Some SDK send timestamp in numeric format like '1630945472.13'.
+ if @timestamp.to_s =~ /\A\d+(\.\d+)?\z/
+ @timestamp = Time.zone.at(@timestamp.to_f)
+ end
+
+ @timestamp
+ end
end
end
diff --git a/app/services/error_tracking/list_issues_service.rb b/app/services/error_tracking/list_issues_service.rb
index 5ddba748fd4..86c7791e759 100644
--- a/app/services/error_tracking/list_issues_service.rb
+++ b/app/services/error_tracking/list_issues_service.rb
@@ -74,7 +74,9 @@ module ErrorTracking
# We are going to support more options in the future.
# For now we implement the bare minimum for rendering the list in UI.
filter_opts = {
- status: opts[:issue_status]
+ status: opts[:issue_status],
+ sort: opts[:sort],
+ limit: opts[:limit]
}
errors = ErrorTracking::ErrorsFinder.new(current_user, project, filter_opts).execute
diff --git a/app/services/feature_flags/base_service.rb b/app/services/feature_flags/base_service.rb
index d041703803b..9ae9ab4de63 100644
--- a/app/services/feature_flags/base_service.rb
+++ b/app/services/feature_flags/base_service.rb
@@ -48,10 +48,11 @@ module FeatureFlags
end
end
- def created_scope_message(scope)
- "Created rule #{scope.environment_scope} "\
- "and set it as #{scope.active ? "active" : "inactive"} "\
- "with strategies #{scope.strategies}."
+ def created_strategy_message(strategy)
+ scopes = strategy.scopes
+ .map { |scope| %Q("#{scope.environment_scope}") }
+ .join(', ')
+ %Q(Created strategy "#{strategy.name}" with scopes #{scopes}.)
end
def feature_flag_by_name
diff --git a/app/services/feature_flags/create_service.rb b/app/services/feature_flags/create_service.rb
index 5111f914447..65f8f8e33f6 100644
--- a/app/services/feature_flags/create_service.rb
+++ b/app/services/feature_flags/create_service.rb
@@ -24,8 +24,8 @@ module FeatureFlags
def audit_message(feature_flag)
message_parts = ["Created feature flag #{feature_flag.name} with description \"#{feature_flag.description}\"."]
- message_parts += feature_flag.scopes.map do |scope|
- created_scope_message(scope)
+ message_parts += feature_flag.strategies.map do |strategy|
+ created_strategy_message(strategy)
end
message_parts.join(" ")
diff --git a/app/services/feature_flags/update_service.rb b/app/services/feature_flags/update_service.rb
index 01e4f661d75..ccfd1b57d44 100644
--- a/app/services/feature_flags/update_service.rb
+++ b/app/services/feature_flags/update_service.rb
@@ -2,10 +2,9 @@
module FeatureFlags
class UpdateService < FeatureFlags::BaseService
- AUDITABLE_SCOPE_ATTRIBUTES_HUMAN_NAMES = {
- 'active' => 'active state',
- 'environment_scope' => 'environment scope',
- 'strategies' => 'strategies'
+ AUDITABLE_STRATEGY_ATTRIBUTES_HUMAN_NAMES = {
+ 'scopes' => 'environment scopes',
+ 'parameters' => 'parameters'
}.freeze
def execute(feature_flag)
@@ -41,7 +40,7 @@ module FeatureFlags
def audit_message(feature_flag)
changes = changed_attributes_messages(feature_flag)
- changes += changed_scopes_messages(feature_flag)
+ changes += changed_strategies_messages(feature_flag)
return if changes.empty?
@@ -56,29 +55,30 @@ module FeatureFlags
end
end
- def changed_scopes_messages(feature_flag)
- feature_flag.scopes.map do |scope|
- if scope.new_record?
- created_scope_message(scope)
- elsif scope.marked_for_destruction?
- deleted_scope_message(scope)
+ def changed_strategies_messages(feature_flag)
+ feature_flag.strategies.map do |strategy|
+ if strategy.new_record?
+ created_strategy_message(strategy)
+ elsif strategy.marked_for_destruction?
+ deleted_strategy_message(strategy)
else
- updated_scope_message(scope)
+ updated_strategy_message(strategy)
end
- end.compact # updated_scope_message can return nil if nothing has been changed
+ end.compact # updated_strategy_message can return nil if nothing has been changed
end
- def deleted_scope_message(scope)
- "Deleted rule #{scope.environment_scope}."
+ def deleted_strategy_message(strategy)
+ scopes = strategy.scopes.map { |scope| scope.environment_scope }.join(', ')
+ "Deleted strategy #{strategy.name} with environment scopes #{scopes}."
end
- def updated_scope_message(scope)
- changes = scope.changes.slice(*AUDITABLE_SCOPE_ATTRIBUTES_HUMAN_NAMES.keys)
+ def updated_strategy_message(strategy)
+ changes = strategy.changes.slice(*AUDITABLE_STRATEGY_ATTRIBUTES_HUMAN_NAMES.keys)
return if changes.empty?
- message = "Updated rule #{scope.environment_scope} "
+ message = "Updated strategy #{strategy.name} "
message += changes.map do |attribute_name, change|
- name = AUDITABLE_SCOPE_ATTRIBUTES_HUMAN_NAMES[attribute_name]
+ name = AUDITABLE_STRATEGY_ATTRIBUTES_HUMAN_NAMES[attribute_name]
"#{name} from #{change.first} to #{change.second}"
end.join(' ')
diff --git a/app/services/git/base_hooks_service.rb b/app/services/git/base_hooks_service.rb
index aee2f685e97..63f3f73905a 100644
--- a/app/services/git/base_hooks_service.rb
+++ b/app/services/git/base_hooks_service.rb
@@ -25,17 +25,13 @@ module Git
raise NotImplementedError, "Please implement #{self.class}##{__method__}"
end
- # The changeset, ordered with the newest commit last
- def commits
- raise NotImplementedError, "Please implement #{self.class}##{__method__}"
- end
-
+ # This should return PROCESS_COMMIT_LIMIT commits, ordered with newest last
def limited_commits
- @limited_commits ||= commits.last(PROCESS_COMMIT_LIMIT)
+ raise NotImplementedError, "Please implement #{self.class}##{__method__}"
end
def commits_count
- commits.count
+ raise NotImplementedError, "Please implement #{self.class}##{__method__}"
end
def event_message
diff --git a/app/services/git/branch_hooks_service.rb b/app/services/git/branch_hooks_service.rb
index 7a22d7ffcdf..9b113be5465 100644
--- a/app/services/git/branch_hooks_service.rb
+++ b/app/services/git/branch_hooks_service.rb
@@ -18,20 +18,25 @@ module Git
:push_hooks
end
- def commits
- strong_memoize(:commits) do
+ def limited_commits
+ strong_memoize(:limited_commits) { threshold_commits.last(PROCESS_COMMIT_LIMIT) }
+ end
+
+ # Taking limit+1 commits allows us to detect when the limit is in effect
+ def threshold_commits
+ strong_memoize(:threshold_commits) do
if creating_default_branch?
# The most recent PROCESS_COMMIT_LIMIT commits in the default branch.
# They are returned newest-to-oldest, but we need to present them oldest-to-newest
- project.repository.commits(newrev, limit: PROCESS_COMMIT_LIMIT).reverse
+ project.repository.commits(newrev, limit: PROCESS_COMMIT_LIMIT + 1).reverse!
elsif creating_branch?
# Use the pushed commits that aren't reachable by the default branch
# as a heuristic. This may include more commits than are actually
# pushed, but that shouldn't matter because we check for existing
# cross-references later.
- project.repository.commits_between(project.default_branch, newrev)
+ project.repository.commits_between(project.default_branch, newrev, limit: PROCESS_COMMIT_LIMIT + 1)
elsif updating_branch?
- project.repository.commits_between(oldrev, newrev)
+ project.repository.commits_between(oldrev, newrev, limit: PROCESS_COMMIT_LIMIT + 1)
else # removing branch
[]
end
@@ -39,9 +44,21 @@ module Git
end
def commits_count
- return count_commits_in_branch if creating_default_branch?
+ strong_memoize(:commits_count) do
+ next threshold_commits.count if
+ strong_memoized?(:threshold_commits) &&
+ threshold_commits.count <= PROCESS_COMMIT_LIMIT
- super
+ if creating_default_branch?
+ project.repository.commit_count_for_ref(ref)
+ elsif creating_branch?
+ project.repository.count_commits_between(project.default_branch, newrev)
+ elsif updating_branch?
+ project.repository.count_commits_between(oldrev, newrev)
+ else # removing branch
+ 0
+ end
+ end
end
override :invalidated_file_types
@@ -179,12 +196,6 @@ module Git
creating_branch? && default_branch?
end
- def count_commits_in_branch
- strong_memoize(:count_commits_in_branch) do
- project.repository.commit_count_for_ref(ref)
- end
- end
-
def default_branch?
strong_memoize(:default_branch) do
[nil, branch_name].include?(project.default_branch)
diff --git a/app/services/git/tag_hooks_service.rb b/app/services/git/tag_hooks_service.rb
index d83924fec28..01174d8a942 100644
--- a/app/services/git/tag_hooks_service.rb
+++ b/app/services/git/tag_hooks_service.rb
@@ -8,10 +8,14 @@ module Git
:tag_push_hooks
end
- def commits
+ def limited_commits
[tag_commit].compact
end
+ def commits_count
+ limited_commits.count
+ end
+
def event_message
tag&.message
end
diff --git a/app/services/groups/open_issues_count_service.rb b/app/services/groups/open_issues_count_service.rb
index 17cf3d38987..c18d239998b 100644
--- a/app/services/groups/open_issues_count_service.rb
+++ b/app/services/groups/open_issues_count_service.rb
@@ -3,11 +3,15 @@
module Groups
# Service class for counting and caching the number of open issues of a group.
class OpenIssuesCountService < Groups::CountService
- PUBLIC_COUNT_KEY = 'group_public_open_issues_count'
- TOTAL_COUNT_KEY = 'group_total_open_issues_count'
+ # TOTAL_COUNT_KEY includes confidential and hidden issues (admin)
+ # TOTAL_COUNT_WITHOUT_HIDDEN_KEY includes confidential issues but not hidden issues (reporter and above)
+ # PUBLIC_COUNT_WITHOUT_HIDDEN_KEY does not include confidential or hidden issues (guest)
+ TOTAL_COUNT_KEY = 'group_open_issues_including_hidden_count'
+ TOTAL_COUNT_WITHOUT_HIDDEN_KEY = 'group_open_issues_without_hidden_count'
+ PUBLIC_COUNT_WITHOUT_HIDDEN_KEY = 'group_open_public_issues_without_hidden_count'
def clear_all_cache_keys
- [cache_key(PUBLIC_COUNT_KEY), cache_key(TOTAL_COUNT_KEY)].each do |key|
+ [cache_key(TOTAL_COUNT_KEY), cache_key(TOTAL_COUNT_WITHOUT_HIDDEN_KEY), cache_key(PUBLIC_COUNT_WITHOUT_HIDDEN_KEY)].each do |key|
Rails.cache.delete(key)
end
end
@@ -15,7 +19,19 @@ module Groups
private
def cache_key_name
- public_only? ? PUBLIC_COUNT_KEY : TOTAL_COUNT_KEY
+ if include_hidden?
+ TOTAL_COUNT_KEY
+ elsif public_only?
+ PUBLIC_COUNT_WITHOUT_HIDDEN_KEY
+ else
+ TOTAL_COUNT_WITHOUT_HIDDEN_KEY
+ end
+ end
+
+ def include_hidden?
+ strong_memoize(:user_is_admin) do
+ user&.can_admin_all_resources?
+ end
end
def public_only?
@@ -35,7 +51,8 @@ module Groups
state: 'opened',
non_archived: true,
include_subgroups: true,
- public_only: public_only?
+ public_only: public_only?,
+ include_hidden: include_hidden?
).execute
end
diff --git a/app/services/groups/update_shared_runners_service.rb b/app/services/groups/update_shared_runners_service.rb
index 639c5bf6ae0..eb6b46a5613 100644
--- a/app/services/groups/update_shared_runners_service.rb
+++ b/app/services/groups/update_shared_runners_service.rb
@@ -8,6 +8,7 @@ module Groups
validate_params
update_shared_runners
+ update_pending_builds!
success
@@ -26,5 +27,13 @@ module Groups
def update_shared_runners
group.update_shared_runners_setting!(params[:shared_runners_setting])
end
+
+ def update_pending_builds!
+ return unless group.previous_changes.include?('shared_runners_enabled')
+
+ update_params = { instance_runners_enabled: group.shared_runners_enabled }
+
+ ::Ci::UpdatePendingBuildService.new(group, update_params).execute
+ end
end
end
diff --git a/app/services/issuable/bulk_update_service.rb b/app/services/issuable/bulk_update_service.rb
index cd32cd78728..238f5ebddae 100644
--- a/app/services/issuable/bulk_update_service.rb
+++ b/app/services/issuable/bulk_update_service.rb
@@ -57,7 +57,11 @@ module Issuable
items.each do |issuable|
next unless can?(current_user, :"update_#{type}", issuable)
- update_class.new(**update_class.constructor_container_arg(issuable.issuing_parent), current_user: current_user, params: params).execute(issuable)
+ update_class.new(
+ **update_class.constructor_container_arg(issuable.issuing_parent),
+ current_user: current_user,
+ params: dup_params
+ ).execute(issuable)
end
items
@@ -78,6 +82,19 @@ module Issuable
.includes_for_bulk_update
end
+ # Duplicates params and its top-level values
+ # We cannot use deep_dup because ActiveRecord objects will result
+ # to new records with no id assigned
+ def dup_params
+ dup = HashWithIndifferentAccess.new
+
+ params.each do |key, value|
+ dup[key] = value.is_a?(ActiveRecord::Base) ? value : value.dup
+ end
+
+ dup
+ end
+
def response_success(message: nil, payload: nil)
ServiceResponse.success(message: message, payload: payload)
end
diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb
index 0984238517e..59e521853de 100644
--- a/app/services/issuable_base_service.rb
+++ b/app/services/issuable_base_service.rb
@@ -51,9 +51,12 @@ class IssuableBaseService < ::BaseProjectService
params.delete(:canonical_issue_id)
params.delete(:project)
params.delete(:discussion_locked)
- params.delete(:confidential)
end
+ # confidential attribute is a special type of metadata and needs to be allowed to be set
+ # by non-members on issues in public projects so that security issues can be reported as confidential.
+ params.delete(:confidential) unless can?(current_user, :set_confidentiality, issuable)
+
filter_assignees(issuable)
filter_milestone
filter_labels
diff --git a/app/services/issue_rebalancing_service.rb b/app/services/issue_rebalancing_service.rb
deleted file mode 100644
index 142d287370f..00000000000
--- a/app/services/issue_rebalancing_service.rb
+++ /dev/null
@@ -1,136 +0,0 @@
-# frozen_string_literal: true
-
-class IssueRebalancingService
- MAX_ISSUE_COUNT = 10_000
- BATCH_SIZE = 100
- SMALLEST_BATCH_SIZE = 5
- RETRIES_LIMIT = 3
- TooManyIssues = Class.new(StandardError)
-
- TIMING_CONFIGURATION = [
- [0.1.seconds, 0.05.seconds], # short timings, lock_timeout: 100ms, sleep after LockWaitTimeout: 50ms
- [0.5.seconds, 0.05.seconds],
- [1.second, 0.5.seconds],
- [1.second, 0.5.seconds],
- [5.seconds, 1.second]
- ].freeze
-
- def initialize(projects_collection)
- @root_namespace = projects_collection.take.root_namespace # rubocop:disable CodeReuse/ActiveRecord
- @base = Issue.in_projects(projects_collection)
- end
-
- def execute
- return unless Feature.enabled?(:rebalance_issues, root_namespace)
-
- raise TooManyIssues, "#{issue_count} issues" if issue_count > MAX_ISSUE_COUNT
-
- start = RelativePositioning::START_POSITION - (gaps / 2) * gap_size
-
- if Feature.enabled?(:issue_rebalancing_optimization)
- Issue.transaction do
- assign_positions(start, indexed_ids)
- .sort_by(&:first)
- .each_slice(BATCH_SIZE) do |pairs_with_position|
- if Feature.enabled?(:issue_rebalancing_with_retry)
- update_positions_with_retry(pairs_with_position, 'rebalance issue positions in batches ordered by id')
- else
- update_positions(pairs_with_position, 'rebalance issue positions in batches ordered by id')
- end
- end
- end
- else
- Issue.transaction do
- indexed_ids.each_slice(BATCH_SIZE) do |pairs|
- pairs_with_position = assign_positions(start, pairs)
-
- if Feature.enabled?(:issue_rebalancing_with_retry)
- update_positions_with_retry(pairs_with_position, 'rebalance issue positions')
- else
- update_positions(pairs_with_position, 'rebalance issue positions')
- end
- end
- end
- end
- end
-
- private
-
- attr_reader :root_namespace, :base
-
- # rubocop: disable CodeReuse/ActiveRecord
- def indexed_ids
- base.reorder(:relative_position, :id).pluck(:id).each_with_index
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
- def assign_positions(start, pairs)
- pairs.map do |id, index|
- [id, start + (index * gap_size)]
- end
- end
-
- def update_positions_with_retry(pairs_with_position, query_name)
- retries = 0
- batch_size = pairs_with_position.size
-
- until pairs_with_position.empty?
- begin
- update_positions(pairs_with_position.first(batch_size), query_name)
- pairs_with_position = pairs_with_position.drop(batch_size)
- retries = 0
- rescue ActiveRecord::StatementTimeout, ActiveRecord::QueryCanceled => ex
- raise ex if batch_size < SMALLEST_BATCH_SIZE
-
- if (retries += 1) == RETRIES_LIMIT
- # shrink the batch size in half when RETRIES limit is reached and update still fails perhaps because batch size is still too big
- batch_size = (batch_size / 2).to_i
- retries = 0
- end
-
- retry
- end
- end
- end
-
- def update_positions(pairs_with_position, query_name)
- values = pairs_with_position.map do |id, index|
- "(#{id}, #{index})"
- end.join(', ')
-
- Gitlab::Database::WithLockRetries.new(timing_configuration: TIMING_CONFIGURATION, klass: self.class).run do
- run_update_query(values, query_name)
- end
- end
-
- def run_update_query(values, query_name)
- Issue.connection.exec_query(<<~SQL, query_name)
- WITH cte(cte_id, new_pos) AS #{Gitlab::Database::AsWithMaterialized.materialized_if_supported} (
- SELECT *
- FROM (VALUES #{values}) as t (id, pos)
- )
- UPDATE #{Issue.table_name}
- SET relative_position = cte.new_pos
- FROM cte
- WHERE cte_id = id
- SQL
- end
-
- def issue_count
- @issue_count ||= base.count
- end
-
- def gaps
- issue_count - 1
- end
-
- def gap_size
- # We could try to split the available range over the number of gaps we need,
- # but IDEAL_DISTANCE * MAX_ISSUE_COUNT is only 0.1% of the available range,
- # so we are guaranteed not to exhaust it by using this static value.
- #
- # If we raise MAX_ISSUE_COUNT or IDEAL_DISTANCE significantly, this may
- # change!
- RelativePositioning::IDEAL_DISTANCE
- end
-end
diff --git a/app/services/issues/base_service.rb b/app/services/issues/base_service.rb
index 5e0a86fdeee..6dce9fd6e73 100644
--- a/app/services/issues/base_service.rb
+++ b/app/services/issues/base_service.rb
@@ -34,6 +34,13 @@ module Issues
private
+ def find_work_item_type_id(issue_type)
+ work_item_type = WorkItem::Type.default_by_type(issue_type)
+ work_item_type ||= WorkItem::Type.default_issue_type
+
+ work_item_type.id
+ end
+
def filter_params(issue)
super
@@ -84,7 +91,8 @@ module Issues
# @param object [Issue, Project]
def issue_type_allowed?(object)
- can?(current_user, :"create_#{params[:issue_type]}", object)
+ WorkItem::Type.base_types.key?(params[:issue_type]) &&
+ can?(current_user, :"create_#{params[:issue_type]}", object)
end
# @param issue [Issue]
diff --git a/app/services/issues/build_service.rb b/app/services/issues/build_service.rb
index 5cb138946d7..7fdc8daf15c 100644
--- a/app/services/issues/build_service.rb
+++ b/app/services/issues/build_service.rb
@@ -6,6 +6,7 @@ module Issues
def execute
filter_resolve_discussion_params
+
@issue = project.issues.new(issue_params).tap do |issue|
ensure_milestone_available(issue)
end
@@ -60,6 +61,13 @@ module Issues
def issue_params
@issue_params ||= build_issue_params
+
+ # If :issue_type is nil then params[:issue_type] was either nil
+ # or not permitted. Either way, the :issue_type will default
+ # to the column default of `issue`. And that means we need to
+ # ensure the work_item_type_id is set
+ @issue_params[:work_item_type_id] = get_work_item_type_id(@issue_params[:issue_type])
+ @issue_params
end
private
@@ -81,6 +89,11 @@ module Issues
{ author: current_user }
.merge(issue_params_with_info_from_discussions)
.merge(allowed_issue_params)
+ .with_indifferent_access
+ end
+
+ def get_work_item_type_id(issue_type = :issue)
+ find_work_item_type_id(issue_type)
end
end
end
diff --git a/app/services/issues/relative_position_rebalancing_service.rb b/app/services/issues/relative_position_rebalancing_service.rb
new file mode 100644
index 00000000000..7d199f99a24
--- /dev/null
+++ b/app/services/issues/relative_position_rebalancing_service.rb
@@ -0,0 +1,193 @@
+# frozen_string_literal: true
+
+module Issues
+ class RelativePositionRebalancingService
+ UPDATE_BATCH_SIZE = 100
+ PREFETCH_ISSUES_BATCH_SIZE = 10_000
+ SMALLEST_BATCH_SIZE = 5
+ RETRIES_LIMIT = 3
+
+ TooManyConcurrentRebalances = Class.new(StandardError)
+
+ def initialize(projects)
+ @projects_collection = (projects.is_a?(Array) ? Project.id_in(projects) : projects).projects_order_id_asc
+ @root_namespace = @projects_collection.take.root_namespace # rubocop:disable CodeReuse/ActiveRecord
+ @caching = ::Gitlab::Issues::Rebalancing::State.new(@root_namespace, @projects_collection)
+ end
+
+ def execute
+ return unless Feature.enabled?(:rebalance_issues, root_namespace)
+
+ # Given can_start_rebalance? and track_new_running_rebalance are not atomic
+ # it can happen that we end up with more than Rebalancing::State::MAX_NUMBER_OF_CONCURRENT_REBALANCES running.
+ # Considering the number of allowed Rebalancing::State::MAX_NUMBER_OF_CONCURRENT_REBALANCES is small we should be ok,
+ # but should be something to consider if we'd want to scale this up.
+ error_message = "#{caching.concurrent_running_rebalances_count} concurrent re-balances currently running"
+ raise TooManyConcurrentRebalances, error_message unless caching.can_start_rebalance?
+
+ block_issue_repositioning! unless root_namespace.issue_repositioning_disabled?
+ caching.track_new_running_rebalance
+ index = caching.get_current_index
+
+ loop do
+ issue_ids = get_issue_ids(index, PREFETCH_ISSUES_BATCH_SIZE)
+ pairs_with_index = assign_indexes(issue_ids, index)
+
+ pairs_with_index.each_slice(UPDATE_BATCH_SIZE) do |pairs_batch|
+ update_positions_with_retry(pairs_batch, 're-balance issue positions in batches ordered by position')
+ end
+
+ index = caching.get_current_index
+
+ break if index >= caching.issue_count - 1
+ end
+
+ caching.cleanup_cache
+ unblock_issue_repositioning!
+ end
+
+ private
+
+ attr_reader :root_namespace, :projects_collection, :caching
+
+ def block_issue_repositioning!
+ Feature.enable(:block_issue_repositioning, root_namespace)
+ end
+
+ def unblock_issue_repositioning!
+ Feature.disable(:block_issue_repositioning, root_namespace)
+ end
+
+ def get_issue_ids(index, limit)
+ issue_ids = caching.get_cached_issue_ids(index, limit)
+
+ # if we have a list of cached issues and no current project id cached,
+ # then we successfully cached issues for all projects
+ return issue_ids if issue_ids.any? && caching.get_current_project_id.blank?
+
+ # if we got no issue ids at the start of re-balancing then we did not cache any issue ids yet
+ preload_issue_ids
+
+ caching.get_cached_issue_ids(index, limit)
+ end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def preload_issue_ids
+ index = 0
+ cached_project_id = caching.get_current_project_id
+
+ collection = projects_collection
+ collection = projects_collection.where(Project.arel_table[:id].gteq(cached_project_id.to_i)) if cached_project_id.present?
+
+ collection.each do |project|
+ caching.cache_current_project_id(project.id)
+ index += 1
+ scope = Issue.in_projects(project).reorder(custom_reorder).select(:id, :relative_position)
+
+ with_retry(PREFETCH_ISSUES_BATCH_SIZE, 100) do |batch_size|
+ Gitlab::Pagination::Keyset::Iterator.new(scope: scope).each_batch(of: batch_size) do |batch|
+ caching.cache_issue_ids(batch)
+ end
+ end
+ end
+
+ caching.remove_current_project_id_cache
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ def assign_indexes(ids, start_index)
+ ids.each_with_index.map do |id, idx|
+ [id, start_index + idx]
+ end
+ end
+
+ # The method runs in a loop where we try for RETRIES_LIMIT=3 times, to run the update statement on
+ # a number of records(batch size). Method gets an array of (id, value) pairs as argument that is used
+ # to build the update query matching by id and updating relative_position = value. If we get a statement
+ # timeout, we split the batch size in half and try(for 3 times again) to batch update on a smaller number of records.
+ # On success, because we know the batch size and we always pick from the beginning of the array param,
+ # we can remove first batch_size number of items from array and continue with the successful batch_size for next batches.
+ # On failures we continue to split batch size to a SMALLEST_BATCH_SIZE limit, which is now set at 5.
+ #
+ # e.g.
+ # 0. items | previous batch size|new batch size | comment
+ # 1. 100 | 100 | 100 | 3 failures -> split the batch size in half
+ # 2. 100 | 100 | 50 | 3 failures -> split the batch size in half again
+ # 3. 100 | 50 | 25 | 3 succeed -> so we drop 25 items 3 times, 4th fails -> split the batch size in half again
+ # 5. 25 | 25 | 12 | 3 failures -> split the batch size in half
+ # 6. 25 | 12 | 6 | 3 failures -> we exit because smallest batch size is 5 and we'll be at 3 if we split again
+
+ def update_positions_with_retry(pairs_with_index, query_name)
+ retry_batch_size = pairs_with_index.size
+
+ until pairs_with_index.empty?
+ with_retry(retry_batch_size, SMALLEST_BATCH_SIZE) do |batch_size|
+ retry_batch_size = batch_size
+ update_positions(pairs_with_index.first(batch_size), query_name)
+ # pairs_with_index[batch_size - 1] - can be nil for last batch
+ # if last batch is smaller than batch_size, so we just get the last pair.
+ last_pair_in_batch = pairs_with_index[batch_size - 1] || pairs_with_index.last
+ caching.cache_current_index(last_pair_in_batch.last + 1)
+ pairs_with_index = pairs_with_index.drop(batch_size)
+ end
+ end
+ end
+
+ def update_positions(pairs_with_position, query_name)
+ values = pairs_with_position.map do |id, index|
+ "(#{id}, #{start_position + (index * gap_size)})"
+ end.join(', ')
+
+ run_update_query(values, query_name)
+ end
+
+ def run_update_query(values, query_name)
+ Issue.connection.exec_query(<<~SQL, query_name)
+ WITH cte(cte_id, new_pos) AS #{Gitlab::Database::AsWithMaterialized.materialized_if_supported} (
+ SELECT *
+ FROM (VALUES #{values}) as t (id, pos)
+ )
+ UPDATE #{Issue.table_name}
+ SET relative_position = cte.new_pos
+ FROM cte
+ WHERE cte_id = id
+ SQL
+ end
+
+ def gaps
+ caching.issue_count - 1
+ end
+
+ def gap_size
+ RelativePositioning::MAX_GAP
+ end
+
+ def start_position
+ @start_position ||= (RelativePositioning::START_POSITION - (gaps / 2) * gap_size).to_i
+ end
+
+ def custom_reorder
+ ::Gitlab::Pagination::Keyset::Order.build([Issue.column_order_relative_position, Issue.column_order_id_asc])
+ end
+
+ def with_retry(initial_batch_size, exit_batch_size)
+ retries = 0
+ batch_size = initial_batch_size
+
+ begin
+ yield batch_size
+ retries = 0
+ rescue ActiveRecord::StatementTimeout, ActiveRecord::QueryCanceled => ex
+ raise ex if batch_size < exit_batch_size
+
+ if (retries += 1) == RETRIES_LIMIT
+ # shrink the batch size in half when RETRIES limit is reached and update still fails perhaps because batch size is still too big
+ batch_size = (batch_size / 2).to_i
+ retries = 0
+ end
+
+ retry
+ end
+ end
+ end
+end
diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb
index 9ede5ef728b..d120b007af2 100644
--- a/app/services/issues/update_service.rb
+++ b/app/services/issues/update_service.rb
@@ -26,6 +26,8 @@ module Issues
end
def before_update(issue, skip_spam_check: false)
+ change_work_item_type(issue)
+
return if skip_spam_check
Spam::SpamActionService.new(
@@ -36,6 +38,14 @@ module Issues
).execute
end
+ def change_work_item_type(issue)
+ return unless issue.changed_attributes['issue_type']
+
+ type_id = find_work_item_type_id(issue.issue_type)
+
+ issue.work_item_type_id = type_id
+ end
+
def handle_changes(issue, options)
super
old_associations = options.fetch(:old_associations, {})
@@ -54,29 +64,12 @@ module Issues
end
handle_assignee_changes(issue, old_assignees)
-
- if issue.previous_changes.include?('confidential')
- # don't enqueue immediately to prevent todos removal in case of a mistake
- TodosDestroyer::ConfidentialIssueWorker.perform_in(Todo::WAIT_FOR_DELETE, issue.id) if issue.confidential?
- create_confidentiality_note(issue)
- track_usage_event(:incident_management_incident_change_confidential, current_user.id)
- end
-
- added_labels = issue.labels - old_labels
-
- if added_labels.present?
- notification_service.async.relabeled_issue(issue, added_labels, current_user)
- end
-
+ handle_confidential_change(issue)
+ handle_added_labels(issue, old_labels)
handle_milestone_change(issue)
-
- added_mentions = issue.mentioned_users(current_user) - old_mentioned_users
-
- if added_mentions.present?
- notification_service.async.new_mentions_in_issue(issue, added_mentions, current_user)
- end
-
+ handle_added_mentions(issue, old_mentioned_users)
handle_severity_change(issue, old_severity)
+ handle_issue_type_change(issue)
end
def handle_assignee_changes(issue, old_assignees)
@@ -156,6 +149,23 @@ module Issues
MergeRequests::CreateFromIssueService.new(project: project, current_user: current_user, mr_params: create_merge_request_params).execute
end
+ def handle_confidential_change(issue)
+ if issue.previous_changes.include?('confidential')
+ # don't enqueue immediately to prevent todos removal in case of a mistake
+ TodosDestroyer::ConfidentialIssueWorker.perform_in(Todo::WAIT_FOR_DELETE, issue.id) if issue.confidential?
+ create_confidentiality_note(issue)
+ track_usage_event(:incident_management_incident_change_confidential, current_user.id)
+ end
+ end
+
+ def handle_added_labels(issue, old_labels)
+ added_labels = issue.labels - old_labels
+
+ if added_labels.present?
+ notification_service.async.relabeled_issue(issue, added_labels, current_user)
+ end
+ end
+
def handle_milestone_change(issue)
return unless issue.previous_changes.include?('milestone_id')
@@ -184,6 +194,14 @@ module Issues
end
end
+ def handle_added_mentions(issue, old_mentioned_users)
+ added_mentions = issue.mentioned_users(current_user) - old_mentioned_users
+
+ if added_mentions.present?
+ notification_service.async.new_mentions_in_issue(issue, added_mentions, current_user)
+ end
+ end
+
def handle_severity_change(issue, old_severity)
return unless old_severity && issue.severity != old_severity
@@ -218,6 +236,16 @@ module Issues
def remove_incident_label?(issue)
issue.issue_type != params[:issue_type] && issue.incident?
end
+
+ def handle_issue_type_change(issue)
+ return unless issue.previous_changes.include?('issue_type')
+
+ do_handle_issue_type_change(issue)
+ end
+
+ def do_handle_issue_type_change(issue)
+ SystemNoteService.change_issue_type(issue, current_user)
+ end
end
end
diff --git a/app/services/members/create_service.rb b/app/services/members/create_service.rb
index 3e809b11024..0cc62e661a3 100644
--- a/app/services/members/create_service.rb
+++ b/app/services/members/create_service.rb
@@ -4,9 +4,12 @@ module Members
class CreateService < Members::BaseService
BlankInvitesError = Class.new(StandardError)
TooManyInvitesError = Class.new(StandardError)
+ MembershipLockedError = Class.new(StandardError)
DEFAULT_INVITE_LIMIT = 100
+ attr_reader :membership_locked
+
def initialize(*args)
super
@@ -17,18 +20,22 @@ module Members
def execute
validate_invite_source!
- validate_invites!
+ validate_invitable!
add_members
enqueue_onboarding_progress_action
result
- rescue BlankInvitesError, TooManyInvitesError => e
+ rescue BlankInvitesError, TooManyInvitesError, MembershipLockedError => e
error(e.message)
end
+ def single_member
+ members.last
+ end
+
private
- attr_reader :source, :errors, :invites, :member_created_namespace_id
+ attr_reader :source, :errors, :invites, :member_created_namespace_id, :members
def invites_from_params
params[:user_ids]
@@ -38,7 +45,7 @@ module Members
raise ArgumentError, s_('AddMember|No invite source provided.') unless invite_source.present?
end
- def validate_invites!
+ def validate_invitable!
raise BlankInvitesError, blank_invites_message if invites.blank?
return unless user_limit && invites.size > user_limit
@@ -52,7 +59,7 @@ module Members
end
def add_members
- members = source.add_users(
+ @members = source.add_users(
invites,
params[:access_level],
expires_at: params[:expires_at],
diff --git a/app/services/members/creator_service.rb b/app/services/members/creator_service.rb
index f6972f81162..7b0bebff760 100644
--- a/app/services/members/creator_service.rb
+++ b/app/services/members/creator_service.rb
@@ -12,54 +12,6 @@ module Members
def access_levels
raise NotImplementedError
end
-
- def add_users(source, users, access_level, current_user: nil, expires_at: nil)
- return [] unless users.present?
-
- emails, users, existing_members = parse_users_list(source, users)
-
- Member.transaction do
- (emails + users).map! do |user|
- new(source,
- user,
- access_level,
- existing_members: existing_members,
- current_user: current_user,
- expires_at: expires_at)
- .execute
- end
- end
- end
-
- private
-
- def parse_users_list(source, list)
- emails = []
- user_ids = []
- users = []
- existing_members = {}
-
- list.each do |item|
- case item
- when User
- users << item
- when Integer
- user_ids << item
- when /\A\d+\Z/
- user_ids << item.to_i
- when Devise.email_regexp
- emails << item
- end
- end
-
- if user_ids.present?
- users.concat(User.id_in(user_ids))
- # the below will automatically discard invalid user_ids
- existing_members = source.members_and_requesters.where(user_id: user_ids).index_by(&:user_id) # rubocop:todo CodeReuse/ActiveRecord
- end
-
- [emails, users, existing_members]
- end
end
def initialize(source, user, access_level, **args)
@@ -149,18 +101,10 @@ module Members
end
def find_or_initialize_member_by_user
- if existing_members
- # TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/334062
- # i'm not so sure this is needed as the parse_users_list looks at members_and_requesters...
- # so it is like we could just do a find or initialize by here and be fine
- existing_members[user.id] || source.members.build(user_id: user.id)
- else
- source.members_and_requesters.find_or_initialize_by(user_id: user.id) # rubocop:todo CodeReuse/ActiveRecord
- end
- end
-
- def existing_members
- args[:existing_members]
+ # have to use members and requesters here since project/group limits on requested_at being nil for members and
+ # wouldn't be found in `source.members` if it already existed
+ # this of course will not treat active invites the same since we aren't searching on email
+ source.members_and_requesters.find_or_initialize_by(user_id: user.id) # rubocop:disable CodeReuse/ActiveRecord
end
def ldap
diff --git a/app/services/members/groups/bulk_creator_service.rb b/app/services/members/groups/bulk_creator_service.rb
new file mode 100644
index 00000000000..57cec241584
--- /dev/null
+++ b/app/services/members/groups/bulk_creator_service.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+module Members
+ module Groups
+ class BulkCreatorService < Members::Groups::CreatorService
+ include Members::BulkCreateUsers
+ end
+ end
+end
diff --git a/app/services/members/invite_service.rb b/app/services/members/invite_service.rb
index 6298943977b..257a986b8dd 100644
--- a/app/services/members/invite_service.rb
+++ b/app/services/members/invite_service.rb
@@ -18,7 +18,7 @@ module Members
params[:email]
end
- def validate_invites!
+ def validate_invitable!
super
# we need the below due to add_users hitting Members::CreatorService.parse_users_list and ignoring invalid emails
diff --git a/app/services/members/mailgun.rb b/app/services/members/mailgun.rb
new file mode 100644
index 00000000000..43fb5a14ef1
--- /dev/null
+++ b/app/services/members/mailgun.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+module Members
+ module Mailgun
+ INVITE_EMAIL_TAG = 'invite_email'
+ INVITE_EMAIL_TOKEN_KEY = :invite_token
+ end
+end
diff --git a/app/services/members/mailgun/process_webhook_service.rb b/app/services/members/mailgun/process_webhook_service.rb
new file mode 100644
index 00000000000..e359a83ad42
--- /dev/null
+++ b/app/services/members/mailgun/process_webhook_service.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module Members
+ module Mailgun
+ class ProcessWebhookService
+ ProcessWebhookServiceError = Class.new(StandardError)
+
+ def initialize(payload)
+ @payload = payload
+ end
+
+ def execute
+ @member = Member.find_by_invite_token(invite_token)
+ update_member_and_log if member
+ rescue ProcessWebhookServiceError => e
+ Gitlab::ErrorTracking.track_exception(e)
+ end
+
+ private
+
+ attr_reader :payload, :member
+
+ def update_member_and_log
+ log_update_event if member.update(invite_email_success: false)
+ end
+
+ def log_update_event
+ Gitlab::AppLogger.info "UPDATED MEMBER INVITE_EMAIL_SUCCESS: member_id: #{member.id}"
+ end
+
+ def invite_token
+ # may want to validate schema in some way using ::JSONSchemer.schema(SCHEMA_PATH).valid?(message) if this
+ # gets more complex
+ payload.dig('user-variables', ::Members::Mailgun::INVITE_EMAIL_TOKEN_KEY) ||
+ raise(ProcessWebhookServiceError, "Failed to receive #{::Members::Mailgun::INVITE_EMAIL_TOKEN_KEY} in user-variables: #{payload}")
+ end
+ end
+ end
+end
diff --git a/app/services/members/projects/bulk_creator_service.rb b/app/services/members/projects/bulk_creator_service.rb
new file mode 100644
index 00000000000..68e71e35d12
--- /dev/null
+++ b/app/services/members/projects/bulk_creator_service.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+module Members
+ module Projects
+ class BulkCreatorService < Members::Projects::CreatorService
+ include Members::BulkCreateUsers
+ end
+ end
+end
diff --git a/app/services/merge_requests/merge_to_ref_service.rb b/app/services/merge_requests/merge_to_ref_service.rb
index eda652c4b9a..8519cbac3cb 100644
--- a/app/services/merge_requests/merge_to_ref_service.rb
+++ b/app/services/merge_requests/merge_to_ref_service.rb
@@ -13,12 +13,12 @@ module MergeRequests
class MergeToRefService < MergeRequests::MergeBaseService
extend ::Gitlab::Utils::Override
- def execute(merge_request)
+ def execute(merge_request, cache_merge_to_ref_calls = false)
@merge_request = merge_request
error_check!
- commit_id = commit
+ commit_id = commit(cache_merge_to_ref_calls)
raise_error('Conflicts detected during merge') unless commit_id
@@ -65,8 +65,8 @@ module MergeRequests
params[:allow_conflicts] || false
end
- def commit
- if Feature.enabled?(:cache_merge_to_ref_calls, project, default_enabled: false)
+ def commit(cache_merge_to_ref_calls = false)
+ if cache_merge_to_ref_calls
Rails.cache.fetch(cache_key, expires_in: 1.day) do
extracted_merge_to_ref
end
diff --git a/app/services/merge_requests/mergeability_check_service.rb b/app/services/merge_requests/mergeability_check_service.rb
index 3e294aeaa07..c3498c5ce97 100644
--- a/app/services/merge_requests/mergeability_check_service.rb
+++ b/app/services/merge_requests/mergeability_check_service.rb
@@ -157,7 +157,9 @@ module MergeRequests
def merge_to_ref
params = { allow_conflicts: Feature.enabled?(:display_merge_conflicts_in_diff, project) }
- result = MergeRequests::MergeToRefService.new(project: project, current_user: merge_request.author, params: params).execute(merge_request)
+ result = MergeRequests::MergeToRefService
+ .new(project: project, current_user: merge_request.author, params: params)
+ .execute(merge_request, true)
result[:status] == :success
end
diff --git a/app/services/merge_requests/squash_service.rb b/app/services/merge_requests/squash_service.rb
index 31c49b3ae70..102f78c6a9b 100644
--- a/app/services/merge_requests/squash_service.rb
+++ b/app/services/merge_requests/squash_service.rb
@@ -2,8 +2,6 @@
module MergeRequests
class SquashService < MergeRequests::BaseService
- SquashInProgressError = Class.new(RuntimeError)
-
def execute
# If performing a squash would result in no change, then
# immediately return a success message without performing a squash
@@ -13,14 +11,7 @@ module MergeRequests
return error(s_('MergeRequests|This project does not allow squashing commits when merge requests are accepted.')) if squash_forbidden?
- if squash_in_progress?
- return error(s_('MergeRequests|Squash task canceled: another squash is already in progress.'))
- end
-
squash! || error(s_('MergeRequests|Failed to squash. Should be done manually.'))
-
- rescue SquashInProgressError
- error(s_('MergeRequests|An error occurred while checking whether another squash is in progress.'))
end
private
@@ -35,14 +26,6 @@ module MergeRequests
false
end
- def squash_in_progress?
- merge_request.squash_in_progress?
- rescue StandardError => e
- log_error(exception: e, message: 'Failed to check squash in progress')
-
- raise SquashInProgressError, e.message
- end
-
def squash_forbidden?
target_project.squash_never?
end
diff --git a/app/services/packages/composer/version_parser_service.rb b/app/services/packages/composer/version_parser_service.rb
index 36275d1b680..516c306d2a5 100644
--- a/app/services/packages/composer/version_parser_service.rb
+++ b/app/services/packages/composer/version_parser_service.rb
@@ -12,18 +12,19 @@ module Packages
if @tag_name.present?
@tag_name.delete_prefix('v')
elsif @branch_name.present?
- branch_sufix_or_prefix(@branch_name.match(Gitlab::Regex.composer_package_version_regex))
+ branch_suffix_or_prefix(@branch_name.match(Gitlab::Regex.composer_package_version_regex))
end
end
private
- def branch_sufix_or_prefix(match)
+ def branch_suffix_or_prefix(match)
if match
- if match.captures[1] == '.x'
- match.captures[0] + '-dev'
+ captures = match.captures.reject(&:blank?)
+ if captures[-1] == '.x'
+ captures[0] + '-dev'
else
- match.captures[0] + '.x-dev'
+ captures[0] + '.x-dev'
end
else
"dev-#{@branch_name}"
diff --git a/app/services/packages/create_package_service.rb b/app/services/packages/create_package_service.rb
index 3dc06497d9f..7e1b6ecbe51 100644
--- a/app/services/packages/create_package_service.rb
+++ b/app/services/packages/create_package_service.rb
@@ -5,15 +5,19 @@ module Packages
protected
def find_or_create_package!(package_type, name: params[:name], version: params[:version])
+ # safe_find_or_create_by! was originally called here.
+ # We merely switched to `find_or_create_by!`
+ # rubocop: disable CodeReuse/ActiveRecord
project
.packages
.with_package_type(package_type)
- .safe_find_or_create_by!(name: name, version: version) do |package|
+ .find_or_create_by!(name: name, version: version) do |package|
package.status = params[:status] if params[:status]
package.creator = package_creator
add_build_info(package)
end
+ # rubocop: enable CodeReuse/ActiveRecord
end
def create_package!(package_type, attrs = {})
diff --git a/app/services/packages/generic/create_package_file_service.rb b/app/services/packages/generic/create_package_file_service.rb
index 42a191fb415..78c97000654 100644
--- a/app/services/packages/generic/create_package_file_service.rb
+++ b/app/services/packages/generic/create_package_file_service.rb
@@ -29,7 +29,8 @@ module Packages
package.update_column(:status, params[:status]) if params[:status] && params[:status] != package.status
- package.build_infos.safe_find_or_create_by!(pipeline: params[:build].pipeline) if params[:build].present?
+ package.create_build_infos!(params[:build])
+
package
end
diff --git a/app/services/packages/maven/find_or_create_package_service.rb b/app/services/packages/maven/find_or_create_package_service.rb
index c7ffd468864..b29adf4e11a 100644
--- a/app/services/packages/maven/find_or_create_package_service.rb
+++ b/app/services/packages/maven/find_or_create_package_service.rb
@@ -51,7 +51,7 @@ module Packages
.execute
end
- package.build_infos.safe_find_or_create_by!(pipeline: params[:build].pipeline) if params[:build].present?
+ package.create_build_infos!(params[:build])
ServiceResponse.success(payload: { package: package })
end
diff --git a/app/services/packages/nuget/update_package_from_metadata_service.rb b/app/services/packages/nuget/update_package_from_metadata_service.rb
index 6ffe4f097f4..d1e47ad00a1 100644
--- a/app/services/packages/nuget/update_package_from_metadata_service.rb
+++ b/app/services/packages/nuget/update_package_from_metadata_service.rb
@@ -21,11 +21,7 @@ module Packages
try_obtain_lease do
@package_file.transaction do
- if use_new_package_file_updater?
- new_execute
- else
- legacy_execute
- end
+ process_package_update
end
end
rescue ActiveRecord::RecordInvalid => e
@@ -34,7 +30,7 @@ module Packages
private
- def new_execute
+ def process_package_update
package_to_destroy = nil
target_package = @package_file.package
@@ -50,36 +46,11 @@ module Packages
end
update_package(target_package)
-
::Packages::UpdatePackageFileService.new(@package_file, package_id: target_package.id, file_name: package_filename)
.execute
-
package_to_destroy&.destroy!
end
- def legacy_execute
- if existing_package
- package = link_to_existing_package
- elsif symbol_package?
- raise InvalidMetadataError, 'symbol package is invalid, matching package does not exist'
- else
- package = update_linked_package
- end
-
- update_package(package)
-
- # Updating file_name updates the path where the file is stored.
- # We must pass the file again so that CarrierWave can handle the update
- @package_file.update!(
- file_name: package_filename,
- file: @package_file.file
- )
- end
-
- def use_new_package_file_updater?
- ::Feature.enabled?(:packages_nuget_new_package_file_updater, @package_file.project, default_enabled: :yaml)
- end
-
def update_package(package)
return if symbol_package?
diff --git a/app/services/pages/delete_service.rb b/app/services/pages/delete_service.rb
index f7d3d70aad6..8d33e6c1000 100644
--- a/app/services/pages/delete_service.rb
+++ b/app/services/pages/delete_service.rb
@@ -12,9 +12,6 @@ module Pages
PagesDomain.for_project(project).delete_all
DestroyPagesDeploymentsWorker.perform_async(project.id)
-
- # TODO: remove this call https://gitlab.com/gitlab-org/gitlab/-/issues/320775
- PagesRemoveWorker.perform_async(project.id) if ::Settings.pages.local_store.enabled
end
end
end
diff --git a/app/services/pages/legacy_storage_lease.rb b/app/services/pages/legacy_storage_lease.rb
deleted file mode 100644
index 1849def0183..00000000000
--- a/app/services/pages/legacy_storage_lease.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-module Pages
- module LegacyStorageLease
- extend ActiveSupport::Concern
-
- include ::ExclusiveLeaseGuard
-
- LEASE_TIMEOUT = 1.hour
-
- def lease_key
- "pages_legacy_storage:#{project.id}"
- end
-
- def lease_timeout
- LEASE_TIMEOUT
- end
- end
-end
diff --git a/app/services/pages/migrate_legacy_storage_to_deployment_service.rb b/app/services/pages/migrate_legacy_storage_to_deployment_service.rb
index 95c7107eb62..9c1671fbc15 100644
--- a/app/services/pages/migrate_legacy_storage_to_deployment_service.rb
+++ b/app/services/pages/migrate_legacy_storage_to_deployment_service.rb
@@ -2,10 +2,7 @@
module Pages
class MigrateLegacyStorageToDeploymentService
- ExclusiveLeaseTakenError = Class.new(StandardError)
-
include BaseServiceUtility
- include ::Pages::LegacyStorageLease
attr_reader :project
@@ -16,18 +13,6 @@ module Pages
end
def execute
- result = try_obtain_lease do
- execute_unsafe
- end
-
- raise ExclusiveLeaseTakenError, "Can't migrate pages for project #{project.id}: exclusive lease taken" if result.nil?
-
- result
- end
-
- private
-
- def execute_unsafe
zip_result = ::Pages::ZipDirectoryService.new(project.pages_path, ignore_invalid_entries: @ignore_invalid_entries).execute
if zip_result[:status] == :error
diff --git a/app/services/projects/batch_count_service.rb b/app/services/projects/batch_count_service.rb
index aec3b32da89..455c7211ab2 100644
--- a/app/services/projects/batch_count_service.rb
+++ b/app/services/projects/batch_count_service.rb
@@ -9,13 +9,19 @@ module Projects
@projects = projects
end
- def refresh_cache
- @projects.each do |project|
- service = count_service.new(project)
- unless service.count_stored?
- service.refresh_cache { global_count[project.id].to_i }
+ def refresh_cache_and_retrieve_data
+ count_services = @projects.map { |project| count_service.new(project) }
+ services_by_cache_key = count_services.index_by(&:cache_key)
+
+ results = Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands do
+ Rails.cache.fetch_multi(*services_by_cache_key.keys) do |key|
+ service = services_by_cache_key[key]
+
+ global_count[service.project.id].to_i
end
end
+
+ results.transform_keys! { |cache_key| services_by_cache_key[cache_key].project }
end
def project_ids
diff --git a/app/services/projects/batch_forks_count_service.rb b/app/services/projects/batch_forks_count_service.rb
index d12772b40ff..6467744a435 100644
--- a/app/services/projects/batch_forks_count_service.rb
+++ b/app/services/projects/batch_forks_count_service.rb
@@ -5,21 +5,6 @@
# because the service use maps to retrieve the project ids
module Projects
class BatchForksCountService < Projects::BatchCountService
- def refresh_cache_and_retrieve_data
- count_services = @projects.map { |project| count_service.new(project) }
-
- values = Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands do
- Rails.cache.fetch_multi(*(count_services.map { |ser| ser.cache_key } )) { |key| nil }
- end
-
- results_per_service = Hash[count_services.zip(values.values)]
- projects_to_refresh = results_per_service.select { |_k, value| value.nil? }
- projects_to_refresh = recreate_cache(projects_to_refresh)
-
- results_per_service.update(projects_to_refresh)
- results_per_service.transform_keys { |k| k.project }
- end
-
# rubocop: disable CodeReuse/ActiveRecord
def global_count
@global_count ||= begin
@@ -33,13 +18,5 @@ module Projects
def count_service
::Projects::ForksCountService
end
-
- def recreate_cache(projects_to_refresh)
- projects_to_refresh.each_with_object({}) do |(service, _v), hash|
- count = global_count[service.project.id].to_i
- service.refresh_cache { count }
- hash[service] = count
- end
- end
end
end
diff --git a/app/services/projects/count_service.rb b/app/services/projects/count_service.rb
index 3cee80c7bbc..5daea3a2600 100644
--- a/app/services/projects/count_service.rb
+++ b/app/services/projects/count_service.rb
@@ -9,6 +9,8 @@ module Projects
# all caches.
VERSION = 1
+ attr_reader :project
+
def initialize(project)
@project = project
end
diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb
index 302c047a65f..e717491b19d 100644
--- a/app/services/projects/create_service.rb
+++ b/app/services/projects/create_service.rb
@@ -12,6 +12,7 @@ module Projects
@import_data = @params.delete(:import_data)
@relations_block = @params.delete(:relations_block)
@default_branch = @params.delete(:default_branch)
+ @readme_template = @params.delete(:readme_template)
build_topics
end
@@ -89,10 +90,14 @@ module Projects
def after_create_actions
log_info("#{@project.owner.name} created a new project \"#{@project.full_name}\"")
- # Skip writing the config for project imports/forks because it
- # will always fail since the Git directory doesn't exist until
- # a background job creates it (see Project#add_import_job).
- @project.set_full_path unless @project.import?
+ if @project.import?
+ experiment(:combined_registration, user: current_user).track(:import_project)
+ else
+ # Skip writing the config for project imports/forks because it
+ # will always fail since the Git directory doesn't exist until
+ # a background job creates it (see Project#add_import_job).
+ @project.set_full_path
+ end
unless @project.gitlab_project_import?
@project.create_wiki unless skip_wiki?
@@ -149,12 +154,16 @@ module Projects
branch_name: @default_branch.presence || @project.default_branch_or_main,
commit_message: 'Initial commit',
file_path: 'README.md',
- file_content: experiment(:new_project_readme_content, namespace: @project.namespace).run_with(@project)
+ file_content: readme_content
}
Files::CreateService.new(@project, current_user, commit_attrs).execute
end
+ def readme_content
+ @readme_template.presence || experiment(:new_project_readme_content, namespace: @project.namespace).run_with(@project)
+ end
+
def skip_wiki?
!@project.feature_available?(:wiki, current_user) || @skip_wiki
end
diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb
index 3cee1b5975a..74b7d18f401 100644
--- a/app/services/projects/fork_service.rb
+++ b/app/services/projects/fork_service.rb
@@ -61,7 +61,8 @@ module Projects
# initializing the project, as that would cause a foreign key constraint
# exception.
relations_block: -> (project) { build_fork_network_member(project) },
- skip_disk_validation: skip_disk_validation
+ skip_disk_validation: skip_disk_validation,
+ external_authorization_classification_label: @project.external_authorization_classification_label
}
if @project.avatar.present? && @project.avatar.image?
diff --git a/app/services/projects/forks_count_service.rb b/app/services/projects/forks_count_service.rb
index 848d8d54104..ca85e2dc281 100644
--- a/app/services/projects/forks_count_service.rb
+++ b/app/services/projects/forks_count_service.rb
@@ -3,8 +3,6 @@
module Projects
# Service class for getting and caching the number of forks of a project.
class ForksCountService < Projects::CountService
- attr_reader :project
-
def cache_key_name
'forks_count'
end
diff --git a/app/services/projects/group_links/destroy_service.rb b/app/services/projects/group_links/destroy_service.rb
index 01a5b617b46..19df0dc2c73 100644
--- a/app/services/projects/group_links/destroy_service.rb
+++ b/app/services/projects/group_links/destroy_service.rb
@@ -13,19 +13,15 @@ module Projects
end
group_link.destroy.tap do |link|
- if Feature.enabled?(:use_specialized_worker_for_project_auth_recalculation)
- refresh_project_authorizations_asynchronously(link.project)
+ refresh_project_authorizations_asynchronously(link.project)
- # Until we compare the inconsistency rates of the new specialized worker and
- # the old approach, we still run AuthorizedProjectsWorker
- # but with some delay and lower urgency as a safety net.
- link.group.refresh_members_authorized_projects(
- blocking: false,
- priority: UserProjectAccessChangedService::LOW_PRIORITY
- )
- else
- link.group.refresh_members_authorized_projects
- end
+ # Until we compare the inconsistency rates of the new specialized worker and
+ # the old approach, we still run AuthorizedProjectsWorker
+ # but with some delay and lower urgency as a safety net.
+ link.group.refresh_members_authorized_projects(
+ blocking: false,
+ priority: UserProjectAccessChangedService::LOW_PRIORITY
+ )
end
end
diff --git a/app/services/projects/move_deploy_keys_projects_service.rb b/app/services/projects/move_deploy_keys_projects_service.rb
index 51d84af249e..98ba5eb3f13 100644
--- a/app/services/projects/move_deploy_keys_projects_service.rb
+++ b/app/services/projects/move_deploy_keys_projects_service.rb
@@ -5,7 +5,7 @@ module Projects
def execute(source_project, remove_remaining_elements: true)
return unless super
- Project.transaction(requires_new: true) do
+ Project.transaction do
move_deploy_keys_projects
remove_remaining_deploy_keys_projects if remove_remaining_elements
diff --git a/app/services/projects/move_forks_service.rb b/app/services/projects/move_forks_service.rb
index 33f0bab12c9..a96cf4dd3ea 100644
--- a/app/services/projects/move_forks_service.rb
+++ b/app/services/projects/move_forks_service.rb
@@ -5,7 +5,7 @@ module Projects
def execute(source_project, remove_remaining_elements: true)
return unless super && source_project.fork_network
- Project.transaction(requires_new: true) do
+ Project.transaction do
move_fork_network_members
update_root_project
refresh_forks_count
diff --git a/app/services/projects/move_lfs_objects_projects_service.rb b/app/services/projects/move_lfs_objects_projects_service.rb
index 57a8d3d69c6..7107ecc6c95 100644
--- a/app/services/projects/move_lfs_objects_projects_service.rb
+++ b/app/services/projects/move_lfs_objects_projects_service.rb
@@ -5,7 +5,7 @@ module Projects
def execute(source_project, remove_remaining_elements: true)
return unless super
- Project.transaction(requires_new: true) do
+ Project.transaction do
move_lfs_objects_projects
remove_remaining_lfs_objects_project if remove_remaining_elements
diff --git a/app/services/projects/move_notification_settings_service.rb b/app/services/projects/move_notification_settings_service.rb
index efe06f158cc..fb84f10207d 100644
--- a/app/services/projects/move_notification_settings_service.rb
+++ b/app/services/projects/move_notification_settings_service.rb
@@ -5,7 +5,7 @@ module Projects
def execute(source_project, remove_remaining_elements: true)
return unless super
- Project.transaction(requires_new: true) do
+ Project.transaction do
move_notification_settings
remove_remaining_notification_settings if remove_remaining_elements
diff --git a/app/services/projects/move_project_authorizations_service.rb b/app/services/projects/move_project_authorizations_service.rb
index c95ad60ab5e..6ac173a20fc 100644
--- a/app/services/projects/move_project_authorizations_service.rb
+++ b/app/services/projects/move_project_authorizations_service.rb
@@ -9,7 +9,7 @@ module Projects
def execute(source_project, remove_remaining_elements: true)
return unless super
- Project.transaction(requires_new: true) do
+ Project.transaction do
move_project_authorizations
remove_remaining_authorizations if remove_remaining_elements
diff --git a/app/services/projects/move_project_group_links_service.rb b/app/services/projects/move_project_group_links_service.rb
index 349953ff973..5f6a7dd09e1 100644
--- a/app/services/projects/move_project_group_links_service.rb
+++ b/app/services/projects/move_project_group_links_service.rb
@@ -9,7 +9,7 @@ module Projects
def execute(source_project, remove_remaining_elements: true)
return unless super
- Project.transaction(requires_new: true) do
+ Project.transaction do
move_group_links
remove_remaining_project_group_links if remove_remaining_elements
diff --git a/app/services/projects/move_project_members_service.rb b/app/services/projects/move_project_members_service.rb
index 9a1b7c6d1b6..011bd17c8cc 100644
--- a/app/services/projects/move_project_members_service.rb
+++ b/app/services/projects/move_project_members_service.rb
@@ -9,7 +9,7 @@ module Projects
def execute(source_project, remove_remaining_elements: true)
return unless super
- Project.transaction(requires_new: true) do
+ Project.transaction do
move_project_members
remove_remaining_members if remove_remaining_elements
diff --git a/app/services/projects/move_users_star_projects_service.rb b/app/services/projects/move_users_star_projects_service.rb
index 20121d429e2..5490448553f 100644
--- a/app/services/projects/move_users_star_projects_service.rb
+++ b/app/services/projects/move_users_star_projects_service.rb
@@ -9,7 +9,7 @@ module Projects
return unless user_stars.any?
- Project.transaction(requires_new: true) do
+ Project.transaction do
user_stars.update_all(project_id: @project.id)
Project.reset_counters @project.id, :users_star_projects
diff --git a/app/services/projects/open_issues_count_service.rb b/app/services/projects/open_issues_count_service.rb
index dc450311db2..8b7a418edf5 100644
--- a/app/services/projects/open_issues_count_service.rb
+++ b/app/services/projects/open_issues_count_service.rb
@@ -7,8 +7,12 @@ module Projects
include Gitlab::Utils::StrongMemoize
# Cache keys used to store issues count
- PUBLIC_COUNT_KEY = 'public_open_issues_count'
- TOTAL_COUNT_KEY = 'total_open_issues_count'
+ # TOTAL_COUNT_KEY includes confidential and hidden issues (admin)
+ # TOTAL_COUNT_WITHOUT_HIDDEN_KEY includes confidential issues but not hidden issues (reporter and above)
+ # PUBLIC_COUNT_WITHOUT_HIDDEN_KEY does not include confidential or hidden issues (guest)
+ TOTAL_COUNT_KEY = 'project_open_issues_including_hidden_count'
+ TOTAL_COUNT_WITHOUT_HIDDEN_KEY = 'project_open_issues_without_hidden_count'
+ PUBLIC_COUNT_WITHOUT_HIDDEN_KEY = 'project_open_public_issues_without_hidden_count'
def initialize(project, user = nil)
@user = user
@@ -16,16 +20,53 @@ module Projects
super(project)
end
+ # rubocop: disable CodeReuse/ActiveRecord
+ def refresh_cache(&block)
+ if block_given?
+ super(&block)
+ else
+ update_cache_for_key(total_count_cache_key) do
+ issues_with_hidden
+ end
+
+ update_cache_for_key(public_count_without_hidden_cache_key) do
+ issues_without_hidden_without_confidential
+ end
+
+ update_cache_for_key(total_count_without_hidden_cache_key) do
+ issues_without_hidden_with_confidential
+ end
+ end
+ end
+
+ private
+
+ def relation_for_count
+ self.class.query(@project, public_only: public_only?, include_hidden: include_hidden?)
+ end
+
def cache_key_name
- public_only? ? PUBLIC_COUNT_KEY : TOTAL_COUNT_KEY
+ if include_hidden?
+ TOTAL_COUNT_KEY
+ elsif public_only?
+ PUBLIC_COUNT_WITHOUT_HIDDEN_KEY
+ else
+ TOTAL_COUNT_WITHOUT_HIDDEN_KEY
+ end
+ end
+
+ def include_hidden?
+ user_is_admin?
end
def public_only?
!user_is_at_least_reporter?
end
- def relation_for_count
- self.class.query(@project, public_only: public_only?)
+ def user_is_admin?
+ strong_memoize(:user_is_admin) do
+ @user&.can_admin_all_resources?
+ end
end
def user_is_at_least_reporter?
@@ -34,46 +75,43 @@ module Projects
end
end
- def public_count_cache_key
- cache_key(PUBLIC_COUNT_KEY)
+ def total_count_without_hidden_cache_key
+ cache_key(TOTAL_COUNT_WITHOUT_HIDDEN_KEY)
+ end
+
+ def public_count_without_hidden_cache_key
+ cache_key(PUBLIC_COUNT_WITHOUT_HIDDEN_KEY)
end
def total_count_cache_key
cache_key(TOTAL_COUNT_KEY)
end
- # rubocop: disable CodeReuse/ActiveRecord
- def refresh_cache(&block)
- if block_given?
- super(&block)
- else
- count_grouped_by_confidential = self.class.query(@project, public_only: false).group(:confidential).count
- public_count = count_grouped_by_confidential[false] || 0
- total_count = public_count + (count_grouped_by_confidential[true] || 0)
+ def issues_with_hidden
+ self.class.query(@project, public_only: false, include_hidden: true).count
+ end
- update_cache_for_key(public_count_cache_key) do
- public_count
- end
+ def issues_without_hidden_without_confidential
+ self.class.query(@project, public_only: true, include_hidden: false).count
+ end
- update_cache_for_key(total_count_cache_key) do
- total_count
- end
- end
+ def issues_without_hidden_with_confidential
+ self.class.query(@project, public_only: false, include_hidden: false).count
end
- # rubocop: enable CodeReuse/ActiveRecord
- # We only show total issues count for reporters
- # which are allowed to view confidential issues
+ # We only show total issues count for admins, who are allowed to view hidden issues.
+ # We also only show issues count including confidential for reporters, who are allowed to view confidential issues.
# This will still show a discrepancy on issues number but should be less than before.
# Check https://gitlab.com/gitlab-org/gitlab-foss/issues/38418 description.
# rubocop: disable CodeReuse/ActiveRecord
- def self.query(projects, public_only: true)
- issues_filtered_by_type = Issue.opened.with_issue_type(Issue::TYPES_FOR_LIST)
- if public_only
- issues_filtered_by_type.public_only.where(project: projects)
+ def self.query(projects, public_only: true, include_hidden: false)
+ if include_hidden
+ Issue.opened.with_issue_type(Issue::TYPES_FOR_LIST).where(project: projects)
+ elsif public_only
+ Issue.public_only.opened.with_issue_type(Issue::TYPES_FOR_LIST).where(project: projects)
else
- issues_filtered_by_type.where(project: projects)
+ Issue.without_hidden.opened.with_issue_type(Issue::TYPES_FOR_LIST).where(project: projects)
end
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/services/projects/operations/update_service.rb b/app/services/projects/operations/update_service.rb
index 51b8e3c6c54..ef74f3e6e7a 100644
--- a/app/services/projects/operations/update_service.rb
+++ b/app/services/projects/operations/update_service.rb
@@ -94,6 +94,7 @@ module Projects
}
}
params[:error_tracking_setting_attributes][:token] = settings[:token] unless /\A\*+\z/.match?(settings[:token]) # Don't update token if we receive masked value
+ params[:error_tracking_setting_attributes][:integrated] = settings[:integrated] unless settings[:integrated].nil?
params
end
diff --git a/app/services/projects/transfer_service.rb b/app/services/projects/transfer_service.rb
index 074550e104d..27376173f07 100644
--- a/app/services/projects/transfer_service.rb
+++ b/app/services/projects/transfer_service.rb
@@ -20,8 +20,16 @@ module Projects
raise TransferError, s_('TransferProject|Please select a new namespace for your project.')
end
- unless allowed_transfer?(current_user, project)
- raise TransferError, s_('TransferProject|Transfer failed, please contact an admin.')
+ if @new_namespace.id == project.namespace_id
+ raise TransferError, s_('TransferProject|Project is already in this namespace.')
+ end
+
+ unless allowed_transfer_project?(current_user, project)
+ raise TransferError, s_("TransferProject|You don't have permission to transfer this project.")
+ end
+
+ unless allowed_to_transfer_to_namespace?(current_user, @new_namespace)
+ raise TransferError, s_("TransferProject|You don't have permission to transfer projects into that namespace.")
end
transfer(project)
@@ -121,11 +129,12 @@ module Projects
Milestones::TransferService.new(current_user, group, project).execute
end
- def allowed_transfer?(current_user, project)
- @new_namespace &&
- can?(current_user, :change_namespace, project) &&
- @new_namespace.id != project.namespace_id &&
- current_user.can?(:transfer_projects, @new_namespace)
+ def allowed_transfer_project?(current_user, project)
+ current_user.can?(:change_namespace, project)
+ end
+
+ def allowed_to_transfer_to_namespace?(current_user, namespace)
+ current_user.can?(:transfer_projects, namespace)
end
def update_namespace_and_visibility(to_namespace)
diff --git a/app/services/projects/update_pages_service.rb b/app/services/projects/update_pages_service.rb
index f96a6ee1255..dc75fe1014a 100644
--- a/app/services/projects/update_pages_service.rb
+++ b/app/services/projects/update_pages_service.rb
@@ -3,18 +3,9 @@
module Projects
class UpdatePagesService < BaseService
InvalidStateError = Class.new(StandardError)
- FailedToExtractError = Class.new(StandardError)
- ExclusiveLeaseTaken = Class.new(StandardError)
-
- include ::Pages::LegacyStorageLease
-
BLOCK_SIZE = 32.kilobytes
PUBLIC_DIR = 'public'
- # this has to be invalid group name,
- # as it shares the namespace with groups
- TMP_EXTRACT_PATH = '@pages.tmp'
-
# old deployment can be cached by pages daemon
# so we need to give pages daemon some time update cache
# 10 minutes is enough, but 30 feels safer
@@ -42,7 +33,6 @@ module Projects
validate_max_entries!
build.artifacts_file.use_file do |artifacts_path|
- deploy_to_legacy_storage(artifacts_path)
create_pages_deployment(artifacts_path, build)
success
end
@@ -78,70 +68,6 @@ module Projects
)
end
- def deploy_to_legacy_storage(artifacts_path)
- # path today used by one project can later be used by another
- # so we can't really scope this feature flag by project or group
- return unless ::Settings.pages.local_store.enabled
-
- return if Feature.enabled?(:skip_pages_deploy_to_legacy_storage, project, default_enabled: :yaml)
-
- # Create temporary directory in which we will extract the artifacts
- make_secure_tmp_dir(tmp_path) do |tmp_path|
- extract_archive!(artifacts_path, tmp_path)
-
- # Check if we did extract public directory
- archive_public_path = File.join(tmp_path, PUBLIC_DIR)
-
- raise InvalidStateError, 'pages miss the public folder' unless Dir.exist?(archive_public_path)
-
- validate_outdated_sha!
-
- deploy_page!(archive_public_path)
- end
- end
-
- def extract_archive!(artifacts_path, temp_path)
- if artifacts.ends_with?('.zip')
- extract_zip_archive!(artifacts_path, temp_path)
- else
- raise InvalidStateError, 'unsupported artifacts format'
- end
- end
-
- def extract_zip_archive!(artifacts_path, temp_path)
- SafeZip::Extract.new(artifacts_path)
- .extract(directories: [PUBLIC_DIR], to: temp_path)
- rescue SafeZip::Extract::Error => e
- raise FailedToExtractError, e.message
- end
-
- def deploy_page!(archive_public_path)
- deployed = try_obtain_lease do
- deploy_page_unsafe!(archive_public_path)
- true
- end
-
- unless deployed
- raise ExclusiveLeaseTaken, "Failed to deploy pages - other deployment is in progress"
- end
- end
-
- def deploy_page_unsafe!(archive_public_path)
- # Do atomic move of pages
- # Move and removal may not be atomic, but they are significantly faster then extracting and removal
- # 1. We move deployed public to previous public path (file removal is slow)
- # 2. We move temporary public to be deployed public
- # 3. We remove previous public path
- FileUtils.mkdir_p(pages_path)
- begin
- FileUtils.move(public_path, previous_public_path)
- rescue StandardError
- end
- FileUtils.move(archive_public_path, public_path)
- ensure
- FileUtils.rm_r(previous_public_path, force: true)
- end
-
def create_pages_deployment(artifacts_path, build)
sha256 = build.job_artifacts_archive.file_sha256
@@ -165,22 +91,6 @@ module Projects
)
end
- def tmp_path
- @tmp_path ||= File.join(::Settings.pages.path, TMP_EXTRACT_PATH)
- end
-
- def pages_path
- @pages_path ||= project.pages_path
- end
-
- def public_path
- @public_path ||= File.join(pages_path, PUBLIC_DIR)
- end
-
- def previous_public_path
- @previous_public_path ||= File.join(pages_path, "#{PUBLIC_DIR}.#{SecureRandom.hex}")
- end
-
def ref
build.ref
end
@@ -216,20 +126,6 @@ module Projects
@pages_deployments_failed_total_counter ||= Gitlab::Metrics.counter(:pages_deployments_failed_total, "Counter of GitLab Pages deployments which failed")
end
- def make_secure_tmp_dir(tmp_path)
- FileUtils.mkdir_p(tmp_path)
- path = Dir.mktmpdir(tmp_dir_prefix, tmp_path)
- begin
- yield(path)
- ensure
- FileUtils.remove_entry_secure(path)
- end
- end
-
- def tmp_dir_prefix
- "project-#{project.id}-build-#{build.id}-"
- end
-
def validate_state!
raise InvalidStateError, 'missing pages artifacts' unless build.artifacts?
raise InvalidStateError, 'missing artifacts metadata' unless build.artifacts_metadata?
diff --git a/app/services/projects/update_service.rb b/app/services/projects/update_service.rb
index d6e7f165d72..b87564fcaef 100644
--- a/app/services/projects/update_service.rb
+++ b/app/services/projects/update_service.rb
@@ -105,6 +105,7 @@ module Projects
end
update_pages_config if changing_pages_related_config?
+ update_pending_builds if shared_runners_toggled?
end
def after_rename_service(project)
@@ -178,6 +179,16 @@ module Projects
params[:topic_list] ||= topic_list if topic_list
end
+
+ def update_pending_builds
+ update_params = { instance_runners_enabled: project.shared_runners_enabled }
+
+ ::Ci::UpdatePendingBuildService.new(project, update_params).execute
+ end
+
+ def shared_runners_toggled?
+ project.previous_changes.include?('shared_runners_enabled')
+ end
end
end
diff --git a/app/services/protected_branches/api_service.rb b/app/services/protected_branches/api_service.rb
index 3e5122a1523..d0d0737fd66 100644
--- a/app/services/protected_branches/api_service.rb
+++ b/app/services/protected_branches/api_service.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module ProtectedBranches
- class ApiService < BaseService
+ class ApiService < ProtectedBranches::BaseService
def create
::ProtectedBranches::CreateService.new(@project, @current_user, protected_branch_params).execute
end
diff --git a/app/services/protected_branches/base_service.rb b/app/services/protected_branches/base_service.rb
new file mode 100644
index 00000000000..f48e02ab4b5
--- /dev/null
+++ b/app/services/protected_branches/base_service.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module ProtectedBranches
+ class BaseService < ::BaseService
+ # current_user - The user that performs the action
+ # params - A hash of parameters
+ def initialize(project, current_user = nil, params = {})
+ @project = project
+ @current_user = current_user
+ @params = params
+ end
+
+ def after_execute(*)
+ # overridden in EE::ProtectedBranches module
+ end
+ end
+end
diff --git a/app/services/protected_branches/create_service.rb b/app/services/protected_branches/create_service.rb
index 37083a4a9e4..dada449989a 100644
--- a/app/services/protected_branches/create_service.rb
+++ b/app/services/protected_branches/create_service.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module ProtectedBranches
- class CreateService < BaseService
+ class CreateService < ProtectedBranches::BaseService
def execute(skip_authorization: false)
raise Gitlab::Access::AccessDeniedError unless skip_authorization || authorized?
diff --git a/app/services/protected_branches/destroy_service.rb b/app/services/protected_branches/destroy_service.rb
index dc177f0ac09..47332ace417 100644
--- a/app/services/protected_branches/destroy_service.rb
+++ b/app/services/protected_branches/destroy_service.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module ProtectedBranches
- class DestroyService < BaseService
+ class DestroyService < ProtectedBranches::BaseService
def execute(protected_branch)
raise Gitlab::Access::AccessDeniedError unless can?(current_user, :destroy_protected_branch, protected_branch)
diff --git a/app/services/protected_branches/update_service.rb b/app/services/protected_branches/update_service.rb
index 1815d92421e..1e70f2d9793 100644
--- a/app/services/protected_branches/update_service.rb
+++ b/app/services/protected_branches/update_service.rb
@@ -1,11 +1,17 @@
# frozen_string_literal: true
module ProtectedBranches
- class UpdateService < BaseService
+ class UpdateService < ProtectedBranches::BaseService
def execute(protected_branch)
raise Gitlab::Access::AccessDeniedError unless can?(current_user, :update_protected_branch, protected_branch)
- protected_branch.update(params)
+ old_merge_access_levels = protected_branch.merge_access_levels.map(&:clone)
+ old_push_access_levels = protected_branch.push_access_levels.map(&:clone)
+
+ if protected_branch.update(params)
+ after_execute(protected_branch: protected_branch, old_merge_access_levels: old_merge_access_levels, old_push_access_levels: old_push_access_levels)
+ end
+
protected_branch
end
end
diff --git a/app/services/repositories/changelog_service.rb b/app/services/repositories/changelog_service.rb
index bac3fdf36da..96db00fbc1b 100644
--- a/app/services/repositories/changelog_service.rb
+++ b/app/services/repositories/changelog_service.rb
@@ -61,7 +61,7 @@ module Repositories
# rubocop: enable Metrics/ParameterLists
def execute
- config = Gitlab::Changelog::Config.from_git(@project)
+ config = Gitlab::Changelog::Config.from_git(@project, @user)
from = start_of_commit_range(config)
# For every entry we want to only include the merge request that
diff --git a/app/services/search/global_service.rb b/app/services/search/global_service.rb
index fe11820fb54..33faf2d6698 100644
--- a/app/services/search/global_service.rb
+++ b/app/services/search/global_service.rb
@@ -24,7 +24,7 @@ module Search
# rubocop: disable CodeReuse/ActiveRecord
def projects
- @projects ||= ProjectsFinder.new(params: { non_archived: true }, current_user: current_user).execute.includes(:topics, :taggings)
+ @projects ||= ProjectsFinder.new(params: { non_archived: true }, current_user: current_user).execute.preload(:topics, :taggings)
end
def allowed_scopes
diff --git a/app/services/service_ping/submit_service.rb b/app/services/service_ping/submit_service.rb
index 09d1670fd1f..3417ce4f583 100644
--- a/app/services/service_ping/submit_service.rb
+++ b/app/services/service_ping/submit_service.rb
@@ -2,8 +2,9 @@
module ServicePing
class SubmitService
- PRODUCTION_URL = 'https://version.gitlab.com/usage_data'
- STAGING_URL = 'https://gitlab-services-version-gitlab-com-staging.gs-staging.gitlab.org/usage_data'
+ PRODUCTION_BASE_URL = 'https://version.gitlab.com'
+ STAGING_BASE_URL = 'https://gitlab-services-version-gitlab-com-staging.gs-staging.gitlab.org'
+ USAGE_DATA_PATH = 'usage_data'
METRICS = %w[leader_issues instance_issues percentage_issues leader_notes instance_notes
percentage_notes leader_milestones instance_milestones percentage_milestones
@@ -41,6 +42,10 @@ module ServicePing
store_metrics(response)
end
+ def url
+ URI.join(base_url, USAGE_DATA_PATH)
+ end
+
private
def submit_payload(usage_data)
@@ -81,12 +86,8 @@ module ServicePing
end
# See https://gitlab.com/gitlab-org/gitlab/-/issues/233615 for details
- def url
- if Rails.env.production?
- PRODUCTION_URL
- else
- STAGING_URL
- end
+ def base_url
+ Rails.env.production? ? PRODUCTION_BASE_URL : STAGING_BASE_URL
end
end
end
diff --git a/app/services/suggestions/apply_service.rb b/app/services/suggestions/apply_service.rb
index 6836700a67d..a0d26e08341 100644
--- a/app/services/suggestions/apply_service.rb
+++ b/app/services/suggestions/apply_service.rb
@@ -33,7 +33,7 @@ module Suggestions
.update_all(commit_id: result[:result], applied: true)
Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter
- .track_apply_suggestion_action(user: current_user)
+ .track_apply_suggestion_action(user: current_user, suggestions: suggestion_set.suggestions)
end
def author
diff --git a/app/services/suggestions/create_service.rb b/app/services/suggestions/create_service.rb
index c5f9fa1eee0..eb98ed57d55 100644
--- a/app/services/suggestions/create_service.rb
+++ b/app/services/suggestions/create_service.rb
@@ -28,7 +28,7 @@ module Suggestions
Gitlab::Database.main.bulk_insert('suggestions', rows) # rubocop:disable Gitlab/BulkInsert
end
- Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter.track_add_suggestion_action(user: @note.author)
+ Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter.track_add_suggestion_action(note: @note)
end
end
end
diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb
index 56a6244eebf..e5080718b69 100644
--- a/app/services/system_note_service.rb
+++ b/app/services/system_note_service.rb
@@ -331,6 +331,10 @@ module SystemNoteService
::SystemNotes::AlertManagementService.new(noteable: alert, project: alert.project).log_resolving_alert(monitoring_tool)
end
+ def change_issue_type(issue, author)
+ ::SystemNotes::IssuablesService.new(noteable: issue, project: issue.project, author: author).change_issue_type
+ end
+
private
def merge_requests_service(noteable, project, author)
diff --git a/app/services/system_notes/issuables_service.rb b/app/services/system_notes/issuables_service.rb
index ae4f65e785c..62aead352aa 100644
--- a/app/services/system_notes/issuables_service.rb
+++ b/app/services/system_notes/issuables_service.rb
@@ -380,6 +380,12 @@ module SystemNotes
create_resource_state_event(status: 'closed', close_auto_resolve_prometheus_alert: true)
end
+ def change_issue_type
+ body = "changed issue type to #{noteable.issue_type.humanize(capitalize: false)}"
+
+ create_note(NoteSummary.new(noteable, project, author, body, action: 'issue_type'))
+ end
+
private
def cross_reference_note_content(gfm_reference)
diff --git a/app/services/todos/destroy/design_service.rb b/app/services/todos/destroy/design_service.rb
new file mode 100644
index 00000000000..a375d659159
--- /dev/null
+++ b/app/services/todos/destroy/design_service.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module Todos
+ module Destroy
+ # Service class for deleting todos that belongs to a deleted/archived design.
+ class DesignService
+ attr_reader :design_ids
+
+ def initialize(design_ids)
+ @design_ids = design_ids
+ end
+
+ def execute
+ todos.delete_all
+ end
+
+ private
+
+ def todos
+ Todo.for_target(deleted_designs.select(:design_id)).for_type(DesignManagement::Design)
+ end
+
+ def deleted_designs
+ DesignManagement::Action.by_design(design_ids).by_event(:deletion)
+ end
+ end
+ end
+end
diff --git a/app/services/users/ban_service.rb b/app/services/users/ban_service.rb
index 88e92ebff9b..959d4be3795 100644
--- a/app/services/users/ban_service.rb
+++ b/app/services/users/ban_service.rb
@@ -8,6 +8,10 @@ module Users
user.ban
end
+ def valid_state?(user)
+ user.active?
+ end
+
def action
:ban
end
diff --git a/app/services/users/banned_user_base_service.rb b/app/services/users/banned_user_base_service.rb
index 16041075941..a582816283a 100644
--- a/app/services/users/banned_user_base_service.rb
+++ b/app/services/users/banned_user_base_service.rb
@@ -8,6 +8,7 @@ module Users
def execute(user)
return permission_error unless allowed?
+ return state_error(user) unless valid_state?(user)
if update_user(user)
log_event(user)
@@ -22,6 +23,10 @@ module Users
attr_reader :current_user
+ def state_error(user)
+ error(_("You cannot %{action} %{state} users." % { action: action.to_s, state: user.state }), :forbidden)
+ end
+
def allowed?
can?(current_user, :admin_all_resources)
end
diff --git a/app/services/users/dismiss_group_callout_service.rb b/app/services/users/dismiss_group_callout_service.rb
new file mode 100644
index 00000000000..8afee6a8187
--- /dev/null
+++ b/app/services/users/dismiss_group_callout_service.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module Users
+ class DismissGroupCalloutService < DismissUserCalloutService
+ private
+
+ def callout
+ current_user.find_or_initialize_group_callout(params[:feature_name], params[:group_id])
+ end
+ end
+end
diff --git a/app/services/users/dismiss_user_callout_service.rb b/app/services/users/dismiss_user_callout_service.rb
index f05c44186bb..96f3f3acb57 100644
--- a/app/services/users/dismiss_user_callout_service.rb
+++ b/app/services/users/dismiss_user_callout_service.rb
@@ -3,9 +3,15 @@
module Users
class DismissUserCalloutService < BaseContainerService
def execute
- current_user.find_or_initialize_callout(params[:feature_name]).tap do |callout|
- callout.update(dismissed_at: Time.current) if callout.valid?
+ callout.tap do |record|
+ record.update(dismissed_at: Time.current) if record.valid?
end
end
+
+ private
+
+ def callout
+ current_user.find_or_initialize_callout(params[:feature_name])
+ end
end
end
diff --git a/app/services/users/migrate_to_ghost_user_service.rb b/app/services/users/migrate_to_ghost_user_service.rb
index a471f55e644..515d7821416 100644
--- a/app/services/users/migrate_to_ghost_user_service.rb
+++ b/app/services/users/migrate_to_ghost_user_service.rb
@@ -14,23 +14,30 @@ module Users
def initialize(user)
@user = user
+ @ghost_user = User.ghost
end
def execute
transition = user.block_transition
- user.transaction do
- # Block the user before moving records to prevent a data race.
- # For example, if the user creates an issue after `migrate_issues`
- # runs and before the user is destroyed, the destroy will fail with
- # an exception.
- user.block
+ # Block the user before moving records to prevent a data race.
+ # For example, if the user creates an issue after `migrate_issues`
+ # runs and before the user is destroyed, the destroy will fail with
+ # an exception.
+ user.block
+ begin
+ user.transaction do
+ migrate_records
+ end
+ rescue Exception # rubocop:disable Lint/RescueException
# Reverse the user block if record migration fails
- if !migrate_records_in_transaction && transition
+ if transition
transition.rollback
user.save!
end
+
+ raise
end
user.reset
@@ -38,14 +45,6 @@ module Users
private
- def migrate_records_in_transaction
- user.transaction(requires_new: true) do
- @ghost_user = User.ghost
-
- migrate_records
- end
- end
-
def migrate_records
migrate_issues
migrate_merge_requests
diff --git a/app/services/users/reject_service.rb b/app/services/users/reject_service.rb
index 833c30d9427..459dd81b74d 100644
--- a/app/services/users/reject_service.rb
+++ b/app/services/users/reject_service.rb
@@ -7,8 +7,8 @@ module Users
end
def execute(user)
- return error(_('You are not allowed to reject a user')) unless allowed?
- return error(_('This user does not have a pending request')) unless user.blocked_pending_approval?
+ return error(_('You are not allowed to reject a user'), :forbidden) unless allowed?
+ return error(_('User does not have a pending request'), :conflict) unless user.blocked_pending_approval?
user.delete_async(deleted_by: current_user, params: { hard_delete: true })
@@ -18,7 +18,7 @@ module Users
log_event(user)
- success
+ success(message: 'Success', http_status: :ok)
end
private
diff --git a/app/services/users/unban_service.rb b/app/services/users/unban_service.rb
index 363783cf240..753a02fa752 100644
--- a/app/services/users/unban_service.rb
+++ b/app/services/users/unban_service.rb
@@ -5,7 +5,11 @@ module Users
private
def update_user(user)
- user.activate
+ user.unban
+ end
+
+ def valid_state?(user)
+ user.banned?
end
def action
diff --git a/app/services/wiki_pages/event_create_service.rb b/app/services/wiki_pages/event_create_service.rb
index ebfc2414f9e..1f613bec00e 100644
--- a/app/services/wiki_pages/event_create_service.rb
+++ b/app/services/wiki_pages/event_create_service.rb
@@ -10,11 +10,9 @@ module WikiPages
end
def execute(slug, page, action, event_fingerprint)
- event = Event.transaction do
- wiki_page_meta = WikiPage::Meta.find_or_create(slug, page)
+ wiki_page_meta = WikiPage::Meta.find_or_create(slug, page)
- ::EventCreateService.new.wiki_event(wiki_page_meta, author, action, event_fingerprint)
- end
+ event = ::EventCreateService.new.wiki_event(wiki_page_meta, author, action, event_fingerprint)
ServiceResponse.success(payload: { event: event })
rescue ::EventCreateService::IllegalActionError, ::ActiveRecord::ActiveRecordError => e
diff --git a/app/validators/gitlab/utils/zoom_url_validator.rb b/app/validators/gitlab/utils/zoom_url_validator.rb
deleted file mode 100644
index 57e30dcefa6..00000000000
--- a/app/validators/gitlab/utils/zoom_url_validator.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-# Gitlab::Utils::ZoomUrlValidator
-#
-# Custom validator for zoom urls
-#
-module Gitlab
- module Utils
- class ZoomUrlValidator < ActiveModel::EachValidator
- ALLOWED_SCHEMES = %w(https).freeze
-
- def validate_each(record, attribute, value)
- links_count = Gitlab::ZoomLinkExtractor.new(value).links.size
- valid = Gitlab::UrlSanitizer.valid?(value, allowed_schemes: ALLOWED_SCHEMES)
-
- return if links_count == 1 && valid
-
- record.errors.add(:url, 'must contain one valid Zoom URL')
- end
- end
- end
-end
diff --git a/app/validators/gitlab/zoom_url_validator.rb b/app/validators/gitlab/zoom_url_validator.rb
new file mode 100644
index 00000000000..c752cec07c2
--- /dev/null
+++ b/app/validators/gitlab/zoom_url_validator.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module Gitlab
+ # Gitlab::Utils::ZoomUrlValidator
+ #
+ # Custom validator for zoom urls
+ #
+ # @example usage
+ # validates :url, 'gitlab/zoom_url': true
+ class ZoomUrlValidator < ActiveModel::EachValidator
+ ALLOWED_SCHEMES = %w(https).freeze
+
+ def validate_each(record, attribute, value)
+ links_count = Gitlab::ZoomLinkExtractor.new(value).links.size
+ valid = Gitlab::UrlSanitizer.valid?(value, allowed_schemes: ALLOWED_SCHEMES)
+
+ return if links_count == 1 && valid
+
+ record.errors.add(:url, 'must contain one valid Zoom URL')
+ end
+ end
+end
diff --git a/app/validators/json_schemas/cluster_agent_authorization_configuration.json b/app/validators/json_schemas/cluster_agent_authorization_configuration.json
new file mode 100644
index 00000000000..f3de0b7043b
--- /dev/null
+++ b/app/validators/json_schemas/cluster_agent_authorization_configuration.json
@@ -0,0 +1,6 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "description": "Cluster Agent configuration for an authorized project or group",
+ "type": "object",
+ "additionalProperties": true
+}
diff --git a/app/validators/json_schemas/dast_profile_schedule_cadence.json b/app/validators/json_schemas/dast_profile_schedule_cadence.json
new file mode 100644
index 00000000000..5583acfa5af
--- /dev/null
+++ b/app/validators/json_schemas/dast_profile_schedule_cadence.json
@@ -0,0 +1,31 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "description": "Dast profile schedule cadence schema",
+ "type": "object",
+ "anyOf": [
+ {
+ "properties": {
+ "unit": { "enum": ["day"] },
+ "duration": { "enum": [1] }
+ }
+ },
+ {
+ "properties": {
+ "unit": { "enum": ["week"] },
+ "duration": { "enum": [1] }
+ }
+ },
+ {
+ "properties": {
+ "unit": { "enum": ["month"] },
+ "duration": { "enum": [1, 3 ,6] }
+ }
+ },
+ {
+ "properties": {
+ "unit": { "enum": ["year"] },
+ "duration": { "enum": [1] }
+ }
+ }
+ ]
+}
diff --git a/app/validators/json_schemas/error_tracking_event_payload.json b/app/validators/json_schemas/error_tracking_event_payload.json
index 19abde7de08..52efcf6800c 100644
--- a/app/validators/json_schemas/error_tracking_event_payload.json
+++ b/app/validators/json_schemas/error_tracking_event_payload.json
@@ -2,161 +2,15 @@
"description": "Error tracking event payload",
"type": "object",
"required": [],
- "modules": {
- "type": "object"
- },
"properties": {
- "event_id": {
- "type": "string"
- },
- "level": {
- "type": "string"
- },
- "timestamp": {
- "type": "string"
- },
- "release": {
- "type": "string"
- },
"environment": {
"type": "string"
},
- "server_name": {
- "type": "string"
- },
- "message": {
- "type": "string"
- },
- "user": {
- "type": "object",
- "required": [],
- "properties": {}
- },
- "tags": {
- "type": "object",
- "required": [],
- "properties": {
- "request_id": {
- "type": "string"
- }
- }
- },
- "contexts": {
- "type": "object",
- "required": [],
- "properties": {
- "os": {
- "type": "object",
- "required": [],
- "properties": {
- "name": {
- "type": "string"
- },
- "version": {
- "type": "string"
- },
- "build": {
- "type": "string"
- },
- "kernel_version": {
- "type": "string"
- }
- }
- },
- "runtime": {
- "type": "object",
- "required": [],
- "properties": {
- "name": {
- "type": "string"
- },
- "version": {
- "type": "string"
- }
- }
- },
- "trace": {
- "type": "object"
- }
- }
- },
- "fingerprint": {
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "breadcrumbs": {
- "type": "object",
- "required": [],
- "properties": {
- "values": {
- "type": "array",
- "items": {
- "type": "object",
- "required": [],
- "properties": {
- "category": {
- "type": "string"
- },
- "data": {
- "type": "object"
- },
- "message": {
- "type": "string"
- },
- "timestamp": {
- "type": "number"
- }
- }
- }
- }
- }
- },
- "transaction": {
- "type": "string"
- },
"platform": {
"type": "string"
},
"sdk": {
- "type": "object",
- "required": [],
- "properties": {
- "name": {
- "type": "string"
- },
- "version": {
- "type": "string"
- }
- }
- },
- "request": {
- "type": "object",
- "required": [],
- "properties": {
- "url": {
- "type": "string"
- },
- "method": {
- "type": "string"
- },
- "headers": {
- "type": "object"
- },
- "env": {
- "type": "object",
- "required": [],
- "properties": {
- "SERVER_NAME": {
- "type": "string"
- },
- "SERVER_PORT": {
- "type": "string"
- }
- }
- }
- }
+ "type": "object"
},
"exception": {
"type": "object",
diff --git a/app/views/admin/application_settings/_ci_cd.html.haml b/app/views/admin/application_settings/_ci_cd.html.haml
index ee97a678aaa..fea116bd419 100644
--- a/app/views/admin/application_settings/_ci_cd.html.haml
+++ b/app/views/admin/application_settings/_ci_cd.html.haml
@@ -41,7 +41,7 @@
= f.label :default_artifacts_expire_in, _('Default artifacts expiration'), class: 'label-bold'
= f.text_field :default_artifacts_expire_in, class: 'form-control gl-form-input'
.form-text.text-muted
- = html_escape(_("The default expiration time for job artifacts. 0 for unlimited. The default unit is in seconds, but you can use other units, for example %{code_open}4 mins 2 sec%{code_close}, %{code_open}2h42min%{code_close}.")) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
+ = html_escape(_("Set the default expiration time for job artifacts in all projects. Set to %{code_open}0%{code_close} to never expire artifacts by default. If no unit is written, it defaults to seconds. For example, these are all equivalent: %{code_open}3600%{code_close}, %{code_open}60 minutes%{code_close}, or %{code_open}one hour%{code_close}.")) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
= link_to _('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'default-artifacts-expiration')
.form-group
.form-check
diff --git a/app/views/admin/application_settings/_eks.html.haml b/app/views/admin/application_settings/_eks.html.haml
index c44bad132bd..c83e28d7f0b 100644
--- a/app/views/admin/application_settings/_eks.html.haml
+++ b/app/views/admin/application_settings/_eks.html.haml
@@ -17,20 +17,20 @@
.form-check
= f.check_box :eks_integration_enabled, class: 'form-check-input'
= f.label :eks_integration_enabled, class: 'form-check-label' do
- Enable Amazon EKS integration
+ = _('Enable Amazon EKS integration')
.form-group
- = f.label :eks_account_id, 'Account ID', class: 'label-bold'
+ = f.label :eks_account_id, _('Account ID'), class: 'label-bold'
= f.text_field :eks_account_id, class: 'form-control gl-form-input'
.form-group
- = f.label :eks_access_key_id, 'Access key ID', class: 'label-bold'
+ = f.label :eks_access_key_id, _('Access key ID'), class: 'label-bold'
= f.text_field :eks_access_key_id, class: 'form-control gl-form-input'
.form-text.text-muted
= _('AWS Access Key. Only required if not using role instance credentials')
.form-group
- = f.label :eks_secret_access_key, 'Secret access key', class: 'label-bold'
+ = f.label :eks_secret_access_key, _('Secret access key'), class: 'label-bold'
= f.password_field :eks_secret_access_key, autocomplete: 'off', class: 'form-control gl-form-input'
.form-text.text-muted
= _('AWS Secret Access Key. Only required if not using role instance credentials')
- = f.submit 'Save changes', class: "gl-button btn btn-confirm"
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_email.html.haml b/app/views/admin/application_settings/_email.html.haml
index 1c35250644d..073c0bf619d 100644
--- a/app/views/admin/application_settings/_email.html.haml
+++ b/app/views/admin/application_settings/_email.html.haml
@@ -33,4 +33,12 @@
.form-text.text-muted
= _('Send emails to help guide new users through the onboarding process.')
+ .form-group
+ .form-check
+ = f.check_box :user_deactivation_emails_enabled, class: 'form-check-input'
+ = f.label :user_deactivation_emails_enabled, class: 'form-check-label' do
+ = _('Enable user deactivation emails')
+ .form-text.text-muted
+ = _('Send emails to users upon account deactivation.')
+
= f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' }
diff --git a/app/views/admin/application_settings/_external_authorization_service_form.html.haml b/app/views/admin/application_settings/_external_authorization_service_form.html.haml
index abd182027b1..23484eaec32 100644
--- a/app/views/admin/application_settings/_external_authorization_service_form.html.haml
+++ b/app/views/admin/application_settings/_external_authorization_service_form.html.haml
@@ -47,4 +47,4 @@
.form-group
= f.label :external_authorization_service_default_label, _('Default classification label'), class: 'label-bold'
= f.text_field :external_authorization_service_default_label, class: 'form-control gl-form-input'
- = f.submit 'Save changes', class: "gl-button btn btn-confirm"
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_files_limits.html.haml b/app/views/admin/application_settings/_files_limits.html.haml
new file mode 100644
index 00000000000..9cd12fa1caa
--- /dev/null
+++ b/app/views/admin/application_settings/_files_limits.html.haml
@@ -0,0 +1,34 @@
+= gitlab_ui_form_for @application_setting, url: network_admin_application_settings_path(anchor: 'js-files-limits-settings'), html: { class: 'fieldset-form' } do |f|
+ = form_errors(@application_setting)
+
+ %fieldset
+ %legend.h5.gl-border-none
+ = _('Unauthenticated API request rate limit')
+ .form-group
+ = f.gitlab_ui_checkbox_component :throttle_unauthenticated_files_api_enabled,
+ _('Enable unauthenticated API request rate limit'),
+ help_text: _('Helps reduce request volume (e.g. from crawlers or abusive bots)'),
+ checkbox_options: { data: { qa_selector: 'throttle_unauthenticated_files_api_checkbox' } }
+ .form-group
+ = f.label :throttle_unauthenticated_files_api_requests_per_period, 'Max unauthenticated API requests per period per IP', class: 'label-bold'
+ = f.number_field :throttle_unauthenticated_files_api_requests_per_period, class: 'form-control gl-form-input'
+ .form-group
+ = f.label :throttle_unauthenticated_files_api_period_in_seconds, 'Unauthenticated API rate limit period in seconds', class: 'label-bold'
+ = f.number_field :throttle_unauthenticated_files_api_period_in_seconds, class: 'form-control gl-form-input'
+
+ %fieldset
+ %legend.h5.gl-border-none
+ = _('Authenticated API request rate limit')
+ .form-group
+ = f.gitlab_ui_checkbox_component :throttle_authenticated_files_api_enabled,
+ _('Enable authenticated API request rate limit'),
+ help_text: _('Helps reduce request volume (e.g. from crawlers or abusive bots)'),
+ checkbox_options: { data: { qa_selector: 'throttle_authenticated_files_api_checkbox' } }
+ .form-group
+ = f.label :throttle_authenticated_files_api_requests_per_period, 'Max authenticated API requests per period per user', class: 'label-bold'
+ = f.number_field :throttle_authenticated_files_api_requests_per_period, class: 'form-control gl-form-input'
+ .form-group
+ = f.label :throttle_authenticated_files_api_period_in_seconds, 'Authenticated API rate limit period in seconds', class: 'label-bold'
+ = f.number_field :throttle_authenticated_files_api_period_in_seconds, class: 'form-control gl-form-input'
+
+ = f.submit 'Save changes', class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' }
diff --git a/app/views/admin/application_settings/_floc.html.haml b/app/views/admin/application_settings/_floc.html.haml
index 398064f9730..52833b5cfc2 100644
--- a/app/views/admin/application_settings/_floc.html.haml
+++ b/app/views/admin/application_settings/_floc.html.haml
@@ -19,4 +19,4 @@
.form-check
= f.check_box :floc_enabled, class: 'form-check-input'
= f.label :floc_enabled, s_('FloC|Enable FloC (Federated Learning of Cohorts)'), class: 'form-check-label'
- = f.submit s_('Save changes'), class: 'gl-button btn btn-confirm'
+ = f.submit _('Save changes'), class: 'gl-button btn btn-confirm'
diff --git a/app/views/admin/application_settings/_git_lfs_limits.html.haml b/app/views/admin/application_settings/_git_lfs_limits.html.haml
new file mode 100644
index 00000000000..de5a2ceaa3d
--- /dev/null
+++ b/app/views/admin/application_settings/_git_lfs_limits.html.haml
@@ -0,0 +1,21 @@
+= form_for @application_setting, url: network_admin_application_settings_path(anchor: 'js-git-lfs-limits-settings'), html: { class: 'fieldset-form' } do |f|
+ = form_errors(@application_setting)
+
+ %fieldset
+ %h5
+ = _('Authenticated Git LFS request rate limit')
+ .form-group
+ .form-check
+ = f.check_box :throttle_authenticated_git_lfs_enabled, class: 'form-check-input', data: { qa_selector: 'throttle_authenticated_git_lfs_checkbox' }
+ = f.label :throttle_authenticated_git_lfs_enabled, class: 'form-check-label gl-font-weight-bold' do
+ = _('Enable authenticated Git LFS request rate limit')
+ %span.form-text.gl-text-gray-600
+ = _('Helps reduce request volume (for example, from crawlers or abusive bots)')
+ .form-group
+ = f.label :throttle_authenticated_git_lfs_requests_per_period, _('Max authenticated Git LFS requests per period per user'), class: 'gl-font-weight-bold'
+ = f.number_field :throttle_authenticated_git_lfs_requests_per_period, class: 'form-control gl-form-input'
+ .form-group
+ = f.label :throttle_authenticated_git_lfs_period_in_seconds, _('Authenticated Git LFS rate limit period in seconds'), class: 'gl-font-weight-bold'
+ = f.number_field :throttle_authenticated_git_lfs_period_in_seconds, class: 'form-control gl-form-input'
+
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' }
diff --git a/app/views/admin/application_settings/_gitpod.html.haml b/app/views/admin/application_settings/_gitpod.html.haml
index c08b41e8c55..8f99a07b87c 100644
--- a/app/views/admin/application_settings/_gitpod.html.haml
+++ b/app/views/admin/application_settings/_gitpod.html.haml
@@ -27,4 +27,4 @@
= s_('Gitpod|The URL to your Gitpod instance configured to read your GitLab projects, such as https://gitpod.example.com.')
- link_start = '<a href="%{url}">'.html_safe % { url: help_page_path('integration/gitpod', anchor: 'enable-gitpod-in-your-user-settings') }
= s_('Gitpod|To use the integration, each user must also enable Gitpod on their GitLab account. %{link_start}How do I enable it?%{link_end} ').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
- = f.submit s_('Save changes'), class: 'gl-button btn btn-confirm'
+ = f.submit _('Save changes'), class: 'gl-button btn btn-confirm'
diff --git a/app/views/admin/application_settings/_import_export_limits.html.haml b/app/views/admin/application_settings/_import_export_limits.html.haml
index 820c11279d5..bc4a1577f90 100644
--- a/app/views/admin/application_settings/_import_export_limits.html.haml
+++ b/app/views/admin/application_settings/_import_export_limits.html.haml
@@ -2,33 +2,37 @@
= form_errors(@application_setting)
%fieldset
+ = html_escape(_("Set any rate limit to %{code_open}0%{code_close} to disable the limit.")) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
+
+
+ %fieldset
.form-group
- = f.label :project_import_limit, _('Max Project Import requests per minute per user'), class: 'label-bold'
+ = f.label :project_import_limit, _('Maximum project import requests per minute'), class: 'label-bold'
= f.number_field :project_import_limit, class: 'form-control gl-form-input'
%fieldset
.form-group
- = f.label :project_export_limit, _('Max Project Export requests per minute per user'), class: 'label-bold'
+ = f.label :project_export_limit, _('Maximum project export requests per minute'), class: 'label-bold'
= f.number_field :project_export_limit, class: 'form-control gl-form-input'
%fieldset
.form-group
- = f.label :project_download_export_limit, _('Max Project Export Download requests per minute per user'), class: 'label-bold'
+ = f.label :project_download_export_limit, _('Maximum project export download requests per minute'), class: 'label-bold'
= f.number_field :project_download_export_limit, class: 'form-control gl-form-input'
%fieldset
.form-group
- = f.label :group_import_limit, _('Max Group Import requests per minute per user'), class: 'label-bold'
+ = f.label :group_import_limit, _('Maximum group import requests per minute'), class: 'label-bold'
= f.number_field :group_import_limit, class: 'form-control gl-form-input'
%fieldset
.form-group
- = f.label :group_export_limit, _('Max Group Export requests per minute per user'), class: 'label-bold'
+ = f.label :group_export_limit, _('Maximum group export requests per minute'), class: 'label-bold'
= f.number_field :group_export_limit, class: 'form-control gl-form-input'
%fieldset
.form-group
- = f.label :group_download_export_limit, _('Max Group Export Download requests per minute per user'), class: 'label-bold'
+ = f.label :group_download_export_limit, _('Maximum group export download requests per minute'), class: 'label-bold'
= f.number_field :group_download_export_limit, class: 'form-control gl-form-input'
- = f.submit 'Save changes', class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' }
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' }
diff --git a/app/views/admin/application_settings/_initial_branch_name.html.haml b/app/views/admin/application_settings/_initial_branch_name.html.haml
index 34c40892467..8832bc02056 100644
--- a/app/views/admin/application_settings/_initial_branch_name.html.haml
+++ b/app/views/admin/application_settings/_initial_branch_name.html.haml
@@ -1,4 +1,4 @@
-= form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-default-branch-name'), html: { class: 'fieldset-form' } do |f|
+= form_for @application_setting, url: repository_admin_application_settings_path(anchor: 'js-default-branch-name'), html: { class: 'fieldset-form' } do |f|
= form_errors(@application_setting)
- fallback_branch_name = "<code>#{Gitlab::DefaultBranch.value}</code>"
diff --git a/app/views/admin/application_settings/_ip_limits.html.haml b/app/views/admin/application_settings/_ip_limits.html.haml
index e584aaf9880..4362ae9cb9b 100644
--- a/app/views/admin/application_settings/_ip_limits.html.haml
+++ b/app/views/admin/application_settings/_ip_limits.html.haml
@@ -1,60 +1,69 @@
-= form_for @application_setting, url: network_admin_application_settings_path(anchor: 'js-ip-limits-settings'), html: { class: 'fieldset-form' } do |f|
+= gitlab_ui_form_for @application_setting, url: network_admin_application_settings_path(anchor: 'js-ip-limits-settings'), html: { class: 'fieldset-form' } do |f|
= form_errors(@application_setting)
%fieldset
- %h5
- = _('Unauthenticated request rate limit')
+ = _("Rate limits can help reduce request volume (like from crawlers or abusive bots).")
+
+ %fieldset
+ .form-group
+ = f.gitlab_ui_checkbox_component :throttle_unauthenticated_api_enabled,
+ _("Enable unauthenticated API request rate limit"),
+ checkbox_options: { data: { qa_selector: 'throttle_unauthenticated_api_checkbox' } },
+ label_options: { class: 'label-bold' }
.form-group
- .form-check
- = f.check_box :throttle_unauthenticated_enabled, class: 'form-check-input', data: { qa_selector: 'throttle_unauthenticated_checkbox' }
- = f.label :throttle_unauthenticated_enabled, class: 'form-check-label label-bold' do
- = _("Enable unauthenticated request rate limit")
- %span.form-text.text-muted
- = _("Helps reduce request volume (e.g. from crawlers or abusive bots)")
+ = f.label :throttle_unauthenticated_api_requests_per_period, _('Maximum unauthenticated API requests per rate limit period per IP'), class: 'label-bold'
+ = f.number_field :throttle_unauthenticated_api_requests_per_period, class: 'form-control gl-form-input'
.form-group
- = f.label :throttle_unauthenticated_requests_per_period, _('Max unauthenticated requests per period per IP'), class: 'label-bold'
+ = f.label :throttle_unauthenticated_api_period_in_seconds, _('Unauthenticated API rate limit period in seconds'), class: 'label-bold'
+ = f.number_field :throttle_unauthenticated_api_period_in_seconds, class: 'form-control gl-form-input'
+
+ %fieldset
+ .form-group
+ = f.gitlab_ui_checkbox_component :throttle_unauthenticated_enabled,
+ _("Enable unauthenticated web request rate limit"),
+ checkbox_options: { data: { qa_selector: 'throttle_unauthenticated_web_checkbox' } },
+ label_options: { class: 'label-bold' }
+ .form-group
+ = f.label :throttle_unauthenticated_requests_per_period, _('Maximum unauthenticated web requests per rate limit period per IP'), class: 'label-bold'
= f.number_field :throttle_unauthenticated_requests_per_period, class: 'form-control gl-form-input'
.form-group
- = f.label :throttle_unauthenticated_period_in_seconds, _('Unauthenticated rate limit period in seconds'), class: 'label-bold'
+ = f.label :throttle_unauthenticated_period_in_seconds, _('Unauthenticated web rate limit period in seconds'), class: 'label-bold'
= f.number_field :throttle_unauthenticated_period_in_seconds, class: 'form-control gl-form-input'
- %hr
- %h5
- = _('Authenticated API request rate limit')
- .form-group
- .form-check
- = f.check_box :throttle_authenticated_api_enabled, class: 'form-check-input', data: { qa_selector: 'throttle_authenticated_api_checkbox' }
- = f.label :throttle_authenticated_api_enabled, class: 'form-check-label label-bold' do
- = _("Enable authenticated API request rate limit")
- %span.form-text.text-muted
- = _("Helps reduce request volume (e.g. from crawlers or abusive bots)")
- .form-group
- = f.label :throttle_authenticated_api_requests_per_period, _('Max authenticated API requests per period per user'), class: 'label-bold'
+
+ %fieldset
+ .form-group
+ = f.gitlab_ui_checkbox_component :throttle_authenticated_api_enabled,
+ _("Enable authenticated API request rate limit"),
+ checkbox_options: { data: { qa_selector: 'throttle_authenticated_api_checkbox' }},
+ label_options: { class: 'label-bold' }
+ .form-group
+ = f.label :throttle_authenticated_api_requests_per_period, _('Maximum authenticated API requests per rate limit period per user'), class: 'label-bold'
= f.number_field :throttle_authenticated_api_requests_per_period, class: 'form-control gl-form-input'
.form-group
= f.label :throttle_authenticated_api_period_in_seconds, _('Authenticated API rate limit period in seconds'), class: 'label-bold'
= f.number_field :throttle_authenticated_api_period_in_seconds, class: 'form-control gl-form-input'
- %hr
- %h5
- = _('Authenticated web request rate limit')
- .form-group
- .form-check
- = f.check_box :throttle_authenticated_web_enabled, class: 'form-check-input', data: { qa_selector: 'throttle_authenticated_web_checkbox' }
- = f.label :throttle_authenticated_web_enabled, class: 'form-check-label label-bold' do
- Enable authenticated web request rate limit
- %span.form-text.text-muted
- Helps reduce request volume (e.g. from crawlers or abusive bots)
- .form-group
- = f.label :throttle_authenticated_web_requests_per_period, _('Max authenticated web requests per period per user'), class: 'label-bold'
+
+ %fieldset
+ .form-group
+ = f.gitlab_ui_checkbox_component :throttle_authenticated_web_enabled,
+ _("Enable authenticated web request rate limit"),
+ checkbox_options: { data: { qa_selector: 'throttle_authenticated_web_checkbox' } },
+ label_options: { class: 'label-bold' }
+ .form-group
+ = f.label :throttle_authenticated_web_requests_per_period, _('Maximum authenticated web requests per rate limit period per user'), class: 'label-bold'
= f.number_field :throttle_authenticated_web_requests_per_period, class: 'form-control gl-form-input'
.form-group
= f.label :throttle_authenticated_web_period_in_seconds, _('Authenticated web rate limit period in seconds'), class: 'label-bold'
= f.number_field :throttle_authenticated_web_period_in_seconds, class: 'form-control gl-form-input'
- %hr
- %h5
+
+ %fieldset
+ %legend.h5.gl-border-none
= _('Response text')
.form-group
= f.label :rate_limiting_response_text, class: 'label-bold' do
- = _('A plain-text response to show to clients that hit the rate limit.')
+ = _('Plain-text response to send to clients that hit a rate limit')
= f.text_area :rate_limiting_response_text, placeholder: ::Gitlab::Throttle::DEFAULT_RATE_LIMITING_RESPONSE_TEXT, class: 'form-control gl-form-input', rows: 5
+ .form-text.text-muted
+ = html_escape(_("If blank, defaults to %{code_open}Retry later%{code_close}.")) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
= f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' }
diff --git a/app/views/admin/application_settings/_issue_limits.html.haml b/app/views/admin/application_settings/_issue_limits.html.haml
index 0e1ba8c9c88..663e1485749 100644
--- a/app/views/admin/application_settings/_issue_limits.html.haml
+++ b/app/views/admin/application_settings/_issue_limits.html.haml
@@ -6,4 +6,4 @@
= f.label :issues_create_limit, 'Max requests per minute per user', class: 'label-bold'
= f.number_field :issues_create_limit, class: 'form-control gl-form-input'
- = f.submit 'Save changes', class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' }
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' }
diff --git a/app/views/admin/application_settings/_mailgun.html.haml b/app/views/admin/application_settings/_mailgun.html.haml
index 6204f7df5dc..40b4d5cac6d 100644
--- a/app/views/admin/application_settings/_mailgun.html.haml
+++ b/app/views/admin/application_settings/_mailgun.html.haml
@@ -1,5 +1,3 @@
-- return unless Feature.enabled?(:mailgun_events_receiver)
-
- expanded = integration_expanded?('mailgun_')
%section.settings.as-mailgun.no-animate#js-mailgun-settings{ class: ('expanded' if expanded) }
.settings-header
diff --git a/app/views/admin/application_settings/_note_limits.html.haml b/app/views/admin/application_settings/_note_limits.html.haml
index d50b3395d8f..eb6122f244a 100644
--- a/app/views/admin/application_settings/_note_limits.html.haml
+++ b/app/views/admin/application_settings/_note_limits.html.haml
@@ -3,10 +3,13 @@
%fieldset
.form-group
- = f.label :notes_create_limit, _('Max requests per minute per user'), class: 'label-bold'
+ = f.label :notes_create_limit, _('Maximum requests per minute'), class: 'label-bold'
= f.number_field :notes_create_limit, class: 'form-control gl-form-input'
.form-group
- = f.label :notes_create_limit_allowlist, _('List of users to be excluded from the limit'), class: 'label-bold'
+ = f.label :notes_create_limit_allowlist, _('Users to exclude from the rate limit'), class: 'label-bold'
= f.text_area :notes_create_limit_allowlist_raw, placeholder: 'username1, username2', class: 'form-control gl-form-input', rows: 5
+ .form-text.text-muted
+ = _('Comma-separated list of users allowed to exceed the rate limit.')
+
= f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' }
diff --git a/app/views/admin/application_settings/_outbound.html.haml b/app/views/admin/application_settings/_outbound.html.haml
index d8d105293a1..142a3fbfbd0 100644
--- a/app/views/admin/application_settings/_outbound.html.haml
+++ b/app/views/admin/application_settings/_outbound.html.haml
@@ -27,4 +27,4 @@
%span.form-text.text-muted
= _('Resolves IP addresses once and uses them to submit requests')
- = f.submit 'Save changes', class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' }
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' }
diff --git a/app/views/admin/application_settings/_package_registry_limits.html.haml b/app/views/admin/application_settings/_package_registry_limits.html.haml
index b1dfd04c55e..8769171c9e0 100644
--- a/app/views/admin/application_settings/_package_registry_limits.html.haml
+++ b/app/views/admin/application_settings/_package_registry_limits.html.haml
@@ -2,36 +2,31 @@
= form_errors(@application_setting)
%fieldset
- %h5
- = _('Unauthenticated API request rate limit')
+ = _("The package registry rate limits can help reduce request volume (like from crawlers or abusive bots).")
+
+ %fieldset
.form-group
.form-check
= f.check_box :throttle_unauthenticated_packages_api_enabled, class: 'form-check-input', data: { qa_selector: 'throttle_unauthenticated_packages_api_checkbox' }
= f.label :throttle_unauthenticated_packages_api_enabled, class: 'form-check-label label-bold' do
= _('Enable unauthenticated API request rate limit')
- %span.form-text.text-muted
- = _('Helps reduce request volume (e.g. from crawlers or abusive bots)')
.form-group
- = f.label :throttle_unauthenticated_packages_api_requests_per_period, 'Max unauthenticated API requests per period per IP', class: 'label-bold'
+ = f.label :throttle_unauthenticated_packages_api_requests_per_period, _('Maximum unauthenticated API requests per rate limit period per IP'), class: 'label-bold'
= f.number_field :throttle_unauthenticated_packages_api_requests_per_period, class: 'form-control gl-form-input'
.form-group
- = f.label :throttle_unauthenticated_packages_api_period_in_seconds, 'Unauthenticated API rate limit period in seconds', class: 'label-bold'
+ = f.label :throttle_unauthenticated_packages_api_period_in_seconds, _('Unauthenticated API rate limit period in seconds'), class: 'label-bold'
= f.number_field :throttle_unauthenticated_packages_api_period_in_seconds, class: 'form-control gl-form-input'
%hr
- %h5
- = _('Authenticated API request rate limit')
.form-group
.form-check
= f.check_box :throttle_authenticated_packages_api_enabled, class: 'form-check-input', data: { qa_selector: 'throttle_authenticated_packages_api_checkbox' }
= f.label :throttle_authenticated_packages_api_enabled, class: 'form-check-label label-bold' do
= _('Enable authenticated API request rate limit')
- %span.form-text.text-muted
- = _('Helps reduce request volume (e.g. from crawlers or abusive bots)')
.form-group
- = f.label :throttle_authenticated_packages_api_requests_per_period, 'Max authenticated API requests per period per user', class: 'label-bold'
+ = f.label :throttle_authenticated_packages_api_requests_per_period, _('Maximum authenticated API requests per rate limit period per user'), class: 'label-bold'
= f.number_field :throttle_authenticated_packages_api_requests_per_period, class: 'form-control gl-form-input'
.form-group
- = f.label :throttle_authenticated_packages_api_period_in_seconds, 'Authenticated API rate limit period in seconds', class: 'label-bold'
+ = f.label :throttle_authenticated_packages_api_period_in_seconds, _('Authenticated API rate limit period in seconds'), class: 'label-bold'
= f.number_field :throttle_authenticated_packages_api_period_in_seconds, class: 'form-control gl-form-input'
- = f.submit 'Save changes', class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' }
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' }
diff --git a/app/views/admin/application_settings/_protected_paths.html.haml b/app/views/admin/application_settings/_protected_paths.html.haml
index faa675f211d..04b42f42014 100644
--- a/app/views/admin/application_settings/_protected_paths.html.haml
+++ b/app/views/admin/application_settings/_protected_paths.html.haml
@@ -28,4 +28,4 @@
= _('All paths are relative to the GitLab URL. Do not include %{relative_url_link_start}relative URL%{relative_url_link_end}.').html_safe % { relative_url_link_start: relative_url_link_start, relative_url_link_end: '</a>'.html_safe }
= f.text_area :protected_paths_raw, placeholder: '/users/sign_in,/users/password', class: 'form-control gl-form-input', rows: 10
- = f.submit 'Save changes', class: 'gl-button btn btn-confirm'
+ = f.submit _('Save changes'), class: 'gl-button btn btn-confirm'
diff --git a/app/views/admin/application_settings/_sidekiq_job_limits.html.haml b/app/views/admin/application_settings/_sidekiq_job_limits.html.haml
new file mode 100644
index 00000000000..eaf4bbf4702
--- /dev/null
+++ b/app/views/admin/application_settings/_sidekiq_job_limits.html.haml
@@ -0,0 +1,21 @@
+= form_for @application_setting, url: preferences_admin_application_settings_path(anchor: 'js-sidekiq-job-limits-settings'), html: { class: 'fieldset-form' } do |f|
+ = form_errors(@application_setting)
+
+ %fieldset
+ .form-group
+ = f.label :sidekiq_job_limiter_mode, _('Limiting mode'), class: 'label-bold'
+ = f.select :sidekiq_job_limiter_mode, sidekiq_job_limiter_modes_for_select, {}, class: 'form-control'
+ .form-text.text-muted
+ = sidekiq_job_limiter_mode_help_text
+ .form-group
+ = f.label :sidekiq_job_limiter_compression_threshold_bytes, _('Sidekiq job compression threshold (bytes)'), class: 'label-bold'
+ = f.number_field :sidekiq_job_limiter_compression_threshold_bytes, class: 'form-control gl-form-input'
+ .form-text.text-muted
+ = _('Threshold in bytes at which to compress Sidekiq job arguments.')
+ .form-group
+ = f.label :sidekiq_job_limiter_limit_bytes, _('Sidekiq job size limit (bytes)'), class: 'label-bold'
+ = f.number_field :sidekiq_job_limiter_limit_bytes, class: 'form-control gl-form-input'
+ .form-text.text-muted
+ = _("Threshold in bytes at which to reject Sidekiq jobs. Set this to 0 to if you don't want to limit Sidekiq jobs.")
+
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/network.html.haml b/app/views/admin/application_settings/network.html.haml
index 0e9dcb23dcb..8dff2bc36cb 100644
--- a/app/views/admin/application_settings/network.html.haml
+++ b/app/views/admin/application_settings/network.html.haml
@@ -16,24 +16,49 @@
%section.settings.as-ip-limits.no-animate#js-ip-limits-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'ip_limits_content' } }
.settings-header
%h4
- = _('User and IP Rate Limits')
+ = _('User and IP rate limits')
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = _('Configure limits for web and API requests.')
+ = _('Set limits for web and API requests.')
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/user_and_ip_rate_limits.md'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= render 'ip_limits'
%section.settings.as-packages-limits.no-animate#js-packages-limits-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'packages_limits_content' } }
.settings-header
%h4
- = _('Package Registry Rate Limits')
+ = _('Package registry rate limits')
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = _('Configure specific limits for Packages API requests that supersede the general user and IP rate limits.')
+ = _('Set rate limits for package registry API requests that supersede the general user and IP rate limits.')
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/package_registry_rate_limits.md'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= render 'package_registry_limits'
+- if Feature.enabled?(:files_api_throttling, default_enabled: :yaml)
+ %section.settings.as-files-limits.no-animate#js-files-limits-settings{ class: ('expanded' if expanded_by_default?), data: { testid: 'files-limits-settings' } }
+ .settings-header
+ %h4
+ = _('Files API Rate Limits')
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Configure specific limits for Files API requests that supersede the general user and IP rate limits.')
+ .settings-content
+ = render 'files_limits'
+
+%section.settings.as-git-lfs-limits.no-animate#js-git-lfs-limits-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'git_lfs_limits_content' } }
+ .settings-header
+ %h4
+ = _('Git LFS Rate Limits')
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Configure specific limits for Git LFS requests that supersede the general user and IP rate limits.')
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/git_lfs_rate_limits.md'), target: '_blank', rel: 'noopener noreferrer'
+ .settings-content
+ = render 'git_lfs_limits'
%section.settings.as-outbound.no-animate#js-outbound-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'outbound_requests_content' } }
.settings-header
@@ -76,22 +101,24 @@
%section.settings.as-note-limits.no-animate#js-note-limits-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
- = _('Notes Rate Limits')
+ = _('Notes rate limit')
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = _('Configure limit for notes created per minute by web and API requests.')
+ = _('Set the per-user rate limit for notes created by web or API requests.')
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/rate_limit_on_notes_creation.md'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= render 'note_limits'
%section.settings.as-import-export-limits.no-animate#js-import-export-limits-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
- = _('Import/Export Rate Limits')
+ = _('Import and export rate limits')
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = _('Configure limits for Project/Group Import/Export.')
+ = _('Set per-user rate limits for imports and exports of projects and groups.')
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/import_export_rate_limits.md'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= render 'import_export_limits'
diff --git a/app/views/admin/application_settings/preferences.html.haml b/app/views/admin/application_settings/preferences.html.haml
index 9711c335802..af4bfd28a01 100644
--- a/app/views/admin/application_settings/preferences.html.haml
+++ b/app/views/admin/application_settings/preferences.html.haml
@@ -82,3 +82,17 @@
= _('Configure the default first day of the week and time tracking units.')
.settings-content
= render 'localization'
+
+%section.settings.as-sidekiq-job-limits.no-animate#js-sidekiq-job-limits-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Sidekiq job size limits')
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Limit the size of Sidekiq jobs stored in Redis.')
+ %span
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/sidekiq_job_limits.md'), target: '_blank', rel: 'noopener noreferrer'
+
+ .settings-content
+ = render 'sidekiq_job_limits'
diff --git a/app/views/admin/applications/_form.html.haml b/app/views/admin/applications/_form.html.haml
index 74eda21d5bd..a1990ad5750 100644
--- a/app/views/admin/applications/_form.html.haml
+++ b/app/views/admin/applications/_form.html.haml
@@ -33,6 +33,14 @@
%span.form-text.text-muted
= _('The application will be used where the client secret can be kept confidential. Native mobile apps and Single Page Apps are considered non-confidential.')
+ = content_tag :div, class: 'form-group row' do
+ .col-sm-2.col-form-label.pt-0
+ = f.label :expire_access_tokens
+ .col-sm-10
+ = f.check_box :expire_access_tokens
+ %span.form-text.text-muted
+ = _('Access tokens expire after 2 hours. A refresh token may be used at any time to generate a new access token. Non-expiring access tokens are deprecated. Clear this setting to enable backward compatibility.')
+
.form-group.row
.col-sm-2.col-form-label.pt-0
= f.label :scopes
diff --git a/app/views/admin/applications/edit.html.haml b/app/views/admin/applications/edit.html.haml
index 4f737a14e12..42f7f6c3d66 100644
--- a/app/views/admin/applications/edit.html.haml
+++ b/app/views/admin/applications/edit.html.haml
@@ -2,6 +2,7 @@
- breadcrumb_title @application.name
- page_title _("Edit"), @application.name, _("Applications")
-%h3.page-title Edit application
+%h3.page-title
+ = _('Edit application')
- @url = admin_application_path(@application)
= render 'form', application: @application
diff --git a/app/views/admin/background_migrations/_migration.html.haml b/app/views/admin/background_migrations/_migration.html.haml
index ddb2eb27705..4a7c0083bc7 100644
--- a/app/views/admin/background_migrations/_migration.html.haml
+++ b/app/views/admin/background_migrations/_migration.html.haml
@@ -17,3 +17,7 @@
= button_to resume_admin_background_migration_path(migration),
class: 'gl-button btn btn-icon has-tooltip', title: _('Resume'), 'aria-label' => _('Resume') do
= sprite_icon('play', css_class: 'gl-button-icon gl-icon')
+ - elsif migration.failed?
+ = button_to retry_admin_background_migration_path(migration),
+ class: 'gl-button btn btn-icon has-tooltip', title: _('Retry'), 'aria-label' => _('Retry') do
+ = sprite_icon('retry', css_class: 'gl-button-icon gl-icon')
diff --git a/app/views/admin/deploy_keys/new.html.haml b/app/views/admin/deploy_keys/new.html.haml
index b0b12a01aed..fe2bc8530f7 100644
--- a/app/views/admin/deploy_keys/new.html.haml
+++ b/app/views/admin/deploy_keys/new.html.haml
@@ -7,4 +7,4 @@
= render partial: 'shared/deploy_keys/form', locals: { form: f, deploy_key: @deploy_key }
.form-actions
= f.submit 'Create', class: 'btn gl-button btn-confirm', data: { qa_selector: "add_deploy_key_button" }
- = link_to 'Cancel', admin_deploy_keys_path, class: 'btn gl-button btn-default btn-cancel'
+ = link_to _('Cancel'), admin_deploy_keys_path, class: 'btn gl-button btn-default btn-cancel'
diff --git a/app/views/admin/identities/edit.html.haml b/app/views/admin/identities/edit.html.haml
index fa09138c502..0fd1f2f547f 100644
--- a/app/views/admin/identities/edit.html.haml
+++ b/app/views/admin/identities/edit.html.haml
@@ -1,6 +1,6 @@
-- add_to_breadcrumbs "Users", admin_users_path
+- add_to_breadcrumbs _('Users'), admin_users_path
- add_to_breadcrumbs @user.name, admin_user_identities_path(@user)
-- breadcrumb_title "Edit Identity"
+- breadcrumb_title _('Edit Identity')
- page_title _("Edit"), @identity.provider, _("Identities"), @user.name, _("Users")
%h3.page-title
= _('Edit identity for %{user_name}') % { user_name: @user.name }
diff --git a/app/views/admin/identities/index.html.haml b/app/views/admin/identities/index.html.haml
index d85ab476693..3b3042b5506 100644
--- a/app/views/admin/identities/index.html.haml
+++ b/app/views/admin/identities/index.html.haml
@@ -1,4 +1,4 @@
-- add_to_breadcrumbs "Users", admin_users_path
+- add_to_breadcrumbs _('Users'), admin_users_path
- breadcrumb_title @user.name
- page_title _("Identities"), @user.name, _("Users")
= render 'admin/users/head'
diff --git a/app/views/admin/identities/new.html.haml b/app/views/admin/identities/new.html.haml
index c28d22625b5..b4f37057c51 100644
--- a/app/views/admin/identities/new.html.haml
+++ b/app/views/admin/identities/new.html.haml
@@ -1,7 +1,7 @@
-- add_to_breadcrumbs "Users", admin_users_path
+- add_to_breadcrumbs _('Users'), admin_users_path
- add_to_breadcrumbs @user.name, admin_user_identities_path(@user)
-- breadcrumb_title "New Identity"
-- page_title _("New Identity")
+- breadcrumb_title _('New Identity')
+- page_title _('New Identity')
%h3.page-title= _('New identity')
%hr
= render 'form'
diff --git a/app/views/admin/impersonation_tokens/index.html.haml b/app/views/admin/impersonation_tokens/index.html.haml
index 1609687fc8d..26fbba83a32 100644
--- a/app/views/admin/impersonation_tokens/index.html.haml
+++ b/app/views/admin/impersonation_tokens/index.html.haml
@@ -1,4 +1,4 @@
-- add_to_breadcrumbs 'Users', admin_users_path
+- add_to_breadcrumbs _('Users'), admin_users_path
- breadcrumb_title @user.name
- page_title _('Impersonation Tokens'), @user.name, _('Users')
- type = _('impersonation token')
diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml
index 79d77790b02..5ebfd296e2b 100644
--- a/app/views/admin/projects/index.html.haml
+++ b/app/views/admin/projects/index.html.haml
@@ -1,18 +1,17 @@
- page_title _('Projects')
- params[:visibility_level] ||= []
+- active_tab_classes = 'active gl-tab-nav-item-active gl-tab-nav-item-active-indigo'
.top-area.scrolling-tabs-container.inner-page-scroll-tabs
- %ul.nav-links.nav.nav-tabs
- - opts = params[:visibility_level].present? ? {} : { page: admin_projects_path }
- = nav_link(opts) do
- = link_to _('All'), admin_projects_path
-
- = nav_link(html_options: { class: active_when(params[:visibility_level] == Gitlab::VisibilityLevel::PRIVATE.to_s) }) do
- = link_to _('Private'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
- = nav_link(html_options: { class: active_when(params[:visibility_level] == Gitlab::VisibilityLevel::INTERNAL.to_s) }) do
- = link_to _('Internal'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
- = nav_link(html_options: { class: active_when(params[:visibility_level] == Gitlab::VisibilityLevel::PUBLIC.to_s) }) do
- = link_to _('Public'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
+ %ul.nav.gl-tabs-nav.gl-overflow-x-auto.gl-display-flex.gl-flex-grow-1.gl-flex-shrink-1.gl-border-b-0.gl-flex-nowrap.gl-webkit-scrollbar-display-none
+ = nav_link(html_options: { class: "nav-item" } ) do
+ = link_to _('All'), admin_projects_path, class: "nav-link gl-tab-nav-item #{active_tab_classes if params[:visibility_level].empty?}"
+ = nav_link(html_options: { class: "nav-item" } ) do
+ = link_to _('Private'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::PRIVATE), class: "nav-link gl-tab-nav-item #{active_tab_classes if params[:visibility_level] == Gitlab::VisibilityLevel::PRIVATE.to_s}"
+ = nav_link(html_options: { class: "nav-item" } ) do
+ = link_to _('Internal'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::INTERNAL), class: "nav-link gl-tab-nav-item #{active_tab_classes if params[:visibility_level] == Gitlab::VisibilityLevel::INTERNAL.to_s}"
+ = nav_link(html_options: { class: "nav-item" } ) do
+ = link_to _('Public'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::PUBLIC), class: "nav-link gl-tab-nav-item #{active_tab_classes if params[:visibility_level] == Gitlab::VisibilityLevel::PUBLIC.to_s}"
.nav-controls
.search-holder
diff --git a/app/views/admin/runners/show.html.haml b/app/views/admin/runners/show.html.haml
index 6f3c16f7abf..59523ed3a0c 100644
--- a/app/views/admin/runners/show.html.haml
+++ b/app/views/admin/runners/show.html.haml
@@ -4,15 +4,7 @@
- page_title "##{@runner.id} (#{@runner.short_sha})"
- add_to_breadcrumbs _('Runners'), admin_runners_path
-- if Feature.enabled?(:runner_detailed_view_vue_ui, current_user, default_enabled: :yaml)
- #js-runner-details{ data: {runner_id: @runner.id} }
-- else
- %h2.page-title
- = s_('Runners|Runner #%{runner_id}' % { runner_id: @runner.id })
- = render 'shared/runners/runner_type_badge', runner: @runner
- = render 'shared/runners/runner_type_alert', runner: @runner
- .gl-mb-6
- = render 'shared/runners/form', runner: @runner, runner_form_url: admin_runner_path(@runner), in_gitlab_com_admin_context: Gitlab.com?
+#js-runner-details{ data: {runner_id: @runner.id} }
.row
.col-md-6
@@ -35,7 +27,7 @@
%strong
= project.full_name
.gl-alert-actions
- = link_to s_('Disable'), admin_namespace_project_runner_project_path(project.namespace, project, runner_project), method: :delete, class: 'btn gl-alert-action btn-confirm btn-md gl-button'
+ = link_to _('Disable'), admin_namespace_project_runner_project_path(project.namespace, project, runner_project), method: :delete, class: 'btn gl-alert-action btn-confirm btn-md gl-button'
%table.table{ data: { testid: 'unassigned-projects' } }
%thead
@@ -60,7 +52,7 @@
.float-right
= form_for project.runner_projects.new, url: admin_namespace_project_runner_projects_path(project.namespace, project), method: :post do |f|
= f.hidden_field :runner_id, value: @runner.id
- = f.submit _('Enable'), class: 'gl-button btn btn-sm'
+ = f.submit _('Enable'), class: 'gl-button btn btn-sm', data: { confirm: (s_('Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?') if @runner.instance_type?) }
= paginate_without_count @projects
.col-md-6
diff --git a/app/views/ci/group_variables/_variable_header.html.haml b/app/views/ci/group_variables/_variable_header.html.haml
index 75a432e7f7c..5ef9dc96691 100644
--- a/app/views/ci/group_variables/_variable_header.html.haml
+++ b/app/views/ci/group_variables/_variable_header.html.haml
@@ -1,7 +1,7 @@
%tr
%th
- = s_('Key')
+ = _('Key')
%th
- = s_('Environments')
+ = _('Environments')
%th
- = s_('Group')
+ = _('Group')
diff --git a/app/views/ci/variables/_index.html.haml b/app/views/ci/variables/_index.html.haml
index cdfc174ebf1..f289e6a3386 100644
--- a/app/views/ci/variables/_index.html.haml
+++ b/app/views/ci/variables/_index.html.haml
@@ -16,7 +16,7 @@
aws_tip_deploy_link: help_page_path('ci/cloud_deployment/index.md', anchor: 'deploy-your-application-to-the-aws-elastic-container-service-ecs'),
aws_tip_commands_link: help_page_path('ci/cloud_deployment/index.md', anchor: 'run-aws-commands-from-gitlab-cicd'),
aws_tip_learn_link: help_page_path('ci/cloud_deployment/index.md', anchor: 'aws'),
- contains_variable_reference_link: help_page_path('ci/variables/index', anchor: 'use-variables-or-in-other-variables'),
+ contains_variable_reference_link: help_page_path('ci/variables/index', anchor: 'use-variables-in-other-variables'),
protected_environment_variables_link: help_page_path('ci/variables/index', anchor: 'protect-a-cicd-variable'),
masked_environment_variables_link: help_page_path('ci/variables/index', anchor: 'mask-a-cicd-variable'),
} }
diff --git a/app/views/devise/mailer/unlock_instructions.html.haml b/app/views/devise/mailer/unlock_instructions.html.haml
index 0c05ee4a6cd..a8f1d89f21e 100644
--- a/app/views/devise/mailer/unlock_instructions.html.haml
+++ b/app/views/devise/mailer/unlock_instructions.html.haml
@@ -1,6 +1,8 @@
#content
= email_default_heading(_("Hello, %{name}!") % { name: @resource.name })
%p
- = _("Your GitLab account has been locked due to an excessive amount of unsuccessful sign in attempts. Your account will automatically unlock in %{duration} or you may click the link below to unlock now.") % { duration: distance_of_time_in_words(Devise.unlock_in) }
+ = _("Your GitLab account has been locked due to an excessive number of unsuccessful sign in attempts. You can wait for your account to automatically unlock in %{duration} or you can click the link below to unlock now.") % { duration: distance_of_time_in_words(Devise.unlock_in) }
#cta
= link_to(_('Unlock account'), unlock_url(@resource, unlock_token: @token))
+ %p
+ = _('If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account.')
diff --git a/app/views/devise/mailer/unlock_instructions.text.erb b/app/views/devise/mailer/unlock_instructions.text.erb
index 9b1e2166cee..d58bb8facc3 100644
--- a/app/views/devise/mailer/unlock_instructions.text.erb
+++ b/app/views/devise/mailer/unlock_instructions.text.erb
@@ -1,5 +1,7 @@
<%= _('Hello, %{name}!') % { name: @resource.name } %>
-<%= _("Your GitLab account has been locked due to an excessive amount of unsuccessful sign in attempts. Your account will automatically unlock in %{duration} or you may click the link below to unlock now.") % { duration: distance_of_time_in_words(Devise.unlock_in) } %>
+<%= _("Your GitLab account has been locked due to an excessive number of unsuccessful sign in attempts. You can wait for your account to automatically unlock in %{duration} or you can click the link below to unlock now.") % { duration: distance_of_time_in_words(Devise.unlock_in) } %>
<%= unlock_url(@resource, unlock_token: @token) %>
+
+<%= _('If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account.') %>
diff --git a/app/views/devise/shared/_footer.html.haml b/app/views/devise/shared/_footer.html.haml
index ca1adb48543..5803107a8f7 100644
--- a/app/views/devise/shared/_footer.html.haml
+++ b/app/views/devise/shared/_footer.html.haml
@@ -4,5 +4,5 @@
- unless public_visibility_restricted?
= link_to _("Explore"), explore_root_path
= link_to _("Help"), help_path
- = link_to _("About GitLab"), "https://about.gitlab.com/"
+ = link_to _("About GitLab"), "https://#{ApplicationHelper.promo_host}"
= footer_message
diff --git a/app/views/devise/shared/_omniauth_box.html.haml b/app/views/devise/shared/_omniauth_box.html.haml
index 8b54b735205..1752a43b032 100644
--- a/app/views/devise/shared/_omniauth_box.html.haml
+++ b/app/views/devise/shared/_omniauth_box.html.haml
@@ -7,10 +7,10 @@
.d-flex.justify-content-between.flex-wrap
- providers.each do |provider|
- has_icon = provider_has_icon?(provider)
- = button_to omniauth_authorize_path(:user, provider), id: "oauth-login-#{provider}", class: "btn gl-button btn-default omniauth-btn oauth-login #{qa_class_for_provider(provider)}" do
+ = button_to omniauth_authorize_path(:user, provider), id: "oauth-login-#{provider}", class: "btn gl-button btn-default omniauth-btn oauth-login #{qa_class_for_provider(provider)}", form: { class: 'gl-w-full' } do
- if has_icon
= provider_image_tag(provider)
- %span
+ %span.gl-button-text
= label_for_provider(provider)
- unless hide_remember_me
%fieldset.remember-me
diff --git a/app/views/devise/shared/_signup_box.html.haml b/app/views/devise/shared/_signup_box.html.haml
index a313ad7d23c..f9649875538 100644
--- a/app/views/devise/shared/_signup_box.html.haml
+++ b/app/views/devise/shared/_signup_box.html.haml
@@ -57,6 +57,7 @@
pattern: ".{#{@minimum_password_length},}",
title: s_('SignUp|Minimum length is %{minimum_password_length} characters.') % { minimum_password_length: @minimum_password_length }
%p.gl-field-hint.text-secondary= s_('SignUp|Minimum length is %{minimum_password_length} characters.') % { minimum_password_length: @minimum_password_length }
+ = render_if_exists 'devise/shared/phone_verification', form: f
%div
- if show_recaptcha_sign_up?
= recaptcha_tags nonce: content_security_policy_nonce
diff --git a/app/views/devise/shared/_tabs_normal.html.haml b/app/views/devise/shared/_tabs_normal.html.haml
index a2d5a8be625..01dd3748887 100644
--- a/app/views/devise/shared/_tabs_normal.html.haml
+++ b/app/views/devise/shared/_tabs_normal.html.haml
@@ -6,4 +6,4 @@
%a.nav-link.active{ href: '#login-pane', data: { toggle: 'tab', qa_selector: 'sign_in_tab' }, role: 'tab' }= tab_title
- if render_signup_link && allow_signup?
%li.nav-item{ role: 'presentation' }
- %a.nav-link{ href: '#register-pane', data: { track_label: 'sign_in_register', track_property: '', track_event: 'click_button', track_value: '', toggle: 'tab', qa_selector: 'register_tab' }, role: 'tab' } Register
+ %a.nav-link{ href: '#register-pane', data: { track_label: 'sign_in_register', track_property: '', track_action: 'click_button', track_value: '', toggle: 'tab', qa_selector: 'register_tab' }, role: 'tab' } Register
diff --git a/app/views/errors/access_denied.html.haml b/app/views/errors/access_denied.html.haml
index ce921060cab..e368ee1a75a 100644
--- a/app/views/errors/access_denied.html.haml
+++ b/app/views/errors/access_denied.html.haml
@@ -12,5 +12,5 @@
= s_('403|Please contact your GitLab administrator to get permission.')
.action-container.js-go-back{ hidden: true }
%button{ type: 'button', class: 'gl-button btn btn-success' }
- = s_('Go Back')
+ = _('Go Back')
= render "errors/footer"
diff --git a/app/views/groups/_group_admin_settings.html.haml b/app/views/groups/_group_admin_settings.html.haml
index 0c3eff85f16..ea191449fe3 100644
--- a/app/views/groups/_group_admin_settings.html.haml
+++ b/app/views/groups/_group_admin_settings.html.haml
@@ -30,8 +30,8 @@
= f.check_box :require_two_factor_authentication, class: 'form-check-input'
= f.label :require_two_factor_authentication, class: 'form-check-label' do
%strong
- = _("Require all users in this group to setup Two-factor authentication")
- = link_to sprite_icon('question-o'), help_page_path('security/two_factor_authentication', anchor: 'enforcing-2fa-for-all-users-in-a-group')
+ = _("Require all users in this group to set up two-factor authentication")
+ = link_to sprite_icon('question-o'), help_page_path('security/two_factor_authentication', anchor: 'enforce-2fa-for-all-users-in-a-group')
.form-group.row
.offset-sm-2.col-sm-10
.form-check
diff --git a/app/views/groups/_home_panel.html.haml b/app/views/groups/_home_panel.html.haml
index b7c2b4d86b2..0352f366f5d 100644
--- a/app/views/groups/_home_panel.html.haml
+++ b/app/views/groups/_home_panel.html.haml
@@ -13,18 +13,18 @@
= @group.name
%span.visibility-icon.text-secondary.gl-ml-2.has-tooltip{ data: { container: 'body' }, title: visibility_icon_description(@group) }
= visibility_level_icon(@group.visibility_level, options: {class: 'icon'})
- .home-panel-metadata.d-flex.align-items-center.text-secondary
+ .home-panel-metadata.text-secondary
%span
= _("Group ID: %{group_id}") % { group_id: @group.id }
- if current_user
- %span.access-request-links.gl-ml-3
+ %span.gl-ml-3
= render 'shared/members/access_request_links', source: @group
.home-panel-buttons.col-md-12.col-lg-6
- if current_user
.gl-display-flex.gl-flex-wrap.gl-lg-justify-content-end.gl-mx-n2{ data: { testid: 'group-buttons' } }
- if current_user.admin?
- = link_to [:admin, @group], class: 'btn btn-default gl-button btn-icon gl-mt-3 gl-mr-2', title: s_('View group in admin area'),
+ = link_to [:admin, @group], class: 'btn btn-default gl-button btn-icon gl-mt-3 gl-mr-2', title: _('View group in admin area'),
data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon('admin')
- if @notification_setting
diff --git a/app/views/groups/_new_group_fields.html.haml b/app/views/groups/_new_group_fields.html.haml
index 49c8c2700ce..8ee7c91a938 100644
--- a/app/views/groups/_new_group_fields.html.haml
+++ b/app/views/groups/_new_group_fields.html.haml
@@ -13,7 +13,10 @@
- if Gitlab.config.mattermost.enabled
.row
= render 'create_chat_team', f: f
-.row
+
+= render 'personalize', f: f
+
+.row.js-invite-members-section
.col-sm-4
= render_if_exists 'shared/groups/invite_members'
diff --git a/app/views/groups/_personalize.html.haml b/app/views/groups/_personalize.html.haml
new file mode 100644
index 00000000000..5ecb0017cd8
--- /dev/null
+++ b/app/views/groups/_personalize.html.haml
@@ -0,0 +1,27 @@
+.row
+ .form-group.col-sm-12.gl-mb-0
+ %label.label-bold
+ = _('Now, personalize your GitLab experience')
+ %p
+ = _("We'll use this to help surface the right features and information to you.")
+
+.row
+ .form-group.col-sm-4
+ = label :user, :role, _('Role')
+ = select :user, :role, ::User.roles.keys.map { |role| [role.titleize, role] }, { selected: @current_user.role }, class: 'form-control'
+
+.row
+ .form-group.col-sm-4
+ = f.label :setup_for_company, _('Who will be using this group?')
+ .gl-display-flex.gl-flex-direction-column.gl-lg-flex-direction-row
+ .gl-flex-grow-1.gl-display-flex.gl-align-items-center
+ = f.radio_button :setup_for_company, true, checked: true
+ = f.label :setup_for_company, _('My company or team'), class: 'gl-font-weight-normal gl-mb-0 gl-ml-2', value: 'true'
+ .gl-flex-grow-1.gl-display-flex.gl-align-items-center
+ = f.radio_button :setup_for_company, false
+ = f.label :setup_for_company, _('Just me'), class: 'gl-font-weight-normal gl-mb-0 gl-ml-2', value: 'false'
+
+.row
+ .form-group.col-sm-4
+ = f.label :jobs_to_be_done, _("What will you use this group for?")
+ = f.select :jobs_to_be_done, ::NamespaceSetting.jobs_to_be_dones.keys.map { |job_to_be_done| [localized_jobs_to_be_done_choices[job_to_be_done], job_to_be_done] }, { include_blank: true }, class: 'form-control'
diff --git a/app/views/groups/dependency_proxies/_url.html.haml b/app/views/groups/dependency_proxies/_url.html.haml
index a8034c50ed8..9a76da63a72 100644
--- a/app/views/groups/dependency_proxies/_url.html.haml
+++ b/app/views/groups/dependency_proxies/_url.html.haml
@@ -1,4 +1,4 @@
-- proxy_url = group_dependency_proxy_image_prefix(@group)
+- proxy_url = @group.dependency_proxy_image_prefix
%h5.prepend-top-20= _('Dependency proxy image prefix')
diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml
index fdd6962eb21..1f746484b7d 100644
--- a/app/views/groups/issues.html.haml
+++ b/app/views/groups/issues.html.haml
@@ -5,29 +5,34 @@
= content_for :meta_tags do
= auto_discovery_link_tag(:atom, safe_params.merge(rss_url_options).to_h, title: "#{@group.name} issues")
-.top-area
- = render 'shared/issuable/nav', type: :issues
- .nav-controls
- = render 'shared/issuable/feed_buttons'
+- if Feature.enabled?(:vue_issues_list, @group, default_enabled: :yaml)
+ .js-issues-list{ data: group_issues_list_data(@group, current_user, @issues) }
+ - if @can_bulk_update
+ = render_if_exists 'shared/issuable/group_bulk_update_sidebar', group: @group, type: :issues
+- else
+ .top-area
+ = render 'shared/issuable/nav', type: :issues
+ .nav-controls
+ = render 'shared/issuable/feed_buttons'
- - if @can_bulk_update
- = render_if_exists 'shared/issuable/bulk_update_button', type: :issues
+ - if @can_bulk_update
+ = render_if_exists 'shared/issuable/bulk_update_button', type: :issues
- = render 'shared/new_project_item_select', path: 'issues/new', label: "New issue", type: :issues, with_feature_enabled: 'issues', with_shared: false, include_projects_in_subgroups: true
+ = render 'shared/new_project_item_select', path: 'issues/new', label: "New issue", type: :issues, with_feature_enabled: 'issues', with_shared: false, include_projects_in_subgroups: true
-= render 'shared/issuable/search_bar', type: :issues
+ = render 'shared/issuable/search_bar', type: :issues
-- if @can_bulk_update
- = render_if_exists 'shared/issuable/group_bulk_update_sidebar', group: @group, type: :issues
+ - if @can_bulk_update
+ = render_if_exists 'shared/issuable/group_bulk_update_sidebar', group: @group, type: :issues
-- if Feature.enabled?(:vue_issuables_list, @group) && @issues.to_a.any?
- - if use_startup_call?
- - add_page_startup_api_call(api_v4_groups_issues_path(id: @group.id, params: startup_call_params))
- .js-issuables-list{ data: { endpoint: expose_url(api_v4_groups_issues_path(id: @group.id)),
- 'can-bulk-edit': @can_bulk_update.to_json,
- 'empty-state-meta': { svg_path: image_path('illustrations/issues.svg') },
- 'sort-key': @sort,
- type: 'issues',
- 'scoped-labels-available': scoped_labels_available?(@group).to_json } }
-- else
- = render 'shared/issues', project_select_button: true
+ - if Feature.enabled?(:vue_issuables_list, @group) && @issues.to_a.any?
+ - if use_startup_call?
+ - add_page_startup_api_call(api_v4_groups_issues_path(id: @group.id, params: startup_call_params))
+ .js-issuables-list{ data: { endpoint: expose_url(api_v4_groups_issues_path(id: @group.id)),
+ 'can-bulk-edit': @can_bulk_update.to_json,
+ 'empty-state-meta': { svg_path: image_path('illustrations/issues.svg') },
+ 'sort-key': @sort,
+ type: 'issues',
+ 'scoped-labels-available': scoped_labels_available?(@group).to_json } }
+ - else
+ = render 'shared/issues', project_select_button: true
diff --git a/app/views/groups/new.html.haml b/app/views/groups/new.html.haml
index 11927142ea6..0f11ca5fb8f 100644
--- a/app/views/groups/new.html.haml
+++ b/app/views/groups/new.html.haml
@@ -15,7 +15,7 @@
#import-group-pane.tab-pane
- if import_sources_enabled?
- - if Feature.enabled?(:bulk_import)
+ - if Feature.enabled?(:bulk_import, default_enabled: :yaml)
= render 'import_group_from_another_instance_panel'
.gl-mt-7.gl-border-b-solid.gl-border-gray-100.gl-border-1
= render 'import_group_from_file_panel'
diff --git a/app/views/groups/runners/_runner.html.haml b/app/views/groups/runners/_runner.html.haml
index 13da2292985..66ffef98553 100644
--- a/app/views/groups/runners/_runner.html.haml
+++ b/app/views/groups/runners/_runner.html.haml
@@ -1,6 +1,3 @@
--# Note: This file should stay aligned with:
--# `app/views/admin/runners/_runner.html.haml`
-
.gl-responsive-table-row{ id: dom_id(runner) }
.table-section.section-10.section-wrap
.table-mobile-header{ role: 'rowheader' }= _('Type')
diff --git a/app/views/groups/runners/index.html.haml b/app/views/groups/runners/index.html.haml
index 4e7bc99b1f0..f904b34d29e 100644
--- a/app/views/groups/runners/index.html.haml
+++ b/app/views/groups/runners/index.html.haml
@@ -3,4 +3,4 @@
%h2.page-title
= s_('Runners|Group Runners')
-#js-group-runners{ data: { registration_token: @group.runners_token, group_id: @group.id } }
+#js-group-runners{ data: group_runners_data_attributes(@group).merge( { group_runners_limited_count: @group_runners_limited_count } ) }
diff --git a/app/views/groups/settings/_membership.html.haml b/app/views/groups/settings/_membership.html.haml
new file mode 100644
index 00000000000..b05a294e864
--- /dev/null
+++ b/app/views/groups/settings/_membership.html.haml
@@ -0,0 +1,6 @@
+%h5= _('Membership')
+
+.form-group
+ = render 'shared/allow_request_access', form: f
+
+= render_if_exists 'groups/member_lock_setting', f: f, group: @group
diff --git a/app/views/groups/settings/_permissions.html.haml b/app/views/groups/settings/_permissions.html.haml
index 683e70248b6..8f428909e60 100644
--- a/app/views/groups/settings/_permissions.html.haml
+++ b/app/views/groups/settings/_permissions.html.haml
@@ -4,9 +4,6 @@
%fieldset
%h5= _('Permissions')
- .form-group
- = render 'shared/allow_request_access', form: f
-
- if @group.root?
.form-group.gl-mb-3
= f.gitlab_ui_checkbox_component :prevent_sharing_groups_outside_hierarchy,
@@ -43,5 +40,5 @@
= render_if_exists 'groups/settings/prevent_forking', f: f, group: @group
= render 'groups/settings/two_factor_auth', f: f, group: @group
= render_if_exists 'groups/personal_access_token_expiration_policy', f: f, group: @group
- = render_if_exists 'groups/member_lock_setting', f: f, group: @group
+ = render 'groups/settings/membership', f: f, group: @group
= f.submit _('Save changes'), class: 'btn gl-button btn-confirm gl-mt-3 js-dirty-submit', data: { qa_selector: 'save_permissions_changes_button' }
diff --git a/app/views/groups/settings/_two_factor_auth.html.haml b/app/views/groups/settings/_two_factor_auth.html.haml
index 9e5eeee2e2a..8204cafcb44 100644
--- a/app/views/groups/settings/_two_factor_auth.html.haml
+++ b/app/views/groups/settings/_two_factor_auth.html.haml
@@ -1,5 +1,5 @@
- return unless group.parent_allows_two_factor_authentication?
-- docs_link_url = help_page_path('security/two_factor_authentication', anchor: 'enforcing-2fa-for-all-users-in-a-group')
+- docs_link_url = help_page_path('security/two_factor_authentication', anchor: 'enforce-2fa-for-all-users-in-a-group')
- docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: docs_link_url }
%h5= _('Two-factor authentication')
diff --git a/app/views/groups/settings/ci_cd/show.html.haml b/app/views/groups/settings/ci_cd/show.html.haml
index 018dd4c424d..331cb31c626 100644
--- a/app/views/groups/settings/ci_cd/show.html.haml
+++ b/app/views/groups/settings/ci_cd/show.html.haml
@@ -9,7 +9,7 @@
- if can?(current_user, :update_max_artifacts_size, @group)
%section.settings#js-general-pipeline-settings.no-animate{ class: ('expanded' if general_expanded) }
.settings-header
- %h4
+ %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
= _("General pipelines")
%button.btn.gl-button.js-settings-toggle{ type: 'button' }
= expanded ? _('Collapse') : _('Expand')
@@ -26,7 +26,7 @@
%section.settings#runners-settings.no-animate{ class: ('expanded' if expanded) }
.settings-header
- %h4
+ %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
= _('Runners')
%button.btn.gl-button.btn-default.js-settings-toggle{ type: "button" }
= expanded ? _('Collapse') : _('Expand')
@@ -38,7 +38,7 @@
%section.settings#auto-devops-settings.no-animate{ class: ('expanded' if expanded) }
.settings-header
- %h4
+ %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
= _('Auto DevOps')
%button.btn.gl-button.btn-default.js-settings-toggle{ type: "button" }
= expanded ? _('Collapse') : _('Expand')
diff --git a/app/views/groups/settings/repository/_initial_branch_name.html.haml b/app/views/groups/settings/repository/_initial_branch_name.html.haml
index 5299c38576d..15a3bacf12d 100644
--- a/app/views/groups/settings/repository/_initial_branch_name.html.haml
+++ b/app/views/groups/settings/repository/_initial_branch_name.html.haml
@@ -1,6 +1,6 @@
%section.settings.as-default-branch-name.no-animate#js-default-branch-name{ class: ('expanded' if expanded_by_default?) }
.settings-header
- %h4
+ %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
= _('Default initial branch name')
%button.gl-button.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml
index 76850f0a884..2e74d983397 100644
--- a/app/views/groups/show.html.haml
+++ b/app/views/groups/show.html.haml
@@ -12,9 +12,11 @@
= content_for :group_invite_members_banner do
.container-fluid.container-limited{ class: "gl-pb-2! gl-pt-6! #{@content_class}" }
.js-group-invite-members-banner{ data: { svg_path: image_path('illustrations/merge_requests.svg'),
- is_dismissed_key: "invite_#{@group.id}_#{current_user.id}",
track_label: 'invite_members_banner',
- invite_members_path: group_group_members_path(@group) } }
+ invite_members_path: group_group_members_path(@group),
+ callouts_path: group_callouts_path,
+ callouts_feature_id: UserCalloutsHelper::INVITE_MEMBERS_BANNER,
+ group_id: @group.id } }
= render 'groups/invite_members_modal', group: @group
= content_for :meta_tags do
diff --git a/app/views/help/instance_configuration.html.haml b/app/views/help/instance_configuration.html.haml
index 88c531535b4..411a81cb976 100644
--- a/app/views/help/instance_configuration.html.haml
+++ b/app/views/help/instance_configuration.html.haml
@@ -7,7 +7,7 @@
= render 'help/instance_configuration/ssh_info'
= render 'help/instance_configuration/gitlab_pages'
- = render 'help/instance_configuration/gitlab_ci'
+ = render 'help/instance_configuration/size_limits'
= render 'help/instance_configuration/package_registry'
= render 'help/instance_configuration/rate_limits'
%p
diff --git a/app/views/help/instance_configuration/_gitlab_ci.html.haml b/app/views/help/instance_configuration/_gitlab_ci.html.haml
deleted file mode 100644
index 53fa3f89873..00000000000
--- a/app/views/help/instance_configuration/_gitlab_ci.html.haml
+++ /dev/null
@@ -1,24 +0,0 @@
-- content_for :table_content do
- %li= link_to _('GitLab CI'), '#gitlab-ci'
-
-- content_for :settings_content do
- %h2#gitlab-ci
- = _('GitLab CI')
-
- %p
- = _('Below are the current settings regarding')
- = succeed('.') { link_to(_('GitLab CI'), 'https://about.gitlab.com/gitlab-ci', target: '_blank') }
-
- .table-responsive
- %table
- %thead
- %tr
- %th= _('Setting')
- %th= instance_configuration_host(@instance_configuration.settings[:host])
- %th= _('Default')
- %tbody
- %tr
- - artifacts_size = @instance_configuration.settings[:gitlab_ci][:artifacts_max_size]
- %td= _('Artifacts maximum size')
- %td= instance_configuration_human_size_cell(artifacts_size[:value])
- %td= instance_configuration_human_size_cell(artifacts_size[:default])
diff --git a/app/views/help/instance_configuration/_gitlab_pages.html.haml b/app/views/help/instance_configuration/_gitlab_pages.html.haml
index 55f043214f6..51835c202d6 100644
--- a/app/views/help/instance_configuration/_gitlab_pages.html.haml
+++ b/app/views/help/instance_configuration/_gitlab_pages.html.haml
@@ -28,8 +28,3 @@
%td= _('Port')
%td
%code= instance_configuration_cell_html(gitlab_pages[:port])
- %br
-
- %p
- - link_to_gitlab_ci = link_to(_('GitLab CI'), '#gitlab-ci')
- = _("The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}.").html_safe % { link_to_gitlab_ci: link_to_gitlab_ci }
diff --git a/app/views/help/instance_configuration/_size_limits.html.haml b/app/views/help/instance_configuration/_size_limits.html.haml
new file mode 100644
index 00000000000..b592eeed020
--- /dev/null
+++ b/app/views/help/instance_configuration/_size_limits.html.haml
@@ -0,0 +1,40 @@
+- size_limits = @instance_configuration.settings[:size_limits]
+- content_for :table_content do
+ - if size_limits.present?
+ %li= link_to _('Size Limits'), '#size-limits'
+
+- content_for :settings_content do
+ - if size_limits.present?
+ %h2#size-limits
+ = _('Size Limits')
+
+ %p
+ = _('There are several size limits in place.')
+ .table-responsive
+ %table
+ %thead
+ %tr
+ %th= _('Setting')
+ %th= instance_configuration_host(@instance_configuration.settings[:host])
+ %tbody
+ %tr
+ %td= _('Maximum attachment size')
+ %td= instance_configuration_human_size_cell(size_limits[:max_attachment_size])
+ %tr
+ %td= _('Maximum push size')
+ %td= instance_configuration_human_size_cell(size_limits[:receive_max_input_size])
+ %tr
+ %td= _('Maximum import size')
+ %td= instance_configuration_human_size_cell(size_limits[:max_import_size])
+ %tr
+ %td= _('Maximum diff patch size')
+ %td= instance_configuration_human_size_cell(size_limits[:diff_max_patch_bytes])
+ %tr
+ %td= _('Maximum job artifact size')
+ %td= instance_configuration_human_size_cell(size_limits[:max_artifacts_size])
+ %tr
+ %td= _('Maximum page size')
+ %td= instance_configuration_human_size_cell(size_limits[:max_pages_size])
+ %tr
+ %td= _('Maximum snippet size')
+ %td= instance_configuration_human_size_cell(size_limits[:snippet_size_limit])
diff --git a/app/views/issues/_issue.atom.builder b/app/views/issues/_issue.atom.builder
index e2ab360a3e4..d14eff22bb6 100644
--- a/app/views/issues/_issue.atom.builder
+++ b/app/views/issues/_issue.atom.builder
@@ -3,42 +3,7 @@
xml.entry do
xml.id project_issue_url(issue.project, issue)
xml.link href: project_issue_url(issue.project, issue)
- xml.title truncate(issue.title, length: 80)
- xml.updated issue.updated_at.xmlschema
- xml.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon_for_user(issue.author))
-
- xml.author do
- xml.name issue.author_name
- xml.email issue.author_public_email
- end
-
- xml.summary issue.title
- xml.description issue.description if issue.description
- xml.content issue.description if issue.description
- xml.milestone issue.milestone.title if issue.milestone
+ # using the shovel operator (xml <<) would make us lose indentation, so we do this (https://github.com/rails/rails/issues/7036)
+ render(partial: 'shared/issuable/issuable', object: issue, locals: { builder: xml })
xml.due_date issue.due_date if issue.due_date
-
- unless issue.labels.empty?
- xml.labels do
- issue.labels.each do |label|
- xml.label label.name
- end
- end
- end
-
- if issue.assignees.any?
- xml.assignees do
- issue.assignees.each do |assignee|
- xml.assignee do
- xml.name assignee.name
- xml.email assignee.public_email
- end
- end
- end
-
- xml.assignee do
- xml.name issue.assignees.first.name
- xml.email issue.assignees.first.public_email
- end
- end
end
diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml
index ba2d6aa79eb..ec2904245d3 100644
--- a/app/views/layouts/_page.html.haml
+++ b/app/views/layouts/_page.html.haml
@@ -14,7 +14,7 @@
= render "layouts/nav/classification_level_banner"
= yield :flash_message
= render "shared/service_ping_consent"
- = render_account_recovery_regular_check
+ = render_two_factor_auth_recovery_settings_check
= render_if_exists "layouts/header/ee_subscribable_banner"
= render_if_exists "shared/namespace_storage_limit_alert"
= render_if_exists "shared/new_user_signups_cap_reached_alert"
diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml
index 5ce275d4a43..2d186dfbd91 100644
--- a/app/views/layouts/_search.html.haml
+++ b/app/views/layouts/_search.html.haml
@@ -1,4 +1,4 @@
-.search.search-form{ data: { track_label: "navbar_search", track_event: "activate_form_input", track_value: "" } }
+.search.search-form{ data: { track_label: "navbar_search", track_action: "activate_form_input", track_value: "" } }
= form_tag search_path, method: :get, class: 'form-inline form-control' do |_f|
.search-input-container
.search-input-wrap
diff --git a/app/views/layouts/_snowplow.html.haml b/app/views/layouts/_snowplow.html.haml
index 9c0384e5faa..fc3b12acc46 100644
--- a/app/views/layouts/_snowplow.html.haml
+++ b/app/views/layouts/_snowplow.html.haml
@@ -7,7 +7,8 @@
};p[i].q=p[i].q||[];n=l.createElement(o);g=l.getElementsByTagName(o)[0];n.async=1;
n.src=w;g.parentNode.insertBefore(n,g)}}(window,document,"script","#{asset_url('snowplow/sp.js')}","snowplow"));
- window.snowplowOptions = #{Gitlab::Tracking.snowplow_options(@group).to_json}
+ window.snowplowOptions = #{Gitlab::Tracking.options(@group).to_json}
gl = window.gl || {};
gl.snowplowStandardContext = #{Gitlab::Tracking::StandardContext.new.to_context.to_json.to_json}
+ gl.snowplowPseudonymizedPageUrl = #{masked_page_url.to_json};
diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml
index 2f6287bdfb3..3e7155b2c0e 100644
--- a/app/views/layouts/header/_default.html.haml
+++ b/app/views/layouts/header/_default.html.haml
@@ -15,7 +15,7 @@
%span.logo-text.d-none.d-lg-block.gl-ml-3
= logo_text
- if Gitlab.com_and_canary?
- = link_to 'https://next.gitlab.com', class: 'canary-badge bg-transparent', target: :_blank, rel: :_noopener do
+ = link_to 'https://next.gitlab.com', class: 'canary-badge bg-transparent', data: { qa_selector: 'canary_badge_link' }, target: :_blank, rel: :_noopener do
%span.gl-badge.gl-bg-green-500.gl-text-white.gl-rounded-pill.gl-font-weight-bold.gl-py-1
= _('Next')
@@ -29,7 +29,15 @@
- if top_nav_show_search
- search_menu_item = top_nav_search_menu_item_attrs
%li.nav-item.d-none.d-lg-block.m-auto
- = render 'layouts/search' unless current_controller?(:search)
+ - unless current_controller?(:search)
+ - if Feature.enabled?(:new_header_search)
+ #js-header-search.header-search{ data: { 'search-context' => search_context.to_json,
+ 'search-path' => search_path,
+ 'issues-path' => issues_dashboard_path,
+ 'mr-path' => merge_requests_dashboard_path } }
+ %input{ type: "text", placeholder: _('Search or jump to...'), class: 'form-control gl-form-input' }
+ - else
+ = render 'layouts/search'
%li.nav-item{ class: 'd-none d-sm-inline-block d-lg-none' }
= link_to search_menu_item.fetch(:href), title: search_menu_item.fetch(:title), aria: { label: search_menu_item.fetch(:title) }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon(search_menu_item.fetch(:icon))
@@ -38,7 +46,7 @@
= link_to assigned_issues_dashboard_path, title: _('Issues'), class: 'dashboard-shortcuts-issues', aria: { label: _('Issues') },
data: { qa_selector: 'issues_shortcut_button', toggle: 'tooltip', placement: 'bottom',
track_label: 'main_navigation',
- track_event: 'click_issues_link',
+ track_action: 'click_issues_link',
track_property: 'navigation',
container: 'body' } do
= sprite_icon('issues')
@@ -52,7 +60,7 @@
toggle: "dropdown",
placement: 'bottom',
track_label: 'main_navigation',
- track_event: 'click_merge_link',
+ track_action: 'click_merge_link',
track_property: 'navigation',
container: 'body' } do
= sprite_icon('git-merge')
@@ -78,7 +86,7 @@
= link_to dashboard_todos_path, title: _('To-Do List'), aria: { label: _('To-Do List') }, class: 'shortcuts-todos',
data: { qa_selector: 'todos_shortcut_button', toggle: 'tooltip', placement: 'bottom',
track_label: 'main_navigation',
- track_event: 'click_to_do_link',
+ track_action: 'click_to_do_link',
track_property: 'navigation',
container: 'body' } do
= sprite_icon('todo-done')
@@ -94,7 +102,7 @@
.dropdown-menu.dropdown-menu-right
= render 'layouts/header/help_dropdown'
- if header_link?(:user_dropdown)
- %li.nav-item.header-user.js-nav-user-dropdown.dropdown{ data: { track_label: "profile_dropdown", track_event: "click_dropdown", track_value: "", qa_selector: 'user_menu' }, class: ('mr-0' if has_impersonation_link) }
+ %li.nav-item.header-user.js-nav-user-dropdown.dropdown{ data: { track_label: "profile_dropdown", track_action: "click_dropdown", track_value: "", qa_selector: 'user_menu' }, class: ('mr-0' if has_impersonation_link) }
= link_to current_user, class: user_dropdown_class, data: { toggle: "dropdown" } do
= image_tag avatar_icon_for_user(current_user, 23), width: 23, height: 23, class: "header-user-avatar qa-user-avatar", alt: current_user.name
= render_if_exists 'layouts/header/user_notification_dot', project: project, namespace: group
diff --git a/app/views/layouts/header/_new_dropdown.html.haml b/app/views/layouts/header/_new_dropdown.html.haml
index 0be87ad963c..a0b271fdafa 100644
--- a/app/views/layouts/header/_new_dropdown.html.haml
+++ b/app/views/layouts/header/_new_dropdown.html.haml
@@ -6,7 +6,7 @@
- return if menu_sections.empty?
-%li.header-new.dropdown{ class: top_class, data: { track_label: "new_dropdown", track_event: "click_dropdown" } }
+%li.header-new.dropdown{ class: top_class, data: { track_label: "new_dropdown", track_action: "click_dropdown" } }
= link_to new_project_path, class: "header-new-dropdown-toggle has-tooltip", id: "js-onboarding-new-project-link", title: title, ref: 'tooltip', aria: { label: title }, data: { toggle: 'dropdown', placement: 'bottom', container: 'body', display: 'static', qa_selector: 'new_menu_toggle' } do
= sprite_icon('plus-square')
= sprite_icon('chevron-down', css_class: 'caret-down')
diff --git a/app/views/layouts/nav/sidebar/_group.html.haml b/app/views/layouts/nav/sidebar/_group.html.haml
index 980730bc3be..c2b50bc0e52 100644
--- a/app/views/layouts/nav/sidebar/_group.html.haml
+++ b/app/views/layouts/nav/sidebar/_group.html.haml
@@ -1,3 +1 @@
--# We're migration the group sidebar to a logical model based structure. If you need to update
--# any of the existing menus, you can find them in app/views/layouts/nav/sidebar/_group_menus.html.haml.
= render partial: 'shared/nav/sidebar', object: Sidebars::Groups::Panel.new(group_sidebar_context(@group, current_user))
diff --git a/app/views/layouts/nav/sidebar/_group_menus.html.haml b/app/views/layouts/nav/sidebar/_group_menus.html.haml
deleted file mode 100644
index 25b6c264d92..00000000000
--- a/app/views/layouts/nav/sidebar/_group_menus.html.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-= render_if_exists "groups/ee/administration_nav"
-
-= render 'shared/sidebar_toggle_button'
diff --git a/app/views/notify/member_invited_email.html.haml b/app/views/notify/member_invited_email.html.haml
index 843a820bd1b..5489a2ac6a1 100644
--- a/app/views/notify/member_invited_email.html.haml
+++ b/app/views/notify/member_invited_email.html.haml
@@ -5,7 +5,6 @@
br_tag: '<br/>'.html_safe,
role: member.human_access.downcase }
- join_text = s_('InviteEmail|Join now')
-- join_url = invite_url(@token, invite_type: Emails::Members::INITIAL_INVITE, experiment_name: 'invite_email_preview_text')
- inviter_name = member.created_by.name if member.created_by
- experiment(:invite_email_preview_text, actor: member) do |experiment_instance|
@@ -17,7 +16,7 @@
= s_('InviteEmail|Join your team on GitLab! %{inviter} invited you to %{project_or_group_name}') % { inviter: inviter_name, project_or_group_name: placeholders[:project_or_group_name] }
- else
= s_('InviteEmail|Join your team on GitLab! You are invited to %{project_or_group_name}') % { project_or_group_name: placeholders[:project_or_group_name] }
- = gmail_goto_action(join_text, join_url)
+ = gmail_goto_action(join_text, invited_join_url(@token, member))
%tr
%td.text-content{ colspan: 2 }
@@ -28,7 +27,7 @@
- else
= html_escape(s_("InviteEmail|You are invited to join the %{strong_start}%{project_or_group_name}%{strong_end}%{br_tag}%{project_or_group} as a %{role}")) % placeholders
%p.invite-actions
- = link_to join_text, join_url, class: 'invite-btn-join'
+ = link_to join_text, invited_join_url(@token, member), class: 'invite-btn-join'
%tr.border-top
%td.text-content.mailer-align-left.half-width
%h4
diff --git a/app/views/profiles/_email_settings.html.haml b/app/views/profiles/_email_settings.html.haml
index 6691d20c8f7..bc678c2c429 100644
--- a/app/views/profiles/_email_settings.html.haml
+++ b/app/views/profiles/_email_settings.html.haml
@@ -11,6 +11,6 @@
- commit_email_link_url = help_page_path('user/profile/index', anchor: 'change-the-email-displayed-on-your-commits', target: '_blank')
- commit_email_link_start = '<a href="%{url}">'.html_safe % { url: commit_email_link_url }
- commit_email_docs_link = s_('Profiles|This email will be used for web based operations, such as edits and merges. %{commit_email_link_start}Learn more%{commit_email_link_end}').html_safe % { commit_email_link_start: commit_email_link_start, commit_email_link_end: '</a>'.html_safe }
-= form.select :commit_email, options_for_select(commit_email_select_options(@user), selected: selected_commit_email(@user)),
+= form.select :commit_email, options_for_select(commit_email_select_options(@user), selected: @user.commit_email),
{ help: commit_email_docs_link },
control_class: 'select2 input-lg', disabled: email_change_disabled
diff --git a/app/views/profiles/emails/index.html.haml b/app/views/profiles/emails/index.html.haml
index c14efa99555..35bdfbb1c29 100644
--- a/app/views/profiles/emails/index.html.haml
+++ b/app/views/profiles/emails/index.html.haml
@@ -38,21 +38,21 @@
= render partial: 'shared/email_with_badge', locals: { email: @primary_email, verified: current_user.confirmed? }
%span.float-right
%span.badge.badge-muted.badge-pill.gl-badge.badge-success= s_('Profiles|Primary email')
- - if @primary_email === current_user.commit_email
+ - if @primary_email === current_user.commit_email_or_default
%span.badge.badge-muted.badge-pill.gl-badge.badge-info= s_('Profiles|Commit email')
- if @primary_email === current_user.public_email
%span.badge.badge-muted.badge-pill.gl-badge.badge-info= s_('Profiles|Public email')
- - if @primary_email === current_user.notification_email
+ - if @primary_email === current_user.notification_email_or_default
%span.badge.badge-muted.badge-pill.gl-badge.badge-info= s_('Profiles|Default notification email')
- @emails.each do |email|
%li{ data: { qa_selector: 'email_row_content' } }
= render partial: 'shared/email_with_badge', locals: { email: email.email, verified: email.confirmed? }
%span.float-right
- - if email.email === current_user.commit_email
+ - if email.email === current_user.commit_email_or_default
%span.badge.badge-muted.badge-pill.gl-badge.badge-info= s_('Profiles|Commit email')
- if email.email === current_user.public_email
%span.badge.badge-muted.badge-pill.gl-badge.badge-info= s_('Profiles|Public email')
- - if email.email === current_user.notification_email
+ - if email.email === current_user.notification_email_or_default
%span.badge.badge-muted.badge-pill.gl-badge.badge-info= s_('Profiles|Notification email')
- unless email.confirmed?
- confirm_title = "#{email.confirmation_sent_at ? _('Resend confirmation email') : _('Send confirmation email')}"
diff --git a/app/views/profiles/keys/show.html.haml b/app/views/profiles/keys/show.html.haml
index 360de7a0c11..09c16b0c038 100644
--- a/app/views/profiles/keys/show.html.haml
+++ b/app/views/profiles/keys/show.html.haml
@@ -1,4 +1,4 @@
-- add_to_breadcrumbs "SSH Keys", profile_keys_path
+- add_to_breadcrumbs _('SSH Keys'), profile_keys_path
- breadcrumb_title @key.title
- page_title @key.title, _('SSH Keys')
- @content_class = "limit-container-width" unless fluid_layout
diff --git a/app/views/profiles/notifications/_email_settings.html.haml b/app/views/profiles/notifications/_email_settings.html.haml
index f452a5b2eb5..f2121199412 100644
--- a/app/views/profiles/notifications/_email_settings.html.haml
+++ b/app/views/profiles/notifications/_email_settings.html.haml
@@ -1,7 +1,7 @@
- form = local_assigns.fetch(:form)
.form-group
= form.label :notification_email, class: "label-bold"
- = form.select :notification_email, @user.public_verified_emails, { include_blank: false }, class: "select2", disabled: local_assigns.fetch(:email_change_disabled, nil)
+ = form.select :notification_email, @user.public_verified_emails, { include_blank: _('Use primary email (%{email})') % { email: @user.email }, selected: @user.notification_email }, class: "select2", disabled: local_assigns.fetch(:email_change_disabled, nil)
.help-block
= local_assigns.fetch(:help_text, nil)
.form-group
diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml
index 6eba0309a4f..0bb4859dd1e 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -99,11 +99,12 @@
= f.text_field :pronouns, class: 'input-md gl-form-input', help: s_("Profiles|Enter your pronouns to let people know how to refer to you")
= f.text_field :pronunciation, class: 'input-md gl-form-input', help: s_("Profiles|Enter how your name is pronounced to help people address you correctly")
+ = render_if_exists 'profiles/extra_settings', form: f
= render_if_exists 'profiles/email_settings', form: f
= f.text_field :skype, class: 'input-md gl-form-input', placeholder: s_("Profiles|username")
= f.text_field :linkedin, class: 'input-md gl-form-input', help: s_("Profiles|Your LinkedIn profile name from linkedin.com/in/profilename")
= f.text_field :twitter, class: 'input-md gl-form-input', placeholder: s_("Profiles|@username")
- = f.text_field :website_url, class: 'input-lg gl-form-input', placeholder: s_("Profiles|website.com")
+ = f.text_field :website_url, class: 'input-lg gl-form-input', placeholder: s_("Profiles|https://website.com")
- if @user.read_only_attribute?(:location)
= f.text_field :location, class: 'gl-form-input', readonly: true, help: s_("Profiles|Your location was automatically set based on your %{provider_label} account") % { provider_label: attribute_provider_label(:location) }
- else
@@ -112,7 +113,7 @@
= f.text_field :organization, label: s_('Profiles|Organization'), class: 'input-md gl-form-input', help: s_("Profiles|Who you represent or work for")
= f.text_area :bio, class: 'gl-form-input', label: s_('Profiles|Bio'), rows: 4, maxlength: 250, help: s_("Profiles|Tell us about yourself in fewer than 250 characters")
%hr
- %h5= s_("Private profile")
+ %h5= _('Private profile')
.checkbox-icon-inline-wrapper
- private_profile_label = capture do
= s_("Profiles|Don't display activity-related personal information on your profiles")
diff --git a/app/views/projects/_commit_button.html.haml b/app/views/projects/_commit_button.html.haml
index 987ec74e4ba..2c18921d874 100644
--- a/app/views/projects/_commit_button.html.haml
+++ b/app/views/projects/_commit_button.html.haml
@@ -1,7 +1,7 @@
.form-actions.gl-display-flex
= button_tag 'Commit changes', id: 'commit-changes', class: 'gl-button btn btn-confirm js-commit-button qa-commit-button'
- = link_to 'Cancel', cancel_path,
+ = link_to _('Cancel'), cancel_path,
class: 'gl-button btn btn-default gl-ml-3', data: {confirm: leave_edit_message}
= render 'shared/projects/edit_information'
diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml
index 8909536a1ec..f2cee618849 100644
--- a/app/views/projects/_home_panel.html.haml
+++ b/app/views/projects/_home_panel.html.haml
@@ -15,13 +15,13 @@
%span.visibility-icon.text-secondary.gl-ml-2.has-tooltip{ data: { container: 'body' }, title: visibility_icon_description(@project) }
= visibility_level_icon(@project.visibility_level, options: { class: 'icon' })
= render_if_exists 'compliance_management/compliance_framework/compliance_framework_badge', project: @project
- .home-panel-metadata.d-flex.flex-wrap.text-secondary.gl-font-base.gl-font-weight-normal.gl-line-height-normal
+ .home-panel-metadata.text-secondary.gl-font-base.gl-font-weight-normal.gl-line-height-normal
- if can?(current_user, :read_project, @project)
- button_class = "btn gl-button btn-sm btn-tertiary btn-default-tertiary home-panel-metadata"
- button_text = s_('ProjectPage|Project ID: %{project_id}') % { project_id: @project.id }
= clipboard_button(title: s_('ProjectPage|Copy project ID'), text: @project.id, hide_button_icon: true, button_text: button_text, class: button_class, qa_selector: 'project_id_content', itemprop: 'identifier')
- if current_user
- %span.access-request-links.gl-ml-3
+ %span.gl-display-inline-block.gl-vertical-align-middle.gl-ml-3
= render 'shared/members/access_request_links', source: @project
.gl-mt-3.gl-pl-3.gl-w-full
@@ -31,7 +31,7 @@
.project-repo-buttons.gl-display-flex.gl-justify-content-md-end.gl-align-items-start.gl-flex-wrap.gl-mt-5
- if current_user
- if current_user.admin?
- = link_to [:admin, @project], class: 'btn gl-button btn-icon gl-align-self-start gl-py-2! gl-mr-3', title: s_('View project in admin area'),
+ = link_to [:admin, @project], class: 'btn gl-button btn-icon gl-align-self-start gl-py-2! gl-mr-3', title: _('View project in admin area'),
data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon('admin')
.gl-display-flex.gl-align-items-start.gl-mr-3
diff --git a/app/views/projects/_import_project_pane.html.haml b/app/views/projects/_import_project_pane.html.haml
index 2055f1c7f60..815a3cf6966 100644
--- a/app/views/projects/_import_project_pane.html.haml
+++ b/app/views/projects/_import_project_pane.html.haml
@@ -76,7 +76,7 @@
- if phabricator_import_enabled?
%div
- = link_to new_import_phabricator_path, class: 'gl-button btn-default btn import_phabricator', data: { track_label: "#{track_label}", track_event: "click_button", track_property: "phabricator" } do
+ = link_to new_import_phabricator_path, class: 'gl-button btn-default btn import_phabricator', data: { track_label: "#{track_label}", track_action: "click_button", track_property: "phabricator" } do
.gl-button-icon
= custom_icon('issues')
= _("Phabricator Tasks")
diff --git a/app/views/projects/_invite_members_empty_project.html.haml b/app/views/projects/_invite_members_empty_project.html.haml
index ee2215b0fbb..5bc53339bf0 100644
--- a/app/views/projects/_invite_members_empty_project.html.haml
+++ b/app/views/projects/_invite_members_empty_project.html.haml
@@ -1,6 +1,6 @@
%h4.gl-mt-0.gl-mb-3{ data: { testid: 'invite-member-section',
track_label: 'invite_members_empty_project',
- track_event: 'render' } }
+ track_action: 'render' } }
= s_('InviteMember|Invite your team')
%p= s_('InviteMember|Add members to this project and start collaborating with your team.')
.js-invite-members-trigger{ data: { variant: 'confirm',
diff --git a/app/views/projects/_new_project_fields.html.haml b/app/views/projects/_new_project_fields.html.haml
index 026c7a0d79d..fb7a7ef8985 100644
--- a/app/views/projects/_new_project_fields.html.haml
+++ b/app/views/projects/_new_project_fields.html.haml
@@ -8,23 +8,25 @@
.form-group.project-name.col-sm-12
= f.label :name, class: 'label-bold' do
%span= _("Project name")
- = f.text_field :name, placeholder: "My awesome project", class: "form-control gl-form-input input-lg", autofocus: true, data: { track_label: "#{track_label}", track_event: "activate_form_input", track_property: "project_name", track_value: "" }, required: true, aria: { required: true }
+ = f.text_field :name, placeholder: "My awesome project", class: "form-control gl-form-input input-lg", data: { track_label: "#{track_label}", track_action: "activate_form_input", track_property: "project_name", track_value: "" }, required: true, aria: { required: true }
.form-group.project-path.col-sm-6
= f.label :namespace_id, class: 'label-bold' do
- %span= s_("Project URL")
+ %span= _('Project URL')
.input-group.gl-flex-nowrap
- if current_user.can_select_namespace?
- .input-group-prepend.flex-shrink-0.has-tooltip{ title: root_url }
- .input-group-text
- = root_url
- namespace_id = namespace_id_from(params)
- = f.select(:namespace_id,
- namespaces_options_with_developer_maintainer_access(selected: namespace_id,
- display_path: true,
- extra_group: namespace_id),
- {},
- { class: 'select2 js-select-namespace qa-project-namespace-select block-truncated', data: { track_label: "#{track_label}", track_event: "activate_form_input", track_property: "project_path", track_value: "", qa_selector: "select_namespace_dropdown" }})
-
+ - if Feature.enabled?(:paginatable_namespace_drop_down_for_project_creation, current_user, default_enabled: :yaml)
+ .js-vue-new-project-url-select{ data: { namespace_full_path: GroupFinder.new(current_user).execute(id: namespace_id)&.full_path, namespace_id: namespace_id, root_url: root_url, track_label: track_label } }
+ - else
+ .input-group-prepend.flex-shrink-0.has-tooltip{ title: root_url }
+ .input-group-text
+ = root_url
+ = f.select(:namespace_id,
+ namespaces_options_with_developer_maintainer_access(selected: namespace_id,
+ display_path: true,
+ extra_group: namespace_id),
+ {},
+ { class: 'select2 js-select-namespace qa-project-namespace-select block-truncated', data: { track_label: "#{track_label}", track_action: "activate_form_input", track_property: "project_path", track_value: "", qa_selector: "select_namespace_dropdown" }})
- else
.input-group-prepend.static-namespace.flex-shrink-0.has-tooltip{ title: user_url(current_user.username) + '/' }
.input-group-text.border-0
@@ -43,7 +45,7 @@
.form-group
= f.label :description, class: 'label-bold' do
= s_('ProjectsNew|Project description %{tag_start}(optional)%{tag_end}').html_safe % { tag_start: '<span>'.html_safe, tag_end: '</span>'.html_safe }
- = f.text_area :description, placeholder: s_('ProjectsNew|Description format'), class: "form-control gl-form-input", rows: 3, maxlength: 250, data: { track_label: "#{track_label}", track_event: "activate_form_input", track_property: "project_description", track_value: "" }
+ = f.text_area :description, placeholder: s_('ProjectsNew|Description format'), class: "form-control gl-form-input", rows: 3, maxlength: 250, data: { track_label: "#{track_label}", track_action: "activate_form_input", track_property: "project_description", track_value: "" }
= f.label :visibility_level, class: 'label-bold' do
= s_('ProjectsNew|Visibility Level')
@@ -54,12 +56,12 @@
.form-group.row.initialize-with-readme-setting
%div{ :class => "col-sm-12" }
.form-check
- = check_box_tag 'project[initialize_with_readme]', '1', true, class: 'form-check-input', data: { qa_selector: "initialize_with_readme_checkbox", track_label: "#{track_label}", track_event: "activate_form_input", track_property: "init_with_readme", track_value: "" }
+ = check_box_tag 'project[initialize_with_readme]', '1', true, class: 'form-check-input', data: { qa_selector: "initialize_with_readme_checkbox", track_label: "#{track_label}", track_action: "activate_form_input", track_property: "init_with_readme", track_value: "" }
= label_tag 'project[initialize_with_readme]', class: 'form-check-label' do
.option-title
%strong= s_('ProjectsNew|Initialize repository with a README')
.option-description
= s_('ProjectsNew|Allows you to immediately clone this project’s repository. Skip this if you plan to push up an existing repository.')
-= f.submit _('Create project'), class: "btn gl-button btn-confirm", data: { track_label: "#{track_label}", track_event: "click_button", track_property: "create_project", track_value: "" }
-= link_to _('Cancel'), dashboard_projects_path, class: 'btn gl-button btn-default btn-cancel', data: { track_label: "#{track_label}", track_event: "click_button", track_property: "cancel", track_value: "" }
+= f.submit _('Create project'), class: "btn gl-button btn-confirm", data: { track_label: "#{track_label}", track_action: "click_button", track_property: "create_project", track_value: "" }
+= link_to _('Cancel'), dashboard_projects_path, class: 'btn gl-button btn-default btn-cancel', data: { track_label: "#{track_label}", track_action: "click_button", track_property: "cancel", track_value: "" }
diff --git a/app/views/projects/blob/_new_dir.html.haml b/app/views/projects/blob/_new_dir.html.haml
index 905dc2a49ec..3cc9fea56e2 100644
--- a/app/views/projects/blob/_new_dir.html.haml
+++ b/app/views/projects/blob/_new_dir.html.haml
@@ -16,6 +16,6 @@
.form-actions
= submit_tag _("Create directory"), class: 'btn gl-button btn-confirm'
- = link_to "Cancel", '#', class: "btn gl-button btn-default btn-cancel", "data-dismiss" => "modal"
+ = link_to _('Cancel'), '#', class: "btn gl-button btn-default btn-cancel", "data-dismiss" => "modal"
= render 'shared/projects/edit_information'
diff --git a/app/views/projects/blob/_remove.html.haml b/app/views/projects/blob/_remove.html.haml
index 298a36e28ec..1463fcf8052 100644
--- a/app/views/projects/blob/_remove.html.haml
+++ b/app/views/projects/blob/_remove.html.haml
@@ -13,4 +13,4 @@
.form-group.row
.offset-sm-2.col-sm-10
= button_tag 'Delete file', class: 'btn gl-button btn-danger btn-remove-file'
- = link_to "Cancel", '#', class: "btn gl-button btn-cancel", "data-dismiss" => "modal"
+ = link_to _('Cancel'), '#', class: "btn gl-button btn-cancel", "data-dismiss" => "modal"
diff --git a/app/views/projects/blob/show.html.haml b/app/views/projects/blob/show.html.haml
index 1ba38808937..66e9badbafb 100644
--- a/app/views/projects/blob/show.html.haml
+++ b/app/views/projects/blob/show.html.haml
@@ -1,4 +1,4 @@
-- breadcrumb_title "Repository"
+- breadcrumb_title _('Repository')
- page_title @blob.path, @ref
- signatures_path = namespace_project_signatures_path(namespace_id: @project.namespace.full_path, project_id: @project.path, id: @last_commit, limit: 1)
- content_for :prefetch_asset_tags do
diff --git a/app/views/projects/blob/viewers/_notebook.html.haml b/app/views/projects/blob/viewers/_notebook.html.haml
index eb4ca1b9816..b537a48e087 100644
--- a/app/views/projects/blob/viewers/_notebook.html.haml
+++ b/app/views/projects/blob/viewers/_notebook.html.haml
@@ -1 +1 @@
-.file-content#js-notebook-viewer{ data: { endpoint: blob_raw_path } }
+.file-content#js-notebook-viewer{ data: { endpoint: blob_raw_path, relative_raw_path: parent_dir_raw_path } }
diff --git a/app/views/projects/branches/new.html.haml b/app/views/projects/branches/new.html.haml
index 6de50d48721..27858932e5e 100644
--- a/app/views/projects/branches/new.html.haml
+++ b/app/views/projects/branches/new.html.haml
@@ -9,7 +9,7 @@
.gl-alert-body
= @error
%h3.page-title
- New Branch
+ = _('New Branch')
%hr
= form_tag namespace_project_branches_path, method: :post, id: "new-branch-form", class: "js-create-branch-form js-requires-input" do
@@ -30,5 +30,5 @@
.form-text.text-muted Existing branch name, tag, or commit SHA
.form-actions
= button_tag 'Create branch', class: 'gl-button btn btn-confirm'
- = link_to 'Cancel', project_branches_path(@project), class: 'gl-button btn btn-default btn-cancel'
+ = link_to _('Cancel'), project_branches_path(@project), class: 'gl-button btn btn-default btn-cancel'
%script#availableRefs{ type: "application/json" }= @project.repository.ref_names.to_json.html_safe
diff --git a/app/views/projects/ci/builds/_build.html.haml b/app/views/projects/ci/builds/_build.html.haml
index 1a3813ba99f..437529c3608 100644
--- a/app/views/projects/ci/builds/_build.html.haml
+++ b/app/views/projects/ci/builds/_build.html.haml
@@ -7,10 +7,14 @@
- pipeline_link = local_assigns.fetch(:pipeline_link, false)
- stage = local_assigns.fetch(:stage, false)
- allow_retry = local_assigns.fetch(:allow_retry, false)
+-# This prevents initializing another Ci::Status object where 'status' is used
+- status = job.detailed_status(current_user)
%tr.build.commit{ class: ('retried' if retried) }
%td.status
- = render "ci/status/badge", status: job.detailed_status(current_user), title: job.status_title
+ -# Sending 'status' prevents calling the user relation inside the presenter, generating N+1,
+ -# see https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68743
+ = render "ci/status/badge", status: status, title: job.status_title(status)
%td
- if can?(current_user, :read_build, job)
diff --git a/app/views/projects/cycle_analytics/show.html.haml b/app/views/projects/cycle_analytics/show.html.haml
index 3c9762e200a..f398ac6ede7 100644
--- a/app/views/projects/cycle_analytics/show.html.haml
+++ b/app/views/projects/cycle_analytics/show.html.haml
@@ -1,6 +1,4 @@
- page_title _("Value Stream Analytics")
- add_page_specific_style 'page_bundles/cycle_analytics'
-- svgs = { empty_state_svg_path: image_path("illustrations/analytics/cycle-analytics-empty-chart.svg"), no_data_svg_path: image_path("illustrations/analytics/cycle-analytics-empty-chart.svg"), no_access_svg_path: image_path("illustrations/analytics/no-access.svg") }
-- initial_data = { project_id: @project.id, group_path: @project.group&.path, request_path: project_cycle_analytics_path(@project), full_path: @project.full_path }.merge!(svgs)
-#js-cycle-analytics{ data: initial_data }
+#js-cycle-analytics{ data: cycle_analytics_initial_data(@project, @group) }
diff --git a/app/views/projects/diffs/_stats.html.haml b/app/views/projects/diffs/_stats.html.haml
index 8edaacf7552..fe9658a440a 100644
--- a/app/views/projects/diffs/_stats.html.haml
+++ b/app/views/projects/diffs/_stats.html.haml
@@ -1,41 +1 @@
-- sum_added_lines = diff_files.sum(&:added_lines)
-- sum_removed_lines = diff_files.sum(&:removed_lines)
-.commit-stat-summary.dropdown
- Showing
- %button.diff-stats-summary-toggler.js-diff-stats-dropdown{ type: "button", data: { toggle: "dropdown", display: "static" } }<
- = pluralize(diff_files.size, "changed file")
- = sprite_icon("chevron-down", css_class: "gl-ml-2")
- %span.diff-stats-additions-deletions-expanded#diff-stats
- with
- %strong.cgreen= pluralize(sum_added_lines, 'addition')
- and
- %strong.cred= pluralize(sum_removed_lines, 'deletion')
- .diff-stats-additions-deletions-collapsed.float-right.d-none{ "aria-hidden": "true", "aria-describedby": "diff-stats" }
- %strong.cgreen<
- +#{sum_added_lines}
- %strong.cred<
- \-#{sum_removed_lines}
- .dropdown-menu.diff-file-changes
- = dropdown_filter("Search files")
- .dropdown-content
- %ul
- - diff_files.each do |diff_file|
- %li
- %a.diff-changed-file{ href: "##{hexdigest(diff_file.file_path)}", title: diff_file.new_path }
- = sprite_icon(diff_file_changed_icon(diff_file), css_class: "#{diff_file_changed_icon_color(diff_file)} diff-file-changed-icon gl-mr-3")
- %span.diff-changed-file-content.gl-mr-3
- - if diff_file.file_path
- %strong.diff-changed-file-name
- = diff_file.file_path
- - else
- %strong.diff-changed-blank-file-name
- = s_('Diffs|No file name available')
- %span.diff-changed-file-path.gl-mt-2= diff_file_path_text(diff_file)
- %span.diff-changed-stats
- %span.cgreen<
- +#{diff_file.added_lines}
- %span.cred<
- \-#{diff_file.removed_lines}
- %li.dropdown-menu-empty-item.hidden
- %a
- = _("No files found.")
+.js-diff-stats-dropdown{ data: { changed: diff_files.size, added: diff_files.sum(&:added_lines), deleted: diff_files.sum(&:removed_lines), files: diff_files_data(diff_files) } }
diff --git a/app/views/projects/error_tracking/details.html.haml b/app/views/projects/error_tracking/details.html.haml
index 4a14e34cbf1..eb26a299a66 100644
--- a/app/views/projects/error_tracking/details.html.haml
+++ b/app/views/projects/error_tracking/details.html.haml
@@ -1,5 +1,5 @@
- page_title _('Error Details')
-- add_to_breadcrumbs 'Errors', project_error_tracking_index_path(@project)
+- add_to_breadcrumbs _('Errors'), project_error_tracking_index_path(@project)
- add_page_specific_style 'page_bundles/error_tracking_details'
#js-error_details{ data: error_details_data(@project, @issue_id) }
diff --git a/app/views/projects/hooks/edit.html.haml b/app/views/projects/hooks/edit.html.haml
index 226cd7d89b6..e8ea4ad90dc 100644
--- a/app/views/projects/hooks/edit.html.haml
+++ b/app/views/projects/hooks/edit.html.haml
@@ -10,7 +10,7 @@
= form_for [@project, @hook], as: :hook, url: project_hook_path(@project, @hook) do |f|
= render partial: 'shared/web_hooks/form', locals: { form: f, hook: @hook }
- = f.submit 'Save changes', class: 'btn gl-button btn-confirm gl-mr-3'
+ = f.submit _('Save changes'), class: 'btn gl-button btn-confirm gl-mr-3'
= render 'shared/web_hooks/test_button', hook: @hook
= link_to _('Delete'), project_hook_path(@project, @hook), method: :delete, class: 'btn gl-button btn-danger float-right', data: { confirm: _('Are you sure?') }
diff --git a/app/views/projects/imports/new.html.haml b/app/views/projects/imports/new.html.haml
index e2d8791b5d2..77c715aa376 100644
--- a/app/views/projects/imports/new.html.haml
+++ b/app/views/projects/imports/new.html.haml
@@ -1,6 +1,6 @@
- page_title _("Import repository")
%h3.page-title
- Import repository
+ = _('Import repository')
%hr
diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml
index ee3aaee6dbb..2de2c2cba6c 100644
--- a/app/views/projects/issues/_issue.html.haml
+++ b/app/views/projects/issues/_issue.html.haml
@@ -12,9 +12,7 @@
- if issue.confidential?
%span.has-tooltip{ title: _('Confidential') }
= confidential_icon(issue)
- - if Feature.enabled?(:ban_user_feature_flag) && issue.hidden?
- %span.has-tooltip{ title: _('This issue is hidden because its author has been banned') }
- = hidden_issue_icon(issue)
+ = hidden_issue_icon(issue)
= link_to issue.title, issue_path(issue)
= render_if_exists 'projects/issues/subepic_flag', issue: issue
- if issue.tasks?
diff --git a/app/views/projects/issues/_nav_btns.html.haml b/app/views/projects/issues/_nav_btns.html.haml
index 1289f7aa0c4..0d69f6f69aa 100644
--- a/app/views/projects/issues/_nav_btns.html.haml
+++ b/app/views/projects/issues/_nav_btns.html.haml
@@ -3,7 +3,7 @@
- show_export_button = local_assigns.fetch(:show_export_button, true)
- issuable_type = 'issues'
- can_edit = can?(current_user, :admin_project, @project)
-- notification_email = @current_user.present? ? @current_user.notification_email : nil
+- notification_email = @current_user.present? ? @current_user.notification_email_or_default : nil
.nav-controls.issues-nav-controls
- if show_feed_buttons
diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml
index ecf10cd4821..53c2052bfab 100644
--- a/app/views/projects/issues/index.html.haml
+++ b/app/views/projects/issues/index.html.haml
@@ -13,8 +13,8 @@
issues_path: project_issues_path(@project),
project_path: @project.full_path } }
-- if Feature.enabled?(:vue_issues_list, @project)
- .js-issues-list{ data: issues_list_data(@project, current_user, finder) }
+- if Feature.enabled?(:vue_issues_list, @project&.group, default_enabled: :yaml)
+ .js-issues-list{ data: project_issues_list_data(@project, current_user, finder) }
- if @can_bulk_update
= render 'shared/issuable/bulk_update_sidebar', type: :issues
- elsif project_issues(@project).exists?
diff --git a/app/views/projects/jobs/index.html.haml b/app/views/projects/jobs/index.html.haml
index 1da3881c104..c58c6ab8287 100644
--- a/app/views/projects/jobs/index.html.haml
+++ b/app/views/projects/jobs/index.html.haml
@@ -1,8 +1,9 @@
- page_title _("Jobs")
- add_page_specific_style 'page_bundles/ci_status'
+- admin = local_assigns.fetch(:admin, false)
- if Feature.enabled?(:jobs_table_vue, @project, default_enabled: :yaml)
- #js-jobs-table{ data: { full_path: @project.full_path, job_counts: job_counts.to_json, job_statuses: job_statuses.to_json, pipeline_editor_path: project_ci_pipeline_editor_path(@project), empty_state_svg_path: image_path('jobs-empty-state.svg') } }
+ #js-jobs-table{ data: { admin: admin, full_path: @project.full_path, job_counts: job_counts.to_json, job_statuses: job_statuses.to_json, pipeline_editor_path: project_ci_pipeline_editor_path(@project), empty_state_svg_path: image_path('jobs-empty-state.svg') } }
- else
.top-area
- build_path_proc = ->(scope) { project_jobs_path(@project, scope: scope) }
diff --git a/app/views/projects/labels/edit.html.haml b/app/views/projects/labels/edit.html.haml
index 343900359b4..8023fb93c64 100644
--- a/app/views/projects/labels/edit.html.haml
+++ b/app/views/projects/labels/edit.html.haml
@@ -3,6 +3,6 @@
- page_title _("Edit"), @label.name, _("Labels")
%h3.page-title
- Edit Label
+ = _('Edit Label')
%hr
= render 'shared/labels/form', url: project_label_path(@project, @label), back_path: project_labels_path(@project)
diff --git a/app/views/projects/labels/new.html.haml b/app/views/projects/labels/new.html.haml
index 38bd6102437..1ae87bf93d1 100644
--- a/app/views/projects/labels/new.html.haml
+++ b/app/views/projects/labels/new.html.haml
@@ -3,6 +3,6 @@
- page_title _("New Label")
%h3.page-title
- New Label
+ = _('New Label')
%hr
= render 'shared/labels/form', url: project_labels_path(@project), back_path: project_labels_path(@project)
diff --git a/app/views/projects/mattermosts/_team_selection.html.haml b/app/views/projects/mattermosts/_team_selection.html.haml
index 4109fdfc13b..4832880eefc 100644
--- a/app/views/projects/mattermosts/_team_selection.html.haml
+++ b/app/views/projects/mattermosts/_team_selection.html.haml
@@ -42,5 +42,5 @@
%hr
.clearfix
.float-right
- = link_to 'Cancel', edit_project_service_path(@project, @integration), class: 'gl-button btn btn-lg'
+ = link_to _('Cancel'), edit_project_service_path(@project, @integration), class: 'gl-button btn btn-lg'
= f.submit 'Install', class: 'gl-button btn btn-success btn-lg'
diff --git a/app/views/projects/merge_requests/_merge_request.atom.builder b/app/views/projects/merge_requests/_merge_request.atom.builder
new file mode 100644
index 00000000000..e27cf93bb97
--- /dev/null
+++ b/app/views/projects/merge_requests/_merge_request.atom.builder
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+xml.entry do
+ xml.id project_merge_request_url(merge_request.project, merge_request)
+ xml.link href: project_merge_request_url(merge_request.project, merge_request)
+ # using the shovel operator (xml <<) would make us lose indentation, so we do this (https://github.com/rails/rails/issues/7036)
+ render(partial: 'shared/issuable/issuable', object: merge_request, locals: { builder: xml })
+end
diff --git a/app/views/projects/merge_requests/_merge_requests.html.haml b/app/views/projects/merge_requests/_merge_requests.html.haml
index e2123e36e67..0abbf953fc7 100644
--- a/app/views/projects/merge_requests/_merge_requests.html.haml
+++ b/app/views/projects/merge_requests/_merge_requests.html.haml
@@ -2,7 +2,7 @@
- if @merge_requests.present?
= render @merge_requests
- else
- = render 'shared/empty_states/merge_requests'
+ = render 'shared/empty_states/merge_requests', button_path: new_merge_request_path
- if @merge_requests.present?
= paginate_collection @merge_requests, total_pages: @total_pages
diff --git a/app/views/projects/merge_requests/_nav_btns.html.haml b/app/views/projects/merge_requests/_nav_btns.html.haml
index 511e53b192f..b34cf23634c 100644
--- a/app/views/projects/merge_requests/_nav_btns.html.haml
+++ b/app/views/projects/merge_requests/_nav_btns.html.haml
@@ -1,6 +1,7 @@
- issuable_type = 'merge-requests'
-- notification_email = @current_user.present? ? @current_user.notification_email : nil
+- notification_email = @current_user.present? ? @current_user.notification_email_or_default : nil
+= render 'shared/issuable/feed_buttons', show_calendar_button: false
.js-csv-import-export-buttons{ data: { show_export_button: "true", issuable_type: issuable_type, issuable_count: issuables_count_for_state(issuable_type.to_sym, params[:state]), email: notification_email, export_csv_path: export_csv_project_merge_requests_path(@project, request.query_parameters), container_class: 'gl-mr-3' } }
- if @can_bulk_update
diff --git a/app/views/projects/merge_requests/_widget.html.haml b/app/views/projects/merge_requests/_widget.html.haml
index 5f2cb1cfcc4..47a0d05fc65 100644
--- a/app/views/projects/merge_requests/_widget.html.haml
+++ b/app/views/projects/merge_requests/_widget.html.haml
@@ -18,5 +18,7 @@
window.gl.mrWidgetData.approvals_help_path = '#{help_page_path("user/project/merge_requests/merge_request_approvals")}';
window.gl.mrWidgetData.pipelines_empty_svg_path = '#{image_path('illustrations/pipelines_empty.svg')}';
window.gl.mrWidgetData.codequality_help_path = '#{help_page_path("user/project/merge_requests/code_quality", anchor: "code-quality-reports")}';
+ window.gl.mrWidgetData.false_positive_doc_url = '#{help_page_path('user/application_security/vulnerabilities/index')}';
+ window.gl.mrWidgetData.can_view_false_positive = '#{(Feature.enabled?(:vulnerability_flags, default_enabled: :yaml) && @merge_request.project.licensed_feature_available?(:sast_fp_reduction)).to_s}';
#js-vue-mr-widget.mr-widget
diff --git a/app/views/projects/merge_requests/creations/_new_compare.html.haml b/app/views/projects/merge_requests/creations/_new_compare.html.haml
index b99714c1794..ea778517374 100644
--- a/app/views/projects/merge_requests/creations/_new_compare.html.haml
+++ b/app/views/projects/merge_requests/creations/_new_compare.html.haml
@@ -1,5 +1,5 @@
%h3.page-title
- New merge request
+ = _('New merge request')
= form_for [@project, @merge_request], url: project_new_merge_request_path(@project), method: :get, html: { class: "merge-request-form js-requires-input" } do |f|
- if params[:nav_source].present?
diff --git a/app/views/projects/merge_requests/creations/_new_submit.html.haml b/app/views/projects/merge_requests/creations/_new_submit.html.haml
index 4aca13ae74a..eb5d052ec19 100644
--- a/app/views/projects/merge_requests/creations/_new_submit.html.haml
+++ b/app/views/projects/merge_requests/creations/_new_submit.html.haml
@@ -1,5 +1,5 @@
%h3.page-title
- New merge request
+ = _('New merge request')
= form_for [@project, @merge_request], html: { class: 'merge-request-form common-note-form js-requires-input js-quick-submit' } do |f|
= render 'shared/issuable/form', f: f, issuable: @merge_request, commits: @commits, presenter: @mr_presenter
= f.hidden_field :source_project_id
diff --git a/app/views/projects/merge_requests/index.atom.builder b/app/views/projects/merge_requests/index.atom.builder
new file mode 100644
index 00000000000..36fe6bf759b
--- /dev/null
+++ b/app/views/projects/merge_requests/index.atom.builder
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+# rubocop: disable CodeReuse/ActiveRecord
+xml.title "#{@project.name} merge requests"
+xml.link href: url_for(safe_params), rel: "self", type: "application/atom+xml"
+xml.link href: project_merge_requests_url(@project), rel: "alternate", type: "text/html"
+xml.id project_merge_requests_url(@project)
+xml.updated @merge_requests.first.updated_at.xmlschema if @merge_requests.reorder(nil).any?
+
+xml << render(partial: 'projects/merge_requests/merge_request', collection: @merge_requests) if @merge_requests.reorder(nil).any?
+# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml
index 289f88c9705..41c6696789d 100644
--- a/app/views/projects/merge_requests/index.html.haml
+++ b/app/views/projects/merge_requests/index.html.haml
@@ -6,6 +6,9 @@
- page_title _("Merge requests")
- new_merge_request_email = @project.new_issuable_address(current_user, 'merge_request')
+= content_for :meta_tags do
+ = auto_discovery_link_tag(:atom, safe_params.merge(rss_url_options).to_h, title: "#{@project.name} merge requests")
+
= render 'projects/last_push'
- if @project.merge_requests.exists?
@@ -20,7 +23,7 @@
= render 'shared/issuable/bulk_update_sidebar', type: :merge_requests
.merge-requests-holder
- = render 'merge_requests'
+ = render 'merge_requests', new_merge_request_path: new_merge_request_path
- if new_merge_request_email
.gl-text-center.gl-pt-5.gl-pb-7
.js-issueable-by-email{ data: { initial_email: new_merge_request_email, issuable_type: issuable_type, emails_help_page_path: help_page_path('development/emails', anchor: 'email-namespace'), quick_actions_help_path: help_page_path('user/project/quick_actions'), markdown_help_path: help_page_path('user/markdown'), reset_path: new_issuable_address_project_path(@project, issuable_type: issuable_type) } }
diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml
index 6d1ba9e693b..7e260a03c5d 100644
--- a/app/views/projects/merge_requests/show.html.haml
+++ b/app/views/projects/merge_requests/show.html.haml
@@ -6,7 +6,6 @@
- page_description @merge_request.description_html
- page_card_attributes @merge_request.card_attributes
- suggest_changes_help_path = help_page_path('user/project/merge_requests/reviews/suggestions.md')
-- number_of_pipelines = @pipelines.size
- mr_action = j(params[:tab].presence || 'show')
- add_page_specific_style 'page_bundles/merge_requests'
- add_page_specific_style 'page_bundles/pipelines'
@@ -32,11 +31,11 @@
= tab_link_for @merge_request, :commits do
= _("Commits")
%span.badge.badge-pill.gl-badge.badge-muted.sm= @commits_count
- - if number_of_pipelines.nonzero?
+ - if @number_of_pipelines.nonzero?
= render "projects/merge_requests/tabs/tab", name: "pipelines", class: "pipelines-tab" do
= tab_link_for @merge_request, :pipelines do
= _("Pipelines")
- %span.badge.badge-pill.gl-badge.badge-muted.sm.js-pipelines-mr-count= number_of_pipelines
+ %span.badge.badge-pill.gl-badge.badge-muted.sm.js-pipelines-mr-count= @number_of_pipelines
= render "projects/merge_requests/tabs/tab", name: "diffs", class: "diffs-tab", id: "diffs-tab", qa_selector: "diffs_tab" do
= tab_link_for @merge_request, :diffs do
= _("Changes")
@@ -76,7 +75,7 @@
= render "projects/merge_requests/tabs/pane", name: "commits", id: "commits", class: "commits" do
-# This tab is always loaded via AJAX
= render "projects/merge_requests/tabs/pane", name: "pipelines", id: "pipelines", class: "pipelines" do
- - if number_of_pipelines.nonzero?
+ - if @number_of_pipelines.nonzero?
= render 'projects/commit/pipelines_list', disable_initialization: true, endpoint: pipelines_project_merge_request_path(@project, @merge_request)
- params = request.query_parameters
- if Feature.enabled?(:default_merge_ref_for_diffs, @project, default_enabled: :yaml)
diff --git a/app/views/projects/packages/packages/show.html.haml b/app/views/projects/packages/packages/show.html.haml
index 42c31b3272f..ebdc9e654f6 100644
--- a/app/views/projects/packages/packages/show.html.haml
+++ b/app/views/projects/packages/packages/show.html.haml
@@ -6,7 +6,4 @@
.row
.col-12
- - if Feature.enabled?(:package_details_apollo, default_enabled: :yaml)
- #js-vue-packages-detail-new{ data: package_details_data(@project, @package) }
- - else
- #js-vue-packages-detail{ data: package_details_data(@project, @package, true) }
+ #js-vue-packages-detail-new{ data: package_details_data(@project, @package) }
diff --git a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml
index 190bf9bf071..f6a0638ccd0 100644
--- a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml
+++ b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml
@@ -27,7 +27,7 @@
%td
.float-right.btn-group
- if can?(current_user, :play_pipeline_schedule, pipeline_schedule)
- = link_to play_pipeline_schedule_path(pipeline_schedule), method: :post, title: s_('Play'), class: 'btn gl-button btn-default btn-icon' do
+ = link_to play_pipeline_schedule_path(pipeline_schedule), method: :post, title: _('Play'), class: 'btn gl-button btn-default btn-icon' do
= sprite_icon('play')
- if can?(current_user, :take_ownership_pipeline_schedule, pipeline_schedule)
= link_to take_ownership_pipeline_schedule_path(pipeline_schedule), method: :post, title: s_('PipelineSchedules|Take ownership'), class: 'btn gl-button btn-default' do
diff --git a/app/views/projects/pipeline_schedules/new.html.haml b/app/views/projects/pipeline_schedules/new.html.haml
index a2652304768..1b50090e445 100644
--- a/app/views/projects/pipeline_schedules/new.html.haml
+++ b/app/views/projects/pipeline_schedules/new.html.haml
@@ -1,4 +1,4 @@
-- breadcrumb_title "Schedules"
+- breadcrumb_title _('Schedules')
- @breadcrumb_link = namespace_project_pipeline_schedules_path(@project.namespace, @project)
- page_title _("New Pipeline Schedule")
- add_page_specific_style 'page_bundles/pipeline_schedules'
diff --git a/app/views/projects/pipelines/_with_tabs.html.haml b/app/views/projects/pipelines/_with_tabs.html.haml
index c1d48992500..23606e24563 100644
--- a/app/views/projects/pipelines/_with_tabs.html.haml
+++ b/app/views/projects/pipelines/_with_tabs.html.haml
@@ -34,8 +34,8 @@
%thead
%tr
%th= _('Status')
- %th= _('Job ID')
%th= _('Name')
+ %th= _('Job ID')
%th
%th= _('Coverage')
%th
diff --git a/app/views/projects/pipelines/show.html.haml b/app/views/projects/pipelines/show.html.haml
index 30ebe4f20b6..8fd8d3cf540 100644
--- a/app/views/projects/pipelines/show.html.haml
+++ b/app/views/projects/pipelines/show.html.haml
@@ -28,4 +28,4 @@
= render "projects/pipelines/with_tabs", pipeline: @pipeline, stages: @stages, pipeline_has_errors: pipeline_has_errors
-.js-pipeline-details-vue{ data: { endpoint: project_pipeline_path(@project, @pipeline, format: :json), metrics_path: namespace_project_ci_prometheus_metrics_histograms_path(namespace_id: @project.namespace, project_id: @project, format: :json), pipeline_project_path: @project.full_path, pipeline_iid: @pipeline.iid, graphql_resource_etag: graphql_etag_pipeline_path(@pipeline) } }
+.js-pipeline-details-vue{ data: { metrics_path: namespace_project_ci_prometheus_metrics_histograms_path(namespace_id: @project.namespace, project_id: @project, format: :json), pipeline_project_path: @project.full_path, pipeline_iid: @pipeline.iid, graphql_resource_etag: graphql_etag_pipeline_path(@pipeline) } }
diff --git a/app/views/projects/project_members/index.html.haml b/app/views/projects/project_members/index.html.haml
index 0239e408e87..12b2b33e364 100644
--- a/app/views/projects/project_members/index.html.haml
+++ b/app/views/projects/project_members/index.html.haml
@@ -3,7 +3,7 @@
.row.gl-mt-3
.col-lg-12
- - if can_invite_members_for_project?(@project) || can_invite_group_for_project?(@project)
+ - if can_invite_members_for_project?(@project)
.row
.col-md-12.col-lg-6.gl-display-flex
.gl-flex-direction-column.gl-flex-wrap.align-items-baseline
@@ -18,10 +18,7 @@
.col-md-12.col-lg-6
.gl-display-flex.gl-flex-wrap.gl-justify-content-end
- if can_admin_project_member?(@project)
- = link_to _("Import a project"),
- import_project_project_members_path(@project),
- class: "btn btn-default btn-md gl-button gl-mt-3 gl-sm-w-auto gl-w-full",
- title: _("Import members from another project")
+ .js-import-a-project-modal{ data: { project_id: @project.id, project_name: @project.name } }
- if @project.allowed_to_share_with_group?
.js-invite-group-trigger{ data: { classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3', display_text: _('Invite a group') } }
- if can_admin_project_member?(@project)
diff --git a/app/views/projects/project_templates/_template.html.haml b/app/views/projects/project_templates/_template.html.haml
index 827ff62f8c3..5e4b1397dd3 100644
--- a/app/views/projects/project_templates/_template.html.haml
+++ b/app/views/projects/project_templates/_template.html.haml
@@ -8,9 +8,9 @@
.text-muted
= template.description
.controls.d-flex.align-items-center
- %a.btn.gl-button.btn-default.gl-mr-3{ href: template.preview, rel: 'noopener noreferrer', target: '_blank', data: { track_label: "template_preview", track_property: template.name, track_event: "click_button", track_value: "" } }
+ %a.btn.gl-button.btn-default.gl-mr-3{ href: template.preview, rel: 'noopener noreferrer', target: '_blank', data: { track_label: "template_preview", track_property: template.name, track_action: "click_button", track_value: "" } }
= _("Preview")
%label.btn.gl-button.btn-confirm.template-button.choose-template.gl-mb-0{ for: template.name }
- %input{ type: "radio", autocomplete: "off", name: "project[template_name]", id: template.name, value: template.name, data: { track_label: "template_use", track_property: template.name, track_event: "click_button", track_value: "" } }
+ %input{ type: "radio", autocomplete: "off", name: "project[template_name]", id: template.name, value: template.name, data: { track_label: "template_use", track_property: template.name, track_action: "click_button", track_value: "" } }
%span{ data: { qa_selector: 'use_template_button' } }
= _("Use template")
diff --git a/app/views/projects/services/slack_slash_commands/_help.html.haml b/app/views/projects/services/slack_slash_commands/_help.html.haml
index 9702f9b08f2..fee0ca15808 100644
--- a/app/views/projects/services/slack_slash_commands/_help.html.haml
+++ b/app/views/projects/services/slack_slash_commands/_help.html.haml
@@ -4,22 +4,21 @@
.info-well
.well-segment
%p
- = s_("SlackService|This service allows users to perform common operations on this project by entering slash commands in Slack.")
+ = s_("SlackService|Perform common operations in this project by entering slash commands in Slack.")
= link_to help_page_path('user/project/integrations/slack_slash_commands.md'), target: '_blank' do
- = _("View documentation")
+ = _("Learn more.")
= sprite_icon('external-link')
%p.inline
- = s_("SlackService|See list of available commands in Slack after setting up this service, by entering")
- %kbd.inline /&lt;command&gt; help
+ = s_("SlackService|After setup, get a list of available Slack slash commands by entering")
+ %kbd.inline /&lt;command&gt; help
- if integration.project_level?
- %p= _("To set up this service:")
+ %p= _("To set up this integration:")
%ul.list-unstyled.indent-list
%li
- 1.
- = link_to 'https://my.slack.com/services/new/slash-commands', target: '_blank', rel: 'noreferrer noopener nofollow' do
- Add a slash command
- = sprite_icon('external-link')
- in your Slack team with these options:
+ - slash_command_link_url = 'https://my.slack.com/services/new/slash-commands'
+ - slash_command_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: slash_command_link_url }
+ - slash_command_link_end = ' %{external_link_icon}</a>'.html_safe % { external_link_icon: sprite_icon('external-link') }
+ = html_escape(s_('SlackService|1. %{slash_command_link_start}Add a slash command%{slash_command_link_end} in your Slack team using this information:')) % { slash_command_link_start: slash_command_link_start, slash_command_link_end: slash_command_link_end }
%hr
@@ -89,6 +88,6 @@
%ul.list-unstyled.indent-list
%li
- = html_escape(s_("SlackService|2. Paste the %{strong_open}Token%{strong_close} into the field below")) % { strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe }
+ = html_escape(s_("SlackService|2. Paste the token from Slack in the %{strong_open}Token%{strong_close} field below.")) % { strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe }
%li
- = html_escape(s_("SlackService|3. Select the %{strong_open}Active%{strong_close} checkbox, press %{strong_open}Save changes%{strong_close} and start using GitLab inside Slack!")) % { strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe }
+ = html_escape(s_("SlackService|3. Select the %{strong_open}Active%{strong_close} checkbox, select %{strong_open}Save changes%{strong_close}, and start using slash commands in Slack!")) % { strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe }
diff --git a/app/views/projects/settings/ci_cd/show.html.haml b/app/views/projects/settings/ci_cd/show.html.haml
index 70626636ac0..75bd985560b 100644
--- a/app/views/projects/settings/ci_cd/show.html.haml
+++ b/app/views/projects/settings/ci_cd/show.html.haml
@@ -105,6 +105,6 @@
= expanded ? _('Collapse') : _('Expand')
%p
= _("Control which projects can be accessed by API requests authenticated with this project's CI_JOB_TOKEN CI/CD variable. It is a security risk to disable this feature, because unauthorized projects might attempt to retrieve an active token and access the API.")
- = link_to _('Learn more'), help_page_path('api/index', anchor: 'limit-gitlab-cicd-job-token-access'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to _('Learn more'), help_page_path('ci/jobs/ci_job_token'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= render 'ci/token_access/index'
diff --git a/app/views/projects/settings/operations/_error_tracking.html.haml b/app/views/projects/settings/operations/_error_tracking.html.haml
index 4ef9e1bd6fb..6b2a1468eec 100644
--- a/app/views/projects/settings/operations/_error_tracking.html.haml
+++ b/app/views/projects/settings/operations/_error_tracking.html.haml
@@ -17,4 +17,5 @@
project: error_tracking_setting_project_json,
api_host: setting.api_host,
enabled: setting.enabled.to_json,
+ integrated: setting.integrated.to_json,
token: setting.token.present? ? '*' * 12 : nil } }
diff --git a/app/views/projects/tags/releases/edit.html.haml b/app/views/projects/tags/releases/edit.html.haml
index 88594209c3b..c99f146ea7a 100644
--- a/app/views/projects/tags/releases/edit.html.haml
+++ b/app/views/projects/tags/releases/edit.html.haml
@@ -15,5 +15,5 @@
= render 'shared/notes/hints'
.error-alert
.gl-mt-5.gl-display-flex
- = f.submit 'Save changes', class: 'btn gl-button btn-confirm gl-mr-3'
- = link_to "Cancel", project_tag_path(@project, @tag.name), class: "btn gl-button btn-default btn-cancel"
+ = f.submit _('Save changes'), class: 'btn gl-button btn-confirm gl-mr-3'
+ = link_to _('Cancel'), project_tag_path(@project, @tag.name), class: "btn gl-button btn-default btn-cancel"
diff --git a/app/views/projects/usage_quotas/index.html.haml b/app/views/projects/usage_quotas/index.html.haml
new file mode 100644
index 00000000000..dfd46af0499
--- /dev/null
+++ b/app/views/projects/usage_quotas/index.html.haml
@@ -0,0 +1,19 @@
+- page_title s_("UsageQuota|Usage")
+
+%h3.page-title
+ = s_('UsageQuota|Usage Quotas')
+
+.row
+ .col-sm-12
+ = s_('UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project').html_safe % { strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe, project_name: @project.name } + '.'
+ %a{ href: help_page_path('user/usage_quotas.md') }
+ = s_('UsageQuota|Learn more about usage quotas') + '.'
+
+.top-area.scrolling-tabs-container.inner-page-scroll-tabs
+ %ul.nav.nav-tabs.nav-links.scrolling-tabs.separator.js-usage-quota-tabs{ role: 'tablist' }
+ %li.nav-item
+ %a.nav-link#storage-quota{ data: { toggle: "tab", action: '#storage-quota-tab' }, href: '#storage-quota-tab', 'aria-controls': '#storage-quota-tab', 'aria-selected': 'true' }
+ = s_('UsageQuota|Storage')
+.tab-content
+ .tab-pane#storage-quota-tab
+ #js-project-storage-count-app{ data: @storage_app_data }
diff --git a/app/views/projects/work_items/index.html.haml b/app/views/projects/work_items/index.html.haml
new file mode 100644
index 00000000000..052db598571
--- /dev/null
+++ b/app/views/projects/work_items/index.html.haml
@@ -0,0 +1,3 @@
+- page_title s_('WorkItem|Work Items')
+
+#js-work-items
diff --git a/app/views/registrations/experience_levels/show.html.haml b/app/views/registrations/experience_levels/show.html.haml
deleted file mode 100644
index 16e59757147..00000000000
--- a/app/views/registrations/experience_levels/show.html.haml
+++ /dev/null
@@ -1,29 +0,0 @@
-- page_title _('What’s your experience level?')
-- @hide_flash = true
-
-.gl-display-flex.gl-flex-direction-column.gl-align-items-center
- = image_tag 'learn-gitlab-avatar.jpg', width: '90'
-
- %h2.gl-text-center.gl-mt-3.gl-mb-3= _('Hello there')
- %p.gl-text-center.gl-font-lg.gl-mb-6= _('Welcome to the guided GitLab tour')
-
- %h3.gl-text-center.gl-font-lg.gl-mt-6.gl-mb-0= _('What describes you best?')
-
- .card-deck.gl-mt-6
- .card
- .card-body.gl-display-flex.gl-py-8.gl-pr-5.gl-pl-7
- .gl-align-self-center.gl-pr-6
- = image_tag 'novice.svg', width: '78', height: '78', alt: ''
- %div
- %p.gl-font-lg.gl-font-weight-bold.gl-mb-2= _('Novice')
- %p= _('I’m not familiar with the basics of DevOps.')
- = link_to _('Show me the basics'), users_sign_up_experience_level_path(experience_level: :novice, namespace_path: params[:namespace_path]), method: :patch, class: 'stretched-link'
-
- .card
- .card-body.gl-display-flex.gl-py-8.gl-pr-5.gl-pl-7
- .gl-align-self-center.gl-pr-6
- = image_tag 'experienced.svg', width: '78', height: '78', alt: ''
- %div
- %p.gl-font-lg.gl-font-weight-bold.gl-mb-2= _('Experienced')
- %p= _('I’m familiar with the basics of DevOps.')
- = link_to _('Show me advanced features'), users_sign_up_experience_level_path(experience_level: :experienced, namespace_path: params[:namespace_path]), method: :patch, class: 'stretched-link'
diff --git a/app/views/search/_category.html.haml b/app/views/search/_category.html.haml
index 7f8a530deb8..ca6f2369bd8 100644
--- a/app/views/search/_category.html.haml
+++ b/app/views/search/_category.html.haml
@@ -27,11 +27,11 @@
= search_filter_link 'snippet_titles', _("Titles and Descriptions"), search: { snippets: true, group_id: nil, project_id: nil }
- else
= search_filter_link 'projects', _("Projects"), data: { qa_selector: 'projects_tab' }
- = render_if_exists 'search/category_code'
+ = render_if_exists 'search/category_code' if feature_flag_tab_enabled?(:global_search_code_tab)
= render_if_exists 'search/epics_filter_link'
- = search_filter_link 'issues', _("Issues")
- = search_filter_link 'merge_requests', _("Merge requests")
- = render_if_exists 'search/category_wiki'
+ = search_filter_link 'issues', _("Issues") if feature_flag_tab_enabled?(:global_search_issues_tab)
+ = search_filter_link 'merge_requests', _("Merge requests") if feature_flag_tab_enabled?(:global_search_merge_requests_tab)
+ = render_if_exists 'search/category_wiki' if feature_flag_tab_enabled?(:global_search_wiki_tab)
= render_if_exists 'search/category_elasticsearch'
= search_filter_link 'milestones', _("Milestones")
= users
diff --git a/app/views/search/results/_blob_data.html.haml b/app/views/search/results/_blob_data.html.haml
index 2f13d7d96c7..88a2ab4bb42 100644
--- a/app/views/search/results/_blob_data.html.haml
+++ b/app/views/search/results/_blob_data.html.haml
@@ -1,7 +1,7 @@
-.blob-result.gl-mt-3.gl-mb-5{ data: { qa_selector: 'result_item_content' } }
+.js-blob-result.gl-mt-3.gl-mb-5{ data: { qa_selector: 'result_item_content' } }
.file-holder.file-holder-top-border
.js-file-title.file-title{ data: { qa_selector: 'file_title_content' } }
- = link_to blob_link, data: {track_event: 'click_text', track_label: 'blob_path', track_property: 'search_result'} do
+ = link_to blob_link, data: {track_action: 'click_text', track_label: 'blob_path', track_property: 'search_result'} do
= sprite_icon('document')
%strong
= search_blob_title(project, path)
diff --git a/app/views/search/results/_commit.html.haml b/app/views/search/results/_commit.html.haml
index 3e5ea785aae..7aeeef5faed 100644
--- a/app/views/search/results/_commit.html.haml
+++ b/app/views/search/results/_commit.html.haml
@@ -1 +1 @@
-= render 'projects/commits/commit', project: commit.project, commit: commit, ref: nil, show_project_name: @project.nil?, link_data_attrs: {track_event: 'click_text', track_label: 'commit_title', track_property: 'search_result'}
+= render 'projects/commits/commit', project: commit.project, commit: commit, ref: nil, show_project_name: @project.nil?, link_data_attrs: {track_action: 'click_text', track_label: 'commit_title', track_property: 'search_result'}
diff --git a/app/views/search/results/_issuable.html.haml b/app/views/search/results/_issuable.html.haml
index 63524bbf00e..5645fbfb238 100644
--- a/app/views/search/results/_issuable.html.haml
+++ b/app/views/search/results/_issuable.html.haml
@@ -3,7 +3,7 @@
%span.gl-display-flex.gl-align-items-center
%span.badge.badge-pill.gl-badge.sm{ class: "badge-#{issuable_state_to_badge_class(issuable)}" }= issuable_state_text(issuable)
= sprite_icon('eye-slash', css_class: 'gl-text-gray-500 gl-ml-2') if issuable.respond_to?(:confidential?) && issuable.confidential?
- = link_to issuable_path(issuable), data: { track_event: 'click_text', track_label: "#{issuable.class.name.downcase}_title", track_property: 'search_result' }, class: 'gl-w-full' do
+ = link_to issuable_path(issuable), data: { track_action: 'click_text', track_label: "#{issuable.class.name.downcase}_title", track_property: 'search_result' }, class: 'gl-w-full' do
%span.term.str-truncated.gl-font-weight-bold.gl-ml-2= issuable.title
.gl-text-gray-500.gl-my-3
= issuable_project_reference(issuable)
diff --git a/app/views/search/results/_milestone.html.haml b/app/views/search/results/_milestone.html.haml
index 6d4ce88a377..a57c94c19c9 100644
--- a/app/views/search/results/_milestone.html.haml
+++ b/app/views/search/results/_milestone.html.haml
@@ -1,6 +1,6 @@
.search-result-row
%h4
- = link_to project_milestone_path(milestone.project, milestone), data: {track_event: 'click_text', track_label: 'milestone_title', track_property: 'search_result'} do
+ = link_to project_milestone_path(milestone.project, milestone), data: {track_action: 'click_text', track_label: 'milestone_title', track_property: 'search_result'} do
%span.term.str-truncated= milestone.title
- if milestone.description.present?
diff --git a/app/views/search/results/_note.html.haml b/app/views/search/results/_note.html.haml
index 8d5d8670b5c..67f16075649 100644
--- a/app/views/search/results/_note.html.haml
+++ b/app/views/search/results/_note.html.haml
@@ -18,7 +18,7 @@
- else
%span #{note.noteable_type.titleize} ##{noteable_identifier}
&middot;
- = link_to note.noteable.title, note_url, data: {track_event: 'click_text', track_label: 'noteable_title', track_property: 'search_result'}
+ = link_to note.noteable.title, note_url, data: {track_action: 'click_text', track_label: 'noteable_title', track_property: 'search_result'}
%span.note-headline-light.note-headline-meta
%span.system-note-separator
diff --git a/app/views/search/results/_wiki_blob.html.haml b/app/views/search/results/_wiki_blob.html.haml
index 55161ce333b..b59275c35df 100644
--- a/app/views/search/results/_wiki_blob.html.haml
+++ b/app/views/search/results/_wiki_blob.html.haml
@@ -3,7 +3,7 @@
%div{ class: 'search-result-row gl-pb-3! gl-mt-5 gl-mb-0!' }
%span.gl-display-flex.gl-align-items-center
- = link_to wiki_blob_link, data: { track_event: 'click_text', track_label: "wiki_title", track_property: 'search_result' }, class: 'gl-w-full' do
+ = link_to wiki_blob_link, data: { track_action: 'click_text', track_label: "wiki_title", track_property: 'search_result' }, class: 'gl-w-full' do
%span.term.str-truncated.gl-font-weight-bold= ::Gitlab::Git::Wiki::GollumSlug.canonicalize_filename(wiki_blob.path)
.description.term.col-sm-10.gl-px-0
= simple_search_highlight_and_truncate(wiki_blob.data, @search_term)
diff --git a/app/views/shared/_check_recovery_settings.html.haml b/app/views/shared/_check_recovery_settings.html.haml
deleted file mode 100644
index 2ba0cca9ef6..00000000000
--- a/app/views/shared/_check_recovery_settings.html.haml
+++ /dev/null
@@ -1,11 +0,0 @@
-= render 'shared/global_alert',
- variant: :warning,
- alert_class: 'js-recovery-settings-callout',
- alert_data: { feature_id: 'account_recovery_regular_check', dismiss_endpoint: user_callouts_path, defer_links: 'true' },
- close_button_data: { testid: 'close-account-recovery-regular-check-callout' } do
- .gl-alert-body
- = s_('Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place.')
- = link_to _('Learn more.'), help_page_path('user/profile/account/two_factor_authentication', anchor: 'recovery-codes'), target: '_blank', rel: 'noopener noreferrer'
- .gl-alert-actions
- = link_to profile_two_factor_auth_path, class: 'deferred-link btn gl-alert-action btn-confirm btn-md gl-button' do
- = s_('Profiles|Manage two-factor authentication')
diff --git a/app/views/shared/_help_dropdown_forum_link.html.haml b/app/views/shared/_help_dropdown_forum_link.html.haml
index 351c875475a..f3c69a7c897 100644
--- a/app/views/shared/_help_dropdown_forum_link.html.haml
+++ b/app/views/shared/_help_dropdown_forum_link.html.haml
@@ -1,2 +1,2 @@
= link_to _("Community forum"), "https://forum.gitlab.com/", target: '_blank', class: 'text-nowrap',
- rel: 'noopener noreferrer', data: { 'track_event': 'click_forum', 'track_property': 'question_menu' }
+ rel: 'noopener noreferrer', data: { 'track_action': 'click_forum', 'track_property': 'question_menu' }
diff --git a/app/views/shared/_two_factor_auth_recovery_settings_check.html.haml b/app/views/shared/_two_factor_auth_recovery_settings_check.html.haml
new file mode 100644
index 00000000000..d4764d1a5d9
--- /dev/null
+++ b/app/views/shared/_two_factor_auth_recovery_settings_check.html.haml
@@ -0,0 +1,11 @@
+= render 'shared/global_alert',
+ variant: :warning,
+ alert_class: 'js-recovery-settings-callout',
+ alert_data: { feature_id: UserCalloutsHelper::TWO_FACTOR_AUTH_RECOVERY_SETTINGS_CHECK, dismiss_endpoint: user_callouts_path, defer_links: 'true' },
+ close_button_data: { testid: 'close-account-recovery-regular-check-callout' } do
+ .gl-alert-body
+ = s_('Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place.')
+ = link_to _('Learn more.'), help_page_path('user/profile/account/two_factor_authentication', anchor: 'recovery-codes'), target: '_blank', rel: 'noopener noreferrer'
+ .gl-alert-actions
+ = link_to profile_two_factor_auth_path, class: 'deferred-link btn gl-alert-action btn-confirm btn-md gl-button' do
+ = s_('Profiles|Manage two-factor authentication')
diff --git a/app/views/shared/_visibility_level.html.haml b/app/views/shared/_visibility_level.html.haml
index 84ce40e240c..3e30dcaf35a 100644
--- a/app/views/shared/_visibility_level.html.haml
+++ b/app/views/shared/_visibility_level.html.haml
@@ -7,7 +7,7 @@
= _('Who can see this group?')
- visibility_docs_path = help_page_path('public_access/public_access')
- docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: visibility_docs_path }
- = s_('Check the %{docs_link_start}documentation%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe }
+ = _('%{docs_link_start}Learn about visibility levels.%{docs_link_end}').html_safe % { docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe }
- if can_change_visibility_level
= render('shared/visibility_radios', model_method: :visibility_level, form: f, selected_level: visibility_level, form_model: form_model)
- else
diff --git a/app/views/shared/_visibility_radios.html.haml b/app/views/shared/_visibility_radios.html.haml
index 90b12557bc8..f48bfcd0e72 100644
--- a/app/views/shared/_visibility_radios.html.haml
+++ b/app/views/shared/_visibility_radios.html.haml
@@ -3,7 +3,7 @@
- available_visibility_levels.each do |level|
.form-check
- = form.radio_button model_method, level, checked: (selected_level == level), class: 'form-check-input', data: { track_label: "blank_project", track_event: "activate_form_input", track_property: "#{model_method}_#{level}", track_value: "", qa_selector: "#{visibility_level_label(level).downcase}_radio" }
+ = form.radio_button model_method, level, checked: (selected_level == level), class: 'form-check-input', data: { track_label: "blank_project", track_action: "activate_form_input", track_property: "#{model_method}_#{level}", track_value: "", qa_selector: "#{visibility_level_label(level).downcase}_radio" }
= form.label "#{model_method}_#{level}", class: 'form-check-label' do
= visibility_level_icon(level)
.option-title
diff --git a/app/views/shared/access_tokens/_table.html.haml b/app/views/shared/access_tokens/_table.html.haml
index 33d6b9573d4..c096044e439 100644
--- a/app/views/shared/access_tokens/_table.html.haml
+++ b/app/views/shared/access_tokens/_table.html.haml
@@ -51,7 +51,7 @@
= _('Expired')
- else
%span{ class: ('text-warning' if token.expires_soon?) }
- = _('In %{time_to_now}') % { time_to_now: distance_of_time_in_words_to_now(token.expires_at) }
+ = time_ago_with_tooltip(token.expires_at)
- else
%span.token-never-expires-label= _('Never')
- if project
diff --git a/app/views/shared/boards/_show.html.haml b/app/views/shared/boards/_show.html.haml
index a49c17e9265..98752345074 100644
--- a/app/views/shared/boards/_show.html.haml
+++ b/app/views/shared/boards/_show.html.haml
@@ -1,5 +1,4 @@
- board = local_assigns.fetch(:board, nil)
-- group = local_assigns.fetch(:group, false)
- @no_breadcrumb_container = true
- @no_container = true
- @content_wrapper_class = "#{@content_wrapper_class} gl-relative"
@@ -18,8 +17,5 @@
- add_page_specific_style 'page_bundles/boards'
= render 'shared/issuable/search_bar', type: :boards, board: board
-#board-app.boards-app.position-relative{ "v-cloak" => "true", data: board_data, ":class" => "{ 'is-compact': detailIssueVisible }" }
- %board-content{ ":lists" => "state.lists", ":disabled" => "disabled" }
- - if !is_epic_board && !Feature.enabled?(:graphql_board_lists, default_enabled: :yaml)
- = render "shared/boards/components/sidebar", group: group
- %board-settings-sidebar
+
+#js-issuable-board-app{ data: board_data }
diff --git a/app/views/shared/boards/components/_sidebar.html.haml b/app/views/shared/boards/components/_sidebar.html.haml
deleted file mode 100644
index 8976e89b3d3..00000000000
--- a/app/views/shared/boards/components/_sidebar.html.haml
+++ /dev/null
@@ -1,27 +0,0 @@
-%board-sidebar{ "inline-template" => true, ":current-user" => (UserSerializer.new.represent(current_user) || {}).to_json }
- %transition{ name: "boards-sidebar-slide" }
- %aside.right-sidebar.right-sidebar-expanded.boards-sidebar{ "v-show" => "showSidebar", 'aria-label': s_('Boards|Board'), 'data-testid': 'issue-boards-sidebar' }
- .issuable-sidebar
- .block.issuable-sidebar-header.position-relative
- %span.issuable-header-text.hide-collapsed.float-left
- %strong.bold
- {{ issue.title }}
- %br/
- %span
- = render_if_exists "shared/boards/components/sidebar/issue_project_path"
- = precede "#" do
- {{ issue.iid }}
- %a.gutter-toggle.position-absolute.position-top-0.position-right-0{ role: "button",
- href: "#",
- "@click.prevent" => "closeSidebar",
- "aria-label" => "Toggle sidebar" }
- = custom_icon("icon_close", size: 15)
- .js-issuable-update
- = render "shared/boards/components/sidebar/assignee"
- = render_if_exists "shared/boards/components/sidebar/epic"
- = render "shared/boards/components/sidebar/milestone"
- = render "shared/boards/components/sidebar/time_tracker"
- = render "shared/boards/components/sidebar/due_date"
- = render "shared/boards/components/sidebar/labels"
- = render_if_exists "shared/boards/components/sidebar/weight"
- = render "shared/boards/components/sidebar/notifications"
diff --git a/app/views/shared/boards/components/sidebar/_assignee.html.haml b/app/views/shared/boards/components/sidebar/_assignee.html.haml
deleted file mode 100644
index 79817025565..00000000000
--- a/app/views/shared/boards/components/sidebar/_assignee.html.haml
+++ /dev/null
@@ -1,10 +0,0 @@
-- dropdown_options = assignees_dropdown_options('issue')
-- relative_url = Gitlab.config.gitlab.relative_url_root || '/'
-
-.block.assignee{ ref: "assigneeBlock" }
- %template{ "v-if" => "issue.assignees" }
- %sidebar-assignees-widget{ ":iid" => "String(issue.iid)",
- ":full-path" => "issue.path.split('/-/')[0].substring(1).replace(`#{relative_url}`, '')",
- ":initial-assignees" => "issue.assignees",
- ":allow-multiple-assignees" => "!Boolean(#{dropdown_options[:data][:"max-select"]})",
- "@assignees-updated" => "setAssignees" }
diff --git a/app/views/shared/boards/components/sidebar/_due_date.html.haml b/app/views/shared/boards/components/sidebar/_due_date.html.haml
deleted file mode 100644
index ab4d22ac03d..00000000000
--- a/app/views/shared/boards/components/sidebar/_due_date.html.haml
+++ /dev/null
@@ -1,31 +0,0 @@
-.block.due_date
- .title.gl-h-5.gl-display-flex.gl-align-items-center
- = _("Due date")
- - if can_admin_issue?
- = loading_icon(css_class: 'gl-ml-2 block-loading')
- = link_to _("Edit"), "#", class: "js-sidebar-dropdown-toggle edit-link gl-ml-auto"
- .value
- .value-content
- %span.no-value{ "v-if" => "!issue.dueDate" }
- = _("None")
- %span.bold{ "v-if" => "issue.dueDate" }
- {{ issue.dueDate | due-date }}
- - if can_admin_issue?
- %span.no-value.js-remove-due-date-holder{ "v-if" => "issue.dueDate" }
- \-
- %a.js-remove-due-date{ href: "#", role: "button" }
- = _('remove due date')
- - if can_admin_issue?
- .selectbox
- %input{ type: "hidden",
- name: "issue[due_date]",
- ":value" => "issue.dueDate" }
- .dropdown
- %button.dropdown-menu-toggle.js-due-date-select.js-issue-boards-due-date{ type: 'button',
- data: { toggle: 'dropdown', field_name: "issue[due_date]", ability_name: "issue" } }
- %span.dropdown-toggle-text= _("Due date")
- = sprite_icon('chevron-down', css_class: "dropdown-menu-toggle-icon gl-top-3")
- .dropdown-menu.dropdown-menu-due-date
- = dropdown_title(_('Due date'))
- = dropdown_content do
- .js-due-date-calendar
diff --git a/app/views/shared/boards/components/sidebar/_labels.html.haml b/app/views/shared/boards/components/sidebar/_labels.html.haml
deleted file mode 100644
index 5af52d4de23..00000000000
--- a/app/views/shared/boards/components/sidebar/_labels.html.haml
+++ /dev/null
@@ -1,34 +0,0 @@
-.block.labels
- .title.gl-h-5.gl-display-flex.gl-align-items-center
- = _("Labels")
- - if can_admin_issue?
- = loading_icon(css_class: 'gl-ml-2 block-loading')
- = link_to _("Edit"), "#", class: "js-sidebar-dropdown-toggle edit-link gl-ml-auto"
- .value.issuable-show-labels.dont-hide
- %span.no-value{ "v-if" => "issue.labels && issue.labels.length === 0" }
- = _("None")
- %span{ "v-for" => "label in issue.labels" }
- %gl-label{ ":key" => "label.id",
- ":background-color" => "label.color",
- ":title" => "label.title",
- ":description" => "label.description",
- ":scoped" => "showScopedLabels(label)" }
-
- - if can_admin_issue?
- .selectbox
- %input{ type: "hidden",
- name: "issue[label_names][]",
- "v-for" => "label in issue.labels",
- ":value" => "label.id" }
- .dropdown
- %button.dropdown-menu-toggle.js-label-select.js-multiselect.js-issue-board-sidebar{ type: "button",
- ":data-selected" => "selectedLabels",
- ":data-labels" => "issue.assignableLabelsEndpoint",
- data: label_dropdown_data(@project, namespace_path: @namespace_path, field_name: "issue[label_names][]") }
- %span.dropdown-toggle-text
- {{ labelDropdownTitle }}
- = sprite_icon('chevron-down', css_class: "dropdown-menu-toggle-icon gl-top-3")
- .dropdown-menu.dropdown-select.dropdown-menu-paging.dropdown-menu-labels.dropdown-menu-selectable.dropdown-extended-height
- = render partial: "shared/issuable/label_page_default"
- - if can?(current_user, :admin_label, current_board_parent)
- = render partial: "shared/issuable/label_page_create", locals: { show_add_list: true }
diff --git a/app/views/shared/boards/components/sidebar/_milestone.html.haml b/app/views/shared/boards/components/sidebar/_milestone.html.haml
deleted file mode 100644
index 6143f1d5afe..00000000000
--- a/app/views/shared/boards/components/sidebar/_milestone.html.haml
+++ /dev/null
@@ -1,29 +0,0 @@
-.block.milestone
- .title.gl-h-5.gl-display-flex.gl-align-items-center
- = _("Milestone")
- - if can_admin_issue?
- = loading_icon(css_class: 'gl-ml-2 block-loading')
- = link_to _("Edit"), "#", class: "js-sidebar-dropdown-toggle edit-link gl-ml-auto"
- .value
- %span.no-value{ "v-if" => "!issue.milestone" }
- = _("None")
- %span.bold.has-tooltip{ "v-if" => "issue.milestone" }
- {{ issue.milestone.title }}
- - if can_admin_issue?
- .selectbox
- %input{ type: "hidden",
- ":value" => "issue.milestone.id",
- name: "issue[milestone_id]",
- "v-if" => "issue.milestone" }
- .dropdown
- %button.dropdown-menu-toggle.js-milestone-select.js-issue-board-sidebar{ type: "button", data: { toggle: "dropdown", show_no: "true", field_name: "issue[milestone_id]", ability_name: "issue", use_id: "true", default_no: "true" },
- ":data-selected" => "milestoneTitle",
- ":data-issuable-id" => "issue.iid",
- ":data-project-id" => "issue.project_id" }
- = _("Milestone")
- = sprite_icon('chevron-down', css_class: "dropdown-menu-toggle-icon gl-top-3")
- .dropdown-menu.dropdown-select.dropdown-menu-selectable
- = dropdown_title(_("Assign milestone"))
- = dropdown_filter(_("Search milestones"))
- = dropdown_content
- = dropdown_loading
diff --git a/app/views/shared/boards/components/sidebar/_notifications.html.haml b/app/views/shared/boards/components/sidebar/_notifications.html.haml
deleted file mode 100644
index 333dd1a00b4..00000000000
--- a/app/views/shared/boards/components/sidebar/_notifications.html.haml
+++ /dev/null
@@ -1,5 +0,0 @@
-- if current_user
- .block.subscriptions
- %subscriptions{ ":loading" => "issue.isFetching && issue.isFetching.subscriptions",
- ":subscribed" => "issue.subscribed",
- ":id" => "issue.id" }
diff --git a/app/views/shared/boards/components/sidebar/_time_tracker.html.haml b/app/views/shared/boards/components/sidebar/_time_tracker.html.haml
deleted file mode 100644
index eea3ec35000..00000000000
--- a/app/views/shared/boards/components/sidebar/_time_tracker.html.haml
+++ /dev/null
@@ -1,6 +0,0 @@
-.block.time-tracking
- %time-tracker{ ":limit-to-hours" => "timeTrackingLimitToHours",
- ":issuable-id" => "issue.id ? issue.id.toString() : ''",
- ":issuable-iid" => "issue.iid ? issue.iid.toString() : ''",
- ":full-path" => "issue.project ? issue.project.fullPath : ''",
- "root-path" => "#{root_url}" }
diff --git a/app/views/shared/deploy_tokens/_form.html.haml b/app/views/shared/deploy_tokens/_form.html.haml
index e7bbb351633..652da4b396a 100644
--- a/app/views/shared/deploy_tokens/_form.html.haml
+++ b/app/views/shared/deploy_tokens/_form.html.haml
@@ -48,7 +48,7 @@
.text-secondary= s_('DeployTokens|Allows read-only access to the package registry.')
%fieldset.form-group.form-check
- = f.check_box :write_package_registry, class: 'form-check-input'
+ = f.check_box :write_package_registry, class: 'form-check-input', data: { qa_selector: 'deploy_token_write_package_registry_checkbox' }
= f.label :write_package_registry, 'write_package_registry', class: 'label-bold form-check-label'
.text-secondary= s_('DeployTokens|Allows read and write access to the package registry.')
diff --git a/app/views/shared/deploy_tokens/_table.html.haml b/app/views/shared/deploy_tokens/_table.html.haml
index fe32fcf94d0..db9c646b694 100644
--- a/app/views/shared/deploy_tokens/_table.html.haml
+++ b/app/views/shared/deploy_tokens/_table.html.haml
@@ -20,7 +20,7 @@
%td
- if token.expires?
%span{ class: ('text-warning' if token.expires_soon?) }
- In #{distance_of_time_in_words_to_now(token.expires_at)}
+ = time_ago_with_tooltip(token.expires_at)
- else
%span.token-never-expires-label= _('Never')
%td= token.scopes.present? ? token.scopes.join(', ') : _('no scopes selected')
diff --git a/app/views/shared/doorkeeper/applications/_form.html.haml b/app/views/shared/doorkeeper/applications/_form.html.haml
index 91a32b55542..180c658dbdc 100644
--- a/app/views/shared/doorkeeper/applications/_form.html.haml
+++ b/app/views/shared/doorkeeper/applications/_form.html.haml
@@ -18,6 +18,12 @@
%span.form-text.text-muted
= _('The application will be used where the client secret can be kept confidential. Native mobile apps and Single Page Apps are considered non-confidential.')
+ .form-group.form-check
+ = f.check_box :expire_access_tokens, class: 'form-check-input'
+ = f.label :expire_access_tokens, class: 'label-bold form-check-label'
+ %span.form-text.text-muted
+ = _('Access tokens expire after 2 hours. A refresh token may be used at any time to generate a new access token. Non-expiring access tokens are deprecated. Clear this setting to enable backward compatibility.')
+
.form-group
= f.label :scopes, class: 'label-bold'
= render 'shared/tokens/scopes_form', prefix: 'doorkeeper_application', token: @application, scopes: @scopes
diff --git a/app/views/shared/empty_states/_merge_requests.html.haml b/app/views/shared/empty_states/_merge_requests.html.haml
index 879447f16ae..72db4d4c846 100644
--- a/app/views/shared/empty_states/_merge_requests.html.haml
+++ b/app/views/shared/empty_states/_merge_requests.html.haml
@@ -20,7 +20,7 @@
= _("To widen your search, change or remove filters above")
.text-center
- if can_create_merge_request
- = link_to _("New merge request"), project_new_merge_request_path(@project), class: "gl-button btn btn-confirm", title: _("New merge request")
+ = link_to _("New merge request"), button_path || project_new_merge_request_path(@project), class: "gl-button btn btn-confirm", title: _("New merge request")
- elsif is_opened_state && opened_merged_count == 0 && closed_merged_count > 0
%h4.text-center
= _("There are no open merge requests")
@@ -28,7 +28,7 @@
= _("To keep this project going, create a new merge request")
.text-center
- if can_create_merge_request
- = link_to _("New merge request"), project_new_merge_request_path(@project), class: "gl-button btn btn-confirm", title: _("New merge request")
+ = link_to _("New merge request"), button_path || project_new_merge_request_path(@project), class: "gl-button btn btn-confirm", title: _("New merge request")
- elsif is_closed_state && opened_merged_count > 0 && closed_merged_count == 0
%h4.text-center
= _("There are no closed merge requests")
diff --git a/app/views/shared/issuable/_board_create_list_dropdown.html.haml b/app/views/shared/issuable/_board_create_list_dropdown.html.haml
deleted file mode 100644
index 74b064648c0..00000000000
--- a/app/views/shared/issuable/_board_create_list_dropdown.html.haml
+++ /dev/null
@@ -1,8 +0,0 @@
-.dropdown.gl-display-flex.gl-align-items-center.gl-ml-3#js-add-list
- %button.gl-button.btn.btn-confirm.js-new-board-list{ type: "button", data: board_list_data }
- Add list
- .dropdown-menu.dropdown-extended-height.dropdown-menu-paging.dropdown-menu-right.dropdown-menu-issues-board-new.dropdown-menu-selectable.js-tab-container-labels
- = render partial: "shared/issuable/label_page_default", locals: { show_footer: true, show_create: true, show_boards_content: true, title: "Add list" }
- - if can?(current_user, :admin_label, board.resource_parent)
- = render partial: "shared/issuable/label_page_create", locals: { show_add_list: true, add_list: true, add_list_class: 'd-none' }
- = dropdown_loading
diff --git a/app/views/shared/issuable/_feed_buttons.html.haml b/app/views/shared/issuable/_feed_buttons.html.haml
index c3e4c3a15cc..f0e4b915ac8 100644
--- a/app/views/shared/issuable/_feed_buttons.html.haml
+++ b/app/views/shared/issuable/_feed_buttons.html.haml
@@ -1,4 +1,8 @@
-= link_to safe_params.merge(rss_url_options), class: 'btn gl-button btn-default btn-icon has-tooltip', data: { container: 'body', testid: 'rss-feed-link' }, title: _('Subscribe to RSS feed') do
+- show_calendar_button = local_assigns.fetch(:show_calendar_button, true)
+
+= link_to safe_params.merge(rss_url_options), class: 'btn gl-button btn-default btn-icon has-tooltip', data: { container: 'body', testid: 'rss-feed-link' }, title: _('Subscribe to RSS feed') , 'aria-label': _('Subscribe to RSS feed') do
= sprite_icon('rss', css_class: 'qa-rss-icon')
-= link_to safe_params.merge(calendar_url_options), class: 'btn gl-button btn-default btn-icon has-tooltip', data: { container: 'body' }, title: _('Subscribe to calendar') do
- = sprite_icon('calendar')
+
+- if show_calendar_button
+ = link_to safe_params.merge(calendar_url_options), class: 'btn gl-button btn-default btn-icon has-tooltip', data: { container: 'body' }, title: _('Subscribe to calendar'), 'aria-label': _('Subscribe to calendar') do
+ = sprite_icon('calendar')
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index dc93442d6cd..cb03bd4c473 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -66,7 +66,7 @@
- if issuable.new_record?
= form.submit "Create #{issuable.class.model_name.human.downcase}", class: 'gl-button btn btn-confirm gl-mr-2', data: { qa_selector: 'issuable_create_button' }
- else
- = form.submit 'Save changes', class: 'gl-button btn btn-confirm gl-mr-2'
+ = form.submit _('Save changes'), class: 'gl-button btn btn-confirm gl-mr-2'
- if issuable.new_record?
= link_to _('Cancel'), polymorphic_path([@project, issuable.class]), class: 'btn gl-button btn-default'
diff --git a/app/views/shared/issuable/_issuable.atom.builder b/app/views/shared/issuable/_issuable.atom.builder
new file mode 100644
index 00000000000..931fb74dc00
--- /dev/null
+++ b/app/views/shared/issuable/_issuable.atom.builder
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+builder.title truncate(issuable.title, length: 80)
+builder.updated issuable.updated_at.xmlschema
+builder.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon_for_user(issuable.author))
+
+builder.author do
+ builder.name issuable.author_name
+ builder.email issuable.author_public_email
+end
+
+builder.summary issuable.title
+builder.description truncate(issuable.description, length: 240) if issuable.description
+builder.content issuable.description if issuable.description
+builder.milestone issuable.milestone.title if issuable.milestone
+
+unless issuable.labels.empty?
+ builder.labels do
+ issuable.labels.each do |label|
+ builder.label label.name
+ end
+ end
+end
+
+if issuable.assignees.any?
+ builder.assignees do
+ issuable.assignees.each do |assignee|
+ builder.assignee do
+ builder.name assignee.name
+ builder.email assignee.public_email
+ end
+ end
+ end
+
+ builder.assignee do
+ builder.name issuable.assignees.first.name
+ builder.email issuable.assignees.first.public_email
+ end
+end
diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml
index 737a0ff8c5b..e6c4b3f4814 100644
--- a/app/views/shared/issuable/_search_bar.html.haml
+++ b/app/views/shared/issuable/_search_bar.html.haml
@@ -207,10 +207,7 @@
#js-board-epics-swimlanes-toggle
.js-board-config{ data: { can_admin_list: user_can_admin_list.to_s, has_scope: board.scoped?.to_s } }
- if user_can_admin_list
- - if Feature.enabled?(:board_new_list, board.resource_parent, default_enabled: :yaml) || board.to_type == "EpicBoard"
- .js-create-column-trigger{ data: board_list_data }
- - else
- = render 'shared/issuable/board_create_list_dropdown', board: board
+ .js-create-column-trigger{ data: board_list_data }
#js-toggle-focus-btn
- elsif type != :productivity_analytics && show_sorting_dropdown
= render 'shared/issuable/sort_dropdown'
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index c76aa176696..1e8724c3448 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -88,7 +88,7 @@
= custom_icon('icon_arrow_right')
.dropdown.sidebar-move-issue-dropdown.hide-collapsed
%button.gl-button.btn.btn-default.btn-block.js-sidebar-dropdown-toggle.js-move-issue{ type: 'button',
- data: { toggle: 'dropdown', display: 'static', track_label: "right_sidebar", track_property: "move_issue", track_event: "click_button", track_value: "" } }
+ data: { toggle: 'dropdown', display: 'static', track_label: "right_sidebar", track_property: "move_issue", track_action: "click_button", track_value: "" } }
= _('Move issue')
.dropdown-menu.dropdown-menu-selectable.dropdown-extended-height
= dropdown_title(_('Move issue'))
diff --git a/app/views/shared/issuable/_sidebar_user_dropdown.html.haml b/app/views/shared/issuable/_sidebar_user_dropdown.html.haml
index 84d2fc033c8..c058e7ebe3e 100644
--- a/app/views/shared/issuable/_sidebar_user_dropdown.html.haml
+++ b/app/views/shared/issuable/_sidebar_user_dropdown.html.haml
@@ -6,7 +6,7 @@
- options[:footer_content] = true
- options[:wrapper_class] = local_assigns.fetch(:wrapper_class)
- options[:toggle_class] += ' js-invite-members-track'
- - data['track-event'] = 'show_invite_members'
+ - data['track-action'] = 'show_invite_members'
- data['track-label'] = local_assigns.fetch(:track_label)
= dropdown_tag(data['dropdown-title'], options: options) do
diff --git a/app/views/shared/issuable/_sort_dropdown.html.haml b/app/views/shared/issuable/_sort_dropdown.html.haml
index f5bf010e4db..5742f22ce05 100644
--- a/app/views/shared/issuable/_sort_dropdown.html.haml
+++ b/app/views/shared/issuable/_sort_dropdown.html.haml
@@ -21,5 +21,6 @@
= sortable_item(sort_title_merged_date, page_filter_path(sort: sort_value_merged_date), sort_title) if viewing_merge_requests
= sortable_item(sort_title_closed_date, page_filter_path(sort: sort_value_closed_date), sort_title) if viewing_merge_requests
= sortable_item(sort_title_relative_position, page_filter_path(sort: sort_value_relative_position), sort_title) if viewing_issues
+ = sortable_item(sort_title_title, page_filter_path(sort: sort_value_title), sort_title) if viewing_issues
= render_if_exists('shared/ee/issuable/sort_dropdown', viewing_issues: viewing_issues, sort_title: sort_title)
= issuable_sort_direction_button(sort_value)
diff --git a/app/views/shared/issuable/form/_metadata.html.haml b/app/views/shared/issuable/form/_metadata.html.haml
index 1043eb49752..2f05d272ca3 100644
--- a/app/views/shared/issuable/form/_metadata.html.haml
+++ b/app/views/shared/issuable/form/_metadata.html.haml
@@ -1,13 +1,10 @@
- project = local_assigns.fetch(:project)
- issuable = local_assigns.fetch(:issuable)
- presenter = local_assigns.fetch(:presenter)
-
-- return unless can?(current_user, :"set_#{issuable.to_ability_name}_metadata", issuable)
-
- has_due_date = issuable.has_attribute?(:due_date)
- form = local_assigns.fetch(:form)
-- if issuable.respond_to?(:confidential)
+- if issuable.respond_to?(:confidential) && can?(current_user, :set_confidentiality, issuable)
.form-group.row
.offset-sm-2.col-sm-10
.form-check
@@ -15,39 +12,40 @@
= form.label :confidential, class: 'form-check-label' do
This issue is confidential and should only be visible to team members with at least Reporter access.
-%hr
-.row
- %div{ class: (has_due_date ? "col-lg-6" : "col-12") }
- .form-group.row.merge-request-assignee
- = render "shared/issuable/form/metadata_issuable_assignee", issuable: issuable, form: form, has_due_date: has_due_date
-
- - if issuable.allows_reviewers?
- .form-group.row.merge-request-reviewer
- = render "shared/issuable/form/metadata_issuable_reviewer", issuable: issuable, form: form, has_due_date: has_due_date, presenter: presenter
+- if can?(current_user, :"set_#{issuable.to_ability_name}_metadata", issuable)
+ %hr
+ .row
+ %div{ class: (has_due_date ? "col-lg-6" : "col-12") }
+ .form-group.row.merge-request-assignee
+ = render "shared/issuable/form/metadata_issuable_assignee", issuable: issuable, form: form, has_due_date: has_due_date
- = render_if_exists "shared/issuable/form/epic", issuable: issuable, form: form, project: project
-
- - if issuable.supports_milestone?
- .form-group.row.issue-milestone
- = form.label :milestone_id, "Milestone", class: "col-form-label #{has_due_date ? "col-md-2 col-lg-4" : "col-sm-2"}"
- .col-sm-10{ class: ("col-md-8" if has_due_date) }
- .issuable-form-select-holder
- = render "shared/issuable/milestone_dropdown", selected: issuable.milestone, name: "#{issuable.class.model_name.param_key}[milestone_id]", show_any: false, show_upcoming: false, show_started: false, extra_class: "qa-issuable-milestone-dropdown js-issuable-form-dropdown js-dropdown-keep-input", dropdown_title: "Select milestone"
+ - if issuable.allows_reviewers?
+ .form-group.row.merge-request-reviewer
+ = render "shared/issuable/form/metadata_issuable_reviewer", issuable: issuable, form: form, has_due_date: has_due_date, presenter: presenter
- .form-group.row
- = form.label :label_ids, "Labels", class: "col-form-label #{has_due_date ? "col-md-2 col-lg-4" : "col-sm-2"}"
- = form.hidden_field :label_ids, multiple: true, value: ''
- .col-sm-10{ class: "#{"col-md-8" if has_due_date}" }
- .issuable-form-select-holder
- = render "shared/issuable/label_dropdown", classes: ["js-issuable-form-dropdown"], selected: issuable.labels, data_options: { field_name: "#{issuable.class.model_name.param_key}[label_ids][]", show_any: false }, dropdown_title: "Select label"
+ = render_if_exists "shared/issuable/form/epic", issuable: issuable, form: form, project: project
- = render_if_exists "shared/issuable/form/merge_request_blocks", issuable: issuable, form: form
+ - if issuable.supports_milestone?
+ .form-group.row.issue-milestone
+ = form.label :milestone_id, "Milestone", class: "col-form-label #{has_due_date ? "col-md-2 col-lg-4" : "col-sm-2"}"
+ .col-sm-10{ class: ("col-md-8" if has_due_date) }
+ .issuable-form-select-holder
+ = render "shared/issuable/milestone_dropdown", selected: issuable.milestone, name: "#{issuable.class.model_name.param_key}[milestone_id]", show_any: false, show_upcoming: false, show_started: false, extra_class: "qa-issuable-milestone-dropdown js-issuable-form-dropdown js-dropdown-keep-input", dropdown_title: "Select milestone"
- - if has_due_date
- .col-lg-6
- = render_if_exists "shared/issuable/form/weight", issuable: issuable, form: form
.form-group.row
- = form.label :due_date, "Due date", class: "col-form-label col-md-2 col-lg-4"
- .col-8
+ = form.label :label_ids, "Labels", class: "col-form-label #{has_due_date ? "col-md-2 col-lg-4" : "col-sm-2"}"
+ = form.hidden_field :label_ids, multiple: true, value: ''
+ .col-sm-10{ class: "#{"col-md-8" if has_due_date}" }
.issuable-form-select-holder
- = form.text_field :due_date, id: "issuable-due-date", class: "datepicker form-control", placeholder: "Select due date", autocomplete: 'off'
+ = render "shared/issuable/label_dropdown", classes: ["js-issuable-form-dropdown"], selected: issuable.labels, data_options: { field_name: "#{issuable.class.model_name.param_key}[label_ids][]", show_any: false }, dropdown_title: "Select label"
+
+ = render_if_exists "shared/issuable/form/merge_request_blocks", issuable: issuable, form: form
+
+ - if has_due_date
+ .col-lg-6
+ = render_if_exists "shared/issuable/form/weight", issuable: issuable, form: form
+ .form-group.row
+ = form.label :due_date, "Due date", class: "col-form-label col-md-2 col-lg-4"
+ .col-8
+ .issuable-form-select-holder
+ = form.text_field :due_date, id: "issuable-due-date", class: "datepicker form-control", placeholder: "Select due date", autocomplete: 'off'
diff --git a/app/views/shared/issuable/form/_type_selector.html.haml b/app/views/shared/issuable/form/_type_selector.html.haml
index 3b4ab22ce32..f5f6f32d5ba 100644
--- a/app/views/shared/issuable/form/_type_selector.html.haml
+++ b/app/views/shared/issuable/form/_type_selector.html.haml
@@ -21,7 +21,7 @@
%li.js-filter-issuable-type
= link_to new_project_issue_path(@project), class: ("is-active" if issuable.issue?) do
#{sprite_icon(work_item_type_icon(:issue), css_class: 'gl-icon')} #{_("Issue")}
- %li.js-filter-issuable-type{ data: { track: { event: "select_issue_type_incident", label: "select_issue_type_incident_dropdown_option" } } }
+ %li.js-filter-issuable-type{ data: { track: { action: "select_issue_type_incident", label: "select_issue_type_incident_dropdown_option" } } }
= link_to new_project_issue_path(@project, { issuable_template: 'incident', issue: { issue_type: 'incident' } }), class: ("is-active" if issuable.incident?) do
#{sprite_icon(work_item_type_icon(:incident), css_class: 'gl-icon')} #{_("Incident")}
diff --git a/app/views/shared/issue_type/_details_header.html.haml b/app/views/shared/issue_type/_details_header.html.haml
index a25e35cdcd4..eca61819cca 100644
--- a/app/views/shared/issue_type/_details_header.html.haml
+++ b/app/views/shared/issue_type/_details_header.html.haml
@@ -15,7 +15,7 @@
= _('Open')
.issuable-meta
- #js-issuable-header-warnings
+ #js-issuable-header-warnings{ data: { hidden: issue_hidden?(issuable).to_s } }
= issuable_meta(issuable, @project)
%a.btn.gl-button.btn-default.btn-icon.float-right.gl-display-block.d-sm-none.gutter-toggle.issuable-gutter-toggle.js-sidebar-toggle{ href: "#" }
diff --git a/app/views/shared/labels/_form.html.haml b/app/views/shared/labels/_form.html.haml
index 604aac9237c..6f65dbe4811 100644
--- a/app/views/shared/labels/_form.html.haml
+++ b/app/views/shared/labels/_form.html.haml
@@ -28,7 +28,7 @@
= render_suggested_colors
.form-actions
- if @label.persisted?
- = f.submit 'Save changes', class: 'btn gl-button btn-confirm js-save-button'
+ = f.submit _('Save changes'), class: 'btn gl-button btn-confirm js-save-button'
- else
= f.submit 'Create label', class: 'btn gl-button btn-confirm js-save-button qa-label-create-button'
- = link_to 'Cancel', back_path, class: 'btn gl-button btn-default btn-cancel'
+ = link_to _('Cancel'), back_path, class: 'btn gl-button btn-default btn-cancel'
diff --git a/app/views/shared/members/_access_request_links.html.haml b/app/views/shared/members/_access_request_links.html.haml
index a983a736a1e..8600db25e65 100644
--- a/app/views/shared/members/_access_request_links.html.haml
+++ b/app/views/shared/members/_access_request_links.html.haml
@@ -5,13 +5,11 @@
= link_to link_text, polymorphic_path([:leave, source, :members]),
method: :delete,
data: { confirm: leave_confirmation_message(source), qa_selector: 'leave_group_link' },
- class: '.gl-pl-3.gl-border-l-1.gl-border-l-solid.gl-border-l-gray-500 js-leave-link'
+ class: 'js-leave-link'
- elsif requester = source.requesters.find_by(user_id: current_user.id) # rubocop: disable CodeReuse/ActiveRecord
= link_to _('Withdraw Access Request'), polymorphic_path([:leave, source, :members]),
method: :delete,
- data: { confirm: remove_member_message(requester) },
- class: '.gl-pl-3.gl-border-l-1.gl-border-l-solid.gl-border-l-gray-500'
+ data: { confirm: remove_member_message(requester) }
- elsif source.request_access_enabled && can?(current_user, :request_access, source)
= link_to _('Request Access'), polymorphic_path([:request_access, source, :members]),
- method: :post,
- class: '.gl-pl-3.gl-border-l-1.gl-border-l-solid.gl-border-l-gray-500'
+ method: :post
diff --git a/app/views/shared/runners/_runner_details.html.haml b/app/views/shared/runners/_runner_details.html.haml
index 672f0b6a83f..a7b2947057d 100644
--- a/app/views/shared/runners/_runner_details.html.haml
+++ b/app/views/shared/runners/_runner_details.html.haml
@@ -60,4 +60,4 @@
- if runner.contacted_at
= time_ago_with_tooltip runner.contacted_at
- else
- = s_('Never')
+ = _('Never')
diff --git a/app/views/shared/wikis/pages.html.haml b/app/views/shared/wikis/pages.html.haml
index c1918198594..0a8ca309823 100644
--- a/app/views/shared/wikis/pages.html.haml
+++ b/app/views/shared/wikis/pages.html.haml
@@ -1,4 +1,4 @@
-- add_to_breadcrumbs "Wiki", wiki_path(@wiki)
+- add_to_breadcrumbs _('Wiki'), wiki_path(@wiki)
- breadcrumb_title s_("Wiki|Pages")
- page_title s_("Wiki|Pages"), _("Wiki")
- sort_title = wiki_sort_title(params[:sort])
diff --git a/app/views/sherlock/queries/_backtrace.html.haml b/app/views/sherlock/queries/_backtrace.html.haml
index ff5a6b73e47..425113ba325 100644
--- a/app/views/sherlock/queries/_backtrace.html.haml
+++ b/app/views/sherlock/queries/_backtrace.html.haml
@@ -8,7 +8,7 @@
%li
%strong
- if defined?(BetterErrors)
- = link_to(location.path, BetterErrors.editor[location.path, location.line])
+ = link_to(location.path, BetterErrors.editor.url(location.path, location.line))
- else
= location.path
%small.light
diff --git a/app/views/sherlock/queries/_general.html.haml b/app/views/sherlock/queries/_general.html.haml
index cd810ae10ad..a16314213c4 100644
--- a/app/views/sherlock/queries/_general.html.haml
+++ b/app/views/sherlock/queries/_general.html.haml
@@ -16,7 +16,7 @@
#{t('sherlock.origin')}:
%strong
- if defined?(BetterErrors)
- = link_to(frame.path, BetterErrors.editor[frame.path, frame.line])
+ = link_to(frame.path, BetterErrors.editor.url(frame.path, frame.line))
- else
= frame.path
%small.light
diff --git a/app/views/users/_middle_dot_divider.html.haml b/app/views/users/_middle_dot_divider.html.haml
new file mode 100644
index 00000000000..540a200921f
--- /dev/null
+++ b/app/views/users/_middle_dot_divider.html.haml
@@ -0,0 +1,5 @@
+- stacking = local_assigns.delete(:stacking)
+- breakpoint = local_assigns.delete(:breakpoint)
+
+%div{ class: middle_dot_divider_classes(stacking, breakpoint), **local_assigns }
+ = yield
diff --git a/app/views/users/_profile_basic_info.html.haml b/app/views/users/_profile_basic_info.html.haml
index c431a72d0e7..3b0186e84e1 100644
--- a/app/views/users/_profile_basic_info.html.haml
+++ b/app/views/users/_profile_basic_info.html.haml
@@ -1,6 +1,6 @@
-%p.mb-1.mb-sm-2.mt-2.mt-sm-3
- %span.middle-dot-divider
+.gl-text-gray-900.gl-mt-4
+ = render 'middle_dot_divider' do
@#{@user.username}
- if can?(current_user, :read_user_profile, @user)
- %span.middle-dot-divider
+ = render 'middle_dot_divider' do
= s_('Member since %{date}') % { date: @user.created_at.to_date.to_s(:long) }
diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml
index 363909c54e2..20cbe08225e 100644
--- a/app/views/users/show.html.haml
+++ b/app/views/users/show.html.haml
@@ -2,7 +2,7 @@
- @hide_breadcrumbs = true
- @no_container = true
- page_title user_display_name(@user)
-- page_description @user.bio_html
+- page_description @user.bio
- header_title @user.name, user_path(@user)
- page_itemtype 'http://schema.org/Person'
- link_classes = "flex-grow-1 mx-1 "
@@ -26,6 +26,13 @@
= link_to new_abuse_report_path(user_id: @user.id, ref_url: request.referer), class: link_classes + 'btn gl-button btn-default btn-icon',
title: s_('UserProfile|Report abuse'), data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
= sprite_icon('error')
+ - verified_gpg_keys = @user.gpg_keys.select(&:verified?)
+ - if verified_gpg_keys.any?
+ = link_to user_gpg_keys_path,
+ class: link_classes + 'btn btn-default btn-md gl-button btn-icon has-tooltip',
+ title: n_('View public GPG key', 'View public GPG keys', verified_gpg_keys.length),
+ data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
+ = sprite_icon('key', css_class: 'gl-button-icon gl-icon')
- if can?(current_user, :read_user_profile, @user)
= link_to user_path(@user, rss_url_options), class: link_classes + 'btn gl-button btn-default btn-icon has-tooltip',
title: s_('UserProfile|Subscribe'), data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
@@ -71,56 +78,56 @@
= emoji_icon(@user.status.emoji, class: 'gl-mr-2')
= markdown_field(@user.status, :message)
= render "users/profile_basic_info"
- .cover-desc.cgray.mb-1.mb-sm-2
+ .gl-text-gray-900.mb-1.mb-sm-2
- unless @user.location.blank?
- .profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline.mb-1.mb-sm-0{ itemprop: 'address', itemscope: true, itemtype: 'https://schema.org/PostalAddress' }
+ = render 'middle_dot_divider', stacking: true, itemprop: 'address', itemscope: true, itemtype: 'https://schema.org/PostalAddress' do
= sprite_icon('location', css_class: 'fgray')
%span{ itemprop: 'addressLocality' }
= @user.location
- .profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline.mb-1.mb-sm-0
+ = render 'middle_dot_divider', stacking: true do
= sprite_icon('clock', css_class: 'fgray')
%span
= local_time(@user.timezone)
- unless work_information(@user).blank?
- .profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline
+ = render 'middle_dot_divider', stacking: true do
= sprite_icon('work', css_class: 'fgray')
%span
= work_information(@user, with_schema_markup: true)
- .cover-desc.cgray.mb-1.mb-sm-2
+ .gl-text-gray-900
- unless @user.skype.blank?
- .profile-link-holder.middle-dot-divider
- = link_to "skype:#{@user.skype}", title: "Skype" do
+ = render 'middle_dot_divider' do
+ = link_to "skype:#{@user.skype}", class: 'gl-hover-text-decoration-none', title: "Skype" do
= sprite_icon('skype')
- unless @user.linkedin.blank?
- .profile-link-holder.middle-dot-divider
- = link_to linkedin_url(@user), title: "LinkedIn", target: '_blank', rel: 'noopener noreferrer nofollow' do
+ = render 'middle_dot_divider' do
+ = link_to linkedin_url(@user), class: 'gl-hover-text-decoration-none', title: "LinkedIn", target: '_blank', rel: 'noopener noreferrer nofollow' do
= sprite_icon('linkedin')
- unless @user.twitter.blank?
- .profile-link-holder.middle-dot-divider-sm
- = link_to twitter_url(@user), title: "Twitter", target: '_blank', rel: 'noopener noreferrer nofollow' do
+ = render 'middle_dot_divider', breakpoint: 'sm' do
+ = link_to twitter_url(@user), class: 'gl-hover-text-decoration-none', title: "Twitter", target: '_blank', rel: 'noopener noreferrer nofollow' do
= sprite_icon('twitter')
- unless @user.website_url.blank?
- .profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline.mt-1.mt-sm-0
+ = render 'middle_dot_divider', stacking: true do
- if Feature.enabled?(:security_auto_fix) && @user.bot?
= sprite_icon('question', css_class: 'gl-text-blue-600')
- = link_to @user.short_website_url, @user.full_website_url, class: 'text-link', target: '_blank', rel: 'me noopener noreferrer nofollow', itemprop: 'url'
+ = link_to @user.short_website_url, @user.full_website_url, target: '_blank', rel: 'me noopener noreferrer nofollow', itemprop: 'url'
- unless @user.public_email.blank?
- .profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline.mt-1.mt-sm-0
- = link_to @user.public_email, "mailto:#{@user.public_email}", class: 'text-link', itemprop: 'email'
- .cover-desc.gl-text-gray-900.gl-mb-2.mb-sm-2
+ = render 'middle_dot_divider', stacking: true do
+ = link_to @user.public_email, "mailto:#{@user.public_email}", itemprop: 'email'
+ .gl-text-gray-900
= sprite_icon('users', css_class: 'gl-vertical-align-middle gl-text-gray-500')
- .profile-link-holder.middle-dot-divider
- = link_to user_followers_path, class: 'text-link' do
+ = render 'middle_dot_divider' do
+ = link_to user_followers_path do
- count = @user.followers.count
= n_('1 follower', '%{count} followers', count) % { count: count }
- .profile-link-holder.middle-dot-divider
- = link_to user_following_path, class: 'text-link', data: { qa_selector: 'following_link' } do
+ = render 'middle_dot_divider' do
+ = link_to user_following_path, data: { qa_selector: 'following_link' } do
= @user.followees.count
= _('following')
- if @user.bio.present?
- .cover-desc.cgray
+ .gl-text-gray-900
.profile-user-bio
- = markdown(@user.bio_html)
+ = @user.bio
- unless profile_tabs.empty?
diff --git a/app/views/users/terms/index.html.haml b/app/views/users/terms/index.html.haml
index 73d0f51f9ac..771ee693120 100644
--- a/app/views/users/terms/index.html.haml
+++ b/app/views/users/terms/index.html.haml
@@ -1,12 +1,14 @@
- redirect_params = { redirect: @redirect } if @redirect
+- accept_term_link = accept_term_path(@term, redirect_params)
.card-body.rendered-terms{ data: { qa_selector: 'terms_content' } }
= markdown_field(@term, :terms)
- if current_user
+ = render_if_exists 'devise/shared/form_phone_verification', accept_term_link: accept_term_link, inline: true
.card-footer.footer-block.clearfix
- if can?(current_user, :accept_terms, @term)
.float-right
- = button_to accept_term_path(@term, redirect_params), class: 'gl-button btn btn-confirm gl-ml-3', data: { qa_selector: 'accept_terms_button' } do
+ = button_to accept_term_link, class: 'gl-button btn btn-confirm gl-ml-3', data: { qa_selector: 'accept_terms_button' } do
= _('Accept terms')
- else
.float-right
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index f326ae0dec8..955674b52a4 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -83,8 +83,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
- :tags:
- - :exclude_from_gitlab_com
+ :tags: []
- :name: chaos:chaos_db_spin
:worker_name: Chaos::DbSpinWorker
:feature_category: :not_owned
@@ -93,8 +92,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
- :tags:
- - :exclude_from_gitlab_com
+ :tags: []
- :name: chaos:chaos_kill
:worker_name: Chaos::KillWorker
:feature_category: :not_owned
@@ -103,8 +101,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
- :tags:
- - :exclude_from_gitlab_com
+ :tags: []
- :name: chaos:chaos_leak_mem
:worker_name: Chaos::LeakMemWorker
:feature_category: :not_owned
@@ -113,8 +110,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
- :tags:
- - :exclude_from_gitlab_com
+ :tags: []
- :name: chaos:chaos_sleep
:worker_name: Chaos::SleepWorker
:feature_category: :not_owned
@@ -123,8 +119,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
- :tags:
- - :exclude_from_gitlab_com
+ :tags: []
- :name: container_repository:cleanup_container_repository
:worker_name: CleanupContainerRepositoryWorker
:feature_category: :container_registry
@@ -142,8 +137,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: container_repository:delete_container_repository
:worker_name: DeleteContainerRepositoryWorker
:feature_category: :container_registry
@@ -170,8 +164,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: cronjob:authorized_project_update_periodic_recalculate
:worker_name: AuthorizedProjectUpdate::PeriodicRecalculateWorker
:feature_category: :source_code_management
@@ -207,8 +200,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: cronjob:ci_platform_metrics_update_cron
:worker_name: CiPlatformMetricsUpdateCronWorker
:feature_category: :continuous_integration
@@ -226,8 +218,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: cronjob:container_expiration_policy
:worker_name: ContainerExpirationPolicyWorker
:feature_category: :container_registry
@@ -245,8 +236,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: cronjob:database_drop_detached_partitions
:worker_name: Database::DropDetachedPartitionsWorker
:feature_category: :database
@@ -345,8 +335,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: cronjob:metrics_dashboard_schedule_annotations_prune
:worker_name: Metrics::Dashboard::ScheduleAnnotationsPruneWorker
:feature_category: :metrics
@@ -364,8 +353,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: cronjob:namespaces_prune_aggregation_schedules
:worker_name: Namespaces::PruneAggregationSchedulesWorker
:feature_category: :source_code_management
@@ -383,8 +371,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: cronjob:pages_domain_removal_cron
:worker_name: PagesDomainRemovalCronWorker
:feature_category: :pages
@@ -429,8 +416,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: cronjob:personal_access_tokens_expiring
:worker_name: PersonalAccessTokens::ExpiringWorker
:feature_category: :authentication_and_authorization
@@ -466,8 +452,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: cronjob:remove_expired_group_links
:worker_name: RemoveExpiredGroupLinksWorker
:feature_category: :authentication_and_authorization
@@ -494,8 +479,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: cronjob:remove_unreferenced_lfs_objects
:worker_name: RemoveUnreferencedLfsObjectsWorker
:feature_category: :git_lfs
@@ -540,8 +524,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: cronjob:schedule_migrate_external_diffs
:worker_name: ScheduleMigrateExternalDiffsWorker
:feature_category: :code_review
@@ -559,8 +542,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: cronjob:ssh_keys_expiring_soon_notification
:worker_name: SshKeys::ExpiringSoonNotificationWorker
:feature_category: :compliance_management
@@ -569,8 +551,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: cronjob:stuck_ci_jobs
:worker_name: StuckCiJobsWorker
:feature_category: :continuous_integration
@@ -624,8 +605,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: cronjob:users_create_statistics
:worker_name: Users::CreateStatisticsWorker
:feature_category: :users
@@ -643,8 +623,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: cronjob:x509_issuer_crl_check
:worker_name: X509IssuerCrlCheckWorker
:feature_category: :source_code_management
@@ -671,25 +650,6 @@
:resource_boundary: :unknown
:weight: 3
:idempotent:
- :tags:
- - :exclude_from_kubernetes
-- :name: deployment:deployments_finished
- :worker_name: Deployments::FinishedWorker
- :feature_category: :continuous_delivery
- :has_external_dependencies:
- :urgency: :low
- :resource_boundary: :cpu
- :weight: 3
- :idempotent:
- :tags: []
-- :name: deployment:deployments_forward_deployment
- :worker_name: Deployments::ForwardDeploymentWorker
- :feature_category: :continuous_delivery
- :has_external_dependencies:
- :urgency: :low
- :resource_boundary: :unknown
- :weight: 3
- :idempotent:
:tags: []
- :name: deployment:deployments_hooks
:worker_name: Deployments::HooksWorker
@@ -709,15 +669,6 @@
:weight: 3
:idempotent: true
:tags: []
-- :name: deployment:deployments_success
- :worker_name: Deployments::SuccessWorker
- :feature_category: :continuous_delivery
- :has_external_dependencies:
- :urgency: :low
- :resource_boundary: :cpu
- :weight: 3
- :idempotent:
- :tags: []
- :name: deployment:deployments_update_environment
:worker_name: Deployments::UpdateEnvironmentWorker
:feature_category: :continuous_delivery
@@ -924,8 +875,7 @@
:resource_boundary: :cpu
:weight: 1
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: github_importer:github_import_import_pull_request_review
:worker_name: Gitlab::GithubImport::ImportPullRequestReviewWorker
:feature_category: :importers
@@ -934,8 +884,7 @@
:resource_boundary: :cpu
:weight: 1
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: github_importer:github_import_refresh_import_jid
:worker_name: Gitlab::GithubImport::RefreshImportJidWorker
:feature_category: :importers
@@ -1007,8 +956,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: github_importer:github_import_stage_import_pull_requests_reviews
:worker_name: Gitlab::GithubImport::Stage::ImportPullRequestsReviewsWorker
:feature_category: :importers
@@ -1017,8 +965,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: github_importer:github_import_stage_import_repository
:worker_name: Gitlab::GithubImport::Stage::ImportRepositoryWorker
:feature_category: :importers
@@ -1037,7 +984,6 @@
:weight: 1
:idempotent:
:tags:
- - :exclude_from_gitlab_com
- :needs_own_queue
- :name: hashed_storage:hashed_storage_project_migrate
:worker_name: HashedStorage::ProjectMigrateWorker
@@ -1048,7 +994,6 @@
:weight: 1
:idempotent:
:tags:
- - :exclude_from_gitlab_com
- :needs_own_queue
- :name: hashed_storage:hashed_storage_project_rollback
:worker_name: HashedStorage::ProjectRollbackWorker
@@ -1059,7 +1004,6 @@
:weight: 1
:idempotent:
:tags:
- - :exclude_from_gitlab_com
- :needs_own_queue
- :name: hashed_storage:hashed_storage_rollbacker
:worker_name: HashedStorage::RollbackerWorker
@@ -1070,7 +1014,6 @@
:weight: 1
:idempotent:
:tags:
- - :exclude_from_gitlab_com
- :needs_own_queue
- :name: incident_management:clusters_applications_check_prometheus_health
:worker_name: Clusters::Applications::CheckPrometheusHealthWorker
@@ -1089,8 +1032,7 @@
:resource_boundary: :cpu
:weight: 2
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: incident_management:incident_management_pager_duty_process_incident
:worker_name: IncidentManagement::PagerDuty::ProcessIncidentWorker
:feature_category: :incident_management
@@ -1144,8 +1086,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: jira_connect:jira_connect_sync_deployments
:worker_name: JiraConnect::SyncDeploymentsWorker
:feature_category: :integrations
@@ -1154,8 +1095,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: jira_connect:jira_connect_sync_feature_flags
:worker_name: JiraConnect::SyncFeatureFlagsWorker
:feature_category: :integrations
@@ -1164,8 +1104,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: jira_connect:jira_connect_sync_merge_request
:worker_name: JiraConnect::SyncMergeRequestWorker
:feature_category: :integrations
@@ -1183,8 +1122,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: jira_importer:jira_import_advance_stage
:worker_name: Gitlab::JiraImport::AdvanceStageWorker
:feature_category: :importers
@@ -1346,8 +1284,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: package_repositories:packages_go_sync_packages
:worker_name: Packages::Go::SyncPackagesWorker
:feature_category: :package_registry
@@ -1356,8 +1293,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: package_repositories:packages_helm_extraction
:worker_name: Packages::Helm::ExtractionWorker
:feature_category: :package_registry
@@ -1375,8 +1311,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: package_repositories:packages_nuget_extraction
:worker_name: Packages::Nuget::ExtractionWorker
:feature_category: :package_registry
@@ -1394,8 +1329,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: pipeline_background:archive_trace
:worker_name: ArchiveTraceWorker
:feature_category: :continuous_integration
@@ -1449,8 +1383,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: pipeline_background:ci_pipeline_success_unlock_artifacts
:worker_name: Ci::PipelineSuccessUnlockArtifactsWorker
:feature_category: :continuous_integration
@@ -1477,8 +1410,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: pipeline_cache:expire_job_cache
:worker_name: ExpireJobCacheWorker
:feature_category: :continuous_integration
@@ -1486,7 +1418,7 @@
:urgency: :high
:resource_boundary: :unknown
:weight: 3
- :idempotent: true
+ :idempotent:
:tags: []
- :name: pipeline_cache:expire_pipeline_cache
:worker_name: ExpirePipelineCacheWorker
@@ -1497,6 +1429,15 @@
:weight: 3
:idempotent:
:tags: []
+- :name: pipeline_creation:ci_external_pull_requests_create_pipeline
+ :worker_name: Ci::ExternalPullRequests::CreatePipelineWorker
+ :feature_category: :pipeline_authoring
+ :has_external_dependencies:
+ :urgency: :high
+ :resource_boundary: :cpu
+ :weight: 4
+ :idempotent:
+ :tags: []
- :name: pipeline_creation:create_pipeline
:worker_name: CreatePipelineWorker
:feature_category: :continuous_integration
@@ -1541,8 +1482,7 @@
:resource_boundary: :unknown
:weight: 3
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: pipeline_default:ci_merge_requests_add_todo_when_build_fails
:worker_name: Ci::MergeRequests::AddTodoWhenBuildFailsWorker
:feature_category: :continuous_integration
@@ -1551,8 +1491,7 @@
:resource_boundary: :unknown
:weight: 3
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: pipeline_default:ci_pipeline_bridge_status
:worker_name: Ci::PipelineBridgeStatusWorker
:feature_category: :continuous_integration
@@ -1742,6 +1681,15 @@
:weight: 1
:idempotent:
:tags: []
+- :name: todos_destroyer:todos_destroyer_destroyed_designs
+ :worker_name: TodosDestroyer::DestroyedDesignsWorker
+ :feature_category: :issue_tracking
+ :has_external_dependencies:
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 1
+ :idempotent: true
+ :tags: []
- :name: todos_destroyer:todos_destroyer_destroyed_issuable
:worker_name: TodosDestroyer::DestroyedIssuableWorker
:feature_category: :issue_tracking
@@ -1750,8 +1698,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: todos_destroyer:todos_destroyer_entity_leave
:worker_name: TodosDestroyer::EntityLeaveWorker
:feature_category: :issue_tracking
@@ -1823,8 +1770,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: approve_blocked_pending_approval_users
:worker_name: ApproveBlockedPendingApprovalUsersWorker
:feature_category: :users
@@ -1833,8 +1779,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: authorized_keys
:worker_name: AuthorizedKeysWorker
:feature_category: :source_code_management
@@ -1870,8 +1815,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: bulk_imports_entity
:worker_name: BulkImports::EntityWorker
:feature_category: :importers
@@ -1880,8 +1824,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: bulk_imports_export_request
:worker_name: BulkImports::ExportRequestWorker
:feature_category: :importers
@@ -1899,8 +1842,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: bulk_imports_relation_export
:worker_name: BulkImports::RelationExportWorker
:feature_category: :importers
@@ -1909,8 +1851,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: chat_notification
:worker_name: ChatNotificationWorker
:feature_category: :chatops
@@ -1928,8 +1869,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: create_commit_signature
:worker_name: CreateCommitSignatureWorker
:feature_category: :source_code_management
@@ -2001,8 +1941,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: design_management_new_version
:worker_name: DesignManagement::NewVersionWorker
:feature_category: :design_management
@@ -2020,8 +1959,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: detect_repository_languages
:worker_name: DetectRepositoryLanguagesWorker
:feature_category: :source_code_management
@@ -2039,8 +1977,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: disallow_two_factor_for_subgroups
:worker_name: DisallowTwoFactorForSubgroupsWorker
:feature_category: :subgroups
@@ -2049,8 +1986,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: email_receiver
:worker_name: EmailReceiverWorker
:feature_category: :issue_tracking
@@ -2070,6 +2006,15 @@
:weight: 2
:idempotent:
:tags: []
+- :name: environments_auto_stop
+ :worker_name: Environments::AutoStopWorker
+ :feature_category: :continuous_delivery
+ :has_external_dependencies:
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 1
+ :idempotent: true
+ :tags: []
- :name: environments_canary_ingress_update
:worker_name: Environments::CanaryIngress::UpdateWorker
:feature_category: :continuous_delivery
@@ -2078,8 +2023,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: error_tracking_issue_link
:worker_name: ErrorTrackingIssueLinkWorker
:feature_category: :error_tracking
@@ -2097,8 +2041,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: expire_build_instance_artifacts
:worker_name: ExpireBuildInstanceArtifactsWorker
:feature_category: :continuous_integration
@@ -2143,8 +2086,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: github_import_advance_stage
:worker_name: Gitlab::GithubImport::AdvanceStageWorker
:feature_category: :importers
@@ -2162,8 +2104,7 @@
:resource_boundary: :cpu
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: gitlab_shell
:worker_name: GitlabShellWorker
:feature_category: :source_code_management
@@ -2181,9 +2122,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :requires_disk_io
- - :exclude_from_kubernetes
+ :tags: []
- :name: group_export
:worker_name: GroupExportWorker
:feature_category: :importers
@@ -2273,8 +2212,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: mailers
:worker_name: ActionMailer::MailDeliveryJob
:feature_category: :issue_tracking
@@ -2301,8 +2239,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: merge_request_mergeability_check
:worker_name: MergeRequestMergeabilityCheckWorker
:feature_category: :code_review
@@ -2356,8 +2293,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: migrate_external_diffs
:worker_name: MigrateExternalDiffsWorker
:feature_category: :code_review
@@ -2384,8 +2320,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: namespaces_onboarding_pipeline_created
:worker_name: Namespaces::OnboardingPipelineCreatedWorker
:feature_category: :subgroups
@@ -2394,8 +2329,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: namespaces_onboarding_progress
:worker_name: Namespaces::OnboardingProgressWorker
:feature_category: :product_analytics
@@ -2404,8 +2338,7 @@
:resource_boundary: :cpu
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: namespaces_onboarding_user_added
:worker_name: Namespaces::OnboardingUserAddedWorker
:feature_category: :users
@@ -2414,8 +2347,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: new_issue
:worker_name: NewIssueWorker
:feature_category: :issue_tracking
@@ -2451,8 +2383,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: pages
:worker_name: PagesWorker
:feature_category: :pages
@@ -2461,9 +2392,7 @@
:resource_boundary: :cpu
:weight: 1
:idempotent:
- :tags:
- - :requires_disk_io
- - :exclude_from_kubernetes
+ :tags: []
- :name: pages_domain_ssl_renewal
:worker_name: PagesDomainSslRenewalWorker
:feature_category: :pages
@@ -2472,9 +2401,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :requires_disk_io
- - :exclude_from_kubernetes
+ :tags: []
- :name: pages_domain_verification
:worker_name: PagesDomainVerificationWorker
:feature_category: :pages
@@ -2483,9 +2410,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :requires_disk_io
- - :exclude_from_kubernetes
+ :tags: []
- :name: pages_remove
:worker_name: PagesRemoveWorker
:feature_category: :pages
@@ -2494,8 +2419,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: pages_transfer
:worker_name: PagesTransferWorker
:feature_category: :pages
@@ -2504,8 +2428,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: pages_update_configuration
:worker_name: PagesUpdateConfigurationWorker
:feature_category: :pages
@@ -2514,8 +2437,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: phabricator_import_import_tasks
:worker_name: Gitlab::PhabricatorImport::ImportTasksWorker
:feature_category: :importers
@@ -2532,7 +2454,7 @@
:urgency: :high
:resource_boundary: :cpu
:weight: 5
- :idempotent:
+ :idempotent: true
:tags: []
- :name: process_commit
:worker_name: ProcessCommitWorker
@@ -2569,9 +2491,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :requires_disk_io
- - :exclude_from_kubernetes
+ :tags: []
- :name: project_export
:worker_name: ProjectExportWorker
:feature_category: :importers
@@ -2598,8 +2518,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: projects_post_creation
:worker_name: Projects::PostCreationWorker
:feature_category: :source_code_management
@@ -2608,8 +2527,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: projects_schedule_bulk_repository_shard_moves
:worker_name: Projects::ScheduleBulkRepositoryShardMovesWorker
:feature_category: :gitaly
@@ -2654,8 +2572,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: propagate_integration_inherit
:worker_name: PropagateIntegrationInheritWorker
:feature_category: :integrations
@@ -2664,8 +2581,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: propagate_integration_inherit_descendant
:worker_name: PropagateIntegrationInheritDescendantWorker
:feature_category: :integrations
@@ -2674,8 +2590,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: propagate_integration_project
:worker_name: PropagateIntegrationProjectWorker
:feature_category: :integrations
@@ -2684,8 +2599,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: propagate_service_template
:worker_name: PropagateServiceTemplateWorker
:feature_category: :integrations
@@ -2721,8 +2635,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: remote_mirror_notification
:worker_name: RemoteMirrorNotificationWorker
:feature_category: :source_code_management
@@ -2799,7 +2712,7 @@
:worker_name: ServiceDeskEmailReceiverWorker
:feature_category: :service_desk
:has_external_dependencies:
- :urgency: :low
+ :urgency: :high
:resource_boundary: :unknown
:weight: 1
:idempotent:
@@ -2894,8 +2807,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: web_hooks_log_execution
:worker_name: WebHooks::LogExecutionWorker
:feature_category: :integrations
@@ -2913,8 +2825,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :exclude_from_kubernetes
+ :tags: []
- :name: x509_certificate_revoke
:worker_name: X509CertificateRevokeWorker
:feature_category: :source_code_management
diff --git a/app/workers/analytics/usage_trends/count_job_trigger_worker.rb b/app/workers/analytics/usage_trends/count_job_trigger_worker.rb
index 41ef75ac20a..dae576a6521 100644
--- a/app/workers/analytics/usage_trends/count_job_trigger_worker.rb
+++ b/app/workers/analytics/usage_trends/count_job_trigger_worker.rb
@@ -13,7 +13,6 @@ module Analytics
DEFAULT_DELAY = 3.minutes.freeze
feature_category :devops_reports
- tags :exclude_from_kubernetes
urgency :low
idempotent!
diff --git a/app/workers/analytics/usage_trends/counter_job_worker.rb b/app/workers/analytics/usage_trends/counter_job_worker.rb
index bfb8a435939..b3a8f7dd3c2 100644
--- a/app/workers/analytics/usage_trends/counter_job_worker.rb
+++ b/app/workers/analytics/usage_trends/counter_job_worker.rb
@@ -12,7 +12,6 @@ module Analytics
feature_category :devops_reports
urgency :low
- tags :exclude_from_kubernetes
idempotent!
diff --git a/app/workers/approve_blocked_pending_approval_users_worker.rb b/app/workers/approve_blocked_pending_approval_users_worker.rb
index fdf1bd99558..661ec87c1dd 100644
--- a/app/workers/approve_blocked_pending_approval_users_worker.rb
+++ b/app/workers/approve_blocked_pending_approval_users_worker.rb
@@ -10,7 +10,6 @@ class ApproveBlockedPendingApprovalUsersWorker
idempotent!
feature_category :users
- tags :exclude_from_kubernetes
def perform(current_user_id)
current_user = User.find(current_user_id)
diff --git a/app/workers/authorized_project_update/user_refresh_from_replica_worker.rb b/app/workers/authorized_project_update/user_refresh_from_replica_worker.rb
index ef5dcc1cb99..48e3d0837c7 100644
--- a/app/workers/authorized_project_update/user_refresh_from_replica_worker.rb
+++ b/app/workers/authorized_project_update/user_refresh_from_replica_worker.rb
@@ -14,19 +14,12 @@ module AuthorizedProjectUpdate
deduplicate :until_executing, including_scheduled: true
def perform(user_id)
- if Feature.enabled?(:user_refresh_from_replica_worker_uses_replica_db)
- use_replica_if_available do
- user = User.find_by_id(user_id)
-
- if user && project_authorizations_needs_refresh?(user)
- enqueue_project_authorizations_refresh(user)
- end
- end
- else
+ use_replica_if_available do
user = User.find_by_id(user_id)
- return unless user
- user.refresh_authorized_projects(source: self.class.name)
+ if user && project_authorizations_needs_refresh?(user)
+ enqueue_project_authorizations_refresh(user)
+ end
end
end
diff --git a/app/workers/background_migration_worker.rb b/app/workers/background_migration_worker.rb
index ef58258d998..b771ab4d4e7 100644
--- a/app/workers/background_migration_worker.rb
+++ b/app/workers/background_migration_worker.rb
@@ -3,6 +3,8 @@
class BackgroundMigrationWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
+ MAX_LEASE_ATTEMPTS = 5
+
data_consistency :always
sidekiq_options retry: 3
@@ -30,10 +32,11 @@ class BackgroundMigrationWorker # rubocop:disable Scalability/IdempotentWorker
# lease_attempts - The number of times we will try to obtain an exclusive
# lease on the class before giving up. See MR for more discussion.
# https://gitlab.com/gitlab-org/gitlab/-/merge_requests/45298#note_434304956
- def perform(class_name, arguments = [], lease_attempts = 5)
+ def perform(class_name, arguments = [], lease_attempts = MAX_LEASE_ATTEMPTS)
with_context(caller_id: class_name.to_s) do
+ retried = lease_attempts != MAX_LEASE_ATTEMPTS
attempts_left = lease_attempts - 1
- should_perform, ttl = perform_and_ttl(class_name, attempts_left)
+ should_perform, ttl = perform_and_ttl(class_name, attempts_left, retried)
break if should_perform.nil?
@@ -50,13 +53,13 @@ class BackgroundMigrationWorker # rubocop:disable Scalability/IdempotentWorker
end
end
- def perform_and_ttl(class_name, attempts_left)
+ def perform_and_ttl(class_name, attempts_left, retried)
# In test environments `perform_in` will run right away. This can then
# lead to stack level errors in the above `#perform`. To work around this
# we'll just perform the migration right away in the test environment.
return [true, nil] if always_perform?
- lease = lease_for(class_name)
+ lease = lease_for(class_name, retried)
lease_obtained = !!lease.try_obtain
healthy_db = healthy_database?
perform = lease_obtained && healthy_db
@@ -82,13 +85,17 @@ class BackgroundMigrationWorker # rubocop:disable Scalability/IdempotentWorker
[perform, lease.ttl]
end
- def lease_for(class_name)
+ def lease_for(class_name, retried)
Gitlab::ExclusiveLease
- .new(lease_key_for(class_name), timeout: self.class.minimum_interval)
+ .new(lease_key_for(class_name, retried), timeout: self.class.minimum_interval)
end
- def lease_key_for(class_name)
- "#{self.class.name}:#{class_name}"
+ def lease_key_for(class_name, retried)
+ key = "#{self.class.name}:#{class_name}"
+ # We use a different exclusive lock key for retried jobs to allow them running concurrently with the scheduled jobs.
+ # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68763 for more information.
+ key += ":retried" if retried
+ key
end
def always_perform?
diff --git a/app/workers/build_success_worker.rb b/app/workers/build_success_worker.rb
index 3f3d61a8df1..ce39ac946a9 100644
--- a/app/workers/build_success_worker.rb
+++ b/app/workers/build_success_worker.rb
@@ -21,8 +21,6 @@ class BuildSuccessWorker # rubocop:disable Scalability/IdempotentWorker
private
- ##
- # TODO: This should be processed in DeploymentSuccessWorker once we started storing `action` value in `deployments` records
def stop_environment(build)
build.persisted_environment.fire_state_event(:stop)
end
diff --git a/app/workers/bulk_import_worker.rb b/app/workers/bulk_import_worker.rb
index d7f0b752a34..fa255d064cc 100644
--- a/app/workers/bulk_import_worker.rb
+++ b/app/workers/bulk_import_worker.rb
@@ -6,7 +6,6 @@ class BulkImportWorker # rubocop:disable Scalability/IdempotentWorker
data_consistency :always
feature_category :importers
- tags :exclude_from_kubernetes
sidekiq_options retry: false, dead: false
@@ -25,9 +24,9 @@ class BulkImportWorker # rubocop:disable Scalability/IdempotentWorker
@bulk_import.start! if @bulk_import.created?
created_entities.first(next_batch_size).each do |entity|
- create_pipeline_tracker_for(entity)
+ entity.create_pipeline_trackers!
- BulkImports::ExportRequestWorker.perform_async(entity.id)
+ BulkImports::ExportRequestWorker.perform_async(entity.id) if entity.group_entity?
BulkImports::EntityWorker.perform_async(entity.id)
entity.start!
@@ -76,13 +75,4 @@ class BulkImportWorker # rubocop:disable Scalability/IdempotentWorker
def re_enqueue
BulkImportWorker.perform_in(PERFORM_DELAY, @bulk_import.id)
end
-
- def create_pipeline_tracker_for(entity)
- BulkImports::Stage.pipelines.each do |stage, pipeline|
- entity.trackers.create!(
- stage: stage,
- pipeline_name: pipeline
- )
- end
- end
end
diff --git a/app/workers/bulk_imports/entity_worker.rb b/app/workers/bulk_imports/entity_worker.rb
index cc52e349130..5c04cdc96a0 100644
--- a/app/workers/bulk_imports/entity_worker.rb
+++ b/app/workers/bulk_imports/entity_worker.rb
@@ -7,7 +7,6 @@ module BulkImports
data_consistency :always
feature_category :importers
- tags :exclude_from_kubernetes
sidekiq_options retry: false, dead: false
diff --git a/app/workers/bulk_imports/pipeline_worker.rb b/app/workers/bulk_imports/pipeline_worker.rb
index 713c6c69213..760a309a381 100644
--- a/app/workers/bulk_imports/pipeline_worker.rb
+++ b/app/workers/bulk_imports/pipeline_worker.rb
@@ -9,7 +9,6 @@ module BulkImports
NDJSON_PIPELINE_PERFORM_DELAY = 1.minute
feature_category :importers
- tags :exclude_from_kubernetes
sidekiq_options retry: false, dead: false
diff --git a/app/workers/bulk_imports/relation_export_worker.rb b/app/workers/bulk_imports/relation_export_worker.rb
index 416dad5b3ae..9324b79cc75 100644
--- a/app/workers/bulk_imports/relation_export_worker.rb
+++ b/app/workers/bulk_imports/relation_export_worker.rb
@@ -10,7 +10,6 @@ module BulkImports
idempotent!
loggable_arguments 2, 3
feature_category :importers
- tags :exclude_from_kubernetes
sidekiq_options status_expiration: StuckExportJobsWorker::EXPORT_JOBS_EXPIRATION
def perform(user_id, portable_id, portable_class, relation)
diff --git a/app/workers/ci/delete_objects_worker.rb b/app/workers/ci/delete_objects_worker.rb
index d31d248597b..cbcad3e8838 100644
--- a/app/workers/ci/delete_objects_worker.rb
+++ b/app/workers/ci/delete_objects_worker.rb
@@ -10,7 +10,6 @@ module Ci
include LimitedCapacity::Worker
feature_category :continuous_integration
- tags :exclude_from_kubernetes
idempotent!
def perform_work(*args)
diff --git a/app/workers/ci/drop_pipeline_worker.rb b/app/workers/ci/drop_pipeline_worker.rb
index f3672dba3fe..edb97c3cac5 100644
--- a/app/workers/ci/drop_pipeline_worker.rb
+++ b/app/workers/ci/drop_pipeline_worker.rb
@@ -9,8 +9,6 @@ module Ci
sidekiq_options retry: 3
include PipelineQueue
- tags :exclude_from_kubernetes
-
idempotent!
def perform(pipeline_id, failure_reason)
diff --git a/app/workers/ci/external_pull_requests/create_pipeline_worker.rb b/app/workers/ci/external_pull_requests/create_pipeline_worker.rb
new file mode 100644
index 00000000000..211ea1f2990
--- /dev/null
+++ b/app/workers/ci/external_pull_requests/create_pipeline_worker.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+module Ci
+ module ExternalPullRequests
+ class CreatePipelineWorker # rubocop:disable Scalability/IdempotentWorker
+ include ApplicationWorker
+
+ data_consistency :always
+ queue_namespace :pipeline_creation
+ feature_category :pipeline_authoring
+ urgency :high
+ worker_resource_boundary :cpu
+
+ def perform(project_id, user_id, external_pull_request_id)
+ user = User.find_by_id(user_id)
+ return unless user
+
+ project = Project.find_by_id(project_id)
+ return unless project
+
+ external_pull_request = project.external_pull_requests.find_by_id(external_pull_request_id)
+ return unless external_pull_request
+
+ ::Ci::CreatePipelineService
+ .new(project, user, execute_params(external_pull_request))
+ .execute(:external_pull_request_event, external_pull_request: external_pull_request)
+ end
+
+ private
+
+ def execute_params(pull_request)
+ {
+ ref: pull_request.source_ref,
+ source_sha: pull_request.source_sha,
+ target_sha: pull_request.target_sha
+ }
+ end
+ end
+ end
+end
diff --git a/app/workers/ci/merge_requests/add_todo_when_build_fails_worker.rb b/app/workers/ci/merge_requests/add_todo_when_build_fails_worker.rb
index af042dc1e64..98bb259db0a 100644
--- a/app/workers/ci/merge_requests/add_todo_when_build_fails_worker.rb
+++ b/app/workers/ci/merge_requests/add_todo_when_build_fails_worker.rb
@@ -10,7 +10,6 @@ module Ci
include PipelineQueue
urgency :low
- tags :exclude_from_kubernetes
idempotent!
def perform(job_id)
diff --git a/app/workers/ci/pipeline_artifacts/create_quality_report_worker.rb b/app/workers/ci/pipeline_artifacts/create_quality_report_worker.rb
index 06bc100c66a..bb0a81a0a17 100644
--- a/app/workers/ci/pipeline_artifacts/create_quality_report_worker.rb
+++ b/app/workers/ci/pipeline_artifacts/create_quality_report_worker.rb
@@ -11,7 +11,6 @@ module Ci
queue_namespace :pipeline_background
feature_category :code_testing
- tags :exclude_from_kubernetes
idempotent!
diff --git a/app/workers/ci/pipeline_artifacts/expire_artifacts_worker.rb b/app/workers/ci/pipeline_artifacts/expire_artifacts_worker.rb
index e4dc293353b..2af07cf6f93 100644
--- a/app/workers/ci/pipeline_artifacts/expire_artifacts_worker.rb
+++ b/app/workers/ci/pipeline_artifacts/expire_artifacts_worker.rb
@@ -15,7 +15,6 @@ module Ci
deduplicate :until_executed, including_scheduled: true
idempotent!
feature_category :continuous_integration
- tags :exclude_from_kubernetes
def perform
service = ::Ci::PipelineArtifacts::DestroyAllExpiredService.new
diff --git a/app/workers/ci/schedule_delete_objects_cron_worker.rb b/app/workers/ci/schedule_delete_objects_cron_worker.rb
index 06bf83ae0a7..55b23bbab62 100644
--- a/app/workers/ci/schedule_delete_objects_cron_worker.rb
+++ b/app/workers/ci/schedule_delete_objects_cron_worker.rb
@@ -12,7 +12,6 @@ module Ci
# rubocop:enable Scalability/CronWorkerContext
feature_category :continuous_integration
- tags :exclude_from_kubernetes
idempotent!
def perform(*args)
diff --git a/app/workers/ci/test_failure_history_worker.rb b/app/workers/ci/test_failure_history_worker.rb
index b67797edf0b..e79ca50c8ce 100644
--- a/app/workers/ci/test_failure_history_worker.rb
+++ b/app/workers/ci/test_failure_history_worker.rb
@@ -9,8 +9,6 @@ module Ci
sidekiq_options retry: 3
include PipelineBackgroundQueue
- tags :exclude_from_kubernetes
-
idempotent!
def perform(pipeline_id)
diff --git a/app/workers/concerns/application_worker.rb b/app/workers/concerns/application_worker.rb
index 6cc6c30c5e9..3399a4f9b57 100644
--- a/app/workers/concerns/application_worker.rb
+++ b/app/workers/concerns/application_worker.rb
@@ -58,10 +58,7 @@ module ApplicationWorker
Gitlab::SidekiqConfig::WorkerRouter.queue_name_from_worker_name(self)
end
- override :validate_worker_attributes!
def validate_worker_attributes!
- super
-
# Since the delayed data_consistency will use sidekiq built in retry mechanism, it is required that this mechanism
# is not disabled.
if retry_disabled? && get_data_consistency == :delayed
@@ -81,6 +78,13 @@ module ApplicationWorker
end
end
+ override :data_consistency
+ def data_consistency(data_consistency, feature_flag: nil)
+ super
+
+ validate_worker_attributes!
+ end
+
def perform_async(*args)
# Worker execution for workers with data_consistency set to :delayed or :sticky
# will be delayed to give replication enough time to complete
diff --git a/app/workers/concerns/chaos_queue.rb b/app/workers/concerns/chaos_queue.rb
index 2ccd55157c6..a9c557f0175 100644
--- a/app/workers/concerns/chaos_queue.rb
+++ b/app/workers/concerns/chaos_queue.rb
@@ -6,6 +6,5 @@ module ChaosQueue
included do
queue_namespace :chaos
feature_category_not_owned!
- tags :exclude_from_gitlab_com
end
end
diff --git a/app/workers/concerns/worker_attributes.rb b/app/workers/concerns/worker_attributes.rb
index 806fce38636..eebea30655c 100644
--- a/app/workers/concerns/worker_attributes.rb
+++ b/app/workers/concerns/worker_attributes.rb
@@ -92,17 +92,6 @@ module WorkerAttributes
set_class_attribute(:data_consistency_feature_flag, feature_flag) if feature_flag
set_class_attribute(:data_consistency, data_consistency)
-
- validate_worker_attributes!
- end
-
- def validate_worker_attributes!
- # Since the deduplication should always take into account the latest binary replication pointer into account,
- # not the first one, the deduplication will not work with sticky or delayed.
- # Follow up issue to improve this: https://gitlab.com/gitlab-org/gitlab/-/issues/325291
- if idempotent? && utilizes_load_balancing_capabilities?
- raise ArgumentError, "Class can't be marked as idempotent if data_consistency is not set to :always"
- end
end
# If data_consistency is not set to :always, worker will try to utilize load balancing capabilities and use the replica
@@ -147,8 +136,6 @@ module WorkerAttributes
def idempotent!
set_class_attribute(:idempotent, true)
-
- validate_worker_attributes!
end
def idempotent?
diff --git a/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb b/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb
index de9bb4d5a93..433ed5e0ea4 100644
--- a/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb
+++ b/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb
@@ -12,7 +12,6 @@ module ContainerExpirationPolicies
queue_namespace :container_repository
feature_category :container_registry
- tags :exclude_from_kubernetes
urgency :low
worker_resource_boundary :unknown
idempotent!
diff --git a/app/workers/database/batched_background_migration_worker.rb b/app/workers/database/batched_background_migration_worker.rb
index 0750ff1acaf..fda539b372d 100644
--- a/app/workers/database/batched_background_migration_worker.rb
+++ b/app/workers/database/batched_background_migration_worker.rb
@@ -9,7 +9,6 @@ module Database
include CronjobQueue # rubocop:disable Scalability/CronWorkerContext
feature_category :database
- tags :exclude_from_kubernetes
idempotent!
LEASE_TIMEOUT_MULTIPLIER = 3
diff --git a/app/workers/database/partition_management_worker.rb b/app/workers/database/partition_management_worker.rb
index a203c76558a..5a1f139dc29 100644
--- a/app/workers/database/partition_management_worker.rb
+++ b/app/workers/database/partition_management_worker.rb
@@ -12,7 +12,7 @@ module Database
idempotent!
def perform
- Gitlab::Database::Partitioning::PartitionManager.new.sync_partitions
+ Gitlab::Database::Partitioning.sync_partitions
ensure
Gitlab::Database::Partitioning::PartitionMonitoring.new.report_metrics
end
diff --git a/app/workers/deployments/drop_older_deployments_worker.rb b/app/workers/deployments/drop_older_deployments_worker.rb
index 979f683cfb3..c464febd119 100644
--- a/app/workers/deployments/drop_older_deployments_worker.rb
+++ b/app/workers/deployments/drop_older_deployments_worker.rb
@@ -10,7 +10,6 @@ module Deployments
queue_namespace :deployment
feature_category :continuous_delivery
- tags :exclude_from_kubernetes
def perform(deployment_id)
Deployments::OlderDeploymentsDropService.new(deployment_id).execute
diff --git a/app/workers/deployments/finished_worker.rb b/app/workers/deployments/finished_worker.rb
deleted file mode 100644
index 25121656408..00000000000
--- a/app/workers/deployments/finished_worker.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# frozen_string_literal: true
-
-# This worker is deprecated and will be removed in 14.0
-# See: https://gitlab.com/gitlab-org/gitlab/-/issues/266381
-module Deployments
- class FinishedWorker # rubocop:disable Scalability/IdempotentWorker
- include ApplicationWorker
-
- data_consistency :always
-
- sidekiq_options retry: 3
-
- queue_namespace :deployment
- feature_category :continuous_delivery
- worker_resource_boundary :cpu
-
- def perform(deployment_id)
- if (deploy = Deployment.find_by_id(deployment_id))
- LinkMergeRequestsService.new(deploy).execute
- deploy.execute_hooks(Time.current)
- end
- end
- end
-end
diff --git a/app/workers/deployments/forward_deployment_worker.rb b/app/workers/deployments/forward_deployment_worker.rb
deleted file mode 100644
index 7f5eb13b88d..00000000000
--- a/app/workers/deployments/forward_deployment_worker.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-# This worker is deprecated and will be removed in 14.0
-# See: https://gitlab.com/gitlab-org/gitlab/-/issues/266381
-module Deployments
- class ForwardDeploymentWorker # rubocop:disable Scalability/IdempotentWorker
- include ApplicationWorker
-
- data_consistency :always
-
- sidekiq_options retry: 3
-
- queue_namespace :deployment
- feature_category :continuous_delivery
-
- def perform(deployment_id)
- Deployments::OlderDeploymentsDropService.new(deployment_id).execute
- end
- end
-end
diff --git a/app/workers/deployments/hooks_worker.rb b/app/workers/deployments/hooks_worker.rb
index d23a440ed36..31c57e5c001 100644
--- a/app/workers/deployments/hooks_worker.rb
+++ b/app/workers/deployments/hooks_worker.rb
@@ -4,7 +4,7 @@ module Deployments
class HooksWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
- data_consistency :delayed, feature_flag: :load_balancing_for_deployments_hooks_worker
+ data_consistency :delayed
queue_namespace :deployment
feature_category :continuous_delivery
diff --git a/app/workers/deployments/success_worker.rb b/app/workers/deployments/success_worker.rb
deleted file mode 100644
index 401c2d7600c..00000000000
--- a/app/workers/deployments/success_worker.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# frozen_string_literal: true
-
-# This worker is deprecated and will be removed in 14.0
-# See: https://gitlab.com/gitlab-org/gitlab/-/issues/266381
-module Deployments
- class SuccessWorker # rubocop:disable Scalability/IdempotentWorker
- include ApplicationWorker
-
- data_consistency :always
-
- sidekiq_options retry: 3
-
- queue_namespace :deployment
- feature_category :continuous_delivery
- worker_resource_boundary :cpu
-
- def perform(deployment_id)
- Deployment.find_by_id(deployment_id).try do |deployment|
- break unless deployment.success?
-
- Deployments::UpdateEnvironmentService.new(deployment).execute
- end
- end
- end
-end
diff --git a/app/workers/design_management/copy_design_collection_worker.rb b/app/workers/design_management/copy_design_collection_worker.rb
index a498eed173c..8b265979afa 100644
--- a/app/workers/design_management/copy_design_collection_worker.rb
+++ b/app/workers/design_management/copy_design_collection_worker.rb
@@ -9,7 +9,6 @@ module DesignManagement
sidekiq_options retry: 3
feature_category :design_management
- tags :exclude_from_kubernetes
idempotent!
urgency :low
diff --git a/app/workers/destroy_pages_deployments_worker.rb b/app/workers/destroy_pages_deployments_worker.rb
index 36424f7473e..7fa73648dd2 100644
--- a/app/workers/destroy_pages_deployments_worker.rb
+++ b/app/workers/destroy_pages_deployments_worker.rb
@@ -10,7 +10,6 @@ class DestroyPagesDeploymentsWorker
loggable_arguments 0, 1
sidekiq_options retry: 3
feature_category :pages
- tags :exclude_from_kubernetes
def perform(project_id, last_deployment_id = nil)
project = Project.find_by_id(project_id)
diff --git a/app/workers/disallow_two_factor_for_group_worker.rb b/app/workers/disallow_two_factor_for_group_worker.rb
index 4f5ef69a730..5b958f9f31f 100644
--- a/app/workers/disallow_two_factor_for_group_worker.rb
+++ b/app/workers/disallow_two_factor_for_group_worker.rb
@@ -9,7 +9,6 @@ class DisallowTwoFactorForGroupWorker
include ExceptionBacktrace
feature_category :subgroups
- tags :exclude_from_kubernetes
idempotent!
def perform(group_id)
diff --git a/app/workers/disallow_two_factor_for_subgroups_worker.rb b/app/workers/disallow_two_factor_for_subgroups_worker.rb
index d3528b0674b..500c13deed2 100644
--- a/app/workers/disallow_two_factor_for_subgroups_worker.rb
+++ b/app/workers/disallow_two_factor_for_subgroups_worker.rb
@@ -11,7 +11,6 @@ class DisallowTwoFactorForSubgroupsWorker
INTERVAL = 2.seconds.to_i
feature_category :subgroups
- tags :exclude_from_kubernetes
idempotent!
def perform(group_id)
diff --git a/app/workers/email_receiver_worker.rb b/app/workers/email_receiver_worker.rb
index 1514897b2e4..51211834e06 100644
--- a/app/workers/email_receiver_worker.rb
+++ b/app/workers/email_receiver_worker.rb
@@ -11,7 +11,7 @@ class EmailReceiverWorker # rubocop:disable Scalability/IdempotentWorker
urgency :high
weight 2
- # https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1087#jobs-written-to-redis-without-passing-through-the-application
+ # https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1263
tags :needs_own_queue
attr_accessor :raw
diff --git a/app/workers/environments/auto_stop_worker.rb b/app/workers/environments/auto_stop_worker.rb
new file mode 100644
index 00000000000..672a4f4121e
--- /dev/null
+++ b/app/workers/environments/auto_stop_worker.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module Environments
+ class AutoStopWorker
+ include ApplicationWorker
+
+ data_consistency :always
+ idempotent!
+ feature_category :continuous_delivery
+
+ def perform(environment_id, params = {})
+ Environment.find_by_id(environment_id).try do |environment|
+ user = environment.stop_action&.user
+ environment.stop_with_action!(user)
+ end
+ end
+ end
+end
diff --git a/app/workers/environments/canary_ingress/update_worker.rb b/app/workers/environments/canary_ingress/update_worker.rb
index 591c88cac96..02f24db1469 100644
--- a/app/workers/environments/canary_ingress/update_worker.rb
+++ b/app/workers/environments/canary_ingress/update_worker.rb
@@ -11,7 +11,6 @@ module Environments
idempotent!
worker_has_external_dependencies!
feature_category :continuous_delivery
- tags :exclude_from_kubernetes
def perform(environment_id, params)
Environment.find_by_id(environment_id).try do |environment|
diff --git a/app/workers/experiments/record_conversion_event_worker.rb b/app/workers/experiments/record_conversion_event_worker.rb
index 4c82c114d15..6487f030628 100644
--- a/app/workers/experiments/record_conversion_event_worker.rb
+++ b/app/workers/experiments/record_conversion_event_worker.rb
@@ -9,7 +9,6 @@ module Experiments
sidekiq_options retry: 3
feature_category :users
- tags :exclude_from_kubernetes
urgency :low
idempotent!
diff --git a/app/workers/expire_job_cache_worker.rb b/app/workers/expire_job_cache_worker.rb
index cd5ca25f031..401fe1dc1e5 100644
--- a/app/workers/expire_job_cache_worker.rb
+++ b/app/workers/expire_job_cache_worker.rb
@@ -1,20 +1,24 @@
# frozen_string_literal: true
-class ExpireJobCacheWorker
+class ExpireJobCacheWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
- data_consistency :always
+ data_consistency :delayed
sidekiq_options retry: 3
include PipelineQueue
queue_namespace :pipeline_cache
urgency :high
- idempotent!
+ # This worker should be idempotent, but we're switching to data_consistency
+ # :sticky and there is an ongoing incompatibility, so it needs to be disabled for
+ # now. The following line can be uncommented and this comment removed once
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/325291 is resolved.
+ # idempotent!
# rubocop: disable CodeReuse/ActiveRecord
def perform(job_id)
- job = CommitStatus.eager_load_pipeline.find_by(id: job_id)
+ job = CommitStatus.preload(:pipeline, :project).find_by(id: job_id)
return unless job
pipeline = job.pipeline
diff --git a/app/workers/expire_pipeline_cache_worker.rb b/app/workers/expire_pipeline_cache_worker.rb
index 64f73d1fba1..07e6939d1c7 100644
--- a/app/workers/expire_pipeline_cache_worker.rb
+++ b/app/workers/expire_pipeline_cache_worker.rb
@@ -19,7 +19,7 @@ class ExpirePipelineCacheWorker
# rubocop: disable CodeReuse/ActiveRecord
def perform(pipeline_id)
- pipeline = Ci::Pipeline.eager_load_project.find_by(id: pipeline_id)
+ pipeline = Ci::Pipeline.find_by(id: pipeline_id)
return unless pipeline
Ci::ExpirePipelineCacheService.new.execute(pipeline)
diff --git a/app/workers/flush_counter_increments_worker.rb b/app/workers/flush_counter_increments_worker.rb
index bcb6a4c2bca..c4a3a5283cc 100644
--- a/app/workers/flush_counter_increments_worker.rb
+++ b/app/workers/flush_counter_increments_worker.rb
@@ -13,7 +13,6 @@ class FlushCounterIncrementsWorker
sidekiq_options retry: 3
feature_category_not_owned!
- tags :exclude_from_kubernetes
urgency :low
deduplicate :until_executing, including_scheduled: true
diff --git a/app/workers/gitlab/github_import/import_pull_request_merged_by_worker.rb b/app/workers/gitlab/github_import/import_pull_request_merged_by_worker.rb
index cce179542c7..ab0cb81249b 100644
--- a/app/workers/gitlab/github_import/import_pull_request_merged_by_worker.rb
+++ b/app/workers/gitlab/github_import/import_pull_request_merged_by_worker.rb
@@ -5,7 +5,6 @@ module Gitlab
class ImportPullRequestMergedByWorker # rubocop:disable Scalability/IdempotentWorker
include ObjectImporter
- tags :exclude_from_kubernetes
worker_resource_boundary :cpu
def representation_class
diff --git a/app/workers/gitlab/github_import/import_pull_request_review_worker.rb b/app/workers/gitlab/github_import/import_pull_request_review_worker.rb
index 8796d6392df..8d5c7b95b10 100644
--- a/app/workers/gitlab/github_import/import_pull_request_review_worker.rb
+++ b/app/workers/gitlab/github_import/import_pull_request_review_worker.rb
@@ -5,7 +5,6 @@ module Gitlab
class ImportPullRequestReviewWorker # rubocop:disable Scalability/IdempotentWorker
include ObjectImporter
- tags :exclude_from_kubernetes
worker_resource_boundary :cpu
def representation_class
diff --git a/app/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker.rb b/app/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker.rb
index c33836e20d1..5188bda03e2 100644
--- a/app/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker.rb
+++ b/app/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker.rb
@@ -12,17 +12,10 @@ module Gitlab
include GithubImport::Queue
include StageMethods
- # The importers to run in this stage. Issues can't be imported earlier
- # on as we also use these to enrich pull requests with assigned labels.
- IMPORTERS = [
- Importer::IssuesImporter,
- Importer::DiffNotesImporter
- ].freeze
-
# client - An instance of Gitlab::GithubImport::Client.
# project - An instance of Project.
def import(client, project)
- waiters = IMPORTERS.each_with_object({}) do |klass, hash|
+ waiters = importers(project).each_with_object({}) do |klass, hash|
info(project.id, message: "starting importer", importer: klass.name)
waiter = klass.new(project, client).execute
hash[waiter.key] = waiter.jobs_remaining
@@ -30,6 +23,25 @@ module Gitlab
AdvanceStageWorker.perform_async(project.id, waiters, :notes)
end
+
+ # The importers to run in this stage. Issues can't be imported earlier
+ # on as we also use these to enrich pull requests with assigned labels.
+ def importers(project)
+ [
+ Importer::IssuesImporter,
+ diff_notes_importer(project)
+ ]
+ end
+
+ private
+
+ def diff_notes_importer(project)
+ if project.group.present? && Feature.enabled?(:github_importer_single_endpoint_notes_import, project.group, type: :ops, default_enabled: :yaml)
+ Importer::SingleEndpointDiffNotesImporter
+ else
+ Importer::DiffNotesImporter
+ end
+ end
end
end
end
diff --git a/app/workers/gitlab/github_import/stage/import_notes_worker.rb b/app/workers/gitlab/github_import/stage/import_notes_worker.rb
index 0160145ffe2..90a1337169f 100644
--- a/app/workers/gitlab/github_import/stage/import_notes_worker.rb
+++ b/app/workers/gitlab/github_import/stage/import_notes_worker.rb
@@ -15,17 +15,31 @@ module Gitlab
# client - An instance of Gitlab::GithubImport::Client.
# project - An instance of Project.
def import(client, project)
- info(project.id, message: "starting importer", importer: 'Importer::NotesImporter')
- waiter = Importer::NotesImporter
- .new(project, client)
- .execute
+ waiters = importers(project).each_with_object({}) do |klass, hash|
+ info(project.id, message: "starting importer", importer: klass.name)
+ waiter = klass.new(project, client).execute
+ hash[waiter.key] = waiter.jobs_remaining
+ end
AdvanceStageWorker.perform_async(
project.id,
- { waiter.key => waiter.jobs_remaining },
+ waiters,
:lfs_objects
)
end
+
+ def importers(project)
+ if project.group.present? && Feature.enabled?(:github_importer_single_endpoint_notes_import, project.group, type: :ops, default_enabled: :yaml)
+ [
+ Importer::SingleEndpointMergeRequestNotesImporter,
+ Importer::SingleEndpointIssueNotesImporter
+ ]
+ else
+ [
+ Importer::NotesImporter
+ ]
+ end
+ end
end
end
end
diff --git a/app/workers/gitlab/github_import/stage/import_pull_requests_merged_by_worker.rb b/app/workers/gitlab/github_import/stage/import_pull_requests_merged_by_worker.rb
index 7d83fe288da..8c2d652a689 100644
--- a/app/workers/gitlab/github_import/stage/import_pull_requests_merged_by_worker.rb
+++ b/app/workers/gitlab/github_import/stage/import_pull_requests_merged_by_worker.rb
@@ -12,8 +12,6 @@ module Gitlab
include GithubImport::Queue
include StageMethods
- tags :exclude_from_kubernetes
-
# client - An instance of Gitlab::GithubImport::Client.
# project - An instance of Project.
def import(client, project)
diff --git a/app/workers/gitlab/github_import/stage/import_pull_requests_reviews_worker.rb b/app/workers/gitlab/github_import/stage/import_pull_requests_reviews_worker.rb
index ea3b89efd22..e10f1170618 100644
--- a/app/workers/gitlab/github_import/stage/import_pull_requests_reviews_worker.rb
+++ b/app/workers/gitlab/github_import/stage/import_pull_requests_reviews_worker.rb
@@ -12,8 +12,6 @@ module Gitlab
include GithubImport::Queue
include StageMethods
- tags :exclude_from_kubernetes
-
# client - An instance of Gitlab::GithubImport::Client.
# project - An instance of Project.
def import(client, project)
diff --git a/app/workers/gitlab_performance_bar_stats_worker.rb b/app/workers/gitlab_performance_bar_stats_worker.rb
index 4e8bcb9af7b..6d637ad1586 100644
--- a/app/workers/gitlab_performance_bar_stats_worker.rb
+++ b/app/workers/gitlab_performance_bar_stats_worker.rb
@@ -15,7 +15,6 @@ class GitlabPerformanceBarStatsWorker
STATS_KEY_EXPIRE = 30.minutes.to_i
feature_category :metrics
- tags :exclude_from_kubernetes
idempotent!
def perform(lease_uuid)
diff --git a/app/workers/group_destroy_worker.rb b/app/workers/group_destroy_worker.rb
index f44c109f12d..92195d3fe16 100644
--- a/app/workers/group_destroy_worker.rb
+++ b/app/workers/group_destroy_worker.rb
@@ -9,7 +9,6 @@ class GroupDestroyWorker # rubocop:disable Scalability/IdempotentWorker
include ExceptionBacktrace
feature_category :subgroups
- tags :requires_disk_io, :exclude_from_kubernetes
def perform(group_id, user_id)
begin
diff --git a/app/workers/hashed_storage/migrator_worker.rb b/app/workers/hashed_storage/migrator_worker.rb
index 80e86fd7814..03019ae3131 100644
--- a/app/workers/hashed_storage/migrator_worker.rb
+++ b/app/workers/hashed_storage/migrator_worker.rb
@@ -11,9 +11,8 @@ module HashedStorage
queue_namespace :hashed_storage
feature_category :source_code_management
- # Gitlab::HashedStorage::Migrator#migration_pending? depends on the
- # queue size of this worker.
- tags :exclude_from_gitlab_com, :needs_own_queue
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/340629
+ tags :needs_own_queue
# @param [Integer] start initial ID of the batch
# @param [Integer] finish last ID of the batch
diff --git a/app/workers/hashed_storage/project_migrate_worker.rb b/app/workers/hashed_storage/project_migrate_worker.rb
index edddea55356..bcc80cc2a70 100644
--- a/app/workers/hashed_storage/project_migrate_worker.rb
+++ b/app/workers/hashed_storage/project_migrate_worker.rb
@@ -11,9 +11,8 @@ module HashedStorage
queue_namespace :hashed_storage
loggable_arguments 1
- # Gitlab::HashedStorage::Migrator#migration_pending? depends on the
- # queue size of this worker.
- tags :exclude_from_gitlab_com, :needs_own_queue
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/340629
+ tags :needs_own_queue
attr_reader :project_id
diff --git a/app/workers/hashed_storage/project_rollback_worker.rb b/app/workers/hashed_storage/project_rollback_worker.rb
index c5841dbbb28..07a7ab63718 100644
--- a/app/workers/hashed_storage/project_rollback_worker.rb
+++ b/app/workers/hashed_storage/project_rollback_worker.rb
@@ -11,9 +11,8 @@ module HashedStorage
queue_namespace :hashed_storage
loggable_arguments 1
- # Gitlab::HashedStorage::Migrator#rollback_pending? depends on the
- # queue size of this worker.
- tags :exclude_from_gitlab_com, :needs_own_queue
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/340629
+ tags :needs_own_queue
attr_reader :project_id
diff --git a/app/workers/hashed_storage/rollbacker_worker.rb b/app/workers/hashed_storage/rollbacker_worker.rb
index 90e48f0e37a..d6a16b4d083 100644
--- a/app/workers/hashed_storage/rollbacker_worker.rb
+++ b/app/workers/hashed_storage/rollbacker_worker.rb
@@ -11,9 +11,8 @@ module HashedStorage
queue_namespace :hashed_storage
feature_category :source_code_management
- # Gitlab::HashedStorage::Migrator#rollback_pending? depends on the
- # queue size of this worker.
- tags :exclude_from_gitlab_com, :needs_own_queue
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/340629
+ tags :needs_own_queue
# @param [Integer] start initial ID of the batch
# @param [Integer] finish last ID of the batch
diff --git a/app/workers/incident_management/add_severity_system_note_worker.rb b/app/workers/incident_management/add_severity_system_note_worker.rb
index 31da7b0bcfe..3a4667bea0a 100644
--- a/app/workers/incident_management/add_severity_system_note_worker.rb
+++ b/app/workers/incident_management/add_severity_system_note_worker.rb
@@ -11,7 +11,6 @@ module IncidentManagement
queue_namespace :incident_management
feature_category :incident_management
- tags :exclude_from_kubernetes
def perform(incident_id, user_id)
return if incident_id.blank? || user_id.blank?
diff --git a/app/workers/issue_rebalancing_worker.rb b/app/workers/issue_rebalancing_worker.rb
index 13e02c37bdb..01984197aae 100644
--- a/app/workers/issue_rebalancing_worker.rb
+++ b/app/workers/issue_rebalancing_worker.rb
@@ -10,7 +10,6 @@ class IssueRebalancingWorker
idempotent!
urgency :low
feature_category :issue_tracking
- tags :exclude_from_kubernetes
deduplicate :until_executed, including_scheduled: true
def perform(ignore = nil, project_id = nil, root_namespace_id = nil)
@@ -33,12 +32,8 @@ class IssueRebalancingWorker
return
end
- # Temporary disable rebalancing for performance reasons
- # For more information check https://gitlab.com/gitlab-com/gl-infra/production/-/issues/4321
- return if projects_to_rebalance.take&.root_namespace&.issue_repositioning_disabled? # rubocop:disable CodeReuse/ActiveRecord
-
- IssueRebalancingService.new(projects_to_rebalance).execute
- rescue IssueRebalancingService::TooManyIssues => e
+ Issues::RelativePositionRebalancingService.new(projects_to_rebalance).execute
+ rescue Issues::RelativePositionRebalancingService::TooManyConcurrentRebalances => e
Gitlab::ErrorTracking.log_exception(e, root_namespace_id: root_namespace_id, project_id: project_id)
end
diff --git a/app/workers/jira_connect/sync_builds_worker.rb b/app/workers/jira_connect/sync_builds_worker.rb
index 379f087bc1b..1a9974af55f 100644
--- a/app/workers/jira_connect/sync_builds_worker.rb
+++ b/app/workers/jira_connect/sync_builds_worker.rb
@@ -8,7 +8,6 @@ module JiraConnect
queue_namespace :jira_connect
feature_category :integrations
data_consistency :delayed
- tags :exclude_from_kubernetes
urgency :low
worker_has_external_dependencies!
diff --git a/app/workers/jira_connect/sync_deployments_worker.rb b/app/workers/jira_connect/sync_deployments_worker.rb
index 3138230ced5..f4286752359 100644
--- a/app/workers/jira_connect/sync_deployments_worker.rb
+++ b/app/workers/jira_connect/sync_deployments_worker.rb
@@ -8,7 +8,6 @@ module JiraConnect
queue_namespace :jira_connect
feature_category :integrations
data_consistency :delayed
- tags :exclude_from_kubernetes
urgency :low
worker_has_external_dependencies!
diff --git a/app/workers/jira_connect/sync_feature_flags_worker.rb b/app/workers/jira_connect/sync_feature_flags_worker.rb
index 4de27c1b551..507d5c29f38 100644
--- a/app/workers/jira_connect/sync_feature_flags_worker.rb
+++ b/app/workers/jira_connect/sync_feature_flags_worker.rb
@@ -8,7 +8,6 @@ module JiraConnect
queue_namespace :jira_connect
feature_category :integrations
data_consistency :delayed
- tags :exclude_from_kubernetes
urgency :low
worker_has_external_dependencies!
diff --git a/app/workers/jira_connect/sync_project_worker.rb b/app/workers/jira_connect/sync_project_worker.rb
index a83444e58e7..b0ebaf30e99 100644
--- a/app/workers/jira_connect/sync_project_worker.rb
+++ b/app/workers/jira_connect/sync_project_worker.rb
@@ -8,7 +8,6 @@ module JiraConnect
queue_namespace :jira_connect
feature_category :integrations
data_consistency :delayed
- tags :exclude_from_kubernetes
urgency :low
worker_has_external_dependencies!
diff --git a/app/workers/member_invitation_reminder_emails_worker.rb b/app/workers/member_invitation_reminder_emails_worker.rb
index fa6787b9063..a7614db30f6 100644
--- a/app/workers/member_invitation_reminder_emails_worker.rb
+++ b/app/workers/member_invitation_reminder_emails_worker.rb
@@ -8,7 +8,6 @@ class MemberInvitationReminderEmailsWorker # rubocop:disable Scalability/Idempot
include CronjobQueue # rubocop:disable Scalability/CronWorkerContext
feature_category :subgroups
- tags :exclude_from_kubernetes
urgency :low
def perform
diff --git a/app/workers/merge_request_cleanup_refs_worker.rb b/app/workers/merge_request_cleanup_refs_worker.rb
index c57c6fbc28d..27bd5774b8d 100644
--- a/app/workers/merge_request_cleanup_refs_worker.rb
+++ b/app/workers/merge_request_cleanup_refs_worker.rb
@@ -10,7 +10,6 @@ class MergeRequestCleanupRefsWorker
sidekiq_options retry: 3
feature_category :code_review
- tags :exclude_from_kubernetes
idempotent!
# Hard-coded to 4 for now. Will be configurable later on via application settings.
diff --git a/app/workers/metrics/dashboard/sync_dashboards_worker.rb b/app/workers/metrics/dashboard/sync_dashboards_worker.rb
index 645c03428a2..fe8694582c4 100644
--- a/app/workers/metrics/dashboard/sync_dashboards_worker.rb
+++ b/app/workers/metrics/dashboard/sync_dashboards_worker.rb
@@ -10,7 +10,6 @@ module Metrics
sidekiq_options retry: 3
feature_category :metrics
- tags :exclude_from_kubernetes
idempotent!
diff --git a/app/workers/namespaces/in_product_marketing_emails_worker.rb b/app/workers/namespaces/in_product_marketing_emails_worker.rb
index 035fa453f59..49e65d59e83 100644
--- a/app/workers/namespaces/in_product_marketing_emails_worker.rb
+++ b/app/workers/namespaces/in_product_marketing_emails_worker.rb
@@ -9,7 +9,6 @@ module Namespaces
include CronjobQueue # rubocop:disable Scalability/CronWorkerContext
feature_category :subgroups
- tags :exclude_from_kubernetes
urgency :low
def perform
diff --git a/app/workers/namespaces/onboarding_issue_created_worker.rb b/app/workers/namespaces/onboarding_issue_created_worker.rb
index 3cff741ecbf..81d105ab19c 100644
--- a/app/workers/namespaces/onboarding_issue_created_worker.rb
+++ b/app/workers/namespaces/onboarding_issue_created_worker.rb
@@ -9,7 +9,6 @@ module Namespaces
sidekiq_options retry: 3
feature_category :issue_tracking
- tags :exclude_from_kubernetes
urgency :low
deduplicate :until_executing
diff --git a/app/workers/namespaces/onboarding_pipeline_created_worker.rb b/app/workers/namespaces/onboarding_pipeline_created_worker.rb
index 2c77fab8114..f9a6b734586 100644
--- a/app/workers/namespaces/onboarding_pipeline_created_worker.rb
+++ b/app/workers/namespaces/onboarding_pipeline_created_worker.rb
@@ -9,7 +9,6 @@ module Namespaces
sidekiq_options retry: 3
feature_category :subgroups
- tags :exclude_from_kubernetes
urgency :low
deduplicate :until_executing
diff --git a/app/workers/namespaces/onboarding_progress_worker.rb b/app/workers/namespaces/onboarding_progress_worker.rb
index 43d13618091..b77db1aec5e 100644
--- a/app/workers/namespaces/onboarding_progress_worker.rb
+++ b/app/workers/namespaces/onboarding_progress_worker.rb
@@ -10,7 +10,6 @@ module Namespaces
feature_category :product_analytics
worker_resource_boundary :cpu
- tags :exclude_from_kubernetes
urgency :low
deduplicate :until_executed
diff --git a/app/workers/namespaces/onboarding_user_added_worker.rb b/app/workers/namespaces/onboarding_user_added_worker.rb
index 4d4d9c03d3e..6a189e81b95 100644
--- a/app/workers/namespaces/onboarding_user_added_worker.rb
+++ b/app/workers/namespaces/onboarding_user_added_worker.rb
@@ -9,7 +9,6 @@ module Namespaces
sidekiq_options retry: 3
feature_category :users
- tags :exclude_from_kubernetes
urgency :low
idempotent!
diff --git a/app/workers/packages/composer/cache_cleanup_worker.rb b/app/workers/packages/composer/cache_cleanup_worker.rb
index fee886bc750..19babf63967 100644
--- a/app/workers/packages/composer/cache_cleanup_worker.rb
+++ b/app/workers/packages/composer/cache_cleanup_worker.rb
@@ -10,7 +10,6 @@ module Packages
include CronjobQueue # rubocop:disable Scalability/CronWorkerContext
feature_category :package_registry
- tags :exclude_from_kubernetes
idempotent!
diff --git a/app/workers/packages/composer/cache_update_worker.rb b/app/workers/packages/composer/cache_update_worker.rb
index f146a0a83cc..874993a1325 100644
--- a/app/workers/packages/composer/cache_update_worker.rb
+++ b/app/workers/packages/composer/cache_update_worker.rb
@@ -10,7 +10,6 @@ module Packages
sidekiq_options retry: 3
feature_category :package_registry
- tags :exclude_from_kubernetes
idempotent!
diff --git a/app/workers/packages/debian/process_changes_worker.rb b/app/workers/packages/debian/process_changes_worker.rb
index 3ddeb858429..0a716c61203 100644
--- a/app/workers/packages/debian/process_changes_worker.rb
+++ b/app/workers/packages/debian/process_changes_worker.rb
@@ -13,7 +13,6 @@ module Packages
queue_namespace :package_repositories
feature_category :package_registry
- tags :exclude_from_kubernetes
def perform(package_file_id, user_id)
@package_file_id = package_file_id
@@ -22,12 +21,7 @@ module Packages
return unless package_file && user
::Packages::Debian::ProcessChangesService.new(package_file, user).execute
- rescue ArgumentError,
- Packages::Debian::ExtractChangesMetadataService::ExtractionError,
- Packages::Debian::ExtractDebMetadataService::CommandFailedError,
- Packages::Debian::ExtractMetadataService::ExtractionError,
- Packages::Debian::ParseDebian822Service::InvalidDebian822Error,
- ActiveRecord::RecordNotFound => e
+ rescue StandardError => e
Gitlab::ErrorTracking.log_exception(e, package_file_id: @package_file_id, user_id: @user_id)
package_file.destroy!
end
diff --git a/app/workers/packages/go/sync_packages_worker.rb b/app/workers/packages/go/sync_packages_worker.rb
index 182c9bfec5d..dbf48cea1ae 100644
--- a/app/workers/packages/go/sync_packages_worker.rb
+++ b/app/workers/packages/go/sync_packages_worker.rb
@@ -12,7 +12,6 @@ module Packages
queue_namespace :package_repositories
feature_category :package_registry
- tags :exclude_from_kubernetes
deduplicate :until_executing
idempotent!
diff --git a/app/workers/packages/helm/extraction_worker.rb b/app/workers/packages/helm/extraction_worker.rb
index 1010a0833b1..0ba2d149f77 100644
--- a/app/workers/packages/helm/extraction_worker.rb
+++ b/app/workers/packages/helm/extraction_worker.rb
@@ -20,9 +20,7 @@ module Packages
::Packages::Helm::ProcessFileService.new(channel, package_file).execute
- rescue ::Packages::Helm::ExtractFileMetadataService::ExtractionError,
- ::Packages::Helm::ProcessFileService::ExtractionError,
- ::ActiveModel::ValidationError => e
+ rescue StandardError => e
Gitlab::ErrorTracking.log_exception(e, project_id: package_file.project_id)
package_file.package.update_column(:status, :error)
end
diff --git a/app/workers/packages/maven/metadata/sync_worker.rb b/app/workers/packages/maven/metadata/sync_worker.rb
index ab18c70e95e..b18b950e1c8 100644
--- a/app/workers/packages/maven/metadata/sync_worker.rb
+++ b/app/workers/packages/maven/metadata/sync_worker.rb
@@ -13,7 +13,6 @@ module Packages
queue_namespace :package_repositories
feature_category :package_registry
- tags :exclude_from_kubernetes
deduplicate :until_executing
idempotent!
diff --git a/app/workers/packages/rubygems/extraction_worker.rb b/app/workers/packages/rubygems/extraction_worker.rb
index 520305981cf..dbaf9bc35a9 100644
--- a/app/workers/packages/rubygems/extraction_worker.rb
+++ b/app/workers/packages/rubygems/extraction_worker.rb
@@ -11,7 +11,6 @@ module Packages
queue_namespace :package_repositories
feature_category :package_registry
- tags :exclude_from_kubernetes
deduplicate :until_executing
def perform(package_file_id)
diff --git a/app/workers/pages_domain_ssl_renewal_worker.rb b/app/workers/pages_domain_ssl_renewal_worker.rb
index d4c68f66699..d6b40318fd4 100644
--- a/app/workers/pages_domain_ssl_renewal_worker.rb
+++ b/app/workers/pages_domain_ssl_renewal_worker.rb
@@ -8,7 +8,6 @@ class PagesDomainSslRenewalWorker # rubocop:disable Scalability/IdempotentWorker
sidekiq_options retry: 3
feature_category :pages
- tags :requires_disk_io, :exclude_from_kubernetes
def perform(domain_id)
domain = PagesDomain.find_by_id(domain_id)
diff --git a/app/workers/pages_domain_verification_worker.rb b/app/workers/pages_domain_verification_worker.rb
index f9504a7c1d2..59de00d40d5 100644
--- a/app/workers/pages_domain_verification_worker.rb
+++ b/app/workers/pages_domain_verification_worker.rb
@@ -8,7 +8,6 @@ class PagesDomainVerificationWorker # rubocop:disable Scalability/IdempotentWork
sidekiq_options retry: 3
feature_category :pages
- tags :requires_disk_io, :exclude_from_kubernetes
# rubocop: disable CodeReuse/ActiveRecord
def perform(domain_id)
diff --git a/app/workers/pages_remove_worker.rb b/app/workers/pages_remove_worker.rb
index 69a8344b5aa..4de99b8654d 100644
--- a/app/workers/pages_remove_worker.rb
+++ b/app/workers/pages_remove_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-# TODO: remove this worker https://gitlab.com/gitlab-org/gitlab/-/issues/320775
+# TODO: remove this worker https://gitlab.com/gitlab-org/gitlab/-/issues/340641
class PagesRemoveWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
@@ -8,13 +8,9 @@ class PagesRemoveWorker # rubocop:disable Scalability/IdempotentWorker
sidekiq_options retry: 3
feature_category :pages
- tags :exclude_from_kubernetes
loggable_arguments 0
def perform(project_id)
- project = Project.find_by_id(project_id)
- return unless project
-
- project.legacy_remove_pages
+ # no-op
end
end
diff --git a/app/workers/pages_transfer_worker.rb b/app/workers/pages_transfer_worker.rb
index c2190a352dd..404c79b9e89 100644
--- a/app/workers/pages_transfer_worker.rb
+++ b/app/workers/pages_transfer_worker.rb
@@ -10,7 +10,6 @@ class PagesTransferWorker # rubocop:disable Scalability/IdempotentWorker
TransferFailedError = Class.new(StandardError)
feature_category :pages
- tags :exclude_from_kubernetes
loggable_arguments 0, 1
def perform(method, args)
diff --git a/app/workers/pages_update_configuration_worker.rb b/app/workers/pages_update_configuration_worker.rb
index 8a37b70a0b7..3dfd82ed517 100644
--- a/app/workers/pages_update_configuration_worker.rb
+++ b/app/workers/pages_update_configuration_worker.rb
@@ -9,7 +9,6 @@ class PagesUpdateConfigurationWorker
idempotent!
feature_category :pages
- tags :exclude_from_kubernetes
def self.perform_async(*args)
return unless ::Settings.pages.local_store.enabled
diff --git a/app/workers/pages_worker.rb b/app/workers/pages_worker.rb
index d0c21cf74e1..5e951ab2c3a 100644
--- a/app/workers/pages_worker.rb
+++ b/app/workers/pages_worker.rb
@@ -8,7 +8,6 @@ class PagesWorker # rubocop:disable Scalability/IdempotentWorker
sidekiq_options retry: 3
feature_category :pages
loggable_arguments 0, 1
- tags :requires_disk_io, :exclude_from_kubernetes
worker_resource_boundary :cpu
def perform(action, *arg)
diff --git a/app/workers/personal_access_tokens/expired_notification_worker.rb b/app/workers/personal_access_tokens/expired_notification_worker.rb
index 8deacf457b2..2d0ea3d3aa4 100644
--- a/app/workers/personal_access_tokens/expired_notification_worker.rb
+++ b/app/workers/personal_access_tokens/expired_notification_worker.rb
@@ -9,7 +9,6 @@ module PersonalAccessTokens
include CronjobQueue
feature_category :authentication_and_authorization
- tags :exclude_from_kubernetes
def perform(*args)
notification_service = NotificationService.new
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index 4a49e18eb9b..7d0322361b8 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -1,8 +1,10 @@
# frozen_string_literal: true
-class PostReceive # rubocop:disable Scalability/IdempotentWorker
+class PostReceive
include ApplicationWorker
+ idempotent!
+ deduplicate :none
data_consistency :always
sidekiq_options retry: 3
diff --git a/app/workers/project_destroy_worker.rb b/app/workers/project_destroy_worker.rb
index 149f8290b54..45d0ebd2b65 100644
--- a/app/workers/project_destroy_worker.rb
+++ b/app/workers/project_destroy_worker.rb
@@ -9,7 +9,6 @@ class ProjectDestroyWorker # rubocop:disable Scalability/IdempotentWorker
include ExceptionBacktrace
feature_category :source_code_management
- tags :requires_disk_io, :exclude_from_kubernetes
def perform(project_id, user_id, params)
project = Project.find(project_id)
diff --git a/app/workers/projects/git_garbage_collect_worker.rb b/app/workers/projects/git_garbage_collect_worker.rb
index 0d67a8ac30e..cf236f8b660 100644
--- a/app/workers/projects/git_garbage_collect_worker.rb
+++ b/app/workers/projects/git_garbage_collect_worker.rb
@@ -5,8 +5,6 @@ module Projects
extend ::Gitlab::Utils::Override
include GitGarbageCollectMethods
- tags :exclude_from_kubernetes
-
private
override :find_resource
diff --git a/app/workers/projects/post_creation_worker.rb b/app/workers/projects/post_creation_worker.rb
index 99438e4e4b2..3a39bd17ce3 100644
--- a/app/workers/projects/post_creation_worker.rb
+++ b/app/workers/projects/post_creation_worker.rb
@@ -9,7 +9,6 @@ module Projects
sidekiq_options retry: 3
feature_category :source_code_management
- tags :exclude_from_kubernetes
idempotent!
def perform(project_id)
diff --git a/app/workers/propagate_integration_group_worker.rb b/app/workers/propagate_integration_group_worker.rb
index 443ff1f2abe..ed08e90f38d 100644
--- a/app/workers/propagate_integration_group_worker.rb
+++ b/app/workers/propagate_integration_group_worker.rb
@@ -6,7 +6,6 @@ class PropagateIntegrationGroupWorker
data_consistency :always
sidekiq_options retry: 3
feature_category :integrations
- tags :exclude_from_kubernetes
urgency :low
idempotent!
diff --git a/app/workers/propagate_integration_inherit_descendant_worker.rb b/app/workers/propagate_integration_inherit_descendant_worker.rb
index 24573591409..8b3ecc1f057 100644
--- a/app/workers/propagate_integration_inherit_descendant_worker.rb
+++ b/app/workers/propagate_integration_inherit_descendant_worker.rb
@@ -6,7 +6,6 @@ class PropagateIntegrationInheritDescendantWorker
data_consistency :always
sidekiq_options retry: 3
feature_category :integrations
- tags :exclude_from_kubernetes
urgency :low
idempotent!
diff --git a/app/workers/propagate_integration_inherit_worker.rb b/app/workers/propagate_integration_inherit_worker.rb
index 24a8778b928..f0a53f8cb07 100644
--- a/app/workers/propagate_integration_inherit_worker.rb
+++ b/app/workers/propagate_integration_inherit_worker.rb
@@ -6,7 +6,6 @@ class PropagateIntegrationInheritWorker
data_consistency :always
sidekiq_options retry: 3
feature_category :integrations
- tags :exclude_from_kubernetes
urgency :low
idempotent!
diff --git a/app/workers/propagate_integration_project_worker.rb b/app/workers/propagate_integration_project_worker.rb
index dba8a270007..bc55b7ff504 100644
--- a/app/workers/propagate_integration_project_worker.rb
+++ b/app/workers/propagate_integration_project_worker.rb
@@ -6,7 +6,6 @@ class PropagateIntegrationProjectWorker
data_consistency :always
sidekiq_options retry: 3
feature_category :integrations
- tags :exclude_from_kubernetes
urgency :low
idempotent!
diff --git a/app/workers/purge_dependency_proxy_cache_worker.rb b/app/workers/purge_dependency_proxy_cache_worker.rb
index 8ab4e77bc78..db43e4adf20 100644
--- a/app/workers/purge_dependency_proxy_cache_worker.rb
+++ b/app/workers/purge_dependency_proxy_cache_worker.rb
@@ -27,6 +27,6 @@ class PurgeDependencyProxyCacheWorker
def valid?
return unless @group
- can?(@current_user, :admin_group, @group) && @group.dependency_proxy_feature_available?
+ can?(@current_user, :admin_group, @group)
end
end
diff --git a/app/workers/releases/create_evidence_worker.rb b/app/workers/releases/create_evidence_worker.rb
index 5aed543500f..628b0e0b806 100644
--- a/app/workers/releases/create_evidence_worker.rb
+++ b/app/workers/releases/create_evidence_worker.rb
@@ -9,7 +9,6 @@ module Releases
sidekiq_options retry: 3
feature_category :release_evidence
- tags :exclude_from_kubernetes
# pipeline_id is optional for backward compatibility with existing jobs
# caller should always try to provide the pipeline and pass nil only
diff --git a/app/workers/releases/manage_evidence_worker.rb b/app/workers/releases/manage_evidence_worker.rb
index f316aa6eefd..94d0342a65a 100644
--- a/app/workers/releases/manage_evidence_worker.rb
+++ b/app/workers/releases/manage_evidence_worker.rb
@@ -9,7 +9,6 @@ module Releases
include CronjobQueue # rubocop:disable Scalability/CronWorkerContext
feature_category :release_evidence
- tags :exclude_from_kubernetes
def perform
releases = Release.without_evidence.released_within_2hrs
diff --git a/app/workers/remove_unaccepted_member_invites_worker.rb b/app/workers/remove_unaccepted_member_invites_worker.rb
index 7833ec30c3c..7fe45b26094 100644
--- a/app/workers/remove_unaccepted_member_invites_worker.rb
+++ b/app/workers/remove_unaccepted_member_invites_worker.rb
@@ -8,7 +8,6 @@ class RemoveUnacceptedMemberInvitesWorker # rubocop:disable Scalability/Idempote
include CronjobQueue # rubocop:disable Scalability/CronWorkerContext
feature_category :authentication_and_authorization
- tags :exclude_from_kubernetes
urgency :low
idempotent!
diff --git a/app/workers/schedule_merge_request_cleanup_refs_worker.rb b/app/workers/schedule_merge_request_cleanup_refs_worker.rb
index 46a6e0ef01f..58cd8f7ade3 100644
--- a/app/workers/schedule_merge_request_cleanup_refs_worker.rb
+++ b/app/workers/schedule_merge_request_cleanup_refs_worker.rb
@@ -8,7 +8,6 @@ class ScheduleMergeRequestCleanupRefsWorker
include CronjobQueue # rubocop:disable Scalability/CronWorkerContext
feature_category :code_review
- tags :exclude_from_kubernetes
idempotent!
def perform
diff --git a/app/workers/service_desk_email_receiver_worker.rb b/app/workers/service_desk_email_receiver_worker.rb
index f546fce3e8a..c8ab8891856 100644
--- a/app/workers/service_desk_email_receiver_worker.rb
+++ b/app/workers/service_desk_email_receiver_worker.rb
@@ -6,9 +6,10 @@ class ServiceDeskEmailReceiverWorker < EmailReceiverWorker # rubocop:disable Sca
data_consistency :always
feature_category :service_desk
+ urgency :high
sidekiq_options retry: 3
- # https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1087#jobs-written-to-redis-without-passing-through-the-application
+ # https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1263
tags :needs_own_queue
def should_perform?
diff --git a/app/workers/ssh_keys/expired_notification_worker.rb b/app/workers/ssh_keys/expired_notification_worker.rb
index 6afeecdd1b5..d8553b5a9a2 100644
--- a/app/workers/ssh_keys/expired_notification_worker.rb
+++ b/app/workers/ssh_keys/expired_notification_worker.rb
@@ -9,7 +9,6 @@ module SshKeys
include CronjobQueue
feature_category :compliance_management
- tags :exclude_from_kubernetes
idempotent!
BATCH_SIZE = 500
diff --git a/app/workers/ssh_keys/expiring_soon_notification_worker.rb b/app/workers/ssh_keys/expiring_soon_notification_worker.rb
index ef256621e07..a89520867ed 100644
--- a/app/workers/ssh_keys/expiring_soon_notification_worker.rb
+++ b/app/workers/ssh_keys/expiring_soon_notification_worker.rb
@@ -9,7 +9,6 @@ module SshKeys
include CronjobQueue
feature_category :compliance_management
- tags :exclude_from_kubernetes
idempotent!
def perform
diff --git a/app/workers/stuck_ci_jobs_worker.rb b/app/workers/stuck_ci_jobs_worker.rb
index 5723380a3f3..a2b2686c8d5 100644
--- a/app/workers/stuck_ci_jobs_worker.rb
+++ b/app/workers/stuck_ci_jobs_worker.rb
@@ -3,59 +3,29 @@
class StuckCiJobsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
- data_consistency :always
-
+ # rubocop:disable Scalability/CronWorkerContext
+ # This is an instance-wide cleanup query, so there's no meaningful
+ # scope to consider this in the context of.
include CronjobQueue
+ # rubocop:enable Scalability/CronWorkerContext
+
+ data_consistency :always
feature_category :continuous_integration
worker_resource_boundary :cpu
EXCLUSIVE_LEASE_KEY = 'stuck_ci_builds_worker_lease'
- BUILD_RUNNING_OUTDATED_TIMEOUT = 1.hour
- BUILD_PENDING_OUTDATED_TIMEOUT = 1.day
- BUILD_SCHEDULED_OUTDATED_TIMEOUT = 1.hour
- BUILD_PENDING_STUCK_TIMEOUT = 1.hour
- BUILD_LOOKBACK = 5.days
-
def perform
return unless try_obtain_lease
- Gitlab::AppLogger.info "#{self.class}: Cleaning stuck builds"
-
- drop(running_timed_out_builds, failure_reason: :stuck_or_timeout_failure)
-
- drop(
- Ci::Build.pending.updated_before(lookback: BUILD_LOOKBACK.ago, timeout: BUILD_PENDING_OUTDATED_TIMEOUT.ago),
- failure_reason: :stuck_or_timeout_failure
- )
-
- drop(scheduled_timed_out_builds, failure_reason: :stale_schedule)
-
- drop_stuck(
- Ci::Build.pending.updated_before(lookback: BUILD_LOOKBACK.ago, timeout: BUILD_PENDING_STUCK_TIMEOUT.ago),
- failure_reason: :stuck_or_timeout_failure
- )
+ Ci::StuckBuilds::DropService.new.execute
remove_lease
end
private
- def scheduled_timed_out_builds
- Ci::Build.where(status: :scheduled).where( # rubocop: disable CodeReuse/ActiveRecord
- 'ci_builds.scheduled_at IS NOT NULL AND ci_builds.scheduled_at < ?',
- BUILD_SCHEDULED_OUTDATED_TIMEOUT.ago
- )
- end
-
- def running_timed_out_builds
- Ci::Build.running.where( # rubocop: disable CodeReuse/ActiveRecord
- 'ci_builds.updated_at < ?',
- BUILD_RUNNING_OUTDATED_TIMEOUT.ago
- )
- end
-
def try_obtain_lease
@uuid = Gitlab::ExclusiveLease.new(EXCLUSIVE_LEASE_KEY, timeout: 30.minutes).try_obtain
end
@@ -63,55 +33,4 @@ class StuckCiJobsWorker # rubocop:disable Scalability/IdempotentWorker
def remove_lease
Gitlab::ExclusiveLease.cancel(EXCLUSIVE_LEASE_KEY, @uuid)
end
-
- def drop(builds, failure_reason:)
- fetch(builds) do |build|
- drop_build :outdated, build, failure_reason
- end
- end
-
- def drop_stuck(builds, failure_reason:)
- fetch(builds) do |build|
- break unless build.stuck?
-
- drop_build :stuck, build, failure_reason
- end
- end
-
- # rubocop: disable CodeReuse/ActiveRecord
- def fetch(builds)
- loop do
- jobs = builds.includes(:tags, :runner, project: [:namespace, :route])
- .limit(100)
- .to_a
-
- break if jobs.empty?
-
- jobs.each do |job|
- with_context(project: job.project) { yield(job) }
- end
- end
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
- def drop_build(type, build, reason)
- Gitlab::AppLogger.info "#{self.class}: Dropping #{type} build #{build.id} for runner #{build.runner_id} (status: #{build.status}, failure_reason: #{reason})"
- Gitlab::OptimisticLocking.retry_lock(build, 3, name: 'stuck_ci_jobs_worker_drop_build') do |b|
- b.drop(reason)
- end
- rescue StandardError => ex
- build.doom!
-
- track_exception_for_build(ex, build)
- end
-
- def track_exception_for_build(ex, build)
- Gitlab::ErrorTracking.track_exception(ex,
- build_id: build.id,
- build_name: build.name,
- build_stage: build.stage,
- pipeline_id: build.pipeline_id,
- project_id: build.project_id
- )
- end
end
diff --git a/app/workers/todos_destroyer/destroyed_designs_worker.rb b/app/workers/todos_destroyer/destroyed_designs_worker.rb
new file mode 100644
index 00000000000..e01c1a109d7
--- /dev/null
+++ b/app/workers/todos_destroyer/destroyed_designs_worker.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module TodosDestroyer
+ class DestroyedDesignsWorker
+ include ApplicationWorker
+
+ data_consistency :always
+
+ sidekiq_options retry: 3
+ include TodosDestroyerQueue
+
+ idempotent!
+
+ def perform(design_ids)
+ ::Todos::Destroy::DesignService.new(design_ids).execute
+ end
+ end
+end
diff --git a/app/workers/todos_destroyer/destroyed_issuable_worker.rb b/app/workers/todos_destroyer/destroyed_issuable_worker.rb
index ff4f5e15472..f93c1389534 100644
--- a/app/workers/todos_destroyer/destroyed_issuable_worker.rb
+++ b/app/workers/todos_destroyer/destroyed_issuable_worker.rb
@@ -9,8 +9,6 @@ module TodosDestroyer
sidekiq_options retry: 3
include TodosDestroyerQueue
- tags :exclude_from_kubernetes
-
idempotent!
def perform(target_id, target_type)
diff --git a/app/workers/user_status_cleanup/batch_worker.rb b/app/workers/user_status_cleanup/batch_worker.rb
index b6ca6548572..f3d73b2e6e9 100644
--- a/app/workers/user_status_cleanup/batch_worker.rb
+++ b/app/workers/user_status_cleanup/batch_worker.rb
@@ -12,7 +12,6 @@ module UserStatusCleanup
# rubocop:enable Scalability/CronWorkerContext
feature_category :users
- tags :exclude_from_kubernetes
idempotent!
diff --git a/app/workers/users/deactivate_dormant_users_worker.rb b/app/workers/users/deactivate_dormant_users_worker.rb
index bcb13483379..d7ea20e4b62 100644
--- a/app/workers/users/deactivate_dormant_users_worker.rb
+++ b/app/workers/users/deactivate_dormant_users_worker.rb
@@ -9,7 +9,6 @@ module Users
include CronjobQueue
feature_category :utilization
- tags :exclude_from_kubernetes
NUMBER_OF_BATCHES = 50
BATCH_SIZE = 200
diff --git a/app/workers/web_hooks/destroy_worker.rb b/app/workers/web_hooks/destroy_worker.rb
index b92fe86bafb..f457cd11e54 100644
--- a/app/workers/web_hooks/destroy_worker.rb
+++ b/app/workers/web_hooks/destroy_worker.rb
@@ -7,7 +7,6 @@ module WebHooks
data_consistency :always
sidekiq_options retry: 3
feature_category :integrations
- tags :exclude_from_kubernetes
urgency :low
idempotent!
diff --git a/app/workers/web_hooks/log_execution_worker.rb b/app/workers/web_hooks/log_execution_worker.rb
index 50d91182c80..280d987fa77 100644
--- a/app/workers/web_hooks/log_execution_worker.rb
+++ b/app/workers/web_hooks/log_execution_worker.rb
@@ -7,6 +7,8 @@ module WebHooks
data_consistency :always
feature_category :integrations
urgency :low
+ sidekiq_options retry: 3
+ loggable_arguments 0, 2, 3
idempotent!
diff --git a/app/workers/wikis/git_garbage_collect_worker.rb b/app/workers/wikis/git_garbage_collect_worker.rb
index f34d3be51d2..1b455c50618 100644
--- a/app/workers/wikis/git_garbage_collect_worker.rb
+++ b/app/workers/wikis/git_garbage_collect_worker.rb
@@ -5,8 +5,6 @@ module Wikis
extend ::Gitlab::Utils::Override
include GitGarbageCollectMethods
- tags :exclude_from_kubernetes
-
private
override :find_resource
diff --git a/babel.config.js b/babel.config.js
index d10de05258b..39bb7858087 100644
--- a/babel.config.js
+++ b/babel.config.js
@@ -31,7 +31,7 @@ if (BABEL_ENV === 'coverage') {
plugins.push([
'babel-plugin-istanbul',
{
- exclude: ['spec/javascripts/**/*', 'app/assets/javascripts/locale/**/app.js'],
+ exclude: ['app/assets/javascripts/locale/**/app.js'],
},
]);
}
diff --git a/bin/background_jobs b/bin/background_jobs
index cbc501094c4..6aebc8126c6 100755
--- a/bin/background_jobs
+++ b/bin/background_jobs
@@ -1,9 +1,80 @@
#!/usr/bin/env bash
-cd $(dirname $0)/.. || exit 1
+cd $(dirname $0)/..
+app_root=$(pwd)
+sidekiq_workers=${SIDEKIQ_WORKERS:-1}
+sidekiq_pidfile="$app_root/tmp/pids/sidekiq-cluster.pid"
+sidekiq_logfile="$app_root/log/sidekiq.log"
+gitlab_user=$(ls -l config.ru | awk '{print $3}')
-if [ -n "$SIDEKIQ_WORKERS" ] ; then
- exec bin/background_jobs_sk_cluster "$@"
-else
- exec bin/background_jobs_sk "$@"
-fi
+warn()
+{
+ echo "$@" 1>&2
+}
+
+get_sidekiq_pid()
+{
+ if [ ! -f $sidekiq_pidfile ]; then
+ warn "No pidfile found at $sidekiq_pidfile; is Sidekiq running?"
+ return
+ fi
+
+ cat $sidekiq_pidfile
+}
+
+stop()
+{
+ sidekiq_pid=$(get_sidekiq_pid)
+
+ if [ $sidekiq_pid ]; then
+ kill -TERM $sidekiq_pid
+ fi
+}
+
+restart()
+{
+ if [ -f $sidekiq_pidfile ]; then
+ stop
+ fi
+
+ warn "Sidekiq output will be written to $sidekiq_logfile"
+ start_sidekiq "$@" >> $sidekiq_logfile 2>&1
+}
+
+start_sidekiq()
+{
+ cmd="exec"
+ chpst=$(command -v chpst)
+
+ if [ -n "$chpst" ]; then
+ cmd="${cmd} ${chpst} -P"
+ fi
+
+ # sidekiq-cluster expects '*' '*' arguments (one wildcard for each process).
+ for (( i=1; i<=$sidekiq_workers; i++ ))
+ do
+ processes_args+=("*")
+ done
+
+ ${cmd} bin/sidekiq-cluster "${processes_args[@]}" -P $sidekiq_pidfile -e $RAILS_ENV "$@"
+}
+
+action="$1"
+shift
+
+case "$action" in
+ stop)
+ stop
+ ;;
+ start)
+ restart "$@" &
+ ;;
+ start_foreground)
+ start_sidekiq "$@"
+ ;;
+ restart)
+ restart "$@" &
+ ;;
+ *)
+ echo "Usage: RAILS_ENV=<env> SIDEKIQ_WORKERS=<n> $0 {stop|start|start_foreground|restart}"
+esac
diff --git a/bin/background_jobs_sk b/bin/background_jobs_sk
deleted file mode 100755
index 0e9a5365d44..00000000000
--- a/bin/background_jobs_sk
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/bin/env bash
-
-cd $(dirname $0)/..
-app_root=$(pwd)
-sidekiq_pidfile="$app_root/tmp/pids/sidekiq.pid"
-sidekiq_logfile="$app_root/log/sidekiq.log"
-sidekiq_config="$app_root/config/sidekiq_queues.yml"
-gitlab_user=$(ls -l config.ru | awk '{print $3}')
-
-warn()
-{
- echo "$@" 1>&2
-}
-
-stop()
-{
- bundle exec sidekiqctl stop $sidekiq_pidfile >> $sidekiq_logfile 2>&1
-}
-
-restart()
-{
- if [ -f $sidekiq_pidfile ]; then
- stop
- fi
-
- pkill -u $gitlab_user -f 'sidekiq [0-9]'
- start_sidekiq -P $sidekiq_pidfile -d -L $sidekiq_logfile "$@" >> $sidekiq_logfile 2>&1
-}
-
-# Starts on foreground but output to the logfile instead stdout.
-start_silent()
-{
- start_sidekiq "$@" >> $sidekiq_logfile 2>&1
-}
-
-start_sidekiq()
-{
- cmd="exec"
- chpst=$(command -v chpst)
-
- if [ -n "$chpst" ]; then
- cmd="${cmd} ${chpst} -P"
- fi
-
- ${cmd} bundle exec sidekiq -C "${sidekiq_config}" -e $RAILS_ENV "$@"
-}
-
-case "$1" in
- stop)
- stop
- ;;
- start)
- restart "$@"
- ;;
- start_silent)
- warn "Deprecated: Will be removed at 13.0 (see https://gitlab.com/gitlab-org/gitlab/-/issues/196731)."
- start_silent
- ;;
- start_foreground)
- start_sidekiq "$@"
- ;;
- restart)
- restart "$@"
- ;;
- *)
- echo "Usage: RAILS_ENV=<env> $0 {stop|start|start_silent|start_foreground|restart}"
-esac
diff --git a/bin/background_jobs_sk_cluster b/bin/background_jobs_sk_cluster
deleted file mode 100755
index d48b5484fce..00000000000
--- a/bin/background_jobs_sk_cluster
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/usr/bin/env bash
-
-cd $(dirname $0)/..
-app_root=$(pwd)
-sidekiq_pidfile="$app_root/tmp/pids/sidekiq-cluster.pid"
-sidekiq_logfile="$app_root/log/sidekiq.log"
-gitlab_user=$(ls -l config.ru | awk '{print $3}')
-
-warn()
-{
- echo "$@" 1>&2
-}
-
-get_sidekiq_pid()
-{
- if [ ! -f $sidekiq_pidfile ]; then
- warn "No pidfile found at $sidekiq_pidfile; is Sidekiq running?"
- return
- fi
-
- cat $sidekiq_pidfile
-}
-
-stop()
-{
- sidekiq_pid=$(get_sidekiq_pid)
-
- if [ $sidekiq_pid ]; then
- kill -TERM $sidekiq_pid
- fi
-}
-
-restart()
-{
- if [ -f $sidekiq_pidfile ]; then
- stop
- fi
-
- warn "Sidekiq output will be written to $sidekiq_logfile"
- start_sidekiq "$@" >> $sidekiq_logfile 2>&1
-}
-
-start_sidekiq()
-{
- cmd="exec"
- chpst=$(command -v chpst)
-
- if [ -n "$chpst" ]; then
- cmd="${cmd} ${chpst} -P"
- fi
-
- # sidekiq-cluster expects '*' '*' arguments (one wildcard for each process).
- for (( i=1; i<=$SIDEKIQ_WORKERS; i++ ))
- do
- processes_args+=("*")
- done
-
- ${cmd} bin/sidekiq-cluster "${processes_args[@]}" -P $sidekiq_pidfile -e $RAILS_ENV "$@"
-}
-
-case "$1" in
- stop)
- stop
- ;;
- start)
- restart "$@" &
- ;;
- start_foreground)
- start_sidekiq "$@"
- ;;
- restart)
- restart "$@" &
- ;;
- *)
- echo "Usage: RAILS_ENV=<env> SIDEKIQ_WORKERS=<n> $0 {stop|start|start_foreground|restart}"
-esac
diff --git a/bin/bundle b/bin/bundle
index f19acf5b5cc..b70fcaf837b 100755
--- a/bin/bundle
+++ b/bin/bundle
@@ -1,3 +1,5 @@
#!/usr/bin/env ruby
-ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
+
+require_relative '../config/bundler_setup'
+
load Gem.bin_path('bundler', 'bundle')
diff --git a/bin/pngquant b/bin/pngquant
new file mode 100755
index 00000000000..8434e9d3ec9
--- /dev/null
+++ b/bin/pngquant
@@ -0,0 +1,64 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+require 'rails'
+require 'png_quantizator'
+require 'parallel'
+require 'rainbow/ext/string'
+require_relative '../tooling/lib/tooling/images'
+
+return if Rails.env.production?
+
+def usage
+ puts <<~EOF
+ Usage: #{$0} [compress|lint] [PATH..]
+
+ compress Compress all documentation PNG images using pngquant.
+ lint Checks that all documentation PNG images have been compressed with pngquant.
+
+ PATH One or more files or directories. If empty, `doc/**/*.png` is used.
+
+ EOF
+end
+
+command = ARGV.shift
+paths = ARGV.presence || ['doc']
+
+files = paths.flat_map do |path|
+ File.directory?(path) ? Dir.glob(File.join(path, '/**/*.png')) : path
+end
+
+case command
+when 'compress'
+ puts "Compressing #{files.size} PNG files"
+
+ Parallel.each(files) do |file|
+ was_uncompressed, savings = Tooling::Image.compress_image(file)
+
+ if was_uncompressed
+ puts "#{file} was reduced by #{savings} bytes"
+ end
+ end
+when 'lint'
+ puts "Checking #{files.size} PNG files"
+
+ uncompressed_files = Parallel.map(files) do |file|
+ is_uncompressed, _ = Tooling::Image.compress_image(file, true)
+ if is_uncompressed
+ puts "Uncompressed file detected: ".color(:red) + file
+ file
+ end
+ end.compact
+
+ if uncompressed_files.empty?
+ puts "All documentation images are optimally compressed!".color(:green)
+ else
+ warn(
+ "The #{uncompressed_files.size} image(s) above have not been optimally compressed using pngquant.".color(:red),
+ 'Please run "bin/pngquant compress" and commit the result.'
+ )
+ abort
+ end
+else
+ usage
+end
diff --git a/bin/rspec b/bin/rspec
index 4236753c9c1..5aebc7336fe 100755
--- a/bin/rspec
+++ b/bin/rspec
@@ -5,5 +5,5 @@ begin
rescue LoadError => e
raise unless e.message.include?('spring')
end
-require 'bundler/setup'
+require_relative '../config/bundler_setup'
load Gem.bin_path('rspec-core', 'rspec')
diff --git a/bin/rspec-stackprof b/bin/rspec-stackprof
index 3bef45c607c..018bfe7da4b 100755
--- a/bin/rspec-stackprof
+++ b/bin/rspec-stackprof
@@ -1,6 +1,6 @@
#!/usr/bin/env ruby
-require 'bundler/setup'
+require_relative '../config/bundler_setup'
require 'stackprof'
$:.unshift 'spec'
require 'spec_helper'
diff --git a/changelogs/README.md b/changelogs/README.md
index 3dad62474a2..1d1a19a0341 100644
--- a/changelogs/README.md
+++ b/changelogs/README.md
@@ -1,13 +1,11 @@
# Generating changelog entries
-To generate and validate your changelog entries:
+From GitLab 14.0.0 onwards, [CHANGELOG.md](../CHANGELOG.md) is generated
+by parsing [Git trailers](https://git-scm.com/docs/git-interpret-trailers)
+in commit messages.
-1. Run `bin/changelog` to generate.
-1. Run `yamllint changelogs` to validate.
-
-See [development/changelog] documentation for detailed usage.
-
-[development/changelog]: https://docs.gitlab.com/ee/development/changelog.html
+See [documentation](https://docs.gitlab.com/ee/development/changelog.html#how-to-generate-a-changelog-entry)
+on how to generate changelog entries.
# Changelog archival
diff --git a/config/application.rb b/config/application.rb
index 06a5a726d92..2349de4892f 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -31,9 +31,18 @@ module Gitlab
require_dependency Rails.root.join('lib/gitlab/middleware/handle_malformed_strings')
require_dependency Rails.root.join('lib/gitlab/middleware/rack_multipart_tempfile_factory')
require_dependency Rails.root.join('lib/gitlab/runtime')
+ require_dependency Rails.root.join('lib/gitlab/patch/legacy_database_config')
config.autoloader = :zeitwerk
+ # To be removed in 15.0
+ # This preload is needed to convert legacy `database.yml`
+ # from `production: adapter: postgresql`
+ # into a `production: main: adapter: postgresql`
+ unless Gitlab::Utils.to_boolean(ENV['SKIP_DATABASE_CONFIG_VALIDATION'], default: false)
+ config.class.prepend(::Gitlab::Patch::LegacyDatabaseConfig)
+ end
+
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
diff --git a/config/boot.rb b/config/boot.rb
index 41bf7953737..afa3c04c3c7 100644
--- a/config/boot.rb
+++ b/config/boot.rb
@@ -1,7 +1,4 @@
# frozen_string_literal: true
-ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
-
-# Set up gems listed in the Gemfile.
-require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
+require_relative 'bundler_setup'
require 'bootsnap/setup' if ENV['RAILS_ENV'] != 'production' || %w(1 yes true).include?(ENV['ENABLE_BOOTSNAP'])
diff --git a/config/bundler_setup.rb b/config/bundler_setup.rb
new file mode 100644
index 00000000000..7cb80836f88
--- /dev/null
+++ b/config/bundler_setup.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+# Instead of requiring 'bundle/setup' directly, we need the following
+# to make bundler more consistent when it comes to loading from
+# bundler config. See the following links for more context:
+# https://gitlab.com/gitlab-org/gitlab/-/issues/339939
+# https://github.com/rubygems/rubygems/pull/4892
+# https://github.com/rubygems/rubygems/issues/3363
+require 'bundler'
+ENV['BUNDLE_GEMFILE'] ||= Bundler.settings[:gemfile] || File.expand_path('../Gemfile', __dir__)
+Bundler::SharedHelpers.set_env('BUNDLE_GEMFILE', ENV['BUNDLE_GEMFILE'])
+
+if Bundler.respond_to?(:reset_settings_and_root!)
+ Bundler.reset_settings_and_root!
+else
+ # Bundler 2.1.4 does not have this method. Do the same as Bundler 2.2.26
+ # https://github.com/rubygems/rubygems/blob/bundler-v2.2.26/bundler/lib/bundler.rb#L612-L615
+ Bundler.instance_eval do
+ @settings = nil
+ @root = nil
+ end
+end
+
+require 'bundler/setup'
diff --git a/config/database.yml.decomposed-postgresql b/config/database.yml.decomposed-postgresql
new file mode 100644
index 00000000000..729d8447077
--- /dev/null
+++ b/config/database.yml.decomposed-postgresql
@@ -0,0 +1,47 @@
+#
+# Development specific
+#
+development:
+ main:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_development
+ username: postgres
+ password: "secure password"
+ host: localhost
+ variables:
+ statement_timeout: 15s
+ ci:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_development_ci
+ username: postgres
+ password: "secure password"
+ host: localhost
+ variables:
+ statement_timeout: 15s
+
+# Warning: The database defined as "test" will be erased and
+# re-generated from your development database when you run "rake".
+# Do not set this db to the same as development or production.
+test: &test
+ main:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_test
+ username: postgres
+ password:
+ host: localhost
+ prepared_statements: false
+ variables:
+ statement_timeout: 15s
+ ci:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_test_ci
+ username: postgres
+ password:
+ host: localhost
+ prepared_statements: false
+ variables:
+ statement_timeout: 15s
diff --git a/config/database.yml.postgresql b/config/database.yml.postgresql
index ca1ff4db1b4..a4daab1fd0c 100644
--- a/config/database.yml.postgresql
+++ b/config/database.yml.postgresql
@@ -2,56 +2,60 @@
# PRODUCTION
#
production:
- adapter: postgresql
- encoding: unicode
- database: gitlabhq_production
- username: git
- password: "secure password"
- host: localhost
- # load_balancing:
- # hosts:
- # - host1.example.com
- # - host2.example.com
- # discover:
- # nameserver: 1.2.3.4
- # port: 8600
- # record: secondary.postgresql.service.consul
- # interval: 300
+ main:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_production
+ username: git
+ password: "secure password"
+ host: localhost
+ # load_balancing:
+ # hosts:
+ # - host1.example.com
+ # - host2.example.com
+ # discover:
+ # nameserver: 1.2.3.4
+ # port: 8600
+ # record: secondary.postgresql.service.consul
+ # interval: 300
#
# Development specific
#
development:
- adapter: postgresql
- encoding: unicode
- database: gitlabhq_development
- username: postgres
- password: "secure password"
- host: localhost
- variables:
- statement_timeout: 15s
+ main:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_development
+ username: postgres
+ password: "secure password"
+ host: localhost
+ variables:
+ statement_timeout: 15s
#
# Staging specific
#
staging:
- adapter: postgresql
- encoding: unicode
- database: gitlabhq_staging
- username: git
- password: "secure password"
- host: localhost
+ main:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_staging
+ username: git
+ password: "secure password"
+ host: localhost
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test: &test
- adapter: postgresql
- encoding: unicode
- database: gitlabhq_test
- username: postgres
- password:
- host: localhost
- prepared_statements: false
- variables:
- statement_timeout: 15s
+ main:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_test
+ username: postgres
+ password:
+ host: localhost
+ prepared_statements: false
+ variables:
+ statement_timeout: 15s
diff --git a/config/events/20210915205037_alert_integrations_view_alert_integrations_list.yml b/config/events/20210915205037_alert_integrations_view_alert_integrations_list.yml
new file mode 100644
index 00000000000..505cdf4c288
--- /dev/null
+++ b/config/events/20210915205037_alert_integrations_view_alert_integrations_list.yml
@@ -0,0 +1,21 @@
+description: "Show alert integrations list"
+category: "`Alert Integrations`"
+action: view_alert_integrations_list
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: monitor
+product_group: group::monitor
+product_category:
+milestone: "13.5"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44549
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205038_default_click_button.yml b/config/events/20210915205038_default_click_button.yml
new file mode 100644
index 00000000000..d6fadb735d1
--- /dev/null
+++ b/config/events/20210915205038_default_click_button.yml
@@ -0,0 +1,21 @@
+description: "Click 2FA codes related buttons: copy, download, print..."
+category: default
+action: click_button
+label_description: "Action button name"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: manage
+product_group: group::compliance
+product_category:
+milestone: "13.7"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49510
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205039_default_copy_keyboard_shortcut.yml b/config/events/20210915205039_default_copy_keyboard_shortcut.yml
new file mode 100644
index 00000000000..c1f792de52e
--- /dev/null
+++ b/config/events/20210915205039_default_copy_keyboard_shortcut.yml
@@ -0,0 +1,21 @@
+description: "Copy 2FA codes with keyboard shortcut"
+category: default
+action: copy_keyboard_shortcut
+label_description: "Action button name"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: manage
+product_group: group::compliance
+product_category:
+milestone: "13.7"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49510
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205040_default_generic.yml b/config/events/20210915205040_default_generic.yml
new file mode 100644
index 00000000000..2c8a4d3ef4c
--- /dev/null
+++ b/config/events/20210915205040_default_generic.yml
@@ -0,0 +1,21 @@
+description: "Show a congratulation on first pipeline"
+category: default
+action: generic
+label_description: "`congratulate_first_pipeline`"
+property_description: "`[admin | maintainer | developer | owner]`"
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::expansion
+product_category:
+milestone: "12.10"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28378
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205041_default_generic.yml b/config/events/20210915205041_default_generic.yml
new file mode 100644
index 00000000000..7d4f5efe3ba
--- /dev/null
+++ b/config/events/20210915205041_default_generic.yml
@@ -0,0 +1,21 @@
+description: "Show GitLab CI suggestion popover"
+category: default
+action: generic
+label_description: "`suggest_commit_first_project_gitlab_ci_yml`"
+property_description: "`[admin | maintainer | developer | owner]`"
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::expansion
+product_category:
+milestone: "12.9"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26605
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205050_code_quality_walkthrough_commit_ci_file_dismissed.yml b/config/events/20210915205050_code_quality_walkthrough_commit_ci_file_dismissed.yml
new file mode 100644
index 00000000000..7ce1a3d9b76
--- /dev/null
+++ b/config/events/20210915205050_code_quality_walkthrough_commit_ci_file_dismissed.yml
@@ -0,0 +1,21 @@
+description: "Commit CI file dismissed"
+category: "`code_quality_walkthrough`"
+action: commit_ci_file_dismissed
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::activation
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205051_code_quality_walkthrough_commit_ci_file_displayed.yml b/config/events/20210915205051_code_quality_walkthrough_commit_ci_file_displayed.yml
new file mode 100644
index 00000000000..4fbece2fef8
--- /dev/null
+++ b/config/events/20210915205051_code_quality_walkthrough_commit_ci_file_displayed.yml
@@ -0,0 +1,21 @@
+description: "Commit CI file displayed"
+category: "`code_quality_walkthrough`"
+action: commit_ci_file_displayed
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::activation
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205052_code_quality_walkthrough_commit_created.yml b/config/events/20210915205052_code_quality_walkthrough_commit_created.yml
new file mode 100644
index 00000000000..5e8d8a1250a
--- /dev/null
+++ b/config/events/20210915205052_code_quality_walkthrough_commit_created.yml
@@ -0,0 +1,21 @@
+description: "Commit created"
+category: "`code_quality_walkthrough`"
+action: commit_created
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::activation
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205053_code_quality_walkthrough_cta_clicked.yml b/config/events/20210915205053_code_quality_walkthrough_cta_clicked.yml
new file mode 100644
index 00000000000..684bb681045
--- /dev/null
+++ b/config/events/20210915205053_code_quality_walkthrough_cta_clicked.yml
@@ -0,0 +1,21 @@
+description: "Click empty state CTA"
+category: "`code_quality_walkthrough`"
+action: cta_clicked
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::activation
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205054_code_quality_walkthrough_failed_pipeline_displayed.yml b/config/events/20210915205054_code_quality_walkthrough_failed_pipeline_displayed.yml
new file mode 100644
index 00000000000..517da8eac13
--- /dev/null
+++ b/config/events/20210915205054_code_quality_walkthrough_failed_pipeline_displayed.yml
@@ -0,0 +1,21 @@
+description: "Show failed pipeline"
+category: "`code_quality_walkthrough`"
+action: failed_pipeline_displayed
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::activation
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205055_code_quality_walkthrough_failed_pipeline_view_logs.yml b/config/events/20210915205055_code_quality_walkthrough_failed_pipeline_view_logs.yml
new file mode 100644
index 00000000000..adb4400f288
--- /dev/null
+++ b/config/events/20210915205055_code_quality_walkthrough_failed_pipeline_view_logs.yml
@@ -0,0 +1,21 @@
+description: "Show failed pipeline logs"
+category: "`code_quality_walkthrough`"
+action: failed_pipeline_view_logs
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::activation
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205056_code_quality_walkthrough_running_pipeline_dismissed.yml b/config/events/20210915205056_code_quality_walkthrough_running_pipeline_dismissed.yml
new file mode 100644
index 00000000000..7fcff9644f4
--- /dev/null
+++ b/config/events/20210915205056_code_quality_walkthrough_running_pipeline_dismissed.yml
@@ -0,0 +1,21 @@
+description: "Dismiss running pipeline"
+category: "`code_quality_walkthrough`"
+action: running_pipeline_dismissed
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::activation
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205057_code_quality_walkthrough_running_pipeline_displayed.yml b/config/events/20210915205057_code_quality_walkthrough_running_pipeline_displayed.yml
new file mode 100644
index 00000000000..b7faa132d8b
--- /dev/null
+++ b/config/events/20210915205057_code_quality_walkthrough_running_pipeline_displayed.yml
@@ -0,0 +1,21 @@
+description: "Show running pipeline"
+category: "`code_quality_walkthrough`"
+action: running_pipeline_displayed
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::activation
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205058_code_quality_walkthrough_success_pipeline_displayed.yml b/config/events/20210915205058_code_quality_walkthrough_success_pipeline_displayed.yml
new file mode 100644
index 00000000000..d5909cdab89
--- /dev/null
+++ b/config/events/20210915205058_code_quality_walkthrough_success_pipeline_displayed.yml
@@ -0,0 +1,21 @@
+description: "Show succeeded pipeline"
+category: "`code_quality_walkthrough`"
+action: success_pipeline_displayed
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::activation
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205059_code_quality_walkthrough_success_pipeline_view_logs.yml b/config/events/20210915205059_code_quality_walkthrough_success_pipeline_view_logs.yml
new file mode 100644
index 00000000000..253bf3c3577
--- /dev/null
+++ b/config/events/20210915205059_code_quality_walkthrough_success_pipeline_view_logs.yml
@@ -0,0 +1,21 @@
+description: "Show succeeded pipeline logs"
+category: "`code_quality_walkthrough`"
+action: success_pipeline_view_logs
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::activation
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205100_default_execute_toolbar_control.yml b/config/events/20210915205100_default_execute_toolbar_control.yml
new file mode 100644
index 00000000000..8a9ea7fd068
--- /dev/null
+++ b/config/events/20210915205100_default_execute_toolbar_control.yml
@@ -0,0 +1,21 @@
+description: "Execute toolbar control"
+category: default
+action: execute_toolbar_control
+label_description: "`content_editor`"
+property_description: "Content type"
+value_description: "Context data: [heading] 3, [heading] 2"
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: create
+product_group: group::editor
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61065
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205101_default_execute_keyboard_shortcut.yml b/config/events/20210915205101_default_execute_keyboard_shortcut.yml
new file mode 100644
index 00000000000..2cd59d96ce7
--- /dev/null
+++ b/config/events/20210915205101_default_execute_keyboard_shortcut.yml
@@ -0,0 +1,21 @@
+description: "Execute keyboard shortcut"
+category: default
+action: execute_keyboard_shortcut
+label_description: "`content_editor`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: create
+product_group: group::editor
+product_category:
+milestone: "14.0"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61248
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205102_default_execute_input_rule.yml b/config/events/20210915205102_default_execute_input_rule.yml
new file mode 100644
index 00000000000..4d0e518d07b
--- /dev/null
+++ b/config/events/20210915205102_default_execute_input_rule.yml
@@ -0,0 +1,21 @@
+description: "Execute input rule"
+category: default
+action: execute_input_rule
+label_description: "`content_editor`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: create
+product_group: group::editor
+product_category:
+milestone: "14.0"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61248
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205103_default_execute_bubble_menu_control.yml b/config/events/20210915205103_default_execute_bubble_menu_control.yml
new file mode 100644
index 00000000000..03f4cd7e289
--- /dev/null
+++ b/config/events/20210915205103_default_execute_bubble_menu_control.yml
@@ -0,0 +1,21 @@
+description: "Execute bubble menu control"
+category: default
+action: execute_bubble_menu_control
+label_description: "`content_editor`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: create
+product_group: group::editor
+product_category:
+milestone: "14.2"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67363
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205107_default_click_link.yml b/config/events/20210915205107_default_click_link.yml
new file mode 100644
index 00000000000..cb9d3a3dffa
--- /dev/null
+++ b/config/events/20210915205107_default_click_link.yml
@@ -0,0 +1,21 @@
+description: "Open frequent items dropdown"
+category: default
+action: click_link
+label_description: "`[dropdown_type]_dropdown_frequent_items_list_item`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: create
+product_group: group::editor
+product_category:
+milestone: "13.7"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/47589
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205108_default_type_search_query.yml b/config/events/20210915205108_default_type_search_query.yml
new file mode 100644
index 00000000000..274613bd201
--- /dev/null
+++ b/config/events/20210915205108_default_type_search_query.yml
@@ -0,0 +1,21 @@
+description: "Type search query"
+category: default
+action: type_search_query
+label_description: "`[dropdown_type]_dropdown_frequent_items_search_input`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: create
+product_group: group::editor
+product_category:
+milestone: "13.7"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/47589
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205109_default_invite_members_banner_button_clicked.yml b/config/events/20210915205109_default_invite_members_banner_button_clicked.yml
new file mode 100644
index 00000000000..adbea725085
--- /dev/null
+++ b/config/events/20210915205109_default_invite_members_banner_button_clicked.yml
@@ -0,0 +1,21 @@
+description: "Click invite members banner"
+category: default
+action: invite_members_banner_button_clicked
+label_description: "`invite_members_banner`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::expansion
+product_category:
+milestone: "13.4"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41774
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205110_default_invite_members_banner_dismissed.yml b/config/events/20210915205110_default_invite_members_banner_dismissed.yml
new file mode 100644
index 00000000000..2041df2f058
--- /dev/null
+++ b/config/events/20210915205110_default_invite_members_banner_dismissed.yml
@@ -0,0 +1,21 @@
+description: "Dismiss invite members banner"
+category: default
+action: invite_members_banner_dismissed
+label_description: "`invite_members_banner`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::expansion
+product_category:
+milestone: "13.4"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41774
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205111_default_change_discussion_sort_direction.yml b/config/events/20210915205111_default_change_discussion_sort_direction.yml
new file mode 100644
index 00000000000..cb6e31910d3
--- /dev/null
+++ b/config/events/20210915205111_default_change_discussion_sort_direction.yml
@@ -0,0 +1,21 @@
+description: "Change discussion sort direction"
+category: default
+action: change_discussion_sort_direction
+label_description: ""
+property_description: "`[asc | desc]`"
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: plan
+product_group: group::product_planning
+product_category:
+milestone: "12.10"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28717
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205112_packages_delete_package.yml b/config/events/20210915205112_packages_delete_package.yml
new file mode 100644
index 00000000000..568a800a8e6
--- /dev/null
+++ b/config/events/20210915205112_packages_delete_package.yml
@@ -0,0 +1,21 @@
+description: "Delete package"
+category: "`UI:[MavenPackages | NpmPackages | ConanPackages | undefined]`"
+action: delete_package
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: create
+product_group: group::ecosystem
+product_category:
+milestone: "13.4"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41668
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205113_packages_request_delete_package_file.yml b/config/events/20210915205113_packages_request_delete_package_file.yml
new file mode 100644
index 00000000000..6c0def2db07
--- /dev/null
+++ b/config/events/20210915205113_packages_request_delete_package_file.yml
@@ -0,0 +1,21 @@
+description: "Request deletion of items from the package file list"
+category: "`UI:[MavenPackages | NpmPackages | ConanPackages | undefined]`"
+action: request_delete_package_file
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "14.0"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62179
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205114_packages_delete_package_file.yml b/config/events/20210915205114_packages_delete_package_file.yml
new file mode 100644
index 00000000000..97d38b12b26
--- /dev/null
+++ b/config/events/20210915205114_packages_delete_package_file.yml
@@ -0,0 +1,21 @@
+description: "Delete items from the package file list"
+category: "`UI:[MavenPackages | NpmPackages | ConanPackages | undefined]`"
+action: delete_package_file
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "14.0"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62179
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205115_packages_pull_package.yml b/config/events/20210915205115_packages_pull_package.yml
new file mode 100644
index 00000000000..a45ad6cf945
--- /dev/null
+++ b/config/events/20210915205115_packages_pull_package.yml
@@ -0,0 +1,21 @@
+description: "Download package"
+category: "`UI:[MavenPackages | NpmPackages | ConanPackages | undefined]`"
+action: pull_package
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "13.7"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/48451
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205116_packages_cancel_delete_package.yml b/config/events/20210915205116_packages_cancel_delete_package.yml
new file mode 100644
index 00000000000..ca9f90e5df4
--- /dev/null
+++ b/config/events/20210915205116_packages_cancel_delete_package.yml
@@ -0,0 +1,21 @@
+description: "Cancel package deletion"
+category: "`UI:[MavenPackages | NpmPackages | ConanPackages | undefined]`"
+action: cancel_delete_package
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "14.0"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62179
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205117_packages_cancel_delete_package_file.yml b/config/events/20210915205117_packages_cancel_delete_package_file.yml
new file mode 100644
index 00000000000..9985af6bf58
--- /dev/null
+++ b/config/events/20210915205117_packages_cancel_delete_package_file.yml
@@ -0,0 +1,21 @@
+description: "Cancel deletion of items from the package file list"
+category: "`UI:[MavenPackages | NpmPackages | ConanPackages | undefined]`"
+action: cancel_delete_package_file
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "14.0"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62179
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205118_default_copy_composer_registry_include_command.yml b/config/events/20210915205118_default_copy_composer_registry_include_command.yml
new file mode 100644
index 00000000000..31714aacf50
--- /dev/null
+++ b/config/events/20210915205118_default_copy_composer_registry_include_command.yml
@@ -0,0 +1,21 @@
+description: "Copy Composer registry include command"
+category: default
+action: copy_composer_registry_include_command
+label_description: "`code_instruction`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "13.3"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38779
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205119_default_copy_composer_package_include_command.yml b/config/events/20210915205119_default_copy_composer_package_include_command.yml
new file mode 100644
index 00000000000..e2a923c0c3a
--- /dev/null
+++ b/config/events/20210915205119_default_copy_composer_package_include_command.yml
@@ -0,0 +1,21 @@
+description: "Copy Composer package include command"
+category: default
+action: copy_composer_package_include_command
+label_description: "`code_instruction`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "13.3"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38779
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205125_default_copy_gradle_install_command.yml b/config/events/20210915205125_default_copy_gradle_install_command.yml
new file mode 100644
index 00000000000..5b016d38fbd
--- /dev/null
+++ b/config/events/20210915205125_default_copy_gradle_install_command.yml
@@ -0,0 +1,21 @@
+description: "Copy Gradle install command"
+category: default
+action: copy_gradle_install_command
+label_description: "`code_instruction`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "13.10"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55738
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205126_default_copy_gradle_add_to_source_command.yml b/config/events/20210915205126_default_copy_gradle_add_to_source_command.yml
new file mode 100644
index 00000000000..fa7c58eb2ef
--- /dev/null
+++ b/config/events/20210915205126_default_copy_gradle_add_to_source_command.yml
@@ -0,0 +1,21 @@
+description: "Copy Gradle add to source command"
+category: default
+action: copy_gradle_add_to_source_command
+label_description: "`code_instruction`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "13.10"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55738
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205127_default_copy_kotlin_install_command.yml b/config/events/20210915205127_default_copy_kotlin_install_command.yml
new file mode 100644
index 00000000000..187a500ba03
--- /dev/null
+++ b/config/events/20210915205127_default_copy_kotlin_install_command.yml
@@ -0,0 +1,21 @@
+description: "Copy Kotlin install command"
+category: default
+action: copy_kotlin_install_command
+label_description: "`code_instruction`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60097
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205128_default_copy_kotlin_add_to_source_command.yml b/config/events/20210915205128_default_copy_kotlin_add_to_source_command.yml
new file mode 100644
index 00000000000..d848afec43f
--- /dev/null
+++ b/config/events/20210915205128_default_copy_kotlin_add_to_source_command.yml
@@ -0,0 +1,21 @@
+description: "Copy Kotlin add to source command"
+category: default
+action: copy_kotlin_add_to_source_command
+label_description: "`code_instruction`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60097
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205140_default_reset_form.yml b/config/events/20210915205140_default_reset_form.yml
new file mode 100644
index 00000000000..c6a57c45971
--- /dev/null
+++ b/config/events/20210915205140_default_reset_form.yml
@@ -0,0 +1,21 @@
+description: "Reset Docker form"
+category: default
+action: reset_form
+label_description: "`docker_container_retention_and_expiration_policies`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.8"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23844
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205141_default_submit_form.yml b/config/events/20210915205141_default_submit_form.yml
new file mode 100644
index 00000000000..2e822fe5242
--- /dev/null
+++ b/config/events/20210915205141_default_submit_form.yml
@@ -0,0 +1,21 @@
+description: "Submit Docker form"
+category: default
+action: submit_form
+label_description: "`docker_container_retention_and_expiration_policies`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.8"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23844
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205142_default_click_dismiss.yml b/config/events/20210915205142_default_click_dismiss.yml
new file mode 100644
index 00000000000..73605ad7878
--- /dev/null
+++ b/config/events/20210915205142_default_click_dismiss.yml
@@ -0,0 +1,21 @@
+description: "Dismiss home page banner"
+category: default
+action: click_dismiss
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::expansion
+product_category:
+milestone: "13.4"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39752
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205143_default_show_home_page_banner.yml b/config/events/20210915205143_default_show_home_page_banner.yml
new file mode 100644
index 00000000000..b33e51205a3
--- /dev/null
+++ b/config/events/20210915205143_default_show_home_page_banner.yml
@@ -0,0 +1,21 @@
+description: "Show home page banner"
+category: default
+action: show_home_page_banner
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::expansion
+product_category:
+milestone: "13.4"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39752
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205145_default_content_editor_loaded.yml b/config/events/20210915205145_default_content_editor_loaded.yml
new file mode 100644
index 00000000000..fd223e5368d
--- /dev/null
+++ b/config/events/20210915205145_default_content_editor_loaded.yml
@@ -0,0 +1,21 @@
+description: "Wiki content editor loaded"
+category: default
+action: content_editor_loaded
+label_description: "`wiki_content_editor`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: create
+product_group: group::editor
+product_category:
+milestone: "14.0"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62919
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205146_default_saved_using_content_editor.yml b/config/events/20210915205146_default_saved_using_content_editor.yml
new file mode 100644
index 00000000000..805ed60a992
--- /dev/null
+++ b/config/events/20210915205146_default_saved_using_content_editor.yml
@@ -0,0 +1,21 @@
+description: "Wiki saved using content editor"
+category: default
+action: saved_using_content_editor
+label_description: "`wiki_content_editor`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: create
+product_group: group::editor
+product_category:
+milestone: "14.0"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62919
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205147_default_browse_templates.yml b/config/events/20210915205147_default_browse_templates.yml
new file mode 100644
index 00000000000..e7ae4423bc1
--- /dev/null
+++ b/config/events/20210915205147_default_browse_templates.yml
@@ -0,0 +1,21 @@
+description: "Browse Pipeline editor templates"
+category: default
+action: browse_templates
+label_description: "`pipeline_editor`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: verify
+product_group: group::pipeline_authoring
+product_category:
+milestone: "14.1"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64349
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205148_default_template_clicked.yml b/config/events/20210915205148_default_template_clicked.yml
new file mode 100644
index 00000000000..277190af855
--- /dev/null
+++ b/config/events/20210915205148_default_template_clicked.yml
@@ -0,0 +1,21 @@
+description: "Click pipeline empty state template"
+category: default
+action: template_clicked
+label_description: "Template name or \"Getting-Started\""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::activation
+product_category:
+milestone: "13.11"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58808
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205149_default_dismiss_banner.yml b/config/events/20210915205149_default_dismiss_banner.yml
new file mode 100644
index 00000000000..7eb23fca354
--- /dev/null
+++ b/config/events/20210915205149_default_dismiss_banner.yml
@@ -0,0 +1,21 @@
+description: "Dismiss Terraform banner"
+category: default
+action: dismiss_banner
+label_description: "`terraform_banner`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: configure
+product_group: group::configure
+product_category:
+milestone: "14.3"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68467
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205150_default_click_button.yml b/config/events/20210915205150_default_click_button.yml
new file mode 100644
index 00000000000..356117f6cb6
--- /dev/null
+++ b/config/events/20210915205150_default_click_button.yml
@@ -0,0 +1,21 @@
+description: "Click Terraform banner button"
+category: default
+action: click_button
+label_description: "`terraform_banner`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: configure
+product_group: group::configure
+product_category:
+milestone: "14.3"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68467
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205151_default_click_dropdown.yml b/config/events/20210915205151_default_click_dropdown.yml
new file mode 100644
index 00000000000..61c04baab8d
--- /dev/null
+++ b/config/events/20210915205151_default_click_dropdown.yml
@@ -0,0 +1,21 @@
+description: "Click quickstart dropdown"
+category: default
+action: click_dropdown
+label_description: "`quickstart_dropdown`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.10"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27990
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205152_default_click_copy_login.yml b/config/events/20210915205152_default_click_copy_login.yml
new file mode 100644
index 00000000000..05283da858d
--- /dev/null
+++ b/config/events/20210915205152_default_click_copy_login.yml
@@ -0,0 +1,21 @@
+description: "Copy quickstart dropdown login"
+category: default
+action: click_copy_login
+label_description: "`quickstart_dropdown`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.10"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27990
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205153_default_click_copy_build.yml b/config/events/20210915205153_default_click_copy_build.yml
new file mode 100644
index 00000000000..86ee97b4b3a
--- /dev/null
+++ b/config/events/20210915205153_default_click_copy_build.yml
@@ -0,0 +1,21 @@
+description: "Copy quickstart dropdown build"
+category: default
+action: click_copy_build
+label_description: "`quickstart_dropdown`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.10"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27990
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205154_default_click_copy_push.yml b/config/events/20210915205154_default_click_copy_push.yml
new file mode 100644
index 00000000000..87de403e7de
--- /dev/null
+++ b/config/events/20210915205154_default_click_copy_push.yml
@@ -0,0 +1,21 @@
+description: "Copy quickstart dropdown push"
+category: default
+action: click_copy_push
+label_description: "`quickstart_dropdown`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.10"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27990
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205155_default_click_button.yml b/config/events/20210915205155_default_click_button.yml
new file mode 100644
index 00000000000..42fa0c97066
--- /dev/null
+++ b/config/events/20210915205155_default_click_button.yml
@@ -0,0 +1,21 @@
+description: "Click registry tag delete button"
+category: default
+action: click_button
+label_description: "`[bulk_registry_tag_delete | registry_tag_delete]`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.8"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23154
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205156_default_confirm_delete.yml b/config/events/20210915205156_default_confirm_delete.yml
new file mode 100644
index 00000000000..cc9481592ae
--- /dev/null
+++ b/config/events/20210915205156_default_confirm_delete.yml
@@ -0,0 +1,21 @@
+description: "Confirm registry tag deletion"
+category: default
+action: confirm_delete
+label_description: "`[bulk_registry_tag_delete | registry_tag_delete]`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.8"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23154
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205157_default_cancel_delete.yml b/config/events/20210915205157_default_cancel_delete.yml
new file mode 100644
index 00000000000..425fe8089d3
--- /dev/null
+++ b/config/events/20210915205157_default_cancel_delete.yml
@@ -0,0 +1,21 @@
+description: "Cancel registry tag deletion"
+category: default
+action: cancel_delete
+label_description: "`[bulk_registry_tag_delete | registry_tag_delete]`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.8"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23154
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205158_default_click_button.yml b/config/events/20210915205158_default_click_button.yml
new file mode 100644
index 00000000000..56329982262
--- /dev/null
+++ b/config/events/20210915205158_default_click_button.yml
@@ -0,0 +1,21 @@
+description: "Click registry repository delete button"
+category: default
+action: click_button
+label_description: "`registry_repository_delete`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.8"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23154
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205159_default_confirm_delete.yml b/config/events/20210915205159_default_confirm_delete.yml
new file mode 100644
index 00000000000..1939df91927
--- /dev/null
+++ b/config/events/20210915205159_default_confirm_delete.yml
@@ -0,0 +1,21 @@
+description: "Confirm registry repository deletion"
+category: default
+action: confirm_delete
+label_description: "`registry_repository_delete`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.8"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23154
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205200_default_cancel_delete.yml b/config/events/20210915205200_default_cancel_delete.yml
new file mode 100644
index 00000000000..99623717a84
--- /dev/null
+++ b/config/events/20210915205200_default_cancel_delete.yml
@@ -0,0 +1,21 @@
+description: "Cancel registry repository deletion"
+category: default
+action: cancel_delete
+label_description: "`registry_repository_delete`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.8"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23154
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205202_default_generic.yml b/config/events/20210915205202_default_generic.yml
new file mode 100644
index 00000000000..3e6169f1c68
--- /dev/null
+++ b/config/events/20210915205202_default_generic.yml
@@ -0,0 +1,21 @@
+description: "Show Pipeline suggestion on new MRs"
+category: default
+action: generic
+label_description: "`no_pipeline_noticed`"
+property_description: "`[admin | maintainer | developer | owner]`"
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::expansion
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35069
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205203_default_click_tab.yml b/config/events/20210915205203_default_click_tab.yml
new file mode 100644
index 00000000000..e61ce545f7b
--- /dev/null
+++ b/config/events/20210915205203_default_click_tab.yml
@@ -0,0 +1,21 @@
+description: "Click tab on new namespace welcoming component"
+category: default
+action: click_tab
+label_description: "Panel name"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: manage
+product_group: group::import
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59452
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205204_default_click_whats_new_drawer.yml b/config/events/20210915205204_default_click_whats_new_drawer.yml
new file mode 100644
index 00000000000..8a994510fc7
--- /dev/null
+++ b/config/events/20210915205204_default_click_whats_new_drawer.yml
@@ -0,0 +1,21 @@
+description: "Show \"What's new\" drawer"
+category: default
+action: click_whats_new_drawer
+label_description: "`namespace_id`"
+property_description: "ID of namespace"
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::adoption
+product_category:
+milestone: "13.5"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/42653
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205207_default_click_dropdown.yml b/config/events/20210915205207_default_click_dropdown.yml
new file mode 100644
index 00000000000..d4d63e1bd2b
--- /dev/null
+++ b/config/events/20210915205207_default_click_dropdown.yml
@@ -0,0 +1,21 @@
+description: "Click Epic's board switcher"
+category: default
+action: click_dropdown
+label_description: "`board_switcher`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: plan
+product_group: group::product_planning
+product_category:
+milestone: "14.0"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63765
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/feature_categories.yml b/config/feature_categories.yml
index 01446f931cf..1ecf217dd92 100644
--- a/config/feature_categories.yml
+++ b/config/feature_categories.yml
@@ -20,7 +20,6 @@
- chatops
- cloud_native_installation
- cluster_cost_management
-- code_analytics
- code_quality
- code_review
- code_testing
@@ -34,6 +33,7 @@
- continuous_integration_scaling
- database
- dataops
+- delivery_management
- dependency_firewall
- dependency_proxy
- dependency_scanning
@@ -42,6 +42,7 @@
- disaster_recovery
- dynamic_application_security_testing
- editor_extension
+- environment_management
- epics
- error_tracking
- experimentation_activation
diff --git a/config/feature_flags/development/add_namespace_and_project_to_snowplow_tracking.yml b/config/feature_flags/development/add_namespace_and_project_to_snowplow_tracking.yml
new file mode 100644
index 00000000000..ebffae2a446
--- /dev/null
+++ b/config/feature_flags/development/add_namespace_and_project_to_snowplow_tracking.yml
@@ -0,0 +1,8 @@
+---
+name: add_namespace_and_project_to_snowplow_tracking
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68277
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338670
+milestone: '14.3'
+type: development
+group: group::product intelligence
+default_enabled: false
diff --git a/config/feature_flags/development/additional_snowplow_tracking.yml b/config/feature_flags/development/additional_snowplow_tracking.yml
index c5726975b37..0d021a2f8b0 100644
--- a/config/feature_flags/development/additional_snowplow_tracking.yml
+++ b/config/feature_flags/development/additional_snowplow_tracking.yml
@@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/12088
rollout_issue_url:
milestone: '11.11'
type: development
-group: group::product analytics
+group: group::product intelligence
default_enabled: false
diff --git a/config/feature_flags/development/between_uses_list_commits.yml b/config/feature_flags/development/between_uses_list_commits.yml
deleted file mode 100644
index 84b34e1f8b2..00000000000
--- a/config/feature_flags/development/between_uses_list_commits.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: between_uses_list_commits
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67591
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337960
-milestone: '14.2'
-type: development
-group: group::source code
-default_enabled: false
diff --git a/config/feature_flags/development/board_new_list.yml b/config/feature_flags/development/board_new_list.yml
deleted file mode 100644
index 7d755dd6689..00000000000
--- a/config/feature_flags/development/board_new_list.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: board_new_list
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52061
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/299366
-milestone: '13.8'
-type: development
-group: group::project management
-default_enabled: true
diff --git a/config/feature_flags/development/bulk_import.yml b/config/feature_flags/development/bulk_import.yml
index 10885093adf..5a654b3f6d9 100644
--- a/config/feature_flags/development/bulk_import.yml
+++ b/config/feature_flags/development/bulk_import.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/255310
milestone: '13.5'
type: development
group: group::import
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/bulk_import_projects.yml b/config/feature_flags/development/bulk_import_projects.yml
new file mode 100644
index 00000000000..853389577cf
--- /dev/null
+++ b/config/feature_flags/development/bulk_import_projects.yml
@@ -0,0 +1,8 @@
+---
+name: bulk_import_projects
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68873
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339941
+milestone: '14.3'
+type: development
+group: group::import
+default_enabled: false
diff --git a/config/feature_flags/development/cache_merge_to_ref_calls.yml b/config/feature_flags/development/cache_merge_to_ref_calls.yml
deleted file mode 100644
index 495ed9236d3..00000000000
--- a/config/feature_flags/development/cache_merge_to_ref_calls.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: cache_merge_to_ref_calls
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67789
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338251
-milestone: '14.2'
-type: development
-group: group::code review
-default_enabled: false
diff --git a/config/feature_flags/development/cached_encoding_detection.yml b/config/feature_flags/development/cached_encoding_detection.yml
deleted file mode 100644
index 362c465cfb6..00000000000
--- a/config/feature_flags/development/cached_encoding_detection.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: cached_encoding_detection
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60128
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/328819
-milestone: '13.12'
-type: development
-group: group::source code
-default_enabled: false
diff --git a/config/feature_flags/development/cached_issues_state_count.yml b/config/feature_flags/development/cached_issues_state_count.yml
new file mode 100644
index 00000000000..34d96b601d9
--- /dev/null
+++ b/config/feature_flags/development/cached_issues_state_count.yml
@@ -0,0 +1,8 @@
+---
+name: cached_issues_state_count
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67418
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/333089
+milestone: '14.3'
+type: development
+group: group::product planning
+default_enabled: false
diff --git a/config/feature_flags/development/changes_batch_commits.yml b/config/feature_flags/development/changes_batch_commits.yml
deleted file mode 100644
index 2b276759fb1..00000000000
--- a/config/feature_flags/development/changes_batch_commits.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: changes_batch_commits
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66731
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/336992
-milestone: '14.2'
-type: development
-group: group::gitaly
-default_enabled: false
diff --git a/config/feature_flags/development/ci_build_tags_limit.yml b/config/feature_flags/development/ci_build_tags_limit.yml
new file mode 100644
index 00000000000..8aaa03a87e3
--- /dev/null
+++ b/config/feature_flags/development/ci_build_tags_limit.yml
@@ -0,0 +1,8 @@
+---
+name: ci_build_tags_limit
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68380
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338929
+milestone: '14.2'
+type: development
+group: group::pipeline execution
+default_enabled: true
diff --git a/config/feature_flags/development/ci_create_external_pr_pipeline_async.yml b/config/feature_flags/development/ci_create_external_pr_pipeline_async.yml
new file mode 100644
index 00000000000..3935a818b1f
--- /dev/null
+++ b/config/feature_flags/development/ci_create_external_pr_pipeline_async.yml
@@ -0,0 +1,8 @@
+---
+name: ci_create_external_pr_pipeline_async
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68567
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338908
+milestone: '14.3'
+type: development
+group: group::pipeline authoring
+default_enabled: false
diff --git a/config/feature_flags/development/ci_daily_limit_for_pipeline_schedules.yml b/config/feature_flags/development/ci_daily_limit_for_pipeline_schedules.yml
deleted file mode 100644
index 6b398663a6a..00000000000
--- a/config/feature_flags/development/ci_daily_limit_for_pipeline_schedules.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: ci_daily_limit_for_pipeline_schedules
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62826
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/332333
-milestone: '14.0'
-type: development
-group: group::pipeline authoring
-default_enabled: true
diff --git a/config/feature_flags/development/ci_fix_commit_status_retried.yml b/config/feature_flags/development/ci_fix_commit_status_retried.yml
deleted file mode 100644
index 56400c861cd..00000000000
--- a/config/feature_flags/development/ci_fix_commit_status_retried.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: ci_fix_commit_status_retried
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54300
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/321631
-milestone: '13.9'
-type: development
-group: group::pipeline authoring
-default_enabled: true
diff --git a/config/feature_flags/development/ci_idempotent_pipeline_process_worker.yml b/config/feature_flags/development/ci_idempotent_pipeline_process_worker.yml
index db6aa3e88ff..60104bd3109 100644
--- a/config/feature_flags/development/ci_idempotent_pipeline_process_worker.yml
+++ b/config/feature_flags/development/ci_idempotent_pipeline_process_worker.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/332963
milestone: '14.0'
type: development
group: group::pipeline authoring
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/ci_include_rules.yml b/config/feature_flags/development/ci_include_rules.yml
index a53f818b4f4..d8a3f0b245e 100644
--- a/config/feature_flags/development/ci_include_rules.yml
+++ b/config/feature_flags/development/ci_include_rules.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337507
milestone: '14.2'
type: development
group: group::pipeline authoring
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/ci_job_trace_force_encode.yml b/config/feature_flags/development/ci_job_trace_force_encode.yml
deleted file mode 100644
index c69dc3437b1..00000000000
--- a/config/feature_flags/development/ci_job_trace_force_encode.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: ci_job_trace_force_encode
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64631
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/333452
-milestone: '14.1'
-type: development
-group: group::verify
-default_enabled: true
diff --git a/config/feature_flags/development/ci_modified_paths_of_external_prs.yml b/config/feature_flags/development/ci_modified_paths_of_external_prs.yml
deleted file mode 100644
index 62f7eb4663f..00000000000
--- a/config/feature_flags/development/ci_modified_paths_of_external_prs.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: ci_modified_paths_of_external_prs
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60736
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/330605
-milestone: '13.12'
-type: development
-group: group::pipeline authoring
-default_enabled: true
diff --git a/config/feature_flags/development/ci_new_artifact_file_reader.yml b/config/feature_flags/development/ci_new_artifact_file_reader.yml
index ccd36558b1d..d475f3f370d 100644
--- a/config/feature_flags/development/ci_new_artifact_file_reader.yml
+++ b/config/feature_flags/development/ci_new_artifact_file_reader.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/273755
milestone: '13.6'
type: development
group: group::pipeline authoring
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/ci_new_query_for_pending_stuck_jobs.yml b/config/feature_flags/development/ci_new_query_for_pending_stuck_jobs.yml
new file mode 100644
index 00000000000..5e63330d01d
--- /dev/null
+++ b/config/feature_flags/development/ci_new_query_for_pending_stuck_jobs.yml
@@ -0,0 +1,8 @@
+---
+name: ci_new_query_for_pending_stuck_jobs
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68880
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339322
+milestone: '14.3'
+type: development
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/feature_flags/development/ci_pending_builds_maintain_namespace_traversal_ids.yml b/config/feature_flags/development/ci_pending_builds_maintain_namespace_traversal_ids.yml
new file mode 100644
index 00000000000..0eafb604fed
--- /dev/null
+++ b/config/feature_flags/development/ci_pending_builds_maintain_namespace_traversal_ids.yml
@@ -0,0 +1,8 @@
+---
+name: ci_pending_builds_maintain_namespace_traversal_ids
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70162
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340930
+milestone: '14.3'
+type: development
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/feature_flags/development/ci_pending_builds_maintain_tags_data.yml b/config/feature_flags/development/ci_pending_builds_maintain_tags_data.yml
new file mode 100644
index 00000000000..bd18789bbcf
--- /dev/null
+++ b/config/feature_flags/development/ci_pending_builds_maintain_tags_data.yml
@@ -0,0 +1,8 @@
+---
+name: ci_pending_builds_maintain_tags_data
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65648
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338363
+milestone: '14.2'
+type: development
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/feature_flags/development/ci_pending_builds_project_runners_decoupling.yml b/config/feature_flags/development/ci_pending_builds_project_runners_decoupling.yml
new file mode 100644
index 00000000000..82acc907507
--- /dev/null
+++ b/config/feature_flags/development/ci_pending_builds_project_runners_decoupling.yml
@@ -0,0 +1,8 @@
+---
+name: ci_pending_builds_project_runners_decoupling
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70415
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/341005
+milestone: '14.4'
+type: development
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/feature_flags/development/ci_pipeline_add_job_with_lock.yml b/config/feature_flags/development/ci_pipeline_add_job_with_lock.yml
index 48aa64ba7f4..6a708013ca5 100644
--- a/config/feature_flags/development/ci_pipeline_add_job_with_lock.yml
+++ b/config/feature_flags/development/ci_pipeline_add_job_with_lock.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337628
milestone: '14.2'
type: development
group: group::pipeline authoring
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/ci_queueing_builds_enabled_checks.yml b/config/feature_flags/development/ci_queueing_builds_enabled_checks.yml
new file mode 100644
index 00000000000..effaf78cef2
--- /dev/null
+++ b/config/feature_flags/development/ci_queueing_builds_enabled_checks.yml
@@ -0,0 +1,8 @@
+---
+name: ci_queueing_builds_enabled_checks
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70581
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/341131
+milestone: '14.4'
+type: development
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/feature_flags/development/ci_queueing_denormalize_namespace_traversal_ids.yml b/config/feature_flags/development/ci_queueing_denormalize_namespace_traversal_ids.yml
new file mode 100644
index 00000000000..e8326ac5cab
--- /dev/null
+++ b/config/feature_flags/development/ci_queueing_denormalize_namespace_traversal_ids.yml
@@ -0,0 +1,8 @@
+---
+name: ci_queueing_denormalize_namespace_traversal_ids
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70162
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340930
+milestone: '14.3'
+type: development
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/feature_flags/development/ci_queueing_denormalize_tags_information.yml b/config/feature_flags/development/ci_queueing_denormalize_tags_information.yml
new file mode 100644
index 00000000000..23f7be4cccc
--- /dev/null
+++ b/config/feature_flags/development/ci_queueing_denormalize_tags_information.yml
@@ -0,0 +1,8 @@
+---
+name: ci_queueing_denormalize_tags_information
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65648
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338366
+milestone: '14.1'
+type: development
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/feature_flags/development/ci_remove_update_retried_from_process_pipeline.yml b/config/feature_flags/development/ci_remove_update_retried_from_process_pipeline.yml
index 82470baf6b4..932ee766340 100644
--- a/config/feature_flags/development/ci_remove_update_retried_from_process_pipeline.yml
+++ b/config/feature_flags/development/ci_remove_update_retried_from_process_pipeline.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/321630
milestone: '13.9'
type: development
group: group::pipeline authoring
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/ci_reset_bridge_with_subsequent_jobs.yml b/config/feature_flags/development/ci_reset_bridge_with_subsequent_jobs.yml
deleted file mode 100644
index 098b3cae2be..00000000000
--- a/config/feature_flags/development/ci_reset_bridge_with_subsequent_jobs.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: ci_reset_bridge_with_subsequent_jobs
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60376
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/329194
-milestone: '13.12'
-type: development
-group: group::pipeline authoring
-default_enabled: true
diff --git a/config/feature_flags/development/ci_same_stage_job_needs.yml b/config/feature_flags/development/ci_same_stage_job_needs.yml
deleted file mode 100644
index dfb54edf030..00000000000
--- a/config/feature_flags/development/ci_same_stage_job_needs.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: ci_same_stage_job_needs
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59668
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/328253
-milestone: '14.1'
-type: development
-group: group::pipeline authoring
-default_enabled: true
diff --git a/config/feature_flags/development/ci_yaml_limit_size.yml b/config/feature_flags/development/ci_yaml_limit_size.yml
index 41f3742a377..2b68939968d 100644
--- a/config/feature_flags/development/ci_yaml_limit_size.yml
+++ b/config/feature_flags/development/ci_yaml_limit_size.yml
@@ -1,7 +1,7 @@
---
name: ci_yaml_limit_size
introduced_by_url: https://dev.gitlab.org/gitlab/gitlabhq/-/merge_requests/3126
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab-foss/-/issues/56018
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/29875
milestone: '12.0'
type: development
group: group::pipeline execution
diff --git a/config/feature_flags/development/content_editor_block_tables.yml b/config/feature_flags/development/content_editor_block_tables.yml
new file mode 100644
index 00000000000..176422bbc92
--- /dev/null
+++ b/config/feature_flags/development/content_editor_block_tables.yml
@@ -0,0 +1,8 @@
+---
+name: content_editor_block_tables
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66187
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338937
+milestone: '14.3'
+type: development
+group: group::editor
+default_enabled: false
diff --git a/config/feature_flags/development/create_vulnerabilities_via_api.yml b/config/feature_flags/development/create_vulnerabilities_via_api.yml
new file mode 100644
index 00000000000..0a3f9fa73f8
--- /dev/null
+++ b/config/feature_flags/development/create_vulnerabilities_via_api.yml
@@ -0,0 +1,8 @@
+---
+name: create_vulnerabilities_via_api
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68158
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338694
+milestone: '14.3'
+type: development
+group: group::threat insights
+default_enabled: false
diff --git a/config/feature_flags/development/customer_relations.yml b/config/feature_flags/development/customer_relations.yml
new file mode 100644
index 00000000000..207f675423a
--- /dev/null
+++ b/config/feature_flags/development/customer_relations.yml
@@ -0,0 +1,8 @@
+---
+name: customer_relations
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69472
+rollout_issue_url:
+milestone: '14.3'
+type: development
+group: group::product planning
+default_enabled: false
diff --git a/config/feature_flags/development/dast_meta_tag_validation.yml b/config/feature_flags/development/dast_meta_tag_validation.yml
deleted file mode 100644
index 50ef18df45a..00000000000
--- a/config/feature_flags/development/dast_meta_tag_validation.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: dast_meta_tag_validation
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67945
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337711
-milestone: '14.2'
-type: development
-group: group::dynamic analysis
-default_enabled: true
diff --git a/config/feature_flags/development/dast_profile_disable_joins.yml b/config/feature_flags/development/dast_profile_disable_joins.yml
deleted file mode 100644
index 469e930dd7c..00000000000
--- a/config/feature_flags/development/dast_profile_disable_joins.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: dast_profile_disable_joins
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66709
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/336944
-milestone: '14.2'
-type: development
-group: group::dynamic analysis
-default_enabled: true
diff --git a/config/feature_flags/development/dast_runner_site_validation.yml b/config/feature_flags/development/dast_runner_site_validation.yml
deleted file mode 100644
index e39a8a6d1e3..00000000000
--- a/config/feature_flags/development/dast_runner_site_validation.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: dast_runner_site_validation
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61649
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/331082
-milestone: '14.0'
-type: development
-group: group::dynamic analysis
-default_enabled: true
diff --git a/config/feature_flags/development/dast_scanner_profile_disable_joins.yml b/config/feature_flags/development/dast_scanner_profile_disable_joins.yml
deleted file mode 100644
index 8c27633b785..00000000000
--- a/config/feature_flags/development/dast_scanner_profile_disable_joins.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: dast_scanner_profile_disable_joins
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66709
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/336946
-milestone: '14.2'
-type: development
-group: group::dynamic analysis
-default_enabled: true
diff --git a/config/feature_flags/development/dast_site_profile_disable_joins.yml b/config/feature_flags/development/dast_site_profile_disable_joins.yml
deleted file mode 100644
index 08327a4abf1..00000000000
--- a/config/feature_flags/development/dast_site_profile_disable_joins.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: dast_site_profile_disable_joins
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66709
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/336945
-milestone: '14.2'
-type: development
-group: group::dynamic analysis
-default_enabled: true
diff --git a/config/feature_flags/development/dast_view_scans.yml b/config/feature_flags/development/dast_view_scans.yml
new file mode 100644
index 00000000000..39c14097b60
--- /dev/null
+++ b/config/feature_flags/development/dast_view_scans.yml
@@ -0,0 +1,8 @@
+---
+name: dast_view_scans
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69571
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340388
+milestone: '14.3'
+type: development
+group: group::dynamic analysis
+default_enabled: false
diff --git a/config/feature_flags/development/delete_branch_confirmation_modals.yml b/config/feature_flags/development/delete_branch_confirmation_modals.yml
index 37fcf533966..9959d8fe8e2 100644
--- a/config/feature_flags/development/delete_branch_confirmation_modals.yml
+++ b/config/feature_flags/development/delete_branch_confirmation_modals.yml
@@ -2,7 +2,7 @@
name: delete_branch_confirmation_modals
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56782
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/329052
-milestone: '13.12'
+milestone: '14.3'
type: development
group: group::expansion
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/diffs_batch_render_cached.yml b/config/feature_flags/development/diffs_batch_render_cached.yml
deleted file mode 100644
index ee2deaa4072..00000000000
--- a/config/feature_flags/development/diffs_batch_render_cached.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: diffs_batch_render_cached
-introduced_by_url: https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/1509
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/334762
-milestone: '14.1'
-type: development
-group: group::code review
-default_enabled: false
diff --git a/config/feature_flags/development/ensure_verified_primary_email_for_2fa.yml b/config/feature_flags/development/ensure_verified_primary_email_for_2fa.yml
new file mode 100644
index 00000000000..7a52486d356
--- /dev/null
+++ b/config/feature_flags/development/ensure_verified_primary_email_for_2fa.yml
@@ -0,0 +1,8 @@
+---
+name: ensure_verified_primary_email_for_2fa
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69593
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340151
+milestone: '14.3'
+type: development
+group: group::access
+default_enabled: true
diff --git a/config/feature_flags/development/environment_last_visible_pipeline_disable_joins.yml b/config/feature_flags/development/environment_last_visible_pipeline_disable_joins.yml
new file mode 100644
index 00000000000..7667542506a
--- /dev/null
+++ b/config/feature_flags/development/environment_last_visible_pipeline_disable_joins.yml
@@ -0,0 +1,8 @@
+---
+name: environment_last_visible_pipeline_disable_joins
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68870
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340283
+milestone: '14.3'
+type: development
+group: group::release
+default_enabled: true
diff --git a/config/feature_flags/development/files_api_throttling.yml b/config/feature_flags/development/files_api_throttling.yml
new file mode 100644
index 00000000000..a106c2cb980
--- /dev/null
+++ b/config/feature_flags/development/files_api_throttling.yml
@@ -0,0 +1,8 @@
+---
+name: files_api_throttling
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68560
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338903
+milestone: '14.3'
+type: development
+group: group::source code
+default_enabled: false
diff --git a/config/feature_flags/development/find_tag_via_gitaly.yml b/config/feature_flags/development/find_tag_via_gitaly.yml
new file mode 100644
index 00000000000..217eac464ad
--- /dev/null
+++ b/config/feature_flags/development/find_tag_via_gitaly.yml
@@ -0,0 +1,8 @@
+---
+name: find_tag_via_gitaly
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70181
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340899
+milestone: '14.3'
+type: development
+group: group::source code
+default_enabled: false
diff --git a/config/feature_flags/development/generate_iids_without_explicit_locking.yml b/config/feature_flags/development/generate_iids_without_explicit_locking.yml
deleted file mode 100644
index d2a7aeb8619..00000000000
--- a/config/feature_flags/development/generate_iids_without_explicit_locking.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: generate_iids_without_explicit_locking
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65590
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/335431
-milestone: '14.2'
-type: development
-group: group::database
-default_enabled: false
diff --git a/config/feature_flags/development/get_tag_signatures.yml b/config/feature_flags/development/get_tag_signatures.yml
deleted file mode 100644
index e0d7d5d6dcf..00000000000
--- a/config/feature_flags/development/get_tag_signatures.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: get_tag_signatures
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67000
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337842
-milestone: '14.2'
-type: development
-group: group::gitaly
-default_enabled: false
diff --git a/config/feature_flags/development/gitaly_pack_objects_hook_with_sidechannel.yml b/config/feature_flags/development/gitaly_pack_objects_hook_with_sidechannel.yml
new file mode 100644
index 00000000000..14cebc656c1
--- /dev/null
+++ b/config/feature_flags/development/gitaly_pack_objects_hook_with_sidechannel.yml
@@ -0,0 +1,8 @@
+---
+name: gitaly_pack_objects_hook_with_sidechannel
+introduced_by_url: https://gitlab.com/gitlab-org/gitaly/-/merge_requests/3758
+rollout_issue_url: https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1187
+milestone: '14.3'
+type: development
+group: 'team::Scalability'
+default_enabled: false
diff --git a/config/feature_flags/development/gitaly_tags_finder.yml b/config/feature_flags/development/gitaly_tags_finder.yml
new file mode 100644
index 00000000000..a0a1791e584
--- /dev/null
+++ b/config/feature_flags/development/gitaly_tags_finder.yml
@@ -0,0 +1,8 @@
+---
+name: gitaly_tags_finder
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69101
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339741
+milestone: '14.3'
+type: development
+group: group::source code
+default_enabled: false
diff --git a/config/feature_flags/development/graphql_board_lists.yml b/config/feature_flags/development/graphql_board_lists.yml
deleted file mode 100644
index 0a7578f4063..00000000000
--- a/config/feature_flags/development/graphql_board_lists.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: graphql_board_lists
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37905
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/248908
-milestone: '13.4'
-type: development
-group: group::project management
-default_enabled: true
diff --git a/config/feature_flags/development/group_authorized_agents.yml b/config/feature_flags/development/group_authorized_agents.yml
new file mode 100644
index 00000000000..e1c4620994d
--- /dev/null
+++ b/config/feature_flags/development/group_authorized_agents.yml
@@ -0,0 +1,8 @@
+---
+name: group_authorized_agents
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69047
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340166
+milestone: '14.3'
+type: development
+group: group::configure
+default_enabled: false
diff --git a/config/feature_flags/development/group_level_protected_environments.yml b/config/feature_flags/development/group_level_protected_environments.yml
deleted file mode 100644
index 598513d4283..00000000000
--- a/config/feature_flags/development/group_level_protected_environments.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: group_level_protected_environments
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61575
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/331085
-milestone: '14.0'
-type: development
-group: group::release
-default_enabled: false
diff --git a/config/feature_flags/development/groups_tokens_optional_encryption.yml b/config/feature_flags/development/groups_tokens_optional_encryption.yml
index 25c172422f6..c34cae689c2 100644
--- a/config/feature_flags/development/groups_tokens_optional_encryption.yml
+++ b/config/feature_flags/development/groups_tokens_optional_encryption.yml
@@ -1,7 +1,7 @@
---
name: groups_tokens_optional_encryption
introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/25532
-rollout_issue_url:
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/333862
milestone: '11.9'
type: development
group: group::runner
diff --git a/config/feature_flags/development/infinitely_collapsible_sections.yml b/config/feature_flags/development/infinitely_collapsible_sections.yml
index 44f37c06d70..d0bf063c6f6 100644
--- a/config/feature_flags/development/infinitely_collapsible_sections.yml
+++ b/config/feature_flags/development/infinitely_collapsible_sections.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/335297
milestone: '14.1'
type: development
group: group::pipeline execution
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/integrated_error_tracking.yml b/config/feature_flags/development/integrated_error_tracking.yml
deleted file mode 100644
index 7fc29492233..00000000000
--- a/config/feature_flags/development/integrated_error_tracking.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: integrated_error_tracking
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65767
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/335846
-milestone: '14.1'
-type: development
-group: group::monitor
-default_enabled: false
diff --git a/config/feature_flags/development/issue_rebalancing_optimization.yml b/config/feature_flags/development/issue_rebalancing_optimization.yml
deleted file mode 100644
index abaeb53f63d..00000000000
--- a/config/feature_flags/development/issue_rebalancing_optimization.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: issue_rebalancing_optimization
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53384
-rollout_issue_url:
-milestone: '13.9'
-type: development
-group: group::project management
-default_enabled: false
diff --git a/config/feature_flags/development/issue_rebalancing_with_retry.yml b/config/feature_flags/development/issue_rebalancing_with_retry.yml
deleted file mode 100644
index c30d919d592..00000000000
--- a/config/feature_flags/development/issue_rebalancing_with_retry.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: issue_rebalancing_with_retry
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59744
-rollout_issue_url:
-milestone: '13.11'
-type: development
-group: group::project management
-default_enabled: false
diff --git a/config/feature_flags/development/keyset_pagination_for_groups_api.yml b/config/feature_flags/development/keyset_pagination_for_groups_api.yml
new file mode 100644
index 00000000000..d4bd37565ee
--- /dev/null
+++ b/config/feature_flags/development/keyset_pagination_for_groups_api.yml
@@ -0,0 +1,8 @@
+---
+name: keyset_pagination_for_groups_api
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68346
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339831
+milestone: '14.3'
+type: development
+group: group::access
+default_enabled: false
diff --git a/config/feature_flags/development/linear_application_settings_elasticsearch_limited_namespaces.yml b/config/feature_flags/development/linear_application_settings_elasticsearch_limited_namespaces.yml
new file mode 100644
index 00000000000..27342e1e1c2
--- /dev/null
+++ b/config/feature_flags/development/linear_application_settings_elasticsearch_limited_namespaces.yml
@@ -0,0 +1,8 @@
+---
+name: linear_application_settings_elasticsearch_limited_namespaces
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68931
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339438
+milestone: '14.3'
+type: development
+group: group::access
+default_enabled: false
diff --git a/config/feature_flags/development/linear_group_including_descendants_by.yml b/config/feature_flags/development/linear_group_including_descendants_by.yml
new file mode 100644
index 00000000000..cf70edce6cc
--- /dev/null
+++ b/config/feature_flags/development/linear_group_including_descendants_by.yml
@@ -0,0 +1,8 @@
+---
+name: linear_group_including_descendants_by
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68835
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339431
+milestone: '14.3'
+type: development
+group: group::access
+default_enabled: false
diff --git a/config/feature_flags/development/linear_groups_template_finder_extended_group_search.yml b/config/feature_flags/development/linear_groups_template_finder_extended_group_search.yml
new file mode 100644
index 00000000000..98505f561b0
--- /dev/null
+++ b/config/feature_flags/development/linear_groups_template_finder_extended_group_search.yml
@@ -0,0 +1,8 @@
+---
+name: linear_groups_template_finder_extended_group_search
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68936
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339439
+milestone: '14.3'
+type: development
+group: group::access
+default_enabled: false
diff --git a/config/feature_flags/development/linear_user_groups_with_developer_maintainer_project_access.yml b/config/feature_flags/development/linear_user_groups_with_developer_maintainer_project_access.yml
new file mode 100644
index 00000000000..09a910ba5f0
--- /dev/null
+++ b/config/feature_flags/development/linear_user_groups_with_developer_maintainer_project_access.yml
@@ -0,0 +1,8 @@
+---
+name: linear_user_groups_with_developer_maintainer_project_access
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68851
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339436
+milestone: '14.3'
+type: development
+group: group::access
+default_enabled: false
diff --git a/config/feature_flags/development/linear_user_manageable_groups.yml b/config/feature_flags/development/linear_user_manageable_groups.yml
new file mode 100644
index 00000000000..e5822fc3d7d
--- /dev/null
+++ b/config/feature_flags/development/linear_user_manageable_groups.yml
@@ -0,0 +1,8 @@
+---
+name: linear_user_manageable_groups
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68845
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339434
+milestone: '14.3'
+type: development
+group: group::access
+default_enabled: false
diff --git a/config/feature_flags/development/linear_user_membership_groups.yml b/config/feature_flags/development/linear_user_membership_groups.yml
new file mode 100644
index 00000000000..19bca849090
--- /dev/null
+++ b/config/feature_flags/development/linear_user_membership_groups.yml
@@ -0,0 +1,8 @@
+---
+name: linear_user_membership_groups
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68842
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339432
+milestone: '14.3'
+type: development
+group: group::access
+default_enabled: false
diff --git a/config/feature_flags/development/load_balancing_for_deployments_hooks_worker.yml b/config/feature_flags/development/load_balancing_for_deployments_hooks_worker.yml
deleted file mode 100644
index fe6dbca3dd4..00000000000
--- a/config/feature_flags/development/load_balancing_for_deployments_hooks_worker.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: load_balancing_for_deployments_hooks_worker
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67878
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338342
-milestone: '14.2'
-type: development
-group: group::release
-default_enabled: false
diff --git a/config/feature_flags/development/local_file_reviews.yml b/config/feature_flags/development/local_file_reviews.yml
deleted file mode 100644
index 4001f6ade72..00000000000
--- a/config/feature_flags/development/local_file_reviews.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: local_file_reviews
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51513
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/296674
-milestone: '13.9'
-type: development
-group: group::code review
-default_enabled: true
diff --git a/config/feature_flags/development/mailgun_events_receiver.yml b/config/feature_flags/development/mailgun_events_receiver.yml
deleted file mode 100644
index 119d8d34f21..00000000000
--- a/config/feature_flags/development/mailgun_events_receiver.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: mailgun_events_receiver
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64249
-rollout_issue_url:
-milestone: '14.1'
-type: development
-group: group::expansion
-default_enabled: false
diff --git a/config/feature_flags/development/merge_request_show_render_cached.yml b/config/feature_flags/development/merge_request_show_render_cached.yml
deleted file mode 100644
index 04a18b2f557..00000000000
--- a/config/feature_flags/development/merge_request_show_render_cached.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: merge_request_show_render_cached
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65217
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/335938
-milestone: '14.2'
-type: development
-group: group::code review
-default_enabled: false
diff --git a/config/feature_flags/development/milestone_reference_pattern.yml b/config/feature_flags/development/milestone_reference_pattern.yml
deleted file mode 100644
index 8ca4ae4c395..00000000000
--- a/config/feature_flags/development/milestone_reference_pattern.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: milestone_reference_pattern
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65847
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/336268
-milestone: '14.1'
-type: development
-group: group::source code
-default_enabled: false
diff --git a/config/feature_flags/development/new_header_search.yml b/config/feature_flags/development/new_header_search.yml
new file mode 100644
index 00000000000..086aee4c4b0
--- /dev/null
+++ b/config/feature_flags/development/new_header_search.yml
@@ -0,0 +1,8 @@
+---
+name: new_header_search
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68681
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339348
+milestone: '14.3'
+type: development
+group: group::global search
+default_enabled: false
diff --git a/config/feature_flags/development/new_route_storage_purchase.yml b/config/feature_flags/development/new_route_storage_purchase.yml
new file mode 100644
index 00000000000..b248a5f7d09
--- /dev/null
+++ b/config/feature_flags/development/new_route_storage_purchase.yml
@@ -0,0 +1,8 @@
+---
+name: new_route_storage_purchase
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68834
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/327896
+milestone: '14.3'
+type: development
+group: group::purchase
+default_enabled: false
diff --git a/config/feature_flags/development/optimize_safe_find_or_create_by.yml b/config/feature_flags/development/optimize_safe_find_or_create_by.yml
deleted file mode 100644
index 6adedb5cece..00000000000
--- a/config/feature_flags/development/optimize_safe_find_or_create_by.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: optimize_safe_find_or_create_by
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68458
-rollout_issue_url:
-milestone: '14.3'
-type: development
-group: group::database
-default_enabled: false
diff --git a/config/feature_flags/development/optimized_issuable_label_filter.yml b/config/feature_flags/development/optimized_issuable_label_filter.yml
deleted file mode 100644
index cc4e8aa2fa9..00000000000
--- a/config/feature_flags/development/optimized_issuable_label_filter.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: optimized_issuable_label_filter
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34503
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/259719
-milestone: '13.4'
-type: development
-group: group::optimize
-default_enabled: true
diff --git a/config/feature_flags/development/other_storage_tab.yml b/config/feature_flags/development/other_storage_tab.yml
deleted file mode 100644
index 8ce4848f98b..00000000000
--- a/config/feature_flags/development/other_storage_tab.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: other_storage_tab
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57121
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/325967
-milestone: '13.11'
-type: development
-group: group::fulfillment
-default_enabled: false
diff --git a/config/feature_flags/development/package_details_apollo.yml b/config/feature_flags/development/package_details_apollo.yml
deleted file mode 100644
index fbab4c2c7c8..00000000000
--- a/config/feature_flags/development/package_details_apollo.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: package_details_apollo
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64939
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/334786
-milestone: '14.1'
-type: development
-group: group::package
-default_enabled: true
diff --git a/config/feature_flags/development/packages_nuget_new_package_file_updater.yml b/config/feature_flags/development/packages_nuget_new_package_file_updater.yml
deleted file mode 100644
index b1f8a79da9a..00000000000
--- a/config/feature_flags/development/packages_nuget_new_package_file_updater.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: packages_nuget_new_package_file_updater
-introduced_by_url:
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/336511
-milestone: '14.2'
-type: development
-group: group::package
-default_enabled: true
diff --git a/config/feature_flags/development/paginatable_namespace_drop_down_for_project_creation.yml b/config/feature_flags/development/paginatable_namespace_drop_down_for_project_creation.yml
new file mode 100644
index 00000000000..297a4f65aa4
--- /dev/null
+++ b/config/feature_flags/development/paginatable_namespace_drop_down_for_project_creation.yml
@@ -0,0 +1,8 @@
+---
+name: paginatable_namespace_drop_down_for_project_creation
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66112
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338930
+milestone: '14.3'
+type: development
+group: group::project management
+default_enabled: false
diff --git a/config/feature_flags/development/permitted_attributes_for_import_export.yml b/config/feature_flags/development/permitted_attributes_for_import_export.yml
new file mode 100644
index 00000000000..da5168b6ab8
--- /dev/null
+++ b/config/feature_flags/development/permitted_attributes_for_import_export.yml
@@ -0,0 +1,8 @@
+---
+name: permitted_attributes_for_import_export
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70168
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340789
+milestone: '14.4'
+type: development
+group: group::import
+default_enabled: true
diff --git a/config/feature_flags/development/pipeline_editor_branch_switcher.yml b/config/feature_flags/development/pipeline_editor_branch_switcher.yml
deleted file mode 100644
index 49cf2a07a2c..00000000000
--- a/config/feature_flags/development/pipeline_editor_branch_switcher.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: pipeline_editor_branch_switcher
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57562
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/326189
-milestone: '13.11'
-type: development
-group: group::pipeline authoring
-default_enabled: true
diff --git a/config/feature_flags/development/pipeline_source_filter.yml b/config/feature_flags/development/pipeline_source_filter.yml
deleted file mode 100644
index be24f6936e4..00000000000
--- a/config/feature_flags/development/pipeline_source_filter.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: pipeline_source_filter
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67846
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338347
-milestone: '14.2'
-type: development
-group: group::pipeline execution
-default_enabled: false
diff --git a/config/feature_flags/development/preserve_latest_wal_locations_for_idempotent_jobs.yml b/config/feature_flags/development/preserve_latest_wal_locations_for_idempotent_jobs.yml
new file mode 100644
index 00000000000..52ef276e950
--- /dev/null
+++ b/config/feature_flags/development/preserve_latest_wal_locations_for_idempotent_jobs.yml
@@ -0,0 +1,8 @@
+---
+name: preserve_latest_wal_locations_for_idempotent_jobs
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66280
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338350
+milestone: '14.3'
+type: development
+group: group::memory
+default_enabled: false
diff --git a/config/feature_flags/development/product_analytics.yml b/config/feature_flags/development/product_analytics.yml
index faed7b5a5d8..4dfe0ce57d8 100644
--- a/config/feature_flags/development/product_analytics.yml
+++ b/config/feature_flags/development/product_analytics.yml
@@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36443
rollout_issue_url:
milestone: '13.2'
type: development
-group: group::product analytics
+group: group::product intelligence
default_enabled: false
diff --git a/config/feature_flags/development/project_storage_ui.yml b/config/feature_flags/development/project_storage_ui.yml
new file mode 100644
index 00000000000..23a5b5c3d29
--- /dev/null
+++ b/config/feature_flags/development/project_storage_ui.yml
@@ -0,0 +1,8 @@
+---
+name: project_storage_ui
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68289
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/334889
+milestone: '14.2'
+type: development
+group: group::utilization
+default_enabled: false
diff --git a/config/feature_flags/development/projects_tokens_optional_encryption.yml b/config/feature_flags/development/projects_tokens_optional_encryption.yml
index c9af986b6b7..6a0fed009ea 100644
--- a/config/feature_flags/development/projects_tokens_optional_encryption.yml
+++ b/config/feature_flags/development/projects_tokens_optional_encryption.yml
@@ -1,7 +1,7 @@
---
name: projects_tokens_optional_encryption
introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/25532
-rollout_issue_url:
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/333864
milestone: '11.9'
type: development
group: group::runner
diff --git a/config/feature_flags/development/query_project_ci_feature_usages_for_coverage.yml b/config/feature_flags/development/query_project_ci_feature_usages_for_coverage.yml
new file mode 100644
index 00000000000..1b720d6276b
--- /dev/null
+++ b/config/feature_flags/development/query_project_ci_feature_usages_for_coverage.yml
@@ -0,0 +1,8 @@
+---
+name: query_project_ci_feature_usages_for_coverage
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69890
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339974
+milestone: '14.3'
+type: development
+group: group::testing
+default_enabled: false
diff --git a/config/feature_flags/development/redirect_to_latest_template_jobs_build.yml b/config/feature_flags/development/redirect_to_latest_template_jobs_build.yml
new file mode 100644
index 00000000000..df03505afc5
--- /dev/null
+++ b/config/feature_flags/development/redirect_to_latest_template_jobs_build.yml
@@ -0,0 +1,8 @@
+---
+name: redirect_to_latest_template_jobs_build
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67782
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337990
+milestone: '14.2'
+type: development
+group: group::configure
+default_enabled: false
diff --git a/config/feature_flags/development/repository_tree_gitaly_pagination.yml b/config/feature_flags/development/repository_tree_gitaly_pagination.yml
new file mode 100644
index 00000000000..afae937b62e
--- /dev/null
+++ b/config/feature_flags/development/repository_tree_gitaly_pagination.yml
@@ -0,0 +1,8 @@
+---
+name: repository_tree_gitaly_pagination
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67509
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340419
+milestone: '14.3'
+type: development
+group: group::source code
+default_enabled: false
diff --git a/config/feature_flags/development/restructured_mr_widget.yml b/config/feature_flags/development/restructured_mr_widget.yml
new file mode 100644
index 00000000000..75914da990f
--- /dev/null
+++ b/config/feature_flags/development/restructured_mr_widget.yml
@@ -0,0 +1,8 @@
+---
+name: restructured_mr_widget
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68565
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339181
+milestone: '14.3'
+type: development
+group: group::code review
+default_enabled: false
diff --git a/config/feature_flags/development/runner_detailed_view_vue_ui.yml b/config/feature_flags/development/runner_detailed_view_vue_ui.yml
deleted file mode 100644
index 78a09910e6c..00000000000
--- a/config/feature_flags/development/runner_detailed_view_vue_ui.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: runner_detailed_view_vue_ui
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57256
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/325737
-milestone: '13.11'
-type: development
-group: group::runner
-default_enabled: true
diff --git a/config/feature_flags/development/runner_graphql_query.yml b/config/feature_flags/development/runner_graphql_query.yml
deleted file mode 100644
index b7af0a2bb22..00000000000
--- a/config/feature_flags/development/runner_graphql_query.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: runner_graphql_query
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59763
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/328700
-type: development
-group: group::runner
-default_enabled: true
-milestone: '13.12'
diff --git a/config/feature_flags/development/security_orchestration_policies_configuration.yml b/config/feature_flags/development/security_orchestration_policies_configuration.yml
index ae64339607e..2570743c101 100644
--- a/config/feature_flags/development/security_orchestration_policies_configuration.yml
+++ b/config/feature_flags/development/security_orchestration_policies_configuration.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/321258
milestone: '13.9'
type: development
group: group::container security
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/set_full_path.yml b/config/feature_flags/development/set_full_path.yml
deleted file mode 100644
index a2f249b60fd..00000000000
--- a/config/feature_flags/development/set_full_path.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: set_full_path
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66929
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337002
-milestone: '14.2'
-type: development
-group: group::gitaly
-default_enabled: false
diff --git a/config/feature_flags/development/skip_pages_deploy_to_legacy_storage.yml b/config/feature_flags/development/skip_pages_deploy_to_legacy_storage.yml
deleted file mode 100644
index a324a6e5ab1..00000000000
--- a/config/feature_flags/development/skip_pages_deploy_to_legacy_storage.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: skip_pages_deploy_to_legacy_storage
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59298
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/327725
-milestone: '13.11'
-type: development
-group: group::release
-default_enabled: false
diff --git a/config/feature_flags/development/sort_by_project_users_by_project_authorizations_user_id.yml b/config/feature_flags/development/sort_by_project_users_by_project_authorizations_user_id.yml
index b88b50c2527..88a4e0b0472 100644
--- a/config/feature_flags/development/sort_by_project_users_by_project_authorizations_user_id.yml
+++ b/config/feature_flags/development/sort_by_project_users_by_project_authorizations_user_id.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/334167
milestone: '14.1'
type: development
group: group::optimize
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/store_mentions_without_subtransaction.yml b/config/feature_flags/development/store_mentions_without_subtransaction.yml
deleted file mode 100644
index a71aa204935..00000000000
--- a/config/feature_flags/development/store_mentions_without_subtransaction.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: store_mentions_without_subtransaction
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68433
-rollout_issue_url:
-milestone: '14.3'
-type: development
-group: group::project management
-default_enabled: false
diff --git a/config/feature_flags/development/track_epic_boards_activity.yml b/config/feature_flags/development/track_epic_boards_activity.yml
index 6461a9e826c..df48cc5a854 100644
--- a/config/feature_flags/development/track_epic_boards_activity.yml
+++ b/config/feature_flags/development/track_epic_boards_activity.yml
@@ -1,7 +1,7 @@
---
name: track_epic_boards_activity
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60357
-rollout_issue_url:
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338038
milestone: '13.12'
type: development
group: group::product planning
diff --git a/config/feature_flags/development/track_unique_visits.yml b/config/feature_flags/development/track_unique_visits.yml
deleted file mode 100644
index dd053211070..00000000000
--- a/config/feature_flags/development/track_unique_visits.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: track_unique_visits
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33146
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/255994
-milestone: '13.2'
-type: development
-group: group::optimize
-default_enabled: true
diff --git a/config/feature_flags/development/usage_data_design_action.yml b/config/feature_flags/development/usage_data_design_action.yml
deleted file mode 100644
index f5fc7f67c6d..00000000000
--- a/config/feature_flags/development/usage_data_design_action.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: usage_data_design_action
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46626
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/287630
-milestone: '13.7'
-type: development
-group: group::product planning
-default_enabled: true
diff --git a/config/feature_flags/development/usage_data_i_testing_load_performance_widget_total.yml b/config/feature_flags/development/usage_data_i_testing_load_performance_widget_total.yml
deleted file mode 100644
index 3ffb9bceb99..00000000000
--- a/config/feature_flags/development/usage_data_i_testing_load_performance_widget_total.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: usage_data_i_testing_load_performance_widget_total
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52688
-rollout_issue_url:
-milestone: '13.9'
-type: development
-group: group::testing
-default_enabled: true
diff --git a/config/feature_flags/development/usage_data_i_testing_metrics_report_widget_total.yml b/config/feature_flags/development/usage_data_i_testing_metrics_report_widget_total.yml
deleted file mode 100644
index 2c086b211ba..00000000000
--- a/config/feature_flags/development/usage_data_i_testing_metrics_report_widget_total.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: usage_data_i_testing_metrics_report_widget_total
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50790
-rollout_issue_url:
-milestone: '13.8'
-type: development
-group: group::testing
-default_enabled: true
diff --git a/config/feature_flags/development/usage_data_i_testing_web_performance_widget_total.yml b/config/feature_flags/development/usage_data_i_testing_web_performance_widget_total.yml
deleted file mode 100644
index 6efb6bea040..00000000000
--- a/config/feature_flags/development/usage_data_i_testing_web_performance_widget_total.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: usage_data_i_testing_web_performance_widget_total
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46746
-rollout_issue_url:
-milestone: '13.8'
-type: development
-group: group::testing
-default_enabled: true
diff --git a/config/feature_flags/development/use_specialized_worker_for_project_auth_recalculation.yml b/config/feature_flags/development/use_specialized_worker_for_project_auth_recalculation.yml
deleted file mode 100644
index 01889de5b0d..00000000000
--- a/config/feature_flags/development/use_specialized_worker_for_project_auth_recalculation.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: use_specialized_worker_for_project_auth_recalculation
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60904
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/331073
-milestone: '14.0'
-type: development
-group: group::access
-default_enabled: false
diff --git a/config/feature_flags/development/use_traversal_ids_for_ancestor_scopes.yml b/config/feature_flags/development/use_traversal_ids_for_ancestor_scopes.yml
new file mode 100644
index 00000000000..7f398fc5f0b
--- /dev/null
+++ b/config/feature_flags/development/use_traversal_ids_for_ancestor_scopes.yml
@@ -0,0 +1,8 @@
+---
+name: use_traversal_ids_for_ancestor_scopes
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67652
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340159
+milestone: '14.3'
+type: development
+group: group::access
+default_enabled: false
diff --git a/config/feature_flags/development/use_upsert_query_for_mr_metrics.yml b/config/feature_flags/development/use_upsert_query_for_mr_metrics.yml
new file mode 100644
index 00000000000..14cc5d1a98c
--- /dev/null
+++ b/config/feature_flags/development/use_upsert_query_for_mr_metrics.yml
@@ -0,0 +1,8 @@
+---
+name: use_upsert_query_for_mr_metrics
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69240
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339677
+milestone: '14.3'
+type: development
+group: group::optimize
+default_enabled: false
diff --git a/config/feature_flags/development/user_refresh_from_replica_worker_uses_replica_db.yml b/config/feature_flags/development/user_refresh_from_replica_worker_uses_replica_db.yml
deleted file mode 100644
index 6e3d8d315cd..00000000000
--- a/config/feature_flags/development/user_refresh_from_replica_worker_uses_replica_db.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: user_refresh_from_replica_worker_uses_replica_db
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64276
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/334766
-milestone: '14.1'
-type: development
-group: group::access
-default_enabled: false
diff --git a/config/feature_flags/development/vuln_report_new_project_filter.yml b/config/feature_flags/development/vuln_report_new_project_filter.yml
index 79c2afaca07..3eb02054205 100644
--- a/config/feature_flags/development/vuln_report_new_project_filter.yml
+++ b/config/feature_flags/development/vuln_report_new_project_filter.yml
@@ -2,7 +2,7 @@
name: vuln_report_new_project_filter
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55745
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/334380
-milestone: '14.2'
+milestone: '14.3'
type: development
group: group::threat insights
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/vulnerability_flags.yml b/config/feature_flags/development/vulnerability_flags.yml
new file mode 100644
index 00000000000..6ea7dd2e3f1
--- /dev/null
+++ b/config/feature_flags/development/vulnerability_flags.yml
@@ -0,0 +1,8 @@
+---
+name: vulnerability_flags
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66775
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340203
+milestone: '14.3'
+type: development
+group: group::static analysis
+default_enabled: true
diff --git a/config/feature_flags/development/work_items.yml b/config/feature_flags/development/work_items.yml
new file mode 100644
index 00000000000..7401c14979a
--- /dev/null
+++ b/config/feature_flags/development/work_items.yml
@@ -0,0 +1,8 @@
+---
+name: work_items
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69085
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339664
+milestone: '14.3'
+type: development
+group: group::project management
+default_enabled: false
diff --git a/config/feature_flags/experiment/combined_registration.yml b/config/feature_flags/experiment/combined_registration.yml
new file mode 100644
index 00000000000..1be740c7141
--- /dev/null
+++ b/config/feature_flags/experiment/combined_registration.yml
@@ -0,0 +1,8 @@
+---
+name: combined_registration
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67614
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/285533
+milestone: '14.3'
+type: experiment
+group: group::adoption
+default_enabled: false
diff --git a/config/feature_flags/experiment/invite_email_from.yml b/config/feature_flags/experiment/invite_email_from.yml
new file mode 100644
index 00000000000..59baf249341
--- /dev/null
+++ b/config/feature_flags/experiment/invite_email_from.yml
@@ -0,0 +1,8 @@
+---
+name: invite_email_from
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68376
+rollout_issue_url: https://gitlab.com/gitlab-org/growth/team-tasks/-/issues/429
+milestone: '14.3'
+type: experiment
+group: group::expansion
+default_enabled: false
diff --git a/config/feature_flags/experiment/learn_gitlab_a_experiment_percentage.yml b/config/feature_flags/experiment/learn_gitlab_a_experiment_percentage.yml
deleted file mode 100644
index 54b7ea465f1..00000000000
--- a/config/feature_flags/experiment/learn_gitlab_a_experiment_percentage.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: learn_gitlab_a_experiment_percentage
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53089
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/281022
-milestone: '13.9'
-type: experiment
-group: group::conversion
-default_enabled: false
diff --git a/config/feature_flags/experiment/learn_gitlab_b_experiment_percentage.yml b/config/feature_flags/experiment/learn_gitlab_b_experiment_percentage.yml
deleted file mode 100644
index cca5d35baf3..00000000000
--- a/config/feature_flags/experiment/learn_gitlab_b_experiment_percentage.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: learn_gitlab_b_experiment_percentage
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53089
-rollout_issue_url: https://gitlab.com/gitlab-org/growth/team-tasks/-/issues/306
-milestone: '13.9'
-type: experiment
-group: group::conversion
-default_enabled: false
diff --git a/config/feature_flags/experiment/repo_integrations_link.yml b/config/feature_flags/experiment/repo_integrations_link.yml
deleted file mode 100644
index 943429a84e7..00000000000
--- a/config/feature_flags/experiment/repo_integrations_link.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: repo_integrations_link
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54652/
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/285154
-milestone: '13.10'
-type: experiment
-group: group::adoption
-default_enabled: false
diff --git a/config/feature_flags/experiment/security_reports_mr_widget_prompt.yml b/config/feature_flags/experiment/security_reports_mr_widget_prompt.yml
new file mode 100644
index 00000000000..ca6d17b1720
--- /dev/null
+++ b/config/feature_flags/experiment/security_reports_mr_widget_prompt.yml
@@ -0,0 +1,8 @@
+---
+name: security_reports_mr_widget_prompt
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70086
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340436
+milestone: '14.3'
+type: experiment
+group: group::adoption
+default_enabled: false
diff --git a/config/feature_flags/ops/active_record_subtransactions_counter.yml b/config/feature_flags/ops/active_record_subtransactions_counter.yml
deleted file mode 100644
index 0d2b1b0c84a..00000000000
--- a/config/feature_flags/ops/active_record_subtransactions_counter.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: active_record_subtransactions_counter
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66477
-rollout_issue_url:
-milestone: '14.1'
-type: ops
-group: group::pipeline execution
-default_enabled: false
diff --git a/config/feature_flags/ops/ci_pipeline_creation_step_duration_tracking.yml b/config/feature_flags/ops/ci_pipeline_creation_step_duration_tracking.yml
new file mode 100644
index 00000000000..4f0ac7b22c3
--- /dev/null
+++ b/config/feature_flags/ops/ci_pipeline_creation_step_duration_tracking.yml
@@ -0,0 +1,8 @@
+---
+name: ci_pipeline_creation_step_duration_tracking
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68485
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339486
+milestone: '14.2'
+type: ops
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/feature_flags/ops/disable_anonymous_project_search.yml b/config/feature_flags/ops/disable_anonymous_project_search.yml
new file mode 100644
index 00000000000..89ef0b0ed25
--- /dev/null
+++ b/config/feature_flags/ops/disable_anonymous_project_search.yml
@@ -0,0 +1,8 @@
+---
+name: disable_anonymous_project_search
+introduced_by_url:
+rollout_issue_url:
+milestone: '14.3'
+type: ops
+group: group::project management
+default_enabled: false
diff --git a/config/feature_flags/ops/disable_anonymous_search.yml b/config/feature_flags/ops/disable_anonymous_search.yml
new file mode 100644
index 00000000000..a49b4c168e1
--- /dev/null
+++ b/config/feature_flags/ops/disable_anonymous_search.yml
@@ -0,0 +1,8 @@
+---
+name: disable_anonymous_search
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70223
+rollout_issue_url:
+milestone: '14.3'
+type: ops
+group: group::project management
+default_enabled: false
diff --git a/config/feature_flags/ops/github_importer_lower_per_page_limit.yml b/config/feature_flags/ops/github_importer_lower_per_page_limit.yml
new file mode 100644
index 00000000000..d3a446dc125
--- /dev/null
+++ b/config/feature_flags/ops/github_importer_lower_per_page_limit.yml
@@ -0,0 +1,8 @@
+---
+name: github_importer_lower_per_page_limit
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67150
+rollout_issue_url:
+milestone: '14.2'
+type: ops
+group: group::import
+default_enabled: false
diff --git a/config/feature_flags/ops/github_importer_single_endpoint_notes_import.yml b/config/feature_flags/ops/github_importer_single_endpoint_notes_import.yml
new file mode 100644
index 00000000000..7bbc6fba9e0
--- /dev/null
+++ b/config/feature_flags/ops/github_importer_single_endpoint_notes_import.yml
@@ -0,0 +1,8 @@
+---
+name: github_importer_single_endpoint_notes_import
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67150
+rollout_issue_url:
+milestone: '14.2'
+type: ops
+group: group::import
+default_enabled: false
diff --git a/config/feature_flags/ops/global_search_code_tab.yml b/config/feature_flags/ops/global_search_code_tab.yml
new file mode 100644
index 00000000000..540f742a147
--- /dev/null
+++ b/config/feature_flags/ops/global_search_code_tab.yml
@@ -0,0 +1,8 @@
+---
+name: global_search_code_tab
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68640
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339207
+milestone: '14.3'
+type: ops
+group: group::global search
+default_enabled: true
diff --git a/config/feature_flags/ops/global_search_commits_tab.yml b/config/feature_flags/ops/global_search_commits_tab.yml
new file mode 100644
index 00000000000..7f6e5978d48
--- /dev/null
+++ b/config/feature_flags/ops/global_search_commits_tab.yml
@@ -0,0 +1,8 @@
+---
+name: global_search_commits_tab
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68640
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339207
+milestone: '14.3'
+type: ops
+group: group::global search
+default_enabled: true
diff --git a/config/feature_flags/ops/global_search_issues_tab.yml b/config/feature_flags/ops/global_search_issues_tab.yml
new file mode 100644
index 00000000000..101b2588386
--- /dev/null
+++ b/config/feature_flags/ops/global_search_issues_tab.yml
@@ -0,0 +1,8 @@
+---
+name: global_search_issues_tab
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68640
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339207
+milestone: '14.3'
+type: ops
+group: group::global search
+default_enabled: true
diff --git a/config/feature_flags/ops/global_search_merge_requests_tab.yml b/config/feature_flags/ops/global_search_merge_requests_tab.yml
new file mode 100644
index 00000000000..7f4570e5134
--- /dev/null
+++ b/config/feature_flags/ops/global_search_merge_requests_tab.yml
@@ -0,0 +1,8 @@
+---
+name: global_search_merge_requests_tab
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68640
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339207
+milestone: '14.3'
+type: ops
+group: group::global search
+default_enabled: true
diff --git a/config/feature_flags/ops/global_search_wiki_tab.yml b/config/feature_flags/ops/global_search_wiki_tab.yml
new file mode 100644
index 00000000000..ff7b777ac05
--- /dev/null
+++ b/config/feature_flags/ops/global_search_wiki_tab.yml
@@ -0,0 +1,8 @@
+---
+name: global_search_wiki_tab
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68640
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339207
+milestone: '14.3'
+type: ops
+group: group::global search
+default_enabled: true
diff --git a/config/feature_flags/ops/lower_relation_max_count_limit.yml b/config/feature_flags/ops/lower_relation_max_count_limit.yml
new file mode 100644
index 00000000000..7a532c0948a
--- /dev/null
+++ b/config/feature_flags/ops/lower_relation_max_count_limit.yml
@@ -0,0 +1,8 @@
+---
+name: lower_relation_max_count_limit
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69620
+rollout_issue_url:
+milestone: '14.3'
+type: ops
+group: group::verify
+default_enabled: false
diff --git a/config/feature_flags/ops/mask_page_urls.yml b/config/feature_flags/ops/mask_page_urls.yml
new file mode 100644
index 00000000000..a752d1c8796
--- /dev/null
+++ b/config/feature_flags/ops/mask_page_urls.yml
@@ -0,0 +1,8 @@
+---
+name: mask_page_urls
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69448
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340181
+milestone: '14.3'
+type: ops
+group: group::product intelligence
+default_enabled: false
diff --git a/config/feature_flags/ops/product_analytics_tracking.yml b/config/feature_flags/ops/product_analytics_tracking.yml
index 82635ad0640..5d392c4e4a7 100644
--- a/config/feature_flags/ops/product_analytics_tracking.yml
+++ b/config/feature_flags/ops/product_analytics_tracking.yml
@@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46482
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/285519
milestone: '13.7'
type: ops
-group: group::product analytics
+group: group::product intelligence
default_enabled: false
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index f7b1c2f7567..a8881fd8a2e 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -959,6 +959,11 @@ production: &base
# (default: false)
auto_link_saml_user: false
+ # CAUTION!
+ # Allows larger SAML messages to be received. Numeric value in bytes (default: 250000)
+ # Too high limits exposes instance to decompression DDoS attack type.
+ saml_message_max_byte_size: 250000
+
# Allow users with existing accounts to sign in and auto link their account via OmniAuth
# login, without having to do a manual login first and manually add OmniAuth. Links on email.
# Define the allowed providers using an array, e.g. ["saml", "twitter"], or as true/false to
@@ -1146,14 +1151,22 @@ production: &base
# # Use multipart uploads when file size reaches 100MB, see
# # http://docs.aws.amazon.com/AmazonS3/latest/dev/uploadobjusingmpu.html
# multipart_chunk_size: 104857600
- # # Turns on AWS Server-Side Encryption with Amazon S3-Managed Keys for backups, this is optional
- # # encryption: 'AES256'
+ # # Specifies Amazon S3 storage class to use for backups (optional)
+ # # storage_class: 'STANDARD'
# # Turns on AWS Server-Side Encryption with Amazon Customer-Provided Encryption Keys for backups, this is optional
- # # This should be set to the 256-bit encryption key for Amazon S3 to use to encrypt or decrypt your data.
- # # 'encryption' must also be set in order for this to have any effect.
+ # # 'encryption' must be set in order for this to have any effect.
+ # # 'encryption_key' should be set to the 256-bit encryption key for Amazon S3 to use to encrypt or decrypt your data.
+ # # encryption: 'AES256'
# # encryption_key: '<key>'
- # # Specifies Amazon S3 storage class to use for backups, this is optional
- # # storage_class: 'STANDARD'
+ # #
+ # # Turns on AWS Server-Side Encryption with Amazon S3-Managed keys (optional)
+ # # https://docs.aws.amazon.com/AmazonS3/latest/userguide/serv-side-encryption.html
+ # # For SSE-S3, set 'server_side_encryption' to 'AES256'.
+ # # For SS3-KMS, set 'server_side_encryption' to 'aws:kms'. Set
+ # # 'server_side_encryption_kms_key_id' to the ARN of customer master key.
+ # # storage_options:
+ # # server_side_encryption: 'aws:kms'
+ # # server_side_encryption_kms_key_id: 'arn:aws:kms:YOUR-KEY-ID-HERE'
## Pseudonymizer exporter
pseudonymizer:
diff --git a/config/helpers/incremental_webpack_compiler.js b/config/helpers/incremental_webpack_compiler.js
deleted file mode 100644
index 5d4f9bd040d..00000000000
--- a/config/helpers/incremental_webpack_compiler.js
+++ /dev/null
@@ -1,131 +0,0 @@
-/* eslint-disable max-classes-per-file, no-underscore-dangle */
-const fs = require('fs');
-const path = require('path');
-
-const log = (msg, ...rest) => console.log(`IncrementalWebpackCompiler: ${msg}`, ...rest);
-
-// If we force a recompile immediately, the page reload doesn't seem to work.
-// Five seconds seem to work fine and the user can read the message
-const TIMEOUT = 5000;
-
-/* eslint-disable class-methods-use-this */
-class NoopCompiler {
- constructor() {
- this.enabled = false;
- }
-
- filterEntryPoints(entryPoints) {
- return entryPoints;
- }
-
- logStatus() {}
-
- setupMiddleware() {}
-}
-/* eslint-enable class-methods-use-this */
-
-class IncrementalWebpackCompiler {
- constructor(historyFilePath) {
- this.enabled = true;
- this.history = {};
- this.compiledEntryPoints = new Set([
- // Login page
- 'pages.sessions.new',
- // Explore page
- 'pages.root',
- ]);
- this.historyFilePath = historyFilePath;
- this._loadFromHistory();
- }
-
- filterEntryPoints(entrypoints) {
- return Object.fromEntries(
- Object.entries(entrypoints).map(([key, val]) => {
- if (this.compiledEntryPoints.has(key)) {
- return [key, val];
- }
- return [key, ['./webpack_non_compiled_placeholder.js']];
- }),
- );
- }
-
- logStatus(totalCount) {
- const current = this.compiledEntryPoints.size;
- log(`Currently compiling route entrypoints: ${current} of ${totalCount}`);
- }
-
- setupMiddleware(app, server) {
- app.use((req, res, next) => {
- const fileName = path.basename(req.url);
-
- /**
- * We are only interested in files that have a name like `pages.foo.bar.chunk.js`
- * because those are the ones corresponding to our entry points.
- *
- * This filters out hot update files that are for example named "pages.foo.bar.[hash].hot-update.js"
- */
- if (fileName.startsWith('pages.') && fileName.endsWith('.chunk.js')) {
- const chunk = fileName.replace(/\.chunk\.js$/, '');
-
- this._addToHistory(chunk);
-
- if (!this.compiledEntryPoints.has(chunk)) {
- log(`First time we are seeing ${chunk}. Adding to compilation.`);
-
- this.compiledEntryPoints.add(chunk);
-
- setTimeout(() => {
- server.middleware.invalidate(() => {
- if (server.sockets) {
- server.sockWrite(server.sockets, 'content-changed');
- }
- });
- }, TIMEOUT);
- }
- }
-
- next();
- });
- }
-
- // private methods
-
- _addToHistory(chunk) {
- if (!this.history[chunk]) {
- this.history[chunk] = { lastVisit: null, count: 0 };
- }
- this.history[chunk].lastVisit = Date.now();
- this.history[chunk].count += 1;
-
- try {
- fs.writeFileSync(this.historyFilePath, JSON.stringify(this.history), 'utf8');
- } catch (e) {
- log('Warning – Could not write to history', e.message);
- }
- }
-
- _loadFromHistory() {
- try {
- this.history = JSON.parse(fs.readFileSync(this.historyFilePath, 'utf8'));
- const entryPoints = Object.keys(this.history);
- log(`Successfully loaded history containing ${entryPoints.length} entry points`);
- /*
- TODO: Let's ask a few folks to give us their history file after a milestone of usage
- Then we can make smarter decisions on when to throw out rather than rendering everything
- Something like top 20/30/40 entries visited in the last 7/10/15 days might be sufficient
- */
- this.compiledEntryPoints = new Set([...this.compiledEntryPoints, ...entryPoints]);
- } catch (e) {
- log(`No history found...`);
- }
- }
-}
-
-module.exports = (enabled, historyFilePath) => {
- log(`Status – ${enabled ? 'enabled' : 'disabled'}`);
-
- if (enabled) {
- return new IncrementalWebpackCompiler(historyFilePath);
- }
- return new NoopCompiler();
-};
diff --git a/config/helpers/incremental_webpack_compiler/compiler.js b/config/helpers/incremental_webpack_compiler/compiler.js
new file mode 100644
index 00000000000..480d7fa3263
--- /dev/null
+++ b/config/helpers/incremental_webpack_compiler/compiler.js
@@ -0,0 +1,117 @@
+/* eslint-disable max-classes-per-file */
+
+const path = require('path');
+const { History, HistoryWithTTL } = require('./history');
+const log = require('./log');
+
+const onRequestEntryPoint = (app, callback) => {
+ app.use((req, res, next) => {
+ const fileName = path.basename(req.url);
+
+ /**
+ * We are only interested in files that have a name like `pages.foo.bar.chunk.js`
+ * because those are the ones corresponding to our entry points.
+ *
+ * This filters out hot update files that are for example named "pages.foo.bar.[hash].hot-update.js"
+ */
+ if (fileName.startsWith('pages.') && fileName.endsWith('.chunk.js')) {
+ const entryPoint = fileName.replace(/\.chunk\.js$/, '');
+ callback(entryPoint);
+ }
+
+ next();
+ });
+};
+
+/**
+ * The NoopCompiler does nothing, following the null object pattern.
+ */
+class NoopCompiler {
+ constructor() {
+ this.enabled = false;
+ }
+
+ // eslint-disable-next-line class-methods-use-this
+ filterEntryPoints(entryPoints) {
+ return entryPoints;
+ }
+
+ // eslint-disable-next-line class-methods-use-this
+ logStatus() {}
+
+ // eslint-disable-next-line class-methods-use-this
+ setupMiddleware() {}
+}
+
+/**
+ * The HistoryOnlyCompiler only records which entry points have been requested.
+ * This is so that if the user disables incremental compilation, history is
+ * still recorded. If they later enable incremental compilation, that history
+ * can be used.
+ */
+class HistoryOnlyCompiler extends NoopCompiler {
+ constructor(historyFilePath) {
+ super();
+ this.history = new History(historyFilePath);
+ }
+
+ setupMiddleware(app) {
+ onRequestEntryPoint(app, (entryPoint) => {
+ this.history.onRequestEntryPoint(entryPoint);
+ });
+ }
+}
+
+// If we force a recompile immediately, the page reload doesn't seem to work.
+// Five seconds seem to work fine and the user can read the message
+const TIMEOUT = 5000;
+
+/**
+ * The IncrementalWebpackCompiler tracks which entry points have been
+ * requested, and only compiles entry points visited within the last `ttl`
+ * days.
+ */
+class IncrementalWebpackCompiler {
+ constructor(historyFilePath, ttl) {
+ this.enabled = true;
+ this.history = new HistoryWithTTL(historyFilePath, ttl);
+ }
+
+ filterEntryPoints(entrypoints) {
+ return Object.fromEntries(
+ Object.entries(entrypoints).map(([entryPoint, paths]) => {
+ if (this.history.isRecentlyVisited(entryPoint)) {
+ return [entryPoint, paths];
+ }
+ return [entryPoint, ['./webpack_non_compiled_placeholder.js']];
+ }),
+ );
+ }
+
+ logStatus(totalCount) {
+ log(`Currently compiling route entrypoints: ${this.history.size} of ${totalCount}`);
+ }
+
+ setupMiddleware(app, server) {
+ onRequestEntryPoint(app, (entryPoint) => {
+ const wasVisitedRecently = this.history.onRequestEntryPoint(entryPoint);
+ if (!wasVisitedRecently) {
+ log(`Have not visited ${entryPoint} recently. Adding to compilation.`);
+
+ setTimeout(() => {
+ server.middleware.invalidate(() => {
+ if (server.sockets) {
+ server.sockWrite(server.sockets, 'content-changed');
+ }
+ });
+ }, TIMEOUT);
+ }
+ });
+ }
+}
+
+module.exports = {
+ NoopCompiler,
+ HistoryOnlyCompiler,
+ IncrementalWebpackCompiler,
+};
diff --git a/config/helpers/incremental_webpack_compiler/history.js b/config/helpers/incremental_webpack_compiler/history.js
new file mode 100644
index 00000000000..24599900011
--- /dev/null
+++ b/config/helpers/incremental_webpack_compiler/history.js
@@ -0,0 +1,176 @@
+/* eslint-disable max-classes-per-file, no-underscore-dangle */
+
+const fs = require('fs');
+const log = require('./log');
+
+const ESSENTIAL_ENTRY_POINTS = [
+ // Login page
+ 'pages.sessions.new',
+ // Explore page
+ 'pages.root',
+];
+
+// TODO: Find a way to keep this list up-to-date/relevant.
+const COMMON_ENTRY_POINTS = [
+ ...ESSENTIAL_ENTRY_POINTS,
+ 'pages.admin',
+ 'pages.admin.dashboard',
+ 'pages.dashboard.groups.index',
+ 'pages.dashboard.projects.index',
+ 'pages.groups.new',
+ 'pages.groups.show',
+ 'pages.profiles.preferences.show',
+ 'pages.projects.commit.show',
+ 'pages.projects.edit',
+ 'pages.projects.issues.index',
+ 'pages.projects.issues.new',
+ 'pages.projects.issues.show',
+ 'pages.projects.jobs.show',
+ 'pages.projects.merge_requests.index',
+ 'pages.projects.merge_requests.show',
+ 'pages.projects.milestones.index',
+ 'pages.projects.new',
+ 'pages.projects.pipelines.index',
+ 'pages.projects.pipelines.show',
+ 'pages.projects.settings.ci_cd.show',
+ 'pages.projects.settings.repository.show',
+ 'pages.projects.show',
+ 'pages.users',
+];
+
+/**
+ * The History class is responsible for tracking which entry points have been
+ * requested, and persisting/loading the history to/from disk.
+ */
+class History {
+ constructor(historyFilePath) {
+ this._historyFilePath = historyFilePath;
+ this._history = {};
+
+ this._loadHistoryFile();
+ }
+
+ onRequestEntryPoint(entryPoint) {
+ const wasVisitedRecently = this.isRecentlyVisited(entryPoint);
+
+ this._addEntryPoint(entryPoint);
+
+ this._writeHistoryFile();
+
+ return wasVisitedRecently;
+ }
+
+ // eslint-disable-next-line class-methods-use-this
+ isRecentlyVisited() {
+ return true;
+ }
+
+ // eslint-disable-next-line class-methods-use-this
+ get size() {
+ return 0;
+ }
+
+ // Private methods
+
+ _addEntryPoint(entryPoint) {
+ if (!this._history[entryPoint]) {
+ this._history[entryPoint] = { lastVisit: null, count: 0 };
+ }
+
+ this._history[entryPoint].lastVisit = Date.now();
+ this._history[entryPoint].count += 1;
+ }
+
+ _writeHistoryFile() {
+ try {
+ fs.writeFileSync(this._historyFilePath, JSON.stringify(this._history), 'utf8');
+ } catch (error) {
+ log('Warning – Could not write to history', error.message);
+ }
+ }
+
+ _loadHistoryFile() {
+ try {
+ fs.accessSync(this._historyFilePath);
+ } catch (e) {
+ // History file doesn't exist; attempt to seed it, and return early
+ this._seedHistory();
+ return;
+ }
+
+ // History file already exists; attempt to load its contents into memory
+ try {
+ this._history = JSON.parse(fs.readFileSync(this._historyFilePath, 'utf8'));
+ const historySize = Object.keys(this._history).length;
+ log(`Successfully loaded history containing ${historySize} entry points`);
+ } catch (error) {
+ log('Could not load history', error.message);
+ }
+ }
+
+ /**
+ * Seeds a reasonable set of approximately the most common entry points to
+ * seed the history. This helps to avoid fresh GDK installs showing the
+ * compiling overlay too often.
+ */
+ _seedHistory() {
+ log('Seeding history...');
+ COMMON_ENTRY_POINTS.forEach((entryPoint) => this._addEntryPoint(entryPoint));
+ this._writeHistoryFile();
+ }
+}
+
+const MS_PER_DAY = 1000 * 60 * 60 * 24;
+
+/**
+ * The HistoryWithTTL class adds LRU-like behaviour onto the base History
+ * behaviour. Entry points visited within the last `ttl` days are considered
+ * "recent", and therefore should be eagerly compiled.
+ */
+class HistoryWithTTL extends History {
+ constructor(historyFilePath, ttl) {
+ super(historyFilePath);
+ this._ttl = ttl;
+ this._calculateRecentEntryPoints();
+ }
+
+ onRequestEntryPoint(entryPoint) {
+ const wasVisitedRecently = super.onRequestEntryPoint(entryPoint);
+
+ this._calculateRecentEntryPoints();
+
+ return wasVisitedRecently;
+ }
+
+ isRecentlyVisited(entryPoint) {
+ return this._recentEntryPoints.has(entryPoint);
+ }
+
+ get size() {
+ return this._recentEntryPoints.size;
+ }
+
+ // Private methods
+
+ _calculateRecentEntryPoints() {
+ const oldestVisitAllowed = Date.now() - MS_PER_DAY * this._ttl;
+
+ const recentEntryPoints = Object.entries(this._history).reduce(
+ (acc, [entryPoint, { lastVisit }]) => {
+ if (lastVisit > oldestVisitAllowed) {
+ acc.push(entryPoint);
+ }
+
+ return acc;
+ },
+ [],
+ );
+
+ this._recentEntryPoints = new Set([...ESSENTIAL_ENTRY_POINTS, ...recentEntryPoints]);
+ }
+}
+
+module.exports = {
+ History,
+ HistoryWithTTL,
+};
diff --git a/config/helpers/incremental_webpack_compiler/index.js b/config/helpers/incremental_webpack_compiler/index.js
new file mode 100644
index 00000000000..81826607490
--- /dev/null
+++ b/config/helpers/incremental_webpack_compiler/index.js
@@ -0,0 +1,17 @@
+const { NoopCompiler, HistoryOnlyCompiler, IncrementalWebpackCompiler } = require('./compiler');
+const log = require('./log');
+
+module.exports = (recordHistory, enabled, historyFilePath, ttl) => {
+ if (!recordHistory) {
+ log(`Status – disabled`);
+ return new NoopCompiler();
+ }
+
+ if (enabled) {
+ log(`Status – enabled, ttl=${ttl}`);
+ return new IncrementalWebpackCompiler(historyFilePath, ttl);
+ }
+
+ log(`Status – history-only`);
+ return new HistoryOnlyCompiler(historyFilePath);
+};
diff --git a/config/helpers/incremental_webpack_compiler/log.js b/config/helpers/incremental_webpack_compiler/log.js
new file mode 100644
index 00000000000..6336cb0a78b
--- /dev/null
+++ b/config/helpers/incremental_webpack_compiler/log.js
@@ -0,0 +1,3 @@
+const log = (msg, ...rest) => console.log(`IncrementalWebpackCompiler: ${msg}`, ...rest);
+
+module.exports = log;
diff --git a/config/initializers/00_active_record_gitlab_schema.rb b/config/initializers/00_active_record_gitlab_schema.rb
new file mode 100644
index 00000000000..f1ddd4d4eb1
--- /dev/null
+++ b/config/initializers/00_active_record_gitlab_schema.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+# This parameter describes a virtual context to indicate
+# table affinity to other tables.
+#
+# Table affinity limits cross-joins, cross-modifications,
+# foreign keys and validates relationship between tables
+#
+# By default it is undefined
+ActiveRecord::Base.class_attribute :gitlab_schema, default: nil
diff --git a/config/initializers/0_acts_as_taggable.rb b/config/initializers/0_acts_as_taggable.rb
index 9f66d970ffd..04619590e3c 100644
--- a/config/initializers/0_acts_as_taggable.rb
+++ b/config/initializers/0_acts_as_taggable.rb
@@ -13,3 +13,7 @@ raise "Counter cache is not disabled" if
ActsAsTaggableOn::Tagging.include IgnorableColumns
ActsAsTaggableOn::Tagging.ignore_column :id_convert_to_bigint, remove_with: '14.2', remove_after: '2021-08-22'
ActsAsTaggableOn::Tagging.ignore_column :taggable_id_convert_to_bigint, remove_with: '14.2', remove_after: '2021-08-22'
+
+# The tags and taggings are supposed to be part of `gitlab_ci`
+ActsAsTaggableOn::Tag.gitlab_schema = :gitlab_ci
+ActsAsTaggableOn::Tagging.gitlab_schema = :gitlab_ci
diff --git a/config/initializers/0_inject_enterprise_edition_module.rb b/config/initializers/0_inject_enterprise_edition_module.rb
index a00075990eb..41d1043af38 100644
--- a/config/initializers/0_inject_enterprise_edition_module.rb
+++ b/config/initializers/0_inject_enterprise_edition_module.rb
@@ -58,39 +58,7 @@ module InjectEnterpriseEditionModule
end
def const_get_maybe_false(mod, name)
- # We're still heavily relying on Rails autoloading instead of zeitwerk,
- # therefore this check: `mod.const_defined?(name, false)`
- # Is not reliable, which may return false while it's defined.
- # After we moved everything over to zeitwerk we can avoid rescuing
- # NameError and just check if const_defined?
- # mod && mod.const_defined?(name, false) && mod.const_get(name, false)
- result = mod && mod.const_get(name, false)
-
- if result.name == "#{mod}::#{name}"
- result
- else
- # This may hit into a Rails issue that when we try to load
- # `EE::API::Appearance`, Rails might load `::Appearance` the first time
- # when `mod.const_get(name, false)` is called if `::Appearance` is not
- # loaded yet. This can be demonstrated as the following:
- #
- # EE.const_get('API::Appearance', false) # => Appearance
- # EE.const_get('API::Appearance', false) # => raise NameError
- #
- # Getting a `NameError` is what we're expecting here, because
- # `EE::API::Appearance` doesn't exist.
- #
- # This is because Rails will attempt to load constants from all the
- # parent namespaces, and if it finds one it'll load it and return it.
- # However, the second time when it's called, since the top-level class
- # is already loaded, then Rails will skip this process. This weird
- # behaviour can be worked around by calling this the second time.
- # The particular line is at:
- # https://github.com/rails/rails/blob/v6.1.3.2/activesupport/lib/active_support/dependencies.rb#L569-L570
- mod.const_get(name, false)
- end
- rescue NameError
- false
+ mod && mod.const_defined?(name, false) && mod.const_get(name, false)
end
end
diff --git a/config/initializers/0_marginalia.rb b/config/initializers/0_marginalia.rb
index 7e48c9d4fcd..f7a1f5f0469 100644
--- a/config/initializers/0_marginalia.rb
+++ b/config/initializers/0_marginalia.rb
@@ -13,7 +13,7 @@ require 'marginalia'
# matching against the raw SQL, and prepending the comment prevents color
# coding from working in the development log.
Marginalia::Comment.prepend_comment = true if Rails.env.production?
-Marginalia::Comment.components = [:application, :correlation_id, :jid, :endpoint_id]
+Marginalia::Comment.components = [:application, :correlation_id, :jid, :endpoint_id, :db_config_name]
# As mentioned in https://github.com/basecamp/marginalia/pull/93/files,
# adding :line has some overhead because a regexp on the backtrace has
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index e71f1e1b028..1c22216d442 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -95,6 +95,7 @@ Settings.omniauth['block_auto_created_users'] = true if Settings.omniauth['block
Settings.omniauth['auto_link_ldap_user'] = false if Settings.omniauth['auto_link_ldap_user'].nil?
Settings.omniauth['auto_link_saml_user'] = false if Settings.omniauth['auto_link_saml_user'].nil?
Settings.omniauth['auto_link_user'] = false if Settings.omniauth['auto_link_user'].nil?
+Settings.omniauth['saml_message_max_byte_size'] = 250000 if Settings.omniauth['saml_message_max_byte_size'].nil?
Settings.omniauth['sync_profile_from_provider'] = false if Settings.omniauth['sync_profile_from_provider'].nil?
Settings.omniauth['sync_profile_attributes'] = ['email'] if Settings.omniauth['sync_profile_attributes'].nil?
@@ -251,6 +252,7 @@ Settings.gitlab_ci['url'] ||= Settings.__send__(:build_gitlab_ci
#
Settings['incoming_email'] ||= Settingslogic.new({})
Settings.incoming_email['enabled'] = false if Settings.incoming_email['enabled'].nil?
+Settings.incoming_email['inbox_method'] ||= 'imap'
#
# Service desk email
diff --git a/config/initializers/action_cable.rb b/config/initializers/action_cable.rb
index 5530e7d64a2..16d29f5910f 100644
--- a/config/initializers/action_cable.rb
+++ b/config/initializers/action_cable.rb
@@ -17,3 +17,6 @@ ActionCable::SubscriptionAdapter::Redis.redis_connector = lambda do |config|
::Redis.new(args)
end
+
+Gitlab::ActionCable::RequestStoreCallbacks.install
+Gitlab::Database::LoadBalancing::ActionCableCallbacks.install if Gitlab::Database::LoadBalancing.enable?
diff --git a/config/initializers/active_record_build_select.rb b/config/initializers/active_record_build_select.rb
deleted file mode 100644
index ab5a872cac6..00000000000
--- a/config/initializers/active_record_build_select.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# frozen_string_literal: true
-
-# rubocop:disable Gitlab/ModuleWithInstanceVariables
-
-# build_select only selects the required fields if the model has ignored_columns.
-# This is incompatible with some migrations or background migration specs because
-# rails keeps a statement cache in memory. So if a model with ignored_columns in a
-# migration is used, the query with select table.col1, table.col2 is stored in the
-# statement cache. If a different migration is then run and one of these columns is
-# removed in the meantime, the query is invalid.
-
-module ActiveRecord
- module QueryMethods
- private
-
- def build_select(arel)
- if select_values.any?
- arel.project(*arel_columns(select_values.uniq))
- else
- arel.project(@klass.arel_table[Arel.star])
- end
- end
- end
-end
diff --git a/config/initializers/active_record_migrations.rb b/config/initializers/active_record_migrations.rb
new file mode 100644
index 00000000000..d878a1b210b
--- /dev/null
+++ b/config/initializers/active_record_migrations.rb
@@ -0,0 +1,3 @@
+# frozen_string_literal: true
+
+Gitlab::Database::Migrations::LockRetryMixin.patch!
diff --git a/config/initializers/database_config.rb b/config/initializers/database_config.rb
index 6bdd0e377da..e9f10abd0b9 100644
--- a/config/initializers/database_config.rb
+++ b/config/initializers/database_config.rb
@@ -24,7 +24,7 @@ ActiveRecord::Base.establish_connection(Gitlab::Database.main.db_config_with_def
Gitlab.ee do
if Gitlab::Runtime.sidekiq? && Gitlab::Geo.geo_database_configured?
- Rails.configuration.geo_database['pool'] = Gitlab::Database.main.default_pool_size
+ Rails.configuration.geo_database['pool'] = Gitlab::Database.default_pool_size
Geo::TrackingBase.establish_connection(Rails.configuration.geo_database)
end
end
diff --git a/config/initializers/doorkeeper.rb b/config/initializers/doorkeeper.rb
index 4533779339a..477d419576a 100644
--- a/config/initializers/doorkeeper.rb
+++ b/config/initializers/doorkeeper.rb
@@ -38,8 +38,11 @@ Doorkeeper.configure do
# authorization_code_expires_in 10.minutes
# Access token expiration time (default 2 hours).
- # If you want to disable expiration, set this to nil.
- access_token_expires_in nil
+ # Until 15.0, applications can opt-out of expiring tokens.
+ # Removal issue: https://gitlab.com/gitlab-org/gitlab/-/issues/340848
+ custom_access_token_expires_in do |context|
+ context.client&.expire_access_tokens ? 2.hours : Float::INFINITY
+ end
# Reuse access token for the same resource owner within an application (disabled by default)
# Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/383
diff --git a/config/initializers/doorkeeper_openid_connect.rb b/config/initializers/doorkeeper_openid_connect.rb
index 12a963ce45d..476230d0f70 100644
--- a/config/initializers/doorkeeper_openid_connect.rb
+++ b/config/initializers/doorkeeper_openid_connect.rb
@@ -57,7 +57,8 @@ Doorkeeper::OpenidConnect.configure do
o.claim(:website) { |user| user.full_website_url if user.website_url? }
o.claim(:profile) { |user| Gitlab::Routing.url_helpers.user_url user }
o.claim(:picture) { |user| user.avatar_url(only_path: false) }
- o.claim(:groups) { |user| user.membership_groups.map(&:full_path) }
+ o.claim(:groups) { |user| user.membership_groups.joins(:route).with_route.map(&:full_path) }
+ o.claim(:groups_direct, response: [:id_token]) { |user| user.groups.joins(:route).with_route.map(&:full_path) }
end
end
end
diff --git a/config/initializers/kaminari_active_record_relation_methods_with_limit.rb b/config/initializers/kaminari_active_record_relation_methods_with_limit.rb
index 982cb69e532..9a5a95403ad 100644
--- a/config/initializers/kaminari_active_record_relation_methods_with_limit.rb
+++ b/config/initializers/kaminari_active_record_relation_methods_with_limit.rb
@@ -4,6 +4,7 @@ module Kaminari
# Active Record specific page scope methods implementations
module ActiveRecordRelationMethodsWithLimit
MAX_COUNT_LIMIT = 10_000
+ MAX_COUNT_NEW_LOWER_LIMIT = 1_000
# This is a modified version of
# https://github.com/kaminari/kaminari/blob/c5186f5d9b7f23299d115408e62047447fd3189d/kaminari-activerecord/lib/kaminari/activerecord/active_record_relation_methods.rb#L17-L41
@@ -21,7 +22,8 @@ module Kaminari
return @total_count = (current_page - 1) * limit_value + @records.length if @records.any? && (@records.length < limit_value)
end
- limit = options.fetch(:limit, MAX_COUNT_LIMIT).to_i
+ max_limit = Feature.enabled?(:lower_relation_max_count_limit, type: :ops) ? MAX_COUNT_NEW_LOWER_LIMIT : MAX_COUNT_LIMIT
+ limit = options.fetch(:limit, max_limit).to_i
# #count overrides the #select which could include generated columns referenced in #order, so skip #order here, where it's irrelevant to the result anyway
c = except(:offset, :limit, :order)
# Remove includes only if they are irrelevant
diff --git a/config/initializers/peek.rb b/config/initializers/peek.rb
index 6fd92865731..9662039e3eb 100644
--- a/config/initializers/peek.rb
+++ b/config/initializers/peek.rb
@@ -24,7 +24,7 @@ Peek.into Peek::Views::Tracing if Labkit::Tracing.tracing_url_enabled?
# See https://github.com/peek/peek/blob/master/lib/peek/views/view.rb
Peek.views
-ActiveSupport::Notifications.subscribe('endpoint_run.grape') do |_name, _start, _finish, _id, payload|
+ActiveSupport::Notifications.subscribe('format_response.grape') do |_name, _start, _finish, _id, payload|
if request_id = payload[:env]['action_dispatch.request_id']
Peek.adapter.save(request_id)
end
diff --git a/config/initializers/postgres_partitioning.rb b/config/initializers/postgres_partitioning.rb
index d4be1e7670d..f2e2fba1559 100644
--- a/config/initializers/postgres_partitioning.rb
+++ b/config/initializers/postgres_partitioning.rb
@@ -1,17 +1,20 @@
# frozen_string_literal: true
-# Make sure we have loaded partitioned models here
-# (even with eager loading disabled).
-
-Gitlab::Database::Partitioning::PartitionManager.register(AuditEvent)
-Gitlab::Database::Partitioning::PartitionManager.register(WebHookLog)
+Gitlab::Database::Partitioning.register_models([
+ AuditEvent,
+ WebHookLog,
+ LooseForeignKeys::DeletedRecord
+])
if Gitlab.ee?
- Gitlab::Database::Partitioning::PartitionManager.register(IncidentManagement::PendingEscalations::Alert)
+ Gitlab::Database::Partitioning.register_models([
+ IncidentManagement::PendingEscalations::Alert,
+ IncidentManagement::PendingEscalations::Issue
+ ])
end
begin
- Gitlab::Database::Partitioning::PartitionManager.new.sync_partitions unless ENV['DISABLE_POSTGRES_PARTITION_CREATION_ON_STARTUP']
+ Gitlab::Database::Partitioning.sync_partitions unless ENV['DISABLE_POSTGRES_PARTITION_CREATION_ON_STARTUP']
rescue ActiveRecord::ActiveRecordError, PG::Error
# ignore - happens when Rake tasks yet have to create a database, e.g. for testing
end
diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb
index 204d4d88f0a..02fc4912f94 100644
--- a/config/initializers/session_store.rb
+++ b/config/initializers/session_store.rb
@@ -13,6 +13,8 @@ end
cookie_key = if Rails.env.development?
"_gitlab_session_#{Digest::SHA256.hexdigest(Rails.root.to_s)}"
+ elsif ::Gitlab.ee? && ::Gitlab::Geo.connected? && ::Gitlab::Geo.secondary?
+ "_gitlab_session_geo_#{Digest::SHA256.hexdigest(GeoNode.current_node_name)}"
else
"_gitlab_session"
end
diff --git a/config/initializers/static_files.rb b/config/initializers/static_files.rb
index 3cdb5a5abcf..2879d48387d 100644
--- a/config/initializers/static_files.rb
+++ b/config/initializers/static_files.rb
@@ -2,6 +2,10 @@
app = Rails.application
+# Disable Sendfile for Sidekiq Web assets since Workhorse won't
+# always have access to these files.
+app.config.middleware.insert_before(Rack::Sendfile, Gitlab::Middleware::SidekiqWebStatic)
+
if app.config.public_file_server.enabled
# The `ActionDispatch::Static` middleware intercepts requests for static files
# by checking if they exist in the `/public` directory.
diff --git a/config/initializers/validate_database_config.rb b/config/initializers/validate_database_config.rb
new file mode 100644
index 00000000000..a651db8b783
--- /dev/null
+++ b/config/initializers/validate_database_config.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+if Gitlab::Utils.to_boolean(ENV['SKIP_DATABASE_CONFIG_VALIDATION'], default: false)
+ return
+end
+
+if Rails.application.config.uses_legacy_database_config
+ warn "WARNING: This installation of GitLab uses a deprecated syntax for 'config/database.yml'. " \
+ "The support for this syntax will be removed in 15.0. " \
+ "More information can be found here: https://gitlab.com/gitlab-org/gitlab/-/issues/338182"
+end
+
+if configurations = ActiveRecord::Base.configurations.configurations
+ if configurations.first.name != Gitlab::Database::MAIN_DATABASE_NAME
+ raise "ERROR: This installation of GitLab uses unsupported 'config/database.yml'. " \
+ "The `main:` database needs to be defined as a first configuration item instead of `#{configurations.first.name}`."
+ end
+
+ rejected_config_names = configurations.map(&:name).to_set - Gitlab::Database::DATABASE_NAMES
+ if rejected_config_names.any?
+ raise "ERROR: This installation of GitLab uses unsupported database names " \
+ "in 'config/database.yml': #{rejected_config_names.to_a.join(", ")}. The only supported ones are " \
+ "#{Gitlab::Database::DATABASE_NAMES.join(", ")}."
+ end
+
+ replicas_config_names = configurations.select(&:replica?).map(&:name)
+ if replicas_config_names.any?
+ raise "ERROR: This installation of GitLab uses unsupported database configuration " \
+ "with 'replica: true' parameter in 'config/database.yml' for: #{replicas_config_names.join(", ")}"
+ end
+end
diff --git a/config/initializers/zz_metrics.rb b/config/initializers/zz_metrics.rb
index e352ff5090a..25e4ec0d483 100644
--- a/config/initializers/zz_metrics.rb
+++ b/config/initializers/zz_metrics.rb
@@ -162,45 +162,6 @@ if Gitlab::Metrics.enabled? && !Rails.env.test? && !(Rails.env.development? && d
config.middleware.use(Gitlab::Metrics::ElasticsearchRackMiddleware)
end
- # This instruments all methods residing in app/models that (appear to) use any
- # of the ActiveRecord methods. This has to take place _after_ initializing as
- # for some unknown reason calling eager_load! earlier breaks Devise.
- Gitlab::Application.config.after_initialize do
- # We should move all the logic of this file to somewhere else
- # and require it after `Rails.application.initialize!` in `environment.rb` file.
- models_path = Rails.root.join('app', 'models').to_s
-
- Dir.glob("**/*.rb", base: models_path).sort.each do |file|
- require_dependency file
- end
-
- regex = Regexp.union(
- ActiveRecord::Querying.public_instance_methods(false).map(&:to_s)
- )
-
- Gitlab::Metrics::Instrumentation
- .instrument_class_hierarchy(ActiveRecord::Base) do |klass, method|
- # Instrumenting the ApplicationSetting class can lead to an infinite
- # loop. Since the data is cached any way we don't really need to
- # instrument it.
- if klass == ApplicationSetting
- false
- else
- loc = method.source_location
-
- loc && loc[0].start_with?(models_path) && method.source =~ regex
- end
- end
-
- # Ability is in app/models, is not an ActiveRecord model, but should still
- # be instrumented.
- Gitlab::Metrics::Instrumentation.instrument_methods(Ability)
- end
-
- Gitlab::Metrics::Instrumentation.configure do |config|
- instrument_classes(config)
- end
-
GC::Profiler.enable
module TrackNewRedisConnections
diff --git a/config/initializers_before_autoloader/000_inflections.rb b/config/initializers_before_autoloader/000_inflections.rb
index 39905adf390..b7e4e143765 100644
--- a/config/initializers_before_autoloader/000_inflections.rb
+++ b/config/initializers_before_autoloader/000_inflections.rb
@@ -25,6 +25,7 @@ ActiveSupport::Inflector.inflections do |inflect|
lfs_object_registry
merge_request_diff_registry
package_file_registry
+ pages_deployment_registry
pipeline_artifact_registry
project_auto_devops
project_registry
diff --git a/config/initializers_before_autoloader/001_fast_gettext.rb b/config/initializers_before_autoloader/001_fast_gettext.rb
index ede38450582..76a1dafd2d8 100644
--- a/config/initializers_before_autoloader/001_fast_gettext.rb
+++ b/config/initializers_before_autoloader/001_fast_gettext.rb
@@ -1,8 +1,31 @@
# frozen_string_literal: true
-FastGettext.add_text_domain 'gitlab',
- path: File.join(Rails.root, 'locale'),
- type: :po,
- ignore_fuzzy: true
+translation_repositories = [
+ FastGettext::TranslationRepository.build(
+ 'gitlab',
+ path: File.join(Rails.root, 'locale'),
+ type: :po,
+ ignore_fuzzy: true
+ )
+]
+
+Gitlab.jh do
+ translation_repositories.unshift(
+ FastGettext::TranslationRepository.build(
+ 'gitlab',
+ path: File.join(Rails.root, 'jh', 'locale'),
+ type: :po,
+ ignore_fuzzy: true
+ )
+ )
+end
+
+FastGettext.add_text_domain(
+ 'gitlab',
+ type: :chain,
+ chain: translation_repositories,
+ ignore_fuzzy: true
+)
+
FastGettext.default_text_domain = 'gitlab'
FastGettext.default_locale = :en
diff --git a/config/initializers_before_autoloader/grape_entity_patch.rb b/config/initializers_before_autoloader/grape_entity_patch.rb
new file mode 100644
index 00000000000..2db5876e75f
--- /dev/null
+++ b/config/initializers_before_autoloader/grape_entity_patch.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+# This can be removed after the problem gets fixed on upstream.
+# You can follow https://github.com/ruby-grape/grape-entity/pull/355 to see the progress.
+#
+# For more information about the issue;
+# https://github.com/ruby/did_you_mean/issues/158#issuecomment-906056018
+
+require 'grape-entity'
+
+module Grape
+ class Entity
+ # Upstream version: https://github.com/ruby-grape/grape-entity/blob/675d3c0e20dfc1d6cf6f5ba5b46741bd404c8be7/lib/grape_entity/entity.rb#L520
+ def exec_with_object(options, &block)
+ if block.parameters.count == 1
+ instance_exec(object, &block)
+ else
+ instance_exec(object, options, &block)
+ end
+ rescue StandardError => e
+ # it handles: https://github.com/ruby/ruby/blob/v3_0_0_preview1/NEWS.md#language-changes point 3, Proc
+ raise Grape::Entity::Deprecated.new e.message, 'in ruby 3.0' if e.is_a?(ArgumentError)
+
+ raise e
+ end
+ end
+end
diff --git a/config/karma.config.js b/config/karma.config.js
deleted file mode 100644
index 39c9dbe264c..00000000000
--- a/config/karma.config.js
+++ /dev/null
@@ -1,203 +0,0 @@
-/* eslint-disable no-inner-declarations, no-param-reassign */
-const path = require('path');
-const chalk = require('chalk');
-const argumentsParser = require('commander');
-const glob = require('glob');
-const webpack = require('webpack');
-const IS_EE = require('./helpers/is_ee_env');
-const webpackConfig = require('./webpack.config');
-
-const ROOT_PATH = path.resolve(__dirname, '..');
-const SPECS_PATH = /^(?:\.[\\/])?(ee[\\/])?spec[\\/]javascripts[\\/]/;
-
-function exitError(message) {
- console.error(chalk.red(`\nError: ${message}\n`));
- process.exit(1);
-}
-
-function exitWarn(message) {
- console.error(chalk.yellow(`\nWarn: ${message}\n`));
- process.exit(0);
-}
-
-function exit(message, isError = true) {
- const fn = isError ? exitError : exitWarn;
-
- fn(message);
-}
-
-// disable problematic options
-webpackConfig.entry = undefined;
-webpackConfig.mode = 'development';
-webpackConfig.optimization.nodeEnv = false;
-webpackConfig.optimization.runtimeChunk = false;
-webpackConfig.optimization.splitChunks = false;
-
-// use quicker sourcemap option
-webpackConfig.devtool = 'cheap-inline-source-map';
-
-// set BABEL_ENV to indicate when we're running code coverage
-webpackConfig.plugins.push(
- new webpack.DefinePlugin({
- 'process.env.BABEL_ENV': JSON.stringify(process.env.BABEL_ENV || process.env.NODE_ENV || null),
- }),
-);
-
-const options = argumentsParser
- .option('--no-fail-on-empty-test-suite')
- .option(
- '-f, --filter-spec [filter]',
- 'Filter run spec files by path. Multiple filters are like a logical OR.',
- (filter, memo) => {
- memo.push(filter, filter.replace(/\/?$/, '/**/*.js'));
- return memo;
- },
- [],
- )
- .parse(process.argv);
-
-const specFilters = options.filterSpec;
-
-const createContext = (specFiles, regex, suffix) => {
- const newContext = specFiles.reduce((context, file) => {
- const relativePath = file.replace(SPECS_PATH, '');
- context[file] = `./${relativePath}`;
- return context;
- }, {});
-
- webpackConfig.plugins.push(
- new webpack.ContextReplacementPlugin(regex, path.join(ROOT_PATH, suffix), newContext),
- );
-};
-
-if (specFilters.length) {
- // resolve filters
- let filteredSpecFiles = specFilters.map((filter) =>
- glob
- .sync(filter, {
- root: ROOT_PATH,
- matchBase: true,
- })
- .filter((filePath) => filePath.endsWith('spec.js')),
- );
-
- // flatten
- filteredSpecFiles = Array.prototype.concat.apply([], filteredSpecFiles);
-
- // remove duplicates
- filteredSpecFiles = [...new Set(filteredSpecFiles)];
-
- if (filteredSpecFiles.length < 1) {
- const isError = options.failOnEmptyTestSuite;
-
- exit('Your filter did not match any test files.', isError);
- }
-
- if (!filteredSpecFiles.every((file) => SPECS_PATH.test(file))) {
- exitError('Test files must be located within /spec/javascripts.');
- }
-
- const CE_FILES = filteredSpecFiles.filter((file) => !file.startsWith('ee'));
- createContext(CE_FILES, /[^e]{2}[\\/]spec[\\/]javascripts$/, 'spec/javascripts');
-
- const EE_FILES = filteredSpecFiles.filter((file) => file.startsWith('ee'));
- createContext(EE_FILES, /ee[\\/]spec[\\/]javascripts$/, 'ee/spec/javascripts');
-}
-
-// Karma configuration
-module.exports = (config) => {
- process.env.TZ = 'Etc/UTC';
-
- const fixturesPath = `tmp/tests/frontend/fixtures${IS_EE ? '-ee' : ''}`;
- const staticFixturesPath = 'spec/frontend/fixtures/static';
-
- const karmaConfig = {
- basePath: ROOT_PATH,
- browsers: ['ChromeHeadlessCustom'],
- client: {
- color: !process.env.CI,
- },
- customLaunchers: {
- ChromeHeadlessCustom: {
- base: 'ChromeHeadless',
- displayName: 'Chrome',
- flags: [
- // chrome cannot run in sandboxed mode inside a docker container unless it is run with
- // escalated kernel privileges (e.g. docker run --cap-add=CAP_SYS_ADMIN)
- '--no-sandbox',
- // https://bugs.chromium.org/p/chromedriver/issues/detail?id=2870
- '--enable-features=NetworkService,NetworkServiceInProcess',
- ],
- },
- },
- frameworks: ['jasmine'],
- files: [
- { pattern: 'spec/javascripts/test_bundle.js', watched: false },
- { pattern: `${fixturesPath}/**/*`, included: false },
- { pattern: `${staticFixturesPath}/**/*`, included: false },
- ],
- proxies: {
- '/fixtures/': `/base/${fixturesPath}/`,
- '/fixtures/static/': `/base/${staticFixturesPath}/`,
- },
- preprocessors: {
- 'spec/javascripts/**/*.js': ['webpack', 'sourcemap'],
- 'ee/spec/javascripts/**/*.js': ['webpack', 'sourcemap'],
- },
- reporters: ['mocha'],
- webpack: webpackConfig,
- webpackMiddleware: { stats: 'errors-only' },
- plugins: [
- 'karma-chrome-launcher',
- 'karma-coverage-istanbul-reporter',
- 'karma-jasmine',
- 'karma-junit-reporter',
- 'karma-mocha-reporter',
- 'karma-sourcemap-loader',
- 'karma-webpack',
- ],
- };
-
- if (process.env.CI) {
- karmaConfig.reporters.push('junit');
- karmaConfig.junitReporter = {
- outputFile: 'junit_karma.xml',
- useBrowserName: false,
- };
- } else {
- // ignore 404s in local environment because we are not fixing them and they bloat the log
- function ignore404() {
- return (request, response /* next */) => {
- response.writeHead(404);
- return response.end('NOT FOUND');
- };
- }
-
- karmaConfig.middleware = ['ignore-404'];
- karmaConfig.plugins.push({
- 'middleware:ignore-404': ['factory', ignore404],
- });
- }
-
- if (process.env.BABEL_ENV === 'coverage' || process.env.NODE_ENV === 'coverage') {
- karmaConfig.reporters.push('coverage-istanbul');
- karmaConfig.coverageIstanbulReporter = {
- reports: ['html', 'text-summary', 'cobertura'],
- dir: 'coverage-javascript/',
- subdir: '.',
- fixWebpackSourcePaths: true,
- };
- karmaConfig.browserNoActivityTimeout = 60000; // 60 seconds
- }
-
- if (process.env.DEBUG) {
- karmaConfig.logLevel = config.LOG_DEBUG;
- process.env.CHROME_LOG_FILE = process.env.CHROME_LOG_FILE || 'chrome_debug.log';
- }
-
- if (process.env.CHROME_LOG_FILE) {
- karmaConfig.customLaunchers.ChromeHeadlessCustom.flags.push('--enable-logging', '--v=1');
- }
-
- config.set(karmaConfig);
-};
diff --git a/config/known_invalid_graphql_queries.yml b/config/known_invalid_graphql_queries.yml
index 2989b3a4262..3dc4b10a6a8 100644
--- a/config/known_invalid_graphql_queries.yml
+++ b/config/known_invalid_graphql_queries.yml
@@ -3,4 +3,3 @@ filenames:
- ee/app/assets/javascripts/oncall_schedules/graphql/mutations/update_oncall_schedule_rotation.mutation.graphql
- ee/app/assets/javascripts/security_configuration/api_fuzzing/graphql/api_fuzzing_ci_configuration.query.graphql
- ee/app/assets/javascripts/security_configuration/api_fuzzing/graphql/create_api_fuzzing_configuration.mutation.graphql
- - ee/app/assets/javascripts/security_configuration/dast_profiles/graphql/dast_failed_site_validations.query.graphql
diff --git a/config/metrics/aggregates/code_review.yml b/config/metrics/aggregates/code_review.yml
index 482e1fc60a1..54ebe5da192 100644
--- a/config/metrics/aggregates/code_review.yml
+++ b/config/metrics/aggregates/code_review.yml
@@ -66,6 +66,7 @@
- 'i_code_review_user_load_conflict_ui'
- 'i_code_review_user_resolve_conflict'
- 'i_code_review_user_searches_diff'
+ - 'i_code_review_user_resolve_thread_in_issue'
- name: code_review_category_monthly_active_users
operator: OR
source: redis
@@ -124,6 +125,7 @@
- 'i_code_review_user_load_conflict_ui'
- 'i_code_review_user_resolve_conflict'
- 'i_code_review_user_searches_diff'
+ - 'i_code_review_user_resolve_thread_in_issue'
- name: code_review_extension_category_monthly_active_users
operator: OR
source: redis
diff --git a/config/metrics/counts_28d/20210201124930_deployments.yml b/config/metrics/counts_28d/20210201124930_deployments.yml
index b19276cdd4e..fc8c37f5a21 100644
--- a/config/metrics/counts_28d/20210201124930_deployments.yml
+++ b/config/metrics/counts_28d/20210201124930_deployments.yml
@@ -7,7 +7,7 @@ product_stage: release
product_group: group::ops release
product_category:
value_type: number
-status: data_available
+status: active
milestone: "13.2"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35493
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210216174910_analytics_unique_visits_for_any_target_monthly.yml b/config/metrics/counts_28d/20210216174910_analytics_unique_visits_for_any_target_monthly.yml
index b031e885f93..f1bff756c5f 100644
--- a/config/metrics/counts_28d/20210216174910_analytics_unique_visits_for_any_target_monthly.yml
+++ b/config/metrics/counts_28d/20210216174910_analytics_unique_visits_for_any_target_monthly.yml
@@ -5,17 +5,20 @@ description: Unique visitors to any analytics feature by month
product_section: dev
product_stage: manage
product_group: group::optimize
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
-data_source:
+data_source: redis_hll
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type:
- smau
- gmau
- paid_gmau
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216174933_p_analytics_pipelines_monthly.yml b/config/metrics/counts_28d/20210216174933_p_analytics_pipelines_monthly.yml
index 85c50572707..e0f19ac36f0 100644
--- a/config/metrics/counts_28d/20210216174933_p_analytics_pipelines_monthly.yml
+++ b/config/metrics/counts_28d/20210216174933_p_analytics_pipelines_monthly.yml
@@ -5,18 +5,21 @@ description: Unique visitors to /groups/:group/-/analytics/ci_cd by month
product_section: dev
product_stage: manage
product_group: group::optimize
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_analytics_pipelines
+ - p_analytics_pipelines
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216174941_p_analytics_valuestream_monthly.yml b/config/metrics/counts_28d/20210216174941_p_analytics_valuestream_monthly.yml
index 70d4cb50aa4..95861042b1c 100644
--- a/config/metrics/counts_28d/20210216174941_p_analytics_valuestream_monthly.yml
+++ b/config/metrics/counts_28d/20210216174941_p_analytics_valuestream_monthly.yml
@@ -5,18 +5,21 @@ description: Unique visitors to /:group/:project/-/value_stream_analytics by mon
product_section: dev
product_stage: manage
product_group: group::optimize
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_analytics_valuestream
+ - p_analytics_valuestream
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216174956_i_analytics_cohorts_monthly.yml b/config/metrics/counts_28d/20210216174956_i_analytics_cohorts_monthly.yml
index ed867d30ff3..75871428fab 100644
--- a/config/metrics/counts_28d/20210216174956_i_analytics_cohorts_monthly.yml
+++ b/config/metrics/counts_28d/20210216174956_i_analytics_cohorts_monthly.yml
@@ -1,22 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.analytics.i_analytics_cohorts_monthly
-description:
+description: "Unique visitors to /-/instance_statistics/cohorts"
product_section: fulfillment
product_stage: fulfillment
product_group: group::utilization
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_analytics_cohorts
+ - i_analytics_cohorts
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175000_i_analytics_dev_ops_score_monthly.yml b/config/metrics/counts_28d/20210216175000_i_analytics_dev_ops_score_monthly.yml
index af99fdbcca8..350363d79ce 100644
--- a/config/metrics/counts_28d/20210216175000_i_analytics_dev_ops_score_monthly.yml
+++ b/config/metrics/counts_28d/20210216175000_i_analytics_dev_ops_score_monthly.yml
@@ -5,18 +5,21 @@ description: Unique visitors to /admin/dev_ops_report by month
product_section: dev
product_stage: manage
product_group: group::optimize
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_analytics_dev_ops_score
+ - i_analytics_dev_ops_score
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175004_g_analytics_merge_request_monthly.yml b/config/metrics/counts_28d/20210216175004_g_analytics_merge_request_monthly.yml
index 7ef394eddae..1f5e3108758 100644
--- a/config/metrics/counts_28d/20210216175004_g_analytics_merge_request_monthly.yml
+++ b/config/metrics/counts_28d/20210216175004_g_analytics_merge_request_monthly.yml
@@ -13,10 +13,13 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_analytics_merge_request
+ - g_analytics_merge_request
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175012_i_analytics_instance_statistics_monthly.yml b/config/metrics/counts_28d/20210216175012_i_analytics_instance_statistics_monthly.yml
index b46687608b4..b2e6ce34d2e 100644
--- a/config/metrics/counts_28d/20210216175012_i_analytics_instance_statistics_monthly.yml
+++ b/config/metrics/counts_28d/20210216175012_i_analytics_instance_statistics_monthly.yml
@@ -5,18 +5,21 @@ description: Unique visitors to /admin/usage_trends by month
product_section: dev
product_stage: manage
product_group: group::optimize
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_analytics_instance_statistics
+ - i_analytics_instance_statistics
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175016_analytics_total_unique_counts_monthly.yml b/config/metrics/counts_28d/20210216175016_analytics_total_unique_counts_monthly.yml
index fa71e5607c1..1e3fd72fb55 100644
--- a/config/metrics/counts_28d/20210216175016_analytics_total_unique_counts_monthly.yml
+++ b/config/metrics/counts_28d/20210216175016_analytics_total_unique_counts_monthly.yml
@@ -7,32 +7,35 @@ product_stage: manage
product_group: group::optimize
product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - users_viewing_analytics_group_devops_adoption
- - i_analytics_dev_ops_adoption
- - i_analytics_dev_ops_score
- - p_analytics_merge_request
- - i_analytics_instance_statistics
- - g_analytics_contribution
- - g_analytics_insights
- - g_analytics_issues
- - g_analytics_productivity
- - g_analytics_valuestream
- - p_analytics_pipelines
- - p_analytics_code_reviews
- - p_analytics_valuestream
- - p_analytics_insights
- - p_analytics_issues
- - p_analytics_repo
- - i_analytics_cohorts
+ - users_viewing_analytics_group_devops_adoption
+ - i_analytics_dev_ops_adoption
+ - i_analytics_dev_ops_score
+ - p_analytics_merge_request
+ - i_analytics_instance_statistics
+ - g_analytics_contribution
+ - g_analytics_insights
+ - g_analytics_issues
+ - g_analytics_productivity
+ - g_analytics_valuestream
+ - p_analytics_pipelines
+ - p_analytics_code_reviews
+ - p_analytics_valuestream
+ - p_analytics_insights
+ - p_analytics_issues
+ - p_analytics_repo
+ - i_analytics_cohorts
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175055_merge_requests.yml b/config/metrics/counts_28d/20210216175055_merge_requests.yml
index 97e1983b5d6..dca4f81eeea 100644
--- a/config/metrics/counts_28d/20210216175055_merge_requests.yml
+++ b/config/metrics/counts_28d/20210216175055_merge_requests.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175057_projects_with_disable_overriding_approvers_per_merge_request.yml b/config/metrics/counts_28d/20210216175057_projects_with_disable_overriding_approvers_per_merge_request.yml
index 921ab4885fa..e3ba4019000 100644
--- a/config/metrics/counts_28d/20210216175057_projects_with_disable_overriding_approvers_per_merge_request.yml
+++ b/config/metrics/counts_28d/20210216175057_projects_with_disable_overriding_approvers_per_merge_request.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.create.projects_with_disable_overriding_approvers_per_merge_request
-description: Count of the number of projects with setting to disable overriding approvers per merge request
+description: Count of the number of projects with setting to disable overriding approvers
+ per merge request
product_section: dev
product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175059_projects_without_disable_overriding_approvers_per_merge_request.yml b/config/metrics/counts_28d/20210216175059_projects_without_disable_overriding_approvers_per_merge_request.yml
index b86af740a13..eaf3bc545c0 100644
--- a/config/metrics/counts_28d/20210216175059_projects_without_disable_overriding_approvers_per_merge_request.yml
+++ b/config/metrics/counts_28d/20210216175059_projects_without_disable_overriding_approvers_per_merge_request.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.create.projects_without_disable_overriding_approvers_per_merge_request
-description: Count of the number of projects without setting to disable overriding approvers per merge request
+description: Count of the number of projects without setting to disable overriding
+ approvers per merge request
product_section: dev
product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175101_merge_requests_users.yml b/config/metrics/counts_28d/20210216175101_merge_requests_users.yml
index 6cdb30a18bf..04f0f124e8f 100644
--- a/config/metrics/counts_28d/20210216175101_merge_requests_users.yml
+++ b/config/metrics/counts_28d/20210216175101_merge_requests_users.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
distribution:
@@ -20,3 +20,4 @@ tier:
performance_indicator_type:
- gmau
- paid_gmau
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175109_suggestions.yml b/config/metrics/counts_28d/20210216175109_suggestions.yml
index 6b41d92d91f..fcccc350252 100644
--- a/config/metrics/counts_28d/20210216175109_suggestions.yml
+++ b/config/metrics/counts_28d/20210216175109_suggestions.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.create.suggestions
-description: Count of unique users per month who create suggestions in merge request comments
+description: Count of unique users per month who create suggestions in merge request
+ comments
product_section: dev
product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175113_merge_request_action_monthly.yml b/config/metrics/counts_28d/20210216175113_merge_request_action_monthly.yml
index 2db087832d0..abd5157271a 100644
--- a/config/metrics/counts_28d/20210216175113_merge_request_action_monthly.yml
+++ b/config/metrics/counts_28d/20210216175113_merge_request_action_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175117_i_source_code_code_intelligence_monthly.yml b/config/metrics/counts_28d/20210216175117_i_source_code_code_intelligence_monthly.yml
index be85a73c7fa..aa0c6e6136c 100644
--- a/config/metrics/counts_28d/20210216175117_i_source_code_code_intelligence_monthly.yml
+++ b/config/metrics/counts_28d/20210216175117_i_source_code_code_intelligence_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175120_i_code_review_mr_diffs_monthly.yml b/config/metrics/counts_28d/20210216175120_i_code_review_mr_diffs_monthly.yml
index 18b89a5b25a..9ca7370c953 100644
--- a/config/metrics/counts_28d/20210216175120_i_code_review_mr_diffs_monthly.yml
+++ b/config/metrics/counts_28d/20210216175120_i_code_review_mr_diffs_monthly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_mr_diffs
+ - i_code_review_mr_diffs
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175124_i_code_review_user_single_file_diffs_monthly.yml b/config/metrics/counts_28d/20210216175124_i_code_review_user_single_file_diffs_monthly.yml
index b518c040926..62cbdb0feb5 100644
--- a/config/metrics/counts_28d/20210216175124_i_code_review_user_single_file_diffs_monthly.yml
+++ b/config/metrics/counts_28d/20210216175124_i_code_review_user_single_file_diffs_monthly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_single_file_diffs
+ - i_code_review_user_single_file_diffs
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175128_i_code_review_mr_single_file_diffs_monthly.yml b/config/metrics/counts_28d/20210216175128_i_code_review_mr_single_file_diffs_monthly.yml
index c256637f367..67955a7d32b 100644
--- a/config/metrics/counts_28d/20210216175128_i_code_review_mr_single_file_diffs_monthly.yml
+++ b/config/metrics/counts_28d/20210216175128_i_code_review_mr_single_file_diffs_monthly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_mr_single_file_diffs
+ - i_code_review_mr_single_file_diffs
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175132_i_code_review_user_create_mr_monthly.yml b/config/metrics/counts_28d/20210216175132_i_code_review_user_create_mr_monthly.yml
index 013f185730a..c88cff6b2f9 100644
--- a/config/metrics/counts_28d/20210216175132_i_code_review_user_create_mr_monthly.yml
+++ b/config/metrics/counts_28d/20210216175132_i_code_review_user_create_mr_monthly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_create_mr
+ - i_code_review_user_create_mr
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175136_i_code_review_user_close_mr_monthly.yml b/config/metrics/counts_28d/20210216175136_i_code_review_user_close_mr_monthly.yml
index 744afd9809b..df3a461d7c8 100644
--- a/config/metrics/counts_28d/20210216175136_i_code_review_user_close_mr_monthly.yml
+++ b/config/metrics/counts_28d/20210216175136_i_code_review_user_close_mr_monthly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_close_mr
+ - i_code_review_user_close_mr
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175140_i_code_review_user_reopen_mr_monthly.yml b/config/metrics/counts_28d/20210216175140_i_code_review_user_reopen_mr_monthly.yml
index 45f5b8e6dac..a1b8c4037be 100644
--- a/config/metrics/counts_28d/20210216175140_i_code_review_user_reopen_mr_monthly.yml
+++ b/config/metrics/counts_28d/20210216175140_i_code_review_user_reopen_mr_monthly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_reopen_mr
+ - i_code_review_user_reopen_mr
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175144_i_code_review_user_merge_mr_monthly.yml b/config/metrics/counts_28d/20210216175144_i_code_review_user_merge_mr_monthly.yml
index 4a7035c3ee1..98e413605f0 100644
--- a/config/metrics/counts_28d/20210216175144_i_code_review_user_merge_mr_monthly.yml
+++ b/config/metrics/counts_28d/20210216175144_i_code_review_user_merge_mr_monthly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_merge_mr
+ - i_code_review_user_merge_mr
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175148_i_code_review_user_create_mr_comment_monthly.yml b/config/metrics/counts_28d/20210216175148_i_code_review_user_create_mr_comment_monthly.yml
index 8fd9dd97780..c968aee2190 100644
--- a/config/metrics/counts_28d/20210216175148_i_code_review_user_create_mr_comment_monthly.yml
+++ b/config/metrics/counts_28d/20210216175148_i_code_review_user_create_mr_comment_monthly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_create_mr_comment
+ - i_code_review_user_create_mr_comment
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175152_i_code_review_user_edit_mr_comment_monthly.yml b/config/metrics/counts_28d/20210216175152_i_code_review_user_edit_mr_comment_monthly.yml
index 693e7075104..f82608a637c 100644
--- a/config/metrics/counts_28d/20210216175152_i_code_review_user_edit_mr_comment_monthly.yml
+++ b/config/metrics/counts_28d/20210216175152_i_code_review_user_edit_mr_comment_monthly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_edit_mr_comment
+ - i_code_review_user_edit_mr_comment
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175156_i_code_review_user_remove_mr_comment_monthly.yml b/config/metrics/counts_28d/20210216175156_i_code_review_user_remove_mr_comment_monthly.yml
index 80d47f52583..056b7d70e47 100644
--- a/config/metrics/counts_28d/20210216175156_i_code_review_user_remove_mr_comment_monthly.yml
+++ b/config/metrics/counts_28d/20210216175156_i_code_review_user_remove_mr_comment_monthly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_remove_mr_comment
+ - i_code_review_user_remove_mr_comment
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175159_i_code_review_user_add_suggestion_monthly.yml b/config/metrics/counts_28d/20210216175159_i_code_review_user_add_suggestion_monthly.yml
index a92186f2678..03a0a97423b 100644
--- a/config/metrics/counts_28d/20210216175159_i_code_review_user_add_suggestion_monthly.yml
+++ b/config/metrics/counts_28d/20210216175159_i_code_review_user_add_suggestion_monthly.yml
@@ -7,17 +7,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_add_suggestion
+ - i_code_review_user_add_suggestion
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175203_i_code_review_user_apply_suggestion_monthly.yml b/config/metrics/counts_28d/20210216175203_i_code_review_user_apply_suggestion_monthly.yml
index 468b1062365..483d06265fc 100644
--- a/config/metrics/counts_28d/20210216175203_i_code_review_user_apply_suggestion_monthly.yml
+++ b/config/metrics/counts_28d/20210216175203_i_code_review_user_apply_suggestion_monthly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_apply_suggestion
+ - i_code_review_user_apply_suggestion
distribution:
- ce
- ee
@@ -21,3 +21,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175405_clusters_applications_cert_managers.yml b/config/metrics/counts_28d/20210216175405_clusters_applications_cert_managers.yml
index 4637648ce92..a34c679e919 100644
--- a/config/metrics/counts_28d/20210216175405_clusters_applications_cert_managers.yml
+++ b/config/metrics/counts_28d/20210216175405_clusters_applications_cert_managers.yml
@@ -1,15 +1,15 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.configure.clusters_applications_cert_managers
-description: Total GitLab Managed clusters with Cert Manager enabled
+description: Count user ids from GitLab Managed clusters with Cert Manager enabled
product_section: ops
product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,6 +17,6 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
-name: "count_distinct_user_id_from_<adjective describing: '(clusters_applications_cert_managers.status IN (3, 5))'>_clusters_<with>_<adjective describing: '(clusters_applications_cert_managers.status IN (3, 5))'>_clusters_applications_cert_managers"
+name: 'count_distinct_user_id_from_clusters_applications_cert_managers'
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175407_clusters_applications_helm.yml b/config/metrics/counts_28d/20210216175407_clusters_applications_helm.yml
index 9e092d6f2e3..2cc0e937d92 100644
--- a/config/metrics/counts_28d/20210216175407_clusters_applications_helm.yml
+++ b/config/metrics/counts_28d/20210216175407_clusters_applications_helm.yml
@@ -1,15 +1,15 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.configure.clusters_applications_helm
-description: Total GitLab Managed clusters with Helm enabled
+description: Count user ids from GitLab Managed clusters with Helm enabled
product_section: ops
product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,6 +17,6 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
-name: "count_distinct_user_id_from_<adjective describing: '(clusters_applications_helm.status IN (3, 5))'>_clusters_<with>_<adjective describing: '(clusters_applications_helm.status IN (3, 5))'>_clusters_applications_helm"
+name: 'count_distinct_user_id_from_clusters_applications_helm'
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175409_clusters_applications_ingress.yml b/config/metrics/counts_28d/20210216175409_clusters_applications_ingress.yml
index 56ee17554eb..2cdd680eaee 100644
--- a/config/metrics/counts_28d/20210216175409_clusters_applications_ingress.yml
+++ b/config/metrics/counts_28d/20210216175409_clusters_applications_ingress.yml
@@ -1,15 +1,15 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.configure.clusters_applications_ingress
-description: Total GitLab Managed clusters with Ingress enabled
+description: Count user ids from GitLab Managed clusters with Ingress enabled
product_section: ops
product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,6 +17,6 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
-name: "count_distinct_user_id_from_<adjective describing: '(clusters_applications_ingress.status IN (3, 5))'>_clusters_<with>_<adjective describing: '(clusters_applications_ingress.status IN (3, 5))'>_clusters_applications_ingress"
+name: 'count_distinct_user_id_from_clusters_applications_ingress'
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175411_clusters_applications_knative.yml b/config/metrics/counts_28d/20210216175411_clusters_applications_knative.yml
index 3bed0406dd5..23114b91d1f 100644
--- a/config/metrics/counts_28d/20210216175411_clusters_applications_knative.yml
+++ b/config/metrics/counts_28d/20210216175411_clusters_applications_knative.yml
@@ -1,15 +1,15 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.configure.clusters_applications_knative
-description: Total GitLab Managed clusters with Knative enabled
+description: Count user ids from GitLab Managed clusters with Knative enabled
product_section: ops
product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,6 +17,6 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
-name: "count_distinct_user_id_from_<adjective describing: '(clusters_applications_knative.status IN (3, 5))'>_clusters_<with>_<adjective describing: '(clusters_applications_knative.status IN (3, 5))'>_clusters_applications_knative"
+name: 'count_distinct_user_id_from_clusters_applications_knative'
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175413_clusters_management_project.yml b/config/metrics/counts_28d/20210216175413_clusters_management_project.yml
index 6e7f851eb6d..0d908d3c45d 100644
--- a/config/metrics/counts_28d/20210216175413_clusters_management_project.yml
+++ b/config/metrics/counts_28d/20210216175413_clusters_management_project.yml
@@ -1,14 +1,15 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.configure.clusters_management_project
-name: "count_distinct_user_id_from_management_project_clusters"
-description: Number of Kubernetes clusters with clusters management project being set
+name: count_distinct_user_id_from_management_project_clusters
+description: Number of Kubernetes clusters with clusters management project being
+ set
product_section: ops
product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -19,3 +20,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175415_clusters_disabled.yml b/config/metrics/counts_28d/20210216175415_clusters_disabled.yml
index 8c2e9b87870..f6296b5429b 100644
--- a/config/metrics/counts_28d/20210216175415_clusters_disabled.yml
+++ b/config/metrics/counts_28d/20210216175415_clusters_disabled.yml
@@ -1,15 +1,15 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.configure.clusters_disabled
-description: Total GitLab Managed disabled clusters
+description: Number of user ids from GitLab Managed disabled clusters
product_section: ops
product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,6 +17,6 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
-name: "count_distinct_user_id_from_<adjective describing: '(clusters.enabled = FALSE)'>_clusters"
+name: 'count_distinct_user_id_from_disabled_clusters'
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175417_clusters_enabled.yml b/config/metrics/counts_28d/20210216175417_clusters_enabled.yml
index 80e3872ddc3..9df51868bef 100644
--- a/config/metrics/counts_28d/20210216175417_clusters_enabled.yml
+++ b/config/metrics/counts_28d/20210216175417_clusters_enabled.yml
@@ -1,15 +1,15 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.configure.clusters_enabled
-description: Total GitLab Managed clusters currently enabled
+description: Number of distict user ids from GitLab Managed clusters currently enabled
product_section: ops
product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,6 +17,6 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
-name: "count_distinct_user_id_from_<adjective describing: '(clusters.enabled = TRUE)'>_clusters"
+name: 'count_distinct_user_id_from_enabled_clusters'
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175419_clusters_platforms_gke.yml b/config/metrics/counts_28d/20210216175419_clusters_platforms_gke.yml
index 0a2f09a4bc0..9a9db498d6a 100644
--- a/config/metrics/counts_28d/20210216175419_clusters_platforms_gke.yml
+++ b/config/metrics/counts_28d/20210216175419_clusters_platforms_gke.yml
@@ -1,15 +1,15 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.configure.clusters_platforms_gke
-description: Total GitLab Managed clusters provisioned with GitLab on GCE GKE
+description: Number of user ids from GitLab Managed clusters provisioned with GitLab on GCE GKE
product_section: ops
product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,6 +17,6 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
-name: "count_distinct_user_id_from_<adjective describing: '(clusters.provider_type = 1 AND (cluster_providers_gcp.status IN (3)) AND clusters.enabled = TRUE)'>_clusters_<with>_<adjective describing: '(clusters.provider_type = 1 AND (cluster_providers_gcp.status IN (3)) AND clusters.enabled = TRUE)'>_cluster_providers_gcp"
+name: 'count_distinct_user_id_from_cluster_providers_gcp'
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175420_clusters_platforms_eks.yml b/config/metrics/counts_28d/20210216175420_clusters_platforms_eks.yml
index 63da2198876..ff7ab633e81 100644
--- a/config/metrics/counts_28d/20210216175420_clusters_platforms_eks.yml
+++ b/config/metrics/counts_28d/20210216175420_clusters_platforms_eks.yml
@@ -1,15 +1,15 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.configure.clusters_platforms_eks
-description: Total GitLab Managed clusters provisioned with GitLab on AWS EKS
+description: Number of user ids from GitLab Managed clusters provisioned with GitLab on AWS EKS
product_section: ops
product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,6 +17,6 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
-name: "count_distinct_user_id_from_<adjective describing: '(clusters.provider_type = 2 AND (cluster_providers_aws.status IN (3)) AND clusters.enabled = TRUE)'>_clusters_<with>_<adjective describing: '(clusters.provider_type = 2 AND (cluster_providers_aws.status IN (3)) AND clusters.enabled = TRUE)'>_cluster_providers_aws"
+name: 'count_distinct_user_id_from_cluster_providers_aws'
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175422_clusters_platforms_user.yml b/config/metrics/counts_28d/20210216175422_clusters_platforms_user.yml
index 2cb190d348f..c548b9e9eff 100644
--- a/config/metrics/counts_28d/20210216175422_clusters_platforms_user.yml
+++ b/config/metrics/counts_28d/20210216175422_clusters_platforms_user.yml
@@ -1,15 +1,15 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.configure.clusters_platforms_user
-description: Total GitLab Managed clusters that are user provisioned
+description: Number of user ids from GitLab Managed clusters that are user provisioned
product_section: ops
product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,6 +17,6 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
-name: "count_distinct_user_id_from_<adjective describing: '(clusters.provider_type = 0 AND clusters.enabled = TRUE)'>_clusters"
+name: 'count_distinct_user_id_from_user_provisioned_clusters'
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175424_instance_clusters_disabled.yml b/config/metrics/counts_28d/20210216175424_instance_clusters_disabled.yml
index e67abe0543c..7bdb34f236c 100644
--- a/config/metrics/counts_28d/20210216175424_instance_clusters_disabled.yml
+++ b/config/metrics/counts_28d/20210216175424_instance_clusters_disabled.yml
@@ -1,15 +1,15 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.configure.instance_clusters_disabled
-description: Total GitLab Managed disabled clusters attached to the instance
+description: Number of users from GitLab Managed disabled clusters attached to the instance
product_section: ops
product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,6 +17,6 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
-name: "count_distinct_user_id_from_<adjective describing: '(clusters.enabled = FALSE AND clusters.cluster_type = 1)'>_clusters"
+name: 'count_distinct_user_id_from_disabled_clusters_attached_to_instance'
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175426_instance_clusters_enabled.yml b/config/metrics/counts_28d/20210216175426_instance_clusters_enabled.yml
index 44784dbf040..81022cc7411 100644
--- a/config/metrics/counts_28d/20210216175426_instance_clusters_enabled.yml
+++ b/config/metrics/counts_28d/20210216175426_instance_clusters_enabled.yml
@@ -1,15 +1,15 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.configure.instance_clusters_enabled
-description: Total GitLab Managed enabled clusters attached to the instance
+description: Number of user ids from GitLab Managed enabled clusters attached to the instance
product_section: ops
product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,6 +17,6 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
-name: "count_distinct_user_id_from_<adjective describing: '(clusters.enabled = TRUE AND clusters.cluster_type = 1)'>_clusters"
+name: 'count_distinct_user_id_from_enabaled_clusters_attached_to_instance'
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175428_group_clusters_disabled.yml b/config/metrics/counts_28d/20210216175428_group_clusters_disabled.yml
index 61735006560..d38d34867ff 100644
--- a/config/metrics/counts_28d/20210216175428_group_clusters_disabled.yml
+++ b/config/metrics/counts_28d/20210216175428_group_clusters_disabled.yml
@@ -1,15 +1,15 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.configure.group_clusters_disabled
-description: Total GitLab Managed disabled clusters attached to groups
+description: Number of user ids GitLab Managed disabled clusters attached to groups
product_section: ops
product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,6 +17,6 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
-name: "count_distinct_user_id_from_<adjective describing: '(clusters.enabled = FALSE AND clusters.cluster_type = 2)'>_clusters"
+name: 'count_distinct_user_id_from_clusters_attached_to_groups'
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175430_group_clusters_enabled.yml b/config/metrics/counts_28d/20210216175430_group_clusters_enabled.yml
index 3973ddf26b6..9d53421eb69 100644
--- a/config/metrics/counts_28d/20210216175430_group_clusters_enabled.yml
+++ b/config/metrics/counts_28d/20210216175430_group_clusters_enabled.yml
@@ -1,15 +1,15 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.configure.group_clusters_enabled
-description: Total GitLab Managed enabled clusters attached to groups
+description: Count disctinct user ids from GitLab Managed enabled clusters attached to groups
product_section: ops
product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,6 +17,6 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
-name: "count_distinct_user_id_from_<adjective describing: '(clusters.enabled = TRUE AND clusters.cluster_type = 2)'>_clusters"
+name: 'count_distinct_user_id_from_enabled_clusters_attached_to_groups'
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175432_project_clusters_disabled.yml b/config/metrics/counts_28d/20210216175432_project_clusters_disabled.yml
index 17b6fef0151..10806cc50fd 100644
--- a/config/metrics/counts_28d/20210216175432_project_clusters_disabled.yml
+++ b/config/metrics/counts_28d/20210216175432_project_clusters_disabled.yml
@@ -1,15 +1,15 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.configure.project_clusters_disabled
-description: Total GitLab Managed disabled clusters attached to projects
+description: Number of user ids from GitLab Managed disabled clusters attached to projects
product_section: ops
product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,6 +17,6 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
-name: "count_distinct_user_id_from_<adjective describing: '(clusters.enabled = FALSE AND clusters.cluster_type = 3)'>_clusters"
+name: 'count_distinct_user_id_from_disabled_clusters_attached_to_projects'
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175434_project_clusters_enabled.yml b/config/metrics/counts_28d/20210216175434_project_clusters_enabled.yml
index a59cdae01e5..28b81acb709 100644
--- a/config/metrics/counts_28d/20210216175434_project_clusters_enabled.yml
+++ b/config/metrics/counts_28d/20210216175434_project_clusters_enabled.yml
@@ -1,15 +1,15 @@
---
data_category: operational
key_path: usage_activity_by_stage_monthly.configure.project_clusters_enabled
-description: Total GitLab Managed enabled clusters attached to projects
+description: Number of user ids from GitLab Managed enabled clusters attached to projects
product_section: ops
product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,6 +17,6 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
-name: "count_distinct_user_id_from_<adjective describing: '(clusters.enabled = TRUE AND clusters.cluster_type = 3)'>_clusters"
+name: 'count_distinct_user_id_from_enabled_clusters_attached_to_projects'
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175542_ci_builds.yml b/config/metrics/counts_28d/20210216175542_ci_builds.yml
index ac42d618ea0..371da6c937b 100644
--- a/config/metrics/counts_28d/20210216175542_ci_builds.yml
+++ b/config/metrics/counts_28d/20210216175542_ci_builds.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175544_ci_external_pipelines.yml b/config/metrics/counts_28d/20210216175544_ci_external_pipelines.yml
index a3044a7b9aa..b13560ede4c 100644
--- a/config/metrics/counts_28d/20210216175544_ci_external_pipelines.yml
+++ b/config/metrics/counts_28d/20210216175544_ci_external_pipelines.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175546_ci_internal_pipelines.yml b/config/metrics/counts_28d/20210216175546_ci_internal_pipelines.yml
index 2b125cf1a7c..317548c8c24 100644
--- a/config/metrics/counts_28d/20210216175546_ci_internal_pipelines.yml
+++ b/config/metrics/counts_28d/20210216175546_ci_internal_pipelines.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175548_ci_pipeline_config_auto_devops.yml b/config/metrics/counts_28d/20210216175548_ci_pipeline_config_auto_devops.yml
index 8bf228643c8..5c4f21f3b3c 100644
--- a/config/metrics/counts_28d/20210216175548_ci_pipeline_config_auto_devops.yml
+++ b/config/metrics/counts_28d/20210216175548_ci_pipeline_config_auto_devops.yml
@@ -7,7 +7,7 @@ product_stage: configure
product_group: group::configure
product_category: auto_devops
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175550_ci_pipeline_config_repository.yml b/config/metrics/counts_28d/20210216175550_ci_pipeline_config_repository.yml
index dd470b7da22..cd9ed768ce1 100644
--- a/config/metrics/counts_28d/20210216175550_ci_pipeline_config_repository.yml
+++ b/config/metrics/counts_28d/20210216175550_ci_pipeline_config_repository.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175552_ci_pipeline_schedules.yml b/config/metrics/counts_28d/20210216175552_ci_pipeline_schedules.yml
index a593d08a567..75129e5d824 100644
--- a/config/metrics/counts_28d/20210216175552_ci_pipeline_schedules.yml
+++ b/config/metrics/counts_28d/20210216175552_ci_pipeline_schedules.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175554_ci_pipelines.yml b/config/metrics/counts_28d/20210216175554_ci_pipelines.yml
index fdb67b99e55..fb3992a766d 100644
--- a/config/metrics/counts_28d/20210216175554_ci_pipelines.yml
+++ b/config/metrics/counts_28d/20210216175554_ci_pipelines.yml
@@ -1,13 +1,13 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.verify.ci_pipelines
-description: "Distinct users triggering pipelines in a month"
+description: Distinct users triggering pipelines in a month
product_section: ops
product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -22,3 +22,4 @@ performance_indicator_type:
- smau
- gmau
- paid_gmau
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216175556_ci_triggers.yml b/config/metrics/counts_28d/20210216175556_ci_triggers.yml
index a8f784ec579..80842966536 100644
--- a/config/metrics/counts_28d/20210216175556_ci_triggers.yml
+++ b/config/metrics/counts_28d/20210216175556_ci_triggers.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180308_personal_snippets.yml b/config/metrics/counts_28d/20210216180308_personal_snippets.yml
index 1a4183acc62..2416212f1eb 100644
--- a/config/metrics/counts_28d/20210216180308_personal_snippets.yml
+++ b/config/metrics/counts_28d/20210216180308_personal_snippets.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: snippets
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180310_project_snippets.yml b/config/metrics/counts_28d/20210216180310_project_snippets.yml
index 1037c5ed029..4a0a02f701d 100644
--- a/config/metrics/counts_28d/20210216180310_project_snippets.yml
+++ b/config/metrics/counts_28d/20210216180310_project_snippets.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: snippets
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180312_snippets.yml b/config/metrics/counts_28d/20210216180312_snippets.yml
index 22e242d5cab..214ceaa7740 100644
--- a/config/metrics/counts_28d/20210216180312_snippets.yml
+++ b/config/metrics/counts_28d/20210216180312_snippets.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: snippets
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180317_snippets.yml b/config/metrics/counts_28d/20210216180317_snippets.yml
index b501c8dd6d0..a80991452c3 100644
--- a/config/metrics/counts_28d/20210216180317_snippets.yml
+++ b/config/metrics/counts_28d/20210216180317_snippets.yml
@@ -8,7 +8,7 @@ product_stage: create
product_group: group::editor
product_category: snippets
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180319_action_monthly_active_users_web_ide_edit.yml b/config/metrics/counts_28d/20210216180319_action_monthly_active_users_web_ide_edit.yml
index fc52a50969e..b9982520cbc 100644
--- a/config/metrics/counts_28d/20210216180319_action_monthly_active_users_web_ide_edit.yml
+++ b/config/metrics/counts_28d/20210216180319_action_monthly_active_users_web_ide_edit.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: web_ide
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180321_action_monthly_active_users_sfe_edit.yml b/config/metrics/counts_28d/20210216180321_action_monthly_active_users_sfe_edit.yml
index 809f1bcc52f..a3eb1192e49 100644
--- a/config/metrics/counts_28d/20210216180321_action_monthly_active_users_sfe_edit.yml
+++ b/config/metrics/counts_28d/20210216180321_action_monthly_active_users_sfe_edit.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: web_ide
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180323_action_monthly_active_users_snippet_editor_edit.yml b/config/metrics/counts_28d/20210216180323_action_monthly_active_users_snippet_editor_edit.yml
index 6c9bb0319cc..3dc7f774fe2 100644
--- a/config/metrics/counts_28d/20210216180323_action_monthly_active_users_snippet_editor_edit.yml
+++ b/config/metrics/counts_28d/20210216180323_action_monthly_active_users_snippet_editor_edit.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: snippets
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180325_action_monthly_active_users_sse_edit.yml b/config/metrics/counts_28d/20210216180325_action_monthly_active_users_sse_edit.yml
index a181eacd724..eb22e82c62e 100644
--- a/config/metrics/counts_28d/20210216180325_action_monthly_active_users_sse_edit.yml
+++ b/config/metrics/counts_28d/20210216180325_action_monthly_active_users_sse_edit.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: static_site_editor
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180327_action_monthly_active_users_ide_edit.yml b/config/metrics/counts_28d/20210216180327_action_monthly_active_users_ide_edit.yml
index f15f9817a58..b53069b4962 100644
--- a/config/metrics/counts_28d/20210216180327_action_monthly_active_users_ide_edit.yml
+++ b/config/metrics/counts_28d/20210216180327_action_monthly_active_users_ide_edit.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: web_ide
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
distribution:
@@ -20,3 +20,4 @@ tier:
performance_indicator_type:
- gmau
- paid_gmau
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180330_g_edit_by_web_ide_monthly.yml b/config/metrics/counts_28d/20210216180330_g_edit_by_web_ide_monthly.yml
index 770ba30b8a2..2e00a23ca7c 100644
--- a/config/metrics/counts_28d/20210216180330_g_edit_by_web_ide_monthly.yml
+++ b/config/metrics/counts_28d/20210216180330_g_edit_by_web_ide_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: web_ide
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180334_g_edit_by_sfe_monthly.yml b/config/metrics/counts_28d/20210216180334_g_edit_by_sfe_monthly.yml
index 44a6758d41e..88d7c43a90e 100644
--- a/config/metrics/counts_28d/20210216180334_g_edit_by_sfe_monthly.yml
+++ b/config/metrics/counts_28d/20210216180334_g_edit_by_sfe_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: web_ide
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180338_g_edit_by_snippet_ide_monthly.yml b/config/metrics/counts_28d/20210216180338_g_edit_by_snippet_ide_monthly.yml
index 5cc87cba469..78a01d5ef64 100644
--- a/config/metrics/counts_28d/20210216180338_g_edit_by_snippet_ide_monthly.yml
+++ b/config/metrics/counts_28d/20210216180338_g_edit_by_snippet_ide_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: snippets
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180341_ide_edit_total_unique_counts_monthly.yml b/config/metrics/counts_28d/20210216180341_ide_edit_total_unique_counts_monthly.yml
index 81ccdfd0854..ea357356742 100644
--- a/config/metrics/counts_28d/20210216180341_ide_edit_total_unique_counts_monthly.yml
+++ b/config/metrics/counts_28d/20210216180341_ide_edit_total_unique_counts_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: web_ide
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -25,3 +25,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180424_i_search_total_monthly.yml b/config/metrics/counts_28d/20210216180424_i_search_total_monthly.yml
index 89afaa17bce..e85084f25f0 100644
--- a/config/metrics/counts_28d/20210216180424_i_search_total_monthly.yml
+++ b/config/metrics/counts_28d/20210216180424_i_search_total_monthly.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::global search
product_category: global_search
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180431_search_total_unique_counts_monthly.yml b/config/metrics/counts_28d/20210216180431_search_total_unique_counts_monthly.yml
index 41d6d1f0d96..aad1d911a6f 100644
--- a/config/metrics/counts_28d/20210216180431_search_total_unique_counts_monthly.yml
+++ b/config/metrics/counts_28d/20210216180431_search_total_unique_counts_monthly.yml
@@ -1,13 +1,16 @@
---
data_category: optional
key_path: redis_hll_counters.search.search_total_unique_counts_monthly
-description: Total unique users for i_search_total, i_search_advanced, i_search_paid for recent 28 days. This metric is redundant because advanced will be a subset of paid and paid will be a subset of total. i_search_total is more appropriate if you just want the total
+description: Total unique users for i_search_total, i_search_advanced, i_search_paid
+ for recent 28 days. This metric is redundant because advanced will be a subset of
+ paid and paid will be a subset of total. i_search_total is more appropriate if you
+ just want the total
product_section: enablement
product_stage: enablement
product_group: group::global search
product_category: global_search
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -25,3 +28,4 @@ tier:
- ultimate
performance_indicator_type:
- gmau
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180509_incident_management_alerts_total_unique_counts.yml b/config/metrics/counts_28d/20210216180509_incident_management_alerts_total_unique_counts.yml
index 8a76ed1dc22..9bed122a0a5 100644
--- a/config/metrics/counts_28d/20210216180509_incident_management_alerts_total_unique_counts.yml
+++ b/config/metrics/counts_28d/20210216180509_incident_management_alerts_total_unique_counts.yml
@@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180511_incident_management_incidents_total_unique_counts.yml b/config/metrics/counts_28d/20210216180511_incident_management_incidents_total_unique_counts.yml
index c561aafb144..3e0aed47e2d 100644
--- a/config/metrics/counts_28d/20210216180511_incident_management_incidents_total_unique_counts.yml
+++ b/config/metrics/counts_28d/20210216180511_incident_management_incidents_total_unique_counts.yml
@@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180524_projects_with_incidents.yml b/config/metrics/counts_28d/20210216180524_projects_with_incidents.yml
index f9a8a2d440a..c2b1d11d2e9 100644
--- a/config/metrics/counts_28d/20210216180524_projects_with_incidents.yml
+++ b/config/metrics/counts_28d/20210216180524_projects_with_incidents.yml
@@ -1,13 +1,13 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.monitor.projects_with_incidents
-description: 'Count of unique projects with an incident created in the last month'
+description: Count of unique projects with an incident created in the last month
product_section: ops
product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180526_projects_with_alert_incidents.yml b/config/metrics/counts_28d/20210216180526_projects_with_alert_incidents.yml
index 70234ac6602..2d17b84f7de 100644
--- a/config/metrics/counts_28d/20210216180526_projects_with_alert_incidents.yml
+++ b/config/metrics/counts_28d/20210216180526_projects_with_alert_incidents.yml
@@ -1,14 +1,14 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.monitor.projects_with_alert_incidents
-description: 'Count of unique projects with an incident from an alert created in the
- last month'
+description: Count of unique projects with an incident from an alert created in the
+ last month
product_section: ops
product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180530_incident_management_alert_status_changed_monthly.yml b/config/metrics/counts_28d/20210216180530_incident_management_alert_status_changed_monthly.yml
index 5bbb15c786c..23c7b6172fd 100644
--- a/config/metrics/counts_28d/20210216180530_incident_management_alert_status_changed_monthly.yml
+++ b/config/metrics/counts_28d/20210216180530_incident_management_alert_status_changed_monthly.yml
@@ -5,15 +5,15 @@ description: Count of unique users changing alert's status changes per month
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - incident_management_alert_status_changed
+ - incident_management_alert_status_changed
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180533_incident_management_alert_assigned_monthly.yml b/config/metrics/counts_28d/20210216180533_incident_management_alert_assigned_monthly.yml
index a23e14b8879..3d77ae78849 100644
--- a/config/metrics/counts_28d/20210216180533_incident_management_alert_assigned_monthly.yml
+++ b/config/metrics/counts_28d/20210216180533_incident_management_alert_assigned_monthly.yml
@@ -5,15 +5,15 @@ description: Count of unique users assigning an alert per month
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - incident_management_alert_assigned
+ - incident_management_alert_assigned
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180537_incident_management_alert_todo_monthly.yml b/config/metrics/counts_28d/20210216180537_incident_management_alert_todo_monthly.yml
index 4cbc1280562..68a99ecae82 100644
--- a/config/metrics/counts_28d/20210216180537_incident_management_alert_todo_monthly.yml
+++ b/config/metrics/counts_28d/20210216180537_incident_management_alert_todo_monthly.yml
@@ -5,15 +5,15 @@ description: Count of unique users adding alerts to the TODO list per month
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - incident_management_alert_todo
+ - incident_management_alert_todo
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180541_incident_management_incident_created_monthly.yml b/config/metrics/counts_28d/20210216180541_incident_management_incident_created_monthly.yml
index 97680ad4d1b..6df78064a8a 100644
--- a/config/metrics/counts_28d/20210216180541_incident_management_incident_created_monthly.yml
+++ b/config/metrics/counts_28d/20210216180541_incident_management_incident_created_monthly.yml
@@ -5,15 +5,15 @@ description: Count of unique users creating incidents per month
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - incident_management_incident_created
+ - incident_management_incident_created
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180545_incident_management_incident_reopened_monthly.yml b/config/metrics/counts_28d/20210216180545_incident_management_incident_reopened_monthly.yml
index f14f31af62d..1ffce106c7d 100644
--- a/config/metrics/counts_28d/20210216180545_incident_management_incident_reopened_monthly.yml
+++ b/config/metrics/counts_28d/20210216180545_incident_management_incident_reopened_monthly.yml
@@ -5,15 +5,15 @@ description: Count of unique users reopening incidents per month
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - incident_management_incident_reopened
+ - incident_management_incident_reopened
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180548_incident_management_incident_closed_monthly.yml b/config/metrics/counts_28d/20210216180548_incident_management_incident_closed_monthly.yml
index 0809c3fab68..0f02aef017c 100644
--- a/config/metrics/counts_28d/20210216180548_incident_management_incident_closed_monthly.yml
+++ b/config/metrics/counts_28d/20210216180548_incident_management_incident_closed_monthly.yml
@@ -5,15 +5,15 @@ description: Count of users closing incidents per month
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - incident_management_incident_closed
+ - incident_management_incident_closed
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180552_incident_management_incident_assigned_monthly.yml b/config/metrics/counts_28d/20210216180552_incident_management_incident_assigned_monthly.yml
index ceed852b509..6130cb51ef5 100644
--- a/config/metrics/counts_28d/20210216180552_incident_management_incident_assigned_monthly.yml
+++ b/config/metrics/counts_28d/20210216180552_incident_management_incident_assigned_monthly.yml
@@ -5,15 +5,15 @@ description: Count of users assigning incidents per month
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - incident_management_incident_assigned
+ - incident_management_incident_assigned
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180556_incident_management_incident_todo_monthly.yml b/config/metrics/counts_28d/20210216180556_incident_management_incident_todo_monthly.yml
index fbe1a334bbb..a4affa056c9 100644
--- a/config/metrics/counts_28d/20210216180556_incident_management_incident_todo_monthly.yml
+++ b/config/metrics/counts_28d/20210216180556_incident_management_incident_todo_monthly.yml
@@ -5,15 +5,15 @@ description: Count of unique users adding incidents to the TODO list per month
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - incident_management_incident_todo
+ - incident_management_incident_todo
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180559_incident_management_incident_comment_monthly.yml b/config/metrics/counts_28d/20210216180559_incident_management_incident_comment_monthly.yml
index d812b52d97b..4b7880627a2 100644
--- a/config/metrics/counts_28d/20210216180559_incident_management_incident_comment_monthly.yml
+++ b/config/metrics/counts_28d/20210216180559_incident_management_incident_comment_monthly.yml
@@ -5,15 +5,15 @@ description: Count of unique users adding comments per month on incidents
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - incident_management_incident_comment
+ - incident_management_incident_comment
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180603_incident_management_incident_zoom_meeting_monthly.yml b/config/metrics/counts_28d/20210216180603_incident_management_incident_zoom_meeting_monthly.yml
index 313f75f7ebb..11a53605434 100644
--- a/config/metrics/counts_28d/20210216180603_incident_management_incident_zoom_meeting_monthly.yml
+++ b/config/metrics/counts_28d/20210216180603_incident_management_incident_zoom_meeting_monthly.yml
@@ -5,15 +5,15 @@ description: Count of users creating Zoom meetings about incidents per month
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - incident_management_incident_zoom_meeting
+ - incident_management_incident_zoom_meeting
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180611_incident_management_incident_relate_monthly.yml b/config/metrics/counts_28d/20210216180611_incident_management_incident_relate_monthly.yml
index 75c9fa64f8c..ee1e29f0caf 100644
--- a/config/metrics/counts_28d/20210216180611_incident_management_incident_relate_monthly.yml
+++ b/config/metrics/counts_28d/20210216180611_incident_management_incident_relate_monthly.yml
@@ -1,19 +1,20 @@
---
data_category: optional
key_path: redis_hll_counters.incident_management.incident_management_incident_relate_monthly
-description: Count of unique users adding issues per month that are related to an incident
+description: Count of unique users adding issues per month that are related to an
+ incident
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - incident_management_incident_relate
+ - incident_management_incident_relate
distribution:
- ce
- ee
@@ -22,3 +23,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180614_incident_management_incident_unrelate_monthly.yml b/config/metrics/counts_28d/20210216180614_incident_management_incident_unrelate_monthly.yml
index 473b0a2b2ad..b24e653bda5 100644
--- a/config/metrics/counts_28d/20210216180614_incident_management_incident_unrelate_monthly.yml
+++ b/config/metrics/counts_28d/20210216180614_incident_management_incident_unrelate_monthly.yml
@@ -5,15 +5,15 @@ description: Count of users removing issues that are related to an incident per
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - incident_management_incident_unrelate
+ - incident_management_incident_unrelate
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180618_incident_management_incident_change_confidential_monthly.yml b/config/metrics/counts_28d/20210216180618_incident_management_incident_change_confidential_monthly.yml
index 17ab21c9818..78a52e1f4bf 100644
--- a/config/metrics/counts_28d/20210216180618_incident_management_incident_change_confidential_monthly.yml
+++ b/config/metrics/counts_28d/20210216180618_incident_management_incident_change_confidential_monthly.yml
@@ -5,15 +5,15 @@ description: Count of users changing incidents to confidential per month
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - incident_management_incident_change_confidential
+ - incident_management_incident_change_confidential
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180622_incident_management_total_unique_counts_monthly.yml b/config/metrics/counts_28d/20210216180622_incident_management_total_unique_counts_monthly.yml
index 5a09b270eb2..9bc738cee98 100644
--- a/config/metrics/counts_28d/20210216180622_incident_management_total_unique_counts_monthly.yml
+++ b/config/metrics/counts_28d/20210216180622_incident_management_total_unique_counts_monthly.yml
@@ -5,28 +5,28 @@ description: Count of unique users performing events related with incidents per
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - incident_management_incident_created
- - incident_management_incident_reopened
- - incident_management_incident_closed
- - incident_management_incident_assigned
- - incident_management_incident_todo
- - incident_management_incident_comment
- - incident_management_incident_zoom_meeting
- - incident_management_incident_published
- - incident_management_incident_relate
- - incident_management_incident_unrelate
- - incident_management_incident_change_confidential
- - incident_management_alert_status_changed
- - incident_management_alert_assigned
- - incident_management_alert_todo
+ - incident_management_incident_created
+ - incident_management_incident_reopened
+ - incident_management_incident_closed
+ - incident_management_incident_assigned
+ - incident_management_incident_todo
+ - incident_management_incident_comment
+ - incident_management_incident_zoom_meeting
+ - incident_management_incident_published
+ - incident_management_incident_relate
+ - incident_management_incident_unrelate
+ - incident_management_incident_change_confidential
+ - incident_management_alert_status_changed
+ - incident_management_alert_assigned
+ - incident_management_alert_todo
distribution:
- ce
- ee
@@ -38,3 +38,4 @@ performance_indicator_type:
- smau
- gmau
- paid_gmau
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180625_incident_management_alert_create_incident_monthly.yml b/config/metrics/counts_28d/20210216180625_incident_management_alert_create_incident_monthly.yml
index 14ba7fa3421..379f9ec1a3c 100644
--- a/config/metrics/counts_28d/20210216180625_incident_management_alert_create_incident_monthly.yml
+++ b/config/metrics/counts_28d/20210216180625_incident_management_alert_create_incident_monthly.yml
@@ -8,13 +8,13 @@ product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - incident_management_alert_create_incident
+ - incident_management_alert_create_incident
distribution:
- ce
- ee
@@ -23,3 +23,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180731_projects_imported_from_github.yml b/config/metrics/counts_28d/20210216180731_projects_imported_from_github.yml
index 38048e0f443..fd9b3ed719a 100644
--- a/config/metrics/counts_28d/20210216180731_projects_imported_from_github.yml
+++ b/config/metrics/counts_28d/20210216180731_projects_imported_from_github.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180745_action_monthly_active_users_design_management.yml b/config/metrics/counts_28d/20210216180745_action_monthly_active_users_design_management.yml
index beb8969618f..9c2820ce851 100644
--- a/config/metrics/counts_28d/20210216180745_action_monthly_active_users_design_management.yml
+++ b/config/metrics/counts_28d/20210216180745_action_monthly_active_users_design_management.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::product planning
product_category: design_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
distribution:
@@ -19,3 +19,4 @@ tier:
- ultimate
performance_indicator_type:
- paid_gmau
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180747_action_monthly_active_users_wiki_repo.yml b/config/metrics/counts_28d/20210216180747_action_monthly_active_users_wiki_repo.yml
index 1353686c5a6..cc950591e6e 100644
--- a/config/metrics/counts_28d/20210216180747_action_monthly_active_users_wiki_repo.yml
+++ b/config/metrics/counts_28d/20210216180747_action_monthly_active_users_wiki_repo.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: wiki
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180814_events.yml b/config/metrics/counts_28d/20210216180814_events.yml
index ddc06e6c9ea..082dc3b8853 100644
--- a/config/metrics/counts_28d/20210216180814_events.yml
+++ b/config/metrics/counts_28d/20210216180814_events.yml
@@ -1,20 +1,22 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.manage.events
-description:
+description: Number of distinct users who have generated a manage event by month
product_section: dev
-product_stage:
+product_stage: manage
product_group: group::manage
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
-data_source:
+data_source: database
distribution:
- ce
- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type:
- umau
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180816_groups.yml b/config/metrics/counts_28d/20210216180816_groups.yml
index 247fa015c22..600408f92ef 100644
--- a/config/metrics/counts_28d/20210216180816_groups.yml
+++ b/config/metrics/counts_28d/20210216180816_groups.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::access
product_category: subgroups
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180818_users_created.yml b/config/metrics/counts_28d/20210216180818_users_created.yml
index 319b8a08e79..1df17b13891 100644
--- a/config/metrics/counts_28d/20210216180818_users_created.yml
+++ b/config/metrics/counts_28d/20210216180818_users_created.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::access
product_category: users
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180955_projects_with_prometheus_alerts.yml b/config/metrics/counts_28d/20210216180955_projects_with_prometheus_alerts.yml
index 7b928a08fae..a67113825e8 100644
--- a/config/metrics/counts_28d/20210216180955_projects_with_prometheus_alerts.yml
+++ b/config/metrics/counts_28d/20210216180955_projects_with_prometheus_alerts.yml
@@ -3,7 +3,7 @@ data_category: optional
key_path: usage_activity_by_stage_monthly.configure.projects_with_prometheus_alerts
description: Projects with Prometheus alerting enabled
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: metrics
value_type: number
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180956_clusters.yml b/config/metrics/counts_28d/20210216180956_clusters.yml
index d5a54796a1f..6b9015dbdfe 100644
--- a/config/metrics/counts_28d/20210216180956_clusters.yml
+++ b/config/metrics/counts_28d/20210216180956_clusters.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: usage_activity_by_stage_monthly.monitor.clusters
description: Count users creating clusters in last 28 days.
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: metrics
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216180958_clusters_applications_prometheus.yml b/config/metrics/counts_28d/20210216180958_clusters_applications_prometheus.yml
index 615bb247f86..b947a6ff7ea 100644
--- a/config/metrics/counts_28d/20210216180958_clusters_applications_prometheus.yml
+++ b/config/metrics/counts_28d/20210216180958_clusters_applications_prometheus.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: usage_activity_by_stage_monthly.monitor.clusters_applications_prometheus
description: Users creating clusters with Prometheus enabled in last 28 days.
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: metrics
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181000_operations_dashboard_default_dashboard.yml b/config/metrics/counts_28d/20210216181000_operations_dashboard_default_dashboard.yml
index 2d29c9fd088..0870789a515 100644
--- a/config/metrics/counts_28d/20210216181000_operations_dashboard_default_dashboard.yml
+++ b/config/metrics/counts_28d/20210216181000_operations_dashboard_default_dashboard.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: usage_activity_by_stage_monthly.monitor.operations_dashboard_default_dashboard
description: Active users with enabled operations dashboard
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: metrics
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181002_projects_with_tracing_enabled.yml b/config/metrics/counts_28d/20210216181002_projects_with_tracing_enabled.yml
index ac0e6015cb9..60b1ca2b765 100644
--- a/config/metrics/counts_28d/20210216181002_projects_with_tracing_enabled.yml
+++ b/config/metrics/counts_28d/20210216181002_projects_with_tracing_enabled.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: usage_activity_by_stage_monthly.monitor.projects_with_tracing_enabled
description: Projects with tracing enabled
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: tracing
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181004_projects_with_error_tracking_enabled.yml b/config/metrics/counts_28d/20210216181004_projects_with_error_tracking_enabled.yml
index f5c1ecec384..3267d7d4412 100644
--- a/config/metrics/counts_28d/20210216181004_projects_with_error_tracking_enabled.yml
+++ b/config/metrics/counts_28d/20210216181004_projects_with_error_tracking_enabled.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: usage_activity_by_stage_monthly.monitor.projects_with_error_tracking_enabled
description: Count of users creating projects with error tracking enabled.
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: metrics
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181006_operations_dashboard_users_with_projects_added.yml b/config/metrics/counts_28d/20210216181006_operations_dashboard_users_with_projects_added.yml
index 7ffe2e82ab2..612a6f9be40 100644
--- a/config/metrics/counts_28d/20210216181006_operations_dashboard_users_with_projects_added.yml
+++ b/config/metrics/counts_28d/20210216181006_operations_dashboard_users_with_projects_added.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: usage_activity_by_stage_monthly.monitor.operations_dashboard_users_with_projects_added
description: Active users with projects on operations dashboard
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: metrics
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181050_packages.yml b/config/metrics/counts_28d/20210216181050_packages.yml
index c007ab50182..45997bad6f2 100644
--- a/config/metrics/counts_28d/20210216181050_packages.yml
+++ b/config/metrics/counts_28d/20210216181050_packages.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181057_projects_with_packages.yml b/config/metrics/counts_28d/20210216181057_projects_with_packages.yml
index e1f1bcd05e7..3398dacaa92 100644
--- a/config/metrics/counts_28d/20210216181057_projects_with_packages.yml
+++ b/config/metrics/counts_28d/20210216181057_projects_with_packages.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181139_issues.yml b/config/metrics/counts_28d/20210216181139_issues.yml
index dd36265fe9d..84f7f6f4ba8 100644
--- a/config/metrics/counts_28d/20210216181139_issues.yml
+++ b/config/metrics/counts_28d/20210216181139_issues.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
instrumentation_class: CountUsersCreatingIssuesMetric
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181141_notes.yml b/config/metrics/counts_28d/20210216181141_notes.yml
index 0e2d39e42e7..280722a8a1c 100644
--- a/config/metrics/counts_28d/20210216181141_notes.yml
+++ b/config/metrics/counts_28d/20210216181141_notes.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181143_projects.yml b/config/metrics/counts_28d/20210216181143_projects.yml
index 16e2ddf8050..daad51c1409 100644
--- a/config/metrics/counts_28d/20210216181143_projects.yml
+++ b/config/metrics/counts_28d/20210216181143_projects.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: projects
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181145_todos.yml b/config/metrics/counts_28d/20210216181145_todos.yml
index e35963f2a57..ad42b23ceb9 100644
--- a/config/metrics/counts_28d/20210216181145_todos.yml
+++ b/config/metrics/counts_28d/20210216181145_todos.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181147_service_desk_enabled_projects.yml b/config/metrics/counts_28d/20210216181147_service_desk_enabled_projects.yml
index 92f5a618bff..b0f78840daa 100644
--- a/config/metrics/counts_28d/20210216181147_service_desk_enabled_projects.yml
+++ b/config/metrics/counts_28d/20210216181147_service_desk_enabled_projects.yml
@@ -4,10 +4,10 @@ key_path: usage_activity_by_stage_monthly.plan.service_desk_enabled_projects
description: Count creator ids from projects with service desk enabled
product_section: dev
product_stage: plan
-product_group: group::plan
+product_group: group::product planning
product_category: service_desk
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -15,6 +15,7 @@ distribution:
- ee
tier:
- free
-- premium
+- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181148_service_desk_issues.yml b/config/metrics/counts_28d/20210216181148_service_desk_issues.yml
index 0cd2ea2632f..1b5d647fa0d 100644
--- a/config/metrics/counts_28d/20210216181148_service_desk_issues.yml
+++ b/config/metrics/counts_28d/20210216181148_service_desk_issues.yml
@@ -5,9 +5,9 @@ description: Count of service desk issues
product_section: dev
product_stage: plan
product_group: group::plan
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181150_projects_jira_active.yml b/config/metrics/counts_28d/20210216181150_projects_jira_active.yml
index a51dfa3e49f..84edf3f7e9c 100644
--- a/config/metrics/counts_28d/20210216181150_projects_jira_active.yml
+++ b/config/metrics/counts_28d/20210216181150_projects_jira_active.yml
@@ -1,13 +1,13 @@
---
data_category: operational
key_path: usage_activity_by_stage_monthly.plan.projects_jira_active
-description: Distinct count of creator_id from projects with an active Jira integration.
+description: Distinct count of creator_id from projects with an active Jira integration.
product_section: dev
product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181152_projects_jira_dvcs_cloud_active.yml b/config/metrics/counts_28d/20210216181152_projects_jira_dvcs_cloud_active.yml
index e78d178c081..07955a6cad1 100644
--- a/config/metrics/counts_28d/20210216181152_projects_jira_dvcs_cloud_active.yml
+++ b/config/metrics/counts_28d/20210216181152_projects_jira_dvcs_cloud_active.yml
@@ -1,13 +1,14 @@
---
data_category: operational
key_path: usage_activity_by_stage_monthly.plan.projects_jira_dvcs_cloud_active
-description: Distinct count of creator_id from projects with an active Jira Cloud DVCS integration.
+description: Distinct count of creator_id from projects with an active Jira Cloud
+ DVCS integration.
product_section: dev
product_stage: ecosystem
product_group: group::integration
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181154_projects_jira_dvcs_server_active.yml b/config/metrics/counts_28d/20210216181154_projects_jira_dvcs_server_active.yml
index c5a8b0cf75e..e87b69c266b 100644
--- a/config/metrics/counts_28d/20210216181154_projects_jira_dvcs_server_active.yml
+++ b/config/metrics/counts_28d/20210216181154_projects_jira_dvcs_server_active.yml
@@ -1,13 +1,14 @@
---
data_category: operational
key_path: usage_activity_by_stage_monthly.plan.projects_jira_dvcs_server_active
-description: Distinct count of creator_id from projects with an active Jira Server DVCS integration.
+description: Distinct count of creator_id from projects with an active Jira Server
+ DVCS integration.
product_section: dev
product_stage: ecosystem
product_group: group::integration
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,4 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
-
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181158_epics.yml b/config/metrics/counts_28d/20210216181158_epics.yml
index 9ede1ef12f8..59b6cbad145 100644
--- a/config/metrics/counts_28d/20210216181158_epics.yml
+++ b/config/metrics/counts_28d/20210216181158_epics.yml
@@ -4,16 +4,18 @@ key_path: usage_activity_by_stage_monthly.plan.epics
description: Count distinct author ids from epics
product_section: dev
product_stage: plan
-product_group: group::plan
+product_group: group::product planning
product_category: epics
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
- ee
tier:
- premium
+- ultimate
performance_indicator_type:
- gmau
- paid_gmau
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181200_label_lists.yml b/config/metrics/counts_28d/20210216181200_label_lists.yml
index f7eaf2bf484..3b97c6eb94c 100644
--- a/config/metrics/counts_28d/20210216181200_label_lists.yml
+++ b/config/metrics/counts_28d/20210216181200_label_lists.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: boards
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181304_g_project_management_issue_title_changed_monthly.yml b/config/metrics/counts_28d/20210216181304_g_project_management_issue_title_changed_monthly.yml
index 285f8371785..8e2b416af70 100644
--- a/config/metrics/counts_28d/20210216181304_g_project_management_issue_title_changed_monthly.yml
+++ b/config/metrics/counts_28d/20210216181304_g_project_management_issue_title_changed_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_title_changed
+ - g_project_management_issue_title_changed
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181308_g_project_management_issue_description_changed_monthly.yml b/config/metrics/counts_28d/20210216181308_g_project_management_issue_description_changed_monthly.yml
index 554bc86cada..942ad55d540 100644
--- a/config/metrics/counts_28d/20210216181308_g_project_management_issue_description_changed_monthly.yml
+++ b/config/metrics/counts_28d/20210216181308_g_project_management_issue_description_changed_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_description_changed
+ - g_project_management_issue_description_changed
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181311_g_project_management_issue_assignee_changed_monthly.yml b/config/metrics/counts_28d/20210216181311_g_project_management_issue_assignee_changed_monthly.yml
index 07fa4ceaa3c..734da3e5403 100644
--- a/config/metrics/counts_28d/20210216181311_g_project_management_issue_assignee_changed_monthly.yml
+++ b/config/metrics/counts_28d/20210216181311_g_project_management_issue_assignee_changed_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_assignee_changed
+ - g_project_management_issue_assignee_changed
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181315_g_project_management_issue_made_confidential_monthly.yml b/config/metrics/counts_28d/20210216181315_g_project_management_issue_made_confidential_monthly.yml
index 5417ffe2433..45cc0d88c4d 100644
--- a/config/metrics/counts_28d/20210216181315_g_project_management_issue_made_confidential_monthly.yml
+++ b/config/metrics/counts_28d/20210216181315_g_project_management_issue_made_confidential_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_made_confidential
+ - g_project_management_issue_made_confidential
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181319_g_project_management_issue_made_visible_monthly.yml b/config/metrics/counts_28d/20210216181319_g_project_management_issue_made_visible_monthly.yml
index f7c63e9bd03..4109da5e9e1 100644
--- a/config/metrics/counts_28d/20210216181319_g_project_management_issue_made_visible_monthly.yml
+++ b/config/metrics/counts_28d/20210216181319_g_project_management_issue_made_visible_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_made_visible
+ - g_project_management_issue_made_visible
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181323_g_project_management_issue_created_monthly.yml b/config/metrics/counts_28d/20210216181323_g_project_management_issue_created_monthly.yml
index a0b173e5c37..0e8df458927 100644
--- a/config/metrics/counts_28d/20210216181323_g_project_management_issue_created_monthly.yml
+++ b/config/metrics/counts_28d/20210216181323_g_project_management_issue_created_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_created
+ - g_project_management_issue_created
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181326_g_project_management_issue_closed_monthly.yml b/config/metrics/counts_28d/20210216181326_g_project_management_issue_closed_monthly.yml
index 7ff662b2466..3334d9518ef 100644
--- a/config/metrics/counts_28d/20210216181326_g_project_management_issue_closed_monthly.yml
+++ b/config/metrics/counts_28d/20210216181326_g_project_management_issue_closed_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_closed
+ - g_project_management_issue_closed
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181330_g_project_management_issue_reopened_monthly.yml b/config/metrics/counts_28d/20210216181330_g_project_management_issue_reopened_monthly.yml
index f6b3b824afd..66034b7d1e4 100644
--- a/config/metrics/counts_28d/20210216181330_g_project_management_issue_reopened_monthly.yml
+++ b/config/metrics/counts_28d/20210216181330_g_project_management_issue_reopened_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_reopened
+ - g_project_management_issue_reopened
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181334_g_project_management_issue_label_changed_monthly.yml b/config/metrics/counts_28d/20210216181334_g_project_management_issue_label_changed_monthly.yml
index a84dcac22d9..ccb50cc01d5 100644
--- a/config/metrics/counts_28d/20210216181334_g_project_management_issue_label_changed_monthly.yml
+++ b/config/metrics/counts_28d/20210216181334_g_project_management_issue_label_changed_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_label_changed
+ - g_project_management_issue_label_changed
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181337_g_project_management_issue_milestone_changed_monthly.yml b/config/metrics/counts_28d/20210216181337_g_project_management_issue_milestone_changed_monthly.yml
index 12ea62b75f1..0a7d5dc82ee 100644
--- a/config/metrics/counts_28d/20210216181337_g_project_management_issue_milestone_changed_monthly.yml
+++ b/config/metrics/counts_28d/20210216181337_g_project_management_issue_milestone_changed_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_milestone_changed
+ - g_project_management_issue_milestone_changed
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181348_g_project_management_issue_cross_referenced_monthly.yml b/config/metrics/counts_28d/20210216181348_g_project_management_issue_cross_referenced_monthly.yml
index a7f631d6620..b2da497f7bf 100644
--- a/config/metrics/counts_28d/20210216181348_g_project_management_issue_cross_referenced_monthly.yml
+++ b/config/metrics/counts_28d/20210216181348_g_project_management_issue_cross_referenced_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_cross_referenced
+ - g_project_management_issue_cross_referenced
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181352_g_project_management_issue_moved_monthly.yml b/config/metrics/counts_28d/20210216181352_g_project_management_issue_moved_monthly.yml
index 1538b0cc755..a76a89646da 100644
--- a/config/metrics/counts_28d/20210216181352_g_project_management_issue_moved_monthly.yml
+++ b/config/metrics/counts_28d/20210216181352_g_project_management_issue_moved_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_moved
+ - g_project_management_issue_moved
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181356_g_project_management_issue_related_monthly.yml b/config/metrics/counts_28d/20210216181356_g_project_management_issue_related_monthly.yml
index 02926948430..43a3e4a7d46 100644
--- a/config/metrics/counts_28d/20210216181356_g_project_management_issue_related_monthly.yml
+++ b/config/metrics/counts_28d/20210216181356_g_project_management_issue_related_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_related
+ - g_project_management_issue_related
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181400_g_project_management_issue_unrelated_monthly.yml b/config/metrics/counts_28d/20210216181400_g_project_management_issue_unrelated_monthly.yml
index 01c5c768674..db3a3eb2a8f 100644
--- a/config/metrics/counts_28d/20210216181400_g_project_management_issue_unrelated_monthly.yml
+++ b/config/metrics/counts_28d/20210216181400_g_project_management_issue_unrelated_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_unrelated
+ - g_project_management_issue_unrelated
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181403_g_project_management_issue_marked_as_duplicate_monthly.yml b/config/metrics/counts_28d/20210216181403_g_project_management_issue_marked_as_duplicate_monthly.yml
index ca0573ba618..39185b34916 100644
--- a/config/metrics/counts_28d/20210216181403_g_project_management_issue_marked_as_duplicate_monthly.yml
+++ b/config/metrics/counts_28d/20210216181403_g_project_management_issue_marked_as_duplicate_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_marked_as_duplicate
+ - g_project_management_issue_marked_as_duplicate
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181407_g_project_management_issue_locked_monthly.yml b/config/metrics/counts_28d/20210216181407_g_project_management_issue_locked_monthly.yml
index 012eaeb5001..c0d6bb6dd94 100644
--- a/config/metrics/counts_28d/20210216181407_g_project_management_issue_locked_monthly.yml
+++ b/config/metrics/counts_28d/20210216181407_g_project_management_issue_locked_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_locked
+ - g_project_management_issue_locked
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181411_g_project_management_issue_unlocked_monthly.yml b/config/metrics/counts_28d/20210216181411_g_project_management_issue_unlocked_monthly.yml
index a1b800b77cf..927e5abdb69 100644
--- a/config/metrics/counts_28d/20210216181411_g_project_management_issue_unlocked_monthly.yml
+++ b/config/metrics/counts_28d/20210216181411_g_project_management_issue_unlocked_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_unlocked
+ - g_project_management_issue_unlocked
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181424_g_project_management_issue_designs_added_monthly.yml b/config/metrics/counts_28d/20210216181424_g_project_management_issue_designs_added_monthly.yml
index e94d56ad8b8..10a0aa99000 100644
--- a/config/metrics/counts_28d/20210216181424_g_project_management_issue_designs_added_monthly.yml
+++ b/config/metrics/counts_28d/20210216181424_g_project_management_issue_designs_added_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_designs_added
+ - g_project_management_issue_designs_added
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181427_g_project_management_issue_designs_modified_monthly.yml b/config/metrics/counts_28d/20210216181427_g_project_management_issue_designs_modified_monthly.yml
index 0af03218ab0..9583b98427e 100644
--- a/config/metrics/counts_28d/20210216181427_g_project_management_issue_designs_modified_monthly.yml
+++ b/config/metrics/counts_28d/20210216181427_g_project_management_issue_designs_modified_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_designs_modified
+ - g_project_management_issue_designs_modified
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181431_g_project_management_issue_designs_removed_monthly.yml b/config/metrics/counts_28d/20210216181431_g_project_management_issue_designs_removed_monthly.yml
index c466a775050..2df771c4aba 100644
--- a/config/metrics/counts_28d/20210216181431_g_project_management_issue_designs_removed_monthly.yml
+++ b/config/metrics/counts_28d/20210216181431_g_project_management_issue_designs_removed_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_designs_removed
+ - g_project_management_issue_designs_removed
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181435_g_project_management_issue_due_date_changed_monthly.yml b/config/metrics/counts_28d/20210216181435_g_project_management_issue_due_date_changed_monthly.yml
index 29517a25739..5c1d36a2795 100644
--- a/config/metrics/counts_28d/20210216181435_g_project_management_issue_due_date_changed_monthly.yml
+++ b/config/metrics/counts_28d/20210216181435_g_project_management_issue_due_date_changed_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_due_date_changed
+ - g_project_management_issue_due_date_changed
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181438_g_project_management_issue_time_estimate_changed_monthly.yml b/config/metrics/counts_28d/20210216181438_g_project_management_issue_time_estimate_changed_monthly.yml
index 6f572b3a0c9..55ebaaf73bf 100644
--- a/config/metrics/counts_28d/20210216181438_g_project_management_issue_time_estimate_changed_monthly.yml
+++ b/config/metrics/counts_28d/20210216181438_g_project_management_issue_time_estimate_changed_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: time_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_time_estimate_changed
+ - g_project_management_issue_time_estimate_changed
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181442_g_project_management_issue_time_spent_changed_monthly.yml b/config/metrics/counts_28d/20210216181442_g_project_management_issue_time_spent_changed_monthly.yml
index 4c0717f699c..0551e7607ec 100644
--- a/config/metrics/counts_28d/20210216181442_g_project_management_issue_time_spent_changed_monthly.yml
+++ b/config/metrics/counts_28d/20210216181442_g_project_management_issue_time_spent_changed_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: time_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_time_spent_changed
+ - g_project_management_issue_time_spent_changed
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181446_g_project_management_issue_comment_added_monthly.yml b/config/metrics/counts_28d/20210216181446_g_project_management_issue_comment_added_monthly.yml
index dc7775542dd..d6876e29cb4 100644
--- a/config/metrics/counts_28d/20210216181446_g_project_management_issue_comment_added_monthly.yml
+++ b/config/metrics/counts_28d/20210216181446_g_project_management_issue_comment_added_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_comment_added
+ - g_project_management_issue_comment_added
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181450_g_project_management_issue_comment_edited_monthly.yml b/config/metrics/counts_28d/20210216181450_g_project_management_issue_comment_edited_monthly.yml
index 27c18c21b3d..0347b00d871 100644
--- a/config/metrics/counts_28d/20210216181450_g_project_management_issue_comment_edited_monthly.yml
+++ b/config/metrics/counts_28d/20210216181450_g_project_management_issue_comment_edited_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_comment_edited
+ - g_project_management_issue_comment_edited
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181453_g_project_management_issue_comment_removed_monthly.yml b/config/metrics/counts_28d/20210216181453_g_project_management_issue_comment_removed_monthly.yml
index ce0bfa86bcd..f2ef56645a2 100644
--- a/config/metrics/counts_28d/20210216181453_g_project_management_issue_comment_removed_monthly.yml
+++ b/config/metrics/counts_28d/20210216181453_g_project_management_issue_comment_removed_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_comment_removed
+ - g_project_management_issue_comment_removed
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181501_g_project_management_issue_cloned_monthly.yml b/config/metrics/counts_28d/20210216181501_g_project_management_issue_cloned_monthly.yml
index 2d785856ed8..d0da9b74eb8 100644
--- a/config/metrics/counts_28d/20210216181501_g_project_management_issue_cloned_monthly.yml
+++ b/config/metrics/counts_28d/20210216181501_g_project_management_issue_cloned_monthly.yml
@@ -7,13 +7,13 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_cloned
+ - g_project_management_issue_cloned
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181504_issues_edit_total_unique_counts_monthly.yml b/config/metrics/counts_28d/20210216181504_issues_edit_total_unique_counts_monthly.yml
index 5da5997ad67..7d490a3dc95 100644
--- a/config/metrics/counts_28d/20210216181504_issues_edit_total_unique_counts_monthly.yml
+++ b/config/metrics/counts_28d/20210216181504_issues_edit_total_unique_counts_monthly.yml
@@ -7,45 +7,45 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - g_project_management_issue_title_changed
- - g_project_management_issue_description_changed
- - g_project_management_issue_assignee_changed
- - g_project_management_issue_made_confidential
- - g_project_management_issue_made_visible
- - g_project_management_issue_created
- - g_project_management_issue_closed
- - g_project_management_issue_reopened
- - g_project_management_issue_label_changed
- - g_project_management_issue_milestone_changed
- - g_project_management_issue_iteration_changed
- - g_project_management_issue_weight_changed
- - g_project_management_issue_cross_referenced
- - g_project_management_issue_moved
- - g_project_management_issue_related
- - g_project_management_issue_unrelated
- - g_project_management_issue_marked_as_duplicate
- - g_project_management_issue_locked
- - g_project_management_issue_unlocked
- - g_project_management_issue_added_to_epic
- - g_project_management_issue_removed_from_epic
- - g_project_management_issue_changed_epic
- - g_project_management_issue_designs_added
- - g_project_management_issue_designs_modified
- - g_project_management_issue_designs_removed
- - g_project_management_issue_due_date_changed
- - g_project_management_issue_time_estimate_changed
- - g_project_management_issue_time_spent_changed
- - g_project_management_issue_comment_added
- - g_project_management_issue_comment_edited
- - g_project_management_issue_comment_removed
- - g_project_management_issue_health_status_changed
- - g_project_management_issue_cloned
+ - g_project_management_issue_title_changed
+ - g_project_management_issue_description_changed
+ - g_project_management_issue_assignee_changed
+ - g_project_management_issue_made_confidential
+ - g_project_management_issue_made_visible
+ - g_project_management_issue_created
+ - g_project_management_issue_closed
+ - g_project_management_issue_reopened
+ - g_project_management_issue_label_changed
+ - g_project_management_issue_milestone_changed
+ - g_project_management_issue_iteration_changed
+ - g_project_management_issue_weight_changed
+ - g_project_management_issue_cross_referenced
+ - g_project_management_issue_moved
+ - g_project_management_issue_related
+ - g_project_management_issue_unrelated
+ - g_project_management_issue_marked_as_duplicate
+ - g_project_management_issue_locked
+ - g_project_management_issue_unlocked
+ - g_project_management_issue_added_to_epic
+ - g_project_management_issue_removed_from_epic
+ - g_project_management_issue_changed_epic
+ - g_project_management_issue_designs_added
+ - g_project_management_issue_designs_modified
+ - g_project_management_issue_designs_removed
+ - g_project_management_issue_due_date_changed
+ - g_project_management_issue_time_estimate_changed
+ - g_project_management_issue_time_spent_changed
+ - g_project_management_issue_comment_added
+ - g_project_management_issue_comment_edited
+ - g_project_management_issue_comment_removed
+ - g_project_management_issue_health_status_changed
+ - g_project_management_issue_cloned
distribution:
- ce
- ee
@@ -57,3 +57,4 @@ performance_indicator_type:
- smau
- gmau
- paid_gmau
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181508_i_quickactions_approve_monthly.yml b/config/metrics/counts_28d/20210216181508_i_quickactions_approve_monthly.yml
index 452d83dec1b..90bc9ba73d0 100644
--- a/config/metrics/counts_28d/20210216181508_i_quickactions_approve_monthly.yml
+++ b/config/metrics/counts_28d/20210216181508_i_quickactions_approve_monthly.yml
@@ -7,17 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_approve
-instrumentation_class: RedisHLLMetric
-options:
- events:
- - i_quickactions_approve
+ - i_quickactions_approve
distribution:
- ce
- ee
@@ -25,3 +21,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181512_i_quickactions_assign_single_monthly.yml b/config/metrics/counts_28d/20210216181512_i_quickactions_assign_single_monthly.yml
index 1e213eeb778..0c78cd4faa8 100644
--- a/config/metrics/counts_28d/20210216181512_i_quickactions_assign_single_monthly.yml
+++ b/config/metrics/counts_28d/20210216181512_i_quickactions_assign_single_monthly.yml
@@ -1,23 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_assign_single_monthly
-description: Count of MAU using the `/assign @user1` quick action to assign a single individual to an issuable
+description: Count of MAU using the `/assign @user1` quick action to assign a single
+ individual to an issuable
product_section: dev
product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_assign_single
+ - i_quickactions_assign_single
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181519_i_quickactions_assign_self_monthly.yml b/config/metrics/counts_28d/20210216181519_i_quickactions_assign_self_monthly.yml
index 10f38fbcb9c..fde995ff768 100644
--- a/config/metrics/counts_28d/20210216181519_i_quickactions_assign_self_monthly.yml
+++ b/config/metrics/counts_28d/20210216181519_i_quickactions_assign_self_monthly.yml
@@ -1,23 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_assign_self_monthly
-description: Count of MAU using the `/assign me` quick action to assign self to an issuable
+description: Count of MAU using the `/assign me` quick action to assign self to an
+ issuable
product_section: dev
product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_assign_self
+ - i_quickactions_assign_self
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181523_i_quickactions_assign_reviewer_monthly.yml b/config/metrics/counts_28d/20210216181523_i_quickactions_assign_reviewer_monthly.yml
index f9351208172..9eeb21e4c0b 100644
--- a/config/metrics/counts_28d/20210216181523_i_quickactions_assign_reviewer_monthly.yml
+++ b/config/metrics/counts_28d/20210216181523_i_quickactions_assign_reviewer_monthly.yml
@@ -1,23 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_assign_reviewer_monthly
-description: Count of MAU using the `/assign_reviewer` or `request_reviewer` quick action
+description: Count of MAU using the `/assign_reviewer` or `request_reviewer` quick
+ action
product_section: dev
product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_assign_reviewer
+ - i_quickactions_assign_reviewer
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181527_i_quickactions_award_monthly.yml b/config/metrics/counts_28d/20210216181527_i_quickactions_award_monthly.yml
index 90ea87a63cf..6a8564ed981 100644
--- a/config/metrics/counts_28d/20210216181527_i_quickactions_award_monthly.yml
+++ b/config/metrics/counts_28d/20210216181527_i_quickactions_award_monthly.yml
@@ -1,23 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_award_monthly
-description: Count of MAU using the `/award` quick action to set an award emoji on an issuable
+description: Count of MAU using the `/award` quick action to set an award emoji on
+ an issuable
product_section: dev
product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_award
+ - i_quickactions_award
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181530_i_quickactions_board_move_monthly.yml b/config/metrics/counts_28d/20210216181530_i_quickactions_board_move_monthly.yml
index cc86c66caf6..f92880c38eb 100644
--- a/config/metrics/counts_28d/20210216181530_i_quickactions_board_move_monthly.yml
+++ b/config/metrics/counts_28d/20210216181530_i_quickactions_board_move_monthly.yml
@@ -7,17 +7,18 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_board_move
+ - i_quickactions_board_move
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181541_i_quickactions_clone_monthly.yml b/config/metrics/counts_28d/20210216181541_i_quickactions_clone_monthly.yml
index 0f7ad1b15cc..10f4e667e25 100644
--- a/config/metrics/counts_28d/20210216181541_i_quickactions_clone_monthly.yml
+++ b/config/metrics/counts_28d/20210216181541_i_quickactions_clone_monthly.yml
@@ -7,17 +7,18 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_clone
+ - i_quickactions_clone
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181545_i_quickactions_close_monthly.yml b/config/metrics/counts_28d/20210216181545_i_quickactions_close_monthly.yml
index 4750bc1412e..7a41293254e 100644
--- a/config/metrics/counts_28d/20210216181545_i_quickactions_close_monthly.yml
+++ b/config/metrics/counts_28d/20210216181545_i_quickactions_close_monthly.yml
@@ -7,17 +7,18 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_close
+ - i_quickactions_close
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181549_i_quickactions_confidential_monthly.yml b/config/metrics/counts_28d/20210216181549_i_quickactions_confidential_monthly.yml
index 843f00bda28..3c5bdf3a4a3 100644
--- a/config/metrics/counts_28d/20210216181549_i_quickactions_confidential_monthly.yml
+++ b/config/metrics/counts_28d/20210216181549_i_quickactions_confidential_monthly.yml
@@ -1,23 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_confidential_monthly
-description: Count of MAU using the `/confidential` quick action to set an issue as confidential
+description: Count of MAU using the `/confidential` quick action to set an issue as
+ confidential
product_section: dev
product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_confidential
+ - i_quickactions_confidential
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181553_i_quickactions_copy_metadata_merge_request_monthly.yml b/config/metrics/counts_28d/20210216181553_i_quickactions_copy_metadata_merge_request_monthly.yml
index 41e31b3031a..3a9f9f70110 100644
--- a/config/metrics/counts_28d/20210216181553_i_quickactions_copy_metadata_merge_request_monthly.yml
+++ b/config/metrics/counts_28d/20210216181553_i_quickactions_copy_metadata_merge_request_monthly.yml
@@ -7,17 +7,18 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_copy_metadata_merge_request
+ - i_quickactions_copy_metadata_merge_request
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181556_i_quickactions_copy_metadata_issue_monthly.yml b/config/metrics/counts_28d/20210216181556_i_quickactions_copy_metadata_issue_monthly.yml
index 861bb1ac02b..e8266a1989e 100644
--- a/config/metrics/counts_28d/20210216181556_i_quickactions_copy_metadata_issue_monthly.yml
+++ b/config/metrics/counts_28d/20210216181556_i_quickactions_copy_metadata_issue_monthly.yml
@@ -5,19 +5,20 @@ description: Count of MAU using the `/copy_metadata` quick action on an issue
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_copy_metadata_issue
+ - i_quickactions_copy_metadata_issue
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181600_i_quickactions_create_merge_request_monthly.yml b/config/metrics/counts_28d/20210216181600_i_quickactions_create_merge_request_monthly.yml
index ec09f5a3269..5132d880fe8 100644
--- a/config/metrics/counts_28d/20210216181600_i_quickactions_create_merge_request_monthly.yml
+++ b/config/metrics/counts_28d/20210216181600_i_quickactions_create_merge_request_monthly.yml
@@ -1,24 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_create_merge_request_monthly
-description: Count of MAU using the `/create_merge_request` quick action
+description: Count of MAU using the `/create_merge_request` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_create_merge_request
+ - i_quickactions_create_merge_request
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
-
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181604_i_quickactions_done_monthly.yml b/config/metrics/counts_28d/20210216181604_i_quickactions_done_monthly.yml
index 84b7359359a..bd96f6965a0 100644
--- a/config/metrics/counts_28d/20210216181604_i_quickactions_done_monthly.yml
+++ b/config/metrics/counts_28d/20210216181604_i_quickactions_done_monthly.yml
@@ -7,17 +7,18 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_done
+ - i_quickactions_done
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181607_i_quickactions_draft_monthly.yml b/config/metrics/counts_28d/20210216181607_i_quickactions_draft_monthly.yml
index d503f9c56b7..825d8355a70 100644
--- a/config/metrics/counts_28d/20210216181607_i_quickactions_draft_monthly.yml
+++ b/config/metrics/counts_28d/20210216181607_i_quickactions_draft_monthly.yml
@@ -4,20 +4,21 @@ key_path: redis_hll_counters.quickactions.i_quickactions_draft_monthly
description: Count of MAU using the `/draft` quick action on a Merge Request
product_section: dev
product_stage: create
-product_group: group::source code
+product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_draft
+ - i_quickactions_draft
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181611_i_quickactions_due_monthly.yml b/config/metrics/counts_28d/20210216181611_i_quickactions_due_monthly.yml
index d1e18f0e072..a8bcaf7b2c9 100644
--- a/config/metrics/counts_28d/20210216181611_i_quickactions_due_monthly.yml
+++ b/config/metrics/counts_28d/20210216181611_i_quickactions_due_monthly.yml
@@ -1,23 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_due_monthly
-description: Count of MAU using the `/due` quick action to change the due date on an issuable
+description: Count of MAU using the `/due` quick action to change the due date on
+ an issuable
product_section: dev
product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_due
+ - i_quickactions_due
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181615_i_quickactions_duplicate_monthly.yml b/config/metrics/counts_28d/20210216181615_i_quickactions_duplicate_monthly.yml
index eb8e1f504d9..41c067dc88c 100644
--- a/config/metrics/counts_28d/20210216181615_i_quickactions_duplicate_monthly.yml
+++ b/config/metrics/counts_28d/20210216181615_i_quickactions_duplicate_monthly.yml
@@ -1,23 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_duplicate_monthly
-description: Count of MAU using the `/duplicate` quick action to mark an issue as a duplicate of another
+description: Count of MAU using the `/duplicate` quick action to mark an issue as
+ a duplicate of another
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_duplicate
+ - i_quickactions_duplicate
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181622_i_quickactions_estimate_monthly.yml b/config/metrics/counts_28d/20210216181622_i_quickactions_estimate_monthly.yml
index 91c79aff0fe..96a51c514c7 100644
--- a/config/metrics/counts_28d/20210216181622_i_quickactions_estimate_monthly.yml
+++ b/config/metrics/counts_28d/20210216181622_i_quickactions_estimate_monthly.yml
@@ -1,23 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_estimate_monthly
-description: Count of MAU using the `/estimate` quick action to set a time estimate on an issue
+description: Count of MAU using the `/estimate` quick action to set a time estimate
+ on an issue
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: time_tracking
+product_category: time_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_estimate
+ - i_quickactions_estimate
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181629_i_quickactions_label_monthly.yml b/config/metrics/counts_28d/20210216181629_i_quickactions_label_monthly.yml
index 774bcc02bef..3f5fa5396e3 100644
--- a/config/metrics/counts_28d/20210216181629_i_quickactions_label_monthly.yml
+++ b/config/metrics/counts_28d/20210216181629_i_quickactions_label_monthly.yml
@@ -5,19 +5,20 @@ description: Count of MAU using the `/label` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_label
+ - i_quickactions_label
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181633_i_quickactions_lock_monthly.yml b/config/metrics/counts_28d/20210216181633_i_quickactions_lock_monthly.yml
index 13aeb663c87..7b65c2cecbb 100644
--- a/config/metrics/counts_28d/20210216181633_i_quickactions_lock_monthly.yml
+++ b/config/metrics/counts_28d/20210216181633_i_quickactions_lock_monthly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_lock_monthly
-description: Count of MAU using the `/lock` quick action
+description: Count of MAU using the `/lock` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_lock
+ - i_quickactions_lock
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181637_i_quickactions_merge_monthly.yml b/config/metrics/counts_28d/20210216181637_i_quickactions_merge_monthly.yml
index 64f987ae889..2b9c653e31e 100644
--- a/config/metrics/counts_28d/20210216181637_i_quickactions_merge_monthly.yml
+++ b/config/metrics/counts_28d/20210216181637_i_quickactions_merge_monthly.yml
@@ -4,20 +4,21 @@ key_path: redis_hll_counters.quickactions.i_quickactions_merge_monthly
description: Count of MAU using the `/merge` quick action
product_section: dev
product_stage: create
-product_group: group::source code
+product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_merge
+ - i_quickactions_merge
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181641_i_quickactions_milestone_monthly.yml b/config/metrics/counts_28d/20210216181641_i_quickactions_milestone_monthly.yml
index 7865b63c6ea..dca92829b75 100644
--- a/config/metrics/counts_28d/20210216181641_i_quickactions_milestone_monthly.yml
+++ b/config/metrics/counts_28d/20210216181641_i_quickactions_milestone_monthly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_milestone_monthly
-description: Count of MAU using the `/milestone` quick action
-product_section: dev
+description: Count of MAU using the `/milestone` quick action
+product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_milestone
+ - i_quickactions_milestone
distribution:
- ce
- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181644_i_quickactions_move_monthly.yml b/config/metrics/counts_28d/20210216181644_i_quickactions_move_monthly.yml
index d57b4cb31af..20bb3e82ce5 100644
--- a/config/metrics/counts_28d/20210216181644_i_quickactions_move_monthly.yml
+++ b/config/metrics/counts_28d/20210216181644_i_quickactions_move_monthly.yml
@@ -7,17 +7,18 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_move
+ - i_quickactions_move
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181659_i_quickactions_reassign_monthly.yml b/config/metrics/counts_28d/20210216181659_i_quickactions_reassign_monthly.yml
index 5b7a8a6a4c8..06cb49ad587 100644
--- a/config/metrics/counts_28d/20210216181659_i_quickactions_reassign_monthly.yml
+++ b/config/metrics/counts_28d/20210216181659_i_quickactions_reassign_monthly.yml
@@ -5,19 +5,20 @@ description: Count of MAU using the `/reassign @user1` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_reassign
+ - i_quickactions_reassign
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181703_i_quickactions_reassign_reviewer_monthly.yml b/config/metrics/counts_28d/20210216181703_i_quickactions_reassign_reviewer_monthly.yml
index 1da59b2b523..de7bf045dbc 100644
--- a/config/metrics/counts_28d/20210216181703_i_quickactions_reassign_reviewer_monthly.yml
+++ b/config/metrics/counts_28d/20210216181703_i_quickactions_reassign_reviewer_monthly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_reassign_reviewer
+ - i_quickactions_reassign_reviewer
distribution:
- ce
- ee
@@ -21,3 +21,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181707_i_quickactions_rebase_monthly.yml b/config/metrics/counts_28d/20210216181707_i_quickactions_rebase_monthly.yml
index b49f8796179..177be7f33b4 100644
--- a/config/metrics/counts_28d/20210216181707_i_quickactions_rebase_monthly.yml
+++ b/config/metrics/counts_28d/20210216181707_i_quickactions_rebase_monthly.yml
@@ -3,21 +3,22 @@ data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_rebase_monthly
description: Count of MAU using the `/rebase` quick action on a Merge Request
product_section: dev
-product_stage: source_code
-product_group: group::source code
+product_stage: source_code
+product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_rebase
+ - i_quickactions_rebase
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181710_i_quickactions_relabel_monthly.yml b/config/metrics/counts_28d/20210216181710_i_quickactions_relabel_monthly.yml
index 287bb72a37f..bcbee861e6a 100644
--- a/config/metrics/counts_28d/20210216181710_i_quickactions_relabel_monthly.yml
+++ b/config/metrics/counts_28d/20210216181710_i_quickactions_relabel_monthly.yml
@@ -5,19 +5,20 @@ description: Count of MAU using the `/relabel` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_relabel
+ - i_quickactions_relabel
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181714_i_quickactions_relate_monthly.yml b/config/metrics/counts_28d/20210216181714_i_quickactions_relate_monthly.yml
index acaf3378966..e16251e169a 100644
--- a/config/metrics/counts_28d/20210216181714_i_quickactions_relate_monthly.yml
+++ b/config/metrics/counts_28d/20210216181714_i_quickactions_relate_monthly.yml
@@ -5,19 +5,20 @@ description: Count of MAU using the `/relate` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_relate
+ - i_quickactions_relate
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181721_i_quickactions_remove_due_date_monthly.yml b/config/metrics/counts_28d/20210216181721_i_quickactions_remove_due_date_monthly.yml
index 1bf024eb356..f573957f5fd 100644
--- a/config/metrics/counts_28d/20210216181721_i_quickactions_remove_due_date_monthly.yml
+++ b/config/metrics/counts_28d/20210216181721_i_quickactions_remove_due_date_monthly.yml
@@ -5,19 +5,20 @@ description: Count of MAU using the `/remove_due_date` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_remove_due_date
+ - i_quickactions_remove_due_date
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181729_i_quickactions_remove_estimate_monthly.yml b/config/metrics/counts_28d/20210216181729_i_quickactions_remove_estimate_monthly.yml
index 4e878c9c37c..8df0eb3ed73 100644
--- a/config/metrics/counts_28d/20210216181729_i_quickactions_remove_estimate_monthly.yml
+++ b/config/metrics/counts_28d/20210216181729_i_quickactions_remove_estimate_monthly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_remove_estimate_monthly
-description: Count of MAU using the `/remove_estimate` quick action
+description: Count of MAU using the `/remove_estimate` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: time_tracking
+product_category: time_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_remove_estimate
+ - i_quickactions_remove_estimate
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181736_i_quickactions_remove_milestone_monthly.yml b/config/metrics/counts_28d/20210216181736_i_quickactions_remove_milestone_monthly.yml
index d2cd09a7d2b..71f51658ba9 100644
--- a/config/metrics/counts_28d/20210216181736_i_quickactions_remove_milestone_monthly.yml
+++ b/config/metrics/counts_28d/20210216181736_i_quickactions_remove_milestone_monthly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_remove_milestone_monthly
-description: Count of MAU using the `/remove_milestone` quick action
+description: Count of MAU using the `/remove_milestone` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_remove_milestone
+ - i_quickactions_remove_milestone
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181744_i_quickactions_remove_time_spent_monthly.yml b/config/metrics/counts_28d/20210216181744_i_quickactions_remove_time_spent_monthly.yml
index 58f7ef809c4..dae709a56f7 100644
--- a/config/metrics/counts_28d/20210216181744_i_quickactions_remove_time_spent_monthly.yml
+++ b/config/metrics/counts_28d/20210216181744_i_quickactions_remove_time_spent_monthly.yml
@@ -7,17 +7,18 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_remove_time_spent
+ - i_quickactions_remove_time_spent
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181747_i_quickactions_remove_zoom_monthly.yml b/config/metrics/counts_28d/20210216181747_i_quickactions_remove_zoom_monthly.yml
index a9e53de5c8f..fcc00892045 100644
--- a/config/metrics/counts_28d/20210216181747_i_quickactions_remove_zoom_monthly.yml
+++ b/config/metrics/counts_28d/20210216181747_i_quickactions_remove_zoom_monthly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_remove_zoom_monthly
-description: Count of MAU using the `/remove_zoom` quick action
+description: Count of MAU using the `/remove_zoom` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_remove_zoom
+ - i_quickactions_remove_zoom
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
-- ultimate
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181751_i_quickactions_reopen_monthly.yml b/config/metrics/counts_28d/20210216181751_i_quickactions_reopen_monthly.yml
index 6a104d2e1cb..4b9e1af8108 100644
--- a/config/metrics/counts_28d/20210216181751_i_quickactions_reopen_monthly.yml
+++ b/config/metrics/counts_28d/20210216181751_i_quickactions_reopen_monthly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_reopen_monthly
-description: Count of MAU using the `/reopen` quick action
+description: Count of MAU using the `/reopen` quick action
product_section: dev
product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_reopen
+ - i_quickactions_reopen
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181755_i_quickactions_shrug_monthly.yml b/config/metrics/counts_28d/20210216181755_i_quickactions_shrug_monthly.yml
index d4ebe27abec..fb549d259d4 100644
--- a/config/metrics/counts_28d/20210216181755_i_quickactions_shrug_monthly.yml
+++ b/config/metrics/counts_28d/20210216181755_i_quickactions_shrug_monthly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_shrug_monthly
-description: Count of MAU using the `/shrug` quick action
+description: Count of MAU using the `/shrug` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_shrug
+ - i_quickactions_shrug
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181758_i_quickactions_spend_subtract_monthly.yml b/config/metrics/counts_28d/20210216181758_i_quickactions_spend_subtract_monthly.yml
index fb0bfcb8f01..912ea2487be 100644
--- a/config/metrics/counts_28d/20210216181758_i_quickactions_spend_subtract_monthly.yml
+++ b/config/metrics/counts_28d/20210216181758_i_quickactions_spend_subtract_monthly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_spend_subtract_monthly
-description: Count of MAU using the `/spend` quick action to subtract time spent
+description: Count of MAU using the `/spend` quick action to subtract time spent
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: time_tracking
+product_category: time_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_spend_subtract
+ - i_quickactions_spend_subtract
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
-- ultimate \ No newline at end of file
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181802_i_quickactions_spend_add_monthly.yml b/config/metrics/counts_28d/20210216181802_i_quickactions_spend_add_monthly.yml
index dbd94c30488..d6992675957 100644
--- a/config/metrics/counts_28d/20210216181802_i_quickactions_spend_add_monthly.yml
+++ b/config/metrics/counts_28d/20210216181802_i_quickactions_spend_add_monthly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_spend_add_monthly
-description: Count of MAU using the `/spend` quick action to add time spent
+description: Count of MAU using the `/spend` quick action to add time spent
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_spend_add
+ - i_quickactions_spend_add
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181806_i_quickactions_submit_review_monthly.yml b/config/metrics/counts_28d/20210216181806_i_quickactions_submit_review_monthly.yml
index 0058aa315c8..5b2272f09e2 100644
--- a/config/metrics/counts_28d/20210216181806_i_quickactions_submit_review_monthly.yml
+++ b/config/metrics/counts_28d/20210216181806_i_quickactions_submit_review_monthly.yml
@@ -7,17 +7,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_submit_review
+ - i_quickactions_submit_review
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
-- ultimate
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181809_i_quickactions_subscribe_monthly.yml b/config/metrics/counts_28d/20210216181809_i_quickactions_subscribe_monthly.yml
index 7aa266017b4..03be662de07 100644
--- a/config/metrics/counts_28d/20210216181809_i_quickactions_subscribe_monthly.yml
+++ b/config/metrics/counts_28d/20210216181809_i_quickactions_subscribe_monthly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_subscribe_monthly
-description: Count of MAU using the `/subscribe` quick action
+description: Count of MAU using the `/subscribe` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_subscribe
+ - i_quickactions_subscribe
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181813_i_quickactions_tableflip_monthly.yml b/config/metrics/counts_28d/20210216181813_i_quickactions_tableflip_monthly.yml
index c8695b2776e..b7a9bb1b669 100644
--- a/config/metrics/counts_28d/20210216181813_i_quickactions_tableflip_monthly.yml
+++ b/config/metrics/counts_28d/20210216181813_i_quickactions_tableflip_monthly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_tableflip_monthly
-description: Count of MAU using the `/tableflip` quick action
+description: Count of MAU using the `/tableflip` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_tableflip
+ - i_quickactions_tableflip
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
-- ultimate \ No newline at end of file
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181817_i_quickactions_tag_monthly.yml b/config/metrics/counts_28d/20210216181817_i_quickactions_tag_monthly.yml
index de74bb6f7b0..c48efc45953 100644
--- a/config/metrics/counts_28d/20210216181817_i_quickactions_tag_monthly.yml
+++ b/config/metrics/counts_28d/20210216181817_i_quickactions_tag_monthly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_tag_monthly
-description: Count of MAU using the `/tag` quick action
+description: Count of MAU using the `/tag` quick action
product_section: dev
product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_tag
+ - i_quickactions_tag
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181821_i_quickactions_target_branch_monthly.yml b/config/metrics/counts_28d/20210216181821_i_quickactions_target_branch_monthly.yml
index 7de88a30689..372220ae58b 100644
--- a/config/metrics/counts_28d/20210216181821_i_quickactions_target_branch_monthly.yml
+++ b/config/metrics/counts_28d/20210216181821_i_quickactions_target_branch_monthly.yml
@@ -4,20 +4,21 @@ key_path: redis_hll_counters.quickactions.i_quickactions_target_branch_monthly
description: Count of MAU using the `/target_branch` quick action on Merge Requests
product_section: dev
product_stage: create
-product_group: group::source code
+product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_target_branch
+ - i_quickactions_target_branch
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181824_i_quickactions_title_monthly.yml b/config/metrics/counts_28d/20210216181824_i_quickactions_title_monthly.yml
index fb94d9581f8..76004594d85 100644
--- a/config/metrics/counts_28d/20210216181824_i_quickactions_title_monthly.yml
+++ b/config/metrics/counts_28d/20210216181824_i_quickactions_title_monthly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_title_monthly
-description: Count of MAU using the `/title` quick action
+description: Count of MAU using the `/title` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_title
+ - i_quickactions_title
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181828_i_quickactions_todo_monthly.yml b/config/metrics/counts_28d/20210216181828_i_quickactions_todo_monthly.yml
index c101c389dfe..05353f9c3bc 100644
--- a/config/metrics/counts_28d/20210216181828_i_quickactions_todo_monthly.yml
+++ b/config/metrics/counts_28d/20210216181828_i_quickactions_todo_monthly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_todo_monthly
-description: Count of MAU using the `/todo` quick action
+description: Count of MAU using the `/todo` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_todo
+ - i_quickactions_todo
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181832_i_quickactions_unassign_specific_monthly.yml b/config/metrics/counts_28d/20210216181832_i_quickactions_unassign_specific_monthly.yml
index 98e0b1bdff3..095e11f90dd 100644
--- a/config/metrics/counts_28d/20210216181832_i_quickactions_unassign_specific_monthly.yml
+++ b/config/metrics/counts_28d/20210216181832_i_quickactions_unassign_specific_monthly.yml
@@ -7,17 +7,18 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_unassign_specific
+ - i_quickactions_unassign_specific
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181835_i_quickactions_unassign_all_monthly.yml b/config/metrics/counts_28d/20210216181835_i_quickactions_unassign_all_monthly.yml
index 502bc6bccfa..54ed00ab80a 100644
--- a/config/metrics/counts_28d/20210216181835_i_quickactions_unassign_all_monthly.yml
+++ b/config/metrics/counts_28d/20210216181835_i_quickactions_unassign_all_monthly.yml
@@ -7,17 +7,18 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_unassign_all
+ - i_quickactions_unassign_all
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181839_i_quickactions_unassign_reviewer_monthly.yml b/config/metrics/counts_28d/20210216181839_i_quickactions_unassign_reviewer_monthly.yml
index 1e3ea5daac8..f9132b9d641 100644
--- a/config/metrics/counts_28d/20210216181839_i_quickactions_unassign_reviewer_monthly.yml
+++ b/config/metrics/counts_28d/20210216181839_i_quickactions_unassign_reviewer_monthly.yml
@@ -1,23 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_unassign_reviewer_monthly
-description: Count of MAU using the `/unassign_reviewer` or `/remove_reviewer` quick action on Merge Requests
+description: Count of MAU using the `/unassign_reviewer` or `/remove_reviewer` quick
+ action on Merge Requests
product_section: dev
product_stage: create
-product_group: group::code review
+product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_unassign_reviewer
+ - i_quickactions_unassign_reviewer
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181843_i_quickactions_unlabel_specific_monthly.yml b/config/metrics/counts_28d/20210216181843_i_quickactions_unlabel_specific_monthly.yml
index d8f3ece625f..38c44348a4c 100644
--- a/config/metrics/counts_28d/20210216181843_i_quickactions_unlabel_specific_monthly.yml
+++ b/config/metrics/counts_28d/20210216181843_i_quickactions_unlabel_specific_monthly.yml
@@ -1,23 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_unlabel_specific_monthly
-description: Count of MAU using the `/unlabel` or `/remove_label` quick action to remove one or more specific labels
+description: Count of MAU using the `/unlabel` or `/remove_label` quick action to
+ remove one or more specific labels
product_section: dev
product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_unlabel_specific
+ - i_quickactions_unlabel_specific
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181846_i_quickactions_unlabel_all_monthly.yml b/config/metrics/counts_28d/20210216181846_i_quickactions_unlabel_all_monthly.yml
index df3403f9f0a..ce3d14e8906 100644
--- a/config/metrics/counts_28d/20210216181846_i_quickactions_unlabel_all_monthly.yml
+++ b/config/metrics/counts_28d/20210216181846_i_quickactions_unlabel_all_monthly.yml
@@ -7,17 +7,18 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_unlabel_all
+ - i_quickactions_unlabel_all
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181850_i_quickactions_unlock_monthly.yml b/config/metrics/counts_28d/20210216181850_i_quickactions_unlock_monthly.yml
index 4fa69c643c9..0f9c059409c 100644
--- a/config/metrics/counts_28d/20210216181850_i_quickactions_unlock_monthly.yml
+++ b/config/metrics/counts_28d/20210216181850_i_quickactions_unlock_monthly.yml
@@ -7,17 +7,18 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_unlock
+ - i_quickactions_unlock
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181854_i_quickactions_unsubscribe_monthly.yml b/config/metrics/counts_28d/20210216181854_i_quickactions_unsubscribe_monthly.yml
index f3add38826d..585370e1fa2 100644
--- a/config/metrics/counts_28d/20210216181854_i_quickactions_unsubscribe_monthly.yml
+++ b/config/metrics/counts_28d/20210216181854_i_quickactions_unsubscribe_monthly.yml
@@ -7,17 +7,18 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_unsubscribe
+ - i_quickactions_unsubscribe
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181901_i_quickactions_wip_monthly.yml b/config/metrics/counts_28d/20210216181901_i_quickactions_wip_monthly.yml
index 2aa277a0163..fed595813ca 100644
--- a/config/metrics/counts_28d/20210216181901_i_quickactions_wip_monthly.yml
+++ b/config/metrics/counts_28d/20210216181901_i_quickactions_wip_monthly.yml
@@ -4,20 +4,21 @@ key_path: redis_hll_counters.quickactions.i_quickactions_wip_monthly
description: Count of MAU using the `/wip` quick action on Merge Requests
product_section: dev
product_stage: create
-product_group: group::source code
+product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_wip
+ - i_quickactions_wip
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181905_i_quickactions_zoom_monthly.yml b/config/metrics/counts_28d/20210216181905_i_quickactions_zoom_monthly.yml
index b6ff94e5367..d6b8bb2b366 100644
--- a/config/metrics/counts_28d/20210216181905_i_quickactions_zoom_monthly.yml
+++ b/config/metrics/counts_28d/20210216181905_i_quickactions_zoom_monthly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_zoom_monthly
-description: Count of MAU using the `/zoom` quick action on Issues
+description: Count of MAU using the `/zoom` quick action on Issues
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_zoom
+ - i_quickactions_zoom
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181923_successful_deployments.yml b/config/metrics/counts_28d/20210216181923_successful_deployments.yml
index 45b50f20720..2bf7204facc 100644
--- a/config/metrics/counts_28d/20210216181923_successful_deployments.yml
+++ b/config/metrics/counts_28d/20210216181923_successful_deployments.yml
@@ -7,7 +7,7 @@ product_stage: release
product_group: group::release
product_category: continuous_delivery
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181924_failed_deployments.yml b/config/metrics/counts_28d/20210216181924_failed_deployments.yml
index a7f0d6e5847..1a0840f2cee 100644
--- a/config/metrics/counts_28d/20210216181924_failed_deployments.yml
+++ b/config/metrics/counts_28d/20210216181924_failed_deployments.yml
@@ -7,7 +7,7 @@ product_stage: release
product_group: group::release
product_category: continuous_delivery
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181935_deployments.yml b/config/metrics/counts_28d/20210216181935_deployments.yml
index 01978e14de0..24a06991d91 100644
--- a/config/metrics/counts_28d/20210216181935_deployments.yml
+++ b/config/metrics/counts_28d/20210216181935_deployments.yml
@@ -7,7 +7,7 @@ product_stage: release
product_group: group::release
product_category: continuous_delivery
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -16,6 +16,6 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type:
- smau
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181937_failed_deployments.yml b/config/metrics/counts_28d/20210216181937_failed_deployments.yml
index 0bf293cef72..9ef4157ce2d 100644
--- a/config/metrics/counts_28d/20210216181937_failed_deployments.yml
+++ b/config/metrics/counts_28d/20210216181937_failed_deployments.yml
@@ -7,7 +7,7 @@ product_stage: release
product_group: group::release
product_category: continuous_delivery
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181939_releases.yml b/config/metrics/counts_28d/20210216181939_releases.yml
index 858b760e464..87c39db5271 100644
--- a/config/metrics/counts_28d/20210216181939_releases.yml
+++ b/config/metrics/counts_28d/20210216181939_releases.yml
@@ -7,7 +7,7 @@ product_stage: release
product_group: group::release
product_category: continuous_delivery
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -17,7 +17,7 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type:
- gmau
- paid_gmau
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181941_successful_deployments.yml b/config/metrics/counts_28d/20210216181941_successful_deployments.yml
index 1d3a5f23cfd..f21cb609208 100644
--- a/config/metrics/counts_28d/20210216181941_successful_deployments.yml
+++ b/config/metrics/counts_28d/20210216181941_successful_deployments.yml
@@ -7,7 +7,7 @@ product_stage: release
product_group: group::release
product_category: continuous_delivery
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181951_clusters_applications_runner.yml b/config/metrics/counts_28d/20210216181951_clusters_applications_runner.yml
index e515792f124..22702146bc5 100644
--- a/config/metrics/counts_28d/20210216181951_clusters_applications_runner.yml
+++ b/config/metrics/counts_28d/20210216181951_clusters_applications_runner.yml
@@ -7,9 +7,9 @@ product_stage: verify
product_group: group::runner
product_category: runner
value_type: number
-status: data_available
+status: active
time_frame: 28d
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216181956_user_unique_users_all_secure_scanners.yml b/config/metrics/counts_28d/20210216181956_user_unique_users_all_secure_scanners.yml
deleted file mode 100644
index 8c659619dfc..00000000000
--- a/config/metrics/counts_28d/20210216181956_user_unique_users_all_secure_scanners.yml
+++ /dev/null
@@ -1,19 +0,0 @@
----
-data_category: operational
-key_path: usage_activity_by_stage_monthly.secure.user_unique_users_all_secure_scanners
-description:
-product_section: sec
-product_stage:
-product_group: group::secure
-product_category:
-value_type: number
-status: data_available
-time_frame: 28d
-data_source:
-distribution:
-- ce
-tier:
-- free
-skip_validation: true
-performance_indicator_type:
-- smau
diff --git a/config/metrics/counts_28d/20210216182034_deploy_keys.yml b/config/metrics/counts_28d/20210216182034_deploy_keys.yml
index f6949e85a5b..77902b38f6d 100644
--- a/config/metrics/counts_28d/20210216182034_deploy_keys.yml
+++ b/config/metrics/counts_28d/20210216182034_deploy_keys.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216182036_keys.yml b/config/metrics/counts_28d/20210216182036_keys.yml
index ca77b038a1e..63df27fe2e7 100644
--- a/config/metrics/counts_28d/20210216182036_keys.yml
+++ b/config/metrics/counts_28d/20210216182036_keys.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216182038_remote_mirrors.yml b/config/metrics/counts_28d/20210216182038_remote_mirrors.yml
index 340ce92ad80..888a25194b2 100644
--- a/config/metrics/counts_28d/20210216182038_remote_mirrors.yml
+++ b/config/metrics/counts_28d/20210216182038_remote_mirrors.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.create.remote_mirrors
-description: Count of users creating projects with remote mirrors. Includes both push and pull mirrors.
+description: Count of users creating projects with remote mirrors. Includes both push
+ and pull mirrors.
product_section: dev
product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216182040_action_monthly_active_users_project_repo.yml b/config/metrics/counts_28d/20210216182040_action_monthly_active_users_project_repo.yml
index cf40c69e276..71b7af1eace 100644
--- a/config/metrics/counts_28d/20210216182040_action_monthly_active_users_project_repo.yml
+++ b/config/metrics/counts_28d/20210216182040_action_monthly_active_users_project_repo.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
distribution:
@@ -21,3 +21,4 @@ performance_indicator_type:
- smau
- gmau
- paid_gmau
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216182041_action_monthly_active_users_git_write.yml b/config/metrics/counts_28d/20210216182041_action_monthly_active_users_git_write.yml
index a37ec1225ff..28b03586bb8 100644
--- a/config/metrics/counts_28d/20210216182041_action_monthly_active_users_git_write.yml
+++ b/config/metrics/counts_28d/20210216182041_action_monthly_active_users_git_write.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216182051_protected_branches.yml b/config/metrics/counts_28d/20210216182051_protected_branches.yml
index 9e1afb8146c..1e9f66b0d22 100644
--- a/config/metrics/counts_28d/20210216182051_protected_branches.yml
+++ b/config/metrics/counts_28d/20210216182051_protected_branches.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.create.protected_branches
-description: Count of users creating projects with repositories making use of at least one protected branch in last 28 days.
+description: Count of users creating projects with repositories making use of at least
+ one protected branch in last 28 days.
product_section: dev
product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216182102_wiki_action_monthly.yml b/config/metrics/counts_28d/20210216182102_wiki_action_monthly.yml
index b34c2a44a8c..490c2260902 100644
--- a/config/metrics/counts_28d/20210216182102_wiki_action_monthly.yml
+++ b/config/metrics/counts_28d/20210216182102_wiki_action_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216182106_design_action_monthly.yml b/config/metrics/counts_28d/20210216182106_design_action_monthly.yml
index b08d1181b0a..28807011aa2 100644
--- a/config/metrics/counts_28d/20210216182106_design_action_monthly.yml
+++ b/config/metrics/counts_28d/20210216182106_design_action_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216182109_project_action_monthly.yml b/config/metrics/counts_28d/20210216182109_project_action_monthly.yml
index c766eb71596..4ef38c412a5 100644
--- a/config/metrics/counts_28d/20210216182109_project_action_monthly.yml
+++ b/config/metrics/counts_28d/20210216182109_project_action_monthly.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: redis_hll_counters.source_code.project_action_monthly
-description: Count of unique actions done on projects and related resources (create, edit, delete, comment)
+description: Count of unique actions done on projects and related resources (create,
+ edit, delete, comment)
product_section: dev
product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +23,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216182125_user_sast_jobs.yml b/config/metrics/counts_28d/20210216182125_user_sast_jobs.yml
index 7d1f7d333f2..e8d8b469b2e 100644
--- a/config/metrics/counts_28d/20210216182125_user_sast_jobs.yml
+++ b/config/metrics/counts_28d/20210216182125_user_sast_jobs.yml
@@ -7,7 +7,7 @@ product_stage: secure
product_group: group::static analysis
product_category: static_application_security_testing
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -20,3 +20,4 @@ tier:
performance_indicator_type:
- gmau
- paid_gmau
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216182127_user_secret_detection_jobs.yml b/config/metrics/counts_28d/20210216182127_user_secret_detection_jobs.yml
index e600c877c7b..67a1c63b528 100644
--- a/config/metrics/counts_28d/20210216182127_user_secret_detection_jobs.yml
+++ b/config/metrics/counts_28d/20210216182127_user_secret_detection_jobs.yml
@@ -7,7 +7,7 @@ product_stage: secure
product_group: group::static analysis
product_category: secret_detection
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -20,3 +20,4 @@ tier:
performance_indicator_type:
- gmau
- paid_gmau
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216182129_sast_pipeline.yml b/config/metrics/counts_28d/20210216182129_sast_pipeline.yml
index 8d45c304779..2fd7a4bf683 100644
--- a/config/metrics/counts_28d/20210216182129_sast_pipeline.yml
+++ b/config/metrics/counts_28d/20210216182129_sast_pipeline.yml
@@ -7,7 +7,7 @@ product_stage: secure
product_group: group::static analysis
product_category: static_application_security_testing
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216182131_secret_detection_pipeline.yml b/config/metrics/counts_28d/20210216182131_secret_detection_pipeline.yml
index ff1067285de..1690987c446 100644
--- a/config/metrics/counts_28d/20210216182131_secret_detection_pipeline.yml
+++ b/config/metrics/counts_28d/20210216182131_secret_detection_pipeline.yml
@@ -7,7 +7,7 @@ product_stage: secure
product_group: group::static analysis
product_category: secret_detection
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216182136_i_testing_test_case_parsed_monthly.yml b/config/metrics/counts_28d/20210216182136_i_testing_test_case_parsed_monthly.yml
index 396f9534393..72abf0b2165 100644
--- a/config/metrics/counts_28d/20210216182136_i_testing_test_case_parsed_monthly.yml
+++ b/config/metrics/counts_28d/20210216182136_i_testing_test_case_parsed_monthly.yml
@@ -8,13 +8,13 @@ product_stage: verify
product_group: group::testing
product_category: code_testing
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_testing_test_case_parsed
+ - i_testing_test_case_parsed
distribution:
- ce
- ee
@@ -23,3 +23,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183159_projects_with_alerts_created.yml b/config/metrics/counts_28d/20210216183159_projects_with_alerts_created.yml
index 4d09eb0b376..45f136efb76 100644
--- a/config/metrics/counts_28d/20210216183159_projects_with_alerts_created.yml
+++ b/config/metrics/counts_28d/20210216183159_projects_with_alerts_created.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts_monthly.projects_with_alerts_created
description: Monthly count of unique projects with HTTP alerting enabled
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: metrics
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183627_omniauth_providers.yml b/config/metrics/counts_28d/20210216183627_omniauth_providers.yml
index d059bcd8022..54335b419e1 100644
--- a/config/metrics/counts_28d/20210216183627_omniauth_providers.yml
+++ b/config/metrics/counts_28d/20210216183627_omniauth_providers.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::access
product_category: authentication_and_authorization
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183629_two-factor.yml b/config/metrics/counts_28d/20210216183629_two-factor.yml
deleted file mode 100644
index 4d4603818eb..00000000000
--- a/config/metrics/counts_28d/20210216183629_two-factor.yml
+++ /dev/null
@@ -1,18 +0,0 @@
----
-data_category: optional
-key_path: usage_activity_by_stage_monthly.manage.user_auth_by_provider.two-factor
-description: Number of unique user logins using two factor authentication
-product_section: dev
-product_stage: manage
-product_group: group::access
-product_category: authentication_and_authorization
-value_type: number
-status: data_available
-time_frame: 28d
-data_source: database
-distribution:
-- ce
-tier:
-- free
-- premium
-- ultimate
diff --git a/config/metrics/counts_28d/20210216183631_two-factor-via-u2f-device.yml b/config/metrics/counts_28d/20210216183631_two-factor-via-u2f-device.yml
deleted file mode 100644
index fe24823cdd6..00000000000
--- a/config/metrics/counts_28d/20210216183631_two-factor-via-u2f-device.yml
+++ /dev/null
@@ -1,18 +0,0 @@
----
-data_category: optional
-key_path: usage_activity_by_stage_monthly.manage.user_auth_by_provider.two-factor-via-u2f-device
-description: Number of unique user logins using two factor via a U2F device
-product_section: dev
-product_stage: manage
-product_group: group::access
-product_category: authentication_and_authorization
-value_type: number
-status: data_available
-time_frame: 28d
-data_source: database
-distribution:
-- ce
-tier:
-- free
-- premium
-- ultimate
diff --git a/config/metrics/counts_28d/20210216183633_two-factor-via-webauthn-device.yml b/config/metrics/counts_28d/20210216183633_two-factor-via-webauthn-device.yml
deleted file mode 100644
index 95176ccabe5..00000000000
--- a/config/metrics/counts_28d/20210216183633_two-factor-via-webauthn-device.yml
+++ /dev/null
@@ -1,18 +0,0 @@
----
-data_category: optional
-key_path: usage_activity_by_stage_monthly.manage.user_auth_by_provider.two-factor-via-webauthn-device
-description: Number of unique user logins using two factor via a WebAuthn device
-product_section: dev
-product_stage: manage
-product_group: group::access
-product_category: authentication_and_authorization
-value_type: number
-status: data_available
-time_frame: 28d
-data_source: database
-distribution:
-- ce
-tier:
-- free
-- premium
-- ultimate
diff --git a/config/metrics/counts_28d/20210216183634_standard.yml b/config/metrics/counts_28d/20210216183634_standard.yml
deleted file mode 100644
index 172fa780a69..00000000000
--- a/config/metrics/counts_28d/20210216183634_standard.yml
+++ /dev/null
@@ -1,19 +0,0 @@
----
-data_category: optional
-key_path: usage_activity_by_stage_monthly.manage.user_auth_by_provider.standard
-description: Number of unique user logins using password authentication
-product_section: dev
-product_stage: manage
-product_group: group::access
-product_category: authentication_and_authorization
-value_type: number
-status: data_available
-time_frame: 28d
-data_source: database
-distribution:
-- ce
-tier:
-- free
-- premium
-- ultimate
-performance_indicator_type: []
diff --git a/config/metrics/counts_28d/20210216183636_google_oauth2.yml b/config/metrics/counts_28d/20210216183636_google_oauth2.yml
deleted file mode 100644
index 1fdccd17217..00000000000
--- a/config/metrics/counts_28d/20210216183636_google_oauth2.yml
+++ /dev/null
@@ -1,19 +0,0 @@
----
-data_category: optional
-key_path: usage_activity_by_stage_monthly.manage.user_auth_by_provider.google_oauth2
-description: Number of unique user logins using Google OAuth authentication
-product_section: dev
-product_stage: manage
-product_group: group::access
-product_category: authentication_and_authorization
-value_type: number
-status: data_available
-time_frame: 28d
-data_source: database
-distribution:
-- ce
-tier:
-- free
-- premium
-- ultimate
-performance_indicator_type: []
diff --git a/config/metrics/counts_28d/20210216183638_unique_users_all_imports.yml b/config/metrics/counts_28d/20210216183638_unique_users_all_imports.yml
index 063c16fefef..95c4946756c 100644
--- a/config/metrics/counts_28d/20210216183638_unique_users_all_imports.yml
+++ b/config/metrics/counts_28d/20210216183638_unique_users_all_imports.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -20,3 +20,4 @@ tier:
performance_indicator_type:
- gmau
- paid_gmau
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183640_gitlab.yml b/config/metrics/counts_28d/20210216183640_gitlab.yml
index 139184cc8ac..6b074612937 100644
--- a/config/metrics/counts_28d/20210216183640_gitlab.yml
+++ b/config/metrics/counts_28d/20210216183640_gitlab.yml
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183642_gitlab_v1.yml b/config/metrics/counts_28d/20210216183642_gitlab_v1.yml
index dc8dec74ef3..aa1eae2e0c0 100644
--- a/config/metrics/counts_28d/20210216183642_gitlab_v1.yml
+++ b/config/metrics/counts_28d/20210216183642_gitlab_v1.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183644_gitlab_project.yml b/config/metrics/counts_28d/20210216183644_gitlab_project.yml
index 394d85b4863..a370f8d5f52 100644
--- a/config/metrics/counts_28d/20210216183644_gitlab_project.yml
+++ b/config/metrics/counts_28d/20210216183644_gitlab_project.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183646_gitlab.yml b/config/metrics/counts_28d/20210216183646_gitlab.yml
index 84a6387fbf5..a19c8d6ac0e 100644
--- a/config/metrics/counts_28d/20210216183646_gitlab.yml
+++ b/config/metrics/counts_28d/20210216183646_gitlab.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183648_github.yml b/config/metrics/counts_28d/20210216183648_github.yml
index d7ad93520a7..efa4cca301f 100644
--- a/config/metrics/counts_28d/20210216183648_github.yml
+++ b/config/metrics/counts_28d/20210216183648_github.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183650_bitbucket.yml b/config/metrics/counts_28d/20210216183650_bitbucket.yml
index c702f1a065f..5731b6b3cae 100644
--- a/config/metrics/counts_28d/20210216183650_bitbucket.yml
+++ b/config/metrics/counts_28d/20210216183650_bitbucket.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183652_bitbucket_server.yml b/config/metrics/counts_28d/20210216183652_bitbucket_server.yml
index 0781ceca40f..be4e45b8975 100644
--- a/config/metrics/counts_28d/20210216183652_bitbucket_server.yml
+++ b/config/metrics/counts_28d/20210216183652_bitbucket_server.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183653_gitea.yml b/config/metrics/counts_28d/20210216183653_gitea.yml
index f5909eb7475..996749bba7d 100644
--- a/config/metrics/counts_28d/20210216183653_gitea.yml
+++ b/config/metrics/counts_28d/20210216183653_gitea.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183655_git.yml b/config/metrics/counts_28d/20210216183655_git.yml
index 68738e36ddd..20fde277b5d 100644
--- a/config/metrics/counts_28d/20210216183655_git.yml
+++ b/config/metrics/counts_28d/20210216183655_git.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183657_manifest.yml b/config/metrics/counts_28d/20210216183657_manifest.yml
index d93467a3965..00ded898baa 100644
--- a/config/metrics/counts_28d/20210216183657_manifest.yml
+++ b/config/metrics/counts_28d/20210216183657_manifest.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183659_gitlab_migration.yml b/config/metrics/counts_28d/20210216183659_gitlab_migration.yml
index 40f4965f8a0..a27be901a49 100644
--- a/config/metrics/counts_28d/20210216183659_gitlab_migration.yml
+++ b/config/metrics/counts_28d/20210216183659_gitlab_migration.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183701_jira.yml b/config/metrics/counts_28d/20210216183701_jira.yml
index cb6c808fb90..c8f45b9f926 100644
--- a/config/metrics/counts_28d/20210216183701_jira.yml
+++ b/config/metrics/counts_28d/20210216183701_jira.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183703_fogbugz.yml b/config/metrics/counts_28d/20210216183703_fogbugz.yml
index e3369043e74..ea7ecc67a8b 100644
--- a/config/metrics/counts_28d/20210216183703_fogbugz.yml
+++ b/config/metrics/counts_28d/20210216183703_fogbugz.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183705_phabricator.yml b/config/metrics/counts_28d/20210216183705_phabricator.yml
index 57bf3e5abf3..b982bdace5a 100644
--- a/config/metrics/counts_28d/20210216183705_phabricator.yml
+++ b/config/metrics/counts_28d/20210216183705_phabricator.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183707_csv.yml b/config/metrics/counts_28d/20210216183707_csv.yml
index 703edf02f76..a43bc380daa 100644
--- a/config/metrics/counts_28d/20210216183707_csv.yml
+++ b/config/metrics/counts_28d/20210216183707_csv.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183709_group_import.yml b/config/metrics/counts_28d/20210216183709_group_import.yml
index bbe9da3175c..7485b5a0b4a 100644
--- a/config/metrics/counts_28d/20210216183709_group_import.yml
+++ b/config/metrics/counts_28d/20210216183709_group_import.yml
@@ -7,13 +7,14 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
- - ce
- - ee
+- ce
+- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183711_gitlab_migration.yml b/config/metrics/counts_28d/20210216183711_gitlab_migration.yml
index 1a517169eeb..b44b46ddf1d 100644
--- a/config/metrics/counts_28d/20210216183711_gitlab_migration.yml
+++ b/config/metrics/counts_28d/20210216183711_gitlab_migration.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183712_total.yml b/config/metrics/counts_28d/20210216183712_total.yml
index 8942de0f9b8..6df82786097 100644
--- a/config/metrics/counts_28d/20210216183712_total.yml
+++ b/config/metrics/counts_28d/20210216183712_total.yml
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183714_gitlab_project.yml b/config/metrics/counts_28d/20210216183714_gitlab_project.yml
index e8d1204d428..65b7f08ee9b 100644
--- a/config/metrics/counts_28d/20210216183714_gitlab_project.yml
+++ b/config/metrics/counts_28d/20210216183714_gitlab_project.yml
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183716_gitlab.yml b/config/metrics/counts_28d/20210216183716_gitlab.yml
index b5ad788c6d0..78113f063ca 100644
--- a/config/metrics/counts_28d/20210216183716_gitlab.yml
+++ b/config/metrics/counts_28d/20210216183716_gitlab.yml
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183718_github.yml b/config/metrics/counts_28d/20210216183718_github.yml
index a476a103458..caa2602d5fa 100644
--- a/config/metrics/counts_28d/20210216183718_github.yml
+++ b/config/metrics/counts_28d/20210216183718_github.yml
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183720_bitbucket.yml b/config/metrics/counts_28d/20210216183720_bitbucket.yml
index 4c3a0bd3721..c9e54883e3f 100644
--- a/config/metrics/counts_28d/20210216183720_bitbucket.yml
+++ b/config/metrics/counts_28d/20210216183720_bitbucket.yml
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183722_bitbucket_server.yml b/config/metrics/counts_28d/20210216183722_bitbucket_server.yml
index 82bcde1b2ee..7b81f7bf2dd 100644
--- a/config/metrics/counts_28d/20210216183722_bitbucket_server.yml
+++ b/config/metrics/counts_28d/20210216183722_bitbucket_server.yml
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183724_gitea.yml b/config/metrics/counts_28d/20210216183724_gitea.yml
index df1d3c5b012..9a8c27cae3f 100644
--- a/config/metrics/counts_28d/20210216183724_gitea.yml
+++ b/config/metrics/counts_28d/20210216183724_gitea.yml
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183726_git.yml b/config/metrics/counts_28d/20210216183726_git.yml
index 7e711694253..b044fd6f493 100644
--- a/config/metrics/counts_28d/20210216183726_git.yml
+++ b/config/metrics/counts_28d/20210216183726_git.yml
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183728_manifest.yml b/config/metrics/counts_28d/20210216183728_manifest.yml
index 3c935d604fa..56d47b288f3 100644
--- a/config/metrics/counts_28d/20210216183728_manifest.yml
+++ b/config/metrics/counts_28d/20210216183728_manifest.yml
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183730_jira.yml b/config/metrics/counts_28d/20210216183730_jira.yml
index 488b4b4c19e..1a51229d107 100644
--- a/config/metrics/counts_28d/20210216183730_jira.yml
+++ b/config/metrics/counts_28d/20210216183730_jira.yml
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183731_fogbugz.yml b/config/metrics/counts_28d/20210216183731_fogbugz.yml
index 2239c83696d..53cfec950c2 100644
--- a/config/metrics/counts_28d/20210216183731_fogbugz.yml
+++ b/config/metrics/counts_28d/20210216183731_fogbugz.yml
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183733_phabricator.yml b/config/metrics/counts_28d/20210216183733_phabricator.yml
index 903a06793e1..07b95a6066c 100644
--- a/config/metrics/counts_28d/20210216183733_phabricator.yml
+++ b/config/metrics/counts_28d/20210216183733_phabricator.yml
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183735_csv.yml b/config/metrics/counts_28d/20210216183735_csv.yml
index 2890302b24a..afdafb3c507 100644
--- a/config/metrics/counts_28d/20210216183735_csv.yml
+++ b/config/metrics/counts_28d/20210216183735_csv.yml
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183737_groups_imported.yml b/config/metrics/counts_28d/20210216183737_groups_imported.yml
index b2a53befda2..0de2e16e661 100644
--- a/config/metrics/counts_28d/20210216183737_groups_imported.yml
+++ b/config/metrics/counts_28d/20210216183737_groups_imported.yml
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216183826_sast_scans.yml b/config/metrics/counts_28d/20210216183826_sast_scans.yml
deleted file mode 100644
index 0f645f5b1d7..00000000000
--- a/config/metrics/counts_28d/20210216183826_sast_scans.yml
+++ /dev/null
@@ -1,18 +0,0 @@
----
-data_category: operational
-key_path: usage_activity_by_stage_monthly.secure.sast_scans
-description: ''
-product_section: ''
-product_stage: ''
-product_group: ''
-product_category: ''
-value_type: number
-status: data_available
-time_frame: 28d
-data_source:
-distribution:
-- ce
-tier:
-- free
-skip_validation: true
-performance_indicator_type: []
diff --git a/config/metrics/counts_28d/20210216183830_container_scanning_scans.yml b/config/metrics/counts_28d/20210216183830_container_scanning_scans.yml
deleted file mode 100644
index 386c05ea5b2..00000000000
--- a/config/metrics/counts_28d/20210216183830_container_scanning_scans.yml
+++ /dev/null
@@ -1,18 +0,0 @@
----
-data_category: operational
-key_path: usage_activity_by_stage_monthly.secure.container_scanning_scans
-description: ''
-product_section: ''
-product_stage: ''
-product_group: ''
-product_category: ''
-value_type: number
-status: data_available
-time_frame: 28d
-data_source:
-distribution:
-- ce
-tier:
-- free
-skip_validation: true
-performance_indicator_type: []
diff --git a/config/metrics/counts_28d/20210216183834_secret_detection_scans.yml b/config/metrics/counts_28d/20210216183834_secret_detection_scans.yml
deleted file mode 100644
index fda980b8252..00000000000
--- a/config/metrics/counts_28d/20210216183834_secret_detection_scans.yml
+++ /dev/null
@@ -1,18 +0,0 @@
----
-data_category: operational
-key_path: usage_activity_by_stage_monthly.secure.secret_detection_scans
-description: ''
-product_section: ''
-product_stage: ''
-product_group: ''
-product_category: ''
-value_type: number
-status: data_available
-time_frame: 28d
-data_source:
-distribution:
-- ce
-tier:
-- free
-skip_validation: true
-performance_indicator_type: []
diff --git a/config/metrics/counts_28d/20210216183922_search_unique_visits_for_any_target_monthly.yml b/config/metrics/counts_28d/20210216183922_search_unique_visits_for_any_target_monthly.yml
index 3987df0e7eb..b4e45462f71 100644
--- a/config/metrics/counts_28d/20210216183922_search_unique_visits_for_any_target_monthly.yml
+++ b/config/metrics/counts_28d/20210216183922_search_unique_visits_for_any_target_monthly.yml
@@ -1,21 +1,24 @@
---
data_category: optional
key_path: search_unique_visits.search_unique_visits_for_any_target_monthly
-description: Total unique users for i_search_total, i_search_advanced, i_search_paid for recent 28 days. This metric is redundant because advanced will be a subset of paid and paid will be a subset of total. i_search_total is more appropriate if you just want the total
+description: Total unique users for i_search_total, i_search_advanced, i_search_paid
+ for recent 28 days. This metric is redundant because advanced will be a subset of
+ paid and paid will be a subset of total. i_search_total is more appropriate if you
+ just want the total
product_section: enablement
product_stage: enablement
product_group: group::global search
product_category: global_search
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_search_total
- - i_search_advanced
- - i_search_paid
+ - i_search_total
+ - i_search_advanced
+ - i_search_paid
distribution:
- ce
- ee
@@ -23,3 +26,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184024_g_edit_by_sse_monthly.yml b/config/metrics/counts_28d/20210216184024_g_edit_by_sse_monthly.yml
index fe05044105a..1a1fbec4f8c 100644
--- a/config/metrics/counts_28d/20210216184024_g_edit_by_sse_monthly.yml
+++ b/config/metrics/counts_28d/20210216184024_g_edit_by_sse_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: static_site_editor
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184047_git_write_action_monthly.yml b/config/metrics/counts_28d/20210216184047_git_write_action_monthly.yml
index e47c1d8b729..ed703302451 100644
--- a/config/metrics/counts_28d/20210216184047_git_write_action_monthly.yml
+++ b/config/metrics/counts_28d/20210216184047_git_write_action_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184140_testing_total_unique_counts_monthly.yml b/config/metrics/counts_28d/20210216184140_testing_total_unique_counts_monthly.yml
index be9420ef8cd..14042fc25f7 100644
--- a/config/metrics/counts_28d/20210216184140_testing_total_unique_counts_monthly.yml
+++ b/config/metrics/counts_28d/20210216184140_testing_total_unique_counts_monthly.yml
@@ -1,11 +1,11 @@
---
data_category: optional
key_path: redis_hll_counters.testing.testing_total_unique_counts_monthly
-description: ''
-product_section: ''
-product_stage: ''
-product_group: ''
-product_category: ''
+description: Total users for events under testing category
+product_section: devops
+product_section: growth
+product_stage: growth
+product_group: group::product intelligence
value_type: number
status: removed
time_frame: 28d
@@ -13,19 +13,20 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_testing_test_case_parsed
- - i_testing_metrics_report_widget_total
- - i_testing_group_code_coverage_visit_total
- - i_testing_full_code_quality_report_total
- - i_testing_web_performance_widget_total
- - i_testing_group_code_coverage_project_click_total
- - i_testing_load_performance_widget_total
- - i_testing_metrics_report_artifact_uploaders
- - i_testing_summary_widget_total
- - users_expanding_testing_code_quality_report
- - users_expanding_testing_accessibility_report
+ - i_testing_test_case_parsed
+ - i_testing_metrics_report_widget_total
+ - i_testing_group_code_coverage_visit_total
+ - i_testing_full_code_quality_report_total
+ - i_testing_web_performance_widget_total
+ - i_testing_group_code_coverage_project_click_total
+ - i_testing_load_performance_widget_total
+ - i_testing_metrics_report_artifact_uploaders
+ - i_testing_summary_widget_total
+ - users_expanding_testing_code_quality_report
+ - users_expanding_testing_accessibility_report
distribution:
- ce
tier:
- free
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184255_i_snippets_show_monthly.yml b/config/metrics/counts_28d/20210216184255_i_snippets_show_monthly.yml
index 7c0bcbb795b..70fc51b3d43 100644
--- a/config/metrics/counts_28d/20210216184255_i_snippets_show_monthly.yml
+++ b/config/metrics/counts_28d/20210216184255_i_snippets_show_monthly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::editor
product_category: snippets
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_snippets_show
+ - i_snippets_show
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184259_p_terraform_state_api_unique_users_monthly.yml b/config/metrics/counts_28d/20210216184259_p_terraform_state_api_unique_users_monthly.yml
index b3b3c7b6749..4f6aeb09d70 100644
--- a/config/metrics/counts_28d/20210216184259_p_terraform_state_api_unique_users_monthly.yml
+++ b/config/metrics/counts_28d/20210216184259_p_terraform_state_api_unique_users_monthly.yml
@@ -7,13 +7,13 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_terraform_state_api_unique_users
+ - p_terraform_state_api_unique_users
distribution:
- ce
- ee
@@ -25,3 +25,4 @@ performance_indicator_type:
- smau
- gmau
- paid_gmau
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184303_o_pipeline_authoring_unique_users_committing_ciconfigfile_monthly.yml b/config/metrics/counts_28d/20210216184303_o_pipeline_authoring_unique_users_committing_ciconfigfile_monthly.yml
index ca852c74821..6c33950166a 100644
--- a/config/metrics/counts_28d/20210216184303_o_pipeline_authoring_unique_users_committing_ciconfigfile_monthly.yml
+++ b/config/metrics/counts_28d/20210216184303_o_pipeline_authoring_unique_users_committing_ciconfigfile_monthly.yml
@@ -1,19 +1,20 @@
---
data_category: optional
key_path: redis_hll_counters.pipeline_authoring.o_pipeline_authoring_unique_users_committing_ciconfigfile_monthly
-description: Monthly unique user count doing commits which contains the CI config file
+description: Monthly unique user count doing commits which contains the CI config
+ file
product_section: ops
product_stage: verify
product_group: group::pipeline authoring
product_category: pipeline_authoring
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - o_pipeline_authoring_unique_users_committing_ciconfigfile
+ - o_pipeline_authoring_unique_users_committing_ciconfigfile
distribution:
- ee
- ce
@@ -22,3 +23,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184312_i_code_review_user_toggled_task_item_status_monthly.yml b/config/metrics/counts_28d/20210216184312_i_code_review_user_toggled_task_item_status_monthly.yml
index 1307111cc3c..72617203f6a 100644
--- a/config/metrics/counts_28d/20210216184312_i_code_review_user_toggled_task_item_status_monthly.yml
+++ b/config/metrics/counts_28d/20210216184312_i_code_review_user_toggled_task_item_status_monthly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_toggled_task_item_status
+ - i_code_review_user_toggled_task_item_status
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184322_i_code_review_user_approve_mr_monthly.yml b/config/metrics/counts_28d/20210216184322_i_code_review_user_approve_mr_monthly.yml
index a2e858cd886..f3c4a921afa 100644
--- a/config/metrics/counts_28d/20210216184322_i_code_review_user_approve_mr_monthly.yml
+++ b/config/metrics/counts_28d/20210216184322_i_code_review_user_approve_mr_monthly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_approve_mr
+ - i_code_review_user_approve_mr
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184326_i_code_review_user_unapprove_mr_monthly.yml b/config/metrics/counts_28d/20210216184326_i_code_review_user_unapprove_mr_monthly.yml
index 583978e9bd6..ab4d4c1bfc7 100644
--- a/config/metrics/counts_28d/20210216184326_i_code_review_user_unapprove_mr_monthly.yml
+++ b/config/metrics/counts_28d/20210216184326_i_code_review_user_unapprove_mr_monthly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_unapprove_mr
+ - i_code_review_user_unapprove_mr
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184330_i_code_review_user_resolve_thread_monthly.yml b/config/metrics/counts_28d/20210216184330_i_code_review_user_resolve_thread_monthly.yml
index 0828587051e..9f2ab332a08 100644
--- a/config/metrics/counts_28d/20210216184330_i_code_review_user_resolve_thread_monthly.yml
+++ b/config/metrics/counts_28d/20210216184330_i_code_review_user_resolve_thread_monthly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_resolve_thread
+ - i_code_review_user_resolve_thread
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184334_i_code_review_user_unresolve_thread_monthly.yml b/config/metrics/counts_28d/20210216184334_i_code_review_user_unresolve_thread_monthly.yml
index fe195544df4..83644eff397 100644
--- a/config/metrics/counts_28d/20210216184334_i_code_review_user_unresolve_thread_monthly.yml
+++ b/config/metrics/counts_28d/20210216184334_i_code_review_user_unresolve_thread_monthly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_unresolve_thread
+ - i_code_review_user_unresolve_thread
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184338_i_code_review_edit_mr_title_monthly.yml b/config/metrics/counts_28d/20210216184338_i_code_review_edit_mr_title_monthly.yml
index 0bd8573477b..df7acea15f8 100644
--- a/config/metrics/counts_28d/20210216184338_i_code_review_edit_mr_title_monthly.yml
+++ b/config/metrics/counts_28d/20210216184338_i_code_review_edit_mr_title_monthly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_edit_mr_title
+ - i_code_review_edit_mr_title
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184342_i_code_review_edit_mr_desc_monthly.yml b/config/metrics/counts_28d/20210216184342_i_code_review_edit_mr_desc_monthly.yml
index ba30f3aad30..02980ed84f8 100644
--- a/config/metrics/counts_28d/20210216184342_i_code_review_edit_mr_desc_monthly.yml
+++ b/config/metrics/counts_28d/20210216184342_i_code_review_edit_mr_desc_monthly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_edit_mr_desc
+ - i_code_review_edit_mr_desc
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184353_i_code_review_user_create_review_note_monthly.yml b/config/metrics/counts_28d/20210216184353_i_code_review_user_create_review_note_monthly.yml
index f948c01170f..cb0ba9c4785 100644
--- a/config/metrics/counts_28d/20210216184353_i_code_review_user_create_review_note_monthly.yml
+++ b/config/metrics/counts_28d/20210216184353_i_code_review_user_create_review_note_monthly.yml
@@ -1,18 +1,19 @@
---
data_category: optional
key_path: redis_hll_counters.code_review.i_code_review_user_create_review_note_monthly
-description: Count of unique users per month who create a note as part of a merge request review
+description: Count of unique users per month who create a note as part of a merge
+ request review
product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_create_review_note
+ - i_code_review_user_create_review_note
distribution:
- ce
- ee
@@ -21,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184357_i_code_review_user_publish_review_monthly.yml b/config/metrics/counts_28d/20210216184357_i_code_review_user_publish_review_monthly.yml
index 478ae4bef09..78228a1da48 100644
--- a/config/metrics/counts_28d/20210216184357_i_code_review_user_publish_review_monthly.yml
+++ b/config/metrics/counts_28d/20210216184357_i_code_review_user_publish_review_monthly.yml
@@ -1,18 +1,19 @@
---
data_category: optional
key_path: redis_hll_counters.code_review.i_code_review_user_publish_review_monthly
-description: Count of unique users per month who publish their review as part of a merge request review
+description: Count of unique users per month who publish their review as part of a
+ merge request review
product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_publish_review
+ - i_code_review_user_publish_review
distribution:
- ce
- ee
@@ -21,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184401_i_code_review_user_create_multiline_mr_comment_monthly.yml b/config/metrics/counts_28d/20210216184401_i_code_review_user_create_multiline_mr_comment_monthly.yml
index 7e5ccc54f67..4a4853a7520 100644
--- a/config/metrics/counts_28d/20210216184401_i_code_review_user_create_multiline_mr_comment_monthly.yml
+++ b/config/metrics/counts_28d/20210216184401_i_code_review_user_create_multiline_mr_comment_monthly.yml
@@ -1,18 +1,19 @@
---
data_category: optional
key_path: redis_hll_counters.code_review.i_code_review_user_create_multiline_mr_comment_monthly
-description: Count of unique users per month who create a multiline comment in a merge request
+description: Count of unique users per month who create a multiline comment in a merge
+ request
product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_create_multiline_mr_comment
+ - i_code_review_user_create_multiline_mr_comment
distribution:
- ce
- ee
@@ -21,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184405_i_code_review_user_edit_multiline_mr_comment_monthly.yml b/config/metrics/counts_28d/20210216184405_i_code_review_user_edit_multiline_mr_comment_monthly.yml
index 59def107ab6..36b2de72379 100644
--- a/config/metrics/counts_28d/20210216184405_i_code_review_user_edit_multiline_mr_comment_monthly.yml
+++ b/config/metrics/counts_28d/20210216184405_i_code_review_user_edit_multiline_mr_comment_monthly.yml
@@ -1,18 +1,19 @@
---
data_category: optional
key_path: redis_hll_counters.code_review.i_code_review_user_edit_multiline_mr_comment_monthly
-description: Count of unique users per week who edit a multiline comment in a merge request
+description: Count of unique users per week who edit a multiline comment in a merge
+ request
product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_edit_multiline_mr_comment
+ - i_code_review_user_edit_multiline_mr_comment
distribution:
- ce
- ee
@@ -21,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184409_i_code_review_user_remove_multiline_mr_comment_monthly.yml b/config/metrics/counts_28d/20210216184409_i_code_review_user_remove_multiline_mr_comment_monthly.yml
index ec940edea17..7cc2b9b2cc2 100644
--- a/config/metrics/counts_28d/20210216184409_i_code_review_user_remove_multiline_mr_comment_monthly.yml
+++ b/config/metrics/counts_28d/20210216184409_i_code_review_user_remove_multiline_mr_comment_monthly.yml
@@ -1,22 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.code_review.i_code_review_user_remove_multiline_mr_comment_monthly
-description: Count of unique users per month who remove a multiline comment in a merge request
+description: Count of unique users per month who remove a multiline comment in a merge
+ request
product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_remove_multiline_mr_comment
+ - i_code_review_user_remove_multiline_mr_comment
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184418_i_code_review_user_assigned_monthly.yml b/config/metrics/counts_28d/20210216184418_i_code_review_user_assigned_monthly.yml
index 2e4b9bffb9f..7e8db2be0b7 100644
--- a/config/metrics/counts_28d/20210216184418_i_code_review_user_assigned_monthly.yml
+++ b/config/metrics/counts_28d/20210216184418_i_code_review_user_assigned_monthly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_assigned
+ - i_code_review_user_assigned
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184422_i_code_review_user_marked_as_draft_monthly.yml b/config/metrics/counts_28d/20210216184422_i_code_review_user_marked_as_draft_monthly.yml
index bf49cac8446..f755351eb1e 100644
--- a/config/metrics/counts_28d/20210216184422_i_code_review_user_marked_as_draft_monthly.yml
+++ b/config/metrics/counts_28d/20210216184422_i_code_review_user_marked_as_draft_monthly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_marked_as_draft
+ - i_code_review_user_marked_as_draft
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184426_i_code_review_user_unmarked_as_draft_monthly.yml b/config/metrics/counts_28d/20210216184426_i_code_review_user_unmarked_as_draft_monthly.yml
index 746e9ed6f2f..a5685f7634a 100644
--- a/config/metrics/counts_28d/20210216184426_i_code_review_user_unmarked_as_draft_monthly.yml
+++ b/config/metrics/counts_28d/20210216184426_i_code_review_user_unmarked_as_draft_monthly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_unmarked_as_draft
+ - i_code_review_user_unmarked_as_draft
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184430_i_code_review_user_review_requested_monthly.yml b/config/metrics/counts_28d/20210216184430_i_code_review_user_review_requested_monthly.yml
index a93b38a14ec..9e6f61a755b 100644
--- a/config/metrics/counts_28d/20210216184430_i_code_review_user_review_requested_monthly.yml
+++ b/config/metrics/counts_28d/20210216184430_i_code_review_user_review_requested_monthly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_review_requested
+ - i_code_review_user_review_requested
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184434_i_code_review_user_approval_rule_added_monthly.yml b/config/metrics/counts_28d/20210216184434_i_code_review_user_approval_rule_added_monthly.yml
index fec8c67a6e7..35562e095c8 100644
--- a/config/metrics/counts_28d/20210216184434_i_code_review_user_approval_rule_added_monthly.yml
+++ b/config/metrics/counts_28d/20210216184434_i_code_review_user_approval_rule_added_monthly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_approval_rule_added
+ - i_code_review_user_approval_rule_added
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184438_i_code_review_user_approval_rule_deleted_monthly.yml b/config/metrics/counts_28d/20210216184438_i_code_review_user_approval_rule_deleted_monthly.yml
index c33697d8925..023f241596e 100644
--- a/config/metrics/counts_28d/20210216184438_i_code_review_user_approval_rule_deleted_monthly.yml
+++ b/config/metrics/counts_28d/20210216184438_i_code_review_user_approval_rule_deleted_monthly.yml
@@ -1,22 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.code_review.i_code_review_user_approval_rule_deleted_monthly
-description: Count of unique users per month who delete an approval rule to a merge request
+description: Count of unique users per month who delete an approval rule to a merge
+ request
product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_approval_rule_deleted
+ - i_code_review_user_approval_rule_deleted
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184442_i_code_review_user_approval_rule_edited_monthly.yml b/config/metrics/counts_28d/20210216184442_i_code_review_user_approval_rule_edited_monthly.yml
index c46191814fe..eae629b21f3 100644
--- a/config/metrics/counts_28d/20210216184442_i_code_review_user_approval_rule_edited_monthly.yml
+++ b/config/metrics/counts_28d/20210216184442_i_code_review_user_approval_rule_edited_monthly.yml
@@ -1,22 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.code_review.i_code_review_user_approval_rule_edited_monthly
-description: Count of unique users per month who delete an approval rule to a merge request
+description: Count of unique users per month who delete an approval rule to a merge
+ request
product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_approval_rule_edited
+ - i_code_review_user_approval_rule_edited
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184446_i_code_review_user_vs_code_api_request_monthly.yml b/config/metrics/counts_28d/20210216184446_i_code_review_user_vs_code_api_request_monthly.yml
index d4f72aab3eb..f833466e32c 100644
--- a/config/metrics/counts_28d/20210216184446_i_code_review_user_vs_code_api_request_monthly.yml
+++ b/config/metrics/counts_28d/20210216184446_i_code_review_user_vs_code_api_request_monthly.yml
@@ -6,13 +6,13 @@ product_stage: create
product_group: group::code review
product_category: editor_extension
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_vs_code_api_request
+ - i_code_review_user_vs_code_api_request
distribution:
- ce
- ee
@@ -21,3 +21,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184450_i_code_review_user_create_mr_from_issue_monthly.yml b/config/metrics/counts_28d/20210216184450_i_code_review_user_create_mr_from_issue_monthly.yml
index 3a672ceb92f..25a1a2948db 100644
--- a/config/metrics/counts_28d/20210216184450_i_code_review_user_create_mr_from_issue_monthly.yml
+++ b/config/metrics/counts_28d/20210216184450_i_code_review_user_create_mr_from_issue_monthly.yml
@@ -6,21 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_create_mr_from_issue
-instrumentation_class: RedisHLLMetric
-options:
- events:
- - i_code_review_user_create_mr
+ - i_code_review_user_create_mr_from_issue
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184454_code_review_total_unique_counts_monthly.yml b/config/metrics/counts_28d/20210216184454_code_review_total_unique_counts_monthly.yml
index 2b6e1c978d7..c4c390d16e6 100644
--- a/config/metrics/counts_28d/20210216184454_code_review_total_unique_counts_monthly.yml
+++ b/config/metrics/counts_28d/20210216184454_code_review_total_unique_counts_monthly.yml
@@ -6,68 +6,68 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_mr_diffs
- - i_code_review_user_single_file_diffs
- - i_code_review_mr_single_file_diffs
- - i_code_review_user_toggled_task_item_status
- - i_code_review_user_create_mr
- - i_code_review_user_close_mr
- - i_code_review_user_reopen_mr
- - i_code_review_user_approve_mr
- - i_code_review_user_unapprove_mr
- - i_code_review_user_resolve_thread
- - i_code_review_user_unresolve_thread
- - i_code_review_edit_mr_title
- - i_code_review_edit_mr_desc
- - i_code_review_user_merge_mr
- - i_code_review_user_create_mr_comment
- - i_code_review_user_edit_mr_comment
- - i_code_review_user_remove_mr_comment
- - i_code_review_user_create_review_note
- - i_code_review_user_publish_review
- - i_code_review_user_create_multiline_mr_comment
- - i_code_review_user_edit_multiline_mr_comment
- - i_code_review_user_remove_multiline_mr_comment
- - i_code_review_user_add_suggestion
- - i_code_review_user_apply_suggestion
- - i_code_review_user_assigned
- - i_code_review_user_marked_as_draft
- - i_code_review_user_unmarked_as_draft
- - i_code_review_user_review_requested
- - i_code_review_user_approval_rule_added
- - i_code_review_user_approval_rule_deleted
- - i_code_review_user_approval_rule_edited
- - i_code_review_user_vs_code_api_request
- - i_code_review_user_create_mr_from_issue
- - i_code_review_user_mr_discussion_locked
- - i_code_review_user_mr_discussion_unlocked
- - i_code_review_user_time_estimate_changed
- - i_code_review_user_time_spent_changed
- - i_code_review_user_assignees_changed
- - i_code_review_user_reviewers_changed
- - i_code_review_user_milestone_changed
- - i_code_review_user_labels_changed
- - i_code_review_click_diff_view_setting
- - i_code_review_click_single_file_mode_setting
- - i_code_review_click_file_browser_setting
- - i_code_review_click_whitespace_setting
- - i_code_review_diff_view_inline
- - i_code_review_diff_view_parallel
- - i_code_review_file_browser_tree_view
- - i_code_review_file_browser_list_view
- - i_code_review_diff_show_whitespace
- - i_code_review_diff_hide_whitespace
- - i_code_review_diff_single_file
- - i_code_review_diff_multiple_files
- - i_code_review_user_load_conflict_ui
- - i_code_review_user_resolve_conflict
- - i_code_review_user_searches_diff
+ - i_code_review_mr_diffs
+ - i_code_review_user_single_file_diffs
+ - i_code_review_mr_single_file_diffs
+ - i_code_review_user_toggled_task_item_status
+ - i_code_review_user_create_mr
+ - i_code_review_user_close_mr
+ - i_code_review_user_reopen_mr
+ - i_code_review_user_approve_mr
+ - i_code_review_user_unapprove_mr
+ - i_code_review_user_resolve_thread
+ - i_code_review_user_unresolve_thread
+ - i_code_review_edit_mr_title
+ - i_code_review_edit_mr_desc
+ - i_code_review_user_merge_mr
+ - i_code_review_user_create_mr_comment
+ - i_code_review_user_edit_mr_comment
+ - i_code_review_user_remove_mr_comment
+ - i_code_review_user_create_review_note
+ - i_code_review_user_publish_review
+ - i_code_review_user_create_multiline_mr_comment
+ - i_code_review_user_edit_multiline_mr_comment
+ - i_code_review_user_remove_multiline_mr_comment
+ - i_code_review_user_add_suggestion
+ - i_code_review_user_apply_suggestion
+ - i_code_review_user_assigned
+ - i_code_review_user_marked_as_draft
+ - i_code_review_user_unmarked_as_draft
+ - i_code_review_user_review_requested
+ - i_code_review_user_approval_rule_added
+ - i_code_review_user_approval_rule_deleted
+ - i_code_review_user_approval_rule_edited
+ - i_code_review_user_vs_code_api_request
+ - i_code_review_user_create_mr_from_issue
+ - i_code_review_user_mr_discussion_locked
+ - i_code_review_user_mr_discussion_unlocked
+ - i_code_review_user_time_estimate_changed
+ - i_code_review_user_time_spent_changed
+ - i_code_review_user_assignees_changed
+ - i_code_review_user_reviewers_changed
+ - i_code_review_user_milestone_changed
+ - i_code_review_user_labels_changed
+ - i_code_review_click_diff_view_setting
+ - i_code_review_click_single_file_mode_setting
+ - i_code_review_click_file_browser_setting
+ - i_code_review_click_whitespace_setting
+ - i_code_review_diff_view_inline
+ - i_code_review_diff_view_parallel
+ - i_code_review_file_browser_tree_view
+ - i_code_review_file_browser_list_view
+ - i_code_review_diff_show_whitespace
+ - i_code_review_diff_hide_whitespace
+ - i_code_review_diff_single_file
+ - i_code_review_diff_multiple_files
+ - i_code_review_user_load_conflict_ui
+ - i_code_review_user_resolve_conflict
+ - i_code_review_user_searches_diff
distribution:
- ce
- ee
@@ -76,3 +76,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184458_p_ci_templates_implicit_auto_devops_monthly.yml b/config/metrics/counts_28d/20210216184458_p_ci_templates_implicit_auto_devops_monthly.yml
index 0f31fe683c6..09590b677f6 100644
--- a/config/metrics/counts_28d/20210216184458_p_ci_templates_implicit_auto_devops_monthly.yml
+++ b/config/metrics/counts_28d/20210216184458_p_ci_templates_implicit_auto_devops_monthly.yml
@@ -7,13 +7,13 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_ci_templates_implicit_auto_devops
+ - p_ci_templates_implicit_auto_devops
distribution:
- ce
- ee
@@ -21,3 +21,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184502_p_ci_templates_implicit_auto_devops_build_monthly.yml b/config/metrics/counts_28d/20210216184502_p_ci_templates_implicit_auto_devops_build_monthly.yml
index 3ac9b6f4ddc..6e944dce726 100644
--- a/config/metrics/counts_28d/20210216184502_p_ci_templates_implicit_auto_devops_build_monthly.yml
+++ b/config/metrics/counts_28d/20210216184502_p_ci_templates_implicit_auto_devops_build_monthly.yml
@@ -7,13 +7,13 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_ci_templates_implicit_auto_devops_build
+ - p_ci_templates_implicit_auto_devops_build
distribution:
- ce
- ee
@@ -21,3 +21,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184506_p_ci_templates_implicit_auto_devops_deploy_monthly.yml b/config/metrics/counts_28d/20210216184506_p_ci_templates_implicit_auto_devops_deploy_monthly.yml
index ab0fabca342..940ef5deb65 100644
--- a/config/metrics/counts_28d/20210216184506_p_ci_templates_implicit_auto_devops_deploy_monthly.yml
+++ b/config/metrics/counts_28d/20210216184506_p_ci_templates_implicit_auto_devops_deploy_monthly.yml
@@ -7,13 +7,13 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_ci_templates_implicit_auto_devops_deploy
+ - p_ci_templates_implicit_auto_devops_deploy
distribution:
- ce
- ee
@@ -21,3 +21,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184510_p_ci_templates_implicit_security_sast_monthly.yml b/config/metrics/counts_28d/20210216184510_p_ci_templates_implicit_security_sast_monthly.yml
index 5ad9c37ea8d..822b436dfdd 100644
--- a/config/metrics/counts_28d/20210216184510_p_ci_templates_implicit_security_sast_monthly.yml
+++ b/config/metrics/counts_28d/20210216184510_p_ci_templates_implicit_security_sast_monthly.yml
@@ -1,21 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_sast_monthly
-description: ''
-product_section: ''
-product_stage: ''
-product_group: ''
-product_category: ''
+description: Count of pipelines with implicit SAST runs
+product_section: ops
+product_stage: verify
+product_group: "group::static analysis"
+product_category: SAST
value_type: number
-status: data_available
+status: active
+milestone: "<13.9"
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_ci_templates_implicit_security_sast
+ - p_ci_templates_implicit_security_sast
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
diff --git a/config/metrics/counts_28d/20210216184513_p_ci_templates_implicit_security_secret_detection_monthly.yml b/config/metrics/counts_28d/20210216184513_p_ci_templates_implicit_security_secret_detection_monthly.yml
index 31ff83c08fa..57831d3a9dc 100644
--- a/config/metrics/counts_28d/20210216184513_p_ci_templates_implicit_security_secret_detection_monthly.yml
+++ b/config/metrics/counts_28d/20210216184513_p_ci_templates_implicit_security_secret_detection_monthly.yml
@@ -1,21 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_secret_detection_monthly
-description: ''
-product_section: ''
-product_stage: ''
-product_group: ''
-product_category: ''
+description: Count of pipelines with implicit Secret Detection runs
+product_section: ops
+product_stage: verify
+product_group: "group::static analysis"
+product_category: secret_detection
value_type: number
-status: data_available
+status: active
+milestone: "<13.9"
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_ci_templates_implicit_security_secret_detection
+ - p_ci_templates_implicit_security_secret_detection
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
diff --git a/config/metrics/counts_28d/20210216184517_p_ci_templates_5_min_production_app_monthly.yml b/config/metrics/counts_28d/20210216184517_p_ci_templates_5_min_production_app_monthly.yml
index 2a0041f589b..0ae42fcecc0 100644
--- a/config/metrics/counts_28d/20210216184517_p_ci_templates_5_min_production_app_monthly.yml
+++ b/config/metrics/counts_28d/20210216184517_p_ci_templates_5_min_production_app_monthly.yml
@@ -4,16 +4,16 @@ key_path: redis_hll_counters.ci_templates.p_ci_templates_5_min_production_app_mo
description: Number of projects using 5 min production app CI template in last 7 days.
product_section: seg
product_stage: deploy
-product_group: "group::5-min-app"
+product_group: group::5-min-app
product_category: five_minute_production_app
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_ci_templates_5_min_production_app
+ - p_ci_templates_5_min_production_app
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184523_p_ci_templates_auto_devops_monthly.yml b/config/metrics/counts_28d/20210216184523_p_ci_templates_auto_devops_monthly.yml
index feb29888b98..6ca23b2d634 100644
--- a/config/metrics/counts_28d/20210216184523_p_ci_templates_auto_devops_monthly.yml
+++ b/config/metrics/counts_28d/20210216184523_p_ci_templates_auto_devops_monthly.yml
@@ -7,13 +7,13 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_ci_templates_auto_devops
+ - p_ci_templates_auto_devops
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184526_p_ci_templates_aws_cf_deploy_ec2_monthly.yml b/config/metrics/counts_28d/20210216184526_p_ci_templates_aws_cf_deploy_ec2_monthly.yml
index 479ae0b65e7..a87e1224745 100644
--- a/config/metrics/counts_28d/20210216184526_p_ci_templates_aws_cf_deploy_ec2_monthly.yml
+++ b/config/metrics/counts_28d/20210216184526_p_ci_templates_aws_cf_deploy_ec2_monthly.yml
@@ -1,19 +1,20 @@
---
data_category: optional
key_path: redis_hll_counters.ci_templates.p_ci_templates_aws_cf_deploy_ec2_monthly
-description: "Count of projects using `AWS/CF-Provision-and-Deploy-EC2.gitlab-ci.yml` template in last 28 days."
+description: Count of projects using `AWS/CF-Provision-and-Deploy-EC2.gitlab-ci.yml`
+ template in last 28 days.
product_section: ops
product_stage: release
-product_group: "group::release"
+product_group: group::release
product_category: continuous_delivery
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_ci_templates_aws_cf_deploy_ec2
+ - p_ci_templates_aws_cf_deploy_ec2
distribution:
- ce
- ee
@@ -21,3 +22,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184530_p_ci_templates_aws_deploy_ecs_monthly.yml b/config/metrics/counts_28d/20210216184530_p_ci_templates_aws_deploy_ecs_monthly.yml
index d6e8edfc8f9..0645894329a 100644
--- a/config/metrics/counts_28d/20210216184530_p_ci_templates_aws_deploy_ecs_monthly.yml
+++ b/config/metrics/counts_28d/20210216184530_p_ci_templates_aws_deploy_ecs_monthly.yml
@@ -1,19 +1,20 @@
---
data_category: optional
key_path: redis_hll_counters.ci_templates.p_ci_templates_aws_deploy_ecs_monthly
-description: "Count of projects using `AWS/Deploy-ECS.gitlab-ci.yml` template in last 28 days."
+description: Count of projects using `AWS/Deploy-ECS.gitlab-ci.yml` template in last
+ 28 days.
product_section: ops
product_stage: release
-product_group: "group::release"
+product_group: group::release
product_category: continuous_delivery
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_ci_templates_aws_deploy_ecs
+ - p_ci_templates_aws_deploy_ecs
distribution:
- ce
- ee
@@ -21,3 +22,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184534_p_ci_templates_auto_devops_build_monthly.yml b/config/metrics/counts_28d/20210216184534_p_ci_templates_auto_devops_build_monthly.yml
index 04b087c2b63..d6333260017 100644
--- a/config/metrics/counts_28d/20210216184534_p_ci_templates_auto_devops_build_monthly.yml
+++ b/config/metrics/counts_28d/20210216184534_p_ci_templates_auto_devops_build_monthly.yml
@@ -7,13 +7,13 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_ci_templates_auto_devops_build
+ - p_ci_templates_auto_devops_build
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184538_p_ci_templates_auto_devops_deploy_monthly.yml b/config/metrics/counts_28d/20210216184538_p_ci_templates_auto_devops_deploy_monthly.yml
index c5f24824bde..792d41e3bbd 100644
--- a/config/metrics/counts_28d/20210216184538_p_ci_templates_auto_devops_deploy_monthly.yml
+++ b/config/metrics/counts_28d/20210216184538_p_ci_templates_auto_devops_deploy_monthly.yml
@@ -7,13 +7,13 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_ci_templates_auto_devops_deploy
+ - p_ci_templates_auto_devops_deploy
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184542_p_ci_templates_auto_devops_deploy_latest_monthly.yml b/config/metrics/counts_28d/20210216184542_p_ci_templates_auto_devops_deploy_latest_monthly.yml
index baac103aae1..deafb216e99 100644
--- a/config/metrics/counts_28d/20210216184542_p_ci_templates_auto_devops_deploy_latest_monthly.yml
+++ b/config/metrics/counts_28d/20210216184542_p_ci_templates_auto_devops_deploy_latest_monthly.yml
@@ -7,13 +7,13 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_ci_templates_auto_devops_deploy_latest
+ - p_ci_templates_auto_devops_deploy_latest
distribution:
- ce
- ee
@@ -21,3 +21,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184546_p_ci_templates_security_sast_monthly.yml b/config/metrics/counts_28d/20210216184546_p_ci_templates_security_sast_monthly.yml
index 0e072188e2a..6c838d74576 100644
--- a/config/metrics/counts_28d/20210216184546_p_ci_templates_security_sast_monthly.yml
+++ b/config/metrics/counts_28d/20210216184546_p_ci_templates_security_sast_monthly.yml
@@ -1,22 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.ci_templates.p_ci_templates_security_sast_monthly
-description: ''
-product_section: ''
-product_stage: ''
-product_group: ''
-product_category: ''
+description: Count of pipelines with SAST runs
+product_section: ops
+product_stage: verify
+product_group: "group::static analysis"
+product_category: SAST
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_ci_templates_security_sast
+ - p_ci_templates_security_sast
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184551_p_ci_templates_security_secret_detection_monthly.yml b/config/metrics/counts_28d/20210216184551_p_ci_templates_security_secret_detection_monthly.yml
index 7e9f5151a23..cda8ebf1550 100644
--- a/config/metrics/counts_28d/20210216184551_p_ci_templates_security_secret_detection_monthly.yml
+++ b/config/metrics/counts_28d/20210216184551_p_ci_templates_security_secret_detection_monthly.yml
@@ -1,22 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.ci_templates.p_ci_templates_security_secret_detection_monthly
-description: ''
-product_section: ''
-product_stage: ''
-product_group: ''
-product_category: ''
+description: Count of pipelines with Secret Detection runs
+product_section: ops
+product_stage: verify
+product_group: "group::static analysis"
+product_category: secret_detection
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_ci_templates_security_secret_detection
+ - p_ci_templates_security_secret_detection
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184555_p_ci_templates_terraform_base_latest_monthly.yml b/config/metrics/counts_28d/20210216184555_p_ci_templates_terraform_base_latest_monthly.yml
index 063b9e7c582..1831c8827f3 100644
--- a/config/metrics/counts_28d/20210216184555_p_ci_templates_terraform_base_latest_monthly.yml
+++ b/config/metrics/counts_28d/20210216184555_p_ci_templates_terraform_base_latest_monthly.yml
@@ -7,13 +7,13 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_ci_templates_terraform_base_latest
+ - p_ci_templates_terraform_base_latest
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184559_ci_templates_total_unique_counts_monthly.yml b/config/metrics/counts_28d/20210216184559_ci_templates_total_unique_counts_monthly.yml
index c036b506ac5..66b8e714723 100644
--- a/config/metrics/counts_28d/20210216184559_ci_templates_total_unique_counts_monthly.yml
+++ b/config/metrics/counts_28d/20210216184559_ci_templates_total_unique_counts_monthly.yml
@@ -7,28 +7,158 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: broken
+status: removed
+milestone_removed: '14.3'
repair_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/332466
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_ci_templates_implicit_auto_devops
- - p_ci_templates_implicit_auto_devops_build
- - p_ci_templates_implicit_auto_devops_deploy
- - p_ci_templates_implicit_security_sast
- - p_ci_templates_implicit_security_secret_detection
- - p_ci_templates_5_min_production_app
- - p_ci_templates_auto_devops
- - p_ci_templates_aws_cf_deploy_ec2
- - p_ci_templates_aws_deploy_ecs
- - p_ci_templates_auto_devops_build
- - p_ci_templates_auto_devops_deploy
- - p_ci_templates_auto_devops_deploy_latest
- - p_ci_templates_security_sast
- - p_ci_templates_security_secret_detection
- - p_ci_templates_terraform_base_latest
+ - p_ci_templates_implicit_auto_devops
+ - p_ci_templates_5_min_production_app
+ - p_ci_templates_aws_cf_deploy_ec2
+ - p_ci_templates_auto_devops_build
+ - p_ci_templates_auto_devops_deploy
+ - p_ci_templates_auto_devops_deploy_latest
+ - p_ci_templates_terraform_base_latest
+ - p_ci_templates_terraform_base
+ - p_ci_templates_dotnet
+ - p_ci_templates_nodejs
+ - p_ci_templates_openshift
+ - p_ci_templates_auto_devops
+ - p_ci_templates_bash
+ - p_ci_templates_rust
+ - p_ci_templates_elixir
+ - p_ci_templates_clojure
+ - p_ci_templates_crystal
+ - p_ci_templates_getting_started
+ - p_ci_templates_code_quality
+ - p_ci_templates_verify_load_performance_testing
+ - p_ci_templates_verify_accessibility
+ - p_ci_templates_verify_failfast
+ - p_ci_templates_verify_browser_performance
+ - p_ci_templates_verify_browser_performance_latest
+ - p_ci_templates_grails
+ - p_ci_templates_security_sast
+ - p_ci_templates_security_dast_runner_validation
+ - p_ci_templates_security_dast_on_demand_scan
+ - p_ci_templates_security_secret_detection
+ - p_ci_templates_security_license_scanning
+ - p_ci_templates_security_coverage_fuzzing
+ - p_ci_templates_security_api_fuzzing_latest
+ - p_ci_templates_security_secure_binaries
+ - p_ci_templates_security_dast_api
+ - p_ci_templates_security_container_scanning
+ - p_ci_templates_security_dast_latest
+ - p_ci_templates_security_dependency_scanning
+ - p_ci_templates_security_api_fuzzing
+ - p_ci_templates_security_dast
+ - p_ci_templates_security_cluster_image_scanning
+ - p_ci_templates_ios_fastlane
+ - p_ci_templates_composer
+ - p_ci_templates_c
+ - p_ci_templates_python
+ - p_ci_templates_django
+ - p_ci_templates_maven
+ - p_ci_templates_flutter
+ - p_ci_templates_workflows_branch_pipelines
+ - p_ci_templates_workflows_mergerequest_pipelines
+ - p_ci_templates_laravel
+ - p_ci_templates_managed_cluster_applications
+ - p_ci_templates_php
+ - p_ci_templates_packer
+ - p_ci_templates_terraform
+ - p_ci_templates_mono
+ - p_ci_templates_serverless
+ - p_ci_templates_go
+ - p_ci_templates_scala
+ - p_ci_templates_latex
+ - p_ci_templates_android
+ - p_ci_templates_android_fastlane
+ - p_ci_templates_android_latest
+ - p_ci_templates_indeni_cloudrail
+ - p_ci_templates_deploy_ecs
+ - p_ci_templates_aws_cf_provision_and_deploy_ec2
+ - p_ci_templates_aws_deploy_ecs
+ - p_ci_templates_gradle
+ - p_ci_templates_chef
+ - p_ci_templates_jobs_dast_default_branch_deploy
+ - p_ci_templates_jobs_load_performance_testing
+ - p_ci_templates_jobs_helm_2to3
+ - p_ci_templates_jobs_sast
+ - p_ci_templates_jobs_secret_detection
+ - p_ci_templates_jobs_code_intelligence
+ - p_ci_templates_jobs_code_quality
+ - p_ci_templates_jobs_deploy_ecs
+ - p_ci_templates_jobs_deploy_ec2
+ - p_ci_templates_jobs_deploy
+ - p_ci_templates_jobs_build
+ - p_ci_templates_jobs_browser_performance_testing
+ - p_ci_templates_jobs_test
+ - p_ci_templates_jobs_deploy_latest
+ - p_ci_templates_jobs_browser_performance_testing_latest
+ - p_ci_templates_jobs_cf_provision
+ - p_ci_templates_jobs_build_latest
+ - p_ci_templates_terraform_latest
+ - p_ci_templates_swift
+ - p_ci_templates_pages_jekyll
+ - p_ci_templates_pages_harp
+ - p_ci_templates_pages_octopress
+ - p_ci_templates_pages_brunch
+ - p_ci_templates_pages_doxygen
+ - p_ci_templates_pages_hyde
+ - p_ci_templates_pages_lektor
+ - p_ci_templates_pages_jbake
+ - p_ci_templates_pages_hexo
+ - p_ci_templates_pages_middleman
+ - p_ci_templates_pages_hugo
+ - p_ci_templates_pages_pelican
+ - p_ci_templates_pages_nanoc
+ - p_ci_templates_pages_swaggerui
+ - p_ci_templates_pages_jigsaw
+ - p_ci_templates_pages_metalsmith
+ - p_ci_templates_pages_gatsby
+ - p_ci_templates_pages_html
+ - p_ci_templates_dart
+ - p_ci_templates_docker
+ - p_ci_templates_julia
+ - p_ci_templates_npm
+ - p_ci_templates_dotnet_core
+ - p_ci_templates_5_minute_production_app
+ - p_ci_templates_ruby
+ - p_ci_templates_implicit_jobs_dast_default_branch_deploy
+ - p_ci_templates_implicit_jobs_load_performance_testing
+ - p_ci_templates_implicit_jobs_helm_2to3
+ - p_ci_templates_implicit_jobs_sast
+ - p_ci_templates_implicit_jobs_secret_detection
+ - p_ci_templates_implicit_jobs_code_intelligence
+ - p_ci_templates_implicit_jobs_code_quality
+ - p_ci_templates_implicit_jobs_deploy_ecs
+ - p_ci_templates_implicit_jobs_deploy_ec2
+ - p_ci_templates_implicit_auto_devops_deploy
+ - p_ci_templates_implicit_auto_devops_build
+ - p_ci_templates_implicit_jobs_browser_performance_testing
+ - p_ci_templates_implicit_jobs_test
+ - p_ci_templates_implicit_auto_devops_deploy_latest
+ - p_ci_templates_implicit_jobs_browser_performance_testing_latest
+ - p_ci_templates_implicit_jobs_cf_provision
+ - p_ci_templates_implicit_jobs_build_latest
+ - p_ci_templates_implicit_security_sast
+ - p_ci_templates_implicit_security_dast_runner_validation
+ - p_ci_templates_implicit_security_dast_on_demand_scan
+ - p_ci_templates_implicit_security_secret_detection
+ - p_ci_templates_implicit_security_license_scanning
+ - p_ci_templates_implicit_security_coverage_fuzzing
+ - p_ci_templates_implicit_security_api_fuzzing_latest
+ - p_ci_templates_implicit_security_secure_binaries
+ - p_ci_templates_implicit_security_dast_api
+ - p_ci_templates_implicit_security_container_scanning
+ - p_ci_templates_implicit_security_dast_latest
+ - p_ci_templates_implicit_security_dependency_scanning
+ - p_ci_templates_implicit_security_api_fuzzing
+ - p_ci_templates_implicit_security_dast
+ - p_ci_templates_implicit_security_cluster_image_scanning
distribution:
- ce
- ee
@@ -37,3 +167,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184803_quickactions_total_unique_counts_monthly.yml b/config/metrics/counts_28d/20210216184803_quickactions_total_unique_counts_monthly.yml
index de5acc6a60c..23f3d923576 100644
--- a/config/metrics/counts_28d/20210216184803_quickactions_total_unique_counts_monthly.yml
+++ b/config/metrics/counts_28d/20210216184803_quickactions_total_unique_counts_monthly.yml
@@ -3,88 +3,89 @@ data_category: optional
key_path: redis_hll_counters.quickactions.quickactions_total_unique_counts_monthly
description: Count of MAU using one or more quick actions
product_section: dev
-product_stage: plan
-product_group: group::project management
-product_category: issue_tracking
+product_stage: plan
+product_group: group::project management
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_approve
- - i_quickactions_assign_single
- - i_quickactions_assign_multiple
- - i_quickactions_assign_self
- - i_quickactions_assign_reviewer
- - i_quickactions_award
- - i_quickactions_board_move
- - i_quickactions_child_epic
- - i_quickactions_clear_weight
- - i_quickactions_clone
- - i_quickactions_close
- - i_quickactions_confidential
- - i_quickactions_copy_metadata_merge_request
- - i_quickactions_copy_metadata_issue
- - i_quickactions_create_merge_request
- - i_quickactions_done
- - i_quickactions_draft
- - i_quickactions_due
- - i_quickactions_duplicate
- - i_quickactions_epic
- - i_quickactions_estimate
- - i_quickactions_iteration
- - i_quickactions_label
- - i_quickactions_lock
- - i_quickactions_merge
- - i_quickactions_milestone
- - i_quickactions_move
- - i_quickactions_parent_epic
- - i_quickactions_promote
- - i_quickactions_publish
- - i_quickactions_reassign
- - i_quickactions_reassign_reviewer
- - i_quickactions_rebase
- - i_quickactions_relabel
- - i_quickactions_relate
- - i_quickactions_remove_child_epic
- - i_quickactions_remove_due_date
- - i_quickactions_remove_epic
- - i_quickactions_remove_estimate
- - i_quickactions_remove_iteration
- - i_quickactions_remove_milestone
- - i_quickactions_remove_parent_epic
- - i_quickactions_remove_time_spent
- - i_quickactions_remove_zoom
- - i_quickactions_reopen
- - i_quickactions_severity
- - i_quickactions_shrug
- - i_quickactions_spend_subtract
- - i_quickactions_spend_add
- - i_quickactions_submit_review
- - i_quickactions_subscribe
- - i_quickactions_tableflip
- - i_quickactions_tag
- - i_quickactions_target_branch
- - i_quickactions_title
- - i_quickactions_todo
- - i_quickactions_unassign_specific
- - i_quickactions_unassign_all
- - i_quickactions_unassign_reviewer
- - i_quickactions_unlabel_specific
- - i_quickactions_unlabel_all
- - i_quickactions_unlock
- - i_quickactions_unsubscribe
- - i_quickactions_weight
- - i_quickactions_wip
- - i_quickactions_zoom
- - i_quickactions_invite_email_single
- - i_quickactions_invite_email_multiple
+ - i_quickactions_approve
+ - i_quickactions_assign_single
+ - i_quickactions_assign_multiple
+ - i_quickactions_assign_self
+ - i_quickactions_assign_reviewer
+ - i_quickactions_award
+ - i_quickactions_board_move
+ - i_quickactions_child_epic
+ - i_quickactions_clear_weight
+ - i_quickactions_clone
+ - i_quickactions_close
+ - i_quickactions_confidential
+ - i_quickactions_copy_metadata_merge_request
+ - i_quickactions_copy_metadata_issue
+ - i_quickactions_create_merge_request
+ - i_quickactions_done
+ - i_quickactions_draft
+ - i_quickactions_due
+ - i_quickactions_duplicate
+ - i_quickactions_epic
+ - i_quickactions_estimate
+ - i_quickactions_iteration
+ - i_quickactions_label
+ - i_quickactions_lock
+ - i_quickactions_merge
+ - i_quickactions_milestone
+ - i_quickactions_move
+ - i_quickactions_parent_epic
+ - i_quickactions_promote
+ - i_quickactions_publish
+ - i_quickactions_reassign
+ - i_quickactions_reassign_reviewer
+ - i_quickactions_rebase
+ - i_quickactions_relabel
+ - i_quickactions_relate
+ - i_quickactions_remove_child_epic
+ - i_quickactions_remove_due_date
+ - i_quickactions_remove_epic
+ - i_quickactions_remove_estimate
+ - i_quickactions_remove_iteration
+ - i_quickactions_remove_milestone
+ - i_quickactions_remove_parent_epic
+ - i_quickactions_remove_time_spent
+ - i_quickactions_remove_zoom
+ - i_quickactions_reopen
+ - i_quickactions_severity
+ - i_quickactions_shrug
+ - i_quickactions_spend_subtract
+ - i_quickactions_spend_add
+ - i_quickactions_submit_review
+ - i_quickactions_subscribe
+ - i_quickactions_tableflip
+ - i_quickactions_tag
+ - i_quickactions_target_branch
+ - i_quickactions_title
+ - i_quickactions_todo
+ - i_quickactions_unassign_specific
+ - i_quickactions_unassign_all
+ - i_quickactions_unassign_reviewer
+ - i_quickactions_unlabel_specific
+ - i_quickactions_unlabel_all
+ - i_quickactions_unlock
+ - i_quickactions_unsubscribe
+ - i_quickactions_weight
+ - i_quickactions_wip
+ - i_quickactions_zoom
+ - i_quickactions_invite_email_single
+ - i_quickactions_invite_email_multiple
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
-- ultimate
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184806_i_package_composer_deploy_token_monthly.yml b/config/metrics/counts_28d/20210216184806_i_package_composer_deploy_token_monthly.yml
index 27893e9a72c..9f4cfe0fc13 100644
--- a/config/metrics/counts_28d/20210216184806_i_package_composer_deploy_token_monthly.yml
+++ b/config/metrics/counts_28d/20210216184806_i_package_composer_deploy_token_monthly.yml
@@ -1,19 +1,20 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.i_package_composer_deploy_token_monthly
-description: A monthly count of Composer packages published to the registry using a deploy token
+description: A monthly count of Composer packages published to the registry using
+ a deploy token
product_section: ops
product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_composer_deploy_token
+ - i_package_composer_deploy_token
distribution:
- ee
- ce
@@ -21,3 +22,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184810_i_package_conan_deploy_token_monthly.yml b/config/metrics/counts_28d/20210216184810_i_package_conan_deploy_token_monthly.yml
index f5b4a753ca3..89a54558bd7 100644
--- a/config/metrics/counts_28d/20210216184810_i_package_conan_deploy_token_monthly.yml
+++ b/config/metrics/counts_28d/20210216184810_i_package_conan_deploy_token_monthly.yml
@@ -1,19 +1,20 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.i_package_conan_deploy_token_monthly
-description: A monthly count of Conan packages published to the registry using a deploy token
+description: A monthly count of Conan packages published to the registry using a deploy
+ token
product_section: ops
product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_conan_deploy_token
+ - i_package_conan_deploy_token
distribution:
- ee
- ce
@@ -21,3 +22,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184814_i_package_container_deploy_token_monthly.yml b/config/metrics/counts_28d/20210216184814_i_package_container_deploy_token_monthly.yml
index 3da9fd8a073..dc08e248c4f 100644
--- a/config/metrics/counts_28d/20210216184814_i_package_container_deploy_token_monthly.yml
+++ b/config/metrics/counts_28d/20210216184814_i_package_container_deploy_token_monthly.yml
@@ -1,7 +1,8 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.i_package_container_deploy_token_monthly
-description: A monthly count of container images published to the registry using a deploy token
+description: A monthly count of container images published to the registry using a
+ deploy token
product_section: ops
product_stage: package
product_group: group::package
@@ -13,7 +14,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_container_deploy_token
+ - i_package_container_deploy_token
distribution:
- ee
- ce
@@ -21,3 +22,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184818_i_package_debian_deploy_token_monthly.yml b/config/metrics/counts_28d/20210216184818_i_package_debian_deploy_token_monthly.yml
index 5bddca4b70e..edb282fd1a1 100644
--- a/config/metrics/counts_28d/20210216184818_i_package_debian_deploy_token_monthly.yml
+++ b/config/metrics/counts_28d/20210216184818_i_package_debian_deploy_token_monthly.yml
@@ -1,7 +1,8 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.i_package_debian_deploy_token_monthly
-description: A monthly count of Debian packages published to the registry using a deploy token
+description: A monthly count of Debian packages published to the registry using a
+ deploy token
product_section: ops
product_stage: package
product_group: group::package
@@ -13,7 +14,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_debian_deploy_token
+ - i_package_debian_deploy_token
distribution:
- ee
- ce
@@ -21,3 +22,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184822_i_package_generic_deploy_token_monthly.yml b/config/metrics/counts_28d/20210216184822_i_package_generic_deploy_token_monthly.yml
index 4bf549b2653..84da476edb5 100644
--- a/config/metrics/counts_28d/20210216184822_i_package_generic_deploy_token_monthly.yml
+++ b/config/metrics/counts_28d/20210216184822_i_package_generic_deploy_token_monthly.yml
@@ -1,7 +1,8 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.i_package_generic_deploy_token_monthly
-description: A monthly count of generic packages published to the registry using a deploy token
+description: A monthly count of generic packages published to the registry using a
+ deploy token
product_section: ops
product_stage: package
product_group: group::package
@@ -14,7 +15,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_generic_deploy_token
+ - i_package_generic_deploy_token
distribution:
- ee
- ce
@@ -22,3 +23,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184826_i_package_golang_deploy_token_monthly.yml b/config/metrics/counts_28d/20210216184826_i_package_golang_deploy_token_monthly.yml
index 61bc69c172a..1e3247a7109 100644
--- a/config/metrics/counts_28d/20210216184826_i_package_golang_deploy_token_monthly.yml
+++ b/config/metrics/counts_28d/20210216184826_i_package_golang_deploy_token_monthly.yml
@@ -1,7 +1,8 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.i_package_golang_deploy_token_monthly
-description: A monthly count of Go modules published to the registry using a deploy token
+description: A monthly count of Go modules published to the registry using a deploy
+ token
product_section: ops
product_stage: package
product_group: group::package
@@ -13,7 +14,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_golang_deploy_token
+ - i_package_golang_deploy_token
distribution:
- ee
- ce
@@ -21,3 +22,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184830_i_package_maven_deploy_token_monthly.yml b/config/metrics/counts_28d/20210216184830_i_package_maven_deploy_token_monthly.yml
index d231688f191..c6e71e4a61b 100644
--- a/config/metrics/counts_28d/20210216184830_i_package_maven_deploy_token_monthly.yml
+++ b/config/metrics/counts_28d/20210216184830_i_package_maven_deploy_token_monthly.yml
@@ -1,19 +1,20 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.i_package_maven_deploy_token_monthly
-description: A monthly count of Maven packages published to the registry using a deploy token
+description: A monthly count of Maven packages published to the registry using a deploy
+ token
product_section: ops
product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_maven_deploy_token
+ - i_package_maven_deploy_token
distribution:
- ee
- ce
@@ -22,3 +23,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184834_i_package_npm_deploy_token_monthly.yml b/config/metrics/counts_28d/20210216184834_i_package_npm_deploy_token_monthly.yml
index df745333d71..143a840761c 100644
--- a/config/metrics/counts_28d/20210216184834_i_package_npm_deploy_token_monthly.yml
+++ b/config/metrics/counts_28d/20210216184834_i_package_npm_deploy_token_monthly.yml
@@ -1,19 +1,20 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.i_package_npm_deploy_token_monthly
-description: A monthly count of npm packages published to the registry using a deploy token
+description: A monthly count of npm packages published to the registry using a deploy
+ token
product_section: ops
product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_npm_deploy_token
+ - i_package_npm_deploy_token
distribution:
- ee
- ce
@@ -22,3 +23,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184838_i_package_nuget_deploy_token_monthly.yml b/config/metrics/counts_28d/20210216184838_i_package_nuget_deploy_token_monthly.yml
index 063530e82ac..cb7c6ae2e5b 100644
--- a/config/metrics/counts_28d/20210216184838_i_package_nuget_deploy_token_monthly.yml
+++ b/config/metrics/counts_28d/20210216184838_i_package_nuget_deploy_token_monthly.yml
@@ -1,19 +1,20 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.i_package_nuget_deploy_token_monthly
-description: A monthly count of NuGet packages published to the registry using a deploy token
+description: A monthly count of NuGet packages published to the registry using a deploy
+ token
product_section: ops
product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_nuget_deploy_token
+ - i_package_nuget_deploy_token
distribution:
- ee
- ce
@@ -22,3 +23,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184842_i_package_pypi_deploy_token_monthly.yml b/config/metrics/counts_28d/20210216184842_i_package_pypi_deploy_token_monthly.yml
index 256689b29a8..cadeb269204 100644
--- a/config/metrics/counts_28d/20210216184842_i_package_pypi_deploy_token_monthly.yml
+++ b/config/metrics/counts_28d/20210216184842_i_package_pypi_deploy_token_monthly.yml
@@ -1,19 +1,20 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.i_package_pypi_deploy_token_monthly
-description: A monthly count of PyPI packages published to the registry using a deploy token
+description: A monthly count of PyPI packages published to the registry using a deploy
+ token
product_section: ops
product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_pypi_deploy_token
+ - i_package_pypi_deploy_token
distribution:
- ee
- ce
@@ -22,3 +23,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184846_i_package_tag_deploy_token_monthly.yml b/config/metrics/counts_28d/20210216184846_i_package_tag_deploy_token_monthly.yml
index 52be708f794..d465a6aff4b 100644
--- a/config/metrics/counts_28d/20210216184846_i_package_tag_deploy_token_monthly.yml
+++ b/config/metrics/counts_28d/20210216184846_i_package_tag_deploy_token_monthly.yml
@@ -1,7 +1,8 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.i_package_tag_deploy_token_monthly
-description: A monthly count of package tags published to the registry using a deploy token
+description: A monthly count of package tags published to the registry using a deploy
+ token
product_section: ops
product_stage: package
product_group: group::package
@@ -13,7 +14,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_tag_deploy_token
+ - i_package_tag_deploy_token
distribution:
- ee
- ce
@@ -21,3 +22,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184850_deploy_token_packages_total_unique_counts_monthly.yml b/config/metrics/counts_28d/20210216184850_deploy_token_packages_total_unique_counts_monthly.yml
index 5452e4399d5..344f35fa353 100644
--- a/config/metrics/counts_28d/20210216184850_deploy_token_packages_total_unique_counts_monthly.yml
+++ b/config/metrics/counts_28d/20210216184850_deploy_token_packages_total_unique_counts_monthly.yml
@@ -1,32 +1,33 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.deploy_token_packages_total_unique_counts_monthly
-description: A monthly count of packages published to the registry using a deploy token
+description: A monthly count of packages published to the registry using a deploy
+ token
product_section: ops
product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_composer_deploy_token
- - i_package_conan_deploy_token
- - i_package_container_deploy_token
- - i_package_debian_deploy_token
- - i_package_generic_deploy_token
- - i_package_golang_deploy_token
- - i_package_helm_deploy_token
- - i_package_maven_deploy_token
- - i_package_npm_deploy_token
- - i_package_nuget_deploy_token
- - i_package_pypi_deploy_token
- - i_package_rubygems_deploy_token
- - i_package_tag_deploy_token
- - i_package_terraform_module_deploy_token
+ - i_package_composer_deploy_token
+ - i_package_conan_deploy_token
+ - i_package_container_deploy_token
+ - i_package_debian_deploy_token
+ - i_package_generic_deploy_token
+ - i_package_golang_deploy_token
+ - i_package_helm_deploy_token
+ - i_package_maven_deploy_token
+ - i_package_npm_deploy_token
+ - i_package_nuget_deploy_token
+ - i_package_pypi_deploy_token
+ - i_package_rubygems_deploy_token
+ - i_package_tag_deploy_token
+ - i_package_terraform_module_deploy_token
distribution:
- ee
- ce
@@ -35,3 +36,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184854_i_package_composer_user_monthly.yml b/config/metrics/counts_28d/20210216184854_i_package_composer_user_monthly.yml
index 4d0c59d2568..f9baba603e9 100644
--- a/config/metrics/counts_28d/20210216184854_i_package_composer_user_monthly.yml
+++ b/config/metrics/counts_28d/20210216184854_i_package_composer_user_monthly.yml
@@ -1,19 +1,20 @@
---
data_category: optional
key_path: redis_hll_counters.user_packages.i_package_composer_user_monthly
-description: A monthly count of users that have published a Composer package to the registry
+description: A monthly count of users that have published a Composer package to the
+ registry
product_section: ops
product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_composer_user
+ - i_package_composer_user
distribution:
- ee
- ce
@@ -22,3 +23,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184858_i_package_conan_user_monthly.yml b/config/metrics/counts_28d/20210216184858_i_package_conan_user_monthly.yml
index 83adab11d09..8a50ea78fe2 100644
--- a/config/metrics/counts_28d/20210216184858_i_package_conan_user_monthly.yml
+++ b/config/metrics/counts_28d/20210216184858_i_package_conan_user_monthly.yml
@@ -7,13 +7,13 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_conan_user
+ - i_package_conan_user
distribution:
- ee
- ce
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184902_i_package_container_user_monthly.yml b/config/metrics/counts_28d/20210216184902_i_package_container_user_monthly.yml
index a0072e65314..50df5df1b25 100644
--- a/config/metrics/counts_28d/20210216184902_i_package_container_user_monthly.yml
+++ b/config/metrics/counts_28d/20210216184902_i_package_container_user_monthly.yml
@@ -1,7 +1,8 @@
---
data_category: optional
key_path: redis_hll_counters.user_packages.i_package_container_user_monthly
-description: A monthly count of users that have published a container image to the registry
+description: A monthly count of users that have published a container image to the
+ registry
product_section: ops
product_stage: package
product_group: group::package
@@ -13,7 +14,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_container_user
+ - i_package_container_user
distribution:
- ee
- ce
@@ -21,3 +22,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184906_i_package_debian_user_monthly.yml b/config/metrics/counts_28d/20210216184906_i_package_debian_user_monthly.yml
index 22e7a1f432a..cb716aae070 100644
--- a/config/metrics/counts_28d/20210216184906_i_package_debian_user_monthly.yml
+++ b/config/metrics/counts_28d/20210216184906_i_package_debian_user_monthly.yml
@@ -1,7 +1,8 @@
---
data_category: optional
key_path: redis_hll_counters.user_packages.i_package_debian_user_monthly
-description: A monthly count of users that have published a Debian package to the registry
+description: A monthly count of users that have published a Debian package to the
+ registry
product_section: ops
product_stage: package
product_group: group::package
@@ -13,7 +14,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_debian_user
+ - i_package_debian_user
distribution:
- ee
- ce
@@ -21,3 +22,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184910_i_package_generic_user_monthly.yml b/config/metrics/counts_28d/20210216184910_i_package_generic_user_monthly.yml
index 7072e6542b8..f028719bfe1 100644
--- a/config/metrics/counts_28d/20210216184910_i_package_generic_user_monthly.yml
+++ b/config/metrics/counts_28d/20210216184910_i_package_generic_user_monthly.yml
@@ -1,7 +1,8 @@
---
data_category: optional
key_path: redis_hll_counters.user_packages.i_package_generic_user_monthly
-description: A monthly count of users that have published a generic package to the registry
+description: A monthly count of users that have published a generic package to the
+ registry
product_section: ops
product_stage: package
product_group: group::package
@@ -14,7 +15,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_generic_user
+ - i_package_generic_user
distribution:
- ee
- ce
@@ -22,3 +23,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184913_i_package_golang_user_monthly.yml b/config/metrics/counts_28d/20210216184913_i_package_golang_user_monthly.yml
index 7303436fe3f..c1fcfd38e63 100644
--- a/config/metrics/counts_28d/20210216184913_i_package_golang_user_monthly.yml
+++ b/config/metrics/counts_28d/20210216184913_i_package_golang_user_monthly.yml
@@ -13,7 +13,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_golang_user
+ - i_package_golang_user
distribution:
- ee
- ce
@@ -21,3 +21,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184917_i_package_maven_user_monthly.yml b/config/metrics/counts_28d/20210216184917_i_package_maven_user_monthly.yml
index c4f13984dc9..3fdb957ef0d 100644
--- a/config/metrics/counts_28d/20210216184917_i_package_maven_user_monthly.yml
+++ b/config/metrics/counts_28d/20210216184917_i_package_maven_user_monthly.yml
@@ -7,13 +7,13 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_maven_user
+ - i_package_maven_user
distribution:
- ee
- ce
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184921_i_package_npm_user_monthly.yml b/config/metrics/counts_28d/20210216184921_i_package_npm_user_monthly.yml
index 637de10004e..f945fbf5266 100644
--- a/config/metrics/counts_28d/20210216184921_i_package_npm_user_monthly.yml
+++ b/config/metrics/counts_28d/20210216184921_i_package_npm_user_monthly.yml
@@ -7,13 +7,13 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_npm_user
+ - i_package_npm_user
distribution:
- ee
- ce
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184925_i_package_nuget_user_monthly.yml b/config/metrics/counts_28d/20210216184925_i_package_nuget_user_monthly.yml
index 5a2f03a7b31..782e7788eb2 100644
--- a/config/metrics/counts_28d/20210216184925_i_package_nuget_user_monthly.yml
+++ b/config/metrics/counts_28d/20210216184925_i_package_nuget_user_monthly.yml
@@ -7,13 +7,13 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_nuget_user
+ - i_package_nuget_user
distribution:
- ee
- ce
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184929_i_package_pypi_user_monthly.yml b/config/metrics/counts_28d/20210216184929_i_package_pypi_user_monthly.yml
index fefa5363e25..d86147526e0 100644
--- a/config/metrics/counts_28d/20210216184929_i_package_pypi_user_monthly.yml
+++ b/config/metrics/counts_28d/20210216184929_i_package_pypi_user_monthly.yml
@@ -7,13 +7,13 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_pypi_user
+ - i_package_pypi_user
distribution:
- ee
- ce
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184933_i_package_tag_user_monthly.yml b/config/metrics/counts_28d/20210216184933_i_package_tag_user_monthly.yml
index 9c339dae78e..f8d411c0348 100644
--- a/config/metrics/counts_28d/20210216184933_i_package_tag_user_monthly.yml
+++ b/config/metrics/counts_28d/20210216184933_i_package_tag_user_monthly.yml
@@ -13,7 +13,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_tag_user
+ - i_package_tag_user
distribution:
- ee
- ce
@@ -21,3 +21,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184937_user_packages_total_unique_counts_monthly.yml b/config/metrics/counts_28d/20210216184937_user_packages_total_unique_counts_monthly.yml
index 59d588c543f..98679813670 100644
--- a/config/metrics/counts_28d/20210216184937_user_packages_total_unique_counts_monthly.yml
+++ b/config/metrics/counts_28d/20210216184937_user_packages_total_unique_counts_monthly.yml
@@ -7,26 +7,26 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_composer_user
- - i_package_conan_user
- - i_package_container_user
- - i_package_debian_user
- - i_package_generic_user
- - i_package_golang_user
- - i_package_helm_user
- - i_package_maven_user
- - i_package_npm_user
- - i_package_nuget_user
- - i_package_pypi_user
- - i_package_rubygems_user
- - i_package_tag_user
- - i_package_terraform_module_user
+ - i_package_composer_user
+ - i_package_conan_user
+ - i_package_container_user
+ - i_package_debian_user
+ - i_package_generic_user
+ - i_package_golang_user
+ - i_package_helm_user
+ - i_package_maven_user
+ - i_package_npm_user
+ - i_package_nuget_user
+ - i_package_pypi_user
+ - i_package_rubygems_user
+ - i_package_tag_user
+ - i_package_terraform_module_user
distribution:
- ee
- ce
@@ -37,3 +37,4 @@ tier:
performance_indicator_type:
- smau
- gmau
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184941_i_ecosystem_jira_service_close_issue_monthly.yml b/config/metrics/counts_28d/20210216184941_i_ecosystem_jira_service_close_issue_monthly.yml
index 070a2cd71c3..7c4a4c8b032 100644
--- a/config/metrics/counts_28d/20210216184941_i_ecosystem_jira_service_close_issue_monthly.yml
+++ b/config/metrics/counts_28d/20210216184941_i_ecosystem_jira_service_close_issue_monthly.yml
@@ -7,13 +7,13 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_ecosystem_jira_service_close_issue
+ - i_ecosystem_jira_service_close_issue
distribution:
- ce
- ee
@@ -21,3 +21,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184945_i_ecosystem_jira_service_cross_reference_monthly.yml b/config/metrics/counts_28d/20210216184945_i_ecosystem_jira_service_cross_reference_monthly.yml
index dd977ce2f4d..2e41282a9cf 100644
--- a/config/metrics/counts_28d/20210216184945_i_ecosystem_jira_service_cross_reference_monthly.yml
+++ b/config/metrics/counts_28d/20210216184945_i_ecosystem_jira_service_cross_reference_monthly.yml
@@ -7,13 +7,13 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_ecosystem_jira_service_cross_reference
+ - i_ecosystem_jira_service_cross_reference
distribution:
- ce
- ee
@@ -21,3 +21,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210216184957_ecosystem_total_unique_counts_monthly.yml b/config/metrics/counts_28d/20210216184957_ecosystem_total_unique_counts_monthly.yml
index 33d805a0905..1c89217829c 100644
--- a/config/metrics/counts_28d/20210216184957_ecosystem_total_unique_counts_monthly.yml
+++ b/config/metrics/counts_28d/20210216184957_ecosystem_total_unique_counts_monthly.yml
@@ -7,25 +7,25 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_ecosystem_jira_service_close_issue
- - i_ecosystem_jira_service_cross_reference
- - i_ecosystem_jira_service_list_issues
- - i_ecosystem_jira_service_create_issue
- - i_ecosystem_slack_service_issue_notification
- - i_ecosystem_slack_service_push_notification
- - i_ecosystem_slack_service_deployment_notification
- - i_ecosystem_slack_service_wiki_page_notification
- - i_ecosystem_slack_service_merge_request_notification
- - i_ecosystem_slack_service_note_notification
- - i_ecosystem_slack_service_tag_push_notification
- - i_ecosystem_slack_service_confidential_note_notification
- - i_ecosystem_slack_service_confidential_issue_notification
+ - i_ecosystem_jira_service_close_issue
+ - i_ecosystem_jira_service_cross_reference
+ - i_ecosystem_jira_service_list_issues
+ - i_ecosystem_jira_service_create_issue
+ - i_ecosystem_slack_service_issue_notification
+ - i_ecosystem_slack_service_push_notification
+ - i_ecosystem_slack_service_deployment_notification
+ - i_ecosystem_slack_service_wiki_page_notification
+ - i_ecosystem_slack_service_merge_request_notification
+ - i_ecosystem_slack_service_note_notification
+ - i_ecosystem_slack_service_tag_push_notification
+ - i_ecosystem_slack_service_confidential_note_notification
+ - i_ecosystem_slack_service_confidential_issue_notification
distribution:
- ce
- ee
@@ -36,3 +36,5 @@ tier:
performance_indicator_type:
- gmau
- paid_gmau
+- smau
+milestone: "<13.9"
diff --git a/config/metrics/counts_28d/20210222041219_i_quickactions_invite_email_single_monthly.yml b/config/metrics/counts_28d/20210222041219_i_quickactions_invite_email_single_monthly.yml
index 0ed31fa36d7..660f3675359 100644
--- a/config/metrics/counts_28d/20210222041219_i_quickactions_invite_email_single_monthly.yml
+++ b/config/metrics/counts_28d/20210222041219_i_quickactions_invite_email_single_monthly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::product planning
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49264
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210222041235_i_quickactions_invite_email_multiple_monthly.yml b/config/metrics/counts_28d/20210222041235_i_quickactions_invite_email_multiple_monthly.yml
index e7e6ecd5d3c..bd178cb07bc 100644
--- a/config/metrics/counts_28d/20210222041235_i_quickactions_invite_email_multiple_monthly.yml
+++ b/config/metrics/counts_28d/20210222041235_i_quickactions_invite_email_multiple_monthly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::product planning
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49264
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210301102134_i_code_review_user_time_estimate_changed_monthly.yml b/config/metrics/counts_28d/20210301102134_i_code_review_user_time_estimate_changed_monthly.yml
index c6447db3ccb..2a7484f710a 100644
--- a/config/metrics/counts_28d/20210301102134_i_code_review_user_time_estimate_changed_monthly.yml
+++ b/config/metrics/counts_28d/20210301102134_i_code_review_user_time_estimate_changed_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55046
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210301102204_i_code_review_user_time_spent_changed_monthly.yml b/config/metrics/counts_28d/20210301102204_i_code_review_user_time_spent_changed_monthly.yml
index 277060a93a9..febb6ea8464 100644
--- a/config/metrics/counts_28d/20210301102204_i_code_review_user_time_spent_changed_monthly.yml
+++ b/config/metrics/counts_28d/20210301102204_i_code_review_user_time_spent_changed_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55046
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210301103859_i_code_review_user_mr_discussion_locked_monthly.yml b/config/metrics/counts_28d/20210301103859_i_code_review_user_mr_discussion_locked_monthly.yml
index e9b8ac665ac..d5b943fbed4 100644
--- a/config/metrics/counts_28d/20210301103859_i_code_review_user_mr_discussion_locked_monthly.yml
+++ b/config/metrics/counts_28d/20210301103859_i_code_review_user_mr_discussion_locked_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55069
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210301103925_i_code_review_user_mr_discussion_unlocked_monthly.yml b/config/metrics/counts_28d/20210301103925_i_code_review_user_mr_discussion_unlocked_monthly.yml
index b1380590eb2..022047e7d0e 100644
--- a/config/metrics/counts_28d/20210301103925_i_code_review_user_mr_discussion_unlocked_monthly.yml
+++ b/config/metrics/counts_28d/20210301103925_i_code_review_user_mr_discussion_unlocked_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55069
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210301144228_o_pipeline_authoring_unique_users_pushing_mr_ciconfigfile_monthly.yml b/config/metrics/counts_28d/20210301144228_o_pipeline_authoring_unique_users_pushing_mr_ciconfigfile_monthly.yml
index 3f71aff89d5..41e0d1c4a4d 100644
--- a/config/metrics/counts_28d/20210301144228_o_pipeline_authoring_unique_users_pushing_mr_ciconfigfile_monthly.yml
+++ b/config/metrics/counts_28d/20210301144228_o_pipeline_authoring_unique_users_pushing_mr_ciconfigfile_monthly.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline authoring
product_category: pipeline_authoring
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54707
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210302110520_i_code_review_user_milestone_changed_monthly.yml b/config/metrics/counts_28d/20210302110520_i_code_review_user_milestone_changed_monthly.yml
index e5530f3a5de..6fc1b724468 100644
--- a/config/metrics/counts_28d/20210302110520_i_code_review_user_milestone_changed_monthly.yml
+++ b/config/metrics/counts_28d/20210302110520_i_code_review_user_milestone_changed_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55484
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210302110607_i_code_review_user_labels_changed_monthly.yml b/config/metrics/counts_28d/20210302110607_i_code_review_user_labels_changed_monthly.yml
index 7ce83b31a76..644a09ffc23 100644
--- a/config/metrics/counts_28d/20210302110607_i_code_review_user_labels_changed_monthly.yml
+++ b/config/metrics/counts_28d/20210302110607_i_code_review_user_labels_changed_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55484
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210302114145_i_code_review_user_assignees_changed_monthly.yml b/config/metrics/counts_28d/20210302114145_i_code_review_user_assignees_changed_monthly.yml
index c0dd76951a5..a72f0675c6f 100644
--- a/config/metrics/counts_28d/20210302114145_i_code_review_user_assignees_changed_monthly.yml
+++ b/config/metrics/counts_28d/20210302114145_i_code_review_user_assignees_changed_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55486
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210302114219_i_code_review_user_reviewers_changed_monthly.yml b/config/metrics/counts_28d/20210302114219_i_code_review_user_reviewers_changed_monthly.yml
index 60ad9493fee..679cef614ef 100644
--- a/config/metrics/counts_28d/20210302114219_i_code_review_user_reviewers_changed_monthly.yml
+++ b/config/metrics/counts_28d/20210302114219_i_code_review_user_reviewers_changed_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55486
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210303150507_i_ecosystem_slack_service_issue_notification_monthly.yml b/config/metrics/counts_28d/20210303150507_i_ecosystem_slack_service_issue_notification_monthly.yml
index 61bacd93dd1..5bee115d9d3 100644
--- a/config/metrics/counts_28d/20210303150507_i_ecosystem_slack_service_issue_notification_monthly.yml
+++ b/config/metrics/counts_28d/20210303150507_i_ecosystem_slack_service_issue_notification_monthly.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54347
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210303150654_i_ecosystem_slack_service_push_notification_monthly.yml b/config/metrics/counts_28d/20210303150654_i_ecosystem_slack_service_push_notification_monthly.yml
index 2741c56f551..3860335ef8e 100644
--- a/config/metrics/counts_28d/20210303150654_i_ecosystem_slack_service_push_notification_monthly.yml
+++ b/config/metrics/counts_28d/20210303150654_i_ecosystem_slack_service_push_notification_monthly.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54347
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210303150912_i_ecosystem_slack_service_deployment_notification_monthly.yml b/config/metrics/counts_28d/20210303150912_i_ecosystem_slack_service_deployment_notification_monthly.yml
index 42ec4cb35d4..69b0bcb7181 100644
--- a/config/metrics/counts_28d/20210303150912_i_ecosystem_slack_service_deployment_notification_monthly.yml
+++ b/config/metrics/counts_28d/20210303150912_i_ecosystem_slack_service_deployment_notification_monthly.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54347
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210303151609_i_ecosystem_slack_service_wiki_page_notification_monthly.yml b/config/metrics/counts_28d/20210303151609_i_ecosystem_slack_service_wiki_page_notification_monthly.yml
index 270409ed250..3a2d77b811a 100644
--- a/config/metrics/counts_28d/20210303151609_i_ecosystem_slack_service_wiki_page_notification_monthly.yml
+++ b/config/metrics/counts_28d/20210303151609_i_ecosystem_slack_service_wiki_page_notification_monthly.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54347
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210303151831_i_ecosystem_slack_service_merge_request_notification_monthly.yml b/config/metrics/counts_28d/20210303151831_i_ecosystem_slack_service_merge_request_notification_monthly.yml
index aee3342e1e0..e9f1ad972f7 100644
--- a/config/metrics/counts_28d/20210303151831_i_ecosystem_slack_service_merge_request_notification_monthly.yml
+++ b/config/metrics/counts_28d/20210303151831_i_ecosystem_slack_service_merge_request_notification_monthly.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54347
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210303151946_i_ecosystem_slack_service_note_notification_monthly.yml b/config/metrics/counts_28d/20210303151946_i_ecosystem_slack_service_note_notification_monthly.yml
index 9aa3fa248dc..d30874198d0 100644
--- a/config/metrics/counts_28d/20210303151946_i_ecosystem_slack_service_note_notification_monthly.yml
+++ b/config/metrics/counts_28d/20210303151946_i_ecosystem_slack_service_note_notification_monthly.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54347
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210303152049_i_ecosystem_slack_service_tag_push_notification_monthly.yml b/config/metrics/counts_28d/20210303152049_i_ecosystem_slack_service_tag_push_notification_monthly.yml
index 5144abd28ed..3f58d21ae15 100644
--- a/config/metrics/counts_28d/20210303152049_i_ecosystem_slack_service_tag_push_notification_monthly.yml
+++ b/config/metrics/counts_28d/20210303152049_i_ecosystem_slack_service_tag_push_notification_monthly.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54347
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210303152144_i_ecosystem_slack_service_confidential_note_notification_monthly.yml b/config/metrics/counts_28d/20210303152144_i_ecosystem_slack_service_confidential_note_notification_monthly.yml
index 530f26aefa3..516b1385474 100644
--- a/config/metrics/counts_28d/20210303152144_i_ecosystem_slack_service_confidential_note_notification_monthly.yml
+++ b/config/metrics/counts_28d/20210303152144_i_ecosystem_slack_service_confidential_note_notification_monthly.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54347
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210303152233_i_ecosystem_slack_service_confidential_issue_notification_monthly.yml b/config/metrics/counts_28d/20210303152233_i_ecosystem_slack_service_confidential_issue_notification_monthly.yml
index 10e5deefae6..e959116a4fa 100644
--- a/config/metrics/counts_28d/20210303152233_i_ecosystem_slack_service_confidential_issue_notification_monthly.yml
+++ b/config/metrics/counts_28d/20210303152233_i_ecosystem_slack_service_confidential_issue_notification_monthly.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54347
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210303154626_i_package_rubygems_deploy_token_monthly.yml b/config/metrics/counts_28d/20210303154626_i_package_rubygems_deploy_token_monthly.yml
index 608cb715558..07fd63aacec 100644
--- a/config/metrics/counts_28d/20210303154626_i_package_rubygems_deploy_token_monthly.yml
+++ b/config/metrics/counts_28d/20210303154626_i_package_rubygems_deploy_token_monthly.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package_registry
value_type: number
-status: data_available
+status: active
milestone: '13.10'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53480
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210303154654_i_package_rubygems_user_monthly.yml b/config/metrics/counts_28d/20210303154654_i_package_rubygems_user_monthly.yml
index 2a9d959abba..e7ecbddda51 100644
--- a/config/metrics/counts_28d/20210303154654_i_package_rubygems_user_monthly.yml
+++ b/config/metrics/counts_28d/20210303154654_i_package_rubygems_user_monthly.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package_registry
value_type: number
-status: data_available
+status: active
milestone: '13.10'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53480
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210409095855_users_expanding_secure_security_report_monthly.yml b/config/metrics/counts_28d/20210409095855_users_expanding_secure_security_report_monthly.yml
index 18c3f96be6a..5a2d55f35a0 100644
--- a/config/metrics/counts_28d/20210409095855_users_expanding_secure_security_report_monthly.yml
+++ b/config/metrics/counts_28d/20210409095855_users_expanding_secure_security_report_monthly.yml
@@ -7,7 +7,7 @@ product_stage: secure
product_group: group::static analysis
product_category: dependency_scanning
value_type: number
-status: data_available
+status: active
milestone: '13.11'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57133
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210409100451_users_expanding_testing_code_quality_report_monthly.yml b/config/metrics/counts_28d/20210409100451_users_expanding_testing_code_quality_report_monthly.yml
index d9b6ad05ac6..2a4023c2e8a 100644
--- a/config/metrics/counts_28d/20210409100451_users_expanding_testing_code_quality_report_monthly.yml
+++ b/config/metrics/counts_28d/20210409100451_users_expanding_testing_code_quality_report_monthly.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::testing
product_category: code_quality
value_type: number
-status: data_available
+status: active
milestone: '13.11'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57133
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210409100628_users_expanding_testing_accessibility_report_monthly.yml b/config/metrics/counts_28d/20210409100628_users_expanding_testing_accessibility_report_monthly.yml
index 3767fedeb86..2332bce99a8 100644
--- a/config/metrics/counts_28d/20210409100628_users_expanding_testing_accessibility_report_monthly.yml
+++ b/config/metrics/counts_28d/20210409100628_users_expanding_testing_accessibility_report_monthly.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::testing
product_category: accessibility_testing
value_type: number
-status: data_available
+status: active
milestone: '13.11'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57133
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210410012206_i_package_terraform_module_deploy_token_monthly.yml b/config/metrics/counts_28d/20210410012206_i_package_terraform_module_deploy_token_monthly.yml
index e5c895e7997..d55ba9c7937 100644
--- a/config/metrics/counts_28d/20210410012206_i_package_terraform_module_deploy_token_monthly.yml
+++ b/config/metrics/counts_28d/20210410012206_i_package_terraform_module_deploy_token_monthly.yml
@@ -7,7 +7,7 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: data_available
+status: active
milestone: '13.11'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55018
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210410012208_i_package_terraform_module_user_monthly.yml b/config/metrics/counts_28d/20210410012208_i_package_terraform_module_user_monthly.yml
index 2dfc10652ea..58700643680 100644
--- a/config/metrics/counts_28d/20210410012208_i_package_terraform_module_user_monthly.yml
+++ b/config/metrics/counts_28d/20210410012208_i_package_terraform_module_user_monthly.yml
@@ -7,7 +7,7 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: data_available
+status: active
milestone: '13.11'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55018
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210413205507_i_testing_summary_widget_total_monthly.yml b/config/metrics/counts_28d/20210413205507_i_testing_summary_widget_total_monthly.yml
index e71f298b992..41be8f98889 100644
--- a/config/metrics/counts_28d/20210413205507_i_testing_summary_widget_total_monthly.yml
+++ b/config/metrics/counts_28d/20210413205507_i_testing_summary_widget_total_monthly.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::testing
product_category: testing
value_type: number
-status: data_available
+status: active
milestone: "13.11"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59316
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210421144352_i_code_review_click_single_file_mode_setting_monthly.yml b/config/metrics/counts_28d/20210421144352_i_code_review_click_single_file_mode_setting_monthly.yml
index 5fea551038a..da9bc2493a7 100644
--- a/config/metrics/counts_28d/20210421144352_i_code_review_click_single_file_mode_setting_monthly.yml
+++ b/config/metrics/counts_28d/20210421144352_i_code_review_click_single_file_mode_setting_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210421145818_i_code_review_click_file_browser_setting_monthly.yml b/config/metrics/counts_28d/20210421145818_i_code_review_click_file_browser_setting_monthly.yml
index 6a1b63c25f7..5a4cf3692ae 100644
--- a/config/metrics/counts_28d/20210421145818_i_code_review_click_file_browser_setting_monthly.yml
+++ b/config/metrics/counts_28d/20210421145818_i_code_review_click_file_browser_setting_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210421145945_i_code_review_click_whitespace_setting_monthly.yml b/config/metrics/counts_28d/20210421145945_i_code_review_click_whitespace_setting_monthly.yml
index f8d978844a9..a378c9eb07f 100644
--- a/config/metrics/counts_28d/20210421145945_i_code_review_click_whitespace_setting_monthly.yml
+++ b/config/metrics/counts_28d/20210421145945_i_code_review_click_whitespace_setting_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210422101516_i_code_review_diff_view_inline_monthly.yml b/config/metrics/counts_28d/20210422101516_i_code_review_diff_view_inline_monthly.yml
index d86772cea6b..3d271e3b38f 100644
--- a/config/metrics/counts_28d/20210422101516_i_code_review_diff_view_inline_monthly.yml
+++ b/config/metrics/counts_28d/20210422101516_i_code_review_diff_view_inline_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210422101613_i_code_review_diff_view_parallel_monthly.yml b/config/metrics/counts_28d/20210422101613_i_code_review_diff_view_parallel_monthly.yml
index d3d2889dfa3..0e2f0430a38 100644
--- a/config/metrics/counts_28d/20210422101613_i_code_review_diff_view_parallel_monthly.yml
+++ b/config/metrics/counts_28d/20210422101613_i_code_review_diff_view_parallel_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210422101753_i_code_review_file_browser_tree_view_monthly.yml b/config/metrics/counts_28d/20210422101753_i_code_review_file_browser_tree_view_monthly.yml
index 55fe49b2639..1bbf3a04418 100644
--- a/config/metrics/counts_28d/20210422101753_i_code_review_file_browser_tree_view_monthly.yml
+++ b/config/metrics/counts_28d/20210422101753_i_code_review_file_browser_tree_view_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210422101852_i_code_review_file_browser_list_view_monthly.yml b/config/metrics/counts_28d/20210422101852_i_code_review_file_browser_list_view_monthly.yml
index d26aa837f26..8aeb80499ae 100644
--- a/config/metrics/counts_28d/20210422101852_i_code_review_file_browser_list_view_monthly.yml
+++ b/config/metrics/counts_28d/20210422101852_i_code_review_file_browser_list_view_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210422101928_i_code_review_diff_show_whitespace_monthly.yml b/config/metrics/counts_28d/20210422101928_i_code_review_diff_show_whitespace_monthly.yml
index 06a8b55ff62..306eeddc25b 100644
--- a/config/metrics/counts_28d/20210422101928_i_code_review_diff_show_whitespace_monthly.yml
+++ b/config/metrics/counts_28d/20210422101928_i_code_review_diff_show_whitespace_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210422102010_i_code_review_diff_hide_whitespace_monthly.yml b/config/metrics/counts_28d/20210422102010_i_code_review_diff_hide_whitespace_monthly.yml
index 6095e9ec05d..ef8410fdb7b 100644
--- a/config/metrics/counts_28d/20210422102010_i_code_review_diff_hide_whitespace_monthly.yml
+++ b/config/metrics/counts_28d/20210422102010_i_code_review_diff_hide_whitespace_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210422102121_i_code_review_diff_single_file_monthly.yml b/config/metrics/counts_28d/20210422102121_i_code_review_diff_single_file_monthly.yml
index 58c7aafd9de..76fe3b835fa 100644
--- a/config/metrics/counts_28d/20210422102121_i_code_review_diff_single_file_monthly.yml
+++ b/config/metrics/counts_28d/20210422102121_i_code_review_diff_single_file_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210422102202_i_code_review_diff_multiple_files_monthly.yml b/config/metrics/counts_28d/20210422102202_i_code_review_diff_multiple_files_monthly.yml
index 9af4cab1e87..9ab2bd2e48a 100644
--- a/config/metrics/counts_28d/20210422102202_i_code_review_diff_multiple_files_monthly.yml
+++ b/config/metrics/counts_28d/20210422102202_i_code_review_diff_multiple_files_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210427102618_code_review_category_monthly_active_users.yml b/config/metrics/counts_28d/20210427102618_code_review_category_monthly_active_users.yml
index d341ce11ec4..be0fa6eaff7 100644
--- a/config/metrics/counts_28d/20210427102618_code_review_category_monthly_active_users.yml
+++ b/config/metrics/counts_28d/20210427102618_code_review_category_monthly_active_users.yml
@@ -1,18 +1,16 @@
---
data_category: optional
key_path: counts_monthly.aggregated_metrics.code_review_category_monthly_active_users
-name: "0"
-description:
-product_section:
-product_stage:
-product_group:
+description: Unique users performing actions on code review events
+product_section: dev
+product_stage: devops::create
+product_group: group::code review
product_category:
value_type: number
-status: data_available
+status: active
milestone: "13.12"
-introduced_by_url:
time_frame: 28d
-data_source:
+data_source: redis_hll
distribution:
- ce
- ee
@@ -20,5 +18,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
diff --git a/config/metrics/counts_28d/20210427103010_code_review_extension_category_monthly_active_users.yml b/config/metrics/counts_28d/20210427103010_code_review_extension_category_monthly_active_users.yml
index e263777a2dd..1e196ab49c4 100644
--- a/config/metrics/counts_28d/20210427103010_code_review_extension_category_monthly_active_users.yml
+++ b/config/metrics/counts_28d/20210427103010_code_review_extension_category_monthly_active_users.yml
@@ -1,18 +1,17 @@
---
data_category: optional
key_path: counts_monthly.aggregated_metrics.code_review_extension_category_monthly_active_users
-name: "0"
-description:
-product_section:
-product_stage:
-product_group:
+description: Number of users performing i_code_review_user_vs_code_api_request event
+product_section: dev
+product_stage: devops::create
+product_group: group::code review
product_category:
value_type: number
-status: data_available
+status: active
milestone: "13.12"
-introduced_by_url:
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53553
time_frame: 28d
-data_source:
+data_source: redis_hll
distribution:
- ce
- ee
@@ -20,5 +19,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
diff --git a/config/metrics/counts_28d/20210427103119_code_review_group_monthly_active_users.yml b/config/metrics/counts_28d/20210427103119_code_review_group_monthly_active_users.yml
index fbe5fba73be..3d66f1cdf8c 100644
--- a/config/metrics/counts_28d/20210427103119_code_review_group_monthly_active_users.yml
+++ b/config/metrics/counts_28d/20210427103119_code_review_group_monthly_active_users.yml
@@ -1,18 +1,17 @@
---
data_category: optional
key_path: counts_monthly.aggregated_metrics.code_review_group_monthly_active_users
-name: "0"
-description:
-product_section:
-product_stage:
-product_group:
+description: Number of users performing at least one of the code review events
+product_section: dev
+product_stage: devops::create
+product_group: group::code review
product_category:
value_type: number
-status: data_available
+status: active
milestone: "13.12"
-introduced_by_url:
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53553
time_frame: 28d
-data_source:
+data_source: redis_hll
distribution:
- ce
- ee
@@ -20,5 +19,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
diff --git a/config/metrics/counts_28d/20210427105033_pipeline_authoring_total_unique_counts_monthly.yml b/config/metrics/counts_28d/20210427105033_pipeline_authoring_total_unique_counts_monthly.yml
index eda0f937450..b37c149ec11 100644
--- a/config/metrics/counts_28d/20210427105033_pipeline_authoring_total_unique_counts_monthly.yml
+++ b/config/metrics/counts_28d/20210427105033_pipeline_authoring_total_unique_counts_monthly.yml
@@ -1,14 +1,13 @@
---
data_category: optional
key_path: redis_hll_counters.pipeline_authoring.pipeline_authoring_total_unique_counts_monthly
-name: "0"
-description:
-product_section:
-product_stage:
-product_group:
-product_category:
+description: Unique users doing commits or push MRs which contains CI cifig file
+product_section: ops
+product_stage: verify
+product_group: group::pipeline authoring
+product_category: pipeline_authoring
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url:
time_frame: 28d
@@ -25,4 +24,3 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
diff --git a/config/metrics/counts_28d/20210427213346_geo_secondary_web_oauth_users.yml b/config/metrics/counts_28d/20210427213346_geo_secondary_web_oauth_users.yml
deleted file mode 100644
index c74b28e0546..00000000000
--- a/config/metrics/counts_28d/20210427213346_geo_secondary_web_oauth_users.yml
+++ /dev/null
@@ -1,26 +0,0 @@
----
-data_category: optional
-key_path: usage_activity_by_stage_monthly.enablement.geo_secondary_web_oauth_users
-name: ""
-description:
-product_section:
-product_stage:
-product_group:
-product_category:
-value_type: number
-status: data_available
-milestone: "13.12"
-introduced_by_url:
-time_frame: 28d
-data_source:
-distribution:
-- ce
-- ee
-tier:
-- free
-- premium
-- ultimate
-skip_validation: true
-performance_indicator_type:
-- gmau
-- paid_gmau
diff --git a/config/metrics/counts_28d/20210514013545_i_code_review_user_resolve_conflict_monthly.yml b/config/metrics/counts_28d/20210514013545_i_code_review_user_resolve_conflict_monthly.yml
index 596063e4a43..8ce25e2d976 100644
--- a/config/metrics/counts_28d/20210514013545_i_code_review_user_resolve_conflict_monthly.yml
+++ b/config/metrics/counts_28d/20210514013545_i_code_review_user_resolve_conflict_monthly.yml
@@ -8,7 +8,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: "13.12"
time_frame: 28d
data_source: redis_hll
diff --git a/config/metrics/counts_28d/20210514013549_i_code_review_user_load_conflict_ui_monthly.yml b/config/metrics/counts_28d/20210514013549_i_code_review_user_load_conflict_ui_monthly.yml
index c793a2887d8..b287346496b 100644
--- a/config/metrics/counts_28d/20210514013549_i_code_review_user_load_conflict_ui_monthly.yml
+++ b/config/metrics/counts_28d/20210514013549_i_code_review_user_load_conflict_ui_monthly.yml
@@ -8,7 +8,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: "13.12"
time_frame: 28d
data_source: redis_hll
diff --git a/config/metrics/counts_28d/20210514141518_monthly_projects_creation.yml b/config/metrics/counts_28d/20210514141518_monthly_projects_creation.yml
index abf16d3dee9..7b39c8a3996 100644
--- a/config/metrics/counts_28d/20210514141518_monthly_projects_creation.yml
+++ b/config/metrics/counts_28d/20210514141518_monthly_projects_creation.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: ''
value_type: number
-status: implemented
+status: active
milestone: "14.0"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61775
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210517074859_i_package_helm_deploy_token_monthly.yml b/config/metrics/counts_28d/20210517074859_i_package_helm_deploy_token_monthly.yml
index 266c5b1cad8..e891843a68d 100644
--- a/config/metrics/counts_28d/20210517074859_i_package_helm_deploy_token_monthly.yml
+++ b/config/metrics/counts_28d/20210517074859_i_package_helm_deploy_token_monthly.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package_registry
value_type: number
-status: implemented
+status: active
milestone: "14.0"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61014
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210517075259_i_package_helm_user_monthly.yml b/config/metrics/counts_28d/20210517075259_i_package_helm_user_monthly.yml
index 0226e885fe7..3653e1d2b2f 100644
--- a/config/metrics/counts_28d/20210517075259_i_package_helm_user_monthly.yml
+++ b/config/metrics/counts_28d/20210517075259_i_package_helm_user_monthly.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package_registry
value_type: number
-status: implemented
+status: active
milestone: "14.0"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61014
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210520111133_total.yml b/config/metrics/counts_28d/20210520111133_total.yml
index 9470b6f1dff..3da6de21632 100644
--- a/config/metrics/counts_28d/20210520111133_total.yml
+++ b/config/metrics/counts_28d/20210520111133_total.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category:
value_type: number
-status: implemented
+status: active
milestone: "14.0"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61775"
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210607113556_i_code_review_click_diff_view_setting_monthly.yml b/config/metrics/counts_28d/20210607113556_i_code_review_click_diff_view_setting_monthly.yml
index 4a3ec6eb8f2..35dfad5b7a8 100644
--- a/config/metrics/counts_28d/20210607113556_i_code_review_click_diff_view_setting_monthly.yml
+++ b/config/metrics/counts_28d/20210607113556_i_code_review_click_diff_view_setting_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210720144005_i_code_review_user_searches_diff_monthly.yml b/config/metrics/counts_28d/20210720144005_i_code_review_user_searches_diff_monthly.yml
index 8b48a623045..3414cf0e868 100644
--- a/config/metrics/counts_28d/20210720144005_i_code_review_user_searches_diff_monthly.yml
+++ b/config/metrics/counts_28d/20210720144005_i_code_review_user_searches_diff_monthly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: active
milestone: '14.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66522
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210721042227_i_quickactions_severity_monthly.yml b/config/metrics/counts_28d/20210721042227_i_quickactions_severity_monthly.yml
index f23300c3a52..a2af908ea49 100644
--- a/config/metrics/counts_28d/20210721042227_i_quickactions_severity_monthly.yml
+++ b/config/metrics/counts_28d/20210721042227_i_quickactions_severity_monthly.yml
@@ -6,7 +6,7 @@ product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: implemented
+status: active
milestone: "14.2"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66422
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210816143831_i_code_review_total_suggestions_added_monthly.yml b/config/metrics/counts_28d/20210816143831_i_code_review_total_suggestions_added_monthly.yml
new file mode 100644
index 00000000000..a5bd56d0a7d
--- /dev/null
+++ b/config/metrics/counts_28d/20210816143831_i_code_review_total_suggestions_added_monthly.yml
@@ -0,0 +1,27 @@
+---
+key_path: redis_hll_counters.code_review.i_code_review_total_suggestions_added_monthly
+name: "count_notes_with_suggestions_monthly"
+description: Total number of monthly suggestions
+product_section: dev
+product_stage: create
+product_group: group::code review
+product_category: code_review
+value_type: number
+status: active
+milestone: "14.3"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67525
+time_frame: 28d
+data_source: redis_hll
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - i_code_review_total_suggestions_added
+data_category: Optional
+performance_indicator_type: []
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_28d/20210816144453_i_code_review_total_suggestions_applied_monthly.yml b/config/metrics/counts_28d/20210816144453_i_code_review_total_suggestions_applied_monthly.yml
new file mode 100644
index 00000000000..2d4f41f6dff
--- /dev/null
+++ b/config/metrics/counts_28d/20210816144453_i_code_review_total_suggestions_applied_monthly.yml
@@ -0,0 +1,27 @@
+---
+key_path: redis_hll_counters.code_review.i_code_review_total_suggestions_applied_monthly
+name: "count_notes_with_applied_suggestions_monthly"
+description: Total number of monthly suggestions applied
+product_section: dev
+product_stage: create
+product_group: group::code review
+product_category: code_review
+value_type: number
+status: active
+milestone: "14.3"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67525
+time_frame: 28d
+data_source: redis_hll
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - i_code_review_total_suggestions_applied
+data_category: Optional
+performance_indicator_type: []
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_28d/20210901221242_p_ci_templates_terraform_base_monthly.yml b/config/metrics/counts_28d/20210901221242_p_ci_templates_terraform_base_monthly.yml
new file mode 100644
index 00000000000..c0c5de03d6f
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221242_p_ci_templates_terraform_base_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_terraform_base_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_terraform_base
diff --git a/config/metrics/counts_28d/20210901221251_p_ci_templates_dotnet_monthly.yml b/config/metrics/counts_28d/20210901221251_p_ci_templates_dotnet_monthly.yml
new file mode 100644
index 00000000000..5a9cff02906
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221251_p_ci_templates_dotnet_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_dotnet_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_dotnet
diff --git a/config/metrics/counts_28d/20210901221300_p_ci_templates_nodejs_monthly.yml b/config/metrics/counts_28d/20210901221300_p_ci_templates_nodejs_monthly.yml
new file mode 100644
index 00000000000..41f112b57f1
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221300_p_ci_templates_nodejs_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_nodejs_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_nodejs
diff --git a/config/metrics/counts_28d/20210901221308_p_ci_templates_openshift_monthly.yml b/config/metrics/counts_28d/20210901221308_p_ci_templates_openshift_monthly.yml
new file mode 100644
index 00000000000..d95c9cbc109
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221308_p_ci_templates_openshift_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_openshift_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_openshift
diff --git a/config/metrics/counts_28d/20210901221317_p_ci_templates_bash_monthly.yml b/config/metrics/counts_28d/20210901221317_p_ci_templates_bash_monthly.yml
new file mode 100644
index 00000000000..98a953405aa
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221317_p_ci_templates_bash_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_bash_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_bash
diff --git a/config/metrics/counts_28d/20210901221326_p_ci_templates_rust_monthly.yml b/config/metrics/counts_28d/20210901221326_p_ci_templates_rust_monthly.yml
new file mode 100644
index 00000000000..3f920a72e15
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221326_p_ci_templates_rust_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_rust_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_rust
diff --git a/config/metrics/counts_28d/20210901221335_p_ci_templates_elixir_monthly.yml b/config/metrics/counts_28d/20210901221335_p_ci_templates_elixir_monthly.yml
new file mode 100644
index 00000000000..555a6f890bb
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221335_p_ci_templates_elixir_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_elixir_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_elixir
diff --git a/config/metrics/counts_28d/20210901221343_p_ci_templates_clojure_monthly.yml b/config/metrics/counts_28d/20210901221343_p_ci_templates_clojure_monthly.yml
new file mode 100644
index 00000000000..b5f6a658333
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221343_p_ci_templates_clojure_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_clojure_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_clojure
diff --git a/config/metrics/counts_28d/20210901221352_p_ci_templates_crystal_monthly.yml b/config/metrics/counts_28d/20210901221352_p_ci_templates_crystal_monthly.yml
new file mode 100644
index 00000000000..18ebe62b906
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221352_p_ci_templates_crystal_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_crystal_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_crystal
diff --git a/config/metrics/counts_28d/20210901221401_p_ci_templates_getting_started_monthly.yml b/config/metrics/counts_28d/20210901221401_p_ci_templates_getting_started_monthly.yml
new file mode 100644
index 00000000000..09d24d2e7ba
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221401_p_ci_templates_getting_started_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_getting_started_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_getting_started
diff --git a/config/metrics/counts_28d/20210901221410_p_ci_templates_code_quality_monthly.yml b/config/metrics/counts_28d/20210901221410_p_ci_templates_code_quality_monthly.yml
new file mode 100644
index 00000000000..69d3c644a26
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221410_p_ci_templates_code_quality_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_code_quality_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_code_quality
diff --git a/config/metrics/counts_28d/20210901221418_p_ci_templates_verify_load_performance_testing_monthly.yml b/config/metrics/counts_28d/20210901221418_p_ci_templates_verify_load_performance_testing_monthly.yml
new file mode 100644
index 00000000000..e0613d891d0
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221418_p_ci_templates_verify_load_performance_testing_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_verify_load_performance_testing_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_verify_load_performance_testing
diff --git a/config/metrics/counts_28d/20210901221427_p_ci_templates_verify_accessibility_monthly.yml b/config/metrics/counts_28d/20210901221427_p_ci_templates_verify_accessibility_monthly.yml
new file mode 100644
index 00000000000..251818174b5
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221427_p_ci_templates_verify_accessibility_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_verify_accessibility_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_verify_accessibility
diff --git a/config/metrics/counts_28d/20210901221436_p_ci_templates_verify_failfast_monthly.yml b/config/metrics/counts_28d/20210901221436_p_ci_templates_verify_failfast_monthly.yml
new file mode 100644
index 00000000000..5af12fc9ae1
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221436_p_ci_templates_verify_failfast_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_verify_failfast_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_verify_failfast
diff --git a/config/metrics/counts_28d/20210901221445_p_ci_templates_verify_browser_performance_monthly.yml b/config/metrics/counts_28d/20210901221445_p_ci_templates_verify_browser_performance_monthly.yml
new file mode 100644
index 00000000000..9baa924ab54
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221445_p_ci_templates_verify_browser_performance_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_verify_browser_performance_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_verify_browser_performance
diff --git a/config/metrics/counts_28d/20210901221454_p_ci_templates_verify_browser_performance_latest_monthly.yml b/config/metrics/counts_28d/20210901221454_p_ci_templates_verify_browser_performance_latest_monthly.yml
new file mode 100644
index 00000000000..d50535100b2
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221454_p_ci_templates_verify_browser_performance_latest_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_verify_browser_performance_latest_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_verify_browser_performance_latest
diff --git a/config/metrics/counts_28d/20210901221503_p_ci_templates_grails_monthly.yml b/config/metrics/counts_28d/20210901221503_p_ci_templates_grails_monthly.yml
new file mode 100644
index 00000000000..fa17dac5c95
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221503_p_ci_templates_grails_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_grails_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_grails
diff --git a/config/metrics/counts_28d/20210901221511_p_ci_templates_security_dast_runner_validation_monthly.yml b/config/metrics/counts_28d/20210901221511_p_ci_templates_security_dast_runner_validation_monthly.yml
new file mode 100644
index 00000000000..ee5778aa20a
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221511_p_ci_templates_security_dast_runner_validation_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_dast_runner_validation_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_dast_runner_validation
diff --git a/config/metrics/counts_28d/20210901221520_p_ci_templates_security_dast_on_demand_scan_monthly.yml b/config/metrics/counts_28d/20210901221520_p_ci_templates_security_dast_on_demand_scan_monthly.yml
new file mode 100644
index 00000000000..25a8772f26c
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221520_p_ci_templates_security_dast_on_demand_scan_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_dast_on_demand_scan_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_dast_on_demand_scan
diff --git a/config/metrics/counts_28d/20210901221529_p_ci_templates_security_license_scanning_monthly.yml b/config/metrics/counts_28d/20210901221529_p_ci_templates_security_license_scanning_monthly.yml
new file mode 100644
index 00000000000..52050daf8a5
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221529_p_ci_templates_security_license_scanning_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_license_scanning_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_license_scanning
diff --git a/config/metrics/counts_28d/20210901221538_p_ci_templates_security_coverage_fuzzing_monthly.yml b/config/metrics/counts_28d/20210901221538_p_ci_templates_security_coverage_fuzzing_monthly.yml
new file mode 100644
index 00000000000..e04854b1ea2
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221538_p_ci_templates_security_coverage_fuzzing_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_coverage_fuzzing_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_coverage_fuzzing
diff --git a/config/metrics/counts_28d/20210901221547_p_ci_templates_security_api_fuzzing_latest_monthly.yml b/config/metrics/counts_28d/20210901221547_p_ci_templates_security_api_fuzzing_latest_monthly.yml
new file mode 100644
index 00000000000..511602c7c28
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221547_p_ci_templates_security_api_fuzzing_latest_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_api_fuzzing_latest_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_api_fuzzing_latest
diff --git a/config/metrics/counts_28d/20210901221556_p_ci_templates_security_secure_binaries_monthly.yml b/config/metrics/counts_28d/20210901221556_p_ci_templates_security_secure_binaries_monthly.yml
new file mode 100644
index 00000000000..ae18f69469d
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221556_p_ci_templates_security_secure_binaries_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_secure_binaries_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_secure_binaries
diff --git a/config/metrics/counts_28d/20210901221605_p_ci_templates_security_dast_api_monthly.yml b/config/metrics/counts_28d/20210901221605_p_ci_templates_security_dast_api_monthly.yml
new file mode 100644
index 00000000000..84fae41c611
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221605_p_ci_templates_security_dast_api_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_dast_api_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_dast_api
diff --git a/config/metrics/counts_28d/20210901221614_p_ci_templates_security_container_scanning_monthly.yml b/config/metrics/counts_28d/20210901221614_p_ci_templates_security_container_scanning_monthly.yml
new file mode 100644
index 00000000000..37440c240ec
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221614_p_ci_templates_security_container_scanning_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_container_scanning_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_container_scanning
diff --git a/config/metrics/counts_28d/20210901221623_p_ci_templates_security_dast_latest_monthly.yml b/config/metrics/counts_28d/20210901221623_p_ci_templates_security_dast_latest_monthly.yml
new file mode 100644
index 00000000000..ff73e16a84b
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221623_p_ci_templates_security_dast_latest_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_dast_latest_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_dast_latest
diff --git a/config/metrics/counts_28d/20210901221632_p_ci_templates_security_dependency_scanning_monthly.yml b/config/metrics/counts_28d/20210901221632_p_ci_templates_security_dependency_scanning_monthly.yml
new file mode 100644
index 00000000000..5015909a1be
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221632_p_ci_templates_security_dependency_scanning_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_dependency_scanning_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_dependency_scanning
diff --git a/config/metrics/counts_28d/20210901221641_p_ci_templates_security_api_fuzzing_monthly.yml b/config/metrics/counts_28d/20210901221641_p_ci_templates_security_api_fuzzing_monthly.yml
new file mode 100644
index 00000000000..e21e7cbcaae
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221641_p_ci_templates_security_api_fuzzing_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_api_fuzzing_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_api_fuzzing
diff --git a/config/metrics/counts_28d/20210901221650_p_ci_templates_security_dast_monthly.yml b/config/metrics/counts_28d/20210901221650_p_ci_templates_security_dast_monthly.yml
new file mode 100644
index 00000000000..6b5b028aa2d
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221650_p_ci_templates_security_dast_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_dast_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_dast
diff --git a/config/metrics/counts_28d/20210901221659_p_ci_templates_security_cluster_image_scanning_monthly.yml b/config/metrics/counts_28d/20210901221659_p_ci_templates_security_cluster_image_scanning_monthly.yml
new file mode 100644
index 00000000000..f3a696627fe
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221659_p_ci_templates_security_cluster_image_scanning_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_cluster_image_scanning_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_cluster_image_scanning
diff --git a/config/metrics/counts_28d/20210901221708_p_ci_templates_ios_fastlane_monthly.yml b/config/metrics/counts_28d/20210901221708_p_ci_templates_ios_fastlane_monthly.yml
new file mode 100644
index 00000000000..7fa3decd102
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221708_p_ci_templates_ios_fastlane_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_ios_fastlane_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_ios_fastlane
diff --git a/config/metrics/counts_28d/20210901221717_p_ci_templates_composer_monthly.yml b/config/metrics/counts_28d/20210901221717_p_ci_templates_composer_monthly.yml
new file mode 100644
index 00000000000..6f18d8f2be4
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221717_p_ci_templates_composer_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_composer_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_composer
diff --git a/config/metrics/counts_28d/20210901221726_p_ci_templates_c_monthly.yml b/config/metrics/counts_28d/20210901221726_p_ci_templates_c_monthly.yml
new file mode 100644
index 00000000000..a9646741a9e
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221726_p_ci_templates_c_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_c_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_c
diff --git a/config/metrics/counts_28d/20210901221735_p_ci_templates_python_monthly.yml b/config/metrics/counts_28d/20210901221735_p_ci_templates_python_monthly.yml
new file mode 100644
index 00000000000..435cbb1f4ff
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221735_p_ci_templates_python_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_python_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_python
diff --git a/config/metrics/counts_28d/20210901221744_p_ci_templates_android_fastlane_monthly.yml b/config/metrics/counts_28d/20210901221744_p_ci_templates_android_fastlane_monthly.yml
new file mode 100644
index 00000000000..356114d1182
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221744_p_ci_templates_android_fastlane_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_android_fastlane_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_android_fastlane
diff --git a/config/metrics/counts_28d/20210901221754_p_ci_templates_django_monthly.yml b/config/metrics/counts_28d/20210901221754_p_ci_templates_django_monthly.yml
new file mode 100644
index 00000000000..6f6f921d20b
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221754_p_ci_templates_django_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_django_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_django
diff --git a/config/metrics/counts_28d/20210901221803_p_ci_templates_maven_monthly.yml b/config/metrics/counts_28d/20210901221803_p_ci_templates_maven_monthly.yml
new file mode 100644
index 00000000000..883a844b26f
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221803_p_ci_templates_maven_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_maven_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_maven
diff --git a/config/metrics/counts_28d/20210901221812_p_ci_templates_flutter_monthly.yml b/config/metrics/counts_28d/20210901221812_p_ci_templates_flutter_monthly.yml
new file mode 100644
index 00000000000..4ecf88abb14
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221812_p_ci_templates_flutter_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_flutter_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_flutter
diff --git a/config/metrics/counts_28d/20210901221822_p_ci_templates_workflows_branch_pipelines_monthly.yml b/config/metrics/counts_28d/20210901221822_p_ci_templates_workflows_branch_pipelines_monthly.yml
new file mode 100644
index 00000000000..7e4a493864c
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221822_p_ci_templates_workflows_branch_pipelines_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_workflows_branch_pipelines_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_workflows_branch_pipelines
diff --git a/config/metrics/counts_28d/20210901221831_p_ci_templates_workflows_mergerequest_pipelines_monthly.yml b/config/metrics/counts_28d/20210901221831_p_ci_templates_workflows_mergerequest_pipelines_monthly.yml
new file mode 100644
index 00000000000..5b813f20ad9
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221831_p_ci_templates_workflows_mergerequest_pipelines_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_workflows_mergerequest_pipelines_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_workflows_mergerequest_pipelines
diff --git a/config/metrics/counts_28d/20210901221840_p_ci_templates_laravel_monthly.yml b/config/metrics/counts_28d/20210901221840_p_ci_templates_laravel_monthly.yml
new file mode 100644
index 00000000000..27ff46f6a35
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221840_p_ci_templates_laravel_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_laravel_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_laravel
diff --git a/config/metrics/counts_28d/20210901221849_p_ci_templates_managed_cluster_applications_monthly.yml b/config/metrics/counts_28d/20210901221849_p_ci_templates_managed_cluster_applications_monthly.yml
new file mode 100644
index 00000000000..92c0ea14727
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221849_p_ci_templates_managed_cluster_applications_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_managed_cluster_applications_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_managed_cluster_applications
diff --git a/config/metrics/counts_28d/20210901221857_p_ci_templates_php_monthly.yml b/config/metrics/counts_28d/20210901221857_p_ci_templates_php_monthly.yml
new file mode 100644
index 00000000000..d32a8f007b9
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221857_p_ci_templates_php_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_php_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_php
diff --git a/config/metrics/counts_28d/20210901221906_p_ci_templates_packer_monthly.yml b/config/metrics/counts_28d/20210901221906_p_ci_templates_packer_monthly.yml
new file mode 100644
index 00000000000..af9f85bf1e4
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221906_p_ci_templates_packer_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_packer_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_packer
diff --git a/config/metrics/counts_28d/20210901221915_p_ci_templates_terraform_monthly.yml b/config/metrics/counts_28d/20210901221915_p_ci_templates_terraform_monthly.yml
new file mode 100644
index 00000000000..743a1ec2013
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221915_p_ci_templates_terraform_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_terraform_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_terraform
diff --git a/config/metrics/counts_28d/20210901221923_p_ci_templates_mono_monthly.yml b/config/metrics/counts_28d/20210901221923_p_ci_templates_mono_monthly.yml
new file mode 100644
index 00000000000..d4e4b37c93c
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221923_p_ci_templates_mono_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_mono_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_mono
diff --git a/config/metrics/counts_28d/20210901221932_p_ci_templates_serverless_monthly.yml b/config/metrics/counts_28d/20210901221932_p_ci_templates_serverless_monthly.yml
new file mode 100644
index 00000000000..9dab50a9e6c
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221932_p_ci_templates_serverless_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_serverless_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_serverless
diff --git a/config/metrics/counts_28d/20210901221941_p_ci_templates_go_monthly.yml b/config/metrics/counts_28d/20210901221941_p_ci_templates_go_monthly.yml
new file mode 100644
index 00000000000..25dce4f9013
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221941_p_ci_templates_go_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_go_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_go
diff --git a/config/metrics/counts_28d/20210901221950_p_ci_templates_scala_monthly.yml b/config/metrics/counts_28d/20210901221950_p_ci_templates_scala_monthly.yml
new file mode 100644
index 00000000000..2faeb424f2d
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221950_p_ci_templates_scala_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_scala_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_scala
diff --git a/config/metrics/counts_28d/20210901221958_p_ci_templates_latex_monthly.yml b/config/metrics/counts_28d/20210901221958_p_ci_templates_latex_monthly.yml
new file mode 100644
index 00000000000..c7d1ea576fc
--- /dev/null
+++ b/config/metrics/counts_28d/20210901221958_p_ci_templates_latex_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_latex_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_latex
diff --git a/config/metrics/counts_28d/20210901222007_p_ci_templates_android_monthly.yml b/config/metrics/counts_28d/20210901222007_p_ci_templates_android_monthly.yml
new file mode 100644
index 00000000000..2523dec8efd
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222007_p_ci_templates_android_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_android_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_android
diff --git a/config/metrics/counts_28d/20210901222016_p_ci_templates_indeni_cloudrail_monthly.yml b/config/metrics/counts_28d/20210901222016_p_ci_templates_indeni_cloudrail_monthly.yml
new file mode 100644
index 00000000000..6841d54790a
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222016_p_ci_templates_indeni_cloudrail_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_indeni_cloudrail_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_indeni_cloudrail
diff --git a/config/metrics/counts_28d/20210901222025_p_ci_templates_deploy_ecs_monthly.yml b/config/metrics/counts_28d/20210901222025_p_ci_templates_deploy_ecs_monthly.yml
new file mode 100644
index 00000000000..9b2ec95d2c5
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222025_p_ci_templates_deploy_ecs_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_deploy_ecs_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_deploy_ecs
diff --git a/config/metrics/counts_28d/20210901222033_p_ci_templates_aws_cf_provision_and_deploy_ec2_monthly.yml b/config/metrics/counts_28d/20210901222033_p_ci_templates_aws_cf_provision_and_deploy_ec2_monthly.yml
new file mode 100644
index 00000000000..d195c569a75
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222033_p_ci_templates_aws_cf_provision_and_deploy_ec2_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_aws_cf_provision_and_deploy_ec2_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_aws_cf_provision_and_deploy_ec2
diff --git a/config/metrics/counts_28d/20210901222042_p_ci_templates_gradle_monthly.yml b/config/metrics/counts_28d/20210901222042_p_ci_templates_gradle_monthly.yml
new file mode 100644
index 00000000000..c66530b37b7
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222042_p_ci_templates_gradle_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_gradle_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_gradle
diff --git a/config/metrics/counts_28d/20210901222051_p_ci_templates_chef_monthly.yml b/config/metrics/counts_28d/20210901222051_p_ci_templates_chef_monthly.yml
new file mode 100644
index 00000000000..f9217f10ac6
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222051_p_ci_templates_chef_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_chef_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_chef
diff --git a/config/metrics/counts_28d/20210901222100_p_ci_templates_jobs_dast_default_branch_deploy_monthly.yml b/config/metrics/counts_28d/20210901222100_p_ci_templates_jobs_dast_default_branch_deploy_monthly.yml
new file mode 100644
index 00000000000..7efd539e992
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222100_p_ci_templates_jobs_dast_default_branch_deploy_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_dast_default_branch_deploy_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_dast_default_branch_deploy
diff --git a/config/metrics/counts_28d/20210901222108_p_ci_templates_jobs_load_performance_testing_monthly.yml b/config/metrics/counts_28d/20210901222108_p_ci_templates_jobs_load_performance_testing_monthly.yml
new file mode 100644
index 00000000000..851855e76b0
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222108_p_ci_templates_jobs_load_performance_testing_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_load_performance_testing_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_load_performance_testing
diff --git a/config/metrics/counts_28d/20210901222117_p_ci_templates_jobs_helm_2to3_monthly.yml b/config/metrics/counts_28d/20210901222117_p_ci_templates_jobs_helm_2to3_monthly.yml
new file mode 100644
index 00000000000..057ce9ab19a
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222117_p_ci_templates_jobs_helm_2to3_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_helm_2to3_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_helm_2to3
diff --git a/config/metrics/counts_28d/20210901222126_p_ci_templates_jobs_sast_monthly.yml b/config/metrics/counts_28d/20210901222126_p_ci_templates_jobs_sast_monthly.yml
new file mode 100644
index 00000000000..81b8196f348
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222126_p_ci_templates_jobs_sast_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_sast_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_sast
diff --git a/config/metrics/counts_28d/20210901222135_p_ci_templates_jobs_secret_detection_monthly.yml b/config/metrics/counts_28d/20210901222135_p_ci_templates_jobs_secret_detection_monthly.yml
new file mode 100644
index 00000000000..09de2ec628a
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222135_p_ci_templates_jobs_secret_detection_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_secret_detection_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_secret_detection
diff --git a/config/metrics/counts_28d/20210901222144_p_ci_templates_jobs_code_intelligence_monthly.yml b/config/metrics/counts_28d/20210901222144_p_ci_templates_jobs_code_intelligence_monthly.yml
new file mode 100644
index 00000000000..98c1d5c752f
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222144_p_ci_templates_jobs_code_intelligence_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_code_intelligence_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_code_intelligence
diff --git a/config/metrics/counts_28d/20210901222153_p_ci_templates_jobs_code_quality_monthly.yml b/config/metrics/counts_28d/20210901222153_p_ci_templates_jobs_code_quality_monthly.yml
new file mode 100644
index 00000000000..2780fb76618
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222153_p_ci_templates_jobs_code_quality_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_code_quality_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_code_quality
diff --git a/config/metrics/counts_28d/20210901222202_p_ci_templates_jobs_deploy_ecs_monthly.yml b/config/metrics/counts_28d/20210901222202_p_ci_templates_jobs_deploy_ecs_monthly.yml
new file mode 100644
index 00000000000..0595e6a6c2f
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222202_p_ci_templates_jobs_deploy_ecs_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_deploy_ecs_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_deploy_ecs
diff --git a/config/metrics/counts_28d/20210901222211_p_ci_templates_jobs_deploy_ec2_monthly.yml b/config/metrics/counts_28d/20210901222211_p_ci_templates_jobs_deploy_ec2_monthly.yml
new file mode 100644
index 00000000000..701d6711c6b
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222211_p_ci_templates_jobs_deploy_ec2_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_deploy_ec2_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_deploy_ec2
diff --git a/config/metrics/counts_28d/20210901222220_p_ci_templates_jobs_deploy_monthly.yml b/config/metrics/counts_28d/20210901222220_p_ci_templates_jobs_deploy_monthly.yml
new file mode 100644
index 00000000000..2c4f32e95dd
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222220_p_ci_templates_jobs_deploy_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_deploy_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_deploy
diff --git a/config/metrics/counts_28d/20210901222229_p_ci_templates_jobs_build_monthly.yml b/config/metrics/counts_28d/20210901222229_p_ci_templates_jobs_build_monthly.yml
new file mode 100644
index 00000000000..2c582ae2d5d
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222229_p_ci_templates_jobs_build_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_build_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_build
diff --git a/config/metrics/counts_28d/20210901222237_p_ci_templates_jobs_browser_performance_testing_monthly.yml b/config/metrics/counts_28d/20210901222237_p_ci_templates_jobs_browser_performance_testing_monthly.yml
new file mode 100644
index 00000000000..f3907820de0
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222237_p_ci_templates_jobs_browser_performance_testing_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_browser_performance_testing_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_browser_performance_testing
diff --git a/config/metrics/counts_28d/20210901222246_p_ci_templates_jobs_test_monthly.yml b/config/metrics/counts_28d/20210901222246_p_ci_templates_jobs_test_monthly.yml
new file mode 100644
index 00000000000..d6b9a891d9c
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222246_p_ci_templates_jobs_test_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_test_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_test
diff --git a/config/metrics/counts_28d/20210901222256_p_ci_templates_jobs_deploy_latest_monthly.yml b/config/metrics/counts_28d/20210901222256_p_ci_templates_jobs_deploy_latest_monthly.yml
new file mode 100644
index 00000000000..6a05970b675
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222256_p_ci_templates_jobs_deploy_latest_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_deploy_latest_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_deploy_latest
diff --git a/config/metrics/counts_28d/20210901222304_p_ci_templates_jobs_browser_performance_testing_latest_monthly.yml b/config/metrics/counts_28d/20210901222304_p_ci_templates_jobs_browser_performance_testing_latest_monthly.yml
new file mode 100644
index 00000000000..a1c568a7ff9
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222304_p_ci_templates_jobs_browser_performance_testing_latest_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_browser_performance_testing_latest_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_browser_performance_testing_latest
diff --git a/config/metrics/counts_28d/20210901222313_p_ci_templates_jobs_cf_provision_monthly.yml b/config/metrics/counts_28d/20210901222313_p_ci_templates_jobs_cf_provision_monthly.yml
new file mode 100644
index 00000000000..02fb579e03b
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222313_p_ci_templates_jobs_cf_provision_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_cf_provision_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_cf_provision
diff --git a/config/metrics/counts_28d/20210901222322_p_ci_templates_jobs_build_latest_monthly.yml b/config/metrics/counts_28d/20210901222322_p_ci_templates_jobs_build_latest_monthly.yml
new file mode 100644
index 00000000000..856cb3d7431
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222322_p_ci_templates_jobs_build_latest_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_build_latest_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_build_latest
diff --git a/config/metrics/counts_28d/20210901222331_p_ci_templates_terraform_latest_monthly.yml b/config/metrics/counts_28d/20210901222331_p_ci_templates_terraform_latest_monthly.yml
new file mode 100644
index 00000000000..920efea27ad
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222331_p_ci_templates_terraform_latest_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_terraform_latest_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_terraform_latest
diff --git a/config/metrics/counts_28d/20210901222341_p_ci_templates_swift_monthly.yml b/config/metrics/counts_28d/20210901222341_p_ci_templates_swift_monthly.yml
new file mode 100644
index 00000000000..d09907dc91b
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222341_p_ci_templates_swift_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_swift_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_swift
diff --git a/config/metrics/counts_28d/20210901222707_p_ci_templates_pages_jekyll_monthly.yml b/config/metrics/counts_28d/20210901222707_p_ci_templates_pages_jekyll_monthly.yml
new file mode 100644
index 00000000000..9271873d5a5
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222707_p_ci_templates_pages_jekyll_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_jekyll_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_jekyll
diff --git a/config/metrics/counts_28d/20210901222742_p_ci_templates_pages_harp_monthly.yml b/config/metrics/counts_28d/20210901222742_p_ci_templates_pages_harp_monthly.yml
new file mode 100644
index 00000000000..1a1666d961e
--- /dev/null
+++ b/config/metrics/counts_28d/20210901222742_p_ci_templates_pages_harp_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_harp_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_harp
diff --git a/config/metrics/counts_28d/20210901223200_p_ci_templates_pages_octopress_monthly.yml b/config/metrics/counts_28d/20210901223200_p_ci_templates_pages_octopress_monthly.yml
new file mode 100644
index 00000000000..e393a28d402
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223200_p_ci_templates_pages_octopress_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_octopress_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_octopress
diff --git a/config/metrics/counts_28d/20210901223210_p_ci_templates_pages_brunch_monthly.yml b/config/metrics/counts_28d/20210901223210_p_ci_templates_pages_brunch_monthly.yml
new file mode 100644
index 00000000000..3e15963a0e4
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223210_p_ci_templates_pages_brunch_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_brunch_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_brunch
diff --git a/config/metrics/counts_28d/20210901223219_p_ci_templates_pages_doxygen_monthly.yml b/config/metrics/counts_28d/20210901223219_p_ci_templates_pages_doxygen_monthly.yml
new file mode 100644
index 00000000000..3a847e76a4d
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223219_p_ci_templates_pages_doxygen_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_doxygen_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_doxygen
diff --git a/config/metrics/counts_28d/20210901223227_p_ci_templates_pages_hyde_monthly.yml b/config/metrics/counts_28d/20210901223227_p_ci_templates_pages_hyde_monthly.yml
new file mode 100644
index 00000000000..18cd9350c18
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223227_p_ci_templates_pages_hyde_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_hyde_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_hyde
diff --git a/config/metrics/counts_28d/20210901223236_p_ci_templates_pages_lektor_monthly.yml b/config/metrics/counts_28d/20210901223236_p_ci_templates_pages_lektor_monthly.yml
new file mode 100644
index 00000000000..8359a8b94a4
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223236_p_ci_templates_pages_lektor_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_lektor_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_lektor
diff --git a/config/metrics/counts_28d/20210901223244_p_ci_templates_pages_jbake_monthly.yml b/config/metrics/counts_28d/20210901223244_p_ci_templates_pages_jbake_monthly.yml
new file mode 100644
index 00000000000..8290dc0e832
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223244_p_ci_templates_pages_jbake_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_jbake_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_jbake
diff --git a/config/metrics/counts_28d/20210901223253_p_ci_templates_pages_hexo_monthly.yml b/config/metrics/counts_28d/20210901223253_p_ci_templates_pages_hexo_monthly.yml
new file mode 100644
index 00000000000..45768b15c10
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223253_p_ci_templates_pages_hexo_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_hexo_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_hexo
diff --git a/config/metrics/counts_28d/20210901223302_p_ci_templates_pages_middleman_monthly.yml b/config/metrics/counts_28d/20210901223302_p_ci_templates_pages_middleman_monthly.yml
new file mode 100644
index 00000000000..c7615209431
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223302_p_ci_templates_pages_middleman_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_middleman_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_middleman
diff --git a/config/metrics/counts_28d/20210901223311_p_ci_templates_pages_hugo_monthly.yml b/config/metrics/counts_28d/20210901223311_p_ci_templates_pages_hugo_monthly.yml
new file mode 100644
index 00000000000..951a61d56ae
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223311_p_ci_templates_pages_hugo_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_hugo_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_hugo
diff --git a/config/metrics/counts_28d/20210901223319_p_ci_templates_pages_pelican_monthly.yml b/config/metrics/counts_28d/20210901223319_p_ci_templates_pages_pelican_monthly.yml
new file mode 100644
index 00000000000..fe749f92436
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223319_p_ci_templates_pages_pelican_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_pelican_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_pelican
diff --git a/config/metrics/counts_28d/20210901223328_p_ci_templates_pages_nanoc_monthly.yml b/config/metrics/counts_28d/20210901223328_p_ci_templates_pages_nanoc_monthly.yml
new file mode 100644
index 00000000000..37b49978853
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223328_p_ci_templates_pages_nanoc_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_nanoc_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_nanoc
diff --git a/config/metrics/counts_28d/20210901223337_p_ci_templates_pages_swaggerui_monthly.yml b/config/metrics/counts_28d/20210901223337_p_ci_templates_pages_swaggerui_monthly.yml
new file mode 100644
index 00000000000..da09183e928
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223337_p_ci_templates_pages_swaggerui_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_swaggerui_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_swaggerui
diff --git a/config/metrics/counts_28d/20210901223346_p_ci_templates_pages_jigsaw_monthly.yml b/config/metrics/counts_28d/20210901223346_p_ci_templates_pages_jigsaw_monthly.yml
new file mode 100644
index 00000000000..5fadb6ce074
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223346_p_ci_templates_pages_jigsaw_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_jigsaw_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_jigsaw
diff --git a/config/metrics/counts_28d/20210901223354_p_ci_templates_pages_metalsmith_monthly.yml b/config/metrics/counts_28d/20210901223354_p_ci_templates_pages_metalsmith_monthly.yml
new file mode 100644
index 00000000000..1f46fd06db7
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223354_p_ci_templates_pages_metalsmith_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_metalsmith_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_metalsmith
diff --git a/config/metrics/counts_28d/20210901223403_p_ci_templates_pages_gatsby_monthly.yml b/config/metrics/counts_28d/20210901223403_p_ci_templates_pages_gatsby_monthly.yml
new file mode 100644
index 00000000000..1132a4b95c2
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223403_p_ci_templates_pages_gatsby_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_gatsby_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_gatsby
diff --git a/config/metrics/counts_28d/20210901223412_p_ci_templates_pages_html_monthly.yml b/config/metrics/counts_28d/20210901223412_p_ci_templates_pages_html_monthly.yml
new file mode 100644
index 00000000000..33ee3737f95
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223412_p_ci_templates_pages_html_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_html_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_html
diff --git a/config/metrics/counts_28d/20210901223421_p_ci_templates_dart_monthly.yml b/config/metrics/counts_28d/20210901223421_p_ci_templates_dart_monthly.yml
new file mode 100644
index 00000000000..eb93f5910ed
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223421_p_ci_templates_dart_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_dart_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_dart
diff --git a/config/metrics/counts_28d/20210901223430_p_ci_templates_docker_monthly.yml b/config/metrics/counts_28d/20210901223430_p_ci_templates_docker_monthly.yml
new file mode 100644
index 00000000000..390d155415e
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223430_p_ci_templates_docker_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_docker_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_docker
diff --git a/config/metrics/counts_28d/20210901223439_p_ci_templates_julia_monthly.yml b/config/metrics/counts_28d/20210901223439_p_ci_templates_julia_monthly.yml
new file mode 100644
index 00000000000..199718e6b1b
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223439_p_ci_templates_julia_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_julia_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_julia
diff --git a/config/metrics/counts_28d/20210901223447_p_ci_templates_npm_monthly.yml b/config/metrics/counts_28d/20210901223447_p_ci_templates_npm_monthly.yml
new file mode 100644
index 00000000000..47aa49e8fb4
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223447_p_ci_templates_npm_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_npm_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_npm
diff --git a/config/metrics/counts_28d/20210901223456_p_ci_templates_dotnet_core_monthly.yml b/config/metrics/counts_28d/20210901223456_p_ci_templates_dotnet_core_monthly.yml
new file mode 100644
index 00000000000..5aadbcdd402
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223456_p_ci_templates_dotnet_core_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_dotnet_core_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_dotnet_core
diff --git a/config/metrics/counts_28d/20210901223505_p_ci_templates_5_minute_production_app_monthly.yml b/config/metrics/counts_28d/20210901223505_p_ci_templates_5_minute_production_app_monthly.yml
new file mode 100644
index 00000000000..43851ae9fb3
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223505_p_ci_templates_5_minute_production_app_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_5_minute_production_app_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_5_minute_production_app
diff --git a/config/metrics/counts_28d/20210901223514_p_ci_templates_ruby_monthly.yml b/config/metrics/counts_28d/20210901223514_p_ci_templates_ruby_monthly.yml
new file mode 100644
index 00000000000..ce9d5065fc1
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223514_p_ci_templates_ruby_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_ruby_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_ruby
diff --git a/config/metrics/counts_28d/20210901223523_p_ci_templates_implicit_jobs_dast_default_branch_deploy_monthly.yml b/config/metrics/counts_28d/20210901223523_p_ci_templates_implicit_jobs_dast_default_branch_deploy_monthly.yml
new file mode 100644
index 00000000000..b52850bdca9
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223523_p_ci_templates_implicit_jobs_dast_default_branch_deploy_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_dast_default_branch_deploy_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_dast_default_branch_deploy
diff --git a/config/metrics/counts_28d/20210901223532_p_ci_templates_implicit_jobs_load_performance_testing_monthly.yml b/config/metrics/counts_28d/20210901223532_p_ci_templates_implicit_jobs_load_performance_testing_monthly.yml
new file mode 100644
index 00000000000..c5ce964bfaa
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223532_p_ci_templates_implicit_jobs_load_performance_testing_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_load_performance_testing_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_load_performance_testing
diff --git a/config/metrics/counts_28d/20210901223541_p_ci_templates_implicit_jobs_helm_2to3_monthly.yml b/config/metrics/counts_28d/20210901223541_p_ci_templates_implicit_jobs_helm_2to3_monthly.yml
new file mode 100644
index 00000000000..11c66d9dd11
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223541_p_ci_templates_implicit_jobs_helm_2to3_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_helm_2to3_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_helm_2to3
diff --git a/config/metrics/counts_28d/20210901223550_p_ci_templates_implicit_jobs_sast_monthly.yml b/config/metrics/counts_28d/20210901223550_p_ci_templates_implicit_jobs_sast_monthly.yml
new file mode 100644
index 00000000000..e30f559b879
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223550_p_ci_templates_implicit_jobs_sast_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_sast_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_sast
diff --git a/config/metrics/counts_28d/20210901223559_p_ci_templates_implicit_jobs_secret_detection_monthly.yml b/config/metrics/counts_28d/20210901223559_p_ci_templates_implicit_jobs_secret_detection_monthly.yml
new file mode 100644
index 00000000000..7c56b16701b
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223559_p_ci_templates_implicit_jobs_secret_detection_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_secret_detection_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_secret_detection
diff --git a/config/metrics/counts_28d/20210901223608_p_ci_templates_implicit_jobs_code_intelligence_monthly.yml b/config/metrics/counts_28d/20210901223608_p_ci_templates_implicit_jobs_code_intelligence_monthly.yml
new file mode 100644
index 00000000000..e52602a96c8
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223608_p_ci_templates_implicit_jobs_code_intelligence_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_code_intelligence_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_code_intelligence
diff --git a/config/metrics/counts_28d/20210901223617_p_ci_templates_implicit_jobs_code_quality_monthly.yml b/config/metrics/counts_28d/20210901223617_p_ci_templates_implicit_jobs_code_quality_monthly.yml
new file mode 100644
index 00000000000..05bcdade966
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223617_p_ci_templates_implicit_jobs_code_quality_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_code_quality_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_code_quality
diff --git a/config/metrics/counts_28d/20210901223626_p_ci_templates_implicit_jobs_deploy_ecs_monthly.yml b/config/metrics/counts_28d/20210901223626_p_ci_templates_implicit_jobs_deploy_ecs_monthly.yml
new file mode 100644
index 00000000000..4bc50406910
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223626_p_ci_templates_implicit_jobs_deploy_ecs_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_deploy_ecs_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_deploy_ecs
diff --git a/config/metrics/counts_28d/20210901223635_p_ci_templates_implicit_jobs_deploy_ec2_monthly.yml b/config/metrics/counts_28d/20210901223635_p_ci_templates_implicit_jobs_deploy_ec2_monthly.yml
new file mode 100644
index 00000000000..6c71d424338
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223635_p_ci_templates_implicit_jobs_deploy_ec2_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_deploy_ec2_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_deploy_ec2
diff --git a/config/metrics/counts_28d/20210901223644_p_ci_templates_implicit_jobs_browser_performance_testing_monthly.yml b/config/metrics/counts_28d/20210901223644_p_ci_templates_implicit_jobs_browser_performance_testing_monthly.yml
new file mode 100644
index 00000000000..9c8f24f35b6
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223644_p_ci_templates_implicit_jobs_browser_performance_testing_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_browser_performance_testing_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_browser_performance_testing
diff --git a/config/metrics/counts_28d/20210901223653_p_ci_templates_implicit_jobs_test_monthly.yml b/config/metrics/counts_28d/20210901223653_p_ci_templates_implicit_jobs_test_monthly.yml
new file mode 100644
index 00000000000..4424cf72a53
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223653_p_ci_templates_implicit_jobs_test_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_test_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_test
diff --git a/config/metrics/counts_28d/20210901223702_p_ci_templates_implicit_jobs_browser_performance_testing_latest_monthly.yml b/config/metrics/counts_28d/20210901223702_p_ci_templates_implicit_jobs_browser_performance_testing_latest_monthly.yml
new file mode 100644
index 00000000000..5bd79adf6e5
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223702_p_ci_templates_implicit_jobs_browser_performance_testing_latest_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_browser_performance_testing_latest_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_browser_performance_testing_latest
diff --git a/config/metrics/counts_28d/20210901223711_p_ci_templates_implicit_jobs_cf_provision_monthly.yml b/config/metrics/counts_28d/20210901223711_p_ci_templates_implicit_jobs_cf_provision_monthly.yml
new file mode 100644
index 00000000000..362aed75e00
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223711_p_ci_templates_implicit_jobs_cf_provision_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_cf_provision_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_cf_provision
diff --git a/config/metrics/counts_28d/20210901223721_p_ci_templates_implicit_jobs_build_latest_monthly.yml b/config/metrics/counts_28d/20210901223721_p_ci_templates_implicit_jobs_build_latest_monthly.yml
new file mode 100644
index 00000000000..d7c78554423
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223721_p_ci_templates_implicit_jobs_build_latest_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_build_latest_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_build_latest
diff --git a/config/metrics/counts_28d/20210901223730_p_ci_templates_implicit_security_dast_runner_validation_monthly.yml b/config/metrics/counts_28d/20210901223730_p_ci_templates_implicit_security_dast_runner_validation_monthly.yml
new file mode 100644
index 00000000000..a688785bc0f
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223730_p_ci_templates_implicit_security_dast_runner_validation_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_dast_runner_validation_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_dast_runner_validation
diff --git a/config/metrics/counts_28d/20210901223739_p_ci_templates_implicit_security_dast_on_demand_scan_monthly.yml b/config/metrics/counts_28d/20210901223739_p_ci_templates_implicit_security_dast_on_demand_scan_monthly.yml
new file mode 100644
index 00000000000..97bd575f2f3
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223739_p_ci_templates_implicit_security_dast_on_demand_scan_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_dast_on_demand_scan_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_dast_on_demand_scan
diff --git a/config/metrics/counts_28d/20210901223748_p_ci_templates_implicit_security_license_scanning_monthly.yml b/config/metrics/counts_28d/20210901223748_p_ci_templates_implicit_security_license_scanning_monthly.yml
new file mode 100644
index 00000000000..0a22cf9e860
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223748_p_ci_templates_implicit_security_license_scanning_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_license_scanning_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_license_scanning
diff --git a/config/metrics/counts_28d/20210901223758_p_ci_templates_implicit_security_coverage_fuzzing_monthly.yml b/config/metrics/counts_28d/20210901223758_p_ci_templates_implicit_security_coverage_fuzzing_monthly.yml
new file mode 100644
index 00000000000..8735c299082
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223758_p_ci_templates_implicit_security_coverage_fuzzing_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_coverage_fuzzing_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_coverage_fuzzing
diff --git a/config/metrics/counts_28d/20210901223806_p_ci_templates_implicit_security_api_fuzzing_latest_monthly.yml b/config/metrics/counts_28d/20210901223806_p_ci_templates_implicit_security_api_fuzzing_latest_monthly.yml
new file mode 100644
index 00000000000..70f42f3861e
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223806_p_ci_templates_implicit_security_api_fuzzing_latest_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_api_fuzzing_latest_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_api_fuzzing_latest
diff --git a/config/metrics/counts_28d/20210901223815_p_ci_templates_implicit_security_secure_binaries_monthly.yml b/config/metrics/counts_28d/20210901223815_p_ci_templates_implicit_security_secure_binaries_monthly.yml
new file mode 100644
index 00000000000..35235a85b19
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223815_p_ci_templates_implicit_security_secure_binaries_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_secure_binaries_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_secure_binaries
diff --git a/config/metrics/counts_28d/20210901223824_p_ci_templates_implicit_security_dast_api_monthly.yml b/config/metrics/counts_28d/20210901223824_p_ci_templates_implicit_security_dast_api_monthly.yml
new file mode 100644
index 00000000000..087a55fd275
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223824_p_ci_templates_implicit_security_dast_api_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_dast_api_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_dast_api
diff --git a/config/metrics/counts_28d/20210901223832_p_ci_templates_implicit_security_container_scanning_monthly.yml b/config/metrics/counts_28d/20210901223832_p_ci_templates_implicit_security_container_scanning_monthly.yml
new file mode 100644
index 00000000000..c1281685678
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223832_p_ci_templates_implicit_security_container_scanning_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_container_scanning_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_container_scanning
diff --git a/config/metrics/counts_28d/20210901223841_p_ci_templates_implicit_security_dast_latest_monthly.yml b/config/metrics/counts_28d/20210901223841_p_ci_templates_implicit_security_dast_latest_monthly.yml
new file mode 100644
index 00000000000..0adb938298c
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223841_p_ci_templates_implicit_security_dast_latest_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_dast_latest_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_dast_latest
diff --git a/config/metrics/counts_28d/20210901223850_p_ci_templates_implicit_security_dependency_scanning_monthly.yml b/config/metrics/counts_28d/20210901223850_p_ci_templates_implicit_security_dependency_scanning_monthly.yml
new file mode 100644
index 00000000000..6e9ccb48983
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223850_p_ci_templates_implicit_security_dependency_scanning_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_dependency_scanning_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_dependency_scanning
diff --git a/config/metrics/counts_28d/20210901223858_p_ci_templates_implicit_security_api_fuzzing_monthly.yml b/config/metrics/counts_28d/20210901223858_p_ci_templates_implicit_security_api_fuzzing_monthly.yml
new file mode 100644
index 00000000000..85868e0c79c
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223858_p_ci_templates_implicit_security_api_fuzzing_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_api_fuzzing_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_api_fuzzing
diff --git a/config/metrics/counts_28d/20210901223907_p_ci_templates_implicit_security_dast_monthly.yml b/config/metrics/counts_28d/20210901223907_p_ci_templates_implicit_security_dast_monthly.yml
new file mode 100644
index 00000000000..7b7ce070486
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223907_p_ci_templates_implicit_security_dast_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_dast_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_dast
diff --git a/config/metrics/counts_28d/20210901223916_p_ci_templates_implicit_security_cluster_image_scanning_monthly.yml b/config/metrics/counts_28d/20210901223916_p_ci_templates_implicit_security_cluster_image_scanning_monthly.yml
new file mode 100644
index 00000000000..ddf785a71bd
--- /dev/null
+++ b/config/metrics/counts_28d/20210901223916_p_ci_templates_implicit_security_cluster_image_scanning_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_cluster_image_scanning_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_cluster_image_scanning
diff --git a/config/metrics/counts_28d/20210902000813_p_ci_templates_implicit_auto_devops_deploy_latest_monthly.yml b/config/metrics/counts_28d/20210902000813_p_ci_templates_implicit_auto_devops_deploy_latest_monthly.yml
new file mode 100644
index 00000000000..3b667e49f0d
--- /dev/null
+++ b/config/metrics/counts_28d/20210902000813_p_ci_templates_implicit_auto_devops_deploy_latest_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_auto_devops_deploy_latest_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_auto_devops_deploy_latest
diff --git a/config/metrics/counts_28d/20210902191057_i_quickactions_unapprove_monthly.yml b/config/metrics/counts_28d/20210902191057_i_quickactions_unapprove_monthly.yml
new file mode 100644
index 00000000000..ccefa1f5dd3
--- /dev/null
+++ b/config/metrics/counts_28d/20210902191057_i_quickactions_unapprove_monthly.yml
@@ -0,0 +1,28 @@
+---
+data_category: optional
+key_path: redis_hll_counters.quickactions.i_quickactions_unapprove_monthly
+description: Count of MAU using the `/unapprove` quick action
+product_section: dev
+product_stage: create
+product_group: group::code review
+product_category: code_review
+value_type: number
+status: active
+milestone: "14.3"
+time_frame: 28d
+data_source: redis_hll
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - i_quickactions_unapprove
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - i_quickactions_unapprove
+distribution:
+ - ce
+ - ee
+tier:
+ - free
+ - premium
+ - ultimate
diff --git a/config/metrics/counts_28d/20210908093509_p_ci_templates_android_latest_monthly.yml b/config/metrics/counts_28d/20210908093509_p_ci_templates_android_latest_monthly.yml
new file mode 100644
index 00000000000..f44d7a6c045
--- /dev/null
+++ b/config/metrics/counts_28d/20210908093509_p_ci_templates_android_latest_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_android_latest_monthly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: "14.3"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_android_latest
diff --git a/config/metrics/counts_28d/20210908150458_i_code_review_user_resolve_thread_in_issue_monthly.yml b/config/metrics/counts_28d/20210908150458_i_code_review_user_resolve_thread_in_issue_monthly.yml
new file mode 100644
index 00000000000..072305ed6f4
--- /dev/null
+++ b/config/metrics/counts_28d/20210908150458_i_code_review_user_resolve_thread_in_issue_monthly.yml
@@ -0,0 +1,27 @@
+---
+key_path: redis_hll_counters.code_review.i_code_review_user_resolve_thread_in_issue_monthly
+name: resolve_thread_in_issue
+description: The number of users who resolve a thread in a new issue through the MR page monthly
+product_section: dev
+product_stage: create
+product_group: group::code review
+product_category: code_review
+value_type: number
+status: active
+milestone: "14.3"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69879
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - i_code_review_user_resolve_thread_in_issue
+performance_indicator_type: []
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_28d/20210910132229_user_auth_by_provider.yml b/config/metrics/counts_28d/20210910132229_user_auth_by_provider.yml
new file mode 100644
index 00000000000..9a2d93e597e
--- /dev/null
+++ b/config/metrics/counts_28d/20210910132229_user_auth_by_provider.yml
@@ -0,0 +1,24 @@
+---
+key_path: usage_activity_by_stage_monthly.manage.user_auth_by_provider
+name: count_distinct_users_using_two_factor_authentication
+description: Number of unique user logins using two factor authentication for available providers
+product_section: dev
+product_stage: manage
+product_group: group::access
+product_category: authentication_and_authorization
+value_type: object
+status: active
+milestone: "14.3"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70061
+time_frame: 28d
+data_source: database
+data_category: optional
+performance_indicator_type: []
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+value_json_schema: "config/metrics/objects_schemas/user_auth_by_provider.json"
diff --git a/config/metrics/counts_28d/20210916080405_promoted_issues.yml b/config/metrics/counts_28d/20210916080405_promoted_issues.yml
new file mode 100644
index 00000000000..106c3a61289
--- /dev/null
+++ b/config/metrics/counts_28d/20210916080405_promoted_issues.yml
@@ -0,0 +1,23 @@
+---
+key_path: counts_monthly.promoted_issues
+name: count_promoted_issues
+description: Count of issues promoted to epics
+product_section: growth
+product_stage: growth
+product_group: group::product intelligence
+product_category: collection
+value_type: number
+status: active
+milestone: "14.3"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70485
+time_frame: 28d
+data_source: database
+data_category: optional
+performance_indicator_type: []
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_7d/20210201124931_g_project_management_issue_title_changed_weekly.yml b/config/metrics/counts_7d/20210201124931_g_project_management_issue_title_changed_weekly.yml
index 48e72f62caf..2a1a174f5a5 100644
--- a/config/metrics/counts_7d/20210201124931_g_project_management_issue_title_changed_weekly.yml
+++ b/config/metrics/counts_7d/20210201124931_g_project_management_issue_title_changed_weekly.yml
@@ -6,7 +6,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
milestone: "13.6"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/issues/229918
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210216175010_i_analytics_instance_statistics_weekly.yml b/config/metrics/counts_7d/20210216175010_i_analytics_instance_statistics_weekly.yml
index fbce567f299..c24d51412f8 100644
--- a/config/metrics/counts_7d/20210216175010_i_analytics_instance_statistics_weekly.yml
+++ b/config/metrics/counts_7d/20210216175010_i_analytics_instance_statistics_weekly.yml
@@ -5,17 +5,21 @@ description: Unique visitors to /admin/usage_trends by week
product_section: dev
product_stage: manage
product_group: group::optimize
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_analytics_instance_statistics
+ - i_analytics_instance_statistics
distribution:
- ee
-tier: []
-skip_validation: true
+- ee
+tier:
+- free
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216175014_analytics_total_unique_counts_weekly.yml b/config/metrics/counts_7d/20210216175014_analytics_total_unique_counts_weekly.yml
index d35ea4076d7..3a9efa3f962 100644
--- a/config/metrics/counts_7d/20210216175014_analytics_total_unique_counts_weekly.yml
+++ b/config/metrics/counts_7d/20210216175014_analytics_total_unique_counts_weekly.yml
@@ -5,33 +5,37 @@ description: The number of unique users who visited any analytics feature by wee
product_section: dev
product_stage: manage
product_group: group::optimize
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - users_viewing_analytics_group_devops_adoption
- - i_analytics_dev_ops_adoption
- - i_analytics_dev_ops_score
- - p_analytics_merge_request
- - i_analytics_instance_statistics
- - g_analytics_contribution
- - g_analytics_insights
- - g_analytics_issues
- - g_analytics_productivity
- - g_analytics_valuestream
- - p_analytics_pipelines
- - p_analytics_code_reviews
- - p_analytics_valuestream
- - p_analytics_insights
- - p_analytics_issues
- - p_analytics_repo
- - i_analytics_cohorts
+ - users_viewing_analytics_group_devops_adoption
+ - i_analytics_dev_ops_adoption
+ - i_analytics_dev_ops_score
+ - p_analytics_merge_request
+ - i_analytics_instance_statistics
+ - g_analytics_contribution
+ - g_analytics_insights
+ - g_analytics_issues
+ - g_analytics_productivity
+ - g_analytics_valuestream
+ - p_analytics_pipelines
+ - p_analytics_code_reviews
+ - p_analytics_valuestream
+ - p_analytics_insights
+ - p_analytics_issues
+ - p_analytics_repo
+ - i_analytics_cohorts
distribution:
+- ce
- ee
-tier: []
-skip_validation: true
+tier:
+- free
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216175111_merge_request_action_weekly.yml b/config/metrics/counts_7d/20210216175111_merge_request_action_weekly.yml
index 004b24b0d0e..da938f35fa9 100644
--- a/config/metrics/counts_7d/20210216175111_merge_request_action_weekly.yml
+++ b/config/metrics/counts_7d/20210216175111_merge_request_action_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216175114_i_source_code_code_intelligence_weekly.yml b/config/metrics/counts_7d/20210216175114_i_source_code_code_intelligence_weekly.yml
index e712a02c27d..6814b32f2bf 100644
--- a/config/metrics/counts_7d/20210216175114_i_source_code_code_intelligence_weekly.yml
+++ b/config/metrics/counts_7d/20210216175114_i_source_code_code_intelligence_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216175118_i_code_review_mr_diffs_weekly.yml b/config/metrics/counts_7d/20210216175118_i_code_review_mr_diffs_weekly.yml
index 7c27eff7b75..57987f98ab6 100644
--- a/config/metrics/counts_7d/20210216175118_i_code_review_mr_diffs_weekly.yml
+++ b/config/metrics/counts_7d/20210216175118_i_code_review_mr_diffs_weekly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_mr_diffs
+ - i_code_review_mr_diffs
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216175122_i_code_review_user_single_file_diffs_weekly.yml b/config/metrics/counts_7d/20210216175122_i_code_review_user_single_file_diffs_weekly.yml
index 8430bb9c1ad..63a8442c4e6 100644
--- a/config/metrics/counts_7d/20210216175122_i_code_review_user_single_file_diffs_weekly.yml
+++ b/config/metrics/counts_7d/20210216175122_i_code_review_user_single_file_diffs_weekly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_single_file_diffs
+ - i_code_review_user_single_file_diffs
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216175126_i_code_review_mr_single_file_diffs_weekly.yml b/config/metrics/counts_7d/20210216175126_i_code_review_mr_single_file_diffs_weekly.yml
index c6d312cac70..2883082131e 100644
--- a/config/metrics/counts_7d/20210216175126_i_code_review_mr_single_file_diffs_weekly.yml
+++ b/config/metrics/counts_7d/20210216175126_i_code_review_mr_single_file_diffs_weekly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_mr_single_file_diffs
+ - i_code_review_mr_single_file_diffs
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216175130_i_code_review_user_create_mr_weekly.yml b/config/metrics/counts_7d/20210216175130_i_code_review_user_create_mr_weekly.yml
index 92a7035b685..b7ceec20354 100644
--- a/config/metrics/counts_7d/20210216175130_i_code_review_user_create_mr_weekly.yml
+++ b/config/metrics/counts_7d/20210216175130_i_code_review_user_create_mr_weekly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_create_mr
+ - i_code_review_user_create_mr
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216175134_i_code_review_user_close_mr_weekly.yml b/config/metrics/counts_7d/20210216175134_i_code_review_user_close_mr_weekly.yml
index c336a950746..dd0cef04ca9 100644
--- a/config/metrics/counts_7d/20210216175134_i_code_review_user_close_mr_weekly.yml
+++ b/config/metrics/counts_7d/20210216175134_i_code_review_user_close_mr_weekly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_close_mr
+ - i_code_review_user_close_mr
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216175138_i_code_review_user_reopen_mr_weekly.yml b/config/metrics/counts_7d/20210216175138_i_code_review_user_reopen_mr_weekly.yml
index c4e59d2dcdb..3c79f72dd19 100644
--- a/config/metrics/counts_7d/20210216175138_i_code_review_user_reopen_mr_weekly.yml
+++ b/config/metrics/counts_7d/20210216175138_i_code_review_user_reopen_mr_weekly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_reopen_mr
+ - i_code_review_user_reopen_mr
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216175142_i_code_review_user_merge_mr_weekly.yml b/config/metrics/counts_7d/20210216175142_i_code_review_user_merge_mr_weekly.yml
index 635681cc47c..ec5e7fbc032 100644
--- a/config/metrics/counts_7d/20210216175142_i_code_review_user_merge_mr_weekly.yml
+++ b/config/metrics/counts_7d/20210216175142_i_code_review_user_merge_mr_weekly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_merge_mr
+ - i_code_review_user_merge_mr
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216175146_i_code_review_user_create_mr_comment_weekly.yml b/config/metrics/counts_7d/20210216175146_i_code_review_user_create_mr_comment_weekly.yml
index 064367405c8..d03ac5f1ef1 100644
--- a/config/metrics/counts_7d/20210216175146_i_code_review_user_create_mr_comment_weekly.yml
+++ b/config/metrics/counts_7d/20210216175146_i_code_review_user_create_mr_comment_weekly.yml
@@ -7,17 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_create_mr_comment
-instrumentation_class: RedisHLLMetric
-options:
- events:
- - i_code_review_user_create_mr
+ - i_code_review_user_create_mr_comment
distribution:
- ce
- ee
@@ -26,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216175150_i_code_review_user_edit_mr_comment_weekly.yml b/config/metrics/counts_7d/20210216175150_i_code_review_user_edit_mr_comment_weekly.yml
index 783c456c379..01b6ac1ee34 100644
--- a/config/metrics/counts_7d/20210216175150_i_code_review_user_edit_mr_comment_weekly.yml
+++ b/config/metrics/counts_7d/20210216175150_i_code_review_user_edit_mr_comment_weekly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_edit_mr_comment
+ - i_code_review_user_edit_mr_comment
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216175154_i_code_review_user_remove_mr_comment_weekly.yml b/config/metrics/counts_7d/20210216175154_i_code_review_user_remove_mr_comment_weekly.yml
index 8e0dc5b31a6..082cf4b5f0f 100644
--- a/config/metrics/counts_7d/20210216175154_i_code_review_user_remove_mr_comment_weekly.yml
+++ b/config/metrics/counts_7d/20210216175154_i_code_review_user_remove_mr_comment_weekly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_remove_mr_comment
+ - i_code_review_user_remove_mr_comment
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216175158_i_code_review_user_add_suggestion_weekly.yml b/config/metrics/counts_7d/20210216175158_i_code_review_user_add_suggestion_weekly.yml
index 57fd33f2e22..a7faca5bc28 100644
--- a/config/metrics/counts_7d/20210216175158_i_code_review_user_add_suggestion_weekly.yml
+++ b/config/metrics/counts_7d/20210216175158_i_code_review_user_add_suggestion_weekly.yml
@@ -7,17 +7,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_add_suggestion
+ - i_code_review_user_add_suggestion
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216175201_i_code_review_user_apply_suggestion_weekly.yml b/config/metrics/counts_7d/20210216175201_i_code_review_user_apply_suggestion_weekly.yml
index 4e34212e9cb..d313eccb956 100644
--- a/config/metrics/counts_7d/20210216175201_i_code_review_user_apply_suggestion_weekly.yml
+++ b/config/metrics/counts_7d/20210216175201_i_code_review_user_apply_suggestion_weekly.yml
@@ -7,17 +7,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_apply_suggestion
+ - i_code_review_user_apply_suggestion
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180328_g_edit_by_web_ide_weekly.yml b/config/metrics/counts_7d/20210216180328_g_edit_by_web_ide_weekly.yml
index 90840faf43d..74d8cf777af 100644
--- a/config/metrics/counts_7d/20210216180328_g_edit_by_web_ide_weekly.yml
+++ b/config/metrics/counts_7d/20210216180328_g_edit_by_web_ide_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: web_ide
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180332_g_edit_by_sfe_weekly.yml b/config/metrics/counts_7d/20210216180332_g_edit_by_sfe_weekly.yml
index 0e7720ee8b3..8624ceac7d3 100644
--- a/config/metrics/counts_7d/20210216180332_g_edit_by_sfe_weekly.yml
+++ b/config/metrics/counts_7d/20210216180332_g_edit_by_sfe_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: web_ide
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180336_g_edit_by_snippet_ide_weekly.yml b/config/metrics/counts_7d/20210216180336_g_edit_by_snippet_ide_weekly.yml
index 3bd141fbfcc..299237ec022 100644
--- a/config/metrics/counts_7d/20210216180336_g_edit_by_snippet_ide_weekly.yml
+++ b/config/metrics/counts_7d/20210216180336_g_edit_by_snippet_ide_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: snippets
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180339_ide_edit_total_unique_counts_weekly.yml b/config/metrics/counts_7d/20210216180339_ide_edit_total_unique_counts_weekly.yml
index 6b5b8d8914e..8e913a78a1f 100644
--- a/config/metrics/counts_7d/20210216180339_ide_edit_total_unique_counts_weekly.yml
+++ b/config/metrics/counts_7d/20210216180339_ide_edit_total_unique_counts_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: web_ide
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -25,3 +25,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180422_i_search_total_weekly.yml b/config/metrics/counts_7d/20210216180422_i_search_total_weekly.yml
index e7146cf8158..2c02c296a85 100644
--- a/config/metrics/counts_7d/20210216180422_i_search_total_weekly.yml
+++ b/config/metrics/counts_7d/20210216180422_i_search_total_weekly.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::global search
product_category: global_search
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180429_search_total_unique_counts_weekly.yml b/config/metrics/counts_7d/20210216180429_search_total_unique_counts_weekly.yml
index c27b8be56ee..55170e41c2c 100644
--- a/config/metrics/counts_7d/20210216180429_search_total_unique_counts_weekly.yml
+++ b/config/metrics/counts_7d/20210216180429_search_total_unique_counts_weekly.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::global search
product_category: global_search
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -24,3 +24,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180513_incident_management_alerts_total_unique_counts.yml b/config/metrics/counts_7d/20210216180513_incident_management_alerts_total_unique_counts.yml
index 628956629fc..8501aca963d 100644
--- a/config/metrics/counts_7d/20210216180513_incident_management_alerts_total_unique_counts.yml
+++ b/config/metrics/counts_7d/20210216180513_incident_management_alerts_total_unique_counts.yml
@@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180515_incident_management_incidents_total_unique_counts.yml b/config/metrics/counts_7d/20210216180515_incident_management_incidents_total_unique_counts.yml
index bfdc0410d2b..8e78722a377 100644
--- a/config/metrics/counts_7d/20210216180515_incident_management_incidents_total_unique_counts.yml
+++ b/config/metrics/counts_7d/20210216180515_incident_management_incidents_total_unique_counts.yml
@@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180528_incident_management_alert_status_changed_weekly.yml b/config/metrics/counts_7d/20210216180528_incident_management_alert_status_changed_weekly.yml
index 903a1da1f1f..cffbc350343 100644
--- a/config/metrics/counts_7d/20210216180528_incident_management_alert_status_changed_weekly.yml
+++ b/config/metrics/counts_7d/20210216180528_incident_management_alert_status_changed_weekly.yml
@@ -5,9 +5,9 @@ description: Count of unique users changing alert's status per week
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180532_incident_management_alert_assigned_weekly.yml b/config/metrics/counts_7d/20210216180532_incident_management_alert_assigned_weekly.yml
index 98546cb7a84..bfc8fd42716 100644
--- a/config/metrics/counts_7d/20210216180532_incident_management_alert_assigned_weekly.yml
+++ b/config/metrics/counts_7d/20210216180532_incident_management_alert_assigned_weekly.yml
@@ -5,9 +5,9 @@ description: Count of unique users assigning an alert per week
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180535_incident_management_alert_todo_weekly.yml b/config/metrics/counts_7d/20210216180535_incident_management_alert_todo_weekly.yml
index 25c54267179..174c58230ca 100644
--- a/config/metrics/counts_7d/20210216180535_incident_management_alert_todo_weekly.yml
+++ b/config/metrics/counts_7d/20210216180535_incident_management_alert_todo_weekly.yml
@@ -5,9 +5,9 @@ description: Count of unique users adding alerts to the TODO list per week
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180539_incident_management_incident_created_weekly.yml b/config/metrics/counts_7d/20210216180539_incident_management_incident_created_weekly.yml
index 79abe8e9459..953c7962708 100644
--- a/config/metrics/counts_7d/20210216180539_incident_management_incident_created_weekly.yml
+++ b/config/metrics/counts_7d/20210216180539_incident_management_incident_created_weekly.yml
@@ -5,9 +5,9 @@ description: Count of unique users creating incidents per week
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180543_incident_management_incident_reopened_weekly.yml b/config/metrics/counts_7d/20210216180543_incident_management_incident_reopened_weekly.yml
index 718faa29b4a..e7cac727367 100644
--- a/config/metrics/counts_7d/20210216180543_incident_management_incident_reopened_weekly.yml
+++ b/config/metrics/counts_7d/20210216180543_incident_management_incident_reopened_weekly.yml
@@ -5,9 +5,9 @@ description: Count of unique users reopening incidents per week
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180546_incident_management_incident_closed_weekly.yml b/config/metrics/counts_7d/20210216180546_incident_management_incident_closed_weekly.yml
index e04baa14a93..65780586fcc 100644
--- a/config/metrics/counts_7d/20210216180546_incident_management_incident_closed_weekly.yml
+++ b/config/metrics/counts_7d/20210216180546_incident_management_incident_closed_weekly.yml
@@ -5,9 +5,9 @@ description: Count of users closing incidents per week
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180550_incident_management_incident_assigned_weekly.yml b/config/metrics/counts_7d/20210216180550_incident_management_incident_assigned_weekly.yml
index 47919052937..f7dc966bb72 100644
--- a/config/metrics/counts_7d/20210216180550_incident_management_incident_assigned_weekly.yml
+++ b/config/metrics/counts_7d/20210216180550_incident_management_incident_assigned_weekly.yml
@@ -5,9 +5,9 @@ description: Count of unique users assiging incidents per week
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180554_incident_management_incident_todo_weekly.yml b/config/metrics/counts_7d/20210216180554_incident_management_incident_todo_weekly.yml
index 6bb7e389b86..d21ba880611 100644
--- a/config/metrics/counts_7d/20210216180554_incident_management_incident_todo_weekly.yml
+++ b/config/metrics/counts_7d/20210216180554_incident_management_incident_todo_weekly.yml
@@ -5,9 +5,9 @@ description: Count of unique users adding incidents to the TODO list per week
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180558_incident_management_incident_comment_weekly.yml b/config/metrics/counts_7d/20210216180558_incident_management_incident_comment_weekly.yml
index cfc02a494fd..f1f1ae465e6 100644
--- a/config/metrics/counts_7d/20210216180558_incident_management_incident_comment_weekly.yml
+++ b/config/metrics/counts_7d/20210216180558_incident_management_incident_comment_weekly.yml
@@ -5,9 +5,9 @@ description: Count of unique users adding comments on incidents per week
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180601_incident_management_incident_zoom_meeting_weekly.yml b/config/metrics/counts_7d/20210216180601_incident_management_incident_zoom_meeting_weekly.yml
index 9e3f16ea2db..45b0709bf25 100644
--- a/config/metrics/counts_7d/20210216180601_incident_management_incident_zoom_meeting_weekly.yml
+++ b/config/metrics/counts_7d/20210216180601_incident_management_incident_zoom_meeting_weekly.yml
@@ -5,9 +5,9 @@ description: Count of unique users creating Zoom meetings about incidents per we
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180609_incident_management_incident_relate_weekly.yml b/config/metrics/counts_7d/20210216180609_incident_management_incident_relate_weekly.yml
index 8b4e93fe938..d0ef9bd6e52 100644
--- a/config/metrics/counts_7d/20210216180609_incident_management_incident_relate_weekly.yml
+++ b/config/metrics/counts_7d/20210216180609_incident_management_incident_relate_weekly.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: redis_hll_counters.incident_management.incident_management_incident_relate_weekly
-description: Count of unique users adding issues per that are related to an incident week
+description: Count of unique users adding issues per that are related to an incident
+ week
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +23,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180612_incident_management_incident_unrelate_weekly.yml b/config/metrics/counts_7d/20210216180612_incident_management_incident_unrelate_weekly.yml
index dab3f0a5611..6755ffd46a6 100644
--- a/config/metrics/counts_7d/20210216180612_incident_management_incident_unrelate_weekly.yml
+++ b/config/metrics/counts_7d/20210216180612_incident_management_incident_unrelate_weekly.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: redis_hll_counters.incident_management.incident_management_incident_unrelate_weekly
-description: Count of unique users removing issue that are related to an incident per week
+description: Count of unique users removing issue that are related to an incident
+ per week
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +23,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180616_incident_management_incident_change_confidential_weekly.yml b/config/metrics/counts_7d/20210216180616_incident_management_incident_change_confidential_weekly.yml
index 5ef90c0269a..2c6efe436cb 100644
--- a/config/metrics/counts_7d/20210216180616_incident_management_incident_change_confidential_weekly.yml
+++ b/config/metrics/counts_7d/20210216180616_incident_management_incident_change_confidential_weekly.yml
@@ -5,9 +5,9 @@ description: Count of unique users changing incidents to confidential per week
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180620_incident_management_total_unique_counts_weekly.yml b/config/metrics/counts_7d/20210216180620_incident_management_total_unique_counts_weekly.yml
index f8b657e27b7..f5d49e87d1c 100644
--- a/config/metrics/counts_7d/20210216180620_incident_management_total_unique_counts_weekly.yml
+++ b/config/metrics/counts_7d/20210216180620_incident_management_total_unique_counts_weekly.yml
@@ -5,9 +5,9 @@ description: Count of unique users performing events related to the incident man
product_section: ops
product_stage: monitor
product_group: group::monitor
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -35,3 +35,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216180623_incident_management_alert_create_incident_weekly.yml b/config/metrics/counts_7d/20210216180623_incident_management_alert_create_incident_weekly.yml
index fc6dbd18b32..24cd426e329 100644
--- a/config/metrics/counts_7d/20210216180623_incident_management_alert_create_incident_weekly.yml
+++ b/config/metrics/counts_7d/20210216180623_incident_management_alert_create_incident_weekly.yml
@@ -8,7 +8,7 @@ product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -23,3 +23,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181306_g_project_management_issue_description_changed_weekly.yml b/config/metrics/counts_7d/20210216181306_g_project_management_issue_description_changed_weekly.yml
index 67721c0f081..9c2fbc1b9ac 100644
--- a/config/metrics/counts_7d/20210216181306_g_project_management_issue_description_changed_weekly.yml
+++ b/config/metrics/counts_7d/20210216181306_g_project_management_issue_description_changed_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181310_g_project_management_issue_assignee_changed_weekly.yml b/config/metrics/counts_7d/20210216181310_g_project_management_issue_assignee_changed_weekly.yml
index 3b24f3d43ee..be1e250f443 100644
--- a/config/metrics/counts_7d/20210216181310_g_project_management_issue_assignee_changed_weekly.yml
+++ b/config/metrics/counts_7d/20210216181310_g_project_management_issue_assignee_changed_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181313_g_project_management_issue_made_confidential_weekly.yml b/config/metrics/counts_7d/20210216181313_g_project_management_issue_made_confidential_weekly.yml
index a1d3ebb2770..49fa886e26f 100644
--- a/config/metrics/counts_7d/20210216181313_g_project_management_issue_made_confidential_weekly.yml
+++ b/config/metrics/counts_7d/20210216181313_g_project_management_issue_made_confidential_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181317_g_project_management_issue_made_visible_weekly.yml b/config/metrics/counts_7d/20210216181317_g_project_management_issue_made_visible_weekly.yml
index eda1f51f2a1..e8a0b4dea52 100644
--- a/config/metrics/counts_7d/20210216181317_g_project_management_issue_made_visible_weekly.yml
+++ b/config/metrics/counts_7d/20210216181317_g_project_management_issue_made_visible_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181321_g_project_management_issue_created_weekly.yml b/config/metrics/counts_7d/20210216181321_g_project_management_issue_created_weekly.yml
index 8c4037fd1db..10a19c045cc 100644
--- a/config/metrics/counts_7d/20210216181321_g_project_management_issue_created_weekly.yml
+++ b/config/metrics/counts_7d/20210216181321_g_project_management_issue_created_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181324_g_project_management_issue_closed_weekly.yml b/config/metrics/counts_7d/20210216181324_g_project_management_issue_closed_weekly.yml
index 41dca2aac8d..8b8348e479a 100644
--- a/config/metrics/counts_7d/20210216181324_g_project_management_issue_closed_weekly.yml
+++ b/config/metrics/counts_7d/20210216181324_g_project_management_issue_closed_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181328_g_project_management_issue_reopened_weekly.yml b/config/metrics/counts_7d/20210216181328_g_project_management_issue_reopened_weekly.yml
index 5ceedd15a2f..36cfe848518 100644
--- a/config/metrics/counts_7d/20210216181328_g_project_management_issue_reopened_weekly.yml
+++ b/config/metrics/counts_7d/20210216181328_g_project_management_issue_reopened_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181332_g_project_management_issue_label_changed_weekly.yml b/config/metrics/counts_7d/20210216181332_g_project_management_issue_label_changed_weekly.yml
index 8df9757fc1e..9a271f2a877 100644
--- a/config/metrics/counts_7d/20210216181332_g_project_management_issue_label_changed_weekly.yml
+++ b/config/metrics/counts_7d/20210216181332_g_project_management_issue_label_changed_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181336_g_project_management_issue_milestone_changed_weekly.yml b/config/metrics/counts_7d/20210216181336_g_project_management_issue_milestone_changed_weekly.yml
index 6ce7c5fa822..83a8c402c00 100644
--- a/config/metrics/counts_7d/20210216181336_g_project_management_issue_milestone_changed_weekly.yml
+++ b/config/metrics/counts_7d/20210216181336_g_project_management_issue_milestone_changed_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181347_g_project_management_issue_cross_referenced_weekly.yml b/config/metrics/counts_7d/20210216181347_g_project_management_issue_cross_referenced_weekly.yml
index 0cd55b58aa0..13094d1f7fd 100644
--- a/config/metrics/counts_7d/20210216181347_g_project_management_issue_cross_referenced_weekly.yml
+++ b/config/metrics/counts_7d/20210216181347_g_project_management_issue_cross_referenced_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181350_g_project_management_issue_moved_weekly.yml b/config/metrics/counts_7d/20210216181350_g_project_management_issue_moved_weekly.yml
index 5ce80d42f33..0f344e64f41 100644
--- a/config/metrics/counts_7d/20210216181350_g_project_management_issue_moved_weekly.yml
+++ b/config/metrics/counts_7d/20210216181350_g_project_management_issue_moved_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181354_g_project_management_issue_related_weekly.yml b/config/metrics/counts_7d/20210216181354_g_project_management_issue_related_weekly.yml
index 7291567e17f..39ee0d124bd 100644
--- a/config/metrics/counts_7d/20210216181354_g_project_management_issue_related_weekly.yml
+++ b/config/metrics/counts_7d/20210216181354_g_project_management_issue_related_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181358_g_project_management_issue_unrelated_weekly.yml b/config/metrics/counts_7d/20210216181358_g_project_management_issue_unrelated_weekly.yml
index b7abc40eb9f..38606e53f88 100644
--- a/config/metrics/counts_7d/20210216181358_g_project_management_issue_unrelated_weekly.yml
+++ b/config/metrics/counts_7d/20210216181358_g_project_management_issue_unrelated_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181401_g_project_management_issue_marked_as_duplicate_weekly.yml b/config/metrics/counts_7d/20210216181401_g_project_management_issue_marked_as_duplicate_weekly.yml
index c661beb585f..647e9504281 100644
--- a/config/metrics/counts_7d/20210216181401_g_project_management_issue_marked_as_duplicate_weekly.yml
+++ b/config/metrics/counts_7d/20210216181401_g_project_management_issue_marked_as_duplicate_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181405_g_project_management_issue_locked_weekly.yml b/config/metrics/counts_7d/20210216181405_g_project_management_issue_locked_weekly.yml
index 99cfc654a63..de8177bd331 100644
--- a/config/metrics/counts_7d/20210216181405_g_project_management_issue_locked_weekly.yml
+++ b/config/metrics/counts_7d/20210216181405_g_project_management_issue_locked_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181409_g_project_management_issue_unlocked_weekly.yml b/config/metrics/counts_7d/20210216181409_g_project_management_issue_unlocked_weekly.yml
index 17754a930fb..e514429b22d 100644
--- a/config/metrics/counts_7d/20210216181409_g_project_management_issue_unlocked_weekly.yml
+++ b/config/metrics/counts_7d/20210216181409_g_project_management_issue_unlocked_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181422_g_project_management_issue_designs_added_weekly.yml b/config/metrics/counts_7d/20210216181422_g_project_management_issue_designs_added_weekly.yml
index 2bc0b001482..86b6b48f6a8 100644
--- a/config/metrics/counts_7d/20210216181422_g_project_management_issue_designs_added_weekly.yml
+++ b/config/metrics/counts_7d/20210216181422_g_project_management_issue_designs_added_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181425_g_project_management_issue_designs_modified_weekly.yml b/config/metrics/counts_7d/20210216181425_g_project_management_issue_designs_modified_weekly.yml
index 162e8e91c7b..da25aafd304 100644
--- a/config/metrics/counts_7d/20210216181425_g_project_management_issue_designs_modified_weekly.yml
+++ b/config/metrics/counts_7d/20210216181425_g_project_management_issue_designs_modified_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181429_g_project_management_issue_designs_removed_weekly.yml b/config/metrics/counts_7d/20210216181429_g_project_management_issue_designs_removed_weekly.yml
index 829f7610001..1ece28bef07 100644
--- a/config/metrics/counts_7d/20210216181429_g_project_management_issue_designs_removed_weekly.yml
+++ b/config/metrics/counts_7d/20210216181429_g_project_management_issue_designs_removed_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181433_g_project_management_issue_due_date_changed_weekly.yml b/config/metrics/counts_7d/20210216181433_g_project_management_issue_due_date_changed_weekly.yml
index b5fa673f35a..048bc6955b4 100644
--- a/config/metrics/counts_7d/20210216181433_g_project_management_issue_due_date_changed_weekly.yml
+++ b/config/metrics/counts_7d/20210216181433_g_project_management_issue_due_date_changed_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181437_g_project_management_issue_time_estimate_changed_weekly.yml b/config/metrics/counts_7d/20210216181437_g_project_management_issue_time_estimate_changed_weekly.yml
index e855dec21e8..a839582fd15 100644
--- a/config/metrics/counts_7d/20210216181437_g_project_management_issue_time_estimate_changed_weekly.yml
+++ b/config/metrics/counts_7d/20210216181437_g_project_management_issue_time_estimate_changed_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181440_g_project_management_issue_time_spent_changed_weekly.yml b/config/metrics/counts_7d/20210216181440_g_project_management_issue_time_spent_changed_weekly.yml
index e7d071731db..f30fa4a93ac 100644
--- a/config/metrics/counts_7d/20210216181440_g_project_management_issue_time_spent_changed_weekly.yml
+++ b/config/metrics/counts_7d/20210216181440_g_project_management_issue_time_spent_changed_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181444_g_project_management_issue_comment_added_weekly.yml b/config/metrics/counts_7d/20210216181444_g_project_management_issue_comment_added_weekly.yml
index 76d60040879..bf575481220 100644
--- a/config/metrics/counts_7d/20210216181444_g_project_management_issue_comment_added_weekly.yml
+++ b/config/metrics/counts_7d/20210216181444_g_project_management_issue_comment_added_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181448_g_project_management_issue_comment_edited_weekly.yml b/config/metrics/counts_7d/20210216181448_g_project_management_issue_comment_edited_weekly.yml
index d0c8fd5c863..b1aa4e063ad 100644
--- a/config/metrics/counts_7d/20210216181448_g_project_management_issue_comment_edited_weekly.yml
+++ b/config/metrics/counts_7d/20210216181448_g_project_management_issue_comment_edited_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181451_g_project_management_issue_comment_removed_weekly.yml b/config/metrics/counts_7d/20210216181451_g_project_management_issue_comment_removed_weekly.yml
index 8dace3f5ed4..1af96466839 100644
--- a/config/metrics/counts_7d/20210216181451_g_project_management_issue_comment_removed_weekly.yml
+++ b/config/metrics/counts_7d/20210216181451_g_project_management_issue_comment_removed_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181459_g_project_management_issue_cloned_weekly.yml b/config/metrics/counts_7d/20210216181459_g_project_management_issue_cloned_weekly.yml
index 3a5a3b6c3b6..6dd6c3db6c5 100644
--- a/config/metrics/counts_7d/20210216181459_g_project_management_issue_cloned_weekly.yml
+++ b/config/metrics/counts_7d/20210216181459_g_project_management_issue_cloned_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181503_issues_edit_total_unique_counts_weekly.yml b/config/metrics/counts_7d/20210216181503_issues_edit_total_unique_counts_weekly.yml
index 6e016fabbba..ad741e44bb6 100644
--- a/config/metrics/counts_7d/20210216181503_issues_edit_total_unique_counts_weekly.yml
+++ b/config/metrics/counts_7d/20210216181503_issues_edit_total_unique_counts_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -54,3 +54,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181506_i_quickactions_approve_weekly.yml b/config/metrics/counts_7d/20210216181506_i_quickactions_approve_weekly.yml
index 0ed6dc80f0b..8a9121e954c 100644
--- a/config/metrics/counts_7d/20210216181506_i_quickactions_approve_weekly.yml
+++ b/config/metrics/counts_7d/20210216181506_i_quickactions_approve_weekly.yml
@@ -7,17 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_approve
-instrumentation_class: RedisHLLMetric
-options:
- events:
- - i_quickactions_approve
+ - i_quickactions_approve
distribution:
- ce
- ee
@@ -25,3 +21,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181510_i_quickactions_assign_single_weekly.yml b/config/metrics/counts_7d/20210216181510_i_quickactions_assign_single_weekly.yml
index a7a3ec1ad95..d89739ce6fc 100644
--- a/config/metrics/counts_7d/20210216181510_i_quickactions_assign_single_weekly.yml
+++ b/config/metrics/counts_7d/20210216181510_i_quickactions_assign_single_weekly.yml
@@ -1,24 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_assign_single_weekly
-description: Count of WAU using the `/assign @user1` quick action to assign a single individual to an issuable
+description: Count of WAU using the `/assign @user1` quick action to assign a single
+ individual to an issuable
product_section: dev
product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_assign_single
+ - i_quickactions_assign_single
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
-
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181517_i_quickactions_assign_self_weekly.yml b/config/metrics/counts_7d/20210216181517_i_quickactions_assign_self_weekly.yml
index a5115aff30f..dfc0547fbf3 100644
--- a/config/metrics/counts_7d/20210216181517_i_quickactions_assign_self_weekly.yml
+++ b/config/metrics/counts_7d/20210216181517_i_quickactions_assign_self_weekly.yml
@@ -1,23 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_assign_self_weekly
-description: Count of WAU using the `/assign me` quick action to assign self to an issuable
+description: Count of WAU using the `/assign me` quick action to assign self to an
+ issuable
product_section: dev
product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_assign_self
+ - i_quickactions_assign_self
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
-- ultimate \ No newline at end of file
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181521_i_quickactions_assign_reviewer_weekly.yml b/config/metrics/counts_7d/20210216181521_i_quickactions_assign_reviewer_weekly.yml
index c38a8df55d8..2482fa44596 100644
--- a/config/metrics/counts_7d/20210216181521_i_quickactions_assign_reviewer_weekly.yml
+++ b/config/metrics/counts_7d/20210216181521_i_quickactions_assign_reviewer_weekly.yml
@@ -1,24 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_assign_reviewer_weekly
-description: Count of WAU using the `/assign_reviewer` or `request_reviewer` quick action
+description: Count of WAU using the `/assign_reviewer` or `request_reviewer` quick
+ action
product_section: dev
product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_assign_reviewer
+ - i_quickactions_assign_reviewer
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
-
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181525_i_quickactions_award_weekly.yml b/config/metrics/counts_7d/20210216181525_i_quickactions_award_weekly.yml
index 38bf53b85c7..f0a6f19180d 100644
--- a/config/metrics/counts_7d/20210216181525_i_quickactions_award_weekly.yml
+++ b/config/metrics/counts_7d/20210216181525_i_quickactions_award_weekly.yml
@@ -1,24 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_award_weekly
-description: Count of WAU using the `/award` quick action to set an award emoji on an issuable
+description: Count of WAU using the `/award` quick action to set an award emoji on
+ an issuable
product_section: dev
product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_award
+ - i_quickactions_award
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
-
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181529_i_quickactions_board_move_weekly.yml b/config/metrics/counts_7d/20210216181529_i_quickactions_board_move_weekly.yml
index 8f250a3f9d6..b036a1f2a9a 100644
--- a/config/metrics/counts_7d/20210216181529_i_quickactions_board_move_weekly.yml
+++ b/config/metrics/counts_7d/20210216181529_i_quickactions_board_move_weekly.yml
@@ -7,17 +7,18 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_board_move
+ - i_quickactions_board_move
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181540_i_quickactions_clone_weekly.yml b/config/metrics/counts_7d/20210216181540_i_quickactions_clone_weekly.yml
index 4c7e9a65640..cb9ed4dd02f 100644
--- a/config/metrics/counts_7d/20210216181540_i_quickactions_clone_weekly.yml
+++ b/config/metrics/counts_7d/20210216181540_i_quickactions_clone_weekly.yml
@@ -7,17 +7,18 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_clone
+ - i_quickactions_clone
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181543_i_quickactions_close_weekly.yml b/config/metrics/counts_7d/20210216181543_i_quickactions_close_weekly.yml
index 0abd261a955..c2fbf0dfad1 100644
--- a/config/metrics/counts_7d/20210216181543_i_quickactions_close_weekly.yml
+++ b/config/metrics/counts_7d/20210216181543_i_quickactions_close_weekly.yml
@@ -7,17 +7,18 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_close
+ - i_quickactions_close
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181547_i_quickactions_confidential_weekly.yml b/config/metrics/counts_7d/20210216181547_i_quickactions_confidential_weekly.yml
index 923c8acdb38..952d089c404 100644
--- a/config/metrics/counts_7d/20210216181547_i_quickactions_confidential_weekly.yml
+++ b/config/metrics/counts_7d/20210216181547_i_quickactions_confidential_weekly.yml
@@ -1,23 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_confidential_weekly
-description: Count of WAU using the `/confidential` quick action to set an issue as confidential
+description: Count of WAU using the `/confidential` quick action to set an issue as
+ confidential
product_section: dev
product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_confidential
+ - i_quickactions_confidential
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181551_i_quickactions_copy_metadata_merge_request_weekly.yml b/config/metrics/counts_7d/20210216181551_i_quickactions_copy_metadata_merge_request_weekly.yml
index 38ed29c54d0..66e0558593e 100644
--- a/config/metrics/counts_7d/20210216181551_i_quickactions_copy_metadata_merge_request_weekly.yml
+++ b/config/metrics/counts_7d/20210216181551_i_quickactions_copy_metadata_merge_request_weekly.yml
@@ -7,18 +7,18 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_copy_metadata_merge_request
+ - i_quickactions_copy_metadata_merge_request
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
-
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181554_i_quickactions_copy_metadata_issue_weekly.yml b/config/metrics/counts_7d/20210216181554_i_quickactions_copy_metadata_issue_weekly.yml
index 2358d4409b9..a55680b9a9f 100644
--- a/config/metrics/counts_7d/20210216181554_i_quickactions_copy_metadata_issue_weekly.yml
+++ b/config/metrics/counts_7d/20210216181554_i_quickactions_copy_metadata_issue_weekly.yml
@@ -5,19 +5,20 @@ description: Count of WAU using the `/copy_metadata` quick action on an issue
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_copy_metadata_issue
+ - i_quickactions_copy_metadata_issue
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181558_i_quickactions_create_merge_request_weekly.yml b/config/metrics/counts_7d/20210216181558_i_quickactions_create_merge_request_weekly.yml
index 35eecec2be2..589f64cb96f 100644
--- a/config/metrics/counts_7d/20210216181558_i_quickactions_create_merge_request_weekly.yml
+++ b/config/metrics/counts_7d/20210216181558_i_quickactions_create_merge_request_weekly.yml
@@ -1,24 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_create_merge_request_weekly
-description: Count of WAU using the `/create_merge_request` quick action
+description: Count of WAU using the `/create_merge_request` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_create_merge_request
+ - i_quickactions_create_merge_request
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
-
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181602_i_quickactions_done_weekly.yml b/config/metrics/counts_7d/20210216181602_i_quickactions_done_weekly.yml
index 575992ebb56..0d8379ef87c 100644
--- a/config/metrics/counts_7d/20210216181602_i_quickactions_done_weekly.yml
+++ b/config/metrics/counts_7d/20210216181602_i_quickactions_done_weekly.yml
@@ -7,17 +7,18 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_done
+ - i_quickactions_done
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181605_i_quickactions_draft_weekly.yml b/config/metrics/counts_7d/20210216181605_i_quickactions_draft_weekly.yml
index dff8845d13e..4722680c905 100644
--- a/config/metrics/counts_7d/20210216181605_i_quickactions_draft_weekly.yml
+++ b/config/metrics/counts_7d/20210216181605_i_quickactions_draft_weekly.yml
@@ -4,20 +4,21 @@ key_path: redis_hll_counters.quickactions.i_quickactions_draft_weekly
description: Count of WAU using the `/draft` quick action on a Merge Request
product_section: dev
product_stage: create
-product_group: group::source code
+product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_draft
+ - i_quickactions_draft
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181609_i_quickactions_due_weekly.yml b/config/metrics/counts_7d/20210216181609_i_quickactions_due_weekly.yml
index 269b20a85f4..c1ab3be82a4 100644
--- a/config/metrics/counts_7d/20210216181609_i_quickactions_due_weekly.yml
+++ b/config/metrics/counts_7d/20210216181609_i_quickactions_due_weekly.yml
@@ -1,24 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_due_weekly
-description: Count of WAU using the `/due` quick action to change the due date on an issuable
+description: Count of WAU using the `/due` quick action to change the due date on
+ an issuable
product_section: dev
product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_due
+ - i_quickactions_due
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
-
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181613_i_quickactions_duplicate_weekly.yml b/config/metrics/counts_7d/20210216181613_i_quickactions_duplicate_weekly.yml
index 0b4d121e7f1..86e7e3f5fe7 100644
--- a/config/metrics/counts_7d/20210216181613_i_quickactions_duplicate_weekly.yml
+++ b/config/metrics/counts_7d/20210216181613_i_quickactions_duplicate_weekly.yml
@@ -1,23 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_duplicate_weekly
-description: Count of WAU using the `/duplicate` quick action to mark an issue as a duplicate of another
+description: Count of WAU using the `/duplicate` quick action to mark an issue as
+ a duplicate of another
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_duplicate
+ - i_quickactions_duplicate
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181620_i_quickactions_estimate_weekly.yml b/config/metrics/counts_7d/20210216181620_i_quickactions_estimate_weekly.yml
index 7a48efa232f..148a58433f7 100644
--- a/config/metrics/counts_7d/20210216181620_i_quickactions_estimate_weekly.yml
+++ b/config/metrics/counts_7d/20210216181620_i_quickactions_estimate_weekly.yml
@@ -1,23 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_estimate_weekly
-description: Count of WAU using the `/estimate` quick action to set a time estimate on an issue
+description: Count of WAU using the `/estimate` quick action to set a time estimate
+ on an issue
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: time_tracking
+product_category: time_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_estimate
+ - i_quickactions_estimate
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
-- ultimate \ No newline at end of file
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181628_i_quickactions_label_weekly.yml b/config/metrics/counts_7d/20210216181628_i_quickactions_label_weekly.yml
index 0106fe73fb7..9312c4cad2e 100644
--- a/config/metrics/counts_7d/20210216181628_i_quickactions_label_weekly.yml
+++ b/config/metrics/counts_7d/20210216181628_i_quickactions_label_weekly.yml
@@ -5,19 +5,20 @@ description: Count of WAU using the `/label` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_label
+ - i_quickactions_label
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181631_i_quickactions_lock_weekly.yml b/config/metrics/counts_7d/20210216181631_i_quickactions_lock_weekly.yml
index 05baed74083..619c94b117b 100644
--- a/config/metrics/counts_7d/20210216181631_i_quickactions_lock_weekly.yml
+++ b/config/metrics/counts_7d/20210216181631_i_quickactions_lock_weekly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_lock_weekly
-description: Count of WAU using the `/lock` quick action
+description: Count of WAU using the `/lock` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_lock
+ - i_quickactions_lock
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
-- ultimate \ No newline at end of file
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181635_i_quickactions_merge_weekly.yml b/config/metrics/counts_7d/20210216181635_i_quickactions_merge_weekly.yml
index 4f71a2b34a2..6bacac4beb7 100644
--- a/config/metrics/counts_7d/20210216181635_i_quickactions_merge_weekly.yml
+++ b/config/metrics/counts_7d/20210216181635_i_quickactions_merge_weekly.yml
@@ -4,20 +4,21 @@ key_path: redis_hll_counters.quickactions.i_quickactions_merge_weekly
description: Count of WAU using the `/merge` quick action
product_section: dev
product_stage: create
-product_group: group::source code
+product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_merge
+ - i_quickactions_merge
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181639_i_quickactions_milestone_weekly.yml b/config/metrics/counts_7d/20210216181639_i_quickactions_milestone_weekly.yml
index 070b1a8fcea..1db5048970d 100644
--- a/config/metrics/counts_7d/20210216181639_i_quickactions_milestone_weekly.yml
+++ b/config/metrics/counts_7d/20210216181639_i_quickactions_milestone_weekly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_milestone_weekly
-description: Count of WAU using the `/milestone` quick action
-product_section: dev
+description: Count of WAU using the `/milestone` quick action
+product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_milestone
+ - i_quickactions_milestone
distribution:
- ce
- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181642_i_quickactions_move_weekly.yml b/config/metrics/counts_7d/20210216181642_i_quickactions_move_weekly.yml
index 2523ac9d6bc..00b5e9db85c 100644
--- a/config/metrics/counts_7d/20210216181642_i_quickactions_move_weekly.yml
+++ b/config/metrics/counts_7d/20210216181642_i_quickactions_move_weekly.yml
@@ -7,17 +7,18 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_move
+ - i_quickactions_move
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181657_i_quickactions_reassign_weekly.yml b/config/metrics/counts_7d/20210216181657_i_quickactions_reassign_weekly.yml
index abc657df3c2..488f5dcd547 100644
--- a/config/metrics/counts_7d/20210216181657_i_quickactions_reassign_weekly.yml
+++ b/config/metrics/counts_7d/20210216181657_i_quickactions_reassign_weekly.yml
@@ -5,19 +5,20 @@ description: Count of WAU using the `/reassign @user1` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_reassign
+ - i_quickactions_reassign
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181701_i_quickactions_reassign_reviewer_weekly.yml b/config/metrics/counts_7d/20210216181701_i_quickactions_reassign_reviewer_weekly.yml
index 951e97973cf..be7648f6fc9 100644
--- a/config/metrics/counts_7d/20210216181701_i_quickactions_reassign_reviewer_weekly.yml
+++ b/config/metrics/counts_7d/20210216181701_i_quickactions_reassign_reviewer_weekly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_reassign_reviewer
+ - i_quickactions_reassign_reviewer
distribution:
- ce
- ee
@@ -21,4 +21,4 @@ tier:
- free
- premium
- ultimate
-
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181705_i_quickactions_rebase_weekly.yml b/config/metrics/counts_7d/20210216181705_i_quickactions_rebase_weekly.yml
index d43e975f900..fd68d75a7d1 100644
--- a/config/metrics/counts_7d/20210216181705_i_quickactions_rebase_weekly.yml
+++ b/config/metrics/counts_7d/20210216181705_i_quickactions_rebase_weekly.yml
@@ -3,21 +3,22 @@ data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_rebase_weekly
description: Count of WAU using the `/rebase` quick action on a Merge Request
product_section: dev
-product_stage: source_code
-product_group: group::source code
+product_stage: source_code
+product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_rebase
+ - i_quickactions_rebase
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181708_i_quickactions_relabel_weekly.yml b/config/metrics/counts_7d/20210216181708_i_quickactions_relabel_weekly.yml
index cd0ef13cf14..d25540e9127 100644
--- a/config/metrics/counts_7d/20210216181708_i_quickactions_relabel_weekly.yml
+++ b/config/metrics/counts_7d/20210216181708_i_quickactions_relabel_weekly.yml
@@ -5,19 +5,20 @@ description: Count of WAU using the `/relabel` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_relabel
+ - i_quickactions_relabel
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181712_i_quickactions_relate_weekly.yml b/config/metrics/counts_7d/20210216181712_i_quickactions_relate_weekly.yml
index f6076e328a8..6114b6340da 100644
--- a/config/metrics/counts_7d/20210216181712_i_quickactions_relate_weekly.yml
+++ b/config/metrics/counts_7d/20210216181712_i_quickactions_relate_weekly.yml
@@ -5,19 +5,20 @@ description: Count of WAU using the `/relate` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_relate
+ - i_quickactions_relate
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181719_i_quickactions_remove_due_date_weekly.yml b/config/metrics/counts_7d/20210216181719_i_quickactions_remove_due_date_weekly.yml
index 2111cb5f388..b0fe3966750 100644
--- a/config/metrics/counts_7d/20210216181719_i_quickactions_remove_due_date_weekly.yml
+++ b/config/metrics/counts_7d/20210216181719_i_quickactions_remove_due_date_weekly.yml
@@ -5,19 +5,20 @@ description: Count of WAU using the `/remove_due_date` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_remove_due_date
+ - i_quickactions_remove_due_date
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181727_i_quickactions_remove_estimate_weekly.yml b/config/metrics/counts_7d/20210216181727_i_quickactions_remove_estimate_weekly.yml
index 69035a5cd2f..181533aa209 100644
--- a/config/metrics/counts_7d/20210216181727_i_quickactions_remove_estimate_weekly.yml
+++ b/config/metrics/counts_7d/20210216181727_i_quickactions_remove_estimate_weekly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_remove_estimate_weekly
-description: Count of WAU using the `/remove_estimate` quick action
+description: Count of WAU using the `/remove_estimate` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: time_tracking
+product_category: time_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_remove_estimate
+ - i_quickactions_remove_estimate
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
-- ultimate \ No newline at end of file
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181734_i_quickactions_remove_milestone_weekly.yml b/config/metrics/counts_7d/20210216181734_i_quickactions_remove_milestone_weekly.yml
index 4dffc94c782..fa4c059c8a3 100644
--- a/config/metrics/counts_7d/20210216181734_i_quickactions_remove_milestone_weekly.yml
+++ b/config/metrics/counts_7d/20210216181734_i_quickactions_remove_milestone_weekly.yml
@@ -1,24 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_remove_milestone_weekly
-description: Count of WAU using the `/remove_milestone` quick action
+description: Count of WAU using the `/remove_milestone` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_remove_milestone
+ - i_quickactions_remove_milestone
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
-
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181742_i_quickactions_remove_time_spent_weekly.yml b/config/metrics/counts_7d/20210216181742_i_quickactions_remove_time_spent_weekly.yml
index 83ade2edb86..884c0b82e08 100644
--- a/config/metrics/counts_7d/20210216181742_i_quickactions_remove_time_spent_weekly.yml
+++ b/config/metrics/counts_7d/20210216181742_i_quickactions_remove_time_spent_weekly.yml
@@ -7,17 +7,18 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_remove_time_spent
+ - i_quickactions_remove_time_spent
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181745_i_quickactions_remove_zoom_weekly.yml b/config/metrics/counts_7d/20210216181745_i_quickactions_remove_zoom_weekly.yml
index bd3beb71a63..5bace9a2061 100644
--- a/config/metrics/counts_7d/20210216181745_i_quickactions_remove_zoom_weekly.yml
+++ b/config/metrics/counts_7d/20210216181745_i_quickactions_remove_zoom_weekly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_remove_zoom_weekly
-description: Count of WAU using the `/remove_zoom` quick action
+description: Count of WAU using the `/remove_zoom` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_remove_zoom
+ - i_quickactions_remove_zoom
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
-- ultimate
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181749_i_quickactions_reopen_weekly.yml b/config/metrics/counts_7d/20210216181749_i_quickactions_reopen_weekly.yml
index 4b861cf2767..fe59955bc03 100644
--- a/config/metrics/counts_7d/20210216181749_i_quickactions_reopen_weekly.yml
+++ b/config/metrics/counts_7d/20210216181749_i_quickactions_reopen_weekly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_reopen_weekly
-description: Count of WAU using the `/reopen` quick action
+description: Count of WAU using the `/reopen` quick action
product_section: dev
product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_reopen
+ - i_quickactions_reopen
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181753_i_quickactions_shrug_weekly.yml b/config/metrics/counts_7d/20210216181753_i_quickactions_shrug_weekly.yml
index b9f858890da..7e984753739 100644
--- a/config/metrics/counts_7d/20210216181753_i_quickactions_shrug_weekly.yml
+++ b/config/metrics/counts_7d/20210216181753_i_quickactions_shrug_weekly.yml
@@ -1,24 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_shrug_weekly
-description: Count of WAU using the `/shrug` quick action
+description: Count of WAU using the `/shrug` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_shrug
+ - i_quickactions_shrug
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
-
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181756_i_quickactions_spend_subtract_weekly.yml b/config/metrics/counts_7d/20210216181756_i_quickactions_spend_subtract_weekly.yml
index 95ca954f425..7225a40b37b 100644
--- a/config/metrics/counts_7d/20210216181756_i_quickactions_spend_subtract_weekly.yml
+++ b/config/metrics/counts_7d/20210216181756_i_quickactions_spend_subtract_weekly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_spend_subtract_weekly
-description: Count of WAU using the `/spend` quick action to subtract time spent
+description: Count of WAU using the `/spend` quick action to subtract time spent
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: time_tracking
+product_category: time_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_spend_subtract
+ - i_quickactions_spend_subtract
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181800_i_quickactions_spend_add_weekly.yml b/config/metrics/counts_7d/20210216181800_i_quickactions_spend_add_weekly.yml
index 5b96c328208..5cc536093c5 100644
--- a/config/metrics/counts_7d/20210216181800_i_quickactions_spend_add_weekly.yml
+++ b/config/metrics/counts_7d/20210216181800_i_quickactions_spend_add_weekly.yml
@@ -1,24 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_spend_add_weekly
-description: Count of WAU using the `/spend` quick action to add time spent
+description: Count of WAU using the `/spend` quick action to add time spent
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_spend_add
+ - i_quickactions_spend_add
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
-
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181804_i_quickactions_submit_review_weekly.yml b/config/metrics/counts_7d/20210216181804_i_quickactions_submit_review_weekly.yml
index 61738f62506..9a70b3d8e26 100644
--- a/config/metrics/counts_7d/20210216181804_i_quickactions_submit_review_weekly.yml
+++ b/config/metrics/counts_7d/20210216181804_i_quickactions_submit_review_weekly.yml
@@ -7,17 +7,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_submit_review
+ - i_quickactions_submit_review
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
-- ultimate
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181808_i_quickactions_subscribe_weekly.yml b/config/metrics/counts_7d/20210216181808_i_quickactions_subscribe_weekly.yml
index 819b314862d..aeffa97de1f 100644
--- a/config/metrics/counts_7d/20210216181808_i_quickactions_subscribe_weekly.yml
+++ b/config/metrics/counts_7d/20210216181808_i_quickactions_subscribe_weekly.yml
@@ -1,24 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_subscribe_weekly
-description: Count of WAU using the `/subscribe` quick action
+description: Count of WAU using the `/subscribe` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_subscribe
+ - i_quickactions_subscribe
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
-
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181811_i_quickactions_tableflip_weekly.yml b/config/metrics/counts_7d/20210216181811_i_quickactions_tableflip_weekly.yml
index 490dd5f3dce..0b2d759771a 100644
--- a/config/metrics/counts_7d/20210216181811_i_quickactions_tableflip_weekly.yml
+++ b/config/metrics/counts_7d/20210216181811_i_quickactions_tableflip_weekly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_tableflip_weekly
-description: Count of WAU using the `/tableflip` quick action
+description: Count of WAU using the `/tableflip` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_tableflip
+ - i_quickactions_tableflip
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181815_i_quickactions_tag_weekly.yml b/config/metrics/counts_7d/20210216181815_i_quickactions_tag_weekly.yml
index 52ffe59604e..d7073ac8378 100644
--- a/config/metrics/counts_7d/20210216181815_i_quickactions_tag_weekly.yml
+++ b/config/metrics/counts_7d/20210216181815_i_quickactions_tag_weekly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_tag_weekly
-description: Count of WAU using the `/tag` quick action
+description: Count of WAU using the `/tag` quick action
product_section: dev
product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_tag
+ - i_quickactions_tag
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181819_i_quickactions_target_branch_weekly.yml b/config/metrics/counts_7d/20210216181819_i_quickactions_target_branch_weekly.yml
index 8a7a20e0168..6741280b2e4 100644
--- a/config/metrics/counts_7d/20210216181819_i_quickactions_target_branch_weekly.yml
+++ b/config/metrics/counts_7d/20210216181819_i_quickactions_target_branch_weekly.yml
@@ -4,20 +4,21 @@ key_path: redis_hll_counters.quickactions.i_quickactions_target_branch_weekly
description: Count of WAU using the `/target_branch` quick action on Merge Requests
product_section: dev
product_stage: create
-product_group: group::source code
+product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_target_branch
+ - i_quickactions_target_branch
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
-- ultimate \ No newline at end of file
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181822_i_quickactions_title_weekly.yml b/config/metrics/counts_7d/20210216181822_i_quickactions_title_weekly.yml
index 5d390130bcf..30b60d472ff 100644
--- a/config/metrics/counts_7d/20210216181822_i_quickactions_title_weekly.yml
+++ b/config/metrics/counts_7d/20210216181822_i_quickactions_title_weekly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_title_weekly
-description: Count of WAU using the `/title` quick action
+description: Count of WAU using the `/title` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_title
+ - i_quickactions_title
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181826_i_quickactions_todo_weekly.yml b/config/metrics/counts_7d/20210216181826_i_quickactions_todo_weekly.yml
index 62c2ecadc39..1752c3a4fd4 100644
--- a/config/metrics/counts_7d/20210216181826_i_quickactions_todo_weekly.yml
+++ b/config/metrics/counts_7d/20210216181826_i_quickactions_todo_weekly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_todo_weekly
-description: Count of WAU using the `/todo` quick action
+description: Count of WAU using the `/todo` quick action
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_todo
+ - i_quickactions_todo
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181830_i_quickactions_unassign_specific_weekly.yml b/config/metrics/counts_7d/20210216181830_i_quickactions_unassign_specific_weekly.yml
index a3bed5449c9..fe8532e5e47 100644
--- a/config/metrics/counts_7d/20210216181830_i_quickactions_unassign_specific_weekly.yml
+++ b/config/metrics/counts_7d/20210216181830_i_quickactions_unassign_specific_weekly.yml
@@ -7,17 +7,18 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_unassign_specific
+ - i_quickactions_unassign_specific
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181833_i_quickactions_unassign_all_weekly.yml b/config/metrics/counts_7d/20210216181833_i_quickactions_unassign_all_weekly.yml
index 41b6b77e73b..c9b473cc2de 100644
--- a/config/metrics/counts_7d/20210216181833_i_quickactions_unassign_all_weekly.yml
+++ b/config/metrics/counts_7d/20210216181833_i_quickactions_unassign_all_weekly.yml
@@ -7,17 +7,18 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_unassign_all
+ - i_quickactions_unassign_all
distribution:
- ce
-- ee
+- ee
tier:
- free
- premium
-- ultimate \ No newline at end of file
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181837_i_quickactions_unassign_reviewer_weekly.yml b/config/metrics/counts_7d/20210216181837_i_quickactions_unassign_reviewer_weekly.yml
index ffcd580673e..8b3be77a180 100644
--- a/config/metrics/counts_7d/20210216181837_i_quickactions_unassign_reviewer_weekly.yml
+++ b/config/metrics/counts_7d/20210216181837_i_quickactions_unassign_reviewer_weekly.yml
@@ -1,23 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_unassign_reviewer_weekly
-description: Count of WAU using the `/unassign_reviewer` or `/remove_reviewer` quick action on Merge Requests
+description: Count of WAU using the `/unassign_reviewer` or `/remove_reviewer` quick
+ action on Merge Requests
product_section: dev
product_stage: create
-product_group: group::code review
+product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_unassign_reviewer
+ - i_quickactions_unassign_reviewer
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181841_i_quickactions_unlabel_specific_weekly.yml b/config/metrics/counts_7d/20210216181841_i_quickactions_unlabel_specific_weekly.yml
index 5ce812bd6ec..1725a41355f 100644
--- a/config/metrics/counts_7d/20210216181841_i_quickactions_unlabel_specific_weekly.yml
+++ b/config/metrics/counts_7d/20210216181841_i_quickactions_unlabel_specific_weekly.yml
@@ -1,23 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_unlabel_specific_weekly
-description: Count of WAU using the `/unlabel` or `/remove_label` quick action to remove one or more specific labels
+description: Count of WAU using the `/unlabel` or `/remove_label` quick action to
+ remove one or more specific labels
product_section: dev
product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_unlabel_specific
+ - i_quickactions_unlabel_specific
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181845_i_quickactions_unlabel_all_weekly.yml b/config/metrics/counts_7d/20210216181845_i_quickactions_unlabel_all_weekly.yml
index b78f9ca8ef9..314d0520116 100644
--- a/config/metrics/counts_7d/20210216181845_i_quickactions_unlabel_all_weekly.yml
+++ b/config/metrics/counts_7d/20210216181845_i_quickactions_unlabel_all_weekly.yml
@@ -7,18 +7,18 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_unlabel_all
+ - i_quickactions_unlabel_all
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
-
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181848_i_quickactions_unlock_weekly.yml b/config/metrics/counts_7d/20210216181848_i_quickactions_unlock_weekly.yml
index 57b310903f3..e43a93bcb14 100644
--- a/config/metrics/counts_7d/20210216181848_i_quickactions_unlock_weekly.yml
+++ b/config/metrics/counts_7d/20210216181848_i_quickactions_unlock_weekly.yml
@@ -7,17 +7,18 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_unlock
+ - i_quickactions_unlock
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181852_i_quickactions_unsubscribe_weekly.yml b/config/metrics/counts_7d/20210216181852_i_quickactions_unsubscribe_weekly.yml
index a105958e4a1..02d944eca4f 100644
--- a/config/metrics/counts_7d/20210216181852_i_quickactions_unsubscribe_weekly.yml
+++ b/config/metrics/counts_7d/20210216181852_i_quickactions_unsubscribe_weekly.yml
@@ -7,17 +7,18 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_unsubscribe
+ - i_quickactions_unsubscribe
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181859_i_quickactions_wip_weekly.yml b/config/metrics/counts_7d/20210216181859_i_quickactions_wip_weekly.yml
index 25e8f4be9ea..c5d3ed1a478 100644
--- a/config/metrics/counts_7d/20210216181859_i_quickactions_wip_weekly.yml
+++ b/config/metrics/counts_7d/20210216181859_i_quickactions_wip_weekly.yml
@@ -4,20 +4,21 @@ key_path: redis_hll_counters.quickactions.i_quickactions_wip_weekly
description: Count of WAU using the `/wip` quick action on Merge Requests
product_section: dev
product_stage: create
-product_group: group::source code
+product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_wip
+ - i_quickactions_wip
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
+- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216181903_i_quickactions_zoom_weekly.yml b/config/metrics/counts_7d/20210216181903_i_quickactions_zoom_weekly.yml
index 5a39c45b49b..5f60ce53ab5 100644
--- a/config/metrics/counts_7d/20210216181903_i_quickactions_zoom_weekly.yml
+++ b/config/metrics/counts_7d/20210216181903_i_quickactions_zoom_weekly.yml
@@ -1,23 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.quickactions.i_quickactions_zoom_weekly
-description: Count of WAU using the `/zoom` quick action on Issues
+description: Count of WAU using the `/zoom` quick action on Issues
product_section: dev
product_stage: plan
product_group: group::project management
-product_category: issue_tracking
+product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_quickactions_zoom
+ - i_quickactions_zoom
distribution:
- ce
-- ee
+- ee
tier:
- free
-- premium
-- ultimate \ No newline at end of file
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216182100_wiki_action_weekly.yml b/config/metrics/counts_7d/20210216182100_wiki_action_weekly.yml
index e82cd9f475b..550d825a1e8 100644
--- a/config/metrics/counts_7d/20210216182100_wiki_action_weekly.yml
+++ b/config/metrics/counts_7d/20210216182100_wiki_action_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216182104_design_action_weekly.yml b/config/metrics/counts_7d/20210216182104_design_action_weekly.yml
index 476ec404822..75b340a8ad5 100644
--- a/config/metrics/counts_7d/20210216182104_design_action_weekly.yml
+++ b/config/metrics/counts_7d/20210216182104_design_action_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216182107_project_action_weekly.yml b/config/metrics/counts_7d/20210216182107_project_action_weekly.yml
index db7052b12ef..21f857dac99 100644
--- a/config/metrics/counts_7d/20210216182107_project_action_weekly.yml
+++ b/config/metrics/counts_7d/20210216182107_project_action_weekly.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: redis_hll_counters.source_code.project_action_weekly
-description: Count of unique actions done on projects and related resources (create, edit, delete, comment)
+description: Count of unique actions done on projects and related resources (create,
+ edit, delete, comment)
product_section: dev
product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +23,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216182134_i_testing_test_case_parsed_weekly.yml b/config/metrics/counts_7d/20210216182134_i_testing_test_case_parsed_weekly.yml
index d03fd57da15..94748444af5 100644
--- a/config/metrics/counts_7d/20210216182134_i_testing_test_case_parsed_weekly.yml
+++ b/config/metrics/counts_7d/20210216182134_i_testing_test_case_parsed_weekly.yml
@@ -8,7 +8,7 @@ product_stage: verify
product_group: group::testing
product_category: code_testing
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -23,3 +23,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184022_g_edit_by_sse_weekly.yml b/config/metrics/counts_7d/20210216184022_g_edit_by_sse_weekly.yml
index abde6514c0d..a903ce2ceea 100644
--- a/config/metrics/counts_7d/20210216184022_g_edit_by_sse_weekly.yml
+++ b/config/metrics/counts_7d/20210216184022_g_edit_by_sse_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: static_site_editor
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184045_git_write_action_weekly.yml b/config/metrics/counts_7d/20210216184045_git_write_action_weekly.yml
index 3e2c55c64a5..7c49c843167 100644
--- a/config/metrics/counts_7d/20210216184045_git_write_action_weekly.yml
+++ b/config/metrics/counts_7d/20210216184045_git_write_action_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184253_i_snippets_show_weekly.yml b/config/metrics/counts_7d/20210216184253_i_snippets_show_weekly.yml
index ad3c78880b6..7fd1d24d098 100644
--- a/config/metrics/counts_7d/20210216184253_i_snippets_show_weekly.yml
+++ b/config/metrics/counts_7d/20210216184253_i_snippets_show_weekly.yml
@@ -7,13 +7,13 @@ product_stage: create
product_group: group::editor
product_category: snippets
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_snippets_show
+ - i_snippets_show
distribution:
- ce
- ee
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184257_p_terraform_state_api_unique_users_weekly.yml b/config/metrics/counts_7d/20210216184257_p_terraform_state_api_unique_users_weekly.yml
new file mode 100644
index 00000000000..bb33cc5bed5
--- /dev/null
+++ b/config/metrics/counts_7d/20210216184257_p_terraform_state_api_unique_users_weekly.yml
@@ -0,0 +1,25 @@
+---
+data_category: optional
+key_path: redis_hll_counters.terraform.p_terraform_state_api_unique_users_weekly
+description: Monthly active users of GitLab Managed Terraform states
+product_section: ops
+product_stage: configure
+product_group: group::configure
+product_category: infrastructure_as_code
+value_type: number
+status: active
+time_frame: 7d
+data_source: redis_hll
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - p_terraform_state_api_unique_users
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184301_o_pipeline_authoring_unique_users_committing_ciconfigfile_weekly.yml b/config/metrics/counts_7d/20210216184301_o_pipeline_authoring_unique_users_committing_ciconfigfile_weekly.yml
index 34c7a54c61a..eaf4f7780cd 100644
--- a/config/metrics/counts_7d/20210216184301_o_pipeline_authoring_unique_users_committing_ciconfigfile_weekly.yml
+++ b/config/metrics/counts_7d/20210216184301_o_pipeline_authoring_unique_users_committing_ciconfigfile_weekly.yml
@@ -7,13 +7,13 @@ product_stage: verify
product_group: group::pipeline authoring
product_category: pipeline_authoring
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - o_pipeline_authoring_unique_users_committing_ciconfigfile
+ - o_pipeline_authoring_unique_users_committing_ciconfigfile
distribution:
- ee
- ce
@@ -21,3 +21,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184310_i_code_review_user_toggled_task_item_status_weekly.yml b/config/metrics/counts_7d/20210216184310_i_code_review_user_toggled_task_item_status_weekly.yml
index 8d67335f0d2..892bafaadd6 100644
--- a/config/metrics/counts_7d/20210216184310_i_code_review_user_toggled_task_item_status_weekly.yml
+++ b/config/metrics/counts_7d/20210216184310_i_code_review_user_toggled_task_item_status_weekly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_toggled_task_item_status
+ - i_code_review_user_toggled_task_item_status
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184320_i_code_review_user_approve_mr_weekly.yml b/config/metrics/counts_7d/20210216184320_i_code_review_user_approve_mr_weekly.yml
index 14eb2ace2fb..6f4de7ac49e 100644
--- a/config/metrics/counts_7d/20210216184320_i_code_review_user_approve_mr_weekly.yml
+++ b/config/metrics/counts_7d/20210216184320_i_code_review_user_approve_mr_weekly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_approve_mr
+ - i_code_review_user_approve_mr
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184324_i_code_review_user_unapprove_mr_weekly.yml b/config/metrics/counts_7d/20210216184324_i_code_review_user_unapprove_mr_weekly.yml
index ba26fdb3d6f..756bbea7657 100644
--- a/config/metrics/counts_7d/20210216184324_i_code_review_user_unapprove_mr_weekly.yml
+++ b/config/metrics/counts_7d/20210216184324_i_code_review_user_unapprove_mr_weekly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_unapprove_mr
+ - i_code_review_user_unapprove_mr
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184328_i_code_review_user_resolve_thread_weekly.yml b/config/metrics/counts_7d/20210216184328_i_code_review_user_resolve_thread_weekly.yml
index 7aed369c9b0..7cff71aa29c 100644
--- a/config/metrics/counts_7d/20210216184328_i_code_review_user_resolve_thread_weekly.yml
+++ b/config/metrics/counts_7d/20210216184328_i_code_review_user_resolve_thread_weekly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_resolve_thread
+ - i_code_review_user_resolve_thread
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184332_i_code_review_user_unresolve_thread_weekly.yml b/config/metrics/counts_7d/20210216184332_i_code_review_user_unresolve_thread_weekly.yml
index 77e7b6a2ffd..20171f95fd3 100644
--- a/config/metrics/counts_7d/20210216184332_i_code_review_user_unresolve_thread_weekly.yml
+++ b/config/metrics/counts_7d/20210216184332_i_code_review_user_unresolve_thread_weekly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_unresolve_thread
+ - i_code_review_user_unresolve_thread
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184336_i_code_review_edit_mr_title_weekly.yml b/config/metrics/counts_7d/20210216184336_i_code_review_edit_mr_title_weekly.yml
index 2676804eab8..5e56eaaa837 100644
--- a/config/metrics/counts_7d/20210216184336_i_code_review_edit_mr_title_weekly.yml
+++ b/config/metrics/counts_7d/20210216184336_i_code_review_edit_mr_title_weekly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_edit_mr_title
+ - i_code_review_edit_mr_title
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184340_i_code_review_edit_mr_desc_weekly.yml b/config/metrics/counts_7d/20210216184340_i_code_review_edit_mr_desc_weekly.yml
index 7195b41324c..3c7a7f7d82a 100644
--- a/config/metrics/counts_7d/20210216184340_i_code_review_edit_mr_desc_weekly.yml
+++ b/config/metrics/counts_7d/20210216184340_i_code_review_edit_mr_desc_weekly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_edit_mr_desc
+ - i_code_review_edit_mr_desc
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184351_i_code_review_user_create_review_note_weekly.yml b/config/metrics/counts_7d/20210216184351_i_code_review_user_create_review_note_weekly.yml
index 0f1b9370ac8..6b91ab4102f 100644
--- a/config/metrics/counts_7d/20210216184351_i_code_review_user_create_review_note_weekly.yml
+++ b/config/metrics/counts_7d/20210216184351_i_code_review_user_create_review_note_weekly.yml
@@ -1,18 +1,19 @@
---
data_category: optional
key_path: redis_hll_counters.code_review.i_code_review_user_create_review_note_weekly
-description: Count of unique users per week who create a note as part of a merge request review
+description: Count of unique users per week who create a note as part of a merge request
+ review
product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_create_review_note
+ - i_code_review_user_create_review_note
distribution:
- ce
- ee
@@ -21,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184355_i_code_review_user_publish_review_weekly.yml b/config/metrics/counts_7d/20210216184355_i_code_review_user_publish_review_weekly.yml
index 2228aacdfac..20c4c9cef5e 100644
--- a/config/metrics/counts_7d/20210216184355_i_code_review_user_publish_review_weekly.yml
+++ b/config/metrics/counts_7d/20210216184355_i_code_review_user_publish_review_weekly.yml
@@ -1,18 +1,19 @@
---
data_category: optional
key_path: redis_hll_counters.code_review.i_code_review_user_publish_review_weekly
-description: Count of unique users per week who publish their review as part of a merge request review
+description: Count of unique users per week who publish their review as part of a
+ merge request review
product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_publish_review
+ - i_code_review_user_publish_review
distribution:
- ce
- ee
@@ -21,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184359_i_code_review_user_create_multiline_mr_comment_weekly.yml b/config/metrics/counts_7d/20210216184359_i_code_review_user_create_multiline_mr_comment_weekly.yml
index 5874320eaa6..26300d52dce 100644
--- a/config/metrics/counts_7d/20210216184359_i_code_review_user_create_multiline_mr_comment_weekly.yml
+++ b/config/metrics/counts_7d/20210216184359_i_code_review_user_create_multiline_mr_comment_weekly.yml
@@ -1,18 +1,19 @@
---
data_category: optional
key_path: redis_hll_counters.code_review.i_code_review_user_create_multiline_mr_comment_weekly
-description: Count of unique users per week who create a multiline comment in a merge request
+description: Count of unique users per week who create a multiline comment in a merge
+ request
product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_create_multiline_mr_comment
+ - i_code_review_user_create_multiline_mr_comment
distribution:
- ce
- ee
@@ -21,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184403_i_code_review_user_edit_multiline_mr_comment_weekly.yml b/config/metrics/counts_7d/20210216184403_i_code_review_user_edit_multiline_mr_comment_weekly.yml
index 77da5c512dd..2cbae1dff37 100644
--- a/config/metrics/counts_7d/20210216184403_i_code_review_user_edit_multiline_mr_comment_weekly.yml
+++ b/config/metrics/counts_7d/20210216184403_i_code_review_user_edit_multiline_mr_comment_weekly.yml
@@ -1,18 +1,19 @@
---
data_category: optional
key_path: redis_hll_counters.code_review.i_code_review_user_edit_multiline_mr_comment_weekly
-description: Count of unique users per week who edit a multiline comment in a merge request
+description: Count of unique users per week who edit a multiline comment in a merge
+ request
product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_edit_multiline_mr_comment
+ - i_code_review_user_edit_multiline_mr_comment
distribution:
- ce
- ee
@@ -21,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184407_i_code_review_user_remove_multiline_mr_comment_weekly.yml b/config/metrics/counts_7d/20210216184407_i_code_review_user_remove_multiline_mr_comment_weekly.yml
index a84bf25dc3b..1d80969f63a 100644
--- a/config/metrics/counts_7d/20210216184407_i_code_review_user_remove_multiline_mr_comment_weekly.yml
+++ b/config/metrics/counts_7d/20210216184407_i_code_review_user_remove_multiline_mr_comment_weekly.yml
@@ -1,22 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.code_review.i_code_review_user_remove_multiline_mr_comment_weekly
-description: Count of unique users per week who remove a multiline comment in a merge request
+description: Count of unique users per week who remove a multiline comment in a merge
+ request
product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_remove_multiline_mr_comment
+ - i_code_review_user_remove_multiline_mr_comment
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184416_i_code_review_user_assigned_weekly.yml b/config/metrics/counts_7d/20210216184416_i_code_review_user_assigned_weekly.yml
index 8dcb7355259..741f8ff83fc 100644
--- a/config/metrics/counts_7d/20210216184416_i_code_review_user_assigned_weekly.yml
+++ b/config/metrics/counts_7d/20210216184416_i_code_review_user_assigned_weekly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_assigned
+ - i_code_review_user_assigned
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184420_i_code_review_user_marked_as_draft_weekly.yml b/config/metrics/counts_7d/20210216184420_i_code_review_user_marked_as_draft_weekly.yml
index d629ff47e6a..960a9b18987 100644
--- a/config/metrics/counts_7d/20210216184420_i_code_review_user_marked_as_draft_weekly.yml
+++ b/config/metrics/counts_7d/20210216184420_i_code_review_user_marked_as_draft_weekly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_marked_as_draft
+ - i_code_review_user_marked_as_draft
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184424_i_code_review_user_unmarked_as_draft_weekly.yml b/config/metrics/counts_7d/20210216184424_i_code_review_user_unmarked_as_draft_weekly.yml
index a9ca86c9c89..76a7a4a97ab 100644
--- a/config/metrics/counts_7d/20210216184424_i_code_review_user_unmarked_as_draft_weekly.yml
+++ b/config/metrics/counts_7d/20210216184424_i_code_review_user_unmarked_as_draft_weekly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_unmarked_as_draft
+ - i_code_review_user_unmarked_as_draft
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184428_i_code_review_user_review_requested_weekly.yml b/config/metrics/counts_7d/20210216184428_i_code_review_user_review_requested_weekly.yml
index 1f048cc0ab5..70b88e97e20 100644
--- a/config/metrics/counts_7d/20210216184428_i_code_review_user_review_requested_weekly.yml
+++ b/config/metrics/counts_7d/20210216184428_i_code_review_user_review_requested_weekly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_review_requested
+ - i_code_review_user_review_requested
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184432_i_code_review_user_approval_rule_added_weekly.yml b/config/metrics/counts_7d/20210216184432_i_code_review_user_approval_rule_added_weekly.yml
index 3880ed061b0..038f53b62a9 100644
--- a/config/metrics/counts_7d/20210216184432_i_code_review_user_approval_rule_added_weekly.yml
+++ b/config/metrics/counts_7d/20210216184432_i_code_review_user_approval_rule_added_weekly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_approval_rule_added
+ - i_code_review_user_approval_rule_added
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184436_i_code_review_user_approval_rule_deleted_weekly.yml b/config/metrics/counts_7d/20210216184436_i_code_review_user_approval_rule_deleted_weekly.yml
index d11f0e03d57..8a7b2c31194 100644
--- a/config/metrics/counts_7d/20210216184436_i_code_review_user_approval_rule_deleted_weekly.yml
+++ b/config/metrics/counts_7d/20210216184436_i_code_review_user_approval_rule_deleted_weekly.yml
@@ -1,22 +1,24 @@
---
data_category: optional
key_path: redis_hll_counters.code_review.i_code_review_user_approval_rule_deleted_weekly
-description: Count of unique users per week who delete an approval rule to a merge request
+description: Count of unique users per week who delete an approval rule to a merge
+ request
product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_approval_rule_deleted
+ - i_code_review_user_approval_rule_deleted
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184440_i_code_review_user_approval_rule_edited_weekly.yml b/config/metrics/counts_7d/20210216184440_i_code_review_user_approval_rule_edited_weekly.yml
index f07a6b8084f..b5831569160 100644
--- a/config/metrics/counts_7d/20210216184440_i_code_review_user_approval_rule_edited_weekly.yml
+++ b/config/metrics/counts_7d/20210216184440_i_code_review_user_approval_rule_edited_weekly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_approval_rule_edited
+ - i_code_review_user_approval_rule_edited
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184444_i_code_review_user_vs_code_api_request_weekly.yml b/config/metrics/counts_7d/20210216184444_i_code_review_user_vs_code_api_request_weekly.yml
index a583b1a1ad7..cab4aa62b43 100644
--- a/config/metrics/counts_7d/20210216184444_i_code_review_user_vs_code_api_request_weekly.yml
+++ b/config/metrics/counts_7d/20210216184444_i_code_review_user_vs_code_api_request_weekly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: editor_extension
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_vs_code_api_request
+ - i_code_review_user_vs_code_api_request
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184448_i_code_review_user_create_mr_from_issue_weekly.yml b/config/metrics/counts_7d/20210216184448_i_code_review_user_create_mr_from_issue_weekly.yml
index 3147fe6d7a6..53a18b79605 100644
--- a/config/metrics/counts_7d/20210216184448_i_code_review_user_create_mr_from_issue_weekly.yml
+++ b/config/metrics/counts_7d/20210216184448_i_code_review_user_create_mr_from_issue_weekly.yml
@@ -6,17 +6,18 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_user_create_mr_from_issue
+ - i_code_review_user_create_mr_from_issue
distribution:
- ce
- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184452_code_review_total_unique_counts_weekly.yml b/config/metrics/counts_7d/20210216184452_code_review_total_unique_counts_weekly.yml
index ddd40581db4..24f82a6a442 100644
--- a/config/metrics/counts_7d/20210216184452_code_review_total_unique_counts_weekly.yml
+++ b/config/metrics/counts_7d/20210216184452_code_review_total_unique_counts_weekly.yml
@@ -6,68 +6,68 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_code_review_mr_diffs
- - i_code_review_user_single_file_diffs
- - i_code_review_mr_single_file_diffs
- - i_code_review_user_toggled_task_item_status
- - i_code_review_user_create_mr
- - i_code_review_user_close_mr
- - i_code_review_user_reopen_mr
- - i_code_review_user_approve_mr
- - i_code_review_user_unapprove_mr
- - i_code_review_user_resolve_thread
- - i_code_review_user_unresolve_thread
- - i_code_review_edit_mr_title
- - i_code_review_edit_mr_desc
- - i_code_review_user_merge_mr
- - i_code_review_user_create_mr_comment
- - i_code_review_user_edit_mr_comment
- - i_code_review_user_remove_mr_comment
- - i_code_review_user_create_review_note
- - i_code_review_user_publish_review
- - i_code_review_user_create_multiline_mr_comment
- - i_code_review_user_edit_multiline_mr_comment
- - i_code_review_user_remove_multiline_mr_comment
- - i_code_review_user_add_suggestion
- - i_code_review_user_apply_suggestion
- - i_code_review_user_assigned
- - i_code_review_user_marked_as_draft
- - i_code_review_user_unmarked_as_draft
- - i_code_review_user_review_requested
- - i_code_review_user_approval_rule_added
- - i_code_review_user_approval_rule_deleted
- - i_code_review_user_approval_rule_edited
- - i_code_review_user_vs_code_api_request
- - i_code_review_user_create_mr_from_issue
- - i_code_review_user_mr_discussion_locked
- - i_code_review_user_mr_discussion_unlocked
- - i_code_review_user_time_estimate_changed
- - i_code_review_user_time_spent_changed
- - i_code_review_user_assignees_changed
- - i_code_review_user_reviewers_changed
- - i_code_review_user_milestone_changed
- - i_code_review_user_labels_changed
- - i_code_review_click_diff_view_setting
- - i_code_review_click_single_file_mode_setting
- - i_code_review_click_file_browser_setting
- - i_code_review_click_whitespace_setting
- - i_code_review_diff_view_inline
- - i_code_review_diff_view_parallel
- - i_code_review_file_browser_tree_view
- - i_code_review_file_browser_list_view
- - i_code_review_diff_show_whitespace
- - i_code_review_diff_hide_whitespace
- - i_code_review_diff_single_file
- - i_code_review_diff_multiple_files
- - i_code_review_user_load_conflict_ui
- - i_code_review_user_resolve_conflict
- - i_code_review_user_searches_diff
+ - i_code_review_mr_diffs
+ - i_code_review_user_single_file_diffs
+ - i_code_review_mr_single_file_diffs
+ - i_code_review_user_toggled_task_item_status
+ - i_code_review_user_create_mr
+ - i_code_review_user_close_mr
+ - i_code_review_user_reopen_mr
+ - i_code_review_user_approve_mr
+ - i_code_review_user_unapprove_mr
+ - i_code_review_user_resolve_thread
+ - i_code_review_user_unresolve_thread
+ - i_code_review_edit_mr_title
+ - i_code_review_edit_mr_desc
+ - i_code_review_user_merge_mr
+ - i_code_review_user_create_mr_comment
+ - i_code_review_user_edit_mr_comment
+ - i_code_review_user_remove_mr_comment
+ - i_code_review_user_create_review_note
+ - i_code_review_user_publish_review
+ - i_code_review_user_create_multiline_mr_comment
+ - i_code_review_user_edit_multiline_mr_comment
+ - i_code_review_user_remove_multiline_mr_comment
+ - i_code_review_user_add_suggestion
+ - i_code_review_user_apply_suggestion
+ - i_code_review_user_assigned
+ - i_code_review_user_marked_as_draft
+ - i_code_review_user_unmarked_as_draft
+ - i_code_review_user_review_requested
+ - i_code_review_user_approval_rule_added
+ - i_code_review_user_approval_rule_deleted
+ - i_code_review_user_approval_rule_edited
+ - i_code_review_user_vs_code_api_request
+ - i_code_review_user_create_mr_from_issue
+ - i_code_review_user_mr_discussion_locked
+ - i_code_review_user_mr_discussion_unlocked
+ - i_code_review_user_time_estimate_changed
+ - i_code_review_user_time_spent_changed
+ - i_code_review_user_assignees_changed
+ - i_code_review_user_reviewers_changed
+ - i_code_review_user_milestone_changed
+ - i_code_review_user_labels_changed
+ - i_code_review_click_diff_view_setting
+ - i_code_review_click_single_file_mode_setting
+ - i_code_review_click_file_browser_setting
+ - i_code_review_click_whitespace_setting
+ - i_code_review_diff_view_inline
+ - i_code_review_diff_view_parallel
+ - i_code_review_file_browser_tree_view
+ - i_code_review_file_browser_list_view
+ - i_code_review_diff_show_whitespace
+ - i_code_review_diff_hide_whitespace
+ - i_code_review_diff_single_file
+ - i_code_review_diff_multiple_files
+ - i_code_review_user_load_conflict_ui
+ - i_code_review_user_resolve_conflict
+ - i_code_review_user_searches_diff
distribution:
- ce
- ee
@@ -76,3 +76,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184456_p_ci_templates_implicit_auto_devops_weekly.yml b/config/metrics/counts_7d/20210216184456_p_ci_templates_implicit_auto_devops_weekly.yml
new file mode 100644
index 00000000000..a6db13c8904
--- /dev/null
+++ b/config/metrics/counts_7d/20210216184456_p_ci_templates_implicit_auto_devops_weekly.yml
@@ -0,0 +1,25 @@
+---
+data_category: optional
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_auto_devops_weekly
+description: Count of pipelines with implicit Auto Build runs
+product_section: ops
+product_stage: configure
+product_group: group::configure
+product_category: infrastructure_as_code
+value_type: number
+status: active
+time_frame: 7d
+data_source: redis_hll
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - p_ci_templates_implicit_auto_devops
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184500_p_ci_templates_implicit_auto_devops_build_weekly.yml b/config/metrics/counts_7d/20210216184500_p_ci_templates_implicit_auto_devops_build_weekly.yml
new file mode 100644
index 00000000000..fbfb93ded5a
--- /dev/null
+++ b/config/metrics/counts_7d/20210216184500_p_ci_templates_implicit_auto_devops_build_weekly.yml
@@ -0,0 +1,25 @@
+---
+data_category: optional
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_auto_devops_build_weekly
+description: Count of pipelines with implicit Auto Build runs
+product_section: ops
+product_stage: configure
+product_group: group::configure
+product_category: infrastructure_as_code
+value_type: number
+status: active
+time_frame: 7d
+data_source: redis_hll
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - p_ci_templates_implicit_auto_devops_build
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184504_p_ci_templates_implicit_auto_devops_deploy_weekly.yml b/config/metrics/counts_7d/20210216184504_p_ci_templates_implicit_auto_devops_deploy_weekly.yml
new file mode 100644
index 00000000000..0b05e776c70
--- /dev/null
+++ b/config/metrics/counts_7d/20210216184504_p_ci_templates_implicit_auto_devops_deploy_weekly.yml
@@ -0,0 +1,25 @@
+---
+data_category: optional
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_auto_devops_deploy_weekly
+description: Count of pipelines with implicit Auto Deploy runs
+product_section: ops
+product_stage: configure
+product_group: group::configure
+product_category: infrastructure_as_code
+value_type: number
+status: active
+time_frame: 7d
+data_source: redis_hll
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - p_ci_templates_implicit_auto_devops_deploy
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184508_p_ci_templates_implicit_security_sast_weekly.yml b/config/metrics/counts_7d/20210216184508_p_ci_templates_implicit_security_sast_weekly.yml
new file mode 100644
index 00000000000..2a70231dcac
--- /dev/null
+++ b/config/metrics/counts_7d/20210216184508_p_ci_templates_implicit_security_sast_weekly.yml
@@ -0,0 +1,26 @@
+---
+data_category: optional
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_sast_weekly
+description: Count of pipelines with implicit SAST runs
+product_section: ops
+product_stage: verify
+product_group: "group::static analysis"
+product_category: SAST
+value_type: number
+status: active
+time_frame: 7d
+data_source: redis_hll
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - p_ci_templates_implicit_security_sast
+distribution:
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184512_p_ci_templates_implicit_security_secret_detection_weekly.yml b/config/metrics/counts_7d/20210216184512_p_ci_templates_implicit_security_secret_detection_weekly.yml
new file mode 100644
index 00000000000..c7673adedfd
--- /dev/null
+++ b/config/metrics/counts_7d/20210216184512_p_ci_templates_implicit_security_secret_detection_weekly.yml
@@ -0,0 +1,25 @@
+---
+data_category: optional
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_secret_detection_weekly
+description: Count of pipelines with implicit Secret Detection runs
+product_section: ops
+product_stage: verify
+product_group: "group::static analysis"
+product_category: secret_detection
+value_type: number
+status: active
+time_frame: 7d
+data_source: redis_hll
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - p_ci_templates_implicit_security_secret_detection
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184515_p_ci_templates_5_min_production_app_weekly.yml b/config/metrics/counts_7d/20210216184515_p_ci_templates_5_min_production_app_weekly.yml
index 01155a1c0e0..45fe5e380f5 100644
--- a/config/metrics/counts_7d/20210216184515_p_ci_templates_5_min_production_app_weekly.yml
+++ b/config/metrics/counts_7d/20210216184515_p_ci_templates_5_min_production_app_weekly.yml
@@ -4,16 +4,16 @@ key_path: redis_hll_counters.ci_templates.p_ci_templates_5_min_production_app_we
description: Number of projects using 5 min production app CI template in last 7 days.
product_section: seg
product_stage: deploy
-product_group: "group::5-min-app"
+product_group: group::5-min-app
product_category: five_minute_production_app
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_ci_templates_5_min_production_app
+ - p_ci_templates_5_min_production_app
distribution:
- ce
- ee
@@ -21,4 +21,4 @@ tier:
- free
- premium
- ultimate
-
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184520_p_ci_templates_auto_devops_weekly.yml b/config/metrics/counts_7d/20210216184520_p_ci_templates_auto_devops_weekly.yml
new file mode 100644
index 00000000000..606fed4b823
--- /dev/null
+++ b/config/metrics/counts_7d/20210216184520_p_ci_templates_auto_devops_weekly.yml
@@ -0,0 +1,25 @@
+---
+data_category: optional
+key_path: redis_hll_counters.ci_templates.p_ci_templates_auto_devops_weekly
+description: Count of pipelines using the latest Auto Deploy template
+product_section: ops
+product_stage: configure
+product_group: group::configure
+product_category: infrastructure_as_code
+value_type: number
+status: active
+time_frame: 7d
+data_source: redis_hll
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - p_ci_templates_auto_devops
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184524_p_ci_templates_aws_cf_deploy_ec2_weekly.yml b/config/metrics/counts_7d/20210216184524_p_ci_templates_aws_cf_deploy_ec2_weekly.yml
index 822006bc84d..adc12342146 100644
--- a/config/metrics/counts_7d/20210216184524_p_ci_templates_aws_cf_deploy_ec2_weekly.yml
+++ b/config/metrics/counts_7d/20210216184524_p_ci_templates_aws_cf_deploy_ec2_weekly.yml
@@ -1,19 +1,20 @@
---
data_category: optional
key_path: redis_hll_counters.ci_templates.p_ci_templates_aws_cf_deploy_ec2_weekly
-description: "Count of projects using `AWS/CF-Provision-and-Deploy-EC2.gitlab-ci.yml` template in last 7 days."
+description: Count of projects using `AWS/CF-Provision-and-Deploy-EC2.gitlab-ci.yml`
+ template in last 7 days.
product_section: ops
product_stage: release
-product_group: "group::release"
+product_group: group::release
product_category: continuous_delivery
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_ci_templates_aws_cf_deploy_ec2
+ - p_ci_templates_aws_cf_deploy_ec2
distribution:
- ce
- ee
@@ -21,3 +22,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184528_p_ci_templates_aws_deploy_ecs_weekly.yml b/config/metrics/counts_7d/20210216184528_p_ci_templates_aws_deploy_ecs_weekly.yml
index 5c027842d63..f5e03b1fbcb 100644
--- a/config/metrics/counts_7d/20210216184528_p_ci_templates_aws_deploy_ecs_weekly.yml
+++ b/config/metrics/counts_7d/20210216184528_p_ci_templates_aws_deploy_ecs_weekly.yml
@@ -1,19 +1,20 @@
---
data_category: optional
key_path: redis_hll_counters.ci_templates.p_ci_templates_aws_deploy_ecs_weekly
-description: "Count of projects using `AWS/Deploy-ECS.gitlab-ci.yml` template in last 7 days."
+description: Count of projects using `AWS/Deploy-ECS.gitlab-ci.yml` template in last
+ 7 days.
product_section: ops
product_stage: release
-product_group: "group::release"
+product_group: group::release
product_category: continuous_delivery
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_ci_templates_aws_deploy_ecs
+ - p_ci_templates_aws_deploy_ecs
distribution:
- ce
- ee
@@ -21,3 +22,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184536_p_ci_templates_auto_devops_deploy_weekly.yml b/config/metrics/counts_7d/20210216184536_p_ci_templates_auto_devops_deploy_weekly.yml
new file mode 100644
index 00000000000..b01a0288228
--- /dev/null
+++ b/config/metrics/counts_7d/20210216184536_p_ci_templates_auto_devops_deploy_weekly.yml
@@ -0,0 +1,27 @@
+---
+data_category: optional
+key_path: redis_hll_counters.ci_templates.p_ci_templates_auto_devops_deploy_weekly
+description: Count of pipelines using the stable Auto Deploy template
+product_section: ops
+product_stage: configure
+product_group: group::configure
+product_category: infrastructure_as_code
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - p_ci_templates_auto_devops_deploy
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184540_p_ci_templates_auto_devops_deploy_latest_weekly.yml b/config/metrics/counts_7d/20210216184540_p_ci_templates_auto_devops_deploy_latest_weekly.yml
new file mode 100644
index 00000000000..59f9f25aa06
--- /dev/null
+++ b/config/metrics/counts_7d/20210216184540_p_ci_templates_auto_devops_deploy_latest_weekly.yml
@@ -0,0 +1,25 @@
+---
+data_category: optional
+key_path: redis_hll_counters.ci_templates.p_ci_templates_auto_devops_deploy_latest_weekly
+description: Count of pipelines using the latest Auto Deploy template
+product_section: ops
+product_stage: configure
+product_group: group::configure
+product_category: infrastructure_as_code
+value_type: number
+status: active
+time_frame: 7d
+data_source: redis_hll
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - p_ci_templates_auto_devops_deploy_latest
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184544_p_ci_templates_security_sast_weekly.yml b/config/metrics/counts_7d/20210216184544_p_ci_templates_security_sast_weekly.yml
new file mode 100644
index 00000000000..07fa0b9ca40
--- /dev/null
+++ b/config/metrics/counts_7d/20210216184544_p_ci_templates_security_sast_weekly.yml
@@ -0,0 +1,25 @@
+---
+data_category: optional
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_sast_weekly
+description: Count of pipelines with SAST runs
+product_section: ops
+product_stage: verify
+product_group: "group::static analysis"
+product_category: SAST
+value_type: number
+status: active
+time_frame: 7d
+data_source: redis_hll
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - p_ci_templates_security_sast
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184549_p_ci_templates_security_secret_detection_weekly.yml b/config/metrics/counts_7d/20210216184549_p_ci_templates_security_secret_detection_weekly.yml
new file mode 100644
index 00000000000..d73981915e1
--- /dev/null
+++ b/config/metrics/counts_7d/20210216184549_p_ci_templates_security_secret_detection_weekly.yml
@@ -0,0 +1,25 @@
+---
+data_category: optional
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_secret_detection_weekly
+description: Count of pipelines with Secret Detection runs
+product_section: ops
+product_stage: verify
+product_group: "group::static analysis"
+product_category: secret_detection
+value_type: number
+status: active
+time_frame: 7d
+data_source: redis_hll
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - p_ci_templates_security_secret_detection
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184553_p_ci_templates_terraform_base_latest_weekly.yml b/config/metrics/counts_7d/20210216184553_p_ci_templates_terraform_base_latest_weekly.yml
new file mode 100644
index 00000000000..d17d8c10e55
--- /dev/null
+++ b/config/metrics/counts_7d/20210216184553_p_ci_templates_terraform_base_latest_weekly.yml
@@ -0,0 +1,25 @@
+---
+data_category: optional
+key_path: redis_hll_counters.ci_templates.p_ci_templates_terraform_base_latest_weekly
+description: Count of pipelines that include the terraform base template from GitLab
+product_section: ops
+product_stage: configure
+product_group: group::configure
+product_category: infrastructure_as_code
+value_type: number
+status: active
+time_frame: 7d
+data_source: redis_hll
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - p_ci_templates_terraform_base_latest
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184557_ci_templates_total_unique_counts_weekly.yml b/config/metrics/counts_7d/20210216184557_ci_templates_total_unique_counts_weekly.yml
index 9edb43b3aee..cf0e69c6da2 100644
--- a/config/metrics/counts_7d/20210216184557_ci_templates_total_unique_counts_weekly.yml
+++ b/config/metrics/counts_7d/20210216184557_ci_templates_total_unique_counts_weekly.yml
@@ -7,28 +7,158 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: broken
+status: removed
+milestone_removed: '14.3'
repair_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/332466
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - p_ci_templates_implicit_auto_devops
- - p_ci_templates_implicit_auto_devops_build
- - p_ci_templates_implicit_auto_devops_deploy
- - p_ci_templates_implicit_security_sast
- - p_ci_templates_implicit_security_secret_detection
- - p_ci_templates_5_min_production_app
- - p_ci_templates_auto_devops
- - p_ci_templates_aws_cf_deploy_ec2
- - p_ci_templates_aws_deploy_ecs
- - p_ci_templates_auto_devops_build
- - p_ci_templates_auto_devops_deploy
- - p_ci_templates_auto_devops_deploy_latest
- - p_ci_templates_security_sast
- - p_ci_templates_security_secret_detection
- - p_ci_templates_terraform_base_latest
+ - p_ci_templates_implicit_auto_devops
+ - p_ci_templates_5_min_production_app
+ - p_ci_templates_aws_cf_deploy_ec2
+ - p_ci_templates_auto_devops_build
+ - p_ci_templates_auto_devops_deploy
+ - p_ci_templates_auto_devops_deploy_latest
+ - p_ci_templates_terraform_base_latest
+ - p_ci_templates_terraform_base
+ - p_ci_templates_dotnet
+ - p_ci_templates_nodejs
+ - p_ci_templates_openshift
+ - p_ci_templates_auto_devops
+ - p_ci_templates_bash
+ - p_ci_templates_rust
+ - p_ci_templates_elixir
+ - p_ci_templates_clojure
+ - p_ci_templates_crystal
+ - p_ci_templates_getting_started
+ - p_ci_templates_code_quality
+ - p_ci_templates_verify_load_performance_testing
+ - p_ci_templates_verify_accessibility
+ - p_ci_templates_verify_failfast
+ - p_ci_templates_verify_browser_performance
+ - p_ci_templates_verify_browser_performance_latest
+ - p_ci_templates_grails
+ - p_ci_templates_security_sast
+ - p_ci_templates_security_dast_runner_validation
+ - p_ci_templates_security_dast_on_demand_scan
+ - p_ci_templates_security_secret_detection
+ - p_ci_templates_security_license_scanning
+ - p_ci_templates_security_coverage_fuzzing
+ - p_ci_templates_security_api_fuzzing_latest
+ - p_ci_templates_security_secure_binaries
+ - p_ci_templates_security_dast_api
+ - p_ci_templates_security_container_scanning
+ - p_ci_templates_security_dast_latest
+ - p_ci_templates_security_dependency_scanning
+ - p_ci_templates_security_api_fuzzing
+ - p_ci_templates_security_dast
+ - p_ci_templates_security_cluster_image_scanning
+ - p_ci_templates_ios_fastlane
+ - p_ci_templates_composer
+ - p_ci_templates_c
+ - p_ci_templates_python
+ - p_ci_templates_django
+ - p_ci_templates_maven
+ - p_ci_templates_flutter
+ - p_ci_templates_workflows_branch_pipelines
+ - p_ci_templates_workflows_mergerequest_pipelines
+ - p_ci_templates_laravel
+ - p_ci_templates_managed_cluster_applications
+ - p_ci_templates_php
+ - p_ci_templates_packer
+ - p_ci_templates_terraform
+ - p_ci_templates_mono
+ - p_ci_templates_serverless
+ - p_ci_templates_go
+ - p_ci_templates_scala
+ - p_ci_templates_latex
+ - p_ci_templates_android
+ - p_ci_templates_android_fastlane
+ - p_ci_templates_android_latest
+ - p_ci_templates_indeni_cloudrail
+ - p_ci_templates_deploy_ecs
+ - p_ci_templates_aws_cf_provision_and_deploy_ec2
+ - p_ci_templates_aws_deploy_ecs
+ - p_ci_templates_gradle
+ - p_ci_templates_chef
+ - p_ci_templates_jobs_dast_default_branch_deploy
+ - p_ci_templates_jobs_load_performance_testing
+ - p_ci_templates_jobs_helm_2to3
+ - p_ci_templates_jobs_sast
+ - p_ci_templates_jobs_secret_detection
+ - p_ci_templates_jobs_code_intelligence
+ - p_ci_templates_jobs_code_quality
+ - p_ci_templates_jobs_deploy_ecs
+ - p_ci_templates_jobs_deploy_ec2
+ - p_ci_templates_jobs_deploy
+ - p_ci_templates_jobs_build
+ - p_ci_templates_jobs_browser_performance_testing
+ - p_ci_templates_jobs_test
+ - p_ci_templates_jobs_deploy_latest
+ - p_ci_templates_jobs_browser_performance_testing_latest
+ - p_ci_templates_jobs_cf_provision
+ - p_ci_templates_jobs_build_latest
+ - p_ci_templates_terraform_latest
+ - p_ci_templates_swift
+ - p_ci_templates_pages_jekyll
+ - p_ci_templates_pages_harp
+ - p_ci_templates_pages_octopress
+ - p_ci_templates_pages_brunch
+ - p_ci_templates_pages_doxygen
+ - p_ci_templates_pages_hyde
+ - p_ci_templates_pages_lektor
+ - p_ci_templates_pages_jbake
+ - p_ci_templates_pages_hexo
+ - p_ci_templates_pages_middleman
+ - p_ci_templates_pages_hugo
+ - p_ci_templates_pages_pelican
+ - p_ci_templates_pages_nanoc
+ - p_ci_templates_pages_swaggerui
+ - p_ci_templates_pages_jigsaw
+ - p_ci_templates_pages_metalsmith
+ - p_ci_templates_pages_gatsby
+ - p_ci_templates_pages_html
+ - p_ci_templates_dart
+ - p_ci_templates_docker
+ - p_ci_templates_julia
+ - p_ci_templates_npm
+ - p_ci_templates_dotnet_core
+ - p_ci_templates_5_minute_production_app
+ - p_ci_templates_ruby
+ - p_ci_templates_implicit_jobs_dast_default_branch_deploy
+ - p_ci_templates_implicit_jobs_load_performance_testing
+ - p_ci_templates_implicit_jobs_helm_2to3
+ - p_ci_templates_implicit_jobs_sast
+ - p_ci_templates_implicit_jobs_secret_detection
+ - p_ci_templates_implicit_jobs_code_intelligence
+ - p_ci_templates_implicit_jobs_code_quality
+ - p_ci_templates_implicit_jobs_deploy_ecs
+ - p_ci_templates_implicit_jobs_deploy_ec2
+ - p_ci_templates_implicit_auto_devops_deploy
+ - p_ci_templates_implicit_auto_devops_build
+ - p_ci_templates_implicit_jobs_browser_performance_testing
+ - p_ci_templates_implicit_jobs_test
+ - p_ci_templates_implicit_auto_devops_deploy_latest
+ - p_ci_templates_implicit_jobs_browser_performance_testing_latest
+ - p_ci_templates_implicit_jobs_cf_provision
+ - p_ci_templates_implicit_jobs_build_latest
+ - p_ci_templates_implicit_security_sast
+ - p_ci_templates_implicit_security_dast_runner_validation
+ - p_ci_templates_implicit_security_dast_on_demand_scan
+ - p_ci_templates_implicit_security_secret_detection
+ - p_ci_templates_implicit_security_license_scanning
+ - p_ci_templates_implicit_security_coverage_fuzzing
+ - p_ci_templates_implicit_security_api_fuzzing_latest
+ - p_ci_templates_implicit_security_secure_binaries
+ - p_ci_templates_implicit_security_dast_api
+ - p_ci_templates_implicit_security_container_scanning
+ - p_ci_templates_implicit_security_dast_latest
+ - p_ci_templates_implicit_security_dependency_scanning
+ - p_ci_templates_implicit_security_api_fuzzing
+ - p_ci_templates_implicit_security_dast
+ - p_ci_templates_implicit_security_cluster_image_scanning
distribution:
- ce
- ee
@@ -37,3 +167,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184801_quickactions_total_unique_counts_weekly.yml b/config/metrics/counts_7d/20210216184801_quickactions_total_unique_counts_weekly.yml
new file mode 100644
index 00000000000..e4826e6575c
--- /dev/null
+++ b/config/metrics/counts_7d/20210216184801_quickactions_total_unique_counts_weekly.yml
@@ -0,0 +1,92 @@
+---
+data_category: optional
+key_path: redis_hll_counters.quickactions.quickactions_total_unique_counts_weekly
+description: Count of WAU using one or more quick actions
+product_section: dev
+product_stage: plan
+product_group: group::project management
+product_category: issue_tracking
+value_type: number
+status: active
+time_frame: 7d
+data_source: redis_hll
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - i_quickactions_approve
+ - i_quickactions_assign_single
+ - i_quickactions_assign_multiple
+ - i_quickactions_assign_self
+ - i_quickactions_assign_reviewer
+ - i_quickactions_award
+ - i_quickactions_board_move
+ - i_quickactions_child_epic
+ - i_quickactions_clear_weight
+ - i_quickactions_clone
+ - i_quickactions_close
+ - i_quickactions_confidential
+ - i_quickactions_copy_metadata_merge_request
+ - i_quickactions_copy_metadata_issue
+ - i_quickactions_create_merge_request
+ - i_quickactions_done
+ - i_quickactions_draft
+ - i_quickactions_due
+ - i_quickactions_duplicate
+ - i_quickactions_epic
+ - i_quickactions_estimate
+ - i_quickactions_iteration
+ - i_quickactions_label
+ - i_quickactions_lock
+ - i_quickactions_merge
+ - i_quickactions_milestone
+ - i_quickactions_move
+ - i_quickactions_parent_epic
+ - i_quickactions_promote
+ - i_quickactions_publish
+ - i_quickactions_reassign
+ - i_quickactions_reassign_reviewer
+ - i_quickactions_rebase
+ - i_quickactions_relabel
+ - i_quickactions_relate
+ - i_quickactions_remove_child_epic
+ - i_quickactions_remove_due_date
+ - i_quickactions_remove_epic
+ - i_quickactions_remove_estimate
+ - i_quickactions_remove_iteration
+ - i_quickactions_remove_milestone
+ - i_quickactions_remove_parent_epic
+ - i_quickactions_remove_time_spent
+ - i_quickactions_remove_zoom
+ - i_quickactions_reopen
+ - i_quickactions_severity
+ - i_quickactions_shrug
+ - i_quickactions_spend_subtract
+ - i_quickactions_spend_add
+ - i_quickactions_submit_review
+ - i_quickactions_subscribe
+ - i_quickactions_tableflip
+ - i_quickactions_tag
+ - i_quickactions_target_branch
+ - i_quickactions_title
+ - i_quickactions_todo
+ - i_quickactions_unassign_specific
+ - i_quickactions_unassign_all
+ - i_quickactions_unassign_reviewer
+ - i_quickactions_unlabel_specific
+ - i_quickactions_unlabel_all
+ - i_quickactions_unlock
+ - i_quickactions_unsubscribe
+ - i_quickactions_weight
+ - i_quickactions_wip
+ - i_quickactions_zoom
+ - i_quickactions_invite_email_single
+ - i_quickactions_invite_email_multiple
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184805_i_package_composer_deploy_token_weekly.yml b/config/metrics/counts_7d/20210216184805_i_package_composer_deploy_token_weekly.yml
index 7d918a5a496..627138b5082 100644
--- a/config/metrics/counts_7d/20210216184805_i_package_composer_deploy_token_weekly.yml
+++ b/config/metrics/counts_7d/20210216184805_i_package_composer_deploy_token_weekly.yml
@@ -1,7 +1,8 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.i_package_composer_deploy_token_weekly
-description: A weekly count of Composer packages published to the registry using a deploy token
+description: A weekly count of Composer packages published to the registry using a
+ deploy token
product_section: ops
product_stage: package
product_group: group::package
@@ -13,7 +14,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_composer_deploy_token
+ - i_package_composer_deploy_token
distribution:
- ee
- ce
@@ -21,3 +22,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184808_i_package_conan_deploy_token_weekly.yml b/config/metrics/counts_7d/20210216184808_i_package_conan_deploy_token_weekly.yml
index 13e5875fc49..f2c52f8b08a 100644
--- a/config/metrics/counts_7d/20210216184808_i_package_conan_deploy_token_weekly.yml
+++ b/config/metrics/counts_7d/20210216184808_i_package_conan_deploy_token_weekly.yml
@@ -1,19 +1,20 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.i_package_conan_deploy_token_weekly
-description: A weekly count of Conan packages published to the registry using a deploy token
+description: A weekly count of Conan packages published to the registry using a deploy
+ token
product_section: ops
product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_conan_deploy_token
+ - i_package_conan_deploy_token
distribution:
- ee
- ce
@@ -21,3 +22,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184812_i_package_container_deploy_token_weekly.yml b/config/metrics/counts_7d/20210216184812_i_package_container_deploy_token_weekly.yml
index 1b930e244ed..9fc146d3c86 100644
--- a/config/metrics/counts_7d/20210216184812_i_package_container_deploy_token_weekly.yml
+++ b/config/metrics/counts_7d/20210216184812_i_package_container_deploy_token_weekly.yml
@@ -1,7 +1,8 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.i_package_container_deploy_token_weekly
-description: A weekly count of container images published to the registry using a deploy token
+description: A weekly count of container images published to the registry using a
+ deploy token
product_section: ops
product_stage: package
product_group: group::package
@@ -13,7 +14,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_container_deploy_token
+ - i_package_container_deploy_token
distribution:
- ee
- ce
@@ -21,3 +22,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184816_i_package_debian_deploy_token_weekly.yml b/config/metrics/counts_7d/20210216184816_i_package_debian_deploy_token_weekly.yml
index daf1268d021..40b86d27bca 100644
--- a/config/metrics/counts_7d/20210216184816_i_package_debian_deploy_token_weekly.yml
+++ b/config/metrics/counts_7d/20210216184816_i_package_debian_deploy_token_weekly.yml
@@ -1,7 +1,8 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.i_package_debian_deploy_token_weekly
-description: A weekly count of Debian packages published to the registry using a deploy token
+description: A weekly count of Debian packages published to the registry using a deploy
+ token
product_section: ops
product_stage: package
product_group: group::package
@@ -13,7 +14,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_debian_deploy_token
+ - i_package_debian_deploy_token
distribution:
- ee
- ce
@@ -21,3 +22,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184820_i_package_generic_deploy_token_weekly.yml b/config/metrics/counts_7d/20210216184820_i_package_generic_deploy_token_weekly.yml
index 82900f13262..02bc59f30d8 100644
--- a/config/metrics/counts_7d/20210216184820_i_package_generic_deploy_token_weekly.yml
+++ b/config/metrics/counts_7d/20210216184820_i_package_generic_deploy_token_weekly.yml
@@ -1,19 +1,20 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.i_package_generic_deploy_token_weekly
-description: A weekly count of generic packages published to the registry using a deploy token
+description: A weekly count of generic packages published to the registry using a
+ deploy token
product_section: ops
product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_generic_deploy_token
+ - i_package_generic_deploy_token
distribution:
- ee
- ce
@@ -21,3 +22,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184824_i_package_golang_deploy_token_weekly.yml b/config/metrics/counts_7d/20210216184824_i_package_golang_deploy_token_weekly.yml
index 73993965b14..59b1aef3cb6 100644
--- a/config/metrics/counts_7d/20210216184824_i_package_golang_deploy_token_weekly.yml
+++ b/config/metrics/counts_7d/20210216184824_i_package_golang_deploy_token_weekly.yml
@@ -1,7 +1,8 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.i_package_golang_deploy_token_weekly
-description: A weekly count of Go modules published to the registry using a deploy token
+description: A weekly count of Go modules published to the registry using a deploy
+ token
product_section: ops
product_stage: package
product_group: group::package
@@ -13,7 +14,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_golang_deploy_token
+ - i_package_golang_deploy_token
distribution:
- ee
- ce
@@ -21,3 +22,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184828_i_package_maven_deploy_token_weekly.yml b/config/metrics/counts_7d/20210216184828_i_package_maven_deploy_token_weekly.yml
index 33ccf6b94c2..e4edfff33a7 100644
--- a/config/metrics/counts_7d/20210216184828_i_package_maven_deploy_token_weekly.yml
+++ b/config/metrics/counts_7d/20210216184828_i_package_maven_deploy_token_weekly.yml
@@ -1,19 +1,20 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.i_package_maven_deploy_token_weekly
-description: A weekly count of Maven packages published to the registry using a deploy token
+description: A weekly count of Maven packages published to the registry using a deploy
+ token
product_section: ops
product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_maven_deploy_token
+ - i_package_maven_deploy_token
distribution:
- ee
- ce
@@ -22,3 +23,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184832_i_package_npm_deploy_token_weekly.yml b/config/metrics/counts_7d/20210216184832_i_package_npm_deploy_token_weekly.yml
index 295258be202..95e1f413b12 100644
--- a/config/metrics/counts_7d/20210216184832_i_package_npm_deploy_token_weekly.yml
+++ b/config/metrics/counts_7d/20210216184832_i_package_npm_deploy_token_weekly.yml
@@ -1,19 +1,20 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.i_package_npm_deploy_token_weekly
-description: A weekly count of npm packages published to the registry using a deploy token
+description: A weekly count of npm packages published to the registry using a deploy
+ token
product_section: ops
product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_npm_deploy_token
+ - i_package_npm_deploy_token
distribution:
- ee
- ce
@@ -22,3 +23,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184836_i_package_nuget_deploy_token_weekly.yml b/config/metrics/counts_7d/20210216184836_i_package_nuget_deploy_token_weekly.yml
index 849f1541c78..55d3a87db45 100644
--- a/config/metrics/counts_7d/20210216184836_i_package_nuget_deploy_token_weekly.yml
+++ b/config/metrics/counts_7d/20210216184836_i_package_nuget_deploy_token_weekly.yml
@@ -1,19 +1,20 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.i_package_nuget_deploy_token_weekly
-description: A weekly count of NuGet packages published to the registry using a deploy token
+description: A weekly count of NuGet packages published to the registry using a deploy
+ token
product_section: ops
product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_nuget_deploy_token
+ - i_package_nuget_deploy_token
distribution:
- ee
- ce
@@ -22,3 +23,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184840_i_package_pypi_deploy_token_weekly.yml b/config/metrics/counts_7d/20210216184840_i_package_pypi_deploy_token_weekly.yml
index 4e74098a20c..14c71a5ab70 100644
--- a/config/metrics/counts_7d/20210216184840_i_package_pypi_deploy_token_weekly.yml
+++ b/config/metrics/counts_7d/20210216184840_i_package_pypi_deploy_token_weekly.yml
@@ -1,19 +1,20 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.i_package_pypi_deploy_token_weekly
-description: A weekly count of Python packages published to the registry using a deploy token
+description: A weekly count of Python packages published to the registry using a deploy
+ token
product_section: ops
product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_pypi_deploy_token
+ - i_package_pypi_deploy_token
distribution:
- ee
- ce
@@ -22,3 +23,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184844_i_package_tag_deploy_token_weekly.yml b/config/metrics/counts_7d/20210216184844_i_package_tag_deploy_token_weekly.yml
index 35cb4ed18cd..e28f423b108 100644
--- a/config/metrics/counts_7d/20210216184844_i_package_tag_deploy_token_weekly.yml
+++ b/config/metrics/counts_7d/20210216184844_i_package_tag_deploy_token_weekly.yml
@@ -1,7 +1,8 @@
---
data_category: optional
key_path: redis_hll_counters.deploy_token_packages.i_package_tag_deploy_token_weekly
-description: A weekly count of users that have published a package tag to the registry using a deploy token
+description: A weekly count of users that have published a package tag to the registry
+ using a deploy token
product_section: ops
product_stage: package
product_group: group::package
@@ -13,7 +14,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_tag_deploy_token
+ - i_package_tag_deploy_token
distribution:
- ee
- ce
@@ -21,3 +22,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184848_deploy_token_packages_total_unique_counts_weekly.yml b/config/metrics/counts_7d/20210216184848_deploy_token_packages_total_unique_counts_weekly.yml
index 584e56510e9..4a90ff637d6 100644
--- a/config/metrics/counts_7d/20210216184848_deploy_token_packages_total_unique_counts_weekly.yml
+++ b/config/metrics/counts_7d/20210216184848_deploy_token_packages_total_unique_counts_weekly.yml
@@ -7,26 +7,26 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_composer_deploy_token
- - i_package_conan_deploy_token
- - i_package_container_deploy_token
- - i_package_debian_deploy_token
- - i_package_generic_deploy_token
- - i_package_golang_deploy_token
- - i_package_helm_deploy_token
- - i_package_maven_deploy_token
- - i_package_npm_deploy_token
- - i_package_nuget_deploy_token
- - i_package_pypi_deploy_token
- - i_package_rubygems_deploy_token
- - i_package_tag_deploy_token
- - i_package_terraform_module_deploy_token
+ - i_package_composer_deploy_token
+ - i_package_conan_deploy_token
+ - i_package_container_deploy_token
+ - i_package_debian_deploy_token
+ - i_package_generic_deploy_token
+ - i_package_golang_deploy_token
+ - i_package_helm_deploy_token
+ - i_package_maven_deploy_token
+ - i_package_npm_deploy_token
+ - i_package_nuget_deploy_token
+ - i_package_pypi_deploy_token
+ - i_package_rubygems_deploy_token
+ - i_package_tag_deploy_token
+ - i_package_terraform_module_deploy_token
distribution:
- ee
- ce
@@ -35,3 +35,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184852_i_package_composer_user_weekly.yml b/config/metrics/counts_7d/20210216184852_i_package_composer_user_weekly.yml
index 09514b747fa..8ffcc7acc57 100644
--- a/config/metrics/counts_7d/20210216184852_i_package_composer_user_weekly.yml
+++ b/config/metrics/counts_7d/20210216184852_i_package_composer_user_weekly.yml
@@ -1,19 +1,20 @@
---
data_category: optional
key_path: redis_hll_counters.user_packages.i_package_composer_user_weekly
-description: A weekly count of users that have published a Composer package to the registry
+description: A weekly count of users that have published a Composer package to the
+ registry
product_section: ops
product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_composer_user
+ - i_package_composer_user
distribution:
- ee
- ce
@@ -22,3 +23,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184856_i_package_conan_user_weekly.yml b/config/metrics/counts_7d/20210216184856_i_package_conan_user_weekly.yml
index 6038b6a7460..dbca15deac9 100644
--- a/config/metrics/counts_7d/20210216184856_i_package_conan_user_weekly.yml
+++ b/config/metrics/counts_7d/20210216184856_i_package_conan_user_weekly.yml
@@ -7,13 +7,13 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_conan_user
+ - i_package_conan_user
distribution:
- ee
- ce
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184900_i_package_container_user_weekly.yml b/config/metrics/counts_7d/20210216184900_i_package_container_user_weekly.yml
index 795982a8c63..313b9b9a68e 100644
--- a/config/metrics/counts_7d/20210216184900_i_package_container_user_weekly.yml
+++ b/config/metrics/counts_7d/20210216184900_i_package_container_user_weekly.yml
@@ -1,7 +1,8 @@
---
data_category: optional
key_path: redis_hll_counters.user_packages.i_package_container_user_weekly
-description: A weekly count of users that have published a container image to the registry
+description: A weekly count of users that have published a container image to the
+ registry
product_section: ops
product_stage: package
product_group: group::package
@@ -13,7 +14,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_container_user
+ - i_package_container_user
distribution:
- ee
- ce
@@ -21,3 +22,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184904_i_package_debian_user_weekly.yml b/config/metrics/counts_7d/20210216184904_i_package_debian_user_weekly.yml
index 9cc704c46fd..2d61d3fa992 100644
--- a/config/metrics/counts_7d/20210216184904_i_package_debian_user_weekly.yml
+++ b/config/metrics/counts_7d/20210216184904_i_package_debian_user_weekly.yml
@@ -13,7 +13,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_debian_user
+ - i_package_debian_user
distribution:
- ee
- ce
@@ -21,3 +21,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184908_i_package_generic_user_weekly.yml b/config/metrics/counts_7d/20210216184908_i_package_generic_user_weekly.yml
index 8e8198a5fcd..63278bcfbd8 100644
--- a/config/metrics/counts_7d/20210216184908_i_package_generic_user_weekly.yml
+++ b/config/metrics/counts_7d/20210216184908_i_package_generic_user_weekly.yml
@@ -1,7 +1,8 @@
---
data_category: optional
key_path: redis_hll_counters.user_packages.i_package_generic_user_weekly
-description: A weekly count of users that have published a generic package to the registry
+description: A weekly count of users that have published a generic package to the
+ registry
product_section: ops
product_stage: package
product_group: group::package
@@ -14,7 +15,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_generic_user
+ - i_package_generic_user
distribution:
- ee
- ce
@@ -22,3 +23,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184911_i_package_golang_user_weekly.yml b/config/metrics/counts_7d/20210216184911_i_package_golang_user_weekly.yml
index f331fccc178..1ccd4d89b5b 100644
--- a/config/metrics/counts_7d/20210216184911_i_package_golang_user_weekly.yml
+++ b/config/metrics/counts_7d/20210216184911_i_package_golang_user_weekly.yml
@@ -13,7 +13,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_golang_user
+ - i_package_golang_user
distribution:
- ee
- ce
@@ -21,3 +21,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184916_i_package_maven_user_weekly.yml b/config/metrics/counts_7d/20210216184916_i_package_maven_user_weekly.yml
index a79ce0401c5..170c03065e5 100644
--- a/config/metrics/counts_7d/20210216184916_i_package_maven_user_weekly.yml
+++ b/config/metrics/counts_7d/20210216184916_i_package_maven_user_weekly.yml
@@ -7,13 +7,13 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_maven_user
+ - i_package_maven_user
distribution:
- ee
- ce
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184919_i_package_npm_user_weekly.yml b/config/metrics/counts_7d/20210216184919_i_package_npm_user_weekly.yml
index 5eb7c85ad1b..6f340c74ae9 100644
--- a/config/metrics/counts_7d/20210216184919_i_package_npm_user_weekly.yml
+++ b/config/metrics/counts_7d/20210216184919_i_package_npm_user_weekly.yml
@@ -7,13 +7,13 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_npm_user
+ - i_package_npm_user
distribution:
- ee
- ce
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184923_i_package_nuget_user_weekly.yml b/config/metrics/counts_7d/20210216184923_i_package_nuget_user_weekly.yml
index e8ead65cf92..ff0c7edfe44 100644
--- a/config/metrics/counts_7d/20210216184923_i_package_nuget_user_weekly.yml
+++ b/config/metrics/counts_7d/20210216184923_i_package_nuget_user_weekly.yml
@@ -7,13 +7,13 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_nuget_user
+ - i_package_nuget_user
distribution:
- ee
- ce
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184927_i_package_pypi_user_weekly.yml b/config/metrics/counts_7d/20210216184927_i_package_pypi_user_weekly.yml
index 19d099eb677..9d227bf4d9e 100644
--- a/config/metrics/counts_7d/20210216184927_i_package_pypi_user_weekly.yml
+++ b/config/metrics/counts_7d/20210216184927_i_package_pypi_user_weekly.yml
@@ -7,13 +7,13 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_pypi_user
+ - i_package_pypi_user
distribution:
- ee
- ce
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184931_i_package_tag_user_weekly.yml b/config/metrics/counts_7d/20210216184931_i_package_tag_user_weekly.yml
index aa65fc12daa..5169e2d5519 100644
--- a/config/metrics/counts_7d/20210216184931_i_package_tag_user_weekly.yml
+++ b/config/metrics/counts_7d/20210216184931_i_package_tag_user_weekly.yml
@@ -1,7 +1,8 @@
---
data_category: optional
key_path: redis_hll_counters.user_packages.i_package_tag_user_weekly
-description: A weekly count of users that have published a package with a tag to the registry
+description: A weekly count of users that have published a package with a tag to the
+ registry
product_section: ops
product_stage: package
product_group: group::package
@@ -13,7 +14,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_tag_user
+ - i_package_tag_user
distribution:
- ee
- ce
@@ -21,3 +22,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184935_user_packages_total_unique_counts_weekly.yml b/config/metrics/counts_7d/20210216184935_user_packages_total_unique_counts_weekly.yml
index d7e35fb52eb..1bd4181f952 100644
--- a/config/metrics/counts_7d/20210216184935_user_packages_total_unique_counts_weekly.yml
+++ b/config/metrics/counts_7d/20210216184935_user_packages_total_unique_counts_weekly.yml
@@ -7,26 +7,26 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_package_composer_user
- - i_package_conan_user
- - i_package_container_user
- - i_package_debian_user
- - i_package_generic_user
- - i_package_golang_user
- - i_package_helm_user
- - i_package_maven_user
- - i_package_npm_user
- - i_package_nuget_user
- - i_package_pypi_user
- - i_package_rubygems_user
- - i_package_tag_user
- - i_package_terraform_module_user
+ - i_package_composer_user
+ - i_package_conan_user
+ - i_package_container_user
+ - i_package_debian_user
+ - i_package_generic_user
+ - i_package_golang_user
+ - i_package_helm_user
+ - i_package_maven_user
+ - i_package_npm_user
+ - i_package_nuget_user
+ - i_package_pypi_user
+ - i_package_rubygems_user
+ - i_package_tag_user
+ - i_package_terraform_module_user
distribution:
- ee
- ce
@@ -35,3 +35,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184939_i_ecosystem_jira_service_close_issue_weekly.yml b/config/metrics/counts_7d/20210216184939_i_ecosystem_jira_service_close_issue_weekly.yml
index 45b42df9a58..33004c0a8a8 100644
--- a/config/metrics/counts_7d/20210216184939_i_ecosystem_jira_service_close_issue_weekly.yml
+++ b/config/metrics/counts_7d/20210216184939_i_ecosystem_jira_service_close_issue_weekly.yml
@@ -7,13 +7,13 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_ecosystem_jira_service_close_issue
+ - i_ecosystem_jira_service_close_issue
distribution:
- ce
- ee
@@ -21,3 +21,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184943_i_ecosystem_jira_service_cross_reference_weekly.yml b/config/metrics/counts_7d/20210216184943_i_ecosystem_jira_service_cross_reference_weekly.yml
index bcd142629ec..193fe8cef3a 100644
--- a/config/metrics/counts_7d/20210216184943_i_ecosystem_jira_service_cross_reference_weekly.yml
+++ b/config/metrics/counts_7d/20210216184943_i_ecosystem_jira_service_cross_reference_weekly.yml
@@ -7,13 +7,13 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_ecosystem_jira_service_cross_reference
+ - i_ecosystem_jira_service_cross_reference
distribution:
- ce
- ee
@@ -21,3 +21,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210216184955_ecosystem_total_unique_counts_weekly.yml b/config/metrics/counts_7d/20210216184955_ecosystem_total_unique_counts_weekly.yml
index 109e4b0ac0a..6f1332ca69e 100644
--- a/config/metrics/counts_7d/20210216184955_ecosystem_total_unique_counts_weekly.yml
+++ b/config/metrics/counts_7d/20210216184955_ecosystem_total_unique_counts_weekly.yml
@@ -7,25 +7,25 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- - i_ecosystem_jira_service_close_issue
- - i_ecosystem_jira_service_cross_reference
- - i_ecosystem_jira_service_list_issues
- - i_ecosystem_jira_service_create_issue
- - i_ecosystem_slack_service_issue_notification
- - i_ecosystem_slack_service_push_notification
- - i_ecosystem_slack_service_deployment_notification
- - i_ecosystem_slack_service_wiki_page_notification
- - i_ecosystem_slack_service_merge_request_notification
- - i_ecosystem_slack_service_note_notification
- - i_ecosystem_slack_service_tag_push_notification
- - i_ecosystem_slack_service_confidential_note_notification
- - i_ecosystem_slack_service_confidential_issue_notification
+ - i_ecosystem_jira_service_close_issue
+ - i_ecosystem_jira_service_cross_reference
+ - i_ecosystem_jira_service_list_issues
+ - i_ecosystem_jira_service_create_issue
+ - i_ecosystem_slack_service_issue_notification
+ - i_ecosystem_slack_service_push_notification
+ - i_ecosystem_slack_service_deployment_notification
+ - i_ecosystem_slack_service_wiki_page_notification
+ - i_ecosystem_slack_service_merge_request_notification
+ - i_ecosystem_slack_service_note_notification
+ - i_ecosystem_slack_service_tag_push_notification
+ - i_ecosystem_slack_service_confidential_note_notification
+ - i_ecosystem_slack_service_confidential_issue_notification
distribution:
- ce
- ee
@@ -33,3 +33,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_7d/20210301144209_o_pipeline_authoring_unique_users_pushing_mr_ciconfigfile_weekly.yml b/config/metrics/counts_7d/20210301144209_o_pipeline_authoring_unique_users_pushing_mr_ciconfigfile_weekly.yml
index d5ae76cfb97..a9622709a20 100644
--- a/config/metrics/counts_7d/20210301144209_o_pipeline_authoring_unique_users_pushing_mr_ciconfigfile_weekly.yml
+++ b/config/metrics/counts_7d/20210301144209_o_pipeline_authoring_unique_users_pushing_mr_ciconfigfile_weekly.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline authoring
product_category: pipeline_authoring
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54707
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210302103002_i_ecosystem_slack_service_issue_notification_weekly.yml b/config/metrics/counts_7d/20210302103002_i_ecosystem_slack_service_issue_notification_weekly.yml
index 3049dc64068..343f01e8223 100644
--- a/config/metrics/counts_7d/20210302103002_i_ecosystem_slack_service_issue_notification_weekly.yml
+++ b/config/metrics/counts_7d/20210302103002_i_ecosystem_slack_service_issue_notification_weekly.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54347
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210302103539_i_code_review_user_time_estimate_changed_weekly.yml b/config/metrics/counts_7d/20210302103539_i_code_review_user_time_estimate_changed_weekly.yml
index 42817360fb6..ae24bce7880 100644
--- a/config/metrics/counts_7d/20210302103539_i_code_review_user_time_estimate_changed_weekly.yml
+++ b/config/metrics/counts_7d/20210302103539_i_code_review_user_time_estimate_changed_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55046
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210302103615_i_code_review_user_time_spent_changed_weekly.yml b/config/metrics/counts_7d/20210302103615_i_code_review_user_time_spent_changed_weekly.yml
index 6acc51a14ee..1f184726f6e 100644
--- a/config/metrics/counts_7d/20210302103615_i_code_review_user_time_spent_changed_weekly.yml
+++ b/config/metrics/counts_7d/20210302103615_i_code_review_user_time_spent_changed_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55046
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210302103629_i_ecosystem_slack_service_push_notification_weekly.yml b/config/metrics/counts_7d/20210302103629_i_ecosystem_slack_service_push_notification_weekly.yml
index 55cb6bcbcb2..7dc1fef5996 100644
--- a/config/metrics/counts_7d/20210302103629_i_ecosystem_slack_service_push_notification_weekly.yml
+++ b/config/metrics/counts_7d/20210302103629_i_ecosystem_slack_service_push_notification_weekly.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54347
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210302103755_i_ecosystem_slack_service_deployment_notification_weekly.yml b/config/metrics/counts_7d/20210302103755_i_ecosystem_slack_service_deployment_notification_weekly.yml
index 76c34c102b1..7c5df5c4d30 100644
--- a/config/metrics/counts_7d/20210302103755_i_ecosystem_slack_service_deployment_notification_weekly.yml
+++ b/config/metrics/counts_7d/20210302103755_i_ecosystem_slack_service_deployment_notification_weekly.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54347
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210302103907_i_ecosystem_slack_service_wiki_page_notification_weekly.yml b/config/metrics/counts_7d/20210302103907_i_ecosystem_slack_service_wiki_page_notification_weekly.yml
index 0a223b45493..1ff2ae4bfbe 100644
--- a/config/metrics/counts_7d/20210302103907_i_ecosystem_slack_service_wiki_page_notification_weekly.yml
+++ b/config/metrics/counts_7d/20210302103907_i_ecosystem_slack_service_wiki_page_notification_weekly.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54347
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210302104007_i_ecosystem_slack_service_merge_request_notification_weekly.yml b/config/metrics/counts_7d/20210302104007_i_ecosystem_slack_service_merge_request_notification_weekly.yml
index d7e05f2672a..0d5259cd109 100644
--- a/config/metrics/counts_7d/20210302104007_i_ecosystem_slack_service_merge_request_notification_weekly.yml
+++ b/config/metrics/counts_7d/20210302104007_i_ecosystem_slack_service_merge_request_notification_weekly.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54347
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210302104047_i_ecosystem_slack_service_note_notification_weekly.yml b/config/metrics/counts_7d/20210302104047_i_ecosystem_slack_service_note_notification_weekly.yml
index 4ee7fc088d0..502633cf2e4 100644
--- a/config/metrics/counts_7d/20210302104047_i_ecosystem_slack_service_note_notification_weekly.yml
+++ b/config/metrics/counts_7d/20210302104047_i_ecosystem_slack_service_note_notification_weekly.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54347
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210302104144_i_ecosystem_slack_service_tag_push_notification_weekly.yml b/config/metrics/counts_7d/20210302104144_i_ecosystem_slack_service_tag_push_notification_weekly.yml
index 938ca77e933..462e3a936bd 100644
--- a/config/metrics/counts_7d/20210302104144_i_ecosystem_slack_service_tag_push_notification_weekly.yml
+++ b/config/metrics/counts_7d/20210302104144_i_ecosystem_slack_service_tag_push_notification_weekly.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54347
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210302104556_i_ecosystem_slack_service_confidential_note_notification_weekly.yml b/config/metrics/counts_7d/20210302104556_i_ecosystem_slack_service_confidential_note_notification_weekly.yml
index 1b8fb7a47e1..ed317741522 100644
--- a/config/metrics/counts_7d/20210302104556_i_ecosystem_slack_service_confidential_note_notification_weekly.yml
+++ b/config/metrics/counts_7d/20210302104556_i_ecosystem_slack_service_confidential_note_notification_weekly.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54347
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210302104814_i_ecosystem_slack_service_confidential_issue_notification_weekly.yml b/config/metrics/counts_7d/20210302104814_i_ecosystem_slack_service_confidential_issue_notification_weekly.yml
index 09fbb902bc7..7f3ec3d463e 100644
--- a/config/metrics/counts_7d/20210302104814_i_ecosystem_slack_service_confidential_issue_notification_weekly.yml
+++ b/config/metrics/counts_7d/20210302104814_i_ecosystem_slack_service_confidential_issue_notification_weekly.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54347
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210302105258_i_code_review_user_mr_discussion_unlocked_weekly.yml b/config/metrics/counts_7d/20210302105258_i_code_review_user_mr_discussion_unlocked_weekly.yml
index b3704a4232a..0ab35b83efb 100644
--- a/config/metrics/counts_7d/20210302105258_i_code_review_user_mr_discussion_unlocked_weekly.yml
+++ b/config/metrics/counts_7d/20210302105258_i_code_review_user_mr_discussion_unlocked_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55069
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210302105318_i_code_review_user_mr_discussion_locked_weekly.yml b/config/metrics/counts_7d/20210302105318_i_code_review_user_mr_discussion_locked_weekly.yml
index aaba247ea02..05850bd0ecf 100644
--- a/config/metrics/counts_7d/20210302105318_i_code_review_user_mr_discussion_locked_weekly.yml
+++ b/config/metrics/counts_7d/20210302105318_i_code_review_user_mr_discussion_locked_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55069
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210302110403_i_code_review_user_milestone_changed_weekly.yml b/config/metrics/counts_7d/20210302110403_i_code_review_user_milestone_changed_weekly.yml
index eed67a4cda6..d0becbb1f82 100644
--- a/config/metrics/counts_7d/20210302110403_i_code_review_user_milestone_changed_weekly.yml
+++ b/config/metrics/counts_7d/20210302110403_i_code_review_user_milestone_changed_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55484
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210302110548_i_code_review_user_labels_changed_weekly.yml b/config/metrics/counts_7d/20210302110548_i_code_review_user_labels_changed_weekly.yml
index b003c999c23..84102e9d620 100644
--- a/config/metrics/counts_7d/20210302110548_i_code_review_user_labels_changed_weekly.yml
+++ b/config/metrics/counts_7d/20210302110548_i_code_review_user_labels_changed_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55484
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210302114202_i_code_review_user_assignees_changed_weekly.yml b/config/metrics/counts_7d/20210302114202_i_code_review_user_assignees_changed_weekly.yml
index 57a1a8bf307..7be4524a57e 100644
--- a/config/metrics/counts_7d/20210302114202_i_code_review_user_assignees_changed_weekly.yml
+++ b/config/metrics/counts_7d/20210302114202_i_code_review_user_assignees_changed_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55486
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210302114235_i_code_review_user_reviewers_changed_weekly.yml b/config/metrics/counts_7d/20210302114235_i_code_review_user_reviewers_changed_weekly.yml
index bd792b7cb7b..9f7603e1669 100644
--- a/config/metrics/counts_7d/20210302114235_i_code_review_user_reviewers_changed_weekly.yml
+++ b/config/metrics/counts_7d/20210302114235_i_code_review_user_reviewers_changed_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55486
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210303154557_i_quickactions_invite_email_single_weekly.yml b/config/metrics/counts_7d/20210303154557_i_quickactions_invite_email_single_weekly.yml
index b0f1ceebbfd..6668773a8a1 100644
--- a/config/metrics/counts_7d/20210303154557_i_quickactions_invite_email_single_weekly.yml
+++ b/config/metrics/counts_7d/20210303154557_i_quickactions_invite_email_single_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::product planning
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49264
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210303154600_i_quickactions_invite_email_multiple_weekly.yml b/config/metrics/counts_7d/20210303154600_i_quickactions_invite_email_multiple_weekly.yml
index da29ef10c7f..4e395cbaa75 100644
--- a/config/metrics/counts_7d/20210303154600_i_quickactions_invite_email_multiple_weekly.yml
+++ b/config/metrics/counts_7d/20210303154600_i_quickactions_invite_email_multiple_weekly.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::product planning
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49264
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210303154624_i_package_rubygems_deploy_token_weekly.yml b/config/metrics/counts_7d/20210303154624_i_package_rubygems_deploy_token_weekly.yml
index c4218863207..dcbe3878463 100644
--- a/config/metrics/counts_7d/20210303154624_i_package_rubygems_deploy_token_weekly.yml
+++ b/config/metrics/counts_7d/20210303154624_i_package_rubygems_deploy_token_weekly.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package_registry
value_type: number
-status: data_available
+status: active
milestone: '13.10'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53480
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210303154652_i_package_rubygems_user_weekly.yml b/config/metrics/counts_7d/20210303154652_i_package_rubygems_user_weekly.yml
index 8d4027cd86e..e8871c1868e 100644
--- a/config/metrics/counts_7d/20210303154652_i_package_rubygems_user_weekly.yml
+++ b/config/metrics/counts_7d/20210303154652_i_package_rubygems_user_weekly.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package_registry
value_type: number
-status: data_available
+status: active
milestone: '13.10'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53480
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210409095855_users_expanding_secure_security_report_weekly.yml b/config/metrics/counts_7d/20210409095855_users_expanding_secure_security_report_weekly.yml
index c8ad3b64364..ebe67adad33 100644
--- a/config/metrics/counts_7d/20210409095855_users_expanding_secure_security_report_weekly.yml
+++ b/config/metrics/counts_7d/20210409095855_users_expanding_secure_security_report_weekly.yml
@@ -7,7 +7,7 @@ product_stage: secure
product_group: group::static analysis
product_category: dependency_scanning
value_type: number
-status: data_available
+status: active
milestone: '13.11'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57133
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210409100451_users_expanding_testing_code_quality_report_weekly.yml b/config/metrics/counts_7d/20210409100451_users_expanding_testing_code_quality_report_weekly.yml
index 278bd1691cd..e4f3d64e93c 100644
--- a/config/metrics/counts_7d/20210409100451_users_expanding_testing_code_quality_report_weekly.yml
+++ b/config/metrics/counts_7d/20210409100451_users_expanding_testing_code_quality_report_weekly.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::testing
product_category: code_quality
value_type: number
-status: data_available
+status: active
milestone: '13.11'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57133
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210409100628_users_expanding_testing_accessibility_report_weekly.yml b/config/metrics/counts_7d/20210409100628_users_expanding_testing_accessibility_report_weekly.yml
index 3cde67e9c1e..6a4d2184190 100644
--- a/config/metrics/counts_7d/20210409100628_users_expanding_testing_accessibility_report_weekly.yml
+++ b/config/metrics/counts_7d/20210409100628_users_expanding_testing_accessibility_report_weekly.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::testing
product_category: accessibility_testing
value_type: number
-status: data_available
+status: active
milestone: '13.11'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57133
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210410012207_i_package_terraform_module_deploy_token_weekly.yml b/config/metrics/counts_7d/20210410012207_i_package_terraform_module_deploy_token_weekly.yml
index d68d290e662..8325cb2620d 100644
--- a/config/metrics/counts_7d/20210410012207_i_package_terraform_module_deploy_token_weekly.yml
+++ b/config/metrics/counts_7d/20210410012207_i_package_terraform_module_deploy_token_weekly.yml
@@ -7,7 +7,7 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: data_available
+status: active
milestone: '13.11'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55018
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210410012209_i_package_terraform_module_user_weekly.yml b/config/metrics/counts_7d/20210410012209_i_package_terraform_module_user_weekly.yml
index f78f2276183..90a8a3bad22 100644
--- a/config/metrics/counts_7d/20210410012209_i_package_terraform_module_user_weekly.yml
+++ b/config/metrics/counts_7d/20210410012209_i_package_terraform_module_user_weekly.yml
@@ -7,7 +7,7 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: data_available
+status: active
milestone: '13.11'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55018
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210413205507_i_testing_summary_widget_total_weekly.yml b/config/metrics/counts_7d/20210413205507_i_testing_summary_widget_total_weekly.yml
index 96994ba0dc2..6adf4d0c092 100644
--- a/config/metrics/counts_7d/20210413205507_i_testing_summary_widget_total_weekly.yml
+++ b/config/metrics/counts_7d/20210413205507_i_testing_summary_widget_total_weekly.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::testing
product_category: testing
value_type: number
-status: data_available
+status: active
milestone: "13.11"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59316
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210421144349_i_code_review_click_single_file_mode_setting_weekly.yml b/config/metrics/counts_7d/20210421144349_i_code_review_click_single_file_mode_setting_weekly.yml
index ec3e664e464..027fd5d31d7 100644
--- a/config/metrics/counts_7d/20210421144349_i_code_review_click_single_file_mode_setting_weekly.yml
+++ b/config/metrics/counts_7d/20210421144349_i_code_review_click_single_file_mode_setting_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210421145814_i_code_review_click_file_browser_setting_weekly.yml b/config/metrics/counts_7d/20210421145814_i_code_review_click_file_browser_setting_weekly.yml
index eed8def8793..76a53ef1b37 100644
--- a/config/metrics/counts_7d/20210421145814_i_code_review_click_file_browser_setting_weekly.yml
+++ b/config/metrics/counts_7d/20210421145814_i_code_review_click_file_browser_setting_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210421145942_i_code_review_click_whitespace_setting_weekly.yml b/config/metrics/counts_7d/20210421145942_i_code_review_click_whitespace_setting_weekly.yml
index 354e2e01443..7d3f82bfbaf 100644
--- a/config/metrics/counts_7d/20210421145942_i_code_review_click_whitespace_setting_weekly.yml
+++ b/config/metrics/counts_7d/20210421145942_i_code_review_click_whitespace_setting_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210422101512_i_code_review_diff_view_inline_weekly.yml b/config/metrics/counts_7d/20210422101512_i_code_review_diff_view_inline_weekly.yml
index 4332d62b411..8e12608620d 100644
--- a/config/metrics/counts_7d/20210422101512_i_code_review_diff_view_inline_weekly.yml
+++ b/config/metrics/counts_7d/20210422101512_i_code_review_diff_view_inline_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210422101609_i_code_review_diff_view_parallel_weekly.yml b/config/metrics/counts_7d/20210422101609_i_code_review_diff_view_parallel_weekly.yml
index 21f757638d3..bcef87a890b 100644
--- a/config/metrics/counts_7d/20210422101609_i_code_review_diff_view_parallel_weekly.yml
+++ b/config/metrics/counts_7d/20210422101609_i_code_review_diff_view_parallel_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210422101750_i_code_review_file_browser_tree_view_weekly.yml b/config/metrics/counts_7d/20210422101750_i_code_review_file_browser_tree_view_weekly.yml
index 03d83daa800..1a2e4fcf83e 100644
--- a/config/metrics/counts_7d/20210422101750_i_code_review_file_browser_tree_view_weekly.yml
+++ b/config/metrics/counts_7d/20210422101750_i_code_review_file_browser_tree_view_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210422101849_i_code_review_file_browser_list_view_weekly.yml b/config/metrics/counts_7d/20210422101849_i_code_review_file_browser_list_view_weekly.yml
index ea6ce090c2f..813641cb82d 100644
--- a/config/metrics/counts_7d/20210422101849_i_code_review_file_browser_list_view_weekly.yml
+++ b/config/metrics/counts_7d/20210422101849_i_code_review_file_browser_list_view_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210422101925_i_code_review_diff_show_whitespace_weekly.yml b/config/metrics/counts_7d/20210422101925_i_code_review_diff_show_whitespace_weekly.yml
index 2042dc2bcca..f11db5ceacd 100644
--- a/config/metrics/counts_7d/20210422101925_i_code_review_diff_show_whitespace_weekly.yml
+++ b/config/metrics/counts_7d/20210422101925_i_code_review_diff_show_whitespace_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210422102007_i_code_review_diff_hide_whitespace_weekly.yml b/config/metrics/counts_7d/20210422102007_i_code_review_diff_hide_whitespace_weekly.yml
index 2104698319e..c2282fc9bc3 100644
--- a/config/metrics/counts_7d/20210422102007_i_code_review_diff_hide_whitespace_weekly.yml
+++ b/config/metrics/counts_7d/20210422102007_i_code_review_diff_hide_whitespace_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210422102118_i_code_review_diff_single_file_weekly.yml b/config/metrics/counts_7d/20210422102118_i_code_review_diff_single_file_weekly.yml
index 2e11afbf0c5..32318d1c4ff 100644
--- a/config/metrics/counts_7d/20210422102118_i_code_review_diff_single_file_weekly.yml
+++ b/config/metrics/counts_7d/20210422102118_i_code_review_diff_single_file_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210422102159_i_code_review_diff_multiple_files_weekly.yml b/config/metrics/counts_7d/20210422102159_i_code_review_diff_multiple_files_weekly.yml
index 99e470b7a9b..e83bd92cfd3 100644
--- a/config/metrics/counts_7d/20210422102159_i_code_review_diff_multiple_files_weekly.yml
+++ b/config/metrics/counts_7d/20210422102159_i_code_review_diff_multiple_files_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210427103328_code_review_group_monthly_active_users.yml b/config/metrics/counts_7d/20210427103328_code_review_group_monthly_active_users.yml
index 6a0eff41bf2..112e8655d37 100644
--- a/config/metrics/counts_7d/20210427103328_code_review_group_monthly_active_users.yml
+++ b/config/metrics/counts_7d/20210427103328_code_review_group_monthly_active_users.yml
@@ -1,18 +1,16 @@
---
data_category: optional
key_path: counts_weekly.aggregated_metrics.code_review_group_monthly_active_users
-name: "0"
-description:
-product_section:
-product_stage:
-product_group:
+description: Number of users performing at least one of the code review events
+product_section: dev
+product_stage: devops::create
+product_group: group::code review
product_category:
value_type: number
-status: data_available
+status: active
milestone: "13.12"
-introduced_by_url:
time_frame: 7d
-data_source:
+data_source: redis_hll
distribution:
- ce
- ee
@@ -20,4 +18,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
+
diff --git a/config/metrics/counts_7d/20210427103407_code_review_category_monthly_active_users.yml b/config/metrics/counts_7d/20210427103407_code_review_category_monthly_active_users.yml
index 88871232e78..8680e59f141 100644
--- a/config/metrics/counts_7d/20210427103407_code_review_category_monthly_active_users.yml
+++ b/config/metrics/counts_7d/20210427103407_code_review_category_monthly_active_users.yml
@@ -1,18 +1,17 @@
---
data_category: optional
key_path: counts_weekly.aggregated_metrics.code_review_category_monthly_active_users
-name: "0"
-description:
-product_section:
-product_stage:
-product_group:
+description: Unique users performing actions on code review events
+product_section: dev
+product_stage: devops::create
+product_group: group::code review
product_category:
value_type: number
-status: data_available
+status: active
milestone: "13.12"
-introduced_by_url:
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53553/
time_frame: 7d
-data_source:
+data_source: redis_hll
distribution:
- ce
- ee
@@ -20,4 +19,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
+
diff --git a/config/metrics/counts_7d/20210427103452_code_review_extension_category_monthly_active_users.yml b/config/metrics/counts_7d/20210427103452_code_review_extension_category_monthly_active_users.yml
index 5e6de879284..29e52e07a14 100644
--- a/config/metrics/counts_7d/20210427103452_code_review_extension_category_monthly_active_users.yml
+++ b/config/metrics/counts_7d/20210427103452_code_review_extension_category_monthly_active_users.yml
@@ -1,18 +1,17 @@
---
data_category: optional
key_path: counts_weekly.aggregated_metrics.code_review_extension_category_monthly_active_users
-name: ""
-description:
-product_section:
-product_stage:
-product_group:
+description: Number of users performing code review extension_category events
+product_section: dev
+product_stage: devops::create
+product_group: group::code review
product_category:
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url:
time_frame: 7d
-data_source:
+data_source: redis_hll
distribution:
- ce
- ee
@@ -20,4 +19,3 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
diff --git a/config/metrics/counts_7d/20210427105030_pipeline_authoring_total_unique_counts_weekly.yml b/config/metrics/counts_7d/20210427105030_pipeline_authoring_total_unique_counts_weekly.yml
index aceb92b7576..fcaeed5faf6 100644
--- a/config/metrics/counts_7d/20210427105030_pipeline_authoring_total_unique_counts_weekly.yml
+++ b/config/metrics/counts_7d/20210427105030_pipeline_authoring_total_unique_counts_weekly.yml
@@ -1,14 +1,13 @@
---
data_category: optional
key_path: redis_hll_counters.pipeline_authoring.pipeline_authoring_total_unique_counts_weekly
-name: "0"
-description:
-product_section:
-product_stage:
-product_group:
-product_category:
+description: Unique users doing commits or push MRs which contains CI cifig file
+product_section: ops
+product_stage: verify
+product_group: group::pipeline authoring
+product_category: pipeline_authoring
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url:
time_frame: 7d
@@ -25,4 +24,3 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
diff --git a/config/metrics/counts_7d/20210514013544_i_code_review_user_load_conflict_ui_weekly.yml b/config/metrics/counts_7d/20210514013544_i_code_review_user_load_conflict_ui_weekly.yml
index 75841e1a340..1402f3fd574 100644
--- a/config/metrics/counts_7d/20210514013544_i_code_review_user_load_conflict_ui_weekly.yml
+++ b/config/metrics/counts_7d/20210514013544_i_code_review_user_load_conflict_ui_weekly.yml
@@ -8,7 +8,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: "13.12"
time_frame: 7d
data_source: redis_hll
diff --git a/config/metrics/counts_7d/20210514013545_i_code_review_user_resolve_conflict_weekly.yml b/config/metrics/counts_7d/20210514013545_i_code_review_user_resolve_conflict_weekly.yml
index 485797cf199..a60f6a23a76 100644
--- a/config/metrics/counts_7d/20210514013545_i_code_review_user_resolve_conflict_weekly.yml
+++ b/config/metrics/counts_7d/20210514013545_i_code_review_user_resolve_conflict_weekly.yml
@@ -8,7 +8,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: "13.12"
time_frame: 28d
data_source: redis_hll
diff --git a/config/metrics/counts_7d/20210517074851_i_package_helm_deploy_token_weekly.yml b/config/metrics/counts_7d/20210517074851_i_package_helm_deploy_token_weekly.yml
index a41d9b758f0..80ed666e376 100644
--- a/config/metrics/counts_7d/20210517074851_i_package_helm_deploy_token_weekly.yml
+++ b/config/metrics/counts_7d/20210517074851_i_package_helm_deploy_token_weekly.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package_registry
value_type: number
-status: implemented
+status: active
milestone: "14.0"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61014
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210517075252_i_package_helm_user_weekly.yml b/config/metrics/counts_7d/20210517075252_i_package_helm_user_weekly.yml
index aa1795925de..a3aede72682 100644
--- a/config/metrics/counts_7d/20210517075252_i_package_helm_user_weekly.yml
+++ b/config/metrics/counts_7d/20210517075252_i_package_helm_user_weekly.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package_registry
value_type: number
-status: implemented
+status: active
milestone: "14.0"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61014
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210607113552_i_code_review_click_diff_view_setting_weekly.yml b/config/metrics/counts_7d/20210607113552_i_code_review_click_diff_view_setting_weekly.yml
index a3cb9e2c400..01ff67560ba 100644
--- a/config/metrics/counts_7d/20210607113552_i_code_review_click_diff_view_setting_weekly.yml
+++ b/config/metrics/counts_7d/20210607113552_i_code_review_click_diff_view_setting_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210720144005_i_code_review_user_searches_diff_weekly.yml b/config/metrics/counts_7d/20210720144005_i_code_review_user_searches_diff_weekly.yml
index ac63687acfb..18a5f85d719 100644
--- a/config/metrics/counts_7d/20210720144005_i_code_review_user_searches_diff_weekly.yml
+++ b/config/metrics/counts_7d/20210720144005_i_code_review_user_searches_diff_weekly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: active
milestone: '14.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66522
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210721042223_i_quickactions_severity_weekly.yml b/config/metrics/counts_7d/20210721042223_i_quickactions_severity_weekly.yml
index 911aec604b1..abce1f1b04b 100644
--- a/config/metrics/counts_7d/20210721042223_i_quickactions_severity_weekly.yml
+++ b/config/metrics/counts_7d/20210721042223_i_quickactions_severity_weekly.yml
@@ -6,7 +6,7 @@ product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: implemented
+status: active
milestone: "14.2"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66422
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210816144119_i_code_review_total_suggestions_added_weekly.yml b/config/metrics/counts_7d/20210816144119_i_code_review_total_suggestions_added_weekly.yml
new file mode 100644
index 00000000000..4460136d6fa
--- /dev/null
+++ b/config/metrics/counts_7d/20210816144119_i_code_review_total_suggestions_added_weekly.yml
@@ -0,0 +1,27 @@
+---
+key_path: redis_hll_counters.code_review.i_code_review_total_suggestions_added_weekly
+name: "count_notes_with_suggestions_weekly"
+description: Total number of weekly suggestions
+product_section: dev
+product_stage: create
+product_group: group::code review
+product_category: code_review
+value_type: number
+status: active
+milestone: "14.3"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67525
+time_frame: 7d
+data_source: redis_hll
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - i_code_review_total_suggestions_added
+data_category: Optional
+performance_indicator_type: []
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_7d/20210816144247_i_code_review_total_suggestions_applied_weekly.yml b/config/metrics/counts_7d/20210816144247_i_code_review_total_suggestions_applied_weekly.yml
new file mode 100644
index 00000000000..9388bad2024
--- /dev/null
+++ b/config/metrics/counts_7d/20210816144247_i_code_review_total_suggestions_applied_weekly.yml
@@ -0,0 +1,27 @@
+---
+key_path: redis_hll_counters.code_review.i_code_review_total_suggestions_applied_weekly
+name: "count_notes_with_applied_suggestions_weekly"
+description: Total number of weekly suggestions applied
+product_section: dev
+product_stage: create
+product_group: group::code review
+product_category: code_review
+value_type: number
+status: active
+milestone: "14.3"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67525
+time_frame: 7d
+data_source: redis_hll
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - i_code_review_total_suggestions_applied
+data_category: Optional
+performance_indicator_type: []
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_7d/20210901221237_p_ci_templates_terraform_base_weekly.yml b/config/metrics/counts_7d/20210901221237_p_ci_templates_terraform_base_weekly.yml
new file mode 100644
index 00000000000..4601cfb0860
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221237_p_ci_templates_terraform_base_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_terraform_base_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_terraform_base
diff --git a/config/metrics/counts_7d/20210901221246_p_ci_templates_dotnet_weekly.yml b/config/metrics/counts_7d/20210901221246_p_ci_templates_dotnet_weekly.yml
new file mode 100644
index 00000000000..8b2c8de3e40
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221246_p_ci_templates_dotnet_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_dotnet_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_dotnet
diff --git a/config/metrics/counts_7d/20210901221255_p_ci_templates_nodejs_weekly.yml b/config/metrics/counts_7d/20210901221255_p_ci_templates_nodejs_weekly.yml
new file mode 100644
index 00000000000..3f10b6c28ef
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221255_p_ci_templates_nodejs_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_nodejs_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_nodejs
diff --git a/config/metrics/counts_7d/20210901221304_p_ci_templates_openshift_weekly.yml b/config/metrics/counts_7d/20210901221304_p_ci_templates_openshift_weekly.yml
new file mode 100644
index 00000000000..70f7ac7f736
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221304_p_ci_templates_openshift_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_openshift_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_openshift
diff --git a/config/metrics/counts_7d/20210901221313_p_ci_templates_bash_weekly.yml b/config/metrics/counts_7d/20210901221313_p_ci_templates_bash_weekly.yml
new file mode 100644
index 00000000000..26d3d7780f4
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221313_p_ci_templates_bash_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_bash_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_bash
diff --git a/config/metrics/counts_7d/20210901221322_p_ci_templates_rust_weekly.yml b/config/metrics/counts_7d/20210901221322_p_ci_templates_rust_weekly.yml
new file mode 100644
index 00000000000..5d22da58b33
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221322_p_ci_templates_rust_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_rust_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_rust
diff --git a/config/metrics/counts_7d/20210901221330_p_ci_templates_elixir_weekly.yml b/config/metrics/counts_7d/20210901221330_p_ci_templates_elixir_weekly.yml
new file mode 100644
index 00000000000..f0bf840127f
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221330_p_ci_templates_elixir_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_elixir_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_elixir
diff --git a/config/metrics/counts_7d/20210901221339_p_ci_templates_clojure_weekly.yml b/config/metrics/counts_7d/20210901221339_p_ci_templates_clojure_weekly.yml
new file mode 100644
index 00000000000..e191ce5b162
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221339_p_ci_templates_clojure_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_clojure_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_clojure
diff --git a/config/metrics/counts_7d/20210901221348_p_ci_templates_crystal_weekly.yml b/config/metrics/counts_7d/20210901221348_p_ci_templates_crystal_weekly.yml
new file mode 100644
index 00000000000..1659cb016ab
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221348_p_ci_templates_crystal_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_crystal_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_crystal
diff --git a/config/metrics/counts_7d/20210901221357_p_ci_templates_getting_started_weekly.yml b/config/metrics/counts_7d/20210901221357_p_ci_templates_getting_started_weekly.yml
new file mode 100644
index 00000000000..438f0eb337a
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221357_p_ci_templates_getting_started_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_getting_started_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_getting_started
diff --git a/config/metrics/counts_7d/20210901221405_p_ci_templates_code_quality_weekly.yml b/config/metrics/counts_7d/20210901221405_p_ci_templates_code_quality_weekly.yml
new file mode 100644
index 00000000000..33a4ec10464
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221405_p_ci_templates_code_quality_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_code_quality_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_code_quality
diff --git a/config/metrics/counts_7d/20210901221414_p_ci_templates_verify_load_performance_testing_weekly.yml b/config/metrics/counts_7d/20210901221414_p_ci_templates_verify_load_performance_testing_weekly.yml
new file mode 100644
index 00000000000..ca61949b607
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221414_p_ci_templates_verify_load_performance_testing_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_verify_load_performance_testing_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_verify_load_performance_testing
diff --git a/config/metrics/counts_7d/20210901221423_p_ci_templates_verify_accessibility_weekly.yml b/config/metrics/counts_7d/20210901221423_p_ci_templates_verify_accessibility_weekly.yml
new file mode 100644
index 00000000000..1d4f411e4fa
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221423_p_ci_templates_verify_accessibility_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_verify_accessibility_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_verify_accessibility
diff --git a/config/metrics/counts_7d/20210901221432_p_ci_templates_verify_failfast_weekly.yml b/config/metrics/counts_7d/20210901221432_p_ci_templates_verify_failfast_weekly.yml
new file mode 100644
index 00000000000..97cd0ecd07d
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221432_p_ci_templates_verify_failfast_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_verify_failfast_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_verify_failfast
diff --git a/config/metrics/counts_7d/20210901221440_p_ci_templates_verify_browser_performance_weekly.yml b/config/metrics/counts_7d/20210901221440_p_ci_templates_verify_browser_performance_weekly.yml
new file mode 100644
index 00000000000..0fb29c0c686
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221440_p_ci_templates_verify_browser_performance_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_verify_browser_performance_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_verify_browser_performance
diff --git a/config/metrics/counts_7d/20210901221449_p_ci_templates_verify_browser_performance_latest_weekly.yml b/config/metrics/counts_7d/20210901221449_p_ci_templates_verify_browser_performance_latest_weekly.yml
new file mode 100644
index 00000000000..424aaebc483
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221449_p_ci_templates_verify_browser_performance_latest_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_verify_browser_performance_latest_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_verify_browser_performance_latest
diff --git a/config/metrics/counts_7d/20210901221458_p_ci_templates_grails_weekly.yml b/config/metrics/counts_7d/20210901221458_p_ci_templates_grails_weekly.yml
new file mode 100644
index 00000000000..f6c5386cc45
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221458_p_ci_templates_grails_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_grails_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_grails
diff --git a/config/metrics/counts_7d/20210901221507_p_ci_templates_security_dast_runner_validation_weekly.yml b/config/metrics/counts_7d/20210901221507_p_ci_templates_security_dast_runner_validation_weekly.yml
new file mode 100644
index 00000000000..2947546da57
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221507_p_ci_templates_security_dast_runner_validation_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_dast_runner_validation_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_dast_runner_validation
diff --git a/config/metrics/counts_7d/20210901221516_p_ci_templates_security_dast_on_demand_scan_weekly.yml b/config/metrics/counts_7d/20210901221516_p_ci_templates_security_dast_on_demand_scan_weekly.yml
new file mode 100644
index 00000000000..bfe8a69c98b
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221516_p_ci_templates_security_dast_on_demand_scan_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_dast_on_demand_scan_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_dast_on_demand_scan
diff --git a/config/metrics/counts_7d/20210901221525_p_ci_templates_security_license_scanning_weekly.yml b/config/metrics/counts_7d/20210901221525_p_ci_templates_security_license_scanning_weekly.yml
new file mode 100644
index 00000000000..589f51e1582
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221525_p_ci_templates_security_license_scanning_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_license_scanning_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_license_scanning
diff --git a/config/metrics/counts_7d/20210901221534_p_ci_templates_security_coverage_fuzzing_weekly.yml b/config/metrics/counts_7d/20210901221534_p_ci_templates_security_coverage_fuzzing_weekly.yml
new file mode 100644
index 00000000000..89edc13d128
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221534_p_ci_templates_security_coverage_fuzzing_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_coverage_fuzzing_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_coverage_fuzzing
diff --git a/config/metrics/counts_7d/20210901221542_p_ci_templates_security_api_fuzzing_latest_weekly.yml b/config/metrics/counts_7d/20210901221542_p_ci_templates_security_api_fuzzing_latest_weekly.yml
new file mode 100644
index 00000000000..b6925668794
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221542_p_ci_templates_security_api_fuzzing_latest_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_api_fuzzing_latest_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_api_fuzzing_latest
diff --git a/config/metrics/counts_7d/20210901221551_p_ci_templates_security_secure_binaries_weekly.yml b/config/metrics/counts_7d/20210901221551_p_ci_templates_security_secure_binaries_weekly.yml
new file mode 100644
index 00000000000..dbf739de6e3
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221551_p_ci_templates_security_secure_binaries_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_secure_binaries_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_secure_binaries
diff --git a/config/metrics/counts_7d/20210901221600_p_ci_templates_security_dast_api_weekly.yml b/config/metrics/counts_7d/20210901221600_p_ci_templates_security_dast_api_weekly.yml
new file mode 100644
index 00000000000..4718fe841d1
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221600_p_ci_templates_security_dast_api_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_dast_api_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_dast_api
diff --git a/config/metrics/counts_7d/20210901221609_p_ci_templates_security_container_scanning_weekly.yml b/config/metrics/counts_7d/20210901221609_p_ci_templates_security_container_scanning_weekly.yml
new file mode 100644
index 00000000000..84f33f2548c
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221609_p_ci_templates_security_container_scanning_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_container_scanning_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_container_scanning
diff --git a/config/metrics/counts_7d/20210901221618_p_ci_templates_security_dast_latest_weekly.yml b/config/metrics/counts_7d/20210901221618_p_ci_templates_security_dast_latest_weekly.yml
new file mode 100644
index 00000000000..38c0485f8e1
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221618_p_ci_templates_security_dast_latest_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_dast_latest_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_dast_latest
diff --git a/config/metrics/counts_7d/20210901221627_p_ci_templates_security_dependency_scanning_weekly.yml b/config/metrics/counts_7d/20210901221627_p_ci_templates_security_dependency_scanning_weekly.yml
new file mode 100644
index 00000000000..f4954107d43
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221627_p_ci_templates_security_dependency_scanning_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_dependency_scanning_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_dependency_scanning
diff --git a/config/metrics/counts_7d/20210901221636_p_ci_templates_security_api_fuzzing_weekly.yml b/config/metrics/counts_7d/20210901221636_p_ci_templates_security_api_fuzzing_weekly.yml
new file mode 100644
index 00000000000..8998597261b
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221636_p_ci_templates_security_api_fuzzing_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_api_fuzzing_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_api_fuzzing
diff --git a/config/metrics/counts_7d/20210901221645_p_ci_templates_security_dast_weekly.yml b/config/metrics/counts_7d/20210901221645_p_ci_templates_security_dast_weekly.yml
new file mode 100644
index 00000000000..6216a39d9f7
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221645_p_ci_templates_security_dast_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_dast_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_dast
diff --git a/config/metrics/counts_7d/20210901221654_p_ci_templates_security_cluster_image_scanning_weekly.yml b/config/metrics/counts_7d/20210901221654_p_ci_templates_security_cluster_image_scanning_weekly.yml
new file mode 100644
index 00000000000..200f46ac22d
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221654_p_ci_templates_security_cluster_image_scanning_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_cluster_image_scanning_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_cluster_image_scanning
diff --git a/config/metrics/counts_7d/20210901221703_p_ci_templates_ios_fastlane_weekly.yml b/config/metrics/counts_7d/20210901221703_p_ci_templates_ios_fastlane_weekly.yml
new file mode 100644
index 00000000000..0ff048bd50a
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221703_p_ci_templates_ios_fastlane_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_ios_fastlane_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_ios_fastlane
diff --git a/config/metrics/counts_7d/20210901221712_p_ci_templates_composer_weekly.yml b/config/metrics/counts_7d/20210901221712_p_ci_templates_composer_weekly.yml
new file mode 100644
index 00000000000..91f7fd8a29f
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221712_p_ci_templates_composer_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_composer_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_composer
diff --git a/config/metrics/counts_7d/20210901221722_p_ci_templates_c_weekly.yml b/config/metrics/counts_7d/20210901221722_p_ci_templates_c_weekly.yml
new file mode 100644
index 00000000000..7e1a97b3d78
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221722_p_ci_templates_c_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_c_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_c
diff --git a/config/metrics/counts_7d/20210901221731_p_ci_templates_python_weekly.yml b/config/metrics/counts_7d/20210901221731_p_ci_templates_python_weekly.yml
new file mode 100644
index 00000000000..3a739ac16eb
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221731_p_ci_templates_python_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_python_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_python
diff --git a/config/metrics/counts_7d/20210901221740_p_ci_templates_android_fastlane_weekly.yml b/config/metrics/counts_7d/20210901221740_p_ci_templates_android_fastlane_weekly.yml
new file mode 100644
index 00000000000..12b2d3445e3
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221740_p_ci_templates_android_fastlane_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_android_fastlane_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_android_fastlane
diff --git a/config/metrics/counts_7d/20210901221749_p_ci_templates_django_weekly.yml b/config/metrics/counts_7d/20210901221749_p_ci_templates_django_weekly.yml
new file mode 100644
index 00000000000..5161260f733
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221749_p_ci_templates_django_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_django_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_django
diff --git a/config/metrics/counts_7d/20210901221758_p_ci_templates_maven_weekly.yml b/config/metrics/counts_7d/20210901221758_p_ci_templates_maven_weekly.yml
new file mode 100644
index 00000000000..6771363d4f0
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221758_p_ci_templates_maven_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_maven_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_maven
diff --git a/config/metrics/counts_7d/20210901221807_p_ci_templates_flutter_weekly.yml b/config/metrics/counts_7d/20210901221807_p_ci_templates_flutter_weekly.yml
new file mode 100644
index 00000000000..f0597215cdb
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221807_p_ci_templates_flutter_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_flutter_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_flutter
diff --git a/config/metrics/counts_7d/20210901221817_p_ci_templates_workflows_branch_pipelines_weekly.yml b/config/metrics/counts_7d/20210901221817_p_ci_templates_workflows_branch_pipelines_weekly.yml
new file mode 100644
index 00000000000..e5ee6349a68
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221817_p_ci_templates_workflows_branch_pipelines_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_workflows_branch_pipelines_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_workflows_branch_pipelines
diff --git a/config/metrics/counts_7d/20210901221826_p_ci_templates_workflows_mergerequest_pipelines_weekly.yml b/config/metrics/counts_7d/20210901221826_p_ci_templates_workflows_mergerequest_pipelines_weekly.yml
new file mode 100644
index 00000000000..c36507c86c1
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221826_p_ci_templates_workflows_mergerequest_pipelines_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_workflows_mergerequest_pipelines_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_workflows_mergerequest_pipelines
diff --git a/config/metrics/counts_7d/20210901221836_p_ci_templates_laravel_weekly.yml b/config/metrics/counts_7d/20210901221836_p_ci_templates_laravel_weekly.yml
new file mode 100644
index 00000000000..4f994b3b21e
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221836_p_ci_templates_laravel_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_laravel_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_laravel
diff --git a/config/metrics/counts_7d/20210901221844_p_ci_templates_managed_cluster_applications_weekly.yml b/config/metrics/counts_7d/20210901221844_p_ci_templates_managed_cluster_applications_weekly.yml
new file mode 100644
index 00000000000..592f52a0681
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221844_p_ci_templates_managed_cluster_applications_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_managed_cluster_applications_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_managed_cluster_applications
diff --git a/config/metrics/counts_7d/20210901221853_p_ci_templates_php_weekly.yml b/config/metrics/counts_7d/20210901221853_p_ci_templates_php_weekly.yml
new file mode 100644
index 00000000000..b1dbd64ae25
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221853_p_ci_templates_php_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_php_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_php
diff --git a/config/metrics/counts_7d/20210901221902_p_ci_templates_packer_weekly.yml b/config/metrics/counts_7d/20210901221902_p_ci_templates_packer_weekly.yml
new file mode 100644
index 00000000000..7b813f3c1c8
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221902_p_ci_templates_packer_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_packer_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_packer
diff --git a/config/metrics/counts_7d/20210901221910_p_ci_templates_terraform_weekly.yml b/config/metrics/counts_7d/20210901221910_p_ci_templates_terraform_weekly.yml
new file mode 100644
index 00000000000..833a103b424
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221910_p_ci_templates_terraform_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_terraform_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_terraform
diff --git a/config/metrics/counts_7d/20210901221919_p_ci_templates_mono_weekly.yml b/config/metrics/counts_7d/20210901221919_p_ci_templates_mono_weekly.yml
new file mode 100644
index 00000000000..5ca5b632ed7
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221919_p_ci_templates_mono_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_mono_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_mono
diff --git a/config/metrics/counts_7d/20210901221928_p_ci_templates_serverless_weekly.yml b/config/metrics/counts_7d/20210901221928_p_ci_templates_serverless_weekly.yml
new file mode 100644
index 00000000000..86c3ca6e3df
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221928_p_ci_templates_serverless_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_serverless_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_serverless
diff --git a/config/metrics/counts_7d/20210901221936_p_ci_templates_go_weekly.yml b/config/metrics/counts_7d/20210901221936_p_ci_templates_go_weekly.yml
new file mode 100644
index 00000000000..b297836dbf5
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221936_p_ci_templates_go_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_go_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_go
diff --git a/config/metrics/counts_7d/20210901221945_p_ci_templates_scala_weekly.yml b/config/metrics/counts_7d/20210901221945_p_ci_templates_scala_weekly.yml
new file mode 100644
index 00000000000..bdc019f53bc
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221945_p_ci_templates_scala_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_scala_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_scala
diff --git a/config/metrics/counts_7d/20210901221954_p_ci_templates_latex_weekly.yml b/config/metrics/counts_7d/20210901221954_p_ci_templates_latex_weekly.yml
new file mode 100644
index 00000000000..5eeb0b587f7
--- /dev/null
+++ b/config/metrics/counts_7d/20210901221954_p_ci_templates_latex_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_latex_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_latex
diff --git a/config/metrics/counts_7d/20210901222003_p_ci_templates_android_weekly.yml b/config/metrics/counts_7d/20210901222003_p_ci_templates_android_weekly.yml
new file mode 100644
index 00000000000..be803873da2
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222003_p_ci_templates_android_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_android_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_android
diff --git a/config/metrics/counts_7d/20210901222011_p_ci_templates_indeni_cloudrail_weekly.yml b/config/metrics/counts_7d/20210901222011_p_ci_templates_indeni_cloudrail_weekly.yml
new file mode 100644
index 00000000000..02848df7032
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222011_p_ci_templates_indeni_cloudrail_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_indeni_cloudrail_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_indeni_cloudrail
diff --git a/config/metrics/counts_7d/20210901222020_p_ci_templates_deploy_ecs_weekly.yml b/config/metrics/counts_7d/20210901222020_p_ci_templates_deploy_ecs_weekly.yml
new file mode 100644
index 00000000000..31f8f31344f
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222020_p_ci_templates_deploy_ecs_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_deploy_ecs_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_deploy_ecs
diff --git a/config/metrics/counts_7d/20210901222029_p_ci_templates_aws_cf_provision_and_deploy_ec2_weekly.yml b/config/metrics/counts_7d/20210901222029_p_ci_templates_aws_cf_provision_and_deploy_ec2_weekly.yml
new file mode 100644
index 00000000000..1df7de7867f
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222029_p_ci_templates_aws_cf_provision_and_deploy_ec2_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_aws_cf_provision_and_deploy_ec2_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_aws_cf_provision_and_deploy_ec2
diff --git a/config/metrics/counts_7d/20210901222038_p_ci_templates_gradle_weekly.yml b/config/metrics/counts_7d/20210901222038_p_ci_templates_gradle_weekly.yml
new file mode 100644
index 00000000000..ffee4a62bef
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222038_p_ci_templates_gradle_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_gradle_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_gradle
diff --git a/config/metrics/counts_7d/20210901222046_p_ci_templates_chef_weekly.yml b/config/metrics/counts_7d/20210901222046_p_ci_templates_chef_weekly.yml
new file mode 100644
index 00000000000..b9601085fe1
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222046_p_ci_templates_chef_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_chef_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_chef
diff --git a/config/metrics/counts_7d/20210901222055_p_ci_templates_jobs_dast_default_branch_deploy_weekly.yml b/config/metrics/counts_7d/20210901222055_p_ci_templates_jobs_dast_default_branch_deploy_weekly.yml
new file mode 100644
index 00000000000..3efb9e7e435
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222055_p_ci_templates_jobs_dast_default_branch_deploy_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_dast_default_branch_deploy_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_dast_default_branch_deploy
diff --git a/config/metrics/counts_7d/20210901222104_p_ci_templates_jobs_load_performance_testing_weekly.yml b/config/metrics/counts_7d/20210901222104_p_ci_templates_jobs_load_performance_testing_weekly.yml
new file mode 100644
index 00000000000..efdab0f1c35
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222104_p_ci_templates_jobs_load_performance_testing_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_load_performance_testing_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_load_performance_testing
diff --git a/config/metrics/counts_7d/20210901222113_p_ci_templates_jobs_helm_2to3_weekly.yml b/config/metrics/counts_7d/20210901222113_p_ci_templates_jobs_helm_2to3_weekly.yml
new file mode 100644
index 00000000000..878e5d1f08b
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222113_p_ci_templates_jobs_helm_2to3_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_helm_2to3_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_helm_2to3
diff --git a/config/metrics/counts_7d/20210901222122_p_ci_templates_jobs_sast_weekly.yml b/config/metrics/counts_7d/20210901222122_p_ci_templates_jobs_sast_weekly.yml
new file mode 100644
index 00000000000..bc7c9914c31
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222122_p_ci_templates_jobs_sast_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_sast_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_sast
diff --git a/config/metrics/counts_7d/20210901222131_p_ci_templates_jobs_secret_detection_weekly.yml b/config/metrics/counts_7d/20210901222131_p_ci_templates_jobs_secret_detection_weekly.yml
new file mode 100644
index 00000000000..c627098b569
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222131_p_ci_templates_jobs_secret_detection_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_secret_detection_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_secret_detection
diff --git a/config/metrics/counts_7d/20210901222139_p_ci_templates_jobs_code_intelligence_weekly.yml b/config/metrics/counts_7d/20210901222139_p_ci_templates_jobs_code_intelligence_weekly.yml
new file mode 100644
index 00000000000..9997a733c84
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222139_p_ci_templates_jobs_code_intelligence_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_code_intelligence_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_code_intelligence
diff --git a/config/metrics/counts_7d/20210901222148_p_ci_templates_jobs_code_quality_weekly.yml b/config/metrics/counts_7d/20210901222148_p_ci_templates_jobs_code_quality_weekly.yml
new file mode 100644
index 00000000000..6286fb00725
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222148_p_ci_templates_jobs_code_quality_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_code_quality_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_code_quality
diff --git a/config/metrics/counts_7d/20210901222157_p_ci_templates_jobs_deploy_ecs_weekly.yml b/config/metrics/counts_7d/20210901222157_p_ci_templates_jobs_deploy_ecs_weekly.yml
new file mode 100644
index 00000000000..abe645e059a
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222157_p_ci_templates_jobs_deploy_ecs_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_deploy_ecs_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_deploy_ecs
diff --git a/config/metrics/counts_7d/20210901222206_p_ci_templates_jobs_deploy_ec2_weekly.yml b/config/metrics/counts_7d/20210901222206_p_ci_templates_jobs_deploy_ec2_weekly.yml
new file mode 100644
index 00000000000..3f3c491acf5
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222206_p_ci_templates_jobs_deploy_ec2_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_deploy_ec2_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_deploy_ec2
diff --git a/config/metrics/counts_7d/20210901222215_p_ci_templates_jobs_deploy_weekly.yml b/config/metrics/counts_7d/20210901222215_p_ci_templates_jobs_deploy_weekly.yml
new file mode 100644
index 00000000000..f5036c5bd7c
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222215_p_ci_templates_jobs_deploy_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_deploy_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_deploy
diff --git a/config/metrics/counts_7d/20210901222224_p_ci_templates_jobs_build_weekly.yml b/config/metrics/counts_7d/20210901222224_p_ci_templates_jobs_build_weekly.yml
new file mode 100644
index 00000000000..80dfa5e52ee
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222224_p_ci_templates_jobs_build_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_build_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_build
diff --git a/config/metrics/counts_7d/20210901222233_p_ci_templates_jobs_browser_performance_testing_weekly.yml b/config/metrics/counts_7d/20210901222233_p_ci_templates_jobs_browser_performance_testing_weekly.yml
new file mode 100644
index 00000000000..a0b5145dc32
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222233_p_ci_templates_jobs_browser_performance_testing_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_browser_performance_testing_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_browser_performance_testing
diff --git a/config/metrics/counts_7d/20210901222242_p_ci_templates_jobs_test_weekly.yml b/config/metrics/counts_7d/20210901222242_p_ci_templates_jobs_test_weekly.yml
new file mode 100644
index 00000000000..ffbac5590cc
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222242_p_ci_templates_jobs_test_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_test_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_test
diff --git a/config/metrics/counts_7d/20210901222251_p_ci_templates_jobs_deploy_latest_weekly.yml b/config/metrics/counts_7d/20210901222251_p_ci_templates_jobs_deploy_latest_weekly.yml
new file mode 100644
index 00000000000..c076bfed8f0
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222251_p_ci_templates_jobs_deploy_latest_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_deploy_latest_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_deploy_latest
diff --git a/config/metrics/counts_7d/20210901222300_p_ci_templates_jobs_browser_performance_testing_latest_weekly.yml b/config/metrics/counts_7d/20210901222300_p_ci_templates_jobs_browser_performance_testing_latest_weekly.yml
new file mode 100644
index 00000000000..97d8bb1f7a8
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222300_p_ci_templates_jobs_browser_performance_testing_latest_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_browser_performance_testing_latest_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_browser_performance_testing_latest
diff --git a/config/metrics/counts_7d/20210901222309_p_ci_templates_jobs_cf_provision_weekly.yml b/config/metrics/counts_7d/20210901222309_p_ci_templates_jobs_cf_provision_weekly.yml
new file mode 100644
index 00000000000..f14bd662bb4
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222309_p_ci_templates_jobs_cf_provision_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_cf_provision_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_cf_provision
diff --git a/config/metrics/counts_7d/20210901222318_p_ci_templates_jobs_build_latest_weekly.yml b/config/metrics/counts_7d/20210901222318_p_ci_templates_jobs_build_latest_weekly.yml
new file mode 100644
index 00000000000..91e8e6d7126
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222318_p_ci_templates_jobs_build_latest_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_build_latest_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_build_latest
diff --git a/config/metrics/counts_7d/20210901222327_p_ci_templates_terraform_latest_weekly.yml b/config/metrics/counts_7d/20210901222327_p_ci_templates_terraform_latest_weekly.yml
new file mode 100644
index 00000000000..98d7cae5c2f
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222327_p_ci_templates_terraform_latest_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_terraform_latest_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_terraform_latest
diff --git a/config/metrics/counts_7d/20210901222336_p_ci_templates_swift_weekly.yml b/config/metrics/counts_7d/20210901222336_p_ci_templates_swift_weekly.yml
new file mode 100644
index 00000000000..8b2fb8cd127
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222336_p_ci_templates_swift_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_swift_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_swift
diff --git a/config/metrics/counts_7d/20210901222703_p_ci_templates_pages_jekyll_weekly.yml b/config/metrics/counts_7d/20210901222703_p_ci_templates_pages_jekyll_weekly.yml
new file mode 100644
index 00000000000..e641f623c60
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222703_p_ci_templates_pages_jekyll_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_jekyll_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_jekyll
diff --git a/config/metrics/counts_7d/20210901222719_p_ci_templates_pages_harp_weekly.yml b/config/metrics/counts_7d/20210901222719_p_ci_templates_pages_harp_weekly.yml
new file mode 100644
index 00000000000..1419e5894bb
--- /dev/null
+++ b/config/metrics/counts_7d/20210901222719_p_ci_templates_pages_harp_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_harp_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_harp
diff --git a/config/metrics/counts_7d/20210901223156_p_ci_templates_pages_octopress_weekly.yml b/config/metrics/counts_7d/20210901223156_p_ci_templates_pages_octopress_weekly.yml
new file mode 100644
index 00000000000..d7d7e62b256
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223156_p_ci_templates_pages_octopress_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_octopress_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_octopress
diff --git a/config/metrics/counts_7d/20210901223206_p_ci_templates_pages_brunch_weekly.yml b/config/metrics/counts_7d/20210901223206_p_ci_templates_pages_brunch_weekly.yml
new file mode 100644
index 00000000000..9a521247591
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223206_p_ci_templates_pages_brunch_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_brunch_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_brunch
diff --git a/config/metrics/counts_7d/20210901223215_p_ci_templates_pages_doxygen_weekly.yml b/config/metrics/counts_7d/20210901223215_p_ci_templates_pages_doxygen_weekly.yml
new file mode 100644
index 00000000000..caca2d80d85
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223215_p_ci_templates_pages_doxygen_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_doxygen_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_doxygen
diff --git a/config/metrics/counts_7d/20210901223223_p_ci_templates_pages_hyde_weekly.yml b/config/metrics/counts_7d/20210901223223_p_ci_templates_pages_hyde_weekly.yml
new file mode 100644
index 00000000000..f87d5663cd0
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223223_p_ci_templates_pages_hyde_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_hyde_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_hyde
diff --git a/config/metrics/counts_7d/20210901223232_p_ci_templates_pages_lektor_weekly.yml b/config/metrics/counts_7d/20210901223232_p_ci_templates_pages_lektor_weekly.yml
new file mode 100644
index 00000000000..e5a5664aee3
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223232_p_ci_templates_pages_lektor_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_lektor_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_lektor
diff --git a/config/metrics/counts_7d/20210901223240_p_ci_templates_pages_jbake_weekly.yml b/config/metrics/counts_7d/20210901223240_p_ci_templates_pages_jbake_weekly.yml
new file mode 100644
index 00000000000..fa44a295b65
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223240_p_ci_templates_pages_jbake_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_jbake_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_jbake
diff --git a/config/metrics/counts_7d/20210901223249_p_ci_templates_pages_hexo_weekly.yml b/config/metrics/counts_7d/20210901223249_p_ci_templates_pages_hexo_weekly.yml
new file mode 100644
index 00000000000..2adf9a396ef
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223249_p_ci_templates_pages_hexo_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_hexo_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_hexo
diff --git a/config/metrics/counts_7d/20210901223257_p_ci_templates_pages_middleman_weekly.yml b/config/metrics/counts_7d/20210901223257_p_ci_templates_pages_middleman_weekly.yml
new file mode 100644
index 00000000000..a920ff72b7b
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223257_p_ci_templates_pages_middleman_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_middleman_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_middleman
diff --git a/config/metrics/counts_7d/20210901223306_p_ci_templates_pages_hugo_weekly.yml b/config/metrics/counts_7d/20210901223306_p_ci_templates_pages_hugo_weekly.yml
new file mode 100644
index 00000000000..10183e79f80
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223306_p_ci_templates_pages_hugo_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_hugo_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_hugo
diff --git a/config/metrics/counts_7d/20210901223315_p_ci_templates_pages_pelican_weekly.yml b/config/metrics/counts_7d/20210901223315_p_ci_templates_pages_pelican_weekly.yml
new file mode 100644
index 00000000000..0d2e5ca9122
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223315_p_ci_templates_pages_pelican_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_pelican_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_pelican
diff --git a/config/metrics/counts_7d/20210901223324_p_ci_templates_pages_nanoc_weekly.yml b/config/metrics/counts_7d/20210901223324_p_ci_templates_pages_nanoc_weekly.yml
new file mode 100644
index 00000000000..5cad30c5f0c
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223324_p_ci_templates_pages_nanoc_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_nanoc_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_nanoc
diff --git a/config/metrics/counts_7d/20210901223332_p_ci_templates_pages_swaggerui_weekly.yml b/config/metrics/counts_7d/20210901223332_p_ci_templates_pages_swaggerui_weekly.yml
new file mode 100644
index 00000000000..5fcd652a26a
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223332_p_ci_templates_pages_swaggerui_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_swaggerui_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_swaggerui
diff --git a/config/metrics/counts_7d/20210901223341_p_ci_templates_pages_jigsaw_weekly.yml b/config/metrics/counts_7d/20210901223341_p_ci_templates_pages_jigsaw_weekly.yml
new file mode 100644
index 00000000000..f0f2afd434e
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223341_p_ci_templates_pages_jigsaw_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_jigsaw_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_jigsaw
diff --git a/config/metrics/counts_7d/20210901223350_p_ci_templates_pages_metalsmith_weekly.yml b/config/metrics/counts_7d/20210901223350_p_ci_templates_pages_metalsmith_weekly.yml
new file mode 100644
index 00000000000..3ca7a23618b
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223350_p_ci_templates_pages_metalsmith_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_metalsmith_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_metalsmith
diff --git a/config/metrics/counts_7d/20210901223359_p_ci_templates_pages_gatsby_weekly.yml b/config/metrics/counts_7d/20210901223359_p_ci_templates_pages_gatsby_weekly.yml
new file mode 100644
index 00000000000..6c8db9b7058
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223359_p_ci_templates_pages_gatsby_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_gatsby_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_gatsby
diff --git a/config/metrics/counts_7d/20210901223408_p_ci_templates_pages_html_weekly.yml b/config/metrics/counts_7d/20210901223408_p_ci_templates_pages_html_weekly.yml
new file mode 100644
index 00000000000..4a7c592cd09
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223408_p_ci_templates_pages_html_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_pages_html_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_pages_html
diff --git a/config/metrics/counts_7d/20210901223416_p_ci_templates_dart_weekly.yml b/config/metrics/counts_7d/20210901223416_p_ci_templates_dart_weekly.yml
new file mode 100644
index 00000000000..d2942ef6f6b
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223416_p_ci_templates_dart_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_dart_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_dart
diff --git a/config/metrics/counts_7d/20210901223425_p_ci_templates_docker_weekly.yml b/config/metrics/counts_7d/20210901223425_p_ci_templates_docker_weekly.yml
new file mode 100644
index 00000000000..307df73a622
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223425_p_ci_templates_docker_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_docker_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_docker
diff --git a/config/metrics/counts_7d/20210901223434_p_ci_templates_julia_weekly.yml b/config/metrics/counts_7d/20210901223434_p_ci_templates_julia_weekly.yml
new file mode 100644
index 00000000000..6624697c56c
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223434_p_ci_templates_julia_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_julia_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_julia
diff --git a/config/metrics/counts_7d/20210901223443_p_ci_templates_npm_weekly.yml b/config/metrics/counts_7d/20210901223443_p_ci_templates_npm_weekly.yml
new file mode 100644
index 00000000000..97de705a4de
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223443_p_ci_templates_npm_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_npm_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_npm
diff --git a/config/metrics/counts_7d/20210901223452_p_ci_templates_dotnet_core_weekly.yml b/config/metrics/counts_7d/20210901223452_p_ci_templates_dotnet_core_weekly.yml
new file mode 100644
index 00000000000..b89ef58fbc1
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223452_p_ci_templates_dotnet_core_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_dotnet_core_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_dotnet_core
diff --git a/config/metrics/counts_7d/20210901223501_p_ci_templates_5_minute_production_app_weekly.yml b/config/metrics/counts_7d/20210901223501_p_ci_templates_5_minute_production_app_weekly.yml
new file mode 100644
index 00000000000..ee6c2eaa60b
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223501_p_ci_templates_5_minute_production_app_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_5_minute_production_app_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_5_minute_production_app
diff --git a/config/metrics/counts_7d/20210901223510_p_ci_templates_ruby_weekly.yml b/config/metrics/counts_7d/20210901223510_p_ci_templates_ruby_weekly.yml
new file mode 100644
index 00000000000..414eb9bc7ff
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223510_p_ci_templates_ruby_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_ruby_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_ruby
diff --git a/config/metrics/counts_7d/20210901223519_p_ci_templates_implicit_jobs_dast_default_branch_deploy_weekly.yml b/config/metrics/counts_7d/20210901223519_p_ci_templates_implicit_jobs_dast_default_branch_deploy_weekly.yml
new file mode 100644
index 00000000000..982257506b1
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223519_p_ci_templates_implicit_jobs_dast_default_branch_deploy_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_dast_default_branch_deploy_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_dast_default_branch_deploy
diff --git a/config/metrics/counts_7d/20210901223528_p_ci_templates_implicit_jobs_load_performance_testing_weekly.yml b/config/metrics/counts_7d/20210901223528_p_ci_templates_implicit_jobs_load_performance_testing_weekly.yml
new file mode 100644
index 00000000000..a38c2396a5f
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223528_p_ci_templates_implicit_jobs_load_performance_testing_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_load_performance_testing_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_load_performance_testing
diff --git a/config/metrics/counts_7d/20210901223537_p_ci_templates_implicit_jobs_helm_2to3_weekly.yml b/config/metrics/counts_7d/20210901223537_p_ci_templates_implicit_jobs_helm_2to3_weekly.yml
new file mode 100644
index 00000000000..4e2dfe4e7e7
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223537_p_ci_templates_implicit_jobs_helm_2to3_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_helm_2to3_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_helm_2to3
diff --git a/config/metrics/counts_7d/20210901223546_p_ci_templates_implicit_jobs_sast_weekly.yml b/config/metrics/counts_7d/20210901223546_p_ci_templates_implicit_jobs_sast_weekly.yml
new file mode 100644
index 00000000000..13a7628fd56
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223546_p_ci_templates_implicit_jobs_sast_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_sast_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_sast
diff --git a/config/metrics/counts_7d/20210901223554_p_ci_templates_implicit_jobs_secret_detection_weekly.yml b/config/metrics/counts_7d/20210901223554_p_ci_templates_implicit_jobs_secret_detection_weekly.yml
new file mode 100644
index 00000000000..59bae76f3e5
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223554_p_ci_templates_implicit_jobs_secret_detection_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_secret_detection_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_secret_detection
diff --git a/config/metrics/counts_7d/20210901223603_p_ci_templates_implicit_jobs_code_intelligence_weekly.yml b/config/metrics/counts_7d/20210901223603_p_ci_templates_implicit_jobs_code_intelligence_weekly.yml
new file mode 100644
index 00000000000..0237f2914ae
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223603_p_ci_templates_implicit_jobs_code_intelligence_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_code_intelligence_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_code_intelligence
diff --git a/config/metrics/counts_7d/20210901223612_p_ci_templates_implicit_jobs_code_quality_weekly.yml b/config/metrics/counts_7d/20210901223612_p_ci_templates_implicit_jobs_code_quality_weekly.yml
new file mode 100644
index 00000000000..05e1a9ab017
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223612_p_ci_templates_implicit_jobs_code_quality_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_code_quality_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_code_quality
diff --git a/config/metrics/counts_7d/20210901223621_p_ci_templates_implicit_jobs_deploy_ecs_weekly.yml b/config/metrics/counts_7d/20210901223621_p_ci_templates_implicit_jobs_deploy_ecs_weekly.yml
new file mode 100644
index 00000000000..88c9db04884
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223621_p_ci_templates_implicit_jobs_deploy_ecs_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_deploy_ecs_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_deploy_ecs
diff --git a/config/metrics/counts_7d/20210901223630_p_ci_templates_implicit_jobs_deploy_ec2_weekly.yml b/config/metrics/counts_7d/20210901223630_p_ci_templates_implicit_jobs_deploy_ec2_weekly.yml
new file mode 100644
index 00000000000..060f5b70ca8
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223630_p_ci_templates_implicit_jobs_deploy_ec2_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_deploy_ec2_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_deploy_ec2
diff --git a/config/metrics/counts_7d/20210901223639_p_ci_templates_implicit_jobs_browser_performance_testing_weekly.yml b/config/metrics/counts_7d/20210901223639_p_ci_templates_implicit_jobs_browser_performance_testing_weekly.yml
new file mode 100644
index 00000000000..67d2a02358a
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223639_p_ci_templates_implicit_jobs_browser_performance_testing_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_browser_performance_testing_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_browser_performance_testing
diff --git a/config/metrics/counts_7d/20210901223649_p_ci_templates_implicit_jobs_test_weekly.yml b/config/metrics/counts_7d/20210901223649_p_ci_templates_implicit_jobs_test_weekly.yml
new file mode 100644
index 00000000000..f5ceb651ef1
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223649_p_ci_templates_implicit_jobs_test_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_test_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_test
diff --git a/config/metrics/counts_7d/20210901223658_p_ci_templates_implicit_jobs_browser_performance_testing_latest_weekly.yml b/config/metrics/counts_7d/20210901223658_p_ci_templates_implicit_jobs_browser_performance_testing_latest_weekly.yml
new file mode 100644
index 00000000000..2c1aee4d4ca
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223658_p_ci_templates_implicit_jobs_browser_performance_testing_latest_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_browser_performance_testing_latest_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_browser_performance_testing_latest
diff --git a/config/metrics/counts_7d/20210901223707_p_ci_templates_implicit_jobs_cf_provision_weekly.yml b/config/metrics/counts_7d/20210901223707_p_ci_templates_implicit_jobs_cf_provision_weekly.yml
new file mode 100644
index 00000000000..d325ed2644f
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223707_p_ci_templates_implicit_jobs_cf_provision_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_cf_provision_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_cf_provision
diff --git a/config/metrics/counts_7d/20210901223716_p_ci_templates_implicit_jobs_build_latest_weekly.yml b/config/metrics/counts_7d/20210901223716_p_ci_templates_implicit_jobs_build_latest_weekly.yml
new file mode 100644
index 00000000000..8936d4ce21a
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223716_p_ci_templates_implicit_jobs_build_latest_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_build_latest_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_build_latest
diff --git a/config/metrics/counts_7d/20210901223725_p_ci_templates_implicit_security_dast_runner_validation_weekly.yml b/config/metrics/counts_7d/20210901223725_p_ci_templates_implicit_security_dast_runner_validation_weekly.yml
new file mode 100644
index 00000000000..c0d3299d9bf
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223725_p_ci_templates_implicit_security_dast_runner_validation_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_dast_runner_validation_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_dast_runner_validation
diff --git a/config/metrics/counts_7d/20210901223735_p_ci_templates_implicit_security_dast_on_demand_scan_weekly.yml b/config/metrics/counts_7d/20210901223735_p_ci_templates_implicit_security_dast_on_demand_scan_weekly.yml
new file mode 100644
index 00000000000..8d39fc698a8
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223735_p_ci_templates_implicit_security_dast_on_demand_scan_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_dast_on_demand_scan_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_dast_on_demand_scan
diff --git a/config/metrics/counts_7d/20210901223744_p_ci_templates_implicit_security_license_scanning_weekly.yml b/config/metrics/counts_7d/20210901223744_p_ci_templates_implicit_security_license_scanning_weekly.yml
new file mode 100644
index 00000000000..9655f006c44
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223744_p_ci_templates_implicit_security_license_scanning_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_license_scanning_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_license_scanning
diff --git a/config/metrics/counts_7d/20210901223753_p_ci_templates_implicit_security_coverage_fuzzing_weekly.yml b/config/metrics/counts_7d/20210901223753_p_ci_templates_implicit_security_coverage_fuzzing_weekly.yml
new file mode 100644
index 00000000000..97a44953b1e
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223753_p_ci_templates_implicit_security_coverage_fuzzing_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_coverage_fuzzing_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_coverage_fuzzing
diff --git a/config/metrics/counts_7d/20210901223802_p_ci_templates_implicit_security_api_fuzzing_latest_weekly.yml b/config/metrics/counts_7d/20210901223802_p_ci_templates_implicit_security_api_fuzzing_latest_weekly.yml
new file mode 100644
index 00000000000..4f4e3a05b4d
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223802_p_ci_templates_implicit_security_api_fuzzing_latest_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_api_fuzzing_latest_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_api_fuzzing_latest
diff --git a/config/metrics/counts_7d/20210901223811_p_ci_templates_implicit_security_secure_binaries_weekly.yml b/config/metrics/counts_7d/20210901223811_p_ci_templates_implicit_security_secure_binaries_weekly.yml
new file mode 100644
index 00000000000..08f8340acbd
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223811_p_ci_templates_implicit_security_secure_binaries_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_secure_binaries_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_secure_binaries
diff --git a/config/metrics/counts_7d/20210901223819_p_ci_templates_implicit_security_dast_api_weekly.yml b/config/metrics/counts_7d/20210901223819_p_ci_templates_implicit_security_dast_api_weekly.yml
new file mode 100644
index 00000000000..b4197326e5c
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223819_p_ci_templates_implicit_security_dast_api_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_dast_api_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_dast_api
diff --git a/config/metrics/counts_7d/20210901223828_p_ci_templates_implicit_security_container_scanning_weekly.yml b/config/metrics/counts_7d/20210901223828_p_ci_templates_implicit_security_container_scanning_weekly.yml
new file mode 100644
index 00000000000..5e40e73ec83
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223828_p_ci_templates_implicit_security_container_scanning_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_container_scanning_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_container_scanning
diff --git a/config/metrics/counts_7d/20210901223837_p_ci_templates_implicit_security_dast_latest_weekly.yml b/config/metrics/counts_7d/20210901223837_p_ci_templates_implicit_security_dast_latest_weekly.yml
new file mode 100644
index 00000000000..2c804015f3b
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223837_p_ci_templates_implicit_security_dast_latest_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_dast_latest_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_dast_latest
diff --git a/config/metrics/counts_7d/20210901223845_p_ci_templates_implicit_security_dependency_scanning_weekly.yml b/config/metrics/counts_7d/20210901223845_p_ci_templates_implicit_security_dependency_scanning_weekly.yml
new file mode 100644
index 00000000000..777413e4f5f
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223845_p_ci_templates_implicit_security_dependency_scanning_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_dependency_scanning_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_dependency_scanning
diff --git a/config/metrics/counts_7d/20210901223854_p_ci_templates_implicit_security_api_fuzzing_weekly.yml b/config/metrics/counts_7d/20210901223854_p_ci_templates_implicit_security_api_fuzzing_weekly.yml
new file mode 100644
index 00000000000..f79388fdfc5
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223854_p_ci_templates_implicit_security_api_fuzzing_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_api_fuzzing_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_api_fuzzing
diff --git a/config/metrics/counts_7d/20210901223903_p_ci_templates_implicit_security_dast_weekly.yml b/config/metrics/counts_7d/20210901223903_p_ci_templates_implicit_security_dast_weekly.yml
new file mode 100644
index 00000000000..2ba2a04de1c
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223903_p_ci_templates_implicit_security_dast_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_dast_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_dast
diff --git a/config/metrics/counts_7d/20210901223912_p_ci_templates_implicit_security_cluster_image_scanning_weekly.yml b/config/metrics/counts_7d/20210901223912_p_ci_templates_implicit_security_cluster_image_scanning_weekly.yml
new file mode 100644
index 00000000000..e1ee3f9fd1d
--- /dev/null
+++ b/config/metrics/counts_7d/20210901223912_p_ci_templates_implicit_security_cluster_image_scanning_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_cluster_image_scanning_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_cluster_image_scanning
diff --git a/config/metrics/counts_7d/20210902000809_p_ci_templates_implicit_auto_devops_deploy_latest_weekly.yml b/config/metrics/counts_7d/20210902000809_p_ci_templates_implicit_auto_devops_deploy_latest_weekly.yml
new file mode 100644
index 00000000000..7f674324a31
--- /dev/null
+++ b/config/metrics/counts_7d/20210902000809_p_ci_templates_implicit_auto_devops_deploy_latest_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_auto_devops_deploy_latest_weekly
+description: Count of pipelines using the latest Auto Deploy template
+product_section: ops
+product_stage: configure
+product_group: group::configure
+product_category: infrastructure_as_code
+value_type: number
+status: active
+milestone: '14.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_auto_devops_deploy_latest
diff --git a/config/metrics/counts_7d/20210902191054_i_quickactions_unapprove_weekly.yml b/config/metrics/counts_7d/20210902191054_i_quickactions_unapprove_weekly.yml
new file mode 100644
index 00000000000..38659cdba82
--- /dev/null
+++ b/config/metrics/counts_7d/20210902191054_i_quickactions_unapprove_weekly.yml
@@ -0,0 +1,28 @@
+---
+data_category: optional
+key_path: redis_hll_counters.quickactions.i_quickactions_unapprove_weekly
+description: Count of WAU using the `/unapprove` quick action
+product_section: dev
+product_stage: create
+product_group: group::code review
+product_category: code_review
+value_type: number
+status: active
+milestone: "14.3"
+time_frame: 7d
+data_source: redis_hll
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - i_quickactions_unapprove
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - i_quickactions_unapprove
+distribution:
+ - ce
+ - ee
+tier:
+ - free
+ - premium
+ - ultimate
diff --git a/config/metrics/counts_7d/20210908093503_p_ci_templates_android_latest_weekly.yml b/config/metrics/counts_7d/20210908093503_p_ci_templates_android_latest_weekly.yml
new file mode 100644
index 00000000000..6fcf7df4c9b
--- /dev/null
+++ b/config/metrics/counts_7d/20210908093503_p_ci_templates_android_latest_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_android_latest_weekly
+description: ''
+product_section: ''
+product_stage: ''
+product_group: ''
+product_category: ''
+value_type: number
+status: active
+milestone: "14.3"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69204
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_android_latest
diff --git a/config/metrics/counts_7d/20210908151645_i_code_review_user_resolve_thread_in_issue_weekly.yml b/config/metrics/counts_7d/20210908151645_i_code_review_user_resolve_thread_in_issue_weekly.yml
new file mode 100644
index 00000000000..c9d0c92194b
--- /dev/null
+++ b/config/metrics/counts_7d/20210908151645_i_code_review_user_resolve_thread_in_issue_weekly.yml
@@ -0,0 +1,27 @@
+---
+key_path: redis_hll_counters.code_review.i_code_review_user_resolve_thread_in_issue_weekly
+name: resolve_thread_in_issue
+description: The number of users who resolve a thread in a new issue through the MR page weekly
+product_section: dev
+product_stage: create
+product_group: group::code review
+product_category: code_review
+value_type: number
+status: active
+milestone: "14.3"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69879
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - i_code_review_user_resolve_thread_in_issue
+performance_indicator_type: []
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_all/20210201124934_deployments.yml b/config/metrics/counts_all/20210201124934_deployments.yml
index a25586f27e8..edf11470cb3 100644
--- a/config/metrics/counts_all/20210201124934_deployments.yml
+++ b/config/metrics/counts_all/20210201124934_deployments.yml
@@ -6,7 +6,7 @@ product_section: ops
product_stage: release
product_group: group::release
value_type: number
-status: data_available
+status: active
milestone: "8.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/735
time_frame: all
diff --git a/config/metrics/counts_all/20210204124930_servers.yml b/config/metrics/counts_all/20210204124930_servers.yml
index 8012b83b251..16e7504db9c 100644
--- a/config/metrics/counts_all/20210204124930_servers.yml
+++ b/config/metrics/counts_all/20210204124930_servers.yml
@@ -2,16 +2,19 @@
data_category: operational
key_path: gitaly.servers
description: Total Gitalty Servers
-product_section: growth
-product_stage: growth
-product_group: group::product intelligence
-product_category: collection
+product_section: dev
+product_stage: create
+product_group: group::gitaly
+product_category: gitaly
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: database
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210204124932_clusters.yml b/config/metrics/counts_all/20210204124932_clusters.yml
index c5be4a912a6..963726e3a14 100644
--- a/config/metrics/counts_all/20210204124932_clusters.yml
+++ b/config/metrics/counts_all/20210204124932_clusters.yml
@@ -2,16 +2,19 @@
data_category: operational
key_path: gitaly.clusters
description: Total GitLab Managed clusters both enabled and disabled
-product_section: growth
-product_stage: growth
-product_group: group::product intelligence
-product_category: collection
+product_section: dev
+product_stage: create
+product_group: group::gitaly
+product_category: gitaly
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: database
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216174832_cycle_analytics_views.yml b/config/metrics/counts_all/20210216174832_cycle_analytics_views.yml
index 03b58e61f70..324ceb8ec84 100644
--- a/config/metrics/counts_all/20210216174832_cycle_analytics_views.yml
+++ b/config/metrics/counts_all/20210216174832_cycle_analytics_views.yml
@@ -5,9 +5,9 @@ description: Total visits to VSA (both group- and project-level) all time
product_section: dev
product_stage: manage
product_group: group::optimize
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216174846_p_analytics_pipelines.yml b/config/metrics/counts_all/20210216174846_p_analytics_pipelines.yml
index c31b0a9d912..c34f5644053 100644
--- a/config/metrics/counts_all/20210216174846_p_analytics_pipelines.yml
+++ b/config/metrics/counts_all/20210216174846_p_analytics_pipelines.yml
@@ -7,11 +7,14 @@ product_stage: manage
product_group: group::optimize
product_category:
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: redis_hll
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216174850_p_analytics_valuestream.yml b/config/metrics/counts_all/20210216174850_p_analytics_valuestream.yml
index 8fb0041b290..671cd9a10b3 100644
--- a/config/metrics/counts_all/20210216174850_p_analytics_valuestream.yml
+++ b/config/metrics/counts_all/20210216174850_p_analytics_valuestream.yml
@@ -7,11 +7,14 @@ product_stage: manage
product_group: group::optimize
product_category:
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: redis_hll
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216174856_p_analytics_repo.yml b/config/metrics/counts_all/20210216174856_p_analytics_repo.yml
index f70c95b4b35..5e6e308d8d2 100644
--- a/config/metrics/counts_all/20210216174856_p_analytics_repo.yml
+++ b/config/metrics/counts_all/20210216174856_p_analytics_repo.yml
@@ -7,11 +7,14 @@ product_stage: manage
product_group: group::optimize
product_category:
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: redis_hll
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216174858_i_analytics_cohorts.yml b/config/metrics/counts_all/20210216174858_i_analytics_cohorts.yml
index 7bd836eb477..9a06f4c44df 100644
--- a/config/metrics/counts_all/20210216174858_i_analytics_cohorts.yml
+++ b/config/metrics/counts_all/20210216174858_i_analytics_cohorts.yml
@@ -7,11 +7,14 @@ product_stage: manage
product_group: group::optimize
product_category:
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: redis_hll
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216174900_i_analytics_dev_ops_score.yml b/config/metrics/counts_all/20210216174900_i_analytics_dev_ops_score.yml
index 5d2413b9297..9130eb837e7 100644
--- a/config/metrics/counts_all/20210216174900_i_analytics_dev_ops_score.yml
+++ b/config/metrics/counts_all/20210216174900_i_analytics_dev_ops_score.yml
@@ -7,11 +7,14 @@ product_stage: manage
product_group: group::optimize
product_category:
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: redis_hll
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216174902_g_analytics_merge_request.yml b/config/metrics/counts_all/20210216174902_g_analytics_merge_request.yml
index 3fdb40f32d9..c15990a9309 100644
--- a/config/metrics/counts_all/20210216174902_g_analytics_merge_request.yml
+++ b/config/metrics/counts_all/20210216174902_g_analytics_merge_request.yml
@@ -10,9 +10,11 @@ value_type: number
status: removed
time_frame: 7d
data_source: redis_hll
-data_source:
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true \ No newline at end of file
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216174906_i_analytics_instance_statistics.yml b/config/metrics/counts_all/20210216174906_i_analytics_instance_statistics.yml
index dc5d05da04a..5ee75f27529 100644
--- a/config/metrics/counts_all/20210216174906_i_analytics_instance_statistics.yml
+++ b/config/metrics/counts_all/20210216174906_i_analytics_instance_statistics.yml
@@ -7,11 +7,14 @@ product_stage: manage
product_group: group::optimize
product_category:
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: redis_hll
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216174908_analytics_unique_visits_for_any_target.yml b/config/metrics/counts_all/20210216174908_analytics_unique_visits_for_any_target.yml
index 55197013071..488bb48be0e 100644
--- a/config/metrics/counts_all/20210216174908_analytics_unique_visits_for_any_target.yml
+++ b/config/metrics/counts_all/20210216174908_analytics_unique_visits_for_any_target.yml
@@ -5,14 +5,17 @@ description: Unique visitors to any analytics feature by week
product_section: dev
product_stage: manage
product_group: group::optimize
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: redis_hll
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175019_projects_with_prometheus_alerts.yml b/config/metrics/counts_all/20210216175019_projects_with_prometheus_alerts.yml
index 5f03db90f3b..4957376bb26 100644
--- a/config/metrics/counts_all/20210216175019_projects_with_prometheus_alerts.yml
+++ b/config/metrics/counts_all/20210216175019_projects_with_prometheus_alerts.yml
@@ -13,7 +13,10 @@ time_frame: all
data_source: database
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175021_pod_logs_usages_total.yml b/config/metrics/counts_all/20210216175021_pod_logs_usages_total.yml
index 74a39d81941..e228a852d5d 100644
--- a/config/metrics/counts_all/20210216175021_pod_logs_usages_total.yml
+++ b/config/metrics/counts_all/20210216175021_pod_logs_usages_total.yml
@@ -13,7 +13,10 @@ time_frame: all
data_source: database
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175024_service_desk_enabled_projects.yml b/config/metrics/counts_all/20210216175024_service_desk_enabled_projects.yml
index 8cd2a5bd761..6c96cc69601 100644
--- a/config/metrics/counts_all/20210216175024_service_desk_enabled_projects.yml
+++ b/config/metrics/counts_all/20210216175024_service_desk_enabled_projects.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::certify
product_category: service_desk
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -16,3 +16,4 @@ distribution:
tier:
- free
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175026_service_desk_issues.yml b/config/metrics/counts_all/20210216175026_service_desk_issues.yml
index 9e2dc5499b0..139f8716978 100644
--- a/config/metrics/counts_all/20210216175026_service_desk_issues.yml
+++ b/config/metrics/counts_all/20210216175026_service_desk_issues.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::certify
product_category: service_desk
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -16,3 +16,4 @@ distribution:
tier:
- free
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175037_suggestions.yml b/config/metrics/counts_all/20210216175037_suggestions.yml
index 5cd566a3186..a1ba75cd51a 100644
--- a/config/metrics/counts_all/20210216175037_suggestions.yml
+++ b/config/metrics/counts_all/20210216175037_suggestions.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175039_merge_requests.yml b/config/metrics/counts_all/20210216175039_merge_requests.yml
index 1c9a1a0185c..e7d46f138b5 100644
--- a/config/metrics/counts_all/20210216175039_merge_requests.yml
+++ b/config/metrics/counts_all/20210216175039_merge_requests.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175041_merge_request_comment.yml b/config/metrics/counts_all/20210216175041_merge_request_comment.yml
index 0b3bce59176..2e14d7f87ab 100644
--- a/config/metrics/counts_all/20210216175041_merge_request_comment.yml
+++ b/config/metrics/counts_all/20210216175041_merge_request_comment.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175043_merge_request_create.yml b/config/metrics/counts_all/20210216175043_merge_request_create.yml
index 13393b8c1b8..4986a4f3f6e 100644
--- a/config/metrics/counts_all/20210216175043_merge_request_create.yml
+++ b/config/metrics/counts_all/20210216175043_merge_request_create.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175045_merge_requests.yml b/config/metrics/counts_all/20210216175045_merge_requests.yml
index 088df8eca7c..179a6258a15 100644
--- a/config/metrics/counts_all/20210216175045_merge_requests.yml
+++ b/config/metrics/counts_all/20210216175045_merge_requests.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175053_suggestions.yml b/config/metrics/counts_all/20210216175053_suggestions.yml
index f0361655616..f09a64efc0c 100644
--- a/config/metrics/counts_all/20210216175053_suggestions.yml
+++ b/config/metrics/counts_all/20210216175053_suggestions.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175206_merged_merge_requests_using_approval_rules.yml b/config/metrics/counts_all/20210216175206_merged_merge_requests_using_approval_rules.yml
index b5facd08c21..d71c35ef2e2 100644
--- a/config/metrics/counts_all/20210216175206_merged_merge_requests_using_approval_rules.yml
+++ b/config/metrics/counts_all/20210216175206_merged_merge_requests_using_approval_rules.yml
@@ -7,12 +7,15 @@ product_stage: manage
product_group: group::compliance
product_category: compliance_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175229_auto_devops_enabled.yml b/config/metrics/counts_all/20210216175229_auto_devops_enabled.yml
index be8c33d144d..0a26577ae8d 100644
--- a/config/metrics/counts_all/20210216175229_auto_devops_enabled.yml
+++ b/config/metrics/counts_all/20210216175229_auto_devops_enabled.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: counts.auto_devops_enabled
-description: Projects with Auto DevOps template enabled (excluding implicit Auto DevOps enabled and Auto DevOps template includes)
+description: Projects with Auto DevOps template enabled (excluding implicit Auto DevOps
+ enabled and Auto DevOps template includes)
product_section: ops
product_stage: configure
product_group: group::configure
product_category: auto_devops
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175231_auto_devops_disabled.yml b/config/metrics/counts_all/20210216175231_auto_devops_disabled.yml
index 69e9729d825..19089c21eb4 100644
--- a/config/metrics/counts_all/20210216175231_auto_devops_disabled.yml
+++ b/config/metrics/counts_all/20210216175231_auto_devops_disabled.yml
@@ -3,16 +3,19 @@ data_category: optional
key_path: counts.auto_devops_disabled
description: Projects with Auto DevOps template disabled
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: auto_devops
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175232_clusters.yml b/config/metrics/counts_all/20210216175232_clusters.yml
index e6894699827..e642c22a735 100644
--- a/config/metrics/counts_all/20210216175232_clusters.yml
+++ b/config/metrics/counts_all/20210216175232_clusters.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.clusters
description: Total GitLab Managed clusters both enabled and disabled
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175234_clusters_enabled.yml b/config/metrics/counts_all/20210216175234_clusters_enabled.yml
index 6b940dfb5b3..cc230c6a201 100644
--- a/config/metrics/counts_all/20210216175234_clusters_enabled.yml
+++ b/config/metrics/counts_all/20210216175234_clusters_enabled.yml
@@ -7,7 +7,7 @@ product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175236_project_clusters_enabled.yml b/config/metrics/counts_all/20210216175236_project_clusters_enabled.yml
index f0db7b473cf..f12ec1f7301 100644
--- a/config/metrics/counts_all/20210216175236_project_clusters_enabled.yml
+++ b/config/metrics/counts_all/20210216175236_project_clusters_enabled.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.project_clusters_enabled
description: Total GitLab Managed clusters attached to projects
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175238_group_clusters_enabled.yml b/config/metrics/counts_all/20210216175238_group_clusters_enabled.yml
index 6765d24cea8..2fa75d87214 100644
--- a/config/metrics/counts_all/20210216175238_group_clusters_enabled.yml
+++ b/config/metrics/counts_all/20210216175238_group_clusters_enabled.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.group_clusters_enabled
description: Total GitLab Managed clusters attached to groups
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175240_instance_clusters_enabled.yml b/config/metrics/counts_all/20210216175240_instance_clusters_enabled.yml
index afa8a761cf1..201d1f72b8d 100644
--- a/config/metrics/counts_all/20210216175240_instance_clusters_enabled.yml
+++ b/config/metrics/counts_all/20210216175240_instance_clusters_enabled.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.instance_clusters_enabled
description: Total GitLab Managed clusters attached to the instance
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175242_clusters_disabled.yml b/config/metrics/counts_all/20210216175242_clusters_disabled.yml
index 0fac20affd3..00fdee27e2c 100644
--- a/config/metrics/counts_all/20210216175242_clusters_disabled.yml
+++ b/config/metrics/counts_all/20210216175242_clusters_disabled.yml
@@ -7,7 +7,7 @@ product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175244_project_clusters_disabled.yml b/config/metrics/counts_all/20210216175244_project_clusters_disabled.yml
index 2b41f610415..21d704b5090 100644
--- a/config/metrics/counts_all/20210216175244_project_clusters_disabled.yml
+++ b/config/metrics/counts_all/20210216175244_project_clusters_disabled.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.project_clusters_disabled
description: Total GitLab Managed disabled clusters previously attached to projects
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175246_group_clusters_disabled.yml b/config/metrics/counts_all/20210216175246_group_clusters_disabled.yml
index b7a839f345a..b31c129496c 100644
--- a/config/metrics/counts_all/20210216175246_group_clusters_disabled.yml
+++ b/config/metrics/counts_all/20210216175246_group_clusters_disabled.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.group_clusters_disabled
description: Total GitLab Managed disabled clusters previously attached to groups
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175248_instance_clusters_disabled.yml b/config/metrics/counts_all/20210216175248_instance_clusters_disabled.yml
index 94b5d48dffa..e60c7a13fcf 100644
--- a/config/metrics/counts_all/20210216175248_instance_clusters_disabled.yml
+++ b/config/metrics/counts_all/20210216175248_instance_clusters_disabled.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.instance_clusters_disabled
description: Total GitLab Managed disabled clusters previously attached to the instance
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175250_clusters_platforms_eks.yml b/config/metrics/counts_all/20210216175250_clusters_platforms_eks.yml
index 1470dbe809f..343275db3f7 100644
--- a/config/metrics/counts_all/20210216175250_clusters_platforms_eks.yml
+++ b/config/metrics/counts_all/20210216175250_clusters_platforms_eks.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.clusters_platforms_eks
description: Total GitLab Managed clusters provisioned with GitLab on AWS EKS
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175251_clusters_platforms_gke.yml b/config/metrics/counts_all/20210216175251_clusters_platforms_gke.yml
index 6f1692cc2b6..4f7c85953ed 100644
--- a/config/metrics/counts_all/20210216175251_clusters_platforms_gke.yml
+++ b/config/metrics/counts_all/20210216175251_clusters_platforms_gke.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.clusters_platforms_gke
description: Total GitLab Managed clusters provisioned with GitLab on GCE GKE
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175253_clusters_platforms_user.yml b/config/metrics/counts_all/20210216175253_clusters_platforms_user.yml
index eaeff4aa3a0..c0cce763b21 100644
--- a/config/metrics/counts_all/20210216175253_clusters_platforms_user.yml
+++ b/config/metrics/counts_all/20210216175253_clusters_platforms_user.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.clusters_platforms_user
description: Total GitLab Managed clusters that are user provisioned
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175255_clusters_applications_helm.yml b/config/metrics/counts_all/20210216175255_clusters_applications_helm.yml
index bb85d43bc63..661d809ae65 100644
--- a/config/metrics/counts_all/20210216175255_clusters_applications_helm.yml
+++ b/config/metrics/counts_all/20210216175255_clusters_applications_helm.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.clusters_applications_helm
description: Total GitLab Managed clusters with GitLab Managed App:Helm enabled
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175257_clusters_applications_ingress.yml b/config/metrics/counts_all/20210216175257_clusters_applications_ingress.yml
index 87b412b45f6..889e701a8d7 100644
--- a/config/metrics/counts_all/20210216175257_clusters_applications_ingress.yml
+++ b/config/metrics/counts_all/20210216175257_clusters_applications_ingress.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.clusters_applications_ingress
description: Total GitLab Managed clusters with GitLab Managed App:Ingress installed
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175259_clusters_applications_cert_managers.yml b/config/metrics/counts_all/20210216175259_clusters_applications_cert_managers.yml
index f93f0e73e9d..a22cf9dd848 100644
--- a/config/metrics/counts_all/20210216175259_clusters_applications_cert_managers.yml
+++ b/config/metrics/counts_all/20210216175259_clusters_applications_cert_managers.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.clusters_applications_cert_managers
description: Total GitLab Managed clusters with GitLab Managed App:Cert Manager installed
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175301_clusters_applications_crossplane.yml b/config/metrics/counts_all/20210216175301_clusters_applications_crossplane.yml
index b365dabe466..1fc50c89bdc 100644
--- a/config/metrics/counts_all/20210216175301_clusters_applications_crossplane.yml
+++ b/config/metrics/counts_all/20210216175301_clusters_applications_crossplane.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.clusters_applications_crossplane
description: Total GitLab Managed clusters with GitLab Managed App:Crossplane installed
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175303_clusters_applications_prometheus.yml b/config/metrics/counts_all/20210216175303_clusters_applications_prometheus.yml
index 7d86d5da125..b883f9cdd1b 100644
--- a/config/metrics/counts_all/20210216175303_clusters_applications_prometheus.yml
+++ b/config/metrics/counts_all/20210216175303_clusters_applications_prometheus.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.clusters_applications_prometheus
description: Total GitLab Managed clusters with GitLab Managed App:Prometheus installed
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175305_clusters_applications_runner.yml b/config/metrics/counts_all/20210216175305_clusters_applications_runner.yml
index d10f2bb240a..5f9c9a9c0d0 100644
--- a/config/metrics/counts_all/20210216175305_clusters_applications_runner.yml
+++ b/config/metrics/counts_all/20210216175305_clusters_applications_runner.yml
@@ -7,7 +7,7 @@ product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175307_clusters_applications_knative.yml b/config/metrics/counts_all/20210216175307_clusters_applications_knative.yml
index a92b043622d..8b5f50c6c7f 100644
--- a/config/metrics/counts_all/20210216175307_clusters_applications_knative.yml
+++ b/config/metrics/counts_all/20210216175307_clusters_applications_knative.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.clusters_applications_knative
description: Total GitLab Managed clusters with GitLab Managed App:Knative installed
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175309_clusters_applications_elastic_stack.yml b/config/metrics/counts_all/20210216175309_clusters_applications_elastic_stack.yml
index 9f94bf9ff30..fafbf8a7d47 100644
--- a/config/metrics/counts_all/20210216175309_clusters_applications_elastic_stack.yml
+++ b/config/metrics/counts_all/20210216175309_clusters_applications_elastic_stack.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.clusters_applications_elastic_stack
description: Total GitLab Managed clusters with GitLab Managed App:Elastic Stack installed
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175310_clusters_applications_jupyter.yml b/config/metrics/counts_all/20210216175310_clusters_applications_jupyter.yml
index 8501a763454..89c8116f0d8 100644
--- a/config/metrics/counts_all/20210216175310_clusters_applications_jupyter.yml
+++ b/config/metrics/counts_all/20210216175310_clusters_applications_jupyter.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.clusters_applications_jupyter
description: Total GitLab Managed clusters with GitLab Managed App:Jupyter installed
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175312_clusters_applications_cilium.yml b/config/metrics/counts_all/20210216175312_clusters_applications_cilium.yml
index f0157783235..faf7f486d32 100644
--- a/config/metrics/counts_all/20210216175312_clusters_applications_cilium.yml
+++ b/config/metrics/counts_all/20210216175312_clusters_applications_cilium.yml
@@ -3,11 +3,11 @@ data_category: operational
key_path: counts.clusters_applications_cilium
description: Total GitLab Managed clusters with GitLab Managed App:Cilium installed
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175314_clusters_management_project.yml b/config/metrics/counts_all/20210216175314_clusters_management_project.yml
index c6dbd9469c1..fb8421d4bf2 100644
--- a/config/metrics/counts_all/20210216175314_clusters_management_project.yml
+++ b/config/metrics/counts_all/20210216175314_clusters_management_project.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.clusters_management_project
description: Total GitLab Managed clusters with defined cluster management project
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175320_projects_with_terraform_reports.yml b/config/metrics/counts_all/20210216175320_projects_with_terraform_reports.yml
index 9fc55da3b64..1008e17211d 100644
--- a/config/metrics/counts_all/20210216175320_projects_with_terraform_reports.yml
+++ b/config/metrics/counts_all/20210216175320_projects_with_terraform_reports.yml
@@ -7,7 +7,7 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175322_projects_with_terraform_states.yml b/config/metrics/counts_all/20210216175322_projects_with_terraform_states.yml
index b7ea1a99a1f..14621390630 100644
--- a/config/metrics/counts_all/20210216175322_projects_with_terraform_states.yml
+++ b/config/metrics/counts_all/20210216175322_projects_with_terraform_states.yml
@@ -7,7 +7,7 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175324_terraform_reports.yml b/config/metrics/counts_all/20210216175324_terraform_reports.yml
index 7694a8fd2fd..69e21a7d63e 100644
--- a/config/metrics/counts_all/20210216175324_terraform_reports.yml
+++ b/config/metrics/counts_all/20210216175324_terraform_reports.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.terraform_reports
description: Count of Terraform MR reports generated
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175326_terraform_states.yml b/config/metrics/counts_all/20210216175326_terraform_states.yml
index 0c1c27335cc..06b6e6d7928 100644
--- a/config/metrics/counts_all/20210216175326_terraform_states.yml
+++ b/config/metrics/counts_all/20210216175326_terraform_states.yml
@@ -7,7 +7,7 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175329_clusters_applications_cert_managers.yml b/config/metrics/counts_all/20210216175329_clusters_applications_cert_managers.yml
index a9f0eb521d9..185ab921fd6 100644
--- a/config/metrics/counts_all/20210216175329_clusters_applications_cert_managers.yml
+++ b/config/metrics/counts_all/20210216175329_clusters_applications_cert_managers.yml
@@ -3,13 +3,13 @@ data_category: optional
key_path: usage_activity_by_stage.configure.clusters_applications_cert_managers
description: Total GitLab Managed clusters with GitLab Managed App:Cert Manager installed
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,4 +17,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175331_clusters_applications_helm.yml b/config/metrics/counts_all/20210216175331_clusters_applications_helm.yml
index 44ff075ea0e..4561338a3cb 100644
--- a/config/metrics/counts_all/20210216175331_clusters_applications_helm.yml
+++ b/config/metrics/counts_all/20210216175331_clusters_applications_helm.yml
@@ -3,13 +3,13 @@ data_category: optional
key_path: usage_activity_by_stage.configure.clusters_applications_helm
description: Total GitLab Managed clusters with GitLab Managed App:Helm enabled
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,4 +17,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175333_clusters_applications_ingress.yml b/config/metrics/counts_all/20210216175333_clusters_applications_ingress.yml
index 9b92d67d09b..8336b6a4048 100644
--- a/config/metrics/counts_all/20210216175333_clusters_applications_ingress.yml
+++ b/config/metrics/counts_all/20210216175333_clusters_applications_ingress.yml
@@ -3,13 +3,13 @@ data_category: optional
key_path: usage_activity_by_stage.configure.clusters_applications_ingress
description: Total GitLab Managed clusters with GitLab Managed App:Ingress installed
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,4 +17,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175335_clusters_applications_knative.yml b/config/metrics/counts_all/20210216175335_clusters_applications_knative.yml
index 5bd5d52f8ab..c5979093a18 100644
--- a/config/metrics/counts_all/20210216175335_clusters_applications_knative.yml
+++ b/config/metrics/counts_all/20210216175335_clusters_applications_knative.yml
@@ -3,13 +3,13 @@ data_category: optional
key_path: usage_activity_by_stage.configure.clusters_applications_knative
description: Total GitLab Managed clusters with GitLab Managed App:Knative installed
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,4 +17,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175337_clusters_management_project.yml b/config/metrics/counts_all/20210216175337_clusters_management_project.yml
index f137981b7fd..8ed91a5e0f0 100644
--- a/config/metrics/counts_all/20210216175337_clusters_management_project.yml
+++ b/config/metrics/counts_all/20210216175337_clusters_management_project.yml
@@ -3,13 +3,13 @@ data_category: optional
key_path: usage_activity_by_stage.configure.clusters_management_project
description: Total GitLab Managed clusters with defined cluster management project
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,4 +17,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175339_clusters_disabled.yml b/config/metrics/counts_all/20210216175339_clusters_disabled.yml
index 15becf3a739..5490df2a311 100644
--- a/config/metrics/counts_all/20210216175339_clusters_disabled.yml
+++ b/config/metrics/counts_all/20210216175339_clusters_disabled.yml
@@ -3,13 +3,13 @@ data_category: optional
key_path: usage_activity_by_stage.configure.clusters_disabled
description: Total GitLab Managed disabled clusters
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,4 +17,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175341_clusters_enabled.yml b/config/metrics/counts_all/20210216175341_clusters_enabled.yml
index 2a5d932ccf5..a5b64e3490b 100644
--- a/config/metrics/counts_all/20210216175341_clusters_enabled.yml
+++ b/config/metrics/counts_all/20210216175341_clusters_enabled.yml
@@ -3,13 +3,13 @@ data_category: optional
key_path: usage_activity_by_stage.configure.clusters_enabled
description: Total GitLab Managed clusters currently enabled
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,4 +17,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175343_clusters_platforms_gke.yml b/config/metrics/counts_all/20210216175343_clusters_platforms_gke.yml
index 2847e56bbcf..3be2ae9259b 100644
--- a/config/metrics/counts_all/20210216175343_clusters_platforms_gke.yml
+++ b/config/metrics/counts_all/20210216175343_clusters_platforms_gke.yml
@@ -3,13 +3,13 @@ data_category: optional
key_path: usage_activity_by_stage.configure.clusters_platforms_gke
description: Total GitLab Managed clusters provisioned with GitLab on GCE GKE
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,4 +17,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175345_clusters_platforms_eks.yml b/config/metrics/counts_all/20210216175345_clusters_platforms_eks.yml
index 52af7411aae..898db74ceed 100644
--- a/config/metrics/counts_all/20210216175345_clusters_platforms_eks.yml
+++ b/config/metrics/counts_all/20210216175345_clusters_platforms_eks.yml
@@ -3,13 +3,13 @@ data_category: optional
key_path: usage_activity_by_stage.configure.clusters_platforms_eks
description: Total GitLab Managed clusters provisioned with GitLab on AWS EKS
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,4 +17,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175346_clusters_platforms_user.yml b/config/metrics/counts_all/20210216175346_clusters_platforms_user.yml
index 53ec5375937..d6fe1d162c4 100644
--- a/config/metrics/counts_all/20210216175346_clusters_platforms_user.yml
+++ b/config/metrics/counts_all/20210216175346_clusters_platforms_user.yml
@@ -3,13 +3,13 @@ data_category: optional
key_path: usage_activity_by_stage.configure.clusters_platforms_user
description: Total GitLab Managed clusters that are user provisioned
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,4 +17,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175348_instance_clusters_disabled.yml b/config/metrics/counts_all/20210216175348_instance_clusters_disabled.yml
index 27826144191..4c8c3ccac9d 100644
--- a/config/metrics/counts_all/20210216175348_instance_clusters_disabled.yml
+++ b/config/metrics/counts_all/20210216175348_instance_clusters_disabled.yml
@@ -3,13 +3,13 @@ data_category: optional
key_path: usage_activity_by_stage.configure.instance_clusters_disabled
description: Total GitLab Managed disabled clusters attached to the instance
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,4 +17,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175350_instance_clusters_enabled.yml b/config/metrics/counts_all/20210216175350_instance_clusters_enabled.yml
index 4e26fef5e62..4f065bb0506 100644
--- a/config/metrics/counts_all/20210216175350_instance_clusters_enabled.yml
+++ b/config/metrics/counts_all/20210216175350_instance_clusters_enabled.yml
@@ -3,13 +3,13 @@ data_category: optional
key_path: usage_activity_by_stage.configure.instance_clusters_enabled
description: Total GitLab Managed enabled clusters attached to the instance
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,4 +17,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175352_group_clusters_disabled.yml b/config/metrics/counts_all/20210216175352_group_clusters_disabled.yml
index 07651126a41..902fd31a5f3 100644
--- a/config/metrics/counts_all/20210216175352_group_clusters_disabled.yml
+++ b/config/metrics/counts_all/20210216175352_group_clusters_disabled.yml
@@ -3,13 +3,13 @@ data_category: optional
key_path: usage_activity_by_stage.configure.group_clusters_disabled
description: Total GitLab Managed disabled clusters attached to groups
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,4 +17,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175354_group_clusters_enabled.yml b/config/metrics/counts_all/20210216175354_group_clusters_enabled.yml
index 72182fde574..197f0a7ea1b 100644
--- a/config/metrics/counts_all/20210216175354_group_clusters_enabled.yml
+++ b/config/metrics/counts_all/20210216175354_group_clusters_enabled.yml
@@ -3,13 +3,13 @@ data_category: optional
key_path: usage_activity_by_stage.configure.group_clusters_enabled
description: Total GitLab Managed enabled clusters attached to groups
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,4 +17,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175356_project_clusters_disabled.yml b/config/metrics/counts_all/20210216175356_project_clusters_disabled.yml
index a8b21924a1b..cd406c21eed 100644
--- a/config/metrics/counts_all/20210216175356_project_clusters_disabled.yml
+++ b/config/metrics/counts_all/20210216175356_project_clusters_disabled.yml
@@ -3,13 +3,13 @@ data_category: optional
key_path: usage_activity_by_stage.configure.project_clusters_disabled
description: Total GitLab Managed disabled clusters attached to projects
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,4 +17,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175358_project_clusters_enabled.yml b/config/metrics/counts_all/20210216175358_project_clusters_enabled.yml
index 80ac8ff67e3..e106a31c4b6 100644
--- a/config/metrics/counts_all/20210216175358_project_clusters_enabled.yml
+++ b/config/metrics/counts_all/20210216175358_project_clusters_enabled.yml
@@ -3,13 +3,13 @@ data_category: optional
key_path: usage_activity_by_stage.configure.project_clusters_enabled
description: Total GitLab Managed enabled clusters attached to projects
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -17,4 +17,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175403_projects_with_prometheus_alerts.yml b/config/metrics/counts_all/20210216175403_projects_with_prometheus_alerts.yml
index ab1a286bc0c..71a38117826 100644
--- a/config/metrics/counts_all/20210216175403_projects_with_prometheus_alerts.yml
+++ b/config/metrics/counts_all/20210216175403_projects_with_prometheus_alerts.yml
@@ -3,14 +3,14 @@ data_category: optional
key_path: usage_activity_by_stage.configure.projects_with_prometheus_alerts
description: Projects with Prometheus alerting enabled
product_section: ops
-product_stage:
+product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
status: removed
milestone_removed: '14.0'
time_frame: all
-data_source:
+data_source: database
distribution:
- ce
- ee
@@ -18,4 +18,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175442_ingress_modsecurity_packets_processed.yml b/config/metrics/counts_all/20210216175442_ingress_modsecurity_packets_processed.yml
index 7e9b163f23a..ef8bb634b85 100644
--- a/config/metrics/counts_all/20210216175442_ingress_modsecurity_packets_processed.yml
+++ b/config/metrics/counts_all/20210216175442_ingress_modsecurity_packets_processed.yml
@@ -20,3 +20,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175444_ingress_modsecurity_packets_anomalous.yml b/config/metrics/counts_all/20210216175444_ingress_modsecurity_packets_anomalous.yml
index 23c3beb2812..067ac95782f 100644
--- a/config/metrics/counts_all/20210216175444_ingress_modsecurity_packets_anomalous.yml
+++ b/config/metrics/counts_all/20210216175444_ingress_modsecurity_packets_anomalous.yml
@@ -20,3 +20,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175446_network_policy_forwards.yml b/config/metrics/counts_all/20210216175446_network_policy_forwards.yml
index 1b3448efecc..ef2b37bb001 100644
--- a/config/metrics/counts_all/20210216175446_network_policy_forwards.yml
+++ b/config/metrics/counts_all/20210216175446_network_policy_forwards.yml
@@ -8,7 +8,7 @@ product_stage: protect
product_group: group::container security
product_category: container_network_security
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175448_network_policy_drops.yml b/config/metrics/counts_all/20210216175448_network_policy_drops.yml
index 54b947599a9..933363c0a14 100644
--- a/config/metrics/counts_all/20210216175448_network_policy_drops.yml
+++ b/config/metrics/counts_all/20210216175448_network_policy_drops.yml
@@ -8,7 +8,7 @@ product_stage: protect
product_group: group::container security
product_category: container_network_security
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175450_ingress_modsecurity_logging.yml b/config/metrics/counts_all/20210216175450_ingress_modsecurity_logging.yml
index 8db0a0bd4d6..55dc3b6ca3b 100644
--- a/config/metrics/counts_all/20210216175450_ingress_modsecurity_logging.yml
+++ b/config/metrics/counts_all/20210216175450_ingress_modsecurity_logging.yml
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175452_ingress_modsecurity_blocking.yml b/config/metrics/counts_all/20210216175452_ingress_modsecurity_blocking.yml
index a663a49b88e..c21b1d24885 100644
--- a/config/metrics/counts_all/20210216175452_ingress_modsecurity_blocking.yml
+++ b/config/metrics/counts_all/20210216175452_ingress_modsecurity_blocking.yml
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175454_ingress_modsecurity_disabled.yml b/config/metrics/counts_all/20210216175454_ingress_modsecurity_disabled.yml
index 44bf44bd20a..a4f4910cf76 100644
--- a/config/metrics/counts_all/20210216175454_ingress_modsecurity_disabled.yml
+++ b/config/metrics/counts_all/20210216175454_ingress_modsecurity_disabled.yml
@@ -18,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175456_ingress_modsecurity_not_installed.yml b/config/metrics/counts_all/20210216175456_ingress_modsecurity_not_installed.yml
index 7de28e42533..4a3717786be 100644
--- a/config/metrics/counts_all/20210216175456_ingress_modsecurity_not_installed.yml
+++ b/config/metrics/counts_all/20210216175456_ingress_modsecurity_not_installed.yml
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175510_ci_builds.yml b/config/metrics/counts_all/20210216175510_ci_builds.yml
index 74f9d3963a7..d4d566eef00 100644
--- a/config/metrics/counts_all/20210216175510_ci_builds.yml
+++ b/config/metrics/counts_all/20210216175510_ci_builds.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175512_ci_internal_pipelines.yml b/config/metrics/counts_all/20210216175512_ci_internal_pipelines.yml
index 85db2d7eed1..fbe697fc77b 100644
--- a/config/metrics/counts_all/20210216175512_ci_internal_pipelines.yml
+++ b/config/metrics/counts_all/20210216175512_ci_internal_pipelines.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175514_ci_external_pipelines.yml b/config/metrics/counts_all/20210216175514_ci_external_pipelines.yml
index 31f948b0eb7..b27115aa904 100644
--- a/config/metrics/counts_all/20210216175514_ci_external_pipelines.yml
+++ b/config/metrics/counts_all/20210216175514_ci_external_pipelines.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -15,3 +15,4 @@ distribution:
tier:
- free
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175516_ci_pipeline_config_auto_devops.yml b/config/metrics/counts_all/20210216175516_ci_pipeline_config_auto_devops.yml
index e3a379ed21e..d5bfa361905 100644
--- a/config/metrics/counts_all/20210216175516_ci_pipeline_config_auto_devops.yml
+++ b/config/metrics/counts_all/20210216175516_ci_pipeline_config_auto_devops.yml
@@ -7,7 +7,7 @@ product_stage: configure
product_group: group::configure
product_category: auto_devops
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175518_ci_pipeline_config_repository.yml b/config/metrics/counts_all/20210216175518_ci_pipeline_config_repository.yml
index 1c03e614c6e..cf850f26d42 100644
--- a/config/metrics/counts_all/20210216175518_ci_pipeline_config_repository.yml
+++ b/config/metrics/counts_all/20210216175518_ci_pipeline_config_repository.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175520_ci_runners.yml b/config/metrics/counts_all/20210216175520_ci_runners.yml
index 185783bf693..e402391f9ba 100644
--- a/config/metrics/counts_all/20210216175520_ci_runners.yml
+++ b/config/metrics/counts_all/20210216175520_ci_runners.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175521_ci_triggers.yml b/config/metrics/counts_all/20210216175521_ci_triggers.yml
index b6452ca45f2..7b8f54f0e25 100644
--- a/config/metrics/counts_all/20210216175521_ci_triggers.yml
+++ b/config/metrics/counts_all/20210216175521_ci_triggers.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175523_ci_pipeline_schedules.yml b/config/metrics/counts_all/20210216175523_ci_pipeline_schedules.yml
index f136cb35ac5..7917c26b8f9 100644
--- a/config/metrics/counts_all/20210216175523_ci_pipeline_schedules.yml
+++ b/config/metrics/counts_all/20210216175523_ci_pipeline_schedules.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175525_ci_builds.yml b/config/metrics/counts_all/20210216175525_ci_builds.yml
index 3b857e8bb0d..885996afdf9 100644
--- a/config/metrics/counts_all/20210216175525_ci_builds.yml
+++ b/config/metrics/counts_all/20210216175525_ci_builds.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175527_ci_external_pipelines.yml b/config/metrics/counts_all/20210216175527_ci_external_pipelines.yml
index 827bcbcd2e2..531f402ce0a 100644
--- a/config/metrics/counts_all/20210216175527_ci_external_pipelines.yml
+++ b/config/metrics/counts_all/20210216175527_ci_external_pipelines.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175529_ci_internal_pipelines.yml b/config/metrics/counts_all/20210216175529_ci_internal_pipelines.yml
index 1e1a1ee7af3..b58e49b2603 100644
--- a/config/metrics/counts_all/20210216175529_ci_internal_pipelines.yml
+++ b/config/metrics/counts_all/20210216175529_ci_internal_pipelines.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175531_ci_pipeline_config_auto_devops.yml b/config/metrics/counts_all/20210216175531_ci_pipeline_config_auto_devops.yml
index 3b9790f9b71..982fe4799e8 100644
--- a/config/metrics/counts_all/20210216175531_ci_pipeline_config_auto_devops.yml
+++ b/config/metrics/counts_all/20210216175531_ci_pipeline_config_auto_devops.yml
@@ -7,7 +7,7 @@ product_stage: configure
product_group: group::configure
product_category: auto_devops
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175533_ci_pipeline_config_repository.yml b/config/metrics/counts_all/20210216175533_ci_pipeline_config_repository.yml
index 6763d3f0f10..269acb1105e 100644
--- a/config/metrics/counts_all/20210216175533_ci_pipeline_config_repository.yml
+++ b/config/metrics/counts_all/20210216175533_ci_pipeline_config_repository.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,4 +17,4 @@ tier:
- free
- premium
- ultimate
-
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175535_ci_pipeline_schedules.yml b/config/metrics/counts_all/20210216175535_ci_pipeline_schedules.yml
index 3c882f1f759..82084178273 100644
--- a/config/metrics/counts_all/20210216175535_ci_pipeline_schedules.yml
+++ b/config/metrics/counts_all/20210216175535_ci_pipeline_schedules.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175537_ci_pipelines.yml b/config/metrics/counts_all/20210216175537_ci_pipelines.yml
index f6fb62945f0..0a5e5ff0269 100644
--- a/config/metrics/counts_all/20210216175537_ci_pipelines.yml
+++ b/config/metrics/counts_all/20210216175537_ci_pipelines.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175539_ci_triggers.yml b/config/metrics/counts_all/20210216175539_ci_triggers.yml
index 5a0e630993c..76824228a41 100644
--- a/config/metrics/counts_all/20210216175539_ci_triggers.yml
+++ b/config/metrics/counts_all/20210216175539_ci_triggers.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175621_web_hooks.yml b/config/metrics/counts_all/20210216175621_web_hooks.yml
index 9c7f000ae50..326c1f08539 100644
--- a/config/metrics/counts_all/20210216175621_web_hooks.yml
+++ b/config/metrics/counts_all/20210216175621_web_hooks.yml
@@ -1,18 +1,21 @@
---
data_category: optional
key_path: counts.web_hooks
-description:
+description: Count of web hooks
product_section: dev
product_stage: ecosystem
product_group: group::integrations
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175623_projects_asana_active.yml b/config/metrics/counts_all/20210216175623_projects_asana_active.yml
index 67b7ef98471..ca0ff0cdaf7 100644
--- a/config/metrics/counts_all/20210216175623_projects_asana_active.yml
+++ b/config/metrics/counts_all/20210216175623_projects_asana_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175625_groups_asana_active.yml b/config/metrics/counts_all/20210216175625_groups_asana_active.yml
index 2fa25aa0bc1..3c1cd0378d0 100644
--- a/config/metrics/counts_all/20210216175625_groups_asana_active.yml
+++ b/config/metrics/counts_all/20210216175625_groups_asana_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175627_templates_asana_active.yml b/config/metrics/counts_all/20210216175627_templates_asana_active.yml
index e0348f0760b..48025516d32 100644
--- a/config/metrics/counts_all/20210216175627_templates_asana_active.yml
+++ b/config/metrics/counts_all/20210216175627_templates_asana_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175628_instances_asana_active.yml b/config/metrics/counts_all/20210216175628_instances_asana_active.yml
index daad2b4f7ad..ab2a7ab1fd8 100644
--- a/config/metrics/counts_all/20210216175628_instances_asana_active.yml
+++ b/config/metrics/counts_all/20210216175628_instances_asana_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175630_projects_inheriting_asana_active.yml b/config/metrics/counts_all/20210216175630_projects_inheriting_asana_active.yml
index adfe86ba5e0..fd79b15fd68 100644
--- a/config/metrics/counts_all/20210216175630_projects_inheriting_asana_active.yml
+++ b/config/metrics/counts_all/20210216175630_projects_inheriting_asana_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175632_groups_inheriting_asana_active.yml b/config/metrics/counts_all/20210216175632_groups_inheriting_asana_active.yml
index c08e3762d53..5f8203fda4b 100644
--- a/config/metrics/counts_all/20210216175632_groups_inheriting_asana_active.yml
+++ b/config/metrics/counts_all/20210216175632_groups_inheriting_asana_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175634_projects_assembla_active.yml b/config/metrics/counts_all/20210216175634_projects_assembla_active.yml
index 892b7723ba0..6d98db7ab3c 100644
--- a/config/metrics/counts_all/20210216175634_projects_assembla_active.yml
+++ b/config/metrics/counts_all/20210216175634_projects_assembla_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175636_groups_assembla_active.yml b/config/metrics/counts_all/20210216175636_groups_assembla_active.yml
index 7a0a02c3f34..e04faffc57f 100644
--- a/config/metrics/counts_all/20210216175636_groups_assembla_active.yml
+++ b/config/metrics/counts_all/20210216175636_groups_assembla_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175638_templates_assembla_active.yml b/config/metrics/counts_all/20210216175638_templates_assembla_active.yml
index c0867387261..1ab0d42a5ee 100644
--- a/config/metrics/counts_all/20210216175638_templates_assembla_active.yml
+++ b/config/metrics/counts_all/20210216175638_templates_assembla_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175640_instances_assembla_active.yml b/config/metrics/counts_all/20210216175640_instances_assembla_active.yml
index 9ae2d48a683..ee2ff3254cc 100644
--- a/config/metrics/counts_all/20210216175640_instances_assembla_active.yml
+++ b/config/metrics/counts_all/20210216175640_instances_assembla_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175642_projects_inheriting_assembla_active.yml b/config/metrics/counts_all/20210216175642_projects_inheriting_assembla_active.yml
index ec1402be55d..c67864be199 100644
--- a/config/metrics/counts_all/20210216175642_projects_inheriting_assembla_active.yml
+++ b/config/metrics/counts_all/20210216175642_projects_inheriting_assembla_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175644_groups_inheriting_assembla_active.yml b/config/metrics/counts_all/20210216175644_groups_inheriting_assembla_active.yml
index eed75f72abd..4d220c45a70 100644
--- a/config/metrics/counts_all/20210216175644_groups_inheriting_assembla_active.yml
+++ b/config/metrics/counts_all/20210216175644_groups_inheriting_assembla_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175645_projects_bamboo_active.yml b/config/metrics/counts_all/20210216175645_projects_bamboo_active.yml
index 0d7f1b4b22f..2f5fa08d325 100644
--- a/config/metrics/counts_all/20210216175645_projects_bamboo_active.yml
+++ b/config/metrics/counts_all/20210216175645_projects_bamboo_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175647_groups_bamboo_active.yml b/config/metrics/counts_all/20210216175647_groups_bamboo_active.yml
index e6379a4bfed..c136a7b1c41 100644
--- a/config/metrics/counts_all/20210216175647_groups_bamboo_active.yml
+++ b/config/metrics/counts_all/20210216175647_groups_bamboo_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175649_templates_bamboo_active.yml b/config/metrics/counts_all/20210216175649_templates_bamboo_active.yml
index e3c0882e781..85b10732ae8 100644
--- a/config/metrics/counts_all/20210216175649_templates_bamboo_active.yml
+++ b/config/metrics/counts_all/20210216175649_templates_bamboo_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175651_instances_bamboo_active.yml b/config/metrics/counts_all/20210216175651_instances_bamboo_active.yml
index 61af43bb5e4..d7a266eceb8 100644
--- a/config/metrics/counts_all/20210216175651_instances_bamboo_active.yml
+++ b/config/metrics/counts_all/20210216175651_instances_bamboo_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175653_projects_inheriting_bamboo_active.yml b/config/metrics/counts_all/20210216175653_projects_inheriting_bamboo_active.yml
index 5670c7dd7b1..69f8205923c 100644
--- a/config/metrics/counts_all/20210216175653_projects_inheriting_bamboo_active.yml
+++ b/config/metrics/counts_all/20210216175653_projects_inheriting_bamboo_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175655_groups_inheriting_bamboo_active.yml b/config/metrics/counts_all/20210216175655_groups_inheriting_bamboo_active.yml
index e71b6d1d89e..6c71d922567 100644
--- a/config/metrics/counts_all/20210216175655_groups_inheriting_bamboo_active.yml
+++ b/config/metrics/counts_all/20210216175655_groups_inheriting_bamboo_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175657_projects_bugzilla_active.yml b/config/metrics/counts_all/20210216175657_projects_bugzilla_active.yml
index 16af8eb9792..e4869d575a1 100644
--- a/config/metrics/counts_all/20210216175657_projects_bugzilla_active.yml
+++ b/config/metrics/counts_all/20210216175657_projects_bugzilla_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175659_groups_bugzilla_active.yml b/config/metrics/counts_all/20210216175659_groups_bugzilla_active.yml
index fe14026cd09..433eb3f248c 100644
--- a/config/metrics/counts_all/20210216175659_groups_bugzilla_active.yml
+++ b/config/metrics/counts_all/20210216175659_groups_bugzilla_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175701_templates_bugzilla_active.yml b/config/metrics/counts_all/20210216175701_templates_bugzilla_active.yml
index 99426d2a418..bc5a1238010 100644
--- a/config/metrics/counts_all/20210216175701_templates_bugzilla_active.yml
+++ b/config/metrics/counts_all/20210216175701_templates_bugzilla_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175702_instances_bugzilla_active.yml b/config/metrics/counts_all/20210216175702_instances_bugzilla_active.yml
index f727c33a009..89aac1d7bb8 100644
--- a/config/metrics/counts_all/20210216175702_instances_bugzilla_active.yml
+++ b/config/metrics/counts_all/20210216175702_instances_bugzilla_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175704_projects_inheriting_bugzilla_active.yml b/config/metrics/counts_all/20210216175704_projects_inheriting_bugzilla_active.yml
index 375680322fc..c85fdde5970 100644
--- a/config/metrics/counts_all/20210216175704_projects_inheriting_bugzilla_active.yml
+++ b/config/metrics/counts_all/20210216175704_projects_inheriting_bugzilla_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175706_groups_inheriting_bugzilla_active.yml b/config/metrics/counts_all/20210216175706_groups_inheriting_bugzilla_active.yml
index 58a5665b089..9b9e49052c0 100644
--- a/config/metrics/counts_all/20210216175706_groups_inheriting_bugzilla_active.yml
+++ b/config/metrics/counts_all/20210216175706_groups_inheriting_bugzilla_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175708_projects_buildkite_active.yml b/config/metrics/counts_all/20210216175708_projects_buildkite_active.yml
index 36ccdfc3bb4..cd99e26434e 100644
--- a/config/metrics/counts_all/20210216175708_projects_buildkite_active.yml
+++ b/config/metrics/counts_all/20210216175708_projects_buildkite_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175710_groups_buildkite_active.yml b/config/metrics/counts_all/20210216175710_groups_buildkite_active.yml
index eef27850d5e..fde47913509 100644
--- a/config/metrics/counts_all/20210216175710_groups_buildkite_active.yml
+++ b/config/metrics/counts_all/20210216175710_groups_buildkite_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175712_templates_buildkite_active.yml b/config/metrics/counts_all/20210216175712_templates_buildkite_active.yml
index 70b1f66c6f2..16287a4e71a 100644
--- a/config/metrics/counts_all/20210216175712_templates_buildkite_active.yml
+++ b/config/metrics/counts_all/20210216175712_templates_buildkite_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175714_instances_buildkite_active.yml b/config/metrics/counts_all/20210216175714_instances_buildkite_active.yml
index ce52864f710..ee905ce7668 100644
--- a/config/metrics/counts_all/20210216175714_instances_buildkite_active.yml
+++ b/config/metrics/counts_all/20210216175714_instances_buildkite_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175716_projects_inheriting_buildkite_active.yml b/config/metrics/counts_all/20210216175716_projects_inheriting_buildkite_active.yml
index 409ea6b9d5d..f91773fe320 100644
--- a/config/metrics/counts_all/20210216175716_projects_inheriting_buildkite_active.yml
+++ b/config/metrics/counts_all/20210216175716_projects_inheriting_buildkite_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175717_groups_inheriting_buildkite_active.yml b/config/metrics/counts_all/20210216175717_groups_inheriting_buildkite_active.yml
index 6dd3e52aa89..fee0f23de9e 100644
--- a/config/metrics/counts_all/20210216175717_groups_inheriting_buildkite_active.yml
+++ b/config/metrics/counts_all/20210216175717_groups_inheriting_buildkite_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175719_projects_campfire_active.yml b/config/metrics/counts_all/20210216175719_projects_campfire_active.yml
index 068b6ca70bd..b61c070c844 100644
--- a/config/metrics/counts_all/20210216175719_projects_campfire_active.yml
+++ b/config/metrics/counts_all/20210216175719_projects_campfire_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175721_groups_campfire_active.yml b/config/metrics/counts_all/20210216175721_groups_campfire_active.yml
index 81b57aaa2b7..0bb65e4336a 100644
--- a/config/metrics/counts_all/20210216175721_groups_campfire_active.yml
+++ b/config/metrics/counts_all/20210216175721_groups_campfire_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175723_templates_campfire_active.yml b/config/metrics/counts_all/20210216175723_templates_campfire_active.yml
index 489e1ff085d..728d3d0af48 100644
--- a/config/metrics/counts_all/20210216175723_templates_campfire_active.yml
+++ b/config/metrics/counts_all/20210216175723_templates_campfire_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175725_instances_campfire_active.yml b/config/metrics/counts_all/20210216175725_instances_campfire_active.yml
index ce01b949a43..f5082d71885 100644
--- a/config/metrics/counts_all/20210216175725_instances_campfire_active.yml
+++ b/config/metrics/counts_all/20210216175725_instances_campfire_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175727_projects_inheriting_campfire_active.yml b/config/metrics/counts_all/20210216175727_projects_inheriting_campfire_active.yml
index 2de7329aace..11f7ba2bcc9 100644
--- a/config/metrics/counts_all/20210216175727_projects_inheriting_campfire_active.yml
+++ b/config/metrics/counts_all/20210216175727_projects_inheriting_campfire_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175729_groups_inheriting_campfire_active.yml b/config/metrics/counts_all/20210216175729_groups_inheriting_campfire_active.yml
index 4639d011005..8a4585d6d6e 100644
--- a/config/metrics/counts_all/20210216175729_groups_inheriting_campfire_active.yml
+++ b/config/metrics/counts_all/20210216175729_groups_inheriting_campfire_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175731_projects_confluence_active.yml b/config/metrics/counts_all/20210216175731_projects_confluence_active.yml
index 29420ee10e7..edab23f9eb5 100644
--- a/config/metrics/counts_all/20210216175731_projects_confluence_active.yml
+++ b/config/metrics/counts_all/20210216175731_projects_confluence_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175733_groups_confluence_active.yml b/config/metrics/counts_all/20210216175733_groups_confluence_active.yml
index 5ee10fc89bd..818be9e61bc 100644
--- a/config/metrics/counts_all/20210216175733_groups_confluence_active.yml
+++ b/config/metrics/counts_all/20210216175733_groups_confluence_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175734_templates_confluence_active.yml b/config/metrics/counts_all/20210216175734_templates_confluence_active.yml
index 4e8db8fe031..bb2d9976110 100644
--- a/config/metrics/counts_all/20210216175734_templates_confluence_active.yml
+++ b/config/metrics/counts_all/20210216175734_templates_confluence_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175736_instances_confluence_active.yml b/config/metrics/counts_all/20210216175736_instances_confluence_active.yml
index eda4940cc6d..83da2211379 100644
--- a/config/metrics/counts_all/20210216175736_instances_confluence_active.yml
+++ b/config/metrics/counts_all/20210216175736_instances_confluence_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175738_projects_inheriting_confluence_active.yml b/config/metrics/counts_all/20210216175738_projects_inheriting_confluence_active.yml
index 925341c3c81..104ee9b8afa 100644
--- a/config/metrics/counts_all/20210216175738_projects_inheriting_confluence_active.yml
+++ b/config/metrics/counts_all/20210216175738_projects_inheriting_confluence_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175740_groups_inheriting_confluence_active.yml b/config/metrics/counts_all/20210216175740_groups_inheriting_confluence_active.yml
index d91c8dcd08d..855f298d716 100644
--- a/config/metrics/counts_all/20210216175740_groups_inheriting_confluence_active.yml
+++ b/config/metrics/counts_all/20210216175740_groups_inheriting_confluence_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175742_projects_custom_issue_tracker_active.yml b/config/metrics/counts_all/20210216175742_projects_custom_issue_tracker_active.yml
index f1d02dcdb9c..f6125e01db2 100644
--- a/config/metrics/counts_all/20210216175742_projects_custom_issue_tracker_active.yml
+++ b/config/metrics/counts_all/20210216175742_projects_custom_issue_tracker_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175744_groups_custom_issue_tracker_active.yml b/config/metrics/counts_all/20210216175744_groups_custom_issue_tracker_active.yml
index db1c0107686..78078808ced 100644
--- a/config/metrics/counts_all/20210216175744_groups_custom_issue_tracker_active.yml
+++ b/config/metrics/counts_all/20210216175744_groups_custom_issue_tracker_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175745_templates_custom_issue_tracker_active.yml b/config/metrics/counts_all/20210216175745_templates_custom_issue_tracker_active.yml
index 8a60d0a3c5f..c1c63d0529a 100644
--- a/config/metrics/counts_all/20210216175745_templates_custom_issue_tracker_active.yml
+++ b/config/metrics/counts_all/20210216175745_templates_custom_issue_tracker_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175747_instances_custom_issue_tracker_active.yml b/config/metrics/counts_all/20210216175747_instances_custom_issue_tracker_active.yml
index 3f2658ffbde..c63b95a30fa 100644
--- a/config/metrics/counts_all/20210216175747_instances_custom_issue_tracker_active.yml
+++ b/config/metrics/counts_all/20210216175747_instances_custom_issue_tracker_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175749_projects_inheriting_custom_issue_tracker_active.yml b/config/metrics/counts_all/20210216175749_projects_inheriting_custom_issue_tracker_active.yml
index cad81761f76..b25687486b8 100644
--- a/config/metrics/counts_all/20210216175749_projects_inheriting_custom_issue_tracker_active.yml
+++ b/config/metrics/counts_all/20210216175749_projects_inheriting_custom_issue_tracker_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175751_groups_inheriting_custom_issue_tracker_active.yml b/config/metrics/counts_all/20210216175751_groups_inheriting_custom_issue_tracker_active.yml
index 20b3fbe3ba0..5ec00059577 100644
--- a/config/metrics/counts_all/20210216175751_groups_inheriting_custom_issue_tracker_active.yml
+++ b/config/metrics/counts_all/20210216175751_groups_inheriting_custom_issue_tracker_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175753_projects_discord_active.yml b/config/metrics/counts_all/20210216175753_projects_discord_active.yml
index e0973b0bffc..7337be70d10 100644
--- a/config/metrics/counts_all/20210216175753_projects_discord_active.yml
+++ b/config/metrics/counts_all/20210216175753_projects_discord_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175755_groups_discord_active.yml b/config/metrics/counts_all/20210216175755_groups_discord_active.yml
index f3fd18b3582..f9b38fee8fa 100644
--- a/config/metrics/counts_all/20210216175755_groups_discord_active.yml
+++ b/config/metrics/counts_all/20210216175755_groups_discord_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175756_templates_discord_active.yml b/config/metrics/counts_all/20210216175756_templates_discord_active.yml
index 0e16a045af2..d0663da787f 100644
--- a/config/metrics/counts_all/20210216175756_templates_discord_active.yml
+++ b/config/metrics/counts_all/20210216175756_templates_discord_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175758_instances_discord_active.yml b/config/metrics/counts_all/20210216175758_instances_discord_active.yml
index 12d230f4169..9eaaa0763cd 100644
--- a/config/metrics/counts_all/20210216175758_instances_discord_active.yml
+++ b/config/metrics/counts_all/20210216175758_instances_discord_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175800_projects_inheriting_discord_active.yml b/config/metrics/counts_all/20210216175800_projects_inheriting_discord_active.yml
index 2dd434f3642..bfc703c42a9 100644
--- a/config/metrics/counts_all/20210216175800_projects_inheriting_discord_active.yml
+++ b/config/metrics/counts_all/20210216175800_projects_inheriting_discord_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175802_groups_inheriting_discord_active.yml b/config/metrics/counts_all/20210216175802_groups_inheriting_discord_active.yml
index 16f962bd7bf..fe0e87708e6 100644
--- a/config/metrics/counts_all/20210216175802_groups_inheriting_discord_active.yml
+++ b/config/metrics/counts_all/20210216175802_groups_inheriting_discord_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175804_projects_drone_ci_active.yml b/config/metrics/counts_all/20210216175804_projects_drone_ci_active.yml
index c0de6ead30e..2315bf3d9e4 100644
--- a/config/metrics/counts_all/20210216175804_projects_drone_ci_active.yml
+++ b/config/metrics/counts_all/20210216175804_projects_drone_ci_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175806_groups_drone_ci_active.yml b/config/metrics/counts_all/20210216175806_groups_drone_ci_active.yml
index c2824b4c179..acb551bab24 100644
--- a/config/metrics/counts_all/20210216175806_groups_drone_ci_active.yml
+++ b/config/metrics/counts_all/20210216175806_groups_drone_ci_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175807_templates_drone_ci_active.yml b/config/metrics/counts_all/20210216175807_templates_drone_ci_active.yml
index 8ee28df4d74..6a764f64ab6 100644
--- a/config/metrics/counts_all/20210216175807_templates_drone_ci_active.yml
+++ b/config/metrics/counts_all/20210216175807_templates_drone_ci_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175809_instances_drone_ci_active.yml b/config/metrics/counts_all/20210216175809_instances_drone_ci_active.yml
index de5f27210ae..d20dd22b65f 100644
--- a/config/metrics/counts_all/20210216175809_instances_drone_ci_active.yml
+++ b/config/metrics/counts_all/20210216175809_instances_drone_ci_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175811_projects_inheriting_drone_ci_active.yml b/config/metrics/counts_all/20210216175811_projects_inheriting_drone_ci_active.yml
index 4d9e656fb28..2e5f7446e19 100644
--- a/config/metrics/counts_all/20210216175811_projects_inheriting_drone_ci_active.yml
+++ b/config/metrics/counts_all/20210216175811_projects_inheriting_drone_ci_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175813_groups_inheriting_drone_ci_active.yml b/config/metrics/counts_all/20210216175813_groups_inheriting_drone_ci_active.yml
index cb8883accf3..0ff92225b8c 100644
--- a/config/metrics/counts_all/20210216175813_groups_inheriting_drone_ci_active.yml
+++ b/config/metrics/counts_all/20210216175813_groups_inheriting_drone_ci_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175815_projects_emails_on_push_active.yml b/config/metrics/counts_all/20210216175815_projects_emails_on_push_active.yml
index 01a94735afc..4b81186a6f2 100644
--- a/config/metrics/counts_all/20210216175815_projects_emails_on_push_active.yml
+++ b/config/metrics/counts_all/20210216175815_projects_emails_on_push_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175817_groups_emails_on_push_active.yml b/config/metrics/counts_all/20210216175817_groups_emails_on_push_active.yml
index 67aa24bf260..dc298ba5974 100644
--- a/config/metrics/counts_all/20210216175817_groups_emails_on_push_active.yml
+++ b/config/metrics/counts_all/20210216175817_groups_emails_on_push_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175818_templates_emails_on_push_active.yml b/config/metrics/counts_all/20210216175818_templates_emails_on_push_active.yml
index a73d3bf2eca..f709aff9f07 100644
--- a/config/metrics/counts_all/20210216175818_templates_emails_on_push_active.yml
+++ b/config/metrics/counts_all/20210216175818_templates_emails_on_push_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175820_instances_emails_on_push_active.yml b/config/metrics/counts_all/20210216175820_instances_emails_on_push_active.yml
index 3b2d47f996f..d37c992ebf4 100644
--- a/config/metrics/counts_all/20210216175820_instances_emails_on_push_active.yml
+++ b/config/metrics/counts_all/20210216175820_instances_emails_on_push_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175822_projects_inheriting_emails_on_push_active.yml b/config/metrics/counts_all/20210216175822_projects_inheriting_emails_on_push_active.yml
index fba967b7637..b86e285c986 100644
--- a/config/metrics/counts_all/20210216175822_projects_inheriting_emails_on_push_active.yml
+++ b/config/metrics/counts_all/20210216175822_projects_inheriting_emails_on_push_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175824_groups_inheriting_emails_on_push_active.yml b/config/metrics/counts_all/20210216175824_groups_inheriting_emails_on_push_active.yml
index 4770cec8031..0d15b246455 100644
--- a/config/metrics/counts_all/20210216175824_groups_inheriting_emails_on_push_active.yml
+++ b/config/metrics/counts_all/20210216175824_groups_inheriting_emails_on_push_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175826_projects_external_wiki_active.yml b/config/metrics/counts_all/20210216175826_projects_external_wiki_active.yml
index 2d59b821034..3754c837376 100644
--- a/config/metrics/counts_all/20210216175826_projects_external_wiki_active.yml
+++ b/config/metrics/counts_all/20210216175826_projects_external_wiki_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175828_groups_external_wiki_active.yml b/config/metrics/counts_all/20210216175828_groups_external_wiki_active.yml
index 9bf2573d8cf..011a185439a 100644
--- a/config/metrics/counts_all/20210216175828_groups_external_wiki_active.yml
+++ b/config/metrics/counts_all/20210216175828_groups_external_wiki_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175829_templates_external_wiki_active.yml b/config/metrics/counts_all/20210216175829_templates_external_wiki_active.yml
index 6eec57b84da..35bbce95380 100644
--- a/config/metrics/counts_all/20210216175829_templates_external_wiki_active.yml
+++ b/config/metrics/counts_all/20210216175829_templates_external_wiki_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175831_instances_external_wiki_active.yml b/config/metrics/counts_all/20210216175831_instances_external_wiki_active.yml
index e69007baa07..f587b145229 100644
--- a/config/metrics/counts_all/20210216175831_instances_external_wiki_active.yml
+++ b/config/metrics/counts_all/20210216175831_instances_external_wiki_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175833_projects_inheriting_external_wiki_active.yml b/config/metrics/counts_all/20210216175833_projects_inheriting_external_wiki_active.yml
index 7926a9e8afd..2662f6299da 100644
--- a/config/metrics/counts_all/20210216175833_projects_inheriting_external_wiki_active.yml
+++ b/config/metrics/counts_all/20210216175833_projects_inheriting_external_wiki_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175835_groups_inheriting_external_wiki_active.yml b/config/metrics/counts_all/20210216175835_groups_inheriting_external_wiki_active.yml
index 5afd44dd6c9..f0bb398258f 100644
--- a/config/metrics/counts_all/20210216175835_groups_inheriting_external_wiki_active.yml
+++ b/config/metrics/counts_all/20210216175835_groups_inheriting_external_wiki_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175837_projects_flowdock_active.yml b/config/metrics/counts_all/20210216175837_projects_flowdock_active.yml
index b291a420ee0..24f36849e59 100644
--- a/config/metrics/counts_all/20210216175837_projects_flowdock_active.yml
+++ b/config/metrics/counts_all/20210216175837_projects_flowdock_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175839_groups_flowdock_active.yml b/config/metrics/counts_all/20210216175839_groups_flowdock_active.yml
index 372d6d70b99..91c41908e5e 100644
--- a/config/metrics/counts_all/20210216175839_groups_flowdock_active.yml
+++ b/config/metrics/counts_all/20210216175839_groups_flowdock_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175840_templates_flowdock_active.yml b/config/metrics/counts_all/20210216175840_templates_flowdock_active.yml
index 8fdd17db523..dc1466d2bef 100644
--- a/config/metrics/counts_all/20210216175840_templates_flowdock_active.yml
+++ b/config/metrics/counts_all/20210216175840_templates_flowdock_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175842_instances_flowdock_active.yml b/config/metrics/counts_all/20210216175842_instances_flowdock_active.yml
index 0ee29e5eafc..0da1700a699 100644
--- a/config/metrics/counts_all/20210216175842_instances_flowdock_active.yml
+++ b/config/metrics/counts_all/20210216175842_instances_flowdock_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175844_projects_inheriting_flowdock_active.yml b/config/metrics/counts_all/20210216175844_projects_inheriting_flowdock_active.yml
index f235a68138a..e930d8642fb 100644
--- a/config/metrics/counts_all/20210216175844_projects_inheriting_flowdock_active.yml
+++ b/config/metrics/counts_all/20210216175844_projects_inheriting_flowdock_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175846_groups_inheriting_flowdock_active.yml b/config/metrics/counts_all/20210216175846_groups_inheriting_flowdock_active.yml
index 613f77a7823..1d6d4eac8b0 100644
--- a/config/metrics/counts_all/20210216175846_groups_inheriting_flowdock_active.yml
+++ b/config/metrics/counts_all/20210216175846_groups_inheriting_flowdock_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175859_projects_hangouts_chat_active.yml b/config/metrics/counts_all/20210216175859_projects_hangouts_chat_active.yml
index b65bdf26462..e5ae5159d47 100644
--- a/config/metrics/counts_all/20210216175859_projects_hangouts_chat_active.yml
+++ b/config/metrics/counts_all/20210216175859_projects_hangouts_chat_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175901_groups_hangouts_chat_active.yml b/config/metrics/counts_all/20210216175901_groups_hangouts_chat_active.yml
index f66a5390585..a16d9ceed31 100644
--- a/config/metrics/counts_all/20210216175901_groups_hangouts_chat_active.yml
+++ b/config/metrics/counts_all/20210216175901_groups_hangouts_chat_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175902_templates_hangouts_chat_active.yml b/config/metrics/counts_all/20210216175902_templates_hangouts_chat_active.yml
index 0660b43acdb..b676501db10 100644
--- a/config/metrics/counts_all/20210216175902_templates_hangouts_chat_active.yml
+++ b/config/metrics/counts_all/20210216175902_templates_hangouts_chat_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175904_instances_hangouts_chat_active.yml b/config/metrics/counts_all/20210216175904_instances_hangouts_chat_active.yml
index 760b2ae0130..6f04eb7456c 100644
--- a/config/metrics/counts_all/20210216175904_instances_hangouts_chat_active.yml
+++ b/config/metrics/counts_all/20210216175904_instances_hangouts_chat_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175906_projects_inheriting_hangouts_chat_active.yml b/config/metrics/counts_all/20210216175906_projects_inheriting_hangouts_chat_active.yml
index b012752e100..85e735be109 100644
--- a/config/metrics/counts_all/20210216175906_projects_inheriting_hangouts_chat_active.yml
+++ b/config/metrics/counts_all/20210216175906_projects_inheriting_hangouts_chat_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175908_groups_inheriting_hangouts_chat_active.yml b/config/metrics/counts_all/20210216175908_groups_inheriting_hangouts_chat_active.yml
index 314f03f9c44..04fb8b998ce 100644
--- a/config/metrics/counts_all/20210216175908_groups_inheriting_hangouts_chat_active.yml
+++ b/config/metrics/counts_all/20210216175908_groups_inheriting_hangouts_chat_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175910_projects_hipchat_active.yml b/config/metrics/counts_all/20210216175910_projects_hipchat_active.yml
index 04bf41281d1..b1e5dfecea4 100644
--- a/config/metrics/counts_all/20210216175910_projects_hipchat_active.yml
+++ b/config/metrics/counts_all/20210216175910_projects_hipchat_active.yml
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175912_groups_hipchat_active.yml b/config/metrics/counts_all/20210216175912_groups_hipchat_active.yml
index 6d1b376d473..444bbafc516 100644
--- a/config/metrics/counts_all/20210216175912_groups_hipchat_active.yml
+++ b/config/metrics/counts_all/20210216175912_groups_hipchat_active.yml
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175913_templates_hipchat_active.yml b/config/metrics/counts_all/20210216175913_templates_hipchat_active.yml
index 1ad29856e8b..40db443b150 100644
--- a/config/metrics/counts_all/20210216175913_templates_hipchat_active.yml
+++ b/config/metrics/counts_all/20210216175913_templates_hipchat_active.yml
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175915_instances_hipchat_active.yml b/config/metrics/counts_all/20210216175915_instances_hipchat_active.yml
index 17b27862eb8..ef754887184 100644
--- a/config/metrics/counts_all/20210216175915_instances_hipchat_active.yml
+++ b/config/metrics/counts_all/20210216175915_instances_hipchat_active.yml
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175917_projects_inheriting_hipchat_active.yml b/config/metrics/counts_all/20210216175917_projects_inheriting_hipchat_active.yml
index 3926629d84e..d93814d3b71 100644
--- a/config/metrics/counts_all/20210216175917_projects_inheriting_hipchat_active.yml
+++ b/config/metrics/counts_all/20210216175917_projects_inheriting_hipchat_active.yml
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175919_groups_inheriting_hipchat_active.yml b/config/metrics/counts_all/20210216175919_groups_inheriting_hipchat_active.yml
index db64df5e880..75fbbb12034 100644
--- a/config/metrics/counts_all/20210216175919_groups_inheriting_hipchat_active.yml
+++ b/config/metrics/counts_all/20210216175919_groups_inheriting_hipchat_active.yml
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175921_projects_irker_active.yml b/config/metrics/counts_all/20210216175921_projects_irker_active.yml
index 6aa1dce7279..95eb098645c 100644
--- a/config/metrics/counts_all/20210216175921_projects_irker_active.yml
+++ b/config/metrics/counts_all/20210216175921_projects_irker_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175923_groups_irker_active.yml b/config/metrics/counts_all/20210216175923_groups_irker_active.yml
index 23dee4faa99..f8321d3a18e 100644
--- a/config/metrics/counts_all/20210216175923_groups_irker_active.yml
+++ b/config/metrics/counts_all/20210216175923_groups_irker_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175924_templates_irker_active.yml b/config/metrics/counts_all/20210216175924_templates_irker_active.yml
index eff644775cc..fc3ed89b6e8 100644
--- a/config/metrics/counts_all/20210216175924_templates_irker_active.yml
+++ b/config/metrics/counts_all/20210216175924_templates_irker_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175926_instances_irker_active.yml b/config/metrics/counts_all/20210216175926_instances_irker_active.yml
index ce785139cdb..ac306aaeb5f 100644
--- a/config/metrics/counts_all/20210216175926_instances_irker_active.yml
+++ b/config/metrics/counts_all/20210216175926_instances_irker_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175928_projects_inheriting_irker_active.yml b/config/metrics/counts_all/20210216175928_projects_inheriting_irker_active.yml
index 84f11bfbbfb..5e2e0b9fd65 100644
--- a/config/metrics/counts_all/20210216175928_projects_inheriting_irker_active.yml
+++ b/config/metrics/counts_all/20210216175928_projects_inheriting_irker_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175930_groups_inheriting_irker_active.yml b/config/metrics/counts_all/20210216175930_groups_inheriting_irker_active.yml
index bb7fe5bd2bd..eff596e72fb 100644
--- a/config/metrics/counts_all/20210216175930_groups_inheriting_irker_active.yml
+++ b/config/metrics/counts_all/20210216175930_groups_inheriting_irker_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175932_projects_jenkins_active.yml b/config/metrics/counts_all/20210216175932_projects_jenkins_active.yml
index 52c1332cf9a..3fd0e56a4e9 100644
--- a/config/metrics/counts_all/20210216175932_projects_jenkins_active.yml
+++ b/config/metrics/counts_all/20210216175932_projects_jenkins_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175934_groups_jenkins_active.yml b/config/metrics/counts_all/20210216175934_groups_jenkins_active.yml
index 04045aaa428..ffc47a98ea0 100644
--- a/config/metrics/counts_all/20210216175934_groups_jenkins_active.yml
+++ b/config/metrics/counts_all/20210216175934_groups_jenkins_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175935_templates_jenkins_active.yml b/config/metrics/counts_all/20210216175935_templates_jenkins_active.yml
index 1cf5485d7a4..542671304b0 100644
--- a/config/metrics/counts_all/20210216175935_templates_jenkins_active.yml
+++ b/config/metrics/counts_all/20210216175935_templates_jenkins_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175937_instances_jenkins_active.yml b/config/metrics/counts_all/20210216175937_instances_jenkins_active.yml
index 2c54388e9f4..39eabd6c502 100644
--- a/config/metrics/counts_all/20210216175937_instances_jenkins_active.yml
+++ b/config/metrics/counts_all/20210216175937_instances_jenkins_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175939_projects_inheriting_jenkins_active.yml b/config/metrics/counts_all/20210216175939_projects_inheriting_jenkins_active.yml
index b5eed44d695..98115a001a6 100644
--- a/config/metrics/counts_all/20210216175939_projects_inheriting_jenkins_active.yml
+++ b/config/metrics/counts_all/20210216175939_projects_inheriting_jenkins_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175941_groups_inheriting_jenkins_active.yml b/config/metrics/counts_all/20210216175941_groups_inheriting_jenkins_active.yml
index ba255d1b3a9..ad5dd2a38d3 100644
--- a/config/metrics/counts_all/20210216175941_groups_inheriting_jenkins_active.yml
+++ b/config/metrics/counts_all/20210216175941_groups_inheriting_jenkins_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175943_projects_jira_active.yml b/config/metrics/counts_all/20210216175943_projects_jira_active.yml
index fa63e02db35..cc1cd2b73dd 100644
--- a/config/metrics/counts_all/20210216175943_projects_jira_active.yml
+++ b/config/metrics/counts_all/20210216175943_projects_jira_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175945_groups_jira_active.yml b/config/metrics/counts_all/20210216175945_groups_jira_active.yml
index 49cc71aeb61..c1632e6006a 100644
--- a/config/metrics/counts_all/20210216175945_groups_jira_active.yml
+++ b/config/metrics/counts_all/20210216175945_groups_jira_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175946_templates_jira_active.yml b/config/metrics/counts_all/20210216175946_templates_jira_active.yml
index d643ad44387..83d3669b7f2 100644
--- a/config/metrics/counts_all/20210216175946_templates_jira_active.yml
+++ b/config/metrics/counts_all/20210216175946_templates_jira_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175948_instances_jira_active.yml b/config/metrics/counts_all/20210216175948_instances_jira_active.yml
index 4b251b68640..6d7cdae01d1 100644
--- a/config/metrics/counts_all/20210216175948_instances_jira_active.yml
+++ b/config/metrics/counts_all/20210216175948_instances_jira_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175950_projects_inheriting_jira_active.yml b/config/metrics/counts_all/20210216175950_projects_inheriting_jira_active.yml
index 1b11fa56c6f..df0874cff7b 100644
--- a/config/metrics/counts_all/20210216175950_projects_inheriting_jira_active.yml
+++ b/config/metrics/counts_all/20210216175950_projects_inheriting_jira_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175952_groups_inheriting_jira_active.yml b/config/metrics/counts_all/20210216175952_groups_inheriting_jira_active.yml
index 68e82a030c8..c4ec2c12954 100644
--- a/config/metrics/counts_all/20210216175952_groups_inheriting_jira_active.yml
+++ b/config/metrics/counts_all/20210216175952_groups_inheriting_jira_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175954_projects_mattermost_active.yml b/config/metrics/counts_all/20210216175954_projects_mattermost_active.yml
index f8c7edb9f40..bf021f1b175 100644
--- a/config/metrics/counts_all/20210216175954_projects_mattermost_active.yml
+++ b/config/metrics/counts_all/20210216175954_projects_mattermost_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175956_groups_mattermost_active.yml b/config/metrics/counts_all/20210216175956_groups_mattermost_active.yml
index 92c072c2c85..70756d6ae02 100644
--- a/config/metrics/counts_all/20210216175956_groups_mattermost_active.yml
+++ b/config/metrics/counts_all/20210216175956_groups_mattermost_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175957_templates_mattermost_active.yml b/config/metrics/counts_all/20210216175957_templates_mattermost_active.yml
index d935e0a86b0..460c5e808d8 100644
--- a/config/metrics/counts_all/20210216175957_templates_mattermost_active.yml
+++ b/config/metrics/counts_all/20210216175957_templates_mattermost_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216175959_instances_mattermost_active.yml b/config/metrics/counts_all/20210216175959_instances_mattermost_active.yml
index f7fe5081472..fedc53d1944 100644
--- a/config/metrics/counts_all/20210216175959_instances_mattermost_active.yml
+++ b/config/metrics/counts_all/20210216175959_instances_mattermost_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180001_projects_inheriting_mattermost_active.yml b/config/metrics/counts_all/20210216180001_projects_inheriting_mattermost_active.yml
index 34b74f6ab28..536586a5e62 100644
--- a/config/metrics/counts_all/20210216180001_projects_inheriting_mattermost_active.yml
+++ b/config/metrics/counts_all/20210216180001_projects_inheriting_mattermost_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180003_groups_inheriting_mattermost_active.yml b/config/metrics/counts_all/20210216180003_groups_inheriting_mattermost_active.yml
index 68576193e3a..9ceaa7c4a1c 100644
--- a/config/metrics/counts_all/20210216180003_groups_inheriting_mattermost_active.yml
+++ b/config/metrics/counts_all/20210216180003_groups_inheriting_mattermost_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180005_projects_mattermost_slash_commands_active.yml b/config/metrics/counts_all/20210216180005_projects_mattermost_slash_commands_active.yml
index d95571b0fb8..8204da004d8 100644
--- a/config/metrics/counts_all/20210216180005_projects_mattermost_slash_commands_active.yml
+++ b/config/metrics/counts_all/20210216180005_projects_mattermost_slash_commands_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180006_groups_mattermost_slash_commands_active.yml b/config/metrics/counts_all/20210216180006_groups_mattermost_slash_commands_active.yml
index 6ce8be4a8be..80b38b68eff 100644
--- a/config/metrics/counts_all/20210216180006_groups_mattermost_slash_commands_active.yml
+++ b/config/metrics/counts_all/20210216180006_groups_mattermost_slash_commands_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180008_templates_mattermost_slash_commands_active.yml b/config/metrics/counts_all/20210216180008_templates_mattermost_slash_commands_active.yml
index d9255db7311..927710d918c 100644
--- a/config/metrics/counts_all/20210216180008_templates_mattermost_slash_commands_active.yml
+++ b/config/metrics/counts_all/20210216180008_templates_mattermost_slash_commands_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180010_instances_mattermost_slash_commands_active.yml b/config/metrics/counts_all/20210216180010_instances_mattermost_slash_commands_active.yml
index ad5e011a21c..6ad05101cbf 100644
--- a/config/metrics/counts_all/20210216180010_instances_mattermost_slash_commands_active.yml
+++ b/config/metrics/counts_all/20210216180010_instances_mattermost_slash_commands_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180012_projects_inheriting_mattermost_slash_commands_active.yml b/config/metrics/counts_all/20210216180012_projects_inheriting_mattermost_slash_commands_active.yml
index 4a26a69ed37..01e97fa6ec3 100644
--- a/config/metrics/counts_all/20210216180012_projects_inheriting_mattermost_slash_commands_active.yml
+++ b/config/metrics/counts_all/20210216180012_projects_inheriting_mattermost_slash_commands_active.yml
@@ -8,7 +8,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180014_groups_inheriting_mattermost_slash_commands_active.yml b/config/metrics/counts_all/20210216180014_groups_inheriting_mattermost_slash_commands_active.yml
index 4c2deca981c..ebedb6796b6 100644
--- a/config/metrics/counts_all/20210216180014_groups_inheriting_mattermost_slash_commands_active.yml
+++ b/config/metrics/counts_all/20210216180014_groups_inheriting_mattermost_slash_commands_active.yml
@@ -8,7 +8,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180016_projects_microsoft_teams_active.yml b/config/metrics/counts_all/20210216180016_projects_microsoft_teams_active.yml
index ff25e7fe72a..9306aca0d2d 100644
--- a/config/metrics/counts_all/20210216180016_projects_microsoft_teams_active.yml
+++ b/config/metrics/counts_all/20210216180016_projects_microsoft_teams_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180018_groups_microsoft_teams_active.yml b/config/metrics/counts_all/20210216180018_groups_microsoft_teams_active.yml
index 2afa40977b1..71b6ba02769 100644
--- a/config/metrics/counts_all/20210216180018_groups_microsoft_teams_active.yml
+++ b/config/metrics/counts_all/20210216180018_groups_microsoft_teams_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180019_templates_microsoft_teams_active.yml b/config/metrics/counts_all/20210216180019_templates_microsoft_teams_active.yml
index 4ac134394fc..fb35802c2b7 100644
--- a/config/metrics/counts_all/20210216180019_templates_microsoft_teams_active.yml
+++ b/config/metrics/counts_all/20210216180019_templates_microsoft_teams_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180021_instances_microsoft_teams_active.yml b/config/metrics/counts_all/20210216180021_instances_microsoft_teams_active.yml
index e78ae2b7411..d58b7483f1f 100644
--- a/config/metrics/counts_all/20210216180021_instances_microsoft_teams_active.yml
+++ b/config/metrics/counts_all/20210216180021_instances_microsoft_teams_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180023_projects_inheriting_microsoft_teams_active.yml b/config/metrics/counts_all/20210216180023_projects_inheriting_microsoft_teams_active.yml
index 73791545ea6..2135727416d 100644
--- a/config/metrics/counts_all/20210216180023_projects_inheriting_microsoft_teams_active.yml
+++ b/config/metrics/counts_all/20210216180023_projects_inheriting_microsoft_teams_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180025_groups_inheriting_microsoft_teams_active.yml b/config/metrics/counts_all/20210216180025_groups_inheriting_microsoft_teams_active.yml
index a1300f264f6..5e16c68d9d9 100644
--- a/config/metrics/counts_all/20210216180025_groups_inheriting_microsoft_teams_active.yml
+++ b/config/metrics/counts_all/20210216180025_groups_inheriting_microsoft_teams_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180027_projects_packagist_active.yml b/config/metrics/counts_all/20210216180027_projects_packagist_active.yml
index a009cb2045e..cff969cb8bb 100644
--- a/config/metrics/counts_all/20210216180027_projects_packagist_active.yml
+++ b/config/metrics/counts_all/20210216180027_projects_packagist_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180029_groups_packagist_active.yml b/config/metrics/counts_all/20210216180029_groups_packagist_active.yml
index efcd3dbd39c..1f97e3104c8 100644
--- a/config/metrics/counts_all/20210216180029_groups_packagist_active.yml
+++ b/config/metrics/counts_all/20210216180029_groups_packagist_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180030_templates_packagist_active.yml b/config/metrics/counts_all/20210216180030_templates_packagist_active.yml
index f6a337662b8..aa56cf08028 100644
--- a/config/metrics/counts_all/20210216180030_templates_packagist_active.yml
+++ b/config/metrics/counts_all/20210216180030_templates_packagist_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180032_instances_packagist_active.yml b/config/metrics/counts_all/20210216180032_instances_packagist_active.yml
index 41693d7a984..eb3492ae263 100644
--- a/config/metrics/counts_all/20210216180032_instances_packagist_active.yml
+++ b/config/metrics/counts_all/20210216180032_instances_packagist_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180034_projects_inheriting_packagist_active.yml b/config/metrics/counts_all/20210216180034_projects_inheriting_packagist_active.yml
index 08073ec5aa9..35b79aad0b7 100644
--- a/config/metrics/counts_all/20210216180034_projects_inheriting_packagist_active.yml
+++ b/config/metrics/counts_all/20210216180034_projects_inheriting_packagist_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180036_groups_inheriting_packagist_active.yml b/config/metrics/counts_all/20210216180036_groups_inheriting_packagist_active.yml
index e431c52ad43..6b182ca55e7 100644
--- a/config/metrics/counts_all/20210216180036_groups_inheriting_packagist_active.yml
+++ b/config/metrics/counts_all/20210216180036_groups_inheriting_packagist_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180038_projects_pipelines_email_active.yml b/config/metrics/counts_all/20210216180038_projects_pipelines_email_active.yml
index 83f9c5b7342..61555020204 100644
--- a/config/metrics/counts_all/20210216180038_projects_pipelines_email_active.yml
+++ b/config/metrics/counts_all/20210216180038_projects_pipelines_email_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180040_groups_pipelines_email_active.yml b/config/metrics/counts_all/20210216180040_groups_pipelines_email_active.yml
index a705d1e2da6..035bcf7d1b2 100644
--- a/config/metrics/counts_all/20210216180040_groups_pipelines_email_active.yml
+++ b/config/metrics/counts_all/20210216180040_groups_pipelines_email_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180041_templates_pipelines_email_active.yml b/config/metrics/counts_all/20210216180041_templates_pipelines_email_active.yml
index df1bf53c012..2d81cf582e9 100644
--- a/config/metrics/counts_all/20210216180041_templates_pipelines_email_active.yml
+++ b/config/metrics/counts_all/20210216180041_templates_pipelines_email_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180043_instances_pipelines_email_active.yml b/config/metrics/counts_all/20210216180043_instances_pipelines_email_active.yml
index a759da8865a..8c93ccf8d3d 100644
--- a/config/metrics/counts_all/20210216180043_instances_pipelines_email_active.yml
+++ b/config/metrics/counts_all/20210216180043_instances_pipelines_email_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180045_projects_inheriting_pipelines_email_active.yml b/config/metrics/counts_all/20210216180045_projects_inheriting_pipelines_email_active.yml
index 7f336697716..68c59a66251 100644
--- a/config/metrics/counts_all/20210216180045_projects_inheriting_pipelines_email_active.yml
+++ b/config/metrics/counts_all/20210216180045_projects_inheriting_pipelines_email_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180047_groups_inheriting_pipelines_email_active.yml b/config/metrics/counts_all/20210216180047_groups_inheriting_pipelines_email_active.yml
index 049343d22f6..c05c227723d 100644
--- a/config/metrics/counts_all/20210216180047_groups_inheriting_pipelines_email_active.yml
+++ b/config/metrics/counts_all/20210216180047_groups_inheriting_pipelines_email_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180049_projects_pivotaltracker_active.yml b/config/metrics/counts_all/20210216180049_projects_pivotaltracker_active.yml
index 5330268e079..afa3609ae5b 100644
--- a/config/metrics/counts_all/20210216180049_projects_pivotaltracker_active.yml
+++ b/config/metrics/counts_all/20210216180049_projects_pivotaltracker_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180051_groups_pivotaltracker_active.yml b/config/metrics/counts_all/20210216180051_groups_pivotaltracker_active.yml
index 3d077219657..487b55d438e 100644
--- a/config/metrics/counts_all/20210216180051_groups_pivotaltracker_active.yml
+++ b/config/metrics/counts_all/20210216180051_groups_pivotaltracker_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180052_templates_pivotaltracker_active.yml b/config/metrics/counts_all/20210216180052_templates_pivotaltracker_active.yml
index 183417d566c..7c869361d05 100644
--- a/config/metrics/counts_all/20210216180052_templates_pivotaltracker_active.yml
+++ b/config/metrics/counts_all/20210216180052_templates_pivotaltracker_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180054_instances_pivotaltracker_active.yml b/config/metrics/counts_all/20210216180054_instances_pivotaltracker_active.yml
index adeec68290a..6334dcf7ea0 100644
--- a/config/metrics/counts_all/20210216180054_instances_pivotaltracker_active.yml
+++ b/config/metrics/counts_all/20210216180054_instances_pivotaltracker_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180056_projects_inheriting_pivotaltracker_active.yml b/config/metrics/counts_all/20210216180056_projects_inheriting_pivotaltracker_active.yml
index c9f6ba7680a..15d298ab409 100644
--- a/config/metrics/counts_all/20210216180056_projects_inheriting_pivotaltracker_active.yml
+++ b/config/metrics/counts_all/20210216180056_projects_inheriting_pivotaltracker_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180058_groups_inheriting_pivotaltracker_active.yml b/config/metrics/counts_all/20210216180058_groups_inheriting_pivotaltracker_active.yml
index b247a3b48e4..c201fc24426 100644
--- a/config/metrics/counts_all/20210216180058_groups_inheriting_pivotaltracker_active.yml
+++ b/config/metrics/counts_all/20210216180058_groups_inheriting_pivotaltracker_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180100_projects_pushover_active.yml b/config/metrics/counts_all/20210216180100_projects_pushover_active.yml
index 1f5635f56da..1e8a1a69a13 100644
--- a/config/metrics/counts_all/20210216180100_projects_pushover_active.yml
+++ b/config/metrics/counts_all/20210216180100_projects_pushover_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180102_groups_pushover_active.yml b/config/metrics/counts_all/20210216180102_groups_pushover_active.yml
index 5a8225f97a3..bf2d9691718 100644
--- a/config/metrics/counts_all/20210216180102_groups_pushover_active.yml
+++ b/config/metrics/counts_all/20210216180102_groups_pushover_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180104_templates_pushover_active.yml b/config/metrics/counts_all/20210216180104_templates_pushover_active.yml
index 79ea70fc7fa..572b5da07d4 100644
--- a/config/metrics/counts_all/20210216180104_templates_pushover_active.yml
+++ b/config/metrics/counts_all/20210216180104_templates_pushover_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180105_instances_pushover_active.yml b/config/metrics/counts_all/20210216180105_instances_pushover_active.yml
index cfe8f5170d1..97f79e00bbb 100644
--- a/config/metrics/counts_all/20210216180105_instances_pushover_active.yml
+++ b/config/metrics/counts_all/20210216180105_instances_pushover_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180107_projects_inheriting_pushover_active.yml b/config/metrics/counts_all/20210216180107_projects_inheriting_pushover_active.yml
index 25942eb52ec..78ee7710012 100644
--- a/config/metrics/counts_all/20210216180107_projects_inheriting_pushover_active.yml
+++ b/config/metrics/counts_all/20210216180107_projects_inheriting_pushover_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180109_groups_inheriting_pushover_active.yml b/config/metrics/counts_all/20210216180109_groups_inheriting_pushover_active.yml
index 941fe56037a..bc303da80b2 100644
--- a/config/metrics/counts_all/20210216180109_groups_inheriting_pushover_active.yml
+++ b/config/metrics/counts_all/20210216180109_groups_inheriting_pushover_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180111_projects_redmine_active.yml b/config/metrics/counts_all/20210216180111_projects_redmine_active.yml
index b19251acb79..6ce6e0e40a3 100644
--- a/config/metrics/counts_all/20210216180111_projects_redmine_active.yml
+++ b/config/metrics/counts_all/20210216180111_projects_redmine_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180113_groups_redmine_active.yml b/config/metrics/counts_all/20210216180113_groups_redmine_active.yml
index 5bb559e9f24..c4890014899 100644
--- a/config/metrics/counts_all/20210216180113_groups_redmine_active.yml
+++ b/config/metrics/counts_all/20210216180113_groups_redmine_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180115_templates_redmine_active.yml b/config/metrics/counts_all/20210216180115_templates_redmine_active.yml
index 3a173346fa8..a85417cbc2c 100644
--- a/config/metrics/counts_all/20210216180115_templates_redmine_active.yml
+++ b/config/metrics/counts_all/20210216180115_templates_redmine_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180116_instances_redmine_active.yml b/config/metrics/counts_all/20210216180116_instances_redmine_active.yml
index 17974b6f157..9d9de8d5f76 100644
--- a/config/metrics/counts_all/20210216180116_instances_redmine_active.yml
+++ b/config/metrics/counts_all/20210216180116_instances_redmine_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180118_projects_inheriting_redmine_active.yml b/config/metrics/counts_all/20210216180118_projects_inheriting_redmine_active.yml
index 8c94c811d69..396e007dcad 100644
--- a/config/metrics/counts_all/20210216180118_projects_inheriting_redmine_active.yml
+++ b/config/metrics/counts_all/20210216180118_projects_inheriting_redmine_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180120_groups_inheriting_redmine_active.yml b/config/metrics/counts_all/20210216180120_groups_inheriting_redmine_active.yml
index 459b97667eb..260b4059958 100644
--- a/config/metrics/counts_all/20210216180120_groups_inheriting_redmine_active.yml
+++ b/config/metrics/counts_all/20210216180120_groups_inheriting_redmine_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180122_projects_slack_active.yml b/config/metrics/counts_all/20210216180122_projects_slack_active.yml
index 4663d4b516c..781fabdea25 100644
--- a/config/metrics/counts_all/20210216180122_projects_slack_active.yml
+++ b/config/metrics/counts_all/20210216180122_projects_slack_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180124_groups_slack_active.yml b/config/metrics/counts_all/20210216180124_groups_slack_active.yml
index 14c7bab4c77..3d33c9c941c 100644
--- a/config/metrics/counts_all/20210216180124_groups_slack_active.yml
+++ b/config/metrics/counts_all/20210216180124_groups_slack_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180126_templates_slack_active.yml b/config/metrics/counts_all/20210216180126_templates_slack_active.yml
index 22a205d7d4c..dffa673cd47 100644
--- a/config/metrics/counts_all/20210216180126_templates_slack_active.yml
+++ b/config/metrics/counts_all/20210216180126_templates_slack_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180127_instances_slack_active.yml b/config/metrics/counts_all/20210216180127_instances_slack_active.yml
index 8c9155ce5ab..badd214e967 100644
--- a/config/metrics/counts_all/20210216180127_instances_slack_active.yml
+++ b/config/metrics/counts_all/20210216180127_instances_slack_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180129_projects_inheriting_slack_active.yml b/config/metrics/counts_all/20210216180129_projects_inheriting_slack_active.yml
index 0b3dae20a6e..c2ffb561f59 100644
--- a/config/metrics/counts_all/20210216180129_projects_inheriting_slack_active.yml
+++ b/config/metrics/counts_all/20210216180129_projects_inheriting_slack_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180131_groups_inheriting_slack_active.yml b/config/metrics/counts_all/20210216180131_groups_inheriting_slack_active.yml
index 93ca97e00e5..98478a5141e 100644
--- a/config/metrics/counts_all/20210216180131_groups_inheriting_slack_active.yml
+++ b/config/metrics/counts_all/20210216180131_groups_inheriting_slack_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180133_projects_slack_slash_commands_active.yml b/config/metrics/counts_all/20210216180133_projects_slack_slash_commands_active.yml
index d98029d89ad..a3bb1984b6a 100644
--- a/config/metrics/counts_all/20210216180133_projects_slack_slash_commands_active.yml
+++ b/config/metrics/counts_all/20210216180133_projects_slack_slash_commands_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180135_groups_slack_slash_commands_active.yml b/config/metrics/counts_all/20210216180135_groups_slack_slash_commands_active.yml
index f1434b65fbf..8a57b153de4 100644
--- a/config/metrics/counts_all/20210216180135_groups_slack_slash_commands_active.yml
+++ b/config/metrics/counts_all/20210216180135_groups_slack_slash_commands_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180137_templates_slack_slash_commands_active.yml b/config/metrics/counts_all/20210216180137_templates_slack_slash_commands_active.yml
index 48edd9813ef..e044d6cf1dd 100644
--- a/config/metrics/counts_all/20210216180137_templates_slack_slash_commands_active.yml
+++ b/config/metrics/counts_all/20210216180137_templates_slack_slash_commands_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180138_instances_slack_slash_commands_active.yml b/config/metrics/counts_all/20210216180138_instances_slack_slash_commands_active.yml
index 7cd8c1de0be..05ef50c0704 100644
--- a/config/metrics/counts_all/20210216180138_instances_slack_slash_commands_active.yml
+++ b/config/metrics/counts_all/20210216180138_instances_slack_slash_commands_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180140_projects_inheriting_slack_slash_commands_active.yml b/config/metrics/counts_all/20210216180140_projects_inheriting_slack_slash_commands_active.yml
index c28b0116702..256e8460570 100644
--- a/config/metrics/counts_all/20210216180140_projects_inheriting_slack_slash_commands_active.yml
+++ b/config/metrics/counts_all/20210216180140_projects_inheriting_slack_slash_commands_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180142_groups_inheriting_slack_slash_commands_active.yml b/config/metrics/counts_all/20210216180142_groups_inheriting_slack_slash_commands_active.yml
index e94e5d173bd..514176e1d69 100644
--- a/config/metrics/counts_all/20210216180142_groups_inheriting_slack_slash_commands_active.yml
+++ b/config/metrics/counts_all/20210216180142_groups_inheriting_slack_slash_commands_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180144_projects_teamcity_active.yml b/config/metrics/counts_all/20210216180144_projects_teamcity_active.yml
index 4c6c5c6c519..f2646e8833f 100644
--- a/config/metrics/counts_all/20210216180144_projects_teamcity_active.yml
+++ b/config/metrics/counts_all/20210216180144_projects_teamcity_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180146_groups_teamcity_active.yml b/config/metrics/counts_all/20210216180146_groups_teamcity_active.yml
index 20a719dbefb..38f02ab6471 100644
--- a/config/metrics/counts_all/20210216180146_groups_teamcity_active.yml
+++ b/config/metrics/counts_all/20210216180146_groups_teamcity_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180148_templates_teamcity_active.yml b/config/metrics/counts_all/20210216180148_templates_teamcity_active.yml
index 5e8ea66b008..b3a37ebc578 100644
--- a/config/metrics/counts_all/20210216180148_templates_teamcity_active.yml
+++ b/config/metrics/counts_all/20210216180148_templates_teamcity_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180149_instances_teamcity_active.yml b/config/metrics/counts_all/20210216180149_instances_teamcity_active.yml
index f02df75cc87..e79ea145ec9 100644
--- a/config/metrics/counts_all/20210216180149_instances_teamcity_active.yml
+++ b/config/metrics/counts_all/20210216180149_instances_teamcity_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180151_projects_inheriting_teamcity_active.yml b/config/metrics/counts_all/20210216180151_projects_inheriting_teamcity_active.yml
index 54121809d98..189211686a7 100644
--- a/config/metrics/counts_all/20210216180151_projects_inheriting_teamcity_active.yml
+++ b/config/metrics/counts_all/20210216180151_projects_inheriting_teamcity_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180153_groups_inheriting_teamcity_active.yml b/config/metrics/counts_all/20210216180153_groups_inheriting_teamcity_active.yml
index 33a126b4d0c..b99e26f4394 100644
--- a/config/metrics/counts_all/20210216180153_groups_inheriting_teamcity_active.yml
+++ b/config/metrics/counts_all/20210216180153_groups_inheriting_teamcity_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180155_projects_unify_circuit_active.yml b/config/metrics/counts_all/20210216180155_projects_unify_circuit_active.yml
index be5ddb60891..f6e854b241d 100644
--- a/config/metrics/counts_all/20210216180155_projects_unify_circuit_active.yml
+++ b/config/metrics/counts_all/20210216180155_projects_unify_circuit_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180157_groups_unify_circuit_active.yml b/config/metrics/counts_all/20210216180157_groups_unify_circuit_active.yml
index ca03f75a395..278260d1aaa 100644
--- a/config/metrics/counts_all/20210216180157_groups_unify_circuit_active.yml
+++ b/config/metrics/counts_all/20210216180157_groups_unify_circuit_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180159_templates_unify_circuit_active.yml b/config/metrics/counts_all/20210216180159_templates_unify_circuit_active.yml
index 77d402bdd52..39facfb237e 100644
--- a/config/metrics/counts_all/20210216180159_templates_unify_circuit_active.yml
+++ b/config/metrics/counts_all/20210216180159_templates_unify_circuit_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180201_instances_unify_circuit_active.yml b/config/metrics/counts_all/20210216180201_instances_unify_circuit_active.yml
index 7e789cdb67f..89e36459000 100644
--- a/config/metrics/counts_all/20210216180201_instances_unify_circuit_active.yml
+++ b/config/metrics/counts_all/20210216180201_instances_unify_circuit_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180203_projects_inheriting_unify_circuit_active.yml b/config/metrics/counts_all/20210216180203_projects_inheriting_unify_circuit_active.yml
index 4b5e83b2fea..d053ad5183e 100644
--- a/config/metrics/counts_all/20210216180203_projects_inheriting_unify_circuit_active.yml
+++ b/config/metrics/counts_all/20210216180203_projects_inheriting_unify_circuit_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180204_groups_inheriting_unify_circuit_active.yml b/config/metrics/counts_all/20210216180204_groups_inheriting_unify_circuit_active.yml
index 55644e584d6..f7bc5ab4a9d 100644
--- a/config/metrics/counts_all/20210216180204_groups_inheriting_unify_circuit_active.yml
+++ b/config/metrics/counts_all/20210216180204_groups_inheriting_unify_circuit_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180206_projects_webex_teams_active.yml b/config/metrics/counts_all/20210216180206_projects_webex_teams_active.yml
index d6284cb68fd..95f4efbb24b 100644
--- a/config/metrics/counts_all/20210216180206_projects_webex_teams_active.yml
+++ b/config/metrics/counts_all/20210216180206_projects_webex_teams_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180208_groups_webex_teams_active.yml b/config/metrics/counts_all/20210216180208_groups_webex_teams_active.yml
index 7ef4fe1ca41..aa1ad25479b 100644
--- a/config/metrics/counts_all/20210216180208_groups_webex_teams_active.yml
+++ b/config/metrics/counts_all/20210216180208_groups_webex_teams_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180210_templates_webex_teams_active.yml b/config/metrics/counts_all/20210216180210_templates_webex_teams_active.yml
index e461f99e596..185b538a228 100644
--- a/config/metrics/counts_all/20210216180210_templates_webex_teams_active.yml
+++ b/config/metrics/counts_all/20210216180210_templates_webex_teams_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180212_instances_webex_teams_active.yml b/config/metrics/counts_all/20210216180212_instances_webex_teams_active.yml
index c82e1a34b19..20bdf4f0616 100644
--- a/config/metrics/counts_all/20210216180212_instances_webex_teams_active.yml
+++ b/config/metrics/counts_all/20210216180212_instances_webex_teams_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180214_projects_inheriting_webex_teams_active.yml b/config/metrics/counts_all/20210216180214_projects_inheriting_webex_teams_active.yml
index e16b7177fb3..cb4e3a00dd7 100644
--- a/config/metrics/counts_all/20210216180214_projects_inheriting_webex_teams_active.yml
+++ b/config/metrics/counts_all/20210216180214_projects_inheriting_webex_teams_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180215_groups_inheriting_webex_teams_active.yml b/config/metrics/counts_all/20210216180215_groups_inheriting_webex_teams_active.yml
index 31737003f39..38623c9f105 100644
--- a/config/metrics/counts_all/20210216180215_groups_inheriting_webex_teams_active.yml
+++ b/config/metrics/counts_all/20210216180215_groups_inheriting_webex_teams_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180217_projects_youtrack_active.yml b/config/metrics/counts_all/20210216180217_projects_youtrack_active.yml
index 9361edb0a12..63addd163cd 100644
--- a/config/metrics/counts_all/20210216180217_projects_youtrack_active.yml
+++ b/config/metrics/counts_all/20210216180217_projects_youtrack_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180219_groups_youtrack_active.yml b/config/metrics/counts_all/20210216180219_groups_youtrack_active.yml
index a2fa39722b3..3261458496b 100644
--- a/config/metrics/counts_all/20210216180219_groups_youtrack_active.yml
+++ b/config/metrics/counts_all/20210216180219_groups_youtrack_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180221_templates_youtrack_active.yml b/config/metrics/counts_all/20210216180221_templates_youtrack_active.yml
index bd32fd5eb6e..a6c11918ce2 100644
--- a/config/metrics/counts_all/20210216180221_templates_youtrack_active.yml
+++ b/config/metrics/counts_all/20210216180221_templates_youtrack_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180223_instances_youtrack_active.yml b/config/metrics/counts_all/20210216180223_instances_youtrack_active.yml
index cb160d513b0..83844709763 100644
--- a/config/metrics/counts_all/20210216180223_instances_youtrack_active.yml
+++ b/config/metrics/counts_all/20210216180223_instances_youtrack_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180225_projects_inheriting_youtrack_active.yml b/config/metrics/counts_all/20210216180225_projects_inheriting_youtrack_active.yml
index 875620ff2ba..cb0ff9b5cf2 100644
--- a/config/metrics/counts_all/20210216180225_projects_inheriting_youtrack_active.yml
+++ b/config/metrics/counts_all/20210216180225_projects_inheriting_youtrack_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180226_groups_inheriting_youtrack_active.yml b/config/metrics/counts_all/20210216180226_groups_inheriting_youtrack_active.yml
index 34f0c8f93fa..1a49783e7b6 100644
--- a/config/metrics/counts_all/20210216180226_groups_inheriting_youtrack_active.yml
+++ b/config/metrics/counts_all/20210216180226_groups_inheriting_youtrack_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180228_projects_jira_server_active.yml b/config/metrics/counts_all/20210216180228_projects_jira_server_active.yml
index 8870013fc2b..f53ca3bf5e4 100644
--- a/config/metrics/counts_all/20210216180228_projects_jira_server_active.yml
+++ b/config/metrics/counts_all/20210216180228_projects_jira_server_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180230_projects_jira_cloud_active.yml b/config/metrics/counts_all/20210216180230_projects_jira_cloud_active.yml
index adf7098e71c..7ad776bf919 100644
--- a/config/metrics/counts_all/20210216180230_projects_jira_cloud_active.yml
+++ b/config/metrics/counts_all/20210216180230_projects_jira_cloud_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180232_projects_jira_dvcs_cloud_active.yml b/config/metrics/counts_all/20210216180232_projects_jira_dvcs_cloud_active.yml
index 33be7ef4f87..a94b2209a3b 100644
--- a/config/metrics/counts_all/20210216180232_projects_jira_dvcs_cloud_active.yml
+++ b/config/metrics/counts_all/20210216180232_projects_jira_dvcs_cloud_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180234_projects_jira_dvcs_server_active.yml b/config/metrics/counts_all/20210216180234_projects_jira_dvcs_server_active.yml
index b7fa31e101e..2f6d7defbb9 100644
--- a/config/metrics/counts_all/20210216180234_projects_jira_dvcs_server_active.yml
+++ b/config/metrics/counts_all/20210216180234_projects_jira_dvcs_server_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180239_personal_snippets.yml b/config/metrics/counts_all/20210216180239_personal_snippets.yml
index ea8404a6163..35467ce30c4 100644
--- a/config/metrics/counts_all/20210216180239_personal_snippets.yml
+++ b/config/metrics/counts_all/20210216180239_personal_snippets.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: snippets
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180241_project_snippets.yml b/config/metrics/counts_all/20210216180241_project_snippets.yml
index 1f915327d39..61ed32e7de5 100644
--- a/config/metrics/counts_all/20210216180241_project_snippets.yml
+++ b/config/metrics/counts_all/20210216180241_project_snippets.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: snippets
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180242_web_ide_commits.yml b/config/metrics/counts_all/20210216180242_web_ide_commits.yml
index c85dd1f876c..618e09027b5 100644
--- a/config/metrics/counts_all/20210216180242_web_ide_commits.yml
+++ b/config/metrics/counts_all/20210216180242_web_ide_commits.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: web_ide
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180244_web_ide_views.yml b/config/metrics/counts_all/20210216180244_web_ide_views.yml
index 222e92482e9..cac6e315d6d 100644
--- a/config/metrics/counts_all/20210216180244_web_ide_views.yml
+++ b/config/metrics/counts_all/20210216180244_web_ide_views.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: web_ide
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180246_web_ide_merge_requests.yml b/config/metrics/counts_all/20210216180246_web_ide_merge_requests.yml
index c5e50275878..60281e0b57b 100644
--- a/config/metrics/counts_all/20210216180246_web_ide_merge_requests.yml
+++ b/config/metrics/counts_all/20210216180246_web_ide_merge_requests.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: web_ide
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180248_web_ide_previews.yml b/config/metrics/counts_all/20210216180248_web_ide_previews.yml
index b4c349e5cc3..249654a68fd 100644
--- a/config/metrics/counts_all/20210216180248_web_ide_previews.yml
+++ b/config/metrics/counts_all/20210216180248_web_ide_previews.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: web_ide
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180250_web_ide_terminals.yml b/config/metrics/counts_all/20210216180250_web_ide_terminals.yml
index d451222dfd4..d674e379091 100644
--- a/config/metrics/counts_all/20210216180250_web_ide_terminals.yml
+++ b/config/metrics/counts_all/20210216180250_web_ide_terminals.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: web_ide
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180252_web_ide_pipelines.yml b/config/metrics/counts_all/20210216180252_web_ide_pipelines.yml
index 562f6381487..bd2e3a97c88 100644
--- a/config/metrics/counts_all/20210216180252_web_ide_pipelines.yml
+++ b/config/metrics/counts_all/20210216180252_web_ide_pipelines.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: web_ide
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180253_snippet_comment.yml b/config/metrics/counts_all/20210216180253_snippet_comment.yml
index efc079fa13e..e28994afad8 100644
--- a/config/metrics/counts_all/20210216180253_snippet_comment.yml
+++ b/config/metrics/counts_all/20210216180253_snippet_comment.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: snippets
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180255_snippet_create.yml b/config/metrics/counts_all/20210216180255_snippet_create.yml
index 4303deb1aeb..5afc32bd5b1 100644
--- a/config/metrics/counts_all/20210216180255_snippet_create.yml
+++ b/config/metrics/counts_all/20210216180255_snippet_create.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: snippets
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180257_snippet_update.yml b/config/metrics/counts_all/20210216180257_snippet_update.yml
index d59f2a63a42..462daa9e4da 100644
--- a/config/metrics/counts_all/20210216180257_snippet_update.yml
+++ b/config/metrics/counts_all/20210216180257_snippet_update.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: snippets
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180259_static_site_editor_views.yml b/config/metrics/counts_all/20210216180259_static_site_editor_views.yml
index 684bf25af10..35698258e53 100644
--- a/config/metrics/counts_all/20210216180259_static_site_editor_views.yml
+++ b/config/metrics/counts_all/20210216180259_static_site_editor_views.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: static_site_editor
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -20,3 +20,4 @@ tier:
performance_indicator_type:
- gmau
- paid_gmau
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180301_static_site_editor_commits.yml b/config/metrics/counts_all/20210216180301_static_site_editor_commits.yml
index 046448d551a..9f248e812f5 100644
--- a/config/metrics/counts_all/20210216180301_static_site_editor_commits.yml
+++ b/config/metrics/counts_all/20210216180301_static_site_editor_commits.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: static_site_editor
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180303_static_site_editor_merge_requests.yml b/config/metrics/counts_all/20210216180303_static_site_editor_merge_requests.yml
index 62741924580..056c718c5eb 100644
--- a/config/metrics/counts_all/20210216180303_static_site_editor_merge_requests.yml
+++ b/config/metrics/counts_all/20210216180303_static_site_editor_merge_requests.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: static_site_editor
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180304_user_preferences_user_gitpod_enabled.yml b/config/metrics/counts_all/20210216180304_user_preferences_user_gitpod_enabled.yml
index ed85c6ba21d..b24b8075439 100644
--- a/config/metrics/counts_all/20210216180304_user_preferences_user_gitpod_enabled.yml
+++ b/config/metrics/counts_all/20210216180304_user_preferences_user_gitpod_enabled.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: web_ide
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180306_snippets.yml b/config/metrics/counts_all/20210216180306_snippets.yml
index 5dcf43846e6..5945b8925aa 100644
--- a/config/metrics/counts_all/20210216180306_snippets.yml
+++ b/config/metrics/counts_all/20210216180306_snippets.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: snippets
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180316_snippets.yml b/config/metrics/counts_all/20210216180316_snippets.yml
index f975500f3e6..2c6f32afcae 100644
--- a/config/metrics/counts_all/20210216180316_snippets.yml
+++ b/config/metrics/counts_all/20210216180316_snippets.yml
@@ -8,7 +8,7 @@ product_stage: create
product_group: group::editor
product_category: snippets
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180410_pool_repositories.yml b/config/metrics/counts_all/20210216180410_pool_repositories.yml
index 06a65c536dd..71d2763685b 100644
--- a/config/metrics/counts_all/20210216180410_pool_repositories.yml
+++ b/config/metrics/counts_all/20210216180410_pool_repositories.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::gitaly
product_category: gitaly
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180413_all_searches.yml b/config/metrics/counts_all/20210216180413_all_searches.yml
index b9a3374b333..cf19868b47f 100644
--- a/config/metrics/counts_all/20210216180413_all_searches.yml
+++ b/config/metrics/counts_all/20210216180413_all_searches.yml
@@ -8,7 +8,7 @@ product_stage: enablement
product_group: group::global search
product_category: global_search
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180414_navbar_searches.yml b/config/metrics/counts_all/20210216180414_navbar_searches.yml
index 5cceeecff8a..118ce95550d 100644
--- a/config/metrics/counts_all/20210216180414_navbar_searches.yml
+++ b/config/metrics/counts_all/20210216180414_navbar_searches.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: counts.navbar_searches
-description: Total Searches using the navbar for All Basic Search and Advanced Search in self-managed and SaaS
+description: Total Searches using the navbar for All Basic Search and Advanced Search
+ in self-managed and SaaS
product_section: enablement
product_stage: enablement
product_group: group::global search
product_category: global_search
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180416_i_search_total.yml b/config/metrics/counts_all/20210216180416_i_search_total.yml
index 0e8a7cfecf0..6166ba87ab5 100644
--- a/config/metrics/counts_all/20210216180416_i_search_total.yml
+++ b/config/metrics/counts_all/20210216180416_i_search_total.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::global search
product_category: global_search
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis_hll
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180434_issues_created_from_gitlab_error_tracking_ui.yml b/config/metrics/counts_all/20210216180434_issues_created_from_gitlab_error_tracking_ui.yml
index 67fac53ec4e..14c96ec488c 100644
--- a/config/metrics/counts_all/20210216180434_issues_created_from_gitlab_error_tracking_ui.yml
+++ b/config/metrics/counts_all/20210216180434_issues_created_from_gitlab_error_tracking_ui.yml
@@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: error_tracking
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180436_issues_with_associated_zoom_link.yml b/config/metrics/counts_all/20210216180436_issues_with_associated_zoom_link.yml
index c840150b205..dd5b6d74486 100644
--- a/config/metrics/counts_all/20210216180436_issues_with_associated_zoom_link.yml
+++ b/config/metrics/counts_all/20210216180436_issues_with_associated_zoom_link.yml
@@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180438_issues_using_zoom_quick_actions.yml b/config/metrics/counts_all/20210216180438_issues_using_zoom_quick_actions.yml
index e69555757d8..680d1931eb9 100644
--- a/config/metrics/counts_all/20210216180438_issues_using_zoom_quick_actions.yml
+++ b/config/metrics/counts_all/20210216180438_issues_using_zoom_quick_actions.yml
@@ -8,7 +8,7 @@ product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180440_issues_with_embedded_grafana_charts_approx.yml b/config/metrics/counts_all/20210216180440_issues_with_embedded_grafana_charts_approx.yml
index aebb69d4fe7..7c4c973c370 100644
--- a/config/metrics/counts_all/20210216180440_issues_with_embedded_grafana_charts_approx.yml
+++ b/config/metrics/counts_all/20210216180440_issues_with_embedded_grafana_charts_approx.yml
@@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180441_issues_created_from_alerts.yml b/config/metrics/counts_all/20210216180441_issues_created_from_alerts.yml
index dcce2f4e366..b1e1c4bc24b 100644
--- a/config/metrics/counts_all/20210216180441_issues_created_from_alerts.yml
+++ b/config/metrics/counts_all/20210216180441_issues_created_from_alerts.yml
@@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180443_issues_created_gitlab_alerts.yml b/config/metrics/counts_all/20210216180443_issues_created_gitlab_alerts.yml
index 373a5e6c262..0f09d09a8ac 100644
--- a/config/metrics/counts_all/20210216180443_issues_created_gitlab_alerts.yml
+++ b/config/metrics/counts_all/20210216180443_issues_created_gitlab_alerts.yml
@@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180445_issues_created_manually_from_alerts.yml b/config/metrics/counts_all/20210216180445_issues_created_manually_from_alerts.yml
index a72f821f1e7..d5f0cfbb02f 100644
--- a/config/metrics/counts_all/20210216180445_issues_created_manually_from_alerts.yml
+++ b/config/metrics/counts_all/20210216180445_issues_created_manually_from_alerts.yml
@@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180447_incident_issues.yml b/config/metrics/counts_all/20210216180447_incident_issues.yml
index bc3dd346e4d..b47ba495373 100644
--- a/config/metrics/counts_all/20210216180447_incident_issues.yml
+++ b/config/metrics/counts_all/20210216180447_incident_issues.yml
@@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180449_alert_bot_incident_issues.yml b/config/metrics/counts_all/20210216180449_alert_bot_incident_issues.yml
index 5fa90b9f6c1..3f43709e753 100644
--- a/config/metrics/counts_all/20210216180449_alert_bot_incident_issues.yml
+++ b/config/metrics/counts_all/20210216180449_alert_bot_incident_issues.yml
@@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180451_incident_labeled_issues.yml b/config/metrics/counts_all/20210216180451_incident_labeled_issues.yml
index 9764d0cba4c..cc38c8e75ad 100644
--- a/config/metrics/counts_all/20210216180451_incident_labeled_issues.yml
+++ b/config/metrics/counts_all/20210216180451_incident_labeled_issues.yml
@@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180453_projects_creating_incidents.yml b/config/metrics/counts_all/20210216180453_projects_creating_incidents.yml
index 10f2abcfb84..763ecb49e55 100644
--- a/config/metrics/counts_all/20210216180453_projects_creating_incidents.yml
+++ b/config/metrics/counts_all/20210216180453_projects_creating_incidents.yml
@@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180454_projects_with_error_tracking_enabled.yml b/config/metrics/counts_all/20210216180454_projects_with_error_tracking_enabled.yml
index c5c4a1e90bf..1d2d9bf518c 100644
--- a/config/metrics/counts_all/20210216180454_projects_with_error_tracking_enabled.yml
+++ b/config/metrics/counts_all/20210216180454_projects_with_error_tracking_enabled.yml
@@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: error_tracking
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180456_projects_with_alerts_service_enabled.yml b/config/metrics/counts_all/20210216180456_projects_with_alerts_service_enabled.yml
index f162e767cbe..609760e25c6 100644
--- a/config/metrics/counts_all/20210216180456_projects_with_alerts_service_enabled.yml
+++ b/config/metrics/counts_all/20210216180456_projects_with_alerts_service_enabled.yml
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180458_projects_with_alerts_created.yml b/config/metrics/counts_all/20210216180458_projects_with_alerts_created.yml
index bfca848f0fd..9b85ad8d146 100644
--- a/config/metrics/counts_all/20210216180458_projects_with_alerts_created.yml
+++ b/config/metrics/counts_all/20210216180458_projects_with_alerts_created.yml
@@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: alert_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180500_projects_with_enabled_alert_integrations.yml b/config/metrics/counts_all/20210216180500_projects_with_enabled_alert_integrations.yml
index 6b37f627c95..44301e6a5bc 100644
--- a/config/metrics/counts_all/20210216180500_projects_with_enabled_alert_integrations.yml
+++ b/config/metrics/counts_all/20210216180500_projects_with_enabled_alert_integrations.yml
@@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180517_projects_with_error_tracking_enabled.yml b/config/metrics/counts_all/20210216180517_projects_with_error_tracking_enabled.yml
index b6de290e3ee..fc8c5d59eea 100644
--- a/config/metrics/counts_all/20210216180517_projects_with_error_tracking_enabled.yml
+++ b/config/metrics/counts_all/20210216180517_projects_with_error_tracking_enabled.yml
@@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: error_tracking
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180518_projects_with_incidents.yml b/config/metrics/counts_all/20210216180518_projects_with_incidents.yml
index 5ed0d61b5d1..627328016e2 100644
--- a/config/metrics/counts_all/20210216180518_projects_with_incidents.yml
+++ b/config/metrics/counts_all/20210216180518_projects_with_incidents.yml
@@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180520_projects_with_alert_incidents.yml b/config/metrics/counts_all/20210216180520_projects_with_alert_incidents.yml
index 9a0d7e14566..64844280a58 100644
--- a/config/metrics/counts_all/20210216180520_projects_with_alert_incidents.yml
+++ b/config/metrics/counts_all/20210216180520_projects_with_alert_incidents.yml
@@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180628_projects_imported_from_github.yml b/config/metrics/counts_all/20210216180628_projects_imported_from_github.yml
index 967e060db39..c8732efd549 100644
--- a/config/metrics/counts_all/20210216180628_projects_imported_from_github.yml
+++ b/config/metrics/counts_all/20210216180628_projects_imported_from_github.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180630_projects_imported_from_github.yml b/config/metrics/counts_all/20210216180630_projects_imported_from_github.yml
index 51dd7a63ba4..360bb66dee8 100644
--- a/config/metrics/counts_all/20210216180630_projects_imported_from_github.yml
+++ b/config/metrics/counts_all/20210216180630_projects_imported_from_github.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180632_unique_users_all_imports.yml b/config/metrics/counts_all/20210216180632_unique_users_all_imports.yml
index f2ee013002c..df9c9d99eb1 100644
--- a/config/metrics/counts_all/20210216180632_unique_users_all_imports.yml
+++ b/config/metrics/counts_all/20210216180632_unique_users_all_imports.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180634_gitlab.yml b/config/metrics/counts_all/20210216180634_gitlab.yml
index c578ff7bab0..c157ae84873 100644
--- a/config/metrics/counts_all/20210216180634_gitlab.yml
+++ b/config/metrics/counts_all/20210216180634_gitlab.yml
@@ -18,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180636_gitlab_v1.yml b/config/metrics/counts_all/20210216180636_gitlab_v1.yml
index 80cf9db3e46..d390645eada 100644
--- a/config/metrics/counts_all/20210216180636_gitlab_v1.yml
+++ b/config/metrics/counts_all/20210216180636_gitlab_v1.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180638_gitlab_project.yml b/config/metrics/counts_all/20210216180638_gitlab_project.yml
index 60f3a0e6bd6..9f31a887b87 100644
--- a/config/metrics/counts_all/20210216180638_gitlab_project.yml
+++ b/config/metrics/counts_all/20210216180638_gitlab_project.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180639_gitlab.yml b/config/metrics/counts_all/20210216180639_gitlab.yml
index 66b4511cc75..a19b04ac6e1 100644
--- a/config/metrics/counts_all/20210216180639_gitlab.yml
+++ b/config/metrics/counts_all/20210216180639_gitlab.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180641_github.yml b/config/metrics/counts_all/20210216180641_github.yml
index 6ebb762be0d..a6ab0bd5b7f 100644
--- a/config/metrics/counts_all/20210216180641_github.yml
+++ b/config/metrics/counts_all/20210216180641_github.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180643_bitbucket.yml b/config/metrics/counts_all/20210216180643_bitbucket.yml
index 1b683d1414d..9239f592c23 100644
--- a/config/metrics/counts_all/20210216180643_bitbucket.yml
+++ b/config/metrics/counts_all/20210216180643_bitbucket.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180645_bitbucket_server.yml b/config/metrics/counts_all/20210216180645_bitbucket_server.yml
index a7d6481a0d1..bbeb3b2c7d3 100644
--- a/config/metrics/counts_all/20210216180645_bitbucket_server.yml
+++ b/config/metrics/counts_all/20210216180645_bitbucket_server.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180647_gitea.yml b/config/metrics/counts_all/20210216180647_gitea.yml
index 4cf1ebfd78f..448663cda8b 100644
--- a/config/metrics/counts_all/20210216180647_gitea.yml
+++ b/config/metrics/counts_all/20210216180647_gitea.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180649_git.yml b/config/metrics/counts_all/20210216180649_git.yml
index 9c60f4a2302..3fee6391a56 100644
--- a/config/metrics/counts_all/20210216180649_git.yml
+++ b/config/metrics/counts_all/20210216180649_git.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180650_manifest.yml b/config/metrics/counts_all/20210216180650_manifest.yml
index ee1037328de..af2a3567e74 100644
--- a/config/metrics/counts_all/20210216180650_manifest.yml
+++ b/config/metrics/counts_all/20210216180650_manifest.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180652_gitlab_migration.yml b/config/metrics/counts_all/20210216180652_gitlab_migration.yml
index 8aa45dee434..2652673fff7 100644
--- a/config/metrics/counts_all/20210216180652_gitlab_migration.yml
+++ b/config/metrics/counts_all/20210216180652_gitlab_migration.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180654_jira.yml b/config/metrics/counts_all/20210216180654_jira.yml
index 7c7a2739576..890e4b46391 100644
--- a/config/metrics/counts_all/20210216180654_jira.yml
+++ b/config/metrics/counts_all/20210216180654_jira.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180656_fogbugz.yml b/config/metrics/counts_all/20210216180656_fogbugz.yml
index 2d4e5ddcc02..217a8d6013c 100644
--- a/config/metrics/counts_all/20210216180656_fogbugz.yml
+++ b/config/metrics/counts_all/20210216180656_fogbugz.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180658_phabricator.yml b/config/metrics/counts_all/20210216180658_phabricator.yml
index e5cdd3f382b..becf44044df 100644
--- a/config/metrics/counts_all/20210216180658_phabricator.yml
+++ b/config/metrics/counts_all/20210216180658_phabricator.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180700_csv.yml b/config/metrics/counts_all/20210216180700_csv.yml
index b69251a5b0b..78322ba56b2 100644
--- a/config/metrics/counts_all/20210216180700_csv.yml
+++ b/config/metrics/counts_all/20210216180700_csv.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180702_group_import.yml b/config/metrics/counts_all/20210216180702_group_import.yml
index 45e2650d69e..68042d4a4a3 100644
--- a/config/metrics/counts_all/20210216180702_group_import.yml
+++ b/config/metrics/counts_all/20210216180702_group_import.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180703_gitlab_migration.yml b/config/metrics/counts_all/20210216180703_gitlab_migration.yml
index 10b549ca252..b25e0d72ad8 100644
--- a/config/metrics/counts_all/20210216180703_gitlab_migration.yml
+++ b/config/metrics/counts_all/20210216180703_gitlab_migration.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180705_total.yml b/config/metrics/counts_all/20210216180705_total.yml
index ca7cab549c1..5d76fd3873b 100644
--- a/config/metrics/counts_all/20210216180705_total.yml
+++ b/config/metrics/counts_all/20210216180705_total.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180707_gitlab_project.yml b/config/metrics/counts_all/20210216180707_gitlab_project.yml
index 3ed628fd20d..f0d513e80b3 100644
--- a/config/metrics/counts_all/20210216180707_gitlab_project.yml
+++ b/config/metrics/counts_all/20210216180707_gitlab_project.yml
@@ -1,7 +1,7 @@
---
data_category: optional
key_path: usage_activity_by_stage.manage.projects_imported.gitlab_project
-description: 'Distinct count of users that imported projects using Project Import/Export'
+description: Distinct count of users that imported projects using Project Import/Export
product_section: dev
product_stage: manage
product_group: group::import
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180709_gitlab.yml b/config/metrics/counts_all/20210216180709_gitlab.yml
index d8c23badb74..ea5e3b25775 100644
--- a/config/metrics/counts_all/20210216180709_gitlab.yml
+++ b/config/metrics/counts_all/20210216180709_gitlab.yml
@@ -1,7 +1,7 @@
---
data_category: optional
key_path: usage_activity_by_stage.manage.projects_imported.gitlab
-description: 'Distinct count of users that imported projects from GitLab.com'
+description: Distinct count of users that imported projects from GitLab.com
product_section: dev
product_stage: manage
product_group: group::import
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180711_github.yml b/config/metrics/counts_all/20210216180711_github.yml
index 4c7444c7805..cd3fd06d057 100644
--- a/config/metrics/counts_all/20210216180711_github.yml
+++ b/config/metrics/counts_all/20210216180711_github.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180713_bitbucket.yml b/config/metrics/counts_all/20210216180713_bitbucket.yml
index 2d3dc154324..d0eb23fc41a 100644
--- a/config/metrics/counts_all/20210216180713_bitbucket.yml
+++ b/config/metrics/counts_all/20210216180713_bitbucket.yml
@@ -1,7 +1,7 @@
---
data_category: optional
key_path: usage_activity_by_stage.manage.projects_imported.bitbucket
-description: 'Distinct count of users that imported projects from Bitbucket Cloud'
+description: Distinct count of users that imported projects from Bitbucket Cloud
product_section: dev
product_stage: manage
product_group: group::import
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180715_bitbucket_server.yml b/config/metrics/counts_all/20210216180715_bitbucket_server.yml
index 82a675b5428..9a3de0cb330 100644
--- a/config/metrics/counts_all/20210216180715_bitbucket_server.yml
+++ b/config/metrics/counts_all/20210216180715_bitbucket_server.yml
@@ -1,7 +1,7 @@
---
data_category: optional
key_path: usage_activity_by_stage.manage.projects_imported.bitbucket_server
-description: 'Distinct count of users that imported projects from Bitbucket Server'
+description: Distinct count of users that imported projects from Bitbucket Server
product_section: dev
product_stage: manage
product_group: group::import
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180716_gitea.yml b/config/metrics/counts_all/20210216180716_gitea.yml
index 50d5923e377..b107b213a30 100644
--- a/config/metrics/counts_all/20210216180716_gitea.yml
+++ b/config/metrics/counts_all/20210216180716_gitea.yml
@@ -1,7 +1,7 @@
---
data_category: optional
key_path: usage_activity_by_stage.manage.projects_imported.gitea
-description: 'Distinct count of users that imported projects from Gitea'
+description: Distinct count of users that imported projects from Gitea
product_section: dev
product_stage: manage
product_group: group::import
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180718_git.yml b/config/metrics/counts_all/20210216180718_git.yml
index f9f648bb713..0cd399a65ec 100644
--- a/config/metrics/counts_all/20210216180718_git.yml
+++ b/config/metrics/counts_all/20210216180718_git.yml
@@ -1,7 +1,7 @@
---
data_category: optional
key_path: usage_activity_by_stage.manage.projects_imported.git
-description: 'Distinct count of users that imported projects using Import by URL'
+description: Distinct count of users that imported projects using Import by URL
product_section: dev
product_stage: manage
product_group: group::import
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180720_manifest.yml b/config/metrics/counts_all/20210216180720_manifest.yml
index 28b689eddcf..b91ae015f6e 100644
--- a/config/metrics/counts_all/20210216180720_manifest.yml
+++ b/config/metrics/counts_all/20210216180720_manifest.yml
@@ -1,7 +1,7 @@
---
data_category: optional
key_path: usage_activity_by_stage.manage.projects_imported.manifest
-description: 'Distinct count of users that imported projects using Manifest file'
+description: Distinct count of users that imported projects using Manifest file
product_section: dev
product_stage: manage
product_group: group::import
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180722_jira.yml b/config/metrics/counts_all/20210216180722_jira.yml
index add51bcf494..89ea9da081d 100644
--- a/config/metrics/counts_all/20210216180722_jira.yml
+++ b/config/metrics/counts_all/20210216180722_jira.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180724_fogbugz.yml b/config/metrics/counts_all/20210216180724_fogbugz.yml
index 45dd4ee1f50..e9cb3159301 100644
--- a/config/metrics/counts_all/20210216180724_fogbugz.yml
+++ b/config/metrics/counts_all/20210216180724_fogbugz.yml
@@ -1,7 +1,7 @@
---
data_category: optional
key_path: usage_activity_by_stage.manage.issues_imported.fogbugz
-description: 'Distinct count of users that imported issues into projects using FogBugz'
+description: Distinct count of users that imported issues into projects using FogBugz
product_section: dev
product_stage: manage
product_group: group::import
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180726_phabricator.yml b/config/metrics/counts_all/20210216180726_phabricator.yml
index c006ac22b75..933047aff58 100644
--- a/config/metrics/counts_all/20210216180726_phabricator.yml
+++ b/config/metrics/counts_all/20210216180726_phabricator.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180727_csv.yml b/config/metrics/counts_all/20210216180727_csv.yml
index 6a6f16e09ef..e6bc3eba973 100644
--- a/config/metrics/counts_all/20210216180727_csv.yml
+++ b/config/metrics/counts_all/20210216180727_csv.yml
@@ -18,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180729_groups_imported.yml b/config/metrics/counts_all/20210216180729_groups_imported.yml
index 04e1febb437..32e968c76e2 100644
--- a/config/metrics/counts_all/20210216180729_groups_imported.yml
+++ b/config/metrics/counts_all/20210216180729_groups_imported.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180734_wiki_pages_create.yml b/config/metrics/counts_all/20210216180734_wiki_pages_create.yml
index 25326291509..e30c339d73c 100644
--- a/config/metrics/counts_all/20210216180734_wiki_pages_create.yml
+++ b/config/metrics/counts_all/20210216180734_wiki_pages_create.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: wiki
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180736_wiki_pages_update.yml b/config/metrics/counts_all/20210216180736_wiki_pages_update.yml
index 82736e363ae..de168835e07 100644
--- a/config/metrics/counts_all/20210216180736_wiki_pages_update.yml
+++ b/config/metrics/counts_all/20210216180736_wiki_pages_update.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: wiki
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180738_wiki_pages_delete.yml b/config/metrics/counts_all/20210216180738_wiki_pages_delete.yml
index 26b88ba5c9f..d9175cd64e8 100644
--- a/config/metrics/counts_all/20210216180738_wiki_pages_delete.yml
+++ b/config/metrics/counts_all/20210216180738_wiki_pages_delete.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: wiki
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180740_design_management_designs_create.yml b/config/metrics/counts_all/20210216180740_design_management_designs_create.yml
index 3332d1963ba..82575446cdc 100644
--- a/config/metrics/counts_all/20210216180740_design_management_designs_create.yml
+++ b/config/metrics/counts_all/20210216180740_design_management_designs_create.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::product planning
product_category: design_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180741_design_management_designs_update.yml b/config/metrics/counts_all/20210216180741_design_management_designs_update.yml
index 3911079ef56..49894014da5 100644
--- a/config/metrics/counts_all/20210216180741_design_management_designs_update.yml
+++ b/config/metrics/counts_all/20210216180741_design_management_designs_update.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::product planning
product_category: design_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180743_design_management_designs_delete.yml b/config/metrics/counts_all/20210216180743_design_management_designs_delete.yml
index c6900276ef7..173c9522c39 100644
--- a/config/metrics/counts_all/20210216180743_design_management_designs_delete.yml
+++ b/config/metrics/counts_all/20210216180743_design_management_designs_delete.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::product planning
product_category: design_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180750_groups.yml b/config/metrics/counts_all/20210216180750_groups.yml
index 6163cbab8ad..67419cf9b82 100644
--- a/config/metrics/counts_all/20210216180750_groups.yml
+++ b/config/metrics/counts_all/20210216180750_groups.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::access
product_category: subgroups
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180752_keys.yml b/config/metrics/counts_all/20210216180752_keys.yml
index d105e047d49..d5c50688915 100644
--- a/config/metrics/counts_all/20210216180752_keys.yml
+++ b/config/metrics/counts_all/20210216180752_keys.yml
@@ -7,7 +7,7 @@ product_stage: managed
product_group: group::access
product_category: authentication_and_authorization
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180754_events.yml b/config/metrics/counts_all/20210216180754_events.yml
index 8d1a58f1820..1dfeadbbdfe 100644
--- a/config/metrics/counts_all/20210216180754_events.yml
+++ b/config/metrics/counts_all/20210216180754_events.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::manage
product_category:
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180756_groups.yml b/config/metrics/counts_all/20210216180756_groups.yml
index 938a95c5911..24d0268165e 100644
--- a/config/metrics/counts_all/20210216180756_groups.yml
+++ b/config/metrics/counts_all/20210216180756_groups.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::access
product_category: subgroups
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180758_users_created.yml b/config/metrics/counts_all/20210216180758_users_created.yml
index 816887531b6..3a815026d24 100644
--- a/config/metrics/counts_all/20210216180758_users_created.yml
+++ b/config/metrics/counts_all/20210216180758_users_created.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::access
product_category:
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180927_grafana_integrated_projects.yml b/config/metrics/counts_all/20210216180927_grafana_integrated_projects.yml
index f46bc3b8566..0e2ac43de54 100644
--- a/config/metrics/counts_all/20210216180927_grafana_integrated_projects.yml
+++ b/config/metrics/counts_all/20210216180927_grafana_integrated_projects.yml
@@ -3,15 +3,19 @@ data_category: optional
key_path: counts.grafana_integrated_projects
description: Total Grafana integrations attached to projects
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: metrics
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
- ce
+- ee
tier:
- free
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180929_projects_with_tracing_enabled.yml b/config/metrics/counts_all/20210216180929_projects_with_tracing_enabled.yml
index 211115a0856..87668ca0e4f 100644
--- a/config/metrics/counts_all/20210216180929_projects_with_tracing_enabled.yml
+++ b/config/metrics/counts_all/20210216180929_projects_with_tracing_enabled.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.projects_with_tracing_enabled
description: Projects with tracing enabled
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: tracing
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180931_projects_prometheus_active.yml b/config/metrics/counts_all/20210216180931_projects_prometheus_active.yml
index 9b4c7e4e145..c79a1ee24b9 100644
--- a/config/metrics/counts_all/20210216180931_projects_prometheus_active.yml
+++ b/config/metrics/counts_all/20210216180931_projects_prometheus_active.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.projects_prometheus_active
description: Count of projects with active integrations for Prometheus
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: metrics
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180933_groups_prometheus_active.yml b/config/metrics/counts_all/20210216180933_groups_prometheus_active.yml
index 44f7150cb66..3cc8dcb47c8 100644
--- a/config/metrics/counts_all/20210216180933_groups_prometheus_active.yml
+++ b/config/metrics/counts_all/20210216180933_groups_prometheus_active.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.groups_prometheus_active
description: Count of groups with active integrations for Prometheus
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: metrics
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180934_templates_prometheus_active.yml b/config/metrics/counts_all/20210216180934_templates_prometheus_active.yml
index eba4f2f5741..4bf8911c666 100644
--- a/config/metrics/counts_all/20210216180934_templates_prometheus_active.yml
+++ b/config/metrics/counts_all/20210216180934_templates_prometheus_active.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.templates_prometheus_active
description: Count of active service templates for Prometheus
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: metrics
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180936_instances_prometheus_active.yml b/config/metrics/counts_all/20210216180936_instances_prometheus_active.yml
index 3c03a3b2eae..7308e5c82b4 100644
--- a/config/metrics/counts_all/20210216180936_instances_prometheus_active.yml
+++ b/config/metrics/counts_all/20210216180936_instances_prometheus_active.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.instances_prometheus_active
description: Count of active instance-level integrations for Prometheus
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: metrics
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180938_projects_inheriting_prometheus_active.yml b/config/metrics/counts_all/20210216180938_projects_inheriting_prometheus_active.yml
index d89a809a613..32b59d9948a 100644
--- a/config/metrics/counts_all/20210216180938_projects_inheriting_prometheus_active.yml
+++ b/config/metrics/counts_all/20210216180938_projects_inheriting_prometheus_active.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.projects_inheriting_prometheus_active
description: Count of active projects inheriting integrations for Prometheus
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: metrics
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180940_groups_inheriting_prometheus_active.yml b/config/metrics/counts_all/20210216180940_groups_inheriting_prometheus_active.yml
index 0d3f11e9a1a..0604fadab62 100644
--- a/config/metrics/counts_all/20210216180940_groups_inheriting_prometheus_active.yml
+++ b/config/metrics/counts_all/20210216180940_groups_inheriting_prometheus_active.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.groups_inheriting_prometheus_active
description: Count of active groups inheriting integrations for Prometheus
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: metrics
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180942_operations_dashboard_default_dashboard.yml b/config/metrics/counts_all/20210216180942_operations_dashboard_default_dashboard.yml
index 3038e53932c..3d00a873ea3 100644
--- a/config/metrics/counts_all/20210216180942_operations_dashboard_default_dashboard.yml
+++ b/config/metrics/counts_all/20210216180942_operations_dashboard_default_dashboard.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.operations_dashboard_default_dashboard
description: Active users with enabled operations dashboard
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: metrics
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180944_operations_dashboard_users_with_projects_added.yml b/config/metrics/counts_all/20210216180944_operations_dashboard_users_with_projects_added.yml
index 4802532c053..c510f56b392 100644
--- a/config/metrics/counts_all/20210216180944_operations_dashboard_users_with_projects_added.yml
+++ b/config/metrics/counts_all/20210216180944_operations_dashboard_users_with_projects_added.yml
@@ -3,11 +3,11 @@ data_category: optional
key_path: counts.operations_dashboard_users_with_projects_added
description: Active users with projects on operations dashboard
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: metrics
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180945_clusters.yml b/config/metrics/counts_all/20210216180945_clusters.yml
index 2294cd5e1de..ef1694a274f 100644
--- a/config/metrics/counts_all/20210216180945_clusters.yml
+++ b/config/metrics/counts_all/20210216180945_clusters.yml
@@ -3,17 +3,18 @@ data_category: optional
key_path: usage_activity_by_stage.monitor.clusters
description: Users creating clusters.
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: metrics
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
- - ce
- - ee
+- ce
+- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180947_clusters_applications_prometheus.yml b/config/metrics/counts_all/20210216180947_clusters_applications_prometheus.yml
index a921b517b40..a43dc103f9c 100644
--- a/config/metrics/counts_all/20210216180947_clusters_applications_prometheus.yml
+++ b/config/metrics/counts_all/20210216180947_clusters_applications_prometheus.yml
@@ -3,17 +3,18 @@ data_category: optional
key_path: usage_activity_by_stage.monitor.clusters_applications_prometheus
description: Users creating clusters with Prometheus enabled.
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: metrics
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
- - ce
- - ee
+- ce
+- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180949_operations_dashboard_default_dashboard.yml b/config/metrics/counts_all/20210216180949_operations_dashboard_default_dashboard.yml
index 278cd3d6337..618f0049e50 100644
--- a/config/metrics/counts_all/20210216180949_operations_dashboard_default_dashboard.yml
+++ b/config/metrics/counts_all/20210216180949_operations_dashboard_default_dashboard.yml
@@ -3,16 +3,17 @@ data_category: optional
key_path: usage_activity_by_stage.monitor.operations_dashboard_default_dashboard
description: Active users with enabled operations dashboard
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: metrics
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
- - ce
- - ee
+- ce
+- ee
tier:
- - free
- - premium
+- free
+- premium
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180951_projects_with_tracing_enabled.yml b/config/metrics/counts_all/20210216180951_projects_with_tracing_enabled.yml
index 6d1d00cd1e3..3532dc60ff0 100644
--- a/config/metrics/counts_all/20210216180951_projects_with_tracing_enabled.yml
+++ b/config/metrics/counts_all/20210216180951_projects_with_tracing_enabled.yml
@@ -3,17 +3,18 @@ data_category: optional
key_path: usage_activity_by_stage.monitor.projects_with_tracing_enabled
description: Projects with tracing enabled
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: tracing
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
- - ce
- - ee
+- ce
+- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216180953_operations_dashboard_users_with_projects_added.yml b/config/metrics/counts_all/20210216180953_operations_dashboard_users_with_projects_added.yml
index 13971a4fc71..1f80f3a935d 100644
--- a/config/metrics/counts_all/20210216180953_operations_dashboard_users_with_projects_added.yml
+++ b/config/metrics/counts_all/20210216180953_operations_dashboard_users_with_projects_added.yml
@@ -3,17 +3,18 @@ data_category: optional
key_path: usage_activity_by_stage.monitor.operations_dashboard_users_with_projects_added
description: Active users with projects on operations dashboard
product_section: ops
-product_stage:
+product_stage: monitor
product_group: group::monitor
product_category: metrics
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
- - ce
- - ee
+- ce
+- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181009_lfs_objects.yml b/config/metrics/counts_all/20210216181009_lfs_objects.yml
index cb8b2fc5474..5b025ff4947 100644
--- a/config/metrics/counts_all/20210216181009_lfs_objects.yml
+++ b/config/metrics/counts_all/20210216181009_lfs_objects.yml
@@ -1,18 +1,21 @@
---
data_category: optional
key_path: counts.lfs_objects
-description:
+description: Count of lfs objects
product_section: ops
product_stage: create
product_group: group::create
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181011_projects_with_packages.yml b/config/metrics/counts_all/20210216181011_projects_with_packages.yml
index 59edfc3634d..e26cae87f95 100644
--- a/config/metrics/counts_all/20210216181011_projects_with_packages.yml
+++ b/config/metrics/counts_all/20210216181011_projects_with_packages.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181012_packages.yml b/config/metrics/counts_all/20210216181012_packages.yml
index ec5e1ae7831..65cc8b20b0d 100644
--- a/config/metrics/counts_all/20210216181012_packages.yml
+++ b/config/metrics/counts_all/20210216181012_packages.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181014_projects_with_expiration_policy_disabled.yml b/config/metrics/counts_all/20210216181014_projects_with_expiration_policy_disabled.yml
index 14cefebb514..0a6e00a0006 100644
--- a/config/metrics/counts_all/20210216181014_projects_with_expiration_policy_disabled.yml
+++ b/config/metrics/counts_all/20210216181014_projects_with_expiration_policy_disabled.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181016_projects_with_expiration_policy_enabled.yml b/config/metrics/counts_all/20210216181016_projects_with_expiration_policy_enabled.yml
index 54ab06ea5c4..c21b1eeb2cc 100644
--- a/config/metrics/counts_all/20210216181016_projects_with_expiration_policy_enabled.yml
+++ b/config/metrics/counts_all/20210216181016_projects_with_expiration_policy_enabled.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181018_projects_with_expiration_policy_enabled_with_keep_n_set_to_1.yml b/config/metrics/counts_all/20210216181018_projects_with_expiration_policy_enabled_with_keep_n_set_to_1.yml
index 3b742c68758..9b786709798 100644
--- a/config/metrics/counts_all/20210216181018_projects_with_expiration_policy_enabled_with_keep_n_set_to_1.yml
+++ b/config/metrics/counts_all/20210216181018_projects_with_expiration_policy_enabled_with_keep_n_set_to_1.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181020_projects_with_expiration_policy_enabled_with_keep_n_set_to_5.yml b/config/metrics/counts_all/20210216181020_projects_with_expiration_policy_enabled_with_keep_n_set_to_5.yml
index 1681e2c642e..92f242f0a1c 100644
--- a/config/metrics/counts_all/20210216181020_projects_with_expiration_policy_enabled_with_keep_n_set_to_5.yml
+++ b/config/metrics/counts_all/20210216181020_projects_with_expiration_policy_enabled_with_keep_n_set_to_5.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181022_projects_with_expiration_policy_enabled_with_keep_n_set_to_10.yml b/config/metrics/counts_all/20210216181022_projects_with_expiration_policy_enabled_with_keep_n_set_to_10.yml
index 3f5ee49993a..0b2f360437e 100644
--- a/config/metrics/counts_all/20210216181022_projects_with_expiration_policy_enabled_with_keep_n_set_to_10.yml
+++ b/config/metrics/counts_all/20210216181022_projects_with_expiration_policy_enabled_with_keep_n_set_to_10.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181024_projects_with_expiration_policy_enabled_with_keep_n_set_to_25.yml b/config/metrics/counts_all/20210216181024_projects_with_expiration_policy_enabled_with_keep_n_set_to_25.yml
index a18a4fa12d8..756ddb1f11b 100644
--- a/config/metrics/counts_all/20210216181024_projects_with_expiration_policy_enabled_with_keep_n_set_to_25.yml
+++ b/config/metrics/counts_all/20210216181024_projects_with_expiration_policy_enabled_with_keep_n_set_to_25.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181025_projects_with_expiration_policy_enabled_with_keep_n_set_to_50.yml b/config/metrics/counts_all/20210216181025_projects_with_expiration_policy_enabled_with_keep_n_set_to_50.yml
index bd7d576520e..5b5b0d3734c 100644
--- a/config/metrics/counts_all/20210216181025_projects_with_expiration_policy_enabled_with_keep_n_set_to_50.yml
+++ b/config/metrics/counts_all/20210216181025_projects_with_expiration_policy_enabled_with_keep_n_set_to_50.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181027_projects_with_expiration_policy_enabled_with_keep_n_set_to_100.yml b/config/metrics/counts_all/20210216181027_projects_with_expiration_policy_enabled_with_keep_n_set_to_100.yml
index 420c428e46c..8b4ebb9b020 100644
--- a/config/metrics/counts_all/20210216181027_projects_with_expiration_policy_enabled_with_keep_n_set_to_100.yml
+++ b/config/metrics/counts_all/20210216181027_projects_with_expiration_policy_enabled_with_keep_n_set_to_100.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181029_projects_with_expiration_policy_enabled_with_cadence_set_to_1d.yml b/config/metrics/counts_all/20210216181029_projects_with_expiration_policy_enabled_with_cadence_set_to_1d.yml
index 21cd670e5aa..d1033a11ea5 100644
--- a/config/metrics/counts_all/20210216181029_projects_with_expiration_policy_enabled_with_cadence_set_to_1d.yml
+++ b/config/metrics/counts_all/20210216181029_projects_with_expiration_policy_enabled_with_cadence_set_to_1d.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181031_projects_with_expiration_policy_enabled_with_cadence_set_to_7d.yml b/config/metrics/counts_all/20210216181031_projects_with_expiration_policy_enabled_with_cadence_set_to_7d.yml
index d6b0d0dc1d6..9e8db324e41 100644
--- a/config/metrics/counts_all/20210216181031_projects_with_expiration_policy_enabled_with_cadence_set_to_7d.yml
+++ b/config/metrics/counts_all/20210216181031_projects_with_expiration_policy_enabled_with_cadence_set_to_7d.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181033_projects_with_expiration_policy_enabled_with_cadence_set_to_14d.yml b/config/metrics/counts_all/20210216181033_projects_with_expiration_policy_enabled_with_cadence_set_to_14d.yml
index 9c4d4b83be9..19360edf23f 100644
--- a/config/metrics/counts_all/20210216181033_projects_with_expiration_policy_enabled_with_cadence_set_to_14d.yml
+++ b/config/metrics/counts_all/20210216181033_projects_with_expiration_policy_enabled_with_cadence_set_to_14d.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181035_projects_with_expiration_policy_enabled_with_cadence_set_to_1month.yml b/config/metrics/counts_all/20210216181035_projects_with_expiration_policy_enabled_with_cadence_set_to_1month.yml
index 963665a5ee0..946330fb339 100644
--- a/config/metrics/counts_all/20210216181035_projects_with_expiration_policy_enabled_with_cadence_set_to_1month.yml
+++ b/config/metrics/counts_all/20210216181035_projects_with_expiration_policy_enabled_with_cadence_set_to_1month.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181037_projects_with_expiration_policy_enabled_with_cadence_set_to_3month.yml b/config/metrics/counts_all/20210216181037_projects_with_expiration_policy_enabled_with_cadence_set_to_3month.yml
index 8fa068bb372..c24f474379a 100644
--- a/config/metrics/counts_all/20210216181037_projects_with_expiration_policy_enabled_with_cadence_set_to_3month.yml
+++ b/config/metrics/counts_all/20210216181037_projects_with_expiration_policy_enabled_with_cadence_set_to_3month.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181038_projects_with_expiration_policy_enabled_with_older_than_set_to_7d.yml b/config/metrics/counts_all/20210216181038_projects_with_expiration_policy_enabled_with_older_than_set_to_7d.yml
index 3742446b11a..76f20bc31b6 100644
--- a/config/metrics/counts_all/20210216181038_projects_with_expiration_policy_enabled_with_older_than_set_to_7d.yml
+++ b/config/metrics/counts_all/20210216181038_projects_with_expiration_policy_enabled_with_older_than_set_to_7d.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: counts.projects_with_expiration_policy_enabled_with_older_than_set_to_7d
-description: A count of projects with the cleanup policy set delete tags older than 7 days
+description: A count of projects with the cleanup policy set delete tags older than
+ 7 days
product_section: ops
product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181040_projects_with_expiration_policy_enabled_with_older_than_set_to_14d.yml b/config/metrics/counts_all/20210216181040_projects_with_expiration_policy_enabled_with_older_than_set_to_14d.yml
index 1216a041bfb..0f60e003840 100644
--- a/config/metrics/counts_all/20210216181040_projects_with_expiration_policy_enabled_with_older_than_set_to_14d.yml
+++ b/config/metrics/counts_all/20210216181040_projects_with_expiration_policy_enabled_with_older_than_set_to_14d.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: counts.projects_with_expiration_policy_enabled_with_older_than_set_to_14d
-description: A count of projects with the cleanup policy set delete tags older than 14 days
+description: A count of projects with the cleanup policy set delete tags older than
+ 14 days
product_section: ops
product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181042_projects_with_expiration_policy_enabled_with_older_than_set_to_30d.yml b/config/metrics/counts_all/20210216181042_projects_with_expiration_policy_enabled_with_older_than_set_to_30d.yml
index 387bf3dff90..90d034f8294 100644
--- a/config/metrics/counts_all/20210216181042_projects_with_expiration_policy_enabled_with_older_than_set_to_30d.yml
+++ b/config/metrics/counts_all/20210216181042_projects_with_expiration_policy_enabled_with_older_than_set_to_30d.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: counts.projects_with_expiration_policy_enabled_with_older_than_set_to_30d
-description: A count of projects with the cleanup policy set delete tags older than 30 days
+description: A count of projects with the cleanup policy set delete tags older than
+ 30 days
product_section: ops
product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181044_projects_with_expiration_policy_enabled_with_older_than_set_to_90d.yml b/config/metrics/counts_all/20210216181044_projects_with_expiration_policy_enabled_with_older_than_set_to_90d.yml
index 8dcfbc1ce02..6add782766a 100644
--- a/config/metrics/counts_all/20210216181044_projects_with_expiration_policy_enabled_with_older_than_set_to_90d.yml
+++ b/config/metrics/counts_all/20210216181044_projects_with_expiration_policy_enabled_with_older_than_set_to_90d.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: counts.projects_with_expiration_policy_enabled_with_older_than_set_to_90d
-description: A count of projects with the cleanup policy set delete tags older than 90 days
+description: A count of projects with the cleanup policy set delete tags older than
+ 90 days
product_section: ops
product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181046_projects_with_expiration_policy_enabled_with_keep_n_unset.yml b/config/metrics/counts_all/20210216181046_projects_with_expiration_policy_enabled_with_keep_n_unset.yml
index 29fe874c89e..67c18c86aee 100644
--- a/config/metrics/counts_all/20210216181046_projects_with_expiration_policy_enabled_with_keep_n_unset.yml
+++ b/config/metrics/counts_all/20210216181046_projects_with_expiration_policy_enabled_with_keep_n_unset.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: counts.projects_with_expiration_policy_enabled_with_keep_n_unset
-description: A count of projects with the cleanup policy with the number of tags to keep unset
+description: A count of projects with the cleanup policy with the number of tags to
+ keep unset
product_section: ops
product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181048_projects_with_expiration_policy_enabled_with_older_than_unset.yml b/config/metrics/counts_all/20210216181048_projects_with_expiration_policy_enabled_with_older_than_unset.yml
index 475b52f856f..205f46dd8a2 100644
--- a/config/metrics/counts_all/20210216181048_projects_with_expiration_policy_enabled_with_older_than_unset.yml
+++ b/config/metrics/counts_all/20210216181048_projects_with_expiration_policy_enabled_with_older_than_unset.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: counts.projects_with_expiration_policy_enabled_with_older_than_unset
-description: A count of projects with the cleanup policy with the number of tags to delete unset
+description: A count of projects with the cleanup policy with the number of tags to
+ delete unset
product_section: ops
product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181051_vendor.yml b/config/metrics/counts_all/20210216181051_vendor.yml
index 840054e4263..82bf1d6393a 100644
--- a/config/metrics/counts_all/20210216181051_vendor.yml
+++ b/config/metrics/counts_all/20210216181051_vendor.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: container_registry_server.vendor
-description: Identifies if a user is using an external container registry and what type
+description: Identifies if a user is using an external container registry and what
+ type
product_section: ops
product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181055_projects_with_packages.yml b/config/metrics/counts_all/20210216181055_projects_with_packages.yml
index 99c51335b80..cc2fa107b47 100644
--- a/config/metrics/counts_all/20210216181055_projects_with_packages.yml
+++ b/config/metrics/counts_all/20210216181055_projects_with_packages.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181102_issues.yml b/config/metrics/counts_all/20210216181102_issues.yml
index 8777da9942f..b902437e2f9 100644
--- a/config/metrics/counts_all/20210216181102_issues.yml
+++ b/config/metrics/counts_all/20210216181102_issues.yml
@@ -4,10 +4,10 @@ key_path: counts.issues
description: Count of Issues created
product_section: dev
product_stage: plan
-product_group: group::plan
+product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
instrumentation_class: CountIssuesMetric
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181104_label_lists.yml b/config/metrics/counts_all/20210216181104_label_lists.yml
index 247e891e956..fd58d1866bb 100644
--- a/config/metrics/counts_all/20210216181104_label_lists.yml
+++ b/config/metrics/counts_all/20210216181104_label_lists.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: boards
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181108_milestones.yml b/config/metrics/counts_all/20210216181108_milestones.yml
index 720c7ae0bc0..aa7c8f90f80 100644
--- a/config/metrics/counts_all/20210216181108_milestones.yml
+++ b/config/metrics/counts_all/20210216181108_milestones.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181109_uploads.yml b/config/metrics/counts_all/20210216181109_uploads.yml
index 42ba5feb46d..220009a2ff5 100644
--- a/config/metrics/counts_all/20210216181109_uploads.yml
+++ b/config/metrics/counts_all/20210216181109_uploads.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181111_labels.yml b/config/metrics/counts_all/20210216181111_labels.yml
index 3a0a200754e..48980c7cba4 100644
--- a/config/metrics/counts_all/20210216181111_labels.yml
+++ b/config/metrics/counts_all/20210216181111_labels.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181113_notes.yml b/config/metrics/counts_all/20210216181113_notes.yml
index 5d2c4a029e3..2d5d5c405cd 100644
--- a/config/metrics/counts_all/20210216181113_notes.yml
+++ b/config/metrics/counts_all/20210216181113_notes.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181115_issues.yml b/config/metrics/counts_all/20210216181115_issues.yml
index 6dbb1b910e1..f80ae26eea0 100644
--- a/config/metrics/counts_all/20210216181115_issues.yml
+++ b/config/metrics/counts_all/20210216181115_issues.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
instrumentation_class: CountUsersCreatingIssuesMetric
@@ -18,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181117_notes.yml b/config/metrics/counts_all/20210216181117_notes.yml
index 20aa29d6d6f..e8cc952b05c 100644
--- a/config/metrics/counts_all/20210216181117_notes.yml
+++ b/config/metrics/counts_all/20210216181117_notes.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181119_projects.yml b/config/metrics/counts_all/20210216181119_projects.yml
index 5384bacfec2..e8bce2b79bf 100644
--- a/config/metrics/counts_all/20210216181119_projects.yml
+++ b/config/metrics/counts_all/20210216181119_projects.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: projects
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181121_todos.yml b/config/metrics/counts_all/20210216181121_todos.yml
index 562e7be5666..e20fe6f7b84 100644
--- a/config/metrics/counts_all/20210216181121_todos.yml
+++ b/config/metrics/counts_all/20210216181121_todos.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181122_service_desk_enabled_projects.yml b/config/metrics/counts_all/20210216181122_service_desk_enabled_projects.yml
index 73c975ecd1e..d57a1b6a052 100644
--- a/config/metrics/counts_all/20210216181122_service_desk_enabled_projects.yml
+++ b/config/metrics/counts_all/20210216181122_service_desk_enabled_projects.yml
@@ -4,10 +4,10 @@ key_path: usage_activity_by_stage.plan.service_desk_enabled_projects
description: Count creator ids from projects with service desk enabled
product_section: dev
product_stage: plan
-product_group: group::plan
+product_group: group::product planning
product_category: service_desk
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181124_service_desk_issues.yml b/config/metrics/counts_all/20210216181124_service_desk_issues.yml
index 521d0f42fbe..476d2fab058 100644
--- a/config/metrics/counts_all/20210216181124_service_desk_issues.yml
+++ b/config/metrics/counts_all/20210216181124_service_desk_issues.yml
@@ -4,10 +4,10 @@ key_path: usage_activity_by_stage.plan.service_desk_issues
description: Count of service desk issues
product_section: dev
product_stage: plan
-product_group: group::plan
+product_group: group::product planning
product_category: service_desk
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181126_projects_jira_active.yml b/config/metrics/counts_all/20210216181126_projects_jira_active.yml
index de8f7e5e578..63b13a17b67 100644
--- a/config/metrics/counts_all/20210216181126_projects_jira_active.yml
+++ b/config/metrics/counts_all/20210216181126_projects_jira_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181128_projects_jira_dvcs_cloud_active.yml b/config/metrics/counts_all/20210216181128_projects_jira_dvcs_cloud_active.yml
index 6dca1863e3e..7e42a3e57a4 100644
--- a/config/metrics/counts_all/20210216181128_projects_jira_dvcs_cloud_active.yml
+++ b/config/metrics/counts_all/20210216181128_projects_jira_dvcs_cloud_active.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: usage_activity_by_stage.plan.projects_jira_dvcs_cloud_active
-description: Distinct count of creator_id from projects with an active Jira Cloud DVCS integration.
+description: Distinct count of creator_id from projects with an active Jira Cloud
+ DVCS integration.
product_section: dev
product_stage: ecosystem
product_group: group::integration
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181130_projects_jira_dvcs_server_active.yml b/config/metrics/counts_all/20210216181130_projects_jira_dvcs_server_active.yml
index 2f37969e8ad..55d90e282c6 100644
--- a/config/metrics/counts_all/20210216181130_projects_jira_dvcs_server_active.yml
+++ b/config/metrics/counts_all/20210216181130_projects_jira_dvcs_server_active.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: usage_activity_by_stage.plan.projects_jira_dvcs_server_active
-description: Distinct count of creator_id from projects with an active Jira Server DVCS integration.
+description: Distinct count of creator_id from projects with an active Jira Server
+ DVCS integration.
product_section: dev
product_stage: ecosystem
product_group: group::integration
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181134_epics.yml b/config/metrics/counts_all/20210216181134_epics.yml
index 339956d84df..4b6a1ed0291 100644
--- a/config/metrics/counts_all/20210216181134_epics.yml
+++ b/config/metrics/counts_all/20210216181134_epics.yml
@@ -4,13 +4,15 @@ key_path: usage_activity_by_stage.plan.epics
description: Count distinct author ids from epics
product_section: dev
product_stage: plan
-product_group: group::plan
+product_group: group::product planning
product_category: epics
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
- ee
tier:
- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181135_label_lists.yml b/config/metrics/counts_all/20210216181135_label_lists.yml
index f3f9d84993b..8bcabe8cd38 100644
--- a/config/metrics/counts_all/20210216181135_label_lists.yml
+++ b/config/metrics/counts_all/20210216181135_label_lists.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: boards
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181249_feature_flags.yml b/config/metrics/counts_all/20210216181249_feature_flags.yml
index 17435693673..17feacedd54 100644
--- a/config/metrics/counts_all/20210216181249_feature_flags.yml
+++ b/config/metrics/counts_all/20210216181249_feature_flags.yml
@@ -7,7 +7,7 @@ product_stage: release
product_group: group::release
product_category: feature_flags
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181252_boards.yml b/config/metrics/counts_all/20210216181252_boards.yml
index 91370f6192f..683fa274e63 100644
--- a/config/metrics/counts_all/20210216181252_boards.yml
+++ b/config/metrics/counts_all/20210216181252_boards.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: boards
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
instrumentation_class: CountBoardsMetric
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181254_projects.yml b/config/metrics/counts_all/20210216181254_projects.yml
index ce9659cccc4..00af8e92387 100644
--- a/config/metrics/counts_all/20210216181254_projects.yml
+++ b/config/metrics/counts_all/20210216181254_projects.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: projects
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181256_todos.yml b/config/metrics/counts_all/20210216181256_todos.yml
index ab13c2b8d11..72932b9ec84 100644
--- a/config/metrics/counts_all/20210216181256_todos.yml
+++ b/config/metrics/counts_all/20210216181256_todos.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::project management
product_category: issue_tracking
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181258_jira_imports_total_imported_count.yml b/config/metrics/counts_all/20210216181258_jira_imports_total_imported_count.yml
index 13b0f38d16a..a4abbad0b7d 100644
--- a/config/metrics/counts_all/20210216181258_jira_imports_total_imported_count.yml
+++ b/config/metrics/counts_all/20210216181258_jira_imports_total_imported_count.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: jira_importer
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181259_jira_imports_projects_count.yml b/config/metrics/counts_all/20210216181259_jira_imports_projects_count.yml
index 4d807c3d333..3722c7ccaa4 100644
--- a/config/metrics/counts_all/20210216181259_jira_imports_projects_count.yml
+++ b/config/metrics/counts_all/20210216181259_jira_imports_projects_count.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: jira_importer
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181301_jira_imports_total_imported_issues_count.yml b/config/metrics/counts_all/20210216181301_jira_imports_total_imported_issues_count.yml
index d20eaa11b41..0b68f3d5698 100644
--- a/config/metrics/counts_all/20210216181301_jira_imports_total_imported_issues_count.yml
+++ b/config/metrics/counts_all/20210216181301_jira_imports_total_imported_issues_count.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: jira_importer
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181908_deploy_keys.yml b/config/metrics/counts_all/20210216181908_deploy_keys.yml
index 5d144cdb855..40cf2ceb97a 100644
--- a/config/metrics/counts_all/20210216181908_deploy_keys.yml
+++ b/config/metrics/counts_all/20210216181908_deploy_keys.yml
@@ -7,7 +7,7 @@ product_stage: release
product_group: group::release
product_category: continuous_delivery
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181911_successful_deployments.yml b/config/metrics/counts_all/20210216181911_successful_deployments.yml
index d02c5ee2d8b..dcaf37a62f3 100644
--- a/config/metrics/counts_all/20210216181911_successful_deployments.yml
+++ b/config/metrics/counts_all/20210216181911_successful_deployments.yml
@@ -7,7 +7,7 @@ product_stage: release
product_group: group::release
product_category: continuous_delivery
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181912_failed_deployments.yml b/config/metrics/counts_all/20210216181912_failed_deployments.yml
index db7532c9e5b..0c3837e3f0b 100644
--- a/config/metrics/counts_all/20210216181912_failed_deployments.yml
+++ b/config/metrics/counts_all/20210216181912_failed_deployments.yml
@@ -7,7 +7,7 @@ product_stage: release
product_group: group::release
product_category: continuous_delivery
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181914_environments.yml b/config/metrics/counts_all/20210216181914_environments.yml
index 86958d713b6..23bb7bf3dda 100644
--- a/config/metrics/counts_all/20210216181914_environments.yml
+++ b/config/metrics/counts_all/20210216181914_environments.yml
@@ -7,7 +7,7 @@ product_stage: release
product_group: group::release
product_category: continuous_delivery
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181916_in_review_folder.yml b/config/metrics/counts_all/20210216181916_in_review_folder.yml
index 17cc4f8b730..145f0a3ab02 100644
--- a/config/metrics/counts_all/20210216181916_in_review_folder.yml
+++ b/config/metrics/counts_all/20210216181916_in_review_folder.yml
@@ -7,7 +7,7 @@ product_stage: release
product_group: group::release
product_category: continuous_delivery
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181918_releases.yml b/config/metrics/counts_all/20210216181918_releases.yml
index caf35bd5245..edd72afffff 100644
--- a/config/metrics/counts_all/20210216181918_releases.yml
+++ b/config/metrics/counts_all/20210216181918_releases.yml
@@ -7,7 +7,7 @@ product_stage: releases
product_group: group::release
product_category: release_orchestration
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181926_deployments.yml b/config/metrics/counts_all/20210216181926_deployments.yml
index 36d5b11c115..cabf887d72d 100644
--- a/config/metrics/counts_all/20210216181926_deployments.yml
+++ b/config/metrics/counts_all/20210216181926_deployments.yml
@@ -7,7 +7,7 @@ product_stage: release
product_group: group::release
product_category: continuous_delivery
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181928_failed_deployments.yml b/config/metrics/counts_all/20210216181928_failed_deployments.yml
index 36346541dd0..d3208764244 100644
--- a/config/metrics/counts_all/20210216181928_failed_deployments.yml
+++ b/config/metrics/counts_all/20210216181928_failed_deployments.yml
@@ -7,7 +7,7 @@ product_stage: release
product_group: group::release
product_category: continuous_delivery
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181930_releases.yml b/config/metrics/counts_all/20210216181930_releases.yml
index e14885bd330..7d3ba2eb218 100644
--- a/config/metrics/counts_all/20210216181930_releases.yml
+++ b/config/metrics/counts_all/20210216181930_releases.yml
@@ -7,7 +7,7 @@ product_stage: release
product_group: group::release
product_category: release_orchestration
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181932_successful_deployments.yml b/config/metrics/counts_all/20210216181932_successful_deployments.yml
index 23dee12d855..e85b46027b4 100644
--- a/config/metrics/counts_all/20210216181932_successful_deployments.yml
+++ b/config/metrics/counts_all/20210216181932_successful_deployments.yml
@@ -7,7 +7,7 @@ product_stage: release
product_group: group::release
product_category: continuous_delivery
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181946_pages_domains.yml b/config/metrics/counts_all/20210216181946_pages_domains.yml
index 4952ae14614..cba92282125 100644
--- a/config/metrics/counts_all/20210216181946_pages_domains.yml
+++ b/config/metrics/counts_all/20210216181946_pages_domains.yml
@@ -7,7 +7,7 @@ product_stage: release
product_group: group::release
product_category: pages
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181949_clusters_applications_runner.yml b/config/metrics/counts_all/20210216181949_clusters_applications_runner.yml
index 11251ac89c5..96f16043e65 100644
--- a/config/metrics/counts_all/20210216181949_clusters_applications_runner.yml
+++ b/config/metrics/counts_all/20210216181949_clusters_applications_runner.yml
@@ -7,7 +7,7 @@ product_stage: configure
product_group: group::configure
product_category: kubernetes_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -16,4 +16,5 @@ distribution:
tier:
- free
- premium
-- ultimate \ No newline at end of file
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216181954_user_unique_users_all_secure_scanners.yml b/config/metrics/counts_all/20210216181954_user_unique_users_all_secure_scanners.yml
deleted file mode 100644
index 0d4d7ab0524..00000000000
--- a/config/metrics/counts_all/20210216181954_user_unique_users_all_secure_scanners.yml
+++ /dev/null
@@ -1,17 +0,0 @@
----
-data_category: operational
-key_path: usage_activity_by_stage.secure.user_unique_users_all_secure_scanners
-description:
-product_section: sec
-product_stage:
-product_group: group::secure
-product_category:
-value_type: number
-status: data_available
-time_frame: all
-data_source:
-distribution:
-- ce
-tier:
-- free
-skip_validation: true
diff --git a/config/metrics/counts_all/20210216182002_remote_mirrors.yml b/config/metrics/counts_all/20210216182002_remote_mirrors.yml
index 8b03e3891f0..2730750ee5a 100644
--- a/config/metrics/counts_all/20210216182002_remote_mirrors.yml
+++ b/config/metrics/counts_all/20210216182002_remote_mirrors.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182004_commit_comment.yml b/config/metrics/counts_all/20210216182004_commit_comment.yml
index 116442201b0..4e2d402e9e1 100644
--- a/config/metrics/counts_all/20210216182004_commit_comment.yml
+++ b/config/metrics/counts_all/20210216182004_commit_comment.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182006_source_code_pushes.yml b/config/metrics/counts_all/20210216182006_source_code_pushes.yml
index 2b36e8e883e..aa5c55ec3e7 100644
--- a/config/metrics/counts_all/20210216182006_source_code_pushes.yml
+++ b/config/metrics/counts_all/20210216182006_source_code_pushes.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
instrumentation_class: RedisMetric
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182010_deploy_keys.yml b/config/metrics/counts_all/20210216182010_deploy_keys.yml
index 862b7a46b40..cedafd4a576 100644
--- a/config/metrics/counts_all/20210216182010_deploy_keys.yml
+++ b/config/metrics/counts_all/20210216182010_deploy_keys.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182012_keys.yml b/config/metrics/counts_all/20210216182012_keys.yml
index b1f53628e90..72d7f5b2b7b 100644
--- a/config/metrics/counts_all/20210216182012_keys.yml
+++ b/config/metrics/counts_all/20210216182012_keys.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182014_projects_with_disable_overriding_approvers_per_merge_request.yml b/config/metrics/counts_all/20210216182014_projects_with_disable_overriding_approvers_per_merge_request.yml
index 886de35954d..37709066148 100644
--- a/config/metrics/counts_all/20210216182014_projects_with_disable_overriding_approvers_per_merge_request.yml
+++ b/config/metrics/counts_all/20210216182014_projects_with_disable_overriding_approvers_per_merge_request.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: usage_activity_by_stage.create.projects_with_disable_overriding_approvers_per_merge_request
-description: Total count of projects that do not allow overriding approvers on discrete merge requests
+description: Total count of projects that do not allow overriding approvers on discrete
+ merge requests
product_section: dev
product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182015_projects_without_disable_overriding_approvers_per_merge_request.yml b/config/metrics/counts_all/20210216182015_projects_without_disable_overriding_approvers_per_merge_request.yml
index 96e21c1bdb3..6613f87aafd 100644
--- a/config/metrics/counts_all/20210216182015_projects_without_disable_overriding_approvers_per_merge_request.yml
+++ b/config/metrics/counts_all/20210216182015_projects_without_disable_overriding_approvers_per_merge_request.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: usage_activity_by_stage.create.projects_without_disable_overriding_approvers_per_merge_request
-description: Count of total projects that do not disable overriding approvers per discrete merge request
+description: Count of total projects that do not disable overriding approvers per
+ discrete merge request
product_section: dev
product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182017_remote_mirrors.yml b/config/metrics/counts_all/20210216182017_remote_mirrors.yml
index 60689e01bcc..9930c937aee 100644
--- a/config/metrics/counts_all/20210216182017_remote_mirrors.yml
+++ b/config/metrics/counts_all/20210216182017_remote_mirrors.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182112_sast_jobs.yml b/config/metrics/counts_all/20210216182112_sast_jobs.yml
index 10e0b0c0532..1012910675b 100644
--- a/config/metrics/counts_all/20210216182112_sast_jobs.yml
+++ b/config/metrics/counts_all/20210216182112_sast_jobs.yml
@@ -7,7 +7,7 @@ product_stage: secure
product_group: group::static analysis
product_category: static_application_security_testing
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182114_secret_detection_jobs.yml b/config/metrics/counts_all/20210216182114_secret_detection_jobs.yml
index b6e603499eb..8a3d1ef15f3 100644
--- a/config/metrics/counts_all/20210216182114_secret_detection_jobs.yml
+++ b/config/metrics/counts_all/20210216182114_secret_detection_jobs.yml
@@ -7,7 +7,7 @@ product_stage: secure
product_group: group::static analysis
product_category: secret_detection
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182116_user_sast_jobs.yml b/config/metrics/counts_all/20210216182116_user_sast_jobs.yml
index a79c1ebeb2f..b4822d0d89b 100644
--- a/config/metrics/counts_all/20210216182116_user_sast_jobs.yml
+++ b/config/metrics/counts_all/20210216182116_user_sast_jobs.yml
@@ -7,7 +7,7 @@ product_stage: secure
product_group: group::static analysis
product_category: static_application_security_testing
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182118_user_secret_detection_jobs.yml b/config/metrics/counts_all/20210216182118_user_secret_detection_jobs.yml
index 7d5f638bf73..6dde13f823b 100644
--- a/config/metrics/counts_all/20210216182118_user_secret_detection_jobs.yml
+++ b/config/metrics/counts_all/20210216182118_user_secret_detection_jobs.yml
@@ -7,7 +7,7 @@ product_stage: secure
product_group: group::static analysis
product_category: secret_detection
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182454_protected_branches_except_default.yml b/config/metrics/counts_all/20210216182454_protected_branches_except_default.yml
index a07ce8ed1bb..f1f1e877a83 100644
--- a/config/metrics/counts_all/20210216182454_protected_branches_except_default.yml
+++ b/config/metrics/counts_all/20210216182454_protected_branches_except_default.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::source code
product_category: source_code_management
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182547_projects_datadog_active.yml b/config/metrics/counts_all/20210216182547_projects_datadog_active.yml
index 02b47c9a2a6..a321b90faa5 100644
--- a/config/metrics/counts_all/20210216182547_projects_datadog_active.yml
+++ b/config/metrics/counts_all/20210216182547_projects_datadog_active.yml
@@ -1,13 +1,13 @@
---
data_category: optional
key_path: counts.projects_datadog_active
-description: 'Count of projects with active integrations for Datadog'
+description: Count of projects with active integrations for Datadog
product_section: dev
product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182549_groups_datadog_active.yml b/config/metrics/counts_all/20210216182549_groups_datadog_active.yml
index 4379dbfba7a..0647618b825 100644
--- a/config/metrics/counts_all/20210216182549_groups_datadog_active.yml
+++ b/config/metrics/counts_all/20210216182549_groups_datadog_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182551_templates_datadog_active.yml b/config/metrics/counts_all/20210216182551_templates_datadog_active.yml
index b6ad06d9801..d2df07b8d21 100644
--- a/config/metrics/counts_all/20210216182551_templates_datadog_active.yml
+++ b/config/metrics/counts_all/20210216182551_templates_datadog_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182553_instances_datadog_active.yml b/config/metrics/counts_all/20210216182553_instances_datadog_active.yml
index 772639560f4..0584c5c2c81 100644
--- a/config/metrics/counts_all/20210216182553_instances_datadog_active.yml
+++ b/config/metrics/counts_all/20210216182553_instances_datadog_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182555_projects_inheriting_datadog_active.yml b/config/metrics/counts_all/20210216182555_projects_inheriting_datadog_active.yml
index 2badb2dd83f..1ef23e06c10 100644
--- a/config/metrics/counts_all/20210216182555_projects_inheriting_datadog_active.yml
+++ b/config/metrics/counts_all/20210216182555_projects_inheriting_datadog_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182557_groups_inheriting_datadog_active.yml b/config/metrics/counts_all/20210216182557_groups_inheriting_datadog_active.yml
index 08dd3318dd4..aed458187a8 100644
--- a/config/metrics/counts_all/20210216182557_groups_inheriting_datadog_active.yml
+++ b/config/metrics/counts_all/20210216182557_groups_inheriting_datadog_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182614_projects_ewm_active.yml b/config/metrics/counts_all/20210216182614_projects_ewm_active.yml
index 3cdc44868d0..93d73cf233f 100644
--- a/config/metrics/counts_all/20210216182614_projects_ewm_active.yml
+++ b/config/metrics/counts_all/20210216182614_projects_ewm_active.yml
@@ -1,13 +1,13 @@
---
data_category: optional
key_path: counts.projects_ewm_active
-description: 'Count of projects with active integrations for EWM'
+description: Count of projects with active integrations for EWM
product_section: dev
product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182616_groups_ewm_active.yml b/config/metrics/counts_all/20210216182616_groups_ewm_active.yml
index 5e1336e59ff..441f6e05077 100644
--- a/config/metrics/counts_all/20210216182616_groups_ewm_active.yml
+++ b/config/metrics/counts_all/20210216182616_groups_ewm_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182618_templates_ewm_active.yml b/config/metrics/counts_all/20210216182618_templates_ewm_active.yml
index 8be6bdf0c59..1ace369980b 100644
--- a/config/metrics/counts_all/20210216182618_templates_ewm_active.yml
+++ b/config/metrics/counts_all/20210216182618_templates_ewm_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182620_instances_ewm_active.yml b/config/metrics/counts_all/20210216182620_instances_ewm_active.yml
index ccc502535c9..cb3821cbb24 100644
--- a/config/metrics/counts_all/20210216182620_instances_ewm_active.yml
+++ b/config/metrics/counts_all/20210216182620_instances_ewm_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182622_projects_inheriting_ewm_active.yml b/config/metrics/counts_all/20210216182622_projects_inheriting_ewm_active.yml
index 8670903142b..b5ac09a9313 100644
--- a/config/metrics/counts_all/20210216182622_projects_inheriting_ewm_active.yml
+++ b/config/metrics/counts_all/20210216182622_projects_inheriting_ewm_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182623_groups_inheriting_ewm_active.yml b/config/metrics/counts_all/20210216182623_groups_inheriting_ewm_active.yml
index 1e8c2575160..4cd950aeff5 100644
--- a/config/metrics/counts_all/20210216182623_groups_inheriting_ewm_active.yml
+++ b/config/metrics/counts_all/20210216182623_groups_inheriting_ewm_active.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182722_projects_mock_ci_active.yml b/config/metrics/counts_all/20210216182722_projects_mock_ci_active.yml
index 71a6b44ffa8..5c12fa79916 100644
--- a/config/metrics/counts_all/20210216182722_projects_mock_ci_active.yml
+++ b/config/metrics/counts_all/20210216182722_projects_mock_ci_active.yml
@@ -18,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182724_groups_mock_ci_active.yml b/config/metrics/counts_all/20210216182724_groups_mock_ci_active.yml
index bdfb6260be3..eafff875bfb 100644
--- a/config/metrics/counts_all/20210216182724_groups_mock_ci_active.yml
+++ b/config/metrics/counts_all/20210216182724_groups_mock_ci_active.yml
@@ -18,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182726_templates_mock_ci_active.yml b/config/metrics/counts_all/20210216182726_templates_mock_ci_active.yml
index a210d3205ad..b421b3d1843 100644
--- a/config/metrics/counts_all/20210216182726_templates_mock_ci_active.yml
+++ b/config/metrics/counts_all/20210216182726_templates_mock_ci_active.yml
@@ -18,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182728_instances_mock_ci_active.yml b/config/metrics/counts_all/20210216182728_instances_mock_ci_active.yml
index e0cf0fd30a1..eb7009db600 100644
--- a/config/metrics/counts_all/20210216182728_instances_mock_ci_active.yml
+++ b/config/metrics/counts_all/20210216182728_instances_mock_ci_active.yml
@@ -18,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182730_projects_inheriting_mock_ci_active.yml b/config/metrics/counts_all/20210216182730_projects_inheriting_mock_ci_active.yml
index f9e6b6ee4d4..d2f5d4fe1e3 100644
--- a/config/metrics/counts_all/20210216182730_projects_inheriting_mock_ci_active.yml
+++ b/config/metrics/counts_all/20210216182730_projects_inheriting_mock_ci_active.yml
@@ -18,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182732_groups_inheriting_mock_ci_active.yml b/config/metrics/counts_all/20210216182732_groups_inheriting_mock_ci_active.yml
index 3e53603ed9f..3727a16d08c 100644
--- a/config/metrics/counts_all/20210216182732_groups_inheriting_mock_ci_active.yml
+++ b/config/metrics/counts_all/20210216182732_groups_inheriting_mock_ci_active.yml
@@ -18,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182734_projects_mock_monitoring_active.yml b/config/metrics/counts_all/20210216182734_projects_mock_monitoring_active.yml
index 378114f9294..59ffe96bc36 100644
--- a/config/metrics/counts_all/20210216182734_projects_mock_monitoring_active.yml
+++ b/config/metrics/counts_all/20210216182734_projects_mock_monitoring_active.yml
@@ -18,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182736_groups_mock_monitoring_active.yml b/config/metrics/counts_all/20210216182736_groups_mock_monitoring_active.yml
index 231d643bde6..2ac5362c37b 100644
--- a/config/metrics/counts_all/20210216182736_groups_mock_monitoring_active.yml
+++ b/config/metrics/counts_all/20210216182736_groups_mock_monitoring_active.yml
@@ -18,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182738_templates_mock_monitoring_active.yml b/config/metrics/counts_all/20210216182738_templates_mock_monitoring_active.yml
index 3b7659c108e..961d787b203 100644
--- a/config/metrics/counts_all/20210216182738_templates_mock_monitoring_active.yml
+++ b/config/metrics/counts_all/20210216182738_templates_mock_monitoring_active.yml
@@ -18,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182739_instances_mock_monitoring_active.yml b/config/metrics/counts_all/20210216182739_instances_mock_monitoring_active.yml
index b82600ae33a..9f2ece8e9a4 100644
--- a/config/metrics/counts_all/20210216182739_instances_mock_monitoring_active.yml
+++ b/config/metrics/counts_all/20210216182739_instances_mock_monitoring_active.yml
@@ -18,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182741_projects_inheriting_mock_monitoring_active.yml b/config/metrics/counts_all/20210216182741_projects_inheriting_mock_monitoring_active.yml
index 71f7ff03adc..842d4047986 100644
--- a/config/metrics/counts_all/20210216182741_projects_inheriting_mock_monitoring_active.yml
+++ b/config/metrics/counts_all/20210216182741_projects_inheriting_mock_monitoring_active.yml
@@ -18,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182743_groups_inheriting_mock_monitoring_active.yml b/config/metrics/counts_all/20210216182743_groups_inheriting_mock_monitoring_active.yml
index dcbcf74bf5d..bd8f344bb36 100644
--- a/config/metrics/counts_all/20210216182743_groups_inheriting_mock_monitoring_active.yml
+++ b/config/metrics/counts_all/20210216182743_groups_inheriting_mock_monitoring_active.yml
@@ -18,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182855_package_events_i_package_composer_delete_package.yml b/config/metrics/counts_all/20210216182855_package_events_i_package_composer_delete_package.yml
index a7917d3ed3e..56909d1bb7b 100644
--- a/config/metrics/counts_all/20210216182855_package_events_i_package_composer_delete_package.yml
+++ b/config/metrics/counts_all/20210216182855_package_events_i_package_composer_delete_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182857_package_events_i_package_composer_pull_package.yml b/config/metrics/counts_all/20210216182857_package_events_i_package_composer_pull_package.yml
index 543a3a7c0bb..9dd401d73a9 100644
--- a/config/metrics/counts_all/20210216182857_package_events_i_package_composer_pull_package.yml
+++ b/config/metrics/counts_all/20210216182857_package_events_i_package_composer_pull_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182859_package_events_i_package_composer_push_package.yml b/config/metrics/counts_all/20210216182859_package_events_i_package_composer_push_package.yml
index ea346af7322..336d177a739 100644
--- a/config/metrics/counts_all/20210216182859_package_events_i_package_composer_push_package.yml
+++ b/config/metrics/counts_all/20210216182859_package_events_i_package_composer_push_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182901_package_events_i_package_conan_delete_package.yml b/config/metrics/counts_all/20210216182901_package_events_i_package_conan_delete_package.yml
index 07f4d151a2d..548b005e9be 100644
--- a/config/metrics/counts_all/20210216182901_package_events_i_package_conan_delete_package.yml
+++ b/config/metrics/counts_all/20210216182901_package_events_i_package_conan_delete_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182903_package_events_i_package_conan_pull_package.yml b/config/metrics/counts_all/20210216182903_package_events_i_package_conan_pull_package.yml
index e9fbb042995..65b5cd2a1a4 100644
--- a/config/metrics/counts_all/20210216182903_package_events_i_package_conan_pull_package.yml
+++ b/config/metrics/counts_all/20210216182903_package_events_i_package_conan_pull_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182905_package_events_i_package_conan_push_package.yml b/config/metrics/counts_all/20210216182905_package_events_i_package_conan_push_package.yml
index 668c7668e94..8a8cc252b1e 100644
--- a/config/metrics/counts_all/20210216182905_package_events_i_package_conan_push_package.yml
+++ b/config/metrics/counts_all/20210216182905_package_events_i_package_conan_push_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182907_package_events_i_package_container_delete_package.yml b/config/metrics/counts_all/20210216182907_package_events_i_package_container_delete_package.yml
index f33d1fc3299..e36411a81e5 100644
--- a/config/metrics/counts_all/20210216182907_package_events_i_package_container_delete_package.yml
+++ b/config/metrics/counts_all/20210216182907_package_events_i_package_container_delete_package.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182909_package_events_i_package_container_pull_package.yml b/config/metrics/counts_all/20210216182909_package_events_i_package_container_pull_package.yml
index e1aa7ddc683..c9c448b642e 100644
--- a/config/metrics/counts_all/20210216182909_package_events_i_package_container_pull_package.yml
+++ b/config/metrics/counts_all/20210216182909_package_events_i_package_container_pull_package.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182911_package_events_i_package_container_push_package.yml b/config/metrics/counts_all/20210216182911_package_events_i_package_container_push_package.yml
index 4d64f574912..9ca8e62f68a 100644
--- a/config/metrics/counts_all/20210216182911_package_events_i_package_container_push_package.yml
+++ b/config/metrics/counts_all/20210216182911_package_events_i_package_container_push_package.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182913_package_events_i_package_debian_delete_package.yml b/config/metrics/counts_all/20210216182913_package_events_i_package_debian_delete_package.yml
index e0256f563a8..e842155ca69 100644
--- a/config/metrics/counts_all/20210216182913_package_events_i_package_debian_delete_package.yml
+++ b/config/metrics/counts_all/20210216182913_package_events_i_package_debian_delete_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182915_package_events_i_package_debian_pull_package.yml b/config/metrics/counts_all/20210216182915_package_events_i_package_debian_pull_package.yml
index 61cebf44a73..be0e94f8beb 100644
--- a/config/metrics/counts_all/20210216182915_package_events_i_package_debian_pull_package.yml
+++ b/config/metrics/counts_all/20210216182915_package_events_i_package_debian_pull_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182917_package_events_i_package_debian_push_package.yml b/config/metrics/counts_all/20210216182917_package_events_i_package_debian_push_package.yml
index 2fb6e56c49a..4fe173115ca 100644
--- a/config/metrics/counts_all/20210216182917_package_events_i_package_debian_push_package.yml
+++ b/config/metrics/counts_all/20210216182917_package_events_i_package_debian_push_package.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182919_package_events_i_package_delete_package.yml b/config/metrics/counts_all/20210216182919_package_events_i_package_delete_package.yml
index 4ab016f854d..988dc7118cb 100644
--- a/config/metrics/counts_all/20210216182919_package_events_i_package_delete_package.yml
+++ b/config/metrics/counts_all/20210216182919_package_events_i_package_delete_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182921_package_events_i_package_delete_package_by_deploy_token.yml b/config/metrics/counts_all/20210216182921_package_events_i_package_delete_package_by_deploy_token.yml
index 45490ab93d6..725df820fde 100644
--- a/config/metrics/counts_all/20210216182921_package_events_i_package_delete_package_by_deploy_token.yml
+++ b/config/metrics/counts_all/20210216182921_package_events_i_package_delete_package_by_deploy_token.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182923_package_events_i_package_delete_package_by_guest.yml b/config/metrics/counts_all/20210216182923_package_events_i_package_delete_package_by_guest.yml
index 4c1a0729633..ea88cab3192 100644
--- a/config/metrics/counts_all/20210216182923_package_events_i_package_delete_package_by_guest.yml
+++ b/config/metrics/counts_all/20210216182923_package_events_i_package_delete_package_by_guest.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182925_package_events_i_package_delete_package_by_user.yml b/config/metrics/counts_all/20210216182925_package_events_i_package_delete_package_by_user.yml
index e46db03bfaa..a87126920ce 100644
--- a/config/metrics/counts_all/20210216182925_package_events_i_package_delete_package_by_user.yml
+++ b/config/metrics/counts_all/20210216182925_package_events_i_package_delete_package_by_user.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182927_package_events_i_package_generic_delete_package.yml b/config/metrics/counts_all/20210216182927_package_events_i_package_generic_delete_package.yml
index c1ee7742636..c8b2f9d61ef 100644
--- a/config/metrics/counts_all/20210216182927_package_events_i_package_generic_delete_package.yml
+++ b/config/metrics/counts_all/20210216182927_package_events_i_package_generic_delete_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182929_package_events_i_package_generic_pull_package.yml b/config/metrics/counts_all/20210216182929_package_events_i_package_generic_pull_package.yml
index 1a31301c8a5..af84d46955a 100644
--- a/config/metrics/counts_all/20210216182929_package_events_i_package_generic_pull_package.yml
+++ b/config/metrics/counts_all/20210216182929_package_events_i_package_generic_pull_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182931_package_events_i_package_generic_push_package.yml b/config/metrics/counts_all/20210216182931_package_events_i_package_generic_push_package.yml
index ab3c69f7eed..55d368c2f6b 100644
--- a/config/metrics/counts_all/20210216182931_package_events_i_package_generic_push_package.yml
+++ b/config/metrics/counts_all/20210216182931_package_events_i_package_generic_push_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182933_package_events_i_package_golang_delete_package.yml b/config/metrics/counts_all/20210216182933_package_events_i_package_golang_delete_package.yml
index 2af3db1ed2c..14d8fc53a7e 100644
--- a/config/metrics/counts_all/20210216182933_package_events_i_package_golang_delete_package.yml
+++ b/config/metrics/counts_all/20210216182933_package_events_i_package_golang_delete_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182934_package_events_i_package_golang_pull_package.yml b/config/metrics/counts_all/20210216182934_package_events_i_package_golang_pull_package.yml
index ffae5c6efa4..65e38c0eb8e 100644
--- a/config/metrics/counts_all/20210216182934_package_events_i_package_golang_pull_package.yml
+++ b/config/metrics/counts_all/20210216182934_package_events_i_package_golang_pull_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182936_package_events_i_package_golang_push_package.yml b/config/metrics/counts_all/20210216182936_package_events_i_package_golang_push_package.yml
index babfe6c3507..3b65801378b 100644
--- a/config/metrics/counts_all/20210216182936_package_events_i_package_golang_push_package.yml
+++ b/config/metrics/counts_all/20210216182936_package_events_i_package_golang_push_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182938_package_events_i_package_maven_delete_package.yml b/config/metrics/counts_all/20210216182938_package_events_i_package_maven_delete_package.yml
index 176996e3447..7505efb4e47 100644
--- a/config/metrics/counts_all/20210216182938_package_events_i_package_maven_delete_package.yml
+++ b/config/metrics/counts_all/20210216182938_package_events_i_package_maven_delete_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182940_package_events_i_package_maven_pull_package.yml b/config/metrics/counts_all/20210216182940_package_events_i_package_maven_pull_package.yml
index e589314f06f..dc5211f9524 100644
--- a/config/metrics/counts_all/20210216182940_package_events_i_package_maven_pull_package.yml
+++ b/config/metrics/counts_all/20210216182940_package_events_i_package_maven_pull_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182942_package_events_i_package_maven_push_package.yml b/config/metrics/counts_all/20210216182942_package_events_i_package_maven_push_package.yml
index 4610a24c51f..0facf7697a8 100644
--- a/config/metrics/counts_all/20210216182942_package_events_i_package_maven_push_package.yml
+++ b/config/metrics/counts_all/20210216182942_package_events_i_package_maven_push_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182944_package_events_i_package_npm_delete_package.yml b/config/metrics/counts_all/20210216182944_package_events_i_package_npm_delete_package.yml
index e540e68355a..dade0515709 100644
--- a/config/metrics/counts_all/20210216182944_package_events_i_package_npm_delete_package.yml
+++ b/config/metrics/counts_all/20210216182944_package_events_i_package_npm_delete_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182946_package_events_i_package_npm_pull_package.yml b/config/metrics/counts_all/20210216182946_package_events_i_package_npm_pull_package.yml
index d2af5aa56c8..607db7969cf 100644
--- a/config/metrics/counts_all/20210216182946_package_events_i_package_npm_pull_package.yml
+++ b/config/metrics/counts_all/20210216182946_package_events_i_package_npm_pull_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182948_package_events_i_package_npm_push_package.yml b/config/metrics/counts_all/20210216182948_package_events_i_package_npm_push_package.yml
index 653fba58565..2aa9a9ac676 100644
--- a/config/metrics/counts_all/20210216182948_package_events_i_package_npm_push_package.yml
+++ b/config/metrics/counts_all/20210216182948_package_events_i_package_npm_push_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182950_package_events_i_package_nuget_delete_package.yml b/config/metrics/counts_all/20210216182950_package_events_i_package_nuget_delete_package.yml
index 82a5509cd03..78a5f920c0a 100644
--- a/config/metrics/counts_all/20210216182950_package_events_i_package_nuget_delete_package.yml
+++ b/config/metrics/counts_all/20210216182950_package_events_i_package_nuget_delete_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182952_package_events_i_package_nuget_pull_package.yml b/config/metrics/counts_all/20210216182952_package_events_i_package_nuget_pull_package.yml
index 5327b10ecf5..29471d9fc68 100644
--- a/config/metrics/counts_all/20210216182952_package_events_i_package_nuget_pull_package.yml
+++ b/config/metrics/counts_all/20210216182952_package_events_i_package_nuget_pull_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182954_package_events_i_package_nuget_push_package.yml b/config/metrics/counts_all/20210216182954_package_events_i_package_nuget_push_package.yml
index e8b0a0e7fb5..2074fa19d5a 100644
--- a/config/metrics/counts_all/20210216182954_package_events_i_package_nuget_push_package.yml
+++ b/config/metrics/counts_all/20210216182954_package_events_i_package_nuget_push_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182956_package_events_i_package_pull_package.yml b/config/metrics/counts_all/20210216182956_package_events_i_package_pull_package.yml
index f3484ae5b41..0d09c626f2b 100644
--- a/config/metrics/counts_all/20210216182956_package_events_i_package_pull_package.yml
+++ b/config/metrics/counts_all/20210216182956_package_events_i_package_pull_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216182958_package_events_i_package_pull_package_by_deploy_token.yml b/config/metrics/counts_all/20210216182958_package_events_i_package_pull_package_by_deploy_token.yml
index 183abf834dd..eeb5c150f0f 100644
--- a/config/metrics/counts_all/20210216182958_package_events_i_package_pull_package_by_deploy_token.yml
+++ b/config/metrics/counts_all/20210216182958_package_events_i_package_pull_package_by_deploy_token.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: counts.package_events_i_package_pull_package_by_deploy_token
-description: A count of packages that have been downloaded from the package registry using a Deploy Token
+description: A count of packages that have been downloaded from the package registry
+ using a Deploy Token
product_section: ops
product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216183000_package_events_i_package_pull_package_by_guest.yml b/config/metrics/counts_all/20210216183000_package_events_i_package_pull_package_by_guest.yml
index bad5254aac4..63ec075c163 100644
--- a/config/metrics/counts_all/20210216183000_package_events_i_package_pull_package_by_guest.yml
+++ b/config/metrics/counts_all/20210216183000_package_events_i_package_pull_package_by_guest.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: counts.package_events_i_package_pull_package_by_guest
-description: A count of packages that have been downloaded from the package registry by a guest
+description: A count of packages that have been downloaded from the package registry
+ by a guest
product_section: ops
product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216183002_package_events_i_package_pull_package_by_user.yml b/config/metrics/counts_all/20210216183002_package_events_i_package_pull_package_by_user.yml
index f5e450cae7a..ce0c3c455ff 100644
--- a/config/metrics/counts_all/20210216183002_package_events_i_package_pull_package_by_user.yml
+++ b/config/metrics/counts_all/20210216183002_package_events_i_package_pull_package_by_user.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: counts.package_events_i_package_pull_package_by_user
-description: A count of packages that have been downloaded from the package registry by a user
+description: A count of packages that have been downloaded from the package registry
+ by a user
product_section: ops
product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216183004_package_events_i_package_push_package.yml b/config/metrics/counts_all/20210216183004_package_events_i_package_push_package.yml
index bbcd3e82234..845251f1aca 100644
--- a/config/metrics/counts_all/20210216183004_package_events_i_package_push_package.yml
+++ b/config/metrics/counts_all/20210216183004_package_events_i_package_push_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216183005_package_events_i_package_push_package_by_deploy_token.yml b/config/metrics/counts_all/20210216183005_package_events_i_package_push_package_by_deploy_token.yml
index 3a37af76f73..4484250f136 100644
--- a/config/metrics/counts_all/20210216183005_package_events_i_package_push_package_by_deploy_token.yml
+++ b/config/metrics/counts_all/20210216183005_package_events_i_package_push_package_by_deploy_token.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: counts.package_events_i_package_push_package_by_deploy_token
-description: A count of packages that have been published to the package registry using a deploy token
+description: A count of packages that have been published to the package registry
+ using a deploy token
product_section: ops
product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216183007_package_events_i_package_push_package_by_guest.yml b/config/metrics/counts_all/20210216183007_package_events_i_package_push_package_by_guest.yml
index 2f241519d3d..a657e2f228e 100644
--- a/config/metrics/counts_all/20210216183007_package_events_i_package_push_package_by_guest.yml
+++ b/config/metrics/counts_all/20210216183007_package_events_i_package_push_package_by_guest.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: counts.package_events_i_package_push_package_by_guest
-description: A count of packages that have been published to the package registry by a Guest
+description: A count of packages that have been published to the package registry
+ by a Guest
product_section: ops
product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +18,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216183009_package_events_i_package_push_package_by_user.yml b/config/metrics/counts_all/20210216183009_package_events_i_package_push_package_by_user.yml
index 25b3932ad67..a3e0a65453d 100644
--- a/config/metrics/counts_all/20210216183009_package_events_i_package_push_package_by_user.yml
+++ b/config/metrics/counts_all/20210216183009_package_events_i_package_push_package_by_user.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: counts.package_events_i_package_push_package_by_user
-description: A count of packages that have been published to the package registry by a user
+description: A count of packages that have been published to the package registry
+ by a user
product_section: ops
product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216183011_package_events_i_package_pypi_delete_package.yml b/config/metrics/counts_all/20210216183011_package_events_i_package_pypi_delete_package.yml
index 2a90a151a53..2c5b6efe160 100644
--- a/config/metrics/counts_all/20210216183011_package_events_i_package_pypi_delete_package.yml
+++ b/config/metrics/counts_all/20210216183011_package_events_i_package_pypi_delete_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216183013_package_events_i_package_pypi_pull_package.yml b/config/metrics/counts_all/20210216183013_package_events_i_package_pypi_pull_package.yml
index 0efeac2f9d1..b659a207b00 100644
--- a/config/metrics/counts_all/20210216183013_package_events_i_package_pypi_pull_package.yml
+++ b/config/metrics/counts_all/20210216183013_package_events_i_package_pypi_pull_package.yml
@@ -1,13 +1,14 @@
---
data_category: optional
key_path: counts.package_events_i_package_pypi_pull_package
-description: A count of Python packages that have been downloaded from the package registry
+description: A count of Python packages that have been downloaded from the package
+ registry
product_section: ops
product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216183015_package_events_i_package_pypi_push_package.yml b/config/metrics/counts_all/20210216183015_package_events_i_package_pypi_push_package.yml
index 75c91704892..33b0819be0b 100644
--- a/config/metrics/counts_all/20210216183015_package_events_i_package_pypi_push_package.yml
+++ b/config/metrics/counts_all/20210216183015_package_events_i_package_pypi_push_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: redis
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216183017_package_events_i_package_tag_delete_package.yml b/config/metrics/counts_all/20210216183017_package_events_i_package_tag_delete_package.yml
index 06217938d8e..580f06259a1 100644
--- a/config/metrics/counts_all/20210216183017_package_events_i_package_tag_delete_package.yml
+++ b/config/metrics/counts_all/20210216183017_package_events_i_package_tag_delete_package.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216183019_package_events_i_package_tag_pull_package.yml b/config/metrics/counts_all/20210216183019_package_events_i_package_tag_pull_package.yml
index b96c1866a17..cb399d23ed1 100644
--- a/config/metrics/counts_all/20210216183019_package_events_i_package_tag_pull_package.yml
+++ b/config/metrics/counts_all/20210216183019_package_events_i_package_tag_pull_package.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216183021_package_events_i_package_tag_push_package.yml b/config/metrics/counts_all/20210216183021_package_events_i_package_tag_push_package.yml
index 264a9773f7b..aa32883e6a5 100644
--- a/config/metrics/counts_all/20210216183021_package_events_i_package_tag_push_package.yml
+++ b/config/metrics/counts_all/20210216183021_package_events_i_package_tag_push_package.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216183023_wiki_pages_view.yml b/config/metrics/counts_all/20210216183023_wiki_pages_view.yml
index 75403722e5c..c4cc4bfcf9c 100644
--- a/config/metrics/counts_all/20210216183023_wiki_pages_view.yml
+++ b/config/metrics/counts_all/20210216183023_wiki_pages_view.yml
@@ -1,18 +1,23 @@
---
data_category: optional
key_path: counts.wiki_pages_view
-description: ''
-product_section: ''
-product_stage: ''
-product_group: ''
-product_category: ''
+description: Total number of wiki page views
+product_section: dev
+product_stage: create
+product_group: group::editor
+product_category: wiki
value_type: number
-status: data_available
+status: active
+milestone: "13.3"
+introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38784"
time_frame: all
-data_source: database
+data_source: redis
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216183400_omniauth_providers.yml b/config/metrics/counts_all/20210216183400_omniauth_providers.yml
index 1f738f7ea73..3598db2ea5a 100644
--- a/config/metrics/counts_all/20210216183400_omniauth_providers.yml
+++ b/config/metrics/counts_all/20210216183400_omniauth_providers.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::access
product_category: authentication_and_authorization
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: database
distribution:
@@ -16,3 +16,4 @@ tier:
- free
- premium
- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/counts_all/20210216183402_two-factor.yml b/config/metrics/counts_all/20210216183402_two-factor.yml
deleted file mode 100644
index 623c67195ce..00000000000
--- a/config/metrics/counts_all/20210216183402_two-factor.yml
+++ /dev/null
@@ -1,18 +0,0 @@
----
-data_category: optional
-key_path: usage_activity_by_stage.manage.user_auth_by_provider.two-factor
-description: Number of unique user logins using two factor authentication
-product_section: dev
-product_stage: manage
-product_group: group::access
-product_category: authentication_and_authorization
-value_type: number
-status: data_available
-time_frame: all
-data_source: database
-distribution:
-- ce
-tier:
-- free
-- premium
-- ultimate
diff --git a/config/metrics/counts_all/20210216183404_two-factor-via-u2f-device.yml b/config/metrics/counts_all/20210216183404_two-factor-via-u2f-device.yml
deleted file mode 100644
index 5bbe08b623c..00000000000
--- a/config/metrics/counts_all/20210216183404_two-factor-via-u2f-device.yml
+++ /dev/null
@@ -1,18 +0,0 @@
----
-data_category: optional
-key_path: usage_activity_by_stage.manage.user_auth_by_provider.two-factor-via-u2f-device
-description: Number of unique user logins using two factor via a U2F device
-product_section: dev
-product_stage: manage
-product_group: group::access
-product_category: authentication_and_authorization
-value_type: number
-status: data_available
-time_frame: all
-data_source: database
-distribution:
-- ce
-tier:
-- free
-- premium
-- ultimate
diff --git a/config/metrics/counts_all/20210216183406_two-factor-via-webauthn-device.yml b/config/metrics/counts_all/20210216183406_two-factor-via-webauthn-device.yml
deleted file mode 100644
index adc75690057..00000000000
--- a/config/metrics/counts_all/20210216183406_two-factor-via-webauthn-device.yml
+++ /dev/null
@@ -1,18 +0,0 @@
----
-data_category: optional
-key_path: usage_activity_by_stage.manage.user_auth_by_provider.two-factor-via-webauthn-device
-description: Number of unique user logins using two factor via a WebAuthn device
-product_section: dev
-product_stage: manage
-product_group: group::access
-product_category: authentication_and_authorization
-value_type: number
-status: data_available
-time_frame: all
-data_source: database
-distribution:
-- ce
-tier:
-- free
-- premium
-- ultimate
diff --git a/config/metrics/counts_all/20210216183408_standard.yml b/config/metrics/counts_all/20210216183408_standard.yml
deleted file mode 100644
index b43bd25031b..00000000000
--- a/config/metrics/counts_all/20210216183408_standard.yml
+++ /dev/null
@@ -1,18 +0,0 @@
----
-data_category: optional
-key_path: usage_activity_by_stage.manage.user_auth_by_provider.standard
-description: Number of unique user logins using password authentication
-product_section: dev
-product_stage: manage
-product_group: group::access
-product_category: authentication_and_authorization
-value_type: number
-status: data_available
-time_frame: all
-data_source: database
-distribution:
-- ce
-tier:
-- free
-- premium
-- ultimate
diff --git a/config/metrics/counts_all/20210216183410_google_oauth2.yml b/config/metrics/counts_all/20210216183410_google_oauth2.yml
deleted file mode 100644
index 205b8dadbb0..00000000000
--- a/config/metrics/counts_all/20210216183410_google_oauth2.yml
+++ /dev/null
@@ -1,18 +0,0 @@
----
-data_category: optional
-key_path: usage_activity_by_stage.manage.user_auth_by_provider.google_oauth2
-description: Number of unique user logins using Google OAuth authentication
-product_section: dev
-product_stage: manage
-product_group: group::access
-product_category: authentication_and_authorization
-value_type: number
-status: data_available
-time_frame: all
-data_source: database
-distribution:
-- ce
-tier:
-- free
-- premium
-- ultimate
diff --git a/config/metrics/counts_all/20210303153000_package_events_i_package_rubygems_delete_package.yml b/config/metrics/counts_all/20210303153000_package_events_i_package_rubygems_delete_package.yml
index de7af7b7e59..1ddfdd79f5c 100644
--- a/config/metrics/counts_all/20210303153000_package_events_i_package_rubygems_delete_package.yml
+++ b/config/metrics/counts_all/20210303153000_package_events_i_package_rubygems_delete_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package_registry
value_type: number
-status: data_available
+status: active
milestone: '13.10'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53480
time_frame: all
diff --git a/config/metrics/counts_all/20210303153002_package_events_i_package_rubygems_pull_package.yml b/config/metrics/counts_all/20210303153002_package_events_i_package_rubygems_pull_package.yml
index c71c378c917..7fd10456636 100644
--- a/config/metrics/counts_all/20210303153002_package_events_i_package_rubygems_pull_package.yml
+++ b/config/metrics/counts_all/20210303153002_package_events_i_package_rubygems_pull_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package_registry
value_type: number
-status: data_available
+status: active
milestone: '13.10'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53480
time_frame: all
diff --git a/config/metrics/counts_all/20210303153004_package_events_i_package_rubygems_push_package.yml b/config/metrics/counts_all/20210303153004_package_events_i_package_rubygems_push_package.yml
index 025e47c0d04..0ba6d527e3a 100644
--- a/config/metrics/counts_all/20210303153004_package_events_i_package_rubygems_push_package.yml
+++ b/config/metrics/counts_all/20210303153004_package_events_i_package_rubygems_push_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package_registry
value_type: number
-status: data_available
+status: active
time_frame: all
milestone: '13.10'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53480
@@ -19,4 +19,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
+
diff --git a/config/metrics/counts_all/20210309165717_projects_with_enabled_alert_integrations_histogram.yml b/config/metrics/counts_all/20210309165717_projects_with_enabled_alert_integrations_histogram.yml
index ad2f6bce59e..91235499c14 100644
--- a/config/metrics/counts_all/20210309165717_projects_with_enabled_alert_integrations_histogram.yml
+++ b/config/metrics/counts_all/20210309165717_projects_with_enabled_alert_integrations_histogram.yml
@@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: object
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55782
time_frame: all
diff --git a/config/metrics/counts_all/20210410012200_package_events_i_package_terraform_module_delete_package.yml b/config/metrics/counts_all/20210410012200_package_events_i_package_terraform_module_delete_package.yml
index 3fb804b9a92..cca5b684905 100644
--- a/config/metrics/counts_all/20210410012200_package_events_i_package_terraform_module_delete_package.yml
+++ b/config/metrics/counts_all/20210410012200_package_events_i_package_terraform_module_delete_package.yml
@@ -7,7 +7,7 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: data_available
+status: active
milestone: '13.11'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55018
time_frame: all
diff --git a/config/metrics/counts_all/20210410012202_package_events_i_package_terraform_module_pull_package.yml b/config/metrics/counts_all/20210410012202_package_events_i_package_terraform_module_pull_package.yml
index bbd5c978794..860bfbe6884 100644
--- a/config/metrics/counts_all/20210410012202_package_events_i_package_terraform_module_pull_package.yml
+++ b/config/metrics/counts_all/20210410012202_package_events_i_package_terraform_module_pull_package.yml
@@ -7,7 +7,7 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: data_available
+status: active
milestone: '13.11'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55018
time_frame: all
diff --git a/config/metrics/counts_all/20210410012204_package_events_i_package_terraform_module_push_package.yml b/config/metrics/counts_all/20210410012204_package_events_i_package_terraform_module_push_package.yml
index fd2f969251f..89fcae57044 100644
--- a/config/metrics/counts_all/20210410012204_package_events_i_package_terraform_module_push_package.yml
+++ b/config/metrics/counts_all/20210410012204_package_events_i_package_terraform_module_push_package.yml
@@ -7,7 +7,7 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: data_available
+status: active
milestone: '13.11'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55018
time_frame: all
diff --git a/config/metrics/counts_all/20210423005644_i_analytics_dev_ops_adoption.yml b/config/metrics/counts_all/20210423005644_i_analytics_dev_ops_adoption.yml
index 45eebbcca09..b769b5d47f1 100644
--- a/config/metrics/counts_all/20210423005644_i_analytics_dev_ops_adoption.yml
+++ b/config/metrics/counts_all/20210423005644_i_analytics_dev_ops_adoption.yml
@@ -1,22 +1,21 @@
---
data_category: optional
key_path: analytics_unique_visits.i_analytics_dev_ops_adoption
-name: "<please fill metric name, suggested format is: {subject}_{verb}{ing|ed}_{object} eg: users_creating_epics or merge_requests_viewed_in_single_file_mode>"
-description:
-product_section:
-product_stage:
-product_group:
+description: Unique users viewing analytics devops adoption
+product_section: dev
+product_stage: manage
+product_group: group::optimize
product_category:
value_type: number
-status: data_available
+status: active
milestone: "13.11"
-introduced_by_url:
time_frame: all
-data_source:
+data_source: redis_hll
distribution:
- ce
-# tier:
-# - free
-# - premium
-# - ultimate
-skip_validation: true
+- ee
+tier:
+- free
+- premium
+- ultimate
+
diff --git a/config/metrics/counts_all/20210427212450_geo_secondary_web_oauth_users.yml b/config/metrics/counts_all/20210427212450_geo_secondary_web_oauth_users.yml
deleted file mode 100644
index f8577a6d0cb..00000000000
--- a/config/metrics/counts_all/20210427212450_geo_secondary_web_oauth_users.yml
+++ /dev/null
@@ -1,23 +0,0 @@
----
-data_category: optional
-key_path: usage_activity_by_stage.enablement.geo_secondary_web_oauth_users
-name: ""
-description:
-product_section:
-product_stage:
-product_group:
-product_category:
-value_type: number
-status: data_available
-milestone: "13.12"
-introduced_by_url:
-time_frame: all
-data_source:
-distribution:
-- ce
-- ee
-tier:
-- free
-- premium
-- ultimate
-skip_validation: true
diff --git a/config/metrics/counts_all/20210428142406_users_viewing_analytics_group_devops_adoption.yml b/config/metrics/counts_all/20210428142406_users_viewing_analytics_group_devops_adoption.yml
index f342e7ef82b..b8ae877b0be 100644
--- a/config/metrics/counts_all/20210428142406_users_viewing_analytics_group_devops_adoption.yml
+++ b/config/metrics/counts_all/20210428142406_users_viewing_analytics_group_devops_adoption.yml
@@ -1,18 +1,17 @@
---
data_category: optional
key_path: analytics_unique_visits.users_viewing_analytics_group_devops_adoption
-name: "<please fill metric name, suggested format is: {subject}_{verb}{ing|ed}_{object} eg: users_creating_epics or merge_requests_viewed_in_single_file_mode>"
-description:
-product_section:
-product_stage:
-product_group:
+name: unique_users_viewing_analytics_group_devops_adoption
+description: Unique users viewing analytics group devops adoption
+product_section: dev
+product_stage: manage
+product_group: group::optimize
product_category:
value_type: number
-status: data_available
+status: active
milestone: "13.12"
-introduced_by_url:
time_frame: all
-data_source:
+data_source: redis_hll
distribution:
- ce
- ee
@@ -20,4 +19,3 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
diff --git a/config/metrics/counts_all/20210502045402_ci_runners_instance_type_active.yml b/config/metrics/counts_all/20210502045402_ci_runners_instance_type_active.yml
index 69fffdf6283..b23d63a3ff8 100644
--- a/config/metrics/counts_all/20210502045402_ci_runners_instance_type_active.yml
+++ b/config/metrics/counts_all/20210502045402_ci_runners_instance_type_active.yml
@@ -8,7 +8,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58197
time_frame: all
diff --git a/config/metrics/counts_all/20210502050341_ci_runners_group_type_active.yml b/config/metrics/counts_all/20210502050341_ci_runners_group_type_active.yml
index 7edc7086c22..d09fd9e7578 100644
--- a/config/metrics/counts_all/20210502050341_ci_runners_group_type_active.yml
+++ b/config/metrics/counts_all/20210502050341_ci_runners_group_type_active.yml
@@ -8,7 +8,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58197
time_frame: all
diff --git a/config/metrics/counts_all/20210502050834_ci_runners_project_type_active.yml b/config/metrics/counts_all/20210502050834_ci_runners_project_type_active.yml
index 66f0c6ad976..11b5626dc1e 100644
--- a/config/metrics/counts_all/20210502050834_ci_runners_project_type_active.yml
+++ b/config/metrics/counts_all/20210502050834_ci_runners_project_type_active.yml
@@ -8,7 +8,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58197
time_frame: all
diff --git a/config/metrics/counts_all/20210502050942_ci_runners_online.yml b/config/metrics/counts_all/20210502050942_ci_runners_online.yml
index 7a2752ac152..d24d7f0125b 100644
--- a/config/metrics/counts_all/20210502050942_ci_runners_online.yml
+++ b/config/metrics/counts_all/20210502050942_ci_runners_online.yml
@@ -8,7 +8,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58197
time_frame: all
diff --git a/config/metrics/counts_all/20210502051651_ci_runners_instance_type_active_online.yml b/config/metrics/counts_all/20210502051651_ci_runners_instance_type_active_online.yml
index e32f288e8c9..621590185a9 100644
--- a/config/metrics/counts_all/20210502051651_ci_runners_instance_type_active_online.yml
+++ b/config/metrics/counts_all/20210502051651_ci_runners_instance_type_active_online.yml
@@ -8,7 +8,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58197
time_frame: all
diff --git a/config/metrics/counts_all/20210502051922_ci_runners_group_type_active_online.yml b/config/metrics/counts_all/20210502051922_ci_runners_group_type_active_online.yml
index 10e1eeb6ceb..82c639c72c6 100644
--- a/config/metrics/counts_all/20210502051922_ci_runners_group_type_active_online.yml
+++ b/config/metrics/counts_all/20210502051922_ci_runners_group_type_active_online.yml
@@ -8,7 +8,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58197
time_frame: all
diff --git a/config/metrics/counts_all/20210502052036_ci_runners_project_type_active_online.yml b/config/metrics/counts_all/20210502052036_ci_runners_project_type_active_online.yml
index f3628f18f60..f124d8d4ae5 100644
--- a/config/metrics/counts_all/20210502052036_ci_runners_project_type_active_online.yml
+++ b/config/metrics/counts_all/20210502052036_ci_runners_project_type_active_online.yml
@@ -8,7 +8,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58197
time_frame: all
diff --git a/config/metrics/counts_all/20210510201537_in_product_marketing_email_create_0_sent.yml b/config/metrics/counts_all/20210510201537_in_product_marketing_email_create_0_sent.yml
index 2d5b7e3b7a0..1f505694535 100644
--- a/config/metrics/counts_all/20210510201537_in_product_marketing_email_create_0_sent.yml
+++ b/config/metrics/counts_all/20210510201537_in_product_marketing_email_create_0_sent.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510201919_in_product_marketing_email_create_0_cta_clicked.yml b/config/metrics/counts_all/20210510201919_in_product_marketing_email_create_0_cta_clicked.yml
index 877f7119f3f..fb2bd8f59e0 100644
--- a/config/metrics/counts_all/20210510201919_in_product_marketing_email_create_0_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510201919_in_product_marketing_email_create_0_cta_clicked.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510202148_in_product_marketing_email_create_1_sent.yml b/config/metrics/counts_all/20210510202148_in_product_marketing_email_create_1_sent.yml
index 5d34d5b5803..13587d77e9a 100644
--- a/config/metrics/counts_all/20210510202148_in_product_marketing_email_create_1_sent.yml
+++ b/config/metrics/counts_all/20210510202148_in_product_marketing_email_create_1_sent.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510202356_in_product_marketing_email_create_1_cta_clicked.yml b/config/metrics/counts_all/20210510202356_in_product_marketing_email_create_1_cta_clicked.yml
index d57303b1241..e5635ba3d92 100644
--- a/config/metrics/counts_all/20210510202356_in_product_marketing_email_create_1_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510202356_in_product_marketing_email_create_1_cta_clicked.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510202604_in_product_marketing_email_create_2_sent.yml b/config/metrics/counts_all/20210510202604_in_product_marketing_email_create_2_sent.yml
index 8d89567d015..10fb21997d3 100644
--- a/config/metrics/counts_all/20210510202604_in_product_marketing_email_create_2_sent.yml
+++ b/config/metrics/counts_all/20210510202604_in_product_marketing_email_create_2_sent.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510202724_in_product_marketing_email_create_2_cta_clicked.yml b/config/metrics/counts_all/20210510202724_in_product_marketing_email_create_2_cta_clicked.yml
index 047e6d4383b..21841bfe7ba 100644
--- a/config/metrics/counts_all/20210510202724_in_product_marketing_email_create_2_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510202724_in_product_marketing_email_create_2_cta_clicked.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510202807_in_product_marketing_email_verify_0_sent.yml b/config/metrics/counts_all/20210510202807_in_product_marketing_email_verify_0_sent.yml
index 0dcefe7cc18..66d894a62a9 100644
--- a/config/metrics/counts_all/20210510202807_in_product_marketing_email_verify_0_sent.yml
+++ b/config/metrics/counts_all/20210510202807_in_product_marketing_email_verify_0_sent.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510202943_in_product_marketing_email_verify_0_cta_clicked.yml b/config/metrics/counts_all/20210510202943_in_product_marketing_email_verify_0_cta_clicked.yml
index f9ed322c94a..39d02b343e5 100644
--- a/config/metrics/counts_all/20210510202943_in_product_marketing_email_verify_0_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510202943_in_product_marketing_email_verify_0_cta_clicked.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510202955_in_product_marketing_email_verify_1_sent.yml b/config/metrics/counts_all/20210510202955_in_product_marketing_email_verify_1_sent.yml
index a5432f3f08e..dcd61e22ab3 100644
--- a/config/metrics/counts_all/20210510202955_in_product_marketing_email_verify_1_sent.yml
+++ b/config/metrics/counts_all/20210510202955_in_product_marketing_email_verify_1_sent.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203005_in_product_marketing_email_verify_1_cta_clicked.yml b/config/metrics/counts_all/20210510203005_in_product_marketing_email_verify_1_cta_clicked.yml
index 33fc65ef90e..359eb181926 100644
--- a/config/metrics/counts_all/20210510203005_in_product_marketing_email_verify_1_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510203005_in_product_marketing_email_verify_1_cta_clicked.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203015_in_product_marketing_email_verify_2_sent.yml b/config/metrics/counts_all/20210510203015_in_product_marketing_email_verify_2_sent.yml
index b6a8165a0ad..b0263ce11ed 100644
--- a/config/metrics/counts_all/20210510203015_in_product_marketing_email_verify_2_sent.yml
+++ b/config/metrics/counts_all/20210510203015_in_product_marketing_email_verify_2_sent.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203025_in_product_marketing_email_verify_2_cta_clicked.yml b/config/metrics/counts_all/20210510203025_in_product_marketing_email_verify_2_cta_clicked.yml
index f7a1116c011..ba0e6ad9753 100644
--- a/config/metrics/counts_all/20210510203025_in_product_marketing_email_verify_2_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510203025_in_product_marketing_email_verify_2_cta_clicked.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203035_in_product_marketing_email_trial_0_sent.yml b/config/metrics/counts_all/20210510203035_in_product_marketing_email_trial_0_sent.yml
index 4525ee77874..843b1de808f 100644
--- a/config/metrics/counts_all/20210510203035_in_product_marketing_email_trial_0_sent.yml
+++ b/config/metrics/counts_all/20210510203035_in_product_marketing_email_trial_0_sent.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203044_in_product_marketing_email_trial_0_cta_clicked.yml b/config/metrics/counts_all/20210510203044_in_product_marketing_email_trial_0_cta_clicked.yml
index 56d54929864..82832d991ee 100644
--- a/config/metrics/counts_all/20210510203044_in_product_marketing_email_trial_0_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510203044_in_product_marketing_email_trial_0_cta_clicked.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203054_in_product_marketing_email_trial_1_sent.yml b/config/metrics/counts_all/20210510203054_in_product_marketing_email_trial_1_sent.yml
index 9ee4363f83c..2393643bacc 100644
--- a/config/metrics/counts_all/20210510203054_in_product_marketing_email_trial_1_sent.yml
+++ b/config/metrics/counts_all/20210510203054_in_product_marketing_email_trial_1_sent.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203104_in_product_marketing_email_trial_1_cta_clicked.yml b/config/metrics/counts_all/20210510203104_in_product_marketing_email_trial_1_cta_clicked.yml
index cd8b881e029..cb72d9bb8f5 100644
--- a/config/metrics/counts_all/20210510203104_in_product_marketing_email_trial_1_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510203104_in_product_marketing_email_trial_1_cta_clicked.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203114_in_product_marketing_email_trial_2_sent.yml b/config/metrics/counts_all/20210510203114_in_product_marketing_email_trial_2_sent.yml
index c1f6a7da94c..b1ae09410d1 100644
--- a/config/metrics/counts_all/20210510203114_in_product_marketing_email_trial_2_sent.yml
+++ b/config/metrics/counts_all/20210510203114_in_product_marketing_email_trial_2_sent.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203124_in_product_marketing_email_trial_2_cta_clicked.yml b/config/metrics/counts_all/20210510203124_in_product_marketing_email_trial_2_cta_clicked.yml
index c46dd95d8dc..a5714e17223 100644
--- a/config/metrics/counts_all/20210510203124_in_product_marketing_email_trial_2_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510203124_in_product_marketing_email_trial_2_cta_clicked.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203134_in_product_marketing_email_team_0_sent.yml b/config/metrics/counts_all/20210510203134_in_product_marketing_email_team_0_sent.yml
index 6cd44c2475f..beb6c6b9ecc 100644
--- a/config/metrics/counts_all/20210510203134_in_product_marketing_email_team_0_sent.yml
+++ b/config/metrics/counts_all/20210510203134_in_product_marketing_email_team_0_sent.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203143_in_product_marketing_email_team_0_cta_clicked.yml b/config/metrics/counts_all/20210510203143_in_product_marketing_email_team_0_cta_clicked.yml
index 020ec65966b..331639ca54f 100644
--- a/config/metrics/counts_all/20210510203143_in_product_marketing_email_team_0_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510203143_in_product_marketing_email_team_0_cta_clicked.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203153_in_product_marketing_email_team_1_sent.yml b/config/metrics/counts_all/20210510203153_in_product_marketing_email_team_1_sent.yml
index 8a0df5a4b9f..afa2854b0f9 100644
--- a/config/metrics/counts_all/20210510203153_in_product_marketing_email_team_1_sent.yml
+++ b/config/metrics/counts_all/20210510203153_in_product_marketing_email_team_1_sent.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203203_in_product_marketing_email_team_1_cta_clicked.yml b/config/metrics/counts_all/20210510203203_in_product_marketing_email_team_1_cta_clicked.yml
index 210bad95a55..0bac5ef76b7 100644
--- a/config/metrics/counts_all/20210510203203_in_product_marketing_email_team_1_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510203203_in_product_marketing_email_team_1_cta_clicked.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203213_in_product_marketing_email_team_2_sent.yml b/config/metrics/counts_all/20210510203213_in_product_marketing_email_team_2_sent.yml
index 3e3e680d45a..fe0770d900b 100644
--- a/config/metrics/counts_all/20210510203213_in_product_marketing_email_team_2_sent.yml
+++ b/config/metrics/counts_all/20210510203213_in_product_marketing_email_team_2_sent.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203223_in_product_marketing_email_team_2_cta_clicked.yml b/config/metrics/counts_all/20210510203223_in_product_marketing_email_team_2_cta_clicked.yml
index 9967091db09..3fe16910ae5 100644
--- a/config/metrics/counts_all/20210510203223_in_product_marketing_email_team_2_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510203223_in_product_marketing_email_team_2_cta_clicked.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210514141520_project_imports_total.yml b/config/metrics/counts_all/20210514141520_project_imports_total.yml
index be421a6b577..3846e3b9fc7 100644
--- a/config/metrics/counts_all/20210514141520_project_imports_total.yml
+++ b/config/metrics/counts_all/20210514141520_project_imports_total.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category:
value_type: number
-status: implemented
+status: active
milestone: "14.0"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61775
time_frame: all
diff --git a/config/metrics/counts_all/20210517073546_package_events_i_package_helm_pull_package.yml b/config/metrics/counts_all/20210517073546_package_events_i_package_helm_pull_package.yml
index c24a713711c..111056238bd 100644
--- a/config/metrics/counts_all/20210517073546_package_events_i_package_helm_pull_package.yml
+++ b/config/metrics/counts_all/20210517073546_package_events_i_package_helm_pull_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package_registry
value_type: number
-status: implemented
+status: active
milestone: "14.0"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61014
time_frame: all
diff --git a/config/metrics/counts_all/20210518081225_in_product_marketing_email_experience_0_sent.yml b/config/metrics/counts_all/20210518081225_in_product_marketing_email_experience_0_sent.yml
index 17b3cbb7cda..17c5b1a48c4 100644
--- a/config/metrics/counts_all/20210518081225_in_product_marketing_email_experience_0_sent.yml
+++ b/config/metrics/counts_all/20210518081225_in_product_marketing_email_experience_0_sent.yml
@@ -8,7 +8,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61347
time_frame: all
diff --git a/config/metrics/counts_all/20210625095025_package_events_i_package_helm_push_package.yml b/config/metrics/counts_all/20210625095025_package_events_i_package_helm_push_package.yml
index 0b1af1bf6d4..3752f3c8b2f 100644
--- a/config/metrics/counts_all/20210625095025_package_events_i_package_helm_push_package.yml
+++ b/config/metrics/counts_all/20210625095025_package_events_i_package_helm_push_package.yml
@@ -6,7 +6,7 @@ product_stage: package
product_group: group::package
product_category: package_registry
value_type: number
-status: implemented
+status: active
milestone: "14.1"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64814
time_frame: all
diff --git a/config/metrics/counts_all/20210709191135_package_events_i_package_nuget_pull_symbol_package.yml b/config/metrics/counts_all/20210709191135_package_events_i_package_nuget_pull_symbol_package.yml
index f61a1066759..8515a522a60 100644
--- a/config/metrics/counts_all/20210709191135_package_events_i_package_nuget_pull_symbol_package.yml
+++ b/config/metrics/counts_all/20210709191135_package_events_i_package_nuget_pull_symbol_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: implemented
+status: active
milestone: "14.1"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64554
time_frame: all
diff --git a/config/metrics/counts_all/20210709191829_package_events_i_package_nuget_push_symbol_package.yml b/config/metrics/counts_all/20210709191829_package_events_i_package_nuget_push_symbol_package.yml
index e220f54dadd..819c53bcc4f 100644
--- a/config/metrics/counts_all/20210709191829_package_events_i_package_nuget_push_symbol_package.yml
+++ b/config/metrics/counts_all/20210709191829_package_events_i_package_nuget_push_symbol_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: implemented
+status: active
milestone: "14.1"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64554
time_frame: all
diff --git a/config/metrics/counts_all/20210709210941_package_events_i_package_pull_symbol_package.yml b/config/metrics/counts_all/20210709210941_package_events_i_package_pull_symbol_package.yml
index 825b86958bf..8edd10b3a42 100644
--- a/config/metrics/counts_all/20210709210941_package_events_i_package_pull_symbol_package.yml
+++ b/config/metrics/counts_all/20210709210941_package_events_i_package_pull_symbol_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: implemented
+status: active
milestone: "14.1"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64554
time_frame: all
diff --git a/config/metrics/counts_all/20210709211058_package_events_i_package_pull_symbol_package_by_deploy_token.yml b/config/metrics/counts_all/20210709211058_package_events_i_package_pull_symbol_package_by_deploy_token.yml
index b31f9e42aa2..f3e48ba6786 100644
--- a/config/metrics/counts_all/20210709211058_package_events_i_package_pull_symbol_package_by_deploy_token.yml
+++ b/config/metrics/counts_all/20210709211058_package_events_i_package_pull_symbol_package_by_deploy_token.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: implemented
+status: active
milestone: "14.1"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64554
time_frame: all
diff --git a/config/metrics/counts_all/20210709211248_package_events_i_package_pull_symbol_package_by_guest.yml b/config/metrics/counts_all/20210709211248_package_events_i_package_pull_symbol_package_by_guest.yml
index 4a40a793d41..33b164a9653 100644
--- a/config/metrics/counts_all/20210709211248_package_events_i_package_pull_symbol_package_by_guest.yml
+++ b/config/metrics/counts_all/20210709211248_package_events_i_package_pull_symbol_package_by_guest.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: implemented
+status: active
milestone: "14.1"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64554
time_frame: all
diff --git a/config/metrics/counts_all/20210709211341_package_events_i_package_pull_symbol_package_by_user.yml b/config/metrics/counts_all/20210709211341_package_events_i_package_pull_symbol_package_by_user.yml
index 44eb3efe429..8959af7f70c 100644
--- a/config/metrics/counts_all/20210709211341_package_events_i_package_pull_symbol_package_by_user.yml
+++ b/config/metrics/counts_all/20210709211341_package_events_i_package_pull_symbol_package_by_user.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: implemented
+status: active
milestone: "14.1"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64554
time_frame: all
diff --git a/config/metrics/counts_all/20210709211439_package_events_i_package_push_symbol_package.yml b/config/metrics/counts_all/20210709211439_package_events_i_package_push_symbol_package.yml
index 5e4114c1e34..35d89b856f3 100644
--- a/config/metrics/counts_all/20210709211439_package_events_i_package_push_symbol_package.yml
+++ b/config/metrics/counts_all/20210709211439_package_events_i_package_push_symbol_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: implemented
+status: active
milestone: "14.1"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64554
time_frame: all
diff --git a/config/metrics/counts_all/20210709211636_package_events_i_package_push_symbol_package_by_deploy_token.yml b/config/metrics/counts_all/20210709211636_package_events_i_package_push_symbol_package_by_deploy_token.yml
index b6da6dfb60b..f102da96d17 100644
--- a/config/metrics/counts_all/20210709211636_package_events_i_package_push_symbol_package_by_deploy_token.yml
+++ b/config/metrics/counts_all/20210709211636_package_events_i_package_push_symbol_package_by_deploy_token.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: implemented
+status: active
milestone: "14.1"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64554
time_frame: all
diff --git a/config/metrics/counts_all/20210709211731_package_events_i_package_push_symbol_package_by_guest.yml b/config/metrics/counts_all/20210709211731_package_events_i_package_push_symbol_package_by_guest.yml
index 26a4c1cb2cd..7e5e63b6a17 100644
--- a/config/metrics/counts_all/20210709211731_package_events_i_package_push_symbol_package_by_guest.yml
+++ b/config/metrics/counts_all/20210709211731_package_events_i_package_push_symbol_package_by_guest.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: implemented
+status: active
milestone: "14.1"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64554
time_frame: all
diff --git a/config/metrics/counts_all/20210709211831_package_events_i_package_push_symbol_package_by_user.yml b/config/metrics/counts_all/20210709211831_package_events_i_package_push_symbol_package_by_user.yml
index aff7e4a5f8d..e45db0aee02 100644
--- a/config/metrics/counts_all/20210709211831_package_events_i_package_push_symbol_package_by_user.yml
+++ b/config/metrics/counts_all/20210709211831_package_events_i_package_push_symbol_package_by_user.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: implemented
+status: active
milestone: "14.1"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64554
time_frame: all
diff --git a/config/metrics/counts_all/20210723075525_diff_searches.yml b/config/metrics/counts_all/20210723075525_diff_searches.yml
index 02bb3c7ff67..28e1ce927dc 100644
--- a/config/metrics/counts_all/20210723075525_diff_searches.yml
+++ b/config/metrics/counts_all/20210723075525_diff_searches.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: active
milestone: '14.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66522
time_frame: all
diff --git a/config/metrics/counts_all/20210727095918_in_product_marketing_email_team_short_0_cta_clicked.yml b/config/metrics/counts_all/20210727095918_in_product_marketing_email_team_short_0_cta_clicked.yml
index c720bf1556a..0f0b467ab45 100644
--- a/config/metrics/counts_all/20210727095918_in_product_marketing_email_team_short_0_cta_clicked.yml
+++ b/config/metrics/counts_all/20210727095918_in_product_marketing_email_team_short_0_cta_clicked.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: active
milestone: "14.2"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66854
time_frame: all
diff --git a/config/metrics/counts_all/20210727095923_in_product_marketing_email_team_short_0_sent.yml b/config/metrics/counts_all/20210727095923_in_product_marketing_email_team_short_0_sent.yml
index 7c63172990f..e60be585be8 100644
--- a/config/metrics/counts_all/20210727095923_in_product_marketing_email_team_short_0_sent.yml
+++ b/config/metrics/counts_all/20210727095923_in_product_marketing_email_team_short_0_sent.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: active
milestone: "14.2"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66854
time_frame: all
diff --git a/config/metrics/counts_all/20210727170553_in_product_marketing_email_trial_short_0_cta_clicked.yml b/config/metrics/counts_all/20210727170553_in_product_marketing_email_trial_short_0_cta_clicked.yml
index 0761627c548..a34cc75c09b 100644
--- a/config/metrics/counts_all/20210727170553_in_product_marketing_email_trial_short_0_cta_clicked.yml
+++ b/config/metrics/counts_all/20210727170553_in_product_marketing_email_trial_short_0_cta_clicked.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: active
milestone: "14.2"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66943
time_frame: all
diff --git a/config/metrics/counts_all/20210727170558_in_product_marketing_email_trial_short_0_sent.yml b/config/metrics/counts_all/20210727170558_in_product_marketing_email_trial_short_0_sent.yml
index e18ab01b4a5..05711afef8f 100644
--- a/config/metrics/counts_all/20210727170558_in_product_marketing_email_trial_short_0_sent.yml
+++ b/config/metrics/counts_all/20210727170558_in_product_marketing_email_trial_short_0_sent.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: active
milestone: "14.2"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66943
time_frame: all
diff --git a/config/metrics/counts_all/20210729140021_in_product_marketing_email_admin_verify_0_cta_clicked.yml b/config/metrics/counts_all/20210729140021_in_product_marketing_email_admin_verify_0_cta_clicked.yml
index aa1ce32f7c8..695fada6670 100644
--- a/config/metrics/counts_all/20210729140021_in_product_marketing_email_admin_verify_0_cta_clicked.yml
+++ b/config/metrics/counts_all/20210729140021_in_product_marketing_email_admin_verify_0_cta_clicked.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: active
milestone: "14.2"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67147
time_frame: all
diff --git a/config/metrics/counts_all/20210729140423_in_product_marketing_email_admin_verify_0_sent.yml b/config/metrics/counts_all/20210729140423_in_product_marketing_email_admin_verify_0_sent.yml
index 6cc374030d1..8f52a79cc2a 100644
--- a/config/metrics/counts_all/20210729140423_in_product_marketing_email_admin_verify_0_sent.yml
+++ b/config/metrics/counts_all/20210729140423_in_product_marketing_email_admin_verify_0_sent.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: active
milestone: "14.2"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67147
time_frame: all
diff --git a/config/metrics/counts_all/20210910132001_user_auth_by_provider.yml b/config/metrics/counts_all/20210910132001_user_auth_by_provider.yml
new file mode 100644
index 00000000000..610c187407b
--- /dev/null
+++ b/config/metrics/counts_all/20210910132001_user_auth_by_provider.yml
@@ -0,0 +1,24 @@
+---
+key_path: usage_activity_by_stage.manage.user_auth_by_provider
+name: count_distinct_users_using_two_factor_authentication
+description: Number of unique user logins using two factor authentication for available providers
+product_section: dev
+product_stage: manage
+product_group: group::access
+product_category: authentication_and_authorization
+value_type: object
+status: active
+milestone: "14.3"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70061
+time_frame: all
+data_source: database
+data_category: optional
+performance_indicator_type: []
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+value_json_schema: "config/metrics/objects_schemas/user_auth_by_provider.json"
diff --git a/config/metrics/license/20210201124932_recorded_at.yml b/config/metrics/license/20210201124932_recorded_at.yml
index 3b80163a05e..59388f5bb20 100644
--- a/config/metrics/license/20210201124932_recorded_at.yml
+++ b/config/metrics/license/20210201124932_recorded_at.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::product intelligence
product_category: collection
value_type: string
-status: data_available
+status: active
milestone: "8.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/557
time_frame: none
diff --git a/config/metrics/license/20210201124933_uuid.yml b/config/metrics/license/20210201124933_uuid.yml
index a9503adf6c9..11cb6ac1411 100644
--- a/config/metrics/license/20210201124933_uuid.yml
+++ b/config/metrics/license/20210201124933_uuid.yml
@@ -6,7 +6,7 @@ product_stage: growth
product_group: group::product intelligence
product_category: collection
value_type: string
-status: data_available
+status: active
milestone: "9.1"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/1521
time_frame: none
diff --git a/config/metrics/license/20210204124827_hostname.yml b/config/metrics/license/20210204124827_hostname.yml
index 36e57ee6e1d..4496f158ea1 100644
--- a/config/metrics/license/20210204124827_hostname.yml
+++ b/config/metrics/license/20210204124827_hostname.yml
@@ -6,7 +6,8 @@ product_stage: growth
product_group: group::product intelligence
product_category: collection
value_type: string
-status: data_available
+status: active
+milestone: "<13.9"
time_frame: none
data_source: system
data_category: standard
diff --git a/config/metrics/license/20210204124829_active_user_count.yml b/config/metrics/license/20210204124829_active_user_count.yml
index f8beb5dfd0e..871a75bd97b 100644
--- a/config/metrics/license/20210204124829_active_user_count.yml
+++ b/config/metrics/license/20210204124829_active_user_count.yml
@@ -6,7 +6,8 @@ product_stage: growth
product_group: group::product intelligence
product_category: collection
value_type: string
-status: data_available
+status: active
+milestone: "<13.9"
data_category: subscription
time_frame: none
data_source: database
diff --git a/config/metrics/license/20210204124928_version.yml b/config/metrics/license/20210204124928_version.yml
index 09b9f978519..de081d10cff 100644
--- a/config/metrics/license/20210204124928_version.yml
+++ b/config/metrics/license/20210204124928_version.yml
@@ -2,17 +2,20 @@
data_category: operational
key_path: gitaly.version
description: Version of Gitaly
-product_section: growth
-product_stage: growth
-product_group: group::product intelligence
-product_category: collection
+product_section: dev
+product_stage: create
+product_group: group::gitaly
+product_category: gitaly
value_type: string
-status: data_available
+status: active
+milestone: "<13.9"
time_frame: none
data_source: system
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type: []
diff --git a/config/metrics/license/20210204124936_pages_version.yml b/config/metrics/license/20210204124936_pages_version.yml
index 72960ef07a0..5e498ceb6c4 100644
--- a/config/metrics/license/20210204124936_pages_version.yml
+++ b/config/metrics/license/20210204124936_pages_version.yml
@@ -7,7 +7,8 @@ product_stage: release
product_group: group::release
product_category: pages
value_type: string
-status: data_available
+status: active
+milestone: "<13.9"
time_frame: none
data_source: system
distribution:
diff --git a/config/metrics/license/20210204124938_recording_ce_finished_at.yml b/config/metrics/license/20210204124938_recording_ce_finished_at.yml
index 07687856974..02521e8bd2c 100644
--- a/config/metrics/license/20210204124938_recording_ce_finished_at.yml
+++ b/config/metrics/license/20210204124938_recording_ce_finished_at.yml
@@ -7,7 +7,9 @@ product_stage: growth
product_group: group::product intelligence
product_category: collection
value_type: string
-status: data_available
+status: active
+milestone: "13.0"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31222
time_frame: none
data_source: system
distribution:
diff --git a/config/metrics/license/20210216175601_version.yml b/config/metrics/license/20210216175601_version.yml
index acc83f0b693..a6af4ff2c9b 100644
--- a/config/metrics/license/20210216175601_version.yml
+++ b/config/metrics/license/20210216175601_version.yml
@@ -7,7 +7,8 @@ product_stage: enablement
product_group: group::distribution
product_category: collection
value_type: string
-status: data_available
+status: active
+milestone: "<13.9"
time_frame: none
data_source: system
distribution:
@@ -17,5 +18,4 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
diff --git a/config/metrics/license/20210216175602_installation_type.yml b/config/metrics/license/20210216175602_installation_type.yml
index 2c838549beb..d19405549d6 100644
--- a/config/metrics/license/20210216175602_installation_type.yml
+++ b/config/metrics/license/20210216175602_installation_type.yml
@@ -7,7 +7,9 @@ product_stage: enablement
product_group: group::distribution
product_category: collection
value_type: string
-status: data_available
+status: active
+milestone: "11.0"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/5952/
time_frame: none
data_source: system
distribution:
diff --git a/config/metrics/license/20210216181053_version.yml b/config/metrics/license/20210216181053_version.yml
index f4c0c9fa794..d6e6ea1c0e0 100644
--- a/config/metrics/license/20210216181053_version.yml
+++ b/config/metrics/license/20210216181053_version.yml
@@ -7,7 +7,8 @@ product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: data_available
+status: active
+milestone: "<13.9"
time_frame: none
data_source: system
distribution:
diff --git a/config/metrics/license/20210216183237_version.yml b/config/metrics/license/20210216183237_version.yml
index 1f2a221e456..6517c3bc4f5 100644
--- a/config/metrics/license/20210216183237_version.yml
+++ b/config/metrics/license/20210216183237_version.yml
@@ -7,7 +7,8 @@ product_stage: enablement
product_group: group::distribution
product_category: ''
value_type: string
-status: data_available
+status: active
+milestone: "<13.9"
time_frame: none
data_source: system
distribution:
diff --git a/config/metrics/objects_schemas/user_auth_by_provider.json b/config/metrics/objects_schemas/user_auth_by_provider.json
new file mode 100644
index 00000000000..9cf4c1d68aa
--- /dev/null
+++ b/config/metrics/objects_schemas/user_auth_by_provider.json
@@ -0,0 +1,16 @@
+{
+ "type": "object",
+ "description": "Distinct users by provider",
+ "properties": {
+ "two-factor": {"type": "number", "description": " Number of unique user logins using two factor authentication" },
+ "two-factor-via-u2f-device": {"type": "number", "description": " Number of unique user logins using two factor authentication via U2F" },
+ "two-factor-via-webauthn-device": {"type": "number", "description": " Number of unique user logins using two factor authentication via two-factor-via-webauthn-device" },
+ "standard": {"type": "number", "description": " Number of unique user logins using password authentication" },
+ "google_oauth2": {"type": "number", "description": " Number of unique user logins using Google OAuth authentication" },
+ "twitter": {"type": "number", "description": " Number of unique user logins using Twitter authentication" },
+ "github": {"type": "number", "description": " Number of unique user logins using Github authentication" },
+ "bitbucket": {"type": "number", "description": " Number of unique user logins using Bitbucket authentication" },
+ "group_saml": {"type": "number", "description": " Number of unique user logins using group SAML authentication" },
+ "salesforce": {"type": "number", "description": " Number of unique user logins using group Salesforce authentication" }
+ }
+}
diff --git a/config/metrics/schema.json b/config/metrics/schema.json
index 24ea41d3f16..ede7b9d3f6c 100644
--- a/config/metrics/schema.json
+++ b/config/metrics/schema.json
@@ -1,6 +1,6 @@
{
"type": "object",
- "required": ["key_path", "description", "value_type", "status", "product_group", "time_frame", "data_source", "distribution", "tier", "data_category"],
+ "required": ["key_path", "description", "value_type", "status", "product_group", "product_stage", "time_frame", "data_source", "distribution", "tier", "data_category", "milestone"],
"properties": {
"key_path": {
"type": "string"
@@ -30,11 +30,11 @@
},
"status": {
"type": ["string"],
- "enum": ["data_available", "implemented", "not_used", "deprecated", "removed", "broken"]
+ "enum": ["active", "deprecated", "removed", "broken"]
},
"milestone": {
- "type": ["string", "null"],
- "pattern": "^[0-9]+\\.[0-9]+$"
+ "type": ["string"],
+ "pattern": "^<?[0-9]+\\.[0-9]+$"
},
"milestone_removed": {
"type": ["string", "null"],
diff --git a/config/metrics/settings/20210201124935_database_adapter.yml b/config/metrics/settings/20210201124935_database_adapter.yml
index 38cdba2a071..a127b2b70dd 100644
--- a/config/metrics/settings/20210201124935_database_adapter.yml
+++ b/config/metrics/settings/20210201124935_database_adapter.yml
@@ -1,13 +1,15 @@
---
data_category: optional
key_path: database.adapter
-description: This metric only returns a value of PostgreSQL in supported versions of GitLab. It could be removed from the usage ping. Historically MySQL was also supported.
+description: This metric only returns a value of PostgreSQL in supported versions
+ of GitLab. It could be removed from the usage ping. Historically MySQL was also
+ supported.
product_section: enablement
product_stage: enablement
product_group: group::enablement distribution
product_category: collection
value_type: string
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +20,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210204124856_instance_auto_devops_enabled.yml b/config/metrics/settings/20210204124856_instance_auto_devops_enabled.yml
index 8d635cc17a0..5b886288fec 100644
--- a/config/metrics/settings/20210204124856_instance_auto_devops_enabled.yml
+++ b/config/metrics/settings/20210204124856_instance_auto_devops_enabled.yml
@@ -7,7 +7,7 @@ product_stage: configure
product_group: group::configure
product_category: auto_devops
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210204124858_container_registry_enabled.yml b/config/metrics/settings/20210204124858_container_registry_enabled.yml
index a780b8cfaa9..c65d1934c61 100644
--- a/config/metrics/settings/20210204124858_container_registry_enabled.yml
+++ b/config/metrics/settings/20210204124858_container_registry_enabled.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: container registry
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210204124900_dependency_proxy_enabled.yml b/config/metrics/settings/20210204124900_dependency_proxy_enabled.yml
index d92a3d9b5f9..694bb4b08bd 100644
--- a/config/metrics/settings/20210204124900_dependency_proxy_enabled.yml
+++ b/config/metrics/settings/20210204124900_dependency_proxy_enabled.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: container registry
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210204124902_gitlab_shared_runners_enabled.yml b/config/metrics/settings/20210204124902_gitlab_shared_runners_enabled.yml
index 552b0467518..6b5719d284d 100644
--- a/config/metrics/settings/20210204124902_gitlab_shared_runners_enabled.yml
+++ b/config/metrics/settings/20210204124902_gitlab_shared_runners_enabled.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::runner
product_category: runner
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210204124904_gravatar_enabled.yml b/config/metrics/settings/20210204124904_gravatar_enabled.yml
index 541c7be16e7..dde0bc118e7 100644
--- a/config/metrics/settings/20210204124904_gravatar_enabled.yml
+++ b/config/metrics/settings/20210204124904_gravatar_enabled.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::access
product_category: users
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210204124906_ldap_enabled.yml b/config/metrics/settings/20210204124906_ldap_enabled.yml
index cabbac5619e..1f58fd0ffba 100644
--- a/config/metrics/settings/20210204124906_ldap_enabled.yml
+++ b/config/metrics/settings/20210204124906_ldap_enabled.yml
@@ -2,17 +2,20 @@
data_category: optional
key_path: ldap_enabled
description: Whether LDAP is enabled
-product_section: growth
-product_stage: growth
-product_group: group::product intelligence
-product_category: collection
+product_section: dev
+product_stage: manage
+product_group: group::access
+product_category: authentication_and_authorization
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210204124908_mattermost_enabled.yml b/config/metrics/settings/20210204124908_mattermost_enabled.yml
index 0cefe4b595f..cc00b3b9da2 100644
--- a/config/metrics/settings/20210204124908_mattermost_enabled.yml
+++ b/config/metrics/settings/20210204124908_mattermost_enabled.yml
@@ -7,7 +7,7 @@ product_stage: ecosystem
product_group: group::integrations
product_category: integrations
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210204124910_omniauth_enabled.yml b/config/metrics/settings/20210204124910_omniauth_enabled.yml
index 6451a66c87e..f4531b10055 100644
--- a/config/metrics/settings/20210204124910_omniauth_enabled.yml
+++ b/config/metrics/settings/20210204124910_omniauth_enabled.yml
@@ -2,17 +2,20 @@
data_category: optional
key_path: omniauth_enabled
description: Whether OmniAuth is enabled
-product_section: growth
-product_stage: growth
-product_group: group::product intelligence
-product_category: collection
+product_section: dev
+product_stage: manage
+product_group: group::access
+product_category: authentication_and_authorization
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210204124912_prometheus_enabled.yml b/config/metrics/settings/20210204124912_prometheus_enabled.yml
index 9002751cf6a..236e1656a6b 100644
--- a/config/metrics/settings/20210204124912_prometheus_enabled.yml
+++ b/config/metrics/settings/20210204124912_prometheus_enabled.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::product intelligence
product_category: collection
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210204124914_prometheus_metrics_enabled.yml b/config/metrics/settings/20210204124914_prometheus_metrics_enabled.yml
index 04fc99f8dc5..1d13b72fbff 100644
--- a/config/metrics/settings/20210204124914_prometheus_metrics_enabled.yml
+++ b/config/metrics/settings/20210204124914_prometheus_metrics_enabled.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::product intelligence
product_category: collection
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210204124916_reply_by_email_enabled.yml b/config/metrics/settings/20210204124916_reply_by_email_enabled.yml
index 4d4de2da28a..c9d223c8c58 100644
--- a/config/metrics/settings/20210204124916_reply_by_email_enabled.yml
+++ b/config/metrics/settings/20210204124916_reply_by_email_enabled.yml
@@ -7,7 +7,7 @@ product_stage: plan
product_group: group::certify
product_category: collection
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210204124918_signup_enabled.yml b/config/metrics/settings/20210204124918_signup_enabled.yml
index 059a3ecba7f..e8c3226ebf8 100644
--- a/config/metrics/settings/20210204124918_signup_enabled.yml
+++ b/config/metrics/settings/20210204124918_signup_enabled.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::access
product_category: authentication_and_authorization
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -17,5 +17,5 @@ tier:
- free
- premium
- ultimate
-skip_validation: true
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210204124920_web_ide_clientside_preview_enabled.yml b/config/metrics/settings/20210204124920_web_ide_clientside_preview_enabled.yml
index f972622d176..9bc2a90fc1d 100644
--- a/config/metrics/settings/20210204124920_web_ide_clientside_preview_enabled.yml
+++ b/config/metrics/settings/20210204124920_web_ide_clientside_preview_enabled.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: collection
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210204124922_grafana_link_enabled.yml b/config/metrics/settings/20210204124922_grafana_link_enabled.yml
index 78225329763..d636f00312d 100644
--- a/config/metrics/settings/20210204124922_grafana_link_enabled.yml
+++ b/config/metrics/settings/20210204124922_grafana_link_enabled.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::product intelligence
product_category: collection
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -15,3 +15,4 @@ distribution:
tier:
- free
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210204124934_pages_enabled.yml b/config/metrics/settings/20210204124934_pages_enabled.yml
index 7c830e56787..28e12d85e41 100644
--- a/config/metrics/settings/20210204124934_pages_enabled.yml
+++ b/config/metrics/settings/20210204124934_pages_enabled.yml
@@ -7,7 +7,7 @@ product_stage: release
product_group: group::release
product_category: collection
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216174829_smtp_server.yml b/config/metrics/settings/20210216174829_smtp_server.yml
index f82fddbc86c..c1e4d77bc6c 100644
--- a/config/metrics/settings/20210216174829_smtp_server.yml
+++ b/config/metrics/settings/20210216174829_smtp_server.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216175459_ingress_modsecurity_enabled.yml b/config/metrics/settings/20210216175459_ingress_modsecurity_enabled.yml
index d92815bebfd..9bf0277363f 100644
--- a/config/metrics/settings/20210216175459_ingress_modsecurity_enabled.yml
+++ b/config/metrics/settings/20210216175459_ingress_modsecurity_enabled.yml
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216175604_edition.yml b/config/metrics/settings/20210216175604_edition.yml
index c85378304cc..9a586f0c78b 100644
--- a/config/metrics/settings/20210216175604_edition.yml
+++ b/config/metrics/settings/20210216175604_edition.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::distribution
product_category: collection
value_type: string
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216175606_ldap_encrypted_secrets_enabled.yml b/config/metrics/settings/20210216175606_ldap_encrypted_secrets_enabled.yml
index fb0d3163b3e..046811b8686 100644
--- a/config/metrics/settings/20210216175606_ldap_encrypted_secrets_enabled.yml
+++ b/config/metrics/settings/20210216175606_ldap_encrypted_secrets_enabled.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::distribution
product_category: global_search
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216175609_version.yml b/config/metrics/settings/20210216175609_version.yml
index 1a8f7af4742..136b8fed4ff 100644
--- a/config/metrics/settings/20210216175609_version.yml
+++ b/config/metrics/settings/20210216175609_version.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::distribution
product_category: collection
value_type: string
-status: data_available
+status: active
time_frame: none
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180314_gitpod_enabled.yml b/config/metrics/settings/20210216180314_gitpod_enabled.yml
index 1ade7ee7186..15a747fdffb 100644
--- a/config/metrics/settings/20210216180314_gitpod_enabled.yml
+++ b/config/metrics/settings/20210216180314_gitpod_enabled.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::editor
product_category: integrations
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180836_enabled.yml b/config/metrics/settings/20210216180836_enabled.yml
index f4f8f721ad1..12eae478add 100644
--- a/config/metrics/settings/20210216180836_enabled.yml
+++ b/config/metrics/settings/20210216180836_enabled.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180838_enabled.yml b/config/metrics/settings/20210216180838_enabled.yml
index 03f4f52aaf9..da6dd5fce62 100644
--- a/config/metrics/settings/20210216180838_enabled.yml
+++ b/config/metrics/settings/20210216180838_enabled.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180840_direct_upload.yml b/config/metrics/settings/20210216180840_direct_upload.yml
index b8b85af94f9..279b9472364 100644
--- a/config/metrics/settings/20210216180840_direct_upload.yml
+++ b/config/metrics/settings/20210216180840_direct_upload.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180841_background_upload.yml b/config/metrics/settings/20210216180841_background_upload.yml
index d354ad6ff49..829e20e2405 100644
--- a/config/metrics/settings/20210216180841_background_upload.yml
+++ b/config/metrics/settings/20210216180841_background_upload.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180843_provider.yml b/config/metrics/settings/20210216180843_provider.yml
index 8b94a67dba7..848e0669b73 100644
--- a/config/metrics/settings/20210216180843_provider.yml
+++ b/config/metrics/settings/20210216180843_provider.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: string
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180845_enabled.yml b/config/metrics/settings/20210216180845_enabled.yml
index a40aadf701a..d5e42959871 100644
--- a/config/metrics/settings/20210216180845_enabled.yml
+++ b/config/metrics/settings/20210216180845_enabled.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180847_enabled.yml b/config/metrics/settings/20210216180847_enabled.yml
index b1adeac5238..49c8c887ccc 100644
--- a/config/metrics/settings/20210216180847_enabled.yml
+++ b/config/metrics/settings/20210216180847_enabled.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180849_direct_upload.yml b/config/metrics/settings/20210216180849_direct_upload.yml
index a25637270e7..d91e033ee4a 100644
--- a/config/metrics/settings/20210216180849_direct_upload.yml
+++ b/config/metrics/settings/20210216180849_direct_upload.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180851_background_upload.yml b/config/metrics/settings/20210216180851_background_upload.yml
index 1326c2ebef4..76dc5007857 100644
--- a/config/metrics/settings/20210216180851_background_upload.yml
+++ b/config/metrics/settings/20210216180851_background_upload.yml
@@ -8,7 +8,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -19,3 +19,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180852_provider.yml b/config/metrics/settings/20210216180852_provider.yml
index e057a6384a2..01cd2a43ff2 100644
--- a/config/metrics/settings/20210216180852_provider.yml
+++ b/config/metrics/settings/20210216180852_provider.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: string
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180854_enabled.yml b/config/metrics/settings/20210216180854_enabled.yml
index c129bb028d5..bf0ec99486b 100644
--- a/config/metrics/settings/20210216180854_enabled.yml
+++ b/config/metrics/settings/20210216180854_enabled.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180856_enabled.yml b/config/metrics/settings/20210216180856_enabled.yml
index bd26d91a2fa..a21b8f0eb15 100644
--- a/config/metrics/settings/20210216180856_enabled.yml
+++ b/config/metrics/settings/20210216180856_enabled.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180858_direct_upload.yml b/config/metrics/settings/20210216180858_direct_upload.yml
index 281b6744d35..85619adc8f2 100644
--- a/config/metrics/settings/20210216180858_direct_upload.yml
+++ b/config/metrics/settings/20210216180858_direct_upload.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180900_background_upload.yml b/config/metrics/settings/20210216180900_background_upload.yml
index 2e39fa7e379..959ae65306d 100644
--- a/config/metrics/settings/20210216180900_background_upload.yml
+++ b/config/metrics/settings/20210216180900_background_upload.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180902_provider.yml b/config/metrics/settings/20210216180902_provider.yml
index a8d265f9676..50b88f893ee 100644
--- a/config/metrics/settings/20210216180902_provider.yml
+++ b/config/metrics/settings/20210216180902_provider.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: string
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180903_enabled.yml b/config/metrics/settings/20210216180903_enabled.yml
index 00e52b86d86..759fdeeba93 100644
--- a/config/metrics/settings/20210216180903_enabled.yml
+++ b/config/metrics/settings/20210216180903_enabled.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: string
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180905_enabled.yml b/config/metrics/settings/20210216180905_enabled.yml
index dba464bfed3..b71472488b1 100644
--- a/config/metrics/settings/20210216180905_enabled.yml
+++ b/config/metrics/settings/20210216180905_enabled.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180907_direct_upload.yml b/config/metrics/settings/20210216180907_direct_upload.yml
index 93b69a728bc..b5e702462ec 100644
--- a/config/metrics/settings/20210216180907_direct_upload.yml
+++ b/config/metrics/settings/20210216180907_direct_upload.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180909_background_upload.yml b/config/metrics/settings/20210216180909_background_upload.yml
index 1af3d227f2f..e4800ee74a7 100644
--- a/config/metrics/settings/20210216180909_background_upload.yml
+++ b/config/metrics/settings/20210216180909_background_upload.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180911_provider.yml b/config/metrics/settings/20210216180911_provider.yml
index f9f98da3569..c0e69fe0646 100644
--- a/config/metrics/settings/20210216180911_provider.yml
+++ b/config/metrics/settings/20210216180911_provider.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: string
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180913_enabled.yml b/config/metrics/settings/20210216180913_enabled.yml
index 436e5f717c1..c1e8869d9a6 100644
--- a/config/metrics/settings/20210216180913_enabled.yml
+++ b/config/metrics/settings/20210216180913_enabled.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180915_enabled.yml b/config/metrics/settings/20210216180915_enabled.yml
index b52d85ef8df..34649634deb 100644
--- a/config/metrics/settings/20210216180915_enabled.yml
+++ b/config/metrics/settings/20210216180915_enabled.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180916_direct_upload.yml b/config/metrics/settings/20210216180916_direct_upload.yml
index 058531516d7..3f5d354baa1 100644
--- a/config/metrics/settings/20210216180916_direct_upload.yml
+++ b/config/metrics/settings/20210216180916_direct_upload.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180918_background_upload.yml b/config/metrics/settings/20210216180918_background_upload.yml
index c03e600b622..d2e630e2a17 100644
--- a/config/metrics/settings/20210216180918_background_upload.yml
+++ b/config/metrics/settings/20210216180918_background_upload.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: boolean
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216180920_provider.yml b/config/metrics/settings/20210216180920_provider.yml
index bda2c485e3a..6de7aed8801 100644
--- a/config/metrics/settings/20210216180920_provider.yml
+++ b/config/metrics/settings/20210216180920_provider.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category: memory
value_type: string
-status: data_available
+status: active
time_frame: none
data_source: system
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216183241_filesystems.yml b/config/metrics/settings/20210216183241_filesystems.yml
index 85f2a736756..216ca790638 100644
--- a/config/metrics/settings/20210216183241_filesystems.yml
+++ b/config/metrics/settings/20210216183241_filesystems.yml
@@ -1,18 +1,20 @@
---
data_category: optional
key_path: gitaly.filesystems
-description: ''
-product_section: ''
-product_stage: ''
-product_group: ''
-product_category: ''
-value_type: number
-status: data_available
+description: Filesystem data for Gitaly installations
+product_section: dev
+product_stage: create
+product_group: group::gitaly
+product_category: gitaly
+value_type: string
+status: active
time_frame: all
data_source: system
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
-performance_indicator_type: []
+- premium
+- ultimate
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210216183248_pg_system_id.yml b/config/metrics/settings/20210216183248_pg_system_id.yml
index 5883473a003..a96994f9de6 100644
--- a/config/metrics/settings/20210216183248_pg_system_id.yml
+++ b/config/metrics/settings/20210216183248_pg_system_id.yml
@@ -5,14 +5,17 @@ description: TBD
product_section: enablement
product_stage: enablement
product_group: group::distribution
-product_category:
+product_category:
value_type: number
-status: data_available
+status: active
time_frame: all
data_source: system
distribution:
- ce
+- ee
tier:
- free
-skip_validation: true
+- premium
+- ultimate
performance_indicator_type: []
+milestone: "<13.9"
diff --git a/config/metrics/settings/20210225045628_operating_system.yml b/config/metrics/settings/20210225045628_operating_system.yml
index 670babcef44..3db6412cc13 100644
--- a/config/metrics/settings/20210225045628_operating_system.yml
+++ b/config/metrics/settings/20210225045628_operating_system.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::distribution
product_category: collection
value_type: string
-status: data_available
+status: active
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54778
time_frame: none
diff --git a/config/metrics/settings/20210321224827_gitaly_apdex.yml b/config/metrics/settings/20210321224827_gitaly_apdex.yml
index 92d80129412..6d5204f61bf 100644
--- a/config/metrics/settings/20210321224827_gitaly_apdex.yml
+++ b/config/metrics/settings/20210321224827_gitaly_apdex.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::gitaly
product_category: gitaly
value_type: number
-status: data_available
+status: active
milestone: "13.11"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/47040
time_frame: none
diff --git a/config/metrics/settings/20210323120839_topology.yml b/config/metrics/settings/20210323120839_topology.yml
index 934dc4dd6ce..a254ad36dfe 100644
--- a/config/metrics/settings/20210323120839_topology.yml
+++ b/config/metrics/settings/20210323120839_topology.yml
@@ -7,7 +7,7 @@ product_stage: enablement
product_group: group::memory
product_category:
value_type: object
-status: data_available
+status: active
milestone: "13.11"
introduced_by_url: https://gitlab.com/groups/gitlab-org/-/epics/3209
time_frame: none
diff --git a/config/metrics/settings/20210702140138_collected_data_categories.yml b/config/metrics/settings/20210702140138_collected_data_categories.yml
index 65ae674d502..27262af8aa5 100644
--- a/config/metrics/settings/20210702140138_collected_data_categories.yml
+++ b/config/metrics/settings/20210702140138_collected_data_categories.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::product intelligence
product_category: collection
value_type: object
-status: implemented
+status: active
milestone: "14.1"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65336
time_frame: none
diff --git a/config/metrics/settings/20210812202137_smtp_encrypted_secrets_enabled.yml b/config/metrics/settings/20210812202137_smtp_encrypted_secrets_enabled.yml
index ea6d92793de..934daf472fa 100644
--- a/config/metrics/settings/20210812202137_smtp_encrypted_secrets_enabled.yml
+++ b/config/metrics/settings/20210812202137_smtp_encrypted_secrets_enabled.yml
@@ -5,7 +5,7 @@ product_section: enablement
product_stage: enablement
product_group: distribution
value_type: boolean
-status: implemented
+status: active
milestone: "14.2"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67802
time_frame: none
diff --git a/config/metrics/settings/20210915152326_service_ping_features_enabled.yml b/config/metrics/settings/20210915152326_service_ping_features_enabled.yml
new file mode 100644
index 00000000000..41101f0ff9d
--- /dev/null
+++ b/config/metrics/settings/20210915152326_service_ping_features_enabled.yml
@@ -0,0 +1,23 @@
+---
+key_path: settings.service_ping_features_enabled
+name: "service_ping_features_enabled"
+description: Whether Service Ping features are enabled
+product_section: growth
+product_stage: growth
+product_group: group::product intelligence
+product_category: collection
+value_type: boolean
+status: active
+milestone: "14.3"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70332
+time_frame: none
+data_source: database
+instrumentation_class: ServicePingFeaturesMetric
+data_category: optional
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/pseudonymizer.yml b/config/pseudonymizer.yml
index 532fbe3b70f..cd8db9d8dc5 100644
--- a/config/pseudonymizer.yml
+++ b/config/pseudonymizer.yml
@@ -385,7 +385,6 @@ tables:
- public_builds
- last_repository_check_failed
- last_repository_check_at
- - container_registry_enabled
- only_allow_merge_if_pipeline_succeeds
- has_external_issue_tracker
- repository_storage
diff --git a/config/routes.rb b/config/routes.rb
index 9fdd2a70417..8f4c3886e88 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -63,11 +63,12 @@ Rails.application.routes.draw do
end
end
- resource :experience_level, only: [:show, :update]
-
Gitlab.ee do
resources :groups, only: [:new, :create]
resources :projects, only: [:new, :create]
+ resources :groups_projects, only: [:new, :create] do
+ post :import, on: :collection
+ end
end
end
@@ -184,7 +185,7 @@ Rails.application.routes.draw do
end
Gitlab.jh do
- draw :province
+ draw :global_jh
end
if ENV['GITLAB_CHAOS_SECRET'] || Rails.env.development? || Rails.env.test?
@@ -221,6 +222,7 @@ Rails.application.routes.draw do
draw :snippets
draw :profile
+ draw :members
# Product analytics collector
match '/collector/i', to: ProductAnalytics::CollectorApp.new, via: :all
diff --git a/config/routes/admin.rb b/config/routes/admin.rb
index d7f73354d4c..e3b365ad276 100644
--- a/config/routes/admin.rb
+++ b/config/routes/admin.rb
@@ -93,6 +93,7 @@ namespace :admin do
member do
post :pause
post :resume
+ post :retry
end
end
diff --git a/config/routes/jira_connect.rb b/config/routes/jira_connect.rb
index 1a21d7a8778..1e871d52c80 100644
--- a/config/routes/jira_connect.rb
+++ b/config/routes/jira_connect.rb
@@ -14,4 +14,10 @@ namespace :jira_connect do
resources :subscriptions, only: [:index, :create, :destroy]
resources :branches, only: [:new]
+
+ resources :installations, only: [:index] do
+ collection do
+ put :update
+ end
+ end
end
diff --git a/config/routes/members.rb b/config/routes/members.rb
new file mode 100644
index 00000000000..e84f0987171
--- /dev/null
+++ b/config/routes/members.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+namespace :members do
+ namespace :mailgun do
+ resources :permanent_failures, only: [:create]
+ end
+end
diff --git a/config/routes/project.rb b/config/routes/project.rb
index 8ba9c100f71..cbd2f5ac839 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -145,6 +145,8 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
resource :packages_and_registries, only: [:show]
end
+ resources :usage_quotas, only: [:index]
+
resources :autocomplete_sources, only: [] do
collection do
get 'members'
@@ -352,6 +354,8 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
get 'details', on: :member
end
+ resources :work_items, only: [:index]
+
resource :tracing, only: [:show]
post 'incidents/integrations/pagerduty', to: 'incident_management/pager_duty_incidents#create'
@@ -599,7 +603,6 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
:vulnerability_feedback, :security, :dependencies, :issues,
:pipelines, :pipeline_schedules, :runners, :snippets)
end
-
# rubocop: disable Cop/PutProjectRoutesUnderScope
resources(:projects,
path: '/',
diff --git a/config/routes/user.rb b/config/routes/user.rb
index 109179f76f1..01de59c3357 100644
--- a/config/routes/user.rb
+++ b/config/routes/user.rb
@@ -21,11 +21,35 @@ if Gitlab::Auth::Ldap::Config.sign_in_enabled?
end
end
-devise_for :users, controllers: { omniauth_callbacks: :omniauth_callbacks,
- registrations: :registrations,
- passwords: :passwords,
- sessions: :sessions,
- confirmations: :confirmations }
+devise_controllers = { omniauth_callbacks: :omniauth_callbacks,
+ registrations: :registrations,
+ passwords: :passwords,
+ sessions: :sessions,
+ confirmations: :confirmations }
+
+if ::Gitlab.ee? && ::Gitlab::Geo.connected? && ::Gitlab::Geo.secondary?
+ devise_for :users, controllers: devise_controllers, path_names: { sign_in: 'auth/geo/sign_in',
+ sign_out: 'auth/geo/sign_out' }
+ # When using Geo, the other type of routes should be present as well, as browsers
+ # cache 302 redirects locally, and events like primary going offline or a failover
+ # can result in browsers requesting the other paths because of it.
+ as :user do
+ get '/users/sign_in', to: 'sessions#new'
+ post '/users/sign_in', to: 'sessions#create'
+ post '/users/sign_out', to: 'sessions#destroy'
+ end
+else
+ devise_for :users, controllers: devise_controllers
+
+ # We avoid drawing Geo routes for FOSS, but keep them in for EE
+ Gitlab.ee do
+ as :user do
+ get '/users/auth/geo/sign_in', to: 'sessions#new'
+ post '/users/auth/geo/sign_in', to: 'sessions#create'
+ post '/users/auth/geo/sign_out', to: 'sessions#destroy'
+ end
+ end
+end
devise_scope :user do
get '/users/almost_there' => 'confirmations#almost_there'
@@ -36,6 +60,8 @@ scope '-/users', module: :users do
post :accept, on: :member
post :decline, on: :member
end
+
+ resources :group_callouts, only: [:create]
end
scope(constraints: { username: Gitlab::PathRegex.root_namespace_route_regex }) do
@@ -64,7 +90,7 @@ constraints(::Constraints::UserUrlConstrainer.new) do
get ':username.keys' => 'users#ssh_keys', constraints: { username: Gitlab::PathRegex.root_namespace_route_regex }
# Get all GPG keys of user
- get ':username.gpg' => 'users#gpg_keys', constraints: { username: Gitlab::PathRegex.root_namespace_route_regex }
+ get ':username.gpg' => 'users#gpg_keys', as: 'user_gpg_keys', constraints: { username: Gitlab::PathRegex.root_namespace_route_regex }
scope(path: ':username',
as: :user,
diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml
index 52ecd62edd5..d7c6e6031aa 100644
--- a/config/sidekiq_queues.yml
+++ b/config/sidekiq_queues.yml
@@ -17,9 +17,8 @@
# 3: high priority
# 5: _super_ high priority, this should only be used for _very_ important queues
#
-# As per http://stackoverflow.com/a/21241357/290102 the formula for calculating
-# the likelihood of a job being popped off a queue (given all queues have work
-# to perform) is:
+# The formula for calculating the likelihood of a job being popped off a queue
+# (given all queues have work to perform) is:
#
# chance = (queue weight / total weight of all queues) * 100
---
@@ -126,6 +125,8 @@
- 2
- - emails_on_push
- 2
+- - environments_auto_stop
+ - 1
- - environments_canary_ingress_update
- 1
- - epics
@@ -248,6 +249,8 @@
- 1
- - namespaces_onboarding_user_added
- 1
+- - namespaces_sync_namespace_name
+ - 1
- - new_epic
- 2
- - new_issue
diff --git a/config/webpack.config.js b/config/webpack.config.js
index b81b5611041..adb11548a88 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -48,6 +48,8 @@ const INCREMENTAL_COMPILER_ENABLED =
IS_DEV_SERVER &&
process.env.DEV_SERVER_INCREMENTAL &&
process.env.DEV_SERVER_INCREMENTAL !== 'false';
+const INCREMENTAL_COMPILER_TTL = Number(process.env.DEV_SERVER_INCREMENTAL_TTL) || Infinity;
+const INCREMENTAL_COMPILER_RECORD_HISTORY = IS_DEV_SERVER && !process.env.CI;
const WEBPACK_REPORT = process.env.WEBPACK_REPORT && process.env.WEBPACK_REPORT !== 'false';
const WEBPACK_MEMORY_TEST =
process.env.WEBPACK_MEMORY_TEST && process.env.WEBPACK_MEMORY_TEST !== 'false';
@@ -69,8 +71,10 @@ let watchAutoEntries = [];
const defaultEntries = ['./main'];
const incrementalCompiler = createIncrementalWebpackCompiler(
+ INCREMENTAL_COMPILER_RECORD_HISTORY,
INCREMENTAL_COMPILER_ENABLED,
path.join(CACHE_PATH, 'incremental-webpack-compiler-history.json'),
+ INCREMENTAL_COMPILER_TTL,
);
function generateEntries() {
@@ -148,15 +152,16 @@ const alias = {
icons: path.join(ROOT_PATH, 'app/views/shared/icons'),
images: path.join(ROOT_PATH, 'app/assets/images'),
vendor: path.join(ROOT_PATH, 'vendor/assets/javascripts'),
- vue$: 'vue/dist/vue.esm.js',
jquery$: 'jquery/dist/jquery.slim.js',
- spec: path.join(ROOT_PATH, 'spec/javascripts'),
jest: path.join(ROOT_PATH, 'spec/frontend'),
shared_queries: path.join(ROOT_PATH, 'app/graphql/queries'),
// the following resolves files which are different between CE and EE
ee_else_ce: path.join(ROOT_PATH, 'app/assets/javascripts'),
+ // the following resolves files which are different between CE and JH
+ jh_else_ce: path.join(ROOT_PATH, 'app/assets/javascripts'),
+
// override loader path for icons.svg so we do not duplicate this asset
'@gitlab/svgs/dist/icons.svg': path.join(
ROOT_PATH,
@@ -171,7 +176,6 @@ if (IS_EE) {
ee_empty_states: path.join(ROOT_PATH, 'ee/app/views/shared/empty_states'),
ee_icons: path.join(ROOT_PATH, 'ee/app/views/shared/icons'),
ee_images: path.join(ROOT_PATH, 'ee/app/assets/images'),
- ee_spec: path.join(ROOT_PATH, 'ee/spec/javascripts'),
ee_jest: path.join(ROOT_PATH, 'ee/spec/frontend'),
ee_else_ce: path.join(ROOT_PATH, 'ee/app/assets/javascripts'),
});
@@ -180,10 +184,12 @@ if (IS_EE) {
if (IS_JH) {
Object.assign(alias, {
jh: path.join(ROOT_PATH, 'jh/app/assets/javascripts'),
+ jh_component: path.join(ROOT_PATH, 'jh/app/assets/javascripts'),
+ jh_empty_states: path.join(ROOT_PATH, 'jh/app/views/shared/empty_states'),
jh_icons: path.join(ROOT_PATH, 'jh/app/views/shared/icons'),
jh_images: path.join(ROOT_PATH, 'jh/app/assets/images'),
- jh_spec: path.join(ROOT_PATH, 'jh/spec/javascripts'),
jh_jest: path.join(ROOT_PATH, 'jh/spec/frontend'),
+ jh_else_ce: path.join(ROOT_PATH, 'jh/app/assets/javascripts'),
});
}
@@ -519,6 +525,15 @@ module.exports = {
);
}),
+ !IS_JH &&
+ new webpack.NormalModuleReplacementPlugin(/^jh_component\/(.*)\.vue/, (resource) => {
+ // eslint-disable-next-line no-param-reassign
+ resource.request = path.join(
+ ROOT_PATH,
+ 'app/assets/javascripts/vue_shared/components/empty_component.js',
+ );
+ }),
+
new CopyWebpackPlugin({
patterns: [
{
@@ -634,10 +649,12 @@ module.exports = {
}),
new webpack.DefinePlugin({
- // This one is used to define window.gon.ee and other things properly in tests:
+ // These are used to define window.gon.ee, window.gon.jh and other things properly in tests:
'process.env.IS_EE': JSON.stringify(IS_EE),
- // This one is used to check against "EE" properly in application code
+ 'process.env.IS_JH': JSON.stringify(IS_JH),
+ // These are used to check against "EE" properly in application code
IS_EE: IS_EE ? 'window.gon && window.gon.ee' : JSON.stringify(false),
+ IS_JH: IS_JH ? 'window.gon && window.gon.jh' : JSON.stringify(false),
// This is used by Sourcegraph because these assets are loaded dnamically
'process.env.SOURCEGRAPH_PUBLIC_PATH': JSON.stringify(SOURCEGRAPH_PUBLIC_PATH),
}),
diff --git a/config/webpack.vendor.config.js b/config/webpack.vendor.config.js
index 6d337c1d82b..84fd993ed14 100644
--- a/config/webpack.vendor.config.js
+++ b/config/webpack.vendor.config.js
@@ -33,8 +33,8 @@ module.exports = {
'echarts',
'lodash',
'vuex',
+ 'vue',
'pikaday',
- 'vue/dist/vue.esm.js',
'@gitlab/at.js',
'jed',
'mermaid',
diff --git a/danger/documentation/Dangerfile b/danger/documentation/Dangerfile
index 9bf425a5815..01ef5dbb49e 100644
--- a/danger/documentation/Dangerfile
+++ b/danger/documentation/Dangerfile
@@ -9,7 +9,7 @@ DOCUMENTATION_UPDATE_MISSING = <<~MSG
For more information, see:
-- The Handbook page on [merge request types](https://about.gitlab.com/handbook/engineering/metrics/#data-classification).
+- The Handbook page on [merge request types](https://about.gitlab.com/handbook/engineering/metrics/#work-type-classification).
- The [definition of done](https://docs.gitlab.com/ee/development/contributing/merge_request_workflow.html#definition-of-done) documentation.
MSG
diff --git a/danger/karma/Dangerfile b/danger/karma/Dangerfile
deleted file mode 100644
index e05bd86313f..00000000000
--- a/danger/karma/Dangerfile
+++ /dev/null
@@ -1,51 +0,0 @@
-# frozen_string_literal: true
-# rubocop:disable Style/SignalException
-
-def get_karma_files(files)
- files.select do |file|
- file.start_with?('ee/spec/javascripts', 'spec/javascripts') &&
- file.end_with?('_spec.js') &&
- !file.end_with?('browser_spec.js')
- end
-end
-
-new_karma_files = get_karma_files(git.added_files.to_a)
-
-unless new_karma_files.empty?
-
- if helper.ci?
- markdown(<<~MARKDOWN)
- ## New karma spec file
-
- New frontend specs ([except `browser_specs`](https://gitlab.com/gitlab-org/gitlab/blob/3b6fe2f1077eedb0b8aff02a7350234f0b7dc4f9/spec/javascripts/lib/utils/browser_spec.js#L2)) should be
- [written in jest](https://docs.gitlab.com/ee/development/testing_guide/frontend_testing.html#jest).
-
- You have created the following tests, please migrate them over to jest:
-
- * #{new_karma_files.map { |path| "`#{path}`" }.join("\n* ")}
- MARKDOWN
- end
-
- fail "You have created a new karma spec file"
-
-end
-
-changed_karma_files = get_karma_files(helper.all_changed_files) - new_karma_files
-
-return if changed_karma_files.empty?
-
-warn 'You have edited karma spec files. Please consider migrating them to jest.'
-
-if helper.ci?
- markdown(<<~MARKDOWN)
- ## Edited karma files
-
- You have edited the following karma spec files. Please consider migrating them to jest:
-
- * #{changed_karma_files.map { |path| "`#{path}`" }.join("\n* ")}
-
- In order to align with our Iteration value, migration can also be done as a follow-up.
-
- For more information: [Jestodus epic](https://gitlab.com/groups/gitlab-org/-/epics/895)
- MARKDOWN
-end
diff --git a/danger/metadata/Dangerfile b/danger/metadata/Dangerfile
index d2e85109d63..27dda687f6a 100644
--- a/danger/metadata/Dangerfile
+++ b/danger/metadata/Dangerfile
@@ -2,6 +2,8 @@
# rubocop:disable Style/SignalException
+DEFAULT_BRANCH = 'master'
+
THROUGHPUT_LABELS = [
'Community contribution',
'security',
@@ -29,12 +31,12 @@ end
has_milestone = !gitlab.mr_json["milestone"].nil?
-unless has_milestone
+unless has_milestone || (helper.security_mr? && gitlab.branch_for_base == DEFAULT_BRANCH)
warn "This merge request does not refer to an existing milestone.", sticky: false
end
has_pick_into_stable_label = gitlab.mr_labels.find { |label| label.start_with?('Pick into') }
-if gitlab.branch_for_base != "master" && !has_pick_into_stable_label && !helper.security_mr?
- warn "Most of the time, merge requests should target `master`. Otherwise, please set the relevant `Pick into X.Y` label."
+if gitlab.branch_for_base != DEFAULT_BRANCH && !has_pick_into_stable_label && !helper.security_mr?
+ warn "Most of the time, merge requests should target `#{DEFAULT_BRANCH}`. Otherwise, please set the relevant `Pick into X.Y` label."
end
diff --git a/data/deprecations/14-3-database-deprecate-legacy-database-conf.yml b/data/deprecations/14-3-database-deprecate-legacy-database-conf.yml
new file mode 100644
index 00000000000..f3f6553729e
--- /dev/null
+++ b/data/deprecations/14-3-database-deprecate-legacy-database-conf.yml
@@ -0,0 +1,13 @@
+- name: "Legacy database configuration"
+ announcement_milestone: "14.3"
+ announcement_date: "2021-09-22"
+ removal_milestone: "15.0"
+ body: |
+ The syntax of [GitLabs database](https://docs.gitlab.com/omnibus/settings/database.html)
+ configuration located in `database.yml` is changing and the legacy format is deprecated. The legacy format
+ supported using a single PostgreSQL adapter, whereas the new format is changing to support multiple databases. The `main:` database needs to be defined as a first configuration item.
+
+ This deprecation mainly impacts users compiling GitLab from source because Omnibus will handle this configuration automatically.
+ stage: Enablement
+ tiers: [Core, Premium, Ultimate]
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338182
diff --git a/data/deprecations/14-3-repository-push-audit-events.yml b/data/deprecations/14-3-repository-push-audit-events.yml
new file mode 100644
index 00000000000..3a39c1f4304
--- /dev/null
+++ b/data/deprecations/14-3-repository-push-audit-events.yml
@@ -0,0 +1,14 @@
+- name: "Audit events for repository push events"
+ announcement_milestone: "14.3" # The milestone when this feature was first announced as deprecated.
+ removal_milestone: "15.0" # the milestone when this feature is planned to be removed
+ body: | # Do not modify this line, instead modify the lines below.
+ Audit events for [repository events](https://docs.gitlab.com/ee/administration/audit_events.html#repository-push) are now deprecated and will be removed in GitLab 15.0.
+
+ These events have always been disabled by default and had to be manually enabled with a
+ feature flag. Enabling them can cause too many events to be generated which can
+ dramatically slow down GitLab instances. For this reason, they are being removed.
+ stage: Manage
+ tiers: Premium
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337993
+ documentation_url: https://docs.gitlab.com/ee/administration/audit_events.html#repository-push
+ announcement_date: "2021-09-02" # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69024
diff --git a/data/deprecations/deprecation_omniauth-kerberos_gem.yml b/data/deprecations/deprecation_omniauth-kerberos_gem.yml
new file mode 100644
index 00000000000..8adbeb19416
--- /dev/null
+++ b/data/deprecations/deprecation_omniauth-kerberos_gem.yml
@@ -0,0 +1,15 @@
+- name: "OmniAuth Kerberos gem"
+ announcement_milestone: "14.3"
+ removal_milestone: "15.0"
+ body: | # Do not modify this line, instead modify the lines below.
+ The `omniauth-kerberos` gem will be removed in our next major release, GitLab 15.0.
+
+ This gem has not been maintained and has very little usage. We therefore plan to remove support for this authentication method and recommend using the Kerberos [SPNEGO](https://en.wikipedia.org/wiki/SPNEGO) integration instead. You can follow the [upgrade instructions](https://docs.gitlab.com/ee/integration/kerberos.html#upgrading-from-password-based-to-ticket-based-kerberos-sign-ins) to upgrade from the `omniauth-kerberos` integration to the supported one.
+
+ Note that we are not deprecating the Kerberos SPNEGO integration, only the old password-based Kerberos integration.
+ stage: Manage
+ tiers: [Premium, Ultimate]
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337384
+ documentation_url: https://docs.gitlab.com/ee/integration/kerberos.html#upgrading-from-password-based-to-ticket-based-kerberos-sign-ins
+ announcement_date: "2021-09-22"
+
diff --git a/data/deprecations/distribution_deprecations_14-3.yml b/data/deprecations/distribution_deprecations_14-3.yml
new file mode 100644
index 00000000000..05263383151
--- /dev/null
+++ b/data/deprecations/distribution_deprecations_14-3.yml
@@ -0,0 +1,8 @@
+- name: "Rename Task Runner pod to Toolbox" # The name of the feature to be deprecated
+ announcement_milestone: "14.2" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-09-22"
+ removal_milestone: "14.4" # the milestone when this feature is planned to be removed
+ body: | # Do not modify this line, instead modify the lines below.
+ The Task Runner pod is used to execute periodic housekeeping tasks within the GitLab application and is often confused with the GitLab Runner. Thus, [Task Runner will be renamed to Toolbox](https://gitlab.com/groups/gitlab-org/charts/-/epics/25).
+
+ This will result in the rename of the sub-chart: `gitlab/task-runner` to `gitlab/toolbox`. Resulting pods will be named along the lines of `{{ .Release.Name }}-toolbox`, which will often be `gitlab-toolbox`. They will be locatable with the label `app=toolbox`.
diff --git a/data/deprecations/serverless.yml b/data/deprecations/serverless.yml
new file mode 100644
index 00000000000..1b99ece154f
--- /dev/null
+++ b/data/deprecations/serverless.yml
@@ -0,0 +1,13 @@
+- name: "GitLab Serverless"
+ announcement_milestone: "14.3"
+ announcement_date: "2021-09-22"
+ removal_milestone: "15.0"
+ body: |
+ [GitLab Serverless](https://docs.gitlab.com/ee/user/project/clusters/serverless/) is a feature set to support Knative-based serverless development with automatic deployments and monitoring.
+
+ We decided to remove the GitLab Serverless features as they never really resonated with our users. Besides, given the continuous development of Kubernetes and Knative, our current implementations do not even work with recent versions.
+ stage: Configure
+ tiers: [Core, Premium, Ultimate]
+ issue_url: "https://gitlab.com/groups/gitlab-org/configure/-/epics/6"
+ documentation_url: "https://docs.gitlab.com/ee/user/project/clusters/serverless/"
+
diff --git a/data/deprecations/templates/_deprecation_template.md.erb b/data/deprecations/templates/_deprecation_template.md.erb
new file mode 100644
index 00000000000..64bd6a75a5e
--- /dev/null
+++ b/data/deprecations/templates/_deprecation_template.md.erb
@@ -0,0 +1,32 @@
+---
+stage: none
+group: none
+info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-development-guidelines"
+---
+
+# Deprecated feature removal schedule
+
+<!--
+This page is automatically generated from the YAML files in `/data/deprecations` by the rake task
+located at `lib/tasks/gitlab/docs/compile_deprecations.rake`.
+
+Do not edit this page directly.
+
+To add a deprecation, use the example.yml file in `/data/deprecations/templates` as a template,
+then run `bin/rake gitlab:docs:compile_deprecations`.
+-->
+<% if milestones.any? -%>
+ <%- milestones.each do |milestone| %>
+## <%= milestone %>
+ <%- deprecations.select{|d| d["removal_milestone"] == milestone}.each do |deprecation| %>
+### <%= deprecation["name"]%>
+
+<%= deprecation["body"] -%>
+
+Announced: <%= deprecation["announcement_date"]%>
+ <%- end -%>
+ <%- end -%>
+<%- else -%>
+
+Deprecated features scheduled for removal will be listed here, sorted by GitLab milestone.
+<% end -%>
diff --git a/data/deprecations/templates/example.yml b/data/deprecations/templates/example.yml
new file mode 100644
index 00000000000..f665dd21530
--- /dev/null
+++ b/data/deprecations/templates/example.yml
@@ -0,0 +1,33 @@
+# This is a template for a feature deprecation
+# A deprecation typically occurs when a feature or capability is planned to be removed in a future release.
+# Deprecations should be announced at least two releases prior to removal. Any breaking changes should only be done in major releases.
+#
+# Below is an example of what a single entry should look like, it's required attributes,
+# and what types we expect those attribute values to be.
+#
+# For more information please refer to the handbook documentation here:
+# {{LINK TBD}}
+#
+# Please delete this line and above before submitting your merge request.
+
+- name: "Feature name" # The name of the feature to be deprecated
+ announcement_milestone: "XX.YY" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "YYYY-MM-DD" # The date of the milestone release when this feature was first announced as deprecated
+ removal_milestone: "XX.YY" # The milestone when this feature is planned to be removed
+ body: | # Do not modify this line, instead modify the lines below.
+ <!-- START OF BODY COMMENT
+
+ This area supports markdown. Delete this entire comment and replace it with your markdown content.
+
+ Make sure to run `bin/rake gitlab:docs:compile_deprecations` locally before committing and pushing your changes.
+
+ When ready, assign to your tech writer to review and merge.
+
+ END OF BODY COMMENT -->
+ stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ removal_date: # (optional - may be required in the future) YYYY-MM-DD format - the date of the milestone release when this feature is planned to be removed
diff --git a/db/fixtures/development/001_create_base_work_item_types.rb b/db/fixtures/development/001_create_base_work_item_types.rb
new file mode 100644
index 00000000000..7a541ca20b0
--- /dev/null
+++ b/db/fixtures/development/001_create_base_work_item_types.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+Gitlab::Seeder.quiet do
+ Gitlab::DatabaseImporters::WorkItems::BaseTypeImporter.import
+end
diff --git a/db/fixtures/development/31_error_tracking.rb b/db/fixtures/development/31_error_tracking.rb
index 60e288696f8..d4d59f4046a 100644
--- a/db/fixtures/development/31_error_tracking.rb
+++ b/db/fixtures/development/31_error_tracking.rb
@@ -33,11 +33,6 @@ Gitlab::Seeder.quiet do
Project.not_mass_generated.visible_to_user(admin_user).sample(1).each do |project|
puts "\nActivating integrated error tracking for the '#{project.full_path}' project"
- unless Feature.enabled?(:integrated_error_tracking, project)
- puts '- enabling feature flag'
- Feature.enable(:integrated_error_tracking, project)
- end
-
puts '- enabling in settings'
project.error_tracking_setting || project.create_error_tracking_setting
project.error_tracking_setting.update!(enabled: true, integrated: true)
diff --git a/db/fixtures/production/003_create_base_work_item_types.rb b/db/fixtures/production/003_create_base_work_item_types.rb
new file mode 100644
index 00000000000..7a541ca20b0
--- /dev/null
+++ b/db/fixtures/production/003_create_base_work_item_types.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+Gitlab::Seeder.quiet do
+ Gitlab::DatabaseImporters::WorkItems::BaseTypeImporter.import
+end
diff --git a/db/migrate/20201029144444_create_vulnerability_finding_links.rb b/db/migrate/20201029144444_create_vulnerability_finding_links.rb
index 80f93b9a0af..225a2de6e19 100644
--- a/db/migrate/20201029144444_create_vulnerability_finding_links.rb
+++ b/db/migrate/20201029144444_create_vulnerability_finding_links.rb
@@ -11,8 +11,8 @@ class CreateVulnerabilityFindingLinks < ActiveRecord::Migration[6.0]
create_table :vulnerability_finding_links, if_not_exists: true do |t|
t.timestamps_with_timezone null: false
t.references :vulnerability_occurrence, index: { name: 'finding_links_on_vulnerability_occurrence_id' }, null: false, foreign_key: { on_delete: :cascade }
- t.text :name, limit: 255
- t.text :url, limit: 2048, null: false
+ t.text :name
+ t.text :url, null: false
end
add_text_limit :vulnerability_finding_links, :name, 255
diff --git a/db/migrate/20210531053916_rename_instance_statistics_measurements.rb b/db/migrate/20210531053916_rename_instance_statistics_measurements.rb
index 9fd459b1275..733ca296952 100644
--- a/db/migrate/20210531053916_rename_instance_statistics_measurements.rb
+++ b/db/migrate/20210531053916_rename_instance_statistics_measurements.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
-class RenameInstanceStatisticsMeasurements < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
+class RenameInstanceStatisticsMeasurements < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
def up
rename_table_safely(:analytics_instance_statistics_measurements, :analytics_usage_trends_measurements)
diff --git a/db/migrate/20210621043337_rename_services_to_integrations.rb b/db/migrate/20210621043337_rename_services_to_integrations.rb
index 17f4b6a2d4d..845c3c01a2a 100644
--- a/db/migrate/20210621043337_rename_services_to_integrations.rb
+++ b/db/migrate/20210621043337_rename_services_to_integrations.rb
@@ -1,9 +1,10 @@
# frozen_string_literal: true
-class RenameServicesToIntegrations < ActiveRecord::Migration[6.1]
- include Gitlab::Database::MigrationHelpers
+class RenameServicesToIntegrations < Gitlab::Database::Migration[1.0]
include Gitlab::Database::SchemaHelpers
+ enable_lock_retries!
+
# Function and trigger names match those migrated in:
# - https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49916
# - https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51852
diff --git a/db/migrate/20210707113056_add_tags_array_to_ci_pending_builds.rb b/db/migrate/20210707113056_add_tags_array_to_ci_pending_builds.rb
new file mode 100644
index 00000000000..229dc01fb87
--- /dev/null
+++ b/db/migrate/20210707113056_add_tags_array_to_ci_pending_builds.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddTagsArrayToCiPendingBuilds < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ def up
+ with_lock_retries do
+ add_column :ci_pending_builds, :tag_ids, :integer, array: true, default: []
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_column :ci_pending_builds, :tag_ids
+ end
+ end
+end
diff --git a/db/migrate/20210707163659_add_vulnerability_events_to_integrations.rb b/db/migrate/20210707163659_add_vulnerability_events_to_integrations.rb
new file mode 100644
index 00000000000..c138af486c1
--- /dev/null
+++ b/db/migrate/20210707163659_add_vulnerability_events_to_integrations.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddVulnerabilityEventsToIntegrations < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ def change
+ add_column :integrations, :vulnerability_events, :boolean, default: false, null: false
+ end
+end
diff --git a/db/migrate/20210708011425_rename_ci_builds_metadata_foreign_key.rb b/db/migrate/20210708011425_rename_ci_builds_metadata_foreign_key.rb
new file mode 100644
index 00000000000..70141f4844e
--- /dev/null
+++ b/db/migrate/20210708011425_rename_ci_builds_metadata_foreign_key.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+class RenameCiBuildsMetadataForeignKey < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ TABLE_NAME = 'ci_builds_metadata'
+ OLD_PREFIX = 'fk_rails_'
+
+ def up
+ with_lock_retries(raise_on_exhaustion: true) do
+ rename_constraint(
+ TABLE_NAME,
+ concurrent_foreign_key_name(TABLE_NAME, :build_id, prefix: 'fk_rails_'),
+ concurrent_foreign_key_name(TABLE_NAME, :build_id)
+ )
+ end
+ end
+
+ def down
+ with_lock_retries(raise_on_exhaustion: true) do
+ rename_constraint(
+ TABLE_NAME,
+ concurrent_foreign_key_name(TABLE_NAME, :build_id),
+ concurrent_foreign_key_name(TABLE_NAME, :build_id, prefix: 'fk_rails_')
+ )
+ end
+ end
+end
diff --git a/db/migrate/20210729081351_create_topics.rb b/db/migrate/20210729081351_create_topics.rb
new file mode 100644
index 00000000000..c6fdc6bb98a
--- /dev/null
+++ b/db/migrate/20210729081351_create_topics.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class CreateTopics < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ def change
+ create_table_with_constraints :topics do |t|
+ t.text :name, null: false
+ t.text_limit :name, 255
+
+ t.index :name, unique: true
+
+ t.timestamps_with_timezone
+ end
+ end
+end
diff --git a/db/migrate/20210729081739_create_project_topics.rb b/db/migrate/20210729081739_create_project_topics.rb
new file mode 100644
index 00000000000..cbb8842f653
--- /dev/null
+++ b/db/migrate/20210729081739_create_project_topics.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class CreateProjectTopics < ActiveRecord::Migration[6.1]
+ def change
+ create_table :project_topics do |t|
+ t.bigint :project_id, null: false
+ t.bigint :topic_id, null: false
+
+ t.index :project_id
+ t.index :topic_id
+ t.index [:project_id, :topic_id], unique: true
+
+ t.timestamps_with_timezone
+ end
+ end
+end
diff --git a/db/migrate/20210729125641_add_foreign_key_to_project_on_project_topic.rb b/db/migrate/20210729125641_add_foreign_key_to_project_on_project_topic.rb
new file mode 100644
index 00000000000..27cf5c60cf0
--- /dev/null
+++ b/db/migrate/20210729125641_add_foreign_key_to_project_on_project_topic.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddForeignKeyToProjectOnProjectTopic < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_foreign_key :project_topics, :projects, column: :project_id, on_delete: :cascade
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key :project_topics, column: :project_id
+ end
+ end
+end
diff --git a/db/migrate/20210729125659_add_foreign_key_to_topic_on_project_topic.rb b/db/migrate/20210729125659_add_foreign_key_to_topic_on_project_topic.rb
new file mode 100644
index 00000000000..1ada08dca1a
--- /dev/null
+++ b/db/migrate/20210729125659_add_foreign_key_to_topic_on_project_topic.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddForeignKeyToTopicOnProjectTopic < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_foreign_key :project_topics, :topics, column: :topic_id, on_delete: :cascade
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key :project_topics, column: :topic_id
+ end
+ end
+end
diff --git a/db/migrate/20210730194555_create_incident_management_pending_issue_escalations.rb b/db/migrate/20210730194555_create_incident_management_pending_issue_escalations.rb
new file mode 100644
index 00000000000..20a6fde96ff
--- /dev/null
+++ b/db/migrate/20210730194555_create_incident_management_pending_issue_escalations.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+class CreateIncidentManagementPendingIssueEscalations < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ def up
+ with_lock_retries do
+ execute(<<~SQL)
+ CREATE TABLE incident_management_pending_issue_escalations (
+ id bigserial NOT NULL,
+ rule_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ process_at timestamp with time zone NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ PRIMARY KEY (id, process_at)
+ ) PARTITION BY RANGE (process_at);
+
+ CREATE INDEX index_incident_management_pending_issue_escalations_on_issue_id
+ ON incident_management_pending_issue_escalations USING btree (issue_id);
+
+ CREATE INDEX index_incident_management_pending_issue_escalations_on_rule_id
+ ON incident_management_pending_issue_escalations USING btree (rule_id);
+ SQL
+ end
+ end
+
+ def down
+ with_lock_retries do
+ drop_table :incident_management_pending_issue_escalations
+ end
+ end
+end
diff --git a/db/migrate/20210807101446_add_cadence_to_dast_profile_schedules.rb b/db/migrate/20210807101446_add_cadence_to_dast_profile_schedules.rb
new file mode 100644
index 00000000000..c9b17e3d5c5
--- /dev/null
+++ b/db/migrate/20210807101446_add_cadence_to_dast_profile_schedules.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddCadenceToDastProfileSchedules < ActiveRecord::Migration[6.1]
+ def change
+ add_column :dast_profile_schedules, :cadence, :jsonb, null: false, default: {}
+ end
+end
diff --git a/db/migrate/20210807101621_add_timezone_to_dast_profile_schedules.rb b/db/migrate/20210807101621_add_timezone_to_dast_profile_schedules.rb
new file mode 100644
index 00000000000..3c3eb507432
--- /dev/null
+++ b/db/migrate/20210807101621_add_timezone_to_dast_profile_schedules.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+class AddTimezoneToDastProfileSchedules < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ # We disable these cops here because adding the column is safe. The table does not
+ # have any data in it as it's behind a feature flag.
+ # rubocop: disable Rails/NotNullColumn
+ def up
+ execute('DELETE FROM dast_profile_schedules')
+
+ unless column_exists?(:dast_profile_schedules, :timezone)
+ add_column :dast_profile_schedules, :timezone, :text, null: false
+ end
+
+ add_text_limit :dast_profile_schedules, :timezone, 255
+ end
+
+ def down
+ return unless column_exists?(:dast_profile_schedules, :timezone)
+
+ remove_column :dast_profile_schedules, :timezone
+ end
+end
diff --git a/db/migrate/20210807102004_add_starts_at_to_dast_profile_schedules.rb b/db/migrate/20210807102004_add_starts_at_to_dast_profile_schedules.rb
new file mode 100644
index 00000000000..4eea5fd7e8c
--- /dev/null
+++ b/db/migrate/20210807102004_add_starts_at_to_dast_profile_schedules.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddStartsAtToDastProfileSchedules < ActiveRecord::Migration[6.1]
+ def change
+ add_column :dast_profile_schedules, :starts_at, :datetime_with_timezone, null: false, default: -> { 'NOW()' }
+ end
+end
diff --git a/db/migrate/20210809014850_create_agent_group_authorizations.rb b/db/migrate/20210809014850_create_agent_group_authorizations.rb
new file mode 100644
index 00000000000..43d7e63e0a2
--- /dev/null
+++ b/db/migrate/20210809014850_create_agent_group_authorizations.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class CreateAgentGroupAuthorizations < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ def change
+ create_table :agent_group_authorizations do |t|
+ t.bigint :group_id, null: false
+ t.bigint :agent_id, null: false
+ t.jsonb :config, null: false
+
+ t.index :group_id
+ t.index [:agent_id, :group_id], unique: true
+ end
+ end
+end
diff --git a/db/migrate/20210809014918_add_agent_group_authorizations_foreign_keys.rb b/db/migrate/20210809014918_add_agent_group_authorizations_foreign_keys.rb
new file mode 100644
index 00000000000..2a3a51d0ca9
--- /dev/null
+++ b/db/migrate/20210809014918_add_agent_group_authorizations_foreign_keys.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class AddAgentGroupAuthorizationsForeignKeys < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_foreign_key :agent_group_authorizations, :namespaces, column: :group_id
+ add_concurrent_foreign_key :agent_group_authorizations, :cluster_agents, column: :agent_id
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key_if_exists :agent_group_authorizations, column: :group_id
+ end
+
+ with_lock_retries do
+ remove_foreign_key_if_exists :agent_group_authorizations, column: :agent_id
+ end
+ end
+end
diff --git a/db/migrate/20210811120204_create_customer_relations_contacts.rb b/db/migrate/20210811120204_create_customer_relations_contacts.rb
new file mode 100644
index 00000000000..0c26ee0ef59
--- /dev/null
+++ b/db/migrate/20210811120204_create_customer_relations_contacts.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+class CreateCustomerRelationsContacts < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ def up
+ create_table_with_constraints :customer_relations_contacts do |t|
+ t.bigint :group_id, null: false
+ t.references :organization, index: true, null: true, foreign_key: { to_table: :customer_relations_organizations, on_delete: :cascade }
+ t.timestamps_with_timezone null: false
+ t.integer :state, limit: 1, default: 1, null: false
+ t.text :phone
+ t.text :first_name, null: false
+ t.text :last_name, null: false
+ t.text :email
+ t.text :description
+
+ t.text_limit :phone, 32
+ t.text_limit :first_name, 255
+ t.text_limit :last_name, 255
+ t.text_limit :email, 255
+ t.text_limit :description, 1024
+ end
+ end
+
+ def down
+ with_lock_retries do
+ drop_table :customer_relations_contacts
+ end
+ end
+end
diff --git a/db/migrate/20210813131313_create_foreign_key_on_contacts_group_id.rb b/db/migrate/20210813131313_create_foreign_key_on_contacts_group_id.rb
new file mode 100644
index 00000000000..58b2471a96a
--- /dev/null
+++ b/db/migrate/20210813131313_create_foreign_key_on_contacts_group_id.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class CreateForeignKeyOnContactsGroupId < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_customer_relations_contacts_on_group_id'
+
+ def up
+ add_concurrent_index :customer_relations_contacts, :group_id, name: INDEX_NAME
+ add_concurrent_foreign_key :customer_relations_contacts, :namespaces, column: :group_id
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key_if_exists :customer_relations_contacts, column: :group_id
+ end
+
+ remove_concurrent_index_by_name :customer_relations_contacts, INDEX_NAME
+ end
+end
diff --git a/db/migrate/20210816095826_add_unique_index_on_dast_profile_to_dast_profile_schedules.rb b/db/migrate/20210816095826_add_unique_index_on_dast_profile_to_dast_profile_schedules.rb
new file mode 100644
index 00000000000..b7ea8545df1
--- /dev/null
+++ b/db/migrate/20210816095826_add_unique_index_on_dast_profile_to_dast_profile_schedules.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+# See https://docs.gitlab.com/ee/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class AddUniqueIndexOnDastProfileToDastProfileSchedules < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ INDEX_NAME = 'index_dast_profile_schedules_on_dast_profile_id'
+ TABLE = :dast_profile_schedules
+ # We disable these cops here because changing this index is safe. The table does not
+ # have any data in it as it's behind a feature flag.
+ # rubocop: disable Migration/AddIndex
+ # rubocop: disable Migration/RemoveIndex
+ def up
+ execute('DELETE FROM dast_profile_schedules')
+
+ if index_exists_by_name?(TABLE, INDEX_NAME)
+ remove_index TABLE, :dast_profile_id, name: INDEX_NAME
+ end
+
+ unless index_exists_by_name?(TABLE, INDEX_NAME)
+ add_index TABLE, :dast_profile_id, unique: true, name: INDEX_NAME
+ end
+ end
+
+ def down
+ execute('DELETE FROM dast_profile_schedules')
+
+ if index_exists_by_name?(TABLE, INDEX_NAME)
+ remove_index TABLE, :dast_profile_id, name: INDEX_NAME
+ end
+
+ unless index_exists_by_name?(TABLE, INDEX_NAME)
+ add_index TABLE, :dast_profile_id
+ end
+ end
+end
diff --git a/db/migrate/20210816192041_add_invites_email_success_to_member.rb b/db/migrate/20210816192041_add_invites_email_success_to_member.rb
new file mode 100644
index 00000000000..89f475b056c
--- /dev/null
+++ b/db/migrate/20210816192041_add_invites_email_success_to_member.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddInvitesEmailSuccessToMember < ActiveRecord::Migration[6.1]
+ def up
+ unless column_exists?(:members, :invite_email_success)
+ add_column :members, :invite_email_success, :boolean, null: false, default: true
+ end
+ end
+
+ def down
+ remove_column :members, :invite_email_success
+ end
+end
diff --git a/db/migrate/20210817130415_add_project_id_name_version_id_to_npm_packages.rb b/db/migrate/20210817130415_add_project_id_name_version_id_to_npm_packages.rb
new file mode 100644
index 00000000000..e4b681d66fb
--- /dev/null
+++ b/db/migrate/20210817130415_add_project_id_name_version_id_to_npm_packages.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddProjectIdNameVersionIdToNpmPackages < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'idx_installable_npm_pkgs_on_project_id_name_version_id'
+
+ def up
+ add_concurrent_index :packages_packages, [:project_id, :name, :version, :id], where: 'package_type = 2 AND status = 0', name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index :packages_packages, [:project_id, :name, :version, :id], where: 'package_type = 2 AND status = 0', name: INDEX_NAME
+ end
+end
diff --git a/db/migrate/20210817172214_add_yaml_limits_application_setting.rb b/db/migrate/20210817172214_add_yaml_limits_application_setting.rb
new file mode 100644
index 00000000000..f502ef9825b
--- /dev/null
+++ b/db/migrate/20210817172214_add_yaml_limits_application_setting.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+class AddYamlLimitsApplicationSetting < ActiveRecord::Migration[6.1]
+ DOWNTIME = false
+
+ def change
+ add_column :application_settings, :max_yaml_size_bytes, :bigint, default: 1.megabyte, null: false
+ add_column :application_settings, :max_yaml_depth, :integer, default: 100, null: false
+ end
+end
diff --git a/db/migrate/20210818061156_remove_project_profile_compound_index_from_dast_profile_schedules.rb b/db/migrate/20210818061156_remove_project_profile_compound_index_from_dast_profile_schedules.rb
new file mode 100644
index 00000000000..b50947a0a99
--- /dev/null
+++ b/db/migrate/20210818061156_remove_project_profile_compound_index_from_dast_profile_schedules.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+# See https://docs.gitlab.com/ee/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class RemoveProjectProfileCompoundIndexFromDastProfileSchedules < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ TABLE = :dast_profile_schedules
+ INDEX_NAME = 'index_dast_profile_schedules_on_project_id_and_dast_profile_id'
+ # We disable these cops here because changing this index is safe. The table does not
+ # have any data in it as it's behind a feature flag.
+ # rubocop: disable Migration/AddIndex
+ # rubocop: disable Migration/RemoveIndex
+ def up
+ execute('DELETE FROM dast_profile_schedules')
+
+ if index_exists_by_name?(TABLE, INDEX_NAME)
+ remove_index TABLE, %i[project_id dast_profile_id], name: INDEX_NAME
+ end
+ end
+
+ def down
+ execute('DELETE FROM dast_profile_schedules')
+
+ unless index_exists_by_name?(TABLE, INDEX_NAME)
+ add_index TABLE, %i[project_id dast_profile_id], unique: true, name: INDEX_NAME
+ end
+ end
+end
diff --git a/db/migrate/20210818115613_add_index_project_id_on_dast_profile_schedule.rb b/db/migrate/20210818115613_add_index_project_id_on_dast_profile_schedule.rb
new file mode 100644
index 00000000000..392b335ab45
--- /dev/null
+++ b/db/migrate/20210818115613_add_index_project_id_on_dast_profile_schedule.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+# See https://docs.gitlab.com/ee/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class AddIndexProjectIdOnDastProfileSchedule < ActiveRecord::Migration[6.1]
+ # We disable these cops here because changing this index is safe. The table does not
+ # have any data in it as it's behind a feature flag.
+ # rubocop: disable Migration/AddIndex
+ def change
+ add_index :dast_profile_schedules, :project_id
+ end
+end
diff --git a/db/migrate/20210818175949_update_integrations_trigger_type_new_on_insert.rb b/db/migrate/20210818175949_update_integrations_trigger_type_new_on_insert.rb
new file mode 100644
index 00000000000..2999a6fd4f6
--- /dev/null
+++ b/db/migrate/20210818175949_update_integrations_trigger_type_new_on_insert.rb
@@ -0,0 +1,79 @@
+# frozen_string_literal: true
+
+class UpdateIntegrationsTriggerTypeNewOnInsert < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::SchemaHelpers
+
+ FUNCTION_NAME = 'integrations_set_type_new'
+
+ def up
+ # Update `type_new` dynamically based on `type`.
+ #
+ # The old class names are in the format `AbcService`, and the new ones `Integrations::Abc`.
+ create_trigger_function(FUNCTION_NAME, replace: true) do
+ <<~SQL
+ UPDATE integrations SET type_new = regexp_replace(NEW.type, '\\A(.+)Service\\Z', 'Integrations::\\1')
+ WHERE integrations.id = NEW.id;
+ RETURN NULL;
+ SQL
+ end
+ end
+
+ def down
+ # We initially went with this static mapping since we assumed that new integrations could
+ # just use the correct class name directly in `type`, but this will complicate the data migration
+ # since we plan to drop `type` at some point and replace it with `type_new`, so we still need
+ # to keep this column filled for all records.
+ create_trigger_function(FUNCTION_NAME, replace: true) do
+ <<~SQL
+ WITH mapping(old_type, new_type) AS (VALUES
+ ('AsanaService', 'Integrations::Asana'),
+ ('AssemblaService', 'Integrations::Assembla'),
+ ('BambooService', 'Integrations::Bamboo'),
+ ('BugzillaService', 'Integrations::Bugzilla'),
+ ('BuildkiteService', 'Integrations::Buildkite'),
+ ('CampfireService', 'Integrations::Campfire'),
+ ('ConfluenceService', 'Integrations::Confluence'),
+ ('CustomIssueTrackerService', 'Integrations::CustomIssueTracker'),
+ ('DatadogService', 'Integrations::Datadog'),
+ ('DiscordService', 'Integrations::Discord'),
+ ('DroneCiService', 'Integrations::DroneCi'),
+ ('EmailsOnPushService', 'Integrations::EmailsOnPush'),
+ ('EwmService', 'Integrations::Ewm'),
+ ('ExternalWikiService', 'Integrations::ExternalWiki'),
+ ('FlowdockService', 'Integrations::Flowdock'),
+ ('HangoutsChatService', 'Integrations::HangoutsChat'),
+ ('IrkerService', 'Integrations::Irker'),
+ ('JenkinsService', 'Integrations::Jenkins'),
+ ('JiraService', 'Integrations::Jira'),
+ ('MattermostService', 'Integrations::Mattermost'),
+ ('MattermostSlashCommandsService', 'Integrations::MattermostSlashCommands'),
+ ('MicrosoftTeamsService', 'Integrations::MicrosoftTeams'),
+ ('MockCiService', 'Integrations::MockCi'),
+ ('MockMonitoringService', 'Integrations::MockMonitoring'),
+ ('PackagistService', 'Integrations::Packagist'),
+ ('PipelinesEmailService', 'Integrations::PipelinesEmail'),
+ ('PivotaltrackerService', 'Integrations::Pivotaltracker'),
+ ('PrometheusService', 'Integrations::Prometheus'),
+ ('PushoverService', 'Integrations::Pushover'),
+ ('RedmineService', 'Integrations::Redmine'),
+ ('SlackService', 'Integrations::Slack'),
+ ('SlackSlashCommandsService', 'Integrations::SlackSlashCommands'),
+ ('TeamcityService', 'Integrations::Teamcity'),
+ ('UnifyCircuitService', 'Integrations::UnifyCircuit'),
+ ('YoutrackService', 'Integrations::Youtrack'),
+ ('WebexTeamsService', 'Integrations::WebexTeams'),
+
+ -- EE-only integrations
+ ('GithubService', 'Integrations::Github'),
+ ('GitlabSlackApplicationService', 'Integrations::GitlabSlackApplication')
+ )
+
+ UPDATE integrations SET type_new = mapping.new_type
+ FROM mapping
+ WHERE integrations.id = NEW.id
+ AND mapping.old_type = NEW.type;
+ RETURN NULL;
+ SQL
+ end
+ end
+end
diff --git a/db/migrate/20210818185548_add_tag_ids_index_to_ci_pending_build.rb b/db/migrate/20210818185548_add_tag_ids_index_to_ci_pending_build.rb
new file mode 100644
index 00000000000..b8e00ed9db0
--- /dev/null
+++ b/db/migrate/20210818185548_add_tag_ids_index_to_ci_pending_build.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddTagIdsIndexToCiPendingBuild < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_ci_pending_builds_on_tag_ids'
+
+ def up
+ add_concurrent_index(:ci_pending_builds, :tag_ids, name: INDEX_NAME, where: 'cardinality(tag_ids) > 0')
+ end
+
+ def down
+ remove_concurrent_index_by_name(:ci_pending_builds, name: INDEX_NAME)
+ end
+end
diff --git a/db/migrate/20210818193008_add_file_template_project_to_service_desk_settings.rb b/db/migrate/20210818193008_add_file_template_project_to_service_desk_settings.rb
new file mode 100644
index 00000000000..4cfd54ac348
--- /dev/null
+++ b/db/migrate/20210818193008_add_file_template_project_to_service_desk_settings.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddFileTemplateProjectToServiceDeskSettings < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ def change
+ add_column :service_desk_settings, :file_template_project_id, :bigint, null: true
+ end
+end
diff --git a/db/migrate/20210818200455_add_file_template_project_foreign_key_to_service_desk_settings.rb b/db/migrate/20210818200455_add_file_template_project_foreign_key_to_service_desk_settings.rb
new file mode 100644
index 00000000000..cc8aeecd2b5
--- /dev/null
+++ b/db/migrate/20210818200455_add_file_template_project_foreign_key_to_service_desk_settings.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class AddFileTemplateProjectForeignKeyToServiceDeskSettings < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_service_desk_settings_on_file_template_project_id'
+
+ def up
+ add_concurrent_index :service_desk_settings, :file_template_project_id, name: INDEX_NAME
+ add_concurrent_foreign_key :service_desk_settings, :projects, column: :file_template_project_id, on_delete: :nullify
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key_if_exists :service_desk_settings, column: :file_template_project_id
+ end
+
+ remove_concurrent_index_by_name :service_desk_settings, name: INDEX_NAME
+ end
+end
diff --git a/db/migrate/20210818220234_add_default_project_approval_rules_vuln_allowed.rb b/db/migrate/20210818220234_add_default_project_approval_rules_vuln_allowed.rb
new file mode 100644
index 00000000000..72d2755effa
--- /dev/null
+++ b/db/migrate/20210818220234_add_default_project_approval_rules_vuln_allowed.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+class AddDefaultProjectApprovalRulesVulnAllowed < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ DEFAULT_VALUE = 0
+
+ def up
+ change_column_default :approval_project_rules, :vulnerabilities_allowed, DEFAULT_VALUE
+
+ update_column_in_batches(:approval_project_rules, :vulnerabilities_allowed, DEFAULT_VALUE) do |table, query|
+ query.where(table[:vulnerabilities_allowed].eq(nil))
+ end
+
+ change_column_null :approval_project_rules, :vulnerabilities_allowed, false
+ end
+
+ def down
+ change_column_default :approval_project_rules, :vulnerabilities_allowed, nil
+ change_column_null :approval_project_rules, :vulnerabilities_allowed, true
+ end
+end
diff --git a/db/migrate/20210819120243_add_throttle_files_api_columns.rb b/db/migrate/20210819120243_add_throttle_files_api_columns.rb
new file mode 100644
index 00000000000..ace093c7b0c
--- /dev/null
+++ b/db/migrate/20210819120243_add_throttle_files_api_columns.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddThrottleFilesApiColumns < ActiveRecord::Migration[6.1]
+ def change
+ add_column :application_settings, :throttle_unauthenticated_files_api_requests_per_period, :integer, default: 125, null: false
+ add_column :application_settings, :throttle_unauthenticated_files_api_period_in_seconds, :integer, default: 15, null: false
+ add_column :application_settings, :throttle_authenticated_files_api_requests_per_period, :integer, default: 500, null: false
+ add_column :application_settings, :throttle_authenticated_files_api_period_in_seconds, :integer, default: 15, null: false
+
+ add_column :application_settings, :throttle_unauthenticated_files_api_enabled, :boolean, default: false, null: false
+ add_column :application_settings, :throttle_authenticated_files_api_enabled, :boolean, default: false, null: false
+ end
+end
diff --git a/db/migrate/20210819152723_remove_tmp_index_approval_project_rules_scanners.rb b/db/migrate/20210819152723_remove_tmp_index_approval_project_rules_scanners.rb
new file mode 100644
index 00000000000..a60141991a6
--- /dev/null
+++ b/db/migrate/20210819152723_remove_tmp_index_approval_project_rules_scanners.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveTmpIndexApprovalProjectRulesScanners < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'tmp_index_approval_project_rules_scanners'
+
+ def up
+ remove_concurrent_index_by_name :approval_project_rules, INDEX_NAME
+ end
+
+ def down
+ add_concurrent_index :approval_project_rules, :scanners, name: INDEX_NAME, using: :gin, where: "scanners @> '{cluster_image_scanning}'"
+ end
+end
diff --git a/db/migrate/20210819153805_set_default_job_token_scope_true.rb b/db/migrate/20210819153805_set_default_job_token_scope_true.rb
new file mode 100644
index 00000000000..4536f664950
--- /dev/null
+++ b/db/migrate/20210819153805_set_default_job_token_scope_true.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class SetDefaultJobTokenScopeTrue < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ def up
+ with_lock_retries do
+ change_column_default :project_ci_cd_settings, :job_token_scope_enabled, from: false, to: true
+ end
+ end
+
+ def down
+ with_lock_retries do
+ change_column_default :project_ci_cd_settings, :job_token_scope_enabled, from: true, to: false
+ end
+ end
+end
diff --git a/db/migrate/20210819162047_add_columns_to_namespace_settings.rb b/db/migrate/20210819162047_add_columns_to_namespace_settings.rb
new file mode 100644
index 00000000000..f617990582a
--- /dev/null
+++ b/db/migrate/20210819162047_add_columns_to_namespace_settings.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+class AddColumnsToNamespaceSettings < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ add_column :namespace_settings, :setup_for_company, :boolean
+ add_column :namespace_settings, :jobs_to_be_done, :smallint
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_column :namespace_settings, :setup_for_company
+ remove_column :namespace_settings, :jobs_to_be_done
+ end
+ end
+end
diff --git a/db/migrate/20210820171834_add_foreign_keys_for_pending_issue_escalations.rb b/db/migrate/20210820171834_add_foreign_keys_for_pending_issue_escalations.rb
new file mode 100644
index 00000000000..9d5322de498
--- /dev/null
+++ b/db/migrate/20210820171834_add_foreign_keys_for_pending_issue_escalations.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class AddForeignKeysForPendingIssueEscalations < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::PartitioningMigrationHelpers
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_partitioned_foreign_key :incident_management_pending_issue_escalations,
+ :incident_management_escalation_rules,
+ column: :rule_id
+
+ add_concurrent_partitioned_foreign_key :incident_management_pending_issue_escalations,
+ :issues,
+ column: :issue_id
+ end
+
+ def down
+ remove_foreign_key_if_exists :incident_management_pending_issue_escalations, :incident_management_escalation_rules, column: :rule_id
+ remove_foreign_key_if_exists :incident_management_pending_issue_escalations, :issues, column: :issue_id
+ end
+end
diff --git a/db/migrate/20210823172643_create_user_group_callout.rb b/db/migrate/20210823172643_create_user_group_callout.rb
new file mode 100644
index 00000000000..72341c0b275
--- /dev/null
+++ b/db/migrate/20210823172643_create_user_group_callout.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class CreateUserGroupCallout < ActiveRecord::Migration[6.1]
+ def up
+ create_table :user_group_callouts do |t|
+ t.bigint :user_id, null: false
+ t.bigint :group_id, null: false
+ t.integer :feature_name, limit: 2, null: false
+ t.datetime_with_timezone :dismissed_at
+
+ t.index :group_id
+ t.index [:user_id, :feature_name, :group_id], unique: true, name: 'index_group_user_callouts_feature'
+ end
+ end
+
+ def down
+ drop_table :user_group_callouts
+ end
+end
diff --git a/db/migrate/20210823213417_create_dependency_proxy_image_ttl_group_policies.rb b/db/migrate/20210823213417_create_dependency_proxy_image_ttl_group_policies.rb
new file mode 100644
index 00000000000..3bbd9c1259e
--- /dev/null
+++ b/db/migrate/20210823213417_create_dependency_proxy_image_ttl_group_policies.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class CreateDependencyProxyImageTtlGroupPolicies < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ def up
+ with_lock_retries do
+ create_table :dependency_proxy_image_ttl_group_policies, id: false do |t|
+ t.timestamps_with_timezone null: false
+ t.references :group, primary_key: true, default: nil, index: false, foreign_key: { to_table: :namespaces, on_delete: :cascade }
+ t.integer :ttl, default: 90
+ t.boolean :enabled, null: false, default: false
+ end
+ end
+ end
+
+ def down
+ with_lock_retries do
+ drop_table :dependency_proxy_image_ttl_group_policies
+ end
+ end
+end
diff --git a/db/migrate/20210824055322_add_project_namespace_id_to_project.rb b/db/migrate/20210824055322_add_project_namespace_id_to_project.rb
new file mode 100644
index 00000000000..9397ad4aab2
--- /dev/null
+++ b/db/migrate/20210824055322_add_project_namespace_id_to_project.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+class AddProjectNamespaceIdToProject < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ # This is being added to Projects as a replacement for Namespace
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/337099
+ add_column :projects, :project_namespace_id, :bigint # rubocop: disable Migration/AddColumnsToWideTables
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_column :projects, :project_namespace_id
+ end
+ end
+end
diff --git a/db/migrate/20210824105038_add_timestamp_columns_to_ci_build_trace_metadata.rb b/db/migrate/20210824105038_add_timestamp_columns_to_ci_build_trace_metadata.rb
new file mode 100644
index 00000000000..5c2391f68ed
--- /dev/null
+++ b/db/migrate/20210824105038_add_timestamp_columns_to_ci_build_trace_metadata.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+class AddTimestampColumnsToCiBuildTraceMetadata < Gitlab::Database::Migration[1.0]
+ def change
+ add_column :ci_build_trace_metadata, :last_archival_attempt_at, :datetime_with_timezone
+ add_column :ci_build_trace_metadata, :archived_at, :datetime_with_timezone
+ end
+end
diff --git a/db/migrate/20210824160459_add_notification_level_to_ci_namespace_monthly_usages.rb b/db/migrate/20210824160459_add_notification_level_to_ci_namespace_monthly_usages.rb
new file mode 100644
index 00000000000..15b580af737
--- /dev/null
+++ b/db/migrate/20210824160459_add_notification_level_to_ci_namespace_monthly_usages.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddNotificationLevelToCiNamespaceMonthlyUsages < Gitlab::Database::Migration[1.0]
+ def change
+ add_column :ci_namespace_monthly_usages, :notification_level, :integer, limit: 2, default: 100, null: false
+ end
+end
diff --git a/db/migrate/20210825104558_change_description_limit_error_tracking_event.rb b/db/migrate/20210825104558_change_description_limit_error_tracking_event.rb
new file mode 100644
index 00000000000..4663cc513da
--- /dev/null
+++ b/db/migrate/20210825104558_change_description_limit_error_tracking_event.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class ChangeDescriptionLimitErrorTrackingEvent < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ def up
+ remove_text_limit :error_tracking_error_events, :description
+ add_text_limit :error_tracking_error_events, :description, 1024
+ end
+
+ def down
+ remove_text_limit :error_tracking_error_events, :description
+ add_text_limit :error_tracking_error_events, :description, 255
+ end
+end
diff --git a/db/migrate/20210825104656_create_analytics_cycle_analytics_merge_request_stage_events.rb b/db/migrate/20210825104656_create_analytics_cycle_analytics_merge_request_stage_events.rb
new file mode 100644
index 00000000000..2e89dfeacbf
--- /dev/null
+++ b/db/migrate/20210825104656_create_analytics_cycle_analytics_merge_request_stage_events.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+class CreateAnalyticsCycleAnalyticsMergeRequestStageEvents < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::PartitioningMigrationHelpers::TableManagementHelpers
+ include Gitlab::Database::MigrationHelpers
+
+ def up
+ execute <<~SQL
+ CREATE TABLE analytics_cycle_analytics_merge_request_stage_events (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone,
+ PRIMARY KEY (stage_event_hash_id, merge_request_id)
+ ) PARTITION BY HASH (stage_event_hash_id)
+ SQL
+
+ create_hash_partitions :analytics_cycle_analytics_merge_request_stage_events, 32
+ end
+
+ def down
+ drop_table :analytics_cycle_analytics_merge_request_stage_events
+ end
+end
diff --git a/db/migrate/20210825110016_create_analytics_cycle_analytics_issue_stage_events.rb b/db/migrate/20210825110016_create_analytics_cycle_analytics_issue_stage_events.rb
new file mode 100644
index 00000000000..acc1d96bd23
--- /dev/null
+++ b/db/migrate/20210825110016_create_analytics_cycle_analytics_issue_stage_events.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+class CreateAnalyticsCycleAnalyticsIssueStageEvents < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::PartitioningMigrationHelpers::TableManagementHelpers
+ include Gitlab::Database::MigrationHelpers
+
+ def up
+ execute <<~SQL
+ CREATE TABLE analytics_cycle_analytics_issue_stage_events (
+ stage_event_hash_id integer NOT NULL,
+ issue_id integer NOT NULL,
+ group_id integer NOT NULL,
+ project_id integer NOT NULL,
+ milestone_id integer,
+ author_id integer,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone,
+ PRIMARY KEY (stage_event_hash_id, issue_id)
+ ) PARTITION BY HASH (stage_event_hash_id)
+ SQL
+
+ create_hash_partitions :analytics_cycle_analytics_issue_stage_events, 32
+ end
+
+ def down
+ drop_table :analytics_cycle_analytics_issue_stage_events
+ end
+end
diff --git a/db/migrate/20210825190458_add_user_deactivation_email_option_to_application_settings.rb b/db/migrate/20210825190458_add_user_deactivation_email_option_to_application_settings.rb
new file mode 100644
index 00000000000..dc3270dc5a7
--- /dev/null
+++ b/db/migrate/20210825190458_add_user_deactivation_email_option_to_application_settings.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+# See https://docs.gitlab.com/ee/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class AddUserDeactivationEmailOptionToApplicationSettings < ActiveRecord::Migration[6.1]
+ def change
+ add_column :application_settings, :user_deactivation_emails_enabled, :boolean, default: true, null: false
+ end
+end
diff --git a/db/migrate/20210825193448_add_iteration_cadence_id_to_issue_boards.rb b/db/migrate/20210825193448_add_iteration_cadence_id_to_issue_boards.rb
new file mode 100644
index 00000000000..cbe7d08894e
--- /dev/null
+++ b/db/migrate/20210825193448_add_iteration_cadence_id_to_issue_boards.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddIterationCadenceIdToIssueBoards < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
+
+ def change
+ add_column :boards, :iteration_cadence_id, :bigint
+ end
+end
diff --git a/db/migrate/20210826120834_add_locked_to_ci_job_artifacts.rb b/db/migrate/20210826120834_add_locked_to_ci_job_artifacts.rb
new file mode 100644
index 00000000000..2149265b4e7
--- /dev/null
+++ b/db/migrate/20210826120834_add_locked_to_ci_job_artifacts.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class AddLockedToCiJobArtifacts < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ TABLE_NAME = 'ci_job_artifacts'
+ COLUMN_NAME = 'locked'
+
+ def up
+ with_lock_retries do
+ add_column TABLE_NAME, COLUMN_NAME, :smallint, default: 2
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_column TABLE_NAME, COLUMN_NAME
+ end
+ end
+end
diff --git a/db/migrate/20210826122748_create_loose_foreign_keys_deleted_records.rb b/db/migrate/20210826122748_create_loose_foreign_keys_deleted_records.rb
new file mode 100644
index 00000000000..5abea4393b4
--- /dev/null
+++ b/db/migrate/20210826122748_create_loose_foreign_keys_deleted_records.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+class CreateLooseForeignKeysDeletedRecords < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::PartitioningMigrationHelpers::TableManagementHelpers
+
+ def up
+ constraint_name = check_constraint_name('loose_foreign_keys_deleted_records', 'deleted_table_name', 'max_length')
+ execute(<<~SQL)
+ CREATE TABLE loose_foreign_keys_deleted_records (
+ created_at timestamp with time zone NOT NULL DEFAULT NOW(),
+ deleted_table_name text NOT NULL,
+ deleted_table_primary_key_value bigint NOT NULL,
+ PRIMARY KEY (created_at, deleted_table_name, deleted_table_primary_key_value),
+ CONSTRAINT #{constraint_name} CHECK ((char_length(deleted_table_name) <= 63))
+ ) PARTITION BY RANGE (created_at);
+ SQL
+
+ min_date = Date.today - 1.month
+ max_date = Date.today + 3.months
+ create_daterange_partitions('loose_foreign_keys_deleted_records', 'created_at', min_date, max_date)
+ end
+
+ def down
+ drop_table :loose_foreign_keys_deleted_records
+ end
+end
diff --git a/db/migrate/20210826124311_add_index_to_error_tracking_error.rb b/db/migrate/20210826124311_add_index_to_error_tracking_error.rb
new file mode 100644
index 00000000000..5973331e487
--- /dev/null
+++ b/db/migrate/20210826124311_add_index_to_error_tracking_error.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class AddIndexToErrorTrackingError < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :error_tracking_errors, [:project_id, :status, :last_seen_at], name: 'index_et_errors_on_project_id_and_status_and_last_seen_at'
+ add_concurrent_index :error_tracking_errors, [:project_id, :status, :first_seen_at], name: 'index_et_errors_on_project_id_and_status_and_first_seen_at'
+ add_concurrent_index :error_tracking_errors, [:project_id, :status, :events_count], name: 'index_et_errors_on_project_id_and_status_and_events_count'
+ add_concurrent_index :error_tracking_errors, [:project_id, :status, :id], name: 'index_et_errors_on_project_id_and_status_and_id'
+ end
+
+ def down
+ remove_concurrent_index :error_tracking_errors, [:project_id, :status, :last_seen_at], name: 'index_et_errors_on_project_id_and_status_and_last_seen_at'
+ remove_concurrent_index :error_tracking_errors, [:project_id, :status, :first_seen_at], name: 'index_et_errors_on_project_id_and_status_and_first_seen_at'
+ remove_concurrent_index :error_tracking_errors, [:project_id, :status, :events_count], name: 'index_et_errors_on_project_id_and_status_and_events_count'
+ remove_concurrent_index :error_tracking_errors, [:project_id, :status, :id], name: 'index_et_errors_on_project_id_and_status_and_id'
+ end
+end
diff --git a/db/migrate/20210826145509_add_function_for_inserting_deleted_records.rb b/db/migrate/20210826145509_add_function_for_inserting_deleted_records.rb
new file mode 100644
index 00000000000..ef688cdfd8c
--- /dev/null
+++ b/db/migrate/20210826145509_add_function_for_inserting_deleted_records.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class AddFunctionForInsertingDeletedRecords < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+ include Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers
+
+ def up
+ execute(<<~SQL)
+ CREATE FUNCTION #{DELETED_RECORDS_INSERT_FUNCTION_NAME}()
+ RETURNS TRIGGER AS
+ $$
+ BEGIN
+ INSERT INTO loose_foreign_keys_deleted_records
+ (deleted_table_name, deleted_table_primary_key_value)
+ SELECT TG_TABLE_NAME, old_table.id FROM old_table
+ ON CONFLICT DO NOTHING;
+
+ RETURN NULL;
+ END
+ $$ LANGUAGE PLPGSQL
+ SQL
+ end
+
+ def down
+ drop_function(DELETED_RECORDS_INSERT_FUNCTION_NAME)
+ end
+end
diff --git a/db/migrate/20210826170902_add_throttle_unauthenticated_api_columns.rb b/db/migrate/20210826170902_add_throttle_unauthenticated_api_columns.rb
new file mode 100644
index 00000000000..675da2ea41c
--- /dev/null
+++ b/db/migrate/20210826170902_add_throttle_unauthenticated_api_columns.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+class AddThrottleUnauthenticatedApiColumns < ActiveRecord::Migration[6.1]
+ def change
+ # The defaults match those from the current `throttle_unauthenticated_*` columns
+ add_column :application_settings, :throttle_unauthenticated_api_enabled, :boolean, default: false, null: false
+ add_column :application_settings, :throttle_unauthenticated_api_requests_per_period, :integer, default: 3600, null: false
+ add_column :application_settings, :throttle_unauthenticated_api_period_in_seconds, :integer, default: 3600, null: false
+ end
+end
diff --git a/db/migrate/20210830085837_add_throttle_authenticated_git_lfs_columns.rb b/db/migrate/20210830085837_add_throttle_authenticated_git_lfs_columns.rb
new file mode 100644
index 00000000000..bc515bc061c
--- /dev/null
+++ b/db/migrate/20210830085837_add_throttle_authenticated_git_lfs_columns.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class AddThrottleAuthenticatedGitLfsColumns < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ add_column :application_settings, :throttle_authenticated_git_lfs_requests_per_period, :integer, default: 1000, null: false
+ add_column :application_settings, :throttle_authenticated_git_lfs_period_in_seconds, :integer, default: 60, null: false
+ add_column :application_settings, :throttle_authenticated_git_lfs_enabled, :boolean, default: false, null: false
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_column :application_settings, :throttle_authenticated_git_lfs_requests_per_period
+ remove_column :application_settings, :throttle_authenticated_git_lfs_period_in_seconds
+ remove_column :application_settings, :throttle_authenticated_git_lfs_enabled, :boolean
+ end
+ end
+end
diff --git a/db/migrate/20210830140524_add_state_to_member.rb b/db/migrate/20210830140524_add_state_to_member.rb
new file mode 100644
index 00000000000..6009376badb
--- /dev/null
+++ b/db/migrate/20210830140524_add_state_to_member.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+class AddStateToMember < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ def up
+ unless column_exists?(:members, :state)
+ with_lock_retries do
+ add_column :members, :state, :integer, limit: 2, default: 0
+ end
+ end
+ end
+
+ def down
+ if column_exists?(:members, :state)
+ with_lock_retries do
+ remove_column :members, :state
+ end
+ end
+ end
+end
diff --git a/db/migrate/20210830154358_add_yaml_limit_constraints.rb b/db/migrate/20210830154358_add_yaml_limit_constraints.rb
new file mode 100644
index 00000000000..74236993fff
--- /dev/null
+++ b/db/migrate/20210830154358_add_yaml_limit_constraints.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+# See https://docs.gitlab.com/ee/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class AddYamlLimitConstraints < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ SIZE_CONSTRAINT_NAME = 'app_settings_yaml_max_size_positive'
+ DEPTH_CONSTRAINT_NAME = 'app_settings_yaml_max_depth_positive'
+
+ disable_ddl_transaction!
+
+ def up
+ add_check_constraint :application_settings, 'max_yaml_size_bytes > 0', SIZE_CONSTRAINT_NAME
+ add_check_constraint :application_settings, 'max_yaml_depth > 0', DEPTH_CONSTRAINT_NAME
+ end
+
+ def down
+ remove_check_constraint :application_settings, SIZE_CONSTRAINT_NAME
+ remove_check_constraint :application_settings, DEPTH_CONSTRAINT_NAME
+ end
+end
diff --git a/db/migrate/20210831134840_add_package_file_id_channel_idx_to_packages_helm_file_metadata.rb b/db/migrate/20210831134840_add_package_file_id_channel_idx_to_packages_helm_file_metadata.rb
new file mode 100644
index 00000000000..a3366bd9ddb
--- /dev/null
+++ b/db/migrate/20210831134840_add_package_file_id_channel_idx_to_packages_helm_file_metadata.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddPackageFileIdChannelIdxToPackagesHelmFileMetadata < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_packages_helm_file_metadata_on_pf_id_and_channel'
+
+ def up
+ add_concurrent_index :packages_helm_file_metadata, [:package_file_id, :channel], name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index :packages_helm_file_metadata, [:package_file_id, :channel], name: INDEX_NAME
+ end
+end
diff --git a/db/migrate/20210831135249_add_installable_helm_pkgs_idx_to_packages.rb b/db/migrate/20210831135249_add_installable_helm_pkgs_idx_to_packages.rb
new file mode 100644
index 00000000000..5e65b5c0fe1
--- /dev/null
+++ b/db/migrate/20210831135249_add_installable_helm_pkgs_idx_to_packages.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddInstallableHelmPkgsIdxToPackages < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'idx_installable_helm_pkgs_on_project_id_id'
+
+ def up
+ add_concurrent_index :packages_packages, [:project_id, :id], name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index :packages_packages, [:project_id, :id], name: INDEX_NAME
+ end
+end
diff --git a/db/migrate/20210831203408_upsert_base_work_item_types.rb b/db/migrate/20210831203408_upsert_base_work_item_types.rb
new file mode 100644
index 00000000000..314412d8d3d
--- /dev/null
+++ b/db/migrate/20210831203408_upsert_base_work_item_types.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+class UpsertBaseWorkItemTypes < ActiveRecord::Migration[6.1]
+ module WorkItem
+ class Type < ActiveRecord::Base
+ self.table_name = 'work_item_types'
+
+ enum base_type: {
+ issue: 0,
+ incident: 1,
+ test_case: 2,
+ requirement: 3
+ }
+ end
+ end
+
+ def up
+ # upsert default types
+ WorkItem::Type.find_or_create_by(name: 'Issue', namespace_id: nil, base_type: :issue, icon_name: 'issue-type-issue')
+ WorkItem::Type.find_or_create_by(name: 'Incident', namespace_id: nil, base_type: :incident, icon_name: 'issue-type-incident')
+ WorkItem::Type.find_or_create_by(name: 'Test Case', namespace_id: nil, base_type: :test_case, icon_name: 'issue-type-test-case')
+ WorkItem::Type.find_or_create_by(name: 'Requirement', namespace_id: nil, base_type: :requirement, icon_name: 'issue-type-requirements')
+ end
+
+ def down
+ # We expect this table to be empty at the point of the up migration,
+ # however there is a remote possibility that issues could already be
+ # using one of these types, with a tight foreign constraint.
+ # Therefore we will not attempt to remove any data.
+ end
+end
diff --git a/db/migrate/20210901065504_add_index_on_name_and_id_to_public_groups.rb b/db/migrate/20210901065504_add_index_on_name_and_id_to_public_groups.rb
new file mode 100644
index 00000000000..77b9e5297a7
--- /dev/null
+++ b/db/migrate/20210901065504_add_index_on_name_and_id_to_public_groups.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddIndexOnNameAndIdToPublicGroups < Gitlab::Database::Migration[1.0]
+ INDEX_NAME = 'index_namespaces_public_groups_name_id'
+ PUBLIC_VISIBILITY_LEVEL = 20
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :namespaces, [:name, :id], name: INDEX_NAME,
+ where: "type = 'Group' AND visibility_level = #{PUBLIC_VISIBILITY_LEVEL}"
+ end
+
+ def down
+ remove_concurrent_index_by_name :namespaces, INDEX_NAME
+ end
+end
diff --git a/db/migrate/20210902171406_add_latest_column_into_the_security_scans_table.rb b/db/migrate/20210902171406_add_latest_column_into_the_security_scans_table.rb
new file mode 100644
index 00000000000..3c022cbaf5e
--- /dev/null
+++ b/db/migrate/20210902171406_add_latest_column_into_the_security_scans_table.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddLatestColumnIntoTheSecurityScansTable < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
+
+ def up
+ add_column :security_scans, :latest, :boolean, default: true, null: false
+ end
+
+ def down
+ remove_column :security_scans, :latest
+ end
+end
diff --git a/db/migrate/20210902171808_set_default_job_token_scope_false.rb b/db/migrate/20210902171808_set_default_job_token_scope_false.rb
new file mode 100644
index 00000000000..0680382094f
--- /dev/null
+++ b/db/migrate/20210902171808_set_default_job_token_scope_false.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class SetDefaultJobTokenScopeFalse < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ change_column_default :project_ci_cd_settings, :job_token_scope_enabled, from: true, to: false
+ end
+ end
+
+ def down
+ with_lock_retries do
+ change_column_default :project_ci_cd_settings, :job_token_scope_enabled, from: false, to: true
+ end
+ end
+end
diff --git a/db/migrate/20210902184334_add_expire_access_tokens_to_doorkeeper_application.rb b/db/migrate/20210902184334_add_expire_access_tokens_to_doorkeeper_application.rb
new file mode 100644
index 00000000000..4638637331d
--- /dev/null
+++ b/db/migrate/20210902184334_add_expire_access_tokens_to_doorkeeper_application.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddExpireAccessTokensToDoorkeeperApplication < Gitlab::Database::Migration[1.0]
+ def change
+ add_column :oauth_applications, :expire_access_tokens, :boolean, default: false, null: false
+ end
+end
diff --git a/db/migrate/20210903054158_recreate_stage_issue_events_table_with_bigints.rb b/db/migrate/20210903054158_recreate_stage_issue_events_table_with_bigints.rb
new file mode 100644
index 00000000000..6c5d23d8703
--- /dev/null
+++ b/db/migrate/20210903054158_recreate_stage_issue_events_table_with_bigints.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+class RecreateStageIssueEventsTableWithBigints < Gitlab::Database::Migration[1.0]
+ include Gitlab::Database::PartitioningMigrationHelpers::TableManagementHelpers
+
+ def up
+ drop_table :analytics_cycle_analytics_issue_stage_events # rubocop:disable Migration/DropTable
+
+ execute <<~SQL
+ CREATE TABLE analytics_cycle_analytics_issue_stage_events (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone,
+ PRIMARY KEY (stage_event_hash_id, issue_id)
+ ) PARTITION BY HASH (stage_event_hash_id)
+ SQL
+
+ create_hash_partitions :analytics_cycle_analytics_issue_stage_events, 32
+ end
+
+ def down
+ drop_table :analytics_cycle_analytics_issue_stage_events
+
+ execute <<~SQL
+ CREATE TABLE analytics_cycle_analytics_issue_stage_events (
+ stage_event_hash_id integer NOT NULL,
+ issue_id integer NOT NULL,
+ group_id integer NOT NULL,
+ project_id integer NOT NULL,
+ milestone_id integer,
+ author_id integer,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone,
+ PRIMARY KEY (stage_event_hash_id, issue_id)
+ ) PARTITION BY HASH (stage_event_hash_id)
+ SQL
+
+ create_hash_partitions :analytics_cycle_analytics_issue_stage_events, 32
+ end
+end
diff --git a/db/migrate/20210906100021_delete_project_namespace_trigger.rb b/db/migrate/20210906100021_delete_project_namespace_trigger.rb
new file mode 100644
index 00000000000..ce68cf7d6d4
--- /dev/null
+++ b/db/migrate/20210906100021_delete_project_namespace_trigger.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+class DeleteProjectNamespaceTrigger < Gitlab::Database::Migration[1.0]
+ include Gitlab::Database::SchemaHelpers
+
+ TRIGGER_NAME = "trigger_delete_project_namespace_on_project_delete"
+ FUNCTION_NAME = 'delete_associated_project_namespace'
+
+ def up
+ create_trigger_function(FUNCTION_NAME, replace: true) do
+ <<~SQL
+ DELETE FROM namespaces
+ WHERE namespaces.id = OLD.project_namespace_id AND
+ namespaces.type = 'Project';
+ RETURN NULL;
+ SQL
+ end
+
+ execute(<<~SQL.squish)
+ CREATE TRIGGER #{TRIGGER_NAME}
+ AFTER DELETE ON projects FOR EACH ROW
+ WHEN (OLD.project_namespace_id IS NOT NULL)
+ EXECUTE FUNCTION #{FUNCTION_NAME}();
+ SQL
+ end
+
+ def down
+ drop_trigger(:projects, TRIGGER_NAME)
+ drop_function(FUNCTION_NAME)
+ end
+end
diff --git a/db/migrate/20210907182337_add_group_id_fkey_for_user_group_callout.rb b/db/migrate/20210907182337_add_group_id_fkey_for_user_group_callout.rb
new file mode 100644
index 00000000000..540344bd761
--- /dev/null
+++ b/db/migrate/20210907182337_add_group_id_fkey_for_user_group_callout.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddGroupIdFkeyForUserGroupCallout < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_foreign_key :user_group_callouts, :namespaces, column: :group_id, on_delete: :cascade
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key :user_group_callouts, column: :group_id
+ end
+ end
+end
diff --git a/db/migrate/20210907182359_add_user_id_fkey_for_user_group_callout.rb b/db/migrate/20210907182359_add_user_id_fkey_for_user_group_callout.rb
new file mode 100644
index 00000000000..37b73335933
--- /dev/null
+++ b/db/migrate/20210907182359_add_user_id_fkey_for_user_group_callout.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddUserIdFkeyForUserGroupCallout < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_foreign_key :user_group_callouts, :users, column: :user_id, on_delete: :cascade
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key :user_group_callouts, column: :user_id
+ end
+ end
+end
diff --git a/db/migrate/20210908060951_add_dast_schedules_to_plan_limits.rb b/db/migrate/20210908060951_add_dast_schedules_to_plan_limits.rb
new file mode 100644
index 00000000000..85c7522d006
--- /dev/null
+++ b/db/migrate/20210908060951_add_dast_schedules_to_plan_limits.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddDastSchedulesToPlanLimits < Gitlab::Database::Migration[1.0]
+ def change
+ add_column(:plan_limits, :dast_profile_schedules, :integer, default: 1, null: false)
+ end
+end
diff --git a/db/migrate/20210908061132_insert_dast_profile_schedules_plan_limits.rb b/db/migrate/20210908061132_insert_dast_profile_schedules_plan_limits.rb
new file mode 100644
index 00000000000..b9980f65c98
--- /dev/null
+++ b/db/migrate/20210908061132_insert_dast_profile_schedules_plan_limits.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class InsertDastProfileSchedulesPlanLimits < Gitlab::Database::Migration[1.0]
+ def up
+ create_or_update_plan_limit('dast_profile_schedules', 'default', 0)
+ create_or_update_plan_limit('dast_profile_schedules', 'free', 1)
+ create_or_update_plan_limit('dast_profile_schedules', 'bronze', 1)
+ create_or_update_plan_limit('dast_profile_schedules', 'silver', 1)
+ create_or_update_plan_limit('dast_profile_schedules', 'premium', 1)
+ create_or_update_plan_limit('dast_profile_schedules', 'premium_trial', 1)
+ create_or_update_plan_limit('dast_profile_schedules', 'gold', 20)
+ create_or_update_plan_limit('dast_profile_schedules', 'ultimate', 20)
+ create_or_update_plan_limit('dast_profile_schedules', 'ultimate_trial', 20)
+ end
+
+ def down
+ create_or_update_plan_limit('dast_profile_schedules', 'default', 0)
+ create_or_update_plan_limit('dast_profile_schedules', 'free', 0)
+ create_or_update_plan_limit('dast_profile_schedules', 'bronze', 0)
+ create_or_update_plan_limit('dast_profile_schedules', 'silver', 0)
+ create_or_update_plan_limit('dast_profile_schedules', 'premium', 0)
+ create_or_update_plan_limit('dast_profile_schedules', 'premium_trial', 0)
+ create_or_update_plan_limit('dast_profile_schedules', 'gold', 0)
+ create_or_update_plan_limit('dast_profile_schedules', 'ultimate', 0)
+ create_or_update_plan_limit('dast_profile_schedules', 'ultimate_trial', 0)
+ end
+end
diff --git a/db/migrate/20210908100810_add_jobs_per_stage_page_size_to_application_settings.rb b/db/migrate/20210908100810_add_jobs_per_stage_page_size_to_application_settings.rb
new file mode 100644
index 00000000000..81a76ecb10a
--- /dev/null
+++ b/db/migrate/20210908100810_add_jobs_per_stage_page_size_to_application_settings.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddJobsPerStagePageSizeToApplicationSettings < Gitlab::Database::Migration[1.0]
+ def change
+ add_column :application_settings, :jobs_per_stage_page_size, :integer, default: 200, null: false
+ end
+end
diff --git a/db/migrate/20210908140437_add_sidekiq_limits_to_application_settings.rb b/db/migrate/20210908140437_add_sidekiq_limits_to_application_settings.rb
new file mode 100644
index 00000000000..dd0796a1c86
--- /dev/null
+++ b/db/migrate/20210908140437_add_sidekiq_limits_to_application_settings.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+class AddSidekiqLimitsToApplicationSettings < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction! # needed for now to avoid subtransactions
+
+ def up
+ with_lock_retries do
+ add_column :application_settings, :sidekiq_job_limiter_mode, :smallint, default: 1, null: false
+ add_column :application_settings, :sidekiq_job_limiter_compression_threshold_bytes, :integer, default: 100_000, null: false
+ add_column :application_settings, :sidekiq_job_limiter_limit_bytes, :integer, default: 0, null: false
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_column :application_settings, :sidekiq_job_limiter_mode
+ remove_column :application_settings, :sidekiq_job_limiter_compression_threshold_bytes
+ remove_column :application_settings, :sidekiq_job_limiter_limit_bytes
+ end
+ end
+end
diff --git a/db/migrate/20210908185736_add_status_to_dependency_proxy_manifests.rb b/db/migrate/20210908185736_add_status_to_dependency_proxy_manifests.rb
new file mode 100644
index 00000000000..b8e7c7af144
--- /dev/null
+++ b/db/migrate/20210908185736_add_status_to_dependency_proxy_manifests.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddStatusToDependencyProxyManifests < Gitlab::Database::Migration[1.0]
+ def change
+ add_column :dependency_proxy_manifests, :status, :smallint, default: 0, null: false
+ end
+end
diff --git a/db/migrate/20210908185754_add_status_to_dependency_proxy_blobs.rb b/db/migrate/20210908185754_add_status_to_dependency_proxy_blobs.rb
new file mode 100644
index 00000000000..4fbdcad33cd
--- /dev/null
+++ b/db/migrate/20210908185754_add_status_to_dependency_proxy_blobs.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddStatusToDependencyProxyBlobs < Gitlab::Database::Migration[1.0]
+ def change
+ add_column :dependency_proxy_blobs, :status, :smallint, default: 0, null: false
+ end
+end
diff --git a/db/migrate/20210909184349_add_index_package_id_id_on_package_files.rb b/db/migrate/20210909184349_add_index_package_id_id_on_package_files.rb
new file mode 100644
index 00000000000..38d9c4b5dd9
--- /dev/null
+++ b/db/migrate/20210909184349_add_index_package_id_id_on_package_files.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddIndexPackageIdIdOnPackageFiles < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_packages_package_files_on_package_id_id'
+
+ def up
+ disable_statement_timeout do
+ execute "CREATE INDEX CONCURRENTLY #{INDEX_NAME} ON packages_package_files (package_id, id)" unless index_exists_by_name?(:package_package_files, INDEX_NAME)
+ end
+ end
+
+ def down
+ remove_concurrent_index_by_name :packages_package_files, INDEX_NAME
+ end
+end
diff --git a/db/migrate/20210910141043_change_ci_minutes_additional_pack_text_limit.rb b/db/migrate/20210910141043_change_ci_minutes_additional_pack_text_limit.rb
new file mode 100644
index 00000000000..ebb0de53d6a
--- /dev/null
+++ b/db/migrate/20210910141043_change_ci_minutes_additional_pack_text_limit.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class ChangeCiMinutesAdditionalPackTextLimit < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ remove_text_limit :ci_minutes_additional_packs, :purchase_xid
+ add_text_limit :ci_minutes_additional_packs, :purchase_xid, 50
+ end
+
+ def down
+ remove_text_limit :ci_minutes_additional_packs, :purchase_xid
+ add_text_limit :ci_minutes_additional_packs, :purchase_xid, 32, validate: false
+ end
+end
diff --git a/db/migrate/20210913010411_create_agent_project_authorizations.rb b/db/migrate/20210913010411_create_agent_project_authorizations.rb
new file mode 100644
index 00000000000..02b6ac677e0
--- /dev/null
+++ b/db/migrate/20210913010411_create_agent_project_authorizations.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class CreateAgentProjectAuthorizations < Gitlab::Database::Migration[1.0]
+ def change
+ create_table :agent_project_authorizations do |t|
+ t.bigint :project_id, null: false
+ t.bigint :agent_id, null: false
+ t.jsonb :config, null: false
+
+ t.index :project_id
+ t.index [:agent_id, :project_id], unique: true
+ end
+ end
+end
diff --git a/db/migrate/20210913010432_add_agent_project_authorizations_foreign_keys.rb b/db/migrate/20210913010432_add_agent_project_authorizations_foreign_keys.rb
new file mode 100644
index 00000000000..545fc125950
--- /dev/null
+++ b/db/migrate/20210913010432_add_agent_project_authorizations_foreign_keys.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class AddAgentProjectAuthorizationsForeignKeys < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_foreign_key :agent_project_authorizations, :projects, column: :project_id
+ add_concurrent_foreign_key :agent_project_authorizations, :cluster_agents, column: :agent_id
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key_if_exists :agent_project_authorizations, column: :project_id
+ end
+
+ with_lock_retries do
+ remove_foreign_key_if_exists :agent_project_authorizations, column: :agent_id
+ end
+ end
+end
diff --git a/db/migrate/20210913122457_add_namespace_traversal_ids_to_ci_pending_builds.rb b/db/migrate/20210913122457_add_namespace_traversal_ids_to_ci_pending_builds.rb
new file mode 100644
index 00000000000..9dd420604f4
--- /dev/null
+++ b/db/migrate/20210913122457_add_namespace_traversal_ids_to_ci_pending_builds.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddNamespaceTraversalIdsToCiPendingBuilds < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
+
+ def change
+ add_column :ci_pending_builds, :namespace_traversal_ids, :integer, array: true, default: []
+ end
+end
diff --git a/db/post_migrate/20201106134950_deduplicate_epic_iids.rb b/db/post_migrate/20201106134950_deduplicate_epic_iids.rb
index bc7daf9329d..8fddc81057b 100644
--- a/db/post_migrate/20201106134950_deduplicate_epic_iids.rb
+++ b/db/post_migrate/20201106134950_deduplicate_epic_iids.rb
@@ -85,7 +85,7 @@ class DeduplicateEpicIids < ActiveRecord::Migration[6.0]
instance = subject.is_a?(::Class) ? nil : subject
- subject.transaction(requires_new: true) do
+ subject.transaction(requires_new: true) do # rubocop:disable Performance/ActiveRecordSubtransactions
InternalId.create!(
**scope,
usage: usage_value,
diff --git a/db/post_migrate/20210622045705_finalize_events_bigint_conversion.rb b/db/post_migrate/20210622045705_finalize_events_bigint_conversion.rb
new file mode 100644
index 00000000000..b99a61e8e63
--- /dev/null
+++ b/db/post_migrate/20210622045705_finalize_events_bigint_conversion.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+class FinalizeEventsBigintConversion < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ TABLE_NAME = 'events'
+
+ def up
+ ensure_batched_background_migration_is_finished(
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: TABLE_NAME,
+ column_name: 'id',
+ job_arguments: [["id"], ["id_convert_to_bigint"]]
+ )
+
+ swap
+ end
+
+ def down
+ swap
+ end
+
+ private
+
+ def swap
+ # This is to replace the existing "events_pkey" PRIMARY KEY, btree (id)
+ add_concurrent_index TABLE_NAME, :id_convert_to_bigint, unique: true, name: 'index_events_on_id_convert_to_bigint'
+ # This is to replace the existing "index_events_on_project_id_and_id" btree (project_id, id)
+ add_concurrent_index TABLE_NAME, [:project_id, :id_convert_to_bigint], name: 'index_events_on_project_id_and_id_convert_to_bigint'
+ # This is to replace the existing "index_events_on_project_id_and_id_desc_on_merged_action" btree (project_id, id DESC) WHERE action = 7
+ add_concurrent_index TABLE_NAME, [:project_id, :id_convert_to_bigint], order: { id_convert_to_bigint: :desc },
+ where: "action = 7", name: 'index_events_on_project_id_and_id_bigint_desc_on_merged_action'
+
+ # Add a FK on `push_event_payloads(event_id)` to `id_convert_to_bigint`, the old FK (fk_36c74129da)
+ # will be removed when events_pkey constraint is droppped.
+ fk_event_id = concurrent_foreign_key_name(:push_event_payloads, :event_id)
+ fk_event_id_tmp = "#{fk_event_id}_tmp"
+ add_concurrent_foreign_key :push_event_payloads, TABLE_NAME,
+ column: :event_id, target_column: :id_convert_to_bigint,
+ name: fk_event_id_tmp, on_delete: :cascade, reverse_lock_order: true
+
+ with_lock_retries(raise_on_exhaustion: true) do
+ # We'll need ACCESS EXCLUSIVE lock on the related tables,
+ # lets make sure it can be acquired from the start.
+ # Lock order should be
+ # 1. events
+ # 2. push_event_payloads
+ # in order to match the order in EventCreateService#create_push_event,
+ # and avoid deadlocks.
+ execute "LOCK TABLE #{TABLE_NAME}, push_event_payloads IN ACCESS EXCLUSIVE MODE"
+
+ # Swap column names
+ temp_name = 'id_tmp'
+ execute "ALTER TABLE #{quote_table_name(TABLE_NAME)} RENAME COLUMN #{quote_column_name(:id)} TO #{quote_column_name(temp_name)}"
+ execute "ALTER TABLE #{quote_table_name(TABLE_NAME)} RENAME COLUMN #{quote_column_name(:id_convert_to_bigint)} TO #{quote_column_name(:id)}"
+ execute "ALTER TABLE #{quote_table_name(TABLE_NAME)} RENAME COLUMN #{quote_column_name(temp_name)} TO #{quote_column_name(:id_convert_to_bigint)}"
+
+ # We need to update the trigger function in order to make PostgreSQL to
+ # regenerate the execution plan for it. This is to avoid type mismatch errors like
+ # "type of parameter 15 (bigint) does not match that when preparing the plan (integer)"
+ function_name = Gitlab::Database::UnidirectionalCopyTrigger.on_table(TABLE_NAME).name(:id, :id_convert_to_bigint)
+ execute "ALTER FUNCTION #{quote_table_name(function_name)} RESET ALL"
+
+ # Swap defaults
+ execute "ALTER SEQUENCE events_id_seq OWNED BY #{TABLE_NAME}.id"
+ change_column_default TABLE_NAME, :id, -> { "nextval('events_id_seq'::regclass)" }
+ change_column_default TABLE_NAME, :id_convert_to_bigint, 0
+
+ # Swap PK constraint
+ execute "ALTER TABLE #{TABLE_NAME} DROP CONSTRAINT events_pkey CASCADE" # this will drop fk_36c74129da
+ rename_index TABLE_NAME, 'index_events_on_id_convert_to_bigint', 'events_pkey'
+ execute "ALTER TABLE #{TABLE_NAME} ADD CONSTRAINT events_pkey PRIMARY KEY USING INDEX events_pkey"
+
+ # Rename the rest of the indexes (we already hold an exclusive lock, so no need to use DROP INDEX CONCURRENTLY here
+ execute 'DROP INDEX index_events_on_project_id_and_id'
+ rename_index TABLE_NAME, 'index_events_on_project_id_and_id_convert_to_bigint', 'index_events_on_project_id_and_id'
+ execute 'DROP INDEX index_events_on_project_id_and_id_desc_on_merged_action'
+ rename_index TABLE_NAME, 'index_events_on_project_id_and_id_bigint_desc_on_merged_action', 'index_events_on_project_id_and_id_desc_on_merged_action'
+
+ # Change the name of the temporary FK
+ rename_constraint(:push_event_payloads, fk_event_id_tmp, fk_event_id)
+ end
+ end
+end
diff --git a/db/post_migrate/20210701141346_finalize_ci_builds_stage_id_bigint_conversion.rb b/db/post_migrate/20210701141346_finalize_ci_builds_stage_id_bigint_conversion.rb
new file mode 100644
index 00000000000..a8a9fe037ec
--- /dev/null
+++ b/db/post_migrate/20210701141346_finalize_ci_builds_stage_id_bigint_conversion.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+class FinalizeCiBuildsStageIdBigintConversion < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ TABLE_NAME = 'ci_builds'
+
+ def up
+ ensure_batched_background_migration_is_finished(
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: TABLE_NAME,
+ column_name: 'id',
+ job_arguments: [%w[id stage_id], %w[id_convert_to_bigint stage_id_convert_to_bigint]]
+ )
+
+ swap_columns
+ end
+
+ def down
+ swap_columns
+ end
+
+ private
+
+ def swap_columns
+ # Create a copy of the original column's index on the new column
+ add_concurrent_index TABLE_NAME, :stage_id_convert_to_bigint, name: :index_ci_builds_on_converted_stage_id # rubocop:disable Migration/PreventIndexCreation
+
+ # Create a copy of the original column's FK on the new column
+ add_concurrent_foreign_key TABLE_NAME, :ci_stages, column: :stage_id_convert_to_bigint, on_delete: :cascade,
+ reverse_lock_order: true
+
+ with_lock_retries(raise_on_exhaustion: true) do
+ quoted_table_name = quote_table_name(TABLE_NAME)
+ quoted_referenced_table_name = quote_table_name(:ci_stages)
+
+ # Acquire locks up-front, not just to the build table but the FK's referenced table
+ execute "LOCK TABLE #{quoted_referenced_table_name}, #{quoted_table_name} IN ACCESS EXCLUSIVE MODE"
+
+ # Swap the column names of the two columns
+ temporary_name = 'stage_id_tmp'
+ execute "ALTER TABLE #{quoted_table_name} RENAME COLUMN #{quote_column_name(:stage_id)} TO #{quote_column_name(temporary_name)}"
+ execute "ALTER TABLE #{quoted_table_name} RENAME COLUMN #{quote_column_name(:stage_id_convert_to_bigint)} TO #{quote_column_name(:stage_id)}"
+ execute "ALTER TABLE #{quoted_table_name} RENAME COLUMN #{quote_column_name(temporary_name)} TO #{quote_column_name(:stage_id_convert_to_bigint)}"
+
+ # Reset the function so PG drops the plan cache for the incorrect integer type
+ function_name = Gitlab::Database::UnidirectionalCopyTrigger.on_table(TABLE_NAME)
+ .name([:id, :stage_id], [:id_convert_to_bigint, :stage_id_convert_to_bigint])
+ execute "ALTER FUNCTION #{quote_table_name(function_name)} RESET ALL"
+
+ # Remove the original column index, and rename the new column index to the original name
+ execute 'DROP INDEX index_ci_builds_on_stage_id'
+ rename_index TABLE_NAME, :index_ci_builds_on_converted_stage_id, :index_ci_builds_on_stage_id
+
+ # Remove the original column foreign key, and rename the new column foreign key to the original name
+ remove_foreign_key TABLE_NAME, name: concurrent_foreign_key_name(TABLE_NAME, :stage_id)
+ rename_constraint(
+ TABLE_NAME,
+ concurrent_foreign_key_name(TABLE_NAME, :stage_id_convert_to_bigint),
+ concurrent_foreign_key_name(TABLE_NAME, :stage_id))
+ end
+ end
+end
diff --git a/db/post_migrate/20210706112800_remove_cloud_license_enabled_from_application_settings.rb b/db/post_migrate/20210706112800_remove_cloud_license_enabled_from_application_settings.rb
new file mode 100644
index 00000000000..7224e84c1b3
--- /dev/null
+++ b/db/post_migrate/20210706112800_remove_cloud_license_enabled_from_application_settings.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveCloudLicenseEnabledFromApplicationSettings < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ remove_column :application_settings, :cloud_license_enabled
+ end
+ end
+
+ def down
+ with_lock_retries do
+ add_column :application_settings, :cloud_license_enabled, :boolean, null: false, default: false
+ end
+ end
+end
diff --git a/db/post_migrate/20210708011426_finalize_ci_builds_metadata_bigint_conversion.rb b/db/post_migrate/20210708011426_finalize_ci_builds_metadata_bigint_conversion.rb
new file mode 100644
index 00000000000..f75df04ba48
--- /dev/null
+++ b/db/post_migrate/20210708011426_finalize_ci_builds_metadata_bigint_conversion.rb
@@ -0,0 +1,113 @@
+# frozen_string_literal: true
+
+class FinalizeCiBuildsMetadataBigintConversion < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ TABLE_NAME = 'ci_builds_metadata'
+
+ def up
+ ensure_batched_background_migration_is_finished(
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: TABLE_NAME,
+ column_name: 'id',
+ job_arguments: [["id"], ["id_convert_to_bigint"]]
+ )
+
+ ensure_batched_background_migration_is_finished(
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: TABLE_NAME,
+ column_name: 'id',
+ job_arguments: [["build_id"], ["build_id_convert_to_bigint"]]
+ )
+
+ swap
+ end
+
+ def down
+ swap
+ end
+
+ private
+
+ def swap
+ # Indexes were pre-created on gitlab.com to avoid slowing down deployments
+ #
+ # rubocop:disable Migration/PreventIndexCreation
+ add_concurrent_index TABLE_NAME, :id_convert_to_bigint, unique: true, name: 'index_ci_builds_metadata_on_id_convert_to_bigint'
+ add_concurrent_index TABLE_NAME, :build_id_convert_to_bigint, where: 'has_exposed_artifacts IS TRUE', name: 'index_ci_builds_metadata_on_build_id_int8_and_exposed_artifacts'
+ create_covering_index TABLE_NAME, 'index_ci_builds_metadata_on_build_id_int8_where_interruptible'
+ add_concurrent_index TABLE_NAME, :build_id_convert_to_bigint, unique: true, name: 'index_ci_builds_metadata_on_build_id_convert_to_bigint'
+ # rubocop:enable Migration/PreventIndexCreation
+
+ add_concurrent_foreign_key TABLE_NAME, :ci_builds, column: :build_id_convert_to_bigint, on_delete: :cascade,
+ reverse_lock_order: true
+
+ with_lock_retries(raise_on_exhaustion: true) do
+ execute "LOCK TABLE ci_builds, #{TABLE_NAME} IN ACCESS EXCLUSIVE MODE"
+
+ # rubocop:disable Migration/WithLockRetriesDisallowedMethod
+ swap_column :id
+ swap_column :build_id
+ # rubocop:enable Migration/WithLockRetriesDisallowedMethod
+
+ # We need to update the trigger function in order to make PostgreSQL to
+ # regenerate the execution plan for it. This is to avoid type mismatch errors like
+ # "type of parameter 15 (bigint) does not match that when preparing the plan (integer)"
+ execute "ALTER FUNCTION #{quote_table_name(Gitlab::Database::UnidirectionalCopyTrigger.on_table(TABLE_NAME).name(:id, :id_convert_to_bigint))} RESET ALL"
+ execute "ALTER FUNCTION #{quote_table_name(Gitlab::Database::UnidirectionalCopyTrigger.on_table(TABLE_NAME).name(:build_id, :build_id_convert_to_bigint))} RESET ALL"
+
+ # Swap defaults for PK
+ execute "ALTER SEQUENCE ci_builds_metadata_id_seq OWNED BY #{TABLE_NAME}.id"
+ change_column_default TABLE_NAME, :id, -> { "nextval('ci_builds_metadata_id_seq'::regclass)" }
+ change_column_default TABLE_NAME, :id_convert_to_bigint, 0
+
+ # Swap defaults for FK
+ change_column_default TABLE_NAME, :build_id, nil
+ change_column_default TABLE_NAME, :build_id_convert_to_bigint, 0
+
+ # Swap PK constraint
+ execute "ALTER TABLE #{TABLE_NAME} DROP CONSTRAINT ci_builds_metadata_pkey CASCADE"
+ rename_index TABLE_NAME, 'index_ci_builds_metadata_on_id_convert_to_bigint', 'ci_builds_metadata_pkey'
+ execute "ALTER TABLE #{TABLE_NAME} ADD CONSTRAINT ci_builds_metadata_pkey PRIMARY KEY USING INDEX ci_builds_metadata_pkey"
+
+ # Rename the rest of the indexes (we already hold an exclusive lock, so no need to use DROP INDEX CONCURRENTLY here)
+ # rubocop:disable Migration/WithLockRetriesDisallowedMethod
+ swap_index 'index_ci_builds_metadata_on_build_id', 'index_ci_builds_metadata_on_build_id_convert_to_bigint'
+ swap_index 'index_ci_builds_metadata_on_build_id_and_has_exposed_artifacts', 'index_ci_builds_metadata_on_build_id_int8_and_exposed_artifacts'
+ swap_index 'index_ci_builds_metadata_on_build_id_and_id_and_interruptible', 'index_ci_builds_metadata_on_build_id_int8_where_interruptible'
+ # rubocop:enable Migration/WithLockRetriesDisallowedMethod
+
+ # Swap FK constraint
+ remove_foreign_key TABLE_NAME, name: concurrent_foreign_key_name(TABLE_NAME, :build_id)
+ rename_constraint(
+ TABLE_NAME,
+ concurrent_foreign_key_name(TABLE_NAME, :build_id_convert_to_bigint),
+ concurrent_foreign_key_name(TABLE_NAME, :build_id)
+ )
+ end
+ end
+
+ def swap_index(old, new)
+ execute "DROP INDEX #{old}"
+ rename_index TABLE_NAME, new, old
+ end
+
+ def swap_column(name)
+ temp_name = "#{name}_tmp"
+ execute "ALTER TABLE #{quote_table_name(TABLE_NAME)} RENAME COLUMN #{quote_column_name(name)} TO #{quote_column_name(temp_name)}"
+ execute "ALTER TABLE #{quote_table_name(TABLE_NAME)} RENAME COLUMN #{quote_column_name(:"#{name}_convert_to_bigint")} TO #{quote_column_name(name)}"
+ execute "ALTER TABLE #{quote_table_name(TABLE_NAME)} RENAME COLUMN #{quote_column_name(temp_name)} TO #{quote_column_name(:"#{name}_convert_to_bigint")}"
+ end
+
+ def create_covering_index(table, name)
+ return if index_exists_by_name?(table, name)
+
+ disable_statement_timeout do
+ execute <<~SQL
+ CREATE INDEX CONCURRENTLY #{name}
+ ON #{table} (build_id_convert_to_bigint) INCLUDE (id_convert_to_bigint)
+ WHERE interruptible = true
+ SQL
+ end
+ end
+end
diff --git a/db/post_migrate/20210721122840_remove_seat_link_enabled_from_application_settings.rb b/db/post_migrate/20210721122840_remove_seat_link_enabled_from_application_settings.rb
new file mode 100644
index 00000000000..20118dbbac8
--- /dev/null
+++ b/db/post_migrate/20210721122840_remove_seat_link_enabled_from_application_settings.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class RemoveSeatLinkEnabledFromApplicationSettings < ActiveRecord::Migration[6.1]
+ def up
+ remove_column :application_settings, :seat_link_enabled
+ end
+
+ def down
+ add_column :application_settings, :seat_link_enabled, :boolean, null: false, default: true
+ end
+end
diff --git a/db/post_migrate/20210730104800_schedule_extract_project_topics_into_separate_table.rb b/db/post_migrate/20210730104800_schedule_extract_project_topics_into_separate_table.rb
new file mode 100644
index 00000000000..3102561a129
--- /dev/null
+++ b/db/post_migrate/20210730104800_schedule_extract_project_topics_into_separate_table.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+class ScheduleExtractProjectTopicsIntoSeparateTable < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ BATCH_SIZE = 1_000
+ DELAY_INTERVAL = 2.minutes
+ MIGRATION = 'ExtractProjectTopicsIntoSeparateTable'
+ INDEX_NAME = 'tmp_index_taggings_on_id_where_taggable_type_project'
+ INDEX_CONDITION = "taggable_type = 'Project'"
+
+ disable_ddl_transaction!
+
+ class Tagging < ActiveRecord::Base
+ include ::EachBatch
+
+ self.table_name = 'taggings'
+ end
+
+ def up
+ # this index is used in 20210730104800_schedule_extract_project_topics_into_separate_table
+ add_concurrent_index :taggings, :id, where: INDEX_CONDITION, name: INDEX_NAME # rubocop:disable Migration/PreventIndexCreation
+
+ queue_background_migration_jobs_by_range_at_intervals(
+ Tagging.where(taggable_type: 'Project'),
+ MIGRATION,
+ DELAY_INTERVAL,
+ batch_size: BATCH_SIZE,
+ track_jobs: true
+ )
+ end
+
+ def down
+ remove_concurrent_index_by_name :taggings, INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20210731132939_backfill_stage_event_hash.rb b/db/post_migrate/20210731132939_backfill_stage_event_hash.rb
new file mode 100644
index 00000000000..2c4dc904387
--- /dev/null
+++ b/db/post_migrate/20210731132939_backfill_stage_event_hash.rb
@@ -0,0 +1,115 @@
+# frozen_string_literal: true
+
+class BackfillStageEventHash < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ BATCH_SIZE = 100
+ EVENT_ID_IDENTIFIER_MAPPING = {
+ 1 => :issue_created,
+ 2 => :issue_first_mentioned_in_commit,
+ 3 => :issue_closed,
+ 4 => :issue_first_added_to_board,
+ 5 => :issue_first_associated_with_milestone,
+ 7 => :issue_last_edited,
+ 8 => :issue_label_added,
+ 9 => :issue_label_removed,
+ 10 => :issue_deployed_to_production,
+ 100 => :merge_request_created,
+ 101 => :merge_request_first_deployed_to_production,
+ 102 => :merge_request_last_build_finished,
+ 103 => :merge_request_last_build_started,
+ 104 => :merge_request_merged,
+ 105 => :merge_request_closed,
+ 106 => :merge_request_last_edited,
+ 107 => :merge_request_label_added,
+ 108 => :merge_request_label_removed,
+ 109 => :merge_request_first_commit_at,
+ 1000 => :code_stage_start,
+ 1001 => :issue_stage_end,
+ 1002 => :plan_stage_start
+ }.freeze
+
+ LABEL_BASED_EVENTS = Set.new([8, 9, 107, 108]).freeze
+
+ class GroupStage < ActiveRecord::Base
+ include EachBatch
+
+ self.table_name = 'analytics_cycle_analytics_group_stages'
+ end
+
+ class ProjectStage < ActiveRecord::Base
+ include EachBatch
+
+ self.table_name = 'analytics_cycle_analytics_project_stages'
+ end
+
+ class StageEventHash < ActiveRecord::Base
+ self.table_name = 'analytics_cycle_analytics_stage_event_hashes'
+ end
+
+ def up
+ GroupStage.reset_column_information
+ ProjectStage.reset_column_information
+ StageEventHash.reset_column_information
+
+ update_stage_table(GroupStage)
+ update_stage_table(ProjectStage)
+
+ add_not_null_constraint :analytics_cycle_analytics_group_stages, :stage_event_hash_id
+ add_not_null_constraint :analytics_cycle_analytics_project_stages, :stage_event_hash_id
+ end
+
+ def down
+ remove_not_null_constraint :analytics_cycle_analytics_group_stages, :stage_event_hash_id
+ remove_not_null_constraint :analytics_cycle_analytics_project_stages, :stage_event_hash_id
+ end
+
+ private
+
+ def update_stage_table(klass)
+ klass.each_batch(of: BATCH_SIZE) do |relation|
+ klass.transaction do
+ records = relation.where(stage_event_hash_id: nil).lock!.to_a # prevent concurrent modification (unlikely to happen)
+ records = delete_invalid_records(records)
+ next if records.empty?
+
+ hashes_by_stage = records.to_h { |stage| [stage, calculate_stage_events_hash(stage)] }
+ hashes = hashes_by_stage.values.uniq
+
+ StageEventHash.insert_all(hashes.map { |hash| { hash_sha256: hash } })
+
+ stage_event_hashes_by_hash = StageEventHash.where(hash_sha256: hashes).index_by(&:hash_sha256)
+ records.each do |stage|
+ stage.update!(stage_event_hash_id: stage_event_hashes_by_hash[hashes_by_stage[stage]].id)
+ end
+ end
+ end
+ end
+
+ def calculate_stage_events_hash(stage)
+ start_event_hash = calculate_event_hash(stage.start_event_identifier, stage.start_event_label_id)
+ end_event_hash = calculate_event_hash(stage.end_event_identifier, stage.end_event_label_id)
+
+ Digest::SHA256.hexdigest("#{start_event_hash}-#{end_event_hash}")
+ end
+
+ def calculate_event_hash(event_identifier, label_id = nil)
+ str = EVENT_ID_IDENTIFIER_MAPPING.fetch(event_identifier).to_s
+ str << "-#{label_id}" if LABEL_BASED_EVENTS.include?(event_identifier)
+
+ Digest::SHA256.hexdigest(str)
+ end
+
+ # Invalid records are safe to delete, since they are not working properly anyway
+ def delete_invalid_records(records)
+ to_be_deleted = records.select do |record|
+ EVENT_ID_IDENTIFIER_MAPPING[record.start_event_identifier].nil? ||
+ EVENT_ID_IDENTIFIER_MAPPING[record.end_event_identifier].nil?
+ end
+
+ to_be_deleted.each(&:delete)
+ records - to_be_deleted
+ end
+end
diff --git a/db/post_migrate/20210806131706_finalize_taggins_bigint_conversion.rb b/db/post_migrate/20210806131706_finalize_taggins_bigint_conversion.rb
new file mode 100644
index 00000000000..beb15e77878
--- /dev/null
+++ b/db/post_migrate/20210806131706_finalize_taggins_bigint_conversion.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+class FinalizeTagginsBigintConversion < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ TABLE_NAME = 'taggings'
+
+ def up
+ ensure_batched_background_migration_is_finished(
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: TABLE_NAME,
+ column_name: 'id',
+ job_arguments: [%w[id taggable_id], %w[id_convert_to_bigint taggable_id_convert_to_bigint]]
+ )
+
+ swap
+ end
+
+ def down
+ swap
+ end
+
+ private
+
+ def swap
+ # rubocop:disable Migration/PreventIndexCreation
+ add_concurrent_index TABLE_NAME, :id_convert_to_bigint, unique: true, name: 'index_taggings_on_id_convert_to_bigint'
+
+ # This is to replace the existing "index_taggings_on_taggable_id_and_taggable_type" btree (taggable_id, taggable_type)
+ add_concurrent_index TABLE_NAME, [:taggable_id_convert_to_bigint, :taggable_type], name: 'i_taggings_on_taggable_id_convert_to_bigint_and_taggable_type'
+
+ # This is to replace the existing "index_taggings_on_taggable_id_and_taggable_type_and_context" btree (taggable_id, taggable_type, context)
+ add_concurrent_index TABLE_NAME, [:taggable_id_convert_to_bigint, :taggable_type, :context], name: 'i_taggings_on_taggable_bigint_and_taggable_type_and_context'
+
+ # This is to replace the existing "taggings_idx" btree (tag_id, taggable_id, taggable_type, context, tagger_id, tagger_type)
+ add_concurrent_index TABLE_NAME, [:tag_id, :taggable_id_convert_to_bigint, :taggable_type, :context, :tagger_id, :tagger_type], unique: true, name: 'taggings_idx_tmp'
+
+ # This is to replace the existing "tmp_index_taggings_on_id_where_taggable_type_project" btree (id) WHERE taggable_type::text = 'Project'::text
+ add_concurrent_index TABLE_NAME, :id_convert_to_bigint, where: "taggable_type = 'Project'", name: 'tmp_index_taggings_on_id_bigint_where_taggable_type_project'
+ # rubocop:enable Migration/PreventIndexCreation
+
+ with_lock_retries(raise_on_exhaustion: true) do
+ # We'll need ACCESS EXCLUSIVE lock on the related tables,
+ # lets make sure it can be acquired from the start
+ execute "LOCK TABLE #{TABLE_NAME} IN ACCESS EXCLUSIVE MODE"
+
+ # Swap column names
+ temp_name = 'taggable_id_tmp'
+ execute "ALTER TABLE #{quote_table_name(TABLE_NAME)} RENAME COLUMN #{quote_column_name(:taggable_id)} TO #{quote_column_name(temp_name)}"
+ execute "ALTER TABLE #{quote_table_name(TABLE_NAME)} RENAME COLUMN #{quote_column_name(:taggable_id_convert_to_bigint)} TO #{quote_column_name(:taggable_id)}"
+ execute "ALTER TABLE #{quote_table_name(TABLE_NAME)} RENAME COLUMN #{quote_column_name(temp_name)} TO #{quote_column_name(:taggable_id_convert_to_bigint)}"
+
+ temp_name = 'id_tmp'
+ execute "ALTER TABLE #{quote_table_name(TABLE_NAME)} RENAME COLUMN #{quote_column_name(:id)} TO #{quote_column_name(temp_name)}"
+ execute "ALTER TABLE #{quote_table_name(TABLE_NAME)} RENAME COLUMN #{quote_column_name(:id_convert_to_bigint)} TO #{quote_column_name(:id)}"
+ execute "ALTER TABLE #{quote_table_name(TABLE_NAME)} RENAME COLUMN #{quote_column_name(temp_name)} TO #{quote_column_name(:id_convert_to_bigint)}"
+
+ # We need to update the trigger function in order to make PostgreSQL to
+ # regenerate the execution plan for it. This is to avoid type mismatch errors like
+ # "type of parameter 15 (bigint) does not match that when preparing the plan (integer)"
+ function_name = Gitlab::Database::UnidirectionalCopyTrigger.on_table(TABLE_NAME).name([:id, :taggable_id], [:id_convert_to_bigint, :taggable_id_convert_to_bigint])
+ execute "ALTER FUNCTION #{quote_table_name(function_name)} RESET ALL"
+
+ # Swap defaults
+ execute "ALTER SEQUENCE taggings_id_seq OWNED BY #{TABLE_NAME}.id"
+ change_column_default TABLE_NAME, :id, -> { "nextval('taggings_id_seq'::regclass)" }
+ change_column_default TABLE_NAME, :id_convert_to_bigint, 0
+
+ # Swap PK constraint
+ execute "ALTER TABLE #{TABLE_NAME} DROP CONSTRAINT taggings_pkey CASCADE"
+ rename_index TABLE_NAME, 'index_taggings_on_id_convert_to_bigint', 'taggings_pkey'
+ execute "ALTER TABLE #{TABLE_NAME} ADD CONSTRAINT taggings_pkey PRIMARY KEY USING INDEX taggings_pkey"
+
+ # Rename the index on the `bigint` column to match the new column name
+ # (we already hold an exclusive lock, so no need to use DROP INDEX CONCURRENTLY here)
+ execute 'DROP INDEX index_taggings_on_taggable_id_and_taggable_type'
+ rename_index TABLE_NAME, 'i_taggings_on_taggable_id_convert_to_bigint_and_taggable_type', 'index_taggings_on_taggable_id_and_taggable_type'
+ execute 'DROP INDEX index_taggings_on_taggable_id_and_taggable_type_and_context'
+ rename_index TABLE_NAME, 'i_taggings_on_taggable_bigint_and_taggable_type_and_context', 'index_taggings_on_taggable_id_and_taggable_type_and_context'
+ execute 'DROP INDEX taggings_idx'
+ rename_index TABLE_NAME, 'taggings_idx_tmp', 'taggings_idx'
+ execute 'DROP INDEX tmp_index_taggings_on_id_where_taggable_type_project'
+ rename_index TABLE_NAME, 'tmp_index_taggings_on_id_bigint_where_taggable_type_project', 'tmp_index_taggings_on_id_where_taggable_type_project'
+ end
+ end
+end
diff --git a/db/post_migrate/20210813151908_replace_external_wiki_triggers.rb b/db/post_migrate/20210813151908_replace_external_wiki_triggers.rb
new file mode 100644
index 00000000000..d11baae42e2
--- /dev/null
+++ b/db/post_migrate/20210813151908_replace_external_wiki_triggers.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+class ReplaceExternalWikiTriggers < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::SchemaHelpers
+
+ def up
+ replace_triggers('type_new', 'Integrations::ExternalWiki')
+
+ # we need an extra trigger to handle when type_new is updated by the
+ # `integrations_set_type_new` trigger.
+ # This can be removed when this trigger has been removed.
+ execute(<<~SQL.squish)
+ CREATE TRIGGER #{trigger_name(:type_new_updated)}
+ AFTER UPDATE OF type_new ON integrations FOR EACH ROW
+ WHEN ((new.type_new)::text = 'Integrations::ExternalWiki'::text AND new.project_id IS NOT NULL)
+ EXECUTE FUNCTION set_has_external_wiki();
+ SQL
+ end
+
+ def down
+ execute("DROP TRIGGER IF EXISTS #{trigger_name(:type_new_updated)} ON integrations;")
+ replace_triggers('type', 'ExternalWikiService')
+ end
+
+ private
+
+ def replace_triggers(column_name, value)
+ triggers(column_name, value).each do |event, condition|
+ trigger = trigger_name(event)
+
+ # create duplicate trigger, using the defined condition
+ execute(<<~SQL.squish)
+ CREATE TRIGGER #{trigger}_new AFTER #{event.upcase} ON integrations FOR EACH ROW
+ WHEN (#{condition})
+ EXECUTE FUNCTION set_has_external_wiki();
+ SQL
+
+ # Swap the triggers in place, so that the new trigger has the canonical name
+ execute("ALTER TRIGGER #{trigger} ON integrations RENAME TO #{trigger}_old;")
+ execute("ALTER TRIGGER #{trigger}_new ON integrations RENAME TO #{trigger};")
+
+ # remove the old, now redundant trigger
+ execute("DROP TRIGGER IF EXISTS #{trigger}_old ON integrations;")
+ end
+ end
+
+ def trigger_name(event)
+ "trigger_has_external_wiki_on_#{event}"
+ end
+
+ def triggers(column_name, value)
+ {
+ delete: "#{matches_value('old', column_name, value)} AND #{project_not_null('old')}",
+ insert: "(new.active = true) AND #{matches_value('new', column_name, value)} AND #{project_not_null('new')}",
+ update: "#{matches_value('new', column_name, value)} AND (old.active <> new.active) AND #{project_not_null('new')}"
+ }
+ end
+
+ def project_not_null(row)
+ "(#{row}.project_id IS NOT NULL)"
+ end
+
+ def matches_value(row, column_name, value)
+ "((#{row}.#{column_name})::text = '#{value}'::text)"
+ end
+end
diff --git a/db/post_migrate/20210817024335_prepare_indexes_for_events_bigint_conversion.rb b/db/post_migrate/20210817024335_prepare_indexes_for_events_bigint_conversion.rb
new file mode 100644
index 00000000000..1d102d6216c
--- /dev/null
+++ b/db/post_migrate/20210817024335_prepare_indexes_for_events_bigint_conversion.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+class PrepareIndexesForEventsBigintConversion < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ TABLE_NAME = 'events'
+
+ def up
+ prepare_async_index TABLE_NAME, :id_convert_to_bigint, unique: true,
+ name: :index_events_on_id_convert_to_bigint
+
+ prepare_async_index TABLE_NAME, [:project_id, :id_convert_to_bigint],
+ name: :index_events_on_project_id_and_id_convert_to_bigint
+
+ prepare_async_index TABLE_NAME, [:project_id, :id_convert_to_bigint], order: { id_convert_to_bigint: :desc },
+ where: 'action = 7', name: :index_events_on_project_id_and_id_bigint_desc_on_merged_action
+ end
+
+ def down
+ unprepare_async_index_by_name TABLE_NAME, :index_events_on_id_convert_to_bigint
+ unprepare_async_index_by_name TABLE_NAME, :index_events_on_project_id_and_id_convert_to_bigint
+ unprepare_async_index_by_name TABLE_NAME, :index_events_on_project_id_and_id_bigint_desc_on_merged_action
+ end
+end
diff --git a/db/post_migrate/20210818185845_backfill_projects_with_coverage.rb b/db/post_migrate/20210818185845_backfill_projects_with_coverage.rb
new file mode 100644
index 00000000000..003b7536767
--- /dev/null
+++ b/db/post_migrate/20210818185845_backfill_projects_with_coverage.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+class BackfillProjectsWithCoverage < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ MIGRATION = 'BackfillProjectsWithCoverage'
+ DELAY_INTERVAL = 2.minutes
+ BATCH_SIZE = 10_000
+ SUB_BATCH_SIZE = 1_000
+
+ disable_ddl_transaction!
+
+ class CiDailyBuildGroupReportResult < ActiveRecord::Base
+ include EachBatch
+
+ self.table_name = 'ci_daily_build_group_report_results'
+ end
+
+ def up
+ queue_background_migration_jobs_by_range_at_intervals(
+ CiDailyBuildGroupReportResult,
+ MIGRATION,
+ DELAY_INTERVAL,
+ batch_size: BATCH_SIZE,
+ other_job_arguments: [SUB_BATCH_SIZE]
+ )
+ end
+
+ def down
+ # noop
+ end
+end
diff --git a/db/post_migrate/20210819145000_drop_temporary_columns_and_triggers_for_ci_builds_runner_session.rb b/db/post_migrate/20210819145000_drop_temporary_columns_and_triggers_for_ci_builds_runner_session.rb
new file mode 100644
index 00000000000..bbcee556020
--- /dev/null
+++ b/db/post_migrate/20210819145000_drop_temporary_columns_and_triggers_for_ci_builds_runner_session.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+class DropTemporaryColumnsAndTriggersForCiBuildsRunnerSession < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ TABLE = 'ci_builds_runner_session'
+ TEMPORARY_COLUMN = 'build_id_convert_to_bigint'
+ MAIN_COLUMN = 'build_id'
+
+ # rubocop:disable Migration/WithLockRetriesDisallowedMethod
+ def up
+ with_lock_retries do
+ cleanup_conversion_of_integer_to_bigint(TABLE, MAIN_COLUMN)
+ end
+ end
+
+ def down
+ check_trigger_permissions!(TABLE)
+
+ with_lock_retries do
+ add_column(TABLE, TEMPORARY_COLUMN, :int, default: 0, null: false)
+ install_rename_triggers(TABLE, MAIN_COLUMN, TEMPORARY_COLUMN)
+ end
+ end
+ # rubocop:enable Migration/WithLockRetriesDisallowedMethod
+end
diff --git a/db/post_migrate/20210823113259_steal_merge_request_diff_commit_users_migration.rb b/db/post_migrate/20210823113259_steal_merge_request_diff_commit_users_migration.rb
new file mode 100644
index 00000000000..7e893d62c28
--- /dev/null
+++ b/db/post_migrate/20210823113259_steal_merge_request_diff_commit_users_migration.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+# See https://docs.gitlab.com/ee/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class StealMergeRequestDiffCommitUsersMigration < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ def up
+ job = Gitlab::Database::BackgroundMigrationJob
+ .for_migration_class('MigrateMergeRequestDiffCommitUsers')
+ .pending
+ .last
+
+ return unless job
+
+ # We schedule in one hour so we don't end up running the migrations while a
+ # deployment is still wrapping up. Not that that really matters, but it
+ # prevents from too much happening during a deployment window.
+ migrate_in(1.hour, 'StealMigrateMergeRequestDiffCommitUsers', job.arguments)
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20210823132600_remove_duplicate_dast_site_tokens.rb b/db/post_migrate/20210823132600_remove_duplicate_dast_site_tokens.rb
new file mode 100644
index 00000000000..35cf3b55200
--- /dev/null
+++ b/db/post_migrate/20210823132600_remove_duplicate_dast_site_tokens.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+class RemoveDuplicateDastSiteTokens < ActiveRecord::Migration[6.1]
+ disable_ddl_transaction!
+
+ class DastSiteToken < ApplicationRecord
+ self.table_name = 'dast_site_tokens'
+ self.inheritance_column = :_type_disabled
+
+ scope :duplicates, -> do
+ all_duplicates = select(:project_id, :url)
+ .distinct
+ .group(:project_id, :url)
+ .having('count(*) > 1')
+ .pluck('array_agg(id) as ids')
+
+ duplicate_ids = extract_duplicate_ids(all_duplicates)
+
+ where(id: duplicate_ids)
+ end
+
+ def self.extract_duplicate_ids(duplicates)
+ duplicates.flat_map { |ids| ids.first(ids.size - 1) }
+ end
+ end
+
+ def up
+ DastSiteToken.duplicates.delete_all
+ end
+
+ def down
+ end
+end
diff --git a/db/post_migrate/20210823142036_drop_temporary_trigger_for_ci_job_artifacts.rb b/db/post_migrate/20210823142036_drop_temporary_trigger_for_ci_job_artifacts.rb
new file mode 100644
index 00000000000..42b25a192d5
--- /dev/null
+++ b/db/post_migrate/20210823142036_drop_temporary_trigger_for_ci_job_artifacts.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+class DropTemporaryTriggerForCiJobArtifacts < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ TABLE = 'ci_job_artifacts'
+ TEMPORARY_COLUMNS = %w(id_convert_to_bigint job_id_convert_to_bigint)
+ MAIN_COLUMNS = %w(id job_id)
+ TRIGGER = 'trigger_be1804f21693'
+
+ # rubocop:disable Migration/WithLockRetriesDisallowedMethod
+ def up
+ check_trigger_permissions!(TABLE)
+
+ with_lock_retries do
+ remove_rename_triggers(TABLE, TRIGGER)
+ end
+ end
+
+ def down
+ check_trigger_permissions!(TABLE)
+
+ with_lock_retries do
+ install_rename_triggers(TABLE, MAIN_COLUMNS, TEMPORARY_COLUMNS, trigger_name: TRIGGER)
+ end
+ end
+ # rubocop:enable Migration/WithLockRetriesDisallowedMethod
+end
diff --git a/db/post_migrate/20210823193234_remove_allow_editing_commit_messages_from_project_settings.rb b/db/post_migrate/20210823193234_remove_allow_editing_commit_messages_from_project_settings.rb
new file mode 100644
index 00000000000..638361d0e83
--- /dev/null
+++ b/db/post_migrate/20210823193234_remove_allow_editing_commit_messages_from_project_settings.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveAllowEditingCommitMessagesFromProjectSettings < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ def up
+ return unless column_exists?(:project_settings, :allow_editing_commit_messages)
+
+ with_lock_retries do
+ remove_column :project_settings, :allow_editing_commit_messages
+ end
+ end
+
+ def down
+ with_lock_retries do
+ add_column :project_settings, :allow_editing_commit_messages, :boolean, default: false, null: false
+ end
+ end
+end
diff --git a/db/post_migrate/20210824102624_add_project_namespace_index_to_project.rb b/db/post_migrate/20210824102624_add_project_namespace_index_to_project.rb
new file mode 100644
index 00000000000..d88a31fca7d
--- /dev/null
+++ b/db/post_migrate/20210824102624_add_project_namespace_index_to_project.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddProjectNamespaceIndexToProject < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_projects_on_project_namespace_id'
+
+ def up
+ add_concurrent_index :projects, :project_namespace_id, name: INDEX_NAME, unique: true
+ end
+
+ def down
+ remove_concurrent_index_by_name :projects, INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20210824102750_add_project_namespace_foreign_key_to_project.rb b/db/post_migrate/20210824102750_add_project_namespace_foreign_key_to_project.rb
new file mode 100644
index 00000000000..5cb42fd61a7
--- /dev/null
+++ b/db/post_migrate/20210824102750_add_project_namespace_foreign_key_to_project.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddProjectNamespaceForeignKeyToProject < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ TARGET_COLUMN = :project_namespace_id
+
+ def up
+ add_concurrent_foreign_key :projects, :namespaces, column: TARGET_COLUMN, on_delete: :cascade
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key_if_exists(:projects, column: TARGET_COLUMN)
+ end
+ end
+end
diff --git a/db/post_migrate/20210824174615_prepare_ci_builds_metadata_and_ci_build_async_indexes.rb b/db/post_migrate/20210824174615_prepare_ci_builds_metadata_and_ci_build_async_indexes.rb
new file mode 100644
index 00000000000..0a0fda7e870
--- /dev/null
+++ b/db/post_migrate/20210824174615_prepare_ci_builds_metadata_and_ci_build_async_indexes.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+class PrepareCiBuildsMetadataAndCiBuildAsyncIndexes < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ def up
+ prepare_async_index :ci_builds_metadata, :id_convert_to_bigint, unique: true,
+ name: :index_ci_builds_metadata_on_id_convert_to_bigint
+
+ prepare_async_index :ci_builds_metadata, :build_id_convert_to_bigint, unique: true,
+ name: :index_ci_builds_metadata_on_build_id_convert_to_bigint
+
+ prepare_async_index :ci_builds_metadata, :build_id_convert_to_bigint, where: 'has_exposed_artifacts IS TRUE',
+ name: :index_ci_builds_metadata_on_build_id_int8_and_exposed_artifacts
+
+ prepare_async_index_from_sql(:ci_builds_metadata, :index_ci_builds_metadata_on_build_id_int8_where_interruptible, <<~SQL.squish)
+ CREATE INDEX CONCURRENTLY "index_ci_builds_metadata_on_build_id_int8_where_interruptible"
+ ON "ci_builds_metadata" ("build_id_convert_to_bigint") INCLUDE ("id_convert_to_bigint")
+ WHERE interruptible = true
+ SQL
+
+ prepare_async_index :ci_builds, :id_convert_to_bigint, unique: true,
+ name: :index_ci_builds_on_converted_id
+ end
+
+ def down
+ unprepare_async_index_by_name :ci_builds, :index_ci_builds_on_converted_id
+
+ unprepare_async_index_by_name :ci_builds_metadata, :index_ci_builds_metadata_on_build_id_int8_where_interruptible
+
+ unprepare_async_index_by_name :ci_builds_metadata, :index_ci_builds_metadata_on_build_id_int8_and_exposed_artifacts
+
+ unprepare_async_index_by_name :ci_builds_metadata, :index_ci_builds_metadata_on_build_id_convert_to_bigint
+
+ unprepare_async_index_by_name :ci_builds_metadata, :index_ci_builds_metadata_on_id_convert_to_bigint
+ end
+
+ private
+
+ def prepare_async_index_from_sql(table_name, index_name, definition)
+ return unless async_index_creation_available?
+
+ return if index_name_exists?(table_name, index_name)
+
+ async_index = Gitlab::Database::AsyncIndexes::PostgresAsyncIndex.safe_find_or_create_by!(name: index_name) do |rec|
+ rec.table_name = table_name
+ rec.definition = definition
+ end
+
+ Gitlab::AppLogger.info(
+ message: 'Prepared index for async creation',
+ table_name: async_index.table_name,
+ index_name: async_index.name)
+ end
+end
diff --git a/db/post_migrate/20210825150212_cleanup_remaining_orphan_invites.rb b/db/post_migrate/20210825150212_cleanup_remaining_orphan_invites.rb
new file mode 100644
index 00000000000..d892e6897af
--- /dev/null
+++ b/db/post_migrate/20210825150212_cleanup_remaining_orphan_invites.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class CleanupRemainingOrphanInvites < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ TMP_INDEX_NAME = 'tmp_idx_members_with_orphaned_invites'
+
+ QUERY_CONDITION = "invite_token IS NOT NULL AND user_id IS NOT NULL"
+
+ def up
+ membership = define_batchable_model('members')
+
+ add_concurrent_index :members, :id, where: QUERY_CONDITION, name: TMP_INDEX_NAME
+
+ membership.where(QUERY_CONDITION).pluck(:id).each_slice(10) do |group|
+ membership.where(id: group).where(QUERY_CONDITION).update_all(invite_token: nil)
+ end
+
+ remove_concurrent_index_by_name :members, TMP_INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :members, TMP_INDEX_NAME if index_exists_by_name?(:members, TMP_INDEX_NAME)
+ end
+end
diff --git a/db/post_migrate/20210825182303_remove_duplicate_dast_site_tokens_with_same_token.rb b/db/post_migrate/20210825182303_remove_duplicate_dast_site_tokens_with_same_token.rb
new file mode 100644
index 00000000000..4d8e18ba8ed
--- /dev/null
+++ b/db/post_migrate/20210825182303_remove_duplicate_dast_site_tokens_with_same_token.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class RemoveDuplicateDastSiteTokensWithSameToken < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ INDEX_NAME = 'index_dast_site_token_on_token'
+
+ # rubocop: disable Migration/AddIndex
+ def up
+ execute("WITH duplicate_tokens AS(
+ SELECT id, rank() OVER (PARTITION BY token ORDER BY id) r FROM dast_site_tokens
+ )
+ DELETE FROM dast_site_tokens c USING duplicate_tokens t
+ WHERE c.id = t.id AND t.r > 1;")
+
+ add_index :dast_site_tokens, :token, name: INDEX_NAME, unique: true
+ end
+
+ # rubocop: disable Migration/RemoveIndex
+ def down
+ remove_index :dast_site_tokens, :token, name: INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20210825193548_add_fk_to_iteration_cadence_id_on_boards.rb b/db/post_migrate/20210825193548_add_fk_to_iteration_cadence_id_on_boards.rb
new file mode 100644
index 00000000000..eb879d9bc7a
--- /dev/null
+++ b/db/post_migrate/20210825193548_add_fk_to_iteration_cadence_id_on_boards.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddFkToIterationCadenceIdOnBoards < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_boards_on_iteration_cadence_id'
+
+ def up
+ add_concurrent_index :boards, :iteration_cadence_id, name: INDEX_NAME
+ add_concurrent_foreign_key :boards, :iterations_cadences, column: :iteration_cadence_id
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key_if_exists :boards, column: :iteration_cadence_id
+ end
+ remove_concurrent_index_by_name :boards, INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20210825193652_backfill_cadence_id_for_boards_scoped_to_iteration.rb b/db/post_migrate/20210825193652_backfill_cadence_id_for_boards_scoped_to_iteration.rb
new file mode 100644
index 00000000000..f350fbe3d12
--- /dev/null
+++ b/db/post_migrate/20210825193652_backfill_cadence_id_for_boards_scoped_to_iteration.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+class BackfillCadenceIdForBoardsScopedToIteration < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ BATCH_SIZE = 1000
+ DELAY = 2.minutes.to_i
+ MIGRATION = 'BackfillIterationCadenceIdForBoards'
+
+ class MigrationBoard < ApplicationRecord
+ include EachBatch
+
+ self.table_name = 'boards'
+ end
+
+ def up
+ schedule_backfill_group_boards
+ schedule_backfill_project_boards
+ end
+
+ def down
+ MigrationBoard.where.not(iteration_cadence_id: nil).each_batch(of: BATCH_SIZE) do |batch, index|
+ range = batch.pluck(Arel.sql('MIN(id)'), Arel.sql('MAX(id)')).first
+ delay = index * DELAY
+
+ migrate_in(delay, MIGRATION, ['none', 'down', *range])
+ end
+ end
+
+ private
+
+ def schedule_backfill_project_boards
+ MigrationBoard.where(iteration_id: -4).where.not(project_id: nil).where(iteration_cadence_id: nil).each_batch(of: BATCH_SIZE) do |batch, index|
+ range = batch.pluck(Arel.sql('MIN(id)'), Arel.sql('MAX(id)')).first
+ delay = index * DELAY
+
+ migrate_in(delay, MIGRATION, ['project', 'up', *range])
+ end
+ end
+
+ def schedule_backfill_group_boards
+ MigrationBoard.where(iteration_id: -4).where.not(group_id: nil).where(iteration_cadence_id: nil).each_batch(of: BATCH_SIZE) do |batch, index|
+ range = batch.pluck(Arel.sql('MIN(id)'), Arel.sql('MAX(id)')).first
+ delay = index * DELAY
+
+ migrate_in(delay, MIGRATION, ['group', 'up', *range])
+ end
+ end
+end
diff --git a/db/post_migrate/20210826110839_prepare_indexes_for_ci_job_artifacts_expire_at_unlocked.rb b/db/post_migrate/20210826110839_prepare_indexes_for_ci_job_artifacts_expire_at_unlocked.rb
new file mode 100644
index 00000000000..e11bb25d83c
--- /dev/null
+++ b/db/post_migrate/20210826110839_prepare_indexes_for_ci_job_artifacts_expire_at_unlocked.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class PrepareIndexesForCiJobArtifactsExpireAtUnlocked < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ TABLE_NAME = 'ci_job_artifacts'
+ INDEX_NAME = 'ci_job_artifacts_expire_at_unlocked_idx'
+
+ def up
+ prepare_async_index TABLE_NAME, [:expire_at], where: 'locked = 0', name: INDEX_NAME
+ end
+
+ def down
+ unprepare_async_index_by_name TABLE_NAME, INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20210826171758_initialize_throttle_unauthenticated_api_columns.rb b/db/post_migrate/20210826171758_initialize_throttle_unauthenticated_api_columns.rb
new file mode 100644
index 00000000000..7615931464b
--- /dev/null
+++ b/db/post_migrate/20210826171758_initialize_throttle_unauthenticated_api_columns.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+# Initialize the new `throttle_unauthenticated_api_*` columns with the current values
+# from the `throttle_unauthenticated_*` columns, which will now only apply to web requests.
+#
+# The columns for the unauthenticated web rate limit will be renamed later
+# in https://gitlab.com/gitlab-org/gitlab/-/issues/340031.
+class InitializeThrottleUnauthenticatedApiColumns < ActiveRecord::Migration[6.1]
+ class ApplicationSetting < ActiveRecord::Base
+ self.table_name = :application_settings
+ end
+
+ def up
+ ApplicationSetting.update_all(%q{
+ throttle_unauthenticated_api_enabled = throttle_unauthenticated_enabled,
+ throttle_unauthenticated_api_requests_per_period = throttle_unauthenticated_requests_per_period,
+ throttle_unauthenticated_api_period_in_seconds = throttle_unauthenticated_period_in_seconds
+ })
+ end
+
+ def down
+ end
+end
diff --git a/db/post_migrate/20210826193907_add_unique_index_dast_site_token_project_id_and_url.rb b/db/post_migrate/20210826193907_add_unique_index_dast_site_token_project_id_and_url.rb
new file mode 100644
index 00000000000..1e65d5647e4
--- /dev/null
+++ b/db/post_migrate/20210826193907_add_unique_index_dast_site_token_project_id_and_url.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddUniqueIndexDastSiteTokenProjectIdAndUrl < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_dast_site_token_on_project_id_and_url'
+
+ def up
+ add_concurrent_index :dast_site_tokens, [:project_id, :url], name: INDEX_NAME, unique: true
+ end
+
+ def down
+ remove_concurrent_index_by_name :dast_site_tokens, name: INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20210830104800_reschedule_extract_project_topics_into_separate_table.rb b/db/post_migrate/20210830104800_reschedule_extract_project_topics_into_separate_table.rb
new file mode 100644
index 00000000000..d6b2db7790f
--- /dev/null
+++ b/db/post_migrate/20210830104800_reschedule_extract_project_topics_into_separate_table.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class RescheduleExtractProjectTopicsIntoSeparateTable < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ MIGRATION = 'ExtractProjectTopicsIntoSeparateTable'
+ DELAY_INTERVAL = 4.minutes
+
+ disable_ddl_transaction!
+
+ def up
+ requeue_background_migration_jobs_by_range_at_intervals(MIGRATION, DELAY_INTERVAL)
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20210831123008_drop_temporary_trigger_for_ci_sources_pipelines.rb b/db/post_migrate/20210831123008_drop_temporary_trigger_for_ci_sources_pipelines.rb
new file mode 100644
index 00000000000..a3fe0e6bd7a
--- /dev/null
+++ b/db/post_migrate/20210831123008_drop_temporary_trigger_for_ci_sources_pipelines.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+class DropTemporaryTriggerForCiSourcesPipelines < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ TABLE = 'ci_sources_pipelines'
+ TEMPORARY_COLUMN = 'source_job_id_convert_to_bigint'
+ MAIN_COLUMN = 'source_job_id'
+ TRIGGER = 'trigger_8485e97c00e3'
+
+ # rubocop:disable Migration/WithLockRetriesDisallowedMethod
+ def up
+ check_trigger_permissions!(TABLE)
+
+ with_lock_retries do
+ remove_rename_triggers(TABLE, TRIGGER)
+ end
+ end
+
+ def down
+ check_trigger_permissions!(TABLE)
+
+ with_lock_retries do
+ install_rename_triggers(TABLE, MAIN_COLUMN, TEMPORARY_COLUMN, trigger_name: TRIGGER)
+ end
+ end
+ # rubocop:enable Migration/WithLockRetriesDisallowedMethod
+end
diff --git a/db/post_migrate/20210901044202_push_event_payloads_bigint_conversion_remove_triggers.rb b/db/post_migrate/20210901044202_push_event_payloads_bigint_conversion_remove_triggers.rb
new file mode 100644
index 00000000000..e11f0d46563
--- /dev/null
+++ b/db/post_migrate/20210901044202_push_event_payloads_bigint_conversion_remove_triggers.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+class PushEventPayloadsBigintConversionRemoveTriggers < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ TABLE_NAME = :push_event_payloads
+ TRIGGER_NAME = 'trigger_07c94931164e'
+
+ # rubocop:disable Migration/WithLockRetriesDisallowedMethod
+ def up
+ check_trigger_permissions!(TABLE_NAME)
+
+ with_lock_retries do
+ remove_rename_triggers(TABLE_NAME, TRIGGER_NAME)
+ end
+ end
+
+ def down
+ check_trigger_permissions!(TABLE_NAME)
+
+ with_lock_retries do
+ install_rename_triggers(TABLE_NAME, :event_id, :event_id_convert_to_bigint, trigger_name: TRIGGER_NAME)
+ end
+ end
+ # rubocop:enable Migration/WithLockRetriesDisallowedMethod
+end
diff --git a/db/post_migrate/20210901044237_events_bigint_conversion_remove_triggers.rb b/db/post_migrate/20210901044237_events_bigint_conversion_remove_triggers.rb
new file mode 100644
index 00000000000..bfe3af2efa8
--- /dev/null
+++ b/db/post_migrate/20210901044237_events_bigint_conversion_remove_triggers.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+class EventsBigintConversionRemoveTriggers < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ TABLE_NAME = :events
+ TRIGGER_NAME = :trigger_69523443cc10
+
+ # rubocop:disable Migration/WithLockRetriesDisallowedMethod
+ def up
+ check_trigger_permissions!(TABLE_NAME)
+
+ with_lock_retries do
+ remove_rename_triggers(TABLE_NAME, TRIGGER_NAME)
+ end
+ end
+
+ def down
+ check_trigger_permissions!(TABLE_NAME)
+
+ with_lock_retries do
+ install_rename_triggers(TABLE_NAME, :id, :id_convert_to_bigint, trigger_name: TRIGGER_NAME)
+ end
+ end
+ # rubocop:enable Migration/WithLockRetriesDisallowedMethod
+end
diff --git a/db/post_migrate/20210901153324_slice_merge_request_diff_commit_migrations.rb b/db/post_migrate/20210901153324_slice_merge_request_diff_commit_migrations.rb
new file mode 100644
index 00000000000..8ee7feae1a6
--- /dev/null
+++ b/db/post_migrate/20210901153324_slice_merge_request_diff_commit_migrations.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+class SliceMergeRequestDiffCommitMigrations < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ BATCH_SIZE = 5_000
+ MIGRATION_CLASS = 'MigrateMergeRequestDiffCommitUsers'
+ STEAL_MIGRATION_CLASS = 'StealMigrateMergeRequestDiffCommitUsers'
+
+ def up
+ old_jobs = Gitlab::Database::BackgroundMigrationJob
+ .for_migration_class(MIGRATION_CLASS)
+ .pending
+ .to_a
+
+ return if old_jobs.empty?
+
+ transaction do
+ # This ensures we stop processing the old ranges, as the background
+ # migrations skip already processed jobs.
+ Gitlab::Database::BackgroundMigrationJob
+ .for_migration_class(MIGRATION_CLASS)
+ .pending
+ .update_all(status: :succeeded)
+
+ rows = []
+
+ old_jobs.each do |job|
+ min, max = job.arguments
+
+ while min < max
+ rows << {
+ class_name: MIGRATION_CLASS,
+ arguments: [min, min + BATCH_SIZE],
+ created_at: Time.now.utc,
+ updated_at: Time.now.utc
+ }
+
+ min += BATCH_SIZE
+ end
+ end
+
+ Gitlab::Database::BackgroundMigrationJob.insert_all!(rows)
+ end
+
+ job = Gitlab::Database::BackgroundMigrationJob
+ .for_migration_class(MIGRATION_CLASS)
+ .pending
+ .first
+
+ migrate_in(1.hour, STEAL_MIGRATION_CLASS, job.arguments)
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20210901184511_prepare_async_indexes_for_ci_builds.rb b/db/post_migrate/20210901184511_prepare_async_indexes_for_ci_builds.rb
new file mode 100644
index 00000000000..47795c5d646
--- /dev/null
+++ b/db/post_migrate/20210901184511_prepare_async_indexes_for_ci_builds.rb
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+class PrepareAsyncIndexesForCiBuilds < Gitlab::Database::Migration[1.0]
+ def up
+ prepare_async_index :ci_builds, :stage_id_convert_to_bigint, name: :index_ci_builds_on_converted_stage_id
+
+ prepare_async_index :ci_builds, [:commit_id, :artifacts_expire_at, :id_convert_to_bigint],
+ where: "type::text = 'Ci::Build'::text
+ AND (retried = false OR retried IS NULL)
+ AND (name::text = ANY (ARRAY['sast'::character varying::text,
+ 'secret_detection'::character varying::text,
+ 'dependency_scanning'::character varying::text,
+ 'container_scanning'::character varying::text,
+ 'dast'::character varying::text]))",
+ name: :index_ci_builds_on_commit_id_expire_at_and_converted_id
+
+ prepare_async_index :ci_builds, [:project_id, :id_convert_to_bigint],
+ name: :index_ci_builds_on_project_and_converted_id
+
+ prepare_async_index :ci_builds, [:runner_id, :id_convert_to_bigint],
+ order: { id_convert_to_bigint: :desc },
+ name: :index_ci_builds_on_runner_id_and_converted_id_desc
+
+ prepare_async_index :ci_builds, [:resource_group_id, :id_convert_to_bigint],
+ where: 'resource_group_id IS NOT NULL',
+ name: :index_ci_builds_on_resource_group_and_converted_id
+
+ prepare_async_index :ci_builds, [:name, :id_convert_to_bigint],
+ where: "(name::text = ANY (ARRAY['container_scanning'::character varying::text,
+ 'dast'::character varying::text,
+ 'dependency_scanning'::character varying::text,
+ 'license_management'::character varying::text,
+ 'sast'::character varying::text,
+ 'secret_detection'::character varying::text,
+ 'coverage_fuzzing'::character varying::text,
+ 'license_scanning'::character varying::text])
+ ) AND type::text = 'Ci::Build'::text",
+ name: :index_security_ci_builds_on_name_and_converted_id_parser
+
+ prepare_async_index_from_sql(:ci_builds, :index_ci_builds_runner_id_and_converted_id_pending_covering, <<~SQL.squish)
+ CREATE INDEX CONCURRENTLY index_ci_builds_runner_id_and_converted_id_pending_covering
+ ON ci_builds (runner_id, id_convert_to_bigint) INCLUDE (project_id)
+ WHERE status::text = 'pending'::text AND type::text = 'Ci::Build'::text
+ SQL
+ end
+
+ def down
+ unprepare_async_index_by_name :ci_builds, :index_ci_builds_runner_id_and_converted_id_pending_covering
+
+ unprepare_async_index_by_name :ci_builds, :index_security_ci_builds_on_name_and_converted_id_parser
+
+ unprepare_async_index_by_name :ci_builds, :index_ci_builds_on_resource_group_and_converted_id
+
+ unprepare_async_index_by_name :ci_builds, :index_ci_builds_on_runner_id_and_converted_id_desc
+
+ unprepare_async_index_by_name :ci_builds, :index_ci_builds_on_project_and_converted_id
+
+ unprepare_async_index_by_name :ci_builds, :index_ci_builds_on_commit_id_expire_at_and_converted_id
+
+ unprepare_async_index_by_name :ci_builds, :index_ci_builds_on_converted_stage_id
+ end
+
+ private
+
+ def prepare_async_index_from_sql(table_name, index_name, definition)
+ return unless async_index_creation_available?
+
+ return if index_name_exists?(table_name, index_name)
+
+ async_index = Gitlab::Database::AsyncIndexes::PostgresAsyncIndex.find_or_create_by!(name: index_name) do |rec|
+ rec.table_name = table_name
+ rec.definition = definition
+ end
+
+ Gitlab::AppLogger.info(
+ message: 'Prepared index for async creation',
+ table_name: async_index.table_name,
+ index_name: async_index.name)
+ end
+end
diff --git a/db/post_migrate/20210902144144_drop_temporary_columns_and_triggers_for_ci_build_needs.rb b/db/post_migrate/20210902144144_drop_temporary_columns_and_triggers_for_ci_build_needs.rb
new file mode 100644
index 00000000000..f04c5cd6561
--- /dev/null
+++ b/db/post_migrate/20210902144144_drop_temporary_columns_and_triggers_for_ci_build_needs.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+class DropTemporaryColumnsAndTriggersForCiBuildNeeds < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ TABLE = 'ci_build_needs'
+ TEMPORARY_COLUMN = 'build_id_convert_to_bigint'
+ MAIN_COLUMN = 'build_id'
+
+ # rubocop:disable Migration/WithLockRetriesDisallowedMethod
+ def up
+ with_lock_retries do
+ cleanup_conversion_of_integer_to_bigint(TABLE, MAIN_COLUMN)
+ end
+ end
+
+ def down
+ check_trigger_permissions!(TABLE)
+
+ with_lock_retries do
+ add_column(TABLE, TEMPORARY_COLUMN, :int, default: 0, null: false)
+ install_rename_triggers(TABLE, MAIN_COLUMN, TEMPORARY_COLUMN)
+ end
+ end
+ # rubocop:enable Migration/WithLockRetriesDisallowedMethod
+end
diff --git a/db/post_migrate/20210906100316_drop_temporary_columns_and_triggers_for_ci_build_trace_chunks.rb b/db/post_migrate/20210906100316_drop_temporary_columns_and_triggers_for_ci_build_trace_chunks.rb
new file mode 100644
index 00000000000..44bec402cae
--- /dev/null
+++ b/db/post_migrate/20210906100316_drop_temporary_columns_and_triggers_for_ci_build_trace_chunks.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class DropTemporaryColumnsAndTriggersForCiBuildTraceChunks < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ TABLE = 'ci_build_trace_chunks'
+ COLUMN = 'build_id'
+
+ # rubocop:disable Migration/WithLockRetriesDisallowedMethod
+ def up
+ with_lock_retries do
+ cleanup_conversion_of_integer_to_bigint(TABLE, COLUMN)
+ end
+ end
+ # rubocop:enable Migration/WithLockRetriesDisallowedMethod
+
+ def down
+ restore_conversion_of_integer_to_bigint(TABLE, COLUMN)
+ end
+end
diff --git a/db/post_migrate/20210907021940_cleanup_bigint_conversion_for_ci_stages.rb b/db/post_migrate/20210907021940_cleanup_bigint_conversion_for_ci_stages.rb
new file mode 100644
index 00000000000..096b5b3bf42
--- /dev/null
+++ b/db/post_migrate/20210907021940_cleanup_bigint_conversion_for_ci_stages.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class CleanupBigintConversionForCiStages < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ TABLE = :ci_stages
+
+ # rubocop:disable Migration/WithLockRetriesDisallowedMethod
+ def up
+ with_lock_retries do
+ cleanup_conversion_of_integer_to_bigint(TABLE, :id)
+ end
+ end
+ # rubocop:enable Migration/WithLockRetriesDisallowedMethod
+
+ def down
+ restore_conversion_of_integer_to_bigint(TABLE, :id)
+ end
+end
diff --git a/db/post_migrate/20210907033745_cleanup_bigint_conversion_for_deployments.rb b/db/post_migrate/20210907033745_cleanup_bigint_conversion_for_deployments.rb
new file mode 100644
index 00000000000..2d71c11cfa8
--- /dev/null
+++ b/db/post_migrate/20210907033745_cleanup_bigint_conversion_for_deployments.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class CleanupBigintConversionForDeployments < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ TABLE = :deployments
+
+ # rubocop:disable Migration/WithLockRetriesDisallowedMethod
+ def up
+ with_lock_retries do
+ cleanup_conversion_of_integer_to_bigint(TABLE, :deployable_id)
+ end
+ end
+ # rubocop:enable Migration/WithLockRetriesDisallowedMethod
+
+ def down
+ restore_conversion_of_integer_to_bigint(TABLE, :deployable_id)
+ end
+end
diff --git a/db/post_migrate/20210907041000_cleanup_bigint_conversion_for_geo_job_artifact_deleted_events.rb b/db/post_migrate/20210907041000_cleanup_bigint_conversion_for_geo_job_artifact_deleted_events.rb
new file mode 100644
index 00000000000..26f00454029
--- /dev/null
+++ b/db/post_migrate/20210907041000_cleanup_bigint_conversion_for_geo_job_artifact_deleted_events.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class CleanupBigintConversionForGeoJobArtifactDeletedEvents < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ TABLE = :geo_job_artifact_deleted_events
+
+ # rubocop:disable Migration/WithLockRetriesDisallowedMethod
+ def up
+ with_lock_retries do
+ cleanup_conversion_of_integer_to_bigint(TABLE, :job_artifact_id)
+ end
+ end
+ # rubocop:enable Migration/WithLockRetriesDisallowedMethod
+
+ def down
+ restore_conversion_of_integer_to_bigint(TABLE, :job_artifact_id)
+ end
+end
diff --git a/db/post_migrate/20210907211557_finalize_ci_builds_bigint_conversion.rb b/db/post_migrate/20210907211557_finalize_ci_builds_bigint_conversion.rb
new file mode 100644
index 00000000000..872eef5fd31
--- /dev/null
+++ b/db/post_migrate/20210907211557_finalize_ci_builds_bigint_conversion.rb
@@ -0,0 +1,222 @@
+# frozen_string_literal: true
+
+class FinalizeCiBuildsBigintConversion < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ TABLE_NAME = 'ci_builds'
+ PK_INDEX_NAME = 'index_ci_builds_on_converted_id'
+
+ SECONDARY_INDEXES = [
+ {
+ original_name: :index_ci_builds_on_commit_id_artifacts_expired_at_and_id,
+ temporary_name: :index_ci_builds_on_commit_id_expire_at_and_converted_id,
+ columns: [:commit_id, :artifacts_expire_at, :id_convert_to_bigint],
+ options: {
+ where: "type::text = 'Ci::Build'::text
+ AND (retried = false OR retried IS NULL)
+ AND (name::text = ANY (ARRAY['sast'::character varying::text,
+ 'secret_detection'::character varying::text,
+ 'dependency_scanning'::character varying::text,
+ 'container_scanning'::character varying::text,
+ 'dast'::character varying::text]))"
+ }
+ },
+ {
+ original_name: :index_ci_builds_on_project_id_and_id,
+ temporary_name: :index_ci_builds_on_project_and_converted_id,
+ columns: [:project_id, :id_convert_to_bigint],
+ options: {}
+ },
+ {
+ original_name: :index_ci_builds_on_runner_id_and_id_desc,
+ temporary_name: :index_ci_builds_on_runner_id_and_converted_id_desc,
+ columns: [:runner_id, :id_convert_to_bigint],
+ options: { order: { id_convert_to_bigint: :desc } }
+ },
+ {
+ original_name: :index_for_resource_group,
+ temporary_name: :index_ci_builds_on_resource_group_and_converted_id,
+ columns: [:resource_group_id, :id_convert_to_bigint],
+ options: { where: 'resource_group_id IS NOT NULL' }
+ },
+ {
+ original_name: :index_security_ci_builds_on_name_and_id_parser_features,
+ temporary_name: :index_security_ci_builds_on_name_and_converted_id_parser,
+ columns: [:name, :id_convert_to_bigint],
+ options: {
+ where: "(name::text = ANY (ARRAY['container_scanning'::character varying::text,
+ 'dast'::character varying::text,
+ 'dependency_scanning'::character varying::text,
+ 'license_management'::character varying::text,
+ 'sast'::character varying::text,
+ 'secret_detection'::character varying::text,
+ 'coverage_fuzzing'::character varying::text,
+ 'license_scanning'::character varying::text])
+ ) AND type::text = 'Ci::Build'::text"
+ }
+ }
+ ].freeze
+
+ MANUAL_INDEX_NAMES = {
+ original_name: :index_ci_builds_runner_id_pending_covering,
+ temporary_name: :index_ci_builds_runner_id_and_converted_id_pending_covering
+ }.freeze
+
+ REFERENCING_FOREIGN_KEYS = [
+ [:ci_build_needs, :build_id, :cascade, 'fk_rails_'],
+ [:ci_build_pending_states, :build_id, :cascade, 'fk_rails_'],
+ [:ci_build_report_results, :build_id, :cascade, 'fk_rails_'],
+ [:ci_build_trace_chunks, :build_id, :cascade, 'fk_rails_'],
+ [:ci_build_trace_metadata, :build_id, :cascade, 'fk_rails_'],
+ [:ci_builds_runner_session, :build_id, :cascade, 'fk_rails_'],
+ [:ci_builds_metadata, :build_id, :cascade, 'fk_'],
+ [:ci_job_artifacts, :job_id, :cascade, 'fk_rails_'],
+ [:ci_job_variables, :job_id, :cascade, 'fk_rails_'],
+ [:ci_pending_builds, :build_id, :cascade, 'fk_rails_'],
+ [:ci_resources, :build_id, :nullify, 'fk_'],
+ [:ci_running_builds, :build_id, :cascade, 'fk_rails_'],
+ [:ci_sources_pipelines, :source_job_id, :cascade, 'fk_'],
+ [:ci_unit_test_failures, :build_id, :cascade, 'fk_'],
+ [:dast_scanner_profiles_builds, :ci_build_id, :cascade, 'fk_'],
+ [:dast_site_profiles_builds, :ci_build_id, :cascade, 'fk_'],
+ [:pages_deployments, :ci_build_id, :nullify, 'fk_rails_'],
+ [:requirements_management_test_reports, :build_id, :nullify, 'fk_rails_'],
+ [:security_scans, :build_id, :cascade, 'fk_rails_'],
+ [:terraform_state_versions, :ci_build_id, :nullify, 'fk_']
+ ].freeze
+
+ def up
+ ensure_batched_background_migration_is_finished(
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: TABLE_NAME,
+ column_name: 'id',
+ job_arguments: [%w[id stage_id], %w[id_convert_to_bigint stage_id_convert_to_bigint]]
+ )
+
+ # Remove this upfront since this table is being dropped, and doesn't need to be migrated
+ if foreign_key_exists?(:dep_ci_build_trace_sections, TABLE_NAME, column: :build_id)
+ remove_foreign_key(:dep_ci_build_trace_sections, TABLE_NAME, column: :build_id)
+ end
+
+ # Remove this unexpected FK if it exists - https://gitlab.com/gitlab-com/gl-infra/production/-/issues/5531#note_676576081
+ if foreign_key_exists?(:ci_resources, TABLE_NAME, column: :build_id, name: 'fk_rails_e169a8e3d5')
+ remove_foreign_key(:ci_resources, TABLE_NAME, column: :build_id, name: 'fk_rails_e169a8e3d5')
+ end
+
+ swap_columns
+ end
+
+ def down
+ swap_columns
+ end
+
+ private
+
+ def swap_columns
+ # Copy existing indexes from the original column to the new column
+ create_indexes
+ # Copy existing FKs from the original column to the new column
+ create_referencing_foreign_keys
+
+ # Remove existing FKs from the referencing tables, so we don't have to lock on them when we drop the existing PK
+ replace_referencing_foreign_keys
+
+ with_lock_retries(raise_on_exhaustion: true) do
+ quoted_table_name = quote_table_name(TABLE_NAME)
+
+ # Swap the original and new column names
+ temporary_name = 'id_tmp'
+ execute "ALTER TABLE #{quoted_table_name} RENAME COLUMN #{quote_column_name(:id)} TO #{quote_column_name(temporary_name)}"
+ execute "ALTER TABLE #{quoted_table_name} RENAME COLUMN #{quote_column_name(:id_convert_to_bigint)} TO #{quote_column_name(:id)}"
+ execute "ALTER TABLE #{quoted_table_name} RENAME COLUMN #{quote_column_name(temporary_name)} TO #{quote_column_name(:id_convert_to_bigint)}"
+
+ # Reset the function so PG drops the plan cache for the incorrect integer type
+ function_name = Gitlab::Database::UnidirectionalCopyTrigger.on_table(TABLE_NAME)
+ .name([:id, :stage_id], [:id_convert_to_bigint, :stage_id_convert_to_bigint])
+ execute "ALTER FUNCTION #{quote_table_name(function_name)} RESET ALL"
+
+ # Swap defaults of the two columns, and change ownership of the sequence to the new id
+ execute "ALTER SEQUENCE ci_builds_id_seq OWNED BY #{TABLE_NAME}.id"
+ change_column_default TABLE_NAME, :id, -> { "nextval('ci_builds_id_seq'::regclass)" }
+ change_column_default TABLE_NAME, :id_convert_to_bigint, 0
+
+ # Swap the PK constraint from the original column to the new column
+ # We deliberately don't CASCADE here because the old FKs should be removed already
+ execute "ALTER TABLE #{quoted_table_name} DROP CONSTRAINT ci_builds_pkey"
+ rename_index TABLE_NAME, PK_INDEX_NAME, 'ci_builds_pkey'
+ execute "ALTER TABLE #{quoted_table_name} ADD CONSTRAINT ci_builds_pkey PRIMARY KEY USING INDEX ci_builds_pkey"
+
+ # Remove old column indexes and change new column indexes to have the original names
+ rename_secondary_indexes # rubocop:disable Migration/WithLockRetriesDisallowedMethod
+ end
+ end
+
+ def create_indexes
+ add_concurrent_index TABLE_NAME, :id_convert_to_bigint, unique: true, name: PK_INDEX_NAME
+
+ SECONDARY_INDEXES.each do |index_definition|
+ options = index_definition[:options]
+ options[:name] = index_definition[:temporary_name]
+
+ add_concurrent_index(TABLE_NAME, index_definition[:columns], options)
+ end
+
+ unless index_name_exists?(TABLE_NAME, MANUAL_INDEX_NAMES[:temporary_name])
+ execute(<<~SQL)
+ CREATE INDEX CONCURRENTLY #{MANUAL_INDEX_NAMES[:temporary_name]}
+ ON ci_builds (runner_id, id_convert_to_bigint) INCLUDE (project_id)
+ WHERE status::text = 'pending'::text AND type::text = 'Ci::Build'::text
+ SQL
+ end
+ end
+
+ def rename_secondary_indexes
+ (SECONDARY_INDEXES + [MANUAL_INDEX_NAMES]).each do |index_definition|
+ remove_index(TABLE_NAME, name: index_definition[:original_name]) # rubocop:disable Migration/RemoveIndex
+ rename_index(TABLE_NAME, index_definition[:temporary_name], index_definition[:original_name])
+ end
+ end
+
+ def create_referencing_foreign_keys
+ REFERENCING_FOREIGN_KEYS.each do |(from_table, column, on_delete, prefix)|
+ # Don't attempt to create the FK if one already exists from the table to the new column
+ # The check in `add_concurrent_foreign_key` already checks for this, but it looks for the foreign key
+ # with the new name only (containing the `_tmp` suffix).
+ #
+ # Since we might partially rename FKs and re-run the migration, we also have to check and see if a FK exists
+ # on those columns that might not match the `_tmp` name.
+ next if foreign_key_exists?(from_table, TABLE_NAME, column: column, primary_key: :id_convert_to_bigint)
+
+ temporary_name = "#{concurrent_foreign_key_name(from_table, column, prefix: prefix)}_tmp"
+
+ add_concurrent_foreign_key(
+ from_table,
+ TABLE_NAME,
+ column: column,
+ target_column: :id_convert_to_bigint,
+ name: temporary_name,
+ on_delete: on_delete,
+ reverse_lock_order: true)
+ end
+ end
+
+ def replace_referencing_foreign_keys
+ REFERENCING_FOREIGN_KEYS.each do |(from_table, column, _, prefix)|
+ existing_name = concurrent_foreign_key_name(from_table, column, prefix: prefix)
+
+ # Don't attempt to replace the FK unless it exists and points at the original column.
+ # This could happen if the migration is re-run due to failing midway.
+ next unless foreign_key_exists?(from_table, TABLE_NAME, column: column, primary_key: :id, name: existing_name)
+
+ with_lock_retries do
+ # Explicitly lock table in order of parent, child to attempt to avoid deadlocks
+ execute "LOCK TABLE #{TABLE_NAME}, #{from_table} IN ACCESS EXCLUSIVE MODE"
+
+ temporary_name = "#{existing_name}_tmp"
+
+ remove_foreign_key(from_table, TABLE_NAME, column: column, primary_key: :id, name: existing_name)
+ rename_constraint(from_table, temporary_name, existing_name)
+ end
+ end
+ end
+end
diff --git a/db/post_migrate/20210908132335_disable_job_token_scope_when_unused.rb b/db/post_migrate/20210908132335_disable_job_token_scope_when_unused.rb
new file mode 100644
index 00000000000..2e6ad12f928
--- /dev/null
+++ b/db/post_migrate/20210908132335_disable_job_token_scope_when_unused.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+class DisableJobTokenScopeWhenUnused < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ class ProjectCiCdSetting < ApplicationRecord
+ include EachBatch
+
+ self.table_name = 'project_ci_cd_settings'
+ end
+
+ module Ci
+ module JobToken
+ class ProjectScopeLink < ApplicationRecord
+ self.table_name = 'ci_job_token_project_scope_links'
+ end
+ end
+ end
+
+ def up
+ # Disabling job token scope after db/migrate/20210902171808_set_default_job_token_scope_false.rb
+ # if users haven't configured it.
+ ProjectCiCdSetting.each_batch(of: 10_000) do |settings|
+ with_enabled_but_unused_scope(settings).each_batch(of: 500) do |settings_to_update|
+ settings_to_update.update_all(job_token_scope_enabled: false)
+ end
+ end
+ end
+
+ def down
+ # irreversible data migration
+
+ # The migration relies on the state of `job_token_scope_enabled` and
+ # updates it based on whether the feature is used or not.
+ #
+ # The inverse migration would be to set `job_token_scope_enabled: true`
+ # for those projects that have the feature disabled and unused. But there
+ # could be also existing cases where the feature is disabled and unused.
+ # For example, old projects.
+ end
+
+ private
+
+ # The presence of ProjectScopeLinks means that the job token scope
+ # is configured and we need to leave it enabled. Unused job token scope
+ # can be disabled since they weren't configured.
+ def with_enabled_but_unused_scope(settings)
+ settings
+ .where(job_token_scope_enabled: true)
+ .where.not(project_id: Ci::JobToken::ProjectScopeLink.select(:source_project_id))
+ end
+end
diff --git a/db/post_migrate/20210909104800_reschedule_extract_project_topics_into_separate_table_2.rb b/db/post_migrate/20210909104800_reschedule_extract_project_topics_into_separate_table_2.rb
new file mode 100644
index 00000000000..ad31a40f324
--- /dev/null
+++ b/db/post_migrate/20210909104800_reschedule_extract_project_topics_into_separate_table_2.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class RescheduleExtractProjectTopicsIntoSeparateTable2 < Gitlab::Database::Migration[1.0]
+ MIGRATION = 'ExtractProjectTopicsIntoSeparateTable'
+ DELAY_INTERVAL = 4.minutes
+
+ disable_ddl_transaction!
+
+ def up
+ requeue_background_migration_jobs_by_range_at_intervals(MIGRATION, DELAY_INTERVAL)
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20210909152027_remove_container_registry_enabled.rb b/db/post_migrate/20210909152027_remove_container_registry_enabled.rb
new file mode 100644
index 00000000000..d97faaf58d2
--- /dev/null
+++ b/db/post_migrate/20210909152027_remove_container_registry_enabled.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveContainerRegistryEnabled < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ remove_column :projects, :container_registry_enabled
+ end
+ end
+
+ def down
+ with_lock_retries do
+ add_column :projects, :container_registry_enabled, :boolean # rubocop:disable Migration/AddColumnsToWideTables
+ end
+ end
+end
diff --git a/db/post_migrate/20210914094840_add_gin_index_on_pending_builds_namespace_traversal_ids.rb b/db/post_migrate/20210914094840_add_gin_index_on_pending_builds_namespace_traversal_ids.rb
new file mode 100644
index 00000000000..3584c7136e3
--- /dev/null
+++ b/db/post_migrate/20210914094840_add_gin_index_on_pending_builds_namespace_traversal_ids.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddGinIndexOnPendingBuildsNamespaceTraversalIds < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_gin_ci_pending_builds_on_namespace_traversal_ids'
+
+ def up
+ add_concurrent_index :ci_pending_builds, :namespace_traversal_ids, name: INDEX_NAME, using: :gin
+ end
+
+ def down
+ remove_concurrent_index_by_name :ci_pending_builds, INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20210915202900_prepare_index_resource_group_status_commit_id_for_ci_builds.rb b/db/post_migrate/20210915202900_prepare_index_resource_group_status_commit_id_for_ci_builds.rb
new file mode 100644
index 00000000000..42d21806405
--- /dev/null
+++ b/db/post_migrate/20210915202900_prepare_index_resource_group_status_commit_id_for_ci_builds.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class PrepareIndexResourceGroupStatusCommitIdForCiBuilds < Gitlab::Database::Migration[1.0]
+ INDEX_NAME = 'index_ci_builds_on_resource_group_and_status_and_commit_id'
+
+ def up
+ prepare_async_index :ci_builds, [:resource_group_id, :status, :commit_id],
+ where: 'resource_group_id IS NOT NULL',
+ name: INDEX_NAME
+ end
+
+ def down
+ unprepare_async_index_by_name :ci_builds, INDEX_NAME
+ end
+end
diff --git a/db/schema_migrations/20210622045705 b/db/schema_migrations/20210622045705
new file mode 100644
index 00000000000..edf47a46a9d
--- /dev/null
+++ b/db/schema_migrations/20210622045705
@@ -0,0 +1 @@
+8400d4497656a9f3f692528f9c0118e8898f2d4d5b0ebbaa55ebadea15628041 \ No newline at end of file
diff --git a/db/schema_migrations/20210701141346 b/db/schema_migrations/20210701141346
new file mode 100644
index 00000000000..bbc8116361e
--- /dev/null
+++ b/db/schema_migrations/20210701141346
@@ -0,0 +1 @@
+da16754bf484ba9a585f9de055f242dbee311d7cf7d0ce67c834ebaed61b96d4 \ No newline at end of file
diff --git a/db/schema_migrations/20210706112800 b/db/schema_migrations/20210706112800
new file mode 100644
index 00000000000..f1f00867472
--- /dev/null
+++ b/db/schema_migrations/20210706112800
@@ -0,0 +1 @@
+5dd1596d0d6e6f5aa39cbf8a65be294650bead7a099cf50917b438cf75529257 \ No newline at end of file
diff --git a/db/schema_migrations/20210707113056 b/db/schema_migrations/20210707113056
new file mode 100644
index 00000000000..3526caf8109
--- /dev/null
+++ b/db/schema_migrations/20210707113056
@@ -0,0 +1 @@
+837b9a56114c63064379cf276a3c7e2bbe845af9022a542c4fcec94a25062017 \ No newline at end of file
diff --git a/db/schema_migrations/20210707163659 b/db/schema_migrations/20210707163659
new file mode 100644
index 00000000000..e0c33c79a85
--- /dev/null
+++ b/db/schema_migrations/20210707163659
@@ -0,0 +1 @@
+ac14aa49830a3af9a1445c0c7680f5660247a8104c8e4c1ae542c4b368f7c9bf \ No newline at end of file
diff --git a/db/schema_migrations/20210708011425 b/db/schema_migrations/20210708011425
new file mode 100644
index 00000000000..33e28f436ce
--- /dev/null
+++ b/db/schema_migrations/20210708011425
@@ -0,0 +1 @@
+e3f4424daaba173f607dbae7c84b4f6070126d262e7e9808c6a90e64648e10ed \ No newline at end of file
diff --git a/db/schema_migrations/20210708011426 b/db/schema_migrations/20210708011426
new file mode 100644
index 00000000000..abb2743928c
--- /dev/null
+++ b/db/schema_migrations/20210708011426
@@ -0,0 +1 @@
+b48556968cbff2e3aff65236b313ed8a626af4a08b1cad06723b74a99b678895 \ No newline at end of file
diff --git a/db/schema_migrations/20210721122840 b/db/schema_migrations/20210721122840
new file mode 100644
index 00000000000..375a03adc3d
--- /dev/null
+++ b/db/schema_migrations/20210721122840
@@ -0,0 +1 @@
+483ef6f8ef379f39ecff32853c777c12c59d2858f061879c375ff6d429396167 \ No newline at end of file
diff --git a/db/schema_migrations/20210729081351 b/db/schema_migrations/20210729081351
new file mode 100644
index 00000000000..1f397457443
--- /dev/null
+++ b/db/schema_migrations/20210729081351
@@ -0,0 +1 @@
+17463867a8c14981386256dc90169fb879e1921d65eccca53eae576d49fba49d \ No newline at end of file
diff --git a/db/schema_migrations/20210729081739 b/db/schema_migrations/20210729081739
new file mode 100644
index 00000000000..2215c7d7e66
--- /dev/null
+++ b/db/schema_migrations/20210729081739
@@ -0,0 +1 @@
+af7963d27bda6ef85fb5b5a06ecf1de14f21829eecdaf13e763aa9a6ffc2e83c \ No newline at end of file
diff --git a/db/schema_migrations/20210729125641 b/db/schema_migrations/20210729125641
new file mode 100644
index 00000000000..e5ee4127656
--- /dev/null
+++ b/db/schema_migrations/20210729125641
@@ -0,0 +1 @@
+b7bc495d010e0640b1145ca55f47696047fd4360d2dfc9a3da7941ab62840132 \ No newline at end of file
diff --git a/db/schema_migrations/20210729125659 b/db/schema_migrations/20210729125659
new file mode 100644
index 00000000000..64c8cd0aeef
--- /dev/null
+++ b/db/schema_migrations/20210729125659
@@ -0,0 +1 @@
+5826e87b2ce13d4951e9b8e774c87c29c6e0a0954a85d60ec68155f2c5cf3ccc \ No newline at end of file
diff --git a/db/schema_migrations/20210730104800 b/db/schema_migrations/20210730104800
new file mode 100644
index 00000000000..d8e2986e946
--- /dev/null
+++ b/db/schema_migrations/20210730104800
@@ -0,0 +1 @@
+7764c058665015707aff6e25ccbf60d4a329c67c16106b2ef523862ef82298b7 \ No newline at end of file
diff --git a/db/schema_migrations/20210730194555 b/db/schema_migrations/20210730194555
new file mode 100644
index 00000000000..5b2a142779d
--- /dev/null
+++ b/db/schema_migrations/20210730194555
@@ -0,0 +1 @@
+2d0399beca58815197487d310318ed1cb3d8e85671d55581a6256ceac7667b43 \ No newline at end of file
diff --git a/db/schema_migrations/20210731132939 b/db/schema_migrations/20210731132939
new file mode 100644
index 00000000000..f032b0fadad
--- /dev/null
+++ b/db/schema_migrations/20210731132939
@@ -0,0 +1 @@
+97d968bba0eb2bf6faa19de8a3e4fe93dc03a623b623dc802ab0fe0a4afb0370 \ No newline at end of file
diff --git a/db/schema_migrations/20210806131706 b/db/schema_migrations/20210806131706
new file mode 100644
index 00000000000..78be9905398
--- /dev/null
+++ b/db/schema_migrations/20210806131706
@@ -0,0 +1 @@
+2539e3e09682f1d7a0902b495a140151a5debef40623348d3cc552d4ba00722f \ No newline at end of file
diff --git a/db/schema_migrations/20210807101446 b/db/schema_migrations/20210807101446
new file mode 100644
index 00000000000..0b6d526429f
--- /dev/null
+++ b/db/schema_migrations/20210807101446
@@ -0,0 +1 @@
+30e1463616c60b92afb28bbb76e3c55830a385af6df0e60e16ed96d9e75943b9 \ No newline at end of file
diff --git a/db/schema_migrations/20210807101621 b/db/schema_migrations/20210807101621
new file mode 100644
index 00000000000..ab053cf4cbc
--- /dev/null
+++ b/db/schema_migrations/20210807101621
@@ -0,0 +1 @@
+7e9b39914ade766357751953a4981225dbae7e5d371d4824af61b01af70f46ae \ No newline at end of file
diff --git a/db/schema_migrations/20210807102004 b/db/schema_migrations/20210807102004
new file mode 100644
index 00000000000..e63485435f8
--- /dev/null
+++ b/db/schema_migrations/20210807102004
@@ -0,0 +1 @@
+a2454f9fca3b1cedf7a0f2288b69abe799fe1f9ff4e2fe26d2cadfdddea73a83 \ No newline at end of file
diff --git a/db/schema_migrations/20210809014850 b/db/schema_migrations/20210809014850
new file mode 100644
index 00000000000..541d397d169
--- /dev/null
+++ b/db/schema_migrations/20210809014850
@@ -0,0 +1 @@
+6f67e2bba5f42d48a9b21f8ab4d9abf4495ef7e0226ea903d51e77eed85ad0cb \ No newline at end of file
diff --git a/db/schema_migrations/20210809014918 b/db/schema_migrations/20210809014918
new file mode 100644
index 00000000000..099f032c76a
--- /dev/null
+++ b/db/schema_migrations/20210809014918
@@ -0,0 +1 @@
+d282a027d03920a53d49444f54745ab7d2c8bcccc485ac9407ff9dbbef77981f \ No newline at end of file
diff --git a/db/schema_migrations/20210811120204 b/db/schema_migrations/20210811120204
new file mode 100644
index 00000000000..1802d357900
--- /dev/null
+++ b/db/schema_migrations/20210811120204
@@ -0,0 +1 @@
+77d80801402f18e69d17a9f120445fe14d05cec3a93a08341abf89ae81cda5b9 \ No newline at end of file
diff --git a/db/schema_migrations/20210813131313 b/db/schema_migrations/20210813131313
new file mode 100644
index 00000000000..abb03783efe
--- /dev/null
+++ b/db/schema_migrations/20210813131313
@@ -0,0 +1 @@
+5ab51c1fb5bde22123f2d55f6422de0d8d0a84b7a98ce3146cbf491475c97b66 \ No newline at end of file
diff --git a/db/schema_migrations/20210813151908 b/db/schema_migrations/20210813151908
new file mode 100644
index 00000000000..b2d1602658b
--- /dev/null
+++ b/db/schema_migrations/20210813151908
@@ -0,0 +1 @@
+fdb6dd20c1cd5feaf0efd8eb94a4d61fc4812f1142572433ae397cd5f27bf603 \ No newline at end of file
diff --git a/db/schema_migrations/20210816095826 b/db/schema_migrations/20210816095826
new file mode 100644
index 00000000000..079a83fae8f
--- /dev/null
+++ b/db/schema_migrations/20210816095826
@@ -0,0 +1 @@
+d1ad234656f49861d2ca7694d23116e930bba597fca32b1015db698cc23bdc1c \ No newline at end of file
diff --git a/db/schema_migrations/20210816192041 b/db/schema_migrations/20210816192041
new file mode 100644
index 00000000000..d60da5dda39
--- /dev/null
+++ b/db/schema_migrations/20210816192041
@@ -0,0 +1 @@
+7d069706b4379685cfe85a5c65444d139f6f93578ff6ff66759e0a694e119bb4 \ No newline at end of file
diff --git a/db/schema_migrations/20210817024335 b/db/schema_migrations/20210817024335
new file mode 100644
index 00000000000..019ec0a26b7
--- /dev/null
+++ b/db/schema_migrations/20210817024335
@@ -0,0 +1 @@
+360bb1c16c93d7a6564ed70fa2dea4212e1fd00d101cfdc9017b54f67eae797d \ No newline at end of file
diff --git a/db/schema_migrations/20210817130415 b/db/schema_migrations/20210817130415
new file mode 100644
index 00000000000..e8481cb4019
--- /dev/null
+++ b/db/schema_migrations/20210817130415
@@ -0,0 +1 @@
+8c1ec0dfc043861377786bd7731a1a1f994d6f03833f4dcc2ba94ab1ddc83acf \ No newline at end of file
diff --git a/db/schema_migrations/20210817172214 b/db/schema_migrations/20210817172214
new file mode 100644
index 00000000000..5e334c7d690
--- /dev/null
+++ b/db/schema_migrations/20210817172214
@@ -0,0 +1 @@
+d6dd6ce802beeea380e0eb1c564f6a5cbc6d30cb3488a3cb91935e1302a4c387 \ No newline at end of file
diff --git a/db/schema_migrations/20210818061156 b/db/schema_migrations/20210818061156
new file mode 100644
index 00000000000..fba5486b2a8
--- /dev/null
+++ b/db/schema_migrations/20210818061156
@@ -0,0 +1 @@
+23becdc9ad558882f4ce42e76391cdc2f760322a09c998082465fcb6d29dfeb5 \ No newline at end of file
diff --git a/db/schema_migrations/20210818115613 b/db/schema_migrations/20210818115613
new file mode 100644
index 00000000000..efe76d3a46a
--- /dev/null
+++ b/db/schema_migrations/20210818115613
@@ -0,0 +1 @@
+9c5114dac05e90c15567bb3274f20f03a82f9e4d73d5c72d89c26bc9d742cc35 \ No newline at end of file
diff --git a/db/schema_migrations/20210818175949 b/db/schema_migrations/20210818175949
new file mode 100644
index 00000000000..8e316d2dd9c
--- /dev/null
+++ b/db/schema_migrations/20210818175949
@@ -0,0 +1 @@
+0d04487e59b783f0aa88ddd4f79716ae570ba87528b15bd07400aa4b1cef92c1 \ No newline at end of file
diff --git a/db/schema_migrations/20210818185548 b/db/schema_migrations/20210818185548
new file mode 100644
index 00000000000..42826826512
--- /dev/null
+++ b/db/schema_migrations/20210818185548
@@ -0,0 +1 @@
+88ca485c8513df96b1f1aec1585c385223dc53889e547db42b509b0cd1bea9b7 \ No newline at end of file
diff --git a/db/schema_migrations/20210818185845 b/db/schema_migrations/20210818185845
new file mode 100644
index 00000000000..7ed2204aeb6
--- /dev/null
+++ b/db/schema_migrations/20210818185845
@@ -0,0 +1 @@
+dc8ca347fb0c87e1a66389fd9f37fa9702f8bd53237ada40192bb0a875dbe940 \ No newline at end of file
diff --git a/db/schema_migrations/20210818193008 b/db/schema_migrations/20210818193008
new file mode 100644
index 00000000000..aef60a5ab5b
--- /dev/null
+++ b/db/schema_migrations/20210818193008
@@ -0,0 +1 @@
+d24d10134d661728dbe688da2b90da55c584627ca764a6cc4604631f8a5fa334 \ No newline at end of file
diff --git a/db/schema_migrations/20210818200455 b/db/schema_migrations/20210818200455
new file mode 100644
index 00000000000..c476ef5b488
--- /dev/null
+++ b/db/schema_migrations/20210818200455
@@ -0,0 +1 @@
+25eb43de74e7eb158718b19d8cea5da2540507e96fcbe47d4829fa806e773308 \ No newline at end of file
diff --git a/db/schema_migrations/20210818220234 b/db/schema_migrations/20210818220234
new file mode 100644
index 00000000000..e32f27029cf
--- /dev/null
+++ b/db/schema_migrations/20210818220234
@@ -0,0 +1 @@
+8d247218468ad383d1a8a2dc67d5e7e67ddad2a33a38203a41e49c4c018adc7e \ No newline at end of file
diff --git a/db/schema_migrations/20210819120243 b/db/schema_migrations/20210819120243
new file mode 100644
index 00000000000..e31d0ca6414
--- /dev/null
+++ b/db/schema_migrations/20210819120243
@@ -0,0 +1 @@
+5c74d34171ed9129ffbb3efe5417da1ba857cd729837544e58074debd5afca88 \ No newline at end of file
diff --git a/db/schema_migrations/20210819145000 b/db/schema_migrations/20210819145000
new file mode 100644
index 00000000000..56301031459
--- /dev/null
+++ b/db/schema_migrations/20210819145000
@@ -0,0 +1 @@
+a73a33d30af332c8c01cd9d55618a1b84bc9074ffe4d06fd72c8eb37cd264954 \ No newline at end of file
diff --git a/db/schema_migrations/20210819152723 b/db/schema_migrations/20210819152723
new file mode 100644
index 00000000000..b5f4d2795f7
--- /dev/null
+++ b/db/schema_migrations/20210819152723
@@ -0,0 +1 @@
+b311fdb0a6e0e10ca3c67b9b2c3d920f8e735f0fd8398fdaa25853e14f88ae97 \ No newline at end of file
diff --git a/db/schema_migrations/20210819153805 b/db/schema_migrations/20210819153805
new file mode 100644
index 00000000000..fe0d1dcfd69
--- /dev/null
+++ b/db/schema_migrations/20210819153805
@@ -0,0 +1 @@
+195d2444bf9d5113ee589b1accdbf04efbc7fb84c2ead4deed3985b254345e07 \ No newline at end of file
diff --git a/db/schema_migrations/20210819162047 b/db/schema_migrations/20210819162047
new file mode 100644
index 00000000000..c50e07543da
--- /dev/null
+++ b/db/schema_migrations/20210819162047
@@ -0,0 +1 @@
+5a02c5a24bb4c7cb63da2e5cc53ff89461f328d0092bb4bb6589223dc4bdae8c \ No newline at end of file
diff --git a/db/schema_migrations/20210820171834 b/db/schema_migrations/20210820171834
new file mode 100644
index 00000000000..be62c2b9a63
--- /dev/null
+++ b/db/schema_migrations/20210820171834
@@ -0,0 +1 @@
+892a71a3f6fdeb20cb2837a426d6d0931c756f8bf3d647e520a72a0bb6f78309 \ No newline at end of file
diff --git a/db/schema_migrations/20210823113259 b/db/schema_migrations/20210823113259
new file mode 100644
index 00000000000..79f416332d8
--- /dev/null
+++ b/db/schema_migrations/20210823113259
@@ -0,0 +1 @@
+06b44a856fc970f52b19ad8eeb38f885182003eff50ef1524ecf30887f4664d9 \ No newline at end of file
diff --git a/db/schema_migrations/20210823132600 b/db/schema_migrations/20210823132600
new file mode 100644
index 00000000000..85ab3b55ee4
--- /dev/null
+++ b/db/schema_migrations/20210823132600
@@ -0,0 +1 @@
+7324c3803c910338261556c65cae5d0827e78b77890386e402e056d480c3486b \ No newline at end of file
diff --git a/db/schema_migrations/20210823142036 b/db/schema_migrations/20210823142036
new file mode 100644
index 00000000000..ec24927dfcf
--- /dev/null
+++ b/db/schema_migrations/20210823142036
@@ -0,0 +1 @@
+874ed71410406d10ade9c834d1374b039effd9e88514d327d04275e11e837ffb \ No newline at end of file
diff --git a/db/schema_migrations/20210823172643 b/db/schema_migrations/20210823172643
new file mode 100644
index 00000000000..e89e11bb544
--- /dev/null
+++ b/db/schema_migrations/20210823172643
@@ -0,0 +1 @@
+e6570f8ee366431b17b34051b9d0dcf2aff6216f8d65b3b6eec5be5666fed229 \ No newline at end of file
diff --git a/db/schema_migrations/20210823193234 b/db/schema_migrations/20210823193234
new file mode 100644
index 00000000000..d47f1ec567a
--- /dev/null
+++ b/db/schema_migrations/20210823193234
@@ -0,0 +1 @@
+b85ef326056bb152d527e34b49caa3c40ee8685c3b14654992246c6adf082f8c \ No newline at end of file
diff --git a/db/schema_migrations/20210823213417 b/db/schema_migrations/20210823213417
new file mode 100644
index 00000000000..bcd41f479e6
--- /dev/null
+++ b/db/schema_migrations/20210823213417
@@ -0,0 +1 @@
+62496310640493bf9b7f0e1cbe91b170542da3250a1cf482f5e0237d0e8847b1 \ No newline at end of file
diff --git a/db/schema_migrations/20210824055322 b/db/schema_migrations/20210824055322
new file mode 100644
index 00000000000..ed3925f8ac5
--- /dev/null
+++ b/db/schema_migrations/20210824055322
@@ -0,0 +1 @@
+abd298ec9e6d9016c05032504d9ff0de7af9c6a031e0eacb041f29e59e82f289 \ No newline at end of file
diff --git a/db/schema_migrations/20210824102624 b/db/schema_migrations/20210824102624
new file mode 100644
index 00000000000..c736c84f8f8
--- /dev/null
+++ b/db/schema_migrations/20210824102624
@@ -0,0 +1 @@
+f1fc9e062f5100db6a549fffa2fcd78d8eb6854cea388a6ac7addf4f6f232920 \ No newline at end of file
diff --git a/db/schema_migrations/20210824102750 b/db/schema_migrations/20210824102750
new file mode 100644
index 00000000000..520c8365d41
--- /dev/null
+++ b/db/schema_migrations/20210824102750
@@ -0,0 +1 @@
+cc99eb2b40ee88d4d6df07253f599deb26be2fca7b941c5cecb2f8fb7ff3641d \ No newline at end of file
diff --git a/db/schema_migrations/20210824105038 b/db/schema_migrations/20210824105038
new file mode 100644
index 00000000000..24772827b3b
--- /dev/null
+++ b/db/schema_migrations/20210824105038
@@ -0,0 +1 @@
+9fe4e2a3d5c50507220ac8363a9f7975ca1fc87575ee0c2ba8948c6d9bcd7019 \ No newline at end of file
diff --git a/db/schema_migrations/20210824160459 b/db/schema_migrations/20210824160459
new file mode 100644
index 00000000000..afab14f962c
--- /dev/null
+++ b/db/schema_migrations/20210824160459
@@ -0,0 +1 @@
+39924743a04ba01cb85eed5ef88762a6a3e29c56f397a59632ba43e0ccec40b3 \ No newline at end of file
diff --git a/db/schema_migrations/20210824174615 b/db/schema_migrations/20210824174615
new file mode 100644
index 00000000000..56160c801f1
--- /dev/null
+++ b/db/schema_migrations/20210824174615
@@ -0,0 +1 @@
+830cf08352b0d1f0c7f08ea67107466ea1d6a478c6f47d5e19f0ffa6c57f5641 \ No newline at end of file
diff --git a/db/schema_migrations/20210825104558 b/db/schema_migrations/20210825104558
new file mode 100644
index 00000000000..3457bbf1ace
--- /dev/null
+++ b/db/schema_migrations/20210825104558
@@ -0,0 +1 @@
+ab678fb5e8ddf7e6dc84f36248440e94953d7c85ee6a50f4e5c06f32c6ee66ec \ No newline at end of file
diff --git a/db/schema_migrations/20210825104656 b/db/schema_migrations/20210825104656
new file mode 100644
index 00000000000..9f91a3c364f
--- /dev/null
+++ b/db/schema_migrations/20210825104656
@@ -0,0 +1 @@
+c15d736eb441503d321e1bf377edd204aa1b5822ed697cce2934ff87eca441a9 \ No newline at end of file
diff --git a/db/schema_migrations/20210825110016 b/db/schema_migrations/20210825110016
new file mode 100644
index 00000000000..8c1b11653f1
--- /dev/null
+++ b/db/schema_migrations/20210825110016
@@ -0,0 +1 @@
+e9e8444056a114d471f60156ec1e5a96082c7922604f1926c0256eb17986c484 \ No newline at end of file
diff --git a/db/schema_migrations/20210825150212 b/db/schema_migrations/20210825150212
new file mode 100644
index 00000000000..bdd83542199
--- /dev/null
+++ b/db/schema_migrations/20210825150212
@@ -0,0 +1 @@
+5dc6a4f9ecbd705bf8361c65b29931cde94968084e8ae7945a27acdcbd6475c8 \ No newline at end of file
diff --git a/db/schema_migrations/20210825182303 b/db/schema_migrations/20210825182303
new file mode 100644
index 00000000000..af9dc177a72
--- /dev/null
+++ b/db/schema_migrations/20210825182303
@@ -0,0 +1 @@
+a7f4911fcb9ab939a6e5e9a6e5e927fd6828ff062324d8483d78c8f8a4ded4e6 \ No newline at end of file
diff --git a/db/schema_migrations/20210825190458 b/db/schema_migrations/20210825190458
new file mode 100644
index 00000000000..e03c12e4284
--- /dev/null
+++ b/db/schema_migrations/20210825190458
@@ -0,0 +1 @@
+43d152f4235a07111a401be7b52a527571be04861c71381c311d6a48c8574dc9 \ No newline at end of file
diff --git a/db/schema_migrations/20210825193448 b/db/schema_migrations/20210825193448
new file mode 100644
index 00000000000..b62b45b61ae
--- /dev/null
+++ b/db/schema_migrations/20210825193448
@@ -0,0 +1 @@
+d9c7cc7721b28cbd442bf40255ecfbd20d0abf4cd31631c150ebdc05c76062be \ No newline at end of file
diff --git a/db/schema_migrations/20210825193548 b/db/schema_migrations/20210825193548
new file mode 100644
index 00000000000..0255e6719ef
--- /dev/null
+++ b/db/schema_migrations/20210825193548
@@ -0,0 +1 @@
+b97b77aef61db2e51106ac090f5511a67fa85be8f3741f618fe03c8c03ecd88c \ No newline at end of file
diff --git a/db/schema_migrations/20210825193652 b/db/schema_migrations/20210825193652
new file mode 100644
index 00000000000..0ecca0962dc
--- /dev/null
+++ b/db/schema_migrations/20210825193652
@@ -0,0 +1 @@
+fd7aef11635bc4c5d6b9346dbed90f6c114da7b7a33744083e8610f3850e4736 \ No newline at end of file
diff --git a/db/schema_migrations/20210826110839 b/db/schema_migrations/20210826110839
new file mode 100644
index 00000000000..165141ef852
--- /dev/null
+++ b/db/schema_migrations/20210826110839
@@ -0,0 +1 @@
+72b64ddbaf86eb296fe49fd38bea759d5247414142fe1cd11aee7e1d6171e142 \ No newline at end of file
diff --git a/db/schema_migrations/20210826120834 b/db/schema_migrations/20210826120834
new file mode 100644
index 00000000000..ebbdb86049c
--- /dev/null
+++ b/db/schema_migrations/20210826120834
@@ -0,0 +1 @@
+a8cd5165815a2f1e6b825ea3ee2a9bde88c1790f6ebe92296bee6a9a892b83f2 \ No newline at end of file
diff --git a/db/schema_migrations/20210826122748 b/db/schema_migrations/20210826122748
new file mode 100644
index 00000000000..e6d87674da3
--- /dev/null
+++ b/db/schema_migrations/20210826122748
@@ -0,0 +1 @@
+a1290cc671c487a7c24bfdb02c564d656a6606258e680e65ed108e3a28de10ca \ No newline at end of file
diff --git a/db/schema_migrations/20210826124311 b/db/schema_migrations/20210826124311
new file mode 100644
index 00000000000..c63d85f13b7
--- /dev/null
+++ b/db/schema_migrations/20210826124311
@@ -0,0 +1 @@
+2cad14b3b7cb4f958a26cb6d4e76380338b745cc90c2e31c521614ea277c4ee9 \ No newline at end of file
diff --git a/db/schema_migrations/20210826145509 b/db/schema_migrations/20210826145509
new file mode 100644
index 00000000000..9f93b675b12
--- /dev/null
+++ b/db/schema_migrations/20210826145509
@@ -0,0 +1 @@
+661b2f03f2387f0d49cbb11c333ad29c6af5caed1f43e860fa0f263f8e7371c2 \ No newline at end of file
diff --git a/db/schema_migrations/20210826170902 b/db/schema_migrations/20210826170902
new file mode 100644
index 00000000000..f20877de3a5
--- /dev/null
+++ b/db/schema_migrations/20210826170902
@@ -0,0 +1 @@
+97536098a2d3b127c6e6b9c079d10d272552dc9064f6b23fb92482baffaac7db \ No newline at end of file
diff --git a/db/schema_migrations/20210826171758 b/db/schema_migrations/20210826171758
new file mode 100644
index 00000000000..a0bb0f5cfc6
--- /dev/null
+++ b/db/schema_migrations/20210826171758
@@ -0,0 +1 @@
+96a8a87cc075b7a2bf3919d0c891fdfedb2a9b7bab6460b82bfb43a3f8abe3cf \ No newline at end of file
diff --git a/db/schema_migrations/20210826193907 b/db/schema_migrations/20210826193907
new file mode 100644
index 00000000000..417333d7212
--- /dev/null
+++ b/db/schema_migrations/20210826193907
@@ -0,0 +1 @@
+b7916e025131f11da97ab89a01b32d1dbacf94bb96dc84877ba18404c8b0b2ba \ No newline at end of file
diff --git a/db/schema_migrations/20210830085837 b/db/schema_migrations/20210830085837
new file mode 100644
index 00000000000..590ff1fe13b
--- /dev/null
+++ b/db/schema_migrations/20210830085837
@@ -0,0 +1 @@
+cf1a51194961500cb63d848afb1d5ebbf2ef77f54d60957e92c9dd6a667913ea \ No newline at end of file
diff --git a/db/schema_migrations/20210830104800 b/db/schema_migrations/20210830104800
new file mode 100644
index 00000000000..ca1aa9180e2
--- /dev/null
+++ b/db/schema_migrations/20210830104800
@@ -0,0 +1 @@
+84a68304f95ae04b85625c214b28a251014582fb142390ff3df8ea6d6f0947e1 \ No newline at end of file
diff --git a/db/schema_migrations/20210830140524 b/db/schema_migrations/20210830140524
new file mode 100644
index 00000000000..ed07d932278
--- /dev/null
+++ b/db/schema_migrations/20210830140524
@@ -0,0 +1 @@
+54f7c66eed745b62d0b53a407a96721f90392ab7f800db9c8a2607f22974ef3c \ No newline at end of file
diff --git a/db/schema_migrations/20210830154358 b/db/schema_migrations/20210830154358
new file mode 100644
index 00000000000..7486c54c4c5
--- /dev/null
+++ b/db/schema_migrations/20210830154358
@@ -0,0 +1 @@
+04a44d0e261b26cc7f39b81a4c59ea8e4903d6d7bf73c2004b426204db4491bc \ No newline at end of file
diff --git a/db/schema_migrations/20210831123008 b/db/schema_migrations/20210831123008
new file mode 100644
index 00000000000..35a14b2b10b
--- /dev/null
+++ b/db/schema_migrations/20210831123008
@@ -0,0 +1 @@
+36572ad3a4a8a7511512ff45e2a68252950ce852af1b5a28c6b4e4491f97be07 \ No newline at end of file
diff --git a/db/schema_migrations/20210831134840 b/db/schema_migrations/20210831134840
new file mode 100644
index 00000000000..d05a375f8fd
--- /dev/null
+++ b/db/schema_migrations/20210831134840
@@ -0,0 +1 @@
+6cad93bd4c086a60164c3cb5c42737194c4b7b20c1ea9f4c6d998b7c3a8918b5 \ No newline at end of file
diff --git a/db/schema_migrations/20210831135249 b/db/schema_migrations/20210831135249
new file mode 100644
index 00000000000..a08cfa6d8d9
--- /dev/null
+++ b/db/schema_migrations/20210831135249
@@ -0,0 +1 @@
+78b14e92c91e7ccb11b7b37e89e8e55749cf109b0fa5ce06e4e396a2ac743f1c \ No newline at end of file
diff --git a/db/schema_migrations/20210831203408 b/db/schema_migrations/20210831203408
new file mode 100644
index 00000000000..6ab3f810e57
--- /dev/null
+++ b/db/schema_migrations/20210831203408
@@ -0,0 +1 @@
+50a06a2a57ed26c25af53d3d7f6f5ef73efde8a23a36c5f825af56b4d0c4c3f6 \ No newline at end of file
diff --git a/db/schema_migrations/20210901044202 b/db/schema_migrations/20210901044202
new file mode 100644
index 00000000000..8601b0d20a2
--- /dev/null
+++ b/db/schema_migrations/20210901044202
@@ -0,0 +1 @@
+1f070444e77eb56ba612f60ed4a0d90b8a44c4af419a09c873f3bf663c78af72 \ No newline at end of file
diff --git a/db/schema_migrations/20210901044237 b/db/schema_migrations/20210901044237
new file mode 100644
index 00000000000..25418c94441
--- /dev/null
+++ b/db/schema_migrations/20210901044237
@@ -0,0 +1 @@
+0d8caaa078914ed2bd43b383ee2efe50093947d65862c2f4dd8dc960cad0a43e \ No newline at end of file
diff --git a/db/schema_migrations/20210901065504 b/db/schema_migrations/20210901065504
new file mode 100644
index 00000000000..f62e6ce1272
--- /dev/null
+++ b/db/schema_migrations/20210901065504
@@ -0,0 +1 @@
+9724a5fc1703418f9b1ea1d5375fc3b01834b30e5ff16c60537db5cb00bc210a \ No newline at end of file
diff --git a/db/schema_migrations/20210901153324 b/db/schema_migrations/20210901153324
new file mode 100644
index 00000000000..a08982bad39
--- /dev/null
+++ b/db/schema_migrations/20210901153324
@@ -0,0 +1 @@
+34287b86616026b94374856991c793ad869c52badddc09be923984002c6214bd \ No newline at end of file
diff --git a/db/schema_migrations/20210901184511 b/db/schema_migrations/20210901184511
new file mode 100644
index 00000000000..45a3b3b8c18
--- /dev/null
+++ b/db/schema_migrations/20210901184511
@@ -0,0 +1 @@
+40780a28f881d4e80bdb6b023f22804c4da735223323c8cf03cfcdcaf5337fe6 \ No newline at end of file
diff --git a/db/schema_migrations/20210902144144 b/db/schema_migrations/20210902144144
new file mode 100644
index 00000000000..330569f1beb
--- /dev/null
+++ b/db/schema_migrations/20210902144144
@@ -0,0 +1 @@
+c99df310082dd6f5faff3cfd90dfca88af26d840889910ebac0e73ba483a09b2 \ No newline at end of file
diff --git a/db/schema_migrations/20210902171406 b/db/schema_migrations/20210902171406
new file mode 100644
index 00000000000..89635e256ea
--- /dev/null
+++ b/db/schema_migrations/20210902171406
@@ -0,0 +1 @@
+d7be9a34d626e507add67f407a6fa0b45f16b244e8ebeeb071debc538fa25b49 \ No newline at end of file
diff --git a/db/schema_migrations/20210902171808 b/db/schema_migrations/20210902171808
new file mode 100644
index 00000000000..1398c2db4b6
--- /dev/null
+++ b/db/schema_migrations/20210902171808
@@ -0,0 +1 @@
+09b482e4716a2b0808ad83770222baed8e863a8f94f85f77ed2d557eaa348df4 \ No newline at end of file
diff --git a/db/schema_migrations/20210902184334 b/db/schema_migrations/20210902184334
new file mode 100644
index 00000000000..f35699b357e
--- /dev/null
+++ b/db/schema_migrations/20210902184334
@@ -0,0 +1 @@
+508b8d4608d28b2a12cf429262c3dd336e130013a41e51ff6c95027ece1540e5 \ No newline at end of file
diff --git a/db/schema_migrations/20210903054158 b/db/schema_migrations/20210903054158
new file mode 100644
index 00000000000..8810481ab85
--- /dev/null
+++ b/db/schema_migrations/20210903054158
@@ -0,0 +1 @@
+113d6bb813a89646d48c8ba6a86fc8e73f741d5c345f603bfe33939fb90f9428 \ No newline at end of file
diff --git a/db/schema_migrations/20210906100021 b/db/schema_migrations/20210906100021
new file mode 100644
index 00000000000..9ae19276eab
--- /dev/null
+++ b/db/schema_migrations/20210906100021
@@ -0,0 +1 @@
+74f6800c968f80e18aa000df42fd23086404fdd7a863237e453541b7eeb4eb7f \ No newline at end of file
diff --git a/db/schema_migrations/20210906100316 b/db/schema_migrations/20210906100316
new file mode 100644
index 00000000000..4ce17059b07
--- /dev/null
+++ b/db/schema_migrations/20210906100316
@@ -0,0 +1 @@
+b7329d4ff7ee651b56cb86c7091e0d933c4f43a77125323fb6c283eedcb737c2 \ No newline at end of file
diff --git a/db/schema_migrations/20210907021940 b/db/schema_migrations/20210907021940
new file mode 100644
index 00000000000..c6392fca8de
--- /dev/null
+++ b/db/schema_migrations/20210907021940
@@ -0,0 +1 @@
+53d1dee0bbe106eeaad3eda6e8012475cf4b59d30f78020c8d2ecf3499ff7e0f \ No newline at end of file
diff --git a/db/schema_migrations/20210907033745 b/db/schema_migrations/20210907033745
new file mode 100644
index 00000000000..23d1c138824
--- /dev/null
+++ b/db/schema_migrations/20210907033745
@@ -0,0 +1 @@
+d02cc8e136f1d761a34c7c585a3fe2b8c3bc3bca67e0e45f950248a5fad36a24 \ No newline at end of file
diff --git a/db/schema_migrations/20210907041000 b/db/schema_migrations/20210907041000
new file mode 100644
index 00000000000..9b7b3d4b14c
--- /dev/null
+++ b/db/schema_migrations/20210907041000
@@ -0,0 +1 @@
+23d4d2d037cd70c5b810824a837b45f016a3be5d112938123c1da08416f667cd \ No newline at end of file
diff --git a/db/schema_migrations/20210907182337 b/db/schema_migrations/20210907182337
new file mode 100644
index 00000000000..cc3d32067c2
--- /dev/null
+++ b/db/schema_migrations/20210907182337
@@ -0,0 +1 @@
+ad564a1fda815473b09f1eda469e67cdd8f532b9b481f7e8ae3ddb8f2df6ee40 \ No newline at end of file
diff --git a/db/schema_migrations/20210907182359 b/db/schema_migrations/20210907182359
new file mode 100644
index 00000000000..41e72e9dfec
--- /dev/null
+++ b/db/schema_migrations/20210907182359
@@ -0,0 +1 @@
+da57784c8c7f8bcb3c8c61089b5a695efdb31b209cb1616af68240380c734669 \ No newline at end of file
diff --git a/db/schema_migrations/20210907211557 b/db/schema_migrations/20210907211557
new file mode 100644
index 00000000000..e89552729ba
--- /dev/null
+++ b/db/schema_migrations/20210907211557
@@ -0,0 +1 @@
+387dcbda7c3b32050298d8a679361a17916a66d0ab686211f0d1a0dc708c4a74 \ No newline at end of file
diff --git a/db/schema_migrations/20210908060951 b/db/schema_migrations/20210908060951
new file mode 100644
index 00000000000..cd4ed794cc5
--- /dev/null
+++ b/db/schema_migrations/20210908060951
@@ -0,0 +1 @@
+716fad7f9005a40d0c6a3acb8e348c7e9459a6a619fc0bf085f231f328f19fd1 \ No newline at end of file
diff --git a/db/schema_migrations/20210908061132 b/db/schema_migrations/20210908061132
new file mode 100644
index 00000000000..a5b7e482228
--- /dev/null
+++ b/db/schema_migrations/20210908061132
@@ -0,0 +1 @@
+f9e14410f22c94d0500102bb0fd0a3a6bd27343b74810b852ceb1349a04be72d \ No newline at end of file
diff --git a/db/schema_migrations/20210908100810 b/db/schema_migrations/20210908100810
new file mode 100644
index 00000000000..a8c9023a1cc
--- /dev/null
+++ b/db/schema_migrations/20210908100810
@@ -0,0 +1 @@
+06e45cf159cf1182b34e83f893bcff65e4722dded2bf4cbcf61fafd652158823 \ No newline at end of file
diff --git a/db/schema_migrations/20210908132335 b/db/schema_migrations/20210908132335
new file mode 100644
index 00000000000..864d6ccc942
--- /dev/null
+++ b/db/schema_migrations/20210908132335
@@ -0,0 +1 @@
+399e35197111c257786a2bdf5dac990a26f48d2cc8493de642dcfa47ddececd2 \ No newline at end of file
diff --git a/db/schema_migrations/20210908140437 b/db/schema_migrations/20210908140437
new file mode 100644
index 00000000000..fec99dfe6fd
--- /dev/null
+++ b/db/schema_migrations/20210908140437
@@ -0,0 +1 @@
+a8dc6d1fecf7b26182dd89f4dae088fb315774ff4720c282f608bd0c45c75a41 \ No newline at end of file
diff --git a/db/schema_migrations/20210908185736 b/db/schema_migrations/20210908185736
new file mode 100644
index 00000000000..826ec2b44e8
--- /dev/null
+++ b/db/schema_migrations/20210908185736
@@ -0,0 +1 @@
+4e9a585d33caed70c3e003e4f0127158ab9c98c790f8131012f052c2bd9cd1f0 \ No newline at end of file
diff --git a/db/schema_migrations/20210908185754 b/db/schema_migrations/20210908185754
new file mode 100644
index 00000000000..53b9efc22d4
--- /dev/null
+++ b/db/schema_migrations/20210908185754
@@ -0,0 +1 @@
+fc70f26e1d691773728e8e2251b23fe39247fc233996c2161143c660a92fe141 \ No newline at end of file
diff --git a/db/schema_migrations/20210909104800 b/db/schema_migrations/20210909104800
new file mode 100644
index 00000000000..70ad28d72b8
--- /dev/null
+++ b/db/schema_migrations/20210909104800
@@ -0,0 +1 @@
+834825de758314db01a3daa2d2b943c11751553705c4dd078f2087b9ec6ff7f7 \ No newline at end of file
diff --git a/db/schema_migrations/20210909152027 b/db/schema_migrations/20210909152027
new file mode 100644
index 00000000000..39db0c43aa6
--- /dev/null
+++ b/db/schema_migrations/20210909152027
@@ -0,0 +1 @@
+abed3f9a6c188890d3dcd21f73a09347f8ccec0f6cc448220fadba5cbda17281 \ No newline at end of file
diff --git a/db/schema_migrations/20210909184349 b/db/schema_migrations/20210909184349
new file mode 100644
index 00000000000..5997ddc46cf
--- /dev/null
+++ b/db/schema_migrations/20210909184349
@@ -0,0 +1 @@
+6be3a6f8f748d8f02e2d42cd1a5103ec8bd5c17097d9e440b152685fc8d6ff83 \ No newline at end of file
diff --git a/db/schema_migrations/20210910141043 b/db/schema_migrations/20210910141043
new file mode 100644
index 00000000000..ccb687b8bda
--- /dev/null
+++ b/db/schema_migrations/20210910141043
@@ -0,0 +1 @@
+3885d2fca4166e71610cd957f1c5a703118cbb5ba47a8d494eb4e017fe499a7d \ No newline at end of file
diff --git a/db/schema_migrations/20210913010411 b/db/schema_migrations/20210913010411
new file mode 100644
index 00000000000..8ae59414604
--- /dev/null
+++ b/db/schema_migrations/20210913010411
@@ -0,0 +1 @@
+71d51d1ac74f5c559bf41b23e5677af7228ba824da835afbe0f2299695912c19 \ No newline at end of file
diff --git a/db/schema_migrations/20210913010432 b/db/schema_migrations/20210913010432
new file mode 100644
index 00000000000..db2f53a8d06
--- /dev/null
+++ b/db/schema_migrations/20210913010432
@@ -0,0 +1 @@
+172e77890657dd82c6ce770c286894731f6ef7fbcffb4b4fc97e0a41d132b8e8 \ No newline at end of file
diff --git a/db/schema_migrations/20210913122457 b/db/schema_migrations/20210913122457
new file mode 100644
index 00000000000..e8f322c64c8
--- /dev/null
+++ b/db/schema_migrations/20210913122457
@@ -0,0 +1 @@
+031fb794e4fa3d54098596defd9de6fb1e507e01bd8f02462c0079e7e59c3416 \ No newline at end of file
diff --git a/db/schema_migrations/20210914094840 b/db/schema_migrations/20210914094840
new file mode 100644
index 00000000000..51d46c05ae6
--- /dev/null
+++ b/db/schema_migrations/20210914094840
@@ -0,0 +1 @@
+994de4d18202a420a7184cabe787f6e3f872900147df0cd848731483e6d87566 \ No newline at end of file
diff --git a/db/schema_migrations/20210915202900 b/db/schema_migrations/20210915202900
new file mode 100644
index 00000000000..bbe7f918f7a
--- /dev/null
+++ b/db/schema_migrations/20210915202900
@@ -0,0 +1 @@
+cc8f1bea8c722dfa06fc23a3dbaaacd7f1b7c5f7b529ebfab34b7c7c38e5db79 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index eee73636eb1..d7e00112d73 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -10,57 +10,37 @@ CREATE EXTENSION IF NOT EXISTS btree_gist;
CREATE EXTENSION IF NOT EXISTS pg_trgm;
-CREATE FUNCTION integrations_set_type_new() RETURNS trigger
+CREATE FUNCTION delete_associated_project_namespace() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
-WITH mapping(old_type, new_type) AS (VALUES
- ('AsanaService', 'Integrations::Asana'),
- ('AssemblaService', 'Integrations::Assembla'),
- ('BambooService', 'Integrations::Bamboo'),
- ('BugzillaService', 'Integrations::Bugzilla'),
- ('BuildkiteService', 'Integrations::Buildkite'),
- ('CampfireService', 'Integrations::Campfire'),
- ('ConfluenceService', 'Integrations::Confluence'),
- ('CustomIssueTrackerService', 'Integrations::CustomIssueTracker'),
- ('DatadogService', 'Integrations::Datadog'),
- ('DiscordService', 'Integrations::Discord'),
- ('DroneCiService', 'Integrations::DroneCi'),
- ('EmailsOnPushService', 'Integrations::EmailsOnPush'),
- ('EwmService', 'Integrations::Ewm'),
- ('ExternalWikiService', 'Integrations::ExternalWiki'),
- ('FlowdockService', 'Integrations::Flowdock'),
- ('HangoutsChatService', 'Integrations::HangoutsChat'),
- ('IrkerService', 'Integrations::Irker'),
- ('JenkinsService', 'Integrations::Jenkins'),
- ('JiraService', 'Integrations::Jira'),
- ('MattermostService', 'Integrations::Mattermost'),
- ('MattermostSlashCommandsService', 'Integrations::MattermostSlashCommands'),
- ('MicrosoftTeamsService', 'Integrations::MicrosoftTeams'),
- ('MockCiService', 'Integrations::MockCi'),
- ('MockMonitoringService', 'Integrations::MockMonitoring'),
- ('PackagistService', 'Integrations::Packagist'),
- ('PipelinesEmailService', 'Integrations::PipelinesEmail'),
- ('PivotaltrackerService', 'Integrations::Pivotaltracker'),
- ('PrometheusService', 'Integrations::Prometheus'),
- ('PushoverService', 'Integrations::Pushover'),
- ('RedmineService', 'Integrations::Redmine'),
- ('SlackService', 'Integrations::Slack'),
- ('SlackSlashCommandsService', 'Integrations::SlackSlashCommands'),
- ('TeamcityService', 'Integrations::Teamcity'),
- ('UnifyCircuitService', 'Integrations::UnifyCircuit'),
- ('YoutrackService', 'Integrations::Youtrack'),
- ('WebexTeamsService', 'Integrations::WebexTeams'),
-
- -- EE-only integrations
- ('GithubService', 'Integrations::Github'),
- ('GitlabSlackApplicationService', 'Integrations::GitlabSlackApplication')
-)
+DELETE FROM namespaces
+WHERE namespaces.id = OLD.project_namespace_id AND
+namespaces.type = 'Project';
+RETURN NULL;
+
+END
+$$;
-UPDATE integrations SET type_new = mapping.new_type
-FROM mapping
-WHERE integrations.id = NEW.id
- AND mapping.old_type = NEW.type;
+CREATE FUNCTION insert_into_loose_foreign_keys_deleted_records() RETURNS trigger
+ LANGUAGE plpgsql
+ AS $$
+BEGIN
+ INSERT INTO loose_foreign_keys_deleted_records
+ (deleted_table_name, deleted_table_primary_key_value)
+ SELECT TG_TABLE_NAME, old_table.id FROM old_table
+ ON CONFLICT DO NOTHING;
+
+ RETURN NULL;
+END
+$$;
+
+CREATE FUNCTION integrations_set_type_new() RETURNS trigger
+ LANGUAGE plpgsql
+ AS $$
+BEGIN
+UPDATE integrations SET type_new = regexp_replace(NEW.type, '\A(.+)Service\Z', 'Integrations::\1')
+WHERE integrations.id = NEW.id;
RETURN NULL;
END
@@ -97,24 +77,6 @@ RETURN NULL;
END
$$;
-CREATE FUNCTION trigger_07c94931164e() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
-BEGIN
- NEW."event_id_convert_to_bigint" := NEW."event_id";
- RETURN NEW;
-END;
-$$;
-
-CREATE FUNCTION trigger_21e7a2602957() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
-BEGIN
- NEW."build_id_convert_to_bigint" := NEW."build_id";
- RETURN NEW;
-END;
-$$;
-
CREATE FUNCTION trigger_3f6129be01d2() RETURNS trigger
LANGUAGE plpgsql
AS $$
@@ -125,24 +87,6 @@ BEGIN
END;
$$;
-CREATE FUNCTION trigger_490d204c00b3() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
-BEGIN
- NEW."id_convert_to_bigint" := NEW."id";
- RETURN NEW;
-END;
-$$;
-
-CREATE FUNCTION trigger_51ab7cef8934() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
-BEGIN
- NEW."build_id_convert_to_bigint" := NEW."build_id";
- RETURN NEW;
-END;
-$$;
-
CREATE FUNCTION trigger_542d6c2ad72e() RETURNS trigger
LANGUAGE plpgsql
AS $$
@@ -152,33 +96,6 @@ BEGIN
END;
$$;
-CREATE FUNCTION trigger_69523443cc10() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
-BEGIN
- NEW."id_convert_to_bigint" := NEW."id";
- RETURN NEW;
-END;
-$$;
-
-CREATE FUNCTION trigger_77f5e1d20482() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
-BEGIN
- NEW."deployable_id_convert_to_bigint" := NEW."deployable_id";
- RETURN NEW;
-END;
-$$;
-
-CREATE FUNCTION trigger_8485e97c00e3() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
-BEGIN
- NEW."source_job_id_convert_to_bigint" := NEW."source_job_id";
- RETURN NEW;
-END;
-$$;
-
CREATE FUNCTION trigger_8487d4de3e7b() RETURNS trigger
LANGUAGE plpgsql
AS $$
@@ -207,34 +124,6 @@ BEGIN
END;
$$;
-CREATE FUNCTION trigger_be1804f21693() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
-BEGIN
- NEW."id_convert_to_bigint" := NEW."id";
- NEW."job_id_convert_to_bigint" := NEW."job_id";
- RETURN NEW;
-END;
-$$;
-
-CREATE FUNCTION trigger_cf2f9e35f002() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
-BEGIN
- NEW."build_id_convert_to_bigint" := NEW."build_id";
- RETURN NEW;
-END;
-$$;
-
-CREATE FUNCTION trigger_f1ca8ec18d78() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
-BEGIN
- NEW."job_artifact_id_convert_to_bigint" := NEW."job_artifact_id";
- RETURN NEW;
-END;
-$$;
-
CREATE TABLE audit_events (
id bigint NOT NULL,
author_id integer NOT NULL,
@@ -267,6 +156,24 @@ CREATE TABLE incident_management_pending_alert_escalations (
)
PARTITION BY RANGE (process_at);
+CREATE TABLE incident_management_pending_issue_escalations (
+ id bigint NOT NULL,
+ rule_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ process_at timestamp with time zone NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL
+)
+PARTITION BY RANGE (process_at);
+
+CREATE TABLE loose_foreign_keys_deleted_records (
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ deleted_table_name text NOT NULL,
+ deleted_table_primary_key_value bigint NOT NULL,
+ CONSTRAINT check_7229f9527e CHECK ((char_length(deleted_table_name) <= 63))
+)
+PARTITION BY RANGE (created_at);
+
CREATE TABLE web_hook_logs (
id bigint NOT NULL,
web_hook_id integer NOT NULL,
@@ -284,6 +191,798 @@ CREATE TABLE web_hook_logs (
)
PARTITION BY RANGE (created_at);
+CREATE TABLE analytics_cycle_analytics_issue_stage_events (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+)
+PARTITION BY HASH (stage_event_hash_id);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_00 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_00 FOR VALUES WITH (modulus 32, remainder 0);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_01 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_01 FOR VALUES WITH (modulus 32, remainder 1);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_02 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_02 FOR VALUES WITH (modulus 32, remainder 2);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_03 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_03 FOR VALUES WITH (modulus 32, remainder 3);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_04 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_04 FOR VALUES WITH (modulus 32, remainder 4);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_05 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_05 FOR VALUES WITH (modulus 32, remainder 5);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_06 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_06 FOR VALUES WITH (modulus 32, remainder 6);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_07 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_07 FOR VALUES WITH (modulus 32, remainder 7);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_08 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_08 FOR VALUES WITH (modulus 32, remainder 8);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_09 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_09 FOR VALUES WITH (modulus 32, remainder 9);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_10 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_10 FOR VALUES WITH (modulus 32, remainder 10);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_11 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_11 FOR VALUES WITH (modulus 32, remainder 11);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_12 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_12 FOR VALUES WITH (modulus 32, remainder 12);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_13 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_13 FOR VALUES WITH (modulus 32, remainder 13);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_14 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_14 FOR VALUES WITH (modulus 32, remainder 14);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_15 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_15 FOR VALUES WITH (modulus 32, remainder 15);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_16 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_16 FOR VALUES WITH (modulus 32, remainder 16);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_17 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_17 FOR VALUES WITH (modulus 32, remainder 17);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_18 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_18 FOR VALUES WITH (modulus 32, remainder 18);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_19 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_19 FOR VALUES WITH (modulus 32, remainder 19);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_20 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_20 FOR VALUES WITH (modulus 32, remainder 20);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_21 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_21 FOR VALUES WITH (modulus 32, remainder 21);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_22 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_22 FOR VALUES WITH (modulus 32, remainder 22);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_23 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_23 FOR VALUES WITH (modulus 32, remainder 23);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_24 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_24 FOR VALUES WITH (modulus 32, remainder 24);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_25 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_25 FOR VALUES WITH (modulus 32, remainder 25);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_26 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_26 FOR VALUES WITH (modulus 32, remainder 26);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_27 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_27 FOR VALUES WITH (modulus 32, remainder 27);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_28 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_28 FOR VALUES WITH (modulus 32, remainder 28);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_29 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_29 FOR VALUES WITH (modulus 32, remainder 29);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_30 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_30 FOR VALUES WITH (modulus 32, remainder 30);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_31 (
+ stage_event_hash_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_31 FOR VALUES WITH (modulus 32, remainder 31);
+
+CREATE TABLE analytics_cycle_analytics_merge_request_stage_events (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+)
+PARTITION BY HASH (stage_event_hash_id);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_00 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_00 FOR VALUES WITH (modulus 32, remainder 0);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_01 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_01 FOR VALUES WITH (modulus 32, remainder 1);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_02 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_02 FOR VALUES WITH (modulus 32, remainder 2);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_03 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_03 FOR VALUES WITH (modulus 32, remainder 3);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_04 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_04 FOR VALUES WITH (modulus 32, remainder 4);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_05 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_05 FOR VALUES WITH (modulus 32, remainder 5);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_06 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_06 FOR VALUES WITH (modulus 32, remainder 6);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_07 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_07 FOR VALUES WITH (modulus 32, remainder 7);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_08 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_08 FOR VALUES WITH (modulus 32, remainder 8);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_09 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_09 FOR VALUES WITH (modulus 32, remainder 9);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_10 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_10 FOR VALUES WITH (modulus 32, remainder 10);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_11 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_11 FOR VALUES WITH (modulus 32, remainder 11);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_12 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_12 FOR VALUES WITH (modulus 32, remainder 12);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_13 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_13 FOR VALUES WITH (modulus 32, remainder 13);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_14 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_14 FOR VALUES WITH (modulus 32, remainder 14);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_15 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_15 FOR VALUES WITH (modulus 32, remainder 15);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_16 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_16 FOR VALUES WITH (modulus 32, remainder 16);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_17 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_17 FOR VALUES WITH (modulus 32, remainder 17);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_18 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_18 FOR VALUES WITH (modulus 32, remainder 18);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_19 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_19 FOR VALUES WITH (modulus 32, remainder 19);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_20 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_20 FOR VALUES WITH (modulus 32, remainder 20);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_21 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_21 FOR VALUES WITH (modulus 32, remainder 21);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_22 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_22 FOR VALUES WITH (modulus 32, remainder 22);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_23 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_23 FOR VALUES WITH (modulus 32, remainder 23);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_24 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_24 FOR VALUES WITH (modulus 32, remainder 24);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_25 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_25 FOR VALUES WITH (modulus 32, remainder 25);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_26 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_26 FOR VALUES WITH (modulus 32, remainder 26);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_27 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_27 FOR VALUES WITH (modulus 32, remainder 27);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_28 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_28 FOR VALUES WITH (modulus 32, remainder 28);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_29 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_29 FOR VALUES WITH (modulus 32, remainder 29);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_30 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_30 FOR VALUES WITH (modulus 32, remainder 30);
+
+CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_31 (
+ stage_event_hash_id bigint NOT NULL,
+ merge_request_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ milestone_id bigint,
+ author_id bigint,
+ start_event_timestamp timestamp with time zone NOT NULL,
+ end_event_timestamp timestamp with time zone
+);
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_31 FOR VALUES WITH (modulus 32, remainder 31);
+
CREATE TABLE product_analytics_events_experimental (
id bigint NOT NULL,
project_id integer NOT NULL,
@@ -8958,6 +9657,38 @@ CREATE SEQUENCE abuse_reports_id_seq
ALTER SEQUENCE abuse_reports_id_seq OWNED BY abuse_reports.id;
+CREATE TABLE agent_group_authorizations (
+ id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ agent_id bigint NOT NULL,
+ config jsonb NOT NULL
+);
+
+CREATE SEQUENCE agent_group_authorizations_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE agent_group_authorizations_id_seq OWNED BY agent_group_authorizations.id;
+
+CREATE TABLE agent_project_authorizations (
+ id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ agent_id bigint NOT NULL,
+ config jsonb NOT NULL
+);
+
+CREATE SEQUENCE agent_project_authorizations_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE agent_project_authorizations_id_seq OWNED BY agent_project_authorizations.id;
+
CREATE TABLE alert_management_alert_assignees (
id bigint NOT NULL,
user_id bigint NOT NULL,
@@ -9086,7 +9817,8 @@ CREATE TABLE analytics_cycle_analytics_group_stages (
custom boolean DEFAULT true NOT NULL,
name character varying(255) NOT NULL,
group_value_stream_id bigint NOT NULL,
- stage_event_hash_id bigint
+ stage_event_hash_id bigint,
+ CONSTRAINT check_e6bd4271b5 CHECK ((stage_event_hash_id IS NOT NULL))
);
CREATE SEQUENCE analytics_cycle_analytics_group_stages_id_seq
@@ -9130,7 +9862,8 @@ CREATE TABLE analytics_cycle_analytics_project_stages (
custom boolean DEFAULT true NOT NULL,
name character varying(255) NOT NULL,
project_value_stream_id bigint NOT NULL,
- stage_event_hash_id bigint
+ stage_event_hash_id bigint,
+ CONSTRAINT check_8f6019de1e CHECK ((stage_event_hash_id IS NOT NULL))
);
CREATE SEQUENCE analytics_cycle_analytics_project_stages_id_seq
@@ -9524,7 +10257,6 @@ CREATE TABLE application_settings (
email_restrictions_enabled boolean DEFAULT false NOT NULL,
email_restrictions text,
npm_package_requests_forwarding boolean DEFAULT true NOT NULL,
- seat_link_enabled boolean DEFAULT true NOT NULL,
container_expiration_policies_enable_historic_entries boolean DEFAULT false NOT NULL,
issues_create_limit integer DEFAULT 0 NOT NULL,
push_rule_id bigint,
@@ -9580,7 +10312,6 @@ CREATE TABLE application_settings (
encrypted_cloud_license_auth_token text,
encrypted_cloud_license_auth_token_iv text,
secret_detection_revocation_token_types_url text,
- cloud_license_enabled boolean DEFAULT false NOT NULL,
disable_feed_token boolean DEFAULT false NOT NULL,
personal_access_token_prefix text,
rate_limiting_response_text text,
@@ -9625,9 +10356,30 @@ CREATE TABLE application_settings (
encrypted_customers_dot_jwt_signing_key bytea,
encrypted_customers_dot_jwt_signing_key_iv bytea,
pypi_package_requests_forwarding boolean DEFAULT true NOT NULL,
+ throttle_unauthenticated_files_api_requests_per_period integer DEFAULT 125 NOT NULL,
+ throttle_unauthenticated_files_api_period_in_seconds integer DEFAULT 15 NOT NULL,
+ throttle_authenticated_files_api_requests_per_period integer DEFAULT 500 NOT NULL,
+ throttle_authenticated_files_api_period_in_seconds integer DEFAULT 15 NOT NULL,
+ throttle_unauthenticated_files_api_enabled boolean DEFAULT false NOT NULL,
+ throttle_authenticated_files_api_enabled boolean DEFAULT false NOT NULL,
+ max_yaml_size_bytes bigint DEFAULT 1048576 NOT NULL,
+ max_yaml_depth integer DEFAULT 100 NOT NULL,
+ throttle_authenticated_git_lfs_requests_per_period integer DEFAULT 1000 NOT NULL,
+ throttle_authenticated_git_lfs_period_in_seconds integer DEFAULT 60 NOT NULL,
+ throttle_authenticated_git_lfs_enabled boolean DEFAULT false NOT NULL,
+ user_deactivation_emails_enabled boolean DEFAULT true NOT NULL,
+ throttle_unauthenticated_api_enabled boolean DEFAULT false NOT NULL,
+ throttle_unauthenticated_api_requests_per_period integer DEFAULT 3600 NOT NULL,
+ throttle_unauthenticated_api_period_in_seconds integer DEFAULT 3600 NOT NULL,
+ jobs_per_stage_page_size integer DEFAULT 200 NOT NULL,
+ sidekiq_job_limiter_mode smallint DEFAULT 1 NOT NULL,
+ sidekiq_job_limiter_compression_threshold_bytes integer DEFAULT 100000 NOT NULL,
+ sidekiq_job_limiter_limit_bytes integer DEFAULT 0 NOT NULL,
CONSTRAINT app_settings_container_reg_cleanup_tags_max_list_size_positive CHECK ((container_registry_cleanup_tags_service_max_list_size >= 0)),
CONSTRAINT app_settings_ext_pipeline_validation_service_url_text_limit CHECK ((char_length(external_pipeline_validation_service_url) <= 255)),
CONSTRAINT app_settings_registry_exp_policies_worker_capacity_positive CHECK ((container_registry_expiration_policies_worker_capacity >= 0)),
+ CONSTRAINT app_settings_yaml_max_depth_positive CHECK ((max_yaml_depth > 0)),
+ CONSTRAINT app_settings_yaml_max_size_positive CHECK ((max_yaml_size_bytes > 0)),
CONSTRAINT check_17d9558205 CHECK ((char_length((kroki_url)::text) <= 1024)),
CONSTRAINT check_2dba05b802 CHECK ((char_length(gitpod_url) <= 255)),
CONSTRAINT check_51700b31b5 CHECK ((char_length(default_branch_name) <= 255)),
@@ -9746,7 +10498,7 @@ CREATE TABLE approval_project_rules (
name character varying NOT NULL,
rule_type smallint DEFAULT 0 NOT NULL,
scanners text[],
- vulnerabilities_allowed smallint,
+ vulnerabilities_allowed smallint DEFAULT 0 NOT NULL,
severity_levels text[] DEFAULT '{}'::text[] NOT NULL
);
@@ -10142,7 +10894,8 @@ CREATE TABLE boards (
weight integer,
hide_backlog_list boolean DEFAULT false NOT NULL,
hide_closed_list boolean DEFAULT false NOT NULL,
- iteration_id bigint
+ iteration_id bigint,
+ iteration_cadence_id bigint
);
CREATE TABLE boards_epic_board_labels (
@@ -10504,7 +11257,6 @@ ALTER SEQUENCE chat_teams_id_seq OWNED BY chat_teams.id;
CREATE TABLE ci_build_needs (
id integer NOT NULL,
- build_id_convert_to_bigint integer DEFAULT 0 NOT NULL,
name text NOT NULL,
artifacts boolean DEFAULT true NOT NULL,
optional boolean DEFAULT false NOT NULL,
@@ -10557,7 +11309,6 @@ ALTER SEQUENCE ci_build_report_results_build_id_seq OWNED BY ci_build_report_res
CREATE TABLE ci_build_trace_chunks (
id bigint NOT NULL,
- build_id_convert_to_bigint integer DEFAULT 0 NOT NULL,
chunk_index integer NOT NULL,
data_store integer NOT NULL,
raw_data bytea,
@@ -10580,11 +11331,13 @@ CREATE TABLE ci_build_trace_metadata (
trace_artifact_id bigint,
archival_attempts smallint DEFAULT 0 NOT NULL,
checksum bytea,
- remote_checksum bytea
+ remote_checksum bytea,
+ last_archival_attempt_at timestamp with time zone,
+ archived_at timestamp with time zone
);
CREATE TABLE ci_builds (
- id integer NOT NULL,
+ id_convert_to_bigint integer DEFAULT 0 NOT NULL,
status character varying,
finished_at timestamp without time zone,
trace text,
@@ -10619,7 +11372,7 @@ CREATE TABLE ci_builds (
coverage_regex character varying,
auto_canceled_by_id integer,
retried boolean,
- stage_id integer,
+ stage_id_convert_to_bigint integer,
protected boolean,
failure_reason integer,
scheduled_at timestamp with time zone,
@@ -10629,8 +11382,8 @@ CREATE TABLE ci_builds (
waiting_for_resource_at timestamp with time zone,
processed boolean,
scheduling_type smallint,
- id_convert_to_bigint bigint DEFAULT 0 NOT NULL,
- stage_id_convert_to_bigint bigint,
+ id bigint NOT NULL,
+ stage_id bigint,
CONSTRAINT check_1e2fbd1b39 CHECK ((lock_version IS NOT NULL))
);
@@ -10644,8 +11397,8 @@ CREATE SEQUENCE ci_builds_id_seq
ALTER SEQUENCE ci_builds_id_seq OWNED BY ci_builds.id;
CREATE TABLE ci_builds_metadata (
- id integer NOT NULL,
- build_id integer NOT NULL,
+ id_convert_to_bigint integer DEFAULT 0 NOT NULL,
+ build_id_convert_to_bigint integer DEFAULT 0 NOT NULL,
project_id integer NOT NULL,
timeout integer,
timeout_source integer DEFAULT 1 NOT NULL,
@@ -10656,8 +11409,8 @@ CREATE TABLE ci_builds_metadata (
environment_auto_stop_in character varying(255),
expanded_environment_name character varying(255),
secrets jsonb DEFAULT '{}'::jsonb NOT NULL,
- build_id_convert_to_bigint bigint DEFAULT 0 NOT NULL,
- id_convert_to_bigint bigint DEFAULT 0 NOT NULL
+ build_id bigint NOT NULL,
+ id bigint NOT NULL
);
CREATE SEQUENCE ci_builds_metadata_id_seq
@@ -10671,7 +11424,6 @@ ALTER SEQUENCE ci_builds_metadata_id_seq OWNED BY ci_builds_metadata.id;
CREATE TABLE ci_builds_runner_session (
id bigint NOT NULL,
- build_id_convert_to_bigint integer DEFAULT 0 NOT NULL,
url character varying NOT NULL,
certificate character varying,
"authorization" character varying,
@@ -10809,6 +11561,7 @@ CREATE TABLE ci_job_artifacts (
file_location smallint,
id bigint NOT NULL,
job_id bigint NOT NULL,
+ locked smallint DEFAULT 2,
CONSTRAINT check_27f0f6dbab CHECK ((file_store IS NOT NULL))
);
@@ -10865,7 +11618,7 @@ CREATE TABLE ci_minutes_additional_packs (
expires_at date,
number_of_minutes integer NOT NULL,
purchase_xid text,
- CONSTRAINT check_d7ef254af0 CHECK ((char_length(purchase_xid) <= 32))
+ CONSTRAINT check_d7ef254af0 CHECK ((char_length(purchase_xid) <= 50))
);
CREATE SEQUENCE ci_minutes_additional_packs_id_seq
@@ -10883,6 +11636,7 @@ CREATE TABLE ci_namespace_monthly_usages (
date date NOT NULL,
additional_amount_available integer DEFAULT 0 NOT NULL,
amount_used numeric(18,2) DEFAULT 0.0 NOT NULL,
+ notification_level smallint DEFAULT 100 NOT NULL,
CONSTRAINT ci_namespace_monthly_usages_year_month_constraint CHECK ((date = date_trunc('month'::text, (date)::timestamp with time zone)))
);
@@ -10903,7 +11657,9 @@ CREATE TABLE ci_pending_builds (
protected boolean DEFAULT false NOT NULL,
instance_runners_enabled boolean DEFAULT false NOT NULL,
namespace_id bigint,
- minutes_exceeded boolean DEFAULT false NOT NULL
+ minutes_exceeded boolean DEFAULT false NOT NULL,
+ tag_ids integer[] DEFAULT '{}'::integer[],
+ namespace_traversal_ids integer[] DEFAULT '{}'::integer[]
);
CREATE SEQUENCE ci_pending_builds_id_seq
@@ -11307,7 +12063,6 @@ CREATE SEQUENCE ci_sources_projects_id_seq
ALTER SEQUENCE ci_sources_projects_id_seq OWNED BY ci_sources_projects.id;
CREATE TABLE ci_stages (
- id_convert_to_bigint integer DEFAULT 0 NOT NULL,
project_id integer,
pipeline_id integer,
created_at timestamp without time zone,
@@ -12041,6 +12796,34 @@ CREATE SEQUENCE custom_emoji_id_seq
ALTER SEQUENCE custom_emoji_id_seq OWNED BY custom_emoji.id;
+CREATE TABLE customer_relations_contacts (
+ id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ organization_id bigint,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ state smallint DEFAULT 1 NOT NULL,
+ phone text,
+ first_name text NOT NULL,
+ last_name text NOT NULL,
+ email text,
+ description text,
+ CONSTRAINT check_1195f4c929 CHECK ((char_length(first_name) <= 255)),
+ CONSTRAINT check_40c70da037 CHECK ((char_length(description) <= 1024)),
+ CONSTRAINT check_cd2d67c484 CHECK ((char_length(last_name) <= 255)),
+ CONSTRAINT check_f4b7f78c89 CHECK ((char_length(phone) <= 32)),
+ CONSTRAINT check_fc0adabf60 CHECK ((char_length(email) <= 255))
+);
+
+CREATE SEQUENCE customer_relations_contacts_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE customer_relations_contacts_id_seq OWNED BY customer_relations_contacts.id;
+
CREATE TABLE customer_relations_organizations (
id bigint NOT NULL,
group_id bigint NOT NULL,
@@ -12073,7 +12856,11 @@ CREATE TABLE dast_profile_schedules (
updated_at timestamp with time zone NOT NULL,
active boolean DEFAULT true NOT NULL,
cron text NOT NULL,
- CONSTRAINT check_86531ea73f CHECK ((char_length(cron) <= 255))
+ cadence jsonb DEFAULT '{}'::jsonb NOT NULL,
+ timezone text NOT NULL,
+ starts_at timestamp with time zone DEFAULT now() NOT NULL,
+ CONSTRAINT check_86531ea73f CHECK ((char_length(cron) <= 255)),
+ CONSTRAINT check_be4d1c3af1 CHECK ((char_length(timezone) <= 255))
);
COMMENT ON TABLE dast_profile_schedules IS '{"owner":"group::dynamic analysis","description":"Scheduling for scans using DAST Profiles"}';
@@ -12321,7 +13108,8 @@ CREATE TABLE dependency_proxy_blobs (
size bigint,
file_store integer,
file_name character varying NOT NULL,
- file text NOT NULL
+ file text NOT NULL,
+ status smallint DEFAULT 0 NOT NULL
);
CREATE SEQUENCE dependency_proxy_blobs_id_seq
@@ -12350,6 +13138,14 @@ CREATE SEQUENCE dependency_proxy_group_settings_id_seq
ALTER SEQUENCE dependency_proxy_group_settings_id_seq OWNED BY dependency_proxy_group_settings.id;
+CREATE TABLE dependency_proxy_image_ttl_group_policies (
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ group_id bigint NOT NULL,
+ ttl integer DEFAULT 90,
+ enabled boolean DEFAULT false NOT NULL
+);
+
CREATE TABLE dependency_proxy_manifests (
id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
@@ -12361,6 +13157,7 @@ CREATE TABLE dependency_proxy_manifests (
file text NOT NULL,
digest text NOT NULL,
content_type text,
+ status smallint DEFAULT 0 NOT NULL,
CONSTRAINT check_079b293a7b CHECK ((char_length(file) <= 255)),
CONSTRAINT check_167a9a8a91 CHECK ((char_length(content_type) <= 255)),
CONSTRAINT check_c579e3f586 CHECK ((char_length(file_name) <= 255)),
@@ -12441,7 +13238,6 @@ CREATE TABLE deployments (
tag boolean NOT NULL,
sha character varying NOT NULL,
user_id integer,
- deployable_id_convert_to_bigint integer,
deployable_type character varying,
created_at timestamp without time zone,
updated_at timestamp without time zone,
@@ -12905,7 +13701,7 @@ CREATE TABLE error_tracking_error_events (
payload jsonb DEFAULT '{}'::jsonb NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
- CONSTRAINT check_92ecc3077b CHECK ((char_length(description) <= 255)),
+ CONSTRAINT check_92ecc3077b CHECK ((char_length(description) <= 1024)),
CONSTRAINT check_c67d5b8007 CHECK ((char_length(level) <= 255)),
CONSTRAINT check_f4b52474ad CHECK ((char_length(environment) <= 255))
);
@@ -12948,7 +13744,7 @@ CREATE SEQUENCE error_tracking_errors_id_seq
ALTER SEQUENCE error_tracking_errors_id_seq OWNED BY error_tracking_errors.id;
CREATE TABLE events (
- id integer NOT NULL,
+ id_convert_to_bigint integer DEFAULT 0 NOT NULL,
project_id integer,
author_id integer NOT NULL,
target_id integer,
@@ -12958,7 +13754,7 @@ CREATE TABLE events (
target_type character varying,
group_id bigint,
fingerprint bytea,
- id_convert_to_bigint bigint DEFAULT 0 NOT NULL,
+ id bigint NOT NULL,
CONSTRAINT check_97e06e05ad CHECK ((octet_length(fingerprint) <= 128))
);
@@ -13320,7 +14116,6 @@ ALTER SEQUENCE geo_hashed_storage_migrated_events_id_seq OWNED BY geo_hashed_sto
CREATE TABLE geo_job_artifact_deleted_events (
id bigint NOT NULL,
- job_artifact_id_convert_to_bigint integer DEFAULT 0 NOT NULL,
file_path character varying NOT NULL,
job_artifact_id bigint NOT NULL
);
@@ -14139,6 +14934,15 @@ CREATE SEQUENCE incident_management_pending_alert_escalations_id_seq
ALTER SEQUENCE incident_management_pending_alert_escalations_id_seq OWNED BY incident_management_pending_alert_escalations.id;
+CREATE SEQUENCE incident_management_pending_issue_escalations_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE incident_management_pending_issue_escalations_id_seq OWNED BY incident_management_pending_issue_escalations.id;
+
CREATE TABLE index_statuses (
id integer NOT NULL,
project_id integer NOT NULL,
@@ -14204,6 +15008,7 @@ CREATE TABLE integrations (
alert_events boolean,
group_id bigint,
type_new text,
+ vulnerability_events boolean DEFAULT false NOT NULL,
CONSTRAINT check_a948a0aa7e CHECK ((char_length(type_new) <= 255))
);
@@ -14829,7 +15634,9 @@ CREATE TABLE members (
requested_at timestamp without time zone,
expires_at date,
ldap boolean DEFAULT false NOT NULL,
- override boolean DEFAULT false NOT NULL
+ override boolean DEFAULT false NOT NULL,
+ state smallint DEFAULT 0,
+ invite_email_success boolean DEFAULT true NOT NULL
);
CREATE SEQUENCE members_id_seq
@@ -15336,6 +16143,8 @@ CREATE TABLE namespace_settings (
lock_delayed_project_removal boolean DEFAULT false NOT NULL,
prevent_sharing_groups_outside_hierarchy boolean DEFAULT false NOT NULL,
new_user_signups_cap integer,
+ setup_for_company boolean,
+ jobs_to_be_done smallint,
CONSTRAINT check_0ba93c78c7 CHECK ((char_length(default_branch_name) <= 255))
);
@@ -15577,7 +16386,8 @@ CREATE TABLE oauth_applications (
owner_id integer,
owner_type character varying,
trusted boolean DEFAULT false NOT NULL,
- confidential boolean DEFAULT true NOT NULL
+ confidential boolean DEFAULT true NOT NULL,
+ expire_access_tokens boolean DEFAULT false NOT NULL
);
CREATE SEQUENCE oauth_applications_id_seq
@@ -16596,7 +17406,8 @@ CREATE TABLE plan_limits (
ci_max_artifact_size_running_container_scanning integer DEFAULT 0 NOT NULL,
ci_max_artifact_size_cluster_image_scanning integer DEFAULT 0 NOT NULL,
ci_jobs_trace_size_limit integer DEFAULT 100 NOT NULL,
- pages_file_entries integer DEFAULT 200000 NOT NULL
+ pages_file_entries integer DEFAULT 200000 NOT NULL,
+ dast_profile_schedules integer DEFAULT 1 NOT NULL
);
CREATE SEQUENCE plan_limits_id_seq
@@ -17297,7 +18108,6 @@ CREATE TABLE project_settings (
squash_option smallint DEFAULT 3,
has_confluence boolean DEFAULT false NOT NULL,
has_vulnerabilities boolean DEFAULT false NOT NULL,
- allow_editing_commit_messages boolean DEFAULT false NOT NULL,
prevent_merge_without_jira_issue boolean DEFAULT false NOT NULL,
cve_id_request_enabled boolean DEFAULT true NOT NULL,
mr_default_target_self boolean DEFAULT false NOT NULL,
@@ -17333,6 +18143,23 @@ CREATE SEQUENCE project_statistics_id_seq
ALTER SEQUENCE project_statistics_id_seq OWNED BY project_statistics.id;
+CREATE TABLE project_topics (
+ id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ topic_id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL
+);
+
+CREATE SEQUENCE project_topics_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE project_topics_id_seq OWNED BY project_topics.id;
+
CREATE TABLE project_tracing_settings (
id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
@@ -17387,7 +18214,6 @@ CREATE TABLE projects (
public_builds boolean DEFAULT true NOT NULL,
last_repository_check_failed boolean,
last_repository_check_at timestamp without time zone,
- container_registry_enabled boolean,
only_allow_merge_if_pipeline_succeeds boolean DEFAULT false NOT NULL,
has_external_issue_tracker boolean,
repository_storage character varying DEFAULT 'default'::character varying NOT NULL,
@@ -17432,7 +18258,8 @@ CREATE TABLE projects (
marked_for_deletion_at date,
marked_for_deletion_by_user_id integer,
autoclose_referenced_issues boolean,
- suggestion_commit_message character varying(255)
+ suggestion_commit_message character varying(255),
+ project_namespace_id bigint
);
CREATE SEQUENCE projects_id_seq
@@ -18180,7 +19007,8 @@ CREATE TABLE security_scans (
scan_type smallint NOT NULL,
info jsonb DEFAULT '{}'::jsonb NOT NULL,
project_id bigint,
- pipeline_id bigint
+ pipeline_id bigint,
+ latest boolean DEFAULT true NOT NULL
);
CREATE SEQUENCE security_scans_id_seq
@@ -18267,7 +19095,8 @@ CREATE TABLE service_desk_settings (
project_id bigint NOT NULL,
issue_template_key character varying(255),
outgoing_name character varying(255),
- project_key character varying(255)
+ project_key character varying(255),
+ file_template_project_id bigint
);
CREATE TABLE shards (
@@ -18615,16 +19444,16 @@ CREATE SEQUENCE system_note_metadata_id_seq
ALTER SEQUENCE system_note_metadata_id_seq OWNED BY system_note_metadata.id;
CREATE TABLE taggings (
- id integer NOT NULL,
+ id_convert_to_bigint integer DEFAULT 0 NOT NULL,
tag_id integer,
- taggable_id integer,
+ taggable_id_convert_to_bigint integer,
taggable_type character varying,
tagger_id integer,
tagger_type character varying,
context character varying,
created_at timestamp without time zone,
- id_convert_to_bigint bigint DEFAULT 0 NOT NULL,
- taggable_id_convert_to_bigint bigint
+ id bigint NOT NULL,
+ taggable_id bigint
);
CREATE SEQUENCE taggings_id_seq
@@ -18789,6 +19618,23 @@ CREATE SEQUENCE token_with_ivs_id_seq
ALTER SEQUENCE token_with_ivs_id_seq OWNED BY token_with_ivs.id;
+CREATE TABLE topics (
+ id bigint NOT NULL,
+ name text NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ CONSTRAINT check_7a90d4c757 CHECK ((char_length(name) <= 255))
+);
+
+CREATE SEQUENCE topics_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE topics_id_seq OWNED BY topics.id;
+
CREATE TABLE trending_projects (
id integer NOT NULL,
project_id integer NOT NULL
@@ -18973,6 +19819,23 @@ CREATE TABLE user_follow_users (
followee_id integer NOT NULL
);
+CREATE TABLE user_group_callouts (
+ id bigint NOT NULL,
+ user_id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ feature_name smallint NOT NULL,
+ dismissed_at timestamp with time zone
+);
+
+CREATE SEQUENCE user_group_callouts_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE user_group_callouts_id_seq OWNED BY user_group_callouts.id;
+
CREATE TABLE user_highest_roles (
user_id bigint NOT NULL,
updated_at timestamp with time zone NOT NULL,
@@ -20037,6 +20900,10 @@ ALTER SEQUENCE zoom_meetings_id_seq OWNED BY zoom_meetings.id;
ALTER TABLE ONLY abuse_reports ALTER COLUMN id SET DEFAULT nextval('abuse_reports_id_seq'::regclass);
+ALTER TABLE ONLY agent_group_authorizations ALTER COLUMN id SET DEFAULT nextval('agent_group_authorizations_id_seq'::regclass);
+
+ALTER TABLE ONLY agent_project_authorizations ALTER COLUMN id SET DEFAULT nextval('agent_project_authorizations_id_seq'::regclass);
+
ALTER TABLE ONLY alert_management_alert_assignees ALTER COLUMN id SET DEFAULT nextval('alert_management_alert_assignees_id_seq'::regclass);
ALTER TABLE ONLY alert_management_alert_user_mentions ALTER COLUMN id SET DEFAULT nextval('alert_management_alert_user_mentions_id_seq'::regclass);
@@ -20291,6 +21158,8 @@ ALTER TABLE ONLY csv_issue_imports ALTER COLUMN id SET DEFAULT nextval('csv_issu
ALTER TABLE ONLY custom_emoji ALTER COLUMN id SET DEFAULT nextval('custom_emoji_id_seq'::regclass);
+ALTER TABLE ONLY customer_relations_contacts ALTER COLUMN id SET DEFAULT nextval('customer_relations_contacts_id_seq'::regclass);
+
ALTER TABLE ONLY customer_relations_organizations ALTER COLUMN id SET DEFAULT nextval('customer_relations_organizations_id_seq'::regclass);
ALTER TABLE ONLY dast_profile_schedules ALTER COLUMN id SET DEFAULT nextval('dast_profile_schedules_id_seq'::regclass);
@@ -20483,6 +21352,8 @@ ALTER TABLE ONLY incident_management_oncall_shifts ALTER COLUMN id SET DEFAULT n
ALTER TABLE ONLY incident_management_pending_alert_escalations ALTER COLUMN id SET DEFAULT nextval('incident_management_pending_alert_escalations_id_seq'::regclass);
+ALTER TABLE ONLY incident_management_pending_issue_escalations ALTER COLUMN id SET DEFAULT nextval('incident_management_pending_issue_escalations_id_seq'::regclass);
+
ALTER TABLE ONLY index_statuses ALTER COLUMN id SET DEFAULT nextval('index_statuses_id_seq'::regclass);
ALTER TABLE ONLY insights ALTER COLUMN id SET DEFAULT nextval('insights_id_seq'::regclass);
@@ -20727,6 +21598,8 @@ ALTER TABLE ONLY project_security_settings ALTER COLUMN project_id SET DEFAULT n
ALTER TABLE ONLY project_statistics ALTER COLUMN id SET DEFAULT nextval('project_statistics_id_seq'::regclass);
+ALTER TABLE ONLY project_topics ALTER COLUMN id SET DEFAULT nextval('project_topics_id_seq'::regclass);
+
ALTER TABLE ONLY project_tracing_settings ALTER COLUMN id SET DEFAULT nextval('project_tracing_settings_id_seq'::regclass);
ALTER TABLE ONLY projects ALTER COLUMN id SET DEFAULT nextval('projects_id_seq'::regclass);
@@ -20855,6 +21728,8 @@ ALTER TABLE ONLY todos ALTER COLUMN id SET DEFAULT nextval('todos_id_seq'::regcl
ALTER TABLE ONLY token_with_ivs ALTER COLUMN id SET DEFAULT nextval('token_with_ivs_id_seq'::regclass);
+ALTER TABLE ONLY topics ALTER COLUMN id SET DEFAULT nextval('topics_id_seq'::regclass);
+
ALTER TABLE ONLY trending_projects ALTER COLUMN id SET DEFAULT nextval('trending_projects_id_seq'::regclass);
ALTER TABLE ONLY u2f_registrations ALTER COLUMN id SET DEFAULT nextval('u2f_registrations_id_seq'::regclass);
@@ -20873,6 +21748,8 @@ ALTER TABLE ONLY user_custom_attributes ALTER COLUMN id SET DEFAULT nextval('use
ALTER TABLE ONLY user_details ALTER COLUMN user_id SET DEFAULT nextval('user_details_user_id_seq'::regclass);
+ALTER TABLE ONLY user_group_callouts ALTER COLUMN id SET DEFAULT nextval('user_group_callouts_id_seq'::regclass);
+
ALTER TABLE ONLY user_permission_export_uploads ALTER COLUMN id SET DEFAULT nextval('user_permission_export_uploads_id_seq'::regclass);
ALTER TABLE ONLY user_preferences ALTER COLUMN id SET DEFAULT nextval('user_preferences_id_seq'::regclass);
@@ -20961,6 +21838,204 @@ ALTER TABLE ONLY zentao_tracker_data ALTER COLUMN id SET DEFAULT nextval('zentao
ALTER TABLE ONLY zoom_meetings ALTER COLUMN id SET DEFAULT nextval('zoom_meetings_id_seq'::regclass);
+ALTER TABLE ONLY analytics_cycle_analytics_issue_stage_events
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_00
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_00_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_01
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_01_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_02
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_02_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_03
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_03_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_04
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_04_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_05
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_05_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_06
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_06_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_07
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_07_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_08
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_08_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_09
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_09_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_10
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_10_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_11
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_11_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_12
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_12_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_13
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_13_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_14
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_14_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_15
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_15_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_16
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_16_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_17
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_17_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_18
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_18_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_19
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_19_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_20
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_20_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_21
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_21_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_22
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_22_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_23
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_23_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_24
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_24_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_25
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_25_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_26
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_26_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_27
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_27_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_28
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_28_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_29
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_29_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_30
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_30_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_31
+ ADD CONSTRAINT analytics_cycle_analytics_issue_stage_events_31_pkey PRIMARY KEY (stage_event_hash_id, issue_id);
+
+ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_00
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_00_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_01
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_01_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_02
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_02_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_03
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_03_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_04
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_04_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_05
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_05_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_06
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_06_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_07
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_07_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_08
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_08_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_09
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_09_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_10
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_10_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_11
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_11_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_12
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_12_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_13
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_13_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_14
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_14_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_15
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_15_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_16
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_16_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_17
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_17_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_18
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_18_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_19
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_19_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_20
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_20_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_21
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_21_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_22
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_22_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_23
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_23_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_24
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_24_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_25
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_25_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_26
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_26_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_27
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_27_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_28
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_28_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_29
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_29_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_30
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_30_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_31
+ ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_31_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+
ALTER TABLE ONLY product_analytics_events_experimental
ADD CONSTRAINT product_analytics_events_experimental_pkey PRIMARY KEY (id, project_id);
@@ -21159,6 +22234,12 @@ ALTER TABLE ONLY gitlab_partitions_static.product_analytics_events_experimental_
ALTER TABLE ONLY abuse_reports
ADD CONSTRAINT abuse_reports_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY agent_group_authorizations
+ ADD CONSTRAINT agent_group_authorizations_pkey PRIMARY KEY (id);
+
+ALTER TABLE ONLY agent_project_authorizations
+ ADD CONSTRAINT agent_project_authorizations_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY alert_management_alert_assignees
ADD CONSTRAINT alert_management_alert_assignees_pkey PRIMARY KEY (id);
@@ -21582,6 +22663,9 @@ ALTER TABLE ONLY csv_issue_imports
ALTER TABLE ONLY custom_emoji
ADD CONSTRAINT custom_emoji_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY customer_relations_contacts
+ ADD CONSTRAINT customer_relations_contacts_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY customer_relations_organizations
ADD CONSTRAINT customer_relations_organizations_pkey PRIMARY KEY (id);
@@ -21630,6 +22714,9 @@ ALTER TABLE ONLY dependency_proxy_blobs
ALTER TABLE ONLY dependency_proxy_group_settings
ADD CONSTRAINT dependency_proxy_group_settings_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY dependency_proxy_image_ttl_group_policies
+ ADD CONSTRAINT dependency_proxy_image_ttl_group_policies_pkey PRIMARY KEY (group_id);
+
ALTER TABLE ONLY dependency_proxy_manifests
ADD CONSTRAINT dependency_proxy_manifests_pkey PRIMARY KEY (id);
@@ -21906,6 +22993,9 @@ ALTER TABLE ONLY incident_management_oncall_shifts
ALTER TABLE ONLY incident_management_pending_alert_escalations
ADD CONSTRAINT incident_management_pending_alert_escalations_pkey PRIMARY KEY (id, process_at);
+ALTER TABLE ONLY incident_management_pending_issue_escalations
+ ADD CONSTRAINT incident_management_pending_issue_escalations_pkey PRIMARY KEY (id, process_at);
+
ALTER TABLE ONLY index_statuses
ADD CONSTRAINT index_statuses_pkey PRIMARY KEY (id);
@@ -22011,6 +23101,9 @@ ALTER TABLE ONLY list_user_preferences
ALTER TABLE ONLY lists
ADD CONSTRAINT lists_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY loose_foreign_keys_deleted_records
+ ADD CONSTRAINT loose_foreign_keys_deleted_records_pkey PRIMARY KEY (created_at, deleted_table_name, deleted_table_primary_key_value);
+
ALTER TABLE ONLY members
ADD CONSTRAINT members_pkey PRIMARY KEY (id);
@@ -22356,6 +23449,9 @@ ALTER TABLE ONLY project_settings
ALTER TABLE ONLY project_statistics
ADD CONSTRAINT project_statistics_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY project_topics
+ ADD CONSTRAINT project_topics_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY project_tracing_settings
ADD CONSTRAINT project_tracing_settings_pkey PRIMARY KEY (id);
@@ -22569,6 +23665,9 @@ ALTER TABLE ONLY todos
ALTER TABLE ONLY token_with_ivs
ADD CONSTRAINT token_with_ivs_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY topics
+ ADD CONSTRAINT topics_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY trending_projects
ADD CONSTRAINT trending_projects_pkey PRIMARY KEY (id);
@@ -22602,6 +23701,9 @@ ALTER TABLE ONLY user_details
ALTER TABLE ONLY user_follow_users
ADD CONSTRAINT user_follow_users_pkey PRIMARY KEY (follower_id, followee_id);
+ALTER TABLE ONLY user_group_callouts
+ ADD CONSTRAINT user_group_callouts_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY user_highest_roles
ADD CONSTRAINT user_highest_roles_pkey PRIMARY KEY (user_id);
@@ -22967,6 +24069,10 @@ CREATE UNIQUE INDEX idx_environment_merge_requests_unique_index ON deployment_me
CREATE INDEX idx_geo_con_rep_updated_events_on_container_repository_id ON geo_container_repository_updated_events USING btree (container_repository_id);
+CREATE INDEX idx_installable_helm_pkgs_on_project_id_id ON packages_packages USING btree (project_id, id);
+
+CREATE INDEX idx_installable_npm_pkgs_on_project_id_name_version_id ON packages_packages USING btree (project_id, name, version, id) WHERE ((package_type = 2) AND (status = 0));
+
CREATE INDEX idx_issues_on_health_status_not_null ON issues USING btree (health_status) WHERE (health_status IS NOT NULL);
CREATE INDEX idx_issues_on_project_id_and_created_at_and_id_and_state_id ON issues USING btree (project_id, created_at, id, state_id);
@@ -23079,6 +24185,14 @@ CREATE UNIQUE INDEX idx_vulnerability_issue_links_on_vulnerability_id_and_link_t
CREATE INDEX index_abuse_reports_on_user_id ON abuse_reports USING btree (user_id);
+CREATE UNIQUE INDEX index_agent_group_authorizations_on_agent_id_and_group_id ON agent_group_authorizations USING btree (agent_id, group_id);
+
+CREATE INDEX index_agent_group_authorizations_on_group_id ON agent_group_authorizations USING btree (group_id);
+
+CREATE UNIQUE INDEX index_agent_project_authorizations_on_agent_id_and_project_id ON agent_project_authorizations USING btree (agent_id, project_id);
+
+CREATE INDEX index_agent_project_authorizations_on_project_id ON agent_project_authorizations USING btree (project_id);
+
CREATE INDEX index_alert_assignees_on_alert_id ON alert_management_alert_assignees USING btree (alert_id);
CREATE UNIQUE INDEX index_alert_assignees_on_user_id_and_alert_id ON alert_management_alert_assignees USING btree (user_id, alert_id);
@@ -23293,6 +24407,8 @@ CREATE INDEX index_boards_epic_user_preferences_on_user_id ON boards_epic_user_p
CREATE INDEX index_boards_on_group_id ON boards USING btree (group_id);
+CREATE INDEX index_boards_on_iteration_cadence_id ON boards USING btree (iteration_cadence_id);
+
CREATE INDEX index_boards_on_iteration_id ON boards USING btree (iteration_id);
CREATE INDEX index_boards_on_milestone_id ON boards USING btree (milestone_id);
@@ -23439,6 +24555,8 @@ CREATE INDEX index_ci_pending_builds_on_namespace_id ON ci_pending_builds USING
CREATE INDEX index_ci_pending_builds_on_project_id ON ci_pending_builds USING btree (project_id);
+CREATE INDEX index_ci_pending_builds_on_tag_ids ON ci_pending_builds USING btree (tag_ids) WHERE (cardinality(tag_ids) > 0);
+
CREATE INDEX index_ci_pipeline_artifacts_failed_verification ON ci_pipeline_artifacts USING btree (verification_retry_at NULLS FIRST) WHERE (verification_state = 3);
CREATE INDEX index_ci_pipeline_artifacts_needs_verification ON ci_pipeline_artifacts USING btree (verification_state) WHERE ((verification_state = 0) OR (verification_state = 3));
@@ -23695,6 +24813,10 @@ CREATE INDEX index_custom_emoji_on_creator_id ON custom_emoji USING btree (creat
CREATE UNIQUE INDEX index_custom_emoji_on_namespace_id_and_name ON custom_emoji USING btree (namespace_id, name);
+CREATE INDEX index_customer_relations_contacts_on_group_id ON customer_relations_contacts USING btree (group_id);
+
+CREATE INDEX index_customer_relations_contacts_on_organization_id ON customer_relations_contacts USING btree (organization_id);
+
CREATE UNIQUE INDEX index_customer_relations_organizations_on_unique_name_per_group ON customer_relations_organizations USING btree (group_id, lower(name));
CREATE UNIQUE INDEX index_cycle_analytics_stage_event_hashes_on_hash_sha_256 ON analytics_cycle_analytics_stage_event_hashes USING btree (hash_sha256);
@@ -23703,9 +24825,9 @@ CREATE UNIQUE INDEX index_daily_build_group_report_results_unique_columns ON ci_
CREATE INDEX index_dast_profile_schedules_active_next_run_at ON dast_profile_schedules USING btree (active, next_run_at);
-CREATE INDEX index_dast_profile_schedules_on_dast_profile_id ON dast_profile_schedules USING btree (dast_profile_id);
+CREATE UNIQUE INDEX index_dast_profile_schedules_on_dast_profile_id ON dast_profile_schedules USING btree (dast_profile_id);
-CREATE UNIQUE INDEX index_dast_profile_schedules_on_project_id_and_dast_profile_id ON dast_profile_schedules USING btree (project_id, dast_profile_id);
+CREATE INDEX index_dast_profile_schedules_on_project_id ON dast_profile_schedules USING btree (project_id);
CREATE INDEX index_dast_profile_schedules_on_user_id ON dast_profile_schedules USING btree (user_id);
@@ -23725,6 +24847,10 @@ CREATE UNIQUE INDEX index_dast_site_profiles_on_project_id_and_name ON dast_site
CREATE UNIQUE INDEX index_dast_site_profiles_pipelines_on_ci_pipeline_id ON dast_site_profiles_pipelines USING btree (ci_pipeline_id);
+CREATE UNIQUE INDEX index_dast_site_token_on_project_id_and_url ON dast_site_tokens USING btree (project_id, url);
+
+CREATE UNIQUE INDEX index_dast_site_token_on_token ON dast_site_tokens USING btree (token);
+
CREATE INDEX index_dast_site_tokens_on_project_id ON dast_site_tokens USING btree (project_id);
CREATE INDEX index_dast_site_validations_on_dast_site_token_id ON dast_site_validations USING btree (dast_site_token_id);
@@ -23935,6 +25061,14 @@ CREATE UNIQUE INDEX index_escalation_rules_on_all_attributes ON incident_managem
CREATE INDEX index_escalation_rules_on_user ON incident_management_escalation_rules USING btree (user_id);
+CREATE INDEX index_et_errors_on_project_id_and_status_and_events_count ON error_tracking_errors USING btree (project_id, status, events_count);
+
+CREATE INDEX index_et_errors_on_project_id_and_status_and_first_seen_at ON error_tracking_errors USING btree (project_id, status, first_seen_at);
+
+CREATE INDEX index_et_errors_on_project_id_and_status_and_id ON error_tracking_errors USING btree (project_id, status, id);
+
+CREATE INDEX index_et_errors_on_project_id_and_status_and_last_seen_at ON error_tracking_errors USING btree (project_id, status, last_seen_at);
+
CREATE INDEX index_events_on_action ON events USING btree (action);
CREATE INDEX index_events_on_author_id_and_created_at ON events USING btree (author_id, created_at);
@@ -24061,6 +25195,8 @@ CREATE INDEX index_geo_reset_checksum_events_on_project_id ON geo_reset_checksum
CREATE INDEX index_geo_upload_deleted_events_on_upload_id ON geo_upload_deleted_events USING btree (upload_id);
+CREATE INDEX index_gin_ci_pending_builds_on_namespace_traversal_ids ON ci_pending_builds USING gin (namespace_traversal_ids);
+
CREATE INDEX index_gitlab_subscription_histories_on_gitlab_subscription_id ON gitlab_subscription_histories USING btree (gitlab_subscription_id);
CREATE INDEX index_gitlab_subscriptions_on_end_date_and_namespace_id ON gitlab_subscriptions USING btree (end_date, namespace_id);
@@ -24131,6 +25267,8 @@ CREATE UNIQUE INDEX index_group_stages_on_group_id_group_value_stream_id_and_nam
CREATE INDEX index_group_stages_on_stage_event_hash_id ON analytics_cycle_analytics_group_stages USING btree (stage_event_hash_id);
+CREATE UNIQUE INDEX index_group_user_callouts_feature ON user_group_callouts USING btree (user_id, feature_name, group_id);
+
CREATE UNIQUE INDEX index_group_wiki_repositories_on_disk_path ON group_wiki_repositories USING btree (disk_path);
CREATE INDEX index_group_wiki_repositories_on_shard_id ON group_wiki_repositories USING btree (shard_id);
@@ -24187,6 +25325,10 @@ CREATE INDEX index_incident_management_pending_alert_escalations_on_rule_id ON O
CREATE INDEX index_incident_management_pending_alert_escalations_on_schedule ON ONLY incident_management_pending_alert_escalations USING btree (schedule_id);
+CREATE INDEX index_incident_management_pending_issue_escalations_on_issue_id ON ONLY incident_management_pending_issue_escalations USING btree (issue_id);
+
+CREATE INDEX index_incident_management_pending_issue_escalations_on_rule_id ON ONLY incident_management_pending_issue_escalations USING btree (rule_id);
+
CREATE UNIQUE INDEX index_index_statuses_on_project_id ON index_statuses USING btree (project_id);
CREATE INDEX index_insights_on_namespace_id ON insights USING btree (namespace_id);
@@ -24595,6 +25737,8 @@ CREATE INDEX index_namespaces_on_traversal_ids ON namespaces USING gin (traversa
CREATE INDEX index_namespaces_on_type_and_id_partial ON namespaces USING btree (type, id) WHERE (type IS NOT NULL);
+CREATE INDEX index_namespaces_public_groups_name_id ON namespaces USING btree (name, id) WHERE (((type)::text = 'Group'::text) AND (visibility_level = 20));
+
CREATE INDEX index_non_requested_project_members_on_source_id_and_type ON members USING btree (source_id, source_type) WHERE ((requested_at IS NULL) AND ((type)::text = 'ProjectMember'::text));
CREATE UNIQUE INDEX index_note_diff_files_on_diff_note_id ON note_diff_files USING btree (diff_note_id);
@@ -24747,6 +25891,8 @@ CREATE INDEX index_packages_events_on_package_id ON packages_events USING btree
CREATE INDEX index_packages_helm_file_metadata_on_channel ON packages_helm_file_metadata USING btree (channel);
+CREATE INDEX index_packages_helm_file_metadata_on_pf_id_and_channel ON packages_helm_file_metadata USING btree (package_file_id, channel);
+
CREATE INDEX index_packages_maven_metadata_on_package_id_and_path ON packages_maven_metadata USING btree (package_id, path);
CREATE INDEX index_packages_maven_metadata_on_path ON packages_maven_metadata USING btree (path);
@@ -24767,6 +25913,8 @@ CREATE INDEX index_packages_package_files_on_file_store ON packages_package_file
CREATE INDEX index_packages_package_files_on_package_id_and_file_name ON packages_package_files USING btree (package_id, file_name);
+CREATE INDEX index_packages_package_files_on_package_id_id ON packages_package_files USING btree (package_id, id);
+
CREATE INDEX index_packages_package_files_on_verification_state ON packages_package_files USING btree (verification_state);
CREATE INDEX index_packages_packages_on_creator_id ON packages_packages USING btree (creator_id);
@@ -24955,6 +26103,12 @@ CREATE INDEX index_project_statistics_on_storage_size_and_project_id ON project_
CREATE INDEX index_project_statistics_on_wiki_size_and_project_id ON project_statistics USING btree (wiki_size, project_id);
+CREATE INDEX index_project_topics_on_project_id ON project_topics USING btree (project_id);
+
+CREATE UNIQUE INDEX index_project_topics_on_project_id_and_topic_id ON project_topics USING btree (project_id, topic_id);
+
+CREATE INDEX index_project_topics_on_topic_id ON project_topics USING btree (topic_id);
+
CREATE UNIQUE INDEX index_project_tracing_settings_on_project_id ON project_tracing_settings USING btree (project_id);
CREATE INDEX index_projects_aimed_for_deletion ON projects USING btree (marked_for_deletion_at) WHERE ((marked_for_deletion_at IS NOT NULL) AND (pending_delete = false));
@@ -25035,6 +26189,8 @@ CREATE INDEX index_projects_on_pending_delete ON projects USING btree (pending_d
CREATE INDEX index_projects_on_pool_repository_id ON projects USING btree (pool_repository_id) WHERE (pool_repository_id IS NOT NULL);
+CREATE UNIQUE INDEX index_projects_on_project_namespace_id ON projects USING btree (project_namespace_id);
+
CREATE INDEX index_projects_on_repository_storage ON projects USING btree (repository_storage);
CREATE INDEX index_projects_on_runners_token ON projects USING btree (runners_token);
@@ -25277,6 +26433,8 @@ CREATE INDEX index_serverless_domain_cluster_on_pages_domain_id ON serverless_do
CREATE INDEX index_service_desk_enabled_projects_on_id_creator_id_created_at ON projects USING btree (id, creator_id, created_at) WHERE (service_desk_enabled = true);
+CREATE INDEX index_service_desk_settings_on_file_template_project_id ON service_desk_settings USING btree (file_template_project_id);
+
CREATE UNIQUE INDEX index_shards_on_name ON shards USING btree (name);
CREATE UNIQUE INDEX index_site_profile_secret_variables_on_site_profile_id_and_key ON dast_site_profile_secret_variables USING btree (dast_site_profile_id, key);
@@ -25459,6 +26617,8 @@ CREATE UNIQUE INDEX index_token_with_ivs_on_hashed_plaintext_token ON token_with
CREATE UNIQUE INDEX index_token_with_ivs_on_hashed_token ON token_with_ivs USING btree (hashed_token);
+CREATE UNIQUE INDEX index_topics_on_name ON topics USING btree (name);
+
CREATE UNIQUE INDEX index_trending_projects_on_project_id ON trending_projects USING btree (project_id);
CREATE INDEX index_u2f_registrations_on_key_handle ON u2f_registrations USING btree (key_handle);
@@ -25503,6 +26663,8 @@ CREATE INDEX index_user_details_on_provisioned_by_group_id ON user_details USING
CREATE UNIQUE INDEX index_user_details_on_user_id ON user_details USING btree (user_id);
+CREATE INDEX index_user_group_callouts_on_group_id ON user_group_callouts USING btree (group_id);
+
CREATE INDEX index_user_highest_roles_on_user_id_and_highest_access_level ON user_highest_roles USING btree (user_id, highest_access_level);
CREATE INDEX index_user_interacted_projects_on_user_id ON user_interacted_projects USING btree (user_id);
@@ -25785,14 +26947,14 @@ CREATE INDEX tmp_idx_deduplicate_vulnerability_occurrences ON vulnerability_occu
CREATE INDEX tmp_idx_on_namespaces_delayed_project_removal ON namespaces USING btree (id) WHERE (delayed_project_removal = true);
-CREATE INDEX tmp_index_approval_project_rules_scanners ON approval_project_rules USING gin (scanners) WHERE (scanners @> '{cluster_image_scanning}'::text[]);
-
CREATE INDEX tmp_index_namespaces_empty_traversal_ids_with_child_namespaces ON namespaces USING btree (id) WHERE ((parent_id IS NOT NULL) AND (traversal_ids = '{}'::integer[]));
CREATE INDEX tmp_index_namespaces_empty_traversal_ids_with_root_namespaces ON namespaces USING btree (id) WHERE ((parent_id IS NULL) AND (traversal_ids = '{}'::integer[]));
CREATE INDEX tmp_index_on_vulnerabilities_non_dismissed ON vulnerabilities USING btree (id) WHERE (state <> 2);
+CREATE INDEX tmp_index_taggings_on_id_where_taggable_type_project ON taggings USING btree (id) WHERE ((taggable_type)::text = 'Project'::text);
+
CREATE UNIQUE INDEX uniq_pkgs_deb_grp_architectures_on_distribution_id_and_name ON packages_debian_group_architectures USING btree (distribution_id, name);
CREATE UNIQUE INDEX uniq_pkgs_deb_grp_components_on_distribution_id_and_name ON packages_debian_group_components USING btree (distribution_id, name);
@@ -25819,6 +26981,134 @@ CREATE UNIQUE INDEX vulnerability_occurrence_pipelines_on_unique_keys ON vulnera
CREATE UNIQUE INDEX work_item_types_namespace_id_and_name_unique ON work_item_types USING btree (namespace_id, btrim(lower(name)));
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_00_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_01_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_02_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_03_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_04_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_05_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_06_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_07_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_08_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_09_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_10_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_11_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_12_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_13_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_14_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_15_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_16_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_17_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_18_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_19_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_20_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_21_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_22_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_23_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_24_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_25_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_26_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_27_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_28_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_29_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_30_pkey;
+
+ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_31_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_00_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_01_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_02_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_03_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_04_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_05_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_06_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_07_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_08_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_09_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_10_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_11_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_12_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_13_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_14_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_15_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_16_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_17_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_18_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_19_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_20_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_21_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_22_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_23_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_24_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_25_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_26_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_27_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_28_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_29_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_30_pkey;
+
+ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_31_pkey;
+
ALTER INDEX index_product_analytics_events_experimental_project_and_time ATTACH PARTITION gitlab_partitions_static.product_analytics_events_expe_project_id_collector_tstamp_idx10;
ALTER INDEX index_product_analytics_events_experimental_project_and_time ATTACH PARTITION gitlab_partitions_static.product_analytics_events_expe_project_id_collector_tstamp_idx11;
@@ -26075,35 +27365,17 @@ ALTER INDEX product_analytics_events_experimental_pkey ATTACH PARTITION gitlab_p
ALTER INDEX product_analytics_events_experimental_pkey ATTACH PARTITION gitlab_partitions_static.product_analytics_events_experimental_63_pkey;
-CREATE TRIGGER trigger_07c94931164e BEFORE INSERT OR UPDATE ON push_event_payloads FOR EACH ROW EXECUTE FUNCTION trigger_07c94931164e();
-
-CREATE TRIGGER trigger_21e7a2602957 BEFORE INSERT OR UPDATE ON ci_build_needs FOR EACH ROW EXECUTE FUNCTION trigger_21e7a2602957();
-
CREATE TRIGGER trigger_3f6129be01d2 BEFORE INSERT OR UPDATE ON ci_builds FOR EACH ROW EXECUTE FUNCTION trigger_3f6129be01d2();
-CREATE TRIGGER trigger_490d204c00b3 BEFORE INSERT OR UPDATE ON ci_stages FOR EACH ROW EXECUTE FUNCTION trigger_490d204c00b3();
-
-CREATE TRIGGER trigger_51ab7cef8934 BEFORE INSERT OR UPDATE ON ci_builds_runner_session FOR EACH ROW EXECUTE FUNCTION trigger_51ab7cef8934();
-
CREATE TRIGGER trigger_542d6c2ad72e BEFORE INSERT OR UPDATE ON ci_builds_metadata FOR EACH ROW EXECUTE FUNCTION trigger_542d6c2ad72e();
-CREATE TRIGGER trigger_69523443cc10 BEFORE INSERT OR UPDATE ON events FOR EACH ROW EXECUTE FUNCTION trigger_69523443cc10();
-
-CREATE TRIGGER trigger_77f5e1d20482 BEFORE INSERT OR UPDATE ON deployments FOR EACH ROW EXECUTE FUNCTION trigger_77f5e1d20482();
-
-CREATE TRIGGER trigger_8485e97c00e3 BEFORE INSERT OR UPDATE ON ci_sources_pipelines FOR EACH ROW EXECUTE FUNCTION trigger_8485e97c00e3();
-
CREATE TRIGGER trigger_8487d4de3e7b BEFORE INSERT OR UPDATE ON ci_builds_metadata FOR EACH ROW EXECUTE FUNCTION trigger_8487d4de3e7b();
CREATE TRIGGER trigger_91dc388a5fe6 BEFORE INSERT OR UPDATE ON dep_ci_build_trace_sections FOR EACH ROW EXECUTE FUNCTION trigger_91dc388a5fe6();
CREATE TRIGGER trigger_aebe8b822ad3 BEFORE INSERT OR UPDATE ON taggings FOR EACH ROW EXECUTE FUNCTION trigger_aebe8b822ad3();
-CREATE TRIGGER trigger_be1804f21693 BEFORE INSERT OR UPDATE ON ci_job_artifacts FOR EACH ROW EXECUTE FUNCTION trigger_be1804f21693();
-
-CREATE TRIGGER trigger_cf2f9e35f002 BEFORE INSERT OR UPDATE ON ci_build_trace_chunks FOR EACH ROW EXECUTE FUNCTION trigger_cf2f9e35f002();
-
-CREATE TRIGGER trigger_f1ca8ec18d78 BEFORE INSERT OR UPDATE ON geo_job_artifact_deleted_events FOR EACH ROW EXECUTE FUNCTION trigger_f1ca8ec18d78();
+CREATE TRIGGER trigger_delete_project_namespace_on_project_delete AFTER DELETE ON projects FOR EACH ROW WHEN ((old.project_namespace_id IS NOT NULL)) EXECUTE FUNCTION delete_associated_project_namespace();
CREATE TRIGGER trigger_has_external_issue_tracker_on_delete AFTER DELETE ON integrations FOR EACH ROW WHEN ((((old.category)::text = 'issue_tracker'::text) AND (old.active = true) AND (old.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_issue_tracker();
@@ -26111,11 +27383,13 @@ CREATE TRIGGER trigger_has_external_issue_tracker_on_insert AFTER INSERT ON inte
CREATE TRIGGER trigger_has_external_issue_tracker_on_update AFTER UPDATE ON integrations FOR EACH ROW WHEN ((((new.category)::text = 'issue_tracker'::text) AND (old.active <> new.active) AND (new.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_issue_tracker();
-CREATE TRIGGER trigger_has_external_wiki_on_delete AFTER DELETE ON integrations FOR EACH ROW WHEN ((((old.type)::text = 'ExternalWikiService'::text) AND (old.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_wiki();
+CREATE TRIGGER trigger_has_external_wiki_on_delete AFTER DELETE ON integrations FOR EACH ROW WHEN (((old.type_new = 'Integrations::ExternalWiki'::text) AND (old.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_wiki();
-CREATE TRIGGER trigger_has_external_wiki_on_insert AFTER INSERT ON integrations FOR EACH ROW WHEN (((new.active = true) AND ((new.type)::text = 'ExternalWikiService'::text) AND (new.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_wiki();
+CREATE TRIGGER trigger_has_external_wiki_on_insert AFTER INSERT ON integrations FOR EACH ROW WHEN (((new.active = true) AND (new.type_new = 'Integrations::ExternalWiki'::text) AND (new.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_wiki();
-CREATE TRIGGER trigger_has_external_wiki_on_update AFTER UPDATE ON integrations FOR EACH ROW WHEN ((((new.type)::text = 'ExternalWikiService'::text) AND (old.active <> new.active) AND (new.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_wiki();
+CREATE TRIGGER trigger_has_external_wiki_on_type_new_updated AFTER UPDATE OF type_new ON integrations FOR EACH ROW WHEN (((new.type_new = 'Integrations::ExternalWiki'::text) AND (new.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_wiki();
+
+CREATE TRIGGER trigger_has_external_wiki_on_update AFTER UPDATE ON integrations FOR EACH ROW WHEN (((new.type_new = 'Integrations::ExternalWiki'::text) AND (old.active <> new.active) AND (new.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_wiki();
CREATE TRIGGER trigger_type_new_on_insert AFTER INSERT ON integrations FOR EACH ROW EXECUTE FUNCTION integrations_set_type_new();
@@ -26134,6 +27408,9 @@ ALTER TABLE ONLY clusters_applications_runners
ALTER TABLE ONLY incident_management_escalation_rules
ADD CONSTRAINT fk_0314ee86eb FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
+ALTER TABLE ONLY service_desk_settings
+ ADD CONSTRAINT fk_03afb71f06 FOREIGN KEY (file_template_project_id) REFERENCES projects(id) ON DELETE SET NULL;
+
ALTER TABLE ONLY design_management_designs_versions
ADD CONSTRAINT fk_03c671965c FOREIGN KEY (design_id) REFERENCES design_management_designs(id) ON DELETE CASCADE;
@@ -26200,6 +27477,9 @@ ALTER TABLE ONLY analytics_devops_adoption_segments
ALTER TABLE ONLY user_details
ADD CONSTRAINT fk_190e4fcc88 FOREIGN KEY (provisioned_by_group_id) REFERENCES namespaces(id) ON DELETE SET NULL;
+ALTER TABLE ONLY agent_project_authorizations
+ ADD CONSTRAINT fk_1d30bb4987 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY vulnerabilities
ADD CONSTRAINT fk_1d37cddf91 FOREIGN KEY (epic_id) REFERENCES epics(id) ON DELETE SET NULL;
@@ -26251,6 +27531,9 @@ ALTER TABLE ONLY geo_event_log
ALTER TABLE ONLY deployments
ADD CONSTRAINT fk_289bba3222 FOREIGN KEY (cluster_id) REFERENCES clusters(id) ON DELETE SET NULL;
+ALTER TABLE ONLY agent_group_authorizations
+ ADD CONSTRAINT fk_2c9f941965 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY ci_freeze_periods
ADD CONSTRAINT fk_2e02bbd1a6 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -26281,6 +27564,9 @@ ALTER TABLE ONLY ci_group_variables
ALTER TABLE ONLY namespaces
ADD CONSTRAINT fk_3448c97865 FOREIGN KEY (push_rule_id) REFERENCES push_rules(id) ON DELETE SET NULL;
+ALTER TABLE ONLY project_topics
+ ADD CONSTRAINT fk_34af9ab07a FOREIGN KEY (topic_id) REFERENCES topics(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY in_product_marketing_emails
ADD CONSTRAINT fk_35c9101b63 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
@@ -26329,9 +27615,6 @@ ALTER TABLE ONLY releases
ALTER TABLE ONLY geo_event_log
ADD CONSTRAINT fk_4a99ebfd60 FOREIGN KEY (repositories_changed_event_id) REFERENCES geo_repositories_changed_events(id) ON DELETE CASCADE;
-ALTER TABLE ONLY dep_ci_build_trace_sections
- ADD CONSTRAINT fk_4ebe41f502 FOREIGN KEY (build_id) REFERENCES ci_builds(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY alert_management_alerts
ADD CONSTRAINT fk_51ab4b6089 FOREIGN KEY (prometheus_alert_id) REFERENCES prometheus_alerts(id) ON DELETE CASCADE;
@@ -26410,6 +27693,9 @@ ALTER TABLE ONLY terraform_state_versions
ALTER TABLE ONLY protected_branch_push_access_levels
ADD CONSTRAINT fk_7111b68cdb FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+ALTER TABLE ONLY projects
+ ADD CONSTRAINT fk_71625606ac FOREIGN KEY (project_namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY integrations
ADD CONSTRAINT fk_71cce407f9 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -26572,6 +27858,9 @@ ALTER TABLE ONLY issues
ALTER TABLE ONLY epics
ADD CONSTRAINT fk_9d480c64b2 FOREIGN KEY (start_date_sourcing_epic_id) REFERENCES epics(id) ON DELETE SET NULL;
+ALTER TABLE ONLY user_group_callouts
+ ADD CONSTRAINT fk_9dc8b9d4b2 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY protected_environments
ADD CONSTRAINT fk_9e112565b7 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
@@ -26626,6 +27915,9 @@ ALTER TABLE ONLY alert_management_alerts
ALTER TABLE ONLY identities
ADD CONSTRAINT fk_aade90f0fc FOREIGN KEY (saml_provider_id) REFERENCES saml_providers(id) ON DELETE CASCADE;
+ALTER TABLE ONLY boards
+ ADD CONSTRAINT fk_ab0a250ff6 FOREIGN KEY (iteration_cadence_id) REFERENCES iterations_cadences(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY dep_ci_build_trace_sections
ADD CONSTRAINT fk_ab7c104e26 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -26674,9 +27966,15 @@ ALTER TABLE ONLY external_status_checks_protected_branches
ALTER TABLE ONLY issue_assignees
ADD CONSTRAINT fk_b7d881734a FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE;
+ALTER TABLE ONLY agent_project_authorizations
+ ADD CONSTRAINT fk_b7fe9b4777 FOREIGN KEY (agent_id) REFERENCES cluster_agents(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY ci_trigger_requests
ADD CONSTRAINT fk_b8ec8b7245 FOREIGN KEY (trigger_id) REFERENCES ci_triggers(id) ON DELETE CASCADE;
+ALTER TABLE ONLY customer_relations_contacts
+ ADD CONSTRAINT fk_b91ddd9345 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY deployments
ADD CONSTRAINT fk_b9a3851b82 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -26713,6 +28011,9 @@ ALTER TABLE ONLY geo_event_log
ALTER TABLE ONLY analytics_cycle_analytics_project_stages
ADD CONSTRAINT fk_c3339bdfc9 FOREIGN KEY (stage_event_hash_id) REFERENCES analytics_cycle_analytics_stage_event_hashes(id) ON DELETE CASCADE;
+ALTER TABLE ONLY user_group_callouts
+ ADD CONSTRAINT fk_c366e12ec3 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY vulnerability_exports
ADD CONSTRAINT fk_c3d3cb5d0f FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
@@ -26797,6 +28098,9 @@ ALTER TABLE ONLY label_links
ALTER TABLE ONLY project_group_links
ADD CONSTRAINT fk_daa8cee94c FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+ALTER TABLE ONLY project_topics
+ ADD CONSTRAINT fk_db13576296 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY security_scans
ADD CONSTRAINT fk_dbc89265b9 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -26815,6 +28119,9 @@ ALTER TABLE ONLY ci_resources
ALTER TABLE ONLY ci_sources_pipelines
ADD CONSTRAINT fk_e1bad85861 FOREIGN KEY (pipeline_id) REFERENCES ci_pipelines(id) ON DELETE CASCADE;
+ALTER TABLE ONLY ci_builds_metadata
+ ADD CONSTRAINT fk_e20479742e FOREIGN KEY (build_id) REFERENCES ci_builds(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY gitlab_subscriptions
ADD CONSTRAINT fk_e2595d00a1 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
@@ -26908,6 +28215,9 @@ ALTER TABLE ONLY dep_ci_build_trace_section_names
ALTER TABLE ONLY ci_stages
ADD CONSTRAINT fk_fb57e6cc56 FOREIGN KEY (pipeline_id) REFERENCES ci_pipelines(id) ON DELETE CASCADE;
+ALTER TABLE ONLY agent_group_authorizations
+ ADD CONSTRAINT fk_fb70782616 FOREIGN KEY (agent_id) REFERENCES cluster_agents(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY system_note_metadata
ADD CONSTRAINT fk_fbd87415c9 FOREIGN KEY (description_version_id) REFERENCES description_versions(id) ON DELETE SET NULL;
@@ -26968,6 +28278,9 @@ ALTER TABLE ONLY incident_management_oncall_participants
ALTER TABLE ONLY events
ADD CONSTRAINT fk_rails_0434b48643 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+ALTER TABLE incident_management_pending_issue_escalations
+ ADD CONSTRAINT fk_rails_0470889ee5 FOREIGN KEY (rule_id) REFERENCES incident_management_escalation_rules(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY ip_restrictions
ADD CONSTRAINT fk_rails_04a93778d5 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
@@ -27223,6 +28536,9 @@ ALTER TABLE ONLY reviews
ALTER TABLE ONLY draft_notes
ADD CONSTRAINT fk_rails_2a8dac9901 FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE CASCADE;
+ALTER TABLE ONLY dependency_proxy_image_ttl_group_policies
+ ADD CONSTRAINT fk_rails_2b1896d021 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY group_group_links
ADD CONSTRAINT fk_rails_2b2353ca49 FOREIGN KEY (shared_with_group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
@@ -27574,6 +28890,9 @@ ALTER TABLE ONLY status_page_published_incidents
ALTER TABLE ONLY deployment_clusters
ADD CONSTRAINT fk_rails_6359a164df FOREIGN KEY (deployment_id) REFERENCES deployments(id) ON DELETE CASCADE;
+ALTER TABLE incident_management_pending_issue_escalations
+ ADD CONSTRAINT fk_rails_636678b3bd FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY evidences
ADD CONSTRAINT fk_rails_6388b435a6 FOREIGN KEY (release_id) REFERENCES releases(id) ON DELETE CASCADE;
@@ -28336,9 +29655,6 @@ ALTER TABLE ONLY packages_packages
ALTER TABLE ONLY cluster_platforms_kubernetes
ADD CONSTRAINT fk_rails_e1e2cf841a FOREIGN KEY (cluster_id) REFERENCES clusters(id) ON DELETE CASCADE;
-ALTER TABLE ONLY ci_builds_metadata
- ADD CONSTRAINT fk_rails_e20479742e FOREIGN KEY (build_id) REFERENCES ci_builds(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY vulnerability_finding_evidences
ADD CONSTRAINT fk_rails_e3205a0c65 FOREIGN KEY (vulnerability_occurrence_id) REFERENCES vulnerability_occurrences(id) ON DELETE CASCADE;
@@ -28525,6 +29841,9 @@ ALTER TABLE ONLY packages_nuget_metadata
ALTER TABLE incident_management_pending_alert_escalations
ADD CONSTRAINT fk_rails_fcbfd9338b FOREIGN KEY (schedule_id) REFERENCES incident_management_oncall_schedules(id) ON DELETE CASCADE;
+ALTER TABLE ONLY customer_relations_contacts
+ ADD CONSTRAINT fk_rails_fd3f2e7572 FOREIGN KEY (organization_id) REFERENCES customer_relations_organizations(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY external_approval_rules
ADD CONSTRAINT fk_rails_fd4f9ac573 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
diff --git a/doc/.vale/gitlab/Acronyms.yml b/doc/.vale/gitlab/Acronyms.yml
index 2d4d0c6909f..122cac6f8a1 100644
--- a/doc/.vale/gitlab/Acronyms.yml
+++ b/doc/.vale/gitlab/Acronyms.yml
@@ -107,6 +107,7 @@ exceptions:
- NTP
- ONLY
- OSS
+ - OTP
- OWASP
- PAT
- PCI-DSS
diff --git a/doc/.vale/gitlab/BadgeCapitalization.yml b/doc/.vale/gitlab/BadgeCapitalization.yml
index 89d6f509d63..33425693d53 100644
--- a/doc/.vale/gitlab/BadgeCapitalization.yml
+++ b/doc/.vale/gitlab/BadgeCapitalization.yml
@@ -10,4 +10,5 @@ link: https://docs.gitlab.com/ee/development/documentation/styleguide/index.html
level: error
scope: raw
raw:
- - '\*\*\(([Ff]ree|[Pp]remium|[Uu]ltimate)( [Ss](elf|ass))?\)\*\*'
+ - '(?!\*\*\((FREE|PREMIUM|ULTIMATE)( (SELF|SAAS))?\)\*\*)'
+ - '(?i)\*\*\((free|premium|ultimate)( (self|saas))?\)\*\*'
diff --git a/doc/.vale/gitlab/CurlStringsQuoted.yml b/doc/.vale/gitlab/CurlStringsQuoted.yml
index c0bc8c18c93..a59fe64d990 100644
--- a/doc/.vale/gitlab/CurlStringsQuoted.yml
+++ b/doc/.vale/gitlab/CurlStringsQuoted.yml
@@ -10,4 +10,4 @@ link: https://docs.gitlab.com/ee/development/documentation/restful_api_styleguid
level: error
scope: code
raw:
- - 'curl.*[^"=]https?://.*'
+ - 'curl [^"]+://.*'
diff --git a/doc/.vale/gitlab/ElementDescriptors.yml b/doc/.vale/gitlab/ElementDescriptors.yml
new file mode 100644
index 00000000000..254da16d00c
--- /dev/null
+++ b/doc/.vale/gitlab/ElementDescriptors.yml
@@ -0,0 +1,14 @@
+---
+# Suggestion: gitlab.ElementDescriptors
+#
+# Suggests the correct way to describe elements in a form.
+#
+# For a list of all options, see https://errata-ai.github.io/vale/styles/
+extends: substitution
+message: 'When describing elements, %s "%s".'
+link: https://docs.gitlab.com/ee/development/documentation/styleguide/index.html#language
+level: suggestion
+ignorecase: true
+swap:
+ button: 'if possible, rewrite to not use'
+ area: 'use "section" instead of'
diff --git a/doc/.vale/gitlab/HeaderGerunds.yml b/doc/.vale/gitlab/HeaderGerunds.yml
deleted file mode 100644
index 9e5fa19f867..00000000000
--- a/doc/.vale/gitlab/HeaderGerunds.yml
+++ /dev/null
@@ -1,14 +0,0 @@
----
-# Suggestion: gitlab.HeaderGerunds
-#
-# Checks for headers that start with gerunds (ing words).
-# Related to: https://docs.gitlab.com/ee/development/documentation/structure.html
-#
-# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
-extends: substitution
-message: 'Can this header start with an imperative verb, instead of a gerund (ing word)?'
-link: https://docs.gitlab.com/ee/development/documentation/styleguide/#heading-titles
-level: suggestion
-scope: heading
-swap:
- - '^\w*ing.*': 'Troubleshooting'
diff --git a/doc/.vale/gitlab/InternalLinkExtension.yml b/doc/.vale/gitlab/InternalLinkExtension.yml
index 0b1baaf667c..5783c4347a9 100644
--- a/doc/.vale/gitlab/InternalLinkExtension.yml
+++ b/doc/.vale/gitlab/InternalLinkExtension.yml
@@ -10,4 +10,4 @@ link: https://docs.gitlab.com/ee/development/documentation/styleguide/index.html
level: error
scope: raw
raw:
- - '\[.+\]\((https?:){0}[\w\/\.-]+(\.html).*?\)'
+ - '\[.+\]\([\w\/\.-]+\.html[^)]*\)'
diff --git a/doc/.vale/gitlab/InternalLinkFormat.yml b/doc/.vale/gitlab/InternalLinkFormat.yml
index 51d5198a0ce..b9ee83b7f5c 100644
--- a/doc/.vale/gitlab/InternalLinkFormat.yml
+++ b/doc/.vale/gitlab/InternalLinkFormat.yml
@@ -10,4 +10,4 @@ link: https://docs.gitlab.com/ee/development/documentation/styleguide/index.html
level: error
scope: raw
raw:
- - '\[.+\]\(\.\/.+?\)'
+ - '\[.+\]\(\.\/.*?\)'
diff --git a/doc/.vale/gitlab/OutdatedVersions.yml b/doc/.vale/gitlab/OutdatedVersions.yml
index 05323726838..15ae0a5814a 100644
--- a/doc/.vale/gitlab/OutdatedVersions.yml
+++ b/doc/.vale/gitlab/OutdatedVersions.yml
@@ -19,3 +19,5 @@ tokens:
- "GitLab (v)?7."
- "GitLab (v)?8."
- "GitLab (v)?9."
+ - "GitLab (v)?10."
+ - "GitLab (v)?11."
diff --git a/doc/.vale/gitlab/ReadingLevel.yml b/doc/.vale/gitlab/ReadingLevel.yml
index 0099e70ec8f..2e78c3ef36c 100644
--- a/doc/.vale/gitlab/ReadingLevel.yml
+++ b/doc/.vale/gitlab/ReadingLevel.yml
@@ -6,6 +6,7 @@
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: readability
message: "Grade level (%s) is high. To lower the score, use shorter sentences and words."
+link: https://docs.gitlab.com/ee/development/documentation/testing.html#vale-readability-score
level: suggestion
grade: 8
metrics:
diff --git a/doc/.vale/gitlab/SubstitutionSuggestions.yml b/doc/.vale/gitlab/SubstitutionSuggestions.yml
index bc9a6e3c70d..e7c0cc04244 100644
--- a/doc/.vale/gitlab/SubstitutionSuggestions.yml
+++ b/doc/.vale/gitlab/SubstitutionSuggestions.yml
@@ -14,7 +14,9 @@ swap:
active user: '"billable user"'
active users: '"billable users"'
docs: '"documentation"'
+ e-mail: '"email"'
GFM: '"GitLab Flavored Markdown"'
+ it is recommended: '"we recommend"'
OAuth2: '"OAuth 2.0"'
once that: '"after that"'
once the: '"after the"'
diff --git a/doc/.vale/gitlab/UnclearAntecedent.yml b/doc/.vale/gitlab/UnclearAntecedent.yml
new file mode 100644
index 00000000000..863bbd4e109
--- /dev/null
+++ b/doc/.vale/gitlab/UnclearAntecedent.yml
@@ -0,0 +1,22 @@
+---
+# Suggestion: gitlab.UnclearAntecedent
+#
+# Checks for words that need a noun for clarity.
+#
+# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
+extends: existence
+message: "'%s' is not precise. Try rewriting with a specific subject and verb."
+link: https://docs.gitlab.com/ee/development/documentation/styleguide/word_list.html#this-these-that-those
+level: suggestion
+ignorecase: false
+tokens:
+ - 'That is'
+ - 'That was'
+ - 'These are'
+ - 'These were'
+ - 'There are'
+ - 'There were'
+ - 'This is'
+ - 'This was'
+ - 'Those are'
+ - 'Those were'
diff --git a/doc/.vale/gitlab/VersionText.yml b/doc/.vale/gitlab/VersionText.yml
index e66a62497b1..fbdda17e2a0 100644
--- a/doc/.vale/gitlab/VersionText.yml
+++ b/doc/.vale/gitlab/VersionText.yml
@@ -9,9 +9,9 @@
# - `> Introduced` (version text without a link)
# - `> [Introduced` (version text with a link)
#
-# Because it excludes `-`, it doesn't look for multi-line version text, for which content
-# immediately on the next line is ok. However, this will often highlight where multi-line version
-# text is attempted without `-` characters.
+# Because it excludes the prefix `> - `, it doesn't look for multi-line version text, for which
+# content immediately on the next line is ok. However, this will often highlight where multi-line
+# version text is attempted without `-` characters.
#
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: existence
@@ -20,4 +20,4 @@ link: https://docs.gitlab.com/ee/development/documentation/styleguide/index.html
level: error
scope: raw
raw:
- - '> (- ){0}\[?Introduced.+\n[^\n`]'
+ - '> \[?Introduced.+\n[^\n]'
diff --git a/doc/.vale/gitlab/spelling-exceptions.txt b/doc/.vale/gitlab/spelling-exceptions.txt
index 43ff584b550..d397a436ff9 100644
--- a/doc/.vale/gitlab/spelling-exceptions.txt
+++ b/doc/.vale/gitlab/spelling-exceptions.txt
@@ -90,6 +90,7 @@ callstack
callstacks
Camo
canonicalized
+captcha
CentOS
Certbot
changeset
@@ -160,7 +161,12 @@ deprovisions
dequarantine
dequarantined
dequarantining
+deserialization
+deserialize
+deserializers
+deserializes
DevOps
+Dhall
disambiguates
discoverability
dismissable
@@ -209,6 +215,7 @@ fixup
Flawfinder
Flowdock
Fluentd
+Flycheck
Forgerock
formatters
Fugit
@@ -469,6 +476,7 @@ queryable
Quicktime
Rackspace
Raspbian
+rbenv
rbtrace
Rdoc
reachability
@@ -815,8 +823,10 @@ Worldline
Xcode
Xeon
YouTrack
+ytt
Yubico
Zeitwerk
Zendesk
+ZenTao
zsh
Zstandard
diff --git a/doc/administration/audit_events.md b/doc/administration/audit_events.md
index 48bd812c7f2..3ff5fb2635d 100644
--- a/doc/administration/audit_events.md
+++ b/doc/administration/audit_events.md
@@ -39,7 +39,7 @@ There are two kinds of events logged:
### Impersonation data
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/536) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/536) in GitLab 13.0.
When a user is being [impersonated](../user/admin_area/index.md#user-impersonation), their actions are logged as audit events as usual, with two additional details:
@@ -48,7 +48,7 @@ When a user is being [impersonated](../user/admin_area/index.md#user-impersonati
![audit events](img/impersonated_audit_events_v13_8.png)
-### Group events **(PREMIUM)**
+### Group events
A user with:
@@ -86,7 +86,7 @@ From there, you can see the following actions:
Group events can also be accessed via the [Group Audit Events API](../api/audit_events.md#group-audit-events)
-### Project events **(PREMIUM)**
+### Project events
A user with a Maintainer role (or above) can retrieve project audit events of all users.
A user with a Developer role is limited to project audit events based on their individual actions.
@@ -126,6 +126,10 @@ From there, you can see the following actions:
- User password required for approvals was updated ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/336211) in GitLab 14.2)
- Permission to modify merge requests approval rules in merge requests was updated ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/336211) in GitLab 14.2)
- New approvals requirement when new commits are added to an MR was updated ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/336211) in GitLab 14.2)
+- When [strategies for feature flags](../operations/feature_flags.md#feature-flag-strategies) are changed ([introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68408) in GitLab 14.3)
+- Allowing force push to protected branch changed ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/338873) in GitLab 14.3)
+- Code owner approval requirement on merge requests targeting protected branch changed ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/338873) in GitLab 14.3)
+- Users and groups allowed to merge and push to protected branch added or removed ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/338873) in GitLab 14.3)
Project events can also be accessed via the [Project Audit Events API](../api/audit_events.md#project-audit-events).
@@ -133,7 +137,7 @@ Project event queries are limited to a maximum of 30 days.
### Instance events **(PREMIUM SELF)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2336) in [GitLab Premium](https://about.gitlab.com/pricing/) 9.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2336) in GitLab 9.3.
Server-wide audit events introduce the ability to observe user actions across
the entire instance of your GitLab server, making it easy to understand who
@@ -143,7 +147,7 @@ Instance events do not include group or project audit events.
To view the server-wide audit events:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Monitoring > Audit Events**.
The following user actions are recorded:
@@ -203,6 +207,8 @@ to request it, or you can [add it yourself](../development/audit_event_guide/).
#### Repository push
+> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/337993) in GitLab 14.3.
+
The current architecture of audit events is not prepared to receive a very high amount of records.
It may make the user interface for your project or audit events very busy, and the disk space consumed by the
`audit_events` PostgreSQL table may increase considerably. It's disabled by default
@@ -240,8 +246,8 @@ The search filters you can see depends on which audit level you are at.
## Export to CSV **(PREMIUM SELF)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/1449) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.4.
-> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/285441) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.7.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/1449) in GitLab 13.4.
+> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/285441) in GitLab 13.7.
Export to CSV allows customers to export the current filter view of your audit events as a
CSV file, which stores tabular data in plain text. The data provides a comprehensive view with respect to
@@ -249,7 +255,7 @@ audit events.
To export the Audit Events to CSV:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Monitoring > Audit Events**.
1. Select the available search [filters](#search).
1. Select **Export as CSV**.
diff --git a/doc/administration/auditor_users.md b/doc/administration/auditor_users.md
index 5f31ed709f2..5498ea9d4be 100644
--- a/doc/administration/auditor_users.md
+++ b/doc/administration/auditor_users.md
@@ -57,7 +57,7 @@ helpful:
To create an Auditor user:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Users**.
1. Create a new user or edit an existing one, and in the **Access** section
select Auditor.
diff --git a/doc/administration/auth/atlassian.md b/doc/administration/auth/atlassian.md
index 868482148e5..b58bbfa8eac 100644
--- a/doc/administration/auth/atlassian.md
+++ b/doc/administration/auth/atlassian.md
@@ -16,7 +16,7 @@ To enable the Atlassian OmniAuth provider for passwordless authentication you mu
1. Click **Create a new app**.
1. Choose an App Name, such as 'GitLab', and click **Create**.
1. Note the `Client ID` and `Secret` for the [GitLab configuration](#gitlab-configuration) steps.
-1. In the left sidebar under **APIS AND FEATURES**, click **OAuth 2.0 (3LO)**.
+1. On the left sidebar under **APIS AND FEATURES**, click **OAuth 2.0 (3LO)**.
1. Enter the GitLab callback URL using the format `https://gitlab.example.com/users/auth/atlassian_oauth2/callback` and click **Save changes**.
1. Click **+ Add** in the left sidebar under **APIS AND FEATURES**.
1. Click **Add** for **Jira platform REST API** and then **Configure**.
diff --git a/doc/administration/auth/ldap/google_secure_ldap.md b/doc/administration/auth/ldap/google_secure_ldap.md
index 55ccf6653a3..137f35986ac 100644
--- a/doc/administration/auth/ldap/google_secure_ldap.md
+++ b/doc/administration/auth/ldap/google_secure_ldap.md
@@ -87,6 +87,7 @@ values obtained during the LDAP client configuration earlier:
password: 'd6V5H8nhMUW9AuDP25abXeLd'
encryption: 'simple_tls'
verify_certificates: true
+ retry_empty_result_with_codes: [80]
tls_options:
cert: |
@@ -159,6 +160,7 @@ values obtained during the LDAP client configuration earlier:
password: 'd6V5H8nhMUW9AuDP25abXeLd'
encryption: 'simple_tls'
verify_certificates: true
+ retry_empty_result_with_codes: [80]
tls_options:
cert: |
@@ -213,7 +215,7 @@ values obtained during the LDAP client configuration earlier:
## Using encrypted credentials
You can optionally store the `bind_dn` and `password` in a separate encrypted configuration file using the
-[same steps as the regular LDAP integration](index.md#using-encrypted-credentials).
+[same steps as the regular LDAP integration](index.md#use-encrypted-credentials).
<!-- ## Troubleshooting
diff --git a/doc/administration/auth/ldap/index.md b/doc/administration/auth/ldap/index.md
index 63e3a0a3686..1992b450338 100644
--- a/doc/administration/auth/ldap/index.md
+++ b/doc/administration/auth/ldap/index.md
@@ -12,24 +12,22 @@ to support user authentication.
This integration works with most LDAP-compliant directory servers, including:
-- Microsoft Active Directory
- - [Microsoft Active Directory Trusts](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc771568(v=ws.10)) are not supported.
-- Apple Open Directory
-- Open LDAP
-- 389 Server
+- Microsoft Active Directory.
+ [Microsoft Active Directory Trusts](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc771568(v=ws.10))
+ are not supported.
+- Apple Open Directory.
+- Open LDAP.
+- 389 Server.
Users added through LDAP take a [licensed seat](../../../subscriptions/self_managed/index.md#billable-users).
-GitLab Enterprise Editions (EE) include enhanced integration,
-including group membership syncing and multiple LDAP server support.
-
## Security
GitLab assumes that LDAP users:
- Are not able to change their LDAP `mail`, `email`, or `userPrincipalName` attributes.
An LDAP user allowed to change their email on the LDAP server can potentially
- [take over any account](#enabling-ldap-sign-in-for-existing-gitlab-users)
+ [take over any account](#enable-ldap-sign-in-for-existing-gitlab-users)
on your GitLab server.
- Have unique email addresses. If not, it's possible for LDAP users with the same
email address to share the same GitLab account.
@@ -42,7 +40,7 @@ the LDAP server, or share email addresses.
Users deleted from the LDAP server are immediately blocked from signing in
to GitLab. However, there's an LDAP check cache time of one hour (which is
-[configurable](#adjusting-ldap-user-sync-schedule) for GitLab Premium users).
+[configurable](#adjust-ldap-user-sync-schedule) for GitLab Premium users).
This means users already signed-in or who are using Git over SSH can access
GitLab for up to one hour. Manually block the user in the GitLab Admin Area
to immediately block all access.
@@ -53,7 +51,7 @@ LDAP-enabled users can authenticate with Git using their GitLab username or
email and LDAP password, even if password authentication for Git is disabled
in the application settings.
-## Enabling LDAP sign-in for existing GitLab users
+## Enable LDAP sign-in for existing GitLab users
When a user signs in to GitLab with LDAP for the first time and their LDAP
email address is the primary email address of an existing GitLab user, the
@@ -74,7 +72,7 @@ See [Google Secure LDAP](google_secure_ldap.md) for detailed configuration instr
## Configuration
-To enable LDAP integration you need to add your LDAP server settings in
+To enable LDAP integration you must add your LDAP server settings in
`/etc/gitlab/gitlab.rb` or `/home/git/gitlab/config/gitlab.yml` for Omnibus
GitLab and installations from source respectively.
@@ -155,7 +153,7 @@ production:
...
```
-### Basic Configuration Settings
+### Basic configuration settings
| Setting | Description | Required | Examples |
|--------------------|-------------|----------|----------|
@@ -169,12 +167,12 @@ production:
| `verify_certificates` | Enables SSL certificate verification if encryption method is `start_tls` or `simple_tls`. Defaults to true. | **{dotted-circle}** No | boolean |
| `timeout` | Set a timeout, in seconds, for LDAP queries. This helps avoid blocking a request if the LDAP server becomes unresponsive. A value of `0` means there is no timeout. (default: `10`) | **{dotted-circle}** No | `10` or `30` |
| `active_directory` | This setting specifies if LDAP server is Active Directory LDAP server. For non-AD servers it skips the AD specific queries. If your LDAP server is not AD, set this to false. | **{dotted-circle}** No | boolean |
-| `allow_username_or_email_login` | If enabled, GitLab ignores everything after the first `@` in the LDAP username submitted by the user on sign-in. If you are using `uid: 'userPrincipalName'` on ActiveDirectory you need to disable this setting, because the userPrincipalName contains an `@`. | **{dotted-circle}** No | boolean |
+| `allow_username_or_email_login` | If enabled, GitLab ignores everything after the first `@` in the LDAP username submitted by the user on sign-in. If you are using `uid: 'userPrincipalName'` on ActiveDirectory you must disable this setting, because the userPrincipalName contains an `@`. | **{dotted-circle}** No | boolean |
| `block_auto_created_users` | To maintain tight control over the number of billable users on your GitLab installation, enable this setting to keep new users blocked until they have been cleared by an administrator (default: false). | **{dotted-circle}** No | boolean |
| `base` | Base where we can search for users. | **{check-circle}** Yes | `'ou=people,dc=gitlab,dc=example'` or `'DC=mydomain,DC=com'` |
| `user_filter` | Filter LDAP users. Format: [RFC 4515](https://tools.ietf.org/search/rfc4515) Note: GitLab does not support `omniauth-ldap`'s custom filter syntax. | **{dotted-circle}** No | For examples, read [Examples of user filters](#examples-of-user-filters). |
| `lowercase_usernames` | If enabled, GitLab converts the name to lower case. | **{dotted-circle}** No | boolean |
-| `retry_empty_result_with_codes` | An array of LDAP query response code that will attempt to retrying the operation if the result/content is empty. | **{dotted-circle}** No | `[80]` |
+| `retry_empty_result_with_codes` | An array of LDAP query response code that attempt to retry the operation if the result/content is empty. For Google Secure LDAP, set this value to `[80]`. | **{dotted-circle}** No | `[80]` |
#### Examples of user filters
@@ -183,17 +181,17 @@ Some examples of the `user_filter` field syntax:
- `'(employeeType=developer)'`
- `'(&(objectclass=user)(|(samaccountname=momo)(samaccountname=toto)))'`
-### SSL Configuration Settings
+### SSL configuration settings
| Setting | Description | Required | Examples |
|---------------|-------------|----------|----------|
-| `ca_file` | Specifies the path to a file containing a PEM-format CA certificate, for example, if you need to use an internal CA. | **{dotted-circle}** No | `'/etc/ca.pem'` |
+| `ca_file` | Specifies the path to a file containing a PEM-format CA certificate, for example, if you need an internal CA. | **{dotted-circle}** No | `'/etc/ca.pem'` |
| `ssl_version` | Specifies the SSL version for OpenSSL to use, if the OpenSSL default is not appropriate. | **{dotted-circle}** No | `'TLSv1_1'` |
| `ciphers` | Specific SSL ciphers to use in communication with LDAP servers. | **{dotted-circle}** No | `'ALL:!EXPORT:!LOW:!aNULL:!eNULL:!SSLv2'` |
| `cert` | Client certificate. | **{dotted-circle}** No | `'-----BEGIN CERTIFICATE----- <REDACTED> -----END CERTIFICATE -----'` |
| `key` | Client private key. | **{dotted-circle}** No | `'-----BEGIN PRIVATE KEY----- <REDACTED> -----END PRIVATE KEY -----'` |
-### Attribute Configuration Settings
+### Attribute configuration settings
LDAP attributes that GitLab uses to create an account for the LDAP user. The specified
attribute can either be the attribute name as a string (for example, `'mail'`), or an
@@ -208,7 +206,7 @@ The user's LDAP sign-in is the attribute specified as `uid` above.
| `first_name` | LDAP attribute for user first name. Used when the attribute configured for `name` does not exist. | **{dotted-circle}** No | `'givenName'` |
| `last_name` | LDAP attribute for user last name. Used when the attribute configured for `name` does not exist. | **{dotted-circle}** No | `'sn'` |
-### LDAP Sync Configuration Settings **(PREMIUM SELF)**
+### LDAP Sync configuration settings **(PREMIUM SELF)**
| Setting | Description | Required | Examples |
|-------------------|-------------|----------|----------|
@@ -261,7 +259,7 @@ Support for nested members in the user filter shouldn't be confused with
GitLab does not support the custom filter syntax used by OmniAuth LDAP.
-#### Escaping special characters
+#### Escape special characters
The `user_filter` DN can contain special characters. For example:
@@ -292,7 +290,7 @@ The `user_filter` DN can contain special characters. For example:
OU=Gitlab \28Inc\29,DC=gitlab,DC=com
```
-### Enabling LDAP username lowercase
+### Enable LDAP username lowercase
Some LDAP servers, depending on their configurations, can return uppercase usernames.
This can lead to several confusing issues such as creating links or namespaces with uppercase names.
@@ -362,10 +360,10 @@ This does not disable [using LDAP credentials for Git access](#git-password-auth
1. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect.
-### Using encrypted credentials
+### Use encrypted credentials
Instead of having the LDAP integration credentials stored in plaintext in the configuration files, you can optionally
-use an encrypted file for the LDAP credentials. To use this feature, you first need to enable
+use an encrypted file for the LDAP credentials. To use this feature, first you must enable
[GitLab encrypted configuration](../../encrypted_configuration.md).
The encrypted configuration for LDAP exists in an encrypted YAML file. By default the file is created at
@@ -451,7 +449,7 @@ If initially your LDAP configuration looked like:
## Encryption
-### TLS Server Authentication
+### TLS server authentication
There are two encryption methods, `simple_tls` and `start_tls`.
@@ -461,7 +459,7 @@ exchanged but no validation of the LDAP server's SSL certificate is performed.
### Limitations
-#### TLS Client Authentication
+#### TLS client authentication
Not implemented by `Net::LDAP`.
@@ -555,7 +553,7 @@ The LDAP sync process:
- Updates existing users.
- Creates new users on first sign in.
-### Adjusting LDAP user sync schedule **(PREMIUM SELF)**
+### Adjust LDAP user sync schedule **(PREMIUM SELF)**
By default, GitLab runs a worker once per day at 01:30 a.m. server time to
check and update GitLab users against LDAP.
@@ -592,7 +590,7 @@ sync to run once every 12 hours at the top of the hour.
If your LDAP supports the `memberof` property, when the user signs in for the
first time GitLab triggers a sync for groups the user should be a member of.
-That way they don't need to wait for the hourly sync to be granted
+That way they don't have to wait for the hourly sync to be granted
access to their groups and projects.
A group sync process runs every hour on the hour, and `group_base` must be set
@@ -635,10 +633,10 @@ following.
1. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect.
-To take advantage of group sync, group owners or maintainers need to [create one
-or more LDAP group links](#adding-group-links).
+To take advantage of group sync, group owners or maintainers must [create one
+or more LDAP group links](#add-group-links).
-### Adding group links **(PREMIUM SELF)**
+### Add group links **(PREMIUM SELF)**
For information on adding group links by using CNs and filters, refer to the
[GitLab groups documentation](../../../user/group/index.md#manage-group-memberships-via-ldap).
@@ -702,15 +700,15 @@ When enabled, the following applies:
- Users are not allowed to share project with other groups or invite members to
a project created in a group.
-To enable it you need to:
+To enable it, you must:
1. [Enable LDAP](#configuration)
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > General**.
1. Expand the **Visibility and access controls** section.
1. Ensure the **Lock memberships to LDAP synchronization** checkbox is selected.
-### Adjusting LDAP group sync schedule **(PREMIUM SELF)**
+### Adjust LDAP group sync schedule **(PREMIUM SELF)**
By default, GitLab runs a group sync process every hour, on the hour.
The values shown are in cron format. If needed, you can use a
diff --git a/doc/administration/auth/ldap/ldap-troubleshooting.md b/doc/administration/auth/ldap/ldap-troubleshooting.md
index 15e8496e915..1952e8afa97 100644
--- a/doc/administration/auth/ldap/ldap-troubleshooting.md
+++ b/doc/administration/auth/ldap/ldap-troubleshooting.md
@@ -145,7 +145,7 @@ may see the following message: `Access denied for your LDAP account`.
We have a workaround, based on toggling the access level of affected users:
-1. As an administrator, on the top bar, select **Menu >** **{admin}** **Admin**.
+1. As an administrator, on the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Users**.
1. Select the name of the affected user.
1. In the user's administrative page, press **Edit** on the top right of the page.
@@ -203,7 +203,7 @@ field contains no data:
To resolve this:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, go to **Settings > General**.
1. Expand both of the following:
- **Account and limit**.
@@ -336,7 +336,7 @@ Gitlab::Auth::Ldap::Person.find_by_uid('<uid>', adapter)
### Group memberships **(PREMIUM SELF)**
-#### Membership(s) not granted **(PREMIUM SELF)**
+#### Membership(s) not granted
Sometimes you may think a particular user should be added to a GitLab group via
LDAP group sync, but for some reason it's not happening. There are several
@@ -345,10 +345,10 @@ things to check to debug the situation.
- Ensure LDAP configuration has a `group_base` specified.
[This configuration](index.md#group-sync) is required for group sync to work properly.
- Ensure the correct [LDAP group link is added to the GitLab
- group](index.md#adding-group-links).
+ group](index.md#add-group-links).
- Check that the user has an LDAP identity:
1. Sign in to GitLab as an administrator user.
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
+ 1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Users**.
1. Search for the user.
1. Open the user by clicking their name. Do not click **Edit**.
@@ -356,7 +356,7 @@ things to check to debug the situation.
an LDAP DN as the 'Identifier'. If not, this user hasn't signed in with
LDAP yet and must do so first.
- You've waited an hour or [the configured
- interval](index.md#adjusting-ldap-group-sync-schedule) for the group to
+ interval](index.md#adjust-ldap-group-sync-schedule) for the group to
sync. To speed up the process, either go to the GitLab group **Group information > Members**
and press **Sync now** (sync one group) or [run the group sync Rake
task](../../raketasks/ldap.md#run-a-group-sync) (sync all groups).
@@ -395,7 +395,7 @@ group sync](#sync-all-groups) in the rails console and [look through the
output](#example-console-output-after-a-group-sync) to see what happens when
GitLab syncs the `admin_group`.
-#### Sync all groups **(PREMIUM SELF)**
+#### Sync all groups
NOTE:
To sync all groups manually when debugging is unnecessary, [use the Rake
@@ -413,7 +413,7 @@ LdapAllGroupsSyncWorker.new.perform
Next, [learn how to read the
output](#example-console-output-after-a-group-sync).
-##### Example console output after a group sync **(PREMIUM SELF)**
+##### Example console output after a group sync
Like the output from the user sync, the output from the [manual group
sync](#sync-all-groups) is also very verbose. However, it contains lots
@@ -503,7 +503,7 @@ stating as such:
No `admin_group` configured for 'ldapmain' provider. Skipping
```
-#### Sync one group **(PREMIUM SELF)**
+#### Sync one group
[Syncing all groups](#sync-all-groups) can produce a lot of noise in the output, which can be
distracting when you're only interested in troubleshooting the memberships of
@@ -525,7 +525,7 @@ EE::Gitlab::Auth::Ldap::Sync::Group.execute_all_providers(group)
The output is similar to
[that you get from syncing all groups](#example-console-output-after-a-group-sync).
-#### Query a group in LDAP **(PREMIUM SELF)**
+#### Query a group in LDAP
When you'd like to confirm that GitLab can read a LDAP group and see all its members,
you can run the following:
diff --git a/doc/administration/auth/smartcard.md b/doc/administration/auth/smartcard.md
index 07c29984552..7e2699d5eb3 100644
--- a/doc/administration/auth/smartcard.md
+++ b/doc/administration/auth/smartcard.md
@@ -28,7 +28,7 @@ GitLab supports two authentication methods:
### Authentication against a local database with X.509 certificates
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/726) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.6 as an experimental feature.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/726) in GitLab 11.6 as an experimental feature.
WARNING:
Smartcard authentication against local databases may change or be removed completely in future
@@ -55,7 +55,7 @@ Certificate:
### Authentication against a local database with X.509 certificates and SAN extension
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8605) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8605) in GitLab 12.3.
Smartcards with X.509 certificates using SAN extensions can be used to authenticate
with GitLab.
@@ -98,7 +98,7 @@ Certificate:
### Authentication against an LDAP server
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7693) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.8 as an experimental feature. Smartcard authentication against an LDAP server may change or be removed completely in future releases.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7693) in GitLab 11.8 as an experimental feature. Smartcard authentication against an LDAP server may change or be removed completely in the future.
GitLab implements a standard way of certificate matching following
[RFC4523](https://tools.ietf.org/html/rfc4523). It uses the
diff --git a/doc/administration/cicd.md b/doc/administration/cicd.md
new file mode 100644
index 00000000000..89fc31822ee
--- /dev/null
+++ b/doc/administration/cicd.md
@@ -0,0 +1,75 @@
+---
+stage: Verify
+group: Pipeline Execution
+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
+type: howto
+---
+
+# GitLab CI/CD instance configuration **(FREE SELF)**
+
+GitLab CI/CD is enabled by default in all new projects on an instance. You can configure
+the instance to have [GitLab CI/CD disabled by default](#disable-gitlab-cicd-in-new-projects)
+in new projects.
+
+You can still choose to [enable GitLab CI/CD in individual projects](../ci/enable_or_disable_ci.md#enable-cicd-in-a-project)
+at any time.
+
+## Disable GitLab CI/CD in new projects
+
+You can set GitLab CI/CD to be disabled by default in all new projects by modifying the settings in:
+
+- `gitlab.yml` for source installations.
+- `gitlab.rb` for Omnibus GitLab installations.
+
+Existing projects that already had CI/CD enabled are unchanged. Also, this setting only changes
+the project default, so project owners can still enable CI/CD in the project settings.
+
+For installations from source:
+
+1. Open `gitlab.yml` with your editor and set `builds` to `false`:
+
+ ```yaml
+ ## Default project features settings
+ default_projects_features:
+ issues: true
+ merge_requests: true
+ wiki: true
+ snippets: false
+ builds: false
+ ```
+
+1. Save the `gitlab.yml` file.
+
+1. Restart GitLab:
+
+ ```shell
+ sudo service gitlab restart
+ ```
+
+For Omnibus GitLab installations:
+
+1. Edit `/etc/gitlab/gitlab.rb` and add this line:
+
+ ```ruby
+ gitlab_rails['gitlab_default_projects_features_builds'] = false
+ ```
+
+1. Save the `/etc/gitlab/gitlab.rb` file.
+
+1. Reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/administration/clusters/kas.md b/doc/administration/clusters/kas.md
index 8e5c162001e..6afaff73396 100644
--- a/doc/administration/clusters/kas.md
+++ b/doc/administration/clusters/kas.md
@@ -129,3 +129,25 @@ or the path to `config.yaml` inside the project is not valid.
To fix this, ensure that the paths to the configuration repository and to the `config.yaml` file
are correct.
+
+### KAS logs - `dial tcp <GITLAB_INTERNAL_IP>:443: connect: connection refused`
+
+If you are running a self-managed GitLab instance and:
+
+- The instance isn't running behind an SSL-terminating proxy.
+- The instance doesn't have HTTPS configured on the GitLab instance itself.
+- The instance's hostname resolves locally to its internal IP address.
+
+You may see the following error when the KAS tries to connect to the GitLab API:
+
+```json
+{"level":"error","time":"2021-08-16T14:56:47.289Z","msg":"GetAgentInfo()","correlation_id":"01FD7QE35RXXXX8R47WZFBAXTN","grpc_service":"gitlab.agent.reverse_tunnel.rpc.ReverseTunnel","grpc_method":"Connect","error":"Get \"https://gitlab.example.com/api/v4/internal/kubernetes/agent_info\": dial tcp 172.17.0.4:443: connect: connection refused"}
+```
+
+To fix this for [Omnibus](https://docs.gitlab.com/omnibus/) package installations,
+set the following parameter in `/etc/gitlab/gitlab.rb`
+(replacing `gitlab.example.com` with your GitLab instance's hostname):
+
+```ruby
+gitlab_kas['gitlab_address'] = 'http://gitlab.example.com'
+```
diff --git a/doc/administration/compliance.md b/doc/administration/compliance.md
index e356ef0366b..1761af1ffa1 100644
--- a/doc/administration/compliance.md
+++ b/doc/administration/compliance.md
@@ -31,3 +31,4 @@ relevant compliance standards.
|**[Compliance frameworks](../user/project/settings/index.md#compliance-frameworks)**<br>Create a custom compliance framework at the group level to describe the type of compliance requirements any child project needs to follow. | Premium+ | **{check-circle}** Yes | Group |
|**[Compliance pipelines](../user/project/settings/index.md#compliance-pipeline-configuration)**<br>Define a pipeline configuration to run for any projects with a given compliance framework. | Ultimate | **{check-circle}** Yes | Group |
|**[Compliance report](../user/compliance/compliance_report/index.md)**<br>Quickly get visibility into the compliance posture of your organization. | Ultimate | **{check-circle}** Yes | Group |
+|**[External Status Checks](../user/project/merge_requests/status_checks.md)**<br>Interface with third party systems you already use during development to ensure you remain compliant. | Ultimate | **{check-circle}** Yes | Project |
diff --git a/doc/administration/configure.md b/doc/administration/configure.md
index 73fbf527fe1..d3e37b4a0ee 100644
--- a/doc/administration/configure.md
+++ b/doc/administration/configure.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
-# Configure your GitLab installation
+# Configure your GitLab installation **(FREE SELF)**
Customize and configure your self-managed GitLab installation.
diff --git a/doc/administration/consul.md b/doc/administration/consul.md
index c88047c4c61..72b3487a549 100644
--- a/doc/administration/consul.md
+++ b/doc/administration/consul.md
@@ -21,7 +21,7 @@ Before configuring Consul:
1. Review the [reference architecture](reference_architectures/index.md#available-reference-architectures)
documentation to determine the number of Consul server nodes you should have.
-1. If necessary, ensure the [appropriate ports are open](https://docs.gitlab.com/omnibus/package-information/defaults.html#ports) in your firewall.
+1. If necessary, ensure the [appropriate ports are open](package_information/defaults.md#ports) in your firewall.
## Configure the Consul nodes
diff --git a/doc/administration/database_load_balancing.md b/doc/administration/database_load_balancing.md
index 7d17b22a4d7..45f27a8a8f2 100644
--- a/doc/administration/database_load_balancing.md
+++ b/doc/administration/database_load_balancing.md
@@ -117,9 +117,9 @@ For Sidekiq, we can define
[data consistency](../development/sidekiq_style_guide.md#job-data-consistency-strategies)
requirements for a specific job.
-## Service Discovery
+## Service Discovery **(PREMIUM SELF)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/5883) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/5883) in GitLab 11.0.
Service discovery allows GitLab to automatically retrieve a list of secondary
databases to use, instead of having to manually specify these in the
@@ -237,9 +237,9 @@ For example:
{"severity":"INFO","time":"2019-09-02T12:12:01.728Z","correlation_id":"abcdefg","event":"host_online","message":"Host came back online","db_host":"111.222.333.444","db_port":null,"tag":"rails.database_load_balancing","environment":"production","hostname":"web-example-1","fqdn":"gitlab.example.com","path":null,"params":null}
```
-## Handling Stale Reads
+## Handling Stale Reads **(PREMIUM SELF)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/3526) in [GitLab Premium](https://about.gitlab.com/pricing/) 10.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/3526) in GitLab 10.3.
To prevent reading from an outdated secondary the load balancer checks if it
is in sync with the primary. If the data is determined to be recent enough the
diff --git a/doc/administration/encrypted_configuration.md b/doc/administration/encrypted_configuration.md
index 8afe30d20ab..9224def4a5a 100644
--- a/doc/administration/encrypted_configuration.md
+++ b/doc/administration/encrypted_configuration.md
@@ -11,8 +11,8 @@ type: reference
GitLab can read settings for certain features from encrypted settings files. The supported features are:
-- [LDAP `user_bn` and `password`](auth/ldap/index.md#using-encrypted-credentials)
-- [SMTP `user_name` and `password`](raketasks/smtp.md#secrets)
+- [LDAP `user_bn` and `password`](auth/ldap/index.md#use-encrypted-credentials).
+- [SMTP `user_name` and `password`](raketasks/smtp.md#secrets).
In order to enable the encrypted configuration settings, a new base key needs to be generated for
`encrypted_settings_key_base`. The secret can be generated in the following ways:
@@ -35,4 +35,4 @@ The new secret can be generated by running:
bundle exec rake gitlab:env:info RAILS_ENV=production GITLAB_GENERATE_ENCRYPTED_SETTINGS_KEY_BASE=true
```
-This prints general information on the GitLab instance, but also causes the key to be generated in `<path-to-gitlab-rails>/config/secrets.yml`
+This prints general information on the GitLab instance, but also causes the key to be generated in `<path-to-gitlab-rails>/config/secrets.yml`.
diff --git a/doc/administration/geo/disaster_recovery/background_verification.md b/doc/administration/geo/disaster_recovery/background_verification.md
index 65e0ffd4366..caa806c92c8 100644
--- a/doc/administration/geo/disaster_recovery/background_verification.md
+++ b/doc/administration/geo/disaster_recovery/background_verification.md
@@ -60,7 +60,7 @@ Feature.enable('geo_repository_verification')
On the **primary** node:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Geo > Nodes**.
1. Expand **Verification information** tab for that node to view automatic checksumming
status for repositories and wikis. Successes are shown in green, pending work
@@ -70,7 +70,7 @@ On the **primary** node:
On the **secondary** node:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Geo > Nodes**.
1. Expand **Verification information** tab for that node to view automatic checksumming
status for repositories and wikis. Successes are shown in green, pending work
@@ -89,7 +89,7 @@ in sync.
## Repository re-verification
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/8550) in GitLab Enterprise Edition 11.6. Available in [GitLab Premium](https://about.gitlab.com/pricing/).
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/8550) in GitLab 11.6.
Due to bugs or transient infrastructure failures, it is possible for Git
repositories to change unexpectedly without being marked for verification.
@@ -100,7 +100,7 @@ increase load and vice versa.
On the **primary** node:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Geo > Nodes**.
1. Select **Edit** for the **primary** node to customize the minimum
re-verification interval:
@@ -151,7 +151,7 @@ sudo gitlab-rake geo:verification:wiki:reset
If the **primary** and **secondary** nodes have a checksum verification mismatch, the cause may not be apparent. To find the cause of a checksum mismatch:
1. On the **primary** node:
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
+ 1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Projects**.
1. Find the project that you want to check the checksum differences and
select its name.
diff --git a/doc/administration/geo/disaster_recovery/planned_failover.md b/doc/administration/geo/disaster_recovery/planned_failover.md
index 8b55bebb42b..a7a64701cbd 100644
--- a/doc/administration/geo/disaster_recovery/planned_failover.md
+++ b/doc/administration/geo/disaster_recovery/planned_failover.md
@@ -111,7 +111,7 @@ ensure these processes are close to 100% as possible during active use.
On the **secondary** node:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Geo > Nodes**.
Replicated objects (shown in green) should be close to 100%,
and there should be no failures (shown in red). If a large proportion of
@@ -139,7 +139,7 @@ This [content was moved to another location](background_verification.md).
On the **primary** node:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Messages**.
1. Add a message notifying users on the maintenance window.
You can check under **Geo > Nodes** to estimate how long it
@@ -152,7 +152,7 @@ To ensure that all data is replicated to a secondary site, updates (write reques
be disabled on the **primary** site:
1. Enable [maintenance mode](../../maintenance_mode/index.md) on the **primary** node.
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
1. On the Sidekiq dashboard, select **Cron**.
1. Select `Disable All` to disable non-Geo periodic background jobs.
@@ -165,7 +165,7 @@ be disabled on the **primary** site:
1. If you are manually replicating any data not managed by Geo, trigger the
final replication process now.
1. On the **primary** node:
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
+ 1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
1. On the Sidekiq dashboard, select **Queues**, and wait for all queues except
those with `geo` in the name to drop to 0.
@@ -180,7 +180,7 @@ be disabled on the **primary** site:
- The Geo log cursor is up to date (0 events behind).
1. On the **secondary** node:
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
+ 1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
1. On the Sidekiq dashboard, select **Queues**, and wait for all the `geo`
queues to drop to 0 queued and 0 running jobs.
diff --git a/doc/administration/geo/disaster_recovery/runbooks/planned_failover_multi_node.md b/doc/administration/geo/disaster_recovery/runbooks/planned_failover_multi_node.md
index 27990748071..4255fba83f6 100644
--- a/doc/administration/geo/disaster_recovery/runbooks/planned_failover_multi_node.md
+++ b/doc/administration/geo/disaster_recovery/runbooks/planned_failover_multi_node.md
@@ -65,7 +65,7 @@ promote a Geo replica and perform a failover.
On the **secondary** node:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Geo > Nodes** to see its status.
Replicated objects (shown in green) should be close to 100%,
and there should be no failures (shown in red). If a large proportion of
@@ -130,7 +130,7 @@ follow these steps to avoid unnecessary data loss:
connection.
1. On the **primary** node:
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
+ 1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
1. On the Sidekiq dhasboard, select **Cron**.
1. Select `Disable All` to disable any non-Geo periodic background jobs.
@@ -148,7 +148,7 @@ follow these steps to avoid unnecessary data loss:
[data not managed by Geo](../../replication/datatypes.md#limitations-on-replicationverification),
trigger the final replication process now.
1. On the **primary** node:
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
+ 1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
1. On the Sidekiq dashboard, select **Queues**, and wait for all queues except
those with `geo` in the name to drop to 0.
@@ -163,7 +163,7 @@ follow these steps to avoid unnecessary data loss:
- The Geo log cursor is up to date (0 events behind).
1. On the **secondary** node:
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
+ 1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
1. On the Sidekiq dashboard, select **Queues**, and wait for all the `geo`
queues to drop to 0 queued and 0 running jobs.
diff --git a/doc/administration/geo/disaster_recovery/runbooks/planned_failover_single_node.md b/doc/administration/geo/disaster_recovery/runbooks/planned_failover_single_node.md
index 9d5e65cd194..18923da1056 100644
--- a/doc/administration/geo/disaster_recovery/runbooks/planned_failover_single_node.md
+++ b/doc/administration/geo/disaster_recovery/runbooks/planned_failover_single_node.md
@@ -115,7 +115,7 @@ follow these steps to avoid unnecessary data loss:
connection.
1. On the **primary** node:
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
+ 1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
1. On the Sidekiq dhasboard, select **Cron**.
1. Select `Disable All` to disable any non-Geo periodic background jobs.
@@ -133,7 +133,7 @@ follow these steps to avoid unnecessary data loss:
[data not managed by Geo](../../replication/datatypes.md#limitations-on-replicationverification),
trigger the final replication process now.
1. On the **primary** node:
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
+ 1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
1. On the Sidekiq dashboard, select **Queues**, and wait for all queues except
those with `geo` in the name to drop to 0.
@@ -148,7 +148,7 @@ follow these steps to avoid unnecessary data loss:
- The Geo log cursor is up to date (0 events behind).
1. On the **secondary** node:
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
+ 1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
1. On the Sidekiq dashboard, select **Queues**, and wait for all the `geo`
queues to drop to 0 queued and 0 running jobs.
diff --git a/doc/administration/geo/index.md b/doc/administration/geo/index.md
index 7175d41abd8..48091967189 100644
--- a/doc/administration/geo/index.md
+++ b/doc/administration/geo/index.md
@@ -7,12 +7,6 @@ type: howto
# Geo **(PREMIUM SELF)**
-> - Introduced in GitLab Enterprise Edition 8.9.
-> - Using Geo in combination with
-> [multi-node architectures](../reference_architectures/index.md)
-> is considered **Generally Available** (GA) in
-> [GitLab Premium](https://about.gitlab.com/pricing/) 10.4.
-
Geo is the solution for widely distributed development teams and for providing a warm-standby as part of a disaster recovery strategy.
## Overview
@@ -144,7 +138,7 @@ The following table lists basic ports that must be open between the **primary**
| 22 | 22 | TCP |
| 5432 | | PostgreSQL |
-See the full list of ports used by GitLab in [Package defaults](https://docs.gitlab.com/omnibus/package-information/defaults.html)
+See the full list of ports used by GitLab in [Package defaults](../package_information/defaults.md)
NOTE:
[Web terminal](../../ci/environments/index.md#web-terminals) support requires your load balancer to correctly handle WebSocket connections.
@@ -214,11 +208,11 @@ For information on configuring Geo, see [Geo configuration](replication/configur
### Updating Geo
-For information on how to update your Geo site(s) to the latest GitLab version, see [Updating the Geo sites](replication/updating_the_geo_nodes.md).
+For information on how to update your Geo site(s) to the latest GitLab version, see [Updating the Geo sites](replication/updating_the_geo_sites.md).
### Pausing and resuming replication
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35913) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.2.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35913) in GitLab 13.2.
WARNING:
In GitLab 13.2 and 13.3, promoting a secondary site to a primary while the
@@ -230,7 +224,7 @@ WARNING:
Pausing and resuming of replication is currently only supported for Geo installations using an
Omnibus GitLab-managed database. External databases are currently not supported.
-In some circumstances, like during [upgrades](replication/updating_the_geo_nodes.md) or a [planned failover](disaster_recovery/planned_failover.md), it is desirable to pause replication between the primary and secondary.
+In some circumstances, like during [upgrades](replication/updating_the_geo_sites.md) or a [planned failover](disaster_recovery/planned_failover.md), it is desirable to pause replication between the primary and secondary.
Pausing and resuming replication is done via a command line tool from the a node in the secondary site where the `postgresql` service is enabled.
diff --git a/doc/administration/geo/replication/configuration.md b/doc/administration/geo/replication/configuration.md
index 5b22741f578..88f1ad5b490 100644
--- a/doc/administration/geo/replication/configuration.md
+++ b/doc/administration/geo/replication/configuration.md
@@ -199,7 +199,7 @@ keys must be manually replicated to the **secondary** site.
gitlab-ctl reconfigure
```
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Geo > Sites**.
1. Select **New site**.
![Add secondary site](img/adding_a_secondary_v13_3.png)
@@ -257,7 +257,7 @@ method to be enabled. This is enabled by default, but if converting an existing
On the **primary** site:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > General**.
1. Expand **Visibility and access controls**.
1. Ensure "Enabled Git access protocols" is set to either "Both SSH and HTTP(S)" or "Only HTTP(S)".
@@ -267,7 +267,7 @@ On the **primary** site:
You can sign in to the **secondary** site with the same credentials you used with
the **primary** site. After you sign in:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Geo > Sites**.
1. Verify that it's correctly identified as a **secondary** Geo site, and that
Geo is enabled.
@@ -338,7 +338,7 @@ when:
## Upgrading Geo
-See the [updating the Geo sites document](updating_the_geo_nodes.md).
+See the [updating the Geo sites document](updating_the_geo_sites.md).
## Troubleshooting
diff --git a/doc/administration/geo/replication/datatypes.md b/doc/administration/geo/replication/datatypes.md
index a696e5410e5..3f38436429a 100644
--- a/doc/administration/geo/replication/datatypes.md
+++ b/doc/administration/geo/replication/datatypes.md
@@ -47,12 +47,16 @@ verification methods:
| Blobs | Container registry _(object storage)_ | Geo with API/Managed/Docker API (*2*) | _Not implemented_ |
| Blobs | Package registry _(file system)_ | Geo with API | SHA256 checksum |
| Blobs | Package registry _(object storage)_ | Geo with API/Managed (*2*) | _Not implemented_ |
+| Blobs | Infrastructure registry _(file system)_ | Geo with API | SHA256 checksum |
+| Blobs | Infrastructure registry _(object storage)_ | Geo with API/Managed (*2*) | _Not implemented_ |
| Blobs | Versioned Terraform State _(file system)_ | Geo with API | SHA256 checksum |
| Blobs | Versioned Terraform State _(object storage)_ | Geo with API/Managed (*2*) | _Not implemented_ |
| Blobs | External Merge Request Diffs _(file system)_ | Geo with API | _Not implemented_ |
| Blobs | External Merge Request Diffs _(object storage)_ | Geo with API/Managed (*2*) | _Not implemented_ |
| Blobs | Pipeline artifacts _(file system)_ | Geo with API | SHA256 checksum |
| Blobs | Pipeline artifacts _(object storage)_ | Geo with API/Managed (*2*) | SHA256 checksum |
+| Blobs | Pages _(file system)_ | Geo with API | _Not implemented_ |
+| Blobs | Pages _(object storage)_ | Geo with API/Managed (*2*) | _Not implemented_ |
- (*1*): Redis replication can be used as part of HA with Redis sentinel. It's not used between Geo sites.
- (*2*): Object storage replication can be performed by Geo or by your object storage provider/appliance
@@ -189,21 +193,15 @@ successfully, you must replicate their data using some other means.
|[Job logs](../../job_logs.md) | **Yes** (10.4) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/8923) | Via Object Storage provider if supported. Native Geo support (Beta). | Verified only on transfer or manually using [Integrity Check Rake Task](../../raketasks/check.md) on both sites and comparing the output between them. |
|[Container Registry](../../packages/container_registry.md) | **Yes** (12.3) | No | No | Disabled by default. See [instructions](docker_registry.md) to enable. |
|[Content in object storage (beta)](object_storage.md) | **Yes** (12.4) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/13845) | No | |
-|[Infrastructure Registry for Terraform Module](../../../user/packages/terraform_module_registry/index.md) | **Yes** (14.0) | [**Yes**](#limitation-of-verification-for-files-in-object-storage) (14.0) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default. |
+|[Infrastructure Registry](../../../user/packages/infrastructure_registry/index.md) | **Yes** (14.0) | [**Yes**](#limitation-of-verification-for-files-in-object-storage) (14.0) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default. |
|[Project designs repository](../../../user/project/issues/design_management.md) | **Yes** (12.7) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/32467) | No | Designs also require replication of LFS objects and Uploads. |
-|[Package Registry for npm](../../../user/packages/npm_registry/index.md) | **Yes** (13.2) | [**Yes**](#limitation-of-verification-for-files-in-object-storage) (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default. |
-|[Package Registry for Maven](../../../user/packages/maven_repository/index.md) | **Yes** (13.2) | [**Yes**](#limitation-of-verification-for-files-in-object-storage) (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default. |
-|[Package Registry for Conan](../../../user/packages/conan_repository/index.md) | **Yes** (13.2) | [**Yes**](#limitation-of-verification-for-files-in-object-storage) (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default. |
-|[Package Registry for NuGet](../../../user/packages/nuget_repository/index.md) | **Yes** (13.2) | [**Yes**](#limitation-of-verification-for-files-in-object-storage) (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default. |
-|[Package Registry for PyPI](../../../user/packages/pypi_repository/index.md) | **Yes** (13.2) | [**Yes**](#limitation-of-verification-for-files-in-object-storage) (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default. |
-|[Package Registry for Composer](../../../user/packages/composer_repository/index.md) | **Yes** (13.2) | [**Yes**](#limitation-of-verification-for-files-in-object-storage) (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default. |
-|[Package Registry for generic packages](../../../user/packages/generic_packages/index.md) | **Yes** (13.5) | [**Yes**](#limitation-of-verification-for-files-in-object-storage) (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default. |
+|[Package Registry](../../../user/packages/package_registry/index.md) | **Yes** (13.2) | [**Yes**](#limitation-of-verification-for-files-in-object-storage) (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default. |
|[Versioned Terraform State](../../terraform_state.md) | **Yes** (13.5) | [**Yes**](#limitation-of-verification-for-files-in-object-storage) (13.12) | Via Object Storage provider if supported. Native Geo support (Beta). | Replication is behind the feature flag `geo_terraform_state_version_replication`, enabled by default. Verification was behind the feature flag `geo_terraform_state_version_verification`, which was removed in 14.0|
|[External merge request diffs](../../merge_request_diffs.md) | **Yes** (13.5) | No | Via Object Storage provider if supported. Native Geo support (Beta). | Replication is behind the feature flag `geo_merge_request_diff_replication`, enabled by default. Verification is under development, behind the feature flag `geo_merge_request_diff_verification`, introduced in 14.0.|
|[Versioned snippets](../../../user/snippets.md#versioned-snippets) | [**Yes** (13.7)](https://gitlab.com/groups/gitlab-org/-/epics/2809) | [**Yes** (14.2)](https://gitlab.com/groups/gitlab-org/-/epics/2810) | No | Verification was implemented behind the feature flag `geo_snippet_repository_verification` in 13.11, and the feature flag was removed in 14.2. |
|[Server-side Git hooks](../../server_hooks.md) | [No](https://gitlab.com/groups/gitlab-org/-/epics/1867) | No | No | |
|[Elasticsearch integration](../../../integration/elasticsearch.md) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/1186) | No | No | |
-|[GitLab Pages](../../pages/index.md) | [No](https://gitlab.com/groups/gitlab-org/-/epics/589) | No | Via Object Storage provider if supported. **No** native Geo support (Beta). | |
+|[GitLab Pages](../../pages/index.md) | [**Yes** (14.3)](https://gitlab.com/groups/gitlab-org/-/epics/589) | No | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_pages_deployment_replication`, enabled by default. |
|[Dependency proxy images](../../../user/packages/dependency_proxy/index.md) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/259694) | No | No | Blocked on [Geo: Secondary Mimicry](https://gitlab.com/groups/gitlab-org/-/epics/1528). Replication of this cache is not needed for Disaster Recovery purposes because it can be recreated from external sources. |
|[Vulnerability Export](../../../user/application_security/vulnerability_report/#export-vulnerability-details) | [Not planned](https://gitlab.com/groups/gitlab-org/-/epics/3111) | No | | Not planned because they are ephemeral and sensitive. They can be regenerated on demand. |
diff --git a/doc/administration/geo/replication/disable_geo.md b/doc/administration/geo/replication/disable_geo.md
index 485a5ee1950..ae2597ad649 100644
--- a/doc/administration/geo/replication/disable_geo.md
+++ b/doc/administration/geo/replication/disable_geo.md
@@ -36,7 +36,7 @@ to do that.
To remove the **primary** site:
1. [Remove all secondary Geo sites](remove_geo_site.md)
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Geo > Nodes**.
1. Select **Remove** for the **primary** node.
1. Confirm by selecting **Remove** when the prompt appears.
diff --git a/doc/administration/geo/replication/docker_registry.md b/doc/administration/geo/replication/docker_registry.md
index 5cc4f66017b..4004ef3c17f 100644
--- a/doc/administration/geo/replication/docker_registry.md
+++ b/doc/administration/geo/replication/docker_registry.md
@@ -130,7 +130,7 @@ For each application and Sidekiq node on the **secondary** site:
To verify Container Registry replication is working, on the **secondary** site:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Geo > Nodes**.
The initial replication, or "backfill", is probably still in progress.
diff --git a/doc/administration/geo/replication/faq.md b/doc/administration/geo/replication/faq.md
index 28030dccb3b..70a6e506c28 100644
--- a/doc/administration/geo/replication/faq.md
+++ b/doc/administration/geo/replication/faq.md
@@ -52,7 +52,7 @@ query.
## Can I `git push` to a **secondary** site?
-Yes! Pushing directly to a **secondary** site (for both HTTP and SSH, including Git LFS) was [introduced](https://about.gitlab.com/releases/2018/09/22/gitlab-11-3-released/) in [GitLab Premium](https://about.gitlab.com/pricing/#self-managed) 11.3.
+Yes! Pushing directly to a **secondary** site (for both HTTP and SSH, including Git LFS) was [introduced](https://about.gitlab.com/releases/2018/09/22/gitlab-11-3-released/) in GitLab 11.3.
## How long does it take to have a commit replicated to a **secondary** site?
diff --git a/doc/administration/geo/replication/object_storage.md b/doc/administration/geo/replication/object_storage.md
index d3931c0ba80..1f799b30125 100644
--- a/doc/administration/geo/replication/object_storage.md
+++ b/doc/administration/geo/replication/object_storage.md
@@ -9,15 +9,19 @@ type: howto
Geo can be used in combination with Object Storage (AWS S3, or other compatible object storage).
-The storage method for files is recorded in the database, and the database is replicated
-from the **primary** Geo site to the **secondary** Geo site, so the **secondary** Geo site
-must match the storage method of the **primary** Geo site.
-Therefore, if the **primary** Geo site uses object storage, the **secondary** Geo site must use it too.
-
Currently, **secondary** sites can use either:
- The same storage bucket as the **primary** site.
- A replicated storage bucket.
+- Local storage, if the primary uses local storage.
+
+The storage method (local or object storage) for files is recorded in the database, and the database
+is replicated from the **primary** Geo site to the **secondary** Geo site.
+
+When accessing an uploaded object, we get its storage method (local or object storage) from the
+database, so the **secondary** Geo site must match the storage method of the **primary** Geo site.
+
+Therefore, if the **primary** Geo site uses object storage, the **secondary** Geo site must use it too.
To have:
@@ -38,7 +42,7 @@ whether they are stored on the local file system or in object storage.
To enable GitLab replication:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Geo > Nodes**.
1. Select **Edit** on the **secondary** site.
1. In the **Synchronization Settings** section, find the **Allow this secondary node to replicate content on Object Storage**
diff --git a/doc/administration/geo/replication/remove_geo_site.md b/doc/administration/geo/replication/remove_geo_site.md
index 274eb28dbc9..b69dfe2e723 100644
--- a/doc/administration/geo/replication/remove_geo_site.md
+++ b/doc/administration/geo/replication/remove_geo_site.md
@@ -9,7 +9,7 @@ type: howto
**Secondary** sites can be removed from the Geo cluster using the Geo administration page of the **primary** site. To remove a **secondary** site:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Geo > Nodes**.
1. Select the **Remove** button for the **secondary** site you want to remove.
1. Confirm by selecting **Remove** when the prompt appears.
diff --git a/doc/administration/geo/replication/troubleshooting.md b/doc/administration/geo/replication/troubleshooting.md
index e072696b37c..7b82d742bd5 100644
--- a/doc/administration/geo/replication/troubleshooting.md
+++ b/doc/administration/geo/replication/troubleshooting.md
@@ -27,7 +27,7 @@ Before attempting more advanced troubleshooting:
On the **primary** node:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Geo > Nodes**.
We perform the following health checks on each **secondary** node
@@ -610,7 +610,7 @@ to start again from scratch, there are a few steps that can help you:
### Design repository failures on mirrored projects and project imports
-On the top bar, under **Menu >** **{admin}** **Admin > Geo > Nodes**,
+On the top bar, under **Menu > Admin > Geo > Nodes**,
if the Design repositories progress bar shows
`Synced` and `Failed` greater than 100%, and negative `Queued`, then the instance
is likely affected by
@@ -836,7 +836,7 @@ node's URL matches its external URL.
On the **primary** node:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Geo > Nodes**.
1. Find the affected **secondary** site and select **Edit**.
1. Ensure the **URL** field matches the value found in `/etc/gitlab/gitlab.rb`
diff --git a/doc/administration/geo/replication/tuning.md b/doc/administration/geo/replication/tuning.md
index 9807f3e6444..bcff6181296 100644
--- a/doc/administration/geo/replication/tuning.md
+++ b/doc/administration/geo/replication/tuning.md
@@ -14,7 +14,7 @@ in the background.
On the **primary** site:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Geo > Nodes**.
1. Select **Edit** of the secondary node you want to tune.
1. Under **Tuning settings**, there are several variables that can be tuned to
diff --git a/doc/administration/geo/replication/updating_the_geo_nodes.md b/doc/administration/geo/replication/updating_the_geo_nodes.md
index 03570048071..f07c8d547a4 100644
--- a/doc/administration/geo/replication/updating_the_geo_nodes.md
+++ b/doc/administration/geo/replication/updating_the_geo_nodes.md
@@ -1,52 +1,9 @@
---
-stage: Enablement
-group: Geo
-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
-type: howto
+redirect_to: 'updating_the_geo_sites.md'
+remove_date: '2021-11-23'
---
-# Updating the Geo nodes **(PREMIUM SELF)**
+This file was moved to [another location](updating_the_geo_sites.md).
-WARNING:
-Read these sections carefully before updating your Geo nodes. Not following
-version-specific update steps may result in unexpected downtime. If you have
-any specific questions, [contact Support](https://about.gitlab.com/support/#contact-support).
-
-Updating Geo nodes involves performing:
-
-1. [Version-specific update steps](version_specific_updates.md), depending on the
- version being updated to or from.
-1. [General update steps](#general-update-steps), for all updates.
-
-## General update steps
-
-NOTE:
-These general update steps are not intended for [high-availability deployments](https://docs.gitlab.com/omnibus/update/README.html#multi-node--ha-deployment), and will cause downtime. If you want to avoid downtime, consider using [zero downtime updates](https://docs.gitlab.com/omnibus/update/README.html#zero-downtime-updates).
-
-To update the Geo nodes when a new GitLab version is released, update **primary**
-and all **secondary** nodes:
-
-1. **Optional:** [Pause replication on each **secondary** node.](../index.md#pausing-and-resuming-replication)
-1. Log into the **primary** node.
-1. [Update GitLab on the **primary** node using Omnibus](https://docs.gitlab.com/omnibus/update/#update-using-the-official-repositories).
-1. Log into each **secondary** node.
-1. [Update GitLab on each **secondary** node using Omnibus](https://docs.gitlab.com/omnibus/update/#update-using-the-official-repositories).
-1. If you paused replication in step 1, [resume replication on each **secondary**](../index.md#pausing-and-resuming-replication)
-1. [Test](#check-status-after-updating) **primary** and **secondary** nodes, and check version in each.
-
-### Check status after updating
-
-Now that the update process is complete, you may want to check whether
-everything is working correctly:
-
-1. Run the Geo Rake task on all nodes, everything should be green:
-
- ```shell
- sudo gitlab-rake gitlab:geo:check
- ```
-
-1. Check the **primary** node's Geo dashboard for any errors.
-1. Test the data replication by pushing code to the **primary** node and see if it
- is received by **secondary** nodes.
-
-If you encounter any issues, see the [Geo troubleshooting guide](troubleshooting.md).
+<!-- This redirect file can be deleted after <2021-11-23>. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/administration/geo/replication/updating_the_geo_sites.md b/doc/administration/geo/replication/updating_the_geo_sites.md
new file mode 100644
index 00000000000..e82afe5f0d4
--- /dev/null
+++ b/doc/administration/geo/replication/updating_the_geo_sites.md
@@ -0,0 +1,54 @@
+---
+stage: Enablement
+group: Geo
+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
+type: howto
+---
+
+# Updating the Geo sites **(PREMIUM SELF)**
+
+WARNING:
+Read these sections carefully before updating your Geo sites. Not following
+version-specific update steps may result in unexpected downtime. If you have
+any specific questions, [contact Support](https://about.gitlab.com/support/#contact-support).
+
+Updating Geo sites involves performing:
+
+1. [Version-specific update steps](version_specific_updates.md), depending on the
+ version being updated to or from.
+1. [General update steps](#general-update-steps), for all updates.
+
+## General update steps
+
+NOTE:
+These general update steps are not intended for multi-site deployments,
+and will cause downtime. If you want to avoid downtime, consider using
+[zero downtime upgrades](../../../update/zero_downtime.md#multi-node--ha-deployment-with-geo).
+
+To update the Geo sites when a new GitLab version is released, update **primary**
+and all **secondary** sites:
+
+1. **Optional:** [Pause replication on each **secondary** sites.](../index.md#pausing-and-resuming-replication)
+1. SSH into each node of the **primary** site.
+1. [Upgrade GitLab on the **primary** site](../../../update/package/index.md#upgrade-using-the-official-repositories).
+1. SSH into each node of **secondary** sites.
+1. [Upgrade GitLab on each **secondary** site](../../../update/package/index.md#upgrade-using-the-official-repositories).
+1. If you paused replication in step 1, [resume replication on each **secondary**](../index.md#pausing-and-resuming-replication)
+1. [Test](#check-status-after-updating) **primary** and **secondary** sites, and check version in each.
+
+### Check status after updating
+
+Now that the update process is complete, you may want to check whether
+everything is working correctly:
+
+1. Run the Geo Rake task on an application node for the primary and secondary sites. Everything should be green:
+
+ ```shell
+ sudo gitlab-rake gitlab:geo:check
+ ```
+
+1. Check the **primary** site's Geo dashboard for any errors.
+1. Test the data replication by pushing code to the **primary** site and see if it
+ is received by **secondary** sites.
+
+If you encounter any issues, see the [Geo troubleshooting guide](troubleshooting.md).
diff --git a/doc/administration/geo/replication/usage.md b/doc/administration/geo/replication/usage.md
index 7fe8eec467e..f3c8f6ac759 100644
--- a/doc/administration/geo/replication/usage.md
+++ b/doc/administration/geo/replication/usage.md
@@ -11,7 +11,7 @@ type: howto
After you set up the [database replication and configure the Geo nodes](../index.md#setup-instructions), use your closest GitLab site as you would do with the primary one.
-You can push directly to a **secondary** site (for both HTTP, SSH including Git LFS), and the request will be proxied to the primary site instead ([introduced](https://about.gitlab.com/releases/2018/09/22/gitlab-11-3-released/) in [GitLab Premium](https://about.gitlab.com/pricing/#self-managed) 11.3).
+You can push directly to a **secondary** site (for both HTTP, SSH including Git LFS), and the request will be proxied to the primary site instead ([introduced](https://about.gitlab.com/releases/2018/09/22/gitlab-11-3-released/) in GitLab 11.3).
Example of the output you will see when pushing to a **secondary** site:
@@ -33,3 +33,13 @@ you can't store credentials in the URL like `user:password@URL`. Instead, you ca
for Unix-like operating systems or `_netrc` for Windows. In that case, the credentials
will be stored as a plain text. If you're looking for a more secure way to store credentials,
you can use [Git Credential Storage](https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage).
+
+## Fetch Go modules from Geo secondary sites
+
+Go modules can be pulled from secondary sites, with a number of limitations:
+
+- Git configuration (using `insteadOf`) is needed to fetch data from the Geo secondary site.
+- For private projects, authentication details need to be specified in `~/.netrc`.
+
+Read more in the
+[working with projects `go get` documentation](../../../user/project/working_with_projects.md#fetch-go-modules-from-geo-secondary-sites).
diff --git a/doc/administration/geo/replication/version_specific_updates.md b/doc/administration/geo/replication/version_specific_updates.md
index 155c06f90b8..84193e6baac 100644
--- a/doc/administration/geo/replication/version_specific_updates.md
+++ b/doc/administration/geo/replication/version_specific_updates.md
@@ -8,9 +8,44 @@ type: howto
# Version-specific update instructions **(PREMIUM SELF)**
Review this page for update instructions for your version. These steps
-accompany the [general steps](updating_the_geo_nodes.md#general-update-steps)
+accompany the [general steps](updating_the_geo_sites.md#general-update-steps)
for updating Geo nodes.
+## Updating to 14.1, 14.2, 14.3
+
+We found an [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/336013) where the Container Registry replication wasn't fully working if you used multi-arch images. In case of a multi-arch image, only the primary architecture (for example `amd64`) would be replicated to the secondary node. This has been [fixed in GitLab 14.3](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67624) and was backported to 14.2 and 14.1, but manual steps are required to force a re-sync.
+
+You can check if you are affected by running:
+
+```shell
+docker manifest inspect <SECONDARY_IMAGE_LOCATION> | jq '.mediaType'
+```
+
+Where `<SECONDARY_IMAGE_LOCATION>` is a container image on your secondary node.
+If the output matches `application/vnd.docker.distribution.manifest.list.v2+json`
+(there can be a `mediaType` entry at several levels, we only care about the top level entry),
+then you don't need to do anything.
+
+Otherwise, on all your **secondary** nodes, in a [Rails console](../../operations/rails_console.md), run the following:
+
+ ```ruby
+ list_type = 'application/vnd.docker.distribution.manifest.list.v2+json'
+
+ Geo::ContainerRepositoryRegistry.synced.each do |gcr|
+ cr = gcr.container_repository
+ primary = Geo::ContainerRepositorySync.new(cr)
+ cr.tags.each do |tag|
+ primary_manifest = JSON.parse(primary.send(:client).repository_raw_manifest(cr.path, tag.name))
+ next unless primary_manifest['mediaType'].eql?(list_type)
+
+ cr.delete_tag_by_name(tag.name)
+ end
+ primary.execute
+ end
+ ```
+
+If you are running a version prior to 14.1 and are using Geo and multi-arch containers in your Container Registry, we recommend [upgrading](updating_the_geo_sites.md) to at least GitLab 14.1.
+
## Updating to GitLab 14.0/14.1
We found an issue where [Primary sites can not be removed from the UI](https://gitlab.com/gitlab-org/gitlab/-/issues/338231).
@@ -277,7 +312,7 @@ GitLab 12.2 includes the following minor PostgreSQL updates:
This update occurs even if major PostgreSQL updates are disabled.
-Before [refreshing Foreign Data Wrapper during a Geo upgrade](https://docs.gitlab.com/omnibus/update/README.html#run-post-deployment-migrations-and-checks),
+Before [refreshing Foreign Data Wrapper during a Geo upgrade](../../../update/zero_downtime.md#step-4-run-post-deployment-migrations-and-checks),
restart the Geo tracking database:
```shell
diff --git a/doc/administration/geo/setup/database.md b/doc/administration/geo/setup/database.md
index fa343f7eb40..d72bb0737ae 100644
--- a/doc/administration/geo/setup/database.md
+++ b/doc/administration/geo/setup/database.md
@@ -501,6 +501,79 @@ two other clusters of nodes supporting a Geo **secondary** site. One for the
main database and the other for the tracking database. For more information,
see [High Availability with Omnibus GitLab](../../postgresql/replication_and_failover.md).
+### Changing the replication password
+
+To change the password for the [replication user](https://wiki.postgresql.org/wiki/Streaming_Replication)
+when using Omnibus-managed PostgreSQL instances:
+
+On the GitLab Geo **primary** server:
+
+1. The default value for the replication user is `gitlab_replicator`, but if you've set a custom replication
+ user in your `/etc/gitlab/gitlab.rb` under the `postgresql['sql_replication_user']` setting, make sure to
+ adapt the following instructions for your own user.
+
+ Generate an MD5 hash of the desired password:
+
+ ```shell
+ sudo gitlab-ctl pg-password-md5 gitlab_replicator
+ # Enter password: <your_password_here>
+ # Confirm password: <your_password_here>
+ # 950233c0dfc2f39c64cf30457c3b7f1e
+ ```
+
+ Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ # Fill with the hash generated by `gitlab-ctl pg-password-md5 gitlab_replicator`
+ postgresql['sql_replication_password'] = '<md5_hash_of_your_password>'
+ ```
+
+1. Save the file and reconfigure GitLab to change the replication user's password in PostgreSQL:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+1. Restart PostgreSQL for the replication password change to take effect:
+
+ ```shell
+ sudo gitlab-ctl restart postgresql
+ ```
+
+Until the password is updated on any **secondary** servers, the [PostgreSQL log](../../logs.md#postgresql-logs) on
+the secondaries will report the following error message:
+
+```console
+FATAL: could not connect to the primary server: FATAL: password authentication failed for user "gitlab_replicator"
+```
+
+On all GitLab Geo **secondary** servers:
+
+1. The first step isn't necessary from a configuration perspective, since the hashed `'sql_replication_password'`
+ is not used on the GitLab Geo **secondary**. However in the event that **secondary** needs to be promoted
+ to the GitLab Geo **primary**, make sure to match the `'sql_replication_password'` in the secondary
+ server configuration.
+
+ Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ # Fill with the hash generated by `gitlab-ctl pg-password-md5 gitlab_replicator` on the Geo primary
+ postgresql['sql_replication_password'] = '<md5_hash_of_your_password>'
+ ```
+
+1. During the initial replication setup, the `gitlab-ctl replicate-geo-database` command writes the plaintext
+ password for the replication user account to two locations:
+
+ - `gitlab-geo.conf`: Used by the PostgreSQL replication process, written to the PostgreSQL data
+ directory, by default at `/var/opt/gitlab/postgresql/data/gitlab-geo.conf`.
+ - `.pgpass`: Used by the `gitlab-psql` user, located by default at `/var/opt/gitlab/postgresql/.pgpass`.
+
+ Update the plaintext password in both of these files, and restart PostgreSQL:
+
+ ```shell
+ sudo gitlab-ctl restart postgresql
+ ```
+
## Multi-node database replication
In GitLab 14.0, Patroni replaced `repmgr` as the supported
@@ -521,7 +594,7 @@ For instructions about how to set up Patroni on the primary site, see the
#### Configuring Patroni cluster for a Geo secondary site
-In a Geo secondary site, the main PostgreSQL database is a read-only replica of the primary site’s PostgreSQL database.
+In a Geo secondary site, the main PostgreSQL database is a read-only replica of the primary site's PostgreSQL database.
If you are currently using `repmgr` on your Geo primary site, see [these instructions](#migrating-from-repmgr-to-patroni)
for migrating from `repmgr` to Patroni.
@@ -651,7 +724,7 @@ Refer to your preferred Load Balancer's documentation for further guidance.
##### Step 3. Configure a PgBouncer node on the secondary site
A production-ready and highly available configuration requires at least
-three Consul nodes, a minimum of one PgBouncer node, but it’s recommended to have
+three Consul nodes, a minimum of one PgBouncer node, but it's recommended to have
one per database node. An internal load balancer (TCP) is required when there is
more than one PgBouncer service nodes. The internal load balancer provides a single
endpoint for connecting to the PgBouncer cluster. For more information,
diff --git a/doc/administration/geo/setup/external_database.md b/doc/administration/geo/setup/external_database.md
index 56d196b54ec..13dbf9d1434 100644
--- a/doc/administration/geo/setup/external_database.md
+++ b/doc/administration/geo/setup/external_database.md
@@ -249,7 +249,7 @@ the tracking database on port 5432.
gitlab-rake geo:db:create
```
-1. The reconfigure should automatically migrate the database. You can migrate the database manually if needed, for example if `gitlab_rails['auto_migrate'] = false`:
+1. The reconfigure should automatically migrate the database. You can migrate the database manually if needed, for example if `geo_secondary['auto_migrate'] = false`:
```shell
gitlab-rake geo:db:migrate
diff --git a/doc/administration/get_started.md b/doc/administration/get_started.md
index 6fe66aa1642..c0d5a45d8d1 100644
--- a/doc/administration/get_started.md
+++ b/doc/administration/get_started.md
@@ -137,7 +137,7 @@ Keep your configuration files and backup archives in a separate location to ensu
You can restore a backup only to **the exact same version and type** (Community Edition/Enterprise Edition) of GitLab on which it was created.
- Review the [Omnibus backup and restore documentation](https://docs.gitlab.com/omnibus/settings/backups).
-- Review the [Helm Chart backup and restore documentation](https://docs.gitlab.com/charts/backup-restore).
+- Review the [Helm Chart backup and restore documentation](https://docs.gitlab.com/charts/backup-restore/).
### Back up GitLab SaaS
@@ -177,7 +177,7 @@ The EC2 instance meets the requirements for an application data backup by taking
In general, if you're running GitLab on a virtualized server, you can create VM snapshots of the entire GitLab server.
It is common for a VM snapshot to require you to power down the server.
-#### Option 2: GitLab Geo
+#### Option 2: GitLab Geo **(PREMIUM SELF)**
Geo provides local, read-only instances of your GitLab instances.
@@ -191,7 +191,7 @@ Learn more about [replication limitations](../administration/geo/replication/dat
GitLab provides support for self-managed GitLab through different channels.
-- Priority support: Premium and Ultimate self-managed customers receive priority support with tiered response times.
+- Priority support: [Premium and Ultimate](https://about.gitlab.com/pricing/) self-managed customers receive priority support with tiered response times.
Learn more about [upgrading to priority support](https://about.gitlab.com/support/#upgrading-to-priority-support).
- Live upgrade assistance: Get one-on-one expert guidance during a production upgrade. With your **priority support plan**,
you're eligible for a live, scheduled screen-sharing session with a member of our support team.
diff --git a/doc/administration/git_protocol.md b/doc/administration/git_protocol.md
index e3e2db81fb0..c8c532e9a01 100644
--- a/doc/administration/git_protocol.md
+++ b/doc/administration/git_protocol.md
@@ -99,7 +99,7 @@ $ GIT_TRACE_PACKET=1 git -c protocol.version=2 ls-remote https://your-gitlab-ins
Verify Git v2 is used by the client:
```shell
-GIT_SSH_COMMAND="ssh -v" git -c protocol.version=2 ls-remote ssh://git@your-gitlab-instance.com/group/repo.git 2>&1 |grep GIT_PROTOCOL
+GIT_SSH_COMMAND="ssh -v" git -c protocol.version=2 ls-remote ssh://git@your-gitlab-instance.com/group/repo.git 2>&1 | grep GIT_PROTOCOL
```
You should see that the `GIT_PROTOCOL` environment variable is sent:
diff --git a/doc/administration/gitaly/configure_gitaly.md b/doc/administration/gitaly/configure_gitaly.md
index 5e8cbac42c1..d0841f4e607 100644
--- a/doc/administration/gitaly/configure_gitaly.md
+++ b/doc/administration/gitaly/configure_gitaly.md
@@ -41,9 +41,8 @@ However, Gitaly can be deployed to its own server, which can benefit GitLab inst
multiple machines.
NOTE:
-When configured to run on their own servers, Gitaly servers
-[must be upgraded](https://docs.gitlab.com/omnibus/update/#upgrading-gitaly-servers) before Gitaly
-clients in your cluster.
+When configured to run on their own servers, Gitaly servers must be
+[upgraded](../../update/package/index.md) before Gitaly clients in your cluster.
The process for setting up Gitaly on its own server is:
@@ -340,6 +339,12 @@ disable enforcement. For more information, see the documentation on configuring
1. Run `sudo -u git /home/git/gitaly/gitaly-hooks check /home/git/gitaly/config.toml`
to confirm that Gitaly can perform callbacks to the GitLab internal API.
+WARNING:
+If directly copying repository data from a GitLab server to Gitaly, ensure that the metadata file,
+default path `/var/opt/gitlab/git-data/repositories/.gitaly-metadata`, is not included in the transfer.
+Copying this file causes GitLab to use the [Rugged patches](index.md#direct-access-to-git-in-gitlab) for repositories hosted on the Gitaly server,
+leading to `Error creating pipeline` and `Commit not found` errors, or stale data.
+
### Configure Gitaly clients
As the final step, you must update Gitaly clients to switch from using local Gitaly service to use
diff --git a/doc/administration/gitaly/index.md b/doc/administration/gitaly/index.md
index bca83e903ac..7a7aac884ed 100644
--- a/doc/administration/gitaly/index.md
+++ b/doc/administration/gitaly/index.md
@@ -87,11 +87,8 @@ Gitaly comes pre-configured with Omnibus GitLab, which is a configuration
- Omnibus GitLab installations for up to 2000 users, see [specific Gitaly configuration instructions](../reference_architectures/2k_users.md#configure-gitaly).
- Source installations or custom Gitaly installations, see [Configure Gitaly](configure_gitaly.md).
-GitLab installations for more than 2000 users should use Gitaly Cluster.
-
-NOTE:
-If not set in GitLab, feature flags are read as false from the console and Gitaly uses their
-default value. The default value depends on the GitLab version.
+GitLab installations for more than 2000 active users performing daily Git write operation may be
+best suited by using Gitaly Cluster.
## Gitaly Cluster
@@ -137,7 +134,7 @@ In this example:
- The [replication factor](#replication-factor) is `3`. There are three copies maintained
of each repository.
-The availability objectives for Gitaly clusters are:
+The availability objectives for Gitaly clusters assuming a single node failure are:
- **Recovery Point Objective (RPO):** Less than 1 minute.
@@ -155,6 +152,58 @@ The availability objectives for Gitaly clusters are:
Faster outage detection, to improve this speed to less than 1 second,
is tracked [in this issue](https://gitlab.com/gitlab-org/gitaly/-/issues/2608).
+WARNING:
+If complete cluster failure occurs, disaster recovery plans should be executed. These can affect the
+RPO and RTO discussed above.
+
+### Architecture and configuration recommendations
+
+The following table provides recommendations based on your
+requirements. Users means concurrent users actively performing
+simultaneous Git Operations.
+
+Gitaly services are present in every GitLab installation and always coordinates Git repository storage and
+retrieval. Gitaly can be as simple as a single background service when operating on a single instance Omnibus
+GitLab (All of GitLab on one machine). Gitaly can be separated into it's own instance and it can be configured in
+a full cluster configuration depending on scaling and availability requirements.
+
+The GitLab Reference Architectures provide guidance for what Gitaly configuration is advisable at each of the scales.
+The Gitaly configuration is noted by the architecture diagrams and the table of required resources.
+
+| User Scaling | Reference Architecture To Use | GitLab Instance Configuration | Gitaly Configuration | Git Repository Storage | Instances Dedicated to Gitaly Services |
+| ------------------------------------------------------------ | ------------------------------------------------------------ | -------------------------------------------- | ------------------------------- | ---------------------------------- | -------------------------------------- |
+| Up to 1000 Users | [1K](../reference_architectures/1k_users.md) | Single Instance for all of GitLab | Already Integrated as a Service | Local Disk | 0 |
+| Up to 2999 Users | [2K](../reference_architectures/2k_users.md) | Horizontally Scaled GitLab Instance (Non-HA) | Single Gitaly Server | Local Disk of Gitaly Instance | 1 |
+| 3000 Users and Over | [3K](../reference_architectures/1k_users.md) | Horizontally Scaled GitLab Instance with HA | Gitaly Cluster | Local Disk of Each Gitaly Instance | 8 |
+| RTO/RPO Requirements for AZ Failure Tolerance Regardless of User Scale | [3K (with downscaling)](../reference_architectures/3k_users.md) | Custom (1) | Gitaly Cluster | Local Disk of Each Gitaly Instance | 8 |
+
+1. If you feel that you need AZ Failure Tolerance for user scaling lower than 3K, please contact Customer Success
+ to discuss your RTO and RPO needs and what options exist to meet those objectives.
+
+WARNING:
+At present, some [known database inconsistency issues](#known-issues-impacting-gitaly-cluster)
+exist in Gitaly Cluster. It is our recommendation that for now, you remain on your current service.
+We will adjust the date for NFS support removal if this applies to you.
+
+### Known issues impacting Gitaly Cluster
+
+The following table outlines current known issues impacting the use of Gitaly Cluster. For
+the most up to date status of these issues, please refer to the referenced issues / epics.
+
+| Issue | Summary |
+| Gitaly Cluster + Geo can cause database inconsistencies | There are some conditions during Geo replication that can cause database inconsistencies with Gitaly Cluster. These have been identified and are being resolved by updating Gitaly Cluster to [identify repositories with a unique and persistent identifier](https://gitlab.com/gitlab-org/gitaly/-/issues/3485). |
+| Database inconsistencies due to repository access outside of Gitaly Cluster's control | Operations that write to the repository storage which do not go through normal Gitaly Cluster methods can cause database inconsistencies. These can include (but are not limited to) snapshot restoration for cluster node disks, node upgrades which modify files under Git control, or any other disk operation that may touch repository storage external to GitLab. The Gitaly team is actively working to provide manual commands to [reconcile the Praefect database with the repository storage](https://gitlab.com/groups/gitlab-org/-/epics/6723). |
+
+### Snapshot backup and recovery limitations
+
+Gitaly Cluster does not support snapshot backups because these can cause issues where the
+Praefect database becomes out of sync with the disk storage. Because of how Praefect rebuilds
+the replication metadata of Gitaly disk information during a restore, we recommend using the
+[official backup and restore Rake tasks](../../raketasks/backup_restore.md).
+
+To track progress on work on a solution for manually re-synchronizing the Praefect database
+with disk storage, see [this epic](https://gitlab.com/groups/gitlab-org/-/epics/6575).
+
### Virtual storage
Virtual storage makes it viable to have a single repository storage in GitLab to simplify repository
@@ -306,7 +355,10 @@ For configuration information, see [Configure replication factor](praefect.md#co
For more information on configuring Gitaly Cluster, see [Configure Gitaly Cluster](praefect.md).
-### Migrate to Gitaly Cluster
+## Migrate to Gitaly Cluster
+
+We recommend you migrate to Gitaly Cluster if your
+[requirements recommend](#architecture-and-configuration-recommendations) Gitaly Cluster.
Whether migrating to Gitaly Cluster because of [NFS support deprecation](index.md#nfs-deprecation-notice)
or to move from single Gitaly nodes, the basic process involves:
@@ -318,6 +370,11 @@ or to move from single Gitaly nodes, the basic process involves:
Gitaly Cluster, existing repositories stored outside Gitaly Cluster must be moved. There is no
automatic migration but the moves can be scheduled with the GitLab API.
+WARNING:
+At present, some [known database inconsistency issues](#known-issues-impacting-gitaly-cluster)
+exist in Gitaly Cluster. It is our recommendation that for now, you remain on your current service.
+We will adjust the date for NFS support removal if this applies to you.
+
## Monitor Gitaly and Gitaly Cluster
You can use the available logs and [Prometheus metrics](../monitoring/prometheus/index.md) to
@@ -449,6 +506,8 @@ To monitor [strong consistency](#strong-consistency), you can use the following
- `gitaly_hook_transaction_voting_delay_seconds`, the client-side delay introduced by waiting for
the transaction to be committed.
+You can also monitor the [Praefect logs](../logs.md#praefect-logs).
+
## Do not bypass Gitaly
GitLab doesn't advise directly accessing Gitaly repositories stored on disk with a Git client,
@@ -539,12 +598,6 @@ To see if GitLab can access the repository file system directly, we use the foll
Direct Git access is enable by default in Omnibus GitLab because it fills in the correct repository
paths in the GitLab configuration file `config/gitlab.yml`. This satisfies the UUID check.
-WARNING:
-If directly copying repository data from a GitLab server to Gitaly, ensure that the metadata file,
-default path `/var/opt/gitlab/git-data/repositories/.gitaly-metadata`, is not included in the transfer.
-Copying this file causes GitLab to use the Rugged patches for repositories hosted on the Gitaly server,
-leading to `Error creating pipeline` and `Commit not found` errors, or stale data.
-
### Transition to Gitaly Cluster
For the sake of removing complexity, we must remove direct Git access in GitLab. However, we can't
diff --git a/doc/administration/gitaly/praefect.md b/doc/administration/gitaly/praefect.md
index 4af7f1a58a5..eb666f1caf4 100644
--- a/doc/administration/gitaly/praefect.md
+++ b/doc/administration/gitaly/praefect.md
@@ -20,10 +20,6 @@ Configure Gitaly Cluster using either:
Smaller GitLab installations may need only [Gitaly itself](index.md).
-NOTE:
-Upgrade instructions for Omnibus GitLab installations
-[are available](https://docs.gitlab.com/omnibus/update/#gitaly-cluster).
-
## Requirements
The minimum recommended configuration for a Gitaly Cluster requires:
@@ -279,7 +275,7 @@ you need to prepare PostgreSQL server with [setup instruction](#manual-database-
```ruby
pgbouncer['databases'] = {
- # Other database configuation including gitlabhq_production
+ # Other database configuration including gitlabhq_production
...
praefect_production: {
@@ -353,6 +349,7 @@ If there are multiple Praefect nodes:
To complete this section you need a [configured PostgreSQL server](#postgresql), including:
+WARNING:
Praefect should be run on a dedicated node. Do not run Praefect on the
application server, or a Gitaly node.
@@ -994,7 +991,7 @@ Particular attention should be shown to:
1. Check that the Praefect storage is configured to store new repositories:
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
+ 1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Repository**.
1. Expand the **Repository storage** section.
@@ -1574,3 +1571,28 @@ sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.t
- Replace the placeholder `<virtual-storage>` with the virtual storage containing the Gitaly node storage to be checked.
- Replace the placeholder `<up-to-date-storage>` with the Gitaly storage name containing up to date repositories.
- Replace the placeholder `<outdated-storage>` with the Gitaly storage name containing outdated repositories.
+
+### Manually remove repositories
+
+> [Introduced](https://gitlab.com/gitlab-org/gitaly/-/merge_requests/3767) in GitLab 14.3.
+
+The `remove-repository` Praefect sub-command removes repositories from a Gitaly Cluster. It removes
+all state associated with a given repository including:
+
+- On-disk repositories on all relevant Gitaly nodes.
+- Any database state tracked by Praefect.
+
+```shell
+sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml remove-repository -virtual-storage <virtual-storage> -repository <repository>
+```
+
+- `-virtual-storage` is the virtual storage the repository is located in.
+- `-repository` is the repository's relative path in the storage.
+
+Sometimes parts of the repository continue to exist after running `remove-repository`. This can be caused
+because of:
+
+- A deletion error.
+- An in-flight RPC call targeting the repository.
+
+If this occurs, run `remove-repository` again.
diff --git a/doc/administration/gitaly/troubleshooting.md b/doc/administration/gitaly/troubleshooting.md
index 3dd700968f9..1b53a0994f5 100644
--- a/doc/administration/gitaly/troubleshooting.md
+++ b/doc/administration/gitaly/troubleshooting.md
@@ -23,7 +23,7 @@ See also [Gitaly timeout](../../user/admin_area/settings/gitaly_timeouts.md) set
When using standalone Gitaly servers, you must make sure they are the same version
as GitLab to ensure full compatibility:
-1. On the top bar, select **Menu >** **{admin}** **Admin** on your GitLab instance.
+1. On the top bar, select **Menu > Admin** on your GitLab instance.
1. On the left sidebar, select **Overview > Gitaly Servers**.
1. Confirm all Gitaly servers indicate that they are up to date.
@@ -226,8 +226,8 @@ update the secrets file on the Gitaly server to match the Gitaly client, then
### Repository pushes fail with a `deny updating a hidden ref` error
Due to [a change](https://gitlab.com/gitlab-org/gitaly/-/merge_requests/3426)
-introduced in GitLab 13.12, Gitaly has read-only, internal GitLab references that users are not
-permitted to update. If you attempt to update internal references with `git push --mirror`, Git
+introduced in GitLab 13.12, Gitaly has read-only, internal GitLab references that users are not
+permitted to update. If you attempt to update internal references with `git push --mirror`, Git
returns the rejection error, `deny updating a hidden ref`.
The following references are read-only:
@@ -243,7 +243,7 @@ To mirror-push branches and tags only, and avoid attempting to mirror-push prote
git push origin +refs/heads/*:refs/heads/* +refs/tags/*:refs/tags/*
```
-Any other namespaces that the admin wants to push can be included there as well via additional patterns.
+Any other namespaces that the admin wants to push can be included there as well via additional patterns.
### Command line tools cannot connect to Gitaly
diff --git a/doc/administration/housekeeping.md b/doc/administration/housekeeping.md
index 8f5bf2ee013..4de48aa3f14 100644
--- a/doc/administration/housekeeping.md
+++ b/doc/administration/housekeeping.md
@@ -27,7 +27,7 @@ GitLab automatically runs `git gc` and `git repack` on repositories after Git pu
You can change how often this happens or turn it off:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Repository**.
1. Expand **Repository maintenance**.
1. In the **Housekeeping** section, configure the [housekeeping options](#housekeeping-options).
@@ -62,6 +62,12 @@ Housekeeping also [removes unreferenced LFS files](../raketasks/cleanup.md#remov
from your project on the same schedule as the `git gc` operation, freeing up storage space for your
project.
+WARNING:
+Running `git gc` or `git repack` commands manually in the
+[repository folder](repository_storage_types.md#from-project-name-to-hashed-path)
+is discouraged. If the created pack files get incorrect access rights (that is, owned by the wrong user)
+browsing to the project page might result in `404` and `503` errors.
+
## How housekeeping handles pool repositories
Housekeeping for pool repositories is handled differently from standard repositories. It is
@@ -76,7 +82,7 @@ This is the current call stack by which it is invoked:
1. `ObjectPoolService#fetch`
1. `Gitaly::FetchIntoObjectPoolRequest`
-To manually invoke it from a Rails console if needed, you can call
+To manually invoke it from a [Rails console](operations/rails_console.md) if needed, you can call
`project.pool_repository.object_pool.fetch`. This is a potentially long-running task, though Gitaly
times out in about 8 hours.
diff --git a/doc/administration/incoming_email.md b/doc/administration/incoming_email.md
index c5cabc5794a..5b72583bc95 100644
--- a/doc/administration/incoming_email.md
+++ b/doc/administration/incoming_email.md
@@ -76,7 +76,7 @@ and use [an application password](https://support.google.com/mail/answer/185833)
If you want to use Office 365, and two-factor authentication is enabled, make sure
you're using an
-[app password](https://docs.microsoft.com/en-us/azure/active-directory/user-help/multi-factor-authentication-end-user-app-passwords)
+[app password](https://support.microsoft.com/en-us/account-billing/manage-app-passwords-for-two-step-verification-d6dc8c6d-4bf7-4851-ad95-6d07799387e9)
instead of the regular password for the mailbox.
To set up a basic Postfix mail server with IMAP access on Ubuntu, follow the
@@ -464,7 +464,7 @@ Example configurations for Microsoft Office 365 with IMAP enabled.
NOTE:
As of September 2020 sub-addressing support
-[has been added to Office 365](https://office365.uservoice.com/forums/273493-office-365-admin/suggestions/18612754-support-for-dynamic-email-aliases-in-office-36). This feature is not
+[has been added to Office 365](https://support.microsoft.com/en-us/office/uservoice-pages-430e1a78-e016-472a-a10f-dc2a3df3450a). This feature is not
enabled by default, and must be enabled through PowerShell.
This series of PowerShell commands enables [sub-addressing](#email-sub-addressing)
@@ -638,7 +638,7 @@ incoming_email:
#### Microsoft Graph
-> Introduced in [GitLab 13.11](https://gitlab.com/gitlab-org/gitlab/-/issues/214900).
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214900) in GitLab 13.11.
GitLab can read incoming email using the Microsoft Graph API instead of
IMAP. Because [Microsoft is deprecating IMAP usage with Basic Authentication](https://techcommunity.microsoft.com/t5/exchange-team-blog/announcing-oauth-2-0-support-for-imap-and-smtp-auth-protocols-in/ba-p/1330432), the Microsoft Graph API will soon be required for new Microsoft Exchange Online
diff --git a/doc/administration/index.md b/doc/administration/index.md
index 46624ab39a3..9412994edb7 100644
--- a/doc/administration/index.md
+++ b/doc/administration/index.md
@@ -111,7 +111,7 @@ Learn how to install, configure, update, and maintain your GitLab instance.
### GitLab platform integrations
-- [Mattermost](https://docs.gitlab.com/omnibus/gitlab-mattermost/): Integrate with [Mattermost](https://mattermost.com), an open source, private cloud workplace for web messaging.
+- [Mattermost](../integration/mattermost/index.md): Integrate with [Mattermost](https://mattermost.com), an open source, private cloud workplace for web messaging.
- [PlantUML](integration/plantuml.md): Create diagrams in AsciiDoc and Markdown documents
created in snippets, wikis, and repositories.
- [Web terminals](integration/terminal.md): Provide terminal access to your applications deployed to Kubernetes from GitLab CI/CD [environments](../ci/environments/index.md#web-terminals).
@@ -164,16 +164,16 @@ Learn how to install, configure, update, and maintain your GitLab instance.
- [Limit repository size](../user/admin_area/settings/account_and_limit_settings.md): Set a hard limit for your repositories' size.
- [Static objects external storage](static_objects_external_storage.md): Set external storage for static objects in a repository.
-## Continuous Integration settings
+## CI/CD settings
-- [Enable/disable GitLab CI/CD](../ci/enable_or_disable_ci.md#make-gitlab-cicd-disabled-by-default-in-new-projects): Enable or disable GitLab CI/CD for your instance.
+- [Enable or disable GitLab CI/CD](cicd.md#disable-gitlab-cicd-in-new-projects): Set new projects in your instance to have GitLab CI/CD enabled or disabled by default.
- [GitLab CI/CD administration settings](../user/admin_area/settings/continuous_integration.md): Enable or disable Auto DevOps site-wide and define the artifacts' max size and expiration time.
- [External Pipeline Validation](external_pipeline_validation.md): Enable, disable, and configure external pipeline validation.
- [Job artifacts](job_artifacts.md): Enable, disable, and configure job artifacts (a set of files and directories which are outputted by a job when it completes successfully).
- [Job logs](job_logs.md): Information about the job logs.
- [Register runners](../ci/runners/runners_scope.md): Learn how to register and configure runners.
- [Shared runners pipelines quota](../user/admin_area/settings/continuous_integration.md#shared-runners-pipeline-minutes-quota): Limit the usage of pipeline minutes for shared runners.
-- [Enable/disable Auto DevOps](../topics/autodevops/index.md#enable-or-disable-auto-devops): Enable or disable Auto DevOps for your instance.
+- [Enable or disable Auto DevOps](../topics/autodevops/index.md#enable-or-disable-auto-devops): Enable or disable Auto DevOps for your instance.
## Snippet settings
diff --git a/doc/administration/instance_limits.md b/doc/administration/instance_limits.md
index 1ea2ec4c904..24ffee088f3 100644
--- a/doc/administration/instance_limits.md
+++ b/doc/administration/instance_limits.md
@@ -78,6 +78,16 @@ This setting limits the request rate on the Packages API per user or IP. For mor
- **Default rate limit**: Disabled by default.
+### Git LFS
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68642) in GitLab 14.3.
+
+This setting limits the request rate on the [Git LFS](../topics/git/lfs/index.md)
+requests per user. For more information, read
+[GitLab Git Large File Storage (LFS) Administration](../administration/lfs/index.md).
+
+- **Default rate limit**: Disabled by default.
+
### Import/Export
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35728) in GitLab 13.2.
@@ -387,6 +397,31 @@ To set this limit for a self-managed installation, run the following in the
Plan.default.actual_limits.update!(ci_pipeline_schedules: 100)
```
+### Limit the number of pipelines created by a pipeline schedule per day
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/323066) in GitLab 14.0.
+
+You can limit the number of pipelines that pipeline schedules can trigger per day.
+
+Schedules that try to run pipelines more frequently than the limit are slowed to a maximum frequency.
+The frequency is calculated by dividing 1440 (the number minutes in a day) by the
+limit value. For example, for a maximum frequency of:
+
+- Once per minute, the limit must be `1440`.
+- Once per 10 minutes, the limit must be `144`.
+- Once per 60 minutes, the limit must be `24`
+
+There is no limit for self-managed instances by default.
+
+To set this limit to `1440` on a self-managed installation, run the following in the
+[GitLab Rails console](operations/rails_console.md#starting-a-rails-console-session):
+
+```ruby
+Plan.default.actual_limits.update!(ci_daily_pipeline_schedule_triggers: 1440)
+```
+
+This limit is [enabled on GitLab.com](../user/gitlab_com/index.md#gitlab-cicd).
+
### Number of instance level variables
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216097) in GitLab 13.1.
@@ -513,19 +548,61 @@ Update `ci_jobs_trace_size_limit` with the new value in megabytes:
Plan.default.actual_limits.update!(ci_jobs_trace_size_limit: 125)
```
+### Maximum number of active DAST profile schedules per project
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68551) in GitLab 14.3.
+
+Limit the number of active DAST profile schedules per project. A DAST profile schedule can be active or inactive.
+
+You can change the limit in the [GitLab Rails console](operations/rails_console.md#starting-a-rails-console-session).
+Update `dast_profile_schedules` with the new value:
+
+```ruby
+Plan.default.actual_limits.update!(dast_profile_schedules: 50)
+```
+
+### Maximum size and depth of CI/CD configuration YAML files
+
+The default maximum size of a CI/CD configuration YAML file is 1 megabyte and the default depth is 100.
+
+You can change these limits in the [GitLab Rails console](operations/rails_console.md#starting-a-rails-console-session).
+Update `max_yaml_size_bytes` with the new value in megabytes:
+
+```ruby
+ApplicationSetting.update!(max_yaml_size_bytes: 2.megabytes)
+```
+
+Update `max_yaml_depth` with the new value in megabytes:
+
+```ruby
+ApplicationSetting.update!(max_yaml_depth: 125)
+```
+
+To disable this limitation entirely, disable the feature flag in the console:
+
+```ruby
+Feature.disable(:ci_yaml_limit_size)
+```
+
## Instance monitoring and metrics
-### Incident Management inbound alert limits
+### Limit inbound incident management alerts
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17859) in GitLab 12.5.
-Limiting inbound alerts for an incident reduces the number of alerts (issues)
-that can be created within a period of time, which can help prevent overloading
-your incident responders with duplicate issues. You can reduce the volume of
-alerts in the following ways:
+You can limit the number of inbound alerts for [incidents](../operations/incident_management/incidents.md)
+that can be created in a period of time. The inbound [incident management](../operations/incident_management/index.md)
+alert limit can help prevent overloading your incident responders by reducing the
+number of alerts or duplicate issues.
+
+To set inbound incident management alert limits:
-- Max requests per period per project, 3600 seconds by default.
-- Rate limit period in seconds, 3600 seconds by default.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Network**.
+1. Expand General **Incident Management Limits**.
+1. Select the **Enable Incident Management inbound alert limit** checkbox.
+1. Optional. Input a custom value for **Maximum requests per project per rate limit period**. Default is 3600.
+1. Optional. Input a custom value for **Rate limit period**. Default is 3600 seconds.
### Prometheus Alert JSON payloads
@@ -577,9 +654,9 @@ panel_groups:
See [Environment Dashboard](../ci/environments/environments_dashboard.md#adding-a-project-to-the-dashboard) for the maximum number of displayed projects.
-## Environment data on Deploy Boards
+## Environment data on deploy boards
-[Deploy Boards](../user/project/deploy_boards.md) load information from Kubernetes about
+[Deploy boards](../user/project/deploy_boards.md) load information from Kubernetes about
Pods and Deployments. However, data over 10 MB for a certain environment read from
Kubernetes won't be shown.
@@ -645,7 +722,7 @@ indexed, which have a separate limit. For more information, read
- For self-managed installations, the field length is unlimited by default.
You can configure this limit for self-managed installations when you
-[enable Elasticsearch](../integration/elasticsearch.md#enabling-advanced-search).
+[enable Elasticsearch](../integration/elasticsearch.md#enable-advanced-search).
Set the limit to `0` to disable it.
## Wiki limits
@@ -733,7 +810,7 @@ Set the limit to `0` to allow any file size.
When asking for versions of a given NuGet package name, the GitLab Package Registry returns a maximum of 300 versions.
-## Branch retargeting on merge **(FREE SELF)**
+## Branch retargeting on merge
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/320902) in GitLab 13.9.
diff --git a/doc/administration/instance_review.md b/doc/administration/instance_review.md
index f2ba3a5a562..b166bb32aa1 100644
--- a/doc/administration/instance_review.md
+++ b/doc/administration/instance_review.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Instance Review **(FREE SELF)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/6995) in [GitLab Free](https://about.gitlab.com/pricing/) 11.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/6995) in GitLab 11.3.
If you run a medium-sized self-managed instance (50+ users) of a free version of GitLab,
[either Community Edition or unlicensed Enterprise Edition](https://about.gitlab.com/install/ce-or-ee/),
diff --git a/doc/administration/integration/kroki.md b/doc/administration/integration/kroki.md
index 729894052b2..008d33c6c94 100644
--- a/doc/administration/integration/kroki.md
+++ b/doc/administration/integration/kroki.md
@@ -56,7 +56,7 @@ read the [Kroki installation](https://docs.kroki.io/kroki/setup/install/#_images
You need to enable Kroki integration from Settings under Admin Area.
To do that, log in with an administrator account and follow these steps:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. Go to **Settings > General**.
1. Expand the **Kroki** section.
1. Select **Enable Kroki** checkbox.
diff --git a/doc/administration/integration/mailgun.md b/doc/administration/integration/mailgun.md
new file mode 100644
index 00000000000..5a56aed4427
--- /dev/null
+++ b/doc/administration/integration/mailgun.md
@@ -0,0 +1,41 @@
+---
+stage: Growth
+group: Expansion
+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
+type: reference, howto
+---
+
+# Mailgun and GitLab **(FREE SELF)**
+
+When you use Mailgun to send emails for your GitLab instance and [Mailgun](https://www.mailgun.com/)
+integration is enabled and configured in GitLab, you can receive their webhook for
+permanent invite email failures. To set up the integration, you must:
+
+1. [Configure your Mailgun domain](#configure-your-mailgun-domain).
+1. [Enable Mailgun integration](#enable-mailgun-integration).
+
+After completing the integration, Mailgun `permanent_failure` webhooks are sent to your GitLab instance.
+
+## Configure your Mailgun domain
+
+Before you can enable Mailgun in GitLab, set up your own Mailgun permanent failure endpoint to receive the webhooks.
+
+Using the [Mailgun webhook guide](https://www.mailgun.com/blog/a-guide-to-using-mailguns-webhooks/):
+
+1. Add a webhook with the **Event type** set to **Permanent Failure**.
+1. Fill in the URL of your instance and include the `/-/members/mailgun/permanent_failures` path.
+ - Example: `https://myinstance.gitlab.com/-/members/mailgun/permanent_failures`
+
+## Enable Mailgun integration
+
+After configuring your Mailgun domain for the permanent failures endpoint,
+you're ready to enable the Mailgun integration:
+
+1. Sign in to GitLab as an [Administrator](../../user/permissions.md) user.
+1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the left sidebar, go to **Settings > General** and expand the **Mailgun** section.
+1. Select the **Enable Mailgun** check box.
+1. Enter the Mailgun HTTP webhook signing key as described in
+ [the Mailgun documentation](https://documentation.mailgun.com/en/latest/user_manual.html#webhooks) and
+ shown in the [API security](https://app.mailgun.com/app/account/security/api_keys) section for your Mailgun account.
+1. Select **Save changes**.
diff --git a/doc/administration/integration/plantuml.md b/doc/administration/integration/plantuml.md
index 9f83ba8e972..94fef89d966 100644
--- a/doc/administration/integration/plantuml.md
+++ b/doc/administration/integration/plantuml.md
@@ -206,8 +206,8 @@ stop;
After configuring your local PlantUML server, you're ready to enable the PlantUML integration:
1. Sign in to GitLab as an [Administrator](../../user/permissions.md) user.
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, go to **Settings > General** and expand the **PlantUML** section.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, go to **Settings > General** and expand the **PlantUML** section.
1. Select the **Enable PlantUML** checkbox.
1. Set the PlantUML instance as `https://gitlab.example.com/-/plantuml/`,
and click **Save changes**.
diff --git a/doc/administration/integration/terminal.md b/doc/administration/integration/terminal.md
index 1be234c2771..882580b35b6 100644
--- a/doc/administration/integration/terminal.md
+++ b/doc/administration/integration/terminal.md
@@ -100,7 +100,7 @@ they receive a `Connection failed` message.
By default, terminal sessions do not expire. To limit the terminal session
lifetime in your GitLab instance:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. Select
[**Settings > Web terminal**](../../user/admin_area/settings/index.md#general).
1. Set a `max session time`.
diff --git a/doc/administration/job_artifacts.md b/doc/administration/job_artifacts.md
index 3b1d253b4b6..b4c16e007cc 100644
--- a/doc/administration/job_artifacts.md
+++ b/doc/administration/job_artifacts.md
@@ -435,6 +435,27 @@ Ci::JobArtifact.where(project: project).order(size: :desc).limit(50).map { |a| p
You can change the number of job artifacts listed by modifying `.limit(50)` to
the number you want.
+#### List artifacts in a single project
+
+List the artifacts for a single project, sorted by artifact size. The output includes the:
+
+- ID of the job that created the artifact
+- artifact size
+- artifact file type
+- artifact creation date
+- on-disk location of the artifact
+
+```ruby
+p = Project.find_by_id(:project ID)
+arts = Ci::JobArtifact.where(project: p)
+
+list = arts.order('sort DESC').limit(50).each do |art|
+ puts "Job ID: #{art.job_id} - Size: #{art.size}b - Type: #{art.file_type} - Created: #{art.created_at} - File loc: #{art.file}"
+end
+```
+
+To change the number of projects listed, change the number in `limit(50)`.
+
#### Delete job artifacts from jobs completed before a specific date
WARNING:
diff --git a/doc/administration/job_logs.md b/doc/administration/job_logs.md
index a4fdf734c2e..64d9248cb16 100644
--- a/doc/administration/job_logs.md
+++ b/doc/administration/job_logs.md
@@ -138,7 +138,7 @@ For more information, see [delete references to missing artifacts](raketasks/che
> - Enabled on GitLab.com.
> - [Recommended for production use](https://gitlab.com/groups/gitlab-org/-/epics/4275) in GitLab 13.6.
> - [Recommended for production use with AWS S3](https://gitlab.com/gitlab-org/gitlab/-/issues/273498) in GitLab 13.7.
-> - To use in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-incremental-logging). **(FREE SELF)**
+> - To use in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-incremental-logging).
By default job logs are sent from the GitLab Runner in chunks and cached temporarily on disk
in `/var/opt/gitlab/gitlab-ci/builds` by Omnibus GitLab. After the job completes,
@@ -183,7 +183,7 @@ Here is the detailed data flow:
to disk, and there is no protection against misconfiguration.
- There is [an epic tracking other potential limitations and improvements](https://gitlab.com/groups/gitlab-org/-/epics/3791).
-### Enable or disable incremental logging **(FREE SELF)**
+### Enable or disable incremental logging
Incremental logging is under development, but [ready for production use as of GitLab 13.6](https://gitlab.com/groups/gitlab-org/-/epics/4275). It is
deployed behind a feature flag that is **disabled by default**.
diff --git a/doc/administration/logs.md b/doc/administration/logs.md
index 883f1db8e09..990287e3907 100644
--- a/doc/administration/logs.md
+++ b/doc/administration/logs.md
@@ -50,6 +50,7 @@ except those captured by `runit`.
| [Mailroom](#mail_room_jsonlog-default) | **{check-circle}** Yes | **{check-circle}** Yes |
| [NGINX](#nginx-logs) | **{check-circle}** Yes | **{check-circle}** Yes |
| [PostgreSQL Logs](#postgresql-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
+| [Praefect Logs](#praefect-logs) | **{dotted-circle}** Yes| **{check-circle}** Yes |
| [Prometheus Logs](#prometheus-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
| [Puma](#puma-logs) | **{check-circle}** Yes | **{check-circle}** Yes |
| [Redis Logs](#redis-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
@@ -63,9 +64,6 @@ Depending on your installation method, this file is located at:
- Omnibus GitLab: `/var/log/gitlab/gitlab-rails/production_json.log`
- Installations from source: `/home/git/gitlab/log/production_json.log`
-When GitLab is running in an environment other than production,
-the corresponding log file is shown here.
-
It contains a structured log for Rails controller requests received from
GitLab, thanks to [Lograge](https://github.com/roidrage/lograge/).
Requests from the API are logged to a separate file in `api_json.log`.
@@ -216,9 +214,6 @@ Depending on your installation method, this file is located at:
- Omnibus GitLab: `/var/log/gitlab/gitlab-rails/production.log`
- Installations from source: `/home/git/gitlab/log/production.log`
-When GitLab is running in an environment other than production,
-the corresponding log file is shown here.
-
It contains information about all performed requests. You can see the
URL and type of request, IP address, and what parts of code were
involved to service this particular request. Also, you can see all SQL
@@ -556,10 +551,9 @@ access to Git repositories.
### For GitLab versions 12.10 and up
-For GitLab version 12.10 and later, there are two `gitlab-shell.log` files.
Information containing `git-{upload-pack,receive-pack}` requests is at
`/var/log/gitlab/gitlab-shell/gitlab-shell.log`. Information about hooks to
-GitLab Shell from Gitaly is at `/var/log/gitlab/gitaly/gitlab-shell.log`.
+GitLab Shell from Gitaly is at `/var/log/gitlab/gitaly/current`.
Example log entries for `/var/log/gitlab/gitlab-shell/gitlab-shell.log`:
@@ -585,7 +579,7 @@ Example log entries for `/var/log/gitlab/gitlab-shell/gitlab-shell.log`:
}
```
-Example log entries for `/var/log/gitlab/gitaly/gitlab-shell.log`:
+Example log entries for `/var/log/gitlab/gitaly/current`:
```json
{
@@ -668,6 +662,12 @@ This file is at `/var/log/gitlab/gitaly/gitaly_ruby_json.log` and is
produced by [`gitaly-ruby`](gitaly/reference.md#gitaly-ruby). It contains an
access log of gRPC calls made by Gitaly to `gitaly-ruby`.
+### `gitaly_hooks.log`
+
+This file is at `/var/log/gitlab/gitaly/gitaly_hooks.log` and is
+produced by `gitaly-hooks` command. It also contains records about
+failures received during processing of the responses from GitLab API.
+
## Puma Logs
### `puma_stdout.log`
@@ -1063,6 +1063,12 @@ For Omnibus GitLab installations, GitLab Exporter logs are in `/var/log/gitlab/g
For Omnibus GitLab installations, GitLab Kubernetes Agent Server logs are
in `/var/log/gitlab/gitlab-kas/`.
+## Praefect Logs
+
+For Omnibus GitLab installations, Praefect logs are in `/var/log/gitlab/praefect/`.
+
+GitLab also tracks [Prometheus metrics for Praefect](gitaly/#monitor-gitaly-cluster).
+
## Performance bar stats
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/48149) in GitLab 13.7.
diff --git a/doc/administration/maintenance_mode/index.md b/doc/administration/maintenance_mode/index.md
index 7664c7c1751..39ee357cc2f 100644
--- a/doc/administration/maintenance_mode/index.md
+++ b/doc/administration/maintenance_mode/index.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# GitLab Maintenance Mode **(PREMIUM SELF)**
-> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2149) in GitLab Premium 13.9.
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2149) in GitLab 13.9.
Maintenance Mode allows administrators to reduce write operations to a minimum while maintenance tasks are performed. The main goal is to block all external actions that change the internal state, including the PostgreSQL database, but especially files, Git repositories, Container repositories, and so on.
@@ -21,7 +21,7 @@ Maintenance Mode allows most external actions that do not change internal state.
There are three ways to enable Maintenance Mode as an administrator:
- **Web UI**:
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
+ 1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > General**.
1. Expand **Maintenance Mode**, and toggle **Enable Maintenance Mode**.
You can optionally add a message for the banner as well.
@@ -45,7 +45,7 @@ There are three ways to enable Maintenance Mode as an administrator:
There are three ways to disable Maintenance Mode:
- **Web UI**:
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
+ 1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > General**.
1. Expand **Maintenance Mode**, and toggle **Enable Maintenance Mode**.
You can optionally add a message for the banner as well.
@@ -171,7 +171,7 @@ it is recommended that you disable all cron jobs except for those related to Geo
To monitor queues and disable jobs:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
### Incident management
diff --git a/doc/administration/merge_request_diffs.md b/doc/administration/merge_request_diffs.md
index 1133bff204c..d6b9fa2b8d3 100644
--- a/doc/administration/merge_request_diffs.md
+++ b/doc/administration/merge_request_diffs.md
@@ -265,3 +265,9 @@ by assigning different processes to different parts of the table. The `BATCH`
and `UPDATE_DELAY` parameters allow the speed of the migration to be traded off
against concurrent access to the table. The `ANSI` parameter should be set to
false if your terminal does not support ANSI escape codes.
+
+By default, `sudo` does not preserve existing environment variables. You should append them, rather than prefix them.
+
+```shell
+sudo gitlab-rake gitlab:external_diffs:force_object_storage START_ID=59946109 END_ID=59946109 UPDATE_DELAY=5
+```
diff --git a/doc/administration/monitoring/gitlab_self_monitoring_project/index.md b/doc/administration/monitoring/gitlab_self_monitoring_project/index.md
index f8764468256..90d0b65dbe5 100644
--- a/doc/administration/monitoring/gitlab_self_monitoring_project/index.md
+++ b/doc/administration/monitoring/gitlab_self_monitoring_project/index.md
@@ -14,7 +14,7 @@ GitLab provides administrators insights into the health of their GitLab instance
To provide a native experience (similar interacting with an application deployed using GitLab), a
project called **Monitoring** is created:
-- With [internal visibility](../../../public_access/public_access.md#internal-projects).
+- With [internal visibility](../../../public_access/public_access.md#internal-projects-and-groups).
- Under a group called **GitLab Instance**.
The project is created specifically for visualizing and configuring the monitoring of your GitLab
@@ -34,7 +34,7 @@ This project can be used to:
## Create the self monitoring project
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Metrics and profiling** and expand **Self monitoring**.
1. Toggle **Self monitoring** on.
1. After your GitLab instance creates the project, GitLab displays a link to the
@@ -47,7 +47,7 @@ WARNING:
Deleting the self monitoring project removes any changes made to the project. If
you create the project again, it's created in its default state.
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, go to **Settings > Metrics and profiling** and expand **Self monitoring**.
1. Toggle **Self monitoring** off.
1. In the confirmation dialog that opens, click **Delete self monitoring project**.
diff --git a/doc/administration/monitoring/performance/gitlab_configuration.md b/doc/administration/monitoring/performance/gitlab_configuration.md
index e8abe2708c7..f316a75a868 100644
--- a/doc/administration/monitoring/performance/gitlab_configuration.md
+++ b/doc/administration/monitoring/performance/gitlab_configuration.md
@@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
GitLab Performance Monitoring is disabled by default. To enable it and change any of its
settings:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Metrics and profiling**
(`/admin/application_settings/metrics_and_profiling`).
1. Add the necessary configuration changes.
diff --git a/doc/administration/monitoring/performance/grafana_configuration.md b/doc/administration/monitoring/performance/grafana_configuration.md
index 0f40fd3c0e7..c37a264938e 100644
--- a/doc/administration/monitoring/performance/grafana_configuration.md
+++ b/doc/administration/monitoring/performance/grafana_configuration.md
@@ -62,7 +62,7 @@ repository.
After setting up Grafana, you can enable a link to access it easily from the
GitLab sidebar:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Metrics and profiling**
and expand **Metrics - Grafana**.
1. Select the **Add a link to Grafana** checkbox.
@@ -79,7 +79,7 @@ GitLab displays your link in the **Menu > Admin > Monitoring > Metrics Dashboard
> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/5822) in GitLab 13.10.
When setting up Grafana through the process above, no scope shows in the screen at
-**Menu >** **{admin}** **Admin > Applications > GitLab Grafana**. However, the `read_user` scope is
+**Menu > Admin > Applications > GitLab Grafana**. However, the `read_user` scope is
required and is provided to the application automatically. Setting any scope other than
`read_user` without also including `read_user` leads to this error when you try to log in using
GitLab as the OAuth provider:
diff --git a/doc/administration/monitoring/performance/performance_bar.md b/doc/administration/monitoring/performance/performance_bar.md
index 6d9418133d8..ef4db93d5fc 100644
--- a/doc/administration/monitoring/performance/performance_bar.md
+++ b/doc/administration/monitoring/performance/performance_bar.md
@@ -72,7 +72,7 @@ From left to right, the performance bar displays:
NOTE:
Not all indicators are available in all environments. For instance, the memory view
-requires running Ruby with [specific patches](https://gitlab.com/gitlab-org/gitlab-build-images/-/blob/master/patches/ruby/2.7.2/thread-memory-allocations-2.7.patch)
+requires running Ruby with [specific patches](https://gitlab.com/gitlab-org/gitlab-build-images/-/blob/master/patches/ruby/2.7.4/thread-memory-allocations-2.7.patch)
applied. When running GitLab locally using [GDK](../../../development/contributing/index.md#gitlab-development-kit),
this is typically not the case and the memory view cannot be used.
@@ -104,7 +104,7 @@ The performance bar is disabled by default for non-administrators. To enable it
for a given group:
1. Sign in as a user with Administrator [role](../../../user/permissions.md).
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Metrics and profiling**
(`admin/application_settings/metrics_and_profiling`), and expand
**Profiling - Performance bar**.
diff --git a/doc/administration/monitoring/prometheus/gitlab_exporter.md b/doc/administration/monitoring/prometheus/gitlab_exporter.md
index 4ba4cad9143..d9852524aec 100644
--- a/doc/administration/monitoring/prometheus/gitlab_exporter.md
+++ b/doc/administration/monitoring/prometheus/gitlab_exporter.md
@@ -6,8 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# GitLab exporter **(FREE SELF)**
->- Available since [Omnibus GitLab 8.17](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/1132).
->- Renamed from `GitLab monitor exporter` to `GitLab exporter` in [GitLab 12.3](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16511).
+> Renamed from `GitLab monitor exporter` to `GitLab exporter` in [GitLab 12.3](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16511).
The [GitLab exporter](https://gitlab.com/gitlab-org/gitlab-exporter) enables you to
measure various GitLab metrics pulled from Redis and the database in Omnibus GitLab
@@ -33,8 +32,8 @@ the GitLab exporter exposed at `localhost:9168`.
## Use a different Rack server
->- Introduced in [Omnibus GitLab 13.8](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/4896).
->- WEBrick is now the default Rack server instead of Puma.
+> - Introduced in [Omnibus GitLab 13.8](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/4896).
+> - WEBrick is now the default Rack server instead of Puma.
By default, the GitLab exporter runs on [WEBrick](https://github.com/ruby/webrick), a single-threaded Ruby web server.
You can choose a different Rack server that better matches your performance needs.
diff --git a/doc/administration/monitoring/prometheus/gitlab_metrics.md b/doc/administration/monitoring/prometheus/gitlab_metrics.md
index 459eb259498..c36d2b0f7a4 100644
--- a/doc/administration/monitoring/prometheus/gitlab_metrics.md
+++ b/doc/administration/monitoring/prometheus/gitlab_metrics.md
@@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
To enable the GitLab Prometheus metrics:
1. Log in to GitLab as a user with Administrator [role](../../../user/permissions.md).
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Metrics and profiling**.
1. Find the **Metrics - Prometheus** section, and select **Add link to Prometheus**.
1. [Restart GitLab](../../restart_gitlab.md#omnibus-gitlab-restart) for the changes to take effect.
@@ -252,12 +252,26 @@ configuration option in `gitlab.yml`. These metrics are served from the
| `geo_group_wiki_repositories_synced` | Gauge | 13.10 | Number of syncable group wikis synced on secondary | `url` |
| `geo_group_wiki_repositories_failed` | Gauge | 13.10 | Number of syncable group wikis failed on secondary | `url` |
| `geo_group_wiki_repositories_registry` | Gauge | 13.10 | Number of syncable group wikis in the registry | `url` |
+| `geo_pages_deployments` | Gauge | 14.3 | Number of pages deployments on primary | `url` |
+| `geo_pages_deployments_checksum_total` | Gauge | 14.3 | Number of pages deployments tried to checksum on primary | `url` |
+| `geo_pages_deployments_checksummed` | Gauge | 14.3 | Number of pages deployments successfully checksummed on primary | `url` |
+| `geo_pages_deployments_checksum_failed` | Gauge | 14.3 | Number of pages deployments failed to calculate the checksum on primary | `url` |
+| `geo_pages_deployments_synced` | Gauge | 14.3 | Number of syncable pages deployments synced on secondary | `url` |
+| `geo_pages_deployments_failed` | Gauge | 14.3 | Number of syncable pages deployments failed to sync on secondary | `url` |
+| `geo_pages_deployments_registry` | Gauge | 14.3 | Number of pages deployments in the registry | `url` |
+| `geo_pages_deployments_verification_total` | Gauge | 14.3 | Number of pages deployments verifications tried on secondary | `url` |
+| `geo_pages_deployments_verified` | Gauge | 14.3 | Number of pages deployments verified on secondary | `url` |
+| `geo_pages_deployments_verification_failed` | Gauge | 14.3 | Number of pages deployments verifications failed on secondary | `url` |
| `limited_capacity_worker_running_jobs` | Gauge | 13.5 | Number of running jobs | `worker` |
| `limited_capacity_worker_max_running_jobs` | Gauge | 13.5 | Maximum number of running jobs | `worker` |
| `limited_capacity_worker_remaining_work_count` | Gauge | 13.5 | Number of jobs waiting to be enqueued | `worker` |
| `destroyed_job_artifacts_count_total` | Counter | 13.6 | Number of destroyed expired job artifacts | |
| `destroyed_pipeline_artifacts_count_total` | Counter | 13.8 | Number of destroyed expired pipeline artifacts | |
| `gitlab_optimistic_locking_retries` | Histogram | 13.10 | Number of retry attempts to execute optimistic retry lock | |
+| `geo_uploads` | Gauge | 14.1 | Number of uploads on primary | `url` |
+| `geo_uploads_synced` | Gauge | 14.1 | Number of uploads synced on secondary | `url` |
+| `geo_uploads_failed` | Gauge | 14.1 | Number of syncable uploads failed to sync on secondary | `url` |
+| `geo_uploads_registry` | Gauge | 14.1 | Number of uploads in the registry | `url` |
## Database load balancing metrics **(PREMIUM SELF)**
diff --git a/doc/administration/monitoring/prometheus/index.md b/doc/administration/monitoring/prometheus/index.md
index dd81f71d418..e04aad9c6b8 100644
--- a/doc/administration/monitoring/prometheus/index.md
+++ b/doc/administration/monitoring/prometheus/index.md
@@ -55,8 +55,7 @@ To disable Prometheus and all of its exporters, as well as any added in the futu
### Changing the port and address Prometheus listens on
WARNING:
-The following change was added in [Omnibus GitLab 8.17](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/1261). Although possible,
-it's not recommended to change the port Prometheus listens
+Although possible, it's not recommended to change the port Prometheus listens
on, as this might affect or conflict with other services running on the GitLab
server. Proceed at your own risk.
@@ -330,8 +329,6 @@ To add a Prometheus dashboard for a single server GitLab setup:
## GitLab metrics
-> Introduced in GitLab 9.3.
-
GitLab monitors its own internal service metrics, and makes them available at the `/-/metrics` endpoint. Unlike other exporters, this endpoint requires authentication as it's available on the same URL and port as user traffic.
Read more about the [GitLab Metrics](gitlab_metrics.md).
@@ -380,9 +377,6 @@ The GitLab exporter allows you to measure various GitLab metrics, pulled from Re
## Configuring Prometheus to monitor Kubernetes
-> - Introduced in GitLab 9.0.
-> - Pod monitoring introduced in GitLab 9.4.
-
If your GitLab server is running within Kubernetes, Prometheus collects metrics from the Nodes and [annotated Pods](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config) in the cluster, including performance data on each container. This is particularly helpful if your CI/CD environments run in the same cluster, as you can use the [Prometheus project integration](../../../user/project/integrations/prometheus.md) to monitor them.
To disable the monitoring of Kubernetes:
diff --git a/doc/administration/object_storage.md b/doc/administration/object_storage.md
index b8a6f2acc56..6c77576cb27 100644
--- a/doc/administration/object_storage.md
+++ b/doc/administration/object_storage.md
@@ -14,7 +14,7 @@ typically much more performant, reliable, and scalable.
## Options
-GitLab has been tested on a number of object storage providers:
+GitLab has been tested by vendors and customers on a number of object storage providers:
- [Amazon S3](https://aws.amazon.com/s3/)
- [Google Cloud Storage](https://cloud.google.com/storage)
@@ -22,7 +22,7 @@ GitLab has been tested on a number of object storage providers:
- [Oracle Cloud Infrastructure](https://docs.cloud.oracle.com/en-us/iaas/Content/Object/Tasks/s3compatibleapi.htm)
- [OpenStack Swift](https://docs.openstack.org/swift/latest/s3_compat.html)
- [Azure Blob storage](https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blobs-introduction)
-- On-premises hardware and appliances from various storage vendors.
+- On-premises hardware and appliances from various storage vendors, whose list is not officially established.
- MinIO. We have [a guide to deploying this](https://docs.gitlab.com/charts/advanced/external-object-storage/minio.html) within our Helm Chart documentation.
### Known compatibility issues
@@ -33,6 +33,10 @@ GitLab has been tested on a number of object storage providers:
- Ceph S3 prior to [Kraken 11.0.2](https://ceph.com/releases/kraken-11-0-2-released/) does not support the [Upload Copy Part API](https://gitlab.com/gitlab-org/gitlab/-/issues/300604). You may need to [disable multi-threaded copying](#multi-threaded-copying).
+- Amazon S3 [Object Lock](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock.html)
+ is not supported. Follow [issue #335775](https://gitlab.com/gitlab-org/gitlab/-/issues/335775)
+ for progress on enabling this option.
+
## Configuration guides
There are two ways of specifying object storage configuration in GitLab:
@@ -70,6 +74,7 @@ because it does not require a shared folder.
Consolidated object storage configuration can't be used for backups or
Mattermost. See the [full table for a complete list](#storage-specific-configuration).
+However, backups can be configured with [server side encryption](../raketasks/backup_restore.md#s3-encrypted-buckets) separately.
Enabling consolidated object storage enables object storage for all object
types. If you want to use local storage for specific object types, you can
@@ -683,8 +688,8 @@ configuration.
#### Encrypted S3 buckets
-> - Introduced in [GitLab 13.1](https://gitlab.com/gitlab-org/gitlab-workhorse/-/merge_requests/466) for instance profiles only and [S3 default encryption](https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html).
-> - Introduced in [GitLab 13.2](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34460) for static credentials when [consolidated object storage configuration](#consolidated-object-storage-configuration) and [S3 default encryption](https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html) are used.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-workhorse/-/merge_requests/466) in GitLab 13.1 for instance profiles only and [S3 default encryption](https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html).
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34460) in GitLab 13.2 for static credentials when [consolidated object storage configuration](#consolidated-object-storage-configuration) and [S3 default encryption](https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html) are used.
When configured either with an instance profile or with the consolidated
object configuration, GitLab Workhorse properly uploads files to S3
@@ -695,7 +700,7 @@ supported since this requires sending the encryption keys in every request](http
##### Server-side encryption headers
-> Introduced in [GitLab 13.3](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38240).
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38240) in GitLab 13.3.
Setting a default encryption on an S3 bucket is the easiest way to
enable encryption, but you may want to [set a bucket policy to ensure
diff --git a/doc/administration/operations/cleaning_up_redis_sessions.md b/doc/administration/operations/cleaning_up_redis_sessions.md
index 194dd8f39e2..ed5014b65e1 100644
--- a/doc/administration/operations/cleaning_up_redis_sessions.md
+++ b/doc/administration/operations/cleaning_up_redis_sessions.md
@@ -1,64 +1,9 @@
---
-stage: Enablement
-group: Distribution
-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: 'index.md'
+remove_date: '2021-12-10'
---
-# Cleaning up stale Redis sessions
+This document was moved to [another location](index.md).
-Since version 6.2, GitLab stores web user sessions as key-value pairs in Redis.
-Prior to GitLab 7.3, user sessions did not automatically expire from Redis. If
-you have been running a large GitLab server (thousands of users) since before
-GitLab 7.3 we recommend cleaning up stale sessions to compact the Redis
-database after you upgrade to GitLab 7.3. You can also perform a cleanup while
-still running GitLab 7.2 or older, but in that case new stale sessions will
-start building up again after you clean up.
-
-In GitLab versions prior to 7.3.0, the session keys in Redis are 16-byte
-hexadecimal values such as '976aa289e2189b17d7ef525a6702ace9'. Starting with
-GitLab 7.3.0, the keys are
-prefixed with `session:gitlab:`, so they would look like
-`session:gitlab:976aa289e2189b17d7ef525a6702ace9`. Below we describe how to
-remove the keys in the old format.
-
-NOTE:
-The instructions below must be modified in accordance with your
-configuration settings if you have used the advanced Redis
-settings outlined in
-[Configuration Files Documentation](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/README.md).
-
-First we define a shell function with the proper Redis connection details.
-
-```shell
-rcli() {
- # This example works for Omnibus installations of GitLab 7.3 or newer. For an
- # installation from source you will have to change the socket path and the
- # path to redis-cli.
- sudo /opt/gitlab/embedded/bin/redis-cli -s /var/opt/gitlab/redis/redis.socket "$@"
-}
-
-# test the new shell function; the response should be PONG
-rcli ping
-```
-
-Now we do a search to see if there are any session keys in the old format for
-us to clean up.
-
-```shell
-# returns the number of old-format session keys in Redis
-rcli keys '*' | grep '^[a-f0-9]\{32\}$' | wc -l
-```
-
-If the number is larger than zero, you can proceed to expire the keys from
-Redis. If the number is zero there is nothing to clean up.
-
-```shell
-# Tell Redis to expire each matched key after 600 seconds.
-rcli keys '*' | grep '^[a-f0-9]\{32\}$' | awk '{ print "expire", $0, 600 }' | rcli
-# This will print '(integer) 1' for each key that gets expired.
-```
-
-Over the next 15 minutes (10 minutes expiry time plus 5 minutes Redis
-background save interval) your Redis database will be compacted. If you are
-still using GitLab 7.2, users who are not clicking around in GitLab during the
-10 minute expiry window will be signed out of GitLab.
+<!-- This redirect file can be deleted after 2021-12-10. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/administration/operations/extra_sidekiq_processes.md b/doc/administration/operations/extra_sidekiq_processes.md
index 2cc4e3a4551..31cbd6c457b 100644
--- a/doc/administration/operations/extra_sidekiq_processes.md
+++ b/doc/administration/operations/extra_sidekiq_processes.md
@@ -90,7 +90,7 @@ To start multiple processes:
To view the Sidekiq processes in GitLab:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
## Negate settings
diff --git a/doc/administration/operations/extra_sidekiq_routing.md b/doc/administration/operations/extra_sidekiq_routing.md
index 6938f8a7012..bb8eb184302 100644
--- a/doc/administration/operations/extra_sidekiq_routing.md
+++ b/doc/administration/operations/extra_sidekiq_routing.md
@@ -40,6 +40,8 @@ In `/etc/gitlab/gitlab.rb`:
```ruby
sidekiq['routing_rules'] = [
+ # Do not re-route workers that require their own queue
+ ['tags=needs_own_queue', nil],
# Route all non-CPU-bound workers that are high urgency to `high-urgency` queue
['resource_boundary!=cpu&urgency=high', 'high-urgency'],
# Route all database, gitaly and global search workers that are throttled to `throttled` queue
@@ -164,3 +166,32 @@ with the migration to avoid losing jobs entirely, especially in a system with
long queues of jobs. The migration can be done by following the migration steps
mentioned in [Sidekiq job
migration](../../raketasks/sidekiq_job_migration.md)
+
+### Workers that cannot be migrated
+
+Some workers cannot share a queue with other workers - typically because
+they check the size of their own queue - and so must be excluded from
+this process. We recommend excluding these from any further worker
+routing by adding a rule to keep them in their own queue, for example:
+
+```ruby
+sidekiq['routing_rules'] = [
+ ['tags=needs_own_queue', nil],
+ # ...
+]
+```
+
+These queues will also need to be included in at least one [Sidekiq
+queue group](extra_sidekiq_processes.md#start-multiple-processes).
+
+The following table shows the workers that should have their own queue:
+
+| Worker name | Queue name | GitLab issue |
+| --- | --- | --- |
+| `EmailReceiverWorker` | `email_receiver` | [`gitlab-com/gl-infra/scalability#1263`](https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1263) |
+| `ServiceDeskEmailReceiverWorker` | `service_desk_email_receiver` | [`gitlab-com/gl-infra/scalability#1263`](https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1263) |
+| `ProjectImportScheduleWorker` | `project_import_schedule` | [`gitlab-org/gitlab#340630`](https://gitlab.com/gitlab-org/gitlab/-/issues/340630) |
+| `HashedStorage::MigratorWorker` | `hashed_storage:hashed_storage_migrator` | [`gitlab-org/gitlab#340629`](https://gitlab.com/gitlab-org/gitlab/-/issues/340629) |
+| `HashedStorage::ProjectMigrateWorker` | `hashed_storage:hashed_storage_project_migrate` | [`gitlab-org/gitlab#340629`](https://gitlab.com/gitlab-org/gitlab/-/issues/340629) |
+| `HashedStorage::ProjectRollbackWorker` | `hashed_storage:hashed_storage_project_rollback` | [`gitlab-org/gitlab#340629`](https://gitlab.com/gitlab-org/gitlab/-/issues/340629) |
+| `HashedStorage::RollbackerWorker` | `hashed_storage:hashed_storage_rollbacker` | [`gitlab-org/gitlab#340629`](https://gitlab.com/gitlab-org/gitlab/-/issues/340629) |
diff --git a/doc/administration/operations/fast_ssh_key_lookup.md b/doc/administration/operations/fast_ssh_key_lookup.md
index 5c1271486c0..e30ad4d8248 100644
--- a/doc/administration/operations/fast_ssh_key_lookup.md
+++ b/doc/administration/operations/fast_ssh_key_lookup.md
@@ -106,7 +106,7 @@ users as long as a large file exists.
To disable any more writes to the `authorized_keys` file:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Network**.
1. Expand **Performance optimization**.
1. Clear the **Write to "authorized_keys" file** checkbox.
diff --git a/doc/administration/operations/index.md b/doc/administration/operations/index.md
index 4b16c3b3a7e..7ccfa2739bb 100644
--- a/doc/administration/operations/index.md
+++ b/doc/administration/operations/index.md
@@ -8,11 +8,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
Keep your GitLab instance up and running smoothly.
-- [Clean up Redis sessions](cleaning_up_redis_sessions.md): Prior to GitLab 7.3,
- user sessions did not automatically expire from Redis. If
- you have been running a large GitLab server (thousands of users) since before
- GitLab 7.3 we recommend cleaning up stale sessions to compact the Redis
- database after you upgrade to GitLab 7.3.
- [Rake tasks](../../raketasks/index.md): Tasks for common administration and operational processes such as
[cleaning up unneeded items from GitLab instance](../../raketasks/cleanup.md), integrity checks,
and more.
diff --git a/doc/administration/operations/moving_repositories.md b/doc/administration/operations/moving_repositories.md
index 765cf64e735..61a9ec8e7d4 100644
--- a/doc/administration/operations/moving_repositories.md
+++ b/doc/administration/operations/moving_repositories.md
@@ -39,6 +39,11 @@ WARNING:
To move repositories into a [Gitaly Cluster](../gitaly/index.md#gitaly-cluster) in GitLab versions
13.12 to 14.1, you must [enable the `gitaly_replicate_repository_direct_fetch` feature flag](../feature_flags.md).
+WARNING:
+Repositories can be **permanently deleted** by a call to `/projects/:project_id/repository_storage_moves`
+that attempts to move a project already stored in a Gitaly Cluster back into that cluster.
+See [this issue for more details](https://gitlab.com/gitlab-org/gitaly/-/issues/3752).
+
Each repository is made read-only for the duration of the move. The repository is not writable
until the move has completed.
diff --git a/doc/administration/operations/puma.md b/doc/administration/operations/puma.md
index e8477eaf686..775761d655d 100644
--- a/doc/administration/operations/puma.md
+++ b/doc/administration/operations/puma.md
@@ -36,6 +36,14 @@ For more details about the Puma configuration, see the
## Puma Worker Killer
+Puma forks worker processes as part of a strategy to reduce memory use.
+
+Each time a worker is created, it shares memory with the primary process and
+only uses additional memory when it makes changes or additions to its memory pages.
+
+Memory use by workers therefore increases over time, and Puma Worker Killer is the
+mechanism that recovers this memory.
+
By default:
- The [Puma Worker Killer](https://github.com/schneems/puma_worker_killer) restarts a worker if it
@@ -56,6 +64,47 @@ To change the memory limit setting:
sudo gitlab-ctl reconfigure
```
+There are costs associated with killing and replacing workers including
+reduced capacity to run GitLab, and CPU that is consumed
+restarting the workers. `per_worker_max_memory_mb` should be set to a
+higher value if the worker killer is replacing workers too often.
+
+Worker count is calculated based on CPU cores, so a small GitLab deployment
+with 4-8 workers may experience performance issues if workers are being restarted
+frequently, once or more per minute. This is too often.
+
+A higher value of `1200` or more would be beneficial if the server has free memory.
+
+The worker killer checks every 20 seconds, and can be monitored using
+[the Puma log](../logs.md#puma_stdoutlog) `/var/log/gitlab/puma/puma_stdout.log`.
+For example, for GitLab 13.5:
+
+```plaintext
+PumaWorkerKiller: Out of memory. 4 workers consuming total: 4871.23828125 MB
+out of max: 4798.08 MB. Sending TERM to pid 26668 consuming 1001.00390625 MB.
+```
+
+From this output:
+
+- The formula that calculates the maximum memory value results in workers
+ being killed before they reach the `per_worker_max_memory_mb` value.
+- The default values for the formula before GitLab 13.5 were 550MB for the primary
+ and `per_worker_max_memory_mb` specified 850MB for each worker.
+- As of GitLab 13.5 the values are primary: 800MB, worker: 1024MB.
+- The threshold for workers to be killed is set at 98% of the limit:
+
+ ```plaintext
+ 0.98 * ( 800 + ( worker_processes * 1024MB ) )
+ ```
+
+- In the log output above, `0.98 * ( 800 + ( 4 * 1024 ) )` returns the
+ `max: 4798.08 MB` value.
+
+Increasing the maximum to `1200`, for example, would set a `max: 5488 MB` value.
+
+Workers use additional memory on top of the shared memory, how much
+depends on a site's use of GitLab.
+
## Worker timeout
A [timeout of 60 seconds](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/initializers/rack_timeout.rb)
@@ -95,7 +144,6 @@ considered as a fair tradeoff in a memory-constraint environment.
When running Puma in Single mode, some features are not supported:
-- Phased restart do not work: [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/300665)
- [Phased restart](https://gitlab.com/gitlab-org/gitlab/-/issues/300665)
- [Puma Worker Killer](https://gitlab.com/gitlab-org/gitlab/-/issues/300664)
diff --git a/doc/administration/operations/sidekiq_memory_killer.md b/doc/administration/operations/sidekiq_memory_killer.md
index 598baa4fcc7..e48ac6e65eb 100644
--- a/doc/administration/operations/sidekiq_memory_killer.md
+++ b/doc/administration/operations/sidekiq_memory_killer.md
@@ -4,7 +4,7 @@ group: Memory
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
---
-# Sidekiq MemoryKiller
+# Sidekiq MemoryKiller **(FREE SELF)**
The GitLab Rails application code suffers from memory leaks. For web requests
this problem is made manageable using
diff --git a/doc/administration/operations/ssh_certificates.md b/doc/administration/operations/ssh_certificates.md
index 374eebeb773..814e742b026 100644
--- a/doc/administration/operations/ssh_certificates.md
+++ b/doc/administration/operations/ssh_certificates.md
@@ -6,8 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# User lookup via OpenSSH's AuthorizedPrincipalsCommand **(FREE SELF)**
-> [Available in](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/19911) GitLab
-> Community Edition 11.2.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/19911) in GitLab 11.2.
The default SSH authentication for GitLab requires users to upload their SSH
public keys before they can use the SSH transport.
diff --git a/doc/administration/operations/unicorn.md b/doc/administration/operations/unicorn.md
deleted file mode 100644
index 6cee19186f9..00000000000
--- a/doc/administration/operations/unicorn.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: 'puma.md'
-remove_date: '2021-08-26'
----
-
-This file was moved to [another location](puma.md).
-
-<!-- This redirect file can be deleted after <2021-08-26>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/administration/package_information/defaults.md b/doc/administration/package_information/defaults.md
new file mode 100644
index 00000000000..45bea065995
--- /dev/null
+++ b/doc/administration/package_information/defaults.md
@@ -0,0 +1,72 @@
+---
+stage: Enablement
+group: Distribution
+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/#designated-technical-writers
+---
+
+# Package defaults
+
+Unless configuration is specified in the `/etc/gitlab/gitlab.rb` file,
+the package will assume the defaults as noted below.
+
+## Ports
+
+See the table below for the list of ports that the Omnibus GitLab assigns
+by default:
+
+| Component | On by default | Communicates via | Alternative | Connection port |
+| :----------------------------------------------------: | :------------: | :--------------: | :---------: | :------------------------------------: |
+| <a name="gitlab-rails"></a> GitLab Rails | Yes | Port | X | 80 or 443 |
+| <a name="gitlab-shell"></a> GitLab Shell | Yes | Port | X | 22 |
+| <a name="postgresql"></a> PostgreSQL | Yes | Socket | Port (5432) | X |
+| <a name="redis"></a> Redis | Yes | Socket | Port (6379) | X |
+| <a name="puma"></a> Puma | Yes | Socket | Port (8080) | X |
+| <a name="gitlab-workhorse"></a> GitLab Workhorse | Yes | Socket | Port (8181) | X |
+| <a name="nginx-status"></a> NGINX status | Yes | Port | X | 8060 |
+| <a name="prometheus"></a> Prometheus | Yes | Port | X | 9090 |
+| <a name="node-exporter"></a> Node exporter | Yes | Port | X | 9100 |
+| <a name="redis-exporter"></a> Redis exporter | Yes | Port | X | 9121 |
+| <a name="postgres-exporter"></a> PostgreSQL exporter | Yes | Port | X | 9187 |
+| <a name="pgbouncer-exporter"></a> PgBouncer exporter | No | Port | X | 9188 |
+| <a name="gitlab-exporter"></a> GitLab Exporter | Yes | Port | X | 9168 |
+| <a name="sidekiq-exporter"></a> Sidekiq exporter | Yes | Port | X | 8082 |
+| <a name="puma-exporter"></a> Puma exporter | No | Port | X | 8083 |
+| <a name="geo-postgresql"></a> Geo PostgreSQL | No | Socket | Port (5431) | X |
+| <a name="redis-sentinel"></a> Redis Sentinel | No | Port | X | 26379 |
+| <a name="incoming-email"></a> Incoming email | No | Port | X | 143 |
+| <a name="elasticsearch"></a> Elastic search | No | Port | X | 9200 |
+| <a name="gitlab-pages"></a> GitLab Pages | No | Port | X | 80 or 443 |
+| <a name="gitlab-registry-web"></a> GitLab Registry | No* | Port | X | 80, 443 or 5050 |
+| <a name="gitlab-registry"></a> GitLab Registry | No | Port | X | 5000 |
+| <a name="ldap"></a> LDAP | No | Port | X | Depends on the component configuration |
+| <a name="kerberos"></a> Kerberos | No | Port | X | 8443 or 8088 |
+| <a name="omniauth"></a> OmniAuth | Yes | Port | X | Depends on the component configuration |
+| <a name="smtp"></a> SMTP | No | Port | X | 465 |
+| <a name="remote-syslog"></a> Remote syslog | No | Port | X | 514 |
+| <a name="mattermost"></a> Mattermost | No | Port | X | 8065 |
+| <a name="mattermost-web"></a> Mattermost | No | Port | X | 80 or 443 |
+| <a name="pgbouncer"></a> PgBouncer | No | Port | X | 6432 |
+| <a name="consul"></a> Consul | No | Port | X | 8300, 8301(UDP), 8500, 8600[^Consul-notes] |
+| <a name="patroni"></a> Patroni | No | Port | X | 8008 |
+| <a name="gitlab-kas"></a> GitLab KAS | No | Port | X | 8150 |
+| <a name="gitaly"></a> Gitaly | No | Port | X | 8075 |
+
+Legend:
+
+- `Component` - Name of the component.
+- `On by default` - Is the component running by default.
+- `Communicates via` - How the component talks with the other components.
+- `Alternative` - If it is possible to configure the component to use different type of communication. The type is listed with default port used in that case.
+- `Connection port` - Port on which the component communicates.
+
+GitLab also expects a filesystem to be ready for the storage of Git repositories
+and various other files.
+
+Note that if you are using NFS (Network File System), files will be carried
+over a network which will require, based on implementation, ports `111` and
+`2049` to be open.
+
+NOTE:
+In some cases, the GitLab Registry will be automatically enabled by default. Please see [our documentation](../packages/container_registry.md) for more details
+
+ [^Consul-notes]: If using additional Consul functionality, more ports may need to be opened. See the [official documentation](https://www.consul.io/docs/install/ports#ports-table) for the list.
diff --git a/doc/administration/package_information/deprecated_os.md b/doc/administration/package_information/deprecated_os.md
new file mode 100644
index 00000000000..251dbe1e20e
--- /dev/null
+++ b/doc/administration/package_information/deprecated_os.md
@@ -0,0 +1,82 @@
+---
+stage: Enablement
+group: Distribution
+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/#designated-technical-writers
+---
+
+# OS Versions that are no longer supported
+
+GitLab provides omnibus packages for operating systems only until their
+EOL (End-Of-Life). After the EOL date of the OS, GitLab will stop releasing
+official packages. The list of deprecated operating systems and the final GitLab
+release for them can be found below:
+
+| OS Version | End Of Life | Last supported GitLab version |
+| --------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Raspbian Wheezy | [May 2015](https://downloads.raspberrypi.org/raspbian/images/raspbian-2015-05-07/) | [GitLab CE](https://packages.gitlab.com/app/gitlab/raspberry-pi2/search?q=gitlab-ce_8.17&dist=debian%2Fwheezy) 8.17 |
+| OpenSUSE 13.2 | [January 2017](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-9.1&dist=opensuse%2F13.2) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-9.1&dist=opensuse%2F13.2) 9.1 |
+| Ubuntu 12.04 | [April 2017](https://ubuntu.com/info/release-end-of-life) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce_9.1&dist=ubuntu%2Fprecise) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee_9.1&dist=ubuntu%2Fprecise) 9.1 |
+| OpenSUSE 42.1 | [May 2017](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-9.3&dist=opensuse%2F42.1) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-9.3&dist=opensuse%2F42.1) 9.3 |
+| OpenSUSE 42.2 | [January 2018](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-10.4&dist=opensuse%2F42.2) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-10.4&dist=opensuse%2F42.2) 10.4 |
+| Debian Wheezy | [May 2018](https://www.debian.org/News/2018/20180601) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce_11.6&dist=debian%2Fwheezy) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee_11.6&dist=debian%2Fwheezy) 11.6 |
+| Raspbian Jessie | [May 2017](https://downloads.raspberrypi.org/raspbian/images/raspbian-2017-07-05/) | [GitLab CE](https://packages.gitlab.com/app/gitlab/raspberry-pi2/search?q=gitlab-ce_11.7&dist=debian%2Fjessie) 11.7 |
+| Ubuntu 14.04 | [April 2019](https://ubuntu.com/info/release-end-of-life) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce_11.10&dist=ubuntu%2Ftrusty) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee_11.10&dist=ubuntu%2Ftrusty) 11.10 |
+| OpenSUSE 42.3 | [July 2019](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-12.1&dist=opensuse%2F42.3) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-12.1&dist=opensuse%2F42.3) 12.1 |
+| OpenSUSE 15.0 | [December 2019](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-12.5&dist=opensuse%2F15.0) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-12.5&dist=opensuse%2F15.0) 12.5 |
+| Raspbian Stretch | [June 2020](https://downloads.raspberrypi.org/raspbian/images/raspbian-2019-04-09/) | [GitLab CE](https://packages.gitlab.com/app/gitlab/raspberry-pi2/search?q=gitlab-ce_13.2&dist=raspbian%2Fstretch) 13.3 |
+| Debian Jessie | [June 2020](https://www.debian.org/News/2020/20200709) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce_13.2&dist=debian%2Fjessie) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee_13.2&dist=debian%2Fjessie) 13.3 |
+| CentOS 6 | [November 2020](https://wiki.centos.org/About/Product) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=13.6&filter=all&filter=all&dist=el%2F6) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=13.6&filter=all&filter=all&dist=el%2F6) 13.6 |
+| OpenSUSE 15.1 | [November 2020](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-13.12&dist=opensuse%2F15.1) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-13.12&dist=opensuse%2F15.2) 13.12 |
+| Ubuntu 16.04 | [April 2021](https://ubuntu.com/info/release-end-of-life) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce_13.12&dist=ubuntu%2Fxenial) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee_13.12&dist=ubuntu%2Fxenial) 13.12 |
+
+NOTE:
+An exception to this deprecation policy is when we are unable to provide
+packages for the next version of the operating system. The most common reason
+for this our package repository provider, Packagecloud, not supporting newer
+versions and hence we can't upload packages to it.
+
+## Update GitLab package sources after upgrading the OS
+
+After upgrading the Operating System (OS) as per its own documentation,
+it may be necessary to also update the GitLab package source URL
+in your package manager configuration.
+If your package manager reports that no further updates are available,
+although [new versions have been released](https://about.gitlab.com/releases/categories/releases/), repeat the
+"Add the GitLab package repository" instructions
+of the [Linux package install guide](https://about.gitlab.com/install/#content).
+Future GitLab upgrades will now be fetched according to your upgraded OS.
+
+## Supported Operating Systems
+
+GitLab officially supports LTS versions of operating systems. While OSs like
+Ubuntu have a clear distinction between LTS and non-LTS versions, there are
+other OSs, openSUSE for example, that don't follow the LTS concept. Hence to
+avoid confusion, the official policy is that at any point of time, all the
+operating systems supported by GitLab are listed in the [installation
+page](https://about.gitlab.com/install/).
+
+The following lists the currently supported OSs and their possible EOL dates.
+
+| OS Version | First supported GitLab version | Arch | OS EOL | Details |
+| ---------------- | ------------------------------ | --------------- | ------------- | ------------------------------------------------------------ |
+| CentOS 7 | GitLab CE / GitLab EE 7.10.0 | x86_64 | June 2024 | <https://wiki.centos.org/About/Product> |
+| CentOS 8 | GitLab CE / GitLab EE 12.8.1 | x86_64, aarch64 | Dec 2021 | <https://wiki.centos.org/About/Product> |
+| Debian 9 | GitLab CE / GitLab EE 9.3.0 | amd64 | 2022 | <https://wiki.debian.org/DebianReleases#Production_Releases> |
+| Debian 10 | GitLab CE / GitLab EE 12.2.0 | amd64, arm64 | TBD | <https://wiki.debian.org/DebianReleases#Production_Releases> |
+| OpenSUSE 15.2 | GitLab CE / GitLab EE 13.11.0 | x86_64, aarch64 | Dec 2021 | <https://en.opensuse.org/Lifetime> |
+| SLES 12 | GitLab EE 9.0.0 | x86_64 | Oct 2027 | <https://www.suse.com/lifecycle/> |
+| Ubuntu 18.04 | GitLab CE / GitLab EE 10.7.0 | amd64 | April 2023 | <https://wiki.ubuntu.com/Releases> |
+| Ubuntu 20.04 | GitLab CE / GitLab EE 13.2.0 | amd64, arm64 | April 2025 | <https://wiki.ubuntu.com/Releases> |
+| Raspbian Buster | GitLab CE 12.2.0 | armhf | 2022 | <https://wiki.debian.org/DebianReleases#Production_Releases> |
+
+### Packages for ARM64
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-omnibus-builder/-/issues/27) in GitLab 13.4.
+
+GitLab provides arm64/aarch64 packages for some supported operating systems.
+You can see if your operating system architecture is supported in the table
+above.
+
+WARNING:
+There are currently still some [known issues and limitation](https://gitlab.com/groups/gitlab-org/-/epics/4397)
+running GitLab on ARM.
diff --git a/doc/administration/package_information/deprecation_policy.md b/doc/administration/package_information/deprecation_policy.md
new file mode 100644
index 00000000000..cc16661442a
--- /dev/null
+++ b/doc/administration/package_information/deprecation_policy.md
@@ -0,0 +1,95 @@
+---
+stage: Enablement
+group: Distribution
+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/#designated-technical-writers
+---
+
+# Deprecation policy
+
+The Omnibus GitLab packages come with number of different libraries and services which offers users plethora of configuration options.
+
+As libraries and services get updated, their configuration options change
+and become obsolete. To increase maintainability and preserve a working
+setup, various configuration requires removal.
+
+## Configuration deprecation
+
+### Policy
+
+The Omnibus GitLab package will retain configuration for at least **one major**
+version. We cannot guarantee that deprecated configuration
+will be available in the next major release. See [example](#example) for more details.
+
+### Notice
+
+If the configuration becomes obsolete, we will announce the deprecation:
+
+- via release blog post on `https://about.gitlab.com/blog/`. The blog post item
+ will contain the deprecation notice together with the target removal date.
+- via installation/reconfigure output (if applicable).
+- via official documentation on `https://docs.gitlab.com/`. The documentation update will contain the corrected syntax (if applicable) or a date of configuration removal.
+
+### Procedure
+
+This section lists steps necessary for deprecating and removing configuration.
+
+We can differentiate two different types of configuration:
+
+- Sensitive: Configuration that can cause major service outage ( Data integrity,
+ installation integrity, preventing users from reaching the installation, etc.)
+- Regular: Configuration that can make a feature unavailable but still makes the installation useable ( Change in default project/group settings, miscommunication with other components and similar )
+
+We also need to differentiate deprecation and removal procedure.
+
+#### Deprecating configuration
+
+Deprecation procedure is similar for both `sensitive` and `regular` configuration. The only difference is in the removal target date.
+
+Common steps:
+
+1. Create an issue at the [Omnibus GitLab issue tracker](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues) with details on deprecation type and other necessary information. Apply the label `deprecation`.
+1. Decide on the removal target for the deprecated configuration
+1. Formulate deprecation notice for each item as noted in [Notice section](#notice)
+
+Removal target:
+
+For regular configuration, removal target should always be the date of the **next major** release. If the date is not known, you can reference the next major version.
+
+For sensitive configuration things are a bit more complicated.
+We should aim to not remove sensitive configuration in the *next major* release if the next major release is 2 minor releases away (This number is chosen to match our security backport release policy).
+
+See the table below for some examples:
+
+| Config. type | Deprecation announced | Final minor release | Remove |
+| -------- | -------- | -------- | -------- |
+| Sensitive | 10.1.0 | 10.9.0 | 11.0.0 |
+| Sensitive | 10.7.0 | 10.9.0 | 12.0.0 |
+| Regular | 10.1.0 | 10.9.0 | 11.0.0 |
+| Regular | 10.8.0 | 10.9.0 | 11.0.0 |
+
+#### Removing configuration
+
+When deprecation is announced and removal target set, the milestone for the issue
+should be changed to match the removal target version.
+
+The final comment in the issue **has to have**:
+
+1. Text snippet for the release blog post section
+1. Documentation MR ( or snippet ) for introducing the change
+1. Draft MR removing the configuration OR details on what needs to be done. See [Adding deprecation messages](https://docs.gitlab.com/omnibus/development/adding-deprecation-messages.html) for more on this
+
+## Example
+
+User configuration available in `/etc/gitlab/gitlab.rb` was introduced in GitLab version 10.0, `gitlab_rails['configuration'] = true`. In GitLab version 10.4.0, a new change was introduced that requires rename of this configuration option. New configuration option is `gitlab_rails['better_configuration'] = true`. Development team will translate the old configuration into new one
+and trigger a deprecation procedure.
+
+This means that these two configuration
+options will both be valid through GitLab version 10. In other words,
+if you still have `gitlab_rails['configuration'] = true` set in GitLab 10.8.0
+the feature will continue working the same way as if you had `gitlab_rails['better_configuration'] = true` set.
+However, setting the old version of configuration will print out a deprecation
+notice at the end of installation/upgrade/reconfigure run.
+
+With GitLab 11, `gitlab_rails['configuration'] = true` will no longer work and you will have to manually change the configuration in `/etc/gitlab/gitlab.rb` to the new valid config.
+**Note** If this configuration option is sensitive and can put integrity of the installation or
+data in danger, installation/upgrade will be aborted.
diff --git a/doc/administration/package_information/index.md b/doc/administration/package_information/index.md
new file mode 100644
index 00000000000..e18fb621b89
--- /dev/null
+++ b/doc/administration/package_information/index.md
@@ -0,0 +1,101 @@
+---
+stage: Enablement
+group: Distribution
+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/#designated-technical-writers
+---
+
+# Package information
+
+The Omnibus GitLab package is bundled with all dependencies required for GitLab
+to function correctly. More details can be found
+at [bundling dependencies document](omnibus_packages.md).
+
+## Package Version
+
+The released package versions are in the format `MAJOR.MINOR.PATCH-EDITION.OMNIBUS_RELEASE`
+
+| Component | Meaning | Example |
+| --------- | ------- | ------- |
+| MAJOR.MINOR.PATCH | The GitLab version this corresponds to | 13.3.0 |
+| EDITION | The edition of GitLab this corresponds to | ee |
+| OMNIBUS_RELEASE | The omnibus release. Usually, this will be 0. This will be incremented if we need to build a new package without changing the GitLab version. | 0 |
+
+## Licenses
+
+See [licensing](licensing.md)
+
+## Defaults
+
+The Omnibus GitLab package requires various configuration to get the
+components in working order.
+If the configuration is not provided, the package will use the default
+values assumed in the package.
+
+These defaults are noted in the package [defaults document](defaults.md).
+
+## Checking the versions of bundled software
+
+Once the Omnibus GitLab package is installed, all versions of the bundled
+libraries are located in `/opt/gitlab/version-manifest.txt`.
+
+If you don't have the package installed, you can always check the Omnibus GitLab
+[source repository](https://gitlab.com/gitlab-org/omnibus-gitlab/tree/master), specifically the
+[config directory](https://gitlab.com/gitlab-org/omnibus-gitlab/tree/master/config).
+
+For example, if you take a look at the `8-6-stable` branch, you can conclude that
+8.6 packages were running [Ruby 2.1.8](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/8-6-stable/config/projects/gitlab.rb#L48).
+Or, that 8.5 packages were bundled with [NGINX 1.9.0](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/8-5-stable/config/software/nginx.rb#L20).
+
+## Signatures of GitLab, Inc. provided packages
+
+Documentation on package signatures can be found at [Signed Packages](signed_packages.md)
+
+## Checking for newer configuration options on upgrade
+
+Configuration file in `/etc/gitlab/gitlab.rb` is created on initial installation
+of the Omnibus GitLab package. On subsequent package upgrades, the configuration
+file is not updated with new configuration. This is done in order to avoid
+accidental overwrite of user configuration provided in `/etc/gitlab/gitlab.rb`.
+
+New configuration options are noted in the
+[`gitlab.rb.template` file](https://gitlab.com/gitlab-org/omnibus-gitlab/raw/master/files/gitlab-config-template/gitlab.rb.template).
+
+The Omnibus GitLab package also provides convenience command which will
+compare the existing user configuration with the latest version of the
+template contained in the package.
+
+To view a diff between your configuration file and the latest version, run:
+
+```shell
+sudo gitlab-ctl diff-config
+```
+
+_**Note:** This command is available from GitLab 8.17_
+
+**Important:** If you are copy-pasting the output of this command into your
+`/etc/gitlab/gitlab.rb` configuration file, make sure to omit leading `+` and `-`
+on each line.
+
+## Init system detection
+
+Omnibus GitLab will attempt to query the underlaying system in order to
+check which init system it uses.
+This manifests itself as a `WARNING` during the `sudo gitlab-ctl reconfigure`
+run.
+
+Depending on the init system, this `WARNING` can be one of:
+
+```plaintext
+/sbin/init: unrecognized option '--version'
+```
+
+when the underlying init system *IS NOT* upstart.
+
+```plaintext
+ -.mount loaded active mounted /
+```
+
+when the underlying init system *IS* systemd.
+
+These warnings _can be safely ignored_. They are not suppressed because this
+allows everyone to debug possible detection issues faster.
diff --git a/doc/administration/package_information/licensing.md b/doc/administration/package_information/licensing.md
new file mode 100644
index 00000000000..8557a94bf93
--- /dev/null
+++ b/doc/administration/package_information/licensing.md
@@ -0,0 +1,79 @@
+---
+stage: Enablement
+group: Distribution
+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/#designated-technical-writers
+---
+
+# Package Licensing
+
+## License
+
+While GitLab itself is MIT, the Omnibus GitLab sources are licensed under the Apache-2.0.
+
+## License file location
+
+Starting with version 8.11, the Omnibus GitLab package contains license
+information of all software that is bundled within the package.
+
+After installing the package, licenses for each individual bundled library
+can be found in `/opt/gitlab/LICENSES` directory.
+
+There is also one `LICENSE` file which contains all licenses compiled together.
+This compiled license can be found in `/opt/gitlab/LICENSE` file.
+
+Starting with version 9.2, the Omnibus GitLab package ships a
+`dependency_licenses.json` file containing version and license information of
+all bundled software, including software libraries, Ruby gems that the rails
+application uses, and JavaScript libraries that is required for the frontend
+components. This file, being in JSON format, is easily machine parseable and
+can be used for automated checks or validations. The file may be found at
+`/opt/gitlab/dependency_licenses.json`.
+
+Starting with version 11.3, we have also made the license information available
+online, at: <https://gitlab-org.gitlab.io/omnibus-gitlab/licenses.html>
+
+## Checking licenses
+
+The Omnibus GitLab package is made up of many pieces of software, comprising code
+that is covered by many different licenses. Those licenses are provided and
+compiled as stated above.
+
+Starting with version 8.13, GitLab has placed an additional step into
+Omnibus GitLab. The `license_check` step calls
+`lib/gitlab/tasks/license_check.rake`, which checks the compiled `LICENSE` file
+against the current list of approved and questionable licenses as denoted in the
+arrays at the top of the script. This script will output one of `Good`,
+`Unknown` or `Check` for each piece of software that is a part of the
+Omnibus GitLab package.
+
+- `Good`: denotes a license that is approved for all usage types, within GitLab and
+ Omnibus GitLab.
+- `Unknown`: denotes a license that is not recognized in the list of 'good' or 'bad',
+ which should be immediately reviewed for implications of use.
+- `Check`: denotes a license that has the potential be incompatible with GitLab itself,
+ and thus should be checked for how it is used as a part of the Omnibus GitLab package
+ to ensure compliance.
+
+This list is currently sourced from the [GitLab development documentation on licensing](https://gitlab.com/gitlab-org/gitlab-foss/blob/master/doc/development/licensing.md).
+However, due to the nature of the Omnibus GitLab package the licenses may not apply
+in the same way. Such as with `git` and `rsync`. See the [GNU License FAQ](https://www.gnu.org/licenses/gpl-faq.en.html#MereAggregation)
+
+## License acknowledgements
+
+### libjpeg-turbo - BSD 3-clause license
+
+This software is based in part on the work of the Independent JPEG Group.
+
+## Trademark Usage
+
+Within the GitLab documentation, reference to third party technology(ies) and/or trademarks of third party entities, may be made. The inclusion of reference to third party technology and/or entities is solely for the purposes of example(s) of how GitLab software may interact with, or be used in conjunction with, such third party technology.
+All trademarks, materials, documentation, and other intellectual property remain the property of any/all such third party.
+
+### Trademark Requirements
+
+Use of GitLab Trademarks must be in compliance with the standards set forth in [our guidelines](https://about.gitlab.com/handbook/marketing/corporate-marketing/brand-activation/trademark-guidelines/) (as updated from time to time).
+CHEF® and all Chef marks are owned by Progress Software Corporation and must be used in accordance with the [Progress Software Trademark Usage Policy](https://www.progress.com/legal/trademarks).
+
+When using a GitLab or 3rd party trademark in documentation, include the (R) symbol in the first instance, for example, "Chef(R) is used for configuring...." You may omit the symbol in subsequent instances.
+
+If a trademark owner requires a particular notice or trademark requirement, such notice or requirement should be stated above.
diff --git a/doc/administration/package_information/omnibus_packages.md b/doc/administration/package_information/omnibus_packages.md
new file mode 100644
index 00000000000..aa73534fc55
--- /dev/null
+++ b/doc/administration/package_information/omnibus_packages.md
@@ -0,0 +1,115 @@
+---
+stage: Enablement
+group: Distribution
+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/#designated-technical-writers
+---
+
+# Omnibus based packages and images
+
+Below you can find some basic information on why GitLab provides packages and
+a Docker image that come with bundled dependencies.
+
+These methods are great for physical and virtual machine installations, and simple Docker installations.
+
+## Goals
+
+We have a few core goals with these packages:
+
+1. Extremely easy to install, upgrade, maintain.
+1. Support for a wide variety of operating systems
+1. Wide support of cloud service providers
+
+## Omnibus GitLab Architecture
+
+GitLab in its core is a Ruby on Rails project. However, GitLab as a whole
+application is more complex and has multiple components. If these components are
+not present or are incorrectly configured, GitLab will not work or it will work
+unpredictably.
+
+The [GitLab Architecture Overview](../../development/architecture.md#gitlab-architecture-overview) shows some of these components and how they
+interact. Each of these components needs to be configured and kept up to date.
+
+Most of the components also have external dependencies. For example, the Rails
+application depends on a number of [Ruby gems](https://gitlab.com/gitlab-org/gitlab-foss/blob/master/Gemfile.lock). Some of these dependencies also
+have their own external dependencies which need to be present on the Operating
+System in order for them to function correctly.
+
+Furthermore, GitLab has a monthly release cycle requiring frequent maintenance
+to stay up to date.
+
+All the things listed above present a challenge for the user maintaining the GitLab
+installation.
+
+## External Software Dependencies
+
+For applications such as GitLab, external dependencies usually bring the following
+challenges:
+
+- Keeping versions in sync between direct and indirect dependencies
+- Availability of a version on a specific Operating System
+- Version changes can introduce or remove previously used configuration
+- Security implications when library is marked as vulnerable but does not have
+ a new version released yet
+
+Keep in mind that if a dependency exists on your Operating System, it does not
+necessarily exist on other supported OSs.
+
+## Benefits
+
+A few benefits of a package with bundled dependencies:
+
+1. Minimal effort required to install GitLab.
+1. Minimum configuration required to get GitLab up and running.
+1. Minimum effort required to upgrade between GitLab versions.
+1. Multiple platforms supported.
+1. Maintenance on older platforms is greatly simplified.
+1. Less effort to support potential issues.
+
+## Drawbacks
+
+Some drawbacks of a package with bundled dependencies:
+
+1. Duplication with possibly existing software.
+1. Less flexibility in configuration.
+
+## Why would I install an omnibus package when I can use a system package?
+
+The answer can be simplified to: less maintenance required. Instead of handling
+multiple packages that *can* break existing functionality if the versions are
+not compatible, only handle one.
+
+Multiple packages require correct configuration in multiple locations.
+Keeping configuration in sync can be error prone.
+
+If you have the skill set to maintain all current dependencies and enough time
+to handle any future dependencies that might get introduced, the above listed
+reasons might not be good enough for you to not use the omnibus package.
+
+There are two things to keep in mind before going down this route:
+
+1. Getting support for any problems
+ you encounter might be more difficult due to the number of possibilities that exist
+ when using a library version that is not tested by majority of users.
+1. Omnibus package also allows shutting off of any services that you do not need,
+ if you need to run a component independently. For example, you can use a
+ [non-bundled PostgreSQL database](https://docs.gitlab.com/omnibus/settings/database.html#using-a-non-packaged-postgresql-database-management-server) with the omnibus package.
+
+Keep in mind that a non-standard solution like the omnibus package
+might be a better fit when the application has a number of moving parts.
+
+## Docker image with multiple services
+
+[GitLab Docker image](../../install/docker.md#gitlab-docker-images) is based on the omnibus package.
+
+Considering that container spawned from this image contains multiple processes,
+these types of containers are also referred to as 'fat containers'.
+
+There are reasons for and against an image like this, but they are similar to
+what was noted above:
+
+1. Very simple to get started.
+1. Upgrading to the latest version is extremely simple.
+1. Running separate services in multiple containers and keeping them running
+ can be more complex and might not be required for a given install.
+
+This method is useful for organizations just getting started with containers and schedulers, and may not be ready for a more complex installation. This method is a great introduction, and will work well for smaller organizations.
diff --git a/doc/administration/package_information/postgresql_versions.md b/doc/administration/package_information/postgresql_versions.md
new file mode 100644
index 00000000000..89da4864872
--- /dev/null
+++ b/doc/administration/package_information/postgresql_versions.md
@@ -0,0 +1,42 @@
+---
+stage: Enablement
+group: Distribution
+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/#designated-technical-writers
+---
+
+# PostgreSQL versions shipped with Omnibus GitLab
+
+NOTE:
+This table lists only GitLab versions where a significant change happened in the
+package regarding PostgreSQL versions, not all.
+
+Usually, PostgreSQL versions change with major or minor GitLab releases. However, patch versions
+of Omnibus GitLab sometimes update the patch level of PostgreSQL.
+
+For example:
+
+- Omnibus 12.7.6 shipped with PostgreSQL 9.6.14 and 10.9.
+- Omnibus 12.7.7 shipped with PostgreSQL 9.6.17 and 10.12.
+
+[Find out which versions of PostgreSQL (and other components) ship with
+each Omnibus GitLab release](https://gitlab-org.gitlab.io/omnibus-gitlab/licenses.html).
+
+Read more about update policies and warnings in the PostgreSQL
+[upgrade docs](https://docs.gitlab.com/omnibus/settings/database.html#upgrade-packaged-postgresql-server).
+
+| GitLab version | PostgreSQL versions | Default version for fresh installs | Default version for upgrades | Notes |
+| -------------- | --------------------- | ---------------------------------- | ---------------------------- | ----- |
+| 14.1 | 12.6, 13.3 | 12.6 | 12.6 | PostgreSQL 13 available for fresh installations if not using Geo or High Availability. |
+| 14.0 | 12.6 | 12.6 | 12.6 | HA installations with repmgr are no longer supported and will be prevented from upgrading to Omnibus GitLab 14.0 |
+| 13.8 | 11.9, 12.4 | 12.4 | 12.4 | Package upgrades automatically performed PostgreSQL upgrade for nodes that are not part of a Geo or HA cluster.). |
+| 13.7 | 11.9, 12.4 | 12.4 | 11.9 | For upgrades users can manually upgrade to 12.4 following the [upgrade docs](https://docs.gitlab.com/omnibus/settings/database.html#gitlab-133-and-later). |
+| 13.4 | 11.9, 12.4 | 11.9 | 11.9 | Package upgrades aborted if users not running PostgreSQL 11 already |
+| 13.3 | 11.7, 12.3 | 11.7 | 11.7 | Package upgrades aborted if users not running PostgreSQL 11 already |
+| 13.0 | 11.7 | 11.7 | 11.7 | Package upgrades aborted if users not running PostgreSQL 11 already |
+| 12.10 | 9.6.17, 10.12, and 11.7 | 11.7 | 11.7 | Package upgrades automatically performed PostgreSQL upgrade for nodes that are not part of a Geo or repmgr cluster. |
+| 12.8 | 9.6.17, 10.12, and 11.7 | 10.12 | 10.12 | Users can manually upgrade to 11.7 following the upgrade docs. |
+| 12.0 | 9.6.11 and 10.7 | 10.7 | 10.7 | Package upgrades automatically performed PostgreSQL upgrade. |
+| 11.11 | 9.6.11 and 10.7 | 9.6.11 | 9.6.11 | Users can manually upgrade to 10.7 following the upgrade docs. |
+| 10.0 | 9.6.3 | 9.6.3 | 9.6.3 | Package upgrades aborted if users still on 9.2. |
+| 9.0 | 9.2.18 and 9.6.1 | 9.6.1 | 9.6.1 | Package upgrades automatically performed PostgreSQL upgrade. |
+| 8.14 | 9.2.18 and 9.6.1 | 9.2.18 | 9.2.18 | Users can manually upgrade to 9.6 following the upgrade docs. |
diff --git a/doc/administration/package_information/signed_packages.md b/doc/administration/package_information/signed_packages.md
new file mode 100644
index 00000000000..fb994809460
--- /dev/null
+++ b/doc/administration/package_information/signed_packages.md
@@ -0,0 +1,25 @@
+---
+stage: Enablement
+group: Distribution
+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/#designated-technical-writers
+---
+
+# Package Signatures
+
+As of the release of GitLab 9.5 on August 22, 2017, GitLab provides signed Omnibus GitLab packages for RPM and DEB based distributions. This means that all packages provided on <https://packages.gitlab.com> are signed, starting with `9.5.0`, and all future versions of supported branches (e.g. `9.3.x` and `9.4.x` after August 22, 2017). Any package version prior to August 22, 2017, will not be signed. Please pass the appropriate argument to your package manager. (Example: `yum --nogpgcheck`)
+
+Omnibus GitLab packages produced by GitLab are created via the [Omnibus](https://github.com/chef/omnibus) tool, for which GitLab has added DEB signing via `debsigs` in [our own fork](https://gitlab.com/gitlab-org/omnibus). This addition, combined with the existing functionality of RPM signing, allows GitLab to provide signed packages for all supported distributions using DEB or RPM.
+
+These packages are produced by the GitLab CI process, as found in the [Omnibus GitLab project](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/.gitlab-ci.yml), prior to their delivery to <https://packages.gitlab.com> to ensure provide assurance that the packages are not altered prior to delivery to our community.
+
+## GnuPG Public Keys
+
+All packages are signed with [GnuPG](https://www.gnupg.org/), in a method appropriate for their format. The key used to sign these packages can be found on [pgp.mit.edu](https://pgp.mit.edu) at [0x3cfcf9baf27eab47](https://pgp.mit.edu/pks/lookup?op=vindex&search=0x3CFCF9BAF27EAB47)
+
+## Verifying Signatures
+
+Information on how to verify GitLab package signatures can be found in [Package Signatures](https://docs.gitlab.com/omnibus/update/package_signatures.html).
+
+## GPG Signature Management
+
+Information on how GitLab manages GPG keys for package signing can be found in [the runbooks](https://gitlab.com/gitlab-com/runbooks/-/blob/master/docs/packaging/manage-package-signing-keys.md).
diff --git a/doc/administration/packages/container_registry.md b/doc/administration/packages/container_registry.md
index eb118709f94..1067474c8b4 100644
--- a/doc/administration/packages/container_registry.md
+++ b/doc/administration/packages/container_registry.md
@@ -321,7 +321,7 @@ The different supported drivers are:
| Driver | Description |
|--------------|--------------------------------------|
| `filesystem` | Uses a path on the local file system |
-| `Azure` | Microsoft Azure Blob Storage |
+| `azure` | Microsoft Azure Blob Storage |
| `gcs` | Google Cloud Storage |
| `s3` | Amazon Simple Storage Service. Be sure to configure your storage bucket with the correct [S3 Permission Scopes](https://docs.docker.com/registry/storage-drivers/s3/#s3-permission-scopes). |
| `swift` | OpenStack Swift Object Storage |
@@ -1054,6 +1054,80 @@ PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
You may want to add the `-m` flag to [remove untagged manifests and unreferenced layers](#removing-untagged-manifests-and-unreferenced-layers).
+## Configuring GitLab and Registry to run on separate nodes (Omnibus GitLab)
+
+By default, package assumes that both services are running on the same node.
+In order to get GitLab and Registry to run on a separate nodes, separate configuration
+is necessary for Registry and GitLab.
+
+### Configuring Registry
+
+Below you will find configuration options you should set in `/etc/gitlab/gitlab.rb`,
+for Registry to run separately from GitLab:
+
+- `registry['registry_http_addr']`, default [set programmatically](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/10-3-stable/files/gitlab-cookbooks/gitlab/libraries/registry.rb#L50). Needs to be reachable by web server (or LB).
+- `registry['token_realm']`, default [set programmatically](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/10-3-stable/files/gitlab-cookbooks/gitlab/libraries/registry.rb#L53). Specifies the endpoint to use to perform authentication, usually the GitLab URL.
+ This endpoint needs to be reachable by user.
+- `registry['http_secret']`, [random string](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/10-3-stable/files/gitlab-cookbooks/gitlab/libraries/registry.rb#L32). A random piece of data used to sign state that may be stored with the client to protect against tampering.
+- `registry['internal_key']`, default [automatically generated](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/10-3-stable/files/gitlab-cookbooks/gitlab/recipes/gitlab-rails.rb#L113-119). Contents of the key that GitLab uses to sign the tokens. They key gets created on the Registry server, but it won't be used there.
+- `gitlab_rails['registry_key_path']`, default [set programmatically](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/10-3-stable/files/gitlab-cookbooks/gitlab/recipes/gitlab-rails.rb#L35). This is the path where `internal_key` contents will be written to disk.
+- `registry['internal_certificate']`, default [automatically generated](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/10-3-stable/files/gitlab-cookbooks/registry/recipes/enable.rb#L60-66). Contents of the certificate that GitLab uses to sign the tokens.
+- `registry['rootcertbundle']`, default [set programmatically](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/10-3-stable/files/gitlab-cookbooks/registry/recipes/enable.rb#L60). Path to certificate. This is the path where `internal_certificate`
+ contents will be written to disk.
+- `registry['health_storagedriver_enabled']`, default [set programmatically](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/10-7-stable/files/gitlab-cookbooks/gitlab/libraries/registry.rb#L88). Configure whether health checks on the configured storage driver are enabled.
+- `gitlab_rails['registry_issuer']`, [default value](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/10-3-stable/files/gitlab-cookbooks/gitlab/attributes/default.rb#L153). This setting needs to be set the same between Registry and GitLab.
+
+### Configuring GitLab
+
+Below you will find configuration options you should set in `/etc/gitlab/gitlab.rb`,
+for GitLab to run separately from Registry:
+
+- `gitlab_rails['registry_enabled']`, must be set to `true`. This setting will
+ signal to GitLab that it should allow Registry API requests.
+- `gitlab_rails['registry_api_url']`, default [set programmatically](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/10-3-stable/files/gitlab-cookbooks/gitlab/libraries/registry.rb#L52). This is the Registry URL used internally that users do not need to interact with, `registry['registry_http_addr']` with scheme.
+- `gitlab_rails['registry_host']`, eg. `registry.gitlab.example`. Registry endpoint without the scheme, the address that gets shown to the end user.
+- `gitlab_rails['registry_port']`. Registry endpoint port, visible to the end user.
+- `gitlab_rails['registry_issuer']` must match the issuer in the Registry configuration.
+- `gitlab_rails['registry_key_path']`, path to the key that matches the certificate on the
+ Registry side.
+- `gitlab_rails['internal_key']`, contents of the key that GitLab uses to sign the tokens.
+
+## Architecture of GitLab Container Registry
+
+The GitLab registry is what users use to store their own Docker images.
+Because of that the Registry is client facing, meaning that we expose it directly
+on the web server (or load balancers, LB for short).
+
+![GitLab Registry diagram](img/gitlab-registry-architecture.png)
+
+The flow described by the diagram above:
+
+1. A user runs `docker login registry.gitlab.example` on their client. This reaches the web server (or LB) on port 443.
+1. Web server connects to the Registry backend pool (by default, using port 5000). Since the user
+ didn’t provide a valid token, the Registry returns a 401 HTTP code and the URL (`token_realm` from
+ Registry configuration) where to get one. This points to the GitLab API.
+1. The Docker client then connects to the GitLab API and obtains a token.
+1. The API signs the token with the registry key and hands it to the Docker client
+1. The Docker client now logs in again with the token received from the API. It can now push and pull Docker images.
+
+Reference: <https://docs.docker.com/registry/spec/auth/token/>
+
+### Communication between GitLab and Registry
+
+Registry doesn’t have a way to authenticate users internally so it relies on
+GitLab to validate credentials. The connection between Registry and GitLab is
+TLS encrypted. The key is used by GitLab to sign the tokens while the certificate
+is used by Registry to validate the signature. By default, a self-signed certificate key pair is generated
+for all installations. This can be overridden as needed.
+
+GitLab interacts with the Registry using the Registry private key. When a Registry
+request goes out, a new short-living (10 minutes) namespace limited token is generated
+and signed with the private key.
+The Registry then verifies that the signature matches the registry certificate
+specified in its configuration and allows the operation.
+GitLab background jobs processing (through Sidekiq) also interacts with Registry.
+These jobs talk directly to Registry in order to handle image deletion.
+
## Troubleshooting
Before diving in to the following sections, here's some basic troubleshooting:
@@ -1122,7 +1196,7 @@ CI/CD > Container Registry > Authorization token duration (minutes)**.
### Docker login attempt fails with: 'token signed by untrusted key'
-[Registry relies on GitLab to validate credentials](https://docs.gitlab.com/omnibus/architecture/registry/).
+[Registry relies on GitLab to validate credentials](#architecture-of-gitlab-container-registry)
If the registry fails to authenticate valid login attempts, you get the following error message:
```shell
diff --git a/doc/administration/packages/dependency_proxy.md b/doc/administration/packages/dependency_proxy.md
index c4906ef6d8e..32e7e191011 100644
--- a/doc/administration/packages/dependency_proxy.md
+++ b/doc/administration/packages/dependency_proxy.md
@@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# GitLab Dependency Proxy administration **(FREE SELF)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7934) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.11.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/273655) to [GitLab Free](https://about.gitlab.com/pricing/) in GitLab 13.6.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/273655) from GitLab Premium to GitLab Free in 13.6.
GitLab can be used as a dependency proxy for a variety of common package managers.
diff --git a/doc/administration/packages/img/gitlab-registry-architecture.png b/doc/administration/packages/img/gitlab-registry-architecture.png
new file mode 100644
index 00000000000..742678d5e11
--- /dev/null
+++ b/doc/administration/packages/img/gitlab-registry-architecture.png
Binary files differ
diff --git a/doc/administration/packages/index.md b/doc/administration/packages/index.md
index 2c2e3fc0442..37473d35573 100644
--- a/doc/administration/packages/index.md
+++ b/doc/administration/packages/index.md
@@ -14,22 +14,17 @@ The Packages feature allows GitLab to act as a repository for the following:
The Package Registry supports the following formats:
-<div class="row">
-<div class="col-md-9">
-<table align="left" style="width:50%">
-<tr style="background:#dfdfdf"><th>Package type</th><th>GitLab version</th></tr>
-<tr><td><a href="https://docs.gitlab.com/ee/user/packages/composer_repository/index.html">Composer</a></td><td>13.2+</td></tr>
-<tr><td><a href="https://docs.gitlab.com/ee/user/packages/conan_repository/index.html">Conan</a></td><td>12.6+</td></tr>
-<tr><td><a href="https://docs.gitlab.com/ee/user/packages/go_proxy/index.html">Go</a></td><td>13.1+</td></tr>
-<tr><td><a href="https://docs.gitlab.com/ee/user/packages/maven_repository/index.html">Maven</a></td><td>11.3+</td></tr>
-<tr><td><a href="https://docs.gitlab.com/ee/user/packages/npm_registry/index.html">npm</a></td><td>11.7+</td></tr>
-<tr><td><a href="https://docs.gitlab.com/ee/user/packages/nuget_repository/index.html">NuGet</a></td><td>12.8+</td></tr>
-<tr><td><a href="https://docs.gitlab.com/ee/user/packages/pypi_repository/index.html">PyPI</a></td><td>12.10+</td></tr>
-<tr><td><a href="https://docs.gitlab.com/ee/user/packages/generic_packages/index.html">Generic packages</a></td><td>13.5+</td></tr>
-<tr><td><a href="https://docs.gitlab.com/ee/user/packages/helm_repository/index.html">Helm Charts</a></td><td>14.1+</td></tr>
-</table>
-</div>
-</div>
+| Package type | GitLab version |
+|-------------------------------------------------------------------|----------------|
+| [Composer](../../user/packages/composer_repository/index.md) | 13.2+ |
+| [Conan](../../user/packages/conan_repository/index.md) | 12.6+ |
+| [Go](../../user/packages/go_proxy/index.md) | 13.1+ |
+| [Maven](../../user/packages/maven_repository/index.md) | 11.3+ |
+| [npm](../../user/packages/npm_registry/index.md) | 11.7+ |
+| [NuGet](../../user/packages/nuget_repository/index.md) | 12.8+ |
+| [PyPI](../../user/packages/pypi_repository/index.md) | 12.10+ |
+| [Generic packages](../../user/packages/generic_packages/index.md) | 13.5+ |
+| [Helm Charts](../../user/packages/helm_repository/index.md) | 14.1+ |
## Accepting contributions
diff --git a/doc/administration/pages/index.md b/doc/administration/pages/index.md
index 5aeb3eaef7f..8b7af5ee170 100644
--- a/doc/administration/pages/index.md
+++ b/doc/administration/pages/index.md
@@ -196,43 +196,6 @@ to use the HTTPS protocol.
WARNING:
Multiple wildcards for one instance is not supported. Only one wildcard per instance can be assigned.
-### Additional configuration for Docker container
-
-The GitLab Pages daemon doesn't have permissions to bind mounts when it runs
-in a Docker container. To overcome this issue, you must change the `chroot`
-behavior:
-
-1. Edit `/etc/gitlab/gitlab.rb`.
-1. Set the `inplace_chroot` to `true` for GitLab Pages:
-
- ```ruby
- gitlab_pages['inplace_chroot'] = true
- ```
-
-1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
-
-NOTE:
-`inplace_chroot` option might not work with the other features, such as [Pages Access Control](#access-control).
-The [GitLab Pages README](https://gitlab.com/gitlab-org/gitlab-pages#caveats) has more information about caveats and workarounds.
-
-### Jailing mechanism disabled by default for API-based configuration
-
-Starting from GitLab 14.1 the [jailing/chroot mechanism is disabled by default](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/589).
-If you are using API-based configuration and the new [Zip storage architecture](#zip-storage)
-there is nothing you need to do.
-
-If you run into any problems, [open a new issue](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/new)
-and enable the jail again by setting the environment variable:
-
-1. Edit `/etc/gitlab/gitlab.rb`.
-1. Set the `DAEMON_ENABLE_JAIL` environment variable to `true` for GitLab Pages:
-
- ```ruby
- gitlab_pages['env']['DAEMON_ENABLE_JAIL'] = "true"
- ```
-
-1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
-
### Global settings
Below is a table of all configuration settings known to Pages in Omnibus GitLab,
@@ -270,7 +233,7 @@ control over how the Pages daemon runs and serves content in your environment.
| `auth_scope` | The OAuth application scope to use for authentication. Must match GitLab Pages OAuth application settings. Leave blank to use `api` scope by default. |
| `gitlab_server` | Server to use for authentication when access control is enabled; defaults to GitLab `external_url`. |
| `headers` | Specify any additional http headers that should be sent to the client with each response. Multiple headers can be given as an array, header and value as one string, for example `['my-header: myvalue', 'my-other-header: my-other-value']` |
-| `inplace_chroot` | On [systems that don't support bind-mounts](index.md#additional-configuration-for-docker-container), this instructs GitLab Pages to `chroot` into its `pages_path` directory. Some caveats exist when using in-place `chroot`; refer to the GitLab Pages [README](https://gitlab.com/gitlab-org/gitlab-pages/blob/master/README.md#caveats) for more information. |
+| `inplace_chroot` | [REMOVED in GitLab 14.3.](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/561) On [systems that don't support bind-mounts](index.md#gitlab-pages-fails-to-start-in-docker-container), this instructs GitLab Pages to `chroot` into its `pages_path` directory. Some caveats exist when using in-place `chroot`; refer to the GitLab Pages [README](https://gitlab.com/gitlab-org/gitlab-pages/blob/master/README.md#caveats) for more information. |
| `enable_disk` | Allows the GitLab Pages daemon to serve content from disk. Shall be disabled if shared disk storage isn't available. |
| `insecure_ciphers` | Use default list of cipher suites, may contain insecure ones like 3DES and RC4. |
| `internal_gitlab_server` | Internal GitLab server address used exclusively for API requests. Useful if you want to send that traffic over an internal load balancer. Defaults to GitLab `external_url`. |
@@ -298,8 +261,9 @@ control over how the Pages daemon runs and serves content in your environment.
| `pages_path` | The directory on disk where pages are stored, defaults to `GITLAB-RAILS/shared/pages`. |
| **`pages_nginx[]`** | |
| `enable` | Include a virtual host `server{}` block for Pages inside NGINX. Needed for NGINX to proxy traffic back to the Pages daemon. Set to `false` if the Pages daemon should directly receive all requests, for example, when using [custom domains](index.md#custom-domains). |
-| `FF_ENABLE_REDIRECTS` | Feature flag to disable redirects (enabled by default). Read the [redirects documentation](../../user/project/pages/redirects.md#disable-redirects) for more information. |
-| `use_legacy_storage` | Temporarily-introduced parameter allowing to use legacy domain configuration source and storage. [Will be removed in GitLab 14.3](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/6166). |
+| `FF_ENABLE_REDIRECTS` | Feature flag to enable/disable redirects (enabled by default). Read the [redirects documentation](../../user/project/pages/redirects.md#feature-flag-for-redirects) for more information. |
+| `FF_ENABLE_PLACEHOLDERS` | Feature flag to enable/disable rewrites (disabled by default). Read the [redirects documentation](../../user/project/pages/redirects.md#feature-flag-for-rewrites) for more information. |
+| `use_legacy_storage` | Temporarily-introduced parameter allowing to use legacy domain configuration source and storage. [Removed in 14.3](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/6166). |
---
@@ -393,7 +357,7 @@ adding a GitLab-controlled verification code to the DNS records for that domain.
If your user base is private or otherwise trusted, you can disable the
verification requirement:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Preferences**.
1. Expand **Pages**.
1. Clear the **Require users to prove ownership of custom domains** checkbox.
@@ -410,7 +374,7 @@ sites served under a custom domain.
To enable it:
1. Choose an email address on which you want to receive notifications about expiring domains.
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Preferences**.
1. Expand **Pages**.
1. Enter the email address for receiving notifications and accept Let's Encrypt's Terms of Service.
@@ -465,7 +429,7 @@ pre-existing applications must modify the GitLab Pages OAuth application. Follow
this:
1. Enable [access control](#access-control).
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Applications**.
1. Expand **GitLab Pages**.
1. Clear the `api` scope's checkbox and select the desired scope's checkbox (for example,
@@ -484,7 +448,7 @@ This can be useful to preserve information published with Pages websites to the
of your instance only.
To do that:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Preferences**.
1. Expand **Pages**.
1. Select the **Disable public access to Pages sites** checkbox.
@@ -522,7 +486,7 @@ Authority (CA) in the system certificate store.
For Omnibus, this is fixed by [installing a custom CA in Omnibus GitLab](https://docs.gitlab.com/omnibus/settings/ssl.html#install-custom-public-certificates).
-### Zip serving and cache configuration
+### ZIP serving and cache configuration
> [Introduced](https://gitlab.com/gitlab-org/gitlab-pages/-/merge_requests/392) in GitLab 13.7.
@@ -530,19 +494,19 @@ WARNING:
These are advanced settings. The recommended default values are set inside GitLab Pages. You should
change these settings only if absolutely necessary. Use extreme caution.
-GitLab Pages can serve content from zip archives through object storage (an
+GitLab Pages can serve content from ZIP archives through object storage (an
[issue](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/485) exists for supporting disk storage
-as well). It uses an in-memory cache to increase the performance when serving content from a zip
+as well). It uses an in-memory cache to increase the performance when serving content from a ZIP
archive. You can modify the cache behavior by changing the following configuration flags.
| Setting | Description |
| ------- | ----------- |
-| `zip_cache_expiration` | The cache expiration interval of zip archives. Must be greater than zero to avoid serving stale content. Default is 60s. |
+| `zip_cache_expiration` | The cache expiration interval of ZIP archives. Must be greater than zero to avoid serving stale content. Default is 60s. |
| `zip_cache_cleanup` | The interval at which archives are cleaned from memory if they have already expired. Default is 30s. |
| `zip_cache_refresh` | The time interval in which an archive is extended in memory if accessed before `zip_cache_expiration`. This works together with `zip_cache_expiration` to determine if an archive is extended in memory. See the [example below](#zip-cache-refresh-example) for important details. Default is 30s. |
-| `zip_open_timeout` | The maximum time allowed to open a zip archive. Increase this time for big archives or slow network connections, as doing so may affect the latency of serving Pages. Default is 30s. |
+| `zip_open_timeout` | The maximum time allowed to open a ZIP archive. Increase this time for big archives or slow network connections, as doing so may affect the latency of serving Pages. Default is 30s. |
-#### Zip cache refresh example
+#### ZIP cache refresh example
Archives are refreshed in the cache (extending the time they are held in memory) if they're accessed
before `zip_cache_expiration`, and the time left before expiring is less than or equal to
@@ -556,7 +520,7 @@ opened) it's refreshed. This extends the time the archive remains in memory from
After an archive reaches `zip_cache_expiration`, it's marked as expired and removed on the next
`zip_cache_cleanup` interval.
-![Zip cache configuration](img/zip_cache_configuration.png)
+![ZIP cache configuration](img/zip_cache_configuration.png)
## Activate verbose logging for daemon
@@ -665,7 +629,7 @@ Follow the steps below to configure the proxy listener of GitLab Pages.
To set the global maximum pages size for a project:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Preferences**.
1. Expand **Pages**.
1. Edit the **Maximum size of pages**.
@@ -742,6 +706,9 @@ database encryption. Proceed with caution.
gitlab_pages['gitlab_server'] = 'http://<gitlab_server_IP_or_URL>'
```
+1. If you have custom UID/GID settings on the **GitLab server**, add them to the **Pages server** `/etc/gitlab/gitlab.rb` as well,
+ otherwise running a `gitlab-ctl reconfigure` on the **GitLab server** can change file ownership and cause Pages requests to fail.
+
1. Create a backup of the secrets file on the **Pages server**:
```shell
@@ -1047,7 +1014,7 @@ If you use [object storage](#using-object-storage), you can disable local storag
Starting from GitLab 13.12, this setting also disables the [legacy storage](#migrate-legacy-storage-to-zip-storage), so if you were using NFS to serve Pages, you can completely disconnect from it.
-## Migrate GitLab Pages to 14.0
+## Prepare GitLab Pages for 14.0
In GitLab 14.0 a number of breaking changes were introduced which may require some user intervention.
The steps below describe the best way to migrate without causing any downtime for your GitLab instance.
@@ -1104,6 +1071,9 @@ You can also find the log file in `/var/log/gitlab/gitlab-pages/current`.
### `open /etc/ssl/ca-bundle.pem: permission denied`
+WARNING:
+This issue is fixed in GitLab 14.3 and above, try upgrading GitLab first.
+
GitLab Pages runs inside a `chroot` jail, usually in a uniquely numbered directory like
`/tmp/gitlab-pages-*`.
@@ -1135,6 +1105,9 @@ sudo gitlab-ctl restart gitlab-pages
### `dial tcp: lookup gitlab.example.com` and `x509: certificate signed by unknown authority`
+WARNING:
+This issue is fixed in GitLab 14.3 and above, try upgrading GitLab first.
+
When setting both `inplace_chroot` and `access_control` to `true`, you might encounter errors like:
```plaintext
@@ -1260,6 +1233,14 @@ For example, you can adapt the `rsync` strategy from the
[moving repositories documentation](../operations/moving_repositories.md).
Alternatively, run the CI pipelines of those projects that contain a `pages` job again.
+## 404 or 500 error when accessing GitLab Pages in a Geo setup
+
+Pages sites are only available on the primary Geo site, while the codebase of the project is available on all sites.
+
+If you try to access a Pages page on a secondary site, you will get a 404 or 500 HTTP code depending on the access control.
+
+Read more which [features don't support Geo replication/verification](../geo/replication/datatypes.md#limitations-on-replicationverification).
+
### Failed to connect to the internal GitLab API
If you see the following error:
@@ -1297,7 +1278,7 @@ in all of your GitLab Pages instances.
### 500 error with `securecookie: failed to generate random iv` and `Failed to save the session`
-This problem most likely results from an [out-dated operating system](https://docs.gitlab.com/omnibus/package-information/deprecated_os.html).
+This problem most likely results from an [out-dated operating system](../package_information/deprecated_os.md).
The [Pages daemon uses the `securecookie` library](https://gitlab.com/search?group_id=9970&project_id=734943&repository_ref=master&scope=blobs&search=securecookie&snippets=false) to get random strings via [`crypto/rand` in Go](https://golang.org/pkg/crypto/rand/#pkg-variables).
This requires the `getrandom` system call or `/dev/urandom` to be available on the host OS.
Upgrading to an [officially supported operating system](https://about.gitlab.com/install/) is recommended.
@@ -1306,7 +1287,7 @@ Upgrading to an [officially supported operating system](https://about.gitlab.com
This problem comes from the permissions of the GitLab Pages OAuth application. To fix it:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Applications > GitLab Pages**.
1. Edit the application.
1. Under **Scopes**, ensure that the `api` scope is selected.
@@ -1391,17 +1372,12 @@ both servers.
GitLab 14.0 introduces a number of changes to GitLab Pages which may require manual intervention.
-1. Firstly [follow the migration guide](#migrate-gitlab-pages-to-140).
+1. Firstly [follow the migration guide](#prepare-gitlab-pages-for-140).
+1. Try to upgrade to GitLab 14.3 or above. Some of the issues were fixed in GitLab 14.1, 14.2 and 14.3.
1. If it doesn't work, see [GitLab Pages logs](#how-to-see-gitlab-pages-logs), and if you see any errors there then search them on this page.
-The most common problem is when using [`inplace_chroot`](#dial-tcp-lookup-gitlabexamplecom-and-x509-certificate-signed-by-unknown-authority).
-
-NOTE:
-Starting from 14.1, the chroot/jailing mechanism is
-[disabled by default for API-based configuration](#jailing-mechanism-disabled-by-default-for-api-based-configuration).
-
WARNING:
-As the last resort you can temporarily enable legacy storage and configuration mechanisms. Support for them [will be removed in GitLab 14.3](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/6166), so GitLab Pages will stop working if don't resolve the underlying issue.
+In GitLab 14.0-14.2 you can temporarily enable legacy storage and configuration mechanisms.
To do that:
@@ -1414,3 +1390,25 @@ To do that:
```
1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+
+### GitLab Pages fails to start in Docker container
+
+WARNING:
+This issue is fixed in GitLab 14.3 and above, try upgrading GitLab first.
+
+The GitLab Pages daemon doesn't have permissions to bind mounts when it runs
+in a Docker container. To overcome this issue, you must change the `chroot`
+behavior:
+
+1. Edit `/etc/gitlab/gitlab.rb`.
+1. Set the `inplace_chroot` to `true` for GitLab Pages:
+
+ ```ruby
+ gitlab_pages['inplace_chroot'] = true
+ ```
+
+1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+
+NOTE:
+`inplace_chroot` option might not work with the other features, such as [Pages Access Control](#access-control).
+The [GitLab Pages README](https://gitlab.com/gitlab-org/gitlab-pages#caveats) has more information about caveats and workarounds.
diff --git a/doc/administration/pages/source.md b/doc/administration/pages/source.md
index b5c3330b2ce..278d792052a 100644
--- a/doc/administration/pages/source.md
+++ b/doc/administration/pages/source.md
@@ -473,7 +473,7 @@ The default for the maximum size of unpacked archives per project is 100 MB.
To change this value:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Preferences**.
1. Expand **Pages**.
1. Update the value for **Maximum size of pages (MB)**.
diff --git a/doc/administration/polling.md b/doc/administration/polling.md
index 5c4ee837057..8bd28824f83 100644
--- a/doc/administration/polling.md
+++ b/doc/administration/polling.md
@@ -26,7 +26,7 @@ The default value (`1`) is recommended for the majority of GitLab installations.
To adjust the polling interval multiplier:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Preferences**.
1. Expand **Polling interval multiplier**.
1. Set a value for the polling interval multiplier. This multiplier is applied to all resources at
diff --git a/doc/administration/postgresql/pgbouncer.md b/doc/administration/postgresql/pgbouncer.md
index 7171e90949e..e215622bbc7 100644
--- a/doc/administration/postgresql/pgbouncer.md
+++ b/doc/administration/postgresql/pgbouncer.md
@@ -173,7 +173,7 @@ ote_pid | tls
Some database changes have to be done directly, and not through PgBouncer.
Read more about the affected tasks: [database restores](../../raketasks/backup_restore.md#backup-and-restore-for-installations-using-pgbouncer)
-and [GitLab upgrades](https://docs.gitlab.com/omnibus/update/README.html#use-postgresql-ha).
+and [GitLab upgrades](../../update/zero_downtime.md#use-postgresql-ha).
1. To find the primary node, run the following on a database node:
diff --git a/doc/administration/postgresql/replication_and_failover.md b/doc/administration/postgresql/replication_and_failover.md
index 1308697c16e..2e0820b69c9 100644
--- a/doc/administration/postgresql/replication_and_failover.md
+++ b/doc/administration/postgresql/replication_and_failover.md
@@ -72,13 +72,13 @@ the PgBouncer service.
### Connection flow
-Each service in the package comes with a set of [default ports](https://docs.gitlab.com/omnibus/package-information/defaults.html#ports). You may need to make specific firewall rules for the connections listed below:
+Each service in the package comes with a set of [default ports](../package_information/defaults.md#ports). You may need to make specific firewall rules for the connections listed below:
-- Application servers connect to either PgBouncer directly via its [default port](https://docs.gitlab.com/omnibus/package-information/defaults.html#pgbouncer) or via a configured Internal Load Balancer (TCP) that serves multiple PgBouncers.
-- PgBouncer connects to the primary database servers [PostgreSQL default port](https://docs.gitlab.com/omnibus/package-information/defaults.html#postgresql)
+- Application servers connect to either PgBouncer directly via its [default port](../package_information/defaults.md) or via a configured Internal Load Balancer (TCP) that serves multiple PgBouncers.
+- PgBouncer connects to the primary database servers [PostgreSQL default port](../package_information/defaults.md)
- Patroni actively manages the running PostgreSQL processes and configuration.
-- PostgreSQL secondaries connect to the primary database servers [PostgreSQL default port](https://docs.gitlab.com/omnibus/package-information/defaults.html#postgresql)
-- Consul servers and agents connect to each others [Consul default ports](https://docs.gitlab.com/omnibus/package-information/defaults.html#consul)
+- PostgreSQL secondaries connect to the primary database servers [PostgreSQL default port](../package_information/defaults.md)
+- Consul servers and agents connect to each others [Consul default ports](../package_information/defaults.md)
## Setting it up
@@ -183,7 +183,7 @@ Few things to remember about the service itself:
- The service runs as the same system account as the database
- In the package, this is by default `gitlab-psql`
-- If you use a non-default user account for PgBouncer service (by default `pgbouncer`), you need to specify this username.
+- If you use a non-default user account for PgBouncer service (by default `pgbouncer`), you need to specify this username.
- Passwords are stored in the following locations:
- `/etc/gitlab/gitlab.rb`: hashed, and in plain text
- `/var/opt/gitlab/pgbouncer/pg_auth`: hashed
@@ -306,7 +306,7 @@ If you enable Monitoring, it must be enabled on **all** database servers.
#### Enable TLS support for the Patroni API
By default, Patroni's [REST API](https://patroni.readthedocs.io/en/latest/rest_api.html#rest-api) is served over HTTP.
-You have the option to enable TLS and use HTTPS over the same [port](https://docs.gitlab.com/omnibus/package-information/defaults.html#patroni).
+You have the option to enable TLS and use HTTPS over the same [port](../package_information/defaults.md).
To enable TLS, you need PEM-formatted certificate and private key files. Both files must be readable by the PostgreSQL user (`gitlab-psql` by default, or the one set by `postgresql['username']`):
@@ -789,7 +789,7 @@ You do not need any special consideration for Patroni while provisioning your da
Patroni monitors the cluster and handles any failover. When the primary node fails it works with Consul to notify PgBouncer. On failure, Patroni handles the transitioning of the old primary to a replica and rejoins it to the cluster automatically.
-With Patroni, the connection flow is slightly different. Patroni on each node connects to Consul agent to join the cluster. Only after this point it decides if the node is the primary or a replica. Based on this decision, it configures and starts PostgreSQL which it communicates with directly over a Unix socket. This means that if the Consul cluster is not functional or does not have a leader, Patroni and by extension PostgreSQL does not start. Patroni also exposes a REST API which can be accessed via its [default port](https://docs.gitlab.com/omnibus/package-information/defaults.html#patroni)
+With Patroni, the connection flow is slightly different. Patroni on each node connects to Consul agent to join the cluster. Only after this point it decides if the node is the primary or a replica. Based on this decision, it configures and starts PostgreSQL which it communicates with directly over a Unix socket. This means that if the Consul cluster is not functional or does not have a leader, Patroni and by extension PostgreSQL does not start. Patroni also exposes a REST API which can be accessed via its [default port](../package_information/defaults.md)
on each node.
### Check replication status
diff --git a/doc/administration/pseudonymizer.md b/doc/administration/pseudonymizer.md
index 533ebe0ad2f..da3a2e4b34c 100644
--- a/doc/administration/pseudonymizer.md
+++ b/doc/administration/pseudonymizer.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Pseudonymizer **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/5532) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.1.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/5532) in GitLab 11.1.
As the GitLab database hosts sensitive information, using it unfiltered for analytics
implies high security requirements. To help alleviate this constraint, the Pseudonymizer
diff --git a/doc/administration/raketasks/check.md b/doc/administration/raketasks/check.md
index 56bf711f187..7cd7ecc26f7 100644
--- a/doc/administration/raketasks/check.md
+++ b/doc/administration/raketasks/check.md
@@ -204,12 +204,20 @@ See [LDAP Rake Tasks - LDAP Check](ldap.md#check) for details.
The following are solutions to problems you might discover using the Rake tasks documented
above.
-### Dangling commits
+### Dangling objects
-`gitlab:git:fsck` can find dangling commits. To fix them, try
-[enabling housekeeping](../housekeeping.md).
+The `gitlab:git:fsck` task can find dangling objects such as:
-If the issue persists, try triggering `gc` via the
+```plaintext
+dangling blob a12...
+dangling commit b34...
+dangling tag c56...
+dangling tree d78...
+```
+
+To delete them, try [running housekeeping](../housekeeping.md).
+
+If the issue persists, try triggering garbage collection via the
[Rails Console](../operations/rails_console.md#starting-a-rails-console-session):
```ruby
@@ -217,6 +225,13 @@ p = Project.find_by_path("project-name")
Repositories::HousekeepingService.new(p, :gc).execute
```
+If the dangling objects are younger than the 2 weeks default grace period,
+and you don't want to wait until they expire automatically, run:
+
+```ruby
+Repositories::HousekeepingService.new(p, :prune).execute
+```
+
### Delete references to missing remote uploads
`gitlab-rake gitlab:uploads:check VERBOSE=1` detects remote objects that do not exist because they were
@@ -271,7 +286,7 @@ To delete these references to missing local artifacts (`job.log` files):
```ruby
artifacts_deleted = 0
- ::Ci::JobArtifact.all.each do |artifact| ### Iterate artifacts
+ ::Ci::JobArtifact.find_each do |artifact| ### Iterate artifacts
# next if artifact.file.filename != "job.log" ### Uncomment if only `job.log` files' references are to be processed
next if artifact.file.exists? ### Skip if the file reference is valid
artifacts_deleted += 1
diff --git a/doc/administration/raketasks/github_import.md b/doc/administration/raketasks/github_import.md
index 0338732e886..f29e2a6c7f6 100644
--- a/doc/administration/raketasks/github_import.md
+++ b/doc/administration/raketasks/github_import.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# GitHub import **(FREE SELF)**
-> [Introduced]( https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10308) in GitLab 9.1.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10308) in GitLab 9.1.
To retrieve and import GitHub repositories, you need a [GitHub personal access token](https://github.com/settings/tokens).
A username should be passed as the second argument to the Rake task,
diff --git a/doc/administration/raketasks/ldap.md b/doc/administration/raketasks/ldap.md
index d7a37d1df3a..585d254e41d 100644
--- a/doc/administration/raketasks/ldap.md
+++ b/doc/administration/raketasks/ldap.md
@@ -44,7 +44,7 @@ waiting for the next scheduled group sync to be run.
NOTE:
If you'd like to change the frequency at which a group sync is performed,
-[adjust the cron schedule](../auth/ldap/index.md#adjusting-ldap-group-sync-schedule)
+[adjust the cron schedule](../auth/ldap/index.md#adjust-ldap-group-sync-schedule)
instead.
**Omnibus Installation**
@@ -151,7 +151,8 @@ sudo gitlab-rake gitlab:ldap:rename_provider[old_provider,new_provider] force=ye
## Secrets
-GitLab can use [LDAP configuration secrets](../auth/ldap/index.md#using-encrypted-credentials) to read from an encrypted file. The following Rake tasks are provided for updating the contents of the encrypted file.
+GitLab can use [LDAP configuration secrets](../auth/ldap/index.md#use-encrypted-credentials) to read from an encrypted file.
+The following Rake tasks are provided for updating the contents of the encrypted file.
### Show secret
diff --git a/doc/administration/raketasks/praefect.md b/doc/administration/raketasks/praefect.md
index 5fe0546999b..d2fd4943c68 100644
--- a/doc/administration/raketasks/praefect.md
+++ b/doc/administration/raketasks/praefect.md
@@ -7,7 +7,7 @@ type: reference
# Praefect Rake tasks **(FREE SELF)**
-> [Introduced]( https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28369) in GitLab 12.10.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28369) in GitLab 12.10.
Rake tasks are available for projects that have been created on Praefect storage. See the
[Praefect documentation](../gitaly/praefect.md) for information on configuring Praefect.
diff --git a/doc/administration/raketasks/project_import_export.md b/doc/administration/raketasks/project_import_export.md
index 80321d75d66..e0ca7bfdeaf 100644
--- a/doc/administration/raketasks/project_import_export.md
+++ b/doc/administration/raketasks/project_import_export.md
@@ -52,7 +52,7 @@ Note the following:
compatible as described in the [Version history](../../user/project/settings/import_export.md#version-history).
- The project import option must be enabled:
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
+ 1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > General**.
1. Expand **Visibility and access controls**.
1. Under **Import sources**, check the "Project export enabled" option.
diff --git a/doc/administration/raketasks/storage.md b/doc/administration/raketasks/storage.md
index cee63a6cae5..017565e1b39 100644
--- a/doc/administration/raketasks/storage.md
+++ b/doc/administration/raketasks/storage.md
@@ -109,7 +109,7 @@ sudo gitlab-rake gitlab:storage:migrate_to_hashed ID_FROM=50 ID_TO=100
To monitor the progress in GitLab:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
1. Watch how long the `hashed_storage:hashed_storage_project_migrate` queue
will take to finish. After it reaches zero, you can confirm every project
diff --git a/doc/administration/redis/replication_and_failover_external.md b/doc/administration/redis/replication_and_failover_external.md
index 234b1aa7fb9..c19e42a5f14 100644
--- a/doc/administration/redis/replication_and_failover_external.md
+++ b/doc/administration/redis/replication_and_failover_external.md
@@ -349,7 +349,7 @@ or a failover promotes a different **Primary** node.
```yaml
production:
- url: redis://:redi-password-goes-here@gitlab-redis/
+ url: redis://:redis-password-goes-here@gitlab-redis/
sentinels:
-
host: 10.0.0.1
diff --git a/doc/administration/redis/troubleshooting.md b/doc/administration/redis/troubleshooting.md
index 0c1046ca22d..6ab3d55e06a 100644
--- a/doc/administration/redis/troubleshooting.md
+++ b/doc/administration/redis/troubleshooting.md
@@ -73,7 +73,7 @@ there may be something wrong with your configuration files or it can be related
to [this issue](https://github.com/redis/redis-rb/issues/531).
You must make sure you are defining the same value in `redis['master_name']`
-and `redis['master_pasword']` as you defined for your sentinel node.
+and `redis['master_password']` as you defined for your sentinel node.
The way the Redis connector `redis-rb` works with sentinel is a bit
non-intuitive. We try to hide the complexity in omnibus, but it still requires
diff --git a/doc/administration/reference_architectures/10k_users.md b/doc/administration/reference_architectures/10k_users.md
index f9397e6dbca..0fd597e6a2d 100644
--- a/doc/administration/reference_architectures/10k_users.md
+++ b/doc/administration/reference_architectures/10k_users.md
@@ -1550,7 +1550,7 @@ To configure the Praefect nodes, on each one:
# Configure the Consul agent
consul['enable'] = true
## Enable service discovery for Prometheus
- consul['monitoring_service_discovery'] = true
+ consul['monitoring_service_discovery'] = true
# START user configuration
# Please set the real values as explained in Required Information section
@@ -2390,7 +2390,7 @@ The following tables and diagram detail the hybrid environment using the same fo
as the normal environment above.
First are the components that run in Kubernetes. The recommendation at this time is to
-use Google Cloud’s Kubernetes Engine (GKE) and associated machine types, but the memory
+use Google Cloud's Kubernetes Engine (GKE) and associated machine types, but the memory
and CPU requirements should translate to most other providers. We hope to update this in the
future with further specific cloud provider details.
diff --git a/doc/administration/reference_architectures/1k_users.md b/doc/administration/reference_architectures/1k_users.md
index 18e34711953..ea40e150e58 100644
--- a/doc/administration/reference_architectures/1k_users.md
+++ b/doc/administration/reference_architectures/1k_users.md
@@ -13,7 +13,7 @@ full list of reference architectures, see
If you need to serve up to 1,000 users and you don't have strict availability
requirements, a single-node solution with
[frequent backups](index.md#automated-backups) is appropriate for
-many organizations .
+many organizations.
> - **Supported users (approximate):** 1,000
> - **High Availability:** No. For a highly-available environment, you can
diff --git a/doc/administration/reference_architectures/25k_users.md b/doc/administration/reference_architectures/25k_users.md
index 65d59422da8..f500434d75b 100644
--- a/doc/administration/reference_architectures/25k_users.md
+++ b/doc/administration/reference_architectures/25k_users.md
@@ -2402,7 +2402,7 @@ The following tables and diagram detail the hybrid environment using the same fo
as the normal environment above.
First are the components that run in Kubernetes. The recommendation at this time is to
-use Google Cloud’s Kubernetes Engine (GKE) and associated machine types, but the memory
+use Google Cloud's Kubernetes Engine (GKE) and associated machine types, but the memory
and CPU requirements should translate to most other providers. We hope to update this in the
future with further specific cloud provider details.
diff --git a/doc/administration/reference_architectures/2k_users.md b/doc/administration/reference_architectures/2k_users.md
index 0af4dbc8a7f..99dd29c3a83 100644
--- a/doc/administration/reference_architectures/2k_users.md
+++ b/doc/administration/reference_architectures/2k_users.md
@@ -995,7 +995,7 @@ The following tables and diagram detail the hybrid environment using the same fo
as the normal environment above.
First are the components that run in Kubernetes. The recommendation at this time is to
-use Google Cloud’s Kubernetes Engine (GKE) and associated machine types, but the memory
+use Google Cloud's Kubernetes Engine (GKE) and associated machine types, but the memory
and CPU requirements should translate to most other providers. We hope to update this in the
future with further specific cloud provider details.
diff --git a/doc/administration/reference_architectures/3k_users.md b/doc/administration/reference_architectures/3k_users.md
index f4ae01c7442..da36968f053 100644
--- a/doc/administration/reference_architectures/3k_users.md
+++ b/doc/administration/reference_architectures/3k_users.md
@@ -2124,7 +2124,7 @@ The following tables and diagram detail the hybrid environment using the same fo
as the normal environment above.
First are the components that run in Kubernetes. The recommendation at this time is to
-use Google Cloud’s Kubernetes Engine (GKE) and associated machine types, but the memory
+use Google Cloud's Kubernetes Engine (GKE) and associated machine types, but the memory
and CPU requirements should translate to most other providers. We hope to update this in the
future with further specific cloud provider details.
diff --git a/doc/administration/reference_architectures/50k_users.md b/doc/administration/reference_architectures/50k_users.md
index b262545b27d..b071b48cbd9 100644
--- a/doc/administration/reference_architectures/50k_users.md
+++ b/doc/administration/reference_architectures/50k_users.md
@@ -2413,7 +2413,7 @@ The following tables and diagram detail the hybrid environment using the same fo
as the normal environment above.
First are the components that run in Kubernetes. The recommendation at this time is to
-use Google Cloud’s Kubernetes Engine (GKE) and associated machine types, but the memory
+use Google Cloud's Kubernetes Engine (GKE) and associated machine types, but the memory
and CPU requirements should translate to most other providers. We hope to update this in the
future with further specific cloud provider details.
diff --git a/doc/administration/reference_architectures/5k_users.md b/doc/administration/reference_architectures/5k_users.md
index 666d18a66fc..4dfe628039a 100644
--- a/doc/administration/reference_architectures/5k_users.md
+++ b/doc/administration/reference_architectures/5k_users.md
@@ -2094,7 +2094,7 @@ The following tables and diagram detail the hybrid environment using the same fo
as the normal environment above.
First are the components that run in Kubernetes. The recommendation at this time is to
-use Google Cloud’s Kubernetes Engine (GKE) and associated machine types, but the memory
+use Google Cloud's Kubernetes Engine (GKE) and associated machine types, but the memory
and CPU requirements should translate to most other providers. We hope to update this in the
future with further specific cloud provider details.
diff --git a/doc/administration/reference_architectures/index.md b/doc/administration/reference_architectures/index.md
index 74d8bf39d03..4d95a61176b 100644
--- a/doc/administration/reference_architectures/index.md
+++ b/doc/administration/reference_architectures/index.md
@@ -139,8 +139,8 @@ to any of the [available reference architectures](#available-reference-architect
> - Level of complexity: **Medium**
> - Required domain knowledge: PostgreSQL, HAProxy, shared storage, distributed systems
-GitLab supports [zero-downtime updates](https://docs.gitlab.com/omnibus/update/#zero-downtime-updates).
-Single GitLab nodes can be updated with only a [few minutes of downtime](https://docs.gitlab.com/omnibus/update/README.html#single-node-deployment).
+GitLab supports [zero-downtime upgrades](../../update/zero_downtime.md).
+Single GitLab nodes can be updated with only a [few minutes of downtime](../../update/zero_downtime.md#single-node-deployment).
To avoid this, we recommend to separate GitLab into several application nodes.
As long as at least one of each component is online and capable of handling the instance's usage load, your team's productivity will not be interrupted during the update.
diff --git a/doc/administration/reference_architectures/troubleshooting.md b/doc/administration/reference_architectures/troubleshooting.md
index 61d9dfea2a2..aabf4809b4a 100644
--- a/doc/administration/reference_architectures/troubleshooting.md
+++ b/doc/administration/reference_architectures/troubleshooting.md
@@ -158,7 +158,7 @@ there may be something wrong with your configuration files or it can be related
to [this issue](https://github.com/redis/redis-rb/issues/531).
You must make sure you are defining the same value in `redis['master_name']`
-and `redis['master_pasword']` as you defined for your sentinel node.
+and `redis['master_password']` as you defined for your sentinel node.
The way the Redis connector `redis-rb` works with sentinel is a bit
non-intuitive. We try to hide the complexity in omnibus, but it still requires
diff --git a/doc/administration/repository_checks.md b/doc/administration/repository_checks.md
index ab203bb7993..0591f5b3c40 100644
--- a/doc/administration/repository_checks.md
+++ b/doc/administration/repository_checks.md
@@ -11,7 +11,7 @@ You can use [`git fsck`](https://git-scm.com/docs/git-fsck) to verify the integr
committed to a repository. GitLab administrators can trigger this check for a project using the
GitLab UI:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Projects**.
1. Select the project to check.
1. In the **Repository check** section, select **Trigger repository check**.
@@ -25,7 +25,7 @@ This setting is off by default, because it can cause many false alarms.
Instead of checking repositories manually, GitLab can be configured to run the checks periodically:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Repository** (`/admin/application_settings/repository`).
1. Expand the **Repository maintenance** section.
1. Enable **Enable repository checks**.
@@ -50,7 +50,7 @@ disk at:
If periodic repository checks cause false alarms, you can clear all repository check states:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Repository** (`/admin/application_settings/repository`).
1. Expand the **Repository maintenance** section.
1. Select **Clear all repository checks**.
diff --git a/doc/administration/repository_storage_paths.md b/doc/administration/repository_storage_paths.md
index f4aed0f6a0f..e7edfb9f338 100644
--- a/doc/administration/repository_storage_paths.md
+++ b/doc/administration/repository_storage_paths.md
@@ -146,7 +146,7 @@ Omnibus stores the repositories in a `repositories` subdirectory of the `git-dat
After you [configure](#configure-repository-storage-paths) multiple repository storage paths, you
can choose where new repositories are stored:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Repository** and expand the **Repository storage**
section.
1. Enter values in the **Storage nodes for new repositories** fields.
diff --git a/doc/administration/repository_storage_types.md b/doc/administration/repository_storage_types.md
index f55bff1bf34..d2bab9a1e04 100644
--- a/doc/administration/repository_storage_types.md
+++ b/doc/administration/repository_storage_types.md
@@ -80,7 +80,7 @@ Administrators can look up a project's hashed path from its name or ID using:
To look up a project's hash path in the Admin Area:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Projects** and select the project.
The **Gitaly relative path** is displayed there and looks similar to:
diff --git a/doc/administration/static_objects_external_storage.md b/doc/administration/static_objects_external_storage.md
index 2f19a2e5058..21949388f19 100644
--- a/doc/administration/static_objects_external_storage.md
+++ b/doc/administration/static_objects_external_storage.md
@@ -16,8 +16,8 @@ storage such as a content delivery network (CDN).
To configure external storage for static objects:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > Repository**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Repository**.
1. Expand the **External storage for repository static objects** section.
1. Enter the base URL and an arbitrary token. When you [set up external storage](#set-up-external-storage),
use a script that sets these values as `ORIGIN_HOSTNAME` and `STORAGE_TOKEN`.
diff --git a/doc/administration/troubleshooting/diagnostics_tools.md b/doc/administration/troubleshooting/diagnostics_tools.md
index fe85b5d5803..53d4810b920 100644
--- a/doc/administration/troubleshooting/diagnostics_tools.md
+++ b/doc/administration/troubleshooting/diagnostics_tools.md
@@ -23,8 +23,3 @@ running on.
[strace-parser](https://gitlab.com/wchandler/strace-parser) is a small tool to analyze
and summarize raw `strace` data.
-
-## Pritaly
-
-[Pritaly](https://gitlab.com/wchandler/pritaly) takes Gitaly logs and colorizes output
-or converts the logs to JSON.
diff --git a/doc/administration/troubleshooting/elasticsearch.md b/doc/administration/troubleshooting/elasticsearch.md
index 79295856da8..cfce3b94554 100644
--- a/doc/administration/troubleshooting/elasticsearch.md
+++ b/doc/administration/troubleshooting/elasticsearch.md
@@ -196,7 +196,7 @@ Troubleshooting search result issues is rather straight forward on Elasticsearch
The first step is to confirm GitLab is using Elasticsearch for the search function.
To do this:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > General**, and then confirm the
integration is enabled.
1. Confirm searches use Elasticsearch by accessing the rails console
diff --git a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
index c55efe78216..491db37d9da 100644
--- a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
+++ b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
@@ -243,7 +243,7 @@ project.update!(repository_read_only: true)
### Transfer project from one namespace to another
```ruby
- p= Project.find_by_full_path('<project_path>')
+p = Project.find_by_full_path('<project_path>')
# To set the owner of the project
current_user= p.creator
@@ -416,9 +416,9 @@ p.create_wiki ### creates the wiki project on the filesystem
### In case of issue boards not loading properly and it's getting time out. We need to call the Issue Rebalancing service to fix this
```ruby
-p=Project.find_by_full_path('PROJECT PATH')
+p = Project.find_by_full_path('PROJECT PATH')
-IssueRebalancingService.new(p.issues.take).execute
+Issues::RelativePositionRebalancingService.new(p.root_namespace.all_projects).execute
```
## Imports / Exports
@@ -596,6 +596,17 @@ curl --silent --header "Private-Token: ********************" \
"https://gitlab.example.com/api/v4/users?per_page=100&active" | jq --compact-output '.[] | [.id,.name,.username]'
```
+### Update Daily Billable & Historical users
+
+```ruby
+# Forces recount of historical (max) users
+::HistoricalDataWorker.new.perform
+
+# Forces recount of daily billable users
+identifier = Analytics::UsageTrends::Measurement.identifiers[:billable_users]
+::Analytics::UsageTrends::CounterJobWorker.new.perform(identifier, User.minimum(:id), User.maximum(:id), Time.zone.now)
+```
+
### Block or Delete Users that have no projects or groups
```ruby
@@ -999,8 +1010,8 @@ This content has been moved to the [Troubleshooting Sidekiq docs](sidekiq.md).
### Get information about LFS objects and associated project
```ruby
-o=LfsObject.find_by(oid: "<oid>")
-p=Project.find(LfsObjectsProject.find_by_lfs_object_id(o.id).project_id)
+o = LfsObject.find_by(oid: "<oid>")
+p = Project.find(LfsObjectsProject.find_by_lfs_object_id(o.id).project_id)
```
You can then delete these records from the database with:
diff --git a/doc/administration/troubleshooting/log_parsing.md b/doc/administration/troubleshooting/log_parsing.md
index 0a73c61ae94..c5443c564f4 100644
--- a/doc/administration/troubleshooting/log_parsing.md
+++ b/doc/administration/troubleshooting/log_parsing.md
@@ -55,6 +55,12 @@ zcat @400000006026b71d1a7af804.s | (head -1; tail -1) | jq '.time'
zcat some_json.log.25.gz | (head -1; tail -1) | jq '.time'
```
+#### Get activity for correlation ID across multiple JSON logs in chronological order
+
+```shell
+grep -hR <correlationID> | jq -c -R 'fromjson?' | jq -C -s 'sort_by(.time)' | less -R
+```
+
### Parsing `production_json.log` and `api_json.log`
#### Find all requests with a 5XX status code
diff --git a/doc/administration/troubleshooting/postgresql.md b/doc/administration/troubleshooting/postgresql.md
index 994c194c6db..3df957bacf9 100644
--- a/doc/administration/troubleshooting/postgresql.md
+++ b/doc/administration/troubleshooting/postgresql.md
@@ -116,7 +116,7 @@ References:
ERROR: deadlock detected
```
-Three applicable timeouts are identified in the issue [#1](https://gitlab.com/gitlab-org/gitlab/-/issues/30528); our recommended settings are as follows:
+Three applicable timeouts are identified in the issue [#30528](https://gitlab.com/gitlab-org/gitlab/-/issues/30528); our recommended settings are as follows:
```ini
deadlock_timeout = 5s
@@ -124,7 +124,7 @@ statement_timeout = 15s
idle_in_transaction_session_timeout = 60s
```
-Quoting from issue [#1](https://gitlab.com/gitlab-org/gitlab/-/issues/30528):
+Quoting from issue [#30528](https://gitlab.com/gitlab-org/gitlab/-/issues/30528):
> "If a deadlock is hit, and we resolve it through aborting the transaction after a short period, then the retry mechanisms we already have will make the deadlocked piece of work try again, and it's unlikely we'll deadlock multiple times in a row."
@@ -146,7 +146,7 @@ PostgresSQL defaults:
- `statement_timeout = 0` (never)
- `idle_in_transaction_session_timeout = 0` (never)
-Comments in issue [#1](https://gitlab.com/gitlab-org/gitlab/-/issues/30528)
+Comments in issue [#30528](https://gitlab.com/gitlab-org/gitlab/-/issues/30528)
indicate that these should both be set to at least a number of minutes for all
Omnibus GitLab installations (so they don't hang indefinitely). However, 15s
for statement_timeout is very short, and will only be effective if the
diff --git a/doc/administration/troubleshooting/tracing_correlation_id.md b/doc/administration/troubleshooting/tracing_correlation_id.md
index 1bb10e72290..3518f52e6f6 100644
--- a/doc/administration/troubleshooting/tracing_correlation_id.md
+++ b/doc/administration/troubleshooting/tracing_correlation_id.md
@@ -27,7 +27,7 @@ activity with the site that you're visiting. See the links below for network mon
documentation for some popular browsers.
- [Network Monitor - Firefox Developer Tools](https://developer.mozilla.org/en-US/docs/Tools/Network_Monitor)
-- [Inspect Network Activity In Chrome DevTools](https://developer.chrome.com/docs/devtools/network)
+- [Inspect Network Activity In Chrome DevTools](https://developer.chrome.com/docs/devtools/network/)
- [Safari Web Development Tools](https://developer.apple.com/safari/tools/)
- [Microsoft Edge Network panel](https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide-chromium/network/)
@@ -127,3 +127,11 @@ some sort of log aggregation software like Loki, ELK, Splunk, or others.
You can use a tool like Ansible or PSSH (parallel SSH) that can execute identical commands across your servers in
parallel, or craft your own solution.
+
+### Viewing the request in the Performance Bar
+
+You can use the [performance bar](../monitoring/performance/performance_bar.md) to view interesting data including calls made to SQL and Gitaly.
+
+To view the data, the correlation ID of the request must match the same session as the user
+viewing the performance bar. For API requests, this means that you must perform the request
+using the session cookie of the signed-in user.
diff --git a/doc/administration/uploads.md b/doc/administration/uploads.md
index 949687cfa0a..15ef024647c 100644
--- a/doc/administration/uploads.md
+++ b/doc/administration/uploads.md
@@ -53,8 +53,8 @@ _The uploads are stored by default in
> **Notes:**
>
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/3867) in [GitLab Premium](https://about.gitlab.com/pricing/) 10.5.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17358) in [GitLab Free](https://about.gitlab.com/pricing/) 10.7.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/3867) in GitLab 10.5.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17358) from GitLab Premium to GitLab Free in 10.7.
> - Since version 11.1, we support direct_upload to S3.
If you don't want to use the local disk where GitLab is installed to store the
diff --git a/doc/administration/whats-new.md b/doc/administration/whats-new.md
index d669d05e9f0..d3768907989 100644
--- a/doc/administration/whats-new.md
+++ b/doc/administration/whats-new.md
@@ -29,7 +29,7 @@ in the first patch release, such as `13.10.1`.
You can configure the What's new variant:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Preferences**, then expand **What's new**.
1. Choose one of the following options:
diff --git a/doc/api/access_requests.md b/doc/api/access_requests.md
index 8ef3e882209..1634184a374 100644
--- a/doc/api/access_requests.md
+++ b/doc/api/access_requests.md
@@ -5,7 +5,7 @@ info: "To determine the technical writer assigned to the Stage/Group associated
type: reference, api
---
-# Group and project access requests API
+# Group and project access requests API **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/18583) in GitLab 8.11.
diff --git a/doc/api/admin_sidekiq_queues.md b/doc/api/admin_sidekiq_queues.md
index d0e310ab548..569dfd4c413 100644
--- a/doc/api/admin_sidekiq_queues.md
+++ b/doc/api/admin_sidekiq_queues.md
@@ -27,15 +27,16 @@ This API endpoint is only available to administrators.
DELETE /admin/sidekiq/queues/:queue_name
```
-| Attribute | Type | Required | Description |
-| --------- | -------------- | -------- | ----------- |
-| `queue_name` | string | yes | The name of the queue to delete jobs from |
-| `user` | string | no | The username of the user who scheduled the jobs |
-| `project` | string | no | The full path of the project where the jobs were scheduled from |
-| `root_namespace` | string | no | The root namespace of the project |
-| `subscription_plan` | string | no | The subscription plan of the root namespace (GitLab.com only) |
-| `caller_id` | string | no | The endpoint or background job that schedule the job (for example: `ProjectsController#create`, `/api/:version/projects/:id`, `PostReceive`) |
-| `feature_category` | string | no | The feature category of the background job (for example: `issue_tracking` or `code_review`) |
+| Attribute | Type | Required | Description |
+|---------------------|--------|----------|----------------------------------------------------------------------------------------------------------------------------------------------|
+| `queue_name` | string | yes | The name of the queue to delete jobs from |
+| `user` | string | no | The username of the user who scheduled the jobs |
+| `project` | string | no | The full path of the project where the jobs were scheduled from |
+| `root_namespace` | string | no | The root namespace of the project |
+| `subscription_plan` | string | no | The subscription plan of the root namespace (GitLab.com only) |
+| `caller_id` | string | no | The endpoint or background job that schedule the job (for example: `ProjectsController#create`, `/api/:version/projects/:id`, `PostReceive`) |
+| `feature_category` | string | no | The feature category of the background job (for example: `issue_tracking` or `code_review`) |
+| `worker_class` | string | no | The class of the background job worker (for example: `PostReceive` or `MergeWorker`) |
At least one attribute, other than `queue_name`, is required.
diff --git a/doc/api/api_resources.md b/doc/api/api_resources.md
index aae76697841..8706b1e7e76 100644
--- a/doc/api/api_resources.md
+++ b/doc/api/api_resources.md
@@ -15,7 +15,7 @@ Available resources for the [GitLab REST API](index.md) can be grouped in the fo
See also:
- [V3 to V4](v3_to_v4.md).
-- Adding [deploy keys for multiple projects](deploy_keys.md#adding-deploy-keys-to-multiple-projects).
+- Adding [deploy keys for multiple projects](deploy_keys.md#add-deploy-keys-to-multiple-projects).
- [API Resources for various templates](#templates-api-resources).
## Project resources
@@ -129,7 +129,7 @@ The following API resources are available outside of project and group contexts
| Resource | Available endpoints |
|:---------------------------------------------------|:------------------------------------------------------------------------|
-| [Instance-level CI/CD variables](instance_level_ci_variables.md) | `/admin/ci/variables` |
+| [Instance-level CI/CD variables](instance_level_ci_variables.md) **(FREE SELF)** | `/admin/ci/variables` |
| [Sidekiq queues administration](admin_sidekiq_queues.md) **(FREE SELF)** | `/admin/sidekiq/queues/:queue_name` |
| [Appearance](appearance.md) **(FREE SELF)** | `/application/appearance` |
| [Applications](applications.md) | `/applications` |
@@ -145,7 +145,7 @@ The following API resources are available outside of project and group contexts
| [Group Activity Analytics](group_activity_analytics.md) | `/analytics/group_activity/{issues_count | merge_requests_count | new_members_count }` |
| [Group repository storage moves](group_repository_storage_moves.md) **(PREMIUM SELF)** | `/group_repository_storage_moves` |
| [Import repository from GitHub](import.md) | `/import/github` |
-| [Instance clusters](instance_clusters.md) | `/admin/clusters` |
+| [Instance clusters](instance_clusters.md) **(FREE SELF)** | `/admin/clusters` |
| [Issues](issues.md) | `/issues` (also available for groups and projects) |
| [Issues Statistics](issues_statistics.md) | `/issues_statistics` (also available for groups and projects) |
| [Jobs](jobs.md) | `/job` |
diff --git a/doc/api/applications.md b/doc/api/applications.md
index 7047dccea88..2b5eff68010 100644
--- a/doc/api/applications.md
+++ b/doc/api/applications.md
@@ -4,7 +4,7 @@ group: Access
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
---
-# Applications API
+# Applications API **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/8160) in GitLab 10.5.
diff --git a/doc/api/avatar.md b/doc/api/avatar.md
index baa670f3e93..200d7524b7f 100644
--- a/doc/api/avatar.md
+++ b/doc/api/avatar.md
@@ -4,7 +4,7 @@ group: Access
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
---
-# Avatar API
+# Avatar API **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/19121) in GitLab 11.0.
diff --git a/doc/api/award_emoji.md b/doc/api/award_emoji.md
index dc3dc9fcaca..61f84dfb812 100644
--- a/doc/api/award_emoji.md
+++ b/doc/api/award_emoji.md
@@ -10,7 +10,7 @@ An [awarded emoji](../user/award_emojis.md) tells a thousand words.
We call GitLab objects on which you can award an emoji "awardables". You can award emojis on the following:
-- [Epics](../user/group/epics/index.md) ([API](epics.md)).
+- [Epics](../user/group/epics/index.md) ([API](epics.md)). **(PREMIUM)**
- [Issues](../user/project/issues/index.md) ([API](issues.md)).
- [Merge requests](../user/project/merge_requests/index.md) ([API](merge_requests.md)).
- [Snippets](../user/snippets.md) ([API](snippets.md)).
diff --git a/doc/api/boards.md b/doc/api/boards.md
index 3288aefb1cf..ab9bd4ea3f1 100644
--- a/doc/api/boards.md
+++ b/doc/api/boards.md
@@ -427,7 +427,7 @@ POST /projects/:id/boards/:board_id/lists
NOTE:
Label, assignee and milestone arguments are mutually exclusive,
that is, only one of them are accepted in a request.
-Check the [Issue Board documentation](../user/project/issue_board.md)
+Check the [issue board documentation](../user/project/issue_board.md)
for more information regarding the required license for each list type.
```shell
diff --git a/doc/api/branches.md b/doc/api/branches.md
index 15d1b6c2a18..7b9354f3264 100644
--- a/doc/api/branches.md
+++ b/doc/api/branches.md
@@ -47,7 +47,7 @@ Example response:
"developers_can_push": false,
"developers_can_merge": false,
"can_push": true,
- "web_url": "http://gitlab.example.com/my-group/my-project/-/tree/master",
+ "web_url": "https://gitlab.example.com/my-group/my-project/-/tree/master",
"commit": {
"author_email": "john@example.com",
"author_name": "John Smith",
@@ -103,7 +103,7 @@ Example response:
"developers_can_push": false,
"developers_can_merge": false,
"can_push": true,
- "web_url": "http://gitlab.example.com/my-group/my-project/-/tree/master",
+ "web_url": "https://gitlab.example.com/my-group/my-project/-/tree/master",
"commit": {
"author_email": "john@example.com",
"author_name": "John Smith",
@@ -180,7 +180,7 @@ Example response:
"developers_can_push": false,
"developers_can_merge": false,
"can_push": true,
- "web_url": "http://gitlab.example.com/my-group/my-project/-/tree/newbranch"
+ "web_url": "https://gitlab.example.com/my-group/my-project/-/tree/newbranch"
}
```
diff --git a/doc/api/broadcast_messages.md b/doc/api/broadcast_messages.md
index b98373b5a58..5aca0667f31 100644
--- a/doc/api/broadcast_messages.md
+++ b/doc/api/broadcast_messages.md
@@ -13,7 +13,7 @@ As of GitLab 12.8, GET requests do not require authentication. All other broadca
- Guests result in `401 Unauthorized`.
- Regular users result in `403 Forbidden`.
-## Get all broadcast messages
+## Get all broadcast messages **(FREE)**
List all broadcast messages.
@@ -46,7 +46,7 @@ Example response:
]
```
-## Get a specific broadcast message
+## Get a specific broadcast message **(FREE)**
Get a specific broadcast message.
diff --git a/doc/api/bulk_imports.md b/doc/api/bulk_imports.md
index 2325f25e789..2b71c83b224 100644
--- a/doc/api/bulk_imports.md
+++ b/doc/api/bulk_imports.md
@@ -4,7 +4,7 @@ group: Import
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
---
-# GitLab Migrations (Bulk Imports) API
+# GitLab Migrations (Bulk Imports) API **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64335) in GitLab 14.1.
diff --git a/doc/api/commits.md b/doc/api/commits.md
index e164532e0eb..e91da23596f 100644
--- a/doc/api/commits.md
+++ b/doc/api/commits.md
@@ -289,11 +289,11 @@ Example response:
```
-## Cherry pick a commit
+## Cherry-pick a commit
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/8047) in GitLab 8.15.
-Cherry picks a commit to a given branch.
+Cherry-picks a commit to a given branch.
```plaintext
POST /projects/:id/repository/commits/:sha/cherry_pick
@@ -381,7 +381,7 @@ Parameters:
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) |
| `sha` | string | yes | Commit SHA to revert |
| `branch` | string | yes | Target branch name |
-| `dry_run` | boolean | no | Does not commit any changes. Default is false. [Introduced in GitLab 13.3](https://gitlab.com/gitlab-org/gitlab/-/issues/231032) |
+| `dry_run` | boolean | no | Does not commit any changes. Default is false. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/231032) in GitLab 13.3 |
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "branch=master" \
diff --git a/doc/api/container_registry.md b/doc/api/container_registry.md
index 12bdeebca1d..2885cc7d803 100644
--- a/doc/api/container_registry.md
+++ b/doc/api/container_registry.md
@@ -4,7 +4,7 @@ group: Package
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
---
-# Container Registry API
+# Container Registry API **(FREE)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/55978) in GitLab 11.8.
> - The use of `CI_JOB_TOKEN` scoped to the current project was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49750) in GitLab 13.12.
@@ -32,6 +32,8 @@ Feature.disable(:ci_job_token_scope)
## Change the visibility of the Container Registry
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18792) in GitLab 14.2.
+
This controls who can view the Container Registry.
```plaintext
diff --git a/doc/api/custom_attributes.md b/doc/api/custom_attributes.md
index 9908c58de35..94f924c051d 100644
--- a/doc/api/custom_attributes.md
+++ b/doc/api/custom_attributes.md
@@ -4,7 +4,7 @@ group: Integrations
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
---
-# Custom Attributes API
+# Custom Attributes API **(FREE SELF)**
Every API call to custom attributes must be authenticated as administrator.
diff --git a/doc/api/dependency_proxy.md b/doc/api/dependency_proxy.md
index e9ddc1e9df9..535c6607cad 100644
--- a/doc/api/dependency_proxy.md
+++ b/doc/api/dependency_proxy.md
@@ -4,19 +4,16 @@ group: Package
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
---
-# Dependency Proxy API
+# Dependency Proxy API **(FREE)**
## Purge the dependency proxy for a group
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11631) in GitLab 12.10.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/273655) to [GitLab Free](https://about.gitlab.com/pricing/) in GitLab 13.6.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/273655) from GitLab Premium to GitLab Free in 13.6.
Deletes the cached manifests and blobs for a group. This endpoint requires the [Owner role](../user/permissions.md)
for the group.
-WARNING:
-[A bug exists](https://gitlab.com/gitlab-org/gitlab/-/issues/277161) for this API.
-
```plaintext
DELETE /groups/:id/dependency_proxy/cache
```
diff --git a/doc/api/deploy_keys.md b/doc/api/deploy_keys.md
index 3d6d680e3e4..bb719b5bc79 100644
--- a/doc/api/deploy_keys.md
+++ b/doc/api/deploy_keys.md
@@ -4,11 +4,12 @@ group: Release
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
---
-# Deploy keys API
+# Deploy keys API **(FREE)**
-## List all deploy keys
+## List all deploy keys **(FREE SELF)**
-Get a list of all deploy keys across all projects of the GitLab instance. This endpoint requires administrator access and is not available on GitLab.com.
+Get a list of all deploy keys across all projects of the GitLab instance. This
+endpoint requires an administrator role and is not available on GitLab.com.
```plaintext
GET /deploy_keys
@@ -74,7 +75,7 @@ Example response:
]
```
-## Single deploy key
+## Get a single deploy key
Get a single key.
@@ -213,10 +214,10 @@ Example response:
}
```
-## Adding deploy keys to multiple projects
+## Add deploy keys to multiple projects
-If you want to easily add the same deploy key to multiple projects in the same
-group, this can be achieved quite easily with the API.
+If you want to add the same deploy key to multiple projects in the same
+group, this can be achieved with the API.
First, find the ID of the projects you're interested in, by either listing all
projects:
diff --git a/doc/api/deploy_tokens.md b/doc/api/deploy_tokens.md
index 6ed8f76583f..3de7ff4ac44 100644
--- a/doc/api/deploy_tokens.md
+++ b/doc/api/deploy_tokens.md
@@ -4,9 +4,9 @@ group: Release
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
---
-# Deploy Tokens API
+# Deploy Tokens API **(FREE)**
-## List all deploy tokens
+## List all deploy tokens **(FREE SELF)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/21811) in GitLab 12.9.
diff --git a/doc/api/deployments.md b/doc/api/deployments.md
index 3ed431cf63d..5f710271d60 100644
--- a/doc/api/deployments.md
+++ b/doc/api/deployments.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: concepts, howto
---
-# Deployments API
+# Deployments API **(FREE)**
## List project deployments
diff --git a/doc/api/discussions.md b/doc/api/discussions.md
index 1c22f261e57..18b74e1450f 100644
--- a/doc/api/discussions.md
+++ b/doc/api/discussions.md
@@ -15,7 +15,9 @@ Discussions are a set of related notes on:
- Merge requests
- Commits
-This includes system notes, which are notes about changes to the object (for example, when a milestone changes, a corresponding system note is added). Label notes are not part of this API, but recorded as separate events in [resource label events](resource_label_events.md).
+This includes system notes, which are notes about changes to the object (for example,
+when a milestone changes, a corresponding system note is added). Label notes are
+not part of this API, but recorded as separate events in [resource label events](resource_label_events.md).
## Discussions pagination
@@ -118,7 +120,8 @@ GET /projects/:id/issues/:issue_iid/discussions
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/11/discussions"
+curl --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/issues/11/discussions"
```
### Get single issue discussion item
@@ -138,7 +141,8 @@ Parameters:
| `discussion_id` | integer | yes | The ID of a discussion item |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7"
+curl --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/issues/11/discussions/<discussion_id>"
```
### Create new issue thread
@@ -159,7 +163,8 @@ Parameters:
| `created_at` | string | no | Date time string, ISO 8601 formatted, such as `2016-03-11T03:45:40Z` (requires administrator or project/group owner rights) |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/11/discussions?body=comment"
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/issues/11/discussions?body=comment"
```
### Add note to existing issue thread
@@ -185,7 +190,8 @@ Parameters:
| `created_at` | string | no | Date time string, ISO 8601 formatted, such as `2016-03-11T03:45:40Z` (requires administrator or project/group owner rights) |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes?body=comment"
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/issues/11/discussions/<discussion_id>/notes?body=comment"
```
### Modify existing issue thread note
@@ -207,7 +213,8 @@ Parameters:
| `body` | string | yes | The content of the note/reply |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes/1108?body=comment"
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/issues/11/discussions/<discussion_id>/notes/1108?body=comment"
```
### Delete an issue thread note
@@ -228,7 +235,8 @@ Parameters:
| `note_id` | integer | yes | The ID of a discussion note |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/11/discussions/636"
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/issues/11/discussions/636"
```
## Snippets
@@ -326,7 +334,8 @@ GET /projects/:id/snippets/:snippet_id/discussions
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/snippets/11/discussions"
+curl --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/snippets/11/discussions"
```
### Get single snippet discussion item
@@ -346,7 +355,8 @@ Parameters:
| `discussion_id` | integer | yes | The ID of a discussion item |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/snippets/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7"
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/snippets/11/discussions/<discussion_id>"
```
### Create new snippet thread
@@ -368,7 +378,8 @@ Parameters:
| `created_at` | string | no | Date time string, ISO 8601 formatted, such as `2016-03-11T03:45:40Z` (requires administrator or project/group owner rights) |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/snippets/11/discussions?body=comment"
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/snippets/11/discussions?body=comment"
```
### Add note to existing snippet thread
@@ -391,7 +402,8 @@ Parameters:
| `created_at` | string | no | Date time string, ISO 8601 formatted, such as `2016-03-11T03:45:40Z` (requires administrator or project/group owner rights) |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/snippets/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes?body=comment"
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/snippets/11/discussions/<discussion_id>/notes?body=comment"
```
### Modify existing snippet thread note
@@ -413,7 +425,8 @@ Parameters:
| `body` | string | yes | The content of the note/reply |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/snippets/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes/1108?body=comment"
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/snippets/11/discussions/<discussion_id>/notes/1108?body=comment"
```
### Delete a snippet thread note
@@ -434,7 +447,8 @@ Parameters:
| `note_id` | integer | yes | The ID of a discussion note |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/snippets/11/discussions/636"
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/snippets/11/discussions/636"
```
## Epics **(ULTIMATE)**
@@ -533,7 +547,8 @@ GET /groups/:id/epics/:epic_id/discussions
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/epics/11/discussions"
+curl --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/groups/5/epics/11/discussions"
```
### Get single epic discussion item
@@ -553,7 +568,8 @@ Parameters:
| `discussion_id` | integer | yes | The ID of a discussion item |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/epics/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7"
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/groups/5/epics/11/discussions/<discussion_id>"
```
### Create new epic thread
@@ -575,7 +591,8 @@ Parameters:
| `created_at` | string | no | Date time string, ISO 8601 formatted, such as `2016-03-11T03:45:40Z` (requires administrator or project/group owner rights) |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/epics/11/discussions?body=comment"
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/groups/5/epics/11/discussions?body=comment"
```
### Add note to existing epic thread
@@ -599,7 +616,8 @@ Parameters:
| `created_at` | string | no | Date time string, ISO 8601 formatted, such as `2016-03-11T03:45:40Z` (requires administrator or project/group owner rights) |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/epics/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes?body=comment"
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/groups/5/epics/11/discussions/<discussion_id>/notes?body=comment"
```
### Modify existing epic thread note
@@ -621,7 +639,8 @@ Parameters:
| `body` | string | yes | The content of note/reply |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/epics/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes/1108?body=comment"
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/groups/5/epics/11/discussions/<discussion_id>/notes/1108?body=comment"
```
### Delete an epic thread note
@@ -642,7 +661,8 @@ Parameters:
| `note_id` | integer | yes | The ID of a thread note |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/epics/11/discussions/636"
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/groups/5/epics/11/discussions/636"
```
## Merge requests
@@ -805,7 +825,8 @@ Diff comments also contain position:
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions"
+curl --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions"
```
### Get single merge request discussion item
@@ -825,7 +846,8 @@ Parameters:
| `discussion_id` | integer | yes | The ID of a discussion item |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7
+curl --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions/<discussion_id>"
```
### Create new merge request thread
@@ -866,57 +888,67 @@ Parameters for all comments:
#### Create a new thread on the overview page
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions?body=comment"
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions?body=comment"
```
#### Create a new thread in the merge request diff
-- Both `position[old_path]` and `position[new_path]` are required and must refer to the file path before and after the change.
-- To create a thread on an added line (highlighted in green in the merge request diff), use `position[new_line]` and don't include `position[old_line]`.
-- To create a thread on a removed line (highlighted in red in the merge request diff), use `position[old_line]` and don't include `position[new_line]`.
-- To create a thread on an unchanged line, include both `position[new_line]` and `position[old_line]` for the line. These positions might not be the same if earlier changes in the file changed the line number. This is a bug that we plan to fix in [GraphQL `createDiffNote` forces clients to compute redundant information (#325161)](https://gitlab.com/gitlab-org/gitlab/-/issues/325161).
-- If you specify incorrect `base`/`head`/`start` `SHA` parameters, you might run into the following bug: [Merge request comments receive "download" link instead of inline code (#296829)](https://gitlab.com/gitlab-org/gitlab/-/issues/296829).
+- Both `position[old_path]` and `position[new_path]` are required and must refer
+ to the file path before and after the change.
+- To create a thread on an added line (highlighted in green in the merge request diff),
+ use `position[new_line]` and don't include `position[old_line]`.
+- To create a thread on a removed line (highlighted in red in the merge request diff),
+ use `position[old_line]` and don't include `position[new_line]`.
+- To create a thread on an unchanged line, include both `position[new_line]` and
+ `position[old_line]` for the line. These positions might not be the same if earlier
+ changes in the file changed the line number. This is a bug that we plan to fix in
+ [GraphQL `createDiffNote` forces clients to compute redundant information (#325161)](https://gitlab.com/gitlab-org/gitlab/-/issues/325161).
+- If you specify incorrect `base`/`head`/`start` `SHA` parameters, you might run
+ into the following bug:
+ [Merge request comments receive "download" link instead of inline code (#296829)](https://gitlab.com/gitlab-org/gitlab/-/issues/296829).
To create a new thread:
1. [Get the latest merge request version](merge_requests.md#get-mr-diff-versions):
- ```shell
- curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/versions"
- ````
+ ```shell
+ curl --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/versions"
+ ```
1. Note the details of the latest version, which is listed first in the response array.
- ```json
- [
- {
- "id": 164560414,
- "head_commit_sha": "f9ce7e16e56c162edbc9e480108041cf6b0291fe",
- "base_commit_sha": "5e6dffa282c5129aa67cd227a0429be21bfdaf80",
- "start_commit_sha": "5e6dffa282c5129aa67cd227a0429be21bfdaf80",
- "created_at": "2021-03-30T09:18:27.351Z",
- "merge_request_id": 93958054,
- "state": "collected",
- "real_size": "2"
- },
- "previous versions are here"
- ]
- ```
+ ```json
+ [
+ {
+ "id": 164560414,
+ "head_commit_sha": "f9ce7e16e56c162edbc9e480108041cf6b0291fe",
+ "base_commit_sha": "5e6dffa282c5129aa67cd227a0429be21bfdaf80",
+ "start_commit_sha": "5e6dffa282c5129aa67cd227a0429be21bfdaf80",
+ "created_at": "2021-03-30T09:18:27.351Z",
+ "merge_request_id": 93958054,
+ "state": "collected",
+ "real_size": "2"
+ },
+ "previous versions are here"
+ ]
+ ```
1. Create a new diff thread. This example creates a thread on an added line:
- ```shell
- curl --request POST --header "PRIVATE-TOKEN: <your_access_token>"\
- --form 'position[position_type]=text'\
- --form 'position[base_sha]=<use base_commit_sha from the versions response>'\
- --form 'position[head_sha]=<use head_commit_sha from the versions response>'\
- --form 'position[start_sha]=<use start_commit_sha from the versions response>'\
- --form 'position[new_path]=file.js'\
- --form 'position[old_path]=file.js'\
- --form 'position[new_line]=18'\
- --form 'body=test comment body'\
- "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions"
- ```
+ ```shell
+ curl --request POST --header "PRIVATE-TOKEN: <your_access_token>"\
+ --form 'position[position_type]=text'\
+ --form 'position[base_sha]=<use base_commit_sha from the versions response>'\
+ --form 'position[head_sha]=<use head_commit_sha from the versions response>'\
+ --form 'position[start_sha]=<use start_commit_sha from the versions response>'\
+ --form 'position[new_path]=file.js'\
+ --form 'position[old_path]=file.js'\
+ --form 'position[new_line]=18'\
+ --form 'body=test comment body'\
+ "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions"
+ ```
#### Parameters for multiline comments
@@ -933,14 +965,31 @@ Parameters for multiline comments only:
#### Line code
-A line code is of the form `<SHA>_<old>_<new>`:
+A line code is of the form `<SHA>_<old>_<new>`, like this: `adc83b19e793491b1c6ea0fd8b46cd9f32e292fc_5_5`
- `<SHA>` is the SHA1 hash of the filename.
- `<old>` is the line number before the change.
- `<new>` is the line number after the change.
-For example, when commenting on an added line number 5, the line code
-looks like `adc83b19e793491b1c6ea0fd8b46cd9f32e292fc_5_5`.
+For example, if a commit (`<COMMIT_ID>`) deletes line 463 in the README, you can comment
+on the deletion by referencing line 463 in the *old* file:
+
+```shell
+curl --request POST --header "PRIVATE-TOKEN: [ACCESS_TOKEN]"\
+ --form "note=Very clever to remove this unnecessary line!"\
+ --form "path=README" --form "line=463" --form "line_type=old"\
+ "https://gitlab.com/api/v4/projects/47/repository/commits/<COMMIT_ID>/comments"
+```
+
+If a commit (`<COMMIT_ID>`) adds line 157 to `hello.rb`, you can comment on the
+addition by referencing line 157 in the *new* file:
+
+```shell
+curl --request POST --header "PRIVATE-TOKEN: [ACCESS_TOKEN]"\
+ --form "note=This is brilliant!" --form "path=hello.rb"\
+ --form "line=157" --form "line_type=old"\
+ "https://gitlab.com/api/v4/projects/47/repository/commits/<COMMIT_ID>/comments"
+```
### Resolve a merge request thread
@@ -960,7 +1009,8 @@ Parameters:
| `resolved` | boolean | yes | Resolve/unresolve the discussion |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7?resolved=true"
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions/<discussion_id>?resolved=true"
```
### Add note to existing merge request thread
@@ -984,7 +1034,8 @@ Parameters:
| `created_at` | string | no | Date time string, ISO 8601 formatted, such as `2016-03-11T03:45:40Z` (requires administrator or project/group owner rights) |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes?body=comment"
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions/<discussion_id>/notes?body=comment"
```
### Modify an existing merge request thread note
@@ -1007,13 +1058,15 @@ Parameters:
| `resolved` | boolean | no | Resolve/unresolve the note (exactly one of `body` or `resolved` must be set |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes/1108?body=comment"
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions/<discussion_id>/notes/1108?body=comment"
```
Resolving a note:
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes/1108?resolved=true"
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions/<discussion_id>/notes/1108?resolved=true"
```
### Delete a merge request thread note
@@ -1034,7 +1087,8 @@ Parameters:
| `note_id` | integer | yes | The ID of a thread note |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions/636"
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions/636"
```
## Commits
@@ -1177,7 +1231,8 @@ Diff comments contain also position:
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/commits/11/discussions"
+curl --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/commits/11/discussions"
```
### Get single commit discussion item
@@ -1197,7 +1252,8 @@ Parameters:
| `discussion_id` | integer | yes | The ID of a discussion item |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/commits/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7"
+curl --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/commits/11/discussions/<discussion_id>"
```
### Create new commit thread
@@ -1232,7 +1288,8 @@ Parameters:
| `position[y]` | integer | no | Y coordinate (for `image` diff notes) |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/commits/11/discussions?body=comment"
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/commits/11/discussions?body=comment"
```
The rules for creating the API request are the same as when
@@ -1259,7 +1316,8 @@ Parameters:
| `created_at` | string | no | Date time string, ISO 8601 formatted, such `2016-03-11T03:45:40Z` (requires administrator or project/group owner rights) |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/commits/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes?body=comment
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/commits/11/discussions/<discussion_id>/notes?body=comment
```
### Modify an existing commit thread note
@@ -1281,13 +1339,15 @@ Parameters:
| `body` | string | no | The content of a note |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/commits/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes/1108?body=comment"
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/commits/11/discussions/<discussion_id>/notes/1108?body=comment"
```
Resolving a note:
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/commits/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes/1108?resolved=true"
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/commits/11/discussions/<discussion_id>/notes/1108?resolved=true"
```
### Delete a commit thread note
@@ -1308,5 +1368,6 @@ Parameters:
| `note_id` | integer | yes | The ID of a thread note |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/commits/11/discussions/636"
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>"\
+ "https://gitlab.example.com/api/v4/projects/5/commits/11/discussions/636"
```
diff --git a/doc/api/dora/metrics.md b/doc/api/dora/metrics.md
index 38f1f50839e..8c82446db2e 100644
--- a/doc/api/dora/metrics.md
+++ b/doc/api/dora/metrics.md
@@ -7,7 +7,7 @@ type: reference, api
# DevOps Research and Assessment (DORA) key metrics API **(ULTIMATE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/279039) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.10.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/279039) in GitLab 13.10.
> - The legacy key/value pair `{ "<date>" => "<value>" }` was removed from the payload in GitLab 14.0.
All methods require [reporter permissions and above](../../user/permissions.md).
@@ -52,7 +52,7 @@ Example response:
## Get group-level DORA metrics
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/279039) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.10.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/279039) in GitLab 13.10.
Get group-level DORA metrics.
diff --git a/doc/api/dora4_project_analytics.md b/doc/api/dora4_project_analytics.md
index efea9723ac4..5a6e1576a3d 100644
--- a/doc/api/dora4_project_analytics.md
+++ b/doc/api/dora4_project_analytics.md
@@ -7,7 +7,7 @@ type: reference, api
# DORA4 Analytics Project API **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/279039) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/279039) in GitLab 13.7.
WARNING:
These endpoints are deprecated and will be removed in GitLab 14.0. Use the [DORA metrics API](dora/metrics.md) instead.
diff --git a/doc/api/environments.md b/doc/api/environments.md
index aa3697c54ac..5187ac7c1b2 100644
--- a/doc/api/environments.md
+++ b/doc/api/environments.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: concepts, howto
---
-# Environments API
+# Environments API **(FREE)**
## List environments
@@ -194,7 +194,7 @@ PUT /projects/:id/environments/:environments_id
| --------------- | ------- | --------------------------------- | ------------------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
| `environment_id` | integer | yes | The ID of the environment |
-| `name` | string | no | The new name of the environment |
+| `name` | string | no | [Deprecated and will be removed in GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/338897) |
| `external_url` | string | no | The new `external_url` |
```shell
diff --git a/doc/api/epic_links.md b/doc/api/epic_links.md
index 5d8a92d0263..d87b44f43a7 100644
--- a/doc/api/epic_links.md
+++ b/doc/api/epic_links.md
@@ -15,7 +15,7 @@ Every API call to `epic_links` must be authenticated.
If a user is not a member of a private group, a `GET` request on that
group results in a `404` status code.
-Multi-level Epics are available only in GitLab [Ultimate](https://about.gitlab.com/pricing/).
+Multi-level Epics are available only in [GitLab Ultimate](https://about.gitlab.com/pricing/).
If the Multi-level Epics feature is not available, a `403` status code is returned.
## List epics related to a given epic
diff --git a/doc/api/error_tracking.md b/doc/api/error_tracking.md
index 0fbb30ef364..1abe5522840 100644
--- a/doc/api/error_tracking.md
+++ b/doc/api/error_tracking.md
@@ -51,7 +51,7 @@ PATCH /projects/:id/error_tracking/settings
| ------------ | ------- | -------- | --------------------- |
| `id` | integer | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
| `active` | boolean | yes | Pass `true` to enable the already configured error tracking settings or `false` to disable it. |
-| `integrated` | boolean | no | Pass `true` to enable the integrated error tracking backend. Available in [GitLab 14.2](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68260) and later. |
+| `integrated` | boolean | no | Pass `true` to enable the integrated error tracking backend. [Available in](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68260) GitLab 14.2 and later. |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/error_tracking/settings?active=true"
@@ -68,3 +68,87 @@ Example response:
"integrated": false
}
```
+
+## Error Tracking client keys
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68384) in GitLab 14.3.
+
+For [integrated error tracking](https://gitlab.com/gitlab-org/gitlab/-/issues/329596) feature that is behind a disabled feature flag. Only for project maintainers.
+
+### List project client keys
+
+```plaintext
+GET /projects/:id/error_tracking/client_keys
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/error_tracking/client_keys"
+```
+
+Example response:
+
+```json
+[
+ {
+ "id": 1,
+ "active": true,
+ "public_key": "glet_aa77551d849c083f76d0bc545ed053a3",
+ "sentry_dsn": "https://glet_aa77551d849c083f76d0bc545ed053a3@gitlab.example.com/api/v4/error_tracking/collector/5"
+ },
+ {
+ "id": 3,
+ "active": true,
+ "public_key": "glet_0ff98b1d849c083f76d0bc545ed053a3",
+ "sentry_dsn": "https://glet_0ff98b1d849c083f76d0bc545ed053a3@gitlab.example.com/api/v4/error_tracking/collector/5"
+ }
+]
+```
+
+### Create a client key
+
+Creates a new client key for a project. The public key attribute is generated automatically.
+
+```plaintext
+POST /projects/:id/error_tracking/client_keys
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+
+```shell
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --header "Content-Type: application/json" \
+ "https://gitlab.example.com/api/v4/projects/5/error_tracking/client_keys"
+```
+
+Example response:
+
+```json
+{
+ "id": 3,
+ "active": true,
+ "public_key": "glet_0ff98b1d849c083f76d0bc545ed053a3",
+ "sentry_dsn": "https://glet_0ff98b1d849c083f76d0bc545ed053a3@gitlab.example.com/api/v4/error_tracking/collector/5"
+}
+```
+
+### Delete a client key
+
+Removes a client key from the project.
+
+```plaintext
+DELETE /projects/:id/error_tracking/client_keys/:key_id
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `key_id` | integer | yes | The ID of the client key. |
+
+```shell
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/error_tracking/client_keys/13"
+```
diff --git a/doc/api/events.md b/doc/api/events.md
index 3fbbfa62e66..8800e7f7f9b 100644
--- a/doc/api/events.md
+++ b/doc/api/events.md
@@ -4,7 +4,7 @@ group: Compliance
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
---
-# Events API
+# Events API **(FREE)**
## Filter parameters
@@ -15,7 +15,7 @@ Available types for the `action` parameter, and the resources that might be affe
- `approved`
- Merge request
- `closed`
- - Epic
+ - Epic **(PREMIUM)**
- Issue
- Merge request
- Milestone
@@ -28,7 +28,7 @@ Available types for the `action` parameter, and the resources that might be affe
- Snippet
- `created`
- Design
- - Epic
+ - Epic **(PREMIUM)**
- Issue
- Merge request
- Milestone
@@ -49,7 +49,7 @@ Available types for the `action` parameter, and the resources that might be affe
- `pushed` commits to (or deleted commits from) a repository, individually or in bulk.
- Project
- `reopened`
- - Epic
+ - Epic **(PREMIUM)**
- Issue
- Merge request
- Milestone
diff --git a/doc/api/feature_flag_specs.md b/doc/api/feature_flag_specs.md
index 33e454d50c4..f2853efc5f2 100644
--- a/doc/api/feature_flag_specs.md
+++ b/doc/api/feature_flag_specs.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Feature Flag Specs API **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9566) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9566) in GitLab 12.5.
This API was removed in [GitLab 14.0](https://gitlab.com/gitlab-org/gitlab/-/issues/213369).
Please use [the new API](feature_flags.md) instead.
diff --git a/doc/api/features.md b/doc/api/features.md
index 87bd565e2bd..30efacb1d00 100644
--- a/doc/api/features.md
+++ b/doc/api/features.md
@@ -4,7 +4,7 @@ group: Release
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
---
-# Features flags API
+# Feature flags API **(FREE SELF)**
This API is for managing Flipper-based [feature flags used in development of GitLab](../development/feature_flags/index.md).
diff --git a/doc/api/freeze_periods.md b/doc/api/freeze_periods.md
index a562423b2af..6ca69d047da 100644
--- a/doc/api/freeze_periods.md
+++ b/doc/api/freeze_periods.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: concepts, howto
---
-# Freeze Periods API
+# Freeze Periods API **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29382) in GitLab 13.0.
diff --git a/doc/api/geo_nodes.md b/doc/api/geo_nodes.md
index 42cf40d62b8..d9b23485fd5 100644
--- a/doc/api/geo_nodes.md
+++ b/doc/api/geo_nodes.md
@@ -393,6 +393,18 @@ Example response:
"package_files_verification_failed_count": null,
"package_files_synced_in_percentage": "0.00%",
"package_files_verified_in_percentage": "0.00%",
+ "pages_deployments_count": 5,
+ "pages_deployments_checksum_total_count": 5,
+ "pages_deployments_checksummed_count": 5,
+ "pages_deployments_checksum_failed_count": 0,
+ "pages_deployments_synced_count": null,
+ "pages_deployments_failed_count": null,
+ "pages_deployments_registry_count": null,
+ "pages_deployments_verification_total_count": null,
+ "pages_deployments_verified_count": null,
+ "pages_deployments_verification_failed_count": null,
+ "pages_deployments_synced_in_percentage": "0.00%",
+ "pages_deployments_verified_in_percentage": "0.00%",
"terraform_state_versions_count": 5,
"terraform_state_versions_checksum_total_count": 5,
"terraform_state_versions_checksummed_count": 5,
@@ -441,6 +453,11 @@ Example response:
"pipeline_artifacts_verification_failed_count": null,
"pipeline_artifacts_synced_in_percentage": "0.00%",
"pipeline_artifacts_verified_in_percentage": "0.00%",
+ "uploads_count": 5,
+ "uploads_synced_count": null,
+ "uploads_failed_count": 0,
+ "uploads_registry_count": null,
+ "uploads_synced_in_percentage": "0.00%",
},
{
"geo_node_id": 2,
@@ -583,6 +600,11 @@ Example response:
"pipeline_artifacts_verification_failed_count": 0,
"pipeline_artifacts_synced_in_percentage": "100.00%",
"pipeline_artifacts_verified_in_percentage": "100.00%",
+ "uploads_count": 5,
+ "uploads_synced_count": null,
+ "uploads_failed_count": 0,
+ "uploads_registry_count": null,
+ "uploads_synced_in_percentage": "0.00%",
}
]
```
@@ -722,6 +744,11 @@ Example response:
"pipeline_artifacts_verification_failed_count": 0,
"pipeline_artifacts_synced_in_percentage": "100.00%",
"pipeline_artifacts_verified_in_percentage": "100.00%",
+ "uploads_count": 5,
+ "uploads_synced_count": null,
+ "uploads_failed_count": 0,
+ "uploads_registry_count": null,
+ "uploads_synced_in_percentage": "0.00%",
}
```
diff --git a/doc/api/graphql/audit_report.md b/doc/api/graphql/audit_report.md
index ba9967f85f2..76f3da2d6ea 100644
--- a/doc/api/graphql/audit_report.md
+++ b/doc/api/graphql/audit_report.md
@@ -4,7 +4,7 @@ group: Integrations
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
---
-# Set up an Audit Report with GraphQL
+# Set up an Audit Report with GraphQL **(FREE)**
This page describes how you can use the GraphiQL explorer to set up an audit report
for a specific subset of users.
diff --git a/doc/api/graphql/custom_emoji.md b/doc/api/graphql/custom_emoji.md
index cb5c0275e08..7307abc0568 100644
--- a/doc/api/graphql/custom_emoji.md
+++ b/doc/api/graphql/custom_emoji.md
@@ -4,7 +4,7 @@ group: Project Management
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
---
-# Use custom emojis with GraphQL **(FREE SELF)**
+# Use custom emojis with GraphQL **(FREE)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37911) in GitLab 13.6
> - [Deployed behind a feature flag](../../user/feature_flags.md), disabled by default.
@@ -93,7 +93,7 @@ For more information on:
## Enable or disable custom emoji API **(FREE SELF)**
-Custom emoji is under development and but ready for production use. It is
+Custom emoji is under development but ready for production use. It is
deployed behind a feature flag that is **disabled by default**.
[GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md)
can enable it.
diff --git a/doc/api/graphql/index.md b/doc/api/graphql/index.md
index e77e6102594..3523276bdf5 100644
--- a/doc/api/graphql/index.md
+++ b/doc/api/graphql/index.md
@@ -4,7 +4,7 @@ group: Integrations
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
---
-# GraphQL API
+# GraphQL API **(FREE)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/19008) in GitLab 11.0 (enabled by feature flag `graphql`).
> - [Always enabled](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30444) in GitLab 12.1.
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 54709f56eb8..c4e73f9c058 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -1,6 +1,6 @@
---
-stage: Plan
-group: Project Management
+stage: Ecosystem
+group: Integrations
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/#designated-technical-writers
---
@@ -56,7 +56,7 @@ Returns [`CiConfig`](#ciconfig).
### `Query.ciMinutesUsage`
-The monthly CI minutes usage data for the current user.
+Monthly CI minutes usage data for the current user.
Returns [`CiMinutesNamespaceMonthlyUsageConnection`](#ciminutesnamespacemonthlyusageconnection).
@@ -74,7 +74,7 @@ Returns [`ContainerRepositoryDetails`](#containerrepositorydetails).
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="querycontainerrepositoryid"></a>`id` | [`ContainerRepositoryID!`](#containerrepositoryid) | The global ID of the container repository. |
+| <a id="querycontainerrepositoryid"></a>`id` | [`ContainerRepositoryID!`](#containerrepositoryid) | Global ID of the container repository. |
### `Query.currentLicense`
@@ -132,7 +132,7 @@ Returns [`GeoNode`](#geonode).
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="querygeonodename"></a>`name` | [`String`](#string) | The name of the Geo node. Defaults to the current Geo node name. |
+| <a id="querygeonodename"></a>`name` | [`String`](#string) | Name of the Geo node. Defaults to the current Geo node name. |
### `Query.group`
@@ -185,7 +185,7 @@ Returns [`Issue`](#issue).
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="queryissueid"></a>`id` | [`IssueID!`](#issueid) | The global ID of the issue. |
+| <a id="queryissueid"></a>`id` | [`IssueID!`](#issueid) | Global ID of the issue. |
### `Query.iteration`
@@ -219,7 +219,7 @@ Returns [`MergeRequest`](#mergerequest).
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="querymergerequestid"></a>`id` | [`MergeRequestID!`](#mergerequestid) | The global ID of the merge request. |
+| <a id="querymergerequestid"></a>`id` | [`MergeRequestID!`](#mergerequestid) | Global ID of the merge request. |
### `Query.metadata`
@@ -261,7 +261,7 @@ Returns [`PackageDetailsType`](#packagedetailstype).
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="querypackageid"></a>`id` | [`PackagesPackageID!`](#packagespackageid) | The global ID of the package. |
+| <a id="querypackageid"></a>`id` | [`PackagesPackageID!`](#packagespackageid) | Global ID of the package. |
### `Query.project`
@@ -304,7 +304,7 @@ Returns [`QueryComplexity`](#querycomplexity).
### `Query.runner`
-Find a runner. Available only when feature flag `runner_graphql_query` is enabled. This flag is enabled by default.
+Find a runner.
Returns [`CiRunner`](#cirunner).
@@ -341,7 +341,7 @@ Returns [`RunnerSetup`](#runnersetup).
### `Query.runners`
-Find runners visible to the current user. Available only when feature flag `runner_graphql_query` is enabled. This flag is enabled by default.
+Find runners visible to the current user.
Returns [`CiRunnerConnection`](#cirunnerconnection).
@@ -373,11 +373,11 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="querysnippetsauthorid"></a>`authorId` | [`UserID`](#userid) | The ID of an author. |
+| <a id="querysnippetsauthorid"></a>`authorId` | [`UserID`](#userid) | ID of an author. |
| <a id="querysnippetsexplore"></a>`explore` | [`Boolean`](#boolean) | Explore personal snippets. |
| <a id="querysnippetsids"></a>`ids` | [`[SnippetID!]`](#snippetid) | Array of global snippet IDs. For example, `gid://gitlab/ProjectSnippet/1`. |
-| <a id="querysnippetsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The ID of a project. |
-| <a id="querysnippetstype"></a>`type` | [`TypeEnum`](#typeenum) | The type of snippet. |
+| <a id="querysnippetsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | ID of a project. |
+| <a id="querysnippetstype"></a>`type` | [`TypeEnum`](#typeenum) | Type of snippet. |
| <a id="querysnippetsvisibility"></a>`visibility` | [`VisibilityScopesEnum`](#visibilityscopesenum) | Visibility of the snippet. |
### `Query.timelogs`
@@ -504,7 +504,7 @@ Returns [`Vulnerability`](#vulnerability).
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="queryvulnerabilityid"></a>`id` | [`VulnerabilityID!`](#vulnerabilityid) | The Global ID of the Vulnerability. |
+| <a id="queryvulnerabilityid"></a>`id` | [`VulnerabilityID!`](#vulnerabilityid) | Global ID of the Vulnerability. |
## `Mutation` type
@@ -563,6 +563,7 @@ Input type: `AdminSidekiqQueuesDeleteJobsInput`
| <a id="mutationadminsidekiqqueuesdeletejobsrootnamespace"></a>`rootNamespace` | [`String`](#string) | Delete jobs matching root_namespace in the context metadata. |
| <a id="mutationadminsidekiqqueuesdeletejobssubscriptionplan"></a>`subscriptionPlan` | [`String`](#string) | Delete jobs matching subscription_plan in the context metadata. |
| <a id="mutationadminsidekiqqueuesdeletejobsuser"></a>`user` | [`String`](#string) | Delete jobs matching user in the context metadata. |
+| <a id="mutationadminsidekiqqueuesdeletejobsworkerclass"></a>`workerClass` | [`String`](#string) | Delete jobs with the given worker class. |
#### Fields
@@ -631,7 +632,7 @@ Input type: `ApiFuzzingCiConfigurationCreateInput`
| <a id="mutationapifuzzingciconfigurationcreateauthusername"></a>`authUsername` | [`String`](#string) | CI variable containing the username for authenticating with the target API. |
| <a id="mutationapifuzzingciconfigurationcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationapifuzzingciconfigurationcreateprojectpath"></a>`projectPath` | [`ID!`](#id) | Full path of the project. |
-| <a id="mutationapifuzzingciconfigurationcreatescanmode"></a>`scanMode` | [`ApiFuzzingScanMode!`](#apifuzzingscanmode) | The mode for API fuzzing scans. |
+| <a id="mutationapifuzzingciconfigurationcreatescanmode"></a>`scanMode` | [`ApiFuzzingScanMode!`](#apifuzzingscanmode) | Mode for API fuzzing scans. |
| <a id="mutationapifuzzingciconfigurationcreatescanprofile"></a>`scanProfile` | [`String`](#string) | Name of a default profile to use for scanning. Ex: Quick-10. |
| <a id="mutationapifuzzingciconfigurationcreatetarget"></a>`target` | [`String!`](#string) | URL for the target of API fuzzing scans. |
@@ -642,7 +643,7 @@ Input type: `ApiFuzzingCiConfigurationCreateInput`
| <a id="mutationapifuzzingciconfigurationcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationapifuzzingciconfigurationcreateconfigurationyaml"></a>`configurationYaml` | [`String`](#string) | A YAML snippet that can be inserted into the project's `.gitlab-ci.yml` to set up API fuzzing scans. |
| <a id="mutationapifuzzingciconfigurationcreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationapifuzzingciconfigurationcreategitlabciyamleditpath"></a>`gitlabCiYamlEditPath` | [`String`](#string) | The location at which the project's `.gitlab-ci.yml` file can be edited in the browser. |
+| <a id="mutationapifuzzingciconfigurationcreategitlabciyamleditpath"></a>`gitlabCiYamlEditPath` | [`String`](#string) | Location at which the project's `.gitlab-ci.yml` file can be edited in the browser. |
### `Mutation.awardEmojiAdd`
@@ -654,7 +655,7 @@ Input type: `AwardEmojiAddInput`
| ---- | ---- | ----------- |
| <a id="mutationawardemojiaddawardableid"></a>`awardableId` | [`AwardableID!`](#awardableid) | Global ID of the awardable resource. |
| <a id="mutationawardemojiaddclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationawardemojiaddname"></a>`name` | [`String!`](#string) | The emoji name. |
+| <a id="mutationawardemojiaddname"></a>`name` | [`String!`](#string) | Emoji name. |
#### Fields
@@ -674,7 +675,7 @@ Input type: `AwardEmojiRemoveInput`
| ---- | ---- | ----------- |
| <a id="mutationawardemojiremoveawardableid"></a>`awardableId` | [`AwardableID!`](#awardableid) | Global ID of the awardable resource. |
| <a id="mutationawardemojiremoveclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationawardemojiremovename"></a>`name` | [`String!`](#string) | The emoji name. |
+| <a id="mutationawardemojiremovename"></a>`name` | [`String!`](#string) | Emoji name. |
#### Fields
@@ -694,7 +695,7 @@ Input type: `AwardEmojiToggleInput`
| ---- | ---- | ----------- |
| <a id="mutationawardemojitoggleawardableid"></a>`awardableId` | [`AwardableID!`](#awardableid) | Global ID of the awardable resource. |
| <a id="mutationawardemojitoggleclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationawardemojitogglename"></a>`name` | [`String!`](#string) | The emoji name. |
+| <a id="mutationawardemojitogglename"></a>`name` | [`String!`](#string) | Emoji name. |
#### Fields
@@ -760,10 +761,10 @@ Input type: `BoardListUpdateLimitMetricsInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationboardlistupdatelimitmetricsclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationboardlistupdatelimitmetricslimitmetric"></a>`limitMetric` | [`ListLimitMetric`](#listlimitmetric) | The new limit metric type for the list. |
-| <a id="mutationboardlistupdatelimitmetricslistid"></a>`listId` | [`ListID!`](#listid) | The global ID of the list. |
-| <a id="mutationboardlistupdatelimitmetricsmaxissuecount"></a>`maxIssueCount` | [`Int`](#int) | The new maximum issue count limit. |
-| <a id="mutationboardlistupdatelimitmetricsmaxissueweight"></a>`maxIssueWeight` | [`Int`](#int) | The new maximum issue weight limit. |
+| <a id="mutationboardlistupdatelimitmetricslimitmetric"></a>`limitMetric` | [`ListLimitMetric`](#listlimitmetric) | New limit metric type for the list. |
+| <a id="mutationboardlistupdatelimitmetricslistid"></a>`listId` | [`ListID!`](#listid) | Global ID of the list. |
+| <a id="mutationboardlistupdatelimitmetricsmaxissuecount"></a>`maxIssueCount` | [`Int`](#int) | New maximum issue count limit. |
+| <a id="mutationboardlistupdatelimitmetricsmaxissueweight"></a>`maxIssueWeight` | [`Int`](#int) | New maximum issue weight limit. |
#### Fields
@@ -771,7 +772,7 @@ Input type: `BoardListUpdateLimitMetricsInput`
| ---- | ---- | ----------- |
| <a id="mutationboardlistupdatelimitmetricsclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationboardlistupdatelimitmetricserrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationboardlistupdatelimitmetricslist"></a>`list` | [`BoardList`](#boardlist) | The updated list. |
+| <a id="mutationboardlistupdatelimitmetricslist"></a>`list` | [`BoardList`](#boardlist) | Updated list. |
### `Mutation.bulkEnableDevopsAdoptionNamespaces`
@@ -1074,6 +1075,7 @@ Input type: `CreateBoardInput`
| <a id="mutationcreateboardgrouppath"></a>`groupPath` | [`ID`](#id) | Full path of the group with which the resource is associated. |
| <a id="mutationcreateboardhidebackloglist"></a>`hideBacklogList` | [`Boolean`](#boolean) | Whether or not backlog list is hidden. |
| <a id="mutationcreateboardhideclosedlist"></a>`hideClosedList` | [`Boolean`](#boolean) | Whether or not closed list is hidden. |
+| <a id="mutationcreateboarditerationcadenceid"></a>`iterationCadenceId` | [`IterationsCadenceID`](#iterationscadenceid) | ID of iteration cadence to be assigned to the board. |
| <a id="mutationcreateboarditerationid"></a>`iterationId` | [`IterationID`](#iterationid) | ID of iteration to be assigned to the board. |
| <a id="mutationcreateboardlabelids"></a>`labelIds` | [`[LabelID!]`](#labelid) | IDs of labels to be added to the board. |
| <a id="mutationcreateboardlabels"></a>`labels` | [`[String!]`](#string) | Labels of the issue. |
@@ -1149,7 +1151,7 @@ Input type: `CreateComplianceFrameworkInput`
| ---- | ---- | ----------- |
| <a id="mutationcreatecomplianceframeworkclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationcreatecomplianceframeworkerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationcreatecomplianceframeworkframework"></a>`framework` | [`ComplianceFramework`](#complianceframework) | The created compliance framework. |
+| <a id="mutationcreatecomplianceframeworkframework"></a>`framework` | [`ComplianceFramework`](#complianceframework) | Created compliance framework. |
### `Mutation.createCustomEmoji`
@@ -1186,7 +1188,7 @@ Input type: `CreateDiffNoteInput`
| <a id="mutationcreatediffnoteclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationcreatediffnoteconfidential"></a>`confidential` | [`Boolean`](#boolean) | Confidentiality flag of a note. Default is false. |
| <a id="mutationcreatediffnotenoteableid"></a>`noteableId` | [`NoteableID!`](#noteableid) | Global ID of the resource to add a note to. |
-| <a id="mutationcreatediffnoteposition"></a>`position` | [`DiffPositionInput!`](#diffpositioninput) | The position of this note on a diff. |
+| <a id="mutationcreatediffnoteposition"></a>`position` | [`DiffPositionInput!`](#diffpositioninput) | Position of this note on a diff. |
#### Fields
@@ -1204,24 +1206,24 @@ Input type: `CreateEpicInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="mutationcreateepicaddlabelids"></a>`addLabelIds` | [`[ID!]`](#id) | The IDs of labels to be added to the epic. |
+| <a id="mutationcreateepicaddlabelids"></a>`addLabelIds` | [`[ID!]`](#id) | IDs of labels to be added to the epic. |
| <a id="mutationcreateepicclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationcreateepicconfidential"></a>`confidential` | [`Boolean`](#boolean) | Indicates if the epic is confidential. |
-| <a id="mutationcreateepicdescription"></a>`description` | [`String`](#string) | The description of the epic. |
-| <a id="mutationcreateepicduedatefixed"></a>`dueDateFixed` | [`String`](#string) | The end date of the epic. |
+| <a id="mutationcreateepicdescription"></a>`description` | [`String`](#string) | Description of the epic. |
+| <a id="mutationcreateepicduedatefixed"></a>`dueDateFixed` | [`String`](#string) | End date of the epic. |
| <a id="mutationcreateepicduedateisfixed"></a>`dueDateIsFixed` | [`Boolean`](#boolean) | Indicates end date should be sourced from due_date_fixed field not the issue milestones. |
-| <a id="mutationcreateepicgrouppath"></a>`groupPath` | [`ID!`](#id) | The group the epic to mutate is in. |
-| <a id="mutationcreateepicremovelabelids"></a>`removeLabelIds` | [`[ID!]`](#id) | The IDs of labels to be removed from the epic. |
-| <a id="mutationcreateepicstartdatefixed"></a>`startDateFixed` | [`String`](#string) | The start date of the epic. |
+| <a id="mutationcreateepicgrouppath"></a>`groupPath` | [`ID!`](#id) | Group the epic to mutate is in. |
+| <a id="mutationcreateepicremovelabelids"></a>`removeLabelIds` | [`[ID!]`](#id) | IDs of labels to be removed from the epic. |
+| <a id="mutationcreateepicstartdatefixed"></a>`startDateFixed` | [`String`](#string) | Start date of the epic. |
| <a id="mutationcreateepicstartdateisfixed"></a>`startDateIsFixed` | [`Boolean`](#boolean) | Indicates start date should be sourced from start_date_fixed field not the issue milestones. |
-| <a id="mutationcreateepictitle"></a>`title` | [`String`](#string) | The title of the epic. |
+| <a id="mutationcreateepictitle"></a>`title` | [`String`](#string) | Title of the epic. |
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationcreateepicclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationcreateepicepic"></a>`epic` | [`Epic`](#epic) | The created epic. |
+| <a id="mutationcreateepicepic"></a>`epic` | [`Epic`](#epic) | Created epic. |
| <a id="mutationcreateepicerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
### `Mutation.createImageDiffNote`
@@ -1236,7 +1238,7 @@ Input type: `CreateImageDiffNoteInput`
| <a id="mutationcreateimagediffnoteclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationcreateimagediffnoteconfidential"></a>`confidential` | [`Boolean`](#boolean) | Confidentiality flag of a note. Default is false. |
| <a id="mutationcreateimagediffnotenoteableid"></a>`noteableId` | [`NoteableID!`](#noteableid) | Global ID of the resource to add a note to. |
-| <a id="mutationcreateimagediffnoteposition"></a>`position` | [`DiffImagePositionInput!`](#diffimagepositioninput) | The position of this note on a diff. |
+| <a id="mutationcreateimagediffnoteposition"></a>`position` | [`DiffImagePositionInput!`](#diffimagepositioninput) | Position of this note on a diff. |
#### Fields
@@ -1261,8 +1263,8 @@ Input type: `CreateIssueInput`
| <a id="mutationcreateissuedescription"></a>`description` | [`String`](#string) | Description of the issue. |
| <a id="mutationcreateissuediscussiontoresolve"></a>`discussionToResolve` | [`String`](#string) | ID of a discussion to resolve. Also pass `merge_request_to_resolve_discussions_of`. |
| <a id="mutationcreateissueduedate"></a>`dueDate` | [`ISO8601Date`](#iso8601date) | Due date of the issue. |
-| <a id="mutationcreateissueepicid"></a>`epicId` | [`EpicID`](#epicid) | The ID of an epic to associate the issue with. |
-| <a id="mutationcreateissuehealthstatus"></a>`healthStatus` | [`HealthStatus`](#healthstatus) | The desired health status. |
+| <a id="mutationcreateissueepicid"></a>`epicId` | [`EpicID`](#epicid) | ID of an epic to associate the issue with. |
+| <a id="mutationcreateissuehealthstatus"></a>`healthStatus` | [`HealthStatus`](#healthstatus) | Desired health status. |
| <a id="mutationcreateissueiid"></a>`iid` | [`Int`](#int) | IID (internal ID) of a project issue. Only admins and project owners can modify. |
| <a id="mutationcreateissuelabelids"></a>`labelIds` | [`[LabelID!]`](#labelid) | IDs of labels to be added to the issue. |
| <a id="mutationcreateissuelabels"></a>`labels` | [`[String!]`](#string) | Labels of the issue. |
@@ -1272,7 +1274,7 @@ Input type: `CreateIssueInput`
| <a id="mutationcreateissueprojectpath"></a>`projectPath` | [`ID!`](#id) | Project full path the issue is associated with. |
| <a id="mutationcreateissuetitle"></a>`title` | [`String!`](#string) | Title of the issue. |
| <a id="mutationcreateissuetype"></a>`type` | [`IssueType`](#issuetype) | Type of the issue. |
-| <a id="mutationcreateissueweight"></a>`weight` | [`Int`](#int) | The weight of the issue. |
+| <a id="mutationcreateissueweight"></a>`weight` | [`Int`](#int) | Weight of the issue. |
#### Fields
@@ -1295,13 +1297,13 @@ Input type: `CreateIterationInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationcreateiterationclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationcreateiterationdescription"></a>`description` | [`String`](#string) | The description of the iteration. |
-| <a id="mutationcreateiterationduedate"></a>`dueDate` | [`String`](#string) | The end date of the iteration. |
+| <a id="mutationcreateiterationdescription"></a>`description` | [`String`](#string) | Description of the iteration. |
+| <a id="mutationcreateiterationduedate"></a>`dueDate` | [`String`](#string) | End date of the iteration. |
| <a id="mutationcreateiterationgrouppath"></a>`groupPath` | [`ID`](#id) | Full path of the group with which the resource is associated. |
| <a id="mutationcreateiterationiterationscadenceid"></a>`iterationsCadenceId` | [`IterationsCadenceID`](#iterationscadenceid) | Global ID of the iterations cadence to be assigned to newly created iteration. |
| <a id="mutationcreateiterationprojectpath"></a>`projectPath` | [`ID`](#id) | Full path of the project with which the resource is associated. |
-| <a id="mutationcreateiterationstartdate"></a>`startDate` | [`String`](#string) | The start date of the iteration. |
-| <a id="mutationcreateiterationtitle"></a>`title` | [`String`](#string) | The title of the iteration. |
+| <a id="mutationcreateiterationstartdate"></a>`startDate` | [`String`](#string) | Start date of the iteration. |
+| <a id="mutationcreateiterationtitle"></a>`title` | [`String`](#string) | Title of the iteration. |
#### Fields
@@ -1309,7 +1311,7 @@ Input type: `CreateIterationInput`
| ---- | ---- | ----------- |
| <a id="mutationcreateiterationclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationcreateiterationerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationcreateiterationiteration"></a>`iteration` | [`Iteration`](#iteration) | The created iteration. |
+| <a id="mutationcreateiterationiteration"></a>`iteration` | [`Iteration`](#iteration) | Created iteration. |
### `Mutation.createNote`
@@ -1393,10 +1395,10 @@ Input type: `CreateTestCaseInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationcreatetestcaseclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationcreatetestcasedescription"></a>`description` | [`String`](#string) | The test case description. |
-| <a id="mutationcreatetestcaselabelids"></a>`labelIds` | [`[ID!]`](#id) | The IDs of labels to be added to the test case. |
-| <a id="mutationcreatetestcaseprojectpath"></a>`projectPath` | [`ID!`](#id) | The project full path to create the test case. |
-| <a id="mutationcreatetestcasetitle"></a>`title` | [`String!`](#string) | The test case title. |
+| <a id="mutationcreatetestcasedescription"></a>`description` | [`String`](#string) | Test case description. |
+| <a id="mutationcreatetestcaselabelids"></a>`labelIds` | [`[ID!]`](#id) | IDs of labels to be added to the test case. |
+| <a id="mutationcreatetestcaseprojectpath"></a>`projectPath` | [`ID!`](#id) | Project full path to create the test case in. |
+| <a id="mutationcreatetestcasetitle"></a>`title` | [`String!`](#string) | Test case title. |
#### Fields
@@ -1404,7 +1406,51 @@ Input type: `CreateTestCaseInput`
| ---- | ---- | ----------- |
| <a id="mutationcreatetestcaseclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationcreatetestcaseerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationcreatetestcasetestcase"></a>`testCase` | [`Issue`](#issue) | The test case created. |
+| <a id="mutationcreatetestcasetestcase"></a>`testCase` | [`Issue`](#issue) | Test case created. |
+
+### `Mutation.customerRelationsOrganizationCreate`
+
+Input type: `CustomerRelationsOrganizationCreateInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationcustomerrelationsorganizationcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationcustomerrelationsorganizationcreatedefaultrate"></a>`defaultRate` | [`Float`](#float) | Standard billing rate for the organization. |
+| <a id="mutationcustomerrelationsorganizationcreatedescription"></a>`description` | [`String`](#string) | Description or notes for the organization. |
+| <a id="mutationcustomerrelationsorganizationcreategroupid"></a>`groupId` | [`GroupID!`](#groupid) | Group for the organization. |
+| <a id="mutationcustomerrelationsorganizationcreatename"></a>`name` | [`String!`](#string) | Name of the organization. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationcustomerrelationsorganizationcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationcustomerrelationsorganizationcreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+| <a id="mutationcustomerrelationsorganizationcreateorganization"></a>`organization` | [`CustomerRelationsOrganization`](#customerrelationsorganization) | Organization after the mutation. |
+
+### `Mutation.customerRelationsOrganizationUpdate`
+
+Input type: `CustomerRelationsOrganizationUpdateInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationcustomerrelationsorganizationupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationcustomerrelationsorganizationupdatedefaultrate"></a>`defaultRate` | [`Float`](#float) | Standard billing rate for the organization. |
+| <a id="mutationcustomerrelationsorganizationupdatedescription"></a>`description` | [`String`](#string) | Description or notes for the organization. |
+| <a id="mutationcustomerrelationsorganizationupdateid"></a>`id` | [`CustomerRelationsOrganizationID!`](#customerrelationsorganizationid) | Global ID of the organization. |
+| <a id="mutationcustomerrelationsorganizationupdatename"></a>`name` | [`String`](#string) | Name of the organization. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationcustomerrelationsorganizationupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationcustomerrelationsorganizationupdateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+| <a id="mutationcustomerrelationsorganizationupdateorganization"></a>`organization` | [`CustomerRelationsOrganization!`](#customerrelationsorganization) | Organization after the mutation. |
### `Mutation.dastOnDemandScanCreate`
@@ -1417,7 +1463,7 @@ Input type: `DastOnDemandScanCreateInput`
| <a id="mutationdastondemandscancreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationdastondemandscancreatedastscannerprofileid"></a>`dastScannerProfileId` | [`DastScannerProfileID`](#dastscannerprofileid) | ID of the scanner profile to be used for the scan. |
| <a id="mutationdastondemandscancreatedastsiteprofileid"></a>`dastSiteProfileId` | [`DastSiteProfileID!`](#dastsiteprofileid) | ID of the site profile to be used for the scan. |
-| <a id="mutationdastondemandscancreatefullpath"></a>`fullPath` | [`ID!`](#id) | The project the site profile belongs to. |
+| <a id="mutationdastondemandscancreatefullpath"></a>`fullPath` | [`ID!`](#id) | Project the site profile belongs to. |
#### Fields
@@ -1435,13 +1481,14 @@ Input type: `DastProfileCreateInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="mutationdastprofilecreatebranchname"></a>`branchName` | [`String`](#string) | The associated branch. |
+| <a id="mutationdastprofilecreatebranchname"></a>`branchName` | [`String`](#string) | Associated branch. |
| <a id="mutationdastprofilecreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationdastprofilecreatedastprofileschedule"></a>`dastProfileSchedule` | [`DastProfileScheduleInput`](#dastprofilescheduleinput) | Represents a DAST Profile Schedule. Results in an error if `dast_on_demand_scans_scheduler` feature flag is disabled. |
| <a id="mutationdastprofilecreatedastscannerprofileid"></a>`dastScannerProfileId` | [`DastScannerProfileID!`](#dastscannerprofileid) | ID of the scanner profile to be associated. |
| <a id="mutationdastprofilecreatedastsiteprofileid"></a>`dastSiteProfileId` | [`DastSiteProfileID!`](#dastsiteprofileid) | ID of the site profile to be associated. |
-| <a id="mutationdastprofilecreatedescription"></a>`description` | [`String`](#string) | The description of the profile. Defaults to an empty string. |
-| <a id="mutationdastprofilecreatefullpath"></a>`fullPath` | [`ID!`](#id) | The project the profile belongs to. |
-| <a id="mutationdastprofilecreatename"></a>`name` | [`String!`](#string) | The name of the profile. |
+| <a id="mutationdastprofilecreatedescription"></a>`description` | [`String`](#string) | Description of the profile. Defaults to an empty string. |
+| <a id="mutationdastprofilecreatefullpath"></a>`fullPath` | [`ID!`](#id) | Project the profile belongs to. |
+| <a id="mutationdastprofilecreatename"></a>`name` | [`String!`](#string) | Name of the profile. |
| <a id="mutationdastprofilecreaterunaftercreate"></a>`runAfterCreate` | [`Boolean`](#boolean) | Run scan using profile after creation. Defaults to false. |
#### Fields
@@ -1449,9 +1496,9 @@ Input type: `DastProfileCreateInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationdastprofilecreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationdastprofilecreatedastprofile"></a>`dastProfile` | [`DastProfile`](#dastprofile) | The created profile. |
+| <a id="mutationdastprofilecreatedastprofile"></a>`dastProfile` | [`DastProfile`](#dastprofile) | Created profile. |
| <a id="mutationdastprofilecreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationdastprofilecreatepipelineurl"></a>`pipelineUrl` | [`String`](#string) | The URL of the pipeline that was created. Requires `runAfterCreate` to be set to `true`. |
+| <a id="mutationdastprofilecreatepipelineurl"></a>`pipelineUrl` | [`String`](#string) | URL of the pipeline that was created. Requires `runAfterCreate` to be set to `true`. |
### `Mutation.dastProfileDelete`
@@ -1499,14 +1546,15 @@ Input type: `DastProfileUpdateInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="mutationdastprofileupdatebranchname"></a>`branchName` | [`String`](#string) | The associated branch. |
+| <a id="mutationdastprofileupdatebranchname"></a>`branchName` | [`String`](#string) | Associated branch. |
| <a id="mutationdastprofileupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationdastprofileupdatedastprofileschedule"></a>`dastProfileSchedule` | [`DastProfileScheduleInput`](#dastprofilescheduleinput) | Represents a DAST profile schedule. Results in an error if `dast_on_demand_scans_scheduler` feature flag is disabled. |
| <a id="mutationdastprofileupdatedastscannerprofileid"></a>`dastScannerProfileId` | [`DastScannerProfileID`](#dastscannerprofileid) | ID of the scanner profile to be associated. |
| <a id="mutationdastprofileupdatedastsiteprofileid"></a>`dastSiteProfileId` | [`DastSiteProfileID`](#dastsiteprofileid) | ID of the site profile to be associated. |
-| <a id="mutationdastprofileupdatedescription"></a>`description` | [`String`](#string) | The description of the profile. Defaults to an empty string. |
-| <a id="mutationdastprofileupdatefullpath"></a>`fullPath` | [`ID!`](#id) | The project the profile belongs to. |
+| <a id="mutationdastprofileupdatedescription"></a>`description` | [`String`](#string) | Description of the profile. Defaults to an empty string. |
+| <a id="mutationdastprofileupdatefullpath"></a>`fullPath` | [`ID!`](#id) | Project the profile belongs to. |
| <a id="mutationdastprofileupdateid"></a>`id` | [`DastProfileID!`](#dastprofileid) | ID of the profile to be deleted. |
-| <a id="mutationdastprofileupdatename"></a>`name` | [`String`](#string) | The name of the profile. |
+| <a id="mutationdastprofileupdatename"></a>`name` | [`String`](#string) | Name of the profile. |
| <a id="mutationdastprofileupdaterunafterupdate"></a>`runAfterUpdate` | [`Boolean`](#boolean) | Run scan using profile after update. Defaults to false. |
#### Fields
@@ -1514,7 +1562,7 @@ Input type: `DastProfileUpdateInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationdastprofileupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationdastprofileupdatedastprofile"></a>`dastProfile` | [`DastProfile`](#dastprofile) | The updated profile. |
+| <a id="mutationdastprofileupdatedastprofile"></a>`dastProfile` | [`DastProfile`](#dastprofile) | Updated profile. |
| <a id="mutationdastprofileupdateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationdastprofileupdatepipelineurl"></a>`pipelineUrl` | [`String`](#string) | The URL of the pipeline that was created. Requires the input argument `runAfterUpdate` to be set to `true` when calling the mutation, otherwise no pipeline will be created. |
@@ -1527,12 +1575,12 @@ Input type: `DastScannerProfileCreateInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationdastscannerprofilecreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationdastscannerprofilecreatefullpath"></a>`fullPath` | [`ID!`](#id) | The project the scanner profile belongs to. |
-| <a id="mutationdastscannerprofilecreateprofilename"></a>`profileName` | [`String!`](#string) | The name of the scanner profile. |
+| <a id="mutationdastscannerprofilecreatefullpath"></a>`fullPath` | [`ID!`](#id) | Project the scanner profile belongs to. |
+| <a id="mutationdastscannerprofilecreateprofilename"></a>`profileName` | [`String!`](#string) | Name of the scanner profile. |
| <a id="mutationdastscannerprofilecreatescantype"></a>`scanType` | [`DastScanTypeEnum`](#dastscantypeenum) | Indicates the type of DAST scan that will run. Either a Passive Scan or an Active Scan. |
| <a id="mutationdastscannerprofilecreateshowdebugmessages"></a>`showDebugMessages` | [`Boolean`](#boolean) | Indicates if debug messages should be included in DAST console output. True to include the debug messages. |
-| <a id="mutationdastscannerprofilecreatespidertimeout"></a>`spiderTimeout` | [`Int`](#int) | The maximum number of minutes allowed for the spider to traverse the site. |
-| <a id="mutationdastscannerprofilecreatetargettimeout"></a>`targetTimeout` | [`Int`](#int) | The maximum number of seconds allowed for the site under test to respond to a request. |
+| <a id="mutationdastscannerprofilecreatespidertimeout"></a>`spiderTimeout` | [`Int`](#int) | Maximum number of minutes allowed for the spider to traverse the site. |
+| <a id="mutationdastscannerprofilecreatetargettimeout"></a>`targetTimeout` | [`Int`](#int) | Maximum number of seconds allowed for the site under test to respond to a request. |
| <a id="mutationdastscannerprofilecreateuseajaxspider"></a>`useAjaxSpider` | [`Boolean`](#boolean) | Indicates if the AJAX spider should be used to crawl the target site. True to run the AJAX spider in addition to the traditional spider, and false to run only the traditional spider. |
#### Fields
@@ -1571,13 +1619,13 @@ Input type: `DastScannerProfileUpdateInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationdastscannerprofileupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationdastscannerprofileupdatefullpath"></a>`fullPath` | [`ID!`](#id) | The project the scanner profile belongs to. |
+| <a id="mutationdastscannerprofileupdatefullpath"></a>`fullPath` | [`ID!`](#id) | Project the scanner profile belongs to. |
| <a id="mutationdastscannerprofileupdateid"></a>`id` | [`DastScannerProfileID!`](#dastscannerprofileid) | ID of the scanner profile to be updated. |
-| <a id="mutationdastscannerprofileupdateprofilename"></a>`profileName` | [`String!`](#string) | The name of the scanner profile. |
+| <a id="mutationdastscannerprofileupdateprofilename"></a>`profileName` | [`String!`](#string) | Name of the scanner profile. |
| <a id="mutationdastscannerprofileupdatescantype"></a>`scanType` | [`DastScanTypeEnum`](#dastscantypeenum) | Indicates the type of DAST scan that will run. Either a Passive Scan or an Active Scan. |
| <a id="mutationdastscannerprofileupdateshowdebugmessages"></a>`showDebugMessages` | [`Boolean`](#boolean) | Indicates if debug messages should be included in DAST console output. True to include the debug messages. |
-| <a id="mutationdastscannerprofileupdatespidertimeout"></a>`spiderTimeout` | [`Int!`](#int) | The maximum number of minutes allowed for the spider to traverse the site. |
-| <a id="mutationdastscannerprofileupdatetargettimeout"></a>`targetTimeout` | [`Int!`](#int) | The maximum number of seconds allowed for the site under test to respond to a request. |
+| <a id="mutationdastscannerprofileupdatespidertimeout"></a>`spiderTimeout` | [`Int!`](#int) | Maximum number of minutes allowed for the spider to traverse the site. |
+| <a id="mutationdastscannerprofileupdatetargettimeout"></a>`targetTimeout` | [`Int!`](#int) | Maximum number of seconds allowed for the site under test to respond to a request. |
| <a id="mutationdastscannerprofileupdateuseajaxspider"></a>`useAjaxSpider` | [`Boolean`](#boolean) | Indicates if the AJAX spider should be used to crawl the target site. True to run the AJAX spider in addition to the traditional spider, and false to run only the traditional spider. |
#### Fields
@@ -1598,12 +1646,12 @@ Input type: `DastSiteProfileCreateInput`
| ---- | ---- | ----------- |
| <a id="mutationdastsiteprofilecreateauth"></a>`auth` | [`DastSiteProfileAuthInput`](#dastsiteprofileauthinput) | Parameters for authentication. |
| <a id="mutationdastsiteprofilecreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationdastsiteprofilecreateexcludedurls"></a>`excludedUrls` | [`[String!]`](#string) | The URLs to skip during an authenticated scan. Defaults to `[]`. |
-| <a id="mutationdastsiteprofilecreatefullpath"></a>`fullPath` | [`ID!`](#id) | The project the site profile belongs to. |
-| <a id="mutationdastsiteprofilecreateprofilename"></a>`profileName` | [`String!`](#string) | The name of the site profile. |
+| <a id="mutationdastsiteprofilecreateexcludedurls"></a>`excludedUrls` | [`[String!]`](#string) | URLs to skip during an authenticated scan. Defaults to `[]`. |
+| <a id="mutationdastsiteprofilecreatefullpath"></a>`fullPath` | [`ID!`](#id) | Project the site profile belongs to. |
+| <a id="mutationdastsiteprofilecreateprofilename"></a>`profileName` | [`String!`](#string) | Name of the site profile. |
| <a id="mutationdastsiteprofilecreaterequestheaders"></a>`requestHeaders` | [`String`](#string) | Comma-separated list of request header names and values to be added to every request made by DAST. |
-| <a id="mutationdastsiteprofilecreatetargettype"></a>`targetType` | [`DastTargetTypeEnum`](#dasttargettypeenum) | The type of target to be scanned. |
-| <a id="mutationdastsiteprofilecreatetargeturl"></a>`targetUrl` | [`String`](#string) | The URL of the target to be scanned. |
+| <a id="mutationdastsiteprofilecreatetargettype"></a>`targetType` | [`DastTargetTypeEnum`](#dasttargettypeenum) | Type of target to be scanned. |
+| <a id="mutationdastsiteprofilecreatetargeturl"></a>`targetUrl` | [`String`](#string) | URL of the target to be scanned. |
#### Fields
@@ -1622,7 +1670,7 @@ Input type: `DastSiteProfileDeleteInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationdastsiteprofiledeleteclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationdastsiteprofiledeletefullpath"></a>`fullPath` | [`ID!`](#id) | The project the site profile belongs to. |
+| <a id="mutationdastsiteprofiledeletefullpath"></a>`fullPath` | [`ID!`](#id) | Project the site profile belongs to. |
| <a id="mutationdastsiteprofiledeleteid"></a>`id` | [`DastSiteProfileID!`](#dastsiteprofileid) | ID of the site profile to be deleted. |
#### Fields
@@ -1642,13 +1690,13 @@ Input type: `DastSiteProfileUpdateInput`
| ---- | ---- | ----------- |
| <a id="mutationdastsiteprofileupdateauth"></a>`auth` | [`DastSiteProfileAuthInput`](#dastsiteprofileauthinput) | Parameters for authentication. |
| <a id="mutationdastsiteprofileupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationdastsiteprofileupdateexcludedurls"></a>`excludedUrls` | [`[String!]`](#string) | The URLs to skip during an authenticated scan. |
-| <a id="mutationdastsiteprofileupdatefullpath"></a>`fullPath` | [`ID!`](#id) | The project the site profile belongs to. |
+| <a id="mutationdastsiteprofileupdateexcludedurls"></a>`excludedUrls` | [`[String!]`](#string) | URLs to skip during an authenticated scan. |
+| <a id="mutationdastsiteprofileupdatefullpath"></a>`fullPath` | [`ID!`](#id) | Project the site profile belongs to. |
| <a id="mutationdastsiteprofileupdateid"></a>`id` | [`DastSiteProfileID!`](#dastsiteprofileid) | ID of the site profile to be updated. |
-| <a id="mutationdastsiteprofileupdateprofilename"></a>`profileName` | [`String!`](#string) | The name of the site profile. |
+| <a id="mutationdastsiteprofileupdateprofilename"></a>`profileName` | [`String!`](#string) | Name of the site profile. |
| <a id="mutationdastsiteprofileupdaterequestheaders"></a>`requestHeaders` | [`String`](#string) | Comma-separated list of request header names and values to be added to every request made by DAST. |
-| <a id="mutationdastsiteprofileupdatetargettype"></a>`targetType` | [`DastTargetTypeEnum`](#dasttargettypeenum) | The type of target to be scanned. |
-| <a id="mutationdastsiteprofileupdatetargeturl"></a>`targetUrl` | [`String`](#string) | The URL of the target to be scanned. |
+| <a id="mutationdastsiteprofileupdatetargettype"></a>`targetType` | [`DastTargetTypeEnum`](#dasttargettypeenum) | Type of target to be scanned. |
+| <a id="mutationdastsiteprofileupdatetargeturl"></a>`targetUrl` | [`String`](#string) | URL of the target to be scanned. |
#### Fields
@@ -1667,8 +1715,8 @@ Input type: `DastSiteTokenCreateInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationdastsitetokencreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationdastsitetokencreatefullpath"></a>`fullPath` | [`ID!`](#id) | The project the site token belongs to. |
-| <a id="mutationdastsitetokencreatetargeturl"></a>`targetUrl` | [`String`](#string) | The URL of the target to be validated. |
+| <a id="mutationdastsitetokencreatefullpath"></a>`fullPath` | [`ID!`](#id) | Project the site token belongs to. |
+| <a id="mutationdastsitetokencreatetargeturl"></a>`targetUrl` | [`String`](#string) | URL of the target to be validated. |
#### Fields
@@ -1677,7 +1725,7 @@ Input type: `DastSiteTokenCreateInput`
| <a id="mutationdastsitetokencreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationdastsitetokencreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationdastsitetokencreateid"></a>`id` | [`DastSiteTokenID`](#dastsitetokenid) | ID of the site token. |
-| <a id="mutationdastsitetokencreatestatus"></a>`status` | [`DastSiteProfileValidationStatusEnum`](#dastsiteprofilevalidationstatusenum) | The current validation status of the target. |
+| <a id="mutationdastsitetokencreatestatus"></a>`status` | [`DastSiteProfileValidationStatusEnum`](#dastsiteprofilevalidationstatusenum) | Current validation status of the target. |
| <a id="mutationdastsitetokencreatetoken"></a>`token` | [`String`](#string) | Token string. |
### `Mutation.dastSiteValidationCreate`
@@ -1690,9 +1738,9 @@ Input type: `DastSiteValidationCreateInput`
| ---- | ---- | ----------- |
| <a id="mutationdastsitevalidationcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationdastsitevalidationcreatedastsitetokenid"></a>`dastSiteTokenId` | [`DastSiteTokenID!`](#dastsitetokenid) | ID of the site token. |
-| <a id="mutationdastsitevalidationcreatefullpath"></a>`fullPath` | [`ID!`](#id) | The project the site profile belongs to. |
-| <a id="mutationdastsitevalidationcreatestrategy"></a>`strategy` | [`DastSiteValidationStrategyEnum`](#dastsitevalidationstrategyenum) | The validation strategy to be used. |
-| <a id="mutationdastsitevalidationcreatevalidationpath"></a>`validationPath` | [`String!`](#string) | The path to be requested during validation. |
+| <a id="mutationdastsitevalidationcreatefullpath"></a>`fullPath` | [`ID!`](#id) | Project the site profile belongs to. |
+| <a id="mutationdastsitevalidationcreatestrategy"></a>`strategy` | [`DastSiteValidationStrategyEnum`](#dastsitevalidationstrategyenum) | Validation strategy to be used. |
+| <a id="mutationdastsitevalidationcreatevalidationpath"></a>`validationPath` | [`String!`](#string) | Path to be requested during validation. |
#### Fields
@@ -1701,7 +1749,7 @@ Input type: `DastSiteValidationCreateInput`
| <a id="mutationdastsitevalidationcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationdastsitevalidationcreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationdastsitevalidationcreateid"></a>`id` | [`DastSiteValidationID`](#dastsitevalidationid) | ID of the site validation. |
-| <a id="mutationdastsitevalidationcreatestatus"></a>`status` | [`DastSiteProfileValidationStatusEnum`](#dastsiteprofilevalidationstatusenum) | The current validation status. |
+| <a id="mutationdastsitevalidationcreatestatus"></a>`status` | [`DastSiteProfileValidationStatusEnum`](#dastsiteprofilevalidationstatusenum) | Current validation status. |
### `Mutation.dastSiteValidationRevoke`
@@ -1712,7 +1760,7 @@ Input type: `DastSiteValidationRevokeInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationdastsitevalidationrevokeclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationdastsitevalidationrevokefullpath"></a>`fullPath` | [`ID!`](#id) | The project the site validation belongs to. |
+| <a id="mutationdastsitevalidationrevokefullpath"></a>`fullPath` | [`ID!`](#id) | Project the site validation belongs to. |
| <a id="mutationdastsitevalidationrevokenormalizedtargeturl"></a>`normalizedTargetUrl` | [`String!`](#string) | Normalized URL of the target to be revoked. |
#### Fields
@@ -1851,7 +1899,7 @@ Input type: `DestroyComplianceFrameworkInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationdestroycomplianceframeworkclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationdestroycomplianceframeworkid"></a>`id` | [`ComplianceManagementFrameworkID!`](#compliancemanagementframeworkid) | The global ID of the compliance framework to destroy. |
+| <a id="mutationdestroycomplianceframeworkid"></a>`id` | [`ComplianceManagementFrameworkID!`](#compliancemanagementframeworkid) | Global ID of the compliance framework to destroy. |
#### Fields
@@ -1899,6 +1947,27 @@ Input type: `DestroyContainerRepositoryTagsInput`
| <a id="mutationdestroycontainerrepositorytagsdeletedtagnames"></a>`deletedTagNames` | [`[String!]!`](#string) | Deleted container repository tags. |
| <a id="mutationdestroycontainerrepositorytagserrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+### `Mutation.destroyCustomEmoji`
+
+Available only when feature flag `custom_emoji` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice.
+
+Input type: `DestroyCustomEmojiInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationdestroycustomemojiclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationdestroycustomemojiid"></a>`id` | [`CustomEmojiID!`](#customemojiid) | Global ID of the custom emoji to destroy. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationdestroycustomemojiclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationdestroycustomemojicustomemoji"></a>`customEmoji` | [`CustomEmoji`](#customemoji) | Deleted custom emoji. |
+| <a id="mutationdestroycustomemojierrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+
### `Mutation.destroyEpicBoard`
Input type: `DestroyEpicBoardInput`
@@ -2109,18 +2178,18 @@ Input type: `EpicAddIssueInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationepicaddissueclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationepicaddissuegrouppath"></a>`groupPath` | [`ID!`](#id) | The group the epic to mutate belongs to. |
-| <a id="mutationepicaddissueiid"></a>`iid` | [`ID!`](#id) | The IID of the epic to mutate. |
-| <a id="mutationepicaddissueissueiid"></a>`issueIid` | [`String!`](#string) | The IID of the issue to be added. |
-| <a id="mutationepicaddissueprojectpath"></a>`projectPath` | [`ID!`](#id) | The full path of the project the issue belongs to. |
+| <a id="mutationepicaddissuegrouppath"></a>`groupPath` | [`ID!`](#id) | Group the epic to mutate belongs to. |
+| <a id="mutationepicaddissueiid"></a>`iid` | [`ID!`](#id) | IID of the epic to mutate. |
+| <a id="mutationepicaddissueissueiid"></a>`issueIid` | [`String!`](#string) | IID of the issue to be added. |
+| <a id="mutationepicaddissueprojectpath"></a>`projectPath` | [`ID!`](#id) | Full path of the project the issue belongs to. |
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationepicaddissueclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationepicaddissueepic"></a>`epic` | [`Epic`](#epic) | The epic after mutation. |
-| <a id="mutationepicaddissueepicissue"></a>`epicIssue` | [`EpicIssue`](#epicissue) | The epic-issue relation. |
+| <a id="mutationepicaddissueepic"></a>`epic` | [`Epic`](#epic) | Epic after mutation. |
+| <a id="mutationepicaddissueepicissue"></a>`epicIssue` | [`EpicIssue`](#epicissue) | Epic-issue relationship. |
| <a id="mutationepicaddissueerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
### `Mutation.epicBoardCreate`
@@ -2144,7 +2213,7 @@ Input type: `EpicBoardCreateInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationepicboardcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationepicboardcreateepicboard"></a>`epicBoard` | [`EpicBoard`](#epicboard) | The created epic board. |
+| <a id="mutationepicboardcreateepicboard"></a>`epicBoard` | [`EpicBoard`](#epicboard) | Created epic board. |
| <a id="mutationepicboardcreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
### `Mutation.epicBoardListCreate`
@@ -2187,7 +2256,7 @@ Input type: `EpicBoardListDestroyInput`
| ---- | ---- | ----------- |
| <a id="mutationepicboardlistdestroyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationepicboardlistdestroyerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationepicboardlistdestroylist"></a>`list` | [`EpicList`](#epiclist) | The epic board list. `null` if the board was destroyed successfully. |
+| <a id="mutationepicboardlistdestroylist"></a>`list` | [`EpicList`](#epiclist) | Epic board list. `null` if the board was destroyed successfully. |
### `Mutation.epicBoardUpdate`
@@ -2200,7 +2269,7 @@ Input type: `EpicBoardUpdateInput`
| <a id="mutationepicboardupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationepicboardupdatehidebackloglist"></a>`hideBacklogList` | [`Boolean`](#boolean) | Whether or not backlog list is hidden. |
| <a id="mutationepicboardupdatehideclosedlist"></a>`hideClosedList` | [`Boolean`](#boolean) | Whether or not closed list is hidden. |
-| <a id="mutationepicboardupdateid"></a>`id` | [`BoardsEpicBoardID!`](#boardsepicboardid) | The epic board global ID. |
+| <a id="mutationepicboardupdateid"></a>`id` | [`BoardsEpicBoardID!`](#boardsepicboardid) | Epic board global ID. |
| <a id="mutationepicboardupdatelabelids"></a>`labelIds` | [`[LabelID!]`](#labelid) | IDs of labels to be added to the board. |
| <a id="mutationepicboardupdatelabels"></a>`labels` | [`[String!]`](#string) | Labels of the issue. |
| <a id="mutationepicboardupdatename"></a>`name` | [`String`](#string) | Board name. |
@@ -2210,7 +2279,7 @@ Input type: `EpicBoardUpdateInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationepicboardupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationepicboardupdateepicboard"></a>`epicBoard` | [`EpicBoard`](#epicboard) | The updated epic board. |
+| <a id="mutationepicboardupdateepicboard"></a>`epicBoard` | [`EpicBoard`](#epicboard) | Updated epic board. |
| <a id="mutationepicboardupdateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
### `Mutation.epicMoveList`
@@ -2234,7 +2303,7 @@ Input type: `EpicMoveListInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationepicmovelistclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationepicmovelistepic"></a>`epic` | [`Epic`](#epic) | The epic after mutation. |
+| <a id="mutationepicmovelistepic"></a>`epic` | [`Epic`](#epic) | Epic after mutation. |
| <a id="mutationepicmovelisterrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
### `Mutation.epicSetSubscription`
@@ -2246,16 +2315,16 @@ Input type: `EpicSetSubscriptionInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationepicsetsubscriptionclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationepicsetsubscriptiongrouppath"></a>`groupPath` | [`ID!`](#id) | The group the epic to mutate belongs to. |
-| <a id="mutationepicsetsubscriptioniid"></a>`iid` | [`ID!`](#id) | The IID of the epic to mutate. |
-| <a id="mutationepicsetsubscriptionsubscribedstate"></a>`subscribedState` | [`Boolean!`](#boolean) | The desired state of the subscription. |
+| <a id="mutationepicsetsubscriptiongrouppath"></a>`groupPath` | [`ID!`](#id) | Group the epic to mutate belongs to. |
+| <a id="mutationepicsetsubscriptioniid"></a>`iid` | [`ID!`](#id) | IID of the epic to mutate. |
+| <a id="mutationepicsetsubscriptionsubscribedstate"></a>`subscribedState` | [`Boolean!`](#boolean) | Desired state of the subscription. |
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationepicsetsubscriptionclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationepicsetsubscriptionepic"></a>`epic` | [`Epic`](#epic) | The epic after mutation. |
+| <a id="mutationepicsetsubscriptionepic"></a>`epic` | [`Epic`](#epic) | Epic after mutation. |
| <a id="mutationepicsetsubscriptionerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
### `Mutation.epicTreeReorder`
@@ -2266,7 +2335,7 @@ Input type: `EpicTreeReorderInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="mutationepictreereorderbaseepicid"></a>`baseEpicId` | [`EpicID!`](#epicid) | The ID of the base epic of the tree. |
+| <a id="mutationepictreereorderbaseepicid"></a>`baseEpicId` | [`EpicID!`](#epicid) | ID of the base epic of the tree. |
| <a id="mutationepictreereorderclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationepictreereordermoved"></a>`moved` | [`EpicTreeNodeFieldsInputType!`](#epictreenodefieldsinputtype) | Parameters for updating the tree positions. |
@@ -2286,10 +2355,10 @@ Input type: `EscalationPolicyCreateInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationescalationpolicycreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationescalationpolicycreatedescription"></a>`description` | [`String`](#string) | The description of the escalation policy. |
-| <a id="mutationescalationpolicycreatename"></a>`name` | [`String!`](#string) | The name of the escalation policy. |
-| <a id="mutationescalationpolicycreateprojectpath"></a>`projectPath` | [`ID!`](#id) | The project to create the escalation policy for. |
-| <a id="mutationescalationpolicycreaterules"></a>`rules` | [`[EscalationRuleInput!]!`](#escalationruleinput) | The steps of the escalation policy. |
+| <a id="mutationescalationpolicycreatedescription"></a>`description` | [`String`](#string) | Description of the escalation policy. |
+| <a id="mutationescalationpolicycreatename"></a>`name` | [`String!`](#string) | Name of the escalation policy. |
+| <a id="mutationescalationpolicycreateprojectpath"></a>`projectPath` | [`ID!`](#id) | Project to create the escalation policy for. |
+| <a id="mutationescalationpolicycreaterules"></a>`rules` | [`[EscalationRuleInput!]!`](#escalationruleinput) | Steps of the escalation policy. |
#### Fields
@@ -2297,7 +2366,7 @@ Input type: `EscalationPolicyCreateInput`
| ---- | ---- | ----------- |
| <a id="mutationescalationpolicycreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationescalationpolicycreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationescalationpolicycreateescalationpolicy"></a>`escalationPolicy` | [`EscalationPolicyType`](#escalationpolicytype) | The escalation policy. |
+| <a id="mutationescalationpolicycreateescalationpolicy"></a>`escalationPolicy` | [`EscalationPolicyType`](#escalationpolicytype) | Escalation policy. |
### `Mutation.escalationPolicyDestroy`
@@ -2308,7 +2377,7 @@ Input type: `EscalationPolicyDestroyInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationescalationpolicydestroyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationescalationpolicydestroyid"></a>`id` | [`IncidentManagementEscalationPolicyID!`](#incidentmanagementescalationpolicyid) | The escalation policy internal ID to remove. |
+| <a id="mutationescalationpolicydestroyid"></a>`id` | [`IncidentManagementEscalationPolicyID!`](#incidentmanagementescalationpolicyid) | Escalation policy internal ID to remove. |
#### Fields
@@ -2316,7 +2385,7 @@ Input type: `EscalationPolicyDestroyInput`
| ---- | ---- | ----------- |
| <a id="mutationescalationpolicydestroyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationescalationpolicydestroyerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationescalationpolicydestroyescalationpolicy"></a>`escalationPolicy` | [`EscalationPolicyType`](#escalationpolicytype) | The escalation policy. |
+| <a id="mutationescalationpolicydestroyescalationpolicy"></a>`escalationPolicy` | [`EscalationPolicyType`](#escalationpolicytype) | Escalation policy. |
### `Mutation.escalationPolicyUpdate`
@@ -2327,10 +2396,10 @@ Input type: `EscalationPolicyUpdateInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationescalationpolicyupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationescalationpolicyupdatedescription"></a>`description` | [`String`](#string) | The description of the escalation policy. |
-| <a id="mutationescalationpolicyupdateid"></a>`id` | [`IncidentManagementEscalationPolicyID!`](#incidentmanagementescalationpolicyid) | The ID of the on-call schedule to create the on-call rotation in. |
-| <a id="mutationescalationpolicyupdatename"></a>`name` | [`String`](#string) | The name of the escalation policy. |
-| <a id="mutationescalationpolicyupdaterules"></a>`rules` | [`[EscalationRuleInput!]`](#escalationruleinput) | The steps of the escalation policy. |
+| <a id="mutationescalationpolicyupdatedescription"></a>`description` | [`String`](#string) | Description of the escalation policy. |
+| <a id="mutationescalationpolicyupdateid"></a>`id` | [`IncidentManagementEscalationPolicyID!`](#incidentmanagementescalationpolicyid) | ID of the on-call schedule to create the on-call rotation in. |
+| <a id="mutationescalationpolicyupdatename"></a>`name` | [`String`](#string) | Name of the escalation policy. |
+| <a id="mutationescalationpolicyupdaterules"></a>`rules` | [`[EscalationRuleInput!]`](#escalationruleinput) | Steps of the escalation policy. |
#### Fields
@@ -2338,7 +2407,7 @@ Input type: `EscalationPolicyUpdateInput`
| ---- | ---- | ----------- |
| <a id="mutationescalationpolicyupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationescalationpolicyupdateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationescalationpolicyupdateescalationpolicy"></a>`escalationPolicy` | [`EscalationPolicyType`](#escalationpolicytype) | The escalation policy. |
+| <a id="mutationescalationpolicyupdateescalationpolicy"></a>`escalationPolicy` | [`EscalationPolicyType`](#escalationpolicytype) | Escalation policy. |
### `Mutation.exportRequirements`
@@ -2380,7 +2449,7 @@ Input type: `GitlabSubscriptionActivateInput`
| ---- | ---- | ----------- |
| <a id="mutationgitlabsubscriptionactivateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationgitlabsubscriptionactivateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationgitlabsubscriptionactivatelicense"></a>`license` | [`CurrentLicense`](#currentlicense) | The current license. |
+| <a id="mutationgitlabsubscriptionactivatelicense"></a>`license` | [`CurrentLicense`](#currentlicense) | Current license. |
### `Mutation.groupUpdate`
@@ -2413,8 +2482,8 @@ Input type: `HttpIntegrationCreateInput`
| <a id="mutationhttpintegrationcreateactive"></a>`active` | [`Boolean!`](#boolean) | Whether the integration is receiving alerts. |
| <a id="mutationhttpintegrationcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationhttpintegrationcreatename"></a>`name` | [`String!`](#string) | Name of the integration. |
-| <a id="mutationhttpintegrationcreatepayloadattributemappings"></a>`payloadAttributeMappings` | [`[AlertManagementPayloadAlertFieldInput!]`](#alertmanagementpayloadalertfieldinput) | The custom mapping of GitLab alert attributes to fields from the payload_example. |
-| <a id="mutationhttpintegrationcreatepayloadexample"></a>`payloadExample` | [`JsonString`](#jsonstring) | The example of an alert payload. |
+| <a id="mutationhttpintegrationcreatepayloadattributemappings"></a>`payloadAttributeMappings` | [`[AlertManagementPayloadAlertFieldInput!]`](#alertmanagementpayloadalertfieldinput) | Custom mapping of GitLab alert attributes to fields from the payload example. |
+| <a id="mutationhttpintegrationcreatepayloadexample"></a>`payloadExample` | [`JsonString`](#jsonstring) | Example of an alert payload. |
| <a id="mutationhttpintegrationcreateprojectpath"></a>`projectPath` | [`ID!`](#id) | Project to create the integration in. |
#### Fields
@@ -2475,8 +2544,8 @@ Input type: `HttpIntegrationUpdateInput`
| <a id="mutationhttpintegrationupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationhttpintegrationupdateid"></a>`id` | [`AlertManagementHttpIntegrationID!`](#alertmanagementhttpintegrationid) | ID of the integration to mutate. |
| <a id="mutationhttpintegrationupdatename"></a>`name` | [`String`](#string) | Name of the integration. |
-| <a id="mutationhttpintegrationupdatepayloadattributemappings"></a>`payloadAttributeMappings` | [`[AlertManagementPayloadAlertFieldInput!]`](#alertmanagementpayloadalertfieldinput) | The custom mapping of GitLab alert attributes to fields from the payload_example. |
-| <a id="mutationhttpintegrationupdatepayloadexample"></a>`payloadExample` | [`JsonString`](#jsonstring) | The example of an alert payload. |
+| <a id="mutationhttpintegrationupdatepayloadattributemappings"></a>`payloadAttributeMappings` | [`[AlertManagementPayloadAlertFieldInput!]`](#alertmanagementpayloadalertfieldinput) | Custom mapping of GitLab alert attributes to fields from the payload example. |
+| <a id="mutationhttpintegrationupdatepayloadexample"></a>`payloadExample` | [`JsonString`](#jsonstring) | Example of an alert payload. |
#### Fields
@@ -2628,7 +2697,7 @@ Input type: `IssueSetIterationInput`
| ---- | ---- | ----------- |
| <a id="mutationissuesetiterationclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationissuesetiterationiid"></a>`iid` | [`String!`](#string) | IID of the issue to mutate. |
-| <a id="mutationissuesetiterationiterationid"></a>`iterationId` | [`IterationID`](#iterationid) | The iteration to assign to the issue. |
+| <a id="mutationissuesetiterationiterationid"></a>`iterationId` | [`IterationID`](#iterationid) | Iteration to assign to the issue. |
| <a id="mutationissuesetiterationprojectpath"></a>`projectPath` | [`ID!`](#id) | Project the issue to mutate is in. |
#### Fields
@@ -2736,7 +2805,7 @@ Input type: `IterationCadenceCreateInput`
| <a id="mutationiterationcadencecreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationiterationcadencecreatedescription"></a>`description` | [`String`](#string) | Description of the iteration cadence. Maximum length is 5000 characters. |
| <a id="mutationiterationcadencecreatedurationinweeks"></a>`durationInWeeks` | [`Int`](#int) | Duration in weeks of the iterations within this cadence. |
-| <a id="mutationiterationcadencecreategrouppath"></a>`groupPath` | [`ID!`](#id) | The group where the iteration cadence is created. |
+| <a id="mutationiterationcadencecreategrouppath"></a>`groupPath` | [`ID!`](#id) | Group where the iteration cadence is created. |
| <a id="mutationiterationcadencecreateiterationsinadvance"></a>`iterationsInAdvance` | [`Int`](#int) | Future iterations to be created when iteration cadence is set to automatic. |
| <a id="mutationiterationcadencecreaterollover"></a>`rollOver` | [`Boolean`](#boolean) | Whether the iteration cadence should roll over issues to the next iteration or not. |
| <a id="mutationiterationcadencecreatestartdate"></a>`startDate` | [`Time`](#time) | Timestamp of the iteration cadence start date. |
@@ -2748,7 +2817,7 @@ Input type: `IterationCadenceCreateInput`
| ---- | ---- | ----------- |
| <a id="mutationiterationcadencecreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationiterationcadencecreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationiterationcadencecreateiterationcadence"></a>`iterationCadence` | [`IterationCadence`](#iterationcadence) | The created iteration cadence. |
+| <a id="mutationiterationcadencecreateiterationcadence"></a>`iterationCadence` | [`IterationCadence`](#iterationcadence) | Created iteration cadence. |
### `Mutation.iterationCadenceDestroy`
@@ -2794,7 +2863,7 @@ Input type: `IterationCadenceUpdateInput`
| ---- | ---- | ----------- |
| <a id="mutationiterationcadenceupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationiterationcadenceupdateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationiterationcadenceupdateiterationcadence"></a>`iterationCadence` | [`IterationCadence`](#iterationcadence) | The updated iteration cadence. |
+| <a id="mutationiterationcadenceupdateiterationcadence"></a>`iterationCadence` | [`IterationCadence`](#iterationcadence) | Updated iteration cadence. |
### `Mutation.iterationCreate`
@@ -2805,13 +2874,13 @@ Input type: `iterationCreateInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationiterationcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationiterationcreatedescription"></a>`description` | [`String`](#string) | The description of the iteration. |
-| <a id="mutationiterationcreateduedate"></a>`dueDate` | [`String`](#string) | The end date of the iteration. |
+| <a id="mutationiterationcreatedescription"></a>`description` | [`String`](#string) | Description of the iteration. |
+| <a id="mutationiterationcreateduedate"></a>`dueDate` | [`String`](#string) | End date of the iteration. |
| <a id="mutationiterationcreategrouppath"></a>`groupPath` | [`ID`](#id) | Full path of the group with which the resource is associated. |
| <a id="mutationiterationcreateiterationscadenceid"></a>`iterationsCadenceId` | [`IterationsCadenceID`](#iterationscadenceid) | Global ID of the iterations cadence to be assigned to newly created iteration. |
| <a id="mutationiterationcreateprojectpath"></a>`projectPath` | [`ID`](#id) | Full path of the project with which the resource is associated. |
-| <a id="mutationiterationcreatestartdate"></a>`startDate` | [`String`](#string) | The start date of the iteration. |
-| <a id="mutationiterationcreatetitle"></a>`title` | [`String`](#string) | The title of the iteration. |
+| <a id="mutationiterationcreatestartdate"></a>`startDate` | [`String`](#string) | Start date of the iteration. |
+| <a id="mutationiterationcreatetitle"></a>`title` | [`String`](#string) | Title of the iteration. |
#### Fields
@@ -2819,7 +2888,7 @@ Input type: `iterationCreateInput`
| ---- | ---- | ----------- |
| <a id="mutationiterationcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationiterationcreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationiterationcreateiteration"></a>`iteration` | [`Iteration`](#iteration) | The created iteration. |
+| <a id="mutationiterationcreateiteration"></a>`iteration` | [`Iteration`](#iteration) | Created iteration. |
### `Mutation.iterationDelete`
@@ -3263,7 +3332,7 @@ Input type: `NamespaceIncreaseStorageTemporarilyInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationnamespaceincreasestoragetemporarilyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationnamespaceincreasestoragetemporarilyid"></a>`id` | [`NamespaceID!`](#namespaceid) | The global ID of the namespace to mutate. |
+| <a id="mutationnamespaceincreasestoragetemporarilyid"></a>`id` | [`NamespaceID!`](#namespaceid) | Global ID of the namespace to mutate. |
#### Fields
@@ -3271,7 +3340,7 @@ Input type: `NamespaceIncreaseStorageTemporarilyInput`
| ---- | ---- | ----------- |
| <a id="mutationnamespaceincreasestoragetemporarilyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationnamespaceincreasestoragetemporarilyerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationnamespaceincreasestoragetemporarilynamespace"></a>`namespace` | [`Namespace`](#namespace) | The namespace after mutation. |
+| <a id="mutationnamespaceincreasestoragetemporarilynamespace"></a>`namespace` | [`Namespace`](#namespace) | Namespace after mutation. |
### `Mutation.oncallRotationCreate`
@@ -3281,15 +3350,15 @@ Input type: `OncallRotationCreateInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="mutationoncallrotationcreateactiveperiod"></a>`activePeriod` | [`OncallRotationActivePeriodInputType`](#oncallrotationactiveperiodinputtype) | The active period of time that the on-call rotation should take place. |
+| <a id="mutationoncallrotationcreateactiveperiod"></a>`activePeriod` | [`OncallRotationActivePeriodInputType`](#oncallrotationactiveperiodinputtype) | Active period of time that the on-call rotation should take place. |
| <a id="mutationoncallrotationcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationoncallrotationcreateendsat"></a>`endsAt` | [`OncallRotationDateInputType`](#oncallrotationdateinputtype) | The end date and time of the on-call rotation, in the timezone of the on-call schedule. |
-| <a id="mutationoncallrotationcreatename"></a>`name` | [`String!`](#string) | The name of the on-call rotation. |
-| <a id="mutationoncallrotationcreateparticipants"></a>`participants` | [`[OncallUserInputType!]!`](#oncalluserinputtype) | The usernames of users participating in the on-call rotation. A maximum limit of 100 participants applies. |
-| <a id="mutationoncallrotationcreateprojectpath"></a>`projectPath` | [`ID!`](#id) | The project to create the on-call schedule in. |
-| <a id="mutationoncallrotationcreaterotationlength"></a>`rotationLength` | [`OncallRotationLengthInputType!`](#oncallrotationlengthinputtype) | The rotation length of the on-call rotation. |
-| <a id="mutationoncallrotationcreatescheduleiid"></a>`scheduleIid` | [`String!`](#string) | The IID of the on-call schedule to create the on-call rotation in. |
-| <a id="mutationoncallrotationcreatestartsat"></a>`startsAt` | [`OncallRotationDateInputType!`](#oncallrotationdateinputtype) | The start date and time of the on-call rotation, in the timezone of the on-call schedule. |
+| <a id="mutationoncallrotationcreateendsat"></a>`endsAt` | [`OncallRotationDateInputType`](#oncallrotationdateinputtype) | End date and time of the on-call rotation, in the timezone of the on-call schedule. |
+| <a id="mutationoncallrotationcreatename"></a>`name` | [`String!`](#string) | Name of the on-call rotation. |
+| <a id="mutationoncallrotationcreateparticipants"></a>`participants` | [`[OncallUserInputType!]!`](#oncalluserinputtype) | Usernames of users participating in the on-call rotation. A maximum limit of 100 participants applies. |
+| <a id="mutationoncallrotationcreateprojectpath"></a>`projectPath` | [`ID!`](#id) | Project to create the on-call schedule in. |
+| <a id="mutationoncallrotationcreaterotationlength"></a>`rotationLength` | [`OncallRotationLengthInputType!`](#oncallrotationlengthinputtype) | Rotation length of the on-call rotation. |
+| <a id="mutationoncallrotationcreatescheduleiid"></a>`scheduleIid` | [`String!`](#string) | IID of the on-call schedule to create the on-call rotation in. |
+| <a id="mutationoncallrotationcreatestartsat"></a>`startsAt` | [`OncallRotationDateInputType!`](#oncallrotationdateinputtype) | Start date and time of the on-call rotation, in the timezone of the on-call schedule. |
#### Fields
@@ -3297,7 +3366,7 @@ Input type: `OncallRotationCreateInput`
| ---- | ---- | ----------- |
| <a id="mutationoncallrotationcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationoncallrotationcreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationoncallrotationcreateoncallrotation"></a>`oncallRotation` | [`IncidentManagementOncallRotation`](#incidentmanagementoncallrotation) | The on-call rotation. |
+| <a id="mutationoncallrotationcreateoncallrotation"></a>`oncallRotation` | [`IncidentManagementOncallRotation`](#incidentmanagementoncallrotation) | On-call rotation. |
### `Mutation.oncallRotationDestroy`
@@ -3308,9 +3377,9 @@ Input type: `OncallRotationDestroyInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationoncallrotationdestroyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationoncallrotationdestroyid"></a>`id` | [`IncidentManagementOncallRotationID!`](#incidentmanagementoncallrotationid) | The ID of the on-call rotation to remove. |
-| <a id="mutationoncallrotationdestroyprojectpath"></a>`projectPath` | [`ID!`](#id) | The project to remove the on-call schedule from. |
-| <a id="mutationoncallrotationdestroyscheduleiid"></a>`scheduleIid` | [`String!`](#string) | The IID of the on-call schedule to the on-call rotation belongs to. |
+| <a id="mutationoncallrotationdestroyid"></a>`id` | [`IncidentManagementOncallRotationID!`](#incidentmanagementoncallrotationid) | ID of the on-call rotation to remove. |
+| <a id="mutationoncallrotationdestroyprojectpath"></a>`projectPath` | [`ID!`](#id) | Project to remove the on-call schedule from. |
+| <a id="mutationoncallrotationdestroyscheduleiid"></a>`scheduleIid` | [`String!`](#string) | IID of the on-call schedule to the on-call rotation belongs to. |
#### Fields
@@ -3318,7 +3387,7 @@ Input type: `OncallRotationDestroyInput`
| ---- | ---- | ----------- |
| <a id="mutationoncallrotationdestroyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationoncallrotationdestroyerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationoncallrotationdestroyoncallrotation"></a>`oncallRotation` | [`IncidentManagementOncallRotation`](#incidentmanagementoncallrotation) | The on-call rotation. |
+| <a id="mutationoncallrotationdestroyoncallrotation"></a>`oncallRotation` | [`IncidentManagementOncallRotation`](#incidentmanagementoncallrotation) | On-call rotation. |
### `Mutation.oncallRotationUpdate`
@@ -3328,14 +3397,14 @@ Input type: `OncallRotationUpdateInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="mutationoncallrotationupdateactiveperiod"></a>`activePeriod` | [`OncallRotationActivePeriodInputType`](#oncallrotationactiveperiodinputtype) | The active period of time that the on-call rotation should take place. |
+| <a id="mutationoncallrotationupdateactiveperiod"></a>`activePeriod` | [`OncallRotationActivePeriodInputType`](#oncallrotationactiveperiodinputtype) | Active period of time that the on-call rotation should take place. |
| <a id="mutationoncallrotationupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationoncallrotationupdateendsat"></a>`endsAt` | [`OncallRotationDateInputType`](#oncallrotationdateinputtype) | The end date and time of the on-call rotation, in the timezone of the on-call schedule. |
-| <a id="mutationoncallrotationupdateid"></a>`id` | [`IncidentManagementOncallRotationID!`](#incidentmanagementoncallrotationid) | The ID of the on-call schedule to create the on-call rotation in. |
-| <a id="mutationoncallrotationupdatename"></a>`name` | [`String`](#string) | The name of the on-call rotation. |
-| <a id="mutationoncallrotationupdateparticipants"></a>`participants` | [`[OncallUserInputType!]`](#oncalluserinputtype) | The usernames of users participating in the on-call rotation. A maximum limit of 100 participants applies. |
-| <a id="mutationoncallrotationupdaterotationlength"></a>`rotationLength` | [`OncallRotationLengthInputType`](#oncallrotationlengthinputtype) | The rotation length of the on-call rotation. |
-| <a id="mutationoncallrotationupdatestartsat"></a>`startsAt` | [`OncallRotationDateInputType`](#oncallrotationdateinputtype) | The start date and time of the on-call rotation, in the timezone of the on-call schedule. |
+| <a id="mutationoncallrotationupdateendsat"></a>`endsAt` | [`OncallRotationDateInputType`](#oncallrotationdateinputtype) | End date and time of the on-call rotation, in the timezone of the on-call schedule. |
+| <a id="mutationoncallrotationupdateid"></a>`id` | [`IncidentManagementOncallRotationID!`](#incidentmanagementoncallrotationid) | ID of the on-call schedule to create the on-call rotation in. |
+| <a id="mutationoncallrotationupdatename"></a>`name` | [`String`](#string) | Name of the on-call rotation. |
+| <a id="mutationoncallrotationupdateparticipants"></a>`participants` | [`[OncallUserInputType!]`](#oncalluserinputtype) | Usernames of users participating in the on-call rotation. A maximum limit of 100 participants applies. |
+| <a id="mutationoncallrotationupdaterotationlength"></a>`rotationLength` | [`OncallRotationLengthInputType`](#oncallrotationlengthinputtype) | Rotation length of the on-call rotation. |
+| <a id="mutationoncallrotationupdatestartsat"></a>`startsAt` | [`OncallRotationDateInputType`](#oncallrotationdateinputtype) | Start date and time of the on-call rotation, in the timezone of the on-call schedule. |
#### Fields
@@ -3343,7 +3412,7 @@ Input type: `OncallRotationUpdateInput`
| ---- | ---- | ----------- |
| <a id="mutationoncallrotationupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationoncallrotationupdateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationoncallrotationupdateoncallrotation"></a>`oncallRotation` | [`IncidentManagementOncallRotation`](#incidentmanagementoncallrotation) | The on-call rotation. |
+| <a id="mutationoncallrotationupdateoncallrotation"></a>`oncallRotation` | [`IncidentManagementOncallRotation`](#incidentmanagementoncallrotation) | On-call rotation. |
### `Mutation.oncallScheduleCreate`
@@ -3354,10 +3423,10 @@ Input type: `OncallScheduleCreateInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationoncallschedulecreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationoncallschedulecreatedescription"></a>`description` | [`String`](#string) | The description of the on-call schedule. |
-| <a id="mutationoncallschedulecreatename"></a>`name` | [`String!`](#string) | The name of the on-call schedule. |
-| <a id="mutationoncallschedulecreateprojectpath"></a>`projectPath` | [`ID!`](#id) | The project to create the on-call schedule in. |
-| <a id="mutationoncallschedulecreatetimezone"></a>`timezone` | [`String!`](#string) | The timezone of the on-call schedule. |
+| <a id="mutationoncallschedulecreatedescription"></a>`description` | [`String`](#string) | Description of the on-call schedule. |
+| <a id="mutationoncallschedulecreatename"></a>`name` | [`String!`](#string) | Name of the on-call schedule. |
+| <a id="mutationoncallschedulecreateprojectpath"></a>`projectPath` | [`ID!`](#id) | Project to create the on-call schedule in. |
+| <a id="mutationoncallschedulecreatetimezone"></a>`timezone` | [`String!`](#string) | Timezone of the on-call schedule. |
#### Fields
@@ -3365,7 +3434,7 @@ Input type: `OncallScheduleCreateInput`
| ---- | ---- | ----------- |
| <a id="mutationoncallschedulecreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationoncallschedulecreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationoncallschedulecreateoncallschedule"></a>`oncallSchedule` | [`IncidentManagementOncallSchedule`](#incidentmanagementoncallschedule) | The on-call schedule. |
+| <a id="mutationoncallschedulecreateoncallschedule"></a>`oncallSchedule` | [`IncidentManagementOncallSchedule`](#incidentmanagementoncallschedule) | On-call schedule. |
### `Mutation.oncallScheduleDestroy`
@@ -3376,8 +3445,8 @@ Input type: `OncallScheduleDestroyInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationoncallscheduledestroyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationoncallscheduledestroyiid"></a>`iid` | [`String!`](#string) | The on-call schedule internal ID to remove. |
-| <a id="mutationoncallscheduledestroyprojectpath"></a>`projectPath` | [`ID!`](#id) | The project to remove the on-call schedule from. |
+| <a id="mutationoncallscheduledestroyiid"></a>`iid` | [`String!`](#string) | On-call schedule internal ID to remove. |
+| <a id="mutationoncallscheduledestroyprojectpath"></a>`projectPath` | [`ID!`](#id) | Project to remove the on-call schedule from. |
#### Fields
@@ -3385,7 +3454,7 @@ Input type: `OncallScheduleDestroyInput`
| ---- | ---- | ----------- |
| <a id="mutationoncallscheduledestroyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationoncallscheduledestroyerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationoncallscheduledestroyoncallschedule"></a>`oncallSchedule` | [`IncidentManagementOncallSchedule`](#incidentmanagementoncallschedule) | The on-call schedule. |
+| <a id="mutationoncallscheduledestroyoncallschedule"></a>`oncallSchedule` | [`IncidentManagementOncallSchedule`](#incidentmanagementoncallschedule) | On-call schedule. |
### `Mutation.oncallScheduleUpdate`
@@ -3396,11 +3465,11 @@ Input type: `OncallScheduleUpdateInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationoncallscheduleupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationoncallscheduleupdatedescription"></a>`description` | [`String`](#string) | The description of the on-call schedule. |
-| <a id="mutationoncallscheduleupdateiid"></a>`iid` | [`String!`](#string) | The on-call schedule internal ID to update. |
-| <a id="mutationoncallscheduleupdatename"></a>`name` | [`String`](#string) | The name of the on-call schedule. |
-| <a id="mutationoncallscheduleupdateprojectpath"></a>`projectPath` | [`ID!`](#id) | The project to update the on-call schedule in. |
-| <a id="mutationoncallscheduleupdatetimezone"></a>`timezone` | [`String`](#string) | The timezone of the on-call schedule. |
+| <a id="mutationoncallscheduleupdatedescription"></a>`description` | [`String`](#string) | Description of the on-call schedule. |
+| <a id="mutationoncallscheduleupdateiid"></a>`iid` | [`String!`](#string) | On-call schedule internal ID to update. |
+| <a id="mutationoncallscheduleupdatename"></a>`name` | [`String`](#string) | Name of the on-call schedule. |
+| <a id="mutationoncallscheduleupdateprojectpath"></a>`projectPath` | [`ID!`](#id) | Project to update the on-call schedule in. |
+| <a id="mutationoncallscheduleupdatetimezone"></a>`timezone` | [`String`](#string) | Timezone of the on-call schedule. |
#### Fields
@@ -3408,7 +3477,7 @@ Input type: `OncallScheduleUpdateInput`
| ---- | ---- | ----------- |
| <a id="mutationoncallscheduleupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationoncallscheduleupdateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationoncallscheduleupdateoncallschedule"></a>`oncallSchedule` | [`IncidentManagementOncallSchedule`](#incidentmanagementoncallschedule) | The on-call schedule. |
+| <a id="mutationoncallscheduleupdateoncallschedule"></a>`oncallSchedule` | [`IncidentManagementOncallSchedule`](#incidentmanagementoncallschedule) | On-call schedule. |
### `Mutation.pipelineCancel`
@@ -3578,7 +3647,7 @@ Input type: `PromoteToEpicInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationpromotetoepicclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationpromotetoepicgrouppath"></a>`groupPath` | [`ID`](#id) | The group the promoted epic will belong to. |
+| <a id="mutationpromotetoepicgrouppath"></a>`groupPath` | [`ID`](#id) | Group the promoted epic will belong to. |
| <a id="mutationpromotetoepiciid"></a>`iid` | [`String!`](#string) | IID of the issue to mutate. |
| <a id="mutationpromotetoepicprojectpath"></a>`projectPath` | [`ID!`](#id) | Project the issue to mutate is in. |
@@ -3587,7 +3656,7 @@ Input type: `PromoteToEpicInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationpromotetoepicclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationpromotetoepicepic"></a>`epic` | [`Epic`](#epic) | The epic after issue promotion. |
+| <a id="mutationpromotetoepicepic"></a>`epic` | [`Epic`](#epic) | Epic after issue promotion. |
| <a id="mutationpromotetoepicerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationpromotetoepicissue"></a>`issue` | [`Issue`](#issue) | Issue after mutation. |
@@ -3601,7 +3670,7 @@ Input type: `ReleaseAssetLinkCreateInput`
| ---- | ---- | ----------- |
| <a id="mutationreleaseassetlinkcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationreleaseassetlinkcreatedirectassetpath"></a>`directAssetPath` | [`String`](#string) | Relative path for a direct asset link. |
-| <a id="mutationreleaseassetlinkcreatelinktype"></a>`linkType` | [`ReleaseAssetLinkType`](#releaseassetlinktype) | The type of the asset link. |
+| <a id="mutationreleaseassetlinkcreatelinktype"></a>`linkType` | [`ReleaseAssetLinkType`](#releaseassetlinktype) | Type of the asset link. |
| <a id="mutationreleaseassetlinkcreatename"></a>`name` | [`String!`](#string) | Name of the asset link. |
| <a id="mutationreleaseassetlinkcreateprojectpath"></a>`projectPath` | [`ID!`](#id) | Full path of the project the asset link is associated with. |
| <a id="mutationreleaseassetlinkcreatetagname"></a>`tagName` | [`String!`](#string) | Name of the associated release's tag. |
@@ -3757,7 +3826,7 @@ Input type: `RepositionImageDiffNoteInput`
| ---- | ---- | ----------- |
| <a id="mutationrepositionimagediffnoteclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationrepositionimagediffnoteid"></a>`id` | [`DiffNoteID!`](#diffnoteid) | Global ID of the DiffNote to update. |
-| <a id="mutationrepositionimagediffnoteposition"></a>`position` | [`UpdateDiffImagePositionInput!`](#updatediffimagepositioninput) | The position of this note on a diff. |
+| <a id="mutationrepositionimagediffnoteposition"></a>`position` | [`UpdateDiffImagePositionInput!`](#updatediffimagepositioninput) | Position of this note on a diff. |
#### Fields
@@ -3769,8 +3838,6 @@ Input type: `RepositionImageDiffNoteInput`
### `Mutation.runnerDelete`
-Available only when feature flag `runner_graphql_query` is enabled. This flag is enabled by default.
-
Input type: `RunnerDeleteInput`
#### Arguments
@@ -3789,8 +3856,6 @@ Input type: `RunnerDeleteInput`
### `Mutation.runnerUpdate`
-Available only when feature flag `runner_graphql_query` is enabled. This flag is enabled by default.
-
Input type: `RunnerUpdateInput`
#### Arguments
@@ -3819,8 +3884,6 @@ Input type: `RunnerUpdateInput`
### `Mutation.runnersRegistrationTokenReset`
-Available only when feature flag `runner_graphql_query` is enabled. This flag is enabled by default.
-
Input type: `RunnersRegistrationTokenResetInput`
#### Arguments
@@ -4082,6 +4145,7 @@ Input type: `UpdateBoardInput`
| <a id="mutationupdateboardhidebackloglist"></a>`hideBacklogList` | [`Boolean`](#boolean) | Whether or not backlog list is hidden. |
| <a id="mutationupdateboardhideclosedlist"></a>`hideClosedList` | [`Boolean`](#boolean) | Whether or not closed list is hidden. |
| <a id="mutationupdateboardid"></a>`id` | [`BoardID!`](#boardid) | Board global ID. |
+| <a id="mutationupdateboarditerationcadenceid"></a>`iterationCadenceId` | [`IterationsCadenceID`](#iterationscadenceid) | ID of iteration cadence to be assigned to the board. |
| <a id="mutationupdateboarditerationid"></a>`iterationId` | [`IterationID`](#iterationid) | ID of iteration to be assigned to the board. |
| <a id="mutationupdateboardlabelids"></a>`labelIds` | [`[LabelID!]`](#labelid) | IDs of labels to be added to the board. |
| <a id="mutationupdateboardlabels"></a>`labels` | [`[String!]`](#string) | Labels of the issue. |
@@ -4105,7 +4169,7 @@ Input type: `UpdateBoardEpicUserPreferencesInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="mutationupdateboardepicuserpreferencesboardid"></a>`boardId` | [`BoardID!`](#boardid) | The board global ID. |
+| <a id="mutationupdateboardepicuserpreferencesboardid"></a>`boardId` | [`BoardID!`](#boardid) | Board global ID. |
| <a id="mutationupdateboardepicuserpreferencesclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationupdateboardepicuserpreferencescollapsed"></a>`collapsed` | [`Boolean!`](#boolean) | Whether the epic should be collapsed in the board. |
| <a id="mutationupdateboardepicuserpreferencesepicid"></a>`epicId` | [`EpicID!`](#epicid) | ID of an epic to set preferences for. |
@@ -4148,7 +4212,7 @@ Input type: `UpdateComplianceFrameworkInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationupdatecomplianceframeworkclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationupdatecomplianceframeworkid"></a>`id` | [`ComplianceManagementFrameworkID!`](#compliancemanagementframeworkid) | The global ID of the compliance framework to update. |
+| <a id="mutationupdatecomplianceframeworkid"></a>`id` | [`ComplianceManagementFrameworkID!`](#compliancemanagementframeworkid) | Global ID of the compliance framework to update. |
| <a id="mutationupdatecomplianceframeworkparams"></a>`params` | [`ComplianceFrameworkInput!`](#complianceframeworkinput) | Parameters to update the compliance framework with. |
#### Fields
@@ -4156,7 +4220,7 @@ Input type: `UpdateComplianceFrameworkInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationupdatecomplianceframeworkclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationupdatecomplianceframeworkcomplianceframework"></a>`complianceFramework` | [`ComplianceFramework`](#complianceframework) | The compliance framework after mutation. |
+| <a id="mutationupdatecomplianceframeworkcomplianceframework"></a>`complianceFramework` | [`ComplianceFramework`](#complianceframework) | Compliance framework after mutation. |
| <a id="mutationupdatecomplianceframeworkerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
### `Mutation.updateContainerExpirationPolicy`
@@ -4184,6 +4248,27 @@ Input type: `UpdateContainerExpirationPolicyInput`
| <a id="mutationupdatecontainerexpirationpolicycontainerexpirationpolicy"></a>`containerExpirationPolicy` | [`ContainerExpirationPolicy`](#containerexpirationpolicy) | Container expiration policy after mutation. |
| <a id="mutationupdatecontainerexpirationpolicyerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+### `Mutation.updateDependencyProxyImageTtlGroupPolicy`
+
+Input type: `UpdateDependencyProxyImageTtlGroupPolicyInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationupdatedependencyproxyimagettlgrouppolicyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationupdatedependencyproxyimagettlgrouppolicyenabled"></a>`enabled` | [`Boolean`](#boolean) | Indicates whether the policy is enabled or disabled. |
+| <a id="mutationupdatedependencyproxyimagettlgrouppolicygrouppath"></a>`groupPath` | [`ID!`](#id) | Group path for the group dependency proxy image TTL policy. |
+| <a id="mutationupdatedependencyproxyimagettlgrouppolicyttl"></a>`ttl` | [`Int`](#int) | Number of days to retain a cached image file. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationupdatedependencyproxyimagettlgrouppolicyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationupdatedependencyproxyimagettlgrouppolicydependencyproxyimagettlpolicy"></a>`dependencyProxyImageTtlPolicy` | [`DependencyProxyImageTtlGroupPolicy`](#dependencyproxyimagettlgrouppolicy) | Group image TTL policy after mutation. |
+| <a id="mutationupdatedependencyproxyimagettlgrouppolicyerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+
### `Mutation.updateEpic`
Input type: `UpdateEpicInput`
@@ -4192,26 +4277,26 @@ Input type: `UpdateEpicInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="mutationupdateepicaddlabelids"></a>`addLabelIds` | [`[ID!]`](#id) | The IDs of labels to be added to the epic. |
+| <a id="mutationupdateepicaddlabelids"></a>`addLabelIds` | [`[ID!]`](#id) | IDs of labels to be added to the epic. |
| <a id="mutationupdateepicclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationupdateepicconfidential"></a>`confidential` | [`Boolean`](#boolean) | Indicates if the epic is confidential. |
-| <a id="mutationupdateepicdescription"></a>`description` | [`String`](#string) | The description of the epic. |
-| <a id="mutationupdateepicduedatefixed"></a>`dueDateFixed` | [`String`](#string) | The end date of the epic. |
+| <a id="mutationupdateepicdescription"></a>`description` | [`String`](#string) | Description of the epic. |
+| <a id="mutationupdateepicduedatefixed"></a>`dueDateFixed` | [`String`](#string) | End date of the epic. |
| <a id="mutationupdateepicduedateisfixed"></a>`dueDateIsFixed` | [`Boolean`](#boolean) | Indicates end date should be sourced from due_date_fixed field not the issue milestones. |
-| <a id="mutationupdateepicgrouppath"></a>`groupPath` | [`ID!`](#id) | The group the epic to mutate is in. |
-| <a id="mutationupdateepiciid"></a>`iid` | [`ID!`](#id) | The IID of the epic to mutate. |
-| <a id="mutationupdateepicremovelabelids"></a>`removeLabelIds` | [`[ID!]`](#id) | The IDs of labels to be removed from the epic. |
-| <a id="mutationupdateepicstartdatefixed"></a>`startDateFixed` | [`String`](#string) | The start date of the epic. |
+| <a id="mutationupdateepicgrouppath"></a>`groupPath` | [`ID!`](#id) | Group the epic to mutate is in. |
+| <a id="mutationupdateepiciid"></a>`iid` | [`ID!`](#id) | IID of the epic to mutate. |
+| <a id="mutationupdateepicremovelabelids"></a>`removeLabelIds` | [`[ID!]`](#id) | IDs of labels to be removed from the epic. |
+| <a id="mutationupdateepicstartdatefixed"></a>`startDateFixed` | [`String`](#string) | Start date of the epic. |
| <a id="mutationupdateepicstartdateisfixed"></a>`startDateIsFixed` | [`Boolean`](#boolean) | Indicates start date should be sourced from start_date_fixed field not the issue milestones. |
| <a id="mutationupdateepicstateevent"></a>`stateEvent` | [`EpicStateEvent`](#epicstateevent) | State event for the epic. |
-| <a id="mutationupdateepictitle"></a>`title` | [`String`](#string) | The title of the epic. |
+| <a id="mutationupdateepictitle"></a>`title` | [`String`](#string) | Title of the epic. |
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationupdateepicclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationupdateepicepic"></a>`epic` | [`Epic`](#epic) | The epic after mutation. |
+| <a id="mutationupdateepicepic"></a>`epic` | [`Epic`](#epic) | Epic after mutation. |
| <a id="mutationupdateepicerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
### `Mutation.updateEpicBoardList`
@@ -4251,7 +4336,7 @@ Input type: `UpdateImageDiffNoteInput`
| <a id="mutationupdateimagediffnotebody"></a>`body` | [`String`](#string) | Content of the note. |
| <a id="mutationupdateimagediffnoteclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationupdateimagediffnoteid"></a>`id` | [`NoteID!`](#noteid) | Global ID of the note to update. |
-| <a id="mutationupdateimagediffnoteposition"></a>`position` | [`UpdateDiffImagePositionInput`](#updatediffimagepositioninput) | The position of this note on a diff. |
+| <a id="mutationupdateimagediffnoteposition"></a>`position` | [`UpdateDiffImagePositionInput`](#updatediffimagepositioninput) | Position of this note on a diff. |
#### Fields
@@ -4274,8 +4359,8 @@ Input type: `UpdateIssueInput`
| <a id="mutationupdateissueconfidential"></a>`confidential` | [`Boolean`](#boolean) | Indicates the issue is confidential. |
| <a id="mutationupdateissuedescription"></a>`description` | [`String`](#string) | Description of the issue. |
| <a id="mutationupdateissueduedate"></a>`dueDate` | [`ISO8601Date`](#iso8601date) | Due date of the issue. |
-| <a id="mutationupdateissueepicid"></a>`epicId` | [`EpicID`](#epicid) | The ID of the parent epic. NULL when removing the association. |
-| <a id="mutationupdateissuehealthstatus"></a>`healthStatus` | [`HealthStatus`](#healthstatus) | The desired health status. |
+| <a id="mutationupdateissueepicid"></a>`epicId` | [`EpicID`](#epicid) | ID of the parent epic. NULL when removing the association. |
+| <a id="mutationupdateissuehealthstatus"></a>`healthStatus` | [`HealthStatus`](#healthstatus) | Desired health status. |
| <a id="mutationupdateissueiid"></a>`iid` | [`String!`](#string) | IID of the issue to mutate. |
| <a id="mutationupdateissuelabelids"></a>`labelIds` | [`[ID!]`](#id) | IDs of labels to be set. Replaces existing issue labels. |
| <a id="mutationupdateissuelocked"></a>`locked` | [`Boolean`](#boolean) | Indicates discussion is locked on the issue. |
@@ -4285,7 +4370,7 @@ Input type: `UpdateIssueInput`
| <a id="mutationupdateissuestateevent"></a>`stateEvent` | [`IssueStateEvent`](#issuestateevent) | Close or reopen an issue. |
| <a id="mutationupdateissuetitle"></a>`title` | [`String`](#string) | Title of the issue. |
| <a id="mutationupdateissuetype"></a>`type` | [`IssueType`](#issuetype) | Type of the issue. |
-| <a id="mutationupdateissueweight"></a>`weight` | [`Int`](#int) | The weight of the issue. |
+| <a id="mutationupdateissueweight"></a>`weight` | [`Int`](#int) | Weight of the issue. |
#### Fields
@@ -4378,7 +4463,7 @@ Input type: `UpdateRequirementInput`
| ---- | ---- | ----------- |
| <a id="mutationupdaterequirementclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationupdaterequirementdescription"></a>`description` | [`String`](#string) | Description of the requirement. |
-| <a id="mutationupdaterequirementiid"></a>`iid` | [`String!`](#string) | The IID of the requirement to update. |
+| <a id="mutationupdaterequirementiid"></a>`iid` | [`String!`](#string) | IID of the requirement to update. |
| <a id="mutationupdaterequirementlasttestreportstate"></a>`lastTestReportState` | [`TestReportState`](#testreportstate) | Creates a test report for the requirement with the given state. |
| <a id="mutationupdaterequirementprojectpath"></a>`projectPath` | [`ID!`](#id) | Full project path the requirement is associated with. |
| <a id="mutationupdaterequirementstate"></a>`state` | [`RequirementState`](#requirementstate) | State of the requirement. |
@@ -4457,7 +4542,39 @@ Input type: `VulnerabilityConfirmInput`
| ---- | ---- | ----------- |
| <a id="mutationvulnerabilityconfirmclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationvulnerabilityconfirmerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationvulnerabilityconfirmvulnerability"></a>`vulnerability` | [`Vulnerability`](#vulnerability) | The vulnerability after state change. |
+| <a id="mutationvulnerabilityconfirmvulnerability"></a>`vulnerability` | [`Vulnerability`](#vulnerability) | Vulnerability after state change. |
+
+### `Mutation.vulnerabilityCreate`
+
+Input type: `VulnerabilityCreateInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationvulnerabilitycreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationvulnerabilitycreateconfidence"></a>`confidence` | [`VulnerabilityConfidence`](#vulnerabilityconfidence) | Confidence of the vulnerability (defaults to `unknown`). |
+| <a id="mutationvulnerabilitycreateconfirmedat"></a>`confirmedAt` | [`Time`](#time) | Timestamp of when the vulnerability state changed to confirmed (defaults to creation time if status is `confirmed`). |
+| <a id="mutationvulnerabilitycreatedescription"></a>`description` | [`String!`](#string) | Description of the vulnerability. |
+| <a id="mutationvulnerabilitycreatedetectedat"></a>`detectedAt` | [`Time`](#time) | Timestamp of when the vulnerability was first detected (defaults to creation time). |
+| <a id="mutationvulnerabilitycreatedismissedat"></a>`dismissedAt` | [`Time`](#time) | Timestamp of when the vulnerability state changed to dismissed (defaults to creation time if status is `dismissed`). |
+| <a id="mutationvulnerabilitycreateidentifiers"></a>`identifiers` | [`[VulnerabilityIdentifierInput!]!`](#vulnerabilityidentifierinput) | Array of CVE or CWE identifiers for the vulnerability. |
+| <a id="mutationvulnerabilitycreatemessage"></a>`message` | [`String`](#string) | Additional information about the vulnerability. |
+| <a id="mutationvulnerabilitycreateproject"></a>`project` | [`ProjectID!`](#projectid) | ID of the project to attach the vulnerability to. |
+| <a id="mutationvulnerabilitycreateresolvedat"></a>`resolvedAt` | [`Time`](#time) | Timestamp of when the vulnerability state changed to resolved (defaults to creation time if status is `resolved`). |
+| <a id="mutationvulnerabilitycreatescannername"></a>`scannerName` | [`String!`](#string) | Name of the security scanner used to discover the vulnerability. |
+| <a id="mutationvulnerabilitycreateseverity"></a>`severity` | [`VulnerabilitySeverity`](#vulnerabilityseverity) | Severity of the vulnerability (defaults to `unknown`). |
+| <a id="mutationvulnerabilitycreatesolution"></a>`solution` | [`String`](#string) | How to fix this vulnerability. |
+| <a id="mutationvulnerabilitycreatestate"></a>`state` | [`VulnerabilityState`](#vulnerabilitystate) | State of the vulnerability (defaults to `detected`). |
+| <a id="mutationvulnerabilitycreatetitle"></a>`title` | [`String!`](#string) | Title of the vulnerability. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationvulnerabilitycreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationvulnerabilitycreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+| <a id="mutationvulnerabilitycreatevulnerability"></a>`vulnerability` | [`Vulnerability`](#vulnerability) | Vulnerability created. |
### `Mutation.vulnerabilityDismiss`
@@ -4478,7 +4595,7 @@ Input type: `VulnerabilityDismissInput`
| ---- | ---- | ----------- |
| <a id="mutationvulnerabilitydismissclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationvulnerabilitydismisserrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationvulnerabilitydismissvulnerability"></a>`vulnerability` | [`Vulnerability`](#vulnerability) | The vulnerability after dismissal. |
+| <a id="mutationvulnerabilitydismissvulnerability"></a>`vulnerability` | [`Vulnerability`](#vulnerability) | Vulnerability after dismissal. |
### `Mutation.vulnerabilityExternalIssueLinkCreate`
@@ -4499,7 +4616,7 @@ Input type: `VulnerabilityExternalIssueLinkCreateInput`
| ---- | ---- | ----------- |
| <a id="mutationvulnerabilityexternalissuelinkcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationvulnerabilityexternalissuelinkcreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationvulnerabilityexternalissuelinkcreateexternalissuelink"></a>`externalIssueLink` | [`VulnerabilityExternalIssueLink`](#vulnerabilityexternalissuelink) | The created external issue link. |
+| <a id="mutationvulnerabilityexternalissuelinkcreateexternalissuelink"></a>`externalIssueLink` | [`VulnerabilityExternalIssueLink`](#vulnerabilityexternalissuelink) | Created external issue link. |
### `Mutation.vulnerabilityExternalIssueLinkDestroy`
@@ -4510,7 +4627,7 @@ Input type: `VulnerabilityExternalIssueLinkDestroyInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationvulnerabilityexternalissuelinkdestroyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationvulnerabilityexternalissuelinkdestroyid"></a>`id` | [`VulnerabilitiesExternalIssueLinkID!`](#vulnerabilitiesexternalissuelinkid) | The global ID of the vulnerability external issue link. |
+| <a id="mutationvulnerabilityexternalissuelinkdestroyid"></a>`id` | [`VulnerabilitiesExternalIssueLinkID!`](#vulnerabilitiesexternalissuelinkid) | Global ID of the vulnerability external issue link. |
#### Fields
@@ -4536,7 +4653,7 @@ Input type: `VulnerabilityResolveInput`
| ---- | ---- | ----------- |
| <a id="mutationvulnerabilityresolveclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationvulnerabilityresolveerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationvulnerabilityresolvevulnerability"></a>`vulnerability` | [`Vulnerability`](#vulnerability) | The vulnerability after state change. |
+| <a id="mutationvulnerabilityresolvevulnerability"></a>`vulnerability` | [`Vulnerability`](#vulnerability) | Vulnerability after state change. |
### `Mutation.vulnerabilityRevertToDetected`
@@ -4555,7 +4672,7 @@ Input type: `VulnerabilityRevertToDetectedInput`
| ---- | ---- | ----------- |
| <a id="mutationvulnerabilityreverttodetectedclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationvulnerabilityreverttodetectederrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationvulnerabilityreverttodetectedvulnerability"></a>`vulnerability` | [`Vulnerability`](#vulnerability) | The vulnerability after revert. |
+| <a id="mutationvulnerabilityreverttodetectedvulnerability"></a>`vulnerability` | [`Vulnerability`](#vulnerability) | Vulnerability after revert. |
## Connections
@@ -5221,6 +5338,29 @@ The edge type for [`ComplianceFramework`](#complianceframework).
| <a id="complianceframeworkedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
| <a id="complianceframeworkedgenode"></a>`node` | [`ComplianceFramework`](#complianceframework) | The item at the end of the edge. |
+#### `ConnectedAgentConnection`
+
+The connection type for [`ConnectedAgent`](#connectedagent).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="connectedagentconnectionedges"></a>`edges` | [`[ConnectedAgentEdge]`](#connectedagentedge) | A list of edges. |
+| <a id="connectedagentconnectionnodes"></a>`nodes` | [`[ConnectedAgent]`](#connectedagent) | A list of nodes. |
+| <a id="connectedagentconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
+
+#### `ConnectedAgentEdge`
+
+The edge type for [`ConnectedAgent`](#connectedagent).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="connectedagentedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
+| <a id="connectedagentedgenode"></a>`node` | [`ConnectedAgent`](#connectedagent) | The item at the end of the edge. |
+
#### `ContainerRepositoryConnection`
The connection type for [`ContainerRepository`](#containerrepository).
@@ -5290,6 +5430,52 @@ The edge type for [`CustomEmoji`](#customemoji).
| <a id="customemojiedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
| <a id="customemojiedgenode"></a>`node` | [`CustomEmoji`](#customemoji) | The item at the end of the edge. |
+#### `CustomerRelationsContactConnection`
+
+The connection type for [`CustomerRelationsContact`](#customerrelationscontact).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="customerrelationscontactconnectionedges"></a>`edges` | [`[CustomerRelationsContactEdge]`](#customerrelationscontactedge) | A list of edges. |
+| <a id="customerrelationscontactconnectionnodes"></a>`nodes` | [`[CustomerRelationsContact]`](#customerrelationscontact) | A list of nodes. |
+| <a id="customerrelationscontactconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
+
+#### `CustomerRelationsContactEdge`
+
+The edge type for [`CustomerRelationsContact`](#customerrelationscontact).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="customerrelationscontactedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
+| <a id="customerrelationscontactedgenode"></a>`node` | [`CustomerRelationsContact`](#customerrelationscontact) | The item at the end of the edge. |
+
+#### `CustomerRelationsOrganizationConnection`
+
+The connection type for [`CustomerRelationsOrganization`](#customerrelationsorganization).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="customerrelationsorganizationconnectionedges"></a>`edges` | [`[CustomerRelationsOrganizationEdge]`](#customerrelationsorganizationedge) | A list of edges. |
+| <a id="customerrelationsorganizationconnectionnodes"></a>`nodes` | [`[CustomerRelationsOrganization]`](#customerrelationsorganization) | A list of nodes. |
+| <a id="customerrelationsorganizationconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
+
+#### `CustomerRelationsOrganizationEdge`
+
+The edge type for [`CustomerRelationsOrganization`](#customerrelationsorganization).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="customerrelationsorganizationedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
+| <a id="customerrelationsorganizationedgenode"></a>`node` | [`CustomerRelationsOrganization`](#customerrelationsorganization) | The item at the end of the edge. |
+
#### `DastProfileConnection`
The connection type for [`DastProfile`](#dastprofile).
@@ -5382,6 +5568,52 @@ The edge type for [`DastSiteValidation`](#dastsitevalidation).
| <a id="dastsitevalidationedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
| <a id="dastsitevalidationedgenode"></a>`node` | [`DastSiteValidation`](#dastsitevalidation) | The item at the end of the edge. |
+#### `DependencyProxyBlobConnection`
+
+The connection type for [`DependencyProxyBlob`](#dependencyproxyblob).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="dependencyproxyblobconnectionedges"></a>`edges` | [`[DependencyProxyBlobEdge]`](#dependencyproxyblobedge) | A list of edges. |
+| <a id="dependencyproxyblobconnectionnodes"></a>`nodes` | [`[DependencyProxyBlob]`](#dependencyproxyblob) | A list of nodes. |
+| <a id="dependencyproxyblobconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
+
+#### `DependencyProxyBlobEdge`
+
+The edge type for [`DependencyProxyBlob`](#dependencyproxyblob).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="dependencyproxyblobedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
+| <a id="dependencyproxyblobedgenode"></a>`node` | [`DependencyProxyBlob`](#dependencyproxyblob) | The item at the end of the edge. |
+
+#### `DependencyProxyManifestConnection`
+
+The connection type for [`DependencyProxyManifest`](#dependencyproxymanifest).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="dependencyproxymanifestconnectionedges"></a>`edges` | [`[DependencyProxyManifestEdge]`](#dependencyproxymanifestedge) | A list of edges. |
+| <a id="dependencyproxymanifestconnectionnodes"></a>`nodes` | [`[DependencyProxyManifest]`](#dependencyproxymanifest) | A list of nodes. |
+| <a id="dependencyproxymanifestconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
+
+#### `DependencyProxyManifestEdge`
+
+The edge type for [`DependencyProxyManifest`](#dependencyproxymanifest).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="dependencyproxymanifestedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
+| <a id="dependencyproxymanifestedgenode"></a>`node` | [`DependencyProxyManifest`](#dependencyproxymanifest) | The item at the end of the edge. |
+
#### `DesignAtVersionConnection`
The connection type for [`DesignAtVersion`](#designatversion).
@@ -6378,6 +6610,29 @@ The edge type for [`PackageTag`](#packagetag).
| <a id="packagetagedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
| <a id="packagetagedgenode"></a>`node` | [`PackageTag`](#packagetag) | The item at the end of the edge. |
+#### `PagesDeploymentRegistryConnection`
+
+The connection type for [`PagesDeploymentRegistry`](#pagesdeploymentregistry).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="pagesdeploymentregistryconnectionedges"></a>`edges` | [`[PagesDeploymentRegistryEdge]`](#pagesdeploymentregistryedge) | A list of edges. |
+| <a id="pagesdeploymentregistryconnectionnodes"></a>`nodes` | [`[PagesDeploymentRegistry]`](#pagesdeploymentregistry) | A list of nodes. |
+| <a id="pagesdeploymentregistryconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
+
+#### `PagesDeploymentRegistryEdge`
+
+The edge type for [`PagesDeploymentRegistry`](#pagesdeploymentregistry).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="pagesdeploymentregistryedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
+| <a id="pagesdeploymentregistryedgenode"></a>`node` | [`PagesDeploymentRegistry`](#pagesdeploymentregistry) | The item at the end of the edge. |
+
#### `PathLockConnection`
The connection type for [`PathLock`](#pathlock).
@@ -7188,6 +7443,29 @@ The edge type for [`TreeEntry`](#treeentry).
| <a id="treeentryedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
| <a id="treeentryedgenode"></a>`node` | [`TreeEntry`](#treeentry) | The item at the end of the edge. |
+#### `UploadRegistryConnection`
+
+The connection type for [`UploadRegistry`](#uploadregistry).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="uploadregistryconnectionedges"></a>`edges` | [`[UploadRegistryEdge]`](#uploadregistryedge) | A list of edges. |
+| <a id="uploadregistryconnectionnodes"></a>`nodes` | [`[UploadRegistry]`](#uploadregistry) | A list of nodes. |
+| <a id="uploadregistryconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
+
+#### `UploadRegistryEdge`
+
+The edge type for [`UploadRegistry`](#uploadregistry).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="uploadregistryedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
+| <a id="uploadregistryedgenode"></a>`node` | [`UploadRegistry`](#uploadregistry) | The item at the end of the edge. |
+
#### `UsageTrendsMeasurementConnection`
The connection type for [`UsageTrendsMeasurement`](#usagetrendsmeasurement).
@@ -7406,6 +7684,19 @@ Configuration details for an Agent.
| ---- | ---- | ----------- |
| <a id="agentconfigurationagentname"></a>`agentName` | [`String`](#string) | Name of the agent. |
+### `AgentMetadata`
+
+Information about a connected Agent.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="agentmetadatacommit"></a>`commit` | [`String`](#string) | Agent version commit. |
+| <a id="agentmetadatapodname"></a>`podName` | [`String`](#string) | Name of the pod running the Agent. |
+| <a id="agentmetadatapodnamespace"></a>`podNamespace` | [`String`](#string) | Namespace of the pod running the Agent. |
+| <a id="agentmetadataversion"></a>`version` | [`String`](#string) | Agent version tag. |
+
### `AlertManagementAlert`
Describes an alert from the project's Alert Management.
@@ -7418,7 +7709,7 @@ Describes an alert from the project's Alert Management.
| <a id="alertmanagementalertcreatedat"></a>`createdAt` | [`Time`](#time) | Timestamp the alert was created. |
| <a id="alertmanagementalertdescription"></a>`description` | [`String`](#string) | Description of the alert. |
| <a id="alertmanagementalertdetails"></a>`details` | [`JSON`](#json) | Alert details. |
-| <a id="alertmanagementalertdetailsurl"></a>`detailsUrl` | [`String!`](#string) | The URL of the alert detail page. |
+| <a id="alertmanagementalertdetailsurl"></a>`detailsUrl` | [`String!`](#string) | URL of the alert detail page. |
| <a id="alertmanagementalertdiscussions"></a>`discussions` | [`DiscussionConnection!`](#discussionconnection) | All discussions on this noteable. (see [Connections](#connections)) |
| <a id="alertmanagementalertendedat"></a>`endedAt` | [`Time`](#time) | Timestamp the alert ended. |
| <a id="alertmanagementalertenvironment"></a>`environment` | [`Environment`](#environment) | Environment for the alert. |
@@ -7430,7 +7721,7 @@ Describes an alert from the project's Alert Management.
| <a id="alertmanagementalertmetricsdashboardurl"></a>`metricsDashboardUrl` | [`String`](#string) | URL for metrics embed for the alert. |
| <a id="alertmanagementalertmonitoringtool"></a>`monitoringTool` | [`String`](#string) | Monitoring tool the alert came from. |
| <a id="alertmanagementalertnotes"></a>`notes` | [`NoteConnection!`](#noteconnection) | All notes on this noteable. (see [Connections](#connections)) |
-| <a id="alertmanagementalertprometheusalert"></a>`prometheusAlert` | [`PrometheusAlert`](#prometheusalert) | The alert condition for Prometheus. |
+| <a id="alertmanagementalertprometheusalert"></a>`prometheusAlert` | [`PrometheusAlert`](#prometheusalert) | Alert condition for Prometheus. |
| <a id="alertmanagementalertrunbook"></a>`runbook` | [`String`](#string) | Runbook for the alert as defined in alert details. |
| <a id="alertmanagementalertservice"></a>`service` | [`String`](#string) | Service the alert came from. |
| <a id="alertmanagementalertseverity"></a>`severity` | [`AlertManagementSeverity`](#alertmanagementseverity) | Severity of the alert. |
@@ -7455,12 +7746,12 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="alertmanagementalerttodosaction"></a>`action` | [`[TodoActionEnum!]`](#todoactionenum) | The action to be filtered. |
-| <a id="alertmanagementalerttodosauthorid"></a>`authorId` | [`[ID!]`](#id) | The ID of an author. |
-| <a id="alertmanagementalerttodosgroupid"></a>`groupId` | [`[ID!]`](#id) | The ID of a group. |
-| <a id="alertmanagementalerttodosprojectid"></a>`projectId` | [`[ID!]`](#id) | The ID of a project. |
-| <a id="alertmanagementalerttodosstate"></a>`state` | [`[TodoStateEnum!]`](#todostateenum) | The state of the todo. |
-| <a id="alertmanagementalerttodostype"></a>`type` | [`[TodoTargetEnum!]`](#todotargetenum) | The type of the todo. |
+| <a id="alertmanagementalerttodosaction"></a>`action` | [`[TodoActionEnum!]`](#todoactionenum) | Action to be filtered. |
+| <a id="alertmanagementalerttodosauthorid"></a>`authorId` | [`[ID!]`](#id) | ID of an author. |
+| <a id="alertmanagementalerttodosgroupid"></a>`groupId` | [`[ID!]`](#id) | ID of a group. |
+| <a id="alertmanagementalerttodosprojectid"></a>`projectId` | [`[ID!]`](#id) | ID of a project. |
+| <a id="alertmanagementalerttodosstate"></a>`state` | [`[TodoStateEnum!]`](#todostateenum) | State of the todo. |
+| <a id="alertmanagementalerttodostype"></a>`type` | [`[TodoTargetEnum!]`](#todotargetenum) | Type of the todo. |
### `AlertManagementAlertStatusCountsType`
@@ -7491,7 +7782,7 @@ An endpoint and credentials used to accept alerts for a project.
| <a id="alertmanagementhttpintegrationname"></a>`name` | [`String`](#string) | Name of the integration. |
| <a id="alertmanagementhttpintegrationpayloadalertfields"></a>`payloadAlertFields` | [`[AlertManagementPayloadAlertField!]`](#alertmanagementpayloadalertfield) | Extract alert fields from payload example for custom mapping. |
| <a id="alertmanagementhttpintegrationpayloadattributemappings"></a>`payloadAttributeMappings` | [`[AlertManagementPayloadAlertMappingField!]`](#alertmanagementpayloadalertmappingfield) | The custom mapping of GitLab alert attributes to fields from the payload_example. |
-| <a id="alertmanagementhttpintegrationpayloadexample"></a>`payloadExample` | [`JsonString`](#jsonstring) | The example of an alert payload. |
+| <a id="alertmanagementhttpintegrationpayloadexample"></a>`payloadExample` | [`JsonString`](#jsonstring) | Example of an alert payload. |
| <a id="alertmanagementhttpintegrationtoken"></a>`token` | [`String`](#string) | Token used to authenticate alert notification requests. |
| <a id="alertmanagementhttpintegrationtype"></a>`type` | [`AlertManagementIntegrationType!`](#alertmanagementintegrationtype) | Type of integration. |
| <a id="alertmanagementhttpintegrationurl"></a>`url` | [`String`](#string) | Endpoint which accepts alert notifications. |
@@ -7516,7 +7807,7 @@ Parsed field (with its name) from an alert used for custom mappings.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="alertmanagementpayloadalertmappingfieldfieldname"></a>`fieldName` | [`AlertManagementPayloadAlertFieldName`](#alertmanagementpayloadalertfieldname) | A GitLab alert field name. |
+| <a id="alertmanagementpayloadalertmappingfieldfieldname"></a>`fieldName` | [`AlertManagementPayloadAlertFieldName`](#alertmanagementpayloadalertfieldname) | GitLab alert field name. |
| <a id="alertmanagementpayloadalertmappingfieldlabel"></a>`label` | [`String`](#string) | Human-readable label of the payload path. |
| <a id="alertmanagementpayloadalertmappingfieldpath"></a>`path` | [`[PayloadAlertFieldPathSegment!]`](#payloadalertfieldpathsegment) | Path to value inside payload JSON. |
| <a id="alertmanagementpayloadalertmappingfieldtype"></a>`type` | [`AlertManagementPayloadAlertFieldType`](#alertmanagementpayloadalertfieldtype) | Type of the parsed value. |
@@ -7556,9 +7847,9 @@ An API Fuzzing scan profile.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="apifuzzingscanprofiledescription"></a>`description` | [`String`](#string) | A short description of the profile. |
-| <a id="apifuzzingscanprofilename"></a>`name` | [`String`](#string) | The unique name of the profile. |
-| <a id="apifuzzingscanprofileyaml"></a>`yaml` | [`String`](#string) | A syntax highlit HTML representation of the YAML. |
+| <a id="apifuzzingscanprofiledescription"></a>`description` | [`String`](#string) | Short description of the profile. |
+| <a id="apifuzzingscanprofilename"></a>`name` | [`String`](#string) | Unique name of the profile. |
+| <a id="apifuzzingscanprofileyaml"></a>`yaml` | [`String`](#string) | Syntax highlighted HTML representation of the YAML. |
### `ApprovalRule`
@@ -7568,9 +7859,19 @@ Describes a rule for who can approve merge requests.
| Name | Type | Description |
| ---- | ---- | ----------- |
+| <a id="approvalruleapprovalsrequired"></a>`approvalsRequired` | [`Int`](#int) | Number of required approvals. |
+| <a id="approvalruleapproved"></a>`approved` | [`Boolean`](#boolean) | Indicates if the rule is satisfied. |
+| <a id="approvalruleapprovedby"></a>`approvedBy` | [`UserCoreConnection`](#usercoreconnection) | List of users defined in the rule that approved the merge request. (see [Connections](#connections)) |
+| <a id="approvalrulecontainshiddengroups"></a>`containsHiddenGroups` | [`Boolean`](#boolean) | Indicates if the rule contains approvers from a hidden group. |
+| <a id="approvalruleeligibleapprovers"></a>`eligibleApprovers` | [`[UserCore!]`](#usercore) | List of all users eligible to approve the merge request (defined explicitly and from associated groups). |
+| <a id="approvalrulegroups"></a>`groups` | [`GroupConnection`](#groupconnection) | List of groups added as approvers for the rule. (see [Connections](#connections)) |
| <a id="approvalruleid"></a>`id` | [`GlobalID!`](#globalid) | ID of the rule. |
| <a id="approvalrulename"></a>`name` | [`String`](#string) | Name of the rule. |
+| <a id="approvalruleoverridden"></a>`overridden` | [`Boolean`](#boolean) | Indicates if the rule was overridden for the merge request. |
+| <a id="approvalrulesection"></a>`section` | [`String`](#string) | Named section of the Code Owners file that the rule applies to. |
+| <a id="approvalrulesourcerule"></a>`sourceRule` | [`ApprovalRule`](#approvalrule) | Source rule used to create the rule. |
| <a id="approvalruletype"></a>`type` | [`ApprovalRuleType`](#approvalruletype) | Type of the rule. |
+| <a id="approvalruleusers"></a>`users` | [`UserCoreConnection`](#usercoreconnection) | List of users added as approvers for the rule. (see [Connections](#connections)) |
### `AwardEmoji`
@@ -7580,12 +7881,12 @@ An emoji awarded by a user.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="awardemojidescription"></a>`description` | [`String!`](#string) | The emoji description. |
-| <a id="awardemojiemoji"></a>`emoji` | [`String!`](#string) | The emoji as an icon. |
-| <a id="awardemojiname"></a>`name` | [`String!`](#string) | The emoji name. |
-| <a id="awardemojiunicode"></a>`unicode` | [`String!`](#string) | The emoji in Unicode. |
-| <a id="awardemojiunicodeversion"></a>`unicodeVersion` | [`String!`](#string) | The Unicode version for this emoji. |
-| <a id="awardemojiuser"></a>`user` | [`UserCore!`](#usercore) | The user who awarded the emoji. |
+| <a id="awardemojidescription"></a>`description` | [`String!`](#string) | Emoji description. |
+| <a id="awardemojiemoji"></a>`emoji` | [`String!`](#string) | Emoji as an icon. |
+| <a id="awardemojiname"></a>`name` | [`String!`](#string) | Emoji name. |
+| <a id="awardemojiunicode"></a>`unicode` | [`String!`](#string) | Emoji in Unicode. |
+| <a id="awardemojiunicodeversion"></a>`unicodeVersion` | [`String!`](#string) | Unicode version for this emoji. |
+| <a id="awardemojiuser"></a>`user` | [`UserCore!`](#usercore) | User who awarded the emoji. |
### `BaseService`
@@ -7637,14 +7938,15 @@ Represents a project or group issue board.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="boardassignee"></a>`assignee` | [`UserCore`](#usercore) | The board assignee. |
+| <a id="boardassignee"></a>`assignee` | [`UserCore`](#usercore) | Board assignee. |
| <a id="boardcreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp of when the board was created. |
| <a id="boardhidebackloglist"></a>`hideBacklogList` | [`Boolean`](#boolean) | Whether or not backlog list is hidden. |
| <a id="boardhideclosedlist"></a>`hideClosedList` | [`Boolean`](#boolean) | Whether or not closed list is hidden. |
| <a id="boardid"></a>`id` | [`ID!`](#id) | ID (global ID) of the board. |
-| <a id="boarditeration"></a>`iteration` | [`Iteration`](#iteration) | The board iteration. |
+| <a id="boarditeration"></a>`iteration` | [`Iteration`](#iteration) | Board iteration. |
+| <a id="boarditerationcadence"></a>`iterationCadence` | [`IterationCadence`](#iterationcadence) | Board iteration cadence. |
| <a id="boardlabels"></a>`labels` | [`LabelConnection`](#labelconnection) | Labels of the board. (see [Connections](#connections)) |
-| <a id="boardmilestone"></a>`milestone` | [`Milestone`](#milestone) | The board milestone. |
+| <a id="boardmilestone"></a>`milestone` | [`Milestone`](#milestone) | Board milestone. |
| <a id="boardname"></a>`name` | [`String`](#string) | Name of the board. |
| <a id="boardupdatedat"></a>`updatedAt` | [`Time!`](#time) | Timestamp of when the board was last updated. |
| <a id="boardwebpath"></a>`webPath` | [`String!`](#string) | Web path of the board. |
@@ -7695,7 +7997,7 @@ Represents an epic on an issue board.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="boardepicauthor"></a>`author` | [`UserCore!`](#usercore) | Author of the epic. |
-| <a id="boardepicawardemoji"></a>`awardEmoji` | [`AwardEmojiConnection`](#awardemojiconnection) | A list of award emojis associated with the epic. (see [Connections](#connections)) |
+| <a id="boardepicawardemoji"></a>`awardEmoji` | [`AwardEmojiConnection`](#awardemojiconnection) | List of award emojis associated with the epic. (see [Connections](#connections)) |
| <a id="boardepicclosedat"></a>`closedAt` | [`Time`](#time) | Timestamp of when the epic was closed. |
| <a id="boardepicconfidential"></a>`confidential` | [`Boolean`](#boolean) | Indicates if the epic is confidential. |
| <a id="boardepiccreatedat"></a>`createdAt` | [`Time`](#time) | Timestamp of when the epic was created. |
@@ -7709,7 +8011,7 @@ Represents an epic on an issue board.
| <a id="boardepicduedatefixed"></a>`dueDateFixed` | [`Time`](#time) | Fixed due date of the epic. |
| <a id="boardepicduedatefrommilestones"></a>`dueDateFromMilestones` | [`Time`](#time) | Inherited due date of the epic from milestones. |
| <a id="boardepicduedateisfixed"></a>`dueDateIsFixed` | [`Boolean`](#boolean) | Indicates if the due date has been manually set. |
-| <a id="boardepicevents"></a>`events` | [`EventConnection`](#eventconnection) | A list of events associated with the object. (see [Connections](#connections)) |
+| <a id="boardepicevents"></a>`events` | [`EventConnection`](#eventconnection) | List of events associated with the object. (see [Connections](#connections)) |
| <a id="boardepicgroup"></a>`group` | [`Group!`](#group) | Group to which the epic belongs. |
| <a id="boardepichaschildren"></a>`hasChildren` | [`Boolean!`](#boolean) | Indicates if the epic has children. |
| <a id="boardepichasissues"></a>`hasIssues` | [`Boolean!`](#boolean) | Indicates if the epic has direct issues. |
@@ -7723,7 +8025,7 @@ Represents an epic on an issue board.
| <a id="boardepicparent"></a>`parent` | [`Epic`](#epic) | Parent epic of the epic. |
| <a id="boardepicparticipants"></a>`participants` | [`UserCoreConnection`](#usercoreconnection) | List of participants for the epic. (see [Connections](#connections)) |
| <a id="boardepicrelationpath"></a>`relationPath` | [`String`](#string) | URI path of the epic-issue relationship. |
-| <a id="boardepicrelativeposition"></a>`relativePosition` | [`Int`](#int) | The relative position of the epic in the epic tree. |
+| <a id="boardepicrelativeposition"></a>`relativePosition` | [`Int`](#int) | Relative position of the epic in the epic tree. |
| <a id="boardepicstartdate"></a>`startDate` | [`Time`](#time) | Start date of the epic. |
| <a id="boardepicstartdatefixed"></a>`startDateFixed` | [`Time`](#time) | Fixed start date of the epic. |
| <a id="boardepicstartdatefrommilestones"></a>`startDateFromMilestones` | [`Time`](#time) | Inherited start date of the epic from milestones. |
@@ -7861,7 +8163,7 @@ Represents a list for an issue board.
| <a id="boardlistissuescount"></a>`issuesCount` | [`Int`](#int) | Count of issues in the list. |
| <a id="boardlistiteration"></a>`iteration` | [`Iteration`](#iteration) | Iteration of the list. |
| <a id="boardlistlabel"></a>`label` | [`Label`](#label) | Label of the list. |
-| <a id="boardlistlimitmetric"></a>`limitMetric` | [`ListLimitMetric`](#listlimitmetric) | The current limit metric for the list. |
+| <a id="boardlistlimitmetric"></a>`limitMetric` | [`ListLimitMetric`](#listlimitmetric) | Current limit metric for the list. |
| <a id="boardlistlisttype"></a>`listType` | [`String!`](#string) | Type of the list. |
| <a id="boardlistmaxissuecount"></a>`maxIssueCount` | [`Int`](#int) | Maximum number of issues in the list. |
| <a id="boardlistmaxissueweight"></a>`maxIssueWeight` | [`Int`](#int) | Maximum weight of issues in the list. |
@@ -7975,7 +8277,7 @@ Represents the total number of issues and their weights for a particular day.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="ciconfigjobrestrictionrefs"></a>`refs` | [`[String!]`](#string) | The Git refs the job restriction applies to. |
+| <a id="ciconfigjobrestrictionrefs"></a>`refs` | [`[String!]`](#string) | Git refs the job restriction applies to. |
### `CiConfigNeed`
@@ -8068,8 +8370,8 @@ Represents the total number of issues and their weights for a particular day.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="ciminutesnamespacemonthlyusageminutes"></a>`minutes` | [`Int`](#int) | The total number of minutes used by all projects in the namespace. |
-| <a id="ciminutesnamespacemonthlyusagemonth"></a>`month` | [`String`](#string) | The month related to the usage data. |
+| <a id="ciminutesnamespacemonthlyusageminutes"></a>`minutes` | [`Int`](#int) | Total number of minutes used by all projects in the namespace. |
+| <a id="ciminutesnamespacemonthlyusagemonth"></a>`month` | [`String`](#string) | Month related to the usage data. |
| <a id="ciminutesnamespacemonthlyusageprojects"></a>`projects` | [`CiMinutesProjectMonthlyUsageConnection`](#ciminutesprojectmonthlyusageconnection) | CI minutes usage data for projects in the namespace. (see [Connections](#connections)) |
### `CiMinutesProjectMonthlyUsage`
@@ -8078,8 +8380,8 @@ Represents the total number of issues and their weights for a particular day.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="ciminutesprojectmonthlyusageminutes"></a>`minutes` | [`Int`](#int) | The number of CI minutes used by the project in the month. |
-| <a id="ciminutesprojectmonthlyusagename"></a>`name` | [`String`](#string) | The name of the project. |
+| <a id="ciminutesprojectmonthlyusageminutes"></a>`minutes` | [`Int`](#int) | Number of CI minutes used by the project in the month. |
+| <a id="ciminutesprojectmonthlyusagename"></a>`name` | [`String`](#string) | Name of the project. |
### `CiRunner`
@@ -8137,11 +8439,12 @@ GitLab CI/CD configuration template.
| Name | Type | Description |
| ---- | ---- | ----------- |
+| <a id="clusteragentconnections"></a>`connections` | [`ConnectedAgentConnection`](#connectedagentconnection) | Active connections for the cluster agent. (see [Connections](#connections)) |
| <a id="clusteragentcreatedat"></a>`createdAt` | [`Time`](#time) | Timestamp the cluster agent was created. |
| <a id="clusteragentcreatedbyuser"></a>`createdByUser` | [`UserCore`](#usercore) | User object, containing information about the person who created the agent. |
| <a id="clusteragentid"></a>`id` | [`ID!`](#id) | ID of the cluster agent. |
| <a id="clusteragentname"></a>`name` | [`String`](#string) | Name of the cluster agent. |
-| <a id="clusteragentproject"></a>`project` | [`Project`](#project) | The project this cluster agent is associated with. |
+| <a id="clusteragentproject"></a>`project` | [`Project`](#project) | Project this cluster agent is associated with. |
| <a id="clusteragenttokens"></a>`tokens` | [`ClusterAgentTokenConnection`](#clusteragenttokenconnection) | Tokens associated with the cluster agent. (see [Connections](#connections)) |
| <a id="clusteragentupdatedat"></a>`updatedAt` | [`Time`](#time) | Timestamp the cluster agent was updated. |
| <a id="clusteragentwebpath"></a>`webPath` | [`String`](#string) | Web path of the cluster agent. |
@@ -8154,7 +8457,7 @@ GitLab CI/CD configuration template.
| ---- | ---- | ----------- |
| <a id="clusteragenttokenclusteragent"></a>`clusterAgent` | [`ClusterAgent`](#clusteragent) | Cluster agent this token is associated with. |
| <a id="clusteragenttokencreatedat"></a>`createdAt` | [`Time`](#time) | Timestamp the token was created. |
-| <a id="clusteragenttokencreatedbyuser"></a>`createdByUser` | [`UserCore`](#usercore) | The user who created the token. |
+| <a id="clusteragenttokencreatedbyuser"></a>`createdByUser` | [`UserCore`](#usercore) | User who created the token. |
| <a id="clusteragenttokendescription"></a>`description` | [`String`](#string) | Description of the token. |
| <a id="clusteragenttokenid"></a>`id` | [`ClustersAgentTokenID!`](#clustersagenttokenid) | Global ID of the token. |
| <a id="clusteragenttokenlastusedat"></a>`lastUsedAt` | [`Time`](#time) | Timestamp the token was last used. |
@@ -8193,10 +8496,10 @@ Represents a code quality degradation on the pipeline.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="codequalitydegradationdescription"></a>`description` | [`String!`](#string) | A description of the code quality degradation. |
-| <a id="codequalitydegradationfingerprint"></a>`fingerprint` | [`String!`](#string) | A unique fingerprint to identify the code quality degradation. For example, an MD5 hash. |
-| <a id="codequalitydegradationline"></a>`line` | [`Int!`](#int) | The line on which the code quality degradation occurred. |
-| <a id="codequalitydegradationpath"></a>`path` | [`String!`](#string) | The relative path to the file containing the code quality degradation. |
+| <a id="codequalitydegradationdescription"></a>`description` | [`String!`](#string) | Description of the code quality degradation. |
+| <a id="codequalitydegradationfingerprint"></a>`fingerprint` | [`String!`](#string) | Unique fingerprint to identify the code quality degradation. For example, an MD5 hash. |
+| <a id="codequalitydegradationline"></a>`line` | [`Int!`](#int) | Line on which the code quality degradation occurred. |
+| <a id="codequalitydegradationpath"></a>`path` | [`String!`](#string) | Relative path to the file containing the code quality degradation. |
| <a id="codequalitydegradationseverity"></a>`severity` | [`CodeQualityDegradationSeverity!`](#codequalitydegradationseverity) | Status of the degradation (BLOCKER, CRITICAL, MAJOR, MINOR, INFO). |
### `Commit`
@@ -8239,6 +8542,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| ---- | ---- | ----------- |
| <a id="commitpipelinesref"></a>`ref` | [`String`](#string) | Filter pipelines by the ref they are run for. |
| <a id="commitpipelinessha"></a>`sha` | [`String`](#string) | Filter pipelines by the sha of the commit they are run for. |
+| <a id="commitpipelinessource"></a>`source` | [`String`](#string) | Filter pipelines by their source. Will be ignored if `dast_view_scans` feature flag is disabled. |
| <a id="commitpipelinesstatus"></a>`status` | [`PipelineStatusEnum`](#pipelinestatusenum) | Filter pipelines by their status. |
### `ComplianceFramework`
@@ -8298,6 +8602,18 @@ Conan metadata.
| <a id="conanmetadatarecipepath"></a>`recipePath` | [`String!`](#string) | Recipe path of the Conan package. |
| <a id="conanmetadataupdatedat"></a>`updatedAt` | [`Time!`](#time) | Date of most recent update. |
+### `ConnectedAgent`
+
+Connection details for an Agent.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="connectedagentconnectedat"></a>`connectedAt` | [`Time`](#time) | When the connection was established. |
+| <a id="connectedagentconnectionid"></a>`connectionId` | [`BigInt`](#bigint) | ID of the connection. |
+| <a id="connectedagentmetadata"></a>`metadata` | [`AgentMetadata`](#agentmetadata) | Information about the Agent. |
+
### `ContainerExpirationPolicy`
A tag expiration policy designed to keep only the images that matter most.
@@ -8326,7 +8642,7 @@ A container repository.
| ---- | ---- | ----------- |
| <a id="containerrepositorycandelete"></a>`canDelete` | [`Boolean!`](#boolean) | Can the current user delete the container repository. |
| <a id="containerrepositorycreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp when the container repository was created. |
-| <a id="containerrepositoryexpirationpolicycleanupstatus"></a>`expirationPolicyCleanupStatus` | [`ContainerRepositoryCleanupStatus`](#containerrepositorycleanupstatus) | The tags cleanup status for the container repository. |
+| <a id="containerrepositoryexpirationpolicycleanupstatus"></a>`expirationPolicyCleanupStatus` | [`ContainerRepositoryCleanupStatus`](#containerrepositorycleanupstatus) | Tags cleanup status for the container repository. |
| <a id="containerrepositoryexpirationpolicystartedat"></a>`expirationPolicyStartedAt` | [`Time`](#time) | Timestamp when the cleanup done by the expiration policy was started on the container repository. |
| <a id="containerrepositoryid"></a>`id` | [`ID!`](#id) | ID of the container repository. |
| <a id="containerrepositorylocation"></a>`location` | [`String!`](#string) | URL of the container repository. |
@@ -8347,7 +8663,7 @@ Details of a container repository.
| ---- | ---- | ----------- |
| <a id="containerrepositorydetailscandelete"></a>`canDelete` | [`Boolean!`](#boolean) | Can the current user delete the container repository. |
| <a id="containerrepositorydetailscreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp when the container repository was created. |
-| <a id="containerrepositorydetailsexpirationpolicycleanupstatus"></a>`expirationPolicyCleanupStatus` | [`ContainerRepositoryCleanupStatus`](#containerrepositorycleanupstatus) | The tags cleanup status for the container repository. |
+| <a id="containerrepositorydetailsexpirationpolicycleanupstatus"></a>`expirationPolicyCleanupStatus` | [`ContainerRepositoryCleanupStatus`](#containerrepositorycleanupstatus) | Tags cleanup status for the container repository. |
| <a id="containerrepositorydetailsexpirationpolicystartedat"></a>`expirationPolicyStartedAt` | [`Time`](#time) | Timestamp when the cleanup done by the expiration policy was started on the container repository. |
| <a id="containerrepositorydetailsid"></a>`id` | [`ID!`](#id) | ID of the container repository. |
| <a id="containerrepositorydetailslocation"></a>`location` | [`String!`](#string) | URL of the container repository. |
@@ -8375,7 +8691,7 @@ A tag from a container repository.
| <a id="containerrepositorytagpath"></a>`path` | [`String!`](#string) | Path of the tag. |
| <a id="containerrepositorytagrevision"></a>`revision` | [`String`](#string) | Revision of the tag. |
| <a id="containerrepositorytagshortrevision"></a>`shortRevision` | [`String`](#string) | Short revision of the tag. |
-| <a id="containerrepositorytagtotalsize"></a>`totalSize` | [`BigInt`](#bigint) | The size of the tag. |
+| <a id="containerrepositorytagtotalsize"></a>`totalSize` | [`BigInt`](#bigint) | Size of the tag. |
### `CurrentLicense`
@@ -8410,9 +8726,38 @@ A custom emoji uploaded by user.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="customemojiexternal"></a>`external` | [`Boolean!`](#boolean) | Whether the emoji is an external link. |
-| <a id="customemojiid"></a>`id` | [`CustomEmojiID!`](#customemojiid) | The ID of the emoji. |
-| <a id="customemojiname"></a>`name` | [`String!`](#string) | The name of the emoji. |
-| <a id="customemojiurl"></a>`url` | [`String!`](#string) | The link to file of the emoji. |
+| <a id="customemojiid"></a>`id` | [`CustomEmojiID!`](#customemojiid) | ID of the emoji. |
+| <a id="customemojiname"></a>`name` | [`String!`](#string) | Name of the emoji. |
+| <a id="customemojiurl"></a>`url` | [`String!`](#string) | Link to file of the emoji. |
+
+### `CustomerRelationsContact`
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="customerrelationscontactcreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp the contact was created. |
+| <a id="customerrelationscontactdescription"></a>`description` | [`String`](#string) | Description or notes for the contact. |
+| <a id="customerrelationscontactemail"></a>`email` | [`String`](#string) | Email address of the contact. |
+| <a id="customerrelationscontactfirstname"></a>`firstName` | [`String!`](#string) | First name of the contact. |
+| <a id="customerrelationscontactid"></a>`id` | [`ID!`](#id) | Internal ID of the contact. |
+| <a id="customerrelationscontactlastname"></a>`lastName` | [`String!`](#string) | Last name of the contact. |
+| <a id="customerrelationscontactorganization"></a>`organization` | [`CustomerRelationsOrganization`](#customerrelationsorganization) | Organization of the contact. |
+| <a id="customerrelationscontactphone"></a>`phone` | [`String`](#string) | Phone number of the contact. |
+| <a id="customerrelationscontactupdatedat"></a>`updatedAt` | [`Time!`](#time) | Timestamp the contact was last updated. |
+
+### `CustomerRelationsOrganization`
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="customerrelationsorganizationcreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp the organization was created. |
+| <a id="customerrelationsorganizationdefaultrate"></a>`defaultRate` | [`Float`](#float) | Standard billing rate for the organization. |
+| <a id="customerrelationsorganizationdescription"></a>`description` | [`String`](#string) | Description or notes for the organization. |
+| <a id="customerrelationsorganizationid"></a>`id` | [`ID!`](#id) | Internal ID of the organization. |
+| <a id="customerrelationsorganizationname"></a>`name` | [`String!`](#string) | Name of the organization. |
+| <a id="customerrelationsorganizationupdatedat"></a>`updatedAt` | [`Time!`](#time) | Timestamp the organization was last updated. |
### `DastProfile`
@@ -8422,13 +8767,14 @@ Represents a DAST Profile.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="dastprofilebranch"></a>`branch` | [`DastProfileBranch`](#dastprofilebranch) | The associated branch. |
-| <a id="dastprofiledastscannerprofile"></a>`dastScannerProfile` | [`DastScannerProfile`](#dastscannerprofile) | The associated scanner profile. |
-| <a id="dastprofiledastsiteprofile"></a>`dastSiteProfile` | [`DastSiteProfile`](#dastsiteprofile) | The associated site profile. |
-| <a id="dastprofiledescription"></a>`description` | [`String`](#string) | The description of the scan. |
+| <a id="dastprofilebranch"></a>`branch` | [`DastProfileBranch`](#dastprofilebranch) | Associated branch. |
+| <a id="dastprofiledastprofileschedule"></a>`dastProfileSchedule` | [`DastProfileSchedule`](#dastprofileschedule) | Associated profile schedule. Will always return `null` if `dast_on_demand_scans_scheduler` feature flag is disabled. |
+| <a id="dastprofiledastscannerprofile"></a>`dastScannerProfile` | [`DastScannerProfile`](#dastscannerprofile) | Associated scanner profile. |
+| <a id="dastprofiledastsiteprofile"></a>`dastSiteProfile` | [`DastSiteProfile`](#dastsiteprofile) | Associated site profile. |
+| <a id="dastprofiledescription"></a>`description` | [`String`](#string) | Description of the scan. |
| <a id="dastprofileeditpath"></a>`editPath` | [`String`](#string) | Relative web path to the edit page of a profile. |
| <a id="dastprofileid"></a>`id` | [`DastProfileID!`](#dastprofileid) | ID of the profile. |
-| <a id="dastprofilename"></a>`name` | [`String`](#string) | The name of the profile. |
+| <a id="dastprofilename"></a>`name` | [`String`](#string) | Name of the profile. |
### `DastProfileBranch`
@@ -8439,7 +8785,33 @@ Represents a DAST Profile Branch.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="dastprofilebranchexists"></a>`exists` | [`Boolean`](#boolean) | Indicates whether or not the branch exists. |
-| <a id="dastprofilebranchname"></a>`name` | [`String`](#string) | The name of the branch. |
+| <a id="dastprofilebranchname"></a>`name` | [`String`](#string) | Name of the branch. |
+
+### `DastProfileCadence`
+
+Represents DAST Profile Cadence.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="dastprofilecadenceduration"></a>`duration` | [`Int`](#int) | Duration of the DAST profile cadence. |
+| <a id="dastprofilecadenceunit"></a>`unit` | [`DastProfileCadenceUnit`](#dastprofilecadenceunit) | Unit for the duration of DAST profile cadence. |
+
+### `DastProfileSchedule`
+
+Represents a DAST profile schedule.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="dastprofilescheduleactive"></a>`active` | [`Boolean`](#boolean) | Status of the DAST profile schedule. |
+| <a id="dastprofileschedulecadence"></a>`cadence` | [`DastProfileCadence`](#dastprofilecadence) | Cadence of the DAST profile schedule. |
+| <a id="dastprofilescheduleid"></a>`id` | [`DastProfileScheduleID!`](#dastprofilescheduleid) | ID of the DAST profile schedule. |
+| <a id="dastprofileschedulenextrunat"></a>`nextRunAt` | [`Time`](#time) | Next run time of the DAST profile schedule in the given timezone. |
+| <a id="dastprofileschedulestartsat"></a>`startsAt` | [`Time`](#time) | Start time of the DAST profile schedule in the given timezone. |
+| <a id="dastprofilescheduletimezone"></a>`timezone` | [`String`](#string) | Time zone of the start time of the DAST profile schedule. |
### `DastScannerProfile`
@@ -8455,8 +8827,8 @@ Represents a DAST scanner profile.
| <a id="dastscannerprofilereferencedinsecuritypolicies"></a>`referencedInSecurityPolicies` | [`[String!]`](#string) | List of security policy names that are referencing given project. |
| <a id="dastscannerprofilescantype"></a>`scanType` | [`DastScanTypeEnum`](#dastscantypeenum) | Indicates the type of DAST scan that will run. Either a Passive Scan or an Active Scan. |
| <a id="dastscannerprofileshowdebugmessages"></a>`showDebugMessages` | [`Boolean!`](#boolean) | Indicates if debug messages should be included in DAST console output. True to include the debug messages. |
-| <a id="dastscannerprofilespidertimeout"></a>`spiderTimeout` | [`Int`](#int) | The maximum number of minutes allowed for the spider to traverse the site. |
-| <a id="dastscannerprofiletargettimeout"></a>`targetTimeout` | [`Int`](#int) | The maximum number of seconds allowed for the site under test to respond to a request. |
+| <a id="dastscannerprofilespidertimeout"></a>`spiderTimeout` | [`Int`](#int) | Maximum number of minutes allowed for the spider to traverse the site. |
+| <a id="dastscannerprofiletargettimeout"></a>`targetTimeout` | [`Int`](#int) | Maximum number of seconds allowed for the site under test to respond to a request. |
| <a id="dastscannerprofileuseajaxspider"></a>`useAjaxSpider` | [`Boolean!`](#boolean) | Indicates if the AJAX spider should be used to crawl the target site. True to run the AJAX spider in addition to the traditional spider, and false to run only the traditional spider. |
### `DastSiteProfile`
@@ -8469,16 +8841,16 @@ Represents a DAST Site Profile.
| ---- | ---- | ----------- |
| <a id="dastsiteprofileauth"></a>`auth` | [`DastSiteProfileAuth`](#dastsiteprofileauth) | Target authentication details. |
| <a id="dastsiteprofileeditpath"></a>`editPath` | [`String`](#string) | Relative web path to the edit page of a site profile. |
-| <a id="dastsiteprofileexcludedurls"></a>`excludedUrls` | [`[String!]`](#string) | The URLs to skip during an authenticated scan. |
+| <a id="dastsiteprofileexcludedurls"></a>`excludedUrls` | [`[String!]`](#string) | URLs to skip during an authenticated scan. |
| <a id="dastsiteprofileid"></a>`id` | [`DastSiteProfileID!`](#dastsiteprofileid) | ID of the site profile. |
| <a id="dastsiteprofilenormalizedtargeturl"></a>`normalizedTargetUrl` | [`String`](#string) | Normalized URL of the target to be scanned. |
-| <a id="dastsiteprofileprofilename"></a>`profileName` | [`String`](#string) | The name of the site profile. |
+| <a id="dastsiteprofileprofilename"></a>`profileName` | [`String`](#string) | Name of the site profile. |
| <a id="dastsiteprofilereferencedinsecuritypolicies"></a>`referencedInSecurityPolicies` | [`[String!]`](#string) | List of security policy names that are referencing given project. |
| <a id="dastsiteprofilerequestheaders"></a>`requestHeaders` | [`String`](#string) | Comma-separated list of request header names and values to be added to every request made by DAST. |
-| <a id="dastsiteprofiletargettype"></a>`targetType` | [`DastTargetTypeEnum`](#dasttargettypeenum) | The type of target to be scanned. |
-| <a id="dastsiteprofiletargeturl"></a>`targetUrl` | [`String`](#string) | The URL of the target to be scanned. |
+| <a id="dastsiteprofiletargettype"></a>`targetType` | [`DastTargetTypeEnum`](#dasttargettypeenum) | Type of target to be scanned. |
+| <a id="dastsiteprofiletargeturl"></a>`targetUrl` | [`String`](#string) | URL of the target to be scanned. |
| <a id="dastsiteprofileuserpermissions"></a>`userPermissions` | [`DastSiteProfilePermissions!`](#dastsiteprofilepermissions) | Permissions for the current user on the resource. |
-| <a id="dastsiteprofilevalidationstatus"></a>`validationStatus` | [`DastSiteProfileValidationStatusEnum`](#dastsiteprofilevalidationstatusenum) | The current validation status of the site profile. |
+| <a id="dastsiteprofilevalidationstatus"></a>`validationStatus` | [`DastSiteProfileValidationStatusEnum`](#dastsiteprofilevalidationstatusenum) | Current validation status of the site profile. |
### `DastSiteProfileAuth`
@@ -8490,10 +8862,10 @@ Input type for DastSiteProfile authentication.
| ---- | ---- | ----------- |
| <a id="dastsiteprofileauthenabled"></a>`enabled` | [`Boolean`](#boolean) | Indicates whether authentication is enabled. |
| <a id="dastsiteprofileauthpassword"></a>`password` | [`String`](#string) | Redacted password to authenticate with on the target website. |
-| <a id="dastsiteprofileauthpasswordfield"></a>`passwordField` | [`String`](#string) | The name of password field at the sign-in HTML form. |
+| <a id="dastsiteprofileauthpasswordfield"></a>`passwordField` | [`String`](#string) | Name of password field at the sign-in HTML form. |
| <a id="dastsiteprofileauthurl"></a>`url` | [`String`](#string) | The URL of the page containing the sign-in HTML form on the target website. |
-| <a id="dastsiteprofileauthusername"></a>`username` | [`String`](#string) | The username to authenticate with on the target website. |
-| <a id="dastsiteprofileauthusernamefield"></a>`usernameField` | [`String`](#string) | The name of username field at the sign-in HTML form. |
+| <a id="dastsiteprofileauthusername"></a>`username` | [`String`](#string) | Username to authenticate with on the target website. |
+| <a id="dastsiteprofileauthusernamefield"></a>`usernameField` | [`String`](#string) | Name of username field at the sign-in HTML form. |
### `DastSiteProfilePermissions`
@@ -8526,8 +8898,59 @@ The response from the AdminSidekiqQueuesDeleteJobs mutation.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="deletejobsresponsecompleted"></a>`completed` | [`Boolean`](#boolean) | Whether or not the entire queue was processed in time; if not, retrying the same request is safe. |
-| <a id="deletejobsresponsedeletedjobs"></a>`deletedJobs` | [`Int`](#int) | The number of matching jobs deleted. |
-| <a id="deletejobsresponsequeuesize"></a>`queueSize` | [`Int`](#int) | The queue size after processing. |
+| <a id="deletejobsresponsedeletedjobs"></a>`deletedJobs` | [`Int`](#int) | Number of matching jobs deleted. |
+| <a id="deletejobsresponsequeuesize"></a>`queueSize` | [`Int`](#int) | Queue size after processing. |
+
+### `DependencyProxyBlob`
+
+Dependency proxy blob.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="dependencyproxyblobcreatedat"></a>`createdAt` | [`Time!`](#time) | Date of creation. |
+| <a id="dependencyproxyblobfilename"></a>`fileName` | [`String!`](#string) | Name of the blob. |
+| <a id="dependencyproxyblobsize"></a>`size` | [`String!`](#string) | Size of the blob file. |
+| <a id="dependencyproxyblobupdatedat"></a>`updatedAt` | [`Time!`](#time) | Date of most recent update. |
+
+### `DependencyProxyImageTtlGroupPolicy`
+
+Group-level Dependency Proxy TTL policy settings.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="dependencyproxyimagettlgrouppolicycreatedat"></a>`createdAt` | [`Time`](#time) | Timestamp of creation. |
+| <a id="dependencyproxyimagettlgrouppolicyenabled"></a>`enabled` | [`Boolean!`](#boolean) | Indicates whether the policy is enabled or disabled. |
+| <a id="dependencyproxyimagettlgrouppolicyttl"></a>`ttl` | [`Int`](#int) | Number of days to retain a cached image file. |
+| <a id="dependencyproxyimagettlgrouppolicyupdatedat"></a>`updatedAt` | [`Time`](#time) | Timestamp of the most recent update. |
+
+### `DependencyProxyManifest`
+
+Dependency proxy manifest.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="dependencyproxymanifestcreatedat"></a>`createdAt` | [`Time!`](#time) | Date of creation. |
+| <a id="dependencyproxymanifestdigest"></a>`digest` | [`String!`](#string) | Digest of the manifest. |
+| <a id="dependencyproxymanifestfilename"></a>`fileName` | [`String!`](#string) | Name of the manifest. |
+| <a id="dependencyproxymanifestimagename"></a>`imageName` | [`String!`](#string) | Name of the image. |
+| <a id="dependencyproxymanifestsize"></a>`size` | [`String!`](#string) | Size of the manifest file. |
+| <a id="dependencyproxymanifestupdatedat"></a>`updatedAt` | [`Time!`](#time) | Date of most recent update. |
+
+### `DependencyProxySetting`
+
+Group-level Dependency Proxy settings.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="dependencyproxysettingenabled"></a>`enabled` | [`Boolean!`](#boolean) | Indicates whether the dependency proxy is enabled for the group. |
### `Design`
@@ -8537,18 +8960,18 @@ A single design.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="designdiffrefs"></a>`diffRefs` | [`DiffRefs!`](#diffrefs) | The diff refs for this design. |
+| <a id="designdiffrefs"></a>`diffRefs` | [`DiffRefs!`](#diffrefs) | Diff refs for this design. |
| <a id="designdiscussions"></a>`discussions` | [`DiscussionConnection!`](#discussionconnection) | All discussions on this noteable. (see [Connections](#connections)) |
| <a id="designevent"></a>`event` | [`DesignVersionEvent!`](#designversionevent) | How this design was changed in the current version. |
-| <a id="designfilename"></a>`filename` | [`String!`](#string) | The filename of the design. |
-| <a id="designfullpath"></a>`fullPath` | [`String!`](#string) | The full path to the design file. |
-| <a id="designid"></a>`id` | [`ID!`](#id) | The ID of this design. |
-| <a id="designimage"></a>`image` | [`String!`](#string) | The URL of the full-sized image. |
+| <a id="designfilename"></a>`filename` | [`String!`](#string) | Filename of the design. |
+| <a id="designfullpath"></a>`fullPath` | [`String!`](#string) | Full path to the design file. |
+| <a id="designid"></a>`id` | [`ID!`](#id) | ID of this design. |
+| <a id="designimage"></a>`image` | [`String!`](#string) | URL of the full-sized image. |
| <a id="designimagev432x230"></a>`imageV432x230` | [`String`](#string) | The URL of the design resized to fit within the bounds of 432x230. This will be `null` if the image has not been generated. |
-| <a id="designissue"></a>`issue` | [`Issue!`](#issue) | The issue the design belongs to. |
+| <a id="designissue"></a>`issue` | [`Issue!`](#issue) | Issue the design belongs to. |
| <a id="designnotes"></a>`notes` | [`NoteConnection!`](#noteconnection) | All notes on this noteable. (see [Connections](#connections)) |
-| <a id="designnotescount"></a>`notesCount` | [`Int!`](#int) | The total count of user-created notes for this design. |
-| <a id="designproject"></a>`project` | [`Project!`](#project) | The project the design belongs to. |
+| <a id="designnotescount"></a>`notesCount` | [`Int!`](#int) | Total count of user-created notes for this design. |
+| <a id="designproject"></a>`project` | [`Project!`](#project) | Project the design belongs to. |
#### Fields with arguments
@@ -8593,18 +9016,18 @@ A design pinned to a specific version. The image field reflects the design as of
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="designatversiondesign"></a>`design` | [`Design!`](#design) | The underlying design. |
-| <a id="designatversiondiffrefs"></a>`diffRefs` | [`DiffRefs!`](#diffrefs) | The diff refs for this design. |
+| <a id="designatversiondesign"></a>`design` | [`Design!`](#design) | Underlying design. |
+| <a id="designatversiondiffrefs"></a>`diffRefs` | [`DiffRefs!`](#diffrefs) | Diff refs for this design. |
| <a id="designatversionevent"></a>`event` | [`DesignVersionEvent!`](#designversionevent) | How this design was changed in the current version. |
-| <a id="designatversionfilename"></a>`filename` | [`String!`](#string) | The filename of the design. |
-| <a id="designatversionfullpath"></a>`fullPath` | [`String!`](#string) | The full path to the design file. |
-| <a id="designatversionid"></a>`id` | [`ID!`](#id) | The ID of this design. |
-| <a id="designatversionimage"></a>`image` | [`String!`](#string) | The URL of the full-sized image. |
+| <a id="designatversionfilename"></a>`filename` | [`String!`](#string) | Filename of the design. |
+| <a id="designatversionfullpath"></a>`fullPath` | [`String!`](#string) | Full path to the design file. |
+| <a id="designatversionid"></a>`id` | [`ID!`](#id) | ID of this design. |
+| <a id="designatversionimage"></a>`image` | [`String!`](#string) | URL of the full-sized image. |
| <a id="designatversionimagev432x230"></a>`imageV432x230` | [`String`](#string) | The URL of the design resized to fit within the bounds of 432x230. This will be `null` if the image has not been generated. |
-| <a id="designatversionissue"></a>`issue` | [`Issue!`](#issue) | The issue the design belongs to. |
-| <a id="designatversionnotescount"></a>`notesCount` | [`Int!`](#int) | The total count of user-created notes for this design. |
-| <a id="designatversionproject"></a>`project` | [`Project!`](#project) | The project the design belongs to. |
-| <a id="designatversionversion"></a>`version` | [`DesignVersion!`](#designversion) | The version this design-at-versions is pinned to. |
+| <a id="designatversionissue"></a>`issue` | [`Issue!`](#issue) | Issue the design belongs to. |
+| <a id="designatversionnotescount"></a>`notesCount` | [`Int!`](#int) | Total count of user-created notes for this design. |
+| <a id="designatversionproject"></a>`project` | [`Project!`](#project) | Project the design belongs to. |
+| <a id="designatversionversion"></a>`version` | [`DesignVersion!`](#designversion) | Version this design-at-versions is pinned to. |
### `DesignCollection`
@@ -8830,16 +9253,16 @@ Snapshot.
| <a id="devopsadoptionsnapshotdastenabledcount"></a>`dastEnabledCount` | [`Int`](#int) | Total number of projects with enabled DAST. |
| <a id="devopsadoptionsnapshotdependencyscanningenabledcount"></a>`dependencyScanningEnabledCount` | [`Int`](#int) | Total number of projects with enabled dependency scanning. |
| <a id="devopsadoptionsnapshotdeploysucceeded"></a>`deploySucceeded` | [`Boolean!`](#boolean) | At least one deployment succeeded. |
-| <a id="devopsadoptionsnapshotendtime"></a>`endTime` | [`Time!`](#time) | The end time for the snapshot where the data points were collected. |
+| <a id="devopsadoptionsnapshotendtime"></a>`endTime` | [`Time!`](#time) | End time for the snapshot where the data points were collected. |
| <a id="devopsadoptionsnapshotissueopened"></a>`issueOpened` | [`Boolean!`](#boolean) | At least one issue was opened. |
| <a id="devopsadoptionsnapshotmergerequestapproved"></a>`mergeRequestApproved` | [`Boolean!`](#boolean) | At least one merge request was approved. |
| <a id="devopsadoptionsnapshotmergerequestopened"></a>`mergeRequestOpened` | [`Boolean!`](#boolean) | At least one merge request was opened. |
| <a id="devopsadoptionsnapshotpipelinesucceeded"></a>`pipelineSucceeded` | [`Boolean!`](#boolean) | At least one pipeline succeeded. |
-| <a id="devopsadoptionsnapshotrecordedat"></a>`recordedAt` | [`Time!`](#time) | The time the snapshot was recorded. |
+| <a id="devopsadoptionsnapshotrecordedat"></a>`recordedAt` | [`Time!`](#time) | Time the snapshot was recorded. |
| <a id="devopsadoptionsnapshotrunnerconfigured"></a>`runnerConfigured` | [`Boolean!`](#boolean) | At least one runner was used. |
| <a id="devopsadoptionsnapshotsastenabledcount"></a>`sastEnabledCount` | [`Int`](#int) | Total number of projects with enabled SAST. |
| <a id="devopsadoptionsnapshotsecurityscansucceeded"></a>`securityScanSucceeded` **{warning-solid}** | [`Boolean!`](#boolean) | **Deprecated** in 14.1. Substituted with specific security metrics. Always false. |
-| <a id="devopsadoptionsnapshotstarttime"></a>`startTime` | [`Time!`](#time) | The start time for the snapshot where the data points were collected. |
+| <a id="devopsadoptionsnapshotstarttime"></a>`startTime` | [`Time!`](#time) | Start time for the snapshot where the data points were collected. |
| <a id="devopsadoptionsnapshottotalprojectscount"></a>`totalProjectsCount` | [`Int`](#int) | Total number of projects. |
| <a id="devopsadoptionsnapshotvulnerabilitymanagementusedcount"></a>`vulnerabilityManagementUsedCount` | [`Int`](#int) | Total number of projects with vulnerability management used at least once. |
@@ -8929,9 +9352,9 @@ Returns [`[DoraMetric!]`](#dorametric).
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="dorametricsenddate"></a>`endDate` | [`Date`](#date) | Date range to end at. Default is the current date. |
-| <a id="dorametricsenvironmenttier"></a>`environmentTier` | [`DeploymentTier`](#deploymenttier) | The deployment tier of the environments to return. Defaults to `PRODUCTION`. |
+| <a id="dorametricsenvironmenttier"></a>`environmentTier` | [`DeploymentTier`](#deploymenttier) | Deployment tier of the environments to return. Defaults to `PRODUCTION`. |
| <a id="dorametricsinterval"></a>`interval` | [`DoraMetricBucketingInterval`](#dorametricbucketinginterval) | How the metric should be aggregrated. Defaults to `DAILY`. In the case of `ALL`, the `date` field in the response will be `null`. |
-| <a id="dorametricsmetric"></a>`metric` | [`DoraMetricType!`](#dorametrictype) | The type of metric to return. |
+| <a id="dorametricsmetric"></a>`metric` | [`DoraMetricType!`](#dorametrictype) | Type of metric to return. |
| <a id="dorametricsstartdate"></a>`startDate` | [`Date`](#date) | Date range to start from. Default is 3 months ago. |
### `DoraMetric`
@@ -8952,9 +9375,9 @@ Describes where code is deployed for a project.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="environmentid"></a>`id` | [`ID!`](#id) | ID of the environment. |
-| <a id="environmentlatestopenedmostseverealert"></a>`latestOpenedMostSevereAlert` | [`AlertManagementAlert`](#alertmanagementalert) | The most severe open alert for the environment. If multiple alerts have equal severity, the most recent is returned. |
+| <a id="environmentlatestopenedmostseverealert"></a>`latestOpenedMostSevereAlert` | [`AlertManagementAlert`](#alertmanagementalert) | Most severe open alert for the environment. If multiple alerts have equal severity, the most recent is returned. |
| <a id="environmentname"></a>`name` | [`String!`](#string) | Human-readable name of the environment. |
-| <a id="environmentpath"></a>`path` | [`String!`](#string) | The path to the environment. |
+| <a id="environmentpath"></a>`path` | [`String!`](#string) | Path to the environment. |
| <a id="environmentstate"></a>`state` | [`String!`](#string) | State of the environment, for example: available/stopped. |
#### Fields with arguments
@@ -8980,7 +9403,7 @@ Represents an epic.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="epicauthor"></a>`author` | [`UserCore!`](#usercore) | Author of the epic. |
-| <a id="epicawardemoji"></a>`awardEmoji` | [`AwardEmojiConnection`](#awardemojiconnection) | A list of award emojis associated with the epic. (see [Connections](#connections)) |
+| <a id="epicawardemoji"></a>`awardEmoji` | [`AwardEmojiConnection`](#awardemojiconnection) | List of award emojis associated with the epic. (see [Connections](#connections)) |
| <a id="epicclosedat"></a>`closedAt` | [`Time`](#time) | Timestamp of when the epic was closed. |
| <a id="epicconfidential"></a>`confidential` | [`Boolean`](#boolean) | Indicates if the epic is confidential. |
| <a id="epiccreatedat"></a>`createdAt` | [`Time`](#time) | Timestamp of when the epic was created. |
@@ -8994,7 +9417,7 @@ Represents an epic.
| <a id="epicduedatefixed"></a>`dueDateFixed` | [`Time`](#time) | Fixed due date of the epic. |
| <a id="epicduedatefrommilestones"></a>`dueDateFromMilestones` | [`Time`](#time) | Inherited due date of the epic from milestones. |
| <a id="epicduedateisfixed"></a>`dueDateIsFixed` | [`Boolean`](#boolean) | Indicates if the due date has been manually set. |
-| <a id="epicevents"></a>`events` | [`EventConnection`](#eventconnection) | A list of events associated with the object. (see [Connections](#connections)) |
+| <a id="epicevents"></a>`events` | [`EventConnection`](#eventconnection) | List of events associated with the object. (see [Connections](#connections)) |
| <a id="epicgroup"></a>`group` | [`Group!`](#group) | Group to which the epic belongs. |
| <a id="epichaschildren"></a>`hasChildren` | [`Boolean!`](#boolean) | Indicates if the epic has children. |
| <a id="epichasissues"></a>`hasIssues` | [`Boolean!`](#boolean) | Indicates if the epic has direct issues. |
@@ -9008,7 +9431,7 @@ Represents an epic.
| <a id="epicparent"></a>`parent` | [`Epic`](#epic) | Parent epic of the epic. |
| <a id="epicparticipants"></a>`participants` | [`UserCoreConnection`](#usercoreconnection) | List of participants for the epic. (see [Connections](#connections)) |
| <a id="epicrelationpath"></a>`relationPath` | [`String`](#string) | URI path of the epic-issue relationship. |
-| <a id="epicrelativeposition"></a>`relativePosition` | [`Int`](#int) | The relative position of the epic in the epic tree. |
+| <a id="epicrelativeposition"></a>`relativePosition` | [`Int`](#int) | Relative position of the epic in the epic tree. |
| <a id="epicstartdate"></a>`startDate` | [`Time`](#time) | Start date of the epic. |
| <a id="epicstartdatefixed"></a>`startDateFixed` | [`Time`](#time) | Fixed start date of the epic. |
| <a id="epicstartdatefrommilestones"></a>`startDateFromMilestones` | [`Time`](#time) | Inherited start date of the epic from milestones. |
@@ -9222,6 +9645,7 @@ Relationship between an epic and an issue.
| <a id="epicissueepic"></a>`epic` | [`Epic`](#epic) | Epic to which this issue belongs. |
| <a id="epicissueepicissueid"></a>`epicIssueId` | [`ID!`](#id) | ID of the epic-issue relation. |
| <a id="epicissuehealthstatus"></a>`healthStatus` | [`HealthStatus`](#healthstatus) | Current health status. |
+| <a id="epicissuehidden"></a>`hidden` | [`Boolean`](#boolean) | Indicates the issue is hidden because the author has been banned. Will always return `null` if `ban_user_feature_flag` feature flag is disabled. |
| <a id="epicissuehumantimeestimate"></a>`humanTimeEstimate` | [`String`](#string) | Human-readable time estimate of the issue. |
| <a id="epicissuehumantotaltimespent"></a>`humanTotalTimeSpent` | [`String`](#string) | Human-readable total time reported as spent on the issue. |
| <a id="epicissueid"></a>`id` | [`ID`](#id) | Global ID of the epic-issue relation. |
@@ -9349,9 +9773,9 @@ Represents an escalation policy.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="escalationpolicytypedescription"></a>`description` | [`String`](#string) | The description of the escalation policy. |
+| <a id="escalationpolicytypedescription"></a>`description` | [`String`](#string) | Description of the escalation policy. |
| <a id="escalationpolicytypeid"></a>`id` | [`IncidentManagementEscalationPolicyID`](#incidentmanagementescalationpolicyid) | ID of the escalation policy. |
-| <a id="escalationpolicytypename"></a>`name` | [`String`](#string) | The name of the escalation policy. |
+| <a id="escalationpolicytypename"></a>`name` | [`String`](#string) | Name of the escalation policy. |
| <a id="escalationpolicytyperules"></a>`rules` | [`[EscalationRuleType!]`](#escalationruletype) | Steps of the escalation policy. |
### `EscalationRuleType`
@@ -9362,11 +9786,11 @@ Represents an escalation rule for an escalation policy.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="escalationruletypeelapsedtimeseconds"></a>`elapsedTimeSeconds` | [`Int`](#int) | The time in seconds before the rule is activated. |
+| <a id="escalationruletypeelapsedtimeseconds"></a>`elapsedTimeSeconds` | [`Int`](#int) | Time in seconds before the rule is activated. |
| <a id="escalationruletypeid"></a>`id` | [`IncidentManagementEscalationRuleID`](#incidentmanagementescalationruleid) | ID of the escalation policy. |
-| <a id="escalationruletypeoncallschedule"></a>`oncallSchedule` | [`IncidentManagementOncallSchedule`](#incidentmanagementoncallschedule) | The on-call schedule to notify. |
-| <a id="escalationruletypestatus"></a>`status` | [`EscalationRuleStatus`](#escalationrulestatus) | The status required to prevent the rule from activating. |
-| <a id="escalationruletypeuser"></a>`user` | [`UserCore`](#usercore) | The user to notify. |
+| <a id="escalationruletypeoncallschedule"></a>`oncallSchedule` | [`IncidentManagementOncallSchedule`](#incidentmanagementoncallschedule) | On-call schedule to notify. |
+| <a id="escalationruletypestatus"></a>`status` | [`EscalationRuleStatus`](#escalationrulestatus) | Status required to prevent the rule from activating. |
+| <a id="escalationruletypeuser"></a>`user` | [`UserCore`](#usercore) | User to notify. |
### `Event`
@@ -9404,21 +9828,21 @@ Represents an external issue.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="geonodecontainerrepositoriesmaxcapacity"></a>`containerRepositoriesMaxCapacity` | [`Int`](#int) | The maximum concurrency of container repository sync for this secondary node. |
+| <a id="geonodecontainerrepositoriesmaxcapacity"></a>`containerRepositoriesMaxCapacity` | [`Int`](#int) | Maximum concurrency of container repository sync for this secondary node. |
| <a id="geonodeenabled"></a>`enabled` | [`Boolean`](#boolean) | Indicates whether this Geo node is enabled. |
-| <a id="geonodefilesmaxcapacity"></a>`filesMaxCapacity` | [`Int`](#int) | The maximum concurrency of LFS/attachment backfill for this secondary node. |
+| <a id="geonodefilesmaxcapacity"></a>`filesMaxCapacity` | [`Int`](#int) | Maximum concurrency of LFS/attachment backfill for this secondary node. |
| <a id="geonodeid"></a>`id` | [`ID!`](#id) | ID of this GeoNode. |
-| <a id="geonodeinternalurl"></a>`internalUrl` | [`String`](#string) | The URL defined on the primary node that secondary nodes should use to contact it. |
-| <a id="geonodeminimumreverificationinterval"></a>`minimumReverificationInterval` | [`Int`](#int) | The interval (in days) in which the repository verification is valid. Once expired, it will be reverified. |
-| <a id="geonodename"></a>`name` | [`String`](#string) | The unique identifier for this Geo node. |
+| <a id="geonodeinternalurl"></a>`internalUrl` | [`String`](#string) | URL defined on the primary node secondary nodes should use to contact it. |
+| <a id="geonodeminimumreverificationinterval"></a>`minimumReverificationInterval` | [`Int`](#int) | Interval (in days) in which the repository verification is valid. After expiry, it is reverted. |
+| <a id="geonodename"></a>`name` | [`String`](#string) | Unique identifier for this Geo node. |
| <a id="geonodeprimary"></a>`primary` | [`Boolean`](#boolean) | Indicates whether this Geo node is the primary. |
-| <a id="geonodereposmaxcapacity"></a>`reposMaxCapacity` | [`Int`](#int) | The maximum concurrency of repository backfill for this secondary node. |
-| <a id="geonodeselectivesyncnamespaces"></a>`selectiveSyncNamespaces` | [`NamespaceConnection`](#namespaceconnection) | The namespaces that should be synced, if `selective_sync_type` == `namespaces`. (see [Connections](#connections)) |
-| <a id="geonodeselectivesyncshards"></a>`selectiveSyncShards` | [`[String!]`](#string) | The repository storages whose projects should be synced, if `selective_sync_type` == `shards`. |
+| <a id="geonodereposmaxcapacity"></a>`reposMaxCapacity` | [`Int`](#int) | Maximum concurrency of repository backfill for this secondary node. |
+| <a id="geonodeselectivesyncnamespaces"></a>`selectiveSyncNamespaces` | [`NamespaceConnection`](#namespaceconnection) | Namespaces that should be synced, if `selective_sync_type` == `namespaces`. (see [Connections](#connections)) |
+| <a id="geonodeselectivesyncshards"></a>`selectiveSyncShards` | [`[String!]`](#string) | Repository storages whose projects should be synced, if `selective_sync_type` == `shards`. |
| <a id="geonodeselectivesynctype"></a>`selectiveSyncType` | [`String`](#string) | Indicates if syncing is limited to only specific groups, or shards. |
| <a id="geonodesyncobjectstorage"></a>`syncObjectStorage` | [`Boolean`](#boolean) | Indicates if this secondary node will replicate blobs in Object Storage. |
-| <a id="geonodeurl"></a>`url` | [`String`](#string) | The user-facing URL for this Geo node. |
-| <a id="geonodeverificationmaxcapacity"></a>`verificationMaxCapacity` | [`Int`](#int) | The maximum concurrency of repository verification for this secondary node. |
+| <a id="geonodeurl"></a>`url` | [`String`](#string) | User-facing URL for this Geo node. |
+| <a id="geonodeverificationmaxcapacity"></a>`verificationMaxCapacity` | [`Int`](#int) | Maximum concurrency of repository verification for this secondary node. |
#### Fields with arguments
@@ -9486,6 +9910,22 @@ four standard [pagination arguments](#connection-pagination-arguments):
| ---- | ---- | ----------- |
| <a id="geonodepackagefileregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. |
+##### `GeoNode.pagesDeploymentRegistries`
+
+Find Pages Deployment registries on this Geo node.
+
+Returns [`PagesDeploymentRegistryConnection`](#pagesdeploymentregistryconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="geonodepagesdeploymentregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. |
+
##### `GeoNode.pipelineArtifactRegistries`
Find pipeline artifact registries on this Geo node.
@@ -9534,6 +9974,22 @@ four standard [pagination arguments](#connection-pagination-arguments):
| ---- | ---- | ----------- |
| <a id="geonodeterraformstateversionregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. |
+##### `GeoNode.uploadRegistries`
+
+Find Upload registries on this Geo node Available only when feature flag `geo_upload_replication` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice.
+
+Returns [`UploadRegistryConnection`](#uploadregistryconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="geonodeuploadregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. |
+
### `GrafanaIntegration`
#### Fields
@@ -9556,13 +10012,22 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="groupadditionalpurchasedstoragesize"></a>`additionalPurchasedStorageSize` | [`Float`](#float) | Additional storage purchased for the root namespace in bytes. |
| <a id="groupautodevopsenabled"></a>`autoDevopsEnabled` | [`Boolean`](#boolean) | Indicates whether Auto DevOps is enabled for all projects within this group. |
| <a id="groupavatarurl"></a>`avatarUrl` | [`String`](#string) | Avatar URL of the group. |
-| <a id="groupbillablememberscount"></a>`billableMembersCount` | [`Int`](#int) | The number of billable users in the group. |
+| <a id="groupbillablememberscount"></a>`billableMembersCount` | [`Int`](#int) | Number of billable users in the group. |
+| <a id="groupcontacts"></a>`contacts` | [`CustomerRelationsContactConnection`](#customerrelationscontactconnection) | Find contacts of this group. (see [Connections](#connections)) |
| <a id="groupcontainerrepositoriescount"></a>`containerRepositoriesCount` | [`Int!`](#int) | Number of container repositories in the group. |
| <a id="groupcontainslockedprojects"></a>`containsLockedProjects` | [`Boolean!`](#boolean) | Includes at least one project where the repository size exceeds the limit. |
| <a id="groupcustomemoji"></a>`customEmoji` | [`CustomEmojiConnection`](#customemojiconnection) | Custom emoji within this namespace. Available only when feature flag `custom_emoji` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice. (see [Connections](#connections)) |
+| <a id="groupdependencyproxyblobcount"></a>`dependencyProxyBlobCount` | [`Int!`](#int) | Number of dependency proxy blobs cached in the group. |
+| <a id="groupdependencyproxyblobs"></a>`dependencyProxyBlobs` | [`DependencyProxyBlobConnection`](#dependencyproxyblobconnection) | Dependency Proxy blobs. (see [Connections](#connections)) |
+| <a id="groupdependencyproxyimagecount"></a>`dependencyProxyImageCount` | [`Int!`](#int) | Number of dependency proxy images cached in the group. |
+| <a id="groupdependencyproxyimageprefix"></a>`dependencyProxyImagePrefix` | [`String!`](#string) | Prefix for pulling images when using the dependency proxy. |
+| <a id="groupdependencyproxyimagettlpolicy"></a>`dependencyProxyImageTtlPolicy` | [`DependencyProxyImageTtlGroupPolicy`](#dependencyproxyimagettlgrouppolicy) | Dependency proxy TTL policy for the group. |
+| <a id="groupdependencyproxymanifests"></a>`dependencyProxyManifests` | [`DependencyProxyManifestConnection`](#dependencyproxymanifestconnection) | Dependency Proxy manifests. (see [Connections](#connections)) |
+| <a id="groupdependencyproxysetting"></a>`dependencyProxySetting` | [`DependencyProxySetting`](#dependencyproxysetting) | Dependency Proxy settings for the group. |
+| <a id="groupdependencyproxytotalsize"></a>`dependencyProxyTotalSize` | [`String!`](#string) | Total size of the dependency proxy cached images. |
| <a id="groupdescription"></a>`description` | [`String`](#string) | Description of the namespace. |
| <a id="groupdescriptionhtml"></a>`descriptionHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `description`. |
-| <a id="groupdora"></a>`dora` | [`Dora`](#dora) | The group's DORA metrics. |
+| <a id="groupdora"></a>`dora` | [`Dora`](#dora) | Group's DORA metrics. |
| <a id="groupemailsdisabled"></a>`emailsDisabled` | [`Boolean`](#boolean) | Indicates if a group has email notifications disabled. |
| <a id="groupepicboards"></a>`epicBoards` | [`EpicBoardConnection`](#epicboardconnection) | Find epic boards. (see [Connections](#connections)) |
| <a id="groupepicsenabled"></a>`epicsEnabled` | [`Boolean`](#boolean) | Indicates if Epics are enabled for namespace. |
@@ -9573,10 +10038,11 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="grouplfsenabled"></a>`lfsEnabled` | [`Boolean`](#boolean) | Indicates if Large File Storage (LFS) is enabled for namespace. |
| <a id="groupmentionsdisabled"></a>`mentionsDisabled` | [`Boolean`](#boolean) | Indicates if a group is disabled from getting mentioned. |
| <a id="groupname"></a>`name` | [`String!`](#string) | Name of the namespace. |
-| <a id="grouppackagesettings"></a>`packageSettings` | [`PackageSettings`](#packagesettings) | The package settings for the namespace. |
+| <a id="grouporganizations"></a>`organizations` | [`CustomerRelationsOrganizationConnection`](#customerrelationsorganizationconnection) | Find organizations of this group. (see [Connections](#connections)) |
+| <a id="grouppackagesettings"></a>`packageSettings` | [`PackageSettings`](#packagesettings) | Package settings for the namespace. |
| <a id="groupparent"></a>`parent` | [`Group`](#group) | Parent group. |
| <a id="grouppath"></a>`path` | [`String!`](#string) | Path of the namespace. |
-| <a id="groupprojectcreationlevel"></a>`projectCreationLevel` | [`String`](#string) | The permission level required to create projects in the group. |
+| <a id="groupprojectcreationlevel"></a>`projectCreationLevel` | [`String`](#string) | Permission level required to create projects in the group. |
| <a id="grouprepositorysizeexcessprojectcount"></a>`repositorySizeExcessProjectCount` | [`Int!`](#int) | Number of projects in the root namespace where the repository size exceeds the limit. |
| <a id="grouprequestaccessenabled"></a>`requestAccessEnabled` | [`Boolean`](#boolean) | Indicates if users can request access to namespace. |
| <a id="grouprequiretwofactorauthentication"></a>`requireTwoFactorAuthentication` | [`Boolean`](#boolean) | Indicates if all users in this group are required to set up two-factor authentication. |
@@ -9585,7 +10051,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="groupsharedrunnerssetting"></a>`sharedRunnersSetting` | [`SharedRunnersSetting`](#sharedrunnerssetting) | Shared runners availability for the namespace and its descendants. |
| <a id="groupstats"></a>`stats` | [`GroupStats`](#groupstats) | Group statistics. |
| <a id="groupstoragesizelimit"></a>`storageSizeLimit` | [`Float`](#float) | Total storage limit of the root namespace in bytes. |
-| <a id="groupsubgroupcreationlevel"></a>`subgroupCreationLevel` | [`String`](#string) | The permission level required to create subgroups within the group. |
+| <a id="groupsubgroupcreationlevel"></a>`subgroupCreationLevel` | [`String`](#string) | Permission level required to create subgroups within the group. |
| <a id="grouptemporarystorageincreaseendson"></a>`temporaryStorageIncreaseEndsOn` | [`Time`](#time) | Date until the temporary storage increase is active. |
| <a id="grouptotalrepositorysize"></a>`totalRepositorySize` | [`Float`](#float) | Total repository size of all projects in the root namespace in bytes. |
| <a id="grouptotalrepositorysizeexcess"></a>`totalRepositorySizeExcess` | [`Float`](#float) | Total excess repository size of all projects in the root namespace in bytes. |
@@ -9797,7 +10263,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="groupissuesassigneeid"></a>`assigneeId` | [`String`](#string) | ID of a user assigned to the issues, "none" and "any" values are supported. |
+| <a id="groupissuesassigneeid"></a>`assigneeId` | [`String`](#string) | ID of a user assigned to the issues. Wildcard values "NONE" and "ANY" are supported. |
| <a id="groupissuesassigneeusername"></a>`assigneeUsername` **{warning-solid}** | [`String`](#string) | **Deprecated** in 13.11. Use `assigneeUsernames`. |
| <a id="groupissuesassigneeusernames"></a>`assigneeUsernames` | [`[String!]`](#string) | Usernames of users assigned to the issue. |
| <a id="groupissuesauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author of the issue. |
@@ -9814,6 +10280,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="groupissueslabelname"></a>`labelName` | [`[String]`](#string) | Labels applied to this issue. |
| <a id="groupissuesmilestonetitle"></a>`milestoneTitle` | [`[String]`](#string) | Milestone applied to this issue. |
| <a id="groupissuesmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. |
+| <a id="groupissuesmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. Wildcard values "NONE" and "ANY" are supported. |
| <a id="groupissuesnot"></a>`not` | [`NegatedIssueFilterInput`](#negatedissuefilterinput) | Negated arguments. |
| <a id="groupissuessearch"></a>`search` | [`String`](#string) | Search query for issue title or description. |
| <a id="groupissuessort"></a>`sort` | [`IssueSort`](#issuesort) | Sort issues by this criteria. |
@@ -9870,7 +10337,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
##### `Group.label`
-A label available on this group.
+Label available on this group.
Returns [`Label`](#label).
@@ -9897,7 +10364,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="grouplabelsincludeancestorgroups"></a>`includeAncestorGroups` | [`Boolean`](#boolean) | Include labels from ancestor groups. |
| <a id="grouplabelsincludedescendantgroups"></a>`includeDescendantGroups` | [`Boolean`](#boolean) | Include labels from descendant groups. |
| <a id="grouplabelsonlygrouplabels"></a>`onlyGroupLabels` | [`Boolean`](#boolean) | Include only group level labels. |
-| <a id="grouplabelssearchterm"></a>`searchTerm` | [`String`](#string) | A search term to find labels with. |
+| <a id="grouplabelssearchterm"></a>`searchTerm` | [`String`](#string) | Search term to find labels with. |
##### `Group.mergeRequests`
@@ -9924,7 +10391,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="groupmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
| <a id="groupmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. |
| <a id="groupmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. |
-| <a id="groupmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | A merge request state. If provided, all resolved merge requests will have this state. |
+| <a id="groupmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. |
| <a id="groupmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. |
##### `Group.milestones`
@@ -9941,17 +10408,17 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="groupmilestonescontainingdate"></a>`containingDate` | [`Time`](#time) | A date that the milestone contains. |
+| <a id="groupmilestonescontainingdate"></a>`containingDate` | [`Time`](#time) | Date the milestone contains. |
| <a id="groupmilestonesenddate"></a>`endDate` **{warning-solid}** | [`Time`](#time) | **Deprecated** in 13.5. Use timeframe.end. |
| <a id="groupmilestonesids"></a>`ids` | [`[ID!]`](#id) | Array of global milestone IDs, e.g., `"gid://gitlab/Milestone/1"`. |
| <a id="groupmilestonesincludeancestors"></a>`includeAncestors` | [`Boolean`](#boolean) | Include milestones from all parent groups. |
| <a id="groupmilestonesincludedescendants"></a>`includeDescendants` | [`Boolean`](#boolean) | Include milestones from all subgroups and subprojects. |
-| <a id="groupmilestonessearchtitle"></a>`searchTitle` | [`String`](#string) | A search string for the title. |
+| <a id="groupmilestonessearchtitle"></a>`searchTitle` | [`String`](#string) | Search string for the title. |
| <a id="groupmilestonessort"></a>`sort` | [`MilestoneSort`](#milestonesort) | Sort milestones by this criteria. |
| <a id="groupmilestonesstartdate"></a>`startDate` **{warning-solid}** | [`Time`](#time) | **Deprecated** in 13.5. Use timeframe.start. |
| <a id="groupmilestonesstate"></a>`state` | [`MilestoneStateEnum`](#milestonestateenum) | Filter milestones by state. |
| <a id="groupmilestonestimeframe"></a>`timeframe` | [`Timeframe`](#timeframe) | List items overlapping the given timeframe. |
-| <a id="groupmilestonestitle"></a>`title` | [`String`](#string) | The title of the milestone. |
+| <a id="groupmilestonestitle"></a>`title` | [`String`](#string) | Title of the milestone. |
##### `Group.packages`
@@ -9994,6 +10461,27 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="groupprojectssearch"></a>`search` | [`String`](#string) | Search project with most similar names or paths. |
| <a id="groupprojectssort"></a>`sort` | [`NamespaceProjectSort`](#namespaceprojectsort) | Sort projects by this criteria. |
+##### `Group.runners`
+
+Find runners visible to the current user.
+
+Returns [`CiRunnerConnection`](#cirunnerconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="grouprunnersmembership"></a>`membership` | [`RunnerMembershipFilter`](#runnermembershipfilter) | Control which runners to include in the results. |
+| <a id="grouprunnerssearch"></a>`search` | [`String`](#string) | Filter by full token or partial text in description field. |
+| <a id="grouprunnerssort"></a>`sort` | [`CiRunnerSort`](#cirunnersort) | Sort order of results. |
+| <a id="grouprunnersstatus"></a>`status` | [`CiRunnerStatus`](#cirunnerstatus) | Filter runners by status. |
+| <a id="grouprunnerstaglist"></a>`tagList` | [`[String!]`](#string) | Filter by tags associated with the runner (comma-separated or array). |
+| <a id="grouprunnerstype"></a>`type` | [`CiRunnerType`](#cirunnertype) | Filter runners by type. |
+
##### `Group.timelogs`
Time logged on issues and merge requests in the group and its subgroups.
@@ -10112,6 +10600,7 @@ Represents a Group Membership.
| Name | Type | Description |
| ---- | ---- | ----------- |
+| <a id="grouppermissionscreateprojects"></a>`createProjects` | [`Boolean!`](#boolean) | Indicates the user can perform `create_projects` on this resource. |
| <a id="grouppermissionsreadgroup"></a>`readGroup` | [`Boolean!`](#boolean) | Indicates the user can perform `read_group` on this resource. |
### `GroupReleaseStats`
@@ -10199,6 +10688,7 @@ Describes an incident management on-call schedule.
| <a id="incidentmanagementoncallscheduledescription"></a>`description` | [`String`](#string) | Description of the on-call schedule. |
| <a id="incidentmanagementoncallscheduleiid"></a>`iid` | [`ID!`](#id) | Internal ID of the on-call schedule. |
| <a id="incidentmanagementoncallschedulename"></a>`name` | [`String!`](#string) | Name of the on-call schedule. |
+| <a id="incidentmanagementoncallscheduleoncallusers"></a>`oncallUsers` | [`[UserCore!]`](#usercore) | |
| <a id="incidentmanagementoncallschedulerotations"></a>`rotations` | [`IncidentManagementOncallRotationConnection!`](#incidentmanagementoncallrotationconnection) | On-call rotations for the on-call schedule. (see [Connections](#connections)) |
| <a id="incidentmanagementoncallscheduletimezone"></a>`timezone` | [`String!`](#string) | Time zone of the on-call schedule. |
@@ -10301,6 +10791,7 @@ Returns [`VulnerabilitySeveritiesCount`](#vulnerabilityseveritiescount).
| <a id="issueemailsdisabled"></a>`emailsDisabled` | [`Boolean!`](#boolean) | Indicates if a project has email notifications disabled: `true` if email notifications are disabled. |
| <a id="issueepic"></a>`epic` | [`Epic`](#epic) | Epic to which this issue belongs. |
| <a id="issuehealthstatus"></a>`healthStatus` | [`HealthStatus`](#healthstatus) | Current health status. |
+| <a id="issuehidden"></a>`hidden` | [`Boolean`](#boolean) | Indicates the issue is hidden because the author has been banned. Will always return `null` if `ban_user_feature_flag` feature flag is disabled. |
| <a id="issuehumantimeestimate"></a>`humanTimeEstimate` | [`String`](#string) | Human-readable time estimate of the issue. |
| <a id="issuehumantotaltimespent"></a>`humanTotalTimeSpent` | [`String`](#string) | Human-readable total time reported as spent on the issue. |
| <a id="issueid"></a>`id` | [`ID!`](#id) | ID of the issue. |
@@ -10521,7 +11012,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="kasenabled"></a>`enabled` | [`Boolean!`](#boolean) | Indicates whether the Kubernetes Agent Server is enabled. |
-| <a id="kasexternalurl"></a>`externalUrl` | [`String`](#string) | The URL used by the Agents to communicate with KAS. |
+| <a id="kasexternalurl"></a>`externalUrl` | [`String`](#string) | URL used by the Agents to communicate with KAS. |
| <a id="kasversion"></a>`version` | [`String`](#string) | KAS version. |
### `Label`
@@ -10599,6 +11090,7 @@ Maven metadata.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mergerequestallowcollaboration"></a>`allowCollaboration` | [`Boolean`](#boolean) | Indicates if members of the target project can push to the fork. |
+| <a id="mergerequestapprovalstate"></a>`approvalState` | [`MergeRequestApprovalState!`](#mergerequestapprovalstate) | Information relating to rules that must be satisfied to merge this merge request. |
| <a id="mergerequestapprovalsleft"></a>`approvalsLeft` | [`Int`](#int) | Number of approvals left. |
| <a id="mergerequestapprovalsrequired"></a>`approvalsRequired` | [`Int`](#int) | Number of approvals required. |
| <a id="mergerequestapproved"></a>`approved` | [`Boolean!`](#boolean) | Indicates if the merge request has all the required approvals. Returns true if no required approvals are configured. |
@@ -10628,7 +11120,7 @@ Maven metadata.
| <a id="mergerequestforceremovesourcebranch"></a>`forceRemoveSourceBranch` | [`Boolean`](#boolean) | Indicates if the project settings will lead to source branch deletion after merge. |
| <a id="mergerequesthasci"></a>`hasCi` | [`Boolean!`](#boolean) | Indicates if the merge request has CI. |
| <a id="mergerequesthassecurityreports"></a>`hasSecurityReports` | [`Boolean!`](#boolean) | Indicates if the source branch has any security reports. |
-| <a id="mergerequestheadpipeline"></a>`headPipeline` | [`Pipeline`](#pipeline) | The pipeline running on the branch HEAD of the merge request. |
+| <a id="mergerequestheadpipeline"></a>`headPipeline` | [`Pipeline`](#pipeline) | Pipeline running on the branch HEAD of the merge request. |
| <a id="mergerequesthumantimeestimate"></a>`humanTimeEstimate` | [`String`](#string) | Human-readable time estimate of the merge request. |
| <a id="mergerequesthumantotaltimespent"></a>`humanTotalTimeSpent` | [`String`](#string) | Human-readable total time reported as spent on the merge request. |
| <a id="mergerequestid"></a>`id` | [`ID!`](#id) | ID of the merge request. |
@@ -10646,7 +11138,7 @@ Maven metadata.
| <a id="mergerequestmergeable"></a>`mergeable` | [`Boolean!`](#boolean) | Indicates if the merge request is mergeable. |
| <a id="mergerequestmergeablediscussionsstate"></a>`mergeableDiscussionsState` | [`Boolean`](#boolean) | Indicates if all discussions in the merge request have been resolved, allowing the merge request to be merged. |
| <a id="mergerequestmergedat"></a>`mergedAt` | [`Time`](#time) | Timestamp of when the merge request was merged, null if not merged. |
-| <a id="mergerequestmilestone"></a>`milestone` | [`Milestone`](#milestone) | The milestone of the merge request. |
+| <a id="mergerequestmilestone"></a>`milestone` | [`Milestone`](#milestone) | Milestone of the merge request. |
| <a id="mergerequestnotes"></a>`notes` | [`NoteConnection!`](#noteconnection) | All notes on this noteable. (see [Connections](#connections)) |
| <a id="mergerequestparticipants"></a>`participants` | [`UserCoreConnection`](#usercoreconnection) | Participants in the merge request. This includes the author, assignees, reviewers, and users mentioned in notes. (see [Connections](#connections)) |
| <a id="mergerequestproject"></a>`project` | [`Project!`](#project) | Alias for target_project. |
@@ -10713,7 +11205,7 @@ Returns [`[DiffStats!]`](#diffstats).
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="mergerequestdiffstatspath"></a>`path` | [`String`](#string) | A specific file-path. |
+| <a id="mergerequestdiffstatspath"></a>`path` | [`String`](#string) | Specific file path. |
##### `MergeRequest.pipelines`
@@ -10731,6 +11223,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| ---- | ---- | ----------- |
| <a id="mergerequestpipelinesref"></a>`ref` | [`String`](#string) | Filter pipelines by the ref they are run for. |
| <a id="mergerequestpipelinessha"></a>`sha` | [`String`](#string) | Filter pipelines by the sha of the commit they are run for. |
+| <a id="mergerequestpipelinessource"></a>`source` | [`String`](#string) | Filter pipelines by their source. Will be ignored if `dast_view_scans` feature flag is disabled. |
| <a id="mergerequestpipelinesstatus"></a>`status` | [`PipelineStatusEnum`](#pipelinestatusenum) | Filter pipelines by their status. |
##### `MergeRequest.reference`
@@ -10745,6 +11238,17 @@ Returns [`String!`](#string).
| ---- | ---- | ----------- |
| <a id="mergerequestreferencefull"></a>`full` | [`Boolean`](#boolean) | Boolean option specifying whether the reference should be returned in full. |
+### `MergeRequestApprovalState`
+
+Information relating to rules that must be satisfied to merge this merge request.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestapprovalstateapprovalrulesoverwritten"></a>`approvalRulesOverwritten` | [`Boolean`](#boolean) | Indicates if the merge request approval rules are overwritten for the merge request. |
+| <a id="mergerequestapprovalstaterules"></a>`rules` | [`[ApprovalRule!]`](#approvalrule) | List of approval rules associated with the merge request. |
+
### `MergeRequestAssignee`
A user assigned to a merge request.
@@ -10760,7 +11264,7 @@ A user assigned to a merge request.
| <a id="mergerequestassigneegroupcount"></a>`groupCount` | [`Int`](#int) | Group count for the user. |
| <a id="mergerequestassigneegroupmemberships"></a>`groupMemberships` | [`GroupMemberConnection`](#groupmemberconnection) | Group memberships of the user. (see [Connections](#connections)) |
| <a id="mergerequestassigneeid"></a>`id` | [`ID!`](#id) | ID of the user. |
-| <a id="mergerequestassigneelocation"></a>`location` | [`String`](#string) | The location of the user. |
+| <a id="mergerequestassigneelocation"></a>`location` | [`String`](#string) | Location of the user. |
| <a id="mergerequestassigneemergerequestinteraction"></a>`mergeRequestInteraction` | [`UserMergeRequestInteraction`](#usermergerequestinteraction) | Details of this user's interactions with the merge request. |
| <a id="mergerequestassigneename"></a>`name` | [`String!`](#string) | Human-readable name of the user. |
| <a id="mergerequestassigneenamespace"></a>`namespace` | [`Namespace`](#namespace) | Personal namespace of the user. |
@@ -10801,7 +11305,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="mergerequestassigneeassignedmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
| <a id="mergerequestassigneeassignedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. |
| <a id="mergerequestassigneeassignedmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. |
-| <a id="mergerequestassigneeassignedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | A merge request state. If provided, all resolved merge requests will have this state. |
+| <a id="mergerequestassigneeassignedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. |
| <a id="mergerequestassigneeassignedmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. |
##### `MergeRequestAssignee.authoredMergeRequests`
@@ -10830,9 +11334,26 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="mergerequestassigneeauthoredmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
| <a id="mergerequestassigneeauthoredmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. |
| <a id="mergerequestassigneeauthoredmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. |
-| <a id="mergerequestassigneeauthoredmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | A merge request state. If provided, all resolved merge requests will have this state. |
+| <a id="mergerequestassigneeauthoredmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. |
| <a id="mergerequestassigneeauthoredmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. |
+##### `MergeRequestAssignee.groups`
+
+Groups where the user has access. Will always return `null` if `paginatable_namespace_drop_down_for_project_creation` feature flag is disabled.
+
+Returns [`GroupConnection`](#groupconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestassigneegroupspermissionscope"></a>`permissionScope` | [`GroupPermission`](#grouppermission) | Filter by permissions the user has on groups. |
+| <a id="mergerequestassigneegroupssearch"></a>`search` | [`String`](#string) | Search by group name or path. |
+
##### `MergeRequestAssignee.reviewRequestedMergeRequests`
Merge requests assigned to the user for review.
@@ -10859,7 +11380,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="mergerequestassigneereviewrequestedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
| <a id="mergerequestassigneereviewrequestedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. |
| <a id="mergerequestassigneereviewrequestedmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. |
-| <a id="mergerequestassigneereviewrequestedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | A merge request state. If provided, all resolved merge requests will have this state. |
+| <a id="mergerequestassigneereviewrequestedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. |
| <a id="mergerequestassigneereviewrequestedmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. |
##### `MergeRequestAssignee.snippets`
@@ -10877,7 +11398,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mergerequestassigneesnippetsids"></a>`ids` | [`[SnippetID!]`](#snippetid) | Array of global snippet IDs. For example, `gid://gitlab/ProjectSnippet/1`. |
-| <a id="mergerequestassigneesnippetstype"></a>`type` | [`TypeEnum`](#typeenum) | The type of snippet. |
+| <a id="mergerequestassigneesnippetstype"></a>`type` | [`TypeEnum`](#typeenum) | Type of snippet. |
| <a id="mergerequestassigneesnippetsvisibility"></a>`visibility` | [`VisibilityScopesEnum`](#visibilityscopesenum) | Visibility of the snippet. |
##### `MergeRequestAssignee.starredProjects`
@@ -10932,12 +11453,12 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="mergerequestassigneetodosaction"></a>`action` | [`[TodoActionEnum!]`](#todoactionenum) | The action to be filtered. |
-| <a id="mergerequestassigneetodosauthorid"></a>`authorId` | [`[ID!]`](#id) | The ID of an author. |
-| <a id="mergerequestassigneetodosgroupid"></a>`groupId` | [`[ID!]`](#id) | The ID of a group. |
-| <a id="mergerequestassigneetodosprojectid"></a>`projectId` | [`[ID!]`](#id) | The ID of a project. |
-| <a id="mergerequestassigneetodosstate"></a>`state` | [`[TodoStateEnum!]`](#todostateenum) | The state of the todo. |
-| <a id="mergerequestassigneetodostype"></a>`type` | [`[TodoTargetEnum!]`](#todotargetenum) | The type of the todo. |
+| <a id="mergerequestassigneetodosaction"></a>`action` | [`[TodoActionEnum!]`](#todoactionenum) | Action to be filtered. |
+| <a id="mergerequestassigneetodosauthorid"></a>`authorId` | [`[ID!]`](#id) | ID of an author. |
+| <a id="mergerequestassigneetodosgroupid"></a>`groupId` | [`[ID!]`](#id) | ID of a group. |
+| <a id="mergerequestassigneetodosprojectid"></a>`projectId` | [`[ID!]`](#id) | ID of a project. |
+| <a id="mergerequestassigneetodosstate"></a>`state` | [`[TodoStateEnum!]`](#todostateenum) | State of the todo. |
+| <a id="mergerequestassigneetodostype"></a>`type` | [`[TodoTargetEnum!]`](#todotargetenum) | Type of the todo. |
### `MergeRequestDiffRegistry`
@@ -10989,7 +11510,7 @@ A user assigned to a merge request as a reviewer.
| <a id="mergerequestreviewergroupcount"></a>`groupCount` | [`Int`](#int) | Group count for the user. |
| <a id="mergerequestreviewergroupmemberships"></a>`groupMemberships` | [`GroupMemberConnection`](#groupmemberconnection) | Group memberships of the user. (see [Connections](#connections)) |
| <a id="mergerequestreviewerid"></a>`id` | [`ID!`](#id) | ID of the user. |
-| <a id="mergerequestreviewerlocation"></a>`location` | [`String`](#string) | The location of the user. |
+| <a id="mergerequestreviewerlocation"></a>`location` | [`String`](#string) | Location of the user. |
| <a id="mergerequestreviewermergerequestinteraction"></a>`mergeRequestInteraction` | [`UserMergeRequestInteraction`](#usermergerequestinteraction) | Details of this user's interactions with the merge request. |
| <a id="mergerequestreviewername"></a>`name` | [`String!`](#string) | Human-readable name of the user. |
| <a id="mergerequestreviewernamespace"></a>`namespace` | [`Namespace`](#namespace) | Personal namespace of the user. |
@@ -11030,7 +11551,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="mergerequestreviewerassignedmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
| <a id="mergerequestreviewerassignedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. |
| <a id="mergerequestreviewerassignedmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. |
-| <a id="mergerequestreviewerassignedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | A merge request state. If provided, all resolved merge requests will have this state. |
+| <a id="mergerequestreviewerassignedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. |
| <a id="mergerequestreviewerassignedmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. |
##### `MergeRequestReviewer.authoredMergeRequests`
@@ -11059,9 +11580,26 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="mergerequestreviewerauthoredmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
| <a id="mergerequestreviewerauthoredmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. |
| <a id="mergerequestreviewerauthoredmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. |
-| <a id="mergerequestreviewerauthoredmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | A merge request state. If provided, all resolved merge requests will have this state. |
+| <a id="mergerequestreviewerauthoredmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. |
| <a id="mergerequestreviewerauthoredmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. |
+##### `MergeRequestReviewer.groups`
+
+Groups where the user has access. Will always return `null` if `paginatable_namespace_drop_down_for_project_creation` feature flag is disabled.
+
+Returns [`GroupConnection`](#groupconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestreviewergroupspermissionscope"></a>`permissionScope` | [`GroupPermission`](#grouppermission) | Filter by permissions the user has on groups. |
+| <a id="mergerequestreviewergroupssearch"></a>`search` | [`String`](#string) | Search by group name or path. |
+
##### `MergeRequestReviewer.reviewRequestedMergeRequests`
Merge requests assigned to the user for review.
@@ -11088,7 +11626,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="mergerequestreviewerreviewrequestedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
| <a id="mergerequestreviewerreviewrequestedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. |
| <a id="mergerequestreviewerreviewrequestedmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. |
-| <a id="mergerequestreviewerreviewrequestedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | A merge request state. If provided, all resolved merge requests will have this state. |
+| <a id="mergerequestreviewerreviewrequestedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. |
| <a id="mergerequestreviewerreviewrequestedmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. |
##### `MergeRequestReviewer.snippets`
@@ -11106,7 +11644,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mergerequestreviewersnippetsids"></a>`ids` | [`[SnippetID!]`](#snippetid) | Array of global snippet IDs. For example, `gid://gitlab/ProjectSnippet/1`. |
-| <a id="mergerequestreviewersnippetstype"></a>`type` | [`TypeEnum`](#typeenum) | The type of snippet. |
+| <a id="mergerequestreviewersnippetstype"></a>`type` | [`TypeEnum`](#typeenum) | Type of snippet. |
| <a id="mergerequestreviewersnippetsvisibility"></a>`visibility` | [`VisibilityScopesEnum`](#visibilityscopesenum) | Visibility of the snippet. |
##### `MergeRequestReviewer.starredProjects`
@@ -11161,12 +11699,12 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="mergerequestreviewertodosaction"></a>`action` | [`[TodoActionEnum!]`](#todoactionenum) | The action to be filtered. |
-| <a id="mergerequestreviewertodosauthorid"></a>`authorId` | [`[ID!]`](#id) | The ID of an author. |
-| <a id="mergerequestreviewertodosgroupid"></a>`groupId` | [`[ID!]`](#id) | The ID of a group. |
-| <a id="mergerequestreviewertodosprojectid"></a>`projectId` | [`[ID!]`](#id) | The ID of a project. |
-| <a id="mergerequestreviewertodosstate"></a>`state` | [`[TodoStateEnum!]`](#todostateenum) | The state of the todo. |
-| <a id="mergerequestreviewertodostype"></a>`type` | [`[TodoTargetEnum!]`](#todotargetenum) | The type of the todo. |
+| <a id="mergerequestreviewertodosaction"></a>`action` | [`[TodoActionEnum!]`](#todoactionenum) | Action to be filtered. |
+| <a id="mergerequestreviewertodosauthorid"></a>`authorId` | [`[ID!]`](#id) | ID of an author. |
+| <a id="mergerequestreviewertodosgroupid"></a>`groupId` | [`[ID!]`](#id) | ID of a group. |
+| <a id="mergerequestreviewertodosprojectid"></a>`projectId` | [`[ID!]`](#id) | ID of a project. |
+| <a id="mergerequestreviewertodosstate"></a>`state` | [`[TodoStateEnum!]`](#todostateenum) | State of the todo. |
+| <a id="mergerequestreviewertodostype"></a>`type` | [`[TodoTargetEnum!]`](#todotargetenum) | Type of the todo. |
### `Metadata`
@@ -11285,7 +11823,7 @@ Contains statistics about a milestone.
| <a id="namespaceistemporarystorageincreaseenabled"></a>`isTemporaryStorageIncreaseEnabled` | [`Boolean!`](#boolean) | Status of the temporary storage increase. |
| <a id="namespacelfsenabled"></a>`lfsEnabled` | [`Boolean`](#boolean) | Indicates if Large File Storage (LFS) is enabled for namespace. |
| <a id="namespacename"></a>`name` | [`String!`](#string) | Name of the namespace. |
-| <a id="namespacepackagesettings"></a>`packageSettings` | [`PackageSettings`](#packagesettings) | The package settings for the namespace. |
+| <a id="namespacepackagesettings"></a>`packageSettings` | [`PackageSettings`](#packagesettings) | Package settings for the namespace. |
| <a id="namespacepath"></a>`path` | [`String!`](#string) | Path of the namespace. |
| <a id="namespacerepositorysizeexcessprojectcount"></a>`repositorySizeExcessProjectCount` | [`Int!`](#int) | Number of projects in the root namespace where the repository size exceeds the limit. |
| <a id="namespacerequestaccessenabled"></a>`requestAccessEnabled` | [`Boolean`](#boolean) | Indicates if users can request access to namespace. |
@@ -11364,9 +11902,9 @@ Represents the network policy.
| <a id="notebodyhtml"></a>`bodyHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `note`. |
| <a id="noteconfidential"></a>`confidential` | [`Boolean`](#boolean) | Indicates if this note is confidential. |
| <a id="notecreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp of the note creation. |
-| <a id="notediscussion"></a>`discussion` | [`Discussion`](#discussion) | The discussion this note is a part of. |
+| <a id="notediscussion"></a>`discussion` | [`Discussion`](#discussion) | Discussion this note is a part of. |
| <a id="noteid"></a>`id` | [`NoteID!`](#noteid) | ID of the note. |
-| <a id="noteposition"></a>`position` | [`DiffPosition`](#diffposition) | The position of this note on a diff. |
+| <a id="noteposition"></a>`position` | [`DiffPosition`](#diffposition) | Position of this note on a diff. |
| <a id="noteproject"></a>`project` | [`Project`](#project) | Project associated with the note. |
| <a id="noteresolvable"></a>`resolvable` | [`Boolean!`](#boolean) | Indicates if the object can be resolved. |
| <a id="noteresolved"></a>`resolved` | [`Boolean!`](#boolean) | Indicates if the object is resolved. |
@@ -11423,10 +11961,10 @@ The rotation participant and color palette.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="oncallparticipanttypecolorpalette"></a>`colorPalette` | [`String`](#string) | The color palette to assign to the on-call user. For example "blue". |
-| <a id="oncallparticipanttypecolorweight"></a>`colorWeight` | [`String`](#string) | The color weight to assign to for the on-call user, for example "500". Max 4 chars. For easy identification of the user. |
+| <a id="oncallparticipanttypecolorpalette"></a>`colorPalette` | [`String`](#string) | Color palette to assign to the on-call user. For example "blue". |
+| <a id="oncallparticipanttypecolorweight"></a>`colorWeight` | [`String`](#string) | Color weight to assign to for the on-call user, for example "500". Max 4 chars. For easy identification of the user. |
| <a id="oncallparticipanttypeid"></a>`id` | [`IncidentManagementOncallParticipantID!`](#incidentmanagementoncallparticipantid) | ID of the on-call participant. |
-| <a id="oncallparticipanttypeuser"></a>`user` | [`UserCore!`](#usercore) | The user who is participating. |
+| <a id="oncallparticipanttypeuser"></a>`user` | [`UserCore!`](#usercore) | User who is participating. |
### `OncallRotationActivePeriodType`
@@ -11436,8 +11974,8 @@ Active period time range for on-call rotation.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="oncallrotationactiveperiodtypeendtime"></a>`endTime` | [`String`](#string) | The end of the rotation active period. |
-| <a id="oncallrotationactiveperiodtypestarttime"></a>`startTime` | [`String`](#string) | The start of the rotation active period. |
+| <a id="oncallrotationactiveperiodtypeendtime"></a>`endTime` | [`String`](#string) | End of the rotation active period. |
+| <a id="oncallrotationactiveperiodtypestarttime"></a>`startTime` | [`String`](#string) | Start of the rotation active period. |
### `Package`
@@ -11468,10 +12006,10 @@ Represents a composer JSON file.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="packagecomposerjsontypelicense"></a>`license` | [`String`](#string) | The license set in the Composer JSON file. |
-| <a id="packagecomposerjsontypename"></a>`name` | [`String`](#string) | The name set in the Composer JSON file. |
-| <a id="packagecomposerjsontypetype"></a>`type` | [`String`](#string) | The type set in the Composer JSON file. |
-| <a id="packagecomposerjsontypeversion"></a>`version` | [`String`](#string) | The version set in the Composer JSON file. |
+| <a id="packagecomposerjsontypelicense"></a>`license` | [`String`](#string) | License set in the Composer JSON file. |
+| <a id="packagecomposerjsontypename"></a>`name` | [`String`](#string) | Name set in the Composer JSON file. |
+| <a id="packagecomposerjsontypetype"></a>`type` | [`String`](#string) | Type set in the Composer JSON file. |
+| <a id="packagecomposerjsontypeversion"></a>`version` | [`String`](#string) | Version set in the Composer JSON file. |
### `PackageDependency`
@@ -11519,7 +12057,7 @@ Represents a package details in the Package Registry. Note that this type is in
| <a id="packagedetailstypetags"></a>`tags` | [`PackageTagConnection`](#packagetagconnection) | Package tags. (see [Connections](#connections)) |
| <a id="packagedetailstypeupdatedat"></a>`updatedAt` | [`Time!`](#time) | Date of most recent update. |
| <a id="packagedetailstypeversion"></a>`version` | [`String`](#string) | Version string. |
-| <a id="packagedetailstypeversions"></a>`versions` | [`PackageConnection`](#packageconnection) | The other versions of the package. (see [Connections](#connections)) |
+| <a id="packagedetailstypeversions"></a>`versions` | [`PackageConnection`](#packageconnection) | Other versions of the package. (see [Connections](#connections)) |
### `PackageFile`
@@ -11529,7 +12067,7 @@ Represents a package file.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="packagefilecreatedat"></a>`createdAt` | [`Time!`](#time) | The created date. |
+| <a id="packagefilecreatedat"></a>`createdAt` | [`Time!`](#time) | Created date. |
| <a id="packagefiledownloadpath"></a>`downloadPath` | [`String!`](#string) | Download path of the package file. |
| <a id="packagefilefilemd5"></a>`fileMd5` | [`String`](#string) | Md5 of the package file. |
| <a id="packagefilefilemetadata"></a>`fileMetadata` | [`PackageFileMetadata`](#packagefilemetadata) | File metadata. |
@@ -11538,7 +12076,7 @@ Represents a package file.
| <a id="packagefilefilesha256"></a>`fileSha256` | [`String`](#string) | Sha256 of the package file. |
| <a id="packagefileid"></a>`id` | [`PackagesPackageFileID!`](#packagespackagefileid) | ID of the file. |
| <a id="packagefilesize"></a>`size` | [`String!`](#string) | Size of the package file. |
-| <a id="packagefileupdatedat"></a>`updatedAt` | [`Time!`](#time) | The updated date. |
+| <a id="packagefileupdatedat"></a>`updatedAt` | [`Time!`](#time) | Updated date. |
### `PackageFileRegistry`
@@ -11578,10 +12116,10 @@ Represents a package tag.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="packagetagcreatedat"></a>`createdAt` | [`Time!`](#time) | The created date. |
-| <a id="packagetagid"></a>`id` | [`ID!`](#id) | The ID of the tag. |
-| <a id="packagetagname"></a>`name` | [`String!`](#string) | The name of the tag. |
-| <a id="packagetagupdatedat"></a>`updatedAt` | [`Time!`](#time) | The updated date. |
+| <a id="packagetagcreatedat"></a>`createdAt` | [`Time!`](#time) | Created date. |
+| <a id="packagetagid"></a>`id` | [`ID!`](#id) | ID of the tag. |
+| <a id="packagetagname"></a>`name` | [`String!`](#string) | Name of the tag. |
+| <a id="packagetagupdatedat"></a>`updatedAt` | [`Time!`](#time) | Updated date. |
### `PageInfo`
@@ -11596,6 +12134,23 @@ Information about pagination in a connection.
| <a id="pageinfohaspreviouspage"></a>`hasPreviousPage` | [`Boolean!`](#boolean) | When paginating backwards, are there more items?. |
| <a id="pageinfostartcursor"></a>`startCursor` | [`String`](#string) | When paginating backwards, the cursor to continue. |
+### `PagesDeploymentRegistry`
+
+Represents the Geo replication and verification state of a pages_deployment.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="pagesdeploymentregistrycreatedat"></a>`createdAt` | [`Time`](#time) | Timestamp when the PagesDeploymentRegistry was created. |
+| <a id="pagesdeploymentregistryid"></a>`id` | [`ID!`](#id) | ID of the PagesDeploymentRegistry. |
+| <a id="pagesdeploymentregistrylastsyncfailure"></a>`lastSyncFailure` | [`String`](#string) | Error message during sync of the PagesDeploymentRegistry. |
+| <a id="pagesdeploymentregistrylastsyncedat"></a>`lastSyncedAt` | [`Time`](#time) | Timestamp of the most recent successful sync of the PagesDeploymentRegistry. |
+| <a id="pagesdeploymentregistrypagesdeploymentid"></a>`pagesDeploymentId` | [`ID!`](#id) | ID of the Pages Deployment. |
+| <a id="pagesdeploymentregistryretryat"></a>`retryAt` | [`Time`](#time) | Timestamp after which the PagesDeploymentRegistry should be resynced. |
+| <a id="pagesdeploymentregistryretrycount"></a>`retryCount` | [`Int`](#int) | Number of consecutive failed sync attempts of the PagesDeploymentRegistry. |
+| <a id="pagesdeploymentregistrystate"></a>`state` | [`RegistryState`](#registrystate) | Sync state of the PagesDeploymentRegistry. |
+
### `PathLock`
Represents a file or directory in the project repository that has been locked.
@@ -11605,8 +12160,8 @@ Represents a file or directory in the project repository that has been locked.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="pathlockid"></a>`id` | [`PathLockID!`](#pathlockid) | ID of the path lock. |
-| <a id="pathlockpath"></a>`path` | [`String`](#string) | The locked path. |
-| <a id="pathlockuser"></a>`user` | [`UserCore`](#usercore) | The user that has locked this path. |
+| <a id="pathlockpath"></a>`path` | [`String`](#string) | Locked path. |
+| <a id="pathlockuser"></a>`user` | [`UserCore`](#usercore) | User that has locked this path. |
### `Pipeline`
@@ -11653,7 +12208,7 @@ Represents a file or directory in the project repository that has been locked.
##### `Pipeline.job`
-A specific job in this pipeline, either by name or ID.
+Specific job in this pipeline, either by name or ID.
Returns [`CiJob`](#cijob).
@@ -11767,17 +12322,17 @@ Represents vulnerability finding of a security report on the pipeline.
| ---- | ---- | ----------- |
| <a id="pipelinesecurityreportfindingconfidence"></a>`confidence` | [`String`](#string) | Type of the security report that found the vulnerability. |
| <a id="pipelinesecurityreportfindingdescription"></a>`description` | [`String`](#string) | Description of the vulnerability finding. |
-| <a id="pipelinesecurityreportfindingfalsepositive"></a>`falsePositive` | [`Boolean`](#boolean) | Indicates whether the vulnerability is a false positive. Available only when feature flag `vulnerability_flags` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice. |
+| <a id="pipelinesecurityreportfindingfalsepositive"></a>`falsePositive` | [`Boolean`](#boolean) | Indicates whether the vulnerability is a false positive. |
| <a id="pipelinesecurityreportfindingidentifiers"></a>`identifiers` | [`[VulnerabilityIdentifier!]!`](#vulnerabilityidentifier) | Identifiers of the vulnerabilit finding. |
| <a id="pipelinesecurityreportfindinglocation"></a>`location` | [`VulnerabilityLocation`](#vulnerabilitylocation) | Location metadata for the vulnerability. Its fields depend on the type of security scan that found the vulnerability. |
| <a id="pipelinesecurityreportfindingname"></a>`name` | [`String`](#string) | Name of the vulnerability finding. |
-| <a id="pipelinesecurityreportfindingproject"></a>`project` | [`Project`](#project) | The project on which the vulnerability finding was found. |
+| <a id="pipelinesecurityreportfindingproject"></a>`project` | [`Project`](#project) | Project on which the vulnerability finding was found. |
| <a id="pipelinesecurityreportfindingprojectfingerprint"></a>`projectFingerprint` | [`String`](#string) | Name of the vulnerability finding. |
| <a id="pipelinesecurityreportfindingreporttype"></a>`reportType` | [`VulnerabilityReportType`](#vulnerabilityreporttype) | Type of the security report that found the vulnerability finding. |
| <a id="pipelinesecurityreportfindingscanner"></a>`scanner` | [`VulnerabilityScanner`](#vulnerabilityscanner) | Scanner metadata for the vulnerability. |
| <a id="pipelinesecurityreportfindingseverity"></a>`severity` | [`VulnerabilitySeverity`](#vulnerabilityseverity) | Severity of the vulnerability finding. |
| <a id="pipelinesecurityreportfindingsolution"></a>`solution` | [`String`](#string) | URL to the vulnerability's details page. |
-| <a id="pipelinesecurityreportfindingstate"></a>`state` | [`VulnerabilityState`](#vulnerabilitystate) | The finding status. |
+| <a id="pipelinesecurityreportfindingstate"></a>`state` | [`VulnerabilityState`](#vulnerabilitystate) | Finding status. |
| <a id="pipelinesecurityreportfindinguuid"></a>`uuid` | [`String`](#string) | Name of the vulnerability finding. |
### `Project`
@@ -11798,16 +12353,16 @@ Represents vulnerability finding of a security report on the pipeline.
| <a id="projectclusteragents"></a>`clusterAgents` | [`ClusterAgentConnection`](#clusteragentconnection) | Cluster agents associated with the project. (see [Connections](#connections)) |
| <a id="projectcodecoveragesummary"></a>`codeCoverageSummary` | [`CodeCoverageSummary`](#codecoveragesummary) | Code coverage summary associated with the project. |
| <a id="projectcomplianceframeworks"></a>`complianceFrameworks` | [`ComplianceFrameworkConnection`](#complianceframeworkconnection) | Compliance frameworks associated with the project. (see [Connections](#connections)) |
-| <a id="projectcontainerexpirationpolicy"></a>`containerExpirationPolicy` | [`ContainerExpirationPolicy`](#containerexpirationpolicy) | The container expiration policy of the project. |
+| <a id="projectcontainerexpirationpolicy"></a>`containerExpirationPolicy` | [`ContainerExpirationPolicy`](#containerexpirationpolicy) | Container expiration policy of the project. |
| <a id="projectcontainerregistryenabled"></a>`containerRegistryEnabled` | [`Boolean`](#boolean) | Indicates if Container Registry is enabled for the current user. |
| <a id="projectcontainerrepositoriescount"></a>`containerRepositoriesCount` | [`Int!`](#int) | Number of container repositories in the project. |
| <a id="projectcreatedat"></a>`createdAt` | [`Time`](#time) | Timestamp of the project creation. |
| <a id="projectdastprofiles"></a>`dastProfiles` | [`DastProfileConnection`](#dastprofileconnection) | DAST Profiles associated with the project. (see [Connections](#connections)) |
-| <a id="projectdastscannerprofiles"></a>`dastScannerProfiles` | [`DastScannerProfileConnection`](#dastscannerprofileconnection) | The DAST scanner profiles associated with the project. (see [Connections](#connections)) |
+| <a id="projectdastscannerprofiles"></a>`dastScannerProfiles` | [`DastScannerProfileConnection`](#dastscannerprofileconnection) | DAST scanner profiles associated with the project. (see [Connections](#connections)) |
| <a id="projectdastsiteprofiles"></a>`dastSiteProfiles` | [`DastSiteProfileConnection`](#dastsiteprofileconnection) | DAST Site Profiles associated with the project. (see [Connections](#connections)) |
| <a id="projectdescription"></a>`description` | [`String`](#string) | Short description of the project. |
| <a id="projectdescriptionhtml"></a>`descriptionHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `description`. |
-| <a id="projectdora"></a>`dora` | [`Dora`](#dora) | The project's DORA metrics. |
+| <a id="projectdora"></a>`dora` | [`Dora`](#dora) | Project's DORA metrics. |
| <a id="projectforkscount"></a>`forksCount` | [`Int!`](#int) | Number of times the project has been forked. |
| <a id="projectfullpath"></a>`fullPath` | [`ID!`](#id) | Full path of the project. |
| <a id="projectgrafanaintegration"></a>`grafanaIntegration` | [`GrafanaIntegration`](#grafanaintegration) | Grafana integration details for the project. |
@@ -11835,7 +12390,7 @@ Represents vulnerability finding of a security report on the pipeline.
| <a id="projectpipelineanalytics"></a>`pipelineAnalytics` | [`PipelineAnalytics`](#pipelineanalytics) | Pipeline analytics. |
| <a id="projectprintingmergerequestlinkenabled"></a>`printingMergeRequestLinkEnabled` | [`Boolean`](#boolean) | Indicates if a link to create or view a merge request should display after a push to Git repositories of the project from the command line. |
| <a id="projectpublicjobs"></a>`publicJobs` | [`Boolean`](#boolean) | Indicates if there is public access to pipelines and job details of the project, including output logs and artifacts. |
-| <a id="projectpushrules"></a>`pushRules` | [`PushRules`](#pushrules) | The project's push rules settings. |
+| <a id="projectpushrules"></a>`pushRules` | [`PushRules`](#pushrules) | Project's push rules settings. |
| <a id="projectremovesourcebranchaftermerge"></a>`removeSourceBranchAfterMerge` | [`Boolean`](#boolean) | Indicates if `Delete source branch` option should be enabled by default for all new merge requests of the project. |
| <a id="projectrepository"></a>`repository` | [`Repository`](#repository) | Git repository of the project. |
| <a id="projectrepositorysizeexcess"></a>`repositorySizeExcess` | [`Float`](#float) | Size of repository that exceeds the limit in bytes. |
@@ -11854,7 +12409,7 @@ Represents vulnerability finding of a security report on the pipeline.
| <a id="projectsshurltorepo"></a>`sshUrlToRepo` | [`String`](#string) | URL to connect to the project via SSH. |
| <a id="projectstarcount"></a>`starCount` | [`Int!`](#int) | Number of times the project has been starred. |
| <a id="projectstatistics"></a>`statistics` | [`ProjectStatistics`](#projectstatistics) | Statistics of the project. |
-| <a id="projectsuggestioncommitmessage"></a>`suggestionCommitMessage` | [`String`](#string) | The commit message used to apply merge request suggestions. |
+| <a id="projectsuggestioncommitmessage"></a>`suggestionCommitMessage` | [`String`](#string) | Commit message used to apply merge request suggestions. |
| <a id="projecttaglist"></a>`tagList` **{warning-solid}** | [`String`](#string) | **Deprecated** in 13.12. Use `topics`. |
| <a id="projectterraformstates"></a>`terraformStates` | [`TerraformStateConnection`](#terraformstateconnection) | Terraform states associated with the project. (see [Connections](#connections)) |
| <a id="projecttopics"></a>`topics` | [`[String!]`](#string) | List of project topics. |
@@ -12069,6 +12624,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="projectdastsitevalidationsnormalizedtargeturls"></a>`normalizedTargetUrls` | [`[String!]`](#string) | Normalized URL of the target to be scanned. |
+| <a id="projectdastsitevalidationsstatus"></a>`status` | [`DastSiteValidationStatusEnum`](#dastsitevalidationstatusenum) | Status of the site validation. Ignored if `dast_failed_site_validations` feature flag is disabled. |
##### `Project.environment`
@@ -12140,7 +12696,7 @@ Returns [`Issue`](#issue).
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="projectissueassigneeid"></a>`assigneeId` | [`String`](#string) | ID of a user assigned to the issues, "none" and "any" values are supported. |
+| <a id="projectissueassigneeid"></a>`assigneeId` | [`String`](#string) | ID of a user assigned to the issues. Wildcard values "NONE" and "ANY" are supported. |
| <a id="projectissueassigneeusername"></a>`assigneeUsername` **{warning-solid}** | [`String`](#string) | **Deprecated** in 13.11. Use `assigneeUsernames`. |
| <a id="projectissueassigneeusernames"></a>`assigneeUsernames` | [`[String!]`](#string) | Usernames of users assigned to the issue. |
| <a id="projectissueauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author of the issue. |
@@ -12156,6 +12712,7 @@ Returns [`Issue`](#issue).
| <a id="projectissuelabelname"></a>`labelName` | [`[String]`](#string) | Labels applied to this issue. |
| <a id="projectissuemilestonetitle"></a>`milestoneTitle` | [`[String]`](#string) | Milestone applied to this issue. |
| <a id="projectissuemilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. |
+| <a id="projectissuemyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. Wildcard values "NONE" and "ANY" are supported. |
| <a id="projectissuenot"></a>`not` | [`NegatedIssueFilterInput`](#negatedissuefilterinput) | Negated arguments. |
| <a id="projectissuesearch"></a>`search` | [`String`](#string) | Search query for issue title or description. |
| <a id="projectissuesort"></a>`sort` | [`IssueSort`](#issuesort) | Sort issues by this criteria. |
@@ -12175,7 +12732,7 @@ Returns [`IssueStatusCountsType`](#issuestatuscountstype).
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="projectissuestatuscountsassigneeid"></a>`assigneeId` | [`String`](#string) | ID of a user assigned to the issues, "none" and "any" values are supported. |
+| <a id="projectissuestatuscountsassigneeid"></a>`assigneeId` | [`String`](#string) | ID of a user assigned to the issues. Wildcard values "NONE" and "ANY" are supported. |
| <a id="projectissuestatuscountsassigneeusername"></a>`assigneeUsername` **{warning-solid}** | [`String`](#string) | **Deprecated** in 13.11. Use `assigneeUsernames`. |
| <a id="projectissuestatuscountsassigneeusernames"></a>`assigneeUsernames` | [`[String!]`](#string) | Usernames of users assigned to the issue. |
| <a id="projectissuestatuscountsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author of the issue. |
@@ -12188,6 +12745,7 @@ Returns [`IssueStatusCountsType`](#issuestatuscountstype).
| <a id="projectissuestatuscountslabelname"></a>`labelName` | [`[String]`](#string) | Labels applied to this issue. |
| <a id="projectissuestatuscountsmilestonetitle"></a>`milestoneTitle` | [`[String]`](#string) | Milestone applied to this issue. |
| <a id="projectissuestatuscountsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. |
+| <a id="projectissuestatuscountsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. Wildcard values "NONE" and "ANY" are supported. |
| <a id="projectissuestatuscountsnot"></a>`not` | [`NegatedIssueFilterInput`](#negatedissuefilterinput) | Negated arguments. |
| <a id="projectissuestatuscountssearch"></a>`search` | [`String`](#string) | Search query for issue title or description. |
| <a id="projectissuestatuscountstypes"></a>`types` | [`[IssueType!]`](#issuetype) | Filter issues by the given issue types. |
@@ -12208,7 +12766,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="projectissuesassigneeid"></a>`assigneeId` | [`String`](#string) | ID of a user assigned to the issues, "none" and "any" values are supported. |
+| <a id="projectissuesassigneeid"></a>`assigneeId` | [`String`](#string) | ID of a user assigned to the issues. Wildcard values "NONE" and "ANY" are supported. |
| <a id="projectissuesassigneeusername"></a>`assigneeUsername` **{warning-solid}** | [`String`](#string) | **Deprecated** in 13.11. Use `assigneeUsernames`. |
| <a id="projectissuesassigneeusernames"></a>`assigneeUsernames` | [`[String!]`](#string) | Usernames of users assigned to the issue. |
| <a id="projectissuesauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author of the issue. |
@@ -12224,6 +12782,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="projectissueslabelname"></a>`labelName` | [`[String]`](#string) | Labels applied to this issue. |
| <a id="projectissuesmilestonetitle"></a>`milestoneTitle` | [`[String]`](#string) | Milestone applied to this issue. |
| <a id="projectissuesmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. |
+| <a id="projectissuesmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. Wildcard values "NONE" and "ANY" are supported. |
| <a id="projectissuesnot"></a>`not` | [`NegatedIssueFilterInput`](#negatedissuefilterinput) | Negated arguments. |
| <a id="projectissuessearch"></a>`search` | [`String`](#string) | Search query for issue title or description. |
| <a id="projectissuessort"></a>`sort` | [`IssueSort`](#issuesort) | Sort issues by this criteria. |
@@ -12296,7 +12855,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
##### `Project.label`
-A label available on this project.
+Label available on this project.
Returns [`Label`](#label).
@@ -12321,7 +12880,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="projectlabelsincludeancestorgroups"></a>`includeAncestorGroups` | [`Boolean`](#boolean) | Include labels from ancestor groups. |
-| <a id="projectlabelssearchterm"></a>`searchTerm` | [`String`](#string) | A search term to find labels with. |
+| <a id="projectlabelssearchterm"></a>`searchTerm` | [`String`](#string) | Search term to find labels with. |
##### `Project.mergeRequest`
@@ -12360,7 +12919,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="projectmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
| <a id="projectmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. |
| <a id="projectmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. |
-| <a id="projectmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | A merge request state. If provided, all resolved merge requests will have this state. |
+| <a id="projectmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. |
| <a id="projectmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. |
##### `Project.milestones`
@@ -12377,16 +12936,16 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="projectmilestonescontainingdate"></a>`containingDate` | [`Time`](#time) | A date that the milestone contains. |
+| <a id="projectmilestonescontainingdate"></a>`containingDate` | [`Time`](#time) | Date the milestone contains. |
| <a id="projectmilestonesenddate"></a>`endDate` **{warning-solid}** | [`Time`](#time) | **Deprecated** in 13.5. Use timeframe.end. |
| <a id="projectmilestonesids"></a>`ids` | [`[ID!]`](#id) | Array of global milestone IDs, e.g., `"gid://gitlab/Milestone/1"`. |
| <a id="projectmilestonesincludeancestors"></a>`includeAncestors` | [`Boolean`](#boolean) | Also return milestones in the project's parent group and its ancestors. |
-| <a id="projectmilestonessearchtitle"></a>`searchTitle` | [`String`](#string) | A search string for the title. |
+| <a id="projectmilestonessearchtitle"></a>`searchTitle` | [`String`](#string) | Search string for the title. |
| <a id="projectmilestonessort"></a>`sort` | [`MilestoneSort`](#milestonesort) | Sort milestones by this criteria. |
| <a id="projectmilestonesstartdate"></a>`startDate` **{warning-solid}** | [`Time`](#time) | **Deprecated** in 13.5. Use timeframe.start. |
| <a id="projectmilestonesstate"></a>`state` | [`MilestoneStateEnum`](#milestonestateenum) | Filter milestones by state. |
| <a id="projectmilestonestimeframe"></a>`timeframe` | [`Timeframe`](#timeframe) | List items overlapping the given timeframe. |
-| <a id="projectmilestonestitle"></a>`title` | [`String`](#string) | The title of the milestone. |
+| <a id="projectmilestonestitle"></a>`title` | [`String`](#string) | Title of the milestone. |
##### `Project.networkPolicies`
@@ -12402,7 +12961,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="projectnetworkpoliciesenvironmentid"></a>`environmentId` | [`EnvironmentID`](#environmentid) | The global ID of the environment to filter policies. |
+| <a id="projectnetworkpoliciesenvironmentid"></a>`environmentId` | [`EnvironmentID`](#environmentid) | Global ID of the environment to filter policies. |
##### `Project.packages`
@@ -12453,6 +13012,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| ---- | ---- | ----------- |
| <a id="projectpipelinesref"></a>`ref` | [`String`](#string) | Filter pipelines by the ref they are run for. |
| <a id="projectpipelinessha"></a>`sha` | [`String`](#string) | Filter pipelines by the sha of the commit they are run for. |
+| <a id="projectpipelinessource"></a>`source` | [`String`](#string) | Filter pipelines by their source. Will be ignored if `dast_view_scans` feature flag is disabled. |
| <a id="projectpipelinesstatus"></a>`status` | [`PipelineStatusEnum`](#pipelinestatusenum) | Filter pipelines by their status. |
##### `Project.projectMembers`
@@ -12482,7 +13042,7 @@ Returns [`Release`](#release).
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="projectreleasetagname"></a>`tagName` | [`String!`](#string) | The name of the tag associated to the release. |
+| <a id="projectreleasetagname"></a>`tagName` | [`String!`](#string) | Name of the tag associated to the release. |
##### `Project.releases`
@@ -12513,7 +13073,7 @@ Returns [`Requirement`](#requirement).
| <a id="projectrequirementauthorusername"></a>`authorUsername` | [`[String!]`](#string) | Filter requirements by author username. |
| <a id="projectrequirementiid"></a>`iid` | [`ID`](#id) | IID of the requirement, e.g., "1". |
| <a id="projectrequirementiids"></a>`iids` | [`[ID!]`](#id) | List of IIDs of requirements, e.g., `[1, 2]`. |
-| <a id="projectrequirementlasttestreportstate"></a>`lastTestReportState` | [`RequirementStatusFilter`](#requirementstatusfilter) | The state of latest requirement test report. |
+| <a id="projectrequirementlasttestreportstate"></a>`lastTestReportState` | [`RequirementStatusFilter`](#requirementstatusfilter) | State of latest requirement test report. |
| <a id="projectrequirementsearch"></a>`search` | [`String`](#string) | Search query for requirement title. |
| <a id="projectrequirementsort"></a>`sort` | [`Sort`](#sort) | List requirements by sort order. |
| <a id="projectrequirementstate"></a>`state` | [`RequirementState`](#requirementstate) | Filter requirements by state. |
@@ -12535,7 +13095,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="projectrequirementsauthorusername"></a>`authorUsername` | [`[String!]`](#string) | Filter requirements by author username. |
| <a id="projectrequirementsiid"></a>`iid` | [`ID`](#id) | IID of the requirement, e.g., "1". |
| <a id="projectrequirementsiids"></a>`iids` | [`[ID!]`](#id) | List of IIDs of requirements, e.g., `[1, 2]`. |
-| <a id="projectrequirementslasttestreportstate"></a>`lastTestReportState` | [`RequirementStatusFilter`](#requirementstatusfilter) | The state of latest requirement test report. |
+| <a id="projectrequirementslasttestreportstate"></a>`lastTestReportState` | [`RequirementStatusFilter`](#requirementstatusfilter) | State of latest requirement test report. |
| <a id="projectrequirementssearch"></a>`search` | [`String`](#string) | Search query for requirement title. |
| <a id="projectrequirementssort"></a>`sort` | [`Sort`](#sort) | List requirements by sort order. |
| <a id="projectrequirementsstate"></a>`state` | [`RequirementState`](#requirementstate) | Filter requirements by state. |
@@ -12770,6 +13330,7 @@ Represents a Project Membership.
| <a id="projectstatisticscommitcount"></a>`commitCount` | [`Float!`](#float) | Commit count of the project. |
| <a id="projectstatisticslfsobjectssize"></a>`lfsObjectsSize` | [`Float!`](#float) | Large File Storage (LFS) object size of the project in bytes. |
| <a id="projectstatisticspackagessize"></a>`packagesSize` | [`Float!`](#float) | Packages size of the project in bytes. |
+| <a id="projectstatisticspipelineartifactssize"></a>`pipelineArtifactsSize` | [`Float`](#float) | CI Pipeline artifacts size in bytes. |
| <a id="projectstatisticsrepositorysize"></a>`repositorySize` | [`Float!`](#float) | Repository size of the project in bytes. |
| <a id="projectstatisticssnippetssize"></a>`snippetsSize` | [`Float`](#float) | Snippets size of the project in bytes. |
| <a id="projectstatisticsstoragesize"></a>`storageSize` | [`Float!`](#float) | Storage size of the project in bytes. |
@@ -12784,7 +13345,7 @@ The alert condition for Prometheus.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="prometheusalerthumanizedtext"></a>`humanizedText` | [`String!`](#string) | The human-readable text of the alert condition. |
+| <a id="prometheusalerthumanizedtext"></a>`humanizedText` | [`String!`](#string) | Human-readable text of the alert condition. |
| <a id="prometheusalertid"></a>`id` | [`ID!`](#id) | ID of the alert condition. |
### `PushRules`
@@ -12838,7 +13399,7 @@ Represents a release.
| ---- | ---- | ----------- |
| <a id="releaseassets"></a>`assets` | [`ReleaseAssets`](#releaseassets) | Assets of the release. |
| <a id="releaseauthor"></a>`author` | [`UserCore`](#usercore) | User that created the release. |
-| <a id="releasecommit"></a>`commit` | [`Commit`](#commit) | The commit associated with the release. |
+| <a id="releasecommit"></a>`commit` | [`Commit`](#commit) | Commit associated with the release. |
| <a id="releasecreatedat"></a>`createdAt` | [`Time`](#time) | Timestamp of when the release was created. |
| <a id="releasedescription"></a>`description` | [`String`](#string) | Description (also known as "release notes") of the release. |
| <a id="releasedescriptionhtml"></a>`descriptionHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `description`. |
@@ -12957,9 +13518,9 @@ Returns [`[String!]`](#string).
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="repositorybranchnameslimit"></a>`limit` | [`Int!`](#int) | The number of branch names to return. |
-| <a id="repositorybranchnamesoffset"></a>`offset` | [`Int!`](#int) | The number of branch names to skip. |
-| <a id="repositorybranchnamessearchpattern"></a>`searchPattern` | [`String!`](#string) | The pattern to search for branch names by. |
+| <a id="repositorybranchnameslimit"></a>`limit` | [`Int!`](#int) | Number of branch names to return. |
+| <a id="repositorybranchnamesoffset"></a>`offset` | [`Int!`](#int) | Number of branch names to skip. |
+| <a id="repositorybranchnamessearchpattern"></a>`searchPattern` | [`String!`](#string) | Pattern to search for branch names by. |
##### `Repository.paginatedTree`
@@ -12975,9 +13536,9 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="repositorypaginatedtreepath"></a>`path` | [`String`](#string) | The path to get the tree for. Default value is the root of the repository. |
+| <a id="repositorypaginatedtreepath"></a>`path` | [`String`](#string) | Path to get the tree for. Default value is the root of the repository. |
| <a id="repositorypaginatedtreerecursive"></a>`recursive` | [`Boolean`](#boolean) | Used to get a recursive tree. Default is false. |
-| <a id="repositorypaginatedtreeref"></a>`ref` | [`String`](#string) | The commit ref to get the tree for. Default value is HEAD. |
+| <a id="repositorypaginatedtreeref"></a>`ref` | [`String`](#string) | Commit ref to get the tree for. Default value is HEAD. |
##### `Repository.tree`
@@ -12989,9 +13550,9 @@ Returns [`Tree`](#tree).
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="repositorytreepath"></a>`path` | [`String`](#string) | The path to get the tree for. Default value is the root of the repository. |
+| <a id="repositorytreepath"></a>`path` | [`String`](#string) | Path to get the tree for. Default value is the root of the repository. |
| <a id="repositorytreerecursive"></a>`recursive` | [`Boolean`](#boolean) | Used to get a recursive tree. Default is false. |
-| <a id="repositorytreeref"></a>`ref` | [`String`](#string) | The commit ref to get the tree for. Default value is HEAD. |
+| <a id="repositorytreeref"></a>`ref` | [`String`](#string) | Commit ref to get the tree for. Default value is HEAD. |
### `RepositoryBlob`
@@ -13002,7 +13563,7 @@ Returns [`Tree`](#tree).
| <a id="repositoryblobcanmodifyblob"></a>`canModifyBlob` | [`Boolean`](#boolean) | Whether the current user can modify the blob. |
| <a id="repositoryblobeditblobpath"></a>`editBlobPath` | [`String`](#string) | Web path to edit the blob in the old-style editor. |
| <a id="repositoryblobexternalstorageurl"></a>`externalStorageUrl` | [`String`](#string) | Web path to download the raw blob via external storage, if enabled. |
-| <a id="repositoryblobfiletype"></a>`fileType` | [`String`](#string) | The expected format of the blob based on the extension. |
+| <a id="repositoryblobfiletype"></a>`fileType` | [`String`](#string) | Expected format of the blob based on the extension. |
| <a id="repositoryblobforkandeditpath"></a>`forkAndEditPath` | [`String`](#string) | Web path to edit this blob using a forked project. |
| <a id="repositoryblobid"></a>`id` | [`ID!`](#id) | ID of the blob. |
| <a id="repositoryblobideeditpath"></a>`ideEditPath` | [`String`](#string) | Web path to edit this blob in the Web IDE. |
@@ -13013,10 +13574,10 @@ Returns [`Tree`](#tree).
| <a id="repositorybloboid"></a>`oid` | [`String!`](#string) | OID of the blob. |
| <a id="repositoryblobpath"></a>`path` | [`String!`](#string) | Path of the blob. |
| <a id="repositoryblobplaindata"></a>`plainData` | [`String`](#string) | Blob plain highlighted data. |
-| <a id="repositoryblobrawblob"></a>`rawBlob` | [`String`](#string) | The raw content of the blob. |
+| <a id="repositoryblobrawblob"></a>`rawBlob` | [`String`](#string) | Raw content of the blob. |
| <a id="repositoryblobrawpath"></a>`rawPath` | [`String`](#string) | Web path to download the raw blob. |
| <a id="repositoryblobrawsize"></a>`rawSize` | [`Int`](#int) | Size (in bytes) of the blob, or the blob target if stored externally. |
-| <a id="repositoryblobrawtextblob"></a>`rawTextBlob` | [`String`](#string) | The raw content of the blob, if the blob is text data. |
+| <a id="repositoryblobrawtextblob"></a>`rawTextBlob` | [`String`](#string) | Raw content of the blob, if the blob is text data. |
| <a id="repositoryblobreplacepath"></a>`replacePath` | [`String`](#string) | Web path to replace the blob content. |
| <a id="repositoryblobrichviewer"></a>`richViewer` | [`BlobViewer`](#blobviewer) | Blob content rich viewer. |
| <a id="repositoryblobsimpleviewer"></a>`simpleViewer` | [`BlobViewer!`](#blobviewer) | Blob content simple viewer. |
@@ -13096,15 +13657,15 @@ Counts of requirements by their state.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="rootstoragestatisticsbuildartifactssize"></a>`buildArtifactsSize` | [`Float!`](#float) | The CI artifacts size in bytes. |
-| <a id="rootstoragestatisticslfsobjectssize"></a>`lfsObjectsSize` | [`Float!`](#float) | The LFS objects size in bytes. |
-| <a id="rootstoragestatisticspackagessize"></a>`packagesSize` | [`Float!`](#float) | The packages size in bytes. |
-| <a id="rootstoragestatisticspipelineartifactssize"></a>`pipelineArtifactsSize` | [`Float!`](#float) | The CI pipeline artifacts size in bytes. |
-| <a id="rootstoragestatisticsrepositorysize"></a>`repositorySize` | [`Float!`](#float) | The Git repository size in bytes. |
-| <a id="rootstoragestatisticssnippetssize"></a>`snippetsSize` | [`Float!`](#float) | The snippets size in bytes. |
-| <a id="rootstoragestatisticsstoragesize"></a>`storageSize` | [`Float!`](#float) | The total storage in bytes. |
-| <a id="rootstoragestatisticsuploadssize"></a>`uploadsSize` | [`Float!`](#float) | The uploads size in bytes. |
-| <a id="rootstoragestatisticswikisize"></a>`wikiSize` | [`Float!`](#float) | The wiki size in bytes. |
+| <a id="rootstoragestatisticsbuildartifactssize"></a>`buildArtifactsSize` | [`Float!`](#float) | CI artifacts size in bytes. |
+| <a id="rootstoragestatisticslfsobjectssize"></a>`lfsObjectsSize` | [`Float!`](#float) | LFS objects size in bytes. |
+| <a id="rootstoragestatisticspackagessize"></a>`packagesSize` | [`Float!`](#float) | Packages size in bytes. |
+| <a id="rootstoragestatisticspipelineartifactssize"></a>`pipelineArtifactsSize` | [`Float!`](#float) | CI pipeline artifacts size in bytes. |
+| <a id="rootstoragestatisticsrepositorysize"></a>`repositorySize` | [`Float!`](#float) | Git repository size in bytes. |
+| <a id="rootstoragestatisticssnippetssize"></a>`snippetsSize` | [`Float!`](#float) | Snippets size in bytes. |
+| <a id="rootstoragestatisticsstoragesize"></a>`storageSize` | [`Float!`](#float) | Total storage in bytes. |
+| <a id="rootstoragestatisticsuploadssize"></a>`uploadsSize` | [`Float!`](#float) | Uploads size in bytes. |
+| <a id="rootstoragestatisticswikisize"></a>`wikiSize` | [`Float!`](#float) | Wiki size in bytes. |
### `RunnerArchitecture`
@@ -13221,8 +13782,8 @@ Represents a resource scanned by a security scan.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="scannedresourcerequestmethod"></a>`requestMethod` | [`String`](#string) | The HTTP request method used to access the URL. |
-| <a id="scannedresourceurl"></a>`url` | [`String`](#string) | The URL scanned by the scanner. |
+| <a id="scannedresourcerequestmethod"></a>`requestMethod` | [`String`](#string) | HTTP request method used to access the URL. |
+| <a id="scannedresourceurl"></a>`url` | [`String`](#string) | URL scanned by the scanner. |
### `SecurityReportSummary`
@@ -13238,6 +13799,7 @@ Represents summary of a security report.
| <a id="securityreportsummarycoveragefuzzing"></a>`coverageFuzzing` | [`SecurityReportSummarySection`](#securityreportsummarysection) | Aggregated counts for the `coverage_fuzzing` scan. |
| <a id="securityreportsummarydast"></a>`dast` | [`SecurityReportSummarySection`](#securityreportsummarysection) | Aggregated counts for the `dast` scan. |
| <a id="securityreportsummarydependencyscanning"></a>`dependencyScanning` | [`SecurityReportSummarySection`](#securityreportsummarysection) | Aggregated counts for the `dependency_scanning` scan. |
+| <a id="securityreportsummarygeneric"></a>`generic` | [`SecurityReportSummarySection`](#securityreportsummarysection) | Aggregated counts for the `generic` scan. |
| <a id="securityreportsummarysast"></a>`sast` | [`SecurityReportSummarySection`](#securityreportsummarysection) | Aggregated counts for the `sast` scan. |
| <a id="securityreportsummarysecretdetection"></a>`secretDetection` | [`SecurityReportSummarySection`](#securityreportsummarysection) | Aggregated counts for the `secret_detection` scan. |
@@ -13249,7 +13811,7 @@ Represents a section of a summary of a security report.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="securityreportsummarysectionscannedresources"></a>`scannedResources` | [`ScannedResourceConnection`](#scannedresourceconnection) | A list of the first 20 scanned resources. (see [Connections](#connections)) |
+| <a id="securityreportsummarysectionscannedresources"></a>`scannedResources` | [`ScannedResourceConnection`](#scannedresourceconnection) | List of the first 20 scanned resources. (see [Connections](#connections)) |
| <a id="securityreportsummarysectionscannedresourcescount"></a>`scannedResourcesCount` | [`Int`](#int) | Total number of scanned resources. |
| <a id="securityreportsummarysectionscannedresourcescsvpath"></a>`scannedResourcesCsvPath` | [`String`](#string) | Path to download all the scanned resources in CSV format. |
| <a id="securityreportsummarysectionscans"></a>`scans` | [`ScanConnection!`](#scanconnection) | List of security scans ran for the type. (see [Connections](#connections)) |
@@ -13448,7 +14010,7 @@ Represents a snippet entry.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="snippetauthor"></a>`author` | [`UserCore`](#usercore) | The owner of the snippet. |
+| <a id="snippetauthor"></a>`author` | [`UserCore`](#usercore) | Owner of the snippet. |
| <a id="snippetcreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp this snippet was created. |
| <a id="snippetdescription"></a>`description` | [`String`](#string) | Description of the snippet. |
| <a id="snippetdescriptionhtml"></a>`descriptionHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `description`. |
@@ -13457,7 +14019,7 @@ Represents a snippet entry.
| <a id="snippethttpurltorepo"></a>`httpUrlToRepo` | [`String`](#string) | HTTP URL to the snippet repository. |
| <a id="snippetid"></a>`id` | [`SnippetID!`](#snippetid) | ID of the snippet. |
| <a id="snippetnotes"></a>`notes` | [`NoteConnection!`](#noteconnection) | All notes on this noteable. (see [Connections](#connections)) |
-| <a id="snippetproject"></a>`project` | [`Project`](#project) | The project the snippet is associated with. |
+| <a id="snippetproject"></a>`project` | [`Project`](#project) | Project the snippet is associated with. |
| <a id="snippetrawurl"></a>`rawUrl` | [`String!`](#string) | Raw URL of the snippet. |
| <a id="snippetsshurltorepo"></a>`sshUrlToRepo` | [`String`](#string) | SSH URL to the snippet repository. |
| <a id="snippettitle"></a>`title` | [`String!`](#string) | Title of the snippet. |
@@ -13499,7 +14061,7 @@ Represents the snippet blob.
| <a id="snippetblobpath"></a>`path` | [`String`](#string) | Blob path. |
| <a id="snippetblobplaindata"></a>`plainData` | [`String`](#string) | Blob plain highlighted data. |
| <a id="snippetblobrawpath"></a>`rawPath` | [`String!`](#string) | Blob raw content endpoint path. |
-| <a id="snippetblobrawplaindata"></a>`rawPlainData` | [`String`](#string) | The raw content of the blob, if the blob is text data. |
+| <a id="snippetblobrawplaindata"></a>`rawPlainData` | [`String`](#string) | Raw content of the blob, if the blob is text data. |
| <a id="snippetblobrenderedastext"></a>`renderedAsText` | [`Boolean!`](#boolean) | Shows whether the blob is rendered as text. |
| <a id="snippetblobrichdata"></a>`richData` | [`String`](#string) | Blob highlighted data. |
| <a id="snippetblobrichviewer"></a>`richViewer` | [`SnippetBlobViewer`](#snippetblobviewer) | Blob content rich viewer. |
@@ -13599,9 +14161,9 @@ Completion status of tasks.
| ---- | ---- | ----------- |
| <a id="terraformstatecreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp the Terraform state was created. |
| <a id="terraformstateid"></a>`id` | [`ID!`](#id) | ID of the Terraform state. |
-| <a id="terraformstatelatestversion"></a>`latestVersion` | [`TerraformStateVersion`](#terraformstateversion) | The latest version of the Terraform state. |
+| <a id="terraformstatelatestversion"></a>`latestVersion` | [`TerraformStateVersion`](#terraformstateversion) | Latest version of the Terraform state. |
| <a id="terraformstatelockedat"></a>`lockedAt` | [`Time`](#time) | Timestamp the Terraform state was locked. |
-| <a id="terraformstatelockedbyuser"></a>`lockedByUser` | [`UserCore`](#usercore) | The user currently holding a lock on the Terraform state. |
+| <a id="terraformstatelockedbyuser"></a>`lockedByUser` | [`UserCore`](#usercore) | User currently holding a lock on the Terraform state. |
| <a id="terraformstatename"></a>`name` | [`String!`](#string) | Name of the Terraform state. |
| <a id="terraformstateupdatedat"></a>`updatedAt` | [`Time!`](#time) | Timestamp the Terraform state was updated. |
@@ -13612,10 +14174,10 @@ Completion status of tasks.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="terraformstateversioncreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp the version was created. |
-| <a id="terraformstateversioncreatedbyuser"></a>`createdByUser` | [`UserCore`](#usercore) | The user that created this version. |
+| <a id="terraformstateversioncreatedbyuser"></a>`createdByUser` | [`UserCore`](#usercore) | User that created this version. |
| <a id="terraformstateversiondownloadpath"></a>`downloadPath` | [`String`](#string) | URL for downloading the version's JSON file. |
| <a id="terraformstateversionid"></a>`id` | [`ID!`](#id) | ID of the Terraform state version. |
-| <a id="terraformstateversionjob"></a>`job` | [`CiJob`](#cijob) | The job that created this version. |
+| <a id="terraformstateversionjob"></a>`job` | [`CiJob`](#cijob) | Job that created this version. |
| <a id="terraformstateversionserial"></a>`serial` | [`Int`](#int) | Serial number of the version. |
| <a id="terraformstateversionupdatedat"></a>`updatedAt` | [`Time!`](#time) | Timestamp the version was updated. |
@@ -13750,8 +14312,8 @@ Represents measured stats metrics for timeboxes.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="timeboxmetricscount"></a>`count` | [`Int!`](#int) | The count metric. |
-| <a id="timeboxmetricsweight"></a>`weight` | [`Int!`](#int) | The weight metric. |
+| <a id="timeboxmetricscount"></a>`count` | [`Int!`](#int) | Count metric. |
+| <a id="timeboxmetricsweight"></a>`weight` | [`Int!`](#int) | Weight metric. |
### `TimeboxReport`
@@ -13770,13 +14332,13 @@ Represents a historically accurate report about the timebox.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="timelogissue"></a>`issue` | [`Issue`](#issue) | The issue that logged time was added to. |
-| <a id="timelogmergerequest"></a>`mergeRequest` | [`MergeRequest`](#mergerequest) | The merge request that logged time was added to. |
-| <a id="timelognote"></a>`note` | [`Note`](#note) | The note where the quick action to add the logged time was executed. |
+| <a id="timelogissue"></a>`issue` | [`Issue`](#issue) | Issue that logged time was added to. |
+| <a id="timelogmergerequest"></a>`mergeRequest` | [`MergeRequest`](#mergerequest) | Merge request that logged time was added to. |
+| <a id="timelognote"></a>`note` | [`Note`](#note) | Note where the quick action was executed to add the logged time. |
| <a id="timelogspentat"></a>`spentAt` | [`Time`](#time) | Timestamp of when the time tracked was spent at. |
-| <a id="timelogsummary"></a>`summary` | [`String`](#string) | The summary of how the time was spent. |
-| <a id="timelogtimespent"></a>`timeSpent` | [`Int!`](#int) | The time spent displayed in seconds. |
-| <a id="timeloguser"></a>`user` | [`UserCore!`](#usercore) | The user that logged the time. |
+| <a id="timelogsummary"></a>`summary` | [`String`](#string) | Summary of how the time was spent. |
+| <a id="timelogtimespent"></a>`timeSpent` | [`Int!`](#int) | Time spent displayed in seconds. |
+| <a id="timeloguser"></a>`user` | [`UserCore!`](#usercore) | User that logged the time. |
### `Todo`
@@ -13787,12 +14349,12 @@ Representing a to-do entry.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="todoaction"></a>`action` | [`TodoActionEnum!`](#todoactionenum) | Action of the to-do item. |
-| <a id="todoauthor"></a>`author` | [`UserCore!`](#usercore) | The author of this to-do item. |
+| <a id="todoauthor"></a>`author` | [`UserCore!`](#usercore) | Author of this to-do item. |
| <a id="todobody"></a>`body` | [`String!`](#string) | Body of the to-do item. |
| <a id="todocreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp this to-do item was created. |
| <a id="todogroup"></a>`group` | [`Group`](#group) | Group this to-do item is associated with. |
| <a id="todoid"></a>`id` | [`ID!`](#id) | ID of the to-do item. |
-| <a id="todoproject"></a>`project` | [`Project`](#project) | The project this to-do item is associated with. |
+| <a id="todoproject"></a>`project` | [`Project`](#project) | Project this to-do item is associated with. |
| <a id="todostate"></a>`state` | [`TodoStateEnum!`](#todostateenum) | State of the to-do item. |
| <a id="todotargettype"></a>`targetType` | [`TodoTargetEnum!`](#todotargetenum) | Target type of the to-do item. |
@@ -13824,6 +14386,23 @@ Represents a directory.
| <a id="treeentrywebpath"></a>`webPath` | [`String`](#string) | Web path for the tree entry (directory). |
| <a id="treeentryweburl"></a>`webUrl` | [`String`](#string) | Web URL for the tree entry (directory). |
+### `UploadRegistry`
+
+Represents the Geo replication and verification state of an upload.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="uploadregistrycreatedat"></a>`createdAt` | [`Time`](#time) | Timestamp when the UploadRegistry was created. |
+| <a id="uploadregistryfileid"></a>`fileId` | [`ID!`](#id) | ID of the Upload. |
+| <a id="uploadregistryid"></a>`id` | [`ID!`](#id) | ID of the UploadRegistry. |
+| <a id="uploadregistrylastsyncfailure"></a>`lastSyncFailure` | [`String`](#string) | Error message during sync of the UploadRegistry. |
+| <a id="uploadregistrylastsyncedat"></a>`lastSyncedAt` | [`Time`](#time) | Timestamp of the most recent successful sync of the UploadRegistry. |
+| <a id="uploadregistryretryat"></a>`retryAt` | [`Time`](#time) | Timestamp after which the UploadRegistry should be resynced. |
+| <a id="uploadregistryretrycount"></a>`retryCount` | [`Int`](#int) | Number of consecutive failed sync attempts of the UploadRegistry. |
+| <a id="uploadregistrystate"></a>`state` | [`RegistryState`](#registrystate) | Sync state of the UploadRegistry. |
+
### `UsageTrendsMeasurement`
Represents a recorded measurement (object count) for the Admins.
@@ -13833,8 +14412,8 @@ Represents a recorded measurement (object count) for the Admins.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="usagetrendsmeasurementcount"></a>`count` | [`Int!`](#int) | Object count. |
-| <a id="usagetrendsmeasurementidentifier"></a>`identifier` | [`MeasurementIdentifier!`](#measurementidentifier) | The type of objects being measured. |
-| <a id="usagetrendsmeasurementrecordedat"></a>`recordedAt` | [`Time`](#time) | The time the measurement was recorded. |
+| <a id="usagetrendsmeasurementidentifier"></a>`identifier` | [`MeasurementIdentifier!`](#measurementidentifier) | Type of objects being measured. |
+| <a id="usagetrendsmeasurementrecordedat"></a>`recordedAt` | [`Time`](#time) | Time the measurement was recorded. |
### `UserCallout`
@@ -13860,7 +14439,7 @@ Core represention of a GitLab user.
| <a id="usercoregroupcount"></a>`groupCount` | [`Int`](#int) | Group count for the user. |
| <a id="usercoregroupmemberships"></a>`groupMemberships` | [`GroupMemberConnection`](#groupmemberconnection) | Group memberships of the user. (see [Connections](#connections)) |
| <a id="usercoreid"></a>`id` | [`ID!`](#id) | ID of the user. |
-| <a id="usercorelocation"></a>`location` | [`String`](#string) | The location of the user. |
+| <a id="usercorelocation"></a>`location` | [`String`](#string) | Location of the user. |
| <a id="usercorename"></a>`name` | [`String!`](#string) | Human-readable name of the user. |
| <a id="usercorenamespace"></a>`namespace` | [`Namespace`](#namespace) | Personal namespace of the user. |
| <a id="usercoreprojectmemberships"></a>`projectMemberships` | [`ProjectMemberConnection`](#projectmemberconnection) | Project memberships of the user. (see [Connections](#connections)) |
@@ -13900,7 +14479,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="usercoreassignedmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
| <a id="usercoreassignedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. |
| <a id="usercoreassignedmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. |
-| <a id="usercoreassignedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | A merge request state. If provided, all resolved merge requests will have this state. |
+| <a id="usercoreassignedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. |
| <a id="usercoreassignedmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. |
##### `UserCore.authoredMergeRequests`
@@ -13929,9 +14508,26 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="usercoreauthoredmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
| <a id="usercoreauthoredmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. |
| <a id="usercoreauthoredmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. |
-| <a id="usercoreauthoredmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | A merge request state. If provided, all resolved merge requests will have this state. |
+| <a id="usercoreauthoredmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. |
| <a id="usercoreauthoredmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. |
+##### `UserCore.groups`
+
+Groups where the user has access. Will always return `null` if `paginatable_namespace_drop_down_for_project_creation` feature flag is disabled.
+
+Returns [`GroupConnection`](#groupconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="usercoregroupspermissionscope"></a>`permissionScope` | [`GroupPermission`](#grouppermission) | Filter by permissions the user has on groups. |
+| <a id="usercoregroupssearch"></a>`search` | [`String`](#string) | Search by group name or path. |
+
##### `UserCore.reviewRequestedMergeRequests`
Merge requests assigned to the user for review.
@@ -13958,7 +14554,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="usercorereviewrequestedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
| <a id="usercorereviewrequestedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. |
| <a id="usercorereviewrequestedmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. |
-| <a id="usercorereviewrequestedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | A merge request state. If provided, all resolved merge requests will have this state. |
+| <a id="usercorereviewrequestedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. |
| <a id="usercorereviewrequestedmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. |
##### `UserCore.snippets`
@@ -13976,7 +14572,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="usercoresnippetsids"></a>`ids` | [`[SnippetID!]`](#snippetid) | Array of global snippet IDs. For example, `gid://gitlab/ProjectSnippet/1`. |
-| <a id="usercoresnippetstype"></a>`type` | [`TypeEnum`](#typeenum) | The type of snippet. |
+| <a id="usercoresnippetstype"></a>`type` | [`TypeEnum`](#typeenum) | Type of snippet. |
| <a id="usercoresnippetsvisibility"></a>`visibility` | [`VisibilityScopesEnum`](#visibilityscopesenum) | Visibility of the snippet. |
##### `UserCore.starredProjects`
@@ -14031,12 +14627,12 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="usercoretodosaction"></a>`action` | [`[TodoActionEnum!]`](#todoactionenum) | The action to be filtered. |
-| <a id="usercoretodosauthorid"></a>`authorId` | [`[ID!]`](#id) | The ID of an author. |
-| <a id="usercoretodosgroupid"></a>`groupId` | [`[ID!]`](#id) | The ID of a group. |
-| <a id="usercoretodosprojectid"></a>`projectId` | [`[ID!]`](#id) | The ID of a project. |
-| <a id="usercoretodosstate"></a>`state` | [`[TodoStateEnum!]`](#todostateenum) | The state of the todo. |
-| <a id="usercoretodostype"></a>`type` | [`[TodoTargetEnum!]`](#todotargetenum) | The type of the todo. |
+| <a id="usercoretodosaction"></a>`action` | [`[TodoActionEnum!]`](#todoactionenum) | Action to be filtered. |
+| <a id="usercoretodosauthorid"></a>`authorId` | [`[ID!]`](#id) | ID of an author. |
+| <a id="usercoretodosgroupid"></a>`groupId` | [`[ID!]`](#id) | ID of a group. |
+| <a id="usercoretodosprojectid"></a>`projectId` | [`[ID!]`](#id) | ID of a project. |
+| <a id="usercoretodosstate"></a>`state` | [`[TodoStateEnum!]`](#todostateenum) | State of the todo. |
+| <a id="usercoretodostype"></a>`type` | [`[TodoTargetEnum!]`](#todotargetenum) | Type of the todo. |
### `UserMergeRequestInteraction`
@@ -14053,7 +14649,7 @@ fields relate to interactions between the two entities.
| <a id="usermergerequestinteractionapproved"></a>`approved` | [`Boolean!`](#boolean) | Whether this user has approved this merge request. |
| <a id="usermergerequestinteractioncanmerge"></a>`canMerge` | [`Boolean!`](#boolean) | Whether this user can merge this merge request. |
| <a id="usermergerequestinteractioncanupdate"></a>`canUpdate` | [`Boolean!`](#boolean) | Whether this user can update this merge request. |
-| <a id="usermergerequestinteractionreviewstate"></a>`reviewState` | [`MergeRequestReviewState`](#mergerequestreviewstate) | The state of the review by this user. |
+| <a id="usermergerequestinteractionreviewstate"></a>`reviewState` | [`MergeRequestReviewState`](#mergerequestreviewstate) | State of the review by this user. |
| <a id="usermergerequestinteractionreviewed"></a>`reviewed` | [`Boolean!`](#boolean) | Whether this user has provided a review for this merge request. |
### `UserPermissions`
@@ -14101,15 +14697,15 @@ Represents a vulnerability.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="vulnerabilityconfirmedat"></a>`confirmedAt` | [`Time`](#time) | Timestamp of when the vulnerability state was changed to confirmed. |
-| <a id="vulnerabilityconfirmedby"></a>`confirmedBy` | [`UserCore`](#usercore) | The user that confirmed the vulnerability. |
+| <a id="vulnerabilityconfirmedby"></a>`confirmedBy` | [`UserCore`](#usercore) | User that confirmed the vulnerability. |
| <a id="vulnerabilitydescription"></a>`description` | [`String`](#string) | Description of the vulnerability. |
| <a id="vulnerabilitydetails"></a>`details` | [`[VulnerabilityDetail!]!`](#vulnerabilitydetail) | Details of the vulnerability. |
| <a id="vulnerabilitydetectedat"></a>`detectedAt` | [`Time!`](#time) | Timestamp of when the vulnerability was first detected. |
| <a id="vulnerabilitydiscussions"></a>`discussions` | [`DiscussionConnection!`](#discussionconnection) | All discussions on this noteable. (see [Connections](#connections)) |
| <a id="vulnerabilitydismissedat"></a>`dismissedAt` | [`Time`](#time) | Timestamp of when the vulnerability state was changed to dismissed. |
-| <a id="vulnerabilitydismissedby"></a>`dismissedBy` | [`UserCore`](#usercore) | The user that dismissed the vulnerability. |
+| <a id="vulnerabilitydismissedby"></a>`dismissedBy` | [`UserCore`](#usercore) | User that dismissed the vulnerability. |
| <a id="vulnerabilityexternalissuelinks"></a>`externalIssueLinks` | [`VulnerabilityExternalIssueLinkConnection!`](#vulnerabilityexternalissuelinkconnection) | List of external issue links related to the vulnerability. (see [Connections](#connections)) |
-| <a id="vulnerabilityfalsepositive"></a>`falsePositive` | [`Boolean`](#boolean) | Indicates whether the vulnerability is a false positive. Available only when feature flag `vulnerability_flags` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice. |
+| <a id="vulnerabilityfalsepositive"></a>`falsePositive` | [`Boolean`](#boolean) | Indicates whether the vulnerability is a false positive. |
| <a id="vulnerabilityhassolutions"></a>`hasSolutions` | [`Boolean`](#boolean) | Indicates whether there is a solution available for this vulnerability. |
| <a id="vulnerabilityid"></a>`id` | [`ID!`](#id) | GraphQL ID of the vulnerability. |
| <a id="vulnerabilityidentifiers"></a>`identifiers` | [`[VulnerabilityIdentifier!]!`](#vulnerabilityidentifier) | Identifiers of the vulnerability. |
@@ -14117,10 +14713,10 @@ Represents a vulnerability.
| <a id="vulnerabilitymergerequest"></a>`mergeRequest` | [`MergeRequest`](#mergerequest) | Merge request that fixes the vulnerability. |
| <a id="vulnerabilitynotes"></a>`notes` | [`NoteConnection!`](#noteconnection) | All notes on this noteable. (see [Connections](#connections)) |
| <a id="vulnerabilityprimaryidentifier"></a>`primaryIdentifier` | [`VulnerabilityIdentifier`](#vulnerabilityidentifier) | Primary identifier of the vulnerability. |
-| <a id="vulnerabilityproject"></a>`project` | [`Project`](#project) | The project on which the vulnerability was found. |
-| <a id="vulnerabilityreporttype"></a>`reportType` | [`VulnerabilityReportType`](#vulnerabilityreporttype) | Type of the security report that found the vulnerability (SAST, DEPENDENCY_SCANNING, CONTAINER_SCANNING, DAST, SECRET_DETECTION, COVERAGE_FUZZING, API_FUZZING, CLUSTER_IMAGE_SCANNING). `Scan Type` in the UI. |
+| <a id="vulnerabilityproject"></a>`project` | [`Project`](#project) | Project on which the vulnerability was found. |
+| <a id="vulnerabilityreporttype"></a>`reportType` | [`VulnerabilityReportType`](#vulnerabilityreporttype) | Type of the security report that found the vulnerability (SAST, DEPENDENCY_SCANNING, CONTAINER_SCANNING, DAST, SECRET_DETECTION, COVERAGE_FUZZING, API_FUZZING, CLUSTER_IMAGE_SCANNING, GENERIC). `Scan Type` in the UI. |
| <a id="vulnerabilityresolvedat"></a>`resolvedAt` | [`Time`](#time) | Timestamp of when the vulnerability state was changed to resolved. |
-| <a id="vulnerabilityresolvedby"></a>`resolvedBy` | [`UserCore`](#usercore) | The user that resolved the vulnerability. |
+| <a id="vulnerabilityresolvedby"></a>`resolvedBy` | [`UserCore`](#usercore) | User that resolved the vulnerability. |
| <a id="vulnerabilityresolvedondefaultbranch"></a>`resolvedOnDefaultBranch` | [`Boolean!`](#boolean) | Indicates whether the vulnerability is fixed on the default branch or not. |
| <a id="vulnerabilityscanner"></a>`scanner` | [`VulnerabilityScanner`](#vulnerabilityscanner) | Scanner metadata for the vulnerability. |
| <a id="vulnerabilityseverity"></a>`severity` | [`VulnerabilitySeverity`](#vulnerabilityseverity) | Severity of the vulnerability (INFO, UNKNOWN, LOW, MEDIUM, HIGH, CRITICAL). |
@@ -14198,7 +14794,7 @@ Represents the vulnerability details commit field.
| <a id="vulnerabilitydetailcommitdescription"></a>`description` | [`String`](#string) | Description of the field. |
| <a id="vulnerabilitydetailcommitfieldname"></a>`fieldName` | [`String`](#string) | Name of the field. |
| <a id="vulnerabilitydetailcommitname"></a>`name` | [`String`](#string) | Name of the field. |
-| <a id="vulnerabilitydetailcommitvalue"></a>`value` | [`String!`](#string) | The commit SHA value. |
+| <a id="vulnerabilitydetailcommitvalue"></a>`value` | [`String!`](#string) | Commit SHA value. |
### `VulnerabilityDetailDiff`
@@ -14357,7 +14953,7 @@ Represents an issue link of a vulnerability.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="vulnerabilityissuelinkid"></a>`id` | [`ID!`](#id) | GraphQL ID of the vulnerability. |
-| <a id="vulnerabilityissuelinkissue"></a>`issue` | [`Issue!`](#issue) | The issue attached to issue link. |
+| <a id="vulnerabilityissuelinkissue"></a>`issue` | [`Issue!`](#issue) | Issue attached to issue link. |
| <a id="vulnerabilityissuelinklinktype"></a>`linkType` | [`VulnerabilityIssueLinkType!`](#vulnerabilityissuelinktype) | Type of the issue link. |
### `VulnerabilityLocationContainerScanning`
@@ -14412,6 +15008,16 @@ Represents the location of a vulnerability found by a dependency security scan.
| <a id="vulnerabilitylocationdependencyscanningdependency"></a>`dependency` | [`VulnerableDependency`](#vulnerabledependency) | Dependency containing the vulnerability. |
| <a id="vulnerabilitylocationdependencyscanningfile"></a>`file` | [`String`](#string) | Path to the vulnerable file. |
+### `VulnerabilityLocationGeneric`
+
+Represents the location of a vulnerability found by a generic scanner.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="vulnerabilitylocationgenericdescription"></a>`description` | [`String`](#string) | Free-form description of where the vulnerability is located. |
+
### `VulnerabilityLocationSast`
Represents the location of a vulnerability found by a SAST scan.
@@ -14497,8 +15103,8 @@ Represents a vulnerable dependency. Used in vulnerability location data.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="vulnerabledependencypackage"></a>`package` | [`VulnerablePackage`](#vulnerablepackage) | The package associated with the vulnerable dependency. |
-| <a id="vulnerabledependencyversion"></a>`version` | [`String`](#string) | The version of the vulnerable dependency. |
+| <a id="vulnerabledependencypackage"></a>`package` | [`VulnerablePackage`](#vulnerablepackage) | Package associated with the vulnerable dependency. |
+| <a id="vulnerabledependencyversion"></a>`version` | [`String`](#string) | Version of the vulnerable dependency. |
### `VulnerablePackage`
@@ -14508,7 +15114,7 @@ Represents a vulnerable package. Used in vulnerability dependency data.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="vulnerablepackagename"></a>`name` | [`String`](#string) | The name of the vulnerable package. |
+| <a id="vulnerablepackagename"></a>`name` | [`String`](#string) | Name of the vulnerable package. |
### `VulnerableProjectsByGrade`
@@ -14698,8 +15304,8 @@ Values for YAML processor result.
| Value | Description |
| ----- | ----------- |
-| <a id="ciconfigstatusinvalid"></a>`INVALID` | The configuration file is not valid. |
-| <a id="ciconfigstatusvalid"></a>`VALID` | The configuration file is valid. |
+| <a id="ciconfigstatusinvalid"></a>`INVALID` | Configuration file is not valid. |
+| <a id="ciconfigstatusvalid"></a>`VALID` | Configuration file is valid. |
### `CiJobStatus`
@@ -14827,10 +15433,10 @@ Status of the tags cleanup of a container repository.
| Value | Description |
| ----- | ----------- |
-| <a id="containerrepositorycleanupstatusongoing"></a>`ONGOING` | The tags cleanup is ongoing. |
-| <a id="containerrepositorycleanupstatusscheduled"></a>`SCHEDULED` | The tags cleanup is scheduled and is going to be executed shortly. |
-| <a id="containerrepositorycleanupstatusunfinished"></a>`UNFINISHED` | The tags cleanup has been partially executed. There are still remaining tags to delete. |
-| <a id="containerrepositorycleanupstatusunscheduled"></a>`UNSCHEDULED` | The tags cleanup is not scheduled. This is the default state. |
+| <a id="containerrepositorycleanupstatusongoing"></a>`ONGOING` | Tags cleanup is ongoing. |
+| <a id="containerrepositorycleanupstatusscheduled"></a>`SCHEDULED` | Tags cleanup is scheduled and is going to be executed shortly. |
+| <a id="containerrepositorycleanupstatusunfinished"></a>`UNFINISHED` | Tags cleanup has been partially executed. There are still remaining tags to delete. |
+| <a id="containerrepositorycleanupstatusunscheduled"></a>`UNSCHEDULED` | Tags cleanup is not scheduled. This is the default state. |
### `ContainerRepositorySort`
@@ -14858,6 +15464,17 @@ Status of a container repository.
| <a id="containerrepositorystatusdelete_failed"></a>`DELETE_FAILED` | Delete Failed status. |
| <a id="containerrepositorystatusdelete_scheduled"></a>`DELETE_SCHEDULED` | Delete Scheduled status. |
+### `DastProfileCadenceUnit`
+
+Unit for the duration of Dast Profile Cadence.
+
+| Value | Description |
+| ----- | ----------- |
+| <a id="dastprofilecadenceunitday"></a>`DAY` | DAST Profile Cadence duration in days. |
+| <a id="dastprofilecadenceunitmonth"></a>`MONTH` | DAST Profile Cadence duration in months. |
+| <a id="dastprofilecadenceunitweek"></a>`WEEK` | DAST Profile Cadence duration in weeks. |
+| <a id="dastprofilecadenceunityear"></a>`YEAR` | DAST Profile Cadence duration in years. |
+
### `DastScanTypeEnum`
| Value | Description |
@@ -14875,6 +15492,15 @@ Status of a container repository.
| <a id="dastsiteprofilevalidationstatusenumpassed_validation"></a>`PASSED_VALIDATION` | Site validation process finished successfully. |
| <a id="dastsiteprofilevalidationstatusenumpending_validation"></a>`PENDING_VALIDATION` | Site validation process has not started. |
+### `DastSiteValidationStatusEnum`
+
+| Value | Description |
+| ----- | ----------- |
+| <a id="dastsitevalidationstatusenumfailed_validation"></a>`FAILED_VALIDATION` | Site validation process finished but failed. |
+| <a id="dastsitevalidationstatusenuminprogress_validation"></a>`INPROGRESS_VALIDATION` | Site validation process is in progress. |
+| <a id="dastsitevalidationstatusenumpassed_validation"></a>`PASSED_VALIDATION` | Site validation process finished successfully. |
+| <a id="dastsitevalidationstatusenumpending_validation"></a>`PENDING_VALIDATION` | Site validation process has not started. |
+
### `DastSiteValidationStrategyEnum`
| Value | Description |
@@ -14960,7 +15586,7 @@ Type of file the position refers to.
| Value | Description |
| ----- | ----------- |
| <a id="diffpositiontypeimage"></a>`image` | An image. |
-| <a id="diffpositiontypetext"></a>`text` | A text file. |
+| <a id="diffpositiontypetext"></a>`text` | Text file. |
### `DoraMetricBucketingInterval`
@@ -15074,6 +15700,14 @@ Group member relation.
| <a id="groupmemberrelationdirect"></a>`DIRECT` | Members in the group itself. |
| <a id="groupmemberrelationinherited"></a>`INHERITED` | Members in the group's ancestor groups. |
+### `GroupPermission`
+
+User permission on groups.
+
+| Value | Description |
+| ----- | ----------- |
+| <a id="grouppermissioncreate_projects"></a>`CREATE_PROJECTS` | Groups where the user can create projects. |
+
### `HealthStatus`
Health status of an issue or epic.
@@ -15143,6 +15777,8 @@ Values for sorting issues.
| <a id="issuesortseverity_desc"></a>`SEVERITY_DESC` | Severity from more critical to less critical. |
| <a id="issuesortsla_due_at_asc"></a>`SLA_DUE_AT_ASC` | Issues with earliest SLA due time shown first. |
| <a id="issuesortsla_due_at_desc"></a>`SLA_DUE_AT_DESC` | Issues with latest SLA due time shown first. |
+| <a id="issuesorttitle_asc"></a>`TITLE_ASC` | Title by ascending order. |
+| <a id="issuesorttitle_desc"></a>`TITLE_DESC` | Title by descending order. |
| <a id="issuesortupdated_asc"></a>`UPDATED_ASC` | Updated at ascending order. |
| <a id="issuesortupdated_desc"></a>`UPDATED_DESC` | Updated at descending order. |
| <a id="issuesortweight_asc"></a>`WEIGHT_ASC` | Weight by ascending order. |
@@ -15189,12 +15825,12 @@ State of a GitLab iteration.
| Value | Description |
| ----- | ----------- |
-| <a id="iterationstateall"></a>`all` | |
-| <a id="iterationstateclosed"></a>`closed` | |
-| <a id="iterationstatecurrent"></a>`current` | |
-| <a id="iterationstateopened"></a>`opened` | |
+| <a id="iterationstateall"></a>`all` | Any iteration. |
+| <a id="iterationstateclosed"></a>`closed` | Closed iteration. |
+| <a id="iterationstatecurrent"></a>`current` | Current iteration. |
+| <a id="iterationstateopened"></a>`opened` | Open iteration. |
| <a id="iterationstatestarted"></a>`started` **{warning-solid}** | **Deprecated** in 14.1. Use current instead. |
-| <a id="iterationstateupcoming"></a>`upcoming` | |
+| <a id="iterationstateupcoming"></a>`upcoming` | Upcoming iteration. |
### `IterationWildcardId`
@@ -15374,10 +16010,10 @@ Milestone ID wildcard values.
| Value | Description |
| ----- | ----------- |
-| <a id="milestonewildcardidany"></a>`ANY` | A milestone is assigned. |
+| <a id="milestonewildcardidany"></a>`ANY` | Milestone is assigned. |
| <a id="milestonewildcardidnone"></a>`NONE` | No milestone is assigned. |
-| <a id="milestonewildcardidstarted"></a>`STARTED` | An open, started milestone (start date <= today). |
-| <a id="milestonewildcardidupcoming"></a>`UPCOMING` | An open milestone due in the future (due date >= today). |
+| <a id="milestonewildcardidstarted"></a>`STARTED` | Milestone assigned is open and started (start date <= today). |
+| <a id="milestonewildcardidupcoming"></a>`UPCOMING` | Milestone assigned is due closest in the future (due date > today). |
### `MoveType`
@@ -15385,8 +16021,8 @@ The position to which the adjacent object should be moved.
| Value | Description |
| ----- | ----------- |
-| <a id="movetypeafter"></a>`after` | The adjacent object will be moved after the object that is being moved. |
-| <a id="movetypebefore"></a>`before` | The adjacent object will be moved before the object that is being moved. |
+| <a id="movetypeafter"></a>`after` | Adjacent object is moved after the object that is being moved. |
+| <a id="movetypebefore"></a>`before` | Adjacent object is moved before the object that is being moved. |
### `MutationOperationMode`
@@ -15421,8 +16057,8 @@ Negated Milestone ID wildcard values.
| Value | Description |
| ----- | ----------- |
-| <a id="negatedmilestonewildcardidstarted"></a>`STARTED` | An open, started milestone (start date <= today). |
-| <a id="negatedmilestonewildcardidupcoming"></a>`UPCOMING` | An open milestone due in the future (due date >= today). |
+| <a id="negatedmilestonewildcardidstarted"></a>`STARTED` | Milestone assigned is open and yet to be started (start date > today). |
+| <a id="negatedmilestonewildcardidupcoming"></a>`UPCOMING` | Milestone assigned is open but due in the past (due date <= today). |
### `NetworkPolicyKind`
@@ -15430,8 +16066,8 @@ Kind of the network policy.
| Value | Description |
| ----- | ----------- |
-| <a id="networkpolicykindciliumnetworkpolicy"></a>`CiliumNetworkPolicy` | The policy kind of Cilium Network Policy. |
-| <a id="networkpolicykindnetworkpolicy"></a>`NetworkPolicy` | The policy kind of Network Policy. |
+| <a id="networkpolicykindciliumnetworkpolicy"></a>`CiliumNetworkPolicy` | Policy kind of Cilium Network Policy. |
+| <a id="networkpolicykindnetworkpolicy"></a>`NetworkPolicy` | Policy kind of Network Policy. |
### `OncallRotationUnitEnum`
@@ -15590,8 +16226,8 @@ State of a requirement.
| Value | Description |
| ----- | ----------- |
-| <a id="requirementstatearchived"></a>`ARCHIVED` | |
-| <a id="requirementstateopened"></a>`OPENED` | |
+| <a id="requirementstatearchived"></a>`ARCHIVED` | Archived requirement. |
+| <a id="requirementstateopened"></a>`OPENED` | Open requirement. |
### `RequirementStatusFilter`
@@ -15599,9 +16235,18 @@ Status of a requirement based on last test report.
| Value | Description |
| ----- | ----------- |
-| <a id="requirementstatusfilterfailed"></a>`FAILED` | |
+| <a id="requirementstatusfilterfailed"></a>`FAILED` | Failed test report. |
| <a id="requirementstatusfiltermissing"></a>`MISSING` | Requirements without any test report. |
-| <a id="requirementstatusfilterpassed"></a>`PASSED` | |
+| <a id="requirementstatusfilterpassed"></a>`PASSED` | Passed test report. |
+
+### `RunnerMembershipFilter`
+
+Values for filtering runners in namespaces.
+
+| Value | Description |
+| ----- | ----------- |
+| <a id="runnermembershipfilterdescendants"></a>`DESCENDANTS` | Include runners that have either a direct relationship or a relationship with descendants. These can be project runners or group runners (in the case where group is queried). |
+| <a id="runnermembershipfilterdirect"></a>`DIRECT` | Include runners that have a direct relationship. |
### `SastUiComponentSize`
@@ -15609,9 +16254,9 @@ Size of UI component in SAST configuration page.
| Value | Description |
| ----- | ----------- |
-| <a id="sastuicomponentsizelarge"></a>`LARGE` | The size of UI component in SAST configuration page is large. |
-| <a id="sastuicomponentsizemedium"></a>`MEDIUM` | The size of UI component in SAST configuration page is medium. |
-| <a id="sastuicomponentsizesmall"></a>`SMALL` | The size of UI component in SAST configuration page is small. |
+| <a id="sastuicomponentsizelarge"></a>`LARGE` | Size of UI component in SAST configuration page is large. |
+| <a id="sastuicomponentsizemedium"></a>`MEDIUM` | Size of UI component in SAST configuration page is medium. |
+| <a id="sastuicomponentsizesmall"></a>`SMALL` | Size of UI component in SAST configuration page is small. |
### `SecurityReportTypeEnum`
@@ -15632,14 +16277,14 @@ The type of the security scanner.
| Value | Description |
| ----- | ----------- |
-| <a id="securityscannertypeapi_fuzzing"></a>`API_FUZZING` | |
-| <a id="securityscannertypecluster_image_scanning"></a>`CLUSTER_IMAGE_SCANNING` | |
-| <a id="securityscannertypecontainer_scanning"></a>`CONTAINER_SCANNING` | |
-| <a id="securityscannertypecoverage_fuzzing"></a>`COVERAGE_FUZZING` | |
-| <a id="securityscannertypedast"></a>`DAST` | |
-| <a id="securityscannertypedependency_scanning"></a>`DEPENDENCY_SCANNING` | |
-| <a id="securityscannertypesast"></a>`SAST` | |
-| <a id="securityscannertypesecret_detection"></a>`SECRET_DETECTION` | |
+| <a id="securityscannertypeapi_fuzzing"></a>`API_FUZZING` | API Fuzzing scanner. |
+| <a id="securityscannertypecluster_image_scanning"></a>`CLUSTER_IMAGE_SCANNING` | Cluster Image Scanning scanner. |
+| <a id="securityscannertypecontainer_scanning"></a>`CONTAINER_SCANNING` | Container Scanning scanner. |
+| <a id="securityscannertypecoverage_fuzzing"></a>`COVERAGE_FUZZING` | Coverage Fuzzing scanner. |
+| <a id="securityscannertypedast"></a>`DAST` | DAST scanner. |
+| <a id="securityscannertypedependency_scanning"></a>`DEPENDENCY_SCANNING` | Dependency Scanning scanner. |
+| <a id="securityscannertypesast"></a>`SAST` | SAST scanner. |
+| <a id="securityscannertypesecret_detection"></a>`SECRET_DETECTION` | Secret Detection scanner. |
### `SentryErrorStatus`
@@ -15741,8 +16386,8 @@ State of a test report.
| Value | Description |
| ----- | ----------- |
-| <a id="testreportstatefailed"></a>`FAILED` | |
-| <a id="testreportstatepassed"></a>`PASSED` | |
+| <a id="testreportstatefailed"></a>`FAILED` | Failed test report. |
+| <a id="testreportstatepassed"></a>`PASSED` | Passed test report. |
### `TodoActionEnum`
@@ -15762,19 +16407,19 @@ State of a test report.
| Value | Description |
| ----- | ----------- |
-| <a id="todostateenumdone"></a>`done` | The state of the todo is done. |
-| <a id="todostateenumpending"></a>`pending` | The state of the todo is pending. |
+| <a id="todostateenumdone"></a>`done` | State of the todo is done. |
+| <a id="todostateenumpending"></a>`pending` | State of the todo is pending. |
### `TodoTargetEnum`
| Value | Description |
| ----- | ----------- |
-| <a id="todotargetenumalert"></a>`ALERT` | An Alert. |
-| <a id="todotargetenumcommit"></a>`COMMIT` | A Commit. |
-| <a id="todotargetenumdesign"></a>`DESIGN` | A Design. |
+| <a id="todotargetenumalert"></a>`ALERT` | Alert. |
+| <a id="todotargetenumcommit"></a>`COMMIT` | Commit. |
+| <a id="todotargetenumdesign"></a>`DESIGN` | Design. |
| <a id="todotargetenumepic"></a>`EPIC` | An Epic. |
-| <a id="todotargetenumissue"></a>`ISSUE` | An Issue. |
-| <a id="todotargetenummergerequest"></a>`MERGEREQUEST` | A MergeRequest. |
+| <a id="todotargetenumissue"></a>`ISSUE` | Issue. |
+| <a id="todotargetenummergerequest"></a>`MERGEREQUEST` | Merge request. |
### `TypeEnum`
@@ -15789,7 +16434,6 @@ Name of the feature that the callout is for.
| Value | Description |
| ----- | ----------- |
-| <a id="usercalloutfeaturenameenumaccount_recovery_regular_check"></a>`ACCOUNT_RECOVERY_REGULAR_CHECK` | Callout feature name for account_recovery_regular_check. |
| <a id="usercalloutfeaturenameenumactive_user_count_threshold"></a>`ACTIVE_USER_COUNT_THRESHOLD` | Callout feature name for active_user_count_threshold. |
| <a id="usercalloutfeaturenameenumbuy_pipeline_minutes_notification_dot"></a>`BUY_PIPELINE_MINUTES_NOTIFICATION_DOT` | Callout feature name for buy_pipeline_minutes_notification_dot. |
| <a id="usercalloutfeaturenameenumcanary_deployment"></a>`CANARY_DEPLOYMENT` | Callout feature name for canary_deployment. |
@@ -15818,6 +16462,7 @@ Name of the feature that the callout is for.
| <a id="usercalloutfeaturenameenumthreat_monitoring_info"></a>`THREAT_MONITORING_INFO` | Callout feature name for threat_monitoring_info. |
| <a id="usercalloutfeaturenameenumtrial_status_reminder_d14"></a>`TRIAL_STATUS_REMINDER_D14` | Callout feature name for trial_status_reminder_d14. |
| <a id="usercalloutfeaturenameenumtrial_status_reminder_d3"></a>`TRIAL_STATUS_REMINDER_D3` | Callout feature name for trial_status_reminder_d3. |
+| <a id="usercalloutfeaturenameenumtwo_factor_auth_recovery_settings_check"></a>`TWO_FACTOR_AUTH_RECOVERY_SETTINGS_CHECK` | Callout feature name for two_factor_auth_recovery_settings_check. |
| <a id="usercalloutfeaturenameenumultimate_trial"></a>`ULTIMATE_TRIAL` | Callout feature name for ultimate_trial. |
| <a id="usercalloutfeaturenameenumunfinished_tag_cleanup_callout"></a>`UNFINISHED_TAG_CLEANUP_CALLOUT` | Callout feature name for unfinished_tag_cleanup_callout. |
| <a id="usercalloutfeaturenameenumweb_ide_alert_dismissed"></a>`WEB_IDE_ALERT_DISMISSED` | Callout feature name for web_ide_alert_dismissed. |
@@ -15829,9 +16474,9 @@ Possible states of a user.
| Value | Description |
| ----- | ----------- |
-| <a id="userstateactive"></a>`active` | The user is active and is able to use the system. |
-| <a id="userstateblocked"></a>`blocked` | The user has been blocked and is prevented from using the system. |
-| <a id="userstatedeactivated"></a>`deactivated` | The user is no longer active and is unable to use the system. |
+| <a id="userstateactive"></a>`active` | User is active and is able to use the system. |
+| <a id="userstateblocked"></a>`blocked` | User has been blocked and is prevented from using the system. |
+| <a id="userstatedeactivated"></a>`deactivated` | User is no longer active and is unable to use the system. |
### `VisibilityLevelsEnum`
@@ -15845,9 +16490,23 @@ Possible states of a user.
| Value | Description |
| ----- | ----------- |
-| <a id="visibilityscopesenuminternal"></a>`internal` | The snippet is visible for any logged in user except external users. |
-| <a id="visibilityscopesenumprivate"></a>`private` | The snippet is visible only to the snippet creator. |
-| <a id="visibilityscopesenumpublic"></a>`public` | The snippet can be accessed without any authentication. |
+| <a id="visibilityscopesenuminternal"></a>`internal` | Snippet is visible for any logged in user except external users. |
+| <a id="visibilityscopesenumprivate"></a>`private` | Snippet is visible only to the snippet creator. |
+| <a id="visibilityscopesenumpublic"></a>`public` | Snippet can be accessed without any authentication. |
+
+### `VulnerabilityConfidence`
+
+Confidence that a given vulnerability is present in the codebase.
+
+| Value | Description |
+| ----- | ----------- |
+| <a id="vulnerabilityconfidenceconfirmed"></a>`CONFIRMED` | Confirmed confidence. |
+| <a id="vulnerabilityconfidenceexperimental"></a>`EXPERIMENTAL` | Experimental confidence. |
+| <a id="vulnerabilityconfidencehigh"></a>`HIGH` | High confidence. |
+| <a id="vulnerabilityconfidenceignore"></a>`IGNORE` | Ignore confidence. |
+| <a id="vulnerabilityconfidencelow"></a>`LOW` | Low confidence. |
+| <a id="vulnerabilityconfidencemedium"></a>`MEDIUM` | Medium confidence. |
+| <a id="vulnerabilityconfidenceunknown"></a>`UNKNOWN` | Unknown confidence. |
### `VulnerabilityDismissalReason`
@@ -15883,11 +16542,11 @@ The grade of the vulnerable project.
| Value | Description |
| ----- | ----------- |
-| <a id="vulnerabilitygradea"></a>`A` | |
-| <a id="vulnerabilitygradeb"></a>`B` | |
-| <a id="vulnerabilitygradec"></a>`C` | |
-| <a id="vulnerabilitygraded"></a>`D` | |
-| <a id="vulnerabilitygradef"></a>`F` | |
+| <a id="vulnerabilitygradea"></a>`A` | A grade. |
+| <a id="vulnerabilitygradeb"></a>`B` | B grade. |
+| <a id="vulnerabilitygradec"></a>`C` | C grade. |
+| <a id="vulnerabilitygraded"></a>`D` | D grade. |
+| <a id="vulnerabilitygradef"></a>`F` | F grade. |
### `VulnerabilityIssueLinkType`
@@ -15895,8 +16554,8 @@ The type of the issue link related to a vulnerability.
| Value | Description |
| ----- | ----------- |
-| <a id="vulnerabilityissuelinktypecreated"></a>`CREATED` | |
-| <a id="vulnerabilityissuelinktyperelated"></a>`RELATED` | |
+| <a id="vulnerabilityissuelinktypecreated"></a>`CREATED` | Issue is created for the vulnerability. |
+| <a id="vulnerabilityissuelinktyperelated"></a>`RELATED` | Has a related issue. |
### `VulnerabilityReportType`
@@ -15904,14 +16563,15 @@ The type of the security scan that found the vulnerability.
| Value | Description |
| ----- | ----------- |
-| <a id="vulnerabilityreporttypeapi_fuzzing"></a>`API_FUZZING` | |
-| <a id="vulnerabilityreporttypecluster_image_scanning"></a>`CLUSTER_IMAGE_SCANNING` | |
-| <a id="vulnerabilityreporttypecontainer_scanning"></a>`CONTAINER_SCANNING` | |
-| <a id="vulnerabilityreporttypecoverage_fuzzing"></a>`COVERAGE_FUZZING` | |
-| <a id="vulnerabilityreporttypedast"></a>`DAST` | |
-| <a id="vulnerabilityreporttypedependency_scanning"></a>`DEPENDENCY_SCANNING` | |
-| <a id="vulnerabilityreporttypesast"></a>`SAST` | |
-| <a id="vulnerabilityreporttypesecret_detection"></a>`SECRET_DETECTION` | |
+| <a id="vulnerabilityreporttypeapi_fuzzing"></a>`API_FUZZING` | API Fuzzing report. |
+| <a id="vulnerabilityreporttypecluster_image_scanning"></a>`CLUSTER_IMAGE_SCANNING` | Cluster Image Scanning report. |
+| <a id="vulnerabilityreporttypecontainer_scanning"></a>`CONTAINER_SCANNING` | Container Scanning report. |
+| <a id="vulnerabilityreporttypecoverage_fuzzing"></a>`COVERAGE_FUZZING` | Coverage Fuzzing report. |
+| <a id="vulnerabilityreporttypedast"></a>`DAST` | DAST report. |
+| <a id="vulnerabilityreporttypedependency_scanning"></a>`DEPENDENCY_SCANNING` | Dependency Scanning report. |
+| <a id="vulnerabilityreporttypegeneric"></a>`GENERIC` | Generic report. |
+| <a id="vulnerabilityreporttypesast"></a>`SAST` | SAST report. |
+| <a id="vulnerabilityreporttypesecret_detection"></a>`SECRET_DETECTION` | Secret Detection report. |
### `VulnerabilitySeverity`
@@ -15919,12 +16579,12 @@ The severity of the vulnerability.
| Value | Description |
| ----- | ----------- |
-| <a id="vulnerabilityseveritycritical"></a>`CRITICAL` | |
-| <a id="vulnerabilityseverityhigh"></a>`HIGH` | |
-| <a id="vulnerabilityseverityinfo"></a>`INFO` | |
-| <a id="vulnerabilityseveritylow"></a>`LOW` | |
-| <a id="vulnerabilityseveritymedium"></a>`MEDIUM` | |
-| <a id="vulnerabilityseverityunknown"></a>`UNKNOWN` | |
+| <a id="vulnerabilityseveritycritical"></a>`CRITICAL` | Critical severity. |
+| <a id="vulnerabilityseverityhigh"></a>`HIGH` | High severity. |
+| <a id="vulnerabilityseverityinfo"></a>`INFO` | Info severity. |
+| <a id="vulnerabilityseveritylow"></a>`LOW` | Low severity. |
+| <a id="vulnerabilityseveritymedium"></a>`MEDIUM` | Medium severity. |
+| <a id="vulnerabilityseverityunknown"></a>`UNKNOWN` | Unknown severity. |
### `VulnerabilitySort`
@@ -15949,10 +16609,10 @@ The state of the vulnerability.
| Value | Description |
| ----- | ----------- |
-| <a id="vulnerabilitystateconfirmed"></a>`CONFIRMED` | |
-| <a id="vulnerabilitystatedetected"></a>`DETECTED` | |
-| <a id="vulnerabilitystatedismissed"></a>`DISMISSED` | |
-| <a id="vulnerabilitystateresolved"></a>`RESOLVED` | |
+| <a id="vulnerabilitystateconfirmed"></a>`CONFIRMED` | Confirmed vulnerability. |
+| <a id="vulnerabilitystatedetected"></a>`DETECTED` | Detected vulnerability. |
+| <a id="vulnerabilitystatedismissed"></a>`DISMISSED` | Dismissed vulnerability. |
+| <a id="vulnerabilitystateresolved"></a>`RESOLVED` | Resolved vulnerability. |
### `WeightWildcardId`
@@ -16072,12 +16732,24 @@ A `CustomEmojiID` is a global ID. It is encoded as a string.
An example `CustomEmojiID` is: `"gid://gitlab/CustomEmoji/1"`.
+### `CustomerRelationsOrganizationID`
+
+A `CustomerRelationsOrganizationID` is a global ID. It is encoded as a string.
+
+An example `CustomerRelationsOrganizationID` is: `"gid://gitlab/CustomerRelations::Organization/1"`.
+
### `DastProfileID`
A `DastProfileID` is a global ID. It is encoded as a string.
An example `DastProfileID` is: `"gid://gitlab/Dast::Profile/1"`.
+### `DastProfileScheduleID`
+
+A `DastProfileScheduleID` is a global ID. It is encoded as a string.
+
+An example `DastProfileScheduleID` is: `"gid://gitlab/Dast::ProfileSchedule/1"`.
+
### `DastScannerProfileID`
A `DastScannerProfileID` is a global ID. It is encoded as a string.
@@ -16550,6 +17222,7 @@ One of:
- [`VulnerabilityLocationCoverageFuzzing`](#vulnerabilitylocationcoveragefuzzing)
- [`VulnerabilityLocationDast`](#vulnerabilitylocationdast)
- [`VulnerabilityLocationDependencyScanning`](#vulnerabilitylocationdependencyscanning)
+- [`VulnerabilityLocationGeneric`](#vulnerabilitylocationgeneric)
- [`VulnerabilityLocationSast`](#vulnerabilitylocationsast)
- [`VulnerabilityLocationSecretDetection`](#vulnerabilitylocationsecretdetection)
@@ -16614,16 +17287,16 @@ Implementations:
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="designfieldsdiffrefs"></a>`diffRefs` | [`DiffRefs!`](#diffrefs) | The diff refs for this design. |
+| <a id="designfieldsdiffrefs"></a>`diffRefs` | [`DiffRefs!`](#diffrefs) | Diff refs for this design. |
| <a id="designfieldsevent"></a>`event` | [`DesignVersionEvent!`](#designversionevent) | How this design was changed in the current version. |
-| <a id="designfieldsfilename"></a>`filename` | [`String!`](#string) | The filename of the design. |
-| <a id="designfieldsfullpath"></a>`fullPath` | [`String!`](#string) | The full path to the design file. |
-| <a id="designfieldsid"></a>`id` | [`ID!`](#id) | The ID of this design. |
-| <a id="designfieldsimage"></a>`image` | [`String!`](#string) | The URL of the full-sized image. |
+| <a id="designfieldsfilename"></a>`filename` | [`String!`](#string) | Filename of the design. |
+| <a id="designfieldsfullpath"></a>`fullPath` | [`String!`](#string) | Full path to the design file. |
+| <a id="designfieldsid"></a>`id` | [`ID!`](#id) | ID of this design. |
+| <a id="designfieldsimage"></a>`image` | [`String!`](#string) | URL of the full-sized image. |
| <a id="designfieldsimagev432x230"></a>`imageV432x230` | [`String`](#string) | The URL of the design resized to fit within the bounds of 432x230. This will be `null` if the image has not been generated. |
-| <a id="designfieldsissue"></a>`issue` | [`Issue!`](#issue) | The issue the design belongs to. |
-| <a id="designfieldsnotescount"></a>`notesCount` | [`Int!`](#int) | The total count of user-created notes for this design. |
-| <a id="designfieldsproject"></a>`project` | [`Project!`](#project) | The project the design belongs to. |
+| <a id="designfieldsissue"></a>`issue` | [`Issue!`](#issue) | Issue the design belongs to. |
+| <a id="designfieldsnotescount"></a>`notesCount` | [`Int!`](#int) | Total count of user-created notes for this design. |
+| <a id="designfieldsproject"></a>`project` | [`Project!`](#project) | Project the design belongs to. |
#### `Entry`
@@ -16655,7 +17328,7 @@ Implementations:
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="eventableevents"></a>`events` | [`EventConnection`](#eventconnection) | A list of events associated with the object. (see [Connections](#connections)) |
+| <a id="eventableevents"></a>`events` | [`EventConnection`](#eventconnection) | List of events associated with the object. (see [Connections](#connections)) |
#### `MemberInterface`
@@ -16776,7 +17449,7 @@ Implementations:
| <a id="usergroupcount"></a>`groupCount` | [`Int`](#int) | Group count for the user. |
| <a id="usergroupmemberships"></a>`groupMemberships` | [`GroupMemberConnection`](#groupmemberconnection) | Group memberships of the user. (see [Connections](#connections)) |
| <a id="userid"></a>`id` | [`ID!`](#id) | ID of the user. |
-| <a id="userlocation"></a>`location` | [`String`](#string) | The location of the user. |
+| <a id="userlocation"></a>`location` | [`String`](#string) | Location of the user. |
| <a id="username"></a>`name` | [`String!`](#string) | Human-readable name of the user. |
| <a id="usernamespace"></a>`namespace` | [`Namespace`](#namespace) | Personal namespace of the user. |
| <a id="userprojectmemberships"></a>`projectMemberships` | [`ProjectMemberConnection`](#projectmemberconnection) | Project memberships of the user. (see [Connections](#connections)) |
@@ -16816,7 +17489,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="userassignedmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
| <a id="userassignedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. |
| <a id="userassignedmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. |
-| <a id="userassignedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | A merge request state. If provided, all resolved merge requests will have this state. |
+| <a id="userassignedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. |
| <a id="userassignedmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. |
###### `User.authoredMergeRequests`
@@ -16845,9 +17518,26 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="userauthoredmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
| <a id="userauthoredmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. |
| <a id="userauthoredmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. |
-| <a id="userauthoredmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | A merge request state. If provided, all resolved merge requests will have this state. |
+| <a id="userauthoredmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. |
| <a id="userauthoredmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. |
+###### `User.groups`
+
+Groups where the user has access. Will always return `null` if `paginatable_namespace_drop_down_for_project_creation` feature flag is disabled.
+
+Returns [`GroupConnection`](#groupconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+####### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="usergroupspermissionscope"></a>`permissionScope` | [`GroupPermission`](#grouppermission) | Filter by permissions the user has on groups. |
+| <a id="usergroupssearch"></a>`search` | [`String`](#string) | Search by group name or path. |
+
###### `User.reviewRequestedMergeRequests`
Merge requests assigned to the user for review.
@@ -16874,7 +17564,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="userreviewrequestedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
| <a id="userreviewrequestedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. |
| <a id="userreviewrequestedmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. |
-| <a id="userreviewrequestedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | A merge request state. If provided, all resolved merge requests will have this state. |
+| <a id="userreviewrequestedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. |
| <a id="userreviewrequestedmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. |
###### `User.snippets`
@@ -16892,7 +17582,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="usersnippetsids"></a>`ids` | [`[SnippetID!]`](#snippetid) | Array of global snippet IDs. For example, `gid://gitlab/ProjectSnippet/1`. |
-| <a id="usersnippetstype"></a>`type` | [`TypeEnum`](#typeenum) | The type of snippet. |
+| <a id="usersnippetstype"></a>`type` | [`TypeEnum`](#typeenum) | Type of snippet. |
| <a id="usersnippetsvisibility"></a>`visibility` | [`VisibilityScopesEnum`](#visibilityscopesenum) | Visibility of the snippet. |
###### `User.starredProjects`
@@ -16947,12 +17637,12 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="usertodosaction"></a>`action` | [`[TodoActionEnum!]`](#todoactionenum) | The action to be filtered. |
-| <a id="usertodosauthorid"></a>`authorId` | [`[ID!]`](#id) | The ID of an author. |
-| <a id="usertodosgroupid"></a>`groupId` | [`[ID!]`](#id) | The ID of a group. |
-| <a id="usertodosprojectid"></a>`projectId` | [`[ID!]`](#id) | The ID of a project. |
-| <a id="usertodosstate"></a>`state` | [`[TodoStateEnum!]`](#todostateenum) | The state of the todo. |
-| <a id="usertodostype"></a>`type` | [`[TodoTargetEnum!]`](#todotargetenum) | The type of the todo. |
+| <a id="usertodosaction"></a>`action` | [`[TodoActionEnum!]`](#todoactionenum) | Action to be filtered. |
+| <a id="usertodosauthorid"></a>`authorId` | [`[ID!]`](#id) | ID of an author. |
+| <a id="usertodosgroupid"></a>`groupId` | [`[ID!]`](#id) | ID of a group. |
+| <a id="usertodosprojectid"></a>`projectId` | [`[ID!]`](#id) | ID of a project. |
+| <a id="usertodosstate"></a>`state` | [`[TodoStateEnum!]`](#todostateenum) | State of the todo. |
+| <a id="usertodostype"></a>`type` | [`[TodoTargetEnum!]`](#todotargetenum) | Type of the todo. |
## Input types
@@ -16970,7 +17660,7 @@ Field that are available while modifying the custom mapping attributes for an HT
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="alertmanagementpayloadalertfieldinputfieldname"></a>`fieldName` | [`AlertManagementPayloadAlertFieldName!`](#alertmanagementpayloadalertfieldname) | A GitLab alert field name. |
+| <a id="alertmanagementpayloadalertfieldinputfieldname"></a>`fieldName` | [`AlertManagementPayloadAlertFieldName!`](#alertmanagementpayloadalertfieldname) | GitLab alert field name. |
| <a id="alertmanagementpayloadalertfieldinputlabel"></a>`label` | [`String`](#string) | Human-readable label of the payload path. |
| <a id="alertmanagementpayloadalertfieldinputpath"></a>`path` | [`[PayloadAlertFieldPathSegment!]!`](#payloadalertfieldpathsegment) | Path to value inside payload JSON. |
| <a id="alertmanagementpayloadalertfieldinputtype"></a>`type` | [`AlertManagementPayloadAlertFieldType!`](#alertmanagementpayloadalertfieldtype) | Type of the parsed value. |
@@ -16992,7 +17682,8 @@ Field that are available while modifying the custom mapping attributes for an HT
| <a id="boardissueinputiterationwildcardid"></a>`iterationWildcardId` | [`IterationWildcardId`](#iterationwildcardid) | Filter by iteration ID wildcard. |
| <a id="boardissueinputlabelname"></a>`labelName` | [`[String]`](#string) | Filter by label name. |
| <a id="boardissueinputmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter by milestone title. |
-| <a id="boardissueinputmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. |
+| <a id="boardissueinputmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter by milestone ID wildcard. |
+| <a id="boardissueinputmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. Wildcard values "NONE" and "ANY" are supported. |
| <a id="boardissueinputnot"></a>`not` | [`NegatedBoardIssueInput`](#negatedboardissueinput) | List of negated arguments. |
| <a id="boardissueinputreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
| <a id="boardissueinputsearch"></a>`search` | [`String`](#string) | Search query for issue title or description. |
@@ -17006,7 +17697,7 @@ Field that are available while modifying the custom mapping attributes for an HT
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="commitactionaction"></a>`action` | [`CommitActionMode!`](#commitactionmode) | The action to perform, create, delete, move, update, chmod. |
+| <a id="commitactionaction"></a>`action` | [`CommitActionMode!`](#commitactionmode) | Action to perform: create, delete, move, update, or chmod. |
| <a id="commitactioncontent"></a>`content` | [`String`](#string) | Content of the file. |
| <a id="commitactionencoding"></a>`encoding` | [`CommitEncoding`](#commitencoding) | Encoding of the file. Default is text. |
| <a id="commitactionexecutefilemode"></a>`executeFilemode` | [`Boolean`](#boolean) | Enables/disables the execute flag on the file. |
@@ -17025,6 +17716,30 @@ Field that are available while modifying the custom mapping attributes for an HT
| <a id="complianceframeworkinputname"></a>`name` | [`String`](#string) | New name for the compliance framework. |
| <a id="complianceframeworkinputpipelineconfigurationfullpath"></a>`pipelineConfigurationFullPath` | [`String`](#string) | Full path of the compliance pipeline configuration stored in a project repository, such as `.gitlab/.compliance-gitlab-ci.yml@compliance/hipaa` **(ULTIMATE)**. |
+### `DastProfileCadenceInput`
+
+Represents DAST Profile Cadence.
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="dastprofilecadenceinputduration"></a>`duration` | [`Int`](#int) | Duration of the DAST Profile Cadence. |
+| <a id="dastprofilecadenceinputunit"></a>`unit` | [`DastProfileCadenceUnit`](#dastprofilecadenceunit) | Unit for the duration of DAST Profile Cadence. |
+
+### `DastProfileScheduleInput`
+
+Input type for DAST Profile Schedules.
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="dastprofilescheduleinputactive"></a>`active` | [`Boolean`](#boolean) | Status of a Dast Profile Schedule. |
+| <a id="dastprofilescheduleinputcadence"></a>`cadence` | [`DastProfileCadenceInput`](#dastprofilecadenceinput) | Cadence of a Dast Profile Schedule. |
+| <a id="dastprofilescheduleinputstartsat"></a>`startsAt` | [`Time`](#time) | Start time of a Dast Profile Schedule. |
+| <a id="dastprofilescheduleinputtimezone"></a>`timezone` | [`String`](#string) | Time Zone for the Start time of a Dast Profile Schedule. |
+
### `DastSiteProfileAuthInput`
Input type for DastSiteProfile authentication.
@@ -17034,11 +17749,11 @@ Input type for DastSiteProfile authentication.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="dastsiteprofileauthinputenabled"></a>`enabled` | [`Boolean`](#boolean) | Indicates whether authentication is enabled. |
-| <a id="dastsiteprofileauthinputpassword"></a>`password` | [`String`](#string) | The password to authenticate with on the target website. |
-| <a id="dastsiteprofileauthinputpasswordfield"></a>`passwordField` | [`String`](#string) | The name of password field at the sign-in HTML form. |
+| <a id="dastsiteprofileauthinputpassword"></a>`password` | [`String`](#string) | Password to authenticate with on the target website. |
+| <a id="dastsiteprofileauthinputpasswordfield"></a>`passwordField` | [`String`](#string) | Name of password field at the sign-in HTML form. |
| <a id="dastsiteprofileauthinputurl"></a>`url` | [`String`](#string) | The URL of the page containing the sign-in HTML form on the target website. |
-| <a id="dastsiteprofileauthinputusername"></a>`username` | [`String`](#string) | The username to authenticate with on the target website. |
-| <a id="dastsiteprofileauthinputusernamefield"></a>`usernameField` | [`String`](#string) | The name of username field at the sign-in HTML form. |
+| <a id="dastsiteprofileauthinputusername"></a>`username` | [`String`](#string) | Username to authenticate with on the target website. |
+| <a id="dastsiteprofileauthinputusernamefield"></a>`usernameField` | [`String`](#string) | Name of username field at the sign-in HTML form. |
### `DiffImagePositionInput`
@@ -17061,8 +17776,8 @@ Input type for DastSiteProfile authentication.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="diffpathsinputnewpath"></a>`newPath` | [`String`](#string) | The path of the file on the head sha. |
-| <a id="diffpathsinputoldpath"></a>`oldPath` | [`String`](#string) | The path of the file on the start sha. |
+| <a id="diffpathsinputnewpath"></a>`newPath` | [`String`](#string) | Path of the file on the HEAD SHA. |
+| <a id="diffpathsinputoldpath"></a>`oldPath` | [`String`](#string) | Path of the file on the start SHA. |
### `DiffPositionInput`
@@ -17085,7 +17800,7 @@ Input type for DastSiteProfile authentication.
| ---- | ---- | ----------- |
| <a id="epicfiltersauthorusername"></a>`authorUsername` | [`String`](#string) | Filter by author username. |
| <a id="epicfilterslabelname"></a>`labelName` | [`[String]`](#string) | Filter by label name. |
-| <a id="epicfiltersmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. |
+| <a id="epicfiltersmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. Wildcard values "NONE" and "ANY" are supported. |
| <a id="epicfiltersnot"></a>`not` | [`NegatedEpicBoardIssueInput`](#negatedepicboardissueinput) | Negated epic arguments. |
| <a id="epicfilterssearch"></a>`search` | [`String`](#string) | Search query for epic title or description. |
@@ -17097,10 +17812,10 @@ A node of an epic tree.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="epictreenodefieldsinputtypeadjacentreferenceid"></a>`adjacentReferenceId` | [`EpicTreeSortingID`](#epictreesortingid) | The ID of the epic_issue or issue that the actual epic or issue is switched with. |
-| <a id="epictreenodefieldsinputtypeid"></a>`id` | [`EpicTreeSortingID!`](#epictreesortingid) | The ID of the epic_issue or epic that is being moved. |
+| <a id="epictreenodefieldsinputtypeadjacentreferenceid"></a>`adjacentReferenceId` | [`EpicTreeSortingID`](#epictreesortingid) | ID of the epic issue or issue the epic or issue is switched with. |
+| <a id="epictreenodefieldsinputtypeid"></a>`id` | [`EpicTreeSortingID!`](#epictreesortingid) | ID of the epic issue or epic that is being moved. |
| <a id="epictreenodefieldsinputtypenewparentid"></a>`newParentId` | [`EpicID`](#epicid) | ID of the new parent epic. |
-| <a id="epictreenodefieldsinputtyperelativeposition"></a>`relativePosition` | [`MoveType`](#movetype) | The type of the switch, after or before allowed. |
+| <a id="epictreenodefieldsinputtyperelativeposition"></a>`relativePosition` | [`MoveType`](#movetype) | Type of switch. Valid values are `after` or `before`. |
### `EscalationRuleInput`
@@ -17110,10 +17825,10 @@ Represents an escalation rule.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="escalationruleinputelapsedtimeseconds"></a>`elapsedTimeSeconds` | [`Int!`](#int) | The time in seconds before the rule is activated. |
-| <a id="escalationruleinputoncallscheduleiid"></a>`oncallScheduleIid` | [`ID`](#id) | The on-call schedule to notify. |
-| <a id="escalationruleinputstatus"></a>`status` | [`EscalationRuleStatus!`](#escalationrulestatus) | The status required to prevent the rule from activating. |
-| <a id="escalationruleinputusername"></a>`username` | [`String`](#string) | The username of the user to notify. |
+| <a id="escalationruleinputelapsedtimeseconds"></a>`elapsedTimeSeconds` | [`Int!`](#int) | Time in seconds before the rule is activated. |
+| <a id="escalationruleinputoncallscheduleiid"></a>`oncallScheduleIid` | [`ID`](#id) | On-call schedule to notify. |
+| <a id="escalationruleinputstatus"></a>`status` | [`EscalationRuleStatus!`](#escalationrulestatus) | Status required to prevent the rule from activating. |
+| <a id="escalationruleinputusername"></a>`username` | [`String`](#string) | Username of the user to notify. |
### `JiraUsersMappingInputType`
@@ -17148,7 +17863,8 @@ Represents an escalation rule.
| <a id="negatedboardissueinputiterationwildcardid"></a>`iterationWildcardId` | [`NegatedIterationWildcardId`](#negatediterationwildcardid) | Filter by iteration ID wildcard. |
| <a id="negatedboardissueinputlabelname"></a>`labelName` | [`[String]`](#string) | Filter by label name. |
| <a id="negatedboardissueinputmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter by milestone title. |
-| <a id="negatedboardissueinputmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. |
+| <a id="negatedboardissueinputmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter by milestone ID wildcard. |
+| <a id="negatedboardissueinputmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. Wildcard values "NONE" and "ANY" are supported. |
| <a id="negatedboardissueinputreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
| <a id="negatedboardissueinputtypes"></a>`types` | [`[IssueType!]`](#issuetype) | Filter by the given issue types. |
| <a id="negatedboardissueinputweight"></a>`weight` | [`String`](#string) | Filter by weight. |
@@ -17161,7 +17877,7 @@ Represents an escalation rule.
| ---- | ---- | ----------- |
| <a id="negatedepicboardissueinputauthorusername"></a>`authorUsername` | [`String`](#string) | Filter by author username. |
| <a id="negatedepicboardissueinputlabelname"></a>`labelName` | [`[String]`](#string) | Filter by label name. |
-| <a id="negatedepicboardissueinputmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. |
+| <a id="negatedepicboardissueinputmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. Wildcard values "NONE" and "ANY" are supported. |
### `NegatedEpicFilterInput`
@@ -17181,6 +17897,7 @@ Represents an escalation rule.
| ---- | ---- | ----------- |
| <a id="negatedissuefilterinputassigneeid"></a>`assigneeId` | [`String`](#string) | ID of a user not assigned to the issues. |
| <a id="negatedissuefilterinputassigneeusernames"></a>`assigneeUsernames` | [`[String!]`](#string) | Usernames of users not assigned to the issue. |
+| <a id="negatedissuefilterinputauthorusername"></a>`authorUsername` | [`String`](#string) | Username of a user who didn't author the issue. |
| <a id="negatedissuefilterinputepicid"></a>`epicId` | [`String`](#string) | ID of an epic not associated with the issues. |
| <a id="negatedissuefilterinputiids"></a>`iids` | [`[String!]`](#string) | List of IIDs of issues to exclude. For example, `[1, 2]`. |
| <a id="negatedissuefilterinputiterationid"></a>`iterationId` | [`[ID!]`](#id) | List of iteration Global IDs not applied to the issue. |
@@ -17188,6 +17905,7 @@ Represents an escalation rule.
| <a id="negatedissuefilterinputlabelname"></a>`labelName` | [`[String!]`](#string) | Labels not applied to this issue. |
| <a id="negatedissuefilterinputmilestonetitle"></a>`milestoneTitle` | [`[String!]`](#string) | Milestone not applied to this issue. |
| <a id="negatedissuefilterinputmilestonewildcardid"></a>`milestoneWildcardId` | [`NegatedMilestoneWildcardId`](#negatedmilestonewildcardid) | Filter by negated milestone wildcard values. |
+| <a id="negatedissuefilterinputmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. |
| <a id="negatedissuefilterinputweight"></a>`weight` | [`String`](#string) | Weight not applied to the issue. |
### `OncallRotationActivePeriodInputType`
@@ -17198,8 +17916,8 @@ Active period time range for on-call rotation.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="oncallrotationactiveperiodinputtypeendtime"></a>`endTime` | [`String!`](#string) | The end of the rotation active period in 24 hour format, for example "18:30". |
-| <a id="oncallrotationactiveperiodinputtypestarttime"></a>`startTime` | [`String!`](#string) | The start of the rotation active period in 24 hour format, for example "18:30". |
+| <a id="oncallrotationactiveperiodinputtypeendtime"></a>`endTime` | [`String!`](#string) | End of the rotation active period in 24 hour format. For example, "18:30". |
+| <a id="oncallrotationactiveperiodinputtypestarttime"></a>`startTime` | [`String!`](#string) | Start of the rotation active period in 24 hour format. For example, "18:30". |
### `OncallRotationDateInputType`
@@ -17209,8 +17927,8 @@ Date input type for on-call rotation.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="oncallrotationdateinputtypedate"></a>`date` | [`String!`](#string) | The date component of the date in YYYY-MM-DD format. |
-| <a id="oncallrotationdateinputtypetime"></a>`time` | [`String!`](#string) | The time component of the date in 24hr HH:MM format. |
+| <a id="oncallrotationdateinputtypedate"></a>`date` | [`String!`](#string) | Date component of the date in YYYY-MM-DD format. |
+| <a id="oncallrotationdateinputtypetime"></a>`time` | [`String!`](#string) | Time component of the date in 24hr HH:MM format. |
### `OncallRotationLengthInputType`
@@ -17220,8 +17938,8 @@ The rotation length of the on-call rotation.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="oncallrotationlengthinputtypelength"></a>`length` | [`Int!`](#int) | The rotation length of the on-call rotation. |
-| <a id="oncallrotationlengthinputtypeunit"></a>`unit` | [`OncallRotationUnitEnum!`](#oncallrotationunitenum) | The unit of the rotation length of the on-call rotation. |
+| <a id="oncallrotationlengthinputtypelength"></a>`length` | [`Int!`](#int) | Rotation length of the on-call rotation. |
+| <a id="oncallrotationlengthinputtypeunit"></a>`unit` | [`OncallRotationUnitEnum!`](#oncallrotationunitenum) | Unit of the rotation length of the on-call rotation. |
### `OncallUserInputType`
@@ -17231,9 +17949,9 @@ The rotation user and color palette.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="oncalluserinputtypecolorpalette"></a>`colorPalette` | [`DataVisualizationColorEnum`](#datavisualizationcolorenum) | A value of DataVisualizationColorEnum. The color from the palette to assign to the on-call user. |
-| <a id="oncalluserinputtypecolorweight"></a>`colorWeight` | [`DataVisualizationWeightEnum`](#datavisualizationweightenum) | A value of DataVisualizationWeightEnum. The color weight to assign to for the on-call user. Note: To view on-call schedules in GitLab, do not provide a value below 500. A value between 500 and 950 ensures sufficient contrast. |
-| <a id="oncalluserinputtypeusername"></a>`username` | [`String!`](#string) | The username of the user to participate in the on-call rotation, such as `user_one`. |
+| <a id="oncalluserinputtypecolorpalette"></a>`colorPalette` | [`DataVisualizationColorEnum`](#datavisualizationcolorenum) | Value of DataVisualizationColorEnum. The color from the palette to assign to the on-call user. |
+| <a id="oncalluserinputtypecolorweight"></a>`colorWeight` | [`DataVisualizationWeightEnum`](#datavisualizationweightenum) | Color weight to assign to for the on-call user. To view on-call schedules in GitLab, do not provide a value below 500. A value between 500 and 950 ensures sufficient contrast. |
+| <a id="oncalluserinputtypeusername"></a>`username` | [`String!`](#string) | Username of the user to participate in the on-call rotation. For example, `"user_one"`. |
### `ReleaseAssetLinkInput`
@@ -17244,7 +17962,7 @@ Fields that are available when modifying a release asset link.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="releaseassetlinkinputdirectassetpath"></a>`directAssetPath` | [`String`](#string) | Relative path for a direct asset link. |
-| <a id="releaseassetlinkinputlinktype"></a>`linkType` | [`ReleaseAssetLinkType`](#releaseassetlinktype) | The type of the asset link. |
+| <a id="releaseassetlinkinputlinktype"></a>`linkType` | [`ReleaseAssetLinkType`](#releaseassetlinktype) | Type of the asset link. |
| <a id="releaseassetlinkinputname"></a>`name` | [`String!`](#string) | Name of the asset link. |
| <a id="releaseassetlinkinputurl"></a>`url` | [`String!`](#string) | URL of the asset link. |
@@ -17256,7 +17974,7 @@ Fields that are available when modifying release assets.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="releaseassetsinputlinks"></a>`links` | [`[ReleaseAssetLinkInput!]`](#releaseassetlinkinput) | A list of asset links to associate to the release. |
+| <a id="releaseassetsinputlinks"></a>`links` | [`[ReleaseAssetLinkInput!]`](#releaseassetlinkinput) | List of asset links to associate to the release. |
### `SastCiConfigurationAnalyzersEntityInput`
@@ -17315,8 +18033,8 @@ A time-frame defined as a closed inclusive range of two dates.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="timeframeend"></a>`end` | [`Date!`](#date) | The end of the range. |
-| <a id="timeframestart"></a>`start` | [`Date!`](#date) | The start of the range. |
+| <a id="timeframeend"></a>`end` | [`Date!`](#date) | End of the range. |
+| <a id="timeframestart"></a>`start` | [`Date!`](#date) | Start of the range. |
### `UpdateDiffImagePositionInput`
@@ -17328,3 +18046,14 @@ A time-frame defined as a closed inclusive range of two dates.
| <a id="updatediffimagepositioninputwidth"></a>`width` | [`Int`](#int) | Total width of the image. |
| <a id="updatediffimagepositioninputx"></a>`x` | [`Int`](#int) | X position of the note. |
| <a id="updatediffimagepositioninputy"></a>`y` | [`Int`](#int) | Y position of the note. |
+
+### `VulnerabilityIdentifierInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="vulnerabilityidentifierinputexternalid"></a>`externalId` | [`String`](#string) | External ID of the vulnerability identifier. |
+| <a id="vulnerabilityidentifierinputexternaltype"></a>`externalType` | [`String`](#string) | External type of the vulnerability identifier. |
+| <a id="vulnerabilityidentifierinputname"></a>`name` | [`String!`](#string) | Name of the vulnerability identifier. |
+| <a id="vulnerabilityidentifierinputurl"></a>`url` | [`String!`](#string) | URL of the vulnerability identifier. |
diff --git a/doc/api/graphql/removed_items.md b/doc/api/graphql/removed_items.md
index 1c425d5f1d5..0048148ab11 100644
--- a/doc/api/graphql/removed_items.md
+++ b/doc/api/graphql/removed_items.md
@@ -12,7 +12,7 @@ According to our [process for removing items](index.md#deprecation-and-removal-p
## GitLab 14.0
-Fields removed in [GitLab 14.0](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63293):
+Fields [removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63293) in GitLab 14.0:
### GraphQL Mutations
@@ -38,7 +38,7 @@ Fields removed in [GitLab 14.0](https://gitlab.com/gitlab-org/gitlab/-/merge_req
## GitLab 13.6
-Fields removed in [GitLab 13.6](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44866):
+Fields [removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44866) in GitLab 13.6:
| Field name | GraphQL type | Deprecated in | Use instead |
|----------------------|--------------------------|---------------|----------------------------|
diff --git a/doc/api/graphql/users_example.md b/doc/api/graphql/users_example.md
index 8fbfb67d166..0658a9402e7 100644
--- a/doc/api/graphql/users_example.md
+++ b/doc/api/graphql/users_example.md
@@ -4,7 +4,7 @@ group: Integrations
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
---
-# Query users with GraphQL
+# Query users with GraphQL **(FREE)**
This page describes how you can use the GraphiQL explorer to query users.
diff --git a/doc/api/group_activity_analytics.md b/doc/api/group_activity_analytics.md
index 003c96b65fa..9206b0a1bd6 100644
--- a/doc/api/group_activity_analytics.md
+++ b/doc/api/group_activity_analytics.md
@@ -4,7 +4,7 @@ group: Optimize
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
---
-# Group Activity Analytics API
+# Group Activity Analytics API **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26460) in GitLab 12.9.
diff --git a/doc/api/group_badges.md b/doc/api/group_badges.md
index 463507bf583..1e830237b50 100644
--- a/doc/api/group_badges.md
+++ b/doc/api/group_badges.md
@@ -4,7 +4,7 @@ group: Access
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
---
-# Group badges API
+# Group badges API **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17082) in GitLab 10.6.
diff --git a/doc/api/group_boards.md b/doc/api/group_boards.md
index eaa7b57e520..6178a3fdc04 100644
--- a/doc/api/group_boards.md
+++ b/doc/api/group_boards.md
@@ -76,7 +76,7 @@ Example response:
]
```
-Users on GitLab [Premium or higher](https://about.gitlab.com/pricing/) see
+Users on [GitLab Premium or higher](https://about.gitlab.com/pricing/) see
different parameters, due to the ability to have multiple group boards.
Example response:
@@ -192,7 +192,7 @@ Example response:
}
```
-Users on GitLab [Premium or higher](https://about.gitlab.com/pricing/) see
+Users on [GitLab Premium or higher](https://about.gitlab.com/pricing/) see
different parameters, due to the ability to have multiple group issue boards.
Example response:
@@ -244,7 +244,7 @@ Example response:
## Create a group issue board **(PREMIUM)**
-Creates a Group Issue Board.
+Creates a group issue board.
```plaintext
POST /groups/:id/boards
@@ -283,7 +283,7 @@ Example response:
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/5954) in GitLab 11.1.
-Updates a Group Issue Board.
+Updates a group issue board.
```plaintext
PUT /groups/:id/boards/:board_id
@@ -351,7 +351,7 @@ Example response:
## Delete a group issue board **(PREMIUM)**
-Deletes a Group Issue Board.
+Deletes a group issue board.
```plaintext
DELETE /groups/:id/boards/:board_id
@@ -452,7 +452,7 @@ Example response:
## New group issue board list
-Creates a new Issue Board list.
+Creates an issue board list.
```plaintext
POST /groups/:id/boards/:board_id/lists
@@ -493,7 +493,7 @@ Example response:
## Edit group issue board list
-Updates an existing Issue Board list. This call is used to change list position.
+Updates an existing issue board list. This call is used to change list position.
```plaintext
PUT /groups/:id/boards/:board_id/lists/:list_id
diff --git a/doc/api/group_import_export.md b/doc/api/group_import_export.md
index d2bcac6332a..0a431cfdfbf 100644
--- a/doc/api/group_import_export.md
+++ b/doc/api/group_import_export.md
@@ -4,7 +4,7 @@ group: Import
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
---
-# Group Import/Export API
+# Group Import/Export API **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20353) in GitLab 12.8.
diff --git a/doc/api/group_labels.md b/doc/api/group_labels.md
index 25102e32360..04a619c8fa9 100644
--- a/doc/api/group_labels.md
+++ b/doc/api/group_labels.md
@@ -13,7 +13,7 @@ It allows users to list, create, update, and delete group labels. Furthermore, u
unsubscribe from group labels.
NOTE:
-The `description_html` - was added to response JSON in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413).
+The `description_html` - was [added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) to response JSON in GitLab 12.7.
## List group labels
@@ -26,7 +26,7 @@ GET /groups/:id/labels
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) owned by the authenticated user. |
-| `with_counts` | boolean | no | Whether or not to include issue and merge request counts. Defaults to `false`. _([Introduced in GitLab 12.2](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/31543))_ |
+| `with_counts` | boolean | no | Whether or not to include issue and merge request counts. Defaults to `false`. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/31543) in GitLab 12.2)_ |
| `include_ancestor_groups` | boolean | no | Include ancestor groups. Defaults to `true`. |
| `include_descendant_groups` | boolean | no | Include descendant groups. Defaults to `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/259024) in GitLab 13.6 |
| `only_group_labels` | boolean | no | Toggle to include only group labels or also project labels. Defaults to `true`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/259024) in GitLab 13.6 |
diff --git a/doc/api/group_level_variables.md b/doc/api/group_level_variables.md
index f816f2dc173..7c51de47bc7 100644
--- a/doc/api/group_level_variables.md
+++ b/doc/api/group_level_variables.md
@@ -4,7 +4,7 @@ group: Pipeline Authoring
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
---
-# Group-level Variables API
+# Group-level Variables API **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/34519) in GitLab 9.5
diff --git a/doc/api/group_milestones.md b/doc/api/group_milestones.md
index d7de3272005..8b9c09ef1a0 100644
--- a/doc/api/group_milestones.md
+++ b/doc/api/group_milestones.md
@@ -32,7 +32,7 @@ Parameters:
| `state` | string | no | Return only `active` or `closed` milestones |
| `title` | string | no | Return only the milestones having the given `title` |
| `search` | string | no | Return only milestones with a title or description matching the provided string |
-| `include_parent_milestones` | boolean | optional | Include milestones from parent group and its ancestors. Introduced in [GitLab 13.4](https://gitlab.com/gitlab-org/gitlab/-/issues/196066) |
+| `include_parent_milestones` | boolean | optional | Include milestones from parent group and its ancestors. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196066) in GitLab 13.4 |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/milestones"
diff --git a/doc/api/group_protected_environments.md b/doc/api/group_protected_environments.md
index ddd9ca891d8..0e1cd149c51 100644
--- a/doc/api/group_protected_environments.md
+++ b/doc/api/group_protected_environments.md
@@ -7,17 +7,11 @@ type: concepts, howto
# Group-level protected environments API **(PREMIUM)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/215888) in [GitLab Premium](https://about.gitlab.com/pricing/) 14.0.
-> - [Deployed behind a feature flag](../user/feature_flags.md), disabled by default.
-> - Disabled on GitLab.com.
-> - Not recommended for production use.
-> - To use in GitLab self-managed instances, ask a GitLab administrator to [enable it](../ci/environments/protected_environments.md#enable-or-disable-group-level-protected-environments). **(FREE SELF)**
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/215888) in GitLab 14.0. [Deployed behind the `group_level_protected_environments` flag](../administration/feature_flags.md), disabled by default.
+> - [Feature flag `group_level_protected_environments`](https://gitlab.com/gitlab-org/gitlab/-/issues/331085) removed in GitLab 14.3.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/331085) in GitLab 14.3.
-This in-development feature might not be available for your use. There can be
-[risks when enabling features still in development](../administration/feature_flags.md#risks-when-enabling-features-still-in-development).
-Refer to this feature's version history for more details.
-
-Read more about [group-level protected environments](../ci/environments/protected_environments.md#group-level-protected-environments),
+Read more about [group-level protected environments](../ci/environments/protected_environments.md#group-level-protected-environments).
## Valid access levels
diff --git a/doc/api/group_relations_export.md b/doc/api/group_relations_export.md
index 2f9c1e381df..4dbf0f6d54c 100644
--- a/doc/api/group_relations_export.md
+++ b/doc/api/group_relations_export.md
@@ -4,7 +4,7 @@ group: Import
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
---
-# Group Relations Export API
+# Group Relations Export API **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59978) in GitLab 13.12.
diff --git a/doc/api/group_wikis.md b/doc/api/group_wikis.md
index e1470a2cdd7..17337934a92 100644
--- a/doc/api/group_wikis.md
+++ b/doc/api/group_wikis.md
@@ -7,7 +7,7 @@ type: reference, api
# Group wikis API **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/212199) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/212199) in GitLab 13.5.
The [group wikis](../user/project/wiki/index.md#group-wikis) API is available only in APIv4.
An API for [project wikis](wikis.md) is also available.
diff --git a/doc/api/groups.md b/doc/api/groups.md
index 3831aef10c9..bd4c7de567c 100644
--- a/doc/api/groups.md
+++ b/doc/api/groups.md
@@ -4,7 +4,7 @@ group: Access
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
---
-# Groups API
+# Groups API **(FREE)**
## List groups
@@ -13,6 +13,11 @@ authentication, only public groups are returned.
By default, this request returns 20 results at a time because the API results [are paginated](index.md#pagination).
+When accessed without authentication, this endpoint also supports [keyset pagination](index.md#keyset-based-pagination):
+
+- When requesting consecutive pages of results, we recommend you use keyset pagination.
+- Beyond a specific offset limit (specified by [max offset allowed by the REST API for offset-based pagination](../administration/instance_limits.md#max-offset-allowed-by-the-rest-api-for-offset-based-pagination)), offset pagination is unavailable.
+
Parameters:
| Attribute | Type | Required | Description |
@@ -764,6 +769,10 @@ For GitLab 14.0 and later, the [limit cannot be disabled](https://gitlab.com/git
## New group
+NOTE:
+On GitLab SaaS, you must use the GitLab UI to create groups without a parent group. You cannot
+use the API to do this.
+
Creates a new project group. Available only for users who can create groups.
```plaintext
@@ -795,10 +804,6 @@ Parameters:
| `shared_runners_minutes_limit` | integer | no | **(PREMIUM SELF)** Pipeline minutes quota for this group (included in plan). Can be `nil` (default; inherit system default), `0` (unlimited) or `> 0` |
| `extra_shared_runners_minutes_limit` | integer | no | **(PREMIUM SELF)** Extra pipeline minutes quota for this group (purchased in addition to the minutes included in the plan). |
-NOTE:
-On GitLab SaaS, you must use the GitLab UI to create groups without a parent group. You cannot
-use the API to do this.
-
### Options for `default_branch_protection`
The `default_branch_protection` attribute determines whether developers and maintainers can push to the applicable [default branch](../user/project/repository/branches/default.md), as described in the following table:
@@ -1338,7 +1343,7 @@ DELETE /groups/:id/share/:group_id
## Push Rules **(PREMIUM)**
-> Introduced in [GitLab](https://about.gitlab.com/pricing/) 13.4.
+> Introduced in GitLab 13.4.
### Get group push rules **(PREMIUM)**
@@ -1370,7 +1375,7 @@ GET /groups/:id/push_rule
}
```
-Users on GitLab [Premium or higher](https://about.gitlab.com/pricing/) also see
+Users on [GitLab Premium or higher](https://about.gitlab.com/pricing/) also see
the `commit_committer_check` and `reject_unsigned_commits` parameters:
```json
diff --git a/doc/api/index.md b/doc/api/index.md
index 12d01828803..7b599b6ae0a 100644
--- a/doc/api/index.md
+++ b/doc/api/index.md
@@ -125,7 +125,7 @@ There are several ways you can authenticate with the GitLab API:
- [Personal access tokens](../user/profile/personal_access_tokens.md)
- [Project access tokens](../user/project/settings/project_access_tokens.md)
- [Session cookie](#session-cookie)
-- [GitLab CI/CD job token](#gitlab-cicd-job-token) **(Specific endpoints only)**
+- [GitLab CI/CD job token](../ci/jobs/ci_job_token.md) **(Specific endpoints only)**
Project access tokens are supported by:
@@ -208,118 +208,6 @@ The primary user of this authentication method is the web frontend of GitLab
itself. The web frontend can use the API as the authenticated user to get a
list of projects without explicitly passing an access token.
-### GitLab CI/CD job token
-
-When a pipeline job is about to run, GitLab generates a unique token and injects it as the
-[`CI_JOB_TOKEN` predefined variable](../ci/variables/predefined_variables.md).
-
-You can use a GitLab CI/CD job token to authenticate with specific API endpoints:
-
-- Packages:
- - [Package Registry](../user/packages/package_registry/index.md). To push to the
- Package Registry, you can use [deploy tokens](../user/project/deploy_tokens/index.md).
- - [Container Registry](../user/packages/container_registry/index.md)
- (the `$CI_REGISTRY_PASSWORD` is `$CI_JOB_TOKEN`).
- - [Container Registry API](container_registry.md) (scoped to the job's project, when the `ci_job_token_scope` feature flag is enabled)
-- [Get job artifacts](job_artifacts.md#get-job-artifacts).
-- [Get job token's job](jobs.md#get-job-tokens-job).
-- [Pipeline triggers](pipeline_triggers.md), using the `token=` parameter.
-- [Release creation](releases/index.md#create-a-release).
-- [Terraform plan](../user/infrastructure/index.md).
-
-The token has the same permissions to access the API as the user that triggers the
-pipeline. Therefore, this user must be assigned to [a role that has the required privileges](../user/permissions.md).
-
-The token is valid only while the pipeline job runs. After the job finishes, you can't
-use the token anymore.
-
-A job token can access a project's resources without any configuration, but it might
-give extra permissions that aren't necessary. There is [a proposal](https://gitlab.com/groups/gitlab-org/-/epics/3559)
-to redesign the feature for more strategic control of the access permissions.
-
-#### GitLab CI/CD job token security
-
-To make sure that this token doesn't leak, GitLab:
-
-- Masks the job token in job logs.
-- Grants permissions to the job token only when the job is running.
-
-To make sure that this token doesn't leak, you should also configure
-your [runners](../ci/runners/README.md) to be secure. Avoid:
-
-- Using Docker's `privileged` mode if the machines are re-used.
-- Using the [`shell` executor](https://docs.gitlab.com/runner/executors/shell.html) when jobs
- run on the same machine.
-
-If you have an insecure GitLab Runner configuration, you increase the risk that someone
-tries to steal tokens from other jobs.
-
-#### Limit GitLab CI/CD job token access
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/328553) in GitLab 14.1.
-> - [Deployed behind a feature flag](../user/feature_flags.md), disabled by default.
-> - Disabled on GitLab.com.
-> - Not recommended for production use.
-> - To use in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-ci-job-token-scope-limit). **(FREE SELF)**
-
-This in-development feature might not be available for your use. There can be
-[risks when enabling features still in development](../administration/feature_flags.md#risks-when-enabling-features-still-in-development).
-Refer to this feature's version history for more details.
-
-You can limit the access scope of a project's CI/CD job token to increase the
-job token's security. A job token might give extra permissions that aren't necessary
-to access specific private resources. Limiting the job token access scope reduces the risk of a leaked
-token being used to access private data that the user associated to the job can access.
-
-Control the job token access scope with an allowlist of other projects authorized
-to be accessed by authenticating with the current project's job token. By default
-the token scope only allows access to the same project where the token comes from.
-Other projects can be added and removed by maintainers with access to both projects.
-
-This setting is enabled by default for all new projects, and disabled by default in projects
-created before GitLab 14.1. It is strongly recommended that project maintainers enable this
-setting at all times, and configure the allowlist for cross-project access if needed.
-
-For example, when the setting is enabled, jobs in a pipeline in project `A` have
-a `CI_JOB_TOKEN` scope limited to project `A`. If the job needs to use the token
-to make an API request to a private project `B`, then `B` must be added to the allowlist for `A`.
-If project `B` is public or internal, it doesn't need to be added to the allowlist.
-The job token scope is only for controlling access to private projects.
-
-To enable and configure the job token scope limit:
-
-1. On the top bar, select **Menu > Projects** and find your project.
-1. On the left sidebar, select **Settings > CI/CD**.
-1. Expand **Token Access**.
-1. Toggle **Limit CI_JOB_TOKEN access** to enabled.
-1. (Optional) Add existing projects to the token's access scope. The user adding a
- project must have the [maintainer role](../user/permissions.md) in both projects.
-
-If the job token scope limit is disabled, the token can potentially be used to authenticate
-API requests to all projects accessible to the user that triggered the job.
-
-There is [a proposal](https://gitlab.com/groups/gitlab-org/-/epics/3559) to improve
-the feature with more strategic control of the access permissions.
-
-##### Enable or disable CI job token scope limit **(FREE SELF)**
-
-The GitLab CI/CD job token access scope limit is under development and not ready for production
-use. It is deployed behind a feature flag that is **disabled by default**.
-[GitLab administrators with access to the GitLab Rails console](../administration/feature_flags.md)
-can enable it.
-
-To enable it:
-
-```ruby
-Feature.enable(:ci_scoped_job_token)
-```
-
-To disable it:
-
-```ruby
-Feature.disable(:ci_scoped_job_token)
-```
-
### Impersonation tokens
Impersonation tokens are a type of [personal access token](../user/profile/personal_access_tokens.md).
@@ -574,22 +462,43 @@ The response header includes a link to the next page. For example:
```http
HTTP/1.1 200 OK
...
-Links: <https://gitlab.example.com/api/v4/projects?pagination=keyset&per_page=50&order_by=id&sort=asc&id_after=42>; rel="next"
Link: <https://gitlab.example.com/api/v4/projects?pagination=keyset&per_page=50&order_by=id&sort=asc&id_after=42>; rel="next"
Status: 200 OK
...
```
+The link to the next page contains an additional filter `id_after=42` that
+excludes already-retrieved records.
+
+As another example, the following request lists 50 [groups](groups.md) per page ordered
+by `name` ascending using keyset pagination:
+
+```shell
+curl --request GET --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups?pagination=keyset&per_page=50&order_by=name&sort=asc"
+```
+
+The response header includes a link to the next page:
+
+```http
+HTTP/1.1 200 OK
+...
+Link: <https://gitlab.example.com/api/v4/groups?pagination=keyset&per_page=50&order_by=name&sort=asc&cursor=eyJuYW1lIjoiRmxpZ2h0anMiLCJpZCI6IjI2IiwiX2tkIjoibiJ9>; rel="next"
+Status: 200 OK
+...
+```
+
+The link to the next page contains an additional filter `cursor=eyJuYW1lIjoiRmxpZ2h0anMiLCJpZCI6IjI2IiwiX2tkIjoibiJ9` that
+excludes already-retrieved records.
+
+The type of filter depends on the
+`order_by` option used, and we can have more than one additional filter.
+
WARNING:
-The `Links` header is scheduled to be removed in GitLab 14.0 to be aligned with the
+The `Links` header was removed in GitLab 14.0 to be aligned with the
[W3C `Link` specification](https://www.w3.org/wiki/LinkHeader). The `Link`
header was [added in GitLab 13.1](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33714)
and should be used instead.
-The link to the next page contains an additional filter `id_after=42` that
-excludes already-retrieved records. The type of filter depends on the
-`order_by` option used, and we may have more than one additional filter.
-
When the end of the collection is reached and there are no additional
records to retrieve, the `Link` header is absent and the resulting array is
empty.
@@ -601,9 +510,10 @@ pagination headers.
Keyset-based pagination is supported only for selected resources and ordering
options:
-| Resource | Order |
-|-------------------------|-------|
-| [Projects](projects.md) | `order_by=id` only. |
+| Resource | Options | Availability |
+|:-------------------------|:---------------------------------|:----------------------------------------|
+| [Projects](projects.md) | `order_by=id` only | Authenticated and unauthenticated users |
+| [Groups](groups.md) | `order_by=name`, `sort=asc` only | Unauthenticated users only |
## Path parameters
@@ -675,7 +585,7 @@ send the payload body:
```shell
curl --request POST --header "Content-Type: application/json" \
- --data '{"name":"<example-name>", "description":"<example-description"}' "https://gitlab/api/v4/projects"
+ --data '{"name":"<example-name>", "description":"<example-description>"}' "https://gitlab/api/v4/projects"
```
URL encoded query strings have a length limitation. Requests that are too large
@@ -705,7 +615,7 @@ curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
--form "namespace=email" \
--form "path=impapi" \
---form "file=@/path/to/somefile.txt"
+--form "file=@/path/to/somefile.txt" \
--form "override_params[visibility]=private" \
--form "override_params[some_other_param]=some_value" \
"https://gitlab.example.com/api/v4/projects/import"
@@ -718,7 +628,7 @@ curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
```shell
curl --globoff --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
-"https://gitlab.example.com/api/v4/projects/169/pipeline?ref=master&variables[][key]=VAR1&variables[][value]=hello&variables[][key]=VAR2&variables[][value]=world"
+"https://gitlab.example.com/api/v4/projects/169/pipeline?ref=master&variables[0][key]=VAR1&variables[0][value]=hello&variables[1][key]=VAR2&variables[1][value]=world"
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
--header "Content-Type: application/json" \
diff --git a/doc/api/instance_clusters.md b/doc/api/instance_clusters.md
index ae94fdb137c..4e0ec3bd433 100644
--- a/doc/api/instance_clusters.md
+++ b/doc/api/instance_clusters.md
@@ -4,7 +4,7 @@ group: Configure
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
---
-# Instance clusters API **(FREE)**
+# Instance clusters API **(FREE SELF)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36001) in GitLab 13.2.
diff --git a/doc/api/instance_level_ci_variables.md b/doc/api/instance_level_ci_variables.md
index de6fd958aa6..2b2579425b5 100644
--- a/doc/api/instance_level_ci_variables.md
+++ b/doc/api/instance_level_ci_variables.md
@@ -4,7 +4,7 @@ group: Pipeline Authoring
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
---
-# Instance-level CI/CD variables API
+# Instance-level CI/CD variables API **(FREE SELF)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14108) in GitLab 13.0
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/218249) in GitLab 13.2.
diff --git a/doc/api/issue_links.md b/doc/api/issue_links.md
index d4f59d10316..ac26d2a3d17 100644
--- a/doc/api/issue_links.md
+++ b/doc/api/issue_links.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Issue links API **(FREE)**
-> The simple "relates to" relationship [moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212329) to [GitLab Free](https://about.gitlab.com/pricing/) in 13.4.
+> The simple "relates to" relationship [moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212329) to GitLab Free in 13.4.
## List issue relations
diff --git a/doc/api/issues.md b/doc/api/issues.md
index feec9b31747..97d0fd3ce8f 100644
--- a/doc/api/issues.md
+++ b/doc/api/issues.md
@@ -20,7 +20,7 @@ Read more on [pagination](index.md#pagination).
WARNING:
The `reference` attribute in responses is deprecated in favor of `references`.
-Introduced in [GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20354).
+[Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20354) in GitLab 12.6.
NOTE:
The `references.relative` attribute is relative to the group or project of the issue being requested.
@@ -61,18 +61,19 @@ GET /issues?state=opened
| `confidential` | boolean | no | Filter confidential or public issues. |
| `created_after` | datetime | no | Return issues created on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `created_before` | datetime | no | Return issues created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
-| `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. _(Introduced in [GitLab 13.3](https://gitlab.com/gitlab-org/gitlab/-/issues/233420))_ |
+| `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233420) in GitLab 13.3)_ |
| `iids[]` | integer array | no | Return only the issues having the given `iid` |
| `in` | string | no | Modify the scope of the `search` attribute. `title`, `description`, or a string joining them with comma. Default is `title,description` |
-| `issue_type` | string | no | Filter to a given type of issue. One of `issue`, `incident`, or `test_case`. _(Introduced in [GitLab 13.12](https://gitlab.com/gitlab-org/gitlab/-/issues/260375))_ |
+| `issue_type` | string | no | Filter to a given type of issue. One of `issue`, `incident`, or `test_case`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/260375) in GitLab 13.12)_ |
| `iteration_id` **(PREMIUM)** | integer | no | Return issues assigned to the given iteration ID. `None` returns issues that do not belong to an iteration. `Any` returns issues that belong to an iteration. Mutually exclusive with `iteration_title`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ |
| `iteration_title` **(PREMIUM)** | string | no | Return issues assigned to the iteration with the given title. Similar to `iteration_id` and mutually exclusive with `iteration_id`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ |
| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `None` lists all issues with no labels. `Any` lists all issues with at least one label. `No+Label` (Deprecated) lists all issues with no labels. Predefined names are case-insensitive. |
-| `milestone` | string | no | The milestone title. `None` lists all issues with no milestone. `Any` lists all issues that have an assigned milestone. |
+| `milestone` | string | no | The milestone title. `None` lists all issues with no milestone. `Any` lists all issues that have an assigned milestone. Using `None` or `Any` will be [deprecated in the future](https://gitlab.com/gitlab-org/gitlab/-/issues/336044). Please use `milestone_id` attribute instead. `milestone` and `milestone_id` are mutually exclusive. |
+| `milestone_id` | string | no | Returns issues assigned to milestones with a given timebox value (`None`, `Any`, `Upcoming`, and `Started`). `None` lists all issues with no milestone. `Any` lists all issues that have an assigned milestone. `Upcoming` lists all issues assigned to milestones due in the future. `Started` lists all issues assigned to open, started milestones. `milestone` and `milestone_id` are mutually exclusive. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/335939) in GitLab 14.3)_ |
| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/14016) in GitLab 10.0)_ |
-| `non_archived` | boolean | no | Return issues only from non-archived projects. If `false`, the response returns issues from both archived and non-archived projects. Default is `true`. _(Introduced in [GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/issues/197170))_ |
-| `not` | Hash | no | Return issues that do not match the parameters supplied. Accepts: `assignee_id`, `assignee_username`, `author_id`, `author_username`, `iids`, `iteration_id`, `iteration_title`, `labels`, `milestone`, and `weight`. |
-| `order_by` | string | no | Return issues ordered by `created_at`, `updated_at`, `priority`, `due_date`, `relative_position`, `label_priority`, `milestone_due`, `popularity`, `weight` fields. Default is `created_at` |
+| `non_archived` | boolean | no | Return issues only from non-archived projects. If `false`, the response returns issues from both archived and non-archived projects. Default is `true`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/197170) in GitLab 13.0)_ |
+| `not` | Hash | no | Return issues that do not match the parameters supplied. Accepts: `assignee_id`, `assignee_username`, `author_id`, `author_username`, `iids`, `iteration_id`, `iteration_title`, `labels`, `milestone`, `milestone_id` and `weight`. |
+| `order_by` | string | no | Return issues ordered by `created_at`, `due_date`, `label_priority`, `milestone_due`, `popularity`, `priority`, `relative_position`, `title`, `updated_at`, or `weight` fields. Default is `created_at`. |
| `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`. Defaults to `created_by_me`<br> For versions before 11.0, use the now deprecated `created-by-me` or `assigned-to-me` scopes instead.<br> _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13004) in GitLab 9.5. [Changed to snake_case](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/18935) in GitLab 11.0)_ |
| `search` | string | no | Search issues against their `title` and `description` |
| `sort` | string | no | Return issues sorted in `asc` or `desc` order. Default is `desc` |
@@ -80,7 +81,7 @@ GET /issues?state=opened
| `updated_after` | datetime | no | Return issues updated on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `updated_before` | datetime | no | Return issues updated on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `weight` **(PREMIUM)** | integer | no | Return issues with the specified `weight`. `None` returns issues with no weight assigned. `Any` returns issues with a weight assigned. |
-| `with_labels_details` | boolean | no | If `true`, the response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. The `description_html` attribute was introduced in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413)|
+| `with_labels_details` | boolean | no | If `true`, the response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. The `description_html` attribute was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) in GitLab 12.7|
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/issues"
@@ -224,11 +225,11 @@ The `assignee` column is deprecated. We now show it as a single-sized array `ass
to the GitLab EE API.
WARNING:
-The `epic_iid` attribute is deprecated and [scheduled for removal in API version 5](https://gitlab.com/gitlab-org/gitlab/-/issues/35157).
+The `epic_iid` attribute is deprecated and [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/35157) in API version 5.
Please use `iid` of the `epic` attribute instead.
NOTE:
-The `closed_by` attribute was [introduced in GitLab 10.6](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042).
+The `closed_by` attribute was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042) in GitLab 10.6.
This value is only present for issues closed after GitLab 10.6 and if the user account
that closed the issue still exists.
@@ -267,16 +268,16 @@ GET /groups/:id/issues?state=opened
| `confidential` | boolean | no | Filter confidential or public issues. |
| `created_after` | datetime | no | Return issues created on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `created_before` | datetime | no | Return issues created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
-| `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. _(Introduced in [GitLab 13.3](https://gitlab.com/gitlab-org/gitlab/-/issues/233420))_ |
+| `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233420) in GitLab 13.3)_ |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) owned by the authenticated user |
| `iids[]` | integer array | no | Return only the issues having the given `iid` |
-| `issue_type` | string | no | Filter to a given type of issue. One of `issue`, `incident`, or `test_case`. _(Introduced in [GitLab 13.12](https://gitlab.com/gitlab-org/gitlab/-/issues/260375))_ |
+| `issue_type` | string | no | Filter to a given type of issue. One of `issue`, `incident`, or `test_case`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/260375) in GitLab 13.12)_ |
| `iteration_id` **(PREMIUM)** | integer | no | Return issues assigned to the given iteration ID. `None` returns issues that do not belong to an iteration. `Any` returns issues that belong to an iteration. Mutually exclusive with `iteration_title`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ |
| `iteration_title` **(PREMIUM)** | string | no | Return issues assigned to the iteration with the given title. Similar to `iteration_id` and mutually exclusive with `iteration_id`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ |
| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `None` lists all issues with no labels. `Any` lists all issues with at least one label. `No+Label` (Deprecated) lists all issues with no labels. Predefined names are case-insensitive. |
| `milestone` | string | no | The milestone title. `None` lists all issues with no milestone. `Any` lists all issues that have an assigned milestone. |
| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/14016) in GitLab 10.0)_ |
-| `non_archived` | boolean | no | Return issues from non archived projects. Default is true. _(Introduced in [GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23785))_ |
+| `non_archived` | boolean | no | Return issues from non archived projects. Default is true. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23785) in GitLab 12.8)_ |
| `not` | Hash | no | Return issues that do not match the parameters supplied. Accepts: `labels`, `milestone`, `author_id`, `author_username`, `assignee_id`, `assignee_username`, `my_reaction_emoji`, `search`, `in` |
| `order_by` | string | no | Return issues ordered by `created_at`, `updated_at`, `priority`, `due_date`, `relative_position`, `label_priority`, `milestone_due`, `popularity`, `weight` fields. Default is `created_at` |
| `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`.<br> For versions before 11.0, use the now deprecated `created-by-me` or `assigned-to-me` scopes instead.<br> _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13004) in GitLab 9.5. [Changed to snake_case](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/18935) in GitLab 11.0)_ |
@@ -286,7 +287,7 @@ GET /groups/:id/issues?state=opened
| `updated_after` | datetime | no | Return issues updated on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `updated_before` | datetime | no | Return issues updated on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `weight` **(PREMIUM)** | integer | no | Return issues with the specified `weight`. `None` returns issues with no weight assigned. `Any` returns issues with a weight assigned. |
-| `with_labels_details` | boolean | no | If `true`, the response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. The `description_html` attribute was introduced in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) |
+| `with_labels_details` | boolean | no | If `true`, the response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. The `description_html` attribute was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) in GitLab 12.7 |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/4/issues"
@@ -428,11 +429,11 @@ WARNING:
The `assignee` column is deprecated. We now show it as a single-sized array `assignees` to conform to the GitLab EE API.
WARNING:
-The `epic_iid` attribute is deprecated and [scheduled for removal in API version 5](https://gitlab.com/gitlab-org/gitlab/-/issues/35157).
+The `epic_iid` attribute is deprecated and [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/35157) in API version 5.
Please use `iid` of the `epic` attribute instead.
NOTE:
-The `closed_by` attribute was [introduced in GitLab 10.6](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042).
+The `closed_by` attribute was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042) in GitLab 10.6.
This value is only present for issues closed after GitLab 10.6 and if the user account that closed
the issue still exists.
@@ -471,10 +472,10 @@ GET /projects/:id/issues?state=opened
| `confidential` | boolean | no | Filter confidential or public issues. |
| `created_after` | datetime | no | Return issues created on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `created_before` | datetime | no | Return issues created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
-| `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. _(Introduced in [GitLab 13.3](https://gitlab.com/gitlab-org/gitlab/-/issues/233420))_ |
+| `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233420) in GitLab 13.3)_ |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
| `iids[]` | integer array | no | Return only the issues having the given `iid` |
-| `issue_type` | string | no | Filter to a given type of issue. One of `issue`, `incident`, or `test_case`. _(Introduced in [GitLab 13.12](https://gitlab.com/gitlab-org/gitlab/-/issues/260375))_ |
+| `issue_type` | string | no | Filter to a given type of issue. One of `issue`, `incident`, or `test_case`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/260375) in GitLab 13.12)_ |
| `iteration_id` **(PREMIUM)** | integer | no | Return issues assigned to the given iteration ID. `None` returns issues that do not belong to an iteration. `Any` returns issues that belong to an iteration. Mutually exclusive with `iteration_title`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ |
| `iteration_title` **(PREMIUM)** | string | no | Return issues assigned to the iteration with the given title. Similar to `iteration_id` and mutually exclusive with `iteration_id`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ |
| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `None` lists all issues with no labels. `Any` lists all issues with at least one label. `No+Label` (Deprecated) lists all issues with no labels. Predefined names are case-insensitive. |
@@ -489,7 +490,7 @@ GET /projects/:id/issues?state=opened
| `updated_after` | datetime | no | Return issues updated on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `updated_before` | datetime | no | Return issues updated on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `weight` **(PREMIUM)** | integer | no | Return issues with the specified `weight`. `None` returns issues with no weight assigned. `Any` returns issues with a weight assigned. |
-| `with_labels_details` | boolean | no | If `true`, the response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. `description_html` was introduced in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) |
+| `with_labels_details` | boolean | no | If `true`, the response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. `description_html` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) in GitLab 12.7 |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/4/issues"
@@ -638,11 +639,11 @@ WARNING:
The `assignee` column is deprecated. We now show it as a single-sized array `assignees` to conform to the GitLab EE API.
WARNING:
-The `epic_iid` attribute is deprecated and [scheduled for removal in API version 5](https://gitlab.com/gitlab-org/gitlab/-/issues/35157).
+The `epic_iid` attribute is deprecated and [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/35157) in API version 5.
Please use `iid` of the `epic` attribute instead.
NOTE:
-The `closed_by` attribute was [introduced in GitLab 10.6](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042). This value is only present for issues closed after GitLab 10.6 and if the user account that closed
+The `closed_by` attribute was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042) in GitLab 10.6. This value is only present for issues closed after GitLab 10.6 and if the user account that closed
the issue still exists.
## Single issue
@@ -803,11 +804,11 @@ The `assignee` column is deprecated. We now show it as a single-sized array `ass
to the GitLab EE API.
WARNING:
-The `epic_iid` attribute is deprecated, and [scheduled for removal in API version 5](https://gitlab.com/gitlab-org/gitlab/-/issues/35157).
+The `epic_iid` attribute is deprecated, and [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/35157) in API version 5.
Please use `iid` of the `epic` attribute instead.
NOTE:
-The `closed_by` attribute was [introduced in GitLab 10.6](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042).
+The `closed_by` attribute was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042) in GitLab 10.6.
This value is only present for issues closed after GitLab 10.6 and if the user account
that closed the issue still exists.
@@ -964,11 +965,11 @@ WARNING:
The `assignee` column is deprecated. We now show it as a single-sized array `assignees` to conform to the GitLab EE API.
WARNING:
-The `epic_iid` attribute is deprecated and [scheduled for removal in API version 5](https://gitlab.com/gitlab-org/gitlab/-/issues/35157).
+The `epic_iid` attribute is deprecated and [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/35157) in API version 5.
Please use `iid` of the `epic` attribute instead.
NOTE:
-The `closed_by` attribute was [introduced in GitLab 10.6](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042). This value is only present for issues closed after GitLab 10.6 and if the user account that closed
+The `closed_by` attribute was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042) in GitLab 10.6. This value is only present for issues closed after GitLab 10.6 and if the user account that closed
the issue still exists.
## New issue
@@ -991,7 +992,7 @@ POST /projects/:id/issues
| `discussion_to_resolve` | string | no | The ID of a discussion to resolve. This fills out the issue with a default description and mark the discussion as resolved. Use in combination with `merge_request_to_resolve_discussions_of`. |
| `due_date` | string | no | The due date. Date time string in the format `YYYY-MM-DD`, for example `2016-03-11` |
| `epic_id` **(PREMIUM)** | integer | no | ID of the epic to add the issue to. Valid values are greater than or equal to 0. |
-| `epic_iid` **(PREMIUM)** | integer | no | IID of the epic to add the issue to. Valid values are greater than or equal to 0. (deprecated, [scheduled for removal in API version 5](https://gitlab.com/gitlab-org/gitlab/-/issues/35157)) |
+| `epic_iid` **(PREMIUM)** | integer | no | IID of the epic to add the issue to. Valid values are greater than or equal to 0. (deprecated, [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/35157) in API version 5) |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
| `iid` | integer/string | no | The internal ID of the project's issue (requires administrator or project owner rights) |
| `issue_type` | string | no | The type of issue. One of `issue`, `incident`, or `test_case`. Default is `issue`. |
@@ -1114,11 +1115,11 @@ WARNING:
The `assignee` column is deprecated. We now show it as a single-sized array `assignees` to conform to the GitLab EE API.
WARNING:
-The `epic_iid` attribute is deprecated and [scheduled for removal in API version 5](https://gitlab.com/gitlab-org/gitlab/-/issues/35157).
+The `epic_iid` attribute is deprecated and [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/35157) in API version 5.
Please use `iid` of the `epic` attribute instead.
NOTE:
-The `closed_by` attribute was [introduced in GitLab 10.6](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042). This value is only present for issues closed after GitLab 10.6 and if the user account that closed
+The `closed_by` attribute was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042) in GitLab 10.6. This value is only present for issues closed after GitLab 10.6 and if the user account that closed
the issue still exists.
## Rate limits
@@ -1161,7 +1162,7 @@ PUT /projects/:id/issues/:issue_iid
| `discussion_locked` | boolean | no | Flag indicating if the issue's discussion is locked. If the discussion is locked only project members can add or edit comments. |
| `due_date` | string | no | The due date. Date time string in the format `YYYY-MM-DD`, for example `2016-03-11` |
| `epic_id` **(PREMIUM)** | integer | no | ID of the epic to add the issue to. Valid values are greater than or equal to 0. |
-| `epic_iid` **(PREMIUM)** | integer | no | IID of the epic to add the issue to. Valid values are greater than or equal to 0. (deprecated, [scheduled for removal in API version 5](https://gitlab.com/gitlab-org/gitlab/-/issues/35157)) |
+| `epic_iid` **(PREMIUM)** | integer | no | IID of the epic to add the issue to. Valid values are greater than or equal to 0. (deprecated, [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/35157) in API version 5) |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
| `issue_iid` | integer | yes | The internal ID of a project's issue |
| `issue_type` | string | no | Updates the type of issue. One of `issue`, `incident`, or `test_case`. |
@@ -1289,11 +1290,11 @@ Issues created by users on GitLab Ultimate include the `health_status` property:
```
NOTE:
-The `closed_by` attribute was [introduced in GitLab 10.6](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042). This value is only present for issues closed after GitLab 10.6 and if the user account that closed
+The `closed_by` attribute was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042) in GitLab 10.6. This value is only present for issues closed after GitLab 10.6 and if the user account that closed
the issue still exists.
WARNING:
-The `epic_iid` attribute is deprecated and [scheduled for removal in API version 5](https://gitlab.com/gitlab-org/gitlab/-/issues/35157).
+The `epic_iid` attribute is deprecated and [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/35157) in API version 5.
Please use `iid` of the `epic` attribute instead.
WARNING:
@@ -1479,11 +1480,11 @@ WARNING:
The `assignee` column is deprecated. We now show it as a single-sized array `assignees` to conform to the GitLab EE API.
WARNING:
-The `epic_iid` attribute is deprecated and [scheduled for removal in API version 5](https://gitlab.com/gitlab-org/gitlab/-/issues/35157).
+The `epic_iid` attribute is deprecated and [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/35157) in API version 5.
Please use `iid` of the `epic` attribute instead.
NOTE:
-The `closed_by` attribute was [introduced in GitLab 10.6](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042). This value is only present for issues closed after GitLab 10.6 and if the user account that closed
+The `closed_by` attribute was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042) in GitLab 10.6. This value is only present for issues closed after GitLab 10.6 and if the user account that closed
the issue still exists.
## Subscribe to an issue
@@ -1624,11 +1625,11 @@ WARNING:
The `assignee` column is deprecated. We now show it as a single-sized array `assignees` to conform to the GitLab EE API.
WARNING:
-The `epic_iid` attribute is deprecated and [scheduled for removal in API version 5](https://gitlab.com/gitlab-org/gitlab/-/issues/35157).
+The `epic_iid` attribute is deprecated and [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/35157) in API version 5.
Please use `iid` of the `epic` attribute instead.
NOTE:
-The `closed_by` attribute was [introduced in GitLab 10.6](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042). This value is only present for issues closed after GitLab 10.6 and if the user account that closed
+The `closed_by` attribute was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042) in GitLab 10.6. This value is only present for issues closed after GitLab 10.6 and if the user account that closed
the issue still exists.
## Unsubscribe from an issue
@@ -1822,7 +1823,7 @@ WARNING:
The `assignee` column is deprecated. We now show it as a single-sized array `assignees` to conform to the GitLab EE API.
NOTE:
-The `closed_by` attribute was [introduced in GitLab 10.6](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042). This value is only present for issues closed after GitLab 10.6 and if the user account that closed
+The `closed_by` attribute was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042) in GitLab 10.6. This value is only present for issues closed after GitLab 10.6 and if the user account that closed
the issue still exists.
## Promote an issue to an epic **(PREMIUM)**
diff --git a/doc/api/job_artifacts.md b/doc/api/job_artifacts.md
index 0a39400dfd4..6d8c256d5aa 100644
--- a/doc/api/job_artifacts.md
+++ b/doc/api/job_artifacts.md
@@ -4,7 +4,7 @@ group: Testing
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
---
-# Job Artifacts API
+# Job Artifacts API **(FREE)**
## Get job artifacts
@@ -20,7 +20,7 @@ GET /projects/:id/jobs/:job_id/artifacts
|-------------|----------------|----------|--------------------------------------------------------------------------------------------------------------|
| `id` | integer/string | yes | ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
| `job_id` | integer | yes | ID of a job. |
-| `job_token` **(PREMIUM)** | string | no | To be used with [triggers](../ci/triggers/index.md#when-a-pipeline-depends-on-the-artifacts-of-another-pipeline) for multi-project pipelines. It should be invoked only inside `.gitlab-ci.yml`. Its value is always `$CI_JOB_TOKEN`. |
+| `job_token` **(PREMIUM)** | string | no | To be used with [triggers](../ci/jobs/ci_job_token.md#download-an-artifact-from-a-different-pipeline) for multi-project pipelines. It should be invoked only inside `.gitlab-ci.yml`. Its value is always `$CI_JOB_TOKEN`. |
Example request using the `PRIVATE-TOKEN` header:
@@ -85,7 +85,7 @@ Parameters
| `id` | integer/string | yes | ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
| `ref_name` | string | yes | Branch or tag name in repository. HEAD or SHA references are not supported. |
| `job` | string | yes | The name of the job. |
-| `job_token` **(PREMIUM)** | string | no | To be used with [triggers](../ci/triggers/index.md#when-a-pipeline-depends-on-the-artifacts-of-another-pipeline) for multi-project pipelines. It should be invoked only inside `.gitlab-ci.yml`. Its value is always `$CI_JOB_TOKEN`. |
+| `job_token` **(PREMIUM)** | string | no | To be used with [triggers](../ci/jobs/ci_job_token.md#download-an-artifact-from-a-different-pipeline) for multi-project pipelines. It should be invoked only inside `.gitlab-ci.yml`. Its value is always `$CI_JOB_TOKEN`. |
Example request using the `PRIVATE-TOKEN` header:
@@ -146,7 +146,7 @@ Parameters
| `id` | integer/string | yes | ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
| `job_id` | integer | yes | The unique job identifier. |
| `artifact_path` | string | yes | Path to a file inside the artifacts archive. |
-| `job_token` **(PREMIUM)** | string | no | To be used with [triggers](../ci/triggers/index.md#when-a-pipeline-depends-on-the-artifacts-of-another-pipeline) for multi-project pipelines. It should be invoked only inside `.gitlab-ci.yml`. Its value is always `$CI_JOB_TOKEN`. |
+| `job_token` **(PREMIUM)** | string | no | To be used with [triggers](../ci/jobs/ci_job_token.md#download-an-artifact-from-a-different-pipeline) for multi-project pipelines. It should be invoked only inside `.gitlab-ci.yml`. Its value is always `$CI_JOB_TOKEN`. |
Example request:
@@ -188,7 +188,7 @@ Parameters:
| `ref_name` | string | yes | Branch or tag name in repository. `HEAD` or `SHA` references are not supported. |
| `artifact_path` | string | yes | Path to a file inside the artifacts archive. |
| `job` | string | yes | The name of the job. |
-| `job_token` **(PREMIUM)** | string | no | To be used with [triggers](../ci/triggers/index.md#when-a-pipeline-depends-on-the-artifacts-of-another-pipeline) for multi-project pipelines. It should be invoked only inside `.gitlab-ci.yml`. Its value is always `$CI_JOB_TOKEN`. |
+| `job_token` **(PREMIUM)** | string | no | To be used with [triggers](../ci/jobs/ci_job_token.md#download-an-artifact-from-a-different-pipeline) for multi-project pipelines. It should be invoked only inside `.gitlab-ci.yml`. Its value is always `$CI_JOB_TOKEN`. |
Example request:
diff --git a/doc/api/jobs.md b/doc/api/jobs.md
index 42774b80b27..ac8b756beac 100644
--- a/doc/api/jobs.md
+++ b/doc/api/jobs.md
@@ -466,7 +466,7 @@ Example of response
## Get Kubernetes Agents by `CI_JOB_TOKEN` **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/324269) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.11.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/324269) in GitLab 13.11.
Retrieve the job that generated the `CI_JOB_TOKEN`, along with a list of allowed GitLab
Kubernetes Agents.
diff --git a/doc/api/labels.md b/doc/api/labels.md
index 1606df03afb..a8cb56f1573 100644
--- a/doc/api/labels.md
+++ b/doc/api/labels.md
@@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
Interact with [labels](../user/project/labels.md) using the REST API.
NOTE:
-The `description_html` - was added to response JSON in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413).
+The `description_html` - was [added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) to response JSON in GitLab 12.7.
## List labels
@@ -24,7 +24,7 @@ GET /projects/:id/labels
| Attribute | Type | Required | Description |
| --------- | ------- | -------- | --------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
-| `with_counts` | boolean | no | Whether or not to include issue and merge request counts. Defaults to `false`. _([Introduced in GitLab 12.2](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/31543))_ |
+| `with_counts` | boolean | no | Whether or not to include issue and merge request counts. Defaults to `false`. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/31543) in GitLab 12.2)_ |
| `include_ancestor_groups` | boolean | no | Include ancestor groups. Defaults to `true`. |
| `search` | string | no | Keyword to filter labels by. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/259024) in GitLab 13.6 |
diff --git a/doc/api/lint.md b/doc/api/lint.md
index a47bb028248..9f95b9a94ae 100644
--- a/doc/api/lint.md
+++ b/doc/api/lint.md
@@ -1,6 +1,6 @@
---
stage: Verify
-group: Pipeline Execution
+group: Pipeline Authoring
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
---
@@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
## Validate the CI YAML configuration
Checks if CI/CD YAML configuration is valid. This endpoint validates basic CI/CD
-configuration syntax. It doesn't have any namespace specific context.
+configuration syntax. It doesn't have any namespace-specific context.
Access to this endpoint does not require authentication when the instance
[allows new sign ups](../user/admin_area/settings/sign_up_restrictions.md#disable-new-sign-ups)
diff --git a/doc/api/members.md b/doc/api/members.md
index 4b383efd792..0b8cf686b8c 100644
--- a/doc/api/members.md
+++ b/doc/api/members.md
@@ -4,7 +4,7 @@ group: Access
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
---
-# Group and project members API
+# Group and project members API **(FREE)**
## Valid access levels
@@ -92,7 +92,7 @@ Gets a list of group or project members viewable by the authenticated user, incl
If a user is a member of this group or project and also of one or more ancestor groups,
only its membership with the highest `access_level` is returned.
-([Improved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56677)] in GitLab 13.11.)
+([Improved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56677) in GitLab 13.11.)
This represents the effective permission of the user.
This function takes pagination parameters `page` and `per_page` to restrict the list of users.
@@ -552,7 +552,7 @@ Example response:
"state": "active",
"avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",
"web_url": "http://192.168.1.8:3000/root",
- "expires_at": "2012-10-22T14:13:35Z",
+ "expires_at": "2012-10-22",
"access_level": 40,
"email": "john@example.com",
"override": false
diff --git a/doc/api/merge_request_approvals.md b/doc/api/merge_request_approvals.md
index ef8af608466..b4403e1d9b9 100644
--- a/doc/api/merge_request_approvals.md
+++ b/doc/api/merge_request_approvals.md
@@ -81,7 +81,7 @@ POST /projects/:id/approvals
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11877) in GitLab 12.3.
> - Moved to GitLab Premium in 13.9.
-> - `protected_branches` property was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/460) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.7.
+> - `protected_branches` property was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/460) in GitLab 12.7.
You can request information about a project's approval rules using the following endpoint:
@@ -954,7 +954,7 @@ POST /projects/:id/merge_requests/:merge_request_iid/approve
| `id` | integer or string | yes | The ID or [URL-encoded path of a project](index.md#namespaced-path-encoding) |
| `merge_request_iid` | integer | yes | The IID of the merge request |
| `sha` | string | no | The `HEAD` of the merge request |
-| `approval_password` **(PREMIUM)** | string | no | Current user's password. Required if [**Require user password to approve**](../user/project/merge_requests/approvals/settings.md#require-user-password-to-approve) is enabled in the project settings. |
+| `approval_password` | string | no | Current user's password. Required if [**Require user password to approve**](../user/project/merge_requests/approvals/settings.md#require-user-password-to-approve) is enabled in the project settings. |
The `sha` parameter works in the same way as
when [accepting a merge request](merge_requests.md#accept-mr): if it is passed, then it must
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index b90f0e70a02..98af228a064 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -222,7 +222,7 @@ Parameters:
]
```
-Users on GitLab Premium or higher also see
+Users on [GitLab Premium or higher](https://about.gitlab.com/pricing/) also see
the `approvals_before_merge` parameter:
```json
@@ -418,7 +418,7 @@ The `merge_status` field may hold one of the following values:
| `cannot_be_merged` | There are merge conflicts between the source and target branches |
| `cannot_be_merged_recheck` | Currently unchecked. Before the current changes, there were conflicts |
-Users on GitLab Premium or higher also see
+Users on [GitLab Premium or higher](https://about.gitlab.com/pricing/) also see
the `approvals_before_merge` parameter:
```json
@@ -460,8 +460,8 @@ Parameters:
| `milestone` | string | no | Return merge requests for a specific milestone. `None` returns merge requests with no milestone. `Any` returns merge requests that have an assigned milestone. |
| `view` | string | no | If `simple`, returns the `iid`, URL, title, description, and basic state of merge request. |
| `labels` | string | no | Return merge requests matching a comma separated list of labels. `None` lists all merge requests with no labels. `Any` lists all merge requests with at least one label. `No+Label` (Deprecated) lists all merge requests with no labels. Predefined names are case-insensitive. |
-| `with_labels_details` | boolean | no | If `true`, response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. Introduced in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413).|
-| `with_merge_status_recheck` | boolean | no | If `true`, this projection requests (but does not guarantee) that the `merge_status` field be recalculated asynchronously. Default is `false`. Introduced in [GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31890). |
+| `with_labels_details` | boolean | no | If `true`, response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) in GitLab 12.7.|
+| `with_merge_status_recheck` | boolean | no | If `true`, this projection requests (but does not guarantee) that the `merge_status` field be recalculated asynchronously. Default is `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31890) in GitLab 13.0. |
| `created_after` | datetime | no | Return merge requests created on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). |
| `created_before` | datetime | no | Return merge requests created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). |
| `updated_after` | datetime | no | Return merge requests updated on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). |
@@ -478,7 +478,7 @@ Parameters:
| `source_branch` | string | no | Return merge requests with the given source branch. |
| `target_branch` | string | no | Return merge requests with the given target branch. |
| `search` | string | no | Search merge requests against their `title` and `description`. |
-| `non_archived` | boolean | no | Return merge requests from non archived projects only. Default is true. _(Introduced in [GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23809))_. |
+| `non_archived` | boolean | no | Return merge requests from non archived projects only. Default is true. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23809) in GitLab 12.8)_. |
| `not` | Hash | no | Return merge requests that do not match the parameters supplied. Accepts: `labels`, `milestone`, `author_id`, `author_username`, `assignee_id`, `assignee_username`, `reviewer_id`, `reviewer_username`, `my_reaction_emoji`. |
```json
@@ -592,7 +592,7 @@ Parameters:
]
```
-Users on GitLab Premium or higher also see
+Users on [GitLab Premium or higher](https://about.gitlab.com/pricing/) also see
the `approvals_before_merge` parameter:
```json
@@ -625,7 +625,7 @@ Parameters:
|----------------------------------|----------------|----------|------------------------------------------------------------------------------------------------------------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
-| `render_html` | integer | no | If `true` response includes rendered HTML for title and description. |
+| `render_html` | boolean | no | If `true` response includes rendered HTML for title and description. |
| `include_diverged_commits_count` | boolean | no | If `true` response includes the commits behind the target branch. |
| `include_rebase_in_progress` | boolean | no | If `true` response includes whether a rebase operation is in progress. |
@@ -764,7 +764,7 @@ Parameters:
}
```
-Users on GitLab Premium also see
+Users on [GitLab Premium or higher](https://about.gitlab.com/pricing/) also see
the `approvals_before_merge` parameter:
```json
@@ -1014,7 +1014,7 @@ The new pipeline can be:
- A detached merge request pipeline.
- A [pipeline for merged results](../ci/pipelines/pipelines_for_merged_results.md)
- if the [project setting is enabled](../ci/pipelines/pipelines_for_merged_results.md#enable-pipelines-for-merged-results).
+ if the [project setting is enabled](../ci/pipelines/pipelines_for_merged_results.md#enable-pipelines-for-merged-results). **(PREMIUM)**
```plaintext
POST /projects/:id/merge_requests/:merge_request_iid/pipelines
@@ -1375,7 +1375,7 @@ Must include at least one non-required attribute from above.
}
```
-Users on GitLab Premium or higher also see
+Users on [GitLab Premium or higher](https://about.gitlab.com/pricing/) also see
the `approvals_before_merge` parameter:
```json
@@ -1561,7 +1561,7 @@ Parameters:
}
```
-Users on GitLab Premium also see
+Users on [GitLab Premium or higher](https://about.gitlab.com/pricing/) also see
the `approvals_before_merge` parameter:
```json
@@ -1750,7 +1750,7 @@ Parameters:
}
```
-Users on GitLab Premium or higher also see
+Users on [GitLab Premium or higher](https://about.gitlab.com/pricing/) also see
the `approvals_before_merge` parameter:
```json
@@ -2051,7 +2051,7 @@ Example response:
}
```
-Users on GitLab Premium also see
+Users on [GitLab Premium or higher](https://about.gitlab.com/pricing/) also see
the `approvals_before_merge` parameter:
```json
@@ -2211,7 +2211,7 @@ Example response:
}
```
-Users on GitLab Premium or higher also see
+Users on [GitLab Premium or higher](https://about.gitlab.com/pricing/) also see
the `approvals_before_merge` parameter:
```json
diff --git a/doc/api/metrics_dashboard_annotations.md b/doc/api/metrics_dashboard_annotations.md
index b2f1e52f194..feba57a7ced 100644
--- a/doc/api/metrics_dashboard_annotations.md
+++ b/doc/api/metrics_dashboard_annotations.md
@@ -7,7 +7,7 @@ type: concepts, howto
# Dashboard annotations API **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29089) in GitLab 12.10 behind a disabled feature flag.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29089) in GitLab 12.10 behind a disabled feature flag.
Metrics dashboard annotations allow you to indicate events on your graphs at a single point in time or over a time span.
diff --git a/doc/api/metrics_user_starred_dashboards.md b/doc/api/metrics_user_starred_dashboards.md
index 603d307f4b7..f615ddaaa71 100644
--- a/doc/api/metrics_user_starred_dashboards.md
+++ b/doc/api/metrics_user_starred_dashboards.md
@@ -43,7 +43,7 @@ Example Response:
## Remove a star from a dashboard
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31892) in GitLab 13.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31892) in GitLab 13.0.
```plaintext
DELETE /projects/:id/metrics/user_starred_dashboards
diff --git a/doc/api/milestones.md b/doc/api/milestones.md
index 183d8b4799b..84b4e2fe39d 100644
--- a/doc/api/milestones.md
+++ b/doc/api/milestones.md
@@ -32,7 +32,7 @@ Parameters:
| `state` | string | optional | Return only `active` or `closed` milestones |
| `title` | string | optional | Return only the milestones having the given `title` |
| `search` | string | optional | Return only milestones with a title or description matching the provided string |
-| `include_parent_milestones` | boolean | optional | Include group milestones from parent group and its ancestors. Introduced in [GitLab 13.4](https://gitlab.com/gitlab-org/gitlab/-/issues/196066) |
+| `include_parent_milestones` | boolean | optional | Include group milestones from parent group and its ancestors. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196066) in GitLab 13.4 |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/milestones"
diff --git a/doc/api/notification_settings.md b/doc/api/notification_settings.md
index 390ba7dbd79..4b70a643263 100644
--- a/doc/api/notification_settings.md
+++ b/doc/api/notification_settings.md
@@ -199,7 +199,7 @@ Example responses:
}
```
-Users on GitLab [Ultimate](https://about.gitlab.com/pricing/) also see the `new_epic`
+Users on [GitLab Ultimate](https://about.gitlab.com/pricing/) also see the `new_epic`
parameter:
```json
diff --git a/doc/api/oauth2.md b/doc/api/oauth2.md
index ce455c89d1a..abf9d7af229 100644
--- a/doc/api/oauth2.md
+++ b/doc/api/oauth2.md
@@ -5,7 +5,7 @@ group: Access
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/#designated-technical-writers
---
-# GitLab as an OAuth2 provider
+# GitLab as an OAuth 2.0 provider **(FREE)**
This document covers using the [OAuth2](https://oauth.net/2/) protocol to allow
other services to access GitLab resources on user's behalf.
@@ -15,9 +15,9 @@ other services, see the [OAuth2 authentication service provider](../integration/
documentation. This functionality is based on the
[doorkeeper Ruby gem](https://github.com/doorkeeper-gem/doorkeeper).
-## Supported OAuth2 flows
+## Supported OAuth 2.0 flows
-GitLab currently supports the following authorization flows:
+GitLab supports the following authorization flows:
- **Authorization code with [Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636):**
Most secure. Without PKCE, you'd have to include client secrets on mobile clients,
@@ -26,14 +26,13 @@ GitLab currently supports the following authorization flows:
server-side apps.
- **Implicit grant:** Originally designed for user-agent only apps, such as
single page web apps running on GitLab Pages).
- The [IETF](https://tools.ietf.org/html/draft-ietf-oauth-security-topics-09#section-2.1.2)
+ The [Internet Engineering Task Force (IETF)](https://tools.ietf.org/html/draft-ietf-oauth-security-topics-09#section-2.1.2)
recommends against Implicit grant flow.
- **Resource owner password credentials:** To be used **only** for securely
hosted, first-party services. GitLab recommends against use of this flow.
The draft specification for [OAuth 2.1](https://oauth.net/2.1/) specifically omits both the
-Implicit grant and Resource Owner Password Credentials flows.
- it will be deprecated in the next OAuth specification version.
+Implicit grant and Resource Owner Password Credentials flows. It will be deprecated in the next OAuth specification version.
Refer to the [OAuth RFC](https://tools.ietf.org/html/rfc6749) to find out
how all those flows work and pick the right one for your use case.
@@ -57,7 +56,7 @@ parameter, which are securely bound to the user agent", with each request to the
For production, please use HTTPS for your `redirect_uri`.
For development, GitLab allows insecure HTTP redirect URIs.
-As OAuth2 bases its security entirely on the transport layer, you should not use unprotected
+As OAuth 2.0 bases its security entirely on the transport layer, you should not use unprotected
URIs. For more information, see the [OAuth 2.0 RFC](https://tools.ietf.org/html/rfc6749#section-3.1.2.1)
and the [OAuth 2.0 Threat Model RFC](https://tools.ietf.org/html/rfc6819#section-4.4.2.1).
These factors are particularly important when using the
@@ -83,7 +82,11 @@ Before starting the flow, generate the `STATE`, the `CODE_VERIFIER` and the `COD
which use the characters `A-Z`, `a-z`, `0-9`, `-`, `.`, `_`, and `~`.
- The `CODE_CHALLENGE` is an URL-safe base64-encoded string of the SHA256 hash of the
`CODE_VERIFIER`
+ - The SHA256 hash must be in binary format before encoding.
- In Ruby, you can set that up with `Base64.urlsafe_encode64(Digest::SHA256.digest(CODE_VERIFIER), padding: false)`.
+ - For reference, a `CODE_VERIFIER` string of `ks02i3jdikdo2k0dkfodf3m39rjfjsdk0wk349rj3jrhf` when hashed
+ and encoded using the Ruby snippet above produces a `CODE_CHALLENGE` string
+ of `2i0WFA-0AerkjQm4X4oDEhqA17QIAKNjXpagHBXmO_U`.
1. Request authorization code. To do that, you should redirect the user to the
`/oauth/authorize` page with the following query parameters:
@@ -123,7 +126,7 @@ Before starting the flow, generate the `STATE`, the `CODE_VERIFIER` and the `COD
"created_at": 1607635748
}
```
-
+
1. To retrieve a new `access_token`, use the `refresh_token` parameter. Refresh tokens may
be used even after the `access_token` itself expires. This request:
- Invalidates the existing `access_token` and `refresh_token`.
@@ -135,7 +138,7 @@ Before starting the flow, generate the `STATE`, the `CODE_VERIFIER` and the `COD
```
Example response:
-
+
```json
{
"access_token": "c97d1fe52119f38c7f67f0a14db68d60caa35ddc86fd12401718b649dcfa9c68",
@@ -203,7 +206,7 @@ be used as a CSRF token.
"created_at": 1607635748
}
```
-
+
1. To retrieve a new `access_token`, use the `refresh_token` parameter. Refresh tokens may
be used even after the `access_token` itself expires. This request:
- Invalidates the existing `access_token` and `refresh_token`.
@@ -245,12 +248,13 @@ scheduled to be removed for existing applications.
We recommend that you use [Authorization code with PKCE](#authorization-code-with-proof-key-for-code-exchange-pkce) instead. If you choose to use Implicit flow, be sure to verify the
`application id` (or `client_id`) associated with the access token before granting
-access to the data, as described in [Retrieving the token information](#retrieving-the-token-information)).
+access to the data. To learn more, read
+[Retrieving the token information](#retrieve-the-token-information)).
Unlike the authorization code flow, the client receives an `access token`
-immediately as a result of the authorization request. The flow does not use
-the client secret or the authorization code because all of the application code
-and storage is easily accessible on client browsers and mobile devices.
+immediately as a result of the authorization request. The flow does not use the
+client secret or the authorization code, as the application
+code and storage is accessible on client browsers and mobile devices.
To request the access token, you should redirect the user to the
`/oauth/authorize` endpoint using `token` response type:
@@ -367,10 +371,11 @@ or you can put the token to the Authorization header:
curl --header "Authorization: Bearer OAUTH-TOKEN" "https://gitlab.example.com/api/v4/user"
```
-## Retrieving the token information
+## Retrieve the token information
-To verify the details of a token, use the `token/info` endpoint provided by the Doorkeeper gem.
-For more information, see [`/oauth/token/info`](https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples#get----oauthtokeninfo).
+To verify the details of a token, use the `token/info` endpoint provided by the
+Doorkeeper gem. For more information, see
+[`/oauth/token/info`](https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples#get----oauthtokeninfo).
You must supply the access token, either:
@@ -407,9 +412,10 @@ prevent breaking changes introduced in [doorkeeper 5.0.2](https://github.com/doo
Don't rely on these fields as they are slated for removal in a later release.
-## OAuth2 tokens and GitLab registries
+## OAuth 2.0 tokens and GitLab registries
-Standard OAuth2 tokens support different degrees of access to GitLab registries, as they:
+Standard OAuth 2.0 tokens support different degrees of access to GitLab
+registries, as they:
- Do not allow users to authenticate to:
- The GitLab [Container registry](../user/packages/container_registry/index.md#authenticate-with-the-container-registry).
diff --git a/doc/api/packages.md b/doc/api/packages.md
index 73092e68c82..a75b2e376fa 100644
--- a/doc/api/packages.md
+++ b/doc/api/packages.md
@@ -4,7 +4,7 @@ group: Package
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
---
-# Packages API
+# Packages API **(FREE)**
This is the API documentation of [GitLab Packages](../administration/packages/index.md).
diff --git a/doc/api/packages/composer.md b/doc/api/packages/composer.md
index 4f8e0a23c9c..b3a27519729 100644
--- a/doc/api/packages/composer.md
+++ b/doc/api/packages/composer.md
@@ -4,7 +4,7 @@ group: Package
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
---
-# Composer API
+# Composer API **(FREE)**
This is the API documentation for [Composer Packages](../../user/packages/composer_repository/index.md).
@@ -108,13 +108,14 @@ V1.
GET group/:id/-/packages/composer/:package_name$:sha
```
-Note the `$` symbol in the URL. When making requests, you may need to use the URL-encoded version of
-the symbol `%24` (see example below).
+Note the `$` symbol in the URL. When making requests, you may need the
+URL-encoded version of the symbol `%24`. Refer to the example after
+the table:
-| Attribute | Type | Required | Description |
-| -------------- | ------ | -------- | ----------- |
-| `id` | string | yes | The ID or full path of the group. |
-| `package_name` | string | yes | The name of the package. |
+| Attribute | Type | Required | Description |
+|----------------|--------|----------|---------------------------------------------------------------------------------------|
+| `id` | string | yes | The ID or full path of the group. |
+| `package_name` | string | yes | The name of the package. |
| `sha` | string | yes | The SHA digest of the package, provided by the [V1 packages list](#v1-packages-list). |
```shell
diff --git a/doc/api/packages/conan.md b/doc/api/packages/conan.md
index 88ed2524173..f5d08ed7ef8 100644
--- a/doc/api/packages/conan.md
+++ b/doc/api/packages/conan.md
@@ -4,7 +4,7 @@ group: Package
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
---
-# Conan API
+# Conan API **(FREE)**
This is the API documentation for [Conan Packages](../../user/packages/conan_repository/index.md).
diff --git a/doc/api/packages/go_proxy.md b/doc/api/packages/go_proxy.md
index 2f81435db42..ffafc387951 100644
--- a/doc/api/packages/go_proxy.md
+++ b/doc/api/packages/go_proxy.md
@@ -4,7 +4,7 @@ group: Package
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
---
-# Go Proxy API
+# Go Proxy API **(FREE SELF)**
This is the API documentation for [Go Packages](../../user/packages/go_proxy/index.md).
This API is behind a feature flag that is disabled by default. GitLab administrators with access to
diff --git a/doc/api/packages/helm.md b/doc/api/packages/helm.md
index f1d5f24cd99..8c3b9869368 100644
--- a/doc/api/packages/helm.md
+++ b/doc/api/packages/helm.md
@@ -4,7 +4,7 @@ group: Package
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
---
-# Helm API
+# Helm API **(FREE)**
This is the API documentation for [Helm](../../user/packages/helm_repository/index.md).
@@ -38,14 +38,14 @@ GET projects/:id/packages/helm/:channel/index.yaml
```shell
curl --user <username>:<personal_access_token> \
- https://gitlab.example.com/api/v4/projects/1/packages/helm/stable/index.yaml
+ "https://gitlab.example.com/api/v4/projects/1/packages/helm/stable/index.yaml"
```
Write the output to a file:
```shell
curl --user <username>:<personal_access_token> \
- https://gitlab.example.com/api/v4/projects/1/packages/helm/stable/index.yaml \
+ "https://gitlab.example.com/api/v4/projects/1/packages/helm/stable/index.yaml" \
--remote-name
```
@@ -67,7 +67,7 @@ GET projects/:id/packages/helm/:channel/charts/:file_name.tgz
```shell
curl --user <username>:<personal_access_token> \
- https://gitlab.example.com/api/v4/projects/1/packages/helm/stable/charts/mychart.tgz \
+ "https://gitlab.example.com/api/v4/projects/1/packages/helm/stable/charts/mychart.tgz" \
--remote-name
```
@@ -91,5 +91,5 @@ POST projects/:id/packages/helm/api/:channel/charts
curl --request POST \
--form 'chart=@mychart.tgz' \
--user <username>:<personal_access_token> \
- https://gitlab.example.com/api/v4/projects/1/packages/helm/api/stable/charts
+ "https://gitlab.example.com/api/v4/projects/1/packages/helm/api/stable/charts"
```
diff --git a/doc/api/packages/maven.md b/doc/api/packages/maven.md
index d03c9be3060..b4b3d579ffb 100644
--- a/doc/api/packages/maven.md
+++ b/doc/api/packages/maven.md
@@ -4,7 +4,7 @@ group: Package
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
---
-# Maven API
+# Maven API **(FREE)**
This is the API documentation for [Maven Packages](../../user/packages/maven_repository/index.md).
diff --git a/doc/api/packages/npm.md b/doc/api/packages/npm.md
index 3992a042915..24ac1a640c9 100644
--- a/doc/api/packages/npm.md
+++ b/doc/api/packages/npm.md
@@ -4,7 +4,7 @@ group: Package
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.example/handbook/engineering/ux/technical-writing/#assignments
---
-# npm API
+# npm API **(FREE)**
This is the API documentation for [npm Packages](../../user/packages/npm_registry/index.md).
@@ -58,11 +58,11 @@ Upload a package.
PUT projects/:id/packages/npm/:package_name
```
-| Attribute | Type | Required | Description |
-| ----------------- | ------ | -------- | ----------- |
-| `id` | string | yes | The ID or full path of the project. |
-| `package_name` | string | yes | The name of the package. |
-| `versions` | string | yes | Package version info. |
+| Attribute | Type | Required | Description |
+|----------------|--------|----------|-------------------------------------|
+| `id` | string | yes | The ID or full path of the project. |
+| `package_name` | string | yes | The name of the package. |
+| `versions` | string | yes | Package version information. |
```shell
curl --request PUT
diff --git a/doc/api/packages/nuget.md b/doc/api/packages/nuget.md
index d19e2dfa65b..aee3a4fe542 100644
--- a/doc/api/packages/nuget.md
+++ b/doc/api/packages/nuget.md
@@ -4,7 +4,7 @@ group: Package
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about..example/handbook/engineering/ux/technical-writing/#assignments
---
-# NuGet API
+# NuGet API **(FREE)**
This is the API documentation for [NuGet Packages](../../user/packages/nuget_repository/index.md).
@@ -73,7 +73,7 @@ curl --user <username>:<personal_access_token> "https://gitlab.example.com/api/v
Write the output to a file:
```shell
-curl --user <username>:<personal_access_token> "https://gitlab.example.com/api/v4/projects/1/packages/nuget/download/MyNuGetPkg/1.3.0.17/mynugetpkg.1.3.0.17.nupkg" >> MyNuGetPkg.1.3.0.17.nupkg
+curl --user <username>:<personal_access_token> "https://gitlab.example.com/api/v4/projects/1/packages/nuget/download/MyNuGetPkg/1.3.0.17/mynugetpkg.1.3.0.17.nupkg" > MyNuGetPkg.1.3.0.17.nupkg
```
This writes the downloaded file to `MyNuGetPkg.1.3.0.17.nupkg` in the current directory.
diff --git a/doc/api/packages/pypi.md b/doc/api/packages/pypi.md
index dd301e9fab8..a1c96d03297 100644
--- a/doc/api/packages/pypi.md
+++ b/doc/api/packages/pypi.md
@@ -4,7 +4,7 @@ group: Package
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
---
-# PyPI API
+# PyPI API **(FREE)**
This is the API documentation for [PyPI Packages](../../user/packages/pypi_repository/index.md).
@@ -47,7 +47,8 @@ To write the output to a file:
curl --user <username>:<personal_access_token> "https://gitlab.example.com/api/v4/groups/1/packages/pypi/files/5y57017232013c8ac80647f4ca153k3726f6cba62d055cd747844ed95b3c65ff/my.pypi.package-0.0.1.tar.gz" >> my.pypi.package-0.0.1.tar.gz
```
-This writes the downloaded file to `my.pypi.package-0.0.1.tar.gz` in the current directory.
+This writes the downloaded file to `my.pypi.package-0.0.1.tar.gz` in the current
+directory.
## Group level simple API entry point
@@ -106,7 +107,7 @@ GET projects/:id/packages/pypi/files/:sha256/:file_identifier
| --------- | ---- | -------- | ----------- |
| `id` | string | yes | The ID or full path of the project. |
| `sha256` | string | yes | PyPI package file sha256 check sum. |
-| `file_identifier` | string | yes | The PyPI package file name. |
+| `file_identifier` | string | yes | The PyPI package filename. |
```shell
curl --user <username>:<personal_access_token> "https://gitlab.example.com/api/v4/projects/1/packages/pypi/files/5y57017232013c8ac80647f4ca153k3726f6cba62d055cd747844ed95b3c65ff/my.pypi.package-0.0.1.tar.gz"
@@ -118,7 +119,8 @@ To write the output to a file:
curl --user <username>:<personal_access_token> "https://gitlab.example.com/api/v4/projects/1/packages/pypi/files/5y57017232013c8ac80647f4ca153k3726f6cba62d055cd747844ed95b3c65ff/my.pypi.package-0.0.1.tar.gz" >> my.pypi.package-0.0.1.tar.gz
```
-This writes the downloaded file to `my.pypi.package-0.0.1.tar.gz` in the current directory.
+This writes the downloaded file to `my.pypi.package-0.0.1.tar.gz` in the current
+directory.
## Project-level simple API entry point
diff --git a/doc/api/packages/rubygems.md b/doc/api/packages/rubygems.md
index 426548d5ed2..10dcaafda42 100644
--- a/doc/api/packages/rubygems.md
+++ b/doc/api/packages/rubygems.md
@@ -4,7 +4,7 @@ group: Package
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
---
-# Ruby gems API
+# Ruby gems API **(FREE SELF)**
This is the API documentation for [Ruby gems](../../user/packages/rubygems_registry/index.md).
diff --git a/doc/api/pages.md b/doc/api/pages.md
index ef6523520de..f81a3c3c72b 100644
--- a/doc/api/pages.md
+++ b/doc/api/pages.md
@@ -4,7 +4,7 @@ group: Release
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
---
-# Pages API
+# Pages API **(FREE)**
Endpoints for managing [GitLab Pages](https://about.gitlab.com/stages-devops-lifecycle/pages/).
diff --git a/doc/api/pages_domains.md b/doc/api/pages_domains.md
index 46d92db9853..47a8df3875e 100644
--- a/doc/api/pages_domains.md
+++ b/doc/api/pages_domains.md
@@ -4,7 +4,7 @@ group: Release
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
---
-# Pages domains API
+# Pages domains API **(FREE)**
Endpoints for connecting custom domain(s) and TLS certificates in [GitLab Pages](https://about.gitlab.com/stages-devops-lifecycle/pages/).
diff --git a/doc/api/personal_access_tokens.md b/doc/api/personal_access_tokens.md
index 4949bf504fa..b96ee81f673 100644
--- a/doc/api/personal_access_tokens.md
+++ b/doc/api/personal_access_tokens.md
@@ -4,14 +4,14 @@ group: Compliance
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
---
-# Personal access tokens API
+# Personal access tokens API **(FREE)**
You can read more about [personal access tokens](../user/profile/personal_access_tokens.md#personal-access-tokens).
## List personal access tokens
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/227264) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.3.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/270200) to [GitLab Free](https://about.gitlab.com/pricing/) in 13.6.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/227264) in GitLab 13.3.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/270200) from GitLab Ultimate to GitLab Free in 13.6.
Get a list of personal access tokens.
@@ -70,8 +70,8 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a
## Revoke a personal access token
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216004) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.3.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/270200) to [GitLab Free](https://about.gitlab.com/pricing/) in 13.6.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216004) in GitLab 13.3.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/270200) from GitLab Ultimate to GitLab Free in 13.6.
Revoke a personal access token.
diff --git a/doc/api/pipeline_triggers.md b/doc/api/pipeline_triggers.md
index 2fe3f487ebc..5472e5bc334 100644
--- a/doc/api/pipeline_triggers.md
+++ b/doc/api/pipeline_triggers.md
@@ -38,6 +38,9 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a
]
```
+The trigger token is displayed in full if the trigger token was created by the authenticated
+user. Trigger tokens created by other users are shortened to four characters.
+
## Get trigger details
Get details of project's build trigger.
diff --git a/doc/api/pipelines.md b/doc/api/pipelines.md
index ad7336bba8f..f3c30a414ea 100644
--- a/doc/api/pipelines.md
+++ b/doc/api/pipelines.md
@@ -32,10 +32,10 @@ GET /projects/:id/pipelines
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
| `scope` | string | no | The scope of pipelines, one of: `running`, `pending`, `finished`, `branches`, `tags` |
| `status` | string | no | The status of pipelines, one of: `created`, `waiting_for_resource`, `preparing`, `pending`, `running`, `success`, `failed`, `canceled`, `skipped`, `manual`, `scheduled` |
+| `source` | string | no | In [GitLab 14.3 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/325439), how the pipeline was triggered, one of: `push`, `web`, `trigger`, `schedule`, `api`, `external`, `pipeline`, `chat`, `webide`, `merge_request_event`, `external_pull_request_event`, `parent_pipeline`, `ondemand_dast_scan`, or `ondemand_dast_validation`. |
| `ref` | string | no | The ref of pipelines |
| `sha` | string | no | The SHA of pipelines |
| `yaml_errors`| boolean | no | Returns pipelines with invalid configurations |
-| `name`| string | no | _([Deprecated in GitLab 14.2](https://gitlab.com/gitlab-org/gitlab/-/issues/336953))_ The name of the user who triggered pipelines |
| `username`| string | no | The username of the user who triggered pipelines |
| `updated_after` | datetime | no | Return pipelines updated after the specified date. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). |
| `updated_before` | datetime | no | Return pipelines updated before the specified date. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). |
@@ -55,6 +55,7 @@ Example of response
"iid": 12,
"project_id": 1,
"status": "pending",
+ "soure": "push",
"ref": "new-pipeline",
"sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
"web_url": "https://example.com/foo/bar/pipelines/47",
@@ -66,6 +67,7 @@ Example of response
"iid": 13,
"project_id": 1,
"status": "pending",
+ "soure": "web",
"ref": "new-pipeline",
"sha": "eb94b618fb5865b26e80fdd8ae531b7a63ad851a",
"web_url": "https://example.com/foo/bar/pipelines/48",
@@ -212,7 +214,7 @@ Sample response:
### Get a pipeline's test report summary
-> Introduced in [GitLab 14.2](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65471)
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65471) in GitLab 14.2.
NOTE:
This API route is part of the [Unit test report](../ci/unit_test_reports.md) feature.
diff --git a/doc/api/plan_limits.md b/doc/api/plan_limits.md
index c89c7b46d54..52152dd6e14 100644
--- a/doc/api/plan_limits.md
+++ b/doc/api/plan_limits.md
@@ -4,7 +4,7 @@ group: Access
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
---
-# Plan limits API **(FREE)**
+# Plan limits API **(FREE SELF)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54232) in GitLab 13.10.
diff --git a/doc/api/project_aliases.md b/doc/api/project_aliases.md
index 1638bb644c2..0d130f6f484 100644
--- a/doc/api/project_aliases.md
+++ b/doc/api/project_aliases.md
@@ -7,7 +7,7 @@ type: reference, api
# Project Aliases API **(PREMIUM SELF)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3264) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.1.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3264) in GitLab 12.1.
All methods require administrator authorization.
diff --git a/doc/api/project_clusters.md b/doc/api/project_clusters.md
index 2b4976510bb..bb05e4788d0 100644
--- a/doc/api/project_clusters.md
+++ b/doc/api/project_clusters.md
@@ -294,7 +294,7 @@ Parameters:
| `platform_kubernetes_attributes[token]` | string | no | The token to authenticate against Kubernetes |
| `platform_kubernetes_attributes[ca_cert]` | string | no | TLS certificate. Required if API is using a self-signed TLS certificate. |
| `platform_kubernetes_attributes[namespace]` | string | no | The unique namespace related to the project |
-| `environment_scope` | string | no | The associated environment to the cluster **(PREMIUM)** |
+| `environment_scope` | string | no | The associated environment to the cluster |
NOTE:
`name`, `api_url`, `ca_cert` and `token` can only be updated if the cluster was added
diff --git a/doc/api/project_level_variables.md b/doc/api/project_level_variables.md
index e596b25ca22..2dcef40aacb 100644
--- a/doc/api/project_level_variables.md
+++ b/doc/api/project_level_variables.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference, api
---
-# Project-level Variables API
+# Project-level Variables API **(FREE)**
## List project variables
diff --git a/doc/api/project_vulnerabilities.md b/doc/api/project_vulnerabilities.md
index 2035d17aa3f..7ba359587f6 100644
--- a/doc/api/project_vulnerabilities.md
+++ b/doc/api/project_vulnerabilities.md
@@ -7,7 +7,7 @@ type: reference, api
# Project Vulnerabilities API **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10242) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10242) in GitLab 12.6.
WARNING:
This API is in an alpha stage and considered unstable.
diff --git a/doc/api/projects.md b/doc/api/projects.md
index a510f05df58..29e3cdf6cbf 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -55,7 +55,7 @@ GET /projects
| `min_access_level` | integer | **{dotted-circle}** No | Limit by current user minimal [access level](members.md#valid-access-levels). |
| `order_by` | string | **{dotted-circle}** No | Return projects ordered by `id`, `name`, `path`, `created_at`, `updated_at`, `last_activity_at`, or `similarity` fields. `repository_size`, `storage_size`, `packages_size` or `wiki_size` fields are only allowed for admins. `similarity` ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/332890) in GitLab 14.1) is only available when searching and is limited to projects that the current user is a member of. Default is `created_at`. |
| `owned` | boolean | **{dotted-circle}** No | Limit by projects explicitly owned by the current user. |
-| `repository_checksum_failed` **(PREMIUM)** | boolean | **{dotted-circle}** No | Limit projects where the repository checksum calculation has failed ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6137) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.2). |
+| `repository_checksum_failed` **(PREMIUM)** | boolean | **{dotted-circle}** No | Limit projects where the repository checksum calculation has failed ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6137) in GitLab 11.2). |
| `repository_storage` | string | **{dotted-circle}** No | Limit results to projects stored on `repository_storage`. _(admins only)_ |
| `search_namespaces` | boolean | **{dotted-circle}** No | Include ancestor namespaces when matching search criteria. Default is `false`. |
| `search` | string | **{dotted-circle}** No | Return list of projects matching the search criteria. |
@@ -65,7 +65,7 @@ GET /projects
| `statistics` | boolean | **{dotted-circle}** No | Include project statistics. Only available to Reporter or higher level role members. |
| `topic` | string | **{dotted-circle}** No | Comma-separated topic names. Limit results to projects that match all of given topics. See `topics` attribute. |
| `visibility` | string | **{dotted-circle}** No | Limit by visibility `public`, `internal`, or `private`. |
-| `wiki_checksum_failed` **(PREMIUM)** | boolean | **{dotted-circle}** No | Limit projects where the wiki checksum calculation has failed ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6137) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.2). |
+| `wiki_checksum_failed` **(PREMIUM)** | boolean | **{dotted-circle}** No | Limit projects where the wiki checksum calculation has failed ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6137) in GitLab 11.2). |
| `with_custom_attributes` | boolean | **{dotted-circle}** No | Include [custom attributes](custom_attributes.md) in response. _(admins only)_ |
| `with_issues_enabled` | boolean | **{dotted-circle}** No | Limit by enabled issues feature. |
| `with_merge_requests_enabled` | boolean | **{dotted-circle}** No | Limit by enabled merge requests feature. |
@@ -2428,7 +2428,7 @@ POST /projects/:id/housekeeping
## Push Rules **(PREMIUM)**
-### Get project push rules **(PREMIUM)**
+### Get project push rules
Get the [push rules](../push_rules/push_rules.md#enabling-push-rules) of a
project.
@@ -2474,7 +2474,7 @@ parameters:
}
```
-### Add project push rule **(PREMIUM)**
+### Add project push rule
Adds a push rule to a specified project.
@@ -2486,7 +2486,7 @@ POST /projects/:id/push_rule
|-----------------------------------------|----------------|------------------------|-------------|
| `author_email_regex` | string | **{dotted-circle}** No | All commit author emails must match this, for example `@my-company.com$`. |
| `branch_name_regex` | string | **{dotted-circle}** No | All branch names must match this, for example `(feature|hotfix)\/*`. |
-| `commit_committer_check` **(PREMIUM)** | boolean | **{dotted-circle}** No | Users can only push commits to this repository that were committed with one of their own verified emails. |
+| `commit_committer_check` | boolean | **{dotted-circle}** No | Users can only push commits to this repository that were committed with one of their own verified emails. |
| `commit_message_negative_regex` | string | **{dotted-circle}** No | No commit message is allowed to match this, for example `ssh\:\/\/`. |
| `commit_message_regex` | string | **{dotted-circle}** No | All commit messages must match this, for example `Fixed \d+\..*`. |
| `deny_delete_tag` | boolean | **{dotted-circle}** No | Deny deleting a tag. |
@@ -2495,9 +2495,9 @@ POST /projects/:id/push_rule
| `max_file_size` | integer | **{dotted-circle}** No | Maximum file size (MB). |
| `member_check` | boolean | **{dotted-circle}** No | Restrict commits by author (email) to existing GitLab users. |
| `prevent_secrets` | boolean | **{dotted-circle}** No | GitLab rejects any files that are likely to contain secrets. |
-| `reject_unsigned_commits` **(PREMIUM)** | boolean | **{dotted-circle}** No | Reject commit when it's not signed through GPG. |
+| `reject_unsigned_commits` | boolean | **{dotted-circle}** No | Reject commit when it's not signed through GPG. |
-### Edit project push rule **(PREMIUM)**
+### Edit project push rule
Edits a push rule for a specified project.
@@ -2509,7 +2509,7 @@ PUT /projects/:id/push_rule
|-----------------------------------------|----------------|------------------------|-------------|
| `author_email_regex` | string | **{dotted-circle}** No | All commit author emails must match this, for example `@my-company.com$`. |
| `branch_name_regex` | string | **{dotted-circle}** No | All branch names must match this, for example `(feature|hotfix)\/*`. |
-| `commit_committer_check` **(PREMIUM)** | boolean | **{dotted-circle}** No | Users can only push commits to this repository that were committed with one of their own verified emails. |
+| `commit_committer_check` | boolean | **{dotted-circle}** No | Users can only push commits to this repository that were committed with one of their own verified emails. |
| `commit_message_negative_regex` | string | **{dotted-circle}** No | No commit message is allowed to match this, for example `ssh\:\/\/`. |
| `commit_message_regex` | string | **{dotted-circle}** No | All commit messages must match this, for example `Fixed \d+\..*`. |
| `deny_delete_tag` | boolean | **{dotted-circle}** No | Deny deleting a tag. |
@@ -2518,7 +2518,7 @@ PUT /projects/:id/push_rule
| `max_file_size` | integer | **{dotted-circle}** No | Maximum file size (MB). |
| `member_check` | boolean | **{dotted-circle}** No | Restrict commits by author (email) to existing GitLab users. |
| `prevent_secrets` | boolean | **{dotted-circle}** No | GitLab rejects any files that are likely to contain secrets. |
-| `reject_unsigned_commits` **(PREMIUM)** | boolean | **{dotted-circle}** No | Reject commits when they are not GPG signed. |
+| `reject_unsigned_commits` | boolean | **{dotted-circle}** No | Reject commits when they are not GPG signed. |
### Delete project push rule
diff --git a/doc/api/protected_environments.md b/doc/api/protected_environments.md
index 9a64e676ad9..82bb1e55e77 100644
--- a/doc/api/protected_environments.md
+++ b/doc/api/protected_environments.md
@@ -7,7 +7,7 @@ type: concepts, howto
# Protected environments API **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30595) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30595) in GitLab 12.8.
## Valid access levels
diff --git a/doc/api/releases/index.md b/doc/api/releases/index.md
index 35bf24c586c..72627783947 100644
--- a/doc/api/releases/index.md
+++ b/doc/api/releases/index.md
@@ -4,7 +4,7 @@ group: Release
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
---
-# Releases API
+# Releases API **(FREE)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41766) in GitLab 11.7.
> - Using this API you can manipulate GitLab [Release](../../user/project/releases/index.md) entries.
@@ -21,7 +21,7 @@ For authentication, the Releases API accepts either:
- A [Personal Access Token](../../user/profile/personal_access_tokens.md) using the
`PRIVATE-TOKEN` header.
-- The [GitLab CI/CD job token](../index.md#gitlab-cicd-job-token) `$CI_JOB_TOKEN` using
+- The [GitLab CI/CD job token](../../ci/jobs/ci_job_token.md) `$CI_JOB_TOKEN` using
the `JOB-TOKEN` header.
## List Releases
@@ -89,8 +89,8 @@ Example response:
"state":"closed",
"created_at":"2019-07-12T19:45:44.256Z",
"updated_at":"2019-07-12T19:45:44.256Z",
- "due_date":"2019-08-16T11:00:00.256Z",
- "start_date":"2019-07-30T12:00:00.256Z",
+ "due_date":"2019-08-16",
+ "start_date":"2019-07-30",
"web_url":"https://gitlab.example.com/root/awesome-app/-/milestones/1",
"issue_stats": {
"total": 98,
@@ -106,8 +106,8 @@ Example response:
"state":"closed",
"created_at":"2019-07-16T14:00:12.256Z",
"updated_at":"2019-07-16T14:00:12.256Z",
- "due_date":"2019-08-16T11:00:00.256Z",
- "start_date":"2019-07-30T12:00:00.256Z",
+ "due_date":"2019-08-16",
+ "start_date":"2019-07-30",
"web_url":"https://gitlab.example.com/root/awesome-app/-/milestones/2",
"issue_stats": {
"total": 24,
@@ -292,8 +292,8 @@ Example response:
"state":"closed",
"created_at":"2019-07-12T19:45:44.256Z",
"updated_at":"2019-07-12T19:45:44.256Z",
- "due_date":"2019-08-16T11:00:00.256Z",
- "start_date":"2019-07-30T12:00:00.256Z",
+ "due_date":"2019-08-16",
+ "start_date":"2019-07-30",
"web_url":"https://gitlab.example.com/root/awesome-app/-/milestones/1",
"issue_stats": {
"total": 98,
@@ -309,8 +309,8 @@ Example response:
"state":"closed",
"created_at":"2019-07-16T14:00:12.256Z",
"updated_at":"2019-07-16T14:00:12.256Z",
- "due_date":"2019-08-16T11:00:00.256Z",
- "start_date":"2019-07-30T12:00:00.256Z",
+ "due_date":"2019-08-16",
+ "start_date":"2019-07-30",
"web_url":"https://gitlab.example.com/root/awesome-app/-/milestones/2",
"issue_stats": {
"total": 24,
@@ -434,8 +434,8 @@ Example response:
"state":"closed",
"created_at":"2019-07-12T19:45:44.256Z",
"updated_at":"2019-07-12T19:45:44.256Z",
- "due_date":"2019-08-16T11:00:00.256Z",
- "start_date":"2019-07-30T12:00:00.256Z",
+ "due_date":"2019-08-16",
+ "start_date":"2019-07-30",
"web_url":"https://gitlab.example.com/root/awesome-app/-/milestones/1",
"issue_stats": {
"total": 99,
@@ -451,8 +451,8 @@ Example response:
"state":"closed",
"created_at":"2019-07-16T14:00:12.256Z",
"updated_at":"2019-07-16T14:00:12.256Z",
- "due_date":"2019-08-16T11:00:00.256Z",
- "start_date":"2019-07-30T12:00:00.256Z",
+ "due_date":"2019-08-16",
+ "start_date":"2019-07-30",
"web_url":"https://gitlab.example.com/root/awesome-app/-/milestones/2",
"issue_stats": {
"total": 24,
@@ -499,7 +499,7 @@ Example response:
### Group milestones **(PREMIUM SELF)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/235391) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/235391) in GitLab 13.5.
Group milestones associated with the project may be specified in the `milestones`
array for [Create a release](#create-a-release) and [Update a release](#update-a-release)
@@ -508,7 +508,7 @@ adding milestones for ancestor groups raises an error.
## Collect release evidence **(PREMIUM SELF)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/199065) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.10.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/199065) in GitLab 12.10.
Create Evidence for an existing Release.
@@ -600,8 +600,8 @@ Example response:
"state":"active",
"created_at":"2019-09-01T13:00:00.256Z",
"updated_at":"2019-09-01T13:00:00.256Z",
- "due_date":"2019-09-20T13:00:00.256Z",
- "start_date":"2019-09-05T12:00:00.256Z",
+ "due_date":"2019-09-20",
+ "start_date":"2019-09-05",
"web_url":"https://gitlab.example.com/root/awesome-app/-/milestones/3",
"issue_stats": {
"opened": 11,
diff --git a/doc/api/releases/links.md b/doc/api/releases/links.md
index 2f8dc363124..c9d183b8351 100644
--- a/doc/api/releases/links.md
+++ b/doc/api/releases/links.md
@@ -4,7 +4,7 @@ group: Release
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
---
-# Release links API
+# Release links API **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41766) in GitLab 11.7.
diff --git a/doc/api/repositories.md b/doc/api/repositories.md
index 9d464c94d99..1c9136d22ac 100644
--- a/doc/api/repositories.md
+++ b/doc/api/repositories.md
@@ -200,7 +200,8 @@ Example response:
"deleted_file": false
}],
"compare_timeout": false,
- "compare_same_ref": false
+ "compare_same_ref": false,
+ "web_url": "https://gitlab.example.com/thedude/gitlab-foss/-/compare/ae73cb07c9eeaf35924a10f713b364d32b2dd34f...0b4bc9a49b562e85de7cc9e834518ea6828729b9"
}
```
@@ -214,7 +215,7 @@ GET /projects/:id/repository/contributors
```
WARNING:
-The `additions` and `deletions` attributes are deprecated [as of GitLab 13.4](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39653), because they [always return `0`](https://gitlab.com/gitlab-org/gitlab/-/issues/233119).
+The `additions` and `deletions` attributes are [deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39653) as of GitLab 13.4, because they [always return `0`](https://gitlab.com/gitlab-org/gitlab/-/issues/233119).
Supported attributes:
@@ -447,6 +448,10 @@ You can set the following variables in this file:
- `template`: a custom template to use for generating the changelog data.
- `categories`: a hash that maps raw category names to the names to use in the
changelog.
+- `include_groups`: a list of group full paths containing users whose
+ contributions should be credited regardless of project membership. The user
+ generating the changelog must have access to each group or the members will
+ not be credited.
Using the default settings, generating a changelog results in a section along
the lines of the following:
@@ -507,7 +512,7 @@ follows:
{% each entries %}
- [{{ title }}]({{ commit.reference }})\
-{% if author.contributor %} by {{ author.reference }}{% end %}\
+{% if author.credit %} by {{ author.reference }}{% end %}\
{% if merge_request %} ([merge request]({{ merge_request.reference }})){% end %}
{% end %}
@@ -597,7 +602,7 @@ template: |
{% each entries %}
- [{{ title }}]({{ commit.reference }})\
- {% if author.contributor %} by {{ author.reference }}{% end %}
+ {% if author.credit %} by {{ author.reference }}{% end %}
{% end %}
@@ -633,8 +638,11 @@ In an entry, the following variables are available (here `foo.bar` means that
- `commit.trailers`: an object containing all the Git trailers that were present
in the commit body.
- `author.reference`: a reference to the commit author (for example, `@alice`).
-- `author.contributor`: a boolean set to `true` when the author is an external
- contributor, otherwise this is set to `false`.
+- `author.contributor`: a boolean set to `true` when the author is not a project
+ member, otherwise `false`.
+- `author.credit`: a boolean set to `true` when `author.contributor` is `true` or
+ when `include_groups` is configured, and the author is a member of one of the
+ groups.
- `merge_request.reference`: a reference to the merge request that first
introduced the change (for example, `gitlab-org/gitlab!50063`).
diff --git a/doc/api/resource_access_tokens.md b/doc/api/resource_access_tokens.md
index 3532cfda47b..fa1e7aace9a 100644
--- a/doc/api/resource_access_tokens.md
+++ b/doc/api/resource_access_tokens.md
@@ -4,7 +4,7 @@ group: Access
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
---
-# Project access tokens API
+# Project access tokens API **(FREE)**
You can read more about [project access tokens](../user/project/settings/project_access_tokens.md).
diff --git a/doc/api/resource_label_events.md b/doc/api/resource_label_events.md
index c5292059c0f..9c05d32c992 100644
--- a/doc/api/resource_label_events.md
+++ b/doc/api/resource_label_events.md
@@ -95,7 +95,7 @@ Parameters:
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/11/resource_label_events/1"
```
-## Epics **(ULTIMATE)**
+## Epics **(PREMIUM)**
### List group epic label events
diff --git a/doc/api/runners.md b/doc/api/runners.md
index 9e48331cdea..bfdf2d49100 100644
--- a/doc/api/runners.md
+++ b/doc/api/runners.md
@@ -4,7 +4,7 @@ group: Runner
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
---
-# Runners API
+# Runners API **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/2640) in GitLab 8.5.
@@ -41,7 +41,6 @@ GET /runners?scope=active
GET /runners?type=project_type
GET /runners?status=active
GET /runners?tag_list=tag1,tag2
-GET /runners?search=gitlab
```
| Attribute | Type | Required | Description |
@@ -50,7 +49,6 @@ GET /runners?search=gitlab
| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` |
| `status` | string | no | The status of runners to show, one of: `active`, `paused`, `online`, `offline` |
| `tag_list` | string array | no | List of the runner's tags |
-| `search` | string | no | The full token or partial description text to match |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/runners"
@@ -85,7 +83,7 @@ Example response:
]
```
-## List all runners
+## List all runners **(FREE SELF)**
Get a list of all runners in the GitLab instance (specific and shared). Access
is restricted to users with `admin` privileges.
@@ -160,6 +158,8 @@ Example response:
]
```
+To view more than the first 20 runners, use [pagination](index.md#pagination).
+
## Get runner's details
Get details of a runner.
@@ -246,8 +246,8 @@ curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab
```
NOTE:
-The `token` attribute in the response was deprecated [in GitLab 12.10](https://gitlab.com/gitlab-org/gitlab/-/issues/214320).
-and removed in [GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/issues/214322).
+The `token` attribute in the response was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/214320) in GitLab 12.10.
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/214322) in GitLab 13.0.
Example response:
@@ -675,3 +675,48 @@ Response:
|-----------|---------------------------------|
| 200 | Credentials are valid |
| 403 | Credentials are invalid |
+
+## Reset instance's runner registration token
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30942) in GitLab 14.3.
+
+Resets the runner registration token for the GitLab instance.
+
+```plaintext
+POST /runners/reset_registration_token
+```
+
+```shell
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
+ "https://gitlab.example.com/api/v4/runners/reset_registration_token"
+```
+
+## Reset project's runner registration token
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30942) in GitLab 14.3.
+
+Resets the runner registration token for a project.
+
+```plaintext
+POST /projects/:id/runners/reset_registration_token
+```
+
+```shell
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
+ "https://gitlab.example.com/api/v4/projects/9/runners/reset_registration_token"
+```
+
+## Reset group's runner registration token
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30942) in GitLab 14.3.
+
+Resets the runner registration token for a group.
+
+```plaintext
+POST /groups/:id/runners/reset_registration_token
+```
+
+```shell
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
+ "https://gitlab.example.com/api/v4/groups/9/runners/reset_registration_token"
+```
diff --git a/doc/api/scim.md b/doc/api/scim.md
index 42580ba65b6..2d9cc148412 100644
--- a/doc/api/scim.md
+++ b/doc/api/scim.md
@@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# SCIM API (SYSTEM ONLY) **(PREMIUM SAAS)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/9388) in GitLab Premium 11.10.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/9388) in GitLab 11.10.
The SCIM API implements the [RFC7644 protocol](https://tools.ietf.org/html/rfc7644). As this API is for
**system** use for SCIM provider integration, it is subject to change without notice.
diff --git a/doc/api/services.md b/doc/api/services.md
index 8daaa532ff4..cf6c5ec511b 100644
--- a/doc/api/services.md
+++ b/doc/api/services.md
@@ -503,7 +503,7 @@ GET /projects/:id/services/emails-on-push
## Confluence service
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/220934) in GitLab 13.2.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/220934) in GitLab 13.2.
Replaces the link to the internal wiki with a link to a Confluence Cloud Workspace.
@@ -659,7 +659,7 @@ PUT /projects/:id/services/hangouts-chat
```
NOTE:
-Specific event parameters (for example, `push_events` flag) were [introduced in v10.4](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/11435)
+Specific event parameters (for example, `push_events` flag) were [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/11435) in GitLab 10.4.
Parameters:
@@ -1119,7 +1119,7 @@ PUT /projects/:id/services/slack
```
NOTE:
-Specific event parameters (for example, `push_events` flag and `push_channel`) were [introduced in v10.4](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/11435)
+Specific event parameters (for example, `push_events` flag and `push_channel`) were [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/11435) in GitLab 10.4.
Parameters:
@@ -1153,6 +1153,8 @@ Parameters:
| `tag_push_events` | boolean | false | Enable notifications for tag push events |
| `wiki_page_channel` | string | false | The name of the channel to receive wiki page events notifications |
| `wiki_page_events` | boolean | false | Enable notifications for wiki page events |
+| `vulnerability_channel` | string | false | **(ULTIMATE)** The name of the channel to receive vulnerability event notifications. |
+| `vulnerability_events` | boolean | false | **(ULTIMATE)** Enable notifications for vulnerability events |
### Delete Slack service
@@ -1229,7 +1231,7 @@ PUT /projects/:id/services/mattermost
```
NOTE:
-Specific event parameters (for example, `push_events` flag and `push_channel`) were [introduced in v10.4](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/11435)
+Specific event parameters (for example, `push_events` flag and `push_channel`) were [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/11435) in GitLab 10.4.
Parameters:
@@ -1250,6 +1252,7 @@ Parameters:
| `confidential_note_events` | boolean | false | Enable notifications for confidential note events |
| `pipeline_events` | boolean | false | Enable notifications for pipeline events |
| `wiki_page_events` | boolean | false | Enable notifications for wiki page events |
+| `vulnerability_events` | boolean | false | **(ULTIMATE)** Enable notifications for vulnerability events |
| `push_channel` | string | false | The name of the channel to receive push events notifications |
| `issue_channel` | string | false | The name of the channel to receive issues events notifications |
| `confidential_issue_channel` | string | false | The name of the channel to receive confidential issues events notifications |
@@ -1259,6 +1262,7 @@ Parameters:
| `tag_push_channel` | string | false | The name of the channel to receive tag push events notifications |
| `pipeline_channel` | string | false | The name of the channel to receive pipeline events notifications |
| `wiki_page_channel` | string | false | The name of the channel to receive wiki page events notifications |
+| `vulnerability_channel` | string | false | **(ULTIMATE)** The name of the channel to receive vulnerability events notifications |
### Delete Mattermost notifications service
@@ -1361,7 +1365,7 @@ GET /projects/:id/services/jenkins
A continuous integration and build server
NOTE:
-This service was [removed in v13.0](https://gitlab.com/gitlab-org/gitlab/-/issues/1600)
+This service was [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/1600) in GitLab 13.0.
### Create/Edit Jenkins CI (Deprecated) service
diff --git a/doc/api/settings.md b/doc/api/settings.md
index d49359b5d43..6b1faa0402f 100644
--- a/doc/api/settings.md
+++ b/doc/api/settings.md
@@ -96,7 +96,7 @@ Example response:
}
```
-Users on GitLab [Premium or Ultimate](https://about.gitlab.com/pricing/) may also see
+Users on [GitLab Premium or Ultimate](https://about.gitlab.com/pricing/) may also see
the `file_template_project_id`, `delayed_project_deletion`, `deletion_adjourned_period`, or the `geo_node_allowed_ips` parameters:
```json
@@ -197,7 +197,7 @@ Example response:
}
```
-Users on GitLab [Premium or Ultimate](https://about.gitlab.com/pricing/) may also see
+Users on [GitLab Premium or Ultimate](https://about.gitlab.com/pricing/) may also see
these parameters:
- `file_template_project_id`
@@ -334,7 +334,7 @@ listed in the descriptions of the relevant settings.
| `issues_create_limit` | integer | no | Max number of issue creation requests per minute per user. Disabled by default.|
| `keep_latest_artifact` | boolean | no | Prevent the deletion of the artifacts from the most recent successful jobs, regardless of the expiry time. Enabled by default. |
| `local_markdown_version` | integer | no | Increase this value when any cached Markdown should be invalidated. |
-| `mailgun_signing_key` | string | no | The Mailgun HTTP webhook signing key for receiving events from webhook |
+| `mailgun_signing_key` | string | no | The Mailgun HTTP webhook signing key for receiving events from webhook. |
| `mailgun_events_enabled` | boolean | no | Enable Mailgun event receiver. |
| `maintenance_mode_message` | string | no | **(PREMIUM)** Message displayed when instance is in maintenance mode. |
| `maintenance_mode` | boolean | no | **(PREMIUM)** When instance is in maintenance mode, non-administrative users can sign in with read-only access and make read-only API requests. |
@@ -386,6 +386,9 @@ listed in the descriptions of the relevant settings.
| `shared_runners_enabled` | boolean | no | (**If enabled, requires:** `shared_runners_text` and `shared_runners_minutes`) Enable shared runners for new projects. |
| `shared_runners_minutes` | integer | required by: `shared_runners_enabled` | **(PREMIUM)** Set the maximum number of pipeline minutes that a group can use on shared runners per month. |
| `shared_runners_text` | string | required by: `shared_runners_enabled` | Shared runners text. |
+| `sidekiq_job_limiter_mode` | string | no | `track` or `compress`. Sets the behavior for [Sidekiq job size limits](../user/admin_area/settings/sidekiq_job_limits.md). Default: 'compress'. |
+| `sidekiq_job_limiter_compression_threshold_bytes` | integer | no | The threshold in bytes at which Sidekiq jobs are compressed before being stored in Redis. Default: 100 000 bytes (100KB). |
+| `sidekiq_job_limiter_limit_bytes` | integer | no | The threshold in bytes at which Sidekiq jobs are rejected. Default: 0 bytes (doesn't reject any job). |
| `sign_in_text` | string | no | Text on the login page. |
| `signin_enabled` | string | no | (Deprecated: Use `password_authentication_enabled_for_web` instead) Flag indicating if password authentication is enabled for the web interface. |
| `signup_enabled` | boolean | no | Enable registration. Default is `true`. |
@@ -412,15 +415,22 @@ listed in the descriptions of the relevant settings.
| `throttle_authenticated_web_enabled` | boolean | no | (**If enabled, requires:** `throttle_authenticated_web_period_in_seconds` and `throttle_authenticated_web_requests_per_period`) Enable authenticated web request rate limit. Helps reduce request volume (for example, from crawlers or abusive bots). |
| `throttle_authenticated_web_period_in_seconds` | integer | required by:<br>`throttle_authenticated_web_enabled` | Rate limit period in seconds. |
| `throttle_authenticated_web_requests_per_period` | integer | required by:<br>`throttle_authenticated_web_enabled` | Max requests per period per user. |
-| `throttle_unauthenticated_enabled` | boolean | no | (**If enabled, requires:** `throttle_unauthenticated_period_in_seconds` and `throttle_unauthenticated_requests_per_period`) Enable unauthenticated request rate limit. Helps reduce request volume (for example, from crawlers or abusive bots). |
-| `throttle_unauthenticated_period_in_seconds` | integer | required by:<br>`throttle_unauthenticated_enabled` | Rate limit period in seconds. |
-| `throttle_unauthenticated_requests_per_period` | integer | required by:<br>`throttle_unauthenticated_enabled` | Max requests per period per IP. |
+| `throttle_unauthenticated_enabled` | boolean | no | ([Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/335300) in GitLab 14.3. Use `throttle_unauthenticated_web_enabled` or `throttle_unauthenticated_api_enabled` instead.) (**If enabled, requires:** `throttle_unauthenticated_period_in_seconds` and `throttle_unauthenticated_requests_per_period`) Enable unauthenticated web request rate limit. Helps reduce request volume (for example, from crawlers or abusive bots). |
+| `throttle_unauthenticated_period_in_seconds` | integer | required by:<br>`throttle_unauthenticated_enabled` | ([Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/335300) in GitLab 14.3. Use `throttle_unauthenticated_web_period_in_seconds` or `throttle_unauthenticated_api_period_in_seconds` instead.) Rate limit period in seconds. |
+| `throttle_unauthenticated_requests_per_period` | integer | required by:<br>`throttle_unauthenticated_enabled` | ([Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/335300) in GitLab 14.3. Use `throttle_unauthenticated_web_requests_per_period` or `throttle_unauthenticated_api_requests_per_period` instead.) Max requests per period per IP. |
+| `throttle_unauthenticated_api_enabled` | boolean | no | (**If enabled, requires:** `throttle_unauthenticated_api_period_in_seconds` and `throttle_unauthenticated_api_requests_per_period`) Enable unauthenticated API request rate limit. Helps reduce request volume (for example, from crawlers or abusive bots). |
+| `throttle_unauthenticated_api_period_in_seconds` | integer | required by:<br>`throttle_unauthenticated_api_enabled` | Rate limit period in seconds. |
+| `throttle_unauthenticated_api_requests_per_period` | integer | required by:<br>`throttle_unauthenticated_api_enabled` | Max requests per period per IP. |
+| `throttle_unauthenticated_web_enabled` | boolean | no | (**If enabled, requires:** `throttle_unauthenticated_web_period_in_seconds` and `throttle_unauthenticated_web_requests_per_period`) Enable unauthenticated web request rate limit. Helps reduce request volume (for example, from crawlers or abusive bots). |
+| `throttle_unauthenticated_web_period_in_seconds` | integer | required by:<br>`throttle_unauthenticated_web_enabled` | Rate limit period in seconds. |
+| `throttle_unauthenticated_web_requests_per_period` | integer | required by:<br>`throttle_unauthenticated_web_enabled` | Max requests per period per IP. |
| `time_tracking_limit_to_hours` | boolean | no | Limit display of time tracking units to hours. Default is `false`. |
| `two_factor_grace_period` | integer | required by: `require_two_factor_authentication` | Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication. |
| `unique_ips_limit_enabled` | boolean | no | (**If enabled, requires:** `unique_ips_limit_per_user` and `unique_ips_limit_time_window`) Limit sign in from multiple IPs. |
| `unique_ips_limit_per_user` | integer | required by: `unique_ips_limit_enabled` | Maximum number of IPs per user. |
| `unique_ips_limit_time_window` | integer | required by: `unique_ips_limit_enabled` | How many seconds an IP is counted towards the limit. |
| `usage_ping_enabled` | boolean | no | Every week GitLab reports license usage back to GitLab, Inc. |
+| `user_deactivation_emails_enabled` | boolean | no | Send an email to users upon account deactivation. |
| `user_default_external` | boolean | no | Newly registered users are external by default. |
| `user_default_internal_regex` | string | no | Specify an email address regex pattern to identify default internal users. |
| `user_oauth_applications` | boolean | no | Allow users to register any application to use GitLab as an OAuth provider. |
diff --git a/doc/api/statistics.md b/doc/api/statistics.md
index a57838e6496..75dfa0de705 100644
--- a/doc/api/statistics.md
+++ b/doc/api/statistics.md
@@ -4,7 +4,7 @@ group: Access
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
---
-# Application statistics API
+# Application statistics API **(FREE SELF)**
## Get current application statistics
diff --git a/doc/api/status_checks.md b/doc/api/status_checks.md
index 25ccd5d767a..0c72ee37348 100644
--- a/doc/api/status_checks.md
+++ b/doc/api/status_checks.md
@@ -42,9 +42,9 @@ GET /projects/:id/merge_requests/:merge_request_iid/status_checks
]
```
-## Set approval status of an external status check
+## Set status of an external status check
-For a single merge request, use the API to inform GitLab that a merge request has been approved by an external service.
+For a single merge request, use the API to inform GitLab that a merge request has passed a check by an external service.
```plaintext
POST /projects/:id/merge_requests/:merge_request_iid/status_check_responses
@@ -62,7 +62,7 @@ POST /projects/:id/merge_requests/:merge_request_iid/status_check_responses
NOTE:
`sha` must be the SHA at the `HEAD` of the merge request's source branch.
-## Get project external status checks **(ULTIMATE)**
+## Get project external status checks
You can request information about a project's external status checks using the following endpoint:
@@ -97,7 +97,7 @@ GET /projects/:id/external_status_checks
]
```
-## Create external status check **(ULTIMATE)**
+## Create external status check
You can create a new external status check for a project using the following endpoint:
@@ -116,7 +116,7 @@ defined external service. This includes confidential merge requests.
| `external_url` | string | yes | URL of status check resource |
| `protected_branch_ids` | `array<Integer>` | no | IDs of protected branches to scope the rule by |
-## Delete external status check **(ULTIMATE)**
+## Delete external status check
You can delete an external status check for a project using the following endpoint:
@@ -129,7 +129,7 @@ DELETE /projects/:id/external_status_checks/:check_id
| `rule_id` | integer | yes | ID of an status check |
| `id` | integer | yes | ID of a project |
-## Update external status check **(ULTIMATE)**
+## Update external status check
You can update an existing external status check for a project using the following endpoint:
diff --git a/doc/api/system_hooks.md b/doc/api/system_hooks.md
index 39a3ccb2bc3..3587016ac6b 100644
--- a/doc/api/system_hooks.md
+++ b/doc/api/system_hooks.md
@@ -4,13 +4,13 @@ group: Integrations
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
---
-# System hooks API
+# System hooks API **(FREE SELF)**
All methods require administrator authorization.
You can configure the URL endpoint of the system hooks from the GitLab user interface:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. Select **System Hooks** (`/admin/hooks`).
Read more about [system hooks](../system_hooks/system_hooks.md).
diff --git a/doc/api/templates/dockerfiles.md b/doc/api/templates/dockerfiles.md
index 2d7e926561f..5f862201571 100644
--- a/doc/api/templates/dockerfiles.md
+++ b/doc/api/templates/dockerfiles.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
-# Dockerfiles API
+# Dockerfiles API **(FREE)**
GitLab provides an API endpoint for instance-level Dockerfile templates.
Default templates are defined at
diff --git a/doc/api/templates/gitignores.md b/doc/api/templates/gitignores.md
index f1bf8120574..71b791de16a 100644
--- a/doc/api/templates/gitignores.md
+++ b/doc/api/templates/gitignores.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
-# .gitignore API
+# .gitignore API **(FREE)**
In GitLab, the `/gitignores` endpoint returns a list of Git `.gitignore` templates. For more information,
see the [Git documentation for `.gitignore`](https://git-scm.com/docs/gitignore).
diff --git a/doc/api/templates/gitlab_ci_ymls.md b/doc/api/templates/gitlab_ci_ymls.md
index 82abe598cf6..abed008218c 100644
--- a/doc/api/templates/gitlab_ci_ymls.md
+++ b/doc/api/templates/gitlab_ci_ymls.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
-# GitLab CI YMLs API
+# GitLab CI YMLs API **(FREE)**
In GitLab, there is an API endpoint available to work with GitLab CI/CD YMLs. For more
information on CI/CD pipeline configuration in GitLab, see the
diff --git a/doc/api/templates/licenses.md b/doc/api/templates/licenses.md
index e7eaa6eb3e0..adba4f75255 100644
--- a/doc/api/templates/licenses.md
+++ b/doc/api/templates/licenses.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
-# Licenses API
+# Licenses API **(FREE)**
In GitLab, there is an API endpoint available for working with various open
source license templates. For more information on the terms of various
diff --git a/doc/api/usage_data.md b/doc/api/usage_data.md
index 00d87c89faf..f244c681086 100644
--- a/doc/api/usage_data.md
+++ b/doc/api/usage_data.md
@@ -11,7 +11,7 @@ The Service Data API is associated with [Service Ping](../development/service_pi
## Export metric definitions as a single YAML file
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57270) in GitLab 13.11.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57270) in GitLab 13.11.
Export all metric definitions as a single YAML file, similar to the [Metrics Dictionary](https://gitlab-org.gitlab.io/growth/product-intelligence/metric-dictionary), for easier importing.
@@ -37,7 +37,7 @@ Example response:
product_group: group::global search
product_category: global_search
value_type: number
- status: data_available
+ status: active
time_frame: 28d
data_source: redis_hll
distribution:
diff --git a/doc/api/users.md b/doc/api/users.md
index 6ba751bd292..dfd2f6cc87d 100644
--- a/doc/api/users.md
+++ b/doc/api/users.md
@@ -4,7 +4,7 @@ group: Access
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
---
-# Users API
+# Users API **(FREE)**
## List users
@@ -39,7 +39,7 @@ GET /users
]
```
-You can also search for users by name or primary email using `?search=`. For example. `/users?search=John`.
+You can also search for users by name, username, primary email, or secondary email, by using `?search=`. For example. `/users?search=John`.
In addition, you can lookup users by username:
@@ -124,7 +124,6 @@ GET /users
"created_at": "2012-05-23T08:00:58Z",
"is_admin": false,
"bio": "",
- "bio_html": "",
"location": null,
"skype": "",
"linkedin": "",
@@ -164,7 +163,6 @@ GET /users
"created_at": "2012-05-23T08:01:01Z",
"is_admin": false,
"bio": "",
- "bio_html": "",
"location": null,
"skype": "",
"linkedin": "",
@@ -191,7 +189,7 @@ GET /users
]
```
-Users on GitLab [Premium or higher](https://about.gitlab.com/pricing/) also see the `shared_runners_minutes_limit`, `extra_shared_runners_minutes_limit`, `is_auditor`, and `using_license_seat` parameters.
+Users on [GitLab Premium or higher](https://about.gitlab.com/pricing/) also see the `shared_runners_minutes_limit`, `extra_shared_runners_minutes_limit`, `is_auditor`, and `using_license_seat` parameters.
```json
[
@@ -207,7 +205,7 @@ Users on GitLab [Premium or higher](https://about.gitlab.com/pricing/) also see
]
```
-Users on GitLab [Premium or higher](https://about.gitlab.com/pricing/) also see
+Users on [GitLab Premium or higher](https://about.gitlab.com/pricing/) also see
the `group_saml` provider option and `provisioned_by_group_id` parameter:
```json
@@ -261,7 +259,7 @@ GET /users?with_custom_attributes=true
## Single user
-Get a single user.
+Get a single user. This endpoint can be accessed without authentication.
### For user
@@ -283,7 +281,6 @@ Parameters:
"web_url": "http://localhost:3000/john_smith",
"created_at": "2012-05-23T08:00:58Z",
"bio": "",
- "bio_html": "",
"bot": false,
"location": null,
"public_email": "john@example.com",
@@ -322,7 +319,6 @@ Example Responses:
"created_at": "2012-05-23T08:00:58Z",
"is_admin": false,
"bio": "",
- "bio_html": "",
"location": null,
"public_email": "john@example.com",
"skype": "",
@@ -361,7 +357,7 @@ Example Responses:
NOTE:
The `plan` and `trial` parameters are only available on GitLab Enterprise Edition.
-Users on GitLab [Premium or higher](https://about.gitlab.com/pricing/) also see
+Users on [GitLab Premium or higher](https://about.gitlab.com/pricing/) also see
the `shared_runners_minutes_limit`, `is_auditor`, and `extra_shared_runners_minutes_limit` parameters.
```json
@@ -375,7 +371,7 @@ the `shared_runners_minutes_limit`, `is_auditor`, and `extra_shared_runners_minu
}
```
-Users on GitLab.com [Premium or higher](https://about.gitlab.com/pricing/) also
+Users on [GitLab.com Premium or higher](https://about.gitlab.com/pricing/) also
see the `group_saml` option and `provisioned_by_group_id` parameter:
```json
@@ -551,7 +547,6 @@ GET /user
"web_url": "http://localhost:3000/john_smith",
"created_at": "2012-05-23T08:00:58Z",
"bio": "",
- "bio_html": "",
"location": null,
"public_email": "john@example.com",
"skype": "",
@@ -601,7 +596,6 @@ GET /user
"created_at": "2012-05-23T08:00:58Z",
"is_admin": false,
"bio": "",
- "bio_html": "",
"location": null,
"public_email": "john@example.com",
"skype": "",
@@ -633,7 +627,7 @@ GET /user
}
```
-Users on GitLab [Premium or higher](https://about.gitlab.com/pricing/) also see these
+Users on [GitLab Premium or higher](https://about.gitlab.com/pricing/) also see these
parameters:
- `shared_runners_minutes_limit`
@@ -668,7 +662,7 @@ Example response:
## Get the status of a user
-Get the status of a user.
+Get the status of a user. This endpoint can be accessed without authentication.
```plaintext
GET /users/:id_or_username/status
@@ -812,7 +806,7 @@ Example response:
### Followers and following
-Get the followers of a user.
+Get the followers of a user. This endpoint can be accessed without authentication.
```plaintext
GET /users/:id/followers
@@ -1467,6 +1461,46 @@ Returns:
- `404 User Not Found` if the user cannot be found.
- `403 Forbidden` if the user cannot be activated because they are blocked by an administrator or by LDAP synchronization.
+## Ban user
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/327354) in GitLab 14.3.
+
+Bans the specified user. Available only for admin.
+
+```plaintext
+POST /users/:id/ban
+```
+
+Parameters:
+
+- `id` (required) - ID of specified user
+
+Returns:
+
+- `201 OK` on success.
+- `404 User Not Found` if user cannot be found.
+- `403 Forbidden` when trying to ban a user that is not active.
+
+## Unban user
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/327354) in GitLab 14.3.
+
+Unbans the specified user. Available only for admin.
+
+```plaintext
+POST /users/:id/unban
+```
+
+Parameters:
+
+- `id` (required) - ID of specified user
+
+Returns:
+
+- `201 OK` on success.
+- `404 User Not Found` if the user cannot be found.
+- `403 Forbidden` when trying to unban a user that is not banned.
+
### Get user contribution events
Please refer to the [Events API documentation](events.md#get-user-contribution-events)
@@ -1564,6 +1598,45 @@ Example Responses:
{ "message": "The user you are trying to approve is not pending approval" }
```
+## Reject user
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/339925) in GitLab 14.3.
+
+Rejects specified user that is [pending approval](../user/admin_area/moderate_users.md#users-pending-approval). Available only for administrators.
+
+```plaintext
+POST /users/:id/reject
+```
+
+Parameters:
+
+- `id` (required) - ID of specified user
+
+```shell
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/users/42/reject"
+```
+
+Returns:
+
+- `200 OK` on success.
+- `403 Forbidden` if not authenticated as an administrator.
+- `404 User Not Found` if user cannot be found.
+- `409 Conflict` if user is not pending approval.
+
+Example Responses:
+
+```json
+{ "message": "Success" }
+```
+
+```json
+{ "message": "404 User Not Found" }
+```
+
+```json
+{ "message": "User does not have a pending request" }
+```
+
## Get an impersonation token of a user
> Requires admin permissions.
diff --git a/doc/api/v3_to_v4.md b/doc/api/v3_to_v4.md
index 8875e4daa87..3fba95c1fb3 100644
--- a/doc/api/v3_to_v4.md
+++ b/doc/api/v3_to_v4.md
@@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# API V3 to API V4
WARNING:
-The GitLab API v3 was removed in [GitLab 11.0](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/36819).
+The GitLab API v3 was [removed](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/36819) in GitLab 11.0.
For information about the current version of the GitLab API, read the [API documentation](index.md).
diff --git a/doc/api/version.md b/doc/api/version.md
index b23930e70f9..b076993f00e 100644
--- a/doc/api/version.md
+++ b/doc/api/version.md
@@ -4,7 +4,7 @@ group: Integrations
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
---
-# Version API
+# Version API **(FREE)**
> Introduced in GitLab 8.13.
diff --git a/doc/api/vulnerabilities.md b/doc/api/vulnerabilities.md
index b18a837de26..1c6f7a760e6 100644
--- a/doc/api/vulnerabilities.md
+++ b/doc/api/vulnerabilities.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Vulnerabilities API **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10242) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10242) in GitLab 12.6.
NOTE:
The former Vulnerabilities API was renamed to Vulnerability Findings API
diff --git a/doc/api/vulnerability_exports.md b/doc/api/vulnerability_exports.md
index 4240d363ff0..9395a4ee5de 100644
--- a/doc/api/vulnerability_exports.md
+++ b/doc/api/vulnerability_exports.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Vulnerability export API **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/197494) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.10. [Updated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30397) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/197494) in GitLab 12.10. [Updated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30397) in GitLab 13.0.
WARNING:
This API is in an alpha stage and considered unstable.
@@ -198,7 +198,7 @@ The response is `404 Not Found` if the vulnerability export is not finished yet
Example response:
```csv
-Group Name,Project Name,Scanner Type,Scanner Name,Status,Vulnerability,Details,Additional Info,Severity,CVE,CWE,Other Identifiers
+Group Name,Project Name,Tool,Scanner Name,Status,Vulnerability,Details,Additional Info,Severity,CVE,CWE,Other Identifiers
Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2017-16997 in glibc,,CVE-2017-16997 in glibc,critical,CVE-2017-16997
Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2017-18269 in glibc,,CVE-2017-18269 in glibc,critical,CVE-2017-18269
Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2018-1000001 in glibc,,CVE-2018-1000001 in glibc,high,CVE-2018-1000001
diff --git a/doc/api/vulnerability_findings.md b/doc/api/vulnerability_findings.md
index c7f045a67a0..dfc6074a1aa 100644
--- a/doc/api/vulnerability_findings.md
+++ b/doc/api/vulnerability_findings.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Vulnerability Findings API **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/19029) in GitLab Ultimate 12.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/19029) in GitLab 12.5.
NOTE:
This API resource is renamed from Vulnerabilities to Vulnerability Findings because the Vulnerabilities are reserved
diff --git a/doc/architecture/blueprints/composable_codebase_using_rails_engines/index.md b/doc/architecture/blueprints/composable_codebase_using_rails_engines/index.md
index 92717dc1fe9..095eaaec23f 100644
--- a/doc/architecture/blueprints/composable_codebase_using_rails_engines/index.md
+++ b/doc/architecture/blueprints/composable_codebase_using_rails_engines/index.md
@@ -6,6 +6,9 @@ comments: false
description: 'Making a GitLab codebase composable - allowing to run parts of the application'
---
+NOTE:
+Due to our focus on improving the overall availability of GitLab.com and reducing tech debt, we do not have capacity to act on this blueprint. We will re-evaluate in Q1-FY23.
+
# Composable GitLab codebase - using Rails Engines
The one of the major risks of a single codebase is an infinite growth of the whole
diff --git a/doc/architecture/blueprints/container_registry_metadata_database/index.md b/doc/architecture/blueprints/container_registry_metadata_database/index.md
index b71517de061..f52635baf7b 100644
--- a/doc/architecture/blueprints/container_registry_metadata_database/index.md
+++ b/doc/architecture/blueprints/container_registry_metadata_database/index.md
@@ -77,12 +77,12 @@ The single entrypoint for the registry is the [HTTP API](https://gitlab.com/gitl
| Operation | UI | Background | Observations |
| ------------------------------------------------------------ | ------------------ | ------------------------ | ------------------------------------------------------------ |
-| [Check API version](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#api-version-check) | :heavy_check_mark: | :heavy_check_mark: | Used globally to ensure that the registry supports the Docker Distribution V2 API, as well as for identifying whether GitLab Rails is talking to the GitLab Container Registry or a third-party one (used to toggle features only available in the former). |
-| [List repository tags](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#listing-image-tags) | :heavy_check_mark: | :heavy_check_mark: | Used to list and show tags in the UI. Used to list tags in the background for [cleanup policies](../../../user/packages/container_registry/#cleanup-policy) and [Geo replication](../../../administration/geo/replication/docker_registry.md). |
-| [Check if manifest exists](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#existing-manifests) | :heavy_check_mark: | :heavy_multiplication_x: | Used to get the digest of a manifest by tag. This is then used to pull the manifest and show the tag details in the UI. |
-| [Pull manifest](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#pulling-an-image-manifest) | :heavy_check_mark: | :heavy_multiplication_x: | Used to show the image size and the manifest digest in the tag details UI. |
-| [Pull blob](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#pulling-a-layer) | :heavy_check_mark: | :heavy_multiplication_x: | Used to show the configuration digest and the creation date in the tag details UI. |
-| [Delete tag](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#deleting-a-tag) | :heavy_check_mark: | :heavy_check_mark: | Used to delete a tag from the UI and in background (cleanup policies). |
+| [Check API version](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#api-version-check) | **{check-circle}** Yes | **{check-circle}** Yes | Used globally to ensure that the registry supports the Docker Distribution V2 API, as well as for identifying whether GitLab Rails is talking to the GitLab Container Registry or a third-party one (used to toggle features only available in the former). |
+| [List repository tags](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#listing-image-tags) | **{check-circle}** Yes | **{check-circle}** Yes | Used to list and show tags in the UI. Used to list tags in the background for [cleanup policies](../../../user/packages/container_registry/#cleanup-policy) and [Geo replication](../../../administration/geo/replication/docker_registry.md). |
+| [Check if manifest exists](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#existing-manifests) | **{check-circle}** Yes | **{dotted-circle}** No | Used to get the digest of a manifest by tag. This is then used to pull the manifest and show the tag details in the UI. |
+| [Pull manifest](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#pulling-an-image-manifest) | **{check-circle}** Yes | **{dotted-circle}** No | Used to show the image size and the manifest digest in the tag details UI. |
+| [Pull blob](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#pulling-a-layer) | **{check-circle}** Yes | **{dotted-circle}** No | Used to show the configuration digest and the creation date in the tag details UI. |
+| [Delete tag](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#deleting-a-tag) | **{check-circle}** Yes | **{check-circle}** Yes | Used to delete a tag from the UI and in background (cleanup policies). |
A valid authentication token is generated in GitLab Rails and embedded in all these requests before sending them to the registry.
@@ -211,22 +211,22 @@ This is a list of all the registry HTTP API operations and how they depend on th
| Operation | Method | Path | Requires Database | Requires Storage | Used by GitLab Rails * |
|--------------------------------------------------------------------------------------------------------------------------------|----------|-----------------------------------------|-------------------|------------------|------------------------|
-| [Check API version](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#api-version-check) | `GET` | `/v2/` | ✖ | ✖ | ✔ |
-| [List repositories](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#listing-repositories) | `GET` | `/v2/_catalog` | ✔ | ✖ | ✖ |
-| [List repository tags](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#listing-image-tags) | `GET` | `/v2/<name>/tags/list` | ✔ | ✖ | ✔ |
-| [Delete tag](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#deleting-a-tag) | `DELETE` | `/v2/<name>/tags/reference/<reference>` | ✔ | ✖ | ✔ |
-| [Check if manifest exists](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#existing-manifests) | `HEAD` | `/v2/<name>/manifests/<reference>` | ✔ | ✖ | ✔ |
-| [Pull manifest](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#pulling-an-image-manifest) | `GET` | `/v2/<name>/manifests/<reference>` | ✔ | ✖ | ✔ |
-| [Push manifest](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#pushing-an-image-manifest) | `PUT` | `/v2/<name>/manifests/<reference>` | ✔ | ✖ | ✖ |
-| [Delete manifest](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#deleting-an-image) | `DELETE` | `/v2/<name>/manifests/<reference>` | ✔ | ✖ | ✖ |
-| [Check if blob exists](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#existing-layers) | `HEAD` | `/v2/<name>/blobs/<digest>` | ✔ | ✖ | ✖ |
-| [Pull blob](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#fetch-blob) | `GET` | `/v2/<name>/blobs/<digest>` | ✔ | ✔ | ✔ |
-| [Delete blob](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#delete-blob) | `DELETE` | `/v2/<name>/blobs/<digest>` | ✔ | ✖ | ✖ |
-| [Start blob upload](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#starting-an-upload) | `POST` | `/v2/<name>/blobs/uploads/` | ✔ | ✔ | ✖ |
-| [Check blob upload status](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#get-blob-upload) | `GET` | `/v2/<name>/blobs/uploads/<uuid>` | ✔ | ✔ | ✖ |
-| [Push blob chunk](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#chunked-upload-1) | `PATCH` | `/v2/<name>/blobs/uploads/<uuid>` | ✔ | ✔ | ✖ |
-| [Complete blob upload](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#put-blob-upload) | `PUT` | `/v2/<name>/blobs/uploads/<uuid>` | ✔ | ✔ | ✖ |
-| [Cancel blob upload](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#canceling-an-upload) | `DELETE` | `/v2/<name>/blobs/uploads/<uuid>` | ✔ | ✔ | ✖ |
+| [Check API version](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#api-version-check) | `GET` | `/v2/` | **{dotted-circle}** No | **{dotted-circle}** No | **{check-circle}** Yes |
+| [List repositories](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#listing-repositories) | `GET` | `/v2/_catalog` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No |
+| [List repository tags](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#listing-image-tags) | `GET` | `/v2/<name>/tags/list` | **{check-circle}** Yes | **{dotted-circle}** No | **{check-circle}** Yes |
+| [Delete tag](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#deleting-a-tag) | `DELETE` | `/v2/<name>/tags/reference/<reference>` | **{check-circle}** Yes | **{dotted-circle}** No | **{check-circle}** Yes |
+| [Check if manifest exists](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#existing-manifests) | `HEAD` | `/v2/<name>/manifests/<reference>` | **{check-circle}** Yes | **{dotted-circle}** No | **{check-circle}** Yes |
+| [Pull manifest](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#pulling-an-image-manifest) | `GET` | `/v2/<name>/manifests/<reference>` | **{check-circle}** Yes | **{dotted-circle}** No | **{check-circle}** Yes |
+| [Push manifest](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#pushing-an-image-manifest) | `PUT` | `/v2/<name>/manifests/<reference>` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No |
+| [Delete manifest](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#deleting-an-image) | `DELETE` | `/v2/<name>/manifests/<reference>` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No |
+| [Check if blob exists](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#existing-layers) | `HEAD` | `/v2/<name>/blobs/<digest>` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No |
+| [Pull blob](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#fetch-blob) | `GET` | `/v2/<name>/blobs/<digest>` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes |
+| [Delete blob](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#delete-blob) | `DELETE` | `/v2/<name>/blobs/<digest>` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No |
+| [Start blob upload](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#starting-an-upload) | `POST` | `/v2/<name>/blobs/uploads/` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No |
+| [Check blob upload status](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#get-blob-upload) | `GET` | `/v2/<name>/blobs/uploads/<uuid>` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No |
+| [Push blob chunk](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#chunked-upload-1) | `PATCH` | `/v2/<name>/blobs/uploads/<uuid>` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No |
+| [Complete blob upload](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#put-blob-upload) | `PUT` | `/v2/<name>/blobs/uploads/<uuid>` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No |
+| [Cancel blob upload](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#canceling-an-upload) | `DELETE` | `/v2/<name>/blobs/uploads/<uuid>` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No |
`*` Please refer to the [list of interactions between registry and Rails](#from-gitlab-rails-to-registry) to know why and how.
diff --git a/doc/architecture/blueprints/database/scalability/patterns/img/db_terminology_v14_2.png b/doc/architecture/blueprints/database/scalability/patterns/img/db_terminology_v14_2.png
deleted file mode 100644
index 85ba1360f06..00000000000
--- a/doc/architecture/blueprints/database/scalability/patterns/img/db_terminology_v14_2.png
+++ /dev/null
Binary files differ
diff --git a/doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_licenses_calls_v14_2.png b/doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_licenses_calls_v14_2.png
index f6ae995391c..ec0f6470bdd 100644
--- a/doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_licenses_calls_v14_2.png
+++ b/doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_licenses_calls_v14_2.png
Binary files differ
diff --git a/doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_licenses_fixed_v14_2.png b/doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_licenses_fixed_v14_2.png
index dcfaae230d3..40abdd1e238 100644
--- a/doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_licenses_fixed_v14_2.png
+++ b/doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_licenses_fixed_v14_2.png
Binary files differ
diff --git a/doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_readwriteratio_v14_2.png b/doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_readwriteratio_v14_2.png
index 9b85f814bc1..0aa14675b5d 100644
--- a/doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_readwriteratio_v14_2.png
+++ b/doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_readwriteratio_v14_2.png
Binary files differ
diff --git a/doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_subscriptions_reads_v14_2.png b/doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_subscriptions_reads_v14_2.png
index 4f448841e48..66f5ec4bbc1 100644
--- a/doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_subscriptions_reads_v14_2.png
+++ b/doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_subscriptions_reads_v14_2.png
Binary files differ
diff --git a/doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_subscriptions_writes_v14_2.png b/doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_subscriptions_writes_v14_2.png
index e4f5756051f..c1d0193ccf0 100644
--- a/doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_subscriptions_writes_v14_2.png
+++ b/doc/architecture/blueprints/database/scalability/patterns/img/read_mostly_subscriptions_writes_v14_2.png
Binary files differ
diff --git a/doc/ci/caching/index.md b/doc/ci/caching/index.md
index 87c7af2030d..29a03fe06ab 100644
--- a/doc/ci/caching/index.md
+++ b/doc/ci/caching/index.md
@@ -1,6 +1,6 @@
---
stage: Verify
-group: Pipeline Execution
+group: Pipeline Authoring
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
type: index, concepts, howto
---
@@ -37,15 +37,15 @@ can't link to files outside it.
- Define artifacts per job.
- Subsequent jobs in later stages of the same pipeline can use artifacts.
- Different projects cannot share artifacts.
-
-Artifacts expire after 30 days unless you define an [expiration time](../yaml/index.md#artifactsexpire_in).
-Use [dependencies](../yaml/index.md#dependencies) to control which jobs fetch the artifacts.
+- Artifacts expire after 30 days by default. You can define a custom [expiration time](../yaml/index.md#artifactsexpire_in).
+- The latest artifacts do not expire if [keep latest artifacts](../pipelines/job_artifacts.md#keep-artifacts-from-most-recent-successful-jobs) is enabled.
+- Use [dependencies](../yaml/index.md#dependencies) to control which jobs fetch the artifacts.
## Good caching practices
To ensure maximum availability of the cache, do one or more of the following:
-- [Tag your runners](../runners/configure_runners.md#use-tags-to-limit-the-number-of-jobs-using-the-runner) and use the tag on jobs
+- [Tag your runners](../runners/configure_runners.md#use-tags-to-control-which-jobs-a-runner-can-run) and use the tag on jobs
that share the cache.
- [Use runners that are only available to a particular project](../runners/runners_scope.md#prevent-a-specific-runner-from-being-enabled-for-other-projects).
- [Use a `key`](../yaml/index.md#cachekey) that fits your workflow. For example,
diff --git a/doc/ci/chatops/index.md b/doc/ci/chatops/index.md
index a461147661c..a2d9cf9054d 100644
--- a/doc/ci/chatops/index.md
+++ b/doc/ci/chatops/index.md
@@ -7,8 +7,8 @@ type: index, concepts, howto
# GitLab ChatOps **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/4466) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.6.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/24780) to [GitLab Free](https://about.gitlab.com/pricing/) in 11.9.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/4466) in GitLab Ultimate 10.6.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/24780) to GitLab Free in 11.9.
GitLab ChatOps provides a method to interact with CI/CD jobs through chat services
like Slack. Many organizations' discussion, collaboration, and troubleshooting takes
diff --git a/doc/ci/ci_cd_for_external_repos/github_integration.md b/doc/ci/ci_cd_for_external_repos/github_integration.md
index 60a939496d6..70a9c8fc775 100644
--- a/doc/ci/ci_cd_for_external_repos/github_integration.md
+++ b/doc/ci/ci_cd_for_external_repos/github_integration.md
@@ -29,7 +29,7 @@ repositories:
1. In GitHub, create a token:
1. Open <https://github.com/settings/tokens/new>.
- 1. Create a **Personal Access Token**.
+ 1. Create a **Personal Access Token**.
1. Enter a **Token description** and update the scope to allow
`repo` and `admin:repo_hook` so that GitLab can access your project,
update commit statuses, and create a web hook to notify GitLab of new commits.
@@ -57,7 +57,7 @@ To manually enable GitLab CI/CD for your repository:
1. In GitHub, create a token:
1. Open <https://github.com/settings/tokens/new>.
- 1. Create a **Personal Access Token**.
+ 1. Create a **Personal Access Token**.
1. Enter a **Token description** and update the scope to allow
`repo` so that GitLab can access your project and update commit statuses.
1. In GitLab, create a project:
diff --git a/doc/ci/ci_cd_for_external_repos/index.md b/doc/ci/ci_cd_for_external_repos/index.md
index 27c808791e5..365e2ee31de 100644
--- a/doc/ci/ci_cd_for_external_repos/index.md
+++ b/doc/ci/ci_cd_for_external_repos/index.md
@@ -7,7 +7,7 @@ type: index, howto
# GitLab CI/CD for external repositories **(PREMIUM)**
->[Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/4642) in [GitLab Premium](https://about.gitlab.com/pricing/) 10.6.
+>[Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/4642) in GitLab 10.6.
GitLab CI/CD can be used with:
@@ -38,7 +38,7 @@ To connect to an external repository:
## Pipelines for external pull requests
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/65139) in GitLab Premium 12.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/65139) in GitLab 12.3.
When using GitLab CI/CD with an [external repository on GitHub](github_integration.md),
it's possible to run a pipeline in the context of a Pull Request.
diff --git a/doc/ci/cloud_deployment/index.md b/doc/ci/cloud_deployment/index.md
index a4b4fd9fd16..25b87366a30 100644
--- a/doc/ci/cloud_deployment/index.md
+++ b/doc/ci/cloud_deployment/index.md
@@ -95,7 +95,7 @@ GitLab provides a series of [CI templates that you can include in your project](
To automate deployments of your application to your [Amazon Elastic Container Service](https://aws.amazon.com/ecs/) (AWS ECS)
cluster, you can `include` the `AWS/Deploy-ECS.gitlab-ci.yml` template in your `.gitlab-ci.yml` file.
-GitLab also provides [Docker images](https://gitlab.com/gitlab-org/cloud-deploy/-/tree/master/aws) that can be used in your `gitlab-ci.yml` file to simplify working with AWS:
+GitLab also provides [Docker images](https://gitlab.com/gitlab-org/cloud-deploy/-/tree/master/aws) that can be used in your `.gitlab-ci.yml` file to simplify working with AWS:
- Use `registry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest` to use AWS CLI commands.
- Use `registry.gitlab.com/gitlab-org/cloud-deploy/aws-ecs:latest` to deploy your application to AWS ECS.
diff --git a/doc/ci/directed_acyclic_graph/index.md b/doc/ci/directed_acyclic_graph/index.md
index d965d4b83f9..11ba1e40b3e 100644
--- a/doc/ci/directed_acyclic_graph/index.md
+++ b/doc/ci/directed_acyclic_graph/index.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
-# Directed Acyclic Graph
+# Directed Acyclic Graph **(FREE)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/47063) in GitLab 12.2.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/206902) in GitLab 12.10.
diff --git a/doc/ci/docker/using_docker_build.md b/doc/ci/docker/using_docker_build.md
index c56bc9a4dc8..d5adedc611c 100644
--- a/doc/ci/docker/using_docker_build.md
+++ b/doc/ci/docker/using_docker_build.md
@@ -23,7 +23,7 @@ To enable Docker commands for your CI/CD jobs, you can use:
- [Docker socket binding](#use-docker-socket-binding)
If you don't want to execute a runner in privileged mode,
-but want to use `docker build`, you can also [use kaniko](using_kaniko.md).
+but want to use `docker build`, you can also use [`kaniko`](using_kaniko.md) or [`buildah`](https://github.com/containers/buildah).
If you are using shared runners on GitLab.com,
[learn more about how these runners are configured](../runners/index.md).
diff --git a/doc/ci/enable_or_disable_ci.md b/doc/ci/enable_or_disable_ci.md
index 421bca9e324..65c907b8e7b 100644
--- a/doc/ci/enable_or_disable_ci.md
+++ b/doc/ci/enable_or_disable_ci.md
@@ -7,34 +7,33 @@ type: howto
# How to enable or disable GitLab CI/CD **(FREE)**
-To effectively use GitLab CI/CD, you need:
+To use GitLab CI/CD, you need:
- A valid [`.gitlab-ci.yml`](yaml/index.md) file present at the root directory
of your project.
-- A [runner](runners/index.md) properly set up.
+- A [runner](runners/index.md) ready to run jobs.
You can read our [quick start guide](quick_start/index.md) to get you started.
-If you are using an external CI/CD server like Jenkins or Drone CI, it is advised
-to disable GitLab CI/CD in order to not have any conflicts with the commits status
+If you use an external CI/CD server like Jenkins or Drone CI, you can
+disable GitLab CI/CD to avoid conflicts with the commits status
API.
-GitLab CI/CD is exposed by using the `/pipelines` and `/jobs` pages of a project.
-Disabling GitLab CI/CD in a project does not delete any previous jobs.
-In fact, the `/pipelines` and `/jobs` pages can still be accessed, although
-it's hidden from the left sidebar menu.
+GitLab CI/CD is enabled by default on all new projects. You can:
-GitLab CI/CD is enabled by default on new installations and can be disabled
-either:
+- Disable GitLab CI/CD [under each project's settings](#enable-cicd-in-a-project).
+- Set GitLab CI/CD to be [disabled in all new projects on an instance](../administration/cicd.md).
-- Individually under each project's settings.
-- Site-wide by modifying the settings in `gitlab.yml` and `gitlab.rb` for source
- and Omnibus installations respectively.
+If you disable GitLab CI/CD in a project:
-This only applies to pipelines run as part of GitLab CI/CD. This doesn't enable or disable
-pipelines that are run from an [external integration](../user/project/integrations/overview.md#integrations-listing).
+- The **CI/CD** item in the left sidebar is removed.
+- The `/pipelines` and `/jobs` pages are no longer available.
+- Existing jobs and pipelines are not deleted. Re-enable CI/CD to access them again.
-## Per-project user setting
+The project or instance settings do not enable or disable pipelines run in an
+[external integration](../user/project/integrations/overview.md#integrations-listing).
+
+## Enable CI/CD in a project
To enable or disable GitLab CI/CD pipelines in your project:
@@ -51,54 +50,6 @@ To enable or disable GitLab CI/CD pipelines in your project:
Press **Save changes** for the settings to take effect.
-## Make GitLab CI/CD disabled by default in new projects
-
-You can set GitLab CI/CD to be disabled by default in all new projects by modifying the settings in:
-
-- `gitlab.yml` for source installations.
-- `gitlab.rb` for Omnibus GitLab installations.
-
-Existing projects that already had CI/CD enabled are unchanged. Also, this setting only changes
-the project default, so project owners can still enable CI/CD in the project settings.
-
-For installations from source:
-
-1. Open `gitlab.yml` with your editor and set `builds` to `false`:
-
- ```yaml
- ## Default project features settings
- default_projects_features:
- issues: true
- merge_requests: true
- wiki: true
- snippets: false
- builds: false
- ```
-
-1. Save the `gitlab.yml` file.
-
-1. Restart GitLab:
-
- ```shell
- sudo service gitlab restart
- ```
-
-For Omnibus GitLab installations:
-
-1. Edit `/etc/gitlab/gitlab.rb` and add this line:
-
- ```ruby
- gitlab_rails['gitlab_default_projects_features_builds'] = false
- ```
-
-1. Save the `/etc/gitlab/gitlab.rb` file.
-
-1. Reconfigure GitLab:
-
- ```shell
- sudo gitlab-ctl reconfigure
- ```
-
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
diff --git a/doc/ci/environments/deployment_safety.md b/doc/ci/environments/deployment_safety.md
index 4e34cc7ce38..1b34b520007 100644
--- a/doc/ci/environments/deployment_safety.md
+++ b/doc/ci/environments/deployment_safety.md
@@ -136,10 +136,10 @@ connect the CD project to your development projects by using [multi-project pipe
A `.gitlab-ci.yml` may contain rules to deploy an application to the production server. This
deployment usually runs automatically after pushing a merge request. To prevent developers from
-changing the `gitlab-ci.yml`, you can define it in a different repository. The configuration can
+changing the `.gitlab-ci.yml`, you can define it in a different repository. The configuration can
reference a file in another project with a completely different set of permissions (similar to
[separating a project for deployments](#separate-project-for-deployments)).
-In this scenario, the `gitlab-ci.yml` is publicly accessible, but can only be edited by users with
+In this scenario, the `.gitlab-ci.yml` is publicly accessible, but can only be edited by users with
appropriate permissions in the other project.
For more information, see [Custom CI/CD configuration path](../pipelines/settings.md#specify-a-custom-cicd-configuration-file).
diff --git a/doc/ci/environments/environments_dashboard.md b/doc/ci/environments/environments_dashboard.md
index ae459b9016c..8ff31827ae7 100644
--- a/doc/ci/environments/environments_dashboard.md
+++ b/doc/ci/environments/environments_dashboard.md
@@ -7,7 +7,7 @@ type: reference
# Environments Dashboard **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3713) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3713) in GitLab 12.5.
The Environments Dashboard provides a cross-project
environment-based view that lets you see the big picture
diff --git a/doc/ci/environments/incremental_rollouts.md b/doc/ci/environments/incremental_rollouts.md
index e473d52f957..bc52fd1f16c 100644
--- a/doc/ci/environments/incremental_rollouts.md
+++ b/doc/ci/environments/incremental_rollouts.md
@@ -43,7 +43,7 @@ number of pods that are defined for the deployment, which are configured when th
cluster is created.
For example, if your application has 10 pods and a 10% rollout job runs, the new instance of the
-application is deployed to a single pod while the remaining nine are present the previous instance.
+application is deployed to a single pod while the rest of the pods show the previous instance of the application.
First we [define the template as manual](https://gitlab.com/gl-release/incremental-rollout-example/blob/master/.gitlab-ci.yml#L100-103):
@@ -135,5 +135,5 @@ to switch to a different deployment. Both deployments are running in parallel, a
can be switched to at any time.
An [example deployable application](https://gitlab.com/gl-release/blue-green-example)
-is available, with a [`gitlab-ci.yml` CI/CD configuration file](https://gitlab.com/gl-release/blue-green-example/blob/master/.gitlab-ci.yml)
+is available, with a [`.gitlab-ci.yml` CI/CD configuration file](https://gitlab.com/gl-release/blue-green-example/blob/master/.gitlab-ci.yml)
that demonstrates blue-green deployments.
diff --git a/doc/ci/environments/index.md b/doc/ci/environments/index.md
index 1b4d8890c6e..6bac004fcdf 100644
--- a/doc/ci/environments/index.md
+++ b/doc/ci/environments/index.md
@@ -99,7 +99,7 @@ deploy_review:
script:
- echo "Deploy a review app"
environment:
- name: review/$CI_COMMIT_REF_NAME
+ name: review/$CI_COMMIT_REF_SLUG
url: https://$CI_ENVIRONMENT_SLUG.example.com
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
@@ -109,9 +109,9 @@ deploy_review:
In this example:
-- The `name` is `review/$CI_COMMIT_REF_NAME`. Because the [environment name](../yaml/index.md#environmentname)
+- The `name` is `review/$CI_COMMIT_REF_SLUG`. Because the [environment name](../yaml/index.md#environmentname)
can contain slashes (`/`), you can use this pattern to distinguish between dynamic and static environments.
-- For the `url`, you could use `$CI_COMMIT_REF_NAME`, but because this value
+- For the `url`, you could use `$CI_COMMIT_REF_SLUG`, but because this value
may contain a `/` or other characters that would not be valid in a domain name or URL,
use `$CI_ENVIRONMENT_SLUG` instead. The `$CI_ENVIRONMENT_SLUG` variable is guaranteed to be unique.
@@ -177,7 +177,7 @@ You can find the play button in the pipelines, environments, deployments, and jo
If you are deploying to a [Kubernetes cluster](../../user/project/clusters/index.md)
associated with your project, you can configure these deployments from your
-`gitlab-ci.yml` file.
+`.gitlab-ci.yml` file.
NOTE:
Kubernetes configuration isn't supported for Kubernetes clusters that are
@@ -385,7 +385,7 @@ deploy_review:
script:
- echo "Deploy a review app"
environment:
- name: review/$CI_COMMIT_REF_NAME
+ name: review/$CI_COMMIT_REF_SLUG
url: https://$CI_ENVIRONMENT_SLUG.example.com
on_stop: stop_review
rules:
@@ -396,7 +396,7 @@ stop_review:
script:
- echo "Remove review app"
environment:
- name: review/$CI_COMMIT_REF_NAME
+ name: review/$CI_COMMIT_REF_SLUG
action: stop
rules:
- if: $CI_MERGE_REQUEST_ID
@@ -440,7 +440,7 @@ is created or updated. The environment runs until `stop_review_app` is executed:
review_app:
script: deploy-review-app
environment:
- name: review/$CI_COMMIT_REF_NAME
+ name: review/$CI_COMMIT_REF_SLUG
on_stop: stop_review_app
auto_stop_in: 1 week
rules:
@@ -449,7 +449,7 @@ review_app:
stop_review_app:
script: stop-review-app
environment:
- name: review/$CI_COMMIT_REF_NAME
+ name: review/$CI_COMMIT_REF_SLUG
action: stop
rules:
- if: $CI_MERGE_REQUEST_ID
@@ -538,7 +538,7 @@ then in the UI, the environments are grouped under that heading:
![Environment groups](img/environments_dynamic_groups_v13_10.png)
The following example shows how to start your environment names with `review`.
-The `$CI_COMMIT_REF_NAME` variable is populated with the branch name at runtime:
+The `$CI_COMMIT_REF_SLUG` variable is populated with the branch name at runtime:
```yaml
deploy_review:
@@ -546,7 +546,7 @@ deploy_review:
script:
- echo "Deploy a review app"
environment:
- name: review/$CI_COMMIT_REF_NAME
+ name: review/$CI_COMMIT_REF_SLUG
```
### Environment incident management
@@ -566,7 +566,7 @@ to get alerts when there are critical issues that need immediate attention.
#### View the latest alerts for environments **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214634) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214634) in GitLab 13.4.
If you [set up alerts for Prometheus metrics](../../operations/metrics/alerts.md),
alerts for environments are shown on the environments page. The alert with the highest
@@ -582,7 +582,7 @@ deployment tab from the environment page and select which deployment to roll bac
#### Auto Rollback **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35404) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35404) in GitLab 13.7.
In a typical Continuous Deployment workflow, the CI pipeline tests every commit before deploying to
production. However, problematic code can still make it to production. For example, inefficient code
@@ -682,9 +682,9 @@ fetch = +refs/environments/*:refs/remotes/origin/environments/*
### Scope environments with specs
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/2112) in [GitLab Premium](https://about.gitlab.com/pricing/) 9.4.
-> - [Environment scoping for CI/CD variables was moved to all tiers](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30779) in GitLab 12.2.
-> - [Environment scoping for Group CI/CD variables](https://gitlab.com/gitlab-org/gitlab/-/issues/2874) added to GitLab Premium in 13.11.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/2112) in GitLab Premium 9.4.
+> - Environment scoping for CI/CD variables was [moved](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30779) from GitLab Premium to GitLab Free in 12.2.
+> - Environment scoping for Group CI/CD variables [added](https://gitlab.com/gitlab-org/gitlab/-/issues/2874) to GitLab Premium in 13.11.
You can limit the environment scope of a CI/CD variable by
defining which environments it can be available for.
@@ -728,11 +728,24 @@ like [Review Apps](../review_apps/index.md) (`review/*`).
The most specific spec takes precedence over the other wildcard matching. In this case,
the `review/feature-1` spec takes precedence over `review/*` and `*` specs.
+### Rename an environment
+
+> Renaming environments through the UI was [removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68550) in GitLab 14.3. Renaming environments through the API was deprecated and [will be removed](https://gitlab.com/gitlab-org/gitlab/-/issues/338897) in GitLab 15.0.
+
+Renaming an environment through the UI is not possible.
+Instead, you need to delete the old environment and create a new one:
+
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Deployments > Environments**.
+1. Find the environment and stop it.
+1. Delete the environment.
+1. Create a new environment with your preferred name.
+
## Related topics
- [Use GitLab CI to deploy to multiple environments (blog post)](https://about.gitlab.com/blog/2021/02/05/ci-deployment-and-environments/)
- [Review Apps](../review_apps/index.md): Use dynamic environments to deploy your code for every branch.
-- [Deploy Boards](../../user/project/deploy_boards.md): View the status of your applications running on Kubernetes.
+- [Deploy boards](../../user/project/deploy_boards.md): View the status of your applications running on Kubernetes.
- [Protected environments](protected_environments.md): Determine who can deploy code to your environments.
- [Environments Dashboard](../environments/environments_dashboard.md): View a summary of each
environment's operational health. **(PREMIUM)**
@@ -763,14 +776,14 @@ To ensure the `action: stop` can always run when needed, you can:
deploy_review:
stage: deploy
environment:
- name: review/$CI_COMMIT_REF_NAME
+ name: review/$CI_COMMIT_REF_SLUG
url: https://$CI_ENVIRONMENT_SLUG.example.com
on_stop: stop_review
stop_review:
stage: deploy
environment:
- name: review/$CI_COMMIT_REF_NAME
+ name: review/$CI_COMMIT_REF_SLUG
action: stop
when: manual
```
@@ -790,7 +803,7 @@ To ensure the `action: stop` can always run when needed, you can:
deploy_review:
stage: deploy
environment:
- name: review/$CI_COMMIT_REF_NAME
+ name: review/$CI_COMMIT_REF_SLUG
url: https://$CI_ENVIRONMENT_SLUG.example.com
on_stop: stop_review
@@ -799,7 +812,7 @@ To ensure the `action: stop` can always run when needed, you can:
needs:
- deploy_review
environment:
- name: review/$CI_COMMIT_REF_NAME
+ name: review/$CI_COMMIT_REF_SLUG
action: stop
when: manual
```
diff --git a/doc/ci/environments/protected_environments.md b/doc/ci/environments/protected_environments.md
index 3cd4ebdbdf1..b31e51b35fc 100644
--- a/doc/ci/environments/protected_environments.md
+++ b/doc/ci/environments/protected_environments.md
@@ -7,7 +7,7 @@ type: concepts, howto
# Protected environments **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6303) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6303) in GitLab 11.3.
[Environments](../environments/index.md) can be used for different reasons:
@@ -157,15 +157,9 @@ For more information, see [Deployment safety](deployment_safety.md).
## Group-level protected environments
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/215888) in [GitLab Premium](https://about.gitlab.com/pricing/) 14.0.
-> - [Deployed behind a feature flag](../../user/feature_flags.md), disabled by default.
-> - Disabled on GitLab.com.
-> - Not recommended for production use.
-> - To use in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-group-level-protected-environments). **(FREE SELF)**
-
-This in-development feature might not be available for your use. There can be
-[risks when enabling features still in development](../../administration/feature_flags.md#risks-when-enabling-features-still-in-development).
-Refer to this feature's version history for more details.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/215888) in GitLab 14.0. [Deployed behind the `group_level_protected_environments` flag](../../administration/feature_flags.md), disabled by default.
+> - [Feature flag `group_level_protected_environments`](https://gitlab.com/gitlab-org/gitlab/-/issues/331085) removed in GitLab 14.3.
+> - [Generally Available](https://gitlab.com/gitlab-org/gitlab/-/issues/331085) on GitLab and on GitLab.com in 14.3.
Typically, large enterprise organizations have an explicit permission boundary
between [developers and operators](https://about.gitlab.com/topics/devops/).
@@ -251,7 +245,7 @@ To protect a group-level environment:
1. Make sure your environments have the correct
[`deployment_tier`](index.md#deployment-tier-of-environments) defined in
- `gitlab-ci.yml`.
+ `.gitlab-ci.yml`.
1. Configure the group-level protected environments via the
[REST API](../../api/group_protected_environments.md).
@@ -259,25 +253,6 @@ NOTE:
Configuration [via the UI](https://gitlab.com/gitlab-org/gitlab/-/issues/325249)
is scheduled for a later release.
-### Enable or disable Group-level protected environments **(FREE SELF)**
-
-Group-level protected environments is under development and not ready for production use. It is
-deployed behind a feature flag that is **disabled by default**.
-[GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md)
-can enable it.
-
-To enable it:
-
-```ruby
-Feature.enable(:group_level_protected_environments)
-```
-
-To disable it:
-
-```ruby
-Feature.disable(:group_level_protected_environments)
-```
-
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
diff --git a/doc/ci/examples/end_to_end_testing_webdriverio/index.md b/doc/ci/examples/end_to_end_testing_webdriverio/index.md
index 7a6d692cd43..06074d6edc2 100644
--- a/doc/ci/examples/end_to_end_testing_webdriverio/index.md
+++ b/doc/ci/examples/end_to_end_testing_webdriverio/index.md
@@ -11,7 +11,7 @@ description: 'Confidence checking your entire app every time a new feature is ad
<!-- vale off -->
-# End-to-end testing with GitLab CI/CD and WebdriverIO
+# End-to-end testing with GitLab CI/CD and WebdriverIO **(FREE)**
[Review Apps](../../review_apps/index.md) are great: for every merge request
(or branch, for that matter), the new code can be copied and deployed to a fresh production-like live
@@ -20,7 +20,7 @@ environment, reducing the effort to assess the impact of changes. Thus, when we
and it will immediately be clear that the application can still be properly built and deployed. After all, you can _see_ it
running!
-<img src="img/deployed_dependency_update.png" alt="dependencies.io">
+![dependencies.io](img/deployed_dependency_update.png)
However, looking at the freshly deployed code to check whether it still looks and behaves as
expected is repetitive manual work, which means it is a prime candidate for automation. This is
diff --git a/doc/ci/examples/index.md b/doc/ci/examples/index.md
index 0569bb281b9..2c2c6ecd30f 100644
--- a/doc/ci/examples/index.md
+++ b/doc/ci/examples/index.md
@@ -6,7 +6,7 @@ comments: false
type: index
---
-# GitLab CI/CD Examples
+# GitLab CI/CD Examples **(FREE)**
This page contains links to a variety of examples that can help you understand how to
implement [GitLab CI/CD](../README.md) for your specific use case.
@@ -33,7 +33,7 @@ The following table lists examples with step-by-step tutorials that are containe
| npm with semantic-release | [Publish npm packages to the GitLab Package Registry using semantic-release](semantic-release.md). |
| PHP with Laravel, Envoy | [Test and deploy Laravel applications with GitLab CI/CD and Envoy](laravel_with_gitlab_and_envoy/index.md). |
| PHP with npm, SCP | [Running Composer and npm scripts with deployment via SCP in GitLab CI/CD](deployment/composer-npm-deploy.md). |
-| PHP with PHPunit, `atoum` | [Testing PHP projects](php.md). |
+| PHP with PHPunit, `atoum` | [Testing PHP projects](php.md). |
| Secrets management with Vault | [Authenticating and Reading Secrets With HashiCorp Vault](authenticating-with-hashicorp-vault/index.md). |
### Contributed examples
@@ -58,7 +58,7 @@ separate example projects:
Get started with GitLab CI/CD and your favorite programming language or framework by using a
`.gitlab-ci.yml` [template](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates).
-When you create a `gitlab-ci.yml` file in the UI, you can
+When you create a `.gitlab-ci.yml` file in the UI, you can
choose one of these templates:
- [Android (`Android.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Android.gitlab-ci.yml)
@@ -76,7 +76,7 @@ choose one of these templates:
- [dotNET Core (`dotNET-Core.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/dotNET-Core.gitlab-ci.yml)
- [Elixir (`Elixir.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Elixir.gitlab-ci.yml)
- [Flutter (`Flutter.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Flutter.gitlab-ci.yml)
-- [goLang (`Go.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Go.gitlab-ci.yml)
+- [Golang (`Go.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Go.gitlab-ci.yml)
- [Gradle (`Gradle.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Gradle.gitlab-ci.yml)
- [Grails (`Grails.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Grails.gitlab-ci.yml)
- [iOS with fastlane (`iOS-Fastlane.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/iOS-Fastlane.gitlab-ci.yml)
@@ -117,15 +117,16 @@ Note that older articles and videos may not reflect the state of the latest GitL
For examples of setting up GitLab CI/CD for cloud-based environments, see:
- [How to set up multi-account AWS SAM deployments with GitLab CI](https://about.gitlab.com/blog/2019/02/04/multi-account-aws-sam-deployments-with-gitlab-ci/)
-- [Automating Kubernetes Deployments with GitLab CI/CD](https://www.youtube.com/watch?v=wEDRfAz6_Uw)
+- Video: [Automating Kubernetes Deployments with GitLab CI/CD](https://www.youtube.com/watch?v=wEDRfAz6_Uw)
- [How to autoscale continuous deployment with GitLab Runner on DigitalOcean](https://about.gitlab.com/blog/2018/06/19/autoscale-continuous-deployment-gitlab-runner-digital-ocean/)
- [How to create a CI/CD pipeline with Auto Deploy to Kubernetes using GitLab and Helm](https://about.gitlab.com/blog/2017/09/21/how-to-create-ci-cd-pipeline-with-autodeploy-to-kubernetes-using-gitlab-and-helm/)
-- [Demo - Deploying from GitLab to OpenShift Container Cluster](https://youtu.be/EwbhA53Jpp4)
+- Video: [Demo - Deploying from GitLab to OpenShift Container Cluster](https://youtu.be/EwbhA53Jpp4)
+- Tutorial: [Set up a GitLab.com Civo Kubernetes integration with GitPod](https://gitlab.com/k33g_org/k33g_org.gitlab.io/-/issues/82)
See also the following video overviews:
-- [Kubernetes, GitLab, and Cloud Native](https://www.youtube.com/watch?v=d-9awBxEbvQ).
-- [Deploying to IBM Cloud with GitLab CI/CD](https://www.youtube.com/watch?v=6ZF4vgKMd-g).
+- Video: [Kubernetes, GitLab, and Cloud Native](https://www.youtube.com/watch?v=d-9awBxEbvQ)
+- Video: [Deploying to IBM Cloud with GitLab CI/CD](https://www.youtube.com/watch?v=6ZF4vgKMd-g)
### Customer stories
@@ -160,7 +161,9 @@ For examples of others who have implemented GitLab CI/CD, see:
### Migrating to GitLab from third-party CI tools
-- [Migrating from Jenkins to GitLab](https://youtu.be/RlEVGOpYF5Y)
+- [Migrating from CircleCI to GitLab](../migration/circleci.md)
+- [Migrating from Jenkins to GitLab](../migration/jenkins.md)
+- Video: [Migrating from Jenkins to GitLab](https://youtu.be/RlEVGOpYF5Y)
### Integrating GitLab CI/CD with other systems
diff --git a/doc/ci/index.md b/doc/ci/index.md
index 9175c20f580..87b259af62a 100644
--- a/doc/ci/index.md
+++ b/doc/ci/index.md
@@ -9,33 +9,23 @@ type: index
# GitLab CI/CD **(FREE)**
-GitLab CI/CD is a tool built into GitLab for software development
-through the [continuous methodologies](introduction/index.md):
+GitLab CI/CD is a tool for software development using the continuous methodologies:
-- Continuous Integration (CI)
-- Continuous Delivery (CD)
-- Continuous Deployment (CD)
+- [Continuous Integration (CI)](introduction/index.md#continuous-integration)
+- [Continuous Delivery (CD)](introduction/index.md#continuous-delivery)
+- [Continuous Deployment (CD)](introduction/index.md#continuous-deployment)
NOTE:
Out-of-the-box management systems can decrease hours spent on maintaining toolchains by 10% or more.
Watch our ["Mastering continuous software development"](https://about.gitlab.com/webcast/mastering-ci-cd/)
-webcast to learn about continuous methods and how the GitLab built-in CI can help you simplify and scale software development.
+webcast to learn about continuous methods and how GitLab CI/CD can help you simplify and scale software development.
-Continuous Integration works by pushing small code chunks to your
-application's codebase hosted in a Git repository, and to every
-push, run a pipeline of scripts to build, test, and validate the
-code changes before merging them into the main branch.
-
-Continuous Delivery and Deployment consist of a step further CI,
-deploying your application to production at every
-push to the default branch of the repository.
-
-These methodologies allow you to catch bugs and errors early in
-the development cycle, ensuring that all the code deployed to
+Use GitLab CI/CD to catch bugs and errors early in
+the development cycle. Ensure that all the code deployed to
production complies with the code standards you established for
your app.
-GitLab can also automatically detect, build, test, deploy, and
+GitLab CI/CD can automatically build, test, deploy, and
monitor your applications by using [Auto DevOps](../topics/autodevops/index.md).
For a complete overview of these methodologies and GitLab CI/CD,
@@ -48,7 +38,7 @@ read the [Introduction to CI/CD with GitLab](introduction/index.md).
<iframe src="https://www.youtube.com/embed/1iXFbchozdY" frameborder="0" allowfullscreen="true"> </iframe>
</figure>
-## Concepts
+## GitLab CI/CD concepts
GitLab CI/CD uses a number of concepts to describe and run your build and deploy.
@@ -63,7 +53,7 @@ GitLab CI/CD uses a number of concepts to describe and run your build and deploy
| [Pipeline efficiency](pipelines/pipeline_efficiency.md) | Configure your pipelines to run quickly and efficiently. |
| [Test cases](test_cases/index.md) | Create testing scenarios. |
-## Configuration
+## GitLab CI/CD configuration
GitLab CI/CD supports numerous configuration options:
@@ -82,21 +72,20 @@ GitLab CI/CD supports numerous configuration options:
Certain operations can only be performed according to the
[user](../user/permissions.md#gitlab-cicd-permissions) and [job](../user/permissions.md#job-permissions) permissions.
-## Feature set
+## GitLab CI/CD features
-Use the vast GitLab CI/CD to easily configure it for specific purposes.
-Its feature set is listed on the table below according to DevOps stages.
+GitLab CI/CD features, grouped by DevOps stage, include:
| Feature | Description |
|:------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------|
| **Configure** | |
| [Auto DevOps](../topics/autodevops/index.md) | Set up your app's entire lifecycle. |
-| [ChatOps](chatops/index.md) | Trigger CI jobs from chat, with results sent back to the channel. |
+| [ChatOps](chatops/index.md) | Trigger CI jobs from chat, with results sent back to the channel. |
|-------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------|
| **Verify** | |
| [Browser Performance Testing](../user/project/merge_requests/browser_performance_testing.md) | Quickly determine the browser performance impact of pending code changes. |
| [Load Performance Testing](../user/project/merge_requests/load_performance_testing.md) | Quickly determine the server performance impact of pending code changes. |
-| [CI services](services/index.md) | Link Docker containers with your base image. |
+| [CI services](services/index.md) | Link Docker containers with your base image. |
| [Code Quality](../user/project/merge_requests/code_quality.md) | Analyze your source code quality. |
| [GitLab CI/CD for external repositories](ci_cd_for_external_repos/index.md) **(PREMIUM)** | Get the benefits of GitLab CI/CD combined with repositories in GitHub and Bitbucket Cloud. |
| [Interactive Web Terminals](interactive_web_terminal/index.md) **(FREE SELF)** | Open an interactive web terminal to debug the running jobs. |
@@ -107,7 +96,7 @@ Its feature set is listed on the table below according to DevOps stages.
| [Auto Deploy](../topics/autodevops/stages.md#auto-deploy) | Deploy your application to a production environment in a Kubernetes cluster. |
| [Building Docker images](docker/using_docker_build.md) | Maintain Docker-based projects using GitLab CI/CD. |
| [Canary Deployments](../user/project/canary_deployments.md) | Ship features to only a portion of your pods and let a percentage of your user base to visit the temporarily deployed feature. |
-| [Deploy Boards](../user/project/deploy_boards.md) | Check the current health and status of each CI/CD environment running on Kubernetes. |
+| [Deploy boards](../user/project/deploy_boards.md) | Check the current health and status of each CI/CD environment running on Kubernetes. |
| [Feature Flags](../operations/feature_flags.md) **(PREMIUM)** | Deploy your features behind Feature Flags. |
| [GitLab Pages](../user/project/pages/index.md) | Deploy static websites. |
| [GitLab Releases](../user/project/releases/index.md) | Add release notes to Git tags. |
@@ -120,29 +109,29 @@ Its feature set is listed on the table below according to DevOps stages.
| [License Compliance](../user/compliance/license_compliance/index.md) **(ULTIMATE)** | Search your project dependencies for their licenses. |
| [Security Test reports](../user/application_security/index.md) **(ULTIMATE)** | Check for app vulnerabilities. |
-## Examples
+## GitLab CI/CD examples
-Find example project code and tutorials for using GitLab CI/CD with a variety of app frameworks, languages, and platforms
-on the [CI Examples](examples/README.md) page.
+See the [CI/CD examples](examples/README.md) page for example project code and tutorials for
+using GitLab CI/CD with various:
-## Administration **(FREE SELF)**
+- App frameworks
+- Languages
+- Platforms
-As a GitLab administrator, you can change the default behavior
-of GitLab CI/CD for:
+## GitLab CI/CD Administration
-- An [entire GitLab instance](../user/admin_area/settings/continuous_integration.md).
-- Specific projects, using [pipelines settings](pipelines/settings.md).
+You can change the default behavior of GitLab CI/CD for:
+
+- An entire GitLab instance in the [CI/CD administration settings](../administration/index.md#cicd-settings).
+- Specific projects in the [pipelines settings](pipelines/settings.md).
See also:
-- [How to enable or disable GitLab CI/CD](enable_or_disable_ci.md).
-- Other [CI administration settings](../administration/index.md#continuous-integration-settings).
+- [Enable or disable GitLab CI/CD in a project](enable_or_disable_ci.md).
## References
-### Why GitLab CI/CD?
-
-Learn more about:
+Learn more about GitLab CI/CD:
- [Why you might choose GitLab CI/CD](https://about.gitlab.com/blog/2016/10/17/gitlab-ci-oohlala/).
- [Reasons you might migrate from another platform](https://about.gitlab.com/blog/2016/07/22/building-our-web-app-on-gitlab-ci/).
@@ -150,10 +139,10 @@ Learn more about:
See also the [Why CI/CD?](https://docs.google.com/presentation/d/1OGgk2Tcxbpl7DJaIOzCX4Vqg3dlwfELC3u2jEeCBbDk) presentation.
-### Breaking changes
+### Major version changes (breaking)
As GitLab CI/CD has evolved, certain breaking changes have
-been necessary. These are:
+been necessary.
#### 13.0
diff --git a/doc/ci/interactive_web_terminal/index.md b/doc/ci/interactive_web_terminal/index.md
index 7e72bd44503..5724c56b096 100644
--- a/doc/ci/interactive_web_terminal/index.md
+++ b/doc/ci/interactive_web_terminal/index.md
@@ -5,12 +5,13 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
-# Interactive Web Terminals
+# Interactive Web Terminals **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/50144) in GitLab 11.3.
Interactive web terminals give the user access to a terminal in GitLab for
-running one-off commands for their CI pipeline. Since this is giving the user
+running one-off commands for their CI pipeline. You can think of it like a method for
+debugging with SSH, but done directly from the job page. Since this is giving the user
shell access to the environment where [GitLab Runner](https://docs.gitlab.com/runner/)
is deployed, some [security precautions](../../administration/integration/terminal.md#security) were
taken to protect the users.
diff --git a/doc/ci/jobs/ci_job_token.md b/doc/ci/jobs/ci_job_token.md
new file mode 100644
index 00000000000..70c22d566e5
--- /dev/null
+++ b/doc/ci/jobs/ci_job_token.md
@@ -0,0 +1,165 @@
+---
+stage: Verify
+group: Pipeline Execution
+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
+---
+
+# GitLab CI/CD job token
+
+When a pipeline job is about to run, GitLab generates a unique token and injects it as the
+[`CI_JOB_TOKEN` predefined variable](../variables/predefined_variables.md).
+
+You can use a GitLab CI/CD job token to authenticate with specific API endpoints:
+
+- Packages:
+ - [Package Registry](../../user/packages/package_registry/index.md). To push to the
+ Package Registry, you can use [deploy tokens](../../user/project/deploy_tokens/index.md).
+ - [Container Registry](../../user/packages/container_registry/index.md)
+ (the `$CI_REGISTRY_PASSWORD` is `$CI_JOB_TOKEN`).
+ - [Container Registry API](../../api/container_registry.md)
+ (scoped to the job's project, when the `ci_job_token_scope` feature flag is enabled).
+- [Get job artifacts](../../api/job_artifacts.md#get-job-artifacts).
+- [Get job token's job](../../api/jobs.md#get-job-tokens-job).
+- [Pipeline triggers](../../api/pipeline_triggers.md), using the `token=` parameter.
+- [Release creation](../../api/releases/index.md#create-a-release).
+- [Terraform plan](../../user/infrastructure/index.md).
+
+The token has the same permissions to access the API as the user that triggers the
+pipeline. Therefore, this user must be assigned to [a role that has the required privileges](../../user/permissions.md#gitlab-cicd-permissions).
+
+The token is valid only while the pipeline job runs. After the job finishes, you can't
+use the token anymore.
+
+A job token can access a project's resources without any configuration, but it might
+give extra permissions that aren't necessary. There is [a proposal](https://gitlab.com/groups/gitlab-org/-/epics/3559)
+to redesign the feature for more strategic control of the access permissions.
+
+You can also use the job token to authenticate and clone a repository from a private project
+in a CI/CD job:
+
+```shell
+git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.example.com/<namespace>/<project>
+```
+
+## GitLab CI/CD job token security
+
+To make sure that this token doesn't leak, GitLab:
+
+- Masks the job token in job logs.
+- Grants permissions to the job token only when the job is running.
+
+To make sure that this token doesn't leak, you should also configure
+your [runners](../runners/index.md) to be secure. Avoid:
+
+- Using Docker's `privileged` mode if the machines are re-used.
+- Using the [`shell` executor](https://docs.gitlab.com/runner/executors/shell.html) when jobs
+ run on the same machine.
+
+If you have an insecure GitLab Runner configuration, you increase the risk that someone
+tries to steal tokens from other jobs.
+
+## Limit GitLab CI/CD job token access
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/328553) in GitLab 14.1.
+> - [Deployed behind a feature flag](../../user/feature_flags.md), disabled by default.
+> - Disabled on GitLab.com.
+> - Not recommended for production use.
+> - To use in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-ci-job-token-scope-limit). **(FREE SELF)**
+
+This in-development feature might not be available for your use. There can be
+[risks when enabling features still in development](../../administration/feature_flags.md#risks-when-enabling-features-still-in-development).
+Refer to this feature's version history for more details.
+
+You can limit the access scope of a project's CI/CD job token to increase the
+job token's security. A job token might give extra permissions that aren't necessary
+to access specific private resources. Limiting the job token access scope reduces the risk of a leaked
+token being used to access private data that the user associated to the job can access.
+
+Control the job token access scope with an allowlist of other projects authorized
+to be accessed by authenticating with the current project's job token. By default
+the token scope only allows access to the same project where the token comes from.
+Other projects can be added and removed by maintainers with access to both projects.
+
+This setting is enabled by default for all new projects, and disabled by default in projects
+created before GitLab 14.1. It is strongly recommended that project maintainers enable this
+setting at all times, and configure the allowlist for cross-project access if needed.
+
+For example, when the setting is enabled, jobs in a pipeline in project `A` have
+a `CI_JOB_TOKEN` scope limited to project `A`. If the job needs to use the token
+to make an API request to a private project `B`, then `B` must be added to the allowlist for `A`.
+If project `B` is public or internal, it doesn't need to be added to the allowlist.
+The job token scope is only for controlling access to private projects.
+
+To enable and configure the job token scope limit:
+
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Settings > CI/CD**.
+1. Expand **Token Access**.
+1. Toggle **Limit CI_JOB_TOKEN access** to enabled.
+1. (Optional) Add existing projects to the token's access scope. The user adding a
+ project must have the [maintainer role](../../user/permissions.md) in both projects.
+
+If the job token scope limit is disabled, the token can potentially be used to authenticate
+API requests to all projects accessible to the user that triggered the job.
+
+There is [a proposal](https://gitlab.com/groups/gitlab-org/-/epics/3559) to improve
+the feature with more strategic control of the access permissions.
+
+### Enable or disable CI job token scope limit **(FREE SELF)**
+
+The GitLab CI/CD job token access scope limit is under development and not ready for production
+use. It is deployed behind a feature flag that is **disabled by default**.
+[GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md)
+can enable it.
+
+To enable it:
+
+```ruby
+Feature.enable(:ci_scoped_job_token)
+```
+
+To disable it:
+
+```ruby
+Feature.disable(:ci_scoped_job_token)
+```
+
+## Trigger a multi-project pipeline by using a CI job token
+
+> `CI_JOB_TOKEN` for multi-project pipelines was [moved](https://gitlab.com/gitlab-org/gitlab/-/issues/31573) from GitLab Premium to GitLab Free in 12.4.
+
+You can use the `CI_JOB_TOKEN` to trigger [multi-project pipelines](../pipelines/multi_project_pipelines.md)
+from a CI/CD job. A pipeline triggered this way creates a dependent pipeline relation
+that is visible on the [pipeline graph](../pipelines/multi_project_pipelines.md#multi-project-pipeline-visualization).
+
+For example:
+
+```yaml
+trigger_pipeline:
+ stage: deploy
+ script:
+ - curl --request POST --form "token=$CI_JOB_TOKEN" --form ref=main "https://gitlab.example.com/api/v4/projects/9/trigger/pipeline"
+ rules:
+ - if: $CI_COMMIT_TAG
+```
+
+If you use the `CI_PIPELINE_SOURCE` [predefined CI/CD variable](../variables/predefined_variables.md)
+in a pipeline triggered this way, [the value is `pipeline` (not `triggered`)](../triggers/index.md#authentication-tokens).
+
+## Download an artifact from a different pipeline **(PREMIUM)**
+
+> `CI_JOB_TOKEN` for artifacts download with the API was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/2346) in GitLab 9.5.
+
+You can use the `CI_JOB_TOKEN` to access artifacts from a job created by a previous
+pipeline. You must specify which job you want to retrieve the artifacts from:
+
+```yaml
+build_submodule:
+ stage: test
+ script:
+ - apt update && apt install -y unzip
+ - curl --location --output artifacts.zip "https://gitlab.example.com/api/v4/projects/1/jobs/artifacts/main/download?job=test&job_token=$CI_JOB_TOKEN"
+ - unzip artifacts.zip
+```
+
+Read more about the [jobs artifacts API](../../api/job_artifacts.md#download-the-artifacts-archive).
diff --git a/doc/ci/jobs/img/job_group_v12_10.png b/doc/ci/jobs/img/job_group_v12_10.png
deleted file mode 100644
index 27e6bfbfc0f..00000000000
--- a/doc/ci/jobs/img/job_group_v12_10.png
+++ /dev/null
Binary files differ
diff --git a/doc/ci/jobs/img/pipeline_delayed_job_v14_2.png b/doc/ci/jobs/img/pipeline_delayed_job_v14_2.png
new file mode 100644
index 00000000000..8dbb118406c
--- /dev/null
+++ b/doc/ci/jobs/img/pipeline_delayed_job_v14_2.png
Binary files differ
diff --git a/doc/ci/jobs/img/pipeline_grouped_jobs_v14_2.png b/doc/ci/jobs/img/pipeline_grouped_jobs_v14_2.png
new file mode 100644
index 00000000000..28be633770b
--- /dev/null
+++ b/doc/ci/jobs/img/pipeline_grouped_jobs_v14_2.png
Binary files differ
diff --git a/doc/ci/jobs/img/pipeline_incremental_rollout.png b/doc/ci/jobs/img/pipeline_incremental_rollout.png
deleted file mode 100644
index b3498e9a5a5..00000000000
--- a/doc/ci/jobs/img/pipeline_incremental_rollout.png
+++ /dev/null
Binary files differ
diff --git a/doc/ci/jobs/img/pipelines_grouped.png b/doc/ci/jobs/img/pipelines_grouped.png
deleted file mode 100644
index 82814754747..00000000000
--- a/doc/ci/jobs/img/pipelines_grouped.png
+++ /dev/null
Binary files differ
diff --git a/doc/ci/jobs/index.md b/doc/ci/jobs/index.md
index aa12e1181cb..54704d5574b 100644
--- a/doc/ci/jobs/index.md
+++ b/doc/ci/jobs/index.md
@@ -58,7 +58,7 @@ In each place, if you hover over the failed job you can see the reason it failed
![Pipeline detail](img/job_failure_reason.png)
-In [GitLab 10.8](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17814) and later,
+In [GitLab 10.8 and later](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17814),
you can also see the reason it failed on the Job detail page.
## The order of jobs in a pipeline
@@ -99,7 +99,7 @@ You can recognize when a pipeline has grouped jobs if you don't see the retry or
cancel button inside them. Hovering over them shows the number of grouped
jobs. Click to expand them.
-![Grouped pipelines](img/pipelines_grouped.png)
+![Grouped pipelines](img/pipeline_grouped_jobs_v14_2.png)
To create a group of jobs, in the [CI/CD pipeline configuration file](../yaml/index.md),
separate each job name with a number and one of the following:
@@ -129,9 +129,7 @@ build ruby 3/3:
- echo "ruby3"
```
-In the pipeline, the result is a group named `build ruby` with three jobs:
-
-![Job group](img/job_group_v12_10.png)
+The pipeline graph displays a group named `build ruby` with three jobs.
The jobs are ordered by comparing the numbers from left to right. You
usually want the first number to be the index and the second number to be the total.
@@ -179,7 +177,7 @@ For example, if you start rolling out new code and:
- Users experience trouble with the new code, you can stop the timed incremental rollout by canceling the pipeline
and [rolling](../environments/index.md#retry-or-roll-back-a-deployment) back to the last stable version.
-![Pipelines example](img/pipeline_incremental_rollout.png)
+![Pipelines example](img/pipeline_delayed_job_v14_2.png)
## Expand and collapse job log sections
diff --git a/doc/ci/jobs/job_control.md b/doc/ci/jobs/job_control.md
index b8b05426297..ad2bbbc883c 100644
--- a/doc/ci/jobs/job_control.md
+++ b/doc/ci/jobs/job_control.md
@@ -1,6 +1,6 @@
---
stage: Verify
-group: Pipeline Execution
+group: Pipeline Authoring
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
---
@@ -225,7 +225,7 @@ check the value of the `$CI_PIPELINE_SOURCE` variable:
| `pipeline` | For [multi-project pipelines](../pipelines/multi_project_pipelines.md) created by [using the API with `CI_JOB_TOKEN`](../pipelines/multi_project_pipelines.md#create-multi-project-pipelines-by-using-the-api), or the [`trigger`](../yaml/index.md#trigger) keyword. |
| `push` | For pipelines triggered by a `git push` event, including for branches and tags. |
| `schedule` | For [scheduled pipelines](../pipelines/schedules.md). |
-| `trigger` | For pipelines created by using a [trigger token](../triggers/index.md#trigger-token). |
+| `trigger` | For pipelines created by using a [trigger token](../triggers/index.md#authentication-tokens). |
| `web` | For pipelines created by using **Run pipeline** button in the GitLab UI, from the project's **CI/CD > Pipelines** section. |
| `webide` | For pipelines created by using the [WebIDE](../../user/project/web_ide/index.md). |
@@ -290,6 +290,35 @@ You can use the `$` character for both variables and paths. For example, if the
`$DOCKERFILES_DIR` variable exists, its value is used. If it does not exist, the
`$` is interpreted as being part of a path.
+## Reuse rules in different jobs
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/322992) in GitLab 14.3.
+
+Use [`!reference` tags](../yaml/index.md#reference-tags) to reuse rules in different
+jobs. You can combine `!reference` rules with regular job-defined rules:
+
+```yaml
+.default_rules:
+ rules:
+ - if: $CI_PIPELINE_SOURCE == "schedule"
+ when: never
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
+
+job1:
+ rules:
+ - !reference [.default_rules, rules]
+ script:
+ - echo "This job runs for the default branch, but not schedules."
+
+job2:
+ rules:
+ - !reference [.default_rules, rules]
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
+ script:
+ - echo "This job runs for the default branch, but not schedules."
+ - echo "It also runs for merge requests."
+```
+
## Specify when jobs run with `only` and `except`
You can use [`only`](../yaml/index.md#only--except) and [`except`](../yaml/index.md#only--except)
@@ -306,7 +335,7 @@ to control when to add jobs to pipelines.
In the following example, `job` runs only for:
- Git tags
-- [Triggers](../triggers/index.md#trigger-token)
+- [Triggers](../triggers/index.md#authentication-tokens)
- [Scheduled pipelines](../pipelines/schedules.md)
```yaml
diff --git a/doc/ci/large_repositories/index.md b/doc/ci/large_repositories/index.md
index c3b0cd79d2c..07b4cd80d6a 100644
--- a/doc/ci/large_repositories/index.md
+++ b/doc/ci/large_repositories/index.md
@@ -5,11 +5,12 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
-# Optimizing GitLab for large repositories
+# Optimize GitLab for large repositories **(FREE)**
Large repositories consisting of more than 50k files in a worktree
-often require special consideration because of
-the time required to clone and check out.
+may require more optimizations beyond
+[pipeline efficiency](../pipelines/pipeline_efficiency.md)
+because of the time required to clone and check out.
GitLab and GitLab Runner handle this scenario well
but require optimized configuration to efficiently perform its
@@ -251,6 +252,8 @@ and does not require us to update each `.gitlab-ci.yml`.
## Pre-clone step
+> [An issue exists](https://gitlab.com/groups/gitlab-com/gl-infra/-/epics/463) to remove the need for this optimization.
+
For very active repositories with a large number of references and files, you can also
optimize your CI jobs by seeding repository data with GitLab Runner's [`pre_clone_script`](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runners-section).
diff --git a/doc/ci/lint.md b/doc/ci/lint.md
index 4e3ac8b9e93..e01bd6b79ff 100644
--- a/doc/ci/lint.md
+++ b/doc/ci/lint.md
@@ -3,11 +3,8 @@ stage: Verify
group: Pipeline Authoring
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
---
-<!-- markdownlint-disable MD044 -->
-<!-- vale gitlab.Spelling = NO -->
-# Validate .gitlab-ci.yml syntax with the CI Lint tool
-<!-- markdownlint-enable MD044 -->
-<!-- vale gitlab.Spelling = YES -->
+
+# Validate `.gitlab-ci.yml` syntax with the CI Lint tool
If you want to test the validity of your GitLab CI/CD configuration before committing
the changes, you can use the CI Lint tool. This tool checks for syntax and logical
diff --git a/doc/ci/migration/circleci.md b/doc/ci/migration/circleci.md
index 106f5b3d819..efaae873588 100644
--- a/doc/ci/migration/circleci.md
+++ b/doc/ci/migration/circleci.md
@@ -1,6 +1,6 @@
---
stage: Verify
-group: Pipeline Execution
+group: Pipeline Authoring
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
comments: false
type: index, howto
@@ -121,11 +121,11 @@ stages:
- test
- deploy
-job 1:
+job1:
stage: build
script: make build dependencies
-job 2:
+job2:
stage: build
script: make build artifacts
@@ -216,12 +216,12 @@ jobs:
Example of the same workflow using `rules` in GitLab CI/CD:
```yaml
-deploy_prod:
+deploy:
stage: deploy
script:
- - echo "Deploy to production server"
+ - echo "Deploy job"
rules:
- - if: '$CI_COMMIT_BRANCH == "main"'
+ - if: '$CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH =~ /^rc-/'
```
### Caching
diff --git a/doc/ci/migration/jenkins.md b/doc/ci/migration/jenkins.md
index 1a987a0ce47..925dff8751c 100644
--- a/doc/ci/migration/jenkins.md
+++ b/doc/ci/migration/jenkins.md
@@ -1,6 +1,6 @@
---
stage: Verify
-group: Pipeline Execution
+group: Pipeline Authoring
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
comments: false
type: index, howto
@@ -130,7 +130,7 @@ There are some important differences in the way runners work in comparison to ag
- Runners can be set up as [shared across an instance, be added at the group level, or set up at the project level](../runners/runners_scope.md).
They self-select jobs from the scopes you've defined automatically.
-- You can also [use tags](../runners/configure_runners.md#use-tags-to-limit-the-number-of-jobs-using-the-runner) for finer control, and
+- You can also [use tags](../runners/configure_runners.md#use-tags-to-control-which-jobs-a-runner-can-run) for finer control, and
associate runners with specific jobs. For example, you can use a tag for jobs that
require dedicated, more powerful, or specific hardware.
- GitLab has [autoscaling for runners](https://docs.gitlab.com/runner/configuration/autoscale.html).
@@ -199,7 +199,7 @@ GitLab takes advantage of our connected ecosystem to automatically pull these ki
your Merge Requests, pipeline details pages, and other locations. You may find that you actually don't
need to configure anything to have these appear.
-If they aren't working as expected, or if you'd like to see what's available, our [CI feature index](../index.md#feature-set) has the full list
+If they aren't working as expected, or if you'd like to see what's available, our [CI feature index](../index.md#gitlab-cicd-features) has the full list
of bundled features and links to the documentation for each.
### Templates
@@ -230,7 +230,7 @@ and is meant to be a mapping of concepts there to concepts in GitLab.
The agent section is used to define how a pipeline executes. For GitLab, we use [runners](../runners/index.md)
to provide this capability. You can configure your own runners in Kubernetes or on any host, or take advantage
of our shared runner fleet (note that the shared runner fleet is only available for GitLab.com users).
-We also support using [tags](../runners/configure_runners.md#use-tags-to-limit-the-number-of-jobs-using-the-runner) to direct different jobs
+We also support using [tags](../runners/configure_runners.md#use-tags-to-control-which-jobs-a-runner-can-run) to direct different jobs
to different runners (execution agents).
The `agent` section also allows you to define which Docker images should be used for execution, for which we use
diff --git a/doc/ci/pipeline_editor/index.md b/doc/ci/pipeline_editor/index.md
index 7132d47d324..10a6d34b076 100644
--- a/doc/ci/pipeline_editor/index.md
+++ b/doc/ci/pipeline_editor/index.md
@@ -56,7 +56,7 @@ reflected in the CI lint. It displays the same results as the existing [CI Lint
> - [Moved to **CI/CD > Editor**](https://gitlab.com/gitlab-org/gitlab/-/issues/263141) in GitLab 13.7.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/290117) in GitLab 13.12.
-To view a visualization of your `gitlab-ci.yml` configuration, in your project,
+To view a visualization of your `.gitlab-ci.yml` configuration, in your project,
go to **CI/CD > Editor**, and then select the **Visualize** tab. The
visualization shows all stages and jobs. Any [`needs`](../yaml/index.md#needs)
relationships are displayed as lines connecting jobs together, showing the
diff --git a/doc/ci/pipelines/img/manual_pipeline_v14_2.png b/doc/ci/pipelines/img/manual_pipeline_v14_2.png
new file mode 100644
index 00000000000..df1c2a4760a
--- /dev/null
+++ b/doc/ci/pipelines/img/manual_pipeline_v14_2.png
Binary files differ
diff --git a/doc/ci/pipelines/img/pipelines.png b/doc/ci/pipelines/img/pipelines.png
deleted file mode 100644
index a604fcb2587..00000000000
--- a/doc/ci/pipelines/img/pipelines.png
+++ /dev/null
Binary files differ
diff --git a/doc/ci/pipelines/img/pipelines_graph_stage_view_v13_12.png b/doc/ci/pipelines/img/pipelines_graph_stage_view_v13_12.png
deleted file mode 100644
index f2f38979e18..00000000000
--- a/doc/ci/pipelines/img/pipelines_graph_stage_view_v13_12.png
+++ /dev/null
Binary files differ
diff --git a/doc/ci/pipelines/img/pipelines_graph_stage_view_v14_2.png b/doc/ci/pipelines/img/pipelines_graph_stage_view_v14_2.png
new file mode 100644
index 00000000000..b0e9f63f743
--- /dev/null
+++ b/doc/ci/pipelines/img/pipelines_graph_stage_view_v14_2.png
Binary files differ
diff --git a/doc/ci/pipelines/index.md b/doc/ci/pipelines/index.md
index 22f18235f99..1eacc799636 100644
--- a/doc/ci/pipelines/index.md
+++ b/doc/ci/pipelines/index.md
@@ -1,6 +1,6 @@
---
stage: Verify
-group: Pipeline Execution
+group: Pipeline Authoring
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
disqus_identifier: 'https://docs.gitlab.com/ee/ci/pipelines.html'
type: reference
@@ -122,6 +122,7 @@ you can filter the pipeline list by:
- Branch name
- Status ([GitLab 13.1 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/217617))
- Tag ([GitLab 13.1 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/217617))
+- Source ([GitLab 14.3 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/338347))
[Starting in GitLab 14.2](https://gitlab.com/gitlab-org/gitlab/-/issues/26621), you can change the
pipeline column to display the pipeline ID or the pipeline IID.
@@ -170,9 +171,6 @@ variables:
You cannot set job-level variables to be pre-filled when you run a pipeline manually.
-Pre-filled variables do not show up when the CI/CD configuration is [external to the project](settings.md#specify-a-custom-cicd-configuration-file).
-See the [related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/336184) for more details.
-
### Run a pipeline by using a URL query string
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/24146) in GitLab 12.5.
@@ -212,11 +210,11 @@ allow you to require manual interaction before moving forward in the pipeline.
You can do this straight from the pipeline graph. Just click the play button
to execute that particular job.
-For example, your pipeline might start automatically, but it requires manual action to
-[deploy to production](../environments/index.md#configure-manual-deployments). In the example below, the `production`
-stage has a job with a manual action.
+For example, your pipeline can start automatically, but require a manual action to
+[deploy to production](../environments/index.md#configure-manual-deployments).
+In the example below, the `production` stage has a job with a manual action:
-![Pipelines example](img/pipelines.png)
+![Pipelines example](img/manual_pipeline_v14_2.png)
#### Start multiple manual actions in a stage
@@ -348,9 +346,9 @@ all the jobs in the pipeline.
You can group the jobs by:
-- Stage, which arranges jobs in the same stage together in the same column.
+- Stage, which arranges jobs in the same stage together in the same column:
- ![jobs grouped by stage](img/pipelines_graph_stage_view_v13_12.png)
+ ![jobs grouped by stage](img/pipelines_graph_stage_view_v14_2.png)
- [Job dependencies](#view-job-dependencies-in-the-pipeline-graph), which arranges
jobs based on their [`needs`](../yaml/index.md#needs) dependencies.
@@ -361,21 +359,16 @@ you visualize the entire pipeline, including all cross-project inter-dependencie
### View job dependencies in the pipeline graph
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/298973) in GitLab 13.12.
-> - [Deployed behind a feature flag](../../user/feature_flags.md), disabled by default.
-> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/328538) in GitLab 13.12.
+> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/328538) in GitLab 14.0.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/328538) in GitLab 14.2.
-This in-development feature might not be available for your use. There can be
-[risks when enabling features still in development](../../administration/feature_flags.md#risks-when-enabling-features-still-in-development).
-Refer to this feature's version history for more details.
-
You can arrange jobs in the pipeline graph based on their [`needs`](../yaml/index.md#needs)
dependencies.
Jobs in the leftmost column run first, and jobs that depend on them are grouped in the next columns.
-For example, `build-job2` depends only on jobs in the first column, so it displays
-in the second column from the left. `deploy-job2` depends on jobs in both the first
+For example, `test-job1` depends only on jobs in the first column, so it displays
+in the second column from the left. `deploy-job1` depends on jobs in both the first
and second column and displays in the third column:
![jobs grouped by needs dependency](img/pipelines_graph_dependency_view_v13_12.png)
diff --git a/doc/ci/pipelines/multi_project_pipelines.md b/doc/ci/pipelines/multi_project_pipelines.md
index 3007d91d1b4..d31ddcf736e 100644
--- a/doc/ci/pipelines/multi_project_pipelines.md
+++ b/doc/ci/pipelines/multi_project_pipelines.md
@@ -273,7 +273,7 @@ upstream_bridge:
> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/31573) to GitLab Free in 12.4.
-When you use the [`CI_JOB_TOKEN` to trigger pipelines](../triggers/index.md#ci-job-token),
+When you use the [`CI_JOB_TOKEN` to trigger pipelines](../jobs/ci_job_token.md),
GitLab recognizes the source of the job token. The pipelines become related,
so you can visualize their relationships on pipeline graphs.
diff --git a/doc/ci/pipelines/parent_child_pipelines.md b/doc/ci/pipelines/parent_child_pipelines.md
index b266a721d11..71f778d81b3 100644
--- a/doc/ci/pipelines/parent_child_pipelines.md
+++ b/doc/ci/pipelines/parent_child_pipelines.md
@@ -61,7 +61,8 @@ microservice_a:
include: path/to/microservice_a.yml
```
-You can include multiple files when composing a child pipeline:
+You can include multiple files when defining a child pipeline. The child pipeline's
+configuration is composed of all configuration files merged together:
```yaml
microservice_a:
@@ -156,15 +157,11 @@ build a matrix of targets and architectures.
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
For an overview, see [Create child pipelines using dynamically generated configurations](https://youtu.be/nMdfus2JWHM).
-<!-- vale gitlab.Spelling = NO -->
-
We also have an example project using
[Dynamic Child Pipelines with Jsonnet](https://gitlab.com/gitlab-org/project-templates/jsonnet)
which shows how to use a data templating language to generate your `.gitlab-ci.yml` at runtime.
You could use a similar process for other templating languages like
-[Dhall](https://dhall-lang.org/) or [`ytt`](https://get-ytt.io/).
-
-<!-- vale gitlab.Spelling = NO -->
+[Dhall](https://dhall-lang.org/) or [ytt](https://get-ytt.io/).
The artifact path is parsed by GitLab, not the runner, so the path must match the
syntax for the OS running GitLab. If GitLab is running on Linux but using a Windows
diff --git a/doc/ci/pipelines/pipeline_efficiency.md b/doc/ci/pipelines/pipeline_efficiency.md
index 91560a0420f..5c3cdd0633e 100644
--- a/doc/ci/pipelines/pipeline_efficiency.md
+++ b/doc/ci/pipelines/pipeline_efficiency.md
@@ -28,6 +28,7 @@ The easiest indicators to check for inefficient pipelines are the runtimes of th
stages, and the total runtime of the pipeline itself. The total pipeline duration is
heavily influenced by the:
+- [Size of the repository](../large_repositories/index.md)
- Total number of stages and jobs.
- Dependencies between jobs.
- The ["critical path"](#directed-acyclic-graphs-dag-visualization), which represents
diff --git a/doc/ci/pipelines/settings.md b/doc/ci/pipelines/settings.md
index b48c62dccc5..94d7e317104 100644
--- a/doc/ci/pipelines/settings.md
+++ b/doc/ci/pipelines/settings.md
@@ -124,7 +124,7 @@ If the CI/CD configuration file is on an external site, the URL must end with `.
If the CI/CD configuration file is in a different project:
-- The file must exist on its default branch.
+- The file must exist on its default branch, or specify the branch as refname.
- The path must be relative to the root directory in the other project.
- The path must include the group and project name at the end.
@@ -132,6 +132,7 @@ For example:
- `.gitlab-ci.yml@mygroup/another-project`
- `my/path/.my-custom-file.yml@mygroup/another-project`
+- `my/path/.my-custom-file.yml@mygroup/another-project:refname`
If the configuration file is in a separate project, you can more set more granular permissions. For example:
diff --git a/doc/ci/quick_start/index.md b/doc/ci/quick_start/index.md
index 257e170b0a5..e2381238318 100644
--- a/doc/ci/quick_start/index.md
+++ b/doc/ci/quick_start/index.md
@@ -7,8 +7,7 @@ type: reference
# Get started with GitLab CI/CD **(FREE)**
-Use this document to get started with
-GitLab [continuous integration](https://about.gitlab.com/stages-devops-lifecycle/continuous-integration/).
+Use this document to get started with [GitLab CI/CD](../index.md).
Before you start, make sure you have:
@@ -126,7 +125,7 @@ The pipeline starts when the commit is committed.
```yaml
default:
- image: ruby:2.7.2
+ image: ruby:2.7.4
```
This command tells the runner to use a Ruby image from Docker Hub
@@ -141,8 +140,22 @@ The pipeline starts when the commit is committed.
[CI Lint tool](../lint.md), which is available in every project.
- You can also use [CI/CD configuration visualization](../pipeline_editor/index.md#visualize-ci-configuration) to
view a graphical representation of your `.gitlab-ci.yml` file.
-- For the complete `.gitlab-ci.yml` syntax, see
- [the `.gitlab-ci.yml` reference topic](../yaml/index.md).
+- Each job contains scripts and stages:
+ - The [`default`](../yaml/index.md#custom-default-keyword-values) keyword is for
+ custom defaults, for example with [`before_script`](../yaml/index.md#before_script)
+ and [`after_script`](../yaml/index.md#after_script).
+ - [`stage`](../yaml/index.md#stage) describes the sequential execution of jobs.
+ Jobs in a single stage run in parallel as long as there are available runners.
+ - Use [Directed Acyclic Graphs (DAG)](../directed_acyclic_graph/index.md) keywords
+ to run jobs out of stage order.
+- You can set additional configuration to customize how your jobs and stages perform:
+ - Use the [`rules`](../yaml/index.md#rules) keyword to specify when to run or skip jobs.
+ The `only` and `except` legacy keywords are still supported, but can't be used
+ with `rules` in the same job.
+ - Keep information across jobs and stages persistent in a pipeline with [`cache`](../yaml/index.md#cache))
+ and [`artifacts`](../yaml/index.md#artifacts). These keywords are ways to store
+ dependencies and job output, even when using ephemeral runners for each job.
+- For the complete `.gitlab-ci.yml` syntax, see [the full `.gitlab-ci.yml` reference topic](../yaml/index.md).
### View the status of your pipeline and jobs
diff --git a/doc/ci/review_apps/index.md b/doc/ci/review_apps/index.md
index 8af04388f92..1b926d506c4 100644
--- a/doc/ci/review_apps/index.md
+++ b/doc/ci/review_apps/index.md
@@ -57,7 +57,7 @@ The process of configuring Review Apps is as follows:
1. Set up the infrastructure to host and deploy the Review Apps (check the [examples](#review-apps-examples) below).
1. [Install](https://docs.gitlab.com/runner/install/) and [configure](https://docs.gitlab.com/runner/commands/) a runner to do deployment.
-1. Set up a job in `.gitlab-ci.yml` that uses the [predefined CI/CD variable](../variables/index.md) `${CI_COMMIT_REF_NAME}`
+1. Set up a job in `.gitlab-ci.yml` that uses the [predefined CI/CD variable](../variables/index.md) `${CI_COMMIT_REF_SLUG}`
to create dynamic environments and restrict it to run only on branches.
Alternatively, you can get a YML template for this job by [enabling review apps](#enable-review-apps-button) for your project.
1. Optionally, set a job that [manually stops](../environments/index.md#stop-an-environment) the Review Apps.
diff --git a/doc/ci/runners/build_cloud/macos/environment.md b/doc/ci/runners/build_cloud/macos/environment.md
index e84b7d0a207..5336890b931 100644
--- a/doc/ci/runners/build_cloud/macos/environment.md
+++ b/doc/ci/runners/build_cloud/macos/environment.md
@@ -4,12 +4,12 @@ group: Runner
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
---
-# VM instances and images for Build Cloud for macOS
+# VM instances and images for Build Cloud for macOS
When you use the Build Cloud for macOS:
-- Each of your jobs runs in a newly provisioned VM, which is dedicated to the specific job.
-- The VM is active only for the duration of the job and immediately deleted.
+- Each of your jobs runs in a newly provisioned VM, which is dedicated to the specific job.
+- The VM is active only for the duration of the job and immediately deleted.
## VM types
diff --git a/doc/ci/runners/build_cloud/macos_build_cloud.md b/doc/ci/runners/build_cloud/macos_build_cloud.md
index 1400c7e08db..794bc2e597d 100644
--- a/doc/ci/runners/build_cloud/macos_build_cloud.md
+++ b/doc/ci/runners/build_cloud/macos_build_cloud.md
@@ -12,11 +12,11 @@ of all the capabilities of the GitLab single DevOps platform and not have to man
build environment.
Build Cloud runners for macOS are in [Beta](https://about.gitlab.com/handbook/product/gitlab-the-product/#beta)
-and shouldn't be relied upon for mission-critical production jobs.
+and shouldn't be relied upon for mission-critical production jobs.
## Quickstart
-To start using Build Cloud for macOS Beta, you must submit an access request issue. After your
+To start using Build Cloud for macOS Beta, you must submit an access request [issue](https://gitlab.com/gitlab-com/macos-buildcloud-runners-beta/-/issues/new?issuable_template=beta_access_request). After your
access has been granted and your build environment configured, you must configure your
`.gitlab-ci.yml` pipeline file:
diff --git a/doc/ci/runners/configure_runners.md b/doc/ci/runners/configure_runners.md
index 2f845a05a4e..13897b934c5 100644
--- a/doc/ci/runners/configure_runners.md
+++ b/doc/ci/runners/configure_runners.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
-# Configuring runners
+# Configuring runners **(FREE)**
If you have installed your own runners, you can configure and secure them in GitLab.
@@ -107,10 +107,10 @@ We're always looking for contributions that can mitigate these
### Reset the runner registration token for a project
If you think that a registration token for a project was revealed, you should
-reset it. A token can be used to register another runner for the project. That new runner
-may then be used to obtain the values of secret variables or to clone project code.
+reset it. A registration token can be used to register another runner for the project.
+That new runner may then be used to obtain the values of secret variables or to clone project code.
-To reset the token:
+To reset the registration token:
1. Go to the project's **Settings > CI/CD**.
1. Expand the **General pipelines settings** section.
@@ -124,6 +124,16 @@ any new runners to the project. If you are using any tools to provision and
register new runners, the tokens used in those tools should be updated to reflect the
value of the new token.
+### Reset the runner authentication token
+
+If you think that an authentication token for a runner was revealed, you should
+reset it. An attacker could use the token to [clone a runner](https://docs.gitlab.com/runner/security/#cloning-a-runner).
+
+To reset the authentication token, [unregister the runner](https://docs.gitlab.com/runner/commands/#gitlab-runner-unregister)
+and then [register](https://docs.gitlab.com/runner/commands/#gitlab-runner-register) it again.
+
+To verify that the previous authentication token has been revoked, use the [Runners API](../../api/runners.md#verify-authentication-for-a-registered-runner).
+
## Determine the IP address of a runner
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17286) in GitLab 10.6.
@@ -142,7 +152,7 @@ different places.
To view the IP address of a shared runner you must have admin access to
the GitLab instance. To determine this:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Runners**.
1. Find the runner in the table and view the **IP Address** column.
@@ -159,13 +169,13 @@ project.
![specific runner IP address](img/specific_runner_ip_address.png)
-## Use tags to limit the number of jobs using the runner
+## Use tags to control which jobs a runner can run
You must set up a runner to be able to run all the different types of jobs
that it may encounter on the projects it's shared over. This would be
problematic for large amounts of projects, if it weren't for tags.
-GitLab CI tags are not the same as Git tags. GitLab CI tags are associated with runners.
+GitLab CI/CD tags are not the same as Git tags. GitLab CI/CD tags are associated with runners.
Git tags are associated with commits.
By tagging a runner for the types of jobs it can handle, you can make sure
@@ -174,6 +184,8 @@ shared runners will [only run the jobs they are equipped to run](../yaml/index.m
For instance, at GitLab we have runners tagged with `rails` if they contain
the appropriate dependencies to run Rails test suites.
+### Set a runner to run untagged jobs
+
When you [register a runner](https://docs.gitlab.com/runner/register/), its default behavior is to **only pick**
[tagged jobs](../yaml/index.md#tags).
To change this, you must have the [Owner role](../../user/permissions.md#project-members-permissions) for the project.
@@ -228,6 +240,48 @@ Example 2:
1. A job that has no tags defined is executed and run.
1. A second job that has a `docker` tag defined is stuck.
+### Use tags to run jobs on different platforms
+
+You can use tags to run different jobs on different platforms. For
+example, if you have an OS X runner with tag `osx` and a Windows runner with tag
+`windows`, you can run a job on each platform:
+
+```yaml
+windows job:
+ stage:
+ - build
+ tags:
+ - windows
+ script:
+ - echo Hello, %USERNAME%!
+
+osx job:
+ stage:
+ - build
+ tags:
+ - osx
+ script:
+ - echo "Hello, $USER!"
+```
+
+### Use CI/CD variables in tags
+
+> Introduced in [GitLab 14.1](https://gitlab.com/gitlab-org/gitlab/-/issues/35742).
+
+You can use [CI/CD variables](../variables/index.md) with `tags` for dynamic runner selection:
+
+```yaml
+variables:
+ KUBERNETES_RUNNER: kubernetes
+
+ job:
+ tags:
+ - docker
+ - $KUBERNETES_RUNNER
+ script:
+ - echo "Hello runner selector feature"
+```
+
## Configure runner behavior with variables
You can use [CI/CD variables](../variables/index.md) to configure runner Git behavior
@@ -546,7 +600,7 @@ the following stages:
| Variable | Description |
|---------------------------------|--------------------------------------------------------|
| `ARTIFACT_DOWNLOAD_ATTEMPTS` | Number of attempts to download artifacts running a job |
-| `EXECUTOR_JOB_SECTION_ATTEMPTS` | [In GitLab 12.10](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4450) and later, the number of attempts to run a section in a job after a [`No Such Container`](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4450) error ([Docker executor](https://docs.gitlab.com/runner/executors/docker.html) only). |
+| `EXECUTOR_JOB_SECTION_ATTEMPTS` | In [GitLab 12.10 and later](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4450), the number of attempts to run a section in a job after a [`No Such Container`](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4450) error ([Docker executor](https://docs.gitlab.com/runner/executors/docker.html) only). |
| `GET_SOURCES_ATTEMPTS` | Number of attempts to fetch sources running a job |
| `RESTORE_CACHE_ATTEMPTS` | Number of attempts to restore the cache running a job |
diff --git a/doc/ci/runners/index.md b/doc/ci/runners/index.md
index 6642913a9d8..9acca60c4b4 100644
--- a/doc/ci/runners/index.md
+++ b/doc/ci/runners/index.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
-# GitLab Build Cloud runners
+# GitLab Build Cloud runners **(FREE)**
If you are using self-managed GitLab or you want to use your own runners on GitLab.com, you can
[install and configure your own runners](https://docs.gitlab.com/runner/install/).
diff --git a/doc/ci/runners/runners_scope.md b/doc/ci/runners/runners_scope.md
index 2af373384d2..b16957ae83c 100644
--- a/doc/ci/runners/runners_scope.md
+++ b/doc/ci/runners/runners_scope.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
-# The scope of runners
+# The scope of runners **(FREE)**
Runners are available based on who you want to have access:
@@ -168,7 +168,7 @@ You must have the [Owner role](../../user/permissions.md#group-members-permissio
| Attribute | Description |
| ------------ | ----------- |
- | Type | Displays the runner type: `group` or `specific`, together with the optional states `locked` and `paused` |
+ | Type | Displays the runner type: `group` or `specific`, and the optional state `paused` |
| Runner token | Token used to identify the runner, and that the runner uses to communicate with the GitLab instance |
| Description | Description given to the runner when it was created |
| Version | GitLab Runner version |
@@ -242,10 +242,10 @@ You can configure a specific runner so it is "locked" and cannot be enabled for
This setting can be enabled when you first [register a runner](https://docs.gitlab.com/runner/register/),
but can also be changed later.
-To lock or unlock a runner:
+To lock or unlock a specific runner:
1. Go to the project's **Settings > CI/CD** and expand the **Runners** section.
-1. Find the runner you want to lock or unlock. Make sure it's enabled.
+1. Find the specific runner you want to lock or unlock. Make sure it's enabled. You cannot lock shared or group runners.
1. Click the pencil button.
1. Check the **Lock to current projects** option.
1. Click **Save changes**.
diff --git a/doc/ci/secrets/index.md b/doc/ci/secrets/index.md
index d3c34a6922e..898d310598f 100644
--- a/doc/ci/secrets/index.md
+++ b/doc/ci/secrets/index.md
@@ -95,7 +95,7 @@ To configure your Vault server:
## Use Vault secrets in a CI job **(PREMIUM)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/28321) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.4 and GitLab Runner 13.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/28321) in GitLab 13.4 and GitLab Runner 13.4.
After [configuring your Vault server](#configure-your-vault-server), you can use
the secrets stored in Vault by defining them with the `vault` keyword:
diff --git a/doc/ci/services/gitlab.md b/doc/ci/services/gitlab.md
index 558f53a9535..5ac66846ab7 100644
--- a/doc/ci/services/gitlab.md
+++ b/doc/ci/services/gitlab.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
-# Use GitLab as a microservice
+# Use GitLab as a microservice **(FREE)**
Many applications need to access JSON APIs, so application tests might need access
to APIs too. The following example shows how to use GitLab as a microservice to give
@@ -24,10 +24,9 @@ tests access to the GitLab API.
GITLAB_ROOT_PASSWORD: "password" # to access the api with user root:password
```
-1. To set values for the `GITLAB_HTTPS` and `GITLAB_ROOT_PASSWORD`,
- [assign them to a variable in the user interface](../variables/index.md#add-a-cicd-variable-to-a-project).
- Then assign that variable to the corresponding variable in your
- `.gitlab-ci.yml` file.
+NOTE:
+Variables set in the GitLab UI are not passed down to the service containers.
+[Learn more](../variables/index.md#).
Then, commands in `script:` sections in your `.gitlab-ci.yml` file can access the API at `http://gitlab/api/v4`.
diff --git a/doc/ci/services/index.md b/doc/ci/services/index.md
index c7891998a37..4114833d1c8 100644
--- a/doc/ci/services/index.md
+++ b/doc/ci/services/index.md
@@ -6,7 +6,7 @@ comments: false
type: index
---
-# Services
+# Services **(FREE)**
The `services` keyword defines a Docker image that runs during a `job`
linked to the Docker image that the image keyword defines. This allows
@@ -186,6 +186,34 @@ following these rules:
To override the default behavior, you can
[specify a service alias](#available-settings-for-services).
+### Connecting services
+
+You can use inter-dependent services with complex jobs, like end-to-end tests where an
+external API needs to communicate with its own database.
+
+For example, for an end-to-end test for a front-end application that uses an API, and where the API needs a database:
+
+```yaml
+end-to-end-tests:
+ image: node:latest
+ services:
+ - name: selenium/standalone-firefox:${FIREFOX_VERSION}
+ alias: firefox
+ - name: registry.gitlab.com/organization/private-api:latest
+ alias: backend-api
+ - postgres:9.6.19
+ variables:
+ FF_NETWORK_PER_BUILD: 1
+ POSTGRES_PASSWORD: supersecretpassword
+ BACKEND_POSTGRES_HOST: postgres
+ script:
+ - npm install
+ - npm test
+```
+
+For this solution to work, you must use
+[the networking mode that creates a new network for each job](https://docs.gitlab.com/runner/executors/docker.html#create-a-network-for-each-job).
+
## Passing CI/CD variables to services
You can also pass custom CI/CD [variables](../variables/index.md)
@@ -311,6 +339,34 @@ services:
The syntax of `command` is similar to [Dockerfile's `CMD`](https://docs.docker.com/engine/reference/builder/#cmd).
+## Using `services` with `docker run` (Docker-in-Docker) side-by-side
+
+Containers started with `docker run` can also connect to services provided by GitLab.
+
+When booting the service is expensive or time consuming, you can use
+this technique to run tests from different client environments,
+while only booting up the tested service once.
+
+```yaml
+access-service:
+ stage: build
+ image: docker:19.03.1
+ services:
+ - docker:dind # necessary for docker run
+ - tutum/wordpress:latest
+ variables:
+ FF_NETWORK_PER_BUILD: "true" # activate container-to-container networking
+ script: |
+ docker run --rm --name curl \
+ --volume "$(pwd)":"$(pwd)" \
+ --workdir "$(pwd)" \
+ --network=host \
+ curlimages/curl:7.74.0 curl "http://tutum-wordpress"
+```
+
+For this solution to work, you must use
+[the networking mode that creates a new network for each job](https://docs.gitlab.com/runner/executors/docker.html#create-a-network-for-each-job).
+
## How Docker integration works
Below is a high level overview of the steps performed by Docker during job
diff --git a/doc/ci/services/mysql.md b/doc/ci/services/mysql.md
index c691a6ef33d..d0ac123ba62 100644
--- a/doc/ci/services/mysql.md
+++ b/doc/ci/services/mysql.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
-# Using MySQL
+# Using MySQL **(FREE)**
Many applications depend on MySQL as their database, and you may
need it for your tests to run.
@@ -16,11 +16,9 @@ If you want to use a MySQL container, you can use [GitLab Runner](../runners/ind
This example shows you how to set a username and password that GitLab uses to access the MySQL container. If you do not set a username and password, you must use `root`.
-1. [Create CI/CD variables](../variables/index.md#custom-cicd-variables) for your
- MySQL database and password by going to **Settings > CI/CD**, expanding **Variables**,
- and clicking **Add Variable**.
-
- This example uses `$MYSQL_DB` and `$MYSQL_PASS` as the keys.
+NOTE:
+Variables set in the GitLab UI are not passed down to the service containers.
+[Learn more](../variables/index.md).
1. To specify a MySQL image, add the following to your `.gitlab-ci.yml` file:
@@ -39,8 +37,8 @@ This example shows you how to set a username and password that GitLab uses to ac
```yaml
variables:
# Configure mysql environment variables (https://hub.docker.com/_/mysql/)
- MYSQL_DATABASE: $MYSQL_DB
- MYSQL_ROOT_PASSWORD: $MYSQL_PASS
+ MYSQL_DATABASE: $MYSQL_DATABASE
+ MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD
```
The MySQL container uses `MYSQL_DATABASE` and `MYSQL_ROOT_PASSWORD` to connect to the database.
diff --git a/doc/ci/services/postgres.md b/doc/ci/services/postgres.md
index 8d14e4795d2..62838e04969 100644
--- a/doc/ci/services/postgres.md
+++ b/doc/ci/services/postgres.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
-# Using PostgreSQL
+# Using PostgreSQL **(FREE)**
As many applications depend on PostgreSQL as their database, you
eventually need it in order for your tests to run. Below you are guided how to
@@ -16,6 +16,10 @@ do this with the Docker and Shell executors of GitLab Runner.
If you're using [GitLab Runner](../runners/index.md) with the Docker executor,
you basically have everything set up already.
+NOTE:
+Variables set in the GitLab UI are not passed down to the service containers.
+[Learn more](../variables/index.md).
+
First, in your `.gitlab-ci.yml` add:
```yaml
@@ -23,25 +27,19 @@ services:
- postgres:12.2-alpine
variables:
- POSTGRES_DB: nice_marmot
- POSTGRES_USER: runner
- POSTGRES_PASSWORD: ""
+ POSTGRES_DB: $POSTGRES_DB
+ POSTGRES_USER: $POSTGRES_USER
+ POSTGRES_PASSWORD: $POSTGRES_PASSWORD
POSTGRES_HOST_AUTH_METHOD: trust
```
-To set values for the `POSTGRES_DB`, `POSTGRES_USER`,
-`POSTGRES_PASSWORD` and `POSTGRES_HOST_AUTH_METHOD`,
-[assign them to a CI/CD variable in the user interface](../variables/index.md#custom-cicd-variables),
-then assign that variable to the corresponding variable in your
-`.gitlab-ci.yml` file.
-
And then configure your application to use the database, for example:
```yaml
Host: postgres
-User: runner
-Password: ''
-Database: nice_marmot
+User: $PG_USER
+Password: $PG_PASSWORD
+Database: $PG_DB
```
If you're wondering why we used `postgres` for the `Host`, read more at
diff --git a/doc/ci/services/redis.md b/doc/ci/services/redis.md
index d8c7b805864..a3446fc2677 100644
--- a/doc/ci/services/redis.md
+++ b/doc/ci/services/redis.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
-# Using Redis
+# Using Redis **(FREE)**
As many applications depend on Redis as their key-value store, you
eventually need it in order for your tests to run. Below you are guided how to
diff --git a/doc/ci/triggers/index.md b/doc/ci/triggers/index.md
index 880473d402d..a2dd4ac91d5 100644
--- a/doc/ci/triggers/index.md
+++ b/doc/ci/triggers/index.md
@@ -14,8 +14,8 @@ tag) with an API call.
The following methods of authentication are supported:
-- [Trigger token](#trigger-token)
-- [CI job token](#ci-job-token)
+- Trigger tokens: A unique trigger token can be obtained when [adding a new trigger](#adding-a-new-trigger).
+- [CI job tokens](../jobs/ci_job_token.md).
If using the `$CI_PIPELINE_SOURCE` [predefined CI/CD variable](../variables/predefined_variables.md)
to limit which jobs run in a pipeline, the value could be either `pipeline` or `trigger`,
@@ -28,71 +28,6 @@ depending on which trigger method is used.
This also applies when using the `pipelines` or `triggers` keywords with the legacy [`only/except` basic syntax](../yaml/index.md#only--except).
-### Trigger token
-
-A unique trigger token can be obtained when [adding a new trigger](#adding-a-new-trigger).
-
-WARNING:
-Passing plain text tokens in public projects is a security issue. Potential
-attackers can impersonate the user that exposed their trigger token publicly in
-their `.gitlab-ci.yml` file. Use [CI/CD variables](../variables/index.md)
-to protect trigger tokens.
-
-### CI job token
-
-You can use the `CI_JOB_TOKEN` [CI/CD variable](../variables/index.md#predefined-cicd-variables) (used to authenticate
-with the [GitLab Container Registry](../../user/packages/container_registry/index.md)) in the following cases.
-
-#### When used with multi-project pipelines
-
-> - Use of `CI_JOB_TOKEN` for multi-project pipelines was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/2017) in [GitLab Premium](https://about.gitlab.com/pricing/) 9.3.
-> - Use of `CI_JOB_TOKEN` for multi-project pipelines was [made available](https://gitlab.com/gitlab-org/gitlab/-/issues/31573) in all tiers in GitLab 12.4.
-
-This way of triggering can only be used when invoked inside `.gitlab-ci.yml`,
-and it creates a dependent pipeline relation visible on the
-[pipeline graph](../pipelines/multi_project_pipelines.md). For example:
-
-```yaml
-trigger_pipeline:
- stage: deploy
- script:
- - curl --request POST --form "token=$CI_JOB_TOKEN" --form ref=main "https://gitlab.example.com/api/v4/projects/9/trigger/pipeline"
- rules:
- - if: $CI_COMMIT_TAG
-```
-
-Pipelines triggered that way also expose a special variable:
-`CI_PIPELINE_SOURCE=pipeline`.
-
-Read more about the [pipelines trigger API](../../api/pipeline_triggers.md).
-
-#### When a pipeline depends on the artifacts of another pipeline **(PREMIUM)**
-
-> The use of `CI_JOB_TOKEN` in the artifacts download API was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/2346) in [GitLab Premium](https://about.gitlab.com/pricing/) 9.5.
-
-With the introduction of dependencies between different projects, one of
-them may need to access artifacts created by a previous one. This process
-must be granted for authorized accesses, and it can be done using the
-`CI_JOB_TOKEN` variable that identifies a specific job. For example:
-
-```yaml
-build_submodule:
- image: debian
- stage: test
- script:
- - apt update && apt install -y unzip
- - curl --location --output artifacts.zip "https://gitlab.example.com/api/v4/projects/1/jobs/artifacts/main/download?job=test&job_token=$CI_JOB_TOKEN"
- - unzip artifacts.zip
- rules:
- - if: $CI_COMMIT_TAG
-```
-
-This allows you to use that for multi-project pipelines and download artifacts
-from any project to which you have access as this follows the same principles
-with the [permission model](../../user/permissions.md#job-permissions).
-
-Read more about the [jobs API](../../api/job_artifacts.md#download-the-artifacts-archive).
-
## Adding a new trigger
Go to your
@@ -106,6 +41,12 @@ overview of the time the triggers were last used.
![Triggers page overview](img/triggers_page.png)
+WARNING:
+Passing plain text tokens in public projects is a security issue. Potential
+attackers can impersonate the user that exposed their trigger token publicly in
+their `.gitlab-ci.yml` file. Use [CI/CD variables](../variables/index.md)
+to protect trigger tokens.
+
## Revoking a trigger
You can revoke a trigger any time by going at your project's
diff --git a/doc/ci/troubleshooting.md b/doc/ci/troubleshooting.md
index df9b20d1708..827a89fa99c 100644
--- a/doc/ci/troubleshooting.md
+++ b/doc/ci/troubleshooting.md
@@ -29,7 +29,7 @@ with your editor of choice.
### Verify syntax with CI Lint tool
The [CI Lint tool](lint.md) is a simple way to ensure the syntax of a CI/CD configuration
-file is correct. Paste in full `gitlab-ci.yml` files or individual jobs configuration,
+file is correct. Paste in full `.gitlab-ci.yml` files or individual jobs configuration,
to verify the basic syntax.
When a `.gitlab-ci.yml` file is present in a project, you can also use the CI Lint
@@ -49,7 +49,7 @@ and check if their values are what you expect.
## GitLab CI/CD documentation
-The [complete `gitlab-ci.yml` reference](yaml/index.md) contains a full list of
+The [complete `.gitlab-ci.yml` reference](yaml/index.md) contains a full list of
every keyword you may need to use to configure your pipelines.
You can also look at a large number of pipeline configuration [examples](examples/index.md)
diff --git a/doc/ci/variables/index.md b/doc/ci/variables/index.md
index a00b8b678ec..fa4bc6e39fb 100644
--- a/doc/ci/variables/index.md
+++ b/doc/ci/variables/index.md
@@ -20,6 +20,15 @@ You can use [predefined CI/CD variables](#predefined-cicd-variables) or define c
- [Group CI/CD variables](#add-a-cicd-variable-to-a-group).
- [Instance CI/CD variables](#add-a-cicd-variable-to-an-instance).
+NOTE:
+Variables set in the GitLab UI are **not** passed down to [service containers](../docker/using_docker_images.md).
+To set them, assign them to variables in the UI, then re-assign them in your `.gitlab-ci.yml`:
+
+```yaml
+variables:
+ SA_PASSWORD: $SA_PASSWORD
+```
+
> For more information about advanced use of GitLab CI/CD:
>
> - <i class="fa fa-youtube-play youtube" aria-hidden="true"></i>&nbsp;Get to productivity faster with these [7 advanced GitLab CI workflow hacks](https://about.gitlab.com/webcast/7cicd-hacks/)
@@ -116,7 +125,7 @@ Use the [`value` and `description`](../yaml/index.md#prefill-variables-in-manual
keywords to define [variables that are prefilled](../pipelines/index.md#prefill-variables-in-manual-pipelines)
for [manually-triggered pipelines](../pipelines/index.md#run-a-pipeline-manually).
-### Use variables or `$` in other variables
+### Use variables in other variables
You can use variables inside other variables:
@@ -129,7 +138,9 @@ job:
- 'eval "$LS_CMD"' # Executes 'ls -al'
```
-If you do not want the `$` interpreted as the start of a variable, use `$$` instead:
+#### Use the `$` character in variables
+
+If you do not want the `$` character interpreted as the start of a variable, use `$$` instead:
```yaml
job:
@@ -228,7 +239,7 @@ You can define instance variables via the UI or [API](../../api/instance_level_c
To add an instance variable:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > CI/CD** and expand the **Variables** section.
1. Select the **Add variable** button, and fill in the details:
@@ -295,6 +306,26 @@ echo "$KUBE_CA_PEM" > "$(pwd)/kube.ca.pem"
kubectl config set-cluster e2e --server="$KUBE_URL" --certificate-authority="$(pwd)/kube.ca.pem"
```
+#### Store multiple values in one variable
+
+It is not possible to create a CI/CD variable that is an array of values, but you
+can use shell scripting techniques for similar behavior.
+
+For example, you can store multiple variables separated by a space in a variable,
+then loop through the values with a script:
+
+```yaml
+job1:
+ variables:
+ FOLDERS: src test docs
+ script:
+ - |
+ for FOLDER in $FOLDERS
+ do
+ echo "The path is root/${FOLDER}"
+ done
+```
+
### Mask a CI/CD variable
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/13784) in GitLab 11.10
diff --git a/doc/ci/variables/predefined_variables.md b/doc/ci/variables/predefined_variables.md
index b5999a555c9..c8688d2433e 100644
--- a/doc/ci/variables/predefined_variables.md
+++ b/doc/ci/variables/predefined_variables.md
@@ -41,7 +41,8 @@ There are also [Kubernetes-specific deployment variables](../../user/project/clu
| `CI_CONFIG_PATH` | 9.4 | 0.5 | The path to the CI/CD configuration file. Defaults to `.gitlab-ci.yml`. Read-only inside a running pipeline. |
| `CI_DEBUG_TRACE` | all | 1.7 | `true` if [debug logging (tracing)](index.md#debug-logging) is enabled. |
| `CI_DEFAULT_BRANCH` | 12.4 | all | The name of the project's default branch. |
-| `CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX` | 13.7 | all | The image prefix for pulling images through the Dependency Proxy. |
+| `CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX` | 13.7 | all | The top-level group image prefix for pulling images through the Dependency Proxy. |
+| `CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX` | 14.3 | all | The direct group image prefix for pulling images through the Dependency Proxy. |
| `CI_DEPENDENCY_PROXY_PASSWORD` | 13.7 | all | The password to pull images through the Dependency Proxy. |
| `CI_DEPENDENCY_PROXY_SERVER` | 13.7 | all | The server for logging in to the Dependency Proxy. This is equivalent to `$CI_SERVER_HOST:$CI_SERVER_PORT`. |
| `CI_DEPENDENCY_PROXY_USER` | 13.7 | all | The username to pull images through the Dependency Proxy. |
@@ -62,7 +63,7 @@ There are also [Kubernetes-specific deployment variables](../../user/project/clu
| `CI_JOB_NAME` | 9.0 | 0.5 | The name of the job. |
| `CI_JOB_STAGE` | 9.0 | 0.5 | The name of the job's stage. |
| `CI_JOB_STATUS` | all | 13.5 | The status of the job as each runner stage is executed. Use with [`after_script`](../yaml/index.md#after_script). Can be `success`, `failed`, or `canceled`. |
-| `CI_JOB_TOKEN` | 9.0 | 1.2 | A token to authenticate with [certain API endpoints](../../api/index.md#gitlab-cicd-job-token). The token is valid as long as the job is running. |
+| `CI_JOB_TOKEN` | 9.0 | 1.2 | A token to authenticate with [certain API endpoints](../jobs/ci_job_token.md). The token is valid as long as the job is running. |
| `CI_JOB_URL` | 11.1 | 0.5 | The job details URL. |
| `CI_JOB_STARTED_AT` | 13.10 | all | The UTC datetime when a job started, in [ISO 8601](https://tools.ietf.org/html/rfc3339#appendix-A) format. |
| `CI_KUBERNETES_ACTIVE` | 13.0 | all | Only available if the pipeline has a Kubernetes cluster available for deployments. `true` when available. |
@@ -82,7 +83,7 @@ There are also [Kubernetes-specific deployment variables](../../user/project/clu
| `CI_PROJECT_ID` | all | all | The ID of the current project. This ID is unique across all projects on the GitLab instance. |
| `CI_PROJECT_NAME` | 8.10 | 0.5 | The name of the directory for the project. For example if the project URL is `gitlab.example.com/group-name/project-1`, `CI_PROJECT_NAME` is `project-1`. |
| `CI_PROJECT_NAMESPACE` | 8.10 | 0.5 | The project namespace (username or group name) of the job. |
-| `CI_PROJECT_PATH_SLUG` | 9.3 | all | `$CI_PROJECT_PATH` in lowercase with characters that are not `a-z` or `0-9` replaced with `-`. Use in URLs and domain names. |
+| `CI_PROJECT_PATH_SLUG` | 9.3 | all | `$CI_PROJECT_PATH` in lowercase with characters that are not `a-z` or `0-9` replaced with `-` and shortened to 63 bytes. Use in URLs and domain names. |
| `CI_PROJECT_PATH` | 8.10 | 0.5 | The project namespace with the project name included. |
| `CI_PROJECT_REPOSITORY_LANGUAGES` | 12.3 | all | A comma-separated, lowercase list of the languages used in the repository. For example `ruby,javascript,html,css`. |
| `CI_PROJECT_ROOT_NAMESPACE` | 13.2 | 0.5 | The root project namespace (username or group name) of the job. For example, if `CI_PROJECT_NAMESPACE` is `root-group/child-group/grandchild-group`, `CI_PROJECT_ROOT_NAMESPACE` is `root-group`. |
diff --git a/doc/ci/variables/where_variables_can_be_used.md b/doc/ci/variables/where_variables_can_be_used.md
index 8009687dbca..0f9339657fe 100644
--- a/doc/ci/variables/where_variables_can_be_used.md
+++ b/doc/ci/variables/where_variables_can_be_used.md
@@ -26,7 +26,7 @@ There are two places defined variables can be used. On the:
|:-------------------------------------------|:-----------------|:-----------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `environment:url` | yes | GitLab | The variable expansion is made by the [internal variable expansion mechanism](#gitlab-internal-variable-expansion-mechanism) in GitLab.<br/><br/>Supported are all variables defined for a job (project/group variables, variables from `.gitlab-ci.yml`, variables from triggers, variables from pipeline schedules).<br/><br/>Not supported are variables defined in the GitLab Runner `config.toml` and variables created in the job's `script`. |
| `environment:name` | yes | GitLab | Similar to `environment:url`, but the variables expansion doesn't support the following:<br/><br/>- Variables that are based on the environment's name (`CI_ENVIRONMENT_NAME`, `CI_ENVIRONMENT_SLUG`).<br/>- Any other variables related to environment (currently only `CI_ENVIRONMENT_URL`).<br/>- [Persisted variables](#persisted-variables). |
-| `resource_group` | yes | GitLab | Similar to `environment:url`, but the variables expansion doesn't support the following:<br/><br/>- Variables that are based on the environment's name (`CI_ENVIRONMENT_NAME`, `CI_ENVIRONMENT_SLUG`).<br/>- Any other variables related to environment (currently only `CI_ENVIRONMENT_URL`).<br/>- [Persisted variables](#persisted-variables). |
+| `resource_group` | yes | GitLab | Similar to `environment:url`, but the variables expansion doesn't support the following:<br/>- `CI_ENVIRONMENT_URL`<br/>- [Persisted variables](#persisted-variables) |
| `include` | yes | GitLab | The variable expansion is made by the [internal variable expansion mechanism](#gitlab-internal-variable-expansion-mechanism) in GitLab. <br/><br/>Predefined project variables are supported: `GITLAB_FEATURES`, `CI_DEFAULT_BRANCH`, and all variables that start with `CI_PROJECT_` (for example `CI_PROJECT_NAME`). |
| `variables` | yes | GitLab/Runner | The variable expansion is first made by the [internal variable expansion mechanism](#gitlab-internal-variable-expansion-mechanism) in GitLab, and then any unrecognized or unavailable variables are expanded by GitLab Runner's [internal variable expansion mechanism](#gitlab-runner-internal-variable-expansion-mechanism). |
| `image` | yes | Runner | The variable expansion is made by GitLab Runner's [internal variable expansion mechanism](#gitlab-runner-internal-variable-expansion-mechanism) |
@@ -63,11 +63,11 @@ because the expansion is done in GitLab before any runner gets the job.
#### Nested variable expansion
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/48627) in GitLab 13.10.
-> - It's [deployed behind a feature flag](../../user/feature_flags.md), disabled by default.
-> - It can be enabled or disabled for a single project.
-> - It's disabled on GitLab.com.
-> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enabling-the-nested-variable-expansion-feature). **(FREE SELF)**
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/48627) in GitLab 13.10. [Deployed behind the `variable_inside_variable` feature flag](../../user/feature_flags.md), disabled by default.
+> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/297382) in GitLab 14.3.
+
+FLAG:
+On self-managed GitLab, by default this feature is disabled. To enable the feature per project or for your entire instance, ask an administrator to [enable the `variable_inside_variable` flag](../../administration/feature_flags.md).
GitLab expands job variable values recursively before sending them to the runner. For example:
@@ -86,29 +86,6 @@ References to unavailable variables are left intact. In this case, the runner
[attempts to expand the variable value](#gitlab-runner-internal-variable-expansion-mechanism) at runtime.
For example, a variable like `CI_BUILDS_DIR` is known by the runner only at runtime.
-##### Enabling the nested variable expansion feature **(FREE SELF)**
-
-This feature comes with the `:variable_inside_variable` feature flag disabled by default.
-
-To enable this feature, ask a GitLab administrator with [Rails console access](../../administration/feature_flags.md#how-to-enable-and-disable-features-behind-flags) to run the
-following command:
-
-```ruby
-# For the instance
-Feature.enable(:variable_inside_variable)
-# For a single project
-Feature.enable(:variable_inside_variable, Project.find(<project id>))
-```
-
-To disable it:
-
-```ruby
-# For the instance
-Feature.disable(:variable_inside_variable)
-# For a single project
-Feature.disable(:variable_inside_variable, Project.find(<project id>))
-```
-
### GitLab Runner internal variable expansion mechanism
- Supported: project/group variables, `.gitlab-ci.yml` variables, `config.toml` variables, and
diff --git a/doc/ci/yaml/gitlab_ci_yaml.md b/doc/ci/yaml/gitlab_ci_yaml.md
index 6cd900123e0..ea05aa45b0b 100644
--- a/doc/ci/yaml/gitlab_ci_yaml.md
+++ b/doc/ci/yaml/gitlab_ci_yaml.md
@@ -1,6 +1,6 @@
---
stage: Verify
-group: Pipeline Execution
+group: Pipeline Authoring
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/#designated-technical-writers
type: reference
---
diff --git a/doc/ci/yaml/includes.md b/doc/ci/yaml/includes.md
index 673a4e75c35..92bf44cca7f 100644
--- a/doc/ci/yaml/includes.md
+++ b/doc/ci/yaml/includes.md
@@ -1,76 +1,81 @@
---
stage: Verify
-group: Pipeline Execution
+group: Pipeline Authoring
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
type: reference
---
# GitLab CI/CD include examples **(FREE)**
-In addition to the [`includes` examples](index.md#include) listed in the
-[GitLab CI YAML reference](index.md), this page lists more variations of `include`
-usage.
+You can use [`include`](index.md#include) to include external YAML files in your CI/CD jobs.
-## Single string or array of multiple values
+## Include a single configuration file
-You can include your extra YAML file(s) either as a single string or
-an array of multiple values. The following examples are all valid.
+To include a single configuration file, use either of these syntax options:
-Single string with the `include:local` method implied:
+- `include` by itself with a single file, which is the same as
+ [`include:local`](index.md#includelocal):
-```yaml
-include: '/templates/.after-script-template.yml'
-```
+ ```yaml
+ include: '/templates/.after-script-template.yml'
+ ```
-Array with `include` method implied:
+- `include` with a single file, and you specify the `include` type:
-```yaml
-include:
- - 'https://gitlab.com/awesome-project/raw/main/.before-script-template.yml'
- - '/templates/.after-script-template.yml'
-```
+ ```yaml
+ include:
+ remote: 'https://gitlab.com/awesome-project/raw/main/.before-script-template.yml'
+ ```
-Single string with `include` method specified explicitly:
+## Include an array of configuration files
-```yaml
-include:
- remote: 'https://gitlab.com/awesome-project/raw/main/.before-script-template.yml'
-```
+You can include an array of configuration files:
-Array with `include:remote` being the single item:
+- If you do not specify an `include` type, the type defaults to [`include:local`](index.md#includelocal):
-```yaml
-include:
- - remote: 'https://gitlab.com/awesome-project/raw/main/.before-script-template.yml'
-```
+ ```yaml
+ include:
+ - 'https://gitlab.com/awesome-project/raw/main/.before-script-template.yml'
+ - '/templates/.after-script-template.yml'
+ ```
-Array with multiple `include` methods specified explicitly:
+- You can define a single item array:
-```yaml
-include:
- - remote: 'https://gitlab.com/awesome-project/raw/main/.before-script-template.yml'
- - local: '/templates/.after-script-template.yml'
- - template: Auto-DevOps.gitlab-ci.yml
-```
+ ```yaml
+ include:
+ - remote: 'https://gitlab.com/awesome-project/raw/main/.before-script-template.yml'
+ ```
-Array mixed syntax:
+- You can define an array and explicitly specify multiple `include` types:
-```yaml
-include:
- - 'https://gitlab.com/awesome-project/raw/main/.before-script-template.yml'
- - '/templates/.after-script-template.yml'
- - template: Auto-DevOps.gitlab-ci.yml
- - project: 'my-group/my-project'
- ref: main
- file: '/templates/.gitlab-ci-template.yml'
-```
+ ```yaml
+ include:
+ - remote: 'https://gitlab.com/awesome-project/raw/main/.before-script-template.yml'
+ - local: '/templates/.after-script-template.yml'
+ - template: Auto-DevOps.gitlab-ci.yml
+ ```
+
+- You can define an array that combines both default and specific `include` type:
+
+ ```yaml
+ include:
+ - 'https://gitlab.com/awesome-project/raw/main/.before-script-template.yml'
+ - '/templates/.after-script-template.yml'
+ - template: Auto-DevOps.gitlab-ci.yml
+ - project: 'my-group/my-project'
+ ref: main
+ file: '/templates/.gitlab-ci-template.yml'
+ ```
-## Re-using a `before_script` template
+## Use `default` configuration from an included configuration file
-In the following example, the content of `.before-script-template.yml` is
-automatically fetched and evaluated along with the content of `.gitlab-ci.yml`.
+You can define a [`default`](index.md#custom-default-keyword-values) section in a
+configuration file. When you use a `default` section with the `include` keyword, the defaults apply to
+all jobs in the pipeline.
-Content of `https://gitlab.com/awesome-project/raw/main/.before-script-template.yml`:
+For example, you can use a `default` section with [`before_script`](index.md#before_script).
+
+Content of a custom configuration file named `/templates/.before-script-template.yml`:
```yaml
default:
@@ -83,19 +88,29 @@ default:
Content of `.gitlab-ci.yml`:
```yaml
-include: 'https://gitlab.com/awesome-project/raw/main/.before-script-template.yml'
+include: '/templates/.before-script-template.yml'
-rspec:
+rspec1:
+ script:
+ - bundle exec rspec
+
+rspec2:
script:
- bundle exec rspec
```
-## Overriding external template values
+The default `before_script` commands execute in both `rspec` jobs, before the `script` commands.
+
+## Override included configuration values
-The following example shows specific YAML-defined variables and details of the
-`production` job from an include file being customized in `.gitlab-ci.yml`.
+When you use the `include` keyword, you can override the included configuration values to adapt them
+to your pipeline requirements.
-Content of `https://company.com/autodevops-template.yml`:
+The following example shows an `include` file that is customized in the
+`.gitlab-ci.yml` file. Specific YAML-defined variables and details of the
+`production` job are overridden.
+
+Content of a custom configuration file named `autodevops-template.yml`:
```yaml
variables:
@@ -136,17 +151,18 @@ production:
url: https://domain.com
```
-In this case, the variables `POSTGRES_USER` and `POSTGRES_PASSWORD` along
-with the environment URL of the `production` job defined in
-`autodevops-template.yml` have been overridden by new values defined in
-`.gitlab-ci.yml`.
+The `POSTGRES_USER` and `POSTGRES_PASSWORD` variables
+and the `environment:url` of the `production` job defined in the `.gitlab-ci.yml` file
+override the values defined in the `autodevops-template.yml` file. The other keywords
+do not change. This method is called *merging*.
+
+## Override included configuration arrays
-The merging lets you extend and override dictionary mappings, but
-you cannot add or modify items to an included array. For example, to add
-an additional item to the production job script, you must repeat the
-existing script items:
+You can use merging to extend and override configuration in an included template, but
+you cannot add or modify individual items in an array. For example, to add
+an additional `notify_owner` command to the extended `production` job's `script` array:
-Content of `https://company.com/autodevops-template.yml`:
+Content of `autodevops-template.yml`:
```yaml
production:
@@ -159,7 +175,7 @@ production:
Content of `.gitlab-ci.yml`:
```yaml
-include: 'https://company.com/autodevops-template.yml'
+include: 'autodevops-template.yml'
stages:
- production
@@ -171,51 +187,32 @@ production:
- notify_owner
```
-In this case, if `install_dependencies` and `deploy` were not repeated in
-`.gitlab-ci.yml`, they would not be part of the script for the `production`
-job in the combined CI configuration.
+If `install_dependencies` and `deploy` are not repeated in
+the `.gitlab-ci.yml` file, the `production` job would have only `notify_owner` in the script.
-## Using nested includes
+## Use nested includes
-The examples below show how includes can be nested from different sources
-using a combination of different methods.
+You can nest `include` sections in configuration files that are then included
+in another configuration. For example, for `include` keywords nested three deep:
-In this example, `.gitlab-ci.yml` includes local the file `/.gitlab-ci/another-config.yml`:
+Content of `.gitlab-ci.yml`:
```yaml
include:
- local: /.gitlab-ci/another-config.yml
```
-The `/.gitlab-ci/another-config.yml` includes a template and the `/templates/docker-workflow.yml` file
-from another project:
+Content of `/.gitlab-ci/another-config.yml`:
```yaml
include:
- - template: Bash.gitlab-ci.yml
- - project: group/my-project
- file: /templates/docker-workflow.yml
+ - local: /.gitlab-ci/config-defaults.yml
```
-The `/templates/docker-workflow.yml` present in `group/my-project` includes two local files
-of the `group/my-project`:
+Content of `/.gitlab-ci/config-defaults.yml`:
```yaml
-include:
- - local: /templates/docker-build.yml
- - local: /templates/docker-testing.yml
-```
-
-Our `/templates/docker-build.yml` present in `group/my-project` adds a `docker-build` job:
-
-```yaml
-docker-build:
- script: docker build -t my-image .
-```
-
-Our second `/templates/docker-test.yml` present in `group/my-project` adds a `docker-test` job:
-
-```yaml
-docker-test:
- script: docker run my-image /run/tests.sh
+default:
+ after_script:
+ - echo "Job complete."
```
diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md
index 63f626e524e..fb5748788f7 100644
--- a/doc/ci/yaml/index.md
+++ b/doc/ci/yaml/index.md
@@ -1,15 +1,11 @@
---
stage: Verify
-group: Pipeline Execution
+group: Pipeline Authoring
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
type: reference
---
-<!-- markdownlint-disable MD044 -->
-<!-- vale gitlab.Spelling = NO -->
-# Keyword reference for the .gitlab-ci.yml file **(FREE)**
-<!-- vale gitlab.Spelling = YES -->
-<!-- markdownlint-enable MD044 -->
+# Keyword reference for the `.gitlab-ci.yml` file **(FREE)**
This document lists the configuration options for your GitLab `.gitlab-ci.yml` file.
@@ -331,7 +327,7 @@ include:
#### Switch between branch pipelines and merge request pipelines
-> [Introduced in](https://gitlab.com/gitlab-org/gitlab/-/issues/201845) GitLab 13.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/201845) in GitLab 13.8.
To make the pipeline switch from branch pipelines to merge request pipelines after
a merge request is created, add a `workflow: rules` section to your `.gitlab-ci.yml` file.
@@ -386,7 +382,7 @@ does not block triggered pipelines.
> [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/42861) to GitLab Free in 11.4.
Use `include` to include external YAML files in your CI/CD configuration.
-You can break down one long `gitlab-ci.yml` file into multiple files to increase readability,
+You can break down one long `.gitlab-ci.yml` file into multiple files to increase readability,
or reduce duplication of the same configuration in multiple places.
You can also store template files in a central repository and `include` them in projects.
@@ -434,7 +430,7 @@ In `include` sections in your `.gitlab-ci.yml` file, you can use:
- [Project variables](../variables/index.md#add-a-cicd-variable-to-a-project)
- [Group variables](../variables/index.md#add-a-cicd-variable-to-a-group)
- [Instance variables](../variables/index.md#add-a-cicd-variable-to-an-instance)
-- Project [predefined variables](../variables/predefined_variables.md).
+- Project [predefined variables](../variables/predefined_variables.md).
```yaml
include:
@@ -450,12 +446,12 @@ that proposes expanding this feature to support more variables.
#### `rules` with `include`
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/276515) in GitLab 14.2.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/276515) in GitLab 14.2.
+> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/337507) in GitLab 14.3 and is ready for production use.
+> - [Enabled with `ci_include_rules` flag](https://gitlab.com/gitlab-org/gitlab/-/issues/337507) for self-managed GitLab in GitLab 14.3 and is ready for production use.
-NOTE:
-On self-managed GitLab, by default this feature is not available. To make it available,
-ask an administrator to [enable the `ci_include_rules` flag](../../administration/feature_flags.md).
-On GitLab.com, this feature is not available. The feature is not ready for production use.
+FLAG:
+On self-managed GitLab, by default this feature is available. To hide the feature per project or for your entire instance, ask an administrator to [disable the `ci_include_rules` flag](../../administration/feature_flags.md). On GitLab.com, this feature is available.
You can use [`rules`](#rules) with `include` to conditionally include other configuration files.
You can only use `rules:if` in `include` with [certain variables](#variables-with-include).
@@ -626,7 +622,7 @@ Use nested includes to compose a set of includes.
You can have up to 100 includes, but you can't have duplicate includes.
-In [GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/issues/28212) and later, the time limit
+In [GitLab 12.4 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/28212), the time limit
to resolve all files is 30 seconds.
#### Additional `includes` examples
@@ -1141,6 +1137,9 @@ The job is not added to the pipeline:
- If no rules match.
- If a rule matches and has `when: never`.
+You can use [`!reference` tags](#reference-tags) to [reuse `rules` configuration](../jobs/job_control.md#reuse-rules-in-different-jobs)
+in different jobs.
+
#### `rules:if`
Use `rules:if` clauses to specify when to add a job to a pipeline:
@@ -1368,7 +1367,7 @@ pipeline based on branch names or pipeline types.
| `pushes` | For pipelines triggered by a `git push` event, including for branches and tags. |
| `schedules` | For [scheduled pipelines](../pipelines/schedules.md). |
| `tags` | When the Git reference for a pipeline is a tag. |
- | `triggers` | For pipelines created by using a [trigger token](../triggers/index.md#trigger-token). |
+ | `triggers` | For pipelines created by using a [trigger token](../triggers/index.md#authentication-tokens). |
| `web` | For pipelines created by using **Run pipeline** button in the GitLab UI, from the project's **CI/CD > Pipelines** section. |
**Example of `only:refs` and `except:refs`**:
@@ -1591,27 +1590,23 @@ production:
#### Requirements and limitations
-- In [GitLab 14.1 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/30632) you
- can refer to jobs in the same stage as the job you are configuring. This feature is
- enabled on GitLab.com and ready for production use. On self-managed [GitLab 14.2 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/30632)
- this feature is available by default. To hide the feature, ask an administrator to
- [disable the `ci_same_stage_job_needs` flag](../../administration/feature_flags.md).
-- In GitLab 14.0 and older, you can only refer to jobs in earlier stages.
-- In GitLab 13.9 and older, if `needs:` refers to a job that might not be added to
- a pipeline because of `only`, `except`, or `rules`, the pipeline might fail to create.
- The maximum number of jobs that a single job can need in the `needs:` array is limited:
- For GitLab.com, the limit is 50. For more information, see our
[infrastructure issue](https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/7541).
- - For self-managed instances, the limit is: 50. This limit [can be changed](#changing-the-needs-job-limit).
+ - For self-managed instances, the default limit is 50. This limit [can be changed](#changing-the-needs-job-limit).
- If `needs:` refers to a job that uses the [`parallel`](#parallel) keyword,
it depends on all jobs created in parallel, not just one job. It also downloads
artifacts from all the parallel jobs by default. If the artifacts have the same
name, they overwrite each other and only the last one downloaded is saved.
-- `needs:` is similar to `dependencies:` in that it must use jobs from prior stages,
- meaning it's impossible to create circular dependencies. Depending on jobs in the
- current stage is not possible either, but [an issue exists](https://gitlab.com/gitlab-org/gitlab/-/issues/30632).
-- Stages must be explicitly defined for all jobs
- that have the keyword `needs:` or are referred to by one.
+- In [GitLab 14.1 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/30632) you
+ can refer to jobs in the same stage as the job you are configuring. This feature is
+ enabled on GitLab.com and ready for production use. On self-managed [GitLab 14.2 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/30632)
+ this feature is available by default.
+- In GitLab 14.0 and older, you can only refer to jobs in earlier stages. Stages must be
+ explicitly defined for all jobs that use the `needs:` keyword, or are referenced
+ in a job's `needs:` section.
+- In GitLab 13.9 and older, if `needs:` refers to a job that might not be added to
+ a pipeline because of `only`, `except`, or `rules`, the pipeline might fail to create.
##### Changing the `needs:` job limit **(FREE SELF)**
@@ -1628,7 +1623,7 @@ To disable directed acyclic graphs (DAG), set the limit to `0`.
#### Artifact downloads with `needs`
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14311) in GitLab v12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14311) in GitLab 12.6.
When a job uses `needs`, it no longer downloads all artifacts from previous stages
by default, because jobs with `needs` can start before earlier stages complete. With
@@ -1680,7 +1675,7 @@ with `needs`.
#### Cross project artifact downloads with `needs` **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14311) in GitLab v12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14311) in GitLab 12.7.
Use `needs` to download artifacts from up to five jobs in pipelines:
@@ -1753,7 +1748,7 @@ pipelines running on the same ref could override the artifacts.
#### Artifact downloads to child pipelines
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/255983) in GitLab v13.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/255983) in GitLab 13.7.
A [child pipeline](../pipelines/parent_child_pipelines.md) can download artifacts from a job in
its parent pipeline or another child pipeline in the same parent-child pipeline hierarchy.
@@ -1832,14 +1827,25 @@ rspec:
### `tags`
+> - A limit of 50 tags per job [enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/338929) in GitLab 14.3.
+> - A limit of 50 tags per job [enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/339855) in GitLab 14.3.
+
Use `tags` to select a specific runner from the list of all runners that are
available for the project.
When you register a runner, you can specify the runner's tags, for
-example `ruby`, `postgres`, `development`.
+example `ruby`, `postgres`, or `development`. To pick up and run a job, a runner must
+be assigned every tag listed in the job.
+
+**Keyword type**: Job keyword. You can use it only as part of a job or in the
+[`default:` section](#custom-default-keyword-values).
+
+**Possible inputs**:
-In the following example, the job is run by a runner that
-has both `ruby` and `postgres` tags defined.
+- An array of tag names.
+- [CI/CD variables](../runners/configure_runners.md#use-cicd-variables-in-tags) in GitLab 14.1 and later.
+
+**Example of `tags`**:
```yaml
job:
@@ -1848,75 +1854,56 @@ job:
- postgres
```
-You can use tags to run different jobs on different platforms. For
-example, if you have an OS X runner with tag `osx` and a Windows runner with tag
-`windows`, you can run a job on each platform:
+In this example, only runners with *both* the `ruby` and `postgres` tags can run the job.
-```yaml
-windows job:
- stage:
- - build
- tags:
- - windows
- script:
- - echo Hello, %USERNAME%!
+**Additional details**:
-osx job:
- stage:
- - build
- tags:
- - osx
- script:
- - echo "Hello, $USER!"
-```
+- In [GitLab 14.3](https://gitlab.com/gitlab-org/gitlab/-/issues/338479) and later,
+ the number of tags must be less than `50`.
-In [GitLab 14.1 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/35742), you can
-use [CI/CD variables](../variables/index.md) with `tags` for dynamic runner selection:
+**Related topics**:
-```yaml
-variables:
- KUBERNETES_RUNNER: kubernetes
-
- job:
- tags:
- - docker
- - $KUBERNETES_RUNNER
- script:
- - echo "Hello runner selector feature"
-```
+- [Use tags to control which jobs a runner can run](../runners/configure_runners.md#use-tags-to-control-which-jobs-a-runner-can-run).
### `allow_failure`
-Use `allow_failure` when you want to let a job fail without impacting the rest of the CI
-suite. The default value is `false`, except for [manual](../jobs/job_control.md#create-a-job-that-must-be-run-manually) jobs that use
-the [`when: manual`](#when) syntax.
+Use `allow_failure` to determine whether a pipeline should continue running when a job fails.
+
+- To let the pipeline continue running subsequent jobs, use `allow_failure: true`.
+- To stop the pipeline from running subsequent jobs, use `allow_failure: false`.
-In jobs that use [`rules:`](#rules), all jobs default to `allow_failure: false`,
-*including* `when: manual` jobs.
+When jobs are allowed to fail (`allow_failure: true`) an orange warning (**{status_warning}**)
+indicates that a job failed. However, the pipeline is successful and the associated commit
+is marked as passed with no warnings.
-When `allow_failure` is set to `true` and the job fails, the job shows an orange warning in the UI.
-However, the logical flow of the pipeline considers the job a
-success/passed, and is not blocked.
+This same warning is displayed when:
-Assuming all other jobs are successful, the job's stage and its pipeline
-show the same orange warning. However, the associated commit is marked as
-"passed", without warnings.
+- All other jobs in the stage are successful.
+- All other jobs in the pipeline are successful.
-In the following example, `job1` and `job2` run in parallel. If `job1`
-fails, it doesn't stop the next stage from running, because it's marked with
-`allow_failure: true`:
+The default value for `allow_failure` is:
+
+- `true` for [manual jobs](../jobs/job_control.md#create-a-job-that-must-be-run-manually).
+- `false` for manual jobs that also use [`rules`](#rules).
+- `false` in all other cases.
+
+**Keyword type**: Job keyword. You can use it only as part of a job.
+
+**Possible inputs**: `true` or `false`.
+
+**Example of `allow_failure`**:
```yaml
job1:
stage: test
script:
- - execute_script_that_will_fail
- allow_failure: true
+ - execute_script_1
job2:
stage: test
script:
- - execute_script_that_will_succeed
+ - execute_script_2
+ allow_failure: true
job3:
stage: deploy
@@ -1924,14 +1911,35 @@ job3:
- deploy_to_staging
```
+In this example, `job1` and `job2` run in parallel:
+
+- If `job1` fails, jobs in the `deploy` stage do not start.
+- If `job2` fails, jobs in the `deploy` stage can still start.
+
+**Additional details**:
+
+- You can use `allow_failure` as a subkey of [`rules:`](#rulesallow_failure).
+- You can use `allow_failure: false` with a manual job to create a [blocking manual job](../jobs/job_control.md#types-of-manual-jobs).
+ A blocked pipeline does not run any jobs in later stages until the manual job
+ is started and completes successfully.
+
#### `allow_failure:exit_codes`
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/273157) in GitLab 13.8.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/292024) in GitLab 13.9.
-Use `allow_failure:exit_codes` to dynamically control if a job should be allowed
-to fail. You can list which exit codes are not considered failures. The job fails
-for any other exit code:
+Use `allow_failure:exit_codes` to control when a job should be
+allowed to fail. The job is `allow_failure: true` for any of the listed exit codes,
+and `allow_failure` false for any other exit code.
+
+**Keyword type**: Job keyword. You can use it only as part of a job.
+
+**Possible inputs**:
+
+- A single exit code.
+- An array of exit codes.
+
+**Example of `allow_failure`**:
```yaml
test_job_1:
@@ -2017,7 +2025,7 @@ In this example, the script:
**Additional details**:
-- In [GitLab 13.5](https://gitlab.com/gitlab-org/gitlab/-/issues/201938) and later, you
+- In [GitLab 13.5 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/201938), you
can use `when:manual` in the same job as [`trigger`](#trigger). In GitLab 13.4 and
earlier, using them together causes the error `jobs:#{job-name} when should be on_success, on_failure or always`.
- The default behavior of `allow_failure` changes to `true` with `when: manual`.
@@ -2136,7 +2144,7 @@ review_app:
stage: deploy
script: make deploy-app
environment:
- name: review/$CI_COMMIT_REF_NAME
+ name: review/$CI_COMMIT_REF_SLUG
url: https://$CI_ENVIRONMENT_SLUG.example.com
on_stop: stop_review_app
@@ -2147,7 +2155,7 @@ stop_review_app:
script: make delete-app
when: manual
environment:
- name: review/$CI_COMMIT_REF_NAME
+ name: review/$CI_COMMIT_REF_SLUG
action: stop
```
@@ -2197,7 +2205,7 @@ For example,
review_app:
script: deploy-review-app
environment:
- name: review/$CI_COMMIT_REF_NAME
+ name: review/$CI_COMMIT_REF_SLUG
auto_stop_in: 1 day
```
@@ -2267,12 +2275,12 @@ deploy as review app:
stage: deploy
script: make deploy
environment:
- name: review/$CI_COMMIT_REF_NAME
+ name: review/$CI_COMMIT_REF_SLUG
url: https://$CI_ENVIRONMENT_SLUG.example.com/
```
The `deploy as review app` job is marked as a deployment to dynamically
-create the `review/$CI_COMMIT_REF_NAME` environment. `$CI_COMMIT_REF_NAME`
+create the `review/$CI_COMMIT_REF_SLUG` environment. `$CI_COMMIT_REF_SLUG`
is a [CI/CD variable](../variables/index.md) set by the runner. The
`$CI_ENVIRONMENT_SLUG` variable is based on the environment name, but suitable
for inclusion in URLs. If the `deploy as review app` job runs in a branch named
@@ -2301,7 +2309,7 @@ Use the `cache:paths` keyword to choose which files or directories to cache.
You can use wildcards that use [glob](https://en.wikipedia.org/wiki/Glob_(programming))
patterns:
-- In [GitLab Runner 13.0](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2620) and later,
+- In [GitLab Runner 13.0 and later](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2620),
[`doublestar.Glob`](https://pkg.go.dev/github.com/bmatcuk/doublestar@v1.2.2?tab=doc#Match).
- In GitLab Runner 12.10 and earlier,
[`filepath.Match`](https://pkg.go.dev/path/filepath#Match).
@@ -2377,7 +2385,7 @@ cache-job:
##### `cache:key:files`
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18986) in GitLab v12.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18986) in GitLab 12.5.
Use the `cache:key:files` keyword to generate a new key when one or two specific files
change. `cache:key:files` lets you reuse some caches, and rebuild them less often,
@@ -2415,7 +2423,7 @@ fallback key is `default`.
##### `cache:key:prefix`
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18986) in GitLab v12.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18986) in GitLab 12.5.
Use `cache:key:prefix` to combine a prefix with the SHA computed for [`cache:key:files`](#cachekeyfiles).
@@ -2864,7 +2872,7 @@ Paths are relative to the project directory (`$CI_PROJECT_DIR`) and can't direct
link outside it. You can use Wildcards that use [glob](https://en.wikipedia.org/wiki/Glob_(programming))
patterns and:
-- In [GitLab Runner 13.0](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2620) and later,
+- In [GitLab Runner 13.0 and later](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2620),
[`doublestar.Glob`](https://pkg.go.dev/github.com/bmatcuk/doublestar@v1.2.2?tab=doc#Match).
- In GitLab Runner 12.10 and earlier,
[`filepath.Match`](https://pkg.go.dev/path/filepath#Match).
@@ -3120,7 +3128,7 @@ dashboards.
##### `artifacts:reports:load_performance` **(PREMIUM)**
-> - Introduced in [GitLab 13.2](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35260) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.2.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35260) in GitLab 13.2.
> - Requires GitLab Runner 11.5 and above.
The `load_performance` report collects [Load Performance Testing metrics](../../user/project/merge_requests/load_performance_testing.md)
@@ -3163,7 +3171,7 @@ marked as Satisfied.
##### `artifacts:reports:sast`
> - Introduced in GitLab 11.5.
-> - Made [available in all tiers](https://gitlab.com/groups/gitlab-org/-/epics/2098) in GitLab 13.3.
+> - [Moved](https://gitlab.com/groups/gitlab-org/-/epics/2098) from GitLab Ultimate to GitLab Free in 13.3.
> - Requires GitLab Runner 11.5 and above.
The `sast` report collects [SAST vulnerabilities](../../user/application_security/sast/index.md)
@@ -3176,8 +3184,7 @@ dashboards.
##### `artifacts:reports:secret_detection`
> - Introduced in GitLab 13.1.
-> - Made [available in all tiers](https://gitlab.com/gitlab-org/gitlab/-/issues/222788) in GitLab
- 13.3.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/222788) to GitLab Free in 13.3.
> - Requires GitLab Runner 11.5 and above.
The `secret-detection` report collects [detected secrets](../../user/application_security/secret_detection/index.md)
@@ -3192,10 +3199,10 @@ dashboards.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207528) in GitLab 13.0.
> - Requires [GitLab Runner](https://docs.gitlab.com/runner/) 11.5 and above.
-The `terraform` report obtains a Terraform `tfplan.json` file. [JQ processing required to remove credentials](../../user/infrastructure/mr_integration.md#configure-terraform-report-artifacts). The collected Terraform
+The `terraform` report obtains a Terraform `tfplan.json` file. [JQ processing required to remove credentials](../../user/infrastructure/iac/mr_integration.md#configure-terraform-report-artifacts). The collected Terraform
plan report uploads to GitLab as an artifact and displays
in merge requests. For more information, see
-[Output `terraform plan` information into a merge request](../../user/infrastructure/mr_integration.md).
+[Output `terraform plan` information into a merge request](../../user/infrastructure/iac/mr_integration.md).
#### `artifacts:untracked`
@@ -3404,7 +3411,22 @@ You can specify the number of [retry attempts for certain stages of job executio
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14887) in GitLab 12.3.
-Use `timeout` to configure a timeout for a specific job. For example:
+Use `timeout` to configure a timeout for a specific job. If the job runs for longer
+than the timeout, the job fails.
+
+The job-level timeout can be longer than the [project-level timeout](../pipelines/settings.md#set-a-limit-for-how-long-jobs-can-run).
+but can't be longer than the [runner's timeout](../runners/configure_runners.md#set-maximum-job-timeout-for-a-runner).
+
+**Keyword type**: Job keyword. You can use it only as part of a job or in the
+[`default:` section](#custom-default-keyword-values).
+
+**Possible inputs**: A period of time written in natural language. For example, these are all equivalent:
+
+- `3600 seconds`
+- `60 minutes`
+- `one hour`
+
+**Example of `timeout`**:
```yaml
build:
@@ -3416,10 +3438,6 @@ test:
timeout: 3h 30m
```
-The job-level timeout can exceed the
-[project-level timeout](../pipelines/settings.md#set-a-limit-for-how-long-jobs-can-run) but can't
-exceed the runner-specific timeout.
-
### `parallel`
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/21480) in GitLab 11.5.
@@ -3583,7 +3601,7 @@ deploystacks:
### `trigger`
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8997) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.8.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8997) in GitLab Premium 11.8.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/199224) to GitLab Free in 12.8.
Use `trigger` to define a downstream pipeline trigger. When GitLab starts a `trigger` job,
@@ -3598,11 +3616,11 @@ You can use this keyword to create two different types of downstream pipelines:
- [Multi-project pipelines](../pipelines/multi_project_pipelines.md#define-multi-project-pipelines-in-your-gitlab-ciyml-file)
- [Child pipelines](../pipelines/parent_child_pipelines.md)
-[In GitLab 13.2](https://gitlab.com/gitlab-org/gitlab/-/issues/197140/) and later, you can
+In [GitLab 13.2 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/197140/), you can
view which job triggered a downstream pipeline. In the [pipeline graph](../pipelines/index.md#visualize-pipelines),
hover over the downstream pipeline job.
-In [GitLab 13.5](https://gitlab.com/gitlab-org/gitlab/-/issues/201938) and later, you
+In [GitLab 13.5 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/201938), you
can use [`when:manual`](#when) in the same job as `trigger`. In GitLab 13.4 and
earlier, using them together causes the error `jobs:#{job-name} when should be on_success, on_failure or always`.
You [cannot start `manual` trigger jobs with the API](https://gitlab.com/gitlab-org/gitlab/-/issues/284086).
@@ -3756,25 +3774,19 @@ The trigger token is different than the [`trigger`](#trigger) keyword.
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32022) in GitLab 12.3.
-Use `interruptible` to indicate that a running job should be canceled if made redundant by a newer pipeline run.
-Defaults to `false` (uninterruptible). Jobs that have not started yet (pending) are considered interruptible
-and safe to be cancelled.
-This value is used only if the [automatic cancellation of redundant pipelines feature](../pipelines/settings.md#auto-cancel-redundant-pipelines)
-is enabled.
-
-When enabled, a pipeline is immediately canceled when a new pipeline starts on the same branch if either of the following is true:
+Use `interruptible` if a job should be canceled when a newer pipeline starts before the job completes.
-- All jobs in the pipeline are set as interruptible.
-- Any uninterruptible jobs have not started yet.
+This keyword is used with the [automatic cancellation of redundant pipelines](../pipelines/settings.md#auto-cancel-redundant-pipelines)
+feature. When enabled, a running job with `interruptible: true` can be cancelled when
+a new pipeline starts on the same branch.
-Set jobs as interruptible that can be safely canceled once started (for instance, a build job).
+You can't cancel subsequent jobs after a job with `interruptible: false` starts.
-In the following example, a new pipeline run causes an existing running pipeline to be:
+**Keyword type**: Job keyword. You can use it only as part of a job.
-- Canceled, if only `step-1` is running or pending.
-- Not canceled, once `step-2` starts running.
+**Possible inputs**: `true` or `false` (default).
-After an uninterruptible job starts running, the pipeline cannot be canceled.
+**Example of `interruptible`**:
```yaml
stages:
@@ -3800,15 +3812,27 @@ step-3:
interruptible: true
```
+In this example, a new pipeline causes a running pipeline to be:
+
+- Canceled, if only `step-1` is running or pending.
+- Not canceled, after `step-2` starts.
+
+**Additional details**:
+
+- Only set `interruptible: true` if the job can be safely canceled after it has started,
+ like a build job. Deployment jobs usually shouldn't be cancelled, to prevent partial deployments.
+- To completely cancel a running pipeline, all jobs must have `interruptible: true`,
+ or `interruptible: false` jobs must not have started.
+
### `resource_group`
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15536) in GitLab 12.7.
-Sometimes running multiple jobs or pipelines at the same time in an environment
+Sometimes running multiple jobs at the same time in an environment
can lead to errors during the deployment.
To avoid these errors, use the `resource_group` attribute to make sure that
-the runner doesn't run certain jobs simultaneously. Resource groups behave similar
+the runner doesn't run certain jobs concurrently. Resource groups behave similar
to semaphores in other programming languages.
When the `resource_group` keyword is defined for a job in the `.gitlab-ci.yml` file,
@@ -4333,15 +4357,12 @@ name level and not in the `vault` section.
### `pages`
-Use `pages` to upload static content to GitLab. The content
-is then published as a website. You must:
+Use `pages` to define a [GitLab Pages](../../user/project/pages/index.md) job that
+uploads static content to GitLab. The content is then published as a website.
-- Place any static content in a `public/` directory.
-- Define [`artifacts`](#artifacts) with a path to the `public/` directory.
+**Keyword type**: Job name.
-The following example moves all files from the root of the project to the
-`public/` directory. The `.public` workaround is so `cp` does not also copy
-`public/` to itself in an infinite loop:
+**Example of `pages`**:
```yaml
pages:
@@ -4357,7 +4378,15 @@ pages:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
```
-View the [GitLab Pages user documentation](../../user/project/pages/index.md).
+This example moves all files from the root of the project to the `public/` directory.
+The `.public` workaround is so `cp` does not also copy `public/` to itself in an infinite loop.
+
+**Additional details**:
+
+You must:
+
+- Place any static content in a `public/` directory.
+- Define [`artifacts`](#artifacts) with a path to the `public/` directory.
### `inherit`
@@ -4481,7 +4510,7 @@ deploy_review_job:
You can use only integers and strings for the variable's name and value.
-If you define a variable at the top level of the `gitlab-ci.yml` file, it is global,
+If you define a variable at the top level of the `.gitlab-ci.yml` file, it is global,
meaning it applies to all jobs. If you define a variable in a job, it's available
to that job only.
@@ -4495,7 +4524,7 @@ You can use [YAML anchors for variables](#yaml-anchors-for-variables).
### Prefill variables in manual pipelines
-> [Introduced in](https://gitlab.com/gitlab-org/gitlab/-/issues/30101) GitLab 13.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30101) in GitLab 13.7.
Use the `value` and `description` keywords to define [pipeline-level (global) variables that are prefilled](../pipelines/index.md#prefill-variables-in-manual-pipelines)
when [running a pipeline manually](../pipelines/index.md#run-a-pipeline-manually):
@@ -4763,6 +4792,7 @@ into templates.
### `!reference` tags
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/266173) in GitLab 13.9.
+> - `rules` keyword support [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/322992) in GitLab 14.3.
Use the `!reference` custom YAML tag to select keyword configuration from other job
sections and reuse it in the current section. Unlike [YAML anchors](#anchors), you can
diff --git a/doc/ci/yaml/script.md b/doc/ci/yaml/script.md
index 93c1a6afe69..626ede21fa5 100644
--- a/doc/ci/yaml/script.md
+++ b/doc/ci/yaml/script.md
@@ -1,6 +1,6 @@
---
stage: Verify
-group: Pipeline Execution
+group: Pipeline Authoring
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
type: reference
---
diff --git a/doc/development/adding_service_component.md b/doc/development/adding_service_component.md
index 503d1b7e55b..f5acf0d26eb 100644
--- a/doc/development/adding_service_component.md
+++ b/doc/development/adding_service_component.md
@@ -47,8 +47,7 @@ Adding a new service follows the same [merge request workflow](contributing/merg
The first iteration should be to add the ability to connect and use the service as an externally installed component. Often this involves providing settings in GitLab to connect to the service, or allow connections from it. And then shipping documentation on how to install and configure the service with GitLab.
-NOTE:
-[Elasticsearch](../integration/elasticsearch.md#installing-elasticsearch) is an example of a service that has been integrated this way. And many of the other services, including internal projects like Gitaly, started off as separately installed alternatives.
+[Elasticsearch](../integration/elasticsearch.md#install-elasticsearch) is an example of a service that has been integrated this way. Many of the other services, including internal projects like Gitaly, started off as separately installed alternatives.
**For services that depend on the existing GitLab codebase:**
diff --git a/doc/development/api_graphql_styleguide.md b/doc/development/api_graphql_styleguide.md
index 40cc8f5ec45..9a17ac4c813 100644
--- a/doc/development/api_graphql_styleguide.md
+++ b/doc/development/api_graphql_styleguide.md
@@ -532,7 +532,7 @@ Example:
```ruby
field :foo, GraphQL::Types::String,
null: true,
- description: 'Some test field. Will always return `null`' \
+ description: 'Some test field. Returns `null`' \
'if `my_feature_flag` feature flag is disabled.'
def foo
@@ -940,7 +940,9 @@ class PostResolver < BaseResolver
end
```
-You should never re-use resolvers directly. Resolvers have a complex life-cycle, with
+While you can use the same resolver class in two different places,
+such as in two different fields where the same object is exposed,
+you should never re-use resolver objects directly. Resolvers have a complex life-cycle, with
authorization, readiness and resolution orchestrated by the framework, and at
each stage [lazy values](#laziness) can be returned to take advantage of batching
opportunities. Never instantiate a resolver or a mutation in application code.
diff --git a/doc/development/application_limits.md b/doc/development/application_limits.md
index b606cda1124..2075e7cda3c 100644
--- a/doc/development/application_limits.md
+++ b/doc/development/application_limits.md
@@ -40,9 +40,7 @@ It's recommended to create two separate migration script files.
desired limit using `create_or_update_plan_limit` migration helper, such as:
```ruby
- class InsertProjectHooksPlanLimits < ActiveRecord::Migration[5.2]
- include Gitlab::Database::MigrationHelpers
-
+ class InsertProjectHooksPlanLimits < Gitlab::Database::Migration[1.0]
def up
create_or_update_plan_limit('project_hooks', 'default', 0)
create_or_update_plan_limit('project_hooks', 'free', 10)
diff --git a/doc/development/architecture.md b/doc/development/architecture.md
index a487e84d090..fe2b621da29 100644
--- a/doc/development/architecture.md
+++ b/doc/development/architecture.md
@@ -603,14 +603,14 @@ For monitoring deployed apps, see [Jaeger tracing documentation](../operations/t
- Layer: Core Service
- Process: `logrotate`
-GitLab is comprised of a large number of services that all log. We started bundling our own Logrotate
-as of GitLab 7.4 to make sure we were logging responsibly. This is just a packaged version of the common open source offering.
+GitLab is comprised of a large number of services that all log. We bundle our own Logrotate
+to make sure we were logging responsibly. This is just a packaged version of the common open source offering.
#### Mattermost
- [Project page](https://github.com/mattermost/mattermost-server/blob/master/README.md)
- Configuration:
- - [Omnibus](https://docs.gitlab.com/omnibus/gitlab-mattermost/)
+ - [Omnibus](../integration/mattermost/index.md)
- [Charts](https://docs.mattermost.com/install/install-mmte-helm-gitlab-helm.html)
- Layer: Core Service (Processor)
- GitLab.com: [Mattermost](../user/project/integrations/mattermost.md)
diff --git a/doc/development/avoiding_downtime_in_migrations.md b/doc/development/avoiding_downtime_in_migrations.md
index b844415c94e..9418eafa487 100644
--- a/doc/development/avoiding_downtime_in_migrations.md
+++ b/doc/development/avoiding_downtime_in_migrations.md
@@ -95,9 +95,7 @@ renaming. For example
```ruby
# A regular migration in db/migrate
-class RenameUsersUpdatedAtToUpdatedAtTimestamp < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
+class RenameUsersUpdatedAtToUpdatedAtTimestamp < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
@@ -125,9 +123,7 @@ We can perform this cleanup using
```ruby
# A post-deployment migration in db/post_migrate
-class CleanupUsersUpdatedAtRename < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
+class CleanupUsersUpdatedAtRename < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
@@ -174,9 +170,7 @@ as follows:
```ruby
# A regular migration in db/migrate
-class ChangeUsersUsernameStringToText < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
+class ChangeUsersUsernameStringToText < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
@@ -195,9 +189,7 @@ Next we need to clean up our changes using a post-deployment migration:
```ruby
# A post-deployment migration in db/post_migrate
-class ChangeUsersUsernameStringToTextCleanup < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
+class ChangeUsersUsernameStringToTextCleanup < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
@@ -245,9 +237,7 @@ the work / load over a longer time period, without slowing down deployments.
For example, to change the column type using a background migration:
```ruby
-class ExampleMigration < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
+class ExampleMigration < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
class Issue < ActiveRecord::Base
@@ -289,9 +279,7 @@ release) by a cleanup migration, which should steal from the queue and handle
any remaining rows. For example:
```ruby
-class MigrateRemainingIssuesClosedAt < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
+class MigrateRemainingIssuesClosedAt < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
class Issue < ActiveRecord::Base
diff --git a/doc/development/background_migrations.md b/doc/development/background_migrations.md
index 695c565ca83..c93b5b448f0 100644
--- a/doc/development/background_migrations.md
+++ b/doc/development/background_migrations.md
@@ -254,7 +254,7 @@ existing data. Since we're dealing with a lot of rows we'll schedule jobs in
batches instead of doing this one by one:
```ruby
-class ScheduleExtractServicesUrl < ActiveRecord::Migration[4.2]
+class ScheduleExtractServicesUrl < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
@@ -281,7 +281,7 @@ jobs and manually run on any un-migrated rows. Such a migration would look like
this:
```ruby
-class ConsumeRemainingExtractServicesUrlJobs < ActiveRecord::Migration[4.2]
+class ConsumeRemainingExtractServicesUrlJobs < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
@@ -463,8 +463,6 @@ end
```ruby
# Post deployment migration
-include Gitlab::Database::MigrationHelpers
-
MIGRATION = 'YourBackgroundMigrationName'
DELAY_INTERVAL = 2.minutes.to_i # can be different
BATCH_SIZE = 10_000 # can be different
@@ -494,8 +492,6 @@ You can reschedule pending migrations from the `background_migration_jobs` table
```ruby
# Post deployment migration
-include Gitlab::Database::MigrationHelpers
-
MIGRATION = 'YourBackgroundMigrationName'
DELAY_INTERVAL = 2.minutes
@@ -511,3 +507,16 @@ end
```
See [`db/post_migrate/20210604070207_retry_backfill_traversal_ids.rb`](https://gitlab.com/gitlab-org/gitlab/blob/master/db/post_migrate/20210604070207_retry_backfill_traversal_ids.rb) for a full example.
+
+### Viewing failure error logs
+
+After running a background migration, if any jobs have failed, you can view the logs in [Kibana](https://log.gprd.gitlab.net/goto/3afc1393447c401d7602c1874793e2f6).
+View the production Sidekiq log and filter for:
+
+- `json.class: BackgroundMigrationWorker`
+- `json.job_status: fail`
+- `json.args: <MyBackgroundMigrationClassName>`
+
+Looking at the `json.error_class`, `json.error_message` and `json.error_backtrace` values may be helpful in understanding why the jobs failed.
+
+Depending on when and how the failure occurred, you may find other helpful information by filtering with `json.class: <MyBackgroundMigrationClassName>`.
diff --git a/doc/development/cascading_settings.md b/doc/development/cascading_settings.md
index d1c5756fa2c..0fa0e220ba9 100644
--- a/doc/development/cascading_settings.md
+++ b/doc/development/cascading_settings.md
@@ -38,9 +38,11 @@ Settings are not cascading by default. To define a cascading setting, take the f
`application_settings`.
```ruby
- class AddDelayedProjectRemovalCascadingSetting < ActiveRecord::Migration[6.0]
+ class AddDelayedProjectRemovalCascadingSetting < Gitlab::Database::Migration[1.0]
include Gitlab::Database::MigrationHelpers::CascadingNamespaceSettings
+ enable_lock_retries!
+
def up
add_cascading_namespace_setting :delayed_project_removal, :boolean, default: false, null: false
end
diff --git a/doc/development/changelog.md b/doc/development/changelog.md
index c96fe2c18c1..be46d61eb4c 100644
--- a/doc/development/changelog.md
+++ b/doc/development/changelog.md
@@ -98,6 +98,7 @@ EE: true
database records created during Cycle Analytics model spec."
- _Any_ contribution from a community member, no matter how small, **may** have
a changelog entry regardless of these guidelines if the contributor wants one.
+- Any [GLEX experiment](experiment_guide/gitlab_experiment.md) changes **should not** have a changelog entry.
- [Removing](feature_flags/#changelog) a feature flag, when the new code is retained.
## Writing good changelog entries
diff --git a/doc/development/cicd/cicd_reference_documentation_guide.md b/doc/development/cicd/cicd_reference_documentation_guide.md
index 33bc416d8bc..aa3888cd866 100644
--- a/doc/development/cicd/cicd_reference_documentation_guide.md
+++ b/doc/development/cicd/cicd_reference_documentation_guide.md
@@ -1,6 +1,6 @@
---
stage: Verify
-group: Pipeline Execution
+group: Pipeline Authoring
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
---
diff --git a/doc/development/cicd/index.md b/doc/development/cicd/index.md
index 76c756b0e95..b4e32066ba8 100644
--- a/doc/development/cicd/index.md
+++ b/doc/development/cicd/index.md
@@ -16,7 +16,7 @@ to learn how to update the [reference page](../../ci/yaml/index.md).
## CI Architecture overview
-The following is a simplified diagram of the CI architecture. Some details are left out in order to focus on
+The following is a simplified diagram of the CI architecture. Some details are left out to focus on
the main components.
![CI software architecture](img/ci_architecture.png)
@@ -73,7 +73,7 @@ which picks the next job and assigns it to the runner. At this point the job tra
For more details read [Job scheduling](#job-scheduling)).
While a job is being executed, the runner sends logs back to the server as well any possible artifacts
-that need to be stored. Also, a job may depend on artifacts from previous jobs in order to run. In this
+that must be stored. Also, a job may depend on artifacts from previous jobs to run. In this
case the runner downloads them using a dedicated API endpoint.
Artifacts are stored in object storage, while metadata is kept in the database. An important example of artifacts
@@ -111,7 +111,7 @@ Once all jobs are completed for the current stage, the server "unlocks" all the
### Communication between runner and GitLab server
-Once the runner is [registered](https://docs.gitlab.com/runner/register/) using the registration token, the server knows what type of jobs it can execute. This depends on:
+After the runner is [registered](https://docs.gitlab.com/runner/register/) using the registration token, the server knows what type of jobs it can execute. This depends on:
- The type of runner it is registered as:
- a shared runner
@@ -119,7 +119,7 @@ Once the runner is [registered](https://docs.gitlab.com/runner/register/) using
- a project specific runner
- Any associated tags.
-The runner initiates the communication by requesting jobs to execute with `POST /api/v4/jobs/request`. Although this polling generally happens every few seconds we leverage caching via HTTP headers to reduce the server-side work load if the job queue doesn't change.
+The runner initiates the communication by requesting jobs to execute with `POST /api/v4/jobs/request`. Although polling happens every few seconds, we leverage caching through HTTP headers to reduce the server-side work load if the job queue doesn't change.
This API endpoint runs [`Ci::RegisterJobService`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/services/ci/register_job_service.rb), which:
diff --git a/doc/development/cicd/templates.md b/doc/development/cicd/templates.md
index 03823a4b712..3fc464e661f 100644
--- a/doc/development/cicd/templates.md
+++ b/doc/development/cicd/templates.md
@@ -178,10 +178,10 @@ This includes:
- Repository/project requirements.
- Expected behavior.
-- Any places that need to be edited by users before using the template.
+- Any places that must be edited by users before using the template.
- If the template should be used by copy pasting it into a configuration file, or
by using it with the `include` keyword in an existing pipeline.
-- If any variables need to be saved in the project's CI/CD settings.
+- If any variables must be saved in the project's CI/CD settings.
```yaml
# Use this template to publish an application that uses the ABC server.
@@ -289,9 +289,9 @@ If the `latest` template does not exist yet, you can copy [the stable template](
### How to include an older stable template
Users may want to use an older [stable template](#stable-version) that is not bundled
-in the current GitLab package. For example, the stable templates in GitLab v13.0 and
-GitLab v14.0 could be so different that a user wants to continue using the v13.0 template even
-after upgrading to GitLab 14.0.
+in the current GitLab package. For example, the stable templates in GitLab 13.0 and
+GitLab 14.0 could be so different that a user wants to continue using the GitLab 13.0
+template even after upgrading to GitLab 14.0.
You can add a note in the template or in documentation explaining how to use `include:remote`
to include older template versions. If other templates are included with `include: template`,
@@ -335,7 +335,7 @@ follow the progress.
## Testing
-Each CI/CD template must be tested in order to make sure that it's safe to be published.
+Each CI/CD template must be tested to make sure that it's safe to be published.
### Manual QA
@@ -380,7 +380,7 @@ is updated in a major version GitLab release.
A template could contain malicious code. For example, a template that contains the `export` shell command in a job
might accidentally expose secret project CI/CD variables in a job log.
-If you're unsure if it's secure or not, you need to ask security experts for cross-validation.
+If you're unsure if it's secure or not, you must ask security experts for cross-validation.
## Contribute CI/CD template merge requests
diff --git a/doc/development/code_intelligence/index.md b/doc/development/code_intelligence/index.md
index 790ba1539b7..e1e2105298c 100644
--- a/doc/development/code_intelligence/index.md
+++ b/doc/development/code_intelligence/index.md
@@ -37,7 +37,7 @@ sequenceDiagram
1. The CI/CD job generates a document in an LSIF format (usually `dump.lsif`) using [an
indexer](https://lsif.dev) for the language of a project. The format
- [describes](https://github.com/sourcegraph/sourcegraph/blob/master/doc/user/code_intelligence/writing_an_indexer.md)
+ [describes](https://github.com/sourcegraph/sourcegraph/blob/main/doc/code_intelligence/explanations/writing_an_indexer.md)
interactions between a method or function and its definition(s) or references. The
document is marked to be stored as an LSIF report artifact.
diff --git a/doc/development/code_review.md b/doc/development/code_review.md
index d66f246ac8c..12cc63ef56d 100644
--- a/doc/development/code_review.md
+++ b/doc/development/code_review.md
@@ -10,7 +10,7 @@ This guide contains advice and best practices for performing code review, and
having your code reviewed.
All merge requests for GitLab CE and EE, whether written by a GitLab team member
-or a volunteer contributor, must go through a code review process to ensure the
+or a wider community member, must go through a code review process to ensure the
code is effective, understandable, maintainable, and secure.
## Getting your merge request reviewed, approved, and merged
@@ -35,7 +35,7 @@ If you need assistance with security scans or comments, feel free to include the
Application Security Team (`@gitlab-com/gl-security/appsec`) in the review.
Depending on the areas your merge request touches, it must be **approved** by one
-or more [maintainers](https://about.gitlab.com/handbook/engineering/workflow/code-review/#maintainer):
+or more [maintainers](https://about.gitlab.com/handbook/engineering/workflow/code-review/#maintainer).
For approvals, we use the approval functionality found in the merge request
widget. For reviewers, we use the [reviewer functionality](../user/project/merge_requests/getting_started.md#reviewer) in the sidebar.
@@ -46,9 +46,11 @@ more than one approval, the last maintainer to review and approve merges it.
### Domain experts
-Domain experts are team members who have substantial experience with a specific technology, product feature or area of the codebase. Team members are encouraged to self-identify as domain experts and add it to their [team profile](https://gitlab.com/gitlab-com/www-gitlab-com/-/blob/master/data/team.yml).
+Domain experts are team members who have substantial experience with a specific technology,
+product feature, or area of the codebase. Team members are encouraged to self-identify as
+domain experts and add it to their [team profiles](https://gitlab.com/gitlab-com/www-gitlab-com/-/blob/master/data/team_members/person/README.md).
-When self-identifying as a domain expert, it is recommended to assign the MR changing the `team.yml` to be merged by an already established Domain Expert or a corresponding Engineering Manager.
+When self-identifying as a domain expert, it is recommended to assign the MR changing the `.yml` file to be merged by an already established Domain Expert or a corresponding Engineering Manager.
We make the following assumption with regards to automatically being considered a domain expert:
@@ -107,7 +109,7 @@ with [domain expertise](#domain-experts).
1. If your merge request includes adding a new JavaScript library (*1*)...
- If the library significantly increases the
[bundle size](https://gitlab.com/gitlab-org/frontend/playground/webpack-memory-metrics/-/blob/master/doc/report.md), it must
- be **approved by a [frontend foundations member](https://about.gitlab.com/direction/create/ecosystem/frontend-ux-foundations/)**.
+ be **approved by a [frontend foundations member](https://about.gitlab.com/direction/ecosystem/foundations/)**.
- If the license used by the new library hasn't been approved for use in
GitLab, the license must be **approved by a [legal department member](https://about.gitlab.com/handbook/legal/)**.
More information about license compatibility can be found in our
@@ -117,11 +119,12 @@ with [domain expertise](#domain-experts).
1. If your merge request includes documentation changes, it must be **approved
by a [Technical writer](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments)**,
based on assignments in the appropriate [DevOps stage group](https://about.gitlab.com/handbook/product/categories/#devops-stages).
+1. If your merge request includes changes to development guidelines, follow the [review process](index.md#development-guidelines-review) and get the approvals accordingly.
1. If your merge request includes end-to-end **and** non-end-to-end changes (*4*), it must be **approved
by a [Software Engineer in Test](https://about.gitlab.com/handbook/engineering/quality/#individual-contributors)**.
1. If your merge request only includes end-to-end changes (*4*) **or** if the MR author is a [Software Engineer in Test](https://about.gitlab.com/handbook/engineering/quality/#individual-contributors), it must be **approved by a [Quality maintainer](https://about.gitlab.com/handbook/engineering/projects/#gitlab_maintainers_qa)**
1. If your merge request includes a new or updated [application limit](https://about.gitlab.com/handbook/product/product-processes/#introducing-application-limits), it must be **approved by a [product manager](https://about.gitlab.com/company/team/)**.
-1. If your merge request includes Product Intelligence (telemetry or analytics) changes, it should be reviewed and approved by a [Product Intelligence engineer](https://gitlab.com/gitlab-org/growth/product_intelligence/engineers).
+1. If your merge request includes Product Intelligence (telemetry or analytics) changes, it should be reviewed and approved by a [Product Intelligence engineer](https://gitlab.com/gitlab-org/growth/product-intelligence/engineers).
1. If your merge request includes an addition of, or changes to a [Feature spec](testing_guide/testing_levels.md#frontend-feature-tests), it must be **approved by a [Quality maintainer](https://about.gitlab.com/handbook/engineering/projects/#gitlab_maintainers_qa) or [Quality reviewer](https://about.gitlab.com/handbook/engineering/projects/#gitlab_reviewers_qa)**.
1. If your merge request introduces a new service to GitLab (Puma, Sidekiq, Gitaly are examples), it must be **approved by a [product manager](https://about.gitlab.com/company/team/)**. See the [process for adding a service component to GitLab](adding_service_component.md) for details.
@@ -134,15 +137,60 @@ with [domain expertise](#domain-experts).
the content.
- (*4*): End-to-end changes include all files within the `qa` directory.
-#### Security requirements
+#### Acceptance checklist
-View the updated documentation regarding [internal application security reviews](https://about.gitlab.com/handbook/engineering/security/#internal-application-security-reviews) for **when** and **how** to request a security review.
+This checklist encourages the authors, reviewers, and maintainers of merge requests (MRs) to confirm changes were analyzed for high-impact risks to quality, performance, reliability, security, and maintainability.
+
+Using checklists improves quality in software engineering. This checklist is a straightforward tool to support and bolster the skills of contributors to the GitLab codebase.
+
+##### Quality
+
+See the [test engineering process](https://about.gitlab.com/handbook/engineering/quality/test-engineering/) for further quality guidelines.
+
+1. I have self-reviewed this MR per [code review guidelines](code_review.md).
+1. For the code that this change impacts, I believe that the automated tests ([Testing Guide](testing_guide/index.md)) validate functionality that is highly important to users (including consideration of [all test levels](testing_guide/testing_levels.md)).
+1. If the existing automated tests do not cover the above functionality, I have added the necessary additional tests or added an issue to describe the automation testing gap and linked it to this MR.
+1. I have considered the technical aspects of this change's impact on GitLab.com hosted customers and self-managed customers.
+1. I have considered the impact of this change on the frontend, backend, and database portions of the system where appropriate and applied the `~frontend`, `~backend`, and `~database` labels accordingly.
+1. I have tested this MR in [all supported browsers](../install/requirements.md#supported-web-browsers), or determined that this testing is not needed.
+1. I have confirmed that this change is [backwards compatible across updates](multi_version_compatibility.md), or I have decided that this does not apply.
+1. I have properly separated EE content from FOSS, or this MR is FOSS only.
+ - [Where should EE code go?](ee_features.md#separation-of-ee-code)
+1. If I am introducing a new expectation for existing data, I have confirmed that existing data meets this expectation or I have made this expectation optional rather than required.
+
+##### Performance, reliability, and availability
+
+1. I am confident that this MR does not harm performance, or I have asked a reviewer to help assess the performance impact. ([Merge request performance guidelines](merge_request_performance_guidelines.md))
+1. I have added [information for database reviewers in the MR description](database_review.md#required), or I have decided that it is unnecessary.
+ - [Does this MR have database-related changes?](database_review.md)
+1. I have considered the availability and reliability risks of this change.
+1. I have considered the scalability risk based on future predicted growth.
+1. I have considered the performance, reliability, and availability impacts of this change on large customers who may have significantly more data than the average customer.
+
+##### Documentation
+
+1. I have included changelog trailers, or I have decided that they are not needed.
+ - [Does this MR need a changelog?](changelog.md#what-warrants-a-changelog-entry)
+1. I have added/updated documentation or decided that documentation changes are unnecessary for this MR.
+ - [Is documentation required?](https://about.gitlab.com/handbook/engineering/ux/technical-writing/workflow/#when-documentation-is-required)
+
+##### Security
+
+1. I have confirmed that if this MR contains changes to processing or storing of credentials or tokens, authorization, and authentication methods, or other items described in [the security review guidelines](https://about.gitlab.com/handbook/engineering/security/#when-to-request-a-security-review), I have added the `~security` label and I have `@`-mentioned `@gitlab-com/gl-security/appsec`.
+1. I have reviewed the documentation regarding [internal application security reviews](https://about.gitlab.com/handbook/engineering/security/#internal-application-security-reviews) for **when** and **how** to request a security review and requested a security review if this is warranted for this change.
+
+##### Deployment
+
+1. I have considered using a feature flag for this change because the change may be high risk.
+1. If I am using a feature flag, I plan to test the change in staging before I test it in production, and I have considered rolling it out to a subset of production customers before rolling it out to all customers.
+ - [When to use a feature flag](https://about.gitlab.com/handbook/product-development-flow/feature-flag-lifecycle/#when-to-use-feature-flags)
+1. I have informed the Infrastructure department of a default setting or new setting change per [definition of done](contributing/merge_request_workflow.md#definition-of-done), or decided that this is unnecessary.
### The responsibility of the merge request author
The responsibility to find the best solution and implement it lies with the
merge request author. The author or [directly responsible individual](https://about.gitlab.com/handbook/people-group/directly-responsible-individuals/)
-will stay assigned to the merge request as the assignee throughout
+(DRI) stays assigned to the merge request as the assignee throughout
the code review lifecycle. If you are unable to set yourself as an assignee, ask a [reviewer](https://about.gitlab.com/handbook/engineering/workflow/code-review/#reviewer) to do this for you.
Before requesting a review from a maintainer to approve and merge, they
@@ -169,7 +217,7 @@ database specialists to get input on the data model or specific queries, or to
any other developer to get an in-depth review of the solution.
If an author is unsure if a merge request needs a [domain expert's](#domain-experts) opinion,
-that indicates it does. Without it it's unlikely they have the required level of confidence in their
+then that indicates it does. Without it, it's unlikely they have the required level of confidence in their
solution.
Before the review, the author is requested to submit comments on the merge
@@ -249,7 +297,7 @@ without duly verifying them.
Note that certain Merge Requests may target a stable branch. These are rare
events. These types of Merge Requests cannot be merged by the Maintainer.
-Instead these should be sent to the [Release Manager](https://about.gitlab.com/community/release-managers/).
+Instead, these should be sent to the [Release Manager](https://about.gitlab.com/community/release-managers/).
After merging, a maintainer should stay as the reviewer listed on the merge request.
@@ -305,8 +353,8 @@ first time.
codebase. Thorough descriptions help all reviewers understand your request
and test effectively.
- If you know your change depends on another being merged first, note it in the
- description and set an [merge request dependency](../user/project/merge_requests/merge_request_dependencies.md).
-- Be grateful for the reviewer's suggestions. (`Good call. I'll make that change.`)
+ description and set a [merge request dependency](../user/project/merge_requests/merge_request_dependencies.md).
+- Be grateful for the reviewer's suggestions. ("Good call. I'll make that change.")
- Don't take it personally. The review is of the code, not of you.
- Explain why the code exists. ("It's like that because of these reasons. Would
it be more clear if I rename this class/file/method/variable?")
@@ -425,20 +473,20 @@ WARNING:
- Start a new merge request pipeline with the `Run pipeline` button in the merge
request's "Pipelines" tab, and enable "Merge When Pipeline Succeeds" (MWPS).
Note that:
- - If **[main is broken](https://about.gitlab.com/handbook/engineering/workflow/#broken-master),
+ - If **[the default branch is broken](https://about.gitlab.com/handbook/engineering/workflow/#broken-master),
do not merge the merge request** except for
[very specific cases](https://about.gitlab.com/handbook/engineering/workflow/#criteria-for-merging-during-broken-master).
For other cases, follow these [handbook instructions](https://about.gitlab.com/handbook/engineering/workflow/#merging-during-broken-master).
- If the latest pipeline was created before the merge request was approved, start a new pipeline to ensure that full RSpec suite has been run. You may skip this step only if the merge request does not contain any backend change.
- If the **latest [Pipeline for Merged Results](../ci/pipelines/pipelines_for_merged_results.md)** finished less than 2 hours ago, you
- might merge without starting a new pipeline as the merge request is close
+ may merge without starting a new pipeline as the merge request is close
enough to `main`.
- When you set the MR to "Merge When Pipeline Succeeds", you should take over
subsequent revisions for anything that would be spotted after that.
- For merge requests that have had [Squash and
merge](../user/project/merge_requests/squash_and_merge.md#squash-and-merge) set,
- the squashed commit’s default commit message is taken from the merge request title.
- You're encouraged to [select a commit with a more informative commit message](../user/project/merge_requests/squash_and_merge.md#overview) before merging.
+ the squashed commit's default commit message is taken from the merge request title.
+ You're encouraged to [select a commit with a more informative commit message](../user/project/merge_requests/squash_and_merge.md) before merging.
Thanks to **Pipeline for Merged Results**, authors no longer have to rebase their
branch as frequently anymore (only when there are conflicts) because the Merge
@@ -526,7 +574,7 @@ author.
GitLab is used in a lot of places. Many users use
our [Omnibus packages](https://about.gitlab.com/install/), but some use
-the [Docker images](https://docs.gitlab.com/omnibus/docker/), some are
+the [Docker images](../install/docker.md), some are
[installed from source](../install/installation.md),
and there are other installation methods available. GitLab.com itself is a large
Enterprise Edition instance. This has some implications:
@@ -566,7 +614,7 @@ Enterprise Edition instance. This has some implications:
If you're adding a new setting in `gitlab.yml`:
1. Try to avoid that, and add to `ApplicationSetting` instead.
1. Ensure that it is also
- [added to Omnibus](https://docs.gitlab.com/omnibus/settings/gitlab.yml.html#adding-a-new-setting-to-gitlab-yml).
+ [added to Omnibus](https://docs.gitlab.com/omnibus/settings/gitlab.yml#adding-a-new-setting-to-gitlabyml).
1. **File system access** is not possible in a [cloud-native architecture](architecture.md#adapting-existing-and-introducing-new-components).
Ensure that we support object storage for any file storage we need to perform. For more
information, see the [uploads documentation](uploads.md).
@@ -613,7 +661,7 @@ A merge request may benefit from being considered a customer critical priority b
Properties of customer critical merge requests:
-- The [VP of Development](https://about.gitlab.com/job-families/engineering/development/management/vp) ([@clefelhocz1](https://gitlab.com/clefelhocz1)) is the DRI for deciding if a merge request qualifies as customer critical.
+- The [VP of Development](https://about.gitlab.com/job-families/engineering/development/management/vp/) ([@clefelhocz1](https://gitlab.com/clefelhocz1)) is the DRI for deciding if a merge request qualifies as customer critical.
- The DRI applies the `customer-critical-merge-request` label to the merge request.
- It is required that the reviewer(s) and maintainer(s) involved with a customer critical merge request are engaged as soon as this decision is made.
- It is required to prioritize work for those involved on a customer critical merge request so that they have the time available necessary to focus on it.
@@ -650,7 +698,3 @@ A good example of collaboration on an MR touching multiple parts of the codebase
### Credits
Largely based on the [`thoughtbot` code review guide](https://github.com/thoughtbot/guides/tree/master/code-review).
-
----
-
-[Return to Development documentation](index.md)
diff --git a/doc/development/contributing/community_roles.md b/doc/development/contributing/community_roles.md
index 3804aa7f8a8..37c3c24a7d1 100644
--- a/doc/development/contributing/community_roles.md
+++ b/doc/development/contributing/community_roles.md
@@ -16,7 +16,3 @@ GitLab community members and their privileges/responsibilities.
| Contributor | Can make contributions to all GitLab public projects | Have a GitLab.com account |
[List of current reviewers/maintainers](https://about.gitlab.com/handbook/engineering/projects/#gitlab-ce).
-
----
-
-[Return to Contributing documentation](index.md)
diff --git a/doc/development/contributing/design.md b/doc/development/contributing/design.md
index c1dd5ff4c0b..9e8375fcbdd 100644
--- a/doc/development/contributing/design.md
+++ b/doc/development/contributing/design.md
@@ -11,32 +11,28 @@ For guidance on UX implementation at GitLab, please refer to our [Design System]
The UX team uses labels to manage their workflow.
-The ~"UX" label on an issue is a signal to the UX team that it will need UX attention.
+The `~UX` label on an issue is a signal to the UX team that it will need UX attention.
To better understand the priority by which UX tackles issues, see the [UX section](https://about.gitlab.com/handbook/engineering/ux/) of the handbook.
-Once an issue has been worked on and is ready for development, a UXer removes the ~"UX" label and applies the ~"UX ready" label to that issue.
+Once an issue has been worked on and is ready for development, a UXer removes the `~UX` label and applies the `~"UX ready"` label to that issue.
-There is a special type label called ~"product discovery" intended for UX,
-PM, FE, and BE. It represents a discovery issue to discuss the problem and
+There is a special type label called `~"product discovery"` intended for UX (user experience),
+PM (product manager), FE (frontend), and BE (backend). It represents a discovery issue to discuss the problem and
potential solutions. The final output for this issue could be a doc of
requirements, a design artifact, or even a prototype. The solution will be
developed in a subsequent milestone.
-~"product discovery" issues are like any other issue and should contain a milestone label, ~"Deliverable" or ~"Stretch", when scheduled in the current milestone.
+`~"product discovery"` issues are like any other issue and should contain a milestone label, `~Deliverable` or `~Stretch`, when scheduled in the current milestone.
The initial issue should be about the problem we are solving. If a separate [product discovery issue](https://about.gitlab.com/handbook/engineering/ux/ux-department-workflow/#how-we-use-labels)
is needed for additional research and design work, it will be created by a PM or UX person.
-Assign the ~UX, ~"product discovery" and ~"Deliverable" labels, add a milestone and
+Assign the `~UX`, `~"product discovery"` and `~Deliverable` labels, add a milestone and
use a title that makes it clear that the scheduled issue is product discovery
(for example, `Product discovery for XYZ`).
In order to complete a product discovery issue in a release, you must complete the following:
-1. UXer removes the ~UX label, adds the ~"UX ready" label.
+1. UXer removes the `~UX` label, adds the `~"UX ready"` label.
1. Modify the issue description in the product discovery issue to contain the final design. If it makes sense, the original information indicating the need for the design can be moved to a lower "Original Information" section.
1. Copy the design to the description of the delivery issue for which the product discovery issue was created. Do not simply refer to the product discovery issue as a separate source of truth.
1. In some cases, a product discovery issue also identifies future enhancements that will not go into the issue that originated the product discovery issue. For these items, create new issues containing the designs to ensure they are not lost. Put the issues in the backlog if they are agreed upon as good ideas. Otherwise leave them for triage.
-
----
-
-[Return to Contributing documentation](index.md)
diff --git a/doc/development/contributing/issue_workflow.md b/doc/development/contributing/issue_workflow.md
index 1dfe560d68d..29f6eb57160 100644
--- a/doc/development/contributing/issue_workflow.md
+++ b/doc/development/contributing/issue_workflow.md
@@ -15,9 +15,7 @@ feature proposal. Show your support with an award emoji and/or join the
discussion.
Please submit bugs using the ['Bug' issue template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/issue_templates/Bug.md) provided on the issue tracker.
-The text in the parenthesis is there to help you with what to include. Omit it
-when submitting the actual issue. You can copy-paste it and then edit as you
-see fit.
+The text in the comments (`<!-- ... -->`) is there to help you with what to include.
## Issue triaging
@@ -30,12 +28,12 @@ The most important thing is making sure valid issues receive feedback from the
development team. Therefore the priority is mentioning developers that can help
on those issues. Please select someone with relevant experience from the
[GitLab team](https://about.gitlab.com/company/team/).
-If there is nobody mentioned with that expertise look in the commit history for
+If there is nobody mentioned with that expertise, look in the commit history for
the affected files to find someone.
We also use [GitLab Triage](https://gitlab.com/gitlab-org/gitlab-triage) to automate
some triaging policies. This is currently set up as a scheduled pipeline
-(`https://gitlab.com/gitlab-org/quality/triage-ops/pipeline_schedules/10512/editpipeline_schedules/10512/edit`,
+(`https://gitlab.com/gitlab-org/quality/triage-ops/-/pipeline_schedules/10512/edit`,
must have at least the Developer role in the project) running on [quality/triage-ops](https://gitlab.com/gitlab-org/quality/triage-ops)
project.
@@ -132,9 +130,9 @@ their color is `#A8D695`.
<https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/stages.yml>,
with `_` replaced with a space.
-For instance, the "Continuous Integration" group is represented by the
-~"group::continuous integration" label in the `gitlab-org` group since its key
-under `stages.manage.groups` is `continuous_integration`.
+For instance, the "Pipeline Execution" group is represented by the
+~"group::pipeline execution" label in the `gitlab-org` group since its key
+under `stages.manage.groups` is `pipeline_execution`.
The current group labels can be found by [searching the labels list for `group::`](https://gitlab.com/groups/gitlab-org/-/labels?search=group::).
@@ -146,17 +144,6 @@ You can find the groups listed in the [Product Stages, Groups, and Categories](h
We use the term group to map down product requirements from our product stages.
As a team needs some way to collect the work their members are planning to be assigned to, we use the `~group::` labels to do so.
-Normally there is a 1:1 relationship between Stage labels and Group labels. In
-the spirit of "Everyone can contribute", any issue can be picked up by any group,
-depending on current priorities. When picking up an issue belonging to a different
-group, it should be relabeled. For example, if an issue labeled `~"devops::create"`
-and `~"group::knowledge"` is picked up by someone in the Access group of the Plan stage,
-the issue should be relabeled as `~"group::access"` while keeping the original
-`~"devops::create"` unchanged.
-
-We also use stage and group labels to help measure our [merge request rates](https://about.gitlab.com/handbook/engineering/metrics/#merge-request-rate).
-Please read [Stage and Group labels](https://about.gitlab.com/handbook/engineering/metrics/#stage-and-group-labels) for more information on how the labels are used in this context.
-
### Category labels
From the handbook's
@@ -384,7 +371,7 @@ below will make it easy to manage this, without unnecessary overhead.
1. If you don't agree with a set weight, discuss with other developers until
consensus is reached about the weight
1. Issue weights are an abstract measurement of complexity of the issue. Do not
- relate issue weight directly to time. This is called [anchoring](https://en.wikipedia.org/wiki/Anchoring)
+ relate issue weight directly to time. This is called [anchoring](https://en.wikipedia.org/wiki/Anchoring_(cognitive_bias))
and something you want to avoid.
1. Something that has a weight of 1 (or no weight) is really small and simple.
Something that is 9 is rewriting a large fundamental part of GitLab,
@@ -476,7 +463,3 @@ should be of the same quality as those created
[in the usual manner](#technical-and-ux-debt) - in particular, the issue title
**must not** begin with `Follow-up`! The creating maintainer should also expect
to be involved in some capacity when work begins on the follow-up issue.
-
----
-
-[Return to Contributing documentation](index.md)
diff --git a/doc/development/contributing/merge_request_workflow.md b/doc/development/contributing/merge_request_workflow.md
index 534150e4d37..25561764bd6 100644
--- a/doc/development/contributing/merge_request_workflow.md
+++ b/doc/development/contributing/merge_request_workflow.md
@@ -223,11 +223,19 @@ the contribution acceptance criteria below:
## Definition of done
-If you contribute to GitLab please know that changes involve more than just
+If you contribute to GitLab, please know that changes involve more than just
code. We use the following [definition of done](https://www.agilealliance.org/glossary/definition-of-done).
-Your contribution is not *done* until you have made sure it meets all of these
+To reach the definition of done, the merge request must create no regressions and meet all these criteria:
+
+- Verified as working in production on GitLab.com.
+- Verified as working for self-managed instances.
+
+If a regression occurs, we prefer you revert the change. We break the definition of done into two phases: [MR Merge](#mr-merge) and [Production use](#production-use).
+Your contribution is *incomplete* until you have made sure it meets all of these
requirements.
+### MR Merge
+
1. Clear description explaining the relevancy of the contribution.
1. Working and clean code that is commented where needed.
1. [Unit, integration, and system tests](../testing_guide/index.md) that all pass
@@ -238,17 +246,30 @@ requirements.
1. [Secure coding guidelines](https://gitlab.com/gitlab-com/gl-security/security-guidelines) have been followed.
1. [Documented](../documentation/index.md) in the `/doc` directory.
1. [Changelog entry added](../changelog.md), if necessary.
-1. Reviewed by relevant reviewers and all concerns are addressed for Availability, Regressions, Security. Documentation reviews should take place as soon as possible, but they should not block a merge request.
-1. Merged by a project maintainer.
+1. Reviewed by relevant reviewers, and all concerns are addressed for Availability, Regressions, and Security. Documentation reviews should take place as soon as possible, but they should not block a merge request.
+1. The [MR acceptance checklist](../code_review.md#acceptance-checklist) has been checked as confirmed in the MR.
1. Create an issue in the [infrastructure issue tracker](https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues) to inform the Infrastructure department when your contribution is changing default settings or introduces a new setting, if relevant.
-1. Confirmed to be working in the [Canary stage](https://about.gitlab.com/handbook/engineering/#canary-testing) with no new [Sentry](https://about.gitlab.com/handbook/engineering/#sentry) errors or on GitLab.com once the contribution is deployed.
-1. Added to the [release post](https://about.gitlab.com/handbook/marketing/blog/release-posts/),
- if relevant.
-1. Added to [the website](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/features.yml), if relevant.
1. [Black-box tests/end-to-end tests](../testing_guide/testing_levels.md#black-box-tests-at-the-system-level-aka-end-to-end-tests)
added if required. Please contact [the quality team](https://about.gitlab.com/handbook/engineering/quality/#teams)
with any questions.
+1. The change is tested in a review app where possible and if appropriate.
1. The new feature does not degrade the user experience of the product.
+1. The change is evaluated to [limit the impact of far-reaching work](https://about.gitlab.com/handbook/engineering/development/#reducing-the-impact-of-far-reaching-work).
+1. An agreed-upon rollout plan.
+1. Merged by a project maintainer.
+
+### Production use
+
+1. Confirmed to be working in staging before implementing the change in production, where possible.
+1. Confirmed to be working in the production with no new [Sentry](https://about.gitlab.com/handbook/engineering/#sentry) errors after the contribution is deployed.
+1. Confirmed that the rollout plan has been completed.
+1. If there is a performance risk in the change, I have analyzed the performance of the system before and after the change.
+1. *If the merge request uses feature flags, per-project or per-group enablement, and a staged rollout:*
+ - Confirmed to be working on GitLab projects.
+ - Confirmed to be working at each stage for all projects added.
+1. Added to the [release post](https://about.gitlab.com/handbook/marketing/blog/release-posts/),
+ if relevant.
+1. Added to [the website](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/features.yml), if relevant.
Contributions do not require approval from the [Product team](https://about.gitlab.com/handbook/product/product-processes/#gitlab-pms-arent-the-arbiters-of-community-contributions).
diff --git a/doc/development/contributing/style_guides.md b/doc/development/contributing/style_guides.md
index 1b339b7f252..754e6c7aec6 100644
--- a/doc/development/contributing/style_guides.md
+++ b/doc/development/contributing/style_guides.md
@@ -177,11 +177,10 @@ This ensures that our list isn't mistakenly removed by another auto generation o
the `.rubocop_todo.yml`. This also allows us greater visibility into the exceptions
which are currently being resolved.
-One way to generate the initial list is to run the `todo` auto generation,
-with `exclude limit` set to a high number.
+One way to generate the initial list is to run the Rake task `rubocop:todo:generate`:
```shell
-bundle exec rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit=100000
+bundle exec rake rubocop:todo:generate
```
You can then move the list from the freshly generated `.rubocop_todo.yml` for the Cop being actively
@@ -242,7 +241,3 @@ See the dedicated [Python Development Guidelines](../python_guide/index.md).
## Misc
Code should be written in [US English](https://en.wikipedia.org/wiki/American_English).
-
----
-
-[Return to Contributing documentation](index.md)
diff --git a/doc/development/database/add_foreign_key_to_existing_column.md b/doc/development/database/add_foreign_key_to_existing_column.md
index f83dc35b4a6..d74f826cc14 100644
--- a/doc/development/database/add_foreign_key_to_existing_column.md
+++ b/doc/development/database/add_foreign_key_to_existing_column.md
@@ -4,11 +4,17 @@ group: Database
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
---
-# Adding foreign key constraint to an existing column
+# Add a foreign key constraint to an existing column
-Foreign keys help ensure consistency between related database tables. The current database review process **always** encourages you to add [foreign keys](../foreign_keys.md) when creating tables that reference records from other tables.
+Foreign keys ensure consistency between related database tables. The current database review process **always** encourages you to add [foreign keys](../foreign_keys.md) when creating tables that reference records from other tables.
-Starting with Rails version 4, Rails includes migration helpers to add foreign key constraints to database tables. Before Rails 4, the only way for ensuring some level of consistency was the [`dependent`](https://guides.rubyonrails.org/association_basics.html#options-for-belongs-to-dependent) option within the association definition. Ensuring data consistency on the application level could fail in some unfortunate cases, so we might end up with inconsistent data in the table. This is mostly affecting older tables, where we simply didn't have the framework support to ensure consistency on the database level. These data inconsistencies can easily cause unexpected application behavior or bugs.
+Starting with Rails version 4, Rails includes migration helpers to add foreign key constraints
+to database tables. Before Rails 4, the only way for ensuring some level of consistency was the
+[`dependent`](https://guides.rubyonrails.org/association_basics.html#options-for-belongs-to-dependent)
+option in the association definition. Ensuring data consistency on the application level could fail
+in some unfortunate cases, so we might end up with inconsistent data in the table. This mostly affects
+older tables, where we didn't have the framework support to ensure consistency on the database level.
+These data inconsistencies can cause unexpected application behavior or bugs.
Adding a foreign key to an existing database column requires database structure changes and potential data changes. In case the table is in use, we should always assume that there is inconsistent data.
@@ -45,7 +51,7 @@ class Email < ActiveRecord::Base
end
```
-Problem: when the user is removed, the email records related to the removed user will stay in the `emails` table:
+Problem: when the user is removed, the email records related to the removed user stays in the `emails` table:
```ruby
user = User.find(1)
@@ -66,9 +72,7 @@ In the example above, you'd be still able to update records in the `emails` tabl
Migration file for adding `NOT VALID` foreign key:
```ruby
-class AddNotValidForeignKeyToEmailsUser < ActiveRecord::Migration[5.2]
- include Gitlab::Database::MigrationHelpers
-
+class AddNotValidForeignKeyToEmailsUser < Gitlab::Database::Migration[1.0]
def up
# safe to use: it requires short lock on the table since we don't validate the foreign key
add_foreign_key :emails, :users, on_delete: :cascade, validate: false
@@ -85,16 +89,16 @@ Avoid using the `add_foreign_key` constraint more than once per migration file,
#### Data migration to fix existing records
-The approach here depends on the data volume and the cleanup strategy. If we can easily find "invalid" records by doing a simple database query and the record count is not that high, then the data migration can be executed within a Rails migration.
+The approach here depends on the data volume and the cleanup strategy. If we can find "invalid"
+records by doing a database query and the record count is not high, then the data migration can
+be executed in a Rails migration.
In case the data volume is higher (>1000 records), it's better to create a background migration. If unsure, please contact the database team for advice.
-Example for cleaning up records in the `emails` table within a database migration:
+Example for cleaning up records in the `emails` table in a database migration:
```ruby
-class RemoveRecordsWithoutUserFromEmailsTable < ActiveRecord::Migration[5.2]
- include Gitlab::Database::MigrationHelpers
-
+class RemoveRecordsWithoutUserFromEmailsTable < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
class Email < ActiveRecord::Base
@@ -116,7 +120,7 @@ end
### Validate the foreign key
-Validating the foreign key will scan the whole table and make sure that each relation is correct.
+Validating the foreign key scans the whole table and makes sure that each relation is correct.
NOTE:
When using [background migrations](../background_migrations.md), foreign key validation should happen in the next GitLab release.
@@ -126,9 +130,7 @@ Migration file for validating the foreign key:
```ruby
# frozen_string_literal: true
-class ValidateForeignKeyOnEmailUsers < ActiveRecord::Migration[5.2]
- include Gitlab::Database::MigrationHelpers
-
+class ValidateForeignKeyOnEmailUsers < Gitlab::Database::Migration[1.0]
def up
validate_foreign_key :emails, :user_id
end
diff --git a/doc/development/database/constraint_naming_convention.md b/doc/development/database/constraint_naming_convention.md
index 3faef8aee09..a22ddc1551c 100644
--- a/doc/development/database/constraint_naming_convention.md
+++ b/doc/development/database/constraint_naming_convention.md
@@ -6,7 +6,10 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Constraints naming conventions
-The most common option is to let Rails pick the name for database constraints and indexes or let PostgreSQL use the defaults (when applicable). However, when needing to define custom names in Rails or working in Go applications where no ORM is used, it is important to follow strict naming conventions to improve consistency and discoverability.
+The most common option is to let Rails pick the name for database constraints and indexes or let
+PostgreSQL use the defaults (when applicable). However, when defining custom names in Rails, or
+working in Go applications where no ORM is used, it is important to follow strict naming conventions
+to improve consistency and discoverability.
The table below describes the naming conventions for custom PostgreSQL constraints.
The intent is not to retroactively change names in existing databases but rather ensure consistency of future changes.
diff --git a/doc/development/database/database_reviewer_guidelines.md b/doc/development/database/database_reviewer_guidelines.md
index 7a9c08d9d49..59653c6dde3 100644
--- a/doc/development/database/database_reviewer_guidelines.md
+++ b/doc/development/database/database_reviewer_guidelines.md
@@ -19,7 +19,7 @@ Database reviewers are domain experts who have substantial experience with datab
A database review is required whenever an application update [touches the database](../database_review.md#general-process).
The database reviewer is tasked with reviewing the database specific updates and
-making sure that any queries or modifications will perform without issues
+making sure that any queries or modifications perform without issues
at the scale of GitLab.com.
For more information on the database review process, check the [database review guidelines](../database_review.md).
@@ -72,7 +72,7 @@ topics and use cases. The most frequently required during database reviewing are
- [Avoiding downtime in migrations](../avoiding_downtime_in_migrations.md).
- [SQL guidelines](../sql.md) for working with SQL queries.
-## How to apply for becoming a database maintainer
+## How to apply to become a database maintainer
Once a database reviewer feels confident on switching to a database maintainer,
they can update their [team profile](https://gitlab.com/gitlab-com/www-gitlab-com/-/blob/master/data/team.yml)
diff --git a/doc/development/database/efficient_in_operator_queries.md b/doc/development/database/efficient_in_operator_queries.md
new file mode 100644
index 00000000000..bc72bce30bf
--- /dev/null
+++ b/doc/development/database/efficient_in_operator_queries.md
@@ -0,0 +1,949 @@
+---
+stage: Enablement
+group: Database
+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
+---
+
+# Efficient `IN` operator queries
+
+This document describes a technique for building efficient ordered database queries with the `IN`
+SQL operator and the usage of a GitLab utility module to help apply the technique.
+
+NOTE:
+The described technique makes heavy use of
+[keyset pagination](pagination_guidelines.md#keyset-pagination).
+It's advised to get familiar with the topic first.
+
+## Motivation
+
+In GitLab, many domain objects like `Issue` live under nested hierarchies of projects and groups.
+To fetch nested database records for domain objects at the group-level,
+we often perform queries with the `IN` SQL operator.
+We are usually interested in ordering the records by some attributes
+and limiting the number of records using `ORDER BY` and `LIMIT` clauses for performance.
+Pagination may be used to fetch subsequent records.
+
+Example tasks requiring querying nested domain objects from the group level:
+
+- Show first 20 issues by creation date or due date from the group `gitlab-org`.
+- Show first 20 merge_requests by merged at date from the group `gitlab-com`.
+
+Unfortunately, ordered group-level queries typically perform badly
+as their executions require heavy I/O, memory, and computations.
+Let's do an in-depth examination of executing one such query.
+
+### Performance problems with `IN` queries
+
+Consider the task of fetching the twenty oldest created issues
+from the group `gitlab-org` with the following query:
+
+```sql
+SELECT "issues".*
+FROM "issues"
+WHERE "issues"."project_id" IN
+ (SELECT "projects"."id"
+ FROM "projects"
+ WHERE "projects"."namespace_id" IN
+ (SELECT traversal_ids[array_length(traversal_ids, 1)] AS id
+ FROM "namespaces"
+ WHERE (traversal_ids @> ('{9970}'))))
+ORDER BY "issues"."created_at" ASC,
+ "issues"."id" ASC
+LIMIT 20
+```
+
+NOTE:
+For pagination, ordering by the `created_at` column is not enough,
+we must add the `id` column as a
+[tie-breaker](pagination_performance_guidelines.md#tie-breaker-column).
+
+The execution of the query can be largely broken down into three steps:
+
+1. The database accesses both `namespaces` and `projects` tables
+ to find all projects from all groups in the group hierarchy.
+1. The database retrieves `issues` records for each project causing heavy disk I/O.
+ Ideally, an appropriate index configuration should optimize this process.
+1. The database sorts the `issues` rows in memory by `created_at` and returns `LIMIT 20` rows to
+ the end-user. For large groups, this final step requires both large memory and CPU resources.
+
+<details>
+<summary>Expand this sentence to see the execution plan for this DB query.</summary>
+<pre><code>
+ Limit (cost=90170.07..90170.12 rows=20 width=1329) (actual time=967.597..967.607 rows=20 loops=1)
+ Buffers: shared hit=239127 read=3060
+ I/O Timings: read=336.879
+ -> Sort (cost=90170.07..90224.02 rows=21578 width=1329) (actual time=967.596..967.603 rows=20 loops=1)
+ Sort Key: issues.created_at, issues.id
+ Sort Method: top-N heapsort Memory: 74kB
+ Buffers: shared hit=239127 read=3060
+ I/O Timings: read=336.879
+ -> Nested Loop (cost=1305.66..89595.89 rows=21578 width=1329) (actual time=4.709..797.659 rows=241534 loops=1)
+ Buffers: shared hit=239121 read=3060
+ I/O Timings: read=336.879
+ -> HashAggregate (cost=1305.10..1360.22 rows=5512 width=4) (actual time=4.657..5.370 rows=1528 loops=1)
+ Group Key: projects.id
+ Buffers: shared hit=2597
+ -> Nested Loop (cost=576.76..1291.32 rows=5512 width=4) (actual time=2.427..4.244 rows=1528 loops=1)
+ Buffers: shared hit=2597
+ -> HashAggregate (cost=576.32..579.06 rows=274 width=25) (actual time=2.406..2.447 rows=265 loops=1)
+ Group Key: namespaces.traversal_ids[array_length(namespaces.traversal_ids, 1)]
+ Buffers: shared hit=334
+ -> Bitmap Heap Scan on namespaces (cost=141.62..575.63 rows=274 width=25) (actual time=1.933..2.330 rows=265 loops=1)
+ Recheck Cond: (traversal_ids @> '{9970}'::integer[])
+ Heap Blocks: exact=243
+ Buffers: shared hit=334
+ -> Bitmap Index Scan on index_namespaces_on_traversal_ids (cost=0.00..141.55 rows=274 width=0) (actual time=1.897..1.898 rows=265 loops=1)
+ Index Cond: (traversal_ids @> '{9970}'::integer[])
+ Buffers: shared hit=91
+ -> Index Only Scan using index_projects_on_namespace_id_and_id on projects (cost=0.44..2.40 rows=20 width=8) (actual time=0.004..0.006 rows=6 loops=265)
+ Index Cond: (namespace_id = (namespaces.traversal_ids)[array_length(namespaces.traversal_ids, 1)])
+ Heap Fetches: 51
+ Buffers: shared hit=2263
+ -> Index Scan using index_issues_on_project_id_and_iid on issues (cost=0.57..10.57 rows=544 width=1329) (actual time=0.114..0.484 rows=158 loops=1528)
+ Index Cond: (project_id = projects.id)
+ Buffers: shared hit=236524 read=3060
+ I/O Timings: read=336.879
+ Planning Time: 7.750 ms
+ Execution Time: 967.973 ms
+(36 rows)
+</code></pre>
+</details>
+
+The performance of the query depends on the number of rows in the database.
+On average, we can say the following:
+
+- Number of groups in the group-hierarchy: less than 1 000
+- Number of projects: less than 5 000
+- Number of issues: less than 100 000
+
+From the list, it's apparent that the number of `issues` records has
+the largest impact on the performance.
+As per normal usage, we can say that the number of issue records grows
+at a faster rate than the `namespaces` and the `projects` records.
+
+This problem affects most of our group-level features where records are listed
+in a specific order, such as group-level issues, merge requests pages, and APIs.
+For very large groups the database queries can easily time out, causing HTTP 500 errors.
+
+## Optimizing ordered `IN` queries
+
+In the talk
+["How to teach an elephant to dance rock'n'roll"](https://www.youtube.com/watch?v=Ha38lcjVyhQ),
+Maxim Boguk demonstrated a technique to optimize a special class of ordered `IN` queries,
+such as our ordered group-level queries.
+
+A typical ordered `IN` query may look like this:
+
+```sql
+SELECT t.* FROM t
+WHERE t.fkey IN (value_set)
+ORDER BY t.pkey
+LIMIT N;
+```
+
+Here's the key insight used in the technique: we need at most `|value_set| + N` record lookups,
+rather than retrieving all records satisfying the condition `t.fkey IN value_set` (`|value_set|`
+is the number of values in `value_set`).
+
+We adopted and generalized the technique for use in GitLab by implementing utilities in the
+`Gitlab::Pagination::Keyset::InOperatorOptimization` class to facilitate building efficient `IN`
+queries.
+
+### Requirements
+
+The technique is not a drop-in replacement for the existing group-level queries using `IN` operator.
+The technique can only optimize `IN` queries that satisfy the following requirements:
+
+- `LIMIT` is present, which usually means that the query is paginated
+ (offset or keyset pagination).
+- The column used with the `IN` query and the columns in the `ORDER BY`
+ clause are covered with a database index. The columns in the index must be
+ in the following order: `column_for_the_in_query`, `order by column 1`, and
+ `order by column 2`.
+- The columns in the `ORDER BY` clause are distinct
+ (the combination of the columns uniquely identifies one particular column in the table).
+
+WARNING:
+This technique will not improve the performance of the `COUNT(*)` queries.
+
+## The `InOperatorOptimization` module
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67352) in GitLab 14.3.
+
+The `Gitlab::Pagination::Keyset::InOperatorOptimization` module implements utilities for applying a generalized version of
+the efficient `IN` query technique described in the previous section.
+
+To build optimized, ordered `IN` queries that meet [the requirements](#requirements),
+use the utility class `QueryBuilder` from the module.
+
+NOTE:
+The generic keyset pagination module introduced in the merge request
+[51481](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51481)
+plays a fundamental role in the generalized implementation of the technique
+in `Gitlab::Pagination::Keyset::InOperatorOptimization`.
+
+### Basic usage of `QueryBuilder`
+
+To illustrate a basic usage, we will build a query that
+fetches 20 issues with the oldest `created_at` from the group `gitlab-org`.
+
+The following ActiveRecord query would produce a query similar to
+[the unoptimized query](#performance-problems-with-in-queries) that we examined earlier:
+
+```ruby
+scope = Issue
+ .where(project_id: Group.find(9970).all_projects.select(:id)) # `gitlab-org` group and its subgroups
+ .order(:created_at, :id)
+ .limit(20)
+```
+
+Instead, use the query builder `InOperatorOptimization::QueryBuilder` to produce an optimized
+version:
+
+```ruby
+scope = Issue.order(:created_at, :id)
+array_scope = Group.find(9970).all_projects.select(:id)
+array_mapping_scope = -> (id_expression) { Issue.where(Issue.arel_table[:project_id].eq(id_expression)) }
+finder_query = -> (created_at_expression, id_expression) { Issue.where(Issue.arel_table[:id].eq(id_expression)) }
+
+Gitlab::Pagination::Keyset::InOperatorOptimization::QueryBuilder.new(
+ scope: scope,
+ array_scope: array_scope,
+ array_mapping_scope: array_mapping_scope,
+ finder_query: finder_query
+).execute.limit(20)
+```
+
+- `scope` represents the original `ActiveRecord::Relation` object without the `IN` query. The
+ relation should define an order which must be supported by the
+ [keyset pagination library](keyset_pagination.md#usage).
+- `array_scope` contains the `ActiveRecord::Relation` object, which represents the original
+ `IN (subquery)`. The select values must contain the columns by which the subquery is "connected"
+ to the main query: the `id` of the project record.
+- `array_mapping_scope` defines a lambda returning an `ActiveRecord::Relation` object. The lambda
+ matches (`=`) single select values from the `array_scope`. The lambda yields as many
+ arguments as the select values defined in the `array_scope`. The arguments are Arel SQL expressions.
+- `finder_query` loads the actual record row from the database. It must also be a lambda, where
+ the order by column expressions is available for locating the record. In this example, the
+ yielded values are `created_at` and `id` SQL expressions. Finding a record is very fast via the
+ primary key, so we don't use the `created_at` value.
+
+The following database index on the `issues` table must be present
+to make the query execute efficiently:
+
+```sql
+"idx_issues_on_project_id_and_created_at_and_id" btree (project_id, created_at, id)
+```
+
+<details>
+<summary>Expand this sentence to see the SQL query.</summary>
+<pre><code>
+SELECT "issues".*
+FROM
+ (WITH RECURSIVE "array_cte" AS MATERIALIZED
+ (SELECT "projects"."id"
+ FROM "projects"
+ WHERE "projects"."namespace_id" IN
+ (SELECT traversal_ids[array_length(traversal_ids, 1)] AS id
+ FROM "namespaces"
+ WHERE (traversal_ids @> ('{9970}')))),
+ "recursive_keyset_cte" AS ( -- initializer row start
+ (SELECT NULL::issues AS records,
+ array_cte_id_array,
+ issues_created_at_array,
+ issues_id_array,
+ 0::bigint AS COUNT
+ FROM
+ (SELECT ARRAY_AGG("array_cte"."id") AS array_cte_id_array,
+ ARRAY_AGG("issues"."created_at") AS issues_created_at_array,
+ ARRAY_AGG("issues"."id") AS issues_id_array
+ FROM
+ (SELECT "array_cte"."id"
+ FROM array_cte) array_cte
+ LEFT JOIN LATERAL
+ (SELECT "issues"."created_at",
+ "issues"."id"
+ FROM "issues"
+ WHERE "issues"."project_id" = "array_cte"."id"
+ ORDER BY "issues"."created_at" ASC, "issues"."id" ASC
+ LIMIT 1) issues ON TRUE
+ WHERE "issues"."created_at" IS NOT NULL
+ AND "issues"."id" IS NOT NULL) array_scope_lateral_query
+ LIMIT 1)
+ -- initializer row finished
+ UNION ALL
+ (SELECT
+ -- result row start
+ (SELECT issues -- record finder query as the first column
+ FROM "issues"
+ WHERE "issues"."id" = recursive_keyset_cte.issues_id_array[position]
+ LIMIT 1),
+ array_cte_id_array,
+ recursive_keyset_cte.issues_created_at_array[:position_query.position-1]||next_cursor_values.created_at||recursive_keyset_cte.issues_created_at_array[position_query.position+1:],
+ recursive_keyset_cte.issues_id_array[:position_query.position-1]||next_cursor_values.id||recursive_keyset_cte.issues_id_array[position_query.position+1:],
+ recursive_keyset_cte.count + 1
+ -- result row finished
+ FROM recursive_keyset_cte,
+ LATERAL
+ -- finding the cursor values of the next record start
+ (SELECT created_at,
+ id,
+ position
+ FROM UNNEST(issues_created_at_array, issues_id_array) WITH
+ ORDINALITY AS u(created_at, id, position)
+ WHERE created_at IS NOT NULL
+ AND id IS NOT NULL
+ ORDER BY "created_at" ASC, "id" ASC
+ LIMIT 1) AS position_query,
+ -- finding the cursor values of the next record end
+ -- finding the next cursor values (next_cursor_values_query) start
+ LATERAL
+ (SELECT "record"."created_at",
+ "record"."id"
+ FROM (
+ VALUES (NULL,
+ NULL)) AS nulls
+ LEFT JOIN
+ (SELECT "issues"."created_at",
+ "issues"."id"
+ FROM (
+ (SELECT "issues"."created_at",
+ "issues"."id"
+ FROM "issues"
+ WHERE "issues"."project_id" = recursive_keyset_cte.array_cte_id_array[position]
+ AND recursive_keyset_cte.issues_created_at_array[position] IS NULL
+ AND "issues"."created_at" IS NULL
+ AND "issues"."id" > recursive_keyset_cte.issues_id_array[position]
+ ORDER BY "issues"."created_at" ASC, "issues"."id" ASC)
+ UNION ALL
+ (SELECT "issues"."created_at",
+ "issues"."id"
+ FROM "issues"
+ WHERE "issues"."project_id" = recursive_keyset_cte.array_cte_id_array[position]
+ AND recursive_keyset_cte.issues_created_at_array[position] IS NOT NULL
+ AND "issues"."created_at" IS NULL
+ ORDER BY "issues"."created_at" ASC, "issues"."id" ASC)
+ UNION ALL
+ (SELECT "issues"."created_at",
+ "issues"."id"
+ FROM "issues"
+ WHERE "issues"."project_id" = recursive_keyset_cte.array_cte_id_array[position]
+ AND recursive_keyset_cte.issues_created_at_array[position] IS NOT NULL
+ AND "issues"."created_at" > recursive_keyset_cte.issues_created_at_array[position]
+ ORDER BY "issues"."created_at" ASC, "issues"."id" ASC)
+ UNION ALL
+ (SELECT "issues"."created_at",
+ "issues"."id"
+ FROM "issues"
+ WHERE "issues"."project_id" = recursive_keyset_cte.array_cte_id_array[position]
+ AND recursive_keyset_cte.issues_created_at_array[position] IS NOT NULL
+ AND "issues"."created_at" = recursive_keyset_cte.issues_created_at_array[position]
+ AND "issues"."id" > recursive_keyset_cte.issues_id_array[position]
+ ORDER BY "issues"."created_at" ASC, "issues"."id" ASC)) issues
+ ORDER BY "issues"."created_at" ASC, "issues"."id" ASC
+ LIMIT 1) record ON TRUE
+ LIMIT 1) AS next_cursor_values))
+ -- finding the next cursor values (next_cursor_values_query) END
+SELECT (records).*
+ FROM "recursive_keyset_cte" AS "issues"
+ WHERE (COUNT <> 0)) issues -- filtering out the initializer row
+LIMIT 20
+</code></pre>
+</details>
+
+### Using the `IN` query optimization
+
+#### Adding more filters
+
+In this example, let's add an extra filter by `milestone_id`.
+
+Be careful when adding extra filters to the query. If the column is not covered by the same index,
+then the query might perform worse than the non-optimized query. The `milestone_id` column in the
+`issues` table is currently covered by a different index:
+
+```sql
+"index_issues_on_milestone_id" btree (milestone_id)
+```
+
+Adding the `miletone_id = X` filter to the `scope` argument or to the optimized scope causes bad performance.
+
+Example (bad):
+
+```ruby
+Gitlab::Pagination::Keyset::InOperatorOptimization::QueryBuilder.new(
+ scope: scope,
+ array_scope: array_scope,
+ array_mapping_scope: array_mapping_scope,
+ finder_query: finder_query
+).execute
+ .where(milestone_id: 5)
+ .limit(20)
+```
+
+To address this concern, we could define another index:
+
+```sql
+"idx_issues_on_project_id_and_milestone_id_and_created_at_and_id" btree (project_id, milestone_id, created_at, id)
+```
+
+Adding more indexes to the `issues` table could significantly affect the performance of
+the `UPDATE` queries. In this case, it's better to rely on the original query. It means that if we
+want to use the optimization for the unfiltered page we need to add extra logic in the application code:
+
+```ruby
+if optimization_possible? # no extra params or params covered with the same index as the ORDER BY clause
+ run_optimized_query
+else
+ run_normal_in_query
+end
+```
+
+#### Multiple `IN` queries
+
+Let's assume that we want to extend the group-level queries to include only incident and test case
+issue types.
+
+The original ActiveRecord query would look like this:
+
+```ruby
+scope = Issue
+ .where(project_id: Group.find(9970).all_projects.select(:id)) # `gitlab-org` group and its subgroups
+ .where(issue_type: [:incident, :test_case]) # 1, 2
+ .order(:created_at, :id)
+ .limit(20)
+```
+
+To construct the array scope, we'll need to take the Cartesian product of the `project_id IN` and
+the `issue_type IN` queries. `issue_type` is an ActiveRecord enum, so we need to
+construct the following table:
+
+| `project_id` | `issue_type_value` |
+| ------------ | ------------------ |
+| 2 | 1 |
+| 2 | 2 |
+| 5 | 1 |
+| 5 | 2 |
+| 10 | 1 |
+| 10 | 2 |
+| 9 | 1 |
+| 9 | 2 |
+
+For the `issue_types` query we can construct a value list without querying a table:
+
+```ruby
+value_list = Arel::Nodes::ValuesList.new([[Issue.issue_types[:incident]],[Issue.issue_types[:test_case]]])
+issue_type_values = Arel::Nodes::Grouping.new(value_list).as('issue_type_values (value)').to_sql
+
+array_scope = Group
+ .find(9970)
+ .all_projects
+ .from("#{Project.table_name}, #{issue_type_values}")
+ .select(:id, :value)
+```
+
+Building the `array_mapping_scope` query requires two arguments: `id` and `issue_type_value`:
+
+```ruby
+array_mapping_scope = -> (id_expression, issue_type_value_expression) { Issue.where(Issue.arel_table[:project_id].eq(id_expression)).where(Issue.arel_table[:issue_type].eq(issue_type_value_expression)) }
+```
+
+The `scope` and the `finder` queries don't change:
+
+```ruby
+scope = Issue.order(:created_at, :id)
+finder_query = -> (created_at_expression, id_expression) { Issue.where(Issue.arel_table[:id].eq(id_expression)) }
+
+Gitlab::Pagination::Keyset::InOperatorOptimization::QueryBuilder.new(
+ scope: scope,
+ array_scope: array_scope,
+ array_mapping_scope: array_mapping_scope,
+ finder_query: finder_query
+).execute.limit(20)
+```
+
+<details>
+<summary>Expand this sentence to see the SQL query.</summary>
+<pre><code>
+SELECT "issues".*
+FROM
+ (WITH RECURSIVE "array_cte" AS MATERIALIZED
+ (SELECT "projects"."id", "value"
+ FROM projects, (
+ VALUES (1), (2)) AS issue_type_values (value)
+ WHERE "projects"."namespace_id" IN
+ (WITH RECURSIVE "base_and_descendants" AS (
+ (SELECT "namespaces".*
+ FROM "namespaces"
+ WHERE "namespaces"."type" = 'Group'
+ AND "namespaces"."id" = 9970)
+ UNION
+ (SELECT "namespaces".*
+ FROM "namespaces", "base_and_descendants"
+ WHERE "namespaces"."type" = 'Group'
+ AND "namespaces"."parent_id" = "base_and_descendants"."id")) SELECT "id"
+ FROM "base_and_descendants" AS "namespaces")),
+ "recursive_keyset_cte" AS (
+ (SELECT NULL::issues AS records,
+ array_cte_id_array,
+ array_cte_value_array,
+ issues_created_at_array,
+ issues_id_array,
+ 0::bigint AS COUNT
+ FROM
+ (SELECT ARRAY_AGG("array_cte"."id") AS array_cte_id_array,
+ ARRAY_AGG("array_cte"."value") AS array_cte_value_array,
+ ARRAY_AGG("issues"."created_at") AS issues_created_at_array,
+ ARRAY_AGG("issues"."id") AS issues_id_array
+ FROM
+ (SELECT "array_cte"."id",
+ "array_cte"."value"
+ FROM array_cte) array_cte
+ LEFT JOIN LATERAL
+ (SELECT "issues"."created_at",
+ "issues"."id"
+ FROM "issues"
+ WHERE "issues"."project_id" = "array_cte"."id"
+ AND "issues"."issue_type" = "array_cte"."value"
+ ORDER BY "issues"."created_at" ASC, "issues"."id" ASC
+ LIMIT 1) issues ON TRUE
+ WHERE "issues"."created_at" IS NOT NULL
+ AND "issues"."id" IS NOT NULL) array_scope_lateral_query
+ LIMIT 1)
+ UNION ALL
+ (SELECT
+ (SELECT issues
+ FROM "issues"
+ WHERE "issues"."id" = recursive_keyset_cte.issues_id_array[POSITION]
+ LIMIT 1), array_cte_id_array,
+ array_cte_value_array,
+ recursive_keyset_cte.issues_created_at_array[:position_query.position-1]||next_cursor_values.created_at||recursive_keyset_cte.issues_created_at_array[position_query.position+1:], recursive_keyset_cte.issues_id_array[:position_query.position-1]||next_cursor_values.id||recursive_keyset_cte.issues_id_array[position_query.position+1:], recursive_keyset_cte.count + 1
+ FROM recursive_keyset_cte,
+ LATERAL
+ (SELECT created_at,
+ id,
+ POSITION
+ FROM UNNEST(issues_created_at_array, issues_id_array) WITH
+ ORDINALITY AS u(created_at, id, POSITION)
+ WHERE created_at IS NOT NULL
+ AND id IS NOT NULL
+ ORDER BY "created_at" ASC, "id" ASC
+ LIMIT 1) AS position_query,
+ LATERAL
+ (SELECT "record"."created_at",
+ "record"."id"
+ FROM (
+ VALUES (NULL,
+ NULL)) AS nulls
+ LEFT JOIN
+ (SELECT "issues"."created_at",
+ "issues"."id"
+ FROM (
+ (SELECT "issues"."created_at",
+ "issues"."id"
+ FROM "issues"
+ WHERE "issues"."project_id" = recursive_keyset_cte.array_cte_id_array[POSITION]
+ AND "issues"."issue_type" = recursive_keyset_cte.array_cte_value_array[POSITION]
+ AND recursive_keyset_cte.issues_created_at_array[POSITION] IS NULL
+ AND "issues"."created_at" IS NULL
+ AND "issues"."id" > recursive_keyset_cte.issues_id_array[POSITION]
+ ORDER BY "issues"."created_at" ASC, "issues"."id" ASC)
+ UNION ALL
+ (SELECT "issues"."created_at",
+ "issues"."id"
+ FROM "issues"
+ WHERE "issues"."project_id" = recursive_keyset_cte.array_cte_id_array[POSITION]
+ AND "issues"."issue_type" = recursive_keyset_cte.array_cte_value_array[POSITION]
+ AND recursive_keyset_cte.issues_created_at_array[POSITION] IS NOT NULL
+ AND "issues"."created_at" IS NULL
+ ORDER BY "issues"."created_at" ASC, "issues"."id" ASC)
+ UNION ALL
+ (SELECT "issues"."created_at",
+ "issues"."id"
+ FROM "issues"
+ WHERE "issues"."project_id" = recursive_keyset_cte.array_cte_id_array[POSITION]
+ AND "issues"."issue_type" = recursive_keyset_cte.array_cte_value_array[POSITION]
+ AND recursive_keyset_cte.issues_created_at_array[POSITION] IS NOT NULL
+ AND "issues"."created_at" > recursive_keyset_cte.issues_created_at_array[POSITION]
+ ORDER BY "issues"."created_at" ASC, "issues"."id" ASC)
+ UNION ALL
+ (SELECT "issues"."created_at",
+ "issues"."id"
+ FROM "issues"
+ WHERE "issues"."project_id" = recursive_keyset_cte.array_cte_id_array[POSITION]
+ AND "issues"."issue_type" = recursive_keyset_cte.array_cte_value_array[POSITION]
+ AND recursive_keyset_cte.issues_created_at_array[POSITION] IS NOT NULL
+ AND "issues"."created_at" = recursive_keyset_cte.issues_created_at_array[POSITION]
+ AND "issues"."id" > recursive_keyset_cte.issues_id_array[POSITION]
+ ORDER BY "issues"."created_at" ASC, "issues"."id" ASC)) issues
+ ORDER BY "issues"."created_at" ASC, "issues"."id" ASC
+ LIMIT 1) record ON TRUE
+ LIMIT 1) AS next_cursor_values)) SELECT (records).*
+ FROM "recursive_keyset_cte" AS "issues"
+ WHERE (COUNT <> 0)) issues
+LIMIT 20
+</code>
+</pre>
+</details>
+
+NOTE:
+To make the query efficient, the following columns need to be covered with an index: `project_id`, `issue_type`, `created_at`, and `id`.
+
+#### Batch iteration
+
+Batch iteration over the records is possible via the keyset `Iterator` class.
+
+```ruby
+scope = Issue.order(:created_at, :id)
+array_scope = Group.find(9970).all_projects.select(:id)
+array_mapping_scope = -> (id_expression) { Issue.where(Issue.arel_table[:project_id].eq(id_expression)) }
+finder_query = -> (created_at_expression, id_expression) { Issue.where(Issue.arel_table[:id].eq(id_expression)) }
+
+opts = {
+ in_operator_optimization_options: {
+ array_scope: array_scope,
+ array_mapping_scope: array_mapping_scope,
+ finder_query: finder_query
+ }
+}
+
+Gitlab::Pagination::Keyset::Iterator.new(scope: scope, **opts).each_batch(of: 100) do |records|
+ puts records.select(:id).map { |r| [r.id] }
+end
+```
+
+#### Keyset pagination
+
+The optimization works out of the box with GraphQL and the `keyset_paginate` helper method.
+Read more about [keyset pagination](keyset_pagination.md).
+
+```ruby
+array_scope = Group.find(9970).all_projects.select(:id)
+array_mapping_scope = -> (id_expression) { Issue.where(Issue.arel_table[:project_id].eq(id_expression)) }
+finder_query = -> (created_at_expression, id_expression) { Issue.where(Issue.arel_table[:id].eq(id_expression)) }
+
+opts = {
+ in_operator_optimization_options: {
+ array_scope: array_scope,
+ array_mapping_scope: array_mapping_scope,
+ finder_query: finder_query
+ }
+}
+
+issues = Issue
+ .order(:created_at, :id)
+ .keyset_paginate(per_page: 20, keyset_order_options: opts)
+ .records
+```
+
+#### Offset pagination with Kaminari
+
+The `ActiveRecord` scope produced by the `InOperatorOptimization` class can be used in
+[offset-paginated](pagination_guidelines.md#offset-pagination)
+queries.
+
+```ruby
+Gitlab::Pagination::Keyset::InOperatorOptimization::QueryBuilder
+ .new(...)
+ .execute
+ .page(1)
+ .per(20)
+ .without_count
+```
+
+## Generalized `IN` optimization technique
+
+Let's dive into how `QueryBuilder` builds the optimized query
+to fetch the twenty oldest created issues from the group `gitlab-org`
+using the generalized `IN` optimization technique.
+
+### Array CTE
+
+As the first step, we use a common table expression (CTE) for collecting the `projects.id` values.
+This is done by wrapping the incoming `array_scope` ActiveRecord relation parameter with a CTE.
+
+```sql
+WITH array_cte AS MATERIALIZED (
+ SELECT "projects"."id"
+ FROM "projects"
+ WHERE "projects"."namespace_id" IN
+ (SELECT traversal_ids[array_length(traversal_ids, 1)] AS id
+ FROM "namespaces"
+ WHERE (traversal_ids @> ('{9970}')))
+)
+```
+
+This query produces the following result set with only one column (`projects.id`):
+
+| ID |
+| --- |
+| 9 |
+| 2 |
+| 5 |
+| 10 |
+
+### Array mapping
+
+For each project (that is, each record storing a project ID in `array_cte`),
+we will fetch the cursor value identifying the first issue respecting the `ORDER BY` clause.
+
+As an example, let's pick the first record `ID=9` from `array_cte`.
+The following query should fetch the cursor value `(created_at, id)` identifying
+the first issue record respecting the `ORDER BY` clause for the project with `ID=9`:
+
+```sql
+SELECT "issues"."created_at", "issues"."id"
+FROM "issues"."project_id"=9
+ORDER BY "issues"."created_at" ASC, "issues"."id" ASC
+LIMIT 1;
+```
+
+We will use `LATERAL JOIN` to loop over the records in the `array_cte` and find the
+cursor value for each project. The query would be built using the `array_mapping_scope` lambda
+function.
+
+```sql
+SELECT ARRAY_AGG("array_cte"."id") AS array_cte_id_array,
+ ARRAY_AGG("issues"."created_at") AS issues_created_at_array,
+ ARRAY_AGG("issues"."id") AS issues_id_array
+FROM (
+ SELECT "array_cte"."id" FROM array_cte
+) array_cte
+LEFT JOIN LATERAL
+(
+ SELECT "issues"."created_at", "issues"."id"
+ FROM "issues"
+ WHERE "issues"."project_id" = "array_cte"."id"
+ ORDER BY "issues"."created_at" ASC, "issues"."id" ASC
+ LIMIT 1
+) issues ON TRUE
+```
+
+Since we have an index on `project_id`, `created_at`, and `id`,
+index-only scans should quickly locate all the cursor values.
+
+This is how the query could be translated to Ruby:
+
+```ruby
+created_at_values = []
+id_values = []
+project_ids.map do |project_id|
+ created_at, id = Issue.select(:created_at, :id).where(project_id: project_id).order(:created_at, :id).limit(1).first # N+1 but it's fast
+ created_at_values << created_at
+ id_values << id
+end
+```
+
+This is what the result set would look like:
+
+| `project_ids` | `created_at_values` | `id_values` |
+| ------------- | ------------------- | ----------- |
+| 2 | 2020-01-10 | 5 |
+| 5 | 2020-01-05 | 4 |
+| 10 | 2020-01-15 | 7 |
+| 9 | 2020-01-05 | 3 |
+
+The table shows the cursor values (`created_at, id`) of the first record for each project
+respecting the `ORDER BY` clause.
+
+At this point, we have the initial data. To start collecting the actual records from the database,
+we'll use a recursive CTE query where each recursion locates one row until
+the `LIMIT` is reached or no more data can be found.
+
+Here's an outline of the steps we will take in the recursive CTE query
+(expressing the steps in SQL is non-trivial but will be explained next):
+
+1. Sort the initial resultset according to the `ORDER BY` clause.
+1. Pick the top cursor to fetch the record, this is our first record. In the example,
+this cursor would be (`2020-01-05`, `3`) for `project_id=9`.
+1. We can use (`2020-01-05`, `3`) to fetch the next issue respecting the `ORDER BY` clause
+`project_id=9` filter. This produces an updated resultset.
+
+ | `project_ids` | `created_at_values` | `id_values` |
+ | ------------- | ------------------- | ----------- |
+ | 2 | 2020-01-10 | 5 |
+ | 5 | 2020-01-05 | 4 |
+ | 10 | 2020-01-15 | 7 |
+ | **9** | **2020-01-06** | **6** |
+
+1. Repeat 1 to 3 with the updated resultset until we have fetched `N=20` records.
+
+### Initializing the recursive CTE query
+
+For the initial recursive query, we'll need to produce exactly one row, we call this the
+initializer query (`initializer_query`).
+
+Use `ARRAY_AGG` function to compact the initial result set into a single row
+and use the row as the initial value for the recursive CTE query:
+
+Example initializer row:
+
+| `records` | `project_ids` | `created_at_values` | `id_values` | `Count` | `Position` |
+| -------------- | --------------- | ------------------- | ----------- | ------- | ---------- |
+| `NULL::issues` | `[9, 2, 5, 10]` | `[...]` | `[...]` | `0` | `NULL` |
+
+- The `records` column contains our sorted database records, and the initializer query sets the
+first value to `NULL`, which is filtered out later.
+- The `count` column tracks the number of records found. We use this column to filter out the
+initializer row from the result set.
+
+### Recursive portion of the CTE query
+
+The result row is produced with the following steps:
+
+1. [Order the keyset arrays.](#order-the-keyset-arrays)
+1. [Find the next cursor.](#find-the-next-cursor)
+1. [Produce a new row.](#produce-a-new-row)
+
+#### Order the keyset arrays
+
+Order the keyset arrays according to the original `ORDER BY` clause with `LIMIT 1` using the
+`UNNEST [] WITH ORDINALITY` table function. The function locates the "lowest" keyset cursor
+values and gives us the array position. These cursor values are used to locate the record.
+
+NOTE:
+At this point, we haven't read anything from the database tables, because we relied on
+fast index-only scans.
+
+| `project_ids` | `created_at_values` | `id_values` |
+| ------------- | ------------------- | ----------- |
+| 2 | 2020-01-10 | 5 |
+| 5 | 2020-01-05 | 4 |
+| 10 | 2020-01-15 | 7 |
+| 9 | 2020-01-05 | 3 |
+
+The first row is the 4th one (`position = 4`), because it has the lowest `created_at` and
+`id` values. The `UNNEST` function also exposes the position using an extra column (note:
+PostgreSQL uses 1-based index).
+
+Demonstration of the `UNNEST [] WITH ORDINALITY` table function:
+
+```sql
+SELECT position FROM unnest('{2020-01-10, 2020-01-05, 2020-01-15, 2020-01-05}'::timestamp[], '{5, 4, 7, 3}'::int[])
+ WITH ORDINALITY AS t(created_at, id, position) ORDER BY created_at ASC, id ASC LIMIT 1;
+```
+
+Result:
+
+```sql
+position
+----------
+ 4
+(1 row)
+```
+
+#### Find the next cursor
+
+Now, let's find the next cursor values (`next_cursor_values_query`) for the project with `id = 9`.
+To do that, we build a keyset pagination SQL query. Find the next row after
+`created_at = 2020-01-05` and `id = 3`. Because we order by two database columns, there can be two
+cases:
+
+- There are rows with `created_at = 2020-01-05` and `id > 3`.
+- There are rows with `created_at > 2020-01-05`.
+
+Generating this query is done by the generic keyset pagination library. After the query is done,
+we have a temporary table with the next cursor values:
+
+| `created_at` | ID |
+| ------------ | --- |
+| 2020-01-06 | 6 |
+
+#### Produce a new row
+
+As the final step, we need to produce a new row by manipulating the initializer row
+(`data_collector_query` method). Two things happen here:
+
+- Read the full row from the DB and return it in the `records` columns. (`result_collector_columns`
+method)
+- Replace the cursor values at the current position with the results from the keyset query.
+
+Reading the full row from the database is only one index scan by the primary key. We use the
+ActiveRecord query passed as the `finder_query`:
+
+```sql
+(SELECT "issues".* FROM issues WHERE id = id_values[position] LIMIT 1)
+```
+
+By adding parentheses, the result row can be put into the `records` column.
+
+Replacing the cursor values at `position` can be done via standard PostgreSQL array operators:
+
+```sql
+-- created_at_values column value
+created_at_values[:position-1]||next_cursor_values.created_at||created_at_values[position+1:]
+
+-- id_values column value
+id_values[:position-1]||next_cursor_values.id||id_values[position+1:]
+```
+
+The Ruby equivalent would be the following:
+
+```ruby
+id_values[0..(position - 1)] + [next_cursor_values.id] + id_values[(position + 1)..-1]
+```
+
+After this, the recursion starts again by finding the next lowest cursor value.
+
+### Finalizing the query
+
+For producing the final `issues` rows, we're going to wrap the query with another `SELECT` statement:
+
+```sql
+SELECT "issues".*
+FROM (
+ SELECT (records).* -- similar to ruby splat operator
+ FROM recursive_keyset_cte
+ WHERE recursive_keyset_cte.count <> 0 -- filter out the initializer row
+) AS issues
+```
+
+### Performance comparison
+
+Assuming that we have the correct database index in place, we can compare the query performance by
+looking at the number of database rows accessed by the query.
+
+- Number of groups: 100
+- Number of projects: 500
+- Number of issues (in the group hierarchy): 50 000
+
+Standard `IN` query:
+
+| Query | Entries read from index | Rows read from the table | Rows sorted in memory |
+| ------------------------ | ----------------------- | ------------------------ | --------------------- |
+| group hierarchy subquery | 100 | 0 | 0 |
+| project lookup query | 500 | 0 | 0 |
+| issue lookup query | 50 000 | 20 | 50 000 |
+
+Optimized `IN` query:
+
+| Query | Entries read from index | Rows read from the table | Rows sorted in memory |
+| ------------------------ | ----------------------- | ------------------------ | --------------------- |
+| group hierarchy subquery | 100 | 0 | 0 |
+| project lookup query | 500 | 0 | 0 |
+| issue lookup query | 519 | 20 | 10 000 |
+
+The group and project queries are not using sorting, the necessary columns are read from database
+indexes. These values are accessed frequently so it's very likely that most of the data will be
+in the PostgreSQL's buffer cache.
+
+The optimized `IN` query will read maximum 519 entries (cursor values) from the index:
+
+- 500 index-only scans for populating the arrays for each project. The cursor values of the first
+record will be here.
+- Maximum 19 additional index-only scans for the consecutive records.
+
+The optimized `IN` query will sort the array (cursor values per project array) 20 times, which
+means we'll sort 20 x 500 rows. However, this might be a less memory-intensive task than
+sorting 10 000 rows at once.
+
+Performance comparison for the `gitlab-org` group:
+
+| Query | Number of 8K Buffers involved | Uncached execution time | Cached execution time |
+| -------------------- | ----------------------------- | ----------------------- | --------------------- |
+| `IN` query | 240833 | 1.2s | 660ms |
+| Optimized `IN` query | 9783 | 450ms | 22ms |
+
+NOTE:
+Before taking measurements, the group lookup query was executed separately in order to make
+the group data available in the buffer cache. Since it's a frequently called query, it's going to
+hit many shared buffers during the query execution in the production environment.
diff --git a/doc/development/database/index.md b/doc/development/database/index.md
index b61a71ffb8e..a7b752e14ef 100644
--- a/doc/development/database/index.md
+++ b/doc/development/database/index.md
@@ -62,6 +62,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
- [Query performance guidelines](../query_performance.md)
- [Pagination guidelines](pagination_guidelines.md)
- [Pagination performance guidelines](pagination_performance_guidelines.md)
+- [Efficient `IN` operator queries](efficient_in_operator_queries.md)
## Case studies
diff --git a/doc/development/database/keyset_pagination.md b/doc/development/database/keyset_pagination.md
index e30c3cc8832..fd62c36b753 100644
--- a/doc/development/database/keyset_pagination.md
+++ b/doc/development/database/keyset_pagination.md
@@ -36,7 +36,8 @@ Keyset pagination works without any configuration for simple ActiveRecord querie
- Order by one column.
- Order by two columns, where the last column is the primary key.
-The library can detect nullable and non-distinct columns and based on these, it will add extra ordering using the primary key. This is necessary because keyset pagination expects distinct order by values:
+The library detects nullable and non-distinct columns and based on these, adds extra ordering
+using the primary key. This is necessary because keyset pagination expects distinct order by values:
```ruby
Project.order(:created_at).keyset_paginate.records # ORDER BY created_at, id
@@ -79,7 +80,7 @@ cursor = paginator.cursor_for_next_page # encoded column attributes for the next
paginator = Project.order(:name).keyset_paginate(cursor: cursor).records # loading the next page
```
-Since keyset pagination does not support page numbers, we are restricted to go to the following pages:
+Because keyset pagination does not support page numbers, we are restricted to go to the following pages:
- Next page
- Previous page
@@ -111,7 +112,8 @@ In the HAML file, we can render the records:
The performance of the keyset pagination depends on the database index configuration and the number of columns we use in the `ORDER BY` clause.
-In case we order by the primary key (`id`), then the generated queries will be efficient since the primary key is covered by a database index.
+In case we order by the primary key (`id`), then the generated queries are efficient because
+the primary key is covered by a database index.
When two or more columns are used in the `ORDER BY` clause, it's advised to check the generated database query and make sure that the correct index configuration is used. More information can be found on the [pagination guideline page](pagination_guidelines.md#index-coverage).
@@ -149,7 +151,9 @@ puts paginator2.records.to_a # UNION query
## Complex order configuration
-Common `ORDER BY` configurations will be handled by the `keyset_paginate` method automatically so no manual configuration is needed. There are a few edge cases where order object configuration is necessary:
+Common `ORDER BY` configurations are handled by the `keyset_paginate` method automatically
+so no manual configuration is needed. There are a few edge cases where order object
+configuration is necessary:
- `NULLS LAST` ordering.
- Function-based ordering.
@@ -170,12 +174,13 @@ scope.keyset_paginate # raises: Gitlab::Pagination::Keyset::Paginator::Unsupport
The `keyset_paginate` method raises an error because the order value on the query is a custom SQL string and not an [`Arel`](https://www.rubydoc.info/gems/arel) AST node. The keyset library cannot automatically infer configuration values from these kinds of queries.
-To make keyset pagination work, we need to configure custom order objects, to do so, we need to collect information about the order columns:
+To make keyset pagination work, we must configure custom order objects, to do so, we must
+collect information about the order columns:
-- `relative_position` can have duplicated values since no unique index is present.
-- `relative_position` can have null values because we don't have a not null constraint on the column. For this, we need to determine where will we see NULL values, at the beginning of the resultset or the end (`NULLS LAST`).
-- Keyset pagination requires distinct order columns, so we'll need to add the primary key (`id`) to make the order distinct.
-- Jumping to the last page and paginating backwards actually reverses the `ORDER BY` clause. For this, we'll need to provide the reversed `ORDER BY` clause.
+- `relative_position` can have duplicated values because no unique index is present.
+- `relative_position` can have null values because we don't have a not null constraint on the column. For this, we must determine where we see NULL values, at the beginning of the result set, or the end (`NULLS LAST`).
+- Keyset pagination requires distinct order columns, so we must add the primary key (`id`) to make the order distinct.
+- Jumping to the last page and paginating backwards actually reverses the `ORDER BY` clause. For this, we must provide the reversed `ORDER BY` clause.
Example:
@@ -206,7 +211,8 @@ scope.keyset_paginate.records # works
### Function-based ordering
-In the following example, we multiply the `id` by 10 and ordering by that value. Since the `id` column is unique, we need to define only one column:
+In the following example, we multiply the `id` by 10 and order by that value. Because the `id`
+column is unique, we define only one column:
```ruby
order = Gitlab::Pagination::Keyset::Order.build([
@@ -233,7 +239,8 @@ The `add_to_projections` flag tells the paginator to expose the column expressio
### `iid` based ordering
-When ordering issues, the database ensures that we'll have distinct `iid` values within a project. Ordering by one column is enough to make the pagination work if the `project_id` filter is present:
+When ordering issues, the database ensures that we have distinct `iid` values in a project.
+Ordering by one column is enough to make the pagination work if the `project_id` filter is present:
```ruby
order = Gitlab::Pagination::Keyset::Order.build([
diff --git a/doc/development/database/multiple_databases.md b/doc/development/database/multiple_databases.md
index 71dcc5bb866..0fd9f821fab 100644
--- a/doc/development/database/multiple_databases.md
+++ b/doc/development/database/multiple_databases.md
@@ -24,24 +24,26 @@ configurations. For example, given a `config/database.yml` like below:
```yaml
development:
- adapter: postgresql
- encoding: unicode
- database: gitlabhq_development
- host: /path/to/gdk/postgresql
- pool: 10
- prepared_statements: false
- variables:
- statement_timeout: 120s
+ main:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_development
+ host: /path/to/gdk/postgresql
+ pool: 10
+ prepared_statements: false
+ variables:
+ statement_timeout: 120s
test: &test
- adapter: postgresql
- encoding: unicode
- database: gitlabhq_test
- host: /path/to/gdk/postgresql
- pool: 10
- prepared_statements: false
- variables:
- statement_timeout: 120s
+ main:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_test
+ host: /path/to/gdk/postgresql
+ pool: 10
+ prepared_statements: false
+ variables:
+ statement_timeout: 120s
```
Edit the `config/database.yml` to look like this:
@@ -98,18 +100,45 @@ and their tables must be placed in two directories for now:
We aim to keep the schema for both tables the same across both databases.
+<!--
+NOTE: The `validate_cross_joins!` method in `spec/support/database/prevent_cross_joins.rb` references
+ the following heading in the code, so if you make a change to this heading, make sure to update
+ the corresponding documentation URL used in `spec/support/database/prevent_cross_joins.rb`.
+-->
+
### Removing joins between `ci_*` and non `ci_*` tables
-We are planning on moving all the `ci_*` tables to a separate database so
+Queries that join across databases raise an error. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68620)
+in GitLab 14.3, for new queries only. Pre-existing queries do not raise an error.
+
+We are planning on moving all the `ci_*` tables to a separate database, so
referencing `ci_*` tables with other tables will not be possible. This means,
that using any kind of `JOIN` in SQL queries will not work. We have identified
already many such examples that need to be fixed in
<https://gitlab.com/groups/gitlab-org/-/epics/6289> .
-The following are some real examples that have resulted from this and these
-patterns may apply to future cases.
+#### Path to removing cross-database joins
+
+The following steps are the process to remove cross-database joins between
+`ci_*` and non `ci_*` tables:
+
+1. **{check-circle}** Add all failing specs to the [`cross-join-allowlist.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/f5de89daeb468fc45e1e95a76d1b5297aa53da11/spec/support/database/cross-join-allowlist.yml)
+ file.
+1. **{dotted-circle}** Find the code that caused the spec failure and wrap the isolated code
+ in [`allow_cross_joins_across_databases`](#allowlist-for-existing-cross-joins).
+ Link to a new issue assigned to the correct team to remove the specs from the
+ `cross-join-allowlist.yml` file.
+1. **{dotted-circle}** Remove the `cross-join-allowlist.yml` file and stop allowing
+ whole test files.
+1. **{dotted-circle}** Fix the problem and remove the `allow_cross_joins_across_databases` call.
+1. **{dotted-circle}** Fix all the cross-joins and remove the `allow_cross_joins_across_databases` method.
+
+#### Suggestions for removing cross-database joins
-#### Remove the code
+The following sections are some real examples that were identified as joining across databases,
+along with possible suggestions on how to fix them.
+
+##### Remove the code
The simplest solution we've seen several times now has been an existing scope
that is unused. This is the easiest example to fix. So the first step is to
@@ -131,7 +160,7 @@ to evaluate, because `UsageData` is not critical to users and it may be possible
to get a similarly useful metric with a simpler approach. Alternatively we may
find that nobody is using these metrics, so we can remove them.
-#### Use `preload` instead of `includes`
+##### Use `preload` instead of `includes`
The `includes` and `preload` methods in Rails are both ways to avoid an N+1
query. The `includes` method in Rails uses a heuristic approach to determine
@@ -145,7 +174,7 @@ allows you to avoid the join, while still avoiding the N+1 query.
You can see a real example of this solution being used in
<https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67655>.
-#### De-normalize some foreign key to the table
+##### De-normalize some foreign key to the table
De-normalization refers to adding redundant precomputed (duplicated) data to
a table to simplify certain queries or to improve performance. In this
@@ -198,7 +227,7 @@ You can see this approach implemented in
<https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66963> . This MR also
de-normalizes `pipeline_id` to fix a similar query.
-#### De-normalize into an extra table
+##### De-normalize into an extra table
Sometimes the previous de-normalization (adding an extra column) doesn't work for
your specific case. This may be due to the fact that your data is not 1:1, or
@@ -245,18 +274,88 @@ logic to delete these rows if or whenever necessary in your domain.
Finally, this de-normalization and new query also improves performance because
it does less joins and needs less filtering.
-#### Summary of cross-join removal patterns
+##### Use `disable_joins` for `has_one` or `has_many` `through:` relations
+
+Sometimes a join query is caused by using `has_one ... through:` or `has_many
+... through:` across tables that span the different databases. These joins
+sometimes can be solved by adding
+[`disable_joins:true`](https://edgeguides.rubyonrails.org/active_record_multiple_databases.html#handling-associations-with-joins-across-databases).
+This is a Rails feature which we
+[backported](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66400). We
+also extended the feature to allow a lambda syntax for enabling `disable_joins`
+with a feature flag. If you use this feature we encourage using a feature flag
+as it mitigates risk if there is some serious performance regression.
+
+You can see an example where this was used in
+<https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66709/diffs>.
+
+With any change to DB queries it is important to analyze and compare the SQL
+before and after the change. `disable_joins` can introduce very poorly performing
+code depending on the actual logic of the `has_many` or `has_one` relationship.
+The key thing to look for is whether any of the intermediate result sets
+used to construct the final result set have an unbounded amount of data loaded.
+The best way to tell is by looking at the SQL generated and confirming that
+each one is limited in some way. You can tell by either a `LIMIT 1` clause or
+by `WHERE` clause that is limiting based on a unique column. Any unbounded
+intermediate dataset could lead to loading too many IDs into memory.
+
+An example where you may see very poor performance is the following
+hypothetical code:
+
+```ruby
+class Project
+ has_many :pipelines
+ has_many :builds, through: :pipelines
+end
+
+class Pipeline
+ has_many :builds
+end
+
+class Build
+ belongs_to :pipeline
+end
+
+def some_action
+ @builds = Project.find(5).builds.order(created_at: :desc).limit(10)
+end
+```
+
+In the above case `some_action` will generate a query like:
+
+```sql
+select * from builds
+inner join pipelines on builds.pipeline_id = pipelines.id
+where pipelines.project_id = 5
+order by builds.created_at desc
+limit 10
+```
+
+However, if you changed the relation to be:
+
+```ruby
+class Project
+ has_many :pipelines
+ has_many :builds, through: :pipelines, disable_joins: true
+end
+```
-A quick checklist for fixing a specific join query would be:
+Then you would get the following 2 queries:
-1. Is the code even used? If not just remove it
-1. If the code is used, then is this feature even used or can we implement the
- feature in a simpler way and still meet the requirements. Always prefer the
- simplest option.
-1. Can we remove the join if we de-normalize the data you are joining to by
- adding a new column
-1. Can we remove the join by adding a new table in the correct database that
- replicates the minimum data needed to do the join
+```sql
+select id from pipelines where project_id = 5;
+
+select * from builds where pipeline_id in (...)
+order by created_at desc
+limit 10;
+```
+
+Because the first query does not limit by any unique column or
+have a `LIMIT` clause, it can load an unlimited number of
+pipeline IDs into memory, which are then sent in the following query.
+This can lead to very poor performance in the Rails application and the
+database. In cases like this, you might need to re-write the
+query or look at other patterns described above for removing cross-joins.
#### How to validate you have correctly removed a cross-join
@@ -291,3 +390,74 @@ end
You can see a real example of using this method for fixing a cross-join in
<https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67655>.
+
+#### Allowlist for existing cross-joins
+
+A cross-join across databases can be explicitly allowed by wrapping the code in the
+`::Gitlab::Database.allow_cross_joins_across_databases` helper method.
+
+This method should only be used:
+
+- For existing code.
+- If the code is required to help migrate away from a cross-join. For example,
+ in a migration that backfills data for future use to remove a cross-join.
+
+The `allow_cross_joins_across_databases` helper method can be used as follows:
+
+```ruby
+::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336590') do
+ subject.perform(1, 4)
+end
+```
+
+The `url` parameter should point to an issue with a milestone for when we intend
+to fix the cross-join. If the cross-join is being used in a migration, we do not
+need to fix the code. See <https://gitlab.com/gitlab-org/gitlab/-/issues/340017>
+for more details.
+
+## `config/database.yml`
+
+GitLab will support running multiple databases in the future, for example to [separate tables for the continuous integration features](https://gitlab.com/groups/gitlab-org/-/epics/6167) from the main database. In order to prepare for this change, we [validate the structure of the configuration](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67877) in `database.yml` to ensure that only known databases are used.
+
+Previously, the `config/database.yml` would look like this:
+
+```yaml
+production:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_production
+ ...
+```
+
+With the support for many databases the support for this
+syntax is deprecated and will be removed in [15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/338182).
+
+The new `config/database.yml` needs to include a database name
+to define a database configuration. Only `main:` and `ci:` database
+names are supported today. The `main:` needs to always be a first
+entry in a hash. This change applies to decomposed and non-decomposed
+change. If an invalidate or deprecated syntax is used the error
+or warning will be printed during application start.
+
+```yaml
+# Non-decomposed database
+production:
+ main:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_production
+ ...
+
+# Decomposed database
+production:
+ main:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_production
+ ...
+ ci:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_production_ci
+ ...
+```
diff --git a/doc/development/database/not_null_constraints.md b/doc/development/database/not_null_constraints.md
index 178a207dab5..de070f7e434 100644
--- a/doc/development/database/not_null_constraints.md
+++ b/doc/development/database/not_null_constraints.md
@@ -25,7 +25,7 @@ For example, consider a migration that creates a table with two `NOT NULL` colum
`db/migrate/20200401000001_create_db_guides.rb`:
```ruby
-class CreateDbGuides < ActiveRecord::Migration[6.0]
+class CreateDbGuides < Gitlab::Database::Migration[1.0]
def change
create_table :db_guides do |t|
t.bigint :stars, default: 0, null: false
@@ -44,7 +44,7 @@ For example, consider a migration that adds a new `NOT NULL` column `active` to
`db/migrate/20200501000001_add_active_to_db_guides.rb`:
```ruby
-class AddExtendedTitleToSprints < ActiveRecord::Migration[6.0]
+class AddExtendedTitleToSprints < Gitlab::Database::Migration[1.0]
def change
add_column :db_guides, :active, :boolean, default: true, null: false
end
@@ -111,9 +111,7 @@ with `validate: false` in a post-deployment migration,
`db/post_migrate/20200501000001_add_not_null_constraint_to_epics_description.rb`:
```ruby
-class AddNotNullConstraintToEpicsDescription < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
+class AddNotNullConstraintToEpicsDescription < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
@@ -144,9 +142,7 @@ so we are going to add a post-deployment migration for the 13.0 milestone (curre
`db/post_migrate/20200501000002_cleanup_epics_with_null_description.rb`:
```ruby
-class CleanupEpicsWithNullDescription < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
+class CleanupEpicsWithNullDescription < Gitlab::Database::Migration[1.0]
# With BATCH_SIZE=1000 and epics.count=29500 on GitLab.com
# - 30 iterations will be run
# - each requires on average ~150ms
@@ -184,9 +180,7 @@ migration helper in a final post-deployment migration,
`db/post_migrate/20200601000001_validate_not_null_constraint_on_epics_description.rb`:
```ruby
-class ValidateNotNullConstraintOnEpicsDescription < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
+class ValidateNotNullConstraintOnEpicsDescription < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
diff --git a/doc/development/database/pagination_guidelines.md b/doc/development/database/pagination_guidelines.md
index b7209b4ca30..3a772b10a6d 100644
--- a/doc/development/database/pagination_guidelines.md
+++ b/doc/development/database/pagination_guidelines.md
@@ -302,7 +302,7 @@ LIMIT 20
##### Tooling
-A generic keyset pagination library is available within the GitLab project which can most of the cases easly replace the existing, kaminari based pagination with significant performance improvements when dealing with large datasets.
+A generic keyset pagination library is available within the GitLab project which can most of the cases easily replace the existing, kaminari based pagination with significant performance improvements when dealing with large datasets.
Example:
diff --git a/doc/development/database/rename_database_tables.md b/doc/development/database/rename_database_tables.md
index 8ac50d2c0a0..881adf00ad0 100644
--- a/doc/development/database/rename_database_tables.md
+++ b/doc/development/database/rename_database_tables.md
@@ -60,7 +60,7 @@ Consider the next release as "Release N.M".
Execute a standard migration (not a post-migration):
```ruby
- include Gitlab::Database::MigrationHelpers
+ enable_lock_retries!
def up
rename_table_safely(:issues, :tickets)
@@ -96,8 +96,6 @@ At this point, we don't have applications using the old database table name in t
1. Remove the database view through a post-migration:
```ruby
- include Gitlab::Database::MigrationHelpers
-
def up
finalize_table_rename(:issues, :tickets)
end
diff --git a/doc/development/database/strings_and_the_text_data_type.md b/doc/development/database/strings_and_the_text_data_type.md
index 688d811b897..a0dda42fdc7 100644
--- a/doc/development/database/strings_and_the_text_data_type.md
+++ b/doc/development/database/strings_and_the_text_data_type.md
@@ -11,11 +11,13 @@ info: To determine the technical writer assigned to the Stage/Group associated w
When adding new columns that will be used to store strings or other textual information:
1. We always use the `text` data type instead of the `string` data type.
-1. `text` columns should always have a limit set, either by using the `create_table_with_constraints` helper
-when creating a table, or by using the `add_text_limit` when altering an existing table.
+1. `text` columns should always have a limit set, either by using the `create_table` with
+the `#text ... limit: 100` helper (see below) when creating a table, or by using the `add_text_limit`
+when altering an existing table.
-The `text` data type can not be defined with a limit, so `create_table_with_constraints` and `add_text_limit` enforce
-that by adding a [check constraint](https://www.postgresql.org/docs/11/ddl-constraints.html) on the column.
+The standard Rails `text` column type can not be defined with a limit, but we extend `create_table` to
+add a `limit: 255` option. Outside of `create_table`, `add_text_limit` can be used to add a [check constraint](https://www.postgresql.org/docs/11/ddl-constraints.html)
+to an already existing column.
## Background information
@@ -41,36 +43,24 @@ Don't use text columns for `attr_encrypted` attributes. Use a
## Create a new table with text columns
When adding a new table, the limits for all text columns should be added in the same migration as
-the table creation.
+the table creation. We add a `limit:` attribute to Rails' `#text` method, which allows adding a limit
+for this column.
For example, consider a migration that creates a table with two text columns,
`db/migrate/20200401000001_create_db_guides.rb`:
```ruby
-class CreateDbGuides < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- def up
- create_table_with_constraints :db_guides do |t|
+class CreateDbGuides < Gitlab::Database::Migration[1.0]
+ def change
+ create_table :db_guides do |t|
t.bigint :stars, default: 0, null: false
- t.text :title
- t.text :notes
-
- t.text_limit :title, 128
- t.text_limit :notes, 1024
+ t.text :title, limit: 128
+ t.text :notes, limit: 1024
end
end
-
- def down
- # No need to drop the constraints, drop_table takes care of everything
- drop_table :db_guides
- end
end
```
-Note that the `create_table_with_constraints` helper uses the `with_lock_retries` helper
-internally, so we don't need to manually wrap the method call in the migration.
-
## Add a text column to an existing table
Adding a column to an existing table requires an exclusive lock for that table. Even though that lock
@@ -84,7 +74,7 @@ For example, consider a migration that adds a new text column `extended_title` t
`db/migrate/20200501000001_add_extended_title_to_sprints.rb`:
```ruby
-class AddExtendedTitleToSprints < ActiveRecord::Migration[6.0]
+class AddExtendedTitleToSprints < Gitlab::Database::Migration[1.0]
# rubocop:disable Migration/AddLimitToTextColumns
# limit is added in 20200501000002_add_text_limit_to_sprints_extended_title
@@ -99,8 +89,7 @@ A second migration should follow the first one with a limit added to `extended_t
`db/migrate/20200501000002_add_text_limit_to_sprints_extended_title.rb`:
```ruby
-class AddTextLimitToSprintsExtendedTitle < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
+class AddTextLimitToSprintsExtendedTitle < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
@@ -175,9 +164,7 @@ in a post-deployment migration,
`db/post_migrate/20200501000001_add_text_limit_migration.rb`:
```ruby
-class AddTextLimitMigration < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
+class AddTextLimitMigration < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
@@ -208,9 +195,7 @@ to add a background migration for the 13.0 milestone (current),
`db/post_migrate/20200501000002_schedule_cap_title_length_on_issues.rb`:
```ruby
-class ScheduleCapTitleLengthOnIssues < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
+class ScheduleCapTitleLengthOnIssues < Gitlab::Database::Migration[1.0]
# Info on how many records will be affected on GitLab.com
# time each batch needs to run on average, etc ...
BATCH_SIZE = 5000
@@ -255,9 +240,7 @@ helper in a final post-deployment migration,
`db/post_migrate/20200601000001_validate_text_limit_migration.rb`:
```ruby
-class ValidateTextLimitMigration < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
+class ValidateTextLimitMigration < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
diff --git a/doc/development/database/table_partitioning.md b/doc/development/database/table_partitioning.md
index 207d5a733ce..5319c73aad0 100644
--- a/doc/development/database/table_partitioning.md
+++ b/doc/development/database/table_partitioning.md
@@ -173,7 +173,7 @@ An example migration of partitioning the `audit_events` table by its
`created_at` column would look like:
```ruby
-class PartitionAuditEvents < ActiveRecord::Migration[6.0]
+class PartitionAuditEvents < Gitlab::Database::Migration[1.0]
include Gitlab::Database::PartitioningMigrationHelpers
def up
@@ -200,7 +200,7 @@ into the partitioned copy.
Continuing the above example, the migration would look like:
```ruby
-class BackfillPartitionAuditEvents < ActiveRecord::Migration[6.0]
+class BackfillPartitionAuditEvents < Gitlab::Database::Migration[1.0]
include Gitlab::Database::PartitioningMigrationHelpers
def up
@@ -233,7 +233,7 @@ failed jobs.
Once again, continuing the example, this migration would look like:
```ruby
-class CleanupPartitionedAuditEventsBackfill < ActiveRecord::Migration[6.0]
+class CleanupPartitionedAuditEventsBackfill < Gitlab::Database::Migration[1.0]
include Gitlab::Database::PartitioningMigrationHelpers
def up
diff --git a/doc/development/database/transaction_guidelines.md b/doc/development/database/transaction_guidelines.md
index 1c25496b153..4c586135015 100644
--- a/doc/development/database/transaction_guidelines.md
+++ b/doc/development/database/transaction_guidelines.md
@@ -12,7 +12,7 @@ For further reference please check PostgreSQL documentation about [transactions]
## Database decomposition and sharding
-The [sharding group](https://about.gitlab.com/handbook/engineering/development/enablement/sharding) plans to split the main GitLab database and move some of the database tables to other database servers.
+The [sharding group](https://about.gitlab.com/handbook/engineering/development/enablement/sharding/) plans to split the main GitLab database and move some of the database tables to other database servers.
The group will start decomposing the `ci_*` related database tables first. To maintain the current application development experience, tooling and static analyzers will be added to the codebase to ensure correct data access and data modification methods. By using the correct form for defining database transactions, we can save significant refactoring work in the future.
diff --git a/doc/development/database_debugging.md b/doc/development/database_debugging.md
index 67ec1b3c4f1..b1c8508c884 100644
--- a/doc/development/database_debugging.md
+++ b/doc/development/database_debugging.md
@@ -25,6 +25,12 @@ If you just want to delete everything and start over with an empty DB (approxima
bundle exec rake db:reset RAILS_ENV=development
```
+If you want to seed the empty DB with sample data (approximately 4 minutes):
+
+```shell
+bundle exec rake dev:setup
+```
+
If you just want to delete everything and start over with sample data (approximately 4 minutes). This
also does `db:reset` and runs DB-specific migrations:
@@ -64,6 +70,36 @@ bundle exec rails db -e development
- `SELECT * FROM schema_migrations WHERE version = '20170926203418';`: Check if a migration was run
- `DELETE FROM schema_migrations WHERE version = '20170926203418';`: Manually remove a migration
+## Access the database with a GUI
+
+Most GUIs (DataGrid, RubyMine, DBeaver) require a TCP connection to the database, but by default
+the database runs on a UNIX socket. To be able to access the database from these tools, some steps
+are needed:
+
+1. On the GDK root directory, run:
+
+ ```shell
+ gdk config set postgresql.host localhost
+ ```
+
+1. Open your `gdk.yml`, and confirm that it has the following lines:
+
+ ```yaml
+ postgresql:
+ host: localhost
+ ```
+
+1. Reconfigure GDK:
+
+ ```shell
+ gdk reconfigure
+ ```
+
+1. On your database GUI, select `localhost` as host, `5432` as port and `gitlabhq_development` as database.
+ Alternatively, you can use the connection string `postgresql://localhost:5432/gitlabhq_development`.
+
+The new connection should be working now.
+
## Access the GDK database with Visual Studio Code
Use these instructions for exploring the GitLab database while developing with the GDK:
diff --git a/doc/development/database_review.md b/doc/development/database_review.md
index 2746d9f6582..42bfa656a61 100644
--- a/doc/development/database_review.md
+++ b/doc/development/database_review.md
@@ -108,7 +108,7 @@ the following preparations into account.
- Ensure the down method reverts the changes in `db/structure.sql`.
- Update the migration output whenever you modify the migrations during the review process.
- Add tests for the migration in `spec/migrations` if necessary. See [Testing Rails migrations at GitLab](testing_guide/testing_migrations_guide.md) for more details.
-- When [high-traffic](https://gitlab.com/gitlab-org/gitlab/-/blob/master/rubocop/rubocop-migrations.yml#L3) tables are involved in the migration, use the [`with_lock_retries`](migration_style_guide.md#retry-mechanism-when-acquiring-database-locks) helper method. Review the relevant [examples in our documentation](migration_style_guide.md#examples) for use cases and solutions.
+- When [high-traffic](https://gitlab.com/gitlab-org/gitlab/-/blob/master/rubocop/rubocop-migrations.yml#L3) tables are involved in the migration, use the [`enable_lock_retries`](migration_style_guide.md#retry-mechanism-when-acquiring-database-locks) method to enable lock-retries. Review the relevant [examples in our documentation](migration_style_guide.md#usage-with-transactional-migrations) for use cases and solutions.
- Ensure RuboCop checks are not disabled unless there's a valid reason to.
- When adding an index to a [large table](https://gitlab.com/gitlab-org/gitlab/-/blob/master/rubocop/rubocop-migrations.yml#L3),
test its execution using `CREATE INDEX CONCURRENTLY` in the `#database-lab` Slack channel and add the execution time to the MR description:
@@ -128,7 +128,9 @@ test its execution using `CREATE INDEX CONCURRENTLY` in the `#database-lab` Slac
- Write the raw SQL in the MR description. Preferably formatted
nicely with [pgFormatter](https://sqlformat.darold.net) or
[paste.depesz.com](https://paste.depesz.com) and using regular quotes
+ <!-- vale off -->
(for example, `"projects"."id"`) and avoiding smart quotes (for example, `“projectsâ€.“idâ€`).
+ <!-- vale on -->
- In case of queries generated dynamically by using parameters, there should be one raw SQL query for each variation.
For example, a finder for issues that may take as a parameter an optional filter on projects,
diff --git a/doc/development/deprecation_guidelines/index.md b/doc/development/deprecation_guidelines/index.md
index 3543345aa34..f8ee29e6904 100644
--- a/doc/development/deprecation_guidelines/index.md
+++ b/doc/development/deprecation_guidelines/index.md
@@ -32,6 +32,6 @@ It also should be [deprecated in advance](https://about.gitlab.com/handbook/mark
For API removals, see the [GraphQL](../../api/graphql/index.md#deprecation-and-removal-process) and [GitLab API](../../api/index.md#compatibility-guidelines) guidelines.
-For configuration removals, see the [Omnibus deprecation policy](https://docs.gitlab.com/omnibus/package-information/deprecation_policy.html).
+For configuration removals, see the [Omnibus deprecation policy](../../administration/package_information/deprecation_policy.md).
For versioning and upgrade details, see our [Release and Maintenance policy](../../policy/maintenance.md).
diff --git a/doc/development/documentation/feature_flags.md b/doc/development/documentation/feature_flags.md
index b0fa6c3428c..5a4d365ed20 100644
--- a/doc/development/documentation/feature_flags.md
+++ b/doc/development/documentation/feature_flags.md
@@ -67,10 +67,12 @@ When the state of a flag changes (for example, disabled by default to enabled by
Possible version history entries are:
```markdown
-> - [Enabled on GitLab.com](issue-link) in GitLab X.X and is ready for production use.
-> - [Enabled on GitLab.com](issue-link) in GitLab X.X and is ready for production use. Available to GitLab.com administrators only.
-> - [Enabled with <flag name> flag](issue-link) for self-managed GitLab in GitLab X.X and is ready for production use.
-> - [Feature flag <flag name> removed](issue-line) in GitLab X.X.
+> - [Introduced](issue-link) in GitLab X.X. [Deployed behind the <flag name> flag](../../administration/feature_flags.md), disabled by default.
+> - [Enabled on GitLab.com](issue-link) in GitLab X.X.
+> - [Enabled on GitLab.com](issue-link) in GitLab X.X. Available to GitLab.com administrators only.
+> - [Enabled on self-managed](issue-link) in GitLab X.X.
+> - [Feature flag <flag name> removed](issue-link) in GitLab X.X.
+> - [Generally available](issue-link) in GitLab X.X.
```
## Feature flag documentation examples
@@ -78,7 +80,7 @@ Possible version history entries are:
The following examples show the progression of a feature flag.
```markdown
-> Introduced in GitLab 13.7.
+> Introduced in GitLab 13.7. [Deployed behind the `forti_token_cloud` flag](../../administration/feature_flags.md), disabled by default.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available,
@@ -86,11 +88,11 @@ ask an administrator to [enable the `forti_token_cloud` flag](../administration/
The feature is not ready for production use.
```
-If it were to be updated in the future to enable its use in production, you can update the version history:
+When the feature is enabled in production, you can update the version history:
```markdown
-> - Introduced in GitLab 13.7.
-> - [Enabled with `forti_token_cloud` flag](https://gitlab.com/issue/etc) for self-managed GitLab in GitLab X.X and ready for production use.
+> - Introduced in GitLab 13.7. [Deployed behind the `forti_token_cloud` flag](../../administration/feature_flags.md), disabled by default.
+> - [Enabled on self-managed](https://gitlab.com/issue/etc) GitLab 13.8.
FLAG:
On self-managed GitLab, by default this feature is available. To hide the feature per user,
@@ -100,8 +102,9 @@ ask an administrator to [disable the `forti_token_cloud` flag](../administration
And, when the feature is done and fully available to all users:
```markdown
-> - Introduced in GitLab 13.7.
-> - [Enabled on GitLab.com](https://gitlab.com/issue/etc) in GitLab X.X and is ready for production use.
-> - [Enabled with `forti_token_cloud` flag](https://gitlab.com/issue/etc) for self-managed GitLab in GitLab X.X and is ready for production use.
-> - [Feature flag `forti_token_cloud`](https://gitlab.com/issue/etc) removed in GitLab X.X.
+> - Introduced in GitLab 13.7. [Deployed behind the `forti_token_cloud` flag](../../administration/feature_flags.md), disabled by default.
+> - [Enabled on self-managed](https://gitlab.com/issue/etc) GitLab 13.8.
+> - [Enabled on GitLab.com](https://gitlab.com/issue/etc) in GitLab 13.9.
+> - [Feature flag `forti_token_cloud`](https://gitlab.com/issue/etc) removed in GitLab 14.0.
+> - [Generally available](issue-link) in GitLab 14.0.
```
diff --git a/doc/development/documentation/index.md b/doc/development/documentation/index.md
index 59a1b8c7b99..a597ea512c6 100644
--- a/doc/development/documentation/index.md
+++ b/doc/development/documentation/index.md
@@ -131,10 +131,10 @@ The following metadata should be added when a page is moved to another location:
- `redirect_to`: The relative path and filename (with an `.md` extension) of the
location to which visitors should be redirected for a moved page.
- [Learn more](#move-or-rename-a-page).
+ [Learn more](redirects.md).
- `disqus_identifier`: Identifier for Disqus commenting system. Used to keep
comments with a page that's been moved to a new URL.
- [Learn more](#redirections-for-pages-with-disqus-comments).
+ [Learn more](redirects.md#redirections-for-pages-with-disqus-comments).
### Comments metadata
@@ -156,133 +156,7 @@ Nanoc layout), which is displayed at the top of the page if defined.
## Move or rename a page
-Moving or renaming a document is the same as changing its location. Be sure to
-assign a technical writer to any merge request that renames or moves a page.
-Technical Writers can help with any questions and can review your change.
-
-When moving or renaming a page, you must redirect browsers to the new page.
-This ensures users find the new page, and have the opportunity to update their
-bookmarks.
-
-There are two types of redirects:
-
-- Redirect codes added into the documentation files themselves, for users who
- view the docs in `/help` on self-managed instances. For example,
- [`/help` on GitLab.com](https://gitlab.com/help).
-- [GitLab Pages redirects](../../user/project/pages/redirects.md),
- for users who view the docs on [`docs.gitlab.com`](https://docs.gitlab.com).
-
-The Technical Writing team manages the [process](https://gitlab.com/gitlab-org/technical-writing/-/blob/main/.gitlab/issue_templates/tw-monthly-tasks.md)
-to regularly update the [`redirects.yaml`](https://gitlab.com/gitlab-org/gitlab-docs/-/blob/main/content/_data/redirects.yaml)
-file.
-
-To add a redirect:
-
-1. In the repository (`gitlab`, `gitlab-runner`, `omnibus-gitlab`, or `charts`),
- create a new documentation file. Don't delete the old one. The easiest
- way is to copy it. For example:
-
- ```shell
- cp doc/user/search/old_file.md doc/api/new_file.md
- ```
-
-1. Add the redirect code to the old documentation file by running the
- following Rake task. The first argument is the path of the old file,
- and the second argument is the path of the new file:
-
- - To redirect to a page in the same project, use relative paths and
- the `.md` extension. Both old and new paths start from the same location.
- In the following example, both paths are relative to `doc/`:
-
- ```shell
- bundle exec rake "gitlab:docs:redirect[doc/user/search/old_file.md, doc/api/new_file.md]"
- ```
-
- - To redirect to a page in a different project or site, use the full URL (with `https://`) :
-
- ```shell
- bundle exec rake "gitlab:docs:redirect[doc/user/search/old_file.md, https://example.com]"
- ```
-
- Alternatively, you can omit the arguments and be asked to enter their values:
-
- ```shell
- bundle exec rake gitlab:docs:redirect
- ```
-
- If you don't want to use the Rake task, you can use the following template.
- However, the file paths must be relative to the `doc` or `docs` directory.
-
- Replace the value of `redirect_to` with the new file path and `YYYY-MM-DD`
- with the date the file should be removed.
-
- Redirect files that link to docs in internal documentation projects
- are removed after three months. Redirect files that link to external sites are
- removed after one year:
-
- ```markdown
- ---
- redirect_to: '../newpath/to/file/index.md'
- remove_date: 'YYYY-MM-DD'
- ---
-
- This document was moved to [another location](../path/to/file/index.md).
-
- <!-- This redirect file can be deleted after <YYYY-MM-DD>. -->
- <!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
- ```
-
-1. If the documentation page being moved has any Disqus comments, follow the steps
- described in [Redirections for pages with Disqus comments](#redirections-for-pages-with-disqus-comments).
-1. Open a merge request with your changes. If a documentation page
- you're removing includes images that aren't used
- with any other documentation pages, be sure to use your merge request to delete
- those images from the repository.
-1. Assign the merge request to a technical writer for review and merge.
-1. Search for links to the old documentation file. You must find and update all
- links that point to the old documentation file:
-
- - In <https://gitlab.com/gitlab-com/www-gitlab-com>, search for full URLs:
- `grep -r "docs.gitlab.com/ee/path/to/file.html" .`
- - In <https://gitlab.com/gitlab-org/gitlab-docs/-/tree/master/content/_data>,
- search the navigation bar configuration files for the path with `.html`:
- `grep -r "path/to/file.html" .`
- - In any of the four internal projects, search for links in the docs
- and codebase. Search for all variations, including full URL and just the path.
- For example, go to the root directory of the `gitlab` project and run:
-
- ```shell
- grep -r "docs.gitlab.com/ee/path/to/file.html" .
- grep -r "path/to/file.html" .
- grep -r "path/to/file.md" .
- grep -r "path/to/file" .
- ```
-
- You may need to try variations of relative links, such as `../path/to/file` or
- `../file` to find every case.
-
-### Redirections for pages with Disqus comments
-
-If the documentation page being relocated already has Disqus comments,
-we need to preserve the Disqus thread.
-
-Disqus uses an identifier per page, and for <https://docs.gitlab.com>, the page identifier
-is configured to be the page URL. Therefore, when we change the document location,
-we need to preserve the old URL as the same Disqus identifier.
-
-To do that, add to the front matter the variable `disqus_identifier`,
-using the old URL as value. For example, let's say we moved the document
-available under `https://docs.gitlab.com/my-old-location/README.html` to a new location,
-`https://docs.gitlab.com/my-new-location/index.html`.
-
-Into the **new document** front matter, we add the following information. You must
-include the filename in the `disqus_identifier` URL, even if it's `index.html` or `README.html`.
-
-```yaml
----
-disqus_identifier: 'https://docs.gitlab.com/my-old-location/README.html'
----
-```
+See [redirects](redirects.md).
## Merge requests for GitLab documentation
@@ -405,76 +279,7 @@ on how the left-side navigation menu is built and updated.
## Previewing the changes live
-NOTE:
-To preview your changes to documentation locally, follow this
-[development guide](https://gitlab.com/gitlab-org/gitlab-docs/blob/main/README.md#development-when-contributing-to-gitlab-documentation) or [these instructions for GDK](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/main/doc/howto/gitlab_docs.md).
-
-The live preview is currently enabled for the following projects:
-
-- [`gitlab`](https://gitlab.com/gitlab-org/gitlab)
-- [`omnibus-gitlab`](https://gitlab.com/gitlab-org/omnibus-gitlab)
-- [`gitlab-runner`](https://gitlab.com/gitlab-org/gitlab-runner)
-
-If your merge request has docs changes, you can use the manual `review-docs-deploy` job
-to deploy the docs review app for your merge request.
-
-![Manual trigger a docs build](img/manual_build_docs.png)
-
-You must push a branch to those repositories, as it doesn't work for forks.
-
-The `review-docs-deploy*` job:
-
-1. Triggers a cross project pipeline and build the docs site with your changes.
-
-In case the review app URL returns 404, this means that either the site is not
-yet deployed, or something went wrong with the remote pipeline. Give it a few
-minutes and it should appear online, otherwise you can check the status of the
-remote pipeline from the link in the merge request's job output.
-If the pipeline failed or got stuck, drop a line in the `#docs` chat channel.
-
-NOTE:
-Someone with no merge rights to the GitLab projects (think of forks from
-contributors) cannot run the manual job. In that case, you can
-ask someone from the GitLab team who has the permissions to do that for you.
-
-### Troubleshooting review apps
-
-In case the review app URL returns 404, follow these steps to debug:
-
-1. **Did you follow the URL from the merge request widget?** If yes, then check if
- the link is the same as the one in the job output.
-1. **Did you follow the URL from the job output?** If yes, then it means that
- either the site is not yet deployed or something went wrong with the remote
- pipeline. Give it a few minutes and it should appear online, otherwise you
- can check the status of the remote pipeline from the link in the job output.
- If the pipeline failed or got stuck, drop a line in the `#docs` chat channel.
-
-### Technical aspects
-
-If you want to know the in-depth details, here's what's really happening:
-
-1. You manually run the `review-docs-deploy` job in a merge request.
-1. The job runs the [`scripts/trigger-build`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/scripts/trigger-build)
- script with the `docs deploy` flag, which triggers the "Triggered from `gitlab-org/gitlab` 'review-docs-deploy' job"
- pipeline trigger in the `gitlab-org/gitlab-docs` project for the `$DOCS_BRANCH` (defaults to `main`).
-1. The preview URL is shown both at the job output and in the merge request
- widget. You also get the link to the remote pipeline.
-1. In the `gitlab-org/gitlab-docs` project, the pipeline is created and it
- [skips the test jobs](https://gitlab.com/gitlab-org/gitlab-docs/blob/8d5d5c750c602a835614b02f9db42ead1c4b2f5e/.gitlab-ci.yml#L50-55)
- to lower the build time.
-1. Once the docs site is built, the HTML files are uploaded as artifacts.
-1. A specific runner tied only to the docs project, runs the Review App job
- that downloads the artifacts and uses `rsync` to transfer the files over
- to a location where NGINX serves them.
-
-The following GitLab features are used among others:
-
-- [Manual jobs](../../ci/jobs/job_control.md#create-a-job-that-must-be-run-manually)
-- [Multi project pipelines](../../ci/pipelines/multi_project_pipelines.md)
-- [Review Apps](../../ci/review_apps/index.md)
-- [Artifacts](../../ci/yaml/index.md#artifacts)
-- [Specific runner](../../ci/runners/runners_scope.md#prevent-a-specific-runner-from-being-enabled-for-other-projects)
-- [Pipelines for merge requests](../../ci/pipelines/merge_request_pipelines.md)
+See how you can use review apps to [preview your changes live](review_apps.md).
## Testing
diff --git a/doc/development/documentation/redirects.md b/doc/development/documentation/redirects.md
new file mode 100644
index 00000000000..eb6878f5870
--- /dev/null
+++ b/doc/development/documentation/redirects.md
@@ -0,0 +1,155 @@
+---
+stage: none
+group: Documentation Guidelines
+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
+description: Learn how to contribute to GitLab Documentation.
+---
+
+<!---
+ The clean_redirects Rake task in the gitlab-docs repository manually
+ excludes this file. If the line containing remove_date is moved to a new
+ document, update the Rake task with the new location.
+
+ https://gitlab.com/gitlab-org/gitlab-docs/-/blob/1979f985708d64558bb487fbe9ed5273729c01b7/Rakefile#L306
+--->
+
+# Redirects in GitLab documentation
+
+Moving or renaming a document is the same as changing its location. Be sure
+to assign a technical writer to any merge request that renames or moves a page.
+Technical Writers can help with any questions and can review your change.
+
+When moving or renaming a page, you must redirect browsers to the new page.
+This ensures users find the new page, and have the opportunity to update their
+bookmarks.
+
+There are two types of redirects:
+
+- Redirect added into the documentation files themselves, for users who
+ view the docs in `/help` on self-managed instances. For example,
+ [`/help` on GitLab.com](https://gitlab.com/help).
+- [GitLab Pages redirects](../../user/project/pages/redirects.md),
+ for users who view the docs on [`docs.gitlab.com`](https://docs.gitlab.com).
+
+ The Technical Writing team manages the [process](https://gitlab.com/gitlab-org/technical-writing/-/blob/main/.gitlab/issue_templates/tw-monthly-tasks.md)
+ to regularly update and [clean up the redirects](https://gitlab.com/gitlab-org/gitlab-docs/-/blob/main/doc/raketasks.md#clean-up-redirects).
+ If you're a contributor, you may add a new redirect, but you don't need to delete
+ the old ones. This process is automatic and handled by the Technical
+ Writing team.
+
+NOTE:
+If the old page you're renaming doesn't exist in a stable branch, skip the
+following steps and ask a Technical Writer to add the redirect in
+[`redirects.yaml`](https://gitlab.com/gitlab-org/gitlab-docs/-/blob/main/content/_data/redirects.yaml).
+For example, if you add a new page on the 3rd of the month and then rename it before it gets
+added in the stable branch on the 18th, the old page will never be part of the internal `/help`.
+In that case, you can jump straight to the
+[Pages redirect](https://gitlab.com/gitlab-org/gitlab-docs/-/blob/main/doc/maintenance.md#pages-redirects).
+
+To add a redirect:
+
+1. In the repository (`gitlab`, `gitlab-runner`, `omnibus-gitlab`, or `charts`),
+ create a new documentation file. Don't delete the old one. The easiest
+ way is to copy it. For example:
+
+ ```shell
+ cp doc/user/search/old_file.md doc/api/new_file.md
+ ```
+
+1. Add the redirect code to the old documentation file by running the
+ following Rake task. The first argument is the path of the old file,
+ and the second argument is the path of the new file:
+
+ - To redirect to a page in the same project, use relative paths and
+ the `.md` extension. Both old and new paths start from the same location.
+ In the following example, both paths are relative to `doc/`:
+
+ ```shell
+ bundle exec rake "gitlab:docs:redirect[doc/user/search/old_file.md, doc/api/new_file.md]"
+ ```
+
+ - To redirect to a page in a different project or site, use the full URL (with `https://`) :
+
+ ```shell
+ bundle exec rake "gitlab:docs:redirect[doc/user/search/old_file.md, https://example.com]"
+ ```
+
+ Alternatively, you can omit the arguments and be asked to enter their values:
+
+ ```shell
+ bundle exec rake gitlab:docs:redirect
+ ```
+
+ If you don't want to use the Rake task, you can use the following template.
+ However, the file paths must be relative to the `doc` or `docs` directory.
+
+ Replace the value of `redirect_to` with the new file path and `YYYY-MM-DD`
+ with the date the file should be removed.
+
+ Redirect files that link to docs in internal documentation projects
+ are removed after three months. Redirect files that link to external sites are
+ removed after one year:
+
+ ```markdown
+ ---
+ redirect_to: '../newpath/to/file/index.md'
+ remove_date: 'YYYY-MM-DD'
+ ---
+
+ This document was moved to [another location](../path/to/file/index.md).
+
+ <!-- This redirect file can be deleted after <YYYY-MM-DD>. -->
+ <!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
+ ```
+
+1. If the documentation page being moved has any Disqus comments, follow the steps
+ described in [Redirections for pages with Disqus comments](#redirections-for-pages-with-disqus-comments).
+1. Open a merge request with your changes. If a documentation page
+ you're removing includes images that aren't used
+ with any other documentation pages, be sure to use your merge request to delete
+ those images from the repository.
+1. Assign the merge request to a technical writer for review and merge.
+1. Search for links to the old documentation file. You must find and update all
+ links that point to the old documentation file:
+
+ - In <https://gitlab.com/gitlab-com/www-gitlab-com>, search for full URLs:
+ `grep -r "docs.gitlab.com/ee/path/to/file.html" .`
+ - In <https://gitlab.com/gitlab-org/gitlab-docs/-/tree/master/content/_data>,
+ search the navigation bar configuration files for the path with `.html`:
+ `grep -r "path/to/file.html" .`
+ - In any of the four internal projects, search for links in the docs
+ and codebase. Search for all variations, including full URL and just the path.
+ For example, go to the root directory of the `gitlab` project and run:
+
+ ```shell
+ grep -r "docs.gitlab.com/ee/path/to/file.html" .
+ grep -r "path/to/file.html" .
+ grep -r "path/to/file.md" .
+ grep -r "path/to/file" .
+ ```
+
+ You may need to try variations of relative links, such as `../path/to/file` or
+ `../file` to find every case.
+
+## Redirections for pages with Disqus comments
+
+If the documentation page being relocated already has Disqus comments,
+we need to preserve the Disqus thread.
+
+Disqus uses an identifier per page, and for <https://docs.gitlab.com>, the page identifier
+is configured to be the page URL. Therefore, when we change the document location,
+we need to preserve the old URL as the same Disqus identifier.
+
+To do that, add to the front matter the variable `disqus_identifier`,
+using the old URL as value. For example, let's say we moved the document
+available under `https://docs.gitlab.com/my-old-location/README.html` to a new location,
+`https://docs.gitlab.com/my-new-location/index.html`.
+
+Into the **new document** front matter, we add the following information. You must
+include the filename in the `disqus_identifier` URL, even if it's `index.html` or `README.html`.
+
+```yaml
+---
+disqus_identifier: 'https://docs.gitlab.com/my-old-location/README.html'
+---
+```
diff --git a/doc/development/documentation/review_apps.md b/doc/development/documentation/review_apps.md
new file mode 100644
index 00000000000..2b8c412f165
--- /dev/null
+++ b/doc/development/documentation/review_apps.md
@@ -0,0 +1,101 @@
+---
+stage: none
+group: Documentation Guidelines
+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
+description: Learn how documentation review apps work.
+---
+
+# Documentation review apps
+
+If you're a GitLab team member and your merge request contains documentation changes, you can use a review app to preview
+how they would look if they were deployed to the [GitLab Docs site](https://docs.gitlab.com).
+
+Review apps are enabled for the following projects:
+
+- [GitLab](https://gitlab.com/gitlab-org/gitlab)
+- [Omnibus GitLab](https://gitlab.com/gitlab-org/omnibus-gitlab)
+- [GitLab Runner](https://gitlab.com/gitlab-org/gitlab-runner)
+- [GitLab Charts](https://gitlab.com/gitlab-org/charts/gitlab)
+
+Alternatively, check the [`gitlab-docs` development guide](https://gitlab.com/gitlab-org/gitlab-docs/blob/main/README.md#development-when-contributing-to-gitlab-documentation)
+or [the GDK documentation](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/main/doc/howto/gitlab_docs.md)
+to render and preview the documentation locally.
+
+## How to trigger a review app
+
+If a merge request has documentation changes, use the `review-docs-deploy` manual job
+to deploy the documentation review app for your merge request.
+
+![Manual trigger a documentation review app](img/manual_build_docs.png)
+
+The `review-docs-deploy*` job triggers a cross project pipeline and builds the
+docs site with your changes. When the pipeline finishes, the review app URL
+appears in the merge request widget. Use it to navigate to your changes.
+
+You must have the Developer role in the project. Users without the Developer role, such
+as external contributors, cannot run the manual job. In that case, ask someone from
+the GitLab team to run the job.
+
+## Technical aspects
+
+If you want to know the in-depth details, here's what's really happening:
+
+1. You manually run the `review-docs-deploy` job in a merge request.
+1. The job runs the [`scripts/trigger-build`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/scripts/trigger-build)
+ script with the `docs deploy` flag, which triggers the "Triggered from `gitlab-org/gitlab` 'review-docs-deploy' job"
+ pipeline trigger in the `gitlab-org/gitlab-docs` project for the `$DOCS_BRANCH` (defaults to `main`).
+1. The preview URL is shown both at the job output and in the merge request
+ widget. You also get the link to the remote pipeline.
+1. In the `gitlab-org/gitlab-docs` project, the pipeline is created and it
+ [skips the test jobs](https://gitlab.com/gitlab-org/gitlab-docs/blob/8d5d5c750c602a835614b02f9db42ead1c4b2f5e/.gitlab-ci.yml#L50-55)
+ to lower the build time.
+1. Once the docs site is built, the HTML files are uploaded as artifacts.
+1. A specific runner tied only to the docs project, runs the Review App job
+ that downloads the artifacts and uses `rsync` to transfer the files over
+ to a location where NGINX serves them.
+
+The following GitLab features are used among others:
+
+- [Manual jobs](../../ci/jobs/job_control.md#create-a-job-that-must-be-run-manually)
+- [Multi project pipelines](../../ci/pipelines/multi_project_pipelines.md)
+- [Review Apps](../../ci/review_apps/index.md)
+- [Artifacts](../../ci/yaml/index.md#artifacts)
+- [Specific runner](../../ci/runners/runners_scope.md#prevent-a-specific-runner-from-being-enabled-for-other-projects)
+- [Pipelines for merge requests](../../ci/pipelines/merge_request_pipelines.md)
+
+## Troubleshooting review apps
+
+### Review app returns a 404 error
+
+If the review app URL returns a 404 error, either the site is not
+yet deployed, or something went wrong with the remote pipeline. You can:
+
+- Wait a few minutes and it should appear online.
+- Check the manual job's log and verify the URL. If the URL is different, try the
+ one from the job log.
+- Check the status of the remote pipeline from the link in the merge request's job output.
+ If the pipeline failed or got stuck, GitLab team members can ask for help in the `#docs`
+ chat channel. Contributors can ping a technical writer in the merge request.
+
+### Not enough disk space
+
+Sometimes the review app server is full and there is no more disk space. Each review
+app takes about 570MB of disk space.
+
+A cron job to remove review apps older than 20 days runs hourly,
+but the disk space still occasionally fills up. To manually free up more space,
+a GitLab technical writing team member can:
+
+1. Navigate to the [`gitlab-docs` schedules page](https://gitlab.com/gitlab-org/gitlab-docs/-/pipeline_schedules).
+1. Select the play button for the `Remove old review apps from review app server`
+ schedule. By default, this cleans up review apps older than 14 days.
+1. Navigate to the [pipelines page](https://gitlab.com/gitlab-org/gitlab-docs/-/pipelines)
+ and start the manual job called `clean-pages`.
+
+If the job says no review apps were found in that period, edit the `CLEAN_REVIEW_APPS_DAYS`
+variable in the schedule, and repeat the process above. Gradually decrease the variable
+until the free disk space reaches an acceptable amount (for example, 3GB).
+Remember to set it to 14 again when you're done.
+
+There's an issue to [migrate from the DigitalOcean server to GCP buckets](https://gitlab.com/gitlab-org/gitlab-docs/-/issues/735)),
+which should solve the disk space problem.
diff --git a/doc/development/documentation/site_architecture/index.md b/doc/development/documentation/site_architecture/index.md
index 046de5c6d86..cd69154217c 100644
--- a/doc/development/documentation/site_architecture/index.md
+++ b/doc/development/documentation/site_architecture/index.md
@@ -33,7 +33,6 @@ from where content is sourced, the `gitlab-docs` project, and the published outp
D --> E
E -- Build pipeline --> F
F[docs.gitlab.com]
- G[/ce/]
H[/ee/]
I[/runner/]
J[/omnibus/]
@@ -42,7 +41,6 @@ from where content is sourced, the `gitlab-docs` project, and the published outp
F --> I
F --> J
F --> K
- H -- symlink --> G
```
GitLab docs content isn't kept in the `gitlab-docs` repository.
@@ -54,15 +52,6 @@ product, and all together are pulled to generate the docs website:
- [GitLab Runner](https://gitlab.com/gitlab-org/gitlab-runner/-/tree/main/docs)
- [GitLab Chart](https://gitlab.com/charts/gitlab/tree/master/doc)
-NOTE:
-In September 2019, we [moved towards a single codebase](https://gitlab.com/gitlab-org/gitlab/-/issues/2952),
-as such the docs for CE and EE are now identical. For historical reasons and
-in order not to break any existing links throughout the internet, we still
-maintain the CE docs (`https://docs.gitlab.com/ce/`), although it is hidden
-from the website, and is now a symlink to the EE docs. When
-[Support wildcard redirects](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/500) is resolved,
-we can remove this completely.
-
## Assets
To provide an optimized site structure, design, and a search-engine friendly
diff --git a/doc/development/documentation/styleguide/index.md b/doc/development/documentation/styleguide/index.md
index 4e548179b9e..2cbecc91b20 100644
--- a/doc/development/documentation/styleguide/index.md
+++ b/doc/development/documentation/styleguide/index.md
@@ -420,6 +420,11 @@ Some contractions, however, should be avoided:
| Requests to localhost are not allowed. | Requests to localhost aren't allowed. |
| Specified URL cannot be used. | Specified URL can't be used. |
+### Acronyms
+
+If you use an acronym, spell it out on first use on a page. You do not need to spell it out more than once on a page.
+When possible, try to avoid acronyms in headings.
+
## Text
- [Write in Markdown](#markdown).
@@ -438,8 +443,21 @@ Some contractions, however, should be avoided:
- List item 2
```
+### Comments
+
+To embed comments within Markdown, use standard HTML comments that are not rendered
+when published. Example:
+
+```html
+<!-- This is a comment that is not rendered -->
+```
+
### Emphasis
+Use **bold** rather than italic to provide emphasis. GitLab uses a sans-serif font and italic text does not stand out as much as it would in a serif font. For details, see [Butterick's Practical Typography guide on bold or italic](https://practicaltypography.com/bold-or-italic.html).
+
+You can use italics when you are introducing a term for the first time. Otherwise, use bold.
+
- Use double asterisks (`**`) to mark a word or text in bold (`**bold**`).
- Use underscore (`_`) for text in italics (`_italic_`).
- Use greater than (`>`) for blockquotes.
@@ -460,6 +478,7 @@ Follow these guidelines for punctuation:
| Use serial commas (Oxford commas) before the final **and** or **or** in a list of three or more items. (Tested in [`OxfordComma.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/OxfordComma.yml).) | You can create new issues, merge requests, and milestones. |
| Always add a space before and after dashes when using it in a sentence (for replacing a comma, for example). | You should try this - or not. |
| When a colon is part of a sentence, always use lowercase after the colon. | Linked issues: a way to create a relationship between issues. |
+| Do not use typographer's quotes. Use straight quotes instead. (Tested in [`NonStandardQuotes.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/NonStandardQuotes.yml).) | "It's the questions we can't answer that teach us the most"---Patrick Rothfuss |
<!-- vale gitlab.Repetition = YES -->
@@ -751,6 +770,7 @@ Valid for Markdown content only, not for front matter entries:
For other punctuation rules, refer to the
[Pajamas Design System Punctuation section](https://design.gitlab.com/content/punctuation/).
+This is overridden by the [documentation-specific punctuation rules](#punctuation).
## Headings
@@ -1003,9 +1023,23 @@ document to ensure it links to the most recent version of the file.
## Navigation
-When documenting navigation through the user interface, use these terms and styles.
+When documenting how to navigate through the GitLab UI:
+
+- Always use location, then action.
+ - `From the **Visibility** list,` (location) `select **Public**.` (action)
+- Be brief and specific. For example:
+ - Avoid: `Select **Save** for the changes to take effect.`
+ - Use instead: `Select **Save**.`
+- When selecting from high-level UI elements, use the word **on**.
+ - Avoid: `From the left sidebar...` or `In the left sidebar...`
+ - Use instead: `On the left sidebar...`
+- If a step must include a reason, start the step with it.
+ - Avoid: `Select the link in the merge request to view the changes.`
+ - Use instead: `To view the changes, select the link in the merge request.`
+- If a step is optional, start the step with the word `Optional` followed by a period.
+ - `1. Optional. Enter a name for the dog.`
-### What to call the menus
+### Names for menus
Use these terms when referring to the main GitLab user interface
elements:
@@ -1017,9 +1051,14 @@ elements:
- **Right sidebar**: This is the navigation sidebar on the right of the user
interface, specific to the open issue, merge request, or epic.
-### How to document the menus
+### Names for UI elements
-To be consistent, use this format when you write about UI navigation.
+UI elements, like button and checkbox names, should be **bold**.
+Guidance for each individual UI element is in [the word list](word_list.md).
+
+### How to write navigation task steps
+
+To be consistent, use this format when you write navigation steps in a task topic.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > CI/CD**.
@@ -1034,20 +1073,27 @@ Another example:
An Admin Area example:
```markdown
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
```
-This text renders this output:
+To select your avatar:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+```markdown
+1. On the top bar, in the top right corner, select your avatar.
+```
## Images
Images, including screenshots, can help a reader better understand a concept.
-However, they can be hard to maintain, and should be used sparingly.
+However, they should be used sparingly because:
-Before including an image in the documentation, ensure it provides value to the
-reader.
+- They tend to become out-of-date.
+- They are difficult and expensive to localize.
+- They cannot be read by screen readers.
+
+If you do include an image in the documentation, ensure it provides value.
+Don't use `lorem ipsum` text. Try to replicate how the feature would be
+used in a real-world scenario, and [use realistic text](#fake-user-information).
### Capture the image
@@ -1106,7 +1152,7 @@ known tool is [`pngquant`](https://pngquant.org/), which is cross-platform and
open source. Install it by visiting the official website and following the
instructions for your OS.
-GitLab has a [Rake task](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/tasks/pngquant.rake)
+GitLab has a [Ruby script](https://gitlab.com/gitlab-org/gitlab/-/blob/master/bin/pngquant)
that you can use to automate the process. In the root directory of your local
copy of `https://gitlab.com/gitlab-org/gitlab`, run in a terminal:
@@ -1114,19 +1160,26 @@ copy of `https://gitlab.com/gitlab-org/gitlab`, run in a terminal:
been compressed:
```shell
- bundle exec rake pngquant:lint
+ bin/pngquant lint
```
- Compress all documentation PNG images using `pngquant`:
```shell
- bundle exec rake pngquant:compress
+ bin/pngquant compress
+ ```
+
+- Compress specific files:
+
+ ```shell
+ bin/pngquant compress doc/user/img/award_emoji_select.png doc/user/img/markdown_logo.png
```
-The only caveat is that the task runs on all images under `doc/`, not only the
-ones you might have included in a merge request. In that case, you can run the
-compress task and only commit the images that are relevant to your merge
-request.
+- Compress all PNG files in a specific directory:
+
+ ```shell
+ bin/pngquant compress doc/user/img
+ ```
## Videos
@@ -1288,64 +1341,22 @@ For a complete reference on code blocks, see the [Kramdown guide](https://about.
> [Introduced](https://gitlab.com/gitlab-org/gitlab-docs/-/issues/384) in GitLab 12.7.
You can use icons from the [GitLab SVG library](https://gitlab-org.gitlab.io/gitlab-svgs/)
-directly in the documentation.
-
-This way, you can achieve a consistent look when writing about interacting with
-GitLab user interface elements.
-
-Usage examples:
-
-- Icon with default size (16px): `**{icon-name}**`
+directly in the documentation. For example, `**{tanuki}**` renders as: **{tanuki}**.
- Example: `**{tanuki}**` renders as: **{tanuki}**.
-- Icon with custom size: `**{icon-name, size}**`
+In most cases, you should avoid using the icons in text.
+However, you can use an icon when hover text is the only
+available way to describe a UI element. For example, **Delete** or **Edit** buttons
+often have hover text only.
- Available sizes (in pixels): 8, 10, 12, 14, 16, 18, 24, 32, 48, and 72
+When you do use an icon, start with the hover text and follow it with the SVG reference in parentheses.
- Example: `**{tanuki, 24}**` renders as: **{tanuki, 24}**.
-- Icon with custom size and class: `**{icon-name, size, class-name}**`.
+- Avoid: `Select **{pencil}** **Edit**.` This generates as: Select **{pencil}** **Edit**.
+- Use instead: `Select **Edit** (**{pencil}**).` This generates as: Select **Edit** (**{pencil}**).
- You can access any class available to this element in GitLab documentation CSS.
+Do not use words to describe the icon:
- Example with `float-right`, a
- [Bootstrap utility class](https://getbootstrap.com/docs/4.4/utilities/float/):
- `**{tanuki, 32, float-right}**` renders as: **{tanuki, 32, float-right}**
-
-### When to use icons
-
-Icons should be used sparingly, and only in ways that aid and do not hinder the
-readability of the text.
-
-For example, this Markdown adds little to the accompanying text:
-
-```markdown
-1. Go to **{home}** **Project information > Details**.
-```
-
-1. Go to **{home}** **Project information > Details**.
-
-However, these tables might help the reader connect the text to the user
-interface:
-
-```markdown
-| Section | Description |
-|:-------------------------|:----------------------------------------------------------------------------------------------------------------------------|
-| **{overview}** Overview | View your GitLab Dashboard, and administer projects, users, groups, jobs, runners, and Gitaly servers. |
-| **{monitor}** Monitoring | View GitLab system information, and information on background jobs, logs, health checks, requests profiles, and audit events. |
-| **{messages}** Messages | Send and manage broadcast messages for your users. |
-```
-
-| Section | Description |
-|:-------------------------|:----------------------------------------------------------------------------------------------------------------------------|
-| **{overview}** Overview | View your GitLab Dashboard, and administer projects, users, groups, jobs, runners, and Gitaly servers. |
-| **{monitor}** Monitoring | View GitLab system information, and information on background jobs, logs, health checks, requests profiles, and audit events. |
-| **{messages}** Messages | Send and manage broadcast messages for your users. |
-
-Use an icon when you find yourself having to describe an interface element. For
-example:
-
-- Do: Select the Admin Area icon ( **{admin}** ).
-- Don't: Select the Admin Area icon (the wrench icon).
+- Avoid: `Select **Erase job log** (the trash icon).`
+- Use instead: `Select **Erase job log** (**{remove}**).` This generates as: Select **Erase job log** (**{remove}**).
## Alert boxes
@@ -1456,27 +1467,9 @@ Follow these styles when you're describing user interface elements in an
application:
- For elements with a visible label, use that label in bold with matching case.
- For example, `the **Cancel** button`.
+ For example, `Select **Cancel**`.
- For elements with a tooltip or hover label, use that label in bold with
- matching case. For example, `the **Add status emoji** button`.
-
-### Verbs for UI elements
-
-Use these verbs for specific uses with user interface
-elements:
-
-| Recommended | Used for | Replaces |
-|:--------------------|:--------------------------------------|:----------------------|
-| select | buttons, links, menu items, dropdowns | click, press, hit |
-| select or clear | checkboxes | enable, click, press |
-| expand | expandable sections | open |
-| turn on or turn off | toggles | flip, enable, disable |
-
-### Other Verbs
-
-| Recommended | Used for | Replaces |
-|:------------|:--------------------------------|:----------------------|
-| go to | making a browser go to location | navigate to, open |
+ matching case. For example, `Select **Add status emoji**`.
## GitLab versions
@@ -1504,10 +1497,6 @@ tagged and released set of documentation for your installed version:
When a feature is added or updated, you can include its version information
either as a **Version history** item or as an inline text reference.
-Version text shouldn't include information about the tier in which the feature
-is available. This information is provided by the [product badge](#product-tier-badges)
-displayed for the page or feature.
-
#### Version text in the **Version History**
If all content in a section is related, add version text after the header for
@@ -1523,6 +1512,10 @@ the section. The version information must:
- Whenever possible, include a link to the completed issue, merge request, or epic
that introduced the feature. An issue is preferred over a merge request, and
a merge request is preferred over an epic.
+- Do not include information about the tier, unless documenting a tier change
+ (for example, `Feature X [moved](issue-link) to Premium in GitLab 19.2`).
+- Do not link to the pricing page.
+ The tier is provided by the [product badge](#product-tier-badges) on the heading.
```markdown
## Feature name
@@ -1647,37 +1640,24 @@ When names change, it is more complicated to search or grep text that has line b
### Product tier badges
-Tier badges are displayed as orange text next to a heading. For example:
+Tier badges are displayed as orange text next to a heading. These badges link to the GitLab
+pricing page. For example:
![Tier badge](img/tier_badge.png)
You must assign a tier badge:
-- To [all H1 topic headings](#product-tier-badges-on-headings).
+- To all H1 topic headings.
- To topic headings that don't apply to the same tier as the H1.
-- To [sections of a topic](#product-tier-badges-on-other-content),
- if they apply to a tier other than what applies to the H1.
-
-#### Product tier badges on headings
-To add a tier badge to a heading, add the relevant [tier badge](#available-product-tier-badges)
+To add a tier badge to a heading, add the relevant tier badge
after the heading text. For example:
```markdown
# Heading title **(FREE)**
```
-#### Product tier badges on other content
-
-In paragraphs, list names, and table cells, an information icon displays when you
-add a tier badge. More verbose information displays when a user points to the icon:
-
-- `**(FREE)**` displays as **(FREE)**
-- `**(FREE SELF)**` displays as **(FREE SELF)**
-- `**(FREE SAAS)**` displays as **(FREE SAAS)**
-
-The `**(FREE)**` generates a `span` element to trigger the
-badges and tooltips (`<span class="badge-trigger free">`).
+Do not add tier badges inline with other text. The single source of truth for a feature should be the heading where the functionality is described.
#### Available product tier badges
diff --git a/doc/development/documentation/styleguide/word_list.md b/doc/development/documentation/styleguide/word_list.md
index 9e921bb30f0..eafe0e7a1c2 100644
--- a/doc/development/documentation/styleguide/word_list.md
+++ b/doc/development/documentation/styleguide/word_list.md
@@ -17,15 +17,17 @@ For guidance not on this page, we defer to these style guides:
<!-- vale off -->
<!-- markdownlint-disable -->
-## @mention
+## `@mention`
-Try to avoid. Say "mention" instead, and consider linking to the
+Try to avoid **`@mention`**. Say **mention** instead, and consider linking to the
[mentions topic](../../../user/project/issues/issue_data_and_actions.md#mentions).
-Don't use `code formatting`.
+Don't use backticks.
## above
-Try to avoid extra words when referring to an example or table in a documentation page, but if required, use **previously** instead.
+Try to avoid using **above** when referring to an example or table in a documentation page. If required, use **previous** instead. For example:
+
+- In the previous example, the dog had fleas.
## admin, admin area
@@ -33,55 +35,111 @@ Use **administration**, **administrator**, **administer**, or **Admin Area** ins
## allow, enable
-Try to avoid, unless you are talking about security-related features. For example:
+Try to avoid **allow** and **enable**, unless you are talking about security-related features. For example:
-- Avoid: This feature allows you to create a pipeline.
-- Use instead: Use this feature to create a pipeline.
+- Do: Use this feature to create a pipeline.
+- Do not: This feature allows you to create a pipeline.
This phrasing is more active and is from the user perspective, rather than the person who implemented the feature.
[View details in the Microsoft style guide](https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/a/allow-allows).
## Alpha
-Uppercase. For example: **The XYZ feature is in Alpha.** or **This Alpha release is ready to test.**
+Use uppercase for **Alpha**. For example: **The XYZ feature is in Alpha.** or **This Alpha release is ready to test.**
You might also want to link to [this section](https://about.gitlab.com/handbook/product/gitlab-the-product/#alpha-beta-ga)
in the handbook when writing about Alpha features.
## and/or
-Instead of **and/or**, use or or rewrite the sentence to spell out both options.
+Instead of **and/or**, use **or** or rewrite the sentence to spell out both options.
+
+## area
+
+Use [**section**](#section) instead of **area**. The only exception is [the Admin Area](#admin-admin-area).
## below
-Try to avoid extra words when referring to an example or table in a documentation page, but if required, use **following** instead.
+Try to avoid **below** when referring to an example or table in a documentation page. If required, use **following** instead. For example:
+
+- In the following example, the dog has fleas.
## Beta
-Uppercase. For example: **The XYZ feature is in Beta.** or **This Beta release is ready to test.**
+Use uppercase for **Beta**. For example: **The XYZ feature is in Beta.** or **This Beta release is ready to test.**
You might also want to link to [this section](https://about.gitlab.com/handbook/product/gitlab-the-product/#alpha-beta-ga)
in the handbook when writing about Beta features.
## blacklist
-Do not use. Another option is **denylist**. ([Vale](../testing.md#vale) rule: [`InclusionCultural.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/InclusionCultural.yml))
+Do not use **blacklist**. Another option is **denylist**. ([Vale](../testing.md#vale) rule: [`InclusionCultural.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/InclusionCultural.yml))
## board
Use lowercase for **boards**, **issue boards**, and **epic boards**.
+## box
+
+Use **text box** to refer to the UI field. Do not use **field** or **box**. For example:
+
+- In the **Variable name** text box, enter `my text`.
+
+## button
+
+Don't use a descriptor with **button**.
+
+- Do: Select **Run pipelines**.
+- Do not: Select the **Run pipelines** button.
+
+## cannot, can not
+
+Use **cannot** instead of **can not**. You can also use **can't**.
+
+See also [contractions](index.md#contractions).
+
## checkbox
-One word, **checkbox**. Do not use **check box**.
+Use one word for **checkbox**. Do not use **check box**.
+
+You **select** (not **check** or **enable**) and **clear** (not **deselect** or **disable**) checkboxes.
+For example:
+
+- Select the **Protect environment** checkbox.
+- Clear the **Protect environment** checkbox.
+
+If you must refer to the checkbox, you can say it is selected or cleared. For example:
+
+- Ensure the **Protect environment** checkbox is cleared.
+- Ensure the **Protect environment** checkbox is selected.
## CI/CD
-Always uppercase. No need to spell out on first use.
+CI/CD is always uppercase. No need to spell it out on first use.
+
+## click
+
+Do not use **click**. Instead, use **select** with buttons, links, menu items, and lists.
+**Select** applies to more devices, while **click** is more specific to a mouse.
+
+## collapse
+
+Use **collapse** instead of **close** when you are talking about expanding or collapsing a section in the UI.
+
+## confirmation dialog
+
+Use **confirmation dialog** to describe the dialog box that asks you to confirm your action. For example:
+
+- On the confirmation dialog, select **OK**.
## currently
-Do not use when talking about the product or its features. The documentation describes the product as it is today. ([Vale](../testing.md#vale) rule: [`CurrentStatus.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/CurrentStatus.yml))
+Do not use **currently** when talking about the product or its features. The documentation describes the product as it is today.
+([Vale](../testing.md#vale) rule: [`CurrentStatus.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/CurrentStatus.yml))
+
+## deploy board
+
+Use lowercase for **deploy board**.
## Developer
@@ -92,26 +150,35 @@ When writing about the Developer role:
- Do not use the phrase, **if you are a developer** to mean someone who is assigned the Developer
role. Instead, write it out. For example, **if you are assigned the Developer role**.
- To describe a situation where the Developer role is the minimum required:
- - Avoid: **the Developer role or higher**
- - Use instead: **at least the Developer role**
+ - Avoid: the Developer role or higher
+ - Use instead: at least the Developer role
Do not use **Developer permissions**. A user who is assigned the Developer role has a set of associated permissions.
## disable
-See [the Microsoft style guide](https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/d/disable-disabled) for guidance.
+See [the Microsoft style guide](https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/d/disable-disabled) for guidance on **disable**.
Use **inactive** or **off** instead. ([Vale](../testing.md#vale) rule: [`InclusionAbleism.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/InclusionAbleism.yml))
+## dropdown list
+
+Use **dropdown list** to refer to the UI element. Do not use **dropdown** without **list** after it.
+Do not use **drop-down** (hyphenated), **dropdown menu**, or other variants.
+
+For example:
+
+- From the **Visibility** dropdown list, select **Public**.
+
## earlier
-Use when talking about version numbers.
+Use **earlier** when talking about version numbers.
-- Avoid: In GitLab 14.1 and lower.
-- Use instead: In GitLab 14.1 and earlier.
+- Do: In GitLab 14.1 and earlier.
+- Do not: In GitLab 14.1 and lower.
## easily
-Do not use. If the user doesn't find the process to be easy, we lose their trust.
+Do not use **easily**. If the user doesn't find the process to be easy, we lose their trust.
## e.g.
@@ -119,60 +186,75 @@ Do not use Latin abbreviations. Use **for example**, **such as**, **for instance
## email
-Do not use **e-mail** with a hyphen. When plural, use **emails** or **email messages**.
+Do not use **e-mail** with a hyphen. When plural, use **emails** or **email messages**. ([Vale](../testing.md#vale) rule: [`SubstitutionSuggestions.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/SubstitutionSuggestions.yml))
## enable
-See [the Microsoft style guide](https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/e/enable-enables) for guidance.
+See [the Microsoft style guide](https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/e/enable-enables) for guidance on **enable**.
Use **active** or **on** instead. ([Vale](../testing.md#vale) rule: [`InclusionAbleism.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/InclusionAbleism.yml))
+## enter
+
+Use **enter** instead of **type** when talking about putting values into text boxes.
+
## epic
-Lowercase.
+Use lowercase for **epic**.
## epic board
-Lowercase.
+Use lowercase for **epic board**.
## etc.
-Try to avoid. Be as specific as you can. Do not use **and so on** as a replacement.
+Try to avoid **etc.**. Be as specific as you can. Do not use **and so on** as a replacement.
-- Avoid: You can update objects, like merge requests, issues, etc.
-- Use instead: You can update objects, like merge requests and issues.
+- Do: You can update objects, like merge requests and issues.
+- Do not: You can update objects, like merge requests, issues, etc.
+
+## expand
+
+Use **expand** instead of **open** when you are talking about expanding or collapsing a section in the UI.
+
+## field
+
+Use **box** instead of **field** or **text box**.
+
+- Avoid: In the **Variable name** field, enter `my text`.
+- Use instead: In the **Variable name** box, enter `my text`.
## foo
-Do not use in product documentation. You can use it in our API and contributor documentation, but try to use a clearer and more meaningful example instead.
+Do not use **foo** in product documentation. You can use it in our API and contributor documentation, but try to use a clearer and more meaningful example instead.
## future tense
-When possible, use present tense instead. For example, use `after you execute this command, GitLab displays the result` instead of `after you execute this command, GitLab will display the result`. ([Vale](../testing.md#vale) rule: [`FutureTense.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/FutureTense.yml))
+When possible, use present tense instead of future tense. For example, use **after you execute this command, GitLab displays the result** instead of **after you execute this command, GitLab will display the result**. ([Vale](../testing.md#vale) rule: [`FutureTense.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/FutureTense.yml))
## Geo
-Title case.
+Use title case for **Geo**.
## GitLab
-Do not make possessive (GitLab's). This guidance follows [GitLab Trademark Guidelines](https://about.gitlab.com/handbook/marketing/corporate-marketing/brand-activation/trademark-guidelines/).
+Do not make **GitLab** possessive (GitLab's). This guidance follows [GitLab Trademark Guidelines](https://about.gitlab.com/handbook/marketing/corporate-marketing/brand-activation/trademark-guidelines/).
## GitLab.com
-Refers to the GitLab instance managed by GitLab itself.
+**GitLab.com** refers to the GitLab instance managed by GitLab itself.
## GitLab SaaS
-Refers to the product license that provides access to GitLab.com. Does not refer to the
+**GitLab SaaS** refers to the product license that provides access to GitLab.com. It does not refer to the
GitLab instance managed by GitLab itself.
## GitLab Runner
-Title case. This is the product you install. See also [runners](#runner-runners) and [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/233529).
+Use title case for **GitLab Runner**. This is the product you install. See also [runners](#runner-runners) and [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/233529).
## GitLab self-managed
-Refers to the product license for GitLab instances managed by customers themselves.
+Use **GitLab self-managed** to refer to the product license for GitLab instances managed by customers themselves.
## Guest
@@ -183,25 +265,32 @@ When writing about the Guest role:
- Do not use the phrase, **if you are a guest** to mean someone who is assigned the Guest
role. Instead, write it out. For example, **if you are assigned the Guest role**.
- To describe a situation where the Guest role is the minimum required:
- - Avoid: **the Guest role or higher**
- - Use instead: **at least the Guest role**
+ - Avoid: the Guest role or higher
+ - Use instead: at least the Guest role
Do not use **Guest permissions**. A user who is assigned the Guest role has a set of associated permissions.
## handy
-Do not use. If the user doesn't find the feature or process to be handy, we lose their trust.
+Do not use **handy**. If the user doesn't find the feature or process to be handy, we lose their trust. ([Vale](../testing.md#vale) rule: [`Simplicity.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/Simplicity.yml))
## high availability, HA
-Do not use. Instead, direct readers to the GitLab [reference architectures](../../../administration/reference_architectures/index.md) for information about configuring GitLab for handling greater amounts of users.
+Do not use **high availability** or **HA**. Instead, direct readers to the GitLab [reference architectures](../../../administration/reference_architectures/index.md) for information about configuring GitLab for handling greater amounts of users.
## higher
-Do not use when talking about version numbers.
+Do not use **higher** when talking about version numbers.
-- Avoid: In GitLab 14.1 and higher.
-- Use instead: In GitLab 14.1 and later.
+- Do: In GitLab 14.1 and later.
+- Do not: In GitLab 14.1 and higher.
+
+## hit
+
+Don't use **hit** to mean **press**.
+
+- Avoid: Hit the **ENTER** button.
+- Use instead: Press **ENTER**.
## I
@@ -213,19 +302,19 @@ Do not use Latin abbreviations. Use **that is** instead. ([Vale](../testing.md#v
## in order to
-Do not use. Use **to** instead. ([Vale](../testing.md#vale) rule: [`Wordy.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/Wordy.yml))
+Do not use **in order to**. Use **to** instead. ([Vale](../testing.md#vale) rule: [`Wordy.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/Wordy.yml))
## issue
-Lowercase.
+Use lowercase for **issue**.
## issue board
-Lowercase.
+Use lowercase for **issue board**.
## issue weights
-Lowercase.
+Use lowercase for **issue weights**.
## job
@@ -235,21 +324,26 @@ If you want to use **CI** with the word **job**, use **CI/CD job** rather than *
## later
-Use when talking about version numbers.
+Use **later** when talking about version numbers.
- Avoid: In GitLab 14.1 and higher.
- Use instead: In GitLab 14.1 and later.
+## list
+
+Do not use **list** when referring to a [**dropdown list**](#dropdown-list).
+Use the full phrase **dropdown list** instead.
+
## log in, log on
-Do not use. Use [sign in](#sign-in) instead. If the user interface has **Log in**, you can use it.
+Do not use **log in** or **log on**. Use [sign in](#sign-in) instead. If the user interface has **Log in**, you can use it.
## lower
-Do not use when talking about version numbers.
+Do not use **lower** when talking about version numbers.
-- Avoid: In GitLab 14.1 and lower.
-- Use instead: In GitLab 14.1 and earlier.
+- Do: In GitLab 14.1 and earlier.
+- Do not: In GitLab 14.1 and lower.
## Maintainer
@@ -260,22 +354,22 @@ When writing about the Maintainer role:
- Do not use the phrase, **if you are a maintainer** to mean someone who is assigned the Maintainer
role. Instead, write it out. For example, **if you are assigned the Maintainer role**.
- To describe a situation where the Maintainer role is the minimum required:
- - Avoid: **the Maintainer role or higher**
- - Use instead: **at least the Maintainer role**
+ - Avoid: the Maintainer role or higher
+ - Use instead: at least the Maintainer role
Do not use **Maintainer permissions**. A user who is assigned the Maintainer role has a set of associated permissions.
## mankind
-Do not use. Use **people** or **humanity** instead. ([Vale](../testing.md#vale) rule: [`InclusionGender.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/InclusionGender.yml))
+Do not use **mankind**. Use **people** or **humanity** instead. ([Vale](../testing.md#vale) rule: [`InclusionGender.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/InclusionGender.yml))
## manpower
-Do not use. Use words like **workforce** or **GitLab team members**. ([Vale](../testing.md#vale) rule: [`InclusionGender.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/InclusionGender.yml))
+Do not use **manpower**. Use words like **workforce** or **GitLab team members**. ([Vale](../testing.md#vale) rule: [`InclusionGender.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/InclusionGender.yml))
## master
-Do not use. Options are **primary** or **main**. ([Vale](../testing.md#vale) rule: [`InclusionCultural.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/InclusionCultural.yml))
+Do not use **master**. Options are **primary** or **main**. ([Vale](../testing.md#vale) rule: [`InclusionCultural.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/InclusionCultural.yml))
## may, might
@@ -287,18 +381,25 @@ Do not use first-person singular. Use **you**, **we**, or **us** instead. ([Vale
## merge requests
-Lowercase. If you use **MR** as the acronym, spell it out on first use.
+Use lowercase for **merge requests**. If you use **MR** as the acronym, spell it out on first use.
## milestones
-Lowercase.
+Use lowercase for **milestones**.
+
+## navigate
+
+Do not use **navigate**. Use **go** instead. For example:
+
+- Go to this webpage.
+- Open a terminal and go to the `runner` directory.
## need to, should
-Try to avoid. If something is required, use **must**.
+Try to avoid **needs to**, because it's wordy. Avoid **should** when you can be more specific. If something is required, use **must**.
-- Avoid: You need to set the variable.
-- Use instead: You must set the variable. Or: Set the variable.
+- Do: You must set the variable. Or: Set the variable.
+- Do not: You need to set the variable.
**Should** is acceptable for recommended actions or items, or in cases where an event may not
happen. For example:
@@ -310,10 +411,10 @@ happen. For example:
## note that
-Do not use.
+Do not use **note that** because it's wordy.
-- Avoid: Note that you can change the settings.
-- Use instead: You can change the settings.
+- Do: You can change the settings.
+- Do not: Note that you can change the settings.
## Owner
@@ -328,15 +429,21 @@ Do not use **Owner permissions**. A user who is assigned the Owner role has a se
## permissions
-Do not use roles and permissions interchangeably. Each user is assigned a role. Each role includes a set of permissions.
+Do not use **roles** and **permissions** interchangeably. Each user is assigned a role. Each role includes a set of permissions.
## please
-Do not use. For details, see the [Microsoft style guide](https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/p/please).
+Do not use **please**. For details, see the [Microsoft style guide](https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/p/please).
+
+## press
+
+Use **press** when talking about keyboard keys. For example:
+
+- To stop the command, press <kbd>Control</kbd>+<kbd>C</kbd>.
## profanity
-Do not use. Doing so may negatively affect other users and contributors, which is contrary to the GitLab value of [Diversity, Inclusion, and Belonging](https://about.gitlab.com/handbook/values/#diversity-inclusion).
+Do not use profanity. Doing so may negatively affect other users and contributors, which is contrary to the GitLab value of [Diversity, Inclusion, and Belonging](https://about.gitlab.com/handbook/values/#diversity-inclusion).
## Reporter
@@ -347,30 +454,48 @@ When writing about the Reporter role:
- Do not use the phrase, **if you are a reporter** to mean someone who is assigned the Reporter
role. Instead, write it out. For example, **if you are assigned the Reporter role**.
- To describe a situation where the Reporter role is the minimum required:
- - Avoid: **the Reporter role or higher**
- - Use instead: **at least the Reporter role**
+ - Avoid: the Reporter role or higher
+ - Use instead: at least the Reporter role
Do not use **Reporter permissions**. A user who is assigned the Reporter role has a set of associated permissions.
## Repository Mirroring
-Title case.
+Use title case for **Repository Mirroring**.
## roles
-Do not use roles and permissions interchangeably. Each user is assigned a role. Each role includes a set of permissions.
+Do not use **roles** and **permissions** interchangeably. Each user is assigned a role. Each role includes a set of permissions.
## runner, runners
-Lowercase. These are the agents that run CI/CD jobs. See also [GitLab Runner](#gitlab-runner) and [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/233529).
+Use lowercase for **runners**. These are the agents that run CI/CD jobs. See also [GitLab Runner](#gitlab-runner) and [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/233529).
## sanity check
-Do not use. Use **check for completeness** instead. ([Vale](../testing.md#vale) rule: [`InclusionAbleism.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/InclusionAbleism.yml))
+Do not use **sanity check**. Use **check for completeness** instead. ([Vale](../testing.md#vale) rule: [`InclusionAbleism.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/InclusionAbleism.yml))
## scalability
-Do not use when talking about increasing GitLab performance for additional users. The words scale or scaling are sometimes acceptable, but references to increasing GitLab performance for additional users should direct readers to the GitLab [reference architectures](../../../administration/reference_architectures/index.md) page.
+Do not use **scalability** when talking about increasing GitLab performance for additional users. The words scale or scaling
+are sometimes acceptable, but references to increasing GitLab performance for additional users should direct readers
+to the GitLab [reference architectures](../../../administration/reference_architectures/index.md) page.
+
+## section
+
+Use **section** to describe an area on a page. For example, if a page has lines that separate the UI
+into separate areas, refer to these areas as sections.
+
+We often think of expandable/collapsible areas as **sections**. When you refer to expanding
+or collapsing a section, don't include the word **section**.
+
+- Do: Expand **Auto DevOps**.
+- Do not: Expand the **Auto DevOps** section.
+
+## select
+
+Use **select** with buttons, links, menu items, and lists. **Select** applies to more devices,
+while **click** is more specific to a mouse.
## setup, set up
@@ -381,13 +506,13 @@ Use **setup** as a noun, and **set up** as a verb. For example:
## sign in
-Use instead of **sign on** or **log on** or **log in**. If the user interface has different words, use those.
+Use **sign in** instead of **sign on** or **log on** or **log in**. If the user interface has different words, use those.
You can use **single sign-on**.
## simply, simple
-Do not use. If the user doesn't find the process to be simple, we lose their trust.
+Do not use **simply** or **simple**. If the user doesn't find the process to be simple, we lose their trust. ([Vale](../testing.md#vale) rule: [`Simplicity.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/Simplicity.yml))
## slashes
@@ -395,34 +520,38 @@ Instead of **and/or**, use **or** or re-write the sentence. This rule also appli
## slave
-Do not use. Another option is **secondary**. ([Vale](../testing.md#vale) rule: [`InclusionCultural.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/InclusionCultural.yml))
+Do not use **slave**. Another option is **secondary**. ([Vale](../testing.md#vale) rule: [`InclusionCultural.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/InclusionCultural.yml))
## subgroup
-Use instead of **sub-group**.
+Use **subgroup** (no hyphen) instead of **sub-group**. ([Vale](../testing.md#vale) rule: [`SubstitutionSuggestions.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/SubstitutionSuggestions.yml))
## that
-Do not use when describing a noun. For example:
+Do not use **that** when describing a noun. For example:
-- Avoid: The file **that** you save...
-- Use instead: The file you save...
+- Do: The file you save...
+- Do not: The file **that** you save...
See also [this, these, that, those](#this-these-that-those).
## terminal
-Lowercase. For example:
+Use lowercase for **terminal**. For example:
- Open a terminal.
- From a terminal, run the `docker login` command.
+## text box
+
+Use **text box** instead of **field** or **box** when referring to the UI element.
+
## there is, there are
-Try to avoid. These phrases hide the subject.
+Try to avoid **there is** and **there are**. These phrases hide the subject.
-- Avoid: There are holes in the bucket.
-- Use instead: The bucket has holes.
+- Do: The bucket has holes.
+- Do not: There are holes in the bucket.
## they
@@ -434,37 +563,48 @@ a gender-neutral pronoun.
Always follow these words with a noun. For example:
-- Avoid: **This** improves performance.
-- Use instead: **This setting** improves performance.
+- Do: **This setting** improves performance.
+- Do not: **This** improves performance.
-- Avoid: **These** are the best.
-- Use instead: **These pants** are the best.
+- Do: **These pants** are the best.
+- Do not: **These** are the best.
-- Avoid: **That** is the one you are looking for.
-- Use instead: **That Jedi** is the one you are looking for.
+- Do: **That droid** is the one you are looking for.
+- Do not: **That** is the one you are looking for.
-- Avoid: **Those** need to be configured.
-- Use instead: **Those settings** need to be configured. (Or even better, **Configure those settings.**)
+- Do: **Those settings** need to be configured. (Or even better, **Configure those settings.**)
+- Do not: **Those** need to be configured.
## to-do item
-Use lowercase. ([Vale](../testing.md#vale) rule: [`ToDo.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/ToDo.yml))
+Use lowercase and hyphenate **to-do** item. ([Vale](../testing.md#vale) rule: [`ToDo.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/ToDo.yml))
## To-Do List
-Use title case. ([Vale](../testing.md#vale) rule: [`ToDo.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/ToDo.yml))
+Use title case for **To-Do List**. ([Vale](../testing.md#vale) rule: [`ToDo.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/ToDo.yml))
+
+## toggle
+
+You **turn on** or **turn off** a toggle. For example:
+
+- Turn on the **blah** toggle.
+
+## type
+
+Do not use **type** if you can avoid it. Use **enter** instead.
## useful
-Do not use. If the user doesn't find the process to be useful, we lose their trust.
+Do not use **useful**. If the user doesn't find the process to be useful, we lose their trust. ([Vale](../testing.md#vale) rule: [`Simplicity.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/Simplicity.yml))
## utilize
-Do not use. Use **use** instead. It's more succinct and easier for non-native English speakers to understand.
+Do not use **utilize**. Use **use** instead. It's more succinct and easier for non-native English speakers to understand.
+([Vale](../testing.md#vale) rule: [`SubstitutionSuggestions.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/SubstitutionSuggestions.yml))
## Value Stream Analytics
-Title case.
+Use title case for **Value Stream Analytics**.
## via
@@ -474,14 +614,14 @@ Do not use Latin abbreviations. Use **with**, **through**, or **by using** inste
Try to avoid **we** and focus instead on how the user can accomplish something in GitLab.
-- Avoid: We created a feature for you to add widgets.
-- Instead, use: Use widgets when you have work you want to organize.
+- Do: Use widgets when you have work you want to organize.
+- Do not: We created a feature for you to add widgets.
-One exception: You can use **we recommend** instead of **it is recommended** or **GitLab recommends**.
+One exception: You can use **we recommend** instead of **it is recommended** or **GitLab recommends**. ([Vale](../testing.md#vale) rule: [`SubstitutionSuggestions.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/SubstitutionSuggestions.yml))
## whitelist
-Do not use. Another option is **allowlist**. ([Vale](../testing.md#vale) rule: [`InclusionCultural.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/InclusionCultural.yml))
+Do not use **whitelist**. Another option is **allowlist**. ([Vale](../testing.md#vale) rule: [`InclusionCultural.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/InclusionCultural.yml))
<!-- vale on -->
<!-- markdownlint-enable -->
diff --git a/doc/development/documentation/testing.md b/doc/development/documentation/testing.md
index 2ade6c1e71d..dfa2f3ed55a 100644
--- a/doc/development/documentation/testing.md
+++ b/doc/development/documentation/testing.md
@@ -228,7 +228,7 @@ guidelines:
In [`ReadingLevel.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/ReadingLevel.yml),
we have implemented
-[the Flesch-Kincaid grade level test](https://readable.com/blog/the-flesch-reading-ease-and-flesch-kincaid-grade-level/)
+[the Flesch-Kincaid grade level test](https://readable.com/readability/flesch-reading-ease-flesch-kincaid-grade-level/)
to determine the readability of our documentation.
As a general guideline, the lower the score, the more readable the documentation.
@@ -319,6 +319,38 @@ To configure Vale in your editor, install one of the following as appropriate:
cases, `vale` should work. To find the location, run `which vale` in a terminal.
- Vim [ALE plugin](https://github.com/dense-analysis/ale).
+- Emacs [Flycheck extension](https://github.com/flycheck/flycheck).
+ This requires some configuration:
+
+ - `Flycheck` supports `markdownlint-cli` out of the box, but you must point it
+ to the `.markdownlint.yml` at the base of the project directory. A `.dir-locals.el`
+ file can accomplish this:
+
+ ```lisp
+ ;; Place this code in a file called `.dir-locals.el` at the root of the gitlab project.
+ ((markdown-mode . ((flycheck-markdown-markdownlint-cli-config . ".markdownlint.yml"))))
+
+ ```
+
+ - A minimal configuration for Flycheck to work with Vale could look like this:
+
+ ```lisp
+ (flycheck-define-checker vale
+ "A checker for prose"
+ :command ("vale" "--output" "line" "--no-wrap"
+ source)
+ :standard-input nil
+ :error-patterns
+ ((error line-start (file-name) ":" line ":" column ":" (id (one-or-more (not (any ":")))) ":" (message) line-end))
+ :modes (markdown-mode org-mode text-mode)
+ :next-checkers ((t . markdown-markdownlint-cli))
+ )
+
+ (add-to-list 'flycheck-checkers 'vale)
+ ```
+
+ In this setup the `markdownlint` checker is set as a "next" checker from the defined `vale` checker.
+ Enabling this custom Vale checker provides error linting from both Vale and markdownlint.
We don't use [Vale Server](https://errata-ai.github.io/vale/#using-vale-with-a-text-editor-or-another-third-party-application).
diff --git a/doc/development/elasticsearch.md b/doc/development/elasticsearch.md
index 4b87f1c28f1..bba4e1cda23 100644
--- a/doc/development/elasticsearch.md
+++ b/doc/development/elasticsearch.md
@@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
This area is to maintain a compendium of useful information when working with Elasticsearch.
Information on how to enable Elasticsearch and perform the initial indexing is in
-the [Elasticsearch integration documentation](../integration/elasticsearch.md#enabling-advanced-search).
+the [Elasticsearch integration documentation](../integration/elasticsearch.md#enable-advanced-search).
## Deep Dive
@@ -233,6 +233,11 @@ Any data or index cleanup needed to support migration retries should be handled
will re-enqueue itself with a delay which is set using the `throttle_delay` option described below. The batching
must be handled within the `migrate` method, this setting controls the re-enqueuing only.
+- `batch_size` - Sets the number of documents modified during a `batched!` migration run. This size should be set to a value which allows the updates
+ enough time to finish. This can be tuned in combination with the `throttle_delay` option described below. The batching
+ must be handled within a custom `migrate` method or by using the [`Elastic::MigrationBackfillHelper`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/app/workers/concerns/elastic/migration_backfill_helper.rb)
+ `migrate` method which uses this setting. Default value is 1000 documents.
+
- `throttle_delay` - Sets the wait time in between batch runs. This time should be set high enough to allow each migration batch
enough time to finish. Additionally, the time should be less than 30 minutes since that is how often the
[`Elastic::MigrationWorker`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/app/workers/elastic/migration_worker.rb)
diff --git a/doc/development/experiment_guide/experimentation.md b/doc/development/experiment_guide/experimentation.md
index ee0f63342f1..b242646c549 100644
--- a/doc/development/experiment_guide/experimentation.md
+++ b/doc/development/experiment_guide/experimentation.md
@@ -106,7 +106,7 @@ class SomeWorker
# Since we cannot access cookies in a worker, we need to bucket models
# based on a unique, unchanging attribute instead.
- # It is therefore necessery to always provide the same subject.
+ # It is therefore necessary to always provide the same subject.
if Gitlab::Experimentation.in_experiment_group?(:experiment_key, subject: user)
# execute experimental code
else
diff --git a/doc/development/experiment_guide/index.md b/doc/development/experiment_guide/index.md
index e4a97091a81..4de272fec20 100644
--- a/doc/development/experiment_guide/index.md
+++ b/doc/development/experiment_guide/index.md
@@ -8,11 +8,13 @@ info: To determine the technical writer assigned to the Stage/Group associated w
Experiments can be conducted by any GitLab team, most often the teams from the [Growth Sub-department](https://about.gitlab.com/handbook/engineering/development/growth/). Experiments are not tied to releases because they primarily target GitLab.com.
-Experiments are run as an A/B/n test, and are behind a feature flag to turn the test on or off. Based on the data the experiment generates, the team decides if the experiment had a positive impact and should be made the new default, or rolled back.
+Experiments are run as an A/B/n test, and are behind an [experiment feature flag](../feature_flags/#experiment-type) to turn the test on or off. Based on the data the experiment generates, the team decides if the experiment had a positive impact and should be made the new default, or rolled back.
-## Experiment tracking issue
+## Experiment rollout issue
-Each experiment should have an [Experiment tracking](https://gitlab.com/groups/gitlab-org/-/issues?scope=all&state=opened&label_name[]=growth%20experiment&search=%22Experiment+tracking%22) issue to track the experiment from roll-out through to cleanup/removal. The tracking issue is similar to a feature flag rollout issue, and is also used to track the status of an experiment. Immediately after an experiment is deployed, the due date of the issue should be set (this depends on the experiment but can be up to a few weeks in the future).
+Each experiment should have an [experiment rollout](https://gitlab.com/groups/gitlab-org/-/boards/1352542) issue to track the experiment from rollout through to cleanup and removal.
+The rollout issue is similar to a feature flag rollout issue, and is also used to track the status of an experiment.
+When an experiment is deployed, the due date of the issue should be set (this depends on the experiment but can be up to a few weeks in the future).
After the deadline, the issue needs to be resolved and either:
- It was successful and the experiment becomes the new default.
@@ -29,6 +31,10 @@ run) shouldn't impact GitLab availability. To avoid or identify issues,
experiments are initially deployed to a small number of users. Regardless,
experiments still need tests.
+Experiments must have corresponding [frontend or feature tests](../testing_guide/index.md) to ensure they
+exist in the application. These tests should help prevent the experiment code from
+being removed before the [experiment cleanup process](https://about.gitlab.com/handbook/engineering/development/growth/experimentation/#experiment-cleanup-issue) starts.
+
If, as a reviewer or maintainer, you find code that would usually fail review
but is acceptable for now, mention your concerns with a note that there's no
need to change the code. The author can then add a comment to this piece of code
@@ -38,22 +44,14 @@ addressed.
## Implementing an experiment
-There are currently two options when implementing an experiment.
-
-One is built into GitLab directly and has been around for a while (this is called
-`Exerimentation Module`), and the other is provided by
-[`gitlab-experiment`](https://gitlab.com/gitlab-org/gitlab-experiment) and is referred
-to as `Gitlab::Experiment` -- GLEX for short.
+[`GLEX`](https://gitlab.com/gitlab-org/gitlab-experiment) - or `Gitlab::Experiment`, the `gitlab-experiment` gem - is the preferred option for implementing an experiment in GitLab.
-Both approaches use [experiment](../feature_flags/index.md#experiment-type)
-feature flags. We recommend using GLEX rather than `Experimentation Module` for new experiments.
+For more information, see [Implementing an A/B/n experiment using GLEX](gitlab_experiment.md).
-- [Implementing an A/B/n experiment using GLEX](gitlab_experiment.md)
-- [Implementing an A/B experiment using `Experimentation Module`](experimentation.md)
+There are still some longer running experiments using the [`Exerimentation Module`](experimentation.md).
-Historical Context: `Experimentation Module` was built iteratively with the needs that
-appeared while implementing Growth sub-department experiments, while GLEX was built
-with the findings of the team and an easier to use API.
+Both approaches use [experiment](../feature_flags/index.md#experiment-type) feature flags.
+`GLEX` is the preferred option for new experiments.
### Add new icons and illustrations for experiments
diff --git a/doc/development/fe_guide/accessibility.md b/doc/development/fe_guide/accessibility.md
index 0cd7cf58b58..7c870de9a6c 100644
--- a/doc/development/fe_guide/accessibility.md
+++ b/doc/development/fe_guide/accessibility.md
@@ -334,7 +334,7 @@ Keep in mind that:
- When you add `:hover` styles, in most cases you should add `:focus` styles too so that the styling is applied for both mouse **and** keyboard users.
- If you remove an interactive element's `outline`, make sure you maintain visual focus state in another way such as with `box-shadow`.
-See the [Pajamas Keyboard-only page](https://design.gitlab.com/accessibility-audits/2-keyboard-only/) for more detail.
+See the [Pajamas Keyboard-only page](https://design.gitlab.com/accessibility-audits/keyboard-only) for more detail.
## Tabindex
@@ -510,7 +510,7 @@ Proper research and testing should be done to ensure compliance with [WCAG](http
### Viewing the browser accessibility tree
- [Firefox DevTools guide](https://developer.mozilla.org/en-US/docs/Tools/Accessibility_inspector#accessing_the_accessibility_inspector)
-- [Chrome DevTools guide](https://developer.chrome.com/docs/devtools/accessibility/reference#pane)
+- [Chrome DevTools guide](https://developer.chrome.com/docs/devtools/accessibility/reference/#pane)
### Browser extensions
diff --git a/doc/development/fe_guide/axios.md b/doc/development/fe_guide/axios.md
index 2d699b305ce..b42a17d7870 100644
--- a/doc/development/fe_guide/axios.md
+++ b/doc/development/fe_guide/axios.md
@@ -75,7 +75,7 @@ We have also decided against using [Axios interceptors](https://github.com/axios
### Mock poll requests in tests with Axios
-Because polling function requires a header object, we need to always include an object as the third argument:
+Because a polling function requires a header object, we need to always include an object as the third argument:
```javascript
mock.onGet('/users').reply(200, { foo: 'bar' }, {});
diff --git a/doc/development/fe_guide/content_editor.md b/doc/development/fe_guide/content_editor.md
index 6cf4076bf83..956e7d0d56e 100644
--- a/doc/development/fe_guide/content_editor.md
+++ b/doc/development/fe_guide/content_editor.md
@@ -4,10 +4,10 @@ group: Editor
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
---
-# Content Editor **(FREE)**
+# Content Editor development guidelines **(FREE)**
The Content Editor is a UI component that provides a WYSIWYG editing
-experience for [GitLab Flavored Markdown](../../user/markdown.md) (GFM) in the GitLab application.
+experience for [GitLab Flavored Markdown](../../user/markdown.md) in the GitLab application.
It also serves as the foundation for implementing Markdown-focused editors
that target other engines, like static site generators.
@@ -16,103 +16,339 @@ to build the Content Editor. These frameworks provide a level of abstraction on
the native
[`contenteditable`](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Editable_content) web technology.
-## Architecture remarks
+## Usage guide
-At a high level, the Content Editor:
+Follow these instructions to include the Content Editor in a feature.
-- Imports arbitrary Markdown.
-- Renders it in a HTML editing area.
-- Exports it back to Markdown with changes introduced by the user.
+1. [Include the Content Editor component](#include-the-content-editor-component).
+1. [Set and get Markdown](#set-and-get-markdown).
+1. [Listen for changes](#listen-for-changes).
-The Content Editor relies on the
-[Markdown API endpoint](../../api/markdown.md) to transform Markdown
-into HTML. It sends the Markdown input to the REST API and displays the API's
-HTML output in the editing area. The editor exports the content back to Markdown
-using a client-side library that serializes editable documents into Markdown.
+### Include the Content Editor component
-![Content Editor high level diagram](img/content_editor_highlevel_diagram.png)
+Import the `ContentEditor` Vue component. We recommend using asynchronous named imports to
+take advantage of caching, as the ContentEditor is a big dependency.
-Check the [Content Editor technical design document](https://docs.google.com/document/d/1fKOiWpdHned4KOLVOOFYVvX1euEjMP5rTntUhpapdBg)
-for more information about the design decisions that drive the development of the editor.
-
-**NOTE**: We also designed the Content Editor to be extensible. We intend to provide
-more information about extension development for supporting new types of content in upcoming
-milestones.
-
-## GitLab Flavored Markdown support
+```html
+<script>
+export default {
+ components: {
+ ContentEditor: () =>
+ import(
+ /* webpackChunkName: 'content_editor' */ '~/content_editor/components/content_editor.vue'
+ ),
+ },
+ // rest of the component definition
+}
+</script>
+```
-The [GitLab Flavored Markdown](../../user/markdown.md) extends
-the [CommonMark specification](https://spec.commonmark.org/0.29/) with support for a
-variety of content types like diagrams, math expressions, and tables. Supporting
-all GitLab Flavored Markdown content types in the Content Editor is a work in progress. For
-the status of the ongoing development for CommonMark and GitLab Flavored Markdown support, read:
+The Content Editor requires two properties:
-- [Basic Markdown formatting extensions](https://gitlab.com/groups/gitlab-org/-/epics/5404) epic.
-- [GitLab Flavored Markdown extensions](https://gitlab.com/groups/gitlab-org/-/epics/5438) epic.
+- `renderMarkdown` is an asynchronous function that returns the response (String) of invoking the
+[Markdown API](../../api/markdown.md).
+- `uploadsPath` is a URL that points to a [GitLab upload service](../uploads.md#upload-encodings)
+ with `multipart/form-data` support.
-## Usage
+See the [`WikiForm.vue`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue#L207)
+component for a production example of these two properties.
-To include the Content Editor in your feature, import the `createContentEditor` factory
-function and the `ContentEditor` Vue component. `createContentEditor` sets up an instance
-of [tiptap's Editor class](https://www.tiptap.dev/api/editor/) with all the necessary
-extensions to support editing GitLab Flavored Markdown content. It also creates
-a Markdown serializer that allows exporting tiptap's document format to Markdown.
+### Set and get Markdown
-`createContentEditor` requires a `renderMarkdown` parameter invoked
-by the editor every time it needs to convert Markdown to HTML. The Content Editor
-does not provide a default value for this function yet.
+The `ContentEditor` Vue component doesn't implement Vue data binding flow (`v-model`)
+because setting and getting Markdown are expensive operations. Data binding would
+trigger these operations every time the user interacts with the component.
-**NOTE**: The Content Editor is in an early development stage. Usage and development
-guidelines are subject to breaking changes in the upcoming months.
+Instead, you should obtain an instance of the `ContentEditor` class by listening to the
+`initialized` event:
```html
<script>
-import { GlButton } from '@gitlab/ui';
-import { createContentEditor, ContentEditor } from '~/content_editor';
-import { __ } from '~/locale';
import createFlash from '~/flash';
+import { __ } from '~/locale';
export default {
- components: {
- ContentEditor,
- GlButton,
+ methods: {
+ async loadInitialContent(contentEditor) {
+ this.contentEditor = contentEditor;
+
+ try {
+ await this.contentEditor.setSerializedContent(this.content);
+ } catch (e) {
+ createFlash(__('Could not load initial document'));
+ }
+ },
+ submitChanges() {
+ const markdown = this.contentEditor.getSerializedContent();
+ },
},
+};
+</script>
+<template>
+ <content-editor
+ :render-markdown="renderMarkdown"
+ :uploads-path="pageInfo.uploadsPath"
+ @initialized="loadInitialContent"
+ />
+</template>
+```
+
+### Listen for changes
+
+You can still react to changes in the Content Editor. Reacting to changes helps
+you know if the document is empty or dirty. Use the `@change` event handler for
+this purpose.
+
+```html
+<script>
+export default {
data() {
return {
- contentEditor: null,
- }
+ empty: false,
+ };
},
- created() {
- this.contentEditor = createContentEditor({
- renderMarkdown: (markdown) => Api.markdown({ text: markdown }),
- });
-
- try {
- await this.contentEditor.setSerializedContent(this.content);
- } catch (e) {
- createFlash({
- message: __('There was an error loading content in the editor'), error: e
- });
+ methods: {
+ handleContentEditorChange({ empty }) {
+ this.empty = empty;
}
},
+};
+</script>
+<template>
+ <div>
+ <content-editor
+ :render-markdown="renderMarkdown"
+ :uploads-path="pageInfo.uploadsPath"
+ @initialized="loadInitialContent"
+ @change="handleContentEditorChange"
+ />
+ <gl-button :disabled="empty" @click="submitChanges">
+ {{ __('Submit changes') }}
+ </gl-button>
+ </div>
+</template>
+```
+
+## Implementation guide
+
+The Content Editor is composed of three main layers:
+
+- **The editing tools UI**, like the toolbar and the table structure editor. They
+ display the editor's state and mutate it by dispatching commands.
+- **The Tiptap Editor object** manages the editor's state,
+ and exposes business logic as commands executed by the editing tools UI.
+- **The Markdown serializer** transforms a Markdown source string into a ProseMirror
+ document and vice versa.
+
+### Editing tools UI
+
+The editing tools UI are Vue components that display the editor's state and
+dispatch [commands](https://www.tiptap.dev/api/commands/#commands) to mutate it.
+They are located in the `~/content_editor/components` directory. For example,
+the **Bold** toolbar button displays the editor's state by becoming active when
+the user selects bold text. This button also dispatches the `toggleBold` command
+to format text as bold:
+
+```mermaid
+sequenceDiagram
+ participant A as Editing tools UI
+ participant B as Tiptap object
+ A->>B: queries state/dispatches commands
+ B--)A: notifies state changes
+```
+
+#### Node views
+
+We implement [node views](https://www.tiptap.dev/guide/node-views/vue/#node-views-with-vue)
+to provide inline editing tools for some content types, like tables and images. Node views
+allow separating the presentation of a content type from its
+[model](https://prosemirror.net/docs/guide/#doc.data_structures). Using a Vue component in
+the presentation layer enables sophisticated editing experiences in the Content Editor.
+Node views are located in `~/content_editor/components/wrappers`.
+
+#### Dispatch commands
+
+You can inject the Tiptap Editor object to Vue components to dispatch
+commands.
+
+NOTE:
+Do not implement logic that changes the editor's
+state in Vue components. Encapsulate this logic in commands, and dispatch
+the command from the component's methods.
+
+```html
+<script>
+export default {
+ inject: ['tiptapEditor'],
methods: {
- async save() {
- await Api.updateContent({
- content: this.contentEditor.getSerializedContent(),
- });
+ execute() {
+ //Incorrect
+ const { state, view } = this.tiptapEditor.state;
+ const { tr, schema } = state;
+ tr.addMark(state.selection.from, state.selection.to, null, null, schema.mark('bold'));
+
+ // Correct
+ this.tiptapEditor.chain().toggleBold().focus().run();
+ },
+ }
+};
+</script>
+<template>
+```
+
+#### Query editor's state
+
+Use the `EditorStateObserver` renderless component to react to changes in the
+editor's state, such as when the document or the selection changes. You can listen to
+the following events:
+
+- `docUpdate`
+- `selectionUpdate`
+- `transaction`
+- `focus`
+- `blur`
+- `error`.
+
+Learn more about these events in [Tiptap's event guide](https://www.tiptap.dev/api/events/).
+
+```html
+<script>
+// Parts of the code has been hidden for efficiency
+import EditorStateObserver from './editor_state_observer.vue';
+
+export default {
+ components: {
+ EditorStateObserver,
+ },
+ data() {
+ return {
+ error: null,
+ };
+ },
+ methods: {
+ displayError({ message }) {
+ this.error = message;
+ },
+ dismissError() {
+ this.error = null;
},
},
};
</script>
<template>
- <div>
- <content-editor :content-editor="contentEditor" />
- <gl-button @click="save()">Save</gl-button>
- </div>
+ <editor-state-observer @error="displayError">
+ <gl-alert v-if="error" class="gl-mb-6" variant="danger" @dismiss="dismissError">
+ {{ error }}
+ </gl-alert>
+ </editor-state-observer>
</template>
```
-Call `setSerializedContent` to set initial Markdown in the Editor. This method is
-asynchronous because it makes an API request to render the Markdown input.
-`getSerializedContent` returns a Markdown string that represents the serialized
-version of the editable document.
+### The Tiptap editor object
+
+The Tiptap [Editor](https://www.tiptap.dev/api/editor) class manages
+the editor's state and encapsulates all the business logic that powers
+the Content Editor. The Content Editor constructs a new instance of this class and
+provides all the necessary extensions to support
+[GitLab Flavored Markdown](../../user/markdown.md).
+
+#### Implement new extensions
+
+Extensions are the building blocks of the Content Editor. You can learn how to implement
+new ones by reading [Tiptap's guide](https://www.tiptap.dev/guide/custom-extensions).
+We recommend checking the list of built-in [nodes](https://www.tiptap.dev/api/nodes) and
+[marks](https://www.tiptap.dev/api/marks) before implementing a new extension
+from scratch.
+
+Store the Content Editor extensions in the `~/content_editor/extensions` directory.
+When using a Tiptap's built-in extension, wrap it in a ES6 module inside this directory:
+
+```javascript
+export { Bold as default } from '@tiptap/extension-bold';
+```
+
+Use the `extend` method to customize the Extension's behavior:
+
+```javascript
+import { HardBreak } from '@tiptap/extension-hard-break';
+
+export default HardBreak.extend({
+ addKeyboardShortcuts() {
+ return {
+ 'Shift-Enter': () => this.editor.commands.setHardBreak(),
+ };
+ },
+});
+```
+
+#### Register extensions
+
+Register the new extension in `~/content_editor/services/create_content_editor.js`. Import
+the extension module and add it to the `builtInContentEditorExtensions` array:
+
+```javascript
+import Emoji from '../extensions/emoji';
+
+const builtInContentEditorExtensions = [
+ Code,
+ CodeBlockHighlight,
+ Document,
+ Dropcursor,
+ Emoji,
+ // Other extensions
+```
+
+### The Markdown serializer
+
+The Markdown Serializer transforms a Markdown String to a
+[ProseMirror document](https://prosemirror.net/docs/guide/#doc) and vice versa.
+
+#### Deserialization
+
+Deserialization is the process of converting Markdown to a ProseMirror document.
+We take advantage of ProseMirror's
+[HTML parsing and serialization capabilities](https://prosemirror.net/docs/guide/#schema.serialization_and_parsing)
+by first rendering the Markdown as HTML using the [Markdown API endpoint](../../api/markdown.md):
+
+```mermaid
+sequenceDiagram
+ participant A as Content Editor
+ participant E as Tiptap Object
+ participant B as Markdown Serializer
+ participant C as Markdown API
+ participant D as ProseMirror Parser
+ A->>B: deserialize(markdown)
+ B->>C: render(markdown)
+ C-->>B: html
+ B->>D: to document(html)
+ D-->>A: document
+ A->>E: setContent(document)
+```
+
+Deserializers live in the extension modules. Read Tiptap's
+[parseHTML](https://www.tiptap.dev/guide/custom-extensions#parse-html) and
+[addAttributes](https://www.tiptap.dev/guide/custom-extensions#attributes) documentation to
+learn how to implement them. Titap's API is a wrapper around ProseMirror's
+[schema spec API](https://prosemirror.net/docs/ref/#model.SchemaSpec).
+
+#### Serialization
+
+Serialization is the process of converting a ProseMirror document to Markdown. The Content
+Editor uses [`prosemirror-markdown`](https://github.com/ProseMirror/prosemirror-markdown)
+to serialize documents. We recommend reading the
+[MarkdownSerializer](https://github.com/ProseMirror/prosemirror-markdown#class-markdownserializer)
+and [MarkdownSerializerState](https://github.com/ProseMirror/prosemirror-markdown#class-markdownserializerstate)
+classes documentation before implementing a serializer:
+
+```mermaid
+sequenceDiagram
+ participant A as Content Editor
+ participant B as Markdown Serializer
+ participant C as ProseMirror Markdown
+ A->>B: serialize(document)
+ B->>C: serialize(document, serializers)
+ C-->>A: markdown string
+```
+
+`prosemirror-markdown` requires implementing a serializer function for each content type supported
+by the Content Editor. We implement serializers in `~/content_editor/services/markdown_serializer.js`.
diff --git a/doc/development/fe_guide/development_process.md b/doc/development/fe_guide/development_process.md
index b85ed4da442..4e50621add4 100644
--- a/doc/development/fe_guide/development_process.md
+++ b/doc/development/fe_guide/development_process.md
@@ -88,7 +88,7 @@ With the purpose of being [respectful of others' time](https://about.gitlab.com/
GitLab architecture.
1. Add a diagram to the issue and ask a frontend maintainer in the Slack channel `#frontend_maintainers` about it.
- ![Diagram of Issue Boards Architecture](img/boards_diagram.png)
+ ![Diagram of issue boards architecture](img/boards_diagram.png)
1. Don't take more than one week between starting work on a feature and
sharing a Merge Request with a reviewer or a maintainer.
diff --git a/doc/development/fe_guide/graphql.md b/doc/development/fe_guide/graphql.md
index 3b49601f027..0229aa0123a 100644
--- a/doc/development/fe_guide/graphql.md
+++ b/doc/development/fe_guide/graphql.md
@@ -421,14 +421,16 @@ is still validated.
Again, make sure that those overrides are as short-lived as possible by tracking their removal in
the appropriate issue.
-#### Feature flags in queries
+#### Feature-flagged queries
-Sometimes it may be helpful to have an entity in the GraphQL query behind a feature flag.
-One example is working on a feature where the backend has already been merged but the frontend
-has not. In this case, you may consider putting the GraphQL entity behind a feature flag to allow smaller
-merge requests to be created and merged.
+In cases where the backend is complete and the frontend is being implemented behind a feature flag,
+a couple options are available to leverage the feature flag in the GraphQL queries.
-To do this we can use the `@include` directive to exclude an entity if the `if` statement passes.
+##### The `@include` directive
+
+The `@include` (or its opposite, `@skip`) can be used to control whether an entity should be
+included in the query. If the `@include` directive evaluates to `false`, the entity's resolver is
+not hit and the entity is excluded from the response. For example:
```graphql
query getAuthorData($authorNameEnabled: Boolean = false) {
@@ -456,6 +458,34 @@ export default {
};
```
+Note that, even if the directive evaluates to `false`, the guarded entity is sent to the backend and
+matched against the GraphQL schema. So this approach requires that the feature-flagged entity
+exists in the schema, even if the feature flag is disabled. When the feature flag is turned off, it
+is recommended that the resolver returns `null` at the very least.
+
+##### Different versions of a query
+
+There's another approach that involves duplicating the standard query, and it should be avoided. The copy includes the new entities
+while the original remains unchanged. It is up to the production code to trigger the right query
+based on the feature flag's status. For example:
+
+```javascript
+export default {
+ apollo: {
+ user: {
+ query() {
+ return this.glFeatures.authorNameEnabled ? NEW_QUERY : ORIGINAL_QUERY,
+ }
+ }
+ },
+};
+```
+
+This approach is not recommended as it results in bigger merge requests and requires maintaining
+two similar queries for as long as the feature flag exists. This can be used in cases where the new
+GraphQL entities are not yet part of the schema, or if they are feature-flagged at the schema level
+(`new_entity: :feature_flag`).
+
### Manually triggering queries
Queries on a component's `apollo` property are made automatically when the component is created.
@@ -1310,7 +1340,7 @@ describe('when query times out', () => {
expect(getAlert().exists()).toBe(false);
expect(getGraph().exists()).toBe(true);
- /* fails again, alert retuns but data persists */
+ /* fails again, alert returns but data persists */
await advanceApolloTimers();
expect(getAlert().exists()).toBe(true);
expect(getGraph().exists()).toBe(true);
diff --git a/doc/development/fe_guide/img/content_editor_highlevel_diagram.png b/doc/development/fe_guide/img/content_editor_highlevel_diagram.png
deleted file mode 100644
index 73a71cf5843..00000000000
--- a/doc/development/fe_guide/img/content_editor_highlevel_diagram.png
+++ /dev/null
Binary files differ
diff --git a/doc/development/fe_guide/index.md b/doc/development/fe_guide/index.md
index 549fa3261b1..a6b49394733 100644
--- a/doc/development/fe_guide/index.md
+++ b/doc/development/fe_guide/index.md
@@ -22,7 +22,7 @@ Be wary of [the limitations that come with using Hamlit](https://github.com/k0ku
We also use [SCSS](https://sass-lang.com) and plain JavaScript with
modern ECMAScript standards supported through [Babel](https://babeljs.io/) and ES module support through [webpack](https://webpack.js.org/).
-Working with our frontend assets requires Node (v10.13.0 or greater) and Yarn
+Working with our frontend assets requires Node (v12.22.1 or greater) and Yarn
(v1.10.0 or greater). You can find information on how to install these on our
[installation guide](../../install/installation.md#4-node).
diff --git a/doc/development/fe_guide/source_editor.md b/doc/development/fe_guide/source_editor.md
index fc128c0ecb1..2ff0bacfc3a 100644
--- a/doc/development/fe_guide/source_editor.md
+++ b/doc/development/fe_guide/source_editor.md
@@ -15,7 +15,7 @@ GitLab features use it, including:
- [CI Linter](../../ci/lint.md)
- [Snippets](../../user/snippets.md)
- [Web Editor](../../user/project/repository/web_editor.md)
-- [Security Policies](../../user/application_security/threat_monitoring/index.md)
+- [Security Policies](../../user/application_security/policies/index.md)
## How to use Source Editor
diff --git a/doc/development/github_importer.md b/doc/development/github_importer.md
index 84c10e0c005..57cb74a6159 100644
--- a/doc/development/github_importer.md
+++ b/doc/development/github_importer.md
@@ -272,3 +272,16 @@ The last log entry reports the number of objects fetched and imported:
"import_stage": "Gitlab::GithubImport::Stage::FinishImportWorker"
}
```
+
+## Errors when importing large projects
+
+The GitHub importer may encounter errors when importing large projects. For help with this, see the
+documentation for the following use cases:
+
+- [Alternative way to import notes and diff notes](../user/project/import/github.md#alternative-way-to-import-notes-and-diff-notes)
+- [Reduce GitHub API request objects per page](../user/project/import/github.md#reduce-github-api-request-objects-per-page)
+
+## Metrics dashboards
+
+To assess the GitHub importer health, the [GitHub importer dashboard](https://dashboards.gitlab.net/d/importers-github-importer/importers-github-importer)
+provides information about the total number of objects fetched vs. imported over time.
diff --git a/doc/development/go_guide/dependencies.md b/doc/development/go_guide/dependencies.md
index c5af21d0772..8aa8f286edc 100644
--- a/doc/development/go_guide/dependencies.md
+++ b/doc/development/go_guide/dependencies.md
@@ -45,7 +45,7 @@ end with a timestamp and the first 12 characters of the commit identifier:
If a VCS tag matches one of these patterns, it is ignored.
For a complete understanding of Go modules and versioning, see [this series of
-blog posts](https://blog.golang.org/using-go-modules) on the official Go
+blog posts](https://go.dev/blog/using-go-modules) on the official Go
website.
## 'Module' vs 'Package'
diff --git a/doc/development/go_guide/index.md b/doc/development/go_guide/index.md
index 224d8a0a0f5..0ee73da48db 100644
--- a/doc/development/go_guide/index.md
+++ b/doc/development/go_guide/index.md
@@ -65,7 +65,7 @@ Remember to run
[SAST](../../user/application_security/sast/index.md) and [Dependency Scanning](../../user/application_security/dependency_scanning/index.md)
**(ULTIMATE)** on your project (or at least the
[`gosec` analyzer](https://gitlab.com/gitlab-org/security-products/analyzers/gosec)),
-and to follow our [Security requirements](../code_review.md#security-requirements).
+and to follow our [Security requirements](../code_review.md#security).
Web servers can take advantages of middlewares like [Secure](https://github.com/unrolled/secure).
@@ -196,7 +196,7 @@ library or framework:
### Subtests
-Use [subtests](https://blog.golang.org/subtests) whenever possible to improve
+Use [subtests](https://go.dev/blog/subtests) whenever possible to improve
code readability and test output.
### Better output in tests
@@ -319,7 +319,7 @@ A few things to keep in mind when adding context:
### References for working with errors
-- [Go 1.13 errors](https://blog.golang.org/go1.13-errors).
+- [Go 1.13 errors](https://go.dev/blog/go1.13-errors).
- [Programing with
errors](https://peter.bourgon.org/blog/2019/09/11/programming-with-errors.html).
- [Don't just check errors, handle them
diff --git a/doc/development/gotchas.md b/doc/development/gotchas.md
index 40598eaff95..fbb6b0219aa 100644
--- a/doc/development/gotchas.md
+++ b/doc/development/gotchas.md
@@ -203,76 +203,6 @@ in an initializer.
- Stack Overflow: [Why you should not write inline JavaScript](https://softwareengineering.stackexchange.com/questions/86589/why-should-i-avoid-inline-scripting)
-## Auto loading
-
-Rails auto-loading on `development` differs from the load policy in the `production` environment.
-In development mode, `config.eager_load` is set to `false`, which means classes
-are loaded as needed. With the classic Rails autoloader, it is known that this can lead to
-[Rails resolving the wrong class](https://guides.rubyonrails.org/v5.2/autoloading_and_reloading_constants.html#when-constants-aren-t-missed-relative-references)
-if the class name is ambiguous. This can be fixed by specifying the complete namespace to the class.
-
-### Error prone example
-
-```ruby
-# app/controllers/application_controller.rb
-class ApplicationController < ActionController::Base
- ...
-end
-
-# app/controllers/projects/application_controller.rb
-class Projects::ApplicationController < ApplicationController
- ...
- private
-
- def project
- ...
- end
-end
-
-# app/controllers/projects/submodule/some_controller.rb
-module Projects
- module Submodule
- class SomeController < ApplicationController
- def index
- @some_id = project.id
- end
- end
- end
-end
-```
-
-In this case, if for any reason the top level `ApplicationController`
-is loaded but `Projects::ApplicationController` is not, `ApplicationController`
-would be resolved to `::ApplicationController` and then the `project` method is
-undefined, causing an error.
-
-#### Solution
-
-```ruby
-# app/controllers/projects/submodule/some_controller.rb
-module Projects
- module Submodule
- class SomeController < Projects::ApplicationController
- def index
- @some_id = project.id
- end
- end
- end
-end
-```
-
-By specifying `Projects::`, we tell Rails exactly what class we are referring
-to and we would avoid the issue.
-
-NOTE:
-This problem disappears as soon as we upgrade to Rails 6 and use the Zeitwerk autoloader.
-
-### Further reading
-
-- Rails Guides: [Autoloading and Reloading Constants (Classic Mode)](https://guides.rubyonrails.org/autoloading_and_reloading_constants_classic_mode.html)
-- Ruby Constant lookup: [Everything you ever wanted to know about constant lookup in Ruby](https://cirw.in/blog/constant-lookup)
-- Rails 6 and Zeitwerk autoloader: [Understanding Zeitwerk in Rails 6](https://medium.com/cedarcode/understanding-zeitwerk-in-rails-6-f168a9f09a1f)
-
## Storing assets that do not require pre-compiling
Assets that need to be served to the user are stored under the `app/assets` directory, which is later pre-compiled and placed in the `public/` directory.
diff --git a/doc/development/graphql_guide/graphql_pro.md b/doc/development/graphql_guide/graphql_pro.md
index ca20d66dd87..3170f0cfdc2 100644
--- a/doc/development/graphql_guide/graphql_pro.md
+++ b/doc/development/graphql_guide/graphql_pro.md
@@ -1,6 +1,6 @@
---
-stage: Plan
-group: Project Management
+stage: Ecosystem
+group: Integrations
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
---
diff --git a/doc/development/graphql_guide/index.md b/doc/development/graphql_guide/index.md
index b8d4b53992e..cc97e41df05 100644
--- a/doc/development/graphql_guide/index.md
+++ b/doc/development/graphql_guide/index.md
@@ -1,6 +1,6 @@
---
-stage: Plan
-group: Project Management
+stage: Ecosystem
+group: Integrations
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
---
diff --git a/doc/development/graphql_guide/pagination.md b/doc/development/graphql_guide/pagination.md
index 5fd2179ea9b..a37c47f1b11 100644
--- a/doc/development/graphql_guide/pagination.md
+++ b/doc/development/graphql_guide/pagination.md
@@ -1,6 +1,6 @@
---
-stage: Plan
-group: Project Management
+stage: Ecosystem
+group: Integrations
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
---
diff --git a/doc/development/i18n/externalization.md b/doc/development/i18n/externalization.md
index 53825f0904a..52a7f839286 100644
--- a/doc/development/i18n/externalization.md
+++ b/doc/development/i18n/externalization.md
@@ -137,7 +137,7 @@ The `~/locale` module exports the following key functions for externalization:
- `s__()` (namespaced double underscore parenthesis)
- `__()` Mark content for translation (note the double underscore).
- `s__()` Mark namespaced content for translation
-- `n__()` Mark pluralized content for translation
+- `n__()` Mark pluralized content for translation
```javascript
import { __, s__, n__ } from '~/locale';
@@ -171,6 +171,45 @@ If you need to translate strings in the Vue component's JavaScript, you can impo
To test Vue translations, learn about [manually testing translations from the UI](#manually-test-translations-from-the-ui).
+### Test files
+
+Test expectations against externalized contents should not be hard coded,
+because we may need to run the tests with non-default locale, and tests with
+hard coded contents will fail.
+
+This means any expectations against externalized contents should call the
+same externalizing method to match the translation.
+
+Bad:
+
+```ruby
+click_button 'Submit review'
+
+expect(rendered).to have_content('Thank you for your feedback!')
+```
+
+Good:
+
+```ruby
+click_button _('Submit review')
+
+expect(rendered).to have_content(_('Thank you for your feedback!'))
+```
+
+This includes JavaScript tests:
+
+Bad:
+
+```javascript
+expect(findUpdateIgnoreStatusButton().text()).toBe('Ignore');
+```
+
+Good:
+
+```javascript
+expect(findUpdateIgnoreStatusButton().text()).toBe(__('Ignore'));
+```
+
#### Recommendations
If strings are reused throughout a component, it can be useful to define these strings as variables. We recommend defining an `i18n` property on the component's `$options` object. If there is a mixture of many-use and single-use strings in the component, consider using this approach to create a local [Single Source of Truth](https://about.gitlab.com/handbook/values/#single-source-of-truth) for externalized strings.
@@ -751,6 +790,28 @@ translate correctly if you extract individual words from the sentence.
When in doubt, try to follow the best practices described in this [Mozilla Developer documentation](https://developer.mozilla.org/en-US/docs/Mozilla/Localization/Localization_content_best_practices#Splitting).
+### Always pass string literals to the translation helpers
+
+The `bin/rake gettext:regenerate` script parses the codebase and extracts all the strings from the
+[translation helpers](#preparing-a-page-for-translation) ready to be translated.
+
+The script cannot resolve the strings if they are passed as variables or function calls. Therefore,
+make sure to always pass string literals to the helpers.
+
+```javascript
+// Good
+__('Some label');
+s__('Namespace', 'Label');
+s__('Namespace|Label');
+n__('%d apple', '%d apples', appleCount);
+
+// Bad
+__(LABEL);
+s__(getLabel());
+s__(NAMESPACE, LABEL);
+n__(LABEL_SINGULAR, LABEL_PLURAL, appleCount);
+```
+
## Updating the PO files with the new content
Now that the new content is marked for translation, run this command to update the
diff --git a/doc/development/i18n/proofreader.md b/doc/development/i18n/proofreader.md
index 462c3fde7d6..76ab00eebfb 100644
--- a/doc/development/i18n/proofreader.md
+++ b/doc/development/i18n/proofreader.md
@@ -43,6 +43,7 @@ are very appreciative of the work done by translators and proofreaders!
- Jan Urbanec - [GitLab](https://gitlab.com/TatranskyMedved), [Crowdin](https://crowdin.com/profile/Tatranskymedved)
- Danish
- Saederup92 - [GitLab](https://gitlab.com/Saederup92), [Crowdin](https://crowdin.com/profile/Saederup92)
+ - scootergrisen - [GitLab](https://gitlab.com/scootergrisen), [Crowdin](https://crowdin.com/profile/scootergrisen)
- Dutch
- Emily Hendle - [GitLab](https://gitlab.com/pundachan), [Crowdin](https://crowdin.com/profile/pandachan)
- Esperanto
@@ -98,7 +99,8 @@ are very appreciative of the work done by translators and proofreaders!
- André Gama - [GitLab](https://gitlab.com/andregamma), [Crowdin](https://crowdin.com/profile/ToeOficial)
- Eduardo Addad de Oliveira - [GitLab](https://gitlab.com/eduardoaddad), [Crowdin](https://crowdin.com/profile/eduardoaddad)
- Romanian
- - Proofreaders needed.
+ - Mircea Pop - [GitLab](https://gitlab.com/eeex), [Crowdin](https://crowdin.com/profile/eex)
+ - Rareș Pița - [GitLab](https://gitlab.com/dlphin), [Crowdin](https://crowdin.com/profile/dlphin)
- Russian
- Nikita Grylov - [GitLab](https://gitlab.com/nixel2007), [Crowdin](https://crowdin.com/profile/nixel2007)
- Alexy Lustin - [GitLab](https://gitlab.com/allustin), [Crowdin](https://crowdin.com/profile/lustin)
@@ -117,6 +119,7 @@ are very appreciative of the work done by translators and proofreaders!
- Turkish
- Ali DemirtaÅŸ - [GitLab](https://gitlab.com/alidemirtas), [Crowdin](https://crowdin.com/profile/alidemirtas)
- Rıfat Ünalmış (Rifat Unalmis) - [GitLab](https://gitlab.com/runalmis), [Crowdin](https://crowdin.com/profile/runalmis)
+ - İsmail Arılık - [GitLab](https://gitlab.com/ismailarilik), [Crowdin](https://crowdin.com/profile/ismailarilik)
- Ukrainian
- Volodymyr Sobotovych - [GitLab](https://gitlab.com/wheleph), [Crowdin](https://crowdin.com/profile/wheleph)
- Andrew Vityuk - [GitLab](https://gitlab.com/3_1_3_u), [Crowdin](https://crowdin.com/profile/andruwa13)
diff --git a/doc/development/img/elasticsearch_architecture.svg b/doc/development/img/elasticsearch_architecture.svg
index 2f38f9b04ee..516214c8b8e 100644
--- a/doc/development/img/elasticsearch_architecture.svg
+++ b/doc/development/img/elasticsearch_architecture.svg
@@ -1 +1 @@
-<svg version="1.2" width="210mm" height="297mm" viewBox="0 0 21000 29700" preserveAspectRatio="xMidYMid" fill-rule="evenodd" stroke-width="28.222" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><defs class="ClipPathGroup"><clipPath id="a" clipPathUnits="userSpaceOnUse"><path d="M0 0h21000v29700H0z"/></clipPath></defs><g class="SlideGroup"><g class="Slide" clip-path="url(#a)"><g class="Page"><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M1975 5575h3051v1651H1975z"/><path fill="#FFF" d="M3500 7200H2000V5600h3000v1600H3500z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M3500 7200H2000V5600h3000v1600H3500z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="2778" y="6311"><tspan>Snippet</tspan></tspan><tspan class="TextPosition" x="2099" y="6785"><tspan>(ActiveRecord)</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M1475 3975h4051v3551H1475z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M3500 7500H1500V4000h4000v3500H3500z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="1788" y="5048"><tspan>ApplicationSearch</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.ConnectorShape"><path class="BoundingBox" fill="none" d="M5975 4675h8051v701H5975z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M6000 5350h4000v-650h4000"/></g><g class="com.sun.star.drawing.ConnectorShape"><path class="BoundingBox" fill="none" d="M5975 5325h8051v1101H5975z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M6000 5350h4000v1050h4000"/></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M1075 2875h4951v4951H1075z"/><path fill="none" stroke="#F33" stroke-width="50" d="M3550 7800H1100V2900h4900v4900H3550z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="700"><tspan class="TextPosition" x="1946" y="3514"><tspan fill="#C9211E">SnippetsSearch</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M1975 12175h3051v1651H1975z"/><path fill="#FFF" d="M3500 13800H2000v-1600h3000v1600H3500z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M3500 13800H2000v-1600h3000v1600H3500z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="2778" y="12911"><tspan>Snippet</tspan></tspan><tspan class="TextPosition" x="2099" y="13385"><tspan>(ActiveRecord)</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M1075 10775h4951v3251H1075z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M3550 14000H1100v-3200h4900v3200H3550z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="2511" y="11461"><tspan>Application</tspan></tspan><tspan class="TextPosition" x="1933" y="11935"><tspan>VersionedSearch</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.ConnectorShape"><path class="BoundingBox" fill="none" d="M3525 13975h4501v7451H3525z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M3550 14000v7400h4450"/></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M14008 14075h4985v851h-4985z"/><path fill="none" stroke="#999" stroke-width="50" d="M16500 14900h-2467v-800h4934v800h-2467z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="14720" y="14648"><tspan fill="gray">ClassMethodProxy</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M13375 13075h6251v2151h-6251z"/><path fill="none" stroke="#F33" stroke-width="50" d="M16500 15200h-3100v-2100h6200v2100h-3100z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="700"><tspan class="TextPosition" x="13799" y="13731"><tspan fill="#C9211E">V12p1::SnippetClassProxy</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M7975 14575h3051v1851H7975z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M9500 16400H8000v-1800h3000v1800H9500z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="8277" y="15411"><tspan>MultiVersion-</tspan></tspan><tspan class="TextPosition" x="8429" y="15885"><tspan>ClassProxy</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M14008 16875h4985v851h-4985z"/><path fill="none" stroke="#999" stroke-width="50" d="M16500 17700h-2467v-800h4934v800h-2467z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="14720" y="17448"><tspan fill="gray">ClassMethodProxy</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M13375 15875h6251v2151h-6251z"/><path fill="none" stroke="#F33" stroke-width="50" d="M16500 18000h-3100v-2100h6200v2100h-3100z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="700"><tspan class="TextPosition" x="13799" y="16531"><tspan fill="#C9211E">V12p2::SnippetClassProxy</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.ConnectorShape"><path class="BoundingBox" fill="none" d="M10975 14125h2451v1401h-2451z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M11000 15500h1463v-1350h937"/></g><g class="com.sun.star.drawing.ConnectorShape"><path class="BoundingBox" fill="none" d="M10975 15475h2451v1501h-2451z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M11000 15500h1463v1450h937"/></g><g class="com.sun.star.drawing.ConnectorShape"><path class="BoundingBox" fill="none" d="M3525 13975h4501v1551H3525z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M3550 14000v1500h4450"/></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M14008 19975h4985v851h-4985z"/><path fill="none" stroke="#999" stroke-width="50" d="M16500 20800h-2467v-800h4934v800h-2467z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="14445" y="20548"><tspan fill="gray">InstanceMethodProxy</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M13375 18975h6251v2151h-6251z"/><path fill="none" stroke="#F33" stroke-width="50" d="M16500 21100h-3100v-2100h6200v2100h-3100z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="700"><tspan class="TextPosition" x="13505" y="19631"><tspan fill="#C9211E">V12p1::SnippetInstanceProxy</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M7975 20275h3051v2251H7975z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M9500 22500H8000v-2200h3000v2200H9500z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="8277" y="21311"><tspan>MultiVersion-</tspan></tspan><tspan class="TextPosition" x="8154" y="21785"><tspan>InstanceProxy</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M14008 22775h4985v851h-4985z"/><path fill="none" stroke="#999" stroke-width="50" d="M16500 23600h-2467v-800h4934v800h-2467z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="14445" y="23348"><tspan fill="gray">InstanceMethodProxy</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M13375 21775h6251v2151h-6251z"/><path fill="none" stroke="#F33" stroke-width="50" d="M16500 23900h-3100v-2100h6200v2100h-3100z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="700"><tspan class="TextPosition" x="13505" y="22431"><tspan fill="#C9211E">V12p2::SnippetInstanceProxy</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.ConnectorShape"><path class="BoundingBox" fill="none" d="M10975 20025h2451v1401h-2451z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M11000 21400h1463v-1350h937"/></g><g class="com.sun.star.drawing.ConnectorShape"><path class="BoundingBox" fill="none" d="M10975 21375h2451v1501h-2451z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M11000 21400h1463v1450h937"/></g><g class="com.sun.star.drawing.TextShape"><path class="BoundingBox" fill="none" d="M900 1600h10697v879H900z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="564" font-weight="400"><tspan class="TextPosition" x="1150" y="2233"><tspan>Standard elasticsearch-rails setup</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.TextShape"><path class="BoundingBox" fill="none" d="M900 9300h7683v879H900z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="564" font-weight="400"><tspan class="TextPosition" x="1150" y="9933"><tspan>GitLab multi-indices setup</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.TextShape"><path class="BoundingBox" fill="none" d="M3400 21300h4821v1197H3400z"/><text class="TextShape"><tspan class="TextParagraph" font-size="388" font-weight="400"><tspan class="TextPosition" x="4250" y="21840"><tspan fill="gray">(instance method)</tspan></tspan><tspan class="TextPosition" x="3651" y="22264"><tspan font-family="Courier" font-size="423">__elasticsearch__</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.TextShape"><path class="BoundingBox" fill="none" d="M3380 15400h4821v1197H3380z"/><text class="TextShape"><tspan class="TextParagraph" font-size="388" font-weight="400"><tspan class="TextPosition" x="4512" y="15940"><tspan fill="gray">(class method)</tspan></tspan><tspan class="TextPosition" x="3631" y="16364"><tspan font-family="Courier" font-size="423">__elasticsearch__</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.TextShape"><path class="BoundingBox" fill="none" d="M9000 3500h4821v1197H9000z"/><text class="TextShape"><tspan class="TextParagraph" font-size="388" font-weight="400"><tspan class="TextPosition" x="10132" y="4040"><tspan fill="gray">(class method)</tspan></tspan><tspan class="TextPosition" x="9251" y="4464"><tspan font-family="Courier" font-size="423">__elasticsearch__</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.TextShape"><path class="BoundingBox" fill="none" d="M9000 6400h4821v1197H9000z"/><text class="TextShape"><tspan class="TextParagraph" font-size="388" font-weight="400"><tspan class="TextPosition" x="9850" y="6940"><tspan fill="gray">(instance method)</tspan></tspan><tspan class="TextPosition" x="9251" y="7364"><tspan font-family="Courier" font-size="423">__elasticsearch__</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M1975 25175h2051v851H1975z"/><path fill="none" stroke="#999" stroke-width="50" d="M3000 26000H2000v-800h2000v800H3000z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="2634" y="25748"><tspan fill="gray">Foo</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.TextShape"><path class="BoundingBox" fill="none" d="M4400 25200h7101v726H4400z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="4650" y="25710"><tspan>elasticsearch-rails’ internal class</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.TextShape"><path class="BoundingBox" fill="none" d="M4400 26400h8601v1200H4400z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="4650" y="26910"><tspan>where model-specific logic is</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M1975 26275h2051v851H1975z"/><path fill="none" stroke="#F33" stroke-width="50" d="M3000 27100H2000v-800h2000v800H3000z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="700"><tspan class="TextPosition" x="2613" y="26848"><tspan fill="#C9211E">Foo</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.TextShape"><path class="BoundingBox" fill="none" d="M4900 17289h5901v2312H4900z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="370" font-weight="400"><tspan class="TextPosition" x="7236" y="17748"><tspan fill="gray">Write operations like </tspan></tspan><tspan class="TextPosition" x="5323" y="18159"><tspan fill="gray">indexing/updating are forwarded </tspan></tspan><tspan class="TextPosition" x="8024" y="18570"><tspan fill="gray">to all instances.</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="370" font-weight="400"><tspan class="TextPosition" x="5501" y="18981"><tspan fill="gray">Read operations are forwarded </tspan></tspan><tspan class="TextPosition" x="7126" y="19392"><tspan fill="gray">to specified instance.</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.ConnectorShape"><path class="BoundingBox" fill="none" d="M10785 15769h1422v2691h-1422z"/><path fill="none" stroke="#999" stroke-width="30" d="M10800 18444c1429 0 934-1618 1119-2337"/><path fill="#999" d="M12206 15769l-460 293 267 217 193-510z"/></g><g class="com.sun.star.drawing.ConnectorShape"><path class="BoundingBox" fill="none" d="M10785 18429h1528v2862h-1528z"/><path fill="none" stroke="#999" stroke-width="30" d="M10800 18444c1509 0 970 1782 1200 2526"/><path fill="#999" d="M12312 21290l-227-496-252 235 479 261z"/></g><g class="com.sun.star.drawing.TextShape"><path class="BoundingBox" fill="none" d="M1800 24000h7101v807H1800z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="494" font-weight="700"><tspan class="TextPosition" x="2050" y="24574"><tspan>Legend</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M13975 4275h5085v851h-5085z"/><path fill="none" stroke="#999" stroke-width="50" d="M16517 5100h-2517v-800h5034v800h-2517z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="14737" y="4848"><tspan fill="gray">ClassMethodProxy</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M13975 5975h5085v851h-5085z"/><path fill="none" stroke="#999" stroke-width="50" d="M16517 6800h-2517v-800h5034v800h-2517z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="14462" y="6548"><tspan fill="gray">InstanceMethodProxy</tspan></tspan></tspan></text></g></g></g></g></svg> \ No newline at end of file
+<svg version="1.2" width="210mm" height="297mm" viewBox="0 0 21000 29700" preserveAspectRatio="xMidYMid" fill-rule="evenodd" stroke-width="28.222" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><defs class="ClipPathGroup"><clipPath id="a" clipPathUnits="userSpaceOnUse"><path d="M0 0h21000v29700H0z"/></clipPath></defs><g class="SlideGroup"><g class="Slide" clip-path="url(#a)"><g class="Page"><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M1975 5575h3051v1651H1975z"/><path fill="#FFF" d="M3500 7200H2000V5600h3000v1600H3500z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M3500 7200H2000V5600h3000v1600H3500z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="2778" y="6311"><tspan>Snippet</tspan></tspan><tspan class="TextPosition" x="2099" y="6785"><tspan>(ActiveRecord)</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M1475 3975h4051v3551H1475z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M3500 7500H1500V4000h4000v3500H3500z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="1788" y="5048"><tspan>ApplicationSearch</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.ConnectorShape"><path class="BoundingBox" fill="none" d="M5975 4675h8051v701H5975z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M6000 5350h4000v-650h4000"/></g><g class="com.sun.star.drawing.ConnectorShape"><path class="BoundingBox" fill="none" d="M5975 5325h8051v1101H5975z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M6000 5350h4000v1050h4000"/></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M1075 2875h4951v4951H1075z"/><path fill="none" stroke="#F33" stroke-width="50" d="M3550 7800H1100V2900h4900v4900H3550z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="700"><tspan class="TextPosition" x="1946" y="3514"><tspan fill="#C9211E">SnippetsSearch</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M1975 12175h3051v1651H1975z"/><path fill="#FFF" d="M3500 13800H2000v-1600h3000v1600H3500z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M3500 13800H2000v-1600h3000v1600H3500z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="2778" y="12911"><tspan>Snippet</tspan></tspan><tspan class="TextPosition" x="2099" y="13385"><tspan>(ActiveRecord)</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M1075 10775h4951v3251H1075z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M3550 14000H1100v-3200h4900v3200H3550z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="2511" y="11461"><tspan>Application</tspan></tspan><tspan class="TextPosition" x="1933" y="11935"><tspan>VersionedSearch</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.ConnectorShape"><path class="BoundingBox" fill="none" d="M3525 13975h4501v7451H3525z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M3550 14000v7400h4450"/></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M14008 14075h4985v851h-4985z"/><path fill="none" stroke="#999" stroke-width="50" d="M16500 14900h-2467v-800h4934v800h-2467z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="14720" y="14648"><tspan fill="gray">ClassMethodProxy</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M13375 13075h6251v2151h-6251z"/><path fill="none" stroke="#F33" stroke-width="50" d="M16500 15200h-3100v-2100h6200v2100h-3100z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="700"><tspan class="TextPosition" x="13799" y="13731"><tspan fill="#C9211E">V12p1::SnippetClassProxy</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M7975 14575h3051v1851H7975z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M9500 16400H8000v-1800h3000v1800H9500z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="8277" y="15411"><tspan>MultiVersion-</tspan></tspan><tspan class="TextPosition" x="8429" y="15885"><tspan>ClassProxy</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M14008 16875h4985v851h-4985z"/><path fill="none" stroke="#999" stroke-width="50" d="M16500 17700h-2467v-800h4934v800h-2467z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="14720" y="17448"><tspan fill="gray">ClassMethodProxy</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M13375 15875h6251v2151h-6251z"/><path fill="none" stroke="#F33" stroke-width="50" d="M16500 18000h-3100v-2100h6200v2100h-3100z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="700"><tspan class="TextPosition" x="13799" y="16531"><tspan fill="#C9211E">V12p2::SnippetClassProxy</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.ConnectorShape"><path class="BoundingBox" fill="none" d="M10975 14125h2451v1401h-2451z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M11000 15500h1463v-1350h937"/></g><g class="com.sun.star.drawing.ConnectorShape"><path class="BoundingBox" fill="none" d="M10975 15475h2451v1501h-2451z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M11000 15500h1463v1450h937"/></g><g class="com.sun.star.drawing.ConnectorShape"><path class="BoundingBox" fill="none" d="M3525 13975h4501v1551H3525z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M3550 14000v1500h4450"/></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M14008 19975h4985v851h-4985z"/><path fill="none" stroke="#999" stroke-width="50" d="M16500 20800h-2467v-800h4934v800h-2467z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="14445" y="20548"><tspan fill="gray">InstanceMethodProxy</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M13375 18975h6251v2151h-6251z"/><path fill="none" stroke="#F33" stroke-width="50" d="M16500 21100h-3100v-2100h6200v2100h-3100z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="700"><tspan class="TextPosition" x="13505" y="19631"><tspan fill="#C9211E">V12p1::SnippetInstanceProxy</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M7975 20275h3051v2251H7975z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M9500 22500H8000v-2200h3000v2200H9500z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="8277" y="21311"><tspan>MultiVersion-</tspan></tspan><tspan class="TextPosition" x="8154" y="21785"><tspan>InstanceProxy</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M14008 22775h4985v851h-4985z"/><path fill="none" stroke="#999" stroke-width="50" d="M16500 23600h-2467v-800h4934v800h-2467z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="14445" y="23348"><tspan fill="gray">InstanceMethodProxy</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M13375 21775h6251v2151h-6251z"/><path fill="none" stroke="#F33" stroke-width="50" d="M16500 23900h-3100v-2100h6200v2100h-3100z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="700"><tspan class="TextPosition" x="13505" y="22431"><tspan fill="#C9211E">V12p2::SnippetInstanceProxy</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.ConnectorShape"><path class="BoundingBox" fill="none" d="M10975 20025h2451v1401h-2451z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M11000 21400h1463v-1350h937"/></g><g class="com.sun.star.drawing.ConnectorShape"><path class="BoundingBox" fill="none" d="M10975 21375h2451v1501h-2451z"/><path fill="none" stroke="#3465A4" stroke-width="50" d="M11000 21400h1463v1450h937"/></g><g class="com.sun.star.drawing.TextShape"><path class="BoundingBox" fill="none" d="M900 1600h10697v879H900z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="564" font-weight="400"><tspan class="TextPosition" x="1150" y="2233"><tspan>Standard elasticsearch-rails setup</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.TextShape"><path class="BoundingBox" fill="none" d="M900 9300h7683v879H900z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="564" font-weight="400"><tspan class="TextPosition" x="1150" y="9933"><tspan>GitLab multi-indices setup</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.TextShape"><path class="BoundingBox" fill="none" d="M3400 21300h4821v1197H3400z"/><text class="TextShape"><tspan class="TextParagraph" font-size="388" font-weight="400"><tspan class="TextPosition" x="4250" y="21840"><tspan fill="gray">(instance method)</tspan></tspan><tspan class="TextPosition" x="3651" y="22264"><tspan font-family="Courier" font-size="423">__elasticsearch__</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.TextShape"><path class="BoundingBox" fill="none" d="M3380 15400h4821v1197H3380z"/><text class="TextShape"><tspan class="TextParagraph" font-size="388" font-weight="400"><tspan class="TextPosition" x="4512" y="15940"><tspan fill="gray">(class method)</tspan></tspan><tspan class="TextPosition" x="3631" y="16364"><tspan font-family="Courier" font-size="423">__elasticsearch__</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.TextShape"><path class="BoundingBox" fill="none" d="M9000 3500h4821v1197H9000z"/><text class="TextShape"><tspan class="TextParagraph" font-size="388" font-weight="400"><tspan class="TextPosition" x="10132" y="4040"><tspan fill="gray">(class method)</tspan></tspan><tspan class="TextPosition" x="9251" y="4464"><tspan font-family="Courier" font-size="423">__elasticsearch__</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.TextShape"><path class="BoundingBox" fill="none" d="M9000 6400h4821v1197H9000z"/><text class="TextShape"><tspan class="TextParagraph" font-size="388" font-weight="400"><tspan class="TextPosition" x="9850" y="6940"><tspan fill="gray">(instance method)</tspan></tspan><tspan class="TextPosition" x="9251" y="7364"><tspan font-family="Courier" font-size="423">__elasticsearch__</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M1975 25175h2051v851H1975z"/><path fill="none" stroke="#999" stroke-width="50" d="M3000 26000H2000v-800h2000v800H3000z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="2634" y="25748"><tspan fill="gray">Foo</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.TextShape"><path class="BoundingBox" fill="none" d="M4400 25200h7101v726H4400z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="4650" y="25710"><tspan>elasticsearch-rails' internal class</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.TextShape"><path class="BoundingBox" fill="none" d="M4400 26400h8601v1200H4400z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="4650" y="26910"><tspan>where model-specific logic is</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M1975 26275h2051v851H1975z"/><path fill="none" stroke="#F33" stroke-width="50" d="M3000 27100H2000v-800h2000v800H3000z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="700"><tspan class="TextPosition" x="2613" y="26848"><tspan fill="#C9211E">Foo</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.TextShape"><path class="BoundingBox" fill="none" d="M4900 17289h5901v2312H4900z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="370" font-weight="400"><tspan class="TextPosition" x="7236" y="17748"><tspan fill="gray">Write operations like </tspan></tspan><tspan class="TextPosition" x="5323" y="18159"><tspan fill="gray">indexing/updating are forwarded </tspan></tspan><tspan class="TextPosition" x="8024" y="18570"><tspan fill="gray">to all instances.</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="370" font-weight="400"><tspan class="TextPosition" x="5501" y="18981"><tspan fill="gray">Read operations are forwarded </tspan></tspan><tspan class="TextPosition" x="7126" y="19392"><tspan fill="gray">to specified instance.</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.ConnectorShape"><path class="BoundingBox" fill="none" d="M10785 15769h1422v2691h-1422z"/><path fill="none" stroke="#999" stroke-width="30" d="M10800 18444c1429 0 934-1618 1119-2337"/><path fill="#999" d="M12206 15769l-460 293 267 217 193-510z"/></g><g class="com.sun.star.drawing.ConnectorShape"><path class="BoundingBox" fill="none" d="M10785 18429h1528v2862h-1528z"/><path fill="none" stroke="#999" stroke-width="30" d="M10800 18444c1509 0 970 1782 1200 2526"/><path fill="#999" d="M12312 21290l-227-496-252 235 479 261z"/></g><g class="com.sun.star.drawing.TextShape"><path class="BoundingBox" fill="none" d="M1800 24000h7101v807H1800z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="494" font-weight="700"><tspan class="TextPosition" x="2050" y="24574"><tspan>Legend</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M13975 4275h5085v851h-5085z"/><path fill="none" stroke="#999" stroke-width="50" d="M16517 5100h-2517v-800h5034v800h-2517z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="14737" y="4848"><tspan fill="gray">ClassMethodProxy</tspan></tspan></tspan></text></g><g class="com.sun.star.drawing.CustomShape"><path class="BoundingBox" fill="none" d="M13975 5975h5085v851h-5085z"/><path fill="none" stroke="#999" stroke-width="50" d="M16517 6800h-2517v-800h5034v800h-2517z"/><text class="TextShape"><tspan class="TextParagraph" font-family="Arial, sans-serif" font-size="423" font-weight="400"><tspan class="TextPosition" x="14462" y="6548"><tspan fill="gray">InstanceMethodProxy</tspan></tspan></tspan></text></g></g></g></g></svg> \ No newline at end of file
diff --git a/doc/development/import_project.md b/doc/development/import_project.md
index 69e5873cd87..d021126c8eb 100644
--- a/doc/development/import_project.md
+++ b/doc/development/import_project.md
@@ -195,7 +195,7 @@ You can use this snippet: `https://gitlab.com/gitlab-org/gitlab/snippets/1924954
You can execute the script from the `gdk/gitlab` directory like this:
```shell
-bundle exec rails r /path_to_sript/script.rb project_name /path_to_extracted_project request_store_enabled
+bundle exec rails r /path_to_script/script.rb project_name /path_to_extracted_project request_store_enabled
```
## Troubleshooting
diff --git a/doc/development/integrations/jenkins.md b/doc/development/integrations/jenkins.md
index a1ad259319d..3987c6658c3 100644
--- a/doc/development/integrations/jenkins.md
+++ b/doc/development/integrations/jenkins.md
@@ -24,8 +24,8 @@ brew services start jenkins
GitLab does not allow requests to localhost or the local network by default. When running Jenkins on your local machine, you need to enable local access.
1. Log into your GitLab instance as an administrator.
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > Network**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Network**.
1. Expand **Outbound requests** and check the following checkboxes:
- **Allow requests to the local network from web hooks and services**
diff --git a/doc/development/integrations/jira_connect.md b/doc/development/integrations/jira_connect.md
index 9772f7504cf..ca3dc3660ee 100644
--- a/doc/development/integrations/jira_connect.md
+++ b/doc/development/integrations/jira_connect.md
@@ -54,7 +54,7 @@ To install the app in Jira:
1. Click **Upload**.
- If the install was successful, you should see the **GitLab for Jira** app under **Manage apps**.
+ If the install was successful, you should see the **GitLab.com for Jira Cloud** app under **Manage apps**.
You can also click **Getting Started** to open the configuration page rendered from your GitLab instance.
_Note that any changes to the app descriptor requires you to uninstall then reinstall the app._
diff --git a/doc/development/integrations/secure.md b/doc/development/integrations/secure.md
index 42a57e7f4fb..d37ce29e353 100644
--- a/doc/development/integrations/secure.md
+++ b/doc/development/integrations/secure.md
@@ -444,6 +444,10 @@ the system saves only the first 20 of them. Note that vulnerabilities in the [Pi
Security](../../user/application_security/security_dashboard/#pipeline-security)
tab do not enforce this limit and all identifiers present in the report artifact are displayed.
+### Details
+
+The `details` field is an object that supports many different content elements that are displayed when viewing vulnerability information. An example of the various data elements can be seen in the [security-reports repository](https://gitlab.com/gitlab-examples/security/security-reports/-/tree/master/samples/details-example).
+
### Location
The `location` indicates where the vulnerability has been detected.
@@ -454,10 +458,6 @@ which is used to track vulnerabilities
as new commits are pushed to the repository.
The attributes used to generate the location fingerprint also depend on the type of scanning.
-### Details
-
-The `details` field is an object that supports many different content elements that are displayed when viewing vulnerability information. An example of the various data elements can be seen in the [security-reports repository](https://gitlab.com/gitlab-examples/security/security-reports/-/tree/master/samples/details-example).
-
#### Dependency Scanning
The `location` of a Dependency Scanning vulnerability is composed of a `dependency` and a `file`.
diff --git a/doc/development/internal_api.md b/doc/development/internal_api.md
index c7fc4bed38c..660d8c60ba8 100644
--- a/doc/development/internal_api.md
+++ b/doc/development/internal_api.md
@@ -501,6 +501,56 @@ curl --request POST --header "Gitlab-Kas-Api-Request: <JWT token>" \
"http://localhost:3000/api/v4/internal/kubernetes/modules/cilium_alert"
```
+### Create Starboard vulnerability
+
+Called from the GitLab Kubernetes Agent Server (`kas`) to create a security vulnerability
+from a Starboard vulnerability report. This request is idempotent. Multiple requests with the same data
+create a single vulnerability.
+
+| Attribute | Type | Required | Description |
+|:----------------|:-------|:---------|:------------|
+| `vulnerability` | Hash | yes | Vulnerability data matching the security report schema [`vulnerability` field](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/blob/master/src/security-report-format.json). |
+| `scanner` | Hash | yes | Scanner data matching the security report schema [`scanner` field](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/blob/master/src/security-report-format.json). |
+
+```plaintext
+PUT internal/kubernetes/modules/starboard_vulnerability
+```
+
+Example Request:
+
+```shell
+curl --request PUT --header "Gitlab-Kas-Api-Request: <JWT token>" \
+ --header "Authorization: Bearer <agent token>" --header "Content-Type: application/json" \
+ --url "http://localhost:3000/api/v4/internal/kubernetes/modules/starboard_vulnerability" \
+ --data '{
+ "vulnerability": {
+ "name": "CVE-123-4567 in libc",
+ "severity": "high",
+ "confidence": "unknown",
+ "location": {
+ "kubernetes_resource": {
+ "namespace": "production",
+ "kind": "deployment",
+ "name": "nginx",
+ "container": "nginx"
+ }
+ },
+ "identifiers": [
+ {
+ "type": "cve",
+ "name": "CVE-123-4567",
+ "value": "CVE-123-4567"
+ }
+ ]
+ },
+ "scanner": {
+ "id": "starboard_trivy",
+ "name": "Trivy (via Starboard Operator)",
+ "vendor": "GitLab"
+ }
+}'
+```
+
## Subscriptions
The subscriptions endpoint is used by [CustomersDot](https://gitlab.com/gitlab-org/customers-gitlab-com) (`customers.gitlab.com`)
@@ -675,7 +725,7 @@ Example request:
```shell
curl --request POST \
- --url http://localhost:3000/api/v4/namespaces/123/minutes \
+ --url "http://localhost:3000/api/v4/namespaces/123/minutes" \
--header 'Content-Type: application/json' \
--header 'PRIVATE-TOKEN: <admin access token>' \
--data '{
@@ -719,7 +769,7 @@ Example request:
```shell
curl --request PATCH \
- --url http://localhost:3000/api/v4/namespaces/123/minutes/move/321 \
+ --url "http://localhost:3000/api/v4/namespaces/123/minutes/move/321" \
--header 'PRIVATE-TOKEN: <admin access token>'
```
diff --git a/doc/development/issue_types.md b/doc/development/issue_types.md
index d02ff590352..31fa50e1d97 100644
--- a/doc/development/issue_types.md
+++ b/doc/development/issue_types.md
@@ -4,7 +4,10 @@ group: Project Management
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
---
-# Issue Types
+# Issue Types (DEPRECATED)
+
+WARNING:
+We are deprecating Issue Types as of GitLab 14.2 in favor of [Work Items and Work Item Types](work_items.md).
Sometimes when a new resource type is added it's not clear if it should be only an
"extension" of Issue (Issue Type) or if it should be a new first-class resource type
diff --git a/doc/development/migration_style_guide.md b/doc/development/migration_style_guide.md
index bbaa6527e84..ce564551fbf 100644
--- a/doc/development/migration_style_guide.md
+++ b/doc/development/migration_style_guide.md
@@ -70,7 +70,7 @@ graph LR
H -->|Yes| E[Regular migration]
H -->|No| I[Post-deploy migration<br/>+ feature flag]
-
+
D -->|Yes| F[Post-deploy migration]
D -->|No| G[Background migration]
```
@@ -217,6 +217,40 @@ In case you need to insert, update, or delete a significant amount of data, you:
- Must disable the single transaction with `disable_ddl_transaction!`.
- Should consider doing it in a [Background Migration](background_migrations.md).
+## Migration helpers and versioning
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/339115) in GitLab 14.3.
+
+Various helper methods are available for many common patterns in database migrations. Those
+helpers can be found in `Gitlab::Database::MigrationHelpers` and related modules.
+
+In order to allow changing a helper's behavior over time, we implement a versioning scheme
+for migration helpers. This allows us to maintain the behavior of a helper for already
+existing migrations but change the behavior for any new migrations.
+
+For that purpose, all database migrations should inherit from `Gitlab::Database::Migration`,
+which is a "versioned" class. For new migrations, the latest version should be used (which
+can be looked up in `Gitlab::Database::Migration::MIGRATION_CLASSES`) to use the latest version
+of migration helpers.
+
+In this example, we use version 1.0 of the migration class:
+
+```ruby
+class TestMigration < Gitlab::Database::Migration[1.0]
+ def change
+ end
+end
+```
+
+Do not include `Gitlab::Database::MigrationHelpers` directly into a
+migration. Instead, use the latest version of `Gitlab::Database::Migration`, which exposes the latest
+version of migration helpers automatically.
+
+Migration helpers and versioning were [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68986)
+in GitLab 14.3.
+For merge requests targeting previous stable branches, use the old format and still inherit from
+`ActiveRecord::Migration[6.1]` instead of `Gitlab::Database::Migration[1.0]`.
+
## Retry mechanism when acquiring database locks
When changing the database schema, we use helper methods to invoke DDL (Data Definition
@@ -247,87 +281,91 @@ This problem could cause failed application upgrade processes and even applicati
stability issues, since the table may be inaccessible for a short period of time.
To increase the reliability and stability of database migrations, the GitLab codebase
-offers a helper method to retry the operations with different `lock_timeout` settings
-and wait time between the attempts. Multiple smaller attempts to acquire the necessary
+offers a method to retry the operations with different `lock_timeout` settings
+and wait time between the attempts. Multiple shorter attempts to acquire the necessary
lock allow the database to process other statements.
-### Examples
+There are two distinct ways to use lock retries:
+
+1. Inside a transactional migration: use `enable_lock_retries!`.
+1. Inside a non-transactional migration: use `with_lock_retries`.
+
+If possible, enable lock-retries for any migration that touches a [high-traffic table](#high-traffic-tables).
+
+### Usage with transactional migrations
+
+Regular migrations execute the full migration in a transaction. We can enable the
+lock-retry methodology by calling `enable_lock_retries!` at the migration level.
+
+This leads to the lock timeout being controlled for this migration. Also, it can lead to retrying the full
+migration if the lock could not be granted within the timeout.
+
+Note that, while this is currently an opt-in setting, we prefer to use lock-retries for all migrations and
+plan to make this the default going forward.
+
+Occasionally a migration may need to acquire multiple locks on different objects.
+To prevent catalog bloat, ask for all those locks explicitly before performing any DDL.
+A better strategy is to split the migration, so that we only need to acquire one lock at the time.
**Removing a column:**
```ruby
-include Gitlab::Database::MigrationHelpers
+enable_lock_retries!
def up
- with_lock_retries do
- remove_column :users, :full_name
- end
+ remove_column :users, :full_name
end
def down
- with_lock_retries do
- add_column :users, :full_name, :string
- end
+ add_column :users, :full_name, :string
end
```
**Multiple changes on the same table:**
-The helper `with_lock_retries` wraps all operations into a single transaction. When you have the lock,
+With the lock-retry methodology enabled, all operations wrap into a single transaction. When you have the lock,
you should do as much as possible inside the transaction rather than trying to get another lock later.
Be careful about running long database statements within the block. The acquired locks are kept until the transaction (block) finishes and depending on the lock type, it might block other database operations.
```ruby
-include Gitlab::Database::MigrationHelpers
+enable_lock_retries!
def up
- with_lock_retries do
- add_column :users, :full_name, :string
- add_column :users, :bio, :string
- end
+ add_column :users, :full_name, :string
+ add_column :users, :bio, :string
end
def down
- with_lock_retries do
- remove_column :users, :full_name
- remove_column :users, :bio
- end
+ remove_column :users, :full_name
+ remove_column :users, :bio
end
```
**Removing a foreign key:**
```ruby
-include Gitlab::Database::MigrationHelpers
+enable_lock_retries!
def up
- with_lock_retries do
- remove_foreign_key :issues, :projects
- end
+ remove_foreign_key :issues, :projects
end
def down
- with_lock_retries do
- add_foreign_key :issues, :projects
- end
+ add_foreign_key :issues, :projects
end
```
**Changing default value for a column:**
```ruby
-include Gitlab::Database::MigrationHelpers
+enable_lock_retries!
def up
- with_lock_retries do
- change_column_default :merge_requests, :lock_version, from: nil, to: 0
- end
+ change_column_default :merge_requests, :lock_version, from: nil, to: 0
end
def down
- with_lock_retries do
- change_column_default :merge_requests, :lock_version, from: 0, to: nil
- end
+ change_column_default :merge_requests, :lock_version, from: 0, to: nil
end
```
@@ -336,25 +374,23 @@ end
We can wrap the `create_table` method with `with_lock_retries`:
```ruby
+enable_lock_retries!
+
def up
- with_lock_retries do
- create_table :issues do |t|
- t.references :project, index: true, null: false, foreign_key: { on_delete: :cascade }
- t.string :title, limit: 255
- end
+ create_table :issues do |t|
+ t.references :project, index: true, null: false, foreign_key: { on_delete: :cascade }
+ t.string :title, limit: 255
end
end
def down
- with_lock_retries do
- drop_table :issues
- end
+ drop_table :issues
end
```
**Creating a new table when we have two foreign keys:**
-Only one foreign key should be created per migration. This is because [the addition of a foreign key constraint requires a `SHARE ROW EXCLUSIVE` lock on the referenced table](https://www.postgresql.org/docs/12/sql-createtable.html#:~:text=The%20addition%20of%20a%20foreign%20key%20constraint%20requires%20a%20SHARE%20ROW%20EXCLUSIVE%20lock%20on%20the%20referenced%20table), and locking multiple tables in the same transaction should be avoided.
+Only one foreign key should be created per transaction. This is because [the addition of a foreign key constraint requires a `SHARE ROW EXCLUSIVE` lock on the referenced table](https://www.postgresql.org/docs/12/sql-createtable.html#:~:text=The%20addition%20of%20a%20foreign%20key%20constraint%20requires%20a%20SHARE%20ROW%20EXCLUSIVE%20lock%20on%20the%20referenced%20table), and locking multiple tables in the same transaction should be avoided.
For this, we need three migrations:
@@ -387,8 +423,6 @@ We can use the `add_concurrent_foreign_key` method in this case, as this helper
has the lock retries built into it.
```ruby
-include Gitlab::Database::MigrationHelpers
-
disable_ddl_transaction!
def up
@@ -405,8 +439,6 @@ end
Adding foreign key to `users`:
```ruby
-include Gitlab::Database::MigrationHelpers
-
disable_ddl_transaction!
def up
@@ -420,16 +452,20 @@ def down
end
```
-**Usage with `disable_ddl_transaction!`**
+### Usage with non-transactional migrations (`disable_ddl_transaction!`)
-Generally the `with_lock_retries` helper should work with `disable_ddl_transaction!`. A custom RuboCop rule ensures that only allowed methods can be placed within the lock retries block.
+Only when we disable transactional migrations using `disable_ddl_transaction!`, we can use
+the `with_lock_retries` helper to guard an individual sequence of steps. It opens a transaction
+to execute the given block.
+
+A custom RuboCop rule ensures that only allowed methods can be placed within the lock retries block.
```ruby
disable_ddl_transaction!
def up
with_lock_retries do
- add_column :users, :name, :text
+ add_column :users, :name, :text unless column_exists?(:users, :name)
end
add_text_limit :users, :name, 255 # Includes constraint validation (full table scan)
@@ -450,7 +486,8 @@ end
### When to use the helper method
-The `with_lock_retries` helper method can be used when you normally use
+You can **only** use the `with_lock_retries` helper method when the execution is not already inside
+an open transaction (using Postgres subtransactions is discouraged). It can be used with
standard Rails migration helper methods. Calling more than one migration
helper is not a problem if they're executed on the same table.
@@ -498,11 +535,11 @@ by calling the method `disable_ddl_transaction!` in the body of your migration
class like so:
```ruby
-class MyMigration < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
+class MyMigration < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
INDEX_NAME = 'index_name'
+
def up
remove_concurrent_index :table_name, :column_name, name: INDEX_NAME
end
@@ -549,7 +586,7 @@ by calling the method `disable_ddl_transaction!` in the body of your migration
class like so:
```ruby
-class MyMigration < ActiveRecord::Migration[6.0]
+class MyMigration < Gitlab::Database::Migration[1.0]
include Gitlab::Database::MigrationHelpers
disable_ddl_transaction!
@@ -594,7 +631,7 @@ The easiest way to test for existence of an index by name is to use the
be used with a name option. For example:
```ruby
-class MyMigration < ActiveRecord::Migration[6.0]
+class MyMigration < Gitlab::Database::Migration[1.0]
include Gitlab::Database::MigrationHelpers
INDEX_NAME = 'index_name'
@@ -631,7 +668,7 @@ Here's an example where we add a new column with a foreign key
constraint. Note it includes `index: true` to create an index for it.
```ruby
-class Migration < ActiveRecord::Migration[6.0]
+class Migration < Gitlab::Database::Migration[1.0]
def change
add_reference :model, :other_model, index: true, foreign_key: { on_delete: :cascade }
@@ -677,7 +714,7 @@ expensive and disruptive operation for larger tables, but in reality it's not.
Take the following migration as an example:
```ruby
-class DefaultRequestAccessGroups < ActiveRecord::Migration[5.2]
+class DefaultRequestAccessGroups < Gitlab::Database::Migration[1.0]
def change
change_column_default(:namespaces, :request_access_enabled, from: false, to: true)
end
@@ -884,7 +921,7 @@ The Rails 5 natively supports `JSONB` (binary JSON) column type.
Example migration adding this column:
```ruby
-class AddOptionsToBuildMetadata < ActiveRecord::Migration[5.0]
+class AddOptionsToBuildMetadata < Gitlab::Database::Migration[1.0]
def change
add_column :ci_builds_metadata, :config_options, :jsonb
end
@@ -916,7 +953,7 @@ Do not store `attr_encrypted` attributes as `:text` in the database; use
efficient:
```ruby
-class AddSecretToSomething < ActiveRecord::Migration[5.0]
+class AddSecretToSomething < Gitlab::Database::Migration[1.0]
def change
add_column :something, :encrypted_secret, :binary
add_column :something, :encrypted_secret_iv, :binary
@@ -974,7 +1011,7 @@ If you need more complex logic, you can define and use models local to a
migration. For example:
```ruby
-class MyMigration < ActiveRecord::Migration[6.0]
+class MyMigration < Gitlab::Database::Migration[1.0]
class Project < ActiveRecord::Base
self.table_name = 'projects'
end
@@ -1073,7 +1110,7 @@ in a previous migration.
It is important not to leave out the `User.reset_column_information` command, in order to ensure that the old schema is dropped from the cache and ActiveRecord loads the updated schema information.
```ruby
-class AddAndSeedMyColumn < ActiveRecord::Migration[6.0]
+class AddAndSeedMyColumn < Gitlab::Database::Migration[1.0]
class User < ActiveRecord::Base
self.table_name = 'users'
end
diff --git a/doc/development/multi_version_compatibility.md b/doc/development/multi_version_compatibility.md
index 3314b5e7ddc..f834f4f4ee3 100644
--- a/doc/development/multi_version_compatibility.md
+++ b/doc/development/multi_version_compatibility.md
@@ -124,7 +124,7 @@ GitLab.com, the feature can be enabled in ChatOps and validated on GitLab.com.
**However, it is not necessarily safe to enable the feature by default.** If the
feature flag is removed, or the default is flipped to enabled, in the same release
-where the code was merged, then customers performing [zero-downtime updates](https://docs.gitlab.com/omnibus/update/#zero-downtime-updates)
+where the code was merged, then customers performing [zero-downtime updates](../update/zero_downtime.md)
will end up running the new frontend code against the previous release's API.
If you're not sure whether it's safe to enable all the changes at once, then one
@@ -201,7 +201,7 @@ gantt
section Database
Schema A :done, schemaA, 00:00 , 1h
Schema B :crit, schemaB, after migr, 58m
- Schema C. : schmeaC, after postmigr, 1h
+ Schema C. : schemaC, after postmigr, 1h
section Machine A
Version N :done, mavn, 00:00 , 75m
diff --git a/doc/development/packages.md b/doc/development/packages.md
index 94882cefc30..869a1755d8f 100644
--- a/doc/development/packages.md
+++ b/doc/development/packages.md
@@ -133,7 +133,7 @@ During this phase, the idea is to collect as much information as possible about
- **Authentication**: What authentication mechanisms are available (OAuth, Basic
Authorization, other). Keep in mind that GitLab users often want to use their
[Personal Access Tokens](../user/profile/personal_access_tokens.md).
- Although not needed for the MVC first iteration, the [CI/CD job tokens](../api/index.md#gitlab-cicd-job-token)
+ Although not needed for the MVC first iteration, the [CI/CD job tokens](../ci/jobs/ci_job_token.md)
have to be supported at some point in the future.
- **Requests**: Which requests are needed to have a working MVC. Ideally, produce
a list of all the requests needed for the MVC (including required actions). Further
diff --git a/doc/development/pipelines.md b/doc/development/pipelines.md
index 820299a426b..dd45091a31b 100644
--- a/doc/development/pipelines.md
+++ b/doc/development/pipelines.md
@@ -64,7 +64,7 @@ graph LR
click 1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8100542&udv=0"
1-2["docs-lint markdown (1.5 minutes)"];
click 1-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=10224335&udv=0"
- 1-3["docs-lint links (6 minutes)"];
+ 1-3["docs-lint links (5 minutes)"];
click 1-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356757&udv=0"
1-4["ui-docs-links lint (2.5 minutes)"];
click 1-4 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=10823717&udv=1020379"
@@ -104,7 +104,7 @@ graph RL;
1-18["kubesec-sast"];
1-19["nodejs-scan-sast"];
1-20["secrets-sast"];
- 1-21["static-analysis (30 minutes)"];
+ 1-21["static-analysis (14 minutes)"];
click 1-21 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914471&udv=0"
class 1-3 criticalPath;
@@ -123,7 +123,7 @@ graph RL;
2_1-1 & 2_1-2 & 2_1-3 & 2_1-4 --> 1-6;
end
- 2_2-2["rspec frontend_fixture/rspec-ee frontend_fixture (11 minutes)"];
+ 2_2-2["rspec frontend_fixture/rspec-ee frontend_fixture (7 minutes)"];
class 2_2-2 criticalPath;
click 2_2-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=7910143&udv=0"
2_2-4["memory-on-boot (3.5 minutes)"];
@@ -152,16 +152,14 @@ graph RL;
click 2_5-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations"
end
- 3_1-1["jest (16 minutes)"];
+ 3_1-1["jest (14.5 minutes)"];
class 3_1-1 criticalPath;
click 3_1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914204&udv=0"
- 3_1-2["karma (2 minutes)"];
- click 3_1-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914200&udv=0"
subgraph "Needs `rspec frontend_fixture/rspec-ee frontend_fixture`";
- 3_1-1 & 3_1-2 --> 2_2-2;
+ 3_1-1 --> 2_2-2;
end
- 3_2-1["rspec:coverage (5.3 minutes)"];
+ 3_2-1["rspec:coverage (4 minutes)"];
subgraph "Depends on `rspec` jobs";
3_2-1 -.->|"(don't use needs because of limitations)"| 2_5-1;
click 3_2-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=7248745&udv=0"
@@ -208,7 +206,7 @@ graph RL;
1-18["kubesec-sast"];
1-19["nodejs-scan-sast"];
1-20["secrets-sast"];
- 1-21["static-analysis (30 minutes)"];
+ 1-21["static-analysis (14 minutes)"];
click 1-21 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914471&udv=0"
class 1-3 criticalPath;
@@ -228,7 +226,7 @@ graph RL;
2_1-1 & 2_1-2 & 2_1-3 & 2_1-4 --> 1-6;
end
- 2_2-2["rspec frontend_fixture/rspec-ee frontend_fixture (11 minutes)"];
+ 2_2-2["rspec frontend_fixture/rspec-ee frontend_fixture (7 minutes)"];
class 2_2-2 criticalPath;
click 2_2-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=7910143&udv=0"
2_2-4["memory-on-boot (3.5 minutes)"];
@@ -265,16 +263,14 @@ graph RL;
click 2_6-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914314&udv=0"
end
- 3_1-1["jest (16 minutes)"];
+ 3_1-1["jest (14.5 minutes)"];
class 3_1-1 criticalPath;
click 3_1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914204&udv=0"
- 3_1-2["karma (2 minutes)"];
- click 3_1-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914200&udv=0"
subgraph "Needs `rspec frontend_fixture/rspec-ee frontend_fixture`";
- 3_1-1 & 3_1-2 --> 2_2-2;
+ 3_1-1 --> 2_2-2;
end
- 3_2-1["rspec:coverage (5.3 minutes)"];
+ 3_2-1["rspec:coverage (4 minutes)"];
subgraph "Depends on `rspec` jobs";
3_2-1 -.->|"(don't use needs because of limitations)"| 2_5-1;
click 3_2-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=7248745&udv=0"
@@ -287,7 +283,7 @@ graph RL;
click 4_1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=7910777&udv=0"
end
- 3_3-1["review-deploy (10.5 minutes)"];
+ 3_3-1["review-deploy (9 minutes)"];
subgraph "Played by `review-build-cng`";
3_3-1 --> 2_6-1;
class 3_3-1 criticalPath;
@@ -336,7 +332,7 @@ graph RL;
1-18["kubesec-sast"];
1-19["nodejs-scan-sast"];
1-20["secrets-sast"];
- 1-21["static-analysis (30 minutes)"];
+ 1-21["static-analysis (14 minutes)"];
click 1-21 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914471&udv=0"
class 1-5 criticalPath;
@@ -354,7 +350,7 @@ graph RL;
class 2_3-1 criticalPath;
end
- 2_4-1["package-and-qa (140 minutes)"];
+ 2_4-1["package-and-qa (113 minutes)"];
subgraph "Needs `build-qa-image` & `build-assets-image`";
2_4-1 --> 1-2 & 2_3-1;
class 2_4-1 criticalPath;
@@ -434,10 +430,27 @@ In the `detect-tests` job, we use this mapping to identify the minimal tests nee
After a merge request has been approved, the pipeline would contain the full RSpec tests. This will ensure that all tests
have been run before a merge request is merged.
+### Jest minimal jobs
+
+Before a merge request is approved, the pipeline will run a minimal set of Jest tests that are related to the merge request changes.
+This is to reduce the pipeline cost and shorten the job duration.
+
+To identify the minimal set of tests needed, we pass a list of all the changed files into `jest` using the [`--findRelatedTests`](https://jestjs.io/docs/cli#--findrelatedtests-spaceseparatedlistofsourcefiles) option.
+In this mode, `jest` would resolve all the dependencies of related to the changed files, which include test files that have these files in the dependency chain.
+
+After a merge request has been approved, the pipeline would contain the full Jest tests. This will ensure that all tests
+have been run before a merge request is merged.
+
+In addition, there are a few circumstances where we would always run the full Jest tests:
+
+- when `package.json`, `yarn.lock`, `jest` config changes
+- when vendored JavaScript is changed
+- when `.graphql` files are changed
+
### PostgreSQL versions testing
Our test suite runs against PG12 as GitLab.com runs on PG12 and
-[Omnibus defaults to PG12 for new installs and upgrades](https://docs.gitlab.com/omnibus/package-information/postgresql_versions.html),
+[Omnibus defaults to PG12 for new installs and upgrades](../administration/package_information/postgresql_versions.md),
Our test suite is currently running against PG11, since GitLab.com still runs on PG11.
We do run our test suite against PG11 on nightly scheduled pipelines as well as upon specific
@@ -454,7 +467,7 @@ database library changes in MRs and `main` pipelines (with the `rspec db-library
#### Long-term plan
-We follow the [PostgreSQL versions shipped with Omnibus GitLab](https://docs.gitlab.com/omnibus/package-information/postgresql_versions.html):
+We follow the [PostgreSQL versions shipped with Omnibus GitLab](../administration/package_information/postgresql_versions.md):
| PostgreSQL version | 13.11 (April 2021) | 13.12 (May 2021) | 14.0 (June 2021?) |
| -------------------| ---------------------- | ---------------------- | ---------------------- |
@@ -627,7 +640,6 @@ that is deployed in stage `review`.
the `qa` stage's jobs (for example, Review App performance report).
- `pages`: This stage includes a job that deploys the various reports as
GitLab Pages (for example, [`coverage-ruby`](https://gitlab-org.gitlab.io/gitlab/coverage-ruby/),
- [`coverage-javascript`](https://gitlab-org.gitlab.io/gitlab/coverage-javascript/),
and `webpack-report` (found at `https://gitlab-org.gitlab.io/gitlab/webpack-report/`, but there is
[an issue with the deployment](https://gitlab.com/gitlab-org/gitlab/-/issues/233458)).
- `notify`: This stage includes jobs that notify various failures to Slack.
diff --git a/doc/development/prometheus_metrics.md b/doc/development/prometheus_metrics.md
index 66e980978bf..da6ba14cdd8 100644
--- a/doc/development/prometheus_metrics.md
+++ b/doc/development/prometheus_metrics.md
@@ -36,9 +36,7 @@ After you add or change an existing common metric, you must [re-run the import s
Or, you can create a database migration:
```ruby
-class ImportCommonMetrics < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
+class ImportCommonMetrics < Gitlab::Database::Migration[1.0]
def up
::Gitlab::DatabaseImporters::CommonMetrics::Importer.new.execute
end
diff --git a/doc/development/query_recorder.md b/doc/development/query_recorder.md
index 8759bd09538..424c089f88e 100644
--- a/doc/development/query_recorder.md
+++ b/doc/development/query_recorder.md
@@ -18,9 +18,9 @@ This style of test works by counting the number of SQL queries executed by Activ
```ruby
it "avoids N+1 database queries" do
- control_count = ActiveRecord::QueryRecorder.new { visit_some_page }.count
+ control = ActiveRecord::QueryRecorder.new { visit_some_page }
create_list(:issue, 5)
- expect { visit_some_page }.not_to exceed_query_limit(control_count)
+ expect { visit_some_page }.not_to exceed_query_limit(control)
end
```
@@ -37,9 +37,9 @@ You should pass the `skip_cached` variable to `QueryRecorder` and use the `excee
```ruby
it "avoids N+1 database queries", :use_sql_query_cache do
- control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) { visit_some_page }.count
+ control = ActiveRecord::QueryRecorder.new(skip_cached: false) { visit_some_page }
create_list(:issue, 5)
- expect { visit_some_page }.not_to exceed_all_query_limit(control_count)
+ expect { visit_some_page }.not_to exceed_all_query_limit(control)
end
```
diff --git a/doc/development/rake_tasks.md b/doc/development/rake_tasks.md
index 6b2b941a0c1..5c8e2d5fc55 100644
--- a/doc/development/rake_tasks.md
+++ b/doc/development/rake_tasks.md
@@ -128,7 +128,6 @@ In order to run the test you can use the following commands:
- `bin/rake spec:unit` to run only the unit tests
- `bin/rake spec:integration` to run only the integration tests
- `bin/rake spec:system` to run only the system tests
-- `bin/rake karma` to run the Karma test suite
`bin/rake spec` takes significant time to pass.
Instead of running the full test suite locally, you can save a lot of time by running
@@ -189,6 +188,17 @@ Alternatively you can use the following on each spec run,
bundle exec spring rspec some_spec.rb
```
+## Generate initial RuboCop TODO list
+
+One way to generate the initial list is to run the Rake task `rubocop:todo:generate`:
+
+```shell
+bundle exec rake rubocop:todo:generate
+```
+
+See [Resolving RuboCop exceptions](contributing/style_guides.md#resolving-rubocop-exceptions)
+on how to proceed from here.
+
## Compile Frontend Assets
You shouldn't ever need to compile frontend assets manually in development, but
diff --git a/doc/development/secure_coding_guidelines.md b/doc/development/secure_coding_guidelines.md
index fc60c1d7d7f..0f13b8ecae9 100644
--- a/doc/development/secure_coding_guidelines.md
+++ b/doc/development/secure_coding_guidelines.md
@@ -295,6 +295,8 @@ The injected client-side code is executed on the victim's browser in the context
Much of the impact is contingent upon the function of the application and the capabilities of the victim's session. For further impact possibilities, please check out [the beef project](https://beefproject.com/).
+For a demonstration of the impact on GitLab with a realistic attack scenario, see [this video on the GitLab Unfiltered channel](https://www.youtube.com/watch?v=t4PzHNycoKo) (internal, it requires being logged in with the GitLab Unfiltered account).
+
### When to consider?
When user submitted data is included in responses to end users, which is just about anywhere.
diff --git a/doc/development/service_ping/implement.md b/doc/development/service_ping/implement.md
index 629128af0c6..d86b06a6965 100644
--- a/doc/development/service_ping/implement.md
+++ b/doc/development/service_ping/implement.md
@@ -4,20 +4,680 @@ group: Product Intelligence
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
---
-# Develop and test Service Ping
+# Implement Service Ping
-To add a new metric and test Service Ping:
+Service Ping consists of two kinds of data:
+- **Counters**: Track how often a certain event happened over time, such as how many CI/CD pipelines have run.
+ They are monotonic and always trend up.
+- **Observations**: Facts collected from one or more GitLab instances and can carry arbitrary data.
+ There are no general guidelines for how to collect those, due to the individual nature of that data.
+
+To implement a new metric in Service Ping, follow these steps:
+
+1. [Implement the required counter](#types-of-counters)
1. [Name and place the metric](#name-and-place-the-metric)
1. [Test counters manually using your Rails console](#test-counters-manually-using-your-rails-console)
1. [Generate the SQL query](#generate-the-sql-query)
1. [Optimize queries with `#database-lab`](#optimize-queries-with-database-lab)
-1. [Add the metric definition](#add-the-metric-definition)
+1. [Add the metric definition to the Metrics Dictionary](#add-the-metric-definition)
1. [Add the metric to the Versions Application](#add-the-metric-to-the-versions-application)
1. [Create a merge request](#create-a-merge-request)
1. [Verify your metric](#verify-your-metric)
1. [Set up and test Service Ping locally](#set-up-and-test-service-ping-locally)
+## Instrumentation classes
+
+We recommend you use [instrumentation classes](metrics_instrumentation.md) in `usage_data.rb` where possible.
+
+For example, we have the following instrumentation class:
+`lib/gitlab/usage/metrics/instrumentations/count_boards_metric.rb`.
+
+You should add it to `usage_data.rb` as follows:
+
+```ruby
+boards: add_metric('CountBoardsMetric', time_frame: 'all'),
+```
+
+## Types of counters
+
+There are several types of counters in `usage_data.rb`:
+
+- **[Batch counters](#batch-counters)**: Used for counts and sums.
+- **[Redis counters](#redis-counters):** Used for in-memory counts.
+- **[Alternative counters](#alternative-counters):** Used for settings and configurations.
+
+NOTE:
+Only use the provided counter methods. Each counter method contains a built-in fail-safe mechanism that isolates each counter to avoid breaking the entire Service Ping process.
+
+### Batch counters
+
+For large tables, PostgreSQL can take a long time to count rows due to MVCC [(Multi-version Concurrency Control)](https://en.wikipedia.org/wiki/Multiversion_concurrency_control). Batch counting is a counting method where a single large query is broken into multiple smaller queries. For example, instead of a single query querying 1,000,000 records, with batch counting, you can execute 100 queries of 10,000 records each. Batch counting is useful for avoiding database timeouts as each batch query is significantly shorter than one single long running query.
+
+For GitLab.com, there are extremely large tables with 15 second query timeouts, so we use batch counting to avoid encountering timeouts. Here are the sizes of some GitLab.com tables:
+
+| Table | Row counts in millions |
+|------------------------------|------------------------|
+| `merge_request_diff_commits` | 2280 |
+| `ci_build_trace_sections` | 1764 |
+| `merge_request_diff_files` | 1082 |
+| `events` | 514 |
+
+Batch counting requires indexes on columns to calculate max, min, and range queries. In some cases,
+you must add a specialized index on the columns involved in a counter.
+
+#### Ordinary batch counters
+
+Simple count of a given `ActiveRecord_Relation`, does a non-distinct batch count, smartly reduces `batch_size`, and handles errors.
+Handles the `ActiveRecord::StatementInvalid` error.
+
+Method:
+
+```ruby
+count(relation, column = nil, batch: true, start: nil, finish: nil)
+```
+
+Arguments:
+
+- `relation` the ActiveRecord_Relation to perform the count
+- `column` the column to perform the count on, by default is the primary key
+- `batch`: default `true` to use batch counting
+- `start`: custom start of the batch counting to avoid complex min calculations
+- `end`: custom end of the batch counting to avoid complex min calculations
+
+Examples:
+
+```ruby
+count(User.active)
+count(::Clusters::Cluster.aws_installed.enabled, :cluster_id)
+count(::Clusters::Cluster.aws_installed.enabled, :cluster_id, start: ::Clusters::Cluster.minimum(:id), finish: ::Clusters::Cluster.maximum(:id))
+```
+
+#### Distinct batch counters
+
+Distinct count of a given `ActiveRecord_Relation` on given column, a distinct batch count, smartly reduces `batch_size`, and handles errors.
+Handles the `ActiveRecord::StatementInvalid` error.
+
+Method:
+
+```ruby
+distinct_count(relation, column = nil, batch: true, batch_size: nil, start: nil, finish: nil)
+```
+
+Arguments:
+
+- `relation`: the ActiveRecord_Relation to perform the count
+- `column`: the column to perform the distinct count, by default is the primary key
+- `batch`: default `true` to use batch counting
+- `batch_size`: if none set it uses default value 10000 from `Gitlab::Database::BatchCounter`
+- `start`: custom start of the batch counting to avoid complex min calculations
+- `end`: custom end of the batch counting to avoid complex min calculations
+
+WARNING:
+Counting over non-unique columns can lead to performance issues. For more information, see the [iterating tables in batches](../iterating_tables_in_batches.md) guide.
+
+Examples:
+
+```ruby
+distinct_count(::Project, :creator_id)
+distinct_count(::Note.with_suggestions.where(time_period), :author_id, start: ::User.minimum(:id), finish: ::User.maximum(:id))
+distinct_count(::Clusters::Applications::CertManager.where(time_period).available.joins(:cluster), 'clusters.user_id')
+```
+
+#### Sum batch operation
+
+Sum the values of a given ActiveRecord_Relation on given column and handles errors.
+Handles the `ActiveRecord::StatementInvalid` error
+
+Method:
+
+```ruby
+sum(relation, column, batch_size: nil, start: nil, finish: nil)
+```
+
+Arguments:
+
+- `relation`: the ActiveRecord_Relation to perform the operation
+- `column`: the column to sum on
+- `batch_size`: if none set it uses default value 1000 from `Gitlab::Database::BatchCounter`
+- `start`: custom start of the batch counting to avoid complex min calculations
+- `end`: custom end of the batch counting to avoid complex min calculations
+
+Examples:
+
+```ruby
+sum(JiraImportState.finished, :imported_issues_count)
+```
+
+#### Grouping and batch operations
+
+The `count`, `distinct_count`, and `sum` batch counters can accept an `ActiveRecord::Relation`
+object, which groups by a specified column. With a grouped relation, the methods do batch counting,
+handle errors, and returns a hash table of key-value pairs.
+
+Examples:
+
+```ruby
+count(Namespace.group(:type))
+# returns => {nil=>179, "Group"=>54}
+
+distinct_count(Project.group(:visibility_level), :creator_id)
+# returns => {0=>1, 10=>1, 20=>11}
+
+sum(Issue.group(:state_id), :weight))
+# returns => {1=>3542, 2=>6820}
+```
+
+#### Add operation
+
+Sum the values given as parameters. Handles the `StandardError`.
+Returns `-1` if any of the arguments are `-1`.
+
+Method:
+
+```ruby
+add(*args)
+```
+
+Examples:
+
+```ruby
+project_imports = distinct_count(::Project.where.not(import_type: nil), :creator_id)
+bulk_imports = distinct_count(::BulkImport, :user_id)
+
+ add(project_imports, bulk_imports)
+```
+
+#### Estimated batch counters
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/48233) in GitLab 13.7.
+
+Estimated batch counter functionality handles `ActiveRecord::StatementInvalid` errors
+when used through the provided `estimate_batch_distinct_count` method.
+Errors return a value of `-1`.
+
+WARNING:
+This functionality estimates a distinct count of a specific ActiveRecord_Relation in a given column,
+which uses the [HyperLogLog](http://algo.inria.fr/flajolet/Publications/FlFuGaMe07.pdf) algorithm.
+As the HyperLogLog algorithm is probabilistic, the **results always include error**.
+The highest encountered error rate is 4.9%.
+
+When correctly used, the `estimate_batch_distinct_count` method enables efficient counting over
+columns that contain non-unique values, which can not be assured by other counters.
+
+##### estimate_batch_distinct_count method
+
+Method:
+
+```ruby
+estimate_batch_distinct_count(relation, column = nil, batch_size: nil, start: nil, finish: nil)
+```
+
+The [method](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/utils/usage_data.rb#L63)
+includes the following arguments:
+
+- `relation`: The ActiveRecord_Relation to perform the count.
+- `column`: The column to perform the distinct count. The default is the primary key.
+- `batch_size`: From `Gitlab::Database::PostgresHll::BatchDistinctCounter::DEFAULT_BATCH_SIZE`. Default value: 10,000.
+- `start`: The custom start of the batch count, to avoid complex minimum calculations.
+- `finish`: The custom end of the batch count to avoid complex maximum calculations.
+
+The method includes the following prerequisites:
+
+- The supplied `relation` must include the primary key defined as the numeric column.
+ For example: `id bigint NOT NULL`.
+- The `estimate_batch_distinct_count` can handle a joined relation. To use its ability to
+ count non-unique columns, the joined relation **must not** have a one-to-many relationship,
+ such as `has_many :boards`.
+- Both `start` and `finish` arguments should always represent primary key relationship values,
+ even if the estimated count refers to another column, for example:
+
+ ```ruby
+ estimate_batch_distinct_count(::Note, :author_id, start: ::Note.minimum(:id), finish: ::Note.maximum(:id))
+ ```
+
+Examples:
+
+1. Simple execution of estimated batch counter, with only relation provided,
+ returned value represents estimated number of unique values in `id` column
+ (which is the primary key) of `Project` relation:
+
+ ```ruby
+ estimate_batch_distinct_count(::Project)
+ ```
+
+1. Execution of estimated batch counter, where provided relation has applied
+ additional filter (`.where(time_period)`), number of unique values estimated
+ in custom column (`:author_id`), and parameters: `start` and `finish` together
+ apply boundaries that defines range of provided relation to analyze:
+
+ ```ruby
+ estimate_batch_distinct_count(::Note.with_suggestions.where(time_period), :author_id, start: ::Note.minimum(:id), finish: ::Note.maximum(:id))
+ ```
+
+1. Execution of estimated batch counter with joined relation (`joins(:cluster)`),
+ for a custom column (`'clusters.user_id'`):
+
+ ```ruby
+ estimate_batch_distinct_count(::Clusters::Applications::CertManager.where(time_period).available.joins(:cluster), 'clusters.user_id')
+ ```
+
+When instrumenting metric with usage of estimated batch counter please add
+`_estimated` suffix to its name, for example:
+
+```ruby
+ "counts": {
+ "ci_builds_estimated": estimate_batch_distinct_count(Ci::Build),
+ ...
+```
+
+### Redis counters
+
+Handles `::Redis::CommandError` and `Gitlab::UsageDataCounters::BaseCounter::UnknownEvent`.
+Returns -1 when a block is sent or hash with all values and -1 when a `counter(Gitlab::UsageDataCounters)` is sent.
+The different behavior is due to 2 different implementations of the Redis counter.
+
+Method:
+
+```ruby
+redis_usage_data(counter, &block)
+```
+
+Arguments:
+
+- `counter`: a counter from `Gitlab::UsageDataCounters`, that has `fallback_totals` method implemented
+- or a `block`: which is evaluated
+
+#### Ordinary Redis counters
+
+Examples of implementation:
+
+- Using Redis methods [`INCR`](https://redis.io/commands/incr), [`GET`](https://redis.io/commands/get), and [`Gitlab::UsageDataCounters::WikiPageCounter`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/wiki_page_counter.rb)
+- Using Redis methods [`HINCRBY`](https://redis.io/commands/hincrby), [`HGETALL`](https://redis.io/commands/hgetall), and [`Gitlab::UsageCounters::PodLogs`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_counters/pod_logs.rb)
+
+##### UsageData API tracking
+
+<!-- There's nearly identical content in `##### Adding new events`. If you fix errors here, you may need to fix the same errors in the other location. -->
+
+1. Track event using `UsageData` API
+
+ Increment event count using ordinary Redis counter, for given event name.
+
+ Tracking events using the `UsageData` API requires the `usage_data_api` feature flag to be enabled, which is enabled by default.
+
+ API requests are protected by checking for a valid CSRF token.
+
+ To be able to increment the values, the related feature `usage_data_<event_name>` should be enabled.
+
+ ```plaintext
+ POST /usage_data/increment_counter
+ ```
+
+ | Attribute | Type | Required | Description |
+ | :-------- | :--- | :------- | :---------- |
+ | `event` | string | yes | The event name it should be tracked |
+
+ Response:
+
+ - `200` if event was tracked
+ - `400 Bad request` if event parameter is missing
+ - `401 Unauthorized` if user is not authenticated
+ - `403 Forbidden` for invalid CSRF token provided
+
+1. Track events using JavaScript/Vue API helper which calls the API above
+
+ Note that `usage_data_api` and `usage_data_#{event_name}` should be enabled to be able to track events
+
+ ```javascript
+ import api from '~/api';
+
+ api.trackRedisCounterEvent('my_already_defined_event_name'),
+ ```
+
+#### Redis HLL counters
+
+WARNING:
+HyperLogLog (HLL) is a probabilistic algorithm and its **results always includes some small error**. According to [Redis documentation](https://redis.io/commands/pfcount), data from
+used HLL implementation is "approximated with a standard error of 0.81%".
+
+With `Gitlab::UsageDataCounters::HLLRedisCounter` we have available data structures used to count unique values.
+
+Implemented using Redis methods [PFADD](https://redis.io/commands/pfadd) and [PFCOUNT](https://redis.io/commands/pfcount).
+
+##### Add new events
+
+1. Define events in [`known_events`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events/).
+
+ Example event:
+
+ ```yaml
+ - name: users_creating_epics
+ category: epics_usage
+ redis_slot: users
+ aggregation: weekly
+ feature_flag: track_epics_activity
+ ```
+
+ Keys:
+
+ - `name`: unique event name.
+
+ Name format for Redis HLL events `<name>_<redis_slot>`.
+
+ [See Metric name](metrics_dictionary.md#metric-name) for a complete guide on metric naming suggestion.
+
+ Consider including in the event's name the Redis slot to be able to count totals for a specific category.
+
+ Example names: `users_creating_epics`, `users_triggering_security_scans`.
+
+ - `category`: event category. Used for getting total counts for events in a category, for easier
+ access to a group of events.
+ - `redis_slot`: optional Redis slot. Default value: event name. Only event data that is stored in the same slot
+ can be aggregated. Ensure keys are in the same slot. For example:
+ `users_creating_epics` with `redis_slot: 'users'` builds Redis key
+ `{users}_creating_epics-2020-34`. If `redis_slot` is not defined the Redis key will
+ be `{users_creating_epics}-2020-34`.
+ Recommended slots to use are: `users`, `projects`. This is the value we count.
+ - `expiry`: expiry time in days. Default: 29 days for daily aggregation and 6 weeks for weekly
+ aggregation.
+ - `aggregation`: may be set to a `:daily` or `:weekly` key. Defines how counting data is stored in Redis.
+ Aggregation on a `daily` basis does not pull more fine grained data.
+ - `feature_flag`: optional `default_enabled: :yaml`. If no feature flag is set then the tracking is enabled. One feature flag can be used for multiple events. For details, see our [GitLab internal Feature flags](../feature_flags/index.md) documentation. The feature flags are owned by the group adding the event tracking.
+
+1. Use one of the following methods to track the event:
+
+ - In the controller using the `RedisTracking` module and the following format:
+
+ ```ruby
+ track_redis_hll_event(*controller_actions, name:, if: nil, &block)
+ ```
+
+ Arguments:
+
+ - `controller_actions`: the controller actions to track.
+ - `name`: the event name.
+ - `if`: optional custom conditions. Uses the same format as Rails callbacks.
+ - `&block`: optional block that computes and returns the `custom_id` that we want to track. This overrides the `visitor_id`.
+
+ Example:
+
+ ```ruby
+ # controller
+ class ProjectsController < Projects::ApplicationController
+ include RedisTracking
+
+ skip_before_action :authenticate_user!, only: :show
+ track_redis_hll_event :index, :show, name: 'users_visiting_projects'
+
+ def index
+ render html: 'index'
+ end
+
+ def new
+ render html: 'new'
+ end
+
+ def show
+ render html: 'show'
+ end
+ end
+ ```
+
+ - In the API using the `increment_unique_values(event_name, values)` helper method.
+
+ Arguments:
+
+ - `event_name`: the event name.
+ - `values`: the values counted. Can be one value or an array of values.
+
+ Example:
+
+ ```ruby
+ get ':id/registry/repositories' do
+ repositories = ContainerRepositoriesFinder.new(
+ user: current_user, subject: user_group
+ ).execute
+
+ increment_unique_values('users_listing_repositories', current_user.id)
+
+ present paginate(repositories), with: Entities::ContainerRegistry::Repository, tags: params[:tags], tags_count: params[:tags_count]
+ end
+ ```
+
+ - Using `track_usage_event(event_name, values)` in services and GraphQL.
+
+ Increment unique values count using Redis HLL, for a given event name.
+
+ Examples:
+
+ - [Track usage event for an incident in a service](https://gitlab.com/gitlab-org/gitlab/-/blob/v13.8.3-ee/app/services/issues/update_service.rb#L66)
+ - [Track usage event for an incident in GraphQL](https://gitlab.com/gitlab-org/gitlab/-/blob/v13.8.3-ee/app/graphql/mutations/alert_management/update_alert_status.rb#L16)
+
+ ```ruby
+ track_usage_event(:incident_management_incident_created, current_user.id)
+ ```
+
+ - Using the `UsageData` API.
+ <!-- There's nearly identical content in `##### UsageData API Tracking`. If you find / fix errors here, you may need to fix errors in that section too. -->
+
+ Increment unique users count using Redis HLL, for a given event name.
+
+ To track events using the `UsageData` API, ensure the `usage_data_api` feature flag
+ is set to `default_enabled: true`. Enabled by default in GitLab 13.7 and later.
+
+ API requests are protected by checking for a valid CSRF token.
+
+ ```plaintext
+ POST /usage_data/increment_unique_users
+ ```
+
+ | Attribute | Type | Required | Description |
+ | :-------- | :--- | :------- | :---------- |
+ | `event` | string | yes | The event name to track |
+
+ Response:
+
+ - `200` if the event was tracked, or if tracking failed for any reason.
+ - `400 Bad request` if an event parameter is missing.
+ - `401 Unauthorized` if the user is not authenticated.
+ - `403 Forbidden` if an invalid CSRF token is provided.
+
+ - Using the JavaScript/Vue API helper, which calls the `UsageData` API.
+
+ To track events using the `UsageData` API, ensure the `usage_data_api` feature flag
+ is set to `default_enabled: true`. Enabled by default in GitLab 13.7 and later.
+
+ Example for an existing event already defined in [known events](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events/):
+
+ ```javascript
+ import api from '~/api';
+
+ api.trackRedisHllUserEvent('my_already_defined_event_name'),
+ ```
+
+1. Get event data using `Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names:, start_date:, end_date:, context: '')`.
+
+ Arguments:
+
+ - `event_names`: the list of event names.
+ - `start_date`: start date of the period for which we want to get event data.
+ - `end_date`: end date of the period for which we want to get event data.
+ - `context`: context of the event. Allowed values are `default`, `free`, `bronze`, `silver`, `gold`, `starter`, `premium`, `ultimate`.
+
+1. Testing tracking and getting unique events
+
+Trigger events in rails console by using `track_event` method
+
+ ```ruby
+ Gitlab::UsageDataCounters::HLLRedisCounter.track_event('users_viewing_compliance_audit_events', values: 1)
+ Gitlab::UsageDataCounters::HLLRedisCounter.track_event('users_viewing_compliance_audit_events', values: [2, 3])
+ ```
+
+Next, get the unique events for the current week.
+
+ ```ruby
+ # Get unique events for metric for current_week
+ Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names: 'users_viewing_compliance_audit_events',
+ start_date: Date.current.beginning_of_week, end_date: Date.current.next_week)
+ ```
+
+##### Recommendations
+
+We have the following recommendations for [adding new events](#add-new-events):
+
+- Event aggregation: weekly.
+- Key expiry time:
+ - Daily: 29 days.
+ - Weekly: 42 days.
+- When adding new metrics, use a [feature flag](../../operations/feature_flags.md) to control the impact.
+- For feature flags triggered by another service, set `default_enabled: false`,
+ - Events can be triggered using the `UsageData` API, which helps when there are > 10 events per change
+
+##### Enable or disable Redis HLL tracking
+
+Events are tracked behind optional [feature flags](../feature_flags/index.md) due to concerns for Redis performance and scalability.
+
+For a full list of events and corresponding feature flags see, [known_events](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events/) files.
+
+To enable or disable tracking for specific event in <https://gitlab.com> or <https://about.staging.gitlab.com>, run commands such as the following to
+[enable or disable the corresponding feature](../feature_flags/index.md).
+
+```shell
+/chatops run feature set <feature_name> true
+/chatops run feature set <feature_name> false
+```
+
+We can also disable tracking completely by using the global flag:
+
+```shell
+/chatops run feature set redis_hll_tracking true
+/chatops run feature set redis_hll_tracking false
+```
+
+##### Known events are added automatically in Service Data payload
+
+All events added in [`known_events/common.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events/common.yml) are automatically added to Service Data generation under the `redis_hll_counters` key. This column is stored in [version-app as a JSON](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/db/schema.rb#L209).
+For each event we add metrics for the weekly and monthly time frames, and totals for each where applicable:
+
+- `#{event_name}_weekly`: Data for 7 days for daily [aggregation](#add-new-events) events and data for the last complete week for weekly [aggregation](#add-new-events) events.
+- `#{event_name}_monthly`: Data for 28 days for daily [aggregation](#add-new-events) events and data for the last 4 complete weeks for weekly [aggregation](#add-new-events) events.
+
+Redis HLL implementation calculates automatic total metrics, if there are more than one metric for the same category, aggregation, and Redis slot.
+
+- `#{category}_total_unique_counts_weekly`: Total unique counts for events in the same category for the last 7 days or the last complete week, if events are in the same Redis slot and we have more than one metric.
+- `#{category}_total_unique_counts_monthly`: Total unique counts for events in same category for the last 28 days or the last 4 complete weeks, if events are in the same Redis slot and we have more than one metric.
+
+Example of `redis_hll_counters` data:
+
+```ruby
+{:redis_hll_counters=>
+ {"compliance"=>
+ {"users_viewing_compliance_dashboard_weekly"=>0,
+ "users_viewing_compliance_dashboard_monthly"=>0,
+ "users_viewing_compliance_audit_events_weekly"=>0,
+ "users_viewing_audit_events_monthly"=>0,
+ "compliance_total_unique_counts_weekly"=>0,
+ "compliance_total_unique_counts_monthly"=>0},
+ "analytics"=>
+ {"users_viewing_analytics_group_devops_adoption_weekly"=>0,
+ "users_viewing_analytics_group_devops_adoption_monthly"=>0,
+ "analytics_total_unique_counts_weekly"=>0,
+ "analytics_total_unique_counts_monthly"=>0},
+ "ide_edit"=>
+ {"users_editing_by_web_ide_weekly"=>0,
+ "users_editing_by_web_ide_monthly"=>0,
+ "users_editing_by_sfe_weekly"=>0,
+ "users_editing_by_sfe_monthly"=>0,
+ "ide_edit_total_unique_counts_weekly"=>0,
+ "ide_edit_total_unique_counts_monthly"=>0}
+ }
+```
+
+Example:
+
+```ruby
+# Redis Counters
+redis_usage_data(Gitlab::UsageDataCounters::WikiPageCounter)
+redis_usage_data { ::Gitlab::UsageCounters::PodLogs.usage_totals[:total] }
+
+# Define events in common.yml https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events/common.yml
+
+# Tracking events
+Gitlab::UsageDataCounters::HLLRedisCounter.track_event('users_expanding_vulnerabilities', values: visitor_id)
+
+# Get unique events for metric
+redis_usage_data { Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names: 'users_expanding_vulnerabilities', start_date: 28.days.ago, end_date: Date.current) }
+```
+
+### Alternative counters
+
+Handles `StandardError` and fallbacks into -1 this way not all measures fail if we encounter one exception.
+Mainly used for settings and configurations.
+
+Method:
+
+```ruby
+alt_usage_data(value = nil, fallback: -1, &block)
+```
+
+Arguments:
+
+- `value`: a simple static value in which case the value is simply returned.
+- or a `block`: which is evaluated
+- `fallback: -1`: the common value used for any metrics that are failing.
+
+Example:
+
+```ruby
+alt_usage_data { Gitlab::VERSION }
+alt_usage_data { Gitlab::CurrentSettings.uuid }
+alt_usage_data(999)
+```
+
+### Add counters to build new metrics
+
+When adding the results of two counters, use the `add` Service Data method that
+handles fallback values and exceptions. It also generates a valid [SQL export](index.md#export-service-ping-sql-queries-and-definitions).
+
+Example:
+
+```ruby
+add(User.active, User.bot)
+```
+
+### Prometheus queries
+
+In those cases where operational metrics should be part of Service Ping, a database or Redis query is unlikely
+to provide useful data. Instead, Prometheus might be more appropriate, because most GitLab architectural
+components publish metrics to it that can be queried back, aggregated, and included as Service Data.
+
+NOTE:
+Prometheus as a data source for Service Ping is only available for single-node Omnibus installations
+that are running the [bundled Prometheus](../../administration/monitoring/prometheus/index.md) instance.
+
+To query Prometheus for metrics, a helper method is available to `yield` a fully configured
+`PrometheusClient`, given it is available as per the note above:
+
+```ruby
+with_prometheus_client do |client|
+ response = client.query('<your query>')
+ ...
+end
+```
+
+Refer to [the `PrometheusClient` definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/prometheus_client.rb)
+for how to use its API to query for data.
+
+### Fallback values for Service Ping
+
+We return fallback values in these cases:
+
+| Case | Value |
+|-----------------------------|-------|
+| Deprecated Metric | -1000 |
+| Timeouts, general failures | -1 |
+| Standard errors in counters | -2 |
+
## Name and place the metric
Add the metric in one of the top-level keys:
@@ -159,7 +819,7 @@ To set up Service Ping locally, you must:
## Test Prometheus-based Service Ping
-If the data submitted includes metrics [queried from Prometheus](index.md#prometheus-queries)
+If the data submitted includes metrics [queried from Prometheus](#prometheus-queries)
you want to inspect and verify, you must:
- Ensure that a Prometheus server is running locally.
@@ -208,3 +868,197 @@ However, it has the following limitations:
with any of the other running services. That is not how node metrics are reported in a production setup, where `node_exporter`
always runs as a process alongside other GitLab components on any given node. For Service Ping, none of the node data would therefore
appear to be associated to any of the services running, because they all appear to be running on different hosts. To alleviate this problem, the `node_exporter` in GCK was arbitrarily "assigned" to the `web` service, meaning only for this service `node_*` metrics appears in Service Ping.
+
+## Aggregated metrics
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/45979) in GitLab 13.6.
+
+WARNING:
+This feature is intended solely for internal GitLab use.
+
+To add data for aggregated metrics to the Service Ping payload, add a corresponding definition to:
+
+- [`config/metrics/aggregates/*.yaml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/aggregates/) for metrics available in the Community Edition.
+- [`ee/config/metrics/aggregates/*.yaml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/aggregates/) for metrics available in the Enterprise Edition.
+
+Each aggregate definition includes following parts:
+
+- `name`: Unique name under which the aggregate metric is added to the Service Ping payload.
+- `operator`: Operator that defines how the aggregated metric data is counted. Available operators are:
+ - `OR`: Removes duplicates and counts all entries that triggered any of listed events.
+ - `AND`: Removes duplicates and counts all elements that were observed triggering all of following events.
+- `time_frame`: One or more valid time frames. Use these to limit the data included in aggregated metric to events within a specific date-range. Valid time frames are:
+ - `7d`: Last seven days of data.
+ - `28d`: Last twenty eight days of data.
+ - `all`: All historical data, only available for `database` sourced aggregated metrics.
+- `source`: Data source used to collect all events data included in aggregated metric. Valid data sources are:
+ - [`database`](#database-sourced-aggregated-metrics)
+ - [`redis`](#redis-sourced-aggregated-metrics)
+- `events`: list of events names to aggregate into metric. All events in this list must
+ relay on the same data source. Additional data source requirements are described in the
+ [Database sourced aggregated metrics](#database-sourced-aggregated-metrics) and
+ [Redis sourced aggregated metrics](#redis-sourced-aggregated-metrics) sections.
+- `feature_flag`: Name of [development feature flag](../feature_flags/index.md#development-type)
+ that is checked before metrics aggregation is performed. Corresponding feature flag
+ should have `default_enabled` attribute set to `false`. The `feature_flag` attribute
+ is optional and can be omitted. When `feature_flag` is missing, no feature flag is checked.
+
+Example aggregated metric entries:
+
+```yaml
+- name: example_metrics_union
+ operator: OR
+ events:
+ - 'users_expanding_secure_security_report'
+ - 'users_expanding_testing_code_quality_report'
+ - 'users_expanding_testing_accessibility_report'
+ source: redis
+ time_frame:
+ - 7d
+ - 28d
+- name: example_metrics_intersection
+ operator: AND
+ source: database
+ time_frame:
+ - 28d
+ - all
+ events:
+ - 'dependency_scanning_pipeline_all_time'
+ - 'container_scanning_pipeline_all_time'
+ feature_flag: example_aggregated_metric
+```
+
+Aggregated metrics collected in `7d` and `28d` time frames are added into Service Ping payload under the `aggregated_metrics` sub-key in the `counts_weekly` and `counts_monthly` top level keys.
+
+```ruby
+{
+ :counts_monthly => {
+ :deployments => 1003,
+ :successful_deployments => 78,
+ :failed_deployments => 275,
+ :packages => 155,
+ :personal_snippets => 2106,
+ :project_snippets => 407,
+ :promoted_issues => 719,
+ :aggregated_metrics => {
+ :example_metrics_union => 7,
+ :example_metrics_intersection => 2
+ },
+ :snippets => 2513
+ }
+}
+```
+
+Aggregated metrics for `all` time frame are present in the `count` top level key, with the `aggregate_` prefix added to their name.
+
+For example:
+
+`example_metrics_intersection`
+
+Becomes:
+
+`counts.aggregate_example_metrics_intersection`
+
+```ruby
+{
+ :counts => {
+ :deployments => 11003,
+ :successful_deployments => 178,
+ :failed_deployments => 1275,
+ :aggregate_example_metrics_intersection => 12
+ }
+}
+```
+
+### Redis sourced aggregated metrics
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/45979) in GitLab 13.6.
+
+To declare the aggregate of events collected with [Redis HLL Counters](#redis-hll-counters),
+you must fulfill the following requirements:
+
+1. All events listed at `events` attribute must come from
+ [`known_events/*.yml`](#known-events-are-added-automatically-in-service-data-payload) files.
+1. All events listed at `events` attribute must have the same `redis_slot` attribute.
+1. All events listed at `events` attribute must have the same `aggregation` attribute.
+1. `time_frame` does not include `all` value, which is unavailable for Redis sourced aggregated metrics.
+
+### Database sourced aggregated metrics
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52784) in GitLab 13.9.
+> - It's [deployed behind a feature flag](../../user/feature_flags.md), disabled by default.
+> - It's enabled on GitLab.com.
+
+To declare an aggregate of metrics based on events collected from database, follow
+these steps:
+
+1. [Persist the metrics for aggregation](#persist-metrics-for-aggregation).
+1. [Add new aggregated metric definition](#add-new-aggregated-metric-definition).
+
+#### Persist metrics for aggregation
+
+Only metrics calculated with [Estimated Batch Counters](#estimated-batch-counters)
+can be persisted for database sourced aggregated metrics. To persist a metric,
+inject a Ruby block into the
+[estimate_batch_distinct_count](#estimate_batch_distinct_count-method) method.
+This block should invoke the
+`Gitlab::Usage::Metrics::Aggregates::Sources::PostgresHll.save_aggregated_metrics`
+[method](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage/metrics/aggregates/sources/postgres_hll.rb#L21),
+which stores `estimate_batch_distinct_count` results for future use in aggregated metrics.
+
+The `Gitlab::Usage::Metrics::Aggregates::Sources::PostgresHll.save_aggregated_metrics`
+method accepts the following arguments:
+
+- `metric_name`: The name of metric to use for aggregations. Should be the same
+ as the key under which the metric is added into Service Ping.
+- `recorded_at_timestamp`: The timestamp representing the moment when a given
+ Service Ping payload was collected. You should use the convenience method `recorded_at`
+ to fill `recorded_at_timestamp` argument, like this: `recorded_at_timestamp: recorded_at`
+- `time_period`: The time period used to build the `relation` argument passed into
+ `estimate_batch_distinct_count`. To collect the metric with all available historical
+ data, set a `nil` value as time period: `time_period: nil`.
+- `data`: HyperLogLog buckets structure representing unique entries in `relation`.
+ The `estimate_batch_distinct_count` method always passes the correct argument
+ into the block, so `data` argument must always have a value equal to block argument,
+ like this: `data: result`
+
+Example metrics persistence:
+
+```ruby
+class UsageData
+ def count_secure_pipelines(time_period)
+ ...
+ relation = ::Security::Scan.latest_successful_by_build.by_scan_types(scan_type).where(security_scans: time_period)
+
+ pipelines_with_secure_jobs['dependency_scanning_pipeline'] = estimate_batch_distinct_count(relation, :commit_id, batch_size: 1000, start: start_id, finish: finish_id) do |result|
+ ::Gitlab::Usage::Metrics::Aggregates::Sources::PostgresHll
+ .save_aggregated_metrics(metric_name: 'dependency_scanning_pipeline', recorded_at_timestamp: recorded_at, time_period: time_period, data: result)
+ end
+ end
+end
+```
+
+#### Add new aggregated metric definition
+
+After all metrics are persisted, you can add an aggregated metric definition at
+[`aggregated_metrics/`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/aggregates/).
+
+To declare the aggregate of metrics collected with [Estimated Batch Counters](#estimated-batch-counters),
+you must fulfill the following requirements:
+
+- Metrics names listed in the `events:` attribute, have to use the same names you passed in the `metric_name` argument while persisting metrics in previous step.
+- Every metric listed in the `events:` attribute, has to be persisted for **every** selected `time_frame:` value.
+
+Example definition:
+
+```yaml
+- name: example_metrics_intersection_database_sourced
+ operator: AND
+ source: database
+ events:
+ - 'dependency_scanning_pipeline'
+ - 'container_scanning_pipeline'
+ time_frame:
+ - 28d
+ - all
+```
diff --git a/doc/development/service_ping/index.md b/doc/development/service_ping/index.md
index 816743a3e97..0a94fa2ff6c 100644
--- a/doc/development/service_ping/index.md
+++ b/doc/development/service_ping/index.md
@@ -66,7 +66,7 @@ We use the following terminology to describe the Service Ping components:
> Introduced in GitLab 14.1.
-Starting with GitLab version 14.1, free self-managed users running [GitLab EE](../ee_features.md) can receive paid features by registering with GitLab and sending us activity data via [Service Ping](#what-is-service-ping).
+Starting with GitLab version 14.1, free self-managed users running [GitLab EE](../ee_features.md) can receive paid features by registering with GitLab and sending us activity data via [Service Ping](#what-is-service-ping). Features introduced here do not remove the feature from its paid tier. Users can continue to access the features in a paid tier without sharing usage data.
The paid feature available in this offering is [Email from GitLab](../../tools/email.md).
Administrators can use this [Premium](https://about.gitlab.com/pricing/premium/) feature to streamline
@@ -85,7 +85,7 @@ Registration is not yet required for participation, but will be added in a futur
You can view the exact JSON payload sent to GitLab Inc. in the Admin Area. To view the payload:
1. Sign in as a user with the [Administrator](../../user/permissions.md) role.
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Metrics and profiling**.
1. Expand the **Usage statistics** section.
1. Select **Preview payload**.
@@ -107,7 +107,7 @@ configuration file.
To disable Service Ping in the GitLab UI:
1. Sign in as a user with the [Administrator](../../user/permissions.md) role.
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Metrics and profiling**.
1. Expand the **Usage statistics** section.
1. Clear the **Enable service ping** checkbox.
@@ -222,844 +222,7 @@ We also collect metrics specific to [Geo](../../administration/geo/index.md) sec
## Implementing Service Ping
-Service Ping consists of two kinds of data, counters and observations. Counters track how often a certain event
-happened over time, such as how many CI pipelines have run. They are monotonic and always trend up.
-Observations are facts collected from one or more GitLab instances and can carry arbitrary data. There are no
-general guidelines around how to collect those, due to the individual nature of that data.
-
-### Types of counters
-
-There are several types of counters in `usage_data.rb`:
-
-- **Ordinary Batch Counters:** Simple count of a given ActiveRecord_Relation
-- **Distinct Batch Counters:** Distinct count of a given ActiveRecord_Relation in a given column
-- **Sum Batch Counters:** Sum the values of a given ActiveRecord_Relation in a given column
-- **Alternative Counters:** Used for settings and configurations
-- **Redis Counters:** Used for in-memory counts.
-
-NOTE:
-Only use the provided counter methods. Each counter method contains a built-in fail-safe mechanism that isolates each counter to avoid breaking the entire Service Ping process.
-
-### Instrumentation classes
-
-We recommend you use [instrumentation classes](metrics_instrumentation.md) in `usage_data.rb` where possible.
-
-For example, we have the following instrumentation class:
-`lib/gitlab/usage/metrics/instrumentations/count_boards_metric.rb`.
-
-You should add it to `usage_data.rb` as follows:
-
-```ruby
-boards: add_metric('CountBoardsMetric', time_frame: 'all'),
-```
-
-### Batch counting
-
-For large tables, PostgreSQL can take a long time to count rows due to MVCC [(Multi-version Concurrency Control)](https://en.wikipedia.org/wiki/Multiversion_concurrency_control). Batch counting is a counting method where a single large query is broken into multiple smaller queries. For example, instead of a single query querying 1,000,000 records, with batch counting, you can execute 100 queries of 10,000 records each. Batch counting is useful for avoiding database timeouts as each batch query is significantly shorter than one single long running query.
-
-For GitLab.com, there are extremely large tables with 15 second query timeouts, so we use batch counting to avoid encountering timeouts. Here are the sizes of some GitLab.com tables:
-
-| Table | Row counts in millions |
-|------------------------------|------------------------|
-| `merge_request_diff_commits` | 2280 |
-| `ci_build_trace_sections` | 1764 |
-| `merge_request_diff_files` | 1082 |
-| `events` | 514 |
-
-The following operation methods are available:
-
-- [Ordinary batch counters](#ordinary-batch-counters)
-- [Distinct batch counters](#distinct-batch-counters)
-- [Sum batch operation](#sum-batch-operation)
-- [Add operation](#add-operation)
-- [Estimated batch counters](#estimated-batch-counters)
-
-Batch counting requires indexes on columns to calculate max, min, and range queries. In some cases,
-you may need to add a specialized index on the columns involved in a counter.
-
-### Ordinary batch counters
-
-Handles `ActiveRecord::StatementInvalid` error
-
-Simple count of a given `ActiveRecord_Relation`, does a non-distinct batch count, smartly reduces `batch_size`, and handles errors.
-
-Method: `count(relation, column = nil, batch: true, start: nil, finish: nil)`
-
-Arguments:
-
-- `relation` the ActiveRecord_Relation to perform the count
-- `column` the column to perform the count on, by default is the primary key
-- `batch`: default `true` to use batch counting
-- `start`: custom start of the batch counting to avoid complex min calculations
-- `end`: custom end of the batch counting to avoid complex min calculations
-
-Examples:
-
-```ruby
-count(User.active)
-count(::Clusters::Cluster.aws_installed.enabled, :cluster_id)
-count(::Clusters::Cluster.aws_installed.enabled, :cluster_id, start: ::Clusters::Cluster.minimum(:id), finish: ::Clusters::Cluster.maximum(:id))
-```
-
-### Distinct batch counters
-
-Handles `ActiveRecord::StatementInvalid` error
-
-Distinct count of a given `ActiveRecord_Relation` on given column, a distinct batch count, smartly reduces `batch_size`, and handles errors.
-
-Method: `distinct_count(relation, column = nil, batch: true, batch_size: nil, start: nil, finish: nil)`
-
-Arguments:
-
-- `relation` the ActiveRecord_Relation to perform the count
-- `column` the column to perform the distinct count, by default is the primary key
-- `batch`: default `true` to use batch counting
-- `batch_size`: if none set it uses default value 10000 from `Gitlab::Database::BatchCounter`
-- `start`: custom start of the batch counting to avoid complex min calculations
-- `end`: custom end of the batch counting to avoid complex min calculations
-
-WARNING:
-Counting over non-unique columns can lead to performance issues. For more information, see the [iterating tables in batches](../iterating_tables_in_batches.md) guide.
-
-Examples:
-
-```ruby
-distinct_count(::Project, :creator_id)
-distinct_count(::Note.with_suggestions.where(time_period), :author_id, start: ::User.minimum(:id), finish: ::User.maximum(:id))
-distinct_count(::Clusters::Applications::CertManager.where(time_period).available.joins(:cluster), 'clusters.user_id')
-```
-
-### Sum batch operation
-
-Handles `ActiveRecord::StatementInvalid` error
-
-Sum the values of a given ActiveRecord_Relation on given column and handles errors.
-
-Method: `sum(relation, column, batch_size: nil, start: nil, finish: nil)`
-
-Arguments:
-
-- `relation` the ActiveRecord_Relation to perform the operation
-- `column` the column to sum on
-- `batch_size`: if none set it uses default value 1000 from `Gitlab::Database::BatchCounter`
-- `start`: custom start of the batch counting to avoid complex min calculations
-- `end`: custom end of the batch counting to avoid complex min calculations
-
-Examples:
-
-```ruby
-sum(JiraImportState.finished, :imported_issues_count)
-```
-
-### Grouping and batch operations
-
-The `count`, `distinct_count`, and `sum` batch counters can accept an `ActiveRecord::Relation`
-object, which groups by a specified column. With a grouped relation, the methods do batch counting,
-handle errors, and returns a hash table of key-value pairs.
-
-Examples:
-
-```ruby
-count(Namespace.group(:type))
-# returns => {nil=>179, "Group"=>54}
-
-distinct_count(Project.group(:visibility_level), :creator_id)
-# returns => {0=>1, 10=>1, 20=>11}
-
-sum(Issue.group(:state_id), :weight))
-# returns => {1=>3542, 2=>6820}
-```
-
-### Add operation
-
-Handles `StandardError`.
-
-Returns `-1` if any of the arguments are `-1`.
-
-Sum the values given as parameters.
-
-Method: `add(*args)`
-
-Examples:
-
-```ruby
-project_imports = distinct_count(::Project.where.not(import_type: nil), :creator_id)
-bulk_imports = distinct_count(::BulkImport, :user_id)
-
- add(project_imports, bulk_imports)
-```
-
-### Estimated batch counters
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/48233) in GitLab 13.7.
-
-Estimated batch counter functionality handles `ActiveRecord::StatementInvalid` errors
-when used through the provided `estimate_batch_distinct_count` method.
-Errors return a value of `-1`.
-
-WARNING:
-This functionality estimates a distinct count of a specific ActiveRecord_Relation in a given column,
-which uses the [HyperLogLog](http://algo.inria.fr/flajolet/Publications/FlFuGaMe07.pdf) algorithm.
-As the HyperLogLog algorithm is probabilistic, the **results always include error**.
-The highest encountered error rate is 4.9%.
-
-When correctly used, the `estimate_batch_distinct_count` method enables efficient counting over
-columns that contain non-unique values, which can not be assured by other counters.
-
-#### estimate_batch_distinct_count method
-
-Method: `estimate_batch_distinct_count(relation, column = nil, batch_size: nil, start: nil, finish: nil)`
-
-The [method](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/utils/usage_data.rb#L63)
-includes the following arguments:
-
-- `relation`: The ActiveRecord_Relation to perform the count.
-- `column`: The column to perform the distinct count. The default is the primary key.
-- `batch_size`: From `Gitlab::Database::PostgresHll::BatchDistinctCounter::DEFAULT_BATCH_SIZE`. Default value: 10,000.
-- `start`: The custom start of the batch count, to avoid complex minimum calculations.
-- `finish`: The custom end of the batch count to avoid complex maximum calculations.
-
-The method includes the following prerequisites:
-
-1. The supplied `relation` must include the primary key defined as the numeric column.
- For example: `id bigint NOT NULL`.
-1. The `estimate_batch_distinct_count` can handle a joined relation. To use its ability to
- count non-unique columns, the joined relation **must not** have a one-to-many relationship,
- such as `has_many :boards`.
-1. Both `start` and `finish` arguments should always represent primary key relationship values,
- even if the estimated count refers to another column, for example:
-
- ```ruby
- estimate_batch_distinct_count(::Note, :author_id, start: ::Note.minimum(:id), finish: ::Note.maximum(:id))
- ```
-
-Examples:
-
-1. Simple execution of estimated batch counter, with only relation provided,
- returned value represents estimated number of unique values in `id` column
- (which is the primary key) of `Project` relation:
-
- ```ruby
- estimate_batch_distinct_count(::Project)
- ```
-
-1. Execution of estimated batch counter, where provided relation has applied
- additional filter (`.where(time_period)`), number of unique values estimated
- in custom column (`:author_id`), and parameters: `start` and `finish` together
- apply boundaries that defines range of provided relation to analyze:
-
- ```ruby
- estimate_batch_distinct_count(::Note.with_suggestions.where(time_period), :author_id, start: ::Note.minimum(:id), finish: ::Note.maximum(:id))
- ```
-
-1. Execution of estimated batch counter with joined relation (`joins(:cluster)`),
- for a custom column (`'clusters.user_id'`):
-
- ```ruby
- estimate_batch_distinct_count(::Clusters::Applications::CertManager.where(time_period).available.joins(:cluster), 'clusters.user_id')
- ```
-
-When instrumenting metric with usage of estimated batch counter please add
-`_estimated` suffix to its name, for example:
-
-```ruby
- "counts": {
- "ci_builds_estimated": estimate_batch_distinct_count(Ci::Build),
- ...
-```
-
-### Redis counters
-
-Handles `::Redis::CommandError` and `Gitlab::UsageDataCounters::BaseCounter::UnknownEvent`
-returns -1 when a block is sent or hash with all values -1 when a `counter(Gitlab::UsageDataCounters)` is sent
-different behavior due to 2 different implementations of Redis counter
-
-Method: `redis_usage_data(counter, &block)`
-
-Arguments:
-
-- `counter`: a counter from `Gitlab::UsageDataCounters`, that has `fallback_totals` method implemented
-- or a `block`: which is evaluated
-
-#### Ordinary Redis counters
-
-Examples of implementation:
-
-- Using Redis methods [`INCR`](https://redis.io/commands/incr), [`GET`](https://redis.io/commands/get), and [`Gitlab::UsageDataCounters::WikiPageCounter`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/wiki_page_counter.rb)
-- Using Redis methods [`HINCRBY`](https://redis.io/commands/hincrby), [`HGETALL`](https://redis.io/commands/hgetall), and [`Gitlab::UsageCounters::PodLogs`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_counters/pod_logs.rb)
-
-##### UsageData API tracking
-
-<!-- There's nearly identical content in `##### Adding new events`. If you fix errors here, you may need to fix the same errors in the other location. -->
-
-1. Track event using `UsageData` API
-
- Increment event count using ordinary Redis counter, for given event name.
-
- Tracking events using the `UsageData` API requires the `usage_data_api` feature flag to be enabled, which is enabled by default.
-
- API requests are protected by checking for a valid CSRF token.
-
- To be able to increment the values, the related feature `usage_data_<event_name>` should be enabled.
-
- ```plaintext
- POST /usage_data/increment_counter
- ```
-
- | Attribute | Type | Required | Description |
- | :-------- | :--- | :------- | :---------- |
- | `event` | string | yes | The event name it should be tracked |
-
- Response:
-
- - `200` if event was tracked
- - `400 Bad request` if event parameter is missing
- - `401 Unauthorized` if user is not authenticated
- - `403 Forbidden` for invalid CSRF token provided
-
-1. Track events using JavaScript/Vue API helper which calls the API above
-
- Note that `usage_data_api` and `usage_data_#{event_name}` should be enabled to be able to track events
-
- ```javascript
- import api from '~/api';
-
- api.trackRedisCounterEvent('my_already_defined_event_name'),
- ```
-
-#### Redis HLL counters
-
-WARNING:
-HyperLogLog (HLL) is a probabilistic algorithm and its **results always includes some small error**. According to [Redis documentation](https://redis.io/commands/pfcount), data from
-used HLL implementation is "approximated with a standard error of 0.81%".
-
-With `Gitlab::UsageDataCounters::HLLRedisCounter` we have available data structures used to count unique values.
-
-Implemented using Redis methods [PFADD](https://redis.io/commands/pfadd) and [PFCOUNT](https://redis.io/commands/pfcount).
-
-##### Add new events
-
-1. Define events in [`known_events`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events/).
-
- Example event:
-
- ```yaml
- - name: users_creating_epics
- category: epics_usage
- redis_slot: users
- aggregation: weekly
- feature_flag: track_epics_activity
- ```
-
- Keys:
-
- - `name`: unique event name.
-
- Name format for Redis HLL events `<name>_<redis_slot>`.
-
- [See Metric name](metrics_dictionary.md#metric-name) for a complete guide on metric naming suggestion.
-
- Consider including in the event's name the Redis slot to be able to count totals for a specific category.
-
- Example names: `users_creating_epics`, `users_triggering_security_scans`.
-
- - `category`: event category. Used for getting total counts for events in a category, for easier
- access to a group of events.
- - `redis_slot`: optional Redis slot. Default value: event name. Only event data that is stored in the same slot
- can be aggregated. Ensure keys are in the same slot. For example:
- `users_creating_epics` with `redis_slot: 'users'` builds Redis key
- `{users}_creating_epics-2020-34`. If `redis_slot` is not defined the Redis key will
- be `{users_creating_epics}-2020-34`.
- Recommended slots to use are: `users`, `projects`. This is the value we count.
- - `expiry`: expiry time in days. Default: 29 days for daily aggregation and 6 weeks for weekly
- aggregation.
- - `aggregation`: may be set to a `:daily` or `:weekly` key. Defines how counting data is stored in Redis.
- Aggregation on a `daily` basis does not pull more fine grained data.
- - `feature_flag`: optional `default_enabled: :yaml`. If no feature flag is set then the tracking is enabled. One feature flag can be used for multiple events. For details, see our [GitLab internal Feature flags](../feature_flags/index.md) documentation. The feature flags are owned by the group adding the event tracking.
-
-1. Use one of the following methods to track the event:
-
- - In the controller using the `RedisTracking` module and the following format:
-
- ```ruby
- track_redis_hll_event(*controller_actions, name:, if: nil, &block)
- ```
-
- Arguments:
-
- - `controller_actions`: the controller actions to track.
- - `name`: the event name.
- - `if`: optional custom conditions. Uses the same format as Rails callbacks.
- - `&block`: optional block that computes and returns the `custom_id` that we want to track. This overrides the `visitor_id`.
-
- Example:
-
- ```ruby
- # controller
- class ProjectsController < Projects::ApplicationController
- include RedisTracking
-
- skip_before_action :authenticate_user!, only: :show
- track_redis_hll_event :index, :show, name: 'users_visiting_projects'
-
- def index
- render html: 'index'
- end
-
- def new
- render html: 'new'
- end
-
- def show
- render html: 'show'
- end
- end
- ```
-
- - In the API using the `increment_unique_values(event_name, values)` helper method.
-
- Arguments:
-
- - `event_name`: the event name.
- - `values`: the values counted. Can be one value or an array of values.
-
- Example:
-
- ```ruby
- get ':id/registry/repositories' do
- repositories = ContainerRepositoriesFinder.new(
- user: current_user, subject: user_group
- ).execute
-
- increment_unique_values('users_listing_repositories', current_user.id)
-
- present paginate(repositories), with: Entities::ContainerRegistry::Repository, tags: params[:tags], tags_count: params[:tags_count]
- end
- ```
-
- - Using `track_usage_event(event_name, values)` in services and GraphQL.
-
- Increment unique values count using Redis HLL, for a given event name.
-
- Examples:
-
- - [Track usage event for an incident in a service](https://gitlab.com/gitlab-org/gitlab/-/blob/v13.8.3-ee/app/services/issues/update_service.rb#L66)
- - [Track usage event for an incident in GraphQL](https://gitlab.com/gitlab-org/gitlab/-/blob/v13.8.3-ee/app/graphql/mutations/alert_management/update_alert_status.rb#L16)
-
- ```ruby
- track_usage_event(:incident_management_incident_created, current_user.id)
- ```
-
- - Using the `UsageData` API.
- <!-- There's nearly identical content in `##### UsageData API Tracking`. If you find / fix errors here, you may need to fix errors in that section too. -->
-
- Increment unique users count using Redis HLL, for a given event name.
-
- To track events using the `UsageData` API, ensure the `usage_data_api` feature flag
- is set to `default_enabled: true`. Enabled by default in GitLab 13.7 and later.
-
- API requests are protected by checking for a valid CSRF token.
-
- ```plaintext
- POST /usage_data/increment_unique_users
- ```
-
- | Attribute | Type | Required | Description |
- | :-------- | :--- | :------- | :---------- |
- | `event` | string | yes | The event name to track |
-
- Response:
-
- - `200` if the event was tracked, or if tracking failed for any reason.
- - `400 Bad request` if an event parameter is missing.
- - `401 Unauthorized` if the user is not authenticated.
- - `403 Forbidden` if an invalid CSRF token is provided.
-
- - Using the JavaScript/Vue API helper, which calls the `UsageData` API.
-
- To track events using the `UsageData` API, ensure the `usage_data_api` feature flag
- is set to `default_enabled: true`. Enabled by default in GitLab 13.7 and later.
-
- Example for an existing event already defined in [known events](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events/):
-
- ```javascript
- import api from '~/api';
-
- api.trackRedisHllUserEvent('my_already_defined_event_name'),
- ```
-
-1. Get event data using `Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names:, start_date:, end_date:, context: '')`.
-
- Arguments:
-
- - `event_names`: the list of event names.
- - `start_date`: start date of the period for which we want to get event data.
- - `end_date`: end date of the period for which we want to get event data.
- - `context`: context of the event. Allowed values are `default`, `free`, `bronze`, `silver`, `gold`, `starter`, `premium`, `ultimate`.
-
-1. Testing tracking and getting unique events
-
-Trigger events in rails console by using `track_event` method
-
- ```ruby
- Gitlab::UsageDataCounters::HLLRedisCounter.track_event('users_viewing_compliance_audit_events', values: 1)
- Gitlab::UsageDataCounters::HLLRedisCounter.track_event('users_viewing_compliance_audit_events', values: [2, 3])
- ```
-
-Next, get the unique events for the current week.
-
- ```ruby
- # Get unique events for metric for current_week
- Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names: 'users_viewing_compliance_audit_events',
- start_date: Date.current.beginning_of_week, end_date: Date.current.next_week)
- ```
-
-##### Recommendations
-
-We have the following recommendations for [adding new events](#add-new-events):
-
-- Event aggregation: weekly.
-- Key expiry time:
- - Daily: 29 days.
- - Weekly: 42 days.
-- When adding new metrics, use a [feature flag](../../operations/feature_flags.md) to control the impact.
-- For feature flags triggered by another service, set `default_enabled: false`,
- - Events can be triggered using the `UsageData` API, which helps when there are > 10 events per change
-
-##### Enable or disable Redis HLL tracking
-
-Events are tracked behind optional [feature flags](../feature_flags/index.md) due to concerns for Redis performance and scalability.
-
-For a full list of events and corresponding feature flags see, [known_events](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events/) files.
-
-To enable or disable tracking for specific event in <https://gitlab.com> or <https://about.staging.gitlab.com>, run commands such as the following to
-[enable or disable the corresponding feature](../feature_flags/index.md).
-
-```shell
-/chatops run feature set <feature_name> true
-/chatops run feature set <feature_name> false
-```
-
-We can also disable tracking completely by using the global flag:
-
-```shell
-/chatops run feature set redis_hll_tracking true
-/chatops run feature set redis_hll_tracking false
-```
-
-##### Known events are added automatically in Service Data payload
-
-All events added in [`known_events/common.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events/common.yml) are automatically added to Service Data generation under the `redis_hll_counters` key. This column is stored in [version-app as a JSON](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/db/schema.rb#L209).
-For each event we add metrics for the weekly and monthly time frames, and totals for each where applicable:
-
-- `#{event_name}_weekly`: Data for 7 days for daily [aggregation](#add-new-events) events and data for the last complete week for weekly [aggregation](#add-new-events) events.
-- `#{event_name}_monthly`: Data for 28 days for daily [aggregation](#add-new-events) events and data for the last 4 complete weeks for weekly [aggregation](#add-new-events) events.
-
-Redis HLL implementation calculates automatic total metrics, if there are more than one metric for the same category, aggregation, and Redis slot.
-
-- `#{category}_total_unique_counts_weekly`: Total unique counts for events in the same category for the last 7 days or the last complete week, if events are in the same Redis slot and we have more than one metric.
-- `#{category}_total_unique_counts_monthly`: Total unique counts for events in same category for the last 28 days or the last 4 complete weeks, if events are in the same Redis slot and we have more than one metric.
-
-Example of `redis_hll_counters` data:
-
-```ruby
-{:redis_hll_counters=>
- {"compliance"=>
- {"users_viewing_compliance_dashboard_weekly"=>0,
- "users_viewing_compliance_dashboard_monthly"=>0,
- "users_viewing_compliance_audit_events_weekly"=>0,
- "users_viewing_audit_events_monthly"=>0,
- "compliance_total_unique_counts_weekly"=>0,
- "compliance_total_unique_counts_monthly"=>0},
- "analytics"=>
- {"users_viewing_analytics_group_devops_adoption_weekly"=>0,
- "users_viewing_analytics_group_devops_adoption_monthly"=>0,
- "analytics_total_unique_counts_weekly"=>0,
- "analytics_total_unique_counts_monthly"=>0},
- "ide_edit"=>
- {"users_editing_by_web_ide_weekly"=>0,
- "users_editing_by_web_ide_monthly"=>0,
- "users_editing_by_sfe_weekly"=>0,
- "users_editing_by_sfe_monthly"=>0,
- "ide_edit_total_unique_counts_weekly"=>0,
- "ide_edit_total_unique_counts_monthly"=>0}
- }
-```
-
-Example:
-
-```ruby
-# Redis Counters
-redis_usage_data(Gitlab::UsageDataCounters::WikiPageCounter)
-redis_usage_data { ::Gitlab::UsageCounters::PodLogs.usage_totals[:total] }
-
-# Define events in common.yml https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events/common.yml
-
-# Tracking events
-Gitlab::UsageDataCounters::HLLRedisCounter.track_event('users_expanding_vulnerabilities', values: visitor_id)
-
-# Get unique events for metric
-redis_usage_data { Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names: 'users_expanding_vulnerabilities', start_date: 28.days.ago, end_date: Date.current) }
-```
-
-### Alternative counters
-
-Handles `StandardError` and fallbacks into -1 this way not all measures fail if we encounter one exception.
-Mainly used for settings and configurations.
-
-Method: `alt_usage_data(value = nil, fallback: -1, &block)`
-
-Arguments:
-
-- `value`: a simple static value in which case the value is simply returned.
-- or a `block`: which is evaluated
-- `fallback: -1`: the common value used for any metrics that are failing.
-
-Example:
-
-```ruby
-alt_usage_data { Gitlab::VERSION }
-alt_usage_data { Gitlab::CurrentSettings.uuid }
-alt_usage_data(999)
-```
-
-### Add counters to build new metrics
-
-When adding the results of two counters, use the `add` Service Data method that
-handles fallback values and exceptions. It also generates a valid [SQL export](#export-service-ping-sql-queries-and-definitions).
-
-Example:
-
-```ruby
-add(User.active, User.bot)
-```
-
-### Prometheus queries
-
-In those cases where operational metrics should be part of Service Ping, a database or Redis query is unlikely
-to provide useful data. Instead, Prometheus might be more appropriate, because most GitLab architectural
-components publish metrics to it that can be queried back, aggregated, and included as Service Data.
-
-NOTE:
-Prometheus as a data source for Service Ping is only available for single-node Omnibus installations
-that are running the [bundled Prometheus](../../administration/monitoring/prometheus/index.md) instance.
-
-To query Prometheus for metrics, a helper method is available to `yield` a fully configured
-`PrometheusClient`, given it is available as per the note above:
-
-```ruby
-with_prometheus_client do |client|
- response = client.query('<your query>')
- ...
-end
-```
-
-Refer to [the `PrometheusClient` definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/prometheus_client.rb)
-for how to use its API to query for data.
-
-### Fallback values for Service Ping
-
-We return fallback values in these cases:
-
-| Case | Value |
-|-----------------------------|-------|
-| Deprecated Metric | -1000 |
-| Timeouts, general failures | -1 |
-| Standard errors in counters | -2 |
-
-## Aggregated metrics
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/45979) in GitLab 13.6.
-
-WARNING:
-This feature is intended solely for internal GitLab use.
-
-To add data for aggregated metrics to the Service Ping payload, add a corresponding definition to:
-
-- [`config/metrics/aggregates/*.yaml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/aggregates/) for metrics available in the Community Edition.
-- [`ee/config/metrics/aggregates/*.yaml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/aggregates/) for metrics available in the Enterprise Edition.
-
-Each aggregate definition includes following parts:
-
-- `name`: Unique name under which the aggregate metric is added to the Service Ping payload.
-- `operator`: Operator that defines how the aggregated metric data is counted. Available operators are:
- - `OR`: Removes duplicates and counts all entries that triggered any of listed events.
- - `AND`: Removes duplicates and counts all elements that were observed triggering all of following events.
-- `time_frame`: One or more valid time frames. Use these to limit the data included in aggregated metric to events within a specific date-range. Valid time frames are:
- - `7d`: Last seven days of data.
- - `28d`: Last twenty eight days of data.
- - `all`: All historical data, only available for `database` sourced aggregated metrics.
-- `source`: Data source used to collect all events data included in aggregated metric. Valid data sources are:
- - [`database`](#database-sourced-aggregated-metrics)
- - [`redis`](#redis-sourced-aggregated-metrics)
-- `events`: list of events names to aggregate into metric. All events in this list must
- relay on the same data source. Additional data source requirements are described in the
- [Database sourced aggregated metrics](#database-sourced-aggregated-metrics) and
- [Redis sourced aggregated metrics](#redis-sourced-aggregated-metrics) sections.
-- `feature_flag`: Name of [development feature flag](../feature_flags/index.md#development-type)
- that is checked before metrics aggregation is performed. Corresponding feature flag
- should have `default_enabled` attribute set to `false`. The `feature_flag` attribute
- is optional and can be omitted. When `feature_flag` is missing, no feature flag is checked.
-
-Example aggregated metric entries:
-
-```yaml
-- name: example_metrics_union
- operator: OR
- events:
- - 'users_expanding_secure_security_report'
- - 'users_expanding_testing_code_quality_report'
- - 'users_expanding_testing_accessibility_report'
- source: redis
- time_frame:
- - 7d
- - 28d
-- name: example_metrics_intersection
- operator: AND
- source: database
- time_frame:
- - 28d
- - all
- events:
- - 'dependency_scanning_pipeline_all_time'
- - 'container_scanning_pipeline_all_time'
- feature_flag: example_aggregated_metric
-```
-
-Aggregated metrics collected in `7d` and `28d` time frames are added into Service Ping payload under the `aggregated_metrics` sub-key in the `counts_weekly` and `counts_monthly` top level keys.
-
-```ruby
-{
- :counts_monthly => {
- :deployments => 1003,
- :successful_deployments => 78,
- :failed_deployments => 275,
- :packages => 155,
- :personal_snippets => 2106,
- :project_snippets => 407,
- :promoted_issues => 719,
- :aggregated_metrics => {
- :example_metrics_union => 7,
- :example_metrics_intersection => 2
- },
- :snippets => 2513
- }
-}
-```
-
-Aggregated metrics for `all` time frame are present in the `count` top level key, with the `aggregate_` prefix added to their name.
-
-For example:
-
-`example_metrics_intersection`
-
-Becomes:
-
-`counts.aggregate_example_metrics_intersection`
-
-```ruby
-{
- :counts => {
- :deployments => 11003,
- :successful_deployments => 178,
- :failed_deployments => 1275,
- :aggregate_example_metrics_intersection => 12
- }
-}
-```
-
-### Redis sourced aggregated metrics
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/45979) in GitLab 13.6.
-
-To declare the aggregate of events collected with [Redis HLL Counters](#redis-hll-counters),
-you must fulfill the following requirements:
-
-1. All events listed at `events` attribute must come from
- [`known_events/*.yml`](#known-events-are-added-automatically-in-service-data-payload) files.
-1. All events listed at `events` attribute must have the same `redis_slot` attribute.
-1. All events listed at `events` attribute must have the same `aggregation` attribute.
-1. `time_frame` does not include `all` value, which is unavailable for Redis sourced aggregated metrics.
-
-### Database sourced aggregated metrics
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52784) in GitLab 13.9.
-> - It's [deployed behind a feature flag](../../user/feature_flags.md), disabled by default.
-> - It's enabled on GitLab.com.
-
-To declare an aggregate of metrics based on events collected from database, follow
-these steps:
-
-1. [Persist the metrics for aggregation](#persist-metrics-for-aggregation).
-1. [Add new aggregated metric definition](#add-new-aggregated-metric-definition).
-
-#### Persist metrics for aggregation
-
-Only metrics calculated with [Estimated Batch Counters](#estimated-batch-counters)
-can be persisted for database sourced aggregated metrics. To persist a metric,
-inject a Ruby block into the
-[estimate_batch_distinct_count](#estimate_batch_distinct_count-method) method.
-This block should invoke the
-`Gitlab::Usage::Metrics::Aggregates::Sources::PostgresHll.save_aggregated_metrics`
-[method](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage/metrics/aggregates/sources/postgres_hll.rb#L21),
-which stores `estimate_batch_distinct_count` results for future use in aggregated metrics.
-
-The `Gitlab::Usage::Metrics::Aggregates::Sources::PostgresHll.save_aggregated_metrics`
-method accepts the following arguments:
-
-- `metric_name`: The name of metric to use for aggregations. Should be the same
- as the key under which the metric is added into Service Ping.
-- `recorded_at_timestamp`: The timestamp representing the moment when a given
- Service Ping payload was collected. You should use the convenience method `recorded_at`
- to fill `recorded_at_timestamp` argument, like this: `recorded_at_timestamp: recorded_at`
-- `time_period`: The time period used to build the `relation` argument passed into
- `estimate_batch_distinct_count`. To collect the metric with all available historical
- data, set a `nil` value as time period: `time_period: nil`.
-- `data`: HyperLogLog buckets structure representing unique entries in `relation`.
- The `estimate_batch_distinct_count` method always passes the correct argument
- into the block, so `data` argument must always have a value equal to block argument,
- like this: `data: result`
-
-Example metrics persistence:
-
-```ruby
-class UsageData
- def count_secure_pipelines(time_period)
- ...
- relation = ::Security::Scan.latest_successful_by_build.by_scan_types(scan_type).where(security_scans: time_period)
-
- pipelines_with_secure_jobs['dependency_scanning_pipeline'] = estimate_batch_distinct_count(relation, :commit_id, batch_size: 1000, start: start_id, finish: finish_id) do |result|
- ::Gitlab::Usage::Metrics::Aggregates::Sources::PostgresHll
- .save_aggregated_metrics(metric_name: 'dependency_scanning_pipeline', recorded_at_timestamp: recorded_at, time_period: time_period, data: result)
- end
- end
-end
-```
-
-#### Add new aggregated metric definition
-
-After all metrics are persisted, you can add an aggregated metric definition at
-[`aggregated_metrics/`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/aggregates/).
-
-To declare the aggregate of metrics collected with [Estimated Batch Counters](#estimated-batch-counters),
-you must fulfill the following requirements:
-
-- Metrics names listed in the `events:` attribute, have to use the same names you passed in the `metric_name` argument while persisting metrics in previous step.
-- Every metric listed in the `events:` attribute, has to be persisted for **every** selected `time_frame:` value.
-
-Example definition:
-
-```yaml
-- name: example_metrics_intersection_database_sourced
- operator: AND
- source: database
- events:
- - 'dependency_scanning_pipeline'
- - 'container_scanning_pipeline'
- time_frame:
- - 28d
- - all
-```
+See the [implement Service Ping](implement.md) guide.
## Example Service Ping payload
@@ -1331,7 +494,7 @@ checking the configuration file of your GitLab instance:
- Using the Admin Area:
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
+ 1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Metrics and profiling**.
1. Expand **Usage Statistics**.
1. Are you able to check or uncheck the checkbox to disable Service Ping?
@@ -1388,7 +551,7 @@ To work around this bug, you have two options:
sudo gitlab-ctl reconfigure
```
- 1. In GitLab, on the top bar, select **Menu >** **{admin}** **Admin**.
+ 1. In GitLab, on the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Metrics and profiling**.
1. Expand **Usage Statistics**.
1. Clear the **Enable service ping** checkbox.
diff --git a/doc/development/service_ping/metrics_dictionary.md b/doc/development/service_ping/metrics_dictionary.md
index b3c5f078a4a..8dc2d2255d1 100644
--- a/doc/development/service_ping/metrics_dictionary.md
+++ b/doc/development/service_ping/metrics_dictionary.md
@@ -22,6 +22,9 @@ All metrics are stored in YAML files:
- [`config/metrics`](https://gitlab.com/gitlab-org/gitlab/-/tree/master/config/metrics)
+WARNING:
+Only metrics with a metric definition YAML are added to the Service Ping JSON payload.
+
Each metric is defined in a separate YAML file consisting of a number of fields:
| Field | Required | Additional information |
@@ -34,14 +37,14 @@ Each metric is defined in a separate YAML file consisting of a number of fields:
| `product_group` | yes | The [group](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/stages.yml) that owns the metric. |
| `product_category` | no | The [product category](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/categories.yml) for the metric. |
| `value_type` | yes | `string`; one of [`string`, `number`, `boolean`, `object`](https://json-schema.org/understanding-json-schema/reference/type.html). |
-| `status` | yes | `string`; [status](#metric-statuses) of the metric, may be set to `data_available`, `implemented`, `not_used`, `deprecated`, `removed`, `broken`. |
+| `status` | yes | `string`; [status](#metric-statuses) of the metric, may be set to `active`, `deprecated`, `removed`, `broken`. |
| `time_frame` | yes | `string`; may be set to a value like `7d`, `28d`, `all`, `none`. |
| `data_source` | yes | `string`; may be set to a value like `database`, `redis`, `redis_hll`, `prometheus`, `system`. |
| `data_category` | yes | `string`; [categories](#data-category) of the metric, may be set to `operational`, `optional`, `subscription`, `standard`. The default value is `optional`.|
| `instrumentation_class` | no | `string`; [the class that implements the metric](metrics_instrumentation.md). |
| `distribution` | yes | `array`; may be set to one of `ce, ee` or `ee`. The [distribution](https://about.gitlab.com/handbook/marketing/strategic-marketing/tiers/#definitions) where the tracked feature is available. |
| `performance_indicator_type` | no | `array`; may be set to one of [`gmau`, `smau`, `paid_gmau`, or `umau`](https://about.gitlab.com/handbook/business-technology/data-team/data-catalog/xmau-analysis/). |
-| `tier` | yes | `array`; may contain one or a combination of `free`, `premium` or `ultimate`. The [tier]( https://about.gitlab.com/handbook/marketing/strategic-marketing/tiers/) where the tracked feature is available. |
+| `tier` | yes | `array`; may contain one or a combination of `free`, `premium` or `ultimate`. The [tier]( https://about.gitlab.com/handbook/marketing/strategic-marketing/tiers/) where the tracked feature is available. This should be verbose and contain all tiers where a metric is available. |
| `milestone` | no | The milestone when the metric is introduced. |
| `milestone_removed` | no | The milestone when the metric is removed. |
| `introduced_by_url` | no | The URL to the Merge Request that introduced the metric. |
@@ -53,11 +56,8 @@ Each metric is defined in a separate YAML file consisting of a number of fields:
Metric definitions can have one of the following statuses:
-- `data_available`: Metric data is available and used in a Sisense dashboard.
-- `implemented`: Metric is implemented but data is not yet available. This is a temporary
- status for newly added metrics awaiting inclusion in a new release.
+- `active`: Metric is used and reports data.
- `broken`: Metric reports broken data (for example, -1 fallback), or does not report data at all. A metric marked as `broken` must also have the `repair_issue_url` attribute.
-- `not_used`: Metric is not used in any dashboard.
- `deprecated`: Metric is deprecated and possibly planned to be removed.
- `removed`: Metric was removed, but it may appear in Service Ping payloads sent from instances running on older versions of GitLab.
@@ -177,7 +177,7 @@ product_section: growth
product_stage: growth
product_group: group::product intelligence
value_type: string
-status: data_available
+status: active
milestone: 9.1
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/1521
time_frame: none
@@ -217,11 +217,11 @@ create ee/config/metrics/counts_7d/issues.yml
## Metrics added dynamic to Service Ping payload
-The [Redis HLL metrics](index.md#known-events-are-added-automatically-in-service-data-payload) are added automatically to Service Ping payload.
+The [Redis HLL metrics](implement.md#known-events-are-added-automatically-in-service-data-payload) are added automatically to Service Ping payload.
A YAML metric definition is required for each metric. A dedicated generator is provided to create metric definitions for Redis HLL events.
-The generator takes `category` and `event` arguments, as the root key will be `redis_hll_counters`, and creates two metric definitions for weekly and monthly timeframes:
+The generator takes `category` and `event` arguments, as the root key is `redis_hll_counters`, and creates two metric definitions for weekly and monthly time frames:
```shell
bundle exec rails generate gitlab:usage_metric_definition:redis_hll issues i_closed
diff --git a/doc/development/service_ping/metrics_instrumentation.md b/doc/development/service_ping/metrics_instrumentation.md
index 8ad1ae9cce2..6fdbd1eea31 100644
--- a/doc/development/service_ping/metrics_instrumentation.md
+++ b/doc/development/service_ping/metrics_instrumentation.md
@@ -115,13 +115,13 @@ There is support for:
- [Redis HLL metrics](#redis-hyperloglog-metrics).
- [Generic metrics](#generic-metrics), which are metrics based on settings or configurations.
-Currently, there is no support for:
+There is no support for:
- `add`, `sum`, `histogram` for database metrics.
You can [track the progress to support these](https://gitlab.com/groups/gitlab-org/-/epics/6118).
-## Creating a new metric instrumentation class
+## Create a new metric instrumentation class
To create a stub instrumentation for a Service Ping metric, you can use a dedicated [generator](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/generators/gitlab/usage_metric_generator.rb):
diff --git a/doc/development/service_ping/metrics_lifecycle.md b/doc/development/service_ping/metrics_lifecycle.md
index 68c5ddecc1f..c0446aece8b 100644
--- a/doc/development/service_ping/metrics_lifecycle.md
+++ b/doc/development/service_ping/metrics_lifecycle.md
@@ -10,7 +10,7 @@ The following guidelines explain the steps to follow at each stage of a metric's
## Add a new metric
-Please follow the [Implementing Service Ping](index.md#implementing-service-ping) guide.
+Follow the [Implement Service Ping](implement.md) guide.
## Change an existing metric
@@ -39,7 +39,7 @@ For GitLab 12.6, the metric was changed to filter out archived projects:
}
```
-In this scenario all instances running up to GitLab 12.5 continue to report `example_metric`,
+In this scenario, all instances running up to GitLab 12.5 continue to report `example_metric`,
including all archived projects, while all instances running GitLab 12.6 and higher filters
out such projects. As Service Ping data is collected from all reporting instances, the
resulting dataset includes mixed data, which distorts any following business analysis.
diff --git a/doc/development/service_ping/review_guidelines.md b/doc/development/service_ping/review_guidelines.md
index f961fd376bd..048b705636f 100644
--- a/doc/development/service_ping/review_guidelines.md
+++ b/doc/development/service_ping/review_guidelines.md
@@ -59,7 +59,7 @@ are regular backend changes.
metrics that are based on Database.
- For tracking using Redis HLL (HyperLogLog):
- Check the Redis slot.
- - Check if a [feature flag is needed](index.md#recommendations).
+ - Check if a [feature flag is needed](implement.md#recommendations).
- For a metric's YAML definition:
- Check the metric's `description`.
- Check the metric's `key_path`.
diff --git a/doc/development/sidekiq_style_guide.md b/doc/development/sidekiq_style_guide.md
index c1733a974e4..04b7e2f5c45 100644
--- a/doc/development/sidekiq_style_guide.md
+++ b/doc/development/sidekiq_style_guide.md
@@ -713,7 +713,7 @@ default weight, which is 1.
## Worker context
-> - [Introduced](https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/9) in GitLab 12.8.
+> [Introduced](https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/9) in GitLab 12.8.
To have some more information about workers in the logs, we add
[metadata to the jobs in the form of an
@@ -1002,9 +1002,7 @@ When renaming queues, use the `sidekiq_queue_migrate` helper migration method
in a **post-deployment migration**:
```ruby
-class MigrateTheRenamedSidekiqQueue < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
+class MigrateTheRenamedSidekiqQueue < Gitlab::Database::Migration[1.0]
def up
sidekiq_queue_migrate 'old_queue_name', to: 'new_queue_name'
end
diff --git a/doc/development/single_table_inheritance.md b/doc/development/single_table_inheritance.md
index aa4fe540b0d..eb406b02a91 100644
--- a/doc/development/single_table_inheritance.md
+++ b/doc/development/single_table_inheritance.md
@@ -31,7 +31,7 @@ could result in loading unexpected code or associations which may cause unintend
side effects or failures during upgrades.
```ruby
-class SomeMigration < ActiveRecord::Migration[6.0]
+class SomeMigration < Gitlab::Database::Migration[1.0]
class Services < ActiveRecord::Base
self.table_name = 'services'
self.inheritance_column = :_type_disabled
@@ -47,7 +47,7 @@ This ensures that the migration loads the columns for the migration in isolation
and the helper disables STI by default.
```ruby
-class EnqueueSomeBackgroundMigration < ActiveRecord::Migration[6.0]
+class EnqueueSomeBackgroundMigration < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
diff --git a/doc/development/snowplow/index.md b/doc/development/snowplow/index.md
index 527b4292b23..e8b7d871b77 100644
--- a/doc/development/snowplow/index.md
+++ b/doc/development/snowplow/index.md
@@ -53,7 +53,7 @@ Snowplow tracking is enabled on GitLab.com, and we use it for most of our tracki
To enable Snowplow tracking on a self-managed instance:
-1. On the top bar, select **Menu >** **{admin}** **Admin**, then select **Settings > General**.
+1. On the top bar, select **Menu > Admin**, then select **Settings > General**.
Alternatively, go to `admin/application_settings/general` in your browser.
1. Expand **Snowplow**.
@@ -101,7 +101,7 @@ sequenceDiagram
## Structured event taxonomy
-When adding new click events, we should add them in a way that's internally consistent. If we don't, it is very painful to perform analysis across features since each feature captures events differently.
+When adding new click events, we should add them in a way that's internally consistent. If we don't, it is difficult to perform analysis across features because each feature captures events differently.
The current method provides several attributes that are sent on each click event. Please try to follow these guidelines when specifying events to capture:
@@ -109,9 +109,9 @@ The current method provides several attributes that are sent on each click event
| --------- | ------- | -------- | ----------- |
| category | text | true | The page or backend area of the application. Unless infeasible, please use the Rails page attribute by default in the frontend, and namespace + class name on the backend. |
| action | text | true | The action the user is taking, or aspect that's being instrumented. The first word should always describe the action or aspect: clicks should be `click`, activations should be `activate`, creations should be `create`, etc. Use underscores to describe what was acted on; for example, activating a form field would be `activate_form_input`. An interface action like clicking on a dropdown would be `click_dropdown`, while a behavior like creating a project record from the backend would be `create_project` |
-| label | text | false | The specific element, or object that's being acted on. This is either the label of the element (e.g. a tab labeled 'Create from template' may be `create_from_template`) or a unique identifier if no text is available (e.g. closing the Groups dropdown in the top navigation bar might be `groups_dropdown_close`), or it could be the name or title attribute of a record being created. |
+| label | text | false | The specific element or object to act on. This can be one of the following: the label of the element (for example, a tab labeled 'Create from template' for `create_from_template`), a unique identifier if no text is available (for example, `groups_dropdown_close` for closing the Groups dropdown in the top bar), or the name or title attribute of a record being created. |
| property | text | false | Any additional property of the element, or object being acted on. |
-| value | decimal | false | Describes a numeric value or something directly related to the event. This could be the value of an input (e.g. `10` when clicking `internal` visibility). |
+| value | decimal | false | Describes a numeric value or something directly related to the event. This could be the value of an input. For example, `10` when clicking `internal` visibility. |
### Examples
@@ -156,7 +156,7 @@ LIMIT 20
Snowplow JS adds many [web-specific parameters](https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/snowplow-tracker-protocol/#Web-specific_parameters) to all web events by default.
-## Implementing Snowplow JS (Frontend) tracking
+## Implement Snowplow JS (Frontend) tracking
GitLab provides `Tracking`, an interface that wraps the [Snowplow JavaScript Tracker](https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/javascript-trackers/) for tracking custom events. The simplest way to use it is to add `data-` attributes to clickable elements and dropdowns. There is also a Vue mixin (exposing a `track` method), and the static method `Tracking.event`. Each of these requires at minimum a `category` and an `action`. You can provide additional [Structured event taxonomy](#structured-event-taxonomy) properties along with an `extra` object that accepts key-value pairs.
@@ -174,7 +174,7 @@ GitLab provides `Tracking`, an interface that wraps the [Snowplow JavaScript Tra
### Tracking with data attributes
-When working within HAML (or Vue templates) we can add `data-track-*` attributes to elements of interest. All elements that have a `data-track-action` attribute automatically have event tracking bound on clicks. You can provide extra data as a valid JSON string using `data-track-extra`.
+When working in HAML (or Vue templates) we can add `data-track-*` attributes to elements of interest. All elements that have a `data-track-action` attribute automatically have event tracking bound on clicks. You can provide extra data as a valid JSON string using `data-track-extra`.
Below is an example of `data-track-*` attributes assigned to a button:
@@ -191,7 +191,7 @@ Below is an example of `data-track-*` attributes assigned to a button:
/>
```
-Event listeners are bound at the document level to handle click events on or within elements with these data attributes. This allows them to be properly handled on re-rendering and changes to the DOM. Note that because of the way these events are bound, click events should not be stopped from propagating up the DOM tree. If for any reason click events are being stopped from propagating, you need to implement your own listeners and follow the instructions in [Tracking within Vue components](#tracking-within-vue-components) or [Tracking in raw JavaScript](#tracking-in-raw-javascript).
+Event listeners are bound at the document level to handle click events on or within elements with these data attributes. This allows them to be properly handled on re-rendering and changes to the DOM. Note that because of the way these events are bound, click events should not be stopped from propagating up the DOM tree. If click events are being stopped from propagating, you must implement your own listeners and follow the instructions in [Tracking within Vue components](#tracking-within-vue-components) or [Tracking in raw JavaScript](#tracking-in-raw-javascript).
Below is a list of supported `data-track-*` attributes:
@@ -237,7 +237,7 @@ import Tracking from '~/tracking';
const trackingMixin = Tracking.mixin({ label: 'right_sidebar' });
```
-You can provide default options that are passed along whenever an event is tracked from within your component. For instance, if all events within a component should be tracked with a given `label`, you can provide one at this time. Available defaults are `category`, `label`, `property`, and `value`. If no category is specified, `document.body.dataset.page` is used as the default.
+You can provide default options that are passed along whenever an event is tracked from within your component. For example, if all events in a component should be tracked with a given `label`, you can provide one at this time. Available defaults are `category`, `label`, `property`, and `value`. If no category is specified, `document.body.dataset.page` is used as the default.
You can then use the mixin normally in your component with the `mixin` Vue declaration. The mixin also provides the ability to specify tracking options in `data` or `computed`. These override any defaults and allow the values to be dynamic from props, or based on state.
@@ -256,7 +256,7 @@ export default {
};
```
-The mixin provides a `track` method that can be called within the template,
+The mixin provides a `track` method that can be called from within the template,
or from component methods. An example of the whole implementation might look like this:
```javascript
@@ -302,7 +302,7 @@ export default {
```
The event data can be provided directly in the `track` function as well.
-This object will merge with any previously provided options.
+This object merges with any previously provided options.
```javascript
this.track('click_button', {
@@ -404,7 +404,7 @@ describe('MyTracking', () => {
### Form tracking
-You can enable Snowplow automatic [form tracking](https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/javascript-trackers/javascript-tracker/javascript-tracker-v2/tracking-specific-events/#form-tracking) by calling `Tracking.enableFormTracking` (after the DOM is ready) and providing a `config` object that includes at least one of the following elements:
+Enable Snowplow automatic [form tracking](https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/javascript-trackers/javascript-tracker/javascript-tracker-v2/tracking-specific-events/#form-tracking) by calling `Tracking.enableFormTracking` (after the DOM is ready) and providing a `config` object that includes at least one of the following elements:
- `forms`: determines which forms are tracked, and are identified by the CSS class name.
- `fields`: determines which fields inside the tracked forms are tracked, and are identified by the field `name`.
@@ -442,7 +442,7 @@ describe('MyFormTracking', () => {
});
```
-## Implementing Snowplow Ruby (Backend) tracking
+## Implement Snowplow Ruby (Backend) tracking
GitLab provides `Gitlab::Tracking`, an interface that wraps the [Snowplow Ruby Tracker](https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/ruby-tracker/) for tracking custom events.
@@ -483,11 +483,11 @@ https://docs.gitlab.com/ee/development/testing_guide/best_practices.html#test-sn
### Performance
-We use the [AsyncEmitter](https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/ruby-tracker//emitters/#the-asyncemitter-class) when tracking events, which allows for instrumentation calls to be run in a background thread. This is still an active area of development.
+We use the [AsyncEmitter](https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/ruby-tracker/emitters/#the-asyncemitter-class) when tracking events, which allows for instrumentation calls to be run in a background thread. This is still an active area of development.
-## Developing and testing Snowplow
+## Develop and test Snowplow
-There are several tools for developing and testing Snowplow Event
+There are several tools for developing and testing a Snowplow event.
| Testing Tool | Frontend Tracking | Backend Tracking | Local Development Environment | Production Environment | Production Environment |
|----------------------------------------------|--------------------|---------------------|-------------------------------|------------------------|------------------------|
@@ -510,7 +510,7 @@ To test frontend events in development:
#### Snowplow Analytics Debugger Chrome Extension
-Snowplow Analytics Debugger is a browser extension for testing frontend events. This works on production, staging and local development environments.
+Snowplow Analytics Debugger is a browser extension for testing frontend events. This works on production, staging, and local development environments.
1. Install the [Snowplow Analytics Debugger](https://chrome.google.com/webstore/detail/snowplow-analytics-debugg/jbnlcgeengmijcghameodeaenefieedm) Chrome browser extension.
1. Open Chrome DevTools to the Snowplow Analytics Debugger tab.
@@ -528,7 +528,7 @@ Snowplow Inspector Chrome Extension is a browser extension for testing frontend
Snowplow Micro is a very small version of a full Snowplow data collection pipeline: small enough that it can be launched by a test suite. Events can be recorded into Snowplow Micro just as they can a full Snowplow pipeline. Micro then exposes an API that can be queried.
-Snowplow Micro is a Docker-based solution for testing frontend and backend events in a local development environment. You need to modify GDK using the instructions below to set this up.
+Snowplow Micro is a Docker-based solution for testing frontend and backend events in a local development environment. You must modify GDK using the instructions below to set this up.
- Read [Introducing Snowplow Micro](https://snowplowanalytics.com/blog/2019/07/17/introducing-snowplow-micro/)
- Look at the [Snowplow Micro repository](https://github.com/snowplow-incubator/snowplow-micro)
@@ -544,10 +544,15 @@ Snowplow Micro is a Docker-based solution for testing frontend and backend event
./snowplow-micro.sh
```
-1. Update your instance's settings to enable Snowplow events and point to the Snowplow Micro collector:
+1. Use GDK to start the PostgreSQL terminal and connect to the `gitlabhq_development` database:
```shell
gdk psql -d gitlabhq_development
+ ```
+
+1. Update your instance's settings to enable Snowplow events and point to the Snowplow Micro collector:
+
+ ```shell
update application_settings set snowplow_collector_hostname='localhost:9090', snowplow_enabled=true, snowplow_cookie_domain='.gitlab.com';
```
@@ -568,14 +573,14 @@ Snowplow Micro is a Docker-based solution for testing frontend and backend event
formTracking: false,
```
-1. Update `snowplow_options` in `lib/gitlab/tracking.rb` to add `protocol` and `port`:
+1. Update `options` in `lib/gitlab/tracking.rb` to add `protocol` and `port`:
```diff
diff --git a/lib/gitlab/tracking.rb b/lib/gitlab/tracking.rb
index 618e359211b..e9084623c43 100644
--- a/lib/gitlab/tracking.rb
+++ b/lib/gitlab/tracking.rb
- @@ -41,7 +41,9 @@ def snowplow_options(group)
+ @@ -41,7 +41,9 @@ def options(group)
cookie_domain: Gitlab::CurrentSettings.snowplow_cookie_domain,
app_id: Gitlab::CurrentSettings.snowplow_app_id,
form_tracking: additional_features,
@@ -609,7 +614,7 @@ Snowplow Micro is a Docker-based solution for testing frontend and backend event
1. Restart GDK:
```shell
- `gdk restart`
+ gdk restart
```
1. Send a test Snowplow event from the Rails console:
diff --git a/doc/development/snowplow/review_guidelines.md b/doc/development/snowplow/review_guidelines.md
index 285fbc3b44b..8edcbf06a0e 100644
--- a/doc/development/snowplow/review_guidelines.md
+++ b/doc/development/snowplow/review_guidelines.md
@@ -26,7 +26,7 @@ events or touches Snowplow related files.
#### The merge request **author** should
- For frontend events, when relevant, add a screenshot of the event in
- the [testing tool](../snowplow/index.md#developing-and-testing-snowplow) used.
+ the [testing tool](../snowplow/index.md#develop-and-test-snowplow) used.
- For backend events, when relevant, add the output of the
[Snowplow Micro](index.md#snowplow-mini) good events
`GET http://localhost:9090/micro/good` (it might be a good idea
@@ -39,5 +39,5 @@ events or touches Snowplow related files.
- Check the [usage recommendations](../snowplow/index.md#usage-recommendations).
- Check that the [Event Dictionary](event_dictionary_guide.md) is up-to-date.
- If needed, check that the events are firing locally using one of the
-[testing tools](../snowplow/index.md#developing-and-testing-snowplow) available.
+[testing tools](../snowplow/index.md#develop-and-test-snowplow) available.
- Approve the MR, and relabel the MR with `~"product intelligence::approved"`.
diff --git a/doc/development/sql.md b/doc/development/sql.md
index 40ee19c0b9e..3483305c113 100644
--- a/doc/development/sql.md
+++ b/doc/development/sql.md
@@ -102,7 +102,7 @@ transaction. Transactions for migrations can be disabled using the following
pattern:
```ruby
-class MigrationName < ActiveRecord::Migration[4.2]
+class MigrationName < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
end
```
@@ -110,7 +110,7 @@ end
For example:
```ruby
-class AddUsersLowerUsernameEmailIndexes < ActiveRecord::Migration[4.2]
+class AddUsersLowerUsernameEmailIndexes < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
diff --git a/doc/development/stage_group_dashboards.md b/doc/development/stage_group_dashboards.md
index 61a98ece892..7c518e9b6ca 100644
--- a/doc/development/stage_group_dashboards.md
+++ b/doc/development/stage_group_dashboards.md
@@ -56,7 +56,7 @@ component can have 2 indicators:
[Git](https://gitlab.com/gitlab-com/runbooks/-/blob/f22f40b2c2eab37d85e23ccac45e658b2c914445/metrics-catalog/services/git.jsonnet#L216),
and
[Web](https://gitlab.com/gitlab-com/runbooks/-/blob/f22f40b2c2eab37d85e23ccac45e658b2c914445/metrics-catalog/services/web.jsonnet#L154)
- services, that threshold is **1 second**.
+ services, that threshold is **5 seconds**.
For Sidekiq job execution, the threshold depends on the [job
urgency](sidekiq_style_guide.md#job-urgency). It is
diff --git a/doc/development/testing_guide/best_practices.md b/doc/development/testing_guide/best_practices.md
index ba7312b760f..79664490368 100644
--- a/doc/development/testing_guide/best_practices.md
+++ b/doc/development/testing_guide/best_practices.md
@@ -54,7 +54,7 @@ When using spring and guard together, use `SPRING=1 bundle exec guard` instead t
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/47767) in GitLab 13.7.
-We've enabled [deprecation warnings](https://ruby-doc.org/core-2.7.2/Warning.html)
+We've enabled [deprecation warnings](https://ruby-doc.org/core-2.7.4/Warning.html)
by default when running specs. Making these warnings more visible to developers
helps upgrading to newer Ruby versions.
@@ -367,26 +367,34 @@ If needed, you can scope interactions within a specific area of the page by usin
As you will likely be scoping to an element such as a `div`, which typically does not have a label,
you may use a `data-testid` selector in this case.
+##### Externalized contents
+
+Test expectations against externalized contents should call the same
+externalizing method to match the translation. For example, you should use the `_`
+method in Ruby and `__` method in JavaScript.
+
+See [Internationalization for GitLab - Test files](../i18n/externalization.md#test-files) for details.
+
##### Actions
Where possible, use more specific [actions](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Actions), such as the ones below.
```ruby
# good
-click_button 'Submit review'
+click_button _('Submit review')
-click_link 'UI testing docs'
+click_link _('UI testing docs')
-fill_in 'Search projects', with: 'gitlab' # fill in text input with text
+fill_in _('Search projects'), with: 'gitlab' # fill in text input with text
-select 'Last updated', from: 'Sort by' # select an option from a select input
+select _('Last updated'), from: 'Sort by' # select an option from a select input
-check 'Checkbox label'
-uncheck 'Checkbox label'
+check _('Checkbox label')
+uncheck _('Checkbox label')
-choose 'Radio input label'
+choose _('Radio input label')
-attach_file('Attach a file', '/path/to/file.png')
+attach_file(_('Attach a file'), '/path/to/file.png')
# bad - interactive elements must have accessible names, so
# we should be able to use one of the specific actions above
@@ -403,17 +411,17 @@ Where possible, use more specific [finders](https://rubydoc.info/github/teamcapy
```ruby
# good
-find_button 'Submit review'
-find_button 'Submit review', disabled: true
+find_button _('Submit review')
+find_button _('Submit review'), disabled: true
-find_link 'UI testing docs'
-find_link 'UI testing docs', href: docs_url
+find_link _('UI testing docs')
+find_link _('UI testing docs'), href: docs_url
-find_field 'Search projects'
-find_field 'Search projects', with: 'gitlab' # find the input field with text
-find_field 'Search projects', disabled: true
-find_field 'Checkbox label', checked: true
-find_field 'Checkbox label', unchecked: true
+find_field _('Search projects')
+find_field _('Search projects'), with: 'gitlab' # find the input field with text
+find_field _('Search projects'), disabled: true
+find_field _('Checkbox label'), checked: true
+find_field _('Checkbox label'), unchecked: true
# acceptable when finding a element that is not a button, link, or field
find('[data-testid="element"]')
@@ -425,31 +433,31 @@ Where possible, use more specific [matchers](https://rubydoc.info/github/teamcap
```ruby
# good
-expect(page).to have_button 'Submit review'
-expect(page).to have_button 'Submit review', disabled: true
-expect(page).to have_button 'Notifications', class: 'is-checked' # assert the "Notifications" GlToggle is checked
+expect(page).to have_button _('Submit review')
+expect(page).to have_button _('Submit review'), disabled: true
+expect(page).to have_button _('Notifications'), class: 'is-checked' # assert the "Notifications" GlToggle is checked
-expect(page).to have_link 'UI testing docs'
-expect(page).to have_link 'UI testing docs', href: docs_url # assert the link has an href
+expect(page).to have_link _('UI testing docs')
+expect(page).to have_link _('UI testing docs'), href: docs_url # assert the link has an href
-expect(page).to have_field 'Search projects'
-expect(page).to have_field 'Search projects', disabled: true
-expect(page).to have_field 'Search projects', with: 'gitlab' # assert the input field has text
+expect(page).to have_field _('Search projects')
+expect(page).to have_field _('Search projects'), disabled: true
+expect(page).to have_field _('Search projects'), with: 'gitlab' # assert the input field has text
-expect(page).to have_checked_field 'Checkbox label'
-expect(page).to have_unchecked_field 'Radio input label'
+expect(page).to have_checked_field _('Checkbox label')
+expect(page).to have_unchecked_field _('Radio input label')
-expect(page).to have_select 'Sort by'
-expect(page).to have_select 'Sort by', selected: 'Last updated' # assert the option is selected
-expect(page).to have_select 'Sort by', options: ['Last updated', 'Created date', 'Due date'] # assert an exact list of options
-expect(page).to have_select 'Sort by', with_options: ['Created date', 'Due date'] # assert a partial list of options
+expect(page).to have_select _('Sort by')
+expect(page).to have_select _('Sort by'), selected: 'Last updated' # assert the option is selected
+expect(page).to have_select _('Sort by'), options: ['Last updated', 'Created date', 'Due date'] # assert an exact list of options
+expect(page).to have_select _('Sort by'), with_options: ['Created date', 'Due date'] # assert a partial list of options
-expect(page).to have_text 'Some paragraph text.'
-expect(page).to have_text 'Some paragraph text.', exact: true # assert exact match
+expect(page).to have_text _('Some paragraph text.')
+expect(page).to have_text _('Some paragraph text.'), exact: true # assert exact match
expect(page).to have_current_path 'gitlab/gitlab-test/-/issues'
-expect(page).to have_title 'Not Found'
+expect(page).to have_title _('Not Found')
# acceptable when a more specific matcher above is not possible
expect(page).to have_css 'h2', text: 'Issue title'
@@ -653,6 +661,12 @@ let_it_be_with_refind(:project) { create(:project) }
let_it_be(:project, refind: true) { create(:project) }
```
+Note that `let_it_be` cannot be used with factories that has stubs, such as `allow`.
+The reason is that `let_it_be` happens in a `before(:all)` block, and RSpec does not
+allow stubs in `before(:all)`.
+See this [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/340487) for more details.
+To resolve, use `let`, or change the factory to not use stubs.
+
### Time-sensitive tests
[`ActiveSupport::Testing::TimeHelpers`](https://api.rubyonrails.org/v6.0.3.1/classes/ActiveSupport/Testing/TimeHelpers.html)
@@ -1197,6 +1211,8 @@ GitLab uses [factory_bot](https://github.com/thoughtbot/factory_bot) as a test f
- Factories don't have to be limited to `ActiveRecord` objects.
[See example](https://gitlab.com/gitlab-org/gitlab-foss/commit/0b8cefd3b2385a21cfed779bd659978c0402766d).
- Factories and their traits should produce valid objects that are [verified by specs](https://gitlab.com/gitlab-org/gitlab/-/blob/master/spec/factories_spec.rb).
+- Avoid the use of [`skip_callback`](https://api.rubyonrails.org/classes/ActiveSupport/Callbacks/ClassMethods.html#method-i-skip_callback) in factories.
+ See [issue #247865](https://gitlab.com/gitlab-org/gitlab/-/issues/247865) for details.
### Fixtures
diff --git a/doc/development/testing_guide/end_to_end/beginners_guide.md b/doc/development/testing_guide/end_to_end/beginners_guide.md
index e0f0e9e7089..7370cc5771b 100644
--- a/doc/development/testing_guide/end_to_end/beginners_guide.md
+++ b/doc/development/testing_guide/end_to_end/beginners_guide.md
@@ -349,8 +349,8 @@ GITLAB_PASSWORD=<GDK root password> bundle exec bin/qa Test::Instance::All http:
Where `<test_file>` is:
-- `qa/specs/features/browser_ui/1_manage/login/login_spec.rb` when running the Login example.
-- `qa/specs/features/browser_ui/2_plan/issues/issue_spec.rb` when running the Issue example.
+- `qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb` when running the Login example.
+- `qa/specs/features/browser_ui/2_plan/issues/create_issue_spec.rb` when running the Issue example.
## End-to-end test merge request template
diff --git a/doc/development/testing_guide/end_to_end/best_practices.md b/doc/development/testing_guide/end_to_end/best_practices.md
index 74c02d19d0a..a3caa8bf2b3 100644
--- a/doc/development/testing_guide/end_to_end/best_practices.md
+++ b/doc/development/testing_guide/end_to_end/best_practices.md
@@ -8,27 +8,33 @@ info: To determine the technical writer assigned to the Stage/Group associated w
This is a tailored extension of the Best Practices [found in the testing guide](../best_practices.md).
-## Link a test to its test-case issue
+## Class and module naming
-Every test should have a corresponding issue in the [Quality Test Cases project](https://gitlab.com/gitlab-org/quality/testcases/).
-It's recommended that you reuse the issue created to plan the test. If one does not already exist you
-can create the issue yourself. Alternatively, you can run the test in a pipeline that has reporting
-enabled and the test-case issue reporter will automatically create a new issue.
+The QA framework uses [Zeitwerk](https://github.com/fxn/zeitwerk) for class and module autoloading. The default Zeitwerk [inflector](https://github.com/fxn/zeitwerk#zeitwerkinflector) simply converts snake_cased file names to PascalCased module or class names. It is advised to stick to this pattern to avoid manual maintenance of inflections.
-Whether you create a new test-case issue or one is created automatically, you will need to manually add
-a `testcase` RSpec metadata tag. In most cases, a single test will be associated with a single test-case
-issue ([see below for exceptions](#exceptions)).
+In case custom inflection logic is needed, custom inflectors are added in the [qa.rb](https://gitlab.com/gitlab-org/gitlab/-/blob/master/qa/qa.rb) file in the `loader.inflector.inflect` method invocation.
+
+## Link a test to its test case
+
+Every test should have a corresponding test case as well as a results issue in the [Quality Test Cases project](https://gitlab.com/gitlab-org/quality/testcases/).
+It's recommended that you reuse the issue created to plan the test as the results issue. If a test case or results issue does not already exist you
+can create them yourself. Alternatively, you can run the test in a pipeline that has reporting
+enabled and the test-case reporter will automatically create a new test case and/or results issue and link the results issue to it's corresponding test case.
+
+Whether you create a new test case or one is created automatically, you will need to manually add
+a `testcase` RSpec metadata tag. In most cases, a single test will be associated with a single test case
+ ([see below for exceptions](#exceptions)).
For example:
```ruby
RSpec.describe 'Stage' do
describe 'General description of the feature under test' do
- it 'test name', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/:issue_id' do
+ it 'test name', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/:test_case_id' do
...
end
- it 'another test', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/:another_issue_id' do
+ it 'another test', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/:another_test_case_id' do
...
end
end
@@ -38,10 +44,10 @@ end
### Exceptions
Most tests are defined by a single line of a `spec` file, which is why those tests can be linked to a
-single test-case issue via the `testcase` tag.
+single test case via the `testcase` tag.
-However, some tests don't have a one-to-one relationship between a line of a `spec` file and a test-case
-issue. This is because some tests are defined in a way that means a single line is associated with
+However, some tests don't have a one-to-one relationship between a line of a `spec` file and a test case.
+This is because some tests are defined in a way that means a single line is associated with
multiple tests, including:
- Parallelized tests.
@@ -49,13 +55,13 @@ multiple tests, including:
- Tests in shared examples that include more than one example.
In those and similar cases we can't assign a single `testcase` tag and so we rely on the test-case
-reporter to programmatically determine the correct test-case issue based on the name and description of
-the test. In such cases, the test-case reporter will automatically create a test-case issue the first time
-the test runs, if no issue exists already.
+reporter to programmatically determine the correct test case based on the name and description of
+the test. In such cases, the test-case reporter will automatically create a test case and/or results issue
+the first time the test runs, if none exist already.
-In such a case, if you create the issue yourself or want to reuse an existing issue,
+In such a case, if you create the test case or results issue yourself or want to reuse an existing issue,
you must use this [end-to-end test issue template](https://gitlab.com/gitlab-org/quality/testcases/-/blob/master/.gitlab/issue_templates/End-to-end%20Test.md)
-to format the issue description.
+to format the issue description. (Note you must copy/paste this for test cases as templates aren't currently available.)
To illustrate, there are two tests in the shared examples in [`qa/specs/features/ee/browser_ui/3_create/repository/restrict_push_protected_branch_spec.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/47b17db82c38ab704a23b5ba5d296ea0c6a732c8/qa/qa/specs/features/ee/browser_ui/3_create/repository/restrict_push_protected_branch_spec.rb):
@@ -84,9 +90,9 @@ RSpec.describe 'Create' do
end
```
-There would be two associated test-case issues, one for each shared example, with the following content:
+There would be two associated test cases, one for each shared example, with the following content:
-[Test 1](https://gitlab.com/gitlab-org/quality/testcases/-/issues/600):
+[Test 1 Test Case](https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1491):
````markdown
```markdown
@@ -105,10 +111,66 @@ pushes and merges
./qa/specs/features/ee/browser_ui/3_create/repository/restrict_push_protected_branch_spec.rb
+### DO NOT EDIT BELOW THIS LINE
+
+Active and historical test results:
+
+https://gitlab.com/gitlab-org/quality/testcases/-/issues/600
+
+```
+````
+
+[Test 1 Results Issue](https://gitlab.com/gitlab-org/quality/testcases/-/issues/600):
+
+````markdown
+```markdown
+Title: browser_ui/3_create/repository/restrict_push_protected_branch_spec.rb | Create Restricted
+protected branch push and merge when only one user is allowed to merge and push to a protected
+branch behaves like only user with access pushes and merges selecte...
+
+Description:
+### Full description
+
+Create Restricted protected branch push and merge when only one user is allowed to merge and push
+to a protected branch behaves like only user with access pushes and merges selected developer user
+pushes and merges
+
+### File path
+
+./qa/specs/features/ee/browser_ui/3_create/repository/restrict_push_protected_branch_spec.rb
+
+```
+````
+
+[Test 2 Test Case](https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/602):
+
+````markdown
+```markdown
+Title: browser_ui/3_create/repository/restrict_push_protected_branch_spec.rb | Create Restricted
+protected branch push and merge when only one user is allowed to merge and push to a protected
+branch behaves like only user with access pushes and merges unselec...
+
+Description:
+### Full description
+
+Create Restricted protected branch push and merge when only one user is allowed to merge and push
+to a protected branch behaves like only user with access pushes and merges unselected maintainer
+user fails to push
+
+### File path
+
+./qa/specs/features/ee/browser_ui/3_create/repository/restrict_push_protected_branch_spec.rb
+
+### DO NOT EDIT BELOW THIS LINE
+
+Active and historical test results:
+
+https://gitlab.com/gitlab-org/quality/testcases/-/issues/602
+
```
````
-[Test 2](https://gitlab.com/gitlab-org/quality/testcases/-/issues/602):
+[Test 2 Results Issue](https://gitlab.com/gitlab-org/quality/testcases/-/issues/602):
````markdown
```markdown
@@ -342,7 +404,7 @@ end
When something requires waiting to be matched, use `eventually_` matchers with clear wait duration definition.
-`Eventually` matchers use the following naming pattern: `eventually_${rspec_matcher_name}`. They are defined in [eventually_matcher.rb](https://gitlab.com/gitlab-org/gitlab/-/blob/master/qa/spec/support/matchers/eventually_matcher.rb).
+`Eventually` matchers use the following naming pattern: `eventually_${rspec_matcher_name}`. They are defined in [eventually_matcher.rb](https://gitlab.com/gitlab-org/gitlab/-/blob/master/qa/qa/support/matchers/eventually_matcher.rb).
```ruby
expect { async_value }.to eventually_eq(value).within(max_duration: 120, max_attempts: 60, reload_page: page)
diff --git a/doc/development/testing_guide/end_to_end/index.md b/doc/development/testing_guide/end_to_end/index.md
index f4b01c64385..36c0f5adf00 100644
--- a/doc/development/testing_guide/end_to_end/index.md
+++ b/doc/development/testing_guide/end_to_end/index.md
@@ -170,6 +170,45 @@ Helm chart](https://gitlab.com/gitlab-org/charts/gitlab/), itself deployed with
See [Review Apps](../review_apps.md) for more details about Review Apps.
+## Test reports
+
+### Allure report
+
+For additional test results visibility, tests that run on pipelines generate
+and host [Allure](https://github.com/allure-framework/allure2) test reports.
+
+The `QA` framework is using the [Allure RSpec](https://github.com/allure-framework/allure-ruby/blob/master/allure-rspec/README.md)
+gem to generate source files for the `Allure` test report. An additional job
+in the pipeline:
+
+- Fetches these source files from all test jobs.
+- Generates and uploads the report to the `GCS` bucket `gitlab-qa-allure-report` under the project `gitlab-qa-resources`.
+
+A common CI template for report uploading is stored in
+[`allure-report.yml`](https://gitlab.com/gitlab-org/quality/pipeline-common/-/blob/master/ci/allure-report.yml).
+
+#### Merge requests
+
+When these tests are executed in the scope of merge requests, the `Allure` report is
+uploaded to the `GCS` bucket and comment is added linking to their respective reports.
+
+#### Scheduled pipelines
+
+Scheduled pipelines for these tests contain a `generate-allure-report` job under the `Report` stage. They also output
+a link to the current test report.
+
+#### Static report links
+
+Each type of scheduled pipeline generates a static link for the latest test report according to its stage:
+
+- [`master`](https://storage.googleapis.com/gitlab-qa-allure-reports/package-and-qa/master/index.html)
+- [`staging-full`](https://storage.googleapis.com/gitlab-qa-allure-reports/staging-full/master/index.html)
+- [`staging-sanity`](https://storage.googleapis.com/gitlab-qa-allure-reports/staging-sanity/master/index.html)
+- [`staging-sanity-no-admin`](https://storage.googleapis.com/gitlab-qa-allure-reports/staging-sanity-no-admin/master/index.html)
+- [`canary-sanity`](https://storage.googleapis.com/gitlab-qa-allure-reports/canary-sanity/master/index.html)
+- [`production`](https://storage.googleapis.com/gitlab-qa-allure-reports/production/master/index.html)
+- [`production-sanity`](https://storage.googleapis.com/gitlab-qa-allure-reports/production-sanity/master/index.html)
+
## How do I run the tests?
If you are not [testing code in a merge request](#testing-code-in-merge-requests),
diff --git a/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md b/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md
index 3a016c0e95c..b6e92367f89 100644
--- a/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md
+++ b/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md
@@ -44,3 +44,4 @@ This is a partial list of the [RSpec metadata](https://relishapp.com/rspec/rspec
| `:smtp` | The test requires a GitLab instance to be configured to use an SMTP server. Tests SMTP notification email delivery from GitLab by using MailHog. |
| `:testcase` | The link to the test case issue in the [Quality Test Cases project](https://gitlab.com/gitlab-org/quality/testcases/). |
| `:transient` | The test tests transient bugs. It is excluded by default. |
+| `:issue`, `:issue_${num}` | Optional links to issues which might be related to the spec. Helps keeping track of related issues and can also be used by tools that create test reports. Currently added automatically to `Allure` test report. Multiple tags can be used by adding optional number postfix like `issue_1`, `issue_2` etc. |
diff --git a/doc/development/testing_guide/frontend_testing.md b/doc/development/testing_guide/frontend_testing.md
index 3af806d8f57..76687db3a3f 100644
--- a/doc/development/testing_guide/frontend_testing.md
+++ b/doc/development/testing_guide/frontend_testing.md
@@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Frontend testing standards and style guidelines
There are two types of test suites encountered while developing frontend code
-at GitLab. We use Karma with Jasmine and Jest for JavaScript unit and integration testing,
+at GitLab. We use Jest for JavaScript unit and integration testing,
and RSpec feature tests with Capybara for e2e (end-to-end) integration testing.
Unit and feature tests need to be written for all new features.
@@ -28,46 +28,9 @@ If you are looking for a guide on Vue component testing, you can jump right away
We use Jest to write frontend unit and integration tests.
Jest tests can be found in `/spec/frontend` and `/ee/spec/frontend` in EE.
-## Karma test suite
-
-While GitLab has switched over to [Jest](https://jestjs.io), Karma tests still exist in our
-application because some of our specs require a browser and can't be easily migrated to Jest.
-Those specs intend to eventually drop Karma in favor of either Jest or RSpec. You can track this migration
-in the [related epic](https://gitlab.com/groups/gitlab-org/-/epics/4900).
-
-[Karma](http://karma-runner.github.io/) is a test runner which uses
-[Jasmine](https://jasmine.github.io/) as its test framework. Jest also uses Jasmine as foundation,
-that's why it's looking quite similar.
-
-Karma tests live in `spec/javascripts/` and `/ee/spec/javascripts` in EE.
-
-`app/assets/javascripts/behaviors/autosize.js`
-might have a corresponding `spec/javascripts/behaviors/autosize_spec.js` file.
-
-Keep in mind that in a CI environment, these tests are run in a headless
-browser and you don't have access to certain APIs, such as
-[`Notification`](https://developer.mozilla.org/en-US/docs/Web/API/notification),
-which have to be stubbed.
-
-### Differences to Karma
-
-- Jest runs in a Node.js environment, not in a browser. [An issue exists](https://gitlab.com/gitlab-org/gitlab/-/issues/26982) for running Jest tests in a browser.
-- Because Jest runs in a Node.js environment, it uses [jsdom](https://github.com/jsdom/jsdom) by default. See also its [limitations](#limitations-of-jsdom) below.
-- Jest does not have access to Webpack loaders or aliases.
- The aliases used by Jest are defined in its [own configuration](https://gitlab.com/gitlab-org/gitlab/-/blob/master/jest.config.js).
-- All calls to `setTimeout` and `setInterval` are mocked away. See also [Jest Timer Mocks](https://jestjs.io/docs/timer-mocks).
-- `rewire` is not required because Jest supports mocking modules. See also [Manual Mocks](https://jestjs.io/docs/manual-mocks).
-- No [context object](https://jasmine.github.io/tutorials/your_first_suite#section-The_%3Ccode%3Ethis%3C/code%3E_keyword) is passed to tests in Jest.
- This means sharing `this.something` between `beforeEach()` and `it()` for example does not work.
- Instead you should declare shared variables in the context that they are needed (via `const` / `let`).
-- The following cause tests to fail in Jest:
- - Unmocked requests.
- - Unhandled Promise rejections.
- - Calls to `console.warn`, including warnings from libraries like Vue.
-
### Limitations of jsdom
-As mentioned [above](#differences-to-karma), Jest uses jsdom instead of a browser for running tests.
+Jest uses jsdom instead of a browser for running tests.
This comes with a number of limitations, namely:
- [No scrolling support](https://github.com/jsdom/jsdom/blob/15.1.1/lib/jsdom/browser/Window.js#L623-L625)
@@ -387,8 +350,7 @@ Sometimes we have to test time-sensitive code. For example, recurring events tha
If the application itself is waiting for some time, mock await the waiting. In Jest this is already
[done by default](https://gitlab.com/gitlab-org/gitlab/-/blob/a2128edfee799e49a8732bfa235e2c5e14949c68/jest.config.js#L47)
-(see also [Jest Timer Mocks](https://jestjs.io/docs/timer-mocks)). In Karma you can use the
-[Jasmine mock clock](https://jasmine.github.io/api/2.9/Clock.html).
+(see also [Jest Timer Mocks](https://jestjs.io/docs/timer-mocks)).
```javascript
const doSomethingLater = () => {
@@ -409,20 +371,6 @@ it('does something', () => {
});
```
-**in Karma:**
-
-```javascript
-it('does something', () => {
- jasmine.clock().install();
-
- doSomethingLater();
- jasmine.clock().tick(4000);
-
- expect(something).toBe('done');
- jasmine.clock().uninstall();
-});
-```
-
### Mocking the current location in Jest
NOTE:
@@ -476,8 +424,7 @@ it('passes', () => {
Sometimes a test needs to wait for something to happen in the application before it continues.
Avoid using [`setTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout)
-because it makes the reason for waiting unclear and if used within Karma with a time larger than zero it slows down our test suite.
-Instead use one of the following approaches.
+because it makes the reason for waiting unclear. Instead use one of the following approaches.
#### Promises and Ajax calls
@@ -505,19 +452,6 @@ it('waits for an Ajax call', async () => {
});
```
-**in Karma:**
-
-```javascript
-it('waits for an Ajax call', done => {
- askTheServer()
- .then(() => {
- expect(something).toBe('done');
- })
- .then(done)
- .catch(done.fail);
-});
-```
-
If you are not able to register handlers to the `Promise`, for example because it is executed in a synchronous Vue life cycle hook, take a look at the [waitFor](#wait-until-axios-requests-finish) helpers or you can flush all pending `Promise`s:
**in Jest:**
@@ -548,22 +482,6 @@ it('renders something', () => {
});
```
-**in Karma:**
-
-```javascript
-it('renders something', done => {
- wrapper.setProps({ value: 'new value' });
-
- wrapper.vm
- .$nextTick()
- .then(() => {
- expect(wrapper.text()).toBe('new value');
- })
- .then(done)
- .catch(done.fail);
-});
-```
-
#### Events
If the application triggers an event that you need to wait for in your test, register an event handler which contains
@@ -776,8 +694,6 @@ TBU
### Stubbing and Mocking
-Jasmine provides stubbing and mocking capabilities. There are some subtle differences in how to use it within Karma and Jest.
-
Stubs or spies are often used synonymously. In Jest it's quite easy thanks to the `.spyOn` method.
[Official docs](https://jestjs.io/docs/jest-object#jestspyonobject-methodname)
The more challenging part are mocks, which can be used for functions or even dependencies.
@@ -835,7 +751,6 @@ For running the frontend tests, you need the following commands:
- `rake frontend:fixtures` (re-)generates [fixtures](#frontend-test-fixtures). Make sure that
fixtures are up-to-date before running tests that require them.
- `yarn jest` runs Jest tests.
-- `yarn karma` runs Karma tests.
### Live testing and focused testing -- Jest
@@ -860,49 +775,36 @@ yarn jest ./path/to/folder/
yarn jest term
```
-### Live testing and focused testing -- Karma
+## Frontend test fixtures
-Karma allows something similar, but it's way more costly.
+Frontend fixtures are files containing responses from backend controllers. These responses can be either HTML
+generated from HAML templates or JSON payloads. Frontend tests that rely on these responses are
+often using fixtures to validate correct integration with the backend code.
-Running Karma with `yarn run karma-start` compiles the JavaScript
-assets and runs a server at `http://localhost:9876/` where it automatically
-runs the tests on any browser which connects to it. You can enter that URL on
-multiple browsers at once to have it run the tests on each in parallel.
+### Use fixtures
-While Karma is running, any changes you make instantly trigger a recompile
-and retest of the **entire test suite**, so you can see instantly if you've broken
-a test with your changes. You can use [Jasmine focused](https://jasmine.github.io/2.5/focused_specs.html) or
-excluded tests (with `fdescribe` or `xdescribe`) to get Karma to run only the
-tests you want while you're working on a specific feature, but make sure to
-remove these directives when you commit your code.
+Jest uses `spec/frontend/__helpers__/fixtures.js` to import fixtures in tests.
-It is also possible to only run Karma on specific folders or files by filtering
-the run tests via the argument `--filter-spec` or short `-f`:
+The following are examples of tests that work for Jest:
-```shell
-# Run all files
-yarn karma-start
-# Run specific spec files
-yarn karma-start --filter-spec profile/account/components/update_username_spec.js
-# Run specific spec folder
-yarn karma-start --filter-spec profile/account/components/
-# Run all specs which path contain vue_shared or vie
-yarn karma-start -f vue_shared -f vue_mr_widget
-```
+```javascript
+it('makes a request', () => {
+ const responseBody = getJSONFixture('some/fixture.json'); // loads spec/frontend/fixtures/some/fixture.json
+ axiosMock.onGet(endpoint).reply(200, responseBody);
-You can also use glob syntax to match files. Remember to put quotes around the
-glob otherwise your shell may split it into multiple arguments:
+ myButton.click();
-```shell
-# Run all specs named `file_spec` within the IDE subdirectory
-yarn karma -f 'spec/javascripts/ide/**/file_spec.js'
-```
+ // ...
+});
-## Frontend test fixtures
+it('uses some HTML element', () => {
+ loadFixtures('some/page.html'); // loads spec/frontend/fixtures/some/page.html and adds it to the DOM
-Frontend fixtures are files containing responses from backend controllers. These responses can be either HTML
-generated from HAML templates or JSON payloads. Frontend tests that rely on these responses are
-often using fixtures to validate correct integration with the backend code.
+ const element = document.getElementById('#my-id');
+
+ // ...
+});
+```
### Generate fixtures
@@ -961,34 +863,6 @@ This will create a new fixture located at
You can import the JSON fixture in a Jest test using the `getJSONFixture` method
[as described below](#use-fixtures).
-### Use fixtures
-
-Jest and Karma test suites import fixtures in different ways:
-
-- The Karma test suite are served by [jasmine-jquery](https://github.com/velesin/jasmine-jquery).
-- Jest use `spec/frontend/__helpers__/fixtures.js`.
-
-The following are examples of tests that work for both Karma and Jest:
-
-```javascript
-it('makes a request', () => {
- const responseBody = getJSONFixture('some/fixture.json'); // loads spec/frontend/fixtures/some/fixture.json
- axiosMock.onGet(endpoint).reply(200, responseBody);
-
- myButton.click();
-
- // ...
-});
-
-it('uses some HTML element', () => {
- loadFixtures('some/page.html'); // loads spec/frontend/fixtures/some/page.html and adds it to the DOM
-
- const element = document.getElementById('#my-id');
-
- // ...
-});
-```
-
## Data-driven tests
Similar to [RSpec's parameterized tests](best_practices.md#table-based--parameterized-tests),
@@ -1139,13 +1013,10 @@ Main information on frontend testing levels can be found in the [Testing Levels
Tests relevant for frontend development can be found at the following places:
-- `spec/javascripts/`, for Karma tests
- `spec/frontend/`, for Jest tests
- `spec/features/`, for RSpec tests
-RSpec runs complete [feature tests](testing_levels.md#frontend-feature-tests), while the Jest and Karma directories contain [frontend unit tests](testing_levels.md#frontend-unit-tests), [frontend component tests](testing_levels.md#frontend-component-tests), and [frontend integration tests](testing_levels.md#frontend-integration-tests).
-
-All tests in `spec/javascripts/` are intended to be migrated to `spec/frontend/` (see also [#52483](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/52483)).
+RSpec runs complete [feature tests](testing_levels.md#frontend-feature-tests), while the Jest directories contain [frontend unit tests](testing_levels.md#frontend-unit-tests), [frontend component tests](testing_levels.md#frontend-component-tests), and [frontend integration tests](testing_levels.md#frontend-integration-tests).
Before May 2018, `features/` also contained feature tests run by Spinach. These tests were removed from the codebase in May 2018 ([#23036](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/23036)).
@@ -1161,6 +1032,16 @@ If you introduce new helpers, place them in that directory.
We have a helper available to make testing actions easier, as per [official documentation](https://vuex.vuejs.org/guide/testing.html):
```javascript
+// prefer using like this, a single object argument so parameters are obvious from reading the test
+await testAction({
+ action: actions.actionName,
+ payload: { deleteListId: 1 },
+ state: { lists: [1, 2, 3] },
+ expectedMutations: [ { type: types.MUTATION} ],
+ expectedActions: [],
+});
+
+// old way, don't do this for new tests
testAction(
actions.actionName, // action
{ }, // params to be passed to action
@@ -1177,8 +1058,6 @@ testAction(
);
```
-Check an example in [`spec/frontend/ide/stores/actions_spec.js`](https://gitlab.com/gitlab-org/gitlab/-/blob/fdc7197609dfa7caeb1d962042a26248e49f27da/spec/frontend/ide/stores/actions_spec.js#L392).
-
### Wait until Axios requests finish
<!-- vale gitlab.Spelling = NO -->
diff --git a/doc/development/testing_guide/index.md b/doc/development/testing_guide/index.md
index 889dc45d6e3..015d8a92a4d 100644
--- a/doc/development/testing_guide/index.md
+++ b/doc/development/testing_guide/index.md
@@ -19,7 +19,7 @@ importance.
GitLab is built on top of [Ruby on Rails](https://rubyonrails.org/), and we're using [RSpec](https://github.com/rspec/rspec-rails#feature-specs) for all
the backend tests, with [Capybara](https://github.com/teamcapybara/capybara) for end-to-end integration testing.
-On the frontend side, we're using [Jest](https://jestjs.io/) and [Karma](http://karma-runner.github.io/)/[Jasmine](https://jasmine.github.io/) for JavaScript unit and
+On the frontend side, we're using [Jest](https://jestjs.io/) for JavaScript unit and
integration testing.
Following are two great articles that everyone should read to understand what
@@ -40,7 +40,7 @@ system tests, parameterized tests etc.
## [Frontend testing standards and style guidelines](frontend_testing.md)
-Everything you should know about how to write good Frontend tests: Karma,
+Everything you should know about how to write good Frontend tests: Jest,
testing promises, stubbing etc.
## [Flaky tests](flaky_tests.md)
diff --git a/doc/development/testing_guide/review_apps.md b/doc/development/testing_guide/review_apps.md
index cf757aad870..72d63fd8194 100644
--- a/doc/development/testing_guide/review_apps.md
+++ b/doc/development/testing_guide/review_apps.md
@@ -175,7 +175,7 @@ For GitLab Team Members only. If you want to sign in to the review app, review
the GitLab handbook information for the [shared 1Password account](https://about.gitlab.com/handbook/security/#1password-for-teams).
- The default username is `root`.
-- The password can be found in the 1Password secure note named `gitlab-{ce,ee} Review App's root password`.
+- The password can be found in the 1Password login item named `GitLab EE Review App`.
### Enable a feature flag for my Review App
diff --git a/doc/development/testing_guide/testing_levels.md b/doc/development/testing_guide/testing_levels.md
index 3a4a28702c7..29cdfab713e 100644
--- a/doc/development/testing_guide/testing_levels.md
+++ b/doc/development/testing_guide/testing_levels.md
@@ -31,7 +31,7 @@ records should use stubs/doubles as much as possible.
| Code path | Tests path | Testing engine | Notes |
| --------- | ---------- | -------------- | ----- |
-| `app/assets/javascripts/` | `spec/javascripts/`, `spec/frontend/` | Karma & Jest | More details in the [Frontend Testing guide](frontend_testing.md) section. |
+| `app/assets/javascripts/` | `spec/frontend/` | Jest | More details in the [Frontend Testing guide](frontend_testing.md) section. |
| `app/finders/` | `spec/finders/` | RSpec | |
| `app/graphql/` | `spec/graphql/` | RSpec | |
| `app/helpers/` | `spec/helpers/` | RSpec | |
@@ -233,7 +233,7 @@ They're useful to test permissions, redirections, what view is rendered etc.
| `app/controllers/` | `spec/requests/`, `spec/controllers` | RSpec | Request specs are preferred over legacy controller specs. |
| `app/mailers/` | `spec/mailers/` | RSpec | |
| `lib/api/` | `spec/requests/api/` | RSpec | |
-| `app/assets/javascripts/` | `spec/javascripts/`, `spec/frontend/` | Karma & Jest | [More details below](#frontend-integration-tests) |
+| `app/assets/javascripts/` | `spec/frontend/` | Jest | [More details below](#frontend-integration-tests) |
### Frontend integration tests
@@ -322,13 +322,6 @@ controller.instance_variable_set(:@user, user)
and use methods [deprecated in Rails 5](https://gitlab.com/gitlab-org/gitlab/-/issues/16260).
-### About Karma
-
-Karma is both in the Unit tests and the Integration tests category. Karma provides an environment to
-run JavaScript tests, so you can either run unit tests (e.g. test a single
-JavaScript method), or integration tests (e.g. test a component that is composed
-of multiple components).
-
## White-box tests at the system level (formerly known as System / Feature tests)
Formal definitions:
@@ -551,7 +544,7 @@ and the basic idea is that the cost of a test includes:
There are cases where the behavior you are testing is not worth the time spent
running the full application, for example, if you are testing styling, animation,
edge cases or small actions that don't involve the backend,
-you should write an integration test using Jasmine.
+you should write an integration test using [Frontend integration tests](https://gitlab.com/gitlab-org/gitlab/-/blob/master/spec/frontend_integration/README.md).
---
diff --git a/doc/development/transient/prevention-patterns.md b/doc/development/transient/prevention-patterns.md
index 472b5756805..c517a6bcd54 100644
--- a/doc/development/transient/prevention-patterns.md
+++ b/doc/development/transient/prevention-patterns.md
@@ -97,7 +97,7 @@ by the server-side endpoint satisfies the API contract.
#### Related reading
[Debug it!](https://pragprog.com/titles/pbdp/debug-it/) explores techniques to diagnose
-and fix non-determinstic bugs and write software that is easier to debug.
+and fix non-deterministic bugs and write software that is easier to debug.
## Backend
diff --git a/doc/development/understanding_explain_plans.md b/doc/development/understanding_explain_plans.md
index c3fefd40171..c3dfeaa6b92 100644
--- a/doc/development/understanding_explain_plans.md
+++ b/doc/development/understanding_explain_plans.md
@@ -826,4 +826,4 @@ A more extensive guide on understanding query plans can be found in
the [presentation](https://public.dalibo.com/exports/conferences/_archives/_2012/201211_explain/understanding_explain.pdf)
from [Dalibo.org](https://www.dalibo.com/en/).
-Depesz's blog also has a good [section](https://www.depesz.com/tag/unexplainable) dedicated to query plans.
+Depesz's blog also has a good [section](https://www.depesz.com/tag/unexplainable/) dedicated to query plans.
diff --git a/doc/development/work_items.md b/doc/development/work_items.md
new file mode 100644
index 00000000000..d4a1073461a
--- /dev/null
+++ b/doc/development/work_items.md
@@ -0,0 +1,196 @@
+---
+stage: Plan
+group: Project Management
+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
+---
+# Work items and work item types
+
+## Challenges
+
+Issues have the potential to be a centralized hub for collaboration.
+We need to accept the
+fact that different issue types require different fields and different context, depending
+on what job they are being used to accomplish. For example:
+
+- A bug needs to list steps to reproduce.
+- An incident needs references to stack traces and other contextual information relevant only
+ to that incident.
+
+Instead of each object type diverging into a separate model, we can standardize on an underlying
+common model that we can customize with the widgets (one or more attributes) it contains.
+
+Here are some problems with current issues usage and why we are looking into work items:
+
+- Using labels to show issue types is cumbersome and makes reporting views more complex.
+- Issue types are one of the top two use cases of labels, so it makes sense to provide first class
+ support for them.
+- Issues are starting to become cluttered as we add more capabilities to them, and they are not
+ perfect:
+
+ - There is no consistent pattern for how to surface relationships to other objects.
+ - There is not a coherent interaction model across different types of issues because we use
+ labels for this.
+ - The various implementations of issue types lack flexibility and extensibility.
+
+- Epics, issues, requirements, and others all have similar but just subtle enough
+ differences in common interactions that the user needs to hold a complicated mental
+ model of how they each behave.
+- Issues are not extensible enough to support all of the emerging jobs they need to facilitate.
+- Codebase maintainability and feature development become bigger challenges as we grow the Issue type
+ beyond its core role of issue tracking into supporting the different work item types and handling
+ logic and structure differences.
+- New functionality is typically implemented with first class objects that import behavior from issues via
+ shared concerns. This leads to duplicated effort and ultimately small differences between common interactions. This
+ leads to inconsistent UX.
+- Codebase maintainability and feature development becomes a bigger challenges as we grow issues
+ beyond its core role of issue tracking into supporting the different types and subtle differences between them.
+
+## Work item and work item type terms
+
+Using the terms "issue" or "issuable" to reference the types of collaboration objects
+(for example, issue, bug, feature, or epic) often creates confusion. To avoid confusion, we will use the term
+work item type (WIT) when referring to the type of a collaboration object.
+An instance of a WIT is a work item (WI). For example, `issue#123`, `bug#456`, `requirement#789`.
+
+### Migration strategy
+
+WI model will be built on top of the existing `Issue` model and we'll gradually migrate `Issue`
+model code to the WI model.
+
+One way to approach it is:
+
+```ruby
+class WorkItems::WorkItem < ApplicationRecord
+ self.table_name = 'issues'
+
+ # ... all the current issue.rb code
+end
+
+class Issue < WorkItems::WorkItem
+ # Do not add code to this class add to WorkItems:WorkItem
+end
+```
+
+We already use the concept of WITs within `issues` table through `issue_type`
+column. There are `issue`, `incident`, and `test_case` issue types. To extend this
+so that in future we can allow users to define custom WITs, we will move the
+`issue_type` to a separate table: `work_item_types`. The migration process of `issue_type`
+to `work_item_types` will involve creating the set of WITs for all root-level groups.
+
+NOTE:
+At first, defining a WIT will only be possible at the root-level group, which would then be inherited by sub-groups.
+We will investigate the possibility of defining new WITs at sub-group levels at a later iteration.
+
+### Introducing work_item_types table
+
+For example, suppose there are three root-level groups with IDs: `11`, `12`, and `13`. Also,
+assume the following base types: `issue: 0`, `incident: 1`, `test_case: 2`.
+
+The respective `work_item_types` records:
+
+| `group_id` | `base_type` | `title` |
+| -------------- | ----------- | --------- |
+| 11 | 0 | Issue |
+| 11 | 1 | Incident |
+| 11 | 2 | Test Case |
+| 12 | 0 | Issue |
+| 12 | 1 | Incident |
+| 12 | 2 | Test Case |
+| 13 | 0 | Issue |
+| 13 | 1 | Incident |
+| 13 | 2 | Test Case |
+
+What we will do to achieve this:
+
+1. Add a `work_item_type_id` column to the `issues` table.
+1. Ensure we write to both `issues#issue_type` and `issues#work_item_type_id` columns for
+ new or updated issues.
+1. Backfill the `work_item_type_id` column to point to the `work_item_types#id` corresponding
+ to issue's project root groups. For example:
+
+ ```ruby
+ issue.project.root_group.work_item_types.where(base_type: issue.issue_type).first.id.
+ ```
+
+1. After `issues#work_item_type_id` is populated, we can switch our queries from
+ using `issue_type` to using `work_item_type_id`.
+
+To introduce a new WIT there are two options:
+
+- Follow the first step of the above process. We will still need to run a migration
+ that adds a new WIT for all root-level groups to make the WIT available to
+ all users. Besides a long-running migration, we'll need to
+ insert several million records to `work_item_types`. This might be unwanted for users
+ that do not want or need additional WITs in their workflow.
+- Create an opt-in flow, so that the record in `work_item_types` for specific root-level group
+ is created only when a customer opts in. However, this implies a lower discoverability
+ of the newly introduced work item type.
+
+### Work item type widgets
+
+All WITs will share the same pool of predefined widgets and will be customized by
+which widgets are active on a specific WIT. Every attribute (column or association)
+will become a widget with self-encapsulated functionality regardless of the WIT it belongs to.
+Because any WIT can have any widget, we only need to define which widget is active for a
+specific WIT. So, after switching the type of a specific work item, we display a different set
+of widgets.
+
+### Widgets metadata
+
+In order to customize each WIT with corresponding active widgets we will need a data
+structure to map each WIT to specific widgets.
+
+NOTE:
+The exact structure of the WITs widgets metadata is still to be defined.
+
+### Custom work item types
+
+With the WIT widget metadata and the workflow around mapping WIT to specific
+widgets, we will be able to expose custom WITs to the users. Users will be able
+to create their own WITs and customize them with widgets from the predefined pool.
+
+### Custom widgets
+
+The end goal is to allow users to define custom widgets and use these custom
+widgets on any WIT. But this is a much further iteration and requires additional
+investigation to determine both data and application architecture to be used.
+
+## Migrate requirements and epics to work item types
+
+We'll migrate requirements and epics into work item types, with their own set
+of widgets. To achieve that, we'll migrate data to the `issues` table,
+and we'll keep current `requirements` and `epics` tables to be used as proxies for old references to ensure
+backward compatibility with already existing references.
+
+### Migrate requirements to work item types
+
+Currently `Requirement` attributes are a subset of `Issue` attributes, so the migration
+consists mainly of:
+
+- Data migration.
+- Keeping backwards compatibility at API levels.
+- Ensuring that old references continue to work.
+
+The migration to a different underlying data structure should be seamless to the end user.
+
+### Migrate epics to work item types
+
+`Epic` has some extra functionality that the `Issue` WIT does not currently have.
+So, migrating epics to a work item type requires providing feature parity between the current `Epic` object and WITs.
+
+The main missing features are:
+
+- Get WIs to the group level. This is dependent on [Consolidate Groups and Projects](https://gitlab.com/gitlab-org/architecture/tasks/-/issues/7)
+ initiative.
+- A hierarchy widget: the ability to structure work items into hierarchies.
+- Inherited date widget.
+
+To avoid disrupting workflows for users who are already using epics, we will introduce a new WIT
+called `Feature` that will provide feature parity with epics at the project-level. Having that combined with progress
+on [Consolidate Groups and Projects](https://gitlab.com/gitlab-org/architecture/tasks/-/issues/7) front will help us
+provide a smooth migration path of epics to WIT with minimal disruption to user workflow.
+
+## Work item, work item type, and widgets roadmap
+
+We will move towards work items, work item types, and custom widgets (CW) in an iterative process.
+For a rough outline of the work ahead of us, see [epic 6033](https://gitlab.com/groups/gitlab-org/-/epics/6033).
diff --git a/doc/downgrade_ee_to_ce/index.md b/doc/downgrade_ee_to_ce/index.md
index 00e59c46da1..865d60fed73 100644
--- a/doc/downgrade_ee_to_ce/index.md
+++ b/doc/downgrade_ee_to_ce/index.md
@@ -6,10 +6,11 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Downgrading from EE to CE
-If you ever decide to downgrade your Enterprise Edition back to the Community
-Edition, there are a few steps you need take before installing the CE package
-on top of the current EE package, or, if you are in an installation from source,
-before you change remotes and fetch the latest CE code.
+If you ever decide to downgrade your Enterprise Edition back to the
+Community Edition, there are a few steps you need take beforehand. On Omnibus GitLab
+installations, these steps are made before installing the CE package on top of
+the current EE package. On installations from source, they are done before
+you change remotes and fetch the latest CE code.
## Disable Enterprise-only features
@@ -17,8 +18,8 @@ First thing to do is to disable the following features.
### Authentication mechanisms
-Kerberos and Atlassian Crowd are only available on the Enterprise Edition, so
-you should disable these mechanisms before downgrading and you should provide
+Kerberos and Atlassian Crowd are only available on the Enterprise Edition. You
+should disable these mechanisms before downgrading. Be sure to provide
alternative authentication methods to your users.
### Remove Service Integration entries from the database
@@ -35,63 +36,63 @@ column if you didn't intend it to be used for storing the inheritance class or o
use another column for that information.)
```
-All integrations are created automatically for every project you have, so in order
-to avoid getting this error, you need to remove all records with the type set to
+All integrations are created automatically for every project you have.
+To avoid getting this error, you must remove all records with the type set to
`GithubService` from your database:
-**Omnibus Installation**
+- **Omnibus Installation**
-```shell
-sudo gitlab-rails runner "Integration.where(type: ['GithubService']).delete_all"
-```
+ ```shell
+ sudo gitlab-rails runner "Integration.where(type: ['GithubService']).delete_all"
+ ```
-**Source Installation**
+- **Source Installation**
-```shell
-bundle exec rails runner "Integration.where(type: ['GithubService']).delete_all" production
-```
+ ```shell
+ bundle exec rails runner "Integration.where(type: ['GithubService']).delete_all" production
+ ```
NOTE:
-If you are running `GitLab =< v13.0` you need to also remove `JenkinsDeprecatedService` records
-and if you are running `GitLab =< v13.6` you need to also remove `JenkinsService` records.
+If you are running `GitLab =< v13.0` you must also remove `JenkinsDeprecatedService` records
+and if you are running `GitLab =< v13.6` you must remove `JenkinsService` records.
### Variables environment scopes
-If you're using this feature and there are variables sharing the same
-key, but they have different scopes in a project, then you might want to
-revisit the environment scope setting for those variables.
+In GitLab Community Edition, [environment scopes](../user/group/clusters/index.md#environment-scopes)
+are completely ignored, so if you are using this feature there may be some
+necessary adjustments to your configuration. This is especially true if
+configuration variables share the same key, but have different
+scopes in a project. In cases like these you could accidentally get a variable
+which you're not expecting for a particular environment. Make sure that you have
+the right variables in this case.
-In CE, environment scopes are completely ignored, therefore you could
-accidentally get a variable which you're not expecting for a particular
-environment. Make sure that you have the right variables in this case.
-
-Data is completely preserved, so you could always upgrade back to EE and
-restore the behavior if you leave it alone.
+Your data is completely preserved in the transition, so you could always upgrade
+back to EE and restore the behavior if you leave it alone.
## Downgrade to CE
After performing the above mentioned steps, you are now ready to downgrade your
GitLab installation to the Community Edition.
-**Omnibus Installation**
-
-To downgrade an Omnibus installation, it is sufficient to install the Community
-Edition package on top of the currently installed one. You can do this manually,
-by directly [downloading the package](https://packages.gitlab.com/gitlab/gitlab-ce)
-you need, or by adding our CE package repository and following the
-[CE installation instructions](https://about.gitlab.com/install/?version=ce).
-
-**Source Installation**
-
-To downgrade a source installation, you need to replace the current remote of
-your GitLab installation with the Community Edition's remote, fetch the latest
-changes, and checkout the latest stable branch:
-
-```shell
-git remote set-url origin git@gitlab.com:gitlab-org/gitlab-foss.git
-git fetch --all
-git checkout 8-x-stable
-```
+- **Omnibus Installation**
+
+ To downgrade an Omnibus installation, it is sufficient to install the Community
+ Edition package on top of the currently installed one. You can do this manually,
+ by directly [downloading the package](https://packages.gitlab.com/gitlab/gitlab-ce)
+ you need, or by adding our CE package repository and following the
+ [CE installation instructions](https://about.gitlab.com/install/?version=ce).
+
+- **Source Installation**
+
+ To downgrade a source installation, you must replace the current remote of
+ your GitLab installation with the Community Edition's remote. After that, you
+ can fetch the latest changes, and checkout the latest stable branch:
+
+ ```shell
+ git remote set-url origin git@gitlab.com:gitlab-org/gitlab-foss.git
+ git fetch --all
+ git checkout 8-x-stable
+ ```
Remember to follow the correct [update guides](../update/index.md) to make
sure all dependencies are up to date.
diff --git a/doc/install/aws/eks_clusters_aws.md b/doc/install/aws/eks_clusters_aws.md
new file mode 100644
index 00000000000..95f9f81f601
--- /dev/null
+++ b/doc/install/aws/eks_clusters_aws.md
@@ -0,0 +1,53 @@
+---
+type: reference, concepts
+stage: Enablement
+group: Alliances
+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
+---
+
+# EKS cluster provisioning best practices **(FREE SELF)**
+
+GitLab can be used to provision an EKS cluster into AWS, however, it necessarily focuses on a basic EKS configuration. Using the AWS tools can help with advanced cluster configuration, automation, and maintenance.
+
+This documentation is not for clusters for deployment of GitLab itself, but instead clusters purpose built for:
+
+- EKS Clusters for GitLab Runners
+- Application Deployment Clusters for GitLab review apps
+- Application Deployment Cluster for production applications
+
+Information on deploying GitLab onto EKS can be found in [Provisioning GitLab Cloud Native Hybrid on AWS EKS](gitlab_hybrid_on_aws.md).
+
+## Use AWS EKS quick start or `eksctl`
+
+Using the EKS Quick Start or `eksctl` enables the following when building an EKS Cluster:
+
+- It can be part of CloudFormation IaC or [CLI (`eksctl`)](https://eksctl.io/) automation
+- You have various cluster configuration options:
+ - Selection of operating system: Amazon Linux 2, Windows, Bottlerocket
+ - Selection of Hardware Architecture: x86, ARM, GPU
+ - Selection of Fargate backend
+- It can deploy high value-add items to the cluster, including:
+ - A bastion host to keep the cluster endpoint private and possible perform performance testing.
+ - Prometheus and Grafana for monitoring.
+- EKS Autoscaler for automatic K8s Node scaling.
+- 2 or 3 Availability Zones (AZ) spread for balance between High Availability (HA) and cost control.
+- Ability to specify spot compute.
+
+Read more about Amazon EKS architecture quick start guide:
+
+- [Landing page](https://aws.amazon.com/quickstart/architecture/amazon-eks/)
+- [Reference guide](https://aws-quickstart.github.io/quickstart-amazon-eks/)
+- [Reference guide deployment steps](https://aws-quickstart.github.io/quickstart-amazon-eks/#_deployment_steps)
+- [Reference guide parameter reference](https://aws-quickstart.github.io/quickstart-amazon-eks/#_parameter_reference)
+
+## Inject GitLab configuration for integrating clusters
+
+Read more how to [configure an App Deployment cluster](../../user/project/clusters/add_existing_cluster.md) and extract information from it to integrate it into GitLab.
+
+## Provision GitLab Runners using Helm charts
+
+Read how to [use the GitLab Runner Helm Chart](https://docs.gitlab.com/runner/install/kubernetes.html) to deploy a runner into a cluster.
+
+## Runner Cache
+
+Since the EKS Quick Start provides for EFS provisioning, the best approach is to use EFS for runner caching. Eventually we will publish information on using an S3 bucket for runner caching here.
diff --git a/doc/install/aws/gitlab_hybrid_on_aws.md b/doc/install/aws/gitlab_hybrid_on_aws.md
new file mode 100644
index 00000000000..9f53f333463
--- /dev/null
+++ b/doc/install/aws/gitlab_hybrid_on_aws.md
@@ -0,0 +1,362 @@
+---
+type: reference, concepts
+stage: Enablement
+group: Alliances
+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
+---
+
+{::options parse_block_html="true" /}
+
+# Provision GitLab Cloud Native Hybrid on AWS EKS **(FREE SELF)**
+
+GitLab "Cloud Native Hybrid" is a hybrid of the cloud native technology Kubernetes (EKS) and EC2. While as much of the GitLab application as possible runs in Kubernetes or on AWS services (PaaS), the GitLab service Gitaly must still be run on Ec2. Gitaly is a layer designed to overcome limitations of the Git binaries in a horizontally scaled architecture. You can read more here about why Gitaly was built and why the limitations of Git mean that it must currently run on instance compute in [Git Characteristics That Make Horizontal Scaling Difficult](https://gitlab.com/gitlab-org/gitaly/-/blob/master/doc/DESIGN.md#git-characteristics-that-make-horizontal-scaling-difficult)
+
+Amazon provides a managed Kubernetes service offering known as [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/).
+
+## Tested AWS Bill of Materials by reference architecture size
+
+| GitLab Cloud Native Hybrid Ref Arch | GitLab Baseline Perf Test Results Omnibus on Instances | AWS Bill of Materials (BOM) for CNH | AWS Build Performance Testing Results for [CNH](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/5K/5k-QuickStart-ARM-RDS-Redis_v13-12-3-ee_2021-07-23_140128/5k-QuickStart-ARM-RDS-Redis_v13-12-3-ee_2021-07-23_140128_results.txt) | CNH Cost Estimate 3 AZs |
+| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| [2K Omnibus](../../administration/reference_architectures/2k_users.md) | [2K Baseline](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/2k) | [2K Cloud Native Hybrid on EKS](#2k-cloud-native-hybrid-on-eks) | GPT Test Results | 1 YR Ec2 Compute Savings + 1 YR RDS & Elasticache RIs<br />(2 AZ Cost Estimate is in BOM Below) |
+| [3K](../../administration/reference_architectures/3k_users.md#cloud-native-hybrid-reference-architecture-with-helm-charts-alternative) | [3k Baseline](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/3k) | [3K Cloud Native Hybrid on EKS](#3k-cloud-native-hybrid-on-eks) | [3K Full Scale GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/3K/3k-QuickStart-ARM-RDS-Cache_v13-12-3-ee_2021-07-23_124216/3k-QuickStart-ARM-RDS-Cache_v13-12-3-ee_2021-07-23_124216_results.txt)<br /><br />[3K AutoScale GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/3K/3k-QuickStart-AutoScale-ARM-RDS-Cache_v13-12-3-ee_2021-07-23_194200/3k-QuickStart-AutoScale-ARM-RDS-Cache_v13-12-3-ee_2021-07-23_194200_results.txt) | 1 YR Ec2 Compute Savings + 1 YR RDS & Elasticache RIs<br />(2 AZ Cost Estimate is in BOM Below) |
+| [5K](../../administration/reference_architectures/5k_users.md#cloud-native-hybrid-reference-architecture-with-helm-charts-alternative) | [5k Baseline](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/5k) | [5K Cloud Native Hybrid on EKS](#5k-cloud-native-hybrid-on-eks) | [5K Full Scale GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/5K/5k-QuickStart-ARM-RDS-Redis_v13-12-3-ee_2021-07-23_140128/5k-QuickStart-ARM-RDS-Redis_v13-12-3-ee_2021-07-23_140128_results.txt)<br /><br />[5K AutoScale from 25% GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/5K/5k-QuickStart-AutoScale-From-25Percent-ARM-RDS-Redis_v13-12-3-ee_2021-07-24_102717/5k-QuickStart-AutoScale-From-25Percent-ARM-RDS-Redis_v13-12-3-ee_2021-07-24_102717_results.txt) | 1 YR Ec2 Compute Savings + 1 YR RDS & Elasticache RIs |
+| [10K](../../administration/reference_architectures/10k_users.md#cloud-native-hybrid-reference-architecture-with-helm-charts-alternative) | [10k Baseline](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/10k) | [10K Cloud Native Hybrid on EKS](#10k-cloud-native-hybrid-on-eks) | [10K Full Scale GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/10K/GL-CloudNative-10k-RDS-Graviton_v13-12-3-ee_2021-07-08_194647/GL-CloudNative-10k-RDS-Graviton_v13-12-3-ee_2021-07-08_194647_results.txt)<br /><br />[10K AutoScale GPT Test Results](hhttps://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/10K/GL-CloudNative-10k-AutoScaling-Test_v13-12-3-ee_2021-07-09_115139/GL-CloudNative-10k-AutoScaling-Test_v13-12-3-ee_2021-07-09_115139_results.txt) | [10K 1 YR Ec2 Compute Savings + 1 YR RDS & Elasticache RIs](https://calculator.aws/#/estimate?id=5ac2e07a22e01c36ee76b5477c5a046cd1bea792) |
+| [50K](../../administration/reference_architectures/50k_users.md#cloud-native-hybrid-reference-architecture-with-helm-charts-alternative) | [50k Baseline](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/50k) | [50K Cloud Native Hybrid on EKS](#50k-cloud-native-hybrid-on-eks) | [50K Full Scale GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/50K/50k-Fixed-Scale-Test_v13-12-3-ee_2021-08-13_172819/50k-Fixed-Scale-Test_v13-12-3-ee_2021-08-13_172819_results.txt)<br /><br />[10K AutoScale GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/50K/50k-AutoScale-Test_v13-12-3-ee_2021-08-13_192633/50k-AutoScale-Test_v13-12-3-ee_2021-08-13_192633.txt) | 10K 1 YR Ec2 Compute Savings + 1 YR RDS & Elasticache RIs |
+
+## Available Infrastructure as Code for GitLab Cloud Native Hybrid
+
+The [AWS Quick Start for GitLab Cloud Native Hybrid on EKS](https://aws-quickstart.github.io/quickstart-eks-gitlab/) is developed by AWS, GitLab, and the community that contributes to AWS Quick Starts, whether directly to the GitLab Quick Start or to the underlying Quick Start dependencies GitLab inherits (for example, EKS Quick Start).
+
+NOTE:
+This automation is in **Developer Preview**. GitLab is working with AWS on [these outstanding issues](https://github.com/aws-quickstart/quickstart-eks-gitlab/issues?q=is%3Aissue+is%3Aopen+%5BHL%5D) before it is fully released.
+
+The [GitLab Environment Toolkit (GET)](https://gitlab.com/gitlab-org/quality/gitlab-environment-toolkit/-/tree/master) is an effort made by GitLab to create a multi-cloud, multi-GitLab (Omnibus + Cloud Native Hybrid) toolkit to provision GitLab. GET is developed by GitLab developers and is open to community contributions.
+It is helpful to review the [GitLab Environment Toolkit (GET) Issues](https://gitlab.com/gitlab-org/quality/gitlab-environment-toolkit/-/issues) to understand if any of them may affect your provisioning plans.
+
+| | [AWS Quick Start for GitLab Cloud Native Hybrid on EKS](https://aws-quickstart.github.io/quickstart-eks-gitlab/) | [GitLab Environment Toolkit (GET)](https://gitlab.com/gitlab-org/quality/gitlab-environment-toolkit/-/tree/master) |
+| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| GitLab Reference Architecture Compliant | Yes | Yes |
+| GitLab Performance Tool (GPT) Tested | Yes | Yes |
+| Amazon Well Architected Compliant | Yes<br />(via Quick Start program) | Critical portions <br />reviewed by AWS |
+| Target Cloud Platforms | AWS | AWS, Google, Azure |
+| IaC Languages | CloudFormation (Quick Starts) | Terraform, Ansible |
+| Community Contributions and Participation (EcoSystem) | <u>GitLab QSG</u>: Getting Started<br /><u>For QSG Dependencies (e.g. EKS)</u>: Substantial | Getting Started |
+| Compatible with AWS Meta-Automation Services (via CloudFormation) | Service Catalog (Direct Import), Control Tower<br />Quick Starts, SaaS Factory | No |
+| Results in a Ready-to-Use instance | Yes | Manual Actions or <br />Supplemental IaC Required |
+| **<u>Configuration Features</u>** | | |
+| Can deploy Omnibus GitLab (non-Kubernetes | No | Yes |
+| Complete Internal Encryption | 85%, Targeting 100% | Manual |
+| AWS GovCloud Support | Yes | TBD |
+
+### Streamlined Performance Testing of AWS Quick Start Prepared GitLab Instances
+
+A set of performance testing instructions have been abbreviated for testing a GitLab instance prepared using the AWS Quick Start for GitLab Cloud Native Hybrid on EKS. They assume zero familiarity with GitLab Performance Tool. They can be accessed here: [Performance Testing an Instance Prepared using AWS Quick Start for GitLab Cloud Native Hybrid on EKS](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/Easy-DIY-Perf-Testing.md).
+
+### AWS GovCloud Support for AWS Quick Start for GitLab CNH on EKS
+
+The AWS Quick Start for GitLab Cloud Native Hybrid on EKS has been tested with GovCloud and works with the following restrictions and understandings.
+
+- GovCloud does not have public Route53 hosted zones, so you must set the following parameters:
+
+ | CloudFormation Quick Start form field | CloudFormation Parameter | Setting |
+ | --------------------------------------------------- | ------------------------ | ------- |
+ | **Create Route 53 hosted zone** | CreatedHostedZone | No |
+ | **Request AWS Certificate Manager SSL certificate** | CreateSslCertificate | No |
+
+- The Quick Start creates public load balancer IPs, so that you can easily configure your local hosts file to get to the GUI for GitLab when deploying tests. However, you may need to manually alter this if public load balancers are not part of your provisioning plan. We are planning to make non-public load balancers a configuration option issue link: [Short Term: Documentation and/or Automation for private GitLab instance with no internet Ingress](https://github.com/aws-quickstart/quickstart-eks-gitlab/issues/55)
+- As of 2021-08-19, AWS GovCloud has Graviton instances for Aurora PostgreSQL available, but does not for ElastiCache Redis.
+- It is challenging to get the Quick Start template to load in GovCloud from the Standard Quick Start URL, so the generic ones are provided here:
+ - [Launch for New VPC in us-gov-east-1](https://us-gov-east-1.console.amazonaws-us-gov.com/cloudformation/home?region=us-gov-east-1#/stacks/quickcreate?templateUrl=https://aws-quickstart.s3.us-east-1.amazonaws.com/quickstart-eks-gitlab/templates/gitlab-entry-new-vpc.template.yaml&stackName=Gitlab-for-EKS-New-VPC)
+ - [Launch for New VPC in us-gov-west-1](https://us-gov-west-1.console.amazonaws-us-gov.com/cloudformation/home?region=us-gov-west-1#/stacks/quickcreate?templateUrl=https://aws-quickstart.s3.us-east-1.amazonaws.com/quickstart-eks-gitlab/templates/gitlab-entry-new-vpc.template.yaml&stackName=Gitlab-for-EKS-New-VPC)
+
+## AWS PaaS qualified for all GitLab implementations
+
+For both Omnibus GitLab or Cloud Native Hybrid implementations, the following GitLab Service roles can be performed by AWS Services (PaaS). Any PaaS solutions that require preconfigured sizing based on the scale of your instance will also be listed in the per-instance size Bill of Materials lists. Those PaaS that do not require specific sizing, are not repeated in the BOM lists (for example, AWS Certification Manager).
+
+These services have been tested with GitLab.
+
+Some services, such as log aggregation, outbound email are not specified by GitLab, but where provided are noted.
+
+| GitLab Services | AWS PaaS (Tested) | Provided by AWS Cloud <br />Native Hybrid Quick Start |
+| ------------------------------------------------------------ | ------------------------------ | ------------------------------------------------------------ |
+| <u>Tested PaaS Mentioned in Reference Architectures</u> | | |
+| **PostgreSQL Database** | Aurora RDS | Yes. |
+| **Redis Caching** | Redis Elasticache | Yes. |
+| **Gitaly Cluster (Git Repository Storage)**<br />(Including Praefect and PostgreSQL) | ASG and Instances | Yes - ASG and Instances<br />**Note: Gitaly cannot be put into a Kubernetes Cluster.** |
+| **All GitLab storages besides Git Repository Storage**<br />(Includes Git-LFS which is S3 Compatible) | AWS S3 | Yes |
+| | | |
+| <u>Tested PaaS for Supplemental Services</u> | | |
+| **Front End Load Balancing** | AWS ELB | Yes |
+| **Internal Load Balancing** | AWS ELB | Yes |
+| **Outbound Email Services** | AWS Simple Email Service (SES) | Yes |
+| **Certificate Authority and Management** | AWS Certificate Manager (ACM) | Yes |
+| **DNS** | AWS Route53 (tested) | Yes |
+| **GitLab and Infrastructure Log Aggregation** | AWS CloudWatch Logs | Yes (ContainerInsights Agent for EKS) |
+| **Infrastructure Performance Metrics** | AWS CloudWatch Metrics | Yes |
+| | | |
+| <u>Supplemental Services and Configurations (Tested)</u> | | |
+| **Prometheus for GitLab** | AWS EKS (Cloud Native Only) | Yes |
+| **Grafana for GitLab** | AWS EKS (Cloud Native Only) | Yes |
+| **Administrative Access to GitLab Backend** | Bastion Host in VPC | Yes - HA - Preconfigured for Cluster Management. |
+| **Encryption (In Transit / At Rest)** | AWS KMS | Yes |
+| **Secrets Storage for Provisioning** | AWS Secrets Manager | Yes |
+| **Configuration Data for Provisioning** | AWS Parameter Store | Yes |
+| **AutoScaling Kubernetes** | EKS AutoScaling Agent | Yes |
+
+## GitLab Cloud Native Hybrid on AWS
+
+### 2K Cloud Native Hybrid on EKS
+
+**2K Cloud Native Hybrid on EKS Bill of Materials (BOM)**
+
+**GPT Test Results**
+
+- [3K Full Scale GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/3K/3k-QuickStart-ARM-RDS-Cache_v13-12-3-ee_2021-07-23_124216/3k-QuickStart-ARM-RDS-Cache_v13-12-3-ee_2021-07-23_124216_results.txt)
+
+- [3K AutoScale GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/3K/3k-QuickStart-AutoScale-ARM-RDS-Cache_v13-12-3-ee_2021-07-23_194200/3k-QuickStart-AutoScale-ARM-RDS-Cache_v13-12-3-ee_2021-07-23_194200_results.txt)
+
+ **Deploy Now**
+ Deploy Now links leverage the AWS Quick Start automation and only prepopulate the number of instances and instance types for the Quick Start based on the Bill of Meterials below. You must provide appropriate input for all other parameters by following the guidance in the [Quick Start documentation's Deployment steps](https://aws-quickstart.github.io/quickstart-eks-gitlab/#_deployment_steps) section.
+
+- **Deploy Now: AWS Quick Start for 2 AZs**
+- **Deploy Now: AWS Quick Start for 3 AZs**
+
+NOTE:
+On Demand pricing is used in this table for comparisons, but should not be used for budgeting nor purchasing AWS resources for a GitLab production instance. Do not use these tables to calculate actual monthly or yearly price estimates, instead use the AWS Calculator links in the "GitLab on AWS Compute" table above and customize it with your desired savings plan.
+
+**BOM Total:** = Bill of Materials Total - this is what you use when building this configuration
+
+**Ref Arch Raw Total:** = The totals if the configuration was built on regular VMs with no PaaS services. Configuring on pure VMs generally requires additional VMs for cluster management activities.
+
+**Idle Configuration (Scaled-In)** = can be used to scale-in during time of low demand and/or for warm standby Geo instances. Requires configuration, testing and management of EKS autoscaling to meet your internal requirements.
+
+| Service | Ref Arch Raw (Full Scaled) | AWS BOM | Example Full Scaled Cost<br />(On Demand, US East) |
+| ------------------------------------------------------------ | -------------------------- | ------------------------------------------------------------ | -------------------------------------------------- |
+| Webservice | 12 vCPU,16 GB | | |
+| Sidekiq | 2 vCPU, 8 GB | | |
+| Supporting services such as NGINX, Prometheus, etc | 2 vCPU, 8 GB | | |
+| **GitLab Ref Arch Raw Total K8s Node Capacity** | 16 vCPU, 32 GB | | |
+| One Node for Overhead and Miscellaneous (EKS Cluster AutoScaler, Grafana, Prometheus, etc) | + 8 vCPU, 16GB | | |
+| **Grand Total w/ Overheads**<br />Minimum hosts = 3 | 24 vCPU, 48 GB | **c5.2xlarge** <br />(8vcpu/16GB) x 3 nodes<br />24 vCPU, 48 GB | $1.02/hr |
+| **Idle Configuration (Scaled-In)** | 16 vCPU, 32 GB | **c5.2xlarge** x 2 | $0.68/hr |
+
+NOTE:
+If EKS node autoscaling is employed, it is likely that your average loading will run lower than this, especially during non-working hours and weekends.
+
+| Non-Kubernetes Compute | Ref Arch Raw Total | AWS BOM<br />(Directly Usable in AWS Quick Start) | Example Cost<br />US East, 3 AZ | Example Cost<br />US East, 2 AZ |
+| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------- | ------------------------------- | ---------------------------------------------------- |
+| **Bastion Host (Quick Start)** | 1 HA instance in ASG | **t2.micro** for prod, **m4.2xlarge** for perf. testing | | |
+| **PostgreSQL**<br />AWS Aurora RDS Nodes Configuration (GPT tested) | 2vCPU, 7.5 GB<br />Tested with Graviton ARM | **db.r6g.large** x 3 nodes <br />(6vCPU, 48 GB) | 3 nodes x $0.26 = $0.78/hr | 3 nodes x $0.26 = $0.78/hr<br />(Aurora is always 3) |
+| **Redis** | 1vCPU, 3.75GB<br />(across 12 nodes for Redis Cache, Redis Queues/Shared State, Sentinel Cache, Sentinel Queues/Shared State) | **cache.m6g.large** x 3 nodes<br />(6vCPU, 19GB) | 3 nodes x $0.15 = $0.45/hr | 2 nodes x $0.15 = $0.30/hr |
+| **<u>Gitaly Cluster</u>** [Details](gitlab_sre_for_aws.md#gitaly-sre-considerations) | [Gitaly & Praefect Must Have an Uneven Node Count for HA](gitlab_sre_for_aws.md#gitaly-and-praefect-elections) | | | |
+| Gitaly Instances (in ASG) | 12 vCPU, 45GB<br />(across 3 nodes) | **m5.xlarge** x 3 nodes<br />(48 vCPU, 180 GB) | $0.192 x 3 = $0.58/hr | $0.192 x 3 = $0.58/hr |
+| | The GitLab Reference architecture for 2K is not Highly Available and therefore has a single Gitaly no Praefect. AWS Quick Starts MUST be HA, so it implements Prafect from the 3K Ref Architecture to meet that requirement | | | |
+| Praefect (Instances in ASG with load balancer) | 6 vCPU, 10 GB<br />([across 3 nodes](gitlab_sre_for_aws.md#gitaly-and-praefect-elections)) | **c5.large** x 3 nodes<br />(6 vCPU, 12 GB) | $0.09 x 3 = $0.21/hr | $0.09 x 3 = $0.21/hr |
+| Praefect PostgreSQL(1) (AWS RDS) | 6 vCPU, 5.4 GB<br />([across 3 nodes](gitlab_sre_for_aws.md#gitaly-and-praefect-elections)) | N/A Reuses GitLab PostgreSQL | $0 | $0 |
+| Internal Load Balancing Node | 2 vCPU, 1.8 GB | AWS ELB | $0.10/hr | $0.10/hr |
+
+### 3K Cloud Native Hybrid on EKS
+
+**3K Cloud Native Hybrid on EKS Bill of Materials (BOM)**
+
+**GPT Test Results**
+
+- [5K Full Scale GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/5K/5k-QuickStart-ARM-RDS-Redis_v13-12-3-ee_2021-07-23_140128/5k-QuickStart-ARM-RDS-Redis_v13-12-3-ee_2021-07-23_140128_results.txt)
+- [5K AutoScale from 25% GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/5K/5k-QuickStart-AutoScale-From-25Percent-ARM-RDS-Redis_v13-12-3-ee_2021-07-24_102717/5k-QuickStart-AutoScale-From-25Percent-ARM-RDS-Redis_v13-12-3-ee_2021-07-24_102717_results.txt)
+
+**Deploy Now**
+
+Deploy Now links leverage the AWS Quick Start automation and only prepopulate the number of instances and instance types for the Quick Start based on the Bill of Meterials below. You must provide appropriate input for all other parameters by following the guidance in the [Quick Start documentation's Deployment steps](https://aws-quickstart.github.io/quickstart-eks-gitlab/#_deployment_steps) section.
+
+- **[Deploy Now: AWS Quick Start for 2 AZs](https://us-east-2.console.aws.amazon.com/cloudformation/home?region=us-east-2#/stacks/quickcreate?templateUrl=https://aws-quickstart.s3.us-east-1.amazonaws.com/quickstart-eks-gitlab/templates/gitlab-entry-new-vpc.template.yaml&stackName=Gitlab-EKS-3K-Users-2AZs&param_NumberOfAZs=2&param_NodeInstanceType=c5.2xlarge&param_NumberOfNodes=3&param_MaxNumberOfNodes=3&param_DBInstanceClass=db.r6g.xlarge&param_CacheNodes=2&param_CacheNodeType=cache.m6g.large&param_GitalyInstanceType=m5.large&param_NumberOfGitalyReplicas=3&param_PraefectInstanceType=c5.large&param_NumberOfPraefectReplicas=3)**
+- **[Deploy Now: AWS Quick Start for 3 AZs](https://us-east-2.console.aws.amazon.com/cloudformation/home?region=us-east-2#/stacks/quickcreate?templateUrl=https://aws-quickstart.s3.us-east-1.amazonaws.com/quickstart-eks-gitlab/templates/gitlab-entry-new-vpc.template.yaml&stackName=Gitlab-EKS-3K-Users-3AZs&param_NumberOfAZs=3&param_NodeInstanceType=c5.2xlarge&param_NumberOfNodes=3&param_MaxNumberOfNodes=3&param_DBInstanceClass=db.r6g.xlarge&param_CacheNodes=3&param_CacheNodeType=cache.m6g.large&param_GitalyInstanceType=m5.large&param_NumberOfGitalyReplicas=3&param_PraefectInstanceType=c5.large&param_NumberOfPraefectReplicas=3)**
+
+NOTE:
+On Demand pricing is used in this table for comparisons, but should not be used for budgeting nor purchasing AWS resources for a GitLab production instance. Do not use these tables to calculate actual monthly or yearly price estimates, instead use the AWS Calculator links in the "GitLab on AWS Compute" table above and customize it with your desired savings plan.
+
+**BOM Total:** = Bill of Materials Total - this is what you use when building this configuration
+
+**Ref Arch Raw Total:** = The totals if the configuration was built on regular VMs with no PaaS services. Configuring on pure VMs generally requires additional VMs for cluster management activities.
+
+ **Idle Configuration (Scaled-In)** = can be used to scale-in during time of low demand and/or for warm standby Geo instances. Requires configuration, testing and management of EKS autoscaling to meet your internal requirements.
+
+| Service | Ref Arch Raw (Full Scaled) | AWS BOM | Example Full Scaled Cost<br />(On Demand, US East) |
+| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | -------------------------------------------------- |
+| Webservice | [4 pods](https://gitlab.com/gitlab-org/charts/gitlab/-/blob/master/examples/ref/3k.yaml#L7) x ([5 vCPU & 6.25 GB](../../administration/reference_architectures/3k_users.md#webservice)) = <br />20 vCPU, 25 GB | | |
+| Sidekiq | [8 pods](https://gitlab.com/gitlab-org/charts/gitlab/-/blob/master/examples/ref/3k.yaml#L24) x ([1 vCPU & 2 GB](../../administration/reference_architectures/3k_users.md#sidekiq)) = <br />8 vCPU, 16 GB | | |
+| Supporting services such as NGINX, Prometheus, etc | [2 allocations](../../administration/reference_architectures/3k_users.md#cluster-topology) x ([2 vCPU and 7.5 GB](../../administration/reference_architectures/3k_users.md#cluster-topology)) = <br />4 vCPU, 15 GB | | |
+| **GitLab Ref Arch Raw Total K8s Node Capacity** | 32 vCPU, 56 GB | | |
+| One Node for Overhead and Miscellaneous (EKS Cluster AutoScaler, Grafana, Prometheus, etc) | + 16 vCPU, 32GB | | |
+| **Grand Total w/ Overheads Full Scale**<br />Minimum hosts = 3 | 48 vCPU, 88 GB | **c5.2xlarge** (8vcpu/16GB) x 5 nodes<br />40 vCPU, 80 GB<br />[Full Scale GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/3K/3k-QuickStart-ARM-RDS-Cache_v13-12-3-ee_2021-07-23_124216/3k-QuickStart-ARM-RDS-Cache_v13-12-3-ee_2021-07-23_124216_results.txt) | $1.70/hr |
+| **Possible Idle Configuration (Scaled-In 75% - round up)**<br />Pod autoscaling must be also adjusted to enable lower idling configuration. | 24 vCPU, 48 GB | c5.2xlarge x 4 | $1.36/hr |
+
+Other combinations of node type and quantity can be used to meet the Grand Total. Due to the properties of pods, hosts that are overly small may have significant unused capacity.
+
+NOTE:
+If EKS node autoscaling is employed, it is likely that your average loading will run lower than this, especially during non-working hours and weekends.
+
+| Non-Kubernetes Compute | Ref Arch Raw Total | AWS BOM<br />(Directly Usable in AWS Quick Start) | Example Cost<br />US East, 3 AZ | Example Cost<br />US East, 2 AZ |
+| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------- | ------------------------------- | ------------------------------------------------------------ |
+| **Bastion Host (Quick Start)** | 1 HA instance in ASG | **t2.micro** for prod, **m4.2xlarge** for perf. testing | | |
+| **PostgreSQL**<br />AWS Aurora RDS Nodes Configuration (GPT tested) | 18vCPU, 36 GB <br />(across 9 nodes for PostgreSQL, PgBouncer, Consul)<br />Tested with Graviton ARM | **db.r6g.xlarge** x 3 nodes <br />(12vCPU, 96 GB) | 3 nodes x $0.52 = $1.56/hr | 3 nodes x $0.52 = $1.56/hr<br />(Aurora is always 3) |
+| **Redis** | 6vCPU, 18GB<br />(across 6 nodes for Redis Cache, Sentinel) | **cache.m6g.large** x 3 nodes<br />(6vCPU, 19GB) | 3 nodes x $0.15 = $0.45/hr | 2 nodes x $0.15 = $0.30/hr |
+| **<u>Gitaly Cluster</u>** [Details](gitlab_sre_for_aws.md#gitaly-sre-considerations) | | | | |
+| Gitaly Instances (in ASG) | 12 vCPU, 45GB<br />([across 3 nodes](gitlab_sre_for_aws.md#gitaly-and-praefect-elections)) | **m5.large** x 3 nodes<br />(12 vCPU, 48 GB) | $0.192 x 3 = $0.58/hr | [Gitaly & Praefect Must Have an Uneven Node Count for HA](gitlab_sre_for_aws.md#gitaly-and-praefect-elections) |
+| Praefect (Instances in ASG with load balancer) | 6 vCPU, 5.4 GB<br />([across 3 nodes](gitlab_sre_for_aws.md#gitaly-and-praefect-elections)) | **c5.large** x 3 nodes<br />(6 vCPU, 12 GB) | $0.09 x 3 = $0.21/hr | [Gitaly & Praefect Must Have an Uneven Node Count for HA](gitlab_sre_for_aws.md#gitaly-and-praefect-elections) |
+| Praefect PostgreSQL(1) (AWS RDS) | 6 vCPU, 5.4 GB<br />([across 3 nodes](gitlab_sre_for_aws.md#gitaly-and-praefect-elections)) | N/A Reuses GitLab PostgreSQL | $0 | |
+| Internal Load Balancing Node | 2 vCPU, 1.8 GB | AWS ELB | $0.10/hr | $0.10/hr |
+
+### 5K Cloud Native Hybrid on EKS
+
+**5K Cloud Native Hybrid on EKS Bill of Materials (BOM)**
+
+**GPT Test Results**
+
+- [5K Full Scale GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/5K/5k-QuickStart-ARM-RDS-Redis_v13-12-3-ee_2021-07-23_140128/5k-QuickStart-ARM-RDS-Redis_v13-12-3-ee_2021-07-23_140128_results.txt)
+- [5K AutoScale from 25% GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/5K/5k-QuickStart-AutoScale-From-25Percent-ARM-RDS-Redis_v13-12-3-ee_2021-07-24_102717/5k-QuickStart-AutoScale-From-25Percent-ARM-RDS-Redis_v13-12-3-ee_2021-07-24_102717_results.txt)
+
+**Deploy Now**
+
+Deploy Now links leverage the AWS Quick Start automation and only prepopulate the number of instances and instance types for the Quick Start based on the Bill of Meterials below. You must provide appropriate input for all other parameters by following the guidance in the [Quick Start documentation's Deployment steps](https://aws-quickstart.github.io/quickstart-eks-gitlab/#_deployment_steps) section.
+
+- **[Deploy Now: AWS Quick Start for 2 AZs](https://us-east-2.console.aws.amazon.com/cloudformation/home?region=us-east-2#/stacks/quickcreate?templateUrl=https://aws-quickstart.s3.us-east-1.amazonaws.com/quickstart-eks-gitlab/templates/gitlab-entry-new-vpc.template.yaml&stackName=Gitlab-EKS-5K-Users-2AZs&param_NumberOfAZs=2&param_NodeInstanceType=c5.2xlarge&param_NumberOfNodes=5&param_MaxNumberOfNodes=5&param_DBInstanceClass=db.r6g.2xlarge&param_CacheNodes=2&param_CacheNodeType=cache.m6g.xlarge&param_GitalyInstanceType=m5.2xlarge&param_NumberOfGitalyReplicas=2&param_PraefectInstanceType=c5.large&param_NumberOfPraefectReplicas=2)**
+- **[Deploy Now: AWS Quick Start for 3 AZs](https://us-east-2.console.aws.amazon.com/cloudformation/home?region=us-east-2#/stacks/quickcreate?templateUrl=https://aws-quickstart.s3.us-east-1.amazonaws.com/quickstart-eks-gitlab/templates/gitlab-entry-new-vpc.template.yaml&stackName=Gitlab-EKS-5K-Users-3AZs&param_NumberOfAZs=3&param_NodeInstanceType=c5.2xlarge&param_NumberOfNodes=5&param_MaxNumberOfNodes=5&param_DBInstanceClass=db.r6g.2xlarge&param_CacheNodes=3&param_CacheNodeType=cache.m6g.xlarge&param_GitalyInstanceType=m5.2xlarge&param_NumberOfGitalyReplicas=3&param_PraefectInstanceType=c5.large&param_NumberOfPraefectReplicas=3)**
+
+NOTE:
+On Demand pricing is used in this table for comparisons, but should not be used for budgeting nor purchasing AWS resources for a GitLab production instance. Do not use these tables to calculate actual monthly or yearly price estimates, instead use the AWS Calculator links in the "GitLab on AWS Compute" table above and customize it with your desired savings plan.
+
+**BOM Total:** = Bill of Materials Total - this is what you use when building this configuration
+
+**Ref Arch Raw Total:** = The totals if the configuration was built on regular VMs with no PaaS services. Configuring on pure VMs generally requires additional VMs for cluster management activities.
+
+**Idle Configuration (Scaled-In)** = can be used to scale-in during time of low demand and/or for warm standby Geo instances. Requires configuration, testing and management of EKS autoscaling to meet your internal requirements.
+
+| Service | Ref Arch Raw (Full Scaled) | AWS BOM | Example Full Scaled Cost<br />(On Demand, US East) |
+| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | -------------------------------------------------- |
+| Webservice | [10 pods](https://gitlab.com/gitlab-org/charts/gitlab/-/blob/master/examples/ref/5k.yaml#L7) x ([5 vCPU & 6.25GB](../../administration/reference_architectures/5k_users.md#webservice)) = <br />50 vCPU, 62.5 GB | | |
+| Sidekiq | [8 pods](https://gitlab.com/gitlab-org/charts/gitlab/-/blob/master/examples/ref/5k.yaml#L24) x ([1 vCPU & 2 GB](../../administration/reference_architectures/5k_users.md#sidekiq)) = <br />8 vCPU, 16 GB | | |
+| Supporting services such as NGINX, Prometheus, etc | [2 allocations](../../administration/reference_architectures/5k_users.md#cluster-topology) x ([2 vCPU and 7.5 GB](../../administration/reference_architectures/5k_users.md#cluster-topology)) = <br />4 vCPU, 15 GB | | |
+| **GitLab Ref Arch Raw Total K8s Node Capacity** | 62 vCPU, 96.5 GB | | |
+| One Node for Quick Start Overhead and Miscellaneous (EKS Cluster AutoScaler, Grafana, Prometheus, etc) | + 8 vCPU, 16GB | | |
+| **Grand Total w/ Overheads Full Scale**<br />Minimum hosts = 3 | 70 vCPU, 112.5 GB | **c5.2xlarge** (8vcpu/16GB) x 9 nodes<br />72 vCPU, 144 GB<br />[Full Scale GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/5K/5k-QuickStart-ARM-RDS-Redis_v13-12-3-ee_2021-07-23_140128/5k-QuickStart-ARM-RDS-Redis_v13-12-3-ee_2021-07-23_140128_results.txt) | $2.38/hr |
+| **Possible Idle Configuration (Scaled-In 75% - round up)**<br />Pod autoscaling must be also adjusted to enable lower idling configuration. | 24 vCPU, 48 GB | c5.2xlarge x 7 | $1.85/hr |
+
+Other combinations of node type and quantity can be used to meet the Grand Total. Due to the cpu and memory requirements of pods, hosts that are overly small may have significant unused capacity.
+
+NOTE:
+If EKS node autoscaling is employed, it is likely that your average loading will run lower than this, especially during non-working hours and weekends.
+
+| Non-Kubernetes Compute | Ref Arch Raw Total | AWS BOM<br />(Directly Usable in AWS Quick Start) | Example Cost<br />US East, 3 AZ | Example Cost<br />US East, 2 AZ |
+| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------- | ------------------------------- | ------------------------------------------------------------ |
+| **Bastion Host (Quick Start)** | 1 HA instance in ASG | **t2.micro** for prod, **m4.2xlarge** for perf. testing | | |
+| **PostgreSQL**<br />AWS Aurora RDS Nodes Configuration (GPT tested) | 21vCPU, 51 GB <br />(across 9 nodes for PostgreSQL, PgBouncer, Consul)<br />Tested with Graviton ARM | **db.r6g.2xlarge** x 3 nodes <br />(24vCPU, 192 GB) | 3 nodes x $1.04 = $3.12/hr | 3 nodes x $1.04 = $3.12/hr<br />(Aurora is always 3) |
+| **Redis** | 9vCPU, 27GB<br />(across 6 nodes for Redis, Sentinel) | **cache.m6g.xlarge** x 3 nodes<br />(12vCPU, 39GB) | 3 nodes x $0.30 = $0.90/hr | 2 nodes x $0.30 = $0.60/hr |
+| **<u>Gitaly Cluster</u>** [Details](gitlab_sre_for_aws.md#gitaly-sre-considerations) | | | | |
+| Gitaly Instances (in ASG) | 24 vCPU, 90GB<br />([across 3 nodes](gitlab_sre_for_aws.md#gitaly-and-praefect-elections)) | **m5.2xlarge** x 3 nodes<br />(24 vCPU, 96GB) | $0.384 x 3 = $1.15/hr | [Gitaly & Praefect Must Have an Uneven Node Count for HA](gitlab_sre_for_aws.md#gitaly-and-praefect-elections) |
+| Praefect (Instances in ASG with load balancer) | 6 vCPU, 5.4 GB<br />([across 3 nodes](gitlab_sre_for_aws.md#gitaly-and-praefect-elections)) | **c5.large** x 3 nodes<br />(6 vCPU, 12 GB) | $0.09 x 3 = $0.21/hr | [Gitaly & Praefect Must Have an Uneven Node Count for HA](gitlab_sre_for_aws.md#gitaly-and-praefect-elections) |
+| Praefect PostgreSQL(1) (AWS RDS) | 6 vCPU, 5.4 GB<br />([across 3 nodes](gitlab_sre_for_aws.md#gitaly-and-praefect-elections)) | N/A Reuses GitLab PostgreSQL | $0 | |
+| Internal Load Balancing Node | 2 vCPU, 1.8 GB | AWS ELB | $0.10/hr | $0.10/hr |
+
+### 10K Cloud Native Hybrid on EKS
+
+**10K Cloud Native Hybrid on EKS Bill of Materials (BOM)**
+
+**GPT Test Results**
+
+- [10K Full Scale GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/10K/GL-CloudNative-10k-RDS-Graviton_v13-12-3-ee_2021-07-08_194647/GL-CloudNative-10k-RDS-Graviton_v13-12-3-ee_2021-07-08_194647_results.txt)
+- [10K AutoScale GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/10K/GL-CloudNative-10k-AutoScaling-Test_v13-12-3-ee_2021-07-09_115139/GL-CloudNative-10k-AutoScaling-Test_v13-12-3-ee_2021-07-09_115139_results.txt)
+
+**Deploy Now**
+
+Deploy Now links leverage the AWS Quick Start automation and only prepopulate the number of instances and instance types for the Quick Start based on the Bill of Meterials below. You must provide appropriate input for all other parameters by following the guidance in the [Quick Start documentation's Deployment steps](https://aws-quickstart.github.io/quickstart-eks-gitlab/#_deployment_steps) section.
+
+- **[Deploy Now: AWS Quick Start for 3 AZs](https://us-east-2.console.aws.amazon.com/cloudformation/home?region=us-east-2#/stacks/quickcreate?templateUrl=https://aws-quickstart.s3.us-east-1.amazonaws.com/quickstart-eks-gitlab/templates/gitlab-entry-new-vpc.template.yaml&stackName=Gitlab-EKS-10K-Users-3AZs&param_NumberOfAZs=3&param_NodeInstanceType=c5.4xlarge&param_NumberOfNodes=9&param_MaxNumberOfNodes=9&param_DBInstanceClass=db.r6g.2xlarge&param_CacheNodes=3&param_CacheNodeType=cache.m6g.2xlarge&param_GitalyInstanceType=m5.4xlarge&param_NumberOfGitalyReplicas=3&param_PraefectInstanceType=c5.large&param_NumberOfPraefectReplicas=3)**
+
+NOTE:
+On Demand pricing is used in this table for comparisons, but should not be used for budgeting nor purchasing AWS resources for a GitLab production instance. Do not use these tables to calculate actual monthly or yearly price estimates, instead use the AWS Calculator links in the "GitLab on AWS Compute" table above and customize it with your desired savings plan.
+
+**BOM Total:** = Bill of Materials Total - this is what you use when building this configuration
+
+**Ref Arch Raw Total:** = The totals if the configuration was built on regular VMs with no PaaS services. Configuring on pure VMs generally requires additional VMs for cluster management activities.
+
+ **Idle Configuration (Scaled-In)** = can be used to scale-in during time of low demand and/or for warm standby Geo instances. Requires configuration, testing and management of EKS autoscaling to meet your internal requirements.
+
+| Service | Ref Arch Raw (Full Scaled) | AWS BOM<br />(Directly Usable in AWS Quick Start) | Example Full Scaled Cost<br />(On Demand, US East) |
+| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | -------------------------------------------------- |
+| Webservice | [20 pods](https://gitlab.com/gitlab-org/charts/gitlab/-/blob/master/examples/ref/10k.yaml#L7) x ([5 vCPU & 6.25 GB](../../administration/reference_architectures/10k_users.md#webservice)) = <br />100 vCPU, 125 GB | | |
+| Sidekiq | [14 pods](https://gitlab.com/gitlab-org/charts/gitlab/-/blob/master/examples/ref/10k.yaml#L24) x ([1 vCPU & 2 GB](../../administration/reference_architectures/10k_users.md#sidekiq))<br />14 vCPU, 28 GB | | |
+| Supporting services such as NGINX, Prometheus, etc | [2 allocations](../../administration/reference_architectures/10k_users.md#cluster-topology) x ([2 vCPU and 7.5 GB](../../administration/reference_architectures/10k_users.md#cluster-topology))<br />4 vCPU, 15 GB | | |
+| **GitLab Ref Arch Raw Total K8s Node Capacity** | 128 vCPU, 158 GB | | |
+| One Node for Overhead and Miscellaneous (EKS Cluster AutoScaler, Grafana, Prometheus, etc) | + 16 vCPU, 32GB | | |
+| **Grand Total w/ Overheads Fully Scaled**<br />Minimum hosts = 3 | 142 vCPU, 190 GB | **c5.4xlarge** (16vcpu/32GB) x 9 nodes<br />144 vCPU, 288GB<br /><br />[Full Scale GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/10K/GL-CloudNative-10k-RDS-Graviton_v13-12-3-ee_2021-07-08_194647/GL-CloudNative-10k-RDS-Graviton_v13-12-3-ee_2021-07-08_194647_results.txt) | $6.12/hr |
+| **Possible Idle Configuration (Scaled-In 75% - round up)**<br />Pod autoscaling must be also adjusted to enable lower idling configuration. | 40 vCPU, 80 GB | c5.4xlarge x 7<br /><br />[AutoScale GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/10K/GL-CloudNative-10k-AutoScaling-Test_v13-12-3-ee_2021-07-09_115139/GL-CloudNative-10k-AutoScaling-Test_v13-12-3-ee_2021-07-09_115139_results.txt) | $4.76/hr |
+
+Other combinations of node type and quantity can be used to meet the Grand Total. Due to the cpu and memory requirements of pods, hosts that are overly small may have significant unused capacity.
+
+NOTE:
+If EKS node autoscaling is employed, it is likely that your average loading will run lower than this, especially during non-working hours and weekends.
+
+| Non-Kubernetes Compute | Ref Arch Raw Total | AWS BOM | Example Cost<br />US East, 3 AZ | Example Cost<br />US East, 2 AZ |
+| ------------------------------------------------------------ | ------------------------------ | ------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| **Bastion Host (Quick Start)** | 1 HA instance in ASG | **t2.micro** for prod, **m4.2xlarge** for perf. testing | | |
+| **PostgreSQL**<br />AWS Aurora RDS Nodes Configuration (GPT tested) | 36vCPU, 102 GB <br />(across 9 nodes for PostgreSQL, PgBouncer, Consul) | **db.r6g.2xlarge** x 3 nodes <br />(24vCPU, 192 GB) | 3 nodes x $1.04 = $3.12/hr | 3 nodes x $1.04 = $3.12/hr<br />(Aurora is always 3) |
+| **Redis** | 30vCPU, 114GB<br />(across 12 nodes for Redis Cache, Redis Queues/Shared State, Sentinel Cache, Sentinel Queues/Shared State) | **cache.m5.2xlarge** x 3 nodes<br />(24vCPU, 78GB) | 3 nodes x $0.62 = $1.86/hr | 2 nodes x $0.62 = $1.24/hr |
+| **<u>Gitaly Cluster</u>** [Details](gitlab_sre_for_aws.md#gitaly-sre-considerations) | | | | |
+| Gitaly Instances (in ASG) | 48 vCPU, 180GB<br />([across 3 nodes](gitlab_sre_for_aws.md#gitaly-and-praefect-elections)) | **m5.4xlarge** x 3 nodes<br />(48 vCPU, 180 GB) | $0.77 x 3 = $2.31/hr | [Gitaly & Praefect Must Have an Uneven Node Count for HA](gitlab_sre_for_aws.md#gitaly-and-praefect-elections) |
+| Praefect (Instances in ASG with load balancer) | 6 vCPU, 5.4 GB<br />([across 3 nodes](gitlab_sre_for_aws.md#gitaly-and-praefect-elections)) | **c5.large** x 3 nodes<br />(6 vCPU, 12 GB) | $0.09 x 3 = $0.21/hr | [Gitaly & Praefect Must Have an Uneven Node Count for HA](gitlab_sre_for_aws.md#gitaly-and-praefect-elections) |
+| Praefect PostgreSQL(1) (AWS RDS) | 6 vCPU, 5.4 GB<br />([across 3 nodes](gitlab_sre_for_aws.md#gitaly-and-praefect-elections)) | N/A Reuses GitLab PostgreSQL | $0 | |
+| Internal Load Balancing Node | 2 vCPU, 1.8 GB | AWS ELB | $0.10/hr | $0.10/hr |
+
+### 50K Cloud Native Hybrid on EKS
+
+**50K Cloud Native Hybrid on EKS Bill of Materials (BOM)**
+
+**GPT Test Results**
+
+- [50K Full Scale GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/50K/50k-Fixed-Scale-Test_v13-12-3-ee_2021-08-13_172819/50k-Fixed-Scale-Test_v13-12-3-ee_2021-08-13_172819_results.txt)
+- [50K AutoScale GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/50K/50k-AutoScale-Test_v13-12-3-ee_2021-08-13_192633/50k-AutoScale-Test_v13-12-3-ee_2021-08-13_192633.txt)
+
+**Deploy Now**
+
+Deploy Now links leverage the AWS Quick Start automation and only prepopulate the number of instances and instance types for the Quick Start based on the Bill of Meterials below. You must provide appropriate input for all other parameters by following the guidance in the [Quick Start documentation's Deployment steps](https://aws-quickstart.github.io/quickstart-eks-gitlab/#_deployment_steps) section.
+
+- **[Deploy Now: AWS Quick Start for 3 AZs - 1/4 Scale EKS](https://us-east-2.console.aws.amazon.com/cloudformation/home?region=us-east-2#/stacks/quickcreate?templateUrl=https://aws-quickstart.s3.us-east-1.amazonaws.com/quickstart-eks-gitlab/templates/gitlab-entry-new-vpc.template.yaml&stackName=Gitlab-EKS-50K-Users-3AZs&param_NumberOfAZs=3&param_NodeInstanceType=c5.4xlarge&param_NumberOfNodes=7&param_MaxNumberOfNodes=9&param_DBInstanceClass=db.r6g.8xlarge&param_CacheNodes=3&param_CacheNodeType=cache.m6g.2xlarge&param_GitalyInstanceType=m5.16xlarge&param_NumberOfGitalyReplicas=3&param_PraefectInstanceType=c5.xlarge&param_NumberOfPraefectReplicas=3)**
+
+NOTE:
+On Demand pricing is used in this table for comparisons, but should not be used for budgeting nor purchasing AWS resources for a GitLab production instance. Do not use these tables to calculate actual monthly or yearly price estimates, instead use the AWS Calculator links in the "GitLab on AWS Compute" table above and customize it with your desired savings plan.
+
+**BOM Total:** = Bill of Materials Total - this is what you use when building this configuration
+
+**Ref Arch Raw Total:** = The totals if the configuration was built on regular VMs with no PaaS services. Configuring on pure VMs generally requires additional VMs for cluster management activities.
+
+ **Idle Configuration (Scaled-In)** = can be used to scale-in during time of low demand and/or for warm standby Geo instances. Requires configuration, testing and management of EKS autoscaling to meet your internal requirements.
+
+| Service | Ref Arch Raw (Full Scaled) | AWS BOM<br />(Directly Usable in AWS Quick Start) | Example Full Scaled Cost<br />(On Demand, US East) |
+| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | -------------------------------------------------- |
+| Webservice | [80 pods](https://gitlab.com/gitlab-org/charts/gitlab/-/blob/master/examples/ref/10k.yaml#L7) x ([5 vCPU & 6.25 GB](../../administration/reference_architectures/10k_users.md#webservice)) = <br />400 vCPU, 500 GB | | |
+| Sidekiq | [14 pods](https://gitlab.com/gitlab-org/charts/gitlab/-/blob/master/examples/ref/10k.yaml#L24) x ([1 vCPU & 2 GB](../../administration/reference_architectures/10k_users.md#sidekiq))<br />14 vCPU, 28 GB | | |
+| Supporting services such as NGINX, Prometheus, etc | [2 allocations](../../administration/reference_architectures/10k_users.md#cluster-topology) x ([2 vCPU and 7.5 GB](../../administration/reference_architectures/10k_users.md#cluster-topology))<br />4 vCPU, 15 GB | | |
+| **GitLab Ref Arch Raw Total K8s Node Capacity** | 428 vCPU, 533 GB | | |
+| One Node for Overhead and Miscellaneous (EKS Cluster AutoScaler, Grafana, Prometheus, etc) | + 16 vCPU, 32GB | | |
+| **Grand Total w/ Overheads Fully Scaled**<br />Minimum hosts = 3 | 444 vCPU, 565 GB | **c5.4xlarge** (16vcpu/32GB) x 28 nodes<br />448 vCPU, 896GB<br /><br />[Full Scale GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/50K/50k-Fixed-Scale-Test_v13-12-3-ee_2021-08-13_172819/50k-Fixed-Scale-Test_v13-12-3-ee_2021-08-13_172819_results.txt) | $19.04/hr |
+| **Possible Idle Configuration (Scaled-In 75% - round up)**<br />Pod autoscaling must be also adjusted to enable lower idling configuration. | 40 vCPU, 80 GB | c5.2xlarge x 10<br /><br />[AutoScale GPT Test Results](https://gitlab.com/gitlab-com/alliances/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/50K/50k-AutoScale-Test_v13-12-3-ee_2021-08-13_192633/50k-AutoScale-Test_v13-12-3-ee_2021-08-13_192633.txt) | $6.80/hr |
+
+Other combinations of node type and quantity can be used to meet the Grand Total. Due to the cpu and memory requirements of pods, hosts that are overly small may have significant unused capacity.
+
+NOTE:
+If EKS node autoscaling is employed, it is likely that your average loading will run lower than this, especially during non-working hours and weekends.
+
+| Non-Kubernetes Compute | Ref Arch Raw Total | AWS BOM | Example Cost<br />US East, 3 AZ | Example Cost<br />US East, 2 AZ |
+| ------------------------------------------------------------ | ------------------------------------------------------------ | --------------------------------------------------------- | ------------------------------- | ------------------------------------------------------------ |
+| **Bastion Host (Quick Start)** | 1 HA instance in ASG | **t2.micro** for prod, **m4.2xlarge** for perf. testing | | |
+| **PostgreSQL**<br />AWS Aurora RDS Nodes Configuration (GPT tested) | 96vCPU, 360 GB <br />(across 3 nodes) | **db.r6g.8xlarge** x 3 nodes <br />(96vCPU, 768 GB total) | 3 nodes x $4.15 = $12.45/hr | 3 nodes x $4.15 = $12.45/hr<br />(Aurora is always 3) |
+| **Redis** | 30vCPU, 114GB<br />(across 12 nodes for Redis Cache, Redis Queues/Shared State, Sentinel Cache, Sentinel Queues/Shared State) | **cache.m6g.2xlarge** x 3 nodes<br />(24vCPU, 78GB total) | 3 nodes x $0.60 = $1.80/hr | 2 nodes x $0.60 = $1.20/hr |
+| **<u>Gitaly Cluster</u>** [Details](gitlab_sre_for_aws.md#gitaly-sre-considerations) | | | | |
+| Gitaly Instances (in ASG) | 64 vCPU, 240GB x [3 nodes](gitlab_sre_for_aws.md#gitaly-and-praefect-elections) | **m5.16xlarge** x 3 nodes<br />(64 vCPU, 256 GB each) | $3.07 x 3 = $9.21/hr | [Gitaly & Praefect Must Have an Uneven Node Count for HA](gitlab_sre_for_aws.md#gitaly-and-praefect-elections) |
+| Praefect (Instances in ASG with load balancer) | 4 vCPU, 3.6 GB x [3 nodes](gitlab_sre_for_aws.md#gitaly-and-praefect-elections) | **c5.xlarge** x 3 nodes<br />(4 vCPU, 8 GB each) | $0.17 x 3 = $0.51/hr | [Gitaly & Praefect Must Have an Uneven Node Count for HA](gitlab_sre_for_aws.md#gitaly-and-praefect-elections) |
+| Praefect PostgreSQL(1) (AWS RDS) | 2 vCPU, 1.8 GB x [3 nodes](gitlab_sre_for_aws.md#gitaly-and-praefect-elections) | N/A Reuses GitLab PostgreSQL | $0 | |
+| Internal Load Balancing Node | 2 vCPU, 1.8 GB | AWS ELB | $0.10/hr | $0.10/hr |
+
+## Helpful Resources
+
+- [Architecting Kubernetes clusters — choosing a worker node size](https://learnk8s.io/kubernetes-node-size)
diff --git a/doc/install/aws/gitlab_sre_for_aws.md b/doc/install/aws/gitlab_sre_for_aws.md
new file mode 100644
index 00000000000..a2d3a2d0295
--- /dev/null
+++ b/doc/install/aws/gitlab_sre_for_aws.md
@@ -0,0 +1,59 @@
+---
+stage: Enablement
+group: Alliances
+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
+comments: false
+description: Doing SRE for GitLab instances and runners on AWS.
+type: index
+---
+
+# GitLab Site Reliability Engineering for AWS **(FREE SELF)**
+
+## Known issues list
+
+Known issues are gathered from within GitLab and from customer reported issues. Customers successfully implement GitLab with a variety of "as a Service" components that GitLab has not specifically been designed for, nor has ongoing testing for. While GitLab does take partner technologies very seriously, the highlighting of known issues here is a convenience for implementers and it does not imply that GitLab has targeted compatibility with, nor carries any type of guarantee of running on the partner technology where the issues occur. Please consult individual issues to understand GitLabs stance and plans on any given known issue.
+
+See the [GitLab AWS known issues list](https://gitlab.com/gitlab-com/alliances/aws/public-tracker/-/issues?label_name%5B%5D=AWS+Known+Issue) for a complete list.
+
+## Gitaly SRE considerations
+
+Gitaly and Gitaly Cluster have been engineered by GitLab to overcome fundamental challenges with horizontal scaling of the open source Git binaries. Here is indepth technical reading on the topic:
+
+### Why Gitaly was built
+
+Below are some links to better understand why Gitaly was built:
+
+- [Git characteristics that make horizontal scaling difficult](https://gitlab.com/gitlab-org/gitaly/-/blob/master/doc/DESIGN.md#git-characteristics-that-make-horizontal-scaling-difficult)
+- [Git architectural characteristics and assumptions](https://gitlab.com/gitlab-org/gitaly/-/blob/master/doc/DESIGN.md#git-architectural-characteristics-and-assumptions)
+- [Affects on horizontal compute architecture](https://gitlab.com/gitlab-org/gitaly/-/blob/master/doc/DESIGN.md#affects-on-horizontal-compute-architecture)
+- [Evidence to back building a new horizontal layer to scale Git](https://gitlab.com/gitlab-org/gitaly/-/blob/master/doc/DESIGN.md#evidence-to-back-building-a-new-horizontal-layer-to-scale-git)
+
+### Gitaly and Praefect elections
+
+As part of Gitaly cluster consistency, Praefect nodes will occasionally need to vote on what data copy is the most accurate. This requires an uneven number of Praefect nodes to avoid stalemates. This means that for HA, Gitaly and Praefect require a minimum of three nodes.
+
+### Gitaly performance monitoring
+
+Complete performance metrics should be collected for Gitaly instances for identification of bottlenecks, as they could have to do with disk IO, network IO or memory.
+
+Gitaly must be implemented on instance compute.
+
+### Gitaly EBS volume sizing guidelines
+
+Gitaly storage is expected to be local (not NFS of any type including EFS).
+Gitaly servers also need disk space for building and caching Git pack files.
+
+Background:
+
+- When not using provisioned EBS IO, EBS volume size determines the IO level, so provisioning volumes that are much larger than needed can be the least expensive way to improve EBS IO.
+- Only use nitro instance types due to higher IO and EBS optimization.
+- Use Amazon Linux 2 to ensure the best disk and memory optimizations (for example, ENA network adapters and drivers).
+- If GitLab backup scripts are used, they need a temporary space location large enough to hold 2 times the current size of the Git File system. If that will be done on Gitaly servers, separate volumes should be used.
+
+### Gitaly HA in EKS quick start
+
+The [AWS GitLab Cloud Native Hybrid on EKS Quick Start](gitlab_hybrid_on_aws.md#available-infrastructure-as-code-for-gitlab-cloud-native-hybrid) for GitLab Cloud Native implements Gitaly as a multi-zone, self-healing infrastructure. It has specific code for reestablishing a Gitaly node when one fails, including AZ failure.
+
+### Gitaly long term management
+
+Gitaly node disk sizes will need to be monitored and increased to accommodate Git repository growth and Gitaly temporary and caching storage needs. The storage configuration on all nodes should be kept identical.
diff --git a/doc/install/aws/index.md b/doc/install/aws/index.md
index ca024f685f1..342b6962628 100644
--- a/doc/install/aws/index.md
+++ b/doc/install/aws/index.md
@@ -1,846 +1,110 @@
---
stage: Enablement
-group: Distribution
+group: Alliances
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
-type: howto
+comments: false
+description: Read through the GitLab installation methods.
+type: index
---
-# Installing GitLab on Amazon Web Services (AWS) **(FREE SELF)**
-
-This page offers a walkthrough of a common configuration
-for GitLab on AWS using the official GitLab Linux package. You should customize it to accommodate your needs.
-
-NOTE:
-For organizations with 1,000 users or less, the recommended AWS installation method is to launch an EC2 single box [Omnibus Installation](https://about.gitlab.com/install/) and implement a snapshot strategy for backing up the data. See the [1,000 user reference architecture](../../administration/reference_architectures/1k_users.md) for more.
+# AWS implementation patterns **(FREE SELF)**
-## Introduction
+GitLab [Reference Architectures](../../administration/reference_architectures/index.md) give qualified and tested guidance on the recommended ways GitLab can be configured to meet the performance requirements of various workloads. Reference Architectures are purpose-designed to be non-implementation specific so they can be extrapolated to as many environments as possible. This generally means they have a highly-granular "machine" to "server role" specification and focus on system elements that impact performance. This is what enables Reference Architectures to be adaptable to the broadest number of supported implementations.
-For the most part, we'll make use of Omnibus GitLab in our setup, but we'll also leverage native AWS services. Instead of using the Omnibus bundled PostgreSQL and Redis, we will use AWS RDS and ElastiCache.
-
-In this guide, we'll go through a multi-node setup where we'll start by
-configuring our Virtual Private Cloud and subnets to later integrate
-services such as RDS for our database server and ElastiCache as a Redis
-cluster to finally manage them within an auto scaling group with custom
-scaling policies.
+Implementation patterns are built on the foundational information and testing done for Reference Architectures and allow architects and implementers at GitLab, GitLab Customers, and GitLab Partners to build out deployments with less experimentation and a higher degree of confidence that the results will perform as expected.
-## Requirements
+## Implementation patterns information
-In addition to having a basic familiarity with [AWS](https://docs.aws.amazon.com/) and [Amazon EC2](https://docs.aws.amazon.com/ec2/), you will need:
+### Install GitLab Cloud Native Hybrid on AWS EKS (HA)
-- [An AWS account](https://console.aws.amazon.com/console/home)
-- [To create or upload an SSH key](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html)
- to connect to the instance via SSH
-- A domain name for the GitLab instance
-- An SSL/TLS certificate to secure your domain. If you do not already own one, you can provision a free public SSL/TLS certificate through [AWS Certificate Manager](https://aws.amazon.com/certificate-manager/)(ACM) for use with the [Elastic Load Balancer](#load-balancer) we'll create.
+[Provision GitLab Cloud Native Hybrid on AWS EKS (HA)](gitlab_hybrid_on_aws.md). This document includes instructions, patterns, and automation for installing GitLab Cloud Native Hybrid on AWS EKS. It also includes [Bill of Materials](https://en.wikipedia.org/wiki/Bill_of_materials) listings and links to Infrastructure as Code. GitLab Cloud Native Hybrid is the supported way to put as much of GitLab as possible into Kubernetes.
-NOTE:
-It can take a few hours to validate a certificate provisioned through ACM. To avoid delays later, request your certificate as soon as possible.
+### Install Omnibus GitLab on AWS EC2 (HA)
-## Architecture
+[Omnibus GitLab on AWS EC2 (HA)](manual_install_aws.md) - instructions for installing GitLab on EC2 instances. Manual instructions from which you may build out a GitLab instance or create your own Infrastructure as Code (IaC).
-Below is a diagram of the recommended architecture.
+### GitLab Site Reliability Engineering (SRE) for AWS
-![AWS architecture diagram](img/aws_ha_architecture_diagram.png)
+[GitLab SRE Considerations for AWS](gitlab_sre_for_aws.md) - important information and known issues for planning, implementing, upgrading and long term management of GitLab instances and runners on AWS.
-## AWS costs
+### EKS cluster provisioning best practices
-GitLab uses the following AWS services, with links to pricing information:
+[EKS Cluster Provisioning Patterns](eks_clusters_aws.md) - considerations for setting up EKS cluster for runners and for integrating.
-- **EC2**: GitLab is deployed on shared hardware, for which
- [on-demand pricing](https://aws.amazon.com/ec2/pricing/on-demand/) applies.
- If you want to run GitLab on a dedicated or reserved instance, see the
- [EC2 pricing page](https://aws.amazon.com/ec2/pricing/) for information about
- its cost.
-- **S3**: GitLab uses S3 ([pricing page](https://aws.amazon.com/s3/pricing/)) to
- store backups, artifacts, and LFS objects.
-- **ELB**: A Classic Load Balancer ([pricing page](https://aws.amazon.com/elasticloadbalancing/pricing/)),
- used to route requests to the GitLab instances.
-- **RDS**: An Amazon Relational Database Service using PostgreSQL
- ([pricing page](https://aws.amazon.com/rds/postgresql/pricing/)).
-- **ElastiCache**: An in-memory cache environment ([pricing page](https://aws.amazon.com/elasticache/pricing/)),
- used to provide a Redis configuration.
+### Scaling HA GitLab Runner on AWS EC2 ASG
-## Create an IAM EC2 instance role and profile
+The following repository is self-contained in regard to enabling this pattern: [GitLab HA Scaling Runner Vending Machine for AWS EC2 ASG](https://gitlab.com/guided-explorations/aws/gitlab-runner-autoscaling-aws-asg/). The [feature list for this implementation pattern](https://gitlab.com/guided-explorations/aws/gitlab-runner-autoscaling-aws-asg/-/blob/main/FEATURES.md) is good to review to understand the complete value it can deliver.
-As we'll be using [Amazon S3 object storage](#amazon-s3-object-storage), our EC2 instances need to have read, write, and list permissions for our S3 buckets. To avoid embedding AWS keys in our GitLab configuration, we'll make use of an [IAM Role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) to allow our GitLab instance with this access. We'll need to create an IAM policy to attach to our IAM role:
+## Additional details on implementation patterns
-### Create an IAM Policy
+GitLab implementation patterns build upon [GitLab Reference Architectures](../../administration/reference_architectures/index.md) in the following ways.
-1. Navigate to the IAM dashboard and click on **Policies** in the left menu.
-1. Click **Create policy**, select the `JSON` tab, and add a policy. We want to [follow security best practices and grant _least privilege_](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege), giving our role only the permissions needed to perform the required actions.
- 1. Assuming you prefix the S3 bucket names with `gl-` as shown in the diagram, add the following policy:
+### Cloud platform well architected compliance
- ```json
- { "Version": "2012-10-17",
- "Statement": [
- {
- "Effect": "Allow",
- "Action": [
- "s3:PutObject",
- "s3:GetObject",
- "s3:DeleteObject",
- "s3:PutObjectAcl"
- ],
- "Resource": "arn:aws:s3:::gl-*/*"
- },
- {
- "Effect": "Allow",
- "Action": [
- "s3:ListBucket",
- "s3:AbortMultipartUpload",
- "s3:ListMultipartUploadParts",
- "s3:ListBucketMultipartUploads"
- ],
- "Resource": "arn:aws:s3:::gl-*"
- }
- ]
- }
- ```
+Testing-backed architectural qualification is a fundamental concept behind implementation patterns:
-1. Click **Review policy**, give your policy a name (we'll use `gl-s3-policy`), and click **Create policy**.
+- Implementation patterns maintain GitLab Reference Architecture compliance and provide [GitLab Performance Tool](https://gitlab.com/gitlab-org/quality/performance) (gpt) reports to demonstrate adherence to them.
+- Implementation patterns may be qualified by and/or contributed to by the technology vendor. For instance, an implementation pattern for AWS may be officially reviewed by AWS.
+- Implementation patterns may specify and test Cloud Platform PaaS services for suitability for GitLab. This testing can be coordinated and help qualify these technologies for Reference Architectures. For instance, qualifying compatibility with and availability of runtime versions of top level PaaS such as those for PostgreSQL and Redis.
+- Implementation patterns can provided qualified testing for platform limitations, for example, ensuring Gitaly Cluster can work correctly on specific Cloud Platform availability zone latency and throughput characteristics or qualifying what levels of available platform partner local disk performance is workable for Gitaly server to operate with integrity.
-### Create an IAM Role
+### Platform partner specificity
-1. Still on the IAM dashboard, click on **Roles** in the left menu, and
- click **Create role**.
-1. Create a new role by selecting **AWS service > EC2**, then click
- **Next: Permissions**.
-1. In the policy filter, search for the `gl-s3-policy` we created above, select it, and click **Tags**.
-1. Add tags if needed and click **Review**.
-1. Give the role a name (we'll use `GitLabS3Access`) and click **Create Role**.
+Implementation patterns enable platform-specific terminology, best practice architecture, and platform-specific build manifests:
-We'll use this role when we [create a launch configuration](#create-a-launch-configuration) later on.
+- Implementation patterns are more vendor specific. For instance, advising specific compute instances / VMs / nodes instead of vCPUs or other generalized measures.
+- Implementation patterns are oriented to implementing good architecture for the vendor in view.
+- Implementation patterns are written to an audience who is familiar with building on the infrastructure that the implementation pattern targets. For example, if the implementation pattern is for GCP, the specific terminology of GCP is used - including using the specific names for PaaS services.
+- Implementation patterns can test and qualify if the versions of PaaS available are compatible with GitLab (for example, PostgreSQL, Redis, etc.).
-## Configuring the network
+### Platform as a Service (PaaS) specification and usage
-We'll start by creating a VPC for our GitLab cloud infrastructure, then
-we can create subnets to have public and private instances in at least
-two [Availability Zones (AZs)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html). Public subnets will require a Route Table keep and an associated
-Internet Gateway.
+Platform as a Service options are a huge portion of the value provided by Cloud Platforms as they simplify operational complexity and reduce the SRE and security skilling required to operate advanced, highly available technology services. Implementation patterns can be prequalified against the partner PaaS options.
-### Creating the Virtual Private Cloud (VPC)
+- Implementation patterns help implementers understand what PaaS options are known to work and how to choose between PaaS solutions when a single platform has more than one PaaS option for the same GitLab role (for example, AWS RDS versus AWS Aurora RDS).
+- For instance, where reference architectures do not have a specific recommendation on what technology is leveraged for GitLab outbound email services or what the sizing should be - a Reference Implementation may advise using a cloud providers Email as a Service (PaaS) and possibly even with specific settings.
-We'll now create a VPC, a virtual networking environment that you'll control:
+### Cost optimizing engineering
-1. Sign in to [Amazon Web Services](https://console.aws.amazon.com/vpc/home).
-1. Select **Your VPCs** from the left menu and then click **Create VPC**.
- At the "Name tag" enter `gitlab-vpc` and at the "IPv4 CIDR block" enter
- `10.0.0.0/16`. If you don't require dedicated hardware, you can leave
- "Tenancy" as default. Click **Yes, Create** when ready.
+Cost engineering is a fundamental aspect of Cloud Architecture and frequently the savings capabilities available on a platform exert strong influence on how to build out scaled computing.
- ![Create VPC](img/create_vpc.png)
+- Implementation patterns may define GPT tested autoscaling for various aspects of GitLab infrastructure, including minimum idling configurations and scaling speeds.
+- Implementation patterns may provide GPT testing for advised configurations that go beyond the scope of reference architectures, for instance GPT tested elastic scaling configurations for Cloud Native Hybrid that enable lower resourcing during periods of lower usage (for example on the weekend).
+- Implementation patterns may engineer specifically for the savings models available on a platform provider. An AWS example would be maximizing the occurrence of a specific instance type for taking advantage of reserved instances.
+- Implementation patterns may leverage ephemeral compute where appropriate and with appropriate customer guidelines. For instance, a Kubernetes node group dedicated to runners on ephemeral compute (with appropriate GitLab Runner tagging to indicate the compute type).
+- Implementation patterns may include vendor specific cost calculators.
-1. Select the VPC, click **Actions**, click **Edit DNS resolution**, and enable DNS resolution. Hit **Save** when done.
+### Actionability and automatability orientation
-### Subnets
+Implementation patterns are one step closer to specifics that can be used as a source for build instructions and automation code:
-Now, let's create some subnets in different Availability Zones. Make sure
-that each subnet is associated to the VPC we just created and
-that CIDR blocks don't overlap. This will also
-allow us to enable multi AZ for redundancy.
+- Implementation patterns enable builders to generate a list of vendor specific resources required to implement GitLab for a given Reference Architecture.
+- Implementation patterns enable builders to use manual instructions or to create automation to build out the reference implementation.
-We will create private and public subnets to match load balancers and
-RDS instances as well:
+## Supplementary implementation patterns
-1. Select **Subnets** from the left menu.
-1. Click **Create subnet**. Give it a descriptive name tag based on the IP,
- for example `gitlab-public-10.0.0.0`, select the VPC we created previously, select an availability zone (we'll use `us-west-2a`),
- and at the IPv4 CIDR block let's give it a 24 subnet `10.0.0.0/24`:
-
- ![Create subnet](img/create_subnet.png)
-
-1. Follow the same steps to create all subnets:
-
- | Name tag | Type | Availability Zone | CIDR block |
- | ------------------------- | ------- | ----------------- | ------------- |
- | `gitlab-public-10.0.0.0` | public | `us-west-2a` | `10.0.0.0/24` |
- | `gitlab-private-10.0.1.0` | private | `us-west-2a` | `10.0.1.0/24` |
- | `gitlab-public-10.0.2.0` | public | `us-west-2b` | `10.0.2.0/24` |
- | `gitlab-private-10.0.3.0` | private | `us-west-2b` | `10.0.3.0/24` |
+Implementation patterns may also provide specialized implementations beyond the scope of reference architecture compliance, especially where the cost of enablement can be more appropriately managed.
-1. Once all the subnets are created, enable **Auto-assign IPv4** for the two public subnets:
- 1. Select each public subnet in turn, click **Actions**, and click **Modify auto-assign IP settings**. Enable the option and save.
-
-### Internet Gateway
-
-Now, still on the same dashboard, go to Internet Gateways and
-create a new one:
+For example:
-1. Select **Internet Gateways** from the left menu.
-1. Click **Create internet gateway**, give it the name `gitlab-gateway` and
- click **Create**.
-1. Select it from the table, and then under the **Actions** dropdown choose
- "Attach to VPC".
-
- ![Create gateway](img/create_gateway.png)
-
-1. Choose `gitlab-vpc` from the list and hit **Attach**.
-
-### Create NAT Gateways
-
-Instances deployed in our private subnets need to connect to the internet for updates, but should not be reachable from the public internet. To achieve this, we'll make use of [NAT Gateways](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html) deployed in each of our public subnets:
-
-1. Navigate to the VPC dashboard and click on **NAT Gateways** in the left menu bar.
-1. Click **Create NAT Gateway** and complete the following:
- 1. **Subnet**: Select `gitlab-public-10.0.0.0` from the dropdown.
- 1. **Elastic IP Allocation ID**: Enter an existing Elastic IP or click **Allocate Elastic IP address** to allocate a new IP to your NAT gateway.
- 1. Add tags if needed.
- 1. Click **Create NAT Gateway**.
+- Small, self-contained GitLab instances for per-person admin training, perhaps on Kubernetes so that a deployment cluster is self-contained as well.
+- GitLab Runner implementation patterns, including using platform-specific PaaS.
-Create a second NAT gateway but this time place it in the second public subnet, `gitlab-public-10.0.2.0`.
+## Intended audiences and contributors
-### Route Tables
+The primary audiences for and contributors to this information is the GitLab **Implementation Eco System** which consists of at least:
-#### Public Route Table
+GitLab Implementation Community:
-We need to create a route table for our public subnets to reach the internet via the internet gateway we created in the previous step.
+- Customers
+- GitLab Channel Partners (Integrators)
+- Platform Partners
-On the VPC dashboard:
+GitLab Internal Implementation Teams:
-1. Select **Route Tables** from the left menu.
-1. Click **Create Route Table**.
-1. At the "Name tag" enter `gitlab-public` and choose `gitlab-vpc` under "VPC".
-1. Click **Create**.
-
-We now need to add our internet gateway as a new target and have
-it receive traffic from any destination.
-
-1. Select **Route Tables** from the left menu and select the `gitlab-public`
- route to show the options at the bottom.
-1. Select the **Routes** tab, click **Edit routes > Add route** and set `0.0.0.0/0`
- as the destination. In the target column, select the `gitlab-gateway` we created previously.
- Hit **Save routes** once done.
-
-Next, we must associate the **public** subnets to the route table:
-
-1. Select the **Subnet Associations** tab and click **Edit subnet associations**.
-1. Check only the public subnets and click **Save**.
-
-#### Private Route Tables
-
-We also need to create two private route tables so that instances in each private subnet can reach the internet via the NAT gateway in the corresponding public subnet in the same availability zone.
-
-1. Follow the same steps as above to create two private route tables. Name them `gitlab-private-a` and `gitlab-private-b` respectively.
-1. Next, add a new route to each of the private route tables where the destination is `0.0.0.0/0` and the target is one of the NAT gateways we created earlier.
- 1. Add the NAT gateway we created in `gitlab-public-10.0.0.0` as the target for the new route in the `gitlab-private-a` route table.
- 1. Similarly, add the NAT gateway in `gitlab-public-10.0.2.0` as the target for the new route in the `gitlab-private-b`.
-1. Lastly, associate each private subnet with a private route table.
- 1. Associate `gitlab-private-10.0.1.0` with `gitlab-private-a`.
- 1. Associate `gitlab-private-10.0.3.0` with `gitlab-private-b`.
-
-## Load Balancer
-
-We'll create a load balancer to evenly distribute inbound traffic on ports `80` and `443` across our GitLab application servers. Based the on the [scaling policies](#create-an-auto-scaling-group) we'll create later, instances will be added to or removed from our load balancer as needed. Additionally, the load balance will perform health checks on our instances.
-
-On the EC2 dashboard, look for Load Balancer in the left navigation bar:
-
-1. Click the **Create Load Balancer** button.
- 1. Choose the **Classic Load Balancer**.
- 1. Give it a name (we'll use `gitlab-loadbalancer`) and for the **Create LB Inside** option, select `gitlab-vpc` from the dropdown menu.
- 1. In the **Listeners** section, set the following listeners:
- - HTTP port 80 for both load balancer and instance protocol and ports
- - TCP port 22 for both load balancer and instance protocols and ports
- - HTTPS port 443 for load balancer protocol and ports, forwarding to HTTP port 80 on the instance (we will configure GitLab to listen on port 80 [later in the guide](#add-support-for-proxied-ssl))
- 1. In the **Select Subnets** section, select both public subnets from the list so that the load balancer can route traffic to both availability zones.
-1. We'll add a security group for our load balancer to act as a firewall to control what traffic is allowed through. Click **Assign Security Groups** and select **Create a new security group**, give it a name
- (we'll use `gitlab-loadbalancer-sec-group`) and description, and allow both HTTP and HTTPS traffic
- from anywhere (`0.0.0.0/0, ::/0`). Also allow SSH traffic, select a custom source, and add a single trusted IP address or an IP address range in CIDR notation. This will allow users to perform Git actions over SSH.
-1. Click **Configure Security Settings** and set the following:
- 1. Select an SSL/TLS certificate from ACM or upload a certificate to IAM.
- 1. Under **Select a Cipher**, pick a predefined security policy from the dropdown. You can see a breakdown of [Predefined SSL Security Policies for Classic Load Balancers](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-security-policy-table.html) in the AWS docs. Check the GitLab codebase for a list of [supported SSL ciphers and protocols](https://gitlab.com/gitlab-org/gitlab/-/blob/9ee7ad433269b37251e0dd5b5e00a0f00d8126b4/lib/support/nginx/gitlab-ssl#L97-99).
-1. Click **Configure Health Check** and set up a health check for your EC2 instances.
- 1. For **Ping Protocol**, select HTTP.
- 1. For **Ping Port**, enter 80.
- 1. For **Ping Path**, enter `/users/sign_in`. (We use `/users/sign_in` as it's a public endpoint that does
- not require authentication.)
- 1. Keep the default **Advanced Details** or adjust them according to your needs.
-1. Click **Add EC2 Instances** - don't add anything as we will create an Auto Scaling Group later to manage instances for us.
-1. Click **Add Tags** and add any tags you need.
-1. Click **Review and Create**, review all your settings, and click **Create** if you're happy.
-
-After the Load Balancer is up and running, you can revisit your Security
-Groups to refine the access only through the ELB and any other requirements
-you might have.
-
-### Configure DNS for Load Balancer
-
-On the Route 53 dashboard, click **Hosted zones** in the left navigation bar:
-
-1. Select an existing hosted zone or, if you do not already have one for your domain, click **Create Hosted Zone**, enter your domain name, and click **Create**.
-1. Click **Create Record Set** and provide the following values:
- 1. **Name:** Use the domain name (the default value) or enter a subdomain.
- 1. **Type:** Select **A - IPv4 address**.
- 1. **Alias:** Defaults to **No**. Select **Yes**.
- 1. **Alias Target:** Find the **ELB Classic Load Balancers** section and select the classic load balancer we created earlier.
- 1. **Routing Policy:** We'll use **Simple** but you can choose a different policy based on your use case.
- 1. **Evaluate Target Health:** We'll set this to **No** but you can choose to have the load balancer route traffic based on target health.
- 1. Click **Create**.
-1. If you registered your domain through Route 53, you're done. If you used a different domain registrar, you need to update your DNS records with your domain registrar. You'll need to:
- 1. Click on **Hosted zones** and select the domain you added above.
- 1. You'll see a list of `NS` records. From your domain registrar's administrator panel, add each of these as `NS` records to your domain's DNS records. These steps may vary between domain registrars. If you're stuck, Google **"name of your registrar" add DNS records** and you should find a help article specific to your domain registrar.
-
-The steps for doing this vary depending on which registrar you use and is beyond the scope of this guide.
-
-## PostgreSQL with RDS
-
-For our database server we will use Amazon RDS which offers Multi AZ
-for redundancy. First we'll create a security group and subnet group, then we'll
-create the actual RDS instance.
-
-### RDS Security Group
-
-We need a security group for our database that will allow inbound traffic from the instances we'll deploy in our `gitlab-loadbalancer-sec-group` later on:
-
-1. From the EC2 dashboard, select **Security Groups** from the left menu bar.
-1. Click **Create security group**.
-1. Give it a name (we'll use `gitlab-rds-sec-group`), a description, and select the `gitlab-vpc` from the **VPC** dropdown.
-1. In the **Inbound rules** section, click **Add rule** and set the following:
- 1. **Type:** search for and select the **PostgreSQL** rule.
- 1. **Source type:** set as "Custom".
- 1. **Source:** select the `gitlab-loadbalancer-sec-group` we created earlier.
-1. When done, click **Create security group**.
-
-### RDS Subnet Group
-
-1. Navigate to the RDS dashboard and select **Subnet Groups** from the left menu.
-1. Click on **Create DB Subnet Group**.
-1. Under **Subnet group details**, enter a name (we'll use `gitlab-rds-group`), a description, and choose the `gitlab-vpc` from the VPC dropdown.
-1. From the **Availability Zones** dropdown, select the Availability Zones that include the subnets you've configured. In our case, we'll add `eu-west-2a` and `eu-west-2b`.
-1. From the **Subnets** dropdown, select the two private subnets (`10.0.1.0/24` and `10.0.3.0/24`) as we defined them in the [subnets section](#subnets).
-1. Click **Create** when ready.
-
-### Create the database
-
-WARNING:
-Avoid using burstable instances (t class instances) for the database as this could lead to performance issues due to CPU credits running out during sustained periods of high load.
-
-Now, it's time to create the database:
-
-1. Navigate to the RDS dashboard, select **Databases** from the left menu, and click **Create database**.
-1. Select **Standard Create** for the database creation method.
-1. Select **PostgreSQL** as the database engine and select the minimum PostgreSQL version as defined for your GitLab version in our [database requirements](../../install/requirements.md#postgresql-requirements).
-1. Since this is a production server, let's choose **Production** from the **Templates** section.
-1. Under **Settings**, set a DB instance identifier, a master username, and a master password. We'll use `gitlab-db-ha`, `gitlab`, and a very secure password respectively. Make a note of these as we'll need them later.
-1. For the DB instance size, select **Standard classes** and select an instance size that meets your requirements from the dropdown menu. We'll use a `db.m4.large` instance.
-1. Under **Storage**, configure the following:
- 1. Select **Provisioned IOPS (SSD)** from the storage type dropdown menu. Provisioned IOPS (SSD) storage is best suited for this use (though you can choose General Purpose (SSD) to reduce the costs). Read more about it at [Storage for Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Storage.html).
- 1. Allocate storage and set provisioned IOPS. We'll use the minimum values, `100` and `1000`, respectively.
- 1. Enable storage autoscaling (optional) and set a maximum storage threshold.
-1. Under **Availability & durability**, select **Create a standby instance** to have a standby RDS instance provisioned in a different [Availability Zone](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.MultiAZ.html).
-1. Under **Connectivity**, configure the following:
- 1. Select the VPC we created earlier (`gitlab-vpc`) from the **Virtual Private Cloud (VPC)** dropdown menu.
- 1. Expand the **Additional connectivity configuration** section and select the subnet group (`gitlab-rds-group`) we created earlier.
- 1. Set public accessibility to **No**.
- 1. Under **VPC security group**, select **Choose existing** and select the `gitlab-rds-sec-group` we create above from the dropdown.
- 1. Leave the database port as the default `5432`.
-1. For **Database authentication**, select **Password authentication**.
-1. Expand the **Additional configuration** section and complete the following:
- 1. The initial database name. We'll use `gitlabhq_production`.
- 1. Configure your preferred backup settings.
- 1. The only other change we'll make here is to disable auto minor version updates under **Maintenance**.
- 1. Leave all the other settings as is or tweak according to your needs.
- 1. Once you're happy, click **Create database**.
-
-Now that the database is created, let's move on to setting up Redis with ElastiCache.
-
-## Redis with ElastiCache
-
-ElastiCache is an in-memory hosted caching solution. Redis maintains its own
-persistence and is used to store session data, temporary cache information, and background job queues for the GitLab application.
-
-### Create a Redis Security Group
-
-1. Navigate to the EC2 dashboard.
-1. Select **Security Groups** from the left menu.
-1. Click **Create security group** and fill in the details. Give it a name (we'll use `gitlab-redis-sec-group`),
- add a description, and choose the VPC we created previously
-1. In the **Inbound rules** section, click **Add rule** and add a **Custom TCP** rule, set port `6379`, and set the "Custom" source as the `gitlab-loadbalancer-sec-group` we created earlier.
-1. When done, click **Create security group**.
-
-### Redis Subnet Group
-
-1. Navigate to the ElastiCache dashboard from your AWS console.
-1. Go to **Subnet Groups** in the left menu, and create a new subnet group (we'll name ours `gitlab-redis-group`).
- Make sure to select our VPC and its [private subnets](#subnets). Click
- **Create** when ready.
-
- ![ElastiCache subnet](img/ec_subnet.png)
-
-### Create the Redis Cluster
-
-1. Navigate back to the ElastiCache dashboard.
-1. Select **Redis** on the left menu and click **Create** to create a new
- Redis cluster. Do not enable **Cluster Mode** as it is [not supported](../../administration/redis/replication_and_failover_external.md#requirements). Even without cluster mode on, you still get the
- chance to deploy Redis in multiple availability zones.
-1. In the settings section:
- 1. Give the cluster a name (`gitlab-redis`) and a description.
- 1. For the version, select the latest of `5.0` series (e.g., `5.0.6`).
- 1. Leave the port as `6379` since this is what we used in our Redis security group above.
- 1. Select the node type (at least `cache.t3.medium`, but adjust to your needs) and the number of replicas.
-1. In the advanced settings section:
- 1. Select the multi-AZ auto-failover option.
- 1. Select the subnet group we created previously.
- 1. Manually select the preferred availability zones, and under "Replica 2"
- choose a different zone than the other two.
-
- ![Redis availability zones](img/ec_az.png)
-
-1. In the security settings, edit the security groups and choose the
- `gitlab-redis-sec-group` we had previously created.
-1. Leave the rest of the settings to their default values or edit to your liking.
-1. When done, click **Create**.
-
-## Setting up Bastion Hosts
-
-Since our GitLab instances will be in private subnets, we need a way to connect to these instances via SSH to make configuration changes, perform upgrades, etc. One way of doing this is via a [bastion host](https://en.wikipedia.org/wiki/Bastion_host), sometimes also referred to as a jump box.
-
-NOTE:
-If you do not want to maintain bastion hosts, you can set up [AWS Systems Manager Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html) for access to instances. This is beyond the scope of this document.
-
-### Create Bastion Host A
-
-1. Navigate to the EC2 Dashboard and click on **Launch instance**.
-1. Select the **Ubuntu Server 18.04 LTS (HVM)** AMI.
-1. Choose an instance type. We'll use a `t2.micro` as we'll only use the bastion host to SSH into our other instances.
-1. Click **Configure Instance Details**.
- 1. Under **Network**, select the `gitlab-vpc` from the dropdown menu.
- 1. Under **Subnet**, select the public subnet we created earlier (`gitlab-public-10.0.0.0`).
- 1. Double check that under **Auto-assign Public IP** you have **Use subnet setting (Enable)** selected.
- 1. Leave everything else as default and click **Add Storage**.
-1. For storage, we'll leave everything as default and only add an 8GB root volume. We won't store anything on this instance.
-1. Click **Add Tags** and on the next screen click **Add Tag**.
- 1. We'll only set `Key: Name` and `Value: Bastion Host A`.
-1. Click **Configure Security Group**.
- 1. Select **Create a new security group**, enter a **Security group name** (we'll use `bastion-sec-group`), and add a description.
- 1. We'll enable SSH access from anywhere (`0.0.0.0/0`). If you want stricter security, specify a single IP address or an IP address range in CIDR notation.
- 1. Click **Review and Launch**
-1. Review all your settings and, if you're happy, click **Launch**.
-1. Acknowledge that you have access to an existing key pair or create a new one. Click **Launch Instance**.
-
-Confirm that you can SSH into the instance:
-
-1. On the EC2 Dashboard, click on **Instances** in the left menu.
-1. Select **Bastion Host A** from your list of instances.
-1. Click **Connect** and follow the connection instructions.
-1. If you are able to connect successfully, let's move on to setting up our second bastion host for redundancy.
-
-### Create Bastion Host B
-
-1. Create an EC2 instance following the same steps as above with the following changes:
- 1. For the **Subnet**, select the second public subnet we created earlier (`gitlab-public-10.0.2.0`).
- 1. Under the **Add Tags** section, we'll set `Key: Name` and `Value: Bastion Host B` so that we can easily identify our two instances.
- 1. For the security group, select the existing `bastion-sec-group` we created above.
-
-### Use SSH Agent Forwarding
-
-EC2 instances running Linux use private key files for SSH authentication. You'll connect to your bastion host using an SSH client and the private key file stored on your client. Since the private key file is not present on the bastion host, you will not be able to connect to your instances in private subnets.
-
-Storing private key files on your bastion host is a bad idea. To get around this, use SSH agent forwarding on your client. See [Securely Connect to Linux Instances Running in a Private Amazon VPC](https://aws.amazon.com/blogs/security/securely-connect-to-linux-instances-running-in-a-private-amazon-vpc/) for a step-by-step guide on how to use SSH agent forwarding.
-
-## Install GitLab and create custom AMI
-
-We will need a preconfigured, custom GitLab AMI to use in our launch configuration later. As a starting point, we will use the official GitLab AMI to create a GitLab instance. Then, we'll add our custom configuration for PostgreSQL, Redis, and Gitaly. If you prefer, instead of using the official GitLab AMI, you can also spin up an EC2 instance of your choosing and [manually install GitLab](https://about.gitlab.com/install/).
-
-### Install GitLab
-
-From the EC2 dashboard:
-
-1. Use the section below titled "[Find official GitLab-created AMI IDs on AWS](#find-official-gitlab-created-ami-ids-on-aws)" to find the correct AMI to launch.
-1. After clicking **Launch** on the desired AMI, select an instance type based on your workload. Consult the [hardware requirements](../../install/requirements.md#hardware-requirements) to choose one that fits your needs (at least `c5.xlarge`, which is sufficient to accommodate 100 users).
-1. Click **Configure Instance Details**:
- 1. In the **Network** dropdown, select `gitlab-vpc`, the VPC we created earlier.
- 1. In the **Subnet** dropdown, select `gitlab-private-10.0.1.0` from the list of subnets we created earlier.
- 1. Double check that **Auto-assign Public IP** is set to `Use subnet setting (Disable)`.
- 1. Click **Add Storage**.
- 1. The root volume is 8GiB by default and should be enough given that we won't store any data there.
-1. Click **Add Tags** and add any tags you may need. In our case, we'll only set `Key: Name` and `Value: GitLab`.
-1. Click **Configure Security Group**. Check **Select an existing security group** and select the `gitlab-loadbalancer-sec-group` we created earlier.
-1. Click **Review and launch** followed by **Launch** if you're happy with your settings.
-1. Finally, acknowledge that you have access to the selected private key file or create a new one. Click **Launch Instances**.
-
-### Add custom configuration
-
-Connect to your GitLab instance via **Bastion Host A** using [SSH Agent Forwarding](#use-ssh-agent-forwarding). Once connected, add the following custom configuration:
-
-#### Disable Let's Encrypt
-
-Since we're adding our SSL certificate at the load balancer, we do not need the GitLab built-in support for Let's Encrypt. Let's Encrypt [is enabled by default](https://docs.gitlab.com/omnibus/settings/ssl.html#lets-encrypt-integration) when using an `https` domain in GitLab 10.7 and later, so we need to explicitly disable it:
-
-1. Open `/etc/gitlab/gitlab.rb` and disable it:
-
- ```ruby
- letsencrypt['enable'] = false
- ```
-
-1. Save the file and reconfigure for the changes to take effect:
-
- ```shell
- sudo gitlab-ctl reconfigure
- ```
-
-#### Install the required extensions for PostgreSQL
-
-From your GitLab instance, connect to the RDS instance to verify access and to install the required `pg_trgm` and `btree_gist` extensions.
-
-To find the host or endpoint, navigate to **Amazon RDS > Databases** and click on the database you created earlier. Look for the endpoint under the **Connectivity & security** tab.
-
-Do not to include the colon and port number:
-
-```shell
-sudo /opt/gitlab/embedded/bin/psql -U gitlab -h <rds-endpoint> -d gitlabhq_production
-```
-
-At the `psql` prompt create the extension and then quit the session:
-
-```shell
-psql (10.9)
-Type "help" for help.
-
-gitlab=# CREATE EXTENSION pg_trgm;
-gitlab=# CREATE EXTENSION btree_gist;
-gitlab=# \q
-```
-
-#### Configure GitLab to connect to PostgreSQL and Redis
-
-1. Edit `/etc/gitlab/gitlab.rb`, find the `external_url 'http://<domain>'` option
- and change it to the `https` domain you will be using.
-
-1. Look for the GitLab database settings and uncomment as necessary. In
- our current case we'll specify the database adapter, encoding, host, name,
- username, and password:
-
- ```ruby
- # Disable the built-in Postgres
- postgresql['enable'] = false
-
- # Fill in the connection details
- gitlab_rails['db_adapter'] = "postgresql"
- gitlab_rails['db_encoding'] = "unicode"
- gitlab_rails['db_database'] = "gitlabhq_production"
- gitlab_rails['db_username'] = "gitlab"
- gitlab_rails['db_password'] = "mypassword"
- gitlab_rails['db_host'] = "<rds-endpoint>"
- ```
-
-1. Next, we need to configure the Redis section by adding the host and
- uncommenting the port:
-
- ```ruby
- # Disable the built-in Redis
- redis['enable'] = false
-
- # Fill in the connection details
- gitlab_rails['redis_host'] = "<redis-endpoint>"
- gitlab_rails['redis_port'] = 6379
- ```
-
-1. Finally, reconfigure GitLab for the changes to take effect:
-
- ```shell
- sudo gitlab-ctl reconfigure
- ```
-
-1. You might also find it useful to run a check and a service status to make sure
- everything has been setup correctly:
-
- ```shell
- sudo gitlab-rake gitlab:check
- sudo gitlab-ctl status
- ```
-
-#### Set up Gitaly
-
-WARNING:
-In this architecture, having a single Gitaly server creates a single point of failure. Use
-[Gitaly Cluster](../../administration/gitaly/praefect.md) to remove this limitation.
-
-Gitaly is a service that provides high-level RPC access to Git repositories.
-It should be enabled and configured on a separate EC2 instance in one of the
-[private subnets](#subnets) we configured previously.
-
-Let's create an EC2 instance where we'll install Gitaly:
-
-1. From the EC2 dashboard, click **Launch instance**.
-1. Choose an AMI. In this example, we'll select the **Ubuntu Server 18.04 LTS (HVM), SSD Volume Type**.
-1. Choose an instance type. We'll pick a `c5.xlarge`.
-1. Click **Configure Instance Details**.
- 1. In the **Network** dropdown, select `gitlab-vpc`, the VPC we created earlier.
- 1. In the **Subnet** dropdown, select `gitlab-private-10.0.1.0` from the list of subnets we created earlier.
- 1. Double check that **Auto-assign Public IP** is set to `Use subnet setting (Disable)`.
- 1. Click **Add Storage**.
-1. Increase the Root volume size to `20 GiB` and change the **Volume Type** to `Provisoned IOPS SSD (io1)`. (This is an arbitrary size. Create a volume big enough for your repository storage requirements.)
- 1. For **IOPS** set `1000` (20 GiB x 50 IOPS). You can provision up to 50 IOPS per GiB. If you select a larger volume, increase the IOPS accordingly. Workloads where many small files are written in a serialized manner, like `git`, requires performant storage, hence the choice of `Provisoned IOPS SSD (io1)`.
-1. Click on **Add Tags** and add your tags. In our case, we'll only set `Key: Name` and `Value: Gitaly`.
-1. Click on **Configure Security Group** and let's **Create a new security group**.
- 1. Give your security group a name and description. We'll use `gitlab-gitaly-sec-group` for both.
- 1. Create a **Custom TCP** rule and add port `8075` to the **Port Range**. For the **Source**, select the `gitlab-loadbalancer-sec-group`.
- 1. Also add an inbound rule for SSH from the `bastion-sec-group` so that we can connect using [SSH Agent Forwarding](#use-ssh-agent-forwarding) from the Bastion hosts.
-1. Click **Review and launch** followed by **Launch** if you're happy with your settings.
-1. Finally, acknowledge that you have access to the selected private key file or create a new one. Click **Launch Instances**.
-
-NOTE:
-Instead of storing configuration _and_ repository data on the root volume, you can also choose to add an additional EBS volume for repository storage. Follow the same guidance as above. See the [Amazon EBS pricing](https://aws.amazon.com/ebs/pricing/). We do not recommend using EFS as it may negatively impact the performance of GitLab. You can review the [relevant documentation](../../administration/nfs.md#avoid-using-cloud-based-file-systems) for more details.
-
-Now that we have our EC2 instance ready, follow the [documentation to install GitLab and set up Gitaly on its own server](../../administration/gitaly/configure_gitaly.md#run-gitaly-on-its-own-server). Perform the client setup steps from that document on the [GitLab instance we created](#install-gitlab) above.
-
-#### Add Support for Proxied SSL
-
-As we are terminating SSL at our [load balancer](#load-balancer), follow the steps at [Supporting proxied SSL](https://docs.gitlab.com/omnibus/settings/nginx.html#supporting-proxied-ssl) to configure this in `/etc/gitlab/gitlab.rb`.
-
-Remember to run `sudo gitlab-ctl reconfigure` after saving the changes to the `gitlab.rb` file.
-
-#### Fast lookup of authorized SSH keys
-
-The public SSH keys for users allowed to access GitLab are stored in `/var/opt/gitlab/.ssh/authorized_keys`. Typically we'd use shared storage so that all the instances are able to access this file when a user performs a Git action over SSH. Since we do not have shared storage in our setup, we'll update our configuration to authorize SSH users via indexed lookup in the GitLab database.
-
-Follow the instructions at [Setting up fast lookup via GitLab Shell](../../administration/operations/fast_ssh_key_lookup.md#setting-up-fast-lookup-via-gitlab-shell) to switch from using the `authorized_keys` file to the database.
-
-If you do not configure fast lookup, Git actions over SSH will result in the following error:
-
-```shell
-Permission denied (publickey).
-fatal: Could not read from remote repository.
-
-Please make sure you have the correct access rights
-and the repository exists.
-```
-
-#### Configure host keys
-
-Ordinarily we would manually copy the contents (primary and public keys) of `/etc/ssh/` on the primary application server to `/etc/ssh` on all secondary servers. This prevents false man-in-the-middle-attack alerts when accessing servers in your cluster behind a load balancer.
-
-We'll automate this by creating static host keys as part of our custom AMI. As these host keys are also rotated every time an EC2 instance boots up, "hard coding" them into our custom AMI serves as a handy workaround.
-
-On your GitLab instance run the following:
-
-```shell
-sudo mkdir /etc/ssh_static
-sudo cp -R /etc/ssh/* /etc/ssh_static
-```
-
-In `/etc/ssh/sshd_config` update the following:
-
-```shell
-# HostKeys for protocol version 2
-HostKey /etc/ssh_static/ssh_host_rsa_key
-HostKey /etc/ssh_static/ssh_host_dsa_key
-HostKey /etc/ssh_static/ssh_host_ecdsa_key
-HostKey /etc/ssh_static/ssh_host_ed25519_key
-```
-
-#### Amazon S3 object storage
-
-Since we're not using NFS for shared storage, we will use [Amazon S3](https://aws.amazon.com/s3/) buckets to store backups, artifacts, LFS objects, uploads, merge request diffs, container registry images, and more. Our documentation includes [instructions on how to configure object storage](../../administration/object_storage.md) for each of these data types, and other information about using object storage with GitLab.
-
-NOTE:
-Since we are using the [AWS IAM profile](#create-an-iam-role) we created earlier, be sure to omit the AWS access key and secret access key/value pairs when configuring object storage. Instead, use `'use_iam_profile' => true` in your configuration as shown in the object storage documentation linked above.
-
-Remember to run `sudo gitlab-ctl reconfigure` after saving the changes to the `gitlab.rb` file.
-
-NOTE:
-One current feature of GitLab that still requires a shared directory (NFS) is
-[GitLab Pages](../../user/project/pages/index.md).
-There is [work in progress](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/196)
-to eliminate the need for NFS to support GitLab Pages.
-
----
-
-That concludes the configuration changes for our GitLab instance. Next, we'll create a custom AMI based on this instance to use for our launch configuration and auto scaling group.
-
-### Log in for the first time
-
-Using the domain name you used when setting up [DNS for the load balancer](#configure-dns-for-load-balancer), you should now be able to visit GitLab in your browser.
-If you didn't change the password by any other means, the default password will be the same as the instance ID. To change the default password, login as the `root` user
-with the default password and [change it in the user profile](../../user/profile#change-your-password).
-
-When our [auto scaling group](#create-an-auto-scaling-group) spins up new instances, we'll be able to log in with username `root` and the newly created password.
-
-### Create custom AMI
-
-On the EC2 dashboard:
-
-1. Select the `GitLab` instance we [created earlier](#install-gitlab).
-1. Click on **Actions**, scroll down to **Image** and click **Create Image**.
-1. Give your image a name and description (we'll use `GitLab-Source` for both).
-1. Leave everything else as default and click **Create Image**
-
-Now we have a custom AMI that we'll use to create our launch configuration the next step.
-
-## Deploy GitLab inside an auto scaling group
-
-### Create a launch configuration
-
-From the EC2 dashboard:
-
-1. Select **Launch Configurations** from the left menu and click **Create launch configuration**.
-1. Select **My AMIs** from the left menu and select the `GitLab` custom AMI we created above.
-1. Select an instance type best suited for your needs (at least a `c5.xlarge`) and click **Configure details**.
-1. Enter a name for your launch configuration (we'll use `gitlab-ha-launch-config`).
-1. **Do not** check **Request Spot Instance**.
-1. From the **IAM Role** dropdown, pick the `GitLabAdmin` instance role we [created earlier](#create-an-iam-ec2-instance-role-and-profile).
-1. Leave the rest as defaults and click **Add Storage**.
-1. The root volume is 8GiB by default and should be enough given that we won't store any data there. Click **Configure Security Group**.
-1. Check **Select and existing security group** and select the `gitlab-loadbalancer-sec-group` we created earlier.
-1. Click **Review**, review your changes, and click **Create launch configuration**.
-1. Acknowledge that you have access to the private key or create a new one. Click **Create launch configuration**.
-
-### Create an auto scaling group
-
-1. As soon as the launch configuration is created, you'll see an option to **Create an Auto Scaling group using this launch configuration**. Click that to start creating the auto scaling group.
-1. Enter a **Group name** (we'll use `gitlab-auto-scaling-group`).
-1. For **Group size**, enter the number of instances you want to start with (we'll enter `2`).
-1. Select the `gitlab-vpc` from the **Network** dropdown.
-1. Add both the private [subnets we created earlier](#subnets).
-1. Expand the **Advanced Details** section and check the **Receive traffic from one or more load balancers** option.
-1. From the **Classic Load Balancers** dropdown, select the load balancer we created earlier.
-1. For **Health Check Type**, select **ELB**.
-1. We'll leave our **Health Check Grace Period** as the default `300` seconds. Click **Configure scaling policies**.
-1. Check **Use scaling policies to adjust the capacity of this group**.
-1. For this group we'll scale between 2 and 4 instances where one instance will be added if CPU
-utilization is greater than 60% and one instance is removed if it falls
-to less than 45%.
-
-![Auto scaling group policies](img/policies.png)
-
-1. Finally, configure notifications and tags as you see fit, review your changes, and create the
-auto scaling group.
-
-As the auto scaling group is created, you'll see your new instances spinning up in your EC2 dashboard. You'll also see the new instances added to your load balancer. Once the instances pass the heath check, they are ready to start receiving traffic from the load balancer.
-
-Since our instances are created by the auto scaling group, go back to your instances and terminate the [instance we created manually above](#install-gitlab). We only needed this instance to create our custom AMI.
-
-## Health check and monitoring with Prometheus
-
-Apart from Amazon's Cloudwatch which you can enable on various services,
-GitLab provides its own integrated monitoring solution based on Prometheus.
-For more information on how to set it up, visit the
-[GitLab Prometheus documentation](../../administration/monitoring/prometheus/index.md)
-
-GitLab also has various [health check endpoints](../../user/admin_area/monitoring/health_check.md)
-that you can ping and get reports.
-
-## GitLab Runner
-
-If you want to take advantage of [GitLab CI/CD](../../ci/index.md), you have to
-set up at least one [runner](https://docs.gitlab.com/runner/).
-
-Read more on configuring an
-[autoscaling GitLab Runner on AWS](https://docs.gitlab.com/runner/configuration/runner_autoscale_aws/).
-
-## Backup and restore
-
-GitLab provides [a tool to back up](../../raketasks/backup_restore.md#back-up-gitlab)
-and restore its Git data, database, attachments, LFS objects, and so on.
-
-Some important things to know:
-
-- The backup/restore tool **does not** store some configuration files, like secrets; you'll
- need to [configure this yourself](../../raketasks/backup_restore.md#storing-configuration-files).
-- By default, the backup files are stored locally, but you can
- [backup GitLab using S3](../../raketasks/backup_restore.md#using-amazon-s3).
-- You can [exclude specific directories form the backup](../../raketasks/backup_restore.md#excluding-specific-directories-from-the-backup).
-
-### Backing up GitLab
-
-To back up GitLab:
-
-1. SSH into your instance.
-1. Take a backup:
-
- ```shell
- sudo gitlab-backup create
- ```
-
-NOTE:
-For GitLab 12.1 and earlier, use `gitlab-rake gitlab:backup:create`.
-
-### Restoring GitLab from a backup
-
-To restore GitLab, first review the [restore documentation](../../raketasks/backup_restore.md#restore-gitlab),
-and primarily the restore prerequisites. Then, follow the steps under the
-[Omnibus installations section](../../raketasks/backup_restore.md#restore-for-omnibus-gitlab-installations).
-
-## Updating GitLab
-
-GitLab releases a new version every month on the 22nd. Whenever a new version is
-released, you can update your GitLab instance:
-
-1. SSH into your instance
-1. Take a backup:
-
- ```shell
- sudo gitlab-backup create
- ```
-
-NOTE:
-For GitLab 12.1 and earlier, use `gitlab-rake gitlab:backup:create`.
-
-1. Update the repositories and install GitLab:
-
- ```shell
- sudo apt update
- sudo apt install gitlab-ee
- ```
-
-After a few minutes, the new version should be up and running.
-
-## Find official GitLab-created AMI IDs on AWS
-
-To find the AMIs generated by GitLab:
-
-1. Login to AWS Web Console, so that clicking the links below will take you directly to the AMI list.
-1. Pick the edition you want:
-
- - [GitLab Enterprise Edition](https://console.aws.amazon.com/ec2/v2/home?region=us-east-1#Images:visibility=public-images;ownerAlias=782774275127;search=GitLab%20EE;sort=desc:name): If you want to unlock the enterprise features, a license is needed. Recommended for this guide.
- - [GitLab Community Edition](https://console.aws.amazon.com/ec2/v2/home?region=us-east-1#Images:visibility=public-images;ownerAlias=782774275127;search=GitLab%20CE;sort=desc:name): The open source version of GitLab.
- - [GitLab Premium or Ultimate Marketplace (Prelicensed)](https://console.aws.amazon.com/ec2/v2/home?region=us-east-1#Images:visibility=public-images;source=Marketplace;search=GitLab%20EE;sort=desc:name): 5 user license built into per-minute billing.
-1. AMI IDs are unique per region, so once you've loaded one of the above, select the desired target region in the upper right of the console to see the appropriate AMIs.
-1. Once the console is loaded, you can add additional search criteria to narrow further. For instance, `13.` to find only 13.x versions.
-1. To launch an EC2 Machine with one of the listed AMIs, check the box at the start of the relevant row, and select the "Launch" button near the top of left of the page.
-
-NOTE:
-If you are trying to restore from an older version of GitLab while moving to AWS, find the
-[Enterprise and Community Editions Before 11.10.3](https://console.aws.amazon.com/ec2/v2/home?region=us-east-1#Images:visibility=public-images;ownerAlias=855262394183;sort=desc:name).
-
-## Conclusion
-
-In this guide, we went mostly through scaling and some redundancy options,
-your mileage may vary.
-
-Keep in mind that all solutions come with a trade-off between
-cost/complexity and uptime. The more uptime you want, the more complex the solution.
-And the more complex the solution, the more work is involved in setting up and
-maintaining it.
-
-Have a read through these other resources and feel free to
-[open an issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new)
-to request additional material:
-
-- [Scaling GitLab](../../administration/reference_architectures/index.md):
- GitLab supports several different types of clustering.
-- [Geo replication](../../administration/geo/index.md):
- Geo is the solution for widely distributed development teams.
-- [Omnibus GitLab](https://docs.gitlab.com/omnibus/) - Everything you need to know
- about administering your GitLab instance.
-- [Upload a license](../../user/admin_area/license.md):
- Activate all GitLab Enterprise Edition functionality with a license.
-- [Pricing](https://about.gitlab.com/pricing/): Pricing for the different tiers.
-
-## Troubleshooting
-
-### Instances are failing health checks
-
-If your instances are failing the load balancer's health checks, verify that they are returning a status `200` from the health check endpoint we configured earlier. Any other status, including redirects (e.g. status `302`) will cause the health check to fail.
-
-You may have to set a password on the `root` user to prevent automatic redirects on the sign-in endpoint before health checks will pass.
-
-### "The change you requested was rejected (422)"
-
-If you see this page when trying to set a password via the web interface, make sure `external_url` in `gitlab.rb` matches the domain you are making a request from, and run `sudo gitlab-ctl reconfigure` after making any changes to it.
-
-### Some job logs are not uploaded to object storage
-
-When the GitLab deployment is scaled up to more than one node, some job logs may not be uploaded to [object storage](../../administration/object_storage.md) properly. [Incremental logging is required](../../administration/object_storage.md#other-alternatives-to-file-system-storage) for CI to use object storage.
-
-Enable [incremental logging](../../administration/job_logs.md#enable-or-disable-incremental-logging) if it has not already been enabled.
+- Quality / Distribution / Self-Managed
+- Alliances
+- Training
+- Support
+- Professional Services
+- Public Sector
diff --git a/doc/install/aws/manual_install_aws.md b/doc/install/aws/manual_install_aws.md
new file mode 100644
index 00000000000..a490cf0eb73
--- /dev/null
+++ b/doc/install/aws/manual_install_aws.md
@@ -0,0 +1,850 @@
+---
+stage: Enablement
+group: Distribution
+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
+type: howto
+---
+
+{::options parse_block_html="true" /}
+
+# Installing GitLab on Amazon Web Services (AWS) (DEPRECATED) **(FREE SELF)**
+
+This page offers a walkthrough of a common configuration for GitLab on AWS using the official GitLab Linux package. You should customize it to accommodate your needs.
+
+NOTE:
+For organizations with 1,000 users or less, the recommended AWS installation method is to launch an EC2 single box [Omnibus Installation](https://about.gitlab.com/install/) and implement a snapshot strategy for backing up the data. See the [1,000 user reference architecture](../../administration/reference_architectures/1k_users.md) for more.
+
+NOTE:
+The [GitLab Environment Toolkit (GET)](https://gitlab.com/gitlab-org/quality/gitlab-environment-toolkit/-/tree/master) is GitLabs internal effort to create a multi-cloud, multi-GitLab toolkit to provision GitLab. It can be used to deploy Omnibus GitLab on AWS. GET is developed by GitLab developers and is open to community contributions.
+
+## Introduction
+
+For the most part, we'll make use of Omnibus GitLab in our setup, but we'll also leverage native AWS services. Instead of using the Omnibus bundled PostgreSQL and Redis, we will use AWS RDS and ElastiCache.
+
+In this guide, we'll go through a multi-node setup where we'll start by
+configuring our Virtual Private Cloud and subnets to later integrate
+services such as RDS for our database server and ElastiCache as a Redis
+cluster to finally manage them within an auto scaling group with custom
+scaling policies.
+
+## Requirements
+
+In addition to having a basic familiarity with [AWS](https://docs.aws.amazon.com/) and [Amazon EC2](https://docs.aws.amazon.com/ec2/), you will need:
+
+- [An AWS account](https://console.aws.amazon.com/console/home)
+- [To create or upload an SSH key](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html)
+ to connect to the instance via SSH
+- A domain name for the GitLab instance
+- An SSL/TLS certificate to secure your domain. If you do not already own one, you can provision a free public SSL/TLS certificate through [AWS Certificate Manager](https://aws.amazon.com/certificate-manager/)(ACM) for use with the [Elastic Load Balancer](#load-balancer) we'll create.
+
+NOTE:
+It can take a few hours to validate a certificate provisioned through ACM. To avoid delays later, request your certificate as soon as possible.
+
+## Architecture
+
+Below is a diagram of the recommended architecture.
+
+![AWS architecture diagram](img/aws_ha_architecture_diagram.png)
+
+## AWS costs
+
+GitLab uses the following AWS services, with links to pricing information:
+
+- **EC2**: GitLab is deployed on shared hardware, for which
+ [on-demand pricing](https://aws.amazon.com/ec2/pricing/on-demand/) applies.
+ If you want to run GitLab on a dedicated or reserved instance, see the
+ [EC2 pricing page](https://aws.amazon.com/ec2/pricing/) for information about
+ its cost.
+- **S3**: GitLab uses S3 ([pricing page](https://aws.amazon.com/s3/pricing/)) to
+ store backups, artifacts, and LFS objects.
+- **ELB**: A Classic Load Balancer ([pricing page](https://aws.amazon.com/elasticloadbalancing/pricing/)),
+ used to route requests to the GitLab instances.
+- **RDS**: An Amazon Relational Database Service using PostgreSQL
+ ([pricing page](https://aws.amazon.com/rds/postgresql/pricing/)).
+- **ElastiCache**: An in-memory cache environment ([pricing page](https://aws.amazon.com/elasticache/pricing/)),
+ used to provide a Redis configuration.
+
+## Create an IAM EC2 instance role and profile
+
+As we'll be using [Amazon S3 object storage](#amazon-s3-object-storage), our EC2 instances need to have read, write, and list permissions for our S3 buckets. To avoid embedding AWS keys in our GitLab configuration, we'll make use of an [IAM Role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) to allow our GitLab instance with this access. We'll need to create an IAM policy to attach to our IAM role:
+
+### Create an IAM Policy
+
+1. Navigate to the IAM dashboard and click on **Policies** in the left menu.
+1. Click **Create policy**, select the `JSON` tab, and add a policy. We want to [follow security best practices and grant _least privilege_](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege), giving our role only the permissions needed to perform the required actions.
+ 1. Assuming you prefix the S3 bucket names with `gl-` as shown in the diagram, add the following policy:
+
+ ```json
+ { "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Effect": "Allow",
+ "Action": [
+ "s3:PutObject",
+ "s3:GetObject",
+ "s3:DeleteObject",
+ "s3:PutObjectAcl"
+ ],
+ "Resource": "arn:aws:s3:::gl-*/*"
+ },
+ {
+ "Effect": "Allow",
+ "Action": [
+ "s3:ListBucket",
+ "s3:AbortMultipartUpload",
+ "s3:ListMultipartUploadParts",
+ "s3:ListBucketMultipartUploads"
+ ],
+ "Resource": "arn:aws:s3:::gl-*"
+ }
+ ]
+ }
+ ```
+
+1. Click **Review policy**, give your policy a name (we'll use `gl-s3-policy`), and click **Create policy**.
+
+### Create an IAM Role
+
+1. Still on the IAM dashboard, click on **Roles** in the left menu, and
+ click **Create role**.
+1. Create a new role by selecting **AWS service > EC2**, then click
+ **Next: Permissions**.
+1. In the policy filter, search for the `gl-s3-policy` we created above, select it, and click **Tags**.
+1. Add tags if needed and click **Review**.
+1. Give the role a name (we'll use `GitLabS3Access`) and click **Create Role**.
+
+We'll use this role when we [create a launch configuration](#create-a-launch-configuration) later on.
+
+## Configuring the network
+
+We'll start by creating a VPC for our GitLab cloud infrastructure, then
+we can create subnets to have public and private instances in at least
+two [Availability Zones (AZs)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html). Public subnets will require a Route Table keep and an associated
+Internet Gateway.
+
+### Creating the Virtual Private Cloud (VPC)
+
+We'll now create a VPC, a virtual networking environment that you'll control:
+
+1. Sign in to [Amazon Web Services](https://console.aws.amazon.com/vpc/home).
+1. Select **Your VPCs** from the left menu and then click **Create VPC**.
+ At the "Name tag" enter `gitlab-vpc` and at the "IPv4 CIDR block" enter
+ `10.0.0.0/16`. If you don't require dedicated hardware, you can leave
+ "Tenancy" as default. Click **Yes, Create** when ready.
+
+ ![Create VPC](img/create_vpc.png)
+
+1. Select the VPC, click **Actions**, click **Edit DNS resolution**, and enable DNS resolution. Hit **Save** when done.
+
+### Subnets
+
+Now, let's create some subnets in different Availability Zones. Make sure
+that each subnet is associated to the VPC we just created and
+that CIDR blocks don't overlap. This will also
+allow us to enable multi AZ for redundancy.
+
+We will create private and public subnets to match load balancers and
+RDS instances as well:
+
+1. Select **Subnets** from the left menu.
+1. Click **Create subnet**. Give it a descriptive name tag based on the IP,
+ for example `gitlab-public-10.0.0.0`, select the VPC we created previously, select an availability zone (we'll use `us-west-2a`),
+ and at the IPv4 CIDR block let's give it a 24 subnet `10.0.0.0/24`:
+
+ ![Create subnet](img/create_subnet.png)
+
+1. Follow the same steps to create all subnets:
+
+ | Name tag | Type | Availability Zone | CIDR block |
+ | ------------------------- | ------- | ----------------- | ------------- |
+ | `gitlab-public-10.0.0.0` | public | `us-west-2a` | `10.0.0.0/24` |
+ | `gitlab-private-10.0.1.0` | private | `us-west-2a` | `10.0.1.0/24` |
+ | `gitlab-public-10.0.2.0` | public | `us-west-2b` | `10.0.2.0/24` |
+ | `gitlab-private-10.0.3.0` | private | `us-west-2b` | `10.0.3.0/24` |
+
+1. Once all the subnets are created, enable **Auto-assign IPv4** for the two public subnets:
+ 1. Select each public subnet in turn, click **Actions**, and click **Modify auto-assign IP settings**. Enable the option and save.
+
+### Internet Gateway
+
+Now, still on the same dashboard, go to Internet Gateways and
+create a new one:
+
+1. Select **Internet Gateways** from the left menu.
+1. Click **Create internet gateway**, give it the name `gitlab-gateway` and
+ click **Create**.
+1. Select it from the table, and then under the **Actions** dropdown choose
+ "Attach to VPC".
+
+ ![Create gateway](img/create_gateway.png)
+
+1. Choose `gitlab-vpc` from the list and hit **Attach**.
+
+### Create NAT Gateways
+
+Instances deployed in our private subnets need to connect to the internet for updates, but should not be reachable from the public internet. To achieve this, we'll make use of [NAT Gateways](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html) deployed in each of our public subnets:
+
+1. Navigate to the VPC dashboard and click on **NAT Gateways** in the left menu bar.
+1. Click **Create NAT Gateway** and complete the following:
+ 1. **Subnet**: Select `gitlab-public-10.0.0.0` from the dropdown.
+ 1. **Elastic IP Allocation ID**: Enter an existing Elastic IP or click **Allocate Elastic IP address** to allocate a new IP to your NAT gateway.
+ 1. Add tags if needed.
+ 1. Click **Create NAT Gateway**.
+
+Create a second NAT gateway but this time place it in the second public subnet, `gitlab-public-10.0.2.0`.
+
+### Route Tables
+
+#### Public Route Table
+
+We need to create a route table for our public subnets to reach the internet via the internet gateway we created in the previous step.
+
+On the VPC dashboard:
+
+1. Select **Route Tables** from the left menu.
+1. Click **Create Route Table**.
+1. At the "Name tag" enter `gitlab-public` and choose `gitlab-vpc` under "VPC".
+1. Click **Create**.
+
+We now need to add our internet gateway as a new target and have
+it receive traffic from any destination.
+
+1. Select **Route Tables** from the left menu and select the `gitlab-public`
+ route to show the options at the bottom.
+1. Select the **Routes** tab, click **Edit routes > Add route** and set `0.0.0.0/0`
+ as the destination. In the target column, select the `gitlab-gateway` we created previously.
+ Hit **Save routes** once done.
+
+Next, we must associate the **public** subnets to the route table:
+
+1. Select the **Subnet Associations** tab and click **Edit subnet associations**.
+1. Check only the public subnets and click **Save**.
+
+#### Private Route Tables
+
+We also need to create two private route tables so that instances in each private subnet can reach the internet via the NAT gateway in the corresponding public subnet in the same availability zone.
+
+1. Follow the same steps as above to create two private route tables. Name them `gitlab-private-a` and `gitlab-private-b` respectively.
+1. Next, add a new route to each of the private route tables where the destination is `0.0.0.0/0` and the target is one of the NAT gateways we created earlier.
+ 1. Add the NAT gateway we created in `gitlab-public-10.0.0.0` as the target for the new route in the `gitlab-private-a` route table.
+ 1. Similarly, add the NAT gateway in `gitlab-public-10.0.2.0` as the target for the new route in the `gitlab-private-b`.
+1. Lastly, associate each private subnet with a private route table.
+ 1. Associate `gitlab-private-10.0.1.0` with `gitlab-private-a`.
+ 1. Associate `gitlab-private-10.0.3.0` with `gitlab-private-b`.
+
+## Load Balancer
+
+We'll create a load balancer to evenly distribute inbound traffic on ports `80` and `443` across our GitLab application servers. Based the on the [scaling policies](#create-an-auto-scaling-group) we'll create later, instances will be added to or removed from our load balancer as needed. Additionally, the load balance will perform health checks on our instances.
+
+On the EC2 dashboard, look for Load Balancer in the left navigation bar:
+
+1. Click the **Create Load Balancer** button.
+ 1. Choose the **Classic Load Balancer**.
+ 1. Give it a name (we'll use `gitlab-loadbalancer`) and for the **Create LB Inside** option, select `gitlab-vpc` from the dropdown menu.
+ 1. In the **Listeners** section, set the following listeners:
+ - HTTP port 80 for both load balancer and instance protocol and ports
+ - TCP port 22 for both load balancer and instance protocols and ports
+ - HTTPS port 443 for load balancer protocol and ports, forwarding to HTTP port 80 on the instance (we will configure GitLab to listen on port 80 [later in the guide](#add-support-for-proxied-ssl))
+ 1. In the **Select Subnets** section, select both public subnets from the list so that the load balancer can route traffic to both availability zones.
+1. We'll add a security group for our load balancer to act as a firewall to control what traffic is allowed through. Click **Assign Security Groups** and select **Create a new security group**, give it a name
+ (we'll use `gitlab-loadbalancer-sec-group`) and description, and allow both HTTP and HTTPS traffic
+ from anywhere (`0.0.0.0/0, ::/0`). Also allow SSH traffic, select a custom source, and add a single trusted IP address or an IP address range in CIDR notation. This will allow users to perform Git actions over SSH.
+1. Click **Configure Security Settings** and set the following:
+ 1. Select an SSL/TLS certificate from ACM or upload a certificate to IAM.
+ 1. Under **Select a Cipher**, pick a predefined security policy from the dropdown. You can see a breakdown of [Predefined SSL Security Policies for Classic Load Balancers](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-security-policy-table.html) in the AWS docs. Check the GitLab codebase for a list of [supported SSL ciphers and protocols](https://gitlab.com/gitlab-org/gitlab/-/blob/9ee7ad433269b37251e0dd5b5e00a0f00d8126b4/lib/support/nginx/gitlab-ssl#L97-99).
+1. Click **Configure Health Check** and set up a health check for your EC2 instances.
+ 1. For **Ping Protocol**, select HTTP.
+ 1. For **Ping Port**, enter 80.
+ 1. For **Ping Path**, enter `/users/sign_in`. (We use `/users/sign_in` as it's a public endpoint that does
+ not require authentication.)
+ 1. Keep the default **Advanced Details** or adjust them according to your needs.
+1. Click **Add EC2 Instances** - don't add anything as we will create an Auto Scaling Group later to manage instances for us.
+1. Click **Add Tags** and add any tags you need.
+1. Click **Review and Create**, review all your settings, and click **Create** if you're happy.
+
+After the Load Balancer is up and running, you can revisit your Security
+Groups to refine the access only through the ELB and any other requirements
+you might have.
+
+### Configure DNS for Load Balancer
+
+On the Route 53 dashboard, click **Hosted zones** in the left navigation bar:
+
+1. Select an existing hosted zone or, if you do not already have one for your domain, click **Create Hosted Zone**, enter your domain name, and click **Create**.
+1. Click **Create Record Set** and provide the following values:
+ 1. **Name:** Use the domain name (the default value) or enter a subdomain.
+ 1. **Type:** Select **A - IPv4 address**.
+ 1. **Alias:** Defaults to **No**. Select **Yes**.
+ 1. **Alias Target:** Find the **ELB Classic Load Balancers** section and select the classic load balancer we created earlier.
+ 1. **Routing Policy:** We'll use **Simple** but you can choose a different policy based on your use case.
+ 1. **Evaluate Target Health:** We'll set this to **No** but you can choose to have the load balancer route traffic based on target health.
+ 1. Click **Create**.
+1. If you registered your domain through Route 53, you're done. If you used a different domain registrar, you need to update your DNS records with your domain registrar. You'll need to:
+ 1. Click on **Hosted zones** and select the domain you added above.
+ 1. You'll see a list of `NS` records. From your domain registrar's administrator panel, add each of these as `NS` records to your domain's DNS records. These steps may vary between domain registrars. If you're stuck, Google **"name of your registrar" add DNS records** and you should find a help article specific to your domain registrar.
+
+The steps for doing this vary depending on which registrar you use and is beyond the scope of this guide.
+
+## PostgreSQL with RDS
+
+For our database server we will use Amazon RDS which offers Multi AZ
+for redundancy. First we'll create a security group and subnet group, then we'll
+create the actual RDS instance.
+
+### RDS Security Group
+
+We need a security group for our database that will allow inbound traffic from the instances we'll deploy in our `gitlab-loadbalancer-sec-group` later on:
+
+1. From the EC2 dashboard, select **Security Groups** from the left menu bar.
+1. Click **Create security group**.
+1. Give it a name (we'll use `gitlab-rds-sec-group`), a description, and select the `gitlab-vpc` from the **VPC** dropdown.
+1. In the **Inbound rules** section, click **Add rule** and set the following:
+ 1. **Type:** search for and select the **PostgreSQL** rule.
+ 1. **Source type:** set as "Custom".
+ 1. **Source:** select the `gitlab-loadbalancer-sec-group` we created earlier.
+1. When done, click **Create security group**.
+
+### RDS Subnet Group
+
+1. Navigate to the RDS dashboard and select **Subnet Groups** from the left menu.
+1. Click on **Create DB Subnet Group**.
+1. Under **Subnet group details**, enter a name (we'll use `gitlab-rds-group`), a description, and choose the `gitlab-vpc` from the VPC dropdown.
+1. From the **Availability Zones** dropdown, select the Availability Zones that include the subnets you've configured. In our case, we'll add `eu-west-2a` and `eu-west-2b`.
+1. From the **Subnets** dropdown, select the two private subnets (`10.0.1.0/24` and `10.0.3.0/24`) as we defined them in the [subnets section](#subnets).
+1. Click **Create** when ready.
+
+### Create the database
+
+WARNING:
+Avoid using burstable instances (t class instances) for the database as this could lead to performance issues due to CPU credits running out during sustained periods of high load.
+
+Now, it's time to create the database:
+
+1. Navigate to the RDS dashboard, select **Databases** from the left menu, and click **Create database**.
+1. Select **Standard Create** for the database creation method.
+1. Select **PostgreSQL** as the database engine and select the minimum PostgreSQL version as defined for your GitLab version in our [database requirements](../../install/requirements.md#postgresql-requirements).
+1. Since this is a production server, let's choose **Production** from the **Templates** section.
+1. Under **Settings**, set a DB instance identifier, a master username, and a master password. We'll use `gitlab-db-ha`, `gitlab`, and a very secure password respectively. Make a note of these as we'll need them later.
+1. For the DB instance size, select **Standard classes** and select an instance size that meets your requirements from the dropdown menu. We'll use a `db.m4.large` instance.
+1. Under **Storage**, configure the following:
+ 1. Select **Provisioned IOPS (SSD)** from the storage type dropdown menu. Provisioned IOPS (SSD) storage is best suited for this use (though you can choose General Purpose (SSD) to reduce the costs). Read more about it at [Storage for Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Storage.html).
+ 1. Allocate storage and set provisioned IOPS. We'll use the minimum values, `100` and `1000`, respectively.
+ 1. Enable storage autoscaling (optional) and set a maximum storage threshold.
+1. Under **Availability & durability**, select **Create a standby instance** to have a standby RDS instance provisioned in a different [Availability Zone](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.MultiAZ.html).
+1. Under **Connectivity**, configure the following:
+ 1. Select the VPC we created earlier (`gitlab-vpc`) from the **Virtual Private Cloud (VPC)** dropdown menu.
+ 1. Expand the **Additional connectivity configuration** section and select the subnet group (`gitlab-rds-group`) we created earlier.
+ 1. Set public accessibility to **No**.
+ 1. Under **VPC security group**, select **Choose existing** and select the `gitlab-rds-sec-group` we create above from the dropdown.
+ 1. Leave the database port as the default `5432`.
+1. For **Database authentication**, select **Password authentication**.
+1. Expand the **Additional configuration** section and complete the following:
+ 1. The initial database name. We'll use `gitlabhq_production`.
+ 1. Configure your preferred backup settings.
+ 1. The only other change we'll make here is to disable auto minor version updates under **Maintenance**.
+ 1. Leave all the other settings as is or tweak according to your needs.
+ 1. Once you're happy, click **Create database**.
+
+Now that the database is created, let's move on to setting up Redis with ElastiCache.
+
+## Redis with ElastiCache
+
+ElastiCache is an in-memory hosted caching solution. Redis maintains its own
+persistence and is used to store session data, temporary cache information, and background job queues for the GitLab application.
+
+### Create a Redis Security Group
+
+1. Navigate to the EC2 dashboard.
+1. Select **Security Groups** from the left menu.
+1. Click **Create security group** and fill in the details. Give it a name (we'll use `gitlab-redis-sec-group`),
+ add a description, and choose the VPC we created previously
+1. In the **Inbound rules** section, click **Add rule** and add a **Custom TCP** rule, set port `6379`, and set the "Custom" source as the `gitlab-loadbalancer-sec-group` we created earlier.
+1. When done, click **Create security group**.
+
+### Redis Subnet Group
+
+1. Navigate to the ElastiCache dashboard from your AWS console.
+1. Go to **Subnet Groups** in the left menu, and create a new subnet group (we'll name ours `gitlab-redis-group`).
+ Make sure to select our VPC and its [private subnets](#subnets). Click
+ **Create** when ready.
+
+ ![ElastiCache subnet](img/ec_subnet.png)
+
+### Create the Redis Cluster
+
+1. Navigate back to the ElastiCache dashboard.
+1. Select **Redis** on the left menu and click **Create** to create a new
+ Redis cluster. Do not enable **Cluster Mode** as it is [not supported](../../administration/redis/replication_and_failover_external.md#requirements). Even without cluster mode on, you still get the
+ chance to deploy Redis in multiple availability zones.
+1. In the settings section:
+ 1. Give the cluster a name (`gitlab-redis`) and a description.
+ 1. For the version, select the latest of `5.0` series (e.g., `5.0.6`).
+ 1. Leave the port as `6379` since this is what we used in our Redis security group above.
+ 1. Select the node type (at least `cache.t3.medium`, but adjust to your needs) and the number of replicas.
+1. In the advanced settings section:
+ 1. Select the multi-AZ auto-failover option.
+ 1. Select the subnet group we created previously.
+ 1. Manually select the preferred availability zones, and under "Replica 2"
+ choose a different zone than the other two.
+
+ ![Redis availability zones](img/ec_az.png)
+
+1. In the security settings, edit the security groups and choose the
+ `gitlab-redis-sec-group` we had previously created.
+1. Leave the rest of the settings to their default values or edit to your liking.
+1. When done, click **Create**.
+
+## Setting up Bastion Hosts
+
+Since our GitLab instances will be in private subnets, we need a way to connect to these instances via SSH to make configuration changes, perform upgrades, etc. One way of doing this is via a [bastion host](https://en.wikipedia.org/wiki/Bastion_host), sometimes also referred to as a jump box.
+
+NOTE:
+If you do not want to maintain bastion hosts, you can set up [AWS Systems Manager Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html) for access to instances. This is beyond the scope of this document.
+
+### Create Bastion Host A
+
+1. Navigate to the EC2 Dashboard and click on **Launch instance**.
+1. Select the **Ubuntu Server 18.04 LTS (HVM)** AMI.
+1. Choose an instance type. We'll use a `t2.micro` as we'll only use the bastion host to SSH into our other instances.
+1. Click **Configure Instance Details**.
+ 1. Under **Network**, select the `gitlab-vpc` from the dropdown menu.
+ 1. Under **Subnet**, select the public subnet we created earlier (`gitlab-public-10.0.0.0`).
+ 1. Double check that under **Auto-assign Public IP** you have **Use subnet setting (Enable)** selected.
+ 1. Leave everything else as default and click **Add Storage**.
+1. For storage, we'll leave everything as default and only add an 8GB root volume. We won't store anything on this instance.
+1. Click **Add Tags** and on the next screen click **Add Tag**.
+ 1. We'll only set `Key: Name` and `Value: Bastion Host A`.
+1. Click **Configure Security Group**.
+ 1. Select **Create a new security group**, enter a **Security group name** (we'll use `bastion-sec-group`), and add a description.
+ 1. We'll enable SSH access from anywhere (`0.0.0.0/0`). If you want stricter security, specify a single IP address or an IP address range in CIDR notation.
+ 1. Click **Review and Launch**
+1. Review all your settings and, if you're happy, click **Launch**.
+1. Acknowledge that you have access to an existing key pair or create a new one. Click **Launch Instance**.
+
+Confirm that you can SSH into the instance:
+
+1. On the EC2 Dashboard, click on **Instances** in the left menu.
+1. Select **Bastion Host A** from your list of instances.
+1. Click **Connect** and follow the connection instructions.
+1. If you are able to connect successfully, let's move on to setting up our second bastion host for redundancy.
+
+### Create Bastion Host B
+
+1. Create an EC2 instance following the same steps as above with the following changes:
+ 1. For the **Subnet**, select the second public subnet we created earlier (`gitlab-public-10.0.2.0`).
+ 1. Under the **Add Tags** section, we'll set `Key: Name` and `Value: Bastion Host B` so that we can easily identify our two instances.
+ 1. For the security group, select the existing `bastion-sec-group` we created above.
+
+### Use SSH Agent Forwarding
+
+EC2 instances running Linux use private key files for SSH authentication. You'll connect to your bastion host using an SSH client and the private key file stored on your client. Since the private key file is not present on the bastion host, you will not be able to connect to your instances in private subnets.
+
+Storing private key files on your bastion host is a bad idea. To get around this, use SSH agent forwarding on your client. See [Securely Connect to Linux Instances Running in a Private Amazon VPC](https://aws.amazon.com/blogs/security/securely-connect-to-linux-instances-running-in-a-private-amazon-vpc/) for a step-by-step guide on how to use SSH agent forwarding.
+
+## Install GitLab and create custom AMI
+
+We will need a preconfigured, custom GitLab AMI to use in our launch configuration later. As a starting point, we will use the official GitLab AMI to create a GitLab instance. Then, we'll add our custom configuration for PostgreSQL, Redis, and Gitaly. If you prefer, instead of using the official GitLab AMI, you can also spin up an EC2 instance of your choosing and [manually install GitLab](https://about.gitlab.com/install/).
+
+### Install GitLab
+
+From the EC2 dashboard:
+
+1. Use the section below titled "[Find official GitLab-created AMI IDs on AWS](#find-official-gitlab-created-ami-ids-on-aws)" to find the correct AMI to launch.
+1. After clicking **Launch** on the desired AMI, select an instance type based on your workload. Consult the [hardware requirements](../../install/requirements.md#hardware-requirements) to choose one that fits your needs (at least `c5.xlarge`, which is sufficient to accommodate 100 users).
+1. Click **Configure Instance Details**:
+ 1. In the **Network** dropdown, select `gitlab-vpc`, the VPC we created earlier.
+ 1. In the **Subnet** dropdown, select `gitlab-private-10.0.1.0` from the list of subnets we created earlier.
+ 1. Double check that **Auto-assign Public IP** is set to `Use subnet setting (Disable)`.
+ 1. Click **Add Storage**.
+ 1. The root volume is 8GiB by default and should be enough given that we won't store any data there.
+1. Click **Add Tags** and add any tags you may need. In our case, we'll only set `Key: Name` and `Value: GitLab`.
+1. Click **Configure Security Group**. Check **Select an existing security group** and select the `gitlab-loadbalancer-sec-group` we created earlier.
+1. Click **Review and launch** followed by **Launch** if you're happy with your settings.
+1. Finally, acknowledge that you have access to the selected private key file or create a new one. Click **Launch Instances**.
+
+### Add custom configuration
+
+Connect to your GitLab instance via **Bastion Host A** using [SSH Agent Forwarding](#use-ssh-agent-forwarding). Once connected, add the following custom configuration:
+
+#### Disable Let's Encrypt
+
+Since we're adding our SSL certificate at the load balancer, we do not need the GitLab built-in support for Let's Encrypt. Let's Encrypt [is enabled by default](https://docs.gitlab.com/omnibus/settings/ssl.html#lets-encrypt-integration) when using an `https` domain in GitLab 10.7 and later, so we need to explicitly disable it:
+
+1. Open `/etc/gitlab/gitlab.rb` and disable it:
+
+ ```ruby
+ letsencrypt['enable'] = false
+ ```
+
+1. Save the file and reconfigure for the changes to take effect:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+#### Install the required extensions for PostgreSQL
+
+From your GitLab instance, connect to the RDS instance to verify access and to install the required `pg_trgm` and `btree_gist` extensions.
+
+To find the host or endpoint, navigate to **Amazon RDS > Databases** and click on the database you created earlier. Look for the endpoint under the **Connectivity & security** tab.
+
+Do not to include the colon and port number:
+
+```shell
+sudo /opt/gitlab/embedded/bin/psql -U gitlab -h <rds-endpoint> -d gitlabhq_production
+```
+
+At the `psql` prompt create the extension and then quit the session:
+
+```shell
+psql (10.9)
+Type "help" for help.
+
+gitlab=# CREATE EXTENSION pg_trgm;
+gitlab=# CREATE EXTENSION btree_gist;
+gitlab=# \q
+```
+
+#### Configure GitLab to connect to PostgreSQL and Redis
+
+1. Edit `/etc/gitlab/gitlab.rb`, find the `external_url 'http://<domain>'` option
+ and change it to the `https` domain you will be using.
+
+1. Look for the GitLab database settings and uncomment as necessary. In
+ our current case we'll specify the database adapter, encoding, host, name,
+ username, and password:
+
+ ```ruby
+ # Disable the built-in Postgres
+ postgresql['enable'] = false
+
+ # Fill in the connection details
+ gitlab_rails['db_adapter'] = "postgresql"
+ gitlab_rails['db_encoding'] = "unicode"
+ gitlab_rails['db_database'] = "gitlabhq_production"
+ gitlab_rails['db_username'] = "gitlab"
+ gitlab_rails['db_password'] = "mypassword"
+ gitlab_rails['db_host'] = "<rds-endpoint>"
+ ```
+
+1. Next, we need to configure the Redis section by adding the host and
+ uncommenting the port:
+
+ ```ruby
+ # Disable the built-in Redis
+ redis['enable'] = false
+
+ # Fill in the connection details
+ gitlab_rails['redis_host'] = "<redis-endpoint>"
+ gitlab_rails['redis_port'] = 6379
+ ```
+
+1. Finally, reconfigure GitLab for the changes to take effect:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+1. You might also find it useful to run a check and a service status to make sure
+ everything has been setup correctly:
+
+ ```shell
+ sudo gitlab-rake gitlab:check
+ sudo gitlab-ctl status
+ ```
+
+#### Set up Gitaly
+
+WARNING:
+In this architecture, having a single Gitaly server creates a single point of failure. Use
+[Gitaly Cluster](../../administration/gitaly/praefect.md) to remove this limitation.
+
+Gitaly is a service that provides high-level RPC access to Git repositories.
+It should be enabled and configured on a separate EC2 instance in one of the
+[private subnets](#subnets) we configured previously.
+
+Let's create an EC2 instance where we'll install Gitaly:
+
+1. From the EC2 dashboard, click **Launch instance**.
+1. Choose an AMI. In this example, we'll select the **Ubuntu Server 18.04 LTS (HVM), SSD Volume Type**.
+1. Choose an instance type. We'll pick a `c5.xlarge`.
+1. Click **Configure Instance Details**.
+ 1. In the **Network** dropdown, select `gitlab-vpc`, the VPC we created earlier.
+ 1. In the **Subnet** dropdown, select `gitlab-private-10.0.1.0` from the list of subnets we created earlier.
+ 1. Double check that **Auto-assign Public IP** is set to `Use subnet setting (Disable)`.
+ 1. Click **Add Storage**.
+1. Increase the Root volume size to `20 GiB` and change the **Volume Type** to `Provisoned IOPS SSD (io1)`. (This is an arbitrary size. Create a volume big enough for your repository storage requirements.)
+ 1. For **IOPS** set `1000` (20 GiB x 50 IOPS). You can provision up to 50 IOPS per GiB. If you select a larger volume, increase the IOPS accordingly. Workloads where many small files are written in a serialized manner, like `git`, requires performant storage, hence the choice of `Provisoned IOPS SSD (io1)`.
+1. Click on **Add Tags** and add your tags. In our case, we'll only set `Key: Name` and `Value: Gitaly`.
+1. Click on **Configure Security Group** and let's **Create a new security group**.
+ 1. Give your security group a name and description. We'll use `gitlab-gitaly-sec-group` for both.
+ 1. Create a **Custom TCP** rule and add port `8075` to the **Port Range**. For the **Source**, select the `gitlab-loadbalancer-sec-group`.
+ 1. Also add an inbound rule for SSH from the `bastion-sec-group` so that we can connect using [SSH Agent Forwarding](#use-ssh-agent-forwarding) from the Bastion hosts.
+1. Click **Review and launch** followed by **Launch** if you're happy with your settings.
+1. Finally, acknowledge that you have access to the selected private key file or create a new one. Click **Launch Instances**.
+
+NOTE:
+Instead of storing configuration _and_ repository data on the root volume, you can also choose to add an additional EBS volume for repository storage. Follow the same guidance as above. See the [Amazon EBS pricing](https://aws.amazon.com/ebs/pricing/). We do not recommend using EFS as it may negatively impact the performance of GitLab. You can review the [relevant documentation](../../administration/nfs.md#avoid-using-cloud-based-file-systems) for more details.
+
+Now that we have our EC2 instance ready, follow the [documentation to install GitLab and set up Gitaly on its own server](../../administration/gitaly/configure_gitaly.md#run-gitaly-on-its-own-server). Perform the client setup steps from that document on the [GitLab instance we created](#install-gitlab) above.
+
+#### Add Support for Proxied SSL
+
+As we are terminating SSL at our [load balancer](#load-balancer), follow the steps at [Supporting proxied SSL](https://docs.gitlab.com/omnibus/settings/nginx.html#supporting-proxied-ssl) to configure this in `/etc/gitlab/gitlab.rb`.
+
+Remember to run `sudo gitlab-ctl reconfigure` after saving the changes to the `gitlab.rb` file.
+
+#### Fast lookup of authorized SSH keys
+
+The public SSH keys for users allowed to access GitLab are stored in `/var/opt/gitlab/.ssh/authorized_keys`. Typically we'd use shared storage so that all the instances are able to access this file when a user performs a Git action over SSH. Since we do not have shared storage in our setup, we'll update our configuration to authorize SSH users via indexed lookup in the GitLab database.
+
+Follow the instructions at [Setting up fast lookup via GitLab Shell](../../administration/operations/fast_ssh_key_lookup.md#setting-up-fast-lookup-via-gitlab-shell) to switch from using the `authorized_keys` file to the database.
+
+If you do not configure fast lookup, Git actions over SSH will result in the following error:
+
+```shell
+Permission denied (publickey).
+fatal: Could not read from remote repository.
+
+Please make sure you have the correct access rights
+and the repository exists.
+```
+
+#### Configure host keys
+
+Ordinarily we would manually copy the contents (primary and public keys) of `/etc/ssh/` on the primary application server to `/etc/ssh` on all secondary servers. This prevents false man-in-the-middle-attack alerts when accessing servers in your cluster behind a load balancer.
+
+We'll automate this by creating static host keys as part of our custom AMI. As these host keys are also rotated every time an EC2 instance boots up, "hard coding" them into our custom AMI serves as a handy workaround.
+
+On your GitLab instance run the following:
+
+```shell
+sudo mkdir /etc/ssh_static
+sudo cp -R /etc/ssh/* /etc/ssh_static
+```
+
+In `/etc/ssh/sshd_config` update the following:
+
+```shell
+# HostKeys for protocol version 2
+HostKey /etc/ssh_static/ssh_host_rsa_key
+HostKey /etc/ssh_static/ssh_host_dsa_key
+HostKey /etc/ssh_static/ssh_host_ecdsa_key
+HostKey /etc/ssh_static/ssh_host_ed25519_key
+```
+
+#### Amazon S3 object storage
+
+Since we're not using NFS for shared storage, we will use [Amazon S3](https://aws.amazon.com/s3/) buckets to store backups, artifacts, LFS objects, uploads, merge request diffs, container registry images, and more. Our documentation includes [instructions on how to configure object storage](../../administration/object_storage.md) for each of these data types, and other information about using object storage with GitLab.
+
+NOTE:
+Since we are using the [AWS IAM profile](#create-an-iam-role) we created earlier, be sure to omit the AWS access key and secret access key/value pairs when configuring object storage. Instead, use `'use_iam_profile' => true` in your configuration as shown in the object storage documentation linked above.
+
+Remember to run `sudo gitlab-ctl reconfigure` after saving the changes to the `gitlab.rb` file.
+
+NOTE:
+One current feature of GitLab that still requires a shared directory (NFS) is
+[GitLab Pages](../../user/project/pages/index.md).
+There is [work in progress](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/196)
+to eliminate the need for NFS to support GitLab Pages.
+
+---
+
+That concludes the configuration changes for our GitLab instance. Next, we'll create a custom AMI based on this instance to use for our launch configuration and auto scaling group.
+
+### Log in for the first time
+
+Using the domain name you used when setting up [DNS for the load balancer](#configure-dns-for-load-balancer), you should now be able to visit GitLab in your browser.
+If you didn't change the password by any other means, the default password will be the same as the instance ID. To change the default password, login as the `root` user
+with the default password and [change it in the user profile](../../user/profile#change-your-password).
+
+When our [auto scaling group](#create-an-auto-scaling-group) spins up new instances, we'll be able to log in with username `root` and the newly created password.
+
+### Create custom AMI
+
+On the EC2 dashboard:
+
+1. Select the `GitLab` instance we [created earlier](#install-gitlab).
+1. Click on **Actions**, scroll down to **Image** and click **Create Image**.
+1. Give your image a name and description (we'll use `GitLab-Source` for both).
+1. Leave everything else as default and click **Create Image**
+
+Now we have a custom AMI that we'll use to create our launch configuration the next step.
+
+## Deploy GitLab inside an auto scaling group
+
+### Create a launch configuration
+
+From the EC2 dashboard:
+
+1. Select **Launch Configurations** from the left menu and click **Create launch configuration**.
+1. Select **My AMIs** from the left menu and select the `GitLab` custom AMI we created above.
+1. Select an instance type best suited for your needs (at least a `c5.xlarge`) and click **Configure details**.
+1. Enter a name for your launch configuration (we'll use `gitlab-ha-launch-config`).
+1. **Do not** check **Request Spot Instance**.
+1. From the **IAM Role** dropdown, pick the `GitLabAdmin` instance role we [created earlier](#create-an-iam-ec2-instance-role-and-profile).
+1. Leave the rest as defaults and click **Add Storage**.
+1. The root volume is 8GiB by default and should be enough given that we won't store any data there. Click **Configure Security Group**.
+1. Check **Select and existing security group** and select the `gitlab-loadbalancer-sec-group` we created earlier.
+1. Click **Review**, review your changes, and click **Create launch configuration**.
+1. Acknowledge that you have access to the private key or create a new one. Click **Create launch configuration**.
+
+### Create an auto scaling group
+
+1. As soon as the launch configuration is created, you'll see an option to **Create an Auto Scaling group using this launch configuration**. Click that to start creating the auto scaling group.
+1. Enter a **Group name** (we'll use `gitlab-auto-scaling-group`).
+1. For **Group size**, enter the number of instances you want to start with (we'll enter `2`).
+1. Select the `gitlab-vpc` from the **Network** dropdown.
+1. Add both the private [subnets we created earlier](#subnets).
+1. Expand the **Advanced Details** section and check the **Receive traffic from one or more load balancers** option.
+1. From the **Classic Load Balancers** dropdown, select the load balancer we created earlier.
+1. For **Health Check Type**, select **ELB**.
+1. We'll leave our **Health Check Grace Period** as the default `300` seconds. Click **Configure scaling policies**.
+1. Check **Use scaling policies to adjust the capacity of this group**.
+1. For this group we'll scale between 2 and 4 instances where one instance will be added if CPU
+utilization is greater than 60% and one instance is removed if it falls
+to less than 45%.
+
+![Auto scaling group policies](img/policies.png)
+
+1. Finally, configure notifications and tags as you see fit, review your changes, and create the
+auto scaling group.
+
+As the auto scaling group is created, you'll see your new instances spinning up in your EC2 dashboard. You'll also see the new instances added to your load balancer. Once the instances pass the heath check, they are ready to start receiving traffic from the load balancer.
+
+Since our instances are created by the auto scaling group, go back to your instances and terminate the [instance we created manually above](#install-gitlab). We only needed this instance to create our custom AMI.
+
+## Health check and monitoring with Prometheus
+
+Apart from Amazon's Cloudwatch which you can enable on various services,
+GitLab provides its own integrated monitoring solution based on Prometheus.
+For more information on how to set it up, visit the
+[GitLab Prometheus documentation](../../administration/monitoring/prometheus/index.md)
+
+GitLab also has various [health check endpoints](../../user/admin_area/monitoring/health_check.md)
+that you can ping and get reports.
+
+## GitLab Runner
+
+If you want to take advantage of [GitLab CI/CD](../../ci/index.md), you have to
+set up at least one [runner](https://docs.gitlab.com/runner/).
+
+Read more on configuring an
+[autoscaling GitLab Runner on AWS](https://docs.gitlab.com/runner/configuration/runner_autoscale_aws/).
+
+## Backup and restore
+
+GitLab provides [a tool to back up](../../raketasks/backup_restore.md#back-up-gitlab)
+and restore its Git data, database, attachments, LFS objects, and so on.
+
+Some important things to know:
+
+- The backup/restore tool **does not** store some configuration files, like secrets; you'll
+ need to [configure this yourself](../../raketasks/backup_restore.md#storing-configuration-files).
+- By default, the backup files are stored locally, but you can
+ [backup GitLab using S3](../../raketasks/backup_restore.md#using-amazon-s3).
+- You can [exclude specific directories form the backup](../../raketasks/backup_restore.md#excluding-specific-directories-from-the-backup).
+
+### Backing up GitLab
+
+To back up GitLab:
+
+1. SSH into your instance.
+1. Take a backup:
+
+ ```shell
+ sudo gitlab-backup create
+ ```
+
+NOTE:
+For GitLab 12.1 and earlier, use `gitlab-rake gitlab:backup:create`.
+
+### Restoring GitLab from a backup
+
+To restore GitLab, first review the [restore documentation](../../raketasks/backup_restore.md#restore-gitlab),
+and primarily the restore prerequisites. Then, follow the steps under the
+[Omnibus installations section](../../raketasks/backup_restore.md#restore-for-omnibus-gitlab-installations).
+
+## Updating GitLab
+
+GitLab releases a new version every month on the 22nd. Whenever a new version is
+released, you can update your GitLab instance:
+
+1. SSH into your instance
+1. Take a backup:
+
+ ```shell
+ sudo gitlab-backup create
+ ```
+
+NOTE:
+For GitLab 12.1 and earlier, use `gitlab-rake gitlab:backup:create`.
+
+1. Update the repositories and install GitLab:
+
+ ```shell
+ sudo apt update
+ sudo apt install gitlab-ee
+ ```
+
+After a few minutes, the new version should be up and running.
+
+## Find official GitLab-created AMI IDs on AWS
+
+To find the AMIs generated by GitLab:
+
+1. Login to AWS Web Console, so that clicking the links below will take you directly to the AMI list.
+1. Pick the edition you want:
+
+ - [GitLab Enterprise Edition](https://console.aws.amazon.com/ec2/v2/home?region=us-east-1#Images:visibility=public-images;ownerAlias=782774275127;search=GitLab%20EE;sort=desc:name): If you want to unlock the enterprise features, a license is needed. Recommended for this guide.
+ - [GitLab Community Edition](https://console.aws.amazon.com/ec2/v2/home?region=us-east-1#Images:visibility=public-images;ownerAlias=782774275127;search=GitLab%20CE;sort=desc:name): The open source version of GitLab.
+ - [GitLab Premium or Ultimate Marketplace (Prelicensed)](https://console.aws.amazon.com/ec2/v2/home?region=us-east-1#Images:visibility=public-images;source=Marketplace;search=GitLab%20EE;sort=desc:name): 5 user license built into per-minute billing.
+1. AMI IDs are unique per region, so once you've loaded one of the above, select the desired target region in the upper right of the console to see the appropriate AMIs.
+1. Once the console is loaded, you can add additional search criteria to narrow further. For instance, `13.` to find only 13.x versions.
+1. To launch an EC2 Machine with one of the listed AMIs, check the box at the start of the relevant row, and select the "Launch" button near the top of left of the page.
+
+NOTE:
+If you are trying to restore from an older version of GitLab while moving to AWS, find the
+[Enterprise and Community Editions Before 11.10.3](https://console.aws.amazon.com/ec2/v2/home?region=us-east-1#Images:visibility=public-images;ownerAlias=855262394183;sort=desc:name).
+
+## Conclusion
+
+In this guide, we went mostly through scaling and some redundancy options,
+your mileage may vary.
+
+Keep in mind that all solutions come with a trade-off between
+cost/complexity and uptime. The more uptime you want, the more complex the solution.
+And the more complex the solution, the more work is involved in setting up and
+maintaining it.
+
+Have a read through these other resources and feel free to
+[open an issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new)
+to request additional material:
+
+- [Scaling GitLab](../../administration/reference_architectures/index.md):
+ GitLab supports several different types of clustering.
+- [Geo replication](../../administration/geo/index.md):
+ Geo is the solution for widely distributed development teams.
+- [Omnibus GitLab](https://docs.gitlab.com/omnibus/) - Everything you need to know
+ about administering your GitLab instance.
+- [Upload a license](../../user/admin_area/license.md):
+ Activate all GitLab Enterprise Edition functionality with a license.
+- [Pricing](https://about.gitlab.com/pricing/): Pricing for the different tiers.
+
+## Troubleshooting
+
+### Instances are failing health checks
+
+If your instances are failing the load balancer's health checks, verify that they are returning a status `200` from the health check endpoint we configured earlier. Any other status, including redirects (e.g. status `302`) will cause the health check to fail.
+
+You may have to set a password on the `root` user to prevent automatic redirects on the sign-in endpoint before health checks will pass.
+
+### "The change you requested was rejected (422)"
+
+If you see this page when trying to set a password via the web interface, make sure `external_url` in `gitlab.rb` matches the domain you are making a request from, and run `sudo gitlab-ctl reconfigure` after making any changes to it.
+
+### Some job logs are not uploaded to object storage
+
+When the GitLab deployment is scaled up to more than one node, some job logs may not be uploaded to [object storage](../../administration/object_storage.md) properly. [Incremental logging is required](../../administration/object_storage.md#other-alternatives-to-file-system-storage) for CI to use object storage.
+
+Enable [incremental logging](../../administration/job_logs.md#enable-or-disable-incremental-logging) if it has not already been enabled.
diff --git a/doc/install/azure/index.md b/doc/install/azure/index.md
index 38d423fbcdf..50cbb9fb3b6 100644
--- a/doc/install/azure/index.md
+++ b/doc/install/azure/index.md
@@ -248,7 +248,7 @@ in this section whenever you need to update GitLab.
To determine the version of GitLab you're currently running:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Dashboard**.
1. Find the version under the **Components** table.
diff --git a/doc/install/docker.md b/doc/install/docker.md
index 7be97a1f2e6..b611f87938e 100644
--- a/doc/install/docker.md
+++ b/doc/install/docker.md
@@ -4,7 +4,7 @@ group: Distribution
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
---
-# GitLab Docker images
+# GitLab Docker images **(FREE SELF)**
The GitLab Docker images are monolithic images of GitLab running all the
necessary services in a single container. If you instead want to install GitLab
@@ -368,7 +368,7 @@ You can then access your GitLab instance at `http://198.51.100.1/` and `https://
### Expose GitLab on different ports
-GitLab will occupy [some ports](https://docs.gitlab.com/omnibus/package-information/defaults.html)
+GitLab will occupy [some ports](../administration/package_information/defaults.md)
inside the container.
If you want to use a different host port than `80` (HTTP) or `443` (HTTPS),
@@ -621,7 +621,7 @@ variety of statistics on the health and performance of GitLab. The files
required for this gets written to a temporary file system (like `/run` or
`/dev/shm`).
-By default, Docker allocates 64Mb to the shared memory directory (mounted at
+By default, Docker allocates 64MB to the shared memory directory (mounted at
`/dev/shm`). This is insufficient to hold all the Prometheus metrics related
files generated, and will generate error logs like the following:
@@ -636,7 +636,7 @@ writing value to /dev/shm/gitlab/sidekiq/histogram_sidekiq_0-0.db failed with un
```
Other than disabling the Prometheus Metrics from the Admin page, the recommended
-solution to fix this problem is to increase the size of shm to at least 256Mb.
+solution to fix this problem is to increase the size of shared memory to at least 256MB.
If using `docker run`, this can be done by passing the flag `--shm-size 256m`.
If using a `docker-compose.yml` file, the `shm_size` key can be used for this
purpose.
diff --git a/doc/install/installation.md b/doc/install/installation.md
index a0587c6ef8a..b524177abc4 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -231,9 +231,9 @@ Download Ruby and compile it:
```shell
mkdir /tmp/ruby && cd /tmp/ruby
-curl --remote-name --progress-bar "https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.2.tar.gz"
-echo 'cb9731a17487e0ad84037490a6baf8bfa31a09e8 ruby-2.7.2.tar.gz' | shasum -c - && tar xzf ruby-2.7.2.tar.gz
-cd ruby-2.7.2
+curl --remote-name --progress-bar "https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.4.tar.gz"
+echo '3043099089608859fc8cce7f9fdccaa1f53a462457e3838ec3b25a7d609fbc5b ruby-2.7.4.tar.gz' | sha256sum -c - && tar xzf ruby-2.7.4.tar.gz
+cd ruby-2.7.4
./configure --disable-install-rdoc --enable-shared
make
diff --git a/doc/install/next_steps.md b/doc/install/next_steps.md
index f271caef493..e25241f0378 100644
--- a/doc/install/next_steps.md
+++ b/doc/install/next_steps.md
@@ -4,7 +4,7 @@ group: Distribution
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
---
-# Steps after installing GitLab
+# Steps after installing GitLab **(FREE SELF)**
Here are a few resources you might want to check out after completing the
installation.
diff --git a/doc/install/requirements.md b/doc/install/requirements.md
index ba515de417f..641b092e1e3 100644
--- a/doc/install/requirements.md
+++ b/doc/install/requirements.md
@@ -36,7 +36,7 @@ For the installation options, see [the main installation page](index.md).
Installation of GitLab on these operating systems is possible, but not supported.
Please see the [installation from source guide](installation.md) and the [installation guides](https://about.gitlab.com/install/) for more information.
-Please see [OS versions that are no longer supported](https://docs.gitlab.com/omnibus/package-information/deprecated_os.html) for Omnibus installs page
+Please see [OS versions that are no longer supported](../administration/package_information/deprecated_os.md) for Omnibus installs page
for a list of supported and unsupported OS versions as well as the last support GitLab version for that OS.
### Microsoft Windows
@@ -60,6 +60,8 @@ Redis version 6.0 or higher is recommended, as this is what ships with
The necessary hard drive space largely depends on the size of the repositories you want to store in GitLab but as a *rule of thumb* you should have at least as much free space as all your repositories combined take up.
+The Omnibus GitLab package requires about 2.5 GB of storage space for installation.
+
If you want to be flexible about growing your hard drive space in the future consider mounting it using [logical volume management (LVM)](https://en.wikipedia.org/wiki/Logical_volume_management) so you can add more hard drives when you need them.
Apart from a local hard drive you can also mount a volume that supports the network file system (NFS) protocol. This volume might be located on a file server, a network attached storage (NAS) device, a storage area network (SAN) or on an Amazon Web Services (AWS) Elastic Block Store (EBS) volume.
@@ -197,7 +199,7 @@ Take for example the following scenarios:
```plaintext
The highest number from
2
- And
+ And
[
the lowest number from
- number of cores: 2
@@ -212,11 +214,11 @@ Take for example the following scenarios:
```plaintext
The highest number from
2
- And
+ And
[
the lowest number from
- number of cores: 4
- - memory limit: (4 - 1.5) = 2.5
+ - memory limit: (4 - 1.5) = 2.5
]
```
@@ -227,7 +229,7 @@ Take for example the following scenarios:
```plaintext
The highest number from
2
- And
+ And
[
the lowest number from
- number of cores: 4
@@ -254,6 +256,12 @@ of [legacy Rugged code](../administration/gitaly/index.md#direct-access-to-git-i
higher, due to how [Ruby MRI multi-threading](https://en.wikipedia.org/wiki/Global_interpreter_lock)
works.
+### Puma per worker maximum memory
+
+By default, each Puma worker will be limited to 1024 MB of memory.
+This setting [can be adjusted](../administration/operations/puma.md#puma-worker-killer) and should be considered
+if you need to increase the number of Puma workers.
+
## Redis and Sidekiq
Redis stores all user sessions and the background task queue.
@@ -321,7 +329,7 @@ For the listed web browsers, GitLab supports:
NOTE:
We don't support running GitLab with JavaScript disabled in the browser and have no plans of supporting that
-in the future because we have features such as Issue Boards which require JavaScript extensively.
+in the future because we have features such as issue boards which require JavaScript extensively.
<!-- ## Troubleshooting
diff --git a/doc/integration/akismet.md b/doc/integration/akismet.md
index a652025387e..efc293569fe 100644
--- a/doc/integration/akismet.md
+++ b/doc/integration/akismet.md
@@ -30,8 +30,8 @@ To use Akismet:
1. Sign in or create a new account.
1. Click **Show** to reveal the API key, and copy the API key's value.
1. Sign in to GitLab as an administrator.
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > Reporting** (`/admin/application_settings/reporting`).
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Reporting** (`/admin/application_settings/reporting`).
1. Select the **Enable Akismet** checkbox.
1. Fill in the API key from step 3.
1. Save the configuration.
diff --git a/doc/integration/auth0.md b/doc/integration/auth0.md
index 34ee326d6d5..870da6cdb3d 100644
--- a/doc/integration/auth0.md
+++ b/doc/integration/auth0.md
@@ -9,8 +9,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
To enable the Auth0 OmniAuth provider, you must create an Auth0 account, and an
application.
-1. Sign in to the [Auth0 Console](https://auth0.com/auth/login). If you need to
- create an account, you can do so at the same link.
+1. Sign in to the [Auth0 Console](https://auth0.com/auth/login). You can also
+ create an account using the same link.
1. Select **New App/API**.
diff --git a/doc/integration/azure.md b/doc/integration/azure.md
index dceb135ad89..47d80ab9a66 100644
--- a/doc/integration/azure.md
+++ b/doc/integration/azure.md
@@ -4,17 +4,19 @@ group: Integrations
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
---
-# Microsoft Azure OAuth2 OmniAuth Provider **(FREE)**
+# Microsoft Azure OAuth 2.0 OmniAuth Provider **(FREE)**
NOTE:
Per Microsoft, this provider uses the [older Azure Active Directory v1.0 endpoint](https://docs.microsoft.com/en-us/azure/active-directory/azuread-dev/v1-protocols-oauth-code).
Microsoft documentation suggests that you should use the [OpenID Connect protocol to use the v2 endpoints](../administration/auth/oidc.md#microsoft-azure) for new projects.
-To use v2 endpoints via OmniAuth, please follow [Microsoft Azure OAuth2 OmniAuth Provider v2 instructions](#microsoft-azure-oauth2-omniauth-provider-v2).
+To use v2 endpoints via OmniAuth, please follow [Microsoft Azure OAuth 2.0 OmniAuth Provider v2 instructions](#microsoft-azure-oauth-20-omniauth-provider-v2).
-To enable the Microsoft Azure OAuth2 OmniAuth provider, you must register your application with Azure. Azure generates a client ID and secret key for you to use.
+To enable the Microsoft Azure OAuth 2.0 OmniAuth provider, you must register
+your application with Azure. Azure generates a client ID and secret key for you
+to use.
-Sign in to the [Azure Portal](https://portal.azure.com), and follow the instructions in
-the [Microsoft Quickstart documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app).
+Sign in to the [Azure Portal](https://portal.azure.com), and follow the
+instructions in the [Microsoft Quickstart documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app).
As you go through the Microsoft procedure, keep the following in mind:
@@ -23,9 +25,9 @@ As you go through the Microsoft procedure, keep the following in mind:
- The redirect URI requires the URL of the Azure OAuth callback of your GitLab
installation. For example, `https://gitlab.mycompany.com/users/auth/azure_oauth2/callback`.
The type dropdown should be set to **Web**.
-- The `client ID` and `client secret` are terms associated with OAuth 2. In some Microsoft documentation,
+- The `client ID` and `client secret` are terms associated with OAuth 2.0. In some Microsoft documentation,
the terms may be listed as `Application ID` and `Application Secret`.
-- If you need to generate a new client secret, follow the Microsoft documentation
+- If you have to generate a new client secret, follow the Microsoft documentation
for [creating a new application secret](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal#create-a-new-application-secret).
- Save the client ID and client secret for your new app, as the client secret is only
displayed one time.
@@ -89,41 +91,46 @@ As you go through the Microsoft procedure, keep the following in mind:
- *If you installed from source,*
[restart GitLab](../administration/restart_gitlab.md#installations-from-source).
-On the sign-in page, you should now see a Microsoft icon below the regular sign-in form.
-Click the icon to begin the authentication process. Microsoft then asks you to
-sign in and authorize the GitLab application. If successful, you are returned to GitLab and signed in.
+On the sign-in page, you should now see a Microsoft icon below the regular
+sign-in form. Click the icon to begin the authentication process. Microsoft then
+asks you to sign in and authorize the GitLab application. If successful, you are
+returned to GitLab and signed in.
Read [Enable OmniAuth for an Existing User](omniauth.md#enable-omniauth-for-an-existing-user)
for information on how existing GitLab users can connect to their newly-available Azure AD accounts.
-## Microsoft Azure OAuth2 OmniAuth Provider v2
+## Microsoft Azure OAuth 2.0 OmniAuth Provider v2
-In order to use v2 endpoints provided by Microsoft Azure Active Directory you must to configure it via Azure OAuth2 OmniAuth Provider v2.
+To use v2 endpoints provided by Microsoft Azure Active Directory you must to
+configure it via Azure OAuth 2.0 OmniAuth Provider v2.
### Registering an Azure application
-To enable the Microsoft Azure OAuth2 OmniAuth provider, you must register your application with Azure. Azure generates a client ID and secret key for you to use.
+To enable the Microsoft Azure OAuth 2.0 OmniAuth provider, you must register
+your application with Azure. Azure generates a client ID and secret key for you
+to use.
-Sign in to the [Azure Portal](https://portal.azure.com), and follow the instructions in
-the [Microsoft Quickstart documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app).
+Sign in to the [Azure Portal](https://portal.azure.com), and follow the
+instructions in the [Microsoft Quickstart documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app).
As you go through the Microsoft procedure, keep the following in mind:
-- If you have multiple instances of Azure Active Directory, you can switch to the desired tenant.
+- If you have multiple instances of Azure Active Directory, you can switch to
+ the desired tenant.
- You're setting up a Web application.
- The redirect URI requires the URL of the Azure OAuth callback of your GitLab
installation. For example, `https://gitlab.example.com/users/auth/azure_activedirectory_v2/callback`.
The type dropdown should be set to **Web**.
-- The `client ID` and `client secret` are terms associated with OAuth 2. In some Microsoft documentation,
+- The `client ID` and `client secret` are terms associated with OAuth 2.0. In some Microsoft documentation,
the terms may be listed as `Application ID` and `Application Secret`.
-- If you need to generate a new client secret, follow the Microsoft documentation
+- If you have to generate a new client secret, follow the Microsoft documentation
for [creating a new application secret](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal#create-a-new-application-secret).
- Save the client ID and client secret for your new app, as the client secret is only
displayed one time.
### Adding API permissions (scopes)
-Once you have created an application, follow the [Microsoft Quickstart documentation to expose a web API](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-expose-web-apis). Be sure to add the following delegated permissions under the Microsoft Graph API:
+After you have created an application, follow the [Microsoft Quickstart documentation to expose a web API](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-expose-web-apis). Be sure to add the following delegated permissions under the Microsoft Graph API:
- `email`
- `openid`
@@ -181,7 +188,8 @@ Once you have created an application, follow the [Microsoft Quickstart documenta
The `scope` parameter is optional and can be added to `args`. Default `scope` is: `openid profile email`.
-1. Replace `CLIENT ID`, `CLIENT SECRET`, and `TENANT ID` with the values you got above.
+1. Replace `CLIENT ID`, `CLIENT SECRET`, and `TENANT ID` with the values you got
+ above.
1. Save the configuration file.
diff --git a/doc/integration/bitbucket.md b/doc/integration/bitbucket.md
index 44aca1ca6b1..7a3f4a7710d 100644
--- a/doc/integration/bitbucket.md
+++ b/doc/integration/bitbucket.md
@@ -10,8 +10,8 @@ NOTE:
Starting from GitLab 11.4, OmniAuth is enabled by default. If you're using an
earlier version, you must explicitly enable it.
-You can set up Bitbucket.org as an OAuth2 provider to use your
-Bitbucket.org account credentials to sign in to GitLab, or import your projects from
+You can set up Bitbucket.org as an OAuth 2.0 provider to use your Bitbucket.org
+account credentials to sign in to GitLab. You can also import your projects from
Bitbucket.org.
- To use Bitbucket.org as an OmniAuth provider, follow the
diff --git a/doc/integration/cas.md b/doc/integration/cas.md
index be54c31ec01..60ce728fa55 100644
--- a/doc/integration/cas.md
+++ b/doc/integration/cas.md
@@ -6,7 +6,11 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# CAS OmniAuth Provider **(FREE)**
-To enable the CAS OmniAuth provider you must register your application with your CAS instance. This requires the service URL GitLab supplies to CAS. It should be something like: `https://gitlab.example.com:443/users/auth/cas3/callback?url`. By default handling for SLO is enabled, you only need to configure CAS for back-channel logout.
+To enable the CAS OmniAuth provider you must register your application with your
+CAS instance. This requires the service URL GitLab supplies to CAS. It should be
+something like: `https://gitlab.example.com:443/users/auth/cas3/callback?url`.
+Handling for Single Logout (SLO) is enabled by default, so you only have to
+configure CAS for back-channel logout.
1. On your GitLab server, open the configuration file.
diff --git a/doc/integration/datadog.md b/doc/integration/datadog.md
index e06cca19e60..687be5adcf7 100644
--- a/doc/integration/datadog.md
+++ b/doc/integration/datadog.md
@@ -27,8 +27,8 @@ project, group, or instance level:
1. *For project-level or group-level integrations:* In GitLab, go to your project or group.
1. *For instance-level integrations:*
1. Sign in to GitLab as a user with the [Administrator role](../user/permissions.md).
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > Integrations**.
+ 1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Integrations**.
1. Scroll to **Add an integration**, and select **Datadog**.
1. Select **Active** to enable the integration.
1. Specify the [**Datadog site**](https://docs.datadoghq.com/getting_started/site/) to send data to.
diff --git a/doc/integration/elasticsearch.md b/doc/integration/elasticsearch.md
index 20b66411a7e..9514c298885 100644
--- a/doc/integration/elasticsearch.md
+++ b/doc/integration/elasticsearch.md
@@ -9,9 +9,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> Moved to GitLab Premium in 13.9.
-This document describes how to enable Advanced Search. After
-Advanced Search is enabled, you'll have the benefit of fast search response times
-and the advantage of the [special searches](../user/search/advanced_search.md).
+This page describes how to enable Advanced Search. When enabled,
+Advanced Search provides faster search response times and [improved search features](../user/search/advanced_search.md).
## Version requirements
@@ -26,94 +25,61 @@ and the advantage of the [special searches](../user/search/advanced_search.md).
| GitLab Enterprise Edition 9.0 through 11.4 | Elasticsearch 5.1 through 5.5 |
| GitLab Enterprise Edition 8.4 through 8.17 | Elasticsearch 2.4 with [Delete By Query Plugin](https://www.elastic.co/guide/en/elasticsearch/plugins/2.4/plugins-delete-by-query.html) installed |
-The Elasticsearch Integration is designed to work with supported versions of
-Elasticsearch and follows Elasticsearch's [End of Life Policy](https://www.elastic.co/support/eol).
+The Elasticsearch Integration works with supported versions of
+Elasticsearch and follows Elasticsearch's [End of Life Policy](https://www.elastic.co/support/eol).
When we change Elasticsearch supported versions in GitLab, we announce them in [deprecation notes](https://about.gitlab.com/handbook/marketing/blog/release-posts/#deprecations) in monthly release posts
-before the actual removal.
+before we remove them.
## System requirements
-Elasticsearch requires additional resources in excess of those documented in the
+Elasticsearch requires additional resources to those documented in the
[GitLab system requirements](../install/requirements.md).
-The amount of resources (memory, CPU, storage) varies greatly, based on the
-amount of data being indexed into the Elasticsearch cluster. According to
+Memory, CPU, and storage resource amounts vary depending on the amount of data you index into the Elasticsearch cluster. Heavily used Elasticsearch clusters may require more resources. According to
[Elasticsearch official guidelines](https://www.elastic.co/guide/en/elasticsearch/guide/current/hardware.html#_memory),
each node should have:
- [Memory](https://www.elastic.co/guide/en/elasticsearch/guide/current/hardware.html#_memory): 8 GiB (minimum).
-- [CPU](https://www.elastic.co/guide/en/elasticsearch/guide/current/hardware.html#_cpus): Modern processor with multiple cores.
-- [Storage](https://www.elastic.co/guide/en/elasticsearch/guide/current/hardware.html#_disks): Use SSD storage. The total storage size of all Elasticsearch nodes is about 50% of the total size of your Git repositories. It includes one primary and one replica.
+- [CPU](https://www.elastic.co/guide/en/elasticsearch/guide/current/hardware.html#_cpus): Modern processor with multiple cores. GitLab.com has minimal CPU requirements for Elasticsearch. Multiple cores provide extra concurrency, which is more beneficial than faster CPUs.
+- [Storage](https://www.elastic.co/guide/en/elasticsearch/guide/current/hardware.html#_disks): Use SSD storage. The total storage size of all Elasticsearch nodes is about 50% of the total size of your Git repositories. It includes one primary and one replica. The [`estimate_cluster_size`](#gitlab-advanced-search-rake-tasks) Rake task ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/221177) in GitLab 13.10) uses total repository size to estimate the Advanced Search storage requirements.
-A few notes on CPU and storage:
-
-- CPU requirements for Elasticsearch tend to be minimal. There are specific
- scenarios where this isn't true, but GitLab.com isn't using Elasticsearch in
- an exceptionally CPU-heavy way. More cores are more performant than faster
- CPUs. Extra concurrency from multiple cores far outweighs a slightly
- faster clock speed in Elasticsearch.
-
-- Storage requirements for Elasticsearch are important, especially for
- indexing-heavy clusters. When possible use SSDs, whose speed is far superior
- to any spinning media for Elasticsearch. In testing, nodes that use SSD storage
- see boosts in both query and indexing performance.
-
-- We've introduced the [`estimate_cluster_size`](#gitlab-advanced-search-rake-tasks)
- Rake task to estimate the Advanced Search storage requirements in advance, which
-- The [`estimate_cluster_size`](#gitlab-advanced-search-rake-tasks) Rake task estimates the
- Advanced Search storage requirements in advance. The Rake task uses total repository size
- for the calculation. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/221177) in GitLab 13.10.
-
-Keep in mind, these are **minimum requirements** for Elasticsearch.
-Heavily-used Elasticsearch clusters likely require considerably more
-resources.
-
-## Installing Elasticsearch
+## Install Elasticsearch
Elasticsearch is *not* included in the Omnibus packages or when you install from
-source. You must [install it separately](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/install-elasticsearch.html "Elasticsearch 7.x installation documentation").
-Be sure to select your version. Providing detailed information on installing
-Elasticsearch is out of the scope of this document.
+source. You must [install it separately](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/install-elasticsearch.html "Elasticsearch 7.x installation documentation") and ensure you select your version. Detailed information on how to install Elasticsearch is out of the scope of this page.
-Elasticsearch should be installed on a separate server, whether you install
-it yourself or use a cloud hosted offering like Elastic's [Elasticsearch Service](https://www.elastic.co/elasticsearch/service)
-(available on AWS, GCP, or Azure) or the [Amazon Elasticsearch](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-gsg.html)
-service. Running Elasticsearch on the same server as GitLab is not recommended
-and can cause a degradation in GitLab instance performance.
+You can install Elasticsearch yourself, or use a cloud hosted offering such as [Elasticsearch Service](https://www.elastic.co/elasticsearch/service)(available on AWS, GCP, or Azure) or the [Amazon Elasticsearch](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-gsg.html)
+service.
+You should install Elasticsearch on a separate server. Running Elasticsearch on the same server as GitLab is not recommended and can cause a degradation in GitLab instance performance.
-**For a single node Elasticsearch cluster the functional cluster health status
-is yellow** (will never be green) because the primary shard is allocated but
-replicas can not be as there is no other node to which Elasticsearch can assign a
-replica.
+For a single node Elasticsearch cluster, the functional cluster health status is always yellow due to the allocation of the primary shard. Elasticsearch cannot assign replica shards to the same node as primary shards.
-After the data is added to the database or repository and [Elasticsearch is
-enabled in the Admin Area](#enabling-advanced-search) the search index is
-updated automatically.
+The search index updates after you:
-## Upgrading to a new Elasticsearch major version
+- Add data to the database or repository.
+- [Enable Elasticsearch](#enable-advanced-search) in the Admin Area.
-Since Elasticsearch can read and use indices created in the previous major version, you don't need to change anything in the GitLab configuration when upgrading Elasticsearch.
+## Upgrade to a new Elasticsearch major version
-The only thing worth noting is that if you have created your current index before GitLab 13.0, you might want to reindex from scratch (which implicitly creates an alias) in order to use some features, for example [Zero downtime reindexing](#zero-downtime-reindexing). Once you do that, you are able to perform zero-downtime reindexing and will benefit from any future features that make use of the alias.
+Elasticsearch reads and uses indices created in the previous major version. You are not required to change the GitLab configuration when you upgrade Elasticsearch.
-If you are unsure when your current index was created,
-you can check whether it was created after GitLab 13.0 by using the
-[Elasticsearch cat aliases API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/cat-alias.html).
-If the list of aliases returned contains an entry for `gitlab-production` that points to an index
+If your current index was created before GitLab 13.0, you must reindex from scratch to create an alias to use features such as [zero downtime reindexing](#zero-downtime-reindexing). After you reindex, you can perform zero downtime reindexing and also benefit from future features that use the alias.
+
+To check if your current index was created before GitLab 13.0, use the [Elasticsearch cat aliases API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/cat-alias.html).
+If the returned list of aliases does not contain a `gitlab-production` alias, you must reindex to use features such as zero downtime reindexing.
+If the returned list of aliases contains an entry for `gitlab-production` that points to an index
named `gitlab-production-<numerical timestamp>`, your index was created after GitLab 13.0.
-If the `gitlab-production` alias is missing, you need to reindex from scratch to use
-features such as Zero-downtime reindexing.
## Elasticsearch repository indexer
-For indexing Git repository data, GitLab uses an [indexer written in Go](https://gitlab.com/gitlab-org/gitlab-elasticsearch-indexer).
+To index Git repository data, GitLab uses an [indexer written in Go](https://gitlab.com/gitlab-org/gitlab-elasticsearch-indexer).
-The way you install the Go indexer depends on your version of GitLab:
+Depending on your GitLab version, there are different installation procedures for the Go indexer:
- For Omnibus GitLab 11.8 or greater, see [Omnibus GitLab](#omnibus-gitlab).
- For installations from source or older versions of Omnibus GitLab,
[install the indexer from source](#from-source).
-- If you are using GitLab Development Kit, see [GDK Elasticsearch how-to](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/howto/elasticsearch.md)
+- If you are using GitLab Development Kit, see [GDK Elasticsearch how-to](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/howto/elasticsearch.md).
### Omnibus GitLab
@@ -126,7 +92,7 @@ First, we need to install some dependencies, then we build and install
the indexer itself.
This project relies on [International Components for Unicode](http://site.icu-project.org/) (ICU) for text encoding,
-therefore we need to ensure the development packages for your platform are
+therefore we must ensure the development packages for your platform are
installed before running `make`.
#### Debian / Ubuntu
@@ -154,7 +120,7 @@ brew install icu4c
export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig:$PKG_CONFIG_PATH"
```
-### Building and installing
+### Build and install
To build and install the indexer, run:
@@ -166,7 +132,7 @@ sudo -u git -H bundle exec rake gitlab:indexer:install[$indexer_path] RAILS_ENV=
cd $indexer_path && sudo make install
```
-The `gitlab-elasticsearch-indexer` will be installed to `/usr/local/bin`.
+The `gitlab-elasticsearch-indexer` is installed to `/usr/local/bin`.
You can change the installation path with the `PREFIX` environment variable.
Please remember to pass the `-E` flag to `sudo` if you do so.
@@ -177,21 +143,21 @@ Example:
PREFIX=/usr sudo -E make install
```
-After installation, be sure to [enable Elasticsearch](#enabling-advanced-search).
+After installation, be sure to [enable Elasticsearch](#enable-advanced-search).
NOTE:
If you see an error such as `Permission denied - /home/git/gitlab-elasticsearch-indexer/` while indexing, you
may need to set the `production -> elasticsearch -> indexer_path` setting in your `gitlab.yml` file to
`/usr/local/bin/gitlab-elasticsearch-indexer`, which is where the binary is installed.
-## Enabling Advanced Search
+## Enable Advanced Search
For GitLab instances with more than 50GB repository data you can follow the instructions for [Indexing large
instances](#indexing-large-instances) below.
-To enable Advanced Search, you need to have admin access to GitLab:
+To enable Advanced Search, you must have admin access to GitLab:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Advanced Search**.
NOTE:
@@ -206,7 +172,7 @@ To enable Advanced Search, you need to have admin access to GitLab:
1. Select **Index all projects**.
1. Select **Check progress** in the confirmation message to see the status of
the background jobs.
-1. Personal snippets need to be indexed using another Rake task:
+1. Personal snippets must be indexed using another Rake task:
```shell
# Omnibus installations
@@ -216,7 +182,7 @@ To enable Advanced Search, you need to have admin access to GitLab:
bundle exec rake gitlab:elastic:index_snippets RAILS_ENV=production
```
-1. After the indexing has completed, enable **Search with Elasticsearch enabled** and select **Save changes**.
+1. After indexing completes, enable **Search with Elasticsearch enabled** and select **Save changes**.
NOTE:
When your Elasticsearch cluster is down while Elasticsearch is enabled,
@@ -237,8 +203,8 @@ The following Elasticsearch settings are available:
| `Username` | The `username` of your Elasticsearch instance. |
| `Password` | The password of your Elasticsearch instance. |
| `Number of Elasticsearch shards` | Elasticsearch indexes are split into multiple shards for performance reasons. In general, you should use at least 5 shards, and indexes with tens of millions of documents need to have more shards ([see below](#guidance-on-choosing-optimal-cluster-configuration)). Changes to this value do not take effect until the index is recreated. You can read more about tradeoffs in the [Elasticsearch documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/scalability.html). |
-| `Number of Elasticsearch replicas` | Each Elasticsearch shard can have a number of replicas. These are a complete copy of the shard, and can provide increased query performance or resilience against hardware failure. Increasing this value will greatly increase total disk space required by the index. |
-| `Limit namespaces and projects that can be indexed` | Enabling this will allow you to select namespaces and projects to index. All other namespaces and projects will use database search instead. If you enable this option but do not select any namespaces or projects, none will be indexed. [Read more below](#limiting-namespaces-and-projects).
+| `Number of Elasticsearch replicas` | Each Elasticsearch shard can have a number of replicas. These are a complete copy of the shard, and can provide increased query performance or resilience against hardware failure. Increasing this value increases total disk space required by the index. |
+| `Limit namespaces and projects that can be indexed` | Enabling this allows you to select namespaces and projects to index. All other namespaces and projects use database search instead. If you enable this option but do not select any namespaces or projects, none will be indexed. [Read more below](#limit-namespaces-and-projects).
| `Using AWS hosted Elasticsearch with IAM credentials` | Sign your Elasticsearch requests using [AWS IAM authorization](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html), [AWS EC2 Instance Profile Credentials](https://docs.aws.amazon.com/codedeploy/latest/userguide/getting-started-create-iam-instance-profile.html#getting-started-create-iam-instance-profile-cli), or [AWS ECS Tasks Credentials](https://docs.aws.amazon.com/AmazonECS/latest/userguide/task-iam-roles.html). Please refer to [Identity and Access Management in Amazon Elasticsearch Service](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-ac.html) for details of AWS hosted Elasticsearch domain access policy configuration. |
| `AWS Region` | The AWS region in which your Elasticsearch service is located. |
| `AWS Access Key` | The AWS access key. |
@@ -255,38 +221,38 @@ Sidekiq performance. Return them to their default values if you see increased `s
in your Sidekiq logs. For more information, see
[issue 322147](https://gitlab.com/gitlab-org/gitlab/-/issues/322147).
-### Limiting namespaces and projects
+### Limit namespaces and projects
-If you select `Limit namespaces and projects that can be indexed`, more options will become available.
+If you select `Limit namespaces and projects that can be indexed`, more options become available.
![limit namespaces and projects options](img/limit_namespaces_projects_options.png)
-You can select namespaces and projects to index exclusively. Note that if the namespace is a group it will include
+You can select namespaces and projects to index exclusively. Note that if the namespace is a group, it includes
any subgroups and projects belonging to those subgroups to be indexed as well.
-Advanced Search only provides cross-group code/commit search (global) if all name-spaces are indexed. In this particular scenario where only a subset of namespaces are indexed, a global search will not provide a code or commit scope. This will be possible only in the scope of an indexed namespace. Currently there is no way to code/commit search in multiple indexed namespaces (when only a subset of namespaces has been indexed). For example if two groups are indexed, there is no way to run a single code search on both. You can only run a code search on the first group and then on the second.
+Advanced Search only provides cross-group code/commit search (global) if all name-spaces are indexed. In this particular scenario where only a subset of namespaces are indexed, a global search will not provide a code or commit scope. This is possible only in the scope of an indexed namespace. There is no way to code/commit search in multiple indexed namespaces (when only a subset of namespaces has been indexed). For example if two groups are indexed, there is no way to run a single code search on both. You can only run a code search on the first group and then on the second.
You can filter the selection dropdown by writing part of the namespace or project name you're interested in.
![limit namespace filter](img/limit_namespace_filter.png)
NOTE:
-If no namespaces or projects are selected, no Advanced Search indexing will take place.
+If no namespaces or projects are selected, no Advanced Search indexing takes place.
WARNING:
-If you have already indexed your instance, you will have to regenerate the index in order to delete all existing data
-for filtering to work correctly. To do this run the Rake tasks `gitlab:elastic:recreate_index` and
-`gitlab:elastic:clear_index_status`. Afterwards, removing a namespace or a project from the list will delete the data
+If you have already indexed your instance, you must regenerate the index to delete all existing data
+for filtering to work correctly. To do this, run the Rake tasks `gitlab:elastic:recreate_index` and
+`gitlab:elastic:clear_index_status`. Afterwards, removing a namespace or a project from the list deletes the data
from the Elasticsearch index as expected.
-## Enabling custom language analyzers
+## Enable custom language analyzers
You can improve the language support for Chinese and Japanese languages by utilizing [`smartcn`](https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-smartcn.html) and/or [`kuromoji`](https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-kuromoji.html) analysis plugins from Elastic.
To enable language(s) support:
1. Install the desired plugin(s), please refer to [Elasticsearch documentation](https://www.elastic.co/guide/en/elasticsearch/plugins/7.9/installation.html) for plugins installation instructions. The plugin(s) must be installed on every node in the cluster, and each node must be restarted after installation. For a list of plugins, see the table later in this section.
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Advanced Search**.
1. Locate **Custom analyzers: language support**.
1. Enable plugin(s) support for **Indexing**.
@@ -303,11 +269,11 @@ For guidance on what to install, see the following Elasticsearch language plugin
| `Enable Japanese (kuromoji) custom analyzer: Indexing` | Enables or disables Japanese language support using [`kuromoji`](https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-kuromoji.html) custom analyzer for newly created indices.|
| `Enable Japanese (kuromoji) custom analyzer: Search` | Enables or disables using [`kuromoji`](https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-kuromoji.html) fields for Advanced Search. Please only enable this after [installing the plugin](https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-kuromoji.html), enabling custom analyzer indexing and recreating the index.|
-## Disabling Advanced Search
+## Disable Advanced Search
To disable the Elasticsearch integration:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Advanced Search**.
1. Uncheck **Elasticsearch indexing** and **Search with Elasticsearch enabled**.
1. Click **Save changes** for the changes to take effect.
@@ -327,7 +293,7 @@ The idea behind this reindexing method is to leverage the [Elasticsearch reindex
and Elasticsearch index alias feature to perform the operation. We set up an index alias which connects to a
`primary` index which is used by GitLab for reads/writes. When reindexing process starts, we temporarily pause
the writes to the `primary` index. Then, we create another index and invoke the Reindex API which migrates the
-index data onto the new index. Once the reindexing job is complete, we switch to the new index by connecting the
+index data onto the new index. After the reindexing job is complete, we switch to the new index by connecting the
index alias to it which becomes the new `primary` index. At the end, we resume the writes and normal operation resumes.
### Trigger the reindex via the Advanced Search administration
@@ -339,7 +305,7 @@ index alias to it which becomes the new `primary` index. At the end, we resume t
To trigger the reindexing process:
1. Sign in to your GitLab instance as an administrator.
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Advanced Search**.
1. Expand **Elasticsearch zero-downtime reindexing**.
1. Select **Trigger cluster reindexing**.
@@ -350,13 +316,13 @@ After this process is completed, the original index is scheduled to be deleted a
14 days. You can cancel this action by pressing the **Cancel** button on the same
page you triggered the reindexing process.
-While the reindexing is running, you will be able to follow its progress under that same section.
+While the reindexing is running, you can follow its progress under that same section.
#### Elasticsearch zero-downtime reindexing
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55681) in GitLab 13.12.
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Advanced Search**.
1. Expand **Elasticsearch zero-downtime reindexing**, and you'll
find the following options:
@@ -404,7 +370,7 @@ Sometimes, you might want to abandon the unfinished reindex job and resume the i
bundle exec rake gitlab:elastic:mark_reindex_failed RAILS_ENV=production
```
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Advanced Search**.
1. Expand **Elasticsearch zero-downtime reindexing**.
1. Clear the **Pause Elasticsearch indexing** checkbox.
@@ -486,8 +452,8 @@ version](../update/index.md#upgrading-to-a-new-major-version).
Rake tasks are available to:
-- [Build and install](#building-and-installing) the indexer.
-- Delete indexes when [disabling Elasticsearch](#disabling-advanced-search).
+- [Build and install](#build-and-install) the indexer.
+- Delete indexes when [disabling Elasticsearch](#disable-advanced-search).
- Add GitLab data to an index.
The following are some available Rake tasks:
@@ -558,7 +524,7 @@ For basic guidance on choosing a cluster configuration you may refer to [Elastic
- A good guideline is to ensure you keep the number of shards per node below 20 per GB heap it has configured. A node with a 30GB heap should therefore have a maximum of 600 shards, but the further below this limit you can keep it the better. This will generally help the cluster stay in good health.
- Number of Elasticsearch shards:
- Small shards result in small segments, which increases overhead. Aim to keep the average shard size between at least a few GB and a few tens of GB.
- - Another consideration is the number of documents. To determine the number of shards to use, sum the numbers in the **Menu >** **{admin}** **Admin > Dashboard > Statistics** pane (the number of documents to be indexed), divide by 5 million, and add 5. For example:
+ - Another consideration is the number of documents. To determine the number of shards to use, sum the numbers in the **Menu > Admin > Dashboard > Statistics** pane (the number of documents to be indexed), divide by 5 million, and add 5. For example:
- If you have fewer than about 2,000,000 documents, use the default of 5 shards
- 10,000,000 documents: `10000000/5000000 + 5` = 7 shards
- 100,000,000 documents: `100000000/5000000 + 5` = 25 shards
@@ -573,7 +539,7 @@ For basic guidance on choosing a cluster configuration you may refer to [Elastic
### Indexing large instances
This section may be helpful in the event that the other
-[basic instructions](#enabling-advanced-search) cause problems
+[basic instructions](#enable-advanced-search) cause problems
due to large volumes of data being indexed.
WARNING:
@@ -582,7 +548,7 @@ Make sure to prepare for this task by having a [Scalable and Highly Available
Setup](../administration/reference_architectures/index.md) or creating [extra
Sidekiq processes](../administration/operations/extra_sidekiq_processes.md).
-1. [Configure your Elasticsearch host and port](#enabling-advanced-search).
+1. [Configure your Elasticsearch host and port](#enable-advanced-search).
1. Create empty indexes:
```shell
@@ -603,7 +569,7 @@ Sidekiq processes](../administration/operations/extra_sidekiq_processes.md).
bundle exec rake gitlab:elastic:clear_index_status RAILS_ENV=production
```
-1. [Enable **Elasticsearch indexing**](#enabling-advanced-search).
+1. [Enable **Elasticsearch indexing**](#enable-advanced-search).
1. Indexing large Git repositories can take a while. To speed up the process, you can [tune for indexing speed](https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-indexing-speed.html#tune-for-indexing-speed):
- You can temporarily disable [`refresh`](https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-refresh.html), the operation responsible for making changes to an index available to search.
@@ -635,7 +601,7 @@ Sidekiq processes](../administration/operations/extra_sidekiq_processes.md).
```
This enqueues a Sidekiq job for each project that needs to be indexed.
- You can view the jobs in **Menu >** **{admin}** **Admin > Monitoring > Background Jobs > Queues Tab**
+ You can view the jobs in **Menu > Admin > Monitoring > Background Jobs > Queues Tab**
and click `elastic_commit_indexer`, or you can query indexing status using a Rake task:
```shell
@@ -734,7 +700,7 @@ Sidekiq processes](../administration/operations/extra_sidekiq_processes.md).
} }'
```
-1. After the indexing has completed, enable [**Search with Elasticsearch enabled**](#enabling-advanced-search).
+1. After the indexing has completed, enable [**Search with Elasticsearch enabled**](#enable-advanced-search).
### Deleted documents
@@ -836,7 +802,7 @@ be necessary for you to [reindex](#zero-downtime-reindexing) after updating GitL
### I indexed all the repositories but I can't get any hits for my search term in the UI
-Make sure you indexed all the database data [as stated above](#enabling-advanced-search).
+Make sure you indexed all the database data [as stated above](#enable-advanced-search).
If there aren't any results (hits) in the UI search, check if you are seeing the same results via the rails console (`sudo gitlab-rails console`):
@@ -857,7 +823,7 @@ More [complex Elasticsearch API calls](https://www.elastic.co/guide/en/elasticse
It is important to understand at which level the problem is manifesting (UI, Rails code, Elasticsearch side) to be able to [troubleshoot further](../administration/troubleshooting/elasticsearch.md#search-results-workflow).
NOTE:
-The above instructions are not to be used for scenarios that only index a [subset of namespaces](#limiting-namespaces-and-projects).
+The above instructions are not to be used for scenarios that only index a [subset of namespaces](#limit-namespaces-and-projects).
See [Elasticsearch Index Scopes](#advanced-search-index-scopes) for more information on searching for specific types of data.
@@ -906,25 +872,20 @@ Elasticsearch::Transport::Transport::Errors::BadRequest([400] {
This is because we changed the index mapping in GitLab 8.12 and the old indexes should be removed and built from scratch again,
see details in the [update guide](../update/upgrading_from_source.md).
-- Exception `Elasticsearch::Transport::Transport::Errors::BadRequest`
+### `Elasticsearch::Transport::Transport::Errors::BadRequest`
- If you have this exception (just like in the case above but the actual message is different) please check if you have the correct Elasticsearch version and you met the other [requirements](#system-requirements).
- There is also an easy way to check it automatically with `sudo gitlab-rake gitlab:check` command.
+If you have this exception (just like in the case above but the actual message is different) please check if you have the correct Elasticsearch version and you met the other [requirements](#system-requirements).
+There is also an easy way to check it automatically with `sudo gitlab-rake gitlab:check` command.
-- Exception `Elasticsearch::Transport::Transport::Errors::RequestEntityTooLarge`
+### `Elasticsearch::Transport::Transport::Errors::RequestEntityTooLarge`
- ```plaintext
- [413] {"Message":"Request size exceeded 10485760 bytes"}
- ```
+```plaintext
+[413] {"Message":"Request size exceeded 10485760 bytes"}
+```
- This exception is seen when your Elasticsearch cluster is configured to reject
- requests above a certain size (10MiB in this case). This corresponds to the
- `http.max_content_length` setting in `elasticsearch.yml`. Increase it to a
- larger size and restart your Elasticsearch cluster.
+This exception is seen when your Elasticsearch cluster is configured to reject requests above a certain size (10MiB in this case). This corresponds to the `http.max_content_length` setting in `elasticsearch.yml`. Increase it to a larger size and restart your Elasticsearch cluster.
- AWS has [fixed limits](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/aes-limits.html)
- for this setting ("Maximum Size of HTTP Request Payloads"), based on the size of
- the underlying instance.
+AWS has [fixed limits](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/aes-limits.html) for this setting ("Maximum Size of HTTP Request Payloads"), based on the size of the underlying instance.
### My single node Elasticsearch cluster status never goes from `yellow` to `green` even though everything seems to be running properly
@@ -953,7 +914,7 @@ Gitlab::Elastic::Indexer::Error: time="2020-01-23T09:13:00Z" level=fatal msg="he
```
You probably have not used either `http://` or `https://` as part of your value in the **"URL"** field of the Elasticsearch Integration Menu. Please make sure you are using either `http://` or `https://` in this field as the [Elasticsearch client for Go](https://github.com/olivere/elastic) that we are using [needs the prefix for the URL to be accepted as valid](https://github.com/olivere/elastic/commit/a80af35aa41856dc2c986204e2b64eab81ccac3a).
-Once you have corrected the formatting of the URL, delete the index (via the [dedicated Rake task](#gitlab-advanced-search-rake-tasks)) and [reindex the content of your instance](#enabling-advanced-search).
+Once you have corrected the formatting of the URL, delete the index (via the [dedicated Rake task](#gitlab-advanced-search-rake-tasks)) and [reindex the content of your instance](#enable-advanced-search).
### My Elasticsearch cluster has a plugin and the integration is not working
diff --git a/doc/integration/facebook.md b/doc/integration/facebook.md
index ded89dd93a4..58c53db7996 100644
--- a/doc/integration/facebook.md
+++ b/doc/integration/facebook.md
@@ -4,9 +4,10 @@ group: Integrations
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
---
-# Facebook OAuth2 OmniAuth Provider **(FREE)**
+# Facebook OAuth 2.0 OmniAuth Provider **(FREE)**
-To enable the Facebook OmniAuth provider you must register your application with Facebook. Facebook generates an app ID and secret key for you to use.
+To enable the Facebook OmniAuth provider you must register your application with
+Facebook. Facebook generates an app ID and secret key for you to use.
1. Sign in to the [Facebook Developer Platform](https://developers.facebook.com/).
@@ -14,8 +15,9 @@ To enable the Facebook OmniAuth provider you must register your application with
1. Select the type "Website"
-1. Enter a name for your app. This can be anything. Consider something like "&lt;Organization&gt;'s GitLab" or "&lt;Your Name&gt;'s GitLab" or
- something else descriptive.
+1. Enter a name for your app. This can be anything. Consider something like
+ "&lt;Organization&gt;'s GitLab" or "&lt;Your Name&gt;'s GitLab" or something
+ else descriptive.
1. Choose "Create New Facebook App ID"
@@ -49,7 +51,8 @@ To enable the Facebook OmniAuth provider you must register your application with
1. Choose "Show" next to the hidden "App Secret"
-1. You should now see an app key and app secret (see screenshot). Keep this page open as you continue configuration.
+1. You should now see an app key and app secret (see screenshot). Keep this page
+ open as you continue configuration.
![Facebook API Keys](img/facebook_api_keys.png)
@@ -101,4 +104,7 @@ To enable the Facebook OmniAuth provider you must register your application with
1. [Reconfigure](../administration/restart_gitlab.md#omnibus-gitlab-reconfigure) or [restart GitLab](../administration/restart_gitlab.md#installations-from-source) for the changes to take effect if you
installed GitLab via Omnibus or from source respectively.
-On the sign in page there should now be a Facebook icon below the regular sign in form. Click the icon to begin the authentication process. Facebook asks the user to sign in and authorize the GitLab application. If everything goes well the user is returned to GitLab and signed in.
+On the sign in page there should now be a Facebook icon below the regular sign
+in form. Click the icon to begin the authentication process. Facebook asks the
+user to sign in and authorize the GitLab application. If everything goes well
+the user is returned to GitLab and signed in.
diff --git a/doc/integration/github.md b/doc/integration/github.md
index f3192e0af6c..0a96d67ac0c 100644
--- a/doc/integration/github.md
+++ b/doc/integration/github.md
@@ -188,7 +188,7 @@ GitHub account` when signing in, in GitLab:
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. In the left sidebar, select **Account**.
+1. On the left sidebar, select **Account**.
1. In the **Social sign-in** section, select **Connect to GitHub**.
After that, you should be able to sign in via GitHub successfully.
diff --git a/doc/integration/gitlab.md b/doc/integration/gitlab.md
index a0b438c9ffa..1f35faacc2e 100644
--- a/doc/integration/gitlab.md
+++ b/doc/integration/gitlab.md
@@ -14,7 +14,7 @@ GitLab.com generates an application ID and secret key for you to use.
1. Sign in to GitLab.com.
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. In the left sidebar, select **Applications**.
+1. On the left sidebar, select **Applications**.
1. Provide the required details for **Add new application**.
- Name: This can be anything. Consider something like `<Organization>'s GitLab` or `<Your Name>'s GitLab` or something else descriptive.
- Redirect URI:
diff --git a/doc/integration/gitpod.md b/doc/integration/gitpod.md
index e3cd3075bc9..bafba2cdf02 100644
--- a/doc/integration/gitpod.md
+++ b/doc/integration/gitpod.md
@@ -44,11 +44,11 @@ With the Gitpod integration enabled for your GitLab instance, to enable it for y
For GitLab self-managed instances, a GitLab administrator needs to:
-1. Set up a Gitpod instance to integrate with GitLab. Refer to the [Gitpod documentation](https://www.gitpod.io/docs/self-hosted/latest/self-hosted/)
+1. Set up a Gitpod instance to integrate with GitLab. Refer to the [Gitpod documentation](https://www.gitpod.io/docs/self-hosted/latest)
to get your instance up and running.
1. Enable it in GitLab:
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
- 1. In the left sidebar, select **Settings > General**.
+ 1. On the top bar, select **Menu > Admin**.
+ 1. On the left sidebar, select **Settings > General**.
1. Expand the **Gitpod** configuration section.
1. Check the **Enable Gitpod integration** checkbox.
1. Add your Gitpod instance URL (for example, `https://gitpod.example.com`).
diff --git a/doc/integration/gmail_action_buttons_for_gitlab.md b/doc/integration/gmail_action_buttons_for_gitlab.md
index f0bcc00c0fa..0468e5d0a42 100644
--- a/doc/integration/gmail_action_buttons_for_gitlab.md
+++ b/doc/integration/gmail_action_buttons_for_gitlab.md
@@ -12,10 +12,11 @@ If correctly set up, emails that require an action are marked in Gmail.
![GMail actions button](img/gmail_action_buttons_for_gitlab.png)
-To get this functioning, you need to be registered with Google. For instructions, see
+To get this functioning, you must be registered with Google. For instructions, see
[Register with Google](https://developers.google.com/gmail/markup/registering-with-google).
-This process has many steps. Make sure that you fulfill all requirements set by Google to avoid your application being rejected by Google.
+This process has many steps. Make sure that you fulfill all requirements set by
+Google to avoid your application being rejected by Google.
In particular, note:
diff --git a/doc/integration/google.md b/doc/integration/google.md
index a08944f65f1..4a2c61577ac 100644
--- a/doc/integration/google.md
+++ b/doc/integration/google.md
@@ -4,12 +4,12 @@ group: Integrations
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
---
-# Google OAuth2 OmniAuth Provider **(FREE)**
+# Google OAuth 2.0 OmniAuth Provider **(FREE)**
-To enable the Google OAuth2 OmniAuth provider you must register your application
+To enable the Google OAuth 2.0 OmniAuth provider you must register your application
with Google. Google generates a client ID and secret key for you to use.
-## Enabling Google OAuth
+## Enable Google OAuth
In Google's side:
@@ -47,7 +47,7 @@ In Google's side:
- Cloud Resource Manager API
- Cloud Billing API
- To do so you need to:
+ To do so you should:
1. Go to the [Google API Console](https://console.developers.google.com/apis/dashboard).
1. Click on **ENABLE APIS AND SERVICES** button at the top of the page.
@@ -98,8 +98,8 @@ On your GitLab server:
1. Change `YOUR_APP_ID` to the client ID from the Google Developer page
1. Similarly, change `YOUR_APP_SECRET` to the client secret
-1. Make sure that you configure GitLab to use a fully-qualified domain name, as Google doesn't accept
- raw IP addresses.
+1. Make sure that you configure GitLab to use a fully-qualified domain name, as
+ Google doesn't accept raw IP addresses.
For Omnibus packages:
@@ -115,8 +115,10 @@ On your GitLab server:
```
1. Save the configuration file.
-1. [Reconfigure](../administration/restart_gitlab.md#omnibus-gitlab-reconfigure) or [restart GitLab](../administration/restart_gitlab.md#installations-from-source) for the changes to take effect if you
- installed GitLab via Omnibus or from source respectively.
+1. [Reconfigure](../administration/restart_gitlab.md#omnibus-gitlab-reconfigure)
+ or [restart GitLab](../administration/restart_gitlab.md#installations-from-source) for
+ the changes to take effect if you installed GitLab via Omnibus or from source
+ respectively.
On the sign in page there should now be a Google icon below the regular sign in
form. Click the icon to begin the authentication process. Google asks the
diff --git a/doc/integration/jenkins.md b/doc/integration/jenkins.md
index 8910e0978b0..18ae71a7059 100644
--- a/doc/integration/jenkins.md
+++ b/doc/integration/jenkins.md
@@ -74,7 +74,7 @@ Create a personal access token to authorize Jenkins' access to GitLab.
1. Sign in to GitLab as the user to be used with Jenkins.
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. In the left sidebar, select **Access Tokens**.
+1. On the left sidebar, select **Access Tokens**.
1. Create a personal access token with the **API** scope checkbox checked. For more details, see
[Personal access tokens](../user/profile/personal_access_tokens.md).
1. Record the personal access token's value, because it's required in [Configure the Jenkins server](#configure-the-jenkins-server) section.
diff --git a/doc/integration/jenkins_deprecated.md b/doc/integration/jenkins_deprecated.md
index b7e4c4f0e26..e349bb4e88f 100644
--- a/doc/integration/jenkins_deprecated.md
+++ b/doc/integration/jenkins_deprecated.md
@@ -40,7 +40,7 @@ In GitLab, perform the following steps.
### Read access to repository
Jenkins needs read access to the GitLab repository. We already specified a
-private key to use in Jenkins, now we need to add a public one to the GitLab
+private key to use in Jenkins, now we must add a public one to the GitLab
project. For that case we need a Deploy key. Read the documentation on
[how to set up a Deploy key](../user/project/deploy_keys/index.md).
@@ -50,7 +50,8 @@ Now navigate to GitLab services page and activate Jenkins
![screen](img/jenkins_gitlab_service.png)
-Done! When you push to GitLab, it creates a build for Jenkins. You can view the merge request build status with a link to the Jenkins build.
+Done! When you push to GitLab, it creates a build for Jenkins. You can view the
+merge request build status with a link to the Jenkins build.
### Multi-project Configuration
diff --git a/doc/integration/jira/configure.md b/doc/integration/jira/configure.md
index b11f367258d..d4e5a1bfca1 100644
--- a/doc/integration/jira/configure.md
+++ b/doc/integration/jira/configure.md
@@ -4,7 +4,7 @@ group: Integrations
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
---
-# Configure the Jira integration in GitLab
+# Configure the Jira integration in GitLab **(FREE)**
You can set up the [Jira integration](index.md#jira-integration)
by configuring your project settings in GitLab.
diff --git a/doc/integration/jira/connect-app.md b/doc/integration/jira/connect-app.md
index e32bd4559f9..7d32c080fff 100644
--- a/doc/integration/jira/connect-app.md
+++ b/doc/integration/jira/connect-app.md
@@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
NOTE:
Only Jira users with administrator level access are able to install or configure
-the GitLab app for Jira Cloud.
+the GitLab.com for Jira Cloud app.
## GitLab.com for Jira Cloud app **(FREE SAAS)**
@@ -60,6 +60,14 @@ After a namespace is added:
Support for syncing past branch and commit data is tracked [in this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/263240).
+## Update the GitLab.com for Jira Cloud app
+
+Most updates to the app are fully automated and don't require any user interaction. See the
+[Atlassian Marketplace documentation](https://developer.atlassian.com/platform/marketplace/upgrading-and-versioning-cloud-apps/)
+for details.
+
+If the app requires additional permissions, [the update must first be manually approved in Jira](https://developer.atlassian.com/platform/marketplace/upgrading-and-versioning-cloud-apps/#changes-that-require-manual-customer-approval).
+
## Install the GitLab.com for Jira Cloud app for self-managed instances **(FREE SELF)**
If your GitLab instance is self-managed, you must follow some
@@ -78,10 +86,10 @@ self-managed GitLab instances with Jira Cloud, you can either:
You can configure your Atlassian Cloud instance to allow you to install applications
from outside the Marketplace, which allows you to install the application:
-1. Sign in to your Jira instance as a user with administrator permissions.
+1. Sign in to your Jira instance as a user with an Administrator role.
1. Place your Jira instance into
[development mode](https://developer.atlassian.com/cloud/jira/platform/getting-started-with-connect/#step-2--enable-development-mode).
-1. Sign in to your GitLab application as a user with [Administrator](../../user/permissions.md) permissions.
+1. Sign in to your GitLab application as a user with an [Administrator](../../user/permissions.md) role.
1. Install the GitLab application from your self-managed GitLab instance, as
described in the [Atlassian developer guides](https://developer.atlassian.com/cloud/jira/platform/getting-started-with-connect/#step-3--install-and-test-your-app):
1. In your Jira instance, go to **Apps > Manage Apps** and click **Upload app**:
@@ -103,13 +111,13 @@ The **GitLab.com for Jira Cloud** app now displays under **Manage apps**. You ca
click **Get started** to open the configuration page rendered from your GitLab instance.
NOTE:
-If you make changes to the application descriptor, you must uninstall, then reinstall, the
+If a GitLab update makes changes to the application descriptor, you must uninstall, then reinstall, the
application.
### Create a Marketplace listing **(FREE SELF)**
If you prefer to not use development mode on your Jira instance, you can create
-your own Marketplace listing for your instance, which enables your application
+your own Marketplace listing for your instance. This enables your application
to be installed from the Atlassian Marketplace.
For full instructions, review the Atlassian [guide to creating a marketplace listing](https://developer.atlassian.com/platform/marketplace/installing-cloud-apps/#creating-the-marketplace-listing). To create a
@@ -127,11 +135,15 @@ Review the
for details.
NOTE:
-DVCS means distributed version control system.
+Using this method, [updates are automated](#update-the-gitlabcom-for-jira-cloud-app)
+the same way as when using our GitLab.com Marketplace listing.
-## Troubleshooting GitLab.com for Jira Cloud app
+## Troubleshoot GitLab.com for Jira Cloud app
-The GitLab.com for Jira Cloud app uses an iframe to add namespaces on the settings page. Some browsers block cross-site cookies, which can lead to a message saying that the user needs to log in on GitLab.com even though the user is already logged in.
+The GitLab.com for Jira Cloud app uses an iframe to add namespaces on the
+settings page. Some browsers block cross-site cookies, which can lead to a
+message saying that the user needs to log in on GitLab.com even though the user
+is already logged in.
> "You need to sign in or sign up before continuing."
diff --git a/doc/integration/jira/development_panel.md b/doc/integration/jira/development_panel.md
index c8ea224f18e..5a2ce8a0a75 100644
--- a/doc/integration/jira/development_panel.md
+++ b/doc/integration/jira/development_panel.md
@@ -65,11 +65,11 @@ For an overview of how to configure Jira Development panel integration, see
[Agile Management - GitLab Jira Development panel integration](https://www.youtube.com/watch?v=VjVTOmMl85M).
To simplify administration, we recommend that a GitLab group maintainer or group owner
-(or instance administrator in the case of self-managed GitLab) set up the integration.
+(or, if possible, instance administrator in the case of self-managed GitLab) set up the integration.
| Jira usage | GitLab.com customers need | GitLab self-managed customers need |
|------------|---------------------------|------------------------------------|
-| [Atlassian cloud](https://www.atlassian.com/cloud) | The [GitLab.com for Jira Cloud](https://marketplace.atlassian.com/apps/1221011/gitlab-com-for-jira-cloud?hosting=cloud&tab=overview) application installed from the [Atlassian Marketplace](https://marketplace.atlassian.com). This offers real-time sync between GitLab and Jira. For more information, see the documentation for the [GitLab.com for Jira Cloud app](connect-app.md). | The [GitLab.com for Jira Cloud](https://marketplace.atlassian.com/apps/1221011/gitlab-com-for-jira-cloud?hosting=cloud&tab=overview), using a workaround process. See the documentation for [installing the GitLab Jira Cloud application for self-managed instances](connect-app.md#install-the-gitlabcom-for-jira-cloud-app-for-self-managed-instances) for more information. |
+| [Atlassian cloud](https://www.atlassian.com/cloud) | The [GitLab.com for Jira Cloud app](https://marketplace.atlassian.com/apps/1221011/gitlab-com-for-jira-cloud?hosting=cloud&tab=overview) installed from the [Atlassian Marketplace](https://marketplace.atlassian.com). This offers real-time sync between GitLab.com and Jira. For more information, see the documentation for the [GitLab.com for Jira Cloud app](connect-app.md). | The [GitLab.com for Jira Cloud app](https://marketplace.atlassian.com/apps/1221011/gitlab-com-for-jira-cloud?hosting=cloud&tab=overview), using a workaround process. See the documentation for [installing the GitLab.com for Jira Cloud app for self-managed instances](connect-app.md#install-the-gitlabcom-for-jira-cloud-app-for-self-managed-instances) for more information. |
| Your own server | The [Jira DVCS (distributed version control system) connector](dvcs.md). This syncs data hourly. | The [Jira DVCS Connector](dvcs.md). |
Each GitLab project can be configured to connect to an entire Jira instance. That means after
@@ -89,10 +89,6 @@ This integration is not supported on GitLab instances under a
[relative URL](https://docs.gitlab.com/omnibus/settings/configuration.html#configuring-a-relative-url-for-gitlab).
For example, `http://example.com/gitlab`.
-## Related topics
-
-- [Using Smart Commits](https://confluence.atlassian.com/fisheye/using-smart-commits-960155400.html) in Jira
-
## Troubleshooting
### Cookies for Oracle's Access Manager
diff --git a/doc/integration/jira/dvcs.md b/doc/integration/jira/dvcs.md
index 7d97312757e..664a0361da4 100644
--- a/doc/integration/jira/dvcs.md
+++ b/doc/integration/jira/dvcs.md
@@ -8,15 +8,16 @@ info: To determine the technical writer assigned to the Stage/Group associated w
Use the Jira DVCS (distributed version control system) connector if you self-host
your Jira instance, and you want to sync information
-between GitLab and Jira. If you use Jira Cloud and GitLab.com, you should use the
-[GitLab.com for Jira Cloud app](connect-app.md) unless you specifically need the DVCS connector.
+between GitLab and Jira. If you use Jira Cloud, you should use the
+[GitLab.com for Jira Cloud app](connect-app.md) unless you specifically need the
+DVCS connector.
When you configure the Jira DVCS connector, make sure your GitLab and Jira instances
are accessible.
- **Self-managed GitLab**: Your GitLab instance must be accessible by Jira.
-- **Jira Cloud**: Your instance must be accessible through the internet.
- **Jira Server**: Your network must allow access to your instance.
+- **Jira Cloud**: Your instance must be accessible through the internet.
## Smart commits
@@ -61,25 +62,25 @@ you can still perform multiple actions in a single commit:
## Configure a GitLab application for DVCS
-We recommend you create and use a `jira` user in GitLab, and use the account only
-for integration work. A separate account ensures regular account maintenance does not affect
-your integration.
+We recommend you create and use a `jira` user in GitLab, and use the account
+only for integration work. A separate account ensures regular account
+maintenance does not affect your integration. If a `jira` user is not feasible,
+you can set up this integration with your own account instead.
1. In GitLab, [create a user](../../user/profile/account/create_accounts.md) for Jira to
- use to connect to GitLab. For Jira to access all projects,
- a user with [administrator](../../user/permissions.md) permissions must
- create the user with administrator permissions.
+ use to connect to GitLab. This user must be added to each project you want Jira to have access to,
+ or have an [Administrator](../../user/permissions.md) role to access all projects.
1. Sign in as the `jira` user.
1. In the top right corner, click the account's avatar, and select **Edit profile**.
-1. In the left sidebar, select **Applications**.
+1. On the left sidebar, select **Applications**.
1. In the **Name** field, enter a descriptive name for the integration, such as `Jira`.
1. In the **Redirect URI** field, enter the URI appropriate for your version of GitLab,
replacing `<gitlab.example.com>` with your GitLab instance domain:
- *For GitLab versions 13.0 and later* **and** *Jira versions 8.14 and later,* use the
generated `Redirect URL` from
[Linking GitLab accounts with Jira](https://confluence.atlassian.com/adminjiraserver/linking-gitlab-accounts-1027142272.html).
- - *For GitLab versions 13.0 and later* **and** *Jira Cloud,* use `https://<gitlab.example.com>/login/oauth/callback`.
- - *For GitLab versions 11.3 and later,* use `https://<gitlab.example.com>/login/oauth/callback`.
+ - *For GitLab versions 13.0 and later* **and** *Jira Cloud,* use `https://<gitlab.example.com>/login/oauth/callback`.
+ - *For GitLab versions 11.3 and later* **and** *Jira versions 8.13 and earlier,* use `https://<gitlab.example.com>/login/oauth/callback`.
If you use GitLab.com, the URL is `https://gitlab.com/login/oauth/callback`.
- *For GitLab versions 11.2 and earlier,* use
`https://<gitlab.example.com>/-/jira/login/oauth/callback`.
@@ -105,9 +106,9 @@ it completes, refreshes every 60 minutes:
- *For Jira versions 8.13 and earlier:* Select **GitHub Enterprise**.
1. For **Team or User Account**, enter either:
- *For Jira versions 8.14 and later:*
- - The relative path of a top-level GitLab group that you have access to.
+ - The relative path of a top-level GitLab group that [the GitLab user](#configure-a-gitlab-application-for-dvcs) has access to.
- *For Jira versions 8.13 and earlier:*
- - The relative path of a top-level GitLab group that you have access to.
+ - The relative path of a top-level GitLab group that [the GitLab user](#configure-a-gitlab-application-for-dvcs) has access to.
- The relative path of your personal namespace.
1. In the **Host URL** field, enter the URI appropriate for your version of GitLab,
@@ -141,7 +142,7 @@ can refresh the data manually from the Jira interface:
column, select the icon:
![Refresh GitLab information in Jira](img/jira_dev_panel_manual_refresh.png)
-## Troubleshooting your DVCS connection
+## Troubleshoot your DVCS connection
Refer to the items in this section if you're having problems with your DVCS connector.
@@ -174,7 +175,8 @@ Error obtaining access token. Cannot access https://gitlab.example.com from Jira
must have the appropriate certificate (such as your organization's
root certificate) added to it .
-Refer to Atlassian's documentation and Atlassian Support for assistance setting up Jira correctly:
+Refer to Atlassian's documentation and Atlassian Support for assistance setting
+up Jira correctly:
- [Add a certificate](https://confluence.atlassian.com/kb/how-to-import-a-public-ssl-certificate-into-a-jvm-867025849.html)
to the trust store.
@@ -232,9 +234,17 @@ To resolve this issue:
[Contact GitLab Support](https://about.gitlab.com/support/) if none of these reasons apply.
+### `410 : Gone` error when connecting to Jira
+
+When you connect to Jira and synchronize repositories, you may receive a `410 : Gone` error.
+
+This issue occurs when you use the Jira DVCS connector and your integration is configured to use **GitHub Enterprise**.
+
+For more information and possible fixes, see [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/340160).
+
### Fix synchronization issues
-If Jira displays incorrect information, such as deleted branches, you may need to
+If Jira displays incorrect information, such as deleted branches, you may have to
resynchronize the information. To do so:
1. In Jira, go to **Jira Administration > Applications > DVCS accounts**.
diff --git a/doc/integration/jira/index.md b/doc/integration/jira/index.md
index febd9907028..85f99b49c41 100644
--- a/doc/integration/jira/index.md
+++ b/doc/integration/jira/index.md
@@ -26,9 +26,7 @@ The supported Jira versions are `v6.x`, `v7.x`, and `v8.x`.
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
For an overview, see [Agile Management - GitLab-Jira Basic Integration](https://www.youtube.com/watch?v=fWvwkx5_00E&feature=youtu.be).
-To set up the integration, [configure the project settings](configure.md) in GitLab.
-You can also configure these settings at a [group level](../../user/admin_area/settings/project_integration_management.md#manage-group-level-default-settings-for-a-project-integration),
-and for self-managed GitLab, at an [instance level](../../user/admin_area/settings/project_integration_management.md#manage-instance-level-default-settings-for-a-project-integration).
+To set up the integration, [configure the settings](configure.md) in GitLab.
### Jira development panel integration
@@ -37,12 +35,9 @@ connects all GitLab projects under a group or personal namespace. When configure
relevant GitLab information, including related branches, commits, and merge requests,
displays in the [development panel](https://support.atlassian.com/jira-software-cloud/docs/view-development-information-for-an-issue/).
-To set up the Jira development panel integration:
-
-- *If your installation uses Jira Cloud,* use the
- [GitLab for Jira app](connect-app.md).
-- *If either your Jira or GitLab installation is self-managed,* use the
- [Jira DVCS Connector](dvcs.md).
+To set up the Jira development panel integration, use the GitLab.com for Jira Cloud app
+or the Jira DVCS (distributed version control system) connector,
+[depending on your installation](development_panel.md#configure-the-integration).
### Direct feature comparison
diff --git a/doc/integration/jira/jira_cloud_configuration.md b/doc/integration/jira/jira_cloud_configuration.md
index e42a102e030..0cfffdb8ba4 100644
--- a/doc/integration/jira/jira_cloud_configuration.md
+++ b/doc/integration/jira/jira_cloud_configuration.md
@@ -11,10 +11,10 @@ on Atlassian cloud. To create the API token:
1. Sign in to [`id.atlassian.com`](https://id.atlassian.com/manage-profile/security/api-tokens)
with your email address. Use an account with *write* access to Jira projects.
-1. Go to **Settings > API tokens**.
+1. Go to **Settings > Atlassian account settings > Security > Create and manage API tokens**.
1. Select **Create API token** to display a modal window with an API token.
-1. To copy the API token, select **Copy to clipboard**, or select **View** and write
- down the new API token. You need this value when you
+1. In the dialog, enter a label for your token and select **Create**.
+1. To copy the API token, select **Copy**, then paste the token somewhere safe. You need this value when you
[configure GitLab](configure.md).
You need the newly created token, and the email
diff --git a/doc/integration/jira/jira_server_configuration.md b/doc/integration/jira/jira_server_configuration.md
index 52e7e5e412b..32a8cd430f9 100644
--- a/doc/integration/jira/jira_server_configuration.md
+++ b/doc/integration/jira/jira_server_configuration.md
@@ -25,7 +25,7 @@ This process creates a user named `gitlab` and adds it to a new group named `git
1. Create a new user account (`gitlab`) with write access to
projects in Jira.
- **Email address**: Jira requires a valid email address, and sends a verification
- email, which you need to set up the password.
+ email, which is required to set up the password.
- **Username**: Jira creates the username by using the email prefix. You can change
this username later.
- **Password**: You must create a password, because the GitLab integration doesn't
diff --git a/doc/integration/kerberos.md b/doc/integration/kerberos.md
index ba3f246f5f5..48339144292 100644
--- a/doc/integration/kerberos.md
+++ b/doc/integration/kerberos.md
@@ -9,6 +9,11 @@ type: reference, how-to
GitLab can integrate with [Kerberos](https://web.mit.edu/kerberos/) as an authentication mechanism.
+WARNING:
+GitLab CI/CD does not work with a Kerberos-enabled GitLab instance due to an unresolved
+[bug in Git CLI](https://lore.kernel.org/git/YKNVop80H8xSTCjz@coredump.intra.peff.net/T/#mab47fd7dcb61fee651f7cc8710b8edc6f62983d5)
+that fails to use job token authentication from the GitLab Runners.
+
## Overview
[Kerberos](https://web.mit.edu/kerberos/) is a secure method for authenticating a request for a service in a
@@ -85,6 +90,9 @@ For source installations, make sure the `kerberos` gem group
gitlab_rails['kerberos_keytab'] = "/etc/http.keytab"
```
+ To avoid GitLab creating users automatically on their first sign in through Kerberos,
+ don't set `kerberos` for `gitlab_rails['omniauth_allow_single_sign_on']`.
+
1. [Reconfigure GitLab](../administration/restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
GitLab now offers the `negotiate` authentication method for signing in and
@@ -107,7 +115,7 @@ set up GitLab to create a new account when a Kerberos user tries to sign in.
If you're an administrator, you can link a Kerberos account to an
existing GitLab account. To do so:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Users**.
1. Select a user, then select the **Identities** tab.
1. Select 'Kerberos SPNEGO' in the 'Provider' dropdown box.
@@ -118,7 +126,7 @@ If you're not an administrator:
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. In the left sidebar, select **Account**.
+1. On the left sidebar, select **Account**.
1. In the **Social sign-in** section, select **Connect Kerberos SPNEGO**.
If you don't see a **Social sign-in** Kerberos option, follow the
requirements in [Enable single sign-on](#enable-single-sign-on).
@@ -147,7 +155,7 @@ With that information at hand:
```
1. As an administrator, you can confirm the new, blocked account:
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
+ 1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Users** and review the **Blocked** tab.
1. You can enable the user.
1. If `block_auto_created_users` is false, the Kerberos user is
diff --git a/doc/integration/mattermost/gitlab-mattermost.msc b/doc/integration/mattermost/gitlab-mattermost.msc
new file mode 100644
index 00000000000..f6d4bf7aa68
--- /dev/null
+++ b/doc/integration/mattermost/gitlab-mattermost.msc
@@ -0,0 +1,28 @@
+msc {
+ # Use https://mscgen.js.org or mscgen to convert this into PNG
+ hscale="1.5",
+ wordwraparcs=on;
+
+ user [ label="User", textbgcolor="blue", textcolor="white" ],
+ mattermost [ label="Mattermost", textbgcolor="red", textcolor="white"],
+ gitlab [ label="GitLab", textbgcolor="indigo", textcolor="white"];
+
+ user=>mattermost [label="GET https://mm.domain.com"];
+ mattermost note gitlab [label="Obtain access code", textcolor="green"];
+ mattermost=>gitlab [label="GET https://gitlab.domain.com/oauth/authorize", textcolor="indigo"];
+ gitlab rbox user [label="GitLab user logs in (if necessary)"];
+ gitlab rbox gitlab [label="GitLab verifies client_id matches an OAuth application"];
+ gitlab=>user [label="GitLab asks user to authorize Mattermost OAuth app"];
+ user=>gitlab [label="User clicks 'Allow'"];
+ gitlab rbox gitlab [label="GitLab verifies redirect_uri matches list of valid URLs"];
+ gitlab=>user [label="302 Redirect: https://mm.domain.com/signup/gitlab/complete"];
+ user=>mattermost [label="GET https://mm.domain.com/signup/gitlab/complete", textcolor="red"];
+ mattermost note gitlab [label="Exchange access code for access token", textcolor="green"];
+ mattermost=>gitlab [label="POST http://gitlab.domain.com/oauth/token", textcolor="indigo"];
+ gitlab=>gitlab [label="Doorkeeper::TokensController#create"];
+ gitlab=>mattermost [label="Access token", textcolor="red"];
+ mattermost note gitlab [label="Mattermost looks up GitLab user", textcolor="green"];
+ mattermost=>gitlab [label="GET https://gitlab.domain.com/api/v4/user", textcolor="indigo"];
+ gitlab=>mattermost [label="User details", textcolor="red"];
+ mattermost=>user [label="Mattermost/GitLab user ready"];
+}
diff --git a/doc/integration/mattermost/img/gitlab-mattermost.png b/doc/integration/mattermost/img/gitlab-mattermost.png
new file mode 100644
index 00000000000..1eedcb391b0
--- /dev/null
+++ b/doc/integration/mattermost/img/gitlab-mattermost.png
Binary files differ
diff --git a/doc/integration/mattermost/index.md b/doc/integration/mattermost/index.md
new file mode 100644
index 00000000000..4830f8ba84e
--- /dev/null
+++ b/doc/integration/mattermost/index.md
@@ -0,0 +1,495 @@
+---
+stage: Enablement
+group: Distribution
+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/#designated-technical-writers
+---
+
+# GitLab Mattermost
+
+NOTE:
+This document applies to GitLab 11.0 and later.
+
+You can run a [GitLab Mattermost](https://gitlab.com/gitlab-org/gitlab-mattermost)
+service on your GitLab server. Mattermost is not part of the single application that GitLab is. There is a good integration between with GitLab, and our Omnibus installer allows you to easily install it. But it is a separate application from a separate company.
+
+## Prerequisites
+
+Each release of GitLab Mattermost is compiled and manually tested on an AMD 64 chipset for Linux. ARM chipsets and operating systems, like Raspberry Pi, are not supported.
+
+## Getting started
+
+GitLab Mattermost expects to run on its own virtual host. In your DNS settings you will need
+two entries pointing to the same machine, e.g., `gitlab.example.com` and
+`mattermost.example.com`.
+
+GitLab Mattermost is disabled by default. To enable it:
+
+1. Edit `/etc/gitlab/gitlab.rb` and add the Mattermost external URL:
+
+ ```ruby
+ mattermost_external_url 'https://mattermost.example.com'
+ ```
+
+1. Reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+1. Confirm that GitLab Mattermost is reachable at `https://mattermost.example.com` and authorized to connect to GitLab. Authorizing Mattermost with GitLab allows users to use GitLab as an SSO provider.
+
+The Omnibus GitLab package attempts to automatically authorize GitLab Mattermost with GitLab if the applications are running on the same server.
+
+Automatic authorization requires access to the GitLab database. If the GitLab database is not available
+you will need to manually authorize GitLab Mattermost for access to GitLab using the process described in the [Authorize GitLab Mattermost section](#authorize-gitlab-mattermost).
+
+## Configuring Mattermost
+
+Starting in GitLab 11.0, Mattermost can be configured using the Mattermost System Console. An extensive list of
+Mattermost settings and where they can be set is available [in the Mattermost documentation](https://docs.mattermost.com/administration/config-settings.html).
+
+While using the System Console is recommended, you can also configure Mattermost using one of the following options:
+
+1. Edit the Mattermost configuration directly through `/var/opt/gitlab/mattermost/config.json`.
+1. Specify environment variables used to run Mattermost by changing the `mattermost['env']` setting in `gitlab.rb`. Any settings configured in this way will be disabled from the System Console and cannot be changed without restarting Mattermost.
+
+## Running GitLab Mattermost with HTTPS
+
+Place the SSL certificate and SSL certificate key inside `/etc/gitlab/ssl`. If the directory doesn't exist, create it:
+
+```shell
+sudo mkdir -p /etc/gitlab/ssl
+sudo chmod 755 /etc/gitlab/ssl
+sudo cp mattermost.gitlab.example.key mattermost.gitlab.example.crt /etc/gitlab/ssl/
+```
+
+In `/etc/gitlab/gitlab.rb` specify the following configuration:
+
+```ruby
+mattermost_external_url 'https://mattermost.gitlab.example'
+mattermost_nginx['redirect_http_to_https'] = true
+```
+
+If you haven't named your certificate and key `mattermost.gitlab.example.crt`
+and `mattermost.gitlab.example.key` then you'll need to also add the full paths
+as shown below.
+
+```ruby
+mattermost_nginx['ssl_certificate'] = "/etc/gitlab/ssl/mattermost-nginx.crt"
+mattermost_nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/mattermost-nginx.key"
+```
+
+where `mattermost-nginx.crt` and `mattermost-nginx.key` are SSL cert and key, respectively.
+
+Once the configuration is set, run `sudo gitlab-ctl reconfigure` to apply the changes.
+
+## Running GitLab Mattermost on its own server
+
+If you want to run GitLab and GitLab Mattermost on two separate servers the GitLab services will still be set up on your GitLab Mattermost server, but they will not accept user requests or
+consume system resources. You can use the following settings and configuration details on the GitLab Mattermost server to effectively disable the GitLab service bundled into the Omnibus package.
+
+```ruby
+mattermost_external_url 'http://mattermost.example.com'
+
+# Shut down GitLab services on the Mattermost server
+gitlab_rails['enable'] = false
+redis['enable'] = false
+postgres_exporter['enable'] = false
+```
+
+Then follow the appropriate steps in the [Authorize GitLab Mattermost section](#authorize-gitlab-mattermost). Last, to enable
+integrations with GitLab add the following on the GitLab Server:
+
+```ruby
+gitlab_rails['mattermost_host'] = "https://mattermost.example.com"
+```
+
+By default GitLab Mattermost requires all users to sign up with GitLab and disables the sign-up by email option. See Mattermost [documentation on GitLab SSO](https://docs.mattermost.com/deployment/sso-gitlab.html).
+
+## Manually (re)authorizing GitLab Mattermost with GitLab
+
+### Reauthorize GitLab Mattermost
+
+To reauthorize GitLab Mattermost, you first need to revoke the existing
+authorization. This can be done in the **Settings > Applications** area of GitLab. Then follow the steps below to complete authorization.
+
+### Authorize GitLab Mattermost
+
+Navigate to the **Settings > Applications** area in GitLab. Create a new application and for the **Redirect URI** use the following (replace `http` with `https` if you use HTTPS):
+
+```plaintext
+http://mattermost.example.com/signup/gitlab/complete
+http://mattermost.example.com/login/gitlab/complete
+```
+
+Note that you do not need to select any options under **Scopes**. Choose **Save application**.
+
+Once the application is created you will be provided with an `Application ID` and `Secret`. One other piece of information needed is the URL of GitLab instance.
+Return to the server running GitLab Mattermost and edit the `/etc/gitlab/gitlab.rb` configuration file as follows using the values you received above:
+
+```ruby
+mattermost['gitlab_enable'] = true
+mattermost['gitlab_id'] = "12345656"
+mattermost['gitlab_secret'] = "123456789"
+mattermost['gitlab_scope'] = ""
+mattermost['gitlab_auth_endpoint'] = "http://gitlab.example.com/oauth/authorize"
+mattermost['gitlab_token_endpoint'] = "http://gitlab.example.com/oauth/token"
+mattermost['gitlab_user_api_endpoint'] = "http://gitlab.example.com/api/v4/user"
+```
+
+Save the changes and then run `sudo gitlab-ctl reconfigure`. If there are no errors your GitLab and GitLab Mattermost should be configured correctly.
+
+### Specify numeric user and group identifiers
+
+Omnibus GitLab creates a user and group `mattermost`. You can specify the
+numeric identifiers for these users in `/etc/gitlab/gitlab.rb` as follows:
+
+```ruby
+mattermost['uid'] = 1234
+mattermost['gid'] = 1234
+```
+
+Run `sudo gitlab-ctl reconfigure` to apply the changes.
+
+### Setting custom environment variables
+
+If necessary you can set custom environment variables to be used by Mattermost
+via `/etc/gitlab/gitlab.rb`. This can be useful if the Mattermost server
+is operated behind a corporate internet proxy. In `/etc/gitlab/gitlab.rb`
+supply a `mattermost['env']` with a hash value. For example:
+
+```ruby
+mattermost['env'] = {"HTTP_PROXY" => "my_proxy", "HTTPS_PROXY" => "my_proxy", "NO_PROXY" => "my_no_proxy"}
+```
+
+Run `sudo gitlab-ctl reconfigure` to apply the changes.
+
+### Connecting to the bundled PostgreSQL database
+
+If you need to connect to the bundled PostgreSQL database and are using the default Omnibus GitLab database configuration, you can connect as
+the PostgreSQL superuser:
+
+```shell
+sudo gitlab-psql -d mattermost_production
+```
+
+### Back up GitLab Mattermost
+
+GitLab Mattermost is not included in the regular [Omnibus GitLab backup](../../raketasks/backup_restore.md#back-up-gitlab) Rake task.
+
+The general Mattermost [backup and disaster recovery](https://docs.mattermost.com/deploy/backup-disaster-recovery.html) documentation can be used as a guide
+on what needs to be backed up.
+
+#### Back up the bundled PostgreSQL database
+
+If you need to back up the bundled PostgreSQL database and are using the default Omnibus GitLab database configuration, you can back up using this command:
+
+```shell
+sudo -i -u gitlab-psql -- /opt/gitlab/embedded/bin/pg_dump -h /var/opt/gitlab/postgresql mattermost_production | gzip > mattermost_dbdump_$(date --rfc-3339=date).sql.gz
+```
+
+#### Back up the `data` directory and `config.json`
+
+Mattermost has a `data` directory and `config.json` file that will need to be backed up as well:
+
+```shell
+sudo tar -zcvf mattermost_data_$(date --rfc-3339=date).gz -C /var/opt/gitlab/mattermost data config.json
+```
+
+### Restore GitLab Mattermost
+
+If you have previously [created a backup of GitLab Mattermost](#back-up-gitlab-mattermost), you can run the following commands to restore it:
+
+```shell
+# Stop Mattermost so we don't have any open database connections
+sudo gitlab-ctl stop mattermost
+
+# Drop the Mattermost database
+sudo -u gitlab-psql /opt/gitlab/embedded/bin/dropdb -U gitlab-psql -h /var/opt/gitlab/postgresql -p 5432 mattermost_production
+
+# Create the Mattermost database
+sudo -u gitlab-psql /opt/gitlab/embedded/bin/createdb -U gitlab-psql -h /var/opt/gitlab/postgresql -p 5432 mattermost_production
+
+# Perform the database restore
+# Replace /tmp/mattermost_dbdump_2021-08-05.sql.gz with your backup
+sudo -u mattermost sh -c "zcat /tmp/mattermost_dbdump_2021-08-05.sql.gz | /opt/gitlab/embedded/bin/psql -U gitlab_mattermost -h /var/opt/gitlab/postgresql -p 5432 mattermost_production"
+
+# Restore the data directory and config.json
+# Replace /tmp/mattermost_data_2021-08-09.gz with your backup
+sudo tar -xzvf /tmp/mattermost_data_2021-08-09.gz -C /var/opt/gitlab/mattermost
+
+# Fix permissions if required
+sudo chown -R mattermost:mattermost /var/opt/gitlab/mattermost/data
+sudo chown mattermost:mattermost /var/opt/gitlab/mattermost/config.json
+
+# Start Mattermost
+sudo gitlab-ctl start mattermost
+```
+
+### Mattermost Command Line Tools (CLI)
+
+NOTE:
+This CLI will be replaced in a future release with the new [`mmctl` Command Line Tool](https://docs.mattermost.com/administration/mmctl-cli-tool.html).
+
+To use the [Mattermost Command Line Tools (CLI)](https://docs.mattermost.com/administration/command-line-tools.html), ensure that you are in the `/opt/gitlab/embedded/service/mattermost` directory when you run the CLI commands and that you specify the location of the configuration file. The executable is `/opt/gitlab/embedded/bin/mattermost`.
+
+```shell
+cd /opt/gitlab/embedded/service/mattermost
+
+sudo /opt/gitlab/embedded/bin/chpst -e /opt/gitlab/etc/mattermost/env -P -U mattermost:mattermost -u mattermost:mattermost /opt/gitlab/embedded/bin/mattermost --config=/var/opt/gitlab/mattermost/config.json version
+```
+
+Until [#4745](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/4745) has been implemented, the command requires quite of bit typing and is hard to remember, so let's make a bash/zsh alias to make it a bit easier to remember. Add the following to your `~/.bashrc` or `~/.zshrc` file:
+
+```shell
+alias mattermost-cli="cd /opt/gitlab/embedded/service/mattermost && sudo /opt/gitlab/embedded/bin/chpst -e /opt/gitlab/etc/mattermost/env -P -U mattermost:mattermost -u mattermost:mattermost /opt/gitlab/embedded/bin/mattermost --config=/var/opt/gitlab/mattermost/config.json $1"
+```
+
+Then source `~/.zshrc` or `~/.bashrc` with `source ~/.zshrc` or `source ~/.bashrc`.
+
+If successful, you can now run any Mattermost CLI command with your new shell alias `mattermost-cli`:
+
+```shell
+$ mattermost-cli version
+
+[sudo] password for username:
+{"level":"info","ts":1569614421.9058893,"caller":"utils/i18n.go:83","msg":"Loaded system translations for 'en' from '/opt/gitlab/embedded/service/mattermost/i18n/en.json'"}
+{"level":"info","ts":1569614421.9062793,"caller":"app/server_app_adapters.go:58","msg":"Server is initializing..."}
+{"level":"info","ts":1569614421.90976,"caller":"sqlstore/supplier.go:223","msg":"Pinging SQL master database"}
+{"level":"info","ts":1569614422.0515099,"caller":"mlog/log.go:165","msg":"Starting up plugins"}
+{"level":"info","ts":1569614422.0515954,"caller":"app/plugin.go:193","msg":"Syncing plugins from the file store"}
+{"level":"info","ts":1569614422.086005,"caller":"app/plugin.go:228","msg":"Found no files in plugins file store"}
+{"level":"info","ts":1569614423.9337213,"caller":"sqlstore/post_store.go:1301","msg":"Post.Message supports at most 16383 characters (65535 bytes)"}
+{"level":"error","ts":1569614425.6317747,"caller":"go-plugin/stream.go:15","msg":" call to OnConfigurationChange failed, error: Must have a GitLab oauth client id","plugin_id":"com.github.manland.mattermost-plugin-gitlab","source":"plugin_stderr"}
+{"level":"info","ts":1569614425.6875598,"caller":"mlog/sugar.go:19","msg":"Ensuring Surveybot exists","plugin_id":"com.mattermost.nps"}
+{"level":"info","ts":1569614425.6953356,"caller":"app/server.go:216","msg":"Current version is 5.14.0 (5.14.2/Fri Aug 30 20:20:48 UTC 2019/817ee89711bf26d33f840ce7f59fba14da1ed168/none)"}
+{"level":"info","ts":1569614425.6953766,"caller":"app/server.go:217","msg":"Enterprise Enabled: false"}
+{"level":"info","ts":1569614425.6954057,"caller":"app/server.go:219","msg":"Current working directory is /opt/gitlab/embedded/service/mattermost/i18n"}
+{"level":"info","ts":1569614425.6954265,"caller":"app/server.go:220","msg":"Loaded config","source":"file:///var/opt/gitlab/mattermost/config.json"}
+Version: 5.14.0
+Build Number: 5.14.2
+Build Date: Fri Aug 30 20:20:48 UTC 2019
+Build Hash: 817ee89711bf26d33f840ce7f59fba14da1ed168
+Build Enterprise Ready: false
+DB Version: 5.14.0
+```
+
+For more details see [Mattermost Command Line Tools (CLI)](https://docs.mattermost.com/administration/command-line-tools.html) and the [Troubleshooting Mattermost CLI](#troubleshooting-the-mattermost-cli) below.
+
+## Configuring GitLab and Mattermost integrations
+
+As of 12.3, the Mattermost GitLab plugin is shipped with Omnibus GitLab: [Mattermost Plugin for GitLab documentation](https://github.com/mattermost/mattermost-plugin-gitlab).
+
+You can use the plugin to subscribe Mattermost to receive notifications about issues, merge requests, and pull requests as well as personal notifications regarding merge request reviews, unread messages, and task assignments. If you want to use slash commands to perform actions
+such as creating and viewing issues, or to trigger deployments use GitLab [Mattermost slash commands](../../user/project/integrations/mattermost_slash_commands.md).
+
+The plugin and slash commands can be used together or individually.
+
+## Email Notifications
+
+### Setting up SMTP for GitLab Mattermost
+
+These settings are configured through the Mattermost System Console by the System Administrator.
+On the **Environment > SMTP** tab of the **System Console**, you can enter the SMTP credentials given by your SMTP provider, or `127.0.0.1` and port `25` to use `sendmail`. More information on the specific settings
+that are needed is available in the [Mattermost documentation](https://docs.mattermost.com/install/smtp-email-setup.html).
+
+These settings can also be configured in `/var/opt/gitlab/mattermost/config.json`.
+
+### Email batching
+
+Enabling this feature allows users to control how often they receive email notifications.
+
+Email batching can be enabled in the Mattermost **System Console** by going to the **Environment > SMTP** tab, and setting the **Enable Email Batching** setting to **True**.
+
+This setting can also be configured in `/var/opt/gitlab/mattermost/config.json`.
+
+## Upgrading GitLab Mattermost
+
+Below is a list of Mattermost versions for GitLab 11.10 and later:
+
+| GitLab Version | Mattermost Version |
+| :------------ |:----------------|
+| 11.11 | 5.10 |
+| 12.0 | 5.11 |
+| 12.1 | 5.12 |
+| 12.2 | 5.13 |
+| 12.3 | 5.14 |
+| 12.4 | 5.15 |
+| 12.5 | 5.16 |
+| 12.6 | 5.17 |
+| 12.7 | 5.17 |
+| 12.8 | 5.19 |
+| 12.9 | 5.20 |
+| 12.10 | 5.21 |
+| 13.0 | 5.22 |
+| 13.1 | 5.23 |
+| 13.2 | 5.24 |
+| 13.3 | 5.25 |
+| 13.4 | 5.26 |
+| 13.5 | 5.27 |
+| 13.6 | 5.28 |
+| 13.7 | 5.29 |
+| 13.8 | 5.30 |
+| 13.9 | 5.31 |
+| 13.10 | 5.32 |
+| 13.11 | 5.33 |
+| 13.12 | 5.34 |
+| 14.0 | 5.35 |
+| 14.1 | 5.36 |
+| 14.2 | 5.37 |
+| 14.3 | 5.38 |
+
+NOTE:
+When upgrading the Mattermost version, it is essential to check the
+[Important Upgrade Notes](https://docs.mattermost.com/administration/important-upgrade-notes.html)
+for Mattermost to address any changes or migrations that need to be performed.
+
+Starting with GitLab 11.0, GitLab Mattermost can be upgraded through the regular Omnibus GitLab update process. When upgrading previous versions of
+GitLab that process can only be used if Mattermost configuration settings have not been changed outside of GitLab (i.e., no changes to Mattermost's `config.json`
+file have been made, either directly or via the Mattermost **System Console** which saves back changes to `config.json`.)
+
+If you are upgrading to at least GitLab 11.0 or have only configured Mattermost using `gitlab.rb`, you can upgrade GitLab using Omnibus and then run `gitlab-ctl reconfigure` to upgrade GitLab Mattermost to the latest version.
+
+If this is not the case, there are two options:
+
+1. Update [`gitlab.rb`](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/files/gitlab-config-template/gitlab.rb.template#L706)
+ with the changes done to `config.json`. This might require adding some parameters as not all
+ settings in `config.json` are available in `gitlab.rb`. Once complete, Omnibus GitLab should be
+ able to upgrade GitLab Mattermost from one version to the next.
+1. Migrate Mattermost outside of the directory controlled by Omnibus GitLab so it can be administered
+ and upgraded independently. Follow the [Mattermost Migration Guide](https://docs.mattermost.com/administration/migrating.html)
+ to move your Mattermost configuration settings and data to another directory or server independent
+ from Omnibus GitLab.
+
+For a complete list of upgrade notices and special considerations for older versions, see the [Mattermost documentation](https://docs.mattermost.com/administration/important-upgrade-notes.html).
+
+## Upgrading GitLab Mattermost from versions prior to 11.0
+
+With version 11.0, GitLab introduced breaking changes which affected Mattermost configuration.
+In versions prior to GitLab 11.0 all
+Mattermost-related settings were configurable from the `gitlab.rb` file, which
+generated the Mattermost `config.json` file. However, Mattermost also
+permitted configuration via its System Console. This configuration ended up in
+the same `config.json` file, which resulted in changes made via the System Console being
+overwritten when users ran `gitlab-ctl reconfigure`.
+
+To resolve this problem, `gitlab.rb` includes only the
+configuration necessary for GitLab<=>Mattermost integration in 11.0. GitLab no longer
+generates the `config.json` file, and instead passes limited configuration settings via environment variables.
+
+The settings that continue to be supported in `gitlab.rb` can be found in
+[`gitlab.rb.template`](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/files/gitlab-config-template/gitlab.rb.template).
+
+From GitLab 11.0, other Mattermost settings can be configured through Mattermost's System Console,
+by editing `/var/opt/gitlab/mattermost/config.json`, or by using `mattermost['env']` in `gitlab.rb`.
+
+If you would like to keep configuring Mattermost using `gitlab.rb`, you can take the following actions
+in preparation for GitLab 11.0:
+
+1. Upgrade to version 10.x which supports the new `mattermost['env']` setting.
+1. Configure any settings not listed above through the `mattermost['env']` setting. Mattermost requires
+ environment variables to be provided in `MM_<CATEGORY>SETTINGS_<ATTRIBUTE>` format. Below is an example
+ of how to convert the old settings syntax to the new one.
+
+The following settings in `gitlab.rb`:
+
+```ruby
+mattermost['service_maximum_login_attempts'] = 10
+mattermost['team_teammate_name_display'] = "full_name"
+mattermost['sql_max_idle_conns'] = 10
+mattermost['log_file_level'] = 'INFO'
+mattermost['email_batching_interval'] = 30
+mattermost['file_enable_file_attachments'] = true
+mattermost['ratelimit_memory_store_size'] = 10000
+mattermost['support_terms_of_service_link'] = "/static/help/terms.html"
+mattermost['privacy_show_email_address'] = true
+mattermost['localization_available_locales'] = "en,es,fr,ja,pt-BR"
+mattermost['webrtc_enable'] = false
+```
+
+Would translate to:
+
+```ruby
+mattermost['env'] = {
+ 'MM_SERVICESETTINGS_MAXIMUMLOGINATTEMPTS' => '10',
+ 'MM_TEAMSETTINGS_TEAMMATENAMEDISPLAY' => 'full_name',
+ 'MM_SQLSETTINGS_MAXIDLECONNS' => '10',
+ 'MM_LOGSETTINGS_FILELEVEL' => 'INFO',
+ 'MM_EMAILSETTINGS_BATCHINGINTERVAL' => '30',
+ 'MM_FILESETTINGS_ENABLEFILEATTACHMENTS' => 'true',
+ 'MM_RATELIMITSETTINGS_MEMORYSTORESIZE' => '10000',
+ 'MM_SUPPORTSETTINGS_TERMSOFSERVICELINK' => '/static/help/terms.html',
+ 'MM_PRIVACYSETTINGS_SHOWEMAILADDRESS' => 'true',
+ 'MM_LOCALIZATIONSETTINGS_AVAILABLELOCALES' => 'en,es,fr,ja,pt-BR',
+ 'MM_WEBRTCSETTINGS_ENABLE' => 'false'
+ }
+```
+
+Refer to the [Mattermost Configuration Settings
+documentation](https://docs.mattermost.com/administration/config-settings.html)
+for details about categories, configuration values, etc.
+
+There are a few exceptions to this rule:
+
+1. `ServiceSettings.ListenAddress` configuration of Mattermost is configured
+ by `mattermost['service_address']` and `mattermost['service_port']` settings.
+1. Configuration settings named in an inconsistent way are given in the
+ following table. Use these mappings when converting them to environment
+ variables.
+
+|`gitlab.rb` configuration|Environment variable|
+|---|---|
+|`mattermost['service_lets_encrypt_cert_cache_file']`|`MM_SERVICESETTINGS_LETSENCRYPTCERTIFICATECACHEFILE`|
+|`mattermost['service_user_access_tokens']`|`MM_SERVICESETTINGS_ENABLEUSERACCESSTOKENS`|
+|`mattermost['log_console_enable']`|`MM_LOGSETTINGS_ENABLECONSOLE`|
+|`mattermost['email_enable_batching']`|`MM_EMAILSETTINGS_ENABLEEMAILBATCHING`|
+|`mattermost['email_batching_buffer_size']`|`MM_EMAILSETTINGS_EMAILBATCHINGBUFFERSIZE`|
+|`mattermost['email_batching_interval']`|`MM_EMAILSETTINGS_EMAILBATCHINGINTERVAL`|
+|`mattermost['email_smtp_auth']`|`MM_EMAILSETTINGS_ENABLESMTPAUTH`|
+|`mattermost['email_notification_content_type']`|`MM_EMAILSETTINGS_NOTIFICATIONCONTENTTYPE`|
+|`mattermost['ratelimit_enable_ratelimiter']`|`MM_RATELIMITSETTINGS_ENABLE`|
+|`mattermost['support_email']`|`MM_SUPPORTSETTINGS_SUPPORTEMAIL`|
+|`mattermost['localization_server_locale']`|`MM_LOCALIZATIONSETTINGS_DEFAULTSERVERLOCALE`|
+|`mattermost['localization_client_locale']`|`MM_LOCALIZATIONSETTINGS_DEFAULTCLIENTLOCALE`|
+|`mattermost['webrtc_gateway_stun_uri']`|`MM_WEBRTCSETTINGS_STUN_URI`|
+|`mattermost['webrtc_gateway_turn_uri']`|`MM_WEBRTCSETTINGS_TURN_URI`|
+|`mattermost['webrtc_gateway_turn_username']`|`MM_WEBRTCSETTINGS_TURN_USERNAME`|
+|`mattermost['webrtc_gateway_turn_sharedkey']`|`MM_WEBRTCSETTINGS_TURN_SHAREDKEY`|
+
+NOTE:
+GitLab 11.0 no longer generates `config.json` file from the configuration specified
+in `gitlab.rb`. Users are responsible for managing this file which can be done via the
+Mattermost System Console or manually.
+If a configuration setting is specified via both the `gitlab.rb` (as an environment variable)
+and `config.json` files, the environment variable gets precedence.
+
+If you encounter any issues [visit the GitLab Mattermost troubleshooting forum](https://forum.mattermost.org/t/upgrading-to-gitlab-mattermost-in-gitlab-8-9/1735) and share any relevant portions of `mattermost.log` along with the step at which you encountered issues.
+
+### Upgrading GitLab Mattermost outside of GitLab
+
+If you choose to upgrade Mattermost outside of the Omnibus GitLab automation, [follow this guide](https://docs.mattermost.com/administration/upgrade.html).
+
+## OAuth2 sequence diagram
+
+The following image is a sequence diagram for how GitLab works as an OAuth2
+provider for Mattermost. You can use this to troubleshoot errors
+in getting the integration to work:
+
+![sequence diagram](img/gitlab-mattermost.png)
+
+## Troubleshooting the Mattermost CLI
+
+### Failed to ping DB retrying in 10 seconds err=dial tcp: lookup dockerhost: no such host
+
+As of version 11.0, majority of the Mattermost settings are now configured via environmental variables. The error is mainly due to the database connection string being commented out in `gitlab.rb` and the database connection settings being set in environmental variables. Additionally, the connection string in the `gitlab.rb` is for MySQL which is no longer supported as of 12.1.
+
+You can fix this by setting up a `mattermost-cli` [shell alias](#mattermost-command-line-tools-cli).
+
+## Community support resources
+
+For help and support around your GitLab Mattermost deployment please see:
+
+- [Troubleshooting Forum](https://forum.mattermost.org/t/how-to-use-the-troubleshooting-forum/150) for configuration questions and issues.
+- [Troubleshooting FAQ](https://docs.mattermost.com/install/troubleshooting.html).
+- [Mattermost GitLab Issues Support Handbook](https://docs.mattermost.com/process/support.html?highlight=omnibus#gitlab-issues).
+- [GitLab Mattermost issue tracker](https://gitlab.com/gitlab-org/gitlab-mattermost/-/issues) for verified bugs with repro steps.
diff --git a/doc/integration/oauth_provider.md b/doc/integration/oauth_provider.md
index 596fff47716..5df6c4f28b7 100644
--- a/doc/integration/oauth_provider.md
+++ b/doc/integration/oauth_provider.md
@@ -4,17 +4,17 @@ group: Access
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
---
-# GitLab as OAuth2 authentication service provider
+# GitLab as an OAuth 2.0 authentication service provider
-This document describes how you can use GitLab as an OAuth 2
+This document describes how you can use GitLab as an OAuth 2.0
authentication service provider.
If you want to use:
-- The [OAuth2](https://oauth.net/2/) protocol to access GitLab resources on user's behalf,
- see [OAuth2 provider](../api/oauth2.md).
-- Other OAuth 2 authentication service providers to sign in to
- GitLab, see the [OAuth2 client documentation](omniauth.md).
+- The [OAuth 2.0](https://oauth.net/2/) protocol to access GitLab resources on
+ a user's behalf, see [OAuth 2.0 provider](../api/oauth2.md).
+- Other OAuth 2.0 authentication service providers to sign in to
+ GitLab, see the [OAuth 2.0 client documentation](omniauth.md).
- The related API, see [Applications API](../api/applications.md).
## Introduction to OAuth
@@ -48,7 +48,7 @@ To add a new application for your user:
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. In the left sidebar, select **Applications**.
+1. On the left sidebar, select **Applications**.
1. Enter a **Name**, **Redirect URI** and OAuth 2 scopes as defined in [Authorized Applications](#authorized-applications).
The **Redirect URI** is the URL where users are sent after they authorize with GitLab.
1. Select **Save application**. GitLab provides:
@@ -81,7 +81,7 @@ To add a new application for a group:
To create an application for your GitLab instance:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Applications**.
1. Select **New application**.
diff --git a/doc/integration/omniauth.md b/doc/integration/omniauth.md
index bba3252fe76..7dc775c2557 100644
--- a/doc/integration/omniauth.md
+++ b/doc/integration/omniauth.md
@@ -7,8 +7,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# OmniAuth **(FREE)**
GitLab leverages OmniAuth to allow users to sign in using Twitter, GitHub, and
-other popular services. [OmniAuth](https://rubygems.org/gems/omniauth/) is
-"a generalized Rack framework for multiple-provider authentication, built on Ruby.
+other popular services. [OmniAuth](https://rubygems.org/gems/omniauth/) is a
+"generalized Rack framework for multiple-provider authentication" built on Ruby.
Configuring OmniAuth does not prevent standard GitLab authentication or LDAP
(if configured) from continuing to work. Users can choose to sign in using any
@@ -22,36 +22,38 @@ of the configured mechanisms.
## Supported Providers
-This is a list of the current supported OmniAuth providers. Before proceeding on each provider's documentation,
-make sure to first read this document as it contains some settings that are common for all providers.
-
-|Provider documentation |OmniAuth provider name |
-|-----------------------------------------------------------------|--------------------------|
-|[Atlassian Crowd](../administration/auth/crowd.md) |`crowd` |
-|[Atlassian](../administration/auth/atlassian.md) |`atlassian_oauth2` |
-|[Auth0](auth0.md) |`auth0` |
-|[Authentiq](../administration/auth/authentiq.md) |`authentiq` |
-|[AWS Cognito](../administration/auth/cognito.md) |`cognito` |
-|[Azure v2](azure.md#microsoft-azure-oauth2-omniauth-provider-v2) |`azure_activedirectory_v2`|
-|[Azure v1](azure.md) |`azure_oauth2` |
-|[Bitbucket Cloud](bitbucket.md) |`bitbucket` |
-|[CAS](cas.md) |`cas3` |
-|[Facebook](facebook.md) |`facebook` |
-|[Generic OAuth2](oauth2_generic.md) |`oauth2_generic` |
-|[GitHub](github.md) |`github` |
-|[GitLab.com](gitlab.md) |`gitlab` |
-|[Google](google.md) |`google_oauth2` |
-|[JWT](../administration/auth/jwt.md) |`jwt` |
-|[Kerberos](kerberos.md) |`kerberos` |
-|[OpenID Connect](../administration/auth/oidc.md) |`openid_connect` |
-|[Salesforce](salesforce.md) |`salesforce` |
-|[SAML](saml.md) |`saml` |
-|[Shibboleth](shibboleth.md) |`shibboleth` |
-|[Twitter](twitter.md) |`twitter` |
+This is a list of the current supported OmniAuth providers. Before proceeding on
+each provider's documentation, make sure to first read this document as it
+contains some settings that are common for all providers.
+
+| Provider documentation | OmniAuth provider name |
+|---------------------------------------------------------------------|----------------------------|
+| [Atlassian Crowd](../administration/auth/crowd.md) | `crowd` |
+| [Atlassian](../administration/auth/atlassian.md) | `atlassian_oauth2` |
+| [Auth0](auth0.md) | `auth0` |
+| [Authentiq](../administration/auth/authentiq.md) | `authentiq` |
+| [AWS Cognito](../administration/auth/cognito.md) | `cognito` |
+| [Azure v2](azure.md#microsoft-azure-oauth-20-omniauth-provider-v2) | `azure_activedirectory_v2` |
+| [Azure v1](azure.md) | `azure_oauth2` |
+| [Bitbucket Cloud](bitbucket.md) | `bitbucket` |
+| [CAS](cas.md) | `cas3` |
+| [Facebook](facebook.md) | `facebook` |
+| [Generic OAuth 2.0](oauth2_generic.md) | `oauth2_generic` |
+| [GitHub](github.md) | `github` |
+| [GitLab.com](gitlab.md) | `gitlab` |
+| [Google](google.md) | `google_oauth2` |
+| [JWT](../administration/auth/jwt.md) | `jwt` |
+| [Kerberos](kerberos.md) | `kerberos` |
+| [OpenID Connect](../administration/auth/oidc.md) | `openid_connect` |
+| [Salesforce](salesforce.md) | `salesforce` |
+| [SAML](saml.md) | `saml` |
+| [Shibboleth](shibboleth.md) | `shibboleth` |
+| [Twitter](twitter.md) | `twitter` |
## Initial OmniAuth Configuration
-The OmniAuth provider names from the table above are needed to configure a few global settings that are in common for all providers.
+The OmniAuth provider names from the table above are needed to configure a few
+global settings that are in common for all providers.
NOTE:
Starting from GitLab 11.4, OmniAuth is enabled by default. If you're using an
@@ -65,18 +67,19 @@ earlier version, you must explicitly enable it.
gitlab_rails['omniauth_allow_single_sign_on'] = ['azure_activedirectory_v2', 'google_oauth2']
```
- The value defaults to `false`. If `false` users must be created manually, or they can't sign in by using OmniAuth.
+ The value defaults to `false`. If `false` users must be created manually, or
+ they can't sign in by using OmniAuth.
+
- `auto_link_ldap_user` can be used if you have [LDAP / ActiveDirectory](../administration/auth/ldap/index.md)
integration enabled. It defaults to `false`. When enabled, users automatically
created through an OmniAuth provider have their LDAP identity created in GitLab as well.
-- `block_auto_created_users` defaults to `true`. If `true` auto created users will
- be blocked by default and must be unblocked by an administrator before
- they are able to sign in.
+- `block_auto_created_users` defaults to `true`. If `true`, auto created users will
+ be blocked pending approval by an administrator before they are able to sign in.
NOTE:
If you set `block_auto_created_users` to `false`, make sure to only
define providers under `allow_single_sign_on` that you are able to control, like
-SAML, Shibboleth, Crowd, or Google. Otherwise, set it to `false`, or any user on
+SAML, Shibboleth, Crowd, or Google. Otherwise, set it to `true`, or any user on
the Internet can successfully sign in to your GitLab without
administrative approval.
@@ -150,7 +153,7 @@ OmniAuth provider for an existing user.
1. Sign in normally - whether standard sign in, LDAP, or another OmniAuth provider.
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. In the left sidebar, select **Account**.
+1. On the left sidebar, select **Account**.
1. In the **Connected Accounts** section, select the desired OmniAuth provider, such as Twitter.
1. The user is redirected to the provider. After the user authorizes GitLab,
they are redirected back to GitLab.
@@ -166,23 +169,21 @@ Automatic linking using this method works for all providers
[except the SAML provider](https://gitlab.com/gitlab-org/gitlab/-/issues/338293). For automatic
linking using the SAML provider, see [SAML-specific](saml.md#general-setup) instructions.
-As an example, the following configuration is used to enable the auto link feature for both:
-
-- OpenID Connect provider.
-- Twitter OAuth provider.
+As an example, the following configuration is used to enable the auto link
+feature for both an **OpenID Connect provider** and a **Twitter OAuth provider**.
-**For Omnibus installations**
+- **For Omnibus installations**
-```ruby
-gitlab_rails['omniauth_auto_link_user'] = ["openid_connect", "twitter"]
-```
+ ```ruby
+ gitlab_rails['omniauth_auto_link_user'] = ["openid_connect", "twitter"]
+ ```
-**For installations from source**
+- **For installations from source**
-```yaml
-omniauth:
- auto_link_user: ["openid_connect", "twitter"]
-```
+ ```yaml
+ omniauth:
+ auto_link_user: ["openid_connect", "twitter"]
+ ```
## Configure OmniAuth Providers as External
@@ -197,18 +198,18 @@ If you decide to remove an OmniAuth provider from the external providers list,
you must manually update the users that use this method to sign in if you want
their accounts to be upgraded to full internal accounts.
-**For Omnibus installations**
+- **For Omnibus installations**
-```ruby
-gitlab_rails['omniauth_external_providers'] = ['twitter', 'google_oauth2']
-```
+ ```ruby
+ gitlab_rails['omniauth_external_providers'] = ['twitter', 'google_oauth2']
+ ```
-**For installations from source**
+- **For installations from source**
-```yaml
-omniauth:
- external_providers: ['twitter', 'google_oauth2']
-```
+ ```yaml
+ omniauth:
+ external_providers: ['twitter', 'google_oauth2']
+ ```
## Using Custom OmniAuth Providers
@@ -217,7 +218,7 @@ The following information only applies for installations from source.
GitLab uses [OmniAuth](https://github.com/omniauth/omniauth) for authentication and already ships
with a few providers pre-installed, such as LDAP, GitHub, and Twitter. You may also
-need to integrate with other authentication solutions. For
+have to integrate with other authentication solutions. For
these cases, you can use the OmniAuth provider.
### Steps
@@ -268,8 +269,8 @@ By default, **Sign In** is enabled by using all the OAuth Providers that have be
To enable/disable an OmniAuth provider:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, go to **Settings**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, go to **Settings**.
1. Scroll to the **Sign-in Restrictions** section, and click **Expand**.
1. Below **Enabled OAuth Sign-In sources**, select the checkbox for each provider you want to enable or disable.
@@ -283,18 +284,18 @@ has an effect if providers are configured and [enabled](#enable-or-disable-sign-
If OmniAuth providers are causing problems even when individually disabled, you
can disable the entire OmniAuth subsystem by modifying the configuration file:
-**For Omnibus installations**
+- **For Omnibus installations**
-```ruby
-gitlab_rails['omniauth_enabled'] = false
-```
+ ```ruby
+ gitlab_rails['omniauth_enabled'] = false
+ ```
-**For installations from source**
+- **For installations from source**:
-```yaml
-omniauth:
- enabled: false
-```
+ ```yaml
+ omniauth:
+ enabled: false
+ ```
## Keep OmniAuth user profiles up to date
@@ -302,18 +303,20 @@ You can enable profile syncing from selected OmniAuth providers and for all or f
When authenticating using LDAP, the user's name and email are always synced.
-```ruby
-gitlab_rails['omniauth_sync_profile_from_provider'] = ['twitter', 'google_oauth2']
-gitlab_rails['omniauth_sync_profile_attributes'] = ['name', 'email', 'location']
-```
+- **For Omnibus installations**
+
+ ```ruby
+ gitlab_rails['omniauth_sync_profile_from_provider'] = ['twitter', 'google_oauth2']
+ gitlab_rails['omniauth_sync_profile_attributes'] = ['name', 'email', 'location']
+ ```
-**For installations from source**
+- **For installations from source**
-```yaml
-omniauth:
- sync_profile_from_provider: ['twitter', 'google_oauth2']
- sync_profile_attributes: ['email', 'location']
-```
+ ```yaml
+ omniauth:
+ sync_profile_from_provider: ['twitter', 'google_oauth2']
+ sync_profile_attributes: ['email', 'location']
+ ```
## Bypassing two factor authentication
@@ -325,16 +328,18 @@ or as `true` or `false` to allow all providers (or none). This option should be
configured only for providers which already have two factor authentication
(default: false). This configuration doesn't apply to SAML.
-```ruby
-gitlab_rails['omniauth_allow_bypass_two_factor'] = ['twitter', 'google_oauth2']
-```
+- **For Omnibus package**
-**For installations from source**
+ ```ruby
+ gitlab_rails['omniauth_allow_bypass_two_factor'] = ['twitter', 'google_oauth2']
+ ```
+
+- **For installations from source**
-```yaml
-omniauth:
- allow_bypass_two_factor: ['twitter', 'google_oauth2']
-```
+ ```yaml
+ omniauth:
+ allow_bypass_two_factor: ['twitter', 'google_oauth2']
+ ```
## Automatically sign in with provider
@@ -342,25 +347,25 @@ You can add the `auto_sign_in_with_provider` setting to your GitLab
configuration to redirect login requests to your OmniAuth provider for
authentication. This removes the need to click a button before actually signing in.
-For example, when using the [Azure v2 integration](azure.md#microsoft-azure-oauth2-omniauth-provider-v2), set the following to enable auto
+For example, when using the [Azure v2 integration](azure.md#microsoft-azure-oauth-20-omniauth-provider-v2), set the following to enable auto
sign-in:
-For Omnibus package:
+- **For Omnibus package**
-```ruby
-gitlab_rails['omniauth_auto_sign_in_with_provider'] = 'azure_activedirectory_v2'
-```
+ ```ruby
+ gitlab_rails['omniauth_auto_sign_in_with_provider'] = 'azure_activedirectory_v2'
+ ```
-For installations from source:
+- **For installations from source**
-```yaml
-omniauth:
- auto_sign_in_with_provider: azure_activedirectory_v2
-```
+ ```yaml
+ omniauth:
+ auto_sign_in_with_provider: azure_activedirectory_v2
+ ```
Keep in mind that every sign-in attempt is redirected to the OmniAuth
provider; you can't sign in using local credentials. Ensure at least
-one of the OmniAuth users has administrator permissions.
+one of the OmniAuth users has an administrator role.
You may also bypass the auto sign in feature by browsing to
`https://gitlab.example.com/users/sign_in?auto_sign_in=false`.
@@ -378,18 +383,22 @@ After you ensure your image is optimized for rendering at 64 x 64 pixels,
you can override this icon in one of two ways:
- **Provide a custom image path**:
+
1. *If you are hosting the image outside of your GitLab server domain,* ensure
your [content security policies](https://docs.gitlab.com/omnibus/settings/configuration.html#content-security-policy)
are configured to allow access to the image file.
1. Depending on your method of installing GitLab, add a custom `icon` parameter
to your GitLab configuration file. Read [OpenID Connect OmniAuth provider](../administration/auth/oidc.md)
for an example for the OpenID Connect provider.
+
- **Directly embed an image in a configuration file**: This example creates a Base64-encoded
version of your image you can serve through a
[Data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs):
+
1. Encode your image file with GNU `base64` command (such as `base64 -w 0 <logo.png>`)
which returns a single-line `<base64-data>` string.
- 1. Add the Base64-encoded data to a custom `icon` parameter in your GitLab configuration file:
+ 1. Add the Base64-encoded data to a custom `icon` parameter in your GitLab
+ configuration file:
```yaml
omniauth:
diff --git a/doc/integration/openid_connect_provider.md b/doc/integration/openid_connect_provider.md
index 84457485382..dd65fb4822a 100644
--- a/doc/integration/openid_connect_provider.md
+++ b/doc/integration/openid_connect_provider.md
@@ -49,6 +49,7 @@ The following user information is shared with clients:
| `website` | `string` | URL for the user's website
| `profile` | `string` | URL for the user's GitLab profile
| `picture` | `string` | URL for the user's GitLab avatar
-| `groups` | `array` | Names of the groups the user is a member of
+| `groups` | `array` | Paths for the groups the user is a member of, either directly or through an ancestor group.
+| `groups_direct` | `array` | Paths for the groups the user is a direct member of.
-The claims `sub`, `sub_legacy`, `email` and `email_verified` are included in the ID token, all other claims are available from the `/oauth/userinfo` endpoint used by OIDC clients.
+The claims `sub`, `sub_legacy`, `email`, `email_verified` and `groups_direct` are included in the ID token. All other claims are available from the `/oauth/userinfo` endpoint used by OIDC clients.
diff --git a/doc/integration/recaptcha.md b/doc/integration/recaptcha.md
index 656ed8b8647..fd5170d615f 100644
--- a/doc/integration/recaptcha.md
+++ b/doc/integration/recaptcha.md
@@ -18,21 +18,23 @@ To use reCAPTCHA, first you must create a site and private key.
1. Fill out the form necessary to obtain reCAPTCHA v2 keys.
1. Log in to your GitLab server, with administrator credentials.
1. Go to Reporting Applications Settings in the Admin Area (`admin/application_settings/reporting`).
+1. Expand the **Spam and Anti-bot Protection** section.
1. Fill all reCAPTCHA fields with keys from previous steps.
-1. Check the `Enable reCAPTCHA` checkbox.
+1. Select the **Enable reCAPTCHA** checkbox.
+1. To enable reCAPTCHA for logins via password, select the **Enable reCAPTCHA for login** checkbox.
1. Save the configuration.
1. Change the first line of the `#execute` method in `app/services/spam/spam_verdict_service.rb`
- to `return CONDITONAL_ALLOW` so that the spam check short-circuits and triggers the response to
+ to `return CONDITIONAL_ALLOW` so that the spam check short-circuits and triggers the response to
return `recaptcha_html`.
NOTE:
Make sure you are viewing an issuable in a project that is public. If you're working with an issue, the issue is public.
-## Enabling reCAPTCHA for user logins via passwords
+## Enable reCAPTCHA for user logins using the HTTP header
-By default, reCAPTCHA is only enabled for user registrations. To enable it for
-user logins via passwords, the `X-GitLab-Show-Login-Captcha` HTTP header must
-be set. For example, in NGINX, this can be done via the `proxy_set_header`
+You can enable reCAPTCHA for user logins via password [in the user interface](#configuration)
+or by setting the `X-GitLab-Show-Login-Captcha` HTTP header.
+For example, in NGINX, this can be done via the `proxy_set_header`
configuration variable:
```nginx
diff --git a/doc/integration/saml.md b/doc/integration/saml.md
index ee3e2f574c7..b89772ba2ca 100644
--- a/doc/integration/saml.md
+++ b/doc/integration/saml.md
@@ -7,9 +7,11 @@ type: reference
# SAML OmniAuth Provider **(FREE SELF)**
-This page describes instance-wide SAML for self-managed GitLab instances. For SAML on GitLab.com, see [SAML SSO for GitLab.com groups](../user/group/saml_sso/index.md).
+This page describes instance-wide SAML for self-managed GitLab instances. For
+SAML on GitLab.com, see [SAML SSO for GitLab.com groups](../user/group/saml_sso/index.md).
-You should also reference the [OmniAuth documentation](omniauth.md) for general settings that apply to all OmniAuth providers.
+You should also reference the [OmniAuth documentation](omniauth.md) for general
+settings that apply to all OmniAuth providers.
## Glossary of common terms
@@ -19,7 +21,7 @@ You should also reference the [OmniAuth documentation](omniauth.md) for general
| Service provider (SP) | GitLab can be configured as a SAML 2.0 SP. |
| Assertion | A piece of information about a user's identity, such as their name or role. Also known as claims or attributes. |
| Single Sign-On (SSO) | Name of authentication scheme. |
-| Assertion consumer service URL | The callback on GitLab where users will be redirected after successfully authenticating with the identity provider. |
+| Assertion consumer service URL | The callback on GitLab where users are redirected after successfully authenticating with the identity provider. |
| Issuer | How GitLab identifies itself to the identity provider. Also known as a "Relying party trust identifier". |
| Certificate fingerprint | Used to confirm that communications over SAML are secure by checking that the server is signing communications with the correct certificate. Also known as a certificate thumbprint. |
@@ -209,7 +211,7 @@ for a full list of supported assertions.
## SAML Groups
-You can require users to be members of a certain group, or assign users [external](../user/permissions.md#external-users), admin or [auditor](../user/permissions.md#auditor-users) roles based on group membership.
+You can require users to be members of a certain group, or assign users [external](../user/permissions.md#external-users), administrator or [auditor](../user/permissions.md#auditor-users) roles based on group membership.
These groups are checked on each SAML login and user attributes updated as necessary.
This feature **does not** allow you to
automatically add users to GitLab [Groups](../user/group/index.md).
@@ -221,13 +223,13 @@ and whether you've installed [GitLab Enterprise Edition (EE)](https://about.gitl
|------------------------------|--------------------|--------------------------------------|
| [Required](#required-groups) | **(FREE SELF)** | Yes |
| [External](#external-groups) | **(FREE SELF)** | No |
-| [Admin](#admin-groups) | **(FREE SELF)** | Yes |
+| [Admin](#administrator-groups) | **(FREE SELF)** | Yes |
| [Auditor](#auditor-groups) | **(PREMIUM SELF)** | Yes |
### Requirements
-First you need to tell GitLab where to look for group information. For this you
-need to make sure that your IdP server sends a specific `AttributeStatement` along
+First tell GitLab where to look for group information. For this, you
+must make sure that your IdP server sends a specific `AttributeStatement` along
with the regular SAML response. Here is an example:
```xml
@@ -242,17 +244,18 @@ with the regular SAML response. Here is an example:
```
The name of the attribute can be anything you like, but it must contain the groups
-to which a user belongs. In order to tell GitLab where to find these groups, you need
+to which a user belongs. To tell GitLab where to find these groups, you need
to add a `groups_attribute:` element to your SAML settings.
### Required groups **(FREE SELF)**
-Your IdP passes Group Information to the SP (GitLab) in the SAML Response. You need to configure GitLab to identify:
+Your IdP passes Group information to the SP (GitLab) in the SAML Response.
+To use this response, configure GitLab to identify:
- Where to look for the groups in the SAML response via the `groups_attribute` setting
- Which group membership is requisite to sign in via the `required_groups` setting
-When `required_groups` is not set or it is empty, anyone with proper authentication
+When `required_groups` is empty or not set, anyone with proper authentication
is able to use the service.
Example:
@@ -273,7 +276,9 @@ Example:
### External groups **(FREE SELF)**
-SAML login supports automatic identification on whether a user should be considered an [external user](../user/permissions.md#external-users). This is based on the user's group membership in the SAML identity provider.
+SAML login supports the automatic identification of a user as an
+[external user](../user/permissions.md#external-users). This is based on the user's group
+membership in the SAML identity provider.
```yaml
{ name: 'saml',
@@ -289,11 +294,13 @@ SAML login supports automatic identification on whether a user should be conside
} }
```
-### Admin groups **(FREE SELF)**
+### Administrator groups **(FREE SELF)**
-The requirements are the same as the previous settings, your IdP needs to pass Group information to GitLab, you need to tell
-GitLab where to look for the groups in the SAML response, and which group(s) should be
-considered admin users.
+The requirements are the same as the previous settings:
+
+- The IdP must pass Group information to GitLab.
+- GitLab must know where to look for the groups in the SAML response, as well as
+ which group(s) grant the user an administrator role.
```yaml
{ name: 'saml',
@@ -313,9 +320,11 @@ considered admin users.
> Introduced in GitLab 11.4.
-The requirements are the same as the previous settings, your IdP needs to pass Group information to GitLab, you need to tell
-GitLab where to look for the groups in the SAML response, and which group(s) should be
-considered [auditor users](../user/permissions.md#auditor-users).
+The requirements are the same as the previous settings:
+
+- The IdP must pass Group information to GitLab.
+- GitLab should know where to look for the groups in the SAML response, as well as which
+ group(s) entail that a given user is an [auditor user](../user/permissions.md#auditor-users).
```yaml
{ name: 'saml',
@@ -333,8 +342,8 @@ considered [auditor users](../user/permissions.md#auditor-users).
## Bypass two factor authentication
-If you want some SAML authentication methods to count as 2FA on a per session basis, you can register them in the
-`upstream_two_factor_authn_contexts` list.
+If you want some SAML authentication methods to count as 2FA on a per session
+basis, you can register them in the `upstream_two_factor_authn_contexts` list.
In addition to the changes in GitLab, make sure that your IdP is returning the
`AuthnContext`. For example:
@@ -411,7 +420,7 @@ In addition to the changes in GitLab, make sure that your IdP is returning the
### `auto_sign_in_with_provider`
You can add this setting to your GitLab configuration to automatically redirect you
-to your SAML server for authentication, thus removing the need to click a button
+to your SAML server for authentication. This removes the requirement to click a button
before actually signing in.
For Omnibus package:
@@ -429,7 +438,7 @@ omniauth:
Keep in mind that every sign in attempt redirects to the SAML server;
you cannot sign in using local credentials. Ensure at least one of the
-SAML users has admin permissions.
+SAML users has an administrator role.
You may also bypass the auto sign-in feature by browsing to
`https://gitlab.example.com/users/sign_in?auto_sign_in=false`.
@@ -464,9 +473,14 @@ args: {
}
```
-#### Setting a username
+#### Set a username
+
+By default, the email in the SAML response is used to automatically generate the
+user's GitLab username. If you'd like to set another attribute as the username,
+assign it to the `nickname` OmniAuth `info` hash attribute.
-By default, the email in the SAML response is used to automatically generate the user's GitLab username. If you'd like to set another attribute as the username, assign it to the `nickname` OmniAuth `info` hash attribute. For example, if you wanted to set the `username` attribute in your SAML Response to the username in GitLab, use the following setting:
+For example, if you want to set the `username` attribute in your SAML Response to the username
+in GitLab, use the following setting:
```yaml
args: {
@@ -482,7 +496,7 @@ args: {
### `allowed_clock_drift`
The clock of the Identity Provider may drift slightly ahead of your system clocks.
-To allow for a small amount of clock drift you can use `allowed_clock_drift` within
+To allow for a small amount of clock drift, you can use `allowed_clock_drift` in
your settings. Its value must be given in a number (and/or fraction) of seconds.
The value given is added to the current time at which the response is validated.
@@ -572,7 +586,8 @@ This may be the case, for example, if you terminate TLS encryption early at a lo
balancer and include sensitive details in assertions that you do not want appearing
in logs. Most organizations should not need additional encryption at this layer.
-The SAML integration supports EncryptedAssertion. You need to define the private key and the public certificate of your GitLab instance in the SAML settings:
+The SAML integration supports EncryptedAssertion. You should define the private
+key and the public certificate of your GitLab instance in the SAML settings:
```yaml
args: {
@@ -602,7 +617,7 @@ SAML Requests use the SAML redirect binding, so this isn't necessary (unlike the
SAML POST binding, where signing is required to prevent intermediaries from
tampering with the requests).
-To sign, you need to create a private key and public certificate pair for your
+To sign, create a private key and public certificate pair for your
GitLab instance to use for SAML. The settings for signing can be set in the
`security` section of the configuration.
@@ -653,7 +668,7 @@ The [Generated passwords for users created through integrated authentication](..
For information on the GitLab.com implementation, please see the [SAML SSO for GitLab.com groups page](../user/group/saml_sso).
-Group SAML SSO helps if you need to allow access via multiple SAML identity providers, but as a multi-tenant solution is less suited to cases where you administer your own GitLab instance.
+Group SAML SSO helps if you have to allow access via multiple SAML identity providers, but as a multi-tenant solution is less suited to cases where you administer your own GitLab instance.
To proceed with configuring Group SAML SSO instead, enable the `group_saml` OmniAuth provider. This can be done from:
@@ -668,7 +683,7 @@ Group SAML on a self-managed instance is limited when compared to the recommende
- [LDAP compatibility](../administration/auth/ldap/index.md).
- [LDAP Group Sync](../user/group/index.md#manage-group-memberships-via-ldap).
- [Required groups](#required-groups).
-- [Admin groups](#admin-groups).
+- [Administrator groups](#administrator-groups).
- [Auditor groups](#auditor-groups).
### Omnibus installations
@@ -750,7 +765,7 @@ Make sure you have access to a Google Workspace [Super Admin](https://support.go
| First name | `first_name` | Required value to communicate with GitLab. |
| Last name | `last_name` | Required value to communicate with GitLab. |
-You also need to setup the following SAML attribute mappings:
+You also must setup the following SAML attribute mappings:
| Google Directory attributes | App attributes |
|-----------------------------------|----------------|
@@ -767,8 +782,9 @@ When configuring the Google Workspace SAML app, be sure to record the following
| SSO URL | Depends | Google Identity Provider details. Set to the GitLab `idp_sso_target_url` setting. |
| Certificate | Downloadable | Run `openssl x509 -in <your_certificate.crt> -noout -fingerprint` to generate the SHA1 fingerprint that can be used in the `idp_cert_fingerprint` setting. |
-While the Google Workspace Admin provides IdP metadata, Entity ID and SHA-256 fingerprint,
-GitLab does not need that information to connect to the Google Workspace SAML app.
+While the Google Workspace Admin provides IdP metadata, Entity ID, and SHA-256
+fingerprint, they are not required. GitLab does not need that information to
+connect to the Google Workspace SAML app.
## Troubleshooting
@@ -778,9 +794,10 @@ You can find the base64-encoded SAML Response in the [`production_json.log`](../
### GitLab+SAML Testing Environments
-If you need to troubleshoot, [a complete GitLab+SAML testing environment using Docker compose](https://gitlab.com/gitlab-com/support/toolbox/replication/tree/master/compose_files) is available.
+To troubleshoot, [a complete GitLab+SAML testing environment using Docker compose](https://gitlab.com/gitlab-com/support/toolbox/replication/tree/master/compose_files)
+is available.
-If you only need a SAML provider for testing, a [quick start guide to start a Docker container](../administration/troubleshooting/test_environments.md#saml) with a plug and play SAML 2.0 Identity Provider (IdP) is available.
+If you only require a SAML provider for testing, a [quick start guide to start a Docker container](../administration/troubleshooting/test_environments.md#saml) with a plug and play SAML 2.0 Identity Provider (IdP) is available.
### 500 error after login
@@ -794,8 +811,8 @@ claim name `email` or `mail`.
### 422 error after login
If you see a "422 error" in GitLab when you are redirected from the SAML
-sign-in page, you might have an incorrectly configured assertion consumer
-service (ACS) URL on the identity provider.
+sign-in page, you might have an incorrectly configured Assertion Consumer
+Service (ACS) URL on the identity provider.
Make sure the ACS URL points to `https://gitlab.example.com/users/auth/saml/callback`, where
`gitlab.example.com` is the URL of your GitLab instance.
@@ -845,14 +862,17 @@ is not providing this information, all SAML requests fail.
Make sure this information is provided.
-Another issue that can result in this error is when the correct information is being sent by the IdP, but the attributes don't match the names in the OmniAuth `info` hash. In this case, you need to set `attribute_statements` in the SAML configuration to [map the attribute names in your SAML Response to the corresponding OmniAuth `info` hash names](#attribute_statements).
+Another issue that can result in this error is when the correct information is being sent by
+the IdP, but the attributes don't match the names in the OmniAuth `info` hash. In this case,
+you must set `attribute_statements` in the SAML configuration to [map the attribute names in
+your SAML Response to the corresponding OmniAuth `info` hash names](#attribute_statements).
### Key validation error, Digest mismatch or Fingerprint mismatch
These errors all come from a similar place, the SAML certificate. SAML requests
-need to be validated using a fingerprint, a certificate or a validator.
+must be validated using either a fingerprint, a certificate, or a validator.
-For this you need to take the following into account:
+For this requirement, be sure to take the following into account:
- If a fingerprint is used, it must be the SHA1 fingerprint
- If no certificate is provided in the settings, a fingerprint or fingerprint
diff --git a/doc/integration/slash_commands.md b/doc/integration/slash_commands.md
index b9b5f394e3c..4059aef9de3 100644
--- a/doc/integration/slash_commands.md
+++ b/doc/integration/slash_commands.md
@@ -4,36 +4,40 @@ group: Integrations
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
---
-# Slash Commands **(FREE)**
+# Slash commands in Mattermost and Slack **(FREE)**
> - [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/24780) to GitLab Free in 11.9.
-Slash commands in Mattermost and Slack allow you to control GitLab and view GitLab content right inside your chat client, without having to leave it. For Slack, this requires an [integration configuration](../user/project/integrations/slack_slash_commands.md). Type the command as a message in your chat client to activate it.
+If you want to control and view GitLab content while you're
+working in Slack and Mattermost, you can use slash commands.
+Type the command as a message in your chat client to activate it.
+For Slack, this requires an [integration configuration](../user/project/integrations/slack_slash_commands.md).
-Commands are scoped to a project, with a trigger term that is specified during configuration.
+Slash commands are scoped to a project
+and require the trigger command specified during configuration.
-We suggest you use the project name as the trigger term for simplicity and clarity.
+We suggest you use the project name as the trigger command for simplicity and clarity.
-Taking the trigger term as `project-name`, the commands are:
+Assuming `project-name` is the trigger command, the slash commands are:
| Command | Effect |
| ------- | ------ |
-| `/project-name help` | Shows all available slash commands |
-| `/project-name issue new <title> <shift+return> <description>` | Creates a new issue with title `<title>` and description `<description>` |
-| `/project-name issue show <id>` | Shows the issue with ID `<id>` |
-| `/project-name issue close <id>` | Closes the issue with ID `<id>` |
-| `/project-name issue search <query>` | Shows up to 5 issues matching `<query>` |
-| `/project-name issue move <id> to <project>` | Moves issue ID `<id>` to `<project>` |
-| `/project-name issue comment <id> <shift+return> <comment>` | Adds a new comment to an issue with ID `<id>` and comment body `<comment>` |
-| `/project-name deploy <from> to <to>` | Deploy from the `<from>` environment to the `<to>` environment |
-| `/project-name run <job name> <arguments>` | Execute [ChatOps](../ci/chatops/index.md) job `<job name>` on the default branch |
+| `/project-name help` | Shows all available slash commands. |
+| `/project-name issue new <title> <shift+return> <description>` | Creates a new issue with title `<title>` and description `<description>`. |
+| `/project-name issue show <id>` | Shows the issue with ID `<id>`. |
+| `/project-name issue close <id>` | Closes the issue with ID `<id>`. |
+| `/project-name issue search <query>` | Shows up to 5 issues matching `<query>`. |
+| `/project-name issue move <id> to <project>` | Moves the issue with ID `<id>` to `<project>`. |
+| `/project-name issue comment <id> <shift+return> <comment>` | Adds a new comment with comment body `<comment>` to the issue with ID `<id>`. |
+| `/project-name deploy <from> to <to>` | [Deploys](#deploy-command) from the `<from>` environment to the `<to>` environment. |
+| `/project-name run <job name> <arguments>` | Executes the [ChatOps](../ci/chatops/index.md) job `<job name>` on the default branch. |
If you are using the [GitLab Slack application](../user/project/integrations/gitlab_slack_application.md) for
your GitLab.com projects, [add the `gitlab` keyword at the beginning of the command](../user/project/integrations/gitlab_slack_application.md#usage).
## Issue commands
-It's possible to create new issue, display issue details and search up to 5 issues.
+You can create a new issue, display issue details, and search up to 5 issues.
## Deploy command
@@ -41,7 +45,7 @@ To deploy to an environment, GitLab tries to find a deployment
manual action in the pipeline.
If there's only one action for a given environment, it is triggered.
-If more than one action is defined, GitLab tries to find an action
-which name equals the environment name we want to deploy to.
+If more than one action is defined, GitLab finds an action
+name that equals the environment name to deploy to.
-The command returns an error when no matching action has been found.
+The command returns an error if no matching action is found.
diff --git a/doc/integration/sourcegraph.md b/doc/integration/sourcegraph.md
index 86ca389e9b2..6f0027aedc7 100644
--- a/doc/integration/sourcegraph.md
+++ b/doc/integration/sourcegraph.md
@@ -76,8 +76,8 @@ You can skip this step if you already have your GitLab repositories searchable i
### Configure your GitLab instance with Sourcegraph
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Sourcegraph** configuration section.
1. Check **Enable Sourcegraph**.
1. Set the Sourcegraph URL to your Sourcegraph instance, such as `https://sourcegraph.example.com`.
diff --git a/doc/integration/trello_power_up.md b/doc/integration/trello_power_up.md
index df1d9270bd5..96150440e53 100644
--- a/doc/integration/trello_power_up.md
+++ b/doc/integration/trello_power_up.md
@@ -42,7 +42,7 @@ To find it in GitLab:
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. In the left sidebar, select **Access Tokens**.
+1. On the left sidebar, select **Access Tokens**.
Learn more about generating a personal access token in the
[Personal Access Token Documentation](../user/profile/personal_access_tokens.md).
diff --git a/doc/integration/twitter.md b/doc/integration/twitter.md
index 1d711ea271e..6bc467ed7b2 100644
--- a/doc/integration/twitter.md
+++ b/doc/integration/twitter.md
@@ -4,9 +4,10 @@ group: Integrations
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
---
-# Twitter OAuth2 OmniAuth Provider **(FREE)**
+# Twitter OAuth 2.0 OmniAuth Provider **(FREE)**
-To enable the Twitter OmniAuth provider you must register your application with Twitter. Twitter generates a client ID and secret key for you to use.
+To enable the Twitter OmniAuth provider you must register your application with
+Twitter. Twitter generates a client ID and secret key for you to use.
1. Sign in to [Twitter Application Management](https://developer.twitter.com/apps).
diff --git a/doc/integration/vault.md b/doc/integration/vault.md
index c98990bcb0e..ebfa91c7516 100644
--- a/doc/integration/vault.md
+++ b/doc/integration/vault.md
@@ -23,7 +23,7 @@ The following assumes you already have Vault installed and running.
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
- 1. In the left sidebar, select **Applications**.
+ 1. On the left sidebar, select **Applications**.
1. Fill out the application **Name** and [**Redirect URI**](https://www.vaultproject.io/docs/auth/jwt#redirect-uris).
1. Select the **OpenID** scope.
1. Select **Save application**.
diff --git a/doc/intro/index.md b/doc/intro/index.md
index a40293955a9..af50726e30c 100644
--- a/doc/intro/index.md
+++ b/doc/intro/index.md
@@ -1,49 +1,9 @@
---
-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"
-comments: false
+redirect_to: '../topics/use_gitlab.md'
+remove_date: '2021-12-08'
---
-# Get started with GitLab **(FREE)**
+This document was moved to [another location](../topics/use_gitlab.md).
-## Organize
-
-Create projects and groups.
-
-- [Create a new project](../user/project/working_with_projects.md#create-a-project)
-- [Create a new group](../user/group/index.md#create-a-group)
-
-## Prioritize
-
-Create issues, labels, milestones, cast your vote, and review issues.
-
-- [Create an issue](../user/project/issues/managing_issues.md#create-a-new-issue)
-- [Assign labels to issues](../user/project/labels.md)
-- [Use milestones as an overview of your project's tracker](../user/project/milestones/index.md)
-- [Use voting to express your like/dislike to issues and merge requests](../user/award_emojis.md)
-
-## Collaborate
-
-Create merge requests and review code.
-
-- [Fork a project and contribute to it](../user/project/repository/forking_workflow.md)
-- [Create a new merge request](../user/project/merge_requests/creating_merge_requests.md)
-- [Automatically close issues from merge requests](../user/project/issues/managing_issues.md#closing-issues-automatically)
-- [Automatically merge when pipeline succeeds](../user/project/merge_requests/merge_when_pipeline_succeeds.md)
-- [Revert any commit](../user/project/merge_requests/revert_changes.md)
-- [Cherry-pick any commit](../user/project/merge_requests/cherry_pick_changes.md)
-
-## Test and Deploy
-
-Use the built-in continuous integration in GitLab.
-
-- [Get started with GitLab CI/CD](../ci/quick_start/index.md)
-
-## Install and Update
-
-Install and update your GitLab installation.
-
-- [Install GitLab](https://about.gitlab.com/install/)
-- [Update GitLab](https://about.gitlab.com/update/)
-- [Explore Omnibus GitLab configuration options](https://docs.gitlab.com/omnibus/settings/configuration.html)
+<!-- This redirect file can be deleted after <2021-12-08>. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/operations/error_tracking.md b/doc/operations/error_tracking.md
index 9234ca36634..e694105d794 100644
--- a/doc/operations/error_tracking.md
+++ b/doc/operations/error_tracking.md
@@ -50,7 +50,7 @@ You may also want to enable Sentry's GitLab integration by following the steps i
### Enable GitLab Runner
To configure GitLab Runner with Sentry, you must add the value for `sentry_dsn` to your GitLab
-Runner's `config.toml` configuration file, as referenced in [GitLab Runner Advanced Configuraton](https://docs.gitlab.com/runner/configuration/advanced-configuration.html).
+Runner's `config.toml` configuration file, as referenced in [GitLab Runner Advanced Configuration](https://docs.gitlab.com/runner/configuration/advanced-configuration.html).
While setting up Sentry, select **Go** if you're asked for the project type.
If you see the following error in your GitLab Runner logs, then you should specify the deprecated
@@ -108,3 +108,54 @@ clicking the **Resolve** button near the top of the page.
Marking an error as resolved indicates that the error has stopped firing events. If a GitLab issue is linked to the error, then the issue closes.
If another event occurs, the error reverts to unresolved.
+
+## Integrated error tracking
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/329596) in GitLab 14.3.
+
+Integrated error tracking is a lightweight alternative to Sentry backend.
+You still use Sentry SDK with your application. But you don't need to deploy Sentry
+or set up for cloud-hosted Sentry. Instead, you use GitLab as a backend for it.
+
+Sentry backend automatically assigns a Data Source Name (DSN) for every project you create.
+GitLab does the same. You should be able to find a DSN for your project in the GitLab error tracking
+settings. By using a GitLab-provided DSN, your application connects to GitLab to report an error.
+Those errors are stored in the GitLab database and rendered by the GitLab UI, in the same way as
+Sentry integration.
+
+### Project settings
+
+The feature should be enabled on the project level. However, there is no UI to enable this feature yet.
+You must use the GitLab API to enable it.
+
+#### How to enable
+
+1. Select **GitLab** as the error tracking backend for your project:
+
+ ![Error Tracking Settings](img/error_tracking_setting_v14_3.png)
+
+1. Create a client key (DSN) to use with Sentry SDK in your application. Make sure to save the
+ response, as it contains a DSN:
+
+ ```shell
+ curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
+ "https://gitlab.example.com/api/v4/projects/PROJECT_ID/error_tracking/client_keys"
+ ```
+
+1. Take the DSN from the previous step and configure your Sentry SDK with it. Errors are now
+ reported to the GitLab collector and are visible in the [GitLab UI](#error-tracking-list).
+
+#### How to disable
+
+To disable the feature, run this command. This is the same command as the one that enables the
+feature, but with a `false` value instead:
+
+```shell
+curl --request PATCH --header "PRIVATE-TOKEN: <your_access_token>" \
+ "https://gitlab.example.com/api/v4/projects/PROJECT_ID/error_tracking/settings?active=false&integrated=false"
+```
+
+#### Limitations
+
+The Integrated Error Tracking feature was built and tested with Sentry SDK for Ruby. Other languages and frameworks
+are not tested and might not work. Check [the compatibility issue](https://gitlab.com/gitlab-org/gitlab/-/issues/340178) for more information.
diff --git a/doc/operations/img/error_tracking_setting_v14_3.png b/doc/operations/img/error_tracking_setting_v14_3.png
new file mode 100644
index 00000000000..14306130c97
--- /dev/null
+++ b/doc/operations/img/error_tracking_setting_v14_3.png
Binary files differ
diff --git a/doc/operations/metrics/alerts.md b/doc/operations/metrics/alerts.md
index ea4dd7e34cb..a3d741b78ea 100644
--- a/doc/operations/metrics/alerts.md
+++ b/doc/operations/metrics/alerts.md
@@ -61,7 +61,7 @@ Prometheus server to use the
## Trigger actions from alerts **(ULTIMATE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4925) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.11.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4925) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.11.
Alerts can be used to trigger actions, like opening an issue automatically
(disabled by default since `13.1`). To configure the actions:
diff --git a/doc/policy/alpha-beta-support.md b/doc/policy/alpha-beta-support.md
new file mode 100644
index 00000000000..be634bbf7be
--- /dev/null
+++ b/doc/policy/alpha-beta-support.md
@@ -0,0 +1,40 @@
+---
+stage: Enablement
+group: Distribution
+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
+---
+
+# Support for Alpha, Beta, and Generally Available Features **(PREMIUM)**
+
+Some GitLab features are released as [Alpha or Beta versions](https://about.gitlab.com/support/statement-of-support.html#alpha--beta-features) which are not fully supported. All other features are considered to be Generally Available (GA).
+
+## Alpha Features
+
+Characteristics of alpha features:
+
+- Not ready for production use.
+- Unstable and can cause performance and stability issues.
+- Configuration and dependencies are likely to change.
+- Features and functions may be removed.
+- Data loss can occur (be that through bugs or updates).
+
+Support is **not** provided for Alpha features and issues with them should be opened in the [GitLab issue tracker](https://gitlab.com/gitlab-org/gitlab/issues).
+
+## Beta Features
+
+Characteristics of beta features:
+
+- Not ready for production use.
+- Unstable and can cause performance and stability issues.
+- Configuration and dependencies are not likely to change.
+- Features and functions are not likely to change.
+- Data loss is not likely.
+
+Your Support Contract provides **best-efforts** support for Beta features, with the expectation that issues will require extra time and assistance from development to troubleshoot.
+
+## Generally Available (GA)
+
+Generally Available features means that they passed the [Production Readiness Review](https://gitlab.com/gitlab-com/gl-infra/readiness/-/blob/master/.gitlab/issue_templates/production_readiness.md) for GitLab.com, and are:
+
+- Ready for production use at any scale.
+- Fully documented and supported.
diff --git a/doc/policy/maintenance.md b/doc/policy/maintenance.md
index d8b36fcaa6d..f7c64895c78 100644
--- a/doc/policy/maintenance.md
+++ b/doc/policy/maintenance.md
@@ -64,10 +64,10 @@ one major version. For example, it is safe to:
- `12.10.1` -> `12.10.8`
NOTE:
-Version specific changes in Omnibus GitLab Linux packages can be found in [the Omnibus GitLab documentation](https://docs.gitlab.com/omnibus/update/README.html#version-specific-changes).
+Version specific changes in Omnibus GitLab Linux packages can be found in [the Omnibus GitLab documentation](../update/package/index.md#version-specific-changes).
NOTE:
-Instructions are available for downloading an Omnibus GitLab Linux package locally and [manually installing](https://docs.gitlab.com/omnibus/manual_install.html) it.
+Instructions are available for downloading an Omnibus GitLab Linux package locally and [manually installing](../update/package/index.md#upgrade-using-a-manually-downloaded-package) it.
NOTE:
A step-by-step guide to [upgrading the Omnibus-bundled PostgreSQL is documented separately](https://docs.gitlab.com/omnibus/settings/database.html#upgrade-packaged-postgresql-server).
diff --git a/doc/public_access/public_access.md b/doc/public_access/public_access.md
index 2cbcae31db3..1b4e1e64562 100644
--- a/doc/public_access/public_access.md
+++ b/doc/public_access/public_access.md
@@ -5,9 +5,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
-# Project visibility
+# Project and group visibility
-GitLab allows [Owners](../user/permissions.md) to set a project's visibility as:
+GitLab allows [Owners](../user/permissions.md) to set a project's or group's visibility as:
- **Public**
- **Internal**
@@ -18,7 +18,7 @@ for your GitLab instance). For example, <https://gitlab.com/public>.
You can control the visibility of individual features with
[project feature settings](../user/permissions.md#project-features).
-## Public projects
+## Public projects and groups
Public projects can be cloned **without any** authentication over HTTPS.
@@ -31,7 +31,7 @@ By default, `/public` is visible to unauthenticated users. However, if the
[**Public** visibility level](../user/admin_area/settings/visibility_and_access_controls.md#restrict-visibility-levels)
is restricted, `/public` is visible only to signed-in users.
-## Internal projects
+## Internal projects and groups
Internal projects can be cloned by any signed-in user except
[external users](../user/permissions.md#external-users).
@@ -47,7 +47,7 @@ and snippets on GitLab.com. Existing projects, groups, and snippets using the `I
visibility setting keep this setting. You can read more about the change in the
[relevant issue](https://gitlab.com/gitlab-org/gitlab/-/issues/12388).
-## Private projects
+## Private projects and groups
Private projects can only be cloned and viewed by project members (except for guests).
@@ -62,7 +62,19 @@ Prerequisite:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand **Visibility, project features, permissions**.
-1. Change **Project visibility** to either Public, Internal, or Private.
+1. Change **Project visibility** to either **Private**, **Internal**, or **Public**.
+1. Select **Save changes**.
+
+## Change group visibility
+
+Prerequisite:
+
+- You must have the Owner role for a group.
+
+1. On the top bar, select **Menu > Groups** and find your project.
+1. On the left sidebar, select **Settings > General**.
+1. Expand **Naming, visibility**.
+1. Under **Visibility level** select either **Private**, **Internal**, or **Public**.
1. Select **Save changes**.
## Restrict use of public or internal projects
diff --git a/doc/push_rules/push_rules.md b/doc/push_rules/push_rules.md
index 28dd3265465..9a8c0d79395 100644
--- a/doc/push_rules/push_rules.md
+++ b/doc/push_rules/push_rules.md
@@ -87,7 +87,7 @@ at the project level or the [group level](../user/group/index.md#group-push-rule
To create global push rules:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Push Rules**.
To override global push rules in a project's settings:
@@ -141,8 +141,7 @@ Feature.disable(:reject_unsigned_commits_by_gitlab)
## Prevent pushing secrets to the repository
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/385) in GitLab 8.12.
-> - Moved to GitLab Premium in 13.9.
+> Moved to GitLab Premium in 13.9.
Secrets such as credential files, SSH private keys, and other files containing secrets should never be committed to source control.
GitLab enables you to turn on a predefined denylist of files which can't be
@@ -217,8 +216,7 @@ id_ecdsa
## Prohibited file names
-> - Introduced in GitLab 7.10.
-> - Moved to GitLab Premium in 13.9.
+> Moved to GitLab Premium in 13.9.
Each filename contained in a Git push is compared to the regular expression in this field. Filenames in Git consist of both the file's name and any directory that may precede it. A singular regular expression can contain multiple independent matches used as exclusions. File names can be broadly matched to any location in the repository, or restricted to specific locations. Filenames can also be partial matches used to exclude file types by extension.
diff --git a/doc/raketasks/backup_restore.md b/doc/raketasks/backup_restore.md
index e9c9659d4f5..b6f772dee17 100644
--- a/doc/raketasks/backup_restore.md
+++ b/doc/raketasks/backup_restore.md
@@ -347,18 +347,21 @@ sudo -u git -H GITLAB_ASSUME_YES=1 bundle exec rake gitlab:backup:restore RAILS_
#### Back up Git repositories concurrently
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37158) in GitLab 13.3.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37158) in GitLab 13.3.
+> - [Concurrent restore introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69330) in GitLab 14.3
When using [multiple repository storages](../administration/repository_storage_paths.md),
-repositories can be backed up concurrently to help fully use CPU time. The
+repositories can be backed up or restored concurrently to help fully use CPU time. The
following variables are available to modify the default behavior of the Rake
task:
- `GITLAB_BACKUP_MAX_CONCURRENCY`: The maximum number of projects to back up at
- the same time. Defaults to `1`.
+ the same time. Defaults to the number of logical CPUs (in GitLab 14.1 and
+ earlier, defaults to `1`).
- `GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY`: The maximum number of projects to
back up at the same time on each storage. This allows the repository backups
- to be spread across storages. Defaults to `1`.
+ to be spread across storages. Defaults to `2` (in GitLab 14.1 and earlier,
+ defaults to `1`).
For example, for Omnibus GitLab installations with 4 repository storages:
@@ -404,6 +407,67 @@ For Omnibus GitLab packages:
1. [Reconfigure GitLab](../administration/restart_gitlab.md#omnibus-gitlab-reconfigure)
for the changes to take effect
+##### S3 Encrypted Buckets
+
+AWS supports these [modes for server side encryption](https://docs.aws.amazon.com/AmazonS3/latest/userguide/serv-side-encryption.html):
+
+- Amazon S3-Managed Keys (SSE-S3)
+- Customer Master Keys (CMKs) Stored in AWS Key Management Service (SSE-KMS)
+- Customer-Provided Keys (SSE-C)
+
+Use your mode of choice with GitLab. Each mode has similar, but slightly
+different, configuration methods.
+
+###### SSE-S3
+
+To enable SSE-S3, in the backup storage options set the `server_side_encryption`
+field to `AES256`. For example, in Omnibus GitLab:
+
+```ruby
+gitlab_rails['backup_upload_storage_options'] = {
+ 'server_side_encryption' => 'AES256'
+}
+```
+
+###### SSE-KMS
+
+To enable SSE-KMS, you'll need the [KMS key via its Amazon Resource Name (ARN)
+in the `arn:aws:kms:region:acct-id:key/key-id` format](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingKMSEncryption.html). Under the `backup_upload_storage_options` config setting, set:
+
+- `server_side_encryption` to `aws:kms`.
+- `server_side_encryption_kms_key_id` to the ARN of the key.
+
+For example, in Omnibus GitLab:
+
+```ruby
+gitlab_rails['backup_upload_storage_options'] = {
+ 'server_side_encryption' => 'aws:kms',
+ 'server_side_encryption_kms_key_id' => 'arn:aws:<YOUR KMS KEY ID>:'
+}
+```
+
+###### SSE-C
+
+SSE-C requires you to set these encryption options:
+
+- `backup_encryption`: AES256.
+- `backup_encryption_key`: Unencoded, 32-byte (256 bits) key. The upload fails if this isn't exactly 32 bytes.
+
+For example, in Omnibus GitLab:
+
+```ruby
+gitlab_rails['backup_encryption'] = 'AES256'
+gitlab_rails['backup_encryption_key'] = '<YOUR 32-BYTE KEY HERE>'
+```
+
+If the key contains binary characters and cannot be encoded in UTF-8,
+instead, specify the key with the `GITLAB_BACKUP_ENCRYPTION_KEY` environment variable.
+For example:
+
+```ruby
+gitlab_rails['env'] = { 'GITLAB_BACKUP_ENCRYPTION_KEY' => "\xDE\xAD\xBE\xEF" * 8 }
+```
+
##### Digital Ocean Spaces
This example can be used for a bucket in Amsterdam (AMS3):
@@ -455,15 +519,25 @@ For installations from source:
# use_iam_profile: 'true'
# The remote 'directory' to store your backups. For S3, this would be the bucket name.
remote_directory: 'my.s3.bucket'
- # Turns on AWS Server-Side Encryption with Amazon S3-Managed Keys for backups, this is optional
- # encryption: 'AES256'
- # Turns on AWS Server-Side Encryption with Amazon Customer-Provided Encryption Keys for backups, this is optional
- # This should be set to the encryption key for Amazon S3 to use to encrypt or decrypt your data.
- # 'encryption' must also be set in order for this to have any effect.
- # To avoid storing the key on disk, the key can also be specified via the `GITLAB_BACKUP_ENCRYPTION_KEY` environment variable.
- # encryption_key: '<key>'
# Specifies Amazon S3 storage class to use for backups, this is optional
# storage_class: 'STANDARD'
+ #
+ # Turns on AWS Server-Side Encryption with Amazon Customer-Provided Encryption Keys for backups, this is optional
+ # 'encryption' must be set in order for this to have any effect.
+ # 'encryption_key' should be set to the 256-bit encryption key for Amazon S3 to use to encrypt or decrypt.
+ # To avoid storing the key on disk, the key can also be specified via the `GITLAB_BACKUP_ENCRYPTION_KEY` your data.
+ # encryption: 'AES256'
+ # encryption_key: '<key>'
+ #
+ #
+ # Turns on AWS Server-Side Encryption with Amazon S3-Managed keys (optional)
+ # https://docs.aws.amazon.com/AmazonS3/latest/userguide/serv-side-encryption.html
+ # For SSE-S3, set 'server_side_encryption' to 'AES256'.
+ # For SS3-KMS, set 'server_side_encryption' to 'aws:kms'. Set
+ # 'server_side_encryption_kms_key_id' to the ARN of customer master key.
+ # storage_options:
+ # server_side_encryption: 'aws:kms'
+ # server_side_encryption_kms_key_id: 'arn:aws:kms:YOUR-KEY-ID-HERE'
```
1. [Restart GitLab](../administration/restart_gitlab.md#installations-from-source)
@@ -807,7 +881,7 @@ You can restore a backup only to _the exact same version and type (CE/EE)_ of
GitLab that you created it on (for example CE 9.1.0).
If your backup is a different version than the current installation, you must
-[downgrade your GitLab installation](https://docs.gitlab.com/omnibus/update/README.html#downgrade)
+[downgrade your GitLab installation](../update/package/downgrade.md)
before restoring the backup.
### Restore prerequisites
@@ -1138,7 +1212,8 @@ There are a few possible downsides to this:
the last project that gets backed up.
- Fork networks should be entirely read-only while the projects inside get backed up to prevent potential changes to the pool repository.
-There is an **experimental** script that attempts to automate this process in [Snippet 2149205](https://gitlab.com/-/snippets/2149205).
+There is an **experimental** script that attempts to automate this process in
+[the Geo team Runbooks project](https://gitlab.com/gitlab-org/geo-team/runbooks/-/tree/main/experimental-online-backup-through-rsync).
## Backup and restore for installations using PgBouncer
@@ -1295,7 +1370,7 @@ Be sure to create a full database backup before attempting any changes.
#### Disable user two-factor authentication (2FA)
Users with 2FA enabled can't sign in to GitLab. In that case, you must
-[disable 2FA for everyone](../security/two_factor_authentication.md#disabling-2fa-for-everyone),
+[disable 2FA for everyone](../security/two_factor_authentication.md#disable-2fa-for-everyone),
after which users must reactivate 2FA.
#### Reset CI/CD variables
diff --git a/doc/raketasks/cleanup.md b/doc/raketasks/cleanup.md
index 9f79d3cc675..c2d3c540cbf 100644
--- a/doc/raketasks/cleanup.md
+++ b/doc/raketasks/cleanup.md
@@ -207,10 +207,6 @@ sudo gitlab-rake gitlab:cleanup:sessions:active_sessions_lookup_keys
bundle exec rake gitlab:cleanup:sessions:active_sessions_lookup_keys RAILS_ENV=production
```
-## Cleaning up stale Redis sessions
-
-[Clean up stale sessions](../administration/operations/cleaning_up_redis_sessions.md) to compact the Redis database after you upgrade to GitLab 7.3.
-
## Container Registry garbage collection
Container Registry can use considerable amounts of disk space. To clear up
diff --git a/doc/raketasks/features.md b/doc/raketasks/features.md
index ba14293a9fd..3248f7370e8 100644
--- a/doc/raketasks/features.md
+++ b/doc/raketasks/features.md
@@ -10,7 +10,8 @@ This Rake task enables [namespaces](../user/group/index.md#namespaces) for proje
## Enable usernames and namespaces for user projects
-This command enables the namespaces feature introduced in GitLab 4.0. It moves every project in its namespace folder.
+This command enables the namespaces feature. It moves every project in its
+namespace folder.
The **repository location changes as part of this task**, so you must **update all your Git URLs** to
point to the new location.
@@ -19,7 +20,7 @@ To change your username:
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. In the left sidebar, select **Account**.
+1. On the left sidebar, select **Account**.
1. In the **Change username** section, type the new username.
1. Select **Update username**.
diff --git a/doc/security/password_length_limits.md b/doc/security/password_length_limits.md
index 847656d8d17..bedf2ac3ab1 100644
--- a/doc/security/password_length_limits.md
+++ b/doc/security/password_length_limits.md
@@ -30,7 +30,7 @@ The user password length is set to a minimum of 8 characters by default.
To change the minimum password length using GitLab UI:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > General** and expand **Sign-up restrictions**.
![Minimum password length settings](../user/admin_area/img/minimum_password_length_settings_v12_6.png)
diff --git a/doc/security/rack_attack.md b/doc/security/rack_attack.md
index 6d2725d1ec1..4894af1fa19 100644
--- a/doc/security/rack_attack.md
+++ b/doc/security/rack_attack.md
@@ -109,7 +109,7 @@ The following settings can be configured:
- `enabled`: By default this is set to `false`. Set this to `true` to enable Rack Attack.
- `ip_whitelist`: Whitelist any IPs from being blocked. They must be formatted as strings within a Ruby array.
- CIDR notation is supported in GitLab v12.1 and up.
+ CIDR notation is supported in GitLab 12.1 and later.
For example, `["127.0.0.1", "127.0.0.2", "127.0.0.3", "192.168.0.1/24"]`.
- `maxretry`: The maximum amount of times a request can be made in the
specified time.
diff --git a/doc/security/rate_limits.md b/doc/security/rate_limits.md
index e698341b4b5..6045dece0c2 100644
--- a/doc/security/rate_limits.md
+++ b/doc/security/rate_limits.md
@@ -34,6 +34,7 @@ These are rate limits you can set in the Admin Area of your instance:
- [Raw endpoints rate limits](../user/admin_area/settings/rate_limits_on_raw_endpoints.md)
- [User and IP rate limits](../user/admin_area/settings/user_and_ip_rate_limits.md)
- [Package registry rate limits](../user/admin_area/settings/package_registry_rate_limits.md)
+- [Git LFS rate limits](../user/admin_area/settings/git_lfs_rate_limits.md)
## Non-configurable limits
diff --git a/doc/security/ssh_keys_restrictions.md b/doc/security/ssh_keys_restrictions.md
index 55eeaae5458..239949b5568 100644
--- a/doc/security/ssh_keys_restrictions.md
+++ b/doc/security/ssh_keys_restrictions.md
@@ -5,7 +5,7 @@ group: Access
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
---
-# Restrict allowed SSH key technologies and minimum length
+# Restrict allowed SSH key technologies and minimum length **(FREE SELF)**
`ssh-keygen` allows users to create RSA keys with as few as 768 bits, which
falls well below recommendations from certain standards groups (such as the US
@@ -20,7 +20,7 @@ algorithms.
GitLab allows you to restrict the allowed SSH key technology as well as specify
the minimum key length for each technology:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > General** (`/admin/application_settings/general`).
1. Expand the **Visibility and access controls** section:
@@ -36,6 +36,16 @@ An icon is visible to the user of a restricted key in the SSH keys section of th
Hovering over this icon tells you why the key is restricted.
+## Default settings
+
+By default, the GitLab.com and self-managed settings for the
+[supported key types](../ssh/index.md#supported-ssh-key-types) are:
+
+- RSA SSH keys are allowed.
+- DSA SSH keys are forbidden ([since GitLab 11.0](https://about.gitlab.com/releases/2018/06/22/gitlab-11-0-released/#support-for-dsa-ssh-keys)).
+- ECDSA SSH keys are allowed.
+- ED25519 SSH keys are allowed.
+
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
diff --git a/doc/security/token_overview.md b/doc/security/token_overview.md
index c00e5bff383..4e72033fd77 100644
--- a/doc/security/token_overview.md
+++ b/doc/security/token_overview.md
@@ -71,7 +71,7 @@ You can use the runner registration token to add runners that execute jobs in a
After registration, the runner receives an authentication token, which it uses to authenticate with GitLab when picking up jobs from the job queue. The authentication token is stored locally in the runner's [`config.toml`](https://docs.gitlab.com/runner/configuration/advanced-configuration.html) file.
-After authentication with GitLab, the runner receives a [job token](../api/index.md#gitlab-cicd-job-token), which it uses to execute the job.
+After authentication with GitLab, the runner receives a [job token](../ci/jobs/ci_job_token.md), which it uses to execute the job.
In case of Docker Machine/Kubernetes/VirtualBox/Parallels/SSH executors, the execution environment has no access to the runner authentication token, because it stays on the runner machine. They have access to the job token only, which is needed to execute the job.
@@ -79,7 +79,7 @@ Malicious access to a runner's file system may expose the `config.toml` file and
## CI/CD job tokens
-The [CI/CD](../api/index.md#gitlab-cicd-job-token) job token
+The [CI/CD](../ci/jobs/ci_job_token.md) job token
is a short lived token only valid for the duration of a job. It gives a CI/CD job
access to a limited amount of API endpoints.
API authentication uses the job token, by using the authorization of the user
@@ -105,7 +105,7 @@ This table shows available scopes per token. Scopes can be limited further on to
1. Limited to the one project.
1. Runner registration and authentication token don't provide direct access to repositories, but can be used to register and authenticate a new runner that may execute jobs which do have access to the repository
-1. Limited to certain [endpoints](../api/index.md#gitlab-cicd-job-token).
+1. Limited to certain [endpoints](../ci/jobs/ci_job_token.md).
## Security considerations
diff --git a/doc/security/two_factor_authentication.md b/doc/security/two_factor_authentication.md
index a009fa9964d..a5b01a1b27d 100644
--- a/doc/security/two_factor_authentication.md
+++ b/doc/security/two_factor_authentication.md
@@ -5,17 +5,15 @@ group: Access
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
---
-# Enforce Two-factor Authentication (2FA)
+# Enforce two-factor authentication **(FREE SELF)**
-Two-factor Authentication (2FA) provides an additional level of security to your
-users' GitLab account. After being enabled, in addition to supplying their
-username and password to sign in, they are prompted for a code generated by an
-application on their phone.
+Two-factor authentication (2FA) provides an additional level of security to your
+users' GitLab account. When enabled, users are prompted for a code generated by an application in
+addition to supplying their username and password to sign in.
-You can read more about it here:
-[Two-factor Authentication (2FA)](../user/profile/account/two_factor_authentication.md)
+Read more about [two-factor authentication (2FA)](../user/profile/account/two_factor_authentication.md)
-## Enforcing 2FA for all users
+## Enforce 2FA for all users
Users on GitLab can enable it without any administrator's intervention. If you
want to enforce everyone to set up 2FA, you can choose from two different ways:
@@ -28,18 +26,27 @@ cannot leave the 2FA configuration area at `/-/profile/two_factor_auth`.
To enable 2FA for all users:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > General** (`/admin/application_settings/general`).
1. Expand the **Sign-in restrictions** section, where you can configure both.
If you want 2FA enforcement to take effect during the next sign-in attempt,
change the grace period to `0`.
-## Enforcing 2FA for all users in a group
+## Disable 2FA enforcement through rails console
+
+Using the [rails console](../administration/operations/rails_console.md), enforcing 2FA for
+all user can be disabled. Connect to the rails console and run:
+
+```ruby
+Gitlab::CurrentSettings.update!('require_two_factor_authentication': false)
+```
+
+## Enforce 2FA for all users in a group **(FREE)**
> [Introduced in](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/24965) GitLab 12.0, 2FA settings for a group are also applied to subgroups.
-If you want to enforce 2FA only for certain groups:
+To enforce 2FA only for certain groups:
1. Go to the group's **Settings > General** page.
1. Expand the **Permissions, LFS, 2FA** section.
@@ -47,11 +54,11 @@ If you want to enforce 2FA only for certain groups:
You can also specify a grace period in the **Time before enforced** option.
-To change this setting, you need to be administrator or owner of the group.
+To change this setting, you must be an administrator or owner of the group.
If you want to enforce 2FA only for certain groups, you can enable it in the
group settings and specify a grace period as above. To change this setting you
-need to be administrator or owner of the group.
+must be administrator or owner of the group.
The following are important notes about 2FA:
@@ -74,13 +81,13 @@ The following are important notes about 2FA:
This action causes all subgroups with 2FA requirements to stop requiring that from their members.
-## Disabling 2FA for everyone
+## Disable 2FA for everyone
WARNING:
-Disabling 2FA for everyone does not disable the [enforce 2FA for all users](#enforcing-2fa-for-all-users)
-or [enforce 2FA for all users in a group](#enforcing-2fa-for-all-users-in-a-group)
-settings. In addition to the steps in this section, you must disable any enforced 2FA
-settings so users aren't asked to set up 2FA again, the next time the user signs in to GitLab.
+Disabling 2FA for everyone does not disable the [enforce 2FA for all users](#enforce-2fa-for-all-users)
+or [enforce 2FA for all users in a group](#enforce-2fa-for-all-users-in-a-group)
+settings. You must also disable any enforced 2FA settings so users aren't asked to set up 2FA again
+when they next sign in to GitLab.
There may be some special situations where you want to disable 2FA for everyone
even when forced 2FA is disabled. There is a Rake task for that:
@@ -97,26 +104,26 @@ WARNING:
This is a permanent and irreversible action. Users have to
reactivate 2FA from scratch if they want to use it again.
-## Two-factor Authentication (2FA) for Git over SSH operations **(PREMIUM)**
+## 2FA for Git over SSH operations **(PREMIUM)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/270554) in GitLab 13.7.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/299088) from GitLab Free to GitLab Premium in 13.9.
> - It's [deployed behind a feature flag](../user/feature_flags.md), disabled by default.
> - It's disabled on GitLab.com.
> - It's not recommended for production use.
-> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-two-factor-authentication-2fa-for-git-operations).
+> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-2fa-for-git-operations).
WARNING:
This feature might not be available to you. Check the **version history** note above for details.
-Two-factor authentication can be enforced for Git over SSH operations. The OTP
+Two-factor authentication can be enforced for Git over SSH operations. The one-time password (OTP)
verification can be done via a GitLab Shell command:
```shell
ssh git@<hostname> 2fa_verify
```
-Once the OTP is verified, Git over SSH operations can be used for a session duration of
+After the OTP is verified, Git over SSH operations can be used for a session duration of
15 minutes (default) with the associated SSH key.
### Security limitation
@@ -126,9 +133,9 @@ Once the OTP is verified, Git over SSH operations can be used for a session dura
Once an OTP is verified, anyone can run Git over SSH with that private SSH key for
the configured [session duration](../user/admin_area/settings/account_and_limit_settings.md#customize-session-duration-for-git-operations-when-2fa-is-enabled).
-### Enable or disable Two-factor Authentication (2FA) for Git operations
+### Enable or disable 2FA for Git operations
-Two-factor Authentication (2FA) for Git operations is under development and not
+2FA for Git operations is under development and not
ready for production use. It is deployed behind a feature flag that is
**disabled by default**. [GitLab administrators with access to the GitLab Rails console](../administration/feature_flags.md)
can enable it.
@@ -147,7 +154,7 @@ Feature.disable(:two_factor_for_cli)
The feature flag affects these features:
-- [Two-factor Authentication (2FA) for Git over SSH operations](#two-factor-authentication-2fa-for-git-over-ssh-operations).
+- [Two-factor Authentication (2FA) for Git over SSH operations](#2fa-for-git-over-ssh-operations).
- [Customize session duration for Git Operations when 2FA is enabled](../user/admin_area/settings/account_and_limit_settings.md#customize-session-duration-for-git-operations-when-2fa-is-enabled).
<!-- ## Troubleshooting
diff --git a/doc/security/user_email_confirmation.md b/doc/security/user_email_confirmation.md
index 1b39937acbe..09e1e09b676 100644
--- a/doc/security/user_email_confirmation.md
+++ b/doc/security/user_email_confirmation.md
@@ -11,7 +11,7 @@ GitLab can be configured to require confirmation of a user's email address when
the user signs up. When this setting is enabled, the user is unable to sign in until
they confirm their email address.
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > General** (`/admin/application_settings/general`).
1. Expand the **Sign-up restrictions** section and look for the **Send confirmation email on sign-up** option.
diff --git a/doc/security/webhooks.md b/doc/security/webhooks.md
index b0535d0bcaf..c0e5d0695cc 100644
--- a/doc/security/webhooks.md
+++ b/doc/security/webhooks.md
@@ -46,8 +46,8 @@ to `127.0.0.1`, `::1` and `0.0.0.0`, as well as IPv4 `10.0.0.0/8`, `172.16.0.0/1
This behavior can be overridden:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > Network**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Network**.
1. Expand the **Outbound requests** section:
![Outbound requests admin settings](img/outbound_requests_section_v12_2.png)
1. Select **Allow requests to the local network from web hooks and services**.
@@ -65,8 +65,8 @@ You can allow certain domains and IP addresses to be accessible to both *system
and *webhooks* even when local requests are not allowed by adding them to the
allowlist:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > Network** (`/admin/application_settings/network`)
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Network** (`/admin/application_settings/network`)
and expand **Outbound requests**:
![Outbound local requests allowlist](img/allowlist_v13_0.png)
diff --git a/doc/ssh/index.md b/doc/ssh/index.md
index c4e651a0072..94c157697ce 100644
--- a/doc/ssh/index.md
+++ b/doc/ssh/index.md
@@ -101,7 +101,7 @@ If you do not have an existing SSH key pair, generate a new one.
You can also dedicate the SSH key pair to a [specific host](#configure-ssh-to-point-to-a-different-directory).
-1. Specify a [passphrase](https://www.ssh.com/ssh/passphrase):
+1. Specify a [passphrase](https://www.ssh.com/academy/ssh/passphrase):
```plaintext
Enter passphrase (empty for no passphrase):
@@ -318,7 +318,7 @@ on the files make them readable to you but not accessible to others.
## Configure two-factor authentication (2FA)
You can set up two-factor authentication (2FA) for
-[Git over SSH](../security/two_factor_authentication.md#two-factor-authentication-2fa-for-git-over-ssh-operations).
+[Git over SSH](../security/two_factor_authentication.md#2fa-for-git-over-ssh-operations).
## Use EGit on Eclipse
diff --git a/doc/subscriptions/bronze_starter.md b/doc/subscriptions/bronze_starter.md
index 410759aa506..327fb8887ad 100644
--- a/doc/subscriptions/bronze_starter.md
+++ b/doc/subscriptions/bronze_starter.md
@@ -32,7 +32,7 @@ the tiers are no longer mentioned in GitLab documentation:
- [Overriding user permissions](../user/group/index.md#override-user-permissions)
- [User contribution analytics](../user/group/contribution_analytics/index.md)
- [Kerberos integration](../integration/kerberos.md)
-- Issue Boards:
+- Issue boards:
- [Configurable issue boards](../user/project/issue_board.md#configurable-issue-boards)
- [Sum of issue weights](../user/project/issue_board.md#sum-of-issue-weights)
- [Work In Progress limits](../user/project/issue_board.md#work-in-progress-limits)
@@ -51,13 +51,13 @@ the tiers are no longer mentioned in GitLab documentation:
- Syncing information through LDAP:
- Groups: [one group](../administration/auth/ldap/ldap-troubleshooting.md#sync-one-group),
[all groups programmatically](../administration/auth/ldap/index.md#group-sync),
- [group sync schedule](../administration/auth/ldap/index.md#adjusting-ldap-group-sync-schedule), and
+ [group sync schedule](../administration/auth/ldap/index.md#adjust-ldap-group-sync-schedule), and
[all groups manually](../administration/auth/ldap/ldap-troubleshooting.md#sync-all-groups)
- [Configuration settings](../administration/auth/ldap/index.md#ldap-sync-configuration-settings)
- Users: [all users](../administration/auth/ldap/index.md#user-sync),
[administrators](../administration/auth/ldap/index.md#administrator-sync),
- [user sync schedule](../administration/auth/ldap/index.md#adjusting-ldap-user-sync-schedule)
- - [Adding group links](../administration/auth/ldap/index.md#adding-group-links)
+ [user sync schedule](../administration/auth/ldap/index.md#adjust-ldap-user-sync-schedule)
+ - [Adding group links](../administration/auth/ldap/index.md#add-group-links)
- [Lock memberships to LDAP synchronization](../administration/auth/ldap/index.md#global-group-memberships-lock)
- Rake tasks for [LDAP tasks](../administration/raketasks/ldap.md), including
[syncing groups](../administration/raketasks/ldap.md#run-a-group-sync)
@@ -102,7 +102,7 @@ the tiers are no longer mentioned in GitLab documentation:
- [Shared runners pipeline minutes quota](../user/admin_area/settings/continuous_integration.md#shared-runners-pipeline-minutes-quota)
- [Push rules](../push_rules/push_rules.md)
- SAML for self-managed GitLab instance:
- - [Administrator groups](../integration/saml.md#admin-groups)
+ - [Administrator groups](../integration/saml.md#administrator-groups)
- [Auditor groups](../integration/saml.md#auditor-groups)
- [External groups](../integration/saml.md#external-groups)
- [Required groups](../integration/saml.md#required-groups)
diff --git a/doc/subscriptions/gitlab_com/index.md b/doc/subscriptions/gitlab_com/index.md
index 55fb77fe927..cecbb362cb9 100644
--- a/doc/subscriptions/gitlab_com/index.md
+++ b/doc/subscriptions/gitlab_com/index.md
@@ -91,21 +91,34 @@ The following table describes details of your subscription:
> - [Updated](https://gitlab.com/gitlab-org/gitlab/-/issues/292086) in GitLab 13.8 to include public
email address.
-To view a list of seats being used, go to **Settings > Billing**.
-Under **Seats currently in use**, select **See usage**.
-
-You can also see this information in your group settings by going to **Menu > Groups > Your Group > Settings > Usage Quotas**, and the information about **Seat usage** will be under the **Seats** tab.
-
The **Seat usage** page lists all users occupying seats. Details for each user include:
- Full name
- Username
- Public email address (if they have provided one in their [user settings](../../user/profile/index.md#access-your-user-settings))
-The Seat usage listing is updated live, but the usage statistics on the billing page are updated
+The seat usage listing is updated live, but the usage statistics on the billing page are updated
only once per day. For this reason there can be a minor difference between the seat usage listing
and the billing page.
+Every user is included in seat usage, with the following exceptions:
+
+- Users who are pending approval.
+- Members with the Guest role on an Ultimate subscription.
+- Users without project or group memberships on an Ultimate subscription.
+- GitLab-created service accounts: `Ghost User` and bots
+ ([`Support Bot`](../../user/project/service_desk.md#support-bot-user),
+ [`Project bot users`](../../user/project/settings/project_access_tokens.md#project-bot-users), and
+ so on.)
+
+### View seat usage
+
+To view a list of seats being used:
+
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Settings > Usage Quotas**.
+1. Under the **Seats** tab, view usage information.
+
### Search seat usage
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/262875) in GitLab 13.8.
@@ -326,7 +339,7 @@ Quotas apply to:
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
- 1. In the left sidebar, select **[Usage Quotas](https://gitlab.com/-/profile/usage_quotas#pipelines-quota-tab)**.
+ 1. On the left sidebar, select **[Usage Quotas](https://gitlab.com/-/profile/usage_quotas#pipelines-quota-tab)**.
Only pipeline minutes for GitLab shared runners are restricted. If you have a
specific runner set up for your projects, there is no limit to your build time on GitLab SaaS.
@@ -362,7 +375,7 @@ To purchase additional minutes for your personal namespace:
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. In the left sidebar, select **Usage Quotas**.
+1. On the left sidebar, select **Usage Quotas**.
1. Select **Buy additional minutes** and GitLab redirects you to the Customers Portal.
1. Locate the subscription card that's linked to your personal namespace on GitLab SaaS, click **Buy more CI minutes**, and complete the details about the transaction. Once we have processed your payment, the extra CI minutes are synced to your personal namespace.
1. To confirm the available CI minutes for your personal projects, go to the **Usage Quotas** settings again.
diff --git a/doc/subscriptions/quarterly_reconciliation.md b/doc/subscriptions/quarterly_reconciliation.md
index af9fec1ddc4..f9cca079e76 100644
--- a/doc/subscriptions/quarterly_reconciliation.md
+++ b/doc/subscriptions/quarterly_reconciliation.md
@@ -18,3 +18,31 @@ pay 25% of what you would have paid previously. This results in substantial savi
If it's not possible for you to participate in quarterly reconciliations, you can opt out of the
process by using a contract amendment. In that case, you default to the annual review.
+
+## Timeline for invoicing and payment
+
+At the end of each subscription quarter, GitLab notifies you about overages.
+The date you're notified about the overage is not the same as the date
+you are billed.
+
+### GitLab SaaS
+
+Group owners receive an email **on the reconciliation date**.
+The email communicates the [overage seat quantity](gitlab_com/index.md#seats-owed-example)
+and expected invoice amount.
+
+**Seven days later**, the subscription is updated to include the additional
+seats, and an invoice is generated for a prorated amount. If a credit card
+is on file, a payment is automatically applied. Otherwise, an invoice is
+sent and subject to your terms.
+
+### Self-managed instances
+
+Admins receive an email **six days after the reconciliation date**.
+This email communicates the [overage seat quantity](self_managed/index.md#users-over-license)
+and expected invoice amount.
+
+**Seven days later**, the subscription is updated to include the additional
+seats, and an invoice is generated for a prorated amount. If a credit card
+is on file, a payment is automatically applied. Otherwise, an invoice is
+sent and subject to your payment terms.
diff --git a/doc/subscriptions/self_managed/index.md b/doc/subscriptions/self_managed/index.md
index 51913ac2650..72bd1c2b4f7 100644
--- a/doc/subscriptions/self_managed/index.md
+++ b/doc/subscriptions/self_managed/index.md
@@ -49,7 +49,7 @@ Prorated charges are not possible without a quarterly usage report.
You can view users for your license and determine if you've gone over your subscription.
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left menu, select **Subscription**.
The lists of users are displayed.
@@ -154,7 +154,7 @@ See the [quarterly subscription reconciliation section](../quarterly_reconciliat
1. When you purchase a GitLab self-managed plan, an activation code is generated.
This activation code is sent to the email address associated with the Customers Portal account.
-1. In GitLab, on the top bar, select **Menu >** **{admin}** **Admin**.
+1. In GitLab, on the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Subscription** and paste the activation code in the text field.
1. Select **Activate**.
@@ -237,7 +237,7 @@ The daily job provides **only** the following information to the Customers Porta
You can manually sync your subscription details at any time.
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Subscription**.
1. In the **Subscription details** section, select **Sync subscription details**.
@@ -246,7 +246,7 @@ A job is queued. When the job finishes, the subscription details are updated.
#### Troubleshooting cloud licensing sync
If the sync job is not working, ensure you allow network traffic from your GitLab instance
-to IP address `104.46.106.135:443` (`customers.gitlab.com`).
+to IP address `104.18.26.123:443` (`customers.gitlab.com`).
## Obtain a subscription
@@ -265,7 +265,7 @@ instance, ensure you're purchasing enough seats to
If you are an administrator, you can view the status of your subscription:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **License**.
The **License** page includes the following details:
diff --git a/doc/system_hooks/system_hooks.md b/doc/system_hooks/system_hooks.md
index f86d3940a33..7dd0701329d 100644
--- a/doc/system_hooks/system_hooks.md
+++ b/doc/system_hooks/system_hooks.md
@@ -52,8 +52,8 @@ for Push and Tag events, but we never display commits.
To create a system hook:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **System Hooks**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **System Hooks**.
1. Provide the **URL** and **Secret Token**.
1. Select the checkbox next to each **Trigger** you want to enable.
1. Select **Enable SSL verification**, if desired.
diff --git a/doc/tools/email.md b/doc/tools/email.md
index 8ba275903da..0429b9b952e 100644
--- a/doc/tools/email.md
+++ b/doc/tools/email.md
@@ -22,8 +22,8 @@ For information about email notifications originating from GitLab, read
## Sending emails to users from within GitLab
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Overview > Users**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Overview > Users**.
1. Select **Send email to users**.
![admin users](email1.png)
diff --git a/doc/topics/authentication/index.md b/doc/topics/authentication/index.md
index 83c9e180c1c..25e6e590f77 100644
--- a/doc/topics/authentication/index.md
+++ b/doc/topics/authentication/index.md
@@ -11,7 +11,7 @@ This page gathers all the resources for the topic **Authentication** within GitL
## GitLab users
- [SSH](../../ssh/index.md)
-- [Two-Factor Authentication (2FA)](../../user/profile/account/two_factor_authentication.md#two-factor-authentication)
+- [Two-factor authentication (2FA)](../../user/profile/account/two_factor_authentication.md#two-factor-authentication)
- [Why do I keep getting signed out?](../../user/profile/index.md#why-do-i-keep-getting-signed-out)
- **Articles:**
- [Support for Universal 2nd Factor Authentication - YubiKeys](https://about.gitlab.com/blog/2016/06/22/gitlab-adds-support-for-u2f/)
@@ -23,7 +23,7 @@ This page gathers all the resources for the topic **Authentication** within GitL
## GitLab administrators
- [LDAP](../../administration/auth/ldap/index.md)
-- [Enforce Two-factor Authentication (2FA)](../../security/two_factor_authentication.md#enforce-two-factor-authentication-2fa)
+- [Enforce two-factor authentication (2FA)](../../security/two_factor_authentication.md)
- **Articles:**
- [Feature Highlight: LDAP Integration](https://about.gitlab.com/blog/2014/07/10/feature-highlight-ldap-sync/)
- [Debugging LDAP](https://about.gitlab.com/handbook/support/workflows/debugging_ldap.html)
@@ -43,7 +43,7 @@ This page gathers all the resources for the topic **Authentication** within GitL
- [Personal access tokens](../../api/index.md#personalproject-access-tokens)
- [Project access tokens](../../api/index.md#personalproject-access-tokens)
- [Impersonation tokens](../../api/index.md#impersonation-tokens)
-- [GitLab as an OAuth2 provider](../../api/oauth2.md#gitlab-as-an-oauth2-provider)
+- [GitLab as an OAuth2 provider](../../api/oauth2.md#gitlab-as-an-oauth-20-provider)
## Third-party resources
diff --git a/doc/topics/autodevops/customize.md b/doc/topics/autodevops/customize.md
index 72f688a0ed5..f8b63f5b41a 100644
--- a/doc/topics/autodevops/customize.md
+++ b/doc/topics/autodevops/customize.md
@@ -373,6 +373,8 @@ applications.
|-----------------------------------------|------------------------------------|
| `ADDITIONAL_HOSTS` | Fully qualified domain names specified as a comma-separated list that are added to the Ingress hosts. |
| `<ENVIRONMENT>_ADDITIONAL_HOSTS` | For a specific environment, the fully qualified domain names specified as a comma-separated list that are added to the Ingress hosts. This takes precedence over `ADDITIONAL_HOSTS`. |
+| `AUTO_BUILD_IMAGE_VERSION` | Customize the image version used for the `build` job. See [list of versions](https://gitlab.com/gitlab-org/cluster-integration/auto-build-image/-/releases). |
+| `AUTO_DEPLOY_IMAGE_VERSION` | Customize the image version used for Kubernetes deployment jobs. See [list of versions](https://gitlab.com/gitlab-org/cluster-integration/auto-deploy-image/-/releases). |
| `AUTO_DEVOPS_ATOMIC_RELEASE` | As of GitLab 13.0, Auto DevOps uses [`--atomic`](https://v2.helm.sh/docs/helm/#options-43) for Helm deployments by default. Set this variable to `false` to disable the use of `--atomic` |
| `AUTO_DEVOPS_BUILD_IMAGE_CNB_ENABLED` | Set to `false` to use Herokuish instead of Cloud Native Buildpacks with Auto Build. [More details](stages.md#auto-build-using-cloud-native-buildpacks). |
| `AUTO_DEVOPS_BUILD_IMAGE_CNB_BUILDER` | The builder used when building with Cloud Native Buildpacks. The default builder is `heroku/buildpacks:18`. [More details](stages.md#auto-build-using-cloud-native-buildpacks). |
@@ -390,6 +392,7 @@ applications.
| `CANARY_ENABLED` | From GitLab 11.0, used to define a [deploy policy for canary environments](#deploy-policy-for-canary-environments). |
| `CANARY_PRODUCTION_REPLICAS` | Number of canary replicas to deploy for [Canary Deployments](../../user/project/canary_deployments.md) in the production environment. Takes precedence over `CANARY_REPLICAS`. Defaults to 1. |
| `CANARY_REPLICAS` | Number of canary replicas to deploy for [Canary Deployments](../../user/project/canary_deployments.md). Defaults to 1. |
+| `DAST_AUTO_DEPLOY_IMAGE_VERSION` | Customize the image version used for DAST deployments on the default branch. Should usually be the same as `AUTO_DEPLOY_IMAGE_VERSION`. See [list of versions](https://gitlab.com/gitlab-org/cluster-integration/auto-deploy-image/-/releases). |
| `DOCKERFILE_PATH` | From GitLab 13.2, allows overriding the [default Dockerfile path for the build stage](#custom-dockerfile) |
| `HELM_RELEASE_NAME` | From GitLab 12.1, allows the `helm` release name to be overridden. Can be used to assign unique release names when deploying multiple projects to a single namespace. |
| `HELM_UPGRADE_VALUES_FILE` | From GitLab 12.6, allows the `helm upgrade` values file to be overridden. Defaults to `.gitlab/auto-deploy-values.yaml`. |
@@ -461,7 +464,7 @@ The following table lists variables used to disable jobs.
| `license_scanning` | `LICENSE_MANAGEMENT_DISABLED` | [From GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/22773) | If the variable is present, the job isn't created. |
| `load_performance` | `LOAD_PERFORMANCE_DISABLED` | From GitLab 13.2 | If the variable is present, the job isn't created. |
| `nodejs-scan-sast` | `SAST_DISABLED` | | If the variable is present, the job isn't created. |
-| `performance` | `PERFORMANCE_DISABLED` | GitLab 11.0 to GitLab 13.12 | Browser performance. If the variable is present, the job isn't created. Replaced by `browser_peformance`. |
+| `performance` | `PERFORMANCE_DISABLED` | GitLab 11.0 to GitLab 13.12 | Browser performance. If the variable is present, the job isn't created. Replaced by `browser_performance`. |
| `browser_performance` | `BROWSER_PERFORMANCE_DISABLED` | From GitLab 14.0 | Browser performance. If the variable is present, the job isn't created. Replaces `performance`. |
| `phpcs-security-audit-sast` | `SAST_DISABLED` | | If the variable is present, the job isn't created. |
| `pmd-apex-sast` | `SAST_DISABLED` | | If the variable is present, the job isn't created. |
@@ -491,9 +494,9 @@ these prefixed variables available to the deployed application as environment va
To configure your application variables:
-1. Go to your project's **Settings > CI/CD**, then expand the
- **Variables** section.
-
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Settings > CI/CD**.
+1. Expand **Variables**.
1. Create a CI/CD variable, ensuring the key is prefixed with
`K8S_SECRET_`. For example, you can create a variable with key
`K8S_SECRET_RAILS_MASTER_KEY`.
diff --git a/doc/topics/autodevops/index.md b/doc/topics/autodevops/index.md
index f4936e9162d..e232af05d50 100644
--- a/doc/topics/autodevops/index.md
+++ b/doc/topics/autodevops/index.md
@@ -105,7 +105,7 @@ test your application.
If you want to build, test, and deploy your app:
-1. See the [requirements for deployment](requirements.md).
+1. View the [requirements for deployment](requirements.md).
1. [Enable Auto DevOps](#enable-or-disable-auto-devops).
1. Follow the [quick start guide](#quick-start).
@@ -153,16 +153,18 @@ precedence over the Auto DevOps pipeline.
To enable Auto DevOps for a project:
-1. Go to your project's **Settings > CI/CD > Auto DevOps**.
-1. Select the **Default to Auto DevOps pipeline**.
-1. (Recommended) Add the [base domain](requirements.md#auto-devops-base-domain).
-1. (Recommended) Choose the [deployment strategy](requirements.md#auto-devops-deployment-strategy).
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Settings > CI/CD**.
+1. Expand **Auto DevOps**.
+1. Select the **Default to Auto DevOps pipeline** checkbox.
+1. Optional but recommended. Add the [base domain](requirements.md#auto-devops-base-domain).
+1. Optional but recommended. Choose the [deployment strategy](requirements.md#auto-devops-deployment-strategy).
1. Select **Save changes**.
GitLab triggers the Auto DevOps pipeline on the default branch.
-To disable it, follow the same process and deselect **Default to Auto
-DevOps pipeline**.
+To disable it, follow the same process and clear the
+**Default to Auto DevOps pipeline** checkbox.
#### At the group level
@@ -180,20 +182,22 @@ at the group level.
To enable Auto DevOps for a group:
-1. Go to your group's **Settings > CI/CD > Auto DevOps**.
-1. Select **Default to Auto DevOps pipeline**.
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Settings > CI/CD**.
+1. Expand **Auto DevOps**.
+1. Select the **Default to Auto DevOps pipeline** checkbox.
1. Select **Save changes**.
+To disable Auto DevOps on the group level, follow the same process and
+clear the **Default to Auto DevOps pipeline** checkbox.
+
After enabling Auto DevOps at the group level, you can trigger the
Auto DevOps pipeline for any project that belongs to that group. To do so:
-1. Go to the project's homepage.
+1. On the top bar, select **Menu > Projects** and find your project.
1. Make sure the project doesn't contain a `.gitlab-ci.yml` file.
-1. From the project's sidebar, go to **CI/CD > Pipelines**.
-1. Select **Run pipeline** to trigger the Auto DevOps pipeline.
-
-To disable Auto DevOps on the group level, follow the same process and
-deselect **Default to Auto DevOps pipeline**.
+1. On the left sidebar, select **CI/CD > Pipelines**.
+1. To trigger the Auto DevOps pipeline, select **Run pipeline**.
#### At the instance level **(FREE SELF)**
@@ -210,10 +214,11 @@ can still enable Auto DevOps at the group and project levels.
To enable Auto DevOps for your instance:
-1. From the top bar, select **Menu >** **{admin}** **Admin**.
-1. Go to **Settings > CI/CD > Continuous Integration and Deployment**.
-1. Select **Default to Auto DevOps pipeline**.
-1. (Optional) Add the Auto DevOps [base domain](requirements.md#auto-devops-base-domain).
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > CI/CD**.
+1. Expand **Auto DevOps**.
+1. Select the **Default to Auto DevOps pipeline** checkbox.
+1. Optional. Add the Auto DevOps [base domain](requirements.md#auto-devops-base-domain).
1. Select **Save changes**.
When enabled, it attempts to run Auto DevOps pipelines in every project. If the
@@ -224,7 +229,7 @@ If a [CI/CD configuration file](../../ci/yaml/index.md) is present,
it remains unchanged and Auto DevOps doesn't affect it.
To disable Auto DevOps in the instance level, follow the same process
-and deselect the **Default to Auto DevOps pipeline** checkbox.
+and clear the **Default to Auto DevOps pipeline** checkbox.
### Quick start
diff --git a/doc/topics/autodevops/prepare_deployment.md b/doc/topics/autodevops/prepare_deployment.md
index 830aff11824..c23774b1ffd 100644
--- a/doc/topics/autodevops/prepare_deployment.md
+++ b/doc/topics/autodevops/prepare_deployment.md
@@ -12,7 +12,7 @@ recommend that you prepare them before enabling Auto DevOps.
## Deployment strategy
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/38542) in GitLab 11.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/38542) in GitLab 11.0.
When using Auto DevOps to deploy your applications, choose the
[continuous deployment strategy](../../ci/introduction/index.md)
@@ -44,7 +44,7 @@ To define the base domain, either:
- In the project, group, or instance level: go to your cluster settings and add it there.
- In the project or group level: add it as an environment variable: `KUBE_INGRESS_BASE_DOMAIN`.
-- In the instance level: go to **Menu >** **{admin}** **Admin > Settings > CI/CD> Continuous Integration and Delivery** and add it there.
+- In the instance level: go to **Menu > Admin > Settings > CI/CD > Continuous Integration and Delivery** and add it there.
The base domain variable `KUBE_INGRESS_BASE_DOMAIN` follows the same order of precedence
as other environment [variables](../../ci/variables/index.md#cicd-variable-precedence).
diff --git a/doc/topics/autodevops/quick_start_guide.md b/doc/topics/autodevops/quick_start_guide.md
index 2cf5a5befd7..59c61da0c45 100644
--- a/doc/topics/autodevops/quick_start_guide.md
+++ b/doc/topics/autodevops/quick_start_guide.md
@@ -6,7 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Tutorial: Use Auto DevOps to deploy an application to Google Kubernetes Engine **(FREE)**
-This step-by-step guide helps you use [Auto DevOps](index.md) to
In this tutorial, we'll help you to get started with [Auto DevOps](index.md)
through an example of how to deploy an application to Google Kubernetes Engine (GKE).
@@ -244,7 +243,7 @@ you to common environment tasks:
- **Stop environment** (**{stop}**) - For more information, see
[Stopping an environment](../../ci/environments/index.md#stop-an-environment)
-GitLab displays the [Deploy Board](../../user/project/deploy_boards.md) below the
+GitLab displays the [deploy board](../../user/project/deploy_boards.md) below the
environment's information, with squares representing pods in your
Kubernetes cluster, color-coded to show their status. Hovering over a square on
the deploy board displays the state of the deployment, and selecting the square
diff --git a/doc/topics/autodevops/requirements.md b/doc/topics/autodevops/requirements.md
index 535ec18e5b6..8dd7c0317d9 100644
--- a/doc/topics/autodevops/requirements.md
+++ b/doc/topics/autodevops/requirements.md
@@ -42,7 +42,9 @@ that works best for your needs:
You can choose the deployment method when enabling Auto DevOps or later:
-1. In GitLab, go to your project's **Settings > CI/CD > Auto DevOps**.
+1. In GitLab, on the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Settings > CI/CD**.
+1. Expand **Auto DevOps**.
1. Choose the deployment strategy.
1. Select **Save changes**.
@@ -60,7 +62,7 @@ To define the base domain, either:
- In the project, group, or instance level: go to your cluster settings and add it there.
- In the project or group level: add it as an environment variable: `KUBE_INGRESS_BASE_DOMAIN`.
-- In the instance level: go to **Menu >** **{admin}** **Admin > Settings > CI/CD> Continuous Integration and Delivery** and add it there.
+- In the instance level: go to **Menu > Admin > Settings > CI/CD > Continuous Integration and Delivery** and add it there.
The base domain variable `KUBE_INGRESS_BASE_DOMAIN` follows the same order of precedence
as other environment [variables](../../ci/variables/index.md#cicd-variable-precedence).
@@ -181,9 +183,9 @@ You can choose to target [AWS ECS](../../ci/cloud_deployment/index.md) as a depl
To get started on Auto DevOps to AWS ECS, you must add a specific CI/CD variable.
To do so, follow these steps:
-1. In your project, go to **Settings > CI/CD** and expand the **Variables**
- section.
-
+1. In GitLab, on the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Settings > CI/CD**.
+1. Expand **Auto DevOps**.
1. Specify which AWS platform to target during the Auto DevOps deployment
by adding the `AUTO_DEVOPS_PLATFORM_TARGET` variable with one of the following values:
- `FARGATE` if the service you're targeting must be of launch type FARGATE.
diff --git a/doc/topics/autodevops/stages.md b/doc/topics/autodevops/stages.md
index 3b595cc7ea8..9e6f3103664 100644
--- a/doc/topics/autodevops/stages.md
+++ b/doc/topics/autodevops/stages.md
@@ -425,9 +425,9 @@ including support for `Deployment` in the `extensions/v1beta1` version.
To use Auto Deploy on a Kubernetes 1.16+ cluster:
1. If you are deploying your application for the first time in GitLab 13.0 or
- newer, no configuration should be required.
+ later, no configuration should be required.
-1. In GitLab 12.10 or older, set the following in the [`.gitlab/auto-deploy-values.yaml` file](customize.md#customize-values-for-helm-chart):
+1. In GitLab 12.10 and earlier, set the following in the [`.gitlab/auto-deploy-values.yaml` file](customize.md#customize-values-for-helm-chart):
```yaml
deploymentApiVersion: apps/v1
@@ -696,11 +696,12 @@ To use Auto Monitoring:
1. [Install and configure the Auto DevOps requirements](requirements.md).
1. [Enable Auto DevOps](index.md#enable-or-disable-auto-devops), if you haven't done already.
-1. Navigate to your project's **{rocket}** **CI/CD > Pipelines** and click **Run pipeline**.
+1. On the left sidebar, select **CI/CD > Pipelines**.
+1. Select **Run pipeline**.
1. After the pipeline finishes successfully, open the
[monitoring dashboard for a deployed environment](../../ci/environments/index.md#monitor-environments)
to view the metrics of your deployed application. To view the metrics of the
- whole Kubernetes cluster, navigate to **Operations > Metrics**.
+ whole Kubernetes cluster, on the left sidebar, select **Monitor > Metrics**.
![Auto Metrics](img/auto_monitoring.png)
diff --git a/doc/topics/autodevops/upgrading_auto_deploy_dependencies.md b/doc/topics/autodevops/upgrading_auto_deploy_dependencies.md
index e4378ce2d78..7ddcdcbacb5 100644
--- a/doc/topics/autodevops/upgrading_auto_deploy_dependencies.md
+++ b/doc/topics/autodevops/upgrading_auto_deploy_dependencies.md
@@ -159,7 +159,7 @@ steps to upgrade to v2:
To use a specific version of Auto Deploy dependencies, specify the previous Auto Deploy
stable template that contains the [desired version of `auto-deploy-image` and `auto-deploy-app`](#verify-dependency-versions).
-For example, if the template is bundled in GitLab v13.3, change your `.gitlab-ci.yml` to:
+For example, if the template is bundled in GitLab 13.3, change your `.gitlab-ci.yml` to:
```yaml
include:
@@ -258,7 +258,7 @@ change. If that happens, the deployment job fails with a message similar to:
```plaintext
*************************************************************************************
[WARNING]
-Detected a major version difference between the the chart that is currently deploying (auto-deploy-app-v0.7.0), and the previously deployed chart (auto-deploy-app-v1.0.0).
+Detected a major version difference between the chart that is currently deploying (auto-deploy-app-v0.7.0), and the previously deployed chart (auto-deploy-app-v1.0.0).
A new major version might not be backward compatible with the current release (production). The deployment could fail or be stuck in an unrecoverable status.
...
```
diff --git a/doc/topics/git/cherry_picking.md b/doc/topics/git/cherry_picking.md
index 4a875e25e1b..64d1914019d 100644
--- a/doc/topics/git/cherry_picking.md
+++ b/doc/topics/git/cherry_picking.md
@@ -5,49 +5,76 @@ info: To determine the technical writer assigned to the Stage/Group associated w
comments: false
---
-# Cherry pick **(FREE)**
+# Cherry-pick a Git commit **(FREE)**
-Given an existing commit on one branch, apply the change to another branch.
+In Git, you can *cherry-pick* a commit (a set of changes) from an existing branch,
+and apply those changes to another branch. Cherry-picks can help you:
-This can be useful for backporting bug fixes to previous release branches. Make
-the commit on the default branch, and then cherry pick it into the release branch.
+- Backport bug fixes from the default branch to previous release branches.
+- Copy changes from a fork
+ [to the upstream repository](../../user/project/merge_requests/cherry_pick_changes.md#cherry-pick-into-a-project).
-## Sample workflow
+You can cherry-pick commits from the command line. In the GitLab user interface,
+you can also:
-1. Check out a new `stable` branch from the default branch:
+- Cherry-pick [all changes from a merge request](../../user/project/merge_requests/cherry_pick_changes.md#cherry-pick-a-merge-request).
+- Cherry-pick [a single commit](../../user/project/merge_requests/cherry_pick_changes.md#cherry-pick-a-commit).
+- Cherry-pick [from a fork to the upstream repository](../../user/project/merge_requests/cherry_pick_changes.md#cherry-pick-into-a-project).
+
+## Cherry-pick from the command line
+
+These instructions explain how to cherry-pick a commit from the default branch (`main`)
+into a different branch (`stable`):
+
+1. Check out the default branch, then check out a new `stable` branch based on it:
```shell
- git checkout master
+ git checkout main
git checkout -b stable
```
1. Change back to the default branch:
```shell
- git checkout master
+ git checkout main
```
-1. Make any required changes, then commit the changes:
+1. Make your changes, then commit them:
```shell
git add changed_file.rb
git commit -m 'Fix bugs in changed_file.rb'
```
-1. Review the commit log and copy the SHA of the latest commit:
+1. Display the commit log:
```shell
- git log
+ $ git log
+
+ commit 0000011111222223333344444555556666677777
+ Merge: 88888999999 aaaaabbbbbb
+ Author: user@example.com
+ Date: Tue Aug 31 21:19:41 2021 +0000
```
-1. Check out the `stable` branch:
+1. Identify the `commit` line, and copy the string of letters and numbers on that line.
+ This information is the SHA (Secure Hash Algorithm) of the commit. The SHA is
+ a unique identifier for this commit, and you need it in a future step.
+
+1. Now that you know the SHA, check out the `stable` branch again:
```shell
git checkout stable
```
-1. Cherry pick the commit by using the SHA copied previously:
+1. Cherry-pick the commit into the `stable` branch, and change `SHA` to your commit
+ SHA:
```shell
- git cherry-pick <commit SHA>
+ git cherry-pick <SHA>
```
+
+## Related links
+
+- Cherry-pick commits with [the Commits API](../../api/commits.md#cherry-pick-a-commit)
+- Git documentation [for cherry-picks](https://git-scm.com/docs/git-cherry-pick)
diff --git a/doc/topics/git/git_rebase.md b/doc/topics/git/git_rebase.md
index 0e288f1445e..b09f9fa0f6c 100644
--- a/doc/topics/git/git_rebase.md
+++ b/doc/topics/git/git_rebase.md
@@ -228,8 +228,13 @@ git push --force-with-lease origin my-feature-branch
```
If the branch you want to force-push is [protected](../../user/project/protected_branches.md),
-you can't force-push to it unless you unprotect it first. Then you can
-force-push and re-protect it.
+you can't force push to it unless you either:
+
+- Unprotect it.
+- [Allow force push](../../user/project/protected_branches.md#allow-force-push-on-a-protected-branch)
+ to it.
+
+Then you can force push and protect it again.
## Merge conflicts
diff --git a/doc/topics/git/index.md b/doc/topics/git/index.md
index c1e766a7c48..e95d8121b66 100644
--- a/doc/topics/git/index.md
+++ b/doc/topics/git/index.md
@@ -34,8 +34,8 @@ The following resources can help you get started with Git:
- [Edit files through the command line](../../gitlab-basics/command-line-commands.md)
- [GitLab Git Cheat Sheet (download)](https://about.gitlab.com/images/press/git-cheat-sheet.pdf)
- Commits:
- - [Revert a commit](../../user/project/merge_requests/revert_changes.md#reverting-a-commit)
- - [Cherry-picking a commit](../../user/project/merge_requests/cherry_pick_changes.md#cherry-picking-a-commit)
+ - [Revert a commit](../../user/project/merge_requests/revert_changes.md#revert-a-commit)
+ - [Cherry-picking a commit](../../user/project/merge_requests/cherry_pick_changes.md#cherry-pick-a-commit)
- [Squashing commits](../gitlab_flow.md#squashing-commits-with-rebase)
- [Squash-and-merge](../../user/project/merge_requests/squash_and_merge.md)
- [Signing commits](../../user/project/repository/gpg_signed_commits/index.md)
@@ -58,7 +58,7 @@ The following are resources on version control concepts:
You can do many Git tasks from the command line:
- [Bisect](bisect.md).
-- [Cherry pick](cherry_picking.md).
+- [Cherry-pick](cherry_picking.md).
- [Feature branching](feature_branching.md).
- [Getting started with Git](getting_started.md).
- [Git add](git_add.md).
diff --git a/doc/topics/git/lfs/migrate_to_git_lfs.md b/doc/topics/git/lfs/migrate_to_git_lfs.md
index d1231257f38..2786368a9d7 100644
--- a/doc/topics/git/lfs/migrate_to_git_lfs.md
+++ b/doc/topics/git/lfs/migrate_to_git_lfs.md
@@ -7,6 +7,11 @@ description: "How to migrate an existing Git repository to Git LFS with BFG."
# Migrate a Git repository into Git LFS with BFG
+WARNING:
+The following documentation is deprecated. We recommend using
+[`git lfs migrate`](https://github.com/git-lfs/git-lfs/blob/main/docs/man/git-lfs-migrate.1.ronn)
+instead of the method documented below.
+
Using Git LFS can help you to reduce the size of your Git
repository and improve its performance.
diff --git a/doc/topics/git/numerous_undo_possibilities_in_git/index.md b/doc/topics/git/numerous_undo_possibilities_in_git/index.md
index 4d58c7ab455..9786d1399f7 100644
--- a/doc/topics/git/numerous_undo_possibilities_in_git/index.md
+++ b/doc/topics/git/numerous_undo_possibilities_in_git/index.md
@@ -209,7 +209,7 @@ To recover from multiple incorrect commits:
The commits are now `A-B-C-D-E`.
Alternatively, with GitLab,
-you can [cherry-pick](../../../user/project/merge_requests/cherry_pick_changes.md#cherry-picking-a-commit)
+you can [cherry-pick](../../../user/project/merge_requests/cherry_pick_changes.md#cherry-pick-a-commit)
that commit into a new merge request.
NOTE:
@@ -388,7 +388,6 @@ git filter-branch --tree-filter 'rm filename' HEAD
The `git filter-branch` command might be slow on large repositories.
Tools are available to execute Git commands more quickly.
-An alternative is the open source community-maintained tool [BFG](https://rtyley.github.io/bfg-repo-cleaner/).
These tools are faster because they do not provide the same
feature set as `git filter-branch` does, but focus on specific use cases.
diff --git a/doc/topics/gitlab_flow.md b/doc/topics/gitlab_flow.md
index d9aff6c35e5..e831c35a8ea 100644
--- a/doc/topics/gitlab_flow.md
+++ b/doc/topics/gitlab_flow.md
@@ -7,8 +7,6 @@ disqus_identifier: 'https://docs.gitlab.com/ee/workflow/gitlab_flow.html'
# Introduction to GitLab Flow **(FREE)**
-![GitLab Flow](img/gitlab_flow.png)
-
Git allows a wide variety of branching strategies and workflows.
Because of this, many organizations end up with workflows that are too complicated, not clearly defined, or not integrated with issue tracking systems.
Therefore, we propose GitLab flow as a clearly defined set of best practices.
@@ -16,9 +14,16 @@ It combines [feature-driven development](https://en.wikipedia.org/wiki/Feature-d
Organizations coming to Git from other version control systems frequently find it hard to develop a productive workflow.
This article describes GitLab flow, which integrates the Git workflow with an issue tracking system.
-It offers a transparent and effective way to work with Git.
-
-![Four stages (working copy, index, local repository, remote repository) and three steps between them](img/gitlab_flow_four_stages.png)
+It offers a transparent and effective way to work with Git:
+
+```mermaid
+graph LR
+ subgraph Git workflow
+ A[Working copy] --> |git add| B[Index]
+ B --> |git commit| C[Local repository]
+ C --> |git push| D[Remote repository]
+ end
+```
When converting to Git, you have to get used to the fact that it takes three steps to share a commit with colleagues.
Most version control systems have only one step: committing from the working copy to a shared server.
@@ -26,8 +31,6 @@ In Git, you add files from the working copy to the staging area. After that, you
The third step is pushing to a shared remote repository.
After getting used to these three steps, the next challenge is the branching model.
-![Multiple long-running branches and merging in all directions](img/gitlab_flow_messy_flow.png)
-
Because many organizations new to Git have no conventions for how to work with it, their repositories can quickly become messy.
The biggest problem is that many long-running branches emerge that all contain part of the changes.
People have a hard time figuring out which branch has the latest code, or which branch to deploy to production.
@@ -65,10 +68,20 @@ For example, many projects do releases but don't need to do hotfixes.
## GitHub flow as a simpler alternative
-![Branch with feature branches merged in](img/gitlab_flow_github_flow.png)
-
In reaction to Git flow, GitHub created a simpler alternative.
-[GitHub flow](https://guides.github.com/introduction/flow/index.html) has only feature branches and a `main` branch.
+[GitHub flow](https://guides.github.com/introduction/flow/index.html) has only feature branches and a `main` branch:
+
+```mermaid
+graph TD
+ subgraph Feature branches in GitHub Flow
+ A[main branch] ===>B[main branch]
+ D[nav branch] --> |add navigation| B
+ B ===> C[main branch]
+ E[feature-branch] --> |add feature| C
+ C ==> F[main branch]
+ end
+```
+
This flow is clean and straightforward, and many organizations have adopted it with great success.
Atlassian recommends [a similar strategy](https://www.atlassian.com/blog/git/simple-git-workflow-is-simple), although they rebase feature branches.
Merging everything into the `main` branch and frequently deploying means you minimize the amount of unreleased code. This approach is in line with lean and continuous delivery best practices.
@@ -77,8 +90,6 @@ With GitLab flow, we offer additional guidance for these questions.
## Production branch with GitLab flow
-![Branches with an arrow that indicates a deployment](img/gitlab_flow_production_branch.png)
-
GitHub flow assumes you can deploy to production every time you merge a feature branch.
While this is possible in some cases, such as SaaS applications, there are some cases where this is not possible, such as:
@@ -88,7 +99,22 @@ While this is possible in some cases, such as SaaS applications, there are some
operations team is at full capacity - but you also merge code at other times.
In these cases, you can make a production branch that reflects the deployed code.
-You can deploy a new version by merging `main` into the production branch.
+You can deploy a new version by merging `development` into the production branch:
+
+```mermaid
+graph TD
+ subgraph Production branch in GitLab Flow
+ A[development] ==>B[development]
+ B ==> C[development]
+ C ==> D[development]
+
+ E[production] ====> F[production]
+ C --> |deployment| F
+ D ==> G[development]
+ F ==> H[production]
+ end
+```
+
If you need to know what code is in production, you can check out the production branch to see.
The approximate time of deployment is visible as the merge commit in the version control system.
This time is pretty accurate if you automatically deploy your production branch.
@@ -97,26 +123,66 @@ This flow prevents the overhead of releasing, tagging, and merging that happens
## Environment branches with GitLab flow
-![Multiple branches with the code cascading from one to another](img/gitlab_flow_environment_branches.png)
-
-It might be a good idea to have an environment that is automatically updated to the `main` branch.
+It might be a good idea to have an environment that is automatically updated to the `staging` branch.
Only, in this case, the name of this environment might differ from the branch name.
-Suppose you have a staging environment, a pre-production environment, and a production environment.
-In this case, deploy the `main` branch to staging.
-To deploy to pre-production, create a merge request from the `main` branch to the pre-production branch.
-Go live by merging the pre-production branch into the production branch.
+Suppose you have a staging environment, a pre-production environment, and a production environment:
+
+```mermaid
+graph LR
+ subgraph Environment branches in GitLab Flow
+
+ A[staging] ==> B[staging]
+ B ==> C[staging]
+ C ==> D[staging]
+
+ A --> |deploy to<br>pre-prod| G
+
+ F[pre-prod] ==> G[pre-prod]
+ G ==> H[pre-prod]
+ H ==> I[pre-prod]
+
+ C --> |deploy to<br>pre-prod| I
+
+ J[production] ==> K[production]
+ K ==> L[production]
+
+ G --> |production <br>deployment| K
+
+ end
+```
+
+In this case, deploy the `staging` branch to your staging environment.
+To deploy to pre-production, create a merge request from the `staging` branch to the `pre-prod` branch.
+Go live by merging the `pre-prod` branch into the `production` branch.
This workflow, where commits only flow downstream, ensures that everything is tested in all environments.
-If you need to cherry-pick a commit with a hotfix, it is common to develop it on a feature branch and merge it into `main` with a merge request.
+If you need to cherry-pick a commit with a hotfix, it is common to develop it on a feature branch and merge it into `production` with a merge request.
In this case, do not delete the feature branch yet.
-If `main` passes automatic testing, you then merge the feature branch into the other branches.
+If `production` passes automatic testing, you then merge the feature branch into the other branches.
If this is not possible because more manual testing is required, you can send merge requests from the feature branch to the downstream branches.
## Release branches with GitLab flow
-![Multiple release branches that vary in length with cherry-picks](img/gitlab_flow_release_branches.png)
+You should work with release branches only if you need to release software to
+the outside world. In this case, each branch contains a minor version, such as
+`2.3-stable` or `2.4-stable`:
+
+```mermaid
+graph LR
+ A:::main ===> B((main))
+ B:::main ==> C((main))
+ C:::main ==> D((main))
+ D:::main ==> E((main))
+
+ A((main)) ----> F((2.3-stable)):::first
+ F --> G((2.3-stable)):::first
+ C -.-> |cherry-pick| G
+ D --> H((2.4-stable)):::second
+
+ classDef main fill:#f4f0ff,stroke:#7b58cf
+ classDef first fill:#e9f3fc,stroke:#1f75cb
+ classDef second fill:#ecf4ee,stroke:#108548
+```
-You only need to work with release branches if you need to release software to the outside world.
-In this case, each branch contains a minor version, such as `2-3-stable` or `2-4-stable`.
Create stable branches using `main` as a starting point, and branch as late as possible.
By doing this, you minimize the length of time during which you have to apply bug fixes to multiple branches.
After announcing a release branch, only add serious bug fixes to the branch.
@@ -167,8 +233,6 @@ When you reopen an issue you need to create a new merge request.
## Issue tracking with GitLab flow
-![Merge request with the branch name "15-require-a-password-to-change-it" and assignee field shown](img/gitlab_flow_merge_request.png)
-
GitLab flow is a way to make the relation between the code and the issue tracker more transparent.
Any significant change to the code should start with an issue that describes the goal.
@@ -207,8 +271,6 @@ It is possible that one feature branch solves more than one issue.
## Linking and closing issues from merge requests
-![Merge request showing the linked issues to close](img/gitlab_flow_close_issue_mr.png)
-
Link to issues by mentioning them in commit messages or the description of a merge request, for example, "Fixes #16" or "Duck typing is preferred. See #12."
GitLab then creates links to the mentioned issues and creates comments in the issues linking back to the merge request.
@@ -218,10 +280,35 @@ If you have an issue that spans across multiple repositories, create an issue fo
## Squashing commits with rebase
-![Vim screen showing the rebase view](img/gitlab_flow_rebase.png)
-
With Git, you can use an interactive rebase (`rebase -i`) to squash multiple commits into one or reorder them.
-This feature helps you replace a couple of small commits with a single commit, or if you want to make the order more logical.
+This feature helps you replace a couple of small commits with a single commit, or if you want to make the order more logical:
+
+```shell
+pick c6ee4d3 add a new file to the repo
+pick c3c130b change readme
+
+# Rebase 168afa0..c3c130b onto 168afa0
+#
+# Commands:
+# p, pick = use commit
+# r, reword = use commit, but edit the commit message
+# e, edit = use commit, but stop for amending
+# s, squash = use commit, but meld into previous commit
+# f, fixup = like "squash", but discard this commit's log message
+# x, exec = run command (the rest of the line) using shell
+#
+# These lines can be re-ordered; they are executed from top to bottom.
+#
+# If you remove a line here THAT COMMIT WILL BE LOST.
+#
+# However, if you remove everything, the rebase will be aborted.
+#
+# Note that empty commits are commented out
+~
+~
+~
+"~/demo/gitlab-ce/.git/rebase-merge/git-rebase-todo" 20L, 673C
+```
However, you should avoid rebasing commits you have pushed to a remote server if you have other active contributors in the same branch.
Because rebasing creates new commits for all your changes, it can cause confusion because the same change would have multiple identifiers.
@@ -244,8 +331,6 @@ Git does not allow you to merge the code again otherwise.
## Reducing merge commits in feature branches
-![List of sequential merge commits](img/gitlab_flow_merge_commits.png)
-
Having lots of merge commits can make your repository history messy.
Therefore, you should try to avoid merge commits in feature branches.
Often, people avoid merge commits by just using rebase to reorder their commits after the commits on the `main` branch.
@@ -303,13 +388,19 @@ Sharing your work before it's complete also allows for discussion and feedback a
## How to write a good commit message
-![Good and bad commit message](img/gitlab_flow_good_commit.png)
-
A commit message should reflect your intention, not just the contents of the commit.
-You can see the changes in a commit, so the commit message should explain why you made those changes.
+You can see the changes in a commit, so the commit message should explain why you made those changes:
+
+```shell
+# This commit message doesn't give enough information
+git commit -m 'Improve XML generation'
+
+# These commit messages clearly state the intent of the commit
+git commit -m 'Properly escape special characters in XML generation'
+```
+
An example of a good commit message is: "Combine templates to reduce duplicate code in the user views."
The words "change," "improve," "fix," and "refactor" don't add much information to a commit message.
-For example, "Improve XML generation" could be better written as "Properly escape special characters in XML generation."
For more information about formatting commit messages, please see this excellent [blog post by Tim Pope](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
To add more context to a commit message, consider adding information regarding the
@@ -326,8 +417,6 @@ Issue: gitlab.com/gitlab-org/gitlab/-/issues/1
## Testing before merging
-![Merge requests showing the test states: red, yellow, and green](img/gitlab_flow_ci_mr.png)
-
In old workflows, the continuous integration (CI) server commonly ran tests on the `main` branch only.
Developers had to ensure their code did not break the `main` branch.
When using GitLab flow, developers create their branches from this `main` branch, so it is essential that it never breaks.
@@ -343,8 +432,6 @@ As said before, if you often have feature branches that last for more than a few
## Working with feature branches
-![Shell output showing git pull output](img/gitlab_flow_git_pull.png)
-
When creating a feature branch, always branch from an up-to-date `main`.
If you know before you start that your work depends on another branch, you can also branch from there.
If you need to merge in another branch after starting, explain the reason in the merge commit.
diff --git a/doc/topics/img/gitlab_flow.png b/doc/topics/img/gitlab_flow.png
deleted file mode 100644
index c12405455f9..00000000000
--- a/doc/topics/img/gitlab_flow.png
+++ /dev/null
Binary files differ
diff --git a/doc/topics/img/gitlab_flow_ci_mr.png b/doc/topics/img/gitlab_flow_ci_mr.png
deleted file mode 100644
index 85a609cb814..00000000000
--- a/doc/topics/img/gitlab_flow_ci_mr.png
+++ /dev/null
Binary files differ
diff --git a/doc/topics/img/gitlab_flow_close_issue_mr.png b/doc/topics/img/gitlab_flow_close_issue_mr.png
deleted file mode 100644
index 70de2fb6cee..00000000000
--- a/doc/topics/img/gitlab_flow_close_issue_mr.png
+++ /dev/null
Binary files differ
diff --git a/doc/topics/img/gitlab_flow_environment_branches.png b/doc/topics/img/gitlab_flow_environment_branches.png
deleted file mode 100644
index 0aff33c6bb8..00000000000
--- a/doc/topics/img/gitlab_flow_environment_branches.png
+++ /dev/null
Binary files differ
diff --git a/doc/topics/img/gitlab_flow_four_stages.png b/doc/topics/img/gitlab_flow_four_stages.png
deleted file mode 100644
index 3ef6a33d2d4..00000000000
--- a/doc/topics/img/gitlab_flow_four_stages.png
+++ /dev/null
Binary files differ
diff --git a/doc/topics/img/gitlab_flow_git_pull.png b/doc/topics/img/gitlab_flow_git_pull.png
deleted file mode 100644
index 0e56e59471c..00000000000
--- a/doc/topics/img/gitlab_flow_git_pull.png
+++ /dev/null
Binary files differ
diff --git a/doc/topics/img/gitlab_flow_github_flow.png b/doc/topics/img/gitlab_flow_github_flow.png
deleted file mode 100644
index 21a22becdb6..00000000000
--- a/doc/topics/img/gitlab_flow_github_flow.png
+++ /dev/null
Binary files differ
diff --git a/doc/topics/img/gitlab_flow_good_commit.png b/doc/topics/img/gitlab_flow_good_commit.png
deleted file mode 100644
index ceb0d4b1691..00000000000
--- a/doc/topics/img/gitlab_flow_good_commit.png
+++ /dev/null
Binary files differ
diff --git a/doc/topics/img/gitlab_flow_merge_commits.png b/doc/topics/img/gitlab_flow_merge_commits.png
deleted file mode 100644
index 4a80811c6e3..00000000000
--- a/doc/topics/img/gitlab_flow_merge_commits.png
+++ /dev/null
Binary files differ
diff --git a/doc/topics/img/gitlab_flow_merge_request.png b/doc/topics/img/gitlab_flow_merge_request.png
deleted file mode 100644
index 010e95983fc..00000000000
--- a/doc/topics/img/gitlab_flow_merge_request.png
+++ /dev/null
Binary files differ
diff --git a/doc/topics/img/gitlab_flow_messy_flow.png b/doc/topics/img/gitlab_flow_messy_flow.png
deleted file mode 100644
index 4fa22d2bb5d..00000000000
--- a/doc/topics/img/gitlab_flow_messy_flow.png
+++ /dev/null
Binary files differ
diff --git a/doc/topics/img/gitlab_flow_production_branch.png b/doc/topics/img/gitlab_flow_production_branch.png
deleted file mode 100644
index c132d51bfb6..00000000000
--- a/doc/topics/img/gitlab_flow_production_branch.png
+++ /dev/null
Binary files differ
diff --git a/doc/topics/img/gitlab_flow_rebase.png b/doc/topics/img/gitlab_flow_rebase.png
deleted file mode 100644
index fe865177ba8..00000000000
--- a/doc/topics/img/gitlab_flow_rebase.png
+++ /dev/null
Binary files differ
diff --git a/doc/topics/img/gitlab_flow_release_branches.png b/doc/topics/img/gitlab_flow_release_branches.png
deleted file mode 100644
index 0a7f61d0248..00000000000
--- a/doc/topics/img/gitlab_flow_release_branches.png
+++ /dev/null
Binary files differ
diff --git a/doc/topics/offline/index.md b/doc/topics/offline/index.md
index df6e1f9491e..a48ac9feb1a 100644
--- a/doc/topics/offline/index.md
+++ b/doc/topics/offline/index.md
@@ -4,7 +4,7 @@ group: Distribution
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
---
-# Offline GitLab
+# Offline GitLab **(FREE SELF)**
Computers in an offline environment are isolated from the public internet as a security measure. This
page lists all the information available for running GitLab in an offline environment.
diff --git a/doc/topics/offline/quick_start_guide.md b/doc/topics/offline/quick_start_guide.md
index dd1ddeb31ff..09fae2b1fd5 100644
--- a/doc/topics/offline/quick_start_guide.md
+++ b/doc/topics/offline/quick_start_guide.md
@@ -4,7 +4,7 @@ group: Distribution
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
---
-# Getting started with an offline GitLab Installation
+# Getting started with an offline GitLab Installation **(FREE SELF)**
This is a step-by-step guide that helps you install, configure, and use a self-managed GitLab
instance entirely offline.
diff --git a/doc/update/deprecations.md b/doc/update/deprecations.md
new file mode 100644
index 00000000000..d453c5d8336
--- /dev/null
+++ b/doc/update/deprecations.md
@@ -0,0 +1,67 @@
+---
+stage: none
+group: none
+info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-development-guidelines"
+---
+
+# Deprecated feature removal schedule
+
+<!--
+This page is automatically generated from the YAML files in `/data/deprecations` by the rake task
+located at `lib/tasks/gitlab/docs/compile_deprecations.rake`.
+
+Do not edit this page directly.
+
+To add a deprecation, use the example.yml file in `/data/deprecations/templates` as a template,
+then run `bin/rake gitlab:docs:compile_deprecations`.
+-->
+
+## 15.0
+
+### Legacy database configuration
+
+The syntax of [GitLabs database](https://docs.gitlab.com/omnibus/settings/database.html)
+configuration located in `database.yml` is changing and the legacy format is deprecated. The legacy format
+supported using a single PostgreSQL adapter, whereas the new format is changing to support multiple databases. The `main:` database needs to be defined as a first configuration item.
+
+This deprecation mainly impacts users compiling GitLab from source because Omnibus will handle this configuration automatically.
+
+Announced: 2021-09-22
+
+### Audit events for repository push events
+
+Audit events for [repository events](../administration/audit_events.md#repository-push) are now deprecated and will be removed in GitLab 15.0.
+
+These events have always been disabled by default and had to be manually enabled with a
+feature flag. Enabling them can cause too many events to be generated which can
+dramatically slow down GitLab instances. For this reason, they are being removed.
+
+Announced: 2021-09-02
+
+### OmniAuth Kerberos gem
+
+The `omniauth-kerberos` gem will be removed in our next major release, GitLab 15.0.
+
+This gem has not been maintained and has very little usage. We therefore plan to remove support for this authentication method and recommend using the Kerberos [SPNEGO](https://en.wikipedia.org/wiki/SPNEGO) integration instead. You can follow the [upgrade instructions](../integration/kerberos.md#upgrading-from-password-based-to-ticket-based-kerberos-sign-ins) to upgrade from the `omniauth-kerberos` integration to the supported one.
+
+Note that we are not deprecating the Kerberos SPNEGO integration, only the old password-based Kerberos integration.
+
+Announced: 2021-09-22
+
+### GitLab Serverless
+
+[GitLab Serverless](../user/project/clusters/serverless/index.md) is a feature set to support Knative-based serverless development with automatic deployments and monitoring.
+
+We decided to remove the GitLab Serverless features as they never really resonated with our users. Besides, given the continuous development of Kubernetes and Knative, our current implementations do not even work with recent versions.
+
+Announced: 2021-09-22
+
+## 14.4
+
+### Rename Task Runner pod to Toolbox
+
+The Task Runner pod is used to execute periodic housekeeping tasks within the GitLab application and is often confused with the GitLab Runner. Thus, [Task Runner will be renamed to Toolbox](https://gitlab.com/groups/gitlab-org/charts/-/epics/25).
+
+This will result in the rename of the sub-chart: `gitlab/task-runner` to `gitlab/toolbox`. Resulting pods will be named along the lines of `{{ .Release.Name }}-toolbox`, which will often be `gitlab-toolbox`. They will be locatable with the label `app=toolbox`.
+
+Announced: 2021-09-22
diff --git a/doc/update/index.md b/doc/update/index.md
index 4b7e63a8277..fadb55684f8 100644
--- a/doc/update/index.md
+++ b/doc/update/index.md
@@ -32,12 +32,12 @@ official ways to update GitLab:
### Linux packages (Omnibus GitLab)
-The [Omnibus update guide](https://docs.gitlab.com/omnibus/update/)
+The [package upgrade guide](package/index.md)
contains the steps needed to update a package installed by official GitLab
repositories.
There are also instructions when you want to
-[update to a specific version](https://docs.gitlab.com/omnibus/update/#multi-step-upgrade-using-the-official-repositories).
+[update to a specific version](package/index.md#upgrade-to-a-specific-version-using-the-official-repositories).
### Installation from source
@@ -70,6 +70,10 @@ Instructions on how to update a cloud-native deployment are in
Use the [version mapping](https://docs.gitlab.com/charts/installation/version_mappings.html)
from the chart version to GitLab version to determine the [upgrade path](#upgrade-paths).
+## Plan your upgrade
+
+See the guide to [plan your GitLab upgrade](plan_your_upgrade.md).
+
## Checking for background migrations before upgrading
Certain major/minor releases may require different migrations to be
@@ -79,7 +83,7 @@ finished before you update to the newer version.
To check the status of [batched background migrations](../user/admin_area/monitoring/background_migrations.md):
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Monitoring > Background Migrations**.
![queued batched background migrations table](img/batched_background_migrations_queued_v14_0.png)
@@ -174,15 +178,15 @@ migration](../integration/elasticsearch.md#retry-a-halted-migration).
## Upgrade paths
-Upgrading across multiple GitLab versions in one go is *only possible with downtime*.
-The following examples assume a downtime upgrade.
-See the section below for [zero downtime upgrades](#upgrading-without-downtime).
+Upgrading across multiple GitLab versions in one go is *only possible by accepting downtime*.
+The following examples assume downtime is acceptable while upgrading.
+If you don't want any downtime, read how to [upgrade with zero downtime](zero_downtime.md).
Find where your version sits in the upgrade path below, and upgrade GitLab
accordingly, while also consulting the
[version-specific upgrade instructions](#version-specific-upgrading-instructions):
-`8.11.Z` -> [`8.12.0`](#upgrades-from-versions-earlier-than-812) -> `8.17.7` -> `9.5.10` -> `10.8.7` -> [`11.11.8`](#1200) -> `12.0.12` -> [`12.1.17`](#1210) -> `12.10.14` -> `13.0.14` -> [`13.1.11`](#1310) -> [latest `13.12.Z`](https://about.gitlab.com/releases/categories/releases/) -> [latest `14.0.Z`](#1400) -> [`14.1.Z`](#1410) -> [latest `14.Y.Z`](https://about.gitlab.com/releases/categories/releases/)
+`8.11.Z` -> `8.12.0` -> `8.17.7` -> `9.5.10` -> `10.8.7` -> [`11.11.8`](#1200) -> `12.0.12` -> [`12.1.17`](#1210) -> `12.10.14` -> `13.0.14` -> [`13.1.11`](#1310) -> [`13.8.8`](#1388) -> [latest `13.12.Z`](https://about.gitlab.com/releases/categories/releases/) -> [latest `14.0.Z`](#1400) -> [latest `14.Y.Z`](https://about.gitlab.com/releases/categories/releases/)
The following table, while not exhaustive, shows some examples of the supported
upgrade paths.
@@ -190,7 +194,7 @@ upgrade paths.
| Target version | Your version | Supported upgrade path | Note |
| -------------- | ------------ | ---------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `14.1.2` | `13.9.2` | `13.9.2` -> `13.12.9` -> `14.0.7` -> `14.1.2` | Two intermediate versions are required: `13.12` and `14.0`, then `14.1`. |
-| `13.5.4` | `12.9.2` | `12.9.2` -> `12.10.14` -> `13.0.14` -> `13.1.11` -> `13.5.4` | Three intermediate versions are required: `12.10`, `13.0` and `13.1`, then `13.5.4`. |
+| `13.12.10` | `12.9.2` | `12.9.2` -> `12.10.14` -> `13.0.14` -> `13.1.11` -> `13.8.8` -> `13.12.10` | Four intermediate versions are required: `12.10`, `13.0`, `13.1` and `13.8.8`, then `13.12.10`. |
| `13.2.10` | `11.5.0` | `11.5.0` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.10.14` -> `13.0.14` -> `13.1.11` -> `13.2.10` | Six intermediate versions are required: `11.11`, `12.0`, `12.1`, `12.10`, `13.0` and `13.1`, then `13.2.10`. |
| `12.10.14` | `11.3.4` | `11.3.4` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.10.14` | Three intermediate versions are required: `11.11`, `12.0` and `12.1`, then `12.10.14`. |
| `12.9.5` | `10.4.5` | `10.4.5` -> `10.8.7` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.9.5` | Four intermediate versions are required: `10.8`, `11.11`, `12.0` and `12.1`, then `12.9.5`. |
@@ -229,76 +233,7 @@ upgraded to. This is to ensure [compatibility with GitLab versions](https://docs
## Upgrading without downtime
-Starting with GitLab 9.1.0 it's possible to upgrade to a newer major, minor, or
-patch version of GitLab without having to take your GitLab instance offline.
-However, for this to work there are the following requirements:
-
-- You can only upgrade 1 minor release at a time. So from 9.1 to 9.2, not to
- 9.3. If you skip releases, database modifications may be run in the wrong
- sequence [and leave the database schema in a broken state](https://gitlab.com/gitlab-org/gitlab/-/issues/321542).
-- You have to use [post-deployment
- migrations](../development/post_deployment_migrations.md) (included in
- [zero downtime update steps below](#steps)).
-- You are using PostgreSQL. Starting from GitLab 12.1, MySQL is not supported.
-- Multi-node GitLab instance. Single-node instances may experience brief interruptions
- [as services restart (Puma in particular)](https://docs.gitlab.com/omnibus/update/README.html#single-node-deployment).
-
-Most of the time you can safely upgrade from a patch release to the next minor
-release if the patch release is not the latest. For example, upgrading from
-9.1.1 to 9.2.0 should be safe even if 9.1.2 has been released. We do recommend
-you check the release posts of any releases between your current and target
-version just in case they include any migrations that may require you to upgrade
-1 release at a time.
-
-Some releases may also include so called "background migrations". These
-migrations are performed in the background by Sidekiq and are often used for
-migrating data. Background migrations are only added in the monthly releases.
-
-Certain major/minor releases may require a set of background migrations to be
-finished. To guarantee this, such a release processes any remaining jobs
-before continuing the upgrading procedure. While this doesn't require downtime
-(if the above conditions are met) we require that you [wait for background
-migrations to complete](#checking-for-background-migrations-before-upgrading)
-between each major/minor release upgrade.
-The time necessary to complete these migrations can be reduced by
-increasing the number of Sidekiq workers that can process jobs in the
-`background_migration` queue. To see the size of this queue,
-[Check for background migrations before upgrading](#checking-for-background-migrations-before-upgrading).
-
-As a rule of thumb, any database smaller than 10 GB doesn't take too much time to
-upgrade; perhaps an hour at most per minor release. Larger databases however may
-require more time, but this is highly dependent on the size of the database and
-the migrations that are being performed.
-
-### Examples
-
-To help explain this, let's look at some examples.
-
-**Example 1:** You are running a large GitLab installation using version 9.4.2,
-which is the latest patch release of 9.4. When GitLab 9.5.0 is released this
-installation can be safely upgraded to 9.5.0 without requiring downtime if the
-requirements mentioned above are met. You can also skip 9.5.0 and upgrade to
-9.5.1 after it's released, but you **can not** upgrade straight to 9.6.0; you
-_have_ to first upgrade to a 9.5.Z release.
-
-**Example 2:** You are running a large GitLab installation using version 9.4.2,
-which is the latest patch release of 9.4. GitLab 9.5 includes some background
-migrations, and 10.0 requires these to be completed (processing any
-remaining jobs for you). Skipping 9.5 is not possible without downtime, and due
-to the background migrations would require potentially hours of downtime
-depending on how long it takes for the background migrations to complete. To
-work around this you have to upgrade to 9.5.Z first, then wait at least a
-week before upgrading to 10.0.
-
-**Example 3:** You use MySQL as the database for GitLab. Any upgrade to a new
-major/minor release requires downtime. If a release includes any background
-migrations this could potentially lead to hours of downtime, depending on the
-size of your database. To work around this you must use PostgreSQL and
-meet the other online upgrade requirements mentioned above.
-
-### Steps
-
-Steps to [upgrade without downtime](https://docs.gitlab.com/omnibus/update/README.html#zero-downtime-updates).
+Read how to [upgrade without downtime](zero_downtime.md).
## Upgrading between editions
@@ -320,7 +255,7 @@ Edition, follow the guides below based on the installation method:
to a version upgrade: stop the server, get the code, update configuration files for
the new functionality, install libraries and do migrations, update the init
script, start the application and check its status.
-- [Omnibus CE to EE](https://docs.gitlab.com/omnibus/update/README.html#update-community-edition-to-enterprise-edition) - Follow this guide to update your Omnibus
+- [Omnibus CE to EE](package/convert_to_ee.md) - Follow this guide to update your Omnibus
GitLab Community Edition to the Enterprise Edition.
### Enterprise to Community Edition
@@ -351,21 +286,43 @@ These include:
Apart from the instructions in this section, you should also check the
installation-specific upgrade instructions, based on how you installed GitLab:
-- [Linux packages (Omnibus GitLab)](https://docs.gitlab.com/omnibus/update/README.html#version-specific-changes)
+- [Linux packages (Omnibus GitLab)](../update/package/index.md#version-specific-changes)
- [Helm charts](https://docs.gitlab.com/charts/installation/upgrade.html)
NOTE:
Specific information that follow related to Ruby and Git versions do not apply to [Omnibus installations](https://docs.gitlab.com/omnibus/)
and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with appropriate Ruby and Git versions and are not using system binaries for Ruby and Git. There is no need to install Ruby or Git when utilizing these two approaches.
+### 14.3.0
+
+Ruby 2.7.4 is required. Refer to [the Ruby installation instructions](../install/installation.md#2-ruby)
+for how to proceed.
+
+- GitLab 14.3.0 contains post-deployment migrations to [address Primary Key overflow risk for tables with an integer PK](https://gitlab.com/groups/gitlab-org/-/epics/4785) for the tables listed below:
+
+ - [`ci_builds.id`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70245)
+ - [`ci_builds.stage_id`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66688)
+ - [`ci_builds_metadata`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65692)
+ - [`taggings`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66625)
+ - [`events`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64779)
+
+ If the migrations are executed as part of a no-downtime deployment, there's a risk of failure due to lock conflicts with the application logic, resulting in lock timeout or deadlocks. In each case, these migrations are safe to re-run until successful:
+
+ ```shell
+ # For Omnibus GitLab
+ sudo gitlab-rake db:migrate
+
+ # For source installations
+ sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
+ ```
+
### 14.2.0
- Due to an issue where `BatchedBackgroundMigrationWorkers` were
[not working](https://gitlab.com/gitlab-org/charts/gitlab/-/issues/2785#note_614738345)
for self-managed instances, a [fix was created](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65106)
- and a [14.0.Z](#1400) version was released. If you haven't updated to 14.0.Z, you need
- to update to at least 14.1.0 that contains the same fix before you update to
- to 14.2.
+ and a [14.0.Z](#1400) version was released. If you haven't updated to 14.0.5, you need
+ to update to at least 14.1.0 that contains the same fix before you update to 14.2.
- GitLab 14.2.0 contains background migrations to [address Primary Key overflow risk for tables with an integer PK](https://gitlab.com/groups/gitlab-org/-/epics/4785) for the tables listed below:
- [`ci_build_needs`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65216)
@@ -393,7 +350,7 @@ and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with ap
- Due to an issue where `BatchedBackgroundMigrationWorkers` were
[not working](https://gitlab.com/gitlab-org/charts/gitlab/-/issues/2785#note_614738345)
for self-managed instances, a [fix was created](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65106)
- and a [14.0.Z](#1400) version was released. If you haven't updated to 14.0.Z, you need
+ and a [14.0.Z](#1400) version was released. If you haven't updated to 14.0.5, you need
to update to at least 14.1.0 that contains the same fix before you update to
a later version.
@@ -480,6 +437,17 @@ DETAIL: trigger trigger_0d588df444c8 on table application_settings depends on co
To work around this bug, follow the previous steps to complete the update.
More details are available [in this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/324160).
+### 13.8.8
+
+GitLab 13.8 includes a background migration to address [an issue with duplicate service records](https://gitlab.com/gitlab-org/gitlab/-/issues/290008). If duplicate services are present, this background migration must complete before a unique index is applied to the services table, which was [introduced in GitLab 13.9](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52563). Upgrades from GitLab 13.8 and earlier to later versions must include an intermediate upgrade to GitLab 13.8.8 and [must wait until the background migrations complete](#checking-for-background-migrations-before-upgrading) before proceeding.
+
+If duplicate services are still present, an upgrade to 13.9.x or later results in a failed upgrade with the following error:
+
+```console
+PG::UniqueViolation: ERROR: could not create unique index "index_services_on_project_id_and_type_unique"
+DETAIL: Key (project_id, type)=(NNN, ServiceName) is duplicated.
+```
+
### 13.6.0
Ruby 2.7.2 is required. GitLab does not start with Ruby 2.6.6 or older versions.
@@ -528,7 +496,7 @@ The Rails upgrade included a change to CSRF token generation which is
not backwards-compatible - GitLab servers with the new Rails version
generate CSRF tokens that are not recognizable by GitLab servers
with the older Rails version - which could cause non-GET requests to
-fail for [multi-node GitLab installations](https://docs.gitlab.com/omnibus/update/#multi-node--ha-deployment).
+fail for [multi-node GitLab installations](zero_downtime.md#multi-node--ha-deployment).
So, if you are using multiple Rails servers and specifically upgrading from 13.0,
all servers must first be upgraded to 13.1.Z before upgrading to 13.2.0 or later:
@@ -577,12 +545,6 @@ After upgraded to 11.11.8 you can safely upgrade to 12.0.Z.
See our [documentation on upgrade paths](../policy/maintenance.md#upgrade-recommendations)
for more information.
-### Upgrades from versions earlier than 8.12
-
-- `8.11.Z` and earlier: you might have to upgrade to `8.12.0` specifically before you can upgrade to `8.17.7`. This was [reported in an issue](https://gitlab.com/gitlab-org/gitlab/-/issues/207259).
-- [CI changes prior to version 8.0](https://docs.gitlab.com/omnibus/update/README.html#updating-gitlab-ci-from-prior-540-to-version-714-via-omnibus-gitlab)
- when it was merged into GitLab.
-
## Miscellaneous
- [MySQL to PostgreSQL](mysql_to_postgresql.md) guides you through migrating
diff --git a/doc/update/package/convert_to_ee.md b/doc/update/package/convert_to_ee.md
new file mode 100644
index 00000000000..2cc54e2c8cf
--- /dev/null
+++ b/doc/update/package/convert_to_ee.md
@@ -0,0 +1,118 @@
+---
+stage: Enablement
+group: Distribution
+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/#designated-technical-writers
+---
+
+# Convert Community Edition to Enterprise Edition **(FREE SELF)**
+
+To convert an existing GitLab Community Edition (CE) server installed using the Omnibus GitLab
+packages to GitLab [Enterprise Edition](https://about.gitlab.com/pricing/) (EE), you install the EE
+package on top of CE.
+
+Converting from the same version of CE to EE is not explicitly necessary, and any standard upgrade
+(for example, CE 12.0 to EE 12.1) should work. However, in the following steps we assume that
+you are upgrading the same version (for example, CE 12.1 to EE 12.1), which is **recommended**.
+
+WARNING:
+When updating to EE from CE, avoid reverting back to CE if you plan on going to EE again in the
+future. Reverting back to CE can cause
+[database issues](index.md#500-error-when-accessing-project--settings--repository)
+that may require Support intervention.
+
+The steps can be summed up to:
+
+1. Find the currently installed GitLab version:
+
+ **For Debian/Ubuntu**
+
+ ```shell
+ sudo apt-cache policy gitlab-ce | grep Installed
+ ```
+
+ The output should be similar to: `Installed: 13.0.4-ce.0`. In that case,
+ the equivalent Enterprise Edition version will be: `13.0.4-ee.0`. Write this
+ value down.
+
+ **For CentOS/RHEL**
+
+ ```shell
+ sudo rpm -q gitlab-ce
+ ```
+
+ The output should be similar to: `gitlab-ce-13.0.4-ce.0.el8.x86_64`. In that
+ case, the equivalent Enterprise Edition version will be:
+ `gitlab-ee-13.0.4-ee.0.el8.x86_64`. Write this value down.
+
+1. Add the `gitlab-ee` [Apt or Yum repository](https://packages.gitlab.com/gitlab/gitlab-ee/install):
+
+ **For Debian/Ubuntu**
+
+ ```shell
+ curl --silent "https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh" | sudo bash
+ ```
+
+ **For CentOS/RHEL**
+
+ ```shell
+ curl --silent "https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.rpm.sh" | sudo bash
+ ```
+
+ The above command will find your OS version and automatically set up the
+ repository. If you are not comfortable installing the repository through a
+ piped script, you can first
+ [check its contents](https://packages.gitlab.com/gitlab/gitlab-ee/install).
+
+1. Next, install the `gitlab-ee` package. Note that this will automatically
+ uninstall the `gitlab-ce` package on your GitLab server. `reconfigure`
+ Omnibus right after the `gitlab-ee` package is installed. **Make sure that you
+ install the exact same GitLab version**:
+
+ **For Debian/Ubuntu**
+
+ ```shell
+ ## Make sure the repositories are up-to-date
+ sudo apt-get update
+
+ ## Install the package using the version you wrote down from step 1
+ sudo apt-get install gitlab-ee=13.0.4-ee.0
+
+ ## Reconfigure GitLab
+ sudo gitlab-ctl reconfigure
+ ```
+
+ **For CentOS/RHEL**
+
+ ```shell
+ ## Install the package using the version you wrote down from step 1
+ sudo yum install gitlab-ee-13.0.4-ee.0.el8.x86_64
+
+ ## Reconfigure GitLab
+ sudo gitlab-ctl reconfigure
+ ```
+
+1. Now go to the GitLab admin panel of your server (`/admin/license/new`) and
+ upload your license file.
+
+1. After you confirm that GitLab is working as expected, you may remove the old
+ Community Edition repository:
+
+ **For Debian/Ubuntu**
+
+ ```shell
+ sudo rm /etc/apt/sources.list.d/gitlab_gitlab-ce.list
+ ```
+
+ **For CentOS/RHEL**
+
+ ```shell
+ sudo rm /etc/yum.repos.d/gitlab_gitlab-ce.repo
+ ```
+
+That's it! You can now use GitLab Enterprise Edition! To update to a newer
+version, follow [Update using the official repositories](index.md#upgrade-using-the-official-repositories).
+
+NOTE:
+If you want to use `dpkg`/`rpm` instead of `apt-get`/`yum`, go through the first
+step to find the current GitLab version and then follow
+[Update using a manually-downloaded package](index.md#upgrade-using-a-manually-downloaded-package).
diff --git a/doc/update/package/downgrade.md b/doc/update/package/downgrade.md
new file mode 100644
index 00000000000..9a528f5ee44
--- /dev/null
+++ b/doc/update/package/downgrade.md
@@ -0,0 +1,83 @@
+---
+stage: Enablement
+group: Distribution
+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/#designated-technical-writers
+---
+
+# Downgrade **(FREE SELF)**
+
+This section contains general information on how to revert to an earlier version
+of a package.
+
+WARNING:
+You must at least have a database backup created under the version you are
+downgrading to. Ideally, you should have a
+[full backup archive](../../raketasks/backup_restore.md#back-up-gitlab)
+on hand.
+
+The example below demonstrates the downgrade procedure when downgrading between minor
+and patch versions (for example, from 13.0.6 to 13.0.5).
+
+When downgrading between major versions, take into account the
+[specific version changes](index.md#version-specific-changes) that occurred when you upgraded
+to the major version you are downgrading from.
+
+These steps consist of:
+
+- Stopping GitLab
+- Removing the current package
+- Installing the old package
+- Reconfiguring GitLab
+- Restoring the backup
+- Starting GitLab
+
+Steps:
+
+1. Stop GitLab and remove the current package:
+
+ ```shell
+ # If running Puma
+ sudo gitlab-ctl stop puma
+
+ # Stop sidekiq
+ sudo gitlab-ctl stop sidekiq
+
+ # If on Ubuntu: remove the current package
+ sudo dpkg -r gitlab-ee
+
+ # If on Centos: remove the current package
+ sudo yum remove gitlab-ee
+ ```
+
+1. Identify the GitLab version you want to downgrade to:
+
+ ```shell
+ # (Replace with gitlab-ce if you have GitLab FOSS installed)
+
+ # Ubuntu
+ sudo apt-cache madison gitlab-ee
+
+ # CentOS:
+ sudo yum --showduplicates list gitlab-ee
+ ```
+
+1. Downgrade GitLab to the desired version (for example, to GitLab 13.0.5):
+
+ ```shell
+ # (Replace with gitlab-ce if you have GitLab FOSS installed)
+
+ # Ubuntu
+ sudo apt install gitlab-ee=13.0.5-ee.0
+
+ # CentOS:
+ sudo yum install gitlab-ee-13.0.5-ee.0.el8
+ ```
+
+1. Reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+1. [Restore GitLab](../../raketasks/backup_restore.md#restore-for-omnibus-gitlab-installations)
+ to complete the downgrade.
diff --git a/doc/update/package/index.md b/doc/update/package/index.md
new file mode 100644
index 00000000000..44be79f22fb
--- /dev/null
+++ b/doc/update/package/index.md
@@ -0,0 +1,278 @@
+---
+stage: Enablement
+group: Distribution
+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/#designated-technical-writers
+---
+
+# Upgrade GitLab using the GitLab Package **(FREE SELF)**
+
+This section describes how to upgrade GitLab to a new version using the
+GitLab package.
+
+We recommend performing upgrades between major and minor releases no more than once per
+week, to allow time for background migrations to finish. Decrease the time required to
+complete these migrations by increasing the number of
+[Sidekiq workers](../../administration/operations/extra_sidekiq_processes.md)
+that can process jobs in the `background_migration` queue.
+
+If you don't follow the steps in [zero downtime upgrades](../zero_downtime.md),
+your GitLab application will not be available to users while an upgrade is in progress.
+They either see a "Deploy in progress" message or a "502" error in their web browser.
+
+Prerequisites:
+
+- [Supported upgrade paths](../index.md#upgrade-paths)
+ has suggestions on when to upgrade. Upgrade paths are enforced for version upgrades by
+ default. This restricts performing direct upgrades that skip major versions (for
+ example 10.3 to 12.7 in one jump) that **can break GitLab
+ installations** due to multiple reasons like deprecated or removed configuration
+ settings, upgrade of internal tools and libraries, and so on.
+- If you are upgrading from a non-Package installation to a GitLab Package installation, see
+ [Upgrading from a non-Package installation to a GitLab Package installation](https://docs.gitlab.com/omnibus/convert_to_omnibus.html).
+- It's important to ensure that any
+ [background migrations](../index.md#checking-for-background-migrations-before-upgrading)
+ have been fully completed before upgrading to a new major version. Upgrading
+ before background migrations have finished may lead to data corruption.
+- Gitaly servers must be upgraded to the newer version prior to upgrading the application server.
+ This prevents the gRPC client on the application server from sending RPCs that the old Gitaly version
+ does not support.
+
+You can upgrade the GitLab Package using one of the following methods:
+
+- [Using the official repositories](#upgrade-using-the-official-repositories).
+- [Using a manually-downloaded package](#upgrade-using-a-manually-downloaded-package).
+
+Both automatically back up the GitLab database before installing a newer
+GitLab version. You may skip this automatic database backup by creating an empty file
+at `/etc/gitlab/skip-auto-backup`:
+
+```shell
+sudo touch /etc/gitlab/skip-auto-backup
+```
+
+For safety reasons, you should maintain an up-to-date backup on your own if you plan to use this flag.
+
+## Version-specific changes
+
+Updating to major versions might need some manual intervention. For more information,
+check the version your are upgrading to:
+
+- [GitLab 14](https://docs.gitlab.com/omnibus/gitlab_14_changes.html)
+- [GitLab 13](https://docs.gitlab.com/omnibus/gitlab_13_changes.html)
+- [GitLab 12](https://docs.gitlab.com/omnibus/gitlab_12_changes.html)
+- [GitLab 11](https://docs.gitlab.com/omnibus/gitlab_11_changes.html)
+
+## Upgrade using the official repositories
+
+All GitLab packages are posted to the GitLab [package server](https://packages.gitlab.com/gitlab/).
+Five repositories are maintained:
+
+- [GitLab EE](https://packages.gitlab.com/gitlab/gitlab-ee): for official
+ [Enterprise Edition](https://about.gitlab.com/pricing/) releases.
+- [GitLab CE](https://packages.gitlab.com/gitlab/gitlab-ce): for official Community Edition releases.
+- [Unstable](https://packages.gitlab.com/gitlab/unstable): for release candidates and other unstable versions.
+- [Nighty Builds](https://packages.gitlab.com/gitlab/nightly-builds): for nightly builds.
+- [Raspberry Pi](https://packages.gitlab.com/gitlab/raspberry-pi2): for official Community Edition releases built for [Raspberry Pi](https://www.raspberrypi.org) packages.
+
+If you have installed Omnibus GitLab [Community Edition](https://about.gitlab.com/install/?version=ce)
+or [Enterprise Edition](https://about.gitlab.com/install/), then the
+official GitLab repository should have already been set up for you.
+
+To upgrade to the newest GitLab version, run:
+
+- For GitLab [Enterprise Edition](https://about.gitlab.com/pricing/):
+
+ ```shell
+ # Debian/Ubuntu
+ sudo apt-get update
+ sudo apt-get install gitlab-ee
+
+ # Centos/RHEL
+ sudo yum install gitlab-ee
+ ```
+
+- For GitLab Community Edition:
+
+ ```shell
+ # Debian/Ubuntu
+ sudo apt-get update
+ sudo apt-get install gitlab-ce
+
+ # Centos/RHEL
+ sudo yum install gitlab-ce
+ ```
+
+### Upgrade to a specific version using the official repositories
+
+Linux package managers default to installing the latest available version of a
+package for installation and upgrades. Upgrading directly to the latest major
+version can be problematic for older GitLab versions that require a multi-stage
+[upgrade path](../index.md#upgrade-paths). An upgrade path can span multiple
+versions, so you must specify the specific GitLab package with each upgrade.
+
+To specify the intended GitLab version number in your package manager's install
+or upgrade command:
+
+1. First, identify the GitLab version number in your package manager:
+
+ ```shell
+ # Ubuntu/Debian
+ sudo apt-cache madison gitlab-ee
+ # RHEL/CentOS 6 and 7
+ yum --showduplicates list gitlab-ee
+ # RHEL/CentOS 8
+ dnf search gitlab-ee*
+ ```
+
+1. Then install the specific GitLab package:
+
+ ```shell
+ # Ubuntu/Debian
+ sudo apt install gitlab-ee=12.0.12-ee.0
+ # RHEL/CentOS 6 and 7
+ yum install gitlab-ee-12.0.12-ee.0.el7
+ # RHEL/CentOS 8
+ dnf install gitlab-ee-12.0.12-ee.0.el8
+ # SUSE
+ zypper install gitlab-ee=12.0.12-ee.0
+ ```
+
+## Upgrade using a manually-downloaded package
+
+NOTE:
+The [package repository](#upgrade-using-the-official-repositories) is recommended over
+a manual installation.
+
+If for some reason you don't use the official repositories, you can
+download the package and install it manually. This method can be used to either
+install GitLab for the first time or update it.
+
+To download and install GitLab:
+
+1. Visit the [official repository](#upgrade-using-the-official-repositories) of your package.
+1. Browse to the repository for the type of package you would like to see the
+ list of packages that are available. Multiple packages exist for a
+ single version, one for each supported distribution type. Next to the filename
+ is a label indicating the distribution, as the file names may be the same.
+1. Find the package version you wish to install and click on it.
+1. Click the **Download** button in the upper right corner to download the package.
+1. After the GitLab package is downloaded, install it using the following commands:
+
+ - For GitLab [Enterprise Edition](https://about.gitlab.com/pricing/):
+
+ ```shell
+ # Debian/Ubuntu
+ dpkg -i gitlab-ee-<version>.deb
+
+ # CentOS/RHEL
+ rpm -Uvh gitlab-ee-<version>.rpm
+ ```
+
+ - For GitLab Community Edition:
+
+ ```shell
+ # GitLab Community Edition
+ # Debian/Ubuntu
+ dpkg -i gitlab-ce-<version>.deb
+
+ # CentOS/RHEL
+ rpm -Uvh gitlab-ce-<version>.rpm
+ ```
+
+## Troubleshooting
+
+### GitLab 13.7 and later unavailable on Amazon Linux 2
+
+Amazon Linux 2 is not an [officially supported operating system](../../administration/package_information/deprecated_os.md#supported-operating-systems).
+However, in past the [official package installation script](https://packages.gitlab.com/gitlab/gitlab-ee/install)
+installed the `el/6` package repository if run on Amazon Linux. From GitLab 13.7, we no longer
+provide `el/6` packages so administrators must run the [installation script](https://packages.gitlab.com/gitlab/gitlab-ee/install)
+again to update the repository to `el/7`:
+
+```shell
+curl --silent "https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.rpm.sh" | sudo bash
+```
+
+See the [epic on support for GitLab on Amazon Linux 2](https://gitlab.com/groups/gitlab-org/-/epics/2195) for the latest details on official Amazon Linux 2 support.
+
+### Get the status of a GitLab installation
+
+```shell
+sudo gitlab-ctl status
+sudo gitlab-rake gitlab:check SANITIZE=true
+```
+
+- Information on using `gitlab-ctl` to perform [maintenance tasks](https://docs.gitlab.com/omnibus/maintenance/index.html).
+- Information on using `gitlab-rake` to [check the configuration](../../administration/raketasks/maintenance.md#check-gitlab-configuration).
+
+### RPM 'package is already installed' error
+
+If you are using RPM and you are upgrading from GitLab Community Edition to GitLab Enterprise Edition you may get an error like this:
+
+```shell
+package gitlab-7.5.2_omnibus.5.2.1.ci-1.el7.x86_64 (which is newer than gitlab-7.5.2_ee.omnibus.5.2.1.ci-1.el7.x86_64) is already installed
+```
+
+You can override this version check with the `--oldpackage` option:
+
+```shell
+sudo rpm -Uvh --oldpackage gitlab-7.5.2_ee.omnibus.5.2.1.ci-1.el7.x86_64.rpm
+```
+
+### Package obsoleted by installed package
+
+CE and EE packages are marked as obsoleting and replacing each other so that both aren't installed and running at the same time.
+
+If you are using local RPM files to switch from CE to EE or vice versa, use `rpm` for installing the package rather than `yum`. If you try to use yum, then you may get an error like this:
+
+```plaintext
+Cannot install package gitlab-ee-11.8.3-ee.0.el6.x86_64. It is obsoleted by installed package gitlab-ce-11.8.3-ce.0.el6.x86_64
+```
+
+To avoid this issue, either:
+
+- Use the same instructions provided in the
+ [Upgrade using a manually-downloaded package](#upgrade-using-a-manually-downloaded-package) section.
+- Temporarily disable this checking in yum by adding `--setopt=obsoletes=0` to the options given to the command.
+
+### 500 error when accessing Project > Settings > Repository
+
+When GitLab is migrated from CE > EE > CE, and then back to EE, you
+might get the following error when viewing a project's repository settings:
+
+```shell
+Processing by Projects::Settings::RepositoryController#show as HTML
+ Parameters: {"namespace_id"=>"<namespace_id>", "project_id"=>"<project_id>"}
+Completed 500 Internal Server Error in 62ms (ActiveRecord: 4.7ms | Elasticsearch: 0.0ms | Allocations: 14583)
+
+NoMethodError (undefined method `commit_message_negative_regex' for #<PushRule:0x00007fbddf4229b8>
+Did you mean? commit_message_regex_change):
+```
+
+This error is caused by an EE feature being added to a CE instance on the initial move to EE.
+After the instance is moved back to CE and then is upgraded to EE again, the
+`push_rules` table already exists in the database. Therefore, a migration is
+unable to add the `commit_message_regex_change` column.
+
+This results in the [backport migration of EE tables](https://gitlab.com/gitlab-org/gitlab/-/blob/cf00e431024018ddd82158f8a9210f113d0f4dbc/db/migrate/20190402150158_backport_enterprise_schema.rb#L1619) not working correctly.
+The backport migration assumes that certain tables in the database do not exist when running CE.
+
+To fix this issue, manually add the missing `commit_message_negative_regex` column and restart GitLab:
+
+```shell
+# Access psql
+sudo gitlab-rails dbconsole
+
+# Add the missing column
+ALTER TABLE push_rules ADD COLUMN commit_message_negative_regex VARCHAR;
+
+# Exit psql
+\q
+
+# Restart GitLab
+sudo gitlab-ctl restart
+```
+
+### Error `Failed to connect to the internal GitLab API` on a separate GitLab Pages server
+
+Please see [GitLab Pages troubleshooting](../../administration/pages/index.md#failed-to-connect-to-the-internal-gitlab-api).
diff --git a/doc/update/patch_versions.md b/doc/update/patch_versions.md
index 0a7057ffe97..d09f19d143b 100644
--- a/doc/update/patch_versions.md
+++ b/doc/update/patch_versions.md
@@ -103,7 +103,7 @@ sudo -u git -H make
### 8. Install/Update `gitlab-elasticsearch-indexer` **(PREMIUM SELF)**
-Please follow the [install instruction](../integration/elasticsearch.md#installing-elasticsearch).
+Please follow the [install instruction](../integration/elasticsearch.md#install-elasticsearch).
### 9. Start application
diff --git a/doc/update/plan_your_upgrade.md b/doc/update/plan_your_upgrade.md
new file mode 100644
index 00000000000..406f8322218
--- /dev/null
+++ b/doc/update/plan_your_upgrade.md
@@ -0,0 +1,180 @@
+---
+stage: Enablement
+group: Distribution
+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
+---
+
+# Create a GitLab upgrade plan
+
+This document serves as a guide to create a strong plan to upgrade a self-managed
+GitLab instance.
+
+General notes:
+
+- If possible, we recommend you test out the upgrade in a test environment before
+ updating your production instance. Ideally, your test environment should mimic
+ your production environment as closely as possible.
+- If [working with Support](https://about.gitlab.com/support/scheduling-live-upgrade-assistance.html)
+ to create your plan, share details of your architecture, including:
+ - How is GitLab installed?
+ - What is the operating system of the node?
+ (check [OS versions that are no longer supported](../administration/package_information/deprecated_os.md) to confirm that later updates are available).
+ - Is it a single-node or a multi-node setup? If multi-node, share any architectural details about each node with us.
+ - Are you using [GitLab Geo](../administration/geo/index.md)? If so, share any architectural details about each secondary node.
+ - What else might be unique or interesting in your setup that might be important for us to understand?
+ - Are you running into any known issues with your current version of GitLab?
+
+## Pre-upgrade and post-upgrade checks
+
+Immediately before and after the upgrade, perform the pre-upgrade and post-upgrade checks
+to ensure the major components of GitLab are working:
+
+1. [Check the general configuration](../administration/raketasks/maintenance.md#check-gitlab-configuration):
+
+ ```shell
+ sudo gitlab-rake gitlab:check
+ ```
+
+1. Confirm that encrypted database values [can be decrypted](../administration/raketasks/doctor.md#verify-database-values-can-be-decrypted-using-the-current-secrets):
+
+ ```shell
+ sudo gitlab-rake gitlab:doctor:secrets
+ ```
+
+1. In GitLab UI, check that:
+ - Users can log in.
+ - The project list is visible.
+ - Project issues and merge requests are accessible.
+ - Users can clone repositories from GitLab.
+ - Users can push commits to GitLab.
+
+1. For GitLab CI/CD, check that:
+ - Runners pick up jobs.
+ - Docker images can be pushed and pulled from the registry.
+
+1. If using Geo, run the relevant checks on the primary and each secondary:
+
+ ```shell
+ sudo gitlab-rake gitlab:geo:check
+ ```
+
+1. If using Elasticsearch, verify that searches are successful.
+
+If in any case something goes wrong, see [how to troubleshoot](#troubleshooting).
+
+## Rollback plan
+
+It's possible that something may go wrong during an upgrade, so it's critical
+that a rollback plan be present for that scenario. A proper rollback plan
+creates a clear path to bring the instance back to its last working state. It is
+comprised of a way to back up the instance and a way to restore it.
+
+### Back up GitLab
+
+Create a backup of GitLab and all its data (database, repos, uploads, builds,
+artifacts, LFS objects, registry, pages). This is vital for making it possible
+to roll back GitLab to a working state if there's a problem with the upgrade:
+
+- Create a [GitLab backup](../raketasks/backup_restore.md#back-up-gitlab).
+ Make sure to follow the instructions based on your installation method.
+ Don't forget to back up the [secrets and configuration files](../raketasks/backup_restore.md#storing-configuration-files).
+- Alternatively, create a snapshot of your instance. If this is a multi-node
+ installation, you must snapshot every node.
+ **This process is out of scope for GitLab Support.**
+
+### Restore GitLab
+
+To restore your GitLab backup:
+
+- Before restoring, make sure to read about the
+ [prerequisites](../raketasks/backup_restore.md#restore-gitlab), most importantly,
+ the versions of the backed up and the new GitLab instance must be the same.
+- [Restore GitLab](../raketasks/backup_restore.md#restore-gitlab).
+ Make sure to follow the instructions based on your installation method.
+ Confirm that the [secrets and configuration files](../raketasks/backup_restore.md#storing-configuration-files) are also restored.
+- If restoring from a snapshot, know the steps to do this.
+ **This process is out of scope for GitLab Support.**
+
+## Upgrade plan
+
+For the upgrade plan, start by creating an outline of a plan that best applies
+to your instance and then upgrade it for any relevant features you're using.
+
+- Generate an upgrade plan by reading and understanding the relevant documentation:
+ - upgrade based on the installation method:
+ - [Linux package (Omnibus)](index.md#linux-packages-omnibus-gitlab)
+ - [Compiled from source](index.md#installation-from-source)
+ - [Docker](index.md#installation-using-docker)
+ - [Helm Charts](index.md#installation-using-helm)
+ - [Zero-downtime upgrades](zero_downtime.md) (if possible and desired)
+ - [Convert from GitLab Community Edition to Enterprise Edition](package/convert_to_ee.md)
+- What version should you upgrade to:
+ - [Determine what upgrade path](index.md#upgrade-paths) to follow.
+ - Account for any [version-specific update instructions](index.md#version-specific-upgrading-instructions).
+ - Account for any [version-specific changes](package/index.md#version-specific-changes).
+ - Check the [OS compatibility with the target GitLab version](../administration/package_information/deprecated_os.md).
+- Due to background migrations, plan to pause any further upgrades after upgrading
+ to a new major version.
+ [All migrations must finish running](index.md#checking-for-background-migrations-before-upgrading)
+ before the next upgrade.
+- If available in your starting version, consider
+ [turning on maintenance mode](../administration/maintenance_mode/) during the
+ upgrade.
+- About PostgreSQL:
+ - On the top bar, select **Menu > Admin**, and look for the version of
+ PostgreSQL you are using.
+ If [a PostgreSQL upgrade is needed](../administration/package_information/postgresql_versions.md),
+ account for the relevant
+ [packaged](https://docs.gitlab.com/omnibus/settings/database.html#upgrade-packaged-postgresql-server)
+ or [non-packaged](https://docs.gitlab.com/omnibus/settings/database.html#upgrade-a-non-packaged-postgresql-database) steps.
+
+### Additional features
+
+Apart from all the generic information above, you may have enabled some features
+that require special planning.
+
+Feel free to ignore sections about features that are inapplicable to your setup,
+such as Geo, external Gitaly, or Elasticsearch.
+
+#### External Gitaly
+
+If you're using an external Gitaly server, it must be upgraded to the newer
+version prior to upgrading the application server.
+
+#### Geo
+
+If you're using Geo:
+
+- Review [Geo upgrade documentation](../administration/geo/replication/updating_the_geo_nodes.md).
+- Read about the [Geo version-specific update instructions](../administration/geo/replication/version_specific_updates.md).
+- Review Geo-specific steps when [updating the database](https://docs.gitlab.com/omnibus/settings/database.html#upgrading-a-geo-instance).
+- Create an upgrade and rollback plan for _each_ Geo node (primary and each secondary).
+
+#### Runners
+
+After updating GitLab, upgrade your runners to match
+[your new GitLab version](https://docs.gitlab.com/runner/#gitlab-runner-versions).
+
+#### Elasticsearch
+
+After updating GitLab, you may have to upgrade
+[Elasticsearch if the new version breaks compatibility](../integration/elasticsearch.md#version-requirements).
+Updating Elasticsearch is **out of scope for GitLab Support**.
+
+## Troubleshooting
+
+If anything doesn't go as planned:
+
+- If time is of the essence, copy any errors and gather any logs to later analyze,
+ and then [roll back to the last working version](#rollback-plan). You can use
+ the following tools to help you gather data:
+ - [`gitlabsos`](https://gitlab.com/gitlab-com/support/toolbox/gitlabsos) if
+ you installed GitLab using the Linux package or Docker.
+ - [`kubesos`](https://gitlab.com/gitlab-com/support/toolbox/kubesos/) if
+ you installed GitLab using the Helm Charts.
+- For support:
+ - [Contact GitLab Support](https://support.gitlab.com) and,
+ if you have one, your Technical Account Manager.
+ - If [the situation qualifies](https://about.gitlab.com/support/#definitions-of-support-impact)
+ and [your plan includes emergency support](https://about.gitlab.com/support/#priority-support),
+ create an emergency ticket.
diff --git a/doc/update/upgrading_from_ce_to_ee.md b/doc/update/upgrading_from_ce_to_ee.md
index 93c9432f6d3..d91b3de6df1 100644
--- a/doc/update/upgrading_from_ce_to_ee.md
+++ b/doc/update/upgrading_from_ce_to_ee.md
@@ -88,7 +88,7 @@ sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production
### 4. Install `gitlab-elasticsearch-indexer` **(PREMIUM SELF)**
-Please follow the [install instruction](../integration/elasticsearch.md#installing-elasticsearch).
+Please follow the [install instruction](../integration/elasticsearch.md#install-elasticsearch).
### 5. Start application
diff --git a/doc/update/upgrading_from_source.md b/doc/update/upgrading_from_source.md
index dd7ef27feca..9abf993f0fe 100644
--- a/doc/update/upgrading_from_source.md
+++ b/doc/update/upgrading_from_source.md
@@ -69,9 +69,9 @@ Download Ruby and compile it:
```shell
mkdir /tmp/ruby && cd /tmp/ruby
-curl --remote-name --progress "https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.2.tar.gz"
-echo 'cb9731a17487e0ad84037490a6baf8bfa31a09e8 ruby-2.7.2.tar.gz' | shasum -c - && tar xzf ruby-2.7.2.tar.gz
-cd ruby-2.7.2
+curl --remote-name --progress-bar "https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.4.tar.gz"
+echo '3043099089608859fc8cce7f9fdccaa1f53a462457e3838ec3b25a7d609fbc5b ruby-2.7.4.tar.gz' | sha256sum -c - && tar xzf ruby-2.7.4.tar.gz
+cd ruby-2.7.4
./configure --disable-install-rdoc --enable-shared
make
@@ -107,11 +107,11 @@ Download and install Go (for Linux, 64-bit):
# Remove former Go installation folder
sudo rm -rf /usr/local/go
-curl --remote-name --progress "https://dl.google.com/go/go1.13.5.linux-amd64.tar.gz"
-echo '512103d7ad296467814a6e3f635631bd35574cab3369a97a323c9a585ccaa569 go1.13.5.linux-amd64.tar.gz' | shasum -a256 -c - && \
- sudo tar -C /usr/local -xzf go1.13.5.linux-amd64.tar.gz
+curl --remote-name --progress-bar "https://dl.google.com/go/go1.15.12.linux-amd64.tar.gz"
+echo 'bbdb935699e0b24d90e2451346da76121b2412d30930eabcd80907c230d098b7 go1.15.12.linux-amd64.tar.gz' | shasum -a256 -c - && \
+ sudo tar -C /usr/local -xzf go1.15.12.linux-amd64.tar.gz
sudo ln -sf /usr/local/go/bin/{go,godoc,gofmt} /usr/local/bin/
-rm go1.13.5.linux-amd64.tar.gz
+rm go1.15.12.linux-amd64.tar.gz
```
diff --git a/doc/update/zero_downtime.md b/doc/update/zero_downtime.md
new file mode 100644
index 00000000000..f0e6377f355
--- /dev/null
+++ b/doc/update/zero_downtime.md
@@ -0,0 +1,942 @@
+---
+stage: Enablement
+group: Distribution
+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/#designated-technical-writers
+---
+
+# Zero downtime upgrades
+
+Starting with GitLab 9.1.0 it's possible to upgrade to a newer major, minor, or
+patch version of GitLab without having to take your GitLab instance offline.
+However, for this to work there are the following requirements:
+
+- You can only upgrade 1 minor release at a time. So from 9.1 to 9.2, not to
+ 9.3. If you skip releases, database modifications may be run in the wrong
+ sequence [and leave the database schema in a broken state](https://gitlab.com/gitlab-org/gitlab/-/issues/321542).
+- You have to use [post-deployment migrations](../development/post_deployment_migrations.md).
+- You are using PostgreSQL. Starting from GitLab 12.1, MySQL is not supported.
+- Multi-node GitLab instance. Single-node instances may experience brief interruptions
+ [as services restart (Puma in particular)](#single-node-deployment).
+
+If you meet all the requirements above, follow these instructions in order. There are three sets of steps, depending on your deployment type:
+
+| Deployment type | Description |
+| --------------------------------------------------------------- | ------------------------------------------------ |
+| [Single-node](#single-node-deployment) | GitLab CE/EE on a single node |
+| [Gitaly Cluster](#gitaly-cluster) | GitLab CE/EE using HA architecture for Gitaly Cluster |
+| [Multi-node / PostgreSQL HA](#use-postgresql-ha) | GitLab CE/EE using HA architecture for PostgreSQL |
+| [Multi-node / Redis HA](#use-redis-ha-using-sentinel) | GitLab CE/EE using HA architecture for Redis |
+| [Geo](#geo-deployment) | GitLab EE with Geo enabled |
+| [Multi-node / HA with Geo](#multi-node--ha-deployment-with-geo) | GitLab CE/EE on multiple nodes |
+
+Each type of deployment will require that you hot reload the `puma` and `sidekiq` processes on all nodes running these
+services after you've upgraded. The reason for this is that those processes each load the GitLab Rails application which reads and loads
+the database schema into memory when starting up. Each of these processes will need to be reloaded (or restarted in the case of `sidekiq`)
+to re-read any database changes that have been made by post-deployment migrations.
+
+Most of the time you can safely upgrade from a patch release to the next minor
+release if the patch release is not the latest. For example, upgrading from
+9.1.1 to 9.2.0 should be safe even if 9.1.2 has been released. We do recommend
+you check the release posts of any releases between your current and target
+version just in case they include any migrations that may require you to upgrade
+1 release at a time.
+
+Some releases may also include so called "background migrations". These
+migrations are performed in the background by Sidekiq and are often used for
+migrating data. Background migrations are only added in the monthly releases.
+
+Certain major/minor releases may require a set of background migrations to be
+finished. To guarantee this, such a release processes any remaining jobs
+before continuing the upgrading procedure. While this doesn't require downtime
+(if the above conditions are met) we require that you [wait for background
+migrations to complete](index.md#checking-for-background-migrations-before-upgrading)
+between each major/minor release upgrade.
+The time necessary to complete these migrations can be reduced by
+increasing the number of Sidekiq workers that can process jobs in the
+`background_migration` queue. To see the size of this queue,
+[Check for background migrations before upgrading](index.md#checking-for-background-migrations-before-upgrading).
+
+As a rule of thumb, any database smaller than 10 GB doesn't take too much time to
+upgrade; perhaps an hour at most per minor release. Larger databases however may
+require more time, but this is highly dependent on the size of the database and
+the migrations that are being performed.
+
+To help explain this, let's look at some examples:
+
+**Example 1:** You are running a large GitLab installation using version 9.4.2,
+which is the latest patch release of 9.4. When GitLab 9.5.0 is released this
+installation can be safely upgraded to 9.5.0 without requiring downtime if the
+requirements mentioned above are met. You can also skip 9.5.0 and upgrade to
+9.5.1 after it's released, but you **can not** upgrade straight to 9.6.0; you
+_have_ to first upgrade to a 9.5.Z release.
+
+**Example 2:** You are running a large GitLab installation using version 9.4.2,
+which is the latest patch release of 9.4. GitLab 9.5 includes some background
+migrations, and 10.0 requires these to be completed (processing any
+remaining jobs for you). Skipping 9.5 is not possible without downtime, and due
+to the background migrations would require potentially hours of downtime
+depending on how long it takes for the background migrations to complete. To
+work around this you have to upgrade to 9.5.Z first, then wait at least a
+week before upgrading to 10.0.
+
+**Example 3:** You use MySQL as the database for GitLab. Any upgrade to a new
+major/minor release requires downtime. If a release includes any background
+migrations this could potentially lead to hours of downtime, depending on the
+size of your database. To work around this you must use PostgreSQL and
+meet the other online upgrade requirements mentioned above.
+
+## Single-node deployment
+
+Before following these instructions, note the following **important** information:
+
+- You can only upgrade 1 minor release at a time. So from 13.6 to 13.7, not to 13.8.
+ If you attempt more than one minor release, the upgrade may fail.
+- On single-node Omnibus deployments, updates with no downtime are not possible when
+ using Puma because Puma always requires a complete restart. This is because the
+ [phased restart](https://github.com/puma/puma/blob/master/README.md#clustered-mode)
+ feature of Puma does not work with the way it is configured in GitLab all-in-one
+ packages (cluster-mode with app preloading).
+- While it is possible to minimize downtime on a single-node instance by following
+ these instructions, **it is not possible to always achieve true zero downtime
+ updates**. Users may see some connections timeout or be refused for a few minutes,
+ depending on which services need to restart.
+
+1. Create an empty file at `/etc/gitlab/skip-auto-reconfigure`. This prevents upgrades from running `gitlab-ctl reconfigure`, which by default automatically stops GitLab, runs all database migrations, and restarts GitLab.
+
+ ```shell
+ sudo touch /etc/gitlab/skip-auto-reconfigure
+ ```
+
+1. Update the GitLab package:
+
+ - For GitLab Community Edition:
+
+ ```shell
+ # Debian/Ubuntu
+ sudo apt-get update
+ sudo apt-get install gitlab-ce
+
+ # Centos/RHEL
+ sudo yum install gitlab-ce
+ ```
+
+ - For GitLab [Enterprise Edition](https://about.gitlab.com/pricing/):
+
+ ```shell
+ # Debian/Ubuntu
+ sudo apt-get update
+ sudo apt-get install gitlab-ee
+
+ # Centos/RHEL
+ sudo yum install gitlab-ee
+ ```
+
+1. To get the regular migrations and latest code in place, run
+
+ ```shell
+ sudo SKIP_POST_DEPLOYMENT_MIGRATIONS=true gitlab-ctl reconfigure
+ ```
+
+1. Once the node is updated and `reconfigure` finished successfully, run post-deployment migrations with
+
+ ```shell
+ sudo gitlab-rake db:migrate
+ ```
+
+1. Hot reload `puma` and `sidekiq` services
+
+ ```shell
+ sudo gitlab-ctl hup puma
+ sudo gitlab-ctl restart sidekiq
+ ```
+
+If you do not want to run zero downtime upgrades in the future, make
+sure you remove `/etc/gitlab/skip-auto-reconfigure` after
+you've completed these steps.
+
+## Multi-node / HA deployment
+
+You can only upgrade 1 minor release at a time. So from 13.6 to 13.7, not to 13.8.
+If you attempt more than one minor release, the upgrade may fail.
+
+### Use a load balancer in front of web (Puma) nodes
+
+With Puma, single node zero-downtime updates are no longer possible. To achieve
+HA with zero-downtime updates, at least two nodes are required to be used with a
+load balancer which distributes the connections properly across both nodes.
+
+The load balancer in front of the application nodes must be configured to check
+proper health check endpoints to check if the service is accepting traffic or
+not. For Puma, the `/-/readiness` endpoint should be used, while
+`/readiness` endpoint can be used for Sidekiq and other services.
+
+Upgrades on web (Puma) nodes must be done in a rolling manner, one after
+another, ensuring at least one node is always up to serve traffic. This is
+required to ensure zero-downtime.
+
+Puma will enter a blackout period as part of the upgrade, during which they
+continue to accept connections but will mark their respective health check
+endpoints to be unhealthy. On seeing this, the load balancer should disconnect
+them gracefully.
+
+Puma will restart only after completing all the currently processing requests.
+This ensures data and service integrity. Once they have restarted, the health
+check end points will be marked healthy.
+
+The nodes must be updated in the following order to update an HA instance using
+load balancer to latest GitLab version.
+
+1. Select one application node as a deploy node and complete the following steps
+ on it:
+
+ 1. Create an empty file at `/etc/gitlab/skip-auto-reconfigure`. This prevents upgrades from running `gitlab-ctl reconfigure`, which by default automatically stops GitLab, runs all database migrations, and restarts GitLab:
+
+ ```shell
+ sudo touch /etc/gitlab/skip-auto-reconfigure
+ ```
+
+ 1. Update the GitLab package:
+
+ ```shell
+ # Debian/Ubuntu
+ sudo apt-get update && sudo apt-get install gitlab-ce
+
+ # Centos/RHEL
+ sudo yum install gitlab-ce
+ ```
+
+ If you are an Enterprise Edition user, replace `gitlab-ce` with
+ `gitlab-ee` in the above command.
+
+ 1. Get the regular migrations and latest code in place:
+
+ ```shell
+ sudo SKIP_POST_DEPLOYMENT_MIGRATIONS=true gitlab-ctl reconfigure
+ ```
+
+ 1. Ensure services use the latest code:
+
+ ```shell
+ sudo gitlab-ctl hup puma
+ sudo gitlab-ctl restart sidekiq
+ ```
+
+1. Complete the following steps on the other Puma/Sidekiq nodes, one
+ after another. Always ensure at least one of such nodes is up and running,
+ and connected to the load balancer before proceeding to the next node.
+
+ 1. Update the GitLab package and ensure a `reconfigure` is run as part of
+ it. If not (due to `/etc/gitlab/skip-auto-reconfigure` file being
+ present), run `sudo gitlab-ctl reconfigure` manually.
+
+ 1. Ensure services use latest code:
+
+ ```shell
+ sudo gitlab-ctl hup puma
+ sudo gitlab-ctl restart sidekiq
+ ```
+
+1. On the deploy node, run the post-deployment migrations:
+
+ ```shell
+ sudo gitlab-rake db:migrate
+ ```
+
+### Gitaly Cluster
+
+[Gitaly Cluster](../administration/gitaly/praefect.md) is built using
+Gitaly and the Praefect component. It has its own PostgreSQL database, independent of the rest of
+the application.
+
+Before you update the main application you need to update Praefect.
+Out of your Praefect nodes, pick one to be your Praefect deploy node.
+This is where you will install the new Omnibus package first and run
+database migrations.
+
+**Praefect deploy node**
+
+- Create an empty file at `/etc/gitlab/skip-auto-reconfigure`. This prevents upgrades from running `gitlab-ctl reconfigure`, which by default automatically stops GitLab, runs all database migrations, and restarts GitLab:
+
+ ```shell
+ sudo touch /etc/gitlab/skip-auto-reconfigure
+ ```
+
+- Ensure that `praefect['auto_migrate'] = true` is set in `/etc/gitlab/gitlab.rb`
+
+**All Praefect nodes _excluding_ the Praefect deploy node**
+
+- To prevent `reconfigure` from automatically running database migrations, ensure that `praefect['auto_migrate'] = false` is set in `/etc/gitlab/gitlab.rb`.
+
+**Praefect deploy node**
+
+- Update the GitLab package:
+
+ ```shell
+ # Debian/Ubuntu
+ sudo apt-get update && sudo apt-get install gitlab-ce
+
+ # Centos/RHEL
+ sudo yum install gitlab-ce
+ ```
+
+ If you are an Enterprise Edition user, replace `gitlab-ce` with `gitlab-ee` in the above command.
+
+- To apply the Praefect database migrations and restart Praefect, run:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+**All Praefect nodes _excluding_ the Praefect deploy node**
+
+- Update the GitLab package:
+
+ ```shell
+ sudo apt-get update && sudo apt-get install gitlab-ce
+ ```
+
+ If you are an Enterprise Edition user, replace `gitlab-ce` with `gitlab-ee` in the above command.
+
+- Ensure nodes are running the latest code:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+### Use PostgreSQL HA
+
+Pick a node to be the `Deploy Node`. It can be any application node, but it must be the same
+node throughout the process.
+
+**Deploy node**
+
+- Create an empty file at `/etc/gitlab/skip-auto-reconfigure`. This prevents upgrades from running `gitlab-ctl reconfigure`, which by default automatically stops GitLab, runs all database migrations, and restarts GitLab.
+
+ ```shell
+ sudo touch /etc/gitlab/skip-auto-reconfigure
+ ```
+
+**All nodes _including_ the Deploy node**
+
+- To prevent `reconfigure` from automatically running database migrations, ensure that `gitlab_rails['auto_migrate'] = false` is set in `/etc/gitlab/gitlab.rb`.
+
+**Gitaly only nodes**
+
+- Update the GitLab package
+
+ ```shell
+ # Debian/Ubuntu
+ sudo apt-get update && sudo apt-get install gitlab-ce
+
+ # Centos/RHEL
+ sudo yum install gitlab-ce
+ ```
+
+ If you are an Enterprise Edition user, replace `gitlab-ce` with `gitlab-ee` in the above command.
+
+- Ensure nodes are running the latest code
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+**Deploy node**
+
+- Update the GitLab package
+
+ ```shell
+ # Debian/Ubuntu
+ sudo apt-get update && sudo apt-get install gitlab-ce
+
+ # Centos/RHEL
+ sudo yum install gitlab-ce
+ ```
+
+ If you are an Enterprise Edition user, replace `gitlab-ce` with `gitlab-ee` in the above command.
+
+- If you're using PgBouncer:
+
+ You'll need to bypass PgBouncer and connect directly to the database master
+ before running migrations.
+
+ Rails uses an advisory lock when attempting to run a migration to prevent
+ concurrent migrations from running on the same database. These locks are
+ not shared across transactions, resulting in `ActiveRecord::ConcurrentMigrationError`
+ and other issues when running database migrations using PgBouncer in transaction
+ pooling mode.
+
+ To find the master node, run the following on a database node:
+
+ ```shell
+ sudo gitlab-ctl patroni members
+ ```
+
+ Then, in your `gitlab.rb` file on the deploy node, update
+ `gitlab_rails['db_host']` and `gitlab_rails['db_port']` with the database
+ master's host and port.
+
+- To get the regular database migrations and latest code in place, run
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ sudo SKIP_POST_DEPLOYMENT_MIGRATIONS=true gitlab-rake db:migrate
+ ```
+
+**All nodes _excluding_ the Deploy node**
+
+- Update the GitLab package
+
+ ```shell
+ sudo apt-get update && sudo apt-get install gitlab-ce
+ ```
+
+ If you are an Enterprise Edition user, replace `gitlab-ce` with `gitlab-ee` in the above command.
+
+- Ensure nodes are running the latest code
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+**Deploy node**
+
+- Run post-deployment database migrations on deploy node to complete the migrations with
+
+ ```shell
+ sudo gitlab-rake db:migrate
+ ```
+
+**For nodes that run Puma or Sidekiq**
+
+- Hot reload `puma` and `sidekiq` services
+
+ ```shell
+ sudo gitlab-ctl hup puma
+ sudo gitlab-ctl restart sidekiq
+ ```
+
+- If you're using PgBouncer:
+
+ Change your `gitlab.rb` to point back to PgBouncer and run:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+If you do not want to run zero downtime upgrades in the future, make
+sure you remove `/etc/gitlab/skip-auto-reconfigure` and revert
+setting `gitlab_rails['auto_migrate'] = false` in
+`/etc/gitlab/gitlab.rb` after you've completed these steps.
+
+### Use Redis HA (using Sentinel) **(PREMIUM ONLY)**
+
+Package upgrades may involve version updates to the bundled Redis service. On
+instances using [Redis for scaling](../administration/redis/index.md),
+upgrades must follow a proper order to ensure minimum downtime, as specified
+below. This doc assumes the official guides are being followed to setup Redis
+HA.
+
+#### In the application node
+
+According to [official Redis docs](https://redis.io/topics/admin#upgrading-or-restarting-a-redis-instance-without-downtime),
+the easiest way to update an HA instance using Sentinel is to upgrade the
+secondaries one after the other, perform a manual failover from current
+primary (running old version) to a recently upgraded secondary (running a new
+version), and then upgrade the original primary. For this, we need to know
+the address of the current Redis primary.
+
+- If your application node is running GitLab 12.7.0 or later, you can use the
+following command to get address of current Redis primary
+
+ ```shell
+ sudo gitlab-ctl get-redis-master
+ ```
+
+- If your application node is running a version older than GitLab 12.7.0, you
+ will have to run the underlying `redis-cli` command (which `get-redis-master`
+ command uses) to fetch information about the primary.
+
+ 1. Get the address of one of the sentinel nodes specified as
+ `gitlab_rails['redis_sentinels']` in `/etc/gitlab/gitlab.rb`
+
+ 1. Get the Redis master name specified as `redis['master_name']` in
+ `/etc/gitlab/gitlab.rb`
+
+ 1. Run the following command
+
+ ```shell
+ sudo /opt/gitlab/embedded/bin/redis-cli -h <sentinel host> -p <sentinel port> SENTINEL get-master-addr-by-name <redis master name>
+ ```
+
+#### In the Redis secondary nodes
+
+1. Install package for new version.
+
+1. Run `sudo gitlab-ctl reconfigure`, if a reconfigure is not run as part of
+ installation (due to `/etc/gitlab/skip-auto-reconfigure` file being present).
+
+1. If reconfigure warns about a pending Redis/Sentinel restart, restart the
+ corresponding service
+
+ ```shell
+ sudo gitlab-ctl restart redis
+ sudo gitlab-ctl restart sentinel
+ ```
+
+#### In the Redis primary node
+
+Before upgrading the Redis primary node, we need to perform a failover so that
+one of the recently upgraded secondary nodes becomes the new primary. Once the
+failover is complete, we can go ahead and upgrade the original primary node.
+
+1. Stop Redis service in Redis primary node so that it fails over to a secondary
+ node
+
+ ```shell
+ sudo gitlab-ctl stop redis
+ ```
+
+1. Wait for failover to be complete. You can verify it by periodically checking
+ details of the current Redis primary node (as mentioned above). If it starts
+ reporting a new IP, failover is complete.
+
+1. Start Redis again in that node, so that it starts following the current
+ primary node.
+
+ ```shell
+ sudo gitlab-ctl start redis
+ ```
+
+1. Install package corresponding to new version.
+
+1. Run `sudo gitlab-ctl reconfigure`, if a reconfigure is not run as part of
+ installation (due to `/etc/gitlab/skip-auto-reconfigure` file being present).
+
+1. If reconfigure warns about a pending Redis/Sentinel restart, restart the
+ corresponding service
+
+ ```shell
+ sudo gitlab-ctl restart redis
+ sudo gitlab-ctl restart sentinel
+ ```
+
+#### Update the application node
+
+Install the package for new version and follow regular package upgrade
+procedure.
+
+## Geo deployment **(PREMIUM ONLY)**
+
+The order of steps is important. While following these steps, make
+sure you follow them in the right order, on the correct node.
+
+Log in to your **primary** node, executing the following:
+
+1. Create an empty file at `/etc/gitlab/skip-auto-reconfigure`. This prevents upgrades from running `gitlab-ctl reconfigure`, which by default automatically stops GitLab, runs all database migrations, and restarts GitLab.
+
+ ```shell
+ sudo touch /etc/gitlab/skip-auto-reconfigure
+ ```
+
+1. Edit `/etc/gitlab/gitlab.rb` and ensure the following is present:
+
+ ```ruby
+ gitlab_rails['auto_migrate'] = false
+ ```
+
+1. Reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+1. Update the GitLab package
+
+ ```shell
+ # Debian/Ubuntu
+ sudo apt-get update && sudo apt-get install gitlab-ee
+
+ # Centos/RHEL
+ sudo yum install gitlab-ee
+ ```
+
+1. To get the database migrations and latest code in place, run
+
+ ```shell
+ sudo SKIP_POST_DEPLOYMENT_MIGRATIONS=true gitlab-ctl reconfigure
+ ```
+
+1. Hot reload `puma` and `sidekiq` services
+
+ ```shell
+ sudo gitlab-ctl hup puma
+ sudo gitlab-ctl restart sidekiq
+ ```
+
+On each **secondary** node, executing the following:
+
+1. Create an empty file at `/etc/gitlab/skip-auto-reconfigure`. This prevents upgrades from running `gitlab-ctl reconfigure`, which by default automatically stops GitLab, runs all database migrations, and restarts GitLab.
+
+ ```shell
+ sudo touch /etc/gitlab/skip-auto-reconfigure
+ ```
+
+1. Edit `/etc/gitlab/gitlab.rb` and ensure the following is present:
+
+ ```ruby
+ gitlab_rails['auto_migrate'] = false
+ ```
+
+1. Reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+1. Update the GitLab package
+
+ ```shell
+ # Debian/Ubuntu
+ sudo apt-get update && sudo apt-get install gitlab-ee
+
+ # Centos/RHEL
+ sudo yum install gitlab-ee
+ ```
+
+1. To get the database migrations and latest code in place, run
+
+ ```shell
+ sudo SKIP_POST_DEPLOYMENT_MIGRATIONS=true gitlab-ctl reconfigure
+ ```
+
+1. Hot reload `puma`, `sidekiq` and restart `geo-logcursor` services
+
+ ```shell
+ sudo gitlab-ctl hup puma
+ sudo gitlab-ctl restart sidekiq
+ sudo gitlab-ctl restart geo-logcursor
+ ```
+
+1. Run post-deployment database migrations, specific to the Geo database
+
+ ```shell
+ sudo gitlab-rake geo:db:migrate
+ ```
+
+After all **secondary** nodes are updated, finalize
+the update on the **primary** node:
+
+- Run post-deployment database migrations
+
+ ```shell
+ sudo gitlab-rake db:migrate
+ ```
+
+After updating all nodes (both **primary** and all **secondaries**), check their status:
+
+- Verify Geo configuration and dependencies
+
+ ```shell
+ sudo gitlab-rake gitlab:geo:check
+ ```
+
+If you do not want to run zero downtime upgrades in the future, make
+sure you remove `/etc/gitlab/skip-auto-reconfigure` and revert
+setting `gitlab_rails['auto_migrate'] = false` in
+`/etc/gitlab/gitlab.rb` after you've completed these steps.
+
+## Multi-node / HA deployment with Geo **(PREMIUM ONLY)**
+
+This section describes the steps required to upgrade a multi-node / HA
+deployment with Geo. Some steps must be performed on a particular node. This
+node will be known as the “deploy node†and is noted through the following
+instructions.
+
+Updates must be performed in the following order:
+
+1. Update Geo **primary** multi-node deployment.
+1. Update Geo **secondary** multi-node deployments.
+1. Post-deployment migrations and checks.
+
+### Step 1: Choose a "deploy node" for each deployment
+
+You now need to choose:
+
+- One instance for use as the **primary** "deploy node" on the Geo **primary** multi-node deployment.
+- One instance for use as the **secondary** "deploy node" on each Geo **secondary** multi-node deployment.
+
+Deploy nodes must be configured to be running Puma or Sidekiq or the `geo-logcursor` daemon. In order
+to avoid any downtime, they must not be in use during the update:
+
+- If running Puma remove the deploy node from the load balancer.
+- If running Sidekiq, ensure the deploy node is not processing jobs:
+
+ ```shell
+ sudo gitlab-ctl stop sidekiq
+ ```
+
+- If running `geo-logcursor` daemon, ensure the deploy node is not processing events:
+
+ ```shell
+ sudo gitlab-ctl stop geo-logcursor
+ ```
+
+For zero-downtime, Puma, Sidekiq, and `geo-logcursor` must be running on other nodes during the update.
+
+### Step 2: Update the Geo primary multi-node deployment
+
+**On all primary nodes _including_ the primary "deploy node"**
+
+1. Create an empty file at `/etc/gitlab/skip-auto-reconfigure`. This prevents upgrades from running `gitlab-ctl reconfigure`, which by default automatically stops GitLab, runs all database migrations, and restarts GitLab.
+
+```shell
+sudo touch /etc/gitlab/skip-auto-reconfigure
+```
+
+1. To prevent `reconfigure` from automatically running database migrations, ensure that `gitlab_rails['auto_migrate'] = false` is set in `/etc/gitlab/gitlab.rb`.
+
+1. Ensure nodes are running the latest code
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+**On primary Gitaly only nodes**
+
+1. Update the GitLab package
+
+ ```shell
+ # Debian/Ubuntu
+ sudo apt-get update && sudo apt-get install gitlab-ee
+
+ # Centos/RHEL
+ sudo yum install gitlab-ee
+ ```
+
+1. Ensure nodes are running the latest code
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+**On the primary "deploy node"**
+
+1. Update the GitLab package
+
+ ```shell
+ # Debian/Ubuntu
+ sudo apt-get update && sudo apt-get install gitlab-ee
+
+ # Centos/RHEL
+ sudo yum install gitlab-ee
+ ```
+
+1. If you're using PgBouncer:
+
+ You'll need to bypass PgBouncer and connect directly to the database master
+ before running migrations.
+
+ Rails uses an advisory lock when attempting to run a migration to prevent
+ concurrent migrations from running on the same database. These locks are
+ not shared across transactions, resulting in `ActiveRecord::ConcurrentMigrationError`
+ and other issues when running database migrations using PgBouncer in transaction
+ pooling mode.
+
+ To find the master node, run the following on a database node:
+
+ ```shell
+ sudo gitlab-ctl patroni members
+ ```
+
+ Then, in your `gitlab.rb` file on the deploy node, update
+ `gitlab_rails['db_host']` and `gitlab_rails['db_port']` with the database
+ master's host and port.
+
+1. To get the regular database migrations and latest code in place, run
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ sudo SKIP_POST_DEPLOYMENT_MIGRATIONS=true gitlab-rake db:migrate
+ ```
+
+1. If this deploy node is normally used to serve requests or process jobs,
+ then you may return it to service at this point.
+
+ - To serve requests, add the deploy node to the load balancer.
+ - To process Sidekiq jobs again, start Sidekiq:
+
+ ```shell
+ sudo gitlab-ctl start sidekiq
+ ```
+
+**On all primary nodes _excluding_ the primary "deploy node"**
+
+1. Update the GitLab package
+
+ ```shell
+ # Debian/Ubuntu
+ sudo apt-get update && sudo apt-get install gitlab-ee
+
+ # Centos/RHEL
+ sudo yum install gitlab-ee
+ ```
+
+1. Ensure nodes are running the latest code
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+**For all primary nodes that run Puma or Sidekiq _including_ the primary "deploy node"**
+
+Hot reload `puma` and `sidekiq` services:
+
+```shell
+sudo gitlab-ctl hup puma
+sudo gitlab-ctl restart sidekiq
+```
+
+### Step 3: Update each Geo secondary multi-node deployment
+
+Only proceed if you have successfully completed all steps on the Geo **primary** multi-node deployment.
+
+**On all secondary nodes _including_ the secondary "deploy node"**
+
+1. Create an empty file at `/etc/gitlab/skip-auto-reconfigure`. This prevents upgrades from running `gitlab-ctl reconfigure`, which by default automatically stops GitLab, runs all database migrations, and restarts GitLab.
+
+```shell
+sudo touch /etc/gitlab/skip-auto-reconfigure
+```
+
+1. To prevent `reconfigure` from automatically running database migrations, ensure that `geo_secondary['auto_migrate'] = false` is set in `/etc/gitlab/gitlab.rb`.
+
+1. Ensure nodes are running the latest code
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+**On secondary Gitaly only nodes**
+
+1. Update the GitLab package
+
+ ```shell
+ # Debian/Ubuntu
+ sudo apt-get update && sudo apt-get install gitlab-ee
+
+ # Centos/RHEL
+ sudo yum install gitlab-ee
+ ```
+
+1. Ensure nodes are running the latest code
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+**On the secondary "deploy node"**
+
+1. Update the GitLab package
+
+ ```shell
+ # Debian/Ubuntu
+ sudo apt-get update && sudo apt-get install gitlab-ee
+
+ # Centos/RHEL
+ sudo yum install gitlab-ee
+ ```
+
+1. To get the regular database migrations and latest code in place, run
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ sudo SKIP_POST_DEPLOYMENT_MIGRATIONS=true gitlab-rake geo:db:migrate
+ ```
+
+1. If this deploy node is normally used to serve requests or perform
+ background processing, then you may return it to service at this point.
+
+ - To serve requests, add the deploy node to the load balancer.
+ - To process Sidekiq jobs again, start Sidekiq:
+
+ ```shell
+ sudo gitlab-ctl start sidekiq
+ ```
+
+ - To process Geo events again, start the `geo-logcursor` daemon:
+
+ ```shell
+ sudo gitlab-ctl start geo-logcursor
+ ```
+
+**On all secondary nodes _excluding_ the secondary "deploy node"**
+
+1. Update the GitLab package
+
+ ```shell
+ # Debian/Ubuntu
+ sudo apt-get update && sudo apt-get install gitlab-ee
+
+ # Centos/RHEL
+ sudo yum install gitlab-ee
+ ```
+
+1. Ensure nodes are running the latest code
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+**For all secondary nodes that run Puma, Sidekiq, or the `geo-logcursor` daemon _including_ the secondary "deploy node"**
+
+Hot reload `puma`, `sidekiq` and ``geo-logcursor`` services:
+
+```shell
+sudo gitlab-ctl hup puma
+sudo gitlab-ctl restart sidekiq
+sudo gitlab-ctl restart geo-logcursor
+```
+
+### Step 4: Run post-deployment migrations and checks
+
+**On the primary "deploy node"**
+
+1. Run post-deployment database migrations:
+
+ ```shell
+ sudo gitlab-rake db:migrate
+ ```
+
+1. Verify Geo configuration and dependencies
+
+ ```shell
+ sudo gitlab-rake gitlab:geo:check
+ ```
+
+1. If you're using PgBouncer:
+
+ Change your `gitlab.rb` to point back to PgBouncer and run:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+**On all secondary "deploy nodes"**
+
+1. Run post-deployment database migrations, specific to the Geo database:
+
+ ```shell
+ sudo gitlab-rake geo:db:migrate
+ ```
+
+1. Verify Geo configuration and dependencies
+
+ ```shell
+ sudo gitlab-rake gitlab:geo:check
+ ```
+
+1. Verify Geo status
+
+ ```shell
+ sudo gitlab-rake geo:status
+ ```
diff --git a/doc/user/admin_area/analytics/dev_ops_report.md b/doc/user/admin_area/analytics/dev_ops_report.md
index f07ccc11c60..7ddddfc5e53 100644
--- a/doc/user/admin_area/analytics/dev_ops_report.md
+++ b/doc/user/admin_area/analytics/dev_ops_report.md
@@ -14,13 +14,13 @@ from planning to monitoring.
To see DevOps Report:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Analytics > DevOps Report**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Analytics > DevOps Report**.
## DevOps Score
NOTE:
-To see the DevOps score, you must activate your GitLab instance's [Service Ping](../settings/usage_statistics.md#service-ping).
+To see the DevOps score, you must activate your GitLab instance's [Service Ping](../settings/usage_statistics.md#service-ping). This is because DevOps Score is a comparative tool, so your score data must be centrally processed by GitLab Inc. first.
You can use the DevOps score to compare your DevOps status to other organizations.
@@ -45,6 +45,7 @@ feature is available.
> - Fuzz Testing metrics [added](https://gitlab.com/gitlab-org/gitlab/-/issues/330398) in GitLab 14.2.
> - Dependency Scanning metrics [added](https://gitlab.com/gitlab-org/gitlab/-/issues/328034) in GitLab 14.2.
> - Multi-select [added](https://gitlab.com/gitlab-org/gitlab/-/issues/333586) in GitLab 14.2.
+> - Overview table [added](https://gitlab.com/gitlab-org/gitlab/-/issues/335638) in GitLab 14.3.
DevOps Adoption shows you which groups in your organization are using the most essential features of GitLab:
diff --git a/doc/user/admin_area/analytics/img/admin_devops_adoption_v14_2.png b/doc/user/admin_area/analytics/img/admin_devops_adoption_v14_2.png
index d4b3436f3ee..666e03f1d9d 100644
--- a/doc/user/admin_area/analytics/img/admin_devops_adoption_v14_2.png
+++ b/doc/user/admin_area/analytics/img/admin_devops_adoption_v14_2.png
Binary files differ
diff --git a/doc/user/admin_area/analytics/index.md b/doc/user/admin_area/analytics/index.md
index 465b26d516c..dd1efc913fa 100644
--- a/doc/user/admin_area/analytics/index.md
+++ b/doc/user/admin_area/analytics/index.md
@@ -10,8 +10,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
Administrators have access to instance-wide analytics:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Analytics**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Analytics**.
There are several kinds of statistics:
diff --git a/doc/user/admin_area/analytics/usage_trends.md b/doc/user/admin_area/analytics/usage_trends.md
index 9c09b62f8af..06995069215 100644
--- a/doc/user/admin_area/analytics/usage_trends.md
+++ b/doc/user/admin_area/analytics/usage_trends.md
@@ -19,7 +19,7 @@ Usage Trends gives you an overview of how much data your instance contains, and
To see Usage Trends:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Analytics > Usage Trends**.
## Total counts
diff --git a/doc/user/admin_area/appearance.md b/doc/user/admin_area/appearance.md
index d7f0b7e3854..0ffa8289d37 100644
--- a/doc/user/admin_area/appearance.md
+++ b/doc/user/admin_area/appearance.md
@@ -11,8 +11,8 @@ disqus_identifier: 'https://docs.gitlab.com/ee/customization/branded_login_page.
There are several options for customizing the appearance of a self-managed instance
of GitLab. To access these settings:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > Appearance**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Appearance**.
## Navigation bar
diff --git a/doc/user/admin_area/broadcast_messages.md b/doc/user/admin_area/broadcast_messages.md
index 93e6aa9bb16..987d7444ae0 100644
--- a/doc/user/admin_area/broadcast_messages.md
+++ b/doc/user/admin_area/broadcast_messages.md
@@ -54,7 +54,7 @@ To display messages to users on your GitLab instance, add a broadcast message.
To add a broadcast message:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Messages**.
1. Add the text for the message to the **Message** field. You can style a message's content using Markdown, emoji, and the `a` and `br` HTML tags.
The `br` tag inserts a line break. The `a` HTML tag accepts `class` and `style` attributes with the following CSS properties:
@@ -84,7 +84,7 @@ If you need to make changes to a broadcast message, you can edit it.
To edit a broadcast message:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Messages**.
1. From the list of broadcast messages, select the edit button for the message.
1. After making the required changes, select **Update broadcast message**.
@@ -98,7 +98,7 @@ You can delete a broadcast message while it's active.
To delete a broadcast message:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Messages**.
1. From the list of broadcast messages, select the delete button for the message.
diff --git a/doc/user/admin_area/credentials_inventory.md b/doc/user/admin_area/credentials_inventory.md
index 8c5ae2dfb47..d79508e5b68 100644
--- a/doc/user/admin_area/credentials_inventory.md
+++ b/doc/user/admin_area/credentials_inventory.md
@@ -25,7 +25,7 @@ and [delete](#delete-a-users-ssh-key) and see:
To access the Credentials inventory:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Credentials**.
The following is an example of the Credentials inventory page:
diff --git a/doc/user/admin_area/diff_limits.md b/doc/user/admin_area/diff_limits.md
index 4be1ace10aa..b50748ca97e 100644
--- a/doc/user/admin_area/diff_limits.md
+++ b/doc/user/admin_area/diff_limits.md
@@ -33,8 +33,8 @@ set values are presented as **Too large** are cannot be expanded in the UI.
To configure these values:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand **Diff limits**.
1. Enter a value for the diff limit.
1. Select **Save changes**.
diff --git a/doc/user/admin_area/geo_nodes.md b/doc/user/admin_area/geo_nodes.md
index 861d3644ab3..a2354e68d72 100644
--- a/doc/user/admin_area/geo_nodes.md
+++ b/doc/user/admin_area/geo_nodes.md
@@ -12,7 +12,7 @@ You can configure various settings for GitLab Geo sites. For more information, s
On either the primary or secondary site:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Geo > Nodes**.
## Common settings
@@ -65,7 +65,7 @@ which is used by users. Internal URL does not need to be a private address.
Internal URL defaults to external URL, but you can also customize it:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Geo > Nodes**.
1. Select **Edit** on the site you want to customize.
1. Edit the internal URL.
diff --git a/doc/user/admin_area/index.md b/doc/user/admin_area/index.md
index 35afb9f376b..a5c3a2a7aeb 100644
--- a/doc/user/admin_area/index.md
+++ b/doc/user/admin_area/index.md
@@ -12,7 +12,7 @@ self-managed instances. If you are an Admin user, you can access the Admin Area
by visiting `/admin` on your self-managed instance. You can also access it through
the UI:
-- GitLab versions 14.0 and later: on the top bar, select **Menu >** **{admin}** **Admin**.
+- GitLab versions 14.0 and later: on the top bar, select **Menu > Admin**.
- GitLab versions 13.12 and earlier: on the top bar, select the Admin Area icon (**{admin}**).
NOTE:
@@ -47,7 +47,7 @@ The Dashboard provides statistics and system information about the GitLab instan
To access the Dashboard, either:
-- On the top bar, select **Menu >** **{admin}** **Admin**.
+- On the top bar, select **Menu > Admin**.
- Visit `/admin` on your self-managed instance.
The Dashboard is the default view of the Admin Area, and is made up of the following sections:
@@ -71,8 +71,8 @@ You can administer all projects in the GitLab instance from the Admin Area's Pro
To access the Projects page:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Overview > Projects**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Overview > Projects**.
1. Select the **All**, **Private**, **Internal**, or **Public** tab to list only
projects of that criteria.
@@ -111,8 +111,8 @@ You can combine the filter options. For example, to list only public projects wi
You can administer all users in the GitLab instance from the Admin Area's Users page:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Overview > Users**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Overview > Users**.
To list users matching a specific criteria, click on one of the following tabs on the **Users** page:
@@ -156,8 +156,8 @@ This allows the administrator to "see what the user sees," and take actions on b
You can impersonate a user in the following ways:
- Through the UI:
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
- 1. In the left sidebar, select **Overview > Users**.
+ 1. On the top bar, select **Menu > Admin**.
+ 1. On the left sidebar, select **Overview > Users**.
1. From the list of users, select a user.
1. Select **Impersonate**.
- With the API, using [impersonation tokens](../../api/index.md#impersonation-tokens).
@@ -199,6 +199,18 @@ The following totals are also included:
GitLab billing is based on the number of [**Billable users**](../../subscriptions/self_managed/index.md#billable-users).
+#### Add email to user
+
+You must be an administrator to manually add emails to users:
+
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Overview > Users** (`/admin/users`).
+1. Locate the user and select them.
+1. Select **Edit**.
+1. In **Email**, enter the new email address. This adds the new email address to the
+ user and sets the previous email address to be a secondary.
+1. Select **Save changes**.
+
### User cohorts
The [Cohorts](user_cohorts.md) tab displays the monthly cohorts of new users and their activities over time.
@@ -209,8 +221,8 @@ You can administer all groups in the GitLab instance from the Admin Area's Group
To access the Groups page:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Overview > Groups**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Overview > Groups**.
For each group, the page displays their name, description, size, number of projects in the group,
number of members, and whether the group is private, internal, or public. To edit a group, click
@@ -231,8 +243,8 @@ You can administer all jobs in the GitLab instance from the Admin Area's Jobs pa
To access the Jobs page:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Overview > Jobs**. All jobs are listed, in descending order of job ID.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Overview > Jobs**. All jobs are listed, in descending order of job ID.
1. Click the **All** tab to list all jobs. Click the **Pending**, **Running**, or **Finished**
tab to list only jobs of that status.
@@ -257,8 +269,8 @@ You can administer all runners in the GitLab instance from the Admin Area's **Ru
To access the **Runners** page:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Overview > Runners**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Overview > Runners**.
The **Runners** page features:
@@ -307,8 +319,8 @@ page. For more details, see [Gitaly](../../administration/gitaly/index.md).
To access the **Gitaly Servers** page:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Overview > Gitaly Servers**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Overview > Gitaly Servers**.
For each Gitaly server, the following details are listed:
diff --git a/doc/user/admin_area/license.md b/doc/user/admin_area/license.md
index 0431b0d1628..4e97cb8e49c 100644
--- a/doc/user/admin_area/license.md
+++ b/doc/user/admin_area/license.md
@@ -116,7 +116,7 @@ before this occurs.
To remove a license file from a self-managed instance:
1. From the top menu, select the Admin Area **{admin}**.
-1. From the left sidebar, select **Subscription**
+1. From the left sidebar, select **Subscription**.
1. Select **Remove license**.
These steps may need to be repeated to completely remove all licenses, including those applied in the past.
@@ -124,8 +124,10 @@ These steps may need to be repeated to completely remove all licenses, including
## License history
You can upload and view more than one license, but only the latest license in the current date
-range is used as the active license. When you upload a future-dated license, it
-doesn't take effect until its applicable date.
+range is used as the active license.
+
+When you upload a future-dated license, it doesn't take effect until its applicable date.
+You can view all of your active subscriptions in the **Subscription history** table.
NOTE:
In GitLab 13.6 and earlier, a notification banner about an expiring license may continue to be displayed even after a new license has been uploaded.
@@ -165,7 +167,7 @@ your license. However, if you have 111, you must purchase more users before you
### There is a connectivity issue
-In GitLab 14.1 and later, to activate your subscription, your GitLab instance must be connected to the internet.
+In GitLab 14.1 and later, to activate your subscription, your GitLab instance must be connected to the internet.
If you have an offline or airgapped environment, you can [upload a license file](license.md#activate-gitlab-ee-with-a-license-file) instead.
diff --git a/doc/user/admin_area/merge_requests_approvals.md b/doc/user/admin_area/merge_requests_approvals.md
index 4f6419cdeb7..ffa08dee10d 100644
--- a/doc/user/admin_area/merge_requests_approvals.md
+++ b/doc/user/admin_area/merge_requests_approvals.md
@@ -15,8 +15,8 @@ project level.
To enable merge request approval rules for an instance:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **{push-rules}** **Push Rules**, and expand **Merge request (MR) approvals**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **{push-rules}** **Push Rules**, and expand **Merge request (MR) approvals**.
1. Set the required rule.
1. Click **Save changes**.
diff --git a/doc/user/admin_area/moderate_users.md b/doc/user/admin_area/moderate_users.md
index 8211167895c..2655d927b87 100644
--- a/doc/user/admin_area/moderate_users.md
+++ b/doc/user/admin_area/moderate_users.md
@@ -13,11 +13,12 @@ users.
## Users pending approval
A user in _pending approval_ state requires action by an administrator. A user sign up can be in a
-pending approval state because an administrator has enabled either, or both, of the following
-options:
+pending approval state because an administrator has enabled any of the following options:
- [Require admin approval for new sign-ups](settings/sign_up_restrictions.md#require-administrator-approval-for-new-sign-ups) setting.
- [User cap](settings/sign_up_restrictions.md#user-cap).
+- [Block auto-created users (OmniAuth)](../../integration/omniauth.md#initial-omniauth-configuration)
+- [Block auto-created users (LDAP)](../../administration/auth/ldap/index.md#basic-configuration-settings)
When a user registers for an account while this setting is enabled:
@@ -39,7 +40,7 @@ sign in.
To view user sign ups pending approval:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Users**.
1. Select the **Pending approval** tab.
@@ -49,7 +50,7 @@ A user sign up pending approval can be approved or rejected from the Admin Area.
To approve or reject a user sign up:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Users**.
1. Select the **Pending approval** tab.
1. (Optional) Select a user.
@@ -74,7 +75,7 @@ administrators can choose to block the user.
Users can be blocked [via an abuse report](review_abuse_reports.md#blocking-users),
or directly from the Admin Area. To do this:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Users**.
1. (Optional) Select a user.
1. Select the **{settings}** **User administration** dropdown.
@@ -97,7 +98,7 @@ Users can also be blocked using the [GitLab API](../../api/users.md#block-user).
A blocked user can be unblocked from the Admin Area. To do this:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Users**.
1. Select on the **Blocked** tab.
1. (Optional) Select a user.
@@ -136,15 +137,19 @@ A deactivated user:
Personal projects, and group and user history of the deactivated user are left intact.
+NOTE:
+Users are notified about account deactivation if
+[user deactivation emails](settings/email.md#user-deactivation-emails) are enabled.
+
A user can be deactivated from the Admin Area. To do this:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Users**.
1. (Optional) Select a user.
1. Select the **{settings}** **User administration** dropdown.
1. Select **Deactivate**.
-For the deactivation option to be visible to an admin, the user:
+For the deactivation option to be visible to an administrator, the user:
- Must be currently active.
- Must not have signed in, or have any activity, in the last 90 days.
@@ -159,7 +164,7 @@ Users can also be deactivated using the [GitLab API](../../api/users.md#deactiva
Administrators can enable automatic deactivation of users who have not signed in, or have no activity
in the last 90 days. To do this:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > General**.
1. Expand the **Account and limit** section.
1. Under **Dormant users**, check **Deactivate dormant users after 90 days of inactivity**.
@@ -177,7 +182,7 @@ A deactivated user can be activated from the Admin Area.
To do this:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Users**.
1. Select the **Deactivated** tab.
1. (Optional) Select a user.
@@ -193,9 +198,9 @@ Users can also be activated using the [GitLab API](../../api/users.md#activate-u
## Ban and unban users
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/327353) in GitLab 14.2.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/327353) in GitLab 14.2.
-GitLab administrators can ban and unban users. Banned users are blocked, and their issues are hidden.
+GitLab administrators can ban and unban users. Banned users are blocked, and their issues are hidden.
The banned user's comments are still displayed. Hiding a banned user's comments is [tracked in this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/327356).
### Ban a user
@@ -204,7 +209,7 @@ To block a user and hide their contributions, administrators can ban the user.
Users can be banned using the Admin Area. To do this:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Users**.
1. (Optional) Select a user.
1. Select the **{settings}** **User administration** dropdown.
@@ -216,7 +221,7 @@ The banned user does not consume a [seat](../../subscriptions/self_managed/index
A banned user can be unbanned using the Admin Area. To do this:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Users**.
1. Select the **Banned** tab.
1. (Optional) Select a user.
diff --git a/doc/user/admin_area/monitoring/health_check.md b/doc/user/admin_area/monitoring/health_check.md
index a3e46ea6225..c5ffb032afd 100644
--- a/doc/user/admin_area/monitoring/health_check.md
+++ b/doc/user/admin_area/monitoring/health_check.md
@@ -146,8 +146,8 @@ Access token has been deprecated in GitLab 9.4 in favor of [IP whitelist](#ip-wh
An access token needs to be provided while accessing the probe endpoints. You can
find the current accepted token in the user interface:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Monitoring > Health Check**. (`admin/health_check`)
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Monitoring > Health Check**. (`admin/health_check`)
![access token](img/health_check_token.png)
diff --git a/doc/user/admin_area/review_abuse_reports.md b/doc/user/admin_area/review_abuse_reports.md
index 7816d0648b2..6494934c34d 100644
--- a/doc/user/admin_area/review_abuse_reports.md
+++ b/doc/user/admin_area/review_abuse_reports.md
@@ -16,7 +16,7 @@ reports in the Admin Area.
To receive notifications of new abuse reports by email, follow these steps:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Reporting**.
1. Expand the **Abuse reports** section.
1. Provide an email address.
@@ -33,7 +33,7 @@ documentation](../report_abuse.md).
To access abuse reports:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Abuse Reports**.
There are 3 ways to resolve an abuse report, with a button for each method:
diff --git a/doc/user/admin_area/settings/account_and_limit_settings.md b/doc/user/admin_area/settings/account_and_limit_settings.md
index 71e05f44ef0..3549aa5323b 100644
--- a/doc/user/admin_area/settings/account_and_limit_settings.md
+++ b/doc/user/admin_area/settings/account_and_limit_settings.md
@@ -11,8 +11,8 @@ type: reference
You can change the default maximum number of projects that users can create in their personal namespace:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**, then expand **Account and limit**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**, then expand **Account and limit**.
1. Increase or decrease that **Default projects limit** value.
If you set **Default projects limit** to 0, users are not allowed to create projects
@@ -22,8 +22,8 @@ in their users personal namespace. However, projects can still be created in a g
You can change the maximum file size for attachments in comments and replies in GitLab:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**, then expand **Account and limit**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**, then expand **Account and limit**.
1. Increase or decrease by changing the value in **Maximum attachment size (MB)**.
NOTE:
@@ -35,8 +35,8 @@ details.
You can change the maximum push size for your repository:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**, then expand **Account and limit**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**, then expand **Account and limit**.
1. Increase or decrease by changing the value in **Maximum push size (MB)**.
NOTE:
@@ -50,8 +50,8 @@ Use [Git LFS](../../../topics/git/lfs/index.md) to add large files to a reposito
You can change the maximum file size for imports in GitLab:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**, then expand **Account and limit**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**, then expand **Account and limit**.
1. Increase or decrease by changing the value in **Maximum import size (MB)**.
NOTE:
@@ -70,8 +70,8 @@ A prefix can help you identify PATs visually, as well as with automation tools.
Only a GitLab administrator can set the prefix, which is a global setting applied
to any PAT generated in the system by any user:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Account and limit** section.
1. Fill in the **Personal Access Token prefix** field.
1. Click **Save changes**.
@@ -113,8 +113,8 @@ These settings can be found in:
1. Fill in the **Repository size limit (MB)** field in the **Naming, visibility** section.
1. Click **Save changes**.
- GitLab global settings:
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
- 1. In the left sidebar, select **Settings > General**.
+ 1. On the top bar, select **Menu > Admin**.
+ 1. On the left sidebar, select **Settings > General**.
1. Expand the **Account and limit** section.
1. Fill in the **Size limit per repository (MB)** field.
1. Click **Save changes**.
@@ -154,19 +154,19 @@ nginx['client_max_body_size'] = "200m"
> - It's deployed behind a feature flag, disabled by default.
> - It's disabled on GitLab.com.
> - It's not recommended for production use.
-> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](../../../security/two_factor_authentication.md#enable-or-disable-two-factor-authentication-2fa-for-git-operations).
+> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](../../../security/two_factor_authentication.md#enable-or-disable-2fa-for-git-operations).
NOTE:
This feature is under development and not ready for production use. It is deployed
behind a feature flag that is **disabled by default**. To use it in GitLab
-self-managed instances, ask a GitLab administrator to [enable it](../../../security/two_factor_authentication.md#enable-or-disable-two-factor-authentication-2fa-for-git-operations).
+self-managed instances, ask a GitLab administrator to [enable it](../../../security/two_factor_authentication.md#enable-or-disable-2fa-for-git-operations).
GitLab administrators can choose to customize the session duration (in minutes) for Git operations when 2FA is enabled. The default is 15 and this can be set to a value between 1 and 10080.
To set a limit on how long these sessions are valid:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Account and limit** section.
1. Fill in the **Session duration for Git operations when 2FA is enabled (minutes)** field.
1. Click **Save changes**.
@@ -190,8 +190,8 @@ there are no restrictions.
To set a lifetime on how long personal access tokens are valid:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Account and limit** section.
1. Fill in the **Maximum allowable lifetime for personal access tokens (days)** field.
1. Click **Save changes**.
@@ -213,8 +213,8 @@ By default, expired SSH keys **are not usable**.
To allow the use of expired SSH keys:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Account and limit** section.
1. Uncheck the **Enforce SSH key expiration** checkbox.
@@ -229,8 +229,8 @@ By default, expired personal access tokens (PATs) **are not usable**.
To allow the use of expired PATs:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Account and limit** section.
1. Uncheck the **Enforce personal access token expiration** checkbox.
@@ -242,8 +242,8 @@ To maintain integrity of user details in [Audit Events](../../../administration/
To do this:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**, then expand **Account and limit**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**, then expand **Account and limit**.
1. Select the **Prevent users from changing their profile name** checkbox.
NOTE:
diff --git a/doc/user/admin_area/settings/continuous_integration.md b/doc/user/admin_area/settings/continuous_integration.md
index 3b56318e711..178b117d06c 100644
--- a/doc/user/admin_area/settings/continuous_integration.md
+++ b/doc/user/admin_area/settings/continuous_integration.md
@@ -15,7 +15,7 @@ job artifacts.
To enable (or disable) [Auto DevOps](../../../topics/autodevops/index.md)
for all projects:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > CI/CD**.
1. Check (or uncheck to disable) the box that says **Default to Auto DevOps pipeline for all projects**.
1. Optionally, set up the [Auto DevOps base domain](../../../topics/autodevops/requirements.md#auto-devops-base-domain)
@@ -33,7 +33,7 @@ If you want to disable it for a specific project, you can do so in
To display details about the instance's shared runners in all projects'
runner settings:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > CI/CD**.
1. Expand **Continuous Integration and Deployment**.
1. Enter your shared runner details in the **Shared runner details** field.
@@ -64,7 +64,7 @@ To change it at the:
- Instance level:
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
+ 1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > CI/CD**.
1. Change the value of maximum artifacts size (in MB).
1. Click **Save changes** for the changes to take effect.
@@ -91,7 +91,7 @@ can be set in the Admin Area of your GitLab instance. The syntax of duration is
described in [`artifacts:expire_in`](../../../ci/yaml/index.md#artifactsexpire_in)
and the default value is `30 days`.
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > CI/CD**.
1. Change the value of default expiration time.
1. Click **Save changes** for the changes to take effect.
@@ -122,7 +122,7 @@ If disabled at the instance level, you cannot enable this per-project.
To disable the setting:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > CI/CD**.
1. Expand **Continuous Integration and Deployment**.
1. Clear the **Keep the latest artifacts for all jobs in the latest successful pipelines** checkbox.
@@ -148,7 +148,7 @@ On GitLab.com, the quota is calculated based on your
To change the pipelines minutes quota:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > CI/CD**.
1. Expand **Continuous Integration and Deployment**.
1. In the **Pipeline minutes quota** box, enter the maximum number of minutes.
@@ -181,7 +181,7 @@ but persisting the traces and artifacts for auditing purposes.
To set the duration for which the jobs are considered as old and expired:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > CI/CD**.
1. Expand the **Continuous Integration and Deployment** section.
1. Set the value of **Archive jobs**.
@@ -198,7 +198,7 @@ As of June 22, 2020 the [value is set](../../gitlab_com/index.md#gitlab-cicd) to
To set all new [CI/CD variables](../../../ci/variables/index.md) as
[protected](../../../ci/variables/index.md#protect-a-cicd-variable) by default:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > CI/CD**.
1. Select **Protect CI/CD variables by default**.
@@ -209,7 +209,7 @@ To set all new [CI/CD variables](../../../ci/variables/index.md) as
The default CI/CD configuration file and path for new projects can be set in the Admin Area
of your GitLab instance (`.gitlab-ci.yml` if not set):
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > CI/CD**.
1. Input the new file and path in the **Default CI/CD configuration file** field.
1. Hit **Save changes** for the changes to take effect.
@@ -245,7 +245,7 @@ in the pipeline editor.
To select a CI/CD template for the required pipeline configuration:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > CI/CD**.
1. Expand the **Required pipeline configuration** section.
1. Select a CI/CD template from the dropdown.
@@ -259,7 +259,7 @@ GitLab administrators can disable the forwarding of npm requests to [npmjs.com](
To disable it:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > CI/CD**.
1. Expand the **Package Registry** section.
1. Clear the checkbox **Forward npm package requests to the npm Registry if the packages are not found in the GitLab Package Registry**.
@@ -271,7 +271,7 @@ GitLab administrators can disable the forwarding of PyPI requests to [pypi.org](
To disable it:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > CI/CD**.
1. Expand the **Package Registry** section.
1. Clear the checkbox **Forward PyPI package requests to the PyPI Registry if the packages are not found in the GitLab Package Registry**.
@@ -283,7 +283,7 @@ GitLab administrators can adjust the maximum allowed file size for each package
To set the maximum file size:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > CI/CD**.
1. Expand the **Package Registry** section.
1. Find the package type you would like to adjust.
@@ -304,7 +304,7 @@ By default, all members of a project and group are able to register runners.
To change this:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. Go to **Settings > CI/CD**.
1. Expand the **Runner registration** section.
1. Select the desired options.
diff --git a/doc/user/admin_area/settings/email.md b/doc/user/admin_area/settings/email.md
index 236b75797a2..c04a9a12912 100644
--- a/doc/user/admin_area/settings/email.md
+++ b/doc/user/admin_area/settings/email.md
@@ -21,7 +21,7 @@ address in the body of the email instead.
To include the author's email address in the email body:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Preferences** (`/admin/application_settings/preferences`).
1. Expand **Email**.
1. Select the **Include author name in email notification email body** checkbox.
@@ -33,7 +33,7 @@ GitLab can send email in multipart format (HTML and plain text) or plain text on
To enable multipart email:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Preferences** (`/admin/application_settings/preferences`).
1. Expand **Email**.
1. Select **Enable multipart email**.
@@ -48,7 +48,7 @@ This configuration option sets the email hostname for [private commit emails](..
To change the hostname used in private commit emails:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Preferences** (`/admin/application_settings/preferences`).
1. Expand **Email**.
1. Enter the desired hostname in the **Custom hostname (for private commit emails)** field.
@@ -66,12 +66,24 @@ can be used for legal, auditing, or compliance reasons, for example.
To add additional text to emails:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Preferences** (`/admin/application_settings/preferences`).
1. Expand **Email**.
1. Enter your text in the **Additional text** field.
1. Select **Save changes**.
+## User deactivation emails **(FREE SELF)**
+
+GitLab sends email notifications to users when their account has been deactivated.
+
+To disable these notifications:
+
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Preferences** (`/admin/application_settings/preferences`).
+1. Expand **Email**.
+1. Clear the **Enable user deactivation emails** checkbox.
+1. Select **Save changes**.
+
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
diff --git a/doc/user/admin_area/settings/external_authorization.md b/doc/user/admin_area/settings/external_authorization.md
index 205dd77c1bf..985f3c133d5 100644
--- a/doc/user/admin_area/settings/external_authorization.md
+++ b/doc/user/admin_area/settings/external_authorization.md
@@ -41,8 +41,8 @@ the [Omnibus GitLab documentation](https://docs.gitlab.com/omnibus/settings/logs
The external authorization service can be enabled by an administrator:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**:
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**:
![Enable external authorization service](img/external_authorization_service_settings.png)
The available required properties are:
diff --git a/doc/user/admin_area/settings/floc.md b/doc/user/admin_area/settings/floc.md
index 0e9d4e5d0c1..17c390aef0e 100644
--- a/doc/user/admin_area/settings/floc.md
+++ b/doc/user/admin_area/settings/floc.md
@@ -22,8 +22,8 @@ Permissions-Policy: interest-cohort=()
To enable it:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand **Federated Learning of Cohorts**.
1. Check the box.
1. Click **Save changes**.
diff --git a/doc/user/admin_area/settings/git_lfs_rate_limits.md b/doc/user/admin_area/settings/git_lfs_rate_limits.md
new file mode 100644
index 00000000000..8a0754374e2
--- /dev/null
+++ b/doc/user/admin_area/settings/git_lfs_rate_limits.md
@@ -0,0 +1,35 @@
+---
+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
+type: reference
+---
+
+# Git LFS Rate Limits **(FREE SELF)**
+
+[Git LFS (Large File Storage)](../../../topics/git/lfs/index.md) is a Git extension
+for handling large files. If you use Git LFS in your repository, common Git operations
+can generate many Git LFS requests. You can enforce
+[general user and IP rate limits](user_and_ip_rate_limits.md), but you can also
+override the general setting to enforce additional limits on Git LFS requests. This
+override can improve the security and durability of your web application. Aside from
+precedence, this configuration provides the same features as the general user and IP
+rate limits.
+
+## Configure Git LFS rate limits
+
+Git LFS rate limits are disabled by default. If enabled and configured, these limits
+supersede the [general user and IP rate limits](user_and_ip_rate_limits.md):
+
+1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the left sidebar, select **Settings > Network**.
+1. Expand **Git LFS Rate Limits**.
+1. Select **Enable authenticated Git LFS request rate limit**.
+1. Enter a value for **Max authenticated Git LFS requests per period per user**.
+1. Enter a value for **Authenticated Git LFS rate limit period in seconds**.
+1. Select **Save changes**.
+
+## Resources
+
+- [Rate limiting](../../../security/rate_limits.md)
+- [User and IP rate limits](user_and_ip_rate_limits.md)
diff --git a/doc/user/admin_area/settings/gitaly_timeouts.md b/doc/user/admin_area/settings/gitaly_timeouts.md
index 04887906c91..1d4f45d1f04 100644
--- a/doc/user/admin_area/settings/gitaly_timeouts.md
+++ b/doc/user/admin_area/settings/gitaly_timeouts.md
@@ -12,7 +12,7 @@ configured to make sure that long-running Gitaly calls don't needlessly take up
To access Gitaly timeout settings:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Preferences**.
1. Expand the **Gitaly timeouts** section.
diff --git a/doc/user/admin_area/settings/help_page.md b/doc/user/admin_area/settings/help_page.md
index 01516430f4f..cf08b9b71db 100644
--- a/doc/user/admin_area/settings/help_page.md
+++ b/doc/user/admin_area/settings/help_page.md
@@ -16,7 +16,7 @@ the GitLab sign-in page.
You can add a help message, which is shown at the top of the GitLab `/help` page (for example,
<https://gitlab.com/help>):
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Preferences**.
1. Expand **Sign-in and Help page**.
1. In **Additional text to show on the Help page**, enter the information you want to display on `/help`.
@@ -34,7 +34,7 @@ is restricted, `/help` is visible only to signed-in users.
You can add a help message, which is shown on the GitLab sign-in page. The message appears in a new
section titled **Need Help?**, located below the sign-in page message:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Preferences**.
1. Expand **Sign-in and Help page**.
1. In **Additional text to show on the sign-in page**, enter the information you want to
@@ -47,7 +47,7 @@ You can now see the message on the sign-in page.
GitLab marketing-related entries are occasionally shown on the Help page. To hide these entries:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Preferences**.
1. Expand **Sign-in and Help page**.
1. Select the **Hide marketing-related entries from the Help page** checkbox.
@@ -60,7 +60,7 @@ You can specify a custom URL to which users are directed when they:
- Select **Support** from the Help dropdown.
- Select **See our website for help** on the Help page.
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Preferences**.
1. Expand **Sign-in and Help page**.
1. In the **Support page URL** field, enter the URL.
@@ -68,8 +68,7 @@ You can specify a custom URL to which users are directed when they:
## Redirect `/help` pages
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/43157) in GitLab 13.5.
-> - Enabled on GitLab.com and is ready for production use.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/43157) in GitLab 13.5.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to
@@ -85,8 +84,8 @@ You can redirect these `/help` links to either:
- The more navigable and searchable version published at [`docs.gitlab.com`](https://docs.gitlab.com).
- A destination that meets [necessary requirements](#destination-requirements).
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > Preferences**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Preferences**.
1. Expand **Sign-in and Help page**.
1. In the **Documentation pages URL** field, enter the URL.
1. Select **Save changes**.
diff --git a/doc/user/admin_area/settings/img/domain_denylist_v14_1.png b/doc/user/admin_area/settings/img/domain_denylist_v14_1.png
index c988afd75f6..e27997fc2c2 100644
--- a/doc/user/admin_area/settings/img/domain_denylist_v14_1.png
+++ b/doc/user/admin_area/settings/img/domain_denylist_v14_1.png
Binary files differ
diff --git a/doc/user/admin_area/settings/img/import_export_rate_limits_v13_2.png b/doc/user/admin_area/settings/img/import_export_rate_limits_v13_2.png
deleted file mode 100644
index 76015ce0ee3..00000000000
--- a/doc/user/admin_area/settings/img/import_export_rate_limits_v13_2.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/admin_area/settings/img/rate_limit_on_issues_creation_v14_2.png b/doc/user/admin_area/settings/img/rate_limit_on_issues_creation_v14_2.png
index 63f4d5a4a1a..1a0a7548a91 100644
--- a/doc/user/admin_area/settings/img/rate_limit_on_issues_creation_v14_2.png
+++ b/doc/user/admin_area/settings/img/rate_limit_on_issues_creation_v14_2.png
Binary files differ
diff --git a/doc/user/admin_area/settings/img/user_and_ip_rate_limits.png b/doc/user/admin_area/settings/img/user_and_ip_rate_limits.png
deleted file mode 100644
index 5056e8354a9..00000000000
--- a/doc/user/admin_area/settings/img/user_and_ip_rate_limits.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/admin_area/settings/import_export_rate_limits.md b/doc/user/admin_area/settings/import_export_rate_limits.md
index 12235bdb5ef..7d5a928eedf 100644
--- a/doc/user/admin_area/settings/import_export_rate_limits.md
+++ b/doc/user/admin_area/settings/import_export_rate_limits.md
@@ -5,28 +5,26 @@ group: Import
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
---
-# Project/group import/export rate limits **(FREE SELF)**
+# Rate limits for imports and exports of project and groups **(FREE SELF)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35728) in GitLab 13.2.
-The following table includes configurable rate limits. The following table includes limits on a
-per minute per user basis:
+You can configure the rate limits for imports and exports of projects and groups:
-| Limit | Default (per minute per user) |
-|--------------------------|-------------------------------|
-| Project Import | 6 |
-| Project Export | 6 |
-| Project Export Download | 1 |
-| Group Import | 6 |
-| Group Export | 6 |
-| Group Export Download | 1 |
+To change a rate limit:
-All rate limits are:
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Network**, then expand **Import and export rate limits**.
+1. Change the value of any rate limit. The rate limits are per minute per user, not per IP address.
+ Set to `0` to disable a rate limit.
-- Configurable through the top bar at **Menu > Admin > Settings > Network > Import/Export Rate Limits**
-- Applied per minute per user
-- Not applied per IP address
-- Active by default. To disable, set the option to `0`
-- Logged to `auth.log` file if exceed rate limit
+| Limit | Default |
+|-------------------------|---------|
+| Project Import | 6 |
+| Project Export | 6 |
+| Project Export Download | 1 |
+| Group Import | 6 |
+| Group Export | 6 |
+| Group Export Download | 1 |
-![Import/Export rate limits](img/import_export_rate_limits_v13_2.png)
+When a user exceeds a rate limit, it is logged in `auth.log`.
diff --git a/doc/user/admin_area/settings/index.md b/doc/user/admin_area/settings/index.md
index 21ca1c573fe..ec5f3ca812f 100644
--- a/doc/user/admin_area/settings/index.md
+++ b/doc/user/admin_area/settings/index.md
@@ -17,8 +17,8 @@ documentation for all current settings and limits on the GitLab.com instance.
To access the default page for Admin Area settings:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
| Option | Description |
| ------ | ----------- |
@@ -37,8 +37,9 @@ To access the default page for Admin Area settings:
| Option | Description |
| ------ | ----------- |
-| [Elasticsearch](../../../integration/elasticsearch.md#enabling-advanced-search) | Elasticsearch integration. Elasticsearch AWS IAM. |
+| [Elasticsearch](../../../integration/elasticsearch.md#enable-advanced-search) | Elasticsearch integration. Elasticsearch AWS IAM. |
| [Kroki](../../../administration/integration/kroki.md#enable-kroki-in-gitlab) | Allow rendering of diagrams in AsciiDoc and Markdown documents using [kroki.io](https://kroki.io). |
+| [Mailgun](../../../administration/integration/mailgun.md) | Enable your GitLab instance to receive invite email bounce events from Mailgun, if it is your email provider. |
| [PlantUML](../../../administration/integration/plantuml.md) | Allow rendering of PlantUML diagrams in documents. |
| [Slack application](../../../user/project/integrations/gitlab_slack_application.md#configuration) **(FREE SAAS)** | Slack integration allows you to interact with GitLab via slash commands in a chat window. This option is only available on GitLab.com, though it may be [available for self-managed instances in the future](https://gitlab.com/gitlab-org/gitlab/-/issues/28164). |
| [Third party offers](third_party_offers.md) | Control the display of third party offers. |
@@ -96,9 +97,10 @@ To access the default page for Admin Area settings:
| Performance optimization | [Write to "authorized_keys" file](../../../administration/operations/fast_ssh_key_lookup.md#setting-up-fast-lookup-via-gitlab-shell) and [Push event activities limit and bulk push events](push_event_activities_limit.md). Various settings that affect GitLab performance. |
| [User and IP rate limits](user_and_ip_rate_limits.md) | Configure limits for web and API requests. |
| [Package Registry Rate Limits](package_registry_rate_limits.md) | Configure specific limits for Packages API requests that supersede the user and IP rate limits. |
+| [Git LFS Rate Limits](git_lfs_rate_limits.md) | Configure specific limits for Git LFS requests that supersede the user and IP rate limits. |
| [Outbound requests](../../../security/webhooks.md) | Allow requests to the local network from hooks and services. |
| [Protected Paths](protected_paths.md) | Configure paths to be protected by Rack Attack. |
-| [Incident Management](../../../operations/incident_management/index.md) Limits | Configure limits on the number of inbound alerts able to be sent to a project. |
+| [Incident Management](../../../operations/incident_management/index.md) Limits | Limit the number of inbound alerts that can be sent to a project. |
| [Notes creation limit](rate_limit_on_notes_creation.md)| Set a rate limit on the note creation requests. |
## Geo
@@ -118,12 +120,13 @@ To access the default page for Admin Area settings:
| [Polling interval multiplier](../../../administration/polling.md) | Configure how frequently the GitLab UI polls for updates. |
| [Gitaly timeouts](gitaly_timeouts.md) | Configure Gitaly timeouts. |
| Localization | [Default first day of the week](../../profile/preferences.md) and [Time tracking](../../project/time_tracking.md#limit-displayed-units-to-hours). |
+| [Sidekiq Job Limits](sidekiq_job_limits.md) | Limit the size of Sidekiq jobs stored in Redis. |
### Default first day of the week
You can change the [Default first day of the week](../../profile/preferences.md)
for the entire GitLab instance:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > Preferences**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Preferences**.
1. Scroll to the **Localization** section, and select your desired first day of the week.
diff --git a/doc/user/admin_area/settings/instance_template_repository.md b/doc/user/admin_area/settings/instance_template_repository.md
index 8a796435ef8..862bf3b1652 100644
--- a/doc/user/admin_area/settings/instance_template_repository.md
+++ b/doc/user/admin_area/settings/instance_template_repository.md
@@ -7,7 +7,7 @@ type: reference
# Instance template repository **(PREMIUM SELF)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5986) in GitLab Premium 11.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5986) in GitLab Premium 11.3.
In hosted systems, enterprises often have a need to share their own templates
across teams. This feature allows an administrator to pick a project to be the
@@ -19,8 +19,8 @@ while the project remains secure.
To select a project to serve as the custom template repository:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > Templates**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Templates**.
1. Select the project:
![File templates in the Admin Area](img/file_template_admin_area_v14_0.png)
diff --git a/doc/user/admin_area/settings/package_registry_rate_limits.md b/doc/user/admin_area/settings/package_registry_rate_limits.md
index 6e7b9b0da30..1aeb011d880 100644
--- a/doc/user/admin_area/settings/package_registry_rate_limits.md
+++ b/doc/user/admin_area/settings/package_registry_rate_limits.md
@@ -7,28 +7,47 @@ type: reference
# Package Registry Rate Limits **(FREE SELF)**
-Rate limiting is a common technique used to improve the security and durability of a web
-application. For more details, see [Rate limits](../../../security/rate_limits.md). General user and
-IP rate limits can be enforced from the top bar at
-**Menu > Admin > Settings > Network > User and IP rate limits**.
-For more details, see [User and IP rate limits](user_and_ip_rate_limits.md).
-
With the [GitLab Package Registry](../../packages/package_registry/index.md),
you can use GitLab as a private or public registry for a variety of common package managers. You can
publish and share packages, which others can consume as a dependency in downstream projects through
the [Packages API](../../../api/packages.md).
-When downloading such dependencies in downstream projects, many requests are made through the
-Packages API. You may therefore reach enforced user and IP rate limits. To address this issue, you
-can define specific rate limits for the Packages API in
-**Menu > Admin > Settings > Network > Package Registry Rate Limits**:
+If downstream projects frequently download such dependencies, many requests are made through the
+Packages API. You may therefore reach enforced [user and IP rate limits](user_and_ip_rate_limits.md).
+To address this issue, you can define specific rate limits for the Packages API:
+
+- [Unauthenticated requests (per IP)](#enable-unauthenticated-request-rate-limit-for-packages-api).
+- [Authenticated API requests (per user)](#enable-authenticated-api-request-rate-limit-for-packages-api).
+
+These limits are disabled by default.
+
+When enabled, they supersede the general user and IP rate limits for requests to
+the Packages API. You can therefore keep the general user and IP rate limits, and
+increase the rate limits for the Packages API. Besides this precedence, there is
+no difference in functionality compared to the general user and IP rate limits.
+
+## Enable unauthenticated request rate limit for packages API
+
+To enable the unauthenticated request rate limit:
+
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Network**, and expand **Package registry rate limits**.
+1. Select **Enable unauthenticated request rate limit**.
+
+ - Optional. Update the **Maximum unauthenticated requests per rate limit period per IP** value.
+ Defaults to `800`.
+ - Optional. Update the **Unauthenticated rate limit period in seconds** value.
+ Defaults to `15`.
+
+## Enable authenticated API request rate limit for packages API
-- Unauthenticated Packages API requests
-- Authenticated Packages API requests
+To enable the authenticated API request rate limit:
-These limits are disabled by default. When enabled, they supersede the general user and IP rate
-limits for requests to the Packages API. You can therefore keep the general user and IP rate limits,
-and increase (if necessary) the rate limits for the Packages API.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Network**, and expand **Package registry rate limits**.
+1. Select **Enable authenticated API request rate limit**.
-Besides this precedence, there are no differences in functionality compared to the general user and
-IP rate limits. For more details, see [User and IP rate limits](user_and_ip_rate_limits.md).
+ - Optional. Update the **Maximum authenticated API requests per rate limit period per user** value.
+ Defaults to `1000`.
+ - Optional. Update the **Authenticated API rate limit period in seconds** value.
+ Defaults to `15`.
diff --git a/doc/user/admin_area/settings/project_integration_management.md b/doc/user/admin_area/settings/project_integration_management.md
index 3b949b638d8..aadabe4d6ad 100644
--- a/doc/user/admin_area/settings/project_integration_management.md
+++ b/doc/user/admin_area/settings/project_integration_management.md
@@ -22,8 +22,8 @@ Only the complete settings for an integration can be inherited. Per-field inheri
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2137) in GitLab 13.3 for project-level integrations.
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2543) in GitLab 13.6 for group-level integrations.
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > Integrations**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Integrations**.
1. Select an integration.
1. Enter configuration details and click **Save changes**.
@@ -54,8 +54,8 @@ integration on all non-configured groups and projects by default.
### Remove an instance-level default setting
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > Integrations**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Integrations**.
1. Select an integration.
1. Click **Reset** and confirm.
@@ -68,8 +68,8 @@ Resetting an instance-level default setting removes the integration from all pro
You can view which projects in your instance use custom settings that [override the instance-level default settings](#use-custom-settings-for-a-group-or-project-integration)
for an integration.
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > Integrations**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Integrations**.
1. Select an integration.
1. Select the **Projects using custom settings** tab.
diff --git a/doc/user/admin_area/settings/push_event_activities_limit.md b/doc/user/admin_area/settings/push_event_activities_limit.md
index 21e4f32ff8d..760ce96d987 100644
--- a/doc/user/admin_area/settings/push_event_activities_limit.md
+++ b/doc/user/admin_area/settings/push_event_activities_limit.md
@@ -26,8 +26,8 @@ the activity feed.
To modify this setting:
- In the Admin Area:
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
- 1. In the left sidebar, select **Settings > Network**, then expand **Performance optimization**.
+ 1. On the top bar, select **Menu > Admin**.
+ 1. On the left sidebar, select **Settings > Network**, then expand **Performance optimization**.
- Through the [Application settings API](../../../api/settings.md#list-of-settings-that-can-be-accessed-via-api-calls)
as `push_event_activities_limit`.
diff --git a/doc/user/admin_area/settings/rate_limit_on_issues_creation.md b/doc/user/admin_area/settings/rate_limit_on_issues_creation.md
index bba61a7b913..a2e8a875ebb 100644
--- a/doc/user/admin_area/settings/rate_limit_on_issues_creation.md
+++ b/doc/user/admin_area/settings/rate_limit_on_issues_creation.md
@@ -12,7 +12,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
This setting allows you to rate limit the requests to the issue and epic creation endpoints.
To can change its value:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Network**.
1. Expand **Issues Rate Limits**.
1. Under **Max requests per minute per user**, enter the new value.
diff --git a/doc/user/admin_area/settings/rate_limit_on_notes_creation.md b/doc/user/admin_area/settings/rate_limit_on_notes_creation.md
index 7615ad6f81d..0a07cf095ee 100644
--- a/doc/user/admin_area/settings/rate_limit_on_notes_creation.md
+++ b/doc/user/admin_area/settings/rate_limit_on_notes_creation.md
@@ -9,15 +9,15 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53637) in GitLab 13.9.
-This setting allows you to rate limit the requests to the note creation endpoint.
+You can configure the per-user rate limit for requests to the note creation endpoint.
To change the note creation rate limit:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Network**.
-1. Expand **Notes Rate Limits**.
-1. Under **Max requests per minute per user**, enter the new value.
-1. Optional. Under **List of users to be excluded from the limit**, list users to be excluded from the limit.
+1. Expand **Notes rate limit**.
+1. In the **Maximum requests per minute** box, enter the new value.
+1. Optional. In the **Users to exclude from the rate limit** box, list users allowed to exceed the limit.
1. Select **Save changes**.
This limit is:
diff --git a/doc/user/admin_area/settings/rate_limits_on_raw_endpoints.md b/doc/user/admin_area/settings/rate_limits_on_raw_endpoints.md
index 24b69ba74c7..020d02b1635 100644
--- a/doc/user/admin_area/settings/rate_limits_on_raw_endpoints.md
+++ b/doc/user/admin_area/settings/rate_limits_on_raw_endpoints.md
@@ -11,8 +11,8 @@ type: reference
This setting defaults to `300` requests per minute, and allows you to rate limit the requests to raw endpoints:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > Network**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Network**.
1. Expand **Performance optimization**.
For example, requests over `300` per minute to `https://gitlab.com/gitlab-org/gitlab-foss/raw/master/app/controllers/application_controller.rb` are blocked. Access to the raw file is released after 1 minute.
diff --git a/doc/user/admin_area/settings/sidekiq_job_limits.md b/doc/user/admin_area/settings/sidekiq_job_limits.md
new file mode 100644
index 00000000000..c6a783beb3f
--- /dev/null
+++ b/doc/user/admin_area/settings/sidekiq_job_limits.md
@@ -0,0 +1,36 @@
+---
+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/engineering/ux/technical-writing/#assignments
+type: reference
+---
+
+# Sidekiq job size limits **(FREE SELF)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68982) in GitLab 14.3.
+
+[Sidekiq](../../../administration/sidekiq.md) jobs get stored in
+Redis. To avoid excessive memory for Redis, we:
+
+- Compress job arguments before storing them in Redis.
+arguments before storing them in Redis, and rejecting jobs that exceed
+- Reject jobs that exceed the specified threshold limit after compression.
+
+To access Sidekiq job size limits:
+
+1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the left sidebar, select **Settings > Preferences**.
+1. Expand **Sidekiq job size limits**.
+1. Adjust the compression threshold or size limit. The compression can
+ be disabled by selecting the **Track** mode.
+
+## Available settings
+
+| Setting | Default | Description |
+|-------------------------------------------|------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| Limiting mode | Compress | This mode compresses the jobs at the specified threshold and rejects them if they exceed the specified limit after compression. |
+| Sidekiq job compression threshold (bytes) | 100 000 (100 KB) | When the size of arguments exceeds this threshold, they are compressed before being stored in Redis. |
+| Sidekiq job size limit (bytes) | 0 | The jobs exceeding this size after compression are rejected. This avoids excessive memory usage in Redis leading to instability. Setting it to 0 prevents rejecting jobs. |
+
+After changing these values, [restart
+Sidekiq](../../../administration/restart_gitlab.md).
diff --git a/doc/user/admin_area/settings/sign_in_restrictions.md b/doc/user/admin_area/settings/sign_in_restrictions.md
index 333e9465c31..223ffeebd44 100644
--- a/doc/user/admin_area/settings/sign_in_restrictions.md
+++ b/doc/user/admin_area/settings/sign_in_restrictions.md
@@ -13,8 +13,8 @@ You can use **Sign-in restrictions** to customize authentication restrictions fo
To access sign-in restriction settings:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Sign-in restrictions** section.
## Password authentication enabled
@@ -26,7 +26,7 @@ You can restrict the password authentication for web interface and Git over HTTP
## Admin Mode
-> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2158) in GitLab 13.10.
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2158) in GitLab 13.10.
When this feature is enabled, instance administrators are limited as regular users. During that period,
they do not have access to all projects, groups, or the **Admin Area** menu.
@@ -118,7 +118,7 @@ For example, if you include the following information in the noted text box:
To access this text box:
1. On the top bar, select **Menu > Admin**.
-1. In the left sidebar, select **Settings > General**, and expand the **Sign-in restrictions** section.
+1. On the left sidebar, select **Settings > General**, and expand the **Sign-in restrictions** section.
```
Your users see the **Custom sign-in text** when they navigate to the sign-in screen for your
diff --git a/doc/user/admin_area/settings/sign_up_restrictions.md b/doc/user/admin_area/settings/sign_up_restrictions.md
index c774ae2eecc..dc09d6a5132 100644
--- a/doc/user/admin_area/settings/sign_up_restrictions.md
+++ b/doc/user/admin_area/settings/sign_up_restrictions.md
@@ -22,8 +22,8 @@ you do not expect public users to sign up for an account.
To disable sign ups:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**, and expand **Sign-up restrictions**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**, and expand **Sign-up restrictions**.
1. Clear the **Sign-up enabled** checkbox, then select **Save changes**.
## Require administrator approval for new sign ups
@@ -38,8 +38,8 @@ enabled by default for new GitLab instances. It is only applicable if sign ups a
To require administrator approval for new sign ups:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**, and expand **Sign-up restrictions**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**, and expand **Sign-up restrictions**.
1. Select the **Require admin approval for new sign-ups** checkbox, then select **Save changes**.
In [GitLab 13.7 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/273258), if an administrator disables this setting, the users in pending approval state are
@@ -52,8 +52,8 @@ their email address before they are allowed to sign in.
To enforce confirmation of the email address used for new sign ups:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**, and expand **Sign-up restrictions**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**, and expand **Sign-up restrictions**.
1. Select the **Enable email restrictions for sign ups** checkbox, then select **Save changes**.
## User cap **(FREE SELF)**
@@ -70,8 +70,8 @@ user cap, the users in pending approval state are automatically approved in a ba
### Set the user cap number
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand **Sign-up restrictions**.
1. Enter a number in **User cap**.
1. Select **Save changes**.
@@ -80,8 +80,8 @@ New user sign ups are subject to the user cap restriction.
## Remove the user cap
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand **Sign-up restrictions**.
1. Remove the number from **User cap**.
1. Select **Save changes**.
@@ -122,15 +122,11 @@ email addresses to disallowed domains after sign up.
### Allowlist email domains
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/598) in GitLab 7.11.0
-
You can restrict users only to sign up using email addresses matching the given
domains list.
### Denylist email domains
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/5259) in GitLab 8.10.
-
You can block users from signing up when using an email addresses of specific domains. This can
reduce the risk of malicious users creating spam accounts with disposable email addresses.
@@ -138,8 +134,8 @@ reduce the risk of malicious users creating spam accounts with disposable email
To create an email domain allowlist or denylist:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**, and expand **Sign-up restrictions**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**, and expand **Sign-up restrictions**.
1. For the allowlist, you must enter the list manually. For the denylist, you can enter the list
manually or upload a `.txt` file that contains list entries.
diff --git a/doc/user/admin_area/settings/terms.md b/doc/user/admin_area/settings/terms.md
index 21805ef771f..c7c41e665ec 100644
--- a/doc/user/admin_area/settings/terms.md
+++ b/doc/user/admin_area/settings/terms.md
@@ -17,8 +17,8 @@ for example `https://gitlab.example.com/-/users/terms`.
To enforce acceptance of a Terms of Service and Privacy Policy:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Terms of Service and Privacy Policy** section.
1. Check the **All users must accept the Terms of Service and Privacy Policy to access GitLab** checkbox.
1. Input the text of the **Terms of Service and Privacy Policy**. You can use [Markdown](../../markdown.md)
diff --git a/doc/user/admin_area/settings/third_party_offers.md b/doc/user/admin_area/settings/third_party_offers.md
index 6f7cb081315..a9c8c5d2a76 100644
--- a/doc/user/admin_area/settings/third_party_offers.md
+++ b/doc/user/admin_area/settings/third_party_offers.md
@@ -15,7 +15,7 @@ for using [Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/
To toggle the display of third-party offers:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings**, and expand **Third-party offers**.
1. Select **Do not display offers from third parties**.
1. Select **Save changes**.
diff --git a/doc/user/admin_area/settings/usage_statistics.md b/doc/user/admin_area/settings/usage_statistics.md
index 89c6be9608b..330a25087ef 100644
--- a/doc/user/admin_area/settings/usage_statistics.md
+++ b/doc/user/admin_area/settings/usage_statistics.md
@@ -73,9 +73,10 @@ If your GitLab instance is behind a proxy, set the appropriate
To enable or disable Service Ping and version check:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > Metrics and profiling**, and expand **Usage statistics**.
-1. Select or clear the **Version check** and **Service ping** checkboxes.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Metrics and profiling**.
+1. Expand **Usage statistics**.
+1. Select or clear the **Enable version check** and **Enable service ping** checkboxes.
1. Select **Save changes**.
<!-- ## Troubleshooting
diff --git a/doc/user/admin_area/settings/user_and_ip_rate_limits.md b/doc/user/admin_area/settings/user_and_ip_rate_limits.md
index fdeda0cf451..32f08801c76 100644
--- a/doc/user/admin_area/settings/user_and_ip_rate_limits.md
+++ b/doc/user/admin_area/settings/user_and_ip_rate_limits.md
@@ -13,30 +13,78 @@ of a web application. For more details, see
The following limits are disabled by default:
-- Unauthenticated requests
-- Authenticated API requests
-- Authenticated web requests
+- [Unauthenticated API requests (per IP)](#enable-unauthenticated-api-request-rate-limit).
+- [Unauthenticated web requests (per IP)](#enable-unauthenticated-web-request-rate-limit).
+- [Authenticated API requests (per user)](#enable-authenticated-api-request-rate-limit).
+- [Authenticated web requests (per user)](#enable-authenticated-web-request-rate-limit).
-To enforce any or all of them:
+NOTE:
+By default, all Git operations are first tried unauthenticated. Because of this, HTTP Git operations
+may trigger the rate limits configured for unauthenticated requests.
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > Network**, and expand **User and IP rate limits**:
- ![user-and-ip-rate-limits](img/user_and_ip_rate_limits.png)
+## Enable unauthenticated API request rate limit
- NOTE:
- By default, all Git operations are first tried unauthenticated. Because of this, HTTP Git operations
- may trigger the rate limits configured for unauthenticated requests.
+To enable the unauthenticated request rate limit:
-## Response text
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Network**, and expand **User and IP rate limits**.
+1. Select **Enable unauthenticated API request rate limit**.
+
+ - Optional. Update the **Maximum unauthenticated API requests per rate limit period per IP** value.
+ Defaults to `3600`.
+ - Optional. Update the **Unauthenticated rate limit period in seconds** value.
+ Defaults to `3600`.
+
+## Enable unauthenticated web request rate limit
+
+To enable the unauthenticated request rate limit:
+
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Network**, and expand **User and IP rate limits**.
+1. Select **Enable unauthenticated web request rate limit**.
+
+ - Optional. Update the **Maximum unauthenticated web requests per rate limit period per IP** value.
+ Defaults to `3600`.
+ - Optional. Update the **Unauthenticated rate limit period in seconds** value.
+ Defaults to `3600`.
+
+## Enable authenticated API request rate limit
+
+To enable the authenticated API request rate limit:
+
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Network**, and expand **User and IP rate limits**.
+1. Select **Enable authenticated API request rate limit**.
+
+ - Optional. Update the **Maximum authenticated API requests per rate limit period per user** value.
+ Defaults to `7200`.
+ - Optional. Update the **Authenticated API rate limit period in seconds** value.
+ Defaults to `3600`.
+
+## Enable authenticated web request rate limit
+
+To enable the unauthenticated request rate limit:
+
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Network**, and expand **User and IP rate limits**.
+1. Select **Enable authenticated web request rate limit**.
+
+ - Optional. Update the **Maximum authenticated web requests per rate limit period per user** value.
+ Defaults to `7200`.
+ - Optional. Update the **Authenticated web rate limit period in seconds** value.
+ Defaults to `3600`.
+
+## Use a custom rate limit response
A request that exceeds a rate limit returns a 429 response code and a
-plain-text body, which by default is:
+plain-text body, which by default is `Retry later`.
-```plaintext
-Retry later
-```
+To use a custom response:
-It is possible to customize this response text in the Admin Area.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Network**, and expand **User and IP rate limits**.
+1. In the **Plain-text response to send to clients that hit a rate limit** text box,
+ add the plain-text response message.
## Response headers
@@ -129,6 +177,10 @@ a comma-separated list of throttle names.
The possible names are:
- `throttle_unauthenticated`
+ - [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/335300) in GitLab 14.3. Use `throttle_unauthenticated_api` or `throttle_unauthenticated_web` instead.
+ `throttle_unauthenticated` is still supported and selects both of them.
+- `throttle_unauthenticated_api`
+- `throttle_unauthenticated_web`
- `throttle_authenticated_api`
- `throttle_authenticated_web`
- `throttle_unauthenticated_protected_paths`
@@ -136,6 +188,7 @@ The possible names are:
- `throttle_authenticated_protected_paths_web`
- `throttle_unauthenticated_packages_api`
- `throttle_authenticated_packages_api`
+- `throttle_authenticated_git_lfs`
For example, to try out throttles for all authenticated requests to
non-protected paths can be done by setting
diff --git a/doc/user/admin_area/settings/visibility_and_access_controls.md b/doc/user/admin_area/settings/visibility_and_access_controls.md
index c46aec76e57..7f3f4b32802 100644
--- a/doc/user/admin_area/settings/visibility_and_access_controls.md
+++ b/doc/user/admin_area/settings/visibility_and_access_controls.md
@@ -13,8 +13,8 @@ specific controls on branches, projects, snippets, groups, and more.
To access the visibility and access control options:
1. Sign in to GitLab as a user with [Administrator role](../../permissions.md).
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Visibility and access controls** section.
## Protect default branches
@@ -33,8 +33,8 @@ or configure [branch protection for groups](../../group/index.md#change-the-defa
To change the default branch protection for the entire instance:
1. Sign in to GitLab as a user with [Administrator role](../../permissions.md).
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Visibility and access controls** section.
1. Select a **Default branch protection**:
- **Not protected** - Both developers and maintainers can push new commits,
@@ -59,8 +59,8 @@ can be overridden on a per-group basis by the group's owner. In
disable this privilege for group owners, enforcing the instance-level protection rule:
1. Sign in to GitLab as a user with [Administrator role](../../permissions.md).
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Visibility and access controls** section.
1. Deselect the **Allow owners to manage default branch protection per group** checkbox.
1. Select **Save changes**.
@@ -75,8 +75,8 @@ Instance-level protections for project creation define which roles can
on the instance. To alter which roles have permission to create projects:
1. Sign in to GitLab as a user with [Administrator role](../../permissions.md).
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Visibility and access controls** section.
1. For **Default project creation protection**, select the desired roles:
- No one.
@@ -90,23 +90,23 @@ Anyone with the **Owner** role, either at the project or group level, can
delete a project. To allow only users with the Administrator role to delete projects:
1. Sign in to GitLab as a user with [Administrator role](../../permissions.md).
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Visibility and access controls** section.
1. Scroll to **Default project deletion protection**, and select **Only admins can delete project**.
1. Select **Save changes**.
## Default delayed project deletion **(PREMIUM SELF)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/255449) in GitLab 14.2.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/255449) in GitLab 14.2 for groups created after August 12, 2021.
-Projects in a group (but not a personal namespace) can be deleted after a delayed period, by
-[configuring in Group Settings](../../group/index.md#enable-delayed-project-removal).
+Projects in a group (but not a personal namespace) can be deleted after a delayed period.
+You can [configure it in group settings](../../group/index.md#enable-delayed-project-removal).
To enable delayed project deletion by default in new groups:
1. Check the **Default delayed project deletion** checkbox.
-1. Click **Save changes**.
+1. Select **Save changes**.
## Default deletion delay **(PREMIUM SELF)**
@@ -142,8 +142,8 @@ Alternatively, projects that are marked for removal can be deleted immediately.
To set the default [visibility levels for new projects](../../../public_access/public_access.md):
1. Sign in to GitLab as a user with [Administrator role](../../permissions.md).
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Visibility and access controls** section.
1. Select the desired default project visibility:
- **Private** - Project access must be granted explicitly to each user. If this
@@ -157,8 +157,8 @@ To set the default [visibility levels for new projects](../../../public_access/p
To set the default visibility levels for new [snippets](../../snippets.md):
1. Sign in to GitLab as a user with [Administrator role](../../permissions.md).
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Visibility and access controls** section.
1. Select the desired default snippet visibility.
1. Select **Save changes**.
@@ -171,8 +171,8 @@ For more details on snippet visibility, read
To set the default visibility levels for new groups:
1. Sign in to GitLab as a user with [Administrator role](../../permissions.md).
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Visibility and access controls** section.
1. Select the desired default group visibility:
- **Private** - The group and its projects can only be viewed by members.
@@ -188,8 +188,8 @@ For more details on group visibility, see
To restrict visibility levels for projects, snippets, and selected pages:
1. Sign in to GitLab as a user with [Administrator role](../../permissions.md).
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Visibility and access controls** section.
1. In the **Restricted visibility levels** section, select the desired visibility levels to restrict.
1. Select **Save changes**.
@@ -202,8 +202,8 @@ For more details on project visibility, see
You can specify from which hosting sites users can [import their projects](../../project/import/index.md):
1. Sign in to GitLab as a user with [Administrator role](../../permissions.md).
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Visibility and access controls** section.
1. Select each of **Import sources** to allow.
1. Select **Save changes**.
@@ -214,8 +214,8 @@ To enable the export of
[projects and their data](../../../user/project/settings/import_export.md#export-a-project-and-its-data):
1. Sign in to GitLab as a user with [Administrator role](../../permissions.md).
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Visibility and access controls** section.
1. Select **Project export enabled**.
1. Select **Save changes**.
@@ -230,8 +230,8 @@ The GitLab restrictions apply at the application level.
To specify the enabled Git access protocols:
1. Sign in to GitLab as a user with [Administrator role](../../permissions.md).
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Visibility and access controls** section.
1. Select the desired Git access protocols:
- Both SSH and HTTP(S)
diff --git a/doc/user/admin_area/user_cohorts.md b/doc/user/admin_area/user_cohorts.md
index e96ce969b3a..89026e56a27 100644
--- a/doc/user/admin_area/user_cohorts.md
+++ b/doc/user/admin_area/user_cohorts.md
@@ -10,8 +10,8 @@ You can analyze your users' GitLab activities over time.
To view user cohorts:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Overview > Users**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Overview > Users**.
1. Select the **Cohorts** tab.
## Overview
diff --git a/doc/user/analytics/index.md b/doc/user/analytics/index.md
index 7cb5db4379a..5b7e6e39187 100644
--- a/doc/user/analytics/index.md
+++ b/doc/user/analytics/index.md
@@ -75,12 +75,12 @@ in one place.
[Learn more about instance-level analytics](../admin_area/analytics/index.md).
-## Group-level analytics **(PREMIUM)**
+## Group-level analytics
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/195979) in GitLab 12.8.
> - Moved to GitLab Premium in 13.9.
-The following analytics features are available at the group level:
+GitLab provides several analytics features at the group level. Some of these features require you to use a higher tier than GitLab Free.
- [Application Security](../application_security/security_dashboard/#group-security-dashboard)
- [Contribution](../group/contribution_analytics/index.md)
@@ -93,7 +93,7 @@ The following analytics features are available at the group level:
## Project-level analytics
-The following analytics features are available at the project level:
+You can use GitLab to review analytics at the project level. Some of these features require you to use a higher tier than GitLab Free.
- [Application Security](../application_security/security_dashboard/#project-security-dashboard)
- [CI/CD](ci_cd_analytics.md)
@@ -105,8 +105,10 @@ The following analytics features are available at the project level:
- [Repository](repository_analytics.md)
- [Value Stream](value_stream_analytics.md)
-## User-configurable analytics **(ULTIMATE)**
+## User-configurable analytics
The following analytics features are available for users to create personalized views:
- [Application Security](../application_security/security_dashboard/#security-center)
+
+Be sure to review the documentation page for this feature for GitLab tier requirements.
diff --git a/doc/user/analytics/issue_analytics.md b/doc/user/analytics/issue_analytics.md
index b77a25a9d62..44b8c87ee27 100644
--- a/doc/user/analytics/issue_analytics.md
+++ b/doc/user/analytics/issue_analytics.md
@@ -7,13 +7,16 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Issue Analytics **(PREMIUM)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196561) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196561) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.9.
Issue Analytics is a bar graph which illustrates the number of issues created each month.
The default time span is 13 months, which includes the current month, and the 12 months
prior.
-To access the chart, navigate to your project sidebar and select **Analytics > Issue**.
+To access the chart:
+
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Analytics > Issue**.
Hover over each bar to see the total number of issues.
diff --git a/doc/user/analytics/merge_request_analytics.md b/doc/user/analytics/merge_request_analytics.md
index 321e2f0fc24..44e4cd8b371 100644
--- a/doc/user/analytics/merge_request_analytics.md
+++ b/doc/user/analytics/merge_request_analytics.md
@@ -20,7 +20,10 @@ The Throughput chart shows the number of merge requests merged, by month. Merge
a common measure of productivity in software engineering. Although imperfect, the average throughput can
be a meaningful benchmark of your team's overall productivity.
-To access Merge Request Analytics, from your project's menu, go to **Analytics > Merge Request**.
+To access Merge Request Analytics:
+
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Analytics > Merge request**.
## Use cases
@@ -93,10 +96,10 @@ You can filter the data that is presented on the page based on the following par
To filter results:
-1. Click on the filter bar.
+1. Select the filter bar.
1. Select a parameter to filter by.
1. Select a value from the autocompleted results, or enter search text to refine the results.
-1. Hit the "Return" key.
+1. Press Enter.
## Date range
diff --git a/doc/user/analytics/productivity_analytics.md b/doc/user/analytics/productivity_analytics.md
index a06d94caf69..391ec5c04d9 100644
--- a/doc/user/analytics/productivity_analytics.md
+++ b/doc/user/analytics/productivity_analytics.md
@@ -50,11 +50,11 @@ The following metrics and visualizations are available on a project or group lev
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13188) in GitLab 12.4.
-GitLab has the ability to filter analytics based on a date range. To filter results:
+You can filter analytics based on a date range. To filter results:
1. Select a group.
-1. Optionally select a project.
-1. Select a date range using the available date pickers.
+1. Optional. Select a project.
+1. Select a date range by using the available date pickers.
## Permissions
diff --git a/doc/user/analytics/value_stream_analytics.md b/doc/user/analytics/value_stream_analytics.md
index 9a1aed9c39f..7057d069e95 100644
--- a/doc/user/analytics/value_stream_analytics.md
+++ b/doc/user/analytics/value_stream_analytics.md
@@ -64,7 +64,7 @@ Items aren't included in the stage time calculation if they have not reached the
| Stage | Description |
|---------|---------------|
-| Issue | Measures the median time between creating an issue and taking action to solve it, by either labeling it or adding it to a milestone, whichever comes first. The label is tracked only if it already includes an [Issue Board list](../project/issue_board.md) created for it. |
+| Issue | Measures the median time between creating an issue and taking action to solve it, by either labeling it or adding it to a milestone, whichever comes first. The label is tracked only if it already includes an [issue board list](../project/issue_board.md) created for it. |
| Plan | Measures the median time between the action you took for the previous stage, and pushing the first commit to the branch. That first branch commit triggers the separation between **Plan** and **Code**, and at least one of the commits in the branch must include the related issue number (such as `#42`). If the issue number is *not* included in a commit, that data is not included in the measurement time of the stage. |
| Code | Measures the median time between pushing a first commit (previous stage) and creating a merge request (MR). The process is tracked with the [issue closing pattern](../project/issues/managing_issues.md#closing-issues-automatically) in the description of the merge request. For example, if the issue is closed with `Closes #xxx`, it's assumed that `xxx` is issue number for the merge request). If there is no closing pattern, the start time is set to the create time of the first commit. |
| Test | Essentially the start to finish time for all pipelines. Measures the median time to run the entire pipeline for that project. Related to the time required by GitLab CI/CD to run every job for the commits pushed to that merge request, as defined in the previous stage. |
@@ -85,7 +85,7 @@ How this works:
In short, the Value Stream Analytics dashboard tracks data related to [GitLab flow](../../topics/gitlab_flow.md). It does not include data for:
- Merge requests that do not close an issue.
-- Issues that do not include labels present in the Issue Board
+- Issues that do not include labels present in the issue board.
- Issues without a milestone.
- Staging stages, in projects without a [production environment](#how-the-production-environment-is-identified).
diff --git a/doc/user/application_security/api_fuzzing/index.md b/doc/user/application_security/api_fuzzing/index.md
index 7ed36572be4..e32989c2915 100644
--- a/doc/user/application_security/api_fuzzing/index.md
+++ b/doc/user/application_security/api_fuzzing/index.md
@@ -85,7 +85,7 @@ In GitLab 14.0 and later, API fuzzing configuration files must be in your reposi
### Web API fuzzing configuration form
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/299234) in GitLab 13.10.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/299234) in GitLab 13.10.
WARNING:
This feature might not be available to you. Check the **version history** note above for details.
@@ -98,17 +98,16 @@ a YAML snippet that you can paste in your GitLab CI/CD configuration.
To generate an API Fuzzing configuration snippet:
-1. From your project's home page, go to **Security & Compliance > Configuration** in the left
- sidebar.
-1. Select **Configure** in the **API Fuzzing** row.
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Security & Compliance > Configuration**.
+1. In the **API Fuzzing** row, select **Configure**.
1. Complete the form as needed. Read below for more information on available configuration options.
1. Select **Generate code snippet**.
A modal opens with the YAML snippet corresponding to the options you've selected in the form.
1. Choose one of the following actions:
- 1. Select **Copy code and open `.gitlab-ci.yml` file** to copy the snippet to your clipboard and
- be redirected to your project's `.gitlab-ci.yml` file where you can paste the YAML
- configuration.
- 1. Select **Copy code only** to copy the snippet to your clipboard and close the modal.
+ 1. To copy the snippet to your clipboard and be redirected to your project's `.gitlab-ci.yml` file,
+ where you can paste the YAML configuration, select **Copy code and open `.gitlab-ci.yml` file**.
+ 1. To copy the snippet to your clipboard and close the modal, select **Copy code only**.
### OpenAPI Specification
@@ -995,7 +994,7 @@ Follow these steps to view details of a fuzzing fault:
**API Fuzzing detected N potential vulnerabilities**. Click the title to display the fault
details.
-1. Click the fault's title to display the fault's details. The table below describes these details.
+1. Select the fault's title to display the fault's details. The table below describes these details.
| Field | Description |
|:--------------------|:----------------------------------------------------------------------------------------|
diff --git a/doc/user/application_security/configuration/index.md b/doc/user/application_security/configuration/index.md
index 664fcd9b72f..98e241ba3bd 100644
--- a/doc/user/application_security/configuration/index.md
+++ b/doc/user/application_security/configuration/index.md
@@ -13,61 +13,56 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - A simplified version was made [available in all tiers](https://gitlab.com/gitlab-org/gitlab/-/issues/294076) in GitLab 13.10.
> - [Redesigned](https://gitlab.com/gitlab-org/gitlab/-/issues/326926) in 14.2.
-The Security Configuration page displays what security scans are available, links to documentation and also simple enablement tools for the current project.
+The Security Configuration page lists the following for the security testing and compliance tools:
-To view a project's security configuration, go to the project's home page,
-then in the left sidebar go to **Security & Compliance > Configuration**.
-
-For each security control the page displays:
-
-- Its name, description and a documentation link.
+- Name, description, and a documentation link.
- Whether or not it is available.
- A configuration button or a link to its configuration guide.
+The status of each security control is determined by the project's latest default branch
+[CI pipeline](../../../ci/pipelines/index.md).
+If a job with the expected security report artifact exists in the pipeline, the feature's status is
+_enabled_.
+
+If the latest pipeline used [Auto DevOps](../../../topics/autodevops/index.md),
+all security features are configured by default.
+
+To view a project's security configuration:
+
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Security & Compliance > Configuration**.
+
+Select **Configuration history** to see the `.gitlab-ci.yml` file's history.
+
## Security testing
You can configure the following security controls:
-- Auto DevOps
- - Click **Enable Auto DevOps** on the alert to enable it for the current project. For more details, see [Auto DevOps](../../../topics/autodevops/index.md).
-- SAST
- - Click **Enable SAST** to use SAST for the current project. For more details, see [Configure SAST in the UI](../sast/index.md#configure-sast-in-the-ui).
-- DAST **(ULTIMATE)**
- - Click **Enable DAST** to use DAST for the current Project. To manage the available DAST profiles used for on-demand scans Click **Manage Scans**. For more details, see [DAST on-demand scans](../dast/index.md#on-demand-scans).
+- Static Application Security Testing (SAST)
+ - Select **Enable SAST** to configure SAST for the current project.
+ For more details, read [Configure SAST in the UI](../sast/index.md#configure-sast-in-the-ui).
+- Dynamic Application Security Testing (DAST) **(ULTIMATE)**
+ - Select **Enable DAST** to configure DAST for the current project.
+ - Select **Manage scans** to manage the saved DAST scans, site profiles, and scanner profiles.
+ For more details, read [DAST on-demand scans](../dast/index.md#on-demand-scans).
- Dependency Scanning **(ULTIMATE)**
- Select **Configure via Merge Request** to create a merge request with the changes required to
enable Dependency Scanning. For more details, see [Enable Dependency Scanning via an automatic merge request](../dependency_scanning/index.md#enable-dependency-scanning-via-an-automatic-merge-request).
-
- Container Scanning **(ULTIMATE)**
- - Can be configured via `.gitlab-ci.yml`. For more details, see [Container Scanning](../../../user/application_security/container_scanning/index.md#configuration).
+ - Can be configured with `.gitlab-ci.yml`. For more details, read [Container Scanning](../../../user/application_security/container_scanning/index.md#configuration).
- Cluster Image Scanning **(ULTIMATE)**
- - Can be configured via `.gitlab-ci.yml`. For more details, see [Cluster Image Scanning](../../../user/application_security/cluster_image_scanning/#configuration).
+ - Can be configured with `.gitlab-ci.yml`. For more details, read [Cluster Image Scanning](../../../user/application_security/cluster_image_scanning/#configuration).
- Secret Detection
- Select **Configure via Merge Request** to create a merge request with the changes required to
- enable Secret Detection. For more details, see [Enable Secret Detection via an automatic merge request](../secret_detection/index.md#enable-secret-detection-via-an-automatic-merge-request).
-
+ enable Secret Detection. For more details, read [Enable Secret Detection via an automatic merge request](../secret_detection/index.md#enable-secret-detection-via-an-automatic-merge-request).
- API Fuzzing **(ULTIMATE)**
- - Click **Enable API Fuzzing** to use API Fuzzing for the current Project. For more details, see [API Fuzzing](../../../user/application_security/api_fuzzing/index.md#enable-web-api-fuzzing).
+ - Select **Enable API Fuzzing** to use API Fuzzing for the current project. For more details, read [API Fuzzing](../../../user/application_security/api_fuzzing/index.md#enable-web-api-fuzzing).
- Coverage Fuzzing **(ULTIMATE)**
- - Can be configured via `.gitlab-ci.yml`. For more details, see [Coverage Fuzzing](../../../user/application_security/coverage_fuzzing/index.md#configuration).
-
-## Status **(ULTIMATE)**
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20711) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.6.
-
-The status of each security control is determined by the project's latest default branch
-[CI pipeline](../../../ci/pipelines/index.md).
-If a job with the expected security report artifact exists in the pipeline, the feature's status is
-_enabled_.
-
-If the latest pipeline used [Auto DevOps](../../../topics/autodevops/index.md),
-all security features are configured by default.
-
-Click **View history** to see the `.gitlab-ci.yml` file's history.
+ - Can be configured with `.gitlab-ci.yml`. For more details, read [Coverage Fuzzing](../../../user/application_security/coverage_fuzzing/index.md#configuration).
## Compliance **(ULTIMATE)**
You can configure the following security controls:
- License Compliance **(ULTIMATE)**
- - Can be configured via `.gitlab-ci.yml`. For more details, see [License Compliance](../../../user/compliance/license_compliance/index.md#configuration).
+ - Can be configured with `.gitlab-ci.yml`. For more details, read [License Compliance](../../../user/compliance/license_compliance/index.md#configuration).
diff --git a/doc/user/application_security/container_scanning/index.md b/doc/user/application_security/container_scanning/index.md
index 5791351a067..2b3d4dbfc0a 100644
--- a/doc/user/application_security/container_scanning/index.md
+++ b/doc/user/application_security/container_scanning/index.md
@@ -9,14 +9,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/3672) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.4.
-WARNING:
-Versions of GitLab prior to 14.0 used Clair as the default container scanning engine. GitLab 14.0
-removes Clair from the product and replaces it with two new scanners. If you
-run container scanning with the default settings, GitLab switches you seamlessly and automatically
-to Trivy in GitLab 14.0. However, if you customized the variables in your container scanning job,
-you should review the [migration guide](#change-scanners)
-and make any necessary updates.
-
Your application's Docker image may itself be based on Docker images that contain known
vulnerabilities. By including an extra job in your pipeline that scans for those vulnerabilities and
displays them in a merge request, you can use GitLab to audit your Docker-based apps.
@@ -57,37 +49,9 @@ To enable container scanning in your pipeline, you need the following:
## Configuration
-How you enable container scanning depends on your GitLab version:
-
-- GitLab 11.9 and later: [Include](../../../ci/yaml/index.md#includetemplate) the
- [`Container-Scanning.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml)
- that comes with your GitLab installation.
-- GitLab versions earlier than 11.9: Copy and use the job from the
- [`Container-Scanning.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml).
-
-Other changes:
-
-- GitLab 13.6 [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/263482) better support for
- [FIPS](https://csrc.nist.gov/publications/detail/fips/140/2/final) by upgrading the
- `CS_MAJOR_VERSION` from `2` to `3`. Version `3` of the `container_scanning` Docker image uses
- [`centos:centos8`](https://hub.docker.com/_/centos)
- as the new base. It also removes the use of the [start.sh](https://gitlab.com/gitlab-org/security-products/analyzers/klar/-/merge_requests/77)
- script and instead executes the analyzer by default. Any customizations made to the
- `container_scanning` job's [`before_script`](../../../ci/yaml/index.md#before_script)
- and [`after_script`](../../../ci/yaml/index.md#after_script)
- blocks may not work with the new version. To roll back to the previous [`alpine:3.11.3`](https://hub.docker.com/_/alpine)-based
- Docker image, you can specify the major version through the [`CS_MAJOR_VERSION`](#available-cicd-variables)
- variable.
-- GitLab 13.9 [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/322656) integration with
- [Trivy](https://github.com/aquasecurity/trivy) by upgrading `CS_MAJOR_VERSION` from `3` to `4`.
-- GitLab 14.0 [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61850)
- an integration with [Trivy](https://github.com/aquasecurity/trivy)
- as the default for container scanning, and also [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/326279)
- an integration with [Grype](https://github.com/anchore/grype)
- as an alternative scanner.
-
-To include the `Container-Scanning.gitlab-ci.yml` template (GitLab 11.9 and later), add the
-following to your `.gitlab-ci.yml` file:
+To enable container scanning, add the
+[`Container-Scanning.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml)
+to your `.gitlab-ci.yml` file:
```yaml
include:
@@ -157,7 +121,7 @@ You can [configure](#customizing-the-container-scanning-settings) analyzers by u
| `CI_APPLICATION_TAG` | `$CI_COMMIT_SHA` | Docker repository tag for the image to be scanned. | All |
| `CS_ANALYZER_IMAGE` | `registry.gitlab.com/security-products/container-scanning:4` | Docker image of the analyzer. | All |
| `CS_DOCKER_INSECURE` | `"false"` | Allow access to secure Docker registries using HTTPS without validating the certificates. | All |
-| `CS_REGISTRY_INSECURE` | `"false"` | Allow access to insecure registries (HTTP only). Should only be set to `true` when testing the image locally. | Trivy. The registry must listen on port `80/tcp`. |
+| `CS_REGISTRY_INSECURE` | `"false"` | Allow access to insecure registries (HTTP only). Should only be set to `true` when testing the image locally. Works with all scanners, but the registry must listen on port `80/tcp` for Trivy to work. | All |
| `CS_SEVERITY_THRESHOLD` | `UNKNOWN` | Severity level threshold. The scanner outputs vulnerabilities with severity level higher than or equal to this threshold. Supported levels are Unknown, Low, Medium, High, and Critical. | Trivy |
| `DOCKER_IMAGE` | `$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG` | The Docker image to be scanned. If set, this variable overrides the `$CI_APPLICATION_REPOSITORY` and `$CI_APPLICATION_TAG` variables. | All |
| `DOCKER_PASSWORD` | `$CI_REGISTRY_PASSWORD` | Password for accessing a Docker registry requiring authentication. The default is only set if `$DOCKER_IMAGE` resides at [`$CI_REGISTRY`](../../../ci/variables/predefined_variables.md). | All |
@@ -625,3 +589,29 @@ To prevent the error, ensure the Docker version that the runner is using is
### Getting warning message `gl-container-scanning-report.json: no matching files`
For information on this, see the [general Application Security troubleshooting section](../../../ci/pipelines/job_artifacts.md#error-message-no-files-to-upload).
+
+## Changes
+
+- GitLab 13.6 [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/263482) better support for
+ [FIPS](https://csrc.nist.gov/publications/detail/fips/140/2/final) by upgrading the
+ `CS_MAJOR_VERSION` from `2` to `3`. Version `3` of the `container_scanning` Docker image uses
+ [`centos:centos8`](https://hub.docker.com/_/centos)
+ as the new base. It also removes the use of the [start.sh](https://gitlab.com/gitlab-org/security-products/analyzers/klar/-/merge_requests/77)
+ script and instead executes the analyzer by default. Any customizations made to the
+ `container_scanning` job's [`before_script`](../../../ci/yaml/index.md#before_script)
+ and [`after_script`](../../../ci/yaml/index.md#after_script)
+ blocks may not work with the new version. To roll back to the previous [`alpine:3.11.3`](https://hub.docker.com/_/alpine)-based
+ Docker image, you can specify the major version through the [`CS_MAJOR_VERSION`](#available-cicd-variables)
+ variable.
+- GitLab 13.9 [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/322656) integration with
+ [Trivy](https://github.com/aquasecurity/trivy) by upgrading `CS_MAJOR_VERSION` from `3` to `4`.
+- GitLab 13.9 [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/321451) the integration with
+ [Clair](https://github.com/quay/clair/).
+- GitLab 14.0 [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61850)
+ an integration with [Trivy](https://github.com/aquasecurity/trivy)
+ as the default for container scanning, and also [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/326279)
+ an integration with [Grype](https://github.com/anchore/grype)
+ as an alternative scanner.
+
+Other changes to the container scanning analyzer can be found in the project's
+[changelog](https://gitlab.com/gitlab-org/security-products/analyzers/container-scanning/-/blob/master/CHANGELOG.md).
diff --git a/doc/user/application_security/coverage_fuzzing/index.md b/doc/user/application_security/coverage_fuzzing/index.md
index 679d20a6394..0d5eb2b6d50 100644
--- a/doc/user/application_security/coverage_fuzzing/index.md
+++ b/doc/user/application_security/coverage_fuzzing/index.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference, howto
---
-# Coverage Guided Fuzz Testing **(ULTIMATE)**
+# Coverage-guided fuzz testing **(ULTIMATE)**
GitLab allows you to add coverage-guided fuzz testing to your pipelines. This helps you discover
bugs and potential security issues that other QA processes may miss. Coverage-guided fuzzing sends
@@ -82,7 +82,7 @@ The `my_fuzz_target` job (the separate job for your fuzz target) does the follow
- Runs on a fuzz stage that usually comes after a test stage.
The `gitlab-cov-fuzz` is a command-line tool that runs the instrumented application. It parses and
-analyzes the exception information that the fuzzer outputs. It also downloads the [corpus](#glossary)
+analyzes the exception information that the fuzzer outputs. It also downloads the [corpus](../terminology/index.md#corpus)
and crash events from previous pipelines automatically. This helps your fuzz targets build on the
progress of previous fuzzing jobs. The parsed crash events and data are written to
`gl-coverage-fuzzing-report.json`.
@@ -97,7 +97,7 @@ Each fuzzing step outputs these artifacts:
- `crashes`: Holds all crash events the current job encountered as well as those not fixed in
previous jobs.
-### Types of Fuzzing Jobs
+### Types of fuzzing jobs
There are two types of jobs:
@@ -127,7 +127,7 @@ any option available in the underlying fuzzing engine.
| `COVFUZZ_SEED_CORPUS` | Path to a seed corpus directory. The default is empty. |
| `COVFUZZ_URL_PREFIX` | Path to the `gitlab-cov-fuzz` repository cloned for use with an offline environment. You should only change this when using an offline environment. The default value is `https://gitlab.com/gitlab-org/security-products/analyzers/gitlab-cov-fuzz/-/raw`. |
-The files in the seed corpus (`COVFUZZ_SEED_CORPUS`), if provided, aren't updated unless you commit new
+The files in the [seed corpus](../terminology/index.md#seed-corpus) (`COVFUZZ_SEED_CORPUS`), if provided, aren't updated unless you commit new
files to your Git repository. There's usually no need to frequently update the seed corpus. As part
of the GitLab artifacts system, GitLab saves in a corpus directory the new test cases that every run
generates. In any subsequent runs, GitLab also reuses the generated corpus together with the seed
@@ -172,13 +172,13 @@ Here's an example coverage fuzzing report:
}
```
-### Additional Configuration
+### Additional configuration
The `gitlab-cov-fuzz` command passes all arguments it receives to the underlying fuzzing engine. You
can therefore use all the options available in that fuzzing engine. For more information on these
options, see the underlying fuzzing engine's documentation.
-### Offline Environment
+### Offline environment
To use coverage fuzzing in an offline environment, follow these steps:
@@ -262,12 +262,3 @@ vulnerability:
- Scanner: The scanner that detected the vulnerability (for example, Coverage Fuzzing).
- Scanner Provider: The engine that did the scan. For Coverage Fuzzing, this can be any of the
engines listed in [Supported fuzzing engines and languages](#supported-fuzzing-engines-and-languages).
-
-### Glossary
-
-- Seed corpus: The set of test cases given as initial input to the fuzz target. This usually speeds
- up the fuzz target substantially. This can be either manually created test cases or auto-generated
- with the fuzz target itself from previous runs.
-- Corpus: The set of meaningful test cases that are generated while the fuzzer is running. Each
- meaningful test case produces new coverage in the tested program. It's advised to re-use the
- corpus and pass it to subsequent runs.
diff --git a/doc/user/application_security/dast/browser_based.md b/doc/user/application_security/dast/browser_based.md
index e8fbc17327c..5094ccd2196 100644
--- a/doc/user/application_security/dast/browser_based.md
+++ b/doc/user/application_security/dast/browser_based.md
@@ -19,7 +19,7 @@ The browser-based crawler works by loading the target application into a special
such as clicking on a link or filling in a form. For each action found, the crawler will execute it, take a new snapshot and determine what in the page changed from the previous snapshot.
Crawling continues by taking more snapshots and finding subsequent actions.
-The benefit of crawling by following user actions in a browser is that the crawler can interact with the target application much like a real user would, identifying complex flows that traditional web crawlers don’t understand. This results in better coverage of the website.
+The benefit of crawling by following user actions in a browser is that the crawler can interact with the target application much like a real user would, identifying complex flows that traditional web crawlers don't understand. This results in better coverage of the website.
Using the browser-based crawler should provide greater coverage for most web applications, compared with the current DAST AJAX crawler. The new crawler replaces the AJAX crawler and is specifically designed to maximize crawl coverage in modern web applications. While both crawlers are currently used in conjunction with the existing DAST scanner, the combination of the browser-based crawler with the current DAST scanner is much more effective at finding and testing every page in an application.
diff --git a/doc/user/application_security/dast/dast_troubleshooting.md b/doc/user/application_security/dast/dast_troubleshooting.md
index 725fab85789..f771bc82d58 100644
--- a/doc/user/application_security/dast/dast_troubleshooting.md
+++ b/doc/user/application_security/dast/dast_troubleshooting.md
@@ -88,3 +88,7 @@ stages:
include:
- template: DAST.latest.gitlab-ci.yml
```
+
+## Lack of IPv6 support
+
+Due to the underlying [ZAProxy engine not supporting IPv6](https://github.com/zaproxy/zaproxy/issues/3705), DAST is unable to scan or crawl IPv6-based applications.
diff --git a/doc/user/application_security/dast/index.md b/doc/user/application_security/dast/index.md
index 7455915761c..0d60701b030 100644
--- a/doc/user/application_security/dast/index.md
+++ b/doc/user/application_security/dast/index.md
@@ -74,7 +74,7 @@ If your application utilizes Docker containers you have another option for deplo
After your Docker build job completes and your image is added to your container registry, you can use the image as a
[service](../../../ci/services/index.md).
-By using service definitions in your `gitlab-ci.yml`, you can scan services with the DAST analyzer.
+By using service definitions in your `.gitlab-ci.yml`, you can scan services with the DAST analyzer.
```yaml
stages:
@@ -328,6 +328,8 @@ Vulnerability rules in an API scan are different than those in a normal website
A new DAST API scanning engine is available in GitLab 13.12 and later. For more details, see [DAST API scanning engine](../dast_api). The new scanning engine supports REST, SOAP, GraphQL, and generic APIs using forms, XML, and JSON. Testing can be performed using OpenAPI, Postman Collections, and HTTP Archive (HAR) documents.
+The target API instance’s base URL is provided by using the `DAST_API_TARGET_URL` variable or an `environment_url.txt` file.
+
#### Specification format
API scans support OpenAPI V2 and OpenAPI V3 specifications. You can define these specifications using `JSON` or `YAML`.
@@ -339,7 +341,7 @@ The specification does not have to be hosted on the same host as the API being t
```yaml
include:
- - template: DAST.gitlab-ci.yml
+ - template: DAST-API.gitlab-ci.yml
variables:
DAST_API_OPENAPI: http://my.api/api-specification.yml
@@ -390,7 +392,7 @@ the following DAST configuration can be used:
```yaml
include:
- - template: DAST.gitlab-ci.yml
+ - template: DAST-API.gitlab-ci.yml
variables:
DAST_API_OPENAPI: http://api-test.host.com/api-specification.yml
@@ -405,7 +407,7 @@ Headers are applied to every request DAST makes.
```yaml
include:
- - template: DAST.gitlab-ci.yml
+ - template: DAST-API.gitlab-ci.yml
variables:
DAST_API_OPENAPI: http://api-test.api.com/api-specification.yml
@@ -554,6 +556,9 @@ By default, several rules are disabled because they either take a long time to
run or frequently generate false positives. The complete list of disabled rules
can be found in [exclude_rules.yml](https://gitlab.com/gitlab-org/security-products/dast/-/blob/main/src/config/exclude_rules.yml).
+The lists for `DAST_EXCLUDE_RULES` and `DAST_ONLY_INCLUDE_RULES` **must** be enclosed in double
+quotes (`"`), otherwise they are interpreted as numeric values.
+
### Hide sensitive information
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/36332) in GitLab 13.1.
@@ -742,7 +747,7 @@ dast:
when: always
```
-### Available CI/CD variables
+## Available CI/CD variables
These CI/CD variables are specific to DAST. They can be used to customize the behavior of DAST to your requirements.
@@ -762,7 +767,7 @@ These CI/CD variables are specific to DAST. They can be used to customize the be
| `DAST_AUTO_UPDATE_ADDONS` | boolean | ZAP add-ons are pinned to specific versions in the DAST Docker image. Set to `true` to download the latest versions when the scan starts. Default: `false`. |
| `DAST_BROWSER_PATH_TO_LOGIN_FORM` <sup>1,2</sup> | selector | Comma-separated list of selectors that will be clicked on prior to attempting to enter `DAST_USERNAME` and `DAST_PASSWORD` into the login form. Example: `"css:.navigation-menu,css:.login-menu-item"`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/326633) in GitLab 14.1. |
| `DAST_DEBUG` <sup>1</sup> | boolean | Enable debug message output. Default: `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12652) in GitLab 13.1. |
-| `DAST_EXCLUDE_RULES` | string | Set to a comma-separated list of Vulnerability Rule IDs to exclude them from running during the scan. Rule IDs are numbers and can be found from the DAST log or on the [ZAP project](https://www.zaproxy.org/docs/alerts/). For example, `HTTP Parameter Override` has a rule ID of `10026`. Cannot be used when `DAST_ONLY_INCLUDE_RULES` is set. **Note:** In earlier versions of GitLab the excluded rules were executed but vulnerabilities they generated were suppressed. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118641) in GitLab 12.10. |
+| `DAST_EXCLUDE_RULES` | string | Set to a comma-separated list of Vulnerability Rule IDs to exclude them from running during the scan. The whole list **must** be enclosed in double quotes (`"`). Rule IDs are numbers and can be found from the DAST log or on the [ZAP project](https://www.zaproxy.org/docs/alerts/). For example, `HTTP Parameter Override` has a rule ID of `10026`. Cannot be used when `DAST_ONLY_INCLUDE_RULES` is set. **Note:** In earlier versions of GitLab the excluded rules were executed but vulnerabilities they generated were suppressed. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118641) in GitLab 12.10. |
| `DAST_EXCLUDE_URLS` <sup>1,2</sup> | URLs | The URLs to skip during the authenticated scan; comma-separated. Regular expression syntax can be used to match multiple URLs. For example, `.*` matches an arbitrary character sequence. Not supported for API scans. Example, `http://example.com/sign-out`. |
| `DAST_FIRST_SUBMIT_FIELD` <sup>2</sup> | string | The `id` or `name` of the element that when clicked submits the username form of a multi-page login process. For example, `css:button[type='user-submit']`. [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/9894) in GitLab 12.4. |
| `DAST_FULL_SCAN_DOMAIN_VALIDATION_REQUIRED` | boolean | **{warning}** **[Removed](https://gitlab.com/gitlab-org/gitlab/-/issues/293595)** in GitLab 14.0. Set to `true` to require domain validation when running DAST full scans. Not supported for API scans. Default: `false` |
@@ -772,7 +777,7 @@ These CI/CD variables are specific to DAST. They can be used to customize the be
| `DAST_MARKDOWN_REPORT` | string | The filename of the Markdown report written at the end of a scan. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12652) in GitLab 13.1. |
| `DAST_MASK_HTTP_HEADERS` | string | Comma-separated list of request and response headers to be masked (GitLab 13.1). Must contain **all** headers to be masked. Refer to [list of headers that are masked by default](#hide-sensitive-information). |
| `DAST_MAX_URLS_PER_VULNERABILITY` | number | The maximum number of URLs reported for a single vulnerability. `DAST_MAX_URLS_PER_VULNERABILITY` is set to `50` by default. To list all the URLs set to `0`. [Introduced](https://gitlab.com/gitlab-org/security-products/dast/-/merge_requests/433) in GitLab 13.12. |
-| `DAST_ONLY_INCLUDE_RULES` | string | Set to a comma-separated list of Vulnerability Rule IDs to configure the scan to run only them. Rule IDs are numbers and can be found from the DAST log or on the [ZAP project](https://www.zaproxy.org/docs/alerts/). Cannot be used when `DAST_EXCLUDE_RULES` is set. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/250651) in GitLab 13.12. |
+| `DAST_ONLY_INCLUDE_RULES` | string | Set to a comma-separated list of Vulnerability Rule IDs to configure the scan to run only them. The whole list **must** be enclosed in double quotes (`"`). Rule IDs are numbers and can be found from the DAST log or on the [ZAP project](https://www.zaproxy.org/docs/alerts/). Cannot be used when `DAST_EXCLUDE_RULES` is set. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/250651) in GitLab 13.12. |
| `DAST_PASSWORD` <sup>1,2</sup> | string | The password to authenticate to in the website. Example: `P@55w0rd!` |
| `DAST_PASSWORD_FIELD` <sup>1,2</sup> | string | The selector of password field at the sign-in HTML form. Example: `id:password` |
| `DAST_PATHS` | string | Set to a comma-separated list of URLs for DAST to scan. For example, `/page1.html,/category1/page3.html,/page2.html`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214120) in GitLab 13.4. |
@@ -795,7 +800,7 @@ These CI/CD variables are specific to DAST. They can be used to customize the be
1. Available to an on-demand DAST scan.
1. Used for authentication.
-#### Selectors
+### Selectors
Selectors are used by CI/CD variables to specify the location of an element displayed on a page in a browser.
Selectors have the format `type`:`search string`. The crawler will search for the selector using the search string based on the type.
@@ -808,7 +813,7 @@ Selectors have the format `type`:`search string`. The crawler will search for th
| `xpath` | `xpath://input[@id="my-button"]/a` | Searches for a HTML element with the provided XPath. Note that XPath searches are expected to be less performant than other searches. |
| None provided | `a.click-me` | Defaults to searching using a CSS selector. |
-##### Find selectors with Google Chrome
+#### Find selectors with Google Chrome
Chrome DevTools element selector tool is an effective way to find a selector.
@@ -824,7 +829,7 @@ Chrome DevTools element selector tool is an effective way to find a selector.
In this example, the `id="user_login"` appears to be a good candidate. You can use this as a selector as the DAST username field by setting
`DAST_USERNAME_FIELD: "id:user_login"`.
-##### Choose the right selector
+#### Choose the right selector
Judicious choice of selector leads to a scan that is resilient to the application changing.
@@ -919,7 +924,7 @@ The DAST job does not require the project's repository to be present when runnin
> - Auditing for DAST profile management was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217872) in GitLab 14.1.
An on-demand DAST scan runs outside the DevOps life cycle. Changes in your repository don't trigger
-the scan. You must start it manually.
+the scan. You must either start it manually, or schedule it to run.
An on-demand DAST scan:
@@ -928,8 +933,6 @@ An on-demand DAST scan:
- Is associated with your project's default branch.
- Is saved on creation so it can be run later.
-In GitLab 13.10 and later, you can select to run an on-demand scan against a specific branch.
-
### On-demand scan modes
An on-demand scan can be run in active or passive mode:
@@ -941,23 +944,34 @@ An on-demand scan can be run in active or passive mode:
### Run an on-demand DAST scan
-NOTE:
-You must have permission to run an on-demand DAST scan against a protected branch.
-The default branch is automatically protected. For more information, see
-[Pipeline security on protected branches](../../../ci/pipelines/index.md#pipeline-security-on-protected-branches).
-
Prerequisites:
+- You must have permission to run an on-demand DAST scan against a protected branch. The default
+ branch is automatically protected. For more information, read
+ [Pipeline security on protected branches](../../../ci/pipelines/index.md#pipeline-security-on-protected-branches).
- A [scanner profile](#create-a-scanner-profile).
- A [site profile](#create-a-site-profile).
-- If you are running an active scan the site profile must be [validated](#validate-a-site-profile).
+- If you are running an active scan the site profile must have been [validated](#validate-a-site-profile).
+
+You can run an on-demand scan immediately, once at a scheduled date and time or at a specified
+frequency:
+
+- Every day
+- Every week
+- Every month
+- Every 3 months
+- Every 6 months
+- Every year
-To run an on-demand scan, either:
+To run an on-demand scan immediately, either:
-- [Create and run an on-demand scan](#create-and-run-an-on-demand-scan).
+- [Create and run an on-demand scan immediately](#create-and-run-an-on-demand-scan-immediately).
- [Run a previously saved on-demand scan](#run-a-saved-on-demand-scan).
-#### Create and run an on-demand scan
+To run an on-demand scan either at a scheduled date or frequency, read
+[Schedule an on-demand scan](#schedule-an-on-demand-scan).
+
+#### Create and run an on-demand scan immediately
1. From your project's home page, go to **Security & Compliance > On-demand Scans** in the left
sidebar.
@@ -965,44 +979,70 @@ To run an on-demand scan, either:
1. In GitLab 13.10 and later, select the desired branch from the **Branch** dropdown.
1. In **Scanner profile**, select a scanner profile from the dropdown.
1. In **Site profile**, select a site profile from the dropdown.
-1. To run the on-demand scan now, select **Save and run scan**. Otherwise select **Save scan** to
- [run](#run-a-saved-on-demand-scan) it later.
+1. To run the on-demand scan immediately, select **Save and run scan**. Otherwise, select
+ **Save scan** to [run](#run-a-saved-on-demand-scan) it later.
The on-demand DAST scan runs and the project's dashboard shows the results.
-### List saved on-demand scans
+#### Run a saved on-demand scan
-To list saved on-demand scans:
+To run a saved on-demand scan:
-1. From your project's home page, go to **Security & Compliance > Configuration**.
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Security & Compliance > Configuration**.
+1. Select **Manage DAST scans**.
+1. In the **DAST Profiles** row, select **Manage**.
1. Select the **Saved Scans** tab.
+1. In the scan's row, select **Run scan**.
+
+ If the branch saved in the scan no longer exists, you must first
+ [edit the scan](#edit-an-on-demand-scan), select a new branch, and save the edited scan.
-### View details of an on-demand scan
+The on-demand DAST scan runs, and the project's dashboard shows the results.
-To view details of an on-demand scan:
+#### Schedule an on-demand scan
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/328749) in GitLab 14.3. [Deployed behind the `dast_on_demand_scans_scheduler` flag](../../../administration/feature_flags.md), disabled by default.
+
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available per user,
+ask an administrator to [disable the `dast_on_demand_scans_scheduler` flag](../../../administration/feature_flags.md).
+The feature is not ready for production use.
+
+To schedule a scan:
+
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Security & Compliance > On-demand Scans**.
+1. Complete the **Scan name** and **Description** text boxes.
+1. In GitLab 13.10 and later, from the **Branch** dropdown list, select the desired branch.
+1. In the **Scanner profile** section, from the dropdown list, select a scanner profile.
+1. In the **Site profile** section, from the dropdown list, select a site profile.
+1. Select **Schedule scan**.
+1. In the **Start time** section, select a time zone, date, and time.
+1. From the **Repeats** dropdown list, select your desired frequency:
+ - To run the scan once, select **Never**.
+ - For a recurring scan, select any other option.
+1. To run the on-demand scan immediately, select **Save and run scan**. To [run](#run-a-saved-on-demand-scan) it according to the schedule you set, select
+ **Save scan**.
+
+#### List saved on-demand scans
+
+To list saved on-demand scans:
1. From your project's home page, go to **Security & Compliance > Configuration**.
-1. Select **Manage DAST scans**.
-1. Select **Manage** in the **DAST Profiles** row.
1. Select the **Saved Scans** tab.
-1. In the saved scan's row select **More actions** (**{ellipsis_v}**), then select **Edit**.
-### Run a saved on-demand scan
+#### View details of an on-demand scan
-To run a saved on-demand scan:
+To view details of an on-demand scan:
1. From your project's home page, go to **Security & Compliance > Configuration**.
1. Select **Manage DAST scans**.
1. Select **Manage** in the **DAST Profiles** row.
1. Select the **Saved Scans** tab.
-1. In the scan's row select **Run scan**.
-
- If the branch saved in the scan no longer exists, you must first
- [edit the scan](#edit-an-on-demand-scan), select a new branch, and save the edited scan.
-
-The on-demand DAST scan runs and the project's dashboard shows the results.
+1. In the saved scan's row select **More actions** (**{ellipsis_v}**), then select **Edit**.
-### Edit an on-demand scan
+#### Edit an on-demand scan
To edit an on-demand scan:
@@ -1014,7 +1054,7 @@ To edit an on-demand scan:
1. Edit the form.
1. Select **Save scan**.
-### Delete an on-demand scan
+#### Delete an on-demand scan
To delete an on-demand scan:
@@ -1049,11 +1089,7 @@ When an API site type is selected, a [host override](#host-override) is used to
#### Site profile validation
> - Site profile validation [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233020) in GitLab 13.8.
-> - Meta tag validation [enabled on GitLab.com](https://gitlab.com/groups/gitlab-org/-/epics/6460) in GitLab 14.2 and is ready for production use.
-> - Meta tag validation [enabled with `dast_meta_tag_validation flag` flag](https://gitlab.com/gitlab-org/gitlab/-/issues/337711) for self-managed GitLab in GitLab 14.2 and is ready for production use.
-
-FLAG:
-On self-managed GitLab, by default this feature is available. To hide the feature, ask an administrator to [disable the `dast_meta_tag_validation` flag](../../../administration/feature_flags.md). On GitLab.com, this feature is available but can be configured by GitLab.com administrators only.
+> - Meta tag validation [introduced](https://gitlab.com/groups/gitlab-org/-/epics/6460) in GitLab 14.2.
Site profile validation reduces the risk of running an active scan against the wrong website. A site
must be validated before an active scan can run against it. The site validation methods are as
@@ -1096,7 +1132,7 @@ To edit an existing site profile:
1. Edit the fields then select **Save profile**.
If a site profile is linked to a security policy, a user cannot edit the profile from this page. See
-[Scan Policies](../policies/index.md)
+[Scan Execution Policies](../policies/index.md#scan-execution-policy-editor)
for more information.
#### Delete a site profile
@@ -1110,7 +1146,7 @@ To delete an existing site profile:
1. Select **Delete** to confirm the deletion.
If a site profile is linked to a security policy, a user cannot delete the profile from this page.
-See [Scan Policies](../policies/index.md)
+See [Scan Execution Policies](../policies/index.md#scan-execution-policy-editor)
for more information.
#### Validate a site profile
@@ -1147,6 +1183,21 @@ The site is validated and an active scan can run against it.
If a validated site profile's target URL is edited, the site's validation status is revoked.
+#### Retry a failed validation
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/322609) in GitLab 14.3.
+
+FLAG:
+On self-managed GitLab, by default this feature is available. To hide the feature, ask an
+administrator to [disable the `dast_failed_site_validations` flag](../../../administration/feature_flags.md).
+
+If a site profile's validation fails, you can retry it by selecting the **Retry validation** button
+in the profiles list.
+
+When loading the DAST profiles library, past failed validations are listed above the profiles
+list. You can also retry the validation from there by selecting the **Retry validation** link in
+the alert. You can also dismiss the alert to revoke failed validations.
+
#### Revoke a site profile's validation status
Note that all site profiles with the same URL have their validation status revoked.
@@ -1240,7 +1291,7 @@ To edit a scanner profile:
1. Select **Save profile**.
If a scanner profile is linked to a security policy, a user cannot edit the profile from this page.
-See [Scan Policies](../policies/index.md)
+See [Scan Execution Policies](../policies/index.md#scan-execution-policy-editor)
for more information.
#### Delete a scanner profile
@@ -1254,7 +1305,7 @@ To delete a scanner profile:
1. Select **Delete**.
If a scanner profile is linked to a security policy, a user cannot delete the profile from this
-page. See [Scan Policies](../policies/index.md)
+page. See [Scan Execution Policies](../policies/index.md#scan-execution-policy-editor)
for more information.
### Auditing
@@ -1311,9 +1362,9 @@ dast:
By default, DAST downloads all artifacts defined by previous jobs in the pipeline. If
your DAST job does not rely on `environment_url.txt` to define the URL under test or any other files created
in previous jobs, we recommend you don't download artifacts. To avoid downloading
-artifacts, add the following to your `gitlab-ci.yml` file:
+artifacts, add the following to your `.gitlab-ci.yml` file:
-```json
+```yaml
dast:
dependencies: []
```
diff --git a/doc/user/application_security/dast_api/index.md b/doc/user/application_security/dast_api/index.md
index 48a784e0d03..055a2ceb161 100644
--- a/doc/user/application_security/dast_api/index.md
+++ b/doc/user/application_security/dast_api/index.md
@@ -897,7 +897,7 @@ variables:
### Exclude Paths
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/211892) in GitLab 14.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/211892) in GitLab 14.0.
When testing an API it can be useful to exclude certain paths. For example, you might exclude testing of an authentication service or an older version of the API. To exclude paths, use the `FUZZAPI_EXCLUDE_PATHS` CI/CD variable . This variable is specified in your `.gitlab-ci.yml` file. To exclude multiple paths, separate entries using the `;` character. In the provided paths you can use a single character wildcard `?` and `*` for a multiple character wildcard.
diff --git a/doc/user/application_security/dependency_list/index.md b/doc/user/application_security/dependency_list/index.md
index 1cb21d34853..edfd0333d54 100644
--- a/doc/user/application_security/dependency_list/index.md
+++ b/doc/user/application_security/dependency_list/index.md
@@ -10,7 +10,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10075) in GitLab Ultimate 12.0.
Use the dependency list to review your project's dependencies and key
-details about those dependencies, including their known vulnerabilities. It is a collection of dependencies in your project, including existing and new findings.
+details about those dependencies, including their known vulnerabilities. It is a collection of dependencies in your project, including existing and new findings.
To see the dependency list, go to your project and select **Security & Compliance > Dependency List**.
@@ -49,7 +49,7 @@ can also be sorted by name or by the packager that installed them.
If a dependency has known vulnerabilities, view them by clicking the arrow next to the
dependency's name or the badge that indicates how many known vulnerabilities exist. For each
vulnerability, its severity and description appears below it. To view more details of a vulnerability,
-select the vulnerability’s description. The [vulnerability's details](../vulnerabilities) page is opened.
+select the vulnerability's description. The [vulnerability's details](../vulnerabilities) page is opened.
### Dependency paths
@@ -78,8 +78,8 @@ You can download your project's full list of dependencies and their details in
### In the UI
-You can download your project’s list of dependencies and their details in JSON format by selecting the **Export** button. Note that the dependency list only shows the results of the last successful pipeline to run on the default branch.
+You can download your project's list of dependencies and their details in JSON format by selecting the **Export** button. Note that the dependency list only shows the results of the last successful pipeline to run on the default branch.
### Using the API
-You can download your project’s list of dependencies [using the API](../../../api/dependencies.md#list-project-dependencies). Note this only provides the dependencies identified by the gemnasium family of analyzers and [not any other of the GitLab dependency analyzers](../dependency_scanning/analyzers.md).
+You can download your project's list of dependencies [using the API](../../../api/dependencies.md#list-project-dependencies). Note this only provides the dependencies identified by the gemnasium family of analyzers and [not any other of the GitLab dependency analyzers](../dependency_scanning/analyzers.md).
diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md
index 565b9c29934..d903ce58982 100644
--- a/doc/user/application_security/dependency_scanning/index.md
+++ b/doc/user/application_security/dependency_scanning/index.md
@@ -57,8 +57,8 @@ However, you can override the selection using the variable `DS_EXCLUDED_ANALYZER
The language detection relies on CI job [`rules`](../../../ci/yaml/index.md#rules) and searches a
maximum of two directory levels from the repository's root. For example, the
-`gemnasium-dependency_scanning` job is enabled if a repository contains either a `Gemfile` or
-`api/Gemfile` file, but not if the only supported dependency file is `api/client/Gemfile`.
+`gemnasium-dependency_scanning` job is enabled if a repository contains either `Gemfile`,
+`api/Gemfile`, or `api/client/Gemfile`, but not if the only supported dependency file is `api/v1/client/Gemfile`.
The following languages and dependency managers are supported:
@@ -147,7 +147,7 @@ table.supported-languages ul {
</tr>
<tr>
<td rowspan="2">Java</td>
- <td><a href="https://gradle.org/">Gradle</a></td>
+ <td><a href="https://gradle.org/">Gradle</a><sup><b><a href="#notes-regarding-supported-languages-and-package-managers">1</a></b></sup></td>
<td>Any</td>
<td>
<ul>
@@ -228,7 +228,7 @@ table.supported-languages ul {
<td>
<ul>
<li><a href="https://pipenv.pypa.io/en/latest/basics/#example-pipfile-pipfile-lock"><code>Pipfile</code></a></li>
- <li><a href="https://pipenv.pypa.io/en/latest/basics/#example-pipfile-pipfile-lock"><code>Pipfile.lock</code></a><sup><b><a href="#notes-regarding-supported-languages-and-package-managers">1</a></b></sup></li>
+ <li><a href="https://pipenv.pypa.io/en/latest/basics/#example-pipfile-pipfile-lock"><code>Pipfile.lock</code></a><sup><b><a href="#notes-regarding-supported-languages-and-package-managers">2</a></b></sup></li>
</ul>
</td>
<td><a href="https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium">Gemnasium</a></td>
@@ -236,7 +236,7 @@ table.supported-languages ul {
</tr>
<tr>
<td>Scala</td>
- <td><a href="https://www.scala-sbt.org/">sbt</a><sup><b><a href="#notes-regarding-supported-languages-and-package-managers">2</a></b></sup></td>
+ <td><a href="https://www.scala-sbt.org/">sbt</a><sup><b><a href="#notes-regarding-supported-languages-and-package-managers">3</a></b></sup></td>
<td>Any</td>
<td><code>build.sbt</code></td>
<td><a href="https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium">Gemnasium</a></td>
@@ -247,6 +247,8 @@ table.supported-languages ul {
### Notes regarding supported languages and package managers
+1. Although Gradle with Java 8 is supported, there are other issues such that Android project builds are not supported at this time. Please see the backlog issue [Android support for Dependency Scanning (gemnasium-maven)](https://gitlab.com/gitlab-org/gitlab/-/issues/336866) for more details.
+
1. The presence of a `Pipfile.lock` file alone will _not_ trigger the analyzer; the presence of a `Pipfile` is still required in order
for the analyzer to be executed. However, if a `Pipfile.lock` file is found, it will be used by `Gemnasium` to scan the exact package
versions listed in this file.
@@ -262,7 +264,7 @@ GitLab relies on [`rules:exists`](../../../ci/yaml/index.md#rulesexists) to star
`Supported files` in the repository as shown in the [table above](#supported-languages-and-package-managers).
The current detection logic limits the maximum search depth to two levels. For example, the `gemnasium-dependency_scanning` job is enabled if
-a repository contains either a `Gemfile.lock` or `api/Gemfile.lock` file, but not if the only supported dependency file is `api/client/Gemfile.lock`.
+a repository contains either a `Gemfile.lock`, `api/Gemfile.lock`, or `api/client/Gemfile.lock`, but not if the only supported dependency file is `api/v1/client/Gemfile.lock`.
### How multiple files are processed
@@ -287,13 +289,13 @@ We execute both analyzers because they use different sources of vulnerability da
#### Python
-We only execute one build in the directory where a requirements file has been detected, such as `requirements.txt` or any
+We only execute one installation in the directory where a requirements file has been detected, such as `requirements.txt` or any
variation of this file (for example, `requirements.pip` or `requires.txt`).
#### Java and Scala
We only execute one build in the directory where a build file has been detected, such as `build.sbt` or `build.gradle`.
-Please note, we support the following types of Java project stuctures:
+Please note, we support the following types of Java project structures:
- [multi-project sbt builds](https://www.scala-sbt.org/1.x/docs/Multi-Project.html)
- [multi-project gradle builds](https://docs.gradle.org/current/userguide/intro_multi_project_builds.html)
@@ -908,3 +910,19 @@ with a dependency on this version of Python should use `retire.js` version 2.10.
### Error: `dependency_scanning is used for configuration only, and its script should not be executed`
For information on this, see the [GitLab Secure troubleshooting section](../index.md#error-job-is-used-for-configuration-only-and-its-script-should-not-be-executed).
+
+### Import multiple certificates for Java-based projects
+
+The `gemnasium-maven` analyzer reads the contents of the `ADDITIONAL_CA_CERT_BUNDLE` variable using `keytool`, which imports either a single certificate or a certificate chain. Multiple unrelated certificates are ignored and only the first one is imported by `keytool`.
+
+To add multiple unrelated certificates to the analyzer, you can declare a `before_script` such as this in the definition of the `gemnasium-maven-dependency_scanning` job:
+
+```yaml
+gemnasium-maven-dependency_scanning:
+ before_script:
+ - . $HOME/.bashrc # make the java tools available to the script
+ - OIFS="$IFS"; IFS=""; echo $ADDITIONAL_CA_CERT_BUNDLE > multi.pem; IFS="$OIFS" # write ADDITIONAL_CA_CERT_BUNDLE variable to a PEM file
+ - csplit -z --digits=2 --prefix=cert multi.pem "/-----END CERTIFICATE-----/+1" "{*}" # split the file into individual certificates
+ - for i in `ls cert*`; do keytool -v -importcert -alias "custom-cert-$i" -file $i -trustcacerts -noprompt -storepass changeit -keystore /opt/asdf/installs/java/adoptopenjdk-11.0.7+10.1/lib/security/cacerts 1>/dev/null 2>&1 || true; done # import each certificate using keytool (note the keystore location is related to the Java version being used and should be changed accordingly for other versions)
+ - unset ADDITIONAL_CA_CERT_BUNDLE # unset the variable so that the analyzer doesn't duplicate the import
+```
diff --git a/doc/user/application_security/img/mr_security_scanning_results_v14_3.png b/doc/user/application_security/img/mr_security_scanning_results_v14_3.png
new file mode 100644
index 00000000000..3e0113dfb46
--- /dev/null
+++ b/doc/user/application_security/img/mr_security_scanning_results_v14_3.png
Binary files differ
diff --git a/doc/user/application_security/index.md b/doc/user/application_security/index.md
index 50fd727b892..7b95769a81f 100644
--- a/doc/user/application_security/index.md
+++ b/doc/user/application_security/index.md
@@ -159,7 +159,9 @@ We recommended you run a scan of the `default` branch before enabling feature br
The merge request security widget displays only a subset of the vulnerabilities in the generated JSON artifact because it contains both NEW and EXISTING findings.
-From the merge request security widget, select **Expand** to unfold the widget, displaying any new and no longer detected (removed) findings by scan type. Select **View Full Report** to go directly to the **Security** tab in the latest branch pipeline.
+From the merge request security widget, select **Expand** to unfold the widget, displaying any new and no longer detected (removed) findings by scan type. Select **View full report** to go directly to the **Security** tab in the latest branch pipeline.
+
+![Security scanning results in a merge request](img/mr_security_scanning_results_v14_3.png)
## View security scan information in the pipeline Security tab
@@ -221,7 +223,8 @@ For this approval group, you must set the number of approvals required to greate
Follow these steps to enable `Vulnerability-Check`:
-1. Go to your project and select **Settings > General**.
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Settings > General**.
1. Expand **Merge request approvals**.
1. Select **Enable** or **Edit**.
1. Set the **Security scanners** that the rule applies to.
@@ -269,7 +272,7 @@ under your project's settings:
## DAST On-Demand Scans
-If you don’t want scans running in your normal DevOps process you can use on-demand scans instead. For more details, see [on-demand scans](dast/index.md#on-demand-scans). This feature is only available for DAST. If you run an on-demand scan against the default branch, it is reported as a "successful pipeline" and these results are included in the security dashboard and vulnerability report.
+If you don't want scans running in your normal DevOps process you can use on-demand scans instead. For more details, see [on-demand scans](dast/index.md#on-demand-scans). This feature is only available for DAST. If you run an on-demand scan against the default branch, it is reported as a "successful pipeline" and these results are included in the security dashboard and vulnerability report.
## Security report validation
@@ -337,6 +340,16 @@ For more details about which findings or vulnerabilities you can view in each of
## Troubleshooting
+### Secure job failing with exit code 1
+
+If a Secure job is failing and it's unclear why, add `SECURE_LOG_LEVEL: "debug"` as a global CI/CD variable for
+more verbose output that is helpful for troubleshooting.
+
+```yaml
+variables:
+ SECURE_LOG_LEVEL: "debug"
+```
+
### Outdated security reports
When a security report generated for a merge request becomes outdated, the merge request shows a warning
diff --git a/doc/user/application_security/offline_deployments/index.md b/doc/user/application_security/offline_deployments/index.md
index 3bf9d85cd0b..cdf54070d69 100644
--- a/doc/user/application_security/offline_deployments/index.md
+++ b/doc/user/application_security/offline_deployments/index.md
@@ -111,7 +111,7 @@ example of such a transfer:
GitLab provides a [vendored template](../../../ci/yaml/index.md#includetemplate)
to ease this process.
-This template should be used in a new, empty project, with a `gitlab-ci.yml` file containing:
+This template should be used in a new, empty project, with a `.gitlab-ci.yml` file containing:
```yaml
include:
diff --git a/doc/user/application_security/policies/img/container_policy_rule_mode_v14_3.png b/doc/user/application_security/policies/img/container_policy_rule_mode_v14_3.png
new file mode 100644
index 00000000000..b21d0330b2f
--- /dev/null
+++ b/doc/user/application_security/policies/img/container_policy_rule_mode_v14_3.png
Binary files differ
diff --git a/doc/user/application_security/policies/img/container_policy_yaml_mode_v14_3.png b/doc/user/application_security/policies/img/container_policy_yaml_mode_v14_3.png
new file mode 100644
index 00000000000..31d5eb57228
--- /dev/null
+++ b/doc/user/application_security/policies/img/container_policy_yaml_mode_v14_3.png
Binary files differ
diff --git a/doc/user/application_security/policies/img/policies_list_v14_3.png b/doc/user/application_security/policies/img/policies_list_v14_3.png
new file mode 100644
index 00000000000..7a24860d4a7
--- /dev/null
+++ b/doc/user/application_security/policies/img/policies_list_v14_3.png
Binary files differ
diff --git a/doc/user/application_security/policies/img/scan_execution_policy_yaml_mode_v14_3.png b/doc/user/application_security/policies/img/scan_execution_policy_yaml_mode_v14_3.png
new file mode 100644
index 00000000000..d04905eda59
--- /dev/null
+++ b/doc/user/application_security/policies/img/scan_execution_policy_yaml_mode_v14_3.png
Binary files differ
diff --git a/doc/user/application_security/policies/img/security_policy_project_v14_3.png b/doc/user/application_security/policies/img/security_policy_project_v14_3.png
new file mode 100644
index 00000000000..5e3aefaeb81
--- /dev/null
+++ b/doc/user/application_security/policies/img/security_policy_project_v14_3.png
Binary files differ
diff --git a/doc/user/application_security/policies/index.md b/doc/user/application_security/policies/index.md
index 3d0135678b7..bd143d8608a 100644
--- a/doc/user/application_security/policies/index.md
+++ b/doc/user/application_security/policies/index.md
@@ -4,57 +4,189 @@ group: Container Security
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/#designated-technical-writers
---
-# Scan Policies **(ULTIMATE)**
+# Policies **(ULTIMATE)**
-> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5329) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.10.
-> - Deployed behind a feature flag, disabled by default.
-> - Disabled on GitLab.com.
+> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5329) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.10. Deployed behind a feature flag, disabled by default.
+> - [Enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/321258) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 14.3.
-Scan Policies in GitLab provide security teams a way to require scans of their choice to be run
+FLAG:
+On self-managed GitLab, by default this feature is available. To hide the feature,
+ask an administrator to [disable the `security_orchestration_policies_configuration` flag](../../../administration/feature_flags.md).
+On GitLab.com, this feature is available.
+
+Policies in GitLab provide security teams a way to require scans of their choice to be run
whenever a project pipeline runs according to the configuration specified. Security teams can
therefore be confident that the scans they set up have not been changed, altered, or disabled. You
-can access these by navigating to your project's **Security & Compliance > Scan Policies** page.
+can access these by navigating to your project's **Security & Compliance > Policies** page.
GitLab supports the following security policies:
+- [Container Network Policy](#container-network-policy)
- [Scan Execution Policy](#scan-execution-policy-schema)
-WARNING:
-Scan Policies is under development and is not ready for production use. It's deployed behind a
-feature flag that's disabled by default.
+## Policy management
-NOTE:
-We recommend using the [Security Policies project](#security-policies-project)
-exclusively for managing policies for the project. Do not add your application's source code to such
-projects.
+The Policies page displays deployed
+policies for all available environments. You can check a
+policy's information (for example description, enforcement
+status, etc.), and create and edit deployed policies:
+
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Security & Compliance > Policies**.
+
+![Policies List Page](img/policies_list_v14_3.png)
+
+Network policies are fetched directly from the selected environment's
+deployment platform while other policies are fetched from the project's
+security policy project. Changes performed outside of this tab are
+reflected upon refresh.
+
+By default, the policy list contains predefined network policies in a
+disabled state. Once enabled, a predefined policy deploys to the
+selected environment's deployment platform and you can manage it like
+the regular policies.
+
+Note that if you're using [Auto DevOps](../../../topics/autodevops/index.md)
+and change a policy in this section, your `auto-deploy-values.yaml` file doesn't update. Auto DevOps
+users must make changes by following the
+[Container Network Policy documentation](../../../topics/autodevops/stages.md#network-policy).
+
+## Policy editor
+
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3403) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.4.
+
+You can use the policy editor to create, edit, and delete policies:
+
+1. On the top bar, select **Menu > Projects** and find your group.
+1. On the left sidebar, select **Security & Compliance > Policies**.
+ - To create a new policy, select **New policy** which is located in the **Policies** page's header.
+ - To edit an existing policy, select **Edit policy** in the selected policy drawer.
+
+The policy editor has two modes:
+
+- The visual _Rule_ mode allows you to construct and preview policy
+ rules using rule blocks and related controls.
+
+ ![Policy Editor Rule Mode](img/container_policy_rule_mode_v14_3.png)
+
+- YAML mode allows you to enter a policy definition in `.yaml` format
+ and is aimed at expert users and cases that the Rule mode doesn't
+ support.
+
+ ![Policy Editor YAML Mode](img/container_policy_yaml_mode_v14_3.png)
+
+You can use both modes interchangeably and switch between them at any
+time. If a YAML resource is incorrect or contains data not supported
+by the Rule mode, Rule mode is automatically
+disabled. If the YAML is incorrect, you must use YAML
+mode to fix your policy before Rule mode is available again.
-## Enable or disable scan policies
+## Container Network Policy
-Scan Policies is under development and is not ready for production use. It's deployed behind a
-feature flag that's disabled by default.
-[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
-can enable it for your instance. Scan Policies can be enabled or disabled per-project.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32365) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.9.
-To enable it:
+The **Container Network Policy** section provides packet flow metrics for
+your application's Kubernetes namespace. This section has the following
+prerequisites:
-```ruby
-# Instance-wide
-Feature.enable(:security_orchestration_policies_configuration)
-# or by project
-Feature.enable(:security_orchestration_policies_configuration, Project.find(<project ID>))
+- Your project contains at least one [environment](../../../ci/environments/index.md).
+- You've [installed Cilium](../../project/clusters/protect/container_network_security/quick_start_guide.md#use-the-cluster-management-template-to-install-cilium).
+- You've configured the [Prometheus service](../../project/integrations/prometheus.md#enabling-prometheus-integration).
+
+If you're using custom Helm values for Cilium, you must enable Hubble
+with flow metrics for each namespace by adding the following lines to
+your [Cilium values](../../project/clusters/protect/container_network_security/quick_start_guide.md#use-the-cluster-management-template-to-install-cilium):
+
+```yaml
+hubble:
+ enabled: true
+ metrics:
+ enabled:
+ - 'flow:sourceContext=namespace;destinationContext=namespace'
```
-To disable it:
+The **Container Network Policy** section displays the following information
+about your packet flow:
+
+- The total amount of the inbound and outbound packets
+- The proportion of packets dropped according to the configured
+ policies
+- The per-second average rate of the forwarded and dropped packets
+ accumulated over time window for the requested time interval
-```ruby
-# Instance-wide
-Feature.disable(:security_orchestration_policies_configuration)
-# or by project
-Feature.disable(:security_orchestration_policies_configuration, Project.find(<project ID>))
+If a significant percentage of packets is dropped, you should
+investigate it for potential threats by
+examining the Cilium logs:
+
+```shell
+kubectl -n gitlab-managed-apps logs -l k8s-app=cilium -c cilium-monitor
```
+### Change the enforcement status
+
+To change a network policy's enforcement status:
+
+- Select the network policy you want to update.
+- Select **Edit policy**.
+- Select the **Policy status** toggle to update the selected policy.
+- Select **Save changes** to deploy network policy changes.
+
+Disabled network policies have the `network-policy.gitlab.com/disabled_by: gitlab` selector inside
+the `podSelector` block. This narrows the scope of such a policy and as a result it doesn't affect
+any pods. The policy itself is still deployed to the corresponding deployment namespace.
+
+### Container Network Policy editor
+
+The policy editor only supports the [CiliumNetworkPolicy](https://docs.cilium.io/en/v1.8/policy/)
+specification. Regular Kubernetes [NetworkPolicy](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#networkpolicy-v1-networking-k8s-io)
+resources aren't supported.
+
+Rule mode supports the following rule types:
+
+- [Labels](https://docs.cilium.io/en/v1.8/policy/language/#labels-based).
+- [Entities](https://docs.cilium.io/en/v1.8/policy/language/#entities-based).
+- [IP/CIDR](https://docs.cilium.io/en/v1.8/policy/language/#ip-cidr-based). Only
+ the `toCIDR` block without `except` is supported.
+- [DNS](https://docs.cilium.io/en/v1.8/policy/language/#dns-based).
+- [Level 4](https://docs.cilium.io/en/v1.8/policy/language/#layer-4-examples)
+ can be added to all other rules.
+
+Once your policy is complete, save it by selecting **Save policy**
+at the bottom of the editor. Existing policies can also be
+removed from the editor interface by selecting **Delete policy**
+at the bottom of the editor.
+
+### Configure a Network Policy Alert
+
+> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3438) and [enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/287676) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.9.
+> - The feature flag was removed and the Threat Monitoring Alerts Project was [made generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/287676) in GitLab 14.0.
+
+You can use policy alerts to track your policy's impact. Alerts are only available if you've
+[installed](../../clusters/agent/repository.md)
+and [configured](../../clusters/agent/index.md#create-an-agent-record-in-gitlab)
+a Kubernetes Agent for this project.
+
+There are two ways to create policy alerts:
+
+- In the [policy editor UI](#container-network-policy-editor),
+ by clicking **Add alert**.
+- In the policy editor's YAML mode, through the `metadata.annotations` property:
+
+ ```yaml
+ metadata:
+ annotations:
+ app.gitlab.com/alert: 'true'
+ ```
+
+Once added, the UI updates and displays a warning about the dangers of too many alerts.
+
## Security Policies project
+NOTE:
+We recommend using the [Security Policies project](#security-policies-project)
+exclusively for managing policies for the project. Do not add your application's source code to such
+projects.
+
The Security Policies feature is a repository to store policies. All security policies are stored as
the `.gitlab/security-policies/policy.yml` YAML file with this format:
@@ -85,6 +217,40 @@ scan_execution_policy:
site_profile: Site Profile D
```
+## Security Policy project selection
+
+NOTE:
+Only project Owners have the [permissions](../../permissions.md#project-members-permissions)
+to select Security Policy Project.
+
+When the Security Policy project is created and policies are created within that repository, you
+must create an association between that project and the project you want to apply policies to:
+
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Security & Compliance > Policies**.
+1. Select **Edit Policy Project**, and search for and select the
+ project you would like to link from the dropdown menu.
+1. Select **Save**.
+
+ ![Security Policy Project](img/security_policy_project_v14_3.png)
+
+### Scan Execution Policy editor
+
+NOTE:
+Only project Owners have the [permissions](../../permissions.md#project-members-permissions)
+to select Security Policy Project.
+
+Once your policy is complete, save it by selecting **Create merge request**
+at the bottom of the editor. You will be redirected to the merge request on the project's
+configured security policy project. If one does not link to your project, a security
+policy project will be automatically created. Existing policies can also be
+removed from the editor interface by selecting **Delete policy**
+at the bottom of the editor.
+
+![Scan Execution Policy Editor YAML Mode](img/scan_execution_policy_yaml_mode_v14_3.png)
+
+The policy editor currently only supports the YAML mode. The Rule mode is tracked in the [Allow Users to Edit Rule-mode Scan Execution Policies in the Policy UI](https://gitlab.com/groups/gitlab-org/-/epics/5363) epic.
+
### Scan Execution Policies Schema
The YAML file with Scan Execution Policies consists of an array of objects matching Scan Execution Policy Schema nested under the `scan_execution_policy` key. You can configure a maximum of 5 policies under the `scan_execution_policy` key.
@@ -121,6 +287,16 @@ This rule enforces the defined actions and schedules a scan on the provided date
| `type` | `string` | `schedule` | The rule's type. |
| `branches` | `array` of `string` | `*` or the branch's name | The branch the given policy applies to (supports wildcard). |
| `cadence` | `string` | CRON expression (for example, `0 0 * * *`) | A whitespace-separated string containing five fields that represents the scheduled time. |
+| `clusters` | `object` | | The cluster where the given policy will enforce running selected scans (only for `container_scanning`/`cluster_image_scanning` scans). The key of the object is the name of the Kubernetes cluster configured for your project in GitLab. In the optionally provided value of the object, you can precisely select Kubernetes resources that will be scanned. |
+
+#### `cluster` schema
+
+| Field | Type | Possible values | Description |
+|--------------|---------------------|--------------------------|-------------|
+| `containers` | `array` of `string` | | The container name that will be scanned (only the first value is currently supported). |
+| `resources` | `array` of `string` | | The resource name that will be scanned (only the first value is currently supported). |
+| `namespaces` | `array` of `string` | | The namespace that will be scanned (only the first value is currently supported). |
+| `kinds` | `array` of `string` | `deployment`/`daemonset` | The resource kind that should be scanned (only the first value is currently supported). |
### `scan` action type
@@ -149,6 +325,9 @@ Note the following:
- A secret detection scan runs in `normal` mode when executed as part of a pipeline, and in
[`historic`](../secret_detection/index.md#full-history-secret-scan)
mode when executed as part of a scheduled scan.
+- A container scanning and cluster image scanning scans configured for the `pipeline` rule type will ignore the cluster defined in the `clusters` object.
+ They will use predefined CI/CD variables defined for your project. Cluster selection with the `clusters` object is supported for the `schedule` rule type.
+ Cluster with name provided in `clusters` object must be created and configured for the project. To be able to successfully perform the `container_scanning`/`cluster_image_scanning` scans for the cluster you must follow instructions for the [Cluster Image Scanning feature](../cluster_image_scanning/index.md#prerequisites).
Here's an example:
@@ -179,8 +358,8 @@ scan_execution_policy:
scanner_profile: Scanner Profile C
site_profile: Site Profile D
- scan: secret_detection
-- name: Enforce Secret Detection in every default branch pipeline
- description: This policy enforces pipeline configuration to have a job with Secret Detection scan for the default branch
+- name: Enforce Secret Detection and Container Scanning in every default branch pipeline
+ description: This policy enforces pipeline configuration to have a job with Secret Detection and Container Scanning scans for the default branch
enabled: true
rules:
- type: pipeline
@@ -188,6 +367,25 @@ scan_execution_policy:
- main
actions:
- scan: secret_detection
+ - scan: container_scanning
+- name: Enforce Cluster Image Scanning on production-cluster every 24h
+ description: This policy enforces Cluster Image Scanning scan to run every 24 hours
+ enabled: true
+ rules:
+ - type: schedule
+ cadence: '15 3 * * *'
+ clusters:
+ production-cluster:
+ containers:
+ - database
+ resources:
+ - production-application
+ namespaces:
+ - production-namespace
+ kinds:
+ - deployment
+ actions:
+ - scan: cluster_image_scanning
```
In this example:
@@ -196,22 +394,9 @@ In this example:
`release/v1.2.1`), DAST scans run with `Scanner Profile A` and `Site Profile B`.
- DAST and secret detection scans run every 10 minutes. The DAST scan runs with `Scanner Profile C`
and `Site Profile D`.
-- Secret detection scans run for every pipeline executed on the `main` branch.
-
-## Security Policy project selection
-
-When the Security Policy project is created and policies are created within that repository, you
-must create an association between that project and the project you want to apply policies to. To do
-this, navigate to your project's **Security & Compliance > Policies**, select
-**Security policy project** from the dropdown menu, then select the **Create policy** button to save
-changes.
-
-You can always change the **Security policy project** by navigating to your project's
-**Security & Compliance > Policies** and modifying the selected project.
-
-NOTE:
-Only project Owners have the [permissions](../../permissions.md#project-members-permissions)
-to select Security Policy Project.
+- Secret detection and container scanning scans run for every pipeline executed on the `main` branch.
+- Cluster Image Scanning scan runs every 24h. The scan runs on the `production-cluster` cluster and fetches vulnerabilities
+ from the container with the name `database` configured for deployment with the name `production-application` in the `production-namespace` namespace.
## Roadmap
diff --git a/doc/user/application_security/sast/analyzers.md b/doc/user/application_security/sast/analyzers.md
index 661a4ee8e82..d399dcaf4a9 100644
--- a/doc/user/application_security/sast/analyzers.md
+++ b/doc/user/application_security/sast/analyzers.md
@@ -65,8 +65,8 @@ Any custom change to the official analyzers can be achieved by using a
You can switch to a custom Docker registry that provides the official analyzer
images under a different prefix. For instance, the following instructs
-SAST to pull `my-docker-registry/gl-images/bandit`
-instead of `registry.gitlab.com/gitlab-org/security-products/analyzers/bandit`.
+SAST to pull `my-docker-registry/gl-images/sast/bandit`
+instead of `registry.gitlab.com/security-products/sast/bandit`.
In `.gitlab-ci.yml` define:
```yaml
diff --git a/doc/user/application_security/sast/index.md b/doc/user/application_security/sast/index.md
index 6e88f38d900..3caa1771a5b 100644
--- a/doc/user/application_security/sast/index.md
+++ b/doc/user/application_security/sast/index.md
@@ -361,6 +361,9 @@ To create a custom ruleset:
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/292686) in GitLab 14.2.
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the `vulnerability_flags` flag](../../../administration/feature_flags.md). On GitLab.com, this feature is available.
+
Vulnerabilities that have been detected and are false positives will be flagged as false positives in the security dashboard.
### Using CI/CD variables to pass credentials for private repositories
@@ -669,19 +672,19 @@ import the following default SAST analyzer images from `registry.gitlab.com` int
[local Docker container registry](../../packages/container_registry/index.md):
```plaintext
-registry.gitlab.com/gitlab-org/security-products/analyzers/bandit:2
-registry.gitlab.com/gitlab-org/security-products/analyzers/brakeman:2
-registry.gitlab.com/gitlab-org/security-products/analyzers/eslint:2
-registry.gitlab.com/gitlab-org/security-products/analyzers/flawfinder:2
-registry.gitlab.com/gitlab-org/security-products/analyzers/gosec:2
-registry.gitlab.com/gitlab-org/security-products/analyzers/kubesec:2
-registry.gitlab.com/gitlab-org/security-products/analyzers/nodejs-scan:2
-registry.gitlab.com/gitlab-org/security-products/analyzers/phpcs-security-audit:2
-registry.gitlab.com/gitlab-org/security-products/analyzers/pmd-apex:2
-registry.gitlab.com/gitlab-org/security-products/analyzers/security-code-scan:2
-registry.gitlab.com/gitlab-org/security-products/analyzers/semgrep:2
-registry.gitlab.com/gitlab-org/security-products/analyzers/sobelow:2
-registry.gitlab.com/gitlab-org/security-products/analyzers/spotbugs:2
+registry.gitlab.com/security-products/sast/bandit:2
+registry.gitlab.com/security-products/sast/brakeman:2
+registry.gitlab.com/security-products/sast/eslint:2
+registry.gitlab.com/security-products/sast/flawfinder:2
+registry.gitlab.com/security-products/sast/gosec:3
+registry.gitlab.com/security-products/sast/kubesec:2
+registry.gitlab.com/security-products/sast/nodejs-scan:2
+registry.gitlab.com/security-products/sast/phpcs-security-audit:2
+registry.gitlab.com/security-products/sast/pmd-apex:2
+registry.gitlab.com/security-products/sast/security-code-scan:2
+registry.gitlab.com/security-products/sast/semgrep:2
+registry.gitlab.com/security-products/sast/sobelow:2
+registry.gitlab.com/security-products/sast/spotbugs:2
```
The process for importing Docker images into a local offline Docker registry depends on
diff --git a/doc/user/application_security/secret_detection/index.md b/doc/user/application_security/secret_detection/index.md
index b6ff68c861b..cd1014d36a6 100644
--- a/doc/user/application_security/secret_detection/index.md
+++ b/doc/user/application_security/secret_detection/index.md
@@ -35,7 +35,7 @@ GitLab displays identified secrets visibly in a few places:
Secret Detection detects a variety of common secrets by default. You can also customize the secret detection patterns using [custom rulesets](#custom-rulesets).
-The [default ruleset provided by Gitleaks](https://gitlab.com/gitlab-org/security-products/analyzers/secrets/-/blob/master/gitleaks.toml) includes the following key types:
+The [default ruleset provided by TruffleHog and Gitleaks](https://gitlab.com/gitlab-org/security-products/analyzers/secrets/-/blob/master/gitleaks.toml) includes the following key types:
- Cloud services:
- Amazon Web Services (AWS)
@@ -89,12 +89,13 @@ However not all features are available on every tier. See the breakdown below fo
Different features are available in different [GitLab tiers](https://about.gitlab.com/pricing/),
as shown in the following table:
-| Capability | In Free | In Ultimate |
+| Capability | In Free & Premium | In Ultimate |
|:----------------------------------------------------------------|:--------------------|:-------------------|
| [Configure Secret Detection Scanners](#configuration) | **{check-circle}** | **{check-circle}** |
| [Customize Secret Detection Settings](#customizing-settings) | **{check-circle}** | **{check-circle}** |
| View [JSON Report](../sast/index.md#reports-json-format) | **{check-circle}** | **{check-circle}** |
| Presentation of JSON Report in Merge Request | **{dotted-circle}** | **{check-circle}** |
+| View identified secrets in the pipelines' **Security** tab | **{dotted-circle}** | **{check-circle}** |
| [Interaction with Vulnerabilities](../vulnerabilities/index.md) | **{dotted-circle}** | **{check-circle}** |
| [Access to Security Dashboard](../security_dashboard/index.md) | **{dotted-circle}** | **{check-circle}** |
@@ -330,7 +331,7 @@ Import the following default Secret Detection analyzer images from `registry.git
[local Docker container registry](../../packages/container_registry/index.md):
```plaintext
-registry.gitlab.com/gitlab-org/security-products/analyzers/secrets:3
+registry.gitlab.com/security-products/secret-detection:3
```
The process for importing Docker images into a local offline Docker registry depends on
diff --git a/doc/user/application_security/security_dashboard/img/pipeline_security_dashboard_v14_2.png b/doc/user/application_security/security_dashboard/img/pipeline_security_dashboard_v14_2.png
index 3a195a5ce8d..52249cef343 100644
--- a/doc/user/application_security/security_dashboard/img/pipeline_security_dashboard_v14_2.png
+++ b/doc/user/application_security/security_dashboard/img/pipeline_security_dashboard_v14_2.png
Binary files differ
diff --git a/doc/user/application_security/security_dashboard/index.md b/doc/user/application_security/security_dashboard/index.md
index b799177ec5a..c78179e9693 100644
--- a/doc/user/application_security/security_dashboard/index.md
+++ b/doc/user/application_security/security_dashboard/index.md
@@ -46,7 +46,7 @@ The security dashboard and vulnerability report displays information about vulne
## Pipeline Security
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13496) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13496) in GitLab 12.3.
At the pipeline level, the Security section displays the vulnerabilities present in the branch of
the project the pipeline ran against.
@@ -64,7 +64,7 @@ the analyzer outputs an
### Scan details
-> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3728) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.10.
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3728) in GitLab 13.10.
The **Scan details** section lists the scans run in the pipeline and the total number of
vulnerabilities per scan. For the DAST scan, select **Download scanned resources** to download a
@@ -104,7 +104,7 @@ To download an SVG image of the chart, select **Save chart to an image** (**{dow
## Group Security Dashboard
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/6709) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/6709) in GitLab 11.5.
The group Security Dashboard gives an overview of the vulnerabilities found in the default branches of the
projects in a group and its subgroups. Access it by navigating to **Security > Security Dashboard**
@@ -139,7 +139,7 @@ Navigate to the group's [vulnerability report](../vulnerability_report/index.md)
## Security Center
-> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3426) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.4.
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3426) in GitLab 13.4.
The Security Center is personal space where you manage vulnerabilities across all your projects. It
displays the vulnerabilities present in the default branches of all the projects you configure. It includes
@@ -166,22 +166,17 @@ To add projects to the Security Center:
After you add projects, the security dashboard and vulnerability report display the vulnerabilities
found in those projects' default branches.
-## Keeping the dashboards up to date
+## Keep dashboards up to date
-The Security Dashboard displays information from the results of the most recent
-security scan on the [default branch](../../project/repository/branches/default.md),
-which means that security scans are performed every time the branch is updated.
-
-If the default branch is updated infrequently, scans are run infrequently and the
-information on the Security Dashboard can become outdated as new vulnerabilities
-are discovered.
+The Security Dashboard displays results of the most recent security scan on the
+[default branch](../../project/repository/branches/default.md). By default, security scans are run
+only when the default branch is updated. Information on the Security Dashboard may not reflect
+newly-discovered vulnerabilities.
To ensure the information on the Security Dashboard is regularly updated,
-[configure a scheduled pipeline](../../../ci/pipelines/schedules.md) to run a
-daily security scan. This updates the information displayed on the Security
-Dashboard regardless of how often the default branch is updated.
-
-That way, reports are created even if no code change happens.
+[configure a scheduled pipeline](../../../ci/pipelines/schedules.md) to run a daily security scan.
+This updates the information displayed on the Security Dashboard regardless of how often the default
+branch is updated.
WARNING:
Running Dependency Scanning from a scheduled pipeline might result in false negatives if your
@@ -191,12 +186,6 @@ can occur because the dependency version resolved during the scan might differ f
resolved when your project was built and released, in a previous pipeline. Java projects can't have
lock files. Python projects can have lock files, but GitLab Secure tools don't support them.
-## Security scans using Auto DevOps
-
-When using [Auto DevOps](../../../topics/autodevops/index.md), use
-[special environment variables](../../../topics/autodevops/customize.md#cicd-variables)
-to configure daily security scans.
-
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
diff --git a/doc/user/application_security/terminology/index.md b/doc/user/application_security/terminology/index.md
index c96497e9233..8277c30b81f 100644
--- a/doc/user/application_security/terminology/index.md
+++ b/doc/user/application_security/terminology/index.md
@@ -38,6 +38,12 @@ The different places in an application that are vulnerable to attack. Secure pro
search the attack surface during scans. Each product defines the attack surface differently. For
example, SAST uses files and line numbers, and DAST uses URLs.
+### Corpus
+
+The set of meaningful test cases that are generated while the fuzzer is running. Each meaningful
+test case produces new coverage in the tested program. It's advised to re-use the corpus and pass it
+to subsequent runs.
+
### CVE
Common Vulnerabilities and Exposures (CVE®) is a list of common identifiers for publicly known
@@ -142,6 +148,12 @@ A standard report format that Secure products comply with when creating JSON rep
Provides an overview of all the vulnerabilities for a project, group, or GitLab instance.
Vulnerabilities are only created from findings discovered on the project's default branch.
+### Seed corpus
+
+The set of test cases given as initial input to the fuzz target. This usually speeds up the fuzz
+target substantially. This can be either manually created test cases or auto-generated with the fuzz
+target itself from previous runs.
+
### Vendor
The party maintaining an analyzer. As such, a vendor is responsible for integrating a scanner into
diff --git a/doc/user/application_security/threat_monitoring/img/threat_monitoring_policy_alert_list_v13_12.png b/doc/user/application_security/threat_monitoring/img/threat_monitoring_policy_alert_list_v13_12.png
deleted file mode 100644
index e165c7e6ceb..00000000000
--- a/doc/user/application_security/threat_monitoring/img/threat_monitoring_policy_alert_list_v13_12.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/application_security/threat_monitoring/img/threat_monitoring_policy_alert_list_v14_3.png b/doc/user/application_security/threat_monitoring/img/threat_monitoring_policy_alert_list_v14_3.png
new file mode 100644
index 00000000000..a11a7fafc4a
--- /dev/null
+++ b/doc/user/application_security/threat_monitoring/img/threat_monitoring_policy_alert_list_v14_3.png
Binary files differ
diff --git a/doc/user/application_security/threat_monitoring/index.md b/doc/user/application_security/threat_monitoring/index.md
index 8cecb9c5929..79f202a6edb 100644
--- a/doc/user/application_security/threat_monitoring/index.md
+++ b/doc/user/application_security/threat_monitoring/index.md
@@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14707) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.9.
-The **Threat Monitoring** page provides metrics and policy management
+The **Threat Monitoring** page provides alerts and metrics
for the GitLab application runtime security features. You can access
these by navigating to your project's **Security & Compliance > Threat
Monitoring** page.
@@ -18,153 +18,7 @@ GitLab supports statistics for the following security features:
- [Container Network Policies](../../../topics/autodevops/stages.md#network-policy)
-## Container Network Policy
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32365) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.9.
-
-The **Container Network Policy** section provides packet flow metrics for
-your application's Kubernetes namespace. This section has the following
-prerequisites:
-
-- Your project contains at least one [environment](../../../ci/environments/index.md)
-- You've [installed Cilium](../../project/clusters/protect/container_network_security/quick_start_guide.md#use-the-cluster-management-template-to-install-cilium)
-- You've configured the [Prometheus service](../../project/integrations/prometheus.md#enabling-prometheus-integration)
-
-If you're using custom Helm values for Cilium, you must enable Hubble
-with flow metrics for each namespace by adding the following lines to
-your [Cilium values](../../project/clusters/protect/container_network_security/quick_start_guide.md#use-the-cluster-management-template-to-install-cilium):
-
-```yaml
-hubble:
- enabled: true
- metrics:
- enabled:
- - 'flow:sourceContext=namespace;destinationContext=namespace'
-```
-
-The **Container Network Policy** section displays the following information
-about your packet flow:
-
-- The total amount of the inbound and outbound packets
-- The proportion of packets dropped according to the configured
- policies
-- The per-second average rate of the forwarded and dropped packets
- accumulated over time window for the requested time interval
-
-If a significant percentage of packets is dropped, you should
-investigate it for potential threats by
-examining the Cilium logs:
-
-```shell
-kubectl -n gitlab-managed-apps logs -l k8s-app=cilium -c cilium-monitor
-```
-
-## Container Network Policy management
-
-> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3328) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.1.
-
-The **Threat Monitoring** page's **Policy** tab displays deployed
-network policies for all available environments. You can check a
-network policy's `yaml` manifest, its enforcement
-status, and create and edit deployed policies. This section has the
-following prerequisites:
-
-- Your project contains at least one [environment](../../../ci/environments/index.md)
-- You've [installed Cilium](../../project/clusters/protect/container_network_security/quick_start_guide.md#use-the-cluster-management-template-to-install-cilium)
-
-Network policies are fetched directly from the selected environment's
-deployment platform. Changes performed outside of this tab are
-reflected upon refresh.
-
-By default, the network policy list contains predefined policies in a
-disabled state. Once enabled, a predefined policy deploys to the
-selected environment's deployment platform and you can manage it like
-the regular policies.
-
-Note that if you're using [Auto DevOps](../../../topics/autodevops/index.md)
-and change a policy in this section, your `auto-deploy-values.yaml` file doesn't update. Auto DevOps
-users must make changes by following the
-[Container Network Policy documentation](../../../topics/autodevops/stages.md#network-policy).
-
-### Changing enforcement status
-
-To change a network policy's enforcement status:
-
-- Click the network policy you want to update.
-- Click the **Edit policy** button.
-- Click the **Policy status** toggle to update the selected policy.
-- Click the **Save changes** button to deploy network policy changes.
-
-Disabled network policies have the `network-policy.gitlab.com/disabled_by: gitlab` selector inside
-the `podSelector` block. This narrows the scope of such a policy and as a result it doesn't affect
-any pods. The policy itself is still deployed to the corresponding deployment namespace.
-
-### Container Network Policy editor
-
-> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3403) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.4.
-
-You can use the policy editor to create, edit, and delete policies.
-
-- To create a new policy, click the **New policy** button located in the **Policy** tab's header.
-- To edit an existing policy, click **Edit policy** in the selected policy drawer.
-
-The policy editor only supports the [CiliumNetworkPolicy](https://docs.cilium.io/en/v1.8/policy/)
-specification. Regular Kubernetes [NetworkPolicy](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#networkpolicy-v1-networking-k8s-io)
-resources aren't supported.
-
-The policy editor has two modes:
-
-- The visual _Rule_ mode allows you to construct and preview policy
- rules using rule blocks and related controls.
-- YAML mode allows you to enter a policy definition in `.yaml` format
- and is aimed at expert users and cases that the Rule mode doesn't
- support.
-
-You can use both modes interchangeably and switch between them at any
-time. If a YAML resource is incorrect, Rule mode is automatically
-disabled. You must use YAML mode to fix your policy before Rule mode
-is available again.
-
-Rule mode supports the following rule types:
-
-- [Labels](https://docs.cilium.io/en/v1.8/policy/language/#labels-based).
-- [Entities](https://docs.cilium.io/en/v1.8/policy/language/#entities-based).
-- [IP/CIDR](https://docs.cilium.io/en/v1.8/policy/language/#ip-cidr-based). Only
- the `toCIDR` block without `except` is supported.
-- [DNS](https://docs.cilium.io/en/v1.8/policy/language/#dns-based).
-- [Level 4](https://docs.cilium.io/en/v1.8/policy/language/#layer-4-examples)
- can be added to all other rules.
-
-Once your policy is complete, save it by pressing the **Save policy**
-button at the bottom of the editor. Existing policies can also be
-removed from the editor interface by clicking the **Delete policy**
-button at the bottom of the editor.
-
-### Configuring Network Policy Alerts
-
-> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3438) and [enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/287676) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.9.
-> - The feature flag was removed and the Threat Monitoring Alerts Project was [made generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/287676) in GitLab 14.0.
-
-You can use policy alerts to track your policy's impact. Alerts are only available if you've
-[installed](../../clusters/agent/repository.md)
-and [configured](../../clusters/agent/index.md#create-an-agent-record-in-gitlab)
-a Kubernetes Agent for this project.
-
-There are two ways to create policy alerts:
-
-- In the [policy editor UI](#container-network-policy-editor),
- by clicking **Add alert**.
-- In the policy editor's YAML mode, through the `metadata.annotations` property:
-
- ```yaml
- metadata:
- annotations:
- app.gitlab.com/alert: 'true'
- ```
-
-Once added, the UI updates and displays a warning about the dangers of too many alerts.
-
-### Container Network Policy Alert list
+## Container Network Policy Alert list
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3438) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.9.
@@ -184,7 +38,7 @@ the selector menu in the **Status** column to set the status for each alert:
By default, the list doesn't display resolved or dismissed alerts.
-![Policy Alert List](img/threat_monitoring_policy_alert_list_v13_12.png)
+![Policy Alert List](img/threat_monitoring_policy_alert_list_v14_3.png)
Clicking an alert's row opens the alert drawer, which shows more information about the alert. A user
can also create an incident from the alert and update the alert status in the alert drawer.
diff --git a/doc/user/application_security/vulnerabilities/index.md b/doc/user/application_security/vulnerabilities/index.md
index a727dc88ffc..9ebecc67704 100644
--- a/doc/user/application_security/vulnerabilities/index.md
+++ b/doc/user/application_security/vulnerabilities/index.md
@@ -37,7 +37,9 @@ A vulnerability's status can be one of the following:
| Detected | The default state for a newly discovered vulnerability. |
| Confirmed | A user has seen this vulnerability and confirmed it to be accurate. |
| Dismissed | A user has seen this vulnerability and dismissed it because it is not accurate or otherwise not to be resolved. |
-| Resolved | The vulnerability has been fixed and is no longer valid. |
+| Resolved | The vulnerability has been fixed or is no longer present. |
+
+Dismissed vulnerabilities are ignored if detected in subsequent scans. Resolved vulnerabilities that are reintroduced and detected by subsequent scans have a _new_ vulnerability record created. When an existing vulnerability is no longer detected in a project's `default` branch, you should change its status to Resolved. This ensures that if it is accidentally reintroduced in a future merge, it will be visible again as a new record. You can use the [Activity filter](../vulnerability_report/#activity-filter) to select all vulnerabilities that are no longer detected, and [change their status](../vulnerability_report#change-status-of-multiple-vulnerabilities).
## Change vulnerability status
diff --git a/doc/user/application_security/vulnerability_report/img/group_vulnerability_report_v14_2.png b/doc/user/application_security/vulnerability_report/img/group_vulnerability_report_v14_2.png
index 193efe9c386..44c689eda3e 100644
--- a/doc/user/application_security/vulnerability_report/img/group_vulnerability_report_v14_2.png
+++ b/doc/user/application_security/vulnerability_report/img/group_vulnerability_report_v14_2.png
Binary files differ
diff --git a/doc/user/application_security/vulnerability_report/img/project_security_dashboard_status_change_v14_2.png b/doc/user/application_security/vulnerability_report/img/project_security_dashboard_status_change_v14_2.png
index 056e051363d..a43340544ca 100644
--- a/doc/user/application_security/vulnerability_report/img/project_security_dashboard_status_change_v14_2.png
+++ b/doc/user/application_security/vulnerability_report/img/project_security_dashboard_status_change_v14_2.png
Binary files differ
diff --git a/doc/user/application_security/vulnerability_report/index.md b/doc/user/application_security/vulnerability_report/index.md
index c2c2e7459ba..8b811c62ec3 100644
--- a/doc/user/application_security/vulnerability_report/index.md
+++ b/doc/user/application_security/vulnerability_report/index.md
@@ -145,6 +145,17 @@ To change the status of vulnerabilities in the table:
![Project Vulnerability Report](img/project_security_dashboard_status_change_v14_2.png)
+### Change status of multiple vulnerabilities
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35816) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.9.
+
+You can change the status of multiple vulnerabilities at once:
+
+1. In the list of vulnerabilities, select the checkbox for each vulnerability you want to update.
+ To select all, select the checkbox in the table header.
+1. Above the table, select a new status.
+1. Click **Change status** to save.
+
## Export vulnerability details
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/213014) in the Security Center (previously known as the Instance Security Dashboard) and project-level Vulnerability Report (previously known as the Project Security Dashboard) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.0.
@@ -191,14 +202,3 @@ You can dismiss a vulnerability for the entire project:
1. Optional. Add a reason for the dismissal and select **Save comment**.
To undo this action, select a different status from the same menu.
-
-### Dismiss multiple vulnerabilities
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35816) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.9.
-
-You can dismiss multiple vulnerabilities at once:
-
-1. In the list of vulnerabilities, select the checkbox for each vulnerability you want to dismiss.
- To select all, select the checkbox in the table header.
-1. Above the table, select a dismissal reason.
-1. Select **Dismiss Selected**.
diff --git a/doc/user/clusters/agent/ci_cd_tunnel.md b/doc/user/clusters/agent/ci_cd_tunnel.md
index 09123fdd472..1ea5168f30c 100644
--- a/doc/user/clusters/agent/ci_cd_tunnel.md
+++ b/doc/user/clusters/agent/ci_cd_tunnel.md
@@ -4,40 +4,52 @@ group: Configure
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
---
-# CI/CD Tunnel
+# CI/CD Tunnel **(PREMIUM)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/327409) in GitLab 14.1.
-> - Pre-configured `KUBECONFIG` [added](https://gitlab.com/gitlab-org/gitlab/-/issues/324275) in GitLab 14.2.
+> - The pre-configured `KUBECONFIG` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/324275) in GitLab 14.2.
+> - The ability to authorize groups was [introduced](https://gitlab.com/groups/gitlab-org/-/epics/5784) in GitLab 14.3.
The CI/CD Tunnel enables users to access Kubernetes clusters from GitLab CI/CD jobs even if there is no network
connectivity between GitLab Runner and a cluster. GitLab Runner does not have to be running in the same cluster.
Only CI/CD jobs set in the configuration project can access one of the configured agents.
-Prerequisites:
+## Prerequisites
- A running [`kas` instance](index.md#set-up-the-kubernetes-agent-server).
- A [configuration repository](index.md#define-a-configuration-repository) with an Agent config file
installed (`.gitlab/agents/<agent-name>/config.yaml`).
- An [Agent record](index.md#create-an-agent-record-in-gitlab).
-- The agent is [installed in the cluster](index.md#install-the-agent-into-the-cluster).
+- The Agent [installed in the cluster](index.md#install-the-agent-into-the-cluster).
-If your project has one or more Agent records, a `KUBECONFIG` variable that is compatible with `kubectl` is provided to your CI/CD jobs. A separate context (`kubecontext`) is available for each configured Agent. By default, no context is selected.
+## Use the CI/CD Tunnel to run Kubernetes commands from GitLab CI/CD
+If your project has access to one or more Agent records available, its CI/CD
+jobs provide a `KUBECONFIG` variable compatible with `kubectl`.
+
+Also, each Agent has a separate context (`kubecontext`). By default,
+there isn't any context selected.
Contexts are named in the following format: `<agent-configuration-project-path>:<agent-name>`.
+To get the list of available contexts, run `kubectl config get-contexts`.
+
+## Example for a `kubectl` command using the CI/CD Tunnel
-To access your cluster from a CI/CD job through the tunnel:
+The following example shows a CI/CD job that runs a `kubectl` command using the CI/CD Tunnel.
+You can run any Kubernetes-specific commands similarly, such as `kubectl`, `helm`,
+`kpt`, and so on. To do so:
-1. In your `.gitlab-ci.yml` select the context for the agent you wish to use:
+1. Set your Agent's context in the first command with the format `<agent-configuration-project-path>:<agent-name>`.
+1. Run Kubernetes commands.
- ```yaml
- deploy:
- image:
- name: bitnami/kubectl:latest
- entrypoint: [""]
- script:
- - kubectl config use-context path/to/agent-configuration-project:your-agent-name
- - kubectl get pods
- ```
+For example:
-1. Execute `kubectl` commands directly against your cluster with this CI/CD job you just created.
+```yaml
+ deploy:
+ image:
+ name: bitnami/kubectl:latest
+ entrypoint: [""]
+ script:
+ - kubectl config use-context path/to/agent-configuration-project:your-agent-name
+ - kubectl get pods
+```
diff --git a/doc/user/clusters/agent/index.md b/doc/user/clusters/agent/index.md
index c59d2a1f61c..d2dc57c0849 100644
--- a/doc/user/clusters/agent/index.md
+++ b/doc/user/clusters/agent/index.md
@@ -20,7 +20,7 @@ tasks in a secure and cloud-native way. It enables:
- Pull-based GitOps deployments.
- [Inventory object](../../infrastructure/clusters/deploy/inventory_object.md) to keep track of objects applied to your cluster.
- Real-time access to API endpoints in a cluster.
-- Alert generation based on [Container network policy](../../application_security/threat_monitoring/index.md#container-network-policy).
+- Alert generation based on [Container network policy](../../application_security/policies/index.md#container-network-policy).
- [CI/CD Tunnel](ci_cd_tunnel.md) that enables users to access Kubernetes clusters from GitLab CI/CD jobs even if there is no network connectivity between GitLab Runner and a cluster.
Many more features are planned. Please review [our roadmap](https://gitlab.com/groups/gitlab-org/-/epics/3329)
@@ -77,6 +77,8 @@ The setup process involves a few steps to enable GitOps deployments:
1. [Install the Agent into the cluster](#install-the-agent-into-the-cluster).
1. [Create manifest files](#create-manifest-files).
+<i class="fa fa-youtube-play youtube" aria-hidden="true"></i> Watch a GitLab 14.2 [walking-through video](https://www.youtube.com/watch?v=XuBpKtsgGkE) with this process.
+
### Upgrades and version compatibility
As the GitLab Kubernetes Agent is a new product, we are constantly adding new features
@@ -104,7 +106,8 @@ To use the KAS:
### Define a configuration repository
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/259669) in GitLab 13.7, the Agent manifest configuration can be added to multiple directories (or subdirectories) of its repository.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/259669) in GitLab 13.7, the Agent manifest configuration can be added to multiple directories (or subdirectories) of its repository.
+> - Group authorization was [introduced](https://gitlab.com/groups/gitlab-org/-/epics/5784) in GitLab 14.3.
To configure an Agent, you need:
@@ -123,6 +126,7 @@ In your repository, add the Agent configuration file under:
Your `config.yaml` file specifies all configurations of the Agent, such as:
- The manifest projects to synchronize.
+- The groups that can access this Agent via the [CI/CD Tunnel](ci_cd_tunnel.md).
- The address of the `hubble-relay` for the Network Security policy integrations.
As an example, a minimal Agent configuration that sets up only the manifest
@@ -174,17 +178,14 @@ To perform a one-liner installation, run the command below. Make sure to replace
- `your-agent-token` with the token received from the previous step (identified as `secret` in the JSON output).
- `gitlab-kubernetes-agent` with the namespace you defined in the previous step.
- `wss://kas.gitlab.example.com` with the configured access of the Kubernetes Agent Server (KAS). For GitLab.com users, the KAS is available under `wss://kas.gitlab.com`.
+- `--agent-version=vX.Y.Z` with the latest released patch version matching your GitLab installation's major and minor versions. For example, for GitLab v13.9.0, use `--agent-version=v13.9.1`. You can find your GitLab version under the "Help/Help" menu.
```shell
-docker run --pull=always --rm registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/cli:stable generate --agent-token=your-agent-token --kas-address=wss://kas.gitlab.example.com --agent-version stable --namespace gitlab-kubernetes-agent | kubectl apply -f -
+docker run --pull=always --rm registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/cli:stable generate --agent-token=your-agent-token --kas-address=wss://kas.gitlab.example.com --agent-version=vX.Y.Z --namespace gitlab-kubernetes-agent | kubectl apply -f -
```
-Set `--agent-version` to the latest released patch version matching your
-GitLab installation's major and minor versions. For example, if you have
-GitLab v13.9.0, set `--agent-version=v13.9.1`.
-
WARNING:
-Version `stable` can be used to refer to the latest stable release at the time when the command runs. It's fine for
+`--agent-version stable` can be used to refer to the latest stable release at the time when the command runs. It's fine for
testing purposes but for production please make sure to specify a matching version explicitly.
To find out the various options the above Docker container supports, run:
@@ -287,7 +288,7 @@ spec:
containers:
- name: agent
# Make sure to specify a matching version for production
- image: "registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/agentk:stable"
+ image: "registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/agentk:vX.Y.Z
args:
- --token-file=/config/token
- --kas-address
@@ -383,29 +384,16 @@ Each time you push a change to a monitored manifest repository, the Agent logs t
#### Example manifest file
-This file creates an NGINX deployment.
+This file creates a minimal `ConfigMap`:
```yaml
-apiVersion: apps/v1
-kind: Deployment
+apiVersion: v1
+kind: ConfigMap
metadata:
- name: nginx-deployment
+ name: demo-map
namespace: gitlab-kubernetes-agent # Can be any namespace managed by you that the agent has access to.
-spec:
- selector:
- matchLabels:
- app: nginx
- replicas: 2
- template:
- metadata:
- labels:
- app: nginx
- spec:
- containers:
- - name: nginx
- image: nginx:1.14.2
- ports:
- - containerPort: 80
+data:
+ key: value
```
## Example projects
@@ -433,8 +421,8 @@ There are several components that work in concert for the Agent to generate the
- Enablement of [hubble-relay](https://docs.cilium.io/en/v1.8/concepts/overview/#hubble) on an
existing installation.
- One or more network policies through any of these options:
- - Use the [Container Network Policy editor](../../application_security/threat_monitoring/index.md#container-network-policy-editor) to create and manage policies.
- - Use an [AutoDevOps](../../application_security/threat_monitoring/index.md#container-network-policy-management) configuration.
+ - Use the [Container Network Policy editor](../../application_security/policies/index.md#container-network-policy-editor) to create and manage policies.
+ - Use an [AutoDevOps](../../application_security/policies/index.md#container-network-policy) configuration.
- Add the required labels and annotations to existing network policies.
- A configuration repository with [Cilium configured in `config.yaml`](repository.md#surface-network-security-alerts-from-cluster-to-gitlab)
diff --git a/doc/user/clusters/agent/repository.md b/doc/user/clusters/agent/repository.md
index a3a3e4c29b0..ea57ded3320 100644
--- a/doc/user/clusters/agent/repository.md
+++ b/doc/user/clusters/agent/repository.md
@@ -9,6 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/259669) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.7.
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3834) in GitLab 13.11, the Kubernetes Agent became available on GitLab.com.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/332227) in GitLab 14.0, the `resource_inclusions` and `resource_exclusions` attributes were removed and `reconcile_timeout`, `dry_run_strategy`, `prune`, `prune_timeout`, `prune_propagation_policy`, and `inventory_policy` attributes were added.
+> - The `ci_access` attribute was [introduced](https://gitlab.com/groups/gitlab-org/-/epics/5784) in GitLab 14.3.
WARNING:
This feature might not be available to you. Check the **version history** note above for details.
@@ -147,6 +148,40 @@ gitops:
- glob: '/**/*.yaml'
```
+## Authorize groups to use an Agent
+
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5784) in GitLab 14.3.
+
+If you use the same cluster across multiple projects, you can set up the CI/CD Tunnel
+to grant the Agent access to one or more groups. This way, all the projects that belong
+to the authorized groups can access the same Agent. This enables you to save resources and
+have a scalable setup.
+
+When you authorize a group, the agent's Kubernetes context is automatically injected
+into every project of the authorized group, and users can select the connection as
+described in the [CI/CD Tunnel documentation](ci_cd_tunnel.md).
+To authorize a group to access the Agent through the [CI/CD Tunnel](ci_cd_tunnel.md),
+use the `ci_access` attribute in your `config.yaml` configuration file.
+
+An Agent can only authorize groups in the same group hierarchy as the Agent's configuration project. At most
+100 groups can be authorized per Agent.
+
+To authorize a group:
+
+1. Edit your `.config.yaml` file under the `.gitlab/agents/<agent name>` directory.
+1. Add the `ci_access` attribute.
+1. Add the `groups` attribute into `ci_access`.
+1. Add the group `id` into `groups`, identifying the authorized group through its path.
+
+For example:
+
+```yaml
+ci_access:
+ # This agent is accessible from CI jobs in projects in these groups
+ groups:
+ - id: group/subgroup
+```
+
## Surface network security alerts from cluster to GitLab
The GitLab Agent provides an [integration with Cilium](index.md#kubernetes-network-security-alerts).
diff --git a/doc/user/clusters/applications.md b/doc/user/clusters/applications.md
index 5d247f04d3b..2da8396cfd7 100644
--- a/doc/user/clusters/applications.md
+++ b/doc/user/clusters/applications.md
@@ -285,10 +285,10 @@ postgresql:
```
Support for installing the Sentry managed application is provided by the
-GitLab Health group. If you run into unknown issues,
+GitLab Monitor group. If you run into unknown issues,
[open a new issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new), and ping at
least 2 people from the
-[Health group](https://about.gitlab.com/handbook/product/categories/#health-group).
+[Monitor group](https://about.gitlab.com/handbook/product/categories/#monitor-group).
### Install PostHog using GitLab CI/CD
@@ -366,9 +366,9 @@ project. Refer to the
of the Prometheus chart's README for the available configuration options.
Support for installing the Prometheus managed application is provided by the
-GitLab APM group. If you run into unknown issues,
+GitLab Monitor group. If you run into unknown issues,
[open a new issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new), and ping at
-least 2 people from the [APM group](https://about.gitlab.com/handbook/product/categories/#apm-group).
+least 2 people from the [Monitor group](https://about.gitlab.com/handbook/product/categories/#monitor-group).
### Install GitLab Runner using GitLab CI/CD
@@ -819,9 +819,9 @@ management project. Refer to the
available configuration options.
Support for installing the Elastic Stack managed application is provided by the
-GitLab APM group. If you run into unknown issues,
+GitLab Monitor group. If you run into unknown issues,
[open a new issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new), and ping at
-least 2 people from the [APM group](https://about.gitlab.com/handbook/product/categories/#apm-group).
+least 2 people from the [Monitor group](https://about.gitlab.com/handbook/product/categories/#monitor-group).
### Install Crossplane using GitLab CI/CD
diff --git a/doc/user/clusters/environments.md b/doc/user/clusters/environments.md
index cb721115e76..cad55f0cf0b 100644
--- a/doc/user/clusters/environments.md
+++ b/doc/user/clusters/environments.md
@@ -36,7 +36,7 @@ In order to:
[deploy to a Kubernetes cluster](../project/clusters/index.md#deploying-to-a-kubernetes-cluster)
successfully.
- Show pod usage correctly, you must
- [enable Deploy Boards](../project/deploy_boards.md#enabling-deploy-boards).
+ [enable deploy boards](../project/deploy_boards.md#enabling-deploy-boards).
After you have successful deployments to your group-level or instance-level cluster:
diff --git a/doc/user/clusters/img/advanced-settings-cluster-management-project-v12_5.png b/doc/user/clusters/img/advanced-settings-cluster-management-project-v12_5.png
deleted file mode 100644
index 5fd1bac5e05..00000000000
--- a/doc/user/clusters/img/advanced-settings-cluster-management-project-v12_5.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/clusters/integrations.md b/doc/user/clusters/integrations.md
index 5e6843144fc..70f940c775b 100644
--- a/doc/user/clusters/integrations.md
+++ b/doc/user/clusters/integrations.md
@@ -33,9 +33,6 @@ You can integrate your Kubernetes cluster with
[Prometheus](https://prometheus.io/) for monitoring key metrics of your
apps directly from the GitLab UI.
-[Alerts](../../operations/metrics/alerts.md) can be configured the same way as
-for [external Prometheus instances](../../operations/metrics/alerts.md#external-prometheus-instances).
-
Once enabled, you can see metrics from services available in the
[metrics library](../project/integrations/prometheus_library/index.md).
diff --git a/doc/user/clusters/management_project.md b/doc/user/clusters/management_project.md
index 204afa9fc89..ca6843f6fde 100644
--- a/doc/user/clusters/management_project.md
+++ b/doc/user/clusters/management_project.md
@@ -32,28 +32,30 @@ Management projects are restricted to the following:
group (or descendants) as the cluster's group.
- For instance-level clusters, there are no such restrictions.
-## Usage
+## How to create and configure a cluster management project
-To use a cluster management project for a cluster:
+To use a cluster management project to manage your cluster:
-1. Select the project.
-1. Configure your pipelines.
-1. Set an environment scope.
+1. Create a new project to serve as the cluster management project
+for your cluster. We recommend that you
+[create this project based on the Cluster Management project template](management_project_template.md#create-a-new-project-based-on-the-cluster-management-template).
+1. [Associate the cluster with the management project](#associate-the-cluster-management-project-with-the-cluster).
+1. [Configure your cluster's pipelines](#configuring-your-pipeline).
+1. [Set the environment scope](#setting-the-environment-scope).
-### Selecting a cluster management project
+### Associate the cluster management project with the cluster
-To select a cluster management project to use:
+To associate a cluster management project with your cluster:
1. Navigate to the appropriate configuration page. For a:
- [Project-level cluster](../project/clusters/index.md), go to your project's
**Infrastructure > Kubernetes clusters** page.
- [Group-level cluster](../group/clusters/index.md), go to your group's **Kubernetes**
page.
- - [Instance-level cluster](../instance/clusters/index.md), go to **Menu >** **{admin}** **Admin > Kubernetes** page.
-1. Select the project using **Cluster management project field** in the **Advanced settings**
- section.
-
-![Selecting a cluster management project under Advanced settings](img/advanced-settings-cluster-management-project-v12_5.png)
+ - [Instance-level cluster](../instance/clusters/index.md), on the top bar, select **Menu > Admin > Kubernetes**.
+1. Expand **Advanced settings**.
+1. From the **Cluster management project** dropdown, select the cluster management project
+you created in the previous step.
### Configuring your pipeline
diff --git a/doc/user/clusters/management_project_template.md b/doc/user/clusters/management_project_template.md
index 1de17396bf4..9e2b00a0f54 100644
--- a/doc/user/clusters/management_project_template.md
+++ b/doc/user/clusters/management_project_template.md
@@ -4,35 +4,68 @@ group: Configure
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
---
-# Cluster Management Project Template **(FREE)**
+# Cluster Management project template **(FREE)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25318) in GitLab 12.10 with Helmfile support via Helm v2.
-> - [Improved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63577) in GitLab 14.0 with Helmfile support via Helm v3 instead, and a much more flexible usage of Helmfile. This introduces breaking changes that are detailed below.
+> - Helm v2 support was [dropped](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63577) in GitLab 14.0. Use Helm v3 instead.
-This [GitLab built-in project template](../project/working_with_projects.md#built-in-templates)
-provides a quicker start for users interested in managing cluster
-applications via [Helm v3](https://helm.sh/) charts. More specifically, taking advantage of the
-[Helmfile](https://github.com/roboll/helmfile) utility client. The template consists of some pre-configured apps that
-should help you get started quickly using various GitLab features. Still, you have all the flexibility to remove the ones you do not
-need, or even add new ones that are not built-in.
+With a [cluster management project](management_project.md) you can manage
+your cluster's deployment and applications through a repository in GitLab.
-## How to use this template
+The Custer Management project template provides you a baseline to get
+started and flexibility to customize your project to your cluster's needs.
+For instance, you can:
-1. Create a new project, choosing "GitLab Cluster Management" from the list of [built-in project templates](../project/working_with_projects.md#built-in-templates).
-1. Make this project a [cluster management project](management_project.md).
-1. If you used the [GitLab Managed Apps](applications.md), refer to
- [Migrating from GitLab Managed Apps](migrating_from_gma_to_project_template.md).
+- Extend the CI/CD configuration.
+- Configure the built-in cluster applications.
+- Remove the built-in cluster applications you don't need.
+- Add other cluster applications using the same structure as the ones already available.
-### Components
+The template contains the following [components](#available-components):
-In the repository of the newly-created project, you will find:
+- A pre-configured GitLab CI/CD file so that you can configure deployment pipelines.
+- A pre-configured [Helmfile](https://github.com/roboll/helmfile) so that
+you can manage cluster applications with [Helm v3](https://helm.sh/).
+- An `applications` directory with a `helmfile.yaml` configured for each
+application available in the template.
-- A predefined [`.gitlab-ci.yml`](https://gitlab.com/gitlab-org/project-templates/cluster-management/-/blob/master/.gitlab-ci.yml)
- file, with a CI pipeline already configured.
-- A main [`helmfile.yaml`](https://gitlab.com/gitlab-org/project-templates/cluster-management/-/blob/master/helmfile.yaml) to toggle which applications you would like to manage.
-- An `applications` directory with a `helmfile.yaml` configured for each application GitLab provides.
+WARNING:
+If you used [GitLab Managed Apps](applications.md) to manage your
+cluster from GitLab, see how to [migrate from GitLab Managed Apps](migrating_from_gma_to_project_template.md) to the Cluster Management
+project.
-#### The `.gitlab-ci.yml` file
+## Set up the management project from the Cluster Management project template
+
+To set up your cluster's management project off of the Cluster Management project template:
+
+1. [Create a new project based on the Cluster Management template](#create-a-new-project-based-on-the-cluster-management-template).
+1. [Associate the cluster management project with your cluster](management_project.md#associate-the-cluster-management-project-with-the-cluster).
+1. Use the [available components](#available-components) to manage your cluster.
+
+### Create a new project based on the Cluster Management template
+
+To get started, create a new project based on the Cluster Management
+project template to use as a cluster management project.
+
+You can either create the [new project](../project/working_with_projects.md#create-a-project)
+from the template or import the project from the URL. Importing
+the project is useful if you are using a GitLab self-managed
+instance that may not have the latest version of the template.
+
+To create the new project:
+
+- From the template: select the **GitLab Cluster Management** project template.
+- Importing from the URL: use `https://gitlab.com/gitlab-org/project-templates/cluster-management.git`.
+
+## Available components
+
+Use the available components to configure your cluster:
+
+- [A `.gitlab-ci.yml` file](#the-gitlab-ciyml-file).
+- [A main `helmfile.yml` file](#the-main-helmfileyml-file).
+- [A directory with built-in applications](#built-in-applications).
+
+### The `.gitlab-ci.yml` file
The base image used in your pipeline is built by the [cluster-applications](https://gitlab.com/gitlab-org/cluster-integration/cluster-applications)
project. This image consists of a set of Bash utility scripts to support [Helm v3 releases](https://helm.sh/docs/intro/using_helm/#three-big-concepts):
@@ -48,23 +81,21 @@ project. This image consists of a set of Bash utility scripts to support [Helm v
facilitate the GitLab Managed Apps adoption.
- `gl-helmfile {arguments}`: A thin wrapper that triggers the [Helmfile](https://github.com/roboll/helmfile) command.
-#### The main `helmfile.yml` file
+### The main `helmfile.yml` file
This file has a list of paths to other Helmfiles for each app. They're all commented out by default, so you must uncomment
-the paths for the apps that you would like to manage.
+the paths for the apps that you would like to use in your cluster.
-By default, each `helmfile.yaml` in these sub-paths have the attribute `installed: true`. This signifies that every time
+By default, each `helmfile.yaml` in these sub-paths has the attribute `installed: true`. This means that every time
the pipeline runs, Helmfile tries to either install or update your apps according to the current state of your
cluster and Helm releases. If you change this attribute to `installed: false`, Helmfile tries try to uninstall this app
from your cluster. [Read more](https://github.com/roboll/helmfile) about how Helmfile works.
-Furthermore, each app has an `applications/{app}/values.yaml` file. This is the
-place where you can define some default values for your app's Helm chart. Some apps already have defaults
+Furthermore, each app has an `applications/{app}/values.yaml` file (`applicaton/{app}/values.yaml.gotmpl` in case of GitLab Runner). This is the
+place where you can define default values for your app's Helm chart. Some apps already have defaults
pre-defined by GitLab.
-#### Built-in applications
-
-The built-in applications are intended to provide an easy way to get started with various Kubernetes oriented GitLab features.
+### Built-in applications
The [built-in supported applications](https://gitlab.com/gitlab-org/project-templates/cluster-management/-/tree/master/applications) are:
@@ -79,8 +110,3 @@ The [built-in supported applications](https://gitlab.com/gitlab-org/project-temp
- [Prometheus](../infrastructure/clusters/manage/management_project_applications/prometheus.md)
- [Sentry](../infrastructure/clusters/manage/management_project_applications/sentry.md)
- [Vault](../infrastructure/clusters/manage/management_project_applications/vault.md)
-
-### Migrate from GitLab Managed Apps
-
-If you had GitLab Managed Apps, either One-Click or CI/CD install, read the docs on how to
-[migrate from GitLab Managed Apps to project template](migrating_from_gma_to_project_template.md)
diff --git a/doc/user/clusters/migrating_from_gma_to_project_template.md b/doc/user/clusters/migrating_from_gma_to_project_template.md
index dc16cf5cc45..2da058fb5bc 100644
--- a/doc/user/clusters/migrating_from_gma_to_project_template.md
+++ b/doc/user/clusters/migrating_from_gma_to_project_template.md
@@ -4,13 +4,24 @@ group: Configure
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
---
-# Migrating from GitLab Managed Apps to a management project template
+# Migrate from GitLab Managed Apps to Cluster Management Projects
-The [GitLab Managed Apps](applications.md) are deprecated in GitLab 14.0. To migrate to the new way of managing them:
+The [GitLab Managed Apps](applications.md) were deprecated in GitLab 14.0
+in favor of [Cluster Management Projects](management_project.md).
+Managing your cluster applications through a project enables you a
+lot more flexibility to manage your cluster than through the late GitLab Managed Apps.
+To migrate to the cluster management project you need
+[GitLab Runners](../../ci/runners/index.md)
+available and be familiar with [Helm](https://helm.sh/).
-1. Read how the [management project template](management_project_template.md) works, and
- create a new project based on the "GitLab Cluster Management" template.
-1. Create a new project as explained in the [management project template](management_project_template.md).
+## Migrate to a Cluster Management Project
+
+To migrate from GitLab Managed Apps to a Cluster Management Project,
+follow the steps below.
+See also [video walk-throughs](#video-walk-throughs) with examples.
+
+1. Create a new project based on the [Cluster Management Project template](management_project_template.md#create-a-new-project-based-on-the-cluster-management-template).
+1. [Associate your new Cluster Management Project with your cluster](management_project.md#associate-the-cluster-management-project-with-the-cluster).
1. Detect apps deployed through Helm v2 releases by using the pre-configured [`.gitlab-ci.yml`](management_project_template.md#the-gitlab-ciyml-file) file:
- In case you had overwritten the default GitLab Managed Apps namespace, edit `.gitlab-ci.yml`,
and make sure the script is receiving the correct namespace as an argument:
@@ -80,6 +91,16 @@ The [GitLab Managed Apps](applications.md) are deprecated in GitLab 14.0. To mig
used in Helm v3. So, the only way to integrate it with this Cluster Management Project is to actually uninstall this app and accept the
chart version proposed in `applications/vault/values.yaml`.
+ - Cert-manager:
+ - For users on Kubernetes version 1.20 or above, the deprecated cert-manager v0.10 is no longer valid and
+ and the upgrade includes a breaking change. So we suggest that you [backup and uninstall cert-manager v0.10](#backup-and-uninstall-cert-manager-v010)
+ , and install cert-manager v1.4 instead. To install this version, uncomment the `applications/cert-manager-1-4/helmfile.yaml`
+ from the [`./helmfile.yaml`](management_project_template.md#the-main-helmfileyml-file).
+ This triggers a pipeline to install the new version.
+ - For users on Kubernetes versions lower than 1.20, you can stick to v0.10 by uncommenting
+ `applications/cert-manager/helmfile.yaml`
+ in your project's main Helmfile ([`./helmfile.yaml`](management_project_template.md#the-main-helmfileyml-file)).
+
1. After following all the previous steps, [run a pipeline manually](../../ci/pipelines/index.md#run-a-pipeline-manually)
and watch the `apply` job logs to see if any of your applications were successfully detected, installed, and whether they got any
unexpected updates.
@@ -93,3 +114,21 @@ The [GitLab Managed Apps](applications.md) are deprecated in GitLab 14.0. To mig
After getting a successful pipeline, repeat these steps for any other deployed apps
you want to manage with the Cluster Management Project.
+
+## Backup and uninstall cert-manager v0.10
+
+1. Follow the [official docs](https://docs.cert-manager.io/en/release-0.10/tasks/backup-restore-crds.html) on how to
+ backup your cert-manager v0.10 data.
+1. Uninstall cert-manager by editing the setting all the occurrences of `installed: true` to `installed: false` in the
+ `applications/cert-manager/helmfile.yaml` file.
+1. Search for any left-over resources by executing the following command `kubectl get Issuers,ClusterIssuers,Certificates,CertificateRequests,Orders,Challenges,Secrets,ConfigMaps -n gitlab-managed-apps | grep certmanager`.
+1. For each of the resources found in the previous step, delete them with `kubectl delete -n gitlab-managed-apps {ResourceType} {ResourceName}`.
+ For example, if you found a resource of type `ConfigMap` named `cert-manager-controller`, delete it by executing:
+ `kubectl delete configmap -n gitlab-managed-apps cert-manager-controller`.
+
+## Video walk-throughs
+
+You can watch these videos with examples on how to migrate from GMA to a Cluster Management project:
+
+- [Migrating from scratch using a brand new cluster management project](https://youtu.be/jCUFGWT0jS0). Also covers Helm v2 apps migration.
+- [Migrating from an existing GitLab managed apps CI/CD project](https://youtu.be/U2lbBGZjZmc).
diff --git a/doc/user/compliance/compliance_report/index.md b/doc/user/compliance/compliance_report/index.md
index c51636e33f5..d30cedfb3cd 100644
--- a/doc/user/compliance/compliance_report/index.md
+++ b/doc/user/compliance/compliance_report/index.md
@@ -14,17 +14,32 @@ Compliance report gives you the ability to see a group's merge request activity.
high-level view for all projects in the group. For example, code approved for merging into
production.
-To access compliance report for a group, go to **{shield}** **Security & Compliance > Compliance**
-on the group's menu.
+You can use the report to:
+
+- Get an overview of the latest merge request for each project.
+- See if merge requests were approved and by whom.
+- See merge request authors.
+- See the latest [CI/CD pipeline](../../../ci/pipelines/index.md) result for each merge request.
+
+## View the compliance report for a group
+
+Prerequisites:
+
+- You must be an administrator or have the Owner role for the group.
+
+To view the compliance report:
+
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Security & Compliance > Compliance**.
NOTE:
-Compliance report shows only the latest merge request on each project.
+The compliance report shows only the latest merge request on each project.
## Merge request drawer
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/299357) in GitLab 14.1.
-When you click on a row, a drawer is shown that provides further details about the merge
+When you select a row, a drawer is shown that provides further details about the merge
request:
- Project name and [compliance framework label](../../project/settings/index.md#compliance-frameworks),
@@ -36,22 +51,6 @@ request:
- A list of users that approved the merge request.
- The user that merged the merge request.
-## Use cases
-
-This feature is for people who care about the compliance status of projects within their group.
-
-You can use the report to:
-
-- Get an overview of the latest merge request for each project.
-- See if merge requests were approved and by whom.
-- See merge request authors.
-- See the latest [CI Pipeline](../../../ci/pipelines/index.md) result for each merge request.
-
-## Permissions
-
-- On [GitLab Ultimate](https://about.gitlab.com/pricing/) tier.
-- By **Administrators** and **Group Owners**.
-
## Approval status and separation of duties
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217939) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.3.
@@ -85,14 +84,23 @@ The data provides a comprehensive view with respect to merge commits. It include
merge request author, merge request ID, merge user, pipeline ID, group name, project name, and merge request approvers.
Depending on the merge strategy, the merge commit SHA can be a merge commit, squash commit, or a diff head commit.
-To download the Chain of Custody report, navigate to **{shield}** **Security & Compliance > Compliance** on the group's menu and click **List of all merge commits**
+To download the Chain of Custody report:
+
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Security & Compliance > Compliance**.
+1. Select **List of all merge commits**.
### Commit-specific Chain of Custody Report **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/267629) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.6.
-You can generate a commit-specific Chain of Custody report for a given commit SHA. To do so, select
-the dropdown next to the **List of all merge commits** button at the top of the compliance report.
+You can generate a commit-specific Chain of Custody report for a given commit SHA.
+
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Security & Compliance > Compliance**.
+1. At the top of the compliance report, to the right of **List of all merge commits**, select the down arrow (**{angle-down}**).
+1. Enter the merge commit SHA, and then select **Export commit custody report**.
+ SHA and then select **Export commit custody report**.
NOTE:
The Chain of Custody report download is a CSV file, with a maximum size of 15 MB.
diff --git a/doc/user/compliance/license_compliance/index.md b/doc/user/compliance/license_compliance/index.md
index e39a3f7111b..165150a58a1 100644
--- a/doc/user/compliance/license_compliance/index.md
+++ b/doc/user/compliance/license_compliance/index.md
@@ -40,7 +40,7 @@ compliance report is shown properly.
![License Compliance Widget](img/license_compliance_v13_0.png)
-You can click on a license to see more information.
+You can select a license to see more information.
When GitLab detects a **Denied** license, you can view it in the [license list](#license-list).
@@ -49,11 +49,20 @@ When GitLab detects a **Denied** license, you can view it in the [license list](
You can view and modify existing policies from the [policies](#policies) tab.
![Edit Policy](img/policies_maintainer_edit_v14_2.png)
+## License expressions
+
+GitLab has limited support for [composite licenses](https://spdx.github.io/spdx-spec/appendix-IV-SPDX-license-expressions/).
+License compliance can read multiple licenses, but always considers them combined using the `AND` operator. For example,
+if a dependency has two licenses, and one of them is allowed and the other is denied by the project [policy](#policies),
+GitLab evaluates the composite license as _denied_, as this is the safer option.
+The ability to support other license expression operators (like `OR`, `WITH`) is tracked
+in [this epic](https://gitlab.com/groups/gitlab-org/-/epics/6571).
+
## Supported languages and package managers
The following languages and package managers are supported.
-Java 8 and Gradle 1.x projects are not supported. The minimum supported version of Maven is 3.2.5.
+Gradle 1.x projects are not supported. The minimum supported version of Maven is 3.2.5.
| Language | Package managers | Notes |
|------------|----------------------------------------------------------------------------------------------|-------|
@@ -140,12 +149,12 @@ License Compliance can be configured using CI/CD variables.
| `ADDITIONAL_CA_CERT_BUNDLE` | no | Bundle of trusted CA certificates (currently supported in Pip, Pipenv, Maven, Gradle, Yarn, and npm projects). |
| `ASDF_JAVA_VERSION` | no | Version of Java to use for the scan. |
| `ASDF_NODEJS_VERSION` | no | Version of Node.js to use for the scan. |
-| `ASDF_PYTHON_VERSION` | no | Version of Python to use for the scan. |
+| `ASDF_PYTHON_VERSION` | no | Version of Python to use for the scan. [Configuration](#selecting-the-version-of-python) |
| `ASDF_RUBY_VERSION` | no | Version of Ruby to use for the scan. |
| `GRADLE_CLI_OPTS` | no | Additional arguments for the Gradle executable. If not supplied, defaults to `--exclude-task=test`. |
| `LICENSE_FINDER_CLI_OPTS` | no | Additional arguments for the `license_finder` executable. For example, if you have multiple projects in nested directories, you can update your `.gitlab-ci-yml` template to specify a recursive scan, like `LICENSE_FINDER_CLI_OPTS: '--recursive'`. |
-| `LM_JAVA_VERSION` | no | Version of Java. If set to `11`, Maven and Gradle use Java 11 instead of Java 8. |
-| `LM_PYTHON_VERSION` | no | Version of Python. If set to `3`, dependencies are installed using Python 3 instead of Python 2.7. |
+| `LM_JAVA_VERSION` | no | Version of Java. If set to `11`, Maven and Gradle use Java 11 instead of Java 8. [Configuration](#selecting-the-version-of-java) |
+| `LM_PYTHON_VERSION` | no | Version of Python. If set to `3`, dependencies are installed using Python 3 instead of Python 2.7. [Configuration](#selecting-the-version-of-python) |
| `MAVEN_CLI_OPTS` | no | Additional arguments for the `mvn` executable. If not supplied, defaults to `-DskipTests`. |
| `PIP_INDEX_URL` | no | Base URL of Python Package Index (default: `https://pypi.org/simple/`). |
| `SECURE_ANALYZERS_PREFIX` | no | Set the Docker registry base address to download the analyzer from. |
@@ -245,6 +254,12 @@ Alternatively, you can use a Java key store to verify the TLS connection. For in
generate a key store file, see the
[Maven Guide to Remote repository access through authenticated HTTPS](http://maven.apache.org/guides/mini/guide-repository-ssl.html).
+### Selecting the version of Java
+
+License Compliance uses Java 8 by default. You can specify a different Java version using `LM_JAVA_VERSION`.
+
+`LM_JAVA_VERSION` only accepts versions: 8, 11, 14, 15.
+
### Selecting the version of Python
> - [Introduced](https://gitlab.com/gitlab-org/security-products/license-management/-/merge_requests/36) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.0.
@@ -264,6 +279,8 @@ license_scanning:
LM_PYTHON_VERSION: 2
```
+`LM_PYTHON_VERSION` or `ASDF_PYTHON_VERSION` can be used to specify the desired version of Python. When both variables are specified `LM_PYTHON_VERSION` takes precedence.
+
### Custom root certificates for Python
You can supply a custom root certificate to complete TLS verification by using the
@@ -693,15 +710,16 @@ instance's administrator can manually update it with a [Rake task](../../../rake
The License list allows you to see your project's licenses and key
details about them.
-In order for the licenses to appear under the license list, the following
+For the licenses to appear under the license list, the following
requirements must be met:
1. The License Compliance CI job must be [configured](#configuration) for your project.
1. Your project must use at least one of the
[supported languages and package managers](#supported-languages-and-package-managers).
-Once everything is set, navigate to **Security & Compliance > License Compliance**
-in your project's sidebar, and the licenses are displayed, where:
+When everything is configured, on the left sidebar, select **Security & Compliance > License Compliance**.
+
+The licenses are displayed, where:
- **Name:** The name of the license.
- **Component:** The components which have this license.
@@ -741,8 +759,10 @@ license.
You can enable `License-Check` one of two ways:
-1. Navigate to your project's **Settings > General** and expand **Merge request approvals**.
-1. Click **Enable** or **Edit**.
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Settings > General**.
+1. Expand **Merge request approvals**.
+1. Select **Enable** or **Edit**.
1. Add or change the **Rule name** to `License-Check` (case sensitive).
![License Check Approver Rule](img/license-check_v13_4.png)
@@ -802,11 +822,11 @@ or using the appropriate [`ASDF_<tool>_VERSION`](https://asdf-vm.com/#/core-conf
activate the appropriate version.
For example, the following `.tool-versions` file activates version `12.16.3` of [Node.js](https://nodejs.org/)
-and version `2.7.2` of [Ruby](https://www.ruby-lang.org/).
+and version `2.7.4` of [Ruby](https://www.ruby-lang.org/).
```plaintext
nodejs 12.16.3
-ruby 2.7.2
+ruby 2.7.4
```
The next example shows how to activate the same versions of the tools mentioned above by using CI/CD variables defined in your
@@ -819,7 +839,7 @@ include:
license_scanning:
variables:
ASDF_NODEJS_VERSION: '12.16.3'
- ASDF_RUBY_VERSION: '2.7.2'
+ ASDF_RUBY_VERSION: '2.7.4'
```
A full list of variables can be found in [CI/CD variables](#available-cicd-variables).
diff --git a/doc/user/discussions/img/btn_new_issue_for_all_threads.png b/doc/user/discussions/img/btn_new_issue_for_all_threads.png
deleted file mode 100644
index b07267a011a..00000000000
--- a/doc/user/discussions/img/btn_new_issue_for_all_threads.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/discussions/img/create-new-issue_v14_3.png b/doc/user/discussions/img/create-new-issue_v14_3.png
new file mode 100644
index 00000000000..d76fed6cb42
--- /dev/null
+++ b/doc/user/discussions/img/create-new-issue_v14_3.png
Binary files differ
diff --git a/doc/user/discussions/img/new-issue-one-thread_v14_3.png b/doc/user/discussions/img/new-issue-one-thread_v14_3.png
new file mode 100644
index 00000000000..34d3a3be0a7
--- /dev/null
+++ b/doc/user/discussions/img/new-issue-one-thread_v14_3.png
Binary files differ
diff --git a/doc/user/discussions/img/new_issue_for_thread.png b/doc/user/discussions/img/new_issue_for_thread.png
deleted file mode 100644
index c7f0fd76844..00000000000
--- a/doc/user/discussions/img/new_issue_for_thread.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/discussions/index.md b/doc/user/discussions/index.md
index a1d8863710c..aa4e3ce6f49 100644
--- a/doc/user/discussions/index.md
+++ b/doc/user/discussions/index.md
@@ -13,7 +13,7 @@ GitLab encourages communication through comments, threads, and
There are two types of comments:
- A standard comment.
-- A comment in a thread, which has to be resolved.
+- A comment in a thread, which can be [resolved](#resolve-a-thread).
In a comment, you can enter [Markdown](../markdown.md) and use [quick actions](../project/quick_actions.md).
@@ -46,9 +46,9 @@ To add a commit diff comment:
1. To select a specific commit, on the merge request, select the **Commits** tab, select the commit
message. To view the latest commit, select the **Changes** tab.
-1. By the line you want to comment on, hover over the line number and select **{comment}**.
- You can select multiple lines by dragging the **{comment}** icon.
-1. Type your comment and select **Start a review** or **Add comment now**.
+1. By the line you want to comment on, hover over the line number and select **Comment** (**{comment}**).
+ You can select multiple lines by dragging the **Comment** (**{comment}**) icon.
+1. Enter your comment and select **Start a review** or **Add comment now**.
The comment is displayed on the merge request's **Discussions** tab.
@@ -164,12 +164,10 @@ from any device you're logged into.
You can assign an issue to a user who made a comment.
-1. In the comment, select the **More Actions** menu.
-1. Select **Assign to commenting user**.
-
-![Assign to commenting user](img/quickly_assign_commenter_v13_1.png)
-
-Select the button again to unassign the commenter.
+1. In the comment, select the **More Actions** (**{ellipsis_v}**) menu.
+1. Select **Assign to commenting user**:
+ ![Assign to commenting user](img/quickly_assign_commenter_v13_1.png)
+1. To unassign the commenter, select the button again.
## Create a thread by replying to a standard comment
@@ -184,13 +182,13 @@ Prerequisites:
To create a thread by replying to a comment:
-1. On the top right of the comment, select **{comment}** (**Reply to comment**).
+1. On the top right of the comment, select **Reply to comment** (**{comment}**).
![Reply to comment button](img/reply_to_comment_button.png)
The reply area is displayed.
-1. Type your reply.
+1. Enter your reply.
1. Select **Comment** or **Add comment now** (depending on where in the UI you are replying).
The top comment is converted to a thread.
@@ -206,7 +204,7 @@ Prerequisites:
To create a thread:
-1. Type a comment.
+1. Enter a comment.
1. Below the comment, to the right of the **Comment** button, select the down arrow (**{chevron-down}**).
1. From the list, select **Start thread**.
1. Select **Start thread** again.
@@ -218,16 +216,16 @@ A threaded comment is created.
## Resolve a thread
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/5022) in GitLab 8.11.
-> - Resolvable threads can be added only to merge request diffs.
> - Resolving comments individually was [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/28750) in GitLab 13.6.
-You can resolve a thread when you want to finish a conversation.
+In a merge request, you can resolve a thread when you want to finish a conversation.
Prerequisites:
- You must have at least the [Developer role](../permissions.md#project-members-permissions)
or be the author of the change being reviewed.
-- You must be in an issue, merge request, commit, or snippet.
+- Resolvable threads can be added only to merge requests. It doesn't work
+ for comments in issues, commits, or snippets.
To resolve a thread:
@@ -237,33 +235,30 @@ To resolve a thread:
- Below the last reply, in the **Reply** field, select **Resolve thread**.
- Below the last reply, in the **Reply** field, enter text, select the **Resolve thread** checkbox, and select **Add comment now**.
-At the top of the page, the number of unresolved threads is updated.
+At the top of the page, the number of unresolved threads is updated:
![Count of unresolved threads](img/unresolved_threads_v14_1.png)
### Move all unresolved threads in a merge request to an issue
If you have multiple unresolved threads in a merge request, you can
-create an issue to resolve them separately.
+create an issue to resolve them separately. In the merge request, at the top of the page,
+select **Create issue to resolve all threads** (**{issue-new}**):
-- In the merge request, at the top of the page, select **Resolve all threads in new issue**.
+![Open new issue for all unresolved threads](img/create-new-issue_v14_3.png)
- ![Open new issue for all unresolved threads](img/btn_new_issue_for_all_threads.png)
-
-All threads are marked as resolved and a link is added from the merge request to
+All threads are marked as resolved, and a link is added from the merge request to
the newly created issue.
### Move one unresolved thread in a merge request to an issue
If you have one specific unresolved thread in a merge request, you can
-create an issue to resolve it separately.
-
-- In the merge request, under the last reply to the thread, next to the
- **Resolve thread** button, select **Resolve this thread in a new issue**.
+create an issue to resolve it separately. In the merge request, under the last reply
+to the thread, next to **Resolve thread**, select **Create issue to resolve thread** (**{issue-new}**):
- ![Create issue for thread](img/new_issue_for_thread.png)
+![Create issue for thread](img/new-issue-one-thread_v14_3.png)
-The thread is marked as resolved and a link is added from the merge request to
+The thread is marked as resolved, and a link is added from the merge request to
the newly created issue.
### Prevent merge unless all threads are resolved
diff --git a/doc/user/gitlab_com/index.md b/doc/user/gitlab_com/index.md
index 024ab86a1b7..23765de8f46 100644
--- a/doc/user/gitlab_com/index.md
+++ b/doc/user/gitlab_com/index.md
@@ -9,6 +9,19 @@ info: To determine the technical writer assigned to the Stage/Group associated w
This page contains information about the settings that are used on GitLab.com, available to
[GitLab SaaS](https://about.gitlab.com/pricing/) customers.
+## Password requirements
+
+GitLab.com has the following requirements for passwords on new accounts and password changes:
+
+- Minimum character length 8 characters.
+- Maximum character length 128 characters.
+- All characters are accepted. For example, `~`, `!`, `@`, `#`, `$`, `%`, `^`, `&`, `*`, `()`,
+ `[]`, `_`, `+`, `=`, and `-`.
+
+## SSH key restrictions
+
+GitLab.com uses the default [SSH key restrictions](../../security/ssh_keys_restrictions.md).
+
## SSH host keys fingerprints
Below are the fingerprints for SSH host keys on GitLab.com. The first time you
@@ -123,6 +136,7 @@ the related documentation.
| [Max jobs in active pipelines](../../administration/instance_limits.md#number-of-jobs-in-active-pipelines) | `500` for Free tier, unlimited otherwise | Unlimited |
| [Max CI/CD subscriptions to a project](../../administration/instance_limits.md#number-of-cicd-subscriptions-to-a-project) | `2` | Unlimited |
| [Max pipeline schedules in projects](../../administration/instance_limits.md#number-of-pipeline-schedules) | `10` for Free tier, `50` for all paid tiers | Unlimited |
+| [Max pipelines per schedule](../../administration/instance_limits.md#limit-the-number-of-pipelines-created-by-a-pipeline-schedule-per-day) | `24` for Free tier, `288` for all paid tiers | Unlimited |
| [Scheduled Job Archival](../../user/admin_area/settings/continuous_integration.md#archive-jobs) | 3 months | Never |
| Max test cases per [unit test report](../../ci/unit_test_reports.md) | `500_000` | Unlimited |
| [Max registered runners](../../administration/instance_limits.md#number-of-registered-runners-per-scope) | `50` per-project and per-group for Free tier,<br/>`1_000` per-group for all paid tiers / `1_000` per-project for all paid tiers | `1_000` per-group / `1_000` per-project |
@@ -292,7 +306,7 @@ endpoints](../../user/admin_area/settings/rate_limits_on_raw_endpoints.md).
For information on rate limiting responses, see:
- [List of headers on responses to blocked requests](../admin_area/settings/user_and_ip_rate_limits.md#response-headers).
-- [Customizable response text](../admin_area/settings/user_and_ip_rate_limits.md#response-text).
+- [Customizable response text](../admin_area/settings/user_and_ip_rate_limits.md#use-a-custom-rate-limit-response).
### Protected paths throttle
@@ -349,7 +363,7 @@ doesn't return the following headers:
### Visibility settings
If created before GitLab 12.2 (July 2019), these items have the
-[Internal visibility](../../public_access/public_access.md#internal-projects)
+[Internal visibility](../../public_access/public_access.md#internal-projects-and-groups)
setting [disabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/12388):
- Projects
diff --git a/doc/user/group/devops_adoption/img/group_devops_adoption_v14_2.png b/doc/user/group/devops_adoption/img/group_devops_adoption_v14_2.png
index 073e747153f..21e38907a10 100644
--- a/doc/user/group/devops_adoption/img/group_devops_adoption_v14_2.png
+++ b/doc/user/group/devops_adoption/img/group_devops_adoption_v14_2.png
Binary files differ
diff --git a/doc/user/group/devops_adoption/index.md b/doc/user/group/devops_adoption/index.md
index 5c84a343da9..554d01039ad 100644
--- a/doc/user/group/devops_adoption/index.md
+++ b/doc/user/group/devops_adoption/index.md
@@ -13,6 +13,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - Fuzz Testing metrics [added](https://gitlab.com/gitlab-org/gitlab/-/issues/330398) in GitLab 14.2.
> - Dependency Scanning metrics [added](https://gitlab.com/gitlab-org/gitlab/-/issues/328034) in GitLab 14.2.
> - Multiselect [added](https://gitlab.com/gitlab-org/gitlab/-/issues/333586) in GitLab 14.2.
+> - Overview table [added](https://gitlab.com/gitlab-org/gitlab/-/issues/335638) in GitLab 14.3.
Prerequisites:
diff --git a/doc/user/group/epics/epic_boards.md b/doc/user/group/epics/epic_boards.md
index 34eebfb9e3b..d184030718a 100644
--- a/doc/user/group/epics/epic_boards.md
+++ b/doc/user/group/epics/epic_boards.md
@@ -4,7 +4,7 @@ group: Product Planning
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
---
-# Epic Boards **(PREMIUM)**
+# Epic boards **(PREMIUM)**
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5067) in GitLab 13.10.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/290039) in GitLab 14.1.
@@ -54,7 +54,7 @@ Prerequisites:
To delete the active epic board:
-1. Select the dropdown with the current board name in the upper left corner of the Epic Boards page.
+1. Select the dropdown with the current board name in the upper left corner of the epic boards page.
1. Select **Delete board**.
1. Select **Delete**.
diff --git a/doc/user/group/epics/index.md b/doc/user/group/epics/index.md
index 24c78d169c4..68df71d1c5d 100644
--- a/doc/user/group/epics/index.md
+++ b/doc/user/group/epics/index.md
@@ -64,7 +64,7 @@ You can also consult the [group permissions table](../../permissions.md#group-me
## Related topics
- [Manage epics](manage_epics.md) and multi-level child epics.
-- Create workflows with [Epic Boards](epic_boards.md).
+- Create workflows with [epic boards](epic_boards.md).
- [Turn on notifications](../../profile/notifications.md) for about epic events.
- [Award an emoji](../../award_emojis.md) to an epic or its comments.
- Collaborate on an epic by posting comments in a [thread](../../discussions/index.md).
diff --git a/doc/user/group/import/index.md b/doc/user/group/import/index.md
index 721afa219d0..31c3a8e774e 100644
--- a/doc/user/group/import/index.md
+++ b/doc/user/group/import/index.md
@@ -77,7 +77,7 @@ Any other items are **not** migrated.
## Enable or disable GitLab Group Migration
-GitLab Migration is deployed behind a feature flag that is **disabled by default**.
+GitLab Migration is deployed behind a feature flag that is **enabled by default**.
[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md) can enable it.
To enable it:
diff --git a/doc/user/group/index.md b/doc/user/group/index.md
index 948f9cab659..caf874cfe28 100644
--- a/doc/user/group/index.md
+++ b/doc/user/group/index.md
@@ -82,6 +82,10 @@ To create a group:
- Underscores
- Dashes and dots (it cannot start with dashes or end in a dot)
1. Choose the [visibility level](../../public_access/public_access.md).
+1. Personalize your GitLab experience by answering the following questions:
+ - What is your role?
+ - Who will be using this group?
+ - What will you use this group for?
1. Invite GitLab members or other users to join the group.
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
@@ -263,7 +267,7 @@ These Group Activity Analytics can be enabled with the `group_activity_analytics
### View group activity
-You can view the most recent actions taken in a group.
+You can view the most recent actions taken in a group, either in your browser or in an RSS feed:
1. On the top bar, select **Menu > Groups**.
1. Select **Your Groups**.
@@ -312,7 +316,7 @@ In GitLab 13.11, you can optionally replace the sharing form with a modal window
To share a group after enabling this feature:
1. Go to your group's page.
-1. In the left sidebar, go to **Group information > Members**, and then select **Invite a group**.
+1. On the left sidebar, go to **Group information > Members**, and then select **Invite a group**.
1. Select a group, and select a **Max role**.
1. (Optional) Select an **Access expiration date**.
1. Select **Invite**.
@@ -664,16 +668,16 @@ Projects can be configured to be deleted either:
- Immediately.
- After a delayed interval. During this interval period, the projects are in a read-only state
- and can be restored, if required. The default interval period is seven days but
+ and can be restored. The default interval period is seven days but
[is configurable](../admin_area/settings/visibility_and_access_controls.md#default-deletion-delay).
-On:
+On self-managed GitLab, projects are deleted immediately by default.
+In GitLab 14.2 and later, an administrator can
+[change the default setting](../admin_area/settings/visibility_and_access_controls.md#default-delayed-project-deletion)
+for projects in newly-created groups.
-- GitLab self-managed instances, projects are deleted immediately by default. In GitLab
- 14.2 and later, an administrator can
- [change the default setting](../admin_area/settings/visibility_and_access_controls.md#default-delayed-project-deletion) for projects in newly-created groups.
-- GitLab.com, see [GitLab.com settings page](../gitlab_com/index.md#delayed-project-deletion) for
- the default setting.
+On GitLab.com, see the [GitLab.com settings page](../gitlab_com/index.md#delayed-project-deletion) for
+the default setting.
To enable delayed deletion of projects in a group:
@@ -750,7 +754,7 @@ The group's new subgroups have push rules set for them based on either:
- [Transfer a project into a group](../project/settings/index.md#transferring-an-existing-project-into-another-namespace).
- [Share a project with a group](../project/members/share_project_with_groups.md): Give all group members access to the project at once.
- [Lock the sharing with group feature](#prevent-a-project-from-being-shared-with-groups).
-- [Enforce two-factor authentication (2FA)](../../security/two_factor_authentication.md#enforcing-2fa-for-all-users-in-a-group): Enforce 2FA
+- [Enforce two-factor authentication (2FA)](../../security/two_factor_authentication.md#enforce-2fa-for-all-users-in-a-group): Enforce 2FA
for all group members.
- Namespaces [API](../../api/namespaces.md) and [Rake tasks](../../raketasks/features.md)..
diff --git a/doc/user/group/issues_analytics/index.md b/doc/user/group/issues_analytics/index.md
index 9240828db0a..3d28ef5306d 100644
--- a/doc/user/group/issues_analytics/index.md
+++ b/doc/user/group/issues_analytics/index.md
@@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Issue Analytics **(PREMIUM)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7478) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7478) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.5.
Issue Analytics is a bar graph which illustrates the number of issues created each month.
The default time span is 13 months, which includes the current month, and the 12 months
diff --git a/doc/user/group/iterations/index.md b/doc/user/group/iterations/index.md
index 5c4e66a4539..70fa3ba639d 100644
--- a/doc/user/group/iterations/index.md
+++ b/doc/user/group/iterations/index.md
@@ -110,7 +110,17 @@ Prerequisites:
- You must have at least the [Developer role](../../permissions.md) for a group.
-To edit an iteration, select the three-dot menu (**{ellipsis_v}**) > **Edit iteration**.
+To edit an iteration, select the three-dot menu (**{ellipsis_v}**) > **Edit**.
+
+## Delete an iteration
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/292268) in GitLab 14.3.
+
+Prerequisites:
+
+- You must have at least the [Developer role](../../permissions.md) for a group.
+
+To delete an iteration, select the three-dot menu (**{ellipsis_v}**) > **Delete**.
## Add an issue to an iteration
diff --git a/doc/user/group/repositories_analytics/index.md b/doc/user/group/repositories_analytics/index.md
index 054c6ab7a6b..685c4601ac4 100644
--- a/doc/user/group/repositories_analytics/index.md
+++ b/doc/user/group/repositories_analytics/index.md
@@ -16,7 +16,7 @@ This feature might not be available to you. Check the **version history** note a
## Current group code coverage
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/263478) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/263478) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.7.
The **Analytics > Repositories** group page displays the overall test coverage of all your projects in your group.
In the **Overall activity** section, you can see:
@@ -27,13 +27,13 @@ In the **Overall activity** section, you can see:
## Average group test coverage from the last 30 days
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/215140) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/215140) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.9.
The **Analytics > Repositories** group page displays the average test coverage of all your projects in your group in a graph for the last 30 days.
## Latest project test coverage list
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/267624) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/267624) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.6.
To see the latest code coverage for each project in your group:
diff --git a/doc/user/group/roadmap/img/epics_state_dropdown_v12_10.png b/doc/user/group/roadmap/img/epics_state_dropdown_v12_10.png
deleted file mode 100644
index c6d0b17455f..00000000000
--- a/doc/user/group/roadmap/img/epics_state_dropdown_v12_10.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/group/roadmap/img/epics_state_dropdown_v14_3.png b/doc/user/group/roadmap/img/epics_state_dropdown_v14_3.png
new file mode 100644
index 00000000000..171876e34a9
--- /dev/null
+++ b/doc/user/group/roadmap/img/epics_state_dropdown_v14_3.png
Binary files differ
diff --git a/doc/user/group/roadmap/img/roadmap_view_v13_2.png b/doc/user/group/roadmap/img/roadmap_view_v13_2.png
deleted file mode 100644
index 94cf2258569..00000000000
--- a/doc/user/group/roadmap/img/roadmap_view_v13_2.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/group/roadmap/img/roadmap_view_v14_3.png b/doc/user/group/roadmap/img/roadmap_view_v14_3.png
new file mode 100644
index 00000000000..ca4b87b9fdd
--- /dev/null
+++ b/doc/user/group/roadmap/img/roadmap_view_v14_3.png
Binary files differ
diff --git a/doc/user/group/roadmap/index.md b/doc/user/group/roadmap/index.md
index 811297c6eda..656c40d1915 100644
--- a/doc/user/group/roadmap/index.md
+++ b/doc/user/group/roadmap/index.md
@@ -32,7 +32,7 @@ When you hover over a milestone bar or title, a popover appears with its title,
date. You can also click the chevron (**{chevron-down}**) next to the **Milestones** heading to
toggle the list of the milestone bars.
-![roadmap view](img/roadmap_view_v13_2.png)
+![roadmap view](img/roadmap_view_v14_3.png)
## Sort and filter the Roadmap
@@ -52,7 +52,7 @@ filtering them by what's important for you.
A dropdown menu lets you show only open or closed epics. By default, all epics are shown.
-![epics state dropdown](img/epics_state_dropdown_v12_10.png)
+![epics state dropdown](img/epics_state_dropdown_v14_3.png)
You can sort epics in the Roadmap view by:
@@ -101,18 +101,38 @@ Feature.disable(:async_filtering)
> - Introduced in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.0.
> - In [GitLab 12.9](https://gitlab.com/gitlab-org/gitlab/-/issues/198062), Timelines were moved to the Premium tier.
-Roadmap supports the following date ranges:
+### Date range presets
-- Quarters
-- Months (default)
-- Weeks
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/204994) in GitLab 14.3. [Deployed behind the `roadmap_daterange_filter` flag](../../../administration/feature_flags.md), disabled by default.
+> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/323917) in GitLab 14.3.
+
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available per group,
+ask an administrator to [enable the `roadmap_daterange_filter` flag](../../../administration/feature_flags.md).
+On GitLab.com, this feature is available.
+The feature is ready for production use.
+
+Roadmap provides three date range options, each with predetermined timeline duration:
+
+- **This quarter**: includes weeks present in current quarter.
+- **This year**: includes weeks or months present in current year.
+- **Within 3 years**: includes weeks, months, or quarters present in the previous 18 months and
+ upcoming 18 months (that is, three years in total).
+
+### Layout presets
+
+Depending on selected [date range preset](#date-range-presets), Roadmap supports the following layout presets:
+
+- **Quarters**: only available when the "Within 3 years" date range is selected.
+- **Months**: available when either "This year" or "Within 3 years" date range is selected.
+- **Weeks** (default): available for all the date range presets.
### Quarters
![roadmap date range in quarters](img/roadmap_timeline_quarters.png)
In the **Quarters** preset, roadmap shows epics and milestones which have start or due dates
-**falling within** or **going through** past quarter, current quarter, and the next four quarters,
+**falling within** currently selected date range preset,
where **today**
is shown by the vertical red line in the timeline. The sub-headers underneath the quarter name on
the timeline header represent the month of the quarter.
@@ -123,7 +143,7 @@ the timeline header represent the month of the quarter.
In the **Months** preset, roadmap shows epics and milestones which have start or due dates
**falling within** or
-**going through** the past month, current month, and the next five months, where **today**
+**going through** currently selected date range preset, where **today**
is shown by the vertical red line in the timeline. The sub-headers underneath the month name on
the timeline header represent the date on starting day (Sunday) of the week. This preset is
selected by default.
@@ -133,7 +153,7 @@ selected by default.
![roadmap date range in weeks](img/roadmap_timeline_weeks.png)
In the **Weeks** preset, roadmap shows epics and milestones which have start or due dates **falling
-within** or **going through** the past week, current week and the next four weeks, where **today**
+within** or **going through** currently selected date range preset, where **today**
is shown by the vertical red line in the timeline. The sub-headers underneath the week name on
the timeline header represent the days of the week.
diff --git a/doc/user/group/saml_sso/index.md b/doc/user/group/saml_sso/index.md
index a627f04fa46..8f6b3e7244a 100644
--- a/doc/user/group/saml_sso/index.md
+++ b/doc/user/group/saml_sso/index.md
@@ -57,6 +57,7 @@ Once users have signed into GitLab using the SSO SAML setup, changing the `NameI
#### NameID Format
We recommend setting the NameID format to `Persistent` unless using a field (such as email) that requires a different format.
+Most NameID formats can be used, except `Transient` due to the temporary nature of this format.
### Assertions
@@ -120,6 +121,14 @@ SSO has the following effects when enabled:
- Users must be signed-in through SSO before they can pull images using the [Dependency Proxy](../../packages/dependency_proxy/index.md).
<!-- Add bullet for API activity when https://gitlab.com/gitlab-org/gitlab/-/issues/9152 is complete -->
+When SSO is enforced, users are not immediately revoked. If the user:
+
+- Is signed out, they cannot access the group after being removed from the identity provider.
+- Has an active session, they can continue accessing the group for up to 24 hours until the identity
+ provider session times out.
+
+When SCIM updates, the user's access is immediately revoked.
+
## Providers
The SAML standard means that a wide range of identity providers will work with GitLab. Your identity provider may have relevant documentation. It may be generic SAML documentation, or specifically targeted for GitLab.
@@ -140,13 +149,13 @@ Follow the Azure documentation on [configuring single sign-on to applications](h
For a demo of the Azure SAML setup including SCIM, see [SCIM Provisioning on Azure Using SAML SSO for Groups Demo](https://youtu.be/24-ZxmTeEBU). The video is outdated in regard to
objectID mapping and the [SCIM documentation should be followed](scim_setup.md#azure-configuration-steps).
-| GitLab Setting | Azure Field |
-|--------------|----------------|
-| Identifier | Identifier (Entity ID) |
-| Assertion consumer service URL | Reply URL (Assertion Consumer Service URL) |
-| GitLab single sign-on URL | Sign on URL |
-| Identity provider single sign-on URL | Login URL |
-| Certificate fingerprint | Thumbprint |
+| GitLab Setting | Azure Field |
+| ------------------------------------ | ------------------------------------------ |
+| Identifier | Identifier (Entity ID) |
+| Assertion consumer service URL | Reply URL (Assertion Consumer Service URL) |
+| GitLab single sign-on URL | Sign on URL |
+| Identity provider single sign-on URL | Login URL |
+| Certificate fingerprint | Thumbprint |
We recommend:
@@ -164,12 +173,12 @@ Please follow the Okta documentation on [setting up a SAML application in Okta](
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
For a demo of the Okta SAML setup including SCIM, see [Demo: Okta Group SAML & SCIM setup](https://youtu.be/0ES9HsZq0AQ).
-| GitLab Setting | Okta Field |
-|--------------|----------------|
-| Identifier | Audience URI |
-| Assertion consumer service URL | Single sign-on URL |
-| GitLab single sign-on URL | Login page URL (under **Application Login Page** settings) |
-| Identity provider single sign-on URL | Identity Provider Single Sign-On URL |
+| GitLab Setting | Okta Field |
+| ------------------------------------ | ---------------------------------------------------------- |
+| Identifier | Audience URI |
+| Assertion consumer service URL | Single sign-on URL |
+| GitLab single sign-on URL | Login page URL (under **Application Login Page** settings) |
+| Identity provider single sign-on URL | Identity Provider Single Sign-On URL |
Under Okta's **Single sign-on URL** field, check the option **Use this for Recipient URL and Destination URL**.
@@ -186,14 +195,14 @@ application.
If you decide to use the OneLogin generic [SAML Test Connector (Advanced)](https://onelogin.service-now.com/support?id=kb_article&sys_id=b2c19353dbde7b8024c780c74b9619fb&kb_category=93e869b0db185340d5505eea4b961934),
we recommend the ["Use the OneLogin SAML Test Connector" documentation](https://onelogin.service-now.com/support?id=kb_article&sys_id=93f95543db109700d5505eea4b96198f) with the following settings:
-| GitLab Setting | OneLogin Field |
-|--------------|----------------|
-| Identifier | Audience |
-| Assertion consumer service URL | Recipient |
-| Assertion consumer service URL | ACS (Consumer) URL |
+| GitLab Setting | OneLogin Field |
+| ------------------------------------------------ | ---------------------------- |
+| Identifier | Audience |
+| Assertion consumer service URL | Recipient |
+| Assertion consumer service URL | ACS (Consumer) URL |
| Assertion consumer service URL (escaped version) | ACS (Consumer) URL Validator |
-| GitLab single sign-on URL | Login URL |
-| Identity provider single sign-on URL | SAML 2.0 Endpoint |
+| GitLab single sign-on URL | Login URL |
+| Identity provider single sign-on URL | SAML 2.0 Endpoint |
Recommended `NameID` value: `OneLogin ID`.
@@ -281,10 +290,7 @@ If a user is already a member of the group, linking the SAML identity does not c
### Blocking access
-To rescind access to the group, perform the following steps, in order:
-
-1. Remove the user from the user data store on the identity provider or the list of users on the specific app.
-1. Remove the user from the GitLab.com group.
+Please refer to [Blocking access via SCIM](scim_setup.md#blocking-access).
### Unlinking accounts
@@ -305,7 +311,7 @@ For example, to unlink the `MyOrg` account:
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. In the left sidebar, select **Account**.
+1. On the left sidebar, select **Account**.
1. In the **Social sign-in** section, select **Disconnect** next to the connected account.
![Unlink Group SAML](img/unlink_group_saml.png)
@@ -331,7 +337,7 @@ Ensure your SAML identity provider sends an attribute statement named `Groups` o
NOTE:
To inspect the SAML response, you can use one of these [SAML debugging tools](#saml-debugging-tools).
-Also note that the value for `Groups` or `groups` in the SAML reponse can be either the group name or
+Also note that the value for `Groups` or `groups` in the SAML response can be either the group name or
the group ID depending what the IdP sends to GitLab.
When SAML SSO is enabled for the top-level group, `Maintainer` and `Owner` level users
@@ -352,10 +358,88 @@ the user gets the highest access level from the groups. For example, if one grou
is linked as `Guest` and another `Maintainer`, a user in both groups gets `Maintainer`
access.
-Users who are not members of any mapped SAML groups are removed from the GitLab group.
+### Automatic member removal
+
+After a group sync, users who are not members of a mapped SAML group are removed from
+the GitLab group.
+
+For example, in the following diagram:
-You can prevent accidental member removal. For example, if you have a SAML group link for `Owner` level access
-in a top-level group, you should also set up a group link for all other members.
+- Alex Garcia signs into GitLab and is removed from GitLab Group C because they don't belong
+ to SAML Group C.
+- Sidney Jones belongs to SAML Group C, but is not added to GitLab Group C because they have
+ not yet signed in.
+
+```mermaid
+graph TB
+ subgraph SAML users
+ SAMLUserA[Sidney Jones]
+ SAMLUserB[Zhang Wei]
+ SAMLUserC[Alex Garcia]
+ SAMLUserD[Charlie Smith]
+ end
+
+ subgraph SAML groups
+ SAMLGroupA["Group A"] --> SAMLGroupB["Group B"]
+ SAMLGroupA --> SAMLGroupC["Group C"]
+ SAMLGroupA --> SAMLGroupD["Group D"]
+ end
+
+ SAMLGroupB --> |Member|SAMLUserA
+ SAMLGroupB --> |Member|SAMLUserB
+
+ SAMLGroupC --> |Member|SAMLUserA
+ SAMLGroupC --> |Member|SAMLUserB
+
+ SAMLGroupD --> |Member|SAMLUserD
+ SAMLGroupD --> |Member|SAMLUserC
+```
+
+```mermaid
+graph TB
+ subgraph GitLab users
+ GitLabUserA[Sidney Jones]
+ GitLabUserB[Zhang Wei]
+ GitLabUserC[Alex Garcia]
+ GitLabUserD[Charlie Smith]
+ end
+
+ subgraph GitLab groups
+ GitLabGroupA["Group A (SAML configured)"] --> GitLabGroupB["Group B (SAML Group Link not configured)"]
+ GitLabGroupA --> GitLabGroupC["Group C (SAML Group Link configured)"]
+ GitLabGroupA --> GitLabGroupD["Group D (SAML Group Link configured)"]
+ end
+
+ GitLabGroupB --> |Member|GitLabUserA
+
+ GitLabGroupC --> |Member|GitLabUserB
+ GitLabGroupC --> |Member|GitLabUserC
+
+ GitLabGroupD --> |Member|GitLabUserC
+ GitLabGroupD --> |Member|GitLabUserD
+```
+
+```mermaid
+graph TB
+ subgraph GitLab users
+ GitLabUserA[Sidney Jones]
+ GitLabUserB[Zhang Wei]
+ GitLabUserC[Alex Garcia]
+ GitLabUserD[Charlie Smith]
+ end
+
+ subgraph GitLab groups after Alex Garcia signs in
+ GitLabGroupA[Group A]
+ GitLabGroupA["Group A (SAML configured)"] --> GitLabGroupB["Group B (SAML Group Link not configured)"]
+ GitLabGroupA --> GitLabGroupC["Group C (SAML Group Link configured)"]
+ GitLabGroupA --> GitLabGroupD["Group D (SAML Group Link configured)"]
+ end
+
+ GitLabGroupB --> |Member|GitLabUserA
+ GitLabGroupC --> |Member|GitLabUserB
+ GitLabGroupD --> |Member|GitLabUserC
+ GitLabGroupD --> |Member|GitLabUserD
+```
## Passwords for users created via SAML SSO for Groups
@@ -392,6 +476,9 @@ This can then be compared to the [NameID](#nameid) being sent by the identity pr
### Users receive a 404
+If you receive a `404` during setup when using "verify configuration", make sure you have used the correct
+[SHA-1 generated fingerprint](../../../integration/saml.md#notes-on-configuring-your-identity-provider).
+
If a user is trying to sign in for the first time and the GitLab single sign-on URL has not [been configured](#configuring-your-identity-provider), they may see a 404.
As outlined in the [user access section](#linking-saml-to-your-existing-gitlabcom-account), a group Owner will need to provide the URL to users.
@@ -403,17 +490,18 @@ If you do not wish to use that GitLab user with the SAML login, you can [unlink
### Message: "SAML authentication failed: User has already been taken"
-The user that you're signed in with already has SAML linked to a different identity.
+The user that you're signed in with already has SAML linked to a different identity, or the NameID value has changed.
Here are possible causes and solutions:
-| Cause | Solution |
-|------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| Cause | Solution |
+| ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| You've tried to link multiple SAML identities to the same user, for a given identity provider. | Change the identity that you sign in with. To do so, [unlink the previous SAML identity](#unlinking-accounts) from this GitLab account before attempting to sign in again. |
+| The NameID changes everytime the user requests SSO identification | Check the NameID is not set with `Transient` format, or the NameID is not changing on subsequent requests.|
### Message: "SAML authentication failed: Email has already been taken"
| Cause | Solution |
-|------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------|
+| ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| When a user account with the email address already exists in GitLab, but the user does not have the SAML identity tied to their account. | The user will need to [link their account](#user-access-and-management). |
### Message: "SAML authentication failed: Extern UID has already been taken, User has already been taken"
@@ -439,8 +527,8 @@ Alternatively, when users need to [link SAML to their existing GitLab.com accoun
### The NameID has changed
-| Cause | Solution |
-|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| Cause | Solution |
+| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| As mentioned in the [NameID](#nameid) section, if the NameID changes for any user, the user can be locked out. This is a common problem when an email address is used as the identifier. | Follow the steps outlined in the ["SAML authentication failed: User has already been taken"](#message-saml-authentication-failed-user-has-already-been-taken) section. |
### I need to change my SAML app
diff --git a/doc/user/group/saml_sso/scim_setup.md b/doc/user/group/saml_sso/scim_setup.md
index a0c281971fc..5e90501d487 100644
--- a/doc/user/group/saml_sso/scim_setup.md
+++ b/doc/user/group/saml_sso/scim_setup.md
@@ -58,7 +58,10 @@ During this configuration, note the following:
- The `Tenant URL` and `secret token` are the ones retrieved in the
[previous step](#gitlab-configuration).
- It is recommended to set a notification email and check the **Send an email notification when a failure occurs** checkbox.
-- For mappings, we will only leave `Synchronize Azure Active Directory Users to AppName` enabled.
+- For mappings, we only leave `Synchronize Azure Active Directory Users to AppName` enabled.
+ `Synchronize Azure Active Directory Groups to AppName` is usually disabled. However, this
+ does not mean Azure AD users cannot be provisioned in groups. Leaving it enabled does not break
+ the SCIM user provisioning, but causes errors in Azure AD that may be confusing and misleading.
You can then test the connection by clicking on **Test Connection**. If the connection is successful, be sure to save your configuration before moving on. See below for [troubleshooting](#troubleshooting).
@@ -69,13 +72,13 @@ Follow [Azure documentation to configure the attribute mapping](https://docs.mic
The following table below provides an attribute mapping known to work with GitLab. If
your SAML configuration differs from [the recommended SAML settings](index.md#azure-setup-notes),
modify the corresponding `customappsso` settings accordingly. If a mapping is not listed in the
-table, use the Azure defaults.
+table, use the Azure defaults. For a list of required attributes, refer to the [SCIM API documentation](../../../api/scim.md).
-| Azure Active Directory Attribute | `customappsso` Attribute | Matching precedence |
-| -------------------------------- | ---------------------- | -------------------- |
-| `objectId` | `externalId` | 1 |
-| `userPrincipalName` | `emails[type eq "work"].value` | |
-| `mailNickname` | `userName` | |
+| Azure Active Directory Attribute | `customappsso` Attribute | Matching precedence |
+| -------------------------------- | ------------------------------ | ------------------- |
+| `objectId` | `externalId` | 1 |
+| `userPrincipalName` | `emails[type eq "work"].value` | |
+| `mailNickname` | `userName` | |
For guidance, you can view [an example configuration in the troubleshooting reference](../../../administration/troubleshooting/group_saml_scim.md#azure-active-directory).
@@ -162,6 +165,12 @@ graph TD
B -->|Yes| D[GitLab sends message back 'Email exists']
```
+During provisioning:
+
+- Both primary and secondary emails are considered when checking whether a GitLab user account exists.
+- Duplicate usernames are also handled, by adding suffix `1` upon user creation. For example,
+ due to already existing `test_user` username, `test_user1` is used.
+
As long as [Group SAML](index.md) has been configured, existing GitLab.com users can link to their accounts in one of the following ways:
- By updating their *primary* email address in their GitLab.com user account to match their identity provider's user profile email address.
@@ -183,13 +192,12 @@ For role information, please see the [Group SAML page](index.md#user-access-and-
### Blocking access
-To rescind access to the group, remove the user from the identity
-provider or users list for the specific app.
-
-Upon the next sync, the user is deprovisioned, which means that the user is removed from the group.
+To rescind access to the top-level group, all sub-groups, and projects, remove or deactivate the user
+on the identity provider. SCIM providers generally update GitLab with the changes on demand, which
+is minutes at most. The user's membership is revoked and they immediately lose access.
NOTE:
-Deprovisioning does not delete the user account.
+Deprovisioning does not delete the GitLab user account.
```mermaid
graph TD
@@ -260,9 +268,9 @@ Alternatively, users can be removed from the SCIM app which de-links all removed
Changing the SAML or SCIM configuration or provider can cause the following problems:
-| Problem | Solution |
-|------------------------------------------------------------------------------|--------------------|
-| SAML and SCIM identity mismatch. | First [verify that the user's SAML NameId matches the SCIM externalId](#how-do-i-verify-users-saml-nameid-matches-the-scim-externalid) and then [update or fix the mismatched SCIM externalId and SAML NameId](#update-or-fix-mismatched-scim-externalid-and-saml-nameid). |
+| Problem | Solution |
+| ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| SAML and SCIM identity mismatch. | First [verify that the user's SAML NameId matches the SCIM externalId](#how-do-i-verify-users-saml-nameid-matches-the-scim-externalid) and then [update or fix the mismatched SCIM externalId and SAML NameId](#update-or-fix-mismatched-scim-externalid-and-saml-nameid). |
| SCIM identity mismatch between GitLab and the Identify Provider SCIM app. | You can confirm whether you're hitting the error because of your SCIM identity mismatch between your SCIM app and GitLab.com by using [SCIM API](../../../api/scim.md#update-a-single-scim-provisioned-user) which shows up in the `id` key and compares it with the user `externalId` in the SCIM app. You can use the same [SCIM API](../../../api/scim.md#update-a-single-scim-provisioned-user) to update the SCIM `id` for the user on GitLab.com. |
### Azure
diff --git a/doc/user/group/settings/import_export.md b/doc/user/group/settings/import_export.md
index a0930867b2a..516f3504a98 100644
--- a/doc/user/group/settings/import_export.md
+++ b/doc/user/group/settings/import_export.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
---
# Group import/export **(FREE)**
-> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2888) in GitLab 13.0 as an experimental feature. May change in future releases.
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2888) in GitLab 13.0 as an experimental feature. May change in future releases.
Existing groups running on any GitLab instance or GitLab.com can be exported with all their related data and moved to a
new GitLab instance.
@@ -22,7 +22,7 @@ See also:
Users with the [Owner role](../../permissions.md) for a group can enable
import and export for that group:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > General > Visibility and access controls**.
1. Scroll to **Import sources**.
1. Enable the desired **Import sources**.
@@ -69,7 +69,7 @@ Users with the [Owner role](../../permissions.md) for a group can export the
contents of that group:
1. On the top bar, select **Menu >** **Groups** and find your group.
-1. In the left sidebar, select **Settings**.
+1. On the left sidebar, select **Settings**.
1. Scroll to the **Advanced** section, and select **Export Group**.
1. After the export is generated, you should receive an email with a link to the [exported contents](#exported-contents)
in a compressed tar archive, with contents in NDJSON format.
diff --git a/doc/user/group/subgroups/index.md b/doc/user/group/subgroups/index.md
index 7d674b5deac..aaff0574ef0 100644
--- a/doc/user/group/subgroups/index.md
+++ b/doc/user/group/subgroups/index.md
@@ -88,7 +88,7 @@ The setting can be changed for any group by:
1. On the left sidebar, select **Settings > General**.
1. Expand the **Permissions, LFS, 2FA** section.
- An administrator:
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
+ 1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Groups**.
1. Select the group, and select **Edit**.
diff --git a/doc/user/group/value_stream_analytics/index.md b/doc/user/group/value_stream_analytics/index.md
index 4d254279a3d..68ae5e0df2d 100644
--- a/doc/user/group/value_stream_analytics/index.md
+++ b/doc/user/group/value_stream_analytics/index.md
@@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Value Stream Analytics **(PREMIUM)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196455) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.9 at the group level.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196455) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.9 for groups.
Value Stream Analytics measures the time spent to go from an
[idea to production](https://about.gitlab.com/blog/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/#from-idea-to-production-with-gitlab)
@@ -79,6 +79,9 @@ Data is shown for workflow items created during the selected date range. To filt
## How metrics are measured
+> DORA API-based deployment metrics [moved](https://gitlab.com/gitlab-org/gitlab/-/issues/337256)
+> to Premium in GitLab 14.3 for group-level Value Stream Analytics.
+
The "Time" metrics near the top of the page are measured as follows:
- **Lead time**: median time from issue created to issue closed.
@@ -113,7 +116,7 @@ Each stage of Value Stream Analytics is further described in the table below.
| **Stage** | **Description** |
| --------- | --------------- |
-| Issue | Measures the median time between creating an issue and taking action to solve it, by either labeling it or adding it to a milestone, whatever comes first. The label is tracked only if it already has an [Issue Board list](../../project/issue_board.md) created for it. |
+| Issue | Measures the median time between creating an issue and taking action to solve it, by either labeling it or adding it to a milestone, whatever comes first. The label is tracked only if it already has an [issue board list](../../project/issue_board.md) created for it. |
| Plan | Measures the median time between the action you took for the previous stage, and pushing the first commit to the branch. The very first commit of the branch is the one that triggers the separation between **Plan** and **Code**, and at least one of the commits in the branch needs to contain the related issue number (for example, `#42`). If none of the commits in the branch mention the related issue number, it is not considered to the measurement time of the stage. |
| Code | Measures the median time between pushing a first commit (previous stage) and creating a merge request (MR) related to that commit. The key to keep the process tracked is to include the [issue closing pattern](../../project/issues/managing_issues.md#closing-issues-automatically) to the description of the merge request (for example, `Closes #xxx`, where `xxx` is the number of the issue related to this merge request). If the closing pattern is not present, then the calculation takes the creation time of the first commit in the merge request as the start time. |
| Test | Measures the median time to run the entire pipeline for that project. It's related to the time GitLab CI/CD takes to run every job for the commits pushed to that merge request defined in the previous stage. It is basically the start->finish time for all pipelines. |
@@ -136,7 +139,7 @@ To sum up, anything that doesn't follow [GitLab flow](../../../topics/gitlab_flo
Value Stream Analytics dashboard does not present any data for:
- Merge requests that do not close an issue.
-- Issues not labeled with a label present in the Issue Board or for issues not assigned a milestone.
+- Issues not labeled with a label present in the issue board or for issues not assigned a milestone.
- Staging stage, if the project has no [production environment](#how-the-production-environment-is-identified).
## How the production environment is identified
diff --git a/doc/user/index.md b/doc/user/index.md
index 8fc91ec95ea..d6eaad469c1 100644
--- a/doc/user/index.md
+++ b/doc/user/index.md
@@ -43,7 +43,7 @@ GitLab is a Git-based platform that integrates a great number of essential tools
- Hosting code in repositories with version control.
- Tracking proposals for new implementations, bug reports, and feedback with a
fully featured [Issue tracker](project/issues/index.md).
-- Organizing and prioritizing with [Issue Boards](project/issue_board.md).
+- Organizing and prioritizing with [issue boards](project/issue_board.md).
- Reviewing code in [Merge Requests](project/merge_requests/index.md) with live-preview changes per
branch with [Review Apps](../ci/review_apps/index.md).
- Building, testing, and deploying with built-in [Continuous Integration](../ci/index.md).
@@ -58,7 +58,7 @@ With GitLab Enterprise Edition, you can also:
- Improve collaboration with:
- [Merge Request Approvals](project/merge_requests/approvals/index.md).
- [Multiple Assignees for Issues](project/issues/multiple_assignees_for_issues.md).
- - [Multiple Issue Boards](project/issue_board.md#multiple-issue-boards).
+ - [Multiple issue boards](project/issue_board.md#multiple-issue-boards).
- Create formal relationships between issues with [linked issues](project/issues/related_issues.md).
- Use [Burndown Charts](project/milestones/burndown_and_burnup_charts.md) to track progress during a sprint or while working on a new version of their software.
- Leverage [Elasticsearch](../integration/elasticsearch.md) with [Advanced Search](search/advanced_search.md) for faster, more advanced code search across your entire GitLab instance.
@@ -66,7 +66,7 @@ With GitLab Enterprise Edition, you can also:
- [Mirror a repository](project/repository/repository_mirroring.md) from elsewhere on your local server.
- View your entire CI/CD pipeline involving more than one project with [Multiple-Project Pipelines](../ci/pipelines/multi_project_pipelines.md).
- [Lock files](project/file_lock.md) to prevent conflicts.
-- View the current health and status of each CI environment running on Kubernetes with [Deploy Boards](project/deploy_boards.md).
+- View the current health and status of each CI environment running on Kubernetes with [deploy boards](project/deploy_boards.md).
- Leverage continuous delivery method with [Canary Deployments](project/canary_deployments.md).
- Scan your code for vulnerabilities and [display them in merge requests](application_security/sast/index.md).
diff --git a/doc/user/infrastructure/clusters/connect/index.md b/doc/user/infrastructure/clusters/connect/index.md
new file mode 100644
index 00000000000..ada278292a9
--- /dev/null
+++ b/doc/user/infrastructure/clusters/connect/index.md
@@ -0,0 +1,126 @@
+---
+stage: Configure
+group: Configure
+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
+---
+
+# Connect a cluster to GitLab **(FREE)**
+
+You can create new or connect existing clusters to GitLab through different [levels](#cluster-levels),
+using different [methods](#methods-to-connect-a-cluster-to-gitlab).
+
+Before getting started:
+
+1. Check the [supported Kubernetes cluster versions](#supported-cluster-versions).
+1. Define the [cluster level](#cluster-levels) according to your case.
+
+After that:
+
+1. Choose the [method](#methods-to-connect-a-cluster-to-gitlab)
+to connect your cluster according to your case.
+1. [View your clusters](#view-your-clusters) connected to GitLab.
+
+## Methods to connect a cluster to GitLab
+
+GitLab offers three methods to connect existing and create new clusters:
+
+- **GitLab Kubernetes Agent**: the best solution to
+[connect existing clusters](#connect-existing-clusters-to-gitlab).
+- **Infrastructure as Code**: it's a broader infrastructure management
+toolset that includes managing your cluster. It's the recommended
+solution to [create a new cluster](#create-new-clusters-from-gitlab)
+from GitLab.
+- **Certificate-based method**: our first and legacy solution uses
+cluster certificates to connect your cluster to GitLab. It is no longer
+recommended for [security implications](#security-implications-for-clusters-connected-with-certificates).
+
+### Connect existing clusters to GitLab
+
+To safely connect and configure an existing cluster on the **project level**,
+we **recommend** using the [GitLab Kubernetes Agent](../../../clusters/agent/index.md).
+We are working to support [the Agent for connecting a cluster at the group level](https://gitlab.com/groups/gitlab-org/-/epics/5784).
+
+Alternatively, you can use [cluster certificates](../../../project/clusters/add_existing_cluster.md)
+to connect clusters in all levels (projects, group, instance). However,
+for [security implications](#security-implications-for-clusters-connected-with-certificates),
+we don't recommend using this method.
+
+### Create new clusters from GitLab
+
+To safely create new clusters from GitLab, use
+[Infrastructure as Code](../../iac/index.md#create-a-new-cluster-through-iac).
+
+The [certificate-based method to create a new cluster](../../../project/clusters/add_remove_clusters.md)
+is still available through the GitLab UI but was **deprecated** in GitLab 14.0.
+If possible, we don't recommend using this method.
+
+### Connect multiple clusters to a single project
+
+To connect multiple clusters to a single project in GitLab,
+we **recommend** using the [GitLab Kubernetes Agent](../../../clusters/agent/index.md).
+
+You can also use the [certificate-based method](../../../project/clusters/multiple_kubernetes_clusters.md),
+but, for [security implications](#security-implications-for-clusters-connected-with-certificates),
+we don't recommend using this method.
+
+## Cluster levels
+
+Choose your cluster's level according to its purpose:
+
+| Level | Purpose |
+|--|--|
+| [Project level](../../../project/clusters/index.md) | Use your cluster for a single project. |
+| [Group level](../../../group/clusters/index.md) | Use the same cluster across multiple projects within your group. |
+| [Instance level](../../../instance/clusters/index.md) **(FREE SELF)** | Use the same cluster across groups and projects within your instance. |
+
+## Supported cluster versions
+
+GitLab is committed to support at least two production-ready Kubernetes minor
+versions at any given time. We regularly review the versions we support, and
+provide a three-month deprecation period before we remove support of a specific
+version. The range of supported versions is based on the evaluation of:
+
+- The versions supported by major managed Kubernetes providers.
+- The versions [supported by the Kubernetes community](https://kubernetes.io/releases/version-skew-policy/#supported-versions).
+
+GitLab supports the following Kubernetes versions, and you can upgrade your
+Kubernetes version to any supported version at any time:
+
+- 1.19 (support ends on February 22, 2022)
+- 1.18 (support ends on November 22, 2021)
+- 1.17 (support ends on September 22, 2021)
+
+Some GitLab features may support versions outside the range provided here.
+
+## View your clusters
+
+To view the Kubernetes clusters connected to your project,
+group, or instance, open the cluster's page according to the
+[level](#cluster-levels) of your cluster.
+
+**Project-level clusters:**
+
+1. Go to your project's homepage.
+1. On the left sidebar, select **Infrastructure > Kubernetes clusters**.
+
+**Group-level clusters:**
+
+1. Go to your group's homepage.
+1. On the left sidebar, select **Kubernetes**.
+
+**Instance-level clusters:** **(FREE SELF)**
+
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Kubernetes**.
+
+## Security implications for clusters connected with certificates
+
+WARNING:
+The whole cluster security is based on a model where [developers](../../../permissions.md)
+are trusted, so **only trusted users should be allowed to control your clusters**.
+
+The use of cluster certificates to connect your cluster grants
+access to a wide set of functionalities needed to successfully
+build and deploy a containerized application. Bear in mind that
+the same credentials are used for all the applications running
+on the cluster.
diff --git a/doc/user/infrastructure/clusters/connect/new_gke_cluster.md b/doc/user/infrastructure/clusters/connect/new_gke_cluster.md
index 35af316d7ac..90044fa74e1 100644
--- a/doc/user/infrastructure/clusters/connect/new_gke_cluster.md
+++ b/doc/user/infrastructure/clusters/connect/new_gke_cluster.md
@@ -48,7 +48,7 @@ so that your credentials are not exposed through the code. To do so, follow the
1. On your computer, encode the JSON file to `base64` (replace `/path/to/sa-key.json` to the path to your key):
```shell
- base64 /path/to/sa-key.json | tr -d \\n`
+ base64 /path/to/sa-key.json | tr -d \\n
```
1. Use the output of this command as the `BASE64_GOOGLE_CREDENTIALS` environment variable in the next step.
diff --git a/doc/user/infrastructure/clusters/manage/management_project_applications/certmanager.md b/doc/user/infrastructure/clusters/manage/management_project_applications/certmanager.md
index 3bf79ea90c7..9ef7bd0f3ff 100644
--- a/doc/user/infrastructure/clusters/manage/management_project_applications/certmanager.md
+++ b/doc/user/infrastructure/clusters/manage/management_project_applications/certmanager.md
@@ -6,16 +6,21 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Install cert-manager with a cluster management project
-> [Introduced](https://gitlab.com/gitlab-org/project-templates/cluster-management/-/merge_requests/5) in GitLab 14.0.
+> - [Introduced](https://gitlab.com/gitlab-org/project-templates/cluster-management/-/merge_requests/5) in GitLab 14.0.
+> - Support for cert-manager v1.4 was [introduced](https://gitlab.com/gitlab-org/project-templates/cluster-management/-/merge_requests/69405) in GitLab 14.3.
Assuming you already have a [Cluster management project](../../../../../user/clusters/management_project.md) created from a
[management project template](../../../../../user/clusters/management_project_template.md), to install cert-manager you should
uncomment this line from your `helmfile.yaml`:
```yaml
- - path: applications/cert-manager/helmfile.yaml
+ - path: applications/cert-manager-1-4/helmfile.yaml
```
+NOTE:
+We kept the `- path: applications/cert-manager/helmfile.yaml` with cert-manager v0.10 to facilitate
+the [migration from GitLab Managed Apps to a cluster management project](../../../../clusters/migrating_from_gma_to_project_template.md).
+
cert-manager:
- Is installed by default into the `gitlab-managed-apps` namespace of your cluster.
@@ -24,7 +29,7 @@ cert-manager:
email address to be specified. The email address is used by Let's Encrypt to
contact you about expiring certificates and issues related to your account.
-The following configuration in your `applications/cert-manager/helmfile.yaml` is required to install cert-manager:
+To install cert-manager in your cluster, configure your `applications/cert-manager-1-4/helmfile.yaml` to:
```yaml
certManager:
@@ -48,9 +53,3 @@ You can customize the installation of cert-manager by defining a
management project. Refer to the
[chart](https://github.com/jetstack/cert-manager) for the
available configuration options.
-
-Support for installing the Cert Manager managed application is provided by the
-GitLab Configure group. If you run into unknown issues,
-[open a new issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new), and ping at
-least 2 people from the
-[Configure group](https://about.gitlab.com/handbook/product/categories/#configure-group).
diff --git a/doc/user/infrastructure/clusters/manage/management_project_applications/cilium.md b/doc/user/infrastructure/clusters/manage/management_project_applications/cilium.md
index 4e84f2c5ef4..c19bfbfb1b1 100644
--- a/doc/user/infrastructure/clusters/manage/management_project_applications/cilium.md
+++ b/doc/user/infrastructure/clusters/manage/management_project_applications/cilium.md
@@ -120,9 +120,3 @@ global:
enabled:
- 'flow:sourceContext=namespace;destinationContext=namespace'
```
-
-Support for installing the Cilium managed application is provided by the
-GitLab Container Security group. If you run into unknown issues,
-[open a new issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new), and ping at
-least 2 people from the
-[Container Security group](https://about.gitlab.com/handbook/product/categories/#container-security-group).
diff --git a/doc/user/infrastructure/clusters/manage/management_project_applications/elasticstack.md b/doc/user/infrastructure/clusters/manage/management_project_applications/elasticstack.md
index 3d2b3caf0af..dbde9bd90b0 100644
--- a/doc/user/infrastructure/clusters/manage/management_project_applications/elasticstack.md
+++ b/doc/user/infrastructure/clusters/manage/management_project_applications/elasticstack.md
@@ -27,8 +27,3 @@ You can customize the installation of Elastic Stack by updating the
management project. Refer to the
[chart](https://gitlab.com/gitlab-org/charts/elastic-stack) for all
available configuration options.
-
-Support for installing the Elastic Stack managed application is provided by the
-GitLab APM group. If you run into unknown issues,
-[open a new issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new), and ping at
-least 2 people from the [APM group](https://about.gitlab.com/handbook/product/categories/#apm-group).
diff --git a/doc/user/infrastructure/clusters/manage/management_project_applications/falco.md b/doc/user/infrastructure/clusters/manage/management_project_applications/falco.md
index dff0c3bd7bc..7bd2a4a5133 100644
--- a/doc/user/infrastructure/clusters/manage/management_project_applications/falco.md
+++ b/doc/user/infrastructure/clusters/manage/management_project_applications/falco.md
@@ -93,9 +93,3 @@ You can check these logs with the following command:
```shell
kubectl -n gitlab-managed-apps logs -l app=falco
```
-
-Support for installing the Falco managed application is provided by the
-GitLab Container Security group. If you run into unknown issues,
-[open a new issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new), and ping at
-least 2 people from the
-[Container Security group](https://about.gitlab.com/handbook/product/categories/#container-security-group).
diff --git a/doc/user/infrastructure/clusters/manage/management_project_applications/fluentd.md b/doc/user/infrastructure/clusters/manage/management_project_applications/fluentd.md
index bf05f8f87d8..c5de0511c2f 100644
--- a/doc/user/infrastructure/clusters/manage/management_project_applications/fluentd.md
+++ b/doc/user/infrastructure/clusters/manage/management_project_applications/fluentd.md
@@ -28,9 +28,3 @@ for the current development release of Fluentd for all available configuration o
The configuration chart link points to the current development release, which
may differ from the version you have installed. To ensure compatibility, switch
to the specific branch or tag you are using.
-
-Support for installing the Fluentd managed application is provided by the
-GitLab Container Security group. If you run into unknown issues,
-[open a new issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new), and ping at
-least 2 people from the
-[Container Security group](https://about.gitlab.com/handbook/product/categories/#container-security-group).
diff --git a/doc/user/infrastructure/clusters/manage/management_project_applications/ingress.md b/doc/user/infrastructure/clusters/manage/management_project_applications/ingress.md
index 4f17dbab11b..5ee26db754e 100644
--- a/doc/user/infrastructure/clusters/manage/management_project_applications/ingress.md
+++ b/doc/user/infrastructure/clusters/manage/management_project_applications/ingress.md
@@ -24,8 +24,3 @@ You can customize the installation of Ingress by updating the
management project. Refer to the
[chart](https://github.com/helm/charts/tree/master/stable/nginx-ingress)
for the available configuration options.
-
-Support for installing the Ingress managed application is provided by the GitLab Configure group.
-If you run into unknown issues, [open a new issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new),
-and ping at least 2 people from the
-[Configure group](https://about.gitlab.com/handbook/product/categories/#configure-group).
diff --git a/doc/user/infrastructure/clusters/manage/management_project_applications/prometheus.md b/doc/user/infrastructure/clusters/manage/management_project_applications/prometheus.md
index 19e6c76d133..3420f340c94 100644
--- a/doc/user/infrastructure/clusters/manage/management_project_applications/prometheus.md
+++ b/doc/user/infrastructure/clusters/manage/management_project_applications/prometheus.md
@@ -25,8 +25,3 @@ You can customize the installation of Prometheus by updating the
management project. Refer to the
[Configuration section](https://github.com/helm/charts/tree/master/stable/prometheus#configuration)
of the Prometheus chart's README for the available configuration options.
-
-Support for installing the Prometheus managed application is provided by the
-GitLab APM group. If you run into unknown issues,
-[open a new issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new), and ping at
-least 2 people from the [APM group](https://about.gitlab.com/handbook/product/categories/#apm-group).
diff --git a/doc/user/infrastructure/clusters/manage/management_project_applications/runner.md b/doc/user/infrastructure/clusters/manage/management_project_applications/runner.md
index 56e01be68cb..841f2af7863 100644
--- a/doc/user/infrastructure/clusters/manage/management_project_applications/runner.md
+++ b/doc/user/infrastructure/clusters/manage/management_project_applications/runner.md
@@ -18,6 +18,8 @@ uncomment this line from your `helmfile.yaml`:
GitLab Runner is installed by default into the `gitlab-managed-apps` namespace of your cluster.
+## Required variables
+
For GitLab Runner to function, you _must_ specify the following in your
`applications/gitlab-runner/values.yaml.gotmpl` file:
@@ -28,10 +30,10 @@ For GitLab Runner to function, you _must_ specify the following in your
These values can be specified using [CI/CD variables](../../../../../ci/variables/index.md):
-- `GITLAB_RUNNER_GITLAB_URL` is used for `gitlabUrl`.
+- `CI_SERVER_URL` is used for `gitlabUrl`. If you are using GitLab.com, you don't need to set this variable.
- `GITLAB_RUNNER_REGISTRATION_TOKEN` is used for `runnerRegistrationToken`
-The methods of specifying these values are mutually exclusive. Either specify variables `GITLAB_RUNNER_REGISTRATION_TOKEN` and `GITLAB_RUNNER_TOKEN` as CI variables (recommended) or provide values for `runnerRegistrationToken:` and `runnerToken:` in `applications/gitlab-runner/values.yaml.gotmpl`.
+The methods of specifying these values are mutually exclusive. Either specify variables `GITLAB_RUNNER_REGISTRATION_TOKEN` and `CI_SERVER_URL` as CI variables (recommended) or provide values for `runnerRegistrationToken:` and `gitlabUrl:` in `applications/gitlab-runner/values.yaml.gotmpl`.
The runner registration token allows connection to a project by a runner and therefore should be treated as a secret to prevent malicious use and code exfiltration through a runner. For this reason, we recommend that you specify the runner registration token as a [protected variable](../../../../../ci/variables/index.md#protect-a-cicd-variable) and [masked variable](../../../../../ci/variables/index.md#mask-a-cicd-variable) and do not commit them to the Git repository in the `values.yaml.gotmpl` file.
@@ -40,9 +42,3 @@ You can customize the installation of GitLab Runner by defining
management project. Refer to the
[chart](https://gitlab.com/gitlab-org/charts/gitlab-runner) for the
available configuration options.
-
-Support for installing the GitLab Runner managed application is provided by the
-GitLab Runner group. If you run into unknown issues,
-[open a new issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new), and ping at
-least 2 people from the
-[Runner group](https://about.gitlab.com/handbook/product/categories/#runner-group).
diff --git a/doc/user/infrastructure/clusters/manage/management_project_applications/sentry.md b/doc/user/infrastructure/clusters/manage/management_project_applications/sentry.md
index 4d82fe389d2..300350010af 100644
--- a/doc/user/infrastructure/clusters/manage/management_project_applications/sentry.md
+++ b/doc/user/infrastructure/clusters/manage/management_project_applications/sentry.md
@@ -68,9 +68,3 @@ ingress:
postgresql:
postgresqlPassword: example-postgresql-password
```
-
-Support for installing the Sentry managed application is provided by the
-GitLab Health group. If you run into unknown issues,
-[open a new issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new), and ping at
-least 2 people from the
-[Health group](https://about.gitlab.com/handbook/product/categories/#health-group).
diff --git a/doc/user/infrastructure/clusters/manage/management_project_applications/vault.md b/doc/user/infrastructure/clusters/manage/management_project_applications/vault.md
index 291321963d0..d6b4eb5c157 100644
--- a/doc/user/infrastructure/clusters/manage/management_project_applications/vault.md
+++ b/doc/user/infrastructure/clusters/manage/management_project_applications/vault.md
@@ -100,9 +100,3 @@ kubectl -n gitlab-managed-apps exec -it vault-0 sh
This should give you your unseal keys and initial root token. Make sure to note these down
and keep these safe, as they're required to unseal the Vault throughout its lifecycle.
-
-Support for installing the Vault managed application is provided by the
-GitLab Release Management group. If you run into unknown issues,
-[open a new issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new), and ping at
-least 2 people from the
-[Release Management group](https://about.gitlab.com/handbook/product/categories/#release-management-group).
diff --git a/doc/user/infrastructure/img/terraform_list_view_v13_8.png b/doc/user/infrastructure/iac/img/terraform_list_view_v13_8.png
index 6eb85285e81..6eb85285e81 100644
--- a/doc/user/infrastructure/img/terraform_list_view_v13_8.png
+++ b/doc/user/infrastructure/iac/img/terraform_list_view_v13_8.png
Binary files differ
diff --git a/doc/user/infrastructure/img/terraform_plan_log_v13_0.png b/doc/user/infrastructure/iac/img/terraform_plan_log_v13_0.png
index c3c6f6b2f8b..c3c6f6b2f8b 100644
--- a/doc/user/infrastructure/img/terraform_plan_log_v13_0.png
+++ b/doc/user/infrastructure/iac/img/terraform_plan_log_v13_0.png
Binary files differ
diff --git a/doc/user/infrastructure/img/terraform_plan_widget_v13_2.png b/doc/user/infrastructure/iac/img/terraform_plan_widget_v13_2.png
index 564835a5dbe..564835a5dbe 100644
--- a/doc/user/infrastructure/img/terraform_plan_widget_v13_2.png
+++ b/doc/user/infrastructure/iac/img/terraform_plan_widget_v13_2.png
Binary files differ
diff --git a/doc/user/infrastructure/iac/index.md b/doc/user/infrastructure/iac/index.md
index 5b44490f78d..89df9c1d18f 100644
--- a/doc/user/infrastructure/iac/index.md
+++ b/doc/user/infrastructure/iac/index.md
@@ -65,7 +65,7 @@ Amazon S3 or Google Cloud Storage. Its features include:
- Locking and unlocking state.
- Remote Terraform plan and apply execution.
-Read more on setting up and [using GitLab Managed Terraform states](../terraform_state.md)
+Read more on setting up and [using GitLab Managed Terraform states](terraform_state.md).
## Terraform module registry
@@ -81,7 +81,7 @@ solution to help collaboration around Terraform code changes and their expected
effects using the Merge Request pages. This way users don't have to build custom
tools or rely on 3rd party solutions to streamline their IaC workflows.
-Read more on setting up and [using the merge request integrations](../mr_integration.md).
+Read more on setting up and [using the merge request integrations](mr_integration.md).
## The GitLab Terraform provider
diff --git a/doc/user/infrastructure/iac/mr_integration.md b/doc/user/infrastructure/iac/mr_integration.md
new file mode 100644
index 00000000000..853a39a59a8
--- /dev/null
+++ b/doc/user/infrastructure/iac/mr_integration.md
@@ -0,0 +1,210 @@
+---
+stage: Configure
+group: Configure
+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
+---
+
+# Terraform integration in Merge Requests **(FREE)**
+
+Collaborating around Infrastructure as Code (IaC) changes requires both code changes and expected infrastructure changes to be checked and approved. GitLab provides a solution to help collaboration around Terraform code changes and their expected effects using the Merge Request pages. This way users don't have to build custom tools or rely on 3rd party solutions to streamline their IaC workflows.
+
+## Output Terraform Plan information into a merge request
+
+Using the [GitLab Terraform Report artifact](../../../ci/yaml/index.md#artifactsreportsterraform),
+you can expose details from `terraform plan` runs directly into a merge request widget,
+enabling you to see statistics about the resources that Terraform creates,
+modifies, or destroys.
+
+WARNING:
+Like any other job artifact, Terraform Plan data is [viewable by anyone with Guest access](../../permissions.md) to the repository.
+Neither Terraform nor GitLab encrypts the plan file by default. If your Terraform Plan
+includes sensitive data such as passwords, access tokens, or certificates, we strongly
+recommend encrypting plan output or modifying the project visibility settings.
+
+## Configure Terraform report artifacts
+
+GitLab ships with a [pre-built CI template](index.md#quick-start) that uses GitLab Managed Terraform state and integrates Terraform changes into merge requests. We recommend customizing the pre-built image and relying on the `gitlab-terraform` helper provided within for a quick setup.
+
+To manually configure a GitLab Terraform Report artifact:
+
+1. For simplicity, let's define a few reusable variables to allow us to
+ refer to these files multiple times:
+
+ ```yaml
+ variables:
+ PLAN: plan.cache
+ PLAN_JSON: plan.json
+ ```
+
+1. Install `jq`, a
+ [lightweight and flexible command-line JSON processor](https://stedolan.github.io/jq/).
+1. Create an alias for a specific `jq` command that parses out the information we
+ want to extract from the `terraform plan` output:
+
+ ```yaml
+ before_script:
+ - apk --no-cache add jq
+ - alias convert_report="jq -r '([.resource_changes[]?.change.actions?]|flatten)|{\"create\":(map(select(.==\"create\"))|length),\"update\":(map(select(.==\"update\"))|length),\"delete\":(map(select(.==\"delete\"))|length)}'"
+ ```
+
+ NOTE:
+ In distributions that use Bash (for example, Ubuntu), `alias` statements are not
+ expanded in non-interactive mode. If your pipelines fail with the error
+ `convert_report: command not found`, alias expansion can be activated explicitly
+ by adding a `shopt` command to your script:
+
+ ```yaml
+ before_script:
+ - shopt -s expand_aliases
+ - alias convert_report="jq -r '([.resource_changes[]?.change.actions?]|flatten)|{\"create\":(map(select(.==\"create\"))|length),\"update\":(map(select(.==\"update\"))|length),\"delete\":(map(select(.==\"delete\"))|length)}'"
+ ```
+
+1. Define a `script` that runs `terraform plan` and `terraform show`. These commands
+ pipe the output and convert the relevant bits into a store variable `PLAN_JSON`.
+ This JSON is used to create a
+ [GitLab Terraform Report artifact](../../../ci/yaml/index.md#artifactsreportsterraform).
+ The Terraform report obtains a Terraform `tfplan.json` file. The collected
+ Terraform plan report is uploaded to GitLab as an artifact, and is shown in merge requests.
+
+ ```yaml
+ plan:
+ stage: build
+ script:
+ - terraform plan -out=$PLAN
+ - terraform show --json $PLAN | convert_report > $PLAN_JSON
+ artifacts:
+ reports:
+ terraform: $PLAN_JSON
+ ```
+
+ For a full example using the pre-built image, see [Example `.gitlab-ci.yml`
+ file](#example-gitlab-ciyml-file).
+
+ For an example displaying multiple reports, see [`.gitlab-ci.yml` multiple reports file](#multiple-terraform-plan-reports).
+
+1. Running the pipeline displays the widget in the merge request, like this:
+
+ ![Merge Request Terraform widget](img/terraform_plan_widget_v13_2.png)
+
+1. Clicking the **View Full Log** button in the widget takes you directly to the
+ plan output present in the pipeline logs:
+
+ ![Terraform plan logs](img/terraform_plan_log_v13_0.png)
+
+### Example `.gitlab-ci.yml` file
+
+```yaml
+default:
+ image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
+
+ cache:
+ key: example-production
+ paths:
+ - ${TF_ROOT}/.terraform
+
+variables:
+ TF_ROOT: ${CI_PROJECT_DIR}/environments/example/production
+ TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/example-production
+
+before_script:
+ - cd ${TF_ROOT}
+
+stages:
+ - prepare
+ - validate
+ - build
+ - deploy
+
+init:
+ stage: prepare
+ script:
+ - gitlab-terraform init
+
+validate:
+ stage: validate
+ script:
+ - gitlab-terraform validate
+
+plan:
+ stage: build
+ script:
+ - gitlab-terraform plan
+ - gitlab-terraform plan-json
+ artifacts:
+ name: plan
+ paths:
+ - ${TF_ROOT}/plan.cache
+ reports:
+ terraform: ${TF_ROOT}/plan.json
+
+apply:
+ stage: deploy
+ environment:
+ name: production
+ script:
+ - gitlab-terraform apply
+ dependencies:
+ - plan
+ when: manual
+ only:
+ - master
+```
+
+### Multiple Terraform Plan reports
+
+Starting with GitLab version 13.2, you can display multiple reports on the Merge Request
+page. The reports also display the `artifacts: name:`. See example below for a suggested setup.
+
+```yaml
+default:
+ image:
+ name: registry.gitlab.com/gitlab-org/gitlab-build-images:terraform
+ entrypoint:
+ - '/usr/bin/env'
+ - 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
+
+ cache:
+ paths:
+ - .terraform
+
+stages:
+ - build
+
+.terraform-plan-generation:
+ stage: build
+ variables:
+ PLAN: plan.tfplan
+ JSON_PLAN_FILE: tfplan.json
+ before_script:
+ - cd ${TERRAFORM_DIRECTORY}
+ - terraform --version
+ - terraform init
+ - apk --no-cache add jq
+ script:
+ - terraform validate
+ - terraform plan -out=${PLAN}
+ - terraform show --json ${PLAN} | jq -r '([.resource_changes[]?.change.actions?]|flatten)|{"create":(map(select(.=="create"))|length),"update":(map(select(.=="update"))|length),"delete":(map(select(.=="delete"))|length)}' > ${JSON_PLAN_FILE}
+ artifacts:
+ reports:
+ terraform: ${TERRAFORM_DIRECTORY}/${JSON_PLAN_FILE}
+
+review_plan:
+ extends: .terraform-plan-generation
+ variables:
+ TERRAFORM_DIRECTORY: "review/"
+ # Review will not include an artifact name
+
+staging_plan:
+ extends: .terraform-plan-generation
+ variables:
+ TERRAFORM_DIRECTORY: "staging/"
+ artifacts:
+ name: Staging
+
+production_plan:
+ extends: .terraform-plan-generation
+ variables:
+ TERRAFORM_DIRECTORY: "production/"
+ artifacts:
+ name: Production
+```
diff --git a/doc/user/infrastructure/iac/terraform_state.md b/doc/user/infrastructure/iac/terraform_state.md
new file mode 100644
index 00000000000..fb051c7fa14
--- /dev/null
+++ b/doc/user/infrastructure/iac/terraform_state.md
@@ -0,0 +1,446 @@
+---
+stage: Configure
+group: Configure
+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
+---
+
+# GitLab managed Terraform State **(FREE)**
+
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2673) in GitLab 13.0.
+
+[Terraform remote backends](https://www.terraform.io/docs/language/settings/backends/index.html)
+enable you to store the state file in a remote, shared store. GitLab uses the
+[Terraform HTTP backend](https://www.terraform.io/docs/language/settings/backends/http.html)
+to securely store the state files in local storage (the default) or
+[the remote store of your choice](../../../administration/terraform_state.md).
+
+WARNING:
+Using local storage (the default) on clustered deployments of GitLab will result in
+a split state across nodes, making subsequent executions of Terraform inconsistent.
+You are highly advised to use a remote storage in that case.
+
+The GitLab managed Terraform state backend can store your Terraform state easily and
+securely, and spares you from setting up additional remote resources like
+Amazon S3 or Google Cloud Storage. Its features include:
+
+- Versioning of Terraform state files.
+- Supporting encryption of the state file both in transit and at rest.
+- Locking and unlocking state.
+- Remote Terraform plan and apply execution.
+
+A GitLab **administrator** must [setup the Terraform state storage configuration](../../../administration/terraform_state.md)
+before using this feature.
+
+## Permissions for using Terraform
+
+In GitLab version 13.1, the [Maintainer role](../../permissions.md) was required to use a
+GitLab managed Terraform state backend. In GitLab versions 13.2 and greater, the
+[Maintainer role](../../permissions.md) is required to lock, unlock, and write to the state
+(using `terraform apply`), while the [Developer role](../../permissions.md) is required to read
+the state (using `terraform plan -lock=false`).
+
+## Set up GitLab-managed Terraform state
+
+To get started with a GitLab-managed Terraform state, there are two different options:
+
+- [Use a local machine](#get-started-using-local-development).
+- [Use GitLab CI](#get-started-using-gitlab-ci).
+
+Terraform States can be found by navigating to a Project's
+**{cloud-gear}** **Infrastructure > Terraform** page.
+
+### Get started using local development
+
+If you plan to only run `terraform plan` and `terraform apply` commands from your
+local machine, this is a simple way to get started:
+
+1. Create your project on your GitLab instance.
+1. Navigate to **Settings > General** and note your **Project name**
+ and **Project ID**.
+1. Define the Terraform backend in your Terraform project to be:
+
+ ```hcl
+ terraform {
+ backend "http" {
+ }
+ }
+ ```
+
+1. Create a [Personal Access Token](../../profile/personal_access_tokens.md) with
+ the `api` scope.
+
+1. On your local machine, run `terraform init`, passing in the following options,
+ replacing `<YOUR-STATE-NAME>`, `<YOUR-PROJECT-ID>`, `<YOUR-USERNAME>` and
+ `<YOUR-ACCESS-TOKEN>` with the relevant values. This command initializes your
+ Terraform state, and stores that state in your GitLab project. The name of
+ your state can contain only uppercase and lowercase letters, decimal digits,
+ hyphens, and underscores. This example uses `gitlab.com`:
+
+ ```shell
+ terraform init \
+ -backend-config="address=https://gitlab.com/api/v4/projects/<YOUR-PROJECT-ID>/terraform/state/<YOUR-STATE-NAME>" \
+ -backend-config="lock_address=https://gitlab.com/api/v4/projects/<YOUR-PROJECT-ID>/terraform/state/<YOUR-STATE-NAME>/lock" \
+ -backend-config="unlock_address=https://gitlab.com/api/v4/projects/<YOUR-PROJECT-ID>/terraform/state/<YOUR-STATE-NAME>/lock" \
+ -backend-config="username=<YOUR-USERNAME>" \
+ -backend-config="password=<YOUR-ACCESS-TOKEN>" \
+ -backend-config="lock_method=POST" \
+ -backend-config="unlock_method=DELETE" \
+ -backend-config="retry_wait_min=5"
+ ```
+
+If you already have a GitLab-managed Terraform state, you can use the `terraform init` command
+with the prepopulated parameters values:
+
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Infrastructure > Terraform**.
+1. Next to the environment you want to use, select the [Actions menu](#managing-state-files)
+ **{ellipsis_v}** and select **Copy Terraform init command**.
+
+You can now run `terraform plan` and `terraform apply` as you normally would.
+
+### Get started using GitLab CI
+
+If you don't want to start with local development, you can also use GitLab CI to
+run your `terraform plan` and `terraform apply` commands.
+
+Next, [configure the backend](#configure-the-backend).
+
+#### Configure the backend
+
+After executing the `terraform init` command, you must configure the Terraform backend
+and the CI YAML file:
+
+1. In your Terraform project, define the [HTTP backend](https://www.terraform.io/docs/language/settings/backends/http.html)
+ by adding the following code block in a `.tf` file (such as `backend.tf`) to
+ define the remote backend:
+
+ ```hcl
+ terraform {
+ backend "http" {
+ }
+ }
+ ```
+
+1. In the root directory of your project repository, configure a
+ `.gitlab-ci.yml` file. This example uses a pre-built image which includes a
+ `gitlab-terraform` helper. For supported Terraform versions, see the [GitLab
+ Terraform Images project](https://gitlab.com/gitlab-org/terraform-images).
+
+ ```yaml
+ image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
+ ```
+
+1. In the `.gitlab-ci.yml` file, define some CI/CD variables to ease
+ development. In this example, `TF_ROOT` is the directory where the Terraform
+ commands must be executed, `TF_ADDRESS` is the URL to the state on the GitLab
+ instance where this pipeline runs, and the final path segment in `TF_ADDRESS`
+ is the name of the Terraform state. Projects may have multiple states, and
+ this name is arbitrary, so in this example we set it to `example-production`
+ which corresponds with the directory we're using as our `TF_ROOT`, and we
+ ensure that the `.terraform` directory is cached between jobs in the pipeline
+ using a cache key based on the state name (`example-production`):
+
+ ```yaml
+ variables:
+ TF_ROOT: ${CI_PROJECT_DIR}/environments/example/production
+ TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/example-production
+
+ cache:
+ key: example-production
+ paths:
+ - ${TF_ROOT}/.terraform
+ ```
+
+1. In a `before_script`, change to your `TF_ROOT`:
+
+ ```yaml
+ before_script:
+ - cd ${TF_ROOT}
+
+ stages:
+ - prepare
+ - validate
+ - build
+ - deploy
+
+ init:
+ stage: prepare
+ script:
+ - gitlab-terraform init
+
+ validate:
+ stage: validate
+ script:
+ - gitlab-terraform validate
+
+ plan:
+ stage: build
+ script:
+ - gitlab-terraform plan
+ - gitlab-terraform plan-json
+ artifacts:
+ name: plan
+ paths:
+ - ${TF_ROOT}/plan.cache
+ reports:
+ terraform: ${TF_ROOT}/plan.json
+
+ apply:
+ stage: deploy
+ environment:
+ name: production
+ script:
+ - gitlab-terraform apply
+ dependencies:
+ - plan
+ when: manual
+ only:
+ - master
+ ```
+
+1. Push your project to GitLab, which triggers a CI job pipeline. This pipeline
+ runs the `gitlab-terraform init`, `gitlab-terraform validate`, and
+ `gitlab-terraform plan` commands.
+
+The output from the above `terraform` commands should be viewable in the job logs.
+
+WARNING:
+Like any other job artifact, Terraform plan data is [viewable by anyone with Guest access](../../permissions.md) to the repository.
+Neither Terraform nor GitLab encrypts the plan file by default. If your Terraform plan
+includes sensitive data such as passwords, access tokens, or certificates, GitLab strongly
+recommends encrypting plan output or modifying the project visibility settings.
+
+### Example project
+
+See [this reference project](https://gitlab.com/gitlab-org/configure/examples/gitlab-terraform-aws) using GitLab and Terraform to deploy a basic AWS EC2 in a custom VPC.
+
+## Using a GitLab managed Terraform state backend as a remote data source
+
+You can use a GitLab-managed Terraform state as a
+[Terraform data source](https://www.terraform.io/docs/language/state/remote-state-data.html).
+To use your existing Terraform state backend as a data source, provide the following details
+as [Terraform input variables](https://www.terraform.io/docs/language/values/variables.html):
+
+- **address**: The URL of the remote state backend you want to use as a data source.
+ For example, `https://gitlab.com/api/v4/projects/<TARGET-PROJECT-ID>/terraform/state/<TARGET-STATE-NAME>`.
+- **username**: The username to authenticate with the data source. If you are using a [Personal Access Token](../../profile/personal_access_tokens.md) for
+ authentication, this is your GitLab username. If you are using GitLab CI, this is `'gitlab-ci-token'`.
+- **password**: The password to authenticate with the data source. If you are using a Personal Access Token for
+ authentication, this is the token value. If you are using GitLab CI, it is the contents of the `${CI_JOB_TOKEN}` CI/CD variable.
+
+An example setup is shown below:
+
+1. Create a file named `example.auto.tfvars` with the following contents:
+
+ ```plaintext
+ example_remote_state_address=https://gitlab.com/api/v4/projects/<TARGET-PROJECT-ID>/terraform/state/<TARGET-STATE-NAME>
+ example_username=<GitLab username>
+ example_access_token=<GitLab Personal Access Token>
+ ```
+
+1. Define the data source by adding the following code block in a `.tf` file (such as `data.tf`):
+
+ ```hcl
+ data "terraform_remote_state" "example" {
+ backend = "http"
+
+ config = {
+ address = var.example_remote_state_address
+ username = var.example_username
+ password = var.example_access_token
+ }
+ }
+ ```
+
+Outputs from the data source can now be referenced in your Terraform resources
+using `data.terraform_remote_state.example.outputs.<OUTPUT-NAME>`.
+
+You need at least the [Developer role](../../permissions.md) in the target project
+to read the Terraform state.
+
+## Migrating to GitLab Managed Terraform state
+
+Terraform supports copying the state when the backend is changed or
+reconfigured. This can be useful if you need to migrate from another backend to
+GitLab managed Terraform state. Using a local terminal is recommended to run the commands needed for migrating to GitLab Managed Terraform state.
+
+The following example demonstrates how to change the state name, the same workflow is needed to migrate to GitLab Managed Terraform state from a different state storage backend.
+
+### Setting up the initial backend
+
+```shell
+PROJECT_ID="<gitlab-project-id>"
+TF_USERNAME="<gitlab-username>"
+TF_PASSWORD="<gitlab-personal-access-token>"
+TF_ADDRESS="https://gitlab.com/api/v4/projects/${PROJECT_ID}/terraform/state/old-state-name"
+
+terraform init \
+ -backend-config=address=${TF_ADDRESS} \
+ -backend-config=lock_address=${TF_ADDRESS}/lock \
+ -backend-config=unlock_address=${TF_ADDRESS}/lock \
+ -backend-config=username=${TF_USERNAME} \
+ -backend-config=password=${TF_PASSWORD} \
+ -backend-config=lock_method=POST \
+ -backend-config=unlock_method=DELETE \
+ -backend-config=retry_wait_min=5
+```
+
+```plaintext
+Initializing the backend...
+
+Successfully configured the backend "http"! Terraform will automatically
+use this backend unless the backend configuration changes.
+
+Initializing provider plugins...
+
+Terraform has been successfully initialized!
+
+You may now begin working with Terraform. Try running "terraform plan" to see
+any changes that are required for your infrastructure. All Terraform commands
+should now work.
+
+If you ever set or change modules or backend configuration for Terraform,
+rerun this command to reinitialize your working directory. If you forget, other
+commands will detect it and remind you to do so if necessary.
+```
+
+### Changing the backend
+
+Now that `terraform init` has created a `.terraform/` directory that knows where
+the old state is, you can tell it about the new location:
+
+```shell
+TF_ADDRESS="https://gitlab.com/api/v4/projects/${PROJECT_ID}/terraform/state/new-state-name"
+
+terraform init \
+ -backend-config=address=${TF_ADDRESS} \
+ -backend-config=lock_address=${TF_ADDRESS}/lock \
+ -backend-config=unlock_address=${TF_ADDRESS}/lock \
+ -backend-config=username=${TF_USERNAME} \
+ -backend-config=password=${TF_PASSWORD} \
+ -backend-config=lock_method=POST \
+ -backend-config=unlock_method=DELETE \
+ -backend-config=retry_wait_min=5
+```
+
+```plaintext
+Initializing the backend...
+Backend configuration changed!
+
+Terraform has detected that the configuration specified for the backend
+has changed. Terraform will now check for existing state in the backends.
+
+
+Acquiring state lock. This may take a few moments...
+Do you want to copy existing state to the new backend?
+ Pre-existing state was found while migrating the previous "http" backend to the
+ newly configured "http" backend. No existing state was found in the newly
+ configured "http" backend. Do you want to copy this state to the new "http"
+ backend? Enter "yes" to copy and "no" to start with an empty state.
+
+ Enter a value: yes
+
+
+Successfully configured the backend "http"! Terraform will automatically
+use this backend unless the backend configuration changes.
+
+Initializing provider plugins...
+
+Terraform has been successfully initialized!
+
+You may now begin working with Terraform. Try running "terraform plan" to see
+any changes that are required for your infrastructure. All Terraform commands
+should now work.
+
+If you ever set or change modules or backend configuration for Terraform,
+rerun this command to reinitialize your working directory. If you forget, other
+commands will detect it and remind you to do so if necessary.
+```
+
+If you type `yes`, it copies your state from the old location to the new
+location. You can then go back to running it in GitLab CI/CD.
+
+## Managing state files
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/273592) in GitLab 13.8.
+
+Users with Developer and greater [permissions](../../permissions.md) can view the
+state files attached to a project at **Infrastructure > Terraform**. Users with the
+Maintainer role can perform commands on the state files. The user interface
+contains these fields:
+
+![Terraform state list](img/terraform_list_view_v13_8.png)
+
+- **Name**: The name of the environment, with a locked (**{lock}**) icon if the
+ state file is locked.
+- **Pipeline**: A link to the most recent pipeline and its status.
+- **Details**: Information about when the state file was created or changed.
+- **Actions**: Actions you can take on the state file, including copying the `terraform init` command,
+ downloading, locking, unlocking, or [removing](#remove-a-state-file) the state file and versions.
+
+NOTE:
+Additional improvements to the
+[graphical interface for managing state files](https://gitlab.com/groups/gitlab-org/-/epics/4563)
+are planned.
+
+## Remove a state file
+
+Users with Maintainer and greater [permissions](../../permissions.md) can use the
+following options to remove a state file:
+
+- **GitLab UI**: Go to **Infrastructure > Terraform**. In the **Actions** column,
+ click the vertical ellipsis (**{ellipsis_v}**) button and select
+ **Remove state file and versions**.
+- **GitLab REST API**: You can remove a state file by making a request to the
+ REST API. For example:
+
+ ```shell
+ curl --header "Private-Token: <your_access_token>" --request DELETE "https://gitlab.example.com/api/v4/projects/<your_project_id>/terraform/state/<your_state_name>"
+ ```
+
+- [GitLab GraphQL API](#remove-a-state-file-with-the-gitlab-graphql-api).
+
+### Remove a state file with the GitLab GraphQL API
+
+You can remove a state file by making a GraphQL API request. For example:
+
+```shell
+mutation deleteState {
+ terraformStateDelete(input: { id: "<global_id_for_the_state>" }) {
+ errors
+ }
+}
+```
+
+You can obtain the `<global_id_for_the_state>` by querying the list of states:
+
+```shell
+query ProjectTerraformStates {
+ project(fullPath: "<your_project_path>") {
+ terraformStates {
+ nodes {
+ id
+ name
+ }
+ }
+ }
+}
+```
+
+For those new to the GitLab GraphQL API, read
+[Getting started with GitLab GraphQL API](../../../api/graphql/getting_started.md).
+
+## Troubleshooting
+
+### Unable to lock Terraform state files in CI jobs for `terraform apply` using a plan created in a previous job
+
+When passing `-backend-config=` to `terraform init`, Terraform persists these values inside the plan
+cache file. This includes the `password` value.
+
+As a result, to create a plan and later use the same plan in another CI job, you might get the error
+`Error: Error acquiring the state lock` errors when using `-backend-config=password=$CI_JOB_TOKEN`.
+This happens because the value of `$CI_JOB_TOKEN` is only valid for the duration of the current job.
+
+As a workaround, use [http backend configuration variables](https://www.terraform.io/docs/language/settings/backends/http.html#configuration-variables) in your CI job,
+which is what happens behind the scenes when following the
+[Get started using GitLab CI](#get-started-using-gitlab-ci) instructions.
diff --git a/doc/user/infrastructure/index.md b/doc/user/infrastructure/index.md
index b2d75a22615..9f28a40474e 100644
--- a/doc/user/infrastructure/index.md
+++ b/doc/user/infrastructure/index.md
@@ -6,9 +6,40 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Infrastructure management **(FREE)**
-GitLab provides you with great solutions to help you manage your
-infrastructure:
+With the rise of DevOps and SRE approaches, infrastructure management becomes codified,
+automatable, and software development best practices gain their place around infrastructure
+management too. On one hand, the daily tasks of classical operations people changed
+and are more similar to traditional software development. On the other hand, software engineers
+are more likely to control their whole DevOps lifecycle, including deployments and delivery.
-- [Infrastructure as Code and GitOps](iac/index.md)
-- [Kubernetes clusters](../project/clusters/index.md)
-- [Runbooks](../project/clusters/runbooks/index.md)
+GitLab offers various features to speed up and simplify your infrastructure management practices.
+
+## Infrastructure as Code
+
+GitLab has deep integrations with Terraform to run Infrastructure as Code pipelines
+and support various processes. Terraform is considered the standard in cloud infrastructure provisioning.
+The various GitLab integrations help you:
+
+- Get started quickly without any setup.
+- Collaborate around infrastructure changes in merge requests the same as you might
+ with code changes.
+- Scale using a module registry.
+
+Learn more about how GitLab can help you run [Infrastructure as Code](iac/index.md).
+
+## Integrated Kubernetes management
+
+GitLab has special integrations with Kubernetes to help you deploy, manage and troubleshoot
+third-party or custom applications in Kubernetes clusters. Auto DevOps provides a full
+DevSecOps pipeline by default targeted at Kubernetes based deployments. To support
+all the GitLab features, GitLab offers a cluster management project for easy onboarding.
+The deploy boards provide quick insights into your cluster, including pod logs tailing.
+
+Learn more about the [GitLab integration with Kubernetes](../project/clusters/index.md).
+
+## Runbooks in GitLab
+
+Runbooks are a collection of documented procedures that explain how to carry out a task,
+such as starting, stopping, debugging, or troubleshooting a system.
+
+Read more about [how executable runbooks work in GitLab](../project/clusters/runbooks/index.md).
diff --git a/doc/user/infrastructure/mr_integration.md b/doc/user/infrastructure/mr_integration.md
index 29bf218b109..81e8f7cbd33 100644
--- a/doc/user/infrastructure/mr_integration.md
+++ b/doc/user/infrastructure/mr_integration.md
@@ -1,210 +1,9 @@
---
-stage: Configure
-group: Configure
-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: 'iac/mr_integration.md'
+remove_date: '2021-11-26'
---
-# Terraform integration in Merge Requests **(FREE)**
+This document was moved to [another location](iac/mr_integration.md).
-Collaborating around Infrastructure as Code (IaC) changes requires both code changes and expected infrastructure changes to be checked and approved. GitLab provides a solution to help collaboration around Terraform code changes and their expected effects using the Merge Request pages. This way users don't have to build custom tools or rely on 3rd party solutions to streamline their IaC workflows.
-
-## Output Terraform Plan information into a merge request
-
-Using the [GitLab Terraform Report artifact](../../ci/yaml/index.md#artifactsreportsterraform),
-you can expose details from `terraform plan` runs directly into a merge request widget,
-enabling you to see statistics about the resources that Terraform creates,
-modifies, or destroys.
-
-WARNING:
-Like any other job artifact, Terraform Plan data is [viewable by anyone with Guest access](../permissions.md) to the repository.
-Neither Terraform nor GitLab encrypts the plan file by default. If your Terraform Plan
-includes sensitive data such as passwords, access tokens, or certificates, we strongly
-recommend encrypting plan output or modifying the project visibility settings.
-
-## Configure Terraform report artifacts
-
-GitLab ships with a [pre-built CI template](iac/index.md#quick-start) that uses GitLab Managed Terraform state and integrates Terraform changes into merge requests. We recommend customizing the pre-built image and relying on the `gitlab-terraform` helper provided within for a quick setup.
-
-To manually configure a GitLab Terraform Report artifact:
-
-1. For simplicity, let's define a few reusable variables to allow us to
- refer to these files multiple times:
-
- ```yaml
- variables:
- PLAN: plan.cache
- PLAN_JSON: plan.json
- ```
-
-1. Install `jq`, a
- [lightweight and flexible command-line JSON processor](https://stedolan.github.io/jq/).
-1. Create an alias for a specific `jq` command that parses out the information we
- want to extract from the `terraform plan` output:
-
- ```yaml
- before_script:
- - apk --no-cache add jq
- - alias convert_report="jq -r '([.resource_changes[]?.change.actions?]|flatten)|{\"create\":(map(select(.==\"create\"))|length),\"update\":(map(select(.==\"update\"))|length),\"delete\":(map(select(.==\"delete\"))|length)}'"
- ```
-
- NOTE:
- In distributions that use Bash (for example, Ubuntu), `alias` statements are not
- expanded in non-interactive mode. If your pipelines fail with the error
- `convert_report: command not found`, alias expansion can be activated explicitly
- by adding a `shopt` command to your script:
-
- ```yaml
- before_script:
- - shopt -s expand_aliases
- - alias convert_report="jq -r '([.resource_changes[]?.change.actions?]|flatten)|{\"create\":(map(select(.==\"create\"))|length),\"update\":(map(select(.==\"update\"))|length),\"delete\":(map(select(.==\"delete\"))|length)}'"
- ```
-
-1. Define a `script` that runs `terraform plan` and `terraform show`. These commands
- pipe the output and convert the relevant bits into a store variable `PLAN_JSON`.
- This JSON is used to create a
- [GitLab Terraform Report artifact](../../ci/yaml/index.md#artifactsreportsterraform).
- The Terraform report obtains a Terraform `tfplan.json` file. The collected
- Terraform plan report is uploaded to GitLab as an artifact, and is shown in merge requests.
-
- ```yaml
- plan:
- stage: build
- script:
- - terraform plan -out=$PLAN
- - terraform show --json $PLAN | convert_report > $PLAN_JSON
- artifacts:
- reports:
- terraform: $PLAN_JSON
- ```
-
- For a full example using the pre-built image, see [Example `.gitlab-ci.yml`
- file](#example-gitlab-ciyml-file).
-
- For an example displaying multiple reports, see [`.gitlab-ci.yml` multiple reports file](#multiple-terraform-plan-reports).
-
-1. Running the pipeline displays the widget in the merge request, like this:
-
- ![Merge Request Terraform widget](img/terraform_plan_widget_v13_2.png)
-
-1. Clicking the **View Full Log** button in the widget takes you directly to the
- plan output present in the pipeline logs:
-
- ![Terraform plan logs](img/terraform_plan_log_v13_0.png)
-
-### Example `.gitlab-ci.yml` file
-
-```yaml
-default:
- image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
-
- cache:
- key: example-production
- paths:
- - ${TF_ROOT}/.terraform
-
-variables:
- TF_ROOT: ${CI_PROJECT_DIR}/environments/example/production
- TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/example-production
-
-before_script:
- - cd ${TF_ROOT}
-
-stages:
- - prepare
- - validate
- - build
- - deploy
-
-init:
- stage: prepare
- script:
- - gitlab-terraform init
-
-validate:
- stage: validate
- script:
- - gitlab-terraform validate
-
-plan:
- stage: build
- script:
- - gitlab-terraform plan
- - gitlab-terraform plan-json
- artifacts:
- name: plan
- paths:
- - ${TF_ROOT}/plan.cache
- reports:
- terraform: ${TF_ROOT}/plan.json
-
-apply:
- stage: deploy
- environment:
- name: production
- script:
- - gitlab-terraform apply
- dependencies:
- - plan
- when: manual
- only:
- - master
-```
-
-### Multiple Terraform Plan reports
-
-Starting with GitLab version 13.2, you can display multiple reports on the Merge Request
-page. The reports also display the `artifacts: name:`. See example below for a suggested setup.
-
-```yaml
-default:
- image:
- name: registry.gitlab.com/gitlab-org/gitlab-build-images:terraform
- entrypoint:
- - '/usr/bin/env'
- - 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
-
- cache:
- paths:
- - .terraform
-
-stages:
- - build
-
-.terraform-plan-generation:
- stage: build
- variables:
- PLAN: plan.tfplan
- JSON_PLAN_FILE: tfplan.json
- before_script:
- - cd ${TERRAFORM_DIRECTORY}
- - terraform --version
- - terraform init
- - apk --no-cache add jq
- script:
- - terraform validate
- - terraform plan -out=${PLAN}
- - terraform show --json ${PLAN} | jq -r '([.resource_changes[]?.change.actions?]|flatten)|{"create":(map(select(.=="create"))|length),"update":(map(select(.=="update"))|length),"delete":(map(select(.=="delete"))|length)}' > ${JSON_PLAN_FILE}
- artifacts:
- reports:
- terraform: ${TERRAFORM_DIRECTORY}/${JSON_PLAN_FILE}
-
-review_plan:
- extends: .terraform-plan-generation
- variables:
- TERRAFORM_DIRECTORY: "review/"
- # Review will not include an artifact name
-
-staging_plan:
- extends: .terraform-plan-generation
- variables:
- TERRAFORM_DIRECTORY: "staging/"
- artifacts:
- name: Staging
-
-production_plan:
- extends: .terraform-plan-generation
- variables:
- TERRAFORM_DIRECTORY: "production/"
- artifacts:
- name: Production
-```
+<!-- This redirect file can be deleted after <2021-11-26>. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/user/infrastructure/terraform_state.md b/doc/user/infrastructure/terraform_state.md
index 179f9677b96..e71291d502e 100644
--- a/doc/user/infrastructure/terraform_state.md
+++ b/doc/user/infrastructure/terraform_state.md
@@ -1,431 +1,9 @@
---
-stage: Configure
-group: Configure
-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: 'iac/terraform_state.md'
+remove_date: '2021-11-26'
---
-# GitLab managed Terraform State **(FREE)**
+This document was moved to [another location](iac/terraform_state.md).
-> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2673) in GitLab 13.0.
-
-[Terraform remote backends](https://www.terraform.io/docs/language/settings/backends/index.html)
-enable you to store the state file in a remote, shared store. GitLab uses the
-[Terraform HTTP backend](https://www.terraform.io/docs/language/settings/backends/http.html)
-to securely store the state files in local storage (the default) or
-[the remote store of your choice](../../administration/terraform_state.md).
-
-WARNING:
-Using local storage (the default) on clustered deployments of GitLab will result in
-a split state across nodes, making subsequent executions of Terraform inconsistent.
-You are highly advised to use a remote storage in that case.
-
-The GitLab managed Terraform state backend can store your Terraform state easily and
-securely, and spares you from setting up additional remote resources like
-Amazon S3 or Google Cloud Storage. Its features include:
-
-- Versioning of Terraform state files.
-- Supporting encryption of the state file both in transit and at rest.
-- Locking and unlocking state.
-- Remote Terraform plan and apply execution.
-
-A GitLab **administrator** must [setup the Terraform state storage configuration](../../administration/terraform_state.md)
-before using this feature.
-
-## Permissions for using Terraform
-
-In GitLab version 13.1, the [Maintainer role](../permissions.md) was required to use a
-GitLab managed Terraform state backend. In GitLab versions 13.2 and greater, the
-[Maintainer role](../permissions.md) is required to lock, unlock, and write to the state
-(using `terraform apply`), while the [Developer role](../permissions.md) is required to read
-the state (using `terraform plan -lock=false`).
-
-## Set up GitLab-managed Terraform state
-
-To get started with a GitLab-managed Terraform state, there are two different options:
-
-- [Use a local machine](#get-started-using-local-development).
-- [Use GitLab CI](#get-started-using-gitlab-ci).
-
-Terraform States can be found by navigating to a Project's
-**{cloud-gear}** **Infrastructure > Terraform** page.
-
-### Get started using local development
-
-If you plan to only run `terraform plan` and `terraform apply` commands from your
-local machine, this is a simple way to get started:
-
-1. Create your project on your GitLab instance.
-1. Navigate to **Settings > General** and note your **Project name**
- and **Project ID**.
-1. Define the Terraform backend in your Terraform project to be:
-
- ```hcl
- terraform {
- backend "http" {
- }
- }
- ```
-
-1. Create a [Personal Access Token](../profile/personal_access_tokens.md) with
- the `api` scope.
-
-1. On your local machine, run `terraform init`, passing in the following options,
- replacing `<YOUR-STATE-NAME>`, `<YOUR-PROJECT-ID>`, `<YOUR-USERNAME>` and
- `<YOUR-ACCESS-TOKEN>` with the relevant values. This command initializes your
- Terraform state, and stores that state in your GitLab project. The name of
- your state can contain only uppercase and lowercase letters, decimal digits,
- hyphens, and underscores. This example uses `gitlab.com`:
-
- ```shell
- terraform init \
- -backend-config="address=https://gitlab.com/api/v4/projects/<YOUR-PROJECT-ID>/terraform/state/<YOUR-STATE-NAME>" \
- -backend-config="lock_address=https://gitlab.com/api/v4/projects/<YOUR-PROJECT-ID>/terraform/state/<YOUR-STATE-NAME>/lock" \
- -backend-config="unlock_address=https://gitlab.com/api/v4/projects/<YOUR-PROJECT-ID>/terraform/state/<YOUR-STATE-NAME>/lock" \
- -backend-config="username=<YOUR-USERNAME>" \
- -backend-config="password=<YOUR-ACCESS-TOKEN>" \
- -backend-config="lock_method=POST" \
- -backend-config="unlock_method=DELETE" \
- -backend-config="retry_wait_min=5"
- ```
-
-If you already have a GitLab-managed Terraform state, you can use the `terraform init` command
-with the prepopulated parameters values:
-
-1. On the top bar, select **Menu > Projects** and find your project.
-1. On the left sidebar, select **Infrastructure > Terraform**.
-1. Next to the environment you want to use, select the [Actions menu](#managing-state-files)
- **{ellipsis_v}** and select **Copy Terraform init command**.
-
-You can now run `terraform plan` and `terraform apply` as you normally would.
-
-### Get started using GitLab CI
-
-If you don't want to start with local development, you can also use GitLab CI to
-run your `terraform plan` and `terraform apply` commands.
-
-Next, [configure the backend](#configure-the-backend).
-
-#### Configure the backend
-
-After executing the `terraform init` command, you must configure the Terraform backend
-and the CI YAML file:
-
-1. In your Terraform project, define the [HTTP backend](https://www.terraform.io/docs/language/settings/backends/http.html)
- by adding the following code block in a `.tf` file (such as `backend.tf`) to
- define the remote backend:
-
- ```hcl
- terraform {
- backend "http" {
- }
- }
- ```
-
-1. In the root directory of your project repository, configure a
- `.gitlab-ci.yml` file. This example uses a pre-built image which includes a
- `gitlab-terraform` helper. For supported Terraform versions, see the [GitLab
- Terraform Images project](https://gitlab.com/gitlab-org/terraform-images).
-
- ```yaml
- image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
- ```
-
-1. In the `.gitlab-ci.yml` file, define some CI/CD variables to ease
- development. In this example, `TF_ROOT` is the directory where the Terraform
- commands must be executed, `TF_ADDRESS` is the URL to the state on the GitLab
- instance where this pipeline runs, and the final path segment in `TF_ADDRESS`
- is the name of the Terraform state. Projects may have multiple states, and
- this name is arbitrary, so in this example we set it to `example-production`
- which corresponds with the directory we're using as our `TF_ROOT`, and we
- ensure that the `.terraform` directory is cached between jobs in the pipeline
- using a cache key based on the state name (`example-production`):
-
- ```yaml
- variables:
- TF_ROOT: ${CI_PROJECT_DIR}/environments/example/production
- TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/example-production
-
- cache:
- key: example-production
- paths:
- - ${TF_ROOT}/.terraform
- ```
-
-1. In a `before_script`, change to your `TF_ROOT`:
-
- ```yaml
- before_script:
- - cd ${TF_ROOT}
-
- stages:
- - prepare
- - validate
- - build
- - deploy
-
- init:
- stage: prepare
- script:
- - gitlab-terraform init
-
- validate:
- stage: validate
- script:
- - gitlab-terraform validate
-
- plan:
- stage: build
- script:
- - gitlab-terraform plan
- - gitlab-terraform plan-json
- artifacts:
- name: plan
- paths:
- - ${TF_ROOT}/plan.cache
- reports:
- terraform: ${TF_ROOT}/plan.json
-
- apply:
- stage: deploy
- environment:
- name: production
- script:
- - gitlab-terraform apply
- dependencies:
- - plan
- when: manual
- only:
- - master
- ```
-
-1. Push your project to GitLab, which triggers a CI job pipeline. This pipeline
- runs the `gitlab-terraform init`, `gitlab-terraform validate`, and
- `gitlab-terraform plan` commands.
-
-The output from the above `terraform` commands should be viewable in the job logs.
-
-WARNING:
-Like any other job artifact, Terraform plan data is [viewable by anyone with Guest access](../permissions.md) to the repository.
-Neither Terraform nor GitLab encrypts the plan file by default. If your Terraform plan
-includes sensitive data such as passwords, access tokens, or certificates, GitLab strongly
-recommends encrypting plan output or modifying the project visibility settings.
-
-### Example project
-
-See [this reference project](https://gitlab.com/gitlab-org/configure/examples/gitlab-terraform-aws) using GitLab and Terraform to deploy a basic AWS EC2 in a custom VPC.
-
-## Using a GitLab managed Terraform state backend as a remote data source
-
-You can use a GitLab-managed Terraform state as a
-[Terraform data source](https://www.terraform.io/docs/language/state/remote-state-data.html).
-To use your existing Terraform state backend as a data source, provide the following details
-as [Terraform input variables](https://www.terraform.io/docs/language/values/variables.html):
-
-- **address**: The URL of the remote state backend you want to use as a data source.
- For example, `https://gitlab.com/api/v4/projects/<TARGET-PROJECT-ID>/terraform/state/<TARGET-STATE-NAME>`.
-- **username**: The username to authenticate with the data source. If you are using a [Personal Access Token](../profile/personal_access_tokens.md) for
- authentication, this is your GitLab username. If you are using GitLab CI, this is `'gitlab-ci-token'`.
-- **password**: The password to authenticate with the data source. If you are using a Personal Access Token for
- authentication, this is the token value. If you are using GitLab CI, it is the contents of the `${CI_JOB_TOKEN}` CI/CD variable.
-
-An example setup is shown below:
-
-1. Create a file named `example.auto.tfvars` with the following contents:
-
- ```plaintext
- example_remote_state_address=https://gitlab.com/api/v4/projects/<TARGET-PROJECT-ID>/terraform/state/<TARGET-STATE-NAME>
- example_username=<GitLab username>
- example_access_token=<GitLab Personal Access Token>
- ```
-
-1. Define the data source by adding the following code block in a `.tf` file (such as `data.tf`):
-
- ```hcl
- data "terraform_remote_state" "example" {
- backend = "http"
-
- config = {
- address = var.example_remote_state_address
- username = var.example_username
- password = var.example_access_token
- }
- }
- ```
-
-Outputs from the data source can now be referenced in your Terraform resources
-using `data.terraform_remote_state.example.outputs.<OUTPUT-NAME>`.
-
-You need at least the [Developer role](../permissions.md) in the target project
-to read the Terraform state.
-
-## Migrating to GitLab Managed Terraform state
-
-Terraform supports copying the state when the backend is changed or
-reconfigured. This can be useful if you need to migrate from another backend to
-GitLab managed Terraform state. Using a local terminal is recommended to run the commands needed for migrating to GitLab Managed Terraform state.
-
-The following example demonstrates how to change the state name, the same workflow is needed to migrate to GitLab Managed Terraform state from a different state storage backend.
-
-### Setting up the initial backend
-
-```shell
-PROJECT_ID="<gitlab-project-id>"
-TF_USERNAME="<gitlab-username>"
-TF_PASSWORD="<gitlab-personal-access-token>"
-TF_ADDRESS="https://gitlab.com/api/v4/projects/${PROJECT_ID}/terraform/state/old-state-name"
-
-terraform init \
- -backend-config=address=${TF_ADDRESS} \
- -backend-config=lock_address=${TF_ADDRESS}/lock \
- -backend-config=unlock_address=${TF_ADDRESS}/lock \
- -backend-config=username=${TF_USERNAME} \
- -backend-config=password=${TF_PASSWORD} \
- -backend-config=lock_method=POST \
- -backend-config=unlock_method=DELETE \
- -backend-config=retry_wait_min=5
-```
-
-```plaintext
-Initializing the backend...
-
-Successfully configured the backend "http"! Terraform will automatically
-use this backend unless the backend configuration changes.
-
-Initializing provider plugins...
-
-Terraform has been successfully initialized!
-
-You may now begin working with Terraform. Try running "terraform plan" to see
-any changes that are required for your infrastructure. All Terraform commands
-should now work.
-
-If you ever set or change modules or backend configuration for Terraform,
-rerun this command to reinitialize your working directory. If you forget, other
-commands will detect it and remind you to do so if necessary.
-```
-
-### Changing the backend
-
-Now that `terraform init` has created a `.terraform/` directory that knows where
-the old state is, you can tell it about the new location:
-
-```shell
-TF_ADDRESS="https://gitlab.com/api/v4/projects/${PROJECT_ID}/terraform/state/new-state-name"
-
-terraform init \
- -backend-config=address=${TF_ADDRESS} \
- -backend-config=lock_address=${TF_ADDRESS}/lock \
- -backend-config=unlock_address=${TF_ADDRESS}/lock \
- -backend-config=username=${TF_USERNAME} \
- -backend-config=password=${TF_PASSWORD} \
- -backend-config=lock_method=POST \
- -backend-config=unlock_method=DELETE \
- -backend-config=retry_wait_min=5
-```
-
-```plaintext
-Initializing the backend...
-Backend configuration changed!
-
-Terraform has detected that the configuration specified for the backend
-has changed. Terraform will now check for existing state in the backends.
-
-
-Acquiring state lock. This may take a few moments...
-Do you want to copy existing state to the new backend?
- Pre-existing state was found while migrating the previous "http" backend to the
- newly configured "http" backend. No existing state was found in the newly
- configured "http" backend. Do you want to copy this state to the new "http"
- backend? Enter "yes" to copy and "no" to start with an empty state.
-
- Enter a value: yes
-
-
-Successfully configured the backend "http"! Terraform will automatically
-use this backend unless the backend configuration changes.
-
-Initializing provider plugins...
-
-Terraform has been successfully initialized!
-
-You may now begin working with Terraform. Try running "terraform plan" to see
-any changes that are required for your infrastructure. All Terraform commands
-should now work.
-
-If you ever set or change modules or backend configuration for Terraform,
-rerun this command to reinitialize your working directory. If you forget, other
-commands will detect it and remind you to do so if necessary.
-```
-
-If you type `yes`, it copies your state from the old location to the new
-location. You can then go back to running it in GitLab CI/CD.
-
-## Managing state files
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/273592) in GitLab 13.8.
-
-Users with Developer and greater [permissions](../permissions.md) can view the
-state files attached to a project at **Infrastructure > Terraform**. Users with the
-Maintainer role can perform commands on the state files. The user interface
-contains these fields:
-
-![Terraform state list](img/terraform_list_view_v13_8.png)
-
-- **Name**: The name of the environment, with a locked (**{lock}**) icon if the
- state file is locked.
-- **Pipeline**: A link to the most recent pipeline and its status.
-- **Details**: Information about when the state file was created or changed.
-- **Actions**: Actions you can take on the state file, including copying the `terraform init` command,
- downloading, locking, unlocking, or [removing](#remove-a-state-file) the state file and versions.
-
-NOTE:
-Additional improvements to the
-[graphical interface for managing state files](https://gitlab.com/groups/gitlab-org/-/epics/4563)
-are planned.
-
-## Remove a state file
-
-Users with Maintainer and greater [permissions](../permissions.md) can use the
-following options to remove a state file:
-
-- **GitLab UI**: Go to **Infrastructure > Terraform**. In the **Actions** column,
- click the vertical ellipsis (**{ellipsis_v}**) button and select
- **Remove state file and versions**.
-- **GitLab REST API**: You can remove a state file by making a request to the
- REST API. For example:
-
- ```shell
- curl --header "Private-Token: <your_access_token>" --request DELETE "https://gitlab.example.com/api/v4/projects/<your_project_id>/terraform/state/<your_state_name>"
- ```
-
-- [GitLab GraphQL API](#remove-a-state-file-with-the-gitlab-graphql-api).
-
-### Remove a state file with the GitLab GraphQL API
-
-You can remove a state file by making a GraphQL API request. For example:
-
-```shell
-mutation deleteState {
- terraformStateDelete(input: { id: "<global_id_for_the_state>" }) {
- errors
- }
-}
-```
-
-You can obtain the `<global_id_for_the_state>` by querying the list of states:
-
-```shell
-query ProjectTerraformStates {
- project(fullPath: "<your_project_path>") {
- terraformStates {
- nodes {
- id
- name
- }
- }
- }
-}
-```
-
-For those new to the GitLab GraphQL API, read
-[Getting started with GitLab GraphQL API](../../api/graphql/getting_started.md).
+<!-- This redirect file can be deleted after <2021-11-26>. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/user/instance/clusters/index.md b/doc/user/instance/clusters/index.md
index 5f51286cf7f..20cd30b6110 100644
--- a/doc/user/instance/clusters/index.md
+++ b/doc/user/instance/clusters/index.md
@@ -16,8 +16,8 @@ projects.
To view the instance level Kubernetes clusters:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Kubernetes**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Kubernetes**.
## Cluster precedence
diff --git a/doc/user/packages/conan_repository/index.md b/doc/user/packages/conan_repository/index.md
index d3e913edfda..dc08baaf731 100644
--- a/doc/user/packages/conan_repository/index.md
+++ b/doc/user/packages/conan_repository/index.md
@@ -297,9 +297,6 @@ dependency. You can install a package from the scope of your instance or your pr
If multiple packages have the same recipe, when you install
a package, the most recently-published package is retrieved.
-WARNING:
-Project-level packages [cannot be downloaded currently](https://gitlab.com/gitlab-org/gitlab/-/issues/270129).
-
Conan packages are often installed as dependencies by using the `conanfile.txt`
file.
diff --git a/doc/user/packages/container_registry/index.md b/doc/user/packages/container_registry/index.md
index 18b86c4a357..1db2165cd5d 100644
--- a/doc/user/packages/container_registry/index.md
+++ b/doc/user/packages/container_registry/index.md
@@ -154,7 +154,7 @@ To use CI/CD to authenticate, you can use:
docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
```
-- A [CI job token](../../../ci/triggers/index.md#ci-job-token).
+- A [CI job token](../../../ci/jobs/ci_job_token.md).
```shell
docker login -u $CI_JOB_USER -p $CI_JOB_TOKEN $CI_REGISTRY
@@ -747,6 +747,8 @@ The **Packages & Registries > Container Registry** entry is removed from the pro
## Change visibility of the Container Registry
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18792) in GitLab 14.2.
+
By default, the Container Registry is visible to everyone with access to the project.
You can, however, change the visibility of the Container Registry for a project.
@@ -863,6 +865,18 @@ these steps:
echo -n "" > list_o_tags.out; for i in {1..N}; do curl --header 'PRIVATE-TOKEN: <PAT>' "https://gitlab.example.com/api/v4/projects/<Project_id>/registry/repositories/<container_repo_id>/tags?per_page=100&page=${i}" | jq '.[].name' | sed 's:^.\(.*\).$:\1:' >> list_o_tags.out; done
```
+ If you have Rails console access, you can enter the following commands to retrieve a list of tags limited by date:
+
+ ```shell
+ output = File.open( "/tmp/list_o_tags.out","w" )
+ Project.find(<Project_id>).container_repositories.find(<container_repo_id>).tags.each do |tag|
+ output << tag.name + "\n" if tag.created_at < 1.month.ago
+ end;nil
+ output.close
+ ```
+
+ This set of commands creates a `/tmp/list_o_tags.out` file listing all tags with a `created_at` date of older than one month.
+
1. Remove from the `list_o_tags.out` file any tags that you want to keep. Here are some example
`sed` commands for this. Note that these commands are simply examples. You may change them to
best suit your needs:
diff --git a/doc/user/packages/debian_repository/index.md b/doc/user/packages/debian_repository/index.md
index 789902c03e3..29641380753 100644
--- a/doc/user/packages/debian_repository/index.md
+++ b/doc/user/packages/debian_repository/index.md
@@ -67,7 +67,7 @@ To create a distribution, publish a package, or install a private package, you n
following:
- [Personal access token](../../../api/index.md#personalproject-access-tokens)
-- [CI/CD job token](../../../api/index.md#gitlab-cicd-job-token)
+- [CI/CD job token](../../../ci/jobs/ci_job_token.md)
- [Deploy token](../../project/deploy_tokens/index.md)
## Create a Distribution
@@ -78,7 +78,7 @@ packages on the group level, create a distribution with the same `codename`.
To create a project-level distribution:
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/<project_id>/debian_distributions?codename=unstable
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/<project_id>/debian_distributions?codename=unstable"
```
Example response:
diff --git a/doc/user/packages/dependency_proxy/index.md b/doc/user/packages/dependency_proxy/index.md
index c76b0a6810f..ad25ec7edbf 100644
--- a/doc/user/packages/dependency_proxy/index.md
+++ b/doc/user/packages/dependency_proxy/index.md
@@ -94,8 +94,11 @@ Proxy.
> - The prefix for group names containing uppercase letters was [fixed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54559) in GitLab 13.10.
Runners log in to the Dependency Proxy automatically. To pull through
-the Dependency Proxy, use the `CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX`
-[predefined CI/CD variable](../../../ci/variables/predefined_variables.md):
+the Dependency Proxy, use one of the [predefined variables](../../../ci/variables/predefined_variables.md):
+
+- `CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX` pulls through the top-level group.
+- `CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX` pulls through the subgroup, or direct group the
+ project exists in.
Example pulling the latest alpine image:
@@ -109,7 +112,10 @@ There are other additional predefined CI/CD variables you can also use:
- `CI_DEPENDENCY_PROXY_USER`: A CI/CD user for logging in to the Dependency Proxy.
- `CI_DEPENDENCY_PROXY_PASSWORD`: A CI/CD password for logging in to the Dependency Proxy.
- `CI_DEPENDENCY_PROXY_SERVER`: The server for logging in to the Dependency Proxy.
-- `CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX`: The image prefix for pulling images through the Dependency Proxy.
+- `CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX`: the image prefix for pulling images through the
+ dependency proxy from the top-level group.
+- `CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX`: the image prefix for pulling images through the
+ dependency proxy from the direct group or subgroup that the project belongs to.
`CI_DEPENDENCY_PROXY_SERVER` and `CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX`
include the server port. If you explicitly include the Dependency Proxy
diff --git a/doc/user/packages/generic_packages/index.md b/doc/user/packages/generic_packages/index.md
index aa6373b66cb..6d35273ae6f 100644
--- a/doc/user/packages/generic_packages/index.md
+++ b/doc/user/packages/generic_packages/index.md
@@ -21,13 +21,13 @@ Publish generic files, like release binaries, in your project's Package Registry
## Authenticate to the Package Registry
To authenticate to the Package Registry, you need either a [personal access token](../../../api/index.md#personalproject-access-tokens),
-[CI/CD job token](../../../api/index.md#gitlab-cicd-job-token), or [deploy token](../../project/deploy_tokens/index.md).
+[CI/CD job token](../../../ci/jobs/ci_job_token.md), or [deploy token](../../project/deploy_tokens/index.md).
In addition to the standard API authentication mechanisms, the generic package
API allows authentication with HTTP Basic authentication for use with tools that
do not support the other available mechanisms. The `user-id` is not checked and
may be any value, and the `password` must be either a [personal access token](../../../api/index.md#personalproject-access-tokens),
-a [CI/CD job token](../../../api/index.md#gitlab-cicd-job-token), or a [deploy token](../../project/deploy_tokens/index.md).
+a [CI/CD job token](../../../ci/jobs/ci_job_token.md), or a [deploy token](../../project/deploy_tokens/index.md).
## Publish a package file
@@ -125,7 +125,7 @@ Example request that uses HTTP Basic authentication:
```shell
curl --user "user:<your_access_token>" \
- https://gitlab.example.com/api/v4/projects/24/packages/generic/my_package/0.0.1/file.txt
+ "https://gitlab.example.com/api/v4/projects/24/packages/generic/my_package/0.0.1/file.txt"
```
## Publish a generic package by using CI/CD
diff --git a/doc/user/packages/helm_repository/index.md b/doc/user/packages/helm_repository/index.md
index f98fc352ab5..2d984d76b97 100644
--- a/doc/user/packages/helm_repository/index.md
+++ b/doc/user/packages/helm_repository/index.md
@@ -25,9 +25,9 @@ Read more in the Helm documentation about these topics:
To authenticate to the Helm repository, you need either:
-- A [personal access token](../../../api/index.md#personalproject-access-tokens).
-- A [deploy token](../../project/deploy_tokens/index.md).
-- A [CI/CD job token](../../../api/index.md#gitlab-cicd-job-token).
+- A [personal access token](../../../api/index.md#personalproject-access-tokens) with the scope set to `api`.
+- A [deploy token](../../project/deploy_tokens/index.md) with the scope set to `read_package_registry`, `write_package_registry`, or both.
+- A [CI/CD job token](../../../ci/jobs/ci_job_token.md).
## Publish a package
@@ -35,24 +35,35 @@ NOTE:
You can publish Helm charts with duplicate names or versions. If duplicates exist, GitLab always
returns the chart with the latest version.
-Once built, a chart can be uploaded to the `stable` channel with `curl` or `helm-push`:
+Once built, a chart can be uploaded to the desired channel with `curl` or `helm-push`:
- With `curl`:
```shell
curl --request POST \
--form 'chart=@mychart-0.1.0.tgz' \
- --user <username>:<personal_access_token> \
- https://gitlab.example.com/api/v4/projects/1/packages/helm/api/stable/charts
+ --user <username>:<access_token> \
+ https://gitlab.example.com/api/v4/projects/<project_id>/packages/helm/api/<channel>/charts
```
+ - `<username>`: the GitLab username or the deploy token username.
+ - `<access_token>`: the personal access token or the deploy token.
+ - `<project_id>`: the project ID (like `42`) or the
+ [URL-encoded](../../../api/index.md#namespaced-path-encoding) path of the project (like `group%2Fproject`).
+ - `<channel>`: the name of the channel (like `stable`).
+
- With the [`helm-push`](https://github.com/chartmuseum/helm-push/#readme) plugin:
```shell
- helm repo add --username <username> --password <personal_access_token> project-1 https://gitlab.example.com/api/v4/projects/1/packages/helm/stable
+ helm repo add --username <username> --password <access_token> project-1 https://gitlab.example.com/api/v4/projects/<project_id>/packages/helm/<channel>
helm push mychart-0.1.0.tgz project-1
```
+ - `<username>`: the GitLab username or the deploy token username.
+ - `<access_token>`: the personal access token or the deploy token.
+ - `<project_id>`: the project ID (like `42`).
+ - `<channel>`: the name of the channel (like `stable`).
+
## Use CI/CD to publish a Helm package
To publish a Helm package automated through [GitLab CI/CD](../../../ci/index.md), you can use
@@ -69,18 +80,31 @@ stages:
upload:
stage: upload
script:
- - 'curl --request POST --user gitlab-ci-token:$CI_JOB_TOKEN --form "chart=@mychart-0.1.0.tgz" "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/helm/api/stable/charts"'
+ - 'curl --request POST --user gitlab-ci-token:$CI_JOB_TOKEN --form "chart=@mychart-0.1.0.tgz" "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/helm/api/<channel>/charts"'
```
+- `<username>`: the GitLab username or the deploy token username.
+- `<access_token>`: the personal access token or the deploy token.
+- `<channel>`: the name of the channel (like `stable`).
+
## Install a package
+NOTE:
+When requesting a package, GitLab considers only the 300 most recent packages created.
+For each package, only the most recent package file is returned.
+
To install the latest version of a chart, use the following command:
```shell
-helm repo add --username <username> --password <personal_access_token> project-1 https://gitlab.example.com/api/v4/projects/1/packages/helm/stable
+helm repo add --username <username> --password <access_token> project-1 https://gitlab.example.com/api/v4/projects/<project_id>/packages/helm/<channel>
helm install my-release project-1/mychart
```
+- `<username>`: the GitLab username or the deploy token username.
+- `<access_token>`: the personal access token or the deploy token.
+- `<project_id>`: the project ID (like `42`).
+- `<channel>`: the name of the channel (like `stable`).
+
If the repo has previously been added, you may need to run:
```shell
diff --git a/doc/user/packages/terraform_module_registry/index.md b/doc/user/packages/terraform_module_registry/index.md
index e3b9563a143..7f101adccad 100644
--- a/doc/user/packages/terraform_module_registry/index.md
+++ b/doc/user/packages/terraform_module_registry/index.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Terraform module registry **(FREE)**
-> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3221) in GitLab 14.0.
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3221) in GitLab 14.0.
Publish Terraform modules in your project's Infrastructure Registry, then reference them using GitLab
as a Terraform module registry.
@@ -16,7 +16,7 @@ as a Terraform module registry.
To authenticate to the Terraform module registry, you need either:
- A [personal access token](../../../api/index.md#personalproject-access-tokens) with at least `read_api` rights.
-- A [CI/CD job token](../../../api/index.md#gitlab-cicd-job-token).
+- A [CI/CD job token](../../../ci/jobs/ci_job_token.md).
## Publish a Terraform Module
@@ -41,6 +41,10 @@ PUT /projects/:id/packages/terraform/modules/:module_name/:module_system/:module
Provide the file content in the request body.
+Note that, in the following example, the request must end with `/file`.
+If you send a request ending with something else, it results in a 404
+error `{"error":"404 Not Found"}`.
+
Example request using a personal access token:
```shell
diff --git a/doc/user/permissions.md b/doc/user/permissions.md
index 81681ec1303..f240a9fd407 100644
--- a/doc/user/permissions.md
+++ b/doc/user/permissions.md
@@ -41,23 +41,23 @@ For more information, see [projects members documentation](project/members/index
The following table lists project permissions available for each role:
-<!-- Keep this table sorted: first, by minimum role, then alphabetically. -->
+<!-- Keep this table sorted: By topic first, then by minimum role, then alphabetically. -->
| Action | Guest | Reporter | Developer | Maintainer | Owner |
|-------------------------------------------------------------------------------------------------------------------------|----------|----------|-----------|------------|-------|
| [Analytics](analytics/index.md):<br>View issue analytics **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Analytics](analytics/index.md):<br>View [merge request analytics](analytics/merge_request_analytics.md) **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Analytics](analytics/index.md):<br>View [merge request analytics](analytics/merge_request_analytics.md) **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ |
| [Analytics](analytics/index.md):<br>View value stream analytics | ✓ | ✓ | ✓ | ✓ | ✓ |
| [Analytics](analytics/index.md):<br>View [DORA metrics](analytics/ci_cd_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
| [Analytics](analytics/index.md):<br>View [CI/CD analytics](analytics/ci_cd_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
-| [Analytics](analytics/index.md):<br>View [code review analytics](analytics/code_review_analytics.md) **(PREMIUM)** | | ✓ | ✓ | ✓ | ✓ |
-| [Analytics](analytics/index.md):<br>View [repository analytics](analytics/repository_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
+| [Analytics](analytics/index.md):<br>View [code review analytics](analytics/code_review_analytics.md) **(PREMIUM)** | | ✓ | ✓ | ✓ | ✓ |
+| [Analytics](analytics/index.md):<br>View [repository analytics](analytics/repository_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
| [Application security](application_security/index.md):<br>View licenses in [dependency list](application_security/dependency_list/index.md) **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
| [Application security](application_security/index.md):<br>Create and run [on-demand DAST scans](application_security/dast/index.md#on-demand-scans) **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
| [Application security](application_security/index.md):<br>Manage [security policy](application_security/policies/index.md) **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
| [Application security](application_security/index.md):<br>View [dependency list](application_security/dependency_list/index.md) **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
| [Application security](application_security/index.md):<br>View [threats list](application_security/threat_monitoring/index.md#threat-monitoring) **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Application security](application_security/index.md):<br>Create a [CVE ID Request](application_security/cve_id_request.md) **(FREE SAAS)** | | | | ✓ | ✓ |
+| [Application security](application_security/index.md):<br>Create a [CVE ID Request](application_security/cve_id_request.md) **(FREE SAAS)** | | | | ✓ | ✓ |
| [Application security](application_security/index.md):<br>Create or assign [security policy project](application_security/policies/index.md) **(ULTIMATE)** | | | | | ✓ |
| [CI/CD](../ci/README.md):<br>Download and browse job artifacts | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
| [CI/CD](../ci/README.md):<br>View a job log | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
@@ -74,13 +74,22 @@ The following table lists project permissions available for each role:
| [CI/CD](../ci/README.md):<br>Run Web IDE's Interactive Web Terminals **(ULTIMATE ONLY)** | | | | ✓ | ✓ |
| [CI/CD](../ci/README.md):<br>Use [environment terminals](../ci/environments/index.md#web-terminals) | | | | ✓ | ✓ |
| [CI/CD](../ci/README.md):<br>Delete pipelines | | | | | ✓ |
+| [Clusters](project/clusters/index.md):<br>View pod logs | | | ✓ | ✓ | ✓ |
+| [Clusters](project/clusters/index.md):<br>Manage clusters | | | | ✓ | ✓ |
+| [Container Registry](packages/container_registry/index.md):<br>Create, edit, delete cleanup policies | | | ✓ | ✓ | ✓ |
+| [Container Registry](packages/container_registry/index.md):<br>Remove a container registry image | | | ✓ | ✓ | ✓ |
+| [Container Registry](packages/container_registry/index.md):<br>Update container registry | | | ✓ | ✓ | ✓ |
+| [GitLab Pages](project/pages/index.md):<br>View Pages protected by [access control](project/pages/introduction.md#gitlab-pages-access-control) | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [GitLab Pages](project/pages/index.md):<br>Manage | | | | ✓ | ✓ |
+| [GitLab Pages](project/pages/index.md):<br>Manage GitLab Pages domains and certificates | | | | ✓ | ✓ |
+| [GitLab Pages](project/pages/index.md):<br>Remove GitLab Pages | | | | ✓ | ✓ |
| [Issues](project/issues/index.md):<br>Add Labels | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ |
| [Issues](project/issues/index.md):<br>Assign | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ |
| [Issues](project/issues/index.md):<br>Create | ✓ | ✓ | ✓ | ✓ | ✓ |
| [Issues](project/issues/index.md):<br>Create [confidential issues](project/issues/confidential_issues.md) | ✓ | ✓ | ✓ | ✓ | ✓ |
| [Issues](project/issues/index.md):<br>View [Design Management](project/issues/design_management.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ |
| [Issues](project/issues/index.md):<br>View related issues | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Set weight | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Set weight | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ |
| [Issues](project/issues/index.md):<br>View [confidential issues](project/issues/confidential_issues.md) | (*2*) | ✓ | ✓ | ✓ | ✓ |
| [Issues](project/issues/index.md):<br>Lock threads | | ✓ | ✓ | ✓ | ✓ |
| [Issues](project/issues/index.md):<br>Manage related issues | | ✓ | ✓ | ✓ | ✓ |
@@ -89,6 +98,10 @@ The following table lists project permissions available for each role:
| [Issues](project/issues/index.md):<br>Set issue [time tracking](project/time_tracking.md) estimate and time spent | | ✓ | ✓ | ✓ | ✓ |
| [Issues](project/issues/index.md):<br>Upload [Design Management](project/issues/design_management.md) files | | | ✓ | ✓ | ✓ |
| [Issues](project/issues/index.md):<br>Delete | | | | | ✓ |
+| [License Compliance](compliance/license_compliance/index.md):<br>View allowed and denied licenses **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [License Compliance](compliance/license_compliance/index.md):<br>View License Compliance reports **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [License Compliance](compliance/license_compliance/index.md):<br>View License list **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
+| [License Compliance](compliance/license_compliance/index.md):<br>Manage license policy **(ULTIMATE)** | | | | ✓ | ✓ |
| [Merge requests](project/merge_requests/index.md):<br>Assign reviewer | | ✓ | ✓ | ✓ | ✓ |
| [Merge requests](project/merge_requests/index.md):<br>See list | | ✓ | ✓ | ✓ | ✓ |
| [Merge requests](project/merge_requests/index.md):<br>Apply code change suggestions | | | ✓ | ✓ | ✓ |
@@ -97,26 +110,38 @@ The following table lists project permissions available for each role:
| [Merge requests](project/merge_requests/index.md):<br>Create | | | ✓ | ✓ | ✓ |
| [Merge requests](project/merge_requests/index.md):<br>Add labels | | | ✓ | ✓ | ✓ |
| [Merge requests](project/merge_requests/index.md):<br>Lock threads | | | ✓ | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Manage or accept | | | ✓ | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Manage or accept | | | ✓ | ✓ | ✓ |
| [Merge requests](project/merge_requests/index.md):<br>Manage merge approval rules (project settings) | | | | ✓ | ✓ |
| [Merge requests](project/merge_requests/index.md):<br>Delete | | | | | ✓ |
+| [Metrics dashboards](../operations/metrics/dashboards/index.md):<br>Manage user-starred metrics dashboards (*7*) | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Metrics dashboards](../operations/metrics/dashboards/index.md):<br>View metrics dashboard annotations | | ✓ | ✓ | ✓ | ✓ |
+| [Metrics dashboards](../operations/metrics/dashboards/index.md):<br>Create/edit/delete metrics dashboard annotations | | | ✓ | ✓ | ✓ |
+| [Package registry](packages/index.md):<br>Pull package | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [Package registry](packages/index.md):<br>Publish package | | | ✓ | ✓ | ✓ |
+| [Package registry](packages/index.md):<br>Delete package | | | | ✓ | ✓ |
+| [Project operations](../operations/index.md):<br>View [Error Tracking](../operations/error_tracking.md) list | | ✓ | ✓ | ✓ | ✓ |
+| [Project operations](../operations/index.md):<br>Manage [Feature Flags](../operations/feature_flags.md) **(PREMIUM)** | | | ✓ | ✓ | ✓ |
+| [Project operations](../operations/index.md):<br>Manage [Error Tracking](../operations/error_tracking.md) | | | | ✓ | ✓ |
| [Projects](project/index.md):<br>Download project | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
| [Projects](project/index.md):<br>Leave comments | ✓ | ✓ | ✓ | ✓ | ✓ |
| [Projects](project/index.md):<br>Reposition comments on images (posted by any user) | ✓ (*10*) | ✓ (*10*) | ✓ (*10*) | ✓ | ✓ |
| [Projects](project/index.md):<br>View Insights **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>View [releases](project/releases/index.md) | ✓ (*6*) | ✓ | ✓ | ✓ | ✓ |
| [Projects](project/index.md):<br>View Requirements **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ |
| [Projects](project/index.md):<br>View [time tracking](project/time_tracking.md) reports | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
| [Projects](project/index.md):<br>View [wiki](project/wiki/index.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ |
| [Projects](project/index.md):<br>Create [snippets](snippets.md) | | ✓ | ✓ | ✓ | ✓ |
| [Projects](project/index.md):<br>Manage labels | | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>View project statistics | | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>View project statistics | | ✓ | ✓ | ✓ | ✓ |
| [Projects](project/index.md):<br>Create, edit, delete [milestones](project/milestones/index.md). | | | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Create, edit, delete [releases](project/releases/index.md) | | | ✓ (*13*) | ✓ (*13*) | ✓ (*13*) |
| [Projects](project/index.md):<br>Create, edit [wiki](project/wiki/index.md) pages | | | ✓ | ✓ | ✓ |
| [Projects](project/index.md):<br>Enable Review Apps | | | ✓ | ✓ | ✓ |
| [Projects](project/index.md):<br>View project [Audit Events](../administration/audit_events.md) | | | ✓ (*11*) | ✓ | ✓ |
| [Projects](project/index.md):<br>Add deploy keys | | | | ✓ | ✓ |
| [Projects](project/index.md):<br>Add new team members | | | | ✓ | ✓ |
| [Projects](project/index.md):<br>Change [project features visibility](../public_access/public_access.md) level | | | | ✓ (14) | ✓ |
+| [Projects](project/index.md):<br>Configure [webhooks](project/integrations/webhooks.md) | | | | ✓ | ✓ |
| [Projects](project/index.md):<br>Delete [wiki](project/wiki/index.md) pages | | | | ✓ | ✓ |
| [Projects](project/index.md):<br>Edit comments (posted by any user) | | | | ✓ | ✓ |
| [Projects](project/index.md):<br>Edit project badges | | | | ✓ | ✓ |
@@ -133,6 +158,27 @@ The following table lists project permissions available for each role:
| [Projects](project/index.md):<br>Disable notification emails | | | | | ✓ |
| [Projects](project/index.md):<br>Rename project | | | | | ✓ |
| [Projects](project/index.md):<br>Transfer project to another namespace | | | | | ✓ |
+| [Repository](project/repository/index.md):<br>Pull project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>View project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>View a commit status | | ✓ | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Add tags | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Create new branches | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Create or update commit status | | | ✓ (*5*) | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Force push to non-protected branches | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Push to non-protected branches | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Remove non-protected branches | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Rewrite or remove Git tags | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Enable or disable branch protection | | | | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Enable or disable tag protection | | | | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Manage [push rules](../push_rules/push_rules.md) | | | | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Push to protected branches | | | | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Turn on or off protected branch push for developers | | | | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Remove fork relationship | | | | | ✓ |
+| [Repository](project/repository/index.md):<br>Force push to protected branches (*4*) | | | | | |
+| [Repository](project/repository/index.md):<br>Remove protected branches (*4*) | | | | | |
+| [Requirements Management](project/requirements/index.md):<br>Archive / reopen **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
+| [Requirements Management](project/requirements/index.md):<br>Create / edit **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
+| [Requirements Management](project/requirements/index.md):<br>Import / export **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
| [Security dashboard](application_security/security_dashboard/index.md):<br>View Security reports **(ULTIMATE)** | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
| [Security dashboard](application_security/security_dashboard/index.md):<br>Create issue from vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
| [Security dashboard](application_security/security_dashboard/index.md):<br>Create vulnerability from vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
@@ -143,60 +189,17 @@ The following table lists project permissions available for each role:
| [Security dashboard](application_security/security_dashboard/index.md):<br>Use security dashboard **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
| [Security dashboard](application_security/security_dashboard/index.md):<br>View vulnerability **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
| [Security dashboard](application_security/security_dashboard/index.md):<br>View vulnerability findings in [dependency list](application_security/dependency_list/index.md) **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| Manage user-starred metrics dashboards (*7*) | ✓ | ✓ | ✓ | ✓ | ✓ |
-| Pull project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| View [Releases](project/releases/index.md) | ✓ (*6*) | ✓ | ✓ | ✓ | ✓ |
-| View allowed and denied licenses **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| View GitLab Pages protected by [access control](project/pages/introduction.md#gitlab-pages-access-control) | ✓ | ✓ | ✓ | ✓ | ✓ |
-| View License Compliance reports **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| View project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| Archive [test case](../ci/test_cases/index.md) | | ✓ | ✓ | ✓ | ✓ |
-| Archive/reopen requirements **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
-| Create new [test case](../ci/test_cases/index.md) | | ✓ | ✓ | ✓ | ✓ |
-| Create/edit requirements **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
-| Import/export requirements **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
-| Move [test case](../ci/test_cases/index.md) | | ✓ | ✓ | ✓ | ✓ |
-| Pull [packages](packages/index.md) | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| Reopen [test case](../ci/test_cases/index.md) | | ✓ | ✓ | ✓ | ✓ |
-| See a commit status | | ✓ | ✓ | ✓ | ✓ |
-| View Error Tracking list | | ✓ | ✓ | ✓ | ✓ |
-| View License list **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
-| View metrics dashboard annotations | | ✓ | ✓ | ✓ | ✓ |
-| Add tags | | | ✓ | ✓ | ✓ |
-| Create new branches | | | ✓ | ✓ | ✓ |
-| Create or update commit status | | | ✓ (*5*) | ✓ | ✓ |
-| Create/edit/delete [releases](project/releases/index.md)| | | ✓ (*13*) | ✓ (*13*) | ✓ (*13*) |
-| Create/edit/delete a Cleanup policy | | | ✓ | ✓ | ✓ |
-| Create/edit/delete metrics dashboard annotations | | | ✓ | ✓ | ✓ |
-| Force push to non-protected branches | | | ✓ | ✓ | ✓ |
-| Manage Feature Flags **(PREMIUM)** | | | ✓ | ✓ | ✓ |
-| Publish [packages](packages/index.md) | | | ✓ | ✓ | ✓ |
-| Push to non-protected branches | | | ✓ | ✓ | ✓ |
-| Read Terraform state | | | ✓ | ✓ | ✓ |
-| Remove a container registry image | | | ✓ | ✓ | ✓ |
-| Remove non-protected branches | | | ✓ | ✓ | ✓ |
-| Rewrite/remove Git tags | | | ✓ | ✓ | ✓ |
-| Update a container registry | | | ✓ | ✓ | ✓ |
-| View Pods logs | | | ✓ | ✓ | ✓ |
-| Configure project hooks | | | | ✓ | ✓ |
-| Delete [packages](packages/index.md) | | | | ✓ | ✓ |
-| Enable/disable branch protection | | | | ✓ | ✓ |
-| Enable/disable tag protections | | | | ✓ | ✓ |
-| Manage [push rules](../push_rules/push_rules.md) | | | | ✓ | ✓ |
-| Manage clusters | | | | ✓ | ✓ |
-| Manage Error Tracking | | | | ✓ | ✓ |
-| Manage GitLab Pages | | | | ✓ | ✓ |
-| Manage GitLab Pages domains and certificates | | | | ✓ | ✓ |
-| Manage license policy **(ULTIMATE)** | | | | ✓ | ✓ |
-| Manage Terraform state | | | | ✓ | ✓ |
-| Push to protected branches | | | | ✓ | ✓ |
-| Remove GitLab Pages | | | | ✓ | ✓ |
-| Turn on/off protected branch push for developers | | | | ✓ | ✓ |
-| Remove fork relationship | | | | | ✓ |
-| Force push to protected branches (*4*) | | | | | |
-| Remove protected branches (*4*) | | | | | |
-
-1. Guest users are able to perform this action on public and internal projects, but not private projects. This doesn't apply to [external users](#external-users) where explicit access must be given even if the project is internal.
+| [Terraform](infrastructure/index.md):<br>Read Terraform state | | | ✓ | ✓ | ✓ |
+| [Terraform](infrastructure/index.md):<br>Manage Terraform state | | | | ✓ | ✓ |
+| [Test cases](../ci/test_cases/index.md):<br>Archive | | ✓ | ✓ | ✓ | ✓ |
+| [Test cases](../ci/test_cases/index.md):<br>Create | | ✓ | ✓ | ✓ | ✓ |
+| [Test cases](../ci/test_cases/index.md):<br>Move | | ✓ | ✓ | ✓ | ✓ |
+| [Test cases](../ci/test_cases/index.md):<br>Reopen | | ✓ | ✓ | ✓ | ✓ |
+
+1. On self-managed GitLab instances, guest users are able to perform this action only on
+ public and internal projects (not on private projects). [External users](#external-users)
+ must be given explicit access even if the project is internal. For GitLab.com, see the
+ [GitLab.com visibility settings](gitlab_com/index.md#visibility-settings).
1. Guest users can only view the [confidential issues](project/issues/confidential_issues.md) they created themselves.
1. If **Public pipelines** is enabled in **Project Settings > CI/CD**.
1. Not allowed for Guest, Reporter, Developer, Maintainer, or Owner. See [protected branches](project/protected_branches.md).
@@ -242,10 +245,10 @@ to learn more.
Find the current permissions on the Value Stream Analytics dashboard, as described in
[related documentation](analytics/value_stream_analytics.md#permissions).
-### Issue Board permissions
+### Issue board permissions
-Find the current permissions for interacting with the Issue Board feature in the
-[Issue Boards permissions page](project/issue_board.md#permissions).
+Find the current permissions for interacting with the issue board feature in the
+[issue boards permissions page](project/issue_board.md#permissions).
### File Locking permissions **(PREMIUM)**
@@ -280,6 +283,7 @@ The following table lists group permissions available for each role:
|--------------------------------------------------------|-------|----------|-----------|------------|-------|
| Browse group | ✓ | ✓ | ✓ | ✓ | ✓ |
| Edit SAML SSO Billing **(PREMIUM SAAS)** | ✓ | ✓ | ✓ | ✓ | ✓ (4) |
+| Pull a container image using the dependency proxy | ✓ | ✓ | ✓ | ✓ | ✓ |
| View Contribution analytics | ✓ | ✓ | ✓ | ✓ | ✓ |
| View group epic **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ |
| View group wiki pages **(PREMIUM)** | ✓ (6) | ✓ | ✓ | ✓ | ✓ |
@@ -301,7 +305,6 @@ The following table lists group permissions available for each role:
| Create/edit/delete iterations | | | ✓ | ✓ | ✓ |
| Create/edit/delete metrics dashboard annotations | | | ✓ | ✓ | ✓ |
| Enable/disable a dependency proxy | | | ✓ | ✓ | ✓ |
-| Pull a container image using the dependency proxy | ✓ | ✓ | ✓ | ✓ | ✓ |
| Purge the dependency proxy for a group | | | | | ✓ |
| Publish [packages](packages/index.md) | | | ✓ | ✓ | ✓ |
| Use security dashboard **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
@@ -314,6 +317,7 @@ The following table lists group permissions available for each role:
| View/manage group-level Kubernetes cluster | | | | ✓ | ✓ |
| Administer project compliance frameworks | | | | | ✓ |
| Create/Delete group deploy tokens | | | | | ✓ |
+| Change group visibility level | | | | | ✓ |
| Delete group | | | | | ✓ |
| Delete group epic **(PREMIUM)** | | | | | ✓ |
| Disable notification emails | | | | | ✓ |
@@ -381,7 +385,7 @@ An administrator can flag a user as external by either of the following methods:
- [Through the API](../api/users.md#user-modification).
- Using the GitLab UI:
- 1. On the top bar, select **Menu >** **{admin}** **Admin**.
+ 1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Users** to create a new user or edit an existing one.
There, you can find the option to flag the user as external.
@@ -393,7 +397,7 @@ and [LDAP groups](../administration/auth/ldap/index.md#external-groups).
By default, new users are not set as external users. This behavior can be changed
by an administrator:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > General**.
1. Expand the **Account and limit** section.
diff --git a/doc/user/profile/account/create_accounts.md b/doc/user/profile/account/create_accounts.md
index 972414dbf0b..3cc56cc47e6 100644
--- a/doc/user/profile/account/create_accounts.md
+++ b/doc/user/profile/account/create_accounts.md
@@ -26,7 +26,7 @@ their own accounts by either:
As an Admin user, you can manually create users:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Users** (`/admin/users`).
1. Select **New user**.
diff --git a/doc/user/profile/account/delete_account.md b/doc/user/profile/account/delete_account.md
index f6af373e295..41b4e508c38 100644
--- a/doc/user/profile/account/delete_account.md
+++ b/doc/user/profile/account/delete_account.md
@@ -21,14 +21,14 @@ As a user, to delete your own account:
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. In the left sidebar, select **Account**.
+1. On the left sidebar, select **Account**.
1. Select **Delete account**.
## As an administrator
As an administrator, to delete a user account:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Users**.
1. Select a user.
1. Under the **Account** tab, select:
diff --git a/doc/user/profile/account/two_factor_authentication.md b/doc/user/profile/account/two_factor_authentication.md
index 597170540ab..14e6f4dad3a 100644
--- a/doc/user/profile/account/two_factor_authentication.md
+++ b/doc/user/profile/account/two_factor_authentication.md
@@ -35,8 +35,19 @@ still access your account if you lose your U2F / WebAuthn device.
## Enabling 2FA
-There are multiple ways to enable two-factor authentication: by using a one-time
-password authenticator or a U2F / WebAuthn device.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35102) in GitLab 14.3, account email confirmation required.
+
+There are multiple ways to enable two-factor authentication (2FA):
+
+- Using a one-time password authenticator.
+- Using a U2F / WebAuthn device.
+
+In GitLab 14.3 and later, your account email must be confirmed to enable two-factor authentication.
+
+FLAG:
+On self-managed GitLab, account email confirmation requirement is enabled. To disable this
+restriction, ask an administrator to
+[disable the `ensure_verified_primary_email_for_2fa` flag](../../../administration/feature_flags.md).
### One-time password
@@ -377,7 +388,7 @@ have lost your code generation device) you can:
- [Use a saved recovery code](#use-a-saved-recovery-code).
- [Generate new recovery codes using SSH](#generate-new-recovery-codes-using-ssh).
- [Regenerate 2FA recovery codes](#regenerate-2fa-recovery-codes).
-- [Ask a GitLab administrator to disable two-factor authentication on your account](#ask-a-gitlab-administrator-to-disable-two-factor-authentication-on-your-account).
+- [Have 2FA disabled on your account](#have-2fa-disabled-on-your-account).
### Use a saved recovery code
@@ -454,12 +465,9 @@ To regenerate 2FA recovery codes, you need access to a desktop browser:
NOTE:
If you regenerate 2FA recovery codes, save them. You can't use any previously created 2FA codes.
-### Ask a GitLab administrator to disable two-factor authentication on your account
+### Have 2FA disabled on your account
-If you cannot use a saved recovery code or generate new recovery codes, ask a
-GitLab global administrator to disable two-factor authentication for your
-account. This temporarily leaves your account in a less secure state.
-Sign in and re-enable two-factor authentication as soon as possible.
+If you cannot use a saved recovery code or generate new recovery codes then please submit a [support ticket](https://support.gitlab.com/hc/en-us/requests/new) requesting that a GitLab global administrator disables two-factor authentication for your account. Please note that only the actual owner of the account can make this request and that disabling this setting will temporarily leave your account in a less secure state. You should therefore sign in and re-enable two-factor authentication as soon as possible.
## Note to GitLab administrators
@@ -516,7 +524,7 @@ To avoid the time sync issue, enable time synchronization in the device that gen
1. Go to Settings.
1. Select General.
1. Select Date & Time.
- 1. Enable Set Automatically. If it’s already enabled, disable it, wait a few seconds, and re-enable.
+ 1. Enable Set Automatically. If it's already enabled, disable it, wait a few seconds, and re-enable.
<!-- ## Troubleshooting
diff --git a/doc/user/profile/active_sessions.md b/doc/user/profile/active_sessions.md
index e55b92378bd..25f349d9272 100644
--- a/doc/user/profile/active_sessions.md
+++ b/doc/user/profile/active_sessions.md
@@ -18,7 +18,7 @@ To list all active sessions:
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. In the left sidebar, select **Active Sessions**.
+1. On the left sidebar, select **Active Sessions**.
![Active sessions list](img/active_sessions_list.png)
@@ -35,7 +35,7 @@ To revoke an active session:
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. In the left sidebar, select **Active Sessions**.
+1. On the left sidebar, select **Active Sessions**.
1. Select **Revoke** next to a session. The current session cannot be revoked, as this would sign you out of GitLab.
NOTE:
diff --git a/doc/user/profile/img/notification_group_settings_v12_8.png b/doc/user/profile/img/notification_group_settings_v12_8.png
deleted file mode 100644
index 4aa4c32a260..00000000000
--- a/doc/user/profile/img/notification_group_settings_v12_8.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/profile/img/notification_project_settings_v12_8.png b/doc/user/profile/img/notification_project_settings_v12_8.png
deleted file mode 100644
index 9b8837a4ef4..00000000000
--- a/doc/user/profile/img/notification_project_settings_v12_8.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/profile/index.md b/doc/user/profile/index.md
index 2c76b46249e..24006e6f875 100644
--- a/doc/user/profile/index.md
+++ b/doc/user/profile/index.md
@@ -31,7 +31,7 @@ To change your password:
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. In the left sidebar, select **Password**.
+1. On the left sidebar, select **Password**.
1. In the **Current password** field, enter your current password.
1. In the **New password** and **Password confirmation** field, enter your new password.
1. Select **Save password**.
@@ -55,10 +55,21 @@ To change your username:
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. In the left sidebar, select **Account**.
+1. On the left sidebar, select **Account**.
1. In the **Change username** section, enter a new username as the path.
1. Select **Update username**.
+## Add emails to your user profile
+
+To add new email to your account:
+
+1. In the top-right corner, select your avatar.
+1. Select **Edit profile**.
+1. On the left sidebar, select **Emails**.
+1. In the **Email** box, enter the new email.
+1. Select **Add email address**.
+1. Verify your email address with the verification email received.
+
## Make your user profile page private
You can make your user profile visible to only you and GitLab administrators.
@@ -219,6 +230,7 @@ To set your time zone:
A commit email is an email address displayed in every Git-related action carried out through the GitLab interface.
Any of your own verified email addresses can be used as the commit email.
+Your primary email is used by default.
To change your commit email:
diff --git a/doc/user/profile/notifications.md b/doc/user/profile/notifications.md
index 17b4251662e..aaa311a4097 100644
--- a/doc/user/profile/notifications.md
+++ b/doc/user/profile/notifications.md
@@ -5,57 +5,72 @@ group: Project Management
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
---
-# GitLab Notification Emails **(FREE)**
+# Notification emails **(FREE)**
-GitLab Notifications allow you to stay informed about what's happening in GitLab. With notifications
-enabled, you can receive updates about activity in issues, merge requests, epics, and designs.
-Notifications are sent via email.
+Stay informed about what's happening in GitLab with email notifications.
+You can receive updates about activity in issues, merge requests, epics, and designs.
-For the tool that enables GitLab administrators to send messages to users, read
+For the tool that GitLab administrators can use to send messages to users, read
[Email from GitLab](../../tools/email.md).
-## Receiving notifications
+## Receive notifications
You receive notifications for one of the following reasons:
-- You participate in an issue, merge request, epic, or design. In this context, _participate_ means comment, or edit.
-- You [enable notifications in an issue, merge request, or epic](#notifications-on-issues-merge-requests-and-epics).
+- You participate in an issue, merge request, epic, or design. In this context, _participate_ means
+ comment or edit.
+- You've [enabled notifications in an issue, merge request, or epic](#notifications-on-issues-merge-requests-and-epics).
- You configured notifications at the [project](#project-notifications) and/or [group](#group-notifications) level.
While notifications are enabled, you receive notification of actions occurring in that issue, merge request, or epic.
NOTE:
-Notifications can be blocked by an administrator, preventing them from being sent.
+Administrators can block notifications, preventing them from being sent.
-## Tuning your notifications
+## Tune your notifications
-The number of notifications can be overwhelming. GitLab allows you to tune the notifications you receive.
+Getting many notifications can be overwhelming. You can tune the notifications you receive.
For example, you might want to be notified about all activity in a specific project.
-For other projects, you only need to be notified when you are mentioned by name.
+For other projects, you only want to be notified when you are mentioned by name.
-You can tune the notifications you receive by combining your notification settings:
+You can tune the notifications you receive by changing your notification settings:
- [Global notification settings](#global-notification-settings)
- [Notification scope](#notification-scope)
- [Notification levels](#notification-levels)
-## Editing notification settings
+## Edit notification settings
+
+These notification settings apply only to you. They do not affect the notifications received by
+anyone else in the same project or group.
To edit your notification settings:
1. In the top-right corner, select your avatar.
1. Select **Preferences**.
-1. In the left sidebar, select **Notifications**.
+1. On the left sidebar, select **Notifications**.
1. Edit the desired notification settings. Edited settings are automatically saved and enabled.
-These notification settings apply only to you. They do not affect the notifications received by anyone else in the same project or group.
+## Notification scope
+
+You can tune the scope of your notifications by selecting different notification levels for each project and group.
-## Global notification settings
+Notification scope is applied from the broadest to most specific levels:
+
+- **Global (default)**: Your global, or _default_, notification level applies if you
+ have not selected a notification level for the project or group in which the activity occurred.
+- **Group**: For each group, you can select a notification level. Your group setting
+ overrides your default setting.
+- **Project**: For each project, you can select a notification level. Your project
+ setting overrides the group setting.
+
+### Global notification settings
Your **Global notification settings** are the default settings unless you select
different values for a project or a group.
- **Notification email**: the email address your notifications are sent to.
+ Defaults to your primary email address.
- **Receive product marketing emails**: select this checkbox to receive
[periodic emails](#product-marketing-emails) about GitLab features.
- **Global notification level**: the default [notification level](#notification-levels)
@@ -65,95 +80,78 @@ different values for a project or a group.
![notification settings](img/notification_global_settings_v13_12.png)
-### Notification scope
-
-You can tune the scope of your notifications by selecting different notification levels for each project and group.
+### Group notifications
-Notification scope is applied in order of precedence (highest to lowest):
-
-- **Project**: For each project, you can select a notification level. Your project
- setting overrides the group setting.
-- **Group**: For each group, you can select a notification level. Your group setting
- overrides your default setting.
-- **Global (default)**: Your global, or _default_, notification level applies if you
- have not selected a notification level for the project or group in which the activity occurred.
-
-#### Project notifications
-
-You can select a notification level for each project to help you closely monitor activity in select projects.
+You can select a notification level and email address for each group.
-![notification settings](img/notification_project_settings_v12_8.png)
+#### Group notification level
-To select a notification level for a project, use either of these methods:
+To select a notification level for a group, use either of these methods:
1. In the top-right corner, select your avatar.
1. Select **Preferences**.
-1. In the left sidebar, select **Notifications**.
-1. Locate the project in the **Projects** section.
+1. On the left sidebar, select **Notifications**.
+1. Locate the project in the **Groups** section.
1. Select the desired [notification level](#notification-levels).
Or:
-1. Go to your project.
-1. Select the notification dropdown, marked with a bell icon (**{notifications}**).
+1. On the top bar, select **Menu > Groups** and find your group.
+1. Select the notification dropdown, next to the bell icon (**{notifications}**).
1. Select the desired [notification level](#notification-levels).
-<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
-For a demonstration of how to be notified when a new release is available, see [Notification for releases](https://www.youtube.com/watch?v=qyeNkGgqmH4).
+#### Group notification email address
-#### Group notifications
+> Introduced in GitLab 12.0
-You can select a notification level and email address for each group.
+You can select an email address to receive notifications for each group you belong to. This could be useful, for example, if you work freelance, and want to keep email about clients' projects separate.
-![notification settings](img/notification_group_settings_v12_8.png)
+1. In the top-right corner, select your avatar.
+1. Select **Preferences**.
+1. On the left sidebar, select **Notifications**.
+1. Locate the project in the **Groups** section.
+1. Select the desired email address.
-##### Group notification level
+### Project notifications
-To select a notification level for a group, use either of these methods:
+You can select a notification level for each project to help you closely monitor activity in select projects.
+
+To select a notification level for a project, use either of these methods:
1. In the top-right corner, select your avatar.
1. Select **Preferences**.
-1. In the left sidebar, select **Notifications**.
-1. Locate the project in the **Groups** section.
+1. On the left sidebar, select **Notifications**.
+1. Locate the project in the **Projects** section.
1. Select the desired [notification level](#notification-levels).
----
+Or:
-1. Go to your group.
-1. Select the notification dropdown, marked with a bell icon (**{notifications}**).
+1. On the top bar, select **Menu > Projects** and find your project.
+1. Select the notification dropdown, next to the bell icon (**{notifications}**).
1. Select the desired [notification level](#notification-levels).
-##### Group notification email address
-
-> Introduced in GitLab 12.0
-
-You can select an email address to receive notifications for each group you belong to. This could be useful, for example, if you work freelance, and want to keep email about clients' projects separate.
-
-1. In the top-right corner, select your avatar.
-1. Select **Preferences**.
-1. In the left sidebar, select **Notifications**.
-1. Locate the project in the **Groups** section.
-1. Select the desired email address.
+<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
+To learn how to be notified when a new release is available, see [Notification for releases](https://www.youtube.com/watch?v=qyeNkGgqmH4).
### Notification levels
For each project and group you can select one of the following levels:
-| Level | Description |
-|:------------|:------------|
-| Global | Your global settings apply. |
-| Watch | Receive notifications for any activity. |
+| Level | Description |
+| ----------- | ----------------------------------------------------------- |
+| Global | Your global settings apply. |
+| Watch | Receive notifications for any activity. |
| On mention | Receive notifications when [mentioned](../project/issues/issue_data_and_actions.md#mentions) in a comment. |
| Participate | Receive notifications for threads you have participated in. |
-| Disabled | Turns off notifications. |
-| Custom | Receive notifications for custom selected events. |
+| Disabled | Turns off notifications. |
+| Custom | Receive notifications for custom selected events. |
### Product marketing emails
You can receive emails that teach you about various GitLab features.
This is enabled by default.
-To opt out, [edit your notification settings](#editing-notification-settings) and clear the
+To opt out, [edit your notification settings](#edit-notification-settings) and clear the
**Receive product marketing emails** checkbox.
Disabling these emails does not disable all emails.
@@ -173,51 +171,56 @@ for all users.
Users are notified of the following events:
+<!-- The table is sorted first by recipient, then alphabetically. -->
+
| Event | Sent to | Settings level |
|------------------------------|---------------------|------------------------------|
-| New SSH key added | User | Security email, always sent. |
-| SSH key has expired | User | Security email, always sent. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/322637) in GitLab 13.12 |
-| New email added | User | Security email, always sent. |
+| New release | Project members | Custom notification |
+| Project moved | Project members (1) | (1) not disabled |
| Email changed | User | Security email, always sent. |
+| Group access level changed | User | Sent when user group access level is changed |
+| New email added | User | Security email, always sent. |
+| New SAML/SCIM user provisioned | User | Sent when a user is provisioned through SAML/SCIM. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/276018) in GitLab 13.8 |
+| New SSH key added | User | Security email, always sent. |
+| New user created | User | Sent on user creation, except for OmniAuth (LDAP)|
| Password changed | User | Security email, always sent when user changes their own password |
| Password changed by administrator | User | Security email, always sent when an administrator changes the password of another user |
-| Two-factor authentication disabled | User | Security email, always sent. |
-| New user created | User | Sent on user creation, except for OmniAuth (LDAP)|
-| New SAML/SCIM user provisioned | User | Sent when a user is provisioned through SAML/SCIM. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/276018) in GitLab 13.8 |
-| User added to project | User | Sent when user is added to project |
+| Personal access tokens expiring soon <!-- Do not delete or lint this instance of future tense --> | User | Security email, always sent. |
+| Personal access tokens have expired | User | Security email, always sent. |
| Project access level changed | User | Sent when user project access level is changed |
+| SSH key has expired | User | Security email, always sent. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/322637) in GitLab 13.12 |
+| Two-factor authentication disabled | User | Security email, always sent. |
| User added to group | User | Sent when user is added to group |
-| Group access level changed | User | Sent when user group access level is changed |
-| Personal Access Tokens expiring soon <!-- Do not delete or lint this instance of future tense --> | User | Security email, always sent. |
-| Personal Access Tokens have expired | User | Security email, always sent. |
-| Project moved | Project members (1) | (1) not disabled |
-| New release | Project members | Custom notification |
+| User added to project | User | Sent when user is added to project |
## Notifications on issues, merge requests, and epics
-To enable notifications on one specific issue, merge request or epic, you need to enable the **Notifications** toggle in the right sidebar.
+To enable notifications on a specific issue, merge request, or epic, you must turn on the
+**Notifications** toggle in the right sidebar.
-- **Enable**: If you are not a participant in the discussion on that issue, but
- want to receive notifications on each update, subscribe to it.
-- **Disable**: If you are receiving notifications for updates to that issue but no
- longer want to receive them, unsubscribe from it.
+- To subscribe, **turn on** if you are not a participant in the discussion, but want to receive
+ notifications on each update.
+- To unsubscribe, **turn off** if you are receiving notifications for updates but no longer want to
+ receive them, unsubscribe from it.
-Disabling this toggle only unsubscribes you from updates related to this issue, merge request, or epic.
+Turning this toggle off only unsubscribes you from updates related to this issue, merge request, or epic.
Learn how to [opt out of all emails from GitLab](#opt-out-of-all-gitlab-emails).
-Enabling this notification on an epic doesn't automatically subscribe you to the issues linked
+Turning notifications on in an epic doesn't automatically subscribe you to the issues linked
to the epic.
For most events, the notification is sent to:
- Participants:
- The author and assignee of the issue/merge request.
- - Authors of comments on the issue/merge request.
- - Anyone mentioned by `@username` in the title or description of the issue, merge request or epic.
- - Anyone with notification level "Participating" or higher that is mentioned by `@username` in any of the comments on the issue, merge request, or epic.
+ - Authors of comments.
+ - Anyone [mentioned](../project/issues/issue_data_and_actions.md#mentions) by username in the title
+ or description of the issue, merge request or epic.
+ - Anyone with notification level "Participating" or higher that is mentioned by their username in
+ any of the comments on the issue, merge request, or epic.
- Watchers: users with notification level "Watch".
- Subscribers: anyone who manually subscribed to the issue, merge request, or epic.
-- Custom: Users with notification level "custom" who turned on notifications for any of the events present in the table below.
+- Custom: Users with notification level "custom" who turned on notifications for any of the events in the following table.
NOTE:
To minimize the number of notifications that do not require any action, in
@@ -259,16 +262,17 @@ If the title or description of an issue or merge request is
changed, notifications are sent to any **new** mentions by `@username` as
if they had been mentioned in the original text.
-You don't receive notifications for issues, merge requests or milestones created
-by yourself (except when an issue is due). You only receive automatic
-notifications when somebody else comments or adds changes to the ones that
-you've created or mentions you.
+By default, you don't receive notifications for issues, merge requests, or epics created
+by yourself. You only receive notifications when somebody else comments or adds changes to the ones
+that you've created or mentions you, or when an issue is due soon.
+To always receive notifications on your own issues and so on, you must turn on
+[notifications about your own activity](#global-notification-settings).
If an open merge request becomes unmergeable due to conflict, its author is notified about the cause.
-If a user has also set the merge request to automatically merge once pipeline succeeds,
+If a user has also set the merge request to automatically merge when pipeline succeeds,
then that user is also notified.
-## Design email notifications
+## Notifications on designs
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217095) in GitLab 13.6.
@@ -284,7 +288,7 @@ The participants are:
If you no longer wish to receive any email notifications:
-1. [Go to the Notifications settings page.](#editing-notification-settings)
+1. [Go to the Notifications settings page.](#edit-notification-settings)
1. Clear the **Receive product marketing emails** checkbox.
1. Set your **Global notification level** to **Disabled**.
1. Clear the **Receive notifications about your own activity** checkbox.
@@ -295,7 +299,7 @@ On self-managed installations, even after doing this, your instance administrato
[can still email you](../../tools/email.md).
To unsubscribe, select the unsubscribe link in one of these emails.
-## Filtering email
+## Filter email
Notification email messages include GitLab-specific headers. You can filter the notification emails based on the content of these headers to better manage your notifications. For example, you could filter all emails for a specific project where you are being assigned either a merge request or issue.
diff --git a/doc/user/profile/personal_access_tokens.md b/doc/user/profile/personal_access_tokens.md
index c534a630480..bdd49b00a15 100644
--- a/doc/user/profile/personal_access_tokens.md
+++ b/doc/user/profile/personal_access_tokens.md
@@ -12,11 +12,26 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - Introduced in GitLab 13.3: [Additional notifications for expiring tokens](https://gitlab.com/gitlab-org/gitlab/-/issues/214721).
> - Introduced in GitLab 14.1: [Prefill token name and scopes](https://gitlab.com/gitlab-org/gitlab/-/issues/334664).
-If you're unable to use [OAuth2](../../api/oauth2.md), you can use a personal access token to authenticate with the [GitLab API](../../api/index.md#personalproject-access-tokens). You can also use a personal access token with Git to authenticate over HTTP.
+Personal access tokens can be an alternative to [OAuth2](../../api/oauth2.md) and used to:
+
+- Authenticate with the [GitLab API](../../api/index.md#personalproject-access-tokens).
+- Authenticate with Git using HTTP Basic Authentication.
In both cases, you authenticate with a personal access token in place of your password.
-Personal access tokens are required when [Two-Factor Authentication (2FA)](account/two_factor_authentication.md) is enabled.
+Personal access tokens are:
+
+- Required when [two-factor authentication (2FA)](account/two_factor_authentication.md) is enabled.
+- Used with a GitLab username to authenticate with GitLab features that require usernames. For example,
+ [GitLab managed Terraform state backend](../infrastructure/iac/terraform_state.md#using-a-gitlab-managed-terraform-state-backend-as-a-remote-data-source)
+ and [Docker container registry](../packages/container_registry/index.md#authenticate-with-the-container-registry),
+- Similar to [project access tokens](../project/settings/project_access_tokens.md), but are attached
+ to a user rather than a project.
+
+NOTE:
+Though required, GitLab usernames are ignored when authenticating with a personal access token.
+There is an [issue for tracking](https://gitlab.com/gitlab-org/gitlab/-/issues/212953) to make GitLab
+use the username.
For examples of how you can use a personal access token to authenticate with the API, see the [API documentation](../../api/index.md#personalproject-access-tokens).
@@ -29,7 +44,7 @@ You can create as many personal access tokens as you like.
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. In the left sidebar, select **Access Tokens**.
+1. On the left sidebar, select **Access Tokens**.
1. Enter a name and optional expiry date for the token.
1. Select the [desired scopes](#personal-access-token-scopes).
1. Select **Create personal access token**.
@@ -53,7 +68,7 @@ At any time, you can revoke a personal access token.
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. In the left sidebar, select **Access Tokens**.
+1. On the left sidebar, select **Access Tokens**.
1. In the **Active personal access tokens** area, next to the key, select **Revoke**.
## View the last time a token was used
@@ -65,7 +80,7 @@ To view the last time a token was used:
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. In the left sidebar, select **Access Tokens**.
+1. On the left sidebar, select **Access Tokens**.
1. In the **Active personal access tokens** area, next to the key, view the **Last Used** date.
## Personal access token scopes
diff --git a/doc/user/project/canary_deployments.md b/doc/user/project/canary_deployments.md
index cac283f6f18..b4723294438 100644
--- a/doc/user/project/canary_deployments.md
+++ b/doc/user/project/canary_deployments.md
@@ -26,7 +26,7 @@ percentage of users are affected and the change can either be fixed or quickly
reverted.
Leveraging [Kubernetes' Canary deployments](https://kubernetes.io/docs/concepts/cluster-administration/manage-deployment/#canary-deployments), visualize your canary
-deployments right inside the [Deploy Board](deploy_boards.md), without the need to leave GitLab.
+deployments right inside the [deploy board](deploy_boards.md), without the need to leave GitLab.
## Use cases
@@ -47,9 +47,9 @@ this document.
## Enabling Canary Deployments
-Canary deployments require that you properly configure Deploy Boards:
+Canary deployments require that you properly configure deploy boards:
-1. Follow the steps to [enable Deploy Boards](deploy_boards.md#enabling-deploy-boards).
+1. Follow the steps to [enable deploy boards](deploy_boards.md#enabling-deploy-boards).
1. To track canary deployments you need to label your Kubernetes deployments and
pods with `track: canary`. To get started quickly, you can use the [Auto Deploy](../../topics/autodevops/stages.md#auto-deploy)
template for canary deployments that GitLab provides.
@@ -61,13 +61,13 @@ This allows GitLab to discover whether a deployment is stable or canary (tempora
Once all of the above are set up and the pipeline has run at least once,
navigate to the environments page under **Pipelines > Environments**.
-As the pipeline executes, Deploy Boards clearly mark canary pods, enabling
+As the pipeline executes, deploy boards clearly mark canary pods, enabling
quick and easy insight into the status of each environment and deployment.
-Canary deployments are marked with a yellow dot in the Deploy Board so that you
+Canary deployments are marked with a yellow dot in the deploy board so that you
can easily notice them.
-![Canary deployments on Deploy Board](img/deploy_boards_canary_deployments.png)
+![Canary deployments on deploy board](img/deploy_boards_canary_deployments.png)
### Advanced traffic control with Canary Ingress
@@ -104,17 +104,17 @@ Here's an example setup flow from scratch:
#### How to check the current traffic weight on a Canary Ingress
-1. Visit the [Deploy Board](../../user/project/deploy_boards.md).
+1. Visit the [deploy board](../../user/project/deploy_boards.md).
1. View the current weights on the right.
![Rollout Status Canary Ingress](img/canary_weight.png)
#### How to change the traffic weight on a Canary Ingress
-You can change the traffic weight within your environment's Deploy Board by using [GraphiQL](../../api/graphql/getting_started.md#graphiql),
+You can change the traffic weight within your environment's deploy board by using [GraphiQL](../../api/graphql/getting_started.md#graphiql),
or by sending requests to the [GraphQL API](../../api/graphql/getting_started.md#command-line).
-To use your [Deploy Board](../../user/project/deploy_boards.md):
+To use your [deploy board](../../user/project/deploy_boards.md):
1. Navigate to **Deployments > Environments** for your project.
1. Set the new weight with the dropdown on the right side.
diff --git a/doc/user/project/clusters/add_eks_clusters.md b/doc/user/project/clusters/add_eks_clusters.md
index 7d006247177..f7dd24fcfad 100644
--- a/doc/user/project/clusters/add_eks_clusters.md
+++ b/doc/user/project/clusters/add_eks_clusters.md
@@ -10,7 +10,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/327908) in GitLab 14.0.
WARNING:
-Use [Infrastrucure as Code](../../infrastructure/index.md) to create new clusters. The method described in this document is deprecated as of GitLab 14.0.
+Use [Infrastructure as Code](../../infrastructure/index.md) to create new clusters. The method described in this document is deprecated as of GitLab 14.0.
Through GitLab, you can create new clusters and add existing clusters hosted on Amazon Elastic
Kubernetes Service (EKS).
@@ -48,7 +48,7 @@ To create a new EKS cluster:
1. Go to your:
- Project's **Infrastructure > Kubernetes clusters** page, for a project-level cluster.
- Group's **Kubernetes** page, for a group-level cluster.
- - **Menu >** **{admin}** **Admin > Kubernetes**, for an instance-level cluster.
+ - **Menu > Admin > Kubernetes**, for an instance-level cluster.
1. Select **Integrate with a cluster certificate**.
1. Under the **Create new cluster** tab, click **Amazon EKS** to display an
`Account ID` and `External ID` needed for later steps.
@@ -166,7 +166,7 @@ When you create a new cluster, you have the following settings:
| Kubernetes cluster name | Your cluster's name. |
| Environment scope | The [associated environment](multiple_kubernetes_clusters.md#setting-the-environment-scope). |
| Service role | The **EKS IAM role** (**role A**). |
-| Kubernetes version | The [Kubernetes version](index.md#supported-cluster-versions) for your cluster. |
+| Kubernetes version | The [Kubernetes version](../../infrastructure/clusters/connect/index.md#supported-cluster-versions) for your cluster. |
| Key pair name | The [key pair](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html) that you can use to connect to your worker nodes. |
| VPC | The [VPC](https://docs.aws.amazon.com/vpc/latest/userguide/what-is-amazon-vpc.html) to use for your EKS Cluster resources. |
| Subnets | The [subnets](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Subnets.html) in your VPC where your worker nodes run. Two are required. |
@@ -240,7 +240,7 @@ For example, the following policy document allows assuming a role whose name sta
To configure Amazon authentication in GitLab, generate an access key for the
IAM user in the Amazon AWS console, and follow these steps:
-1. In GitLab, on the top bar, select **Menu >** **{admin}** **Admin > Settings > General** and expand the **Amazon EKS** section.
+1. In GitLab, on the top bar, select **Menu > Admin > Settings > General** and expand the **Amazon EKS** section.
1. Check **Enable Amazon EKS integration**.
1. Enter your **Account ID**.
1. Enter your [access key and ID](#eks-access-key-and-id).
diff --git a/doc/user/project/clusters/add_existing_cluster.md b/doc/user/project/clusters/add_existing_cluster.md
index efd480fa3ce..505c493de4e 100644
--- a/doc/user/project/clusters/add_existing_cluster.md
+++ b/doc/user/project/clusters/add_existing_cluster.md
@@ -4,11 +4,17 @@ group: Configure
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
---
-# Add an existing Kubernetes cluster
+# Connect existing clusters through cluster certificates
If you have an existing Kubernetes cluster, you can add it to a project, group,
or instance and benefit from the integration with GitLab.
+WARNING:
+The process described on this page uses cluster certificates to connect your cluster
+to GitLab. Although this method still works, it is **no longer recommended**.
+To connect your cluster to GitLab, we **recommend** using the [GitLab Kubernetes Agent](../../clusters/agent/index.md)
+instead. **(PREMIUM)**
+
## Prerequisites
See the prerequisites below to add existing clusters to GitLab.
@@ -61,7 +67,7 @@ To add a Kubernetes cluster to your project, group, or instance:
1. Navigate to your:
1. Project's **{cloud-gear}** **Infrastructure > Kubernetes clusters** page, for a project-level cluster.
1. Group's **{cloud-gear}** **Kubernetes** page, for a group-level cluster.
- 1. **Menu >** **{admin}** **Admin >** **{cloud-gear}** **Kubernetes** page, for an instance-level cluster.
+ 1. **Menu > Admin > Kubernetes** page, for an instance-level cluster.
1. Click **Add Kubernetes cluster**.
1. Click the **Add existing cluster** tab and fill in the details:
1. **Kubernetes cluster name** (required) - The name you wish to give the cluster.
@@ -211,7 +217,8 @@ integration to work properly.
WARNING:
Disabling RBAC means that any application running in the cluster,
or user who can authenticate to the cluster, has full API access. This is a
-[security concern](index.md#security-implications), and may not be desirable.
+[security concern](../../infrastructure/clusters/connect/index.md#security-implications-for-clusters-connected-with-certificates),
+and may not be desirable.
To effectively disable RBAC, global permissions can be applied granting full access:
diff --git a/doc/user/project/clusters/add_gke_clusters.md b/doc/user/project/clusters/add_gke_clusters.md
index a454b4dff99..78d4bce737d 100644
--- a/doc/user/project/clusters/add_gke_clusters.md
+++ b/doc/user/project/clusters/add_gke_clusters.md
@@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Deprecated](https://gitlab.com/groups/gitlab-org/-/epics/6049) in GitLab 14.0.
WARNING:
-Use [Infrastrucure as Code](../../infrastructure/index.md) to create new clusters. The method described in this document is deprecated as of GitLab 14.0.
+Use [Infrastructure as Code](../../infrastructure/index.md) to create new clusters. The method described in this document is deprecated as of GitLab 14.0.
Through GitLab, you can create new clusters and add existing clusters hosted on Amazon Elastic
Kubernetes Service (EKS).
@@ -62,7 +62,7 @@ To create and add a new Kubernetes cluster to your project, group, or instance:
- Project's **{cloud-gear}** **Infrastructure > Kubernetes clusters** page, for a project-level
cluster.
- Group's **{cloud-gear}** **Kubernetes** page, for a group-level cluster.
- - **Menu >** **{admin}** **Admin >** **{cloud-gear}** **Kubernetes** page, for an instance-level cluster.
+ - **Menu > Admin > Kubernetes** page, for an instance-level cluster.
1. Click **Integrate with a cluster certificate**.
1. Under the **Create new cluster** tab, click **Google GKE**.
1. Connect your Google account if you haven't done already by clicking the
diff --git a/doc/user/project/clusters/add_remove_clusters.md b/doc/user/project/clusters/add_remove_clusters.md
index fba02183be5..4f2bc5526e0 100644
--- a/doc/user/project/clusters/add_remove_clusters.md
+++ b/doc/user/project/clusters/add_remove_clusters.md
@@ -9,11 +9,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/327908) in GitLab 14.0.
WARNING:
-Creating a new cluster through the certificate-based method
-is deprecated and no longer recommended. Kubernetes cluster, similar to any other
-infrastructure, should be created, updated, maintained using [Infrastructure as Code](../../infrastructure/index.md).
-GitLab is developing a built-in capability to create clusters with Terraform.
-You can follow along in this [epic](https://gitlab.com/groups/gitlab-org/-/epics/6049).
+Creating a new cluster through cluster certificates
+is deprecated and no longer recommended. To create a new cluster use
+[Infrastructure as Code](../../infrastructure/iac/index.md#create-a-new-cluster-through-iac).
NOTE:
Every new Google Cloud Platform (GCP) account receives
@@ -30,29 +28,38 @@ in a few clicks.
## Create new cluster
-> The certificate-based method for creating clusters from GitLab was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/327908) in GitLab 14.0.
+> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/327908) in GitLab 14.0.
+
+As of GitLab 14.0, use [Infrastructure as Code](../../infrastructure/iac/index.md#create-a-new-cluster-through-iac)
+to **safely create new clusters from GitLab**.
-As of GitLab 14.0, use [Infrastructure as Code](../../infrastructure/index.md)
-to **safely create your new cluster from GitLab**.
+Creating clusters from GitLab using cluster certificates is still available on the
+GitLab UI but was **deprecated** in GitLab 14.0 and is scheduled for removal in
+GitLab 15.0. We don't recommend using this method.
-The certificate-based method is **deprecated** and scheduled for removal in
-GitLab 15.0. However, you can still use it until then. Through
-this method, you can host your cluster in EKS, GKE, on premises, and with other
-providers. To host them on premises and with other providers,
-use either the EKS or GKE method to guide you through and enter your cluster's
-settings manually:
+You can create a new cluster hosted in EKS, GKE, on premises, and with other
+providers using cluster certificates:
- [New cluster hosted on Google Kubernetes Engine (GKE)](add_gke_clusters.md).
- [New cluster hosted on Amazon Elastic Kubernetes Service (EKS)](add_eks_clusters.md).
+To host them on premises and with other providers, you can use Terraform
+or your preferred tool of choice to create and connect a cluster with GitLab.
+The [GitLab Terraform provider](https://registry.terraform.io/providers/gitlabhq/gitlab/latest/docs/resources/project_cluster)
+supports connecting existing clusters using the certificate-based connection method.
+
## Add existing cluster
-If you already have a cluster and want to integrate it with GitLab, see how to
-[add an existing cluster](add_existing_cluster.md).
+As of GitLab 14.0, use the [GitLab Kubernetes Agent](../../clusters/agent/index.md)
+to connect your cluster to GitLab.
+
+Alternatively, you can [add an existing cluster](add_existing_cluster.md)
+through the certificate-based method, but we don't recommend using this method for [security implications](../../infrastructure/clusters/connect/index.md#security-implications-for-clusters-connected-with-certificates).
## Configure your cluster
-As of GitLab 14.0, use the [GitLab Kubernetes Agent](../../clusters/agent/index.md) to configure your cluster.
+As of GitLab 14.0, use the [GitLab Kubernetes Agent](../../clusters/agent/index.md)
+to configure your cluster.
## Disable a cluster
@@ -62,7 +69,7 @@ one to GitLab, the cluster connection to GitLab becomes enabled. To disable it:
1. Go to your:
- Project's **{cloud-gear}** **Infrastructure > Kubernetes clusters** page, for a project-level cluster.
- Group's **{cloud-gear}** **Kubernetes** page, for a group-level cluster.
- - **Menu >** **{admin}** **Admin >** **{cloud-gear}** **Kubernetes** page, for an instance-level cluster.
+ - **Menu > Admin > Kubernetes** page, for an instance-level cluster.
1. Select the name of the cluster you want to disable.
1. Toggle **GitLab Integration** off (in gray).
1. Click **Save changes**.
diff --git a/doc/user/project/clusters/deploy_to_cluster.md b/doc/user/project/clusters/deploy_to_cluster.md
index fdd65d70242..54141fe1103 100644
--- a/doc/user/project/clusters/deploy_to_cluster.md
+++ b/doc/user/project/clusters/deploy_to_cluster.md
@@ -4,7 +4,13 @@ group: Configure
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
---
-# Deploy to a Kubernetes cluster
+# Deploy to a Kubernetes cluster with cluster certificates
+
+WARNING:
+The process described on this page uses cluster certificates to deploy to your cluster
+from GitLab. Although this method still works, it is **no longer recommended**.
+To deploy to your cluster from GitLab, we **recommend** using the [GitLab Kubernetes Agent](../../clusters/agent/index.md)
+instead. **(PREMIUM)**
A Kubernetes cluster can be the destination for a deployment job. If
diff --git a/doc/user/project/clusters/index.md b/doc/user/project/clusters/index.md
index a0efea267f0..791dc90cad5 100644
--- a/doc/user/project/clusters/index.md
+++ b/doc/user/project/clusters/index.md
@@ -16,10 +16,6 @@ We offer extensive integrations to help you connect and manage your Kubernetes c
Read through this document to get started.
-## Clusters infrastructure
-
-Use [Infrastructure as Code](../../infrastructure) to create and manage your clusters with the GitLab integration with Terraform.
-
## Benefit from the GitLab-Kubernetes integration
Using the GitLab-Kubernetes integration, you can benefit of GitLab
@@ -30,76 +26,18 @@ features such as:
- Use [role-based or attribute-based access controls](cluster_access.md).
- Run serverless workloads on [Kubernetes with Knative](serverless/index.md).
- Connect GitLab to in-cluster applications using [cluster integrations](../../clusters/integrations.md).
-- Use [Deploy Boards](../deploy_boards.md) to see the health and status of each CI [environment](../../../ci/environments/index.md) running on your Kubernetes cluster.
+- Use [deploy boards](../deploy_boards.md) to see the health and status of each CI [environment](../../../ci/environments/index.md) running on your Kubernetes cluster.
- Use [Canary deployments](../canary_deployments.md) to update only a portion of your fleet with the latest version of your application.
- View your [Kubernetes podlogs](kubernetes_pod_logs.md) directly in GitLab.
- Connect to your cluster through GitLab [web terminals](deploy_to_cluster.md#web-terminals-for-kubernetes-clusters).
## Supported cluster versions
-GitLab is committed to support at least two production-ready Kubernetes minor
-versions at any given time. We regularly review the versions we support, and
-provide a three-month deprecation period before we remove support of a specific
-version. The range of supported versions is based on the evaluation of:
-
-- The versions supported by major managed Kubernetes providers.
-- The versions [supported by the Kubernetes community](https://kubernetes.io/releases/version-skew-policy/#supported-versions).
-
-GitLab supports the following Kubernetes versions, and you can upgrade your
-Kubernetes version to any supported version at any time:
-
-- 1.19 (support ends on February 22, 2022)
-- 1.18 (support ends on November 22, 2021)
-- 1.17 (support ends on September 22, 2021)
-- 1.16 (support ends on July 22, 2021)
-- 1.15 (support ends on May 22, 2021)
-
-Some GitLab features may support versions outside the range provided here.
-
-## Add and remove clusters
-
-You can create new or add existing clusters to GitLab:
-
-- On the project-level, to have a cluster dedicated to a project.
-- On the [group level](../../group/clusters/index.md), to use the same cluster across multiple projects within your group.
-- On the [instance level](../../instance/clusters/index.md), to use the same cluster across multiple groups and projects. **(FREE SELF)**
-
-To create new clusters, use one of the following methods:
-
-- [Infrastructure as Code](../../infrastructure/index.md) (**recommended**).
-- [Cluster certificates](add_remove_clusters.md) (**deprecated**).
-
-You can also [add existing clusters](add_existing_cluster.md) to GitLab.
-
-## View your clusters
-
-To view your project-level Kubernetes clusters, to go **Infrastructure > Kubernetes clusters**
-from your project. On this page, you can add a new cluster
-and view information about your existing clusters, such as:
-
-- Nodes count.
-- Rough estimates of memory and CPU usage.
-
-## Configuring your Kubernetes cluster
-
-Use the [GitLab Kubernetes Agent](../../clusters/agent/index.md) to safely
-configure your clusters. Otherwise, there are [security implications](#security-implications).
-
-### Security implications
-
-WARNING:
-The whole cluster security is based on a model where [developers](../../permissions.md)
-are trusted, so **only trusted users should be allowed to control your clusters**.
-
-The default cluster configuration grants access to a wide set of
-functionalities needed to successfully build and deploy a containerized
-application. Bear in mind that the same credentials are used for all the
-applications running on the cluster.
+See the [Kubernetes clusters versions supported by GitLab](../../infrastructure/clusters/connect/index.md#supported-cluster-versions).
-## Multiple Kubernetes clusters
+## Connect your cluster to GitLab
-See how to associate [multiple Kubernetes clusters](multiple_kubernetes_clusters.md)
-with your GitLab project.
+Learn how to [create new and connect existing clusters to GitLab](../../infrastructure/clusters/connect/index.md).
## Cluster integrations
diff --git a/doc/user/project/clusters/kubernetes_pod_logs.md b/doc/user/project/clusters/kubernetes_pod_logs.md
index 7a9c7eb423d..eb0e8d0e91c 100644
--- a/doc/user/project/clusters/kubernetes_pod_logs.md
+++ b/doc/user/project/clusters/kubernetes_pod_logs.md
@@ -46,15 +46,15 @@ a [metrics dashboard](../../../operations/metrics/index.md) and select **View lo
[permissions](../../permissions.md#project-members-permissions) in the project.
1. To navigate to the **Log Explorer** from the sidebar menu, go to **Monitor > Logs**
([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/22011) in GitLab 12.5.).
-1. To navigate to the **Log Explorer** from a specific pod on a [Deploy Board](../deploy_boards.md):
+1. To navigate to the **Log Explorer** from a specific pod on a [deploy board](../deploy_boards.md):
1. Go to **Deployments > Environments** and find the environment
which contains the desired pod, like `production`.
1. On the **Environments** page, you should see the status of the environment's
- pods with [Deploy Boards](../deploy_boards.md).
+ pods with [deploy boards](../deploy_boards.md).
1. When mousing over the list of pods, GitLab displays a tooltip with the exact pod name
and status.
- ![Deploy Boards pod list](img/pod_logs_deploy_board.png)
+ ![deploy boards pod list](img/pod_logs_deploy_board.png)
1. Click on the desired pod to display the **Log Explorer**.
### Logs view
diff --git a/doc/user/project/clusters/protect/container_network_security/quick_start_guide.md b/doc/user/project/clusters/protect/container_network_security/quick_start_guide.md
index 62010bb7802..1940cf229b8 100644
--- a/doc/user/project/clusters/protect/container_network_security/quick_start_guide.md
+++ b/doc/user/project/clusters/protect/container_network_security/quick_start_guide.md
@@ -137,7 +137,7 @@ Network Policies can be managed through GitLab in one of two ways:
- Management through a YAML file in each application's project (for projects using Auto DevOps). For
more information, see the [Network Policy documentation](../../../../../topics/autodevops/stages.md#network-policy).
- Management through the GitLab Policy management UI (for projects not using Auto DevOps). For more
- information, see the [Container Network Policy documentation](../../../../application_security/threat_monitoring/index.md#container-network-policy-management) (Ultimate only).
+ information, see the [Container Network Policy documentation](../../../../application_security/policies/index.md#container-network-policy) (Ultimate only).
Each method has benefits and drawbacks:
@@ -167,7 +167,7 @@ hubble:
```
Additional information about the statistics page is available in the
-[documentation that describes the Threat Management UI](../../../../application_security/threat_monitoring/index.md#container-network-policy).
+[documentation that describes the Threat Management UI](../../../../application_security/policies/index.md#container-network-policy).
## Forwarding logs to a SIEM
diff --git a/doc/user/project/clusters/runbooks/index.md b/doc/user/project/clusters/runbooks/index.md
index b2054c4befb..7357fc850e5 100644
--- a/doc/user/project/clusters/runbooks/index.md
+++ b/doc/user/project/clusters/runbooks/index.md
@@ -63,7 +63,7 @@ information.
Follow this step-by-step guide to configure an executable runbook in GitLab using
the components outlined above and the pre-loaded demo runbook.
-1. Create an [OAuth Application for JupyterHub](../../../../integration/oauth_provider.md#gitlab-as-oauth2-authentication-service-provider).
+1. Create an [OAuth Application for JupyterHub](../../../../integration/oauth_provider.md#gitlab-as-an-oauth-20-authentication-service-provider).
1. When [installing JupyterHub with Helm](https://zero-to-jupyterhub.readthedocs.io/en/latest/jupyterhub/installation.html), use the following values
```yaml
diff --git a/doc/user/project/clusters/serverless/index.md b/doc/user/project/clusters/serverless/index.md
index ec22f71157f..fb32579f40e 100644
--- a/doc/user/project/clusters/serverless/index.md
+++ b/doc/user/project/clusters/serverless/index.md
@@ -4,9 +4,10 @@ group: Configure
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
---
-# Serverless **(FREE)**
+# Serverless (DEPRECATED) **(FREE)**
-> Introduced in GitLab 11.5.
+> - Introduced in GitLab 11.5.
+> - [Deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/6) in GitLab 14.3.
WARNING:
Serverless is currently in [alpha](https://about.gitlab.com/handbook/product/gitlab-the-product/#alpha).
@@ -316,7 +317,7 @@ The optional `runtime` parameter can refer to one of the following runtime alias
| `openfaas/classic/python3` | OpenFaaS |
| `openfaas/classic/ruby` | OpenFaaS |
-After the `gitlab-ci.yml` template has been added and the `serverless.yml` file
+After the `.gitlab-ci.yml` template has been added and the `serverless.yml` file
has been created, pushing a commit to your project results in a CI pipeline
being executed which deploys each function as a Knative service. After the
deploy stage has finished, additional details for the function display
diff --git a/doc/user/project/deploy_boards.md b/doc/user/project/deploy_boards.md
index 64a5515136b..05f026cca18 100644
--- a/doc/user/project/deploy_boards.md
+++ b/doc/user/project/deploy_boards.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: howto, reference
---
-# Deploy Boards **(FREE)**
+# Deploy boards **(FREE)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/1589) in [GitLab Premium](https://about.gitlab.com/pricing/) 9.0.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212320) to GitLab Free in 13.8.
@@ -16,7 +16,7 @@ type: howto, reference
> This is [fixed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60525) in
> GitLab 13.12.
-GitLab Deploy Boards offer a consolidated view of the current health and
+GitLab deploy boards offer a consolidated view of the current health and
status of each CI [environment](../../ci/environments/index.md) running on [Kubernetes](https://kubernetes.io), displaying the status
of the pods in the deployment. Developers and other teammates can view the
progress and status of a rollout, pod by pod, in the workflow they already use
@@ -28,23 +28,23 @@ environments by using [Auto DevOps](../../topics/autodevops/index.md).
## Overview
-With Deploy Boards you can gain more insight into deploys with benefits such as:
+With deploy boards you can gain more insight into deploys with benefits such as:
- Following a deploy from the start, not just when it's done
- Watching the rollout of a build across multiple servers
- Finer state detail (Succeeded, Running, Failed, Pending, Unknown)
- See [Canary Deployments](canary_deployments.md)
-Here's an example of a Deploy Board of the production environment.
+Here's an example of a deploy board of the production environment.
-![Deploy Boards landing page](img/deploy_boards_landing_page.png)
+![deploy boards landing page](img/deploy_boards_landing_page.png)
The squares represent pods in your Kubernetes cluster that are associated with
the given environment. Hovering above each square you can see the state of a
deploy rolling out. The percentage is the percent of the pods that are updated
to the latest release.
-Since Deploy Boards are tightly coupled with Kubernetes, there is some required
+Since deploy boards are tightly coupled with Kubernetes, there is some required
knowledge. In particular, you should be familiar with:
- [Kubernetes pods](https://kubernetes.io/docs/concepts/workloads/pods/)
@@ -54,7 +54,7 @@ knowledge. In particular, you should be familiar with:
## Use cases
-Since the Deploy Board is a visual representation of the Kubernetes pods for a
+Since the deploy board is a visual representation of the Kubernetes pods for a
specific environment, there are a lot of use cases. To name a few:
- You want to promote what's running in staging, to production. You go to the
@@ -73,9 +73,9 @@ specific environment, there are a lot of use cases. To name a few:
list, find the [Review App](../../ci/review_apps/index.md) you're interested in, and click the
manual action to deploy it to staging.
-## Enabling Deploy Boards
+## Enabling deploy boards
-To display the Deploy Boards for a specific [environment](../../ci/environments/index.md) you should:
+To display the deploy boards for a specific [environment](../../ci/environments/index.md) you should:
1. Have [defined an environment](../../ci/environments/index.md) with a deploy stage.
@@ -83,7 +83,7 @@ To display the Deploy Boards for a specific [environment](../../ci/environments/
NOTE:
If you're using OpenShift, ensure that you're using the `Deployment` resource
- instead of `DeploymentConfiguration`. Otherwise, the Deploy Boards don't render
+ instead of `DeploymentConfiguration`. Otherwise, the deploy boards don't render
correctly. For more information, read the
[OpenShift docs](https://docs.openshift.com/container-platform/3.7/dev_guide/deployments/kubernetes_deployments.html#kubernetes-deployments-vs-deployment-configurations)
and [GitLab issue #4584](https://gitlab.com/gitlab-org/gitlab/-/issues/4584).
@@ -114,17 +114,17 @@ To display the Deploy Boards for a specific [environment](../../ci/environments/
If you use GCP to manage clusters, you can see the deployment details in GCP itself by navigating to **Workloads > deployment name > Details**:
- ![Deploy Boards Kubernetes Label](img/deploy_boards_kubernetes_label.png)
+ ![deploy boards Kubernetes Label](img/deploy_boards_kubernetes_label.png)
Once all of the above are set up and the pipeline has run at least once,
navigate to the environments page under **Deployments > Environments**.
-Deploy Boards are visible by default. You can explicitly click
+Deploy boards are visible by default. You can explicitly click
the triangle next to their respective environment name in order to hide them.
### Example manifest file
-The following example is an extract of a Kubernetes manifest deployment file, using the two annotations `app.gitlab.com/env` and `app.gitlab.com/app` to enable the **Deploy Boards**:
+The following example is an extract of a Kubernetes manifest deployment file, using the two annotations `app.gitlab.com/env` and `app.gitlab.com/app` to enable the **deploy boards**:
```yaml
apiVersion: apps/v1
diff --git a/doc/user/project/deploy_keys/index.md b/doc/user/project/deploy_keys/index.md
index 1b9a17ee071..e9a38f91677 100644
--- a/doc/user/project/deploy_keys/index.md
+++ b/doc/user/project/deploy_keys/index.md
@@ -121,7 +121,7 @@ repositories to secure, shared services, such as CI/CD.
Instance administrators can add public deploy keys:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Deploy Keys**.
1. Select **New deploy key**.
diff --git a/doc/user/project/deploy_tokens/index.md b/doc/user/project/deploy_tokens/index.md
index 70363b67c88..1798aa0c1c6 100644
--- a/doc/user/project/deploy_tokens/index.md
+++ b/doc/user/project/deploy_tokens/index.md
@@ -181,7 +181,7 @@ To pull images from the Dependency Proxy, you must:
1. Create a group deploy token with both `read_registry` and `write_registry` scopes.
1. Take note of your `username` and `token`.
-1. Follow the Depenency Proxy [authentication instructions](../../packages/dependency_proxy/index.md).
+1. Follow the Dependency Proxy [authentication instructions](../../packages/dependency_proxy/index.md).
### GitLab deploy token
diff --git a/doc/user/project/description_templates.md b/doc/user/project/description_templates.md
index 72ef88b5fab..5b19a54bd91 100644
--- a/doc/user/project/description_templates.md
+++ b/doc/user/project/description_templates.md
@@ -116,7 +116,7 @@ Only instance administrators can set instance-level templates.
To set the instance-level description template repository:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Templates**.
1. Expand **Templates**
1. From the dropdown, select your template project as the template repository at instance level.
diff --git a/doc/user/project/import/bitbucket.md b/doc/user/project/import/bitbucket.md
index 802eb3efc51..cda018a0c37 100644
--- a/doc/user/project/import/bitbucket.md
+++ b/doc/user/project/import/bitbucket.md
@@ -16,18 +16,18 @@ Import your projects from Bitbucket Cloud to GitLab with minimal effort.
The Bitbucket importer can import:
-- Repository description (GitLab 7.7+)
-- Git repository data (GitLab 7.7+)
-- Issues (GitLab 7.7+)
-- Issue comments (GitLab 8.15+)
-- Pull requests (GitLab 8.4+)
-- Pull request comments (GitLab 8.15+)
-- Milestones (GitLab 8.15+)
-- Wiki (GitLab 8.15+)
+- Repository description
+- Git repository data
+- Issues
+- Issue comments
+- Pull requests
+- Pull request comments
+- Milestones
+- Wiki
When importing:
-- References to pull requests and issues are preserved (GitLab 8.7+).
+- References to pull requests and issues are preserved.
- Repository public access is retained. If a repository is private in Bitbucket, it's created as
private in GitLab as well.
diff --git a/doc/user/project/import/github.md b/doc/user/project/import/github.md
index 1ab343d75fb..4443ae902fb 100644
--- a/doc/user/project/import/github.md
+++ b/doc/user/project/import/github.md
@@ -31,13 +31,18 @@ each imported repository maintains visibility level unless that [visibility
level is restricted](../../../public_access/public_access.md#restrict-use-of-public-or-internal-projects),
in which case it defaults to the default project visibility.
-The namespace is a user or group in GitLab, such as `gitlab.com/janedoe` or `gitlab.com/customer-success`. You can do some bulk actions to move projects to different namespaces in the rails console.
+The namespace is a user or group in GitLab, such as `gitlab.com/janedoe` or
+`gitlab.com/customer-success`. You can do some bulk actions to move projects to
+different namespaces in the rails console.
-This process does not migrate or import any types of groups or organizations from GitHub to GitLab.
+This process does not migrate or import any types of groups or organizations
+from GitHub to GitLab.
## Use cases
-The steps you take depend on whether you are importing from GitHub.com or GitHub Enterprise, as well as whether you are importing to GitLab.com or self-managed GitLab instance.
+The steps you take depend on whether you are importing from GitHub.com or
+GitHub Enterprise. The steps also depend on whether you are importing to GitLab.com or
+self-managed GitLab instance.
- If you're importing to GitLab.com, you can alternatively import GitHub repositories
using a [personal access token](#use-a-github-token). We do not recommend
@@ -49,12 +54,14 @@ The steps you take depend on whether you are importing from GitHub.com or GitHub
- If you're importing from GitHub Enterprise to your self-managed GitLab instance, you must first enable
[GitHub integration](../../../integration/github.md).
- To import projects from GitHub Enterprise to GitLab.com, use the [Import API](../../../api/import.md).
-- If you're importing from GitHub.com to your self-managed GitLab instance, you do not need to set up GitHub integration. You can use the [Import API](../../../api/import.md).
+- If you're importing from GitHub.com to your self-managed GitLab instance,
+ setting up GitHub integration is not required. You can use the [Import API](../../../api/import.md).
## How it works
-When issues and pull requests are being imported, the importer attempts to find their GitHub authors and
-assignees in the database of the GitLab instance (note that pull requests are called "merge requests" in GitLab).
+When issues and pull requests are being imported, the importer attempts to find
+their GitHub authors and assignees in the database of the GitLab instance (note
+that pull requests are called "merge requests" in GitLab).
For this association to succeed, each GitHub author and assignee in the repository
must meet one of the following conditions prior to the import:
@@ -64,12 +71,13 @@ must meet one of the following conditions prior to the import:
that matches their GitLab account's email address.
NOTE:
- GitLab content imports that use GitHub accounts require that the GitHub public-facing
- email address is populated so that all comments and contributions are properly mapped
- to the same user in GitLab. GitHub Enterprise (on premise) does not require this field
- to be populated to use the product, so you may need to add it on existing GitHub Enterprise
- accounts for imported content to be properly mapped to the user in the new system.
- Refer to GitHub documentation for instructions on how to add that address.
+ GitLab content imports that use GitHub accounts require that the GitHub
+ public-facing email address is populated so that all comments and
+ contributions are properly mapped to the same user in GitLab. GitHub
+ Enterprise (on premise) does not require this field to be populated to use the
+ product, so you may have to add it on existing accounts for the imported
+ content to be properly mapped to the user in the new system. Refer to GitHub
+ documentation for instructions on how to add this email address.
If a user referenced in the project is not found in the GitLab database, the project creator (typically the user
that initiated the import process) is set as the author/assignee, but a note on the issue mentioning the original
@@ -132,7 +140,7 @@ If you are not using the GitHub integration, you can still perform an authorizat
1. Copy the token hash.
1. Go back to GitLab and provide the token to the GitHub importer.
1. Hit the **List Your GitHub Repositories** button and wait while GitLab reads your repositories' information.
- Once done, you'll be taken to the importer page to select the repositories to import.
+ Once done, you are taken to the importer page to select the repositories to import.
To use a newer personal access token in imports after previously performing these steps, sign out of
your GitLab account and sign in again, or revoke the older personal access token in GitHub.
@@ -152,7 +160,7 @@ your GitHub repositories are listed.
![GitHub importer page](img/import_projects_from_github_importer_v12_3.png)
-## Mirroring and pipeline status sharing
+## Mirror a repository and share pipeline status
Depending on your GitLab tier, [repository mirroring](../repository/repository_mirroring.md) can be set up to keep
your imported repository in sync with its GitHub copy.
@@ -169,7 +177,7 @@ Mirroring does not sync any new or updated pull requests from your GitHub projec
## Improve the speed of imports on self-managed instances
NOTE:
-Administrator access to the GitLab server is required.
+An administrator role on the GitLab server is required for this process.
For large projects it may take a while to import all data. To reduce the time necessary, you can increase the number of
Sidekiq workers that process the following queues:
@@ -183,4 +191,52 @@ servers. For 4 servers with 8 cores this means you can import up to 32 objects (
Reducing the time spent in cloning a repository can be done by increasing network throughput, CPU capacity, and disk
performance (by using high performance SSDs, for example) of the disks that store the Git repositories (for your GitLab instance).
-Increasing the number of Sidekiq workers will *not* reduce the time spent cloning repositories.
+Increasing the number of Sidekiq workers does *not* reduce the time spent cloning repositories.
+
+## Alternative way to import notes and diff notes
+
+When GitHub Importer runs on extremely large projects not all notes & diff notes can be imported due to GitHub API `issues_comments` & `pull_requests_comments` endpoints limitation.
+Not all pages can be fetched due to the following error coming from GitHub API: `In order to keep the API fast for everyone, pagination is limited for this resource. Check the rel=last link relation in the Link response header to see how far back you can traverse.`.
+
+An alternative approach for importing notes and diff notes is available behind a feature flag.
+
+Instead of using `issues_comments` and `pull_requests_comments`, use individual resources `issue_comments` and `pull_request_comments` instead to pull notes from one object at a time.
+This allows us to carry over any missing comments, however it increases the number of network requests required to perform the import, which means its execution takes a longer time.
+
+To use the alternative way of importing notes, the `github_importer_single_endpoint_notes_import` feature flag must be enabled on the group project is being imported into.
+
+Start a [Rails console](../../../administration/operations/rails_console.md#starting-a-rails-console-session).
+
+```ruby
+group = Group.find_by_full_path('my/group/fullpath')
+
+# Enable
+Feature.enable(:github_importer_single_endpoint_notes_import, group)
+
+# Disable
+Feature.disable(:github_importer_single_endpoint_notes_import, group)
+```
+
+## Reduce GitHub API request objects per page
+
+Some GitHub API endpoints may return a 500 or 502 error for project imports from large repositories.
+To reduce the chance of such errors, you can enable the feature flag
+`github_importer_lower_per_page_limit` in the group project importing the data. This reduces the
+page size from 100 to 50.
+
+To enable this feature flag, start a [Rails console](../../../administration/operations/rails_console.md#starting-a-rails-console-session)
+and run the following `enable` command:
+
+```ruby
+group = Group.find_by_full_path('my/group/fullpath')
+
+# Enable
+Feature.enable(:github_importer_lower_per_page_limit, group)
+```
+
+To disable the feature, run this command:
+
+```ruby
+# Disable
+Feature.disable(:github_importer_lower_per_page_limit, group)
+```
diff --git a/doc/user/project/import/index.md b/doc/user/project/import/index.md
index dcc41c6c85e..65e1eafa477 100644
--- a/doc/user/project/import/index.md
+++ b/doc/user/project/import/index.md
@@ -76,7 +76,7 @@ a self-managed instance from an old server to a new server.
The backups produced don't depend on the operating system running GitLab. You can therefore use
the restore method to switch between different operating system distributions or versions, as long
-as the same GitLab version [is available for installation](https://docs.gitlab.com/omnibus/package-information/deprecated_os.md).
+as the same GitLab version [is available for installation](../../../administration/package_information/deprecated_os.md).
To instead merge two self-managed GitLab instances together, use the instructions in
[Migrate from self-managed GitLab to GitLab.com](#migrate-from-self-managed-gitlab-to-gitlabcom).
diff --git a/doc/user/project/import/jira.md b/doc/user/project/import/jira.md
index 3e0faec0a49..c6992422733 100644
--- a/doc/user/project/import/jira.md
+++ b/doc/user/project/import/jira.md
@@ -4,7 +4,7 @@ group: Project Management
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
---
-# Import your Jira project issues to GitLab **(PREMIUM)**
+# Import your Jira project issues to GitLab **(FREE)**
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2766) in GitLab 12.10.
diff --git a/doc/user/project/index.md b/doc/user/project/index.md
index 668a0dffd32..8c81af418a0 100644
--- a/doc/user/project/index.md
+++ b/doc/user/project/index.md
@@ -22,8 +22,8 @@ Projects include the following [features](https://about.gitlab.com/features/):
**Repositories:**
- [Issue tracker](issues/index.md): Discuss implementations with your team.
- - [Issue Boards](issue_board.md): Organize and prioritize your workflow.
- - [Multiple Issue Boards](issue_board.md#multiple-issue-boards): Create team-specific workflows (Issue Boards) for a project.
+ - [Issue boards](issue_board.md): Organize and prioritize your workflow.
+ - [Multiple issue boards](issue_board.md#multiple-issue-boards): Create team-specific workflows (issue boards) for a project.
- [Repositories](repository/index.md): Host your code in a fully-integrated platform.
- [Branches](repository/branches/index.md): Use Git branching strategies to
collaborate on code.
@@ -41,8 +41,8 @@ Projects include the following [features](https://about.gitlab.com/features/):
**Issues and merge requests:**
- [Issue tracker](issues/index.md): Discuss implementations with your team.
- - [Issue Boards](issue_board.md): Organize and prioritize your workflow.
- - [Multiple Issue Boards](issue_board.md#multiple-issue-boards): Create team-specific workflows (Issue Boards) for a project.
+ - [Issue boards](issue_board.md): Organize and prioritize your workflow.
+ - [Multiple issue boards](issue_board.md#multiple-issue-boards): Create team-specific workflows (issue boards) for a project.
- [Merge Requests](merge_requests/index.md): Apply a branching
strategy and get reviewed by your team.
- [Merge Request Approvals](merge_requests/approvals/index.md): Ask for approval before
@@ -141,7 +141,7 @@ There are numerous [APIs](../../api/index.md) to use with your projects:
- [Threads](../../api/discussions.md)
- [General](../../api/projects.md)
- [Import/export](../../api/project_import_export.md)
-- [Issue Board](../../api/boards.md)
+- [Issue board](../../api/boards.md)
- [Labels](../../api/labels.md)
- [Markdown](../../api/markdown.md)
- [Merge Requests](../../api/merge_requests.md)
diff --git a/doc/user/project/integrations/github.md b/doc/user/project/integrations/github.md
index 6b342392bdf..4908d21e764 100644
--- a/doc/user/project/integrations/github.md
+++ b/doc/user/project/integrations/github.md
@@ -11,7 +11,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
GitLab provides an integration for updating the pipeline statuses on GitHub.
This is especially useful if using GitLab for CI/CD only.
-This project integration is separate from the [instance wide GitHub integration](../import/github.md#mirroring-and-pipeline-status-sharing)
+This project integration is separate from the [instance wide GitHub integration](../import/github.md#mirror-a-repository-and-share-pipeline-status)
and is automatically configured on [GitHub import](../../../integration/github.md).
![Pipeline status update on GitHub](img/github_status_check_pipeline_update.png)
diff --git a/doc/user/project/integrations/img/slack_setup.png b/doc/user/project/integrations/img/slack_setup.png
index 7928fb7d495..8acae659fb4 100644
--- a/doc/user/project/integrations/img/slack_setup.png
+++ b/doc/user/project/integrations/img/slack_setup.png
Binary files differ
diff --git a/doc/user/project/integrations/img/zentao_product_id.png b/doc/user/project/integrations/img/zentao_product_id.png
new file mode 100644
index 00000000000..a91b4c3f82d
--- /dev/null
+++ b/doc/user/project/integrations/img/zentao_product_id.png
Binary files differ
diff --git a/doc/user/project/integrations/index.md b/doc/user/project/integrations/index.md
index 6f86098b33d..ac6e18e8e6a 100644
--- a/doc/user/project/integrations/index.md
+++ b/doc/user/project/integrations/index.md
@@ -17,8 +17,8 @@ For more information, read the
[overview of integrations](overview.md) or learn how to manage your integrations:
- *For GitLab 13.3 and later,* read [Project integration management](../../admin_area/settings/project_integration_management.md).
-- *For GitLab 13.2 and earlier,* read [Service Templates](services_templates.md),
- which are deprecated and [scheduled to be removed](https://gitlab.com/gitlab-org/gitlab/-/issues/268032)
+- *For GitLab 13.2 and earlier,* read [Integration Management](../../admin_area/settings/project_integration_management.md),
+ which replaced the deprecated Service Templates [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/268032)
in GitLab 14.0.
## Project webhooks
diff --git a/doc/user/project/integrations/mattermost_slash_commands.md b/doc/user/project/integrations/mattermost_slash_commands.md
index 5b5feb73b69..8027cc1c61e 100644
--- a/doc/user/project/integrations/mattermost_slash_commands.md
+++ b/doc/user/project/integrations/mattermost_slash_commands.md
@@ -22,7 +22,7 @@ on your configuration:
- **Omnibus GitLab installations**: Mattermost is bundled with
[Omnibus GitLab](https://docs.gitlab.com/omnibus/). To configure Mattermost for Omnibus GitLab, read the
- [Omnibus GitLab Mattermost documentation](https://docs.gitlab.com/omnibus/gitlab-mattermost/).
+ [Omnibus GitLab Mattermost documentation](../../../integration/mattermost/index.md).
- **If Mattermost is installed on the same server as GitLab**, use the
[automated configuration](#automated-configuration).
- **For all other installations**, use the [manual configuration](#manual-configuration).
@@ -68,7 +68,7 @@ information from GitLab. To get this information:
1. In a different browser tab than your current Mattermost session, sign in to
GitLab as a user with [Administrator role](../../permissions.md).
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. In the left menu, select **Settings > Integrations**, then select
**Mattermost slash commands**.
1. GitLab displays potential values for Mattermost settings. Copy the **Request URL**
diff --git a/doc/user/project/integrations/overview.md b/doc/user/project/integrations/overview.md
index 13def74450c..a6f739c6408 100644
--- a/doc/user/project/integrations/overview.md
+++ b/doc/user/project/integrations/overview.md
@@ -12,8 +12,10 @@ functionality to GitLab.
## Accessing integrations
-You can find the available integrations under your project's
-**Settings > Integrations** page.
+To find the available integrations for your project:
+
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Settings > Integrations**.
There are more than 20 integrations to integrate with. Select the one that you
want to configure.
@@ -60,6 +62,7 @@ Click on the service links to see further configuration instructions and details
| [Unify Circuit](unify_circuit.md) | Receive events notifications. | **{dotted-circle}** No |
| [Webex Teams](webex_teams.md) | Receive events notifications. | **{dotted-circle}** No |
| [YouTrack](youtrack.md) | Use YouTrack as the issue tracker. | **{dotted-circle}** No |
+| [ZenTao](zentao.md) | Use ZenTao as the issue tracker. | **{dotted-circle}** No |
## Push hooks limit
diff --git a/doc/user/project/integrations/services_templates.md b/doc/user/project/integrations/services_templates.md
deleted file mode 100644
index 37df48c75f8..00000000000
--- a/doc/user/project/integrations/services_templates.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: '../../admin_area/settings/project_integration_management.md'
-remove_date: '2021-09-09'
----
-
-This document was moved to [another location](../../admin_area/settings/project_integration_management.md).
-
-<!-- This redirect file can be deleted after <2021-09-09>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/user/project/integrations/slack.md b/doc/user/project/integrations/slack.md
index 5db4e839b54..a38d2157699 100644
--- a/doc/user/project/integrations/slack.md
+++ b/doc/user/project/integrations/slack.md
@@ -10,27 +10,27 @@ The Slack notifications service enables your GitLab project to send events
(such as issue creation) to your existing Slack team as notifications. Setting up
Slack notifications requires configuration changes for both Slack and GitLab.
-You can also use Slack slash commands to control GitLab inside Slack. This is the
-separately configured [Slack slash commands](slack_slash_commands.md).
+You can also use [Slack slash commands](slack_slash_commands.md)
+to control GitLab from Slack. Slash commands are configured separately.
-## Slack configuration
+## Configure Slack
1. Sign in to your Slack team and [start a new Incoming WebHooks configuration](https://my.slack.com/services/new/incoming-webhook).
1. Identify the Slack channel where notifications should be sent to by default.
Select **Add Incoming WebHooks integration** to add the configuration.
-1. Copy the **Webhook URL**, which is used later in the GitLab configuration.
+1. Copy the **Webhook URL** to use later when you configure GitLab.
-## GitLab configuration
+## Configure GitLab
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Integrations**.
-1. Select the **Slack notifications** integration to configure it.
+1. Select **Slack notifications**.
1. In the **Enable integration** section, select the **Active** checkbox.
1. In the **Trigger** section, select the checkboxes for each type of GitLab
event to send to Slack as a notification. For a full list, see
- [Triggers available for Slack notifications](#triggers-available-for-slack-notifications).
+ [Triggers for Slack notifications](#triggers-for-slack-notifications).
By default, messages are sent to the channel you configured during
- [Slack integration](#slack-configuration).
+ [Slack configuration](#configure-slack).
1. (Optional) To send messages to a different channel, multiple channels, or as
a direct message:
- *To send messages to channels,* enter the Slack channel names, separated by
@@ -40,38 +40,39 @@ separately configured [Slack slash commands](slack_slash_commands.md).
NOTE:
Usernames and private channels are not supported.
-1. In **Webhook**, enter the webhook URL you copied from the previous
- [Slack integration](#slack-configuration) step.
+1. In **Webhook**, enter the webhook URL you copied in the
+ [Slack configuration](#configure-slack) step.
1. (Optional) In **Username**, enter the username of the Slack bot that sends
the notifications.
1. Select the **Notify only broken pipelines** checkbox to notify only on failures.
1. In the **Branches to be notified** dropdown, select which types of branches
to send notifications for.
-1. Leave the **Labels to be notified** field blank to get all notifications or
- add labels that the issue or merge request must have in order to trigger a
+1. Leave the **Labels to be notified** field blank to get all notifications, or
+ add labels that the issue or merge request must have to trigger a
notification.
1. Select **Test settings** to verify your information, and then select
**Save changes**.
Your Slack team now starts receiving GitLab event notifications as configured.
-### Triggers available for Slack notifications
+## Triggers for Slack notifications
The following triggers are available for Slack notifications:
-| Trigger | Description |
-|------------------------|-------------|
-| **Push** | Triggered by a push to the repository. |
-| **Issue** | Triggered when an issue is created, updated, or closed. |
-| **Confidential issue** | Triggered when a confidential issue is created, updated, or closed. |
-| **Merge request** | Triggered when a merge request is created, updated, or merged. |
-| **Note** | Triggered when someone adds a comment. |
-| **Confidential note** | Triggered when someone adds a confidential note. |
-| **Tag push** | Triggered when a new tag is pushed to the repository. |
-| **Pipeline** | Triggered when a pipeline status changes. |
-| **Wiki page** | Triggered when a wiki page is created or updated. |
-| **Deployment** | Triggered when a deployment starts or finishes. |
-| **Alert** | Triggered when a new, unique alert is recorded. |
+| Trigger name | Trigger event |
+| ------------------------ | ------------------------------------------------------ |
+| **Push** | A push to the repository. |
+| **Issue** | An issue is created, updated, or closed. |
+| **Confidential issue** | A confidential issue is created, updated, or closed. |
+| **Merge request** | A merge request is created, updated, or merged. |
+| **Note** | A comment is added. |
+| **Confidential note** | A confidential note is added. |
+| **Tag push** | A new tag is pushed to the repository. |
+| **Pipeline** | A pipeline status changed. |
+| **Wiki page** | A wiki page is created or updated. |
+| **Deployment** | A deployment starts or finishes. |
+| **Alert** | A new, unique alert is recorded. |
+| **Vulnerability** | **(ULTIMATE)** A new, unique vulnerability is recorded. |
## Troubleshooting
@@ -81,45 +82,48 @@ for errors relating to your Slack service.
### Something went wrong on our end
-This is a generic error shown in the GitLab UI and does not mean much by itself.
+You might get this generic error message in the GitLab UI.
Review [the logs](../../../administration/logs.md#productionlog) to find
-an error message and keep troubleshooting from there.
+the error message and keep troubleshooting from there.
### `certificate verify failed`
-You may see an entry similar to the following in your Sidekiq log:
+You might see an entry like the following in your Sidekiq log:
```plaintext
2019-01-10_13:22:08.42572 2019-01-10T13:22:08.425Z 6877 TID-abcdefg ProjectServiceWorker JID-3bade5fb3dd47a85db6d78c5 ERROR: {:class=>"ProjectServiceWorker", :service_class=>"SlackService", :message=>"SSL_connect returned=1 errno=0 state=error: certificate verify failed"}
```
-This is probably a problem either with GitLab communicating with Slack, or GitLab
-communicating with itself. The former is less likely, as Slack's security certificates
-should _hopefully_ always be trusted. We can establish which we're dealing with by using
-the below rails console script.
+This issue occurs when there is a problem with GitLab communicating with Slack,
+or GitLab communicating with itself.
+The former is less likely, as Slack security certificates should always be trusted.
-```shell
-# start a rails console:
-sudo gitlab-rails console -e production
+To view which of these problems is the cause of the issue:
-# or for source installs:
-bundle exec rails console -e production
-```
+1. Start a Rails console:
-```ruby
-# run this in the Rails console
-# replace <SLACK URL> with your actual Slack URL
-result = Net::HTTP.get(URI('https://<SLACK URL>'));0
+ ```shell
+ sudo gitlab-rails console -e production
-# replace <GITLAB URL> with your actual GitLab URL
-result = Net::HTTP.get(URI('https://<GITLAB URL>'));0
-```
+ # for source installs:
+ bundle exec rails console -e production
+ ```
+
+1. Run the following commands:
+
+ ```ruby
+ # replace <SLACK URL> with your actual Slack URL
+ result = Net::HTTP.get(URI('https://<SLACK URL>'));0
+
+ # replace <GITLAB URL> with your actual GitLab URL
+ result = Net::HTTP.get(URI('https://<GITLAB URL>'));0
+ ```
-If GitLab is not trusting HTTPS connections to itself, then you may
-need to [add your certificate to the GitLab trusted certificates](https://docs.gitlab.com/omnibus/settings/ssl.html#install-custom-public-certificates).
+If GitLab does not trust HTTPS connections to itself,
+[add your certificate to the GitLab trusted certificates](https://docs.gitlab.com/omnibus/settings/ssl.html#install-custom-public-certificates).
-If GitLab is not trusting connections to Slack, then the GitLab
-OpenSSL trust store is incorrect. Some typical causes:
+If GitLab does not trust connections to Slack,
+the GitLab OpenSSL trust store is incorrect. Typical causes are:
- Overriding the trust store with `gitlab_rails['env'] = {"SSL_CERT_FILE" => "/path/to/file.pem"}`.
- Accidentally modifying the default CA bundle `/opt/gitlab/embedded/ssl/certs/cacert.pem`.
diff --git a/doc/user/project/integrations/slack_slash_commands.md b/doc/user/project/integrations/slack_slash_commands.md
index dfebf9a1123..066a2f83753 100644
--- a/doc/user/project/integrations/slack_slash_commands.md
+++ b/doc/user/project/integrations/slack_slash_commands.md
@@ -8,27 +8,36 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> Introduced in GitLab 8.15.
-Slack slash commands allow you to control GitLab and view content right inside
-Slack, without having to leave it. This requires configurations in both Slack and GitLab.
+If you want to control and view GitLab content while you're
+working in Slack, you can use Slack slash commands.
+To use Slack slash commands, you must configure both Slack and GitLab.
-GitLab can also send events (e.g., `issue created`) to Slack as notifications.
-This is the separately configured [Slack Notifications Service](slack.md).
+GitLab can also send events (for example, `issue created`) to Slack as notifications.
+The [Slack notifications service](slack.md) is configured separately.
NOTE:
-For GitLab.com, use the [Slack app](gitlab_slack_application.md) instead.
+For GitLab.com, use the [GitLab Slack app](gitlab_slack_application.md) instead.
-## Configuration
+## Configure GitLab and Slack
-1. Slack slash commands are scoped to a project. Navigate to the [Integrations page](overview.md#accessing-integrations) in your project's settings, i.e. **Project > Settings > Integrations**.
-1. Select the **Slack slash commands** integration to configure it. This page contains required information to complete the configuration in Slack. Leave this browser tab open.
-1. Open a new browser tab and sign in to your Slack team. [Start a new Slash Commands integration](https://my.slack.com/services/new/slash-commands).
-1. Enter a trigger term. We suggest you use the project name. Click **Add Slash Command Integration**.
-1. Complete the rest of the fields in the Slack configuration page using information from the GitLab browser tab. In particular, the URL needs to be copied and pasted. Click **Save Integration** to complete the configuration in Slack.
-1. While still on the Slack configuration page, copy the **token**. Go back to the GitLab browser tab and paste in the **token**.
-1. Ensure that the **Active** toggle is enabled and click **Save changes** to complete the configuration in GitLab.
+Slack slash command [integrations](overview.md#accessing-integrations)
+are scoped to a project.
-![Slack setup instructions](img/slack_setup.png)
+1. In GitLab, on the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Settings > Integrations**.
+1. Select **Slack slash commands**. Leave this browser tab open.
+1. Open a new browser tab, sign in to your Slack team, and [start a new Slash Commands integration](https://my.slack.com/services/new/slash-commands).
+1. Enter a trigger command. We suggest you use the project name.
+ Select **Add Slash Command Integration**.
+1. Complete the rest of the fields in the Slack configuration page using information from the GitLab browser tab.
+ In particular, make sure you copy and paste the **URL**.
-## Usage
+ ![Slack setup instructions](img/slack_setup.png)
-You can now use the [Slack slash commands](../../../integration/slash_commands.md).
+1. On the Slack configuration page, select **Save Integration** and copy the **Token**.
+1. Go back to the GitLab configuration page and paste in the **Token**.
+1. Ensure the **Active** checkbox is selected and select **Save changes**.
+
+## Slash commands
+
+You can now use the available [Slack slash commands](../../../integration/slash_commands.md).
diff --git a/doc/user/project/integrations/webex_teams.md b/doc/user/project/integrations/webex_teams.md
index 3632fdf0e0c..de152aabde5 100644
--- a/doc/user/project/integrations/webex_teams.md
+++ b/doc/user/project/integrations/webex_teams.md
@@ -27,7 +27,7 @@ notifications:
1. Navigate to:
- **Settings > Integrations** in a project to enable the integration at the project level.
- **Settings > Integrations** in a group to enable the integration at the group level.
- - On the top bar, select **Menu >** **{admin}** **Admin**. Then, in the left sidebar,
+ - On the top bar, select **Menu > Admin**. Then, in the left sidebar,
select **Settings > Integrations** to enable an instance-level integration.
1. Select the **Webex Teams** integration.
1. Ensure that the **Active** toggle is enabled.
diff --git a/doc/user/project/integrations/zentao.md b/doc/user/project/integrations/zentao.md
new file mode 100644
index 00000000000..ab8a7829139
--- /dev/null
+++ b/doc/user/project/integrations/zentao.md
@@ -0,0 +1,40 @@
+---
+stage: Ecosystem
+group: Integrations
+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
+---
+
+# ZenTao product integration **(PREMIUM)**
+
+[ZenTao](https://www.zentao.net/) is a web-based project management platform.
+
+## Configure ZenTao
+
+This integration requires a ZenTao API secret key.
+
+Complete these steps in ZenTao:
+
+1. Go to your **Admin** page and select **Develop > Application**.
+1. Select **Add Application**.
+1. Under **Name** and **Code**, enter a name and a code for the new secret key.
+1. Under **Account**, select an existing account name.
+1. Select **Save**.
+1. Copy the generated key to use in GitLab.
+
+## Configure GitLab
+
+Complete these steps in GitLab:
+
+1. Go to your project and select **Settings > Integrations**.
+1. Select **ZenTao**.
+1. Turn on the **Active** toggle under **Enable Integration**.
+1. Provide the ZenTao configuration information:
+ - **ZenTao Web URL**: The base URL of the ZenTao instance web interface you're linking to this GitLab project (for example, `example.zentao.net`).
+ - **ZenTao API URL** (optional): The base URL to the ZenTao instance API. Defaults to the Web URL value if not set.
+ - **ZenTao API token**: Use the key you generated when you [configured ZenTao](#configure-zentao).
+ - **ZenTao Product ID**: To display issues from a single ZenTao product in a given GitLab project. The Product ID can be found in the ZenTao product page under **Settings > Overview**.
+
+ ![ZenTao settings page](img/zentao_product_id.png)
+
+1. To verify the ZenTao connection is working, select **Test settings**.
+1. Select **Save changes**.
diff --git a/doc/user/project/issue_board.md b/doc/user/project/issue_board.md
index 0c624d7df01..4d1805e3d31 100644
--- a/doc/user/project/issue_board.md
+++ b/doc/user/project/issue_board.md
@@ -4,9 +4,9 @@ group: Project Management
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
---
-# Issue Boards **(FREE)**
+# Issue boards **(FREE)**
-The GitLab Issue Board is a software project management tool used to plan,
+The issue board is a software project management tool used to plan,
organize, and visualize a workflow for a feature or product release.
It can be used as a [Kanban](https://en.wikipedia.org/wiki/Kanban_(development)) or a
[Scrum](https://en.wikipedia.org/wiki/Scrum_(software_development)) board.
@@ -46,7 +46,7 @@ To learn more, visit [GitLab Enterprise features for issue boards](#gitlab-enter
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
Watch a [video presentation](https://youtu.be/vjccjHI7aGI) of
-the Issue Board feature.
+the issue board feature.
## Multiple issue boards
@@ -70,7 +70,7 @@ GitLab automatically loads the last board you visited.
To create a new issue board:
-1. Click the dropdown with the current board name in the upper left corner of the Issue Boards page.
+1. Click the dropdown with the current board name in the upper left corner of the issue boards page.
1. Click **Create new board**.
1. Enter the new board's name and select its scope: milestone, labels, assignee, or weight.
@@ -78,7 +78,7 @@ To create a new issue board:
To delete the currently active issue board:
-1. Click the dropdown with the current board name in the upper left corner of the Issue Boards page.
+1. Click the dropdown with the current board name in the upper left corner of the issue boards page.
1. Click **Delete board**.
1. Click **Delete** to confirm.
@@ -195,7 +195,7 @@ card includes:
## Permissions
Users with the [Reporter and higher roles](../permissions.md) can use all the functionality of the
-Issue Board feature to create or delete lists. They can also drag issues from one list to another.
+issue board feature to create or delete lists. They can also drag issues from one list to another.
## How GitLab orders issues in a list
@@ -229,8 +229,7 @@ and vice versa.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/285074) in GitLab 13.9.
> - [Deployed behind a feature flag](../feature_flags.md), enabled by default.
> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/248908) in GitLab 14.1
-> - Recommended for production use.
-> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#enable-or-disable-graphql-based-issue-boards). **(FREE SELF)**
+> - [Feature flag `graphql_board_lists`](https://gitlab.com/gitlab-org/gitlab/-/issues/248908) removed in GitLab 14.3
There can be
[risks when disabling released features](../../administration/feature_flags.md#risks-when-disabling-released-features).
@@ -271,7 +270,7 @@ clicking **View scope**.
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
Watch a [video presentation](https://youtu.be/m5UTNCSqaDk) of
-the Configurable Issue Board feature.
+the configurable issue board feature.
### Focus mode
@@ -339,14 +338,14 @@ As in other list types, click the trash icon to remove a list.
### Iteration lists **(PREMIUM)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/250479) in GitLab 13.11.
-> - [Deployed behind the `board_new_list` and `iteration_board_lists` feature flags](../feature_flags.md), enabled by default.
-> - Enabled on GitLab.com.
-> - Recommended for production use.
-> - For GitLab self-managed instances, GitLab administrators can opt to disable the feature flags: [`board_new_list`](#enable-or-disable-new-add-list-form) and [`iteration_board_lists`](#enable-or-disable-iteration-lists-in-boards). **(PREMIUM SELF)**
+> - Enabled on GitLab.com and is ready for production use.
+> - Enabled with `iteration_board_lists` flag for self-managed GitLab and is ready for production use.
+> GitLab administrators can opt to [disable the feature flag](#enable-or-disable-iteration-lists-in-boards).
-There can be
-[risks when disabling released features](../../administration/feature_flags.md#risks-when-disabling-released-features).
-Refer to this feature's version history for more details.
+FLAG:
+On self-managed GitLab, by default this feature is available. To hide the feature, ask an
+administrator to [disable the `iteration_board_lists` flag](../../administration/feature_flags.md).
+On GitLab.com, this feature is available.
You're also able to create lists of an iteration.
These are lists that filter issues by the assigned
@@ -387,7 +386,7 @@ appears on the right. There you can see and edit the issue's:
- Title
- Assignees
-- Epic **PREMIUM**
+- Epic **(PREMIUM)**
- Milestone
- Time tracking value (view only)
- Due date
@@ -673,52 +672,8 @@ A few things to remember:
by default. If you have more than 20 issues, start scrolling down and the next
20 appear.
-### Enable or disable GraphQL-based issue boards **(FREE SELF)**
-
-NOTE:
-When enabling GraphQL-based issue boards, you must also enable the
-[new add list form](#enable-or-disable-new-add-list-form).
-
-It is deployed behind a feature flag that is **enabled by default** as of GitLab 14.1.
-[GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md)
-can disable it.
-
-To enable it:
-
-```ruby
-Feature.enable(:graphql_board_lists)
-```
-
-To disable it:
-
-```ruby
-Feature.disable(:graphql_board_lists)
-```
-
-### Enable or disable new add list form **(FREE SELF)**
-
-The new form for adding lists is under development but ready for production use. It is
-deployed behind a feature flag that is **enabled by default**.
-[GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md)
-can disable it.
-
-To enable it:
-
-```ruby
-Feature.enable(:board_new_list)
-```
-
-To disable it:
-
-```ruby
-Feature.disable(:board_new_list)
-```
-
### Enable or disable iteration lists in boards **(PREMIUM SELF)**
-NOTE:
-When disabling iteration lists in boards, you also need to disable the [new add list form](#enable-or-disable-new-add-list-form).
-
The iteration list is under development but ready for production use. It is
deployed behind a feature flag that is **enabled by default**.
[GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md)
diff --git a/doc/user/project/issues/crosslinking_issues.md b/doc/user/project/issues/crosslinking_issues.md
index 2b07131df6e..ed6c07f2c6d 100644
--- a/doc/user/project/issues/crosslinking_issues.md
+++ b/doc/user/project/issues/crosslinking_issues.md
@@ -19,14 +19,20 @@ issue itself and the first commit related to that issue.
If the issue and the code you're committing are both in the same project,
add `#xxx` to the commit message, where `xxx` is the issue number.
-If they are not in the same project, you can add the full URL to the issue
-(`https://gitlab.com/<username>/<projectname>/issues/<xxx>`).
```shell
git commit -m "this is my commit message. Ref #xxx"
```
-or
+If they are in different projects, but in the same group,
+add `projectname#xxx` to the commit message.
+
+```shell
+git commit -m "this is my commit message. Ref projectname#xxx"
+```
+
+If they are not in the same group, you can add the full URL to the issue
+(`https://gitlab.com/<username>/<projectname>/issues/<xxx>`).
```shell
git commit -m "this is my commit message. Related to https://gitlab.com/<username>/<projectname>/issues/<xxx>"
diff --git a/doc/user/project/issues/index.md b/doc/user/project/issues/index.md
index 56c219eb8c3..9842b0820e6 100644
--- a/doc/user/project/issues/index.md
+++ b/doc/user/project/issues/index.md
@@ -43,9 +43,9 @@ To learn how the GitLab Strategic Marketing department uses GitLab issues with [
- [Cross-link issues](crosslinking_issues.md)
- [Bulk edit issues](../issues/managing_issues.md)
- [Sort issue lists](sorting_issue_lists.md)
-- [Search for issues](../../search/index.md#filtering-issue-and-merge-request-lists)
+- [Search for issues](../../search/index.md#filter-issue-and-merge-request-lists)
- [Epics](../../group/epics/index.md)
-- [Issue Boards](../issue_board.md)
+- [Issue boards](../issue_board.md)
- [Issues API](../../../api/issues.md)
- [Configure an external issue tracker](../../../integration/external-issue-tracker.md)
- [Parts of an issue](issue_data_and_actions.md)
diff --git a/doc/user/project/issues/issue_data_and_actions.md b/doc/user/project/issues/issue_data_and_actions.md
index 78dc6805f2b..6bb60e5e31a 100644
--- a/doc/user/project/issues/issue_data_and_actions.md
+++ b/doc/user/project/issues/issue_data_and_actions.md
@@ -129,7 +129,7 @@ element. Due dates can be changed as many times as needed.
### Labels
Categorize issues by giving them [labels](../labels.md). They help to organize workflows,
-and they enable you to work with the [GitLab Issue Board](../issue_board.md).
+and they enable you to work with the [issue board](../issue_board.md).
Group Labels, which allow you to use the same labels for all projects in the same
group, can also be given to issues. They work exactly the same, but are immediately
diff --git a/doc/user/project/issues/managing_issues.md b/doc/user/project/issues/managing_issues.md
index a2185c83f4d..7033b90b736 100644
--- a/doc/user/project/issues/managing_issues.md
+++ b/doc/user/project/issues/managing_issues.md
@@ -44,7 +44,7 @@ There are many ways to get to the New Issue form from a project's page:
![New issue from a project's dashboard](img/new_issue_from_projects_dashboard.png)
-- From an **Issue Board**, create a new issue by clicking on the plus sign (**+**) at the top of a list.
+- From an **issue board**, create a new issue by clicking on the plus sign (**+**) at the top of a list.
It opens a new issue for that project, pre-labeled with its respective list.
![From the issue board](img/new_issue_from_issue_board.png)
@@ -72,7 +72,7 @@ When you're creating a new issue, these are the fields you can fill in:
To visit the issue tracker for all projects in your group:
1. Go to the group dashboard.
-1. In the left sidebar, select **Issues**.
+1. On the left sidebar, select **Issues**.
1. In the top-right, select the **Select project to create issue** button.
1. Select the project you'd like to create an issue for. The button now reflects the selected
project.
@@ -237,10 +237,10 @@ using the close button:
![close issue - button](img/button_close_issue_v13_6.png)
-You can also close an issue from the [Issue Boards](../issue_board.md) by dragging an issue card
+You can also close an issue from the [issue boards](../issue_board.md) by dragging an issue card
from its list and dropping it into the **Closed** list.
-![close issue from the Issue Board](img/close_issue_from_board.gif)
+![close issue from the issue board](img/close_issue_from_board.gif)
### Closing issues automatically
diff --git a/doc/user/project/issues/sorting_issue_lists.md b/doc/user/project/issues/sorting_issue_lists.md
index 2681a39aeb6..aed346fb504 100644
--- a/doc/user/project/issues/sorting_issue_lists.md
+++ b/doc/user/project/issues/sorting_issue_lists.md
@@ -16,6 +16,7 @@ You can sort a list of issues several ways, including by:
- Milestone due date
- Popularity
- Priority
+- Title ([introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67234) in GitLab 14.3)
- Weight
The available sorting options can change based on the context of the list.
diff --git a/doc/user/project/members/share_project_with_groups.md b/doc/user/project/members/share_project_with_groups.md
index 353ce73329e..e1149b85cd5 100644
--- a/doc/user/project/members/share_project_with_groups.md
+++ b/doc/user/project/members/share_project_with_groups.md
@@ -59,7 +59,7 @@ In GitLab 13.11, you can optionally replace the sharing form with a modal window
To share a project after enabling this feature:
1. Go to your project's page.
-1. In the left sidebar, go to **Project information > Members**, and then select **Invite a group**.
+1. On the left sidebar, go to **Project information > Members**, and then select **Invite a group**.
1. Select a group, and select a **Max role**.
1. (Optional) Select an **Access expiration date**.
1. Select **Invite**.
diff --git a/doc/user/project/merge_requests/approvals/index.md b/doc/user/project/merge_requests/approvals/index.md
index 47744edd5ce..aff55419a88 100644
--- a/doc/user/project/merge_requests/approvals/index.md
+++ b/doc/user/project/merge_requests/approvals/index.md
@@ -61,7 +61,9 @@ GitLab displays one of these buttons after the body of the merge request:
Eligible approvers can also use the `/approve`
[quick action](../../../project/quick_actions.md) when adding a comment to
-a merge request.
+a merge request. [In GitLab 13.10 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/292936),
+if a user approves a merge request and is shown in the reviewer list, a green check mark
+(**{check-circle-filled}**) displays next to their name.
After a merge request receives the [number and type of approvals](rules.md) you configure, it can merge
unless it's blocked for another reason. Merge requests can be blocked by other problems,
diff --git a/doc/user/project/merge_requests/changes.md b/doc/user/project/merge_requests/changes.md
index c59d5973e21..d348c00bdc2 100644
--- a/doc/user/project/merge_requests/changes.md
+++ b/doc/user/project/merge_requests/changes.md
@@ -97,11 +97,8 @@ a merge request. You can choose to hide or show whitespace changes:
## Mark files as viewed
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51513) in GitLab 13.9.
-> - Deployed behind a feature flag, enabled by default.
-> - Enabled on GitLab.com.
-> - Recommended for production use.
-> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#enable-or-disable-file-views). **(FREE SELF)**
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51513) in GitLab 13.9 behind a feature flag, enabled by default.
+> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/296674) in GitLab 14.3.
When reviewing a merge request with many files multiple times, it may be useful to the reviewer
to focus on new changes and ignore the files that they have already reviewed and don't want to
@@ -116,25 +113,6 @@ To mark a file as viewed:
Once checked, the file remains marked for that reviewer unless there are newly introduced
changes to its content or the checkbox is unchecked.
-### Enable or disable file views **(FREE SELF)**
-
-The file view feature is under development but ready for production use.
-It is deployed behind a feature flag that is **enabled by default**.
-[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
-can opt to enable it for your instance.
-
-To enable it:
-
-```ruby
-Feature.enable(:local_file_reviews)
-```
-
-To disable it:
-
-```ruby
-Feature.disable(:local_file_reviews)
-```
-
## Show merge request conflicts in diff
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/232484) in GitLab 13.5.
diff --git a/doc/user/project/merge_requests/cherry_pick_changes.md b/doc/user/project/merge_requests/cherry_pick_changes.md
index a0c3efe7143..4a2319774ac 100644
--- a/doc/user/project/merge_requests/cherry_pick_changes.md
+++ b/doc/user/project/merge_requests/cherry_pick_changes.md
@@ -11,7 +11,7 @@ GitLab implements Git's powerful feature to
[cherry-pick any commit](https://git-scm.com/docs/git-cherry-pick "Git cherry-pick documentation")
with a **Cherry-pick** button in merge requests and commit details.
-## Cherry-picking a merge request
+## Cherry-pick a merge request
After the merge request has been merged, a **Cherry-pick** button displays
to cherry-pick the changes introduced by that merge request.
@@ -25,7 +25,7 @@ where you can choose to either:
- Cherry-pick the changes directly into the selected branch.
- Create a new merge request with the cherry-picked changes.
-### Cherry-pick tracking
+### Track a cherry-pick
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2675) in GitLab 12.9.
@@ -40,7 +40,7 @@ NOTE:
We only track cherry-pick executed from GitLab (both UI and API). Support for tracking cherry-picked commits through the command line
is tracked [in this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/202215).
-## Cherry-picking a commit
+## Cherry-pick a commit
You can cherry-pick a commit from the commit details page:
diff --git a/doc/user/project/merge_requests/code_quality.md b/doc/user/project/merge_requests/code_quality.md
index 6337fb1e87b..e9f1874eb96 100644
--- a/doc/user/project/merge_requests/code_quality.md
+++ b/doc/user/project/merge_requests/code_quality.md
@@ -56,11 +56,10 @@ See also the Code Climate list of [Supported Languages for Maintainability](http
## Code Quality in diff view **(ULTIMATE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/267612) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.11.
-> - [Deployed behind a feature flag](../../../user/feature_flags.md), disabled by default.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/267612) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.11, disabled by default behind the `codequality_mr_diff` [feature flag](../../../administration/feature_flags.md).
> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/284140) in GitLab 13.12.
-> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/284140) in GitLab 14.1.
-> - [Inline annotation added](https://gitlab.com/gitlab-org/gitlab/-/issues/2526) in GitLab 14.1.
+> - [Disabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/2526) in GitLab 14.0 due to [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/334116).
+> - [Inline annotation added](https://gitlab.com/gitlab-org/gitlab/-/issues/2526) and [feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/284140) in GitLab 14.1.
Changes to files in merge requests can cause Code Quality to fall if merged. In these cases,
the merge request's diff view displays an indicator next to lines with new Code Quality violations. For example:
@@ -276,7 +275,7 @@ might look like this example:
job1:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"' # Run job1 in merge request pipelines
- - if: '$CI_COMMIT_BRANCH == "master"' # Run job1 in pipelines on the master branch (but not in other branch pipelines)
+ - if: '$CI_COMMIT_BRANCH == "main"' # Run job1 in pipelines on the main branch (but not in other branch pipelines)
- if: '$CI_COMMIT_TAG' # Run job1 in pipelines for tags
```
@@ -292,7 +291,7 @@ code_quality:
- if: '$CODE_QUALITY_DISABLED'
when: never
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"' # Run code quality job in merge request pipelines
- - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' # Run code quality job in pipelines on the master branch (but not in other branch pipelines)
+ - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' # Run code quality job in pipelines on the default branch (but not in other branch pipelines)
- if: '$CI_COMMIT_TAG' # Run code quality job in pipelines for tags
```
diff --git a/doc/user/project/merge_requests/fail_fast_testing.md b/doc/user/project/merge_requests/fail_fast_testing.md
index 6d8a128c39f..0d87a04461b 100644
--- a/doc/user/project/merge_requests/fail_fast_testing.md
+++ b/doc/user/project/merge_requests/fail_fast_testing.md
@@ -45,7 +45,7 @@ This template requires:
- Use [Pipelines for merge requests](../../../ci/pipelines/merge_request_pipelines.md#configure-pipelines-for-merge-requests)
- [Pipelines for Merged Results](../../../ci/pipelines/pipelines_for_merged_results.md#enable-pipelines-for-merged-results)
enabled in the project settings.
-- A Docker image with Ruby available. The template uses `image: ruby:2.6` by default, but you [can override](../../../ci/yaml/includes.md#overriding-external-template-values) this.
+- A Docker image with Ruby available. The template uses `image: ruby:2.6` by default, but you [can override](../../../ci/yaml/includes.md#override-included-configuration-values) this.
## Configuring Fast RSpec Failure
diff --git a/doc/user/project/merge_requests/fast_forward_merge.md b/doc/user/project/merge_requests/fast_forward_merge.md
index b1e8d761f5c..7edc379399b 100644
--- a/doc/user/project/merge_requests/fast_forward_merge.md
+++ b/doc/user/project/merge_requests/fast_forward_merge.md
@@ -24,9 +24,11 @@ When a fast-forward merge is not possible, the user is given the option to rebas
## Enabling fast-forward merges
-1. Navigate to your project's **Settings** and search for the 'Merge method'
-1. Select the **Fast-forward merge** option
-1. Hit **Save changes** for the changes to take effect
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Settings > General**.
+1. Expand **Merge requests**.
+1. In the **Merge method** section, select **Fast-forward merge**.
+1. Select **Save changes**.
Now, when you visit the merge request page, you can accept it
**only if a fast-forward merge is possible**.
diff --git a/doc/user/project/merge_requests/getting_started.md b/doc/user/project/merge_requests/getting_started.md
index 46fc3ec141d..72fcd7f36b0 100644
--- a/doc/user/project/merge_requests/getting_started.md
+++ b/doc/user/project/merge_requests/getting_started.md
@@ -65,7 +65,7 @@ request's page at the top-right side:
After you have created the merge request, you can also:
- [Discuss](../../discussions/index.md) your implementation with your team in the merge request thread.
-- [Perform inline code reviews](reviews/index.md#perform-inline-code-reviews).
+- [Perform inline code reviews](reviews/index.md).
- Add [merge request dependencies](merge_request_dependencies.md) to restrict it to be merged only when other merge requests have been merged. **(PREMIUM)**
- Preview continuous integration [pipelines on the merge request widget](widgets.md).
- Preview how your changes look directly on your deployed application with [Review Apps](widgets.md#live-preview-with-review-apps).
@@ -166,10 +166,13 @@ is set for deletion, the merge request widget displays the
### Branch retargeting on merge **(FREE SELF)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/320902) in GitLab 13.9.
-> - [Deployed behind a feature flag](../../feature_flags.md), disabled by default.
-> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/320895) in GitLab 13.10.
-> - Recommended for production use.
-> - To use in GitLab self-managed instances, ask a GitLab administrator to [disable it](#enable-or-disable-branch-retargeting-on-merge). **(FREE SELF)**
+> - [Disabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/320902) in GitLab 13.9.
+> - [Enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/320895) GitLab 13.10.
+
+FLAG:
+On self-managed GitLab, by default this feature is available. To hide the feature,
+ask an administrator to
+[disable the `retarget_merge_requests` flag](../../../administration/feature_flags.md).
In specific circumstances, GitLab can retarget the destination branch of
open merge request, if the destination branch merges while the merge request is
@@ -203,22 +206,3 @@ This improvement is [tracked as a follow-up](https://gitlab.com/gitlab-org/gitla
- Take one thing at a time and ship the smallest changes possible. By doing so,
reviews are faster and your changes are less prone to errors.
- Do not use capital letters nor special chars in branch names.
-
-### Enable or disable branch retargeting on merge **(FREE SELF)**
-
-Automatically retargeting merge requests is under development but ready for production use.
-It is deployed behind a feature flag that is **enabled by default**.
-[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
-can opt to disable it.
-
-To enable it:
-
-```ruby
-Feature.enable(:retarget_merge_requests)
-```
-
-To disable it:
-
-```ruby
-Feature.disable(:retarget_merge_requests)
-```
diff --git a/doc/user/project/merge_requests/index.md b/doc/user/project/merge_requests/index.md
index 6c2f07d7012..b7e055ca749 100644
--- a/doc/user/project/merge_requests/index.md
+++ b/doc/user/project/merge_requests/index.md
@@ -27,7 +27,7 @@ important parts of the merge request:
![Merge request tab positions](img/merge_request_tab_position_v13_11.png)
- **Overview**: Contains the description, notifications from pipelines, and a
- discussion area for [comment threads](../../discussions/index.md#resolve-a-thread))
+ discussion area for [comment threads](../../discussions/index.md#resolve-a-thread)
and [code suggestions](reviews/suggestions.md). The right sidebar provides fields
to add assignees, reviewers, labels, and a milestone to your work, and the
[merge request widgets area](widgets.md) reports results from pipelines and tests.
@@ -53,7 +53,7 @@ GitLab displays open merge requests, with tabs to filter the list by open and cl
![Project merge requests list view](img/project_merge_requests_list_view_v13_5.png)
-You can [search and filter](../../search/index.md#filtering-issue-and-merge-request-lists),
+You can [search and filter](../../search/index.md#filter-issue-and-merge-request-lists),
the results, or select a merge request to begin a review.
## Merge request sidebar
@@ -76,6 +76,21 @@ can assign, categorize, and track progress on a merge request:
- [**Notifications**](../../profile/notifications.md): A toggle to select whether
or not to receive notifications for updates to a merge request.
+## Add changes to a merge request
+
+If you have permission to add changes to a merge request, you can add your changes
+to an existing merge request in several ways, depending on the complexity of your change and whether you need access to a development environment:
+
+- [Edit changes in the Web IDE](../web_ide/index.md) in your browser. Use this
+ browser-based method to edit multiple files, or if you are not comfortable with Git commands.
+ You cannot run tests from the Web IDE.
+- [Edit changes in Gitpod](../../../integration/gitpod.md#launch-gitpod-in-gitlab), if you
+ need a fully-featured environment to both edit files, and run tests afterward. Gitpod
+ supports running the [GitLab Development Kit (GDK)](https://gitlab.com/gitlab-org/gitlab-development-kit).
+ To use Gitpod, you must [enable Gitpod in your user account](../../../integration/gitpod.md#enable-gitpod-in-your-user-settings).
+- [Push changes from the command line](../../../gitlab-basics/start-using-git.md), if you are
+ familiar with Git and the command line.
+
## Close a merge request
If you decide to permanently stop work on a merge request,
@@ -130,7 +145,7 @@ For a web developer writing a webpage for your company's website:
1. You request your web designers for their implementation.
1. You request the [approval](approvals/index.md) from your manager.
1. Once approved, your merge request is [squashed and merged](squash_and_merge.md), and [deployed to staging with GitLab Pages](https://about.gitlab.com/blog/2021/02/05/ci-deployment-and-environments/).
-1. Your production team [cherry picks](cherry_pick_changes.md) the merge commit into production.
+1. Your production team [cherry-picks](cherry_pick_changes.md) the merge commit into production.
## Related topics
diff --git a/doc/user/project/merge_requests/load_performance_testing.md b/doc/user/project/merge_requests/load_performance_testing.md
index 7ea785c00ea..1d892a3c2e1 100644
--- a/doc/user/project/merge_requests/load_performance_testing.md
+++ b/doc/user/project/merge_requests/load_performance_testing.md
@@ -181,7 +181,7 @@ include:
review:
stage: deploy
environment:
- name: review/$CI_COMMIT_REF_NAME
+ name: review/$CI_COMMIT_REF_SLUG
url: http://$CI_ENVIRONMENT_SLUG.example.com
script:
- run_deploy_script
diff --git a/doc/user/project/merge_requests/revert_changes.md b/doc/user/project/merge_requests/revert_changes.md
index a798f2c9b85..e6fb619d365 100644
--- a/doc/user/project/merge_requests/revert_changes.md
+++ b/doc/user/project/merge_requests/revert_changes.md
@@ -5,12 +5,12 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference, concepts
---
-# Reverting changes **(FREE)**
+# Revert changes **(FREE)**
You can use Git's powerful feature to [revert any commit](https://git-scm.com/docs/git-revert "Git revert documentation")
by clicking the **Revert** button in merge requests and commit details.
-## Reverting a merge request
+## Revert a merge request
NOTE:
The **Revert** button is available only for merge requests
@@ -34,7 +34,7 @@ create a new merge request with the revert changes.
After the merge request has been reverted, the **Revert** button is no longer available.
-## Reverting a commit
+## Revert a commit
You can revert a commit from the commit details page:
diff --git a/doc/user/project/merge_requests/reviews/index.md b/doc/user/project/merge_requests/reviews/index.md
index 61cd0d25aaf..dbf3b0180e6 100644
--- a/doc/user/project/merge_requests/reviews/index.md
+++ b/doc/user/project/merge_requests/reviews/index.md
@@ -12,9 +12,10 @@ type: index, reference
[Merge requests](../index.md) are the primary method of making changes to files in a
GitLab project. [Create and submit a merge request](../creating_merge_requests.md)
-to propose changes. Your team leaves [comments](../../../discussions/index.md), and
-makes [code suggestions](suggestions.md) you can accept from the user interface.
-When your work is reviewed, your team members can choose to accept or reject it.
+to propose changes. Your team leaves [comments](../../../discussions/index.md) on
+your merge request, and makes [code suggestions](suggestions.md) you can accept
+from the user interface. When your work is reviewed, your team members can choose
+to accept or reject it.
## Review a merge request
@@ -28,7 +29,9 @@ To start your review:
1. Go to the merge request you want to review, and select the **Changes** tab.
To learn more about navigating the diffs displayed in this tab, read
[Changes tab in merge requests](../changes.md).
-1. Select a line of code. In GitLab version 13.2 and later, you can [highlight a set of lines](#comment-on-multiple-lines).
+1. Select the **{comment}** **comment** icon in the gutter to expand the diff lines
+ and display a comment box. In GitLab version 13.2 and later, you can
+ [select multiple lines](#comment-on-multiple-lines).
1. Write your first comment, and select **Start a review** below your comment:
![Starting a review](img/mr_review_start.png)
1. Continue adding comments to lines of code, and select the appropriate button after
@@ -40,7 +43,13 @@ To start your review:
The comment shows the actions to perform after publication, but does not perform them
until you submit your review.
1. When your review is complete, you can [submit the review](#submit-a-review). Your comments
- are now visible, and any quick actions included your comments are performed.
+ are now visible, and any [quick actions](../../quick_actions.md) included in
+ your comments are performed.
+
+[In GitLab 13.10 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/292936),
+if you [approve a merge request](../approvals/index.md#approve-a-merge-request) and
+are shown in the reviewer list, a green check mark **{check-circle-filled}**
+displays next to your name.
### Submit a review
@@ -57,7 +66,7 @@ When you submit your review, GitLab:
review comments attached. Replying to this email creates a new comment on the merge request.
- Perform any quick actions you added to your review comments.
-### Resolving/Unresolving threads
+### Resolve or unresolve thread with a comment
Review comments can also resolve or unresolve [resolvable threads](../../../discussions/index.md#resolve-a-thread)).
When replying to a comment, a checkbox is displayed to resolve or unresolve
@@ -72,7 +81,7 @@ comment itself.
![Unresolve status](img/mr_review_unresolve.png)
-### Adding a new comment
+### Add a new comment
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8225) in GitLab 13.10.
@@ -97,7 +106,7 @@ This example shows reviewers and approval rules in a merge request sidebar:
![Reviewer approval rules in sidebar](img/reviewer_approval_rules_sidebar_v13_8.png)
-### Requesting a new review
+### Request a new review
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/293933) in GitLab 13.9.
@@ -112,13 +121,6 @@ the author of the merge request can request a new review from the reviewer:
GitLab creates a new [to-do item](../../../todos.md) for the reviewer, and sends
them a notification email.
-#### Approval status
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/292936) in GitLab 13.10.
-
-If a user in the reviewer list has approved the merge request, a green tick symbol is
-shown to the right of their name.
-
## Semi-linear history merge requests
A merge commit is created for every merge, but the branch is only merged if
@@ -130,18 +132,7 @@ succeeded, the target branch build also succeeds after the merge.
1. In the **Merge method** section, select **Merge commit with semi-linear history**.
1. Select **Save changes**.
-## Perform inline code reviews
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/13950) in GitLab 11.5.
-
-In a merge request, you can leave comments in any part of the file being changed.
-In the merge request Diff UI, you can:
-
-- **Comment on a single line**: Select the **{comment}** **comment** icon in the
- gutter to expand the diff lines and display a comment box.
-- [**Comment on multiple lines**](#comment-on-multiple-lines).
-
-### Comment on multiple lines
+## Comment on multiple lines
> - [Introduced](https://gitlab.com/gitlab-org/ux-research/-/issues/870) in GitLab 13.2.
> - [Added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49875) click-and-drag features in GitLab 13.8.
diff --git a/doc/user/project/merge_requests/reviews/suggestions.md b/doc/user/project/merge_requests/reviews/suggestions.md
index 8ee068531c8..4027ec08234 100644
--- a/doc/user/project/merge_requests/reviews/suggestions.md
+++ b/doc/user/project/merge_requests/reviews/suggestions.md
@@ -46,7 +46,7 @@ branch. The [Developer role](../../../permissions.md) is required to do so.
## Multi-line suggestions
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53310) in GitLab 11.10.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53310) in GitLab 11.10.
Reviewers can also suggest changes to multiple lines with a single suggestion
within merge request diff threads by adjusting the range offsets. The
diff --git a/doc/user/project/merge_requests/squash_and_merge.md b/doc/user/project/merge_requests/squash_and_merge.md
index 2842c084bc5..c3fc2fa871f 100644
--- a/doc/user/project/merge_requests/squash_and_merge.md
+++ b/doc/user/project/merge_requests/squash_and_merge.md
@@ -12,8 +12,6 @@ type: reference, concepts
With squash and merge you can combine all your merge request's commits into one
and retain a clean history.
-## Overview
-
Squashing lets you tidy up the commit history of a branch when accepting a merge
request. It applies all of the changes in the merge request as a single commit,
and then merges that commit using the merge method set for the project.
@@ -58,7 +56,7 @@ meaningful commit messages and:
- It's simpler to [revert](revert_changes.md) if necessary.
- The merged branch retains the full commit history.
-## Enabling squash for a merge request
+## Enable squash for a merge request
Anyone who can create or edit a merge request can choose for it to be squashed
on the merge request form. Users can select or clear the checkbox when they
@@ -98,7 +96,7 @@ it. This is because squashing is only available when accepting a merge request,
so a merge request may need to be rebased before squashing, even though
squashing can itself be considered equivalent to rebasing.
-## Squash Commits Options
+## Squash commits options
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/17613) in GitLab 13.2.
> - Deployed behind a feature flag, disabled by default.
diff --git a/doc/user/project/merge_requests/status_checks.md b/doc/user/project/merge_requests/status_checks.md
index 1576b639a76..399d7958bbf 100644
--- a/doc/user/project/merge_requests/status_checks.md
+++ b/doc/user/project/merge_requests/status_checks.md
@@ -125,7 +125,7 @@ the status checks as `pending`:
![Status checks widget pending](img/status_checks_widget_pending_v14_0.png)
-After GitLab [receives a response](../../../api/status_checks.md#set-approval-status-of-an-external-status-check)
+After GitLab [receives a response](../../../api/status_checks.md#set-status-of-an-external-status-check)
from the external status check, the widget updates accordingly.
NOTE:
diff --git a/doc/user/project/merge_requests/test_coverage_visualization.md b/doc/user/project/merge_requests/test_coverage_visualization.md
index ce8bfa2d054..813e3c1c9ce 100644
--- a/doc/user/project/merge_requests/test_coverage_visualization.md
+++ b/doc/user/project/merge_requests/test_coverage_visualization.md
@@ -24,7 +24,8 @@ Collecting the coverage information is done via GitLab CI/CD's
[artifacts reports feature](../../../ci/yaml/index.md#artifactsreports).
You can specify one or more coverage reports to collect, including wildcard paths.
GitLab then takes the coverage information in all the files and combines it
-together.
+together. Coverage files are parsed in a background job so there can be a delay
+between pipeline completion and the visualization loading on the page.
For the coverage analysis to work, you have to provide a properly formatted
[Cobertura XML](https://cobertura.github.io/cobertura/) report to
@@ -129,7 +130,7 @@ The `source` is ignored if the path does not follow this pattern. The parser ass
### JavaScript example
-The following [`gitlab-ci.yml`](../../../ci/yaml/index.md) example uses [Mocha](https://mochajs.org/)
+The following [`.gitlab-ci.yml`](../../../ci/yaml/index.md) example uses [Mocha](https://mochajs.org/)
JavaScript testing and [nyc](https://github.com/istanbuljs/nyc) coverage-tooling to
generate the coverage artifact:
@@ -147,7 +148,7 @@ test:
#### Maven example
-The following [`gitlab-ci.yml`](../../../ci/yaml/index.md) example for Java or Kotlin uses [Maven](https://maven.apache.org/)
+The following [`.gitlab-ci.yml`](../../../ci/yaml/index.md) example for Java or Kotlin uses [Maven](https://maven.apache.org/)
to build the project and [JaCoCo](https://www.eclemma.org/jacoco/) coverage-tooling to
generate the coverage artifact.
You can check the [Docker image configuration and scripts](https://gitlab.com/haynes/jacoco2cobertura) if you want to build your own image.
@@ -185,7 +186,7 @@ coverage-jdk11:
#### Gradle example
-The following [`gitlab-ci.yml`](../../../ci/yaml/index.md) example for Java or Kotlin uses [Gradle](https://gradle.org/)
+The following [`.gitlab-ci.yml`](../../../ci/yaml/index.md) example for Java or Kotlin uses [Gradle](https://gradle.org/)
to build the project and [JaCoCo](https://www.eclemma.org/jacoco/) coverage-tooling to
generate the coverage artifact.
You can check the [Docker image configuration and scripts](https://gitlab.com/haynes/jacoco2cobertura) if you want to build your own image.
@@ -223,7 +224,7 @@ coverage-jdk11:
### Python example
-The following [`gitlab-ci.yml`](../../../ci/yaml/index.md) example for Python uses [pytest-cov](https://pytest-cov.readthedocs.io/) to collect test coverage data and [coverage.py](https://coverage.readthedocs.io/) to convert the report to use full relative paths.
+The following [`.gitlab-ci.yml`](../../../ci/yaml/index.md) example for Python uses [pytest-cov](https://pytest-cov.readthedocs.io/) to collect test coverage data and [coverage.py](https://coverage.readthedocs.io/) to convert the report to use full relative paths.
The information isn't displayed without the conversion.
This example assumes that the code for your package is in `src/` and your tests are in `tests.py`:
@@ -243,7 +244,7 @@ run tests:
### C/C++ example
-The following [`gitlab-ci.yml`](../../../ci/yaml/index.md) example for C/C++ with
+The following [`.gitlab-ci.yml`](../../../ci/yaml/index.md) example for C/C++ with
`gcc` or `g++` as the compiler uses [`gcovr`](https://gcovr.com/en/stable/) to generate the coverage
output file in Cobertura XML format.
diff --git a/doc/user/project/merge_requests/versions.md b/doc/user/project/merge_requests/versions.md
index 1d196de36e2..3922ee4d770 100644
--- a/doc/user/project/merge_requests/versions.md
+++ b/doc/user/project/merge_requests/versions.md
@@ -1,6 +1,6 @@
---
-stage: none
-group: unassigned
+stage: Create
+group: Code Review
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
type: reference, concepts
---
diff --git a/doc/user/project/pages/index.md b/doc/user/project/pages/index.md
index 5a688fbb485..385a4fafa7d 100644
--- a/doc/user/project/pages/index.md
+++ b/doc/user/project/pages/index.md
@@ -46,7 +46,7 @@ To create a GitLab Pages website:
| Document | Description |
| -------- | ----------- |
-| [Create a `gitlab-ci.yml` file from scratch](getting_started/pages_from_scratch.md) | Add a Pages site to an existing project. Learn how to create and configure your own CI file. |
+| [Create a `.gitlab-ci.yml` file from scratch](getting_started/pages_from_scratch.md) | Add a Pages site to an existing project. Learn how to create and configure your own CI file. |
| [Use a `.gitlab-ci.yml` template](getting_started/pages_ci_cd_template.md) | Add a Pages site to an existing project. Use a pre-populated CI template file. |
| [Fork a sample project](getting_started/pages_forked_sample_project.md) | Create a new project with Pages already configured by forking a sample project. |
| [Use a project template](getting_started/pages_new_project_template.md) | Create a new project with Pages already configured by using a template. |
diff --git a/doc/user/project/pages/pages_access_control.md b/doc/user/project/pages/pages_access_control.md
index 532a36b2327..4b4d479e3e9 100644
--- a/doc/user/project/pages/pages_access_control.md
+++ b/doc/user/project/pages/pages_access_control.md
@@ -52,6 +52,6 @@ To sign out of your GitLab Pages website, revoke the application access token
for GitLab Pages:
1. In the top menu, select your profile, and then select **Settings**.
-1. In the left sidebar, select **Applications**.
+1. On the left sidebar, select **Applications**.
1. Scroll to the **Authorized applications** section, find the **GitLab Pages**
entry, and select its **Revoke** button.
diff --git a/doc/user/project/pages/redirects.md b/doc/user/project/pages/redirects.md
index 8ed6f214605..3deea92f56e 100644
--- a/doc/user/project/pages/redirects.md
+++ b/doc/user/project/pages/redirects.md
@@ -9,62 +9,58 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/24) in GitLab Pages 1.25.0 and GitLab 13.4 behind a feature flag, disabled by default.
> - [Became enabled by default](https://gitlab.com/gitlab-org/gitlab-pages/-/merge_requests/367) in GitLab 13.5.
-WARNING:
-This feature might not be available to you. Check the **version history** note above for details.
-
In GitLab Pages, you can configure rules to forward one URL to another using
[Netlify style](https://docs.netlify.com/routing/redirects/#syntax-for-the-redirects-file)
HTTP redirects.
-## Supported features
-
-GitLab Pages only supports the
-[`_redirects` plain text file syntax](https://docs.netlify.com/routing/redirects/#syntax-for-the-redirects-file),
-and `.toml` files are not supported.
-
-Redirects are only supported at a basic level. GitLab Pages doesn't support all
-[special options offered by Netlify](https://docs.netlify.com/routing/redirects/redirect-options/).
-
-Note that supported paths must start with a forward slash `/`.
+Not all
+[special options offered by Netlify](https://docs.netlify.com/routing/redirects/redirect-options/)
+are supported.
| Feature | Supported | Example |
| ------- | --------- | ------- |
-| Redirects (`301`, `302`) | **{check-circle}** Yes | `/wardrobe.html /narnia.html 302`
-| Rewrites (other status codes) | **{dotted-circle}** No | `/en/* /en/404.html 404` |
-| [Splats](https://docs.netlify.com/routing/redirects/redirect-options/#splats) | **{dotted-circle}** No | `/news/* /blog/:splat` |
-| Placeholders | **{dotted-circle}** No | `/news/:year/:month/:date/:slug /blog/:year/:month/:date/:slug` |
+| [Redirects (`301`, `302`)](#redirects) | **{check-circle}** Yes | `/wardrobe.html /narnia.html 302`
+| [Rewrites (`200`)](#rewrites) | **{check-circle}** Yes | `/* / 200` |
+| [Splats](#splats) | **{check-circle}** Yes | `/news/* /blog/:splat` |
+| [Placeholders](#placeholders) | **{check-circle}** Yes | `/news/:year/:month/:date /blog-:year-:month-:date.html` |
+| Rewrites (other than `200`) | **{dotted-circle}** No | `/en/* /en/404.html 404` |
| Query parameters | **{dotted-circle}** No | `/store id=:id /blog/:id 301` |
| Force ([shadowing](https://docs.netlify.com/routing/redirects/rewrites-proxies/#shadowing)) | **{dotted-circle}** No | `/app/ /app/index.html 200!` |
| Domain-level redirects | **{dotted-circle}** No | `http://blog.example.com/* https://www.example.com/blog/:splat 301` |
| Redirect by country or language | **{dotted-circle}** No | `/ /anz 302 Country=au,nz` |
| Redirect by role | **{dotted-circle}** No | `/admin/* 200! Role=admin` |
+NOTE:
+The [matching behavior test cases](https://gitlab.com/gitlab-org/gitlab-pages/-/blob/master/internal/redirects/matching_test.go)
+are a good resource for understanding how GitLab implements rule matching in
+detail. Community contributions are welcome for any edge cases that aren't included in
+this test suite!
+
## Create redirects
-To create redirects,
-create a configuration file named `_redirects` in the `public/` directory of your
-GitLab Pages site.
+To create redirects, create a configuration file named `_redirects` in the
+`public/` directory of your GitLab Pages site.
-If your GitLab Pages site uses the default domain name (such as
-`namespace.gitlab.io/projectname`) you must prefix every rule with the project name:
+Note that:
-```plaintext
-/projectname/redirect-portal.html /projectname/magic-land.html 301
-/projectname/cake-portal.html /projectname/still-alive.html 302
-/projectname/wardrobe.html /projectname/narnia.html 302
-/projectname/pit.html /projectname/spikes.html 302
-```
+- All paths must start with a forward slash `/`.
+- A default status code of `301` is applied if no [status code](#http-status-codes) is provided.
+- The `_redirects` file has a file size limit of 64KB and a maximum of 1,000 rules per project.
+ Only the first 1,000 rules are processed.
+- If your GitLab Pages site uses the default domain name (such as
+ `namespace.gitlab.io/projectname`) you must prefix every rule with the project name:
-If your GitLab Pages site uses [custom domains](custom_domains_ssl_tls_certification/index.md),
-no project name prefix is needed. For example, if your custom domain is `example.com`,
-your `_redirect` file would look like:
+ ```plaintext
+ /projectname/wardrobe.html /projectname/narnia.html 302
+ ```
-```plaintext
-/redirect-portal.html /magic-land.html 301
-/cake-portal.html /still-alive.html 302
-/wardrobe.html /narnia.html 302
-/pit.html /spikes.html 302
-```
+- If your GitLab Pages site uses [custom domains](custom_domains_ssl_tls_certification/index.md),
+ no project name prefix is needed. For example, if your custom domain is `example.com`,
+ your `_redirects` file would look like:
+
+ ```plaintext
+ /wardrobe.html /narnia.html 302
+ ```
## Files override redirects
@@ -81,6 +77,132 @@ GitLab doesn't support Netlify's
[force option](https://docs.netlify.com/routing/redirects/rewrites-proxies/#shadowing)
to change this behavior.
+## HTTP status codes
+
+A default status code of `301` is applied if no status code is provided, but
+you can explicitly set your own. The following HTTP codes are supported:
+
+- **301**: Permanent redirect.
+- **302**: Temporary redirect.
+- **200**: Standard response for successful HTTP requests. Pages
+ serves the content in the `to` rule if it exists, without changing the URL in
+ the address bar.
+
+## Redirects
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-pages/-/merge_requests/458) in GitLab 14.3.
+> - Enabled on GitLab.com.
+> - Enabled by default in self-managed GitLab behind the [`FF_ENABLE_REDIRECTS` feature flag](#feature-flag-for-redirects).
+
+To create a redirect, add a rule that includes a `from` path, a `to` path,
+and an [HTTP status code](#http-status-codes):
+
+```plaintext
+# 301 permanent redirect
+/old/file.html /new/file.html 301
+
+# 302 temporary redirect
+/old/another_file.html /new/another_file.html 302
+```
+
+## Rewrites
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-pages/-/merge_requests/458) in GitLab 14.3.
+> - Enabled on GitLab.com.
+> - Disabled by default in self-managed GitLab behind the [`FF_ENABLE_PLACEHOLDERS` feature flag](#feature-flag-for-rewrites).
+
+Provide a status code of `200` to serve the content of the `to` path when the
+request matches the `from`:
+
+```plaintext
+/old/file.html /new/file.html 200
+```
+
+This status code can be used in combination with [splat rules](#splats) to dynamically
+rewrite the URL.
+
+## Splats
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-pages/-/merge_requests/458) in GitLab 14.3.
+
+A rule with an asterisk (`*`) in its `from` path, known as a splat, matches
+anything at the start, middle, or end of the requested path. This example
+matches anything after `/old/` and rewrites it to `/new/file.html`:
+
+```plaintext
+/old/* /new/file.html 200
+```
+
+### Splat placeholders
+
+The content matched by a `*` in a rule's `from` path can be injected into the
+`to` path using the `:splat` placeholder:
+
+```plaintext
+/old/* /new/:splat 200
+```
+
+In this example, a request to `/old/file.html` serves the contents of `/new/file.html`
+with a `200` status code.
+
+If a rule's `from` path includes multiple splats, the value of the first splat
+match replaces any `:splat`s in the `to` path.
+
+### Splat matching behavior
+
+Splats are "greedy" and match as many characters as possible:
+
+```plaintext
+/old/*/file /new/:splat/file 301
+```
+
+In this example, the rule redirects `/old/a/b/c/file` to `/new/a/b/c/file`.
+
+Splats also match empty strings, so the previous rule redirects
+`/old/file` to `/new/file`.
+
+### Rewrite all requests to a root `index.html`
+
+Single page applications (SPAs) often perform their own routing using
+client-side routes. For these applications, it's important that _all_ requests
+are rewritten to the root `index.html` so that the routing logic can be handled
+by the JavaScript application. You can do this with a `_redirects`
+rule like:
+
+```plaintext
+/* /index.html 200
+```
+
+## Placeholders
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-pages/-/merge_requests/458) in GitLab 14.3.
+
+Use placeholders in rules to match portions of the requested URL and use these
+matches when rewriting or redirecting to a new URL.
+
+A placehold is formatted as a `:` character followed by a string of letters
+(`[a-zA-Z]+`) in both the `from` and `to` paths:
+
+```plaintext
+/news/:year/:month/:date/:slug /blog/:year-:month-:date-:slug 200
+```
+
+This rule instructs Pages to respond to a request for `/news/2021/08/12/file.html` by
+serving the content of `/blog/2021-08-12-file.html` with a `200`.
+
+### Placeholder matching behavior
+
+Compared to [splats](#splats), placeholders are more limited in how much content
+they match. Placeholders match text between forward slashes
+(`/`), so use placeholders to match single path segments.
+
+In addition, placeholders do not match empty strings. A rule like the following
+would **not** match a request URL like `/old/file`:
+
+```plaintext
+/old/:path /new/:path
+```
+
## Debug redirect rules
If a redirect isn't working as expected, or you want to check your redirect syntax, visit
@@ -103,8 +225,49 @@ rule 10: valid
rule 11: valid
```
-## Disable redirects
+## Differences from Netlify's implementation
+
+Most supported `_redirects` rules behave the same in both GitLab and Netlify.
+However, there are some minor differences:
+
+- **All rule URLs must begin with a slash:**
+
+ Netlify does not require URLs to begin with a forward slash:
+
+ ```plaintext
+ # Valid in Netlify, invalid in GitLab
+ */path /new/path 200
+ ```
+
+ GitLab validates that all URLs begin with a forward slash. A valid
+ equivalent of the previous example:
+
+ ```plaintext
+ # Valid in both Netlify and GitLab
+ /old/path /new/path 200
+ ```
+- **All placeholder values are populated:**
+
+ Netlify only populates placeholder values that appear in the `to` path:
+
+ ```plaintext
+ /old /new/:placeholder
+ ```
+
+ Given a request to `/old`:
+
+ - Netlify redirects to `/new/:placeholder` (with a
+ literal `:placeholder`).
+ - GitLab redirects to `/new/`.
+
+## Features behind feature flags
+
+Some Pages features are behind feature flags.
+
+### Feature flag for redirects
+
+FLAG:
Redirects in GitLab Pages is under development, and is deployed behind a feature flag
that is **enabled by default**.
@@ -126,3 +289,28 @@ For [source installations](../../../administration/pages/source.md), define the
export FF_ENABLE_REDIRECTS="false"
/path/to/pages/bin/gitlab-pages -config gitlab-pages.conf
```
+
+### Feature flag for rewrites
+
+FLAG:
+Rewrites in GitLab Pages is under development, and is deployed behind a feature flag
+that is **disabled by default**.
+
+To enable rewrites, for [Omnibus installations](../../../administration/pages/index.md), define the
+`FF_ENABLE_PLACEHOLDERS` environment variable in the
+[global settings](../../../administration/pages/index.md#global-settings).
+Add the following line to `/etc/gitlab/gitlab.rb` and
+[reconfigure the instance](../../../administration/restart_gitlab.md#omnibus-gitlab-reconfigure):
+
+```ruby
+gitlab_pages['env']['FF_ENABLE_PLACEHOLDERS'] = 'true'
+```
+
+For [source installations](../../../administration/pages/source.md), define the
+`FF_ENABLE_PLACEHOLDERS` environment variable, then
+[restart GitLab](../../../administration/restart_gitlab.md#installations-from-source):
+
+```shell
+export FF_ENABLE_PLACEHOLDERS="true"
+/path/to/pages/bin/gitlab-pages -config gitlab-pages.conf
+```
diff --git a/doc/user/project/quick_actions.md b/doc/user/project/quick_actions.md
index 683496b4a9b..52b59d70302 100644
--- a/doc/user/project/quick_actions.md
+++ b/doc/user/project/quick_actions.md
@@ -103,6 +103,7 @@ threads. Some quick actions might not be available to all subscription tiers.
| `/target_branch <local branch name>` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Set target branch. |
| `/title <new title>` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Change title. |
| `/todo` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Add a to-do item. |
+| `/unapprove` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Unapprove the merge request. ([introduced in GitLab 14.3](https://gitlab.com/gitlab-org/gitlab/-/issues/8003)|
| `/unassign @user1 @user2` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Remove specific assignees. |
| `/unassign` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Remove all assignees. |
| `/unassign_reviewer @user1 @user2` or `/remove_reviewer @user1 @user2` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Remove specific reviewers. |
diff --git a/doc/user/project/releases/img/deploy_freeze_v13_10.png b/doc/user/project/releases/img/deploy_freeze_v13_10.png
deleted file mode 100644
index 5c4b2d983dd..00000000000
--- a/doc/user/project/releases/img/deploy_freeze_v13_10.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/releases/img/deploy_freeze_v14_3.png b/doc/user/project/releases/img/deploy_freeze_v14_3.png
new file mode 100644
index 00000000000..13580ac1576
--- /dev/null
+++ b/doc/user/project/releases/img/deploy_freeze_v14_3.png
Binary files differ
diff --git a/doc/user/project/releases/index.md b/doc/user/project/releases/index.md
index 76b300bdd57..49b5ec2ca60 100644
--- a/doc/user/project/releases/index.md
+++ b/doc/user/project/releases/index.md
@@ -186,7 +186,8 @@ To subscribe to notifications for releases:
## Prevent unintentional releases by setting a deploy freeze
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29382) in GitLab 13.0.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29382) in GitLab 13.0.
+> - The ability to delete freeze periods through the UI was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/212451) in GitLab 14.3.
Prevent unintended production releases during a period of time you specify by
setting a [*deploy freeze* period](../../../ci/environments/deployment_safety.md).
@@ -199,7 +200,7 @@ If the job that's executing is within a freeze period, GitLab CI/CD creates an e
variable named `$CI_DEPLOY_FREEZE`.
To prevent the deployment job from executing, create a `rules` entry in your
-`gitlab-ci.yml`, for example:
+`.gitlab-ci.yml`, for example:
```yaml
deploy_to_production:
@@ -219,11 +220,8 @@ To set a deploy freeze window in the UI, complete these steps:
1. Click **Add deploy freeze** to open the deploy freeze modal.
1. Enter the start time, end time, and timezone of the desired deploy freeze period.
1. Click **Add deploy freeze** in the modal.
-1. After the deploy freeze is saved, you can edit it by selecting the edit button (**{pencil}**).
- ![Deploy freeze modal for setting a deploy freeze period](img/deploy_freeze_v13_10.png)
-
-WARNING:
-To delete a deploy freeze, use the [Freeze Periods API](../../../api/freeze_periods.md).
+1. After the deploy freeze is saved, you can edit it by selecting the edit button (**{pencil}**) and remove it by selecting the delete button (**{remove}**).
+ ![Deploy freeze modal for setting a deploy freeze period](img/deploy_freeze_v14_3.png)
If a project contains multiple freeze periods, all periods apply. If they overlap, the freeze covers the
complete overlapping period.
@@ -394,9 +392,9 @@ upload:
- if: $CI_COMMIT_TAG
script:
- |
- curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file bin/${DARWIN_AMD64_BINARY} ${PACKAGE_REGISTRY_URL}/${DARWIN_AMD64_BINARY}
+ curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file bin/${DARWIN_AMD64_BINARY} "${PACKAGE_REGISTRY_URL}/${DARWIN_AMD64_BINARY}"
- |
- curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file bin/${LINUX_AMD64_BINARY} ${PACKAGE_REGISTRY_URL}/${LINUX_AMD64_BINARY}
+ curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file bin/${LINUX_AMD64_BINARY} "${PACKAGE_REGISTRY_URL}/${LINUX_AMD64_BINARY}"
release:
# Caution, as of 2021-02-02 these assets links require a login, see:
diff --git a/doc/user/project/repository/branches/default.md b/doc/user/project/repository/branches/default.md
index 12fd7389f21..a1ea929bb49 100644
--- a/doc/user/project/repository/branches/default.md
+++ b/doc/user/project/repository/branches/default.md
@@ -37,7 +37,7 @@ the [Git commands you need](#update-the-default-branch-name-in-your-repository)
To update the default branch name for an individual [project](../../index.md):
-1. Sign in to GitLab as a user with the [Administrator](../../../permissions.md) role.
+1. Sign in to GitLab with at least the [Maintainer](../../../permissions.md) role.
1. In the left navigation menu, go to **Settings > Repository**.
1. Expand **Default branch**, and select a new default branch.
1. (Optional) Select the **Auto-close referenced issues on default branch** checkbox to close
@@ -63,8 +63,8 @@ GitLab [administrators](../../../permissions.md) of self-managed instances can
customize the initial branch for projects hosted on that instance. Individual
groups and subgroups can override this instance-wide setting for their projects.
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > Repository**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Repository**.
1. Expand **Default initial branch name**.
1. Change the default initial branch to a custom name of your choice.
1. Select **Save changes**.
@@ -77,7 +77,7 @@ overrides it.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/221014) in GitLab 13.6.
-Administrators of groups and subgroups can configure the default branch name for a group:
+Users with at least the Owner role of groups and subgroups can configure the default branch name for a group:
1. Go to the group **Settings > Repository**.
1. Expand **Default initial branch name**.
@@ -128,8 +128,8 @@ renames a Git repository's (`example`) default branch.
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main
```
-1. Sign in to GitLab as an [administrator](../../../permissions.md) and follow
- the instructions to
+1. Sign in to GitLab with at least the [Maintainer](../../../permissions.md)
+ role and follow the instructions to
[change the default branch for this project](#change-the-default-branch-name-for-a-project).
Select `main` as your new default branch.
1. Protect your new `main` branch as described in the [protected branches documentation](../../protected_branches.md).
diff --git a/doc/user/project/repository/gpg_signed_commits/index.md b/doc/user/project/repository/gpg_signed_commits/index.md
index c41b3ed8615..23d7aecc960 100644
--- a/doc/user/project/repository/gpg_signed_commits/index.md
+++ b/doc/user/project/repository/gpg_signed_commits/index.md
@@ -19,6 +19,11 @@ NOTE:
The term GPG is used for all OpenPGP/PGP/GPG related material and
implementations.
+To view a user's public GPG key, you can:
+
+- Go to `https://gitlab.example.com/<username>.gpg`.
+- Select **View public GPG keys** (**{key}**) in the top right of the user's profile.
+
GPG verified tags are not supported yet.
See the [further reading](#further-reading) section for more details on GPG.
@@ -150,7 +155,7 @@ You can add a GPG key in your user settings:
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. In the left sidebar, select **GPG Keys**.
+1. On the left sidebar, select **GPG Keys**.
1. Paste your _public_ key in the **Key** text box.
![Paste GPG public key](img/profile_settings_gpg_keys_paste_pub.png)
@@ -248,7 +253,7 @@ To revoke a GPG key:
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. In the left sidebar, select **GPG Keys**.
+1. On the left sidebar, select **GPG Keys**.
1. Select **Revoke** next to the GPG key you want to delete.
## Removing a GPG key
@@ -262,7 +267,7 @@ To remove a GPG key from your account:
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. In the left sidebar, select **GPG Keys**.
+1. On the left sidebar, select **GPG Keys**.
1. Select the trash icon (**{remove}**) next to the GPG key you want to delete.
## Rejecting commits that are not signed **(PREMIUM)**
diff --git a/doc/user/project/repository/index.md b/doc/user/project/repository/index.md
index afdcf2a94fa..de7459e6278 100644
--- a/doc/user/project/repository/index.md
+++ b/doc/user/project/repository/index.md
@@ -34,7 +34,7 @@ You can [commit your changes](https://git-scm.com/book/en/v2/Git-Basics-Recordin
to a branch in the repository. When you use the command line, you can commit multiple times before you push.
- **Commit message:**
- A commit message identities what is being changed and why.
+ A commit message identifies what is being changed and why.
In GitLab, you can add keywords to the commit
message to perform one of the following actions:
- **Trigger a GitLab CI/CD pipeline:**
@@ -50,10 +50,10 @@ to a branch in the repository. When you use the command line, you can commit mul
on their respective thread.
- **Cherry-pick a commit:**
In GitLab, you can
- [cherry-pick a commit](../merge_requests/cherry_pick_changes.md#cherry-picking-a-commit)
+ [cherry-pick a commit](../merge_requests/cherry_pick_changes.md#cherry-pick-a-commit)
from the UI.
- **Revert a commit:**
- [Revert a commit](../merge_requests/revert_changes.md#reverting-a-commit)
+ [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).
diff --git a/doc/user/project/repository/repository_mirroring.md b/doc/user/project/repository/repository_mirroring.md
index 76eae58b431..5a02a35fce1 100644
--- a/doc/user/project/repository/repository_mirroring.md
+++ b/doc/user/project/repository/repository_mirroring.md
@@ -223,13 +223,15 @@ If a repository you're interested in is located on a different server, and you w
to browse its content and its activity using the GitLab interface, you can configure
mirror pulling:
-1. If you [configured two-factor authentication (2FA)](https://docs.github.com/en/github/authenticating-to-github/securing-your-account-with-two-factor-authentication-2fa)
- for GitHub, create a [personal access token for GitHub](https://docs.github.com/en/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token)
- with the `read_repository` scope. If 2FA is enabled, this personal access
+1. If your remote repository is on GitHub and you have
+ [two-factor authentication (2FA) configured](https://docs.github.com/en/github/authenticating-to-github/securing-your-account-with-two-factor-authentication-2fa),
+ create a [personal access token for GitHub](https://docs.github.com/en/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token).
+ with the `repo` scope. If 2FA is enabled, this personal access
token serves as your GitHub password.
1. In your project, go to **Settings > Repository**, and then expand the
**Mirroring repositories** section.
-1. In the **Git repository URL** field, enter a repository URL.
+1. In the **Git repository URL** field, enter a repository URL. Include the username
+ in the URL if required: `https://MYUSERNAME@github.com/group/PROJECTNAME.git`
1. In the **Mirror direction** dropdown, select **Pull**.
1. In the **Authentication method** dropdown, select your authentication method.
1. Select from the following checkboxes, if needed:
@@ -611,7 +613,7 @@ If you receive this error after creating a new project using
Check if the repository owner is specified in the URL of your mirrored repository:
1. Go to your project.
-1. In the left sidebar, select **Settings > Repository**.
+1. On the left sidebar, select **Settings > Repository**.
1. Select **Mirroring repositories**.
1. If no repository owner is specified, delete and add the URL again in this format:
diff --git a/doc/user/project/repository/x509_signed_commits/index.md b/doc/user/project/repository/x509_signed_commits/index.md
index 7c115734345..17031dd29af 100644
--- a/doc/user/project/repository/x509_signed_commits/index.md
+++ b/doc/user/project/repository/x509_signed_commits/index.md
@@ -5,72 +5,82 @@ info: "To determine the technical writer assigned to the Stage/Group associated
type: concepts, howto
---
-# Signing commits and tags with X.509 **(FREE)**
+# Sign commits and tags with X.509 certificates **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17773) in GitLab 12.8.
[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 SMIME, but Git also supports signing of commits and tags
-with X.509 certificates in a similar way as with [GPG](../gpg_signed_commits/index.md).
-The main difference is the trust anchor which is the PKI for X.509 certificates
-instead of a web of trust with GPG.
-
-## How GitLab handles X.509
-
-GitLab uses its own certificate store and therefore defines the trust chain.
-
+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#adding-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-chain-of-trust/).
For a commit or tag to be *verified* by GitLab:
-- The signing certificate email must match a verified email address used by the committer in GitLab.
-- The Certificate Authority has to be trusted by the GitLab instance, see also
- [Omnibus install custom public certificates](https://docs.gitlab.com/omnibus/settings/ssl.html#install-custom-public-certificates).
-- The signing time has to be within the time range of the [certificate validity](https://www.rfc-editor.org/rfc/rfc5280.html#section-4.1.2.5)
+- The signing certificate email must match a verified email address in GitLab.
+- The GitLab instance must be able to establish a full [trust chain](https://www.ssl.com/faqs/what-is-a-chain-of-trust/)
+ 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.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 or later than commit time.
-
-NOTE:
-Certificate revocation lists are checked on a daily basis via background worker.
+- The signing time is equal to, or later than, the commit time.
-NOTE:
-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://tools.ietf.org/html/rfc5280).
+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://tools.ietf.org/html/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 will not show as verified in GitLab, and
+ 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.
-## Obtaining an X.509 key pair
+## Configure for signed commits
-If your organization has Public Key Infrastructure (PKI), that PKI provides
-an S/MIME key.
+To sign your commits, tags, or both, you must:
-If you do not have an S/MIME key pair from a PKI, you can either create your
-own self-signed one, or purchase one. MozillaZine keeps a nice collection
-of [S/MIME-capable signing authorities](http://kb.mozillazine.org/Getting_an_SMIME_certificate)
-and some of them generate keys for free.
+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).
-## Associating your X.509 certificate with Git
+### Obtain an X.509 key pair
-To take advantage of X.509 signing, you need Git 2.19.0 or later. You can
-check your Git version with:
+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.
-```shell
-git --version
-```
+### 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.
@@ -84,71 +94,267 @@ git config --global user.signingkey $signingkey
git config --global gpg.format x509
```
-### Windows and MacOS
+#### Windows and macOS
-Install [S/MIME Sign](https://github.com/github/smimesign) by downloading the
-installer or via `brew install smimesign` on MacOS.
+To configure Windows or macOS:
-Get the ID of your certificate with `smimesign --list-keys` and set your
-signing key `git config --global user.signingkey ID`, then configure X.509:
+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`.
+1. Configure X.509 with this command:
-```shell
-git config --global gpg.x509.program smimesign
-git config --global gpg.format x509
-```
+ ```shell
+ git config --global gpg.x509.program smimesign
+ git config --global gpg.format x509
+ ```
-## Signing commits
+### Sign and verify commits
-After you have [associated your X.509 certificate with Git](#associating-your-x509-certificate-with-git) you
-can start signing your commits:
+After you have [associated your X.509 certificate with Git](#associate-your-x509-certificate-with-git) you
+can sign your commits:
-1. Commit like you used to, the only difference is the addition of the `-S` flag:
+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](#verifying-commits).
+1. Push to GitLab, and check that your commits are verified with the `--show-signature` flag:
-If you don't want to type the `-S` flag every time you commit, you can tell Git
-to sign your commits automatically:
-
-```shell
-git config --global commit.gpgsign true
-```
-
-## Verifying commits
+ ```shell
+ git log --show-signature
+ ```
-To verify that a commit is signed, you can use the `--show-signature` flag:
+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 log --show-signature
-```
+ ```shell
+ git config --global commit.gpgsign true
+ ```
-## Signing tags
+### Sign and verify tags
-After you have [associated your X.509 certificate with Git](#associating-your-x509-certificate-with-git) you
+After you have [associated your X.509 certificate with Git](#associate-your-x509-certificate-with-git) you
can start signing your tags:
-1. Tag like you used to, the only difference is the addition of the `-s` flag:
+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 check that your tags [are verified](#verifying-tags).
+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:
-If you don't want to type the `-s` flag every time you tag, you can tell Git
-to sign your tags automatically:
+ ```shell
+ git config --global tag.gpgsign true
+ ```
-```shell
-git config --global tag.gpgsign true
-```
+## Resources
-## Verifying tags
+- [Rake task for X.509 signatures](../../../../raketasks/x509_signatures.md)
-To verify that a tag is signed, you can use the `--verify` flag:
+## Troubleshooting
+
+### 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
-git tag --verify v1.1.1
+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 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 certificate(s) required to establish trust
+ [to the GitLab certificate store](https://docs.gitlab.com/omnibus/settings/ssl.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 certificate(s) 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/service_desk.md b/doc/user/project/service_desk.md
index d46e55ca005..fa5ef35418a 100644
--- a/doc/user/project/service_desk.md
+++ b/doc/user/project/service_desk.md
@@ -244,8 +244,8 @@ Graph API instead of IMAP. Follow the [documentation in the incoming email secti
gitlab_rails['service_desk_email_email'] = "project_contact@example.onmicrosoft.com"
gitlab_rails['service_desk_email_mailbox_name'] = "inbox"
gitlab_rails['service_desk_email_log_file'] = "/var/log/gitlab/mailroom/mail_room_json.log"
- gitlab_rails['service_desk_inbox_method'] = 'microsoft_graph'
- gitlab_rails['service_desk_inbox_options'] = {
+ gitlab_rails['service_desk_email_inbox_method'] = 'microsoft_graph'
+ gitlab_rails['service_desk_email_inbox_options'] = {
'tenant_id': '<YOUR-TENANT-ID>',
'client_id': '<YOUR-CLIENT-ID>',
'client_secret': '<YOUR-CLIENT-SECRET>',
diff --git a/doc/user/project/settings/import_export.md b/doc/user/project/settings/import_export.md
index 52e064ef66e..662d7e70910 100644
--- a/doc/user/project/settings/import_export.md
+++ b/doc/user/project/settings/import_export.md
@@ -45,6 +45,8 @@ Note the following:
a maintainer or administrator role in the group where the exported project lives.
- Project members with the [Owner role](../../permissions.md) are imported as Maintainers.
- Imported users can be mapped by their public email on self-managed instances, if an administrative user (not an owner) does the import.
+ Additionally, the user must be an existing member of the namespace, or the user can be added as a
+member of the project for contributions to be mapped.
Otherwise, a supplementary comment is left to mention that the original author and
the MRs, notes, or issues are owned by the importer.
- For project migration imports performed over GitLab.com Groups, preserving author information is
@@ -217,7 +219,7 @@ GitLab.com may have [different settings](../../gitlab_com/index.md#importexport)
## Troubleshooting
-### Import workaround for large repositories
+### Import workaround for large repositories
[Maximum import size limitations](#import-the-project)
can prevent an import from being successful.
@@ -225,7 +227,7 @@ If changing the import limits is not possible,
the following local workflow can be used to temporarily
reduce the repository size for another import attempt.
-1. Create a temporary working directory from the export:
+1. Create a temporary working directory from the export:
```shell
EXPORT=<filename-without-extension>
@@ -238,9 +240,11 @@ reduce the repository size for another import attempt.
# Prevent interference with recreating an importable file later
mv project.bundle ../"$EXPORT"-original.bundle
mv ../"$EXPORT".tar.gz ../"$EXPORT"-original.tar.gz
+
+ git switch --create smaller-tmp-main
```
-1. To reduce the repository size,
+1. To reduce the repository size, work on this `smaller-tmp-main` branch:
[identify and remove large files](../repository/reducing_the_repo_size_using_git.md)
or [interactively rebase and fixup](../../../topics/git/git_rebase.md#interactive-rebase)
to reduce the number of commits.
@@ -252,7 +256,7 @@ reduce the repository size for another import attempt.
git gc --prune=now --aggressive
# Prepare recreating an importable file
- git bundle create ../project.bundle <default-branch-name>
+ git bundle create ../project.bundle smaller-tmp-main
cd ..
mv project/ ../"$EXPORT"-project
cd ..
@@ -268,5 +272,5 @@ reduce the repository size for another import attempt.
1. Update the imported repository's
[branch protection rules](../protected_branches.md) and
its [default branch](../repository/branches/default.md), and
- delete the temporary, `smaller-…` branch, and
+ delete the temporary, `smaller-tmp-main` branch, and
the local, temporary data.
diff --git a/doc/user/project/settings/index.md b/doc/user/project/settings/index.md
index 66fdace81ba..8b159a75451 100644
--- a/doc/user/project/settings/index.md
+++ b/doc/user/project/settings/index.md
@@ -87,59 +87,64 @@ Example `.compliance-gitlab-ci.yml`
# Allows compliance team to control the ordering and interweaving of stages/jobs.
# Stages without jobs defined will remain hidden.
stages:
-- pre-compliance
-- build
-- test
-- pre-deploy-compliance
-- deploy
-- post-compliance
-
-variables: # can be overriden by a developer's local .gitlab-ci.yml
+ - pre-compliance
+ - build
+ - test
+ - pre-deploy-compliance
+ - deploy
+ - post-compliance
+
+variables: # Can be overridden by setting a job-specific variable in project's local .gitlab-ci.yml
FOO: sast
-sast: # none of these attributes can be overriden by a developer's local .gitlab-ci.yml
+sast: # None of these attributes can be overridden by a project's local .gitlab-ci.yml
variables:
FOO: sast
image: ruby:2.6
stage: pre-compliance
rules:
- - when: always
+ - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
+ when: never
+ - when: always # or when: on_success
allow_failure: false
before_script:
- - "# No before scripts."
+ - "# No before scripts."
script:
- - echo "running $FOO"
+ - echo "running $FOO"
after_script:
- - "# No after scripts."
+ - "# No after scripts."
sanity check:
image: ruby:2.6
stage: pre-deploy-compliance
rules:
- - when: always
+ - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
+ when: never
+ - when: always # or when: on_success
allow_failure: false
before_script:
- - "# No before scripts."
+ - "# No before scripts."
script:
- - echo "running $FOO"
+ - echo "running $FOO"
after_script:
- - "# No after scripts."
-
+ - "# No after scripts."
audit trail:
image: ruby:2.6
stage: post-compliance
rules:
- - when: always
+ - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
+ when: never
+ - when: always # or when: on_success
allow_failure: false
before_script:
- - "# No before scripts."
+ - "# No before scripts."
script:
- - echo "running $FOO"
+ - echo "running $FOO"
after_script:
- - "# No after scripts."
+ - "# No after scripts."
-include: # Execute individual project's configuration
+include: # Execute individual project's configuration (if project contains .gitlab-ci.yml)
project: '$CI_PROJECT_PATH'
file: '$CI_CONFIG_PATH'
ref: '$CI_COMMIT_REF_NAME' # Must be defined or MR pipelines always use the use default branch.
@@ -174,7 +179,7 @@ cannot change them:
- Explicitly set the container image file to run the job in. This ensures that your script
steps execute in the correct environment.
- Explicitly set any relevant GitLab pre-defined [job keywords](../../../ci/yaml/index.md#job-keywords).
- This ensures that your job uses the settings you intend and that they are not overriden by
+ This ensures that your job uses the settings you intend and that they are not overridden by
project-level pipelines.
### Sharing and permissions
@@ -187,33 +192,34 @@ section.
You can now change the [Project visibility](../../../public_access/public_access.md).
If you set **Project Visibility** to public, you can limit access to some features
to **Only Project Members**. In addition, you can select the option to
-[Allow users to request access](../members/index.md#prevent-users-from-requesting-access-to-a-project).
+[Allow users to request access](../members/index.md#request-access-to-a-project).
Use the switches to enable or disable the following features:
-| Option | More access limit options | Description |
-|:----------------------------------|:--------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| **Issues** | ✓ | Activates the GitLab issues tracker |
-| **Repository** | ✓ | Enables [repository](../repository/) functionality |
-| **Merge Requests** | ✓ | Enables [merge request](../merge_requests/) functionality; also see [Merge request settings](#merge-request-settings) |
-| **Forks** | ✓ | Enables [forking](../repository/forking_workflow.md) functionality |
-| **Pipelines** | ✓ | Enables [CI/CD](../../../ci/index.md) functionality |
-| **Container Registry** | | Activates a [registry](../../packages/container_registry/) for your Docker images |
-| **Git Large File Storage** | | Enables the use of [large files](../../../topics/git/lfs/index.md#git-large-file-storage-lfs) |
-| **Packages** | | Supports configuration of a [package registry](../../../administration/packages/index.md#gitlab-package-registry-administration) functionality |
-| **Analytics** | ✓ | Enables [analytics](../../analytics/) |
-| **Wiki** | ✓ | Enables a separate system for [documentation](../wiki/) |
-| **Snippets** | ✓ | Enables [sharing of code and text](../../snippets.md) |
-| **Pages** | ✓ | Allows you to [publish static websites](../pages/) |
-| **Metrics Dashboard** | ✓ | Control access to [metrics dashboard](../integrations/prometheus.md)
-| **Requirements** | ✓ | Control access to [Requirements Management](../requirements/index.md) |
-| **Operations Dashboard** | ✓ | Control access to [operations dashboard](../../../operations/index.md)
+| Option | More access limit options | Description |
+|:---------------------------------|:--------------------------|:--------------|
+| **Issues** | ✓ | Activates the GitLab issues tracker. |
+| **Repository** | ✓ | Enables [repository](../repository/) functionality |
+| **Merge Requests** | ✓ | Enables [merge request](../merge_requests/) functionality; also see [Merge request settings](#merge-request-settings). |
+| **Forks** | ✓ | Enables [forking](../repository/forking_workflow.md) functionality. |
+| **Git Large File Storage (LFS)** | | Enables the use of [large files](../../../topics/git/lfs/index.md#git-large-file-storage-lfs). |
+| **Packages** | | Supports configuration of a [package registry](../../../administration/packages/index.md#gitlab-package-registry-administration) functionality. |
+| **CI/CD** | ✓ | Enables [CI/CD](../../../ci/index.md) functionality. |
+| **Container Registry** | | Activates a [registry](../../packages/container_registry/) for your Docker images. |
+| **Analytics** | ✓ | Enables [analytics](../../analytics/). |
+| **Requirements** | ✓ | Control access to [Requirements Management](../requirements/index.md). |
+| **Security & Compliance** | ✓ | Control access to [security features](../../application_security/index.md). |
+| **Wiki** | ✓ | Enables a separate system for [documentation](../wiki/). |
+| **Snippets** | ✓ | Enables [sharing of code and text](../../snippets.md). |
+| **Pages** | ✓ | Allows you to [publish static websites](../pages/). |
+| **Operations** | ✓ | Control access to [operations dashboard](../../../operations/index.md). |
+| **Metrics Dashboard** | ✓ | Control access to [metrics dashboard](../integrations/prometheus.md). |
Some features depend on others:
- If you disable the **Issues** option, GitLab also removes the following
features:
- - **Issue Boards**
+ - **issue boards**
- [**Service Desk**](#service-desk)
NOTE:
@@ -227,7 +233,7 @@ Some features depend on others:
- If you disable **Repository** functionality, GitLab also disables the following
features for your project:
- **Merge Requests**
- - **Pipelines**
+ - **CI/CD**
- **Container Registry**
- **Git Large File Storage**
- **Packages**
@@ -247,7 +253,7 @@ setting **Enable CVE ID requests in the issue sidebar**.
#### Disabling email notifications
-Project owners can disable all [email notifications](../../profile/notifications.md#gitlab-notification-emails)
+Project owners can disable all [email notifications](../../profile/notifications.md)
related to the project by selecting the **Disable email notifications** checkbox.
### Merge request settings
@@ -350,7 +356,7 @@ to transfer a project.
You can transfer an existing project into a [group](../../group/index.md) if:
-- You have at least the Maintainer** role in that group.
+- You have at least **Maintainer** [role](../../permissions.md#project-members-permissions) in that group.
- You're at least an **Owner** of the project to be transferred.
- The group to which the project is being transferred to must allow creation of new projects.
@@ -457,7 +463,7 @@ To do so:
1. Confirm the action by typing the project's path as instructed.
NOTE:
-Only project Owners have the [permissions](../../permissions.md#project-members-permissions)
+Only project owners have the [permissions](../../permissions.md#project-members-permissions)
to remove a fork relationship.
## Monitor settings
diff --git a/doc/user/project/settings/project_access_tokens.md b/doc/user/project/settings/project_access_tokens.md
index 643042cb96a..cae9276eafd 100644
--- a/doc/user/project/settings/project_access_tokens.md
+++ b/doc/user/project/settings/project_access_tokens.md
@@ -7,25 +7,30 @@ type: reference, howto
# Project access tokens
-NOTE:
-Project access tokens are supported for self-managed instances on Free and above. They are also supported on GitLab SaaS Premium and above (excluding [trial licenses](https://about.gitlab.com/free-trial/)). Self-managed Free instances should review their security and compliance policies with regards to [user self-enrollment](../../admin_area/settings/sign_up_restrictions.md#disable-new-sign-ups) and consider [disabling project access tokens](#enable-or-disable-project-access-token-creation) to lower potential abuse.
-
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/210181) in GitLab 13.0.
> - [Became available on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/235765) in GitLab 13.5 for paid groups only.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/235765) in GitLab 13.5.
-WARNING:
-This feature might not be available to you. Check the **version history** note above for details.
+Project access tokens are similar to [personal access tokens](../../profile/personal_access_tokens.md)
+except they are attached to a project rather than a user. They can be used to:
+
+- Authenticate with the [GitLab API](../../../api/index.md#personalproject-access-tokens).
+- Authenticate with Git using HTTP Basic Authentication. If you are asked for a username when
+ authenticating, you can use any non-empty value because only the token is needed.
-Project access tokens are scoped to a project and can be used to authenticate with the
-[GitLab API](../../../api/index.md#personalproject-access-tokens). You can also use
-project access tokens with Git to authenticate over HTTPS. If you are asked for a
-username when authenticating over HTTPS, you can use any non-empty value because only
-the token is needed.
+Project access tokens:
-Project access tokens expire on the date you define, at midnight UTC.
+- Expire on the date you define, at midnight UTC.
+- Are supported for self-managed instances on Free tier and above. Free self-managed instances
+ should:
+ - Review their security and compliance policies with regards to
+ [user self-enrollment](../../admin_area/settings/sign_up_restrictions.md#disable-new-sign-ups).
+ - Consider [disabling project access tokens](#enable-or-disable-project-access-token-creation) to
+ lower potential abuse.
+- Are also supported on GitLab SaaS Premium and above (excluding [trial licenses](https://about.gitlab.com/free-trial/).)
-For examples of how you can use a project access token to authenticate with the API, see the following section from our [API Docs](../../../api/index.md#personalproject-access-tokens).
+For examples of how you can use a project access token to authenticate with the API, see the
+[relevant section from our API Docs](../../../api/index.md#personalproject-access-tokens).
## Creating a project access token
@@ -60,10 +65,7 @@ API calls made with a project access token are associated with the corresponding
These bot users are included in a project's **Project information > Members** list but cannot be modified. Also, a bot
user cannot be added to any other project.
-- The username is set to `project_{project_id}_bot` for the first access token, such as `project_123_bot`.
-- The username is set to `project_{project_id}_bot{bot_count}` for further access tokens, such as `project_123_bot1`.
-
-When the project access token is [revoked](#revoking-a-project-access-token) the bot user is deleted
+When the project access token is [revoked](#revoking-a-project-access-token), the bot user is deleted
and all records are moved to a system-wide user with the username "Ghost User". For more
information, see [Associated Records](../../profile/account/delete_account.md#associated-records).
diff --git a/doc/user/project/time_tracking.md b/doc/user/project/time_tracking.md
index 2b901ddc17b..8902bdc21c4 100644
--- a/doc/user/project/time_tracking.md
+++ b/doc/user/project/time_tracking.md
@@ -115,7 +115,7 @@ In GitLab self-managed instances, you can limit the display of time units to
hours.
To do so:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Preferences**.
1. Expand **Localization**.
1. Under **Time tracking**, select the **Limit display of time tracking units to hours** checkbox.
diff --git a/doc/user/project/web_ide/img/open_web_ide.png b/doc/user/project/web_ide/img/open_web_ide.png
deleted file mode 100644
index 02a5a564472..00000000000
--- a/doc/user/project/web_ide/img/open_web_ide.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/web_ide/index.md b/doc/user/project/web_ide/index.md
index 160c2314ded..010a63b7957 100644
--- a/doc/user/project/web_ide/index.md
+++ b/doc/user/project/web_ide/index.md
@@ -16,9 +16,22 @@ projects by providing an advanced editor with commit staging.
## Open the Web IDE
You can open the Web IDE when viewing a file, from the repository file list,
-and from merge requests.
-
-![Open Web IDE](img/open_web_ide.png)
+and from merge requests:
+
+- *When viewing a file, or the repository file list* -
+ 1. In the upper right corner of the page, select **Edit in Web IDE** if it is visible.
+ 1. If **Edit in Web IDE** is not visible:
+ 1. Select the **(angle-down)** next to **Edit** or **Gitpod**, depending on your configuration.
+ 1. Select **Edit in Web IDE** from the list to display it as the editing option.
+ 1. Select **Edit in Web IDE** to open the editor.
+- *When viewing a merge request* -
+ 1. Go to your merge request, and select the **Overview** tab.
+ 1. Scroll to the widgets area, after the merge request description.
+ 1. Select **Edit in Web IDE** if it is visible.
+ 1. If **Edit in Web IDE** is not visible:
+ 1. Select the **(angle-down)** next to **Open in Gitpod**.
+ 1. Select **Open in Web IDE** from the list to display it as the editing option.
+ 1. Select **Open in Web IDE** to open the editor.
## File finder
@@ -249,7 +262,7 @@ The image is uploaded to the same directory and is named `image.png` by default.
If another file already exists with the same name, a numeric suffix is automatically
added to the filename.
-There are two ways to preview Markdown content in the Web IDE:
+There are two ways to preview Markdown content in the Web IDE:
1. At the top of the file's tab, select **Preview Markdown** to preview the formatting
in your file. You can't edit the file in this view.
@@ -280,8 +293,8 @@ a `main` entry point inside the Web IDE.
Live Preview is enabled for all projects on GitLab.com. If you are an administrator
of a self-managed GitLab instance, and you want to enable Live Preview:
-1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. In the left sidebar, select **Settings > General**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
1. Scroll to **Web IDE** and select **Expand**:
![Administrator Live Preview setting](img/admin_live_preview_v13_0.png)
1. Select **Enable Live Preview** and select **Save changes**.
diff --git a/doc/user/project/wiki/index.md b/doc/user/project/wiki/index.md
index 0507b6b78ca..d0a1f485fa8 100644
--- a/doc/user/project/wiki/index.md
+++ b/doc/user/project/wiki/index.md
@@ -46,13 +46,17 @@ for previously created wikis.
## Create the wiki home page
-When a wiki is created, it is empty. On your first visit, create the landing page
-users see when viewing the wiki:
+When a wiki is created, it is empty. On your first visit, you can create the
+home page users see when viewing the wiki. This page requires a specific title
+to be used as your wiki's home page. To create it:
1. Go to your project or group and select **Wiki**.
1. Select **Create your first page**.
+1. GitLab requires this first page be titled `home`. The page with this
+ title serves as the front page for your wiki.
1. Select a **Format** for styling your text.
-1. Add a welcome message in the **Content** section. You can always edit it later.
+1. Add a welcome message for your home page in the **Content** section. You can
+ always edit it later.
1. Add a **Commit message**. Git requires a commit message, so GitLab creates one
if you don't enter one yourself.
1. Select **Create page**.
@@ -105,7 +109,7 @@ Wiki pages are stored as files in a Git repository, so certain characters have a
### Length restrictions for file and directory names
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/24364) in GitLab 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/24364) in GitLab 12.8.
Many common file systems have a [limit of 255 bytes](https://en.wikipedia.org/wiki/Comparison_of_file_systems#Limits)
for file and directory names. Git and GitLab both support paths exceeding
@@ -123,7 +127,7 @@ may not be able to check out the wiki locally afterward.
## Edit a wiki page
-You need the [Developer role](../../permissions.md) or higher to edit a wiki page:
+You need at least the [Developer role](../../permissions.md) to edit a wiki page:
1. Go to your project or group and select **Wiki**.
1. Go to the page you want to edit.
@@ -138,7 +142,7 @@ For an example, read [Table of contents](../../markdown.md#table-of-contents).
## Delete a wiki page
-You need the [Maintainer role](../../permissions.md) or higher to delete a wiki page:
+You need at least the [Maintainer role](../../permissions.md) to delete a wiki page:
1. Go to your project or group and select **Wiki**.
1. Go to the page you want to delete.
@@ -148,7 +152,7 @@ You need the [Maintainer role](../../permissions.md) or higher to delete a wiki
## Move a wiki page
-You need the [Developer role](../../permissions.md) or higher to move a wiki page:
+You need at least the [Developer role](../../permissions.md) to move a wiki page:
1. Go to your project or group and select **Wiki**.
1. Go to the page you want to move.
@@ -175,7 +179,7 @@ From the history page you can see:
### View changes between page versions
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15242) in GitLab 13.2.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15242) in GitLab 13.2.
You can see the changes made in a version of a wiki page, similar to versioned diff file views:
@@ -201,9 +205,9 @@ Commits to wikis are not counted in [repository analytics](../../analytics/repos
## Customize sidebar
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23109) in GitLab 13.8, the sidebar can be customized by selecting the **Edit sidebar** button.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23109) in GitLab 13.8, the sidebar can be customized by selecting the **Edit sidebar** button.
-You need Developer [permissions](../../permissions.md) or higher to customize the wiki
+You need at least the [Developer role](../../permissions.md) to customize the wiki
navigation sidebar. This process creates a wiki page named `_sidebar` which fully
replaces the default sidebar navigation:
@@ -238,7 +242,7 @@ Administrators for self-managed GitLab installs can
## Group wikis **(PREMIUM)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13195) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13195) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.5.
Group wikis work the same way as project wikis. Their usage is similar to project
wikis, with a few limitations:
@@ -306,7 +310,7 @@ to disable the wiki but toggle it on (in blue).
## Content Editor **(FREE)**
-> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5643) in GitLab 14.0.
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5643) in GitLab 14.0.
GitLab version 14.0 introduces a WYSIWYG editing experience for GitLab Flavored Markdown
in Wikis through the [Content Editor](../../../development/fe_guide/content_editor.md).
diff --git a/doc/user/project/working_with_projects.md b/doc/user/project/working_with_projects.md
index 77dd44e5c7f..32bb202767a 100644
--- a/doc/user/project/working_with_projects.md
+++ b/doc/user/project/working_with_projects.md
@@ -334,6 +334,52 @@ git config --global url."https://${user}:${personal_access_token}@gitlab.example
git config --global url."git@gitlab.example.com".insteadOf "https://gitlab.example.com"
```
+### Fetch Go modules from Geo secondary sites
+
+As Go modules are stored in Git repositories, you can use the [Geo](../../administration/geo/index.md)
+feature that allows Git repositories to be accessed on the secondary Geo servers.
+
+In the following examples, the primary's site domain name is `gitlab.example.com`,
+and the secondary's is `gitlab-secondary.example.com`.
+
+`go get` will initially generate some HTTP traffic to the primary, but when the module
+download commences, the `insteadOf` configuration sends the traffic to the secondary.
+
+#### Use SSH to access the Geo secondary
+
+To fetch Go modules from the secondary using SSH:
+
+1. Reconfigure Git on the client to send traffic for the primary to the secondary:
+
+ ```plaintext
+ git config --global url."git@gitlab-secondary.example.com".insteadOf "https://gitlab.example.com"
+ git config --global url."git@gitlab-secondary.example.com".insteadOf "http://gitlab.example.com"
+ ```
+
+1. Ensure the client is set up for SSH access to GitLab repositories. This can be tested on the primary,
+ and GitLab will replicate the public key to the secondary.
+
+#### Use HTTP to access the Geo secondary
+
+Using HTTP to fetch Go modules does not work with CI/CD job tokens, only with
+persistent access tokens that are replicated to the secondary.
+
+To fetch Go modules from the secondary using HTTP:
+
+1. Put in place a Git `insteadOf` redirect on the client:
+
+ ```plaintext
+ git config --global url."https://gitlab-secondary.example.com".insteadOf "https://gitlab.example.com"
+ ```
+
+1. Generate a [personal access token](../profile/personal_access_tokens.md) and
+ provide those credentials in the client's `~/.netrc` file:
+
+ ```plaintext
+ machine gitlab.example.com login USERNAME password TOKEN
+ machine gitlab-secondary.example.com login USERNAME password TOKEN
+ ```
+
## Access project page with project ID
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53671) in GitLab 11.8.
diff --git a/doc/user/search/advanced_search.md b/doc/user/search/advanced_search.md
index f29ac531d2e..f994539b9fc 100644
--- a/doc/user/search/advanced_search.md
+++ b/doc/user/search/advanced_search.md
@@ -119,3 +119,24 @@ You can search a specific issue or merge request by its ID with a special prefix
- To search by issue ID, use prefix `#` followed by issue ID. For example, [#23456](https://gitlab.com/search?snippets=&scope=issues&repository_ref=&search=%2323456&group_id=9970&project_id=278964)
- To search by merge request ID, use prefix `!` followed by merge request ID. For example [!23456](https://gitlab.com/search?snippets=&scope=merge_requests&repository_ref=&search=%2123456&group_id=9970&project_id=278964)
+
+## Global search scopes **(FREE SELF)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68640) in GitLab 14.3.
+
+To improve the performance of your instance's global search, you can limit
+the scope of the search. To do so, you can exclude global search scopes by disabling
+[`ops` feature flags](../../development/feature_flags/index.md#ops-type).
+
+Global search has all its scopes **enabled** by default in GitLab SaaS and
+self-managed instances. A GitLab administrator can disable the following `ops`
+feature flags to limit the scope of your instance's global search and optimize
+its performance:
+
+| Scope | Feature flag | Description |
+|--|--|--|
+| Code | `global_search_code_tab` | When enabled, the global search includes code as part of the search. |
+| Commits | `global_search_commits_tab` | When enabled, the global search includes commits as part of the search. |
+| Issues | `global_search_issues_tab` | When enabled, the global search includes issues as part of the search. |
+| Merge Requests | `global_search_merge_requests_tab` | When enabled, the global search includes merge requests as part of the search. |
+| Wiki | `global_search_wiki_tab` | When enabled, the global search includes wiki as part of the search. |
diff --git a/doc/user/search/index.md b/doc/user/search/index.md
index 92d01e6a43e..7cf62f09303 100644
--- a/doc/user/search/index.md
+++ b/doc/user/search/index.md
@@ -27,8 +27,8 @@ When you click **Issues**, GitLab shows the opened issues assigned to you:
You can search through **Open**, **Closed**, or **All** issues.
-You can also filter the results using the search and filter field, as described below in
-[Filtering issue and merge request lists](#filtering-issue-and-merge-request-lists).
+You can also filter the results using the search and filter field, as described in
+[Filter issue and merge request lists](#filter-issue-and-merge-request-lists).
### Issues and MRs assigned to you or created by you
@@ -37,11 +37,11 @@ in the search field in the upper right corner:
![shortcut to your issues and merge requests](img/issues_mrs_shortcut.png)
-### Filtering issue and merge request lists
+### Filter issue and merge request lists
-> - Filtering by Epics was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/195704) in GitLab Ultimate 12.9.
-> - Filtering by child Epics was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9029) in GitLab Ultimate 13.0.
-> - Filtering by Iterations was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6. Moved to GitLab Premium in 13.9.
+> - Filter by Epics was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/195704) in GitLab Ultimate 12.9.
+> - Filter by child Epics was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9029) in GitLab Ultimate 13.0.
+> - Filter by Iterations was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6. Moved to GitLab Premium in 13.9.
Follow these steps to filter the **Issues** and **Merge Requests** list pages in projects and
groups:
@@ -64,12 +64,13 @@ groups:
- `!=`: Is not ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18059) in GitLab 12.7)
1. Enter the text to [filter the attribute by](#filters-autocomplete).
1. Repeat this process to filter by multiple attributes. Multiple attributes are joined by a logical
- `AND`.
+ `AND`. For example, filtering by an Author and Milestone `!=` 12.6 filters for the issues where the
+ author matches your selection, and the milestone is not 12.6:
-For example, filtering by Author `=` Jane and Milestone `!=` 12.6 filters for the issues where Jane
-is the author and the milestone is not 12.6.
+ ![filter issues in a project](img/issue_search_filter_v12_7.png)
-![filter issues in a project](img/issue_search_filter_v12_7.png)
+GitLab displays the results on-screen, but you can also
+[retrieve them as an RSS feed](#retrieve-search-results-as-feed).
### Filtering by **None** / **Any**
@@ -96,6 +97,21 @@ You can filter issues and merge requests by specific terms included in titles or
![filter issues by specific terms](img/issue_search_by_term.png)
+### Retrieve search results as feed
+
+> Feeds for merge requests were [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66336) in GitLab 14.3.
+
+GitLab provides RSS feeds of search results for your project. To subscribe to the
+RSS feed of search results:
+
+1. Go to your project's page.
+1. On the left sidebar, select **Issues** or **Merge requests**.
+1. Build your search query as described in [Filter issue and merge request lists](#filter-issue-and-merge-request-lists).
+1. Select the feed symbol **{rss}** to display the results as an RSS feed in Atom format.
+
+The URL of the result contains both a feed token, and your search query.
+You can add this URL to your feed reader.
+
### Filtering by ID
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/39908) in GitLab 12.1.
@@ -217,12 +233,12 @@ filters them for you as you type.
You can also **Explore** all public and internal groups available in GitLab.com,
and sort them by **Last created**, **Oldest created**, **Last updated**, or **Oldest updated**.
-## Issue Boards
+## Issue boards
-From an [Issue Board](../../user/project/issue_board.md), you can filter issues by **Author**, **Assignee**, **Milestone**, and **Labels**.
+From an [issue board](../../user/project/issue_board.md), you can filter issues by **Author**, **Assignee**, **Milestone**, and **Labels**.
You can also filter them by name (issue title), from the field **Filter by name**, which is loaded as you type.
-To search for issues to add to lists present in your Issue Board, click
+To search for issues to add to lists present in your issue board, click
the button **Add issues** on the top-right of your screen, opening a modal window from which
you can, besides filtering them by **Name**, **Author**, **Assignee**, **Milestone**,
and **Labels**, select multiple issues to add to a list of your choice:
diff --git a/doc/user/workspace/img/hardware_settings.png b/doc/user/workspace/img/hardware_settings.png
index ff460918f25..919ff46f8c8 100644
--- a/doc/user/workspace/img/hardware_settings.png
+++ b/doc/user/workspace/img/hardware_settings.png
Binary files differ
diff --git a/doc/user/workspace/index.md b/doc/user/workspace/index.md
index d9c9d19721b..2ce30c645d5 100644
--- a/doc/user/workspace/index.md
+++ b/doc/user/workspace/index.md
@@ -1,25 +1,25 @@
---
stage: Manage
-group: Access
+group: Workspace
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
---
# Workspace
-Workspace will be the top [namespace](../group/index.md#namespaces) for you to manage
-everything GitLab, including:
+Workspace will be above the [top-level namespaces](../group/index.md#namespaces) for you to manage everything you can do as a GitLab administrator, including:
- Defining and applying settings to all of your groups, subgroups, and projects.
- Aggregating data from all your groups, subgroups, and projects.
-Workspace will take many of the features from the
-[Admin Area](../admin_area/index.md) and will:
+The functionality in the [Admin Area](../admin_area/index.md) of self-managed installations will be split up and go to:
-- Enable a top namespace for GitLab.com.
-- Eventually replace the instance level for self-managed installations.
+1. Groups (available in the Workspace, Top-level group namespaces, and Sub-groups)
+1. Hardware Controls (for functionality that does not apply to groups)
-Our goal is to reach feature parity between SaaS and self-managed installations, with one
-exception: **Hardware Controls** will appear **only** on self-managed installations.
+Our goal is to reach feature parity between SaaS and Self-Managed installations, with all [Admin Area settings](/ee/user/admin_area/settings/) moving to either:
+
+- Workspace (contains features relevant to both GitLab-managed and self-managed installations) with a dedicated Settings menu available within the left navigation bar.
+- Hardware controls (only contains features relative to Self-Managed installations, with one per installation).
NOTE:
Workspace is currently in development.
diff --git a/generator_templates/active_record/migration/migration.rb b/generator_templates/active_record/migration/migration.rb
index dddd6e247d4..103c2fd7ea2 100644
--- a/generator_templates/active_record/migration/migration.rb
+++ b/generator_templates/active_record/migration/migration.rb
@@ -3,10 +3,7 @@
# See https://docs.gitlab.com/ee/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
-class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
- # Uncomment the following include if you require helper functions:
- # include Gitlab::Database::MigrationHelpers
-
+class <%= migration_class_name %> < Gitlab::Database::Migration[<%= Gitlab::Database::Migration.current_version %>]
# When using the methods "add_concurrent_index" or "remove_concurrent_index"
# you must disable the use of transactions
# as these methods can not run in an existing transaction.
diff --git a/generator_templates/post_deployment_migration/post_deployment_migration/migration.rb b/generator_templates/post_deployment_migration/post_deployment_migration/migration.rb
index 689d1de9d17..c456fa29ea8 100644
--- a/generator_templates/post_deployment_migration/post_deployment_migration/migration.rb
+++ b/generator_templates/post_deployment_migration/post_deployment_migration/migration.rb
@@ -3,10 +3,7 @@
# See https://docs.gitlab.com/ee/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
-class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
- # Uncomment the following include if you require helper functions:
- # include Gitlab::Database::MigrationHelpers
-
+class <%= migration_class_name %> < Gitlab::Database::Migration[<%= Gitlab::Database::Migration.current_version %>]
# When using the methods "add_concurrent_index" or "remove_concurrent_index"
# you must disable the use of transactions
# as these methods can not run in an existing transaction.
@@ -20,6 +17,9 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
# comments:
# disable_ddl_transaction!
- def change
+ def up
+ end
+
+ def down
end
end
diff --git a/generator_templates/usage_metric_definition/metric_definition.yml b/generator_templates/usage_metric_definition/metric_definition.yml
index 1d84214d924..9ce03bdb7b4 100644
--- a/generator_templates/usage_metric_definition/metric_definition.yml
+++ b/generator_templates/usage_metric_definition/metric_definition.yml
@@ -6,7 +6,7 @@ product_stage:
product_group:
product_category:
value_type: <%= value_type %>
-status: implemented
+status: active
milestone: "<%= milestone %>"
introduced_by_url:
time_frame: <%= time_frame %>
diff --git a/jest.config.base.js b/jest.config.base.js
index 997f3c254b4..3ace87c49bc 100644
--- a/jest.config.base.js
+++ b/jest.config.base.js
@@ -1,10 +1,12 @@
const IS_EE = require('./config/helpers/is_ee_env');
const isESLint = require('./config/helpers/is_eslint');
+const IS_JH = require('./config/helpers/is_jh_env');
module.exports = (path, options = {}) => {
const {
moduleNameMapper: extModuleNameMapper = {},
moduleNameMapperEE: extModuleNameMapperEE = {},
+ moduleNameMapperJH: extModuleNameMapperJH = {},
} = options;
const reporters = ['default'];
@@ -29,6 +31,9 @@ module.exports = (path, options = {}) => {
testMatch.push(`<rootDir>/ee/${glob}`);
}
+ if (IS_JH) {
+ testMatch.push(`<rootDir>/jh/${glob}`);
+ }
// workaround for eslint-import-resolver-jest only resolving in test files
// see https://github.com/JoinColony/eslint-import-resolver-jest#note
if (isESLint(module)) {
@@ -41,8 +46,11 @@ module.exports = (path, options = {}) => {
'^~(/.*)$': '<rootDir>/app/assets/javascripts$1',
'^ee_component(/.*)$':
'<rootDir>/app/assets/javascripts/vue_shared/components/empty_component.js',
+ '^jh_component(/.*)$':
+ '<rootDir>/app/assets/javascripts/vue_shared/components/empty_component.js',
'^shared_queries(/.*)$': '<rootDir>/app/graphql/queries$1',
'^ee_else_ce(/.*)$': '<rootDir>/app/assets/javascripts$1',
+ '^jh_else_ce(/.*)$': '<rootDir>/app/assets/javascripts$1',
'^helpers(/.*)$': '<rootDir>/spec/frontend/__helpers__$1',
'^vendor(/.*)$': '<rootDir>/vendor/assets/javascripts$1',
[TEST_FIXTURES_PATTERN]: '<rootDir>/tmp/tests/frontend/fixtures$1',
@@ -70,6 +78,19 @@ module.exports = (path, options = {}) => {
collectCoverageFrom.push(rootDirEE.replace('$1', '/**/*.{js,vue}'));
}
+ if (IS_JH) {
+ const rootDirJH = '<rootDir>/jh/app/assets/javascripts$1';
+ Object.assign(moduleNameMapper, {
+ '^jh(/.*)$': rootDirJH,
+ '^jh_component(/.*)$': rootDirJH,
+ '^jh_else_ce(/.*)$': rootDirJH,
+ '^jh_jest/(.*)$': '<rootDir>/jh/spec/frontend/$1',
+ ...extModuleNameMapperJH,
+ });
+
+ collectCoverageFrom.push(rootDirJH.replace('$1', '/**/*.{js,vue}'));
+ }
+
const coverageDirectory = () => {
if (process.env.CI_NODE_INDEX && process.env.CI_NODE_TOTAL) {
return `<rootDir>/coverage-frontend/jest-${process.env.CI_NODE_INDEX}-${process.env.CI_NODE_TOTAL}`;
@@ -107,6 +128,7 @@ module.exports = (path, options = {}) => {
testEnvironment: '<rootDir>/spec/frontend/environment.js',
testEnvironmentOptions: {
IS_EE,
+ IS_JH,
},
};
};
diff --git a/jest.config.integration.js b/jest.config.integration.js
index 92296fb751e..da8e813a2cb 100644
--- a/jest.config.integration.js
+++ b/jest.config.integration.js
@@ -8,9 +8,13 @@ module.exports = {
moduleNameMapper: {
'^test_helpers(/.*)$': '<rootDir>/spec/frontend_integration/test_helpers$1',
'^ee_else_ce_test_helpers(/.*)$': '<rootDir>/spec/frontend_integration/test_helpers$1',
+ '^jh_else_ce_test_helpers(/.*)$': '<rootDir>/spec/frontend_integration/test_helpers$1',
},
moduleNameMapperEE: {
'^ee_else_ce_test_helpers(/.*)$': '<rootDir>/ee/spec/frontend_integration/test_helpers$1',
},
+ moduleNameMapperJH: {
+ '^jh_else_ce_test_helpers(/.*)$': '<rootDir>/jh/spec/frontend_integration/test_helpers$1',
+ },
}),
};
diff --git a/jest.config.js b/jest.config.js
index cfc8e254791..4d9e19abbaf 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -3,15 +3,3 @@ const baseConfig = require('./jest.config.base');
module.exports = {
...baseConfig('spec/frontend'),
};
-
-const karmaTestFile = process.argv.find((arg) => arg.includes('spec/javascripts/'));
-if (karmaTestFile) {
- console.error(`
-Files in spec/javascripts/ and ee/spec/javascripts need to be run with Karma.
-Please use the following command instead:
-
-yarn karma -f ${karmaTestFile}
-
-`);
- process.exit(1);
-}
diff --git a/lib/api/admin/sidekiq.rb b/lib/api/admin/sidekiq.rb
index d91d4a0d4d5..05eb7f8222b 100644
--- a/lib/api/admin/sidekiq.rb
+++ b/lib/api/admin/sidekiq.rb
@@ -12,11 +12,11 @@ module API
namespace 'queues' do
desc 'Drop jobs matching the given metadata from the Sidekiq queue'
params do
- Gitlab::ApplicationContext::KNOWN_KEYS.each do |key|
+ Gitlab::SidekiqQueue::ALLOWED_KEYS.each do |key|
optional key, type: String, allow_blank: false
end
- at_least_one_of(*Gitlab::ApplicationContext::KNOWN_KEYS)
+ at_least_one_of(*Gitlab::SidekiqQueue::ALLOWED_KEYS)
end
delete ':queue_name' do
result =
diff --git a/lib/api/api.rb b/lib/api/api.rb
index 40f1b2fa9d3..d0d96858f61 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -171,6 +171,7 @@ module API
mount ::API::Deployments
mount ::API::Environments
mount ::API::ErrorTracking
+ mount ::API::ErrorTrackingClientKeys
mount ::API::ErrorTrackingCollector
mount ::API::Events
mount ::API::FeatureFlags
diff --git a/lib/api/ci/pipelines.rb b/lib/api/ci/pipelines.rb
index 4d6d38f2dce..03b59e7e6ad 100644
--- a/lib/api/ci/pipelines.rb
+++ b/lib/api/ci/pipelines.rb
@@ -7,8 +7,6 @@ module API
before { authenticate_non_get! }
- feature_category :continuous_integration
-
params do
requires :id, type: String, desc: 'The project ID'
end
@@ -44,7 +42,6 @@ module API
optional :ref, type: String, desc: 'The ref of pipelines'
optional :sha, type: String, desc: 'The sha of pipelines'
optional :yaml_errors, type: Boolean, desc: 'Returns pipelines with invalid configurations'
- optional :name, type: String, desc: '(deprecated) The name of the user who triggered pipelines'
optional :username, type: String, desc: 'The username of the user who triggered pipelines'
optional :updated_before, type: DateTime, desc: 'Return pipelines updated before the specified datetime. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ'
optional :updated_after, type: DateTime, desc: 'Return pipelines updated after the specified datetime. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ'
@@ -54,7 +51,7 @@ module API
desc: 'Sort pipelines'
optional :source, type: String, values: ::Ci::Pipeline.sources.keys
end
- get ':id/pipelines' do
+ get ':id/pipelines', feature_category: :continuous_integration do
authorize! :read_pipeline, user_project
authorize! :read_build, user_project
@@ -70,7 +67,7 @@ module API
requires :ref, type: String, desc: 'Reference'
optional :variables, Array, desc: 'Array of variables available in the pipeline'
end
- post ':id/pipeline' do
+ post ':id/pipeline', feature_category: :continuous_integration do
Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/20711')
authorize! :create_pipeline, user_project
@@ -97,7 +94,7 @@ module API
params do
optional :ref, type: String, desc: 'branch ref of pipeline'
end
- get ':id/pipelines/latest' do
+ get ':id/pipelines/latest', feature_category: :continuous_integration do
authorize! :read_pipeline, latest_pipeline
present latest_pipeline, with: Entities::Ci::Pipeline
@@ -110,7 +107,7 @@ module API
params do
requires :pipeline_id, type: Integer, desc: 'The pipeline ID'
end
- get ':id/pipelines/:pipeline_id' do
+ get ':id/pipelines/:pipeline_id', feature_category: :continuous_integration do
authorize! :read_pipeline, pipeline
present pipeline, with: Entities::Ci::Pipeline
@@ -126,7 +123,7 @@ module API
use :pagination
end
- get ':id/pipelines/:pipeline_id/jobs' do
+ get ':id/pipelines/:pipeline_id/jobs', feature_category: :continuous_integration do
authorize!(:read_pipeline, user_project)
pipeline = user_project.all_pipelines.find(params[:pipeline_id])
@@ -149,7 +146,7 @@ module API
use :pagination
end
- get ':id/pipelines/:pipeline_id/bridges' do
+ get ':id/pipelines/:pipeline_id/bridges', feature_category: :pipeline_authoring do
authorize!(:read_build, user_project)
pipeline = user_project.all_pipelines.find(params[:pipeline_id])
@@ -169,7 +166,7 @@ module API
params do
requires :pipeline_id, type: Integer, desc: 'The pipeline ID'
end
- get ':id/pipelines/:pipeline_id/variables' do
+ get ':id/pipelines/:pipeline_id/variables', feature_category: :pipeline_authoring do
authorize! :read_pipeline_variable, pipeline
present pipeline.variables, with: Entities::Ci::Variable
@@ -182,7 +179,7 @@ module API
params do
requires :pipeline_id, type: Integer, desc: 'The pipeline ID'
end
- get ':id/pipelines/:pipeline_id/test_report' do
+ get ':id/pipelines/:pipeline_id/test_report', feature_category: :code_testing do
authorize! :read_build, pipeline
present pipeline.test_reports, with: TestReportEntity, details: true
@@ -195,7 +192,7 @@ module API
params do
requires :pipeline_id, type: Integer, desc: 'The pipeline ID'
end
- get ':id/pipelines/:pipeline_id/test_report_summary' do
+ get ':id/pipelines/:pipeline_id/test_report_summary', feature_category: :code_testing do
authorize! :read_build, pipeline
present pipeline.test_report_summary, with: TestReportSummaryEntity
@@ -208,7 +205,7 @@ module API
params do
requires :pipeline_id, type: Integer, desc: 'The pipeline ID'
end
- delete ':id/pipelines/:pipeline_id' do
+ delete ':id/pipelines/:pipeline_id', feature_category: :continuous_integration do
authorize! :destroy_pipeline, pipeline
destroy_conditionally!(pipeline) do
@@ -223,7 +220,7 @@ module API
params do
requires :pipeline_id, type: Integer, desc: 'The pipeline ID'
end
- post ':id/pipelines/:pipeline_id/retry' do
+ post ':id/pipelines/:pipeline_id/retry', feature_category: :continuous_integration do
authorize! :update_pipeline, pipeline
pipeline.retry_failed(current_user)
@@ -238,7 +235,7 @@ module API
params do
requires :pipeline_id, type: Integer, desc: 'The pipeline ID'
end
- post ':id/pipelines/:pipeline_id/cancel' do
+ post ':id/pipelines/:pipeline_id/cancel', feature_category: :continuous_integration do
authorize! :update_pipeline, pipeline
pipeline.cancel_running
diff --git a/lib/api/ci/runners.rb b/lib/api/ci/runners.rb
index 7f755b1a4d4..93a40925c21 100644
--- a/lib/api/ci/runners.rb
+++ b/lib/api/ci/runners.rb
@@ -222,6 +222,56 @@ module API
end
end
+ resource :runners do
+ before { authenticate_non_get! }
+
+ desc 'Resets runner registration token' do
+ success Entities::Ci::ResetRegistrationTokenResult
+ end
+ post 'reset_registration_token' do
+ authorize! :update_runners_registration_token
+
+ ApplicationSetting.current.reset_runners_registration_token!
+ present ApplicationSetting.current_without_cache.runners_registration_token, with: Entities::Ci::ResetRegistrationTokenResult
+ end
+ end
+
+ params do
+ requires :id, type: String, desc: 'The ID of a project'
+ end
+ resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
+ before { authenticate_non_get! }
+
+ desc 'Resets runner registration token' do
+ success Entities::Ci::ResetRegistrationTokenResult
+ end
+ post ':id/runners/reset_registration_token' do
+ project = find_project! user_project.id
+ authorize! :update_runners_registration_token, project
+
+ project.reset_runners_token!
+ present project.runners_token, with: Entities::Ci::ResetRegistrationTokenResult
+ end
+ end
+
+ params do
+ requires :id, type: String, desc: 'The ID of a group'
+ end
+ resource :groups, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
+ before { authenticate_non_get! }
+
+ desc 'Resets runner registration token' do
+ success Entities::Ci::ResetRegistrationTokenResult
+ end
+ post ':id/runners/reset_registration_token' do
+ group = find_group! user_group.id
+ authorize! :update_runners_registration_token, group
+
+ group.reset_runners_token!
+ present group.runners_token, with: Entities::Ci::ResetRegistrationTokenResult
+ end
+ end
+
helpers do
def filter_runners(runners, scope, allowed_scopes: ::Ci::Runner::AVAILABLE_SCOPES)
return runners unless scope.present?
diff --git a/lib/api/commits.rb b/lib/api/commits.rb
index 5d8985455ad..10dc51556b9 100644
--- a/lib/api/commits.rb
+++ b/lib/api/commits.rb
@@ -336,7 +336,7 @@ module API
lines = Gitlab::Diff::Parser.new.parse(diff.diff.each_line)
lines.each do |line|
- next unless line.new_pos == params[:line] && line.type == params[:line_type]
+ next unless line.line == params[:line] && line.type == params[:line_type]
break opts[:line_code] = Gitlab::Git.diff_line_code(diff.new_path, line.new_pos, line.old_pos)
end
diff --git a/lib/api/dependency_proxy.rb b/lib/api/dependency_proxy.rb
index 3379bb2f029..185b8d5a15d 100644
--- a/lib/api/dependency_proxy.rb
+++ b/lib/api/dependency_proxy.rb
@@ -15,7 +15,7 @@ module API
end
end
- before do
+ after_validation do
authorize! :admin_group, user_group
end
@@ -35,6 +35,8 @@ module API
# rubocop:disable CodeReuse/Worker
PurgeDependencyProxyCacheWorker.perform_async(current_user.id, user_group.id)
# rubocop:enable CodeReuse/Worker
+
+ status :accepted
end
end
end
diff --git a/lib/api/entities/application_setting.rb b/lib/api/entities/application_setting.rb
index f23fce40468..465c5f4112b 100644
--- a/lib/api/entities/application_setting.rb
+++ b/lib/api/entities/application_setting.rb
@@ -27,6 +27,14 @@ module API
expose(*::ApplicationSettingsHelper.external_authorization_service_attributes)
+ # Also expose these columns under their new attribute names.
+ #
+ # TODO: Once we rename the columns, we have to swap this around and keep supporting the old names until v5.
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/340031
+ expose :throttle_unauthenticated_enabled, as: :throttle_unauthenticated_web_enabled
+ expose :throttle_unauthenticated_period_in_seconds, as: :throttle_unauthenticated_web_period_in_seconds
+ expose :throttle_unauthenticated_requests_per_period, as: :throttle_unauthenticated_web_requests_per_period
+
# support legacy names, can be removed in v5
expose :password_authentication_enabled_for_web, as: :password_authentication_enabled
expose :password_authentication_enabled_for_web, as: :signin_enabled
diff --git a/lib/api/entities/basic_project_details.rb b/lib/api/entities/basic_project_details.rb
index 0b231906ccd..5c33af86b84 100644
--- a/lib/api/entities/basic_project_details.rb
+++ b/lib/api/entities/basic_project_details.rb
@@ -43,12 +43,20 @@ module API
# N+1 is solved then by using `subject.topics.map(&:name)`
# MR describing the solution: https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/20555
projects_relation.preload(:project_feature, :route)
- .preload(:import_state, :topics)
+ .preload(:import_state, :topics, :topics_acts_as_taggable)
.preload(:auto_devops)
.preload(namespace: [:route, :owner])
end
# rubocop: enable CodeReuse/ActiveRecord
+ def self.execute_batch_counting(projects_relation)
+ # Call the count methods on every project, so the BatchLoader would load them all at
+ # once when the entities are rendered
+ projects_relation.each(&:forks_count)
+
+ super
+ end
+
private
alias_method :project, :object
diff --git a/lib/api/entities/blob.rb b/lib/api/entities/blob.rb
index b14ef127b68..12700d99865 100644
--- a/lib/api/entities/blob.rb
+++ b/lib/api/entities/blob.rb
@@ -10,7 +10,7 @@ module API
# in the future we can only return the filename here without the leading
# directory path.
# https://gitlab.com/gitlab-org/gitlab/issues/34521
- expose :filename, &:path
+ expose :path, as: :filename
expose :id
expose :ref
expose :startline
diff --git a/lib/api/entities/ci/pipeline_basic.rb b/lib/api/entities/ci/pipeline_basic.rb
index 8086062dc9b..4d56176bdb3 100644
--- a/lib/api/entities/ci/pipeline_basic.rb
+++ b/lib/api/entities/ci/pipeline_basic.rb
@@ -4,11 +4,9 @@ module API
module Entities
module Ci
class PipelineBasic < Grape::Entity
- expose :id, :project_id, :sha, :ref, :status
+ expose :id, :project_id, :sha, :ref, :status, :source
expose :created_at, :updated_at
- expose :source, if: ->(pipeline, options) { ::Feature.enabled?(:pipeline_source_filter, options[:project], default_enabled: :yaml) }
-
expose :web_url do |pipeline, _options|
Gitlab::Routing.url_helpers.project_pipeline_url(pipeline.project, pipeline)
end
diff --git a/lib/api/entities/ci/reset_registration_token_result.rb b/lib/api/entities/ci/reset_registration_token_result.rb
new file mode 100644
index 00000000000..23426432f68
--- /dev/null
+++ b/lib/api/entities/ci/reset_registration_token_result.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module API
+ module Entities
+ module Ci
+ class ResetRegistrationTokenResult < Grape::Entity
+ expose(:token) {|object| object}
+ end
+ end
+ end
+end
diff --git a/lib/api/entities/clusters/agent_authorization.rb b/lib/api/entities/clusters/agent_authorization.rb
new file mode 100644
index 00000000000..6c533fff105
--- /dev/null
+++ b/lib/api/entities/clusters/agent_authorization.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module API
+ module Entities
+ module Clusters
+ class AgentAuthorization < Grape::Entity
+ expose :agent_id, as: :id
+ expose :project, with: Entities::ProjectIdentity, as: :config_project
+ expose :config, as: :configuration
+ end
+ end
+ end
+end
diff --git a/lib/api/entities/commit_note.rb b/lib/api/entities/commit_note.rb
index d08b6fc8225..fe91712b48d 100644
--- a/lib/api/entities/commit_note.rb
+++ b/lib/api/entities/commit_note.rb
@@ -5,7 +5,7 @@ module API
class CommitNote < Grape::Entity
expose :note
expose(:path) { |note| note.diff_file.try(:file_path) if note.diff_note? }
- expose(:line) { |note| note.diff_line.try(:new_line) if note.diff_note? }
+ expose(:line) { |note| note.diff_line.try(:line) if note.diff_note? }
expose(:line_type) { |note| note.diff_line.try(:type) if note.diff_note? }
expose :author, using: Entities::UserBasic
expose :created_at
diff --git a/lib/api/entities/compare.rb b/lib/api/entities/compare.rb
index fe2f03db2af..75a36d9bb01 100644
--- a/lib/api/entities/compare.rb
+++ b/lib/api/entities/compare.rb
@@ -20,6 +20,10 @@ module API
end
expose :same, as: :compare_same_ref
+
+ expose :web_url do |compare, _|
+ Gitlab::UrlBuilder.build(compare)
+ end
end
end
end
diff --git a/lib/api/entities/error_tracking.rb b/lib/api/entities/error_tracking.rb
index a38e00ca295..b55cba05ea0 100644
--- a/lib/api/entities/error_tracking.rb
+++ b/lib/api/entities/error_tracking.rb
@@ -10,6 +10,13 @@ module API
expose :api_url
expose :integrated
end
+
+ class ClientKey < Grape::Entity
+ expose :id
+ expose :active
+ expose :public_key
+ expose :sentry_dsn
+ end
end
end
end
diff --git a/lib/api/entities/global_notification_setting.rb b/lib/api/entities/global_notification_setting.rb
index f3ca64347f0..f35efad5d01 100644
--- a/lib/api/entities/global_notification_setting.rb
+++ b/lib/api/entities/global_notification_setting.rb
@@ -4,7 +4,7 @@ module API
module Entities
class GlobalNotificationSetting < Entities::NotificationSetting
expose :notification_email do |notification_setting, options|
- notification_setting.user.notification_email
+ notification_setting.user.notification_email_or_default
end
end
end
diff --git a/lib/api/entities/project.rb b/lib/api/entities/project.rb
index 890b42ed8c8..b0e53ac3794 100644
--- a/lib/api/entities/project.rb
+++ b/lib/api/entities/project.rb
@@ -126,6 +126,10 @@ module API
expose :keep_latest_artifacts_available?, as: :keep_latest_artifact
# rubocop: disable CodeReuse/ActiveRecord
+ def self.preload_resource(project)
+ ActiveRecord::Associations::Preloader.new.preload(project, project_group_links: { group: :route })
+ end
+
def self.preload_relation(projects_relation, options = {})
# Preloading topics, should be done with using only `:topics`,
# as `:topics` are defined as: `has_many :topics, through: :taggings`
@@ -140,12 +144,21 @@ module API
.preload(project_group_links: { group: :route },
fork_network: :root_project,
fork_network_member: :forked_from_project,
- forked_from_project: [:route, :topics, :group, :project_feature, namespace: [:route, :owner]])
+ forked_from_project: [:route, :topics, :topics_acts_as_taggable, :group, :project_feature, namespace: [:route, :owner]])
end
# rubocop: enable CodeReuse/ActiveRecord
- def self.forks_counting_projects(projects_relation)
- projects_relation + projects_relation.map(&:forked_from_project).compact
+ def self.execute_batch_counting(projects_relation)
+ # Call the count methods on every project, so the BatchLoader would load them all at
+ # once when the entities are rendered
+ projects_relation.each(&:open_issues_count)
+ projects_relation.map(&:forked_from_project).compact.each(&:forks_count)
+
+ super
+ end
+
+ def self.repositories_for_preload(projects_relation)
+ super + projects_relation.map(&:forked_from_project).compact.map(&:repository)
end
end
end
diff --git a/lib/api/entities/user.rb b/lib/api/entities/user.rb
index 973e80dd5ef..5c46233a639 100644
--- a/lib/api/entities/user.rb
+++ b/lib/api/entities/user.rb
@@ -4,8 +4,10 @@ module API
module Entities
class User < UserBasic
include UsersHelper
+ include ActionView::Helpers::SanitizeHelper
+
expose :created_at, if: ->(user, opts) { Ability.allowed?(opts[:current_user], :read_user_profile, user) }
- expose :bio, :bio_html, :location, :public_email, :skype, :linkedin, :twitter, :website_url, :organization, :job_title, :pronouns
+ expose :bio, :location, :public_email, :skype, :linkedin, :twitter, :website_url, :organization, :job_title, :pronouns
expose :bot?, as: :bot
expose :work_information do |user|
work_information(user)
@@ -16,6 +18,12 @@ module API
expose :following, if: ->(user, opts) { Ability.allowed?(opts[:current_user], :read_user_profile, user) } do |user|
user.followees.size
end
+
+ # This is only for multi version compatibility reasons, as we removed user.bio_html
+ # to be removed in 14.4
+ expose :bio_html do |user|
+ strip_tags(user.bio)
+ end
end
end
end
diff --git a/lib/api/entities/user_public.rb b/lib/api/entities/user_public.rb
index 78f088d3c1a..5d0e464abe1 100644
--- a/lib/api/entities/user_public.rb
+++ b/lib/api/entities/user_public.rb
@@ -14,7 +14,7 @@ module API
expose :two_factor_enabled?, as: :two_factor_enabled
expose :external
expose :private_profile
- expose :commit_email
+ expose :commit_email_or_default, as: :commit_email
end
end
end
diff --git a/lib/api/environments.rb b/lib/api/environments.rb
index e50da4264b5..c032b80e39b 100644
--- a/lib/api/environments.rb
+++ b/lib/api/environments.rb
@@ -58,7 +58,8 @@ module API
end
params do
requires :environment_id, type: Integer, desc: 'The environment ID'
- optional :name, type: String, desc: 'The new environment name'
+ # TODO: disallow renaming via the API https://gitlab.com/gitlab-org/gitlab/-/issues/338897
+ optional :name, type: String, desc: 'DEPRECATED: Renaming environment can lead to errors, this will be removed in 15.0'
optional :external_url, type: String, desc: 'The new URL on which this deployment is viewable'
optional :slug, absence: { message: "is automatically generated and cannot be changed" }
end
diff --git a/lib/api/error_tracking.rb b/lib/api/error_tracking.rb
index 3abf2831bd3..369efe3bf8c 100644
--- a/lib/api/error_tracking.rb
+++ b/lib/api/error_tracking.rb
@@ -6,24 +6,30 @@ module API
feature_category :error_tracking
+ helpers do
+ def project_setting
+ @project_setting ||= user_project.error_tracking_setting
+ end
+ end
+
params do
requires :id, type: String, desc: 'The ID of a project'
end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
+ before do
+ authorize! :admin_operations, user_project
+
+ not_found!('Error Tracking Setting') unless project_setting
+ end
+
desc 'Get error tracking settings for the project' do
detail 'This feature was introduced in GitLab 12.7.'
success Entities::ErrorTracking::ProjectSetting
end
get ':id/error_tracking/settings' do
- authorize! :admin_operations, user_project
-
- setting = user_project.error_tracking_setting
-
- not_found!('Error Tracking Setting') unless setting
-
- present setting, with: Entities::ErrorTracking::ProjectSetting
+ present project_setting, with: Entities::ErrorTracking::ProjectSetting
end
desc 'Enable or disable error tracking settings for the project' do
@@ -36,12 +42,6 @@ module API
end
patch ':id/error_tracking/settings/' do
- authorize! :admin_operations, user_project
-
- setting = user_project.error_tracking_setting
-
- not_found!('Error Tracking Setting') unless setting
-
update_params = {
error_tracking_setting_attributes: { enabled: params[:active] }
}
@@ -53,7 +53,7 @@ module API
result = ::Projects::Operations::UpdateService.new(user_project, current_user, update_params).execute
if result[:status] == :success
- present setting, with: Entities::ErrorTracking::ProjectSetting
+ present project_setting, with: Entities::ErrorTracking::ProjectSetting
else
result
end
diff --git a/lib/api/error_tracking_client_keys.rb b/lib/api/error_tracking_client_keys.rb
new file mode 100644
index 00000000000..eaa84b7186c
--- /dev/null
+++ b/lib/api/error_tracking_client_keys.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+module API
+ class ErrorTrackingClientKeys < ::API::Base
+ before { authenticate! }
+
+ feature_category :error_tracking
+
+ params do
+ requires :id, type: String, desc: 'The ID of a project'
+ end
+
+ resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
+ segment ':id/error_tracking' do
+ before do
+ authorize! :admin_operations, user_project
+ end
+
+ desc 'List all client keys' do
+ detail 'This feature was introduced in GitLab 14.3.'
+ success Entities::ErrorTracking::ClientKey
+ end
+ get '/client_keys' do
+ collection = user_project.error_tracking_client_keys
+
+ present paginate(collection), with: Entities::ErrorTracking::ClientKey
+ end
+
+ desc 'Create a client key' do
+ detail 'This feature was introduced in GitLab 14.3.'
+ success Entities::ErrorTracking::ClientKey
+ end
+ post '/client_keys' do
+ key = user_project.error_tracking_client_keys.create!
+
+ present key, with: Entities::ErrorTracking::ClientKey
+ end
+
+ desc 'Delete a client key' do
+ detail 'This feature was introduced in GitLab 14.3.'
+ success Entities::ErrorTracking::ClientKey
+ end
+ delete '/client_keys/:key_id' do
+ key = user_project.error_tracking_client_keys.find(params[:key_id])
+ key.destroy!
+ end
+ end
+ end
+ end
+end
diff --git a/lib/api/error_tracking_collector.rb b/lib/api/error_tracking_collector.rb
index 13e8e476808..b1e0f6a858a 100644
--- a/lib/api/error_tracking_collector.rb
+++ b/lib/api/error_tracking_collector.rb
@@ -8,6 +8,8 @@ module API
feature_category :error_tracking
content_type :envelope, 'application/x-sentry-envelope'
+ content_type :json, 'application/json'
+ content_type :txt, 'text/plain'
default_format :envelope
before do
@@ -33,17 +35,24 @@ module API
end
def active_client_key?
+ public_key = extract_public_key
+
+ find_client_key(public_key)
+ end
+
+ def extract_public_key
+ # Some SDK send public_key as a param. In this case we don't need to parse headers.
+ return params[:sentry_key] if params[:sentry_key].present?
+
begin
- public_key = ::ErrorTracking::Collector::SentryAuthParser.parse(request)[:public_key]
+ ::ErrorTracking::Collector::SentryAuthParser.parse(request)[:public_key]
rescue StandardError
bad_request!('Failed to parse sentry request')
end
-
- find_client_key(public_key)
end
end
- desc 'Submit error tracking event to the project' do
+ desc 'Submit error tracking event to the project as envelope' do
detail 'This feature was introduced in GitLab 14.1.'
end
params do
@@ -89,5 +98,38 @@ module API
# it is safe only for submission of new events.
no_content!
end
+
+ desc 'Submit error tracking event to the project' do
+ detail 'This feature was introduced in GitLab 14.1.'
+ end
+ params do
+ requires :id, type: String, desc: 'The ID of a project'
+ end
+ post 'error_tracking/collector/api/:id/store' do
+ # There is a reason why we have such uncommon path.
+ # We depend on a client side error tracking software which
+ # modifies URL for its own reasons.
+ #
+ # When we give user a URL like this
+ # HOST/api/v4/error_tracking/collector/123
+ #
+ # Then error tracking software will convert it like this:
+ # HOST/api/v4/error_tracking/collector/api/123/store/
+
+ begin
+ parsed_body = Gitlab::Json.parse(request.body.read)
+ rescue StandardError
+ bad_request!('Failed to parse sentry request')
+ end
+
+ ::ErrorTracking::CollectErrorService
+ .new(project, nil, event: parsed_body)
+ .execute
+
+ # Collector should never return any information back.
+ # Because DSN and public key are designed for public use,
+ # it is safe only for submission of new events.
+ no_content!
+ end
end
end
diff --git a/lib/api/feature_flags.rb b/lib/api/feature_flags.rb
index fb5858bc10b..c1f958ac007 100644
--- a/lib/api/feature_flags.rb
+++ b/lib/api/feature_flags.rb
@@ -118,7 +118,7 @@ module API
put do
authorize_update_feature_flag!
exclude_legacy_flags_check!
- render_api_error!('PUT operations are not supported for legacy feature flags', :unprocessable_entity) if feature_flag.legacy_flag?
+ render_api_error!('PUT operations are not supported for legacy feature flags', :unprocessable_entity) unless feature_flag.new_version_flag?
attrs = declared_params(include_missing: false)
@@ -207,7 +207,7 @@ module API
end
def exclude_legacy_flags_check!
- if feature_flag.legacy_flag?
+ unless feature_flag.new_version_flag?
not_found!
end
end
diff --git a/lib/api/files.rb b/lib/api/files.rb
index f3de7fbe96b..9d2b7cce837 100644
--- a/lib/api/files.rb
+++ b/lib/api/files.rb
@@ -35,10 +35,9 @@ module API
not_found!('Commit') unless @commit
@repo = user_project.repository
- @blob = @repo.blob_at(@commit.sha, params[:file_path])
+ @blob = @repo.blob_at(@commit.sha, params[:file_path], limit: Gitlab::Git::Blob::LFS_POINTER_MAX_SIZE)
not_found!('File') unless @blob
- @blob.load_all_data!
end
def commit_response(attrs)
@@ -48,13 +47,21 @@ module API
}
end
+ def content_sha
+ Rails.cache.fetch("blob_content_sha256:#{user_project.full_path}:#{@blob.id}") do
+ @blob.load_all_data!
+
+ Digest::SHA256.hexdigest(@blob.data)
+ end
+ end
+
def blob_data
{
file_name: @blob.name,
file_path: @blob.path,
size: @blob.size,
encoding: "base64",
- content_sha256: Digest::SHA256.hexdigest(@blob.data),
+ content_sha256: content_sha,
ref: params[:ref],
blob_id: @blob.id,
commit_id: @commit.id,
@@ -154,6 +161,8 @@ module API
get ":id/repository/files/:file_path", requirements: FILE_ENDPOINT_REQUIREMENTS do
assign_file_vars!
+ @blob.load_all_data!
+
data = blob_data
set_http_headers(data)
diff --git a/lib/api/generic_packages.rb b/lib/api/generic_packages.rb
index a57d6bbcd2a..5e184d35255 100644
--- a/lib/api/generic_packages.rb
+++ b/lib/api/generic_packages.rb
@@ -62,7 +62,7 @@ module API
authorize_upload!(project)
bad_request!('File is too large') if max_file_size_exceeded?
- ::Gitlab::Tracking.event(self.options[:for].name, 'push_package', user: current_user, project: project, namespace: project.namespace)
+ track_package_event('push_package', :generic, project: project, user: current_user, namespace: project.namespace)
create_package_file_params = declared_params.merge(build: current_authenticated_job)
::Packages::Generic::CreatePackageFileService
@@ -96,7 +96,7 @@ module API
package = ::Packages::Generic::PackageFinder.new(project).execute!(params[:package_name], params[:package_version])
package_file = ::Packages::PackageFileFinder.new(package, params[:file_name]).execute!
- ::Gitlab::Tracking.event(self.options[:for].name, 'pull_package', user: current_user, project: project, namespace: project.namespace)
+ track_package_event('pull_package', :generic, project: project, user: current_user, namespace: project.namespace)
present_carrierwave_file!(package_file.file)
end
diff --git a/lib/api/group_variables.rb b/lib/api/group_variables.rb
index 13daf05fc78..e726f9b61cc 100644
--- a/lib/api/group_variables.rb
+++ b/lib/api/group_variables.rb
@@ -6,7 +6,7 @@ module API
before { authenticate! }
before { authorize! :admin_group, user_group }
- feature_category :continuous_integration
+ feature_category :pipeline_authoring
helpers ::API::Helpers::VariablesHelpers
diff --git a/lib/api/groups.rb b/lib/api/groups.rb
index 0896357cc73..a1123b6291b 100644
--- a/lib/api/groups.rb
+++ b/lib/api/groups.rb
@@ -108,6 +108,20 @@ module API
present paginate(groups), options
end
+ def present_groups_with_pagination_strategies(params, groups)
+ return present_groups(params, groups) if current_user.present? || Feature.disabled?(:keyset_pagination_for_groups_api)
+
+ options = {
+ with: Entities::Group,
+ current_user: nil,
+ statistics: false
+ }
+
+ groups, options = with_custom_attributes(groups, options)
+
+ present paginate_with_strategies(groups), options
+ end
+
def delete_group(group)
destroy_conditionally!(group) do |group|
::Groups::DestroyService.new(group, current_user).async_execute
@@ -168,7 +182,7 @@ module API
end
get do
groups = find_groups(declared_params(include_missing: false), params[:id])
- present_groups params, groups
+ present_groups_with_pagination_strategies params, groups
end
desc 'Create a group. Available only for users who can create groups.' do
diff --git a/lib/api/helm_packages.rb b/lib/api/helm_packages.rb
index 4280744d8b4..8a7e84c9f87 100644
--- a/lib/api/helm_packages.rb
+++ b/lib/api/helm_packages.rb
@@ -44,15 +44,10 @@ module API
get ":channel/index.yaml" do
authorize_read_package!(authorized_user_project)
- package_files = Packages::Helm::PackageFilesFinder.new(
- authorized_user_project,
- params[:channel],
- order_by: 'created_at',
- sort: 'desc'
- ).execute
+ packages = Packages::Helm::PackagesFinder.new(authorized_user_project, params[:channel]).execute
env['api.format'] = :yaml
- present ::Packages::Helm::IndexPresenter.new(authorized_user_project, params[:id], package_files),
+ present ::Packages::Helm::IndexPresenter.new(params[:id], params[:channel], packages),
with: ::API::Entities::Helm::Index
end
@@ -66,7 +61,7 @@ module API
get ":channel/charts/:file_name.tgz", requirements: FILE_NAME_REQUIREMENTS do
authorize_read_package!(authorized_user_project)
- package_file = Packages::Helm::PackageFilesFinder.new(authorized_user_project, params[:channel], file_name: "#{params[:file_name]}.tgz").execute.last!
+ package_file = Packages::Helm::PackageFilesFinder.new(authorized_user_project, params[:channel], file_name: "#{params[:file_name]}.tgz").most_recent!
track_package_event('pull_package', :helm, project: authorized_user_project, namespace: authorized_user_project.namespace)
diff --git a/lib/api/helpers/issues_helpers.rb b/lib/api/helpers/issues_helpers.rb
index b1954f8ece9..185a10a250c 100644
--- a/lib/api/helpers/issues_helpers.rb
+++ b/lib/api/helpers/issues_helpers.rb
@@ -34,7 +34,17 @@ module API
end
def self.sort_options
- %w[created_at updated_at priority due_date relative_position label_priority milestone_due popularity]
+ %w[
+ created_at
+ due_date
+ label_priority
+ milestone_due
+ popularity
+ priority
+ relative_position
+ title
+ updated_at
+ ]
end
def issue_finder(args = {})
@@ -43,9 +53,11 @@ module API
args.delete(:id)
args[:not] ||= {}
args[:milestone_title] ||= args.delete(:milestone)
- args[:not][:milestone_title] ||= args[:not]&.delete(:milestone)
+ args[:milestone_wildcard_id] ||= args.delete(:milestone_id)
+ args[:not][:milestone_title] ||= args[:not].delete(:milestone)
+ args[:not][:milestone_wildcard_id] ||= args[:not].delete(:milestone_id)
args[:label_name] ||= args.delete(:labels)
- args[:not][:label_name] ||= args[:not]&.delete(:labels)
+ args[:not][:label_name] ||= args[:not].delete(:labels)
args[:scope] = args[:scope].underscore if args[:scope]
args[:sort] = "#{args[:order_by]}_#{args[:sort]}"
args[:issue_types] ||= args.delete(:issue_type)
diff --git a/lib/api/helpers/members_helpers.rb b/lib/api/helpers/members_helpers.rb
index e72bbb931f0..1e89f9f97a2 100644
--- a/lib/api/helpers/members_helpers.rb
+++ b/lib/api/helpers/members_helpers.rb
@@ -50,24 +50,48 @@ module API
GroupMembersFinder.new(group).execute
end
- def create_member(current_user, user, source, params)
- source.add_user(user, params[:access_level], current_user: current_user, expires_at: params[:expires_at])
+ def present_members(members)
+ present members, with: Entities::Member, current_user: current_user, show_seat_info: params[:show_seat_info]
end
- def track_areas_of_focus(member, areas_of_focus)
- return unless areas_of_focus
+ def present_member_invitations(invitations)
+ present invitations, with: Entities::Invitation, current_user: current_user
+ end
+
+ def add_single_member_by_user_id(create_service_params)
+ source = create_service_params[:source]
+ user_id = create_service_params[:user_ids]
+ user = User.find_by(id: user_id) # rubocop: disable CodeReuse/ActiveRecord
+
+ if user
+ conflict!('Member already exists') if member_already_exists?(source, user_id)
+
+ instance = ::Members::CreateService.new(current_user, create_service_params)
+ instance.execute
+
+ not_allowed! if instance.membership_locked # This currently can only be reached in EE if group membership is locked
- areas_of_focus.each do |area_of_focus|
- Gitlab::Tracking.event(::Members::CreateService.name, 'area_of_focus', label: area_of_focus, property: member.id.to_s)
+ member = instance.single_member
+ render_validation_error!(member) if member.invalid?
+
+ present_members(member)
+ else
+ not_found!('User')
end
end
- def present_members(members)
- present members, with: Entities::Member, current_user: current_user, show_seat_info: params[:show_seat_info]
+ def add_multiple_members?(user_id)
+ user_id.include?(',')
end
- def present_member_invitations(invitations)
- present invitations, with: Entities::Invitation, current_user: current_user
+ def add_single_member?(user_id)
+ user_id.present?
+ end
+
+ private
+
+ def member_already_exists?(source, user_id)
+ source.members.exists?(user_id: user_id) # rubocop: disable CodeReuse/ActiveRecord
end
end
end
diff --git a/lib/api/helpers/packages/npm.rb b/lib/api/helpers/packages/npm.rb
index ce5db52fdbc..34e126c73fc 100644
--- a/lib/api/helpers/packages/npm.rb
+++ b/lib/api/helpers/packages/npm.rb
@@ -57,7 +57,11 @@ module API
.by_path(namespace_path)
next unless namespace
- finder = ::Packages::Npm::PackageFinder.new(package_name, namespace: namespace)
+ finder = ::Packages::Npm::PackageFinder.new(
+ package_name,
+ namespace: namespace,
+ last_of_each_version: false
+ )
finder.last&.project_id
end
diff --git a/lib/api/helpers/pagination_strategies.rb b/lib/api/helpers/pagination_strategies.rb
index 61cff37e4ab..8c2186768ea 100644
--- a/lib/api/helpers/pagination_strategies.rb
+++ b/lib/api/helpers/pagination_strategies.rb
@@ -3,10 +3,16 @@
module API
module Helpers
module PaginationStrategies
- def paginate_with_strategies(relation, request_scope)
+ def paginate_with_strategies(relation, request_scope = nil)
paginator = paginator(relation, request_scope)
- yield(paginator.paginate(relation)).tap do |records, _|
+ result = if block_given?
+ yield(paginator.paginate(relation))
+ else
+ paginator.paginate(relation)
+ end
+
+ result.tap do |records, _|
paginator.finalize(records)
end
end
@@ -20,17 +26,31 @@ module API
private
def keyset_paginator(relation)
- request_context = Gitlab::Pagination::Keyset::RequestContext.new(self)
- unless Gitlab::Pagination::Keyset.available?(request_context, relation)
+ if cursor_based_keyset_pagination_supported?(relation)
+ request_context_class = Gitlab::Pagination::Keyset::CursorBasedRequestContext
+ paginator_class = Gitlab::Pagination::Keyset::CursorPager
+ availability_checker = Gitlab::Pagination::CursorBasedKeyset
+ else
+ request_context_class = Gitlab::Pagination::Keyset::RequestContext
+ paginator_class = Gitlab::Pagination::Keyset::Pager
+ availability_checker = Gitlab::Pagination::Keyset
+ end
+
+ request_context = request_context_class.new(self)
+
+ unless availability_checker.available?(request_context, relation)
return error!('Keyset pagination is not yet available for this type of request', 405)
end
- Gitlab::Pagination::Keyset::Pager.new(request_context)
+ paginator_class.new(request_context)
end
def offset_paginator(relation, request_scope)
offset_limit = limit_for_scope(request_scope)
- if Gitlab::Pagination::Keyset.available_for_type?(relation) && offset_limit_exceeded?(offset_limit)
+ if (Gitlab::Pagination::Keyset.available_for_type?(relation) ||
+ cursor_based_keyset_pagination_supported?(relation)) &&
+ offset_limit_exceeded?(offset_limit)
+
return error!("Offset pagination has a maximum allowed offset of #{offset_limit} " \
"for requests that return objects of type #{relation.klass}. " \
"Remaining records can be retrieved using keyset pagination.", 405)
@@ -39,6 +59,10 @@ module API
Gitlab::Pagination::OffsetPagination.new(self)
end
+ def cursor_based_keyset_pagination_supported?(relation)
+ Gitlab::Pagination::CursorBasedKeyset.available_for_type?(relation)
+ end
+
def keyset_pagination_enabled?
params[:pagination] == 'keyset'
end
diff --git a/lib/api/helpers/settings_helpers.rb b/lib/api/helpers/settings_helpers.rb
index a3ea1057bc8..82de4917f0b 100644
--- a/lib/api/helpers/settings_helpers.rb
+++ b/lib/api/helpers/settings_helpers.rb
@@ -10,10 +10,18 @@ module API
end
def self.optional_attributes
- [*::ApplicationSettingsHelper.visible_attributes,
- *::ApplicationSettingsHelper.external_authorization_service_attributes,
- *::ApplicationSettingsHelper.deprecated_attributes,
- :performance_bar_allowed_group_id].freeze
+ [
+ *::ApplicationSettingsHelper.visible_attributes,
+ *::ApplicationSettingsHelper.external_authorization_service_attributes,
+ *::ApplicationSettingsHelper.deprecated_attributes,
+ :performance_bar_allowed_group_id,
+ # TODO: Once we rename these columns, we can remove them here and add the old
+ # names to `ApplicationSettingsHelper.deprecated_attributes` instead.
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/340031
+ :throttle_unauthenticated_web_enabled,
+ :throttle_unauthenticated_web_period_in_seconds,
+ :throttle_unauthenticated_web_requests_per_period
+ ].freeze
end
end
end
diff --git a/lib/api/internal/kubernetes.rb b/lib/api/internal/kubernetes.rb
index 7af5c2ad2ee..d1ad3c1feb1 100644
--- a/lib/api/internal/kubernetes.rb
+++ b/lib/api/internal/kubernetes.rb
@@ -100,6 +100,23 @@ module API
end
end
+ namespace 'kubernetes/agent_configuration' do
+ desc 'POST agent configuration' do
+ detail 'Store configuration for an agent'
+ end
+ params do
+ requires :agent_id, type: Integer, desc: 'ID of the configured Agent'
+ requires :agent_config, type: JSON, desc: 'Configuration for the Agent'
+ end
+ post '/' do
+ agent = Clusters::Agent.find(params[:agent_id])
+
+ Clusters::Agents::RefreshAuthorizationService.new(agent, config: params[:agent_config]).execute
+
+ no_content!
+ end
+ end
+
namespace 'kubernetes/usage_metrics' do
desc 'POST usage metrics' do
detail 'Updates usage metrics for agent'
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index a6565f913e3..39ce6e0b062 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -14,6 +14,10 @@ module API
params :negatable_issue_filter_params do
optional :labels, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, desc: 'Comma-separated list of label names'
optional :milestone, type: String, desc: 'Milestone title'
+ optional :milestone_id, types: String, values: %w[Any None Upcoming Started],
+ desc: 'Return issues assigned to milestones without the specified timebox value ("Any", "None", "Upcoming" or "Started")'
+ mutually_exclusive :milestone_id, :milestone
+
optional :iids, type: Array[Integer], coerce_with: ::API::Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'The IID array of issues'
optional :author_id, type: Integer, desc: 'Return issues which are not authored by the user with the given ID'
@@ -32,9 +36,14 @@ module API
params :issues_stats_params do
optional :labels, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, desc: 'Comma-separated list of label names'
optional :milestone, type: String, desc: 'Milestone title'
+ # 'milestone_id' only accepts wildcard values 'Any', 'None', 'Upcoming', 'Started'
+ # the param has '_id' in the name to keep consistency (ex. assignee_id accepts id and wildcard values).
+ optional :milestone_id, types: String, values: %w[Any None Upcoming Started],
+ desc: 'Return issues assigned to milestones with the specified timebox value ("Any", "None", "Upcoming" or "Started")'
optional :iids, type: Array[Integer], coerce_with: ::API::Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'The IID array of issues'
optional :search, type: String, desc: 'Search issues for text present in the title, description, or any combination of these'
optional :in, type: String, desc: '`title`, `description`, or a string joining them with comma'
+ mutually_exclusive :milestone_id, :milestone
optional :author_id, type: Integer, desc: 'Return issues which are authored by the user with the given ID'
optional :author_username, type: String, desc: 'Return issues which are authored by the user with the given username'
@@ -69,7 +78,7 @@ module API
optional :state, type: String, values: %w[opened closed all], default: 'all',
desc: 'Return opened, closed, or all issues'
optional :order_by, type: String, values: Helpers::IssuesHelpers.sort_options, default: 'created_at',
- desc: 'Return issues ordered by `created_at` or `updated_at` fields.'
+ desc: 'Return issues ordered by `created_at`, `due_date`, `label_priority`, `milestone_due`, `popularity`, `priority`, `relative_position`, `title`, or `updated_at` fields.'
optional :sort, type: String, values: %w[asc desc], default: 'desc',
desc: 'Return issues sorted in `asc` or `desc` order.'
optional :due_date, type: String, values: %w[0 overdue week month next_month_and_previous_two_weeks] << '',
diff --git a/lib/api/lint.rb b/lib/api/lint.rb
index 945cdf3edb2..fa871b4bc57 100644
--- a/lib/api/lint.rb
+++ b/lib/api/lint.rb
@@ -13,18 +13,13 @@ module API
post '/lint' do
unauthorized! if (Gitlab::CurrentSettings.signup_disabled? || Gitlab::CurrentSettings.signup_limited?) && current_user.nil?
- result = Gitlab::Ci::YamlProcessor.new(params[:content], user: current_user).execute
+ result = Gitlab::Ci::Lint.new(project: nil, current_user: current_user)
+ .validate(params[:content], dry_run: false)
status 200
-
- response = if result.errors.empty?
- { status: 'valid', errors: [], warnings: result.warnings }
- else
- { status: 'invalid', errors: result.errors, warnings: result.warnings }
- end
-
- response.tap do |response|
- response[:merged_yaml] = result.merged_yaml if params[:include_merged_yaml]
+ Entities::Ci::Lint::Result.represent(result, current_user: current_user).serializable_hash.tap do |presented_result|
+ presented_result[:status] = presented_result[:valid] ? 'valid' : 'invalid'
+ presented_result.delete(:merged_yaml) unless params[:include_merged_yaml]
end
end
end
diff --git a/lib/api/members.rb b/lib/api/members.rb
index 7130635281a..332520ccd26 100644
--- a/lib/api/members.rb
+++ b/lib/api/members.rb
@@ -96,42 +96,22 @@ module API
optional :invite_source, type: String, desc: 'Source that triggered the member creation process', default: 'members-api'
optional :areas_of_focus, type: Array[String], coerce_with: Validations::Types::CommaSeparatedToArray.coerce, desc: 'Areas the inviter wants the member to focus upon'
end
- # rubocop: disable CodeReuse/ActiveRecord
+
post ":id/members" do
::Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/333434')
source = find_source(source_type, params[:id])
authorize_admin_source!(source_type, source)
- if params[:user_id].to_s.include?(',')
- create_service_params = params.except(:user_id).merge({ user_ids: params[:user_id], source: source })
+ user_id = params[:user_id].to_s
+ create_service_params = params.except(:user_id).merge({ user_ids: user_id, source: source })
+ if add_multiple_members?(user_id)
::Members::CreateService.new(current_user, create_service_params).execute
- elsif params[:user_id].present?
- member = source.members.find_by(user_id: params[:user_id])
- conflict!('Member already exists') if member
-
- user = User.find_by_id(params[:user_id])
- not_found!('User') unless user
-
- member = create_member(current_user, user, source, params)
-
- if !member
- not_allowed! # This currently can only be reached in EE
- elsif member.valid? && member.persisted?
- present_members(member)
- Gitlab::Tracking.event(::Members::CreateService.name,
- 'create_member',
- label: params[:invite_source],
- property: 'existing_user',
- user: current_user)
- track_areas_of_focus(member, params[:areas_of_focus])
- else
- render_validation_error!(member)
- end
+ elsif add_single_member?(user_id)
+ add_single_member_by_user_id(create_service_params)
end
end
- # rubocop: enable CodeReuse/ActiveRecord
desc 'Updates a member of a group or project.' do
success Entities::Member
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index 7ab57982907..34af9eab511 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -202,7 +202,7 @@ module API
options[:project] = user_project
if Feature.enabled?(:api_caching_merge_requests, user_project, type: :development, default_enabled: :yaml)
- present_cached merge_requests, expires_in: 10.minutes, **options
+ present_cached merge_requests, expires_in: 2.days, **options
else
present merge_requests, options
end
diff --git a/lib/api/npm_project_packages.rb b/lib/api/npm_project_packages.rb
index 7ff4439ce04..dbfc0a61577 100644
--- a/lib/api/npm_project_packages.rb
+++ b/lib/api/npm_project_packages.rb
@@ -48,14 +48,13 @@ module API
put ':package_name', requirements: ::API::Helpers::Packages::Npm::NPM_ENDPOINT_REQUIREMENTS do
authorize_create_package!(project)
- track_package_event('push_package', :npm, category: 'API::NpmPackages', project: project, user: current_user, namespace: project.namespace)
-
created_package = ::Packages::Npm::CreatePackageService
.new(project, current_user, params.merge(build: current_authenticated_job)).execute
if created_package[:status] == :error
render_api_error!(created_package[:message], created_package[:http_status])
else
+ track_package_event('push_package', :npm, category: 'API::NpmPackages', project: project, user: current_user, namespace: project.namespace)
created_package
end
end
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 28bcb382ecf..a92d904be84 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -152,6 +152,12 @@ module API
ProjectsFinder.new(current_user: current_user, params: project_params).execute
end
+ def present_project(project, options = {})
+ options[:with].preload_resource(project) if options[:with].respond_to?(:preload_resource)
+
+ present project, options
+ end
+
def present_projects(projects, options = {})
verify_statistics_order_by_projects!
@@ -264,9 +270,9 @@ module API
project = ::Projects::CreateService.new(current_user, attrs).execute
if project.saved?
- present project, with: Entities::Project,
- user_can_admin_project: can?(current_user, :admin_project, project),
- current_user: current_user
+ present_project project, with: Entities::Project,
+ user_can_admin_project: can?(current_user, :admin_project, project),
+ current_user: current_user
else
if project.errors[:limit_reached].present?
error!(project.errors[:limit_reached], 403)
@@ -301,9 +307,9 @@ module API
project = ::Projects::CreateService.new(user, attrs).execute
if project.saved?
- present project, with: Entities::Project,
- user_can_admin_project: can?(current_user, :admin_project, project),
- current_user: current_user
+ present_project project, with: Entities::Project,
+ user_can_admin_project: can?(current_user, :admin_project, project),
+ current_user: current_user
else
render_validation_error!(project)
end
@@ -336,7 +342,7 @@ module API
project, options = with_custom_attributes(user_project, options)
- present project, options
+ present_project project, options
end
desc 'Fork new project for the current user or provided namespace.' do
@@ -376,9 +382,11 @@ module API
if forked_project.errors.any?
conflict!(forked_project.errors.messages)
else
- present forked_project, with: Entities::Project,
- user_can_admin_project: can?(current_user, :admin_project, forked_project),
- current_user: current_user
+ present_project forked_project, {
+ with: Entities::Project,
+ user_can_admin_project: can?(current_user, :admin_project, forked_project),
+ current_user: current_user
+ }
end
end
@@ -427,9 +435,9 @@ module API
result = ::Projects::UpdateService.new(user_project, current_user, attrs).execute
if result[:status] == :success
- present user_project, with: Entities::Project,
- user_can_admin_project: can?(current_user, :admin_project, user_project),
- current_user: current_user
+ present_project user_project, with: Entities::Project,
+ user_can_admin_project: can?(current_user, :admin_project, user_project),
+ current_user: current_user
else
render_validation_error!(user_project)
end
@@ -443,7 +451,7 @@ module API
::Projects::UpdateService.new(user_project, current_user, archived: true).execute
- present user_project, with: Entities::Project, current_user: current_user
+ present_project user_project, with: Entities::Project, current_user: current_user
end
desc 'Unarchive a project' do
@@ -454,7 +462,7 @@ module API
::Projects::UpdateService.new(user_project, current_user, archived: false).execute
- present user_project, with: Entities::Project, current_user: current_user
+ present_project user_project, with: Entities::Project, current_user: current_user
end
desc 'Star a project' do
@@ -467,7 +475,7 @@ module API
current_user.toggle_star(user_project)
user_project.reset
- present user_project, with: Entities::Project, current_user: current_user
+ present_project user_project, with: Entities::Project, current_user: current_user
end
end
@@ -479,7 +487,7 @@ module API
current_user.toggle_star(user_project)
user_project.reset
- present user_project, with: Entities::Project, current_user: current_user
+ present_project user_project, with: Entities::Project, current_user: current_user
else
not_modified!
end
@@ -528,7 +536,7 @@ module API
result = ::Projects::ForkService.new(fork_from_project, current_user).execute(user_project)
if result
- present user_project.reset, with: Entities::Project, current_user: current_user
+ present_project user_project.reset, with: Entities::Project, current_user: current_user
else
render_api_error!("Project already forked", 409) if user_project.forked?
end
@@ -698,7 +706,7 @@ module API
result = ::Projects::TransferService.new(user_project, current_user).execute(namespace)
if result
- present user_project, with: Entities::Project, current_user: current_user
+ present_project user_project, with: Entities::Project, current_user: current_user
else
render_api_error!("Failed to transfer project #{user_project.errors.messages}", 400)
end
diff --git a/lib/api/projects_relation_builder.rb b/lib/api/projects_relation_builder.rb
index 6dfd82d109f..db46602cd90 100644
--- a/lib/api/projects_relation_builder.rb
+++ b/lib/api/projects_relation_builder.rb
@@ -7,28 +7,35 @@ module API
class_methods do
def prepare_relation(projects_relation, options = {})
projects_relation = preload_relation(projects_relation, options)
+
execute_batch_counting(projects_relation)
- # Call the forks count method on every project, so the BatchLoader would load them all at
- # once when the entities are rendered
- projects_relation.each(&:forks_count)
+
+ preload_repository_cache(projects_relation)
projects_relation
end
+ # This is overridden by the specific Entity class to
+ # preload assocations that it needs
def preload_relation(projects_relation, options = {})
projects_relation
end
- def forks_counting_projects(projects_relation)
- projects_relation
+ # This is overridden by the specific Entity class to
+ # batch load certain counts
+ def execute_batch_counting(projects_relation)
end
- def batch_open_issues_counting(projects_relation)
- ::Projects::BatchOpenIssuesCountService.new(projects_relation).refresh_cache
+ def preload_repository_cache(projects_relation)
+ repositories = repositories_for_preload(projects_relation)
+
+ Gitlab::RepositoryCache::Preloader.new(repositories).preload( # rubocop:disable CodeReuse/ActiveRecord
+ %i[exists? root_ref has_visible_content? avatar readme_path]
+ )
end
- def execute_batch_counting(projects_relation)
- batch_open_issues_counting(projects_relation)
+ def repositories_for_preload(projects_relation)
+ projects_relation.map(&:repository)
end
end
end
diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb
index 20320d1b7ae..3c9255e3117 100644
--- a/lib/api/repositories.rb
+++ b/lib/api/repositories.rb
@@ -51,18 +51,22 @@ module API
optional :ref, type: String, desc: 'The name of a repository branch or tag, if not given the default branch is used'
optional :path, type: String, desc: 'The path of the tree'
optional :recursive, type: Boolean, default: false, desc: 'Used to get a recursive tree'
+
use :pagination
+ optional :pagination, type: String, values: %w(legacy keyset), default: 'legacy', desc: 'Specify the pagination method'
+
+ given pagination: -> (value) { value == 'keyset' } do
+ optional :page_token, type: String, desc: 'Record from which to start the keyset pagination'
+ end
end
get ':id/repository/tree' do
- ref = params[:ref] || user_project.default_branch
- path = params[:path] || nil
+ tree_finder = ::Repositories::TreeFinder.new(user_project, declared_params(include_missing: false))
+
+ not_found!("Tree") unless tree_finder.commit_exists?
- commit = user_project.commit(ref)
- not_found!('Tree') unless commit
+ tree = Gitlab::Pagination::GitalyKeysetPager.new(self, user_project).paginate(tree_finder)
- tree = user_project.repository.tree(commit.id, path, recursive: params[:recursive])
- entries = ::Kaminari.paginate_array(tree.sorted_entries)
- present paginate(entries), with: Entities::TreeObject
+ present tree, with: Entities::TreeObject
end
desc 'Get raw blob contents from the repository'
diff --git a/lib/api/settings.rb b/lib/api/settings.rb
index aac195f0668..36f816ae638 100644
--- a/lib/api/settings.rb
+++ b/lib/api/settings.rb
@@ -176,6 +176,7 @@ module API
optional :require_admin_approval_after_user_signup, type: Boolean, desc: 'Require explicit admin approval for new signups'
optional :whats_new_variant, type: String, values: ApplicationSetting.whats_new_variants.keys, desc: "What's new variant, possible values: `all_tiers`, `current_tier`, and `disabled`."
optional :floc_enabled, type: Grape::API::Boolean, desc: 'Enable FloC (Federated Learning of Cohorts)'
+ optional :user_deactivation_emails_enabled, type: Boolean, desc: 'Send emails to users upon account deactivation'
ApplicationSetting::SUPPORTED_KEY_TYPES.each do |type|
optional :"#{type}_key_restriction",
@@ -225,6 +226,16 @@ module API
attrs[:asset_proxy_allowlist] = attrs.delete(:asset_proxy_whitelist)
end
+ # Also accept these attributes under their new names.
+ #
+ # TODO: Once we rename the columns, we have to swap this around and keep supporting the old names until v5.
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/340031
+ %w[enabled period_in_seconds requests_per_period].each do |suffix|
+ old_name = :"throttle_unauthenticated_#{suffix}"
+ new_name = :"throttle_unauthenticated_web_#{suffix}"
+ attrs[old_name] = attrs.delete(new_name) if attrs.has_key?(new_name)
+ end
+
# since 13.0 it's not possible to disable hashed storage - support can be removed in 14.0
attrs.delete(:hashed_storage_enabled) if attrs.has_key?(:hashed_storage_enabled)
diff --git a/lib/api/templates.rb b/lib/api/templates.rb
index a595129fd6a..85a299c5673 100644
--- a/lib/api/templates.rb
+++ b/lib/api/templates.rb
@@ -11,7 +11,7 @@ module API
},
gitlab_ci_ymls: {
gitlab_version: 8.9,
- feature_category: :continuous_integration
+ feature_category: :pipeline_authoring
},
dockerfiles: {
gitlab_version: 8.15,
diff --git a/lib/api/users.rb b/lib/api/users.rb
index 2608fb87e22..e3271b8b9b2 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -615,6 +615,22 @@ module API
end
end
+ desc 'Reject a pending user. Available only for admins.'
+ params do
+ requires :id, type: Integer, desc: 'The ID of the user'
+ end
+ post ':id/reject', feature_category: :authentication_and_authorization do
+ user = find_user_by_id(params)
+
+ result = ::Users::RejectService.new(current_user).execute(user)
+
+ if result[:success]
+ present user
+ else
+ render_api_error!(result[:message], result[:http_status])
+ end
+ end
+
# rubocop: enable CodeReuse/ActiveRecord
desc 'Deactivate an active user. Available only for admins.'
params do
@@ -687,6 +703,38 @@ module API
end
# rubocop: enable CodeReuse/ActiveRecord
+ desc 'Ban a user. Available only for admins.'
+ params do
+ requires :id, type: Integer, desc: 'The ID of the user'
+ end
+ post ':id/ban', feature_category: :authentication_and_authorization do
+ authenticated_as_admin!
+ user = find_user_by_id(params)
+
+ result = ::Users::BanService.new(current_user).execute(user)
+ if result[:status] == :success
+ true
+ else
+ render_api_error!(result[:message], result[:http_status])
+ end
+ end
+
+ desc 'Unban a user. Available only for admins.'
+ params do
+ requires :id, type: Integer, desc: 'The ID of the user'
+ end
+ post ':id/unban', feature_category: :authentication_and_authorization do
+ authenticated_as_admin!
+ user = find_user_by_id(params)
+
+ result = ::Users::UnbanService.new(current_user).execute(user)
+ if result[:status] == :success
+ true
+ else
+ render_api_error!(result[:message], result[:http_status])
+ end
+ end
+
desc 'Get memberships' do
success Entities::Membership
end
diff --git a/lib/backup/gitaly_backup.rb b/lib/backup/gitaly_backup.rb
index 55fd68fd6e8..47b63990262 100644
--- a/lib/backup/gitaly_backup.rb
+++ b/lib/backup/gitaly_backup.rb
@@ -22,8 +22,8 @@ module Backup
end
args = []
- args += ['-parallel', @parallel.to_s] if type == :create && @parallel
- args += ['-parallel-storage', @parallel_storage.to_s] if type == :create && @parallel_storage
+ args += ['-parallel', @parallel.to_s] if @parallel
+ args += ['-parallel-storage', @parallel_storage.to_s] if @parallel_storage
@stdin, stdout, @thread = Open3.popen2(ENV, bin_path, command, '-path', backup_repos_path, *args)
diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb
index 52810b0fb35..6c5350082e8 100644
--- a/lib/backup/manager.rb
+++ b/lib/backup/manager.rb
@@ -47,10 +47,12 @@ module Backup
return
end
- directory = connect_to_remote_directory(Gitlab.config.backup.upload)
+ directory = connect_to_remote_directory
+ upload = directory.files.create(create_attributes)
- if directory.files.create(create_attributes)
+ if upload
progress.puts "done".color(:green)
+ upload
else
puts "uploading backup to #{remote_directory} failed".color(:red)
raise Backup::Error, 'Backup failed'
@@ -206,11 +208,16 @@ module Backup
@backup_file_list.map {|item| item.gsub("#{FILE_NAME_SUFFIX}", "")}
end
- def connect_to_remote_directory(options)
- config = ObjectStorage::Config.new(options)
- config.load_provider
+ def object_storage_config
+ @object_storage_config ||= begin
+ config = ObjectStorage::Config.new(Gitlab.config.backup.upload)
+ config.load_provider
+ config
+ end
+ end
- connection = ::Fog::Storage.new(config.credentials)
+ def connect_to_remote_directory
+ connection = ::Fog::Storage.new(object_storage_config.credentials)
# We only attempt to create the directory for local backups. For AWS
# and other cloud providers, we cannot guarantee the user will have
@@ -280,10 +287,8 @@ module Backup
key: remote_target,
body: File.open(File.join(backup_path, tar_file)),
multipart_chunk_size: Gitlab.config.backup.upload.multipart_chunk_size,
- encryption: Gitlab.config.backup.upload.encryption,
- encryption_key: Gitlab.config.backup.upload.encryption_key,
storage_class: Gitlab.config.backup.upload.storage_class
- }
+ }.merge(encryption_attributes)
# Google bucket-only policies prevent setting an ACL. In any case, by default,
# all objects are set to the default ACL, which is project-private:
@@ -293,6 +298,19 @@ module Backup
attrs
end
+ def encryption_attributes
+ return object_storage_config.fog_attributes if object_storage_config.aws_server_side_encryption_enabled?
+
+ # Use customer-managed keys. Also, this preserves
+ # backward-compatibility for existing usages of `SSE-S3` that
+ # don't set `backup.upload.storage_options.server_side_encryption`
+ # to `'AES256'`.
+ {
+ encryption_key: Gitlab.config.backup.upload.encryption_key,
+ encryption: Gitlab.config.backup.upload.encryption
+ }
+ end
+
def google_provider?
Gitlab.config.backup.upload.connection&.provider&.downcase == 'google'
end
diff --git a/lib/backup/pages.rb b/lib/backup/pages.rb
index ae293073ba2..393cf4108a1 100644
--- a/lib/backup/pages.rb
+++ b/lib/backup/pages.rb
@@ -2,12 +2,16 @@
module Backup
class Pages < Backup::Files
+ # pages used to deploy tmp files to this path
+ # if some of these files are still there, we don't need them in the backup
+ LEGACY_PAGES_TMP_PATH = '@pages.tmp'
+
attr_reader :progress
def initialize(progress)
@progress = progress
- super('pages', Gitlab.config.pages.path, excludes: [::Projects::UpdatePagesService::TMP_EXTRACT_PATH])
+ super('pages', Gitlab.config.pages.path, excludes: [LEGACY_PAGES_TMP_PATH])
end
end
end
diff --git a/lib/banzai/filter/playable_link_filter.rb b/lib/banzai/filter/playable_link_filter.rb
index 0a043aa809c..5b290ff08f6 100644
--- a/lib/banzai/filter/playable_link_filter.rb
+++ b/lib/banzai/filter/playable_link_filter.rb
@@ -52,7 +52,7 @@ module Banzai
doc.document.create_element(media_type, media_element_attrs)
end
- def download_paragraph(doc, element)
+ def download_link(doc, element)
link_content = element['title'] || element['alt']
link_element_attrs = {
@@ -67,19 +67,15 @@ module Banzai
link_element_attrs['data-canonical-src'] = element['data-canonical-src']
end
- link = doc.document.create_element('a', link_content, link_element_attrs)
-
- doc.document.create_element('p').tap do |paragraph|
- paragraph.children = link
- end
+ doc.document.create_element('a', link_content, link_element_attrs)
end
def media_node(doc, element)
- container_element_attrs = { class: "#{media_type}-container" }
+ container_element_attrs = { class: "media-container #{media_type}-container" }
- doc.document.create_element( "div", container_element_attrs).tap do |container|
+ doc.document.create_element('span', container_element_attrs).tap do |container|
container.add_child(media_element(doc, element))
- container.add_child(download_paragraph(doc, element))
+ container.add_child(download_link(doc, element))
end
end
end
diff --git a/lib/banzai/filter/references/label_reference_filter.rb b/lib/banzai/filter/references/label_reference_filter.rb
index 3ae9c5f8d90..a019ae0108e 100644
--- a/lib/banzai/filter/references/label_reference_filter.rb
+++ b/lib/banzai/filter/references/label_reference_filter.rb
@@ -23,7 +23,8 @@ module Banzai
label_relation = labels.where(title: label_names)
end
- return Label.none if (relation = [id_relation, label_relation].compact).empty?
+ relation = [id_relation, label_relation].compact
+ return Label.none if relation.all?(Label.none)
Label.from_union(relation)
end
diff --git a/lib/banzai/filter/references/milestone_reference_filter.rb b/lib/banzai/filter/references/milestone_reference_filter.rb
index d992e667056..94f7106d31e 100644
--- a/lib/banzai/filter/references/milestone_reference_filter.rb
+++ b/lib/banzai/filter/references/milestone_reference_filter.rb
@@ -23,7 +23,8 @@ module Banzai
milestone_relation = find_milestones(parent, false).where(name: milestone_names)
end
- return Milestone.none if (relation = [iid_relation, milestone_relation].compact).empty?
+ relation = [iid_relation, milestone_relation].compact
+ return Milestone.none if relation.all?(Milestone.none)
Milestone.from_union(relation).includes(:project, :group)
end
@@ -116,11 +117,11 @@ module Banzai
# We don't support IID lookups because IIDs can clash between
# group/project milestones and group/subgroup milestones.
- params[:group_ids] = self_and_ancestors_ids(parent) unless find_by_iid
+ params[:group_ids] = group_and_ancestors_ids(parent) unless find_by_iid
end
end
- def self_and_ancestors_ids(parent)
+ def group_and_ancestors_ids(parent)
if group_context?(parent)
parent.self_and_ancestors.select(:id)
elsif project_context?(parent)
diff --git a/lib/banzai/filter/references/reference_cache.rb b/lib/banzai/filter/references/reference_cache.rb
index 816ce973cad..b2d47aba2d6 100644
--- a/lib/banzai/filter/references/reference_cache.rb
+++ b/lib/banzai/filter/references/reference_cache.rb
@@ -28,11 +28,18 @@ module Banzai
@references_per_parent[parent_type] ||= begin
refs = Hash.new { |hash, key| hash[key] = Set.new }
- if Feature.enabled?(:milestone_reference_pattern, default_enabled: :yaml)
- doc_search(refs)
- else
- node_search(nodes, refs)
+ prepare_doc_for_scan(filter.doc).to_enum(:scan, regex).each do
+ parent_path = if parent_type == :project
+ full_project_path($~[:namespace], $~[:project])
+ else
+ full_group_path($~[:group])
+ end
+
+ ident = filter.identifier($~)
+ refs[parent_path] << ident if ident
end
+
+ refs
end
end
@@ -163,39 +170,6 @@ module Banzai
delegate :project, :group, :parent, :parent_type, to: :filter
- # Deprecated: https://gitlab.com/gitlab-org/gitlab/-/issues/336268
- def node_search(nodes, refs)
- nodes.each do |node|
- prepare_node_for_scan(node).scan(regex) do
- parent_path = if parent_type == :project
- full_project_path($~[:namespace], $~[:project])
- else
- full_group_path($~[:group])
- end
-
- ident = filter.identifier($~)
- refs[parent_path] << ident if ident
- end
- end
-
- refs
- end
-
- def doc_search(refs)
- prepare_doc_for_scan(filter.doc).to_enum(:scan, regex).each do
- parent_path = if parent_type == :project
- full_project_path($~[:namespace], $~[:project])
- else
- full_group_path($~[:group])
- end
-
- ident = filter.identifier($~)
- refs[parent_path] << ident if ident
- end
-
- refs
- end
-
def regex
strong_memoize(:regex) do
[
@@ -215,13 +189,6 @@ module Banzai
filter.requires_unescaping? ? unescape_html_entities(html) : html
end
- # Deprecated: https://gitlab.com/gitlab-org/gitlab/-/issues/336268
- def prepare_node_for_scan(node)
- html = node.to_html
-
- filter.requires_unescaping? ? unescape_html_entities(html) : html
- end
-
def unescape_html_entities(text)
CGI.unescapeHTML(text.to_s)
end
diff --git a/lib/banzai/reference_parser/base_parser.rb b/lib/banzai/reference_parser/base_parser.rb
index 0c015ba00c7..831baa9a778 100644
--- a/lib/banzai/reference_parser/base_parser.rb
+++ b/lib/banzai/reference_parser/base_parser.rb
@@ -212,9 +212,8 @@ module Banzai
def gather_references(nodes, ids_only: false)
nodes = nodes_user_can_reference(current_user, nodes)
visible = nodes_visible_to_user(current_user, nodes)
- not_visible = nodes - visible
- { visible: referenced_by(visible, ids_only: ids_only), not_visible: not_visible }
+ { visible: referenced_by(visible, ids_only: ids_only), nodes: nodes, visible_nodes: visible }
end
# Returns a Hash containing the projects for a given list of HTML nodes.
diff --git a/lib/bulk_imports/common/pipelines/entity_finisher.rb b/lib/bulk_imports/common/pipelines/entity_finisher.rb
new file mode 100644
index 00000000000..aa9221cceee
--- /dev/null
+++ b/lib/bulk_imports/common/pipelines/entity_finisher.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+module BulkImports
+ module Common
+ module Pipelines
+ class EntityFinisher
+ def self.ndjson_pipeline?
+ false
+ end
+
+ def initialize(context)
+ @context = context
+ @entity = @context.entity
+ @trackers = @entity.trackers
+ end
+
+ def run
+ return if entity.finished? || entity.failed?
+
+ if all_other_trackers_failed?
+ entity.fail_op!
+ else
+ entity.finish!
+ end
+
+ logger.info(
+ bulk_import_id: context.bulk_import.id,
+ bulk_import_entity_id: context.entity.id,
+ bulk_import_entity_type: context.entity.source_type,
+ pipeline_class: self.class.name,
+ message: "Entity #{entity.status_name}"
+ )
+ end
+
+ private
+
+ attr_reader :context, :entity, :trackers
+
+ def logger
+ @logger ||= Gitlab::Import::Logger.build
+ end
+
+ def all_other_trackers_failed?
+ trackers.where.not(relation: self.class.name).all? { |tracker| tracker.failed? } # rubocop: disable CodeReuse/ActiveRecord
+ end
+ end
+ end
+ end
+end
diff --git a/lib/bulk_imports/groups/graphql/get_projects_query.rb b/lib/bulk_imports/groups/graphql/get_projects_query.rb
new file mode 100644
index 00000000000..4cec1ad1462
--- /dev/null
+++ b/lib/bulk_imports/groups/graphql/get_projects_query.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+module BulkImports
+ module Groups
+ module Graphql
+ module GetProjectsQuery
+ extend self
+
+ def to_s
+ <<-'GRAPHQL'
+ query($full_path: ID!, $cursor: String, $per_page: Int) {
+ group(fullPath: $full_path) {
+ projects(includeSubgroups: false, first: $per_page, after: $cursor) {
+ page_info: pageInfo {
+ next_page: endCursor
+ has_next_page: hasNextPage
+ }
+ nodes {
+ name
+ full_path: fullPath
+ }
+ }
+ }
+ }
+ GRAPHQL
+ end
+
+ def variables(context)
+ {
+ full_path: context.entity.source_full_path,
+ cursor: context.tracker.next_page,
+ per_page: ::BulkImports::Tracker::DEFAULT_PAGE_SIZE
+ }
+ end
+
+ def base_path
+ %w[data group projects]
+ end
+
+ def data_path
+ base_path << 'nodes'
+ end
+
+ def page_info_path
+ base_path << 'page_info'
+ end
+ end
+ end
+ end
+end
diff --git a/lib/bulk_imports/groups/pipelines/entity_finisher.rb b/lib/bulk_imports/groups/pipelines/entity_finisher.rb
deleted file mode 100644
index 1a709179bf9..00000000000
--- a/lib/bulk_imports/groups/pipelines/entity_finisher.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-# frozen_string_literal: true
-
-module BulkImports
- module Groups
- module Pipelines
- class EntityFinisher
- def self.ndjson_pipeline?
- false
- end
-
- def initialize(context)
- @context = context
- @entity = @context.entity
- @trackers = @entity.trackers
- end
-
- def run
- return if entity.finished? || entity.failed?
-
- if all_other_trackers_failed?
- entity.fail_op!
- else
- entity.finish!
- end
-
- logger.info(
- bulk_import_id: context.bulk_import.id,
- bulk_import_entity_id: context.entity.id,
- bulk_import_entity_type: context.entity.source_type,
- pipeline_class: self.class.name,
- message: "Entity #{entity.status_name}"
- )
- end
-
- private
-
- attr_reader :context, :entity, :trackers
-
- def logger
- @logger ||= Gitlab::Import::Logger.build
- end
-
- def all_other_trackers_failed?
- trackers.where.not(relation: self.class.name).all? { |tracker| tracker.failed? } # rubocop: disable CodeReuse/ActiveRecord
- end
- end
- end
- end
-end
diff --git a/lib/bulk_imports/groups/pipelines/project_entities_pipeline.rb b/lib/bulk_imports/groups/pipelines/project_entities_pipeline.rb
new file mode 100644
index 00000000000..c318675e649
--- /dev/null
+++ b/lib/bulk_imports/groups/pipelines/project_entities_pipeline.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module BulkImports
+ module Groups
+ module Pipelines
+ class ProjectEntitiesPipeline
+ include Pipeline
+
+ extractor Common::Extractors::GraphqlExtractor, query: Graphql::GetProjectsQuery
+ transformer Common::Transformers::ProhibitedAttributesTransformer
+
+ def transform(context, data)
+ {
+ source_type: :project_entity,
+ source_full_path: data['full_path'],
+ destination_name: data['name'],
+ destination_namespace: context.entity.group.full_path,
+ parent_id: context.entity.id
+ }
+ end
+
+ def load(context, data)
+ context.bulk_import.entities.create!(data)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/bulk_imports/groups/stage.rb b/lib/bulk_imports/groups/stage.rb
new file mode 100644
index 00000000000..8c3b6975b73
--- /dev/null
+++ b/lib/bulk_imports/groups/stage.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+module BulkImports
+ module Groups
+ class Stage < ::BulkImports::Stage
+ private
+
+ def config
+ @config ||= {
+ group: {
+ pipeline: BulkImports::Groups::Pipelines::GroupPipeline,
+ stage: 0
+ },
+ avatar: {
+ pipeline: BulkImports::Groups::Pipelines::GroupAvatarPipeline,
+ stage: 1
+ },
+ subgroups: {
+ pipeline: BulkImports::Groups::Pipelines::SubgroupEntitiesPipeline,
+ stage: 1
+ },
+ members: {
+ pipeline: BulkImports::Groups::Pipelines::MembersPipeline,
+ stage: 1
+ },
+ labels: {
+ pipeline: BulkImports::Groups::Pipelines::LabelsPipeline,
+ stage: 1
+ },
+ milestones: {
+ pipeline: BulkImports::Groups::Pipelines::MilestonesPipeline,
+ stage: 1
+ },
+ badges: {
+ pipeline: BulkImports::Groups::Pipelines::BadgesPipeline,
+ stage: 1
+ },
+ boards: {
+ pipeline: BulkImports::Groups::Pipelines::BoardsPipeline,
+ stage: 2
+ },
+ finisher: {
+ pipeline: BulkImports::Common::Pipelines::EntityFinisher,
+ stage: 3
+ }
+ }.merge(project_entities_pipeline)
+ end
+
+ def project_entities_pipeline
+ if ::Feature.enabled?(:bulk_import_projects, default_enabled: :yaml)
+ {
+ project_entities: {
+ pipeline: BulkImports::Groups::Pipelines::ProjectEntitiesPipeline,
+ stage: 1
+ }
+ }
+ else
+ {}
+ end
+ end
+ end
+ end
+end
+
+::BulkImports::Groups::Stage.prepend_mod_with('BulkImports::Groups::Stage')
diff --git a/lib/bulk_imports/pipeline.rb b/lib/bulk_imports/pipeline.rb
index f27818dae18..6798936576b 100644
--- a/lib/bulk_imports/pipeline.rb
+++ b/lib/bulk_imports/pipeline.rb
@@ -69,8 +69,8 @@ module BulkImports
# Multiple transformers can be defined within a single
# pipeline and run sequentially for each record in the
# following order:
- # - Transformers defined using `transformer` class method
# - Instance method `transform`
+ # - Transformers defined using `transformer` class method
#
# Instance method `transform` is always the last to run.
#
diff --git a/lib/bulk_imports/projects/graphql/get_project_query.rb b/lib/bulk_imports/projects/graphql/get_project_query.rb
new file mode 100644
index 00000000000..2aec496880f
--- /dev/null
+++ b/lib/bulk_imports/projects/graphql/get_project_query.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+module BulkImports
+ module Projects
+ module Graphql
+ module GetProjectQuery
+ extend self
+
+ def to_s
+ <<-'GRAPHQL'
+ query($full_path: ID!) {
+ project(fullPath: $full_path) {
+ description
+ visibility
+ archived
+ created_at: createdAt
+ shared_runners_enabled: sharedRunnersEnabled
+ container_registry_enabled: containerRegistryEnabled
+ only_allow_merge_if_pipeline_succeeds: onlyAllowMergeIfPipelineSucceeds
+ only_allow_merge_if_all_discussions_are_resolved: onlyAllowMergeIfAllDiscussionsAreResolved
+ request_access_enabled: requestAccessEnabled
+ printing_merge_request_link_enabled: printingMergeRequestLinkEnabled
+ remove_source_branch_after_merge: removeSourceBranchAfterMerge
+ autoclose_referenced_issues: autocloseReferencedIssues
+ suggestion_commit_message: suggestionCommitMessage
+ wiki_enabled: wikiEnabled
+ }
+ }
+ GRAPHQL
+ end
+
+ def variables(context)
+ { full_path: context.entity.source_full_path }
+ end
+
+ def base_path
+ %w[data project]
+ end
+
+ def data_path
+ base_path
+ end
+
+ def page_info_path
+ base_path << 'page_info'
+ end
+ end
+ end
+ end
+end
diff --git a/lib/bulk_imports/projects/pipelines/project_pipeline.rb b/lib/bulk_imports/projects/pipelines/project_pipeline.rb
new file mode 100644
index 00000000000..c9da33fe8e3
--- /dev/null
+++ b/lib/bulk_imports/projects/pipelines/project_pipeline.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module BulkImports
+ module Projects
+ module Pipelines
+ class ProjectPipeline
+ include Pipeline
+
+ abort_on_failure!
+
+ extractor ::BulkImports::Common::Extractors::GraphqlExtractor, query: Graphql::GetProjectQuery
+ transformer ::BulkImports::Common::Transformers::ProhibitedAttributesTransformer
+ transformer ::BulkImports::Projects::Transformers::ProjectAttributesTransformer
+
+ def load(context, data)
+ project = ::Projects::CreateService.new(context.current_user, data).execute
+
+ if project.persisted?
+ context.entity.update!(project: project)
+
+ project
+ else
+ raise(::BulkImports::Error, "Unable to import project #{project.full_path}. #{project.errors.full_messages}.")
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/bulk_imports/projects/stage.rb b/lib/bulk_imports/projects/stage.rb
new file mode 100644
index 00000000000..b606003091b
--- /dev/null
+++ b/lib/bulk_imports/projects/stage.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module BulkImports
+ module Projects
+ class Stage < ::BulkImports::Stage
+ private
+
+ def config
+ @config ||= {
+ group: {
+ pipeline: BulkImports::Projects::Pipelines::ProjectPipeline,
+ stage: 0
+ },
+ finisher: {
+ pipeline: BulkImports::Common::Pipelines::EntityFinisher,
+ stage: 1
+ }
+ }
+ end
+ end
+ end
+end
+
+::BulkImports::Projects::Stage.prepend_mod_with('BulkImports::Projects::Stage')
diff --git a/lib/bulk_imports/projects/transformers/project_attributes_transformer.rb b/lib/bulk_imports/projects/transformers/project_attributes_transformer.rb
new file mode 100644
index 00000000000..24c55d8dbb1
--- /dev/null
+++ b/lib/bulk_imports/projects/transformers/project_attributes_transformer.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module BulkImports
+ module Projects
+ module Transformers
+ class ProjectAttributesTransformer
+ PROJECT_IMPORT_TYPE = 'gitlab_project_migration'
+
+ def transform(context, data)
+ entity = context.entity
+ visibility = data.delete('visibility')
+
+ data['name'] = entity.destination_name
+ data['path'] = entity.destination_name.parameterize
+ data['import_type'] = PROJECT_IMPORT_TYPE
+ data['visibility_level'] = Gitlab::VisibilityLevel.string_options[visibility] if visibility.present?
+ data['namespace_id'] = Namespace.find_by_full_path(entity.destination_namespace)&.id if entity.destination_namespace.present?
+
+ data.transform_keys!(&:to_sym)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/bulk_imports/stage.rb b/lib/bulk_imports/stage.rb
index b1bceecbaea..103623cd030 100644
--- a/lib/bulk_imports/stage.rb
+++ b/lib/bulk_imports/stage.rb
@@ -2,55 +2,8 @@
module BulkImports
class Stage
- include Singleton
-
- CONFIG = {
- group: {
- pipeline: BulkImports::Groups::Pipelines::GroupPipeline,
- stage: 0
- },
- avatar: {
- pipeline: BulkImports::Groups::Pipelines::GroupAvatarPipeline,
- stage: 1
- },
- subgroups: {
- pipeline: BulkImports::Groups::Pipelines::SubgroupEntitiesPipeline,
- stage: 1
- },
- members: {
- pipeline: BulkImports::Groups::Pipelines::MembersPipeline,
- stage: 1
- },
- labels: {
- pipeline: BulkImports::Groups::Pipelines::LabelsPipeline,
- stage: 1
- },
- milestones: {
- pipeline: BulkImports::Groups::Pipelines::MilestonesPipeline,
- stage: 1
- },
- badges: {
- pipeline: BulkImports::Groups::Pipelines::BadgesPipeline,
- stage: 1
- },
- boards: {
- pipeline: BulkImports::Groups::Pipelines::BoardsPipeline,
- stage: 2
- },
- finisher: {
- pipeline: BulkImports::Groups::Pipelines::EntityFinisher,
- stage: 3
- }
- }.freeze
-
def self.pipelines
- instance.pipelines
- end
-
- def self.pipeline_exists?(name)
- pipelines.any? do |(_, pipeline)|
- pipeline.to_s == name.to_s
- end
+ new.pipelines
end
def pipelines
@@ -65,9 +18,8 @@ module BulkImports
private
def config
- @config ||= CONFIG
+ # To be implemented in a sub-class
+ NotImplementedError
end
end
end
-
-::BulkImports::Stage.prepend_mod_with('BulkImports::Stage')
diff --git a/lib/error_tracking/collector/dsn.rb b/lib/error_tracking/collector/dsn.rb
new file mode 100644
index 00000000000..665181328f3
--- /dev/null
+++ b/lib/error_tracking/collector/dsn.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module ErrorTracking
+ module Collector
+ class Dsn
+ # Build a sentry compatible DSN URL for GitLab collector.
+ #
+ # The expected URL looks like that:
+ # https://PUBLIC_KEY@gitlab.example.com/api/v4/error_tracking/collector/PROJECT_ID
+ #
+ def self.build_url(public_key, project_id)
+ gitlab = Settings.gitlab
+
+ custom_port = Settings.gitlab_on_standard_port? ? nil : ":#{gitlab.port}"
+
+ base_url = [
+ gitlab.protocol,
+ "://",
+ public_key,
+ '@',
+ gitlab.host,
+ custom_port,
+ gitlab.relative_url_root
+ ].join('')
+
+ "#{base_url}/api/v4/error_tracking/collector/#{project_id}"
+ end
+ end
+ end
+end
diff --git a/lib/gem_extensions/active_record/association.rb b/lib/gem_extensions/active_record/association.rb
index 91a9f45ce7e..c6634a0524a 100644
--- a/lib/gem_extensions/active_record/association.rb
+++ b/lib/gem_extensions/active_record/association.rb
@@ -15,7 +15,7 @@ module GemExtensions
def scope
if disable_joins
- DisableJoins::Associations::AssociationScope.create.scope(self)
+ ::GemExtensions::ActiveRecord::DisableJoins::Associations::AssociationScope.create.scope(self)
else
super
end
@@ -25,7 +25,7 @@ module GemExtensions
if klass
@association_scope ||= begin # rubocop:disable Gitlab/ModuleWithInstanceVariables
if disable_joins
- DisableJoins::Associations::AssociationScope.scope(self)
+ ::GemExtensions::ActiveRecord::DisableJoins::Associations::AssociationScope.scope(self)
else
super
end
diff --git a/lib/gem_extensions/active_record/disable_joins/associations/association_scope.rb b/lib/gem_extensions/active_record/disable_joins/associations/association_scope.rb
index 1e4476330a2..9ff80829bc3 100644
--- a/lib/gem_extensions/active_record/disable_joins/associations/association_scope.rb
+++ b/lib/gem_extensions/active_record/disable_joins/associations/association_scope.rb
@@ -64,7 +64,7 @@ module GemExtensions
end
if scope.order_values.empty? && ordered
- split_scope = DisableJoins::Relation.create(scope.klass, key, join_ids)
+ split_scope = ::GemExtensions::ActiveRecord::DisableJoins::Relation.create(scope.klass, key, join_ids)
split_scope.where_clause += scope.where_clause
split_scope
else
diff --git a/lib/gitlab/action_cable/request_store_callbacks.rb b/lib/gitlab/action_cable/request_store_callbacks.rb
new file mode 100644
index 00000000000..a9f30b0fc10
--- /dev/null
+++ b/lib/gitlab/action_cable/request_store_callbacks.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module ActionCable
+ module RequestStoreCallbacks
+ def self.install
+ ::ActionCable::Server::Worker.set_callback :work, :around, &wrapper
+ ::ActionCable::Channel::Base.set_callback :subscribe, :around, &wrapper
+ ::ActionCable::Channel::Base.set_callback :unsubscribe, :around, &wrapper
+ end
+
+ def self.wrapper
+ lambda do |_, inner|
+ ::Gitlab::WithRequestStore.with_request_store do
+ inner.call
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/auth/auth_finders.rb b/lib/gitlab/auth/auth_finders.rb
index a7312ac759a..f6ee08defcf 100644
--- a/lib/gitlab/auth/auth_finders.rb
+++ b/lib/gitlab/auth/auth_finders.rb
@@ -338,6 +338,10 @@ module Gitlab
Gitlab::PathRegex.repository_git_route_regex.match?(current_request.path)
end
+ def git_lfs_request?
+ Gitlab::PathRegex.repository_git_lfs_route_regex.match?(current_request.path)
+ end
+
def archive_request?
current_request.path.include?('/-/archive/')
end
diff --git a/lib/gitlab/auth/o_auth/user.rb b/lib/gitlab/auth/o_auth/user.rb
index 1c5ded2e8ed..feb5fea4c85 100644
--- a/lib/gitlab/auth/o_auth/user.rb
+++ b/lib/gitlab/auth/o_auth/user.rb
@@ -54,7 +54,7 @@ module Gitlab
Users::UpdateService.new(gl_user, user: gl_user).execute!
- gl_user.block if block_after_save
+ gl_user.block_pending_approval if block_after_save
log.info "(#{provider}) saving user #{auth_hash.email} from login with admin => #{gl_user.admin}, extern_uid => #{auth_hash.uid}"
gl_user
diff --git a/lib/gitlab/background_migration/backfill_design_internal_ids.rb b/lib/gitlab/background_migration/backfill_design_internal_ids.rb
index 6d1df95c66d..236c6b6eb9a 100644
--- a/lib/gitlab/background_migration/backfill_design_internal_ids.rb
+++ b/lib/gitlab/background_migration/backfill_design_internal_ids.rb
@@ -73,7 +73,7 @@ module Gitlab
# violation. We can safely roll-back the nested transaction and perform
# a lookup instead to retrieve the record.
def create_record
- subject.transaction(requires_new: true) do
+ subject.transaction(requires_new: true) do # rubocop:disable Performance/ActiveRecordSubtransactions
InternalId.create!(
**scope,
usage: usage_value,
diff --git a/lib/gitlab/background_migration/backfill_iteration_cadence_id_for_boards.rb b/lib/gitlab/background_migration/backfill_iteration_cadence_id_for_boards.rb
new file mode 100644
index 00000000000..67f4690868e
--- /dev/null
+++ b/lib/gitlab/background_migration/backfill_iteration_cadence_id_for_boards.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module BackgroundMigration
+ # rubocop: disable Style/Documentation
+ class BackfillIterationCadenceIdForBoards
+ def perform(*args)
+ end
+ end
+ end
+end
+
+Gitlab::BackgroundMigration::BackfillIterationCadenceIdForBoards.prepend_mod_with('Gitlab::BackgroundMigration::BackfillIterationCadenceIdForBoards')
diff --git a/lib/gitlab/background_migration/backfill_project_repositories.rb b/lib/gitlab/background_migration/backfill_project_repositories.rb
index f5c8796bd18..a9eaeb0562d 100644
--- a/lib/gitlab/background_migration/backfill_project_repositories.rb
+++ b/lib/gitlab/background_migration/backfill_project_repositories.rb
@@ -21,7 +21,7 @@ module Gitlab
shard_id = shards.fetch(name, nil)
return shard_id if shard_id.present?
- Shard.transaction(requires_new: true) do
+ Shard.transaction(requires_new: true) do # rubocop:disable Performance/ActiveRecordSubtransactions
create!(name)
end
rescue ActiveRecord::RecordNotUnique
diff --git a/lib/gitlab/background_migration/backfill_projects_with_coverage.rb b/lib/gitlab/background_migration/backfill_projects_with_coverage.rb
new file mode 100644
index 00000000000..ca262c0bd59
--- /dev/null
+++ b/lib/gitlab/background_migration/backfill_projects_with_coverage.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module BackgroundMigration
+ # Backfill project_ci_feature_usages for a range of projects with coverage
+ class BackfillProjectsWithCoverage
+ class ProjectCiFeatureUsage < ActiveRecord::Base # rubocop:disable Style/Documentation
+ self.table_name = 'project_ci_feature_usages'
+ end
+
+ COVERAGE_ENUM_VALUE = 1
+ INSERT_DELAY_SECONDS = 0.1
+
+ def perform(start_id, end_id, sub_batch_size)
+ report_results = ActiveRecord::Base.connection.execute <<~SQL
+ SELECT DISTINCT project_id, default_branch
+ FROM ci_daily_build_group_report_results
+ WHERE id BETWEEN #{start_id} AND #{end_id}
+ SQL
+
+ report_results.to_a.in_groups_of(sub_batch_size, false) do |batch|
+ ProjectCiFeatureUsage.insert_all(build_values(batch))
+
+ sleep INSERT_DELAY_SECONDS
+ end
+ end
+
+ private
+
+ def build_values(batch)
+ batch.map do |data|
+ {
+ project_id: data['project_id'],
+ feature: COVERAGE_ENUM_VALUE,
+ default_branch: data['default_branch']
+ }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/background_migration/extract_project_topics_into_separate_table.rb b/lib/gitlab/background_migration/extract_project_topics_into_separate_table.rb
new file mode 100644
index 00000000000..31b5b5cdb73
--- /dev/null
+++ b/lib/gitlab/background_migration/extract_project_topics_into_separate_table.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module BackgroundMigration
+ # The class to extract the project topics into a separate `topics` table
+ class ExtractProjectTopicsIntoSeparateTable
+ # Temporary AR table for tags
+ class Tag < ActiveRecord::Base
+ self.table_name = 'tags'
+ end
+
+ # Temporary AR table for taggings
+ class Tagging < ActiveRecord::Base
+ self.table_name = 'taggings'
+ belongs_to :tag
+ end
+
+ # Temporary AR table for topics
+ class Topic < ActiveRecord::Base
+ self.table_name = 'topics'
+ end
+
+ # Temporary AR table for project topics
+ class ProjectTopic < ActiveRecord::Base
+ self.table_name = 'project_topics'
+ belongs_to :topic
+ end
+
+ # Temporary AR table for projects
+ class Project < ActiveRecord::Base
+ self.table_name = 'projects'
+ end
+
+ def perform(start_id, stop_id)
+ Tagging.includes(:tag).where(taggable_type: 'Project', id: start_id..stop_id).each do |tagging|
+ if Project.exists?(id: tagging.taggable_id) && tagging.tag
+ begin
+ topic = Topic.find_or_create_by(name: tagging.tag.name)
+ project_topic = ProjectTopic.find_or_create_by(project_id: tagging.taggable_id, topic: topic)
+
+ tagging.delete if project_topic.persisted?
+ rescue StandardError => e
+ Gitlab::ErrorTracking.log_exception(e, tagging_id: tagging.id)
+ end
+ else
+ tagging.delete
+ end
+ end
+
+ mark_job_as_succeeded(start_id, stop_id)
+ end
+
+ private
+
+ def mark_job_as_succeeded(*arguments)
+ Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
+ self.class.name.demodulize,
+ arguments
+ )
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/background_migration/mailers/unconfirm_mailer.rb b/lib/gitlab/background_migration/mailers/unconfirm_mailer.rb
index c096dae0631..3605b157f4f 100644
--- a/lib/gitlab/background_migration/mailers/unconfirm_mailer.rb
+++ b/lib/gitlab/background_migration/mailers/unconfirm_mailer.rb
@@ -14,7 +14,7 @@ module Gitlab
mail(
template_path: 'unconfirm_mailer',
template_name: 'unconfirm_notification_email',
- to: @user.notification_email,
+ to: @user.notification_email_or_default,
subject: subject('GitLab email verification request')
)
end
diff --git a/lib/gitlab/background_migration/migrate_merge_request_diff_commit_users.rb b/lib/gitlab/background_migration/migrate_merge_request_diff_commit_users.rb
index e694e5359cd..7d150b9cd83 100644
--- a/lib/gitlab/background_migration/migrate_merge_request_diff_commit_users.rb
+++ b/lib/gitlab/background_migration/migrate_merge_request_diff_commit_users.rb
@@ -14,7 +14,7 @@ module Gitlab
# The number of rows in merge_request_diff_commits to get in a single
# query.
- COMMIT_ROWS_PER_QUERY = 10_000
+ COMMIT_ROWS_PER_QUERY = 1_000
# The number of rows in merge_request_diff_commits to update in a single
# query.
@@ -78,6 +78,8 @@ module Gitlab
# rubocop: enable Style/Documentation
def perform(start_id, stop_id)
+ return if already_processed?(start_id, stop_id)
+
# This Hash maps user names + emails to their corresponding rows in
# merge_request_diff_commit_users.
user_mapping = {}
@@ -94,6 +96,13 @@ module Gitlab
)
end
+ def already_processed?(start_id, stop_id)
+ Database::BackgroundMigrationJob
+ .for_migration_execution('MigrateMergeRequestDiffCommitUsers', [start_id, stop_id])
+ .succeeded
+ .any?
+ end
+
# Returns the data we'll use to determine what merge_request_diff_commits
# rows to update, and what data to use for populating their
# commit_author_id and committer_id columns.
diff --git a/lib/gitlab/background_migration/steal_migrate_merge_request_diff_commit_users.rb b/lib/gitlab/background_migration/steal_migrate_merge_request_diff_commit_users.rb
new file mode 100644
index 00000000000..43a7032e682
--- /dev/null
+++ b/lib/gitlab/background_migration/steal_migrate_merge_request_diff_commit_users.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module BackgroundMigration
+ # A background migration that finished any pending
+ # MigrateMergeRequestDiffCommitUsers jobs, and schedules new jobs itself.
+ #
+ # This migration exists so we can bypass rescheduling issues (e.g. jobs
+ # getting dropped after too many retries) that may occur when
+ # MigrateMergeRequestDiffCommitUsers jobs take longer than expected.
+ class StealMigrateMergeRequestDiffCommitUsers
+ def perform(start_id, stop_id)
+ MigrateMergeRequestDiffCommitUsers.new.perform(start_id, stop_id)
+ schedule_next_job
+ end
+
+ def schedule_next_job
+ next_job = Database::BackgroundMigrationJob
+ .for_migration_class('MigrateMergeRequestDiffCommitUsers')
+ .pending
+ .first
+
+ return unless next_job
+
+ BackgroundMigrationWorker.perform_in(
+ 5.minutes,
+ 'StealMigrateMergeRequestDiffCommitUsers',
+ next_job.arguments
+ )
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/bitbucket_server_import/importer.rb b/lib/gitlab/bitbucket_server_import/importer.rb
index 2c60b2e36cb..e0eee64dc58 100644
--- a/lib/gitlab/bitbucket_server_import/importer.rb
+++ b/lib/gitlab/bitbucket_server_import/importer.rb
@@ -56,7 +56,7 @@ module Gitlab
log_info(stage: "complete")
- Gitlab::Cache::Import::Caching.expire(already_imported_cache_key, 15.minutes.to_i)
+ Gitlab::Cache::Import::Caching.expire(already_imported_cache_key, Gitlab::Cache::Import::Caching::SHORTER_TIMEOUT)
true
end
diff --git a/lib/gitlab/branch_push_merge_commit_analyzer.rb b/lib/gitlab/branch_push_merge_commit_analyzer.rb
index a8f601f2451..ddf2086363c 100644
--- a/lib/gitlab/branch_push_merge_commit_analyzer.rb
+++ b/lib/gitlab/branch_push_merge_commit_analyzer.rb
@@ -114,7 +114,7 @@ module Gitlab
# If child commit is a direct ancestor, its first parent is also a direct ancestor.
# We assume direct ancestors matches the trail of the target branch over time,
# This assumption is correct most of the time, especially for gitlab managed merges,
- # but there are exception cases which can't be solved (https://stackoverflow.com/a/49754723/474597)
+ # but there are exception cases which can't be solved.
def mark_all_direct_ancestors(commit)
loop do
commit = get_commit(commit.parent_ids.first)
diff --git a/lib/gitlab/cache/import/caching.rb b/lib/gitlab/cache/import/caching.rb
index 89c85cb50be..947efee43a9 100644
--- a/lib/gitlab/cache/import/caching.rb
+++ b/lib/gitlab/cache/import/caching.rb
@@ -7,6 +7,10 @@ module Gitlab
# The default timeout of the cache keys.
TIMEOUT = 24.hours.to_i
+ LONGER_TIMEOUT = 72.hours.to_i
+
+ SHORTER_TIMEOUT = 15.minutes.to_i
+
WRITE_IF_GREATER_SCRIPT = <<-EOF.strip_heredoc.freeze
local key, value, ttl = KEYS[1], tonumber(ARGV[1]), ARGV[2]
local existing = tonumber(redis.call("get", key))
diff --git a/lib/gitlab/changelog/config.rb b/lib/gitlab/changelog/config.rb
index 0538fe68474..fd5d701b858 100644
--- a/lib/gitlab/changelog/config.rb
+++ b/lib/gitlab/changelog/config.rb
@@ -34,17 +34,17 @@ module Gitlab
'(?:-(?P<pre>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))' \
'?(?:\+(?P<meta>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$'
- attr_accessor :date_format, :categories, :template, :tag_regex
+ attr_accessor :date_format, :categories, :template, :tag_regex, :always_credit_user_ids
- def self.from_git(project)
+ def self.from_git(project, user = nil)
if (yaml = project.repository.changelog_config)
- from_hash(project, YAML.safe_load(yaml))
+ from_hash(project, YAML.safe_load(yaml), user)
else
new(project)
end
end
- def self.from_hash(project, hash)
+ def self.from_hash(project, hash, user = nil)
config = new(project)
if (date = hash['date_format'])
@@ -72,6 +72,14 @@ module Gitlab
config.tag_regex = regex
end
+ config.always_credit_user_ids = Set.new
+ if (group_paths = Array(hash['include_groups']))
+ group_paths.each do |group_path|
+ group = Group.find_by_full_path(group_path)
+ config.always_credit_user_ids.merge(group&.users_ids_of_direct_members&.compact) if user&.can?(:read_group, group)
+ end
+ end
+
config
end
@@ -89,7 +97,11 @@ module Gitlab
end
def contributor?(user)
- @project.team.contributor?(user)
+ @project.team.contributor?(user&.id)
+ end
+
+ def always_credit_author?(user)
+ always_credit_user_ids&.include?(user&.id) || false
end
def category(name)
diff --git a/lib/gitlab/changelog/release.rb b/lib/gitlab/changelog/release.rb
index c0b6a5c5679..a0d598c7464 100644
--- a/lib/gitlab/changelog/release.rb
+++ b/lib/gitlab/changelog/release.rb
@@ -42,6 +42,7 @@ module Gitlab
'reference' => author.to_reference(full: true),
'contributor' => @config.contributor?(author)
}
+ entry['author']['credit'] = entry['author']['contributor'] || @config.always_credit_author?(author)
end
if merge_request
diff --git a/lib/gitlab/changelog/template.tpl b/lib/gitlab/changelog/template.tpl
index 584939dff51..68c1c624394 100644
--- a/lib/gitlab/changelog/template.tpl
+++ b/lib/gitlab/changelog/template.tpl
@@ -4,7 +4,7 @@
{% each entries %}
- [{{ title }}]({{ commit.reference }})\
-{% if author.contributor %} by {{ author.reference }}{% end %}\
+{% if author.credit %} by {{ author.reference }}{% end %}\
{% if merge_request %} ([merge request]({{ merge_request.reference }})){% end %}
{% end %}
diff --git a/lib/gitlab/checks/base_single_checker.rb b/lib/gitlab/checks/base_single_checker.rb
index f93902055c9..06519833d7c 100644
--- a/lib/gitlab/checks/base_single_checker.rb
+++ b/lib/gitlab/checks/base_single_checker.rb
@@ -30,5 +30,3 @@ module Gitlab
end
end
end
-
-Gitlab::Checks::BaseSingleChecker.prepend_mod_with('Gitlab::Checks::BaseSingleChecker')
diff --git a/lib/gitlab/checks/changes_access.rb b/lib/gitlab/checks/changes_access.rb
index 9ecc93f871b..3ce2e50c548 100644
--- a/lib/gitlab/checks/changes_access.rb
+++ b/lib/gitlab/checks/changes_access.rb
@@ -76,23 +76,33 @@ module Gitlab
result
end
+ def single_change_accesses
+ @single_changes_accesses ||=
+ changes.map do |change|
+ commits =
+ if change[:newrev].blank? || Gitlab::Git.blank_ref?(change[:newrev])
+ []
+ else
+ Gitlab::Lazy.new { commits_for(change[:newrev]) }
+ end
+
+ Checks::SingleChangeAccess.new(
+ change,
+ user_access: user_access,
+ project: project,
+ protocol: protocol,
+ logger: logger,
+ commits: commits
+ )
+ end
+ end
+
protected
def single_access_checks!
# Iterate over all changes to find if user allowed all of them to be applied
- changes.each do |change|
- commits = Gitlab::Lazy.new { commits_for(change[:newrev]) } if Feature.enabled?(:changes_batch_commits)
-
- # If user does not have access to make at least one change, cancel all
- # push by allowing the exception to bubble up
- Checks::SingleChangeAccess.new(
- change,
- user_access: user_access,
- project: project,
- protocol: protocol,
- logger: logger,
- commits: commits
- ).validate!
+ single_change_accesses.each do |single_change_access|
+ single_change_access.validate!
end
end
@@ -102,3 +112,5 @@ module Gitlab
end
end
end
+
+Gitlab::Checks::ChangesAccess.prepend_mod_with('Gitlab::Checks::ChangesAccess')
diff --git a/lib/gitlab/ci/artifact_file_reader.rb b/lib/gitlab/ci/artifact_file_reader.rb
index d576953c1a0..3cfed8e5e2c 100644
--- a/lib/gitlab/ci/artifact_file_reader.rb
+++ b/lib/gitlab/ci/artifact_file_reader.rb
@@ -45,7 +45,7 @@ module Gitlab
end
def read_zip_file!(file_path)
- if ::Feature.enabled?(:ci_new_artifact_file_reader, job.project, default_enabled: false)
+ if ::Feature.enabled?(:ci_new_artifact_file_reader, job.project, default_enabled: :yaml)
read_with_new_artifact_file_reader(file_path)
else
read_with_legacy_artifact_file_reader(file_path)
diff --git a/lib/gitlab/ci/config/entry/default.rb b/lib/gitlab/ci/config/entry/default.rb
index eaaf9f69102..145772c7a92 100644
--- a/lib/gitlab/ci/config/entry/default.rb
+++ b/lib/gitlab/ci/config/entry/default.rb
@@ -53,7 +53,7 @@ module Gitlab
description: 'Set retry default value.',
inherit: false
- entry :tags, ::Gitlab::Config::Entry::ArrayOfStrings,
+ entry :tags, Entry::Tags,
description: 'Set the default tags.',
inherit: false
diff --git a/lib/gitlab/ci/config/entry/job.rb b/lib/gitlab/ci/config/entry/job.rb
index bd4d5f33689..f867189d521 100644
--- a/lib/gitlab/ci/config/entry/job.rb
+++ b/lib/gitlab/ci/config/entry/job.rb
@@ -85,7 +85,7 @@ module Gitlab
description: 'Retry configuration for this job.',
inherit: true
- entry :tags, ::Gitlab::Config::Entry::ArrayOfStrings,
+ entry :tags, Entry::Tags,
description: 'Set the tags.',
inherit: true
diff --git a/lib/gitlab/ci/config/entry/processable.rb b/lib/gitlab/ci/config/entry/processable.rb
index 3543b5493bd..2549c35ebd6 100644
--- a/lib/gitlab/ci/config/entry/processable.rb
+++ b/lib/gitlab/ci/config/entry/processable.rb
@@ -16,6 +16,7 @@ module Gitlab
PROCESSABLE_ALLOWED_KEYS = %i[extends stage only except rules variables
inherit allow_failure when needs resource_group].freeze
+ MAX_NESTING_LEVEL = 10
included do
validations do
@@ -31,7 +32,7 @@ module Gitlab
with_options allow_nil: true do
validates :extends, array_of_strings_or_string: true
- validates :rules, nested_array_of_hashes: true
+ validates :rules, nested_array_of_hashes_or_arrays: { max_level: MAX_NESTING_LEVEL }
validates :resource_group, type: String
end
end
diff --git a/lib/gitlab/ci/config/entry/tags.rb b/lib/gitlab/ci/config/entry/tags.rb
new file mode 100644
index 00000000000..ca3b48372e2
--- /dev/null
+++ b/lib/gitlab/ci/config/entry/tags.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class Config
+ module Entry
+ ##
+ # Entry that represents an array of tags.
+ #
+ class Tags < ::Gitlab::Config::Entry::Node
+ include ::Gitlab::Config::Entry::Validatable
+
+ TAGS_LIMIT = 50
+
+ validations do
+ validates :config, array_of_strings: true
+
+ validate do
+ next unless ::Feature.enabled?(:ci_build_tags_limit, default_enabled: :yaml)
+
+ if config.is_a?(Array) && config.size >= TAGS_LIMIT
+ errors.add(:config, _("must be less than the limit of %{tag_limit} tags") % { tag_limit: TAGS_LIMIT })
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/cron_parser.rb b/lib/gitlab/ci/cron_parser.rb
index bc03658aab8..7334a112ccf 100644
--- a/lib/gitlab/ci/cron_parser.rb
+++ b/lib/gitlab/ci/cron_parser.rb
@@ -6,8 +6,40 @@ module Gitlab
VALID_SYNTAX_SAMPLE_TIME_ZONE = 'UTC'
VALID_SYNTAX_SAMPLE_CRON = '* * * * *'
- def self.parse_natural(expression, cron_timezone = 'UTC')
- new(Fugit::Nat.parse(expression)&.original, cron_timezone)
+ class << self
+ def parse_natural(expression, cron_timezone = 'UTC')
+ new(Fugit::Nat.parse(expression)&.original, cron_timezone)
+ end
+
+ # This method generates compatible expressions that can be
+ # parsed by Fugit::Nat.parse to generate a cron line.
+ # It takes start date of the cron and cadence in the following format:
+ # cadence = {
+ # unit: 'day/week/month/year'
+ # duration: 1
+ # }
+ def parse_natural_with_timestamp(starts_at, cadence)
+ case cadence[:unit]
+ when 'day' # Currently supports only 'every 1 day'.
+ "#{starts_at.min} #{starts_at.hour} * * *"
+ when 'week' # Currently supports only 'every 1 week'.
+ "#{starts_at.min} #{starts_at.hour} * * #{starts_at.wday}"
+ when 'month'
+ unless [1, 3, 6, 12].include?(cadence[:duration])
+ raise NotImplementedError, "The cadence #{cadence} is not supported"
+ end
+
+ "#{starts_at.min} #{starts_at.hour} #{starts_at.mday} #{fall_in_months(cadence[:duration], starts_at)} *"
+ when 'year' # Currently supports only 'every 1 year'.
+ "#{starts_at.min} #{starts_at.hour} #{starts_at.mday} #{starts_at.month} *"
+ else
+ raise NotImplementedError, "The cadence unit #{cadence[:unit]} is not implemented"
+ end
+ end
+
+ def fall_in_months(offset, start_date)
+ (1..(12 / offset)).map { |i| start_date.next_month(offset * i).month }.join(',')
+ end
end
def initialize(cron, cron_timezone = 'UTC')
diff --git a/lib/gitlab/ci/lint.rb b/lib/gitlab/ci/lint.rb
index cd2c135dd7e..8c1067b9bc6 100644
--- a/lib/gitlab/ci/lint.rb
+++ b/lib/gitlab/ci/lint.rb
@@ -21,7 +21,7 @@ module Gitlab
def initialize(project:, current_user:, sha: nil)
@project = project
@current_user = current_user
- @sha = sha || project.repository.commit&.sha
+ @sha = sha || project&.repository&.commit&.sha
end
def validate(content, dry_run: false)
diff --git a/lib/gitlab/ci/parsers/security/common.rb b/lib/gitlab/ci/parsers/security/common.rb
index 41acb4d5040..1cf4f252ab9 100644
--- a/lib/gitlab/ci/parsers/security/common.rb
+++ b/lib/gitlab/ci/parsers/security/common.rb
@@ -86,6 +86,7 @@ module Gitlab
def create_finding(data, remediations = [])
identifiers = create_identifiers(data['identifiers'])
+ flags = create_flags(data['flags'])
links = create_links(data['links'])
location = create_location(data['location'] || {})
signatures = create_signatures(tracking_data(data))
@@ -111,6 +112,7 @@ module Gitlab
scanner: create_scanner(data['scanner']),
scan: report&.scan,
identifiers: identifiers,
+ flags: flags,
links: links,
remediations: remediations,
raw_metadata: data.to_json,
@@ -205,6 +207,18 @@ module Gitlab
url: identifier['url']))
end
+ def create_flags(flags)
+ return [] unless flags.is_a?(Array)
+
+ flags.map { |flag| create_flag(flag) }.compact
+ end
+
+ def create_flag(flag)
+ return unless flag.is_a?(Hash)
+
+ ::Gitlab::Ci::Reports::Security::Flag.new(type: flag['type'], origin: flag['origin'], description: flag['description'])
+ end
+
def create_links(links)
return [] unless links.is_a?(Array)
diff --git a/lib/gitlab/ci/parsers/security/validators/schema_validator.rb b/lib/gitlab/ci/parsers/security/validators/schema_validator.rb
index 3d92886cba8..143b930c669 100644
--- a/lib/gitlab/ci/parsers/security/validators/schema_validator.rb
+++ b/lib/gitlab/ci/parsers/security/validators/schema_validator.rb
@@ -12,7 +12,7 @@ module Gitlab
end
def initialize(report_type)
- @report_type = report_type
+ @report_type = report_type.to_sym
end
delegate :validate, to: :schemer
diff --git a/lib/gitlab/ci/pipeline/chain/build.rb b/lib/gitlab/ci/pipeline/chain/build.rb
index d3bc3a38f1f..6feb693221b 100644
--- a/lib/gitlab/ci/pipeline/chain/build.rb
+++ b/lib/gitlab/ci/pipeline/chain/build.rb
@@ -5,9 +5,6 @@ module Gitlab
module Pipeline
module Chain
class Build < Chain::Base
- include Gitlab::Allowable
- include Chain::Helpers
-
def perform!
@pipeline.assign_attributes(
source: @command.source,
@@ -23,35 +20,12 @@ module Gitlab
pipeline_schedule: @command.schedule,
merge_request: @command.merge_request,
external_pull_request: @command.external_pull_request,
- locked: @command.project.default_pipeline_lock,
- variables_attributes: variables_attributes
- )
+ locked: @command.project.default_pipeline_lock)
end
def break?
@pipeline.errors.any?
end
-
- private
-
- def variables_attributes
- variables = Array(@command.variables_attributes)
-
- # We allow parent pipelines to pass variables to child pipelines since
- # these variables are coming from internal configurations. We will check
- # permissions to :set_pipeline_variables when those are injected upstream,
- # to the parent pipeline.
- # In other scenarios (e.g. multi-project pipelines or run pipeline via UI)
- # the variables are provided from the outside and those should be guarded.
- return variables if @command.creates_child_pipeline?
-
- if variables.present? && !can?(@command.current_user, :set_pipeline_variables, @command.project)
- error("Insufficient permissions to set pipeline variables")
- variables = []
- end
-
- variables
- end
end
end
end
diff --git a/lib/gitlab/ci/pipeline/chain/build/associations.rb b/lib/gitlab/ci/pipeline/chain/build/associations.rb
index eb49c56bcd7..b5d63691849 100644
--- a/lib/gitlab/ci/pipeline/chain/build/associations.rb
+++ b/lib/gitlab/ci/pipeline/chain/build/associations.rb
@@ -6,7 +6,25 @@ module Gitlab
module Chain
class Build
class Associations < Chain::Base
+ include Gitlab::Allowable
+ include Chain::Helpers
+
def perform!
+ assign_pipeline_variables
+ assign_source_pipeline
+ end
+
+ def break?
+ @pipeline.errors.any?
+ end
+
+ private
+
+ def assign_pipeline_variables
+ @pipeline.variables_attributes = variables_attributes
+ end
+
+ def assign_source_pipeline
return unless @command.bridge
@pipeline.build_source_pipeline(
@@ -17,8 +35,45 @@ module Gitlab
)
end
- def break?
- false
+ def variables_attributes
+ variables = Array(@command.variables_attributes)
+ variables = apply_permissions(variables)
+ validate_uniqueness(variables)
+ end
+
+ def apply_permissions(variables)
+ # We allow parent pipelines to pass variables to child pipelines since
+ # these variables are coming from internal configurations. We will check
+ # permissions to :set_pipeline_variables when those are injected upstream,
+ # to the parent pipeline.
+ # In other scenarios (e.g. multi-project pipelines or run pipeline via UI)
+ # the variables are provided from the outside and those should be guarded.
+ return variables if @command.creates_child_pipeline?
+
+ if variables.present? && !can?(@command.current_user, :set_pipeline_variables, @command.project)
+ error("Insufficient permissions to set pipeline variables")
+ variables = []
+ end
+
+ variables
+ end
+
+ def validate_uniqueness(variables)
+ duplicated_keys = variables
+ .map { |var| var[:key] }
+ .tally
+ .filter_map { |key, count| key if count > 1 }
+
+ if duplicated_keys.empty?
+ variables
+ else
+ error(duplicate_variables_message(duplicated_keys), config_error: true)
+ []
+ end
+ end
+
+ def duplicate_variables_message(keys)
+ "Duplicate variable #{'name'.pluralize(keys.size)}: #{keys.join(', ')}"
end
end
end
diff --git a/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb b/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb
index 1c0dfbdbee3..f637001f9f8 100644
--- a/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb
+++ b/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb
@@ -7,15 +7,19 @@ module Gitlab
class CancelPendingPipelines < Chain::Base
include Chain::Helpers
+ BATCH_SIZE = 25
+
+ # rubocop: disable CodeReuse/ActiveRecord
def perform!
return unless project.auto_cancel_pending_pipelines?
Gitlab::OptimisticLocking.retry_lock(auto_cancelable_pipelines, name: 'cancel_pending_pipelines') do |cancelables|
- cancelables.find_each do |cancelable|
- cancelable.auto_cancel_running(pipeline)
+ cancelables.select(:id).each_batch(of: BATCH_SIZE) do |cancelables_batch|
+ auto_cancel_interruptible_pipelines(cancelables_batch.ids)
end
end
end
+ # rubocop: enable CodeReuse/ActiveRecord
def break?
false
@@ -23,16 +27,21 @@ module Gitlab
private
- # rubocop: disable CodeReuse/ActiveRecord
def auto_cancelable_pipelines
- project.all_pipelines.ci_and_parent_sources
- .where(ref: pipeline.ref)
- .where.not(id: pipeline.same_family_pipeline_ids)
- .where.not(sha: project.commit(pipeline.ref).try(:id))
+ project.all_pipelines.created_after(1.week.ago)
+ .ci_and_parent_sources
+ .for_ref(pipeline.ref)
+ .id_not_in(pipeline.same_family_pipeline_ids)
+ .where_not_sha(project.commit(pipeline.ref).try(:id))
.alive_or_scheduled
+ end
+
+ def auto_cancel_interruptible_pipelines(pipeline_ids)
+ ::Ci::Pipeline
+ .id_in(pipeline_ids)
.with_only_interruptible_builds
+ .each { |cancelable| cancelable.auto_cancel_running(pipeline) }
end
- # rubocop: enable CodeReuse/ActiveRecord
end
end
end
diff --git a/lib/gitlab/ci/pipeline/chain/command.rb b/lib/gitlab/ci/pipeline/chain/command.rb
index 626eba97817..c9bc4ec411d 100644
--- a/lib/gitlab/ci/pipeline/chain/command.rb
+++ b/lib/gitlab/ci/pipeline/chain/command.rb
@@ -87,6 +87,13 @@ module Gitlab
@metrics ||= ::Gitlab::Ci::Pipeline::Metrics
end
+ def observe_step_duration(step_class, duration)
+ if Feature.enabled?(:ci_pipeline_creation_step_duration_tracking, type: :ops, default_enabled: :yaml)
+ metrics.pipeline_creation_step_duration_histogram
+ .observe({ step: step_class.name }, duration.seconds)
+ end
+ end
+
def observe_creation_duration(duration)
metrics.pipeline_creation_duration_histogram
.observe({}, duration.seconds)
diff --git a/lib/gitlab/ci/pipeline/chain/config/content/external_project.rb b/lib/gitlab/ci/pipeline/chain/config/content/external_project.rb
index 8a19e433483..092e7d43371 100644
--- a/lib/gitlab/ci/pipeline/chain/config/content/external_project.rb
+++ b/lib/gitlab/ci/pipeline/chain/config/content/external_project.rb
@@ -11,8 +11,12 @@ module Gitlab
strong_memoize(:content) do
next unless external_project_path?
- path_file, path_project = ci_config_path.split('@', 2)
- YAML.dump('include' => [{ 'project' => path_project, 'file' => path_file }])
+ path_file, path_project, ref = extract_location_tokens
+
+ config_location = { 'project' => path_project, 'file' => path_file }
+ config_location['ref'] = ref if ref.present?
+
+ YAML.dump('include' => [config_location])
end
end
@@ -26,6 +30,18 @@ module Gitlab
def external_project_path?
ci_config_path =~ /\A.+(yml|yaml)@.+\z/
end
+
+ # Example: path/to/.gitlab-ci.yml@another-group/another-project:refname
+ def extract_location_tokens
+ path_file, path_project = ci_config_path.split('@', 2)
+
+ if path_project.include? ":"
+ project, ref = path_project.split(':', 2)
+ [path_file, project, ref]
+ else
+ [path_file, path_project]
+ end
+ end
end
end
end
diff --git a/lib/gitlab/ci/pipeline/chain/sequence.rb b/lib/gitlab/ci/pipeline/chain/sequence.rb
index bbfc6759b35..845eb6c7a42 100644
--- a/lib/gitlab/ci/pipeline/chain/sequence.rb
+++ b/lib/gitlab/ci/pipeline/chain/sequence.rb
@@ -14,9 +14,16 @@ module Gitlab
def build!
@sequence.each do |step_class|
+ step_start = ::Gitlab::Metrics::System.monotonic_time
step = step_class.new(@pipeline, @command)
step.perform!
+
+ @command.observe_step_duration(
+ step_class,
+ ::Gitlab::Metrics::System.monotonic_time - step_start
+ )
+
break if step.break?
end
diff --git a/lib/gitlab/ci/pipeline/metrics.rb b/lib/gitlab/ci/pipeline/metrics.rb
index 10de77afe74..28df9f5386c 100644
--- a/lib/gitlab/ci/pipeline/metrics.rb
+++ b/lib/gitlab/ci/pipeline/metrics.rb
@@ -4,6 +4,8 @@ module Gitlab
module Ci
module Pipeline
class Metrics
+ extend Gitlab::Utils::StrongMemoize
+
def self.pipeline_creation_duration_histogram
name = :gitlab_ci_pipeline_creation_duration_seconds
comment = 'Pipeline creation duration'
@@ -13,6 +15,17 @@ module Gitlab
::Gitlab::Metrics.histogram(name, comment, labels, buckets)
end
+ def self.pipeline_creation_step_duration_histogram
+ strong_memoize(:pipeline_creation_step_histogram) do
+ name = :gitlab_ci_pipeline_creation_step_duration_seconds
+ comment = 'Duration of each pipeline creation step'
+ labels = { step: nil }
+ buckets = [0.01, 0.05, 0.1, 0.5, 1.0, 2.0, 5.0, 10.0, 15.0, 20.0, 50.0, 240.0]
+
+ ::Gitlab::Metrics.histogram(name, comment, labels, buckets)
+ end
+ end
+
def self.pipeline_security_orchestration_policy_processing_duration_histogram
name = :gitlab_ci_pipeline_security_orchestration_policy_processing_duration_seconds
comment = 'Pipeline security orchestration policy processing duration'
diff --git a/lib/gitlab/ci/pipeline/seed/build.rb b/lib/gitlab/ci/pipeline/seed/build.rb
index c393fed26de..934bf22d8ad 100644
--- a/lib/gitlab/ci/pipeline/seed/build.rb
+++ b/lib/gitlab/ci/pipeline/seed/build.rb
@@ -15,12 +15,7 @@ module Gitlab
@context = context
@pipeline = context.pipeline
@seed_attributes = attributes
- @stages_for_needs_lookup = if Feature.enabled?(:ci_same_stage_job_needs, @pipeline.project, default_enabled: :yaml)
- (previous_stages + [current_stage]).compact
- else
- previous_stages
- end
-
+ @stages_for_needs_lookup = (previous_stages + [current_stage]).compact
@needs_attributes = dig(:needs_attributes)
@resource_group_key = attributes.delete(:resource_group_key)
@job_variables = @seed_attributes.delete(:job_variables)
@@ -123,6 +118,8 @@ module Gitlab
return { environment: nil }
end
+ build.persisted_environment = environment
+
{
deployment: Seed::Deployment.new(build, environment).to_resource,
metadata_attributes: {
diff --git a/lib/gitlab/ci/pipeline/seed/processable/resource_group.rb b/lib/gitlab/ci/pipeline/seed/processable/resource_group.rb
index f8ea6d4184c..a29fef6eb34 100644
--- a/lib/gitlab/ci/pipeline/seed/processable/resource_group.rb
+++ b/lib/gitlab/ci/pipeline/seed/processable/resource_group.rb
@@ -28,7 +28,16 @@ module Gitlab
def expanded_resource_group_key
strong_memoize(:expanded_resource_group_key) do
- ExpandVariables.expand(resource_group_key, -> { processable.simple_variables })
+ ExpandVariables.expand(resource_group_key, -> { variables })
+ end
+ end
+
+ def variables
+ processable.simple_variables.tap do |variables|
+ # Adding persisted environment variables
+ if processable.persisted_environment.present?
+ variables.concat(processable.persisted_environment.predefined_variables)
+ end
end
end
end
diff --git a/lib/gitlab/ci/queue/metrics.rb b/lib/gitlab/ci/queue/metrics.rb
index 859aeb35f26..7f45d626922 100644
--- a/lib/gitlab/ci/queue/metrics.rb
+++ b/lib/gitlab/ci/queue/metrics.rb
@@ -97,7 +97,9 @@ module Gitlab
def observe_queue_size(size_proc, runner_type)
return unless Feature.enabled?(:gitlab_ci_builds_queuing_metrics, default_enabled: false)
- self.class.queue_size_total.observe({ runner_type: runner_type }, size_proc.call.to_f)
+ size = size_proc.call.to_f
+ self.class.queue_size_total.observe({ runner_type: runner_type }, size)
+ self.class.current_queue_size.set({ runner_type: runner_type }, size)
end
def observe_queue_time(metric, runner_type)
@@ -199,6 +201,15 @@ module Gitlab
end
end
+ def self.current_queue_size
+ strong_memoize(:current_queue_size) do
+ name = :gitlab_ci_current_queue_size
+ comment = 'Current size of initialized CI/CD builds queue'
+
+ Gitlab::Metrics.gauge(name, comment)
+ end
+ end
+
def self.queue_iteration_duration_seconds
strong_memoize(:queue_iteration_duration_seconds) do
name = :gitlab_ci_queue_iteration_duration_seconds
diff --git a/lib/gitlab/ci/reports/security/finding.rb b/lib/gitlab/ci/reports/security/finding.rb
index dc1c51b3ed0..39531e12f69 100644
--- a/lib/gitlab/ci/reports/security/finding.rb
+++ b/lib/gitlab/ci/reports/security/finding.rb
@@ -10,6 +10,7 @@ module Gitlab
attr_reader :compare_key
attr_reader :confidence
attr_reader :identifiers
+ attr_reader :flags
attr_reader :links
attr_reader :location
attr_reader :metadata_version
@@ -30,10 +31,11 @@ module Gitlab
delegate :file_path, :start_line, :end_line, to: :location
- def initialize(compare_key:, identifiers:, links: [], remediations: [], location:, metadata_version:, name:, raw_metadata:, report_type:, scanner:, scan:, uuid:, confidence: nil, severity: nil, details: {}, signatures: [], project_id: nil, vulnerability_finding_signatures_enabled: false) # rubocop:disable Metrics/ParameterLists
+ def initialize(compare_key:, identifiers:, flags: [], links: [], remediations: [], location:, metadata_version:, name:, raw_metadata:, report_type:, scanner:, scan:, uuid:, confidence: nil, severity: nil, details: {}, signatures: [], project_id: nil, vulnerability_finding_signatures_enabled: false) # rubocop:disable Metrics/ParameterLists
@compare_key = compare_key
@confidence = confidence
@identifiers = identifiers
+ @flags = flags
@links = links
@location = location
@metadata_version = metadata_version
@@ -58,6 +60,7 @@ module Gitlab
compare_key
confidence
identifiers
+ flags
links
location
metadata_version
diff --git a/lib/gitlab/ci/reports/security/flag.rb b/lib/gitlab/ci/reports/security/flag.rb
new file mode 100644
index 00000000000..7e6cc758864
--- /dev/null
+++ b/lib/gitlab/ci/reports/security/flag.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Reports
+ module Security
+ class Flag
+ attr_reader :type, :origin, :description
+
+ MAP = { 'flagged-as-likely-false-positive' => :false_positive }.freeze
+ DEFAULT_FLAG_TYPE = :false_positive
+
+ def flag_type
+ MAP.fetch(type, DEFAULT_FLAG_TYPE)
+ end
+
+ def initialize(type: nil, origin: nil, description: nil)
+ @type = type
+ @origin = origin
+ @description = description
+ end
+
+ def to_hash
+ {
+ flag_type: flag_type,
+ origin: origin,
+ description: description
+ }.compact
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/status/build/failed.rb b/lib/gitlab/ci/status/build/failed.rb
index dbbb9a01dab..ee210e51232 100644
--- a/lib/gitlab/ci/status/build/failed.rb
+++ b/lib/gitlab/ci/status/build/failed.rb
@@ -32,7 +32,8 @@ module Gitlab
user_blocked: 'pipeline user was blocked',
ci_quota_exceeded: 'no more CI minutes available',
no_matching_runner: 'no matching runner available',
- trace_size_exceeded: 'log size limit exceeded'
+ trace_size_exceeded: 'log size limit exceeded',
+ builds_disabled: 'project builds are disabled'
}.freeze
private_constant :REASONS
diff --git a/lib/gitlab/ci/templates/Android.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Android.latest.gitlab-ci.yml
new file mode 100644
index 00000000000..9f0e9bcc1f2
--- /dev/null
+++ b/lib/gitlab/ci/templates/Android.latest.gitlab-ci.yml
@@ -0,0 +1,87 @@
+# To contribute improvements to CI/CD templates, please follow the Development guide at:
+# https://docs.gitlab.com/ee/development/cicd/templates.html
+# This specific template is located at:
+# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Android.gitlab-ci.yml
+
+# Read more about this script on this blog post https://about.gitlab.com/2018/10/24/setting-up-gitlab-ci-for-android-projects/, by Jason Lenny
+# If you are interested in using Android with FastLane for publishing take a look at the Android-Fastlane template.
+
+image: openjdk:11-jdk
+
+variables:
+
+ # ANDROID_COMPILE_SDK is the version of Android you're compiling with.
+ # It should match compileSdkVersion.
+ ANDROID_COMPILE_SDK: "30"
+
+ # ANDROID_BUILD_TOOLS is the version of the Android build tools you are using.
+ # It should match buildToolsVersion.
+ ANDROID_BUILD_TOOLS: "30.0.3"
+
+ # It's what version of the command line tools we're going to download from the official site.
+ # Official Site-> https://developer.android.com/studio/index.html
+ # There, look down below at the cli tools only, sdk tools package is of format:
+ # commandlinetools-os_type-ANDROID_SDK_TOOLS_latest.zip
+ # when the script was last modified for latest compileSdkVersion, it was which is written down below
+ ANDROID_SDK_TOOLS: "7583922"
+
+# Packages installation before running script
+before_script:
+ - apt-get --quiet update --yes
+ - apt-get --quiet install --yes wget tar unzip lib32stdc++6 lib32z1
+
+ # Setup path as ANDROID_SDK_ROOT for moving/exporting the downloaded sdk into it
+ - export ANDROID_SDK_ROOT="${PWD}/android-home"
+ # Create a new directory at specified location
+ - install -d $ANDROID_SDK_ROOT
+ # Here we are installing androidSDK tools from official source,
+ # (the key thing here is the url from where you are downloading these sdk tool for command line, so please do note this url pattern there and here as well)
+ # after that unzipping those tools and
+ # then running a series of SDK manager commands to install necessary android SDK packages that'll allow the app to build
+ - wget --output-document=$ANDROID_SDK_ROOT/cmdline-tools.zip https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS}_latest.zip
+ # move to the archive at ANDROID_SDK_ROOT
+ - pushd $ANDROID_SDK_ROOT
+ - unzip -d cmdline-tools cmdline-tools.zip
+ - pushd cmdline-tools
+ # since commandline tools version 7583922 the root folder is named "cmdline-tools" so we rename it if necessary
+ - mv cmdline-tools tools || true
+ - popd
+ - popd
+ - export PATH=$PATH:${ANDROID_SDK_ROOT}/cmdline-tools/tools/bin/
+
+ # Nothing fancy here, just checking sdkManager version
+ - sdkmanager --version
+
+ # use yes to accept all licenses
+ - yes | sdkmanager --licenses || true
+ - sdkmanager "platforms;android-${ANDROID_COMPILE_SDK}"
+ - sdkmanager "platform-tools"
+ - sdkmanager "build-tools;${ANDROID_BUILD_TOOLS}"
+
+ # Not necessary, but just for surity
+ - chmod +x ./gradlew
+
+# Basic android and gradle stuff
+# Check linting
+lintDebug:
+ interruptible: true
+ stage: build
+ script:
+ - ./gradlew -Pci --console=plain :app:lintDebug -PbuildDir=lint
+
+# Make Project
+assembleDebug:
+ interruptible: true
+ stage: build
+ script:
+ - ./gradlew assembleDebug
+ artifacts:
+ paths:
+ - app/build/outputs/
+
+# Run all tests, if any fails, interrupt the pipeline(fail it)
+debugTests:
+ interruptible: true
+ stage: test
+ script:
+ - ./gradlew -Pci --console=plain :app:testDebug
diff --git a/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
index cf99d722e4d..5efa557d7eb 100644
--- a/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
@@ -1,6 +1,9 @@
+variables:
+ AUTO_BUILD_IMAGE_VERSION: 'v1.0.0'
+
build:
stage: build
- image: 'registry.gitlab.com/gitlab-org/cluster-integration/auto-build-image:v1.0.0'
+ image: 'registry.gitlab.com/gitlab-org/cluster-integration/auto-build-image:${AUTO_BUILD_IMAGE_VERSION}'
variables:
DOCKER_TLS_CERTDIR: ''
services:
diff --git a/lib/gitlab/ci/templates/Jobs/Build.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Build.latest.gitlab-ci.yml
new file mode 100644
index 00000000000..6a3b0cfa9e7
--- /dev/null
+++ b/lib/gitlab/ci/templates/Jobs/Build.latest.gitlab-ci.yml
@@ -0,0 +1,41 @@
+# WARNING: This latest template is for internal FEATURE-FLAG TESTING ONLY.
+# It is not meant to be used with `include:`.
+# This template is scheduled for removal when testing is complete: https://gitlab.com/gitlab-org/gitlab/-/issues/337987
+
+variables:
+ AUTO_BUILD_IMAGE_VERSION: 'v1.3.1'
+
+build:
+ stage: build
+ image: 'registry.gitlab.com/gitlab-org/cluster-integration/auto-build-image:${AUTO_BUILD_IMAGE_VERSION}'
+ variables:
+ DOCKER_TLS_CERTDIR: ''
+ services:
+ - name: 'docker:20.10.6-dind'
+ command: ['--tls=false', '--host=tcp://0.0.0.0:2375']
+ script:
+ - |
+ if [[ -z "$CI_COMMIT_TAG" ]]; then
+ export CI_APPLICATION_REPOSITORY=${CI_APPLICATION_REPOSITORY:-$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG}
+ export CI_APPLICATION_TAG=${CI_APPLICATION_TAG:-$CI_COMMIT_SHA}
+ else
+ export CI_APPLICATION_REPOSITORY=${CI_APPLICATION_REPOSITORY:-$CI_REGISTRY_IMAGE}
+ export CI_APPLICATION_TAG=${CI_APPLICATION_TAG:-$CI_COMMIT_TAG}
+ fi
+ - /build/build.sh
+ rules:
+ - if: '$BUILD_DISABLED'
+ when: never
+ - if: '$AUTO_DEVOPS_PLATFORM_TARGET == "EC2"'
+ when: never
+ - if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH'
+
+build_artifact:
+ stage: build
+ script:
+ - printf "To build your project, please create a build_artifact job into your .gitlab-ci.yml file.\nMore information at https://docs.gitlab.com/ee/ci/cloud_deployment\n"
+ - exit 1
+ rules:
+ - if: '$BUILD_DISABLED'
+ when: never
+ - if: '$AUTO_DEVOPS_PLATFORM_TARGET == "EC2"'
diff --git a/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml
index 43ecc4b96d5..00b771f1e5c 100644
--- a/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml
@@ -7,7 +7,7 @@ code_quality:
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
- CODE_QUALITY_IMAGE: "registry.gitlab.com/gitlab-org/ci-cd/codequality:0.85.24"
+ CODE_QUALITY_IMAGE: "registry.gitlab.com/gitlab-org/ci-cd/codequality:0.85.24-gitlab.1"
needs: []
script:
- export SOURCE_CODE=$PWD
diff --git a/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml
index 208951fa1a1..e0627b85aba 100644
--- a/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml
@@ -1,5 +1,8 @@
+variables:
+ DAST_AUTO_DEPLOY_IMAGE_VERSION: 'v2.12.0'
+
.dast-auto-deploy:
- image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v2.12.0"
+ image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:${DAST_AUTO_DEPLOY_IMAGE_VERSION}"
dast_environment_deploy:
extends: .dast-auto-deploy
diff --git a/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
index 5c466f0984c..2df985cfbb5 100644
--- a/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
@@ -1,5 +1,8 @@
+variables:
+ AUTO_DEPLOY_IMAGE_VERSION: 'v2.12.0'
+
.auto-deploy:
- image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v2.12.0"
+ image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:${AUTO_DEPLOY_IMAGE_VERSION}"
dependencies: []
review:
@@ -96,6 +99,8 @@ canary:
name: production
url: http://$CI_PROJECT_PATH_SLUG.$KUBE_INGRESS_BASE_DOMAIN
rules:
+ - if: '$CI_DEPLOY_FREEZE != null'
+ when: never
- if: '$CI_KUBERNETES_ACTIVE == null || $CI_KUBERNETES_ACTIVE == ""'
when: never
- if: '$CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH'
@@ -125,6 +130,8 @@ canary:
production:
<<: *production_template
rules:
+ - if: '$CI_DEPLOY_FREEZE != null'
+ when: never
- if: '$CI_KUBERNETES_ACTIVE == null || $CI_KUBERNETES_ACTIVE == ""'
when: never
- if: '$STAGING_ENABLED'
@@ -141,6 +148,8 @@ production_manual:
<<: *production_template
allow_failure: false
rules:
+ - if: '$CI_DEPLOY_FREEZE != null'
+ when: never
- if: '$CI_KUBERNETES_ACTIVE == null || $CI_KUBERNETES_ACTIVE == ""'
when: never
- if: '$INCREMENTAL_ROLLOUT_ENABLED'
@@ -177,6 +186,8 @@ production_manual:
resource_group: production
allow_failure: true
rules:
+ - if: '$CI_DEPLOY_FREEZE != null'
+ when: never
- if: '$CI_KUBERNETES_ACTIVE == null || $CI_KUBERNETES_ACTIVE == ""'
when: never
- if: '$INCREMENTAL_ROLLOUT_MODE == "timed"'
@@ -190,6 +201,8 @@ production_manual:
.timed_rollout_template: &timed_rollout_template
<<: *rollout_template
rules:
+ - if: '$CI_DEPLOY_FREEZE != null'
+ when: never
- if: '$CI_KUBERNETES_ACTIVE == null || $CI_KUBERNETES_ACTIVE == ""'
when: never
- if: '$INCREMENTAL_ROLLOUT_MODE == "manual"'
diff --git a/lib/gitlab/ci/templates/Jobs/Helm-2to3.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Helm-2to3.gitlab-ci.yml
index a130b09c51a..1ec1aa60d88 100644
--- a/lib/gitlab/ci/templates/Jobs/Helm-2to3.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Helm-2to3.gitlab-ci.yml
@@ -41,9 +41,9 @@
echo "Adopting Helm v2 manifests from $release"
# some resource kinds must be listed explicitly https://github.com/kubernetes/kubernetes/issues/42885
for name in $(kubectl -n "$KUBE_NAMESPACE" get all,ingress,daemonset -o name -l chart="$chart"); do
- kubectl annotate --overwrite "$name" meta.helm.sh/release-name="$release"
- kubectl annotate --overwrite "$name" meta.helm.sh/release-namespace="$KUBE_NAMESPACE"
- kubectl label --overwrite "$name" app.kubernetes.io/managed-by=Helm
+ kubectl annotate -n "$KUBE_NAMESPACE" --overwrite "$name" meta.helm.sh/release-name="$release"
+ kubectl annotate -n "$KUBE_NAMESPACE" --overwrite "$name" meta.helm.sh/release-namespace="$KUBE_NAMESPACE"
+ kubectl label -n "$KUBE_NAMESPACE" --overwrite "$name" app.kubernetes.io/managed-by=Helm
done
done
# migrate each release
diff --git a/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml
index c458ab6a00a..081a3a6cc78 100644
--- a/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml
@@ -16,6 +16,9 @@ stages:
init:
extends: .terraform:init
+fmt:
+ extends: .terraform:fmt
+
validate:
extends: .terraform:validate
diff --git a/lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml b/lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml
index 39c3374e534..e696c75253e 100644
--- a/lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml
@@ -20,7 +20,6 @@ cache:
key: "${TF_ROOT}"
paths:
- ${TF_ROOT}/.terraform/
- - ${TF_ROOT}/.terraform.lock.hcl
.init: &init
stage: init
diff --git a/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml
index c30860ad174..3a70e6bc4b8 100644
--- a/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml
@@ -20,7 +20,6 @@ cache:
key: "${TF_ROOT}"
paths:
- ${TF_ROOT}/.terraform/
- - ${TF_ROOT}/.terraform.lock.hcl
.terraform:init: &terraform_init
stage: init
@@ -28,6 +27,14 @@ cache:
- cd ${TF_ROOT}
- gitlab-terraform init
+.terraform:fmt: &terraform_fmt
+ stage: validate
+ needs: []
+ script:
+ - cd ${TF_ROOT}
+ - gitlab-terraform fmt -check -recursive
+ allow_failure: true
+
.terraform:validate: &terraform_validate
stage: validate
script:
diff --git a/lib/gitlab/ci/templates/dotNET.gitlab-ci.yml b/lib/gitlab/ci/templates/dotNET.gitlab-ci.yml
index dd88953b9a4..841f17767eb 100644
--- a/lib/gitlab/ci/templates/dotNET.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/dotNET.gitlab-ci.yml
@@ -21,7 +21,7 @@
#
# The deploy stage copies the exe and msi from build stage to a network drive
# You need to have the network drive mapped as Local System user for gitlab-runner service to see it
-# The best way to persist the mapping is via a scheduled task (see: https://stackoverflow.com/a/7867064/1288473),
+# The best way to persist the mapping is via a scheduled task
# running the following batch command: net use P: \\x.x.x.x\Projects /u:your_user your_pass /persistent:yes
# place project specific paths in variables to make the rest of the script more generic
diff --git a/lib/gitlab/ci/trace.rb b/lib/gitlab/ci/trace.rb
index f9798023838..72a94dcd412 100644
--- a/lib/gitlab/ci/trace.rb
+++ b/lib/gitlab/ci/trace.rb
@@ -4,6 +4,7 @@ module Gitlab
module Ci
class Trace
include ::Gitlab::ExclusiveLeaseHelpers
+ include ::Gitlab::Utils::StrongMemoize
include Checksummable
LOCK_TTL = 10.minutes
@@ -23,6 +24,8 @@ module Gitlab
attr_reader :job
delegate :old_trace, to: :job
+ delegate :can_attempt_archival_now?, :increment_archival_attempts!,
+ :archival_attempts_message, to: :trace_metadata
def initialize(job)
@job = job
@@ -188,11 +191,7 @@ module Gitlab
def unsafe_archive!
raise ArchiveError, 'Job is not finished yet' unless job.complete?
- if trace_artifact
- unsafe_trace_cleanup!
-
- raise AlreadyArchivedError, 'Could not archive again'
- end
+ unsafe_trace_conditionally_cleanup_before_retry!
if job.trace_chunks.any?
Gitlab::Ci::Trace::ChunkedIO.new(job) do |stream|
@@ -212,12 +211,19 @@ module Gitlab
end
end
- def unsafe_trace_cleanup!
+ def already_archived?
+ # TODO check checksum to ensure archive completed successfully
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/259619
+ trace_artifact.archived_trace_exists?
+ end
+
+ def unsafe_trace_conditionally_cleanup_before_retry!
return unless trace_artifact
- if trace_artifact.archived_trace_exists?
+ if already_archived?
# An archive already exists, so make sure to remove the trace chunks
erase_trace_chunks!
+ raise AlreadyArchivedError, 'Could not archive again'
else
# An archive already exists, but its associated file does not, so remove it
trace_artifact.destroy!
@@ -251,11 +257,19 @@ module Gitlab
File.open(path) do |stream|
# TODO: Set `file_format: :raw` after we've cleaned up legacy traces migration
# https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/20307
- job.create_job_artifacts_trace!(
+ trace_artifact = job.create_job_artifacts_trace!(
project: job.project,
file_type: :trace,
file: stream,
file_sha256: self.class.hexdigest(path))
+
+ trace_metadata.track_archival!(trace_artifact.id)
+ end
+ end
+
+ def trace_metadata
+ strong_memoize(:trace_metadata) do
+ job.ensure_trace_metadata!
end
end
diff --git a/lib/gitlab/ci/trace/backoff.rb b/lib/gitlab/ci/trace/backoff.rb
new file mode 100644
index 00000000000..c13d88cced1
--- /dev/null
+++ b/lib/gitlab/ci/trace/backoff.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class Trace
+ ##
+ # Trace::Backoff class is responsible for calculating a backoff value
+ # for when to be able to retry archiving a build's trace
+ #
+ # Because we're updating `last_archival_attempt_at` timestamp with every
+ # failed archival attempt, we need to be sure that sum of the backoff values
+ # for 1..MAX_ATTEMPTS is under 7 days(CHUNK_REDIS_TTL).
+ #
+ class Backoff
+ include Gitlab::Utils::StrongMemoize
+
+ MAX_JITTER_VALUE = 4
+
+ attr_reader :archival_attempts
+
+ def initialize(archival_attempts)
+ @archival_attempts = archival_attempts
+ end
+
+ def value
+ (((chunks_ttl / (3.5 * max_attempts)) * archival_attempts) / 1.hour).hours
+ end
+
+ # This formula generates an increasing delay between executions
+ # 9.6, 19.2, 28.8, 38.4, 48.0 + a random amount of time to
+ # change the order of execution for the jobs.
+ # With maximum value for each call to rand(4), this sums up to 6.8 days
+ # and with minimum values is 6 days.
+ #
+ def value_with_jitter
+ value + jitter
+ end
+
+ private
+
+ def jitter
+ rand(MAX_JITTER_VALUE).hours
+ end
+
+ def chunks_ttl
+ ::Ci::BuildTraceChunks::RedisBase::CHUNK_REDIS_TTL
+ end
+
+ def max_attempts
+ ::Ci::BuildTraceMetadata::MAX_ATTEMPTS
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/trace/stream.rb b/lib/gitlab/ci/trace/stream.rb
index fdc598c025a..2d31049a0c9 100644
--- a/lib/gitlab/ci/trace/stream.rb
+++ b/lib/gitlab/ci/trace/stream.rb
@@ -3,7 +3,6 @@
module Gitlab
module Ci
class Trace
- # This was inspired from: http://stackoverflow.com/a/10219411/1520132
class Stream
BUFFER_SIZE = 4096
LIMIT_SIZE = 500.kilobytes
diff --git a/lib/gitlab/ci/variables/collection.rb b/lib/gitlab/ci/variables/collection.rb
index ef9ba1b73c7..09c75a2b3f1 100644
--- a/lib/gitlab/ci/variables/collection.rb
+++ b/lib/gitlab/ci/variables/collection.rb
@@ -10,7 +10,7 @@ module Gitlab
def initialize(variables = [], errors = nil)
@variables = []
- @variables_by_key = {}
+ @variables_by_key = Hash.new { |h, k| h[k] = [] }
@errors = errors
variables.each { |variable| self.append(variable) }
@@ -19,7 +19,7 @@ module Gitlab
def append(resource)
item = Collection::Item.fabricate(resource)
@variables.append(item)
- @variables_by_key[item[:key]] = item
+ @variables_by_key[item[:key]] << item
self
end
@@ -46,7 +46,12 @@ module Gitlab
end
def [](key)
- @variables_by_key[key]
+ all(key)&.last
+ end
+
+ def all(key)
+ vars = @variables_by_key[key]
+ vars unless vars.empty?
end
def size
@@ -72,7 +77,7 @@ module Gitlab
match = Regexp.last_match
if match[:key]
# we matched variable
- if variable = @variables_by_key[match[:key]]
+ if variable = self[match[:key]]
variable.value
elsif keep_undefined
match[0]
@@ -85,7 +90,7 @@ module Gitlab
end
def sort_and_expand_all(project, keep_undefined: false)
- return self if Feature.disabled?(:variable_inside_variable, project)
+ return self if Feature.disabled?(:variable_inside_variable, project, default_enabled: :yaml)
sorted = Sort.new(self)
return self.class.new(self, sorted.errors) unless sorted.valid?
diff --git a/lib/gitlab/ci/variables/collection/sort.rb b/lib/gitlab/ci/variables/collection/sort.rb
index 90a929b8a07..62637825c15 100644
--- a/lib/gitlab/ci/variables/collection/sort.rb
+++ b/lib/gitlab/ci/variables/collection/sort.rb
@@ -42,7 +42,7 @@ module Gitlab
depends_on = var_item.depends_on
return unless depends_on
- depends_on.filter_map { |var_ref_name| @collection[var_ref_name] }.each(&block)
+ depends_on.filter_map { |var_ref_name| @collection.all(var_ref_name) }.flatten.each(&block)
end
end
end
diff --git a/lib/gitlab/ci/yaml_processor.rb b/lib/gitlab/ci/yaml_processor.rb
index c94fa84f608..1aa3dbc5e47 100644
--- a/lib/gitlab/ci/yaml_processor.rb
+++ b/lib/gitlab/ci/yaml_processor.rb
@@ -47,9 +47,7 @@ module Gitlab
validate_job!(name, job)
end
- if ::Feature.enabled?(:ci_same_stage_job_needs, @opts[:project], default_enabled: :yaml)
- YamlProcessor::Dag.check_circular_dependencies!(@jobs)
- end
+ YamlProcessor::Dag.check_circular_dependencies!(@jobs)
end
def validate_job!(name, job)
@@ -103,16 +101,8 @@ module Gitlab
job_stage_index = stage_index(name)
dependency_stage_index = stage_index(dependency)
- if ::Feature.enabled?(:ci_same_stage_job_needs, @opts[:project], default_enabled: :yaml)
- unless dependency_stage_index.present? && dependency_stage_index <= job_stage_index
- error!("#{name} job: #{dependency_type} #{dependency} is not defined in current or prior stages")
- end
- else
- # A dependency might be defined later in the configuration
- # with a stage that does not exist
- unless dependency_stage_index.present? && dependency_stage_index < job_stage_index
- error!("#{name} job: #{dependency_type} #{dependency} is not defined in prior stages")
- end
+ unless dependency_stage_index.present? && dependency_stage_index <= job_stage_index
+ error!("#{name} job: #{dependency_type} #{dependency} is not defined in current or prior stages")
end
end
diff --git a/lib/gitlab/config/entry/validators.rb b/lib/gitlab/config/entry/validators.rb
index 13c6eaf4993..5d2bf3cfebf 100644
--- a/lib/gitlab/config/entry/validators.rb
+++ b/lib/gitlab/config/entry/validators.rb
@@ -90,14 +90,22 @@ module Gitlab
end
end
- class NestedArrayOfHashesValidator < ArrayOfHashesValidator
+ class NestedArrayOfHashesOrArraysValidator < ArrayOfHashesValidator
include NestedArrayHelpers
def validate_each(record, attribute, value)
- unless validate_nested_array(value, 1, &method(:validate_array_of_hashes))
+ max_level = options.fetch(:max_level, 1)
+
+ unless validate_nested_array(value, max_level, &method(:validate_hash))
record.errors.add(attribute, 'should be an array containing hashes and arrays of hashes')
end
end
+
+ private
+
+ def validate_hash(value)
+ value.is_a?(Hash)
+ end
end
class ArrayOrStringValidator < ActiveModel::EachValidator
diff --git a/lib/gitlab/config/loader/yaml.rb b/lib/gitlab/config/loader/yaml.rb
index 80c9abecd8e..f3a3818f010 100644
--- a/lib/gitlab/config/loader/yaml.rb
+++ b/lib/gitlab/config/loader/yaml.rb
@@ -9,9 +9,6 @@ module Gitlab
include Gitlab::Utils::StrongMemoize
- MAX_YAML_SIZE = 1.megabyte
- MAX_YAML_DEPTH = 100
-
def initialize(config, additional_permitted_classes: [])
@config = YAML.safe_load(config,
permitted_classes: [Symbol, *additional_permitted_classes],
@@ -52,8 +49,8 @@ module Gitlab
def deep_size
strong_memoize(:deep_size) do
Gitlab::Utils::DeepSize.new(@config,
- max_size: MAX_YAML_SIZE,
- max_depth: MAX_YAML_DEPTH)
+ max_size: Gitlab::CurrentSettings.current_application_settings.max_yaml_size_bytes,
+ max_depth: Gitlab::CurrentSettings.current_application_settings.max_yaml_depth)
end
end
end
diff --git a/lib/gitlab/contributions_calendar.rb b/lib/gitlab/contributions_calendar.rb
index 4e430d8937d..7d7c604d86a 100644
--- a/lib/gitlab/contributions_calendar.rb
+++ b/lib/gitlab/contributions_calendar.rb
@@ -33,6 +33,7 @@ module Gitlab
.having(action: :commented)
events = Event
+ .select(:project_id, :target_type, :action, :date, :total_amount)
.from_union([repo_events, issue_events, mr_events, note_events])
.map(&:attributes)
diff --git a/lib/gitlab/cycle_analytics/summary/base.rb b/lib/gitlab/cycle_analytics/summary/base.rb
index 50a8f189df0..e30e526f017 100644
--- a/lib/gitlab/cycle_analytics/summary/base.rb
+++ b/lib/gitlab/cycle_analytics/summary/base.rb
@@ -16,6 +16,10 @@ module Gitlab
def value
raise NotImplementedError, "Expected #{self.name} to implement value"
end
+
+ private
+
+ attr_reader :project, :options
end
end
end
diff --git a/lib/gitlab/cycle_analytics/summary/deploy.rb b/lib/gitlab/cycle_analytics/summary/deploy.rb
index ea16226a865..403cec5ed19 100644
--- a/lib/gitlab/cycle_analytics/summary/deploy.rb
+++ b/lib/gitlab/cycle_analytics/summary/deploy.rb
@@ -24,3 +24,5 @@ module Gitlab
end
end
end
+
+Gitlab::CycleAnalytics::Summary::Deploy.prepend_mod_with('Gitlab::CycleAnalytics::Summary::Deploy')
diff --git a/lib/gitlab/database.rb b/lib/gitlab/database.rb
index acad19e096c..385ac40cf13 100644
--- a/lib/gitlab/database.rb
+++ b/lib/gitlab/database.rb
@@ -2,7 +2,11 @@
module Gitlab
module Database
+ DATABASE_NAMES = %w[main ci].freeze
+
+ MAIN_DATABASE_NAME = 'main'
CI_DATABASE_NAME = 'ci'
+ DEFAULT_POOL_HEADROOM = 10
# This constant is used when renaming tables concurrently.
# If you plan to rename a table using the `rename_table_safely` method, add your table here one milestone before the rename.
@@ -59,6 +63,20 @@ module Gitlab
DATABASES[PRIMARY_DATABASE_NAME]
end
+ # We configure the database connection pool size automatically based on the
+ # configured concurrency. We also add some headroom, to make sure we don't
+ # run out of connections when more threads besides the 'user-facing' ones
+ # are running.
+ #
+ # Read more about this in
+ # doc/development/database/client_side_connection_pool.md
+ def self.default_pool_size
+ headroom =
+ (ENV["DB_POOL_HEADROOM"].presence || DEFAULT_POOL_HEADROOM).to_i
+
+ Gitlab::Runtime.max_threads + headroom
+ end
+
def self.has_config?(database_name)
Gitlab::Application.config.database_configuration[Rails.env].include?(database_name.to_s)
end
@@ -145,11 +163,19 @@ module Gitlab
def self.allow_cross_joins_across_databases(url:)
# this method is implemented in:
# spec/support/database/prevent_cross_joins.rb
+ yield
end
+ # This method will allow cross database modifications within the block
+ # Example:
+ #
+ # allow_cross_database_modification_within_transaction(url: 'url-to-an-issue') do
+ # create(:build) # inserts ci_build and project record in one transaction
+ # end
def self.allow_cross_database_modification_within_transaction(url:)
- # this method is implemented in:
+ # this method will be overridden in:
# spec/support/database/cross_database_modification_check.rb
+ yield
end
def self.add_post_migrate_path_to_rails(force: false)
@@ -172,14 +198,30 @@ module Gitlab
::ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).map(&:name)
end
- def self.db_config_name(ar_connection)
- if ar_connection.respond_to?(:pool) &&
- ar_connection.pool.respond_to?(:db_config) &&
- ar_connection.pool.db_config.respond_to?(:name)
- return ar_connection.pool.db_config.name
- end
+ def self.db_config_for_connection(connection)
+ return unless connection
- 'unknown'
+ # The LB connection proxy does not have a direct db_config
+ # that can be referenced
+ return if connection.is_a?(::Gitlab::Database::LoadBalancing::ConnectionProxy)
+
+ # During application init we might receive `NullPool`
+ return unless connection.respond_to?(:pool) &&
+ connection.pool.respond_to?(:db_config)
+
+ connection.pool.db_config
+ end
+
+ # At the moment, the connection can only be retrieved by
+ # Gitlab::Database::LoadBalancer#read or #read_write or from the
+ # ActiveRecord directly. Therefore, if the load balancer doesn't
+ # recognize the connection, this method returns the primary role
+ # directly. In future, we may need to check for other sources.
+ # Expected returned names:
+ # main, main_replica, ci, ci_replica, unknown
+ def self.db_config_name(connection)
+ db_config = db_config_for_connection(connection)
+ db_config&.name || 'unknown'
end
def self.read_only?
@@ -207,9 +249,13 @@ module Gitlab
extend ActiveSupport::Concern
class_methods do
- # A monkeypatch over ActiveRecord::Base.transaction.
- # It provides observability into transactional methods.
+ # A patch over ActiveRecord::Base.transaction that provides
+ # observability into transactional methods.
def transaction(**options, &block)
+ if options[:requires_new] && connection.transaction_open?
+ ::Gitlab::Database::Metrics.subtransactions_increment(self.name)
+ end
+
ActiveSupport::Notifications.instrument('transaction.active_record', { connection: connection }) do
super(**options, &block)
end
diff --git a/lib/gitlab/database/async_indexes/migration_helpers.rb b/lib/gitlab/database/async_indexes/migration_helpers.rb
index dff6376270a..2f990aba2fb 100644
--- a/lib/gitlab/database/async_indexes/migration_helpers.rb
+++ b/lib/gitlab/database/async_indexes/migration_helpers.rb
@@ -55,11 +55,14 @@ module Gitlab
schema_creation = ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaCreation.new(ApplicationRecord.connection)
definition = schema_creation.accept(create_index)
- async_index = PostgresAsyncIndex.safe_find_or_create_by!(name: index_name) do |rec|
+ async_index = PostgresAsyncIndex.find_or_create_by!(name: index_name) do |rec|
rec.table_name = table_name
rec.definition = definition
end
+ async_index.definition = definition
+ async_index.save! # No-op if definition is not changed
+
Gitlab::AppLogger.info(
message: 'Prepared index for async creation',
table_name: async_index.table_name,
@@ -68,8 +71,6 @@ module Gitlab
async_index
end
- private
-
def async_index_creation_available?
ApplicationRecord.connection.table_exists?(:postgres_async_indexes) &&
Feature.enabled?(:database_async_index_creation, type: :ops)
diff --git a/lib/gitlab/database/background_migration/batched_job.rb b/lib/gitlab/database/background_migration/batched_job.rb
index 03bd02d7554..32765cb6a56 100644
--- a/lib/gitlab/database/background_migration/batched_job.rb
+++ b/lib/gitlab/database/background_migration/batched_job.rb
@@ -4,6 +4,7 @@ module Gitlab
module Database
module BackgroundMigration
class BatchedJob < ActiveRecord::Base # rubocop:disable Rails/ApplicationRecord
+ include EachBatch
include FromUnion
self.table_name = :batched_background_migration_jobs
diff --git a/lib/gitlab/database/background_migration/batched_migration.rb b/lib/gitlab/database/background_migration/batched_migration.rb
index 9d66824da51..d9fc2ea48f6 100644
--- a/lib/gitlab/database/background_migration/batched_migration.rb
+++ b/lib/gitlab/database/background_migration/batched_migration.rb
@@ -68,6 +68,17 @@ module Gitlab
)
end
+ def retry_failed_jobs!
+ batched_jobs.failed.each_batch(of: 100) do |batch|
+ self.class.transaction do
+ batch.lock.each(&:split_and_retry!)
+ self.active!
+ end
+ end
+
+ self.active!
+ end
+
def next_min_value
last_job&.max_value&.next || min_value
end
diff --git a/lib/gitlab/database/connection.rb b/lib/gitlab/database/connection.rb
index 21861e4fba8..cda6220ee6c 100644
--- a/lib/gitlab/database/connection.rb
+++ b/lib/gitlab/database/connection.rb
@@ -5,8 +5,6 @@ module Gitlab
# Configuration settings and methods for interacting with a PostgreSQL
# database, with support for multiple databases.
class Connection
- DEFAULT_POOL_HEADROOM = 10
-
attr_reader :scope
# Initializes a new `Database`.
@@ -20,20 +18,6 @@ module Gitlab
@open_transactions_baseline = 0
end
- # We configure the database connection pool size automatically based on
- # the configured concurrency. We also add some headroom, to make sure we
- # don't run out of connections when more threads besides the 'user-facing'
- # ones are running.
- #
- # Read more about this in
- # doc/development/database/client_side_connection_pool.md
- def default_pool_size
- headroom =
- (ENV["DB_POOL_HEADROOM"].presence || DEFAULT_POOL_HEADROOM).to_i
-
- Gitlab::Runtime.max_threads + headroom
- end
-
def config
# The result of this method must not be cached, as other methods may use
# it after making configuration changes and expect those changes to be
@@ -48,7 +32,7 @@ module Gitlab
end
def pool_size
- config[:pool] || default_pool_size
+ config[:pool] || Database.default_pool_size
end
def username
@@ -77,7 +61,9 @@ module Gitlab
def db_config_with_default_pool_size
db_config_object = scope.connection_db_config
- config = db_config_object.configuration_hash.merge(pool: default_pool_size)
+ config = db_config_object
+ .configuration_hash
+ .merge(pool: Database.default_pool_size)
ActiveRecord::DatabaseConfigurations::HashConfig.new(
db_config_object.env_name,
@@ -88,7 +74,16 @@ module Gitlab
# Disables prepared statements for the current database connection.
def disable_prepared_statements
- scope.establish_connection(config.merge(prepared_statements: false))
+ db_config_object = scope.connection_db_config
+ config = db_config_object.configuration_hash.merge(prepared_statements: false)
+
+ hash_config = ActiveRecord::DatabaseConfigurations::HashConfig.new(
+ db_config_object.env_name,
+ db_config_object.name,
+ config
+ )
+
+ scope.establish_connection(hash_config)
end
# Check whether the underlying database is in read-only mode
@@ -174,8 +169,11 @@ module Gitlab
end
def exists?
- connection
-
+ # We can't _just_ check if `connection` raises an error, as it will
+ # point to a `ConnectionProxy`, and obtaining those doesn't involve any
+ # database queries. So instead we obtain the database version, which is
+ # cached after the first call.
+ connection.schema_cache.database_version
true
rescue StandardError
false
@@ -189,6 +187,19 @@ module Gitlab
row['system_identifier']
end
+ def pg_wal_lsn_diff(location1, location2)
+ lsn1 = connection.quote(location1)
+ lsn2 = connection.quote(location2)
+
+ query = <<-SQL.squish
+ SELECT pg_wal_lsn_diff(#{lsn1}, #{lsn2})
+ AS result
+ SQL
+
+ row = connection.select_all(query).first
+ row['result'] if row
+ end
+
# @param [ActiveRecord::Connection] ar_connection
# @return [String]
def get_write_location(ar_connection)
diff --git a/lib/gitlab/database/load_balancing.rb b/lib/gitlab/database/load_balancing.rb
index 08f108eb8e4..bbfbf83222f 100644
--- a/lib/gitlab/database/load_balancing.rb
+++ b/lib/gitlab/database/load_balancing.rb
@@ -36,89 +36,42 @@ module Gitlab
# Returns a Hash containing the load balancing configuration.
def self.configuration
- Gitlab::Database.main.config[:load_balancing] || {}
- end
-
- # Returns the maximum replica lag size in bytes.
- def self.max_replication_difference
- (configuration['max_replication_difference'] || 8.megabytes).to_i
- end
-
- # Returns the maximum lag time for a replica.
- def self.max_replication_lag_time
- (configuration['max_replication_lag_time'] || 60.0).to_f
- end
-
- # Returns the interval (in seconds) to use for checking the status of a
- # replica.
- def self.replica_check_interval
- (configuration['replica_check_interval'] || 60).to_f
- end
-
- # Returns the additional hosts to use for load balancing.
- def self.hosts
- configuration['hosts'] || []
- end
-
- def self.service_discovery_enabled?
- configuration.dig('discover', 'record').present?
- end
-
- def self.service_discovery_configuration
- conf = configuration['discover'] || {}
-
- {
- nameserver: conf['nameserver'] || 'localhost',
- port: conf['port'] || 8600,
- record: conf['record'],
- record_type: conf['record_type'] || 'A',
- interval: conf['interval'] || 60,
- disconnect_timeout: conf['disconnect_timeout'] || 120,
- use_tcp: conf['use_tcp'] || false
- }
- end
-
- def self.pool_size
- Gitlab::Database.main.pool_size
+ @configuration ||= Configuration.for_model(ActiveRecord::Base)
end
# Returns true if load balancing is to be enabled.
def self.enable?
return false if Gitlab::Runtime.rake?
- return false unless self.configured?
- true
+ configured?
end
- # Returns true if load balancing has been configured. Since
- # Sidekiq does not currently use load balancing, we
- # may want Web application servers to detect replication lag by
- # posting the write location of the database if load balancing is
- # configured.
def self.configured?
- hosts.any? || service_discovery_enabled?
+ configuration.load_balancing_enabled? ||
+ configuration.service_discovery_enabled?
end
def self.start_service_discovery
- return unless service_discovery_enabled?
+ return unless configuration.service_discovery_enabled?
- ServiceDiscovery.new(service_discovery_configuration).start
+ ServiceDiscovery
+ .new(proxy.load_balancer, **configuration.service_discovery)
+ .start
end
# Configures proxying of requests.
- def self.configure_proxy(proxy = ConnectionProxy.new(hosts))
- ActiveRecord::Base.load_balancing_proxy = proxy
+ def self.configure_proxy
+ lb = LoadBalancer.new(configuration, primary_only: !enable?)
+ ActiveRecord::Base.load_balancing_proxy = ConnectionProxy.new(lb)
# Populate service discovery immediately if it is configured
- if service_discovery_enabled?
- ServiceDiscovery.new(service_discovery_configuration).perform_service_discovery
+ if configuration.service_discovery_enabled?
+ ServiceDiscovery
+ .new(lb, **configuration.service_discovery)
+ .perform_service_discovery
end
end
- def self.active_record_models
- ActiveRecord::Base.descendants
- end
-
DB_ROLES = [
ROLE_PRIMARY = :primary,
ROLE_REPLICA = :replica,
@@ -126,24 +79,12 @@ module Gitlab
].freeze
# Returns the role (primary/replica) of the database the connection is
- # connecting to. At the moment, the connection can only be retrieved by
- # Gitlab::Database::LoadBalancer#read or #read_write or from the
- # ActiveRecord directly. Therefore, if the load balancer doesn't
- # recognize the connection, this method returns the primary role
- # directly. In future, we may need to check for other sources.
+ # connecting to.
def self.db_role_for_connection(connection)
- return ROLE_UNKNOWN unless connection
-
- # The connection proxy does not have a role assigned
- # as this is dependent on a execution context
- return ROLE_UNKNOWN if connection.is_a?(ConnectionProxy)
-
- # During application init we might receive `NullPool`
- return ROLE_UNKNOWN unless connection.respond_to?(:pool) &&
- connection.pool.respond_to?(:db_config) &&
- connection.pool.db_config.respond_to?(:name)
+ db_config = Database.db_config_for_connection(connection)
+ return ROLE_UNKNOWN unless db_config
- if connection.pool.db_config.name.ends_with?(LoadBalancer::REPLICA_SUFFIX)
+ if db_config.name.ends_with?(LoadBalancer::REPLICA_SUFFIX)
ROLE_REPLICA
else
ROLE_PRIMARY
diff --git a/lib/gitlab/database/load_balancing/action_cable_callbacks.rb b/lib/gitlab/database/load_balancing/action_cable_callbacks.rb
new file mode 100644
index 00000000000..4feba989a0a
--- /dev/null
+++ b/lib/gitlab/database/load_balancing/action_cable_callbacks.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module LoadBalancing
+ module ActionCableCallbacks
+ def self.install
+ ::ActionCable::Server::Worker.set_callback :work, :around, &wrapper
+ ::ActionCable::Channel::Base.set_callback :subscribe, :around, &wrapper
+ ::ActionCable::Channel::Base.set_callback :unsubscribe, :around, &wrapper
+ end
+
+ def self.wrapper
+ lambda do |_, inner|
+ ::Gitlab::Database::LoadBalancing::Session.current.use_primary!
+
+ inner.call
+ ensure
+ ::Gitlab::Database::LoadBalancing.proxy.load_balancer.release_host
+ ::Gitlab::Database::LoadBalancing::Session.clear_session
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/load_balancing/configuration.rb b/lib/gitlab/database/load_balancing/configuration.rb
new file mode 100644
index 00000000000..238f55fd98e
--- /dev/null
+++ b/lib/gitlab/database/load_balancing/configuration.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module LoadBalancing
+ # Configuration settings for a single LoadBalancer instance.
+ class Configuration
+ attr_accessor :hosts, :max_replication_difference,
+ :max_replication_lag_time, :replica_check_interval,
+ :service_discovery, :model
+
+ # Creates a configuration object for the given ActiveRecord model.
+ def self.for_model(model)
+ cfg = model.connection_db_config.configuration_hash.deep_symbolize_keys
+ lb_cfg = cfg[:load_balancing] || {}
+ config = new(model)
+
+ if (diff = lb_cfg[:max_replication_difference])
+ config.max_replication_difference = diff
+ end
+
+ if (lag = lb_cfg[:max_replication_lag_time])
+ config.max_replication_lag_time = lag.to_f
+ end
+
+ if (interval = lb_cfg[:replica_check_interval])
+ config.replica_check_interval = interval.to_f
+ end
+
+ if (hosts = lb_cfg[:hosts])
+ config.hosts = hosts
+ end
+
+ discover = lb_cfg[:discover] || {}
+
+ # We iterate over the known/default keys so we don't end up with
+ # random keys in our configuration hash.
+ config.service_discovery.each do |key, _|
+ if (value = discover[key])
+ config.service_discovery[key] = value
+ end
+ end
+
+ config
+ end
+
+ def initialize(model, hosts = [])
+ @max_replication_difference = 8.megabytes
+ @max_replication_lag_time = 60.0
+ @replica_check_interval = 60.0
+ @model = model
+ @hosts = hosts
+ @service_discovery = {
+ nameserver: 'localhost',
+ port: 8600,
+ record: nil,
+ record_type: 'A',
+ interval: 60,
+ disconnect_timeout: 120,
+ use_tcp: false
+ }
+ end
+
+ def pool_size
+ # The pool size may change when booting up GitLab, as GitLab enforces
+ # a certain number of threads. If a Configuration is memoized, this
+ # can lead to incorrect pool sizes.
+ #
+ # To support this scenario, we always attempt to read the pool size
+ # from the model's configuration.
+ @model.connection_db_config.configuration_hash[:pool] ||
+ Database.default_pool_size
+ end
+
+ def load_balancing_enabled?
+ hosts.any? || service_discovery_enabled?
+ end
+
+ def service_discovery_enabled?
+ service_discovery[:record].present?
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/load_balancing/connection_proxy.rb b/lib/gitlab/database/load_balancing/connection_proxy.rb
index 938f4951532..1be63da8896 100644
--- a/lib/gitlab/database/load_balancing/connection_proxy.rb
+++ b/lib/gitlab/database/load_balancing/connection_proxy.rb
@@ -34,15 +34,15 @@ module Gitlab
).freeze
# hosts - The hosts to use for load balancing.
- def initialize(hosts = [])
- @load_balancer = LoadBalancer.new(hosts)
+ def initialize(load_balancer)
+ @load_balancer = load_balancer
end
def select_all(arel, name = nil, binds = [], preparable: nil)
if arel.respond_to?(:locked) && arel.locked
# SELECT ... FOR UPDATE queries should be sent to the primary.
- write_using_load_balancer(:select_all, arel, name, binds,
- sticky: true)
+ current_session.write!
+ write_using_load_balancer(:select_all, arel, name, binds)
else
read_using_load_balancer(:select_all, arel, name, binds)
end
@@ -56,7 +56,8 @@ module Gitlab
STICKY_WRITES.each do |name|
define_method(name) do |*args, **kwargs, &block|
- write_using_load_balancer(name, *args, sticky: true, **kwargs, &block)
+ current_session.write!
+ write_using_load_balancer(name, *args, **kwargs, &block)
end
end
@@ -65,13 +66,20 @@ module Gitlab
track_read_only_transaction!
read_using_load_balancer(:transaction, *args, **kwargs, &block)
else
- write_using_load_balancer(:transaction, *args, sticky: true, **kwargs, &block)
+ current_session.write!
+ write_using_load_balancer(:transaction, *args, **kwargs, &block)
end
ensure
untrack_read_only_transaction!
end
+ def respond_to_missing?(name, include_private = false)
+ @load_balancer.read_write do |connection|
+ connection.respond_to?(name, include_private)
+ end
+ end
+
# Delegates all unknown messages to a read-write connection.
def method_missing(...)
if current_session.fallback_to_replicas_for_ambiguous_queries?
@@ -102,18 +110,13 @@ module Gitlab
# name - The name of the method to call on a connection object.
# sticky - If set to true the session will stick to the master after
# the write.
- def write_using_load_balancer(name, *args, sticky: false, **kwargs, &block)
+ def write_using_load_balancer(...)
if read_only_transaction?
raise WriteInsideReadOnlyTransactionError, 'A write query is performed inside a read-only transaction'
end
@load_balancer.read_write do |connection|
- # Sticking has to be enabled before calling the method. Not doing so
- # could lead to methods called in a block still being performed on a
- # secondary instead of on a primary (when necessary).
- current_session.write! if sticky
-
- connection.send(name, *args, **kwargs, &block)
+ connection.send(...)
end
end
diff --git a/lib/gitlab/database/load_balancing/host.rb b/lib/gitlab/database/load_balancing/host.rb
index 4c5357ae8e3..acd7df0a263 100644
--- a/lib/gitlab/database/load_balancing/host.rb
+++ b/lib/gitlab/database/load_balancing/host.rb
@@ -29,11 +29,15 @@ module Gitlab
@host = host
@port = port
@load_balancer = load_balancer
- @pool = load_balancer.create_replica_connection_pool(::Gitlab::Database::LoadBalancing.pool_size, host, port)
+ @pool = load_balancer.create_replica_connection_pool(
+ load_balancer.configuration.pool_size,
+ host,
+ port
+ )
@online = true
@last_checked_at = Time.zone.now
- interval = ::Gitlab::Database::LoadBalancing.replica_check_interval
+ interval = load_balancer.configuration.replica_check_interval
@intervals = (interval..(interval * 2)).step(0.5).to_a
end
@@ -108,7 +112,7 @@ module Gitlab
def replication_lag_below_threshold?
if (lag_time = replication_lag_time)
- lag_time <= ::Gitlab::Database::LoadBalancing.max_replication_lag_time
+ lag_time <= load_balancer.configuration.max_replication_lag_time
else
false
end
@@ -125,7 +129,7 @@ module Gitlab
# only do this if we haven't replicated in a while so we only need
# to connect to the primary when truly necessary.
if (lag_size = replication_lag_size)
- lag_size <= ::Gitlab::Database::LoadBalancing.max_replication_difference
+ lag_size <= load_balancer.configuration.max_replication_difference
else
false
end
@@ -159,8 +163,6 @@ module Gitlab
def primary_write_location
load_balancer.primary_write_location
- ensure
- load_balancer.release_primary_connection
end
def database_replica_location
diff --git a/lib/gitlab/database/load_balancing/host_list.rb b/lib/gitlab/database/load_balancing/host_list.rb
index aa731521732..fb3175c7d5d 100644
--- a/lib/gitlab/database/load_balancing/host_list.rb
+++ b/lib/gitlab/database/load_balancing/host_list.rb
@@ -35,12 +35,6 @@ module Gitlab
def hosts=(hosts)
@mutex.synchronize do
- ::Gitlab::Database::LoadBalancing::Logger.info(
- event: :host_list_update,
- message: "Updating the host list for service discovery",
- host_list_length: hosts.length,
- old_host_list_length: @hosts.length
- )
@hosts = hosts
unsafe_shuffle
end
diff --git a/lib/gitlab/database/load_balancing/load_balancer.rb b/lib/gitlab/database/load_balancing/load_balancer.rb
index e3f5d0ac470..9b00b323301 100644
--- a/lib/gitlab/database/load_balancing/load_balancer.rb
+++ b/lib/gitlab/database/load_balancing/load_balancer.rb
@@ -12,12 +12,22 @@ module Gitlab
REPLICA_SUFFIX = '_replica'
- attr_reader :host_list
-
- # hosts - The hostnames/addresses of the additional databases.
- def initialize(hosts = [], model = ActiveRecord::Base)
- @model = model
- @host_list = HostList.new(hosts.map { |addr| Host.new(addr, self) })
+ attr_reader :host_list, :configuration
+
+ # configuration - An instance of `LoadBalancing::Configuration` that
+ # contains the configuration details (such as the hosts)
+ # for this load balancer.
+ # primary_only - If set, the replicas are ignored and the primary is
+ # always used.
+ def initialize(configuration, primary_only: false)
+ @configuration = configuration
+ @primary_only = primary_only
+ @host_list =
+ if primary_only
+ HostList.new([PrimaryHost.new(self)])
+ else
+ HostList.new(configuration.hosts.map { |addr| Host.new(addr, self) })
+ end
end
def disconnect!(timeout: 120)
@@ -169,7 +179,11 @@ module Gitlab
when ActiveRecord::StatementInvalid, ActionView::Template::Error
# After connecting to the DB Rails will wrap query errors using this
# class.
- connection_error?(error.cause)
+ if (cause = error.cause)
+ connection_error?(cause)
+ else
+ false
+ end
when *CONNECTION_ERRORS
true
else
@@ -213,26 +227,26 @@ module Gitlab
.establish_connection(replica_db_config)
end
- private
-
# ActiveRecord::ConnectionAdapters::ConnectionHandler handles fetching,
# and caching for connections pools for each "connection", so we
# leverage that.
def pool
ActiveRecord::Base.connection_handler.retrieve_connection_pool(
- @model.connection_specification_name,
+ @configuration.model.connection_specification_name,
role: ActiveRecord::Base.writing_role,
shard: ActiveRecord::Base.default_shard
)
end
+ private
+
def ensure_caching!
host.enable_query_cache! unless host.query_cache_enabled
end
def request_cache
- base = RequestStore[:gitlab_load_balancer] ||= {}
- base[pool] ||= {}
+ base = SafeRequestStore[:gitlab_load_balancer] ||= {}
+ base[self] ||= {}
end
end
end
diff --git a/lib/gitlab/database/load_balancing/primary_host.rb b/lib/gitlab/database/load_balancing/primary_host.rb
new file mode 100644
index 00000000000..e379652c260
--- /dev/null
+++ b/lib/gitlab/database/load_balancing/primary_host.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module LoadBalancing
+ # A host that wraps the primary database connection.
+ #
+ # This class is used to always enable load balancing as if replicas exist,
+ # without the need for extra database connections. This ensures that code
+ # using the load balancer doesn't have to handle the case where load
+ # balancing is enabled, but no replicas have been configured (= the
+ # default case).
+ class PrimaryHost
+ def initialize(load_balancer)
+ @load_balancer = load_balancer
+ end
+
+ def release_connection
+ # no-op as releasing primary connections isn't needed.
+ nil
+ end
+
+ def enable_query_cache!
+ # This could mess up the primary connection, so we make this a no-op
+ nil
+ end
+
+ def disable_query_cache!
+ # This could mess up the primary connection, so we make this a no-op
+ nil
+ end
+
+ def query_cache_enabled
+ @load_balancer.pool.query_cache_enabled
+ end
+
+ def connection
+ @load_balancer.pool.connection
+ end
+
+ def disconnect!(timeout: 120)
+ nil
+ end
+
+ def offline!
+ nil
+ end
+
+ def online?
+ true
+ end
+
+ def primary_write_location
+ @load_balancer.primary_write_location
+ end
+
+ def database_replica_location
+ row = query_and_release(<<-SQL.squish)
+ SELECT pg_last_wal_replay_lsn()::text AS location
+ SQL
+
+ row['location'] if row.any?
+ rescue *Host::CONNECTION_ERRORS
+ nil
+ end
+
+ def caught_up?(_location)
+ true
+ end
+
+ def query_and_release(sql)
+ connection.select_all(sql).first || {}
+ rescue StandardError
+ {}
+ ensure
+ release_connection
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/load_balancing/service_discovery.rb b/lib/gitlab/database/load_balancing/service_discovery.rb
index 251961c8246..dfd4892371c 100644
--- a/lib/gitlab/database/load_balancing/service_discovery.rb
+++ b/lib/gitlab/database/load_balancing/service_discovery.rb
@@ -13,11 +13,17 @@ module Gitlab
# balancer with said hosts. Requests may continue to use the old hosts
# until they complete.
class ServiceDiscovery
+ EmptyDnsResponse = Class.new(StandardError)
+
attr_reader :interval, :record, :record_type, :disconnect_timeout,
:load_balancer
MAX_SLEEP_ADJUSTMENT = 10
+ MAX_DISCOVERY_RETRIES = 3
+
+ RETRY_DELAY_RANGE = (0.1..0.2).freeze
+
RECORD_TYPES = {
'A' => Net::DNS::A,
'SRV' => Net::DNS::SRV
@@ -43,14 +49,14 @@ module Gitlab
# use_tcp - Use TCP instaed of UDP to look up resources
# load_balancer - The load balancer instance to use
def initialize(
+ load_balancer,
nameserver:,
port:,
record:,
record_type: 'A',
interval: 60,
disconnect_timeout: 120,
- use_tcp: false,
- load_balancer: LoadBalancing.proxy.load_balancer
+ use_tcp: false
)
@nameserver = nameserver
@port = port
@@ -76,15 +82,23 @@ module Gitlab
end
def perform_service_discovery
- refresh_if_necessary
- rescue StandardError => error
- # Any exceptions that might occur should be reported to
- # Sentry, instead of silently terminating this thread.
- Gitlab::ErrorTracking.track_exception(error)
-
- Gitlab::AppLogger.error(
- "Service discovery encountered an error: #{error.message}"
- )
+ MAX_DISCOVERY_RETRIES.times do
+ return refresh_if_necessary
+ rescue StandardError => error
+ # Any exceptions that might occur should be reported to
+ # Sentry, instead of silently terminating this thread.
+ Gitlab::ErrorTracking.track_exception(error)
+
+ Gitlab::Database::LoadBalancing::Logger.error(
+ event: :service_discovery_failure,
+ message: "Service discovery encountered an error: #{error.message}",
+ host_list_length: load_balancer.host_list.length
+ )
+
+ # Slightly randomize the retry delay so that, in the case of a total
+ # dns outage, all starting services do not pressure the dns server at the same time.
+ sleep(rand(RETRY_DELAY_RANGE))
+ end
interval
end
@@ -99,7 +113,22 @@ module Gitlab
current = addresses_from_load_balancer
- replace_hosts(from_dns) if from_dns != current
+ if from_dns != current
+ ::Gitlab::Database::LoadBalancing::Logger.info(
+ event: :host_list_update,
+ message: "Updating the host list for service discovery",
+ host_list_length: from_dns.length,
+ old_host_list_length: current.length
+ )
+ replace_hosts(from_dns)
+ else
+ ::Gitlab::Database::LoadBalancing::Logger.info(
+ event: :host_list_unchanged,
+ message: "Unchanged host list for service discovery",
+ host_list_length: from_dns.length,
+ old_host_list_length: current.length
+ )
+ end
interval
end
@@ -141,6 +170,8 @@ module Gitlab
addresses_from_srv_record(response)
end
+ raise EmptyDnsResponse if addresses.empty?
+
# Addresses are sorted so we can directly compare the old and new
# addresses, without having to use any additional data structures.
[new_wait_time_for(resources), addresses.sort]
diff --git a/lib/gitlab/database/load_balancing/sidekiq_client_middleware.rb b/lib/gitlab/database/load_balancing/sidekiq_client_middleware.rb
index 0e36ebbc3ee..518a812b406 100644
--- a/lib/gitlab/database/load_balancing/sidekiq_client_middleware.rb
+++ b/lib/gitlab/database/load_balancing/sidekiq_client_middleware.rb
@@ -4,13 +4,15 @@ module Gitlab
module Database
module LoadBalancing
class SidekiqClientMiddleware
+ include Gitlab::Utils::StrongMemoize
+
def call(worker_class, job, _queue, _redis_pool)
# Mailers can't be constantized
worker_class = worker_class.to_s.safe_constantize
if load_balancing_enabled?(worker_class)
job['worker_data_consistency'] = worker_class.get_data_consistency
- set_data_consistency_location!(job) unless location_already_provided?(job)
+ set_data_consistency_locations!(job) unless job['wal_locations']
else
job['worker_data_consistency'] = ::WorkerAttributes::DEFAULT_DATA_CONSISTENCY
end
@@ -27,16 +29,23 @@ module Gitlab
worker_class.get_data_consistency_feature_flag_enabled?
end
- def set_data_consistency_location!(job)
- if Session.current.use_primary?
- job['database_write_location'] = load_balancer.primary_write_location
- else
- job['database_replica_location'] = load_balancer.host.database_replica_location
- end
+ def set_data_consistency_locations!(job)
+ # Once we add support for multiple databases to our load balancer, we would use something like this:
+ # job['wal_locations'] = Gitlab::Database::DATABASES.transform_values do |connection|
+ # connection.load_balancer.primary_write_location
+ # end
+ #
+ job['wal_locations'] = { Gitlab::Database::MAIN_DATABASE_NAME.to_sym => wal_location } if wal_location
end
- def location_already_provided?(job)
- job['database_replica_location'] || job['database_write_location']
+ def wal_location
+ strong_memoize(:wal_location) do
+ if Session.current.use_primary?
+ load_balancer.primary_write_location
+ else
+ load_balancer.host.database_replica_location
+ end
+ end
end
def load_balancer
diff --git a/lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb b/lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb
index 0551750568a..15f8f0fb240 100644
--- a/lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb
+++ b/lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb
@@ -29,7 +29,7 @@ module Gitlab
private
def clear
- load_balancer.release_host
+ release_hosts
Session.clear_session
end
@@ -40,10 +40,11 @@ module Gitlab
def select_load_balancing_strategy(worker_class, job)
return :primary unless load_balancing_available?(worker_class)
- location = job['database_write_location'] || job['database_replica_location']
- return :primary_no_wal unless location
+ wal_locations = get_wal_locations(job)
+
+ return :primary_no_wal unless wal_locations
- if replica_caught_up?(location)
+ if all_databases_has_replica_caught_up?(wal_locations)
# Happy case: we can read from a replica.
retried_before?(worker_class, job) ? :replica_retried : :replica
elsif can_retry?(worker_class, job)
@@ -55,6 +56,19 @@ module Gitlab
end
end
+ def get_wal_locations(job)
+ job['dedup_wal_locations'] || job['wal_locations'] || legacy_wal_location(job)
+ end
+
+ # Already scheduled jobs could still contain legacy database write location.
+ # TODO: remove this in the next iteration
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/338213
+ def legacy_wal_location(job)
+ wal_location = job['database_write_location'] || job['database_replica_location']
+
+ { Gitlab::Database::MAIN_DATABASE_NAME.to_sym => wal_location } if wal_location
+ end
+
def load_balancing_available?(worker_class)
worker_class.include?(::ApplicationWorker) &&
worker_class.utilizes_load_balancing_capabilities? &&
@@ -75,12 +89,26 @@ module Gitlab
job['retry_count'].nil?
end
- def load_balancer
- LoadBalancing.proxy.load_balancer
+ def all_databases_has_replica_caught_up?(wal_locations)
+ wal_locations.all? do |_config_name, location|
+ # Once we add support for multiple databases to our load balancer, we would use something like this:
+ # Gitlab::Database::DATABASES[config_name].load_balancer.select_up_to_date_host(location)
+ load_balancer.select_up_to_date_host(location)
+ end
end
- def replica_caught_up?(location)
- load_balancer.select_up_to_date_host(location)
+ def release_hosts
+ # Once we add support for multiple databases to our load balancer, we would use something like this:
+ # connection.load_balancer.primary_write_location
+ #
+ # Gitlab::Database::DATABASES.values.each do |connection|
+ # connection.load_balancer.release_host
+ # end
+ load_balancer.release_host
+ end
+
+ def load_balancer
+ LoadBalancing.proxy.load_balancer
end
end
end
diff --git a/lib/gitlab/database/migration.rb b/lib/gitlab/database/migration.rb
new file mode 100644
index 00000000000..b2248b0f4eb
--- /dev/null
+++ b/lib/gitlab/database/migration.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ class Migration
+ module LockRetriesConcern
+ extend ActiveSupport::Concern
+
+ class_methods do
+ def enable_lock_retries!
+ @enable_lock_retries = true # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ end
+
+ def enable_lock_retries?
+ @enable_lock_retries
+ end
+ end
+
+ delegate :enable_lock_retries?, to: :class
+ end
+
+ # This implements a simple versioning scheme for migration helpers.
+ #
+ # We need to be able to version helpers, so we can change their behavior without
+ # altering the behavior of already existing migrations in incompatible ways.
+ #
+ # We can continue to change the behavior of helpers without bumping the version here,
+ # *if* the change is backwards-compatible.
+ #
+ # If not, we would typically override the helper method in a new MigrationHelpers::V[0-9]+
+ # class and create a new entry with a bumped version below.
+ #
+ # We use major version bumps to indicate significant changes and minor version bumps
+ # to indicate backwards-compatible or otherwise minor changes (e.g. a Rails version bump).
+ # However, this hasn't been strictly formalized yet.
+ MIGRATION_CLASSES = {
+ 1.0 => Class.new(ActiveRecord::Migration[6.1]) do
+ include LockRetriesConcern
+ include Gitlab::Database::MigrationHelpers::V2
+ end
+ }.freeze
+
+ def self.[](version)
+ MIGRATION_CLASSES[version] || raise(ArgumentError, "Unknown migration version: #{version}")
+ end
+
+ # The current version to be used in new migrations
+ def self.current_version
+ 1.0
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb
index 23d9b16dc09..9968096b1f6 100644
--- a/lib/gitlab/database/migration_helpers.rb
+++ b/lib/gitlab/database/migration_helpers.rb
@@ -73,6 +73,7 @@ module Gitlab
end
end
+ # @deprecated Use `create_table` in V2 instead
#
# Creates a new table, optionally allowing the caller to add check constraints to the table.
# Aside from that addition, this method should behave identically to Rails' `create_table` method.
@@ -380,6 +381,8 @@ module Gitlab
# The timings can be controlled via the +timing_configuration+ parameter.
# If the lock was not acquired within the retry period, a last attempt is made without using +lock_timeout+.
#
+ # Note this helper uses subtransactions when run inside an already open transaction.
+ #
# ==== Examples
# # Invoking without parameters
# with_lock_retries do
@@ -411,7 +414,8 @@ module Gitlab
raise_on_exhaustion = !!kwargs.delete(:raise_on_exhaustion)
merged_args = {
klass: self.class,
- logger: Gitlab::BackgroundMigration::Logger
+ logger: Gitlab::BackgroundMigration::Logger,
+ allow_savepoints: true
}.merge(kwargs)
Gitlab::Database::WithLockRetries.new(**merged_args)
@@ -600,17 +604,17 @@ module Gitlab
# new_column - The name of the new column.
# trigger_name - The name of the trigger to use (optional).
def install_rename_triggers(table, old, new, trigger_name: nil)
- Gitlab::Database::UnidirectionalCopyTrigger.on_table(table).create(old, new, trigger_name: trigger_name)
+ Gitlab::Database::UnidirectionalCopyTrigger.on_table(table, connection: connection).create(old, new, trigger_name: trigger_name)
end
# Removes the triggers used for renaming a column concurrently.
def remove_rename_triggers(table, trigger)
- Gitlab::Database::UnidirectionalCopyTrigger.on_table(table).drop(trigger)
+ Gitlab::Database::UnidirectionalCopyTrigger.on_table(table, connection: connection).drop(trigger)
end
# Returns the (base) name to use for triggers when renaming columns.
def rename_trigger_name(table, old, new)
- Gitlab::Database::UnidirectionalCopyTrigger.on_table(table).name(old, new)
+ Gitlab::Database::UnidirectionalCopyTrigger.on_table(table, connection: connection).name(old, new)
end
# Changes the type of a column concurrently.
@@ -968,42 +972,7 @@ module Gitlab
# columns - The name, or array of names, of the column(s) that we want to convert to bigint.
# primary_key - The name of the primary key column (most often :id)
def initialize_conversion_of_integer_to_bigint(table, columns, primary_key: :id)
- unless table_exists?(table)
- raise "Table #{table} does not exist"
- end
-
- unless column_exists?(table, primary_key)
- raise "Column #{primary_key} does not exist on #{table}"
- end
-
- columns = Array.wrap(columns)
- columns.each do |column|
- next if column_exists?(table, column)
-
- raise ArgumentError, "Column #{column} does not exist on #{table}"
- end
-
- check_trigger_permissions!(table)
-
- conversions = columns.to_h { |column| [column, convert_to_bigint_column(column)] }
-
- with_lock_retries do
- conversions.each do |(source_column, temporary_name)|
- column = column_for(table, source_column)
-
- if (column.name.to_s == primary_key.to_s) || !column.null
- # If the column to be converted is either a PK or is defined as NOT NULL,
- # set it to `NOT NULL DEFAULT 0` and we'll copy paste the correct values bellow
- # That way, we skip the expensive validation step required to add
- # a NOT NULL constraint at the end of the process
- add_column(table, temporary_name, :bigint, default: column.default || 0, null: false)
- else
- add_column(table, temporary_name, :bigint, default: column.default)
- end
- end
-
- install_rename_triggers(table, conversions.keys, conversions.values)
- end
+ create_temporary_columns_and_triggers(table, columns, primary_key: primary_key, data_type: :bigint)
end
# Reverts `initialize_conversion_of_integer_to_bigint`
@@ -1019,6 +988,17 @@ module Gitlab
temporary_columns.each { |column| remove_column(table, column) }
end
+ alias_method :cleanup_conversion_of_integer_to_bigint, :revert_initialize_conversion_of_integer_to_bigint
+
+ # Reverts `cleanup_conversion_of_integer_to_bigint`
+ #
+ # table - The name of the database table containing the columns
+ # columns - The name, or array of names, of the column(s) that we have converted to bigint.
+ # primary_key - The name of the primary key column (most often :id)
+
+ def restore_conversion_of_integer_to_bigint(table, columns, primary_key: :id)
+ create_temporary_columns_and_triggers(table, columns, primary_key: primary_key, data_type: :int)
+ end
# Backfills the new columns used in an integer-to-bigint conversion using background migrations.
#
@@ -1400,13 +1380,11 @@ into similar problems in the future (e.g. when new tables are created).
# validate - Whether to validate the constraint in this call
#
def add_check_constraint(table, check, constraint_name, validate: true)
- validate_check_constraint_name!(constraint_name)
-
# Transactions would result in ALTER TABLE locks being held for the
# duration of the transaction, defeating the purpose of this method.
- if transaction_open?
- raise 'add_check_constraint can not be run inside a transaction'
- end
+ validate_not_in_transaction!(:add_check_constraint)
+
+ validate_check_constraint_name!(constraint_name)
if check_constraint_exists?(table, constraint_name)
warning_message = <<~MESSAGE
@@ -1451,6 +1429,10 @@ into similar problems in the future (e.g. when new tables are created).
end
def remove_check_constraint(table, constraint_name)
+ # This is technically not necessary, but aligned with add_check_constraint
+ # and allows us to continue use with_lock_retries here
+ validate_not_in_transaction!(:remove_check_constraint)
+
validate_check_constraint_name!(constraint_name)
# DROP CONSTRAINT requires an EXCLUSIVE lock
@@ -1649,6 +1631,45 @@ into similar problems in the future (e.g. when new tables are created).
private
+ def create_temporary_columns_and_triggers(table, columns, primary_key: :id, data_type: :bigint)
+ unless table_exists?(table)
+ raise "Table #{table} does not exist"
+ end
+
+ unless column_exists?(table, primary_key)
+ raise "Column #{primary_key} does not exist on #{table}"
+ end
+
+ columns = Array.wrap(columns)
+ columns.each do |column|
+ next if column_exists?(table, column)
+
+ raise ArgumentError, "Column #{column} does not exist on #{table}"
+ end
+
+ check_trigger_permissions!(table)
+
+ conversions = columns.to_h { |column| [column, convert_to_bigint_column(column)] }
+
+ with_lock_retries do
+ conversions.each do |(source_column, temporary_name)|
+ column = column_for(table, source_column)
+
+ if (column.name.to_s == primary_key.to_s) || !column.null
+ # If the column to be converted is either a PK or is defined as NOT NULL,
+ # set it to `NOT NULL DEFAULT 0` and we'll copy paste the correct values bellow
+ # That way, we skip the expensive validation step required to add
+ # a NOT NULL constraint at the end of the process
+ add_column(table, temporary_name, data_type, default: column.default || 0, null: false)
+ else
+ add_column(table, temporary_name, data_type, default: column.default)
+ end
+ end
+
+ install_rename_triggers(table, conversions.keys, conversions.values)
+ end
+ end
+
def validate_check_constraint_name!(constraint_name)
if constraint_name.to_s.length > MAX_IDENTIFIER_NAME_LENGTH
raise "The maximum allowed constraint name is #{MAX_IDENTIFIER_NAME_LENGTH} characters"
diff --git a/lib/gitlab/database/migration_helpers/cascading_namespace_settings.rb b/lib/gitlab/database/migration_helpers/cascading_namespace_settings.rb
index eecf96acb30..d9ef5ab462e 100644
--- a/lib/gitlab/database/migration_helpers/cascading_namespace_settings.rb
+++ b/lib/gitlab/database/migration_helpers/cascading_namespace_settings.rb
@@ -31,10 +31,8 @@ module Gitlab
namespace_options = options.merge(null: true, default: nil)
- with_lock_retries do
- add_column(:namespace_settings, setting_name, type, namespace_options)
- add_column(:namespace_settings, lock_column_name, :boolean, default: false, null: false)
- end
+ add_column(:namespace_settings, setting_name, type, namespace_options)
+ add_column(:namespace_settings, lock_column_name, :boolean, default: false, null: false)
add_column(:application_settings, setting_name, type, options)
add_column(:application_settings, lock_column_name, :boolean, default: false, null: false)
@@ -43,10 +41,8 @@ module Gitlab
def remove_cascading_namespace_setting(setting_name)
lock_column_name = "lock_#{setting_name}".to_sym
- with_lock_retries do
- remove_column(:namespace_settings, setting_name) if column_exists?(:namespace_settings, setting_name)
- remove_column(:namespace_settings, lock_column_name) if column_exists?(:namespace_settings, lock_column_name)
- end
+ remove_column(:namespace_settings, setting_name) if column_exists?(:namespace_settings, setting_name)
+ remove_column(:namespace_settings, lock_column_name) if column_exists?(:namespace_settings, lock_column_name)
remove_column(:application_settings, setting_name) if column_exists?(:application_settings, setting_name)
remove_column(:application_settings, lock_column_name) if column_exists?(:application_settings, lock_column_name)
diff --git a/lib/gitlab/database/migration_helpers/loose_foreign_key_helpers.rb b/lib/gitlab/database/migration_helpers/loose_foreign_key_helpers.rb
new file mode 100644
index 00000000000..30601bffd7a
--- /dev/null
+++ b/lib/gitlab/database/migration_helpers/loose_foreign_key_helpers.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module MigrationHelpers
+ module LooseForeignKeyHelpers
+ include Gitlab::Database::SchemaHelpers
+
+ DELETED_RECORDS_INSERT_FUNCTION_NAME = 'insert_into_loose_foreign_keys_deleted_records'
+
+ def track_record_deletions(table)
+ execute(<<~SQL)
+ CREATE TRIGGER #{record_deletion_trigger_name(table)}
+ AFTER DELETE ON #{table} REFERENCING OLD TABLE AS old_table
+ FOR EACH STATEMENT
+ EXECUTE FUNCTION #{DELETED_RECORDS_INSERT_FUNCTION_NAME}();
+ SQL
+ end
+
+ def untrack_record_deletions(table)
+ drop_trigger(table, record_deletion_trigger_name(table))
+ end
+
+ private
+
+ def record_deletion_trigger_name(table)
+ "#{table}_loose_fk_trigger"
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/migration_helpers/v2.rb b/lib/gitlab/database/migration_helpers/v2.rb
index f20a9b30fa7..0e7f6075196 100644
--- a/lib/gitlab/database/migration_helpers/v2.rb
+++ b/lib/gitlab/database/migration_helpers/v2.rb
@@ -6,6 +6,118 @@ module Gitlab
module V2
include Gitlab::Database::MigrationHelpers
+ # Superseded by `create_table` override below
+ def create_table_with_constraints(*_)
+ raise <<~EOM
+ #create_table_with_constraints is not supported anymore - use #create_table instead, for example:
+
+ create_table :db_guides do |t|
+ t.bigint :stars, default: 0, null: false
+ t.text :title, limit: 128
+ t.text :notes, limit: 1024
+
+ t.check_constraint 'stars > 1000', name: 'so_many_stars'
+ end
+
+ See https://docs.gitlab.com/ee/development/database/strings_and_the_text_data_type.html
+ EOM
+ end
+
+ # Creates a new table, optionally allowing the caller to add text limit constraints to the table.
+ # This method only extends Rails' `create_table` method
+ #
+ # Example:
+ #
+ # create_table :db_guides do |t|
+ # t.bigint :stars, default: 0, null: false
+ # t.text :title, limit: 128
+ # t.text :notes, limit: 1024
+ #
+ # t.check_constraint 'stars > 1000', name: 'so_many_stars'
+ # end
+ #
+ # See Rails' `create_table` for more info on the available arguments.
+ #
+ # When adding foreign keys to other tables, consider wrapping the call into a with_lock_retries block
+ # to avoid traffic stalls.
+ def create_table(table_name, *args, **kwargs, &block)
+ helper_context = self
+
+ super do |t|
+ t.define_singleton_method(:text) do |column_name, **kwargs|
+ limit = kwargs.delete(:limit)
+
+ super(column_name, **kwargs)
+
+ if limit
+ # rubocop:disable GitlabSecurity/PublicSend
+ name = helper_context.send(:text_limit_name, table_name, column_name)
+ # rubocop:enable GitlabSecurity/PublicSend
+
+ column_name = helper_context.quote_column_name(column_name)
+ definition = "char_length(#{column_name}) <= #{limit}"
+
+ t.check_constraint(definition, name: name)
+ end
+ end
+
+ t.instance_eval(&block) unless block.nil?
+ end
+ end
+
+ # Executes the block with a retry mechanism that alters the +lock_timeout+ and +sleep_time+ between attempts.
+ # The timings can be controlled via the +timing_configuration+ parameter.
+ # If the lock was not acquired within the retry period, a last attempt is made without using +lock_timeout+.
+ #
+ # In order to retry the block, the method wraps the block into a transaction.
+ #
+ # When called inside an open transaction it will execute the block directly if lock retries are enabled
+ # with `enable_lock_retries!` at migration level, otherwise it will raise an error.
+ #
+ # ==== Examples
+ # # Invoking without parameters
+ # with_lock_retries do
+ # drop_table :my_table
+ # end
+ #
+ # # Invoking with custom +timing_configuration+
+ # t = [
+ # [1.second, 1.second],
+ # [2.seconds, 2.seconds]
+ # ]
+ #
+ # with_lock_retries(timing_configuration: t) do
+ # drop_table :my_table # this will be retried twice
+ # end
+ #
+ # # Disabling the retries using an environment variable
+ # > export DISABLE_LOCK_RETRIES=true
+ #
+ # with_lock_retries do
+ # drop_table :my_table # one invocation, it will not retry at all
+ # end
+ #
+ # ==== Parameters
+ # * +timing_configuration+ - [[ActiveSupport::Duration, ActiveSupport::Duration], ...] lock timeout for the block, sleep time before the next iteration, defaults to `Gitlab::Database::WithLockRetries::DEFAULT_TIMING_CONFIGURATION`
+ # * +logger+ - [Gitlab::JsonLogger]
+ # * +env+ - [Hash] custom environment hash, see the example with `DISABLE_LOCK_RETRIES`
+ def with_lock_retries(*args, **kwargs, &block)
+ if transaction_open?
+ if enable_lock_retries?
+ Gitlab::AppLogger.warn 'Lock retries already enabled, executing the block directly'
+ yield
+ else
+ raise <<~EOF
+ #{__callee__} can not be run inside an already open transaction
+
+ Use migration-level lock retries instead, see https://docs.gitlab.com/ee/development/migration_style_guide.html#retry-mechanism-when-acquiring-database-locks
+ EOF
+ end
+ else
+ super(*args, **kwargs.merge(allow_savepoints: false), &block)
+ end
+ end
+
# Renames a column without requiring downtime.
#
# Concurrent renames work by using database triggers to ensure both the
diff --git a/lib/gitlab/database/migrations/lock_retry_mixin.rb b/lib/gitlab/database/migrations/lock_retry_mixin.rb
new file mode 100644
index 00000000000..fff0f35e33c
--- /dev/null
+++ b/lib/gitlab/database/migrations/lock_retry_mixin.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module Migrations
+ module LockRetryMixin
+ module ActiveRecordMigrationProxyLockRetries
+ def migration_class
+ migration.class
+ end
+
+ def enable_lock_retries?
+ # regular AR migrations don't have this,
+ # only ones inheriting from Gitlab::Database::Migration have
+ return false unless migration.respond_to?(:enable_lock_retries?)
+
+ migration.enable_lock_retries?
+ end
+ end
+
+ module ActiveRecordMigratorLockRetries
+ # We patch the original method to start a transaction
+ # using the WithLockRetries methodology for the whole migration.
+ def ddl_transaction(migration, &block)
+ if use_transaction?(migration) && migration.enable_lock_retries?
+ Gitlab::Database::WithLockRetries.new(
+ klass: migration.migration_class,
+ logger: Gitlab::BackgroundMigration::Logger
+ ).run(raise_on_exhaustion: false, &block)
+ else
+ super
+ end
+ end
+ end
+
+ def self.patch!
+ ActiveRecord::MigrationProxy.prepend(ActiveRecordMigrationProxyLockRetries)
+ ActiveRecord::Migrator.prepend(ActiveRecordMigratorLockRetries)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/partitioning.rb b/lib/gitlab/database/partitioning.rb
new file mode 100644
index 00000000000..bbde2063c41
--- /dev/null
+++ b/lib/gitlab/database/partitioning.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module Partitioning
+ def self.register_models(models)
+ registered_models.merge(models)
+ end
+
+ def self.registered_models
+ @registered_models ||= Set.new
+ end
+
+ def self.sync_partitions(models_to_sync = registered_models)
+ MultiDatabasePartitionManager.new(models_to_sync).sync_partitions
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/partitioning/monthly_strategy.rb b/lib/gitlab/database/partitioning/monthly_strategy.rb
index 7992c2fdaa7..4cdde5bf2f1 100644
--- a/lib/gitlab/database/partitioning/monthly_strategy.rb
+++ b/lib/gitlab/database/partitioning/monthly_strategy.rb
@@ -4,17 +4,18 @@ module Gitlab
module Database
module Partitioning
class MonthlyStrategy
- attr_reader :model, :partitioning_key, :retain_for
+ attr_reader :model, :partitioning_key, :retain_for, :retain_non_empty_partitions
# We create this many partitions in the future
HEADROOM = 6.months
delegate :table_name, to: :model
- def initialize(model, partitioning_key, retain_for: nil)
+ def initialize(model, partitioning_key, retain_for: nil, retain_non_empty_partitions: false)
@model = model
@partitioning_key = partitioning_key
@retain_for = retain_for
+ @retain_non_empty_partitions = retain_non_empty_partitions
end
def current_partitions
@@ -29,7 +30,10 @@ module Gitlab
end
def extra_partitions
- current_partitions - desired_partitions
+ partitions = current_partitions - desired_partitions
+ partitions.reject!(&:holds_data?) if retain_non_empty_partitions
+
+ partitions
end
private
diff --git a/lib/gitlab/database/partitioning/multi_database_partition_manager.rb b/lib/gitlab/database/partitioning/multi_database_partition_manager.rb
new file mode 100644
index 00000000000..5a93e3fb1fb
--- /dev/null
+++ b/lib/gitlab/database/partitioning/multi_database_partition_manager.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module Partitioning
+ class MultiDatabasePartitionManager
+ def initialize(models)
+ @models = models
+ end
+
+ def sync_partitions
+ Gitlab::AppLogger.info(message: "Syncing dynamic postgres partitions")
+
+ models.each do |model|
+ Gitlab::Database::SharedModel.using_connection(model.connection) do
+ Gitlab::AppLogger.debug(message: "Switched database connection",
+ connection_name: connection_name,
+ table_name: model.table_name)
+
+ PartitionManager.new(model).sync_partitions
+ end
+ end
+
+ Gitlab::AppLogger.info(message: "Finished sync of dynamic postgres partitions")
+ end
+
+ private
+
+ attr_reader :models
+
+ def connection_name
+ Gitlab::Database::SharedModel.connection.pool.db_config.name
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/partitioning/partition_manager.rb b/lib/gitlab/database/partitioning/partition_manager.rb
index 7e433ecdd39..8742c0ff166 100644
--- a/lib/gitlab/database/partitioning/partition_manager.rb
+++ b/lib/gitlab/database/partitioning/partition_manager.rb
@@ -6,60 +6,49 @@ module Gitlab
class PartitionManager
UnsafeToDetachPartitionError = Class.new(StandardError)
- def self.register(model)
- raise ArgumentError, "Only models with a #partitioning_strategy can be registered." unless model.respond_to?(:partitioning_strategy)
-
- models << model
- end
-
- def self.models
- @models ||= Set.new
- end
-
LEASE_TIMEOUT = 1.minute
MANAGEMENT_LEASE_KEY = 'database_partition_management_%s'
RETAIN_DETACHED_PARTITIONS_FOR = 1.week
- attr_reader :models
-
- def initialize(models = self.class.models)
- @models = models
+ def initialize(model)
+ @model = model
end
def sync_partitions
- Gitlab::AppLogger.info("Checking state of dynamic postgres partitions")
+ Gitlab::AppLogger.info(message: "Checking state of dynamic postgres partitions", table_name: model.table_name)
- models.each do |model|
- # Double-checking before getting the lease:
- # The prevailing situation is no missing partitions and no extra partitions
- next if missing_partitions(model).empty? && extra_partitions(model).empty?
+ # Double-checking before getting the lease:
+ # The prevailing situation is no missing partitions and no extra partitions
+ return if missing_partitions.empty? && extra_partitions.empty?
- only_with_exclusive_lease(model, lease_key: MANAGEMENT_LEASE_KEY) do
- partitions_to_create = missing_partitions(model)
- create(partitions_to_create) unless partitions_to_create.empty?
+ only_with_exclusive_lease(model, lease_key: MANAGEMENT_LEASE_KEY) do
+ partitions_to_create = missing_partitions
+ create(partitions_to_create) unless partitions_to_create.empty?
- if Feature.enabled?(:partition_pruning, default_enabled: :yaml)
- partitions_to_detach = extra_partitions(model)
- detach(partitions_to_detach) unless partitions_to_detach.empty?
- end
+ if Feature.enabled?(:partition_pruning, default_enabled: :yaml)
+ partitions_to_detach = extra_partitions
+ detach(partitions_to_detach) unless partitions_to_detach.empty?
end
- rescue StandardError => e
- Gitlab::AppLogger.error(message: "Failed to create / detach partition(s)",
- table_name: model.table_name,
- exception_class: e.class,
- exception_message: e.message)
end
+ rescue StandardError => e
+ Gitlab::AppLogger.error(message: "Failed to create / detach partition(s)",
+ table_name: model.table_name,
+ exception_class: e.class,
+ exception_message: e.message)
end
private
- def missing_partitions(model)
+ attr_reader :model
+ delegate :connection, to: :model
+
+ def missing_partitions
return [] unless connection.table_exists?(model.table_name)
model.partitioning_strategy.missing_partitions
end
- def extra_partitions(model)
+ def extra_partitions
return [] unless connection.table_exists?(model.table_name)
model.partitioning_strategy.extra_partitions
@@ -74,8 +63,9 @@ module Gitlab
end
def create(partitions)
- connection.transaction do
- with_lock_retries do
+ # with_lock_retries starts a requires_new transaction most of the time, but not on the last iteration
+ with_lock_retries do
+ connection.transaction(requires_new: false) do # so we open a transaction here if not already in progress
partitions.each do |partition|
connection.execute partition.to_sql
@@ -88,8 +78,9 @@ module Gitlab
end
def detach(partitions)
- connection.transaction do
- with_lock_retries do
+ # with_lock_retries starts a requires_new transaction most of the time, but not on the last iteration
+ with_lock_retries do
+ connection.transaction(requires_new: false) do # so we open a transaction here if not already in progress
partitions.each { |p| detach_one_partition(p) }
end
end
@@ -119,13 +110,10 @@ module Gitlab
def with_lock_retries(&block)
Gitlab::Database::WithLockRetries.new(
klass: self.class,
- logger: Gitlab::AppLogger
+ logger: Gitlab::AppLogger,
+ connection: connection
).run(&block)
end
-
- def connection
- ActiveRecord::Base.connection
- end
end
end
end
diff --git a/lib/gitlab/database/partitioning/partition_monitoring.rb b/lib/gitlab/database/partitioning/partition_monitoring.rb
index 6963ecd2cc1..e5b561fc447 100644
--- a/lib/gitlab/database/partitioning/partition_monitoring.rb
+++ b/lib/gitlab/database/partitioning/partition_monitoring.rb
@@ -6,7 +6,7 @@ module Gitlab
class PartitionMonitoring
attr_reader :models
- def initialize(models = PartitionManager.models)
+ def initialize(models = Gitlab::Database::Partitioning.registered_models)
@models = models
end
diff --git a/lib/gitlab/database/partitioning/time_partition.rb b/lib/gitlab/database/partitioning/time_partition.rb
index 1221f042530..e09ca483549 100644
--- a/lib/gitlab/database/partitioning/time_partition.rb
+++ b/lib/gitlab/database/partitioning/time_partition.rb
@@ -69,6 +69,10 @@ module Gitlab
partition_name <=> other.partition_name
end
+ def holds_data?
+ conn.execute("SELECT 1 FROM #{fully_qualified_partition} LIMIT 1").ntuples > 0
+ end
+
private
def date_or_nil(obj)
diff --git a/lib/gitlab/database/partitioning_migration_helpers/foreign_key_helpers.rb b/lib/gitlab/database/partitioning_migration_helpers/foreign_key_helpers.rb
index f1aa7871245..bd8ed677d77 100644
--- a/lib/gitlab/database/partitioning_migration_helpers/foreign_key_helpers.rb
+++ b/lib/gitlab/database/partitioning_migration_helpers/foreign_key_helpers.rb
@@ -6,6 +6,8 @@ module Gitlab
module ForeignKeyHelpers
include ::Gitlab::Database::SchemaHelpers
+ ERROR_SCOPE = 'foreign keys'
+
# Adds a foreign key with only minimal locking on the tables involved.
#
# In concept it works similarly to add_concurrent_foreign_key, but we have
@@ -32,6 +34,8 @@ module Gitlab
# name - The name of the foreign key.
#
def add_concurrent_partitioned_foreign_key(source, target, column:, on_delete: :cascade, name: nil)
+ assert_not_in_transaction_block(scope: ERROR_SCOPE)
+
partition_options = {
column: column,
on_delete: on_delete,
diff --git a/lib/gitlab/database/partitioning_migration_helpers/index_helpers.rb b/lib/gitlab/database/partitioning_migration_helpers/index_helpers.rb
index c0cc97de276..c9a3b5caf79 100644
--- a/lib/gitlab/database/partitioning_migration_helpers/index_helpers.rb
+++ b/lib/gitlab/database/partitioning_migration_helpers/index_helpers.rb
@@ -7,6 +7,8 @@ module Gitlab
include Gitlab::Database::MigrationHelpers
include Gitlab::Database::SchemaHelpers
+ ERROR_SCOPE = 'index'
+
# Concurrently creates a new index on a partitioned table. In concept this works similarly to
# `add_concurrent_index`, and won't block reads or writes on the table while the index is being built.
#
@@ -21,6 +23,8 @@ module Gitlab
#
# See Rails' `add_index` for more info on the available arguments.
def add_concurrent_partitioned_index(table_name, column_names, options = {})
+ assert_not_in_transaction_block(scope: ERROR_SCOPE)
+
raise ArgumentError, 'A name is required for indexes added to partitioned tables' unless options[:name]
partitioned_table = find_partitioned_table(table_name)
@@ -57,6 +61,8 @@ module Gitlab
#
# remove_concurrent_partitioned_index_by_name :users, 'index_name_goes_here'
def remove_concurrent_partitioned_index_by_name(table_name, index_name)
+ assert_not_in_transaction_block(scope: ERROR_SCOPE)
+
find_partitioned_table(table_name)
unless index_name_exists?(table_name, index_name)
diff --git a/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers.rb b/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers.rb
index 9ccbdc9930e..0dc9f92e4c8 100644
--- a/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers.rb
+++ b/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers.rb
@@ -431,7 +431,7 @@ module Gitlab
replace_table = Gitlab::Database::Partitioning::ReplaceTable.new(original_table_name.to_s,
replacement_table_name, replaced_table_name, primary_key_name)
- with_lock_retries do
+ transaction do
drop_sync_trigger(original_table_name)
replace_table.perform do |sql|
diff --git a/lib/gitlab/database/postgres_foreign_key.rb b/lib/gitlab/database/postgres_foreign_key.rb
index 94f74724295..72640f8785d 100644
--- a/lib/gitlab/database/postgres_foreign_key.rb
+++ b/lib/gitlab/database/postgres_foreign_key.rb
@@ -2,7 +2,7 @@
module Gitlab
module Database
- class PostgresForeignKey < ApplicationRecord
+ class PostgresForeignKey < SharedModel
self.primary_key = :oid
scope :by_referenced_table_identifier, ->(identifier) do
diff --git a/lib/gitlab/database/postgres_partition.rb b/lib/gitlab/database/postgres_partition.rb
index 7da60d8375d..eb080904f73 100644
--- a/lib/gitlab/database/postgres_partition.rb
+++ b/lib/gitlab/database/postgres_partition.rb
@@ -2,7 +2,7 @@
module Gitlab
module Database
- class PostgresPartition < ActiveRecord::Base
+ class PostgresPartition < SharedModel
self.primary_key = :identifier
belongs_to :postgres_partitioned_table, foreign_key: 'parent_identifier', primary_key: 'identifier'
diff --git a/lib/gitlab/database/postgres_partitioned_table.rb b/lib/gitlab/database/postgres_partitioned_table.rb
index 5d2eaa22ee4..3bd342f940f 100644
--- a/lib/gitlab/database/postgres_partitioned_table.rb
+++ b/lib/gitlab/database/postgres_partitioned_table.rb
@@ -2,7 +2,7 @@
module Gitlab
module Database
- class PostgresPartitionedTable < ActiveRecord::Base
+ class PostgresPartitionedTable < SharedModel
DYNAMIC_PARTITION_STRATEGIES = %w[range list].freeze
self.primary_key = :identifier
diff --git a/lib/gitlab/database/postgresql_adapter/dump_schema_versions_mixin.rb b/lib/gitlab/database/postgresql_adapter/dump_schema_versions_mixin.rb
index a2e7f4befab..59ca06b5aca 100644
--- a/lib/gitlab/database/postgresql_adapter/dump_schema_versions_mixin.rb
+++ b/lib/gitlab/database/postgresql_adapter/dump_schema_versions_mixin.rb
@@ -7,7 +7,7 @@ module Gitlab
extend ActiveSupport::Concern
def dump_schema_information # :nodoc:
- Gitlab::Database::SchemaMigrations.touch_all(self)
+ Gitlab::Database::SchemaMigrations.touch_all(self) if Gitlab.dev_or_test_env?
nil
end
diff --git a/lib/gitlab/database/rename_table_helpers.rb b/lib/gitlab/database/rename_table_helpers.rb
index 7f5af038c6d..e881c0e5455 100644
--- a/lib/gitlab/database/rename_table_helpers.rb
+++ b/lib/gitlab/database/rename_table_helpers.rb
@@ -4,27 +4,27 @@ module Gitlab
module Database
module RenameTableHelpers
def rename_table_safely(old_table_name, new_table_name)
- with_lock_retries do
+ transaction do
rename_table(old_table_name, new_table_name)
execute("CREATE VIEW #{old_table_name} AS SELECT * FROM #{new_table_name}")
end
end
def undo_rename_table_safely(old_table_name, new_table_name)
- with_lock_retries do
+ transaction do
execute("DROP VIEW IF EXISTS #{old_table_name}")
rename_table(new_table_name, old_table_name)
end
end
def finalize_table_rename(old_table_name, new_table_name)
- with_lock_retries do
+ transaction do
execute("DROP VIEW IF EXISTS #{old_table_name}")
end
end
def undo_finalize_table_rename(old_table_name, new_table_name)
- with_lock_retries do
+ transaction do
execute("CREATE VIEW #{old_table_name} AS SELECT * FROM #{new_table_name}")
end
end
diff --git a/lib/gitlab/database/schema_migrations/context.rb b/lib/gitlab/database/schema_migrations/context.rb
index 35105121bbd..a95f85c6bef 100644
--- a/lib/gitlab/database/schema_migrations/context.rb
+++ b/lib/gitlab/database/schema_migrations/context.rb
@@ -6,7 +6,7 @@ module Gitlab
class Context
attr_reader :connection
- DEFAULT_SCHEMA_MIGRATIONS_PATH = "db/schema_migrations"
+ class_attribute :default_schema_migrations_path, default: 'db/schema_migrations'
def initialize(connection)
@connection = connection
@@ -30,7 +30,7 @@ module Gitlab
end
def database_schema_migrations_path
- @connection.pool.db_config.configuration_hash[:schema_migrations_path] || DEFAULT_SCHEMA_MIGRATIONS_PATH
+ @connection.pool.db_config.configuration_hash[:schema_migrations_path] || self.class.default_schema_migrations_path
end
end
end
diff --git a/lib/gitlab/database/shared_model.rb b/lib/gitlab/database/shared_model.rb
new file mode 100644
index 00000000000..8f256758961
--- /dev/null
+++ b/lib/gitlab/database/shared_model.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ class SharedModel < ActiveRecord::Base
+ self.abstract_class = true
+
+ class << self
+ def using_connection(connection)
+ raise 'cannot nest connection overrides for shared models' unless overriding_connection.nil?
+
+ self.overriding_connection = connection
+
+ yield
+ ensure
+ self.overriding_connection = nil
+ end
+
+ def connection
+ if connection = self.overriding_connection
+ connection
+ else
+ super
+ end
+ end
+
+ private
+
+ def overriding_connection
+ Thread.current[:overriding_connection]
+ end
+
+ def overriding_connection=(connection)
+ Thread.current[:overriding_connection] = connection
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/transaction/context.rb b/lib/gitlab/database/transaction/context.rb
index a50dd30b75b..a902537f02e 100644
--- a/lib/gitlab/database/transaction/context.rb
+++ b/lib/gitlab/database/transaction/context.rb
@@ -6,9 +6,8 @@ module Gitlab
class Context
attr_reader :context
- LOG_DEPTH_THRESHOLD = 8
- LOG_SAVEPOINTS_THRESHOLD = 32
- LOG_DURATION_S_THRESHOLD = 300
+ LOG_SAVEPOINTS_THRESHOLD = 1 # 1 `SAVEPOINT` created in a transaction
+ LOG_DURATION_S_THRESHOLD = 120 # transaction that is running for 2 minutes or longer
LOG_THROTTLE_DURATION = 1
def initialize
@@ -19,6 +18,10 @@ module Gitlab
@context[:start_time] = current_timestamp
end
+ def set_depth(depth)
+ @context[:depth] = [@context[:depth].to_i, depth].max
+ end
+
def increment_savepoints
@context[:savepoints] = @context[:savepoints].to_i + 1
end
@@ -31,42 +34,33 @@ module Gitlab
@context[:releases] = @context[:releases].to_i + 1
end
- def set_depth(depth)
- @context[:depth] = [@context[:depth].to_i, depth].max
- end
-
def track_sql(sql)
(@context[:queries] ||= []).push(sql)
end
+ def track_backtrace(backtrace)
+ cleaned_backtrace = Gitlab::BacktraceCleaner.clean_backtrace(backtrace)
+ (@context[:backtraces] ||= []).push(cleaned_backtrace)
+ end
+
def duration
return unless @context[:start_time].present?
current_timestamp - @context[:start_time]
end
- def depth_threshold_exceeded?
- @context[:depth].to_i > LOG_DEPTH_THRESHOLD
- end
-
def savepoints_threshold_exceeded?
- @context[:savepoints].to_i > LOG_SAVEPOINTS_THRESHOLD
+ @context[:savepoints].to_i >= LOG_SAVEPOINTS_THRESHOLD
end
def duration_threshold_exceeded?
- duration.to_i > LOG_DURATION_S_THRESHOLD
- end
-
- def log_savepoints?
- depth_threshold_exceeded? || savepoints_threshold_exceeded?
- end
-
- def log_duration?
- duration_threshold_exceeded?
+ duration.to_i >= LOG_DURATION_S_THRESHOLD
end
def should_log?
- !logged_already? && (log_savepoints? || log_duration?)
+ return false if logged_already?
+
+ savepoints_threshold_exceeded? || duration_threshold_exceeded?
end
def commit
@@ -77,6 +71,10 @@ module Gitlab
log(:rollback)
end
+ def backtraces
+ @context[:backtraces].to_a
+ end
+
private
def queries
@@ -110,7 +108,8 @@ module Gitlab
savepoints_count: @context[:savepoints].to_i,
rollbacks_count: @context[:rollbacks].to_i,
releases_count: @context[:releases].to_i,
- sql: queries
+ sql: queries,
+ savepoint_backtraces: backtraces
}
application_info(attributes)
diff --git a/lib/gitlab/database/transaction/observer.rb b/lib/gitlab/database/transaction/observer.rb
index 7888f0916e3..ad6886a3d52 100644
--- a/lib/gitlab/database/transaction/observer.rb
+++ b/lib/gitlab/database/transaction/observer.rb
@@ -21,9 +21,10 @@ module Gitlab
context.set_start_time
context.set_depth(0)
context.track_sql(event.payload[:sql])
- elsif cmd.start_with?('SAVEPOINT ')
+ elsif cmd.start_with?('SAVEPOINT', 'EXCEPTION')
context.set_depth(manager.open_transactions)
context.increment_savepoints
+ context.track_backtrace(caller)
elsif cmd.start_with?('ROLLBACK TO SAVEPOINT')
context.increment_rollbacks
elsif cmd.start_with?('RELEASE SAVEPOINT ')
diff --git a/lib/gitlab/database/with_lock_retries.rb b/lib/gitlab/database/with_lock_retries.rb
index bbf8f133f0f..f9d467ae5cc 100644
--- a/lib/gitlab/database/with_lock_retries.rb
+++ b/lib/gitlab/database/with_lock_retries.rb
@@ -61,13 +61,15 @@ module Gitlab
[10.seconds, 10.minutes]
].freeze
- def initialize(logger: NULL_LOGGER, timing_configuration: DEFAULT_TIMING_CONFIGURATION, klass: nil, env: ENV)
+ def initialize(logger: NULL_LOGGER, allow_savepoints: true, timing_configuration: DEFAULT_TIMING_CONFIGURATION, klass: nil, env: ENV, connection: ActiveRecord::Base.connection)
@logger = logger
@klass = klass
+ @allow_savepoints = allow_savepoints
@timing_configuration = timing_configuration
@env = env
@current_iteration = 1
@log_params = { method: 'with_lock_retries', class: klass.to_s }
+ @connection = connection
end
# Executes a block of code, retrying it whenever a database lock can't be acquired in time
@@ -95,7 +97,7 @@ module Gitlab
run_block_with_lock_timeout
rescue ActiveRecord::LockWaitTimeout
if retry_with_lock_timeout?
- disable_idle_in_transaction_timeout if ActiveRecord::Base.connection.transaction_open?
+ disable_idle_in_transaction_timeout if connection.transaction_open?
wait_until_next_retry
reset_db_settings
@@ -115,14 +117,16 @@ module Gitlab
private
- attr_reader :logger, :env, :block, :current_iteration, :log_params, :timing_configuration
+ attr_reader :logger, :env, :block, :current_iteration, :log_params, :timing_configuration, :connection
def run_block
block.call
end
def run_block_with_lock_timeout
- ActiveRecord::Base.transaction(requires_new: true) do
+ raise "WithLockRetries should not run inside already open transaction" if connection.transaction_open? && @allow_savepoints.blank?
+
+ connection.transaction(requires_new: true) do # rubocop:disable Performance/ActiveRecordSubtransactions
execute("SET LOCAL lock_timeout TO '#{current_lock_timeout_in_ms}ms'")
log(message: 'Lock timeout is set', current_iteration: current_iteration, lock_timeout_in_ms: current_lock_timeout_in_ms)
@@ -149,7 +153,7 @@ module Gitlab
log(message: "Couldn't acquire lock to perform the migration", current_iteration: current_iteration)
log(message: "Executing the migration without lock timeout", current_iteration: current_iteration)
- disable_lock_timeout if ActiveRecord::Base.connection.transaction_open?
+ disable_lock_timeout if connection.transaction_open?
run_block
@@ -165,7 +169,7 @@ module Gitlab
end
def execute(statement)
- ActiveRecord::Base.connection.execute(statement)
+ connection.execute(statement)
end
def retry_count
diff --git a/lib/gitlab/database_importers/work_items/base_type_importer.rb b/lib/gitlab/database_importers/work_items/base_type_importer.rb
new file mode 100644
index 00000000000..c5acdb41de5
--- /dev/null
+++ b/lib/gitlab/database_importers/work_items/base_type_importer.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module DatabaseImporters
+ module WorkItems
+ module BaseTypeImporter
+ def self.import
+ WorkItem::Type::BASE_TYPES.each do |type, attributes|
+ WorkItem::Type.create!(base_type: type, **attributes.slice(:name, :icon_name))
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/devise_failure.rb b/lib/gitlab/devise_failure.rb
index eb475307f27..111ea697ec2 100644
--- a/lib/gitlab/devise_failure.rb
+++ b/lib/gitlab/devise_failure.rb
@@ -2,18 +2,10 @@
module Gitlab
class DeviseFailure < Devise::FailureApp
- include ::SessionsHelper
-
# If the request format is not known, send a redirect instead of a 401
# response, since this is the outcome we're most likely to want
def http_auth?
request_format && super
end
-
- def respond
- limit_session_time
-
- super
- end
end
end
diff --git a/lib/gitlab/diff/highlight_cache.rb b/lib/gitlab/diff/highlight_cache.rb
index a792eafde79..075027ebdc8 100644
--- a/lib/gitlab/diff/highlight_cache.rb
+++ b/lib/gitlab/diff/highlight_cache.rb
@@ -132,6 +132,8 @@ module Gitlab
diff_file_id,
gzip_compress(highlighted_diff_lines_hash.to_json)
)
+ rescue Encoding::UndefinedConversionError
+ nil
end
# HSETs have to have their expiration date manually updated
diff --git a/lib/gitlab/email/handler/create_issue_handler.rb b/lib/gitlab/email/handler/create_issue_handler.rb
index b110d39818d..4b490ae0d26 100644
--- a/lib/gitlab/email/handler/create_issue_handler.rb
+++ b/lib/gitlab/email/handler/create_issue_handler.rb
@@ -55,7 +55,7 @@ module Gitlab
private
def create_issue
- Issues::CreateService.new(
+ ::Issues::CreateService.new(
project: project,
current_user: author,
params: {
diff --git a/lib/gitlab/email/handler/service_desk_handler.rb b/lib/gitlab/email/handler/service_desk_handler.rb
index 84b55079cea..74c8d0a1fd7 100644
--- a/lib/gitlab/email/handler/service_desk_handler.rb
+++ b/lib/gitlab/email/handler/service_desk_handler.rb
@@ -71,7 +71,7 @@ module Gitlab
end
def create_issue!
- @issue = Issues::CreateService.new(
+ @issue = ::Issues::CreateService.new(
project: project,
current_user: User.support_bot,
params: {
diff --git a/lib/gitlab/email/message/in_product_marketing/team.rb b/lib/gitlab/email/message/in_product_marketing/team.rb
index cf723ad5efd..6a0471ef9c5 100644
--- a/lib/gitlab/email/message/in_product_marketing/team.rb
+++ b/lib/gitlab/email/message/in_product_marketing/team.rb
@@ -23,7 +23,7 @@ module Gitlab
def title
[
- s_('InProductMarketing|Team work makes the dream work'),
+ s_('InProductMarketing|Team work makes the dream work'),
s_('InProductMarketing|*GitLab*, noun: a synonym for efficient teams'),
s_('InProductMarketing|Find out how your teams are really doing')
][series]
diff --git a/lib/gitlab/encoding_helper.rb b/lib/gitlab/encoding_helper.rb
index 50e7631d983..2e0060c7c18 100644
--- a/lib/gitlab/encoding_helper.rb
+++ b/lib/gitlab/encoding_helper.rb
@@ -40,15 +40,7 @@ module Gitlab
def detect_encoding(data, limit: CharlockHolmes::EncodingDetector::DEFAULT_BINARY_SCAN_LEN, cache_key: nil)
return if data.nil?
- if Feature.enabled?(:cached_encoding_detection, type: :development, default_enabled: :yaml)
- return CharlockHolmes::EncodingDetector.new(limit).detect(data) unless cache_key.present?
-
- Rails.cache.fetch([:detect_binary, CharlockHolmes::VERSION, cache_key], expires_in: 1.week) do
- CharlockHolmes::EncodingDetector.new(limit).detect(data)
- end
- else
- CharlockHolmes::EncodingDetector.new(limit).detect(data)
- end
+ CharlockHolmes::EncodingDetector.new(limit).detect(data)
end
def detect_binary?(data, detect = nil)
diff --git a/lib/gitlab/experimentation.rb b/lib/gitlab/experimentation.rb
index 2f78e4e5c0a..c74bd8e75ef 100644
--- a/lib/gitlab/experimentation.rb
+++ b/lib/gitlab/experimentation.rb
@@ -5,12 +5,8 @@
# Utility module for A/B testing experimental features. Define your experiments in the `EXPERIMENTS` constant.
# Experiment options:
# - tracking_category (optional, used to set the category when tracking an experiment event)
-# - use_backwards_compatible_subject_index (optional, set this to true if you need backwards compatibility -- you likely do not need this, see note in the next paragraph.)
# - rollout_strategy: default is `:cookie` based rollout. We may also set it to `:user` based rollout
#
-# Using the backwards-compatible subject index (use_backwards_compatible_subject_index option):
-# This option was added when [the calculation of experimentation_subject_index was changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/45733/diffs#41af4a6fa5a10c7068559ce21c5188483751d934_157_173). It is not intended to be used by new experiments, it exists merely for the segmentation integrity of in-flight experiments at the time the change was deployed. That is, we want users who were assigned to the "experimental" group or the "control" group before the change to still be in those same groups after the change. See [the original issue](https://gitlab.com/gitlab-org/gitlab/-/issues/270858) and [this related comment](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/48110#note_458223745) for more information.
-#
# The experiment is controlled by a Feature Flag (https://docs.gitlab.com/ee/development/feature_flags/controls.html),
# which is named "#{experiment_key}_experiment_percentage" and *must* be set with a percentage and not be used for other purposes.
#
@@ -48,14 +44,6 @@ module Gitlab
show_trial_status_in_sidebar: {
tracking_category: 'Growth::Conversion::Experiment::ShowTrialStatusInSidebar',
rollout_strategy: :group
- },
- learn_gitlab_a: {
- tracking_category: 'Growth::Conversion::Experiment::LearnGitLabA',
- rollout_strategy: :user
- },
- learn_gitlab_b: {
- tracking_category: 'Growth::Activation::Experiment::LearnGitLabB',
- rollout_strategy: :user
}
}.freeze
@@ -118,11 +106,7 @@ module Gitlab
private
def index_for_subject(experiment, subject)
- index = if experiment.use_backwards_compatible_subject_index
- Digest::SHA1.hexdigest(subject_id(subject)).hex
- else
- Zlib.crc32("#{experiment.key}#{subject_id(subject)}")
- end
+ index = Zlib.crc32("#{experiment.key}#{subject_id(subject)}")
index % 100
end
diff --git a/lib/gitlab/experimentation/controller_concern.rb b/lib/gitlab/experimentation/controller_concern.rb
index 2a43f0d5ca9..7cc29cde45c 100644
--- a/lib/gitlab/experimentation/controller_concern.rb
+++ b/lib/gitlab/experimentation/controller_concern.rb
@@ -48,7 +48,7 @@ module Gitlab
Experimentation.log_invalid_rollout(experiment_key, subject)
- subject ||= fallback_experimentation_subject_index(experiment_key)
+ subject ||= experimentation_subject_id
Experimentation.in_experiment_group?(experiment_key, subject: subject)
end
@@ -106,16 +106,6 @@ module Gitlab
cookies.signed[:experimentation_subject_id]
end
- def fallback_experimentation_subject_index(experiment_key)
- return if experimentation_subject_id.blank?
-
- if Experimentation.get_experiment(experiment_key).use_backwards_compatible_subject_index
- experimentation_subject_id.delete('-')
- else
- experimentation_subject_id
- end
- end
-
def track_experiment_event_for(experiment_key, action, value, subject: nil)
return unless Experimentation.active?(experiment_key)
@@ -139,7 +129,7 @@ module Gitlab
def tracking_group(experiment_key, suffix = nil, subject: nil)
return unless Experimentation.active?(experiment_key)
- subject ||= fallback_experimentation_subject_index(experiment_key)
+ subject ||= experimentation_subject_id
group = experiment_enabled?(experiment_key, subject: subject) ? GROUP_EXPERIMENTAL : GROUP_CONTROL
suffix ? "#{group}#{suffix}" : group
diff --git a/lib/gitlab/experimentation/experiment.rb b/lib/gitlab/experimentation/experiment.rb
index 17dda45f5b7..8ba95520638 100644
--- a/lib/gitlab/experimentation/experiment.rb
+++ b/lib/gitlab/experimentation/experiment.rb
@@ -5,12 +5,11 @@ module Gitlab
class Experiment
FEATURE_FLAG_SUFFIX = "_experiment_percentage"
- attr_reader :key, :tracking_category, :use_backwards_compatible_subject_index, :rollout_strategy
+ attr_reader :key, :tracking_category, :rollout_strategy
def initialize(key, **params)
@key = key
@tracking_category = params[:tracking_category]
- @use_backwards_compatible_subject_index = params[:use_backwards_compatible_subject_index]
@rollout_strategy = params[:rollout_strategy] || :cookie
end
diff --git a/lib/gitlab/git.rb b/lib/gitlab/git.rb
index d5ced2045f5..a1855132b0c 100644
--- a/lib/gitlab/git.rb
+++ b/lib/gitlab/git.rb
@@ -5,7 +5,6 @@ require_dependency 'gitlab/encoding_helper'
module Gitlab
module Git
# The ID of empty tree.
- # See http://stackoverflow.com/a/40884093/1856239 and
# https://github.com/git/git/blob/3ad8b5bf26362ac67c9020bf8c30eee54a84f56d/cache.h#L1011-L1012
EMPTY_TREE_ID = '4b825dc642cb6eb9a060e54bf8d69288fbee4904'
BLANK_SHA = ('0' * 40).freeze
diff --git a/lib/gitlab/git/commit.rb b/lib/gitlab/git/commit.rb
index 7fd4acb4179..6605e896ef1 100644
--- a/lib/gitlab/git/commit.rb
+++ b/lib/gitlab/git/commit.rb
@@ -108,20 +108,25 @@ module Gitlab
# See also #repository.commits_between
#
# Ex.
- # Commit.between(repo, '29eda46b', 'master')
+ # Commit.between(repo, '29eda46b', 'master') # all commits, ordered oldest to newest
+ # Commit.between(repo, '29eda46b', 'master', limit: 100) # 100 newest commits, ordered oldest to newest
#
- def between(repo, base, head)
+ def between(repo, base, head, limit: nil)
# In either of these cases, we are guaranteed to return no commits, so
# shortcut the RPC call
return [] if Gitlab::Git.blank_ref?(base) || Gitlab::Git.blank_ref?(head)
wrapped_gitaly_errors do
- if Feature.enabled?(:between_uses_list_commits, default_enabled: :yaml)
- revisions = [head, "^#{base}"] # base..head
-
- repo.gitaly_commit_client.list_commits(revisions, reverse: true)
+ revisions = [head, "^#{base}"] # base..head
+ client = repo.gitaly_commit_client
+
+ # We must return the commits in chronological order but using both
+ # limit and reverse in the Gitaly RPC would return the oldest N,
+ # rather than newest N, commits, so reorder in Ruby with limit
+ if limit
+ client.list_commits(revisions, pagination_params: { limit: limit }).reverse!
else
- repo.gitaly_commit_client.between(base, head)
+ client.list_commits(revisions, reverse: true)
end
end
end
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index 1ab80fe2454..bc15bd367d8 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -127,6 +127,13 @@ module Gitlab
end
end
+ def find_tag(name)
+ wrapped_gitaly_errors do
+ gitaly_ref_client.find_tag(name)
+ end
+ rescue CommandError
+ end
+
def local_branches(sort_by: nil, pagination_params: nil)
wrapped_gitaly_errors do
gitaly_ref_client.local_branches(sort_by: sort_by, pagination_params: pagination_params)
@@ -191,9 +198,9 @@ module Gitlab
# Returns an Array of Tags
#
- def tags
+ def tags(sort_by: nil)
wrapped_gitaly_errors do
- gitaly_ref_client.tags
+ gitaly_ref_client.tags(sort_by: sort_by)
end
end
@@ -360,27 +367,31 @@ module Gitlab
end
end
- def new_blobs(newrev, dynamic_timeout: nil)
- return [] if newrev.blank? || newrev == ::Gitlab::Git::BLANK_SHA
+ def new_blobs(newrevs, dynamic_timeout: nil)
+ newrevs = Array.wrap(newrevs).reject { |rev| rev.blank? || rev == ::Gitlab::Git::BLANK_SHA }
+ return [] if newrevs.empty?
- strong_memoize("new_blobs_#{newrev}") do
- wrapped_gitaly_errors do
- gitaly_ref_client.list_new_blobs(newrev, REV_LIST_COMMIT_LIMIT, dynamic_timeout: dynamic_timeout)
- end
+ newrevs = newrevs.uniq.sort
+
+ @new_blobs ||= Hash.new do |h, revs|
+ h[revs] = blobs(['--not', '--all', '--not'] + newrevs, with_paths: true, dynamic_timeout: dynamic_timeout)
end
+
+ @new_blobs[newrevs]
end
# List blobs reachable via a set of revisions. Supports the
# pseudo-revisions `--not` and `--all`. Uses the minimum of
# GitalyClient.medium_timeout and dynamic timeout if the dynamic
# timeout is set, otherwise it'll always use the medium timeout.
- def blobs(revisions, dynamic_timeout: nil)
+ def blobs(revisions, with_paths: false, dynamic_timeout: nil)
revisions = revisions.reject { |rev| rev.blank? || rev == ::Gitlab::Git::BLANK_SHA }
return [] if revisions.blank?
wrapped_gitaly_errors do
- gitaly_blob_client.list_blobs(revisions, limit: REV_LIST_COMMIT_LIMIT, dynamic_timeout: dynamic_timeout)
+ gitaly_blob_client.list_blobs(revisions, limit: REV_LIST_COMMIT_LIMIT,
+ with_paths: with_paths, dynamic_timeout: dynamic_timeout)
end
end
@@ -491,13 +502,6 @@ module Gitlab
[]
end
- # Returns a RefName for a given SHA
- def ref_name_for_sha(ref_path, sha)
- raise ArgumentError, "sha can't be empty" unless sha.present?
-
- gitaly_ref_client.find_ref_name(sha, ref_path)
- end
-
# Get refs hash which key is the commit id
# and value is a Gitlab::Git::Tag or Gitlab::Git::Branch
# Note that both inherit from Gitlab::Git::Ref
@@ -607,10 +611,6 @@ module Gitlab
end
end
- def find_tag(name)
- tags.find { |tag| tag.name == name }
- end
-
def merge_to_ref(user, **kwargs)
wrapped_gitaly_errors do
gitaly_operation_client.user_merge_to_ref(user, **kwargs)
@@ -876,12 +876,6 @@ module Gitlab
end
end
- def squash_in_progress?(squash_id)
- wrapped_gitaly_errors do
- gitaly_repository_client.squash_in_progress?(squash_id)
- end
- end
-
def bundle_to_disk(save_path)
wrapped_gitaly_errors do
gitaly_repository_client.create_bundle(save_path)
@@ -911,17 +905,7 @@ module Gitlab
# This guard avoids Gitaly log/error spam
raise NoRepository, 'repository does not exist' unless exists?
- if Feature.enabled?(:set_full_path)
- gitaly_repository_client.set_full_path(full_path)
- else
- set_config('gitlab.fullpath' => full_path)
- end
- end
-
- def set_config(entries)
- wrapped_gitaly_errors do
- gitaly_repository_client.set_config(entries)
- end
+ gitaly_repository_client.set_full_path(full_path)
end
def disconnect_alternates
diff --git a/lib/gitlab/git/rugged_impl/tree.rb b/lib/gitlab/git/rugged_impl/tree.rb
index 5993c8888d3..40c003821b9 100644
--- a/lib/gitlab/git/rugged_impl/tree.rb
+++ b/lib/gitlab/git/rugged_impl/tree.rb
@@ -13,18 +13,53 @@ module Gitlab
extend ::Gitlab::Utils::Override
include Gitlab::Git::RuggedImpl::UseRugged
+ TREE_SORT_ORDER = { tree: 0, blob: 1, commit: 2 }.freeze
+
override :tree_entries
def tree_entries(repository, sha, path, recursive, pagination_params = nil)
if use_rugged?(repository, :rugged_tree_entries)
- [
- execute_rugged_call(:tree_entries_with_flat_path_from_rugged, repository, sha, path, recursive),
- nil
- ]
+ entries = execute_rugged_call(:tree_entries_with_flat_path_from_rugged, repository, sha, path, recursive)
+
+ if pagination_params
+ paginated_response(entries, pagination_params[:limit], pagination_params[:page_token].to_s)
+ else
+ [entries, nil]
+ end
else
super
end
end
+ # Rugged version of TreePagination in Go: https://gitlab.com/gitlab-org/gitaly/-/merge_requests/3611
+ def paginated_response(entries, limit, token)
+ total_entries = entries.count
+
+ return [[], nil] if limit == 0 || limit.blank?
+
+ entries = Gitlab::Utils.stable_sort_by(entries) { |x| TREE_SORT_ORDER[x.type] }
+
+ if token.blank?
+ index = 0
+ else
+ index = entries.index { |entry| entry.id == token }
+
+ raise Gitlab::Git::CommandError, "could not find starting OID: #{token}" if index.nil?
+
+ index += 1
+ end
+
+ return [entries[index..], nil] if limit < 0
+
+ last_index = index + limit
+ result = entries[index...last_index]
+
+ if last_index < total_entries
+ cursor = Gitaly::PaginationCursor.new(next_cursor: result.last.id)
+ end
+
+ [result, cursor]
+ end
+
def tree_entries_with_flat_path_from_rugged(repository, sha, path, recursive)
tree_entries_from_rugged(repository, sha, path, recursive).tap do |entries|
# This was an optimization to reduce N+1 queries for Gitaly
diff --git a/lib/gitlab/git/user.rb b/lib/gitlab/git/user.rb
index 05ae3391040..0798cc51055 100644
--- a/lib/gitlab/git/user.rb
+++ b/lib/gitlab/git/user.rb
@@ -6,7 +6,7 @@ module Gitlab
attr_reader :username, :name, :email, :gl_id, :timezone
def self.from_gitlab(gitlab_user)
- new(gitlab_user.username, gitlab_user.name, gitlab_user.commit_email, Gitlab::GlId.gl_id(gitlab_user), gitlab_user.timezone)
+ new(gitlab_user.username, gitlab_user.name, gitlab_user.commit_email_or_default, Gitlab::GlId.gl_id(gitlab_user), gitlab_user.timezone)
end
def self.from_gitaly(gitaly_user)
diff --git a/lib/gitlab/gitaly_client/blob_service.rb b/lib/gitlab/gitaly_client/blob_service.rb
index 362ecbd845d..3b08a833aeb 100644
--- a/lib/gitlab/gitaly_client/blob_service.rb
+++ b/lib/gitlab/gitaly_client/blob_service.rb
@@ -19,12 +19,13 @@ module Gitlab
consume_blob_response(response)
end
- def list_blobs(revisions, limit: 0, bytes_limit: 0, dynamic_timeout: nil)
+ def list_blobs(revisions, limit: 0, bytes_limit: 0, with_paths: false, dynamic_timeout: nil)
request = Gitaly::ListBlobsRequest.new(
repository: @gitaly_repo,
revisions: Array.wrap(revisions),
limit: limit,
- bytes_limit: bytes_limit
+ bytes_limit: bytes_limit,
+ with_paths: with_paths
)
timeout =
diff --git a/lib/gitlab/gitaly_client/commit_service.rb b/lib/gitlab/gitaly_client/commit_service.rb
index fa616a252e4..75588ad980c 100644
--- a/lib/gitlab/gitaly_client/commit_service.rb
+++ b/lib/gitlab/gitaly_client/commit_service.rb
@@ -127,6 +127,7 @@ module Gitlab
entries = response.flat_map do |message|
cursor = message.pagination_cursor if message.pagination_cursor
+
message.entries.map do |gitaly_tree_entry|
Gitlab::Git::Tree.new(
id: gitaly_tree_entry.oid,
@@ -255,11 +256,12 @@ module Gitlab
consume_commits_response(response)
end
- def list_commits(revisions, reverse: false)
+ def list_commits(revisions, reverse: false, pagination_params: nil)
request = Gitaly::ListCommitsRequest.new(
repository: @gitaly_repo,
revisions: Array.wrap(revisions),
- reverse: reverse
+ reverse: reverse,
+ pagination_params: pagination_params
)
response = GitalyClient.call(@repository.storage, :commit_service, :list_commits, request, timeout: GitalyClient.medium_timeout)
diff --git a/lib/gitlab/gitaly_client/ref_service.rb b/lib/gitlab/gitaly_client/ref_service.rb
index 7097d5bd181..235eef4575e 100644
--- a/lib/gitlab/gitaly_client/ref_service.rb
+++ b/lib/gitlab/gitaly_client/ref_service.rb
@@ -5,6 +5,16 @@ module Gitlab
class RefService
include Gitlab::EncodingHelper
+ TAGS_SORT_KEY = {
+ 'name' => Gitaly::FindAllTagsRequest::SortBy::Key::REFNAME,
+ 'updated' => Gitaly::FindAllTagsRequest::SortBy::Key::CREATORDATE
+ }.freeze
+
+ TAGS_SORT_DIRECTION = {
+ 'asc' => Gitaly::SortDirection::ASCENDING,
+ 'desc' => Gitaly::SortDirection::DESCENDING
+ }.freeze
+
# 'repository' is a Gitlab::Git::Repository
def initialize(repository)
@repository = repository
@@ -52,38 +62,6 @@ module Gitlab
consume_refs_response(response) { |name| Gitlab::Git.tag_name(name) }
end
- def find_ref_name(commit_id, ref_prefix)
- request = Gitaly::FindRefNameRequest.new(
- repository: @gitaly_repo,
- commit_id: commit_id,
- prefix: ref_prefix
- )
- response = GitalyClient.call(@storage, :ref_service, :find_ref_name, request, timeout: GitalyClient.medium_timeout)
- encode!(response.name.dup)
- end
-
- def list_new_blobs(newrev, limit = 0, dynamic_timeout: nil)
- request = Gitaly::ListNewBlobsRequest.new(
- repository: @gitaly_repo,
- commit_id: newrev,
- limit: limit
- )
-
- timeout =
- if dynamic_timeout
- [dynamic_timeout, GitalyClient.medium_timeout].min
- else
- GitalyClient.medium_timeout
- end
-
- response = GitalyClient.call(@storage, :ref_service, :list_new_blobs, request, timeout: timeout)
- response.flat_map do |msg|
- # Returns an Array of Gitaly::NewBlobObject objects
- # Available methods are: #size, #oid and #path
- msg.new_blob_objects
- end
- end
-
def count_tag_names
tag_names.count
end
@@ -94,13 +72,15 @@ module Gitlab
def local_branches(sort_by: nil, pagination_params: nil)
request = Gitaly::FindLocalBranchesRequest.new(repository: @gitaly_repo, pagination_params: pagination_params)
- request.sort_by = sort_by_param(sort_by) if sort_by
+ request.sort_by = sort_local_branches_by_param(sort_by) if sort_by
response = GitalyClient.call(@storage, :ref_service, :find_local_branches, request, timeout: GitalyClient.fast_timeout)
consume_find_local_branches_response(response)
end
- def tags
+ def tags(sort_by: nil)
request = Gitaly::FindAllTagsRequest.new(repository: @gitaly_repo)
+ request.sort_by = sort_tags_by_param(sort_by) if sort_by
+
response = GitalyClient.call(@storage, :ref_service, :find_all_tags, request, timeout: GitalyClient.medium_timeout)
consume_tags_response(response)
end
@@ -127,6 +107,21 @@ module Gitlab
Gitlab::Git::Branch.new(@repository, encode!(branch.name.dup), branch.target_commit.id, target_commit)
end
+ def find_tag(tag_name)
+ return if tag_name.blank?
+
+ request = Gitaly::FindTagRequest.new(
+ repository: @gitaly_repo,
+ tag_name: encode_binary(tag_name)
+ )
+
+ response = GitalyClient.call(@repository.storage, :ref_service, :find_tag, request, timeout: GitalyClient.medium_timeout)
+ tag = response.tag
+ return unless tag
+
+ Gitlab::Git::Tag.new(@repository, tag)
+ end
+
def delete_refs(refs: [], except_with_prefixes: [])
request = Gitaly::DeleteRefsRequest.new(
repository: @gitaly_repo,
@@ -211,7 +206,7 @@ module Gitlab
response.flat_map { |message| message.names.map { |name| yield(name) } }
end
- def sort_by_param(sort_by)
+ def sort_local_branches_by_param(sort_by)
sort_by = 'name' if sort_by == 'name_asc'
enum_value = Gitaly::FindLocalBranchesRequest::SortBy.resolve(sort_by.upcase.to_sym)
@@ -220,6 +215,17 @@ module Gitlab
enum_value
end
+ def sort_tags_by_param(sort_by)
+ match = sort_by.match(/^(?<key>name|updated)_(?<direction>asc|desc)$/)
+
+ return unless match
+
+ Gitaly::FindAllTagsRequest::SortBy.new(
+ key: TAGS_SORT_KEY[match[:key]],
+ direction: TAGS_SORT_DIRECTION[match[:direction]]
+ )
+ end
+
def consume_find_local_branches_response(response)
response.flat_map do |message|
message.branches.map do |gitaly_branch|
diff --git a/lib/gitlab/gitaly_client/repository_service.rb b/lib/gitlab/gitaly_client/repository_service.rb
index 2e26b3341a2..7e7d543d0a5 100644
--- a/lib/gitlab/gitaly_client/repository_service.rb
+++ b/lib/gitlab/gitaly_client/repository_service.rb
@@ -155,23 +155,6 @@ module Gitlab
)
end
- def squash_in_progress?(squash_id)
- request = Gitaly::IsSquashInProgressRequest.new(
- repository: @gitaly_repo,
- squash_id: squash_id.to_s
- )
-
- response = GitalyClient.call(
- @storage,
- :repository_service,
- :is_squash_in_progress,
- request,
- timeout: GitalyClient.fast_timeout
- )
-
- response.in_progress
- end
-
def fetch_source_branch(source_repository, source_branch, local_ref)
request = Gitaly::FetchSourceBranchRequest.new(
repository: @gitaly_repo,
@@ -281,25 +264,6 @@ module Gitlab
nil
end
- def set_config(entries)
- return if entries.empty?
-
- request = Gitaly::SetConfigRequest.new(repository: @gitaly_repo)
- entries.each do |key, value|
- request.entries << build_set_config_entry(key, value)
- end
-
- GitalyClient.call(
- @storage,
- :repository_service,
- :set_config,
- request,
- timeout: GitalyClient.fast_timeout
- )
-
- nil
- end
-
def license_short_name
request = Gitaly::FindLicenseRequest.new(repository: @gitaly_repo)
diff --git a/lib/gitlab/github_import.rb b/lib/gitlab/github_import.rb
index c3cc15e10f7..7ac0d875512 100644
--- a/lib/gitlab/github_import.rb
+++ b/lib/gitlab/github_import.rb
@@ -11,6 +11,7 @@ module Gitlab
Client.new(
token_to_use,
host: host.presence || self.formatted_import_url(project),
+ per_page: self.per_page(project),
parallel: parallel
)
end
@@ -33,5 +34,13 @@ module Gitlab
url.to_s
end
end
+
+ def self.per_page(project)
+ if project.group.present? && Feature.enabled?(:github_importer_lower_per_page_limit, project.group, type: :ops, default_enabled: :yaml)
+ Gitlab::GithubImport::Client::LOWER_PER_PAGE
+ else
+ Gitlab::GithubImport::Client::DEFAULT_PER_PAGE
+ end
+ end
end
end
diff --git a/lib/gitlab/github_import/client.rb b/lib/gitlab/github_import/client.rb
index 138716b1b53..efa816c5eb0 100644
--- a/lib/gitlab/github_import/client.rb
+++ b/lib/gitlab/github_import/client.rb
@@ -19,6 +19,8 @@ module Gitlab
attr_reader :octokit
SEARCH_MAX_REQUESTS_PER_MINUTE = 30
+ DEFAULT_PER_PAGE = 100
+ LOWER_PER_PAGE = 50
# A single page of data and the corresponding page number.
Page = Struct.new(:objects, :number)
@@ -44,7 +46,7 @@ module Gitlab
# this value to `true` for parallel importing is crucial as
# otherwise hitting the rate limit will result in a thread
# being blocked in a `sleep()` call for up to an hour.
- def initialize(token, host: nil, per_page: 100, parallel: true)
+ def initialize(token, host: nil, per_page: DEFAULT_PER_PAGE, parallel: true)
@host = host
@octokit = ::Octokit::Client.new(
access_token: token,
diff --git a/lib/gitlab/github_import/importer/diff_note_importer.rb b/lib/gitlab/github_import/importer/diff_note_importer.rb
index 9bda066efcc..4cfc920e2e3 100644
--- a/lib/gitlab/github_import/importer/diff_note_importer.rb
+++ b/lib/gitlab/github_import/importer/diff_note_importer.rb
@@ -24,13 +24,14 @@ module Gitlab
note_body = MarkdownText.format(note.note, note.author, author_found)
attributes = {
+ discussion_id: Discussion.discussion_id(note),
noteable_type: 'MergeRequest',
noteable_id: mr_id,
project_id: project.id,
author_id: author_id,
note: note_body,
system: false,
- commit_id: note.commit_id,
+ commit_id: note.original_commit_id,
line_code: note.line_code,
type: 'LegacyDiffNote',
created_at: note.created_at,
diff --git a/lib/gitlab/github_import/importer/single_endpoint_diff_notes_importer.rb b/lib/gitlab/github_import/importer/single_endpoint_diff_notes_importer.rb
new file mode 100644
index 00000000000..a2c3d1bd057
--- /dev/null
+++ b/lib/gitlab/github_import/importer/single_endpoint_diff_notes_importer.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+# This importer is used when `github_importer_single_endpoint_notes_import`
+# feature flag is on and replaces `DiffNotesImporter`.
+#
+# It fetches 1 PR's diff notes at a time using `pull_request_comments` endpoint, which is
+# slower than `NotesImporter` but it makes sure all notes are imported,
+# as it can sometimes not be the case for `NotesImporter`, because
+# `issues_comments` endpoint it uses can be limited by GitHub API
+# to not return all available pages.
+module Gitlab
+ module GithubImport
+ module Importer
+ class SingleEndpointDiffNotesImporter
+ include ParallelScheduling
+ include SingleEndpointNotesImporting
+
+ def importer_class
+ DiffNoteImporter
+ end
+
+ def representation_class
+ Representation::DiffNote
+ end
+
+ def sidekiq_worker_class
+ ImportDiffNoteWorker
+ end
+
+ def object_type
+ :diff_note
+ end
+
+ def collection_method
+ :pull_request_comments
+ end
+
+ private
+
+ def noteables
+ project.merge_requests.where.not(iid: already_imported_noteables) # rubocop: disable CodeReuse/ActiveRecord
+ end
+
+ def page_counter_id(merge_request)
+ "merge_request/#{merge_request.id}/#{collection_method}"
+ end
+
+ def notes_imported_cache_key
+ "github-importer/merge_request/diff_notes/already-imported/#{project.id}"
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/github_import/importer/single_endpoint_issue_notes_importer.rb b/lib/gitlab/github_import/importer/single_endpoint_issue_notes_importer.rb
new file mode 100644
index 00000000000..49569ed52d8
--- /dev/null
+++ b/lib/gitlab/github_import/importer/single_endpoint_issue_notes_importer.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+# This importer is used when `github_importer_single_endpoint_notes_import`
+# feature flag is on and replaces `IssuesImporter` issue notes import.
+#
+# It fetches 1 issue's comments at a time using `issue_comments` endpoint, which is
+# slower than `NotesImporter` but it makes sure all notes are imported,
+# as it can sometimes not be the case for `NotesImporter`, because
+# `issues_comments` endpoint it uses can be limited by GitHub API
+# to not return all available pages.
+module Gitlab
+ module GithubImport
+ module Importer
+ class SingleEndpointIssueNotesImporter
+ include ParallelScheduling
+ include SingleEndpointNotesImporting
+
+ def importer_class
+ NoteImporter
+ end
+
+ def representation_class
+ Representation::Note
+ end
+
+ def sidekiq_worker_class
+ ImportNoteWorker
+ end
+
+ def object_type
+ :note
+ end
+
+ def collection_method
+ :issue_comments
+ end
+
+ private
+
+ def noteables
+ project.issues.where.not(iid: already_imported_noteables) # rubocop: disable CodeReuse/ActiveRecord
+ end
+
+ def page_counter_id(issue)
+ "issue/#{issue.id}/#{collection_method}"
+ end
+
+ def notes_imported_cache_key
+ "github-importer/issue/notes/already-imported/#{project.id}"
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/github_import/importer/single_endpoint_merge_request_notes_importer.rb b/lib/gitlab/github_import/importer/single_endpoint_merge_request_notes_importer.rb
new file mode 100644
index 00000000000..d837639c14d
--- /dev/null
+++ b/lib/gitlab/github_import/importer/single_endpoint_merge_request_notes_importer.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+# This importer is used when `github_importer_single_endpoint_notes_import`
+# feature flag is on and replaces `NotesImporter` MR notes import.
+#
+# It fetches 1 PR's comments at a time using `issue_comments` endpoint, which is
+# slower than `NotesImporter` but it makes sure all notes are imported,
+# as it can sometimes not be the case for `NotesImporter`, because
+# `issues_comments` endpoint it uses can be limited by GitHub API
+# to not return all available pages.
+module Gitlab
+ module GithubImport
+ module Importer
+ class SingleEndpointMergeRequestNotesImporter
+ include ParallelScheduling
+ include SingleEndpointNotesImporting
+
+ def importer_class
+ NoteImporter
+ end
+
+ def representation_class
+ Representation::Note
+ end
+
+ def sidekiq_worker_class
+ ImportNoteWorker
+ end
+
+ def object_type
+ :note
+ end
+
+ def collection_method
+ :issue_comments
+ end
+
+ private
+
+ def noteables
+ project.merge_requests.where.not(iid: already_imported_noteables) # rubocop: disable CodeReuse/ActiveRecord
+ end
+
+ def page_counter_id(merge_request)
+ "merge_request/#{merge_request.id}/#{collection_method}"
+ end
+
+ def notes_imported_cache_key
+ "github-importer/merge_request/notes/already-imported/#{project.id}"
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/github_import/issuable_finder.rb b/lib/gitlab/github_import/issuable_finder.rb
index 136531505ea..5298a3d81ea 100644
--- a/lib/gitlab/github_import/issuable_finder.rb
+++ b/lib/gitlab/github_import/issuable_finder.rb
@@ -23,7 +23,7 @@ module Gitlab
#
# This method will return `nil` if no ID could be found.
def database_id
- val = Gitlab::Cache::Import::Caching.read(cache_key)
+ val = Gitlab::Cache::Import::Caching.read(cache_key, timeout: timeout)
val.to_i if val.present?
end
@@ -32,7 +32,7 @@ module Gitlab
#
# database_id - The ID of the corresponding database row.
def cache_database_id(database_id)
- Gitlab::Cache::Import::Caching.write(cache_key, database_id)
+ Gitlab::Cache::Import::Caching.write(cache_key, database_id, timeout: timeout)
end
private
@@ -76,6 +76,14 @@ module Gitlab
)
end
end
+
+ def timeout
+ if project.group.present? && ::Feature.enabled?(:github_importer_single_endpoint_notes_import, project.group, type: :ops, default_enabled: :yaml)
+ Gitlab::Cache::Import::Caching::LONGER_TIMEOUT
+ else
+ Gitlab::Cache::Import::Caching::TIMEOUT
+ end
+ end
end
end
end
diff --git a/lib/gitlab/github_import/parallel_scheduling.rb b/lib/gitlab/github_import/parallel_scheduling.rb
index 8c76f5a9d94..4d0074e43d7 100644
--- a/lib/gitlab/github_import/parallel_scheduling.rb
+++ b/lib/gitlab/github_import/parallel_scheduling.rb
@@ -44,7 +44,7 @@ module Gitlab
# still scheduling duplicates while. Since all work has already been
# completed those jobs will just cycle through any remaining pages while
# not scheduling anything.
- Gitlab::Cache::Import::Caching.expire(already_imported_cache_key, 15.minutes.to_i)
+ Gitlab::Cache::Import::Caching.expire(already_imported_cache_key, Gitlab::Cache::Import::Caching::SHORTER_TIMEOUT)
info(project.id, message: "importer finished")
retval
diff --git a/lib/gitlab/github_import/representation/diff_note.rb b/lib/gitlab/github_import/representation/diff_note.rb
index d336b1ba797..d0584cc6255 100644
--- a/lib/gitlab/github_import/representation/diff_note.rb
+++ b/lib/gitlab/github_import/representation/diff_note.rb
@@ -11,7 +11,7 @@ module Gitlab
expose_attribute :noteable_type, :noteable_id, :commit_id, :file_path,
:diff_hunk, :author, :note, :created_at, :updated_at,
- :github_id
+ :github_id, :original_commit_id
NOTEABLE_ID_REGEX = %r{/pull/(?<iid>\d+)}i.freeze
@@ -34,6 +34,7 @@ module Gitlab
noteable_id: matches[:iid].to_i,
file_path: note.path,
commit_id: note.commit_id,
+ original_commit_id: note.original_commit_id,
diff_hunk: note.diff_hunk,
author: user,
note: note.body,
diff --git a/lib/gitlab/github_import/single_endpoint_notes_importing.rb b/lib/gitlab/github_import/single_endpoint_notes_importing.rb
new file mode 100644
index 00000000000..43402ecd165
--- /dev/null
+++ b/lib/gitlab/github_import/single_endpoint_notes_importing.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+
+# This module is used in:
+# - SingleEndpointDiffNotesImporter
+# - SingleEndpointIssueNotesImporter
+# - SingleEndpointMergeRequestNotesImporter
+#
+# `github_importer_single_endpoint_notes_import`
+# feature flag is on.
+#
+# It fetches 1 PR's associated objects at a time using `issue_comments` or
+# `pull_request_comments` endpoint, which is slower than `NotesImporter`
+# but it makes sure all notes are imported, as it can sometimes not be
+# the case for `NotesImporter`, because `issues_comments` endpoint
+# it uses can be limited by GitHub API to not return all available pages.
+module Gitlab
+ module GithubImport
+ module SingleEndpointNotesImporting
+ BATCH_SIZE = 100
+
+ def each_object_to_import
+ each_notes_page do |page|
+ page.objects.each do |note|
+ next if already_imported?(note)
+
+ Gitlab::GithubImport::ObjectCounter.increment(project, object_type, :fetched)
+
+ yield(note)
+
+ mark_as_imported(note)
+ end
+ end
+ end
+
+ def id_for_already_imported_cache(note)
+ note.id
+ end
+
+ private
+
+ def each_notes_page
+ noteables.each_batch(of: BATCH_SIZE, column: :iid) do |batch|
+ batch.each do |noteable|
+ # The page counter needs to be scoped by noteable to avoid skipping
+ # pages of notes from already imported noteables.
+ page_counter = PageCounter.new(project, page_counter_id(noteable))
+ repo = project.import_source
+ options = collection_options.merge(page: page_counter.current)
+
+ client.each_page(collection_method, repo, noteable.iid, options) do |page|
+ next unless page_counter.set(page.number)
+
+ yield page
+ end
+
+ mark_notes_imported(noteable)
+ end
+ end
+ end
+
+ def mark_notes_imported(noteable)
+ Gitlab::Cache::Import::Caching.set_add(
+ notes_imported_cache_key,
+ noteable.iid
+ )
+ end
+
+ def already_imported_noteables
+ Gitlab::Cache::Import::Caching.values_from_set(notes_imported_cache_key)
+ end
+
+ def noteables
+ NotImplementedError
+ end
+
+ def notes_imported_cache_key
+ NotImplementedError
+ end
+
+ def page_counter_id(noteable)
+ NotImplementedError
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/github_import/user_finder.rb b/lib/gitlab/github_import/user_finder.rb
index f583ef39d13..93483ee697a 100644
--- a/lib/gitlab/github_import/user_finder.rb
+++ b/lib/gitlab/github_import/user_finder.rb
@@ -106,7 +106,7 @@ module Gitlab
unless email
user = client.user(username)
- email = Gitlab::Cache::Import::Caching.write(cache_key, user.email) if user
+ email = Gitlab::Cache::Import::Caching.write(cache_key, user.email, timeout: timeout(user.email)) if user
end
email
@@ -171,6 +171,16 @@ module Gitlab
# which we couldn't find an ID.
[exists, number > 0 ? number : nil]
end
+
+ private
+
+ def timeout(email)
+ if email
+ Gitlab::Cache::Import::Caching::TIMEOUT
+ else
+ Gitlab::Cache::Import::Caching::SHORTER_TIMEOUT
+ end
+ end
end
end
end
diff --git a/lib/gitlab/gon_helper.rb b/lib/gitlab/gon_helper.rb
index 16a8b5f959e..258c13894fb 100644
--- a/lib/gitlab/gon_helper.rb
+++ b/lib/gitlab/gon_helper.rb
@@ -21,6 +21,8 @@ module Gitlab
gon.sentry_environment = Gitlab.config.sentry.environment
end
+ gon.recaptcha_api_server_url = ::Recaptcha.configuration.api_server_url
+ gon.recaptcha_sitekey = Gitlab::CurrentSettings.recaptcha_site_key
gon.gitlab_url = Gitlab.config.gitlab.url
gon.revision = Gitlab.revision
gon.feature_category = Gitlab::ApplicationContext.current_context_attribute(:feature_category).presence
@@ -35,6 +37,7 @@ module Gitlab
gon.first_day_of_week = current_user&.first_day_of_week || Gitlab::CurrentSettings.first_day_of_week
gon.time_display_relative = true
gon.ee = Gitlab.ee?
+ gon.jh = Gitlab.jh?
gon.dot_com = Gitlab.com?
if current_user
@@ -51,6 +54,7 @@ module Gitlab
push_frontend_feature_flag(:usage_data_api, type: :ops, default_enabled: :yaml)
push_frontend_feature_flag(:security_auto_fix, default_enabled: false)
push_frontend_feature_flag(:improved_emoji_picker, default_enabled: :yaml)
+ push_frontend_feature_flag(:new_header_search, default_enabled: :yaml)
end
# Exposes the state of a feature flag to the frontend code.
diff --git a/lib/gitlab/graphql/authorize/connection_filter_extension.rb b/lib/gitlab/graphql/authorize/connection_filter_extension.rb
index c75510df3e3..889c024ab5e 100644
--- a/lib/gitlab/graphql/authorize/connection_filter_extension.rb
+++ b/lib/gitlab/graphql/authorize/connection_filter_extension.rb
@@ -7,12 +7,14 @@ module Gitlab
class Redactor
include ::Gitlab::Graphql::Laziness
- def initialize(type, context)
+ def initialize(type, context, resolver)
@type = type
@context = context
+ @resolver = resolver
end
def redact(nodes)
+ perform_before_authorize_action(nodes)
remove_unauthorized(nodes)
nodes
@@ -29,6 +31,13 @@ module Gitlab
private
+ def perform_before_authorize_action(nodes)
+ before_connection_authorization_block = @resolver&.before_connection_authorization_block
+ return unless before_connection_authorization_block.respond_to?(:call)
+
+ before_connection_authorization_block.call(nodes, @context[:current_user])
+ end
+
def remove_unauthorized(nodes)
nodes
.map! { |lazy| force(lazy) }
@@ -49,14 +58,14 @@ module Gitlab
end
def redact_connection(conn, context)
- redactor = Redactor.new(@field.type.unwrap.node_type, context)
+ redactor = Redactor.new(@field.type.unwrap.node_type, context, @field.resolver)
return unless redactor.active?
conn.redactor = redactor if conn.respond_to?(:redactor=)
end
def redact_list(list, context)
- redactor = Redactor.new(@field.type.unwrap, context)
+ redactor = Redactor.new(@field.type.unwrap, context, @field.resolver)
redactor.redact(list) if redactor.active?
end
end
diff --git a/lib/gitlab/graphql/loaders/full_path_model_loader.rb b/lib/gitlab/graphql/loaders/full_path_model_loader.rb
index 26c1ce64a83..7f9013c6e4c 100644
--- a/lib/gitlab/graphql/loaders/full_path_model_loader.rb
+++ b/lib/gitlab/graphql/loaders/full_path_model_loader.rb
@@ -5,19 +5,20 @@ module Gitlab
module Loaders
# Suitable for use to find resources that expose `where_full_path_in`,
# such as Project, Group, Namespace
+ # full path is always converted to lowercase for case-insensitive results
class FullPathModelLoader
attr_reader :model_class, :full_path
def initialize(model_class, full_path)
@model_class = model_class
- @full_path = full_path
+ @full_path = full_path.downcase
end
def find
BatchLoader::GraphQL.for(full_path).batch(key: model_class) do |full_paths, loader, args|
# `with_route` avoids an N+1 calculating full_path
args[:key].where_full_path_in(full_paths).with_route.each do |model_instance|
- loader.call(model_instance.full_path, model_instance)
+ loader.call(model_instance.full_path.downcase, model_instance)
end
end
end
diff --git a/lib/gitlab/graphql/todos_project_permission_preloader/field_extension.rb b/lib/gitlab/graphql/todos_project_permission_preloader/field_extension.rb
deleted file mode 100644
index 77f3b1ac71a..00000000000
--- a/lib/gitlab/graphql/todos_project_permission_preloader/field_extension.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Graphql
- module TodosProjectPermissionPreloader
- class FieldExtension < ::GraphQL::Schema::FieldExtension
- def after_resolve(value:, memo:, **rest)
- todos = value.to_a
-
- Preloaders::UserMaxAccessLevelInProjectsPreloader.new(
- todos.map(&:project).compact,
- current_user(rest)
- ).execute
-
- value
- end
-
- private
-
- def current_user(options)
- options.dig(:context, :current_user)
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/i18n.rb b/lib/gitlab/i18n.rb
index 5f1b9873fee..33f2916345e 100644
--- a/lib/gitlab/i18n.rb
+++ b/lib/gitlab/i18n.rb
@@ -7,6 +7,7 @@ module Gitlab
AVAILABLE_LANGUAGES = {
'bg' => 'Bulgarian - българÑки',
'cs_CZ' => 'Czech - ÄeÅ¡tina',
+ 'da_DK' => 'Danish - dansk',
'de' => 'German - Deutsch',
'en' => 'English',
'eo' => 'Esperanto - esperanto',
@@ -18,10 +19,12 @@ module Gitlab
'it' => 'Italian - italiano',
'ja' => 'Japanese - 日本語',
'ko' => 'Korean - 한국어',
+ 'nb_NO' => 'Norwegian (Bokmål) - norsk (bokmål)',
'nl_NL' => 'Dutch - Nederlands',
'pl_PL' => 'Polish - polski',
'pt_BR' => 'Portuguese (Brazil) - português (Brasil)',
- 'ru' => 'Russian - РуÑÑкий',
+ 'ro_RO' => 'Romanian - română',
+ 'ru' => 'Russian - руÑÑкий',
'tr_TR' => 'Turkish - Türkçe',
'uk' => 'Ukrainian - українÑька',
'zh_CN' => 'Chinese, Simplified - 简体中文',
@@ -39,25 +42,28 @@ module Gitlab
# https://gitlab.com/gitlab-org/gitlab/-/issues/18923
TRANSLATION_LEVELS = {
'bg' => 0,
- 'cs_CZ' => 1,
+ 'cs_CZ' => 0,
+ 'da_DK' => 25,
'de' => 16,
'en' => 100,
'eo' => 0,
- 'es' => 36,
+ 'es' => 42,
'fil_PH' => 0,
- 'fr' => 12,
+ 'fr' => 11,
'gl_ES' => 0,
'id_ID' => 0,
'it' => 2,
- 'ja' => 39,
+ 'ja' => 38,
'ko' => 12,
+ 'nb_NO' => 26,
'nl_NL' => 0,
'pl_PL' => 6,
- 'pt_BR' => 36,
+ 'pt_BR' => 45,
+ 'ro_RO' => 21,
'ru' => 28,
'tr_TR' => 16,
'uk' => 40,
- 'zh_CN' => 74,
+ 'zh_CN' => 94,
'zh_HK' => 2,
'zh_TW' => 3
}.freeze
diff --git a/lib/gitlab/import_export/attributes_permitter.rb b/lib/gitlab/import_export/attributes_permitter.rb
index 86f51add504..acd03d9ec20 100644
--- a/lib/gitlab/import_export/attributes_permitter.rb
+++ b/lib/gitlab/import_export/attributes_permitter.rb
@@ -42,6 +42,10 @@ module Gitlab
class AttributesPermitter
attr_reader :permitted_attributes
+ # We want to use AttributesCleaner for these relations instead, in the future this should be removed to make sure
+ # we are using AttributesPermitter for every imported relation.
+ DISABLED_RELATION_NAMES = %i[user author ci_cd_settings issuable_sla push_rule].freeze
+
def initialize(config: ImportExport::Config.new.to_h)
@config = config
@attributes_finder = Gitlab::ImportExport::AttributesFinder.new(config: @config)
@@ -50,16 +54,20 @@ module Gitlab
build_permitted_attributes
end
- def permit(relation_name, relation_hash)
- permitted_attributes = permitted_attributes_for(relation_name)
+ def permit(relation_sym, relation_hash)
+ permitted_attributes = permitted_attributes_for(relation_sym)
relation_hash.select do |key, _|
- permitted_attributes.include?(key)
+ permitted_attributes.include?(key.to_sym)
end
end
- def permitted_attributes_for(relation_name)
- @permitted_attributes[relation_name] || []
+ def permitted_attributes_for(relation_sym)
+ @permitted_attributes[relation_sym] || []
+ end
+
+ def permitted_attributes_defined?(relation_sym)
+ !DISABLED_RELATION_NAMES.include?(relation_sym) && @attributes_finder.included_attributes.key?(relation_sym)
end
private
@@ -88,11 +96,15 @@ module Gitlab
end
def build_attributes
- @attributes_finder.included_attributes.each(&method(:add_permitted_attributes))
+ @attributes_finder.included_attributes.each do |model_name, attributes|
+ add_permitted_attributes(model_name, attributes)
+ end
end
def build_methods
- @attributes_finder.methods.each(&method(:add_permitted_attributes))
+ @attributes_finder.methods.each do |model_name, attributes|
+ add_permitted_attributes(model_name, attributes)
+ end
end
def add_permitted_attributes(model_name, attributes)
diff --git a/lib/gitlab/import_export/base/relation_factory.rb b/lib/gitlab/import_export/base/relation_factory.rb
index 30cd5ccfbcb..a84efd1d240 100644
--- a/lib/gitlab/import_export/base/relation_factory.rb
+++ b/lib/gitlab/import_export/base/relation_factory.rb
@@ -29,7 +29,7 @@ module Gitlab
owner_id
].freeze
- TOKEN_RESET_MODELS = %i[Project Namespace Group Ci::Trigger Ci::Build Ci::Runner ProjectHook].freeze
+ TOKEN_RESET_MODELS = %i[Project Namespace Group Ci::Trigger Ci::Build Ci::Runner ProjectHook ErrorTracking::ProjectErrorTrackingSetting].freeze
def self.create(*args, **kwargs)
new(*args, **kwargs).create
@@ -45,6 +45,7 @@ module Gitlab
end
def initialize(relation_sym:, relation_index:, relation_hash:, members_mapper:, object_builder:, user:, importable:, excluded_keys: [])
+ @relation_sym = relation_sym
@relation_name = self.class.overrides[relation_sym]&.to_sym || relation_sym
@relation_index = relation_index
@relation_hash = relation_hash.except('noteable_id')
@@ -181,8 +182,17 @@ module Gitlab
end
def parsed_relation_hash
- @parsed_relation_hash ||= Gitlab::ImportExport::AttributeCleaner.clean(relation_hash: @relation_hash,
- relation_class: relation_class)
+ strong_memoize(:parsed_relation_hash) do
+ if Feature.enabled?(:permitted_attributes_for_import_export, default_enabled: :yaml) && attributes_permitter.permitted_attributes_defined?(@relation_sym)
+ attributes_permitter.permit(@relation_sym, @relation_hash)
+ else
+ Gitlab::ImportExport::AttributeCleaner.clean(relation_hash: @relation_hash, relation_class: relation_class)
+ end
+ end
+ end
+
+ def attributes_permitter
+ @attributes_permitter ||= Gitlab::ImportExport::AttributesPermitter.new
end
def existing_or_new_object
diff --git a/lib/gitlab/import_export/project/import_export.yml b/lib/gitlab/import_export/project/import_export.yml
index 3ebdcc950c3..fe0974d27a6 100644
--- a/lib/gitlab/import_export/project/import_export.yml
+++ b/lib/gitlab/import_export/project/import_export.yml
@@ -107,6 +107,7 @@ tree:
- lists:
- label:
- :priorities
+ - :service_desk_setting
group_members:
- :user
@@ -120,6 +121,41 @@ included_attributes:
- :name
ci_cd_settings:
- :group_runners_enabled
+ metrics_setting:
+ - :dashboard_timezone
+ - :external_dashboard_url
+ - :project_id
+ project_badges:
+ - :created_at
+ - :group_id
+ - :image_url
+ - :link_url
+ - :name
+ - :project_id
+ - :type
+ - :updated_at
+ pipeline_schedules:
+ - :active
+ - :created_at
+ - :cron
+ - :cron_timezone
+ - :description
+ - :next_run_at
+ - :owner_id
+ - :project_id
+ - :ref
+ - :updated_at
+ error_tracking_setting:
+ - :api_url
+ - :organization_name
+ - :project_id
+ - :project_name
+ auto_devops:
+ - :created_at
+ - :deploy_strategy
+ - :enabled
+ - :project_id
+ - :updated_at
# Do not include the following attributes for the models specified.
excluded_attributes:
@@ -127,6 +163,7 @@ excluded_attributes:
- :name
- :path
- :namespace_id
+ - :project_namespace_id
- :creator_id
- :pool_repository_id
- :import_url
@@ -297,6 +334,7 @@ excluded_attributes:
- :integrated
service_desk_setting:
- :outgoing_name
+ - :file_template_project_id
priorities:
- :label_id
events:
@@ -331,6 +369,9 @@ excluded_attributes:
project_members:
- :source_id
- :invite_email_success
+ - :state
+ group_members:
+ - :state
metrics:
- :merge_request_id
- :pipeline_id
@@ -359,6 +400,7 @@ excluded_attributes:
boards:
- :milestone_id
- :iteration_id
+ - :iteration_cadence_id
lists:
- :board_id
- :label_id
@@ -454,7 +496,6 @@ ee:
- :unprotect_access_levels
- protected_environments:
- :deploy_access_levels
- - :service_desk_setting
- :security_setting
- :push_rule
diff --git a/lib/gitlab/import_export/relation_tree_restorer.rb b/lib/gitlab/import_export/relation_tree_restorer.rb
index d5f924ae2bd..8d93098a80a 100644
--- a/lib/gitlab/import_export/relation_tree_restorer.rb
+++ b/lib/gitlab/import_export/relation_tree_restorer.rb
@@ -61,7 +61,9 @@ module Gitlab
# the configuration yaml file too.
# Finally, it updates each attribute in the newly imported project/group.
def create_relations!
- relations.each(&method(:process_relation!))
+ relations.each do |relation_key, relation_definition|
+ process_relation!(relation_key, relation_definition)
+ end
end
def process_relation!(relation_key, relation_definition)
diff --git a/lib/gitlab/instrumentation/redis_interceptor.rb b/lib/gitlab/instrumentation/redis_interceptor.rb
index 0f21a16793d..ba25e54ac9f 100644
--- a/lib/gitlab/instrumentation/redis_interceptor.rb
+++ b/lib/gitlab/instrumentation/redis_interceptor.rb
@@ -41,7 +41,10 @@ module Gitlab
instrumentation_class.add_call_details(duration, args)
end
- if duration > DURATION_ERROR_THRESHOLD && Feature.enabled?(:report_on_long_redis_durations, default_enabled: :yaml)
+ if duration > DURATION_ERROR_THRESHOLD &&
+ instrumentation_class == ::Gitlab::Instrumentation::Redis::SharedState &&
+ Feature.enabled?(:report_on_long_redis_durations, default_enabled: :yaml)
+
Gitlab::ErrorTracking.track_exception(MysteryRedisDurationError.new(caller),
command: command_from_args(args),
duration: duration,
diff --git a/lib/gitlab/integrations/sti_type.rb b/lib/gitlab/integrations/sti_type.rb
index 0fa9f435b5c..91797a7b99b 100644
--- a/lib/gitlab/integrations/sti_type.rb
+++ b/lib/gitlab/integrations/sti_type.rb
@@ -7,7 +7,7 @@ module Gitlab
Asana Assembla Bamboo Bugzilla Buildkite Campfire Confluence CustomIssueTracker Datadog
Discord DroneCi EmailsOnPush Ewm ExternalWiki Flowdock HangoutsChat Irker Jenkins Jira Mattermost
MattermostSlashCommands MicrosoftTeams MockCi MockMonitoring Packagist PipelinesEmail Pivotaltracker
- Prometheus Pushover Redmine Slack SlackSlashCommands Teamcity UnifyCircuit WebexTeams Youtrack
+ Prometheus Pushover Redmine Slack SlackSlashCommands Teamcity UnifyCircuit WebexTeams Youtrack Zentao
)).freeze
def self.namespaced_integrations
diff --git a/lib/gitlab/issuables_count_for_state.rb b/lib/gitlab/issuables_count_for_state.rb
index 6b33b60e850..f11dd520d2d 100644
--- a/lib/gitlab/issuables_count_for_state.rb
+++ b/lib/gitlab/issuables_count_for_state.rb
@@ -5,11 +5,14 @@ module Gitlab
class IssuablesCountForState
# The name of the Gitlab::SafeRequestStore cache key.
CACHE_KEY = :issuables_count_for_state
+ # The expiration time for the Rails cache.
+ CACHE_EXPIRES_IN = 1.hour
+ THRESHOLD = 1000
# The state values that can be safely casted to a Symbol.
STATES = %w[opened closed merged all].freeze
- attr_reader :project
+ attr_reader :project, :finder
def self.declarative_policy_class
'IssuablePolicy'
@@ -18,11 +21,12 @@ module Gitlab
# finder - The finder class to use for retrieving the issuables.
# fast_fail - restrict counting to a shorter period, degrading gracefully on
# failure
- def initialize(finder, project = nil, fast_fail: false)
+ def initialize(finder, project = nil, fast_fail: false, store_in_redis_cache: false)
@finder = finder
@project = project
@fast_fail = fast_fail
@cache = Gitlab::SafeRequestStore[CACHE_KEY] ||= initialize_cache
+ @store_in_redis_cache = store_in_redis_cache
end
def for_state_or_opened(state = nil)
@@ -52,7 +56,16 @@ module Gitlab
private
def cache_for_finder
- @cache[@finder]
+ cached_counts = Rails.cache.read(redis_cache_key, cache_options) if cache_issues_count?
+
+ cached_counts ||= @cache[finder]
+ return cached_counts if cached_counts.empty?
+
+ if cache_issues_count? && cached_counts.values.all? { |count| count >= THRESHOLD }
+ Rails.cache.write(redis_cache_key, cached_counts, cache_options)
+ end
+
+ cached_counts
end
def cast_state_to_symbol?(state)
@@ -108,5 +121,33 @@ module Gitlab
"Count of failed calls to IssuableFinder#count_by_state with fast failure"
).increment
end
+
+ def cache_issues_count?
+ @store_in_redis_cache &&
+ finder.instance_of?(IssuesFinder) &&
+ parent_group.present? &&
+ !params_include_filters?
+ end
+
+ def parent_group
+ finder.params.group
+ end
+
+ def redis_cache_key
+ ['group', parent_group&.id, 'issues']
+ end
+
+ def cache_options
+ { expires_in: CACHE_EXPIRES_IN }
+ end
+
+ def params_include_filters?
+ non_filtering_params = %i[
+ scope state sort group_id include_subgroups
+ attempt_group_search_optimizations non_archived issue_types
+ ]
+
+ finder.params.except(*non_filtering_params).values.any?
+ end
end
end
diff --git a/lib/gitlab/issues/rebalancing/state.rb b/lib/gitlab/issues/rebalancing/state.rb
new file mode 100644
index 00000000000..dce165a3489
--- /dev/null
+++ b/lib/gitlab/issues/rebalancing/state.rb
@@ -0,0 +1,154 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Issues
+ module Rebalancing
+ class State
+ REDIS_EXPIRY_TIME = 10.days
+ MAX_NUMBER_OF_CONCURRENT_REBALANCES = 5
+ NAMESPACE = 1
+ PROJECT = 2
+
+ def initialize(root_namespace, projects)
+ @root_namespace = root_namespace
+ @projects = projects
+ @rebalanced_container_type = @root_namespace.is_a?(Group) ? NAMESPACE : PROJECT
+ @rebalanced_container_id = @rebalanced_container_type == NAMESPACE ? @root_namespace.id : projects.take.id # rubocop:disable CodeReuse/ActiveRecord
+ end
+
+ def track_new_running_rebalance
+ with_redis do |redis|
+ redis.multi do |multi|
+ # we trigger re-balance for namespaces(groups) or specific user project
+ value = "#{rebalanced_container_type}/#{rebalanced_container_id}"
+ multi.sadd(concurrent_running_rebalances_key, value)
+ multi.expire(concurrent_running_rebalances_key, REDIS_EXPIRY_TIME)
+ end
+ end
+ end
+
+ def concurrent_running_rebalances_count
+ with_redis { |redis| redis.scard(concurrent_running_rebalances_key).to_i }
+ end
+
+ def rebalance_in_progress?
+ all_rebalanced_containers = with_redis { |redis| redis.smembers(concurrent_running_rebalances_key) }
+
+ is_running = case rebalanced_container_type
+ when NAMESPACE
+ namespace_ids = all_rebalanced_containers.map {|string| string.split("#{NAMESPACE}/").second.to_i }.compact
+ namespace_ids.include?(root_namespace.id)
+ when PROJECT
+ project_ids = all_rebalanced_containers.map {|string| string.split("#{PROJECT}/").second.to_i }.compact
+ project_ids.include?(projects.take.id) # rubocop:disable CodeReuse/ActiveRecord
+ else
+ false
+ end
+
+ refresh_keys_expiration if is_running
+
+ is_running
+ end
+
+ def can_start_rebalance?
+ rebalance_in_progress? || too_many_rebalances_running?
+ end
+
+ def cache_issue_ids(issue_ids)
+ with_redis do |redis|
+ values = issue_ids.map { |issue| [issue.relative_position, issue.id] }
+
+ redis.multi do |multi|
+ multi.zadd(issue_ids_key, values) unless values.blank?
+ multi.expire(issue_ids_key, REDIS_EXPIRY_TIME)
+ end
+ end
+ end
+
+ def get_cached_issue_ids(index, limit)
+ with_redis do |redis|
+ redis.zrange(issue_ids_key, index, index + limit - 1)
+ end
+ end
+
+ def cache_current_index(index)
+ with_redis { |redis| redis.set(current_index_key, index, ex: REDIS_EXPIRY_TIME) }
+ end
+
+ def get_current_index
+ with_redis { |redis| redis.get(current_index_key).to_i }
+ end
+
+ def cache_current_project_id(project_id)
+ with_redis { |redis| redis.set(current_project_key, project_id, ex: REDIS_EXPIRY_TIME) }
+ end
+
+ def get_current_project_id
+ with_redis { |redis| redis.get(current_project_key) }
+ end
+
+ def issue_count
+ @issue_count ||= with_redis { |redis| redis.zcard(issue_ids_key)}
+ end
+
+ def remove_current_project_id_cache
+ with_redis { |redis| redis.del(current_project_key)}
+ end
+
+ def refresh_keys_expiration
+ with_redis do |redis|
+ redis.multi do |multi|
+ multi.expire(issue_ids_key, REDIS_EXPIRY_TIME)
+ multi.expire(current_index_key, REDIS_EXPIRY_TIME)
+ multi.expire(current_project_key, REDIS_EXPIRY_TIME)
+ multi.expire(concurrent_running_rebalances_key, REDIS_EXPIRY_TIME)
+ end
+ end
+ end
+
+ def cleanup_cache
+ with_redis do |redis|
+ redis.multi do |multi|
+ multi.del(issue_ids_key)
+ multi.del(current_index_key)
+ multi.del(current_project_key)
+ multi.srem(concurrent_running_rebalances_key, "#{rebalanced_container_type}/#{rebalanced_container_id}")
+ end
+ end
+ end
+
+ private
+
+ attr_accessor :root_namespace, :projects, :rebalanced_container_type, :rebalanced_container_id
+
+ def too_many_rebalances_running?
+ concurrent_running_rebalances_count <= MAX_NUMBER_OF_CONCURRENT_REBALANCES
+ end
+
+ def redis_key_prefix
+ "gitlab:issues-position-rebalances"
+ end
+
+ def issue_ids_key
+ "#{redis_key_prefix}:#{root_namespace.id}"
+ end
+
+ def current_index_key
+ "#{issue_ids_key}:current_index"
+ end
+
+ def current_project_key
+ "#{issue_ids_key}:current_project_id"
+ end
+
+ def concurrent_running_rebalances_key
+ "#{redis_key_prefix}:running_rebalances"
+ end
+
+ def with_redis(&blk)
+ Gitlab::Redis::SharedState.with(&blk) # rubocop: disable CodeReuse/ActiveRecord
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/kas/client.rb b/lib/gitlab/kas/client.rb
index 842ee98e4da..753a185344e 100644
--- a/lib/gitlab/kas/client.rb
+++ b/lib/gitlab/kas/client.rb
@@ -7,6 +7,7 @@ module Gitlab
JWT_AUDIENCE = 'gitlab-kas'
STUB_CLASSES = {
+ agent_tracker: Gitlab::Agent::AgentTracker::Rpc::AgentTracker::Stub,
configuration_project: Gitlab::Agent::ConfigurationProject::Rpc::ConfigurationProject::Stub
}.freeze
@@ -17,6 +18,15 @@ module Gitlab
raise ConfigurationError, 'KAS internal URL is not configured' unless Gitlab::Kas.internal_url.present?
end
+ def get_connected_agents(project:)
+ request = Gitlab::Agent::AgentTracker::Rpc::GetConnectedAgentsRequest.new(project_id: project.id)
+
+ stub_for(:agent_tracker)
+ .get_connected_agents(request, metadata: metadata)
+ .agents
+ .to_a
+ end
+
def list_agent_config_files(project:)
request = Gitlab::Agent::ConfigurationProject::Rpc::ListAgentConfigFilesRequest.new(
repository: repository(project),
@@ -49,7 +59,7 @@ module Gitlab
end
def kas_endpoint_url
- Gitlab::Kas.internal_url.sub(%r{^grpc://|^grpcs://}, '')
+ Gitlab::Kas.internal_url.sub(%r{^grpcs?://}, '')
end
def credentials
diff --git a/lib/gitlab/kubernetes/cilium_network_policy.rb b/lib/gitlab/kubernetes/cilium_network_policy.rb
index e333d3818b9..8a31e068c30 100644
--- a/lib/gitlab/kubernetes/cilium_network_policy.rb
+++ b/lib/gitlab/kubernetes/cilium_network_policy.rb
@@ -9,6 +9,36 @@ module Gitlab
API_VERSION = "cilium.io/v2"
KIND = 'CiliumNetworkPolicy'
+ PREDEFINED_POLICIES = {
+ 'allow-inbound-http' => <<~YAML.rstrip,
+ apiVersion: cilium.io/v2
+ kind: CiliumNetworkPolicy
+ metadata:
+ name: allow-inbound-http
+ spec:
+ endpointSelector:
+ matchLabels:
+ network-policy.gitlab.com/disabled_by: gitlab
+ ingress:
+ - toPorts:
+ - ports:
+ - port: '80'
+ - port: '443'
+ YAML
+ 'drop-outbound' => <<~YAML.rstrip
+ apiVersion: cilium.io/v2
+ kind: CiliumNetworkPolicy
+ metadata:
+ name: drop-outbound
+ spec:
+ endpointSelector:
+ matchLabels:
+ network-policy.gitlab.com/disabled_by: gitlab
+ egress:
+ - {}
+ YAML
+ }.freeze
+
# We are modeling existing kubernetes resource and don't have
# control over amount of parameters.
# rubocop:disable Metrics/ParameterLists
diff --git a/lib/gitlab/marginalia/comment.rb b/lib/gitlab/marginalia/comment.rb
index ee15d3b1812..f635f41ec39 100644
--- a/lib/gitlab/marginalia/comment.rb
+++ b/lib/gitlab/marginalia/comment.rb
@@ -41,6 +41,10 @@ module Gitlab
def endpoint_id
Labkit::Context.current&.get_attribute(:caller_id)
end
+
+ def db_config_name
+ ::Gitlab::Database.db_config_name(marginalia_adapter)
+ end
end
end
end
diff --git a/lib/gitlab/metrics/instrumentation.rb b/lib/gitlab/metrics/instrumentation.rb
index 66361529546..ad45a037161 100644
--- a/lib/gitlab/metrics/instrumentation.rb
+++ b/lib/gitlab/metrics/instrumentation.rb
@@ -153,6 +153,10 @@ module Gitlab
method_visibility = method_visibility_for(target, name)
+ # We silence warnings to avoid such warnings:
+ # `Skipping set of ruby2_keywords flag for <...>
+ # (method accepts keywords or method does not accept argument splat)`
+ # as we apply ruby2_keywords 'blindly' for every instrumented method.
proxy_module.class_eval <<-EOF, __FILE__, __LINE__ + 1
def #{name}(#{args_signature})
if trans = Gitlab::Metrics::Instrumentation.transaction
@@ -162,6 +166,7 @@ module Gitlab
super
end
end
+ silence_warnings { ruby2_keywords(:#{name}) if respond_to?(:ruby2_keywords, true) }
#{method_visibility} :#{name}
EOF
diff --git a/lib/gitlab/metrics/subscribers/rack_attack.rb b/lib/gitlab/metrics/subscribers/rack_attack.rb
index 1c7767f5ca9..ebd0d1634e7 100644
--- a/lib/gitlab/metrics/subscribers/rack_attack.rb
+++ b/lib/gitlab/metrics/subscribers/rack_attack.rb
@@ -20,7 +20,9 @@ module Gitlab
:throttle_authenticated_web,
:throttle_authenticated_protected_paths_api,
:throttle_authenticated_protected_paths_web,
- :throttle_authenticated_packages_api
+ :throttle_authenticated_packages_api,
+ :throttle_authenticated_git_lfs,
+ :throttle_authenticated_files_api
].freeze
PAYLOAD_KEYS = [
diff --git a/lib/gitlab/middleware/sidekiq_web_static.rb b/lib/gitlab/middleware/sidekiq_web_static.rb
new file mode 100644
index 00000000000..61b5fb9e0c6
--- /dev/null
+++ b/lib/gitlab/middleware/sidekiq_web_static.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+# This module removes the X-Sendfile-Type header for /admin/sidekiq
+# assets since Workhorse isn't always guaranteed to have the assets
+# present on disk, such as when using Cloud Native GitLab
+# containers. These assets are also small and served infrequently so it
+# should be fine to do this.
+module Gitlab
+ module Middleware
+ class SidekiqWebStatic
+ SIDEKIQ_REGEX = %r{\A/admin/sidekiq/}.freeze
+
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ env.delete('HTTP_X_SENDFILE_TYPE') if env['PATH_INFO'] =~ SIDEKIQ_REGEX
+
+ @app.call(env)
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/object_hierarchy.rb b/lib/gitlab/object_hierarchy.rb
index 2e54e8bfc1a..693f1470d9d 100644
--- a/lib/gitlab/object_hierarchy.rb
+++ b/lib/gitlab/object_hierarchy.rb
@@ -65,8 +65,15 @@ module Gitlab
# Note: By default the order is breadth-first
# rubocop: disable CodeReuse/ActiveRecord
def base_and_ancestors(upto: nil, hierarchy_order: nil)
- recursive_query = base_and_ancestors_cte(upto, hierarchy_order).apply_to(unscoped_model.all)
- recursive_query = recursive_query.order(depth: hierarchy_order) if hierarchy_order
+ cte = base_and_ancestors_cte(upto, hierarchy_order)
+
+ recursive_query = if hierarchy_order
+ # othewise depth won't be available for outer query
+ cte.apply_to(unscoped_model.all.select(objects_table[Arel.star])).order(depth: hierarchy_order)
+ else
+ cte.apply_to(unscoped_model.all)
+ end
+
read_only(recursive_query)
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -78,7 +85,10 @@ module Gitlab
# and incremented as we go down the descendant tree
# rubocop: disable CodeReuse/ActiveRecord
def base_and_descendants(with_depth: false)
- read_only(base_and_descendants_cte(with_depth: with_depth).apply_to(unscoped_model.all))
+ outer_select_relation = unscoped_model.all
+ outer_select_relation = outer_select_relation.select(objects_table[Arel.star]) if with_depth # Otherwise Active Record will not select `depth` as it's not a table column
+
+ read_only(base_and_descendants_cte(with_depth: with_depth).apply_to(outer_select_relation))
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -145,7 +155,7 @@ module Gitlab
cte = SQL::RecursiveCTE.new(:base_and_ancestors)
base_query = ancestors_base.except(:order)
- base_query = base_query.select("1 as #{DEPTH_COLUMN}", "ARRAY[#{objects_table.name}.id] AS tree_path", "false AS tree_cycle", objects_table[Arel.star]) if hierarchy_order
+ base_query = base_query.select("1 as #{DEPTH_COLUMN}", "ARRAY[#{objects_table.name}.id] AS tree_path", "false AS tree_cycle", base_query.default_select_columns) if hierarchy_order
cte << base_query
@@ -162,7 +172,7 @@ module Gitlab
cte.table[DEPTH_COLUMN] + 1,
"tree_path || #{quoted_objects_table_name}.id",
"#{quoted_objects_table_name}.id = ANY(tree_path)",
- objects_table[Arel.star]
+ parent_query.default_select_columns
).where(cte.table[:tree_cycle].eq(false))
end
@@ -178,7 +188,7 @@ module Gitlab
cte = SQL::RecursiveCTE.new(:base_and_descendants)
base_query = descendants_base.except(:order)
- base_query = base_query.select("1 AS #{DEPTH_COLUMN}", "ARRAY[#{objects_table.name}.id] AS tree_path", "false AS tree_cycle", objects_table[Arel.star]) if with_depth
+ base_query = base_query.select("1 AS #{DEPTH_COLUMN}", "ARRAY[#{objects_table.name}.id] AS tree_path", "false AS tree_cycle", base_query.default_select_columns) if with_depth
cte << base_query
@@ -195,7 +205,7 @@ module Gitlab
cte.table[DEPTH_COLUMN] + 1,
"tree_path || #{quoted_objects_table_name}.id",
"#{quoted_objects_table_name}.id = ANY(tree_path)",
- objects_table[Arel.star]
+ descendants_query.default_select_columns
).where(cte.table[:tree_cycle].eq(false))
end
diff --git a/lib/gitlab/pagination/cursor_based_keyset.rb b/lib/gitlab/pagination/cursor_based_keyset.rb
new file mode 100644
index 00000000000..f19cdf06d9a
--- /dev/null
+++ b/lib/gitlab/pagination/cursor_based_keyset.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Pagination
+ module CursorBasedKeyset
+ SUPPORTED_ORDERING = {
+ Group => { name: :asc }
+ }.freeze
+
+ def self.available_for_type?(relation)
+ SUPPORTED_ORDERING.key?(relation.klass)
+ end
+
+ def self.available?(cursor_based_request_context, relation)
+ available_for_type?(relation) &&
+ order_satisfied?(relation, cursor_based_request_context)
+ end
+
+ def self.order_satisfied?(relation, cursor_based_request_context)
+ order_by_from_request = cursor_based_request_context.order_by
+
+ SUPPORTED_ORDERING[relation.klass] == order_by_from_request
+ end
+ private_class_method :order_satisfied?
+ end
+ end
+end
diff --git a/lib/gitlab/pagination/gitaly_keyset_pager.rb b/lib/gitlab/pagination/gitaly_keyset_pager.rb
index b05891066ac..a16bf7a379c 100644
--- a/lib/gitlab/pagination/gitaly_keyset_pager.rb
+++ b/lib/gitlab/pagination/gitaly_keyset_pager.rb
@@ -14,23 +14,39 @@ module Gitlab
# It is expected that the given finder will respond to `execute` method with `gitaly_pagination: true` option
# and supports pagination via gitaly.
def paginate(finder)
- return paginate_via_gitaly(finder) if keyset_pagination_enabled?
- return paginate_first_page_via_gitaly(finder) if paginate_first_page?
+ return paginate_via_gitaly(finder) if keyset_pagination_enabled?(finder)
+ return paginate_first_page_via_gitaly(finder) if paginate_first_page?(finder)
- branches = ::Kaminari.paginate_array(finder.execute)
+ records = ::Kaminari.paginate_array(finder.execute)
Gitlab::Pagination::OffsetPagination
.new(request_context)
- .paginate(branches)
+ .paginate(records)
end
private
- def keyset_pagination_enabled?
- Feature.enabled?(:branch_list_keyset_pagination, project, default_enabled: :yaml) && params[:pagination] == 'keyset'
+ def keyset_pagination_enabled?(finder)
+ return false unless params[:pagination] == "keyset"
+
+ if finder.is_a?(BranchesFinder)
+ Feature.enabled?(:branch_list_keyset_pagination, project, default_enabled: :yaml)
+ elsif finder.is_a?(::Repositories::TreeFinder)
+ Feature.enabled?(:repository_tree_gitaly_pagination, project, default_enabled: :yaml)
+ else
+ false
+ end
end
- def paginate_first_page?
- Feature.enabled?(:branch_list_keyset_pagination, project, default_enabled: :yaml) && (params[:page].blank? || params[:page].to_i == 1)
+ def paginate_first_page?(finder)
+ return false unless params[:page].blank? || params[:page].to_i == 1
+
+ if finder.is_a?(BranchesFinder)
+ Feature.enabled?(:branch_list_keyset_pagination, project, default_enabled: :yaml)
+ elsif finder.is_a?(::Repositories::TreeFinder)
+ Feature.enabled?(:repository_tree_gitaly_pagination, project, default_enabled: :yaml)
+ else
+ false
+ end
end
def paginate_via_gitaly(finder)
@@ -43,7 +59,7 @@ module Gitlab
# Headers are added to immitate offset pagination, while it is the default option
def paginate_first_page_via_gitaly(finder)
finder.execute(gitaly_pagination: true).tap do |records|
- total = project.repository.branch_count
+ total = finder.total
per_page = params[:per_page].presence || Kaminari.config.default_per_page
Gitlab::Pagination::OffsetHeaderBuilder.new(
diff --git a/lib/gitlab/pagination/keyset/column_order_definition.rb b/lib/gitlab/pagination/keyset/column_order_definition.rb
index 0755af9587b..2b968c4253f 100644
--- a/lib/gitlab/pagination/keyset/column_order_definition.rb
+++ b/lib/gitlab/pagination/keyset/column_order_definition.rb
@@ -173,6 +173,18 @@ module Gitlab
distinct
end
+ def order_direction_as_sql_string
+ sql_string = ascending_order? ? +'ASC' : +'DESC'
+
+ if nulls_first?
+ sql_string << ' NULLS FIRST'
+ elsif nulls_last?
+ sql_string << ' NULLS LAST'
+ end
+
+ sql_string
+ end
+
private
attr_reader :reversed_order_expression, :nullable, :distinct
diff --git a/lib/gitlab/pagination/keyset/cursor_based_request_context.rb b/lib/gitlab/pagination/keyset/cursor_based_request_context.rb
new file mode 100644
index 00000000000..18390f5b59d
--- /dev/null
+++ b/lib/gitlab/pagination/keyset/cursor_based_request_context.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Pagination
+ module Keyset
+ class CursorBasedRequestContext
+ DEFAULT_SORT_DIRECTION = :desc
+ attr_reader :request_context
+ delegate :params, to: :request_context
+
+ def initialize(request_context)
+ @request_context = request_context
+ end
+
+ def per_page
+ params[:per_page]
+ end
+
+ def cursor
+ params[:cursor]
+ end
+
+ def apply_headers(cursor_for_next_page)
+ Gitlab::Pagination::Keyset::HeaderBuilder
+ .new(request_context)
+ .add_next_page_header({ cursor: cursor_for_next_page })
+ end
+
+ def order_by
+ { params[:order_by].to_sym => params[:sort]&.to_sym || DEFAULT_SORT_DIRECTION }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/pagination/keyset/cursor_pager.rb b/lib/gitlab/pagination/keyset/cursor_pager.rb
new file mode 100644
index 00000000000..0b49aa87a02
--- /dev/null
+++ b/lib/gitlab/pagination/keyset/cursor_pager.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Pagination
+ module Keyset
+ class CursorPager < Gitlab::Pagination::Base
+ attr_reader :cursor_based_request_context, :paginator
+
+ def initialize(cursor_based_request_context)
+ @cursor_based_request_context = cursor_based_request_context
+ end
+
+ def paginate(relation)
+ @paginator ||= relation.keyset_paginate(
+ per_page: cursor_based_request_context.per_page,
+ cursor: cursor_based_request_context.cursor
+ )
+
+ paginator.records
+ end
+
+ def finalize(_records = [])
+ # can be called only after executing `paginate(relation)`
+ apply_headers
+ end
+
+ private
+
+ def apply_headers
+ return unless paginator.has_next_page?
+
+ cursor_based_request_context
+ .apply_headers(paginator.cursor_for_next_page)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/pagination/keyset/in_operator_optimization/array_scope_columns.rb b/lib/gitlab/pagination/keyset/in_operator_optimization/array_scope_columns.rb
new file mode 100644
index 00000000000..95afd5a8595
--- /dev/null
+++ b/lib/gitlab/pagination/keyset/in_operator_optimization/array_scope_columns.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Pagination
+ module Keyset
+ module InOperatorOptimization
+ class ArrayScopeColumns
+ ARRAY_SCOPE_CTE_NAME = 'array_cte'
+
+ def initialize(columns)
+ validate_columns!(columns)
+
+ array_scope_table = Arel::Table.new(ARRAY_SCOPE_CTE_NAME)
+ @columns = columns.map do |column|
+ ColumnData.new(column, "array_scope_#{column}", array_scope_table)
+ end
+ end
+
+ def array_scope_cte_name
+ ARRAY_SCOPE_CTE_NAME
+ end
+
+ def array_aggregated_columns
+ columns.map(&:array_aggregated_column)
+ end
+
+ def array_aggregated_column_names
+ columns.map(&:array_aggregated_column_name)
+ end
+
+ def arel_columns
+ columns.map(&:arel_column)
+ end
+
+ def array_lookup_expressions_by_position(table_name)
+ columns.map do |column|
+ Arel.sql("#{table_name}.#{column.array_aggregated_column_name}[position]")
+ end
+ end
+
+ private
+
+ attr_reader :columns
+
+ def validate_columns!(columns)
+ if columns.blank?
+ msg = <<~MSG
+ No array columns were given.
+ Make sure you explicitly select the columns in the array_scope parameter.
+ Example: Project.select(:id)
+ MSG
+ raise StandardError, msg
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/pagination/keyset/in_operator_optimization/column_data.rb b/lib/gitlab/pagination/keyset/in_operator_optimization/column_data.rb
new file mode 100644
index 00000000000..3f620f74eca
--- /dev/null
+++ b/lib/gitlab/pagination/keyset/in_operator_optimization/column_data.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Pagination
+ module Keyset
+ module InOperatorOptimization
+ class ColumnData
+ attr_reader :original_column_name, :as, :arel_table
+
+ def initialize(original_column_name, as, arel_table)
+ @original_column_name = original_column_name.to_s
+ @as = as.to_s
+ @arel_table = arel_table
+ end
+
+ def projection
+ arel_column.as(as)
+ end
+
+ def arel_column
+ arel_table[original_column_name]
+ end
+
+ def arel_column_as
+ arel_table[as]
+ end
+
+ def array_aggregated_column_name
+ "#{arel_table.name}_#{original_column_name}_array"
+ end
+
+ def array_aggregated_column
+ Arel::Nodes::NamedFunction.new('ARRAY_AGG', [arel_column]).as(array_aggregated_column_name)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/pagination/keyset/in_operator_optimization/order_by_columns.rb b/lib/gitlab/pagination/keyset/in_operator_optimization/order_by_columns.rb
new file mode 100644
index 00000000000..d8c69a74e6b
--- /dev/null
+++ b/lib/gitlab/pagination/keyset/in_operator_optimization/order_by_columns.rb
@@ -0,0 +1,76 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Pagination
+ module Keyset
+ module InOperatorOptimization
+ class OrderByColumns
+ include Enumerable
+
+ # This class exposes collection methods for the order by columns
+ #
+ # Example: by modelling the `issues.created_at ASC, issues.id ASC` ORDER BY
+ # SQL clause, this class will receive two ColumnOrderDefinition objects
+ def initialize(columns, arel_table)
+ @columns = columns.map do |column|
+ ColumnData.new(column.attribute_name, "order_by_columns_#{column.attribute_name}", arel_table)
+ end
+ end
+
+ def arel_columns
+ columns.map(&:arel_column)
+ end
+
+ def array_aggregated_columns
+ columns.map(&:array_aggregated_column)
+ end
+
+ def array_aggregated_column_names
+ columns.map(&:array_aggregated_column_name)
+ end
+
+ def original_column_names
+ columns.map(&:original_column_name)
+ end
+
+ def original_column_names_as_arel_string
+ columns.map { |c| Arel.sql(c.original_column_name) }
+ end
+
+ def original_column_names_as_tmp_tamble
+ temp_table = Arel::Table.new('record')
+ original_column_names.map { |c| temp_table[c] }
+ end
+
+ def cursor_values(table_name)
+ columns.each_with_object({}) do |column, hash|
+ hash[column.original_column_name] = Arel.sql("#{table_name}.#{column.array_aggregated_column_name}[position]")
+ end
+ end
+
+ def array_lookup_expressions_by_position(table_name)
+ columns.map do |column|
+ Arel.sql("#{table_name}.#{column.array_aggregated_column_name}[position]")
+ end
+ end
+
+ def replace_value_in_array_by_position_expressions
+ columns.map do |column|
+ name = "#{QueryBuilder::RECURSIVE_CTE_NAME}.#{column.array_aggregated_column_name}"
+ new_value = "next_cursor_values.#{column.original_column_name}"
+ "#{name}[:position_query.position-1]||#{new_value}||#{name}[position_query.position+1:]"
+ end
+ end
+
+ def each(&block)
+ columns.each(&block)
+ end
+
+ private
+
+ attr_reader :columns
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder.rb b/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder.rb
new file mode 100644
index 00000000000..39d6e016ac7
--- /dev/null
+++ b/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder.rb
@@ -0,0 +1,290 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Pagination
+ module Keyset
+ module InOperatorOptimization
+ # rubocop: disable CodeReuse/ActiveRecord
+ class QueryBuilder
+ UnsupportedScopeOrder = Class.new(StandardError)
+
+ RECURSIVE_CTE_NAME = 'recursive_keyset_cte'
+ RECORDS_COLUMN = 'records'
+
+ # This class optimizes slow database queries (PostgreSQL specific) where the
+ # IN SQL operator is used with sorting.
+ #
+ # Arguments:
+ # scope - ActiveRecord::Relation supporting keyset pagination
+ # array_scope - ActiveRecord::Relation for the `IN` subselect
+ # array_mapping_scope - Lambda for connecting scope with array_scope
+ # finder_query - ActiveRecord::Relation for finding one row by the passed in cursor values
+ # values - keyset cursor values (optional)
+ #
+ # Example ActiveRecord query: Issues in the namespace hierarchy
+ # > scope = Issue
+ # > .where(project_id: Group.find(9970).all_projects.select(:id))
+ # > .order(:created_at, :id)
+ # > .limit(20);
+ #
+ # Optimized version:
+ #
+ # > scope = Issue.where({}).order(:created_at, :id) # base scope
+ # > array_scope = Group.find(9970).all_projects.select(:id)
+ # > array_mapping_scope = -> (id_expression) { Issue.where(Issue.arel_table[:project_id].eq(id_expression)) }
+ #
+ # # finding the record by id is good enough, we can ignore the created_at_expression
+ # > finder_query = -> (created_at_expression, id_expression) { Issue.where(Issue.arel_table[:id].eq(id_expression)) }
+ #
+ # > Gitlab::Pagination::Keyset::InOperatorOptimization::QueryBuilder.new(
+ # > scope: scope,
+ # > array_scope: array_scope,
+ # > array_mapping_scope: array_mapping_scope,
+ # > finder_query: finder_query
+ # > ).execute.limit(20)
+ def initialize(scope:, array_scope:, array_mapping_scope:, finder_query:, values: {})
+ @scope, success = Gitlab::Pagination::Keyset::SimpleOrderBuilder.build(scope)
+
+ unless success
+ error_message = <<~MSG
+ The order on the scope does not support keyset pagination. You might need to define a custom Order object.\n
+ See https://docs.gitlab.com/ee/development/database/keyset_pagination.html#complex-order-configuration\n
+ Or the Gitlab::Pagination::Keyset::Order class for examples
+ MSG
+ raise(UnsupportedScopeOrder, error_message)
+ end
+
+ @order = Gitlab::Pagination::Keyset::Order.extract_keyset_order_object(scope)
+ @array_scope = array_scope
+ @array_mapping_scope = array_mapping_scope
+ @finder_query = finder_query
+ @values = values
+ @model = @scope.model
+ @table_name = @model.table_name
+ @arel_table = @model.arel_table
+ end
+
+ def execute
+ selector_cte = Gitlab::SQL::CTE.new(:array_cte, array_scope)
+
+ cte = Gitlab::SQL::RecursiveCTE.new(RECURSIVE_CTE_NAME, union_args: { remove_duplicates: false, remove_order: false })
+ cte << initializer_query
+ cte << data_collector_query
+
+ q = cte
+ .apply_to(model.where({})
+ .with(selector_cte.to_arel))
+ .select(result_collector_final_projections)
+ .where("count <> 0") # filter out the initializer row
+
+ model.from(q.arel.as(table_name))
+ end
+
+ private
+
+ attr_reader :array_scope, :scope, :order, :array_mapping_scope, :finder_query, :values, :model, :table_name, :arel_table
+
+ def initializer_query
+ array_column_names = array_scope_columns.array_aggregated_column_names + order_by_columns.array_aggregated_column_names
+
+ projections = [
+ *result_collector_initializer_columns,
+ *array_column_names,
+ '0::bigint AS count'
+ ]
+
+ model.select(projections).from(build_column_arrays_query).limit(1)
+ end
+
+ # This query finds the first cursor values for each item in the array CTE.
+ #
+ # array_cte:
+ #
+ # |project_id|
+ # |----------|
+ # | 1|
+ # | 2|
+ # | 3|
+ # | 4|
+ #
+ # For each project_id, find the first issues row by respecting the created_at, id order.
+ #
+ # The `array_mapping_scope` parameter defines how the `array_scope` and the `scope` can be combined.
+ #
+ # scope = Issue.where({}) # empty scope
+ # array_mapping_scope = Issue.where(project_id: X)
+ #
+ # scope.merge(array_mapping_scope) # Issue.where(project_id: X)
+ #
+ # X will be replaced with a value from the `array_cte` temporary table.
+ #
+ # |created_at|id|
+ # |----------|--|
+ # |2020-01-15| 2|
+ # |2020-01-07| 3|
+ # |2020-01-07| 4|
+ # |2020-01-10| 5|
+ def build_column_arrays_query
+ q = Arel::SelectManager.new
+ .project(array_scope_columns.array_aggregated_columns + order_by_columns.array_aggregated_columns)
+ .from(array_cte)
+ .join(Arel.sql("LEFT JOIN LATERAL (#{initial_keyset_query.to_sql}) #{table_name} ON TRUE"))
+
+ order_by_columns.each { |column| q.where(column.arel_column.not_eq(nil)) }
+
+ q.as('array_scope_lateral_query')
+ end
+
+ def array_cte
+ Arel::SelectManager.new
+ .project(array_scope_columns.arel_columns)
+ .from(Arel.sql(array_scope_columns.array_scope_cte_name))
+ .as(array_scope_columns.array_scope_cte_name)
+ end
+
+ def initial_keyset_query
+ keyset_scope = scope.merge(array_mapping_scope.call(*array_scope_columns.arel_columns))
+ order
+ .apply_cursor_conditions(keyset_scope, values, use_union_optimization: true)
+ .reselect(*order_by_columns.arel_columns)
+ .limit(1)
+ end
+
+ def data_collector_query
+ array_column_list = array_scope_columns.array_aggregated_column_names
+
+ order_column_value_arrays = order_by_columns.replace_value_in_array_by_position_expressions
+
+ select = [
+ *result_collector_columns,
+ *array_column_list,
+ *order_column_value_arrays,
+ "#{RECURSIVE_CTE_NAME}.count + 1"
+ ]
+
+ from = <<~SQL
+ #{RECURSIVE_CTE_NAME},
+ #{array_order_query.lateral.as('position_query').to_sql},
+ #{ensure_one_row(next_cursor_values_query).lateral.as('next_cursor_values').to_sql}
+ SQL
+
+ model.select(select).from(from)
+ end
+
+ # NULL guard. This method ensures that NULL values are returned when the passed in scope returns 0 rows.
+ # Example query: returns issues.id or NULL
+ #
+ # SELECT issues.id FROM (VALUES (NULL)) nulls (id)
+ # LEFT JOIN (SELECT id FROM issues WHERE id = 1 LIMIT 1) issues ON TRUE
+ # LIMIT 1
+ def ensure_one_row(query)
+ q = Arel::SelectManager.new
+ q.projections = order_by_columns.original_column_names_as_tmp_tamble
+
+ null_values = [nil] * order_by_columns.count
+
+ from = Arel::Nodes::Grouping.new(Arel::Nodes::ValuesList.new([null_values])).as('nulls')
+
+ q.from(from)
+ q.join(Arel.sql("LEFT JOIN (#{query.to_sql}) record ON TRUE"))
+ q.limit = 1
+ q
+ end
+
+ # This subquery finds the cursor values for the next record by sorting the generated cursor arrays in memory and taking the first element.
+ # It combines the cursor arrays (UNNEST) together and sorts them according to the originally defined ORDER BY clause.
+ #
+ # Example: issues in the group hierarchy with ORDER BY created_at, id
+ #
+ # |project_id| |created_at|id| # 2 arrays combined: issues_created_at_array, issues_id_array
+ # |----------| |----------|--|
+ # | 1| |2020-01-15| 2|
+ # | 2| |2020-01-07| 3|
+ # | 3| |2020-01-07| 4|
+ # | 4| |2020-01-10| 5|
+ #
+ # The query will return the cursor values: (2020-01-07, 3) and the array position: 1
+ # From the position, we can tell that the record belongs to the project with id 2.
+ def array_order_query
+ q = Arel::SelectManager.new
+ .project([*order_by_columns.original_column_names_as_arel_string, Arel.sql('position')])
+ .from("UNNEST(#{list(order_by_columns.array_aggregated_column_names)}) WITH ORDINALITY AS u(#{list(order_by_columns.original_column_names)}, position)")
+
+ order_by_columns.each { |column| q.where(Arel.sql(column.original_column_name).not_eq(nil)) } # ignore rows where all columns are NULL
+
+ q.order(Arel.sql(order_by_without_table_references)).take(1)
+ end
+
+ # This subquery finds the next cursor values after the previously determined position (from array_order_query).
+ # The current cursor values are passed in as SQL literals since the actual values are encoded into SQL arrays.
+ #
+ # Example: issues in the group hierarchy with ORDER BY created_at, id
+ #
+ # |project_id| |created_at|id| # 2 arrays combined: issues_created_at_array, issues_id_array
+ # |----------| |----------|--|
+ # | 1| |2020-01-15| 2|
+ # | 2| |2020-01-07| 3|
+ # | 3| |2020-01-07| 4|
+ # | 4| |2020-01-10| 5|
+ #
+ # Assuming that the determined position is 1, the cursor values will be the following:
+ # - Filter: project_id = 2
+ # - created_at = 2020-01-07
+ # - id = 3
+ def next_cursor_values_query
+ cursor_values = order_by_columns.cursor_values(RECURSIVE_CTE_NAME)
+ array_mapping_scope_columns = array_scope_columns.array_lookup_expressions_by_position(RECURSIVE_CTE_NAME)
+
+ keyset_scope = scope
+ .reselect(*order_by_columns.arel_columns)
+ .merge(array_mapping_scope.call(*array_mapping_scope_columns))
+
+ order
+ .apply_cursor_conditions(keyset_scope, cursor_values, use_union_optimization: true)
+ .reselect(*order_by_columns.arel_columns)
+ .limit(1)
+ end
+
+ # Generates an ORDER BY clause by using the column position index and the original order clauses.
+ # This method is used to sort the collected arrays in SQL.
+ # Example: "issues".created_at DESC , "issues".id ASC => 1 DESC, 2 ASC
+ def order_by_without_table_references
+ order.column_definitions.each_with_index.map do |column_definition, i|
+ "#{i + 1} #{column_definition.order_direction_as_sql_string}"
+ end.join(", ")
+ end
+
+ def result_collector_initializer_columns
+ ["NULL::#{table_name} AS #{RECORDS_COLUMN}"]
+ end
+
+ def result_collector_columns
+ query = finder_query
+ .call(*order_by_columns.array_lookup_expressions_by_position(RECURSIVE_CTE_NAME))
+ .select("#{table_name}")
+ .limit(1)
+
+ ["(#{query.to_sql})"]
+ end
+
+ def result_collector_final_projections
+ ["(#{RECORDS_COLUMN}).*"]
+ end
+
+ def array_scope_columns
+ @array_scope_columns ||= ArrayScopeColumns.new(array_scope.select_values)
+ end
+
+ def order_by_columns
+ @order_by_columns ||= OrderByColumns.new(order.column_definitions, arel_table)
+ end
+
+ def list(array)
+ array.join(', ')
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/pagination/keyset/iterator.rb b/lib/gitlab/pagination/keyset/iterator.rb
index c6f0014a0f4..14807fa37c4 100644
--- a/lib/gitlab/pagination/keyset/iterator.rb
+++ b/lib/gitlab/pagination/keyset/iterator.rb
@@ -6,12 +6,13 @@ module Gitlab
class Iterator
UnsupportedScopeOrder = Class.new(StandardError)
- def initialize(scope:, use_union_optimization: true)
+ def initialize(scope:, use_union_optimization: true, in_operator_optimization_options: nil)
@scope, success = Gitlab::Pagination::Keyset::SimpleOrderBuilder.build(scope)
raise(UnsupportedScopeOrder, 'The order on the scope does not support keyset pagination') unless success
@order = Gitlab::Pagination::Keyset::Order.extract_keyset_order_object(scope)
- @use_union_optimization = use_union_optimization
+ @use_union_optimization = in_operator_optimization_options ? false : use_union_optimization
+ @in_operator_optimization_options = in_operator_optimization_options
end
# rubocop: disable CodeReuse/ActiveRecord
@@ -19,11 +20,10 @@ module Gitlab
cursor_attributes = {}
loop do
- current_scope = scope.dup.limit(of)
- relation = order
- .apply_cursor_conditions(current_scope, cursor_attributes, { use_union_optimization: @use_union_optimization })
- .reorder(order)
- .limit(of)
+ current_scope = scope.dup
+ relation = order.apply_cursor_conditions(current_scope, cursor_attributes, keyset_options)
+ relation = relation.reorder(order) unless @in_operator_optimization_options
+ relation = relation.limit(of)
yield relation
@@ -38,6 +38,13 @@ module Gitlab
private
attr_reader :scope, :order
+
+ def keyset_options
+ {
+ use_union_optimization: @use_union_optimization,
+ in_operator_optimization_options: @in_operator_optimization_options
+ }
+ end
end
end
end
diff --git a/lib/gitlab/pagination/keyset/order.rb b/lib/gitlab/pagination/keyset/order.rb
index ccfa9334a12..80726fc8efd 100644
--- a/lib/gitlab/pagination/keyset/order.rb
+++ b/lib/gitlab/pagination/keyset/order.rb
@@ -152,15 +152,24 @@ module Gitlab
end
# rubocop: disable CodeReuse/ActiveRecord
- def apply_cursor_conditions(scope, values = {}, options = { use_union_optimization: false })
+ def apply_cursor_conditions(scope, values = {}, options = { use_union_optimization: false, in_operator_optimization_options: nil })
values ||= {}
transformed_values = values.with_indifferent_access
- scope = apply_custom_projections(scope)
+ scope = apply_custom_projections(scope.dup)
where_values = build_where_values(transformed_values)
if options[:use_union_optimization] && where_values.size > 1
build_union_query(scope, where_values).reorder(self)
+ elsif options[:in_operator_optimization_options]
+ opts = options[:in_operator_optimization_options]
+
+ Gitlab::Pagination::Keyset::InOperatorOptimization::QueryBuilder.new(
+ **{
+ scope: scope.reorder(self),
+ values: values
+ }.merge(opts)
+ ).execute
else
scope.where(build_or_query(where_values)) # rubocop: disable CodeReuse/ActiveRecord
end
@@ -187,7 +196,7 @@ module Gitlab
columns = Arel::Nodes::Grouping.new(column_definitions.map(&:column_expression))
values = Arel::Nodes::Grouping.new(column_definitions.map do |column_definition|
value = values[column_definition.attribute_name]
- Arel::Nodes.build_quoted(value, column_definition.column_expression)
+ build_quoted(value, column_definition.column_expression)
end)
if column_definitions.first.ascending_order?
@@ -197,6 +206,12 @@ module Gitlab
end
end
+ def build_quoted(value, column_expression)
+ return value if value.instance_of?(Arel::Nodes::SqlLiteral)
+
+ Arel::Nodes.build_quoted(value, column_expression)
+ end
+
# Adds extra columns to the SELECT clause
def apply_custom_projections(scope)
additional_projections = column_definitions.select(&:add_to_projections).map do |column_definition|
@@ -204,7 +219,7 @@ module Gitlab
column_definition.column_expression.dup.as(column_definition.attribute_name).to_sql
end
- scope = scope.select(*scope.arel.projections, *additional_projections) if additional_projections
+ scope = scope.reselect(*scope.arel.projections, *additional_projections) unless additional_projections.blank?
scope
end
diff --git a/lib/gitlab/pagination/offset_pagination.rb b/lib/gitlab/pagination/offset_pagination.rb
index 4f8a6ffb2cc..7b5013f137b 100644
--- a/lib/gitlab/pagination/offset_pagination.rb
+++ b/lib/gitlab/pagination/offset_pagination.rb
@@ -29,7 +29,7 @@ module Gitlab
return pagination_data unless Feature.enabled?(:api_kaminari_count_with_limit, type: :ops)
limited_total_count = pagination_data.total_count_with_limit
- if limited_total_count > Kaminari::ActiveRecordRelationMethods::MAX_COUNT_LIMIT
+ if limited_total_count > max_limit
# The call to `total_count_with_limit` memoizes `@arel` because of a call to `references_eager_loaded_tables?`
# We need to call `reset` because `without_count` relies on `@arel` being unmemoized
pagination_data.reset.without_count
@@ -38,6 +38,14 @@ module Gitlab
end
end
+ def max_limit
+ if Feature.enabled?(:lower_relation_max_count_limit, type: :ops)
+ Kaminari::ActiveRecordRelationMethods::MAX_COUNT_NEW_LOWER_LIMIT
+ else
+ Kaminari::ActiveRecordRelationMethods::MAX_COUNT_LIMIT
+ end
+ end
+
def needs_pagination?(relation)
return true unless relation.respond_to?(:current_page)
return true if params[:page].present? && relation.current_page != params[:page].to_i
diff --git a/lib/gitlab/patch/legacy_database_config.rb b/lib/gitlab/patch/legacy_database_config.rb
new file mode 100644
index 00000000000..a7d4fdf7490
--- /dev/null
+++ b/lib/gitlab/patch/legacy_database_config.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+# The purpose of this code is to transform legacy `database.yml`
+# into a `database.yml` containing `main:` as a name of a first database
+#
+# This should be removed once all places using legacy `database.yml`
+# are fixed. The likely moment to remove this check is the %14.0.
+#
+# This converts the following syntax:
+#
+# production:
+# adapter: postgresql
+# database: gitlabhq_production
+# username: git
+# password: "secure password"
+# host: localhost
+#
+# Into:
+#
+# production:
+# main:
+# adapter: postgresql
+# database: gitlabhq_production
+# username: git
+# password: "secure password"
+# host: localhost
+#
+
+module Gitlab
+ module Patch
+ module LegacyDatabaseConfig
+ extend ActiveSupport::Concern
+
+ prepended do
+ attr_reader :uses_legacy_database_config
+ end
+
+ def database_configuration
+ @uses_legacy_database_config = false # rubocop:disable Gitlab/ModuleWithInstanceVariables
+
+ super.to_h do |env, configs|
+ # This check is taken from Rails where the transformation
+ # of a flat database.yml is done into `primary:`
+ # https://github.com/rails/rails/blob/v6.1.4/activerecord/lib/active_record/database_configurations.rb#L169
+ if configs.is_a?(Hash) && !configs.all? { |_, v| v.is_a?(Hash) }
+ configs = { "main" => configs }
+
+ @uses_legacy_database_config = true # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ end
+
+ [env, configs]
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/path_regex.rb b/lib/gitlab/path_regex.rb
index 4cb47ffc6d9..c648f4d1fd0 100644
--- a/lib/gitlab/path_regex.rb
+++ b/lib/gitlab/path_regex.rb
@@ -184,6 +184,10 @@ module Gitlab
@repository_git_route_regex ||= /#{repository_route_regex}\.git/.freeze
end
+ def repository_git_lfs_route_regex
+ @repository_git_lfs_route_regex ||= %r{#{repository_git_route_regex}\/(info\/lfs|gitlab-lfs)\/}.freeze
+ end
+
def repository_wiki_git_route_regex
@repository_wiki_git_route_regex ||= /#{full_namespace_route_regex}\.*\.wiki\.git/.freeze
end
diff --git a/lib/gitlab/quick_actions/issue_actions.rb b/lib/gitlab/quick_actions/issue_actions.rb
index ff17ecf8024..c5cf3262039 100644
--- a/lib/gitlab/quick_actions/issue_actions.rb
+++ b/lib/gitlab/quick_actions/issue_actions.rb
@@ -267,7 +267,7 @@ module Gitlab
private
def zoom_link_service
- Issues::ZoomLinkService.new(project: quick_action_target.project, current_user: current_user, params: { issue: quick_action_target })
+ ::Issues::ZoomLinkService.new(project: quick_action_target.project, current_user: current_user, params: { issue: quick_action_target })
end
end
end
diff --git a/lib/gitlab/quick_actions/merge_request_actions.rb b/lib/gitlab/quick_actions/merge_request_actions.rb
index 47c76e98e5c..6348a4902f8 100644
--- a/lib/gitlab/quick_actions/merge_request_actions.rb
+++ b/lib/gitlab/quick_actions/merge_request_actions.rb
@@ -155,6 +155,20 @@ module Gitlab
@execution_message[:approve] = _('Approved the current merge request.')
end
+ desc _('Unapprove a merge request')
+ explanation _('Unapprove the current merge request.')
+ types MergeRequest
+ condition do
+ quick_action_target.persisted? && quick_action_target.can_be_unapproved_by?(current_user)
+ end
+ command :unapprove do
+ success = MergeRequests::RemoveApprovalService.new(project: quick_action_target.project, current_user: current_user).execute(quick_action_target)
+
+ next unless success
+
+ @execution_message[:unapprove] = _('Unapproved the current merge request.')
+ end
+
desc do
if quick_action_target.allows_multiple_reviewers?
_('Assign reviewer(s)')
diff --git a/lib/gitlab/rack_attack.rb b/lib/gitlab/rack_attack.rb
index 175f32bd4c6..3f4c0fa45aa 100644
--- a/lib/gitlab/rack_attack.rb
+++ b/lib/gitlab/rack_attack.rb
@@ -82,15 +82,27 @@ module Gitlab
end
def self.configure_throttles(rack_attack)
- throttle_or_track(rack_attack, 'throttle_unauthenticated', Gitlab::Throttle.unauthenticated_options) do |req|
- if req.throttle_unauthenticated?
- req.ip
+ # Each of these settings follows the same pattern of specifying separate
+ # authenticated and unauthenticated rates via settings
+ Gitlab::Throttle::REGULAR_THROTTLES.each do |throttle|
+ unauthenticated_options = Gitlab::Throttle.options(throttle, authenticated: false)
+ throttle_or_track(rack_attack, "throttle_unauthenticated_#{throttle}", unauthenticated_options) do |req|
+ if req.throttle?(throttle, authenticated: false)
+ req.ip
+ end
+ end
+
+ authenticated_options = Gitlab::Throttle.options(throttle, authenticated: true)
+ throttle_or_track(rack_attack, "throttle_authenticated_#{throttle}", authenticated_options) do |req|
+ if req.throttle?(throttle, authenticated: true)
+ req.throttled_user_id([:api])
+ end
end
end
- throttle_or_track(rack_attack, 'throttle_authenticated_api', Gitlab::Throttle.authenticated_api_options) do |req|
- if req.throttle_authenticated_api?
- req.throttled_user_id([:api])
+ throttle_or_track(rack_attack, 'throttle_unauthenticated_web', Gitlab::Throttle.unauthenticated_web_options) do |req|
+ if req.throttle_unauthenticated_web?
+ req.ip
end
end
@@ -127,14 +139,8 @@ module Gitlab
end
end
- throttle_or_track(rack_attack, 'throttle_unauthenticated_packages_api', Gitlab::Throttle.unauthenticated_packages_api_options) do |req|
- if req.throttle_unauthenticated_packages_api?
- req.ip
- end
- end
-
- throttle_or_track(rack_attack, 'throttle_authenticated_packages_api', Gitlab::Throttle.authenticated_packages_api_options) do |req|
- if req.throttle_authenticated_packages_api?
+ throttle_or_track(rack_attack, 'throttle_authenticated_git_lfs', Gitlab::Throttle.throttle_authenticated_git_lfs_options) do |req|
+ if req.throttle_authenticated_git_lfs?
req.throttled_user_id([:api])
end
end
@@ -159,7 +165,15 @@ module Gitlab
return false if dry_run_config.empty?
return true if dry_run_config == '*'
- dry_run_config.split(',').map(&:strip).include?(name)
+ dry_run_throttles = dry_run_config.split(',').map(&:strip)
+
+ # `throttle_unauthenticated` was split into API and web, so to maintain backwards-compatibility
+ # this throttle name now controls both rate limits.
+ if dry_run_throttles.include?('throttle_unauthenticated')
+ dry_run_throttles += %w[throttle_unauthenticated_api throttle_unauthenticated_web]
+ end
+
+ dry_run_throttles.include?(name)
end
def self.user_allowlist
diff --git a/lib/gitlab/rack_attack/request.rb b/lib/gitlab/rack_attack/request.rb
index 7fee6a1b43d..099174842d0 100644
--- a/lib/gitlab/rack_attack/request.rb
+++ b/lib/gitlab/rack_attack/request.rb
@@ -3,6 +3,8 @@
module Gitlab
module RackAttack
module Request
+ FILES_PATH_REGEX = %r{^/api/v\d+/projects/[^/]+/repository/files/.+}.freeze
+
def unauthenticated?
!(authenticated_user_id([:api, :rss, :ics]) || authenticated_runner_id)
end
@@ -58,9 +60,25 @@ module Gitlab
path =~ protected_paths_regex
end
- def throttle_unauthenticated?
+ def throttle?(throttle, authenticated:)
+ fragment = Gitlab::Throttle.throttle_fragment!(throttle, authenticated: authenticated)
+
+ __send__("#{fragment}?") # rubocop:disable GitlabSecurity/PublicSend
+ end
+
+ def throttle_unauthenticated_api?
+ api_request? &&
!should_be_skipped? &&
!throttle_unauthenticated_packages_api? &&
+ !throttle_unauthenticated_files_api? &&
+ Gitlab::Throttle.settings.throttle_unauthenticated_api_enabled &&
+ unauthenticated?
+ end
+
+ def throttle_unauthenticated_web?
+ web_request? &&
+ !should_be_skipped? &&
+ # TODO: Column will be renamed in https://gitlab.com/gitlab-org/gitlab/-/issues/340031
Gitlab::Throttle.settings.throttle_unauthenticated_enabled &&
unauthenticated?
end
@@ -68,11 +86,13 @@ module Gitlab
def throttle_authenticated_api?
api_request? &&
!throttle_authenticated_packages_api? &&
+ !throttle_authenticated_files_api? &&
Gitlab::Throttle.settings.throttle_authenticated_api_enabled
end
def throttle_authenticated_web?
web_request? &&
+ !throttle_authenticated_git_lfs? &&
Gitlab::Throttle.settings.throttle_authenticated_web_enabled
end
@@ -109,6 +129,24 @@ module Gitlab
Gitlab::Throttle.settings.throttle_authenticated_packages_api_enabled
end
+ def throttle_authenticated_git_lfs?
+ git_lfs_path? &&
+ Gitlab::Throttle.settings.throttle_authenticated_git_lfs_enabled
+ end
+
+ def throttle_unauthenticated_files_api?
+ files_api_path? &&
+ Feature.enabled?(:files_api_throttling, default_enabled: :yaml) &&
+ Gitlab::Throttle.settings.throttle_unauthenticated_files_api_enabled &&
+ unauthenticated?
+ end
+
+ def throttle_authenticated_files_api?
+ files_api_path? &&
+ Feature.enabled?(:files_api_throttling, default_enabled: :yaml) &&
+ Gitlab::Throttle.settings.throttle_authenticated_files_api_enabled
+ end
+
private
def authenticated_user_id(request_formats)
@@ -130,6 +168,14 @@ module Gitlab
def packages_api_path?
path =~ ::Gitlab::Regex::Packages::API_PATH_REGEX
end
+
+ def git_lfs_path?
+ path =~ Gitlab::PathRegex.repository_git_lfs_route_regex
+ end
+
+ def files_api_path?
+ path =~ FILES_PATH_REGEX
+ end
end
end
end
diff --git a/lib/gitlab/reference_extractor.rb b/lib/gitlab/reference_extractor.rb
index 547549361be..f914123a94d 100644
--- a/lib/gitlab/reference_extractor.rb
+++ b/lib/gitlab/reference_extractor.rb
@@ -6,16 +6,11 @@ module Gitlab
REFERABLES = %i(user issue label milestone mentioned_user mentioned_group mentioned_project
merge_request snippet commit commit_range directly_addressed_user epic iteration vulnerability).freeze
attr_accessor :project, :current_user, :author
- # This counter is increased by a number of references filtered out by
- # banzai reference exctractor. Note that this counter is stateful and
- # not idempotent and is increased whenever you call `references`.
- attr_reader :stateful_not_visible_counter
def initialize(project, current_user = nil)
@project = project
@current_user = current_user
@references = {}
- @stateful_not_visible_counter = 0
super()
end
@@ -26,14 +21,19 @@ module Gitlab
def references(type, ids_only: false)
refs = super(type, project, current_user, ids_only: ids_only)
- @stateful_not_visible_counter += refs[:not_visible].count
+ update_visible_nodes_set(refs[:nodes], refs[:visible_nodes])
refs[:visible]
end
+ # this method is stateful, it tracks if all nodes from `references`
+ # calls are visible or not
+ def all_visible?
+ not_visible_nodes.empty?
+ end
+
def reset_memoized_values
@references = {}
- @stateful_not_visible_counter = 0
super()
end
@@ -76,5 +76,16 @@ module Gitlab
@pattern = Regexp.union(patterns.compact)
end
+
+ private
+
+ def update_visible_nodes_set(all, visible)
+ not_visible_nodes.merge(all)
+ not_visible_nodes.subtract(visible)
+ end
+
+ def not_visible_nodes
+ @not_visible_nodes ||= Set.new
+ end
end
end
diff --git a/lib/gitlab/regex.rb b/lib/gitlab/regex.rb
index 698a417283e..a88ef5fe73e 100644
--- a/lib/gitlab/regex.rb
+++ b/lib/gitlab/regex.rb
@@ -21,7 +21,8 @@ module Gitlab
end
def composer_package_version_regex
- @composer_package_version_regex ||= %r{^v?(\d+(\.(\d+|x))*(-.+)?)}.freeze
+ # see https://github.com/composer/semver/blob/31f3ea725711245195f62e54ffa402d8ef2fdba9/src/VersionParser.php#L215
+ @composer_package_version_regex ||= %r{\Av?((\d++)(\.(?:\d++|[xX*]))?(\.(?:\d++|[xX*]))?(\.(?:\d++|[xX*]))?)?\z}.freeze
end
def composer_dev_version_regex
diff --git a/lib/gitlab/repository_cache/preloader.rb b/lib/gitlab/repository_cache/preloader.rb
new file mode 100644
index 00000000000..726dde4e0ca
--- /dev/null
+++ b/lib/gitlab/repository_cache/preloader.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+module Gitlab
+ class RepositoryCache
+ class Preloader
+ def initialize(repositories)
+ @repositories = repositories
+ end
+
+ def preload(methods)
+ return if @repositories.empty?
+
+ cache_keys = []
+
+ sources_by_cache_key = @repositories.each_with_object({}) do |repository, hash|
+ methods.each do |method|
+ cache_key = repository.cache.cache_key(method)
+
+ hash[cache_key] = { repository: repository, method: method }
+ cache_keys << cache_key
+ end
+ end
+
+ Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands do
+ backend.read_multi(*cache_keys).each do |cache_key, value|
+ source = sources_by_cache_key[cache_key]
+
+ source[:repository].memoize_method_cache_value(source[:method], value)
+ end
+ end
+ end
+
+ private
+
+ def backend
+ @repositories.first.cache.backend
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/repository_cache_adapter.rb b/lib/gitlab/repository_cache_adapter.rb
index d0230c035cc..c096c870f2a 100644
--- a/lib/gitlab/repository_cache_adapter.rb
+++ b/lib/gitlab/repository_cache_adapter.rb
@@ -217,6 +217,10 @@ module Gitlab
fallback
end
+ def memoize_method_cache_value(method, value)
+ strong_memoize(memoizable_name(method)) { value }
+ end
+
# Expires the caches of a specific set of methods
def expire_method_caches(methods)
methods.each do |name|
diff --git a/lib/gitlab/saas.rb b/lib/gitlab/saas.rb
index 8d9d8415cb1..e87c2a0b700 100644
--- a/lib/gitlab/saas.rb
+++ b/lib/gitlab/saas.rb
@@ -20,6 +20,22 @@ module Gitlab
def self.dev_url
'https://dev.gitlab.org'
end
+
+ def self.registry_prefix
+ 'registry.gitlab.com'
+ end
+
+ def self.customer_support_url
+ 'https://support.gitlab.com'
+ end
+
+ def self.customer_license_support_url
+ 'https://support.gitlab.com/hc/en-us/requests/new?ticket_form_id=360000071293'
+ end
+
+ def self.gitlab_com_status_url
+ 'https://status.gitlab.com'
+ end
end
end
diff --git a/lib/gitlab/search_results.rb b/lib/gitlab/search_results.rb
index 90513e346f2..217a48e740d 100644
--- a/lib/gitlab/search_results.rb
+++ b/lib/gitlab/search_results.rb
@@ -188,7 +188,7 @@ module Gitlab
merge_requests = MergeRequestsFinder.new(current_user, issuable_params).execute
unless default_project_filter
- merge_requests = merge_requests.in_projects(project_ids_relation)
+ merge_requests = merge_requests.of_projects(project_ids_relation)
end
apply_sort(merge_requests, scope: 'merge_requests')
diff --git a/lib/gitlab/seeder.rb b/lib/gitlab/seeder.rb
index 4158cec9b09..5671fce481f 100644
--- a/lib/gitlab/seeder.rb
+++ b/lib/gitlab/seeder.rb
@@ -1,17 +1,5 @@
# frozen_string_literal: true
-# :nocov:
-module DeliverNever
- def deliver_later
- self
- end
-end
-
-module MuteNotifications
- def new_note(note)
- end
-end
-
module Gitlab
class Seeder
extend ActionView::Helpers::NumberHelper
@@ -82,18 +70,22 @@ module Gitlab
Project.include(ProjectSeed)
User.include(UserSeed)
- mute_notifications
- mute_mailer
+ old_perform_deliveries = ActionMailer::Base.perform_deliveries
+ ActionMailer::Base.perform_deliveries = false
SeedFu.quiet = true
without_statement_timeout do
- yield
+ without_new_note_notifications do
+ yield
+ end
end
+ puts "\nOK".color(:green)
+ ensure
SeedFu.quiet = false
+ ActionMailer::Base.perform_deliveries = old_perform_deliveries
ActiveRecord::Base.logger = old_logger
- puts "\nOK".color(:green)
end
def self.without_gitaly_timeout
@@ -109,12 +101,14 @@ module Gitlab
ApplicationSetting.expire
end
- def self.mute_notifications
- NotificationService.prepend(MuteNotifications)
- end
+ def self.without_new_note_notifications
+ NotificationService.alias_method :original_new_note, :new_note
+ NotificationService.define_method(:new_note) { |note| }
- def self.mute_mailer
- ActionMailer::MessageDelivery.prepend(DeliverNever)
+ yield
+ ensure
+ NotificationService.alias_method :new_note, :original_new_note
+ NotificationService.remove_method :original_new_note
end
def self.without_statement_timeout
diff --git a/lib/gitlab/sidekiq_cluster/cli.rb b/lib/gitlab/sidekiq_cluster/cli.rb
index 05319ba17a2..3dee257229d 100644
--- a/lib/gitlab/sidekiq_cluster/cli.rb
+++ b/lib/gitlab/sidekiq_cluster/cli.rb
@@ -57,6 +57,11 @@ module Gitlab
worker_queues = SidekiqConfig::CliMethods.worker_queues(@rails_path)
queue_groups = argv.map do |queues_or_query_string|
+ if queues_or_query_string =~ /[\r\n]/
+ raise CommandError,
+ 'The queue arguments cannot contain newlines'
+ end
+
next worker_queues if queues_or_query_string == SidekiqConfig::WorkerMatcher::WILDCARD_MATCH
# When using the queue query syntax, we treat each queue group
diff --git a/lib/gitlab/sidekiq_logging/structured_logger.rb b/lib/gitlab/sidekiq_logging/structured_logger.rb
index 842e53b2ffb..1aebce987fe 100644
--- a/lib/gitlab/sidekiq_logging/structured_logger.rb
+++ b/lib/gitlab/sidekiq_logging/structured_logger.rb
@@ -69,6 +69,7 @@ module Gitlab
message = base_message(payload)
payload['load_balancing_strategy'] = job['load_balancing_strategy'] if job['load_balancing_strategy']
+ payload['dedup_wal_locations'] = job['dedup_wal_locations'] if job['dedup_wal_locations'].present?
if job_exception
payload['message'] = "#{message}: fail: #{payload['duration_s']} sec"
diff --git a/lib/gitlab/sidekiq_middleware.rb b/lib/gitlab/sidekiq_middleware.rb
index 3422cb47516..d084e9e9d7e 100644
--- a/lib/gitlab/sidekiq_middleware.rb
+++ b/lib/gitlab/sidekiq_middleware.rb
@@ -26,12 +26,14 @@ module Gitlab
chain.add ::Gitlab::SidekiqMiddleware::BatchLoader
chain.add ::Labkit::Middleware::Sidekiq::Server
chain.add ::Gitlab::SidekiqMiddleware::InstrumentationLogger
- chain.add ::Gitlab::Database::LoadBalancing::SidekiqServerMiddleware if load_balancing_enabled?
chain.add ::Gitlab::SidekiqMiddleware::AdminMode::Server
chain.add ::Gitlab::SidekiqVersioning::Middleware
chain.add ::Gitlab::SidekiqStatus::ServerMiddleware
chain.add ::Gitlab::SidekiqMiddleware::WorkerContext::Server
+ # DuplicateJobs::Server should be placed at the bottom, but before the SidekiqServerMiddleware,
+ # so we can compare the latest WAL location against replica
chain.add ::Gitlab::SidekiqMiddleware::DuplicateJobs::Server
+ chain.add ::Gitlab::Database::LoadBalancing::SidekiqServerMiddleware if load_balancing_enabled?
end
end
@@ -42,13 +44,15 @@ module Gitlab
lambda do |chain|
chain.add ::Gitlab::SidekiqMiddleware::WorkerContext::Client # needs to be before the Labkit middleware
chain.add ::Labkit::Middleware::Sidekiq::Client
+ # Sidekiq Client Middleware should be placed before DuplicateJobs::Client middleware,
+ # so we can store WAL location before we deduplicate the job.
+ chain.add ::Gitlab::Database::LoadBalancing::SidekiqClientMiddleware if load_balancing_enabled?
chain.add ::Gitlab::SidekiqMiddleware::DuplicateJobs::Client
chain.add ::Gitlab::SidekiqStatus::ClientMiddleware
chain.add ::Gitlab::SidekiqMiddleware::AdminMode::Client
- # Size limiter should be placed at the bottom, but before the metrics midleware
+ # Size limiter should be placed at the bottom, but before the metrics middleware
chain.add ::Gitlab::SidekiqMiddleware::SizeLimiter::Client
chain.add ::Gitlab::SidekiqMiddleware::ClientMetrics
- chain.add ::Gitlab::Database::LoadBalancing::SidekiqClientMiddleware if load_balancing_enabled?
end
end
diff --git a/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb b/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb
index c1dc616cbb2..aeb58d7c153 100644
--- a/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb
+++ b/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb
@@ -17,10 +17,26 @@ module Gitlab
#
# When new jobs can be scheduled again, the strategy calls `#delete`.
class DuplicateJob
+ include Gitlab::Utils::StrongMemoize
+
DUPLICATE_KEY_TTL = 6.hours
+ WAL_LOCATION_TTL = 60.seconds
+ MAX_REDIS_RETRIES = 5
DEFAULT_STRATEGY = :until_executing
STRATEGY_NONE = :none
+ LUA_SET_WAL_SCRIPT = <<~EOS
+ local key, wal, offset, ttl = KEYS[1], ARGV[1], tonumber(ARGV[2]), ARGV[3]
+ local existing_offset = redis.call("LINDEX", key, -1)
+ if existing_offset == false then
+ redis.call("RPUSH", key, wal, offset)
+ redis.call("EXPIRE", key, ttl)
+ elseif offset > tonumber(existing_offset) then
+ redis.call("LSET", key, 0, wal)
+ redis.call("LSET", key, -1, offset)
+ end
+ EOS
+
attr_reader :existing_jid
def initialize(job, queue_name)
@@ -44,22 +60,59 @@ module Gitlab
# This method will return the jid that was set in redis
def check!(expiry = DUPLICATE_KEY_TTL)
read_jid = nil
+ read_wal_locations = {}
Sidekiq.redis do |redis|
redis.multi do |multi|
redis.set(idempotency_key, jid, ex: expiry, nx: true)
+ read_wal_locations = check_existing_wal_locations!(redis, expiry)
read_jid = redis.get(idempotency_key)
end
end
job['idempotency_key'] = idempotency_key
+ # We need to fetch values since the read_wal_locations and read_jid were obtained inside transaction, under redis.multi command.
+ self.existing_wal_locations = read_wal_locations.transform_values(&:value)
self.existing_jid = read_jid.value
end
+ def update_latest_wal_location!
+ return unless job_wal_locations.present?
+
+ Sidekiq.redis do |redis|
+ redis.multi do
+ job_wal_locations.each do |connection_name, location|
+ redis.eval(LUA_SET_WAL_SCRIPT, keys: [wal_location_key(connection_name)], argv: [location, pg_wal_lsn_diff(connection_name).to_i, WAL_LOCATION_TTL])
+ end
+ end
+ end
+ end
+
+ def latest_wal_locations
+ return {} unless job_wal_locations.present?
+
+ strong_memoize(:latest_wal_locations) do
+ read_wal_locations = {}
+
+ Sidekiq.redis do |redis|
+ redis.multi do
+ job_wal_locations.keys.each do |connection_name|
+ read_wal_locations[connection_name] = redis.lindex(wal_location_key(connection_name), 0)
+ end
+ end
+ end
+
+ read_wal_locations.transform_values(&:value).compact
+ end
+ end
+
def delete!
Sidekiq.redis do |redis|
- redis.del(idempotency_key)
+ redis.multi do |multi|
+ redis.del(idempotency_key)
+ delete_wal_locations!(redis)
+ end
end
end
@@ -93,6 +146,7 @@ module Gitlab
private
+ attr_accessor :existing_wal_locations
attr_reader :queue_name, :job
attr_writer :existing_jid
@@ -100,6 +154,10 @@ module Gitlab
@worker_klass ||= worker_class_name.to_s.safe_constantize
end
+ def pg_wal_lsn_diff(connection_name)
+ Gitlab::Database::DATABASES[connection_name].pg_wal_lsn_diff(job_wal_locations[connection_name], existing_wal_locations[connection_name])
+ end
+
def strategy
return DEFAULT_STRATEGY unless worker_klass
return DEFAULT_STRATEGY unless worker_klass.respond_to?(:idempotent?)
@@ -120,6 +178,20 @@ module Gitlab
job['jid']
end
+ def job_wal_locations
+ return {} unless preserve_wal_location?
+
+ job['wal_locations'] || {}
+ end
+
+ def existing_wal_location_key(connection_name)
+ "#{idempotency_key}:#{connection_name}:existing_wal_location"
+ end
+
+ def wal_location_key(connection_name)
+ "#{idempotency_key}:#{connection_name}:wal_location"
+ end
+
def idempotency_key
@idempotency_key ||= job['idempotency_key'] || "#{namespace}:#{idempotency_hash}"
end
@@ -135,6 +207,29 @@ module Gitlab
def idempotency_string
"#{worker_class_name}:#{Sidekiq.dump_json(arguments)}"
end
+
+ def delete_wal_locations!(redis)
+ job_wal_locations.keys.each do |connection_name|
+ redis.del(wal_location_key(connection_name))
+ redis.del(existing_wal_location_key(connection_name))
+ end
+ end
+
+ def check_existing_wal_locations!(redis, expiry)
+ read_wal_locations = {}
+
+ job_wal_locations.each do |connection_name, location|
+ key = existing_wal_location_key(connection_name)
+ redis.set(key, location, ex: expiry, nx: true)
+ read_wal_locations[connection_name] = redis.get(key)
+ end
+
+ read_wal_locations
+ end
+
+ def preserve_wal_location?
+ Feature.enabled?(:preserve_latest_wal_locations_for_idempotent_jobs, default_enabled: :yaml)
+ end
end
end
end
diff --git a/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/deduplicates_when_scheduling.rb b/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/deduplicates_when_scheduling.rb
index 469033a5e52..fc58d4f5323 100644
--- a/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/deduplicates_when_scheduling.rb
+++ b/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/deduplicates_when_scheduling.rb
@@ -14,6 +14,8 @@ module Gitlab
job['duplicate-of'] = duplicate_job.existing_jid
if duplicate_job.idempotent?
+ duplicate_job.update_latest_wal_location!
+
Gitlab::SidekiqLogging::DeduplicationLogger.instance.log(
job, "dropped #{strategy_name}", duplicate_job.options)
return false
@@ -23,8 +25,16 @@ module Gitlab
yield
end
+ def perform(job)
+ update_job_wal_location!(job)
+ end
+
private
+ def update_job_wal_location!(job)
+ job['dedup_wal_locations'] = duplicate_job.latest_wal_locations if duplicate_job.latest_wal_locations.present?
+ end
+
def deduplicatable_job?
!duplicate_job.scheduled? || duplicate_job.options[:including_scheduled]
end
diff --git a/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executed.rb b/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executed.rb
index 738efa36fc8..5164b994267 100644
--- a/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executed.rb
+++ b/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executed.rb
@@ -8,9 +8,14 @@ module Gitlab
# removes the lock after the job has executed preventing a new job to be queued
# while a job is still executing.
class UntilExecuted < Base
+ extend ::Gitlab::Utils::Override
+
include DeduplicatesWhenScheduling
- def perform(_job)
+ override :perform
+ def perform(job)
+ super
+
yield
duplicate_job.delete!
diff --git a/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing.rb b/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing.rb
index 68d66383b2b..1f7e3a4ea30 100644
--- a/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing.rb
+++ b/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing.rb
@@ -8,9 +8,13 @@ module Gitlab
# removes the lock before the job starts allowing a new job to be queued
# while a job is still executing.
class UntilExecuting < Base
+ extend ::Gitlab::Utils::Override
+
include DeduplicatesWhenScheduling
- def perform(_job)
+ override :perform
+ def perform(job)
+ super
duplicate_job.delete!
yield
diff --git a/lib/gitlab/sidekiq_middleware/size_limiter/validator.rb b/lib/gitlab/sidekiq_middleware/size_limiter/validator.rb
index b37eeb8bad1..a83522a489a 100644
--- a/lib/gitlab/sidekiq_middleware/size_limiter/validator.rb
+++ b/lib/gitlab/sidekiq_middleware/size_limiter/validator.rb
@@ -4,12 +4,12 @@ module Gitlab
module SidekiqMiddleware
module SizeLimiter
# Handle a Sidekiq job payload limit based on current configuration.
- # This validator pulls the configuration from the environment variables:
- # - GITLAB_SIDEKIQ_SIZE_LIMITER_MODE: the current mode of the size
- # limiter. This must be either `track` or `compress`.
- # - GITLAB_SIDEKIQ_SIZE_LIMITER_COMPRESSION_THRESHOLD_BYTES: the
- # threshold before the input job payload is compressed.
- # - GITLAB_SIDEKIQ_SIZE_LIMITER_LIMIT_BYTES: the size limit in bytes.
+ # This validator pulls the configuration from application settings:
+ # - limiter_mode: the current mode of the size
+ # limiter. This must be either `track` or `compress`.
+ # - compression_threshold_bytes: the threshold before the input job
+ # payload is compressed.
+ # - limit_bytes: the size limit in bytes.
#
# In track mode, if a job payload limit exceeds the size limit, an
# event is sent to Sentry and the job is scheduled like normal.
@@ -18,12 +18,29 @@ module Gitlab
# then compressed. If the compressed payload still exceeds the limit, the
# job is discarded, and a ExceedLimitError exception is raised.
class Validator
- def self.validate!(worker_class, job)
- new(worker_class, job).validate!
+ # Avoid limiting the size of jobs for `BackgroundMigrationWorker` classes.
+ # We can't read the configuration from `ApplicationSetting` for those jobs
+ # when migrating a path that modifies the `application_settings` table.
+ # Reading the application settings through `ApplicationSetting#current`
+ # causes a `SELECT` with a list of column names, but that list of column
+ # names might not match what the table currently looks like causing
+ # an error when scheduling background migrations.
+ #
+ # The worker classes aren't constants here, because that would force
+ # Application Settings to be loaded earlier causing failures loading
+ # the environmant in rake tasks
+ EXEMPT_WORKER_NAMES = ["BackgroundMigrationWorker", "Database::BatchedBackgroundMigrationWorker"].to_set
+
+ class << self
+ def validate!(worker_class, job)
+ return if EXEMPT_WORKER_NAMES.include?(worker_class.to_s)
+
+ new(worker_class, job).validate!
+ end
end
DEFAULT_SIZE_LIMIT = 0
- DEFAULT_COMPRESION_THRESHOLD_BYTES = 100_000 # 100kb
+ DEFAULT_COMPRESSION_THRESHOLD_BYTES = 100_000 # 100kb
MODES = [
TRACK_MODE = 'track',
@@ -34,9 +51,9 @@ module Gitlab
def initialize(
worker_class, job,
- mode: ENV['GITLAB_SIDEKIQ_SIZE_LIMITER_MODE'],
- compression_threshold: ENV['GITLAB_SIDEKIQ_SIZE_LIMITER_COMPRESSION_THRESHOLD_BYTES'],
- size_limit: ENV['GITLAB_SIDEKIQ_SIZE_LIMITER_LIMIT_BYTES']
+ mode: Gitlab::CurrentSettings.sidekiq_job_limiter_mode,
+ compression_threshold: Gitlab::CurrentSettings.sidekiq_job_limiter_compression_threshold_bytes,
+ size_limit: Gitlab::CurrentSettings.sidekiq_job_limiter_limit_bytes
)
@worker_class = worker_class
@job = job
@@ -47,11 +64,11 @@ module Gitlab
end
def validate!
- return unless @size_limit > 0
- return if allow_big_payload?
-
job_args = compress_if_necessary(::Sidekiq.dump_json(@job['args']))
+
+ return if @size_limit == 0
return if job_args.bytesize <= @size_limit
+ return if allow_big_payload?
exception = exceed_limit_error(job_args)
if compress_mode?
@@ -72,10 +89,10 @@ module Gitlab
end
def set_compression_threshold(compression_threshold)
- @compression_threshold = (compression_threshold || DEFAULT_COMPRESION_THRESHOLD_BYTES).to_i
+ @compression_threshold = (compression_threshold || DEFAULT_COMPRESSION_THRESHOLD_BYTES).to_i
if @compression_threshold <= 0
::Sidekiq.logger.warn "Invalid Sidekiq size limiter compression threshold: #{@compression_threshold}"
- @compression_threshold = DEFAULT_COMPRESION_THRESHOLD_BYTES
+ @compression_threshold = DEFAULT_COMPRESSION_THRESHOLD_BYTES
end
end
@@ -83,6 +100,7 @@ module Gitlab
@size_limit = (size_limit || DEFAULT_SIZE_LIMIT).to_i
if @size_limit < 0
::Sidekiq.logger.warn "Invalid Sidekiq size limiter limit: #{@size_limit}"
+ @size_limit = DEFAULT_SIZE_LIMIT
end
end
diff --git a/lib/gitlab/sidekiq_queue.rb b/lib/gitlab/sidekiq_queue.rb
index eb3a8e3d497..67a9d8120d8 100644
--- a/lib/gitlab/sidekiq_queue.rb
+++ b/lib/gitlab/sidekiq_queue.rb
@@ -7,6 +7,9 @@ module Gitlab
NoMetadataError = Class.new(StandardError)
InvalidQueueError = Class.new(StandardError)
+ WORKER_KEY = 'worker_class'
+ ALLOWED_KEYS = Gitlab::ApplicationContext::KNOWN_KEYS + [WORKER_KEY]
+
attr_reader :queue_name
def initialize(queue_name)
@@ -21,8 +24,8 @@ module Gitlab
job_search_metadata =
search_metadata
.stringify_keys
- .slice(*Gitlab::ApplicationContext::KNOWN_KEYS)
- .transform_keys { |key| "meta.#{key}" }
+ .slice(*ALLOWED_KEYS)
+ .transform_keys(&method(:transform_key))
.compact
raise NoMetadataError if job_search_metadata.empty?
@@ -49,6 +52,14 @@ module Gitlab
private
+ def transform_key(key)
+ if Gitlab::ApplicationContext::KNOWN_KEYS.include?(key)
+ "meta.#{key}"
+ elsif key == WORKER_KEY
+ 'class'
+ end
+ end
+
def queue
strong_memoize(:queue) do
# Sidekiq::Queue.new always returns a queue, even if it doesn't
diff --git a/lib/gitlab/signed_tag.rb b/lib/gitlab/signed_tag.rb
index 3b22cb7622d..49194300a39 100644
--- a/lib/gitlab/signed_tag.rb
+++ b/lib/gitlab/signed_tag.rb
@@ -7,12 +7,7 @@ module Gitlab
def initialize(repository, tag)
@repository = repository
@tag = tag
-
- if Feature.enabled?(:get_tag_signatures)
- @signature_data = Gitlab::Git::Tag.extract_signature_lazily(repository, tag.id) if repository
- else
- @signature_data = [signature_text_of_message.b, signed_text_of_message.b]
- end
+ @signature_data = Gitlab::Git::Tag.extract_signature_lazily(repository, tag.id) if repository
end
def signature
@@ -26,22 +21,5 @@ module Gitlab
def signed_text
@signature_data&.fetch(1)
end
-
- private
-
- def signature_text_of_message
- @tag.message.slice(@tag.message.index("-----BEGIN SIGNED MESSAGE-----")..-1)
- rescue StandardError
- nil
- end
-
- def signed_text_of_message
- %{object #{@tag.target_commit.id}
-type commit
-tag #{@tag.name}
-tagger #{@tag.tagger.name} <#{@tag.tagger.email}> #{@tag.tagger.date.seconds} #{@tag.tagger.timezone}
-
-#{@tag.message.gsub(/-----BEGIN SIGNED MESSAGE-----(.*)-----END SIGNED MESSAGE-----/m, "")}}
- end
end
end
diff --git a/lib/gitlab/slash_commands/issue_close.rb b/lib/gitlab/slash_commands/issue_close.rb
index 3dad7216983..5d33f2fe62d 100644
--- a/lib/gitlab/slash_commands/issue_close.rb
+++ b/lib/gitlab/slash_commands/issue_close.rb
@@ -29,7 +29,7 @@ module Gitlab
private
def close_issue(issue:)
- Issues::CloseService.new(project: project, current_user: current_user).execute(issue)
+ ::Issues::CloseService.new(project: project, current_user: current_user).execute(issue)
end
def presenter(issue)
diff --git a/lib/gitlab/slash_commands/issue_move.rb b/lib/gitlab/slash_commands/issue_move.rb
index 0612663017c..9f10da247d7 100644
--- a/lib/gitlab/slash_commands/issue_move.rb
+++ b/lib/gitlab/slash_commands/issue_move.rb
@@ -29,11 +29,11 @@ module Gitlab
return Gitlab::SlashCommands::Presenters::Access.new.not_found
end
- new_issue = Issues::MoveService.new(project: project, current_user: current_user)
+ new_issue = ::Issues::MoveService.new(project: project, current_user: current_user)
.execute(old_issue, target_project)
presenter(new_issue).present(old_issue)
- rescue Issues::MoveService::MoveError => e
+ rescue ::Issues::MoveService::MoveError => e
presenter(old_issue).display_move_error(e.message)
end
diff --git a/lib/gitlab/slash_commands/issue_new.rb b/lib/gitlab/slash_commands/issue_new.rb
index fab016d2e1b..ef368767689 100644
--- a/lib/gitlab/slash_commands/issue_new.rb
+++ b/lib/gitlab/slash_commands/issue_new.rb
@@ -33,7 +33,7 @@ module Gitlab
private
def create_issue(title:, description:)
- Issues::CreateService.new(project: project, current_user: current_user, params: { title: title, description: description }, spam_params: nil).execute
+ ::Issues::CreateService.new(project: project, current_user: current_user, params: { title: title, description: description }, spam_params: nil).execute
end
def presenter(issue)
diff --git a/lib/gitlab/subscription_portal.rb b/lib/gitlab/subscription_portal.rb
index ab2e1404cd2..78fa5009bc4 100644
--- a/lib/gitlab/subscription_portal.rb
+++ b/lib/gitlab/subscription_portal.rb
@@ -13,6 +13,38 @@ module Gitlab
def self.payment_form_url
"#{self.subscriptions_url}/payment_forms/cc_validation"
end
+
+ def self.subscriptions_comparison_url
+ 'https://about.gitlab.com/pricing/gitlab-com/feature-comparison'
+ end
+
+ def self.subscriptions_graphql_url
+ "#{self.subscriptions_url}/graphql"
+ end
+
+ def self.subscriptions_more_minutes_url
+ "#{self.subscriptions_url}/buy_pipeline_minutes"
+ end
+
+ def self.subscriptions_more_storage_url
+ "#{self.subscriptions_url}/buy_storage"
+ end
+
+ def self.subscriptions_manage_url
+ "#{self.subscriptions_url}/subscriptions"
+ end
+
+ def self.subscriptions_plans_url
+ "#{self.subscriptions_url}/plans"
+ end
+
+ def self.subscription_portal_admin_email
+ ENV.fetch('SUBSCRIPTION_PORTAL_ADMIN_EMAIL', 'gl_com_api@gitlab.com')
+ end
+
+ def self.subscription_portal_admin_token
+ ENV.fetch('SUBSCRIPTION_PORTAL_ADMIN_TOKEN', 'customer_admin_token')
+ end
end
end
diff --git a/lib/gitlab/template/gitlab_ci_yml_template.rb b/lib/gitlab/template/gitlab_ci_yml_template.rb
index da925f0f83a..263483ba54b 100644
--- a/lib/gitlab/template/gitlab_ci_yml_template.rb
+++ b/lib/gitlab/template/gitlab_ci_yml_template.rb
@@ -7,6 +7,7 @@ module Gitlab
TEMPLATES_WITH_LATEST_VERSION = {
'Jobs/Browser-Performance-Testing' => true,
+ 'Jobs/Build' => true,
'Security/API-Fuzzing' => true,
'Security/DAST' => true,
'Terraform' => true
diff --git a/lib/gitlab/throttle.rb b/lib/gitlab/throttle.rb
index 8f045021088..622dc7d9ed0 100644
--- a/lib/gitlab/throttle.rb
+++ b/lib/gitlab/throttle.rb
@@ -4,6 +4,11 @@ module Gitlab
class Throttle
DEFAULT_RATE_LIMITING_RESPONSE_TEXT = 'Retry later'
+ # Each of these settings follows the same pattern of specifying separate
+ # authenticated and unauthenticated rates via settings. New throttles should
+ # ideally be regular as well.
+ REGULAR_THROTTLES = [:api, :packages_api, :files_api].freeze
+
def self.settings
Gitlab::CurrentSettings.current_application_settings
end
@@ -24,21 +29,38 @@ module Gitlab
"HTTP_#{env_value.upcase.tr('-', '_')}"
end
- def self.unauthenticated_options
+ class << self
+ def options(throttle, authenticated:)
+ fragment = throttle_fragment!(throttle, authenticated: authenticated)
+
+ # rubocop:disable GitlabSecurity/PublicSend
+ limit_proc = proc { |req| settings.public_send("#{fragment}_requests_per_period") }
+ period_proc = proc { |req| settings.public_send("#{fragment}_period_in_seconds").seconds }
+ # rubocop:enable GitlabSecurity/PublicSend
+
+ { limit: limit_proc, period: period_proc }
+ end
+
+ def throttle_fragment!(throttle, authenticated:)
+ raise("Unknown throttle: #{throttle}") unless REGULAR_THROTTLES.include?(throttle)
+
+ "throttle_#{'un' unless authenticated}authenticated_#{throttle}"
+ end
+ end
+
+ def self.unauthenticated_web_options
+ # TODO: Columns will be renamed in https://gitlab.com/gitlab-org/gitlab/-/issues/340031
+ # Once this is done, web can be made into a regular throttle
limit_proc = proc { |req| settings.throttle_unauthenticated_requests_per_period }
period_proc = proc { |req| settings.throttle_unauthenticated_period_in_seconds.seconds }
- { limit: limit_proc, period: period_proc }
- end
- def self.authenticated_api_options
- limit_proc = proc { |req| settings.throttle_authenticated_api_requests_per_period }
- period_proc = proc { |req| settings.throttle_authenticated_api_period_in_seconds.seconds }
{ limit: limit_proc, period: period_proc }
end
def self.authenticated_web_options
limit_proc = proc { |req| settings.throttle_authenticated_web_requests_per_period }
period_proc = proc { |req| settings.throttle_authenticated_web_period_in_seconds.seconds }
+
{ limit: limit_proc, period: period_proc }
end
@@ -49,16 +71,9 @@ module Gitlab
{ limit: limit_proc, period: period_proc }
end
- def self.unauthenticated_packages_api_options
- limit_proc = proc { |req| settings.throttle_unauthenticated_packages_api_requests_per_period }
- period_proc = proc { |req| settings.throttle_unauthenticated_packages_api_period_in_seconds.seconds }
-
- { limit: limit_proc, period: period_proc }
- end
-
- def self.authenticated_packages_api_options
- limit_proc = proc { |req| settings.throttle_authenticated_packages_api_requests_per_period }
- period_proc = proc { |req| settings.throttle_authenticated_packages_api_period_in_seconds.seconds }
+ def self.throttle_authenticated_git_lfs_options
+ limit_proc = proc { |req| settings.throttle_authenticated_git_lfs_requests_per_period }
+ period_proc = proc { |req| settings.throttle_authenticated_git_lfs_period_in_seconds.seconds }
{ limit: limit_proc, period: period_proc }
end
diff --git a/lib/gitlab/timeless.rb b/lib/gitlab/timeless.rb
index 4f974c98c71..b72d33113dd 100644
--- a/lib/gitlab/timeless.rb
+++ b/lib/gitlab/timeless.rb
@@ -6,7 +6,8 @@ module Gitlab
original_record_timestamps = model.record_timestamps
model.record_timestamps = false
- if block.arity.abs == 1
+ # negative arity means arguments are optional
+ if block.arity == 1 || block.arity < 0
block.call(model)
else
block.call
diff --git a/lib/gitlab/tracking.rb b/lib/gitlab/tracking.rb
index 5fb360296b7..f4fbea50515 100644
--- a/lib/gitlab/tracking.rb
+++ b/lib/gitlab/tracking.rb
@@ -18,7 +18,7 @@ module Gitlab
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(error, snowplow_category: category, snowplow_action: action)
end
- def snowplow_options(group)
+ def options(group)
additional_features = Feature.enabled?(:additional_snowplow_tracking, group)
{
namespace: SNOWPLOW_NAMESPACE,
diff --git a/lib/gitlab/tracking/standard_context.rb b/lib/gitlab/tracking/standard_context.rb
index 7902f96dfa6..fe5669be014 100644
--- a/lib/gitlab/tracking/standard_context.rb
+++ b/lib/gitlab/tracking/standard_context.rb
@@ -8,7 +8,8 @@ module Gitlab
def initialize(namespace: nil, project: nil, user: nil, **extra)
@namespace = namespace
- @plan = @namespace&.actual_plan_name
+ @plan = namespace&.actual_plan_name
+ @project = project
@extra = extra
end
@@ -34,14 +35,29 @@ module Gitlab
private
+ attr_accessor :namespace, :project, :extra, :plan
+
def to_h
{
environment: environment,
source: source,
- plan: @plan,
- extra: @extra
+ plan: plan,
+ extra: extra
+ }.merge(project_and_namespace)
+ end
+
+ def project_and_namespace
+ return {} unless ::Feature.enabled?(:add_namespace_and_project_to_snowplow_tracking, default_enabled: :yaml)
+
+ {
+ namespace_id: namespace&.id,
+ project_id: project_id
}
end
+
+ def project_id
+ project.is_a?(Integer) ? project : project&.id
+ end
end
end
end
diff --git a/lib/gitlab/url_builder.rb b/lib/gitlab/url_builder.rb
index a242f718b16..c00a0e1bcb4 100644
--- a/lib/gitlab/url_builder.rb
+++ b/lib/gitlab/url_builder.rb
@@ -24,6 +24,8 @@ module Gitlab
instance.project_job_url(object.project, object, **options)
when Commit
commit_url(object, **options)
+ when Compare
+ compare_url(object, **options)
when Group
instance.group_canonical_url(object, **options)
when Issue
@@ -68,6 +70,12 @@ module Gitlab
instance.commit_url(commit, **options)
end
+ def compare_url(compare, **options)
+ return '' unless compare.project
+
+ instance.project_compare_url(compare.project, **options.merge(compare.to_param))
+ end
+
def note_url(note, **options)
if note.for_commit?
return '' unless note.project
diff --git a/lib/gitlab/usage/metrics/instrumentations/service_ping_features_metric.rb b/lib/gitlab/usage/metrics/instrumentations/service_ping_features_metric.rb
new file mode 100644
index 00000000000..dcf528c8136
--- /dev/null
+++ b/lib/gitlab/usage/metrics/instrumentations/service_ping_features_metric.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Usage
+ module Metrics
+ module Instrumentations
+ class ServicePingFeaturesMetric < GenericMetric
+ value do
+ Gitlab::CurrentSettings.usage_ping_features_enabled
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb
index 910c8397f20..854242031be 100644
--- a/lib/gitlab/usage_data.rb
+++ b/lib/gitlab/usage_data.rb
@@ -259,7 +259,8 @@ module Gitlab
smtp_encrypted_secrets_enabled: alt_usage_data(fallback: nil) { Gitlab::Email::SmtpConfig.encrypted_secrets.active? },
operating_system: alt_usage_data(fallback: nil) { operating_system },
gitaly_apdex: alt_usage_data { gitaly_apdex },
- collected_data_categories: add_metric('CollectedDataCategoriesMetric', time_frame: 'none')
+ collected_data_categories: add_metric('CollectedDataCategoriesMetric', time_frame: 'none'),
+ service_ping_features_enabled: add_metric('ServicePingFeaturesMetric', time_frame: 'none')
}
}
end
@@ -918,7 +919,7 @@ module Gitlab
jira: count(::JiraImportState.where(time_period)), # rubocop: disable CodeReuse/ActiveRecord
fogbugz: projects_imported_count('fogbugz', time_period),
phabricator: projects_imported_count('phabricator', time_period),
- csv: count(Issues::CsvImport.where(time_period)) # rubocop: disable CodeReuse/ActiveRecord
+ csv: count(::Issues::CsvImport.where(time_period)) # rubocop: disable CodeReuse/ActiveRecord
}
end
@@ -934,7 +935,7 @@ module Gitlab
project_imports = distinct_count(::Project.where(time_period).where.not(import_type: nil), :creator_id)
bulk_imports = distinct_count(::BulkImport.where(time_period), :user_id)
jira_issue_imports = distinct_count(::JiraImportState.where(time_period), :user_id)
- csv_issue_imports = distinct_count(Issues::CsvImport.where(time_period), :user_id)
+ csv_issue_imports = distinct_count(::Issues::CsvImport.where(time_period), :user_id)
group_imports = distinct_count(::GroupImportState.where(time_period), :user_id)
add(project_imports, bulk_imports, jira_issue_imports, csv_issue_imports, group_imports)
diff --git a/lib/gitlab/usage_data_counters/ci_template_unique_counter.rb b/lib/gitlab/usage_data_counters/ci_template_unique_counter.rb
index c9106d7c6b8..e5a50c92329 100644
--- a/lib/gitlab/usage_data_counters/ci_template_unique_counter.rb
+++ b/lib/gitlab/usage_data_counters/ci_template_unique_counter.rb
@@ -3,6 +3,7 @@
module Gitlab::UsageDataCounters
class CiTemplateUniqueCounter
REDIS_SLOT = 'ci_templates'
+ KNOWN_EVENTS_FILE_PATH = File.expand_path('known_events/ci_templates.yml', __dir__)
# NOTE: Events originating from implicit Auto DevOps pipelines get prefixed with `implicit_`
TEMPLATE_TO_EVENT = {
@@ -20,19 +21,24 @@ module Gitlab::UsageDataCounters
class << self
def track_unique_project_event(project_id:, template:, config_source:)
- if event = unique_project_event(template, config_source)
- Gitlab::UsageDataCounters::HLLRedisCounter.track_event(event, values: project_id)
- end
+ Gitlab::UsageDataCounters::HLLRedisCounter.track_event(ci_template_event_name(template, config_source), values: project_id)
end
- private
+ def ci_templates(relative_base = 'lib/gitlab/ci/templates')
+ Dir.glob('**/*.gitlab-ci.yml', base: Rails.root.join(relative_base))
+ end
+
+ def ci_template_event_name(template_name, config_source)
+ prefix = 'implicit_' if config_source.to_s == 'auto_devops_source'
+ template_event_name = TEMPLATE_TO_EVENT[template_name] || template_to_event_name(template_name)
- def unique_project_event(template, config_source)
- if name = TEMPLATE_TO_EVENT[template]
- prefix = 'implicit_' if config_source.to_s == 'auto_devops_source'
+ "p_#{REDIS_SLOT}_#{prefix}#{template_event_name}"
+ end
+
+ private
- "p_#{REDIS_SLOT}_#{prefix}#{name}"
- end
+ def template_to_event_name(template)
+ ActiveSupport::Inflector.parameterize(template.chomp('.gitlab-ci.yml'), separator: '_').underscore
end
end
end
diff --git a/lib/gitlab/usage_data_counters/hll_redis_counter.rb b/lib/gitlab/usage_data_counters/hll_redis_counter.rb
index 96562a44391..8fc8bb5d344 100644
--- a/lib/gitlab/usage_data_counters/hll_redis_counter.rb
+++ b/lib/gitlab/usage_data_counters/hll_redis_counter.rb
@@ -18,6 +18,24 @@ module Gitlab
KNOWN_EVENTS_PATH = File.expand_path('known_events/*.yml', __dir__)
ALLOWED_AGGREGATIONS = %i(daily weekly).freeze
+ CATEGORIES_FOR_TOTALS = %w[
+ analytics
+ code_review
+ compliance
+ deploy_token_packages
+ ecosystem
+ epic_boards_usage
+ epics_usage
+ ide_edit
+ incident_management
+ issues_edit
+ pipeline_authoring
+ quickactions
+ search
+ testing
+ user_packages
+ ].freeze
+
# Track event on entity_id
# Increment a Redis HLL counter for unique event_name and entity_id
#
@@ -90,7 +108,7 @@ module Gitlab
hash["#{event}_monthly"] = unique_events(**monthly_time_range.merge(event_names: [event]))
end
- if eligible_for_totals?(events_names)
+ if eligible_for_totals?(events_names) && CATEGORIES_FOR_TOTALS.include?(category)
event_results["#{category}_total_unique_counts_weekly"] = unique_events(**weekly_time_range.merge(event_names: events_names))
event_results["#{category}_total_unique_counts_monthly"] = unique_events(**monthly_time_range.merge(event_names: events_names))
end
diff --git a/lib/gitlab/usage_data_counters/known_events/analytics.yml b/lib/gitlab/usage_data_counters/known_events/analytics.yml
index e4f20b61901..261bdeb9bfa 100644
--- a/lib/gitlab/usage_data_counters/known_events/analytics.yml
+++ b/lib/gitlab/usage_data_counters/known_events/analytics.yml
@@ -2,84 +2,67 @@
category: analytics
redis_slot: analytics
aggregation: weekly
- feature_flag: track_unique_visits
- name: i_analytics_dev_ops_adoption
category: analytics
redis_slot: analytics
aggregation: weekly
- feature_flag: track_unique_visits
- name: i_analytics_dev_ops_score
category: analytics
redis_slot: analytics
aggregation: weekly
- feature_flag: track_unique_visits
- name: p_analytics_merge_request
category: analytics
redis_slot: analytics
aggregation: weekly
- feature_flag: track_unique_visits
- name: i_analytics_instance_statistics
category: analytics
redis_slot: analytics
aggregation: weekly
- feature_flag: track_unique_visits
- name: g_analytics_contribution
category: analytics
redis_slot: analytics
aggregation: weekly
- feature_flag: track_unique_visits
- name: g_analytics_insights
category: analytics
redis_slot: analytics
aggregation: weekly
- feature_flag: track_unique_visits
- name: g_analytics_issues
category: analytics
redis_slot: analytics
aggregation: weekly
- feature_flag: track_unique_visits
- name: g_analytics_productivity
category: analytics
redis_slot: analytics
aggregation: weekly
- feature_flag: track_unique_visits
- name: g_analytics_valuestream
category: analytics
redis_slot: analytics
aggregation: weekly
- feature_flag: track_unique_visits
- name: p_analytics_pipelines
category: analytics
redis_slot: analytics
aggregation: weekly
- feature_flag: track_unique_visits
- name: p_analytics_code_reviews
category: analytics
redis_slot: analytics
aggregation: weekly
- feature_flag: track_unique_visits
- name: p_analytics_valuestream
category: analytics
redis_slot: analytics
aggregation: weekly
- feature_flag: track_unique_visits
- name: p_analytics_insights
category: analytics
redis_slot: analytics
aggregation: weekly
- feature_flag: track_unique_visits
- name: p_analytics_issues
category: analytics
redis_slot: analytics
aggregation: weekly
- feature_flag: track_unique_visits
- name: p_analytics_repo
category: analytics
redis_slot: analytics
aggregation: weekly
- feature_flag: track_unique_visits
- name: i_analytics_cohorts
category: analytics
redis_slot: analytics
aggregation: weekly
- feature_flag: track_unique_visits
diff --git a/lib/gitlab/usage_data_counters/known_events/ci_templates.yml b/lib/gitlab/usage_data_counters/known_events/ci_templates.yml
index 3c692f2b1af..cf790767f17 100644
--- a/lib/gitlab/usage_data_counters/known_events/ci_templates.yml
+++ b/lib/gitlab/usage_data_counters/known_events/ci_templates.yml
@@ -4,73 +4,590 @@
redis_slot: ci_templates
aggregation: weekly
-- name: p_ci_templates_implicit_auto_devops_build
+# Explicit include:template pipeline events
+- name: p_ci_templates_5_min_production_app
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
-- name: p_ci_templates_implicit_auto_devops_deploy
+- name: p_ci_templates_aws_cf_deploy_ec2
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
-- name: p_ci_templates_implicit_security_sast
+- name: p_ci_templates_auto_devops_build
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
-- name: p_ci_templates_implicit_security_secret_detection
+- name: p_ci_templates_auto_devops_deploy
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
-# Explicit include:template pipeline events
-- name: p_ci_templates_5_min_production_app
+- name: p_ci_templates_auto_devops_deploy_latest
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
+# This part of the file is generated automatically by
+# bin/rake gitlab:usage_data:generate_ci_template_events
+#
+# Do not edit it manually!
+#
+# The section above this should be removed once we roll out tracking all ci
+# templates
+# https://gitlab.com/gitlab-org/gitlab/-/issues/339684
+
+- name: p_ci_templates_terraform_base_latest
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_terraform_base
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_dotnet
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_nodejs
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_openshift
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
- name: p_ci_templates_auto_devops
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
-
-- name: p_ci_templates_aws_cf_deploy_ec2
+- name: p_ci_templates_bash
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
-
-- name: p_ci_templates_aws_deploy_ecs
+- name: p_ci_templates_rust
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
-
-- name: p_ci_templates_auto_devops_build
+- name: p_ci_templates_elixir
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
-
-- name: p_ci_templates_auto_devops_deploy
+- name: p_ci_templates_clojure
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
-
-- name: p_ci_templates_auto_devops_deploy_latest
+- name: p_ci_templates_crystal
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_getting_started
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_code_quality
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_verify_load_performance_testing
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_verify_accessibility
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_verify_failfast
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_verify_browser_performance
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_verify_browser_performance_latest
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_grails
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
-
- name: p_ci_templates_security_sast
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
-
+- name: p_ci_templates_security_dast_runner_validation
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_security_dast_on_demand_scan
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
- name: p_ci_templates_security_secret_detection
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
-
-- name: p_ci_templates_terraform_base_latest
+- name: p_ci_templates_security_license_scanning
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_security_coverage_fuzzing
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_security_api_fuzzing_latest
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_security_secure_binaries
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_security_dast_api
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_security_container_scanning
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_security_dast_latest
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_security_dependency_scanning
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_security_api_fuzzing
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_security_dast
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_security_cluster_image_scanning
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_ios_fastlane
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_composer
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_c
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_python
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_android_fastlane
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_android_latest
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_django
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_maven
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_flutter
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_workflows_branch_pipelines
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_workflows_mergerequest_pipelines
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_laravel
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_managed_cluster_applications
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_php
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_packer
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_terraform
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_mono
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_serverless
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_go
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_scala
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_latex
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_android
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_indeni_cloudrail
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_deploy_ecs
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_aws_cf_provision_and_deploy_ec2
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_aws_deploy_ecs
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_gradle
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_chef
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_jobs_dast_default_branch_deploy
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_jobs_load_performance_testing
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_jobs_helm_2to3
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_jobs_sast
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_jobs_secret_detection
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_jobs_code_intelligence
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_jobs_code_quality
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_jobs_deploy_ecs
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_jobs_deploy_ec2
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_jobs_deploy
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_jobs_build
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_jobs_browser_performance_testing
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_jobs_test
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_jobs_deploy_latest
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_jobs_browser_performance_testing_latest
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_jobs_cf_provision
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_jobs_build_latest
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_terraform_latest
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_swift
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_pages_jekyll
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_pages_harp
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_pages_octopress
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_pages_brunch
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_pages_doxygen
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_pages_hyde
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_pages_lektor
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_pages_jbake
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_pages_hexo
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_pages_middleman
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_pages_hugo
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_pages_pelican
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_pages_nanoc
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_pages_swaggerui
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_pages_jigsaw
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_pages_metalsmith
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_pages_gatsby
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_pages_html
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_dart
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_docker
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_julia
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_npm
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_dotnet_core
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_5_minute_production_app
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_ruby
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_jobs_dast_default_branch_deploy
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_jobs_load_performance_testing
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_jobs_helm_2to3
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_jobs_sast
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_jobs_secret_detection
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_jobs_code_intelligence
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_jobs_code_quality
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_jobs_deploy_ecs
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_jobs_deploy_ec2
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_auto_devops_deploy
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_auto_devops_build
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_jobs_browser_performance_testing
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_jobs_test
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_auto_devops_deploy_latest
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_jobs_browser_performance_testing_latest
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_jobs_cf_provision
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_jobs_build_latest
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_security_sast
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_security_dast_runner_validation
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_security_dast_on_demand_scan
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_security_secret_detection
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_security_license_scanning
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_security_coverage_fuzzing
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_security_api_fuzzing_latest
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_security_secure_binaries
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_security_dast_api
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_security_container_scanning
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_security_dast_latest
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_security_dependency_scanning
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_security_api_fuzzing
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_security_dast
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
+- name: p_ci_templates_implicit_security_cluster_image_scanning
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
diff --git a/lib/gitlab/usage_data_counters/known_events/code_review_events.yml b/lib/gitlab/usage_data_counters/known_events/code_review_events.yml
index 7ad51bfe832..d4a818f8fe0 100644
--- a/lib/gitlab/usage_data_counters/known_events/code_review_events.yml
+++ b/lib/gitlab/usage_data_counters/known_events/code_review_events.yml
@@ -237,3 +237,15 @@
category: code_review
aggregation: weekly
feature_flag: diff_searching_usage_data
+- name: i_code_review_total_suggestions_applied
+ redis_slot: code_review
+ category: code_review
+ aggregation: weekly
+- name: i_code_review_total_suggestions_added
+ redis_slot: code_review
+ category: code_review
+ aggregation: weekly
+- name: i_code_review_user_resolve_thread_in_issue
+ redis_slot: code_review
+ category: code_review
+ aggregation: weekly
diff --git a/lib/gitlab/usage_data_counters/known_events/common.yml b/lib/gitlab/usage_data_counters/known_events/common.yml
index 3db0482d38e..261d3b37783 100644
--- a/lib/gitlab/usage_data_counters/known_events/common.yml
+++ b/lib/gitlab/usage_data_counters/known_events/common.yml
@@ -4,27 +4,22 @@
redis_slot: compliance
category: compliance
aggregation: weekly
- feature_flag: track_unique_visits
- name: g_compliance_audit_events
category: compliance
redis_slot: compliance
aggregation: weekly
- feature_flag: track_unique_visits
- name: i_compliance_audit_events
category: compliance
redis_slot: compliance
aggregation: weekly
- feature_flag: track_unique_visits
- name: i_compliance_credential_inventory
category: compliance
redis_slot: compliance
aggregation: weekly
- feature_flag: track_unique_visits
- name: a_compliance_audit_events_api
category: compliance
redis_slot: compliance
aggregation: weekly
- feature_flag: track_unique_visits
- name: g_edit_by_web_ide
category: ide_edit
redis_slot: edit
@@ -67,7 +62,6 @@
- name: design_action
category: source_code
aggregation: daily
- feature_flag: usage_data_design_action
- name: project_action
category: source_code
aggregation: daily
@@ -160,7 +154,6 @@
category: testing
redis_slot: testing
aggregation: weekly
- feature_flag: usage_data_i_testing_metrics_report_widget_total
- name: i_testing_group_code_coverage_visit_total
category: testing
redis_slot: testing
@@ -174,7 +167,6 @@
category: testing
redis_slot: testing
aggregation: weekly
- feature_flag: usage_data_i_testing_web_performance_widget_total
- name: i_testing_group_code_coverage_project_click_total
category: testing
redis_slot: testing
@@ -183,7 +175,6 @@
category: testing
redis_slot: testing
aggregation: weekly
- feature_flag: usage_data_i_testing_load_performance_widget_total
- name: i_testing_metrics_report_artifact_uploaders
category: testing
redis_slot: testing
diff --git a/lib/gitlab/usage_data_counters/known_events/quickactions.yml b/lib/gitlab/usage_data_counters/known_events/quickactions.yml
index 7df351859fb..7f77fa8ee02 100644
--- a/lib/gitlab/usage_data_counters/known_events/quickactions.yml
+++ b/lib/gitlab/usage_data_counters/known_events/quickactions.yml
@@ -3,6 +3,10 @@
category: quickactions
redis_slot: quickactions
aggregation: weekly
+- name: i_quickactions_unapprove
+ category: quickactions
+ redis_slot: quickactions
+ aggregation: weekly
- name: i_quickactions_assign_single
category: quickactions
redis_slot: quickactions
diff --git a/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter.rb b/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter.rb
index 0d6f4b93aee..0fadd68aeab 100644
--- a/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter.rb
+++ b/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter.rb
@@ -20,8 +20,10 @@ module Gitlab
MR_CREATE_MULTILINE_COMMENT_ACTION = 'i_code_review_user_create_multiline_mr_comment'
MR_EDIT_MULTILINE_COMMENT_ACTION = 'i_code_review_user_edit_multiline_mr_comment'
MR_REMOVE_MULTILINE_COMMENT_ACTION = 'i_code_review_user_remove_multiline_mr_comment'
- MR_ADD_SUGGESTION_ACTION = 'i_code_review_user_add_suggestion'
- MR_APPLY_SUGGESTION_ACTION = 'i_code_review_user_apply_suggestion'
+ MR_USER_ADD_SUGGESTION_ACTION = 'i_code_review_user_add_suggestion'
+ MR_TOTAL_ADD_SUGGESTION_ACTION = 'i_code_review_total_suggestions_added'
+ MR_USER_APPLY_SUGGESTION_ACTION = 'i_code_review_user_apply_suggestion'
+ MR_TOTAL_APPLY_SUGGESTION_ACTION = 'i_code_review_total_suggestions_applied'
MR_MARKED_AS_DRAFT_ACTION = 'i_code_review_user_marked_as_draft'
MR_UNMARKED_AS_DRAFT_ACTION = 'i_code_review_user_unmarked_as_draft'
MR_RESOLVE_THREAD_ACTION = 'i_code_review_user_resolve_thread'
@@ -46,6 +48,7 @@ module Gitlab
MR_LABELS_CHANGED_ACTION = 'i_code_review_user_labels_changed'
MR_LOAD_CONFLICT_UI_ACTION = 'i_code_review_user_load_conflict_ui'
MR_RESOLVE_CONFLICT_ACTION = 'i_code_review_user_resolve_conflict'
+ MR_RESOLVE_THREAD_IN_ISSUE_ACTION = 'i_code_review_user_resolve_thread_in_issue'
class << self
def track_mr_diffs_action(merge_request:)
@@ -112,8 +115,9 @@ module Gitlab
track_unique_action_by_user(MR_PUBLISH_REVIEW_ACTION, user)
end
- def track_add_suggestion_action(user:)
- track_unique_action_by_user(MR_ADD_SUGGESTION_ACTION, user)
+ def track_add_suggestion_action(note:)
+ track_unique_action_by_user(MR_USER_ADD_SUGGESTION_ACTION, note.author)
+ track_unique_action_by_objects(MR_TOTAL_ADD_SUGGESTION_ACTION, note.suggestions)
end
def track_marked_as_draft_action(user:)
@@ -124,16 +128,17 @@ module Gitlab
track_unique_action_by_user(MR_UNMARKED_AS_DRAFT_ACTION, user)
end
- def track_apply_suggestion_action(user:)
- track_unique_action_by_user(MR_APPLY_SUGGESTION_ACTION, user)
+ def track_apply_suggestion_action(user:, suggestions:)
+ track_unique_action_by_user(MR_USER_APPLY_SUGGESTION_ACTION, user)
+ track_unique_action_by_objects(MR_TOTAL_APPLY_SUGGESTION_ACTION, suggestions)
end
def track_users_assigned_to_mr(users:)
- track_unique_action_by_users(MR_ASSIGNED_USERS_ACTION, users)
+ track_unique_action_by_objects(MR_ASSIGNED_USERS_ACTION, users)
end
def track_users_review_requested(users:)
- track_unique_action_by_users(MR_REVIEW_REQUESTED_USERS_ACTION, users)
+ track_unique_action_by_objects(MR_REVIEW_REQUESTED_USERS_ACTION, users)
end
def track_title_edit_action(user:)
@@ -210,6 +215,10 @@ module Gitlab
track_unique_action_by_user(MR_RESOLVE_CONFLICT_ACTION, user)
end
+ def track_resolve_thread_in_issue_action(user:)
+ track_unique_action_by_user(MR_RESOLVE_THREAD_IN_ISSUE_ACTION, user)
+ end
+
private
def track_unique_action_by_merge_request(action, merge_request)
@@ -222,10 +231,10 @@ module Gitlab
track_unique_action(action, user.id)
end
- def track_unique_action_by_users(action, users)
- return if users.blank?
+ def track_unique_action_by_objects(action, objects)
+ return if objects.blank?
- track_unique_action(action, users.map(&:id))
+ track_unique_action(action, objects.map(&:id))
end
def track_unique_action(action, value)
diff --git a/lib/gitlab/zentao/client.rb b/lib/gitlab/zentao/client.rb
new file mode 100644
index 00000000000..bdfa4b3a308
--- /dev/null
+++ b/lib/gitlab/zentao/client.rb
@@ -0,0 +1,73 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Zentao
+ class Client
+ Error = Class.new(StandardError)
+ ConfigError = Class.new(Error)
+
+ attr_reader :integration
+
+ def initialize(integration)
+ raise ConfigError, 'Please check your integration configuration.' unless integration
+
+ @integration = integration
+ end
+
+ def ping
+ response = fetch_product(zentao_product_xid)
+
+ active = response.fetch('deleted') == '0' rescue false
+
+ if active
+ { success: true }
+ else
+ { success: false, message: 'Not Found' }
+ end
+ end
+
+ def fetch_product(product_id)
+ get("products/#{product_id}")
+ end
+
+ def fetch_issues(params = {})
+ get("products/#{zentao_product_xid}/issues",
+ params.reverse_merge(page: 1, limit: 20))
+ end
+
+ def fetch_issue(issue_id)
+ get("issues/#{issue_id}")
+ end
+
+ private
+
+ def get(path, params = {})
+ options = { headers: headers, query: params }
+ response = Gitlab::HTTP.get(url(path), options)
+
+ return {} unless response.success?
+
+ Gitlab::Json.parse(response.body)
+ rescue JSON::ParserError
+ {}
+ end
+
+ def url(path)
+ host = integration.api_url.presence || integration.url
+
+ URI.join(host, '/api.php/v1/', path)
+ end
+
+ def headers
+ {
+ 'Content-Type': 'application/json',
+ 'Token': integration.api_token
+ }
+ end
+
+ def zentao_product_xid
+ integration.zentao_product_xid
+ end
+ end
+ end
+end
diff --git a/lib/object_storage/config.rb b/lib/object_storage/config.rb
index f933d4e4866..82d9fc07043 100644
--- a/lib/object_storage/config.rb
+++ b/lib/object_storage/config.rb
@@ -84,13 +84,16 @@ module ObjectStorage
def fog_attributes
@fog_attributes ||= begin
- return {} unless enabled? && aws?
- return {} unless server_side_encryption.present?
+ return {} unless aws_server_side_encryption_enabled?
aws_server_side_encryption_headers.compact
end
end
+ def aws_server_side_encryption_enabled?
+ aws? && server_side_encryption.present?
+ end
+
private
# This returns a Hash of HTTP encryption headers to send along to S3.
diff --git a/lib/sidebars/concerns/has_pill.rb b/lib/sidebars/concerns/has_pill.rb
index 4bbf69bf16b..0a2e1f12008 100644
--- a/lib/sidebars/concerns/has_pill.rb
+++ b/lib/sidebars/concerns/has_pill.rb
@@ -21,8 +21,8 @@ module Sidebars
{}
end
- def format_cached_count(count_service, count)
- if count > count_service::CACHED_COUNT_THRESHOLD
+ def format_cached_count(threshold, count)
+ if count > threshold
number_to_human(
count,
units: { thousand: 'k', million: 'm' }, precision: 1, significant: false, format: '%n%u'
diff --git a/lib/sidebars/groups/menus/ci_cd_menu.rb b/lib/sidebars/groups/menus/ci_cd_menu.rb
index e870bbf5ebc..f5bce57f496 100644
--- a/lib/sidebars/groups/menus/ci_cd_menu.rb
+++ b/lib/sidebars/groups/menus/ci_cd_menu.rb
@@ -11,11 +11,6 @@ module Sidebars
true
end
- override :link
- def link
- renderable_items.first.link
- end
-
override :title
def title
_('CI/CD')
diff --git a/lib/sidebars/groups/menus/group_information_menu.rb b/lib/sidebars/groups/menus/group_information_menu.rb
index b28cb927ad2..9656811455e 100644
--- a/lib/sidebars/groups/menus/group_information_menu.rb
+++ b/lib/sidebars/groups/menus/group_information_menu.rb
@@ -13,11 +13,6 @@ module Sidebars
true
end
- override :link
- def link
- renderable_items.first.link
- end
-
override :title
def title
context.group.subgroup? ? _('Subgroup information') : _('Group information')
diff --git a/lib/sidebars/groups/menus/issues_menu.rb b/lib/sidebars/groups/menus/issues_menu.rb
index 95641c09076..4044cb1c716 100644
--- a/lib/sidebars/groups/menus/issues_menu.rb
+++ b/lib/sidebars/groups/menus/issues_menu.rb
@@ -17,11 +17,6 @@ module Sidebars
true
end
- override :link
- def link
- issues_group_path(context.group)
- end
-
override :title
def title
_('Issues')
@@ -43,7 +38,7 @@ module Sidebars
count_service = ::Groups::OpenIssuesCountService
count = count_service.new(context.group, context.current_user).count
- format_cached_count(count_service, count)
+ format_cached_count(count_service::CACHED_COUNT_THRESHOLD, count)
end
end
diff --git a/lib/sidebars/groups/menus/merge_requests_menu.rb b/lib/sidebars/groups/menus/merge_requests_menu.rb
index 7faf50305c6..050cba07641 100644
--- a/lib/sidebars/groups/menus/merge_requests_menu.rb
+++ b/lib/sidebars/groups/menus/merge_requests_menu.rb
@@ -37,7 +37,7 @@ module Sidebars
count_service = ::Groups::MergeRequestsCountService
count = count_service.new(context.group, context.current_user).count
- format_cached_count(count_service, count)
+ format_cached_count(count_service::CACHED_COUNT_THRESHOLD, count)
end
end
diff --git a/lib/sidebars/groups/menus/packages_registries_menu.rb b/lib/sidebars/groups/menus/packages_registries_menu.rb
index e46e2820c04..e81e9355e7e 100644
--- a/lib/sidebars/groups/menus/packages_registries_menu.rb
+++ b/lib/sidebars/groups/menus/packages_registries_menu.rb
@@ -13,11 +13,6 @@ module Sidebars
true
end
- override :link
- def link
- renderable_items.first.link
- end
-
override :title
def title
_('Packages & Registries')
diff --git a/lib/sidebars/groups/menus/settings_menu.rb b/lib/sidebars/groups/menus/settings_menu.rb
index 8bc6077d302..f0239ca6a1a 100644
--- a/lib/sidebars/groups/menus/settings_menu.rb
+++ b/lib/sidebars/groups/menus/settings_menu.rb
@@ -19,11 +19,6 @@ module Sidebars
true
end
- override :link
- def link
- edit_group_path(context.group)
- end
-
override :title
def title
_('Settings')
diff --git a/lib/sidebars/groups/panel.rb b/lib/sidebars/groups/panel.rb
index 73b943c5655..6efe89d496a 100644
--- a/lib/sidebars/groups/panel.rb
+++ b/lib/sidebars/groups/panel.rb
@@ -16,11 +16,6 @@ module Sidebars
add_menu(Sidebars::Groups::Menus::SettingsMenu.new(context))
end
- override :render_raw_menus_partial
- def render_raw_menus_partial
- 'layouts/nav/sidebar/group_menus'
- end
-
override :aria_label
def aria_label
context.group.subgroup? ? _('Subgroup navigation') : _('Group navigation')
diff --git a/lib/sidebars/menu.rb b/lib/sidebars/menu.rb
index 3b8872fd572..1af3d024291 100644
--- a/lib/sidebars/menu.rb
+++ b/lib/sidebars/menu.rb
@@ -33,10 +33,9 @@ module Sidebars
has_renderable_items? || menu_with_partial?
end
- # Menus might have or not a link
override :link
def link
- nil
+ renderable_items.first&.link
end
# This method normalizes the information retrieved from the submenus and this menu
diff --git a/lib/sidebars/projects/menus/analytics_menu.rb b/lib/sidebars/projects/menus/analytics_menu.rb
index 29fd0609596..b13b25d1cfe 100644
--- a/lib/sidebars/projects/menus/analytics_menu.rb
+++ b/lib/sidebars/projects/menus/analytics_menu.rb
@@ -21,7 +21,7 @@ module Sidebars
def link
return cycle_analytics_menu_item.link if cycle_analytics_menu_item.render?
- renderable_items.first.link
+ super
end
override :extra_container_html_options
diff --git a/lib/sidebars/projects/menus/ci_cd_menu.rb b/lib/sidebars/projects/menus/ci_cd_menu.rb
index f85a9faacd3..67e4209c382 100644
--- a/lib/sidebars/projects/menus/ci_cd_menu.rb
+++ b/lib/sidebars/projects/menus/ci_cd_menu.rb
@@ -15,11 +15,6 @@ module Sidebars
add_item(pipeline_schedules_menu_item)
end
- override :link
- def link
- project_pipelines_path(context.project)
- end
-
override :extra_container_html_options
def extra_container_html_options
{
diff --git a/lib/sidebars/projects/menus/deployments_menu.rb b/lib/sidebars/projects/menus/deployments_menu.rb
index fa6482562e8..110d78367b9 100644
--- a/lib/sidebars/projects/menus/deployments_menu.rb
+++ b/lib/sidebars/projects/menus/deployments_menu.rb
@@ -13,11 +13,6 @@ module Sidebars
true
end
- override :link
- def link
- renderable_items.first.link
- end
-
override :extra_container_html_options
def extra_container_html_options
{
diff --git a/lib/sidebars/projects/menus/infrastructure_menu.rb b/lib/sidebars/projects/menus/infrastructure_menu.rb
index aad1ce60d0e..e26bb2237e6 100644
--- a/lib/sidebars/projects/menus/infrastructure_menu.rb
+++ b/lib/sidebars/projects/menus/infrastructure_menu.rb
@@ -15,11 +15,6 @@ module Sidebars
true
end
- override :link
- def link
- renderable_items.first.link
- end
-
override :extra_container_html_options
def extra_container_html_options
{
diff --git a/lib/sidebars/projects/menus/issues_menu.rb b/lib/sidebars/projects/menus/issues_menu.rb
index fd57f21db88..3774bec2f13 100644
--- a/lib/sidebars/projects/menus/issues_menu.rb
+++ b/lib/sidebars/projects/menus/issues_menu.rb
@@ -18,11 +18,6 @@ module Sidebars
true
end
- override :link
- def link
- project_issues_path(context.project)
- end
-
override :extra_container_html_options
def extra_container_html_options
{
diff --git a/lib/sidebars/projects/menus/learn_gitlab_menu.rb b/lib/sidebars/projects/menus/learn_gitlab_menu.rb
index f29f4a6eed6..16335f5b076 100644
--- a/lib/sidebars/projects/menus/learn_gitlab_menu.rb
+++ b/lib/sidebars/projects/menus/learn_gitlab_menu.rb
@@ -23,7 +23,7 @@ module Sidebars
override :has_pill?
def has_pill?
- context.learn_gitlab_experiment_enabled
+ context.learn_gitlab_enabled
end
override :pill_count
@@ -40,8 +40,7 @@ module Sidebars
{
class: 'home',
data: {
- track_label: 'learn_gitlab',
- track_property: context.learn_gitlab_experiment_tracking_category
+ track_label: 'learn_gitlab'
}
}
end
@@ -53,7 +52,7 @@ module Sidebars
override :render?
def render?
- context.learn_gitlab_experiment_enabled
+ context.learn_gitlab_enabled
end
end
end
diff --git a/lib/sidebars/projects/menus/monitor_menu.rb b/lib/sidebars/projects/menus/monitor_menu.rb
index 0d7e0776d5b..59554726263 100644
--- a/lib/sidebars/projects/menus/monitor_menu.rb
+++ b/lib/sidebars/projects/menus/monitor_menu.rb
@@ -19,11 +19,6 @@ module Sidebars
true
end
- override :link
- def link
- renderable_items.first&.link
- end
-
override :extra_container_html_options
def extra_container_html_options
{
diff --git a/lib/sidebars/projects/menus/packages_registries_menu.rb b/lib/sidebars/projects/menus/packages_registries_menu.rb
index d49bb680853..f5f0da2992e 100644
--- a/lib/sidebars/projects/menus/packages_registries_menu.rb
+++ b/lib/sidebars/projects/menus/packages_registries_menu.rb
@@ -13,11 +13,6 @@ module Sidebars
true
end
- override :link
- def link
- renderable_items.first.link
- end
-
override :title
def title
_('Packages & Registries')
diff --git a/lib/sidebars/projects/menus/project_information_menu.rb b/lib/sidebars/projects/menus/project_information_menu.rb
index a5f06ebea20..44b94ee3522 100644
--- a/lib/sidebars/projects/menus/project_information_menu.rb
+++ b/lib/sidebars/projects/menus/project_information_menu.rb
@@ -13,11 +13,6 @@ module Sidebars
true
end
- override :link
- def link
- renderable_items.first.link
- end
-
override :extra_container_html_options
def extra_container_html_options
{ class: 'shortcuts-project-information' }
diff --git a/lib/sidebars/projects/menus/repository_menu.rb b/lib/sidebars/projects/menus/repository_menu.rb
index a784aecc3dc..0a295f0f618 100644
--- a/lib/sidebars/projects/menus/repository_menu.rb
+++ b/lib/sidebars/projects/menus/repository_menu.rb
@@ -20,11 +20,6 @@ module Sidebars
true
end
- override :link
- def link
- project_tree_path(context.project)
- end
-
override :extra_container_html_options
def extra_container_html_options
{
diff --git a/lib/sidebars/projects/menus/security_compliance_menu.rb b/lib/sidebars/projects/menus/security_compliance_menu.rb
index 5616b466560..9367514cdca 100644
--- a/lib/sidebars/projects/menus/security_compliance_menu.rb
+++ b/lib/sidebars/projects/menus/security_compliance_menu.rb
@@ -15,11 +15,6 @@ module Sidebars
true
end
- override :link
- def link
- renderable_items.first&.link
- end
-
override :title
def title
_('Security & Compliance')
diff --git a/lib/sidebars/projects/menus/settings_menu.rb b/lib/sidebars/projects/menus/settings_menu.rb
index 250143df649..6439c97d0bc 100644
--- a/lib/sidebars/projects/menus/settings_menu.rb
+++ b/lib/sidebars/projects/menus/settings_menu.rb
@@ -17,15 +17,11 @@ module Sidebars
add_item(monitor_menu_item)
add_item(pages_menu_item)
add_item(packages_and_registries_menu_item)
+ add_item(usage_quotas_menu_item)
true
end
- override :link
- def link
- edit_project_path(context.project)
- end
-
override :title
def title
_('Settings')
@@ -146,6 +142,19 @@ module Sidebars
item_id: :packages_and_registries
)
end
+
+ def usage_quotas_menu_item
+ unless Feature.enabled?(:project_storage_ui, context.project&.group, default_enabled: :yaml)
+ return ::Sidebars::NilMenuItem.new(item_id: :usage_quotas)
+ end
+
+ ::Sidebars::MenuItem.new(
+ title: s_('UsageQuota|Usage Quotas'),
+ link: project_usage_quotas_path(context.project),
+ active_routes: { path: 'usage_quotas#index' },
+ item_id: :usage_quotas
+ )
+ end
end
end
end
diff --git a/lib/support/logrotate/gitlab b/lib/support/logrotate/gitlab
index c34db47e214..43fa8eb963c 100644
--- a/lib/support/logrotate/gitlab
+++ b/lib/support/logrotate/gitlab
@@ -1,5 +1,4 @@
# GitLab logrotate settings
-# based on: http://stackoverflow.com/a/4883967
/home/git/gitlab/log/*.log {
su git git
diff --git a/lib/system_check/incoming_email_check.rb b/lib/system_check/incoming_email_check.rb
index e0e1147711c..84033ada710 100644
--- a/lib/system_check/incoming_email_check.rb
+++ b/lib/system_check/incoming_email_check.rb
@@ -7,9 +7,11 @@ module SystemCheck
def multi_check
if Gitlab.config.incoming_email.enabled
- checks = [
- SystemCheck::IncomingEmail::ImapAuthenticationCheck
- ]
+ checks = []
+
+ if Gitlab.config.incoming_email.inbox_method == 'imap'
+ checks << SystemCheck::IncomingEmail::ImapAuthenticationCheck
+ end
if Rails.env.production?
checks << SystemCheck::IncomingEmail::InitdConfiguredCheck
diff --git a/lib/tasks/gitlab/db.rake b/lib/tasks/gitlab/db.rake
index 51f15f5a56a..a6738b01f18 100644
--- a/lib/tasks/gitlab/db.rake
+++ b/lib/tasks/gitlab/db.rake
@@ -118,7 +118,7 @@ namespace :gitlab do
desc 'Create missing dynamic database partitions'
task create_dynamic_partitions: :environment do
- Gitlab::Database::Partitioning::PartitionManager.new.sync_partitions
+ Gitlab::Database::Partitioning.sync_partitions
end
# This is targeted towards deploys and upgrades of GitLab.
@@ -151,6 +151,12 @@ namespace :gitlab do
# initializers here as the application can continue to run while
# a rake task reloads the database schema.
Rake::Task['db:test:load'].enhance do
+ # Due to bug in `db:test:load` if many DBs are used
+ # the `ActiveRecord::Base.connection` might be switched to another one
+ # This is due to `if should_reconnect`:
+ # https://github.com/rails/rails/blob/a81aeb63a007ede2fe606c50539417dada9030c7/activerecord/lib/active_record/railties/databases.rake#L622
+ ActiveRecord::Base.establish_connection :main
+
Rake::Task['gitlab:db:create_dynamic_partitions'].invoke
end
diff --git a/lib/tasks/gitlab/docs/compile_deprecations.rake b/lib/tasks/gitlab/docs/compile_deprecations.rake
new file mode 100644
index 00000000000..0fd43775015
--- /dev/null
+++ b/lib/tasks/gitlab/docs/compile_deprecations.rake
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+namespace :gitlab do
+ namespace :docs do
+ desc "Generate deprecation list from individual files"
+ task :compile_deprecations do
+ require_relative '../../../../tooling/deprecations/docs'
+
+ File.write(Deprecations::Docs.path, Deprecations::Docs.render)
+
+ puts "Deprecations compiled to #{Deprecations::Docs.path}"
+ end
+
+ desc "Check that the deprecation doc is up to date"
+ task :check_deprecations do
+ require_relative '../../../../tooling/deprecations/docs'
+
+ contents = Deprecations::Docs.render
+ doc = File.read(Deprecations::Docs.path)
+
+ if doc == contents
+ puts "Deprecations doc is up to date."
+ else
+ format_output('Deprecations doc is outdated! Please update it by running `bundle exec rake gitlab:docs:compile_deprecations`.')
+ abort
+ end
+ end
+ end
+end
diff --git a/lib/tasks/gitlab/gitaly.rake b/lib/tasks/gitlab/gitaly.rake
index 6675439e430..ef58c9339f1 100644
--- a/lib/tasks/gitlab/gitaly.rake
+++ b/lib/tasks/gitlab/gitaly.rake
@@ -15,8 +15,7 @@ namespace :gitlab do
gdk_gitaly_dir = ENV.fetch('GDK_GITALY', Rails.root.join('../gitaly'))
# Our test setup expects a git repo, so clone rather than copy
- version = Gitlab::GitalyClient.expected_server_version
- checkout_or_clone_version(version: version, repo: gdk_gitaly_dir, target_dir: args.dir, clone_opts: %w[--depth 1])
+ clone_repo(gdk_gitaly_dir, args.dir, clone_opts: %w[--depth 1]) unless Dir.exist?(args.dir)
# We assume the GDK gitaly already compiled binaries
build_dir = File.join(gdk_gitaly_dir, '_build')
@@ -31,7 +30,7 @@ namespace :gitlab do
FileUtils.cp_r(ruby_bundle_file, args.dir)
gitaly_binary = File.join(build_dir, 'bin', 'gitaly')
- warn_gitaly_out_of_date!(gitaly_binary, version)
+ warn_gitaly_out_of_date!(gitaly_binary, Gitlab::GitalyClient.expected_server_version)
rescue Errno::ENOENT => e
puts "Could not copy files, did you run `gdk update`? Error: #{e.message}"
diff --git a/lib/tasks/gitlab/graphql.rake b/lib/tasks/gitlab/graphql.rake
index 52c5c680292..b9137aa0d4c 100644
--- a/lib/tasks/gitlab/graphql.rake
+++ b/lib/tasks/gitlab/graphql.rake
@@ -111,7 +111,7 @@ namespace :gitlab do
desc 'GitLab | GraphQL | Generate GraphQL docs'
task compile_docs: [:environment, :enable_feature_flags] do
- renderer = Tooling::Graphql::Docs::Renderer.new(GitlabSchema, render_options)
+ renderer = Tooling::Graphql::Docs::Renderer.new(GitlabSchema, **render_options)
renderer.write
@@ -120,7 +120,7 @@ namespace :gitlab do
desc 'GitLab | GraphQL | Check if GraphQL docs are up to date'
task check_docs: [:environment, :enable_feature_flags] do
- renderer = Tooling::Graphql::Docs::Renderer.new(GitlabSchema, render_options)
+ renderer = Tooling::Graphql::Docs::Renderer.new(GitlabSchema, **render_options)
doc = File.read(Rails.root.join(OUTPUT_DIR, 'index.md'))
diff --git a/lib/tasks/gitlab/product_intelligence.rake b/lib/tasks/gitlab/product_intelligence.rake
deleted file mode 100644
index 329cd9c8c2a..00000000000
--- a/lib/tasks/gitlab/product_intelligence.rake
+++ /dev/null
@@ -1,24 +0,0 @@
-# frozen_string_literal: true
-
-namespace :gitlab do
- namespace :product_intelligence do
- # @example
- # bundle exec rake gitlab:product_intelligence:activate_metrics MILESTONE=14.0
-
- desc 'GitLab | Product Intelligence | Update milestone metrics status to data_available'
- task activate_metrics: :environment do
- milestone = ENV['MILESTONE']
- raise "Please supply the MILESTONE env var".color(:red) unless milestone.present?
-
- Gitlab::Usage::MetricDefinition.definitions.values.each do |metric|
- next if metric.attributes[:milestone] != milestone || metric.attributes[:status] != 'implemented'
-
- metric.attributes[:status] = 'data_available'
- path = metric.path
- File.open(path, "w") { |file| file << metric.to_h.deep_stringify_keys.to_yaml }
- end
-
- puts "Task completed successfully"
- end
- end
-end
diff --git a/lib/tasks/gitlab/sidekiq.rake b/lib/tasks/gitlab/sidekiq.rake
index d3060d92e88..90ed91221ae 100644
--- a/lib/tasks/gitlab/sidekiq.rake
+++ b/lib/tasks/gitlab/sidekiq.rake
@@ -86,9 +86,8 @@ namespace :gitlab do
# 3: high priority
# 5: _super_ high priority, this should only be used for _very_ important queues
#
- # As per http://stackoverflow.com/a/21241357/290102 the formula for calculating
- # the likelihood of a job being popped off a queue (given all queues have work
- # to perform) is:
+ # The formula for calculating the likelihood of a job being popped off a queue
+ # (given all queues have work to perform) is:
#
# chance = (queue weight / total weight of all queues) * 100
BANNER
diff --git a/lib/tasks/gitlab/usage_data.rake b/lib/tasks/gitlab/usage_data.rake
index ddd3424acda..35ddc627389 100644
--- a/lib/tasks/gitlab/usage_data.rake
+++ b/lib/tasks/gitlab/usage_data.rake
@@ -28,5 +28,33 @@ namespace :gitlab do
task generate_from_yaml: :environment do
puts Gitlab::Json.pretty_generate(Gitlab::UsageDataMetrics.uncached_data)
end
+
+ desc 'GitLab | UsageDataMetrics | Generate known_events/ci_templates.yml based on template definitions'
+ task generate_ci_template_events: :environment do
+ banner = <<~BANNER
+ # This file is generated automatically by
+ # bin/rake gitlab:usage_data:generate_ci_template_events
+ #
+ # Do not edit it manually!
+ BANNER
+
+ repository_includes = ci_template_includes_hash(:repository_source)
+ auto_devops_jobs_includes = ci_template_includes_hash(:auto_devops_source, 'Jobs')
+ auto_devops_security_includes = ci_template_includes_hash(:auto_devops_source, 'Security')
+ all_includes = [*repository_includes, *auto_devops_jobs_includes, *auto_devops_security_includes]
+
+ File.write(Gitlab::UsageDataCounters::CiTemplateUniqueCounter::KNOWN_EVENTS_FILE_PATH, banner + YAML.dump(all_includes).gsub(/ *$/m, ''))
+ end
+
+ def ci_template_includes_hash(source, template_directory = nil)
+ Gitlab::UsageDataCounters::CiTemplateUniqueCounter.ci_templates("lib/gitlab/ci/templates/#{template_directory}").map do |template|
+ {
+ 'name' => Gitlab::UsageDataCounters::CiTemplateUniqueCounter.ci_template_event_name("#{template_directory}/#{template}", source),
+ 'category' => 'ci_templates',
+ 'redis_slot' => Gitlab::UsageDataCounters::CiTemplateUniqueCounter::REDIS_SLOT,
+ 'aggregation' => 'weekly'
+ }
+ end
+ end
end
end
diff --git a/lib/tasks/karma.rake b/lib/tasks/karma.rake
deleted file mode 100644
index fa3f8805159..00000000000
--- a/lib/tasks/karma.rake
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-unless Rails.env.production?
- namespace :karma do
- # alias exists for legacy reasons
- desc 'GitLab | Karma | Generate fixtures for JavaScript tests'
- task fixtures: ['frontend:fixtures']
-
- desc 'GitLab | Karma | Run JavaScript tests'
- task tests: ['yarn:check'] do
- sh "yarn run karma" do |ok, res|
- abort('rake karma:tests failed') unless ok
- end
- end
- end
-
- desc 'GitLab | Karma | Shortcut for karma:fixtures and karma:tests'
- task karma: ['karma:fixtures', 'karma:tests']
-end
diff --git a/lib/tasks/pngquant.rake b/lib/tasks/pngquant.rake
deleted file mode 100644
index 45c0288cadf..00000000000
--- a/lib/tasks/pngquant.rake
+++ /dev/null
@@ -1,55 +0,0 @@
-# frozen_string_literal: true
-
-return if Rails.env.production?
-
-require 'png_quantizator'
-require 'parallel'
-require_relative '../../tooling/lib/tooling/images'
-
-# The amount of variance (in bytes) allowed in
-# file size when testing for compression size
-
-namespace :pngquant do
- # Returns an array of all images eligible for compression
- def doc_images
- Dir.glob('doc/**/*.png', File::FNM_CASEFOLD)
- end
-
- desc 'GitLab | Pngquant | Compress all documentation PNG images using pngquant'
- task :compress do
- files = doc_images
- puts "Compressing #{files.size} PNG files in doc/**"
-
- Parallel.each(files) do |file|
- was_uncompressed, savings = Tooling::Image.compress_image(file)
-
- if was_uncompressed
- puts "#{file} was reduced by #{savings} bytes"
- end
- end
- end
-
- desc 'GitLab | Pngquant | Checks that all documentation PNG images have been compressed with pngquant'
- task :lint do
- files = doc_images
- puts "Checking #{files.size} PNG files in doc/**"
-
- uncompressed_files = Parallel.map(files) do |file|
- is_uncompressed, _ = Tooling::Image.compress_image(file, true)
- if is_uncompressed
- puts "Uncompressed file detected: ".color(:red) + file
- file
- end
- end.compact
-
- if uncompressed_files.empty?
- puts "All documentation images are optimally compressed!".color(:green)
- else
- warn(
- "The #{uncompressed_files.size} image(s) above have not been optimally compressed using pngquant.".color(:red),
- 'Please run "bin/rake pngquant:compress" and commit the result.'
- )
- abort
- end
- end
-end
diff --git a/lib/tasks/rubocop.rake b/lib/tasks/rubocop.rake
index f5d16835347..a4147ae1bba 100644
--- a/lib/tasks/rubocop.rake
+++ b/lib/tasks/rubocop.rake
@@ -4,4 +4,21 @@ unless Rails.env.production?
require 'rubocop/rake_task'
RuboCop::RakeTask.new
+
+ namespace :rubocop do
+ namespace :todo do
+ desc 'Generate RuboCop todos'
+ task :generate do
+ require 'rubocop'
+
+ options = %w[
+ --auto-gen-config
+ --auto-gen-only-exclude
+ --exclude-limit=100000
+ ]
+
+ RuboCop::CLI.new.run(options)
+ end
+ end
+ end
end
diff --git a/locale/am_ET/gitlab.po b/locale/am_ET/gitlab.po
index 24b0b4b44f0..78d2ce5a587 100644
--- a/locale/am_ET/gitlab.po
+++ b/locale/am_ET/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: am\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:22\n"
+"PO-Revision-Date: 2021-09-01 22:32\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -267,8 +267,8 @@ msgstr[1] "%d ተደራሽ á‹«áˆáˆ†áŠ‘ merge requests"
msgid "%d issue"
msgid_plural "%d issues"
-msgstr[0] "%d ርዕሰ ጉዳይ"
-msgstr[1] "%d ርዕሰ ጉዳዮች"
+msgstr[0] ""
+msgstr[1] ""
msgid "%d issue in this group"
msgid_plural "%d issues in this group"
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -402,8 +407,8 @@ msgstr[1] ""
msgid "%s additional commit has been omitted to prevent performance issues."
msgid_plural "%s additional commits have been omitted to prevent performance issues."
-msgstr[0] "የአáˆáƒá€áˆ እክሎች እንዳያጋጥሙ %s ተጨማሪ commit አáˆá‰°áŠ«á‰°á‰°áˆá¢"
-msgstr[1] "የአáˆáƒá€áˆ እክሎች እንዳያጋጥሙ %s ተጨማሪ commits አáˆá‰°áŠ«á‰°á‰±áˆá¢"
+msgstr[0] ""
+msgstr[1] ""
msgid "%{actionText} & %{openOrClose} %{noteable}"
msgstr "%{actionText} እና %{openOrClose} %{noteable}"
@@ -517,6 +522,9 @@ msgstr[1] "%{count} ተሳታáŠá‹Žá‰½"
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr "%{count} ተዛማጅ %{pluralized_subject}: %{links}"
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -548,7 +556,7 @@ msgid "%{duration}ms"
msgstr "%{duration}ሚ"
msgid "%{edit_in_new_fork_notice} Try to cherry-pick this commit again."
-msgstr "%{edit_in_new_fork_notice} ይህንን commit cherry-pick ለማረጠይሞክሩá¡á¡"
+msgstr ""
msgid "%{edit_in_new_fork_notice} Try to create a new directory again."
msgstr "%{edit_in_new_fork_notice} እንደገና አዲስ ማá‹áŒ« ለመáጠር ይሞክሩá¢"
@@ -608,7 +616,7 @@ msgid "%{integrations_link_start}Integrations%{link_end} enable you to make thir
msgstr ""
msgid "%{issuableType} will be removed! Are you sure?"
-msgstr "%{issuableType} ይወገዳáˆ! እርáŒáŒ áŠ› ኖት? "
+msgstr ""
msgid "%{issueType} actions"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrhestration|No rules defined - policy will not run."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/ar_SA/gitlab.po b/locale/ar_SA/gitlab.po
index 42110a491fc..b2a7f469fe0 100644
--- a/locale/ar_SA/gitlab.po
+++ b/locale/ar_SA/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ar\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:25\n"
+"PO-Revision-Date: 2021-09-01 22:32\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -598,6 +598,15 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -805,6 +814,9 @@ msgstr[5] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -943,9 +955,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -955,6 +964,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -1126,6 +1138,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1652,7 +1667,7 @@ msgstr[4] ""
msgstr[5] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -1972,10 +1987,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -2002,10 +2017,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2782,7 +2797,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -3010,12 +3025,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -3082,6 +3091,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -3145,6 +3157,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -3211,7 +3229,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -4060,9 +4078,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -4078,9 +4093,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -4135,6 +4147,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4630,7 +4648,7 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4639,9 +4657,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4669,6 +4693,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4681,6 +4708,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4690,19 +4723,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4813,6 +4852,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4975,9 +5017,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -5098,9 +5137,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -5221,6 +5257,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -5398,6 +5440,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5590,9 +5635,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5881,9 +5923,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5896,12 +5935,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5971,9 +6016,6 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -6274,30 +6316,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6352,6 +6388,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6505,6 +6544,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6988,12 +7030,21 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -7003,15 +7054,21 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -7027,7 +7084,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7636,6 +7693,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7651,9 +7711,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -8335,7 +8392,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8821,9 +8878,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8962,9 +9016,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8977,6 +9028,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9709,7 +9763,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10954,6 +11008,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10966,6 +11023,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10978,12 +11038,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -11005,6 +11071,9 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -11137,9 +11206,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -11209,6 +11275,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -11257,9 +11326,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -11284,6 +11359,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -11302,6 +11380,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -11491,10 +11572,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11554,6 +11635,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11986,6 +12079,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -12046,7 +12145,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -12559,6 +12658,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12634,6 +12736,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12841,9 +12946,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12892,6 +12994,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12931,6 +13036,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -13285,6 +13393,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -13297,6 +13408,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -13372,6 +13486,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -13393,6 +13510,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13729,6 +13852,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -15112,6 +15238,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -15199,6 +15328,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -15331,10 +15463,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -15379,7 +15511,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -15400,9 +15532,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -15457,19 +15586,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -15514,7 +15640,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -15526,6 +15652,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -15550,10 +15679,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15625,7 +15754,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15670,6 +15799,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15724,9 +15856,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15976,6 +16105,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -16057,7 +16189,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -16408,6 +16540,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -16420,6 +16558,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -16453,7 +16594,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16981,10 +17122,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -17125,6 +17266,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -17263,7 +17407,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -17563,6 +17707,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -18322,6 +18469,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -18331,6 +18484,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -18424,6 +18583,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -18544,6 +18706,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18733,9 +18898,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -19273,6 +19435,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19966,9 +20131,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -20095,9 +20257,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -20116,6 +20275,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -20581,10 +20743,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -21097,6 +21262,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -21145,6 +21313,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -21163,6 +21334,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -21175,7 +21349,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -21190,9 +21364,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -21226,6 +21406,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -21250,6 +21436,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -21289,6 +21478,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -21457,6 +21649,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -21574,9 +21769,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -21589,9 +21781,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -22081,9 +22270,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -22462,7 +22648,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22657,12 +22843,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22705,9 +22885,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22717,21 +22894,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22747,9 +22915,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22900,9 +23065,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -23086,6 +23248,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -23623,6 +23788,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23752,7 +23920,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -24052,7 +24220,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -24244,6 +24412,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -25381,6 +25552,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25822,13 +26038,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent MR approvals from users who make commits to the MR."
-msgstr ""
-
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25840,9 +26053,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -26107,6 +26317,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -26299,9 +26512,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -27400,9 +27610,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -27454,6 +27661,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -27493,9 +27703,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27997,6 +28204,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -28066,6 +28279,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -28183,6 +28399,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28717,6 +28936,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -29176,6 +29398,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -29449,6 +29674,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -29512,6 +29740,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -30022,9 +30253,6 @@ msgstr[5] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -30076,7 +30304,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -30112,7 +30340,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -30226,55 +30454,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityPolicies|Environment(s)"
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -30313,9 +30610,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -30427,9 +30721,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -30496,6 +30787,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -31069,7 +31363,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -31117,7 +31411,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -31318,9 +31612,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -31552,6 +31843,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31903,6 +32197,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -33382,6 +33685,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -33433,12 +33739,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -33451,7 +33763,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -33688,7 +34000,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33910,6 +34222,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33946,9 +34261,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -34102,6 +34414,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -34240,9 +34555,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -34288,6 +34609,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -34468,9 +34792,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -34690,9 +35011,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -34765,6 +35083,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35818,13 +36139,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -36391,6 +36718,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -36610,9 +36940,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -36631,9 +36958,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -36682,6 +37015,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36838,6 +37174,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -37315,9 +37654,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -37522,6 +37867,15 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -37780,9 +38134,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -37795,6 +38146,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37900,6 +38254,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -38155,6 +38512,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -38218,6 +38578,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -38776,6 +39139,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -38791,6 +39157,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38935,7 +39304,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -39361,7 +39730,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -39391,6 +39760,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -39499,6 +39892,15 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "branch name"
msgstr ""
@@ -39622,10 +40024,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39994,6 +40396,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -40189,9 +40594,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -40411,8 +40813,14 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -40447,8 +40855,14 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -40495,6 +40909,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -40558,9 +40975,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -40600,9 +41014,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -40630,12 +41041,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/as_IN/gitlab.po b/locale/as_IN/gitlab.po
index e8632619461..3af05fa14f2 100644
--- a/locale/as_IN/gitlab.po
+++ b/locale/as_IN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: as\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:20\n"
+"PO-Revision-Date: 2021-09-01 22:31\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/az_AZ/gitlab.po b/locale/az_AZ/gitlab.po
index cb3b0397e96..6a6be9d7653 100644
--- a/locale/az_AZ/gitlab.po
+++ b/locale/az_AZ/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: az\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:16\n"
+"PO-Revision-Date: 2021-09-01 22:31\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/ba_RU/gitlab.po b/locale/ba_RU/gitlab.po
index 6aa674c403a..11f5e2aab67 100644
--- a/locale/ba_RU/gitlab.po
+++ b/locale/ba_RU/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ba\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:21\n"
+"PO-Revision-Date: 2021-09-01 22:31\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -313,6 +313,10 @@ msgid "%d tag per image name"
msgid_plural "%d tags per image name"
msgstr[0] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -445,6 +449,9 @@ msgstr[0] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -583,9 +590,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -595,6 +599,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -756,6 +763,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1152,7 +1162,7 @@ msgid_plural "%d issues selected"
msgstr[0] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgid "1 merged merge request"
@@ -1417,10 +1427,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1447,10 +1457,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2227,7 +2237,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2455,12 +2465,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2527,6 +2531,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2590,6 +2597,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2656,7 +2669,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3500,9 +3513,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3518,9 +3528,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3575,6 +3582,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4040,7 +4053,7 @@ msgid "ApprovalRuleSummary|%{count} approval required from %{membersCount}"
msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCount}"
msgstr[0] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4049,9 +4062,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4079,6 +4098,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4091,6 +4113,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4100,19 +4128,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4223,6 +4257,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4380,9 +4417,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4498,9 +4532,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4616,6 +4647,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4793,6 +4830,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -4985,9 +5025,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5271,9 +5308,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5286,12 +5320,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5351,9 +5391,6 @@ msgid "Boards|Blocked by %{blockedByCount} %{issuableType}"
msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5654,30 +5691,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5732,6 +5763,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -5880,6 +5914,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6363,12 +6400,16 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6378,15 +6419,16 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6402,7 +6444,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7011,6 +7053,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7026,9 +7071,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7710,7 +7752,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8191,9 +8233,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8332,9 +8371,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8347,6 +8383,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9064,7 +9103,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10299,6 +10338,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10311,6 +10353,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10323,12 +10368,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10345,6 +10396,9 @@ msgid "DastSiteValidation|This will affect %d other profile targeting the same U
msgid_plural "DastSiteValidation|This will affect %d other profiles targeting the same URL."
msgstr[0] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10477,9 +10531,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10549,6 +10600,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10597,9 +10651,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10624,6 +10684,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10642,6 +10705,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10816,10 +10882,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -10864,6 +10930,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11291,6 +11369,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11351,7 +11435,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11859,6 +11943,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -11934,6 +12021,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12141,9 +12231,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12192,6 +12279,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12231,6 +12321,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12585,6 +12678,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12597,6 +12693,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12672,6 +12771,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12693,6 +12795,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13029,6 +13137,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14397,6 +14508,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14484,6 +14598,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14616,10 +14733,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14664,7 +14781,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14685,9 +14802,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14742,19 +14856,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14799,7 +14910,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14811,6 +14922,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14835,10 +14949,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -14910,7 +15024,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -14955,6 +15069,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15009,9 +15126,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15261,6 +15375,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15342,7 +15459,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15693,6 +15810,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15705,6 +15828,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15738,7 +15864,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16266,10 +16392,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16400,6 +16526,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16538,7 +16667,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16823,6 +16952,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17582,6 +17714,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17591,6 +17729,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17679,6 +17823,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17799,6 +17946,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -17988,9 +18138,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18528,6 +18675,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19221,9 +19371,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19345,9 +19492,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19366,6 +19510,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19801,10 +19948,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20312,6 +20462,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20360,6 +20513,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20378,6 +20534,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20390,7 +20549,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20405,9 +20564,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20441,6 +20606,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20465,6 +20636,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20504,6 +20678,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20672,6 +20849,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20789,9 +20969,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20804,9 +20981,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21286,9 +21460,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21667,7 +21838,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -21857,12 +22028,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -21905,9 +22070,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -21917,21 +22079,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -21947,9 +22100,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22095,9 +22245,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22281,6 +22428,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22798,6 +22948,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -22927,7 +23080,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23222,7 +23375,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23414,6 +23567,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24551,6 +24707,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -24992,13 +25193,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25010,9 +25208,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25277,6 +25472,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25469,9 +25667,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26570,9 +26765,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26624,6 +26816,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26663,9 +26858,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27167,6 +27359,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27236,6 +27434,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27348,6 +27549,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -27857,6 +28061,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28301,6 +28508,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28569,6 +28779,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28632,6 +28845,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29087,9 +29303,6 @@ msgstr[0] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29141,7 +29354,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29177,7 +29390,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29291,55 +29504,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityPolicies|Environment(s)"
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29378,9 +29660,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29492,9 +29771,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29561,6 +29837,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30134,7 +30413,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30182,7 +30461,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30383,9 +30662,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30607,6 +30883,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -30958,6 +31237,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32427,6 +32715,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32478,12 +32769,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32496,7 +32793,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32718,7 +33015,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -32935,6 +33232,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -32971,9 +33271,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33127,6 +33424,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33265,9 +33565,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33313,6 +33619,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33493,9 +33802,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33715,9 +34021,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33790,6 +34093,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -34833,13 +35139,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35401,6 +35713,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35620,9 +35935,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35641,9 +35953,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35692,6 +36010,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -35848,6 +36169,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36325,9 +36649,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36522,6 +36852,10 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36780,9 +37114,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36795,6 +37126,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -36900,6 +37234,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37155,6 +37492,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37213,6 +37553,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37771,6 +38114,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37786,6 +38132,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -37930,7 +38279,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38356,7 +38705,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38386,6 +38735,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38489,6 +38862,10 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+
msgid "branch name"
msgstr ""
@@ -38612,10 +38989,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -38964,6 +39341,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39144,9 +39524,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39361,8 +39738,9 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39397,8 +39775,9 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39445,6 +39824,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39508,9 +39890,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39550,9 +39929,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39580,12 +39956,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/bg/gitlab.po b/locale/bg/gitlab.po
index 570eebb5e8a..6883f117fb0 100644
--- a/locale/bg/gitlab.po
+++ b/locale/bg/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: bg\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:25\n"
+"PO-Revision-Date: 2021-09-01 22:32\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr "Ðов клон"
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr "Ðе можете да Ñъздавате повече проекти"
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/bn_BD/gitlab.po b/locale/bn_BD/gitlab.po
index 2fca98fbc1e..228bcc29383 100644
--- a/locale/bn_BD/gitlab.po
+++ b/locale/bn_BD/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: bn\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:15\n"
+"PO-Revision-Date: 2021-09-01 22:30\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/bn_IN/gitlab.po b/locale/bn_IN/gitlab.po
index 03f8bc2234f..565d1f64646 100644
--- a/locale/bn_IN/gitlab.po
+++ b/locale/bn_IN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: bn-IN\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:22\n"
+"PO-Revision-Date: 2021-09-01 22:32\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/br_FR/gitlab.po b/locale/br_FR/gitlab.po
index 75cfa7b6dc7..a9757e284dd 100644
--- a/locale/br_FR/gitlab.po
+++ b/locale/br_FR/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: br-FR\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:18\n"
+"PO-Revision-Date: 2021-09-01 22:31\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -541,6 +541,14 @@ msgstr[2] ""
msgstr[3] ""
msgstr[4] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -733,6 +741,9 @@ msgstr[4] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -871,9 +882,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -883,6 +891,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -1052,6 +1063,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1552,7 +1566,7 @@ msgstr[3] ""
msgstr[4] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -1861,10 +1875,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1891,10 +1905,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2671,7 +2685,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2899,12 +2913,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2971,6 +2979,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -3034,6 +3045,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -3100,7 +3117,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3948,9 +3965,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3966,9 +3980,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -4023,6 +4034,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4512,7 +4529,7 @@ msgstr[2] ""
msgstr[3] ""
msgstr[4] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4521,9 +4538,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4551,6 +4574,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4563,6 +4589,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4572,19 +4604,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4695,6 +4733,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4856,9 +4897,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4978,9 +5016,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -5100,6 +5135,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -5277,6 +5318,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5469,9 +5513,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5759,9 +5800,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5774,12 +5812,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5847,9 +5891,6 @@ msgstr[2] ""
msgstr[3] ""
msgstr[4] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -6150,30 +6191,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6228,6 +6263,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6380,6 +6418,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6863,12 +6904,20 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6878,15 +6927,20 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6902,7 +6956,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7511,6 +7565,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7526,9 +7583,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -8210,7 +8264,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8695,9 +8749,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8836,9 +8887,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8851,6 +8899,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9580,7 +9631,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10823,6 +10874,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10835,6 +10889,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10847,12 +10904,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10873,6 +10936,9 @@ msgstr[2] ""
msgstr[3] ""
msgstr[4] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -11005,9 +11071,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -11077,6 +11140,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -11125,9 +11191,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -11152,6 +11224,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -11170,6 +11245,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -11356,10 +11434,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11416,6 +11494,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11847,6 +11937,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11907,7 +12003,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -12419,6 +12515,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12494,6 +12593,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12701,9 +12803,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12752,6 +12851,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12791,6 +12893,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -13145,6 +13250,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -13157,6 +13265,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -13232,6 +13343,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -13253,6 +13367,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13589,6 +13709,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14969,6 +15092,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -15056,6 +15182,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -15188,10 +15317,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -15236,7 +15365,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -15257,9 +15386,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -15314,19 +15440,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -15371,7 +15494,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -15383,6 +15506,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -15407,10 +15533,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15482,7 +15608,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15527,6 +15653,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15581,9 +15710,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15833,6 +15959,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15914,7 +16043,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -16265,6 +16394,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -16277,6 +16412,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -16310,7 +16448,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16838,10 +16976,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16980,6 +17118,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -17118,7 +17259,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -17415,6 +17556,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -18174,6 +18318,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -18183,6 +18333,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -18275,6 +18431,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -18395,6 +18554,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18584,9 +18746,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -19124,6 +19283,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19817,9 +19979,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19945,9 +20104,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19966,6 +20122,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -20425,10 +20584,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
+msgstr ""
+
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20940,6 +21102,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20988,6 +21153,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -21006,6 +21174,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -21018,7 +21189,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -21033,9 +21204,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -21069,6 +21246,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -21093,6 +21276,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -21132,6 +21318,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -21300,6 +21489,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -21417,9 +21609,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -21432,9 +21621,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21922,9 +22108,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -22303,7 +22486,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22497,12 +22680,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22545,9 +22722,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22557,21 +22731,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22587,9 +22752,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22739,9 +22901,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22925,6 +23084,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -23458,6 +23620,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23587,7 +23752,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23886,7 +24051,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -24078,6 +24243,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -25215,6 +25383,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25656,13 +25869,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25674,9 +25884,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25941,6 +26148,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -26133,9 +26343,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -27234,9 +27441,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -27288,6 +27492,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -27327,9 +27534,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27831,6 +28035,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27900,6 +28110,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -28016,6 +28229,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28545,6 +28761,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -29001,6 +29220,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -29273,6 +29495,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -29336,6 +29561,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29835,9 +30063,6 @@ msgstr[4] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29889,7 +30114,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29925,7 +30150,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -30039,55 +30264,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -30126,9 +30420,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -30240,9 +30531,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -30309,6 +30597,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30882,7 +31173,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30930,7 +31221,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -31131,9 +31422,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -31363,6 +31651,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31714,6 +32005,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -33191,6 +33491,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -33242,12 +33545,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -33260,7 +33569,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -33494,7 +33803,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33715,6 +34024,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33751,9 +34063,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33907,6 +34216,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -34045,9 +34357,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -34093,6 +34411,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -34273,9 +34594,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -34495,9 +34813,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -34570,6 +34885,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35621,13 +35939,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -36193,6 +36517,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -36412,9 +36739,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -36433,9 +36757,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -36484,6 +36814,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36640,6 +36973,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -37117,9 +37453,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -37322,6 +37664,14 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -37580,9 +37930,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -37595,6 +37942,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37700,6 +38050,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37955,6 +38308,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -38017,6 +38373,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -38575,6 +38934,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -38590,6 +38952,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38734,7 +39099,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -39160,7 +39525,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -39190,6 +39555,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -39297,6 +39686,14 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+
msgid "branch name"
msgstr ""
@@ -39420,10 +39817,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39788,6 +40185,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39980,9 +40380,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -40201,8 +40598,13 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -40237,8 +40639,13 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -40285,6 +40692,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -40348,9 +40758,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -40390,9 +40797,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -40420,12 +40824,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/bs_BA/gitlab.po b/locale/bs_BA/gitlab.po
index 2c60bf2d8dd..0a8cfe0f5c1 100644
--- a/locale/bs_BA/gitlab.po
+++ b/locale/bs_BA/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: bs\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:19\n"
+"PO-Revision-Date: 2021-09-01 22:31\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -427,6 +427,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -589,6 +595,9 @@ msgstr[2] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -727,9 +736,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -739,6 +745,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -904,6 +913,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1352,7 +1364,7 @@ msgstr[1] ""
msgstr[2] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -1639,10 +1651,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1669,10 +1681,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2449,7 +2461,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2677,12 +2689,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2749,6 +2755,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2812,6 +2821,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2878,7 +2893,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3724,9 +3739,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3742,9 +3754,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3799,6 +3808,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4276,7 +4291,7 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4285,9 +4300,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4315,6 +4336,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4327,6 +4351,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4336,19 +4366,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4459,6 +4495,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4618,9 +4657,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4738,9 +4774,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4858,6 +4891,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -5035,6 +5074,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5227,9 +5269,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5515,9 +5554,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5530,12 +5566,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5599,9 +5641,6 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5902,30 +5941,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5980,6 +6013,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6130,6 +6166,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6613,12 +6652,18 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6628,15 +6673,18 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6652,7 +6700,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7261,6 +7309,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7276,9 +7327,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7960,7 +8008,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8443,9 +8491,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8584,9 +8629,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8599,6 +8641,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9322,7 +9367,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10561,6 +10606,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10573,6 +10621,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10585,12 +10636,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10609,6 +10666,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10741,9 +10801,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10813,6 +10870,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10861,9 +10921,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10888,6 +10954,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10906,6 +10975,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -11086,10 +11158,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11140,6 +11212,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11569,6 +11653,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11629,7 +11719,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -12139,6 +12229,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12214,6 +12307,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12421,9 +12517,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12472,6 +12565,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12511,6 +12607,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12865,6 +12964,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12877,6 +12979,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12952,6 +13057,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12973,6 +13081,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13309,6 +13423,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14683,6 +14800,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14770,6 +14890,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14902,10 +15025,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14950,7 +15073,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14971,9 +15094,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -15028,19 +15148,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -15085,7 +15202,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -15097,6 +15214,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -15121,10 +15241,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15196,7 +15316,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15241,6 +15361,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15295,9 +15418,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15547,6 +15667,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15628,7 +15751,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15979,6 +16102,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15991,6 +16120,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -16024,7 +16156,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16552,10 +16684,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16690,6 +16822,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16828,7 +16963,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -17119,6 +17254,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17878,6 +18016,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17887,6 +18031,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17977,6 +18127,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -18097,6 +18250,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18286,9 +18442,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18826,6 +18979,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19519,9 +19675,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19645,9 +19798,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19666,6 +19816,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -20113,10 +20266,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20626,6 +20782,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20674,6 +20833,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20692,6 +20854,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20704,7 +20869,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20719,9 +20884,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20755,6 +20926,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20779,6 +20956,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20818,6 +20998,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20986,6 +21169,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -21103,9 +21289,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -21118,9 +21301,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21604,9 +21784,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21985,7 +22162,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22177,12 +22354,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22225,9 +22396,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22237,21 +22405,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22267,9 +22426,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22417,9 +22573,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22603,6 +22756,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -23128,6 +23284,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23257,7 +23416,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23554,7 +23713,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23746,6 +23905,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24883,6 +25045,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25324,13 +25531,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25342,9 +25546,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25609,6 +25810,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25801,9 +26005,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26902,9 +27103,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26956,6 +27154,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26995,9 +27196,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27499,6 +27697,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27568,6 +27772,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27682,6 +27889,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28201,6 +28411,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28651,6 +28864,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28921,6 +29137,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28984,6 +29203,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29461,9 +29683,6 @@ msgstr[2] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29515,7 +29734,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29551,7 +29770,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29665,55 +29884,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29752,9 +30040,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29866,9 +30151,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29935,6 +30217,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30508,7 +30793,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30556,7 +30841,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30757,9 +31042,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30985,6 +31267,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31336,6 +31621,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32809,6 +33103,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32860,12 +33157,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32878,7 +33181,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -33106,7 +33409,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33325,6 +33628,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33361,9 +33667,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33517,6 +33820,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33655,9 +33961,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33703,6 +34015,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33883,9 +34198,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -34105,9 +34417,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -34180,6 +34489,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35227,13 +35539,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35797,6 +36115,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -36016,9 +36337,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -36037,9 +36355,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -36088,6 +36412,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36244,6 +36571,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36721,9 +37051,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36922,6 +37258,12 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -37180,9 +37522,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -37195,6 +37534,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37300,6 +37642,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37555,6 +37900,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37615,6 +37963,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -38173,6 +38524,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -38188,6 +38542,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38332,7 +38689,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38758,7 +39115,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38788,6 +39145,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38893,6 +39274,12 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "branch name"
msgstr ""
@@ -39016,10 +39403,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39376,6 +39763,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39562,9 +39952,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39781,8 +40168,11 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39817,8 +40207,11 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39865,6 +40258,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39928,9 +40324,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39970,9 +40363,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -40000,12 +40390,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/ca_ES/gitlab.po b/locale/ca_ES/gitlab.po
index 528a2bd058b..7d1fd006527 100644
--- a/locale/ca_ES/gitlab.po
+++ b/locale/ca_ES/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ca\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:26\n"
+"PO-Revision-Date: 2021-09-01 22:32\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] "%{count} participants"
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1352,7 +1363,7 @@ msgid "404|Make sure the address is correct and the page hasn't moved."
msgstr ""
msgid "404|Page Not Found"
-msgstr "404|No s'ha trobat la pàgina"
+msgstr ""
msgid "404|Please contact your GitLab administrator if you think this is a mistake."
msgstr ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2117,7 +2128,7 @@ msgid "AddMember|No invite source provided."
msgstr ""
msgid "AddMember|No users specified."
-msgstr "AddMember|No s’ha especificat cap usuari."
+msgstr ""
msgid "AddMember|Too many users specified (limit is %{user_limit})"
msgstr ""
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr "Artefactes"
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr "Taulers"
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr "Estat"
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
+msgstr ""
+
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityPolicies|Environment(s)"
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/cs_CZ/gitlab.po b/locale/cs_CZ/gitlab.po
index 3a473cf53eb..2b9e77ced37 100644
--- a/locale/cs_CZ/gitlab.po
+++ b/locale/cs_CZ/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: cs\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:26\n"
+"PO-Revision-Date: 2021-09-01 22:32\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -61,10 +61,10 @@ msgstr[3] ""
msgid " improved on %d point"
msgid_plural " improved on %d points"
-msgstr[0] "vylepšeno na %d bodu"
-msgstr[1] "se zlepšil na %d bodech"
-msgstr[2] "se zlepšil na %d bodech"
-msgstr[3] "se zlepšil na %d bodech"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
msgid " or "
msgstr ""
@@ -484,6 +484,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -661,6 +668,9 @@ msgstr[3] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -799,9 +809,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -811,6 +818,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -978,6 +988,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1452,7 +1465,7 @@ msgstr[2] ""
msgstr[3] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -1568,13 +1581,13 @@ msgid "403|Please contact your GitLab administrator to get permission."
msgstr ""
msgid "403|You don't have the permission to access this page."
-msgstr "403 | Nemáte oprávnění pro přístup na tuto stránku."
+msgstr ""
msgid "404|Make sure the address is correct and the page hasn't moved."
-msgstr "404 | Ujistěte se, že adresa je správná a stránka nebyla přesunuta."
+msgstr ""
msgid "404|Page Not Found"
-msgstr "404 | Stránka nebyla nalezena"
+msgstr ""
msgid "404|Please contact your GitLab administrator if you think this is a mistake."
msgstr ""
@@ -1750,10 +1763,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1780,10 +1793,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2560,8 +2573,8 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
-msgstr "Chystáte se zastavit všechny úlohy. To způsobí přerušení všech aktuálně spuštěných úloh."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
+msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
@@ -2788,12 +2801,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2860,6 +2867,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2923,6 +2933,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2989,7 +3005,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3836,9 +3852,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3854,9 +3867,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3911,6 +3921,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4394,7 +4410,7 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4403,9 +4419,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4433,6 +4455,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4445,6 +4470,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4454,19 +4485,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4577,6 +4614,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4737,9 +4777,6 @@ msgstr ""
msgid "Artifacts"
msgstr "Artefakty"
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4858,9 +4895,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4979,6 +5013,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -5156,6 +5196,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5348,9 +5391,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5637,9 +5677,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5652,12 +5689,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5723,9 +5766,6 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -6026,30 +6066,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6104,6 +6138,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6255,6 +6292,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6738,12 +6778,19 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6753,15 +6800,19 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6777,7 +6828,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7386,6 +7437,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7401,9 +7455,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -8085,7 +8136,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8569,9 +8620,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8710,9 +8758,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8725,6 +8770,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9451,7 +9499,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10692,6 +10740,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10704,6 +10755,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10716,12 +10770,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10741,6 +10801,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10873,9 +10936,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10945,6 +11005,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10993,9 +11056,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -11020,6 +11089,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -11038,6 +11110,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -11221,10 +11296,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11278,6 +11353,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11708,6 +11795,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11768,7 +11861,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -12279,6 +12372,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12354,6 +12450,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12561,9 +12660,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12612,6 +12708,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12651,6 +12750,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -13005,6 +13107,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -13017,6 +13122,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -13092,6 +13200,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -13113,6 +13224,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13449,6 +13566,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14826,6 +14946,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14913,6 +15036,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -15045,10 +15171,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -15093,7 +15219,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -15114,9 +15240,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -15171,19 +15294,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -15228,7 +15348,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -15240,6 +15360,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -15264,10 +15387,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15339,7 +15462,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15384,6 +15507,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15438,9 +15564,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15690,6 +15813,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15771,7 +15897,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -16122,6 +16248,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -16134,6 +16266,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -16167,7 +16302,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16695,10 +16830,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16835,6 +16970,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16973,7 +17111,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -17267,6 +17405,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -18026,6 +18167,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -18035,6 +18182,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -18126,6 +18279,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -18246,6 +18402,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18435,9 +18594,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18975,6 +19131,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19668,9 +19827,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19795,9 +19951,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19816,6 +19969,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -20269,10 +20425,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
+msgstr ""
+
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20783,6 +20942,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20831,6 +20993,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20849,6 +21014,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20861,7 +21029,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20876,9 +21044,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20912,6 +21086,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20936,6 +21116,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20975,6 +21158,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -21143,6 +21329,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -21260,9 +21449,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -21275,9 +21461,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21763,9 +21946,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -22144,7 +22324,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22337,12 +22517,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22385,9 +22559,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22397,21 +22568,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22427,9 +22589,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22578,9 +22737,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22764,6 +22920,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -23293,6 +23452,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23422,7 +23584,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23720,7 +23882,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23912,6 +24074,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -25049,6 +25214,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25490,13 +25700,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25508,9 +25715,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25775,6 +25979,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25967,9 +26174,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -27068,9 +27272,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -27122,6 +27323,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -27161,9 +27365,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27665,6 +27866,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27734,6 +27941,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27849,6 +28059,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28373,6 +28586,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28826,6 +29042,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -29097,6 +29316,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -29160,6 +29382,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29648,9 +29873,6 @@ msgstr[3] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29702,7 +29924,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29738,7 +29960,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29852,55 +30074,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityPolicies|Environment(s)"
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29939,9 +30230,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -30053,9 +30341,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -30122,6 +30407,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30695,7 +30983,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30743,7 +31031,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30944,9 +31232,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -31174,6 +31459,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31525,6 +31813,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -33000,6 +33297,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -33051,12 +33351,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -33069,7 +33375,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -33300,7 +33606,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33520,6 +33826,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33556,9 +33865,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33712,6 +34018,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33850,9 +34159,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33898,6 +34213,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -34078,9 +34396,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -34300,9 +34615,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -34375,6 +34687,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35424,13 +35739,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35995,6 +36316,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -36214,9 +36538,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -36235,9 +36556,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -36286,6 +36613,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36442,6 +36772,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36919,9 +37252,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -37122,6 +37461,13 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -37380,9 +37726,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -37395,6 +37738,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37500,6 +37846,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37755,6 +38104,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37816,6 +38168,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -38374,6 +38729,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -38389,6 +38747,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38533,7 +38894,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38959,7 +39320,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38989,6 +39350,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -39095,6 +39480,13 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "branch name"
msgstr ""
@@ -39218,10 +39610,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39582,6 +39974,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39771,9 +40166,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39991,8 +40383,12 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -40027,8 +40423,12 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -40075,6 +40475,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -40138,9 +40541,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -40180,9 +40580,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -40210,12 +40607,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/cy_GB/gitlab.po b/locale/cy_GB/gitlab.po
index 43f4d34101e..b78476c9887 100644
--- a/locale/cy_GB/gitlab.po
+++ b/locale/cy_GB/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: cy\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:11\n"
+"PO-Revision-Date: 2021-09-01 22:30\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -54,12 +54,12 @@ msgstr ""
msgid " degraded on %d point"
msgid_plural " degraded on %d points"
-msgstr[0] " diraddiwyd ar %d pwyntiau"
-msgstr[1] " diraddiwyd ar %d pwynt"
-msgstr[2] " diraddiwyd ar %d bwynt "
-msgstr[3] " diraddiwyd ar %d pwynt "
-msgstr[4] " diraddiwyd ar %d phwynt "
-msgstr[5] " diraddiwyd ar %d pwynt"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
msgid " improved on %d point"
msgid_plural " improved on %d points"
@@ -598,6 +598,15 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -805,6 +814,9 @@ msgstr[5] "%{count} cyfranogwr"
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr "%{count} %{pluralized_subject} cysylltiedig: %{links}"
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -943,9 +955,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -955,6 +964,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -1126,6 +1138,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1652,7 +1667,7 @@ msgstr[4] ""
msgstr[5] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -1972,10 +1987,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -2002,10 +2017,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2782,7 +2797,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -3010,12 +3025,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -3082,6 +3091,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -3145,6 +3157,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -3211,7 +3229,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -4060,9 +4078,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -4078,9 +4093,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -4135,6 +4147,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4630,7 +4648,7 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4639,9 +4657,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4669,6 +4693,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4681,6 +4708,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4690,19 +4723,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4813,6 +4852,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4975,9 +5017,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -5098,9 +5137,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -5221,6 +5257,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -5398,6 +5440,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5590,9 +5635,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5881,9 +5923,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5896,12 +5935,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5971,9 +6016,6 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -6274,30 +6316,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6352,6 +6388,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6505,6 +6544,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6988,12 +7030,21 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -7003,15 +7054,21 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -7027,7 +7084,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7636,6 +7693,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7651,9 +7711,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -8335,7 +8392,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8821,9 +8878,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8962,9 +9016,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8977,6 +9028,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9709,7 +9763,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10954,6 +11008,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10966,6 +11023,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10978,12 +11038,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -11005,6 +11071,9 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -11137,9 +11206,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -11209,6 +11275,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -11257,9 +11326,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -11284,6 +11359,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -11302,6 +11380,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -11491,10 +11572,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11554,6 +11635,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11986,6 +12079,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -12046,7 +12145,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -12559,6 +12658,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12634,6 +12736,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12841,9 +12946,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12892,6 +12994,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12931,6 +13036,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -13285,6 +13393,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -13297,6 +13408,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -13372,6 +13486,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -13393,6 +13510,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13729,6 +13852,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -15112,6 +15238,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -15199,6 +15328,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -15331,10 +15463,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -15379,7 +15511,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -15400,9 +15532,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -15457,19 +15586,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -15514,7 +15640,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -15526,6 +15652,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -15550,10 +15679,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15625,7 +15754,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15670,6 +15799,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15724,9 +15856,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15976,6 +16105,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -16057,7 +16189,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -16408,6 +16540,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -16420,6 +16558,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -16453,7 +16594,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16981,10 +17122,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -17125,6 +17266,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -17263,7 +17407,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -17563,6 +17707,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -18322,6 +18469,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -18331,6 +18484,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -18424,6 +18583,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -18544,6 +18706,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18733,9 +18898,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -19273,6 +19435,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19966,9 +20131,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -20095,9 +20257,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -20116,6 +20275,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -20581,10 +20743,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -21097,6 +21262,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -21145,6 +21313,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -21163,6 +21334,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -21175,7 +21349,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -21190,9 +21364,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -21226,6 +21406,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -21250,6 +21436,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -21289,6 +21478,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -21457,6 +21649,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -21574,9 +21769,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -21589,9 +21781,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -22081,9 +22270,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -22462,7 +22648,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22657,12 +22843,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22705,9 +22885,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22717,21 +22894,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22747,9 +22915,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22900,9 +23065,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -23086,6 +23248,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -23623,6 +23788,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23752,7 +23920,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -24052,7 +24220,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -24244,6 +24412,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -25381,6 +25552,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25822,13 +26038,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25840,9 +26053,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -26107,6 +26317,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -26299,9 +26512,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -27400,9 +27610,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -27454,6 +27661,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -27493,9 +27703,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27997,6 +28204,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -28066,6 +28279,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -28183,6 +28399,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28717,6 +28936,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -29176,6 +29398,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -29449,6 +29674,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -29512,6 +29740,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -30022,9 +30253,6 @@ msgstr[5] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -30076,7 +30304,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -30112,7 +30340,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -30226,55 +30454,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -30313,9 +30610,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -30427,9 +30721,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -30496,6 +30787,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -31069,7 +31363,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -31117,7 +31411,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -31318,9 +31612,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -31552,6 +31843,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31903,6 +32197,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -33382,6 +33685,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -33433,12 +33739,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -33451,7 +33763,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -33688,7 +34000,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33910,6 +34222,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33946,9 +34261,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -34102,6 +34414,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -34240,9 +34555,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -34288,6 +34609,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -34468,9 +34792,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -34690,9 +35011,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -34765,6 +35083,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35818,13 +36139,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -36391,6 +36718,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -36610,9 +36940,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -36631,9 +36958,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -36682,6 +37015,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36838,6 +37174,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -37315,9 +37654,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -37522,6 +37867,15 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -37780,9 +38134,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -37795,6 +38146,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37900,6 +38254,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -38155,6 +38512,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -38218,6 +38578,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -38776,6 +39139,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -38791,6 +39157,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38935,7 +39304,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -39361,7 +39730,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -39391,6 +39760,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -39499,6 +39892,15 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "branch name"
msgstr ""
@@ -39622,10 +40024,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39994,6 +40396,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -40189,9 +40594,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -40411,8 +40813,14 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -40447,8 +40855,14 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -40495,6 +40909,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -40558,9 +40975,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -40600,9 +41014,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -40630,12 +41041,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/da_DK/gitlab.po b/locale/da_DK/gitlab.po
index 948aa8f1413..f114892c048 100644
--- a/locale/da_DK/gitlab.po
+++ b/locale/da_DK/gitlab.po
@@ -14,574 +14,582 @@ msgstr ""
"X-Crowdin-Language: da\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:26\n"
+"PO-Revision-Date: 2021-09-02 01:27\n"
msgid " %{name}, confirm your email address now! "
-msgstr ""
+msgstr " %{name}, bekræft din e-mailadresse nu! "
msgid " %{start} to %{end}"
-msgstr ""
+msgstr " %{start} til %{end}"
msgid " (from %{timeoutSource})"
-msgstr ""
+msgstr " (fra %{timeoutSource})"
msgid " Collected %{time}"
-msgstr ""
+msgstr " Indsamlet %{time}"
msgid " Please sign in."
-msgstr ""
+msgstr " Log venligst ind."
msgid " Target Path"
-msgstr ""
+msgstr " MÃ¥lsti"
msgid " Try to %{action} this file again."
-msgstr ""
+msgstr " Prøv at %{action} filen igen."
msgid " Type"
-msgstr ""
+msgstr " Type"
msgid " You need to do this before %{grace_period_deadline}."
-msgstr ""
+msgstr " Du skal gøre det inden %{grace_period_deadline}."
msgid " and"
-msgstr ""
+msgstr " og"
msgid " and "
-msgstr ""
+msgstr " og "
msgid " and %{sliced}"
-msgstr ""
+msgstr " og %{sliced}"
msgid " degraded on %d point"
msgid_plural " degraded on %d points"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] " forringet på %d punkt"
+msgstr[1] " forringet på %d punkter"
msgid " improved on %d point"
msgid_plural " improved on %d points"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] " forbedret på %d punkt"
+msgstr[1] " forbedret på %d punkter"
msgid " or "
-msgstr ""
+msgstr " eller "
msgid " or %{emphasisStart}!merge request id%{emphasisEnd}"
-msgstr ""
+msgstr " eller %{emphasisStart}!sammenlægningsanmodning-id%{emphasisEnd}"
msgid " or %{emphasisStart}#issue id%{emphasisEnd}"
-msgstr ""
+msgstr " eller %{emphasisStart}#problemstilling-id%{emphasisEnd}"
msgid " or %{emphasisStart}&epic id%{emphasisEnd}"
-msgstr ""
+msgstr " eller %{emphasisStart}#epic-id%{emphasisEnd}"
msgid " or references (e.g. path/to/project!merge_request_id)"
-msgstr ""
+msgstr " eller referencer (f.eks. sti/til/projekt!sammenlægningsanmodning-id)"
msgid " reacted with :%{name}:"
-msgstr ""
+msgstr " reagerede med :%{name}:"
msgid "\"%{path}\" did not exist on \"%{ref}\""
-msgstr ""
+msgstr "\"%{path}\" fandtes ikke på \"%{ref}\""
msgid "\"%{repository_name}\" size (%{repository_size}) is larger than the limit of %{limit}."
-msgstr ""
+msgstr "Størrelsen på \"%{repository_name}\" (%{repository_size}) er større end grænsen på %{limit}."
msgid "\"el\" parameter is required for createInstance()"
-msgstr ""
+msgstr "Parameteren \"el\" kræves til createInstance()"
msgid "#general, #development"
-msgstr ""
+msgstr "#generelt, #udvikling"
msgid "%d Approval"
msgid_plural "%d Approvals"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d godkendelse"
+msgstr[1] "%d godkendelser"
msgid "%d Module"
msgid_plural "%d Modules"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d modul"
+msgstr[1] "%d moduler"
msgid "%d Other"
msgid_plural "%d Others"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d anden"
+msgstr[1] "%d andre"
msgid "%d Package"
msgid_plural "%d Packages"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d pakke"
+msgstr[1] "%d pakker"
msgid "%d Scanned URL"
msgid_plural "%d Scanned URLs"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d skannet URL"
+msgstr[1] "%d skannede URL'er"
msgid "%d URL scanned"
msgid_plural "%d URLs scanned"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d URL skannet"
+msgstr[1] "%d URL'er skannet"
msgid "%d approver"
msgid_plural "%d approvers"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d godkender"
+msgstr[1] "%d godkendere"
msgid "%d approver (you've approved)"
msgid_plural "%d approvers (you've approved)"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d godkender (som du har godkendt)"
+msgstr[1] "%d godkendere (som du har godkendt)"
msgid "%d changed file"
msgid_plural "%d changed files"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d ændret fil"
+msgstr[1] "%d ændret filer"
msgid "%d character remaining"
msgid_plural "%d characters remaining"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d tegn tilbage"
+msgstr[1] "%d tegn tilbage"
msgid "%d child epic"
msgid_plural "%d child epics"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d underepic"
+msgstr[1] "%d underepics"
msgid "%d code quality issue"
msgid_plural "%d code quality issues"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d kodekvalitetsproblemstilling"
+msgstr[1] "%d kodekvalitetsproblemstillinger"
msgid "%d comment"
msgid_plural "%d comments"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d kommentar"
+msgstr[1] "%d kommentarer"
msgid "%d comment on this commit"
msgid_plural "%d comments on this commit"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d kommentar til committen"
+msgstr[1] "%d kommentarer til committen"
msgid "%d commenter"
msgid_plural "%d commenters"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d kommentator"
+msgstr[1] "%d kommentatorer"
msgid "%d commit"
msgid_plural "%d commits"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d commit"
+msgstr[1] "%d commits"
msgid "%d commit author"
msgid_plural "%d commit authors"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d commit-forfatter"
+msgstr[1] "%d commit-forfattere"
msgid "%d commit behind"
msgid_plural "%d commits behind"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d commit bagud"
+msgstr[1] "%d commits bagud"
msgid "%d commit,"
msgid_plural "%d commits,"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d commit,"
+msgstr[1] "%d commits,"
msgid "%d commits"
-msgstr ""
+msgstr "%d commits"
msgid "%d completed issue"
msgid_plural "%d completed issues"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d fuldført problemstilling"
+msgstr[1] "%d fuldførte problemstillinger"
msgid "%d contribution"
msgid_plural "%d contributions"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d bidrag"
+msgstr[1] "%d bidrag"
msgid "%d day"
msgid_plural "%d days"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d dag"
+msgstr[1] "%d dage"
msgid "%d epic"
msgid_plural "%d epics"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d epic"
+msgstr[1] "%d epics"
msgid "%d error"
msgid_plural "%d errors"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d fejl"
+msgstr[1] "%d fejl"
msgid "%d error found:"
msgid_plural "%d errors found:"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d fejl fundet:"
+msgstr[1] "%d fejl fundet:"
msgid "%d exporter"
msgid_plural "%d exporters"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d eksportør"
+msgstr[1] "%d eksportører"
msgid "%d failed"
msgid_plural "%d failed"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d mislykkedes"
+msgstr[1] "%d mislykkedes"
msgid "%d failed security job"
msgid_plural "%d failed security jobs"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d mislykkedes sikkerhedsjob"
+msgstr[1] "%d mislykkedes sikkerhedsjob"
msgid "%d file"
msgid_plural "%d files"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d fil"
+msgstr[1] "%d filer"
msgid "%d fixed test result"
msgid_plural "%d fixed test results"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d rettet testresultat"
+msgstr[1] "%d rettet testresultater"
msgid "%d group"
msgid_plural "%d groups"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d gruppe"
+msgstr[1] "%d grupper"
msgid "%d group selected"
msgid_plural "%d groups selected"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d gruppe valgt"
+msgstr[1] "%d grupper valgt"
msgid "%d hour"
msgid_plural "%d hours"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d time"
+msgstr[1] "%d timer"
msgid "%d inaccessible merge request"
msgid_plural "%d inaccessible merge requests"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d utilgængelig sammenlægningsanmodning"
+msgstr[1] "%d utilgængelige sammenlægningsanmodninger"
msgid "%d issue"
msgid_plural "%d issues"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d problemstilling"
+msgstr[1] "%d problemstillinger"
msgid "%d issue in this group"
msgid_plural "%d issues in this group"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d problemstilling i gruppen"
+msgstr[1] "%d problemstillinger i gruppen"
msgid "%d issue successfully imported with the label"
msgid_plural "%d issues successfully imported with the label"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d problemstilling importeret med etiketten"
+msgstr[1] "%d problemstillinger importeret med etiketten"
msgid "%d layer"
msgid_plural "%d layers"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d lag"
+msgstr[1] "%d lag"
msgid "%d merge request"
msgid_plural "%d merge requests"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d sammenlægningsanmodning"
+msgstr[1] "%d sammenlægningsanmodninger"
msgid "%d merge request that you don't have access to."
msgid_plural "%d merge requests that you don't have access to."
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d sammenlægningsanmodning som du ikke har adgang til."
+msgstr[1] "%d sammenlægningsanmodninger som du ikke har adgang til."
msgid "%d metric"
msgid_plural "%d metrics"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d måling"
+msgstr[1] "%d målinger"
msgid "%d milestone"
msgid_plural "%d milestones"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d milepæl"
+msgstr[1] "%d milepæle"
msgid "%d minute"
msgid_plural "%d minutes"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d minut"
+msgstr[1] "%d minutter"
msgid "%d more comment"
msgid_plural "%d more comments"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d kommentar mere"
+msgstr[1] "%d kommentarer mere"
msgid "%d open issue"
msgid_plural "%d open issues"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d åben problemstilling"
+msgstr[1] "%d åbne problemstillinger"
msgid "%d pending comment"
msgid_plural "%d pending comments"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d afventende kommentar"
+msgstr[1] "%d afventende kommentarer"
msgid "%d personal project will be removed and cannot be restored."
msgid_plural "%d personal projects will be removed and cannot be restored."
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d personligt projekt fjernes og kan ikke gendannes."
+msgstr[1] "%d personlige projekter fjernes og kan ikke gendannes."
msgid "%d previously merged commit"
msgid_plural "%d previously merged commits"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d tidligere sammenlagt commit"
+msgstr[1] "%d tidligere sammenlagte commits"
msgid "%d project"
msgid_plural "%d projects"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d projekt"
+msgstr[1] "%d projekter"
msgid "%d project selected"
msgid_plural "%d projects selected"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d projekt valgt"
+msgstr[1] "%d projekter valgt"
msgid "%d request with warnings"
msgid_plural "%d requests with warnings"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d anmodning med advarsler"
+msgstr[1] "%d anmodninger med advarsler"
msgid "%d second"
msgid_plural "%d seconds"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d sekund"
+msgstr[1] "%d sekunder"
msgid "%d shard selected"
msgid_plural "%d shards selected"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d shard valgt"
+msgstr[1] "%d shards valgt"
msgid "%d tag"
msgid_plural "%d tags"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d mærkat"
+msgstr[1] "%d mærkater"
msgid "%d tag per image name"
msgid_plural "%d tags per image name"
+msgstr[0] "%d mærkat pr. billednavn"
+msgstr[1] "%d mærkater pr. billednavn"
+
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
msgstr[0] ""
msgstr[1] ""
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d utildelt problemstilling"
+msgstr[1] "%d utildelte problemstillinger"
msgid "%d unresolved thread"
msgid_plural "%d unresolved threads"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d uløst tråd"
+msgstr[1] "%d uløste tråde"
msgid "%d vulnerability"
msgid_plural "%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d sårbarhed"
+msgstr[1] "%d sårbarheder"
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d sårbarhed afskediget"
+msgstr[1] "%d sårbarheder afskediget"
msgid "%d vulnerability updated"
msgid_plural "%d vulnerabilities updated"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d sårbarhed opdateret"
+msgstr[1] "%d sårbarheder opdateret"
msgid "%d warning found:"
msgid_plural "%d warnings found:"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d advarsel fundet:"
+msgstr[1] "%d advarsler fundet:"
msgid "%s additional commit has been omitted to prevent performance issues."
msgid_plural "%s additional commits have been omitted to prevent performance issues."
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%s yderligere commit er udeladt for at forhindre ydelsesproblemer."
+msgstr[1] "%s yderligere commits er udeladt for at forhindre ydelsesproblemer."
msgid "%{actionText} & %{openOrClose} %{noteable}"
-msgstr ""
+msgstr "%{actionText} og %{openOrClose} %{noteable}"
msgid "%{address} is an invalid IP address range"
-msgstr ""
+msgstr "%{address} er et ugyldigt IP-adresseområde"
msgid "%{anchorOpen}Learn more%{anchorClose} about how you can customize / disable registration on your instance."
-msgstr ""
+msgstr "%{anchorOpen}Lær mere%{anchorClose} om hvordan du kan tilpasse/deaktivere registrering på din instans."
msgid "%{author_link} cloned %{original_issue} to %{new_issue}."
-msgstr ""
+msgstr "%{author_link} klonede %{original_issue} til %{new_issue}."
msgid "%{author_link} cloned %{original_issue}. You don't have access to the new project."
-msgstr ""
+msgstr "%{author_link} klonede %{original_issue}. Du har ikke adgang til det nye projekt."
msgid "%{author_link} wrote:"
-msgstr ""
+msgstr "%{author_link} skrev:"
msgid "%{authorsName}'s thread"
-msgstr ""
+msgstr "%{authorsName}s tråd"
msgid "%{board_target} not found"
-msgstr ""
+msgstr "%{board_target} ikke fundet"
msgid "%{bold_start}%{count}%{bold_end} issue"
msgid_plural "%{bold_start}%{count}%{bold_end} issues"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{bold_start}%{count}%{bold_end} problemstilling"
+msgstr[1] "%{bold_start}%{count}%{bold_end} problemstillinger"
msgid "%{bold_start}%{count}%{bold_end} member"
msgid_plural "%{bold_start}%{count}%{bold_end} members"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{bold_start}%{count}%{bold_end} medlem"
+msgstr[1] "%{bold_start}%{count}%{bold_end} medlemmer"
msgid "%{bold_start}%{count}%{bold_end} opened merge request"
msgid_plural "%{bold_start}%{count}%{bold_end} opened merge requests"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{bold_start}%{count}%{bold_end} åbnet sammenfletningsanmodning"
+msgstr[1] "%{bold_start}%{count}%{bold_end} åbnet sammenfletningsanmodninger"
msgid "%{code_open}Masked:%{code_close} Hidden in job logs. Must match masking requirements."
-msgstr ""
+msgstr "%{code_open}Maskeret:%{code_close} Skjult i joblogge. Skal passe med maskeringskrav."
msgid "%{code_open}Protected:%{code_close} Only exposed to protected branches or tags."
msgstr ""
msgid "%{commit_author_link} authored %{commit_timeago}"
-msgstr ""
+msgstr "%{commit_author_link} forfattede %{commit_timeago}"
msgid "%{completedCount} completed weight"
-msgstr ""
+msgstr "%{completedCount} fuldført vægt"
msgid "%{completedCount} of %{count} task completed"
msgid_plural "%{completedCount} of %{count} tasks completed"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{completedCount} af %{count} opgave fuldført"
+msgstr[1] "%{completedCount} af %{count} opgaver fuldført"
msgid "%{completedWeight} of %{totalWeight} weight completed"
-msgstr ""
+msgstr "%{completedWeight} af %{totalWeight} vægt fuldført"
msgid "%{cores} cores"
-msgstr ""
+msgstr "%{cores} kerner"
msgid "%{count} %{scope} for term '%{term}'"
msgstr ""
msgid "%{count} LOC/commit"
-msgstr ""
+msgstr "%{count} LOC/commit"
msgid "%{count} approval required from %{name}"
msgid_plural "%{count} approvals required from %{name}"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{count} godkendelse kræves fra %{name}"
+msgstr[1] "%{count} godkendelser kræves fra %{name}"
msgid "%{count} approvals from %{name}"
-msgstr ""
+msgstr "%{count} godkendelser fra %{name}"
msgid "%{count} files touched"
-msgstr ""
+msgstr "%{count} filer berørt"
msgid "%{count} item"
msgid_plural "%{count} items"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{count} element"
+msgstr[1] "%{count} elementer"
msgid "%{count} items per page"
-msgstr ""
+msgstr "%{count} elementer pr. side"
msgid "%{count} more"
-msgstr ""
+msgstr "%{count} mere"
msgid "%{count} more assignees"
-msgstr ""
+msgstr "%{count} tildelte mere"
msgid "%{count} more release"
msgid_plural "%{count} more releases"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{count} udgivelse mere"
+msgstr[1] "%{count} udgivelser mere"
msgid "%{count} of %{required} approvals from %{name}"
-msgstr ""
+msgstr "%{count} af %{required} godkendelser fra %{name}"
msgid "%{count} of %{total}"
-msgstr ""
+msgstr "%{count} af %{total}"
msgid "%{count} participant"
msgid_plural "%{count} participants"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{count} deltager"
+msgstr[1] "%{count} deltagere"
msgid "%{count} related %{pluralized_subject}: %{links}"
+msgstr "%{count} relaterede %{pluralized_subject}: %{links}"
+
+msgid "%{count} selected"
msgstr ""
msgid "%{count} total weight"
-msgstr ""
+msgstr "%{count} vægt i alt"
msgid "%{criticalStart}%{critical} Critical%{criticalEnd} %{highStart}%{high} High%{highEnd} and %{otherStart}%{otherMessage}%{otherEnd}"
-msgstr ""
+msgstr "%{criticalStart}%{critical} kritisk%{criticalEnd} %{highStart}%{high} høj%{highEnd} og %{otherStart}%{otherMessage}%{otherEnd}"
msgid "%{dashboard_path} could not be found."
-msgstr ""
+msgstr "%{dashboard_path} blev ikke fundet."
msgid "%{days} days until tags are automatically removed"
-msgstr ""
+msgstr "%{days} dage før mærkater fjernes automatisk"
msgid "%{deployLinkStart}Use a template to deploy to ECS%{deployLinkEnd}, or use a docker image to %{commandsLinkStart}run AWS commands in GitLab CI/CD%{commandsLinkEnd}."
-msgstr ""
+msgstr "%{deployLinkStart}Brug en skabelon til at udsende til ECS%{deployLinkEnd} eller brug et docker-aftryk til at %{commandsLinkStart}køre AWS-kommandoer i GitLab CI/CD%{commandsLinkEnd}."
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
-msgstr ""
+msgstr "%{description}- Sentry-begivenhed: %{errorUrl}- Først set: %{firstSeen}- Sidst set: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
-msgstr ""
+msgstr "%{doc_link_start}Avanceret søgning%{doc_link_end} er deaktiveret eftersom %{ref_elem} ikke er standardgrenen; %{default_branch_link_start}søg i stedet på %{default_branch}%{default_branch_link_end}."
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
-msgstr ""
+msgstr "%{doc_link_start}Avanceret søgning%{doc_link_end} er aktiveret."
msgid "%{due_date} (Past due)"
-msgstr ""
+msgstr "%{due_date} (overskredet)"
msgid "%{duration}ms"
-msgstr ""
+msgstr "%{duration} ms"
msgid "%{edit_in_new_fork_notice} Try to cherry-pick this commit again."
-msgstr ""
+msgstr "%{edit_in_new_fork_notice} Prøv at cherry-pick'e committen igen."
msgid "%{edit_in_new_fork_notice} Try to create a new directory again."
-msgstr ""
+msgstr "%{edit_in_new_fork_notice} Prøv at oprette en ny mappe igen."
msgid "%{edit_in_new_fork_notice} Try to revert this commit again."
-msgstr ""
+msgstr "%{edit_in_new_fork_notice} Prøv at tilbageføre committen igen."
msgid "%{edit_in_new_fork_notice} Try to upload a file again."
-msgstr ""
+msgstr "%{edit_in_new_fork_notice} Prøv at uploade en fil igen."
msgid "%{emailPrefix}@company.com"
-msgstr ""
+msgstr "%{emailPrefix}@company.com"
msgid "%{extra} more downstream pipelines"
msgstr ""
msgid "%{filePath} deleted"
-msgstr ""
+msgstr "%{filePath} slettet"
msgid "%{firstLabel} +%{labelCount} more"
-msgstr ""
+msgstr "%{firstLabel} +%{labelCount} mere"
msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
-msgstr ""
+msgstr "%{firstMilestoneName} + %{numberOfOtherMilestones} mere"
msgid "%{gitlab_experience_text}. Don't worry, this information isn't shared outside of your self-managed GitLab instance."
-msgstr ""
+msgstr "%{gitlab_experience_text}. Bare rolig, informationen deles ikke uden for din selvhåndterede GitLab-instans."
msgid "%{gitlab_experience_text}. We won't share this information with anyone."
-msgstr ""
+msgstr "%{gitlab_experience_text}. Vi deler ikke informationen med nogen."
msgid "%{global_id} is not a valid ID for %{expected_types}."
-msgstr ""
+msgstr "%{global_id} er ikke et gyldigt id til %{expected_types}."
msgid "%{group_name} activity"
msgstr ""
@@ -590,139 +598,139 @@ msgid "%{group_name} group members"
msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
-msgstr ""
+msgstr "%{group_name} bruger gruppehåndterede kontoer. Du skal oprette en ny GitLab-konto som håndteres af %{group_name}."
msgid "%{group_name}&%{epic_iid} &middot; created %{epic_created} by %{author}"
-msgstr ""
+msgstr "%{group_name}&%{epic_iid} &middot; oprettede %{epic_created} af %{author}"
msgid "%{hook_type} was deleted"
-msgstr ""
+msgstr "%{hook_type} blev slettet"
msgid "%{hook_type} was scheduled for deletion"
-msgstr ""
+msgstr "%{hook_type} blev planlagt til sletning"
msgid "%{host} sign-in from new location"
-msgstr ""
+msgstr "Indlogning på %{host} fra ny placering"
msgid "%{integrations_link_start}Integrations%{link_end} enable you to make third-party applications part of your GitLab workflow. If the available integrations don't meet your needs, consider using a %{webhooks_link_start}webhook%{link_end}."
-msgstr ""
+msgstr "%{integrations_link_start}Integreringer%{link_end} giver dig mulighed for at gøre programmer fra tredjepart en del af dit GitLab-workflow. Hvis de tilgængelige integreringer ikke opfylder dine behov, så overvej at bruge en %{webhooks_link_start}webhook%{link_end}."
msgid "%{issuableType} will be removed! Are you sure?"
-msgstr ""
+msgstr "%{issuableType} fjernes! Er du sikker?"
msgid "%{issueType} actions"
msgstr ""
msgid "%{issuesCount} issues with a limit of %{maxIssueCount}"
-msgstr ""
+msgstr "%{issuesCount} problemstillinger med en grænse på %{maxIssueCount}"
msgid "%{issuesSize} with a limit of %{maxIssueCount}"
-msgstr ""
+msgstr "%{issuesSize} med en grænse på %{maxIssueCount}"
msgid "%{italic_start}What's new%{italic_end} is inactive and cannot be viewed."
-msgstr ""
+msgstr "%{italic_start}Nyheder%{italic_end} er inaktiv og kan ikke vises."
msgid "%{itemsCount} issues with a limit of %{maxIssueCount}"
-msgstr ""
+msgstr "%{itemsCount} problemstillinger med en grænse på %{maxIssueCount}"
msgid "%{labelStart}Actual response:%{labelEnd} %{headers}"
-msgstr ""
+msgstr "%{labelStart}Faktiske svar:%{labelEnd} %{headers}"
msgid "%{labelStart}Assert:%{labelEnd} %{assertion}"
msgstr ""
msgid "%{labelStart}Class:%{labelEnd} %{class}"
-msgstr ""
+msgstr "%{labelStart}Klasse:%{labelEnd} %{class}"
msgid "%{labelStart}Crash Address:%{labelEnd} %{crash_address}"
-msgstr ""
+msgstr "%{labelStart}Nedbrudsadresse:%{labelEnd} %{crash_address}"
msgid "%{labelStart}Crash State:%{labelEnd} %{stacktrace_snippet}"
-msgstr ""
+msgstr "%{labelStart}Nedbrudstilstand:%{labelEnd} %{stacktrace_snippet}"
msgid "%{labelStart}Evidence:%{labelEnd} %{evidence}"
-msgstr ""
+msgstr "%{labelStart}Bevis:%{labelEnd} %{evidence}"
msgid "%{labelStart}File:%{labelEnd} %{file}"
-msgstr ""
+msgstr "%{labelStart}Fil:%{labelEnd} %{file}"
msgid "%{labelStart}Image:%{labelEnd} %{image}"
-msgstr ""
+msgstr "%{labelStart}Billede:%{labelEnd} %{image}"
msgid "%{labelStart}Method:%{labelEnd} %{method}"
-msgstr ""
+msgstr "%{labelStart}Metode:%{labelEnd} %{method}"
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
-msgstr ""
-
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
+msgstr "%{labelStart}Navnerum:%{labelEnd} %{namespace}"
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
-msgstr ""
+msgstr "%{labelStart}Skanner:%{labelEnd} %{scanner}"
msgid "%{labelStart}Sent request:%{labelEnd} %{headers}"
-msgstr ""
+msgstr "%{labelStart}Sendt anmodning:%{labelEnd} %{headers}"
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr "%{labelStart}Alvorlighed:%{labelEnd} %{severity}"
+
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
msgstr ""
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
-msgstr ""
+msgstr "%{labelStart}Uændret svar:%{labelEnd} %{headers}"
msgid "%{label_for_message} unavailable"
-msgstr ""
+msgstr "%{label_for_message} utilgængelig"
msgid "%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} is a free, automated, and open certificate authority (CA) that issues digital certificates to enable HTTPS (SSL/TLS) for sites."
-msgstr ""
+msgstr "%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} er en gratis automatiserede open source certifikatmyndighed (CA) som udsteder digitale certifikater for at gøre det muligt at bruge HTTPS (SSL/TLS) på websteder."
msgid "%{level_name} is not allowed in a %{group_level_name} group."
-msgstr ""
+msgstr "%{level_name} er ikke tilladt i en %{group_level_name}-gruppe."
msgid "%{level_name} is not allowed since the fork source project has lower visibility."
-msgstr ""
+msgstr "%{level_name} er ikke tilladt eftersom forgreningskildeprojektet har lavere synlighed."
msgid "%{link_start}Learn more%{link_end} about roles."
-msgstr ""
+msgstr "%{link_start}Lær mere%{link_end} om roller."
msgid "%{link_start}Learn more%{link_end} about what information is shared with GitLab Inc."
-msgstr ""
+msgstr "%{link_start}Lær mere%{link_end} om hvilken information der deles med GitLab Inc."
msgid "%{link_start}Remove the %{draft_snippet} prefix%{link_end} from the title to allow this merge request to be merged when it's ready."
-msgstr ""
+msgstr "%{link_start}Fjern præfikset %{draft_snippet}%{link_end} fra titlen, når den er klar, for at give tilladelse til at sammenlægningsanmodningen kan sammenlægges."
msgid "%{link_start}Start the title with %{draft_snippet}%{link_end} to prevent a merge request that is a work in progress from being merged before it's ready."
-msgstr ""
+msgstr "%{link_start}Start titlen med %{draft_snippet}%{link_end} for at forhindre en sammenlægningsanmodning der er under udarbejdelse i at blive sammenlagt før den er klar."
msgid "%{listToShow}, and %{awardsListLength} more"
-msgstr ""
+msgstr "%{listToShow} og %{awardsListLength} mere"
msgid "%{location} is missing required keys: %{keys}"
-msgstr ""
+msgstr "%{location} mangler krævede nøgler: %{keys}"
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
-msgstr ""
+msgstr "%{lock_path} er låst af GitLab-brugeren %{lock_user_id}"
msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
-msgstr ""
+msgstr "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} og %{quickActionsDocsLinkStart}hurtige handlinger%{quickActionsDocsLinkEnd} understøttes"
msgid "%{mergeLength}/%{usersLength} can merge"
-msgstr ""
+msgstr "%{mergeLength}/%{usersLength} kan sammenlægge"
msgid "%{message} showing first %{warnings_displayed}"
-msgstr ""
+msgstr "%{message} viser første %{warnings_displayed}"
msgid "%{milestone} (expired)"
-msgstr ""
+msgstr "%{milestone} (udløbet)"
msgid "%{milliseconds}ms"
-msgstr ""
+msgstr "%{milliseconds} ms"
msgid "%{model_name} not found"
-msgstr ""
+msgstr "%{model_name} ikke fundet"
msgid "%{mrText}, this issue will be closed automatically."
-msgstr ""
+msgstr "%{mrText}, problemstillingen lukkes automatisk."
msgid "%{name_with_link} namespace has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
msgstr ""
@@ -731,22 +739,22 @@ msgid "%{name_with_link} namespace has run out of Shared Runner Pipeline minutes
msgstr ""
msgid "%{name} (Busy)"
-msgstr ""
+msgstr "%{name} (optaget)"
msgid "%{name} contained %{resultsString}"
-msgstr ""
+msgstr "%{name} indeholdte %{resultsString}"
msgid "%{name} found %{resultsString}"
-msgstr ""
+msgstr "%{name} fandt %{resultsString}"
msgid "%{name} is already being used for another emoji"
-msgstr ""
+msgstr "%{name} bruges allerede af en anden emoji"
msgid "%{name} is scheduled for %{action}"
-msgstr ""
+msgstr "%{name} er planlagt til %{action}"
msgid "%{name}'s avatar"
-msgstr ""
+msgstr "%{name}s avatar"
msgid "%{name}(%{url}) namespace has %{percent} or less Shared Runner Pipeline minutes remaining. After it runs out, no new jobs or pipelines in its projects will run."
msgstr ""
@@ -755,54 +763,54 @@ msgid "%{name}(%{url}) namespace has run out of Shared Runner Pipeline minutes s
msgstr ""
msgid "%{name}, confirm your email address now!"
-msgstr ""
+msgstr "%{name}, bekræft din e-mailadresse nu!"
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{no_of_days} dag"
+msgstr[1] "%{no_of_days} dage"
msgid "%{number_commits_behind} commits behind %{default_branch}, %{number_commits_ahead} commits ahead"
-msgstr ""
+msgstr "%{number_commits_behind} commits bagefter %{default_branch}, %{number_commits_ahead} commits foran"
msgid "%{oneMonthAgo} - %{today}"
-msgstr ""
+msgstr "%{oneMonthAgo} - %{today}"
msgid "%{oneWeekAgo} - %{today}"
-msgstr ""
+msgstr "%{oneWeekAgo} - %{today}"
msgid "%{oneYearAgo} - %{today}"
-msgstr ""
+msgstr "%{oneYearAgo} - %{today}"
msgid "%{openOrClose} %{noteable}"
-msgstr ""
+msgstr "%{openOrClose} %{noteable}"
msgid "%{openedEpics} open, %{closedEpics} closed"
-msgstr ""
+msgstr "%{openedEpics} åbne, %{closedEpics} lukkede"
msgid "%{openedIssues} open, %{closedIssues} closed"
-msgstr ""
+msgstr "%{openedIssues} åbne, %{closedIssues} lukkede"
msgid "%{percentage}%% weight completed"
-msgstr ""
+msgstr "%{percentage}%% vægt fuldført"
msgid "%{percent}%% complete"
-msgstr ""
+msgstr "%{percent}%% fuldført"
msgid "%{percent}%{percentSymbol} complete"
-msgstr ""
+msgstr "%{percent} %{percentSymbol} fuldført"
msgid "%{placeholder} is not a valid color scheme"
-msgstr ""
+msgstr "%{placeholder} er ikke et gyldigt farveskema"
msgid "%{placeholder} is not a valid theme"
-msgstr ""
+msgstr "%{placeholder} er ikke et gyldigt tema"
msgid "%{primary} (%{secondary})"
-msgstr ""
+msgstr "%{primary} (%{secondary})"
msgid "%{ref} cannot be added: %{error}"
-msgstr ""
+msgstr "%{ref} kan ikke tilføjes: %{error}"
msgid "%{releases} release"
msgid_plural "%{releases} releases"
@@ -810,19 +818,19 @@ msgstr[0] ""
msgstr[1] ""
msgid "%{remaining_approvals} left"
-msgstr ""
+msgstr "%{remaining_approvals} tilbage"
msgid "%{reportType} %{status}"
-msgstr ""
+msgstr "%{reportType} %{status}"
msgid "%{reportType} detected %{totalStart}%{total}%{totalEnd} potential %{vulnMessage}"
-msgstr ""
+msgstr "%{reportType} registrerede %{totalStart}%{total}%{totalEnd} potientielle %{vulnMessage}"
msgid "%{reportType} detected %{totalStart}no%{totalEnd} vulnerabilities."
-msgstr ""
+msgstr "%{reportType} registrerede %{totalStart}ingen%{totalEnd} sårbarheder."
msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}."
-msgstr ""
+msgstr "%{retryButtonStart}Prøv igen%{retryButtonEnd} eller %{newFileButtonStart}vedhæft en ny fil%{newFileButtonEnd}."
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation_link}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
@@ -830,13 +838,16 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
-msgid "%{seconds}s"
+msgid "%{scope} results for term '%{term}'"
msgstr ""
+msgid "%{seconds}s"
+msgstr "%{seconds} s"
+
msgid "%{securityScanner} is not enabled for this project. %{linkStart}More information%{linkEnd}"
msgid_plural "%{securityScanner} are not enabled for this project. %{linkStart}More information%{linkEnd}"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{securityScanner} er ikke aktiveret til projektet. %{linkStart}Mere information%{linkEnd}"
+msgstr[1] "%{securityScanner} er ikke aktiveret til projektet. %{linkStart}Mere information%{linkEnd}"
msgid "%{securityScanner} result is not available because a pipeline has not been run since it was enabled. %{linkStart}Run a pipeline%{linkEnd}"
msgid_plural "%{securityScanner} results are not available because a pipeline has not been run since it was enabled. %{linkStart}Run a pipeline%{linkEnd}"
@@ -844,37 +855,37 @@ msgstr[0] ""
msgstr[1] ""
msgid "%{service_ping_link_start}Learn more%{service_ping_link_end} about what information is shared with GitLab Inc."
-msgstr ""
+msgstr "%{service_ping_link_start}Lær mere%{service_ping_link_end} om hvilken information der deles med GitLab Inc."
msgid "%{size} %{unit}"
-msgstr ""
+msgstr "%{size} %{unit}"
msgid "%{size} GiB"
-msgstr ""
+msgstr "%{size} GiB"
msgid "%{size} KiB"
-msgstr ""
+msgstr "%{size} KiB"
msgid "%{size} MiB"
-msgstr ""
+msgstr "%{size} MiB"
msgid "%{size} bytes"
-msgstr ""
+msgstr "%{size} byte"
msgid "%{sourceBranch} into %{targetBranch}"
-msgstr ""
+msgstr "%{sourceBranch} ind i %{targetBranch}"
msgid "%{spammable_titlecase} was submitted to Akismet successfully."
-msgstr ""
+msgstr "%{spammable_titlecase} blev indsendt til Akismet."
msgid "%{spanStart}at line%{spanEnd} %{errorLine}%{errorColumn}"
-msgstr ""
+msgstr "%{spanStart}på linje%{spanEnd} %{errorLine}%{errorColumn}"
msgid "%{spanStart}in%{spanEnd} %{errorFn}"
-msgstr ""
+msgstr "%{spanStart}i%{spanEnd} %{errorFn}"
msgid "%{start} to %{end}"
-msgstr ""
+msgstr "%{start} til %{end}"
msgid "%{state} epics"
msgstr ""
@@ -884,59 +895,59 @@ msgstr ""
msgid "%{strong_start}%{branch_count}%{strong_end} Branch"
msgid_plural "%{strong_start}%{branch_count}%{strong_end} Branches"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{strong_start}%{branch_count}%{strong_end} gren"
+msgstr[1] "%{strong_start}%{branch_count}%{strong_end} grene"
msgid "%{strong_start}%{commit_count}%{strong_end} Commit"
msgid_plural "%{strong_start}%{commit_count}%{strong_end} Commits"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{strong_start}%{commit_count}%{strong_end} commit"
+msgstr[1] "%{strong_start}%{commit_count}%{strong_end} commits"
msgid "%{strong_start}%{count} approval rule%{strong_end} requires eligible members to approve before merging."
msgid_plural "%{strong_start}%{count} approval rules%{strong_end} require eligible members to approve before merging."
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{strong_start}%{count} godkendelsesregel%{strong_end} kræver godkendelse fra berettigede medlemmer inden sammenlægning."
+msgstr[1] "%{strong_start}%{count} godkendelsesregler%{strong_end} kræver godkendelse fra berettigede medlemmer inden sammenlægning."
msgid "%{strong_start}%{count} eligible member%{strong_end} must approve to merge."
msgid_plural "%{strong_start}%{count} eligible members%{strong_end} must approve to merge."
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{strong_start}%{count} berettigede medlem%{strong_end} skal godkende for at sammenlægge."
+msgstr[1] "%{strong_start}%{count} berettigede medlemmer%{strong_end} skal godkende for at sammenlægge."
msgid "%{strong_start}%{count} member%{strong_end} must approve to merge. Anyone with role Developer or higher can approve."
msgid_plural "%{strong_start}%{count} members%{strong_end} must approve to merge. Anyone with role Developer or higher can approve."
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{strong_start}%{count} medlem%{strong_end} skal godkende for at sammenlægge. Alle med rollen Udvikler eller højere kan godkende."
+msgstr[1] "%{strong_start}%{count} medlemmer%{strong_end} skal godkende for at sammenlægge. Alle med rollen Udvikler eller højere kan godkende."
msgid "%{strong_start}%{human_size}%{strong_end} Files"
-msgstr ""
+msgstr "%{strong_start}%{human_size}%{strong_end} filer"
msgid "%{strong_start}%{human_size}%{strong_end} Storage"
-msgstr ""
+msgstr "%{strong_start}%{human_size}%{strong_end} lager"
msgid "%{strong_start}%{release_count}%{strong_end} Release"
msgid_plural "%{strong_start}%{release_count}%{strong_end} Releases"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{strong_start}%{release_count}%{strong_end} udgivelse"
+msgstr[1] "%{strong_start}%{release_count}%{strong_end} udgivelser"
msgid "%{strong_start}%{tag_count}%{strong_end} Tag"
msgid_plural "%{strong_start}%{tag_count}%{strong_end} Tags"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{strong_start}%{tag_count}%{strong_end} mærkat"
+msgstr[1] "%{strong_start}%{tag_count}%{strong_end} mærkater"
msgid "%{tabname} changed"
-msgstr ""
+msgstr "%{tabname} ændret"
msgid "%{tags} tag per image name"
-msgstr ""
+msgstr "%{tags} mærkat pr. billednavn"
msgid "%{tags} tags per image name"
-msgstr ""
+msgstr "%{tags} mærkater pr. billednavn"
msgid "%{tag}-%{evidence}-%{filename}"
-msgstr ""
+msgstr "%{tag}-%{evidence}-%{filename}"
msgid "%{template_project_id} is unknown or invalid"
-msgstr ""
+msgstr "%{template_project_id} er ukendt eller ugyldigt"
msgid "%{text} %{files}"
msgid_plural "%{text} %{files} files"
@@ -944,490 +955,490 @@ msgstr[0] ""
msgstr[1] ""
msgid "%{text} is available"
-msgstr ""
+msgstr "%{text} er tilgængelig"
msgid "%{timebox_name} should belong either to a project or a group."
-msgstr ""
+msgstr "%{timebox_name} skal enten tilhøre et projekt eller en gruppe."
msgid "%{timebox_type} does not support burnup charts"
msgstr ""
msgid "%{timebox_type} must have a start and due date"
-msgstr ""
+msgstr "%{timebox_type} skal have en start- og forfaldsdato"
msgid "%{title} %{operator} %{threshold}"
-msgstr ""
+msgstr "%{title} %{operator} %{threshold}"
msgid "%{title} changes"
-msgstr ""
+msgstr "%{title} ændringer"
msgid "%{totalCpu} (%{freeSpacePercentage}%{percentSymbol} free)"
-msgstr ""
+msgstr "%{totalCpu} (%{freeSpacePercentage} %{percentSymbol} ledig)"
msgid "%{totalMemory} (%{freeSpacePercentage}%{percentSymbol} free)"
-msgstr ""
+msgstr "%{totalMemory} (%{freeSpacePercentage} %{percentSymbol} ledig)"
msgid "%{totalWeight} total weight"
-msgstr ""
+msgstr "%{totalWeight} vægt i alt"
msgid "%{total_warnings} warning(s) found:"
-msgstr ""
+msgstr "%{total_warnings} advarsler fundet:"
msgid "%{total} open issue weight"
msgstr ""
msgid "%{total} warnings found: showing first %{warningsDisplayed}"
-msgstr ""
+msgstr "%{total} advarsler fundet: viser første %{warningsDisplayed}"
msgid "%{userName} (cannot merge)"
-msgstr ""
+msgstr "%{userName} (kan ikke sammenlægge)"
msgid "%{userName}'s avatar"
-msgstr ""
+msgstr "%{userName}s avatar"
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
-msgstr ""
+msgstr "%{user_name} (%{user_username}) blev fjernet fra %{rotation} i %{schedule} i %{project}. "
msgid "%{user_name} profile page"
msgstr ""
msgid "%{username} changed the draft status of merge request %{mr_link}"
-msgstr ""
+msgstr "%{username} ændrede udkaststatussen på sammenlægningsanmodningen %{mr_link}"
msgid "%{username} has asked for a GitLab account on your instance %{host}:"
-msgstr ""
+msgstr "%{username} har spurgt om en GitLab-konto på din instans %{host}:"
msgid "%{username}'s avatar"
-msgstr ""
+msgstr "%{username}s avatar"
msgid "%{user} created a merge request: %{mr_link}"
-msgstr ""
+msgstr "%{user} oprettede en sammenlægningsanmodning: %{mr_link}"
msgid "%{user} created an epic: %{epic_link}"
-msgstr ""
+msgstr "%{user} oprettede en epic: %{epic_link}"
msgid "%{user} created an issue: %{issue_link}"
-msgstr ""
+msgstr "%{user} oprettede en problemstilling: %{issue_link}"
msgid "%{value} is not included in the list"
-msgstr ""
+msgstr "%{value} er ikke med på listen"
msgid "%{value} s"
-msgstr ""
+msgstr "%{value} s"
msgid "%{verb} %{time_spent_value} spent time."
-msgstr ""
+msgstr "%{verb} %{time_spent_value} brugt tid."
msgid "%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notifications to web applications in response to events in a group or project."
-msgstr ""
+msgstr "%{webhooks_link_start}%{webhook_type}%{link_end} gør det muligt for dig at sende underretninger til webprogrammer som svar til begivenheder i en gruppe eller et projekt."
msgid "%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notifications to web applications in response to events in a group or project. We recommend using an %{integrations_link_start}integration%{link_end} in preference to a webhook."
-msgstr ""
+msgstr "%{webhooks_link_start}%{webhook_type}%{link_end} gør det muligt for dig at sende underretninger til webprogrammer som svar til begivenheder i en gruppe eller et projekt. Vi anbefaler at bruge en %{integrations_link_start}integrering%{link_end} i stedet for en webhook."
msgid "%{wildcards_link_start}Wildcards%{wildcards_link_end} such as %{code_tag_start}v*%{code_tag_end} or %{code_tag_start}*-release%{code_tag_end} are supported."
-msgstr ""
+msgstr "%{wildcards_link_start}Jokertegn%{wildcards_link_end} såsom %{code_tag_start}v*%{code_tag_end} eller %{code_tag_start}*-release%{code_tag_end} understøttes."
msgid "&lt; 1 hour"
-msgstr ""
+msgstr "&lt; 1 time"
msgid "'%{data}' at %{location} does not match format: %{format}"
-msgstr ""
+msgstr "'%{data}' på %{location} passer ikke til formatet: %{format}"
msgid "'%{data}' at %{location} does not match pattern: %{pattern}"
-msgstr ""
+msgstr "'%{data}' på %{location} passer ikke til mønsteret: %{pattern}"
msgid "'%{data}' at %{location} is invalid: error_type=%{type}"
-msgstr ""
+msgstr "'%{data}' på %{location} er ugyldig: error_type=%{type}"
msgid "'%{data}' at %{location} is not of type: %{type}"
-msgstr ""
+msgstr "'%{data}' på %{location} er ikke af typen: %{type}"
msgid "'%{data}' at %{location} is not one of: %{enum}"
-msgstr ""
+msgstr "'%{data}' på %{location} er ikke en af: %{enum}"
msgid "'%{data}' at %{location} is not: %{const}"
-msgstr ""
+msgstr "'%{data}' på %{location} er ikke: %{const}"
msgid "'%{level}' is not a valid visibility level"
-msgstr ""
+msgstr "'%{level}' er ikke et gyldigt synlighedsniveau"
msgid "'%{name}' Value Stream created"
-msgstr ""
+msgstr "'%{name}' Value Stream oprettet"
msgid "'%{name}' Value Stream deleted"
-msgstr ""
+msgstr "'%{name}' Value Stream slettet"
msgid "'%{name}' Value Stream saved"
-msgstr ""
+msgstr "'%{name}' Value Stream gemt"
msgid "'%{source}' is not a import source"
-msgstr ""
+msgstr "'%{source}' er ikke en importkilde"
msgid "'%{template_name}' is unknown or invalid"
-msgstr ""
+msgstr "'%{template_name}' er ukendt eller ugyldigt"
msgid "(%d closed)"
msgid_plural "(%d closed)"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "(%d lukket)"
+msgstr[1] "(%d lukket)"
msgid "(%{mrCount} merged)"
-msgstr ""
+msgstr "(%{mrCount} sammenlagt)"
msgid "(%{value}) has already been taken"
-msgstr ""
+msgstr "(%{value}) er allerede taget"
msgid "(+%{count}&nbsp;rules)"
-msgstr ""
+msgstr "(+%{count}&nbsp;regler)"
msgid "(Group Managed Account)"
-msgstr ""
+msgstr "(gruppehåndteret konto)"
msgid "(No changes)"
-msgstr ""
+msgstr "(ingen ændringer)"
msgid "(UTC %{offset}) %{timezone}"
-msgstr ""
+msgstr "(UTC %{offset}) %{timezone}"
msgid "(check progress)"
-msgstr ""
+msgstr "(tjek forløb)"
msgid "(deleted)"
-msgstr ""
+msgstr "(slettet)"
msgid "(expired)"
-msgstr ""
+msgstr "(udløbet)"
msgid "(leave blank if you don't want to change it)"
-msgstr ""
+msgstr "(lad den være tom hvis du ikke vil ændre den)"
msgid "(max size 15 MB)"
-msgstr ""
+msgstr "(maks. størrelse 15 MB)"
msgid "(removed)"
-msgstr ""
+msgstr "(fjernet)"
msgid "(revoked)"
-msgstr ""
+msgstr "(tilbagekaldt)"
msgid "(we need your current password to confirm your changes)"
-msgstr ""
+msgstr "(vi har brug for din nuværende adgangskode for at bekræfte dine ændringer)"
msgid "* * * * *"
-msgstr ""
+msgstr "* * * * *"
msgid "+ %{amount} more"
-msgstr ""
+msgstr "+ %{amount} mere"
msgid "+ %{count} more"
-msgstr ""
+msgstr "+ %{count} mere"
msgid "+ %{moreCount} more"
-msgstr ""
+msgstr "+ %{moreCount} mere"
msgid "+ %{numberOfHiddenAssignees} more"
-msgstr ""
+msgstr "+ %{numberOfHiddenAssignees} mere"
msgid "+%d more"
msgid_plural "+%d more"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "+%d mere"
+msgstr[1] "+%d mere"
msgid "+%{approvers} more approvers"
-msgstr ""
+msgstr "+%{approvers} flere godkendere"
msgid "+%{extra} more"
-msgstr ""
+msgstr "+%{extra} mere"
msgid "+%{more_assignees_count}"
-msgstr ""
+msgstr "+%{more_assignees_count}"
msgid "+%{more_assignees_count} more assignees"
-msgstr ""
+msgstr "+%{more_assignees_count} tildelte mere"
msgid "+%{more_reviewers_count}"
-msgstr ""
+msgstr "+%{more_reviewers_count}"
msgid "+%{more_reviewers_count} more reviewers"
-msgstr ""
+msgstr "+%{more_reviewers_count} kontrollanter mere"
msgid "+%{tags} more"
-msgstr ""
+msgstr "+%{tags} mere"
msgid ", or "
-msgstr ""
+msgstr " eller "
msgid "- Available to run jobs."
-msgstr ""
+msgstr "- Tilgængelig til at køre jobs."
msgid "- Event"
msgid_plural "- Events"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "- Begivenhed"
+msgstr[1] "- Begivenheder"
msgid "- Not available to run jobs."
-msgstr ""
+msgstr "- Ikke tilgængelig til at køre jobs."
msgid "- User"
msgid_plural "- Users"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "- Bruger"
+msgstr[1] "- Brugere"
msgid "- of - weight completed"
-msgstr ""
+msgstr "- af - vægt fuldført"
msgid "- show less"
-msgstr ""
+msgstr "- vis mindre"
msgid "."
-msgstr ""
+msgstr "."
msgid "0 bytes"
-msgstr ""
+msgstr "0 byte"
msgid "0 for unlimited, only effective with remote storage enabled."
-msgstr ""
+msgstr "0 for ubegrænset, kun gældende når fjernlager er aktiveret."
msgid "0t1DgySidms"
-msgstr ""
+msgstr "0t1DgySidms"
msgid "1 Day"
msgid_plural "%d Days"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 dag"
+msgstr[1] "%d dage"
msgid "1 Issue"
msgid_plural "%d Issues"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 problemstilling"
+msgstr[1] "%d problemstillinger"
msgid "1 closed issue"
msgid_plural "%{issues} closed issues"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 lukket problemstilling"
+msgstr[1] "%{issues} lukkede problemstillinger"
msgid "1 closed merge request"
msgid_plural "%{merge_requests} closed merge requests"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 lukket sammenlægningsanmodning"
+msgstr[1] "%{merge_requests} lukket sammenlægningsanmodninger"
msgid "1 day"
msgid_plural "%d days"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 dag"
+msgstr[1] "%d dage"
msgid "1 day remaining"
msgid_plural "%d days remaining"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 dag tilbage"
+msgstr[1] "%d dage tilbage"
msgid "1 day selected"
msgid_plural "%d days selected"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 dag valgt"
+msgstr[1] "%d dage valgte"
msgid "1 deploy key"
msgid_plural "%d deploy keys"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 udsendelsesnøgle"
+msgstr[1] "%d udsendelsesnøgler"
msgid "1 follower"
msgid_plural "%{count} followers"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 følger"
+msgstr[1] "%{count} følgere"
msgid "1 group"
msgid_plural "%d groups"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 gruppe"
+msgstr[1] "%d grupper"
msgid "1 hour"
msgid_plural "%d hours"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 time"
+msgstr[1] "%d timer"
msgid "1 issue selected"
msgid_plural "%d issues selected"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 problemstilling valgt"
+msgstr[1] "%d problemstillinger valgt"
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
-msgstr[0] ""
-msgstr[1] ""
+msgid_plural "%d merge requests selected"
+msgstr[0] "1 sammenlægningsanmodning valgt"
+msgstr[1] "%d sammenlægningsanmodninger valgt"
msgid "1 merged merge request"
msgid_plural "%{merge_requests} merged merge requests"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 sammenlagt sammenlægningsanmodning"
+msgstr[1] "%{merge_requests} sammenlagte sammenlægningsanmodninger"
msgid "1 minute"
msgid_plural "%d minutes"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 minut"
+msgstr[1] "%d minutter"
msgid "1 month remaining"
msgid_plural "%d months remaining"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 måned tilbage"
+msgstr[1] "%d måneder tilbage"
msgid "1 open issue"
msgid_plural "%{issues} open issues"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 åben problemstilling"
+msgstr[1] "%{issues} åbne problemstillinger"
msgid "1 open merge request"
msgid_plural "%{merge_requests} open merge requests"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 åben sammenlægningsanmodning"
+msgstr[1] "%{merge_requests} åbne sammenlægningsanmodninger"
msgid "1 pipeline"
msgid_plural "%d pipelines"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 pipeline"
+msgstr[1] "%d pipelines"
msgid "1 role"
msgid_plural "%d roles"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 rolle"
+msgstr[1] "%d roller"
msgid "1 user"
msgid_plural "%{num} users"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 bruger"
+msgstr[1] "%{num} brugere"
msgid "1 week remaining"
msgid_plural "%d weeks remaining"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 uge tilbage"
+msgstr[1] "%d uger tilbage"
msgid "1 year remaining"
msgid_plural "%d years remaining"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 år tilbage"
+msgstr[1] "%d år tilbage"
msgid "1-9 contributions"
-msgstr ""
+msgstr "1-9 bidrag"
msgid "10-19 contributions"
-msgstr ""
+msgstr "10-19 bidrag"
msgid "1000+"
-msgstr ""
+msgstr "1000+"
msgid "1st contribution!"
-msgstr ""
+msgstr "Første bidrag!"
msgid "20-29 contributions"
-msgstr ""
+msgstr "20-29 bidrag"
msgid "2FA"
-msgstr ""
+msgstr "2FG"
msgid "2FADevice|Registered On"
-msgstr ""
+msgstr "Registreret"
msgid "3 days"
-msgstr ""
+msgstr "3 dage"
msgid "3 hours"
-msgstr ""
+msgstr "3 timer"
msgid "30 days"
-msgstr ""
+msgstr "30 dage"
msgid "30 minutes"
-msgstr ""
+msgstr "30 minutter"
msgid "30+ contributions"
-msgstr ""
+msgstr "30+ bidrag"
msgid "403|Please contact your GitLab administrator to get permission."
-msgstr ""
+msgstr "Kontakt venligst din GitLab-administrator for at få tilladelse."
msgid "403|You don't have the permission to access this page."
-msgstr ""
+msgstr "Du har ikke tilladelse til at tilgå siden."
msgid "404|Make sure the address is correct and the page hasn't moved."
-msgstr ""
+msgstr "Sørg for at adressen er korrekt og at siden ikke er flyttet."
msgid "404|Page Not Found"
-msgstr ""
+msgstr "Side ikke fundet"
msgid "404|Please contact your GitLab administrator if you think this is a mistake."
-msgstr ""
+msgstr "Kontakt venligst din GitLab-administrator, hvis du mener, at det er en fejltagelse."
msgid "7 days"
-msgstr ""
+msgstr "7 dage"
msgid "8 hours"
-msgstr ""
+msgstr "8 timer"
msgid ":%{startLine} to %{endLine}"
-msgstr ""
+msgstr ":%{startLine} til %{endLine}"
msgid "A %{incident_docs_start}modified issue%{incident_docs_end} to guide the resolution of incidents."
-msgstr ""
+msgstr "En %{incident_docs_start}ændret problemstilling%{incident_docs_end} til at vejlede løsningen af hændelser."
msgid "A .NET Core console application template, customizable for any .NET Core project"
-msgstr ""
+msgstr "En .NET Core-konsolprogramskabelon, der kan tilpasses til ethvert .NET Core-projekt"
msgid "A CI/CD pipeline must run and be successful before merge."
-msgstr ""
+msgstr "En CI-/CD-pipeline skal køre og lykkedes inden sammenlægning."
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "Et GitBook-websted som bruger Netlify til CI/CD frem for GitLab, men stadigvæk med alle de andre gode GitLab-funktioner"
msgid "A Gitpod configured Webapplication in Spring and Java"
-msgstr ""
+msgstr "Et Gitpod-konfigureret webprogram i Spring og Java"
msgid "A Hexo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "Et Hexo-websted som bruger Netlify til CI/CD frem for GitLab, men stadigvæk med alle de andre gode GitLab-funktioner"
msgid "A Hugo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "Et Hugo-websted som bruger Netlify til CI/CD frem for GitLab, men stadigvæk med alle de andre gode GitLab-funktioner"
msgid "A Jekyll site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "Et Jekyll-websted som bruger Netlify til CI/CD frem for GitLab, men stadigvæk med alle de andre gode GitLab-funktioner"
msgid "A Let's Encrypt SSL certificate can not be obtained until your domain is verified."
-msgstr ""
+msgstr "Et Let's Encrypt SSL-certifikat kan ikke indhentes før dit domæne er bekræftet."
msgid "A Metrics Dashboard menu item appears in the Monitoring section of the Admin Area."
msgstr ""
msgid "A basic page and serverless function that uses AWS Lambda, AWS API Gateway, and GitLab Pages"
-msgstr ""
+msgstr "En grundlæggende side og serverfri funktion der bruger AWS Lambda, AWS API Gateway og GitLab Pages"
msgid "A basic template for developing Linux programs using Kotlin Native"
-msgstr ""
+msgstr "En grundlæggende skabelon til at udvikle Linux-programmer med Kotlin Native"
msgid "A complete DevOps platform"
-msgstr ""
+msgstr "En komplet DevOps-platform"
msgid "A default branch cannot be chosen for an empty project."
-msgstr ""
+msgstr "En standardgren kan ikke vælges til et tomt projekt."
msgid "A deleted user"
-msgstr ""
+msgstr "En slettet bruger"
msgid "A description is required"
-msgstr ""
+msgstr "En beskrivelse kræves"
msgid "A different reason"
-msgstr ""
+msgstr "En anden årsag"
msgid "A file has been changed."
-msgstr ""
+msgstr "En fil er blevet ændret."
msgid "A file was not found."
-msgstr ""
+msgstr "En fil blev ikke fundet."
msgid "A file with '%{file_name}' already exists in %{branch} branch"
-msgstr ""
+msgstr "Filen '%{file_name}' findes allerede i grenen %{branch}"
msgid "A group is a collection of several projects"
-msgstr ""
+msgstr "En gruppe er en samling af projekter"
msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
@@ -1436,16 +1447,16 @@ msgid "A job artifact is an archive of files and directories saved by a job when
msgstr ""
msgid "A limit of %{ci_project_subscriptions_limit} subscriptions to or from a project applies."
-msgstr ""
+msgstr "En grænse på %{ci_project_subscriptions_limit} abonnementer til eller fra et projekt gælder."
msgid "A management, operational, or technical control (that is, safeguard or countermeasure) employed by an organization that provides equivalent or comparable protection for an information system."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
-msgstr ""
+msgstr "Et medlem af misbrugsteamet gennemgår din rapport hurtigt muligt."
msgid "A merge request hasn't yet been merged"
-msgstr ""
+msgstr "En sammenlægningsanmodning er endnu ikke blevet sammenlagt"
msgid "A new Auto DevOps pipeline has been created, go to %{pipelines_link_start}Pipelines page%{pipelines_link_end} for details"
msgstr ""
@@ -1457,7 +1468,7 @@ msgid "A new Release %{tag} for %{name} was published. Visit the Releases page t
msgstr ""
msgid "A new branch will be created in your fork and a new merge request will be started."
-msgstr ""
+msgstr "Der oprettes en ny gren i din forgrening og en ny sammenlægningsanmodning startes."
msgid "A new impersonation token has been created."
msgstr ""
@@ -1466,13 +1477,13 @@ msgid "A non-confidential epic cannot be assigned to a confidential parent epic"
msgstr ""
msgid "A plain HTML site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "Et rent HTML-websted som bruger Netlify til CI/CD frem for GitLab, men stadigvæk med alle de andre gode GitLab-funktioner"
msgid "A plain-text response to show to clients that hit the rate limit."
msgstr ""
msgid "A platform value can be web, mob or app."
-msgstr ""
+msgstr "En platformværdi kan være web, mob eller app."
msgid "A project boilerplate for Salesforce App development with Salesforce Developer tools"
msgstr ""
@@ -1484,31 +1495,31 @@ msgid "A project’s repository name defines its URL (the one you use to access
msgstr ""
msgid "A ready-to-go template for use with Android apps"
-msgstr ""
+msgstr "En skabelon der er klar til brug med Android-programmer"
msgid "A ready-to-go template for use with iOS Swift apps"
-msgstr ""
+msgstr "En skabelon der er klar til brug med iOS Swift-programmer"
msgid "A rebase is already in progress."
-msgstr ""
+msgstr "En rebase er allerede i gang."
msgid "A sign-in to your account has been made from the following IP address: %{ip}"
-msgstr ""
+msgstr "Der blev logget ind på din konto fra følgende IP-adresse: %{ip}"
msgid "A string appended to the project path to form the Service Desk email address."
msgstr ""
msgid "A title is required"
-msgstr ""
+msgstr "En titel kræves"
msgid "A user with write access to the source branch selected this option"
-msgstr ""
+msgstr "En bruger med skriveadgang til kildegrenen valgte valgmuligheden"
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
-msgstr ""
+msgstr "HANDLING KRÆVES: Noget gik galt under indhentning af Let's Encrypt-certifikatet til GitLab Pages-domænet '%{domain}'"
msgid "API"
-msgstr ""
+msgstr "API"
msgid "API Fuzzing"
msgstr ""
@@ -1517,21 +1528,21 @@ msgid "API Fuzzing Configuration"
msgstr ""
msgid "API Help"
-msgstr ""
+msgstr "Hjælp for API"
msgid "API Token"
-msgstr ""
+msgstr "API-token"
msgid "API key"
-msgstr ""
+msgstr "API-nøgle"
msgid "API?"
-msgstr ""
+msgstr "API?"
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1541,13 +1552,13 @@ msgid "APIFuzzing|Base URL of API testing target. For example, http://www.exampl
msgstr ""
msgid "APIFuzzing|Choose a method"
-msgstr ""
+msgstr "Vælg en metode"
msgid "APIFuzzing|Choose a profile"
-msgstr ""
+msgstr "Vælg en profil"
msgid "APIFuzzing|Code snippet could not be generated. Try again later."
-msgstr ""
+msgstr "Kodeuddrag kunne ikke genereres. Prøv igen senere."
msgid "APIFuzzing|Configure HTTP basic authentication values. Other authentication methods are supported. %{linkStart}Learn more%{linkEnd}."
msgstr ""
@@ -1556,12 +1567,12 @@ msgid "APIFuzzing|Customize common API fuzzing settings to suit your requirement
msgstr ""
msgid "APIFuzzing|Enable authentication"
-msgstr ""
+msgstr "Aktivér godkendelse"
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -1574,40 +1585,40 @@ msgid "APIFuzzing|File path or URL to requests to be tested. For example, folder
msgstr ""
msgid "APIFuzzing|Generate code snippet"
-msgstr ""
+msgstr "Generer kodeuddrag"
msgid "APIFuzzing|Make sure your credentials are secured"
-msgstr ""
+msgstr "Sørg for at dine loginoplysninger er sikret"
msgid "APIFuzzing|Password for basic authentication"
-msgstr ""
+msgstr "Adgangskode til grundlæggende godkendelse"
msgid "APIFuzzing|Predefined profiles"
-msgstr ""
+msgstr "Prædefinerede profiler"
msgid "APIFuzzing|Scan mode"
-msgstr ""
+msgstr "Skanningstilstand"
msgid "APIFuzzing|Scan profile"
msgstr ""
msgid "APIFuzzing|Show code snippet for the profile"
-msgstr ""
+msgstr "Vis kodeuddrag for profilen"
msgid "APIFuzzing|Target URL"
-msgstr ""
+msgstr "MÃ¥l-URL"
msgid "APIFuzzing|There are three ways to perform scans."
-msgstr ""
+msgstr "Der findes tre måder til at udføre skanninger."
msgid "APIFuzzing|Tip: Insert the following variables anywhere below stages and include"
-msgstr ""
+msgstr "Tip: indsæt følgende variabler et vilkårligt sted nedenunder stages og include"
msgid "APIFuzzing|Tip: Insert this part below all include"
-msgstr ""
+msgstr "Tip: indsæt denne del nedenunder alle include"
msgid "APIFuzzing|Tip: Insert this part below all stages"
-msgstr ""
+msgstr "Tip: indsæt denne del nedenunder alle stages"
msgid "APIFuzzing|To prevent a security leak, authentication info must be added as a %{ciVariablesLinkStart}CI variable%{ciVariablesLinkEnd}. A user with maintainer access rights can manage CI variables in the %{ciSettingsLinkStart}Settings%{ciSettingsLinkEnd} area. We detected that you are not a maintainer. Commit your changes and assign them to a maintainer to update the credentials before merging."
msgstr ""
@@ -1619,10 +1630,10 @@ msgid "APIFuzzing|Use this tool to generate API fuzzing configuration YAML to co
msgstr ""
msgid "APIFuzzing|Username for basic authentication"
-msgstr ""
+msgstr "Brugernavn for grundlæggende godkendelse"
msgid "APIFuzzing|You may need a maintainer's help to secure your credentials."
-msgstr ""
+msgstr "Det kan være du skal have hjælp fra en vedligeholder for at sikre dine loginoplysninger."
msgid "APIFuzzing|folder/example.postman_collection.json"
msgstr ""
@@ -1631,7 +1642,7 @@ msgid "APIFuzzing|folder/example_fuzz.har"
msgstr ""
msgid "APIFuzzing|folder/openapi.json"
-msgstr ""
+msgstr "mappe/openapi.json"
msgid "AWS Access Key"
msgstr ""
@@ -1646,25 +1657,25 @@ msgid "AWS Secret Access Key. Only required if not using role instance credentia
msgstr ""
msgid "AWS service error: %{error}"
-msgstr ""
+msgstr "Fejl ved AWS-tjeneste: %{error}"
msgid "Abort"
-msgstr ""
+msgstr "Afbryd"
msgid "About GitLab"
-msgstr ""
+msgstr "Om GitLab"
msgid "About auto deploy"
-msgstr ""
+msgstr "Om automatisk udsendelse"
msgid "About this feature"
-msgstr ""
+msgstr "Om funktionen"
msgid "Abuse Reports"
-msgstr ""
+msgstr "Misbrugsrapporter"
msgid "Abuse reports"
-msgstr ""
+msgstr "Misbrugsrapporter"
msgid "Abuse reports notification email"
msgstr ""
@@ -1673,64 +1684,64 @@ msgid "Abuse reports will be sent to this address if it is set. Abuse reports ar
msgstr ""
msgid "Accept invitation"
-msgstr ""
+msgstr "Accepter invitation"
msgid "Accept terms"
-msgstr ""
+msgstr "Accepter vilkår"
msgid "Acceptable for use in this project"
-msgstr ""
+msgstr "Acceptabelt til brug i projektet"
msgid "Access Git repositories or the API."
-msgstr ""
+msgstr "Tilgå Git-depoter eller API'et."
msgid "Access Tokens"
-msgstr ""
+msgstr "Adgangstokens"
msgid "Access denied for your LDAP account."
-msgstr ""
+msgstr "Adgang nægtet for din LDAP-konto."
msgid "Access denied! Please verify you can add deploy keys to this repository."
-msgstr ""
+msgstr "Adgang nægtet! Bekræft venligst, at du kan tilføje udsendelsesnøgler til depotet."
msgid "Access denied: %{error}"
-msgstr ""
+msgstr "Adgang nægtet: %{error}"
msgid "Access expiration date"
-msgstr ""
+msgstr "Udløbsdato for adgang"
msgid "Access expires"
-msgstr ""
+msgstr "Adgang udløber"
msgid "Access forbidden. Check your access level."
-msgstr ""
+msgstr "Adgang forbudt. Tjek dit adgangsniveau."
msgid "Access granted"
-msgstr ""
+msgstr "Adgang givet"
msgid "Access requests"
msgstr ""
msgid "Access to '%{classification_label}' not allowed"
-msgstr ""
+msgstr "Adgang til '%{classification_label}' ikke tilladt"
msgid "AccessDropdown|Deploy Keys"
-msgstr ""
+msgstr "Udsendelsesnøgler"
msgid "AccessDropdown|Groups"
-msgstr ""
+msgstr "Grupper"
msgid "AccessDropdown|Roles"
-msgstr ""
+msgstr "Roller"
msgid "AccessDropdown|Users"
-msgstr ""
+msgstr "Brugere"
msgid "AccessTokens|Access Tokens"
-msgstr ""
+msgstr "Adgangstokens"
msgid "AccessTokens|Are you sure?"
-msgstr ""
+msgstr "Er du sikker?"
msgid "AccessTokens|Are you sure? Any RSS or calendar URLs currently in use will stop working."
msgstr ""
@@ -1739,7 +1750,7 @@ msgid "AccessTokens|Are you sure? Any issue email addresses currently in use wil
msgstr ""
msgid "AccessTokens|Created"
-msgstr ""
+msgstr "Oprettet"
msgid "AccessTokens|Feed token"
msgstr ""
@@ -1748,7 +1759,7 @@ msgid "AccessTokens|Incoming email token"
msgstr ""
msgid "AccessTokens|It cannot be used to access any other data."
-msgstr ""
+msgstr "Den kan ikke bruges til at få adgang til andre data."
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
@@ -1784,103 +1795,103 @@ msgid "AccessTokens|Your static object token authenticates you when repository s
msgstr ""
msgid "AccessTokens|reset this token"
-msgstr ""
+msgstr "nulstil tokenen"
msgid "AccessibilityReport|Learn more"
-msgstr ""
+msgstr "Lær mere"
msgid "AccessibilityReport|Message: %{message}"
-msgstr ""
+msgstr "Meddelelse: %{message}"
msgid "AccessibilityReport|New"
-msgstr ""
+msgstr "Ny"
msgid "AccessibilityReport|The accessibility scanning found an error of the following type: %{code}"
msgstr ""
msgid "Account"
-msgstr ""
+msgstr "Konto"
msgid "Account ID"
-msgstr ""
+msgstr "Konto-id"
msgid "Account and limit"
-msgstr ""
+msgstr "Konto og grænse"
msgid "Account:"
-msgstr ""
+msgstr "Konto:"
msgid "Account: %{account}"
-msgstr ""
+msgstr "Konto: %{account}"
msgid "Action"
-msgstr ""
+msgstr "Handling"
msgid "Action to take when receiving an alert. %{docsLink}"
msgstr ""
msgid "Actions"
-msgstr ""
+msgstr "Handlinger"
msgid "Activate Service Desk"
-msgstr ""
+msgstr "Aktivér Service Desk"
msgid "Active"
-msgstr ""
+msgstr "Aktiv"
msgid "Active %{type} (%{token_length})"
-msgstr ""
+msgstr "Aktiv %{type} (%{token_length})"
msgid "Active Sessions"
-msgstr ""
+msgstr "Aktive sessioner"
msgid "Activity"
-msgstr ""
+msgstr "Aktivitet"
msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
-msgstr ""
+msgstr "Der opstod en fejl under indhentning af aktiviteter. Genindlæs siden for at prøve igen."
msgid "Add"
-msgstr ""
+msgstr "Tilføj"
msgid "Add \"%{value}\""
-msgstr ""
+msgstr "Tilføj \"%{value}\""
msgid "Add %{linkStart}assets%{linkEnd} to your Release. GitLab automatically includes read-only assets, like source code and release evidence."
msgstr ""
msgid "Add CHANGELOG"
-msgstr ""
+msgstr "Tilføj CHANGELOG"
msgid "Add CONTRIBUTING"
-msgstr ""
+msgstr "Tilføj CONTRIBUTING"
msgid "Add GitLab to Slack"
-msgstr ""
+msgstr "Tilføj GitLab til Slack"
msgid "Add Jaeger URL"
-msgstr ""
+msgstr "Tilføj Jaeger-URL"
msgid "Add Kubernetes cluster"
-msgstr ""
+msgstr "Tilføj Kubernetes-klynge"
msgid "Add LICENSE"
-msgstr ""
+msgstr "Tilføj LICENSE"
msgid "Add New Node"
-msgstr ""
+msgstr "Tilføj nyt knudepunkt"
msgid "Add README"
-msgstr ""
+msgstr "Tilføj README"
msgid "Add Zoom meeting"
-msgstr ""
+msgstr "Tilføj Zoom-møde"
msgid "Add a %{type}"
-msgstr ""
+msgstr "Tilføj en %{type}"
msgid "Add a GPG key"
-msgstr ""
+msgstr "Tilføj en GPG-nøgle"
msgid "Add a Jaeger URL to replace this page with a link to your Jaeger server. You first need to %{link_start_tag}install Jaeger%{link_end_tag}."
msgstr ""
@@ -1889,16 +1900,16 @@ msgid "Add a Terms of Service agreement and Privacy Policy for users of this Git
msgstr ""
msgid "Add a bullet list"
-msgstr ""
+msgstr "Tilføj en punktliste"
msgid "Add a collapsible section"
-msgstr ""
+msgstr "Tilføj et afsnit som kan foldes sammen"
msgid "Add a comment to this line"
-msgstr ""
+msgstr "Tilføj en kommentar til linjen"
msgid "Add a comment to this line or drag for multiple lines"
-msgstr ""
+msgstr "Tilføj en kommentar til linjen eller træk for flere linjer"
msgid "Add a custom message with details about the instance's shared runners. The message is visible in group and project CI/CD settings, in the Runners section. Markdown is supported."
msgstr ""
@@ -1907,292 +1918,292 @@ msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
msgid "Add a general comment to this %{noteable_name}."
-msgstr ""
+msgstr "Tilføj en generel kommentar til %{noteable_name}."
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
-msgstr ""
+msgstr "Tilføj en startside til din wiki med information om dit projekt, så viser GitLab den her i stedet for denne meddelelse."
msgid "Add a horizontal rule"
-msgstr ""
+msgstr "Tilføj en vandret streg"
msgid "Add a line"
-msgstr ""
+msgstr "Tilføj en linje"
msgid "Add a link"
-msgstr ""
+msgstr "Tilføj et link"
msgid "Add a link to Grafana"
-msgstr ""
+msgstr "Tilføj et link til Grafana"
msgid "Add a new issue"
-msgstr ""
+msgstr "Tilføj en ny problemstilling"
msgid "Add a numbered list"
-msgstr ""
+msgstr "Tilføj en nummereret liste"
msgid "Add a related issue"
-msgstr ""
+msgstr "Tilføj en relateret problemstilling"
msgid "Add a table"
-msgstr ""
+msgstr "Tilføj en tabel"
msgid "Add a task list"
-msgstr ""
+msgstr "Tilføj en opgaveliste"
msgid "Add a to do"
-msgstr ""
+msgstr "Tilføj en to do"
msgid "Add an SSH key"
-msgstr ""
+msgstr "Tilføj en SSH-nøgle"
msgid "Add an existing issue"
-msgstr ""
+msgstr "Tilføj en eksisterende problemstilling"
msgid "Add an impersonation token"
msgstr ""
msgid "Add another link"
-msgstr ""
+msgstr "Tilføj endnu et link"
msgid "Add approval rule"
-msgstr ""
+msgstr "Tilføj godkendelsesregel"
msgid "Add approvers"
-msgstr ""
+msgstr "Tilføj godkendere"
msgid "Add bold text"
-msgstr ""
+msgstr "Tilføj fed tekst"
msgid "Add broadcast message"
-msgstr ""
+msgstr "Tilføj broadcastmeddelelse"
msgid "Add child epic to an epic"
-msgstr ""
+msgstr "Tilføj underepic til en epic"
msgid "Add comment now"
-msgstr ""
+msgstr "Tilføj kommentar nu"
msgid "Add comment to design"
-msgstr ""
+msgstr "Tilføj kommentar til design"
msgid "Add commit messages as comments to Asana tasks. %{docs_link}"
-msgstr ""
+msgstr "Tilføj commit-meddelelser som kommentarer til Asana-opgaver. %{docs_link}"
msgid "Add commit messages as comments to Pivotal Tracker stories. %{docs_link}"
-msgstr ""
+msgstr "Tilføj commit-meddelelser som kommentarer til Pivotal Tracker-historier. %{docs_link}"
msgid "Add deploy freeze"
-msgstr ""
+msgstr "Tilføj udsendelsesfrysning"
msgid "Add deploy keys to grant read/write access to this repository. %{link_start}What are deploy keys?%{link_end}"
-msgstr ""
+msgstr "Tilføj udsendelsesnøgler for at give læse-/skriveadgang til depotet. %{link_start}Hvad er udsendelsesnøgler?%{link_end}"
msgid "Add domain"
-msgstr ""
+msgstr "Tilføj domæne"
msgid "Add email address"
-msgstr ""
+msgstr "Tilføj e-mailadresse"
msgid "Add email participant(s)"
-msgstr ""
+msgstr "Tilføj e-mail-deltagere"
msgid "Add environment"
-msgstr ""
+msgstr "Tilføj miljø"
msgid "Add existing confidential %{issuableType}"
-msgstr ""
+msgstr "Tilføj eksisterende fortrolig %{issuableType}"
msgid "Add header and footer to emails. Please note that color settings will only be applied within the application interface"
msgstr ""
msgid "Add image comment"
-msgstr ""
+msgstr "Tilføj billedkommentar"
msgid "Add italic text"
-msgstr ""
+msgstr "Tilføj kursiv tekst"
msgid "Add key"
-msgstr ""
+msgstr "Tilføj nøgle"
msgid "Add label(s)"
-msgstr ""
+msgstr "Tilføj etiketter"
msgid "Add list"
-msgstr ""
+msgstr "Tilføj liste"
msgid "Add new application"
-msgstr ""
+msgstr "Tilføj nyt program"
msgid "Add new directory"
-msgstr ""
+msgstr "Tilføj ny mappe"
msgid "Add or remove previously merged commits"
-msgstr ""
+msgstr "Tilføj eller fjern commits, som tidligere er blevet sammenlagt"
msgid "Add or subtract spent time"
msgstr ""
msgid "Add previously merged commits"
-msgstr ""
+msgstr "Tilføj commits, som tidligere er blevet sammenlagt"
msgid "Add project"
-msgstr ""
+msgstr "Tilføj projekt"
msgid "Add projects"
-msgstr ""
+msgstr "Tilføj projekter"
msgid "Add reaction"
-msgstr ""
+msgstr "Tilføj reaktion"
msgid "Add request manually"
-msgstr ""
+msgstr "Tilføj anmodning manuelt"
msgid "Add strikethrough text"
-msgstr ""
+msgstr "Tilføj gennemstreget tekst"
msgid "Add suggestion to batch"
msgstr ""
msgid "Add system hook"
-msgstr ""
+msgstr "Tilføj systemhook"
msgid "Add text to the sign-in page. Markdown enabled."
-msgstr ""
+msgstr "Tilføj tekst til indlogningssiden. Markdown er aktiveret."
msgid "Add to Slack"
-msgstr ""
+msgstr "Tilføj til Slack"
msgid "Add to board"
-msgstr ""
+msgstr "Tilføj til tavle"
msgid "Add to epic"
-msgstr ""
+msgstr "Tilføj til epic"
msgid "Add to merge train"
-msgstr ""
+msgstr "Tilføj til sammenlægningstog"
msgid "Add to merge train when pipeline succeeds"
-msgstr ""
+msgstr "Tilføj til sammenlægningstog når pipeline lykkes"
msgid "Add to review"
-msgstr ""
+msgstr "Tilføj til kontrol"
msgid "Add to tree"
-msgstr ""
+msgstr "Tilføj til træ"
msgid "Add trigger"
-msgstr ""
+msgstr "Tilføj udløser"
msgid "Add user(s) to the group:"
-msgstr ""
+msgstr "Tilføj brugere til gruppen:"
msgid "Add users to group"
-msgstr ""
+msgstr "Tilføj brugere til gruppe"
msgid "Add variable"
-msgstr ""
+msgstr "Tilføj variabel"
msgid "Add webhook"
-msgstr ""
+msgstr "Tilføj webhook"
msgid "Add/remove"
-msgstr ""
+msgstr "Tilføj/fjern"
msgid "AddContextCommits|Add previously merged commits"
-msgstr ""
+msgstr "Tilføj commits, som tidligere er blevet sammenlagt"
msgid "AddContextCommits|Add/remove"
-msgstr ""
+msgstr "Tilføj/fjern"
msgid "AddMember|Emails cannot be blank"
-msgstr ""
+msgstr "E-mails må ikke være tomme"
msgid "AddMember|Invite email is invalid"
-msgstr ""
+msgstr "Invitations e-mail er ugyldig"
msgid "AddMember|Invite limit of %{daily_invites} per day exceeded"
-msgstr ""
+msgstr "Invitationsgrænse på %{daily_invites} pr. dag overskredet"
msgid "AddMember|No invite source provided."
-msgstr ""
+msgstr "Ingen invitationskilde angivet."
msgid "AddMember|No users specified."
-msgstr ""
+msgstr "Ingen brugere angivet."
msgid "AddMember|Too many users specified (limit is %{user_limit})"
-msgstr ""
+msgstr "For mange brugere angivet (grænsen er %{user_limit})"
msgid "Added"
-msgstr ""
+msgstr "Tilføjet"
msgid "Added %{epic_ref} as a child epic."
-msgstr ""
+msgstr "Tilføjede %{epic_ref} som en underepic."
msgid "Added %{label_references} %{label_text}."
-msgstr ""
+msgstr "Tilføjede %{label_references} %{label_text}."
msgid "Added a to do."
-msgstr ""
+msgstr "Tilføjede en to do."
msgid "Added an issue to an epic."
-msgstr ""
+msgstr "Tilføjede en problemstilling til en epic."
msgid "Added at"
-msgstr ""
+msgstr "Tilføjet klokken"
msgid "Added for this merge request"
-msgstr ""
+msgstr "Tilføjet for denne sammenlægningsanmodning"
msgid "Added in this version"
-msgstr ""
+msgstr "Tilføjet i denne version"
msgid "Adding new applications is disabled in your GitLab instance. Please contact your GitLab administrator to get the permission"
-msgstr ""
+msgstr "Tilføjelse af nye programmer er deaktiveret i din GitLab-instans. Kontakt din GitLab-administrator for at få tilladelsen"
msgid "Additional Metadata"
-msgstr ""
+msgstr "Yderligere metadata"
msgid "Additional minutes"
-msgstr ""
+msgstr "Yderligere minutter"
msgid "Additional minutes:"
-msgstr ""
+msgstr "Yderligere minutter:"
msgid "Additional text"
-msgstr ""
+msgstr "Yderligere tekst"
msgid "Additional text for the sign-in and Help page."
-msgstr ""
+msgstr "Yderligere tekst til indlognings- og hjælpesiden."
msgid "Additional text to show on the Help page"
-msgstr ""
+msgstr "Yderligere tekst som skal vises på hjælpesiden"
msgid "Additional text to show on the sign-in page"
-msgstr ""
+msgstr "Yderligere tekst som skal vises på indlogningssiden"
msgid "Address"
-msgstr ""
+msgstr "Adresse"
msgid "Adds"
-msgstr ""
+msgstr "Tilføjer"
msgid "Adds %{epic_ref} as child epic."
-msgstr ""
+msgstr "Tilføjer %{epic_ref} som underepic."
msgid "Adds %{labels} %{label_text}."
-msgstr ""
+msgstr "Tilføjer %{labels} %{label_text}."
msgid "Adds a Zoom meeting"
-msgstr ""
+msgstr "Tilføjer et Zoom-møde"
msgid "Adds a to do."
-msgstr ""
+msgstr "Tilføjer en to do."
msgid "Adds an issue to an epic."
-msgstr ""
+msgstr "Tilføjer en problemstilling til en epic."
msgid "Adds email participant(s)"
-msgstr ""
+msgstr "Tilføjer e-mail-deltagere"
msgid "Adjust how frequently the GitLab UI polls for updates."
msgstr ""
@@ -2201,46 +2212,46 @@ msgid "Adjust your filters/search criteria above. If you believe this may be an
msgstr ""
msgid "Admin"
-msgstr ""
+msgstr "Administrator"
msgid "Admin Area"
-msgstr ""
+msgstr "Administratorområde"
msgid "Admin Mode"
-msgstr ""
+msgstr "Administratortilstand"
msgid "Admin Note"
-msgstr ""
+msgstr "Administratorbemærkning"
msgid "Admin Notifications"
-msgstr ""
+msgstr "Administratorunderretninger"
msgid "Admin Overview"
-msgstr ""
+msgstr "Administratoroversigt"
msgid "Admin Section"
-msgstr ""
+msgstr "Administratorafsnit"
msgid "Admin mode already enabled"
-msgstr ""
+msgstr "Administratortilstand allerede aktiveret"
msgid "Admin mode disabled"
-msgstr ""
+msgstr "Administratortilstand deaktiveret"
msgid "Admin mode enabled"
-msgstr ""
+msgstr "Administratortilstand aktiveret"
msgid "Admin navigation"
-msgstr ""
+msgstr "Administratornavigation"
msgid "Admin notes"
-msgstr ""
+msgstr "Administratorbemærkninger"
msgid "AdminArea|%{billable_users_link_start}Learn more%{billable_users_link_end} about what defines a billable user"
msgstr ""
msgid "AdminArea|Active users"
-msgstr ""
+msgstr "Aktive brugere"
msgid "AdminArea|All users created in the instance, including users who are not %{billable_users_link_start}billable users%{billable_users_link_end}."
msgstr ""
@@ -2249,139 +2260,139 @@ msgid "AdminArea|Billable users"
msgstr ""
msgid "AdminArea|Blocked users"
-msgstr ""
+msgstr "Blokerede brugere"
msgid "AdminArea|Bots"
-msgstr ""
+msgstr "Botter"
msgid "AdminArea|Components"
-msgstr ""
+msgstr "Komponenter"
msgid "AdminArea|Developer"
-msgstr ""
+msgstr "Udvikler"
msgid "AdminArea|Features"
-msgstr ""
+msgstr "Funktioner"
msgid "AdminArea|Groups"
-msgstr ""
+msgstr "Grupper"
msgid "AdminArea|Guest"
-msgstr ""
+msgstr "Gæst"
msgid "AdminArea|Included Free in license"
msgstr ""
msgid "AdminArea|Latest groups"
-msgstr ""
+msgstr "Seneste grupper"
msgid "AdminArea|Latest projects"
-msgstr ""
+msgstr "Seneste projekter"
msgid "AdminArea|Latest users"
-msgstr ""
+msgstr "Seneste brugere"
msgid "AdminArea|Maintainer"
-msgstr ""
+msgstr "Vedligeholder"
msgid "AdminArea|New group"
-msgstr ""
+msgstr "Ny gruppe"
msgid "AdminArea|New project"
-msgstr ""
+msgstr "Nyt projekt"
msgid "AdminArea|New user"
-msgstr ""
+msgstr "Ny bruger"
msgid "AdminArea|Owner"
-msgstr ""
+msgstr "Ejer"
msgid "AdminArea|Projects"
-msgstr ""
+msgstr "Projekter"
msgid "AdminArea|Reporter"
-msgstr ""
+msgstr "Rapportør"
msgid "AdminArea|Stop all jobs"
-msgstr ""
+msgstr "Stop alle job"
msgid "AdminArea|Stop all jobs?"
-msgstr ""
+msgstr "Stop alle job?"
msgid "AdminArea|Stop jobs"
-msgstr ""
+msgstr "Stop job"
msgid "AdminArea|Stopping jobs failed"
-msgstr ""
+msgstr "Stop af job mislykkedes"
msgid "AdminArea|Total users"
-msgstr ""
+msgstr "Brugere i alt"
msgid "AdminArea|Users"
-msgstr ""
+msgstr "Brugere"
msgid "AdminArea|Users statistics"
-msgstr ""
+msgstr "Brugerstatistik"
msgid "AdminArea|Users with highest role"
-msgstr ""
+msgstr "Brugere med højeste rolle"
msgid "AdminArea|Users without a Group and Project"
-msgstr ""
+msgstr "Brugere uden en gruppe og projekt"
msgid "AdminArea|View latest groups"
-msgstr ""
+msgstr "Vis seneste grupper"
msgid "AdminArea|View latest projects"
-msgstr ""
+msgstr "Vis seneste projekter"
msgid "AdminArea|View latest users"
-msgstr ""
+msgstr "Vis seneste brugere"
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
-msgstr ""
+msgstr "Fejl ved indlæsning af statistikken. Prøv venligst igen"
msgid "AdminProjects| You’re about to permanently delete the project %{projectName}, its repository, and all related resources, including issues and merge requests. Once you confirm and press %{strong_start}Delete project%{strong_end}, it cannot be undone or recovered."
-msgstr ""
+msgstr " Du er ved at slette projektet %{projectName} og dets depot, og alle relaterede ressourcer, herunder problemstillinger og sammenlægningsanmodninger permanent. Når du bekræfter og trykke på %{strong_start}Slet projekt%{strong_end}, så kan det ikke fortrydes eller gendannes."
msgid "AdminProjects|Delete"
-msgstr ""
+msgstr "Slet"
msgid "AdminProjects|Delete Project %{projectName}?"
-msgstr ""
+msgstr "Slet projektet %{projectName}?"
msgid "AdminSettings|A Let's Encrypt account will be configured for this GitLab instance using this email address. You will receive emails to warn of expiring certificates. %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "En Let's Encrypt-konto konfigureres til GitLab-instansen med denne e-mailadresse. Du modtager e-mails til at advare om certifikater der er ved at udløbe. %{link_start}Lær mere%{link_end}."
msgid "AdminSettings|All new projects can use the instance's shared runners by default."
-msgstr ""
+msgstr "Alle nye projekter kan bruge instansens delte runners som standard."
msgid "AdminSettings|Auto DevOps domain"
-msgstr ""
+msgstr "Auto DevOps-domæne"
msgid "AdminSettings|Configure Let's Encrypt"
-msgstr ""
+msgstr "Konfigurer Let's Encrypt"
msgid "AdminSettings|Disable feed token"
msgstr ""
msgid "AdminSettings|Disable public access to Pages sites"
-msgstr ""
+msgstr "Deaktivér offentlig adgang til Pages-websteder"
msgid "AdminSettings|Domain verification is an essential security measure for public GitLab sites. Users are required to demonstrate they control a domain before it is enabled. %{link_start}Learn more.%{link_end}"
msgstr ""
msgid "AdminSettings|Enable shared runners for new projects"
-msgstr ""
+msgstr "Aktivér delte runners til nye projekter"
msgid "AdminSettings|Feed token"
msgstr ""
msgid "AdminSettings|I have read and agree to the Let's Encrypt %{link_start}Terms of Service%{link_end} (PDF)."
-msgstr ""
+msgstr "Jeg har læst og accepteret Let's Encrypts %{link_start}Vilkår for tjeneste%{link_end} (PDF)."
msgid "AdminSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
@@ -2390,28 +2401,28 @@ msgid "AdminSettings|Keep the latest artifacts for all jobs in the latest succes
msgstr ""
msgid "AdminSettings|Let's Encrypt email"
-msgstr ""
+msgstr "E-mail for Let's Encrypt"
msgid "AdminSettings|Maximum duration of a session for Git operations when 2FA is enabled."
-msgstr ""
+msgstr "Maksimale varighed på en session for Git-handlinger når 2FG er aktiveret."
msgid "AdminSettings|New CI/CD variables in projects and groups default to protected."
-msgstr ""
+msgstr "Nye CI-/CD-variabler i projekter og grupper indstilles som standard til beskyttet."
msgid "AdminSettings|No required pipeline"
-msgstr ""
+msgstr "Ingen krævet pipeline"
msgid "AdminSettings|Protect CI/CD variables by default"
-msgstr ""
+msgstr "Beskyt CI-/CD-variabler som standard"
msgid "AdminSettings|Require users to prove ownership of custom domains"
-msgstr ""
+msgstr "Kræv at brugere beviser ejerskab for tilpassede domæner"
msgid "AdminSettings|Required pipeline configuration"
msgstr ""
msgid "AdminSettings|Select a CI/CD template"
-msgstr ""
+msgstr "Vælg en CI-/CD-skabelon"
msgid "AdminSettings|Select a group to use as the source for instance-level project templates."
msgstr ""
@@ -2420,7 +2431,7 @@ msgid "AdminSettings|Select to disable public access for Pages sites, which requ
msgstr ""
msgid "AdminSettings|Session duration for Git operations when 2FA is enabled (minutes)"
-msgstr ""
+msgstr "Sessionsvarighed for Git-handlinger når 2FG er aktiveret (minutter)"
msgid "AdminSettings|Set a CI/CD template as the required pipeline configuration for all projects in the instance. Project CI/CD configuration merges into the required pipeline configuration when the pipeline runs. %{link_start}What is a required pipeline configuration?%{link_end}"
msgstr ""
@@ -2429,7 +2440,7 @@ msgid "AdminSettings|Set the maximum size of GitLab Pages per project (0 for unl
msgstr ""
msgid "AdminSettings|Size and domain settings for Pages static sites."
-msgstr ""
+msgstr "Indstillinger for størrelse og domæne for statiske Pages-websteder."
msgid "AdminSettings|The default domain to use for Auto Review Apps and Auto Deploy stages in all projects."
msgstr ""
@@ -2447,181 +2458,175 @@ msgid "AdminSettings|The template for the required pipeline configuration can be
msgstr ""
msgid "AdminStatistics|Active Users"
-msgstr ""
+msgstr "Aktive brugere"
msgid "AdminStatistics|Forks"
-msgstr ""
+msgstr "Forgreninger"
msgid "AdminStatistics|Issues"
-msgstr ""
+msgstr "Problemstillinger"
msgid "AdminStatistics|Merge requests"
-msgstr ""
+msgstr "Sammenlægningsanmodninger"
msgid "AdminStatistics|Milestones"
-msgstr ""
+msgstr "Milepæle"
msgid "AdminStatistics|Notes"
-msgstr ""
+msgstr "Bemærkninger"
msgid "AdminStatistics|SSH Keys"
-msgstr ""
+msgstr "SSH-nøgler"
msgid "AdminStatistics|Snippets"
-msgstr ""
+msgstr "Uddrag"
msgid "AdminUsers|(Admin)"
-msgstr ""
+msgstr "(administrator)"
msgid "AdminUsers|(Banned)"
-msgstr ""
+msgstr "(udelukket)"
msgid "AdminUsers|(Blocked)"
-msgstr ""
+msgstr "(blokeret)"
msgid "AdminUsers|(Deactivated)"
-msgstr ""
+msgstr "(deaktiveret)"
msgid "AdminUsers|(Internal)"
-msgstr ""
+msgstr "(intern)"
msgid "AdminUsers|(Pending approval)"
-msgstr ""
+msgstr "(afventer godkendelse)"
msgid "AdminUsers|2FA Disabled"
-msgstr ""
+msgstr "2FG deaktiveret"
msgid "AdminUsers|2FA Enabled"
-msgstr ""
+msgstr "2FG aktiveret"
msgid "AdminUsers|A user can validate themselves by inputting a credit/debit card, or an admin can manually validate a user."
msgstr ""
msgid "AdminUsers|Access"
-msgstr ""
+msgstr "Adgang"
msgid "AdminUsers|Access Git repositories"
-msgstr ""
+msgstr "Tilgå Git-depoter"
msgid "AdminUsers|Access the API"
-msgstr ""
+msgstr "Tilgå API'et"
msgid "AdminUsers|Activate"
-msgstr ""
+msgstr "Aktivér"
msgid "AdminUsers|Activate user %{username}?"
-msgstr ""
+msgstr "Aktivér brugeren %{username}?"
msgid "AdminUsers|Active"
-msgstr ""
+msgstr "Aktiv"
msgid "AdminUsers|Adjust the user cap setting on your instance"
-msgstr ""
+msgstr "Juster indstillingen brugerloft på din instans"
msgid "AdminUsers|Admin"
-msgstr ""
+msgstr "Administrator"
msgid "AdminUsers|Administrators have access to all groups, projects and users and can manage all features in this installation"
-msgstr ""
+msgstr "Administratorer har adgang til alle grupper, projekter og brugere, og kan håndtere alle funktioner i installationen"
msgid "AdminUsers|Admins"
-msgstr ""
+msgstr "Administratorer"
msgid "AdminUsers|Approve"
-msgstr ""
+msgstr "Godkend"
msgid "AdminUsers|Approve user %{username}?"
-msgstr ""
+msgstr "Godkend brugeren %{username}?"
msgid "AdminUsers|Approved users can:"
-msgstr ""
+msgstr "Godkendte brugere kan:"
msgid "AdminUsers|Automatically marked as default internal user"
-msgstr ""
+msgstr "Automatisk mærket som standard intern bruger"
msgid "AdminUsers|Ban user"
-msgstr ""
+msgstr "Udeluk bruger"
msgid "AdminUsers|Ban user %{username}?"
-msgstr ""
+msgstr "Udeluk brugeren %{username}?"
msgid "AdminUsers|Banned"
-msgstr ""
+msgstr "Udelukket"
msgid "AdminUsers|Be added to groups and projects"
-msgstr ""
+msgstr "Bliv tilføjet til grupper og projekter"
msgid "AdminUsers|Block"
-msgstr ""
+msgstr "Blokér"
msgid "AdminUsers|Block user"
-msgstr ""
+msgstr "Blokér bruger"
msgid "AdminUsers|Block user %{username}?"
-msgstr ""
+msgstr "Blokér brugeren %{username}?"
msgid "AdminUsers|Blocked"
-msgstr ""
+msgstr "Blokeret"
msgid "AdminUsers|Blocking user has the following effects:"
-msgstr ""
-
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
+msgstr "Blokering af brugeren har følgende indvirkninger:"
msgid "AdminUsers|Cannot sign in or access instance information"
-msgstr ""
+msgstr "Kan ikke logge ind eller tilgå instansinformation"
msgid "AdminUsers|Cannot unblock LDAP blocked users"
-msgstr ""
+msgstr "Kan ikke afblokere LDAP-blokerede brugere"
msgid "AdminUsers|Cohorts"
msgstr ""
msgid "AdminUsers|Confirm user"
-msgstr ""
+msgstr "Bekræft bruger"
msgid "AdminUsers|Confirm user %{username}?"
-msgstr ""
+msgstr "Bekræft brugeren %{username}?"
msgid "AdminUsers|Could not load user group counts. Please refresh the page to try again."
msgstr ""
msgid "AdminUsers|Deactivate"
-msgstr ""
+msgstr "Deaktivér"
msgid "AdminUsers|Deactivate user %{username}?"
-msgstr ""
+msgstr "Deaktivér brugeren %{username}?"
msgid "AdminUsers|Deactivated"
-msgstr ""
+msgstr "Deaktiveret"
msgid "AdminUsers|Deactivating a user has the following effects:"
-msgstr ""
+msgstr "Deaktivering af en bruger har følgende indvirkninger:"
msgid "AdminUsers|Delete User %{username} and contributions?"
-msgstr ""
+msgstr "Slet brugeren %{username} og bidrag?"
msgid "AdminUsers|Delete User %{username}?"
-msgstr ""
+msgstr "Slet brugeren %{username}?"
msgid "AdminUsers|Delete user"
-msgstr ""
+msgstr "Slet bruger"
msgid "AdminUsers|Delete user and contributions"
-msgstr ""
+msgstr "Slet brugeren og bidrag"
msgid "AdminUsers|Export permissions as CSV"
-msgstr ""
+msgstr "Eksportér tilladelser som CSV"
msgid "AdminUsers|External"
-msgstr ""
+msgstr "Eksterne"
msgid "AdminUsers|External users cannot see internal or private projects unless access is explicitly granted. Also, external users cannot create projects, groups, or personal snippets."
-msgstr ""
+msgstr "Eksterne brugere kan ikke se interne eller private projekter, medmindre der aktivt gives adgang. Desuden kan eksterne brugere ikke oprette projekter, grupper eller personlige uddrag."
msgid "AdminUsers|For more information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
msgstr ""
@@ -2633,94 +2638,103 @@ msgid "AdminUsers|If you have any questions about this process please consult ou
msgstr ""
msgid "AdminUsers|Important information about usage on your GitLab instance"
-msgstr ""
+msgstr "Vigtig information om forbrug på din GitLab-instans"
msgid "AdminUsers|Is using seat"
msgstr ""
-msgid "AdminUsers|It's you!"
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
msgstr ""
+msgid "AdminUsers|It's you!"
+msgstr "Det er dig!"
+
msgid "AdminUsers|Learn more about %{link_start}banned users.%{link_end}"
-msgstr ""
+msgstr "Lær mere om %{link_start}udelukkede brugere%{link_end}."
msgid "AdminUsers|Log in"
-msgstr ""
+msgstr "Log ind"
msgid "AdminUsers|Manage (accept/reject) pending user sign ups"
-msgstr ""
+msgstr "HÃ¥ndter (accepter/afvis) afventende brugertilmeldinger"
msgid "AdminUsers|New user"
-msgstr ""
+msgstr "Ny bruger"
msgid "AdminUsers|No users found"
-msgstr ""
+msgstr "Ingen brugere fundet"
msgid "AdminUsers|Owned groups will be left"
msgstr ""
msgid "AdminUsers|Pending approval"
-msgstr ""
+msgstr "Afventer godkendelse"
msgid "AdminUsers|Personal projects will be left"
-msgstr ""
+msgstr "Personlige projekter efterlades"
msgid "AdminUsers|Personal projects, group and user history will be left intact"
-msgstr ""
+msgstr "Personlige projekter, grupper og brugerhistorik efterlades intakte."
msgid "AdminUsers|Reactivating a user will:"
-msgstr ""
+msgstr "Genaktivering af en bruger vil:"
msgid "AdminUsers|Regular"
-msgstr ""
+msgstr "Almindelige"
msgid "AdminUsers|Regular users have access to their groups and projects"
-msgstr ""
+msgstr "Almindelige brugere har adgang til deres grupper og projekter"
msgid "AdminUsers|Reject"
-msgstr ""
+msgstr "Afvis"
msgid "AdminUsers|Reject user %{username}?"
-msgstr ""
+msgstr "Afvis brugeren %{username}?"
msgid "AdminUsers|Rejected users:"
-msgstr ""
+msgstr "Afviste brugere:"
msgid "AdminUsers|Restore user access to the account, including web, Git and API."
-msgstr ""
+msgstr "Gendan brugeradgang til kontoen, herunder web, Git og API."
msgid "AdminUsers|Search by name, email or username"
-msgstr ""
+msgstr "Søg efter navn, e-mail eller brugernavn"
msgid "AdminUsers|Search users"
-msgstr ""
+msgstr "Søg efter brugere"
msgid "AdminUsers|Send email to users"
-msgstr ""
+msgstr "Send e-mail til brugere"
msgid "AdminUsers|Sort by"
+msgstr "Sortér efter"
+
+msgid "AdminUsers|The user can't access git repositories."
msgstr ""
-msgid "AdminUsers|The user will be logged out"
+msgid "AdminUsers|The user can't log in."
msgstr ""
+msgid "AdminUsers|The user will be logged out"
+msgstr "Brugeren logges ud"
+
msgid "AdminUsers|The user will not be able to access git repositories"
-msgstr ""
+msgstr "Brugeren vil ikke være i stand til at tilgå git-depoter"
msgid "AdminUsers|The user will not be able to access the API"
-msgstr ""
+msgstr "Brugeren vil ikke være i stand til at tilgå API'et"
msgid "AdminUsers|The user will not be able to use slash commands"
-msgstr ""
+msgstr "Brugeren vil ikke være i stand til at bruge skråstregskommandoer"
msgid "AdminUsers|The user will not receive any notifications"
-msgstr ""
+msgstr "Brugeren modtager ingen underretninger"
msgid "AdminUsers|To confirm, type %{projectName}"
-msgstr ""
+msgstr "Skriv %{projectName} for at bekræfte"
msgid "AdminUsers|To confirm, type %{username}"
-msgstr ""
+msgstr "Skriv %{username} for at bekræfte"
msgid "AdminUsers|Unban user"
msgstr ""
@@ -2735,22 +2749,22 @@ msgid "AdminUsers|Unblock user %{username}?"
msgstr ""
msgid "AdminUsers|Unlock user %{username}?"
-msgstr ""
+msgstr "Oplås brugeren %{username}?"
msgid "AdminUsers|User administration"
-msgstr ""
+msgstr "Brugeradministration"
msgid "AdminUsers|User is validated and can use free CI minutes on shared runners."
msgstr ""
msgid "AdminUsers|User will not be able to access git repositories"
-msgstr ""
+msgstr "Brugeren vil ikke være i stand til at tilgå git-depoter"
msgid "AdminUsers|User will not be able to login"
-msgstr ""
+msgstr "Brugeren vil ikke være i stand til at logge ind"
msgid "AdminUsers|Users"
-msgstr ""
+msgstr "Brugere"
msgid "AdminUsers|Users can still be invited to your instance and/or add themselves if permitted based on your settings. They will not have access to your instance, nor count towards your subscribed seat count until you %{approve_link}."
msgstr ""
@@ -2759,25 +2773,25 @@ msgid "AdminUsers|Validate user account"
msgstr ""
msgid "AdminUsers|View pending member requests"
-msgstr ""
+msgstr "Vis afventende medlemsanmodninger"
msgid "AdminUsers|What can I do?"
msgstr ""
msgid "AdminUsers|What does this mean?"
-msgstr ""
+msgstr "Hvad betyder det?"
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
-msgstr ""
+msgstr "Når brugeren logger ind igen, så genaktiveres deres konto som en fuldt aktiv konto"
msgid "AdminUsers|Will be deleted"
-msgstr ""
+msgstr "Slettes"
msgid "AdminUsers|Without projects"
-msgstr ""
+msgstr "Uden projekter"
msgid "AdminUsers|You are about to permanently delete the user %{username}. Issues, merge requests, and groups linked to them will be transferred to a system-wide \"Ghost-user\". To avoid data loss, consider using the %{strongStart}block user%{strongEnd} feature instead. Once you %{strongStart}Delete user%{strongEnd}, it cannot be undone or recovered."
msgstr ""
@@ -2786,58 +2800,58 @@ msgid "AdminUsers|You are about to permanently delete the user %{username}. This
msgstr ""
msgid "AdminUsers|You can always block their account again if needed."
-msgstr ""
+msgstr "Du kan altid blokere deres konto igen hvis det bliver nødvendigt."
msgid "AdminUsers|You can always deactivate their account again if needed."
-msgstr ""
+msgstr "Du kan altid deaktivere deres konto igen hvis det bliver nødvendigt."
msgid "AdminUsers|You can always re-activate their account, their data will remain intact."
-msgstr ""
+msgstr "Du kan altid genaktivere deres konto. Deres data forbliver intakte."
msgid "AdminUsers|You can always unblock their account, their data will remain intact."
-msgstr ""
+msgstr "Du kan altid afblokere deres konto. Deres data forbliver intakte."
msgid "AdminUsers|You can ban their account in the future if necessary."
-msgstr ""
+msgstr "Du kan udelukke deres konto i fremtiden hvis det bliver nødvendigt."
msgid "AdminUsers|You can unban their account in the future. Their data remains intact."
msgstr ""
msgid "AdminUsers|You cannot remove your own admin rights."
-msgstr ""
+msgstr "Du kan ikke fjerne dine egne administratorrettigheder."
msgid "AdminUsers|You must transfer ownership or delete the groups owned by this user before you can delete their account"
-msgstr ""
+msgstr "Du skal overføre ejerskab eller slette de grupper som ejes af brugeren inden du kan slette dens konto"
msgid "AdminUsers|Your GitLab instance has reached the maximum allowed %{user_doc_link} set by an instance admin."
msgstr ""
msgid "AdminUsers|approve them"
-msgstr ""
+msgstr "godkend dem"
msgid "AdminUsers|contact our support team"
-msgstr ""
+msgstr "kontakt vores supportteam"
msgid "AdminUsers|docs"
-msgstr ""
+msgstr "dokumentation"
msgid "AdminUsers|user cap"
-msgstr ""
+msgstr "brugerloft"
msgid "Administration"
-msgstr ""
+msgstr "Administration"
msgid "Admin|Additional users must be reviewed and approved by a system administrator. Learn more about %{help_link_start}usage caps%{help_link_end}."
msgstr ""
msgid "Admin|Admin notes"
-msgstr ""
+msgstr "Administratorbemærkninger"
msgid "Admin|Learn more about quarterly reconciliation"
msgstr ""
msgid "Admin|Note"
-msgstr ""
+msgstr "Bemærkning"
msgid "Admin|Quarterly reconciliation will occur on %{qrtlyDate}"
msgstr ""
@@ -2849,19 +2863,19 @@ msgid "Admin|The number of maximum users for your instance is currently exceedin
msgstr ""
msgid "Admin|View pending user approvals"
-msgstr ""
+msgstr "Vis afventende brugergodkendelser"
msgid "Admin|Your instance has reached its user cap"
-msgstr ""
+msgstr "Din instans har nået sit brugerloft"
msgid "Advanced"
-msgstr ""
+msgstr "Avanceret"
msgid "Advanced Search"
-msgstr ""
+msgstr "Avanceret søgning"
msgid "Advanced Settings"
-msgstr ""
+msgstr "Avancerede indstillinger"
msgid "Advanced export options"
msgstr ""
@@ -2888,7 +2902,7 @@ msgid "After you've reviewed these contribution guidelines, you'll be all set to
msgstr ""
msgid "Akismet API Key"
-msgstr ""
+msgstr "Akismet API-nøgle"
msgid "Alert"
msgid_plural "Alerts"
@@ -2923,43 +2937,43 @@ msgid "AlertManagement|All alerts"
msgstr ""
msgid "AlertManagement|Assign status"
-msgstr ""
+msgstr "Tildel status"
msgid "AlertManagement|Assignees"
-msgstr ""
+msgstr "Tildelere"
msgid "AlertManagement|Authorize external service"
msgstr ""
msgid "AlertManagement|Create incident"
-msgstr ""
+msgstr "Opret hændelse"
msgid "AlertManagement|Display alerts from all your monitoring tools directly within GitLab. Streamline the investigation of your alerts and the escalation of alerts to incidents."
msgstr ""
msgid "AlertManagement|Edit"
-msgstr ""
+msgstr "Rediger"
msgid "AlertManagement|Environment"
-msgstr ""
+msgstr "Miljø"
msgid "AlertManagement|Events"
-msgstr ""
+msgstr "Begivenheder"
msgid "AlertManagement|Incident"
-msgstr ""
+msgstr "Hændelse"
msgid "AlertManagement|Key"
-msgstr ""
+msgstr "Nøgle"
msgid "AlertManagement|Metrics"
-msgstr ""
+msgstr "MÃ¥linger"
msgid "AlertManagement|Metrics weren't available in the alerts payload."
msgstr ""
msgid "AlertManagement|More information"
-msgstr ""
+msgstr "Mere information"
msgid "AlertManagement|No alert data to display."
msgstr ""
@@ -2977,31 +2991,31 @@ msgid "AlertManagement|Open"
msgstr ""
msgid "AlertManagement|Please try again."
-msgstr ""
+msgstr "Prøv venligst igen."
msgid "AlertManagement|Reported %{when}"
-msgstr ""
+msgstr "Rapporteret %{when}"
msgid "AlertManagement|Reported %{when} by %{tool}"
-msgstr ""
+msgstr "Rapporteret %{when} af %{tool}"
msgid "AlertManagement|Resolved"
-msgstr ""
+msgstr "Løst"
msgid "AlertManagement|Runbook"
msgstr ""
msgid "AlertManagement|Service"
-msgstr ""
+msgstr "Tjeneste"
msgid "AlertManagement|Severity"
-msgstr ""
+msgstr "Alvorlighed"
msgid "AlertManagement|Start time"
-msgstr ""
+msgstr "Starttidspunkt"
msgid "AlertManagement|Status"
-msgstr ""
+msgstr "Status"
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
@@ -3028,16 +3042,16 @@ msgid "AlertManagement|This assignee cannot be assigned to this alert."
msgstr ""
msgid "AlertManagement|Tool"
-msgstr ""
+msgstr "Værktøj"
msgid "AlertManagement|Triggered"
-msgstr ""
+msgstr "Udløst"
msgid "AlertManagement|Value"
-msgstr ""
+msgstr "Værdi"
msgid "AlertManagement|View incident"
-msgstr ""
+msgstr "Vis hændelse"
msgid "AlertMappingBuilder|Define fallback"
msgstr ""
@@ -3052,7 +3066,7 @@ msgid "AlertMappingBuilder|Payload alert key"
msgstr ""
msgid "AlertMappingBuilder|Select key"
-msgstr ""
+msgstr "Vælg nøgle"
msgid "AlertMappingBuilder|Title is a required field for alerts in GitLab. Should the payload field you specified not be available, specifiy which field we should use instead. "
msgstr ""
@@ -3061,40 +3075,40 @@ msgid "AlertSettings|A webhook URL and authorization key is generated for the in
msgstr ""
msgid "AlertSettings|Add new integration"
-msgstr ""
+msgstr "Tilføj ny integrering"
msgid "AlertSettings|Alert settings"
msgstr ""
msgid "AlertSettings|Authorization key"
-msgstr ""
+msgstr "Godkendelsesnøgle"
msgid "AlertSettings|Configure details"
-msgstr ""
+msgstr "Konfigurer detaljer"
msgid "AlertSettings|Current integrations"
-msgstr ""
+msgstr "Nuværende integreringer"
msgid "AlertSettings|Customize alert payload mapping (optional)"
msgstr ""
msgid "AlertSettings|Delete integration"
-msgstr ""
+msgstr "Slet integrering"
msgid "AlertSettings|Edit integration"
-msgstr ""
+msgstr "Rediger integrering"
msgid "AlertSettings|Edit payload"
msgstr ""
msgid "AlertSettings|Enable integration"
-msgstr ""
+msgstr "Aktivér integrering"
msgid "AlertSettings|Enter an example payload from your selected monitoring tool. This supports sending alerts to a GitLab endpoint."
msgstr ""
msgid "AlertSettings|Enter integration name"
-msgstr ""
+msgstr "Indtast integreringsnavn"
msgid "AlertSettings|Free versions of GitLab are limited to one integration per type. To add more, %{linkStart}upgrade your subscription%{linkEnd}."
msgstr ""
@@ -3121,16 +3135,16 @@ msgid "AlertSettings|Parse payload fields"
msgstr ""
msgid "AlertSettings|Proceed with editing"
-msgstr ""
+msgstr "Forsæt med redigering"
msgid "AlertSettings|Prometheus"
-msgstr ""
+msgstr "Prometheus"
msgid "AlertSettings|Prometheus API base URL"
msgstr ""
msgid "AlertSettings|Reset Key"
-msgstr ""
+msgstr "Nulstil nøgle"
msgid "AlertSettings|Reset the mapping"
msgstr ""
@@ -3142,25 +3156,25 @@ msgid "AlertSettings|Save & create test alert"
msgstr ""
msgid "AlertSettings|Save integration"
-msgstr ""
+msgstr "Gem integrering"
msgid "AlertSettings|Save integration & send"
-msgstr ""
+msgstr "Gem integrering og send"
msgid "AlertSettings|Select integration type"
-msgstr ""
+msgstr "Vælg integreringstype"
msgid "AlertSettings|Send test alert"
msgstr ""
msgid "AlertSettings|Send without saving"
-msgstr ""
+msgstr "Send uden at gemme"
msgid "AlertSettings|The form has unsaved changes"
-msgstr ""
+msgstr "Formularen har ændringer som ikke er blevet gemt"
msgid "AlertSettings|The form has unsaved changes. How would you like to proceed?"
-msgstr ""
+msgstr "Formularen har ændringer som ikke er blevet gemt. Hvordan vil du fortsætte?"
msgid "AlertSettings|To create a custom mapping, enter an example payload from your monitoring tool, in JSON format. Select the \"Parse payload fields\" button to continue."
msgstr ""
@@ -3178,7 +3192,7 @@ msgid "AlertSettings|View URL and authorization key"
msgstr ""
msgid "AlertSettings|View credentials"
-msgstr ""
+msgstr "Vis loginoplysninger"
msgid "AlertSettings|Webhook URL"
msgstr ""
@@ -3238,43 +3252,43 @@ msgid "AlertsIntegrations|The test alert should now be visible in your alerts li
msgstr ""
msgid "Algorithm"
-msgstr ""
+msgstr "Algoritme"
msgid "All"
-msgstr ""
+msgstr "Alle"
msgid "All %{replicableType} are being scheduled for %{action}"
msgstr ""
msgid "All (default)"
-msgstr ""
+msgstr "Alle (standard)"
msgid "All Members"
-msgstr ""
+msgstr "Alle medlemmer"
msgid "All branches"
-msgstr ""
+msgstr "Alle grene"
msgid "All changes are committed"
-msgstr ""
+msgstr "Alle ændringer er committed"
msgid "All email addresses will be used to identify your commits."
msgstr ""
msgid "All environments"
-msgstr ""
+msgstr "Alle miljøer"
msgid "All epics"
-msgstr ""
+msgstr "Alle epics"
msgid "All groups and projects"
-msgstr ""
+msgstr "Alle grupper og projekter"
msgid "All issues for this milestone are closed."
msgstr ""
msgid "All issues for this milestone are closed. You may close this milestone now."
-msgstr ""
+msgstr "Alle problemstillinger for milepælen er lukket. Du kan nu lukke milepælen."
msgid "All merge conflicts were resolved. The merge request can now be merged."
msgstr ""
@@ -3286,22 +3300,22 @@ msgid "All paths are relative to the GitLab URL. Do not include %{relative_url_l
msgstr ""
msgid "All projects"
-msgstr ""
+msgstr "Alle projekter"
msgid "All projects selected"
-msgstr ""
+msgstr "Alle projekter valgt"
msgid "All threads resolved"
-msgstr ""
+msgstr "Alle tråde løst"
msgid "All users must accept the Terms of Service and Privacy Policy to access GitLab"
msgstr ""
msgid "All users must have a name."
-msgstr ""
+msgstr "Alle brugere skal have et navn."
msgid "Allow \"%{group_name}\" to sign you in"
-msgstr ""
+msgstr "Tillad \"%{group_name}\" at logge dig ind"
msgid "Allow access to members of the following group"
msgstr ""
@@ -3310,7 +3324,7 @@ msgid "Allow access to the following IP addresses"
msgstr ""
msgid "Allow commits from members who can merge to the target branch."
-msgstr ""
+msgstr "Tillad commits fra medlemmer, som kan sammenlægge til målgrenen."
msgid "Allow group owners to manage LDAP-related settings"
msgstr ""
@@ -3340,7 +3354,7 @@ msgid "Allow projects and subgroups to override the group setting"
msgstr ""
msgid "Allow projects within this group to use Git LFS"
-msgstr ""
+msgstr "Tillad projekter i gruppen at bruge Git LFS"
msgid "Allow public access to pipelines and job details, including output logs and artifacts."
msgstr ""
@@ -3373,13 +3387,13 @@ msgid "Allow users to request access (if visibility is public or internal)"
msgstr ""
msgid "Allowed"
-msgstr ""
+msgstr "Tilladt"
msgid "Allowed Geo IP"
-msgstr ""
+msgstr "Tilladte Geo-IP"
msgid "Allowed characters: +, 0-9, -, and spaces."
-msgstr ""
+msgstr "Tilladte tegn: +, 0-9, - og mellemrum."
msgid "Allowed email domain restriction only permitted for top-level groups"
msgstr ""
@@ -3397,16 +3411,16 @@ msgid "Allows you to add and manage Kubernetes clusters."
msgstr ""
msgid "Almost there"
-msgstr ""
+msgstr "Du er der næsten"
msgid "Almost there..."
-msgstr ""
+msgstr "Du er der næsten ..."
msgid "Already blocked"
-msgstr ""
+msgstr "Allerede blokeret"
msgid "Already have login and password?"
-msgstr ""
+msgstr "Har du allerede login og adgangskode?"
msgid "Also called \"Issuer\" or \"Relying party trust identifier\""
msgstr ""
@@ -3427,7 +3441,7 @@ msgid "Alternatively, you can convert your account to a managed account by the %
msgstr ""
msgid "Amazon EKS"
-msgstr ""
+msgstr "Amazon EKS"
msgid "Amazon EKS integration allows you to provision EKS clusters from GitLab."
msgstr ""
@@ -3457,283 +3471,283 @@ msgid "An alert has been triggered in %{project_path}."
msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
-msgstr ""
+msgstr "Et program kaldet %{link_to_client} anmoder om adgang til din GitLab-konto."
msgid "An email notification was recently sent from the admin panel. Please wait %{wait_time_in_words} before attempting to send another message."
msgstr ""
msgid "An empty GitLab User field will add the FogBugz user's full name (e.g. \"By John Smith\") in the description of all issues and comments. It will also associate and/or assign these issues and comments with the project creator."
-msgstr ""
+msgstr "Et tomt GitLab-brugerfelt tilføjer FogBugz-brugerens fulde navn (f.eks. \"Af Ronni Ræv\") i beskrivelsen på alle problemstillinger og kommentarer. Det vil også tilknytte og/eller tildele problemstillingerne og kommentarerne med projektopretteren."
msgid "An empty index will be created if one does not already exist"
-msgstr ""
+msgstr "Der oprettes et tomt indeks hvis der ikke allerede findes et"
msgid "An error has occurred"
-msgstr ""
+msgstr "Der opstod en fejl"
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
msgid "An error occurred adding a draft to the thread."
-msgstr ""
+msgstr "Der opstod en fejl ved tilføjelse af et udkast til tråden."
msgid "An error occurred adding a new draft."
-msgstr ""
+msgstr "Der opstod en fejl ved tilføjelse af et nyt udkast."
msgid "An error occurred creating the new branch."
-msgstr ""
+msgstr "Der opstod en fejl ved oprettelse af den nye gren."
msgid "An error occurred fetching the approval rules."
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af godkendelsesreglerne."
msgid "An error occurred fetching the approvers for the new rule."
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af godkenderne til den ny regel."
msgid "An error occurred fetching the dropdown data."
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af rullegardinsdataene."
msgid "An error occurred fetching the project authors."
msgstr ""
msgid "An error occurred previewing the blob"
-msgstr ""
+msgstr "Der opstod en fejl ved forhåndsvisning af blob'en"
msgid "An error occurred when removing the label."
-msgstr ""
+msgstr "Der opstod en fejl ved fjernelse af etiketten."
msgid "An error occurred when toggling the notification subscription"
msgstr ""
msgid "An error occurred when updating the issue weight"
-msgstr ""
+msgstr "Der opstod en fejl ved opdatering af problemstillingsvægten"
msgid "An error occurred when updating the title"
-msgstr ""
+msgstr "Der opstod en fejl ved opdatering af titlen"
msgid "An error occurred while acknowledging the notification. Refresh the page and try again."
-msgstr ""
+msgstr "Der opstod en fejl under tilkendegivelse af underretningen. Opdater siden og prøv igen."
msgid "An error occurred while adding approvers"
-msgstr ""
+msgstr "Der opstod en fejl under tilføjelse af godkendere"
msgid "An error occurred while adding formatted title for epic"
-msgstr ""
+msgstr "Der opstod en fejl under tilføjelse af formateret titel til epic"
msgid "An error occurred while authorizing your role"
-msgstr ""
+msgstr "Der opstod en fejl under godkendelse af din rolle"
msgid "An error occurred while checking group path. Please refresh and try again."
-msgstr ""
+msgstr "Der opstod en fejl under tjek af gruppesti. Opdater venligst og prøv igen."
msgid "An error occurred while decoding the file."
-msgstr ""
+msgstr "Der opstod en fejl under afkodning af filen."
msgid "An error occurred while deleting the approvers group"
-msgstr ""
+msgstr "Der opstod en fejl under sletning af godkendergruppen"
msgid "An error occurred while deleting the comment"
-msgstr ""
+msgstr "Der opstod en fejl under sletning af kommentaren"
msgid "An error occurred while deleting the pipeline."
-msgstr ""
+msgstr "Der opstod en fejl under sletning af pipelinen."
msgid "An error occurred while detecting host keys"
-msgstr ""
+msgstr "Der opstod en fejl under registrering af værtsnøgler"
msgid "An error occurred while disabling Service Desk."
-msgstr ""
+msgstr "Der opstod en fejl under deaktivering af Service Desk."
msgid "An error occurred while dismissing the alert. Refresh the page and try again."
-msgstr ""
+msgstr "Der opstod en fejl under afskedigelse af advarslen. Opdater siden og prøv igen."
msgid "An error occurred while dismissing the feature highlight. Refresh the page and try dismissing again."
-msgstr ""
+msgstr "Der opstod en fejl under afskedigelse af funktionen fremhævning. Opdater siden og prøv at afskedige igen."
msgid "An error occurred while drawing job relationship links."
msgstr ""
msgid "An error occurred while enabling Service Desk."
-msgstr ""
+msgstr "Der opstod en fejl under aktivering af Service Desk."
msgid "An error occurred while fetching ancestors"
msgstr ""
msgid "An error occurred while fetching branches. Retry the search."
-msgstr ""
+msgstr "Der opstod en fejl under hentning af grene. Prøv søgningen igen."
msgid "An error occurred while fetching codequality mr diff reports."
msgstr ""
msgid "An error occurred while fetching commits. Retry the search."
-msgstr ""
+msgstr "Der opstod en fejl under hentning af commits. Prøv søgningen igen."
msgid "An error occurred while fetching coverage reports."
-msgstr ""
+msgstr "Der opstod en fejl under hentning af dækningsrapporter."
msgid "An error occurred while fetching environments."
-msgstr ""
+msgstr "Der opstod en fejl under hentning af miljøer."
msgid "An error occurred while fetching exposed artifacts."
msgstr ""
msgid "An error occurred while fetching folder content."
-msgstr ""
+msgstr "Der opstod en fejl under hentning af mappeindhold."
msgid "An error occurred while fetching issues."
-msgstr ""
+msgstr "Der opstod en fejl under hentning af problemstillinger."
msgid "An error occurred while fetching label colors."
-msgstr ""
+msgstr "Der opstod en fejl under hentning af etiketfarver."
msgid "An error occurred while fetching markdown preview"
-msgstr ""
+msgstr "Der opstod en fejl under hentning af markdown-forhåndsvisning"
msgid "An error occurred while fetching participants"
-msgstr ""
+msgstr "Der opstod en fejl under hentning af deltagere"
msgid "An error occurred while fetching participants."
-msgstr ""
+msgstr "Der opstod en fejl under hentning af deltagere."
msgid "An error occurred while fetching pending comments"
-msgstr ""
+msgstr "Der opstod en fejl under hentning af afventende kommentarer"
msgid "An error occurred while fetching projects autocomplete."
msgstr ""
msgid "An error occurred while fetching reference"
-msgstr ""
+msgstr "Der opstod en fejl under hentning af reference"
msgid "An error occurred while fetching sidebar data"
-msgstr ""
+msgstr "Der opstod en fejl under hentning af sidebjælkedata"
msgid "An error occurred while fetching tags. Retry the search."
-msgstr ""
+msgstr "Der opstod en fejl under hentning af mærkater. Prøv søgningen igen."
msgid "An error occurred while fetching terraform reports."
-msgstr ""
-
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl under hentning af terraformrapporter."
msgid "An error occurred while fetching the job log."
-msgstr ""
+msgstr "Der opstod en fejl under hentning af jobloggen."
msgid "An error occurred while fetching the job logs."
-msgstr ""
+msgstr "Der opstod en fejl under hentning af joblogge."
msgid "An error occurred while fetching the job."
-msgstr ""
+msgstr "Der opstod en fejl under hentning af jobbet."
msgid "An error occurred while fetching the jobs."
-msgstr ""
+msgstr "Der opstod en fejl under hentning af jobbene."
msgid "An error occurred while fetching the latest pipeline."
-msgstr ""
-
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
+msgstr "Der opstod en fejl under hentning af den seneste pipeline."
msgid "An error occurred while fetching the releases. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl under hentning af udgivelserne. Prøv venligst igen."
msgid "An error occurred while fetching this tab."
-msgstr ""
+msgstr "Der opstod en fejl under hentning af fanebladet."
msgid "An error occurred while generating a username. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl under generering af et brugernavn. Prøv venligst igen."
msgid "An error occurred while getting autocomplete data. Please refresh the page and try again."
-msgstr ""
+msgstr "Der opstod en fejl under hentning af autofuldførdata. Opdater venligst siden og prøv igen."
msgid "An error occurred while getting files for - %{branchId}"
-msgstr ""
+msgstr "Der opstod en fejl under hentning af filer for - %{branchId}"
msgid "An error occurred while getting issue counts"
msgstr ""
msgid "An error occurred while getting projects"
-msgstr ""
+msgstr "Der opstod en fejl under hentning af projekter"
msgid "An error occurred while initializing path locks"
-msgstr ""
+msgstr "Der opstod en fejl under initialisering af stilåse"
msgid "An error occurred while loading a section of this page."
-msgstr ""
+msgstr "Der opstod en fejl under indlæsning af et afsnit på siden."
msgid "An error occurred while loading all the files."
-msgstr ""
+msgstr "Der opstod en fejl under indlæsning af alle filerne."
msgid "An error occurred while loading chart data"
-msgstr ""
+msgstr "Der opstod en fejl under indlæsning af diagramdata"
msgid "An error occurred while loading commit signatures"
msgstr ""
msgid "An error occurred while loading designs. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl under indlæsning af designs. Prøv venligst igen."
msgid "An error occurred while loading diff"
-msgstr ""
+msgstr "Der opstod en fejl under indlæsning af diff"
msgid "An error occurred while loading filenames"
-msgstr ""
+msgstr "Der opstod en fejl under indlæsning af filnavne"
msgid "An error occurred while loading group members."
-msgstr ""
+msgstr "Der opstod en fejl under indlæsning af gruppemedlemmer."
msgid "An error occurred while loading issues"
-msgstr ""
+msgstr "Der opstod en fejl under indlæsning af problemstillinger"
msgid "An error occurred while loading merge requests."
+msgstr "Der opstod en fejl under indlæsning af sammenlægningsanmodninger."
+
+msgid "An error occurred while loading the Needs tab."
msgstr ""
-msgid "An error occurred while loading the access tokens form, please try again."
+msgid "An error occurred while loading the Test Reports tab."
msgstr ""
+msgid "An error occurred while loading the access tokens form, please try again."
+msgstr "Der opstod en fejl under indlæsning af formularen til adgangstokens, prøv venligst igen."
+
msgid "An error occurred while loading the data. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl under indlæsning af dataene. Prøv venligst igen."
msgid "An error occurred while loading the file"
-msgstr ""
+msgstr "Der opstod en fejl under indlæsning af filen"
msgid "An error occurred while loading the file content."
-msgstr ""
+msgstr "Der opstod en fejl under indlæsning af filindholdet."
msgid "An error occurred while loading the file."
-msgstr ""
+msgstr "Der opstod en fejl under indlæsning af filen."
msgid "An error occurred while loading the file. Please try again later."
-msgstr ""
+msgstr "Der opstod en fejl under indlæsning af filen. Prøv venligst igen senere."
msgid "An error occurred while loading the file. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl under indlæsning af filen. Prøv venligst igen."
msgid "An error occurred while loading the merge request changes."
-msgstr ""
+msgstr "Der opstod en fejl under indlæsning af ændringerne for sammenlægningsanmodning."
msgid "An error occurred while loading the merge request version data."
-msgstr ""
+msgstr "Der opstod en fejl under indlæsning af versionsdata for sammenlægningsanmodningen."
msgid "An error occurred while loading the merge request."
-msgstr ""
+msgstr "Der opstod en fejl under indlæsning af sammenlægningsanmodningen."
msgid "An error occurred while loading the notification settings. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl under indlæsning af underretningsindstillingerne. Prøv venligst igen."
msgid "An error occurred while loading the pipeline."
-msgstr ""
+msgstr "Der opstod en fejl under indlæsning af pipelinen."
msgid "An error occurred while loading the pipelines jobs."
-msgstr ""
+msgstr "Der opstod en fejl under indlæsning af pipelinejobbene."
msgid "An error occurred while loading your content. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl under indlæsning af dit indhold. Prøv venligst igen."
msgid "An error occurred while making the request."
msgstr ""
msgid "An error occurred while moving the issue."
-msgstr ""
+msgstr "Der opstod en fejl under flytning af problemstillingen."
msgid "An error occurred while parsing recent searches"
msgstr ""
@@ -3742,91 +3756,91 @@ msgid "An error occurred while parsing the file."
msgstr ""
msgid "An error occurred while removing epics."
-msgstr ""
+msgstr "Der opstod en fejl under fjernelse af epics."
msgid "An error occurred while removing issues."
-msgstr ""
+msgstr "Der opstod en fejl under fjernelse af problemstillinger."
msgid "An error occurred while rendering preview broadcast message"
msgstr ""
msgid "An error occurred while rendering the editor"
-msgstr ""
+msgstr "Der opstod en fejl under gengivelse af editoren"
msgid "An error occurred while reordering issues."
-msgstr ""
+msgstr "Der opstod en fejl under omorganisering af problemstillinger."
msgid "An error occurred while retrieving calendar activity"
-msgstr ""
+msgstr "Der opstod en fejl under indhentning af kalenderaktivitet"
msgid "An error occurred while retrieving diff"
-msgstr ""
+msgstr "Der opstod en fejl under indhentning af diff"
msgid "An error occurred while retrieving diff files"
-msgstr ""
+msgstr "Der opstod en fejl under indhentning af diff-filer"
msgid "An error occurred while retrieving projects."
-msgstr ""
+msgstr "Der opstod en fejl under indhentning af projekter."
msgid "An error occurred while saving changes: %{error}"
-msgstr ""
+msgstr "Der opstod en fejl under gemning af ændringer: %{error}"
msgid "An error occurred while subscribing to notifications."
msgstr ""
msgid "An error occurred while triggering the job."
-msgstr ""
+msgstr "Der opstod en fejl under udløsning af jobbet."
msgid "An error occurred while trying to generate the report. Please try again later."
-msgstr ""
+msgstr "Der opstod en fejl under forsøg på at generere rapporten. Prøv venligst igen senere."
msgid "An error occurred while trying to run a new pipeline for this merge request."
-msgstr ""
+msgstr "Der opstod en fejl under forsøg på at køre en ny pipeline til sammenlægningsanmodningen."
msgid "An error occurred while unsubscribing to notifications."
msgstr ""
msgid "An error occurred while updating approvers"
-msgstr ""
+msgstr "Der opstod en fejl under opdatering af godkendere"
msgid "An error occurred while updating assignees."
-msgstr ""
+msgstr "Der opstod en fejl under opdatering af tildelte."
msgid "An error occurred while updating configuration."
-msgstr ""
+msgstr "Der opstod en fejl under opdatering af konfiguration."
msgid "An error occurred while updating labels."
-msgstr ""
+msgstr "Der opstod en fejl under opdatering af etiketter."
msgid "An error occurred while updating the comment"
-msgstr ""
+msgstr "Der opstod en fejl under opdatering af kommentaren"
msgid "An error occurred while updating the configuration."
-msgstr ""
+msgstr "Der opstod en fejl under opdatering af konfigurationen."
msgid "An error occurred while updating the notification settings. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl under opdatering af underretningsindstillingerne. Prøv venligst igen."
msgid "An error occurred while uploading the file. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl under upload af filen. Prøv venligst igen."
msgid "An error occurred while uploading the image. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl under upload af billedet. Prøv venligst igen."
msgid "An error occurred while validating group path"
msgstr ""
msgid "An error occurred while validating username"
-msgstr ""
+msgstr "Der opstod en fejl under validering af brugernavn"
msgid "An error occurred. Please sign in again."
-msgstr ""
+msgstr "Der opstod en fejl. Log venligst ind igen."
msgid "An error occurred. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl. Prøv venligst igen."
msgid "An example project for managing Kubernetes clusters integrated with GitLab"
-msgstr ""
+msgstr "Et eksempelprojekt til håndtering af Kubernetes-klynger integreret med GitLab"
msgid "An example project that shows off the best practices for setting up GitLab for your own organization, including sample issues, merge requests, and milestones"
msgstr ""
@@ -3838,34 +3852,34 @@ msgid "An instance-level serverless domain already exists."
msgstr ""
msgid "An issue already exists"
-msgstr ""
+msgstr "Der findes allerede en problemstilling"
msgid "An unauthenticated user"
msgstr ""
msgid "An unexpected error occurred while checking the project environment."
-msgstr ""
+msgstr "Der opstod en uventet fejl under tjek af projektmiljøet."
msgid "An unexpected error occurred while checking the project runners."
msgstr ""
msgid "An unexpected error occurred while communicating with the Web Terminal."
-msgstr ""
+msgstr "Der opstod en uventet fejl under kommunikation med Web Terminal."
msgid "An unexpected error occurred while loading the code quality diff."
msgstr ""
msgid "An unexpected error occurred while starting the Web Terminal."
-msgstr ""
+msgstr "Der opstod en uventet fejl under start af Web Terminal."
msgid "An unexpected error occurred while stopping the Web Terminal."
-msgstr ""
+msgstr "Der opstod en uventet fejl under stop af Web Terminal."
msgid "An unknown error occurred while loading this graph."
-msgstr ""
+msgstr "Der opstod en ukendt fejl under indlæsning af grafen."
msgid "An unknown error occurred."
-msgstr ""
+msgstr "Der opstod en ukendt fejl."
msgid "Analytics"
msgstr ""
@@ -3874,16 +3888,16 @@ msgid "Analyze a review version of your web application."
msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
-msgstr ""
+msgstr "Analyser dine afhængigheder for kendte sårbarheder."
msgid "Analyze your source code and git history for secrets."
-msgstr ""
+msgstr "Analyser din kildekode og git-historik for hemmeligheder."
msgid "Analyze your source code for known vulnerabilities."
-msgstr ""
+msgstr "Analyser din kildekode for kendte sårbarheder."
msgid "Analyzing file…"
-msgstr ""
+msgstr "Analyserer fil …"
msgid "Ancestors"
msgstr ""
@@ -3892,7 +3906,7 @@ msgid "And this registration token:"
msgstr ""
msgid "Anonymous"
-msgstr ""
+msgstr "Anonym"
msgid "Another action is currently in progress"
msgstr ""
@@ -3904,7 +3918,7 @@ msgid "Anti-spam verification"
msgstr ""
msgid "Any"
-msgstr ""
+msgstr "Alle"
msgid "Any %{header}"
msgstr ""
@@ -3940,16 +3954,16 @@ msgid "Any namespace"
msgstr ""
msgid "App ID"
-msgstr ""
+msgstr "Program-id"
msgid "Appearance"
-msgstr ""
+msgstr "Udseende"
msgid "Appearance was successfully created."
-msgstr ""
+msgstr "Udseende blev oprettet."
msgid "Appearance was successfully updated."
-msgstr ""
+msgstr "Udseende blev opdateret."
msgid "Append the comment with %{shrug}"
msgstr ""
@@ -3958,10 +3972,10 @@ msgid "Append the comment with %{tableflip}"
msgstr ""
msgid "Application"
-msgstr ""
+msgstr "Program"
msgid "Application ID"
-msgstr ""
+msgstr "Program-id"
msgid "Application limits saved successfully"
msgstr ""
@@ -3982,26 +3996,26 @@ msgid "Application was successfully updated."
msgstr ""
msgid "Application: %{name}"
-msgstr ""
+msgstr "Program: %{name}"
msgid "ApplicationSettings|After sign up text"
-msgstr ""
+msgstr "Tekst efter tilmelding"
msgid "ApplicationSettings|Allowed domains for sign-ups"
-msgstr ""
+msgstr "Tilladte domæner ved tilmeldinger"
msgid "ApplicationSettings|Approve %d user"
msgid_plural "ApplicationSettings|Approve %d users"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Godkend %d bruger"
+msgstr[1] "Godkend %d brugere"
msgid "ApplicationSettings|Approve users in the pending approval status?"
-msgstr ""
+msgstr "Godkend brugere med statussen afventer godkendelse?"
msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Ved at foretage ændringen godkender du automatisk %d bruger med statussen afventer godkendelse."
+msgstr[1] "Ved at foretage ændringen godkender du automatisk %d brugere med statussen afventer godkendelse."
msgid "ApplicationSettings|Denied domains for sign-ups"
msgstr ""
@@ -4013,22 +4027,22 @@ msgid "ApplicationSettings|Domain denylist"
msgstr ""
msgid "ApplicationSettings|Email restrictions"
-msgstr ""
+msgstr "Restriktioner for e-mail"
msgid "ApplicationSettings|Email restrictions for sign-ups"
-msgstr ""
+msgstr "Restriktioner for e-mail ved tilmeldinger"
msgid "ApplicationSettings|Enable domain denylist for sign ups"
msgstr ""
msgid "ApplicationSettings|Enable email restrictions for sign ups"
-msgstr ""
+msgstr "Aktivér restriktioner for e-mail ved tilmeldinger"
msgid "ApplicationSettings|Enter denylist manually"
msgstr ""
msgid "ApplicationSettings|Markdown enabled"
-msgstr ""
+msgstr "Markdown aktiveret"
msgid "ApplicationSettings|Minimum password length (number of characters)"
msgstr ""
@@ -4040,28 +4054,28 @@ msgid "ApplicationSettings|Once the instance reaches the user cap, any user who
msgstr ""
msgid "ApplicationSettings|Require admin approval for new sign-ups"
-msgstr ""
+msgstr "Kræv administratorgodkendelse ved nye tilmeldinger"
msgid "ApplicationSettings|Restricts sign-ups for email addresses that match the given regex. See the %{linkStart}supported syntax%{linkEnd} for more information."
msgstr ""
msgid "ApplicationSettings|Save changes"
-msgstr ""
+msgstr "Gem ændringer"
msgid "ApplicationSettings|See GitLab's %{linkStart}Password Policy Guidelines%{linkEnd}"
msgstr ""
msgid "ApplicationSettings|Send confirmation email on sign-up"
-msgstr ""
+msgstr "Send bekræftelses e-mail ved tilmelding"
msgid "ApplicationSettings|Sign-up enabled"
-msgstr ""
+msgstr "Tilmelding aktiveret"
msgid "ApplicationSettings|Upload denylist file"
msgstr ""
msgid "ApplicationSettings|User cap"
-msgstr ""
+msgstr "Brugerloft"
msgid "ApplicationSettings|Users with e-mail addresses that match these domain(s) will NOT be able to sign-up. Wildcards allowed. Use separate lines for multiple entries. Ex: domain.com, *.domain.com"
msgstr ""
@@ -4073,164 +4087,185 @@ msgid "ApplicationSettings|When enabled, any user visiting %{host} and creating
msgstr ""
msgid "ApplicationSettings|When enabled, any user visiting %{host} will be able to create an account."
-msgstr ""
+msgstr "Når den er aktiveret, så vil brugere der besøger %{host} være i stand til at oprette en konto."
msgid "ApplicationSettings|domain.com"
-msgstr ""
+msgstr "domain.com"
msgid "Applications"
-msgstr ""
+msgstr "Programmer"
msgid "Applied"
-msgstr ""
+msgstr "Anvendt"
msgid "Apply"
-msgstr ""
+msgstr "Anvend"
msgid "Apply a label"
-msgstr ""
+msgstr "Anvend en etiket"
msgid "Apply a template"
-msgstr ""
+msgstr "Anvend en skabelon"
msgid "Apply suggestion"
-msgstr ""
+msgstr "Anvend forslag"
msgid "Apply suggestions"
-msgstr ""
+msgstr "Anvend forslag"
msgid "Apply template"
-msgstr ""
+msgstr "Anvend skabelon"
msgid "Apply this approval rule to any branch or a specific protected branch."
msgstr ""
msgid "Applying"
-msgstr ""
+msgstr "Anvender"
msgid "Applying a template will replace the existing issue description. Any changes you have made will be lost."
msgstr ""
msgid "Applying command"
-msgstr ""
+msgstr "Anvender kommando"
msgid "Applying command to %{commandDescription}"
-msgstr ""
+msgstr "Anvender kommando på %{commandDescription}"
msgid "Applying multiple commands"
-msgstr ""
+msgstr "Anvender flere kommandoer"
msgid "Applying suggestion..."
-msgstr ""
+msgstr "Anvender forslag ..."
msgid "Applying suggestions..."
-msgstr ""
+msgstr "Anvender forslag ..."
msgid "Approval Status"
-msgstr ""
+msgstr "Godkendelsesstatus"
msgid "Approval rules"
-msgstr ""
+msgstr "Godkendelsesregler"
msgid "Approval rules reset to project defaults"
-msgstr ""
+msgstr "Godkendelsesregler nulstillet til projektstandarder"
msgid "Approval settings"
-msgstr ""
+msgstr "Godkendelsesindstillinger"
msgid "ApprovalRuleRemove|%d member"
msgid_plural "ApprovalRuleRemove|%d members"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d medlem"
+msgstr[1] "%d medlemmer"
msgid "ApprovalRuleRemove|You are about to remove the %{name} approver group which has %{strongStart}%{count} member%{strongEnd}. Approvals from this member are not revoked."
msgid_plural "ApprovalRuleRemove|You are about to remove the %{name} approver group which has %{strongStart}%{count} members%{strongEnd}. Approvals from these members are not revoked."
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Du er ved at fjerne godkendergruppen %{name} som har %{strongStart}%{count} medlem%{strongEnd}. Godkendelser fra medlemmet tilbagekaldes ikke."
+msgstr[1] "Du er ved at fjerne godkendergruppen %{name} som har %{strongStart}%{count} medlemmer%{strongEnd}. Godkendelser fra medlemmerne tilbagekaldes ikke."
msgid "ApprovalRuleSummary|%d member"
msgid_plural "ApprovalRuleSummary|%d members"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d medlem"
+msgstr[1] "%d medlemmer"
msgid "ApprovalRuleSummary|%{count} approval required from %{membersCount}"
msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCount}"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{count} godkendelse kræves fra %{membersCount}"
+msgstr[1] "%{count} godkendelser kræves fra %{membersCount}"
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
-msgstr ""
+msgstr "Tilføj godkendere"
msgid "ApprovalRule|All scanners"
+msgstr "Alle skannere"
+
+msgid "ApprovalRule|All severity levels"
msgstr ""
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
-msgid "ApprovalRule|Approval rules"
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
msgstr ""
+msgid "ApprovalRule|Approval rules"
+msgstr "Godkendelsesregler"
+
msgid "ApprovalRule|Approvals required"
-msgstr ""
+msgstr "Godkendelser kræves"
msgid "ApprovalRule|Approver Type"
-msgstr ""
+msgstr "Godkendertype"
msgid "ApprovalRule|Approvers"
-msgstr ""
+msgstr "Godkendere"
msgid "ApprovalRule|Examples: QA, Security."
-msgstr ""
+msgstr "Eksempler: kvalitetssikring, sikkerhed."
msgid "ApprovalRule|Name"
-msgstr ""
+msgstr "Navn"
msgid "ApprovalRule|Number of vulnerabilities allowed before approval rule is triggered."
-msgstr ""
+msgstr "Antal sårbarheder som er tilladt før godkendelsesreglen udløses."
msgid "ApprovalRule|Please enter a number equal or greater than zero"
-msgstr ""
+msgstr "Indtast venligst et tal fra 0 og op"
msgid "ApprovalRule|Please select at least one security scanner"
+msgstr "Vælg venligst mindst én sikkerhedsskanner"
+
+msgid "ApprovalRule|Please select at least one severity level"
msgstr ""
msgid "ApprovalRule|Rule name"
-msgstr ""
+msgstr "Regelnavn"
msgid "ApprovalRule|Security scanners"
-msgstr ""
+msgstr "Sikkerhedsskannere"
msgid "ApprovalRule|Select All"
-msgstr ""
+msgstr "Vælg alle"
msgid "ApprovalRule|Select scanners"
+msgstr "Vælg skannere"
+
+msgid "ApprovalRule|Select severity levels"
msgstr ""
-msgid "ApprovalRule|Target branch"
+msgid "ApprovalRule|Severity levels"
msgstr ""
+msgid "ApprovalRule|Target branch"
+msgstr "MÃ¥lgren"
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4252,46 +4287,46 @@ msgid "ApprovalStatusTooltip|Fails to adhere to separation of duties"
msgstr ""
msgid "Approvals are optional."
-msgstr ""
+msgstr "Godkendelser er valgfrie."
msgid "Approvals|Section: %section"
-msgstr ""
+msgstr "Afsnit: %section"
msgid "Approve"
-msgstr ""
+msgstr "Godkend"
msgid "Approve a merge request"
-msgstr ""
+msgstr "Godkend en sammenlægningsanmodning"
msgid "Approve the current merge request."
-msgstr ""
+msgstr "Godkend den nuværende sammenlægningsanmodning."
msgid "Approved"
-msgstr ""
+msgstr "Godkendt"
msgid "Approved MRs"
-msgstr ""
+msgstr "Godkendte sammenlægningsanmodninger"
msgid "Approved the current merge request."
-msgstr ""
+msgstr "Godkendte den nuværende sammenlægningsanmodning."
msgid "Approved-By"
-msgstr ""
+msgstr "Godkendt-af"
msgid "Approver"
-msgstr ""
+msgstr "Godkender"
msgid "Approvers"
-msgstr ""
+msgstr "Godkendere"
msgid "Approvers from private group(s) not shown"
msgstr ""
msgid "Apr"
-msgstr ""
+msgstr "Apr."
msgid "April"
-msgstr ""
+msgstr "April"
msgid "Architecture not found for OS"
msgstr ""
@@ -4309,58 +4344,61 @@ msgid "Archive test case"
msgstr ""
msgid "Archived"
-msgstr ""
+msgstr "Arkiveret"
msgid "Archived (%{movedToStart}moved%{movedToEnd})"
-msgstr ""
+msgstr "Arkiveret (%{movedToStart}flyttet%{movedToEnd})"
msgid "Archived in this version"
-msgstr ""
+msgstr "Arkiveret i versionen"
msgid "Archived project! Repository and other project resources are read-only"
-msgstr ""
+msgstr "Arkiveret projekt! Depotet og andre projektressourcer er skrivebeskyttet"
msgid "Archived projects"
-msgstr ""
+msgstr "Arkiverede projekter"
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
-msgstr ""
+msgstr "Er du HELT SIKKER på, at du vil slette projektet?"
msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
-msgstr ""
+msgstr "Er du HELT SIKKER på, at du vil fjerne gruppen?"
msgid "Are you sure that you want to archive this project?"
-msgstr ""
+msgstr "Er du sikker på, at du vil arkivere projektet?"
msgid "Are you sure that you want to unarchive this project?"
-msgstr ""
+msgstr "Er du sikker på, at du vil afarkivere projektet?"
msgid "Are you sure you want to %{action} %{name}?"
+msgstr "Er du sikker på, at du vil %{action} %{name}?"
+
+msgid "Are you sure you want to attempt to merge?"
msgstr ""
msgid "Are you sure you want to cancel editing this comment?"
-msgstr ""
+msgstr "Er du sikker på, at du vil annullere redigering af kommentaren?"
msgid "Are you sure you want to close this blocked issue?"
-msgstr ""
+msgstr "Er du sikker på, at du vil lukke den blokerede problemstilling?"
msgid "Are you sure you want to delete %{name}?"
-msgstr ""
+msgstr "Er du sikker på, at du vil slette %{name}?"
msgid "Are you sure you want to delete these artifacts?"
-msgstr ""
+msgstr "Er du sikker på, at du vil slette artefakterne?"
msgid "Are you sure you want to delete this %{typeOfComment}?"
msgstr ""
msgid "Are you sure you want to delete this SSH key?"
-msgstr ""
+msgstr "Er du sikker på, at du vil slette SSH-nøglen?"
msgid "Are you sure you want to delete this device? This action cannot be undone."
-msgstr ""
+msgstr "Er du sikker på, at du vil slette enheden? Handlingen kan ikke fortrydes."
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4369,105 +4407,105 @@ msgid "Are you sure you want to delete this pipeline? Doing so will expire all p
msgstr ""
msgid "Are you sure you want to deploy this environment?"
-msgstr ""
+msgstr "Er du sikker på, at du vil udsende miljøet?"
msgid "Are you sure you want to discard this comment?"
-msgstr ""
+msgstr "Er du sikker på, at du vil forkaste kommentaren?"
msgid "Are you sure you want to discard your changes?"
-msgstr ""
+msgstr "Er du sikker på, at du vil forkaste dine ændringer?"
msgid "Are you sure you want to erase this build?"
msgstr ""
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Er du sikker på, at du vil importere %d depot?"
+msgstr[1] "Er du sikker på, at du vil importere %d depoter?"
msgid "Are you sure you want to lock %{path}?"
-msgstr ""
+msgstr "Er du sikker på, at du vil låse %{path}?"
msgid "Are you sure you want to lock this directory?"
-msgstr ""
+msgstr "Er du sikker på, at du vil låse mappen?"
msgid "Are you sure you want to lose unsaved changes?"
-msgstr ""
+msgstr "Er du sikker på, at du vil kassere ændringer som ikke er blevet gemt?"
msgid "Are you sure you want to lose your issue information?"
-msgstr ""
+msgstr "Er du sikker på, at du vil miste din problemstillingsinformation?"
msgid "Are you sure you want to merge immediately?"
-msgstr ""
+msgstr "Er du sikker på, at du vil sammenlægge straks?"
msgid "Are you sure you want to re-deploy this environment?"
-msgstr ""
+msgstr "Er du sikker på, at du vil genudsende miljøet?"
msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
+msgstr "Er du sikker på, at du vil regenerere den offentlige nøgle? Du skal opdatere den offentlige nøgle på fjernserveren, før spejling fungerer igen."
msgid "Are you sure you want to reindex?"
-msgstr ""
+msgstr "Er du sikker på, at du vil genindeksere?"
msgid "Are you sure you want to remove %{email}?"
-msgstr ""
+msgstr "Er du sikker på, at du vil fjerne %{email}?"
msgid "Are you sure you want to remove %{group_name}?"
-msgstr ""
+msgstr "Er du sikker på, at du vil fjerne %{group_name}?"
msgid "Are you sure you want to remove the attachment?"
-msgstr ""
+msgstr "Er du sikker på, at du vil fjerne vedhæftningen?"
msgid "Are you sure you want to remove the license?"
-msgstr ""
+msgstr "Er du sikker på, at du vil fjerne licensen?"
msgid "Are you sure you want to remove this deploy key? If anything is still using this key, it will stop working."
-msgstr ""
+msgstr "Er du sikker på, at du vil fjerne udsendelsesnøglen? Hvis der er noget som stadigvæk bruger nøglen, så vil det stoppe med at virke."
msgid "Are you sure you want to remove this identity?"
-msgstr ""
+msgstr "Er du sikker på, at du vil fjerne identiteten?"
msgid "Are you sure you want to remove this list?"
-msgstr ""
+msgstr "Er du sikker på, at du vil fjerne listen?"
msgid "Are you sure you want to reset the SCIM token? SCIM provisioning will stop working until the new token is updated."
msgstr ""
msgid "Are you sure you want to reset the health check token?"
-msgstr ""
+msgstr "Er du sikker på, at du vil nulstille tokenen til sundhedstjek?"
msgid "Are you sure you want to reset the registration token?"
-msgstr ""
+msgstr "Er du sikker på, at du vil nulstille tokenen til registrering?"
msgid "Are you sure you want to retry this migration?"
-msgstr ""
+msgstr "Er du sikker på, at du vil prøve migreringen igen?"
msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
-msgstr ""
+msgstr "Er du sikker på, at du vil tilbagekalde denne %{type}? Handlingen kan ikke fortrydes."
msgid "Are you sure you want to revoke this nickname?"
-msgstr ""
+msgstr "Er du sikker på, at du vil tilbagekalde kaldenavnet?"
msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
-msgstr ""
+msgstr "Er du sikker på, at du vil tilbagekalde den personlige adgangstoken? Handlingen kan ikke fortrydes."
msgid "Are you sure you want to stop this environment?"
-msgstr ""
+msgstr "Er du sikker på, at du vil stoppe miljøet?"
msgid "Are you sure you want to unlock %{path_lock_path}?"
-msgstr ""
+msgstr "Er du sikker på, at du vil oplåse %{path_lock_path}?"
msgid "Are you sure you want to unlock %{path}?"
-msgstr ""
+msgstr "Er du sikker på, at du vil oplåse %{path}?"
msgid "Are you sure you want to unlock this directory?"
-msgstr ""
+msgstr "Er du sikker på, at du vil oplåse mappen?"
msgid "Are you sure you want to unsubscribe from the %{type}: %{link_to_noteable_text}?"
msgstr ""
msgid "Are you sure?"
-msgstr ""
+msgstr "Er du sikker?"
msgid "Are you sure? All commits that were signed with this GPG key will be unverified."
msgstr ""
@@ -4488,19 +4526,16 @@ msgid "Arrange charts"
msgstr ""
msgid "Artifact"
-msgstr ""
+msgstr "Artefakt"
msgid "Artifact could not be deleted."
-msgstr ""
+msgstr "Artefaktet kunne ikke slettes."
msgid "Artifact was successfully deleted."
-msgstr ""
+msgstr "Artefaktet blev slettet."
msgid "Artifacts"
-msgstr ""
-
-msgid "Artifacts maximum size"
-msgstr ""
+msgstr "Artefakter"
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4509,7 +4544,7 @@ msgid "AsanaService|%{user} pushed to branch %{branch} of %{project_name} ( %{co
msgstr ""
msgid "AsanaService|Add commit messages as comments to Asana tasks."
-msgstr ""
+msgstr "Tilføj commit-meddelelser som kommentarer til Asana-opgaver."
msgid "AsanaService|Comma-separated list of branches to be automatically inspected. Leave blank to include all branches."
msgstr ""
@@ -4518,10 +4553,10 @@ msgid "AsanaService|User Personal Access Token. User must have access to the tas
msgstr ""
msgid "Ascending"
-msgstr ""
+msgstr "Stigende"
msgid "Ask again later"
-msgstr ""
+msgstr "Spørg igen senere"
msgid "Ask someone with write access to resolve it."
msgstr ""
@@ -4539,34 +4574,34 @@ msgid "Assets:"
msgstr ""
msgid "Assign"
-msgstr ""
+msgstr "Tildel"
msgid "Assign Iteration"
-msgstr ""
+msgstr "Tildel gennemløb"
msgid "Assign To"
-msgstr ""
+msgstr "Tildel til"
msgid "Assign custom color like #FF0000"
-msgstr ""
+msgstr "Tildel tilpasset farve såsom #FF0000"
msgid "Assign labels"
-msgstr ""
+msgstr "Tildel etiketter"
msgid "Assign milestone"
-msgstr ""
+msgstr "Tildel milepæl"
msgid "Assign reviewer"
-msgstr ""
+msgstr "Tildel kontrollant"
msgid "Assign reviewer(s)"
-msgstr ""
+msgstr "Tildel kontrollanter"
msgid "Assign some issues to this milestone."
-msgstr ""
+msgstr "Tildel nogle problemstillinger til milepælen."
msgid "Assign to"
-msgstr ""
+msgstr "Tildel til"
msgid "Assign to commenting user"
msgstr ""
@@ -4578,34 +4613,34 @@ msgid "Assign yourself to this issue"
msgstr ""
msgid "Assigned %{assignee_users_sentence}."
-msgstr ""
+msgstr "Tildelte %{assignee_users_sentence}."
msgid "Assigned %{reviewer_users_sentence} as %{reviewer_text}."
-msgstr ""
+msgstr "Tildelte %{reviewer_users_sentence} som %{reviewer_text}."
msgid "Assigned Issues"
-msgstr ""
+msgstr "Tildelte problemstillinger"
msgid "Assigned merge requests"
msgstr ""
msgid "Assigned projects"
-msgstr ""
+msgstr "Tildelte projekter"
msgid "Assigned to %{assigneeName}"
-msgstr ""
+msgstr "Tildelt til %{assigneeName}"
msgid "Assigned to %{assignee_name}"
-msgstr ""
+msgstr "Tildelt til %{assignee_name}"
msgid "Assigned to %{name}"
-msgstr ""
+msgstr "Tildelt til %{name}"
msgid "Assigned to me"
-msgstr ""
+msgstr "Tildelt til mig"
msgid "Assigned to you"
-msgstr ""
+msgstr "Tildelt til dig"
msgid "Assignee"
msgid_plural "%d Assignees"
@@ -4616,22 +4651,19 @@ msgid "Assignee has no permissions"
msgstr ""
msgid "Assignee lists not available with your current license"
-msgstr ""
-
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
+msgstr "Tildeltelister ikke tilgængelige med din nuværende licens"
msgid "Assignee(s)"
-msgstr ""
+msgstr "Tildelte"
msgid "Assignees"
msgstr ""
msgid "Assigns %{assignee_users_sentence}."
-msgstr ""
+msgstr "Tildeler %{assignee_users_sentence}."
msgid "Assigns %{reviewer_users_sentence} as %{reviewer_text}."
-msgstr ""
+msgstr "Tildeler %{reviewer_users_sentence} som %{reviewer_text}."
msgid "At least one approval from a code owner is required to change files matching the respective CODEOWNER rules."
msgstr ""
@@ -4652,75 +4684,75 @@ msgid "At risk"
msgstr ""
msgid "Attach a file"
-msgstr ""
+msgstr "Vedhæft en fil"
msgid "Attach a file by drag &amp; drop or %{upload_link}"
-msgstr ""
+msgstr "Vedhæft en fil ved at trække og slippe, eller %{upload_link}"
msgid "Attaching File - %{progress}"
-msgstr ""
+msgstr "Vedhæfter fil - %{progress}"
msgid "Attaching a file"
msgid_plural "Attaching %d files"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Vedhæfter en fil"
+msgstr[1] "Vedhæfter %d filer"
msgid "Attaching the file failed."
-msgstr ""
+msgstr "Kunne ikke vedhæfte filen."
msgid "Audit Events"
msgstr ""
msgid "AuditLogs|(removed)"
-msgstr ""
+msgstr "(fjernet)"
msgid "AuditLogs|Action"
-msgstr ""
+msgstr "Handling"
msgid "AuditLogs|Author"
-msgstr ""
+msgstr "Forfatter"
msgid "AuditLogs|Date"
-msgstr ""
+msgstr "Dato"
msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
msgstr ""
msgid "AuditLogs|Failed to find %{type}. Please try again."
-msgstr ""
+msgstr "Kunne ikke finde %{type}. Prøv venligst igen."
msgid "AuditLogs|Group Events"
-msgstr ""
+msgstr "Gruppebegivenheder"
msgid "AuditLogs|IP Address"
-msgstr ""
+msgstr "IP-adresse"
msgid "AuditLogs|Member Events"
-msgstr ""
+msgstr "Medlemsbegivenheder"
msgid "AuditLogs|No matching %{type} found."
msgstr ""
msgid "AuditLogs|Object"
-msgstr ""
+msgstr "Objekt"
msgid "AuditLogs|Project Events"
-msgstr ""
+msgstr "Projektbegivenheder"
msgid "AuditLogs|Target"
-msgstr ""
+msgstr "MÃ¥l"
msgid "AuditLogs|This month"
-msgstr ""
+msgstr "Denne måned"
msgid "AuditLogs|User Events"
-msgstr ""
+msgstr "Brugerbegivenheder"
msgid "Aug"
-msgstr ""
+msgstr "Aug."
msgid "August"
-msgstr ""
+msgstr "August"
msgid "Authenticate"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4756,31 +4794,31 @@ msgid "Authentication Failure"
msgstr ""
msgid "Authentication Log"
-msgstr ""
+msgstr "Godkendelseslog"
msgid "Authentication failed: %{error_message}"
-msgstr ""
+msgstr "Godkendelse mislykkedes: %{error_message}"
msgid "Authentication log"
-msgstr ""
+msgstr "Godkendelseslog"
msgid "Authentication method"
-msgstr ""
+msgstr "Godkendelsesmetode"
msgid "Authentication method updated"
-msgstr ""
+msgstr "Godkendelsesmetode opdateret"
msgid "Authentication via U2F device failed."
-msgstr ""
+msgstr "Godkendelse via U2F-enhed mislykkedes."
msgid "Authentication via WebAuthn device failed."
msgstr ""
msgid "Author"
-msgstr ""
+msgstr "Forfatter"
msgid "Author: %{author_name}"
-msgstr ""
+msgstr "Forfatter: %{author_name}"
msgid "Authored %{timeago}"
msgstr ""
@@ -4789,10 +4827,10 @@ msgid "Authored %{timeago} by %{author}"
msgstr ""
msgid "Authorization code:"
-msgstr ""
+msgstr "Godkendelseskode:"
msgid "Authorization key"
-msgstr ""
+msgstr "Godkendelsesnøgle"
msgid "Authorization required"
msgstr ""
@@ -4801,10 +4839,10 @@ msgid "Authorization token duration (minutes)"
msgstr ""
msgid "Authorization was granted by entering your username and password in the application."
-msgstr ""
+msgstr "Godkendelse blev givet ved indtastning af dit brugernavn og adgangskode i programmet."
msgid "Authorize"
-msgstr ""
+msgstr "Godkend"
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
@@ -4819,16 +4857,16 @@ msgid "Authorized At"
msgstr ""
msgid "Authorized applications (%{size})"
-msgstr ""
+msgstr "Godkendte programmer (%{size})"
msgid "Authors: %{authors}"
-msgstr ""
+msgstr "Forfattere: %{authors}"
msgid "Auto DevOps"
-msgstr ""
+msgstr "Auto DevOps"
msgid "Auto DevOps enabled"
-msgstr ""
+msgstr "Auto DevOps aktiveret"
msgid "Auto stop successfully canceled."
msgstr ""
@@ -4843,22 +4881,22 @@ msgid "AutoDevOps|%{auto_devops_start}Automate building, testing, and deploying%
msgstr ""
msgid "AutoDevOps|Auto DevOps"
-msgstr ""
+msgstr "Auto DevOps"
msgid "AutoDevOps|Auto DevOps documentation"
-msgstr ""
+msgstr "Dokumentation for Auto DevOps"
msgid "AutoDevOps|Dismiss Auto DevOps box"
msgstr ""
msgid "AutoDevOps|Enable in settings"
-msgstr ""
+msgstr "Aktivér i indstillinger"
msgid "AutoDevOps|It will automatically build, test, and deploy your application based on a predefined CI/CD configuration."
msgstr ""
msgid "AutoDevOps|Learn more in the %{link_to_documentation}"
-msgstr ""
+msgstr "Lær mere i %{link_to_documentation}"
msgid "AutoDevOps|The Auto DevOps pipeline has been enabled and will be used if no alternative CI configuration file is found."
msgstr ""
@@ -4914,11 +4952,14 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
msgid "Automatically resolved"
-msgstr ""
+msgstr "Automatisk løst"
msgid "Automatically update this project's branches and tags from the upstream repository every hour."
msgstr ""
@@ -4927,7 +4968,7 @@ msgid "Autosave|Note"
msgstr ""
msgid "Available"
-msgstr ""
+msgstr "Tilgængelig"
msgid "Available ID"
msgstr ""
@@ -4945,124 +4986,124 @@ msgid "Available specific runners"
msgstr ""
msgid "Avatar for %{assigneeName}"
-msgstr ""
+msgstr "Avatar til %{assigneeName}"
msgid "Avatar for %{name}"
-msgstr ""
+msgstr "Avatar til %{name}"
msgid "Avatar will be removed. Are you sure?"
-msgstr ""
+msgstr "Avataren fjernes. Er du sikker?"
msgid "Average per day: %{average}"
-msgstr ""
+msgstr "Gennemsnit pr. dag: %{average}"
msgid "Award added"
-msgstr ""
+msgstr "Pris tilføjet"
msgid "Award removed"
-msgstr ""
+msgstr "Pris fjernet"
msgid "AwardEmoji|No emojis found."
-msgstr ""
+msgstr "Ingen emojis fundet."
msgid "Back"
-msgstr ""
+msgstr "Tilbage"
msgid "Back to page %{number}"
-msgstr ""
+msgstr "Tilbage til side %{number}"
msgid "Background Color"
-msgstr ""
+msgstr "Baggrundsfarve"
msgid "Background Jobs"
-msgstr ""
+msgstr "Baggrundsjob"
msgid "Background Migrations"
msgstr ""
msgid "Background color"
-msgstr ""
+msgstr "Baggrundsfarve"
msgid "Badges"
-msgstr ""
+msgstr "Badges"
msgid "Badges|Add badge"
-msgstr ""
+msgstr "Tilføj badge"
msgid "Badges|Adding the badge failed, please check the entered URLs and try again."
-msgstr ""
+msgstr "Tilføjelse af badget mislykkedes. Tjek venligst de indtastede URL'er og prøv igen."
msgid "Badges|Badge image URL"
-msgstr ""
+msgstr "URL for badgebillede"
msgid "Badges|Badge image preview"
-msgstr ""
+msgstr "Forhåndsvisning af badgebillede"
msgid "Badges|Badge saved."
-msgstr ""
+msgstr "Badge gemt."
msgid "Badges|Delete badge?"
-msgstr ""
+msgstr "Slet badge?"
msgid "Badges|Deleting the badge failed, please try again."
-msgstr ""
+msgstr "Sletning af badget mislykkedes. Prøv venligst igen."
msgid "Badges|Enter a valid URL"
-msgstr ""
+msgstr "Indtast en gyldig URL"
msgid "Badges|Example: %{exampleUrl}"
-msgstr ""
+msgstr "Eksempel: %{exampleUrl}"
msgid "Badges|Group Badge"
-msgstr ""
+msgstr "Gruppebadge"
msgid "Badges|Link"
-msgstr ""
+msgstr "Link"
msgid "Badges|Name"
-msgstr ""
+msgstr "Navn"
msgid "Badges|New badge added."
-msgstr ""
+msgstr "Ny badge tilføjet."
msgid "Badges|No badge image"
-msgstr ""
+msgstr "Intet badgebillede"
msgid "Badges|No image to preview"
-msgstr ""
+msgstr "Intet billede at forhåndsvise"
msgid "Badges|Project Badge"
-msgstr ""
+msgstr "Projektbadge"
msgid "Badges|Reload badge image"
-msgstr ""
+msgstr "Genindlæs badgebillede"
msgid "Badges|Save changes"
-msgstr ""
+msgstr "Gem ændringer"
msgid "Badges|Saving the badge failed, please check the entered URLs and try again."
-msgstr ""
+msgstr "Kunne ikke gemme badget. Tjek venligst de indtastede URL'er og prøv igen."
msgid "Badges|Supported %{docsLinkStart}variables%{docsLinkEnd}: %{placeholders}"
-msgstr ""
+msgstr "Understøttede %{docsLinkStart}variabler%{docsLinkEnd}: %{placeholders}"
msgid "Badges|The badge was deleted."
-msgstr ""
+msgstr "Badget blev slettet."
msgid "Badges|This group has no badges"
-msgstr ""
+msgstr "Gruppen har ingen badges"
msgid "Badges|This project has no badges"
-msgstr ""
+msgstr "Projektet har ingen badges"
msgid "Badges|You are going to delete this badge. Deleted badges %{strongStart}cannot%{strongEnd} be restored."
msgstr ""
msgid "Badges|Your badges"
-msgstr ""
+msgstr "Dine badges"
msgid "Balsamiq file could not be loaded."
-msgstr ""
+msgstr "Balsamiq-filen kunne ikke indlæses."
msgid "BambooService|Atlassian Bamboo"
msgstr ""
@@ -5086,7 +5127,7 @@ msgid "BambooService|The user with API access to the Bamboo server."
msgstr ""
msgid "Based on"
-msgstr ""
+msgstr "Baseret på"
msgid "Be careful. Changing the project's namespace can have unintended side effects."
msgstr ""
@@ -5104,10 +5145,7 @@ msgid "Before this can be merged, a Jira issue must be linked in the title or de
msgstr ""
msgid "Begin with the selected commit"
-msgstr ""
-
-msgid "Below are the current settings regarding"
-msgstr ""
+msgstr "Begynd med den valgte commit"
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5116,10 +5154,10 @@ msgid "Below are the settings for %{link_to_gitlab_pages}."
msgstr ""
msgid "Below you will find all the groups that are public."
-msgstr ""
+msgstr "Nedenunder finder du alle de grupper, som er offentlige."
msgid "Beta"
-msgstr ""
+msgstr "Beta"
msgid "Bi-weekly code coverage"
msgstr ""
@@ -5137,7 +5175,7 @@ msgid "BillingPlans|@%{user_name} you are currently using the %{plan_name}."
msgstr ""
msgid "BillingPlans|Compare all plans"
-msgstr ""
+msgstr "Sammenlign alle planer"
msgid "BillingPlans|Congratulations, your free trial is activated."
msgstr ""
@@ -5146,7 +5184,7 @@ msgid "BillingPlans|End of availability for the Bronze Plan"
msgstr ""
msgid "BillingPlans|Free upgrade!"
-msgstr ""
+msgstr "Gratis opgradering!"
msgid "BillingPlans|If you would like to downgrade your plan please contact %{support_link_start}Customer Support%{support_link_end}."
msgstr ""
@@ -5161,13 +5199,13 @@ msgid "BillingPlans|Looking to purchase or manage a subscription for your group?
msgstr ""
msgid "BillingPlans|Manage plan"
-msgstr ""
+msgstr "HÃ¥ndter plan"
msgid "BillingPlans|Pricing page"
msgstr ""
msgid "BillingPlans|See all %{plan_name} features"
-msgstr ""
+msgstr "Se alle %{plan_name}-funktioner"
msgid "BillingPlans|This group uses the plan associated with its parent group."
msgstr ""
@@ -5176,7 +5214,7 @@ msgid "BillingPlans|To manage the plan for this group, visit the billing section
msgstr ""
msgid "BillingPlans|Upgrade to GitLab %{planNameForUpgrade}"
-msgstr ""
+msgstr "Opgrader til GitLab %{planNameForUpgrade}"
msgid "BillingPlans|While GitLab is ending availability of the Bronze plan, you can still renew your Bronze subscription one additional time before %{eoa_bronze_plan_end_date}. We are also offering a limited time free upgrade to our Premium Plan (up to 25 users)! Learn more about the changes and offers in our %{announcement_link}."
msgstr ""
@@ -5194,34 +5232,34 @@ msgid "BillingPlans|for the remainder of your subscription"
msgstr ""
msgid "BillingPlans|frequently asked questions"
-msgstr ""
+msgstr "ofte stillede spørgsmål"
msgid "BillingPlans|group"
-msgstr ""
+msgstr "gruppe"
msgid "BillingPlans|monthly"
-msgstr ""
+msgstr "månedligt"
msgid "BillingPlans|per user"
-msgstr ""
+msgstr "pr. bruger"
msgid "BillingPlan|Contact sales"
-msgstr ""
+msgstr "Kontakt salgsafdelingen"
msgid "BillingPlan|Upgrade"
-msgstr ""
+msgstr "Opgrader"
msgid "BillingPlan|Upgrade for free"
-msgstr ""
+msgstr "Opgrader gratis"
msgid "Billings|%{planName} plan"
msgstr ""
msgid "Billings|An error occurred while extending your trial."
-msgstr ""
+msgstr "Der opstod en fejl under forlængelse af din prøveperiode."
msgid "Billings|An error occurred while reactivating your trial."
-msgstr ""
+msgstr "Der opstod en fejl under genaktivering af din prøveperiode."
msgid "Billings|By extending your trial, you will receive an additional 30 days of %{planName}. Your trial can be only extended once."
msgstr ""
@@ -5233,7 +5271,7 @@ msgid "Billings|Extend trial"
msgstr ""
msgid "Billings|Reactivate trial"
-msgstr ""
+msgstr "Genaktivér prøveperiode"
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
@@ -5272,10 +5310,10 @@ msgid "Billing|An error occurred while removing a billable member"
msgstr ""
msgid "Billing|Cannot remove user"
-msgstr ""
+msgstr "Kan ikke fjerne brugeren"
msgid "Billing|Direct memberships"
-msgstr ""
+msgstr "Direkte medlemskaber"
msgid "Billing|Enter at least three characters to search."
msgstr ""
@@ -5284,7 +5322,7 @@ msgid "Billing|Export list"
msgstr ""
msgid "Billing|Group"
-msgstr ""
+msgstr "Gruppe"
msgid "Billing|Group invite"
msgstr ""
@@ -5293,10 +5331,10 @@ msgid "Billing|Members who were invited via a group invitation cannot be removed
msgstr ""
msgid "Billing|No users to display."
-msgstr ""
+msgstr "Ingen brugere at vise."
msgid "Billing|Private"
-msgstr ""
+msgstr "Privat"
msgid "Billing|Project invite"
msgstr ""
@@ -5326,36 +5364,36 @@ msgid "Bitbucket Server import"
msgstr ""
msgid "Bitbucket import"
-msgstr ""
+msgstr "Bitbucket-import"
msgid "Blame"
msgstr ""
msgid "Block user"
-msgstr ""
+msgstr "Blokér bruger"
msgid "Blocked"
-msgstr ""
+msgstr "Blokeret"
msgid "Blocked by %d issue"
msgid_plural "Blocked by %d issues"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Blokeret af %d problemstilling"
+msgstr[1] "Blokeret af %d problemstillinger"
msgid "Blocked issue"
-msgstr ""
+msgstr "Blokeret problemstilling"
msgid "Blocking"
-msgstr ""
+msgstr "Blokerer"
msgid "Blocking issues"
msgstr ""
msgid "Blocks"
-msgstr ""
+msgstr "Blokeringer"
msgid "Blog"
-msgstr ""
+msgstr "Blog"
msgid "Board scope affects which issues are displayed for anyone who visits this board"
msgstr ""
@@ -5364,13 +5402,13 @@ msgid "BoardNewIssue|No matching results"
msgstr ""
msgid "BoardNewIssue|Projects"
-msgstr ""
+msgstr "Projekter"
msgid "BoardNewIssue|Search projects"
-msgstr ""
+msgstr "Søg efter projekter"
msgid "BoardNewIssue|Select a project"
-msgstr ""
+msgstr "Vælg et projekt"
msgid "BoardScope|An error occurred while getting milestones, please try again."
msgstr ""
@@ -5388,16 +5426,13 @@ msgid "BoardScope|Assignee"
msgstr ""
msgid "BoardScope|Edit"
-msgstr ""
+msgstr "Rediger"
msgid "BoardScope|Milestone"
-msgstr ""
-
-msgid "BoardScope|No matching results"
-msgstr ""
+msgstr "Milepæl"
msgid "BoardScope|No milestone"
-msgstr ""
+msgstr "Ingen milepæl"
msgid "BoardScope|Search milestones"
msgstr ""
@@ -5406,6 +5441,9 @@ msgid "BoardScope|Select assignee"
msgstr ""
msgid "BoardScope|Select milestone"
+msgstr "Vælg milepæl"
+
+msgid "BoardScope|Select weight"
msgstr ""
msgid "BoardScope|Started"
@@ -5414,11 +5452,14 @@ msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
-msgid "Boards"
+msgid "BoardScope|Weight"
msgstr ""
+msgid "Boards"
+msgstr "Tavler"
+
msgid "Boards and Board Lists"
-msgstr ""
+msgstr "Tavler og tavlelister"
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
msgid_plural "Boards|+ %{displayedIssuablesCount} more %{issuableType}s"
@@ -5426,13 +5467,13 @@ msgstr[0] ""
msgstr[1] ""
msgid "Boards|An error occurred while creating the epic. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl under oprettelse af epicen. Prøv venligst igen."
msgid "Boards|An error occurred while creating the issue. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl under oprettelse af problemstillingen. Prøv venligst igen."
msgid "Boards|An error occurred while creating the list. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl under oprettelse af listen. Prøv venligst igen."
msgid "Boards|An error occurred while fetching group projects. Please try again."
msgstr ""
@@ -5475,218 +5516,215 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
-msgstr ""
+msgstr "Sammenfold"
msgid "Boards|Edit board"
-msgstr ""
+msgstr "Rediger tavle"
msgid "Boards|Expand"
-msgstr ""
+msgstr "Udvid"
msgid "Boards|Failed to fetch blocking %{issuableType}s"
msgstr ""
msgid "Boards|New epic"
-msgstr ""
+msgstr "Ny epic"
msgid "Boards|Retrieving blocking %{issuableType}s"
msgstr ""
msgid "Boards|View all blocking %{issuableType}s"
-msgstr ""
+msgstr "Vis alle blokerende %{issuableType}s"
msgid "Boards|View scope"
-msgstr ""
+msgstr "Vis omfang"
msgid "Board|Are you sure you want to delete this board?"
-msgstr ""
+msgstr "Er du sikker på, at du vil slette tavlen?"
msgid "Board|Board scope"
-msgstr ""
+msgstr "Tavleomfang"
msgid "Board|Create board"
-msgstr ""
+msgstr "Opret tavle"
msgid "Board|Create new board"
-msgstr ""
+msgstr "Opret ny tavle"
msgid "Board|Delete board"
-msgstr ""
+msgstr "Slet tavle"
msgid "Board|Edit board"
-msgstr ""
+msgstr "Rediger tavle"
msgid "Board|Enter board name"
-msgstr ""
+msgstr "Indtast tavlenavn"
msgid "Board|Failed to delete board. Please try again."
-msgstr ""
+msgstr "Kunne ikke slette tavle. Prøv venligst igen."
msgid "Board|Load more epics"
-msgstr ""
+msgstr "Indlæs flere epics"
msgid "Board|Load more issues"
-msgstr ""
+msgstr "Indlæs flere problemstillinger"
msgid "Board|Loading epics"
-msgstr ""
+msgstr "Indlæser epics"
msgid "Bold text"
-msgstr ""
+msgstr "Fed tekst"
msgid "Both project and dashboard_path are required"
msgstr ""
msgid "Branch"
-msgstr ""
+msgstr "Gren"
msgid "Branch %{branchName} was not found in this project's repository."
-msgstr ""
+msgstr "Grenen %{branchName} blev ikke fundet i projektets depot."
msgid "Branch %{branch_name} was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}"
msgstr ""
msgid "Branch already exists"
-msgstr ""
+msgstr "Grenen findes allerede"
msgid "Branch changed"
-msgstr ""
+msgstr "Gren ændret"
msgid "Branch is already taken"
-msgstr ""
+msgstr "Grenen er allerede taget"
msgid "Branch name"
-msgstr ""
+msgstr "Grennavn"
msgid "Branch not loaded - %{branchId}"
msgstr ""
msgid "Branches"
-msgstr ""
+msgstr "Grene"
msgid "Branches|Active"
-msgstr ""
+msgstr "Aktiv"
msgid "Branches|Active branches"
-msgstr ""
+msgstr "Aktive grene"
msgid "Branches|All"
-msgstr ""
+msgstr "Alle"
msgid "Branches|Cancel, keep branch"
-msgstr ""
+msgstr "Annuller, behold gren"
msgid "Branches|Cant find HEAD commit for this branch"
-msgstr ""
+msgstr "Kan ikke finde HEAD-commit til grenen"
msgid "Branches|Compare"
-msgstr ""
+msgstr "Sammenlign"
msgid "Branches|Delete all branches that are merged into '%{default_branch}'"
-msgstr ""
+msgstr "Slet alle grene som er sammenlagt ind i '%{default_branch}'"
msgid "Branches|Delete branch"
-msgstr ""
+msgstr "Slet gren"
msgid "Branches|Delete branch. Are you ABSOLUTELY SURE?"
-msgstr ""
+msgstr "Slet gren. Er du HELT SIKKER?"
msgid "Branches|Delete merged branches"
-msgstr ""
+msgstr "Slet sammenlagte grene"
msgid "Branches|Delete protected branch"
-msgstr ""
+msgstr "Slet beskyttet gren"
msgid "Branches|Delete protected branch '%{branch_name}'?"
-msgstr ""
+msgstr "Slet beskyttet gren '%{branch_name}'?"
msgid "Branches|Delete protected branch. Are you ABSOLUTELY SURE?"
-msgstr ""
+msgstr "Slet beskyttet gren. Er du HELT SIKKER?"
msgid "Branches|Deleting the %{strongStart}%{branchName}%{strongEnd} branch cannot be undone. Are you sure?"
-msgstr ""
+msgstr "Sletning af grenen %{strongStart}%{branchName}%{strongEnd} kan ikke fortrydes. Er du sikker?"
msgid "Branches|Deleting the '%{branch_name}' branch cannot be undone. Are you sure?"
-msgstr ""
+msgstr "Sletning af grenen '%{branch_name}' kan ikke fortrydes. Er du sikker?"
msgid "Branches|Deleting the merged branches cannot be undone. Are you sure?"
-msgstr ""
+msgstr "Sletning af de sammenlagte grene kan ikke fortrydes. Er du sikker?"
msgid "Branches|Filter by branch name"
-msgstr ""
+msgstr "Filtrér efter grennavn"
msgid "Branches|Merged into %{default_branch}"
-msgstr ""
+msgstr "Sammenlagt ind i %{default_branch}"
msgid "Branches|New branch"
-msgstr ""
+msgstr "Ny gren"
msgid "Branches|No branches to show"
-msgstr ""
+msgstr "Ingen grene at vise"
msgid "Branches|Once you confirm and press %{delete_protected_branch}, it cannot be undone or recovered."
-msgstr ""
+msgstr "Når du bekræfter og trykker på %{delete_protected_branch}, så kan det ikke fortrydes eller gendannes."
msgid "Branches|Once you confirm and press %{strongStart}%{buttonText},%{strongEnd} it cannot be undone or recovered."
-msgstr ""
+msgstr "Når du bekræfter og trykker på %{strongStart}%{buttonText}%{strongEnd}, så kan det ikke fortrydes eller gendannes."
msgid "Branches|Only a project maintainer or owner can delete a protected branch"
-msgstr ""
+msgstr "Kun en projektvedligeholder eller -ejer kan slette en beskyttet gren"
msgid "Branches|Overview"
-msgstr ""
+msgstr "Oversigt"
msgid "Branches|Please type the following to confirm:"
-msgstr ""
+msgstr "Skriv venligst følgende for at bekræfte:"
msgid "Branches|Protected branches can be managed in %{project_settings_link}."
-msgstr ""
+msgstr "Beskyttede grene kan håndteres i %{project_settings_link}."
msgid "Branches|Show active branches"
-msgstr ""
+msgstr "Vis aktive grene"
msgid "Branches|Show all branches"
-msgstr ""
+msgstr "Vis alle grene"
msgid "Branches|Show more active branches"
-msgstr ""
+msgstr "Vis flere aktive grene"
msgid "Branches|Show more stale branches"
-msgstr ""
+msgstr "Vis flere uaktuelle grene"
msgid "Branches|Show overview of the branches"
-msgstr ""
+msgstr "Vis oversigt for grenene"
msgid "Branches|Show stale branches"
-msgstr ""
+msgstr "Vis uaktuelle grene"
msgid "Branches|Stale"
-msgstr ""
+msgstr "Uaktuel"
msgid "Branches|Stale branches"
-msgstr ""
+msgstr "Uaktuelle grene"
msgid "Branches|The branch could not be updated automatically because it has diverged from its upstream counterpart."
msgstr ""
msgid "Branches|The default branch cannot be deleted"
-msgstr ""
+msgstr "Standardgrenen kan ikke slettes"
msgid "Branches|This branch hasn’t been merged into %{defaultBranchName}. To avoid data loss, consider merging this branch before deleting it."
msgstr ""
msgid "Branches|This branch hasn’t been merged into %{default_branch}."
-msgstr ""
+msgstr "Grenen er ikke blevet sammenlagt ind i %{default_branch}."
msgid "Branches|To avoid data loss, consider merging this branch before deleting it."
msgstr ""
msgid "Branches|To confirm, type %{branch_name_confirmation}:"
-msgstr ""
+msgstr "Skriv %{branch_name_confirmation} for at bekræfte:"
msgid "Branches|To discard the local changes and overwrite the branch with the upstream version, delete it here and choose 'Update Now' above."
msgstr ""
@@ -5704,19 +5742,19 @@ msgid "Branches|You're about to permanently delete the protected branch %{strong
msgstr ""
msgid "Branches|You’re about to permanently delete the protected branch %{branch_name}."
-msgstr ""
+msgstr "Du er ved at slette den beskyttede gren %{branch_name} permanent."
msgid "Branches|diverged from upstream"
msgstr ""
msgid "Branches|merged"
-msgstr ""
+msgstr "sammenlagt"
msgid "Branches|project settings"
-msgstr ""
+msgstr "projektindstillinger"
msgid "Branches|protected"
-msgstr ""
+msgstr "beskyttet"
msgid "Breadcrumbs"
msgstr ""
@@ -5737,71 +5775,65 @@ msgid "Broadcast messages are displayed for every user and can be used to notify
msgstr ""
msgid "Browse Directory"
-msgstr ""
+msgstr "Gennemse mappe"
msgid "Browse File"
-msgstr ""
+msgstr "Gennemse fil"
msgid "Browse Files"
-msgstr ""
+msgstr "Gennemse filer"
msgid "Browse artifacts"
-msgstr ""
+msgstr "Gennemse artefakter"
msgid "Browse files"
-msgstr ""
+msgstr "Gennemse filer"
msgid "Browse templates"
-msgstr ""
+msgstr "Gennemse skabeloner"
msgid "BuildArtifacts|An error occurred while fetching the artifacts"
-msgstr ""
+msgstr "Der opstod en fejl under hentning af artefakterne"
msgid "BuildArtifacts|Loading artifacts"
-msgstr ""
+msgstr "Indlæser artefakter"
msgid "Built-in"
-msgstr ""
+msgstr "Indbygget"
msgid "Bulk request concurrency"
msgstr ""
msgid "Bulk update"
-msgstr ""
+msgstr "Masseopdatering"
msgid "BulkImport|Existing groups"
-msgstr ""
+msgstr "Eksisterende grupper"
msgid "BulkImport|Filter by source group"
-msgstr ""
+msgstr "Filtrér efter kildegruppe"
msgid "BulkImport|From source group"
-msgstr ""
-
-msgid "BulkImport|Import %{groups}"
-msgstr ""
+msgstr "Fra kildegruppe"
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
+msgstr "Importér grupper fra GitLab"
+
+msgid "BulkImport|Import selected"
msgstr ""
msgid "BulkImport|Importing the group failed"
msgstr ""
msgid "BulkImport|Name already exists."
-msgstr ""
-
-msgid "BulkImport|No groups on this page are available for import"
-msgstr ""
+msgstr "Navnet findes allerede."
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5812,7 +5844,7 @@ msgid "BulkImport|Showing %{start}-%{end} of %{total} matching filter \"%{filter
msgstr ""
msgid "BulkImport|To new group"
-msgstr ""
+msgstr "Til ny gruppe"
msgid "BulkImport|Update of import statuses with realtime changes failed"
msgstr ""
@@ -5827,7 +5859,7 @@ msgid "BulkImport|expected an associated Project but has an associated Group"
msgstr ""
msgid "BulkImport|must be a group"
-msgstr ""
+msgstr "skal være en gruppe"
msgid "Burndown chart"
msgstr ""
@@ -5845,22 +5877,25 @@ msgid "Burnup chart could not be generated due to too many events"
msgstr ""
msgid "Business"
-msgstr ""
+msgstr "Virksomhed"
msgid "Business metrics (Custom)"
-msgstr ""
+msgstr "Virksomhedsmålinger (tilpasset)"
msgid "Busy"
-msgstr ""
+msgstr "Optaget"
msgid "Buy CI Minutes"
+msgstr "Køb CI-minutter"
+
+msgid "Buy Storage"
msgstr ""
msgid "Buy more Pipeline minutes"
msgstr ""
msgid "By %{user_name}"
-msgstr ""
+msgstr "Af %{user_name}"
msgid "By authenticating with an account tied to an Enterprise e-mail address, it is understood that this account is an Enterprise User. "
msgstr ""
@@ -5869,31 +5904,31 @@ msgid "By default, all projects and groups will use the global notifications set
msgstr ""
msgid "ByAuthor|by"
-msgstr ""
+msgstr "af"
msgid "CHANGELOG"
-msgstr ""
+msgstr "CHANGELOG"
msgid "CI Lint"
-msgstr ""
+msgstr "CI Lint"
msgid "CI configuration validated, including all configuration added with the %{codeStart}includes%{codeEnd} keyword. %{link}"
msgstr ""
msgid "CI minutes"
-msgstr ""
+msgstr "CI-minutter"
msgid "CI settings"
-msgstr ""
+msgstr "CI-indstillinger"
msgid "CI variables"
-msgstr ""
+msgstr "CI-variabler"
msgid "CI will run using the credentials assigned above."
-msgstr ""
+msgstr "CI vil køre med de legitimationsoplysninger som er tildelt ovenover."
msgid "CI/CD"
-msgstr ""
+msgstr "CI/CD"
msgid "CI/CD Analytics"
msgstr ""
@@ -5902,16 +5937,16 @@ msgid "CI/CD Settings"
msgstr ""
msgid "CI/CD configuration"
-msgstr ""
+msgstr "Konfiguration af CI/CD"
msgid "CI/CD configuration file"
msgstr ""
msgid "CI/CD|No projects have been added to the scope"
-msgstr ""
+msgstr "Ingen projekter er blevet tilføjet til omfanget"
msgid "CICDAnalytics|%{percent}%{percentSymbol}"
-msgstr ""
+msgstr "%{percent} %{percentSymbol}"
msgid "CICDAnalytics|All time"
msgstr ""
@@ -5946,16 +5981,16 @@ msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration
msgstr ""
msgid "CICD|Add an existing project to the scope"
-msgstr ""
+msgstr "Tilføj et eksisterende projekt til omfanget"
msgid "CICD|Auto DevOps"
-msgstr ""
+msgstr "Auto DevOps"
msgid "CICD|Automatic deployment to staging, manual deployment to production"
msgstr ""
msgid "CICD|Continuous deployment to production"
-msgstr ""
+msgstr "Kontinuerlig udsendelse til produktion"
msgid "CICD|Continuous deployment to production using timed incremental rollout"
msgstr ""
@@ -5967,10 +6002,10 @@ msgid "CICD|Default to Auto DevOps pipeline for all projects"
msgstr ""
msgid "CICD|Deployment strategy"
-msgstr ""
+msgstr "Udsendelsesstrategi"
msgid "CICD|Jobs"
-msgstr ""
+msgstr "Job"
msgid "CICD|Limit CI_JOB_TOKEN access"
msgstr ""
@@ -5985,24 +6020,27 @@ msgid "CICD|The Auto DevOps pipeline runs if no alternative CI configuration fil
msgstr ""
msgid "CICD|group enabled"
-msgstr ""
+msgstr "gruppe aktiveret"
msgid "CICD|instance enabled"
-msgstr ""
+msgstr "instans aktiveret"
msgid "CLOSED"
-msgstr ""
+msgstr "LUKKET"
msgid "CLOSED (MOVED)"
-msgstr ""
+msgstr "LUKKET (FLYTTET)"
msgid "CODEOWNERS rule violation"
msgstr ""
msgid "CONTRIBUTING"
-msgstr ""
+msgstr "CONTRIBUTING"
msgid "CPU"
+msgstr "CPU"
+
+msgid "CSV is being generated and will be emailed to you upon completion."
msgstr ""
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
@@ -6057,7 +6095,7 @@ msgid "Can be manually deployed to"
msgstr ""
msgid "Can create groups:"
-msgstr ""
+msgstr "Kan oprette grupper:"
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6072,10 +6110,10 @@ msgid "Can't apply this suggestion."
msgstr ""
msgid "Can't be empty"
-msgstr ""
+msgstr "Må ikke være tom"
msgid "Can't create snippet: %{err}"
-msgstr ""
+msgstr "Kan ikke oprette uddrag: %{err}"
msgid "Can't fetch content for the blob: %{err}"
msgstr ""
@@ -6090,10 +6128,10 @@ msgid "Can't load mermaid module: %{err}"
msgstr ""
msgid "Can't scan the code?"
-msgstr ""
+msgstr "Kan koden ikke skannes?"
msgid "Can't update snippet: %{err}"
-msgstr ""
+msgstr "Kan ikke opdatere uddrag: %{err}"
msgid "Canary"
msgstr ""
@@ -6123,46 +6161,46 @@ msgid "CanaryIngress|Doing so will set a deployment change in progress. This tem
msgstr ""
msgid "CanaryIngress|Stable"
-msgstr ""
+msgstr "Stabil"
msgid "CanaryIngress|You are changing the ratio of the canary rollout for %{environment} compared to the stable deployment to:"
msgstr ""
msgid "Cancel"
-msgstr ""
+msgstr "Annuller"
msgid "Cancel and close"
-msgstr ""
+msgstr "Annuller og luk"
msgid "Cancel index deletion"
-msgstr ""
+msgstr "Annuller sletning af indeks"
msgid "Cancel running"
-msgstr ""
+msgstr "Annuller kørsel"
msgid "Cancel this job"
-msgstr ""
+msgstr "Annuller jobbet"
msgid "Cancel your account"
msgstr ""
msgid "Cancel, keep project"
-msgstr ""
+msgstr "Annuller, behold projekt"
msgid "Canceled deployment to"
-msgstr ""
+msgstr "Annullerede udsendelse til"
msgid "Cancelled"
-msgstr ""
+msgstr "Annulleret"
msgid "Cancelling Preview"
-msgstr ""
+msgstr "Annullerer forhåndsvisning"
msgid "Cannot be assigned to other projects."
-msgstr ""
+msgstr "Kan ikke tildeles til andre projekter."
msgid "Cannot be merged automatically"
-msgstr ""
+msgstr "Kan ikke sammenlægges automatisk"
msgid "Cannot create the abuse report. The user has been deleted."
msgstr ""
@@ -6189,13 +6227,13 @@ msgid "Cannot make the epic confidential if it contains non-confidential issues"
msgstr ""
msgid "Cannot merge"
-msgstr ""
+msgstr "Kan ikke sammenlægge"
msgid "Cannot modify %{profile_name} referenced in security policy"
msgstr ""
msgid "Cannot modify managed Kubernetes cluster"
-msgstr ""
+msgstr "Kan ikke ændre håndteret Kubernetes-klynge"
msgid "Cannot modify provider during creation"
msgstr ""
@@ -6246,10 +6284,10 @@ msgid "Certain user content will be moved to a system-wide \"Ghost User\" in ord
msgstr ""
msgid "Certificate"
-msgstr ""
+msgstr "Certifikat"
msgid "Certificate (PEM)"
-msgstr ""
+msgstr "Certifikat (PEM)"
msgid "Certificate Issuer"
msgstr ""
@@ -6270,58 +6308,58 @@ msgid "Change branches"
msgstr ""
msgid "Change label"
-msgstr ""
+msgstr "Ændr etiket"
msgid "Change made by"
-msgstr ""
+msgstr "Ændring foretaget af"
msgid "Change milestone"
-msgstr ""
+msgstr "Ændr milepæl"
msgid "Change path"
-msgstr ""
+msgstr "Ændr sti"
msgid "Change reviewer(s)"
-msgstr ""
+msgstr "Ændr kontrollanter"
msgid "Change reviewer(s)."
-msgstr ""
+msgstr "Ændr kontrollanter."
msgid "Change role"
-msgstr ""
+msgstr "Ændr rolle"
msgid "Change status"
-msgstr ""
+msgstr "Ændr status"
msgid "Change subscription"
-msgstr ""
+msgstr "Ændr abonnement"
msgid "Change template"
msgstr ""
msgid "Change title"
-msgstr ""
+msgstr "Ændr titel"
msgid "Change your password"
-msgstr ""
+msgstr "Ændr din adgangskode"
msgid "Change your password or recover your current one"
msgstr ""
msgid "ChangeReviewer|Reviewer changed from %{old} to %{new}"
-msgstr ""
+msgstr "Kontrollant ændret fra %{old} til %{new}"
msgid "ChangeReviewer|Reviewer changed to %{new}"
-msgstr ""
+msgstr "Kontrollant ændret til %{new}"
msgid "ChangeReviewer|Unassigned"
-msgstr ""
+msgstr "Utildelt"
msgid "ChangeTypeAction|A new branch will be created in your fork and a new merge request will be started."
msgstr ""
msgid "ChangeTypeAction|Cherry-pick"
-msgstr ""
+msgstr "Cherry-pick"
msgid "ChangeTypeAction|Pick into branch"
msgstr ""
@@ -6330,7 +6368,7 @@ msgid "ChangeTypeAction|Pick into project"
msgstr ""
msgid "ChangeTypeAction|Revert"
-msgstr ""
+msgstr "Tilbagefør"
msgid "ChangeTypeAction|Revert in branch"
msgstr ""
@@ -6345,13 +6383,13 @@ msgid "ChangeTypeAction|Start a %{newMergeRequest} with these changes"
msgstr ""
msgid "ChangeTypeAction|Switch branch"
-msgstr ""
+msgstr "Skift gren"
msgid "ChangeTypeAction|Switch project"
-msgstr ""
+msgstr "Skift projekt"
msgid "ChangeTypeAction|This will create a new commit in order to revert the existing changes."
-msgstr ""
+msgstr "Det vil oprette en ny commit for at tilbageføre de eksisterende ændringer."
msgid "ChangeTypeAction|Your changes will be committed to %{branchName} because a merge request is open."
msgstr ""
@@ -6360,13 +6398,13 @@ msgid "Changed assignee(s)."
msgstr ""
msgid "Changed reviewer(s)."
-msgstr ""
+msgstr "Ændrede kontrollanter."
msgid "Changed the title to \"%{title_param}\"."
msgstr ""
msgid "Changes"
-msgstr ""
+msgstr "Ændringer"
msgid "Changes are shown as if the %{b_open}source%{b_close} revision was being merged into the %{b_open}target%{b_close} revision."
msgstr ""
@@ -6375,13 +6413,13 @@ msgid "Changes are still tracked. Useful for cluster/index migrations."
msgstr ""
msgid "Changes saved."
-msgstr ""
+msgstr "Ændringer gemt."
msgid "Changes suppressed. Click to show."
msgstr ""
msgid "Changes the title to \"%{title_param}\"."
-msgstr ""
+msgstr "Ændrer titlen til \"%{title_param}\"."
msgid "Changes to the title have not been saved"
msgstr ""
@@ -6393,16 +6431,16 @@ msgid "Charts can't be displayed as the request for data has timed out. %{docume
msgstr ""
msgid "Chat"
-msgstr ""
+msgstr "Chat"
msgid "ChatMessage|%{project_link}: Pipeline %{pipeline_link} of %{ref_type} %{ref_link} by %{user_combined_name} %{humanized_status} in %{duration}"
msgstr ""
msgid "ChatMessage|Branch"
-msgstr ""
+msgstr "Gren"
msgid "ChatMessage|Commit"
-msgstr ""
+msgstr "Commit"
msgid "ChatMessage|Failed job"
msgstr ""
@@ -6420,7 +6458,7 @@ msgid "ChatMessage|Pipeline %{pipeline_link} of %{ref_type} %{ref_link} by %{use
msgstr ""
msgid "ChatMessage|Tag"
-msgstr ""
+msgstr "Mærkat"
msgid "ChatMessage|and [%{count} more](%{pipeline_failed_jobs_url})"
msgstr ""
@@ -6435,13 +6473,13 @@ msgid "ChatMessage|has passed with warnings"
msgstr ""
msgid "ChatMessage|in %{duration}"
-msgstr ""
+msgstr "om %{duration}"
msgid "ChatMessage|in %{project_link}"
-msgstr ""
+msgstr "i %{project_link}"
msgid "Check again"
-msgstr ""
+msgstr "Tjek igen"
msgid "Check feature availability on namespace plan"
msgstr ""
@@ -6450,7 +6488,7 @@ msgid "Check out, review, and merge locally"
msgstr ""
msgid "Check the %{docs_link_start}documentation%{docs_link_end}."
-msgstr ""
+msgstr "Tjek %{docs_link_start}dokumentationen%{docs_link_end}."
msgid "Check the current instance configuration "
msgstr ""
@@ -6468,13 +6506,13 @@ msgid "Check your source instance permissions."
msgstr ""
msgid "Checking %{text} availability…"
-msgstr ""
+msgstr "Tjekker tilgængelighed af %{text} …"
msgid "Checking approval status"
-msgstr ""
+msgstr "Tjekker godkendelsesstatus"
msgid "Checking branch availability..."
-msgstr ""
+msgstr "Tjekker tilgængelighed af gren ..."
msgid "Checking group URL availability..."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,14 +6546,16 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
-msgstr ""
+msgstr "%{startDate} - %{endDate}"
+
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -6537,13 +6582,13 @@ msgid "Checkout|Checkout"
msgstr ""
msgid "Checkout|City"
-msgstr ""
+msgstr "By"
msgid "Checkout|Confirm purchase"
-msgstr ""
+msgstr "Bekræft køb"
msgid "Checkout|Confirming..."
-msgstr ""
+msgstr "Bekræfter ..."
msgid "Checkout|Continue to billing"
msgstr ""
@@ -6552,10 +6597,10 @@ msgid "Checkout|Continue to payment"
msgstr ""
msgid "Checkout|Country"
-msgstr ""
+msgstr "Land"
msgid "Checkout|Create a new group"
-msgstr ""
+msgstr "Opret en ny gruppe"
msgid "Checkout|Credit card form failed to load. Please try again."
msgstr ""
@@ -6564,7 +6609,7 @@ msgid "Checkout|Credit card form failed to load: %{message}"
msgstr ""
msgid "Checkout|Edit"
-msgstr ""
+msgstr "Rediger"
msgid "Checkout|Exp %{expirationMonth}/%{expirationYear}"
msgstr ""
@@ -6576,7 +6621,7 @@ msgid "Checkout|Failed to confirm your order: %{message}. Please try again."
msgstr ""
msgid "Checkout|Failed to load countries. Please try again."
-msgstr ""
+msgstr "Kunne ikke indlæse lande. Prøv venligst igen."
msgid "Checkout|Failed to load states. Please try again."
msgstr ""
@@ -6588,40 +6633,40 @@ msgid "Checkout|Failed to register credit card. Please try again."
msgstr ""
msgid "Checkout|GitLab group"
-msgstr ""
+msgstr "GitLab-gruppe"
msgid "Checkout|GitLab plan"
-msgstr ""
+msgstr "GitLab-plan"
msgid "Checkout|Group"
-msgstr ""
+msgstr "Gruppe"
msgid "Checkout|Name of company or organization using GitLab"
-msgstr ""
+msgstr "Navn på virksomhed eller organisation som bruger GitLab"
msgid "Checkout|Need more users? Purchase GitLab for your %{company}."
-msgstr ""
+msgstr "Brug for flere brugere? Køb GitLab til din %{company}."
msgid "Checkout|Number of users"
-msgstr ""
+msgstr "Antal brugere"
msgid "Checkout|Payment method"
-msgstr ""
+msgstr "Betalingsmetode"
msgid "Checkout|Please select a country"
-msgstr ""
+msgstr "Vælg venligst et land"
msgid "Checkout|Please select a state"
-msgstr ""
+msgstr "Vælg venligst en stat"
msgid "Checkout|Purchase details"
msgstr ""
msgid "Checkout|Select"
-msgstr ""
+msgstr "Vælg"
msgid "Checkout|State"
-msgstr ""
+msgstr "Stat"
msgid "Checkout|Street address"
msgstr ""
@@ -6639,13 +6684,13 @@ msgid "Checkout|Tax"
msgstr ""
msgid "Checkout|Total"
-msgstr ""
+msgstr "I alt"
msgid "Checkout|Total minutes: %{quantity}"
msgstr ""
msgid "Checkout|Users"
-msgstr ""
+msgstr "Brugere"
msgid "Checkout|You'll create your new group after checkout"
msgstr ""
@@ -6657,16 +6702,16 @@ msgid "Checkout|Your subscription will be applied to this group"
msgstr ""
msgid "Checkout|Zip code"
-msgstr ""
+msgstr "Postnummer"
msgid "Checkout|company or team"
-msgstr ""
+msgstr "virksomhed eller team"
msgid "Checkout|x 1,000 minutes per pack = %{strong}"
msgstr ""
msgid "Cherry-pick this commit"
-msgstr ""
+msgstr "Cherry-pick committen"
msgid "Cherry-pick this merge request"
msgstr ""
@@ -6675,49 +6720,49 @@ msgid "Child"
msgstr ""
msgid "Child epic does not exist."
-msgstr ""
+msgstr "Underepicen findes ikke."
msgid "Child epic doesn't exist."
-msgstr ""
+msgstr "Underepicen findes ikke."
msgid "Chinese language support using"
-msgstr ""
+msgstr "Understøttelse af kinesisk sprog med"
msgid "Choose File..."
-msgstr ""
+msgstr "Vælg fil ..."
msgid "Choose a branch/tag (e.g. %{branch}) or enter a commit (e.g. %{sha}) to see what's changed or to create a merge request."
msgstr ""
msgid "Choose a file"
-msgstr ""
+msgstr "Vælg en fil"
msgid "Choose a group"
-msgstr ""
+msgstr "Vælg en gruppe"
msgid "Choose a template"
-msgstr ""
+msgstr "Vælg en skabelon"
msgid "Choose a template..."
-msgstr ""
+msgstr "Vælg en skabelon ..."
msgid "Choose a type..."
-msgstr ""
+msgstr "Vælg en type ..."
msgid "Choose any color"
-msgstr ""
+msgstr "Vælg en farve"
msgid "Choose any color."
-msgstr ""
+msgstr "Vælg en farve."
msgid "Choose any color. Or you can choose one of the suggested colors below"
-msgstr ""
+msgstr "Vælg en farve. Eller du kan vælge en de forslåede farver nedenunder"
msgid "Choose file…"
-msgstr ""
+msgstr "Vælg fil …"
msgid "Choose labels"
-msgstr ""
+msgstr "Vælg etiketter"
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -6732,7 +6777,7 @@ msgid "Choose visibility level, enable/disable project features and their permis
msgstr ""
msgid "Choose what content you want to see on a group’s overview page."
-msgstr ""
+msgstr "Vælg hvilket indhold du vil se på en gruppes oversigtsside."
msgid "Choose which Git strategy to use when fetching the project."
msgstr ""
@@ -6747,109 +6792,109 @@ msgid "CiCdAnalytics|Date range: %{range}"
msgstr ""
msgid "CiStatusLabel|canceled"
-msgstr ""
+msgstr "annulleret"
msgid "CiStatusLabel|created"
-msgstr ""
+msgstr "oprettet"
msgid "CiStatusLabel|delayed"
-msgstr ""
+msgstr "forsinket"
msgid "CiStatusLabel|failed"
-msgstr ""
+msgstr "mislykkedes"
msgid "CiStatusLabel|manual action"
-msgstr ""
+msgstr "manuel handling"
msgid "CiStatusLabel|passed"
-msgstr ""
+msgstr "bestået"
msgid "CiStatusLabel|passed with warnings"
-msgstr ""
+msgstr "bestået med advarsler"
msgid "CiStatusLabel|pending"
-msgstr ""
+msgstr "afventer"
msgid "CiStatusLabel|preparing"
-msgstr ""
+msgstr "forbereder"
msgid "CiStatusLabel|skipped"
-msgstr ""
+msgstr "sprunget over"
msgid "CiStatusLabel|waiting for delayed job"
-msgstr ""
+msgstr "venter på forsinket job"
msgid "CiStatusLabel|waiting for manual action"
-msgstr ""
+msgstr "venter på manuel handling"
msgid "CiStatusLabel|waiting for resource"
-msgstr ""
+msgstr "venter på ressource"
msgid "CiStatusText|blocked"
-msgstr ""
+msgstr "blokeret"
msgid "CiStatusText|canceled"
-msgstr ""
+msgstr "annulleret"
msgid "CiStatusText|created"
-msgstr ""
+msgstr "oprettet"
msgid "CiStatusText|delayed"
-msgstr ""
+msgstr "forsinket"
msgid "CiStatusText|failed"
-msgstr ""
+msgstr "mislykkedes"
msgid "CiStatusText|manual"
-msgstr ""
+msgstr "manuelt"
msgid "CiStatusText|passed"
-msgstr ""
+msgstr "bestået"
msgid "CiStatusText|pending"
-msgstr ""
+msgstr "afventer"
msgid "CiStatusText|preparing"
-msgstr ""
+msgstr "forbereder"
msgid "CiStatusText|skipped"
-msgstr ""
+msgstr "sprunget over"
msgid "CiStatusText|waiting"
-msgstr ""
+msgstr "venter"
msgid "CiStatus|running"
-msgstr ""
+msgstr "kører"
msgid "CiVariables|Cannot use Masked Variable with current value"
msgstr ""
msgid "CiVariables|Environments"
-msgstr ""
+msgstr "Miljøer"
msgid "CiVariables|Input variable key"
msgstr ""
msgid "CiVariables|Input variable value"
-msgstr ""
+msgstr "Indtast værdi for variabel"
msgid "CiVariables|Key"
-msgstr ""
+msgstr "Nøgle"
msgid "CiVariables|Masked"
-msgstr ""
+msgstr "Maskeret"
msgid "CiVariables|Protected"
msgstr ""
msgid "CiVariables|Remove variable"
-msgstr ""
+msgstr "Fjern variabel"
msgid "CiVariables|Remove variable row"
-msgstr ""
+msgstr "Fjern variabelrække"
msgid "CiVariables|Scope"
-msgstr ""
+msgstr "Omfang"
msgid "CiVariables|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used as default"
msgstr ""
@@ -6858,34 +6903,34 @@ msgid "CiVariables|State"
msgstr ""
msgid "CiVariables|Type"
-msgstr ""
+msgstr "Type"
msgid "CiVariables|Value"
-msgstr ""
+msgstr "Værdi"
msgid "CiVariables|Variables"
-msgstr ""
+msgstr "Variabler"
msgid "CiVariable|* (All environments)"
-msgstr ""
+msgstr "* (alle miljøer)"
msgid "CiVariable|All environments"
-msgstr ""
+msgstr "Alle miljøer"
msgid "CiVariable|Create wildcard"
-msgstr ""
+msgstr "Opret jokertegn"
msgid "CiVariable|Masked"
-msgstr ""
+msgstr "Maskeret"
msgid "CiVariable|New environment"
-msgstr ""
+msgstr "Nyt miljø"
msgid "CiVariable|Protected"
-msgstr ""
+msgstr "Beskyttet"
msgid "CiVariable|Search environments"
-msgstr ""
+msgstr "Søg i miljøer"
msgid "CiVariable|Toggle masked"
msgstr ""
@@ -6897,7 +6942,7 @@ msgid "Classification Label (optional)"
msgstr ""
msgid "ClassificationLabelUnavailable|is unavailable: %{reason}"
-msgstr ""
+msgstr "er utilgængelig: %{reason}"
msgid "Clean up after running %{link_start}git filter-repo%{link_end} on the repository."
msgstr ""
@@ -6918,7 +6963,7 @@ msgid "Cleanup policy maximum workers running concurrently"
msgstr ""
msgid "Clear"
-msgstr ""
+msgstr "Ryd"
msgid "Clear all repository checks"
msgstr ""
@@ -6927,31 +6972,31 @@ msgid "Clear chart filters"
msgstr ""
msgid "Clear due date"
-msgstr ""
+msgstr "Ryd forfaldsdato"
msgid "Clear recent searches"
-msgstr ""
+msgstr "Ryd seneste søgninger"
msgid "Clear search"
-msgstr ""
+msgstr "Ryd søgning"
msgid "Clear search input"
-msgstr ""
+msgstr "Ryd søgeindtastning"
msgid "Clear start date"
-msgstr ""
+msgstr "Ryd startdato"
msgid "Clear templates search input"
msgstr ""
msgid "Clear weight"
-msgstr ""
+msgstr "Ryd vægt"
msgid "Cleared weight."
msgstr ""
msgid "Clears weight."
-msgstr ""
+msgstr "Rydder vægt."
msgid "Click %{link_start}here%{link_end} to view the request."
msgstr ""
@@ -6972,25 +7017,25 @@ msgid "Click to expand text"
msgstr ""
msgid "Click to hide"
-msgstr ""
+msgstr "Klik for at skjule"
msgid "Click to reveal"
-msgstr ""
+msgstr "Klik for at vise"
msgid "Client authentication certificate"
msgstr ""
msgid "Client authentication key"
-msgstr ""
+msgstr "Klientgodkendelsesnøgle"
msgid "Client authentication key password"
-msgstr ""
+msgstr "Adgangskode til klientgodkendelsesnøgle"
msgid "Client request timeout"
msgstr ""
msgid "Clients"
-msgstr ""
+msgstr "Klienter"
msgid "Clone"
msgstr ""
@@ -6999,19 +7044,19 @@ msgid "Clone repository"
msgstr ""
msgid "Clone this issue"
-msgstr ""
+msgstr "Klon problemstillingen"
msgid "Clone with %{http_label}"
-msgstr ""
+msgstr "Klon med %{http_label}"
msgid "Clone with %{protocol}"
-msgstr ""
+msgstr "Klon med %{protocol}"
msgid "Clone with KRB5"
-msgstr ""
+msgstr "Klon med KRB5"
msgid "Clone with SSH"
-msgstr ""
+msgstr "Klon med SSH"
msgid "CloneIssue|Cannot clone issue due to insufficient permissions!"
msgstr ""
@@ -7026,31 +7071,31 @@ msgid "Clones this issue, without comments, to %{project}."
msgstr ""
msgid "Close"
-msgstr ""
+msgstr "Luk"
msgid "Close %{issueType}"
-msgstr ""
+msgstr "Luk %{issueType}"
msgid "Close %{tabname}"
-msgstr ""
+msgstr "Luk %{tabname}"
msgid "Close design"
-msgstr ""
+msgstr "Luk design"
msgid "Close epic"
-msgstr ""
+msgstr "Luk epic"
msgid "Close milestone"
-msgstr ""
+msgstr "Luk milepæle"
msgid "Close sidebar"
-msgstr ""
+msgstr "Luk sidebjælke"
msgid "Close this %{quick_action_target}"
msgstr ""
msgid "Closed"
-msgstr ""
+msgstr "Lukket"
msgid "Closed %{epicTimeagoDate}"
msgstr ""
@@ -7059,10 +7104,10 @@ msgid "Closed MRs"
msgstr ""
msgid "Closed epics"
-msgstr ""
+msgstr "Lukkede epics"
msgid "Closed issues"
-msgstr ""
+msgstr "Lukkede problemstillinger"
msgid "Closed this %{quick_action_target}."
msgstr ""
@@ -7077,7 +7122,7 @@ msgid "Cloud licenses can not be removed."
msgstr ""
msgid "Cluster"
-msgstr ""
+msgstr "Klynge"
msgid "Cluster Health"
msgstr ""
@@ -7092,7 +7137,7 @@ msgid "Cluster is required for Stages::ClusterEndpointInserter"
msgstr ""
msgid "Cluster level"
-msgstr ""
+msgstr "Klyngeniveau"
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
@@ -7113,22 +7158,22 @@ msgid "ClusterAgents|An unknown error occurred. Please try again."
msgstr ""
msgid "ClusterAgents|Configuration"
-msgstr ""
+msgstr "Konfiguration"
msgid "ClusterAgents|Copy token"
msgstr ""
msgid "ClusterAgents|Created by"
-msgstr ""
+msgstr "Oprettet af"
msgid "ClusterAgents|Created by %{name} %{time}"
-msgstr ""
+msgstr "Oprettet af %{name} %{time}"
msgid "ClusterAgents|Date created"
-msgstr ""
+msgstr "Dato oprettet"
msgid "ClusterAgents|Description"
-msgstr ""
+msgstr "Beskrivelse"
msgid "ClusterAgents|For alternative installation methods %{linkStart}go to the documentation%{linkEnd}."
msgstr ""
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7146,19 +7194,16 @@ msgid "ClusterAgents|Integrate with the GitLab Agent"
msgstr ""
msgid "ClusterAgents|Last used"
-msgstr ""
+msgstr "Sidst brugt"
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
-msgstr ""
+msgstr "Navn"
msgid "ClusterAgents|Never"
-msgstr ""
+msgstr "Aldrig"
msgid "ClusterAgents|Read more about getting started"
msgstr ""
@@ -7197,13 +7242,13 @@ msgid "ClusterAgents|The token value will not be shown again after you close thi
msgstr ""
msgid "ClusterAgents|This agent has no tokens"
-msgstr ""
+msgstr "Agenten har ingen tokens"
msgid "ClusterAgents|To install an Agent you should create an agent directory in the Repository first. We recommend that you add the Agent configuration to the directory before you start the installation process."
msgstr ""
msgid "ClusterAgents|Unknown user"
-msgstr ""
+msgstr "Ukendt bruger"
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
@@ -7239,16 +7284,16 @@ msgid "ClusterIntegration|API URL should be a valid http/https url."
msgstr ""
msgid "ClusterIntegration|Add Kubernetes cluster"
-msgstr ""
+msgstr "Tilføj Kubernetes-klynge"
msgid "ClusterIntegration|Add a Kubernetes cluster integration"
-msgstr ""
+msgstr "Tilføj en integrering af Kubernetes-klynge"
msgid "ClusterIntegration|Adding a Kubernetes cluster to your group will automatically share the cluster across all your projects. Use review apps, deploy your applications, and easily run your pipelines for all projects using the same cluster."
-msgstr ""
+msgstr "Tilføjelse af en Kubernetes-klynge til din gruppe deler automatisk klyngen på tværs af alle dine projekter. Brug gennemgå programmer, udsend dine programmer og kør nemt dine pipelines til alle projekter med den samme klynge."
msgid "ClusterIntegration|Adding a Kubernetes cluster will automatically share the cluster across all projects. Use review apps, deploy your applications, and easily run your pipelines for all projects using the same cluster."
-msgstr ""
+msgstr "Tilføjelse af en Kubernetes-klynge deler automatisk klyngen på tværs af alle projekter. Brug gennemgå programmer, udsend dine programmer og kør nemt dine pipelines til alle projekter med den samme klynge."
msgid "ClusterIntegration|Adding an integration to your group will share the cluster across all your projects."
msgstr ""
@@ -7272,16 +7317,16 @@ msgid "ClusterIntegration|Allows GitLab to query a specifically configured in-cl
msgstr ""
msgid "ClusterIntegration|Amazon EKS"
-msgstr ""
+msgstr "Amazon EKS"
msgid "ClusterIntegration|An error occurred when trying to contact the Google Cloud API. Please try again later."
-msgstr ""
+msgstr "Der opstod en fejl ved forsøg på at kontakte Google Cloud-API'en. Prøv venligst igen senere."
msgid "ClusterIntegration|An error occurred while trying to fetch project zones: %{error}"
msgstr ""
msgid "ClusterIntegration|An error occurred while trying to fetch your projects: %{error}"
-msgstr ""
+msgstr "Der opstod en fejl under forsøg på at hente dine projekter: %{error}"
msgid "ClusterIntegration|An error occurred while trying to fetch zone machine types: %{error}"
msgstr ""
@@ -7293,22 +7338,22 @@ msgid "ClusterIntegration|Any project namespaces"
msgstr ""
msgid "ClusterIntegration|Apply for credit"
-msgstr ""
+msgstr "Ansøg om kredit"
msgid "ClusterIntegration|Authenticate with AWS"
-msgstr ""
+msgstr "Godkend med AWS"
msgid "ClusterIntegration|Authenticate with Amazon Web Services"
msgstr ""
msgid "ClusterIntegration|Authentication Error"
-msgstr ""
+msgstr "Fejl ved godkendelse"
msgid "ClusterIntegration|Base domain"
msgstr ""
msgid "ClusterIntegration|CA Certificate"
-msgstr ""
+msgstr "CA-certifikat"
msgid "ClusterIntegration|Certificate Authority bundle (PEM format)"
msgstr ""
@@ -7317,10 +7362,10 @@ msgid "ClusterIntegration|Check your CA certificate"
msgstr ""
msgid "ClusterIntegration|Check your cluster status"
-msgstr ""
+msgstr "Tjek din klyngestatus"
msgid "ClusterIntegration|Check your token"
-msgstr ""
+msgstr "Tjek din token"
msgid "ClusterIntegration|Choose the %{linkStart}security group %{linkEnd} to apply to the EKS-managed Elastic Network Interfaces that are created in your worker node subnets."
msgstr ""
@@ -7362,16 +7407,16 @@ msgid "ClusterIntegration|Connect existing cluster"
msgstr ""
msgid "ClusterIntegration|Connection Error"
-msgstr ""
+msgstr "Fejl ved forbindelse"
msgid "ClusterIntegration|Copy API URL"
-msgstr ""
+msgstr "Kopiér API-URL"
msgid "ClusterIntegration|Copy CA Certificate"
-msgstr ""
+msgstr "Kopiér CA-certifikat"
msgid "ClusterIntegration|Copy Kubernetes cluster name"
-msgstr ""
+msgstr "Kopiér Kubernetes-klyngenavn"
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -7398,7 +7443,7 @@ msgid "ClusterIntegration|Could not load subnetworks"
msgstr ""
msgid "ClusterIntegration|Create Kubernetes cluster"
-msgstr ""
+msgstr "Opret Kubernetes-klynge"
msgid "ClusterIntegration|Create a provision role on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the account and external ID above. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
@@ -7443,10 +7488,10 @@ msgid "ClusterIntegration|Enable Prometheus integration"
msgstr ""
msgid "ClusterIntegration|Enable or disable GitLab's connection to your Kubernetes cluster."
-msgstr ""
+msgstr "Aktivér eller deaktivér GitLabs forbindelse til din Kubernetes-klynge."
msgid "ClusterIntegration|Enable this setting if using role-based access control (RBAC)."
-msgstr ""
+msgstr "Aktivér indstillingen, hvis du bruger rollebaseret adgangsstyring (RBAC)."
msgid "ClusterIntegration|Enter new Service Token"
msgstr ""
@@ -7455,22 +7500,22 @@ msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes clust
msgstr ""
msgid "ClusterIntegration|Enter the details for your Kubernetes cluster"
-msgstr ""
+msgstr "Indtast detaljerne til din Kubernetes-klynge"
msgid "ClusterIntegration|Environment scope"
-msgstr ""
+msgstr "Miljøomfang"
msgid "ClusterIntegration|Environment scope is required."
-msgstr ""
+msgstr "Miljøomfang kræves."
msgid "ClusterIntegration|Every new Google Cloud Platform (GCP) account receives $300 in credit upon %{sign_up_link}. In partnership with Google, GitLab is able to offer an additional $200 for both new and existing GCP accounts to get started with GitLab's Google Kubernetes Engine Integration."
-msgstr ""
+msgstr "Hver nye Google Cloud Platform-konto (GCP) modtager $300 i kredit ved %{sign_up_link}. I samarbejde med Google kan GitLab tilbyde yderligere $200 til både nye og eksisterende GCP-kontoer for at komme godt i gang med GitLabs Google Kubernetes Engine-integrering."
msgid "ClusterIntegration|Failed to configure EKS provider: %{message}"
msgstr ""
msgid "ClusterIntegration|Failed to configure Google Kubernetes Engine Cluster: %{message}"
-msgstr ""
+msgstr "Kunne ikke konfigurere Google Kubernetes Engine-klynge: %{message}"
msgid "ClusterIntegration|Failed to fetch CloudFormation stack: %{message}"
msgstr ""
@@ -7482,19 +7527,19 @@ msgid "ClusterIntegration|Failed to run Kubeclient: %{message}"
msgstr ""
msgid "ClusterIntegration|Fetching machine types"
-msgstr ""
+msgstr "Henter maskintyper"
msgid "ClusterIntegration|Fetching projects"
-msgstr ""
+msgstr "Henter projekter"
msgid "ClusterIntegration|Fetching zones"
-msgstr ""
+msgstr "Henter zoner"
msgid "ClusterIntegration|GitLab Agent managed clusters"
msgstr ""
msgid "ClusterIntegration|GitLab Integration"
-msgstr ""
+msgstr "GitLab-integrering"
msgid "ClusterIntegration|GitLab failed to authenticate."
msgstr ""
@@ -7506,25 +7551,25 @@ msgid "ClusterIntegration|GitLab-managed cluster"
msgstr ""
msgid "ClusterIntegration|Google Cloud Platform project"
-msgstr ""
+msgstr "Google Cloud Platform-projekt"
msgid "ClusterIntegration|Google GKE"
-msgstr ""
+msgstr "Google GKE"
msgid "ClusterIntegration|Google Kubernetes Engine"
-msgstr ""
+msgstr "Google Kubernetes Engine"
msgid "ClusterIntegration|Google Kubernetes Engine project"
-msgstr ""
+msgstr "Google Kubernetes Engine-projekt"
msgid "ClusterIntegration|Group cluster"
-msgstr ""
+msgstr "Gruppeklynge"
msgid "ClusterIntegration|HTTP Error"
-msgstr ""
+msgstr "Fejl ved HTTP"
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
-msgstr ""
+msgstr "Hvis du opsætter flere klynger og bruger Auto DevOps, så %{help_link_start}læs først dette%{help_link_end}."
msgid "ClusterIntegration|If you do not wish to delete all associated GitLab resources, you can simply remove the integration."
msgstr ""
@@ -7536,7 +7581,7 @@ msgid "ClusterIntegration|Instance cluster"
msgstr ""
msgid "ClusterIntegration|Instance type"
-msgstr ""
+msgstr "Instanstype"
msgid "ClusterIntegration|Integrate Kubernetes with a cluster certificate"
msgstr ""
@@ -7560,13 +7605,13 @@ msgid "ClusterIntegration|Kubernetes cluster is being created..."
msgstr ""
msgid "ClusterIntegration|Kubernetes cluster name"
-msgstr ""
+msgstr "Kubernetes-klyngenavn"
msgid "ClusterIntegration|Kubernetes cluster was successfully created."
msgstr ""
msgid "ClusterIntegration|Kubernetes clusters allow you to use review apps, deploy your applications, run your pipelines, and much more in an easy way."
-msgstr ""
+msgstr "Kubernetes-klynger giver mulighed for at bruge gennemgå programmer, udsend dine programmer, kør dine pipelines og meget mere på en nem måde."
msgid "ClusterIntegration|Kubernetes version"
msgstr ""
@@ -7575,13 +7620,13 @@ msgid "ClusterIntegration|Kubernetes version not found"
msgstr ""
msgid "ClusterIntegration|Learn more about %{help_link_start_machine_type}machine types%{help_link_end} and %{help_link_start_pricing}pricing%{help_link_end}."
-msgstr ""
+msgstr "Lær mere om %{help_link_start_machine_type}maskintyper%{help_link_end} og %{help_link_start_pricing}prissætning%{help_link_end}."
msgid "ClusterIntegration|Learn more about %{help_link_start}zones%{help_link_end}."
-msgstr ""
+msgstr "Lær mere om %{help_link_start}zoner%{help_link_end}."
msgid "ClusterIntegration|Learn more about Kubernetes"
-msgstr ""
+msgstr "Lær mere om Kubernetes"
msgid "ClusterIntegration|Learn more about group Kubernetes clusters"
msgstr ""
@@ -7593,7 +7638,7 @@ msgid "ClusterIntegration|Loading IAM Roles"
msgstr ""
msgid "ClusterIntegration|Loading Key Pairs"
-msgstr ""
+msgstr "Indlæser nøglepar"
msgid "ClusterIntegration|Loading VPCs"
msgstr ""
@@ -7602,7 +7647,7 @@ msgid "ClusterIntegration|Loading instance types"
msgstr ""
msgid "ClusterIntegration|Loading networks"
-msgstr ""
+msgstr "Indlæser netværk"
msgid "ClusterIntegration|Loading security groups"
msgstr ""
@@ -7614,13 +7659,13 @@ msgid "ClusterIntegration|Loading subnetworks"
msgstr ""
msgid "ClusterIntegration|Machine type"
-msgstr ""
+msgstr "Maskintype"
msgid "ClusterIntegration|Make sure your API endpoint is correct"
msgstr ""
msgid "ClusterIntegration|Make sure your account %{link_to_requirements} to create Kubernetes clusters"
-msgstr ""
+msgstr "Sørg for, at din konto %{link_to_requirements} for at oprette Kubernetes-klynger"
msgid "ClusterIntegration|Manage your Kubernetes cluster by visiting %{provider_link}"
msgstr ""
@@ -7641,16 +7686,16 @@ msgid "ClusterIntegration|No instance type found"
msgstr ""
msgid "ClusterIntegration|No machine types matched your search"
-msgstr ""
+msgstr "Ingen maskintyper passede til din søgning"
msgid "ClusterIntegration|No networks found"
-msgstr ""
+msgstr "Ingen netværk fundet"
msgid "ClusterIntegration|No projects found"
-msgstr ""
+msgstr "Ingen projekter fundet"
msgid "ClusterIntegration|No projects matched your search"
-msgstr ""
+msgstr "Ingen projekter passede til din søgning"
msgid "ClusterIntegration|No security group found"
msgstr ""
@@ -7662,13 +7707,13 @@ msgid "ClusterIntegration|No subnetworks found"
msgstr ""
msgid "ClusterIntegration|No zones matched your search"
-msgstr ""
+msgstr "Ingen zoner passede til din søgning"
msgid "ClusterIntegration|Node calculations use the Kubernetes Metrics API. Make sure your cluster has metrics installed"
msgstr ""
msgid "ClusterIntegration|Number of nodes"
-msgstr ""
+msgstr "Antal knudepunkter"
msgid "ClusterIntegration|Number of nodes must be a numerical value."
msgstr ""
@@ -7677,13 +7722,13 @@ msgid "ClusterIntegration|Please enter access information for your Kubernetes cl
msgstr ""
msgid "ClusterIntegration|Please make sure that your Google account meets the following requirements:"
-msgstr ""
+msgstr "Sørg for, at din Google-konto opfylder følgende krav:"
msgid "ClusterIntegration|Project cluster"
-msgstr ""
+msgstr "Projektklynge"
msgid "ClusterIntegration|Project namespace (optional, unique)"
-msgstr ""
+msgstr "Projektnavneområde (valgfrit, unikt)"
msgid "ClusterIntegration|Project namespace prefix (optional, unique)"
msgstr ""
@@ -7695,7 +7740,7 @@ msgid "ClusterIntegration|Provision Role ARN"
msgstr ""
msgid "ClusterIntegration|RBAC-enabled cluster"
-msgstr ""
+msgstr "RBAC-aktiveret klynge"
msgid "ClusterIntegration|Read our %{linkStart}help page%{linkEnd} on Kubernetes cluster integration."
msgstr ""
@@ -7704,10 +7749,10 @@ msgid "ClusterIntegration|Read our %{link_start}help page%{link_end} on Kubernet
msgstr ""
msgid "ClusterIntegration|Remove Kubernetes cluster integration"
-msgstr ""
+msgstr "Fjern integrering af Kubernetes-klynge"
msgid "ClusterIntegration|Remove integration"
-msgstr ""
+msgstr "Fjern integration"
msgid "ClusterIntegration|Remove integration and resources"
msgstr ""
@@ -7719,13 +7764,13 @@ msgid "ClusterIntegration|Remove integration?"
msgstr ""
msgid "ClusterIntegration|Remove this Kubernetes cluster's configuration from this project. This will not delete your actual Kubernetes cluster."
-msgstr ""
+msgstr "Fjern Kubernetes-klyngens konfiguration fra projektet. Det sletter ikke selve Kubernetes-klyngen."
msgid "ClusterIntegration|Removes cluster from project but keeps associated resources"
msgstr ""
msgid "ClusterIntegration|Save changes"
-msgstr ""
+msgstr "Gem ændringer"
msgid "ClusterIntegration|Search IAM Roles"
msgstr ""
@@ -7740,13 +7785,13 @@ msgid "ClusterIntegration|Search instance types"
msgstr ""
msgid "ClusterIntegration|Search machine types"
-msgstr ""
+msgstr "Søg efter maskintyper"
msgid "ClusterIntegration|Search networks"
msgstr ""
msgid "ClusterIntegration|Search projects"
-msgstr ""
+msgstr "Søg efter projekter"
msgid "ClusterIntegration|Search security groups"
msgstr ""
@@ -7758,13 +7803,13 @@ msgid "ClusterIntegration|Search subnetworks"
msgstr ""
msgid "ClusterIntegration|Search zones"
-msgstr ""
+msgstr "Søg efter zoner"
msgid "ClusterIntegration|Security group"
-msgstr ""
+msgstr "Sikkerhedsgruppe"
msgid "ClusterIntegration|See and edit the details for your Kubernetes cluster"
-msgstr ""
+msgstr "Se og rediger detaljerne til din Kubernetes-klynge"
msgid "ClusterIntegration|Select a VPC to choose a security group"
msgstr ""
@@ -7788,16 +7833,16 @@ msgid "ClusterIntegration|Select a zone to choose a network"
msgstr ""
msgid "ClusterIntegration|Select machine type"
-msgstr ""
+msgstr "Vælg maskintype"
msgid "ClusterIntegration|Select project"
-msgstr ""
+msgstr "Vælg projekt"
msgid "ClusterIntegration|Select project and zone to choose machine type"
-msgstr ""
+msgstr "Vælg projekt og zone for at vælge maskintype"
msgid "ClusterIntegration|Select project to choose zone"
-msgstr ""
+msgstr "Vælg projekt for at vælge zone"
msgid "ClusterIntegration|Select the key pair name that will be used to create EC2 nodes. To use a new key pair name, first create one on %{linkStart}Amazon Web Services%{linkEnd}."
msgstr ""
@@ -7806,10 +7851,10 @@ msgid "ClusterIntegration|Select the region you want to create the new cluster i
msgstr ""
msgid "ClusterIntegration|Select zone"
-msgstr ""
+msgstr "Vælg zone"
msgid "ClusterIntegration|Select zone to choose machine type"
-msgstr ""
+msgstr "Vælg zone for at vælge maskintype"
msgid "ClusterIntegration|Service Token"
msgstr ""
@@ -7824,7 +7869,7 @@ msgid "ClusterIntegration|Set a prefix for your namespaces. If not set, defaults
msgstr ""
msgid "ClusterIntegration|Something went wrong on our end."
-msgstr ""
+msgstr "Noget gik galt i vores ende."
msgid "ClusterIntegration|Something went wrong while creating your Kubernetes cluster"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -7857,7 +7902,7 @@ msgid "ClusterIntegration|There was an HTTP error when connecting to your cluste
msgstr ""
msgid "ClusterIntegration|This account must have permissions to create a Kubernetes cluster in the %{link_to_container_project} specified below"
-msgstr ""
+msgstr "Kontoen skal have tilladelser til at oprette en Kubernetes-klynge i %{link_to_container_project} angivet nedenfor"
msgid "ClusterIntegration|This is necessary if your integration has become out of sync. The cache is repopulated during the next CI job that requires namespace and service accounts."
msgstr ""
@@ -7866,7 +7911,7 @@ msgid "ClusterIntegration|This is necessary to clear existing environment-namesp
msgstr ""
msgid "ClusterIntegration|This option will allow you to install applications on RBAC clusters."
-msgstr ""
+msgstr "Valgmuligheden giver dig mulighed for at installere programmer på RBAC-klynger."
msgid "ClusterIntegration|This project does not have billing enabled. To create a cluster, %{linkToBillingStart}enable billing%{linkToBillingEnd} and try again."
msgstr ""
@@ -7893,16 +7938,16 @@ msgid "ClusterIntegration|Unable to Authenticate"
msgstr ""
msgid "ClusterIntegration|Unable to Connect"
-msgstr ""
+msgstr "Kan ikke oprette forbindelse"
msgid "ClusterIntegration|Unknown Error"
-msgstr ""
+msgstr "Ukendt fejl"
msgid "ClusterIntegration|Uses the Cloud Run, Istio, and HTTP Load Balancing addons for this cluster."
msgstr ""
msgid "ClusterIntegration|VPC"
-msgstr ""
+msgstr "VPC"
msgid "ClusterIntegration|Validating project billing status"
msgstr ""
@@ -7914,7 +7959,7 @@ msgid "ClusterIntegration|We were unable to fetch any projects. Ensure that you
msgstr ""
msgid "ClusterIntegration|With a Kubernetes cluster associated to this project, you can use review apps, deploy your applications, run your pipelines, and much more in an easy way."
-msgstr ""
+msgstr "Med en Kubernetes-klynge tilknyttet til projektet, kan du bruge gennemgå programmer, udsend dine programmer, kør dine pipelines og meget mere på en nem måde."
msgid "ClusterIntegration|You are about to remove your cluster integration and all GitLab-created resources associated with this cluster."
msgstr ""
@@ -7929,7 +7974,7 @@ msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
-msgstr ""
+msgstr "Din konto skal have %{link_to_kubernetes_engine}"
msgid "ClusterIntegration|Your cluster API is unreachable. Please ensure your API URL is correct."
msgstr ""
@@ -7938,25 +7983,25 @@ msgid "ClusterIntegration|Your service role is distinct from the provision role
msgstr ""
msgid "ClusterIntegration|Zone"
-msgstr ""
+msgstr "Zone"
msgid "ClusterIntegration|access to Google Kubernetes Engine"
-msgstr ""
+msgstr "adgang til Google Kubernetes Engine"
msgid "ClusterIntegration|meets the requirements"
-msgstr ""
+msgstr "opfylder kravene"
msgid "ClusterIntegration|sign up"
-msgstr ""
+msgstr "tilmeld"
msgid "ClusterIntergation|Select a VPC"
msgstr ""
msgid "ClusterIntergation|Select a network"
-msgstr ""
+msgstr "Vælg et netværk"
msgid "ClusterIntergation|Select a security group"
-msgstr ""
+msgstr "Vælg en sikkerhedsgruppe"
msgid "ClusterIntergation|Select a subnet"
msgstr ""
@@ -7965,10 +8010,10 @@ msgid "ClusterIntergation|Select a subnetwork"
msgstr ""
msgid "ClusterIntergation|Select an instance type"
-msgstr ""
+msgstr "Vælg en instanstype"
msgid "ClusterIntergation|Select key pair"
-msgstr ""
+msgstr "Vælg et nøglepar"
msgid "ClusterIntergation|Select service role"
msgstr ""
@@ -7977,13 +8022,13 @@ msgid "Clusters|An error occurred while loading clusters"
msgstr ""
msgid "Code"
-msgstr ""
+msgstr "Kode"
msgid "Code Coverage: %{coveragePercentage}"
msgstr ""
msgid "Code Coverage: %{coveragePercentage}%{percentSymbol}"
-msgstr ""
+msgstr "Kodedækning: %{coveragePercentage} %{percentSymbol}"
msgid "Code Coverage| Empty code coverage data"
msgstr ""
@@ -7992,16 +8037,16 @@ msgid "Code Coverage|Couldn't fetch the code coverage data"
msgstr ""
msgid "Code Owner"
-msgstr ""
+msgstr "Kodeejer"
msgid "Code Owners"
-msgstr ""
+msgstr "Kodeejere"
msgid "Code Quality"
-msgstr ""
+msgstr "Kodekvalitet"
msgid "Code Review"
-msgstr ""
+msgstr "Kodekontrol"
msgid "Code Review Analytics displays a table of open merge requests considered to be in code review. There are currently no merge requests in review for this project and/or filters."
msgstr ""
@@ -8013,10 +8058,10 @@ msgid "Code owner approval is required"
msgstr ""
msgid "Code owners"
-msgstr ""
+msgstr "Kodeejere"
msgid "Code review"
-msgstr ""
+msgstr "Kodekontrol"
msgid "Code snippet copied. Insert it in the correct location in the YAML file."
msgstr ""
@@ -8028,49 +8073,49 @@ msgid "CodeNavigation|No references found"
msgstr ""
msgid "CodeOwner|Pattern"
-msgstr ""
+msgstr "Mønster"
msgid "CodeQuality|New code quality degradations on this line"
msgstr ""
msgid "Cohorts|Inactive users"
-msgstr ""
+msgstr "Inaktive brugere"
msgid "Cohorts|Month %{month_index}"
-msgstr ""
+msgstr "MÃ¥ned %{month_index}"
msgid "Cohorts|New users"
-msgstr ""
+msgstr "Nye brugere"
msgid "Cohorts|Registration month"
msgstr ""
msgid "Cohorts|Returning users"
-msgstr ""
+msgstr "Tilbagevendende brugere"
msgid "Cohorts|User cohorts are shown for the last %{months_included} months. Only users with activity are counted in the 'New users' column; inactive users are counted separately."
msgstr ""
msgid "Collapse"
-msgstr ""
+msgstr "Sammenfold"
msgid "Collapse all threads"
-msgstr ""
+msgstr "Sammenfold alle tråde"
msgid "Collapse approvers"
-msgstr ""
+msgstr "Sammenfold godkendere"
msgid "Collapse issues"
-msgstr ""
+msgstr "Sammenfold problemstillinger"
msgid "Collapse milestones"
-msgstr ""
+msgstr "Sammenfold milepæle"
msgid "Collapse replies"
-msgstr ""
+msgstr "Sammenfold svar"
msgid "Collapse sidebar"
-msgstr ""
+msgstr "Sammenfold sidebjælke"
msgid "Collapses this file (only for you) until it’s changed again."
msgstr ""
@@ -8079,7 +8124,7 @@ msgid "Collector hostname"
msgstr ""
msgid "Colorize messages"
-msgstr ""
+msgstr "Farvelæg meddelelser"
msgid "ComboSearch is not defined"
msgstr ""
@@ -8091,10 +8136,10 @@ msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
msgid "Command"
-msgstr ""
+msgstr "Kommando"
msgid "Command line instructions"
-msgstr ""
+msgstr "Instruktioner for kommandolinje"
msgid "Commands applied"
msgstr ""
@@ -8103,16 +8148,16 @@ msgid "Commands did not apply"
msgstr ""
msgid "Comment"
-msgstr ""
+msgstr "Kommentér"
msgid "Comment & close %{noteable_name}"
-msgstr ""
+msgstr "Kommentér og luk %{noteable_name}"
msgid "Comment & reopen %{noteable_name}"
-msgstr ""
+msgstr "Kommentér og genåbn %{noteable_name}"
msgid "Comment & resolve thread"
-msgstr ""
+msgstr "Kommentér og løs tråd"
msgid "Comment & unresolve thread"
msgstr ""
@@ -8121,10 +8166,10 @@ msgid "Comment '%{label}' position"
msgstr ""
msgid "Comment form position"
-msgstr ""
+msgstr "Placering af kommentarformular"
msgid "Comment is being updated"
-msgstr ""
+msgstr "Kommentaren er ved at blive opdateret"
msgid "Comment on lines %{startLine} to %{endLine}"
msgstr ""
@@ -8139,54 +8184,54 @@ msgid "Commenting on symbolic links that replace or are replaced by files is cur
msgstr ""
msgid "Comments"
-msgstr ""
+msgstr "Kommentarer"
msgid "Commit"
msgid_plural "Commits"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Commit"
+msgstr[1] "Commits"
msgid "Commit %{commit_id}"
-msgstr ""
+msgstr "Commit %{commit_id}"
msgid "Commit (when editing commit message)"
msgstr ""
msgid "Commit Message"
-msgstr ""
+msgstr "Commit-meddelelse"
msgid "Commit changes"
msgstr ""
msgid "Commit deleted"
-msgstr ""
+msgstr "Commit slettet"
msgid "Commit message"
-msgstr ""
+msgstr "Commit-meddelelse"
msgid "Commit message (optional)"
-msgstr ""
+msgstr "Commit-meddelelse (valgfrit)"
msgid "Commit statistics for %{ref} %{start_time} - %{end_time}"
-msgstr ""
+msgstr "Commit-statistik for %{ref} %{start_time} - %{end_time}"
msgid "Commit to %{branchName} branch"
-msgstr ""
+msgstr "Commit til grenen %{branchName}"
msgid "CommitBoxTitle|Commit"
-msgstr ""
+msgstr "Commit"
msgid "CommitMessage|Add %{file_name}"
-msgstr ""
+msgstr "Tilføj %{file_name}"
msgid "CommitMessage|Add %{file_name} and create a code quality job"
msgstr ""
msgid "CommitWidget|authored"
-msgstr ""
+msgstr "forfattede"
msgid "Commits"
-msgstr ""
+msgstr "Commits"
msgid "Commits feed"
msgstr ""
@@ -8195,10 +8240,10 @@ msgid "Commits per day hour (UTC)"
msgstr ""
msgid "Commits per day of month"
-msgstr ""
+msgstr "Commits pr. månedsdag"
msgid "Commits per weekday"
-msgstr ""
+msgstr "Commits pr. ugedag"
msgid "Commits to"
msgstr ""
@@ -8207,46 +8252,46 @@ msgid "Commits you select appear here. Go to the first tab and select commits to
msgstr ""
msgid "Commits|An error occurred while fetching merge requests data."
-msgstr ""
+msgstr "Der opstod en fejl under hentning af data for sammenlægningsanmodninger."
msgid "Commits|History"
-msgstr ""
+msgstr "Historik"
msgid "Commits|No related merge requests found"
-msgstr ""
+msgstr "Ingen relaterede sammenlægningsanmodninger fundet"
msgid "Committed by"
-msgstr ""
+msgstr "Committed af"
msgid "Commit…"
-msgstr ""
+msgstr "Commit …"
msgid "Community forum"
msgstr ""
msgid "Company"
-msgstr ""
+msgstr "Virksomhed"
msgid "Compare"
-msgstr ""
+msgstr "Sammenlign"
msgid "Compare %{oldCommitId}...%{newCommitId}"
msgstr ""
msgid "Compare Git revisions"
-msgstr ""
+msgstr "Sammenlign Git-revisioner"
msgid "Compare GitLab editions"
msgstr ""
msgid "Compare Revisions"
-msgstr ""
+msgstr "Sammenlign revisioner"
msgid "Compare changes"
-msgstr ""
+msgstr "Sammenlign ændringer"
msgid "Compare changes with the last commit"
-msgstr ""
+msgstr "Sammenlign ændringer med den sidste commit"
msgid "Compare changes with the merge request target branch"
msgstr ""
@@ -8255,71 +8300,68 @@ msgid "Compare submodule commit revisions"
msgstr ""
msgid "Compare with previous version"
-msgstr ""
+msgstr "Sammenlign med forrige version"
msgid "CompareBranches|%{source_branch} and %{target_branch} are the same."
msgstr ""
msgid "CompareBranches|There isn't anything to compare."
-msgstr ""
+msgstr "Der er intet at sammenligne."
msgid "CompareRevisions|Branches"
-msgstr ""
+msgstr "Grene"
msgid "CompareRevisions|Compare"
-msgstr ""
+msgstr "Sammenlign"
msgid "CompareRevisions|Create merge request"
-msgstr ""
+msgstr "Opret sammenlægningsanmodning"
msgid "CompareRevisions|Filter by Git revision"
-msgstr ""
+msgstr "Filtrér efter Git-revision"
msgid "CompareRevisions|Select Git revision"
-msgstr ""
+msgstr "Vælg Git-revision"
msgid "CompareRevisions|Select branch/tag"
-msgstr ""
+msgstr "Vælg gren/mærkat"
msgid "CompareRevisions|Select target project"
-msgstr ""
+msgstr "Vælg målprojekt"
msgid "CompareRevisions|Swap revisions"
msgstr ""
msgid "CompareRevisions|Tags"
-msgstr ""
+msgstr "Mærkater"
msgid "CompareRevisions|There was an error while loading the branch/tag list. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl under indlæsning af gren-/mærkatlisten. Prøv venligst igen."
msgid "CompareRevisions|There was an error while searching the branch/tag list. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl under søgning i gren-/mærkatlisten. Prøv venligst igen."
msgid "CompareRevisions|There was an error while updating the branch/tag list. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl under opdatering af gren-/mærkatlisten. Prøv venligst igen."
msgid "CompareRevisions|View open merge request"
msgstr ""
msgid "Complete"
-msgstr ""
+msgstr "Fuldført"
msgid "Completed"
-msgstr ""
+msgstr "Fuldført"
msgid "Compliance"
-msgstr ""
+msgstr "Overholdelse"
msgid "Compliance Dashboard"
-msgstr ""
+msgstr "Overholdelsesbetjeningspanel"
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8384,19 +8426,19 @@ msgid "ComplianceFramework|New Compliance Framework"
msgstr ""
msgid "Component"
-msgstr ""
+msgstr "Komponent"
msgid "Confidence"
msgstr ""
msgid "Confidential"
-msgstr ""
+msgstr "Fortroligt"
msgid "Confidentiality"
-msgstr ""
+msgstr "Fortrolighed"
msgid "Configuration"
-msgstr ""
+msgstr "Konfiguration"
msgid "Configuration help"
msgstr ""
@@ -8417,10 +8459,10 @@ msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if
msgstr ""
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
-msgstr ""
+msgstr "Konfigurer GitLab-runners for at komme i gang med at bruge Web Terminal. %{helpStart}Lær mere%{helpEnd}."
msgid "Configure Gitaly timeouts."
-msgstr ""
+msgstr "Konfigurer Gitaly-timeouts."
msgid "Configure Integrations"
msgstr ""
@@ -8456,10 +8498,7 @@ msgid "Configure limits for Project/Group Import/Export."
msgstr ""
msgid "Configure limits for web and API requests."
-msgstr ""
-
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
+msgstr "Konfigurer grænser for web- og API-anmodninger."
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,47 +8512,50 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
msgid "Configure the %{link} integration."
-msgstr ""
+msgstr "Konfigurer %{link}-integreringen."
msgid "Configure the default first day of the week and time tracking units."
msgstr ""
msgid "Configure the way a user creates a new account."
-msgstr ""
+msgstr "Konfigurer måden en bruger opretter en ny konto."
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
msgid "Confirm"
-msgstr ""
+msgstr "Bekræft"
msgid "Confirm new password"
-msgstr ""
+msgstr "Bekræft ny adgangskode"
msgid "Confirm user"
-msgstr ""
+msgstr "Bekræft bruger"
msgid "Confirm your account"
-msgstr ""
+msgstr "Bekræft din konto"
msgid "Confirm your email address"
-msgstr ""
+msgstr "Bekræft din e-mailadresse"
msgid "Confirmation email sent to %{email}"
-msgstr ""
+msgstr "Bekræftelses e-mail sendt til %{email}"
msgid "Confirmation required"
-msgstr ""
+msgstr "Bekræftelse kræves"
msgid "Confirmed at:"
msgstr ""
msgid "Confirmed:"
-msgstr ""
+msgstr "Bekræftet:"
msgid "Conflict: This file was added both in the source and target branches, but with different contents."
msgstr ""
@@ -8555,10 +8597,10 @@ msgid "ConfluenceService|Your GitLab wiki is still available at %{wiki_link}. To
msgstr ""
msgid "Congratulations, your free trial is activated."
-msgstr ""
+msgstr "Tillykke, din gratis prøveperiode er aktiveret."
msgid "Connect"
-msgstr ""
+msgstr "Opret forbindelse"
msgid "Connect all repositories"
msgstr ""
@@ -8570,22 +8612,22 @@ msgid "Connect your external repositories, and CI/CD pipelines will run for new
msgstr ""
msgid "Connected"
-msgstr ""
+msgstr "Forbundet"
msgid "Connecting"
-msgstr ""
+msgstr "Opretter forbindelse"
msgid "Connecting to terminal sync service"
msgstr ""
msgid "Connecting..."
-msgstr ""
+msgstr "Opretter forbindelse ..."
msgid "Connection failed"
msgstr ""
msgid "Connection failure"
-msgstr ""
+msgstr "Fejl ved forbindelse"
msgid "Connection timed out"
msgstr ""
@@ -8600,10 +8642,10 @@ msgid "Contact support"
msgstr ""
msgid "Container Registry"
-msgstr ""
+msgstr "Beholderregister"
msgid "Container Scanning"
-msgstr ""
+msgstr "Beholderskanning"
msgid "Container does not exist"
msgstr ""
@@ -8661,7 +8703,7 @@ msgid "ContainerRegistry|Cleanup disabled"
msgstr ""
msgid "ContainerRegistry|Cleanup in progress"
-msgstr ""
+msgstr "Igangværende oprydning"
msgid "ContainerRegistry|Cleanup incomplete"
msgstr ""
@@ -8769,7 +8811,7 @@ msgid "ContainerRegistry|Keep tags matching:"
msgstr ""
msgid "ContainerRegistry|Keep the most recent:"
-msgstr ""
+msgstr "Behold den seneste:"
msgid "ContainerRegistry|Keep these tags"
msgstr ""
@@ -8808,7 +8850,7 @@ msgid "ContainerRegistry|Remember to run %{docLinkStart}garbage collection%{docL
msgstr ""
msgid "ContainerRegistry|Remove repository"
-msgstr ""
+msgstr "Fjern depot"
msgid "ContainerRegistry|Remove tag"
msgid_plural "ContainerRegistry|Remove tags"
@@ -8939,7 +8981,7 @@ msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item}. Are you sure?"
-msgstr ""
+msgstr "Du er ved at fjerne %{item}. Er du sikker?"
msgid "ContainerRegistry|You are about to remove repository %{title}. Once you confirm, this repository will be permanently deleted."
msgstr ""
@@ -8957,7 +8999,7 @@ msgid "ContentEditor|You have to provide a renderMarkdown function or a custom s
msgstr ""
msgid "Contents of .gitlab-ci.yml"
-msgstr ""
+msgstr "Indholdet i .gitlab-ci.yml"
msgid "ContextCommits|Failed to create context commits. Please try again."
msgstr ""
@@ -8969,19 +9011,19 @@ msgid "ContextCommits|Failed to delete context commits. Please try again."
msgstr ""
msgid "Continue"
-msgstr ""
+msgstr "Fortsæt"
msgid "Continue to the next step"
-msgstr ""
+msgstr "Fortsæt til det næste trin"
msgid "Continuous Integration and Deployment"
-msgstr ""
+msgstr "Kontinuerlig integrering og udsendelse"
msgid "Contribute to GitLab"
-msgstr ""
+msgstr "Bidrag til GitLab"
msgid "Contribution"
-msgstr ""
+msgstr "Bidrag"
msgid "Contribution Analytics"
msgstr ""
@@ -8999,16 +9041,16 @@ msgid "ContributionAnalytics|Contribution analytics for issues, merge requests a
msgstr ""
msgid "ContributionAnalytics|Issues"
-msgstr ""
+msgstr "Problemstillinger"
msgid "ContributionAnalytics|Last 3 months"
-msgstr ""
+msgstr "Sidste 3 måneder"
msgid "ContributionAnalytics|Last month"
-msgstr ""
+msgstr "Sidste måned"
msgid "ContributionAnalytics|Last week"
-msgstr ""
+msgstr "Sidste uge"
msgid "ContributionAnalytics|Merge requests"
msgstr ""
@@ -9026,13 +9068,13 @@ msgid "Contributions for %{calendar_date}"
msgstr ""
msgid "Contributions per group member"
-msgstr ""
+msgstr "Bidrag pr. gruppemedlem"
msgid "Contributor"
-msgstr ""
+msgstr "Bidragsyder"
msgid "Contributors"
-msgstr ""
+msgstr "Bidragsydere"
msgid "Control emails linked to your account"
msgstr ""
@@ -9041,112 +9083,112 @@ msgid "Control how the GitLab Package Registry functions."
msgstr ""
msgid "Control whether to display third-party offers in GitLab."
-msgstr ""
+msgstr "Styr om der vises tilbud fra tredjepart i GitLab."
msgid "Control which projects can be accessed by API requests authenticated with this project's CI_JOB_TOKEN CI/CD variable. It is a security risk to disable this feature, because unauthorized projects might attempt to retrieve an active token and access the API."
msgstr ""
msgid "Cookie domain"
-msgstr ""
+msgstr "Cookiedomæne"
msgid "Copied"
-msgstr ""
+msgstr "Kopieret"
msgid "Copied labels and milestone from %{source_issuable_reference}."
msgstr ""
msgid "Copy"
-msgstr ""
+msgstr "Kopiér"
msgid "Copy %{http_label} clone URL"
msgstr ""
msgid "Copy %{name}"
-msgstr ""
+msgstr "Kopiér %{name}"
msgid "Copy %{protocol} clone URL"
msgstr ""
msgid "Copy %{proxy_url}"
-msgstr ""
+msgstr "Kopiér %{proxy_url}"
msgid "Copy %{type}"
-msgstr ""
+msgstr "Kopiér %{type}"
msgid "Copy Account ID to clipboard"
-msgstr ""
+msgstr "Kopiér konto-id til udklipsholder"
msgid "Copy External ID to clipboard"
msgstr ""
msgid "Copy ID"
-msgstr ""
+msgstr "Kopiér id"
msgid "Copy IP Address"
-msgstr ""
+msgstr "Kopiér IP-adresse"
msgid "Copy KRB5 clone URL"
-msgstr ""
+msgstr "Kopiér klonings-URL for KRB5"
msgid "Copy SSH clone URL"
-msgstr ""
+msgstr "Kopiér klonings-URL for SSH"
msgid "Copy SSH public key"
-msgstr ""
+msgstr "Kopiér offentlig SSH-nøgle"
msgid "Copy URL"
-msgstr ""
+msgstr "Kopiér URL"
msgid "Copy branch name"
-msgstr ""
+msgstr "Kopiér grennavn"
msgid "Copy codes"
-msgstr ""
+msgstr "Kopiér koder"
msgid "Copy command"
-msgstr ""
+msgstr "Kopiér kommando"
msgid "Copy commands"
-msgstr ""
+msgstr "Kopiér kommandoer"
msgid "Copy commit SHA"
msgstr ""
msgid "Copy environment"
-msgstr ""
+msgstr "Kopiér miljø"
msgid "Copy evidence SHA"
msgstr ""
msgid "Copy file contents"
-msgstr ""
+msgstr "Kopiér filindhold"
msgid "Copy file path"
-msgstr ""
+msgstr "Kopiér filsti"
msgid "Copy key"
-msgstr ""
+msgstr "Kopiér nøgle"
msgid "Copy labels and milestone from %{source_issuable_reference}."
-msgstr ""
+msgstr "Kopiér etiketter og milepæl fra %{source_issuable_reference}."
msgid "Copy labels and milestone from other issue or merge request in this project"
msgstr ""
msgid "Copy link"
-msgstr ""
+msgstr "Kopiér link"
msgid "Copy link to chart"
-msgstr ""
+msgstr "Kopiér link til diagram"
msgid "Copy reference"
-msgstr ""
+msgstr "Kopiér reference"
msgid "Copy secret"
-msgstr ""
+msgstr "Kopiér hemmelighed"
msgid "Copy source branch name"
-msgstr ""
+msgstr "Kopiér kildegrennavn"
msgid "Copy the code below to implement tracking in your application:"
msgstr ""
@@ -9155,25 +9197,25 @@ msgid "Copy this registration token."
msgstr ""
msgid "Copy this value"
-msgstr ""
+msgstr "Kopiér værdien"
msgid "Copy to clipboard"
-msgstr ""
+msgstr "Kopiér til udklipsholder"
msgid "Copy token"
-msgstr ""
+msgstr "Kopiér token"
msgid "Copy trigger token"
-msgstr ""
+msgstr "Kopiér udløsertoken"
msgid "Copy value"
-msgstr ""
+msgstr "Kopiér værdi"
msgid "Corpus Management|Are you sure you want to delete the corpus?"
msgstr ""
msgid "CorpusManagement|Actions"
-msgstr ""
+msgstr "Handlinger"
msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
msgstr ""
@@ -9185,7 +9227,7 @@ msgid "CorpusManagement|Fuzz testing corpus management"
msgstr ""
msgid "CorpusManagement|Last updated"
-msgstr ""
+msgstr "Sidst opdateret"
msgid "CorpusManagement|Last used"
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -9203,7 +9245,7 @@ msgid "CorpusManagement|Not Set"
msgstr ""
msgid "CorpusManagement|Target"
-msgstr ""
+msgstr "MÃ¥l"
msgid "CorpusManagement|To use this corpus, edit the corresponding YAML file"
msgstr ""
@@ -9233,10 +9275,10 @@ msgid "Could not commit. An unexpected error occurred."
msgstr ""
msgid "Could not connect to FogBugz, check your URL"
-msgstr ""
+msgstr "Kunne ikke oprette forbindelse til FogBugz, tjek din URL"
msgid "Could not connect to Sentry. Refresh the page to try again."
-msgstr ""
+msgstr "Kunne ikke oprette forbindelse til Sentry. Opdater siden og prøv igen."
msgid "Could not connect to Web IDE file mirror service."
msgstr ""
@@ -9245,25 +9287,25 @@ msgid "Could not create Wiki Repository at this time. Please try again later."
msgstr ""
msgid "Could not create environment"
-msgstr ""
+msgstr "Kunne ikke oprette miljø"
msgid "Could not create group"
-msgstr ""
+msgstr "Kunne ikke oprette gruppe"
msgid "Could not create issue"
-msgstr ""
+msgstr "Kunne ikke oprette problemstilling"
msgid "Could not create project"
-msgstr ""
+msgstr "Kunne ikke oprette projekt"
msgid "Could not create wiki page"
-msgstr ""
+msgstr "Kunne ikke oprette wikiside"
msgid "Could not delete chat nickname %{chat_name}."
-msgstr ""
+msgstr "Kunne ikke slette chatkaldenavnet %{chat_name}."
msgid "Could not delete wiki page"
-msgstr ""
+msgstr "Kunne ikke slette wikiside"
msgid "Could not draw the lines for job relationships"
msgstr ""
@@ -9272,31 +9314,31 @@ msgid "Could not fetch policy because existing policy YAML is invalid"
msgstr ""
msgid "Could not find design."
-msgstr ""
+msgstr "Kunne ikke finde design."
msgid "Could not find iteration"
-msgstr ""
+msgstr "Kunne ikke finde gennemløb"
msgid "Could not get the data properly"
-msgstr ""
+msgstr "Kunne ikke hente dataene ordentligt"
msgid "Could not load the user chart. Please refresh the page to try again."
-msgstr ""
+msgstr "Kunne ikke indlæse brugerdiagrammet. Opdater venligst siden og prøv igen."
msgid "Could not load usage counts. Please refresh the page to try again."
msgstr ""
msgid "Could not remove %{user} from %{group}. Cannot remove last group owner."
-msgstr ""
+msgstr "Kunne ikke fjerne %{user} fra %{group}. Kan ikke fjerne sidste gruppeejer."
msgid "Could not remove %{user} from %{group}. User is not a group member."
-msgstr ""
+msgstr "Kunne ikke fjerne %{user} fra %{group}. Brugeren er ikke et gruppemedlem."
msgid "Could not remove the trigger."
-msgstr ""
+msgstr "Kunne ikke fjerne udløseren."
msgid "Could not restore the group"
-msgstr ""
+msgstr "Kunne ikke gendanne gruppen"
msgid "Could not revoke impersonation token %{token_name}."
msgstr ""
@@ -9308,82 +9350,82 @@ msgid "Could not revoke project access token %{project_access_token_name}."
msgstr ""
msgid "Could not save group ID"
-msgstr ""
+msgstr "Kunne ikke gemme gruppe-id"
msgid "Could not save project ID"
-msgstr ""
+msgstr "Kunne ikke gemme projekt-id"
msgid "Could not save prometheus manual configuration"
msgstr ""
msgid "Could not update the LDAP settings"
-msgstr ""
+msgstr "Kunne ikke opdatere LDAP-indstillingerne"
msgid "Could not update wiki page"
-msgstr ""
+msgstr "Kunne ikke opdatere wikiside"
msgid "Could not upload your designs as one or more files uploaded are not supported."
-msgstr ""
+msgstr "Kunne ikke uploade dine designs da en eller flere af de uploadede filer ikke understøttes."
msgid "Couldn't assign policy to project"
-msgstr ""
+msgstr "Kunne ikke tildele regelsæt til projekt"
msgid "Coverage"
-msgstr ""
+msgstr "Dækning"
msgid "Coverage Fuzzing"
msgstr ""
msgid "Create"
-msgstr ""
+msgstr "Opret"
msgid "Create %{environment}"
-msgstr ""
+msgstr "Opret %{environment}"
msgid "Create %{humanized_resource_name}"
-msgstr ""
+msgstr "Opret %{humanized_resource_name}"
msgid "Create %{type}"
-msgstr ""
+msgstr "Opret %{type}"
msgid "Create New Directory"
-msgstr ""
+msgstr "Opret ny mappe"
msgid "Create New Domain"
-msgstr ""
+msgstr "Opret nyt domæne"
msgid "Create a GitLab account first, and then connect it to your %{label} account."
msgstr ""
msgid "Create a Mattermost team for this group"
-msgstr ""
+msgstr "Opret et Mattermost-team til gruppen"
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
msgid "Create a merge request"
-msgstr ""
+msgstr "Opret en sammenlægningsanmodning"
msgid "Create a new %{codeStart}.gitlab-ci.yml%{codeEnd} file at the root of the repository to get started."
msgstr ""
msgid "Create a new branch"
-msgstr ""
+msgstr "Opret en ny gren"
msgid "Create a new file as there are no files yet. Afterwards, you'll be able to commit your changes."
msgstr ""
msgid "Create a new issue"
-msgstr ""
+msgstr "Opret en ny problemstilling"
msgid "Create a new repository"
-msgstr ""
+msgstr "Opret et nyt depot"
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
msgid "Create an account using:"
-msgstr ""
+msgstr "Opret en konto med:"
msgid "Create an incident. Incidents are created for each alert triggered."
msgstr ""
@@ -9392,10 +9434,10 @@ msgid "Create and provide your GitHub %{link_start}Personal Access Token%{link_e
msgstr ""
msgid "Create branch"
-msgstr ""
+msgstr "Opret branch"
msgid "Create commit"
-msgstr ""
+msgstr "Opret commit"
msgid "Create confidential merge request"
msgstr ""
@@ -9404,139 +9446,139 @@ msgid "Create confidential merge request and branch"
msgstr ""
msgid "Create directory"
-msgstr ""
+msgstr "Opret mappe"
msgid "Create empty repository"
-msgstr ""
+msgstr "Opret tomt depot"
msgid "Create epic"
-msgstr ""
+msgstr "Opret epic"
msgid "Create file"
-msgstr ""
+msgstr "Opret fil"
msgid "Create from"
-msgstr ""
+msgstr "Opret fra"
msgid "Create group"
-msgstr ""
+msgstr "Opret gruppe"
msgid "Create group label"
-msgstr ""
+msgstr "Opret gruppeetiket"
msgid "Create incident"
-msgstr ""
+msgstr "Opret hændelse"
msgid "Create issue"
-msgstr ""
+msgstr "Opret problemstilling"
msgid "Create iteration"
-msgstr ""
+msgstr "Opret gennemløb"
msgid "Create list"
-msgstr ""
+msgstr "Opret liste"
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
msgid "Create merge request"
-msgstr ""
+msgstr "Opret sammenlægningsanmodning"
msgid "Create merge request and branch"
msgstr ""
msgid "Create milestone"
-msgstr ""
+msgstr "Opret milepæl"
msgid "Create new"
msgstr ""
msgid "Create new %{name} by email"
-msgstr ""
+msgstr "Opret ny %{name} via e-mail"
msgid "Create new CI/CD pipeline"
-msgstr ""
+msgstr "Opret ny CI-/CD-pipeline"
msgid "Create new Value Stream"
-msgstr ""
+msgstr "Opret ny Value Stream"
msgid "Create new branch"
-msgstr ""
+msgstr "Opret ny gren"
msgid "Create new confidential %{issuableType}"
msgstr ""
msgid "Create new directory"
-msgstr ""
+msgstr "Opret ny mappe"
msgid "Create new file"
-msgstr ""
+msgstr "Opret ny fil"
msgid "Create new file or directory"
-msgstr ""
+msgstr "Opret ny fil eller mappe"
msgid "Create new label"
-msgstr ""
+msgstr "Opret ny etiket"
msgid "Create new project"
-msgstr ""
+msgstr "Opret nyt projekt"
msgid "Create new..."
msgstr ""
msgid "Create project"
-msgstr ""
+msgstr "Opret projekt"
msgid "Create project label"
-msgstr ""
+msgstr "Opret projektetiket"
msgid "Create release"
-msgstr ""
+msgstr "Opret udgivelse"
msgid "Create requirement"
-msgstr ""
+msgstr "Opret krav"
msgid "Create snippet"
-msgstr ""
+msgstr "Opret uddrag"
msgid "Create tag %{tagName}"
-msgstr ""
+msgstr "Opret mærkatet %{tagName}"
msgid "Create user"
-msgstr ""
+msgstr "Opret bruger"
msgid "Create wildcard: %{searchTerm}"
-msgstr ""
+msgstr "Opret jokertegn: %{searchTerm}"
msgid "Create your first page"
-msgstr ""
+msgstr "Opret din første side"
msgid "Create your group"
-msgstr ""
+msgstr "Opret din gruppe"
msgid "Create/import your first project"
-msgstr ""
+msgstr "Opret/importér dit første projekt"
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
-msgstr ""
+msgstr "Du har ikke tilladelse til at oprette en undergruppe i gruppen."
msgid "CreateGroup|You don’t have permission to create groups."
-msgstr ""
+msgstr "Du har ikke tilladelse til at oprette grupper."
msgid "CreateTag|Tag"
-msgstr ""
+msgstr "Mærkat"
msgid "CreateTokenToCloneLink|create a personal access token"
msgstr ""
msgid "CreateValueStreamForm|%{name} (default)"
-msgstr ""
+msgstr "%{name} (standard)"
msgid "CreateValueStreamForm|'%{name}' Value Stream created"
-msgstr ""
+msgstr "'%{name}' Value Stream oprettet"
msgid "CreateValueStreamForm|'%{name}' Value Stream saved"
-msgstr ""
+msgstr "'%{name}' Value Stream gemt"
msgid "CreateValueStreamForm|Add another stage"
msgstr ""
@@ -9551,7 +9593,7 @@ msgid "CreateValueStreamForm|Code stage start"
msgstr ""
msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
+msgstr "Opret Value Stream"
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9560,7 +9602,7 @@ msgid "CreateValueStreamForm|Create from no template"
msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
-msgstr ""
+msgstr "Opret ny Value Stream"
msgid "CreateValueStreamForm|Default stages"
msgstr ""
@@ -9569,7 +9611,7 @@ msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
msgid "CreateValueStreamForm|Edit Value Stream"
-msgstr ""
+msgstr "Rediger Value Stream"
msgid "CreateValueStreamForm|Editing stage"
msgstr ""
@@ -9596,7 +9638,7 @@ msgid "CreateValueStreamForm|Maximum length %{maxLength} characters"
msgstr ""
msgid "CreateValueStreamForm|Name is required"
-msgstr ""
+msgstr "Navn kræves"
msgid "CreateValueStreamForm|New stage"
msgstr ""
@@ -9620,7 +9662,7 @@ msgid "CreateValueStreamForm|Restore stage"
msgstr ""
msgid "CreateValueStreamForm|Save Value Stream"
-msgstr ""
+msgstr "Gem Value Stream"
msgid "CreateValueStreamForm|Select end event"
msgstr ""
@@ -9656,10 +9698,10 @@ msgid "CreateValueStreamForm|Value Stream name"
msgstr ""
msgid "Created"
-msgstr ""
+msgstr "Oprettet"
msgid "Created %{epicTimeagoDate}"
-msgstr ""
+msgstr "Oprettet %{epicTimeagoDate}"
msgid "Created %{timestamp}"
msgstr ""
@@ -9677,28 +9719,28 @@ msgid "Created branch '%{branch_name}' and a merge request to resolve this issue
msgstr ""
msgid "Created by %{job}"
-msgstr ""
+msgstr "Oprettet af %{job}"
msgid "Created by me"
-msgstr ""
+msgstr "Oprettet af mig"
msgid "Created by:"
-msgstr ""
+msgstr "Oprettet af:"
msgid "Created date"
-msgstr ""
+msgstr "Oprettelsesdato"
msgid "Created issue %{issueLink}"
-msgstr ""
+msgstr "Oprettede problemstillingen %{issueLink}"
msgid "Created issue %{issueLink} at %{projectLink}"
-msgstr ""
+msgstr "Oprettede problemstillingen %{issueLink} hos %{projectLink}"
msgid "Created merge request %{mergeRequestLink}"
-msgstr ""
+msgstr "Oprettede sammenlægningsanmodningen %{mergeRequestLink}"
msgid "Created merge request %{mergeRequestLink} at %{projectLink}"
-msgstr ""
+msgstr "Oprettede sammenlægningsanmodningen %{mergeRequestLink} hos %{projectLink}"
msgid "Created on"
msgstr ""
@@ -9710,37 +9752,37 @@ msgid "Created on:"
msgstr ""
msgid "Creates a branch and a merge request to resolve this issue."
-msgstr ""
+msgstr "Oprettet en gren og en sammenlægningsanmodning til at løse problemstillingen."
msgid "Creates branch '%{branch_name}' and a merge request to resolve this issue."
-msgstr ""
+msgstr "Oprettet grenen '%{branch_name}' og en sammenlægningsanmodning til at løse problemstillingen."
msgid "Creating"
-msgstr ""
+msgstr "Opretter"
msgid "Creating epic"
-msgstr ""
+msgstr "Opretter epic"
msgid "Creating graphs uses the data from the Prometheus server. If this takes a long time, ensure that data is available."
msgstr ""
msgid "Creation date"
-msgstr ""
+msgstr "Oprettelsesdato"
msgid "Credentials"
-msgstr ""
+msgstr "Loginoplysninger"
msgid "CredentialsInventory|GPG Keys"
-msgstr ""
+msgstr "GPG-nøgler"
msgid "CredentialsInventory|No credentials found"
-msgstr ""
+msgstr "Ingen loginoplysninger fundet"
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
msgid "CredentialsInventory|SSH Keys"
-msgstr ""
+msgstr "SSH-nøgler"
msgid "Credit card validated at:"
msgstr ""
@@ -9752,7 +9794,7 @@ msgid "Critical vulnerabilities present"
msgstr ""
msgid "Cron Timezone"
-msgstr ""
+msgstr "Tidszone for Cron"
msgid "Cron time zone"
msgstr ""
@@ -9767,10 +9809,10 @@ msgid "CsvParser|Quoted field unterminated"
msgstr ""
msgid "CsvParser|Too few fields"
-msgstr ""
+msgstr "For få felter"
msgid "CsvParser|Too many fields"
-msgstr ""
+msgstr "For mange felter"
msgid "CsvParser|Trailing quote on quoted field is malformed"
msgstr ""
@@ -9779,13 +9821,13 @@ msgid "CsvParser|Unable to auto-detect delimiter; defaulted to \",\""
msgstr ""
msgid "Current"
-msgstr ""
+msgstr "Nuværende"
msgid "Current Branch"
-msgstr ""
+msgstr "Nuværende gren"
msgid "Current Project"
-msgstr ""
+msgstr "Nuværende projekt"
msgid "Current forks will keep their visibility level."
msgstr ""
@@ -9794,7 +9836,7 @@ msgid "Current node must be the primary node or you will be locking yourself out
msgstr ""
msgid "Current password"
-msgstr ""
+msgstr "Nuværende adgangskode"
msgid "Current sign-in IP:"
msgstr ""
@@ -9809,19 +9851,19 @@ msgid "CurrentUser|Buy Pipeline minutes"
msgstr ""
msgid "CurrentUser|Edit profile"
-msgstr ""
+msgstr "Rediger profil"
msgid "CurrentUser|One of your groups is running out"
msgstr ""
msgid "CurrentUser|Preferences"
-msgstr ""
+msgstr "Præferencer"
msgid "CurrentUser|Start an Ultimate trial"
-msgstr ""
+msgstr "Start en Ultimate-prøveperiode"
msgid "CurrentUser|Upgrade"
-msgstr ""
+msgstr "Opgrader"
msgid "Custom Attributes"
msgstr ""
@@ -9836,7 +9878,7 @@ msgid "Custom hostname (for private commit emails)"
msgstr ""
msgid "Custom metrics"
-msgstr ""
+msgstr "Tilpasset målinger"
msgid "Custom notification events"
msgstr ""
@@ -9845,10 +9887,10 @@ msgid "Custom notification levels are the same as participating levels. With cus
msgstr ""
msgid "Custom project templates"
-msgstr ""
+msgstr "Tilpasset projektskabeloner"
msgid "Custom project templates have not been set up for groups that you are a member of. They are enabled from a group’s settings page. Contact your group’s Owner or Maintainer to setup custom project templates."
-msgstr ""
+msgstr "Tilpasset projektskabeloner er ikke blevet sat op for grupper som du er et medlem af. De aktiveres fra en gruppes indstillingsside. Kontakt din gruppes ejer eller vedligeholder for at opsætte tilpasset projektskabeloner."
msgid "Custom range"
msgstr ""
@@ -9866,19 +9908,19 @@ msgid "Customize CI/CD settings, including Auto DevOps, shared runners, and job
msgstr ""
msgid "Customize colors"
-msgstr ""
+msgstr "Tilpas farver"
msgid "Customize how FogBugz email addresses and usernames are imported into GitLab. In the next step, you'll be able to select the projects you want to import."
msgstr ""
msgid "Customize icon"
-msgstr ""
+msgstr "Tilpas ikon"
msgid "Customize language and region related settings."
msgstr ""
msgid "Customize name"
-msgstr ""
+msgstr "Tilpas navn"
msgid "Customize your pipeline configuration and coverage report."
msgstr ""
@@ -9887,10 +9929,10 @@ msgid "Customize your pipeline configuration."
msgstr ""
msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
+msgstr "Vil du tilpasse siden?"
msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
+msgstr "Gå til præferencer"
msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
msgstr ""
@@ -9968,13 +10010,13 @@ msgid "CycleAnalyticsEvent|Merge request merged"
msgstr ""
msgid "CycleAnalyticsStage|Code"
-msgstr ""
+msgstr "Kode"
msgid "CycleAnalyticsStage|Issue"
-msgstr ""
+msgstr "Problemstilling"
msgid "CycleAnalyticsStage|Plan"
-msgstr ""
+msgstr "Plan"
msgid "CycleAnalyticsStage|Review"
msgstr ""
@@ -10007,7 +10049,7 @@ msgid "CycleAnalytics|Average days to completion"
msgstr ""
msgid "CycleAnalytics|Date"
-msgstr ""
+msgstr "Dato"
msgid "CycleAnalytics|Days to completion"
msgstr ""
@@ -10026,14 +10068,14 @@ msgstr ""
msgid "CycleAnalytics|Project selected"
msgid_plural "CycleAnalytics|%d projects selected"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Projekt valgt"
+msgstr[1] "%d projekter valgt"
msgid "CycleAnalytics|Select labels"
-msgstr ""
+msgstr "Vælg etiketter"
msgid "CycleAnalytics|Show"
-msgstr ""
+msgstr "Vis"
msgid "CycleAnalytics|Showing %{subjectFilterText} and %{selectedLabelsCount} label"
msgid_plural "CycleAnalytics|Showing %{subjectFilterText} and %{selectedLabelsCount} labels"
@@ -10050,7 +10092,7 @@ msgid "CycleAnalytics|Stages"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
-msgstr ""
+msgstr "Opgaver efter type"
msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
msgstr ""
@@ -10083,13 +10125,13 @@ msgid "DAST Scans"
msgstr ""
msgid "DNS"
-msgstr ""
+msgstr "DNS"
msgid "DORA4Metrics|%{startDate} - %{endDate}"
msgstr ""
msgid "DORA4Metrics|Date"
-msgstr ""
+msgstr "Dato"
msgid "DORA4Metrics|Days from merge to deploy"
msgstr ""
@@ -10122,25 +10164,25 @@ msgid "DORA4Metrics|The chart displays the median time between a merge request b
msgstr ""
msgid "Dashboard"
-msgstr ""
+msgstr "Betjeningspanel"
msgid "Dashboard uid not found"
-msgstr ""
+msgstr "Betjeningspanel-uid ikke fundet"
msgid "DashboardProjects|All"
-msgstr ""
+msgstr "Alle"
msgid "DashboardProjects|Personal"
-msgstr ""
+msgstr "Personlige"
msgid "DashboardProjects|Trending"
msgstr ""
msgid "Dashboard|%{firstProject} and %{secondProject}"
-msgstr ""
+msgstr "%{firstProject} og %{secondProject}"
msgid "Dashboard|%{firstProject}, %{rest}, and %{secondProject}"
-msgstr ""
+msgstr "%{firstProject}, %{rest} og %{secondProject}"
msgid "Dashboard|Unable to add %{invalidProjects}. This dashboard is available for public projects, and private projects in groups with a Premium plan."
msgstr ""
@@ -10152,7 +10194,7 @@ msgid "DastConfig|DAST Settings"
msgstr ""
msgid "DastConfig|Generate code snippet"
-msgstr ""
+msgstr "Generer kodeuddrag"
msgid "DastConfig|Scan Configuration"
msgstr ""
@@ -10164,13 +10206,13 @@ msgid "DastProfiles|AJAX spider"
msgstr ""
msgid "DastProfiles|Active"
-msgstr ""
+msgstr "Aktiv"
msgid "DastProfiles|Additional request headers (Optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
-msgstr ""
+msgstr "Er du sikker på, at du vil slette profilen?"
msgid "DastProfiles|Authentication"
msgstr ""
@@ -10179,7 +10221,7 @@ msgid "DastProfiles|Authentication URL"
msgstr ""
msgid "DastProfiles|Branch missing"
-msgstr ""
+msgstr "Gren mangler"
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -10227,7 +10269,7 @@ msgid "DastProfiles|Debug messages"
msgstr ""
msgid "DastProfiles|Delete profile"
-msgstr ""
+msgstr "Slet profil"
msgid "DastProfiles|Do you want to discard this scanner profile?"
msgstr ""
@@ -10239,7 +10281,7 @@ msgid "DastProfiles|Do you want to discard your changes?"
msgstr ""
msgid "DastProfiles|Edit profile"
-msgstr ""
+msgstr "Rediger profil"
msgid "DastProfiles|Edit scanner profile"
msgstr ""
@@ -10257,7 +10299,7 @@ msgid "DastProfiles|Enter headers in a comma-separated list."
msgstr ""
msgid "DastProfiles|Error Details"
-msgstr ""
+msgstr "Fejldetaljer"
msgid "DastProfiles|Excluded URLs"
msgstr ""
@@ -10305,13 +10347,13 @@ msgid "DastProfiles|Passive"
msgstr ""
msgid "DastProfiles|Password"
-msgstr ""
+msgstr "Adgangskode"
msgid "DastProfiles|Password form field"
msgstr ""
msgid "DastProfiles|Profile name"
-msgstr ""
+msgstr "Profilnavn"
msgid "DastProfiles|Request header names and values. Headers are added to every request made by DAST."
msgstr ""
@@ -10323,7 +10365,7 @@ msgid "DastProfiles|Rest API"
msgstr ""
msgid "DastProfiles|Run scan"
-msgstr ""
+msgstr "Kør skanning"
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -10332,7 +10374,7 @@ msgid "DastProfiles|Save commonly used configurations for target sites and scan
msgstr ""
msgid "DastProfiles|Save profile"
-msgstr ""
+msgstr "Gem profil"
msgid "DastProfiles|Saved Scans"
msgstr ""
@@ -10347,7 +10389,7 @@ msgid "DastProfiles|Scanner Profile"
msgstr ""
msgid "DastProfiles|Scanner Profiles"
-msgstr ""
+msgstr "Skannerprofiler"
msgid "DastProfiles|Scanner name"
msgstr ""
@@ -10374,7 +10416,7 @@ msgid "DastProfiles|Spider timeout"
msgstr ""
msgid "DastProfiles|Target"
-msgstr ""
+msgstr "MÃ¥l"
msgid "DastProfiles|Target URL"
msgstr ""
@@ -10401,13 +10443,13 @@ msgid "DastProfiles|Turn on AJAX spider"
msgstr ""
msgid "DastProfiles|URL"
-msgstr ""
+msgstr "URL"
msgid "DastProfiles|URLs to skip during the authenticated scan."
msgstr ""
msgid "DastProfiles|Username"
-msgstr ""
+msgstr "Brugernavn"
msgid "DastProfiles|Username form field"
msgstr ""
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10505,7 +10562,7 @@ msgid "Data is still calculating..."
msgstr ""
msgid "Data type"
-msgstr ""
+msgstr "Datatype"
msgid "Database update failed"
msgstr ""
@@ -10520,7 +10577,7 @@ msgid "DatadogIntegration|API URL"
msgstr ""
msgid "DatadogIntegration|Environment"
-msgstr ""
+msgstr "Miljø"
msgid "DatadogIntegration|For self-managed deployments, set the %{codeOpen}env%{codeClose} tag for all the data sent to Datadog. %{linkOpen}How do I use tags?%{linkClose}"
msgstr ""
@@ -10547,10 +10604,10 @@ msgid "Datasource name not found"
msgstr ""
msgid "Date"
-msgstr ""
+msgstr "Dato"
msgid "Date picker"
-msgstr ""
+msgstr "Datovælger"
msgid "Date range"
msgstr ""
@@ -10562,19 +10619,19 @@ msgid "Day of month"
msgstr ""
msgid "DayTitle|F"
-msgstr ""
+msgstr "F"
msgid "DayTitle|M"
-msgstr ""
+msgstr "M"
msgid "DayTitle|S"
msgstr ""
msgid "DayTitle|W"
-msgstr ""
+msgstr "O"
msgid "Days"
-msgstr ""
+msgstr "Dage"
msgid "Days to merge"
msgstr ""
@@ -10583,7 +10640,7 @@ msgid "Deactivate dormant users after 90 days of inactivity. Users can return to
msgstr ""
msgid "Dear Administrator,"
-msgstr ""
+msgstr "Kære administrator,"
msgid "Debian package already exists in Distribution"
msgstr ""
@@ -10592,16 +10649,16 @@ msgid "Debug"
msgstr ""
msgid "Dec"
-msgstr ""
+msgstr "Dec."
msgid "December"
-msgstr ""
+msgstr "December"
msgid "Decline"
-msgstr ""
+msgstr "Afvis"
msgid "Decline and sign out"
-msgstr ""
+msgstr "Afvis og log ud"
msgid "Decompressed archive size validation failed."
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10619,7 +10673,7 @@ msgid "Default artifacts expiration"
msgstr ""
msgid "Default branch"
-msgstr ""
+msgstr "Standardgren"
msgid "Default branch and protected branches"
msgstr ""
@@ -10681,9 +10735,12 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
-msgid "Definition"
+msgid "Define how approval rules are applied as a merge request moves toward completion."
msgstr ""
+msgid "Definition"
+msgstr "Definition"
+
msgid "Delayed Project Deletion (%{adjourned_deletion})"
msgstr ""
@@ -10694,7 +10751,7 @@ msgid "DelayedJobs|Are you sure you want to run %{job_name} immediately? This jo
msgstr ""
msgid "DelayedJobs|Start now"
-msgstr ""
+msgstr "Start nu"
msgid "DelayedJobs|Unschedule"
msgstr ""
@@ -10703,46 +10760,52 @@ msgid "DelayedJobs|delayed"
msgstr ""
msgid "Delete"
-msgstr ""
+msgstr "Slet"
msgid "Delete %{issuableType}"
-msgstr ""
+msgstr "Slet %{issuableType}"
msgid "Delete %{name}"
-msgstr ""
+msgstr "Slet %{name}"
msgid "Delete Comment"
-msgstr ""
+msgstr "Slet kommentar"
msgid "Delete Key"
-msgstr ""
+msgstr "Slet nøgle"
msgid "Delete Value Stream"
-msgstr ""
+msgstr "Slet Value Stream"
msgid "Delete account"
-msgstr ""
+msgstr "Slet konto"
msgid "Delete artifacts"
-msgstr ""
+msgstr "Slet artefakter"
msgid "Delete badge"
+msgstr "Slet badge"
+
+msgid "Delete column"
msgstr ""
msgid "Delete comment"
+msgstr "Slet kommentar"
+
+msgid "Delete corpus"
msgstr ""
msgid "Delete domain"
-msgstr ""
+msgstr "Slet domæne"
msgid "Delete file"
-msgstr ""
+msgstr "Slet fil"
msgid "Delete image repository"
msgstr ""
msgid "Delete label"
-msgstr ""
+msgstr "Slet etiket"
msgid "Delete label: %{labelName}"
msgstr ""
@@ -10751,9 +10814,12 @@ msgid "Delete pipeline"
msgstr ""
msgid "Delete project"
-msgstr ""
+msgstr "Slet projekt"
msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgstr "Slet projekt. Er du HELT SIKKER?"
+
+msgid "Delete row"
msgstr ""
msgid "Delete self monitoring project"
@@ -10763,28 +10829,31 @@ msgid "Delete serverless domain?"
msgstr ""
msgid "Delete snippet"
-msgstr ""
+msgstr "Slet uddrag"
msgid "Delete snippet?"
-msgstr ""
+msgstr "Slet uddrag?"
msgid "Delete source branch"
-msgstr ""
+msgstr "Slet kildegren"
msgid "Delete subscription"
+msgstr "Slet abonnement"
+
+msgid "Delete table"
msgstr ""
msgid "Delete this attachment"
-msgstr ""
+msgstr "Slet vedhæftningen"
msgid "Delete this epic and all descendants?"
msgstr ""
msgid "Delete user list"
-msgstr ""
+msgstr "Slet brugerliste"
msgid "Delete variable"
-msgstr ""
+msgstr "Slet variabel"
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -10808,40 +10877,40 @@ msgid "DeleteProject|Failed to restore wiki repository. Please contact the admin
msgstr ""
msgid "DeleteValueStream|'%{name}' Value Stream deleted"
-msgstr ""
+msgstr "'%{name}' Value Stream slettet"
msgid "DeleteValueStream|Are you sure you want to delete the \"%{name}\" Value Stream?"
msgstr ""
msgid "DeleteValueStream|Delete %{name}"
-msgstr ""
+msgstr "Slet %{name}"
msgid "Deleted"
-msgstr ""
+msgstr "Slettet"
msgid "Deleted Projects"
-msgstr ""
+msgstr "Slettede projekter"
msgid "Deleted chat nickname: %{chat_name}!"
-msgstr ""
+msgstr "Slettede chatkaldenavn: %{chat_name}!"
msgid "Deleted projects"
-msgstr ""
+msgstr "Slettede projekter"
msgid "Deleted projects cannot be restored!"
-msgstr ""
+msgstr "Slettede projekter kan ikke gendannes!"
msgid "Deleting"
-msgstr ""
+msgstr "Sletter"
msgid "Deleting a project places it into a read-only state until %{date}, at which point the project will be permanently deleted. Are you ABSOLUTELY sure?"
msgstr ""
msgid "Deleting the project will delete its repository and all related resources, including issues and merge requests."
-msgstr ""
+msgstr "Sletning af projektet vil slette dets depot og alle relaterede ressourcer, herunder problemstillinger og sammenlægningsanmodninger."
msgid "Deletion pending. This project will be deleted on %{date}. Repository and other project resources are read-only."
-msgstr ""
+msgstr "Afventer sletning. Projektet vil blive slettet %{date}. Depotet og andre projektressourcer er skrivebeskyttet."
msgid "Denied"
msgstr ""
@@ -10856,7 +10925,7 @@ msgid "Deny access request"
msgstr ""
msgid "Dependencies"
-msgstr ""
+msgstr "Afhængigheder"
msgid "Dependencies help page link"
msgstr ""
@@ -10868,8 +10937,8 @@ msgstr[1] ""
msgid "Dependencies|%d more"
msgid_plural "Dependencies|%d more"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d mere"
+msgstr[1] "%d mere"
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
@@ -10877,43 +10946,43 @@ msgstr[0] ""
msgstr[1] ""
msgid "Dependencies|%{remainingLicensesCount} more"
-msgstr ""
+msgstr "%{remainingLicensesCount} mere"
msgid "Dependencies|(top level)"
-msgstr ""
+msgstr "(topniveau)"
msgid "Dependencies|All"
-msgstr ""
+msgstr "Alle"
msgid "Dependencies|Based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
msgid "Dependencies|Component"
-msgstr ""
+msgstr "Komponent"
msgid "Dependencies|Component name"
-msgstr ""
+msgstr "Komponentnavn"
msgid "Dependencies|Dependency path"
-msgstr ""
+msgstr "Afhængighedssti"
msgid "Dependencies|Export as JSON"
-msgstr ""
+msgstr "Eksportér som JSON"
msgid "Dependencies|Job failed to generate the dependency list"
msgstr ""
msgid "Dependencies|Learn more about dependency paths"
-msgstr ""
+msgstr "Lær mere om afhængighedsstier"
msgid "Dependencies|License"
-msgstr ""
+msgstr "Licens"
msgid "Dependencies|Location"
-msgstr ""
+msgstr "Placering"
msgid "Dependencies|Location and dependency path"
-msgstr ""
+msgstr "Placering og afhængighedssti"
msgid "Dependencies|Packager"
msgstr ""
@@ -10928,7 +10997,7 @@ msgid "Dependencies|There may be multiple paths"
msgstr ""
msgid "Dependencies|Toggle vulnerability list"
-msgstr ""
+msgstr "SÃ¥rbarhedsliste til/fra"
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
@@ -10937,7 +11006,7 @@ msgid "Dependencies|Vulnerable components"
msgstr ""
msgid "Dependency List"
-msgstr ""
+msgstr "Afhængighedsliste"
msgid "Dependency List has no entries"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -10972,20 +11041,20 @@ msgstr[1] ""
msgid "Deploy"
msgid_plural "Deploys"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Udsendelse"
+msgstr[1] "Udsendelser"
msgid "Deploy Keys"
-msgstr ""
+msgstr "Udsendelsesnøgler"
msgid "Deploy freezes"
msgstr ""
msgid "Deploy key was successfully updated."
-msgstr ""
+msgstr "Udsendelsesnøglen blev opdateret."
msgid "Deploy keys"
-msgstr ""
+msgstr "Udsendelsesnøgler"
msgid "Deploy keys grant read/write access to all repositories in your instance"
msgstr ""
@@ -10994,17 +11063,29 @@ msgid "Deploy progress not found. To see pods, ensure your environment matches %
msgstr ""
msgid "Deploy to..."
-msgstr ""
+msgstr "Udsend til ..."
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
msgid "DeployFreeze|Add deploy freeze"
+msgstr "Tilføj udsendelsesfrysning"
+
+msgid "DeployFreeze|Delete"
msgstr ""
-msgid "DeployFreeze|Edit"
+msgid "DeployFreeze|Delete deploy freeze?"
msgstr ""
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
+msgid "DeployFreeze|Edit"
+msgstr "Rediger"
+
msgid "DeployFreeze|Freeze end"
msgstr ""
@@ -11018,13 +11099,13 @@ msgid "DeployFreeze|Specify deploy freezes using %{cron_syntax_link_start}cron s
msgstr ""
msgid "DeployFreeze|Time zone"
-msgstr ""
+msgstr "Tidszone"
msgid "DeployKeys|+%{count} others"
-msgstr ""
+msgstr "+%{count} andre"
msgid "DeployKeys|Current project"
-msgstr ""
+msgstr "Nuværende projekt"
msgid "DeployKeys|Deploy key"
msgstr ""
@@ -11069,37 +11150,37 @@ msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
+msgstr "Tillader læse- og skriveadgang til registerbilleder."
msgid "DeployTokens|Allows read and write access to the package registry."
-msgstr ""
+msgstr "Tillader læse- og skriveadgang til pakkeregistret."
msgid "DeployTokens|Allows read-only access to registry images."
-msgstr ""
+msgstr "Tillader skrivebeskyttet adgang til registerbilleder."
msgid "DeployTokens|Allows read-only access to the package registry."
-msgstr ""
+msgstr "Tillader skrivebeskyttet adgang til pakkeregistret."
msgid "DeployTokens|Allows read-only access to the repository."
-msgstr ""
+msgstr "Tillader skrivebeskyttet adgang til depotet."
msgid "DeployTokens|Copy deploy token"
-msgstr ""
+msgstr "Kopiér udsendelsestoken"
msgid "DeployTokens|Copy username"
-msgstr ""
+msgstr "Kopiér brugernavn"
msgid "DeployTokens|Create a new deploy token for all projects in this group. %{link_start}What are deploy tokens?%{link_end}"
msgstr ""
msgid "DeployTokens|Create deploy token"
-msgstr ""
+msgstr "Opret udsendelsestoken"
msgid "DeployTokens|Created"
-msgstr ""
+msgstr "Oprettet"
msgid "DeployTokens|Deploy tokens"
-msgstr ""
+msgstr "Udsendelsestokens"
msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
@@ -11114,25 +11195,25 @@ msgid "DeployTokens|Enter an expiration date for your token. Defaults to never e
msgstr ""
msgid "DeployTokens|Expires"
-msgstr ""
+msgstr "Udløber"
msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
-msgstr ""
+msgstr "Navn"
msgid "DeployTokens|New deploy token"
msgstr ""
msgid "DeployTokens|Revoke"
-msgstr ""
+msgstr "Tilbagekald"
msgid "DeployTokens|Revoke %{name}"
msgstr ""
msgid "DeployTokens|Scopes"
-msgstr ""
+msgstr "Omfang"
msgid "DeployTokens|This %{entity_type} has no active Deploy Tokens."
msgstr ""
@@ -11147,7 +11228,7 @@ msgid "DeployTokens|Use this token as a password. Save it. This password can %{i
msgstr ""
msgid "DeployTokens|Username"
-msgstr ""
+msgstr "Brugernavn"
msgid "DeployTokens|Your new Deploy Token username"
msgstr ""
@@ -11159,22 +11240,22 @@ msgid "DeployTokens|Your new project deploy token has been created."
msgstr ""
msgid "Deployed"
-msgstr ""
+msgstr "Udsendt"
msgid "Deployed to"
-msgstr ""
+msgstr "Udsendt til"
msgid "Deployed-after"
-msgstr ""
+msgstr "Udsendt-efter"
msgid "Deployed-before"
-msgstr ""
+msgstr "Udsendt-inden"
msgid "Deploying to"
-msgstr ""
+msgstr "Udsender til"
msgid "Deploying to AWS is easy with GitLab"
-msgstr ""
+msgstr "Udsendelse til AWS er let med GitLab"
msgid "Deployment Frequency"
msgstr ""
@@ -11183,7 +11264,7 @@ msgid "Deployment frequency"
msgstr ""
msgid "Deployments"
-msgstr ""
+msgstr "Udsendelser"
msgid "Deployments|%{deployments} environment impacted."
msgid_plural "Deployments|%{deployments} environments impacted."
@@ -11191,43 +11272,43 @@ msgstr[0] ""
msgstr[1] ""
msgid "Deployment|API"
-msgstr ""
+msgstr "API"
msgid "Deployment|This deployment was created using the API"
msgstr ""
msgid "Deployment|canceled"
-msgstr ""
+msgstr "annulleret"
msgid "Deployment|created"
-msgstr ""
+msgstr "oprettet"
msgid "Deployment|failed"
-msgstr ""
+msgstr "mislykkedes"
msgid "Deployment|running"
-msgstr ""
+msgstr "kører"
msgid "Deployment|skipped"
-msgstr ""
+msgstr "sprunget over"
msgid "Deployment|success"
-msgstr ""
+msgstr "lykkedes"
msgid "Deprioritize label"
msgstr ""
msgid "Descending"
-msgstr ""
+msgstr "Faldende"
msgid "Describe the goal of the changes and what reviewers should be aware of."
msgstr ""
msgid "Description"
-msgstr ""
+msgstr "Beskrivelse"
msgid "Description (optional)"
-msgstr ""
+msgstr "Beskrivelse (valgfrit)"
msgid "Description parsed with %{link_start}GitLab Flavored Markdown%{link_end}"
msgstr ""
@@ -11239,10 +11320,10 @@ msgid "Description template"
msgstr ""
msgid "Description:"
-msgstr ""
+msgstr "Beskrivelse:"
msgid "Descriptive label"
-msgstr ""
+msgstr "Beskrivende etiket"
msgid "Design Management files and data"
msgstr ""
@@ -11275,22 +11356,22 @@ msgid "DesignManagement|Archived designs will still be available in previous ver
msgstr ""
msgid "DesignManagement|Are you sure you want to archive the selected designs?"
-msgstr ""
+msgstr "Er du sikker på, at du vil arkivere de valgte designs?"
msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
-msgstr ""
+msgstr "Er du sikker på, at du vil annullere ændringer til kommentaren?"
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
-msgstr ""
+msgstr "Er du sikker på, at du vil annullere oprettelse af kommentaren?"
msgid "DesignManagement|Cancel changes"
-msgstr ""
+msgstr "Annuller ændringer"
msgid "DesignManagement|Cancel comment confirmation"
-msgstr ""
+msgstr "Annuller bekræftelse af kommentar"
msgid "DesignManagement|Cancel comment update confirmation"
-msgstr ""
+msgstr "Annuller bekræftelse om opdatering af kommentar"
msgid "DesignManagement|Click the image where you'd like to start a new discussion"
msgstr ""
@@ -11305,43 +11386,43 @@ msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
msgid "DesignManagement|Could not create new discussion. Please try again."
-msgstr ""
+msgstr "Kunne ikke oprette ny debat. Prøv venligst igen."
msgid "DesignManagement|Could not update discussion. Please try again."
-msgstr ""
+msgstr "Kunne ikke opdatere debat. Prøv venligst igen."
msgid "DesignManagement|Could not update note. Please try again."
msgstr ""
msgid "DesignManagement|Deselect all"
-msgstr ""
+msgstr "Fravælg alle"
msgid "DesignManagement|Designs"
-msgstr ""
+msgstr "Designs"
msgid "DesignManagement|Discard comment"
-msgstr ""
+msgstr "Forkast kommentar"
msgid "DesignManagement|Download design"
-msgstr ""
+msgstr "Download design"
msgid "DesignManagement|Error uploading a new design. Please try again."
msgstr ""
msgid "DesignManagement|Go back to designs"
-msgstr ""
+msgstr "GÃ¥ tilbage til designs"
msgid "DesignManagement|Go to next design"
-msgstr ""
+msgstr "Gå til næste design"
msgid "DesignManagement|Go to previous design"
-msgstr ""
+msgstr "GÃ¥ til forrige design"
msgid "DesignManagement|Keep changes"
-msgstr ""
+msgstr "Behold ændringer"
msgid "DesignManagement|Keep comment"
-msgstr ""
+msgstr "Behold kommentar"
msgid "DesignManagement|Learn more about resolving comments"
msgstr ""
@@ -11356,16 +11437,16 @@ msgid "DesignManagement|Resolved Comments"
msgstr ""
msgid "DesignManagement|Save comment"
-msgstr ""
+msgstr "Gem kommentar"
msgid "DesignManagement|Select all"
-msgstr ""
+msgstr "Vælg alle"
msgid "DesignManagement|The maximum number of designs allowed to be uploaded is %{upload_limit}. Please try again."
msgstr ""
msgid "DesignManagement|There was an error moving your designs. Please upload your designs below."
-msgstr ""
+msgstr "Der opstod en fejl ved flytning af dine designs. Upload venligst dine designs nedenunder."
msgid "DesignManagement|To upload designs, you'll need to enable LFS and have an admin enable hashed storage. %{requirements_link_start}More information%{requirements_link_end}"
msgstr ""
@@ -11374,10 +11455,10 @@ msgid "DesignManagement|Unresolve thread"
msgstr ""
msgid "DesignManagement|Upload designs"
-msgstr ""
+msgstr "Upload designs"
msgid "DesignManagement|Upload skipped."
-msgstr ""
+msgstr "Upload sprunget over."
msgid "DesignManagement|Your designs are being copied and are on their way… Please refresh to update."
msgstr ""
@@ -11386,34 +11467,34 @@ msgid "DesignManagement|and %{moreCount} more."
msgstr ""
msgid "Designs"
-msgstr ""
+msgstr "Designs"
msgid "Destroy"
-msgstr ""
+msgstr "Ødelæg"
msgid "Detail"
-msgstr ""
+msgstr "Detalje"
msgid "Details"
-msgstr ""
+msgstr "Detaljer"
msgid "Details (default)"
-msgstr ""
+msgstr "Detaljer (standard)"
msgid "Detect host keys"
-msgstr ""
+msgstr "Registrer værtsnøgler"
msgid "DevOps Adoption"
msgstr ""
msgid "DevOps Report"
-msgstr ""
+msgstr "DevOps-rapport"
msgid "DevOps adoption"
msgstr ""
msgid "Devices (optional)"
-msgstr ""
+msgstr "Enheder (valgfrit)"
msgid "DevopsAdoption|%{adoptedCount}/%{featuresCount} %{title} features adopted"
msgstr ""
@@ -11430,14 +11511,20 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
msgid "DevopsAdoption|Approvals"
-msgstr ""
+msgstr "Godkendelser"
msgid "DevopsAdoption|Are you sure that you would like to remove %{name} from the table?"
-msgstr ""
+msgstr "Er du sikker på, at du vil fjerne %{name} fra tabellen?"
msgid "DevopsAdoption|At least one approval on a merge request"
msgstr ""
@@ -11455,28 +11542,28 @@ msgid "DevopsAdoption|At least one pipeline successfully run"
msgstr ""
msgid "DevopsAdoption|Code owners"
-msgstr ""
+msgstr "Kodeejere"
msgid "DevopsAdoption|Code owners enabled for at least one project"
-msgstr ""
+msgstr "Kodeejere aktiveret for mindst ét projekt"
msgid "DevopsAdoption|Confirm remove Group"
msgstr ""
msgid "DevopsAdoption|DAST"
-msgstr ""
+msgstr "DAST"
msgid "DevopsAdoption|DAST enabled for at least one project"
-msgstr ""
+msgstr "DAST aktiveret for mindst ét projekt"
msgid "DevopsAdoption|Dependency Scanning"
-msgstr ""
+msgstr "Afhængighedsskanning"
msgid "DevopsAdoption|Dependency Scanning enabled for at least one project"
-msgstr ""
+msgstr "Afhængighedsskanning aktiveret for mindst ét projekt"
msgid "DevopsAdoption|Deploys"
-msgstr ""
+msgstr "Udsender"
msgid "DevopsAdoption|Dev"
msgstr ""
@@ -11485,12 +11572,12 @@ msgid "DevopsAdoption|DevOps adoption tracks the use of key features across your
msgstr ""
msgid "DevopsAdoption|Edit groups"
-msgstr ""
+msgstr "Rediger grupper"
msgid "DevopsAdoption|Edit subgroups"
-msgstr ""
+msgstr "Rediger undergrupper"
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11500,13 +11587,13 @@ msgid "DevopsAdoption|Fuzz Testing enabled for at least one project"
msgstr ""
msgid "DevopsAdoption|Issues"
-msgstr ""
+msgstr "Problemstillinger"
msgid "DevopsAdoption|MRs"
msgstr ""
msgid "DevopsAdoption|No results…"
-msgstr ""
+msgstr "Ingen resultater …"
msgid "DevopsAdoption|Not adopted"
msgstr ""
@@ -11518,13 +11605,13 @@ msgid "DevopsAdoption|Overall adoption"
msgstr ""
msgid "DevopsAdoption|Pipelines"
-msgstr ""
+msgstr "Pipelines"
msgid "DevopsAdoption|Remove Group"
-msgstr ""
+msgstr "Fjern gruppe"
msgid "DevopsAdoption|Remove Group from the table."
-msgstr ""
+msgstr "Fjern gruppe fra tabellen."
msgid "DevopsAdoption|Runner configured for project/group"
msgstr ""
@@ -11533,25 +11620,25 @@ msgid "DevopsAdoption|Runners"
msgstr ""
msgid "DevopsAdoption|SAST"
-msgstr ""
+msgstr "SAST"
msgid "DevopsAdoption|SAST enabled for at least one project"
-msgstr ""
+msgstr "SAST aktiveret for mindst ét projekt"
msgid "DevopsAdoption|Sec"
msgstr ""
msgid "DevopsAdoption|There was an error enabling the current group. Please refresh the page."
-msgstr ""
+msgstr "Der opstod en fejl ved aktivering af den nuværende gruppe. Opdater venligst siden."
msgid "DevopsAdoption|There was an error fetching Group adoption data. Please refresh the page."
msgstr ""
msgid "DevopsAdoption|There was an error fetching Groups. Please refresh the page."
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af grupper. Opdater venligst siden."
msgid "DevopsAdoption|This group has no subgroups"
-msgstr ""
+msgstr "Gruppen har ingen undergrupper"
msgid "DevopsAdoption|You cannot remove the group you are currently in."
msgstr ""
@@ -11563,19 +11650,19 @@ msgid "DevopsReport|DevOps score metrics are based on usage over the last 30 day
msgstr ""
msgid "DevopsReport|High"
-msgstr ""
+msgstr "Høj"
msgid "DevopsReport|Leader usage"
msgstr ""
msgid "DevopsReport|Low"
-msgstr ""
+msgstr "Lav"
msgid "DevopsReport|Moderate"
msgstr ""
msgid "DevopsReport|Overview"
-msgstr ""
+msgstr "Oversigt"
msgid "DevopsReport|Score"
msgstr ""
@@ -11587,7 +11674,7 @@ msgid "DevopsReport|Your usage"
msgstr ""
msgid "Didn't receive a confirmation email?"
-msgstr ""
+msgstr "Modtog du ikke en bekræftelses e-mail?"
msgid "Didn't receive confirmation instructions?"
msgstr ""
@@ -11599,7 +11686,7 @@ msgid "Diff files surpassing this limit will be presented as 'too large' and won
msgstr ""
msgid "Diff limits"
-msgstr ""
+msgstr "Diff-grænser"
msgid "Difference between start date and now"
msgstr ""
@@ -11617,13 +11704,13 @@ msgid "Diffs|Show %{unfoldCount} lines"
msgstr ""
msgid "Diffs|Show all unchanged lines"
-msgstr ""
+msgstr "Vis alle uændrede linjer"
msgid "Diffs|Something went wrong while fetching diff lines."
msgstr ""
msgid "Direct member"
-msgstr ""
+msgstr "Direkte medlem"
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -11632,22 +11719,22 @@ msgid "Direct users to this page after they sign out."
msgstr ""
msgid "Direction"
-msgstr ""
+msgstr "Retning"
msgid "Directory name"
-msgstr ""
+msgstr "Mappenavn"
msgid "Disable"
-msgstr ""
+msgstr "Deaktivér"
msgid "Disable Two-factor Authentication"
msgstr ""
msgid "Disable What's new"
-msgstr ""
+msgstr "Deaktivér Nyheder"
msgid "Disable for this project"
-msgstr ""
+msgstr "Deaktivér for projektet"
msgid "Disable group runners"
msgstr ""
@@ -11656,7 +11743,7 @@ msgid "Disable two-factor authentication"
msgstr ""
msgid "Disabled"
-msgstr ""
+msgstr "Deaktiveret"
msgid "Disabled by %{parent} owner"
msgstr ""
@@ -11665,22 +11752,22 @@ msgid "Disabled mirrors can only be enabled by instance owners. It is recommende
msgstr ""
msgid "Discard"
-msgstr ""
+msgstr "Forkast"
msgid "Discard all changes"
-msgstr ""
+msgstr "Forkast alle ændringer"
msgid "Discard all changes?"
-msgstr ""
+msgstr "Forkast alle ændringer?"
msgid "Discard changes"
-msgstr ""
+msgstr "Forkast ændringer"
msgid "Discard changes to %{path}?"
-msgstr ""
+msgstr "Forkast ændringer til %{path}?"
msgid "Discard draft"
-msgstr ""
+msgstr "Forkast kladde"
msgid "DiscordService|Discord Notifications"
msgstr ""
@@ -11689,10 +11776,10 @@ msgid "DiscordService|Send notifications about project events to a Discord chann
msgstr ""
msgid "Discover"
-msgstr ""
+msgstr "Opdag"
msgid "Discover GitLab Geo"
-msgstr ""
+msgstr "Opdag GitLab Geo"
msgid "Discover projects, groups and snippets. Share your projects with others"
msgstr ""
@@ -11716,10 +11803,10 @@ msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd
msgstr ""
msgid "Discover|Start a free trial"
-msgstr ""
+msgstr "Start en gratis prøveperiode"
msgid "Discover|Upgrade now"
-msgstr ""
+msgstr "Opgrader nu"
msgid "Discuss a specific suggestion or question"
msgstr ""
@@ -11737,10 +11824,10 @@ msgid "Discussion to reply to cannot be found"
msgstr ""
msgid "Disk Usage"
-msgstr ""
+msgstr "Diskforbrug"
msgid "Dismiss"
-msgstr ""
+msgstr "Afskedig"
msgid "Dismiss %d selected vulnerability as"
msgid_plural "Dismiss %d selected vulnerabilities as"
@@ -11763,10 +11850,10 @@ msgid "Dismissable"
msgstr ""
msgid "Dismissed"
-msgstr ""
+msgstr "Afskediget"
msgid "Dismissed at %{projectLink}"
-msgstr ""
+msgstr "Afskediget hos %{projectLink}"
msgid "Dismissed on pipeline %{pipelineLink}"
msgstr ""
@@ -11784,7 +11871,7 @@ msgid "Display rendered file"
msgstr ""
msgid "Display source"
-msgstr ""
+msgstr "Vis kilde"
msgid "Display time tracking in issues in total hours only."
msgstr ""
@@ -11796,13 +11883,13 @@ msgid "Do not force push over diverged refs. After the mirror is created, this s
msgstr ""
msgid "Do you want to remove this deploy key?"
-msgstr ""
+msgstr "Vil du fjerne udsendelsesnøglen?"
msgid "Dockerfile"
msgstr ""
msgid "Documentation"
-msgstr ""
+msgstr "Dokumentation"
msgid "Documentation for popular identity providers"
msgstr ""
@@ -11811,34 +11898,34 @@ msgid "Documentation pages URL"
msgstr ""
msgid "Documents reindexed: %{processed_documents} (%{percentage}%%)"
-msgstr ""
+msgstr "Dokumenter genindekseret: %{processed_documents} (%{percentage}%%)"
msgid "Does not apply to projects in personal namespaces, which are deleted immediately on request."
msgstr ""
msgid "Domain"
-msgstr ""
+msgstr "Domæne"
msgid "Domain Name"
-msgstr ""
+msgstr "Domænenavn"
msgid "Domain cannot be deleted while associated to one or more clusters."
msgstr ""
msgid "Domain was successfully created."
-msgstr ""
+msgstr "Domænet blev oprettet."
msgid "Domain was successfully deleted."
-msgstr ""
+msgstr "Domænet blev slettet."
msgid "Domain was successfully updated."
-msgstr ""
+msgstr "Domænet blev opdateret."
msgid "Don't have an account yet?"
-msgstr ""
+msgstr "Har du ikke en konto endnu?"
msgid "Don't include description in commit message"
-msgstr ""
+msgstr "Medtag ikke beskrivelse i commit-meddelelse"
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -11847,43 +11934,43 @@ msgid "Don't send service data"
msgstr ""
msgid "Don't show again"
-msgstr ""
+msgstr "Vis ikke igen"
msgid "Done"
-msgstr ""
+msgstr "Færdig"
msgid "Dormant users"
msgstr ""
msgid "Download"
-msgstr ""
+msgstr "Download"
msgid "Download %{format}"
-msgstr ""
+msgstr "Download %{format}"
msgid "Download %{format}:"
-msgstr ""
+msgstr "Download %{format}:"
msgid "Download %{name} artifact"
-msgstr ""
+msgstr "Download artefaktet %{name}"
msgid "Download (%{fileSizeReadable})"
-msgstr ""
+msgstr "Download (%{fileSizeReadable})"
msgid "Download (%{size})"
-msgstr ""
+msgstr "Download (%{size})"
msgid "Download CSV"
-msgstr ""
+msgstr "Download CSV"
msgid "Download artifacts"
-msgstr ""
+msgstr "Download artefakter"
msgid "Download as"
-msgstr ""
+msgstr "Download som"
msgid "Download codes"
-msgstr ""
+msgstr "Download koder"
msgid "Download evidence JSON"
msgstr ""
@@ -11892,16 +11979,16 @@ msgid "Download export"
msgstr ""
msgid "Download image"
-msgstr ""
+msgstr "Download billede"
msgid "Download raw data (.csv)"
-msgstr ""
+msgstr "Download rå data (.csv)"
msgid "Download source code"
-msgstr ""
+msgstr "Download kildekode"
msgid "Download this directory"
-msgstr ""
+msgstr "Download mappen"
msgid "DownloadCommit|Email Patches"
msgstr ""
@@ -11910,7 +11997,7 @@ msgid "DownloadCommit|Plain Diff"
msgstr ""
msgid "DownloadSource|Download"
-msgstr ""
+msgstr "Download"
msgid "Downstream"
msgstr ""
@@ -11919,7 +12006,7 @@ msgid "Downvotes"
msgstr ""
msgid "Draft"
-msgstr ""
+msgstr "Udkast"
msgid "Draft merge requests can't be merged."
msgstr ""
@@ -11958,13 +12045,13 @@ msgid "DropdownWidget|No %{issuableAttribute} found"
msgstr ""
msgid "Due Date"
-msgstr ""
+msgstr "Forfaldsdato"
msgid "Due date"
-msgstr ""
+msgstr "Forfaldsdato"
msgid "Duration"
-msgstr ""
+msgstr "Varighed"
msgid "During this process, you’ll be asked for URLs from GitLab’s side. Use the URLs shown below."
msgstr ""
@@ -11973,133 +12060,139 @@ msgid "Dynamic Application Security Testing (DAST)"
msgstr ""
msgid "E-mail:"
-msgstr ""
+msgstr "E-mail:"
msgid "Each project can also have an issue tracker and a wiki."
msgstr ""
msgid "Edit"
-msgstr ""
+msgstr "Rediger"
msgid "Edit %{issuable}"
-msgstr ""
+msgstr "Rediger %{issuable}"
msgid "Edit %{name}"
-msgstr ""
+msgstr "Rediger %{name}"
msgid "Edit Comment"
-msgstr ""
+msgstr "Rediger kommentar"
msgid "Edit Deploy Key"
-msgstr ""
+msgstr "Rediger udsendelsesnøgle"
msgid "Edit Geo Node"
msgstr ""
msgid "Edit Group Hook"
+msgstr "Rediger gruppehook"
+
+msgid "Edit Identity"
msgstr ""
msgid "Edit Label"
-msgstr ""
+msgstr "Rediger etiket"
msgid "Edit Milestone"
-msgstr ""
+msgstr "Rediger milepæl"
msgid "Edit Password"
-msgstr ""
+msgstr "Rediger adgangskode"
msgid "Edit Pipeline Schedule %{id}"
msgstr ""
msgid "Edit Release"
-msgstr ""
+msgstr "Rediger udgivelse"
msgid "Edit Requirement"
-msgstr ""
+msgstr "Rediger krav"
msgid "Edit Slack integration"
-msgstr ""
+msgstr "Rediger Slack-integrering"
msgid "Edit Snippet"
-msgstr ""
+msgstr "Rediger uddrag"
msgid "Edit System Hook"
-msgstr ""
+msgstr "Rediger systemhook"
msgid "Edit application"
-msgstr ""
+msgstr "Rediger program"
msgid "Edit comment"
-msgstr ""
+msgstr "Rediger kommentar"
msgid "Edit deploy freeze"
-msgstr ""
+msgstr "Rediger udsendelsesfrysning"
msgid "Edit description"
-msgstr ""
+msgstr "Rediger beskrivelse"
msgid "Edit environment"
-msgstr ""
+msgstr "Rediger miljø"
msgid "Edit files in the editor and commit changes here"
-msgstr ""
+msgstr "Rediger filer i editoren og commit ændringer her"
msgid "Edit fork in Web IDE"
-msgstr ""
+msgstr "Rediger forgrening i Web IDE"
msgid "Edit group application"
-msgstr ""
+msgstr "Rediger gruppeprogram"
msgid "Edit group: %{group_name}"
-msgstr ""
+msgstr "Rediger gruppe: %{group_name}"
msgid "Edit identity for %{user_name}"
msgstr ""
msgid "Edit in Web IDE"
-msgstr ""
+msgstr "Rediger i Web IDE"
msgid "Edit in single-file editor"
msgstr ""
msgid "Edit inline"
-msgstr ""
+msgstr "Rediger indlejret"
msgid "Edit issues"
-msgstr ""
+msgstr "Rediger problemstillinger"
msgid "Edit public deploy key"
-msgstr ""
+msgstr "Rediger offentlig udsendelsesnøgle"
msgid "Edit sidebar"
+msgstr "Rediger sidebjælke"
+
+msgid "Edit table"
msgstr ""
msgid "Edit this file only."
-msgstr ""
+msgstr "Rediger kun filen."
msgid "Edit this release"
-msgstr ""
+msgstr "Rediger udgivelsen"
msgid "Edit title and description"
-msgstr ""
+msgstr "Rediger titel og beskrivelse"
msgid "Edit user: %{user_name}"
-msgstr ""
+msgstr "Rediger bruger: %{user_name}"
msgid "Edit wiki page"
-msgstr ""
+msgstr "Rediger wikiside"
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
msgid "Edited"
-msgstr ""
+msgstr "Redigeret"
msgid "Edited %{timeago}"
-msgstr ""
+msgstr "Redigerede %{timeago}"
msgid "Editing"
-msgstr ""
+msgstr "Redigerer"
msgid "Elapsed time"
msgstr ""
@@ -12141,7 +12234,7 @@ msgid "Elastic|None. Select projects to index."
msgstr ""
msgid "Email"
-msgstr ""
+msgstr "E-mail"
msgid "Email %{number}"
msgstr ""
@@ -12174,7 +12267,7 @@ msgid "Email patch"
msgstr ""
msgid "Email sent"
-msgstr ""
+msgstr "E-mail sendt"
msgid "Email the pipeline status to a list of recipients."
msgstr ""
@@ -12183,10 +12276,10 @@ msgid "Email updates (optional)"
msgstr ""
msgid "Email:"
-msgstr ""
+msgstr "E-mail:"
msgid "Email: %{email}"
-msgstr ""
+msgstr "E-mail: %{email}"
msgid "EmailError|It appears that the email is blank. Make sure your reply is at the top of the email, we can't process inline replies."
msgstr ""
@@ -12222,7 +12315,7 @@ msgid "EmailParticipantsWarning|and %{moreCount} more"
msgstr ""
msgid "Emails"
-msgstr ""
+msgstr "E-mails"
msgid "Emails sent from Service Desk have this name."
msgstr ""
@@ -12258,43 +12351,40 @@ msgid "EmailsOnPushService|tanuki@example.com gitlab@example.com"
msgstr ""
msgid "Embed"
-msgstr ""
+msgstr "Indlejr"
msgid "Embed an image of your existing Jaeger server in GitLab."
msgstr ""
msgid "Empty file"
-msgstr ""
+msgstr "Tom fil"
msgid "Enable"
-msgstr ""
+msgstr "Aktivér"
msgid "Enable Auto DevOps"
-msgstr ""
+msgstr "Aktivér Auto DevOps"
msgid "Enable Git pack file bitmap creation"
msgstr ""
msgid "Enable Gitpod"
-msgstr ""
+msgstr "Aktivér Gitpod"
msgid "Enable Gitpod?"
-msgstr ""
-
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
+msgstr "Aktivér Gitpod?"
msgid "Enable Invisible Captcha during sign up"
msgstr ""
msgid "Enable Kroki"
-msgstr ""
+msgstr "Aktivér Kroki"
msgid "Enable Mailgun event receiver"
msgstr ""
msgid "Enable PlantUML"
-msgstr ""
+msgstr "Aktivér PlantUML"
msgid "Enable Pseudonymizer data collection"
msgstr ""
@@ -12324,7 +12414,7 @@ msgid "Enable access to the performance bar for non-administrators in a given gr
msgstr ""
msgid "Enable admin mode"
-msgstr ""
+msgstr "Aktivér administratortilstand"
msgid "Enable and disable Service Desk. Some additional configuration might be required. %{link_start}Learn more%{link_end}."
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12357,7 +12450,7 @@ msgid "Enable feature to choose access level"
msgstr ""
msgid "Enable for this project"
-msgstr ""
+msgstr "Aktivér for projektet"
msgid "Enable group runners"
msgstr ""
@@ -12371,9 +12464,12 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
-msgid "Enable integration"
+msgid "Enable incident management inbound alert limit"
msgstr ""
+msgid "Enable integration"
+msgstr "Aktivér integrering"
+
msgid "Enable kuromoji custom analyzer: Indexing"
msgstr ""
@@ -12381,7 +12477,7 @@ msgid "Enable kuromoji custom analyzer: Search"
msgstr ""
msgid "Enable maintenance mode"
-msgstr ""
+msgstr "Aktivér vedligeholdelsestilstand"
msgid "Enable multipart emails"
msgstr ""
@@ -12396,13 +12492,13 @@ msgid "Enable protected paths rate limit"
msgstr ""
msgid "Enable proxy"
-msgstr ""
+msgstr "Aktivér proxy"
msgid "Enable reCAPTCHA"
-msgstr ""
+msgstr "Aktivér reCAPTCHA"
msgid "Enable reCAPTCHA for login"
-msgstr ""
+msgstr "Aktivér reCAPTCHA for indlogning"
msgid "Enable reCAPTCHA, Invisible Captcha, Akismet and set IP limits. For reCAPTCHA, we currently only support %{recaptcha_v2_link_start}v2%{recaptcha_v2_link_end}"
msgstr ""
@@ -12429,7 +12525,7 @@ msgid "Enable smartcn custom analyzer: Search"
msgstr ""
msgid "Enable two-factor authentication"
-msgstr ""
+msgstr "Aktivér tofaktorgodkendelse"
msgid "Enable unauthenticated API request rate limit"
msgstr ""
@@ -12453,13 +12549,13 @@ msgid "EnableReviewApp|%{stepStart}Step 4 (optional)%{stepEnd}. Enable Visual Re
msgstr ""
msgid "EnableReviewApp|Close"
-msgstr ""
+msgstr "Luk"
msgid "EnableReviewApp|Copy snippet text"
msgstr ""
msgid "Enabled"
-msgstr ""
+msgstr "Aktiveret"
msgid "Enabled Git access protocols"
msgstr ""
@@ -12477,19 +12573,19 @@ msgid "Encountered an error while rendering: %{err}"
msgstr ""
msgid "End Time"
-msgstr ""
+msgstr "Sluttid"
msgid "Ends"
-msgstr ""
+msgstr "Slutter"
msgid "Ends at (UTC)"
-msgstr ""
+msgstr "Slutter (UTC)"
msgid "Ends on"
-msgstr ""
+msgstr "Slutter"
msgid "Ends: %{endsAt}"
-msgstr ""
+msgstr "Slutter: %{endsAt}"
msgid "Enforce DNS rebinding attack protection"
msgstr ""
@@ -12519,13 +12615,13 @@ msgid "Enter 2FA for Admin Mode"
msgstr ""
msgid "Enter Admin Mode"
-msgstr ""
+msgstr "GÃ¥ i administratortilstand"
msgid "Enter IP address range"
msgstr ""
msgid "Enter a number"
-msgstr ""
+msgstr "Indtast et tal"
msgid "Enter an integer number between 0 and 100"
msgstr ""
@@ -12537,7 +12633,7 @@ msgid "Enter at least three characters to search"
msgstr ""
msgid "Enter domain"
-msgstr ""
+msgstr "Indtast domæne"
msgid "Enter in your Bitbucket Server URL and personal access token below"
msgstr ""
@@ -12552,7 +12648,7 @@ msgid "Enter new AWS Secret Access Key"
msgstr ""
msgid "Enter number of issues"
-msgstr ""
+msgstr "Indtast antal problemstillinger"
msgid "Enter one or more user ID separated by commas"
msgstr ""
@@ -12582,13 +12678,13 @@ msgid "Enter your Packagist username."
msgstr ""
msgid "Enter your password to approve"
-msgstr ""
+msgstr "Indtast din adgangskode for at godkende"
msgid "Enterprise"
msgstr ""
msgid "Environment"
-msgstr ""
+msgstr "Miljø"
msgid "Environment does not have deployments"
msgstr ""
@@ -12600,7 +12696,7 @@ msgid "Environment is required for Stages::VariableEndpointInserter"
msgstr ""
msgid "Environment scope"
-msgstr ""
+msgstr "Miljøomfang"
msgid "Environment variable %{code_start}%{environment_variable}%{code_end} does not exist or is not pointing to a valid directory."
msgstr ""
@@ -12612,10 +12708,10 @@ msgid "Environment variables on this GitLab instance are configured to be %{link
msgstr ""
msgid "Environment:"
-msgstr ""
+msgstr "Miljø:"
msgid "EnvironmentDashboard|API"
-msgstr ""
+msgstr "API"
msgid "EnvironmentDashboard|Created through the Deployment API"
msgstr ""
@@ -12624,40 +12720,40 @@ msgid "EnvironmentDashboard|You are looking at the last updated environment"
msgstr ""
msgid "Environments"
-msgstr ""
+msgstr "Miljøer"
msgid "Environments Dashboard"
-msgstr ""
+msgstr "Betjeningspanel for miljøer"
msgid "Environments allow you to track deployments of your application. %{linkStart}More information%{linkEnd}."
msgstr ""
msgid "Environments in %{name}"
-msgstr ""
+msgstr "Miljøer i %{name}"
msgid "EnvironmentsAlert|%{severity} • %{title} %{text}. %{linkStart}View Details%{linkEnd} · %{startedAt} "
msgstr ""
msgid "EnvironmentsDashboard|Add a project to the dashboard"
-msgstr ""
+msgstr "Tilføj et projekt til betjeningspanelet"
msgid "EnvironmentsDashboard|Add projects"
-msgstr ""
+msgstr "Tilføj projekter"
msgid "EnvironmentsDashboard|Environments Dashboard"
msgstr ""
msgid "EnvironmentsDashboard|Job: %{job}"
-msgstr ""
+msgstr "Job: %{job}"
msgid "EnvironmentsDashboard|More actions"
-msgstr ""
+msgstr "Flere handlinger"
msgid "EnvironmentsDashboard|More information"
-msgstr ""
+msgstr "Mere information"
msgid "EnvironmentsDashboard|Remove"
-msgstr ""
+msgstr "Fjern"
msgid "EnvironmentsDashboard|The environments dashboard provides a summary of each project's environments' status, including pipeline and alert statuses."
msgstr ""
@@ -12687,7 +12783,7 @@ msgid "Environments|An error occurred while stopping the environment, please try
msgstr ""
msgid "Environments|Are you sure you want to stop this environment?"
-msgstr ""
+msgstr "Er du sikker på, at du vil stoppe miljøet?"
msgid "Environments|Auto stop in"
msgstr ""
@@ -12696,7 +12792,7 @@ msgid "Environments|Auto stops %{autoStopAt}"
msgstr ""
msgid "Environments|Commit"
-msgstr ""
+msgstr "Commit"
msgid "Environments|Currently showing %{fetched} results."
msgstr ""
@@ -12705,58 +12801,64 @@ msgid "Environments|Currently showing all results."
msgstr ""
msgid "Environments|Delete"
-msgstr ""
+msgstr "Slet"
msgid "Environments|Delete '%{environmentName}'?"
msgstr ""
msgid "Environments|Delete environment"
-msgstr ""
+msgstr "Slet miljø"
msgid "Environments|Deleting the '%{environmentName}' environment cannot be undone. Do you want to delete it anyway?"
msgstr ""
msgid "Environments|Deploy to..."
-msgstr ""
+msgstr "Udsend til ..."
msgid "Environments|Deployment"
-msgstr ""
+msgstr "Udsendelse"
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
msgid "Environments|Environment"
-msgstr ""
+msgstr "Miljø"
msgid "Environments|Environments"
-msgstr ""
+msgstr "Miljøer"
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
msgid "Environments|Job"
-msgstr ""
+msgstr "Job"
msgid "Environments|Learn about environments"
-msgstr ""
+msgstr "Lær om miljøer"
msgid "Environments|Learn more about stopping environments"
-msgstr ""
+msgstr "Lær mere om at stoppe miljøer"
msgid "Environments|Logs from %{start} to %{end}."
msgstr ""
msgid "Environments|More information"
-msgstr ""
+msgstr "Mere information"
msgid "Environments|New environment"
-msgstr ""
+msgstr "Nyt miljø"
msgid "Environments|No deployed environments"
msgstr ""
@@ -12801,20 +12903,23 @@ msgid "Environments|Select pod"
msgstr ""
msgid "Environments|Show all"
-msgstr ""
+msgstr "Vis alle"
msgid "Environments|Stop"
-msgstr ""
+msgstr "Stop"
msgid "Environments|Stop environment"
-msgstr ""
+msgstr "Stop miljø"
msgid "Environments|Stopping %{environmentName}"
msgstr ""
-msgid "Environments|There was an error fetching the logs. Please try again."
+msgid "Environments|Take the survey"
msgstr ""
+msgid "Environments|There was an error fetching the logs. Please try again."
+msgstr "Der opstod en fejl ved hentning af loggene. Prøv venligst igen."
+
msgid "Environments|This action will relaunch the job for commit %{linkStart}%{commitId}%{linkEnd}, putting the environment in a previous version. Are you sure you want to continue?"
msgstr ""
@@ -12828,19 +12933,25 @@ msgid "Environments|Upcoming deployment"
msgstr ""
msgid "Environments|Updated"
-msgstr ""
+msgstr "Opdateret"
msgid "Environments|You don't have any environments right now"
msgstr ""
-msgid "Environments|protected"
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
msgstr ""
-msgid "Epic"
+msgid "Environments|by %{avatar}"
msgstr ""
+msgid "Environments|protected"
+msgstr "beskyttet"
+
+msgid "Epic"
+msgstr "Epic"
+
msgid "Epic Boards"
-msgstr ""
+msgstr "Epictavler"
msgid "Epic cannot be found."
msgstr ""
@@ -12855,13 +12966,13 @@ msgid "Epic not found for given params"
msgstr ""
msgid "Epics"
-msgstr ""
+msgstr "Epics"
msgid "Epics Roadmap"
msgstr ""
msgid "Epics and Issues"
-msgstr ""
+msgstr "Epics og problemstillinger"
msgid "Epics let you manage your portfolio of projects more efficiently and with less effort"
msgstr ""
@@ -12870,16 +12981,16 @@ msgid "Epics, issues, and merge requests"
msgstr ""
msgid "Epics|%{startDate} – %{dueDate}"
-msgstr ""
+msgstr "%{startDate} – %{dueDate}"
msgid "Epics|%{startDate} – No due date"
-msgstr ""
+msgstr "%{startDate} – ingen forfaldsdato"
msgid "Epics|Add a new epic"
-msgstr ""
+msgstr "Tilføj en ny epic"
msgid "Epics|Add an existing epic"
-msgstr ""
+msgstr "Tilføj en eksisterende epic"
msgid "Epics|An error occurred while saving the %{epicDateType} date"
msgstr ""
@@ -12888,7 +12999,7 @@ msgid "Epics|An error occurred while updating labels."
msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
-msgstr ""
+msgstr "Er du sikker på, at du vil fjerne %{bStart}%{targetIssueTitle}%{bEnd} fra %{bStart}%{parentEpicTitle}%{bEnd}?"
msgid "Epics|Assign Epic"
msgstr ""
@@ -12903,49 +13014,49 @@ msgid "Epics|Leave empty to inherit from milestone dates"
msgstr ""
msgid "Epics|No start date – %{dueDate}"
-msgstr ""
+msgstr "Ingen startdato – %{dueDate}"
msgid "Epics|Remove epic"
-msgstr ""
+msgstr "Fjern epic"
msgid "Epics|Remove issue"
-msgstr ""
+msgstr "Fjern problemstilling"
msgid "Epics|Search epics"
-msgstr ""
+msgstr "Søg efter epics"
msgid "Epics|Select epic"
-msgstr ""
+msgstr "Vælg epic"
msgid "Epics|Show more"
-msgstr ""
+msgstr "Vis mere"
msgid "Epics|Something went wrong while assigning issue to epic."
-msgstr ""
+msgstr "Noget gik galt under tildeling af problemstilling til epic."
msgid "Epics|Something went wrong while creating child epics."
-msgstr ""
+msgstr "Noget gik galt under oprettelse af underepics."
msgid "Epics|Something went wrong while creating issue."
-msgstr ""
+msgstr "Noget gik galt under oprettelse af problemstilling."
msgid "Epics|Something went wrong while fetching child epics."
-msgstr ""
+msgstr "Noget gik galt under hentning af underepics."
msgid "Epics|Something went wrong while fetching epics list."
-msgstr ""
+msgstr "Noget gik galt under hentning af epicsliste."
msgid "Epics|Something went wrong while fetching group epics."
-msgstr ""
+msgstr "Noget gik galt under hentning af gruppeepics."
msgid "Epics|Something went wrong while moving item."
-msgstr ""
+msgstr "Noget gik galt under flytning af element."
msgid "Epics|Something went wrong while ordering item."
-msgstr ""
+msgstr "Noget gik galt under flytning af organisering af element."
msgid "Epics|Something went wrong while removing issue from epic."
-msgstr ""
+msgstr "Noget gik galt under fjernelse af problemstilling fra epic."
msgid "Epics|These dates affect how your epics appear in the roadmap. Dates from milestones come from the milestones assigned to issues in the epic. You can also set fixed dates or remove them entirely."
msgstr ""
@@ -12960,43 +13071,43 @@ msgid "Epics|To schedule your epic's %{epicDateType} date based on milestones, a
msgstr ""
msgid "Epics|Unable to save epic. Please try again"
-msgstr ""
+msgstr "Kan ikke gemme epic. Prøv venligst igen."
msgid "Epics|due"
msgstr ""
msgid "Epics|start"
-msgstr ""
+msgstr "start"
msgid "Error"
-msgstr ""
+msgstr "Fejl"
msgid "Error Details"
-msgstr ""
+msgstr "Fejldetaljer"
msgid "Error Tracking"
-msgstr ""
+msgstr "Fejlsporing"
msgid "Error creating epic"
-msgstr ""
+msgstr "Fejl ved oprettelse af epic"
msgid "Error creating label."
-msgstr ""
+msgstr "Fejl ved oprettelse af etiket."
msgid "Error creating new iteration"
-msgstr ""
+msgstr "Fejl ved oprettelse af nyt gennemløb"
msgid "Error creating repository for snippet with id %{snippet_id}"
-msgstr ""
+msgstr "Fejl ved oprettelse af depot for uddrag med id'et %{snippet_id}"
msgid "Error creating the snippet"
-msgstr ""
+msgstr "Fejl ved oprettelse af uddraget"
msgid "Error deleting %{issuableType}"
-msgstr ""
+msgstr "Fejl ved sletning af %{issuableType}"
msgid "Error deleting project. Check logs for error details."
-msgstr ""
+msgstr "Fejl ved sletning af projekt. Tjek loggene for fejldetaljer."
msgid "Error fetching burnup chart data"
msgstr ""
@@ -13008,10 +13119,10 @@ msgid "Error fetching forked projects. Please try again."
msgstr ""
msgid "Error fetching labels."
-msgstr ""
+msgstr "Fejl ved hentning af etiketter."
msgid "Error fetching network graph."
-msgstr ""
+msgstr "Fejl ved hentning af netværksgraf."
msgid "Error fetching payload data."
msgstr ""
@@ -13026,46 +13137,46 @@ msgid "Error loading branch data. Please try again."
msgstr ""
msgid "Error loading branches."
-msgstr ""
+msgstr "Fejl ved indlæsning af grene."
msgid "Error loading burndown chart data"
msgstr ""
msgid "Error loading countries data."
-msgstr ""
+msgstr "Fejl ved indlæsning af landedata."
msgid "Error loading file viewer."
-msgstr ""
+msgstr "Fejl ved indlæsning af filfremviser."
msgid "Error loading issues"
-msgstr ""
+msgstr "Fejl ved indlæsning af problemstillinger"
msgid "Error loading iterations"
-msgstr ""
+msgstr "Fejl ved indlæsning af gennemløb"
msgid "Error loading last commit."
-msgstr ""
+msgstr "Fejl ved indlæsning af sidste commit."
msgid "Error loading markdown preview"
msgstr ""
msgid "Error loading merge requests."
-msgstr ""
+msgstr "Fejl ved indlæsning af sammenlægningsanmodninger."
msgid "Error loading milestone tab"
msgstr ""
msgid "Error loading project data. Please try again."
-msgstr ""
+msgstr "Fejl ved indlæsning af projektdata. Prøv venligst igen."
msgid "Error loading template types."
-msgstr ""
+msgstr "Fejl ved indlæsning af skabelontyper."
msgid "Error loading template."
-msgstr ""
+msgstr "Fejl ved indlæsning af skabelon."
msgid "Error loading viewer"
-msgstr ""
+msgstr "Fejl ved indlæsning af fremviser"
msgid "Error occurred when fetching sidebar data"
msgstr ""
@@ -13074,7 +13185,7 @@ msgid "Error occurred when saving assignees"
msgstr ""
msgid "Error occurred when saving reviewers"
-msgstr ""
+msgstr "Der opstod en fejl under gemning af kontrollanter"
msgid "Error occurred while updating the %{issuableType} status"
msgstr ""
@@ -13086,16 +13197,16 @@ msgid "Error occurred while updating the issue weight"
msgstr ""
msgid "Error occurred. A blocked user cannot be deactivated"
-msgstr ""
+msgstr "Der opstod en fejl. En blokeret bruger kan ikke deaktiveres"
msgid "Error occurred. A blocked user must be unblocked to be activated"
msgstr ""
msgid "Error occurred. User was not banned"
-msgstr ""
+msgstr "Der opstod en fejl. Brugeren blev ikke udelukket"
msgid "Error occurred. User was not blocked"
-msgstr ""
+msgstr "Der opstod en fejl. Brugeren blev ikke blokeret"
msgid "Error occurred. User was not confirmed"
msgstr ""
@@ -13113,7 +13224,7 @@ msgid "Error parsing CSV file. Please make sure it has"
msgstr ""
msgid "Error rendering markdown preview"
-msgstr ""
+msgstr "Fejl ved gengivelse af markdown-forhåndsvisning"
msgid "Error saving label update."
msgstr ""
@@ -13125,7 +13236,7 @@ msgid "Error tracking"
msgstr ""
msgid "Error updating %{issuableType}"
-msgstr ""
+msgstr "Fejl ved opdatering af %{issuableType}"
msgid "Error updating status for all to-do items."
msgstr ""
@@ -13134,22 +13245,22 @@ msgid "Error updating status of to-do item."
msgstr ""
msgid "Error updating the snippet"
-msgstr ""
+msgstr "Fejl ved opdatering af uddraget"
msgid "Error uploading file"
-msgstr ""
+msgstr "Fejl ved upload af fil"
msgid "Error uploading file. Please try again."
-msgstr ""
+msgstr "Fejl ved upload af fil. Prøv venligst igen."
msgid "Error uploading file: %{stripped}"
-msgstr ""
+msgstr "Fejl ved upload af fil: %{stripped}"
msgid "Error while loading the merge request. Please try again."
-msgstr ""
+msgstr "Fejl ved indlæsning af sammenlægningsanmodningen. Prøv venligst igen."
msgid "Error while loading the project data. Please try again."
-msgstr ""
+msgstr "Fejl ved indlæsning af projektdataene. Prøv venligst igen."
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13158,7 +13269,7 @@ msgid "Error with Akismet. Please check the logs for more info."
msgstr ""
msgid "Error: %{error_message}"
-msgstr ""
+msgstr "Fejl: %{error_message}"
msgid "Error: No AWS credentials were supplied"
msgstr ""
@@ -13167,13 +13278,16 @@ msgid "Error: No AWS provision role found for user"
msgstr ""
msgid "Error: Unable to create deploy freeze"
+msgstr "Fejl: kan ikke oprette udsendelsesfrysning"
+
+msgid "Error: Unable to delete deploy freeze"
msgstr ""
msgid "Error: Unable to find AWS role for current user"
msgstr ""
msgid "ErrorTracking|Active"
-msgstr ""
+msgstr "Aktiv"
msgid "ErrorTracking|After adding your Auth Token, select the Connect button to load projects."
msgstr ""
@@ -13197,19 +13311,19 @@ msgid "ErrorTracking|No projects available"
msgstr ""
msgid "ErrorTracking|Select project"
-msgstr ""
+msgstr "Vælg projekt"
msgid "ErrorTracking|To enable project selection, enter a valid Auth Token."
msgstr ""
msgid "Errors"
-msgstr ""
+msgstr "Fejl"
msgid "Errors found on line %{line_number}: %{error_lines}. Please check if these lines have a requirement title."
msgstr ""
msgid "Errors:"
-msgstr ""
+msgstr "Fejl:"
msgid "Escalation Policies"
msgstr ""
@@ -13242,7 +13356,7 @@ msgid "EscalationPolicies|Add escalation policy"
msgstr ""
msgid "EscalationPolicies|Add policy"
-msgstr ""
+msgstr "Tilføj regelsæt"
msgid "EscalationPolicies|Are you sure you want to delete the \"%{escalationPolicy}\" escalation policy? This action cannot be undone."
msgstr ""
@@ -13287,7 +13401,7 @@ msgid "EscalationPolicies|Remove escalation rule"
msgstr ""
msgid "EscalationPolicies|Search for user"
-msgstr ""
+msgstr "Søg efter bruger"
msgid "EscalationPolicies|Select schedule"
msgstr ""
@@ -13317,13 +13431,13 @@ msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
-msgstr ""
+msgstr "Filtrér efter alle"
msgid "EventFilterBy|Filter by comments"
-msgstr ""
+msgstr "Filtrér efter kommentarer"
msgid "EventFilterBy|Filter by designs"
-msgstr ""
+msgstr "Filtrér efter designs"
msgid "EventFilterBy|Filter by epic events"
msgstr ""
@@ -13338,51 +13452,51 @@ msgid "EventFilterBy|Filter by push events"
msgstr ""
msgid "EventFilterBy|Filter by team"
-msgstr ""
+msgstr "Filtrér efter team"
msgid "EventFilterBy|Filter by wiki"
-msgstr ""
+msgstr "Filtrér efter wiki"
msgid "Events"
-msgstr ""
+msgstr "Begivenheder"
msgid "Every %{action} attempt has failed: %{job_error_message}. Please try again."
msgstr ""
msgid "Every day"
-msgstr ""
+msgstr "Hver dag"
msgid "Every day (at %{time})"
-msgstr ""
+msgstr "Hver dag (kl. %{time})"
msgid "Every month"
-msgstr ""
+msgstr "Hver måned"
msgid "Every month (Day %{day} at %{time})"
-msgstr ""
+msgstr "Hver måned (dag %{day} kl. %{time})"
msgid "Every three months"
-msgstr ""
+msgstr "Hver tredje måned"
msgid "Every two weeks"
-msgstr ""
+msgstr "Hver anden uge"
msgid "Every week"
msgid_plural "Every %d weeks"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Hver uge"
+msgstr[1] "Hver %d. uge"
msgid "Every week (%{weekday} at %{time})"
-msgstr ""
+msgstr "Hver uge (%{weekday} kl. %{time})"
msgid "Everyone"
-msgstr ""
+msgstr "Alle"
msgid "Everyone With Access"
-msgstr ""
+msgstr "Alle med adgang"
msgid "Everyone can contribute"
-msgstr ""
+msgstr "Alle kan bidrage"
msgid "Everything on your to-do list is marked as done."
msgstr ""
@@ -13412,10 +13526,10 @@ msgid "Exactly one of %{attributes} is required"
msgstr ""
msgid "Example: %{ip_address}. %{read_more_link}."
-msgstr ""
+msgstr "Eksempel: %{ip_address}. %{read_more_link}."
msgid "Example: @sub\\.company\\.com$"
-msgstr ""
+msgstr "Eksempel: @sub\\.company\\.com$"
msgid "Example: Usage = single query. (Requested) / (Capacity) = multiple queries combined into a formula."
msgstr ""
@@ -13424,7 +13538,7 @@ msgid "Except policy:"
msgstr ""
msgid "Exceptions"
-msgstr ""
+msgstr "Undtagelser"
msgid "Excess storage"
msgstr ""
@@ -13460,7 +13574,7 @@ msgid "Expand all files"
msgstr ""
msgid "Expand all threads"
-msgstr ""
+msgstr "Udfold alle tråde"
msgid "Expand approvers"
msgstr ""
@@ -13475,13 +13589,13 @@ msgid "Expand milestones"
msgstr ""
msgid "Expand panel"
-msgstr ""
+msgstr "Udfold panel"
msgid "Expand pipeline"
msgstr ""
msgid "Expand sidebar"
-msgstr ""
+msgstr "Udfold sidebjælke"
msgid "Expected documents: %{expected_documents}"
msgstr ""
@@ -13493,73 +13607,73 @@ msgid "ExperimentSubject|Must have exactly one of User, Namespace, or Project."
msgstr ""
msgid "Expiration"
-msgstr ""
+msgstr "Udløb"
msgid "Expiration date"
-msgstr ""
+msgstr "Udløbsdato"
msgid "Expiration date (optional)"
-msgstr ""
+msgstr "Udløbsdato (valgfrit)"
msgid "Expired"
-msgstr ""
+msgstr "Udløbet"
msgid "Expired %{expiredOn}"
-msgstr ""
+msgstr "Udløbet %{expiredOn}"
msgid "Expired:"
msgstr ""
msgid "Expires"
-msgstr ""
+msgstr "Udløber"
msgid "Expires in %{expires_at}"
-msgstr ""
+msgstr "Udløber om %{expires_at}"
msgid "Expires:"
-msgstr ""
+msgstr "Udløber:"
msgid "Explain the problem. If appropriate, provide a link to the relevant issue or comment."
msgstr ""
msgid "Explore"
-msgstr ""
+msgstr "Udforsk"
msgid "Explore GitLab"
-msgstr ""
+msgstr "Udforsk GitLab"
msgid "Explore Groups"
-msgstr ""
+msgstr "Udforsk grupper"
msgid "Explore groups"
-msgstr ""
+msgstr "Udforsk grupper"
msgid "Explore projects"
-msgstr ""
+msgstr "Udforsk projekter"
msgid "Explore public groups"
-msgstr ""
+msgstr "Udforsk offentlige grupper"
msgid "Export"
msgstr ""
msgid "Export %{name}"
-msgstr ""
+msgstr "Eksportér %{name}"
msgid "Export %{requirementsCount} requirements?"
msgstr ""
msgid "Export as CSV"
-msgstr ""
+msgstr "Eksportér som CSV"
msgid "Export commit custody report"
msgstr ""
msgid "Export group"
-msgstr ""
+msgstr "Eksportér gruppe"
msgid "Export project"
-msgstr ""
+msgstr "Eksportér projekt"
msgid "Export requirements"
msgstr ""
@@ -13580,13 +13694,13 @@ msgid "External Classification Policy Authorization"
msgstr ""
msgid "External ID"
-msgstr ""
+msgstr "Eksternt id"
msgid "External URL"
-msgstr ""
+msgstr "Ekstern URL"
msgid "External User:"
-msgstr ""
+msgstr "Ekstern bruger:"
msgid "External authentication"
msgstr ""
@@ -13622,25 +13736,25 @@ msgid "ExternalWikiService|Link to an external wiki from the sidebar."
msgstr ""
msgid "ExternalWikiService|https://example.com/xxx/wiki/..."
-msgstr ""
+msgstr "https://example.com/xxx/wiki/..."
msgid "Facebook"
-msgstr ""
+msgstr "Facebook"
msgid "Failed"
-msgstr ""
+msgstr "Mislykkedes"
msgid "Failed Jobs"
-msgstr ""
+msgstr "Mislykkede job"
msgid "Failed on"
msgstr ""
msgid "Failed to add a Zoom meeting"
-msgstr ""
+msgstr "Kunne ikke tilføje et Zoom-møde"
msgid "Failed to apply commands."
-msgstr ""
+msgstr "Kunne ikke anvende kommandoer."
msgid "Failed to assign a reviewer because no user was found."
msgstr ""
@@ -13658,7 +13772,7 @@ msgid "Failed to cancel auto stop because you do not have permission to update t
msgstr ""
msgid "Failed to change the owner"
-msgstr ""
+msgstr "Kunne ikke ændre ejeren"
msgid "Failed to check related branches."
msgstr ""
@@ -13688,13 +13802,13 @@ msgid "Failed to create new project access token: %{token_response_message}"
msgstr ""
msgid "Failed to create repository"
-msgstr ""
+msgstr "Kunne ikke oprette depot"
msgid "Failed to create resources"
-msgstr ""
+msgstr "Kunne ikke oprette ressourcer"
msgid "Failed to create wiki"
-msgstr ""
+msgstr "Kunne ikke oprette wiki"
msgid "Failed to deploy to"
msgstr ""
@@ -13721,7 +13835,7 @@ msgid "Failed to get ref."
msgstr ""
msgid "Failed to install."
-msgstr ""
+msgstr "Kunne ikke installere."
msgid "Failed to load assignees."
msgstr ""
@@ -13730,19 +13844,19 @@ msgid "Failed to load assignees. Please try again."
msgstr ""
msgid "Failed to load authors. Please try again."
-msgstr ""
+msgstr "Kunne ikke indlæse forfattere. Prøv venligst igen."
msgid "Failed to load branches. Please try again."
-msgstr ""
+msgstr "Kunne ikke indlæse grene. Prøv venligst igen."
msgid "Failed to load deploy keys."
msgstr ""
msgid "Failed to load emoji list."
-msgstr ""
+msgstr "Kunne ikke indlæse emojiliste."
msgid "Failed to load error details from Sentry."
-msgstr ""
+msgstr "Kunne ikke indlæse fejldetaljer fra Sentry."
msgid "Failed to load errors from Sentry."
msgstr ""
@@ -13754,19 +13868,19 @@ msgid "Failed to load groups, users and deploy keys."
msgstr ""
msgid "Failed to load iterations."
-msgstr ""
+msgstr "Kunne ikke indlæse gennemløb."
msgid "Failed to load labels. Please try again."
-msgstr ""
+msgstr "Kunne ikke indlæse etiketter. Prøv venligst igen."
msgid "Failed to load milestones."
msgstr ""
msgid "Failed to load milestones. Please try again."
-msgstr ""
+msgstr "Kunne ikke indlæse milepæle. Prøv venligst igen."
msgid "Failed to load projects"
-msgstr ""
+msgstr "Kunne ikke indlæse projekter"
msgid "Failed to load related branches"
msgstr ""
@@ -13793,13 +13907,13 @@ msgid "Failed to move this issue because target project doesn't exist."
msgstr ""
msgid "Failed to promote label due to internal error. Please contact administrators."
-msgstr ""
+msgstr "Kunne ikke promovere etiket på grund af intern fejl. Kontakt venligst administratorer."
msgid "Failed to protect the branch"
msgstr ""
msgid "Failed to protect the environment"
-msgstr ""
+msgstr "Kunne ikke beskytte miljøet"
msgid "Failed to publish issue on status page."
msgstr ""
@@ -13808,7 +13922,7 @@ msgid "Failed to register Agent"
msgstr ""
msgid "Failed to remove a Zoom meeting"
-msgstr ""
+msgstr "Kunne ikke fjerne et Zoom-møde"
msgid "Failed to remove a to-do item for the design."
msgstr ""
@@ -13820,28 +13934,28 @@ msgid "Failed to remove the pipeline schedule"
msgstr ""
msgid "Failed to remove user identity."
-msgstr ""
+msgstr "Kunne ikke fjerne brugeridentitet."
msgid "Failed to remove user key."
-msgstr ""
+msgstr "Kunne ikke fjerne brugernøgle."
msgid "Failed to reset key. Please try again."
-msgstr ""
+msgstr "Kunne ikke nulstille nøgle. Prøv venligst igen."
msgid "Failed to retrieve page"
msgstr ""
msgid "Failed to save merge conflicts resolutions. Please try again!"
-msgstr ""
+msgstr "Kunne ikke gemme konfliktløsninger. Prøv venligst igen!"
msgid "Failed to save new settings"
-msgstr ""
+msgstr "Kunne ikke gemme nye indstillinger"
msgid "Failed to save preferences (%{error_message})."
-msgstr ""
+msgstr "Kunne ikke gemme præferencer (%{error_message})."
msgid "Failed to save preferences."
-msgstr ""
+msgstr "Kunne ikke gemme præferencer."
msgid "Failed to set due date because the date format is invalid."
msgstr ""
@@ -13856,25 +13970,25 @@ msgid "Failed to toggle the to-do status for the design."
msgstr ""
msgid "Failed to update branch!"
-msgstr ""
+msgstr "Kunne ikke opdatere gren!"
msgid "Failed to update environment!"
-msgstr ""
+msgstr "Kunne ikke opdatere miljøet!"
msgid "Failed to update framework"
-msgstr ""
+msgstr "Kunne ikke opdatere framework"
msgid "Failed to update issue status"
-msgstr ""
+msgstr "Kunne ikke opdatere problemstillingsstatus"
msgid "Failed to update the Canary Ingress."
msgstr ""
msgid "Failed to update."
-msgstr ""
+msgstr "Kunne ikke opdatere."
msgid "Failed to upgrade."
-msgstr ""
+msgstr "Kunne ikke opgradere."
msgid "Failed to upload object map file"
msgstr ""
@@ -13883,13 +13997,13 @@ msgid "Failed to verify domain ownership"
msgstr ""
msgid "Failure"
-msgstr ""
+msgstr "Mislykkedes"
msgid "False positive"
-msgstr ""
+msgstr "Falsk positiv"
msgid "Fast timeout"
-msgstr ""
+msgstr "Hurtig timeout"
msgid "Fast-forward merge without a merge commit"
msgstr ""
@@ -13898,30 +14012,30 @@ msgid "Faster releases. Better code. Less pain."
msgstr ""
msgid "Favicon"
-msgstr ""
+msgstr "Favicon"
msgid "Favicon was successfully removed."
-msgstr ""
+msgstr "Favicon blev fjernet."
msgid "Favicon will be removed. Are you sure?"
-msgstr ""
+msgstr "Favicon fjernes. Er du sikker?"
msgid "Feature Flags"
-msgstr ""
+msgstr "Funktionsflag"
msgid "Feature flag status"
-msgstr ""
+msgstr "Status for funktionsflag"
msgid "Feature flag was not removed."
-msgstr ""
+msgstr "Funktionsflaget blev ikke fjernet."
msgid "Feature flag was successfully removed."
-msgstr ""
+msgstr "Funktionsflaget blev fjernet."
msgid "FeatureFlags|%d user"
msgid_plural "FeatureFlags|%d users"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d bruger"
+msgstr[1] "%d brugere"
msgid "FeatureFlags|%{percent} by available ID"
msgstr ""
@@ -13930,58 +14044,58 @@ msgid "FeatureFlags|%{percent} by session ID"
msgstr ""
msgid "FeatureFlags|%{percent} by user ID"
-msgstr ""
+msgstr "%{percent} af bruger-id"
msgid "FeatureFlags|%{percent} randomly"
msgstr ""
msgid "FeatureFlags|* (All Environments)"
-msgstr ""
+msgstr "* (alle miljøer)"
msgid "FeatureFlags|API URL"
msgstr ""
msgid "FeatureFlags|Active"
-msgstr ""
+msgstr "Aktiv"
msgid "FeatureFlags|Add strategy"
-msgstr ""
+msgstr "Tilføj strategi"
msgid "FeatureFlags|All Environments"
-msgstr ""
+msgstr "Alle miljøer"
msgid "FeatureFlags|All Users"
-msgstr ""
+msgstr "Alle brugere"
msgid "FeatureFlags|All users"
-msgstr ""
+msgstr "Alle brugere"
msgid "FeatureFlags|Configure"
-msgstr ""
+msgstr "Konfigurer"
msgid "FeatureFlags|Configure feature flags"
-msgstr ""
+msgstr "Konfigurer funktionsflag"
msgid "FeatureFlags|Consider using the more flexible \"Percent rollout\" strategy instead."
msgstr ""
msgid "FeatureFlags|Create feature flag"
-msgstr ""
+msgstr "Opret funktionsflag"
msgid "FeatureFlags|Delete %{name}?"
-msgstr ""
+msgstr "Slet %{name}?"
msgid "FeatureFlags|Delete feature flag"
-msgstr ""
+msgstr "Slet funktionsflag"
msgid "FeatureFlags|Description"
-msgstr ""
+msgstr "Beskrivelse"
msgid "FeatureFlags|Edit Feature Flag"
-msgstr ""
+msgstr "Rediger funktionsflag"
msgid "FeatureFlags|Edit User List"
-msgstr ""
+msgstr "Rediger brugerliste"
msgid "FeatureFlags|Enable features for specific users and environments by configuring feature flag strategies."
msgstr ""
@@ -13990,7 +14104,7 @@ msgid "FeatureFlags|Environment Specs"
msgstr ""
msgid "FeatureFlags|Feature Flag"
-msgstr ""
+msgstr "Funktionsflag"
msgid "FeatureFlags|Feature Flag User List Details"
msgstr ""
@@ -14005,10 +14119,10 @@ msgid "FeatureFlags|Feature Flag has no strategies"
msgstr ""
msgid "FeatureFlags|Feature Flags"
-msgstr ""
+msgstr "Funktionsflag"
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
-msgstr ""
+msgstr "Funktionsflaget %{name} fjernes. Er du sikker?"
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
@@ -14020,49 +14134,49 @@ msgid "FeatureFlags|Get started with feature flags"
msgstr ""
msgid "FeatureFlags|ID"
-msgstr ""
+msgstr "Id"
msgid "FeatureFlags|Inactive"
msgstr ""
msgid "FeatureFlags|Inactive flag for %{scope}"
-msgstr ""
+msgstr "Inaktivt flag for %{scope}"
msgid "FeatureFlags|Install a %{docsLinkAnchoredStart}compatible client library%{docsLinkAnchoredEnd} and specify the API URL, application name, and instance ID during the configuration setup. %{docsLinkStart}More Information%{docsLinkEnd}"
msgstr ""
msgid "FeatureFlags|Instance ID"
-msgstr ""
+msgstr "Instans-id"
msgid "FeatureFlags|List details"
msgstr ""
msgid "FeatureFlags|Loading feature flags"
-msgstr ""
+msgstr "Indlæser funktionsflag"
msgid "FeatureFlags|More information"
-msgstr ""
+msgstr "Mere information"
msgid "FeatureFlags|Name"
-msgstr ""
+msgstr "Navn"
msgid "FeatureFlags|New"
-msgstr ""
+msgstr "Nyt"
msgid "FeatureFlags|New Feature Flag"
-msgstr ""
+msgstr "Nyt funktionsflag"
msgid "FeatureFlags|New User List"
-msgstr ""
+msgstr "Ny brugerliste"
msgid "FeatureFlags|New feature flag"
-msgstr ""
+msgstr "Nyt funktionsflag"
msgid "FeatureFlags|No user list selected"
msgstr ""
msgid "FeatureFlags|Percent of users"
-msgstr ""
+msgstr "Procent brugere"
msgid "FeatureFlags|Percent rollout"
msgstr ""
@@ -14071,19 +14185,19 @@ msgid "FeatureFlags|Percent rollout must be an integer number between 0 and 100"
msgstr ""
msgid "FeatureFlags|Remove"
-msgstr ""
+msgstr "Fjern"
msgid "FeatureFlags|Set the Unleash client application name to the name of the environment your application runs in. This value is used to match environment scopes. See the %{linkStart}example client configuration%{linkEnd}."
msgstr ""
msgid "FeatureFlags|Status"
-msgstr ""
+msgstr "Status"
msgid "FeatureFlags|Strategies"
-msgstr ""
+msgstr "Strategier"
msgid "FeatureFlags|There was an error fetching the feature flags."
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af funktionsflagene."
msgid "FeatureFlags|To prevent accidental actions we ask you to confirm your intention. Please type %{projectName} to proceed or close this modal to cancel."
msgstr ""
@@ -14092,37 +14206,37 @@ msgid "FeatureFlags|Try again in a few moments or contact your support team."
msgstr ""
msgid "FeatureFlags|User IDs"
-msgstr ""
+msgstr "Bruger-id'er"
msgid "FeatureFlags|User List"
-msgstr ""
+msgstr "Brugerliste"
msgid "FeatureFlags|User Lists"
-msgstr ""
+msgstr "Brugerlister"
msgid "FeatureFlags|View user lists"
-msgstr ""
+msgstr "Vis brugerlister"
msgid "FeatureFlag|Percentage"
-msgstr ""
+msgstr "Procent"
msgid "FeatureFlag|Select a user list"
-msgstr ""
+msgstr "Vælg en brugerliste"
msgid "FeatureFlag|Select the environment scope for this feature flag"
-msgstr ""
+msgstr "Vælg miljøomfanget for funktionsflaget"
msgid "FeatureFlag|There are no configured user lists"
-msgstr ""
+msgstr "Der er ingen konfigurerede brugerlister"
msgid "FeatureFlag|Type"
-msgstr ""
+msgstr "Type"
msgid "FeatureFlag|User IDs"
-msgstr ""
+msgstr "Bruger-id'er"
msgid "FeatureFlag|User List"
-msgstr ""
+msgstr "Brugerliste"
msgid "FeatureHighlight|%{daysRemaining} day remaining to enjoy %{featureName}"
msgid_plural "FeatureHighlight|%{daysRemaining} days remaining to enjoy %{featureName}"
@@ -14133,10 +14247,10 @@ msgid "FeatureHighlight|Enjoying your GitLab %{planNameForTrial} trial? To conti
msgstr ""
msgid "Feb"
-msgstr ""
+msgstr "Feb."
msgid "February"
-msgstr ""
+msgstr "Februar"
msgid "Fetch and check out the branch for this merge request"
msgstr ""
@@ -14145,25 +14259,25 @@ msgid "Fetching incoming email"
msgstr ""
msgid "File"
-msgstr ""
+msgstr "Fil"
msgid "File %{current} of %{total}"
-msgstr ""
+msgstr "Fil %{current} af %{total}"
msgid "File Hooks"
-msgstr ""
+msgstr "Filhooks"
msgid "File Hooks (%{count})"
-msgstr ""
+msgstr "Filhooks (%{count})"
msgid "File added"
-msgstr ""
+msgstr "Fil tilføjet"
msgid "File browser"
-msgstr ""
+msgstr "Filvælger"
msgid "File deleted"
-msgstr ""
+msgstr "Fil slettet"
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -14172,13 +14286,13 @@ msgid "File mode changed from %{a_mode} to %{b_mode}"
msgstr ""
msgid "File moved"
-msgstr ""
+msgstr "Fil flyttet"
msgid "File name"
-msgstr ""
+msgstr "Filnavn"
msgid "File renamed with no changes."
-msgstr ""
+msgstr "Fil omdøbt uden ændringer."
msgid "File suppressed by a .gitattributes entry or the file's encoding is unsupported."
msgstr ""
@@ -14187,22 +14301,22 @@ msgid "File synchronization concurrency limit"
msgstr ""
msgid "File templates"
-msgstr ""
+msgstr "Filskabeloner"
msgid "File upload error."
-msgstr ""
+msgstr "Fejl ved upload af fil."
msgid "Filename"
-msgstr ""
+msgstr "Filnavn"
msgid "Files"
-msgstr ""
+msgstr "Filer"
msgid "Files breadcrumb"
msgstr ""
msgid "Files with large changes are collapsed by default."
-msgstr ""
+msgstr "Filer med store ændringer er sammenfoldet som standard."
msgid "Files, directories, and submodules in the path %{path} for commit reference %{ref}"
msgstr ""
@@ -14214,7 +14328,7 @@ msgid "Filter"
msgstr ""
msgid "Filter by"
-msgstr ""
+msgstr "Filtrér efter"
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
@@ -14226,7 +14340,7 @@ msgid "Filter by %{page_context_word} that are currently open."
msgstr ""
msgid "Filter by Git revision"
-msgstr ""
+msgstr "Filtrér efter Git-revision"
msgid "Filter by issues that are currently closed."
msgstr ""
@@ -14235,7 +14349,7 @@ msgid "Filter by issues that are currently opened."
msgstr ""
msgid "Filter by label"
-msgstr ""
+msgstr "Filtrér efter etiket"
msgid "Filter by merge requests that are currently closed and unmerged."
msgstr ""
@@ -14247,7 +14361,7 @@ msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
-msgstr ""
+msgstr "Filtrér efter navn"
msgid "Filter by test cases that are currently archived."
msgstr ""
@@ -14256,10 +14370,10 @@ msgid "Filter by test cases that are currently open."
msgstr ""
msgid "Filter by two-factor authentication"
-msgstr ""
+msgstr "Filtrér efter tofaktorgodkendelse"
msgid "Filter by user"
-msgstr ""
+msgstr "Filtrér efter bruger"
msgid "Filter parameters are not valid. Make sure that the end date is after the start date."
msgstr ""
@@ -14268,28 +14382,28 @@ msgid "Filter pipelines"
msgstr ""
msgid "Filter results"
-msgstr ""
+msgstr "Filtrér resultater"
msgid "Filter results by group"
-msgstr ""
+msgstr "Filtrér resultater efter gruppe"
msgid "Filter results by project"
-msgstr ""
+msgstr "Filtrér resultater efter projekt"
msgid "Filter results..."
-msgstr ""
+msgstr "Filtrér resultater ..."
msgid "Filter users"
-msgstr ""
+msgstr "Filtrér brugere"
msgid "Filter your repositories by name"
-msgstr ""
+msgstr "Filtrér dine depoter efter navn"
msgid "Filter..."
msgstr ""
msgid "Find File"
-msgstr ""
+msgstr "Find fil"
msgid "Find bugs in your code with API fuzzing."
msgstr ""
@@ -14298,16 +14412,16 @@ msgid "Find bugs in your code with coverage-guided fuzzing."
msgstr ""
msgid "Find by path"
-msgstr ""
+msgstr "Find efter sti"
msgid "Find file"
-msgstr ""
+msgstr "Find fil"
msgid "Fingerprint"
-msgstr ""
+msgstr "Fingeraftryk"
msgid "Fingerprints"
-msgstr ""
+msgstr "Fingeraftryk"
msgid "Finish editing this message first!"
msgstr ""
@@ -14322,43 +14436,43 @@ msgid "Finished at"
msgstr ""
msgid "First Seen"
-msgstr ""
+msgstr "Først set"
msgid "First day of the week"
-msgstr ""
+msgstr "Første dag i ugen"
msgid "First name"
-msgstr ""
+msgstr "Fornavn"
msgid "First seen"
-msgstr ""
+msgstr "Først set"
msgid "Fixed burndown chart"
msgstr ""
msgid "Fixed date"
-msgstr ""
+msgstr "Fast dato"
msgid "Fixed due date"
-msgstr ""
+msgstr "Fast forfaldsdato"
msgid "Fixed start date"
-msgstr ""
+msgstr "Fast startdato"
msgid "Fixed:"
-msgstr ""
+msgstr "Fast:"
msgid "Flags"
-msgstr ""
+msgstr "Flag"
msgid "FloC|Configure whether you want to participate in FloC."
msgstr ""
msgid "FloC|Enable FloC (Federated Learning of Cohorts)"
-msgstr ""
+msgstr "Aktivér FloC (Federated Learning of Cohorts)"
msgid "FloC|Federated Learning of Cohorts"
-msgstr ""
+msgstr "Federated Learning of Cohorts"
msgid "FlowdockService|1b609b52537..."
msgstr ""
@@ -14370,7 +14484,7 @@ msgid "FlowdockService|Send event notifications from GitLab to Flowdock flows. %
msgstr ""
msgid "Focus filter bar"
-msgstr ""
+msgstr "Flyt fokus til filterlinje"
msgid "FogBugz Email"
msgstr ""
@@ -14382,25 +14496,25 @@ msgid "FogBugz Password"
msgstr ""
msgid "FogBugz URL"
-msgstr ""
+msgstr "FogBugz-URL"
msgid "FogBugz import"
msgstr ""
msgid "Folder/%{name}"
-msgstr ""
+msgstr "Mappe/%{name}"
msgid "Follow"
-msgstr ""
+msgstr "Følg"
msgid "Followed Users' Activity"
msgstr ""
msgid "Followed users"
-msgstr ""
+msgstr "Fulgte brugere"
msgid "Font Color"
-msgstr ""
+msgstr "Skriftfarve"
msgid "Footer message"
msgstr ""
@@ -14433,13 +14547,13 @@ msgid "For investigating IT service disruptions or outages"
msgstr ""
msgid "For more info, read the documentation."
-msgstr ""
+msgstr "Læs dokumentationen, for mere information."
msgid "For more information on how the number of active users is calculated, see the %{self_managed_subscriptions_doc_link} documentation."
msgstr ""
msgid "For more information, go to the "
-msgstr ""
+msgstr "For mere information, gå til "
msgid "For more information, see the File Hooks documentation."
msgstr ""
@@ -14448,31 +14562,31 @@ msgid "For more information, see the documentation on %{deactivating_service_pin
msgstr ""
msgid "Forgot your password?"
-msgstr ""
+msgstr "Glemt din adgangskode?"
msgid "Fork"
msgstr ""
msgid "Fork Error!"
-msgstr ""
+msgstr "Fejl ved forgrening!"
msgid "Fork project"
-msgstr ""
+msgstr "Forgren projekt"
msgid "Fork project?"
-msgstr ""
+msgstr "Forgren projekt?"
msgid "ForkProject|A fork is a copy of a project."
-msgstr ""
+msgstr "En forgrening er en kopi af et projekt."
msgid "ForkProject|An error occurred while forking the project. Please try again."
msgstr ""
msgid "ForkProject|Cancel"
-msgstr ""
+msgstr "Annuller"
msgid "ForkProject|Create a group"
-msgstr ""
+msgstr "Opret en gruppe"
msgid "ForkProject|Fork project"
msgstr ""
@@ -14490,16 +14604,16 @@ msgid "ForkProject|Please select a visibility level"
msgstr ""
msgid "ForkProject|Private"
-msgstr ""
+msgstr "Privat"
msgid "ForkProject|Project access must be granted explicitly to each user. If this project is part of a group, access will be granted to members of the group."
msgstr ""
msgid "ForkProject|Public"
-msgstr ""
+msgstr "Offentlig"
msgid "ForkProject|Select a namespace"
-msgstr ""
+msgstr "Vælg et navnerum"
msgid "ForkProject|Select a namespace to fork the project"
msgstr ""
@@ -14511,13 +14625,13 @@ msgid "ForkProject|The project can be accessed without any authentication."
msgstr ""
msgid "ForkProject|Visibility level"
-msgstr ""
+msgstr "Synlighedsniveau"
msgid "ForkProject|Want to house several dependent projects under the same namespace?"
msgstr ""
msgid "ForkSuggestion|Cancel"
-msgstr ""
+msgstr "Annuller"
msgid "ForkSuggestion|Fork"
msgstr ""
@@ -14526,31 +14640,34 @@ msgid "ForkSuggestion|You can’t %{edit_start}edit%{edit_end} files directly in
msgstr ""
msgid "ForkedFromProjectPath|Forked from"
-msgstr ""
+msgstr "Forgrenet fra"
msgid "ForkedFromProjectPath|Forked from an inaccessible project"
msgstr ""
msgid "Forking in progress"
-msgstr ""
+msgstr "Igangværende forgrening"
msgid "Forks"
-msgstr ""
+msgstr "Forgreninger"
msgid "Format: %{dateFormat}"
+msgstr "Format: %{dateFormat}"
+
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
msgstr ""
msgid "Found errors in your %{gitlab_ci_yml}:"
-msgstr ""
+msgstr "Fandt fejl i din %{gitlab_ci_yml}:"
msgid "Found errors in your .gitlab-ci.yml:"
-msgstr ""
+msgstr "Fandt fejl i din .gitlab-ci.yml:"
msgid "Framework successfully deleted"
msgstr ""
msgid "Free Trial of GitLab.com Ultimate"
-msgstr ""
+msgstr "Gratis prøveperiode af GitLab.com Ultimate"
msgid "Freeze end"
msgstr ""
@@ -14559,22 +14676,22 @@ msgid "Freeze start"
msgstr ""
msgid "Frequency"
-msgstr ""
+msgstr "Hyppighed"
msgid "Frequently searched"
msgstr ""
msgid "Friday"
-msgstr ""
+msgstr "Fredag"
msgid "From"
-msgstr ""
+msgstr "Fra"
msgid "From %{code_open}%{source_title}%{code_close} into"
msgstr ""
msgid "From %{providerTitle}"
-msgstr ""
+msgstr "Fra %{providerTitle}"
msgid "From issue creation until deploy to production"
msgstr ""
@@ -14586,13 +14703,13 @@ msgid "Full"
msgstr ""
msgid "Full name"
-msgstr ""
+msgstr "Fulde navn"
msgid "GPG Key ID:"
msgstr ""
msgid "GPG Keys"
-msgstr ""
+msgstr "GPG-nøgler"
msgid "GPG keys allow you to verify signed commits."
msgstr ""
@@ -14601,25 +14718,25 @@ msgid "GPG signature (loading...)"
msgstr ""
msgid "General"
-msgstr ""
+msgstr "Generelt"
msgid "General Settings"
-msgstr ""
+msgstr "Generelle indstillinger"
msgid "General pipelines"
-msgstr ""
+msgstr "Generelle pipelines"
msgid "Generate a default set of labels"
msgstr ""
msgid "Generate key"
-msgstr ""
+msgstr "Generer nøgle"
msgid "Generate new export"
msgstr ""
msgid "Generate new token"
-msgstr ""
+msgstr "Generer ny token"
msgid "Generate project access tokens scoped to this project for your applications that need access to the GitLab API."
msgstr ""
@@ -14627,23 +14744,26 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
-msgid "Generic package file size in bytes"
+msgid "Generic"
msgstr ""
+msgid "Generic package file size in bytes"
+msgstr "Maksimale filstørrelse for generisk pakke i byte"
+
msgid "GenericReport|After"
-msgstr ""
+msgstr "Efter"
msgid "GenericReport|Before"
-msgstr ""
+msgstr "Før"
msgid "GenericReport|Diff"
msgstr ""
msgid "Geo"
-msgstr ""
+msgstr "Geo"
msgid "Geo Nodes"
-msgstr ""
+msgstr "Geo-knudepunkter"
msgid "Geo Replication"
msgstr ""
@@ -14661,10 +14781,10 @@ msgid "Geo|%{component} verified"
msgstr ""
msgid "Geo|%{label} can't be blank"
-msgstr ""
+msgstr "%{label} må ikke være tomt"
msgid "Geo|%{label} should be between 1-999"
-msgstr ""
+msgstr "%{label} skal være fra 1 til 999"
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -14682,7 +14802,7 @@ msgid "Geo|%{title} checksum progress"
msgstr ""
msgid "Geo|(%{timeAgo})"
-msgstr ""
+msgstr "(%{timeAgo})"
msgid "Geo|Add site"
msgstr ""
@@ -14691,10 +14811,10 @@ msgid "Geo|Adjust your filters/search criteria above. If you believe this may be
msgstr ""
msgid "Geo|All %{replicable_name}"
-msgstr ""
+msgstr "Alle %{replicable_name}"
msgid "Geo|All projects"
-msgstr ""
+msgstr "Alle projekter"
msgid "Geo|All projects are being scheduled for resync"
msgstr ""
@@ -14736,10 +14856,10 @@ msgid "Geo|Data replication lag"
msgstr ""
msgid "Geo|Data type"
-msgstr ""
+msgstr "Datatype"
msgid "Geo|Disabled"
-msgstr ""
+msgstr "Deaktiveret"
msgid "Geo|Discover GitLab Geo"
msgstr ""
@@ -14748,21 +14868,21 @@ msgid "Geo|Does not match the primary storage configuration"
msgstr ""
msgid "Geo|Failed"
-msgstr ""
+msgstr "Mislykkedes"
msgid "Geo|Filter by name"
-msgstr ""
+msgstr "Filtrér efter navn"
msgid "Geo|Filter by status"
-msgstr ""
+msgstr "Filtrér efter status"
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14772,13 +14892,13 @@ msgid "Geo|Go to the primary site"
msgstr ""
msgid "Geo|Healthy"
-msgstr ""
+msgstr "Sund"
msgid "Geo|If you want to make changes, you must visit the primary site."
msgstr ""
msgid "Geo|In progress"
-msgstr ""
+msgstr "I gang"
msgid "Geo|In sync"
msgstr ""
@@ -14805,16 +14925,16 @@ msgid "Geo|Last time verified"
msgstr ""
msgid "Geo|Learn more about Geo"
-msgstr ""
+msgstr "Lær mere om Geo"
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
msgstr ""
msgid "Geo|Never"
-msgstr ""
+msgstr "Aldrig"
msgid "Geo|Next sync scheduled at"
msgstr ""
@@ -14828,38 +14948,35 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
-msgstr ""
+msgstr "Ikke synkroniseret endnu"
msgid "Geo|Nothing to checksum"
msgstr ""
msgid "Geo|Nothing to synchronize"
-msgstr ""
+msgstr "Intet at synkronisere"
msgid "Geo|Nothing to verify"
msgstr ""
msgid "Geo|Offline"
-msgstr ""
+msgstr "Offline"
msgid "Geo|Pending synchronization"
-msgstr ""
+msgstr "Afventende synkronisering"
msgid "Geo|Pending verification"
msgstr ""
msgid "Geo|Primary node"
-msgstr ""
+msgstr "Primære knudepunkt"
msgid "Geo|Primary site"
msgstr ""
msgid "Geo|Project"
-msgstr ""
+msgstr "Projekt"
msgid "Geo|Project (ID: %{project_id}) no longer exists on the primary. It is safe to remove this entry, as this will not remove any data on disk."
msgstr ""
@@ -14871,33 +14988,30 @@ msgid "Geo|Projects in certain storage shards"
msgstr ""
msgid "Geo|Queued"
-msgstr ""
+msgstr "Sat i kø"
msgid "Geo|Redownload"
-msgstr ""
+msgstr "Download igen"
msgid "Geo|Remove"
-msgstr ""
+msgstr "Fjern"
msgid "Geo|Remove entry"
msgstr ""
msgid "Geo|Remove node"
-msgstr ""
-
-msgid "Geo|Remove secondary node"
-msgstr ""
+msgstr "Fjern knudepunkt"
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14919,16 +15033,16 @@ msgid "Geo|Replication summary"
msgstr ""
msgid "Geo|Resync"
-msgstr ""
+msgstr "Synkroniser igen"
msgid "Geo|Resync all"
-msgstr ""
+msgstr "Synkroniser alle igen"
msgid "Geo|Resync all %{replicableType}"
-msgstr ""
+msgstr "Synkroniser alle %{replicableType} igen"
msgid "Geo|Resync all projects"
-msgstr ""
+msgstr "Synkroniser alle projekter igen"
msgid "Geo|Retry count"
msgstr ""
@@ -14942,11 +15056,11 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
-msgstr ""
+msgstr "Sekundære knudepunkt"
msgid "Geo|Secondary site"
msgstr ""
@@ -14954,23 +15068,26 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
-msgid "Geo|Status"
+msgid "Geo|Site's status was updated %{timeAgo}."
msgstr ""
+msgid "Geo|Status"
+msgstr "Status"
+
msgid "Geo|Storage config"
msgstr ""
msgid "Geo|Synced"
-msgstr ""
+msgstr "Synkroniseret"
msgid "Geo|Synced at"
msgstr ""
msgid "Geo|Synchronization"
-msgstr ""
+msgstr "Synkronisering"
msgid "Geo|Synchronization failed - %{error}"
-msgstr ""
+msgstr "Synkronisering mislykkedes - %{error}"
msgid "Geo|Synchronization settings"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15012,25 +15129,25 @@ msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
msgid "Geo|URL can't be blank"
-msgstr ""
+msgstr "URL'en må ikke være tom"
msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
-msgstr ""
+msgstr "URL'en skal være en gyldig URL (f.eks.: https://gitlab.com)"
msgid "Geo|Undefined"
-msgstr ""
+msgstr "Udefineret"
msgid "Geo|Unhealthy"
msgstr ""
msgid "Geo|Unknown"
-msgstr ""
+msgstr "Ukendt"
msgid "Geo|Unknown state"
-msgstr ""
+msgstr "Ukendt tilstand"
msgid "Geo|Updated %{timeAgo}"
-msgstr ""
+msgstr "Opdateret %{timeAgo}"
msgid "Geo|Verification"
msgstr ""
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15063,10 +15180,10 @@ msgid "Geo|misconfigured"
msgstr ""
msgid "Geo|primary"
-msgstr ""
+msgstr "primær"
msgid "Geo|secondary"
-msgstr ""
+msgstr "sekundær"
msgid "Get a free instance review"
msgstr ""
@@ -15075,29 +15192,32 @@ msgid "Get a support subscription"
msgstr ""
msgid "Get started"
-msgstr ""
+msgstr "Kom godt i gang"
msgid "Get started with GitLab"
-msgstr ""
+msgstr "Kom godt i gang med GitLab"
msgid "Get started with error tracking"
msgstr ""
msgid "Get started with performance monitoring"
-msgstr ""
+msgstr "Kom godt i gang med ydelsesovervågning"
msgid "Get started!"
-msgstr ""
+msgstr "Kom godt i gang!"
msgid "Getting started with releases"
msgstr ""
msgid "Git"
-msgstr ""
+msgstr "Git"
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15105,7 +15225,7 @@ msgid "Git LFS objects will be synced if LFS is %{docs_link_start}enabled for th
msgstr ""
msgid "Git LFS status:"
-msgstr ""
+msgstr "Git LFS-status:"
msgid "Git global setup"
msgstr ""
@@ -15114,31 +15234,31 @@ msgid "Git repository URL"
msgstr ""
msgid "Git revision"
-msgstr ""
+msgstr "Git-revision"
msgid "Git shallow clone"
msgstr ""
msgid "Git strategy"
-msgstr ""
+msgstr "Git-strategi"
msgid "Git transfer in progress"
-msgstr ""
+msgstr "Igangværende Git-overførsel"
msgid "Git version"
-msgstr ""
+msgstr "Git-version"
msgid "GitHub API rate limit exceeded. Try again after %{reset_time}"
msgstr ""
msgid "GitHub import"
-msgstr ""
+msgstr "GitHub-import"
msgid "GitHubImporter|*Merged by: %{author} at %{timestamp}*"
msgstr ""
msgid "GitLab"
-msgstr ""
+msgstr "GitLab"
msgid "GitLab / Unsubscribe"
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15162,7 +15279,7 @@ msgid "GitLab Issue"
msgstr ""
msgid "GitLab Pages"
-msgstr ""
+msgstr "GitLab Pages"
msgid "GitLab Shell"
msgstr ""
@@ -15174,7 +15291,7 @@ msgid "GitLab Team Member"
msgstr ""
msgid "GitLab User"
-msgstr ""
+msgstr "GitLab-bruger"
msgid "GitLab Workhorse"
msgstr ""
@@ -15189,10 +15306,10 @@ msgid "GitLab export"
msgstr ""
msgid "GitLab for Slack"
-msgstr ""
+msgstr "GitLab for Slack"
msgid "GitLab group: %{source_link}"
-msgstr ""
+msgstr "GitLab-gruppe: %{source_link}"
msgid "GitLab is a complete DevOps platform, delivered as a single application, fundamentally changing the way Development, Security, and Ops teams collaborate"
msgstr ""
@@ -15207,13 +15324,13 @@ msgid "GitLab is obtaining a Let's Encrypt SSL certificate for this domain. This
msgstr ""
msgid "GitLab is open source software to collaborate on code."
-msgstr ""
+msgstr "GitLab er open source-software til at samarbejde om kode."
msgid "GitLab is undergoing maintenance and is operating in a read-only mode."
-msgstr ""
+msgstr "GitLab er ved at blive vedligeholdt og kører i skrivebeskyttet tilstand."
msgid "GitLab member or Email address"
-msgstr ""
+msgstr "GitLab-medlem eller e-mailadresse"
msgid "GitLab metadata URL"
msgstr ""
@@ -15228,7 +15345,7 @@ msgid "GitLab single sign-on URL"
msgstr ""
msgid "GitLab username"
-msgstr ""
+msgstr "GitLab-brugernavn"
msgid "GitLab uses %{jaeger_link} to monitor distributed systems."
msgstr ""
@@ -15237,22 +15354,22 @@ msgid "GitLab uses %{linkStart}Sidekiq%{linkEnd} to process background jobs"
msgstr ""
msgid "GitLab version"
-msgstr ""
+msgstr "GitLab-version"
msgid "GitLab will inform you if a new version is available."
-msgstr ""
+msgstr "GitLab informerer dig hvis der findes en ny version."
msgid "GitLab will run a background job that will produce pseudonymized CSVs of the GitLab database that will be uploaded to your configured object storage directory."
msgstr ""
msgid "GitLab.com"
-msgstr ""
+msgstr "GitLab.com"
msgid "GitLab.com import"
msgstr ""
msgid "GitLabPagesDomains|Retry"
-msgstr ""
+msgstr "Prøv igen"
msgid "GitLabPages|%{domain} is not verified. To learn how to verify ownership, visit your %{link_start}domain details%{link_end}."
msgstr ""
@@ -15264,22 +15381,22 @@ msgid "GitLabPages|Access pages"
msgstr ""
msgid "GitLabPages|Are you sure?"
-msgstr ""
+msgstr "Er du sikker?"
msgid "GitLabPages|Certificate: %{subject}"
-msgstr ""
+msgstr "Certifikat: %{subject}"
msgid "GitLabPages|Configure pages"
-msgstr ""
+msgstr "Konfigurer sider"
msgid "GitLabPages|Domains"
-msgstr ""
+msgstr "Domæner"
msgid "GitLabPages|Edit"
-msgstr ""
+msgstr "Rediger"
msgid "GitLabPages|Expired"
-msgstr ""
+msgstr "Udløbet"
msgid "GitLabPages|Force HTTPS (requires valid certificates)"
msgstr ""
@@ -15291,25 +15408,25 @@ msgid "GitLabPages|Maximum size of pages (MB)"
msgstr ""
msgid "GitLabPages|New Domain"
-msgstr ""
+msgstr "Nyt domæne"
msgid "GitLabPages|Only project maintainers can remove pages"
msgstr ""
msgid "GitLabPages|Pages"
-msgstr ""
+msgstr "Sider"
msgid "GitLabPages|Remove"
-msgstr ""
+msgstr "Fjern"
msgid "GitLabPages|Remove pages"
-msgstr ""
+msgstr "Fjern sider"
msgid "GitLabPages|Removing pages will prevent them from being exposed to the outside world."
msgstr ""
msgid "GitLabPages|Save changes"
-msgstr ""
+msgstr "Gem ændringer"
msgid "GitLabPages|Something went wrong while obtaining the Let's Encrypt certificate for %{domain}. To retry visit your %{link_start}domain details%{link_end}."
msgstr ""
@@ -15342,7 +15459,7 @@ msgid "GitLabPages|Your pages are served under:"
msgstr ""
msgid "Gitaly Servers"
-msgstr ""
+msgstr "Gitaly-servere"
msgid "Gitaly relative path:"
msgstr ""
@@ -15354,7 +15471,7 @@ msgid "Gitaly timeouts"
msgstr ""
msgid "Gitaly|Address"
-msgstr ""
+msgstr "Adresse"
msgid "Gitea Host URL"
msgstr ""
@@ -15381,10 +15498,10 @@ msgid "GithubIntegration|This requires mirroring your GitHub repository to this
msgstr ""
msgid "Gitpod"
-msgstr ""
+msgstr "Gitpod"
msgid "Gitpod|Enable Gitpod integration"
-msgstr ""
+msgstr "Aktivér Gitpod-integrering"
msgid "Gitpod|Gitpod URL"
msgstr ""
@@ -15396,7 +15513,7 @@ msgid "Gitpod|To use the integration, each user must also enable Gitpod on their
msgstr ""
msgid "Gitpod|https://gitpod.example.com"
-msgstr ""
+msgstr "https://gitpod.example.com"
msgid "Given access %{time_ago}"
msgstr ""
@@ -15404,95 +15521,98 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
-msgid "Global Shortcuts"
+msgid "Global Search is disabled for this scope"
msgstr ""
+msgid "Global Shortcuts"
+msgstr "Globale genveje"
+
msgid "Global notification settings"
-msgstr ""
+msgstr "Globale underretningsindstillinger"
msgid "Go Back"
-msgstr ""
+msgstr "GÃ¥ tilbage"
msgid "Go Micro is a framework for micro service development"
msgstr ""
msgid "Go back"
-msgstr ""
+msgstr "GÃ¥ tilbage"
msgid "Go back (while searching for files)"
-msgstr ""
+msgstr "Gå tilbage (når der søges efter filer)"
msgid "Go back to configuration"
-msgstr ""
+msgstr "GÃ¥ tilbage til konfiguration"
msgid "Go full screen"
-msgstr ""
+msgstr "Gå i fuldskærm"
msgid "Go to %{source_name}"
-msgstr ""
+msgstr "GÃ¥ til %{source_name}"
msgid "Go to commits"
-msgstr ""
+msgstr "GÃ¥ til commits"
msgid "Go to definition"
-msgstr ""
+msgstr "GÃ¥ til definition"
msgid "Go to environments"
-msgstr ""
+msgstr "Gå til miljøer"
msgid "Go to epic"
-msgstr ""
+msgstr "GÃ¥ til epic"
msgid "Go to file"
-msgstr ""
+msgstr "GÃ¥ til fil"
msgid "Go to file permalink (while viewing a file)"
msgstr ""
msgid "Go to files"
-msgstr ""
+msgstr "GÃ¥ til filer"
msgid "Go to find file"
-msgstr ""
+msgstr "GÃ¥ til find fil"
msgid "Go to fork"
-msgstr ""
+msgstr "GÃ¥ til forgrening"
msgid "Go to issue boards"
-msgstr ""
+msgstr "GÃ¥ til problemstillingstavler"
msgid "Go to issues"
-msgstr ""
+msgstr "GÃ¥ til problemstillinger"
msgid "Go to jobs"
-msgstr ""
+msgstr "GÃ¥ til job"
msgid "Go to kubernetes"
-msgstr ""
+msgstr "GÃ¥ til kubernetes"
msgid "Go to merge requests"
-msgstr ""
+msgstr "Gå til sammenlægningsanmodninger"
msgid "Go to metrics"
-msgstr ""
+msgstr "Gå til målinger"
msgid "Go to next page"
-msgstr ""
+msgstr "Gå til næste side"
msgid "Go to parent"
msgstr ""
msgid "Go to previous page"
-msgstr ""
+msgstr "GÃ¥ til forrige side"
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
-msgstr ""
+msgstr "GÃ¥ til projekt"
msgid "Go to releases"
-msgstr ""
+msgstr "GÃ¥ til udgivelser"
msgid "Go to repository charts"
msgstr ""
@@ -15501,43 +15621,43 @@ msgid "Go to repository graph"
msgstr ""
msgid "Go to snippets"
-msgstr ""
+msgstr "GÃ¥ til uddrag"
msgid "Go to the activity feed"
msgstr ""
msgid "Go to the milestone list"
-msgstr ""
+msgstr "Gå til milepælslisten"
msgid "Go to the project's activity feed"
msgstr ""
msgid "Go to the project's overview page"
-msgstr ""
+msgstr "GÃ¥ til projektets oversigtsside"
msgid "Go to wiki"
-msgstr ""
+msgstr "GÃ¥ til wiki"
msgid "Go to your To-Do list"
-msgstr ""
+msgstr "GÃ¥ til din To-Do-liste"
msgid "Go to your fork"
-msgstr ""
+msgstr "GÃ¥ til din forgrening"
msgid "Go to your groups"
-msgstr ""
+msgstr "GÃ¥ til dine grupper"
msgid "Go to your issues"
-msgstr ""
+msgstr "GÃ¥ til dine problemstillinger"
msgid "Go to your merge requests"
-msgstr ""
+msgstr "Gå til dine sammenlægningsanmodninger"
msgid "Go to your projects"
-msgstr ""
+msgstr "GÃ¥ til dine projekter"
msgid "Go to your snippets"
-msgstr ""
+msgstr "GÃ¥ til dine uddrag"
msgid "Goal of the changes and what reviewers should be aware of"
msgstr ""
@@ -15546,22 +15666,22 @@ msgid "Google authentication is not %{link_start}properly configured%{link_end}.
msgstr ""
msgid "Got it"
-msgstr ""
+msgstr "Modtaget"
msgid "Got it!"
-msgstr ""
+msgstr "Modtaget!"
msgid "Grafana URL"
-msgstr ""
+msgstr "Grafana-URL"
msgid "Grafana response contains invalid json"
-msgstr ""
+msgstr "Grafana-svaret indeholder ugyldig json"
msgid "GrafanaIntegration|API token"
-msgstr ""
+msgstr "API-token"
msgid "GrafanaIntegration|Active"
-msgstr ""
+msgstr "Aktiv"
msgid "GrafanaIntegration|Enter the %{docLinkStart}Grafana API token%{docLinkEnd}."
msgstr ""
@@ -15570,7 +15690,7 @@ msgid "GrafanaIntegration|Enter the base URL of the Grafana instance."
msgstr ""
msgid "GrafanaIntegration|Grafana URL"
-msgstr ""
+msgstr "Grafana-URL"
msgid "GrafanaIntegration|Grafana authentication"
msgstr ""
@@ -15579,13 +15699,13 @@ msgid "GrafanaIntegration|Set up Grafana authentication to embed Grafana panels
msgstr ""
msgid "Grant access"
-msgstr ""
+msgstr "Giv adgang"
msgid "Grant write permissions to this key"
msgstr ""
msgid "Graph"
-msgstr ""
+msgstr "Graf"
msgid "GraphViewType|Job dependencies"
msgstr ""
@@ -15597,37 +15717,37 @@ msgid "GraphViewType|Stage"
msgstr ""
msgid "Gravatar"
-msgstr ""
+msgstr "Gravatar"
msgid "Gravatar enabled"
-msgstr ""
+msgstr "Gravatar aktiveret"
msgid "Group"
-msgstr ""
+msgstr "Gruppe"
msgid "Group %{group_name} couldn't be exported."
-msgstr ""
+msgstr "Gruppen %{group_name} kunne ikke eksporteres."
msgid "Group %{group_name} was exported successfully."
-msgstr ""
+msgstr "Gruppen %{group_name} blev eksporteret."
msgid "Group %{group_name} was scheduled for deletion."
-msgstr ""
+msgstr "Gruppen %{group_name} blev planlagt til sletning."
msgid "Group %{group_name} was successfully created."
-msgstr ""
+msgstr "Gruppen %{group_name} blev oprettet."
msgid "Group Git LFS status:"
msgstr ""
msgid "Group Hooks"
-msgstr ""
+msgstr "Gruppehooks"
msgid "Group ID"
-msgstr ""
+msgstr "Gruppe-id"
msgid "Group ID: %{group_id}"
-msgstr ""
+msgstr "Gruppe-id: %{group_id}"
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -15642,22 +15762,22 @@ msgid "Group Wikis"
msgstr ""
msgid "Group application: %{name}"
-msgstr ""
+msgstr "Gruppeprogram: %{name}"
msgid "Group applications"
-msgstr ""
+msgstr "Gruppeprogrammer"
msgid "Group audit events"
msgstr ""
msgid "Group avatar"
-msgstr ""
+msgstr "Gruppeavatar"
msgid "Group by"
-msgstr ""
+msgstr "Gruppér efter"
msgid "Group description (optional)"
-msgstr ""
+msgstr "Gruppebeskrivelse (valgfrit)"
msgid "Group export could not be started."
msgstr ""
@@ -15681,7 +15801,7 @@ msgid "Group has been already marked for deletion"
msgstr ""
msgid "Group has not been marked for deletion"
-msgstr ""
+msgstr "Gruppen er blevet mærket til sletning"
msgid "Group import could not be scheduled"
msgstr ""
@@ -15690,10 +15810,10 @@ msgid "Group import requests"
msgstr ""
msgid "Group info:"
-msgstr ""
+msgstr "Gruppeinformation:"
msgid "Group information"
-msgstr ""
+msgstr "Gruppeinformation"
msgid "Group is required when cluster_type is :group"
msgstr ""
@@ -15705,7 +15825,7 @@ msgid "Group maintainers can register group runners in the %{link}"
msgstr ""
msgid "Group members"
-msgstr ""
+msgstr "Gruppemedlemmer"
msgid "Group membership expiration date changed"
msgstr ""
@@ -15717,22 +15837,22 @@ msgid "Group milestone"
msgstr ""
msgid "Group name"
-msgstr ""
+msgstr "Gruppenavn"
msgid "Group name (your organization)"
-msgstr ""
+msgstr "Gruppenavn (din organisation)"
msgid "Group navigation"
-msgstr ""
+msgstr "Gruppenavigation"
msgid "Group overview content"
-msgstr ""
+msgstr "Indhold for gruppeoversigt"
msgid "Group path is already taken. We've suggested one that is available."
msgstr ""
msgid "Group path is available."
-msgstr ""
+msgstr "Gruppesti er tilgængelig."
msgid "Group pipeline minutes were successfully reset."
msgstr ""
@@ -15741,7 +15861,7 @@ msgid "Group project URLs are prefixed with the group namespace"
msgstr ""
msgid "Group projects"
-msgstr ""
+msgstr "Gruppeprojekter"
msgid "Group requires separate account"
msgstr ""
@@ -15756,43 +15876,43 @@ msgid "Group sharing provides access to all group members (including members who
msgstr ""
msgid "Group variables (inherited)"
-msgstr ""
+msgstr "Gruppevariabler (nedarvet)"
msgid "Group was exported"
-msgstr ""
+msgstr "Gruppen blev eksporteret"
msgid "Group was successfully updated."
-msgstr ""
+msgstr "Gruppen blev opdateret."
msgid "Group: %{group_name}"
-msgstr ""
+msgstr "Gruppe: %{group_name}"
msgid "Group: %{name}"
-msgstr ""
+msgstr "Gruppe: %{name}"
msgid "GroupActivityMetrics|Issues opened"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
-msgstr ""
+msgstr "Sidste 90 dage"
msgid "GroupActivityMetrics|Members added"
-msgstr ""
+msgstr "Medlemmer tilføjet"
msgid "GroupActivityMetrics|Merge Requests opened"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
-msgstr ""
+msgstr "Seneste aktivitet"
msgid "GroupImport|Failed to import group."
-msgstr ""
+msgstr "Kunne ikke importere gruppe."
msgid "GroupImport|Group '%{group_name}' is being imported."
-msgstr ""
+msgstr "Gruppen '%{group_name}' importeres."
msgid "GroupImport|Group could not be imported: %{errors}"
-msgstr ""
+msgstr "Gruppen kunne ikke importeres: %{errors}"
msgid "GroupImport|Please wait while we import the group for you. Refresh at will."
msgstr ""
@@ -15804,19 +15924,19 @@ msgid "GroupImport|Unable to process group import file"
msgstr ""
msgid "GroupRoadmap|%{dateWord} – No end date"
-msgstr ""
+msgstr "%{dateWord} – ingen slutdato"
msgid "GroupRoadmap|%{startDateInWords} – %{endDateInWords}"
msgstr ""
msgid "GroupRoadmap|Loading epics"
-msgstr ""
+msgstr "Indlæser epics"
msgid "GroupRoadmap|No start and end date"
-msgstr ""
+msgstr "Ingen start- eller slutdato"
msgid "GroupRoadmap|No start date – %{dateWord}"
-msgstr ""
+msgstr "Ingen startdato – %{dateWord}"
msgid "GroupRoadmap|Roadmaps can display up to 1,000 epics. These appear in your selected sort order."
msgstr ""
@@ -15825,10 +15945,10 @@ msgid "GroupRoadmap|Some of your epics might not be visible"
msgstr ""
msgid "GroupRoadmap|Something went wrong while fetching epics"
-msgstr ""
+msgstr "Noget gik galt under hentning af epics"
msgid "GroupRoadmap|Something went wrong while fetching milestones"
-msgstr ""
+msgstr "Noget gik galt under hentning af milepæle"
msgid "GroupRoadmap|Sorry, no epics matched your search"
msgstr ""
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15867,7 +15996,7 @@ msgid "GroupSAML|Certificate fingerprint"
msgstr ""
msgid "GroupSAML|Configuration"
-msgstr ""
+msgstr "Konfiguration"
msgid "GroupSAML|Copy SAML Response XML"
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -15897,7 +16026,7 @@ msgid "GroupSAML|Generate a SCIM token to set up your System for Cross-Domain Id
msgstr ""
msgid "GroupSAML|Identity"
-msgstr ""
+msgstr "Identitet"
msgid "GroupSAML|Identity provider single sign-on URL"
msgstr ""
@@ -15909,13 +16038,13 @@ msgid "GroupSAML|Manage your group’s membership while adding another level of
msgstr ""
msgid "GroupSAML|Members"
-msgstr ""
+msgstr "Medlemmer"
msgid "GroupSAML|Members will be forwarded here when signing in to your group. Get this from your identity provider, where it can also be called \"SSO Service Location\", \"SAML Token Issuance Endpoint\", or \"SAML 2.0/W-Federation URL\"."
msgstr ""
msgid "GroupSAML|NameID"
-msgstr ""
+msgstr "Navn-id"
msgid "GroupSAML|NameID Format"
msgstr ""
@@ -15936,7 +16065,7 @@ msgid "GroupSAML|SAML Group Links"
msgstr ""
msgid "GroupSAML|SAML Group Name"
-msgstr ""
+msgstr "SAML-gruppenavn"
msgid "GroupSAML|SAML Group Name: %{saml_group_name}"
msgstr ""
@@ -15990,7 +16119,7 @@ msgid "GroupSAML|Your SCIM token"
msgstr ""
msgid "GroupSAML|as %{access_level}"
-msgstr ""
+msgstr "som %{access_level}"
msgid "GroupSAML|must match stored NameID of \"%{extern_uid}\" as we use this to identify users. If the NameID changes users will be unable to sign in."
msgstr ""
@@ -16008,7 +16137,7 @@ msgid "GroupSelect|Search groups"
msgstr ""
msgid "GroupSelect|Select a group"
-msgstr ""
+msgstr "Vælg en gruppe"
msgid "GroupSettings|Allow project access token creation"
msgstr ""
@@ -16017,7 +16146,7 @@ msgid "GroupSettings|Auto DevOps pipeline was updated for the group"
msgstr ""
msgid "GroupSettings|Badges"
-msgstr ""
+msgstr "Badges"
msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
msgstr ""
@@ -16041,7 +16170,7 @@ msgid "GroupSettings|Custom project templates"
msgstr ""
msgid "GroupSettings|Customize this group's badges."
-msgstr ""
+msgstr "Tilpas gruppens badges."
msgid "GroupSettings|Default to Auto DevOps pipeline for all projects within this group"
msgstr ""
@@ -16056,7 +16185,7 @@ msgid "GroupSettings|Enable delayed project deletion"
msgstr ""
msgid "GroupSettings|Export group"
-msgstr ""
+msgstr "Eksportér gruppe"
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
@@ -16137,13 +16266,13 @@ msgid "GroupSettings|This setting will prevent group members from forking projec
msgstr ""
msgid "GroupSettings|Transfer group"
-msgstr ""
+msgstr "Overfør gruppe"
msgid "GroupSettings|Users can create %{link_start}project access tokens%{link_end} for projects in this group."
msgstr ""
msgid "GroupSettings|What are badges?"
-msgstr ""
+msgstr "Hvad er badges?"
msgid "GroupSettings|You can only transfer the group to a group you manage."
msgstr ""
@@ -16152,7 +16281,7 @@ msgid "GroupSettings|You will need to update your local repositories to point to
msgstr ""
msgid "GroupSettings|cannot be changed by you"
-msgstr ""
+msgstr "kan ikke ændres af dig"
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -16164,34 +16293,34 @@ msgid "GroupSettings|remove the share with group lock from %{ancestor_group_name
msgstr ""
msgid "Groups"
-msgstr ""
+msgstr "Grupper"
msgid "Groups (%{count})"
-msgstr ""
+msgstr "Grupper (%{count})"
msgid "Groups and projects"
-msgstr ""
+msgstr "Grupper og projekter"
msgid "Groups and subgroups"
-msgstr ""
+msgstr "Grupper og undergrupper"
msgid "Groups to synchronize"
msgstr ""
msgid "GroupsDropdown|Frequently visited"
-msgstr ""
+msgstr "Ofte besøgte"
msgid "GroupsDropdown|Groups you visit often will appear here"
msgstr ""
msgid "GroupsDropdown|Loading groups"
-msgstr ""
+msgstr "Indlæser grupper"
msgid "GroupsDropdown|Search your groups"
msgstr ""
msgid "GroupsDropdown|Something went wrong on our end."
-msgstr ""
+msgstr "Noget gik galt i vores ende."
msgid "GroupsDropdown|Sorry, no groups matched your search"
msgstr ""
@@ -16206,7 +16335,7 @@ msgid "GroupsEmptyState|If you organize your projects under a group, it works li
msgstr ""
msgid "GroupsEmptyState|No groups found"
-msgstr ""
+msgstr "Ingen grupper fundet"
msgid "GroupsEmptyState|You can manage your group member’s permissions and access to each project in the group."
msgstr ""
@@ -16224,10 +16353,10 @@ msgid "GroupsNew|Contact an administrator to enable options for importing your g
msgstr ""
msgid "GroupsNew|Create group"
-msgstr ""
+msgstr "Opret gruppe"
msgid "GroupsNew|Create new group"
-msgstr ""
+msgstr "Opret ny gruppe"
msgid "GroupsNew|Export groups with all their related data and move to a new GitLab instance."
msgstr ""
@@ -16239,13 +16368,13 @@ msgid "GroupsNew|Groups can also be nested by creating %{linkStart}subgroups%{li
msgstr ""
msgid "GroupsNew|Import group"
-msgstr ""
+msgstr "Importér gruppe"
msgid "GroupsNew|Import groups from another instance of GitLab"
msgstr ""
msgid "GroupsNew|My Awesome Group"
-msgstr ""
+msgstr "Min fantastiske gruppe"
msgid "GroupsNew|Navigate to user settings to find your %{link_start}personal access token%{link_end}."
msgstr ""
@@ -16275,22 +16404,22 @@ msgid "GroupsNew|Upload file"
msgstr ""
msgid "GroupsNew|e.g. h8d3f016698e..."
-msgstr ""
+msgstr "f.eks. h8d3f016698e ..."
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
-msgstr ""
+msgstr "Er du sikker på, at du vil forlade gruppen \"%{fullName}\"?"
msgid "GroupsTree|Edit group"
-msgstr ""
+msgstr "Rediger gruppe"
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
msgid "GroupsTree|Leave this group"
-msgstr ""
+msgstr "Forlad gruppen"
msgid "GroupsTree|Loading groups"
-msgstr ""
+msgstr "Indlæser grupper"
msgid "GroupsTree|No groups matched your search"
msgstr ""
@@ -16299,10 +16428,10 @@ msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
msgid "GroupsTree|Search by name"
-msgstr ""
+msgstr "Søg efter navn"
msgid "Guideline"
-msgstr ""
+msgstr "Retningslinje"
msgid "HAR (HTTP Archive)"
msgstr ""
@@ -16326,46 +16455,46 @@ msgid "Header cannot be associated with both a request and a response"
msgstr ""
msgid "Header logo"
-msgstr ""
+msgstr "Headerlogo"
msgid "Header logo was successfully removed."
msgstr ""
msgid "Header logo will be removed. Are you sure?"
-msgstr ""
+msgstr "Headerlogo fjernes. Er du sikker?"
msgid "Header message"
-msgstr ""
+msgstr "Headermeddelelse"
msgid "Header must be associated with a request or response"
msgstr ""
msgid "Heading 1"
-msgstr ""
+msgstr "Overskrift 1"
msgid "Heading 2"
-msgstr ""
+msgstr "Overskrift 2"
msgid "Heading 3"
-msgstr ""
+msgstr "Overskrift 3"
msgid "Heading 4"
-msgstr ""
+msgstr "Overskrift 4"
msgid "Headings"
-msgstr ""
+msgstr "Overskrifter"
msgid "Health"
-msgstr ""
+msgstr "Helbred"
msgid "Health Check"
-msgstr ""
+msgstr "Sundhedstjek"
msgid "Health information can be retrieved from the following endpoints. More information is available"
msgstr ""
msgid "Health status"
-msgstr ""
+msgstr "Helbredsstatus"
msgid "Health status cannot be edited because this issue is closed"
msgstr ""
@@ -16386,7 +16515,7 @@ msgid "Hello %{name},"
msgstr ""
msgid "Hello there"
-msgstr ""
+msgstr "Hej med dig"
msgid "Hello, %{name}!"
msgstr ""
@@ -16395,24 +16524,24 @@ msgid "Hello, %{username}!"
msgstr ""
msgid "Help"
-msgstr ""
+msgstr "Hjælp"
msgid "Helps prevent bots from brute-force attacks."
-msgstr ""
+msgstr "Hjælper med at forhindre botter i at udføre brute-force-angreb."
msgid "Helps prevent bots from creating accounts."
-msgstr ""
+msgstr "Hjælper med at forhindre botter i at oprette kontoer."
msgid "Helps prevent bots from creating issues"
-msgstr ""
+msgstr "Hjælper med at forhindre botter i at oprette problemstillinger"
msgid "Helps prevent malicious users hide their activity"
-msgstr ""
+msgstr "Hjælper med at forhindre ondsindede brugere i at skjule deres aktivitet"
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16422,36 +16551,36 @@ msgid "Here you will find recent merge request activity"
msgstr ""
msgid "Hi %{username}!"
-msgstr ""
+msgstr "Hej %{username}!"
msgid "Hide"
-msgstr ""
+msgstr "Skjul"
msgid "Hide archived projects"
-msgstr ""
+msgstr "Skjul arkiverede projekter"
msgid "Hide chart"
msgid_plural "Hide charts"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Skjul diagram"
+msgstr[1] "Skjul diagrammer"
msgid "Hide comments on this file"
-msgstr ""
+msgstr "Skjul kommentarer på filen"
msgid "Hide details"
-msgstr ""
+msgstr "Skjul detaljer"
msgid "Hide file browser"
-msgstr ""
+msgstr "Skjul filvælger"
msgid "Hide group projects"
-msgstr ""
+msgstr "Skjul gruppeprojekter"
msgid "Hide host keys manual input"
msgstr ""
msgid "Hide list"
-msgstr ""
+msgstr "Skjul liste"
msgid "Hide marketing-related entries from the Help page"
msgstr ""
@@ -16460,18 +16589,18 @@ msgid "Hide payload"
msgstr ""
msgid "Hide shared projects"
-msgstr ""
+msgstr "Skjul delte projekter"
msgid "Hide tooltips or popovers"
msgstr ""
msgid "Hide value"
msgid_plural "Hide values"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Skjul værdi"
+msgstr[1] "Skjul værdier"
msgid "Hide values"
-msgstr ""
+msgstr "Skjul værdier"
msgid "High or unknown vulnerabilities present"
msgstr ""
@@ -16480,7 +16609,7 @@ msgid "Highest number of requests per minute for each raw path, default to 300.
msgstr ""
msgid "Highest role:"
-msgstr ""
+msgstr "Højeste rolle:"
msgid "HighlightBar|Alert events:"
msgstr ""
@@ -16495,34 +16624,34 @@ msgid "HighlightBar|Time to SLA:"
msgstr ""
msgid "History"
-msgstr ""
+msgstr "Historik"
msgid "History of authentications"
-msgstr ""
+msgstr "Historik for godkendelser"
msgid "Home page URL"
-msgstr ""
+msgstr "URL for startside"
msgid "Homepage"
-msgstr ""
+msgstr "Startside"
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
msgid "Hook was successfully created."
-msgstr ""
+msgstr "Hook blev oprettet."
msgid "Hook was successfully updated."
-msgstr ""
+msgstr "Hook blev opdateret."
msgid "Hostname"
-msgstr ""
+msgstr "Værtsnavn"
msgid "Hostname used in private commit emails. %{learn_more}"
msgstr ""
msgid "Hour (UTC)"
-msgstr ""
+msgstr "Time (UTC)"
msgid "Housekeeping"
msgstr ""
@@ -16537,7 +16666,7 @@ msgid "How do I configure runners?"
msgstr ""
msgid "How do I configure this integration?"
-msgstr ""
+msgstr "Hvordan konfigurerer jeg integreringen?"
msgid "How do I generate it?"
msgstr ""
@@ -16545,11 +16674,14 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
msgid "How do I set up this service?"
-msgstr ""
+msgstr "Hvordan opsætter jeg tjenesten?"
msgid "How it works"
msgstr ""
@@ -16561,19 +16693,19 @@ msgid "How many seconds an IP will be counted towards the limit"
msgstr ""
msgid "I accept the %{terms_link}"
-msgstr ""
+msgstr "Jeg accepterer %{terms_link}"
msgid "I accept the|Terms of Service and Privacy Policy"
-msgstr ""
+msgstr "Jeg accepterer|vilkår for tjeneste og privatlivspolitik"
msgid "I forgot my password"
-msgstr ""
+msgstr "Jeg har glemt min adgangskode"
msgid "I want to explore GitLab to see if it’s worth switching to"
-msgstr ""
+msgstr "Jeg vil udforske GitLab for at se om det er værd at skifte til"
msgid "I want to learn the basics of Git"
-msgstr ""
+msgstr "Jeg vil lære det grundlæggende i Git"
msgid "I want to move my repository to GitLab from somewhere else"
msgstr ""
@@ -16585,49 +16717,49 @@ msgid "I want to use GitLab CI with my existing repository"
msgstr ""
msgid "I'd like to receive updates about GitLab via email"
-msgstr ""
+msgstr "Jeg vil gerne modtage opdateringer om GitLab via e-mail"
msgid "I'm signing up for GitLab because:"
-msgstr ""
+msgstr "Jeg tilmelder mig GitLab fordi:"
msgid "ID"
-msgstr ""
+msgstr "Id"
msgid "ID:"
-msgstr ""
+msgstr "Id:"
msgid "IDE"
-msgstr ""
+msgstr "IDE"
msgid "IDE|Back"
-msgstr ""
+msgstr "Tilbage"
msgid "IDE|Commit"
-msgstr ""
+msgstr "Commit"
msgid "IDE|Commit to %{branchName} branch"
-msgstr ""
+msgstr "Commit til grenen %{branchName}"
msgid "IDE|Edit"
-msgstr ""
+msgstr "Rediger"
msgid "IDE|Get started with Live Preview"
-msgstr ""
+msgstr "Kom godt i gang med liveforhåndsvisning"
msgid "IDE|Go to project"
-msgstr ""
+msgstr "GÃ¥ til projekt"
msgid "IDE|Live Preview"
-msgstr ""
+msgstr "Liveforhåndsvisning"
msgid "IDE|Preview your web application using Web IDE client-side evaluation."
msgstr ""
msgid "IDE|Refresh preview"
-msgstr ""
+msgstr "Opdater forhåndsvisning"
msgid "IDE|Review"
-msgstr ""
+msgstr "Kontrol"
msgid "IDE|Successful commit"
msgstr ""
@@ -16645,7 +16777,7 @@ msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
msgid "IP Address"
-msgstr ""
+msgstr "IP-adresse"
msgid "IP expiration time"
msgstr ""
@@ -16654,7 +16786,7 @@ msgid "IP subnet restriction only allowed for top-level groups"
msgstr ""
msgid "IPs per user"
-msgstr ""
+msgstr "IP'er pr. bruger"
msgid "Identifier"
msgstr ""
@@ -16663,7 +16795,7 @@ msgid "Identifiers"
msgstr ""
msgid "Identities"
-msgstr ""
+msgstr "Identiteter"
msgid "If any indexed field exceeds this limit it will be truncated to this number of characters and the rest will not be indexed or searchable. This does not apply to repository and wiki indexing. Setting this to 0 means it is unlimited."
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16708,10 +16840,10 @@ msgid "If this email was added in error, you can remove it here: %{profile_email
msgstr ""
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
-msgstr ""
+msgstr "Hvis det var en fejltagelse, så kan du %{leave_link_start}forlade %{source_type}%{link_end}."
msgid "If this was a mistake you can leave the %{source_type}."
-msgstr ""
+msgstr "Hvis det var en fejltagelse, så kan du forlade %{source_type}."
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
@@ -16753,16 +16885,16 @@ msgid "If your HTTP repository is not publicly accessible, add your credentials.
msgstr ""
msgid "Ignore"
-msgstr ""
+msgstr "Ignorer"
msgid "Ignored"
-msgstr ""
+msgstr "Ignoreret"
msgid "Image URL"
msgstr ""
msgid "Image details"
-msgstr ""
+msgstr "Billeddetaljer"
msgid "ImageDiffViewer|2-up"
msgstr ""
@@ -16774,10 +16906,10 @@ msgid "ImageDiffViewer|Swipe"
msgstr ""
msgid "ImageViewerDimensions|H"
-msgstr ""
+msgstr "H"
msgid "ImageViewerDimensions|W"
-msgstr ""
+msgstr "B"
msgid "Images with incorrect dimensions are not resized automatically, and may result in unexpected behavior."
msgstr ""
@@ -16792,7 +16924,7 @@ msgid "Impersonation has been disabled"
msgstr ""
msgid "Import"
-msgstr ""
+msgstr "Importér"
msgid "Import %d compatible repository"
msgid_plural "Import %d compatible repositories"
@@ -16805,13 +16937,13 @@ msgstr[0] ""
msgstr[1] ""
msgid "Import CSV"
-msgstr ""
+msgstr "Importér CSV"
msgid "Import Projects from Gitea"
-msgstr ""
+msgstr "Importér projekter fra Gitea"
msgid "Import a project"
-msgstr ""
+msgstr "Importér et projekt"
msgid "Import an exported GitLab project"
msgstr ""
@@ -16820,70 +16952,70 @@ msgid "Import failed due to a GitHub error: %{original}"
msgstr ""
msgid "Import from"
-msgstr ""
+msgstr "Importér fra"
msgid "Import from Jira"
-msgstr ""
+msgstr "Importér fra Jira"
msgid "Import group from file"
-msgstr ""
+msgstr "Importér gruppe fra fil"
msgid "Import groups"
-msgstr ""
+msgstr "Importér grupper"
msgid "Import in progress"
-msgstr ""
+msgstr "Import i gang"
msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
msgid "Import issues"
-msgstr ""
+msgstr "Importér problemstillinger"
msgid "Import members"
-msgstr ""
+msgstr "Importér medlemmer"
msgid "Import members from another project"
-msgstr ""
+msgstr "Importér medlemmer fra et andet projekt"
msgid "Import multiple repositories by uploading a manifest file."
msgstr ""
msgid "Import project"
-msgstr ""
+msgstr "Importér projekt"
msgid "Import project from"
-msgstr ""
+msgstr "Importér projekt fra"
msgid "Import project members"
-msgstr ""
+msgstr "Importér projektmedlemmer"
msgid "Import projects from Bitbucket"
-msgstr ""
+msgstr "Importér projekter fra Bitbucket"
msgid "Import projects from Bitbucket Server"
-msgstr ""
+msgstr "Importér projekter fra Bitbucket-server"
msgid "Import projects from FogBugz"
-msgstr ""
+msgstr "Importér projekter fra FogBugz"
msgid "Import projects from GitLab.com"
-msgstr ""
+msgstr "Importér projekter fra GitLab.com"
msgid "Import repositories from Bitbucket Server"
-msgstr ""
+msgstr "Importér depoter fra Bitbucket-server"
msgid "Import repositories from GitHub"
-msgstr ""
+msgstr "Importér depoter fra GitHub"
msgid "Import repository"
-msgstr ""
+msgstr "Importér depot"
msgid "Import requirements"
msgstr ""
msgid "Import started by: %{importInitiator}"
-msgstr ""
+msgstr "Import startet af: %{importInitiator}"
msgid "Import tasks"
msgstr ""
@@ -16892,7 +17024,7 @@ msgid "Import tasks from Phabricator into issues"
msgstr ""
msgid "Import timed out. Import took longer than %{import_jobs_expiration} seconds"
-msgstr ""
+msgstr "Importen fik timeout. Importen tog længere end %{import_jobs_expiration} sekunder"
msgid "Import/Export Rate Limits"
msgstr ""
@@ -16945,7 +17077,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "Importing..."
-msgstr ""
+msgstr "Importerer ..."
msgid "Import|A repository URL usually ends in a .git suffix, although this is not required. Double check to make sure your repository URL is correct."
msgstr ""
@@ -16957,7 +17089,7 @@ msgid "Improves Git cloning performance."
msgstr ""
msgid "In %{time_to_now}"
-msgstr ""
+msgstr "Om %{time_to_now}"
msgid "In case of pull mirroring, your user will be the author of all events in the activity feed that are the result of an update, like new branches being created or new commits being pushed to existing branches."
msgstr ""
@@ -16966,11 +17098,14 @@ msgid "In each example, replace %{code_start}TOKEN%{code_end} with the trigger t
msgstr ""
msgid "In progress"
-msgstr ""
+msgstr "I gang"
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17017,10 +17152,10 @@ msgid "InProductMarketing|Beef up your security"
msgstr ""
msgid "InProductMarketing|Better code in less time"
-msgstr ""
+msgstr "Bedre kode på mindre tid"
msgid "InProductMarketing|Blog"
-msgstr ""
+msgstr "Blog"
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
@@ -17038,10 +17173,10 @@ msgid "InProductMarketing|Create a custom runner"
msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
-msgstr ""
+msgstr "Opret et projekt i GitLab på 5 minutter"
msgid "InProductMarketing|Create your first project!"
-msgstr ""
+msgstr "Opret dit første projekt!"
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
@@ -17050,7 +17185,7 @@ msgid "InProductMarketing|Did you know teams that use GitLab are far more effici
msgstr ""
msgid "InProductMarketing|Difficult"
-msgstr ""
+msgstr "Svært"
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
@@ -17059,7 +17194,7 @@ msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Easy"
-msgstr ""
+msgstr "Nemt"
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -17074,7 +17209,7 @@ msgid "InProductMarketing|Explore the power of GitLab CI/CD"
msgstr ""
msgid "InProductMarketing|Facebook"
-msgstr ""
+msgstr "Facebook"
msgid "InProductMarketing|Feedback from users like you really improves our product. Thanks for your help!"
msgstr ""
@@ -17089,7 +17224,7 @@ msgid "InProductMarketing|Follow our steps"
msgstr ""
msgid "InProductMarketing|Free 30-day trial"
-msgstr ""
+msgstr "Gratis 30-dages prøveperiode"
msgid "InProductMarketing|Get going with CI/CD quickly using our %{quick_start_link}. Start with an available runner and then create a CI .yml file – it's really that easy."
msgstr ""
@@ -17098,7 +17233,7 @@ msgid "InProductMarketing|Get our import guides"
msgstr ""
msgid "InProductMarketing|Get started today"
-msgstr ""
+msgstr "Kom godt i gang i dag"
msgid "InProductMarketing|Get started today with a 30-day GitLab Ultimate trial, no credit card required."
msgstr ""
@@ -17254,7 +17389,7 @@ msgid "InProductMarketing|Start by importing your projects"
msgstr ""
msgid "InProductMarketing|Start with a GitLab Ultimate free trial"
-msgstr ""
+msgstr "Start med en gratis prøveperiode af GitLab Ultimate"
msgid "InProductMarketing|Start your trial now!"
msgstr ""
@@ -17308,10 +17443,10 @@ msgid "InProductMarketing|To understand and get the most out of GitLab, start at
msgstr ""
msgid "InProductMarketing|Try GitLab Ultimate for free"
-msgstr ""
+msgstr "Prøv GitLab Ultimate, gratis"
msgid "InProductMarketing|Try it out"
-msgstr ""
+msgstr "Prøv det"
msgid "InProductMarketing|Try it yourself"
msgstr ""
@@ -17320,7 +17455,7 @@ msgid "InProductMarketing|Turn coworkers into collaborators"
msgstr ""
msgid "InProductMarketing|Twitter"
-msgstr ""
+msgstr "Twitter"
msgid "InProductMarketing|Understand repository mirroring"
msgstr ""
@@ -17338,10 +17473,10 @@ msgid "InProductMarketing|Used by more than 100,000 organizations from around th
msgstr ""
msgid "InProductMarketing|Very difficult"
-msgstr ""
+msgstr "Meget svært"
msgid "InProductMarketing|Very easy"
-msgstr ""
+msgstr "Meget nemt"
msgid "InProductMarketing|We know a thing or two about efficiency and we don't want to keep that to ourselves. Sign up for a free trial of GitLab Ultimate and your teams will be on it from day one."
msgstr ""
@@ -17359,7 +17494,7 @@ msgid "InProductMarketing|Working in GitLab = more efficient"
msgstr ""
msgid "InProductMarketing|YouTube"
-msgstr ""
+msgstr "YouTube"
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -17371,10 +17506,10 @@ msgid "InProductMarketing|connect an external repository"
msgstr ""
msgid "InProductMarketing|create a project"
-msgstr ""
+msgstr "opret et projekt"
msgid "InProductMarketing|from Bitbucket"
-msgstr ""
+msgstr "fra Bitbucket"
msgid "InProductMarketing|go to about.gitlab.com"
msgstr ""
@@ -17401,7 +17536,7 @@ msgid "InProductMarketing|unsubscribe"
msgstr ""
msgid "InProductMarketing|update your preferences"
-msgstr ""
+msgstr "opdater dine præferencer"
msgid "InProductMarketing|using a CI/CD template"
msgstr ""
@@ -17410,10 +17545,10 @@ msgid "InProductMarketing|you may %{unsubscribe_link} at any time."
msgstr ""
msgid "Inactive"
-msgstr ""
+msgstr "Inaktiv"
msgid "Incident"
-msgstr ""
+msgstr "Hændelse"
msgid "Incident Management Limits"
msgstr ""
@@ -17431,7 +17566,7 @@ msgid "IncidentManagement|Achieved SLA"
msgstr ""
msgid "IncidentManagement|All"
-msgstr ""
+msgstr "Alle"
msgid "IncidentManagement|All alerts promoted to incidents will automatically be displayed within the list. You can also create a new incident using the button below."
msgstr ""
@@ -17440,34 +17575,34 @@ msgid "IncidentManagement|Assignees"
msgstr ""
msgid "IncidentManagement|Closed"
-msgstr ""
+msgstr "Lukket"
msgid "IncidentManagement|Create incident"
-msgstr ""
+msgstr "Opret hændelse"
msgid "IncidentManagement|Critical - S1"
-msgstr ""
+msgstr "Kritisk - S1"
msgid "IncidentManagement|Date created"
-msgstr ""
+msgstr "Dato oprettet"
msgid "IncidentManagement|Display your incidents in a dedicated view"
msgstr ""
msgid "IncidentManagement|High - S2"
-msgstr ""
+msgstr "Høj - S2"
msgid "IncidentManagement|Incident"
-msgstr ""
+msgstr "Hændelse"
msgid "IncidentManagement|Incidents"
-msgstr ""
+msgstr "Hændelser"
msgid "IncidentManagement|Low - S4"
-msgstr ""
+msgstr "Lav - S4"
msgid "IncidentManagement|Medium - S3"
-msgstr ""
+msgstr "Mellem - S3"
msgid "IncidentManagement|Missed SLA"
msgstr ""
@@ -17485,7 +17620,7 @@ msgid "IncidentManagement|Published to status page"
msgstr ""
msgid "IncidentManagement|Severity"
-msgstr ""
+msgstr "Alvorlighed"
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -17497,10 +17632,10 @@ msgid "IncidentManagement|Time to SLA"
msgstr ""
msgid "IncidentManagement|Unassigned"
-msgstr ""
+msgstr "Utildelt"
msgid "IncidentManagement|Unknown"
-msgstr ""
+msgstr "Ukendt"
msgid "IncidentManagement|Unpublished"
msgstr ""
@@ -17518,7 +17653,7 @@ msgid "IncidentSettings|Incident settings"
msgstr ""
msgid "IncidentSettings|Incidents"
-msgstr ""
+msgstr "Hændelser"
msgid "IncidentSettings|Introduce a countdown timer in incident issues to better track Service Level Agreements (SLAs). The timer starts automatically when the incident is created, and sets a time limit for resolving the incident. When activated, the time to SLA countdown appears on all new incidents."
msgstr ""
@@ -17542,22 +17677,22 @@ msgid "IncidentSettings|When activated, this applies to all new incidents in the
msgstr ""
msgid "IncidentSettings|hours"
-msgstr ""
+msgstr "timer"
msgid "IncidentSettings|minutes"
-msgstr ""
+msgstr "minutter"
msgid "Incidents"
-msgstr ""
+msgstr "Hændelser"
msgid "Incidents|Add a URL"
-msgstr ""
+msgstr "Tilføj en URL"
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
msgstr ""
msgid "Incidents|Must start with http or https"
-msgstr ""
+msgstr "Skal begynde med http eller https"
msgid "Incidents|There was an issue deleting the image."
msgstr ""
@@ -17575,16 +17710,16 @@ msgid "Incident|Alert details"
msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
-msgstr ""
+msgstr "Er du sikker på, at du vil slette billedet?"
msgid "Incident|Deleting %{filename}"
-msgstr ""
+msgstr "Sletter %{filename}"
msgid "Incident|Metrics"
-msgstr ""
+msgstr "MÃ¥linger"
msgid "Incident|Summary"
-msgstr ""
+msgstr "Opsummering"
msgid "Incident|There was an issue loading alert data. Please try again."
msgstr ""
@@ -17596,7 +17731,7 @@ msgid "Include author name in notification email body"
msgstr ""
msgid "Include description in commit message"
-msgstr ""
+msgstr "Medtag beskrivelse i commit-meddelelse"
msgid "Include merge request description"
msgstr ""
@@ -17641,16 +17776,16 @@ msgid "Increase"
msgstr ""
msgid "Indent"
-msgstr ""
+msgstr "Indryk"
msgid "Index"
msgstr ""
msgid "Index all projects"
-msgstr ""
+msgstr "Indeksér alle projekter"
msgid "Index deletion is canceled"
-msgstr ""
+msgstr "Sletning af indeks er annulleret"
msgid "Indicates whether this runner can pick jobs without tags"
msgstr ""
@@ -17659,7 +17794,7 @@ msgid "Inform users without uploaded SSH keys that they can't push over SSH unti
msgstr ""
msgid "Infrastructure"
-msgstr ""
+msgstr "Infrastruktur"
msgid "Infrastructure Registry"
msgstr ""
@@ -17701,7 +17836,7 @@ msgid "Inherited:"
msgstr ""
msgid "Inline"
-msgstr ""
+msgstr "Indlejret"
msgid "Input host keys manually"
msgstr ""
@@ -17710,7 +17845,7 @@ msgid "Input the remote repository URL"
msgstr ""
msgid "Insert"
-msgstr ""
+msgstr "Indsæt"
msgid "Insert a %{rows}x%{cols} table."
msgstr ""
@@ -17719,31 +17854,43 @@ msgid "Insert a code block"
msgstr ""
msgid "Insert a quote"
-msgstr ""
+msgstr "Indsæt et citat"
msgid "Insert a video"
-msgstr ""
+msgstr "Indsæt en video"
msgid "Insert an image"
-msgstr ""
+msgstr "Indsæt et billede"
msgid "Insert code"
+msgstr "Indsæt kode"
+
+msgid "Insert column after"
msgstr ""
-msgid "Insert image"
+msgid "Insert column before"
msgstr ""
+msgid "Insert image"
+msgstr "Indsæt billede"
+
msgid "Insert inline code"
msgstr ""
msgid "Insert link"
+msgstr "Indsæt link"
+
+msgid "Insert row after"
msgstr ""
-msgid "Insert suggestion"
+msgid "Insert row before"
msgstr ""
+msgid "Insert suggestion"
+msgstr "Indsæt forslag"
+
msgid "Insert video"
-msgstr ""
+msgstr "Indsæt video"
msgid "Insights"
msgstr ""
@@ -17761,12 +17908,12 @@ msgid "Install on clusters"
msgstr ""
msgid "Installation"
-msgstr ""
+msgstr "Installation"
msgid "Instance"
msgid_plural "Instances"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Instans"
+msgstr[1] "Instanser"
msgid "Instance Configuration"
msgstr ""
@@ -17793,16 +17940,16 @@ msgid "Insufficient permissions"
msgstr ""
msgid "Integration"
-msgstr ""
+msgstr "Integration"
msgid "Integration Settings"
-msgstr ""
+msgstr "Integreringsindstillinger"
msgid "Integrations"
-msgstr ""
+msgstr "Integrationer"
msgid "Integrations|%{integrationTitle}: active"
-msgstr ""
+msgstr "%{integrationTitle}: aktiv"
msgid "Integrations|%{integration} settings saved and active."
msgstr ""
@@ -17811,21 +17958,24 @@ msgid "Integrations|%{integration} settings saved, but not active."
msgstr ""
msgid "Integrations|Active integrations"
-msgstr ""
+msgstr "Aktive integreringer"
msgid "Integrations|Add an integration"
-msgstr ""
+msgstr "Tilføj en integrering"
msgid "Integrations|Add namespace"
-msgstr ""
+msgstr "Tilføj navnerum"
msgid "Integrations|Adding a namespace works only in browsers that allow cross‑site cookies. Use %{firefox_link_start}Firefox%{link_end}, %{chrome_link_start}Google Chrome%{link_end}, or enable cross‑site cookies in your browser, when adding a namespace."
msgstr ""
msgid "Integrations|All details"
-msgstr ""
+msgstr "Alle detaljer"
msgid "Integrations|All projects inheriting these settings will also be reset."
+msgstr "Alle projekter som nedarver indstillingerne nulstilles også."
+
+msgid "Integrations|An error occurred while loading projects using custom settings."
msgstr ""
msgid "Integrations|Browser limitations"
@@ -17844,28 +17994,28 @@ msgid "Integrations|Connection successful."
msgstr ""
msgid "Integrations|Create new issue in Jira"
-msgstr ""
+msgstr "Opret ny problemstilling i Jira"
msgid "Integrations|Default settings are inherited from the group level."
-msgstr ""
+msgstr "Standardindstillinger nedarves fra gruppeniveauet."
msgid "Integrations|Default settings are inherited from the instance level."
-msgstr ""
+msgstr "Standardindstillinger nedarves fra instansniveauet."
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
msgid "Integrations|Enable comments"
-msgstr ""
+msgstr "Aktivér kommentarer"
msgid "Integrations|Failed to link namespace. Please try again."
-msgstr ""
+msgstr "Kunne ikke linke navnerum. Prøv venligst igen."
msgid "Integrations|Failed to load namespaces. Please try again."
-msgstr ""
+msgstr "Kunne ikke indlæse navnerum. Prøv venligst igen."
msgid "Integrations|Failed to unlink namespace. Please try again."
-msgstr ""
+msgstr "Kunne ikke aflinke navnerum. Prøv venligst igen."
msgid "Integrations|GitLab administrators can set up integrations that all groups and projects inherit and use by default. These integrations apply to all groups and projects that don't already use custom settings. You can override custom settings for a group or project if the settings are necessary at that level. Learn more about %{integrations_link_start}instance-level integration management%{link_end}."
msgstr ""
@@ -17892,7 +18042,7 @@ msgid "Integrations|Keep your PHP dependencies updated on Packagist."
msgstr ""
msgid "Integrations|Link namespaces"
-msgstr ""
+msgstr "Link navnerum"
msgid "Integrations|Linked namespaces"
msgstr ""
@@ -17904,7 +18054,7 @@ msgid "Integrations|Namespaces are the GitLab groups and subgroups you link to t
msgstr ""
msgid "Integrations|No available namespaces."
-msgstr ""
+msgstr "Ingen tilgængelige navnerum."
msgid "Integrations|No linked namespaces"
msgstr ""
@@ -17922,22 +18072,22 @@ msgid "Integrations|Projects using custom settings will not be impacted unless t
msgstr ""
msgid "Integrations|Reset integration?"
-msgstr ""
+msgstr "Nulstil integrering?"
msgid "Integrations|Resetting this integration will clear the settings and deactivate this integration."
-msgstr ""
+msgstr "Nulstilling af integreringen rydder indstillingerne og deaktiverer integreringen."
msgid "Integrations|Return to GitLab for Jira"
-msgstr ""
+msgstr "Vend tilbage til GitLab for Jira"
msgid "Integrations|Save settings?"
-msgstr ""
+msgstr "Gem indstillinger?"
msgid "Integrations|Saving will update the default settings for all projects that are not using custom settings."
msgstr ""
msgid "Integrations|Search Jira issues"
-msgstr ""
+msgstr "Søg efter Jira-problemstillinger"
msgid "Integrations|Send notifications about project events to Unify Circuit."
msgstr ""
@@ -17946,6 +18096,9 @@ msgid "Integrations|Sign in to add namespaces"
msgstr ""
msgid "Integrations|Standard"
+msgstr "Standard"
+
+msgid "Integrations|There are no projects using custom settings"
msgstr ""
msgid "Integrations|This integration, and inheriting projects were reset."
@@ -17958,7 +18111,7 @@ msgid "Integrations|Use custom settings"
msgstr ""
msgid "Integrations|Use default settings"
-msgstr ""
+msgstr "Brug standardindstillinger"
msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
msgstr ""
@@ -17979,28 +18132,28 @@ msgid "Integrations|You've activated every integration 🎉"
msgstr ""
msgid "Interactive mode"
-msgstr ""
+msgstr "Interaktiv tilstand"
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
msgid "Internal"
-msgstr ""
+msgstr "Interne"
msgid "Internal - The group and any internal projects can be viewed by any logged in user except external users."
-msgstr ""
+msgstr "Interne - gruppen og interne projekter kan vises af brugere som er logget ind, undtagen eksterne brugere."
msgid "Internal - The project can be accessed by any logged in user except external users."
-msgstr ""
+msgstr "Interne - projektet kan tilgås af brugere som er logget ind, undtagen eksterne brugere."
msgid "Internal URL (optional)"
-msgstr ""
+msgstr "Intern URL (valgfrit)"
msgid "Internal users"
-msgstr ""
+msgstr "Interne brugere"
msgid "Internal users cannot be deactivated"
-msgstr ""
+msgstr "Interne brugere kan ikke deaktiveres"
msgid "Interval Pattern"
msgstr ""
@@ -18015,13 +18168,13 @@ msgid "Invalid Insights config file detected"
msgstr ""
msgid "Invalid OS"
-msgstr ""
+msgstr "Ugyldigt styresystem"
msgid "Invalid URL"
-msgstr ""
+msgstr "Ugyldig URL"
msgid "Invalid container_name"
-msgstr ""
+msgstr "Ugyldig container_name"
msgid "Invalid cursor parameter"
msgstr ""
@@ -18030,115 +18183,112 @@ msgid "Invalid cursor value provided"
msgstr ""
msgid "Invalid date"
-msgstr ""
+msgstr "Ugyldig dato"
msgid "Invalid date format. Please use UTC format as YYYY-MM-DD"
-msgstr ""
+msgstr "Ugyldigt datoformat. Brug venligst UTC-format såsom ÅÅÅÅ-MM-DD"
msgid "Invalid date range"
msgstr ""
msgid "Invalid feature"
-msgstr ""
+msgstr "Ugyldig funktion"
msgid "Invalid field"
-msgstr ""
+msgstr "Ugyldigt felt"
msgid "Invalid file format with specified file type"
-msgstr ""
+msgstr "Ugyldigt filformat med angivne filtype"
msgid "Invalid file."
-msgstr ""
+msgstr "Ugyldig fil."
msgid "Invalid hash"
-msgstr ""
+msgstr "Ugyldig hash"
msgid "Invalid import params"
msgstr ""
msgid "Invalid input, please avoid emojis"
-msgstr ""
+msgstr "Ugyldig indtastning, undgå venligst emojier"
msgid "Invalid login or password"
-msgstr ""
+msgstr "Ugyldigt login eller adgangskode"
msgid "Invalid period"
-msgstr ""
+msgstr "Ugyldig periode"
msgid "Invalid pin code"
-msgstr ""
+msgstr "Ugyldig pinkode"
msgid "Invalid pod_name"
-msgstr ""
+msgstr "Ugyldig pod_name"
msgid "Invalid policy type"
-msgstr ""
+msgstr "Ugyldig regelsættype"
msgid "Invalid query"
-msgstr ""
+msgstr "Ugyldig forespørgsel"
msgid "Invalid repository bundle for snippet with id %{snippet_id}"
msgstr ""
msgid "Invalid repository path"
-msgstr ""
+msgstr "Ugyldig depotsti"
msgid "Invalid search parameter"
msgstr ""
msgid "Invalid server response"
-msgstr ""
+msgstr "Ugyldigt serversvar"
msgid "Invalid start or end time format"
msgstr ""
msgid "Invalid status"
-msgstr ""
+msgstr "Ugyldig status"
msgid "Invalid two-factor code."
-msgstr ""
+msgstr "Ugyldig tofaktorkode."
msgid "Invalid yaml"
-msgstr ""
+msgstr "Ugyldig yaml"
msgid "Investigate vulnerability: %{title}"
msgstr ""
msgid "Invitation"
-msgstr ""
+msgstr "Invitation"
msgid "Invitation declined"
msgstr ""
msgid "Invite"
-msgstr ""
+msgstr "Inviter"
msgid "Invite \"%{email}\" by email"
-msgstr ""
+msgstr "Inviter \"%{email}\" via e-mail"
msgid "Invite \"%{trimmed}\" by email"
-msgstr ""
+msgstr "Inviter \"%{trimmed}\" via e-mail"
msgid "Invite Members"
-msgstr ""
+msgstr "Inviter medlemmer"
msgid "Invite a group"
-msgstr ""
+msgstr "Inviter en gruppe"
msgid "Invite email has already been taken"
msgstr ""
msgid "Invite group"
-msgstr ""
+msgstr "Inviter gruppe"
msgid "Invite member"
-msgstr ""
+msgstr "Inviter medlem"
msgid "Invite members"
-msgstr ""
-
-msgid "Invite your team"
-msgstr ""
+msgstr "Inviter medlemmer"
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18165,10 +18315,10 @@ msgid "InviteEmail|Projects are used to host and collaborate on code, track issu
msgstr ""
msgid "InviteEmail|What's it about?"
-msgstr ""
+msgstr "Hvad handler det om?"
msgid "InviteEmail|You are invited to join the %{strong_start}%{project_or_group_name}%{strong_end}%{br_tag}%{project_or_group} as a %{role}"
-msgstr ""
+msgstr "Du inviteres til at deltage i %{strong_start}%{project_or_group_name}%{strong_end}%{br_tag}%{project_or_group} som en %{role}"
msgid "InviteEmail|You have been invited to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18189,7 +18339,7 @@ msgid "InviteMembersModal|Access expiration date (optional)"
msgstr ""
msgid "InviteMembersModal|Cancel"
-msgstr ""
+msgstr "Annuller"
msgid "InviteMembersModal|Close invite team members"
msgstr ""
@@ -18198,7 +18348,7 @@ msgid "InviteMembersModal|Collaborate on open issues and merge requests"
msgstr ""
msgid "InviteMembersModal|Configure CI/CD"
-msgstr ""
+msgstr "Konfigurer CI/CD"
msgid "InviteMembersModal|Configure security features"
msgstr ""
@@ -18210,13 +18360,13 @@ msgid "InviteMembersModal|GitLab member or email address"
msgstr ""
msgid "InviteMembersModal|Invite"
-msgstr ""
+msgstr "Inviter"
msgid "InviteMembersModal|Invite a group"
-msgstr ""
+msgstr "Inviter en gruppe"
msgid "InviteMembersModal|Invite members"
-msgstr ""
+msgstr "Inviter medlemmer"
msgid "InviteMembersModal|Members were successfully added"
msgstr ""
@@ -18231,52 +18381,52 @@ msgid "InviteMembersModal|Select a group to invite"
msgstr ""
msgid "InviteMembersModal|Select a role"
-msgstr ""
+msgstr "Vælg en rolle"
msgid "InviteMembersModal|Select members or type email addresses"
-msgstr ""
+msgstr "Vælg medlemmer eller skriv e-mailadresser"
msgid "InviteMembersModal|Something went wrong"
-msgstr ""
+msgstr "Noget gik galt"
msgid "InviteMembersModal|What would you like new member(s) to focus on? (optional)"
msgstr ""
msgid "InviteMembersModal|You're inviting a group to the %{strongStart}%{name}%{strongEnd} group."
-msgstr ""
+msgstr "Du inviterer en gruppe til gruppen %{strongStart}%{name}%{strongEnd}."
msgid "InviteMembersModal|You're inviting a group to the %{strongStart}%{name}%{strongEnd} project."
-msgstr ""
+msgstr "Du inviterer en gruppe til projektet %{strongStart}%{name}%{strongEnd}."
msgid "InviteMembersModal|You're inviting members to the %{strongStart}%{name}%{strongEnd} group."
-msgstr ""
+msgstr "Du inviterer medlemmer til gruppen %{strongStart}%{name}%{strongEnd}."
msgid "InviteMembersModal|You're inviting members to the %{strongStart}%{name}%{strongEnd} project."
-msgstr ""
+msgstr "Du inviterer medlemmer til projektet %{strongStart}%{name}%{strongEnd}."
msgid "InviteMembers|Invite a group"
-msgstr ""
+msgstr "Inviter en gruppe"
msgid "InviteMembers|Invite team members"
-msgstr ""
+msgstr "Inviter teammedlemmer"
msgid "InviteMember|Add members to this project and start collaborating with your team."
-msgstr ""
+msgstr "Tilføj medlemmer til projektet og begynd at samarbejde med dit team."
msgid "InviteMember|Invite Member"
-msgstr ""
+msgstr "Inviter medlem"
msgid "InviteMember|Invite Members (optional)"
-msgstr ""
+msgstr "Inviter medlemmer (valgfrit)"
msgid "InviteMember|Invite another member"
msgstr ""
msgid "InviteMember|Invite members"
-msgstr ""
+msgstr "Inviter medlemmer"
msgid "InviteMember|Invite your team"
-msgstr ""
+msgstr "Inviter dit team"
msgid "InviteMember|Invited users will be added with developer level permissions. %{linkStart}View the documentation%{linkEnd} to see how to change this later."
msgstr ""
@@ -18294,22 +18444,22 @@ msgid "InviteReminderEmail|%{inviter}'s invitation to GitLab is pending"
msgstr ""
msgid "InviteReminderEmail|Accept invitation"
-msgstr ""
+msgstr "Accepter invitation"
msgid "InviteReminderEmail|Accept invitation: %{invite_url}"
-msgstr ""
+msgstr "Accepter invitation: %{invite_url}"
msgid "InviteReminderEmail|Decline invitation"
-msgstr ""
+msgstr "Afvis invitation"
msgid "InviteReminderEmail|Decline invitation: %{decline_url}"
-msgstr ""
+msgstr "Afvis invitation: %{decline_url}"
msgid "InviteReminderEmail|Hey there %{wave_emoji}"
-msgstr ""
+msgstr "Hej med dig %{wave_emoji}"
msgid "InviteReminderEmail|Hey there!"
-msgstr ""
+msgstr "Hej med dig!"
msgid "InviteReminderEmail|In case you missed it..."
msgstr ""
@@ -18324,7 +18474,7 @@ msgid "InviteReminderEmail|This is a friendly reminder that %{inviter} invited y
msgstr ""
msgid "Invited"
-msgstr ""
+msgstr "Inviteret"
msgid "Invocations"
msgstr ""
@@ -18348,10 +18498,10 @@ msgid "IrkerService|Send update messages to an irker server. Before you can use
msgstr ""
msgid "IrkerService|Server host (optional)"
-msgstr ""
+msgstr "Servervært (valgfrit)"
msgid "IrkerService|Server port (optional)"
-msgstr ""
+msgstr "Serverport (valgfrit)"
msgid "IrkerService|URI to add before each recipient."
msgstr ""
@@ -18366,7 +18516,7 @@ msgid "IrkerService|irker daemon port (defaults to 6659)."
msgstr ""
msgid "Is blocked by"
-msgstr ""
+msgstr "Blokeres af"
msgid "Is this GitLab trial for your company?"
msgstr ""
@@ -18393,7 +18543,7 @@ msgid "IssuableStatus|promoted"
msgstr ""
msgid "Issue"
-msgstr ""
+msgstr "Problemstilling"
msgid "Issue %{issue_reference} has already been added to epic %{epic_reference}."
msgstr ""
@@ -18402,16 +18552,16 @@ msgid "Issue Analytics"
msgstr ""
msgid "Issue Boards"
-msgstr ""
+msgstr "Problemstillingstavler"
msgid "Issue Type"
-msgstr ""
+msgstr "Problemstillingstype"
msgid "Issue already promoted to epic."
msgstr ""
msgid "Issue cannot be found."
-msgstr ""
+msgstr "Problemstillingen kan ikke findes."
msgid "Issue created from vulnerability %{vulnerability_link}"
msgstr ""
@@ -18420,7 +18570,7 @@ msgid "Issue creation requests"
msgstr ""
msgid "Issue details"
-msgstr ""
+msgstr "Problemstillingsdetaljer"
msgid "Issue events"
msgstr ""
@@ -18438,7 +18588,7 @@ msgid "Issue published on status page."
msgstr ""
msgid "Issue types"
-msgstr ""
+msgstr "Problemstillingstyper"
msgid "Issue update failed"
msgstr ""
@@ -18453,46 +18603,46 @@ msgid "Issue(s) already assigned"
msgstr ""
msgid "IssueAnalytics|Age"
-msgstr ""
+msgstr "Alder"
msgid "IssueAnalytics|Assignees"
msgstr ""
msgid "IssueAnalytics|Due date"
-msgstr ""
+msgstr "Forfaldsdato"
msgid "IssueAnalytics|Failed to load issues. Please try again."
-msgstr ""
+msgstr "Kunne ikke indlæse problemstillinger. Prøv venligst igen."
msgid "IssueAnalytics|Issue"
-msgstr ""
+msgstr "Problemstilling"
msgid "IssueAnalytics|Milestone"
-msgstr ""
+msgstr "Milepæl"
msgid "IssueAnalytics|Opened by"
-msgstr ""
+msgstr "Ã…bnet af"
msgid "IssueAnalytics|Status"
-msgstr ""
+msgstr "Status"
msgid "IssueAnalytics|Weight"
-msgstr ""
+msgstr "Vægt"
msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
msgstr ""
msgid "IssueBoards|Board"
-msgstr ""
+msgstr "Tavle"
msgid "IssueBoards|Boards"
-msgstr ""
+msgstr "Tavler"
msgid "IssueBoards|Create new board"
-msgstr ""
+msgstr "Opret ny tavle"
msgid "IssueBoards|Delete board"
-msgstr ""
+msgstr "Slet tavle"
msgid "IssueBoards|No matching boards found"
msgstr ""
@@ -18501,7 +18651,7 @@ msgid "IssueBoards|Some of your boards are hidden, activate a license to see the
msgstr ""
msgid "IssueBoards|Switch board"
-msgstr ""
+msgstr "Skift tavle"
msgid "IssueTracker|Custom issue tracker"
msgstr ""
@@ -18558,7 +18708,7 @@ msgid "IssueTracker|Use a custom issue tracker that is not in the integration li
msgstr ""
msgid "Issues"
-msgstr ""
+msgstr "Problemstillinger"
msgid "Issues Rate Limits"
msgstr ""
@@ -18603,7 +18753,7 @@ msgid "IssuesAnalytics|Issues opened per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
-msgstr ""
+msgstr "Sidste 12 måneder"
msgid "IssuesAnalytics|Sorry, your filter produced no results"
msgstr ""
@@ -18618,7 +18768,7 @@ msgid "IssuesAnalytics|Total:"
msgstr ""
msgid "Issue|Title"
-msgstr ""
+msgstr "Titel"
msgid "It is not possible to %{action} files that are stored in LFS using the web interface"
msgstr ""
@@ -18642,31 +18792,31 @@ msgid "It's you"
msgstr ""
msgid "Italic text"
-msgstr ""
+msgstr "Kursiv tekst"
msgid "Iteration"
-msgstr ""
+msgstr "Gennemløb"
msgid "Iteration changed to"
-msgstr ""
+msgstr "Gennemløb ændret til"
msgid "Iteration lists not available with your current license"
-msgstr ""
+msgstr "Gennemløbslister ikke tilgængelige med din nuværende licens"
msgid "Iteration removed"
-msgstr ""
+msgstr "Gennemløb fjernet"
msgid "Iteration updated"
-msgstr ""
+msgstr "Gennemløb opdateret"
msgid "Iterations"
-msgstr ""
+msgstr "Gennemløb"
msgid "Iterations|Add iteration"
-msgstr ""
+msgstr "Tilføj gennemløb"
msgid "Iterations|Automated scheduling"
-msgstr ""
+msgstr "Automatiseret planlægning"
msgid "Iterations|Cadence name"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -18684,13 +18837,13 @@ msgid "Iterations|Delete iteration cadence?"
msgstr ""
msgid "Iterations|Duration"
-msgstr ""
+msgstr "Varighed"
msgid "Iterations|Edit cadence"
msgstr ""
msgid "Iterations|Edit iteration"
-msgstr ""
+msgstr "Rediger gennemløb"
msgid "Iterations|Edit iteration cadence"
msgstr ""
@@ -18711,7 +18864,7 @@ msgid "Iterations|Move incomplete issues to the next iteration"
msgstr ""
msgid "Iterations|New iteration"
-msgstr ""
+msgstr "Nyt gennemløb"
msgid "Iterations|New iteration cadence"
msgstr ""
@@ -18732,16 +18885,16 @@ msgid "Iterations|Save cadence"
msgstr ""
msgid "Iterations|Select duration"
-msgstr ""
+msgstr "Vælg varighed"
msgid "Iterations|Select number"
msgstr ""
msgid "Iterations|Select start date"
-msgstr ""
+msgstr "Vælg startdato"
msgid "Iterations|Start date"
-msgstr ""
+msgstr "Startdato"
msgid "Iterations|The duration for each iteration (in weeks)"
msgstr ""
@@ -18753,10 +18906,10 @@ msgid "Iterations|This will delete the cadence as well as all of the iterations
msgstr ""
msgid "Iterations|Title"
-msgstr ""
+msgstr "Titel"
msgid "Iterations|Unable to find iteration."
-msgstr ""
+msgstr "Kan ikke finde gennemløb."
msgid "Iteration|Dates cannot overlap with other existing Iterations within this group"
msgstr ""
@@ -18765,7 +18918,7 @@ msgid "Iteration|Dates cannot overlap with other existing Iterations within this
msgstr ""
msgid "Iteration|cannot be more than 500 years in the future"
-msgstr ""
+msgstr "må ikke være mere end 500 år ud i fremtiden"
msgid "I’m familiar with the basics of DevOps."
msgstr ""
@@ -18774,22 +18927,22 @@ msgid "I’m joining my team who’s already on GitLab"
msgstr ""
msgid "I’m not familiar with the basics of DevOps."
-msgstr ""
+msgstr "Jeg er ikke bekendt med det grundlæggende i DevOps."
msgid "Jaeger URL"
-msgstr ""
+msgstr "Jaeger-URL"
msgid "Jan"
-msgstr ""
+msgstr "Jan."
msgid "January"
-msgstr ""
+msgstr "Januar"
msgid "Japanese language support using"
msgstr ""
msgid "Jira Issues"
-msgstr ""
+msgstr "Jira-problemstillinger"
msgid "Jira display name"
msgstr ""
@@ -18810,7 +18963,7 @@ msgid "Jira service not configured."
msgstr ""
msgid "Jira user"
-msgstr ""
+msgstr "Jira-bruger"
msgid "Jira users have been imported from the configured Jira instance. They can be mapped by selecting a GitLab user from the dropdown in the \"GitLab username\" column. When the form appears, the dropdown defaults to the user conducting the import."
msgstr ""
@@ -18822,10 +18975,10 @@ msgid "JiraConnect|Create branch for Jira issue %{jiraIssue}"
msgstr ""
msgid "JiraConnect|Failed to create branch."
-msgstr ""
+msgstr "Kunne ikke oprette gren."
msgid "JiraConnect|Failed to create branch. Please try again."
-msgstr ""
+msgstr "Kunne ikke oprette gren. Prøv venligst igen."
msgid "JiraConnect|New branch was successfully created."
msgstr ""
@@ -18915,7 +19068,7 @@ msgid "JiraService|Fetch issue types for this Jira project"
msgstr ""
msgid "JiraService|For example, 12, 24"
-msgstr ""
+msgstr "F.eks. 12, 24"
msgid "JiraService|For example, AB"
msgstr ""
@@ -18978,7 +19131,7 @@ msgid "JiraService|Project key is required to generate issue types"
msgstr ""
msgid "JiraService|Select issue type"
-msgstr ""
+msgstr "Vælg problemstillingstype"
msgid "JiraService|Set a custom final state by using transition IDs. %{linkStart}Learn about transition IDs%{linkEnd}"
msgstr ""
@@ -19017,7 +19170,7 @@ msgid "JiraService|Use custom transitions"
msgstr ""
msgid "JiraService|Username or Email"
-msgstr ""
+msgstr "Brugernavn eller e-mail"
msgid "JiraService|Using Jira for issue tracking?"
msgstr ""
@@ -19038,19 +19191,19 @@ msgid "JiraService|You need to configure Jira before enabling this integration.
msgstr ""
msgid "Job"
-msgstr ""
+msgstr "Job"
msgid "Job Failed #%{build_id}"
msgstr ""
msgid "Job ID"
-msgstr ""
+msgstr "Job-id"
msgid "Job artifact"
-msgstr ""
+msgstr "Jobartefakt"
msgid "Job artifacts"
-msgstr ""
+msgstr "Jobartefakter"
msgid "Job has been erased"
msgstr ""
@@ -19062,7 +19215,7 @@ msgid "Job has wrong arguments format."
msgstr ""
msgid "Job is missing the `model_type` argument."
-msgstr ""
+msgstr "Jobbet mangler argumentet `model_type`."
msgid "Job is stuck. Check runners."
msgstr ""
@@ -19080,7 +19233,7 @@ msgid "Job was retried"
msgstr ""
msgid "Jobs"
-msgstr ""
+msgstr "Job"
msgid "Jobs fail if they run longer than the timeout time. Input value is in seconds by default. Human readable input is also accepted, for example %{code_open}1 hour%{code_close}."
msgstr ""
@@ -19089,10 +19242,10 @@ msgid "Jobs older than the configured time are considered expired and are archiv
msgstr ""
msgid "Jobs|Are you sure you want to proceed?"
-msgstr ""
+msgstr "Er du sikker på, at du vil fortsætte?"
msgid "Jobs|Are you sure you want to retry this job?"
-msgstr ""
+msgstr "Er du sikker på, at du vil prøve jobbet igen?"
msgid "Jobs|Create CI/CD configuration file"
msgstr ""
@@ -19113,19 +19266,19 @@ msgid "Jobs|You're about to retry a job that failed because it attempted to depl
msgstr ""
msgid "Job|Browse"
-msgstr ""
+msgstr "Gennemse"
msgid "Job|Complete Raw"
msgstr ""
msgid "Job|Download"
-msgstr ""
+msgstr "Download"
msgid "Job|Erase job log"
msgstr ""
msgid "Job|Job artifacts"
-msgstr ""
+msgstr "Jobartefakter"
msgid "Job|Job has been erased"
msgstr ""
@@ -19134,25 +19287,25 @@ msgid "Job|Job has been erased by %{userLink}"
msgstr ""
msgid "Job|Keep"
-msgstr ""
+msgstr "Behold"
msgid "Job|Pipeline"
-msgstr ""
+msgstr "Pipeline"
msgid "Job|Scroll to bottom"
-msgstr ""
+msgstr "Rul nederst"
msgid "Job|Scroll to top"
-msgstr ""
+msgstr "Rul øverst"
msgid "Job|Show complete raw"
msgstr ""
msgid "Job|The artifacts were removed"
-msgstr ""
+msgstr "Artefakterne blev fjernet"
msgid "Job|The artifacts will be removed"
-msgstr ""
+msgstr "Artefakterne vil blive fjernet"
msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
msgstr ""
@@ -19173,7 +19326,7 @@ msgid "Job|allowed to fail"
msgstr ""
msgid "Job|delayed"
-msgstr ""
+msgstr "forsinket"
msgid "Job|for"
msgstr ""
@@ -19185,13 +19338,13 @@ msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
-msgstr ""
+msgstr "udløst"
msgid "Job|with"
-msgstr ""
+msgstr "med"
msgid "Join Zoom meeting"
-msgstr ""
+msgstr "Deltag i Zoom-møde"
msgid "Joined %{time_ago}"
msgstr ""
@@ -19203,31 +19356,31 @@ msgid "Joined projects (%{projects_count})"
msgstr ""
msgid "Jul"
-msgstr ""
+msgstr "Jul."
msgid "July"
-msgstr ""
+msgstr "Juli"
msgid "Jump to next unresolved thread"
-msgstr ""
+msgstr "Hop til næste uløste tråd"
msgid "Jun"
-msgstr ""
+msgstr "Jun."
msgid "June"
-msgstr ""
+msgstr "Juni"
msgid "Just me"
-msgstr ""
+msgstr "Kun mig"
msgid "K8s pod health"
msgstr ""
msgid "KEY"
-msgstr ""
+msgstr "NØGLE"
msgid "Keep"
-msgstr ""
+msgstr "Behold"
msgid "Keep artifacts from most recent successful jobs"
msgstr ""
@@ -19245,64 +19398,64 @@ msgid "Kerberos access denied"
msgstr ""
msgid "Key"
-msgstr ""
+msgstr "Nøgle"
msgid "Key (PEM)"
-msgstr ""
+msgstr "Nøgle (PEM)"
msgid "Key: %{key}"
-msgstr ""
+msgstr "Nøgle: %{key}"
msgid "Keyboard shortcuts"
-msgstr ""
+msgstr "Tastaturgenveje"
msgid "KeyboardKey|Alt"
-msgstr ""
+msgstr "Alt"
msgid "KeyboardKey|Ctrl"
-msgstr ""
+msgstr "Ctrl"
msgid "KeyboardKey|Ctrl+"
-msgstr ""
+msgstr "Ctrl+"
msgid "KeyboardKey|Enter"
-msgstr ""
+msgstr "Enter"
msgid "KeyboardKey|Esc"
-msgstr ""
+msgstr "Esc"
msgid "KeyboardKey|Shift"
-msgstr ""
+msgstr "Skift"
msgid "KeyboardShortcuts|No shortcuts matched your search"
-msgstr ""
+msgstr "Ingen genveje passede til din søgning"
msgid "KeyboardShortcuts|Search keyboard shortcuts"
-msgstr ""
+msgstr "Søg efter tastaturgenveje"
msgid "Keys"
-msgstr ""
+msgstr "Nøgler"
msgid "Ki"
-msgstr ""
+msgstr "Ki"
msgid "Kroki"
msgstr ""
msgid "Kubernetes"
-msgstr ""
+msgstr "Kubernetes"
msgid "Kubernetes API returned status code: %{error_code}"
msgstr ""
msgid "Kubernetes Cluster"
-msgstr ""
+msgstr "Kubernetes-klynge"
msgid "Kubernetes Clusters"
-msgstr ""
+msgstr "Kubernetes-klynger"
msgid "Kubernetes cluster"
-msgstr ""
+msgstr "Kubernetes-klynge"
msgid "Kubernetes cluster creation time exceeds timeout; %{timeout}"
msgstr ""
@@ -19317,85 +19470,82 @@ msgid "Kubernetes cluster was successfully updated."
msgstr ""
msgid "Kubernetes clusters"
-msgstr ""
+msgstr "Kubernetes-klynger"
msgid "Kubernetes deployment not found"
-msgstr ""
+msgstr "Kubernetes-udsendelse ikke fundet"
msgid "Kubernetes error: %{error_code}"
msgstr ""
msgid "LDAP"
-msgstr ""
+msgstr "LDAP"
msgid "LDAP Synchronization"
-msgstr ""
+msgstr "LDAP-synkronisering"
msgid "LDAP group settings"
-msgstr ""
+msgstr "LDAP-gruppeindstillinger"
msgid "LDAP settings"
-msgstr ""
+msgstr "LDAP-indstillinger"
msgid "LDAP settings updated"
-msgstr ""
+msgstr "LDAP-indstillinger opdateret"
msgid "LDAP sync in progress. This could take a few minutes. Refresh the page to see the changes."
msgstr ""
msgid "LDAP synchronizations"
-msgstr ""
+msgstr "LDAP-synkroniseringer"
msgid "LDAP uid:"
msgstr ""
msgid "LFS"
-msgstr ""
+msgstr "LFS"
msgid "LFS objects"
-msgstr ""
+msgstr "LFS-objekter"
msgid "LFSStatus|Disabled"
-msgstr ""
+msgstr "Deaktiveret"
msgid "LFSStatus|Enabled"
-msgstr ""
+msgstr "Aktiveret"
msgid "LICENSE"
-msgstr ""
+msgstr "LICENSE"
msgid "Label"
-msgstr ""
+msgstr "Etiket"
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
-msgstr ""
+msgstr "Etiketprioritet"
msgid "Label was created"
-msgstr ""
+msgstr "Etiketten blev oprettet"
msgid "Label was removed"
-msgstr ""
+msgstr "Etiketten blev fjernet"
msgid "Label was successfully updated."
-msgstr ""
+msgstr "Etiketten blev opdateret."
msgid "LabelSelect|%{firstLabelName} +%{remainingLabelCount} more"
-msgstr ""
+msgstr "%{firstLabelName} +%{remainingLabelCount} mere"
msgid "LabelSelect|%{labelsString}, and %{remainingLabelCount} more"
-msgstr ""
+msgstr "%{labelsString} og %{remainingLabelCount} mere"
msgid "LabelSelect|Labels"
-msgstr ""
+msgstr "Etiketter"
msgid "Labels"
-msgstr ""
+msgstr "Etiketter"
msgid "Labels can be applied to %{features}. Group labels are available for any project within the group."
msgstr ""
@@ -19419,60 +19569,60 @@ msgid "Labels|Promoting %{labelTitle} will make it available for all projects in
msgstr ""
msgid "Language"
-msgstr ""
+msgstr "Sprog"
msgid "Large File Storage"
msgstr ""
msgid "Last %d day"
msgid_plural "Last %d days"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Sidste %d dag"
+msgstr[1] "Sidste %d dage"
msgid "Last %{days} days"
-msgstr ""
+msgstr "Sidste %{days} dage"
msgid "Last 2 weeks"
-msgstr ""
+msgstr "Sidste 2 uger"
msgid "Last 30 days"
-msgstr ""
+msgstr "Sidste 30 dage"
msgid "Last 60 days"
-msgstr ""
+msgstr "Sidste 60 dage"
msgid "Last 90 days"
-msgstr ""
+msgstr "Sidste 90 dage"
msgid "Last Accessed On"
-msgstr ""
+msgstr "Sidst tilgået"
msgid "Last Activity"
-msgstr ""
+msgstr "Sidste aktivitet"
msgid "Last Pipeline"
-msgstr ""
+msgstr "Sidste pipeline"
msgid "Last Seen"
-msgstr ""
+msgstr "Sidst set"
msgid "Last Used"
-msgstr ""
+msgstr "Sidst brugt"
msgid "Last accessed on"
-msgstr ""
+msgstr "Sidst tilgået"
msgid "Last activity"
-msgstr ""
+msgstr "Sidste aktivitet"
msgid "Last commit"
-msgstr ""
+msgstr "Sidste commit"
msgid "Last contact"
-msgstr ""
+msgstr "Sidste kontakt"
msgid "Last edited %{date}"
-msgstr ""
+msgstr "Sidst redigeret %{date}"
msgid "Last edited by %{link_start}%{avatar} %{name}%{link_end}"
msgstr ""
@@ -19481,13 +19631,13 @@ msgid "Last item before this page loaded in your browser:"
msgstr ""
msgid "Last modified"
-msgstr ""
+msgstr "Sidst ændret"
msgid "Last month"
-msgstr ""
+msgstr "Sidste måned"
msgid "Last name"
-msgstr ""
+msgstr "Efternavn"
msgid "Last reply by"
msgstr ""
@@ -19495,41 +19645,41 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
-msgstr ""
+msgstr "Sidst set"
msgid "Last sign-in"
-msgstr ""
+msgstr "Sidste indlogning"
msgid "Last sign-in IP:"
-msgstr ""
+msgstr "Sidste indlognings-IP:"
msgid "Last sign-in at:"
msgstr ""
msgid "Last successful sync"
-msgstr ""
+msgstr "Sidste synkronisering som lykkedes"
msgid "Last successful update"
+msgstr "Sidste opdatering som lykkedes"
+
+msgid "Last time checked"
msgstr ""
msgid "Last time verified"
msgstr ""
msgid "Last update"
-msgstr ""
+msgstr "Sidste opdatering"
msgid "Last update attempt"
-msgstr ""
+msgstr "Sidste opdateringsforsøg"
msgid "Last updated"
-msgstr ""
+msgstr "Sidst opdateret"
msgid "Last used"
-msgstr ""
+msgstr "Sidst brugt"
msgid "Last used %{last_used_at} ago"
msgstr ""
@@ -19538,13 +19688,13 @@ msgid "Last used on:"
msgstr ""
msgid "Last week"
-msgstr ""
+msgstr "Sidste uge"
msgid "Last year"
-msgstr ""
+msgstr "Sidste år"
msgid "LastCommit|authored"
-msgstr ""
+msgstr "forfattede"
msgid "LastPushEvent|You pushed to"
msgstr ""
@@ -19553,7 +19703,7 @@ msgid "LastPushEvent|at"
msgstr ""
msgid "Latest changes"
-msgstr ""
+msgstr "Seneste ændringer"
msgid "Latest pipeline for the most recent commit on this branch"
msgstr ""
@@ -19568,19 +19718,19 @@ msgid "Lead time"
msgstr ""
msgid "Learn GitLab"
-msgstr ""
+msgstr "Lær GitLab"
msgid "Learn GitLab - Ultimate trial"
-msgstr ""
+msgstr "Lær GitLab - Ultimate-prøveperiode"
msgid "Learn GitLab|Trial only"
-msgstr ""
+msgstr "Kun prøveperiode"
msgid "Learn More"
-msgstr ""
+msgstr "Lær mere"
msgid "Learn More."
-msgstr ""
+msgstr "Lær mere."
msgid "Learn how to %{link_start}contribute to the built-in templates%{link_end}"
msgstr ""
@@ -19589,37 +19739,37 @@ msgid "Learn how to %{no_packages_link_start}publish and share your packages%{no
msgstr ""
msgid "Learn more"
-msgstr ""
+msgstr "Lær mere"
msgid "Learn more about %{link_start_tag}Jaeger configuration%{link_end_tag}."
-msgstr ""
+msgstr "Lær mere om %{link_start_tag}Jaeger-konfiguration%{link_end_tag}."
msgid "Learn more about %{username}"
-msgstr ""
+msgstr "Lær mere om %{username}"
msgid "Learn more about Auto DevOps"
-msgstr ""
+msgstr "Lær mere om Auto DevOps"
msgid "Learn more about Needs relationships"
msgstr ""
msgid "Learn more about Web Terminal"
-msgstr ""
+msgstr "Lær mere om Web Terminal"
msgid "Learn more about X.509 signed commits"
-msgstr ""
+msgstr "Lær mere om X.509-underskrevne commits"
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
msgid "Learn more about custom project templates"
-msgstr ""
+msgstr "Lær mere om tilpassede projektskabeloner"
msgid "Learn more about deploying to AWS"
-msgstr ""
+msgstr "Lær mere om udsendelse til AWS"
msgid "Learn more about deploying to a cluster"
-msgstr ""
+msgstr "Lær mere om udsendelse til en klynge"
msgid "Learn more about group-level project templates"
msgstr ""
@@ -19628,22 +19778,22 @@ msgid "Learn more about shards and replicas in the %{configuration_link_start}Ad
msgstr ""
msgid "Learn more about signing commits"
-msgstr ""
+msgstr "Lær mere om at underskrive commits"
msgid "Learn more in the"
-msgstr ""
+msgstr "Lær mere i"
msgid "Learn more in the|pipeline schedules documentation"
msgstr ""
msgid "Learn more."
-msgstr ""
+msgstr "Lær mere."
msgid "LearnGitLab|%{percentage}%{percentSymbol} completed"
-msgstr ""
+msgstr "%{percentage} %{percentSymbol} fuldført"
msgid "LearnGitLab|Add code owners"
-msgstr ""
+msgstr "Tilføj kodeejere"
msgid "LearnGitLab|Add merge request approval"
msgstr ""
@@ -19655,19 +19805,19 @@ msgid "LearnGitLab|Create a workflow for your new workspace, and learn how GitLa
msgstr ""
msgid "LearnGitLab|Create an issue"
-msgstr ""
+msgstr "Opret en problemstilling"
msgid "LearnGitLab|Create or import a repository"
msgstr ""
msgid "LearnGitLab|Create or import your first repository into your new project."
-msgstr ""
+msgstr "Opret eller importér dit første depot i dit nye projekt."
msgid "LearnGitLab|Create/import issues (tickets) to collaborate on ideas and plan work."
msgstr ""
msgid "LearnGitLab|Deploy"
-msgstr ""
+msgstr "Udsend"
msgid "LearnGitLab|Enable require merge approvals"
msgstr ""
@@ -19676,10 +19826,10 @@ msgid "LearnGitLab|GitLab works best as a team. Invite your colleague to enjoy a
msgstr ""
msgid "LearnGitLab|Invite your colleagues"
-msgstr ""
+msgstr "Inviter dine kollegaer"
msgid "LearnGitLab|Learn GitLab"
-msgstr ""
+msgstr "Lær GitLab"
msgid "LearnGitLab|Plan and execute"
msgstr ""
@@ -19706,25 +19856,25 @@ msgid "LearnGitLab|Scan your code to uncover vulnerabilities before deploying."
msgstr ""
msgid "LearnGitLab|Set up CI/CD"
-msgstr ""
+msgstr "Opsæt CI/CD"
msgid "LearnGitLab|Set up your workspace"
-msgstr ""
+msgstr "Opsæt dit arbejdsområde"
msgid "LearnGitLab|Set-up CI/CD"
-msgstr ""
+msgstr "Opsæt CI/CD"
msgid "LearnGitLab|Start a free Ultimate trial"
-msgstr ""
+msgstr "Start en gratis Ultimate-prøveperiode"
msgid "LearnGitLab|Submit a merge request"
-msgstr ""
+msgstr "Indsend en sammenlægningsanmodning"
msgid "LearnGitLab|Submit a merge request (MR)"
msgstr ""
msgid "LearnGitLab|Try GitLab Ultimate for free"
-msgstr ""
+msgstr "Prøv GitLab Ultimate, gratis"
msgid "LearnGitLab|Try all GitLab features for 30 days, no credit card required."
msgstr ""
@@ -19739,13 +19889,13 @@ msgid "LearnGitlab|Ok, let's go"
msgstr ""
msgid "LearnGitlab|Trial only"
-msgstr ""
+msgstr "Kun prøveperiode"
msgid "Leave"
-msgstr ""
+msgstr "Forlad"
msgid "Leave Admin Mode"
-msgstr ""
+msgstr "Forlad administratortilstand"
msgid "Leave blank for no limit. Once set, existing personal access tokens may be revoked."
msgstr ""
@@ -19754,13 +19904,13 @@ msgid "Leave edit mode? All unsaved changes will be lost."
msgstr ""
msgid "Leave group"
-msgstr ""
+msgstr "Forlad gruppe"
msgid "Leave project"
-msgstr ""
+msgstr "Forlad projekt"
msgid "Leave zen mode"
-msgstr ""
+msgstr "Forlad zen-tilstand"
msgid "Leaving this setting enabled is recommended."
msgstr ""
@@ -19772,40 +19922,40 @@ msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
msgid "Let's Encrypt is a free, automated, and open certificate authority (CA) that gives digital certificates in order to enable HTTPS (SSL/TLS) for websites. Learn more about Let's Encrypt configuration by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
-msgstr ""
+msgstr "Let's Encrypt er en gratis automatiserede open source certifikatmyndighed (CA) som giver digitale certifikater for at gøre det muligt at bruge HTTPS (SSL/TLS) på websteder. Lær mere om konfigurationen af Let's Encrypt ved at følge %{docs_link_start}dokumentationen på GitLab Pages%{docs_link_end}."
msgid "Let's talk!"
msgstr ""
msgid "License Compliance"
-msgstr ""
+msgstr "Licensoverholdelse"
msgid "License file"
-msgstr ""
+msgstr "Licensfil"
msgid "License overview"
-msgstr ""
+msgstr "Licensoversigt"
msgid "LicenseCompliance|%{docLinkStart}License Approvals%{docLinkEnd} are active"
-msgstr ""
+msgstr "%{docLinkStart}Licensgodkendelser%{docLinkEnd} er aktiv"
msgid "LicenseCompliance|%{docLinkStart}License Approvals%{docLinkEnd} are inactive"
-msgstr ""
+msgstr "%{docLinkStart}Licensgodkendelser%{docLinkEnd} er inaktiv"
msgid "LicenseCompliance|Acceptable license to be used in the project"
msgstr ""
msgid "LicenseCompliance|Add a license"
-msgstr ""
+msgstr "Tilføj en licens"
msgid "LicenseCompliance|Add license and related policy"
msgstr ""
msgid "LicenseCompliance|Allow"
-msgstr ""
+msgstr "Tillad"
msgid "LicenseCompliance|Allowed"
-msgstr ""
+msgstr "Tilladt"
msgid "LicenseCompliance|Denied"
msgstr ""
@@ -19817,55 +19967,55 @@ msgid "LicenseCompliance|Disallow merge request if detected and will instruct de
msgstr ""
msgid "LicenseCompliance|Learn more about %{linkStart}License Approvals%{linkEnd}"
-msgstr ""
+msgstr "Lær mere om %{linkStart}licensgodkendelser%{linkEnd}"
msgid "LicenseCompliance|License Approvals"
-msgstr ""
+msgstr "Licensgodkendelser"
msgid "LicenseCompliance|License Compliance detected %d license and policy violation for the source branch only"
msgid_plural "LicenseCompliance|License Compliance detected %d licenses and policy violations for the source branch only"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Licensoverholdelse registrerede %d overtrædelse af licens og regelsæt kun for kildegrenen"
+msgstr[1] "Licensoverholdelse registrerede %d overtrædelser af licenser og regelsæt kun for kildegrenen"
msgid "LicenseCompliance|License Compliance detected %d license and policy violation for the source branch only; approval required"
msgid_plural "LicenseCompliance|License Compliance detected %d licenses and policy violations for the source branch only; approval required"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Licensoverholdelse registrerede %d overtrædelse af licens og regelsæt kun for kildegrenen; kræver godkendelse"
+msgstr[1] "Licensoverholdelse registrerede %d overtrædelse af licenser og regelsæt kun for kildegrenen; kræver godkendelse"
msgid "LicenseCompliance|License Compliance detected %d license for the source branch only"
msgid_plural "LicenseCompliance|License Compliance detected %d licenses for the source branch only"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Licensoverholdelse registrerede %d licens kun for kildegrenen"
+msgstr[1] "Licensoverholdelse registrerede %d licenser kun for kildegrenen"
msgid "LicenseCompliance|License Compliance detected %d new license"
msgid_plural "LicenseCompliance|License Compliance detected %d new licenses"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Licensoverholdelse registrerede %d ny licens"
+msgstr[1] "Licensoverholdelse registrerede %d nye licenser"
msgid "LicenseCompliance|License Compliance detected %d new license and policy violation"
msgid_plural "LicenseCompliance|License Compliance detected %d new licenses and policy violations"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Licensoverholdelse registrerede %d ny overtrædelse af licens og regelsæt"
+msgstr[1] "Licensoverholdelse registrerede %d nye overtrædelser af licenser og regelsæt"
msgid "LicenseCompliance|License Compliance detected %d new license and policy violation; approval required"
msgid_plural "LicenseCompliance|License Compliance detected %d new licenses and policy violations; approval required"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Licensoverholdelse registrerede %d ny overtrædelse af licens og regelsæt; kræver godkendelse"
+msgstr[1] "Licensoverholdelse registrerede %d nye overtrædelser af licenser og regelsæt; kræver godkendelse"
msgid "LicenseCompliance|License Compliance detected no licenses for the source branch only"
-msgstr ""
+msgstr "Licensoverholdelse registrerede ingen licenser kun for kildegrenen"
msgid "LicenseCompliance|License Compliance detected no new licenses"
-msgstr ""
+msgstr "Licensoverholdelse registrerede ingen nye licenser"
msgid "LicenseCompliance|License name"
-msgstr ""
+msgstr "Licensnavn"
msgid "LicenseCompliance|Remove license"
-msgstr ""
+msgstr "Fjern licens"
msgid "LicenseCompliance|Remove license?"
-msgstr ""
+msgstr "Fjern licens?"
msgid "LicenseCompliance|There are currently no policies in this project."
msgstr ""
@@ -19874,13 +20024,13 @@ msgid "LicenseCompliance|There are currently no policies that match in this proj
msgstr ""
msgid "LicenseCompliance|This license already exists in this project."
-msgstr ""
+msgstr "Licensen findes allerede i projektet."
msgid "LicenseCompliance|You are about to remove the license, %{name}, from this project."
-msgstr ""
+msgstr "Du er ved at fjerne licensen %{name} fra projektet."
msgid "LicenseManagement|Allowed"
-msgstr ""
+msgstr "Tilladt"
msgid "LicenseManagement|Denied"
msgstr ""
@@ -19892,10 +20042,10 @@ msgid "Licensed Features"
msgstr ""
msgid "Licensed to:"
-msgstr ""
+msgstr "Licenseret til:"
msgid "Licenses"
-msgstr ""
+msgstr "Licenser"
msgid "Licenses|%{remainingComponentsCount} more"
msgstr ""
@@ -19904,10 +20054,10 @@ msgid "Licenses|Acceptable license to be used in the project"
msgstr ""
msgid "Licenses|Component"
-msgstr ""
+msgstr "Komponent"
msgid "Licenses|Components"
-msgstr ""
+msgstr "Komponenter"
msgid "Licenses|Detected in Project"
msgstr ""
@@ -19925,16 +20075,16 @@ msgid "Licenses|Error fetching the license list. Please check your network conne
msgstr ""
msgid "Licenses|License Compliance"
-msgstr ""
+msgstr "Licensoverholdelse"
msgid "Licenses|Name"
-msgstr ""
+msgstr "Navn"
msgid "Licenses|Policies"
-msgstr ""
+msgstr "Regelsæt"
msgid "Licenses|Policy"
-msgstr ""
+msgstr "Regelsæt"
msgid "Licenses|Policy violation: denied"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -19972,7 +20125,7 @@ msgid "Line changes"
msgstr ""
msgid "Link"
-msgstr ""
+msgstr "Link"
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -19987,7 +20140,7 @@ msgid "Link an external wiki from the project's sidebar. %{docs_link}"
msgstr ""
msgid "Link copied"
-msgstr ""
+msgstr "Link kopieret"
msgid "Link text"
msgstr ""
@@ -19996,16 +20149,16 @@ msgid "Link title"
msgstr ""
msgid "Link title is required"
-msgstr ""
+msgstr "Linktitel kræves"
msgid "Link to an image"
-msgstr ""
+msgstr "Link til et billede"
msgid "Link to go to GitLab pipeline documentation"
msgstr ""
msgid "Link to your Grafana instance."
-msgstr ""
+msgstr "Link til din Grafana-instans."
msgid "Linked emails (%{email_count})"
msgstr ""
@@ -20014,19 +20167,19 @@ msgid "Linked issues"
msgstr ""
msgid "LinkedIn"
-msgstr ""
+msgstr "LinkedIn"
msgid "LinkedIn:"
-msgstr ""
+msgstr "LinkedIn:"
msgid "LinkedPipelines|%{counterLabel} more downstream pipelines"
msgstr ""
msgid "Links"
-msgstr ""
+msgstr "Links"
msgid "List"
-msgstr ""
+msgstr "Liste"
msgid "List Your Gitea Repositories"
msgstr ""
@@ -20050,25 +20203,25 @@ msgid "List the merge requests that must be merged before this one."
msgstr ""
msgid "List view"
-msgstr ""
+msgstr "Listevisning"
msgid "List your Bitbucket Server repositories"
msgstr ""
msgid "Live preview"
-msgstr ""
+msgstr "Liveforhåndsvisning"
msgid "Load more"
-msgstr ""
+msgstr "Indlæs mere"
msgid "Load more users"
-msgstr ""
+msgstr "Indlæs flere brugere"
msgid "Loading"
-msgstr ""
+msgstr "Indlæser"
msgid "Loading %{name}"
-msgstr ""
+msgstr "Indlæser %{name}"
msgid "Loading contribution stats for group members"
msgstr ""
@@ -20080,76 +20233,76 @@ msgid "Loading functions timed out. Please reload the page to try again."
msgstr ""
msgid "Loading issues"
-msgstr ""
+msgstr "Indlæser problemstillinger"
msgid "Loading more"
msgstr ""
msgid "Loading snippet"
-msgstr ""
+msgstr "Indlæser uddrag"
msgid "Loading the GitLab IDE..."
msgstr ""
msgid "Loading..."
-msgstr ""
+msgstr "Indlæser ..."
msgid "Loading…"
-msgstr ""
+msgstr "Indlæser …"
msgid "Local IP addresses and domain names that hooks and services may access."
msgstr ""
msgid "Localization"
-msgstr ""
+msgstr "Oversættelse"
msgid "Location"
-msgstr ""
+msgstr "Placering"
msgid "Location:"
msgstr ""
msgid "Lock"
-msgstr ""
+msgstr "LÃ¥s"
msgid "Lock %{issuableDisplayName}"
-msgstr ""
+msgstr "LÃ¥s %{issuableDisplayName}"
msgid "Lock memberships to LDAP synchronization"
msgstr ""
msgid "Lock not found"
-msgstr ""
+msgstr "LÃ¥s ikke fundet"
msgid "Lock the discussion"
-msgstr ""
+msgstr "LÃ¥s debatten"
msgid "Lock this %{issuableDisplayName}? Only %{strongStart}project members%{strongEnd} will be able to comment."
msgstr ""
msgid "Lock to current projects"
-msgstr ""
+msgstr "Lås til nuværende projekter"
msgid "Locked"
-msgstr ""
+msgstr "LÃ¥st"
msgid "Locked Files"
-msgstr ""
+msgstr "LÃ¥ste filer"
msgid "Locked by %{fileLockUserName}"
-msgstr ""
+msgstr "LÃ¥st af %{fileLockUserName}"
msgid "Locked the discussion."
-msgstr ""
+msgstr "LÃ¥ste debatten."
msgid "Locked to current projects"
-msgstr ""
+msgstr "Låst til nuværende projekter"
msgid "Locks give the ability to lock specific file or folder."
msgstr ""
msgid "Locks the discussion."
-msgstr ""
+msgstr "LÃ¥ser debatten."
msgid "Login with smartcard"
msgstr ""
@@ -20158,10 +20311,10 @@ msgid "Logo was successfully removed."
msgstr ""
msgid "Logo will be removed. Are you sure?"
-msgstr ""
+msgstr "Logo fjernes. Er du sikker?"
msgid "Logs"
-msgstr ""
+msgstr "Logge"
msgid "Logs|To see the logs, deploy your code to an environment."
msgstr ""
@@ -20170,13 +20323,13 @@ msgid "Low vulnerabilities present"
msgstr ""
msgid "MB"
-msgstr ""
+msgstr "MB"
msgid "MD5"
-msgstr ""
+msgstr "MD5"
msgid "MERGED"
-msgstr ""
+msgstr "SAMMENLAGT"
msgid "MR widget|Back to the Merge request"
msgstr ""
@@ -20200,7 +20353,7 @@ msgid "MRApprovals|Approvers"
msgstr ""
msgid "MRApprovals|Commented by"
-msgstr ""
+msgstr "Kommenteret af"
msgid "MRDiffFile|Changes are too large to be shown."
msgstr ""
@@ -20209,7 +20362,7 @@ msgid "MRDiffFile|View file @ %{commitSha}"
msgstr ""
msgid "MRDiff|Show changes only"
-msgstr ""
+msgstr "Vis kun ændringer"
msgid "MRDiff|Show full file"
msgstr ""
@@ -20227,7 +20380,7 @@ msgid "Mailgun events"
msgstr ""
msgid "Maintenance mode"
-msgstr ""
+msgstr "Vedligeholdelsestilstand"
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -20245,10 +20398,10 @@ msgid "Makes this issue confidential."
msgstr ""
msgid "Manage Web IDE features."
-msgstr ""
+msgstr "HÃ¥ndter Web IDE-funktioner."
msgid "Manage access"
-msgstr ""
+msgstr "HÃ¥ndter adgang"
msgid "Manage all notifications"
msgstr ""
@@ -20266,34 +20419,34 @@ msgid "Manage git repositories with fine-grained access controls that keep your
msgstr ""
msgid "Manage group labels"
-msgstr ""
+msgstr "HÃ¥ndter gruppeetiketter"
msgid "Manage labels"
-msgstr ""
+msgstr "HÃ¥ndter etiketter"
msgid "Manage milestones"
-msgstr ""
+msgstr "Håndter milepæle"
msgid "Manage project labels"
-msgstr ""
+msgstr "HÃ¥ndter projektetiketter"
msgid "Manage projects."
-msgstr ""
+msgstr "HÃ¥ndter projekter."
msgid "Manage two-factor authentication"
-msgstr ""
+msgstr "HÃ¥ndter tofaktorgodkendelse"
msgid "Manage your license"
-msgstr ""
+msgstr "HÃ¥ndter din licens"
msgid "Manage your project's triggers"
-msgstr ""
+msgstr "Håndter dit projekts udløsere"
msgid "Managed Account"
msgstr ""
msgid "Manifest"
-msgstr ""
+msgstr "Manifest"
msgid "Manifest file import"
msgstr ""
@@ -20314,19 +20467,19 @@ msgid "Map a FogBugz account ID to a GitLab user"
msgstr ""
msgid "Mar"
-msgstr ""
+msgstr "Mar."
msgid "March"
-msgstr ""
+msgstr "Marts"
msgid "Mark as done"
-msgstr ""
+msgstr "Mærk som færdig"
msgid "Mark as draft"
-msgstr ""
+msgstr "Mærk som kladde"
msgid "Mark as ready"
-msgstr ""
+msgstr "Mærk som klar"
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -20335,22 +20488,22 @@ msgid "Mark this issue as related to another issue"
msgstr ""
msgid "Mark to do as done"
-msgstr ""
+msgstr "Mærk to do som færdig"
msgid "Markdown"
-msgstr ""
+msgstr "Markdown"
msgid "Markdown Help"
-msgstr ""
+msgstr "Hjælp for Markdown"
msgid "Markdown enabled."
-msgstr ""
+msgstr "Markdown aktiveret."
msgid "Markdown is supported"
-msgstr ""
+msgstr "Markdown understøttes"
msgid "Markdown supported."
-msgstr ""
+msgstr "Markdown understøttes."
msgid "MarkdownEditor|Add a link (%{modifierKey}K)"
msgstr ""
@@ -20383,7 +20536,7 @@ msgid "Marked this issue as related to %{issue_ref}."
msgstr ""
msgid "Marked to do as done."
-msgstr ""
+msgstr "Mærkede to do som færdig."
msgid "Marks this %{noun} as a draft."
msgstr ""
@@ -20395,7 +20548,7 @@ msgid "Marks this issue as related to %{issue_ref}."
msgstr ""
msgid "Marks to do as done."
-msgstr ""
+msgstr "Mærker to do som færdig."
msgid "Mask variable"
msgstr ""
@@ -20404,7 +20557,7 @@ msgid "Match not found; try refining your search query."
msgstr ""
msgid "Mattermost"
-msgstr ""
+msgstr "Mattermost"
msgid "Mattermost URL:"
msgstr ""
@@ -20437,7 +20590,7 @@ msgid "MattermostService|Response username"
msgstr ""
msgid "MattermostService|Suggestions:"
-msgstr ""
+msgstr "Forslag:"
msgid "MattermostService|Use this service to perform common tasks in your project by entering slash commands in Mattermost."
msgstr ""
@@ -20446,7 +20599,7 @@ msgid "Max 100,000 events"
msgstr ""
msgid "Max 20 characters"
-msgstr ""
+msgstr "Maks. 20 tegn"
msgid "Max Group Export Download requests per minute per user"
msgstr ""
@@ -20469,11 +20622,14 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
msgid "Max file size is 200 KB."
-msgstr ""
+msgstr "Maks. filstørrelse er 200 KB."
msgid "Max requests per minute per user"
msgstr ""
@@ -20491,19 +20647,19 @@ msgid "MaxBuilds"
msgstr ""
msgid "Maximum Conan package file size in bytes"
-msgstr ""
+msgstr "Maksimale filstørrelse for Conan-pakke i byte"
msgid "Maximum Maven package file size in bytes"
-msgstr ""
+msgstr "Maksimale filstørrelse for Maven-pakke i byte"
msgid "Maximum NuGet package file size in bytes"
-msgstr ""
+msgstr "Maksimale filstørrelse for NuGet-pakke i byte"
msgid "Maximum PyPI package file size in bytes"
-msgstr ""
+msgstr "Maksimale filstørrelse for PyPi-pakke i byte"
msgid "Maximum Terraform Module package file size in bytes"
-msgstr ""
+msgstr "Maksimale filstørrelse for Terraform-modulpakke i byte"
msgid "Maximum Users"
msgstr ""
@@ -20512,9 +20668,12 @@ msgid "Maximum allowable lifetime for personal access token (days)"
msgstr ""
msgid "Maximum artifacts size"
-msgstr ""
+msgstr "Maksimal størrelse for artefakter"
msgid "Maximum artifacts size (MB)"
+msgstr "Maksimal størrelse for artefakter (MB)"
+
+msgid "Maximum attachment size"
msgstr ""
msgid "Maximum attachment size (MB)"
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20578,7 +20746,7 @@ msgid "Maximum lines in a diff"
msgstr ""
msgid "Maximum npm package file size in bytes"
-msgstr ""
+msgstr "Maksimale filstørrelse for npm-pakke i byte"
msgid "Maximum number of %{name} (%{count}) exceeded"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20632,7 +20809,7 @@ msgid "Maximum time that users are allowed to skip the setup of two-factor authe
msgstr ""
msgid "May"
-msgstr ""
+msgstr "Maj"
msgid "Mean time to merge"
msgstr ""
@@ -20647,25 +20824,28 @@ msgid "Medium vulnerabilities present"
msgstr ""
msgid "Member lock"
-msgstr ""
+msgstr "Medlemslås"
msgid "Member since"
-msgstr ""
+msgstr "Medlem siden"
msgid "Member since %{date}"
-msgstr ""
+msgstr "Medlem siden %{date}"
msgid "Member since:"
-msgstr ""
+msgstr "Medlem siden:"
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
msgid "Members"
-msgstr ""
+msgstr "Medlemmer"
msgid "Members can be added by project %{i_open}Maintainers%{i_close} or %{i_open}Owners%{i_close}"
msgstr ""
@@ -20674,7 +20854,7 @@ msgid "Members listed as CODEOWNERS of affected files."
msgstr ""
msgid "Members of %{group} can also merge into this branch: %{branch}"
-msgstr ""
+msgstr "Medlemmer af %{group} kan også sammenlægge i grenen: %{branch}"
msgid "Members of %{group} can also push to this branch: %{branch}"
msgstr ""
@@ -20683,13 +20863,13 @@ msgid "Members of a group may only view projects they have permission to access"
msgstr ""
msgid "Members|%{time} by %{user}"
-msgstr ""
+msgstr "%{time} af %{user}"
msgid "Members|%{userName} is currently an LDAP user. Editing their permissions will override the settings from the LDAP group sync."
msgstr ""
msgid "Members|2FA"
-msgstr ""
+msgstr "2FG"
msgid "Members|An error occurred while trying to enable LDAP override, please try again."
msgstr ""
@@ -20707,13 +20887,13 @@ msgid "Members|Are you sure you want to deny %{usersName}'s request to join \"%{
msgstr ""
msgid "Members|Are you sure you want to leave \"%{source}\"?"
-msgstr ""
+msgstr "Er du sikker på, at du vil forlade \"%{source}\"?"
msgid "Members|Are you sure you want to remove \"%{groupName}\"?"
-msgstr ""
+msgstr "Er du sikker på, at du vil fjerne \"%{groupName}\"?"
msgid "Members|Are you sure you want to remove %{usersName} from \"%{source}\"?"
-msgstr ""
+msgstr "Er du sikker på, at du vil fjerne %{usersName} fra \"%{source}\"?"
msgid "Members|Are you sure you want to remove this orphaned member from \"%{source}\"?"
msgstr ""
@@ -20725,16 +20905,16 @@ msgid "Members|Are you sure you want to withdraw your access request for \"%{sou
msgstr ""
msgid "Members|Direct"
-msgstr ""
+msgstr "Direkte"
msgid "Members|Disabled"
-msgstr ""
+msgstr "Deaktiveret"
msgid "Members|Edit permissions"
-msgstr ""
+msgstr "Rediger tilladelser"
msgid "Members|Enabled"
-msgstr ""
+msgstr "Aktiveret"
msgid "Members|Expiration date removed successfully."
msgstr ""
@@ -20743,10 +20923,10 @@ msgid "Members|Expiration date updated successfully."
msgstr ""
msgid "Members|Expired"
-msgstr ""
+msgstr "Udløbet"
msgid "Members|Filter members"
-msgstr ""
+msgstr "Filtrér medlemmer"
msgid "Members|Inherited"
msgstr ""
@@ -20755,19 +20935,19 @@ msgid "Members|LDAP override enabled."
msgstr ""
msgid "Members|Leave \"%{source}\""
-msgstr ""
+msgstr "Forlad \"%{source}\""
msgid "Members|Membership"
-msgstr ""
+msgstr "Medlemskab"
msgid "Members|No expiration set"
msgstr ""
msgid "Members|Remove \"%{groupName}\""
-msgstr ""
+msgstr "Fjern \"%{groupName}\""
msgid "Members|Remove group"
-msgstr ""
+msgstr "Fjern gruppe"
msgid "Members|Revert to LDAP group sync settings"
msgstr ""
@@ -20791,25 +20971,25 @@ msgid "Member|Deny access"
msgstr ""
msgid "Member|Remove member"
-msgstr ""
+msgstr "Fjern medlem"
msgid "Member|Revoke invite"
-msgstr ""
+msgstr "Tilbagekald invitation"
msgid "Memory Usage"
-msgstr ""
+msgstr "Hukommelsesforbrug"
msgid "Menu"
-msgstr ""
+msgstr "Menu"
msgid "Merge"
-msgstr ""
+msgstr "Sammenlæg"
msgid "Merge Conflicts"
msgstr ""
msgid "Merge Request"
-msgstr ""
+msgstr "Sammenlægningsanmodning"
msgid "Merge Request Analytics"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20836,25 +21019,25 @@ msgid "Merge commit SHA"
msgstr ""
msgid "Merge commit message"
-msgstr ""
+msgstr "Sammenlæg commit-meddelelse"
msgid "Merge events"
msgstr ""
msgid "Merge immediately"
-msgstr ""
+msgstr "Sammenlæg straks"
msgid "Merge in progress"
-msgstr ""
+msgstr "Igangværende sammenlægning"
msgid "Merge locally"
-msgstr ""
+msgstr "Sammenlæg lokalt"
msgid "Merge options"
msgstr ""
msgid "Merge request"
-msgstr ""
+msgstr "Sammenlægningsanmodning"
msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
msgstr ""
@@ -20881,7 +21064,7 @@ msgid "Merge request was scheduled to merge after pipeline succeeds"
msgstr ""
msgid "Merge requests"
-msgstr ""
+msgstr "Sammenlægningsanmodninger"
msgid "Merge requests are a place to propose changes you've made to a project and discuss those changes with others"
msgstr ""
@@ -20905,16 +21088,16 @@ msgid "MergeConflict|HEAD//our changes"
msgstr ""
msgid "MergeConflict|Use ours"
-msgstr ""
+msgstr "Brug vores"
msgid "MergeConflict|Use theirs"
-msgstr ""
+msgstr "Brug deres"
msgid "MergeConflict|conflict"
-msgstr ""
+msgstr "konflikt"
msgid "MergeConflict|conflicts"
-msgstr ""
+msgstr "konflikter"
msgid "MergeConflict|origin//their changes"
msgstr ""
@@ -20932,7 +21115,7 @@ msgid "MergeRequestAnalytics|Merge Request"
msgstr ""
msgid "MergeRequestAnalytics|Milestone"
-msgstr ""
+msgstr "Milepæl"
msgid "MergeRequestAnalytics|Pipelines"
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -20980,16 +21157,16 @@ msgid "MergeRequests|Thread will be unresolved"
msgstr ""
msgid "MergeRequests|View file @ %{commitId}"
-msgstr ""
+msgstr "Vis fil @ %{commitId}"
msgid "MergeRequests|View replaced file @ %{commitId}"
-msgstr ""
+msgstr "Vis erstattet fil @ %{commitId}"
msgid "MergeRequests|commented on commit %{commitLink}"
msgstr ""
msgid "MergeRequests|started a thread"
-msgstr ""
+msgstr "startede en tråd"
msgid "MergeRequests|started a thread on %{linkStart}an old version of the diff%{linkEnd}"
msgstr ""
@@ -21016,13 +21193,13 @@ msgid "MergeRequest|Error loading full diff. Please try again."
msgstr ""
msgid "MergeRequest|No files found"
-msgstr ""
+msgstr "Ingen filer fundet"
msgid "MergeRequest|Search files (%{modifier_key}P)"
-msgstr ""
+msgstr "Søg efter filer (%{modifier_key}P)"
msgid "Merged"
-msgstr ""
+msgstr "Sammenlagt"
msgid "Merged MRs"
msgstr ""
@@ -21031,7 +21208,7 @@ msgid "Merged branches are being deleted. This can take some time depending on t
msgstr ""
msgid "Merged by"
-msgstr ""
+msgstr "Sammenlagt af"
msgid "Merged this merge request."
msgstr ""
@@ -21046,13 +21223,13 @@ msgid "Merging immediately isn't recommended as it may negatively impact the exi
msgstr ""
msgid "Message"
-msgstr ""
+msgstr "Meddelelse"
msgid "Messages"
-msgstr ""
+msgstr "Meddelelser"
msgid "Method"
-msgstr ""
+msgstr "Metode"
msgid "Method call threshold (ms)"
msgstr ""
@@ -21064,7 +21241,7 @@ msgid "Metric was successfully updated."
msgstr ""
msgid "Metric:"
-msgstr ""
+msgstr "MÃ¥ling:"
msgid "MetricChart|Please select a metric"
msgstr ""
@@ -21079,10 +21256,10 @@ msgid "MetricChart|There is too much data to calculate. Please change your selec
msgstr ""
msgid "Metrics"
-msgstr ""
+msgstr "MÃ¥linger"
msgid "Metrics - Grafana"
-msgstr ""
+msgstr "MÃ¥linger - Grafana"
msgid "Metrics - Prometheus"
msgstr ""
@@ -21154,7 +21331,7 @@ msgid "MetricsSettings|UTC (Coordinated Universal Time)"
msgstr ""
msgid "MetricsSettings|User's local timezone"
-msgstr ""
+msgstr "Brugerens lokale tidszone"
msgid "Metrics|1. Define and preview panel"
msgstr ""
@@ -21163,31 +21340,31 @@ msgid "Metrics|2. Paste panel YAML into dashboard"
msgstr ""
msgid "Metrics|Add metric"
-msgstr ""
+msgstr "Tilføj måling"
msgid "Metrics|Add panel"
-msgstr ""
+msgstr "Tilføj panel"
msgid "Metrics|Avg"
msgstr ""
msgid "Metrics|Back to dashboard"
-msgstr ""
+msgstr "Tilbage til betjeningspanel"
msgid "Metrics|Cancel"
-msgstr ""
+msgstr "Annuller"
msgid "Metrics|Check out the CI/CD documentation on deploying to an environment"
msgstr ""
msgid "Metrics|Collapse panel"
-msgstr ""
+msgstr "Sammenfold panel"
msgid "Metrics|Collapse panel (Esc)"
-msgstr ""
+msgstr "Sammenfold panel (Esc)"
msgid "Metrics|Copy YAML"
-msgstr ""
+msgstr "Kopiér YAML"
msgid "Metrics|Copy and paste the panel YAML into your dashboard YAML file."
msgstr ""
@@ -21196,16 +21373,16 @@ msgid "Metrics|Create custom dashboard %{fileName}"
msgstr ""
msgid "Metrics|Create metric"
-msgstr ""
+msgstr "Opret måling"
msgid "Metrics|Create new dashboard"
-msgstr ""
+msgstr "Opret nyt betjeningspanel"
msgid "Metrics|Create your dashboard configuration file"
msgstr ""
msgid "Metrics|Current"
-msgstr ""
+msgstr "Nuværende"
msgid "Metrics|Dashboard files can be found in %{codeStart}.gitlab/dashboards%{codeEnd} at the root of this project."
msgstr ""
@@ -21214,36 +21391,36 @@ msgid "Metrics|Define panel YAML below to preview panel."
msgstr ""
msgid "Metrics|Delete metric"
-msgstr ""
+msgstr "Slet måling"
msgid "Metrics|Delete metric?"
-msgstr ""
+msgstr "Slet måling?"
msgid "Metrics|Duplicate"
-msgstr ""
+msgstr "Dupliker"
msgid "Metrics|Duplicate current dashboard"
-msgstr ""
+msgstr "Dupliker nuværende betjeningspanel"
msgid "Metrics|Duplicate dashboard"
-msgstr ""
+msgstr "Dupliker betjeningspanel"
msgid "Metrics|Duplicate this dashboard to add panel or edit dashboard YAML."
msgstr ""
msgid "Metrics|Duplicating..."
-msgstr ""
+msgstr "Duplikerer ..."
msgid "Metrics|Edit dashboard YAML"
msgstr ""
msgid "Metrics|Edit metric"
msgid_plural "Metrics|Edit metrics"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Rediger måling"
+msgstr[1] "Rediger målinger"
msgid "Metrics|Expand panel"
-msgstr ""
+msgstr "Udfold panel"
msgid "Metrics|For grouping similar metrics"
msgstr ""
@@ -21279,13 +21456,13 @@ msgid "Metrics|Min"
msgstr ""
msgid "Metrics|More actions"
-msgstr ""
+msgstr "Flere handlinger"
msgid "Metrics|Must be a valid PromQL query."
msgstr ""
msgid "Metrics|New metric"
-msgstr ""
+msgstr "Ny måling"
msgid "Metrics|Open repository"
msgstr ""
@@ -21309,10 +21486,10 @@ msgid "Metrics|Refresh Prometheus data"
msgstr ""
msgid "Metrics|Refresh dashboard"
-msgstr ""
+msgstr "Opdater betjeningspanel"
msgid "Metrics|Select a value"
-msgstr ""
+msgstr "Vælg en værdi"
msgid "Metrics|Set refresh rate"
msgstr ""
@@ -21321,10 +21498,10 @@ msgid "Metrics|Star dashboard"
msgstr ""
msgid "Metrics|There was an error creating the dashboard."
-msgstr ""
+msgstr "Der opstod en fejl ved oprettelse af betjeningspanelet."
msgid "Metrics|There was an error creating the dashboard. %{error}"
-msgstr ""
+msgstr "Der opstod en fejl ved oprettelse af betjeningspanelet. %{error}"
msgid "Metrics|There was an error fetching annotations. Please try again."
msgstr ""
@@ -21345,16 +21522,16 @@ msgid "Metrics|There was an error getting environments information."
msgstr ""
msgid "Metrics|There was an error getting options for variable \"%{name}\"."
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af valgmuligheder for variablen \"%{name}\"."
msgid "Metrics|There was an error trying to validate your query"
msgstr ""
msgid "Metrics|There was an error while retrieving metrics"
-msgstr ""
+msgstr "Der opstod en fejl under indhentning af målinger"
msgid "Metrics|There was an error while retrieving metrics. %{message}"
-msgstr ""
+msgstr "Der opstod en fejl under indhentning af målinger. %{message}"
msgid "Metrics|To create a new dashboard, add a new YAML file to %{codeStart}.gitlab/dashboards%{codeEnd} at the root of this project."
msgstr ""
@@ -21378,13 +21555,13 @@ msgid "Metrics|Validating query"
msgstr ""
msgid "Metrics|Values"
-msgstr ""
+msgstr "Værdier"
msgid "Metrics|View documentation"
-msgstr ""
+msgstr "Vis dokumentation"
msgid "Metrics|View logs"
-msgstr ""
+msgstr "Vis logge"
msgid "Metrics|View runbook - %{label}"
msgstr ""
@@ -21417,7 +21594,7 @@ msgid "Metrics|e.g. req/sec"
msgstr ""
msgid "Mi"
-msgstr ""
+msgstr "Mi"
msgid "Middleman project with Static Site Editor support"
msgstr ""
@@ -21426,7 +21603,7 @@ msgid "Migrated %{success_count}/%{total_count} files."
msgstr ""
msgid "Migration"
-msgstr ""
+msgstr "Migrering"
msgid "Migration has been scheduled to be retried"
msgstr ""
@@ -21436,8 +21613,8 @@ msgstr ""
msgid "Milestone"
msgid_plural "Milestones"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Milepæl"
+msgstr[1] "Milepæle"
msgid "Milestone due date"
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21455,13 +21629,13 @@ msgid "MilestoneCombobox|Group milestones"
msgstr ""
msgid "MilestoneCombobox|Milestone"
-msgstr ""
+msgstr "Milepæl"
msgid "MilestoneCombobox|No matching results"
msgstr ""
msgid "MilestoneCombobox|No milestone"
-msgstr ""
+msgstr "Ingen milepæl"
msgid "MilestoneCombobox|Project milestones"
msgstr ""
@@ -21470,7 +21644,7 @@ msgid "MilestoneCombobox|Search Milestones"
msgstr ""
msgid "MilestoneCombobox|Select milestone"
-msgstr ""
+msgstr "Vælg milepæl"
msgid "MilestoneSidebar|Closed:"
msgstr ""
@@ -21479,49 +21653,49 @@ msgid "MilestoneSidebar|Copy reference"
msgstr ""
msgid "MilestoneSidebar|Due date"
-msgstr ""
+msgstr "Forfaldsdato"
msgid "MilestoneSidebar|Edit"
-msgstr ""
+msgstr "Rediger"
msgid "MilestoneSidebar|From"
-msgstr ""
+msgstr "Fra"
msgid "MilestoneSidebar|Issues"
-msgstr ""
+msgstr "Problemstillinger"
msgid "MilestoneSidebar|Merge requests"
-msgstr ""
+msgstr "Sammenlægningsanmodninger"
msgid "MilestoneSidebar|Merged:"
-msgstr ""
+msgstr "Sammenlagt:"
msgid "MilestoneSidebar|New Issue"
-msgstr ""
+msgstr "Ny problemstilling"
msgid "MilestoneSidebar|New issue"
-msgstr ""
+msgstr "Ny problemstilling"
msgid "MilestoneSidebar|No due date"
-msgstr ""
+msgstr "Ingen forfaldsdato"
msgid "MilestoneSidebar|No start date"
msgstr ""
msgid "MilestoneSidebar|None"
-msgstr ""
+msgstr "Ingen"
msgid "MilestoneSidebar|Open:"
msgstr ""
msgid "MilestoneSidebar|Reference:"
-msgstr ""
+msgstr "Reference:"
msgid "MilestoneSidebar|Start date"
-msgstr ""
+msgstr "Startdato"
msgid "MilestoneSidebar|Toggle sidebar"
-msgstr ""
+msgstr "Sidebjælke til/fra"
msgid "MilestoneSidebar|Until"
msgstr ""
@@ -21530,7 +21704,7 @@ msgid "MilestoneSidebar|complete"
msgstr ""
msgid "Milestones"
-msgstr ""
+msgstr "Milepæle"
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle} and remove it from %{issuesWithCount} and %{mergeRequestsWithCount}. Once deleted, it cannot be undone or recovered."
msgstr ""
@@ -21539,13 +21713,13 @@ msgid "Milestones| You’re about to permanently delete the milestone %{mileston
msgstr ""
msgid "Milestones|Close Milestone"
-msgstr ""
+msgstr "Luk milepæl"
msgid "Milestones|Completed Issues (closed)"
-msgstr ""
+msgstr "Fuldførte problemstillinger (lukkede)"
msgid "Milestones|Delete milestone"
-msgstr ""
+msgstr "Slet milepæl"
msgid "Milestones|Delete milestone %{milestoneTitle}?"
msgstr ""
@@ -21563,7 +21737,7 @@ msgid "Milestones|Ongoing Issues (open and assigned)"
msgstr ""
msgid "Milestones|Project Milestone"
-msgstr ""
+msgstr "Projektmilepæle"
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
@@ -21578,7 +21752,7 @@ msgid "Milestones|Promoting %{milestoneTitle} will make it available for all pro
msgstr ""
msgid "Milestones|Reopen Milestone"
-msgstr ""
+msgstr "Genåbn milepæl"
msgid "Milestones|This action cannot be reversed."
msgstr ""
@@ -21593,7 +21767,7 @@ msgid "Minimum interval in days"
msgstr ""
msgid "Minutes"
-msgstr ""
+msgstr "Minutter"
msgid "Mirror direction"
msgstr ""
@@ -21629,58 +21803,58 @@ msgid "Mirroring will only be available if the feature is included in the plan o
msgstr ""
msgid "Miscellaneous"
-msgstr ""
+msgstr "Diverse"
msgid "Missing"
-msgstr ""
+msgstr "Mangler"
msgid "Missing OAuth configuration for GitHub."
msgstr ""
msgid "Missing OS"
-msgstr ""
+msgstr "Manglende styresystem"
msgid "Missing arch"
-msgstr ""
+msgstr "Manglende arkitektur"
msgid "Missing commit signatures endpoint!"
msgstr ""
msgid "MissingSSHKeyWarningLink|Add SSH key"
-msgstr ""
+msgstr "Tilføj SSH-nøgle"
msgid "MissingSSHKeyWarningLink|Don't show again"
-msgstr ""
+msgstr "Vis ikke igen"
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push repositories via SSH until you add an SSH key to your profile"
-msgstr ""
+msgstr "Du vil ikke være i stand til at bruge pull eller push på depoter via SSH før du tilføjer en SSH-nøgle til din profil"
msgid "ModalButton|Add projects"
-msgstr ""
+msgstr "Tilføj projekter"
msgid "Modal|Close"
-msgstr ""
+msgstr "Luk"
msgid "Modified"
-msgstr ""
+msgstr "Ændret"
msgid "Modified in this version"
-msgstr ""
+msgstr "Ændret i denne version"
msgid "Modify commit message"
-msgstr ""
+msgstr "Rediger commit-meddelelse"
msgid "Modify commit messages"
-msgstr ""
+msgstr "Rediger commit-meddelelser"
msgid "Modify merge commit"
msgstr ""
msgid "Monday"
-msgstr ""
+msgstr "Mandag"
msgid "Monitor"
-msgstr ""
+msgstr "Overvågning"
msgid "Monitor Settings"
msgstr ""
@@ -21692,82 +21866,82 @@ msgid "Monitor your errors by integrating with Sentry."
msgstr ""
msgid "Monitoring"
-msgstr ""
+msgstr "Overvågning"
msgid "Month"
-msgstr ""
+msgstr "MÃ¥ned"
msgid "Months"
-msgstr ""
+msgstr "MÃ¥neder"
msgid "More Information"
-msgstr ""
+msgstr "Mere information"
msgid "More Slack commands"
-msgstr ""
+msgstr "Flere Slack-kommandoer"
msgid "More actions"
-msgstr ""
+msgstr "Flere handlinger"
msgid "More details"
-msgstr ""
+msgstr "Flere detaljer"
msgid "More info"
-msgstr ""
+msgstr "Mere information"
msgid "More information"
-msgstr ""
+msgstr "Mere information"
msgid "More information and share feedback"
-msgstr ""
+msgstr "Mere information og del feedback"
msgid "More information is available|here"
-msgstr ""
+msgstr "Der findes mere information|her"
msgid "More information."
-msgstr ""
+msgstr "Mere information."
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
msgid "More topics"
-msgstr ""
+msgstr "Flere emner"
msgid "Most relevant"
-msgstr ""
+msgstr "Mest relevante"
msgid "Most stars"
-msgstr ""
+msgstr "Flest stjerner"
msgid "Mount point %{mounted_as} not found in %{model_class}."
-msgstr ""
+msgstr "Monteringspunktet %{mounted_as} ikke fundet i %{model_class}."
msgid "Move"
-msgstr ""
+msgstr "Flyt"
msgid "Move down"
-msgstr ""
+msgstr "Flyt ned"
msgid "Move issue"
-msgstr ""
+msgstr "Flyt problemstilling"
msgid "Move issue from one column of the board to another"
-msgstr ""
+msgstr "Flyt problemstilling fra én kolonne i tavlen til en anden"
msgid "Move selection down"
-msgstr ""
+msgstr "Flyt markering ned"
msgid "Move selection up"
-msgstr ""
+msgstr "Flyt markering op"
msgid "Move test case"
-msgstr ""
+msgstr "Flyt testsag"
msgid "Move this issue to another project."
-msgstr ""
+msgstr "Flyt problemstillingen til et andet projekt."
msgid "Move up"
-msgstr ""
+msgstr "Flyt op"
msgid "MoveIssue|Cannot move issue due to insufficient permissions!"
msgstr ""
@@ -21782,22 +21956,22 @@ msgid "Moved this issue to %{path_to_project}."
msgstr ""
msgid "Moves issue to %{label} column in the board."
-msgstr ""
+msgstr "Flytter problemstilling til kolonnen %{label} i tavlen."
msgid "Moves this issue to %{path_to_project}."
-msgstr ""
+msgstr "Flytter problemstillingen til %{path_to_project}."
msgid "MrDeploymentActions|Deploy"
-msgstr ""
+msgstr "Udsend"
msgid "MrDeploymentActions|Re-deploy"
-msgstr ""
+msgstr "Genudsend"
msgid "MrDeploymentActions|Stop environment"
-msgstr ""
+msgstr "Stop miljø"
msgid "Multi-project"
-msgstr ""
+msgstr "Multiprojekt"
msgid "Multi-project Runners cannot be removed"
msgstr ""
@@ -21826,61 +22000,61 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
-msgstr ""
+msgstr "Min fantastiske gruppe"
msgid "My company or team"
-msgstr ""
+msgstr "Min virksomhed eller team"
msgid "My-Reaction"
-msgstr ""
+msgstr "Min-reaktion"
msgid "N/A"
-msgstr ""
+msgstr "—"
msgid "Name"
-msgstr ""
+msgstr "Navn"
msgid "Name can't be blank"
-msgstr ""
+msgstr "Navnet må ikke være tomt"
msgid "Name has already been taken"
-msgstr ""
+msgstr "Navnet er allerede taget"
msgid "Name is already taken."
-msgstr ""
+msgstr "Navnet er allerede taget."
msgid "Name new label"
-msgstr ""
+msgstr "Navngiv ny etiket"
msgid "Name:"
-msgstr ""
+msgstr "Navn:"
msgid "Namespace"
-msgstr ""
+msgstr "Navnerum"
msgid "Namespace ID:"
msgstr ""
msgid "Namespace is empty"
-msgstr ""
+msgstr "Navnerummet er tomt"
msgid "Namespace:"
-msgstr ""
+msgstr "Navnerum:"
msgid "NamespaceStorageSize|%{namespace_name} contains %{locked_project_count} locked project"
msgid_plural "NamespaceStorageSize|%{namespace_name} contains %{locked_project_count} locked projects"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{namespace_name} indeholder %{locked_project_count} låst projekt"
+msgstr[1] "%{namespace_name} indeholder %{locked_project_count} låste projekter"
msgid "NamespaceStorageSize|%{namespace_name} is now read-only. You cannot: %{base_message}"
-msgstr ""
+msgstr "%{namespace_name} er nu skrivebeskyttet. Du kan ikke: %{base_message}"
msgid "NamespaceStorageSize|If you reach 100%% storage capacity, you will not be able to: %{base_message}"
-msgstr ""
+msgstr "Hvis du når 100%% lagerkapacitet, så vil du ikke være i stand til at: %{base_message}"
msgid "NamespaceStorageSize|Please purchase additional storage to unlock your projects over the free %{free_size_limit} project limit. You can't %{base_message}"
msgstr ""
@@ -21901,10 +22075,10 @@ msgid "NamespaceStorageSize|push to your repository, create pipelines, create is
msgstr ""
msgid "Namespaces"
-msgstr ""
+msgstr "Navnerum"
msgid "Namespaces to index"
-msgstr ""
+msgstr "Navnerum som skal indekseres"
msgid "Naming, topics, avatar"
msgstr ""
@@ -21913,37 +22087,37 @@ msgid "Naming, visibility"
msgstr ""
msgid "Navigate to the project to close the milestone."
-msgstr ""
+msgstr "Naviger til projektet for at lukke milepælen."
msgid "Navigation bar"
-msgstr ""
+msgstr "Navigationslinje"
msgid "Nav|Help"
-msgstr ""
+msgstr "Hjælp"
msgid "Nav|Home"
-msgstr ""
+msgstr "Hjem"
msgid "Nav|Sign In / Register"
-msgstr ""
+msgstr "Log ind/tilmeld"
msgid "Nav|Sign out and sign in with a different account"
-msgstr ""
+msgstr "Log ud og log ind med en anden konto"
msgid "Need help?"
-msgstr ""
+msgstr "Brug for hjælp?"
msgid "Needs"
msgstr ""
msgid "Needs attention"
-msgstr ""
+msgstr "Behøver opmærksomhed"
msgid "Network"
-msgstr ""
+msgstr "Netværk"
msgid "Network Policy|New rule"
-msgstr ""
+msgstr "Ny regel"
msgid "NetworkPolicies|%{ifLabelStart}if%{ifLabelEnd} %{ruleType} %{isLabelStart}is%{isLabelEnd} %{ruleDirection} %{ruleSelector} %{directionLabelStart}and is inbound from a%{directionLabelEnd} %{rule} %{portsLabelStart}on%{portsLabelEnd} %{ports}"
msgstr ""
@@ -21970,22 +22144,22 @@ msgid "NetworkPolicies|+ Add alert"
msgstr ""
msgid "NetworkPolicies|.yaml"
-msgstr ""
+msgstr ".yaml"
msgid "NetworkPolicies|.yaml mode"
-msgstr ""
+msgstr ".yaml-tilstand"
msgid "NetworkPolicies|Actions"
-msgstr ""
+msgstr "Handlinger"
msgid "NetworkPolicies|Alerts are intended to be selectively used for a limited number of events that are potentially concerning and warrant a manual review. Alerts should not be used as a substitute for a SIEM or a logging tool. High volume alerts are likely to be dropped so as to preserve the stability of GitLab's integration with Kubernetes."
msgstr ""
msgid "NetworkPolicies|All selected"
-msgstr ""
+msgstr "Alle valgte"
msgid "NetworkPolicies|Allow"
-msgstr ""
+msgstr "Tillad"
msgid "NetworkPolicies|Allow all inbound traffic to %{selector} from %{ruleSelector} on %{ports}"
msgstr ""
@@ -21994,34 +22168,28 @@ msgid "NetworkPolicies|Allow all outbound traffic from %{selector} to %{ruleSele
msgstr ""
msgid "NetworkPolicies|Are you sure you want to delete this policy? This action cannot be undone."
-msgstr ""
+msgstr "Er du sikker på, at du vil slette regelsættet? Handlingen kan ikke fortrydes."
msgid "NetworkPolicies|Create policy"
-msgstr ""
+msgstr "Opret regelsæt"
msgid "NetworkPolicies|Define this policy's location, conditions and actions."
msgstr ""
msgid "NetworkPolicies|Delete policy"
-msgstr ""
+msgstr "Slet regelsæt"
msgid "NetworkPolicies|Delete policy: %{policy}"
-msgstr ""
+msgstr "Slet regelsæt: %{policy}"
msgid "NetworkPolicies|Deny all traffic"
msgstr ""
msgid "NetworkPolicies|Description"
-msgstr ""
+msgstr "Beskrivelse"
msgid "NetworkPolicies|Edit policy"
-msgstr ""
-
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
+msgstr "Rediger regelsæt"
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22045,16 +22213,16 @@ msgid "NetworkPolicies|Kubernetes error: %{error}"
msgstr ""
msgid "NetworkPolicies|Name"
-msgstr ""
+msgstr "Navn"
msgid "NetworkPolicies|Network"
-msgstr ""
+msgstr "Netværk"
msgid "NetworkPolicies|Network traffic"
-msgstr ""
+msgstr "Netværkstrafik"
msgid "NetworkPolicies|New policy"
-msgstr ""
+msgstr "Nyt regelsæt"
msgid "NetworkPolicies|No policies detected"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,38 +22242,26 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
-msgstr ""
+msgstr "Regel"
msgid "NetworkPolicies|Rule mode"
-msgstr ""
+msgstr "Regeltilstand"
msgid "NetworkPolicies|Rule mode is unavailable for this policy. In some cases, we cannot parse the YAML file back into the rules editor."
msgstr ""
msgid "NetworkPolicies|Rules"
-msgstr ""
+msgstr "Regler"
msgid "NetworkPolicies|Save changes"
-msgstr ""
-
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
+msgstr "Gem ændringer"
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22123,10 +22276,10 @@ msgid "NetworkPolicies|Unable to parse policy"
msgstr ""
msgid "NetworkPolicies|all DNS names"
-msgstr ""
+msgstr "Alle DNS-navne"
msgid "NetworkPolicies|all IP addresses"
-msgstr ""
+msgstr "alle IP-adresser"
msgid "NetworkPolicies|any pod"
msgstr ""
@@ -22135,7 +22288,7 @@ msgid "NetworkPolicies|any port"
msgstr ""
msgid "NetworkPolicies|domain name"
-msgstr ""
+msgstr "domænenavn"
msgid "NetworkPolicies|entity"
msgstr ""
@@ -22165,16 +22318,16 @@ msgid "NetworkPolicies|ports/protocols"
msgstr ""
msgid "NetworkPolicy|Policy"
-msgstr ""
+msgstr "Regelsæt"
msgid "NetworkPolicy|Search by policy name"
-msgstr ""
+msgstr "Søg efter regelsæt"
msgid "NetworkPolicy|Status"
-msgstr ""
+msgstr "Status"
msgid "Never"
-msgstr ""
+msgstr "Aldrig"
msgid "New"
msgstr ""
@@ -22183,82 +22336,79 @@ msgid "New %{issueType}"
msgstr ""
msgid "New Application"
-msgstr ""
+msgstr "Nyt program"
msgid "New Branch"
-msgstr ""
+msgstr "Ny gren"
msgid "New Deploy Key"
-msgstr ""
+msgstr "Ny udsendelsesnøgle"
msgid "New Environment"
-msgstr ""
+msgstr "Nyt miljø"
msgid "New Epic"
-msgstr ""
+msgstr "Ny epic"
msgid "New File"
-msgstr ""
+msgstr "Ny fil"
msgid "New Group"
-msgstr ""
+msgstr "Ny gruppe"
msgid "New Group Name"
-msgstr ""
+msgstr "Nyt gruppenavn"
msgid "New Identity"
-msgstr ""
+msgstr "Ny identitet"
msgid "New Issue"
msgid_plural "New Issues"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Ny problemstilling"
+msgstr[1] "Nye problemstillinger"
msgid "New Jira import"
-msgstr ""
+msgstr "Ny Jira-import"
msgid "New Label"
-msgstr ""
+msgstr "Ny etiket"
msgid "New Milestone"
-msgstr ""
+msgstr "Ny milepæl"
msgid "New Pages Domain"
msgstr ""
msgid "New Password"
-msgstr ""
+msgstr "Ny adgangskode"
msgid "New Pipeline Schedule"
msgstr ""
msgid "New Project"
-msgstr ""
+msgstr "Nyt projekt"
msgid "New Requirement"
-msgstr ""
+msgstr "Nyt krav"
msgid "New Snippet"
-msgstr ""
+msgstr "Nyt uddrag"
msgid "New Test Case"
-msgstr ""
+msgstr "Ny testsag"
msgid "New User"
-msgstr ""
+msgstr "Ny bruger"
msgid "New application"
-msgstr ""
+msgstr "Nyt program"
msgid "New branch"
-msgstr ""
+msgstr "Ny gren"
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22266,28 +22416,28 @@ msgid "New confidential issue title"
msgstr ""
msgid "New deploy key"
-msgstr ""
+msgstr "Ny udsendelsesnøgle"
msgid "New directory"
-msgstr ""
+msgstr "Ny mappe"
msgid "New discussion"
-msgstr ""
+msgstr "Ny debat"
msgid "New environment"
-msgstr ""
+msgstr "Nyt miljø"
msgid "New epic"
-msgstr ""
+msgstr "Ny epic"
msgid "New epic title"
msgstr ""
msgid "New file"
-msgstr ""
+msgstr "Ny fil"
msgid "New group"
-msgstr ""
+msgstr "Ny gruppe"
msgid "New group URL"
msgstr ""
@@ -22299,55 +22449,55 @@ msgid "New health check access token has been generated!"
msgstr ""
msgid "New identity"
-msgstr ""
+msgstr "Ny identitet"
msgid "New issue"
-msgstr ""
+msgstr "Ny problemstilling"
msgid "New issue title"
msgstr ""
msgid "New iteration created"
-msgstr ""
+msgstr "Nyt gennemløb oprettet"
msgid "New label"
-msgstr ""
+msgstr "Ny etiket"
msgid "New list"
-msgstr ""
+msgstr "Ny liste"
msgid "New merge request"
-msgstr ""
+msgstr "Ny sammenlægningsanmodning"
msgid "New milestone"
-msgstr ""
+msgstr "Ny milepæl"
msgid "New password"
-msgstr ""
+msgstr "Ny adgangskode"
msgid "New pipelines cause older pending or running pipelines on the same branch to be cancelled."
msgstr ""
msgid "New project"
-msgstr ""
+msgstr "Nyt projekt"
msgid "New project page"
-msgstr ""
+msgstr "Ny projektside"
msgid "New project pages"
-msgstr ""
+msgstr "Nye projektsider"
msgid "New project/repository"
msgstr ""
msgid "New public deploy key"
-msgstr ""
+msgstr "Ny offentlig udsendelsesnøgle"
msgid "New release"
-msgstr ""
+msgstr "Ny udgivelse"
msgid "New requirement"
-msgstr ""
+msgstr "Nyt krav"
msgid "New response for issue #%{issue_iid}:"
msgstr ""
@@ -22359,16 +22509,16 @@ msgid "New schedule"
msgstr ""
msgid "New snippet"
-msgstr ""
+msgstr "Nyt uddrag"
msgid "New subgroup"
-msgstr ""
+msgstr "Ny undergruppe"
msgid "New tag"
-msgstr ""
+msgstr "Nyt mærkat"
msgid "New test case"
-msgstr ""
+msgstr "Ny testsag"
msgid "New users set to external"
msgstr ""
@@ -22377,34 +22527,34 @@ msgid "New! Suggest changes directly"
msgstr ""
msgid "New..."
-msgstr ""
+msgstr "Ny(t) ..."
msgid "Newest first"
-msgstr ""
+msgstr "Nyeste først"
msgid "Newly registered users will by default be external"
msgstr ""
msgid "Next"
-msgstr ""
+msgstr "Næste"
msgid "Next commit"
-msgstr ""
+msgstr "Næste commit"
msgid "Next design"
-msgstr ""
+msgstr "Næste design"
msgid "Next file in diff"
-msgstr ""
+msgstr "Næste fil i diff"
msgid "Next unresolved discussion"
-msgstr ""
+msgstr "Næste uløste debat"
msgid "Nickname"
-msgstr ""
+msgstr "Kaldenavn"
msgid "No"
-msgstr ""
+msgstr "Nej"
msgid "No %{header} for this request."
msgstr ""
@@ -22413,33 +22563,36 @@ msgid "No %{providerTitle} repositories found"
msgstr ""
msgid "No CSV data to display."
-msgstr ""
+msgstr "Ingen CSV-data at vise."
msgid "No Epic"
-msgstr ""
+msgstr "Ingen epic"
msgid "No Matching Results"
msgstr ""
msgid "No Milestone"
-msgstr ""
+msgstr "Ingen milepæl"
msgid "No Scopes"
-msgstr ""
+msgstr "Ingen omfang"
msgid "No Tag"
-msgstr ""
+msgstr "Intet mærkat"
msgid "No active admin user found"
msgstr ""
msgid "No activities found"
-msgstr ""
+msgstr "Ingen aktivitet fundet"
msgid "No application_settings found"
-msgstr ""
+msgstr "Ingen application_settings fundet"
msgid "No approvers"
+msgstr "Ingen godkendere"
+
+msgid "No artifacts found"
msgstr ""
msgid "No assignee"
@@ -22449,28 +22602,28 @@ msgid "No authentication methods configured."
msgstr ""
msgid "No available branches"
-msgstr ""
+msgstr "Ingen tilgængelige grene"
msgid "No available groups to fork the project."
-msgstr ""
+msgstr "Ingen tilgængelige grupper til at forgrene projektet."
msgid "No branches found"
-msgstr ""
+msgstr "Ingen grene fundet"
msgid "No changes"
-msgstr ""
+msgstr "Ingen ændringer"
msgid "No changes between %{source} and %{target}"
-msgstr ""
+msgstr "Ingen ændringer mellem %{source} og %{target}"
msgid "No child epics match applied filters"
msgstr ""
msgid "No commenters"
-msgstr ""
+msgstr "Ingen kommentatorer"
msgid "No commits present here"
-msgstr ""
+msgstr "Her er ingen commits"
msgid "No committers"
msgstr ""
@@ -22491,7 +22644,7 @@ msgid "No containers available"
msgstr ""
msgid "No contributions"
-msgstr ""
+msgstr "Ingen bidrag"
msgid "No contributions were found"
msgstr ""
@@ -22500,79 +22653,79 @@ msgid "No credit card required."
msgstr ""
msgid "No data found"
-msgstr ""
+msgstr "Ingen data fundet"
msgid "No data to display"
-msgstr ""
+msgstr "Ingen data at vise"
msgid "No deployments detected. Use environments to control your software's continuous deployment. %{linkStart}Learn more about deployment jobs.%{linkEnd}"
msgstr ""
msgid "No deployments found"
-msgstr ""
+msgstr "Ingen udsendelser fundet"
msgid "No due date"
-msgstr ""
+msgstr "Ingen forfaldsdato"
msgid "No email participants were added. Either none were provided, or they already exist."
msgstr ""
msgid "No endpoint provided"
-msgstr ""
+msgstr "Intet slutpunkt angivet"
msgid "No errors to display."
-msgstr ""
+msgstr "Ingen fejl at vise."
msgid "No estimate or time spent"
msgstr ""
msgid "No file chosen."
-msgstr ""
+msgstr "Ingen fil valgt."
msgid "No file hooks found."
-msgstr ""
+msgstr "Ingen filhooks fundet."
msgid "No file selected"
-msgstr ""
+msgstr "Ingen fil valgt"
msgid "No files"
-msgstr ""
+msgstr "Ingen filer"
msgid "No files found."
-msgstr ""
+msgstr "Ingen filer fundet."
msgid "No forks are available to you."
msgstr ""
msgid "No grouping"
-msgstr ""
+msgstr "Ingen gruppering"
msgid "No issues found"
-msgstr ""
+msgstr "Ingen problemstillinger fundet"
msgid "No iteration"
-msgstr ""
+msgstr "Ingen gennemløb"
msgid "No iterations found"
-msgstr ""
+msgstr "Ingen gennemløb fundet"
msgid "No iterations to show"
-msgstr ""
+msgstr "Ingen gennemløb at vise"
msgid "No job log"
-msgstr ""
+msgstr "Ingen joblog"
msgid "No jobs to show"
-msgstr ""
+msgstr "Ingen job at vise"
msgid "No label"
-msgstr ""
+msgstr "Ingen etiket"
msgid "No labels with such name or description"
msgstr ""
msgid "No license. All rights reserved"
-msgstr ""
+msgstr "Ingen licens. Alle rettigheder forbeholdt"
msgid "No matches found"
msgstr ""
@@ -22593,19 +22746,19 @@ msgid "No matching results..."
msgstr ""
msgid "No members found"
-msgstr ""
+msgstr "Ingen medlemmer fundet"
msgid "No merge requests found"
-msgstr ""
+msgstr "Ingen sammenlægningsanmodninger fundet"
msgid "No messages were logged"
-msgstr ""
+msgstr "Ingen meddelelser blev logget"
msgid "No milestone"
-msgstr ""
+msgstr "Ingen milepæl"
msgid "No milestones to show"
-msgstr ""
+msgstr "Ingen milepæle at vise"
msgid "No other labels with such name or description"
msgstr ""
@@ -22617,7 +22770,7 @@ msgid "No parent group"
msgstr ""
msgid "No plan"
-msgstr ""
+msgstr "Ingen plan"
msgid "No pods available"
msgstr ""
@@ -22632,13 +22785,13 @@ msgid "No prioritized labels with such name or description"
msgstr ""
msgid "No profiles found"
-msgstr ""
+msgstr "Ingen profiler fundet"
msgid "No projects found"
-msgstr ""
+msgstr "Ingen projekter fundet"
msgid "No public groups"
-msgstr ""
+msgstr "Ingen offentlige grupper"
msgid "No ref selected"
msgstr ""
@@ -22647,7 +22800,7 @@ msgid "No related merge requests found."
msgstr ""
msgid "No repository"
-msgstr ""
+msgstr "Intet depot"
msgid "No runner executable"
msgstr ""
@@ -22662,7 +22815,7 @@ msgid "No severity matches the provided parameter"
msgstr ""
msgid "No source selected"
-msgstr ""
+msgstr "Ingen kilde valgt"
msgid "No stack trace for this error"
msgstr ""
@@ -22671,61 +22824,61 @@ msgid "No starrers matched your search"
msgstr ""
msgid "No start date"
-msgstr ""
+msgstr "Ingen startdato"
msgid "No tag selected"
-msgstr ""
+msgstr "Intet mærkat valgt"
msgid "No template"
-msgstr ""
+msgstr "Ingen skabelon"
msgid "No template selected"
-msgstr ""
+msgstr "Ingen skabelon valgt"
msgid "No test coverage"
-msgstr ""
+msgstr "Ingen testdækning"
msgid "No triggers exist yet. Use the form above to create one."
msgstr ""
msgid "No vulnerabilities present"
-msgstr ""
+msgstr "Ingen sårbarheder tilstede"
msgid "No webhooks found, add one in the form above."
-msgstr ""
+msgstr "Ingen webhooks fundet, tilføj en i formularen ovenover."
msgid "No worries, you can still use all the %{strong}%{plan_name}%{strong_close} features for now. You have %{remaining_days} to renew your subscription."
msgstr ""
msgid "No. of commits"
-msgstr ""
+msgstr "Antal commits"
msgid "Nobody has starred this repository yet"
msgstr ""
msgid "Node was successfully created."
-msgstr ""
+msgstr "Knudepunkt blev oprettet."
msgid "Node was successfully updated."
-msgstr ""
+msgstr "Knudepunkt blev opdateret."
msgid "Nodes"
-msgstr ""
+msgstr "Knudepunkter"
msgid "Non-admin users can sign in with read-only access and make read-only API requests."
msgstr ""
msgid "None"
-msgstr ""
+msgstr "Ingen"
msgid "None of the group milestones have the same project as the release"
msgstr ""
msgid "Normal text"
-msgstr ""
+msgstr "Normal tekst"
msgid "Not Implemented"
-msgstr ""
+msgstr "Ikke implementeret"
msgid "Not all browsers support U2F devices. Therefore, we require that you set up a two-factor authentication app first. That way you'll always be able to sign in - even when you're using an unsupported browser."
msgstr ""
@@ -22737,34 +22890,34 @@ msgid "Not all data has been processed yet, the accuracy of the chart for the se
msgstr ""
msgid "Not available"
-msgstr ""
+msgstr "Ikke tilgængelig"
msgid "Not available for private projects"
-msgstr ""
+msgstr "Ikke tilgængelig for private projekter"
msgid "Not available for protected branches"
-msgstr ""
+msgstr "Ikke tilgængelig for beskyttede grene"
msgid "Not available to run jobs."
-msgstr ""
+msgstr "Ikke tilgængelig til at køre job."
msgid "Not confidential"
-msgstr ""
+msgstr "Ikke fortrolig"
msgid "Not found."
-msgstr ""
+msgstr "Ikke fundet."
msgid "Not permitted to destroy framework"
msgstr ""
msgid "Not ready yet. Try again later."
-msgstr ""
+msgstr "Ikke klar endnu. Prøv igen senere."
msgid "Not started"
-msgstr ""
+msgstr "Ikke startet"
msgid "Not supported"
-msgstr ""
+msgstr "Ikke understøttet"
msgid "Note"
msgstr ""
@@ -22797,10 +22950,10 @@ msgid "Notes Rate Limits"
msgstr ""
msgid "Notes|Are you sure you want to cancel creating this comment?"
-msgstr ""
+msgstr "Er du sikker på, at du vil annullere oprettelse af kommentaren?"
msgid "Notes|Collapse replies"
-msgstr ""
+msgstr "Sammenfold svar"
msgid "Notes|Confidential comments are only visible to project members"
msgstr ""
@@ -22809,13 +22962,13 @@ msgid "Notes|Make this comment confidential"
msgstr ""
msgid "Notes|Show all activity"
-msgstr ""
+msgstr "Vis al aktivitet"
msgid "Notes|Show comments only"
-msgstr ""
+msgstr "Vis kun kommentarer"
msgid "Notes|Show history only"
-msgstr ""
+msgstr "Vis kun historik"
msgid "Notes|This comment has changed since you started editing, please review the %{open_link}updated comment%{close_link} to ensure information is not lost"
msgstr ""
@@ -22827,19 +22980,19 @@ msgid "Notes|You're only seeing %{boldStart}other activity%{boldEnd} in the feed
msgstr ""
msgid "Nothing found…"
-msgstr ""
+msgstr "Intet fundet …"
msgid "Nothing to preview."
-msgstr ""
+msgstr "Intet at forhåndsvise."
msgid "Notification events"
-msgstr ""
+msgstr "Underretningshændelser"
msgid "Notification setting - %{notification_title}"
-msgstr ""
+msgstr "Underretningsindstilling - %{notification_title}"
msgid "Notification settings saved"
-msgstr ""
+msgstr "Underretningsindstillinger gemt"
msgid "NotificationEmail|Assignee"
msgid_plural "NotificationEmail|Assignees"
@@ -22853,22 +23006,22 @@ msgstr[1] ""
msgid "NotificationEmail|Reviewer"
msgid_plural "NotificationEmail|Reviewers"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Kontrollant"
+msgstr[1] "Kontrollanter"
msgid "NotificationEmail|Reviewer: %{users}"
msgid_plural "NotificationEmail|Reviewers: %{users}"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Kontrollant: %{users}"
+msgstr[1] "Kontrollanter: %{users}"
msgid "NotificationEvent|Change reviewer merge request"
msgstr ""
msgid "NotificationEvent|Close issue"
-msgstr ""
+msgstr "Luk problemstilling"
msgid "NotificationEvent|Close merge request"
-msgstr ""
+msgstr "Luk sammenlægningsanmodning"
msgid "NotificationEvent|Failed pipeline"
msgstr ""
@@ -22880,7 +23033,7 @@ msgid "NotificationEvent|Issue due"
msgstr ""
msgid "NotificationEvent|Merge merge request"
-msgstr ""
+msgstr "Sammenlæg sammenlægningsanmodning"
msgid "NotificationEvent|Merge when pipeline succeeds"
msgstr ""
@@ -22889,19 +23042,19 @@ msgid "NotificationEvent|Moved project"
msgstr ""
msgid "NotificationEvent|New epic"
-msgstr ""
+msgstr "Ny epic"
msgid "NotificationEvent|New issue"
-msgstr ""
+msgstr "Ny problemstilling"
msgid "NotificationEvent|New merge request"
-msgstr ""
+msgstr "Ny sammenlægningsanmodning"
msgid "NotificationEvent|New note"
msgstr ""
msgid "NotificationEvent|New release"
-msgstr ""
+msgstr "Ny udgivelse"
msgid "NotificationEvent|Push to merge request"
msgstr ""
@@ -22913,54 +23066,57 @@ msgid "NotificationEvent|Reassign merge request"
msgstr ""
msgid "NotificationEvent|Reopen issue"
-msgstr ""
+msgstr "Genåbn problemstilling"
msgid "NotificationEvent|Reopen merge request"
-msgstr ""
+msgstr "Genåbn sammenlægningsanmodning"
msgid "NotificationEvent|Successful pipeline"
msgstr ""
msgid "NotificationLevel|Custom"
-msgstr ""
+msgstr "Tilpasset"
msgid "NotificationLevel|Disabled"
-msgstr ""
+msgstr "Deaktiveret"
msgid "NotificationLevel|Global"
-msgstr ""
+msgstr "Global"
msgid "NotificationLevel|On mention"
msgstr ""
msgid "NotificationLevel|Participate"
-msgstr ""
+msgstr "Deltag"
msgid "NotificationLevel|Watch"
msgstr ""
msgid "Notifications"
-msgstr ""
+msgstr "Underretninger"
msgid "Notifications have been disabled by the project or group owner"
-msgstr ""
+msgstr "Underretninger er blevet deaktiveret af projekt- eller gruppeejeren"
msgid "Notifications off"
-msgstr ""
+msgstr "Underretninger fra"
msgid "Notifications on"
-msgstr ""
+msgstr "Underretninger til"
msgid "Notify users by email when sign-in location is not recognized."
msgstr ""
msgid "Nov"
-msgstr ""
+msgstr "Nov."
msgid "November"
-msgstr ""
+msgstr "November"
msgid "Novice"
+msgstr "Nybegynder"
+
+msgid "Now, personalize your GitLab experience"
msgstr ""
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
@@ -22979,7 +23135,7 @@ msgid "Number of Git pushes after which an incremental %{code_start}git repack%{
msgstr ""
msgid "Number of LOCs per commit"
-msgstr ""
+msgstr "Antal LOC'er pr. commit"
msgid "Number of changes (branches or tags) in a single push to determine whether individual push events or bulk push event will be created. Bulk push event will be created if it surpasses that value."
msgstr ""
@@ -22988,28 +23144,28 @@ msgid "Number of changes (branches or tags) in a single push to determine whethe
msgstr ""
msgid "Number of commits"
-msgstr ""
+msgstr "Antal commits"
msgid "Number of commits per MR"
-msgstr ""
+msgstr "Antal commits pr. sammenlægningsanmodning"
msgid "Number of events"
-msgstr ""
+msgstr "Antal hændelser"
msgid "Number of events for this project: %{total_count}."
-msgstr ""
+msgstr "Antal hændelser for projektet: %{total_count}."
msgid "Number of files touched"
-msgstr ""
+msgstr "Antal filer berørt"
msgid "Number of replicas"
msgstr ""
msgid "Number of shards"
-msgstr ""
+msgstr "Antal shards"
msgid "OK"
-msgstr ""
+msgstr "OK"
msgid "Object Storage replication"
msgstr ""
@@ -23018,28 +23174,28 @@ msgid "Object does not exist on the server or you don't have permissions to acce
msgstr ""
msgid "Oct"
-msgstr ""
+msgstr "Okt."
msgid "October"
-msgstr ""
+msgstr "Oktober"
msgid "OfSearchInADropdown|Filter"
msgstr ""
msgid "Off"
-msgstr ""
+msgstr "Fra"
msgid "Oh no!"
-msgstr ""
+msgstr "Ã…h nej!"
msgid "Ok, let's go"
-msgstr ""
+msgstr "Ok lad os komme i gang"
msgid "Okay"
-msgstr ""
+msgstr "Okay"
msgid "Oldest first"
-msgstr ""
+msgstr "Ældste først"
msgid "OmniAuth"
msgstr ""
@@ -23048,7 +23204,7 @@ msgid "Omnibus Protected Paths throttle is active, and takes priority over these
msgstr ""
msgid "On"
-msgstr ""
+msgstr "Til"
msgid "On track"
msgstr ""
@@ -23063,10 +23219,10 @@ msgid "OnCallScheduless|Any escalation rules that are using this schedule will a
msgstr ""
msgid "OnCallSchedules|1 day"
-msgstr ""
+msgstr "1 dag"
msgid "OnCallSchedules|2 weeks"
-msgstr ""
+msgstr "2 uger"
msgid "OnCallSchedules|Add a rotation"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23168,10 +23324,10 @@ msgid "OnCallSchedules|Route alerts directly to specific members of your team"
msgstr ""
msgid "OnCallSchedules|Select participant"
-msgstr ""
+msgstr "Vælg deltager"
msgid "OnCallSchedules|Select timezone"
-msgstr ""
+msgstr "Vælg tidszone"
msgid "OnCallSchedules|Sets the default timezone for the schedule, for all participants"
msgstr ""
@@ -23228,7 +23384,7 @@ msgid "OnDemandScans|Create new site profile"
msgstr ""
msgid "OnDemandScans|Description (optional)"
-msgstr ""
+msgstr "Beskrivelse (valgfrit)"
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
@@ -23273,7 +23429,7 @@ msgid "OnDemandScans|Scan name"
msgstr ""
msgid "OnDemandScans|Scanner profile"
-msgstr ""
+msgstr "Skannerprofil"
msgid "OnDemandScans|Select one of the existing profiles"
msgstr ""
@@ -23312,12 +23468,12 @@ msgid "Once the exported file is ready, you will receive a notification email wi
msgstr ""
msgid "Once you confirm and press \"Reduce project visibility\":"
-msgstr ""
+msgstr "Når du bekræfter og trykker på \"Reducer projektets synlighed\":"
msgid "One more item"
msgid_plural "%d more items"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Et element mere"
+msgstr[1] "%d elementer mere"
msgid "One or more groups that you don't have access to."
msgstr ""
@@ -23347,25 +23503,25 @@ msgid "Only Issue ID or merge request ID is required"
msgstr ""
msgid "Only Project Members"
-msgstr ""
+msgstr "Kun projektmedlemmer"
msgid "Only active projects show up in the search and on the dashboard."
msgstr ""
msgid "Only admins can delete project"
-msgstr ""
+msgstr "Kun administratorer kan slette projektet"
msgid "Only include features new to your current subscription tier."
msgstr ""
msgid "Only policy:"
-msgstr ""
+msgstr "Kun regelsæt:"
msgid "Only proceed if you trust %{idp_url} to control your GitLab account sign in."
msgstr ""
msgid "Only project members can comment."
-msgstr ""
+msgstr "Kun projektmedlemmer kan kommentere."
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
@@ -23380,46 +23536,46 @@ msgid "Only ‘Reporter’ roles and above on tiers Premium and above can see Pr
msgstr ""
msgid "Oops, are you sure?"
-msgstr ""
+msgstr "Ups, er du sikker?"
msgid "Open"
-msgstr ""
+msgstr "Ã…ben"
msgid "Open Selection"
-msgstr ""
+msgstr "Ã…bn markering"
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
msgstr ""
msgid "Open epics"
-msgstr ""
+msgstr "Ã…bne epics"
msgid "Open errors"
-msgstr ""
+msgstr "Ã…bne fejl"
msgid "Open in file view"
-msgstr ""
+msgstr "Ã…bn i filvisning"
msgid "Open in your IDE"
-msgstr ""
+msgstr "Ã…bn i din IDE"
msgid "Open raw"
-msgstr ""
+msgstr "Åbn rå"
msgid "Open registration is enabled on your instance."
msgstr ""
msgid "Open sidebar"
-msgstr ""
+msgstr "Åbn sidebjælke"
msgid "Open: %{open}"
msgstr ""
msgid "OpenAPI"
-msgstr ""
+msgstr "OpenAPI"
msgid "OpenAPI Specification file path or URL"
msgstr ""
@@ -23431,13 +23587,13 @@ msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
-msgstr ""
+msgstr "Ã…bne problemstillinger"
msgid "OpenedNDaysAgo|Opened"
msgstr ""
msgid "Opens in a new window"
-msgstr ""
+msgstr "Ã…bnes i et nyt vindue"
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -23455,13 +23611,13 @@ msgid "Operations Dashboard"
msgstr ""
msgid "OperationsDashboard|Add a project to the dashboard"
-msgstr ""
+msgstr "Tilføj et projekt til betjeningspanelet"
msgid "OperationsDashboard|Add projects"
-msgstr ""
+msgstr "Tilføj projekter"
msgid "OperationsDashboard|More information"
-msgstr ""
+msgstr "Mere information"
msgid "OperationsDashboard|Operations Dashboard"
msgstr ""
@@ -23470,10 +23626,10 @@ msgid "OperationsDashboard|The operations dashboard provides a summary of each p
msgstr ""
msgid "Optimize your workflow with CI/CD Pipelines"
-msgstr ""
+msgstr "Optimer dit workflow med CI-/CD-pipelines"
msgid "Optional"
-msgstr ""
+msgstr "Valgfrit"
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
@@ -23482,7 +23638,7 @@ msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and
msgstr ""
msgid "Options"
-msgstr ""
+msgstr "Valgmuligheder"
msgid "Or you can choose one of the suggested colors below"
msgstr ""
@@ -23491,19 +23647,19 @@ msgid "Orphaned member"
msgstr ""
msgid "Other Labels"
-msgstr ""
+msgstr "Andre etiketter"
msgid "Other available runners"
msgstr ""
msgid "Other information"
-msgstr ""
+msgstr "Anden information"
msgid "Other merge requests block this MR"
msgstr ""
msgid "Other versions"
-msgstr ""
+msgstr "Andre versioner"
msgid "Other visibility settings have been disabled by the administrator."
msgstr ""
@@ -23527,37 +23683,37 @@ msgid "OutdatedBrowser|GitLab may not work properly, because you are using an ou
msgstr ""
msgid "OutdatedBrowser|Please install a %{browser_link_start}supported web browser%{browser_link_end} for a better experience."
-msgstr ""
+msgstr "Installer venligst en %{browser_link_start}understøttede webbrowser%{browser_link_end} for at få en bedre oplevelse."
msgid "Outdent"
msgstr ""
msgid "Overridden"
-msgstr ""
+msgstr "Tilsidesat"
msgid "Overview"
-msgstr ""
+msgstr "Oversigt"
msgid "Overwrite diverged branches"
msgstr ""
msgid "Owned by %{image_tag}"
-msgstr ""
+msgstr "Ejet af %{image_tag}"
msgid "Owned by anyone"
-msgstr ""
+msgstr "Ejet af alle"
msgid "Owned by me"
-msgstr ""
+msgstr "Ejet af mig"
msgid "Owned by:"
-msgstr ""
+msgstr "Ejet af:"
msgid "Owner"
-msgstr ""
+msgstr "Ejer"
msgid "Package Registry"
-msgstr ""
+msgstr "Pakkeregister"
msgid "Package Registry Rate Limits"
msgstr ""
@@ -23569,7 +23725,7 @@ msgid "Package Registry: unauthenticated API requests"
msgstr ""
msgid "Package already exists"
-msgstr ""
+msgstr "Pakken findes allerede"
msgid "Package deleted successfully"
msgstr ""
@@ -23580,26 +23736,29 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
-msgid "Package type must be Conan"
+msgid "Package type"
msgstr ""
+msgid "Package type must be Conan"
+msgstr "Pakketype skal være Conan"
+
msgid "Package type must be Debian"
-msgstr ""
+msgstr "Pakketype skal være Debian"
msgid "Package type must be Helm"
-msgstr ""
+msgstr "Pakketype skal være Helm"
msgid "Package type must be Maven"
-msgstr ""
+msgstr "Pakketype skal være Maven"
msgid "Package type must be NuGet"
-msgstr ""
+msgstr "Pakketype skal være NuGet"
msgid "Package type must be PyPi"
-msgstr ""
+msgstr "Pakketype skal være PyPi"
msgid "Package type must be RubyGems"
-msgstr ""
+msgstr "Pakketype skal være RubyGems"
msgid "PackageRegistry|%{boldStart}Allow duplicates%{boldEnd} - Accept packages with the same name and version."
msgstr ""
@@ -23623,7 +23782,7 @@ msgid "PackageRegistry|Add NuGet Source"
msgstr ""
msgid "PackageRegistry|Add composer registry"
-msgstr ""
+msgstr "Tilføj composer-register"
msgid "PackageRegistry|Allow duplicates"
msgstr ""
@@ -23641,7 +23800,7 @@ msgid "PackageRegistry|Built by pipeline %{link} triggered %{datetime} by %{auth
msgstr ""
msgid "PackageRegistry|Composer"
-msgstr ""
+msgstr "Composer"
msgid "PackageRegistry|Conan"
msgstr ""
@@ -23707,7 +23866,7 @@ msgid "PackageRegistry|Copy require package include"
msgstr ""
msgid "PackageRegistry|Copy yarn command"
-msgstr ""
+msgstr "Kopiér yarn-kommando"
msgid "PackageRegistry|Copy yarn setup command"
msgstr ""
@@ -23716,34 +23875,34 @@ msgid "PackageRegistry|Created by commit %{link} on branch %{branch}"
msgstr ""
msgid "PackageRegistry|Debian"
-msgstr ""
+msgstr "Debian"
msgid "PackageRegistry|Delete Package File"
-msgstr ""
+msgstr "Slet pakkefil"
msgid "PackageRegistry|Delete Package Version"
-msgstr ""
+msgstr "Slet pakkeversion"
msgid "PackageRegistry|Delete package"
-msgstr ""
+msgstr "Slet pakke"
msgid "PackageRegistry|Failed to load the package data"
msgstr ""
msgid "PackageRegistry|For more information on Composer packages in GitLab, %{linkStart}see the documentation.%{linkEnd}"
-msgstr ""
+msgstr "%{linkStart}Se dokumentationen%{linkEnd} for mere information om Composer-pakker i GitLab."
msgid "PackageRegistry|For more information on the Conan registry, %{linkStart}see the documentation%{linkEnd}."
-msgstr ""
+msgstr "%{linkStart}Se dokumentationen%{linkEnd} for mere information om Conan-registeret."
msgid "PackageRegistry|For more information on the Maven registry, %{linkStart}see the documentation%{linkEnd}."
-msgstr ""
+msgstr "%{linkStart}Se dokumentationen%{linkEnd} for mere information om Maven-registeret."
msgid "PackageRegistry|For more information on the NuGet registry, %{linkStart}see the documentation%{linkEnd}."
-msgstr ""
+msgstr "%{linkStart}Se dokumentationen%{linkEnd} for mere information om NuGet-registeret."
msgid "PackageRegistry|For more information on the PyPi registry, %{linkStart}see the documentation%{linkEnd}."
-msgstr ""
+msgstr "%{linkStart}Se dokumentationen%{linkEnd} for mere information om PyPi-registeret."
msgid "PackageRegistry|Generic"
msgstr ""
@@ -23785,19 +23944,19 @@ msgid "PackageRegistry|Manually Published"
msgstr ""
msgid "PackageRegistry|Maven"
-msgstr ""
+msgstr "Maven"
msgid "PackageRegistry|Maven Command"
-msgstr ""
+msgstr "Maven-kommando"
msgid "PackageRegistry|Maven XML"
msgstr ""
msgid "PackageRegistry|NuGet"
-msgstr ""
+msgstr "NuGet"
msgid "PackageRegistry|NuGet Command"
-msgstr ""
+msgstr "NuGet-kommando"
msgid "PackageRegistry|Package Registry"
msgstr ""
@@ -23815,7 +23974,7 @@ msgid "PackageRegistry|Package updated by commit %{link} on branch %{branch}, bu
msgstr ""
msgid "PackageRegistry|Pip Command"
-msgstr ""
+msgstr "Pip-kommando"
msgid "PackageRegistry|Publish and share packages for a variety of common package managers. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
@@ -23827,7 +23986,7 @@ msgid "PackageRegistry|Published to the %{project} Package Registry %{datetime}"
msgstr ""
msgid "PackageRegistry|PyPI"
-msgstr ""
+msgstr "PyPI"
msgid "PackageRegistry|Recipe: %{recipe}"
msgstr ""
@@ -23836,7 +23995,7 @@ msgid "PackageRegistry|Registry setup"
msgstr ""
msgid "PackageRegistry|Remove package"
-msgstr ""
+msgstr "Fjern pakke"
msgid "PackageRegistry|RubyGems"
msgstr ""
@@ -23851,28 +24010,28 @@ msgid "PackageRegistry|Settings saved successfully"
msgstr ""
msgid "PackageRegistry|Show Composer commands"
-msgstr ""
+msgstr "Vis Composer-kommandoer"
msgid "PackageRegistry|Show Conan commands"
-msgstr ""
+msgstr "Vis Conan-kommandoer"
msgid "PackageRegistry|Show NPM commands"
-msgstr ""
+msgstr "Vis NPM-kommandoer"
msgid "PackageRegistry|Show Nuget commands"
-msgstr ""
+msgstr "Vis Nuget-kommandoer"
msgid "PackageRegistry|Show PyPi commands"
-msgstr ""
+msgstr "Vis PyPi-kommandoer"
msgid "PackageRegistry|Show Yarn commands"
-msgstr ""
+msgstr "Vis Yarn-kommandoer"
msgid "PackageRegistry|Something went wrong while deleting the package file."
-msgstr ""
+msgstr "Noget gik galt under sletning af pakkefilen."
msgid "PackageRegistry|Something went wrong while deleting the package."
-msgstr ""
+msgstr "Noget gik galt under sletning af pakken."
msgid "PackageRegistry|Sorry, your filter produced no results"
msgstr ""
@@ -23884,10 +24043,10 @@ msgid "PackageRegistry|There are no other versions of this package."
msgstr ""
msgid "PackageRegistry|There are no packages yet"
-msgstr ""
+msgstr "Der er endnu ingen pakker"
msgid "PackageRegistry|There was a problem fetching the details for this package."
-msgstr ""
+msgstr "Der var problemer med at hente detaljerne for pakken."
msgid "PackageRegistry|This NuGet package has no dependencies."
msgstr ""
@@ -23896,13 +24055,13 @@ msgid "PackageRegistry|To widen your search, change or remove the filters above.
msgstr ""
msgid "PackageRegistry|Type"
-msgstr ""
+msgstr "Type"
msgid "PackageRegistry|Unable to fetch package version information."
msgstr ""
msgid "PackageRegistry|Unable to load package"
-msgstr ""
+msgstr "Kan ikke indlæse pakke"
msgid "PackageRegistry|Use GitLab as a private registry for common package formats. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
@@ -23914,28 +24073,28 @@ msgid "PackageRegistry|You are about to delete %{name}, this operation is irreve
msgstr ""
msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
-msgstr ""
+msgstr "Du er ved at slette version %{version} af %{name}. Er du sikker?"
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
msgstr ""
msgid "PackageRegistry|npm"
-msgstr ""
+msgstr "npm"
msgid "PackageRegistry|published by %{author}"
-msgstr ""
+msgstr "udgivet af %{author}"
msgid "Packages & Registries"
msgstr ""
msgid "Page not found"
-msgstr ""
+msgstr "Siden blev ikke fundet"
msgid "Page settings"
-msgstr ""
+msgstr "Sideindstillinger"
msgid "PagerDutySettings|Active"
-msgstr ""
+msgstr "Aktiv"
msgid "PagerDutySettings|Create a GitLab incident for each PagerDuty incident by %{linkStart}configuring a webhook in PagerDuty%{linkEnd}"
msgstr ""
@@ -23959,40 +24118,40 @@ msgid "Pages"
msgstr ""
msgid "Pages Domain"
-msgstr ""
+msgstr "Pages-domæne"
msgid "Pagination|First"
-msgstr ""
+msgstr "Første"
msgid "Pagination|Go to first page"
-msgstr ""
+msgstr "Gå til første side"
msgid "Pagination|Go to last page"
-msgstr ""
+msgstr "GÃ¥ til sidste side"
msgid "Pagination|Go to next page"
-msgstr ""
+msgstr "Gå til næste side"
msgid "Pagination|Go to previous page"
-msgstr ""
+msgstr "GÃ¥ til forrige side"
msgid "Pagination|Last"
-msgstr ""
+msgstr "Sidste"
msgid "Pagination|Last »"
-msgstr ""
+msgstr "Sidste »"
msgid "Pagination|Next"
-msgstr ""
+msgstr "Næste"
msgid "Pagination|Prev"
-msgstr ""
+msgstr "Forrige"
msgid "Pagination|« First"
-msgstr ""
+msgstr "« Første"
msgid "Parameter"
-msgstr ""
+msgstr "Parameter"
msgid "Parameter \"job_id\" cannot exceed length of %{job_id_max_size}"
msgstr ""
@@ -24013,7 +24172,7 @@ msgid "Part of merge request changes"
msgstr ""
msgid "Participants"
-msgstr ""
+msgstr "Deltagere"
msgid "Pass job variables"
msgstr ""
@@ -24022,19 +24181,19 @@ msgid "Pass the header %{codeOpen} X-Profile-Token: %{profile_token} %{codeClose
msgstr ""
msgid "Passed"
-msgstr ""
+msgstr "Bestået"
msgid "Passed on"
msgstr ""
msgid "Password"
-msgstr ""
+msgstr "Adgangskode"
msgid "Password (for password-protected Elasticsearch servers)"
msgstr ""
msgid "Password (optional)"
-msgstr ""
+msgstr "Adgangskode (valgfrit)"
msgid "Password authentication is unavailable."
msgstr ""
@@ -24052,13 +24211,13 @@ msgid "Passwords should be unique and not used for any other sites or services."
msgstr ""
msgid "Past due"
-msgstr ""
+msgstr "Overskredet"
msgid "Paste a public key here."
-msgstr ""
+msgstr "Indsæt en offentlig nøgle her."
msgid "Paste a public key here. %{link_start}How do I generate it?%{link_end}"
-msgstr ""
+msgstr "Indsæt en offentlig nøgle her. %{link_start}Hvordan genererer jeg den?%{link_end}"
msgid "Paste confidential epic link"
msgstr ""
@@ -24073,7 +24232,7 @@ msgid "Paste issue link"
msgstr ""
msgid "Paste project path (i.e. gitlab-org/gitlab)"
-msgstr ""
+msgstr "Indsæt projektsti (f.eks. gitlab-org/gitlab)"
msgid "Paste your public SSH key, which is usually contained in the file '~/.ssh/id_ed25519.pub' or '~/.ssh/id_rsa.pub' and begins with 'ssh-ed25519' or 'ssh-rsa'. Do not paste your private SSH key, as that can compromise your identity."
msgstr ""
@@ -24082,16 +24241,16 @@ msgid "Patch to apply"
msgstr ""
msgid "Path"
-msgstr ""
+msgstr "Sti"
msgid "Path:"
-msgstr ""
+msgstr "Sti:"
msgid "Paths can contain wildcards, like */welcome"
-msgstr ""
+msgstr "Stier kan indeholde jokertegn såsom */velkommen"
msgid "Pause"
-msgstr ""
+msgstr "Pause"
msgid "Pause Elasticsearch indexing"
msgstr ""
@@ -24106,25 +24265,25 @@ msgid "Peer review by"
msgstr ""
msgid "Pending"
-msgstr ""
+msgstr "Afventende"
msgid "Pending comments"
-msgstr ""
+msgstr "Afventende kommentarer"
msgid "Pending sync…"
msgstr ""
msgid "People without permission will never get a notification and won't be able to comment."
-msgstr ""
+msgstr "Personer uden tilladelse får aldrig en underretning og kan ikke kommentere."
msgid "People without permission will never get a notification."
-msgstr ""
+msgstr "Personer uden tilladelse får aldrig en underretning."
msgid "Percent rollout must be an integer number between 0 and 100"
msgstr ""
msgid "Percentage"
-msgstr ""
+msgstr "Procent"
msgid "Perform advanced options such as changing path, transferring, exporting, or removing the group."
msgstr ""
@@ -24136,7 +24295,7 @@ msgid "Perform common operations on GitLab project"
msgstr ""
msgid "Performance optimization"
-msgstr ""
+msgstr "Ydelsesoptimering"
msgid "PerformanceBar|Backend"
msgstr ""
@@ -24148,7 +24307,7 @@ msgid "PerformanceBar|DOM Content Loaded"
msgstr ""
msgid "PerformanceBar|Download"
-msgstr ""
+msgstr "Download"
msgid "PerformanceBar|Elasticsearch calls"
msgstr ""
@@ -24166,7 +24325,7 @@ msgid "PerformanceBar|Gitaly calls"
msgstr ""
msgid "PerformanceBar|Memory"
-msgstr ""
+msgstr "Hukommelse"
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -24178,7 +24337,7 @@ msgid "PerformanceBar|SQL queries"
msgstr ""
msgid "PerformanceBar|Sort by duration"
-msgstr ""
+msgstr "Sortér efter varighed"
msgid "PerformanceBar|Sort chronologically"
msgstr ""
@@ -24193,19 +24352,19 @@ msgid "PerformanceBar|Trace"
msgstr ""
msgid "Period in seconds"
-msgstr ""
+msgstr "Periode i sekunder"
msgid "Permanently delete project"
-msgstr ""
+msgstr "Slet projekt permanent"
msgid "Permanently remove group"
-msgstr ""
+msgstr "Fjern gruppe permanent"
msgid "Permissions"
-msgstr ""
+msgstr "Tilladelser"
msgid "Permissions Help"
-msgstr ""
+msgstr "Hjælp for tilladelser"
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -24223,7 +24382,7 @@ msgid "Personal project creation is not allowed. Please contact your administrat
msgstr ""
msgid "Personal projects"
-msgstr ""
+msgstr "Personlige projekter"
msgid "Personal projects limit:"
msgstr ""
@@ -24238,13 +24397,13 @@ msgid "Phabricator Tasks"
msgstr ""
msgid "Pick a name"
-msgstr ""
+msgstr "Vælg et navn"
msgid "Pin code"
-msgstr ""
+msgstr "Pinkode"
msgid "Pipeline"
-msgstr ""
+msgstr "Pipeline"
msgid "Pipeline %{label}"
msgstr ""
@@ -24253,10 +24412,10 @@ msgid "Pipeline %{label} for \"%{dataTitle}\""
msgstr ""
msgid "Pipeline ID"
-msgstr ""
+msgstr "Pipeline-id"
msgid "Pipeline IID"
-msgstr ""
+msgstr "Pipeline-iid"
msgid "Pipeline Schedule"
msgstr ""
@@ -24391,43 +24550,43 @@ msgid "PipelineScheduleIntervalPattern|Custom (%{linkStart}Cron syntax%{linkEnd}
msgstr ""
msgid "PipelineSchedules|Activated"
-msgstr ""
+msgstr "Aktiveret"
msgid "PipelineSchedules|Active"
-msgstr ""
+msgstr "Aktiv"
msgid "PipelineSchedules|All"
-msgstr ""
+msgstr "Alle"
msgid "PipelineSchedules|Inactive"
-msgstr ""
+msgstr "Inaktiv"
msgid "PipelineSchedules|Next Run"
msgstr ""
msgid "PipelineSchedules|None"
-msgstr ""
+msgstr "Ingen"
msgid "PipelineSchedules|Provide a short description for this pipeline"
msgstr ""
msgid "PipelineSchedules|Take ownership"
-msgstr ""
+msgstr "Tag ejerskab"
msgid "PipelineSchedules|Target"
-msgstr ""
+msgstr "MÃ¥l"
msgid "PipelineSchedules|Variables"
-msgstr ""
+msgstr "Variabler"
msgid "PipelineStatusTooltip|Pipeline: %{ciStatus}"
-msgstr ""
+msgstr "Pipeline: %{ciStatus}"
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
-msgstr ""
+msgstr "Pipeline: %{ci_status}"
msgid "Pipelines"
-msgstr ""
+msgstr "Pipelines"
msgid "Pipelines charts"
msgstr ""
@@ -24439,13 +24598,13 @@ msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
msgid "Pipelines|API"
-msgstr ""
+msgstr "API"
msgid "Pipelines|Add a code quality job"
-msgstr ""
+msgstr "Tilføj et kodekvalitetsjob"
msgid "Pipelines|Are you sure you want to run this pipeline?"
-msgstr ""
+msgstr "Er du sikker på, at du vil køre pipelinen?"
msgid "Pipelines|Build with confidence"
msgstr ""
@@ -24469,16 +24628,16 @@ msgid "Pipelines|Copy trigger token"
msgstr ""
msgid "Pipelines|Could not load artifacts."
-msgstr ""
+msgstr "Kunne ikke indlæse artefakter."
msgid "Pipelines|Could not load merged YAML content"
msgstr ""
msgid "Pipelines|Description"
-msgstr ""
+msgstr "Beskrivelse"
msgid "Pipelines|Edit"
-msgstr ""
+msgstr "Rediger"
msgid "Pipelines|Editor"
msgstr ""
@@ -24487,7 +24646,7 @@ msgid "Pipelines|Get familiar with GitLab CI/CD syntax by starting with a basic
msgstr ""
msgid "Pipelines|Get started with GitLab CI/CD"
-msgstr ""
+msgstr "Kom godt i gang med GitLab CI/CD"
msgid "Pipelines|GitLab CI/CD can automatically build, test, and deploy your code. Let GitLab take care of time consuming tasks, so you can spend more time creating."
msgstr ""
@@ -24496,7 +24655,7 @@ msgid "Pipelines|If you are unsure, please ask a project maintainer to review it
msgstr ""
msgid "Pipelines|Improve code quality with GitLab CI/CD"
-msgstr ""
+msgstr "Forbedr kodekvalitet med GitLab CI/CD"
msgid "Pipelines|Install GitLab Runners"
msgstr ""
@@ -24505,7 +24664,7 @@ msgid "Pipelines|It is recommended the code is reviewed thoroughly before runnin
msgstr ""
msgid "Pipelines|Last Used"
-msgstr ""
+msgstr "Sidst brugt"
msgid "Pipelines|Learn about Runners"
msgstr ""
@@ -24514,25 +24673,25 @@ msgid "Pipelines|Lint"
msgstr ""
msgid "Pipelines|Loading Pipelines"
-msgstr ""
+msgstr "Indlæser pipelines"
msgid "Pipelines|Loading pipelines"
-msgstr ""
+msgstr "Indlæser pipelines"
msgid "Pipelines|Merged YAML is view only"
msgstr ""
msgid "Pipelines|More Information"
-msgstr ""
+msgstr "Mere information"
msgid "Pipelines|No artifacts available"
-msgstr ""
+msgstr "Ingen artefakter tilgængelige"
msgid "Pipelines|No triggers have been created yet. Add one using the form above."
msgstr ""
msgid "Pipelines|Owner"
-msgstr ""
+msgstr "Ejer"
msgid "Pipelines|Pipeline Editor"
msgstr ""
@@ -24541,7 +24700,7 @@ msgid "Pipelines|Project cache successfully reset."
msgstr ""
msgid "Pipelines|Revoke"
-msgstr ""
+msgstr "Tilbagekald"
msgid "Pipelines|Something went wrong while cleaning runners cache."
msgstr ""
@@ -24622,22 +24781,22 @@ msgid "Pipelines|Visualize"
msgstr ""
msgid "Pipelines|invalid"
-msgstr ""
+msgstr "ugyldig"
msgid "Pipelines|parent"
msgstr ""
msgid "Pipeline|Actions"
-msgstr ""
+msgstr "Handlinger"
msgid "Pipeline|Branch name"
-msgstr ""
+msgstr "Grennavn"
msgid "Pipeline|Branches or tags could not be loaded."
msgstr ""
msgid "Pipeline|Canceled"
-msgstr ""
+msgstr "Annulleret"
msgid "Pipeline|Checking pipeline status"
msgstr ""
@@ -24646,31 +24805,31 @@ msgid "Pipeline|Checking pipeline status."
msgstr ""
msgid "Pipeline|Commit"
-msgstr ""
+msgstr "Commit"
msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Created"
-msgstr ""
+msgstr "Oprettet"
msgid "Pipeline|Date"
-msgstr ""
+msgstr "Dato"
msgid "Pipeline|Detached merge request pipeline"
msgstr ""
msgid "Pipeline|Duration"
-msgstr ""
+msgstr "Varighed"
msgid "Pipeline|Failed"
msgstr ""
msgid "Pipeline|In progress"
-msgstr ""
+msgstr "I gang"
msgid "Pipeline|Key"
-msgstr ""
+msgstr "Nøgle"
msgid "Pipeline|Manual"
msgstr ""
@@ -24691,7 +24850,7 @@ msgid "Pipeline|Pending"
msgstr ""
msgid "Pipeline|Pipeline"
-msgstr ""
+msgstr "Pipeline"
msgid "Pipeline|Pipeline %{idStart}#%{idEnd} %{statusStart}%{statusEnd} for %{commitStart}%{commitEnd}"
msgstr ""
@@ -24712,9 +24871,54 @@ msgid "Pipeline|Run pipeline"
msgstr ""
msgid "Pipeline|Running"
-msgstr ""
+msgstr "Kører"
msgid "Pipeline|Skipped"
+msgstr "Sprunget over"
+
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
msgstr ""
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
@@ -24724,7 +24928,7 @@ msgid "Pipeline|Stages"
msgstr ""
msgid "Pipeline|Status"
-msgstr ""
+msgstr "Status"
msgid "Pipeline|Stop pipeline"
msgstr ""
@@ -24733,7 +24937,7 @@ msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
msgid "Pipeline|Tag name"
-msgstr ""
+msgstr "Mærkatnavn"
msgid "Pipeline|Test coverage"
msgstr ""
@@ -24754,19 +24958,19 @@ msgid "Pipeline|Triggerer"
msgstr ""
msgid "Pipeline|Value"
-msgstr ""
+msgstr "Værdi"
msgid "Pipeline|Variables"
-msgstr ""
+msgstr "Variabler"
msgid "Pipeline|View pipeline"
-msgstr ""
+msgstr "Vis pipeline"
msgid "Pipeline|We are currently unable to fetch pipeline data"
msgstr ""
msgid "Pipeline|You’re about to stop pipeline %{pipelineId}."
-msgstr ""
+msgstr "Du er ved at stoppe pipelinen %{pipelineId}."
msgid "Pipeline|for"
msgstr ""
@@ -24781,7 +24985,7 @@ msgid "Pipeline|with stages"
msgstr ""
msgid "PivotalTrackerService|Add commit messages as comments to Pivotal Tracker stories."
-msgstr ""
+msgstr "Tilføj commit-meddelelser som kommentarer til Pivotal Tracker-historier."
msgid "PivotalTrackerService|Comma-separated list of branches to automatically inspect. Leave blank to include all branches."
msgstr ""
@@ -24793,16 +24997,16 @@ msgid "Plain diff"
msgstr ""
msgid "Plan:"
-msgstr ""
+msgstr "Plan:"
msgid "PlantUML"
-msgstr ""
+msgstr "PlantUML"
msgid "PlantUML URL"
msgstr ""
msgid "Play"
-msgstr ""
+msgstr "Afspil"
msgid "Play all manual"
msgstr ""
@@ -24814,10 +25018,10 @@ msgid "Please %{startTagRegister}register%{endRegisterTag} or %{startTagSignIn}s
msgstr ""
msgid "Please accept the Terms of Service before continuing."
-msgstr ""
+msgstr "Accepter venligst vilkår for tjeneste før du fortsætter."
msgid "Please add a comment in the text area above"
-msgstr ""
+msgstr "Tilføj venligst en kommentar i tekstområdet ovenover"
msgid "Please check the configuration file for this chart"
msgstr ""
@@ -24829,19 +25033,19 @@ msgid "Please check the configuration file to ensure that it is available and th
msgstr ""
msgid "Please check your email %{email} to confirm your account"
-msgstr ""
+msgstr "Tjek venligst din e-mail %{email} for at bekræfte din konto"
msgid "Please check your email (%{email}) to verify that you own this address and unlock the power of CI/CD. Didn't receive it? %{resend_link}. Wrong email address? %{update_link}."
msgstr ""
msgid "Please choose a file"
-msgstr ""
+msgstr "Vælg venligst en fil"
msgid "Please complete your profile with email address"
msgstr ""
msgid "Please confirm your email address"
-msgstr ""
+msgstr "Bekræft venligst din e-mailadresse"
msgid "Please contact an admin to register runners."
msgstr ""
@@ -24853,7 +25057,7 @@ msgid "Please contact your administrator with any questions."
msgstr ""
msgid "Please contact your administrator."
-msgstr ""
+msgstr "Kontakt venligst din administrator."
msgid "Please convert %{linkStart}them to Git%{linkEnd}, and go through the %{linkToImportFlow} again."
msgstr ""
@@ -24862,7 +25066,7 @@ msgid "Please copy, download, or print your recovery codes before proceeding."
msgstr ""
msgid "Please create a password for your new account."
-msgstr ""
+msgstr "Opret venligst en adgangskode til din nye konto."
msgid "Please create a username with only alphanumeric characters."
msgstr ""
@@ -24871,7 +25075,7 @@ msgid "Please create an index before enabling indexing"
msgstr ""
msgid "Please delete your current license if you want to downgrade to the free plan."
-msgstr ""
+msgstr "Slet venligst din nuværende licens hvis du vil nedgradere til den gratis plan."
msgid "Please enable and migrate to hashed storage to avoid security issues and ensure data integrity. %{migrate_link}"
msgstr ""
@@ -24883,22 +25087,22 @@ msgid "Please enter a number greater than %{number} (from the project settings)"
msgstr ""
msgid "Please enter a valid URL format, ex: http://www.example.com/home"
-msgstr ""
+msgstr "Indtast venligst et gyldigt URL-format. F.eks.: http://www.example.com/home"
msgid "Please enter a valid hex (#RRGGBB or #RGB) color value"
-msgstr ""
+msgstr "Indtast venligst en gyldig hex-farveværdi (#RRGGBB eller #RGB)"
msgid "Please enter a valid number"
-msgstr ""
+msgstr "Indtast venligst et gyldigt tal"
msgid "Please enter or upload a valid license."
-msgstr ""
+msgstr "Indtast eller upload venligst en gyldig licens."
msgid "Please fill in a descriptive name for your group."
msgstr ""
msgid "Please fill out this field."
-msgstr ""
+msgstr "Udfyld venligst feltet."
msgid "Please follow the %{link_start}Let's Encrypt troubleshooting instructions%{link_end} to re-obtain your Let's Encrypt certificate."
msgstr ""
@@ -24916,28 +25120,28 @@ msgid "Please only enable search after installing the plugin, enabling indexing
msgstr ""
msgid "Please provide a name"
-msgstr ""
+msgstr "Angiv venligst et navn"
msgid "Please provide a name."
-msgstr ""
+msgstr "Angiv venligst et navn."
msgid "Please provide a valid URL"
-msgstr ""
+msgstr "Angiv venligst en gyldig URL"
msgid "Please provide a valid URL."
-msgstr ""
+msgstr "Angiv venligst en gyldig URL."
msgid "Please provide a valid YouTube URL or ID"
-msgstr ""
+msgstr "Angiv venligst en gyldig URL eller id til YouTube"
msgid "Please provide a valid email address."
-msgstr ""
+msgstr "Angiv venligst en gyldig e-mailadresse."
msgid "Please provide attributes to update"
msgstr ""
msgid "Please provide your username or email address."
-msgstr ""
+msgstr "Angiv venligst dit brugernavn eller e-mailadresse."
msgid "Please reach out if you have any questions and we'll be happy to assist."
msgstr ""
@@ -24946,25 +25150,25 @@ msgid "Please refer to %{docs_url}"
msgstr ""
msgid "Please select"
-msgstr ""
+msgstr "Vælg venligst"
msgid "Please select a Jira project"
-msgstr ""
+msgstr "Vælg venligst et Jira-projekt"
msgid "Please select a country"
-msgstr ""
+msgstr "Vælg venligst et land"
msgid "Please select a file"
-msgstr ""
+msgstr "Vælg venligst en fil"
msgid "Please select a group."
-msgstr ""
+msgstr "Vælg venligst en gruppe."
msgid "Please select a valid target branch"
-msgstr ""
+msgstr "Vælg venligst en gyldig målgren"
msgid "Please select a valid target branch."
-msgstr ""
+msgstr "Vælg venligst en gyldig målgren."
msgid "Please select and add a member"
msgstr ""
@@ -24976,19 +25180,19 @@ msgid "Please select what should be included in each exported requirement."
msgstr ""
msgid "Please select..."
-msgstr ""
+msgstr "Vælg venligst ..."
msgid "Please set a new password before proceeding."
msgstr ""
msgid "Please share your feedback about %{featureName} %{linkStart}in this issue%{linkEnd} to help us improve the experience."
-msgstr ""
+msgstr "Del venligst din feedback om %{featureName} %{linkStart}i problemstillingen%{linkEnd} for at hjælpe os med at forbedre oplevelsen."
msgid "Please solve the captcha"
-msgstr ""
+msgstr "Løs venligst captcha'en"
msgid "Please try again"
-msgstr ""
+msgstr "Prøv venligst igen"
msgid "Please try and refresh the page. If the problem persists please contact support."
msgstr ""
@@ -24997,7 +25201,7 @@ msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
msgid "Please type the following to confirm:"
-msgstr ""
+msgstr "Skriv venligst følgende for at bekræfte:"
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -25024,7 +25228,7 @@ msgid "Point to any links you like: documentation, built binaries, or other rela
msgstr ""
msgid "Policies"
-msgstr ""
+msgstr "Regelsæt"
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
@@ -25036,10 +25240,10 @@ msgid "Polling interval multiplier"
msgstr ""
msgid "Popularity"
-msgstr ""
+msgstr "Popularitet"
msgid "Port"
-msgstr ""
+msgstr "Port"
msgid "Postman collection"
msgstr ""
@@ -25051,120 +25255,117 @@ msgid "Pre-defined push rules."
msgstr ""
msgid "Preferences"
-msgstr ""
+msgstr "Præferencer"
msgid "Preferences saved."
-msgstr ""
+msgstr "Præferencer gemt."
msgid "Preferences|Behavior"
-msgstr ""
+msgstr "Opførsel"
msgid "Preferences|Choose between fixed (max. 1280px) and fluid (%{percentage}) application layout."
-msgstr ""
+msgstr "Vælg mellem fast (maks. 1280px) og flydende (%{percentage}) programlayout."
msgid "Preferences|Choose what content you want to see on a project’s overview page."
-msgstr ""
+msgstr "Vælg hvilket indhold du vil se på et projekts oversigtsside."
msgid "Preferences|Choose what content you want to see on your homepage."
-msgstr ""
+msgstr "Vælg det indhold du vil se på din startside."
msgid "Preferences|Configure how dates and times display for you."
-msgstr ""
+msgstr "Konfigurer hvordan datoer og klokkeslæt vises for dig."
msgid "Preferences|Customize integrations with third party services."
-msgstr ""
+msgstr "Tilpas integreringer med tjenester fra tredjepart."
msgid "Preferences|Customize the appearance of the application header and navigation sidebar."
-msgstr ""
+msgstr "Tilpas udseendet på programheaderen og navigationssidebjælken."
msgid "Preferences|Display time in 24-hour format"
-msgstr ""
+msgstr "Vis klokkeslæt i 24-timers format"
msgid "Preferences|Enable Gitpod integration"
-msgstr ""
+msgstr "Aktivér Gitpod-integrering"
msgid "Preferences|Enable integrated code intelligence on code views"
-msgstr ""
+msgstr "Aktivér integreret kodeintelligens på kodevisninger"
msgid "Preferences|Failed to save preferences."
-msgstr ""
+msgstr "Kunne ikke gemme præferencer."
msgid "Preferences|For example: 30 minutes ago."
-msgstr ""
+msgstr "F.eks.: 30 minutter siden."
msgid "Preferences|Gitpod"
-msgstr ""
+msgstr "Gitpod"
msgid "Preferences|Homepage content"
-msgstr ""
+msgstr "Indhold på startside"
msgid "Preferences|Instead of all the files changed, show only one file at a time. To switch between files, use the file browser."
-msgstr ""
+msgstr "Vis kun én fil ad gangen frem for alle de ændrede filer. Brug filvælgeren til at skifte mellem filerne."
msgid "Preferences|Integrations"
-msgstr ""
+msgstr "Integreringer"
msgid "Preferences|Layout width"
-msgstr ""
+msgstr "Bredde på layout"
msgid "Preferences|Must be a number between %{min} and %{max}"
-msgstr ""
+msgstr "Skal være et tal fra %{min} til %{max}"
msgid "Preferences|Navigation theme"
-msgstr ""
+msgstr "Tema for navigation"
msgid "Preferences|Project overview content"
-msgstr ""
+msgstr "Indhold for projektoversigt"
msgid "Preferences|Render whitespace characters in the Web IDE"
-msgstr ""
+msgstr "Gengiv blanktegn i Web IDE"
msgid "Preferences|Show one file at a time on merge request's Changes tab"
msgstr ""
msgid "Preferences|Show whitespace changes in diffs"
-msgstr ""
+msgstr "Vis blanktegnsændringer i diff'er"
msgid "Preferences|Sourcegraph"
-msgstr ""
+msgstr "Sourcegraph"
msgid "Preferences|Surround text selection when typing quotes or brackets"
-msgstr ""
+msgstr "Omslut tekstmarkering når der skrives citater eller klammer"
msgid "Preferences|Syntax highlighting theme"
-msgstr ""
+msgstr "Tema for syntaksfremhævning"
msgid "Preferences|Tab width"
-msgstr ""
+msgstr "Bredde på tabulatorstop"
msgid "Preferences|This feature is experimental and translations are not complete yet"
-msgstr ""
+msgstr "Funktionen er eksperimentel og oversættelserne er ikke færdige endnu"
msgid "Preferences|This setting allows you to customize the appearance of the syntax."
-msgstr ""
+msgstr "Indstillingen giver dig mulighed for at tilpasse udseendet på syntaksen."
msgid "Preferences|This setting allows you to customize the behavior of the system layout and default views."
-msgstr ""
+msgstr "Indstillingen giver dig mulighed for at tilpasse opførslen på systemlayoutet og standardvisningerne."
msgid "Preferences|Time preferences"
-msgstr ""
+msgstr "Præferencer for tid"
msgid "Preferences|Use relative times"
-msgstr ""
+msgstr "Brug relative tidspunkter"
msgid "Press %{key}-C to copy"
-msgstr ""
+msgstr "Tryk på %{key}-C for at kopiere"
msgid "Prev"
-msgstr ""
+msgstr "Forrige"
-msgid "Prevent MR approvals by author."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent MR approvals from users who make commits to the MR."
-msgstr ""
-
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,47 +25377,44 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
msgid "Preview"
-msgstr ""
+msgstr "Forhåndsvis"
msgid "Preview JavaScript projects in the Web IDE with CodeSandbox Live Preview. %{link_start}Learn more.%{link_end} "
msgstr ""
msgid "Preview Markdown"
-msgstr ""
+msgstr "Forhåndsvis Markdown"
msgid "Preview changes"
-msgstr ""
+msgstr "Forhåndsvis ændringer"
msgid "Preview payload"
msgstr ""
msgid "Previous Artifacts"
-msgstr ""
+msgstr "Forrige artefakter"
msgid "Previous commit"
-msgstr ""
+msgstr "Forrige commit"
msgid "Previous design"
-msgstr ""
+msgstr "Forrige design"
msgid "Previous file in diff"
-msgstr ""
+msgstr "Forrige fil i diff"
msgid "Previous unresolved discussion"
-msgstr ""
+msgstr "Forrige uløste debat"
msgid "Primary"
-msgstr ""
+msgstr "Primær"
msgid "Primary Action"
-msgstr ""
+msgstr "Primær handling"
msgid "Print codes"
msgstr ""
@@ -25234,10 +25432,10 @@ msgid "Prioritized label"
msgstr ""
msgid "Priority"
-msgstr ""
+msgstr "Prioritet"
msgid "Private"
-msgstr ""
+msgstr "Privat"
msgid "Private - Guest users are not allowed to view detailed release information like title and source code."
msgstr ""
@@ -25249,10 +25447,10 @@ msgid "Private - The group and its projects can only be viewed by members."
msgstr ""
msgid "Private group(s)"
-msgstr ""
+msgstr "Private grupper"
msgid "Private profile"
-msgstr ""
+msgstr "Privat profil"
msgid "Private projects Minutes cost factor"
msgstr ""
@@ -25261,7 +25459,7 @@ msgid "Private projects can be created in your personal namespace with:"
msgstr ""
msgid "Proceed"
-msgstr ""
+msgstr "Fortsæt"
msgid "Product Analytics"
msgstr ""
@@ -25270,7 +25468,7 @@ msgid "ProductAnalytics|There is no data for this type of chart currently. Pleas
msgstr ""
msgid "Productivity"
-msgstr ""
+msgstr "Produktivitet"
msgid "Productivity Analytics"
msgstr ""
@@ -25285,31 +25483,31 @@ msgid "ProductivityAanalytics|is earlier than the allowed minimum date"
msgstr ""
msgid "ProductivityAnalytics|Ascending"
-msgstr ""
+msgstr "Stigende"
msgid "ProductivityAnalytics|Days"
-msgstr ""
+msgstr "Dage"
msgid "ProductivityAnalytics|Days to merge"
msgstr ""
msgid "ProductivityAnalytics|Descending"
-msgstr ""
+msgstr "Faldende"
msgid "ProductivityAnalytics|Hours"
-msgstr ""
+msgstr "Timer"
msgid "ProductivityAnalytics|List"
-msgstr ""
+msgstr "Liste"
msgid "ProductivityAnalytics|Merge Requests"
-msgstr ""
+msgstr "Sammenlægningsanmodninger"
msgid "ProductivityAnalytics|Merge date"
msgstr ""
msgid "ProductivityAnalytics|Merge requests"
-msgstr ""
+msgstr "Sammenlægningsanmodninger"
msgid "ProductivityAnalytics|Time to merge"
msgstr ""
@@ -25321,16 +25519,16 @@ msgid "ProductivityAnalytics|is earlier than the given merged at after date"
msgstr ""
msgid "Profile"
-msgstr ""
+msgstr "Profil"
msgid "Profile Settings"
-msgstr ""
+msgstr "Profilindstillinger"
msgid "Profile image guideline"
msgstr ""
msgid "Profile page:"
-msgstr ""
+msgstr "Profilside:"
msgid "ProfileSession|on"
msgstr ""
@@ -25342,67 +25540,67 @@ msgid "Profiles| You are going to change the username %{currentUsernameBold} to
msgstr ""
msgid "Profiles|\"Busy\" will be shown next to your name"
-msgstr ""
+msgstr "\"Optaget\" vises ved siden af dit navn"
msgid "Profiles|%{provider} Active"
-msgstr ""
+msgstr "%{provider} aktiv"
msgid "Profiles|@username"
-msgstr ""
+msgstr "@brugernavn"
msgid "Profiles|Account could not be deleted. GitLab was unable to verify your identity."
-msgstr ""
+msgstr "Kontoen kunne ikke slettes. GitLab var ikke i stand til at bekræfte din identitet."
msgid "Profiles|Account scheduled for removal."
-msgstr ""
+msgstr "Kontoen er planlagt til fjernelse."
msgid "Profiles|Activate signin with one of the following services"
-msgstr ""
+msgstr "Aktivér indlogning med en af følgende tjenester"
msgid "Profiles|Active"
-msgstr ""
+msgstr "Aktiv"
msgid "Profiles|Add key"
-msgstr ""
+msgstr "Tilføj nøgle"
msgid "Profiles|Add status emoji"
-msgstr ""
+msgstr "Tilføj statusemoji"
msgid "Profiles|An error occurred while updating your username, please try again."
-msgstr ""
+msgstr "Der opstod en fejl under opdatering af dit brugernavn, prøv venligst igen."
msgid "Profiles|Avatar cropper"
-msgstr ""
+msgstr "Beskæring af avatar"
msgid "Profiles|Avatar will be removed. Are you sure?"
-msgstr ""
+msgstr "Avataren fjernes. Er du sikker?"
msgid "Profiles|Bio"
msgstr ""
msgid "Profiles|Busy"
-msgstr ""
+msgstr "Optaget"
msgid "Profiles|Change username"
-msgstr ""
+msgstr "Ændr brugernavn"
msgid "Profiles|Changing your username can have unintended side effects."
-msgstr ""
+msgstr "Ændring af dit brugernavn kan have utilsigtede bivirkninger."
msgid "Profiles|Choose file..."
-msgstr ""
+msgstr "Vælg fil ..."
msgid "Profiles|Choose to show contributions of private projects on your public profile without any project, repository or organization information"
msgstr ""
msgid "Profiles|City, country"
-msgstr ""
+msgstr "By, land"
msgid "Profiles|Clear status"
-msgstr ""
+msgstr "Ryd status"
msgid "Profiles|Click on icon to activate signin with one of the following services"
-msgstr ""
+msgstr "Klik på ikonet for at aktivere indlogning med en af følgende tjenester"
msgid "Profiles|Commit email"
msgstr ""
@@ -25411,22 +25609,22 @@ msgid "Profiles|Connect %{provider}"
msgstr ""
msgid "Profiles|Connected Accounts"
-msgstr ""
+msgstr "Forbundne kontoer"
msgid "Profiles|Current path: %{path}"
-msgstr ""
+msgstr "Nuværende sti: %{path}"
msgid "Profiles|Current status"
-msgstr ""
+msgstr "Nuværende status"
msgid "Profiles|Default notification email"
msgstr ""
msgid "Profiles|Delete account"
-msgstr ""
+msgstr "Slet konto"
msgid "Profiles|Deleting an account has the following effects:"
-msgstr ""
+msgstr "Sletning af en konto kan have utilsigtede bivirkninger:"
msgid "Profiles|Disconnect"
msgstr ""
@@ -25435,12 +25633,15 @@ msgid "Profiles|Disconnect %{provider}"
msgstr ""
msgid "Profiles|Do not show on profile"
-msgstr ""
+msgstr "Vis ikke på profil"
msgid "Profiles|Don't display activity-related personal information on your profiles"
-msgstr ""
+msgstr "Vis ikke aktivitetsrelateret personlig information på dine profiler"
msgid "Profiles|Edit Profile"
+msgstr "Rediger profil"
+
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
msgstr ""
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
@@ -25453,16 +25654,16 @@ msgid "Profiles|Enter your pronouns to let people know how to refer to you"
msgstr ""
msgid "Profiles|Expired key is not valid."
-msgstr ""
+msgstr "Udløbet nøgle er ikke gyldig."
msgid "Profiles|Expired:"
-msgstr ""
+msgstr "Udløbet:"
msgid "Profiles|Expires at"
msgstr ""
msgid "Profiles|Expires:"
-msgstr ""
+msgstr "Udløber:"
msgid "Profiles|Feed token was successfully reset"
msgstr ""
@@ -25480,40 +25681,40 @@ msgid "Profiles|If after setting a password, the option to delete your account i
msgstr ""
msgid "Profiles|Include private contributions on my profile"
-msgstr ""
+msgstr "Medtag private bidrag på min profil"
msgid "Profiles|Incoming email token was successfully reset"
msgstr ""
msgid "Profiles|Increase your account's security by enabling Two-Factor Authentication (2FA)"
-msgstr ""
+msgstr "Forbedr sikkerheden på din konto ved at aktivere tofaktorgodkendelse (2FG)"
msgid "Profiles|Invalid key."
-msgstr ""
+msgstr "Ugyldig nøgle."
msgid "Profiles|Invalid password"
-msgstr ""
+msgstr "Ugyldig adgangskode"
msgid "Profiles|Invalid username"
-msgstr ""
+msgstr "Ugyldigt brugernavn"
msgid "Profiles|Key"
-msgstr ""
+msgstr "Nøgle"
msgid "Profiles|Key can still be used after expiration."
-msgstr ""
+msgstr "Nøglen kan stadigvæk bruges efter den udløber."
msgid "Profiles|Key usable beyond expiration date."
-msgstr ""
+msgstr "Nøglen kan bruges efter udløbsdatoen."
msgid "Profiles|Key will be deleted on this date."
-msgstr ""
+msgstr "Nøglen slettes på denne dato."
msgid "Profiles|Last used:"
-msgstr ""
+msgstr "Sidst brugt:"
msgid "Profiles|Learn more"
-msgstr ""
+msgstr "Lær mere"
msgid "Profiles|Location"
msgstr ""
@@ -25522,52 +25723,52 @@ msgid "Profiles|Made a private contribution"
msgstr ""
msgid "Profiles|Main settings"
-msgstr ""
+msgstr "Hovedindstillinger"
msgid "Profiles|Manage two-factor authentication"
-msgstr ""
+msgstr "HÃ¥ndter tofaktorgodkendelse"
msgid "Profiles|No file chosen."
-msgstr ""
+msgstr "Ingen fil valgt."
msgid "Profiles|Notification email"
-msgstr ""
+msgstr "Underretnings e-mail"
msgid "Profiles|Organization"
-msgstr ""
+msgstr "Organisation"
msgid "Profiles|Path"
-msgstr ""
+msgstr "Sti"
msgid "Profiles|Position and size your new avatar"
-msgstr ""
+msgstr "Placér og tilpas størrelsen på din nye avatar"
msgid "Profiles|Primary email"
-msgstr ""
+msgstr "Primære e-mail"
msgid "Profiles|Private contributions"
-msgstr ""
+msgstr "Private bidrag"
msgid "Profiles|Profile was successfully updated"
-msgstr ""
+msgstr "Profilen blev opdateret"
msgid "Profiles|Public avatar"
-msgstr ""
+msgstr "Offentlig avatar"
msgid "Profiles|Public email"
-msgstr ""
+msgstr "Offentlig e-mail"
msgid "Profiles|Publicly visible private SSH keys can compromise your system."
msgstr ""
msgid "Profiles|Remove avatar"
-msgstr ""
+msgstr "Fjern avatar"
msgid "Profiles|Set new profile picture"
-msgstr ""
+msgstr "Indstil nyt profilbillede"
msgid "Profiles|Set your local time zone"
-msgstr ""
+msgstr "Indstil din lokale tidszone"
msgid "Profiles|Social sign-in"
msgstr ""
@@ -25588,7 +25789,7 @@ msgid "Profiles|The maximum file size allowed is 200KB."
msgstr ""
msgid "Profiles|This email will be displayed on your public profile"
-msgstr ""
+msgstr "E-mailen vises på din offentlige profil"
msgid "Profiles|This email will be used for web based operations, such as edits and merges. %{commit_email_link_start}Learn more%{commit_email_link_end}"
msgstr ""
@@ -25597,67 +25798,64 @@ msgid "Profiles|This emoji and message will appear on your profile and throughou
msgstr ""
msgid "Profiles|This information will appear on your profile"
-msgstr ""
+msgstr "Informationen vises på din profil"
msgid "Profiles|Time settings"
-msgstr ""
+msgstr "Tidsindstillinger"
msgid "Profiles|Two-Factor Authentication"
-msgstr ""
+msgstr "Tofaktorgodkendelse"
msgid "Profiles|Type your %{confirmationValue} to confirm:"
msgstr ""
msgid "Profiles|Typically starts with \"ssh-ed25519 …\" or \"ssh-rsa …\""
-msgstr ""
+msgstr "Begynder typisk med \"ssh-ed25519 …\" eller \"ssh-rsa …\""
msgid "Profiles|Update profile settings"
-msgstr ""
+msgstr "Opdater profilindstillinger"
msgid "Profiles|Update username"
-msgstr ""
+msgstr "Opdater brugernavn"
msgid "Profiles|Upload new avatar"
-msgstr ""
+msgstr "Upload ny avatar"
msgid "Profiles|Use a private email - %{email}"
-msgstr ""
+msgstr "Brug en privat e-mail - %{email}"
msgid "Profiles|User ID"
-msgstr ""
+msgstr "Bruger-id"
msgid "Profiles|Username change failed - %{message}"
msgstr ""
msgid "Profiles|Username successfully changed"
-msgstr ""
+msgstr "Brugernavnet blev ændret"
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
-msgstr ""
-
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
+msgstr "Det kan være sjovt at bruge emojier i navne men prøv venligst at indstille en statusmeddelelse i stedet"
msgid "Profiles|What's your status?"
-msgstr ""
+msgstr "Hvad er din status?"
msgid "Profiles|Who you represent or work for"
msgstr ""
msgid "Profiles|You can change your avatar here"
-msgstr ""
+msgstr "Her kan du ændre din avatar"
msgid "Profiles|You can change your avatar here or remove the current avatar to revert to %{gravatar_link}"
-msgstr ""
+msgstr "Du kan ændre din avatar her eller fjerne den nuværende avatar for at vende tilbage til %{gravatar_link}"
msgid "Profiles|You can upload your avatar here"
-msgstr ""
+msgstr "Her kan du uploade din avatar"
msgid "Profiles|You can upload your avatar here or change it at %{gravatar_link}"
-msgstr ""
+msgstr "Du kan uploade din avatar her eller ændre den på %{gravatar_link}"
msgid "Profiles|You don't have access to delete this user."
-msgstr ""
+msgstr "Du har ikke adgang til at slette brugeren."
msgid "Profiles|You must transfer ownership or delete groups you are an owner of before you can delete your account"
msgstr ""
@@ -25681,46 +25879,46 @@ msgid "Profiles|Your name was automatically set based on your %{provider_label}
msgstr ""
msgid "Profiles|Your status"
-msgstr ""
+msgstr "Din status"
msgid "Profiles|e.g. My MacBook key"
-msgstr ""
+msgstr "f.eks. Min MacBook-nøgle"
msgid "Profiles|username"
-msgstr ""
+msgstr "brugernavn"
msgid "Profiles|website.com"
msgstr ""
msgid "Profiles|your account"
-msgstr ""
+msgstr "din konto"
msgid "Profile|%{job_title} at %{organization}"
-msgstr ""
+msgstr "%{job_title} hos %{organization}"
msgid "Profiling - Performance bar"
msgstr ""
msgid "Programming languages used in this repository"
-msgstr ""
+msgstr "Programmeringssprog som bruges i depotet"
msgid "Progress"
-msgstr ""
+msgstr "Forløb"
msgid "Project"
-msgstr ""
+msgstr "Projekt"
msgid "Project \"%{name}\" is no longer available. Select another project to continue."
msgstr ""
msgid "Project %{project_repo} could not be found"
-msgstr ""
+msgstr "Projektet %{project_repo} kunne ikke findes"
msgid "Project & Group can not be assigned at the same time"
msgstr ""
msgid "Project '%{project_name}' is being imported."
-msgstr ""
+msgstr "Projektet '%{project_name}' importeres."
msgid "Project '%{project_name}' is in the process of being deleted."
msgstr ""
@@ -25729,7 +25927,7 @@ msgid "Project '%{project_name}' is restored."
msgstr ""
msgid "Project '%{project_name}' queued for deletion."
-msgstr ""
+msgstr "Projektet '%{project_name}' er sat i kø til sletning."
msgid "Project '%{project_name}' was successfully created."
msgstr ""
@@ -25744,19 +25942,19 @@ msgid "Project Access Tokens"
msgstr ""
msgid "Project Badges"
-msgstr ""
+msgstr "Projektbadges"
msgid "Project Files"
-msgstr ""
+msgstr "Projektfiler"
msgid "Project ID"
-msgstr ""
+msgstr "Projekt-id"
msgid "Project Templates"
-msgstr ""
+msgstr "Projektskabeloner"
msgid "Project URL"
-msgstr ""
+msgstr "Projekt-URL"
msgid "Project access must be granted explicitly to each user. If this project is part of a group, access will be granted to members of the group."
msgstr ""
@@ -25765,7 +25963,7 @@ msgid "Project access token creation is disabled in this group. You can still us
msgstr ""
msgid "Project already deleted"
-msgstr ""
+msgstr "Projektet er allerede slettet"
msgid "Project and wiki repositories"
msgstr ""
@@ -25783,7 +25981,7 @@ msgid "Project configuration, excluding integrations"
msgstr ""
msgid "Project description (optional)"
-msgstr ""
+msgstr "Projektbeskrivelse (valgfrit)"
msgid "Project does not exist or you don't have permission to perform this action"
msgstr ""
@@ -25819,22 +26017,22 @@ msgid "Project import requests"
msgstr ""
msgid "Project info:"
-msgstr ""
+msgstr "Projektinformation:"
msgid "Project information"
-msgstr ""
+msgstr "Projektinformation"
msgid "Project is required when cluster_type is :project"
msgstr ""
msgid "Project members"
-msgstr ""
+msgstr "Projektmedlemmer"
msgid "Project milestone"
-msgstr ""
+msgstr "Projektmilepæl"
msgid "Project name"
-msgstr ""
+msgstr "Projektnavn"
msgid "Project name suffix"
msgstr ""
@@ -25846,7 +26044,7 @@ msgid "Project order will not be saved as local storage is not available."
msgstr ""
msgid "Project path"
-msgstr ""
+msgstr "Projektsti"
msgid "Project security status"
msgstr ""
@@ -25867,7 +26065,7 @@ msgid "Project was not found or you do not have permission to add this project t
msgstr ""
msgid "Project: %{name}"
-msgstr ""
+msgstr "Projekt: %{name}"
msgid "ProjectActivityRSS|Subscribe"
msgstr ""
@@ -25879,31 +26077,31 @@ msgid "ProjectCreationLevel|Default project creation protection"
msgstr ""
msgid "ProjectCreationLevel|Developers + Maintainers"
-msgstr ""
+msgstr "Udviklere + vedligeholdere"
msgid "ProjectCreationLevel|Maintainers"
-msgstr ""
+msgstr "Vedligeholdere"
msgid "ProjectCreationLevel|No one"
-msgstr ""
+msgstr "Ingen"
msgid "ProjectFileTree|Name"
-msgstr ""
+msgstr "Navn"
msgid "ProjectFileTree|Show more"
-msgstr ""
+msgstr "Vis mere"
msgid "ProjectLastActivity|Never"
-msgstr ""
+msgstr "Aldrig"
msgid "ProjectOverview|Fork"
msgstr ""
msgid "ProjectOverview|Forks"
-msgstr ""
+msgstr "Forgreninger"
msgid "ProjectOverview|Go to your fork"
-msgstr ""
+msgstr "GÃ¥ til din forgrening"
msgid "ProjectOverview|Star"
msgstr ""
@@ -25924,28 +26122,28 @@ msgid "ProjectOverview|You must sign in to star a project"
msgstr ""
msgid "ProjectPage|Copy project ID"
-msgstr ""
+msgstr "Kopiér projekt-id"
msgid "ProjectPage|Project ID: %{project_id}"
-msgstr ""
+msgstr "Projekt-id: %{project_id}"
msgid "ProjectSelect| or group"
-msgstr ""
+msgstr " eller gruppe"
msgid "ProjectSelect|Search for project"
-msgstr ""
+msgstr "Søg efter projekt"
msgid "ProjectService|Drone server URL"
msgstr ""
msgid "ProjectService|Enter new API key"
-msgstr ""
+msgstr "Indtast ny API-nøgle"
msgid "ProjectService|Enter new password"
-msgstr ""
+msgstr "Indtast ny adgangskode"
msgid "ProjectService|Enter new password."
-msgstr ""
+msgstr "Indtast ny adgangskode."
msgid "ProjectService|Issue URL"
msgstr ""
@@ -26032,16 +26230,16 @@ msgid "ProjectService|Trigger event when an issue is created, updated, or closed
msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
-msgstr ""
+msgstr "%{link_start}Hvad er beskrivelsesskabeloner?%{link_end}"
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
-msgstr ""
+msgstr "Yderligere indstillinger der påvirker hvordan og hvornår sammenlægninger foretages."
msgid "ProjectSettings|All discussions must be resolved"
-msgstr ""
+msgstr "Alle debatter skal løses"
msgid "ProjectSettings|Allow"
-msgstr ""
+msgstr "Tillad"
msgid "ProjectSettings|Always show thumbs-up and thumbs-down award emoji buttons on issues, merge requests, and snippets."
msgstr ""
@@ -26053,16 +26251,16 @@ msgid "ProjectSettings|Automatically resolve merge request diff discussions when
msgstr ""
msgid "ProjectSettings|Badges"
-msgstr ""
+msgstr "Badges"
msgid "ProjectSettings|Build, test, and deploy your changes."
msgstr ""
msgid "ProjectSettings|Checkbox is visible and selected by default."
-msgstr ""
+msgstr "Afkrydsningsboksen er som standard synlig og tilvalgt."
msgid "ProjectSettings|Checkbox is visible and unselected by default."
-msgstr ""
+msgstr "Afkrydsningsboksen er som standard synlig og fravalgt."
msgid "ProjectSettings|Choose your merge method, merge options, merge checks, and merge suggestions."
msgstr ""
@@ -26071,16 +26269,16 @@ msgid "ProjectSettings|Choose your merge method, merge options, merge checks, me
msgstr ""
msgid "ProjectSettings|Configure your project resources and monitor their health."
-msgstr ""
+msgstr "Konfigurer dine projektressourcer og overvåg deres helbred."
msgid "ProjectSettings|Contact an admin to change this setting."
-msgstr ""
+msgstr "Kontakt en administrator for at ændre indstillingen."
msgid "ProjectSettings|Container registry"
msgstr ""
msgid "ProjectSettings|Customize this project's badges."
-msgstr ""
+msgstr "Tilpas projektets badges."
msgid "ProjectSettings|Determine what happens to the commit history when you merge a merge request."
msgstr ""
@@ -26089,7 +26287,7 @@ msgid "ProjectSettings|Disable email notifications"
msgstr ""
msgid "ProjectSettings|Do not allow"
-msgstr ""
+msgstr "Tillad ikke"
msgid "ProjectSettings|Enable \"Delete source branch\" option by default"
msgstr ""
@@ -26104,7 +26302,7 @@ msgid "ProjectSettings|Encourage"
msgstr ""
msgid "ProjectSettings|Every merge creates a merge commit."
-msgstr ""
+msgstr "Hver sammenlægning opretter en sammenlægningscommit."
msgid "ProjectSettings|Every project can have its own space to store its Docker images"
msgstr ""
@@ -26113,16 +26311,16 @@ msgid "ProjectSettings|Every project can have its own space to store its package
msgstr ""
msgid "ProjectSettings|Everyone"
-msgstr ""
+msgstr "Alle"
msgid "ProjectSettings|Existing merge requests and protected branches are not affected."
msgstr ""
msgid "ProjectSettings|Failed to protect the tag"
-msgstr ""
+msgstr "Kunne ikke beskytte mærkatet"
msgid "ProjectSettings|Failed to update tag!"
-msgstr ""
+msgstr "Kunne ikke opdatere mærkatet!"
msgid "ProjectSettings|Fast-forward merge"
msgstr ""
@@ -26134,22 +26332,22 @@ msgid "ProjectSettings|Flexible tool to collaboratively develop ideas and plan w
msgstr ""
msgid "ProjectSettings|Forks"
-msgstr ""
+msgstr "Forgreninger"
msgid "ProjectSettings|Git Large File Storage (LFS)"
-msgstr ""
+msgstr "Git Large File Storage (LFS)"
msgid "ProjectSettings|Global"
-msgstr ""
+msgstr "Globalt"
msgid "ProjectSettings|Internal"
-msgstr ""
+msgstr "Internt"
msgid "ProjectSettings|Introduces the risk of merging changes that do not pass the pipeline."
msgstr ""
msgid "ProjectSettings|Issues"
-msgstr ""
+msgstr "Problemstillinger"
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
@@ -26197,7 +26395,7 @@ msgid "ProjectSettings|Override user notification preferences for all project me
msgstr ""
msgid "ProjectSettings|Packages"
-msgstr ""
+msgstr "Pakker"
msgid "ProjectSettings|Pages"
msgstr ""
@@ -26209,16 +26407,16 @@ msgid "ProjectSettings|Pipelines must succeed"
msgstr ""
msgid "ProjectSettings|Private"
-msgstr ""
+msgstr "Privat"
msgid "ProjectSettings|Project visibility"
msgstr ""
msgid "ProjectSettings|Public"
-msgstr ""
+msgstr "Offentlig"
msgid "ProjectSettings|Repository"
-msgstr ""
+msgstr "Depot"
msgid "ProjectSettings|Require"
msgstr ""
@@ -26227,7 +26425,7 @@ msgid "ProjectSettings|Require an associated issue from Jira"
msgstr ""
msgid "ProjectSettings|Requirements"
-msgstr ""
+msgstr "Krav"
msgid "ProjectSettings|Requirements management system."
msgstr ""
@@ -26254,7 +26452,7 @@ msgid "ProjectSettings|Skipped pipelines are considered successful"
msgstr ""
msgid "ProjectSettings|Snippets"
-msgstr ""
+msgstr "Uddrag"
msgid "ProjectSettings|Squash commits when merging"
msgstr ""
@@ -26269,10 +26467,10 @@ msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
msgid "ProjectSettings|Supported variables:"
-msgstr ""
+msgstr "Understøttede variabler:"
msgid "ProjectSettings|Target project"
-msgstr ""
+msgstr "MÃ¥lprojekt"
msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
msgstr ""
@@ -26299,7 +26497,7 @@ msgid "ProjectSettings|To enable this feature, configure pipelines. %{link_start
msgstr ""
msgid "ProjectSettings|Transfer project"
-msgstr ""
+msgstr "Overfør projekt"
msgid "ProjectSettings|Upstream project"
msgstr ""
@@ -26332,7 +26530,7 @@ msgid "ProjectSettings|Visualize the project's performance metrics."
msgstr ""
msgid "ProjectSettings|What are badges?"
-msgstr ""
+msgstr "Hvad er badges?"
msgid "ProjectSettings|When pipelines for merge requests are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure pipelines for merge requests?%{link_end}"
msgstr ""
@@ -26341,16 +26539,16 @@ msgid "ProjectSettings|When there is a merge conflict, the user is given the opt
msgstr ""
msgid "ProjectSettings|Wiki"
-msgstr ""
+msgstr "Wiki"
msgid "ProjectSettings|With GitLab Pages you can host your static websites on GitLab."
msgstr ""
msgid "ProjectTemplates|.NET Core"
-msgstr ""
+msgstr ".NET Core"
msgid "ProjectTemplates|Android"
-msgstr ""
+msgstr "Android"
msgid "ProjectTemplates|GitLab Cluster Management"
msgstr ""
@@ -26425,10 +26623,10 @@ msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
msgid "Projects"
-msgstr ""
+msgstr "Projekter"
msgid "Projects (%{count})"
-msgstr ""
+msgstr "Projekter (%{count})"
msgid "Projects Successfully Retrieved"
msgstr ""
@@ -26440,13 +26638,13 @@ msgid "Projects contributed to"
msgstr ""
msgid "Projects shared with %{group_name}"
-msgstr ""
+msgstr "Projekter delt med %{group_name}"
msgid "Projects that can be accessed"
msgstr ""
msgid "Projects to index"
-msgstr ""
+msgstr "Projekter som skal indekseres"
msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
msgstr ""
@@ -26470,13 +26668,13 @@ msgid "Projects with no vulnerabilities and security scanning enabled"
msgstr ""
msgid "Projects with write access"
-msgstr ""
+msgstr "Projekter med skriveadgang"
msgid "ProjectsDropdown|Frequently visited"
-msgstr ""
+msgstr "Ofte besøgte"
msgid "ProjectsDropdown|Loading projects"
-msgstr ""
+msgstr "Indlæser projekter"
msgid "ProjectsDropdown|Projects you visit often will appear here"
msgstr ""
@@ -26485,7 +26683,7 @@ msgid "ProjectsDropdown|Search your projects"
msgstr ""
msgid "ProjectsDropdown|Something went wrong on our end."
-msgstr ""
+msgstr "Noget gik galt i vores ende."
msgid "ProjectsDropdown|Sorry, no projects matched your search"
msgstr ""
@@ -26503,7 +26701,7 @@ msgid "ProjectsNew|Contact an administrator to enable options for importing your
msgstr ""
msgid "ProjectsNew|Create"
-msgstr ""
+msgstr "Opret"
msgid "ProjectsNew|Create a blank project to house your files, plan your work, and collaborate on code, among other things."
msgstr ""
@@ -26512,22 +26710,22 @@ msgid "ProjectsNew|Create a project pre-populated with the necessary files to ge
msgstr ""
msgid "ProjectsNew|Create blank project"
-msgstr ""
+msgstr "Opret tomt projekt"
msgid "ProjectsNew|Create from template"
-msgstr ""
+msgstr "Opret fra skabelon"
msgid "ProjectsNew|Create new project"
-msgstr ""
+msgstr "Opret nyt projekt"
msgid "ProjectsNew|Description format"
msgstr ""
msgid "ProjectsNew|Import"
-msgstr ""
+msgstr "Importér"
msgid "ProjectsNew|Import project"
-msgstr ""
+msgstr "Importér projekt"
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -26551,7 +26749,7 @@ msgid "ProjectsNew|Want to house several dependent projects under the same names
msgstr ""
msgid "Prometheus"
-msgstr ""
+msgstr "Prometheus"
msgid "PrometheusAlerts|%{count} alerts applied"
msgstr ""
@@ -26602,10 +26800,10 @@ msgid "PrometheusAlerts|https://gitlab.com/gitlab-com/runbooks"
msgstr ""
msgid "PrometheusAlerts|is equal to"
-msgstr ""
+msgstr "er lig med"
msgid "PrometheusAlerts|is less than"
-msgstr ""
+msgstr "er mindre end"
msgid "PrometheusService|%{exporters} with %{metrics} were found"
msgstr ""
@@ -26617,7 +26815,7 @@ msgid "PrometheusService|Auto configuration settings are used unless you overrid
msgstr ""
msgid "PrometheusService|Common metrics"
-msgstr ""
+msgstr "Almindelige målinger"
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
@@ -26659,13 +26857,13 @@ msgid "PrometheusService|Monitor application health with Prometheus metrics and
msgstr ""
msgid "PrometheusService|More information"
-msgstr ""
+msgstr "Mere information"
msgid "PrometheusService|New metric"
msgstr ""
msgid "PrometheusService|No %{docsUrlStart}common metrics%{docsUrlEnd} were found"
-msgstr ""
+msgstr "Ingen %{docsUrlStart}almindelige målinger%{docsUrlEnd} blev fundet"
msgid "PrometheusService|No custom metrics have been created. Create one using the button above"
msgstr ""
@@ -26692,7 +26890,7 @@ msgid "PrometheusService|To use a Prometheus installed on a cluster, deactivate
msgstr ""
msgid "PrometheusService|Waiting for your first deployment to an environment to find common metrics"
-msgstr ""
+msgstr "Venter på din første udsendelse til et miljø for at finde almindelige målinger"
msgid "PrometheusService|You can now manage your Prometheus settings on the %{operations_link_start}Operations%{operations_link_end} page. Fields on this page have been deprecated."
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26746,19 +26941,19 @@ msgid "Promotions|Burndown Charts are visual representations of the progress of
msgstr ""
msgid "Promotions|Buy EE"
-msgstr ""
+msgstr "Køb EE"
msgid "Promotions|Buy GitLab Enterprise Edition"
msgstr ""
msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
+msgstr "Kontakt en ejer af gruppen %{namespace_name} for at opgradere planen."
msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
+msgstr "Kontakt ejeren %{link_start}%{owner_name}%{link_end} for at opgradere planen."
msgid "Promotions|Contact your Administrator to upgrade your license."
-msgstr ""
+msgstr "Kontakt din administrator for at opgradere din licens."
msgid "Promotions|Description templates allow you to define context-specific templates for issue and merge request description fields for your project."
msgstr ""
@@ -26770,7 +26965,7 @@ msgid "Promotions|Dismiss repository features promotion"
msgstr ""
msgid "Promotions|Don't show me this again"
-msgstr ""
+msgstr "Vis mig det ikke igen"
msgid "Promotions|Epics let you manage your portfolio of projects more efficiently and with less effort by tracking groups of issues that share a theme, across projects and milestones."
msgstr ""
@@ -26790,14 +26985,17 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Learn more"
+msgid "Promotions|Keep track of events in your project"
msgstr ""
+msgid "Promotions|Learn more"
+msgstr "Lær mere"
+
msgid "Promotions|Merge request approvals"
msgstr ""
msgid "Promotions|Not now, thanks!"
-msgstr ""
+msgstr "Ikke nu, tak!"
msgid "Promotions|Push Rules"
msgstr ""
@@ -26818,28 +27016,25 @@ msgid "Promotions|Set the number of necessary approvals and define a list of app
msgstr ""
msgid "Promotions|Start GitLab Ultimate trial"
-msgstr ""
+msgstr "Start GitLab Ultimate-prøveperiode"
msgid "Promotions|The Advanced Search in GitLab is a powerful search service that saves you time. Instead of creating duplicate code and wasting time, you can now search for code within other teams that can help your own project."
msgstr ""
msgid "Promotions|This feature is locked."
-msgstr ""
+msgstr "Funktionen er låst."
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
-msgstr ""
+msgstr "Prøv det gratis"
msgid "Promotions|Upgrade plan"
-msgstr ""
+msgstr "Opgrader plan"
msgid "Promotions|Upgrade your plan to activate Advanced Search."
-msgstr ""
+msgstr "Opgrader din plan for at aktivere avanceret søgning."
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
@@ -26851,25 +27046,25 @@ msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
msgid "Promotions|Upgrade your plan to improve merge requests."
-msgstr ""
+msgstr "Opgrader din plan for at forbedre sammenlægningsanmodninger."
msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
msgstr ""
msgid "Promotions|Upgrade your plan to improve repositories."
-msgstr ""
+msgstr "Opgrader din plan for at forbedre depoter."
msgid "Promotions|Webhooks allow you to trigger a URL if, for example, new code is pushed or a new issue is created. You can configure webhooks to listen for specific events like pushes, issues or merge requests. Group webhooks will apply to all projects in a group, allowing you to standardize webhook functionality across your entire group."
msgstr ""
msgid "Promotions|Weight"
-msgstr ""
+msgstr "Vægt"
msgid "Promotions|Weighting your issue"
-msgstr ""
+msgstr "Vægtning af din problemstilling"
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
-msgstr ""
+msgstr "Når du har mange problemstillinger, så kan det være svært at få et overblik. Ved at tilføje en vægt til dine problemstillinger kan du bedre få en ide om den indtast, omkostning, krævede tid og værdien af hver, og dermed bedre vil kunne håndtere dem."
msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
msgstr ""
@@ -26887,43 +27082,43 @@ msgid "Prompt users to upload SSH keys"
msgstr ""
msgid "Protect"
-msgstr ""
+msgstr "Beskyt"
msgid "Protect a tag"
-msgstr ""
+msgstr "Beskyt et mærkat"
msgid "Protect variable"
-msgstr ""
+msgstr "Beskyt variabel"
msgid "Protected"
-msgstr ""
+msgstr "Beskyttet"
msgid "Protected Branch"
-msgstr ""
+msgstr "Beskyttet gren"
msgid "Protected Branches"
-msgstr ""
+msgstr "Beskyttet grene"
msgid "Protected Environment"
-msgstr ""
+msgstr "Beskyttet miljø"
msgid "Protected Paths"
-msgstr ""
+msgstr "Beskyttet stier"
msgid "Protected Paths: requests"
msgstr ""
msgid "Protected Tag"
-msgstr ""
+msgstr "Beskyttet mærkat"
msgid "Protected Tags"
-msgstr ""
+msgstr "Beskyttet mærkater"
msgid "Protected branches"
-msgstr ""
+msgstr "Beskyttede grene"
msgid "Protected environments"
-msgstr ""
+msgstr "Beskyttet miljøer"
msgid "ProtectedBranch|%{wildcards_link_start}Wildcards%{wildcards_link_end} such as %{code_tag_start}*-stable%{code_tag_end} or %{code_tag_start}production/*%{code_tag_end} are supported."
msgstr ""
@@ -26953,10 +27148,10 @@ msgid "ProtectedBranch|Allowed to push:"
msgstr ""
msgid "ProtectedBranch|Branch"
-msgstr ""
+msgstr "Gren"
msgid "ProtectedBranch|Branch:"
-msgstr ""
+msgstr "Gren:"
msgid "ProtectedBranch|By default, protected branches restrict who can modify the branch."
msgstr ""
@@ -26971,19 +27166,19 @@ msgid "ProtectedBranch|Keep stable branches secure and force developers to use m
msgstr ""
msgid "ProtectedBranch|Learn more."
-msgstr ""
+msgstr "Lær mere."
msgid "ProtectedBranch|Protect"
-msgstr ""
+msgstr "Beskyt"
msgid "ProtectedBranch|Protect a branch"
-msgstr ""
+msgstr "Beskyt en gren"
msgid "ProtectedBranch|Protected branch (%{protected_branches_count})"
msgstr ""
msgid "ProtectedBranch|Protected branches"
-msgstr ""
+msgstr "Beskyttet grene"
msgid "ProtectedBranch|Reject code pushes that change files listed in the CODEOWNERS file."
msgstr ""
@@ -27010,13 +27205,13 @@ msgid "ProtectedEnvironment|Allowed to deploy"
msgstr ""
msgid "ProtectedEnvironment|Environment"
-msgstr ""
+msgstr "Miljø"
msgid "ProtectedEnvironment|Only specified users can execute deployments in a protected environment."
msgstr ""
msgid "ProtectedEnvironment|Protect"
-msgstr ""
+msgstr "Beskyt"
msgid "ProtectedEnvironment|Protect an environment"
msgstr ""
@@ -27025,10 +27220,10 @@ msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_coun
msgstr ""
msgid "ProtectedEnvironment|Select an environment"
-msgstr ""
+msgstr "Vælg et miljø"
msgid "ProtectedEnvironment|Select users"
-msgstr ""
+msgstr "Vælg brugere"
msgid "ProtectedEnvironment|There are currently no protected environments. Protect an environment with this form."
msgstr ""
@@ -27049,13 +27244,13 @@ msgid "ProtectedTag|By default, protected branches restrict who can modify the t
msgstr ""
msgid "ProtectedTag|Learn more."
-msgstr ""
+msgstr "Lær mere."
msgid "ProtectedTag|Limit access to creating and updating tags."
msgstr ""
msgid "ProtectedTag|Protected tags"
-msgstr ""
+msgstr "Beskyttet mærkater"
msgid "ProtectedTag|What are protected tags?"
msgstr ""
@@ -27064,7 +27259,7 @@ msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to dep
msgstr ""
msgid "Provider"
-msgstr ""
+msgstr "Udbyder"
msgid "Provision instructions"
msgstr ""
@@ -27079,7 +27274,7 @@ msgid "Pseudonymizer data collection"
msgstr ""
msgid "Public"
-msgstr ""
+msgstr "Offentlig"
msgid "Public - The group and any public projects can be viewed without any authentication."
msgstr ""
@@ -27094,22 +27289,22 @@ msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
msgid "Public pipelines"
-msgstr ""
+msgstr "Offentlige pipelines"
msgid "Public projects Minutes cost factor"
msgstr ""
msgid "Publish to status page"
-msgstr ""
+msgstr "Udgiv til statussiden"
msgid "Published"
-msgstr ""
+msgstr "Udgivet"
msgid "Published on status page"
-msgstr ""
+msgstr "Udgivet på statussiden"
msgid "Publishes this issue to the associated status page."
-msgstr ""
+msgstr "Udgiver problemstillingen til den tilknyttede statusside."
msgid "Pull"
msgstr ""
@@ -27121,10 +27316,10 @@ msgid "Puma is running with a thread count above 1 and the Rugged service is ena
msgstr ""
msgid "Purchase more minutes"
-msgstr ""
+msgstr "Køb flere minutter"
msgid "Purchase more storage"
-msgstr ""
+msgstr "Køb mere lager"
msgid "PurchaseStep|An error occured in the purchase step. If the problem persists please contact support@gitlab.com."
msgstr ""
@@ -27226,25 +27421,25 @@ msgid "PushoverService|Enter your application key."
msgstr ""
msgid "PushoverService|Enter your user key."
-msgstr ""
+msgstr "Indtast din brugernøgle."
msgid "PushoverService|Get real-time notifications on your device."
msgstr ""
msgid "PushoverService|High priority"
-msgstr ""
+msgstr "Høj prioritet"
msgid "PushoverService|Leave blank for all active devices."
msgstr ""
msgid "PushoverService|Low priority"
-msgstr ""
+msgstr "Lav prioritet"
msgid "PushoverService|Lowest priority"
-msgstr ""
+msgstr "Laveste prioritet"
msgid "PushoverService|Normal priority"
-msgstr ""
+msgstr "Normal prioritet"
msgid "PushoverService|See project %{project_full_name}"
msgstr ""
@@ -27256,7 +27451,7 @@ msgid "Quarters"
msgstr ""
msgid "Query"
-msgstr ""
+msgstr "Forespørgsel"
msgid "Query cannot be processed"
msgstr ""
@@ -27265,7 +27460,7 @@ msgid "Query is valid"
msgstr ""
msgid "Queued"
-msgstr ""
+msgstr "Sat i kø"
msgid "Quick actions can be used in description and comment boxes."
msgstr ""
@@ -27280,7 +27475,7 @@ msgid "Quickly and easily edit multiple files in your project."
msgstr ""
msgid "README"
-msgstr ""
+msgstr "README"
msgid "Rails"
msgstr ""
@@ -27289,7 +27484,7 @@ msgid "Rake Tasks Help"
msgstr ""
msgid "Random"
-msgstr ""
+msgstr "Tilfældig"
msgid "Rate Limits"
msgstr ""
@@ -27316,31 +27511,37 @@ msgid "Re-verification interval"
msgstr ""
msgid "Read documentation"
-msgstr ""
+msgstr "Læs dokumentation"
msgid "Read more"
-msgstr ""
+msgstr "Læs mere"
msgid "Read more about GitLab at %{link_to_promo}."
-msgstr ""
+msgstr "Læs mere om GitLab på %{link_to_promo}."
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
-msgstr ""
+msgstr "Læs mere om projekttilladelser %{help_link_open}her%{help_link_close}"
msgid "Read more about related issues"
-msgstr ""
+msgstr "Læs mere om relaterede problemstillinger"
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
msgid "Rebase"
-msgstr ""
+msgstr "Rebase"
msgid "Rebase in progress"
-msgstr ""
+msgstr "Rebase i gang"
msgid "Rebase source branch"
msgstr ""
@@ -27364,7 +27565,7 @@ msgid "Receive product marketing emails"
msgstr ""
msgid "Recent"
-msgstr ""
+msgstr "Seneste"
msgid "Recent Deliveries"
msgstr ""
@@ -27379,49 +27580,52 @@ msgid "Recent jobs served by this runner"
msgstr ""
msgid "Recent searches"
-msgstr ""
+msgstr "Seneste søgninger"
msgid "Recently used"
msgstr ""
msgid "Reconfigure"
-msgstr ""
+msgstr "Genkonfigurer"
msgid "Recovering projects"
-msgstr ""
+msgstr "Gendanner projekter"
msgid "Recovery Codes"
-msgstr ""
+msgstr "Gendannelseskoder"
msgid "Redirect to SAML provider to test configuration"
msgstr ""
msgid "Redirecting"
-msgstr ""
+msgstr "Omdirigerer"
msgid "Redis"
msgstr ""
-msgid "Reduce project visibility"
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
msgstr ""
+msgid "Reduce project visibility"
+msgstr "Reducer projektets synlighed"
+
msgid "Reduce this project’s visibility?"
-msgstr ""
+msgstr "Reducer projektets synlighed?"
msgid "Reference"
-msgstr ""
+msgstr "Reference"
msgid "References"
-msgstr ""
+msgstr "Referencer"
msgid "Refine your search criteria (select a %{strong_open}group%{strong_close} and %{strong_open}project%{strong_close} when possible)"
msgstr ""
msgid "Refresh"
-msgstr ""
+msgstr "Opdater"
msgid "Refresh the page and try again."
-msgstr ""
+msgstr "Opdater siden og prøv igen."
msgid "Refreshing in a second to show the updated status..."
msgid_plural "Refreshing in %d seconds to show the updated status..."
@@ -27450,10 +27654,10 @@ msgid "Region that Elasticsearch is configured"
msgstr ""
msgid "Register"
-msgstr ""
+msgstr "Tilmeld"
msgid "Register / Sign In"
-msgstr ""
+msgstr "Tilmeld/log ind"
msgid "Register Two-Factor Authenticator"
msgstr ""
@@ -27486,13 +27690,13 @@ msgid "Registration|Checkout"
msgstr ""
msgid "Registration|Your GitLab group"
-msgstr ""
+msgstr "Din GitLab-gruppe"
msgid "Registration|Your first project"
-msgstr ""
+msgstr "Dit første projekt"
msgid "Registration|Your profile"
-msgstr ""
+msgstr "Din profil"
msgid "Registry setup"
msgstr ""
@@ -27504,10 +27708,10 @@ msgid "Reindexing Status: %{status} (Slice multiplier: %{multiplier}, Maximum ru
msgstr ""
msgid "Rejected (closed)"
-msgstr ""
+msgstr "Afvist (lukket)"
msgid "Related feature flags"
-msgstr ""
+msgstr "Relaterede funktionsflag"
msgid "Related issues"
msgstr ""
@@ -27515,13 +27719,16 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
msgid "Release"
msgid_plural "Releases"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Udgivelse"
+msgstr[1] "Udgivelser"
msgid "Release assets"
msgstr ""
@@ -27542,22 +27749,22 @@ msgid "Release title"
msgstr ""
msgid "Release with tag \"%{tag}\" was not found"
-msgstr ""
+msgstr "Udgivelse med mærkatet \"%{tag}\" blev ikke fundet"
msgid "ReleaseAssetLinkType|Image"
-msgstr ""
+msgstr "Billede"
msgid "ReleaseAssetLinkType|Images"
-msgstr ""
+msgstr "Billeder"
msgid "ReleaseAssetLinkType|Other"
msgstr ""
msgid "ReleaseAssetLinkType|Package"
-msgstr ""
+msgstr "Pakke"
msgid "ReleaseAssetLinkType|Packages"
-msgstr ""
+msgstr "Pakker"
msgid "ReleaseAssetLinkType|Runbook"
msgstr ""
@@ -27569,7 +27776,7 @@ msgid "Released date"
msgstr ""
msgid "Releases"
-msgstr ""
+msgstr "Udgivelser"
msgid "Releases are based on Git tags and mark specific points in a project's development history. They can contain information about the type of changes and can also deliver binaries, like compiled versions of your software."
msgstr ""
@@ -27581,7 +27788,7 @@ msgid "Releases documentation"
msgstr ""
msgid "Releases|New Release"
-msgstr ""
+msgstr "Ny udgivelse"
msgid "Release|Something went wrong while creating a new release."
msgstr ""
@@ -27596,25 +27803,25 @@ msgid "Remediations"
msgstr ""
msgid "Remember me"
-msgstr ""
+msgstr "Husk mig"
msgid "Remind later"
-msgstr ""
+msgstr "PÃ¥mind senere"
msgid "Remote object has no absolute path."
msgstr ""
msgid "Remove"
-msgstr ""
+msgstr "Fjern"
msgid "Remove %{displayReference}"
-msgstr ""
+msgstr "Fjern %{displayReference}"
msgid "Remove Zoom meeting"
-msgstr ""
+msgstr "Fjern Zoom-møde"
msgid "Remove access"
-msgstr ""
+msgstr "Fjern adgang"
msgid "Remove all or specific assignee(s)"
msgstr ""
@@ -27626,13 +27833,13 @@ msgid "Remove all or specific reviewer(s)"
msgstr ""
msgid "Remove approver"
-msgstr ""
+msgstr "Fjern godkender"
msgid "Remove approvers"
-msgstr ""
+msgstr "Fjern godkendere"
msgid "Remove approvers?"
-msgstr ""
+msgstr "Fjern godkendere?"
msgid "Remove asset link"
msgstr ""
@@ -27641,28 +27848,28 @@ msgid "Remove assignee"
msgstr ""
msgid "Remove avatar"
-msgstr ""
+msgstr "Fjern avatar"
msgid "Remove card"
-msgstr ""
+msgstr "Fjern kort"
msgid "Remove child epic from an epic"
msgstr ""
msgid "Remove deploy key"
-msgstr ""
+msgstr "Fjern udsendelsesnøgle"
msgid "Remove description history"
msgstr ""
msgid "Remove due date"
-msgstr ""
+msgstr "Fjern forfaldsdato"
msgid "Remove favicon"
-msgstr ""
+msgstr "Fjern favicon"
msgid "Remove file"
-msgstr ""
+msgstr "Fjern fil"
msgid "Remove fork relationship"
msgstr ""
@@ -27671,58 +27878,58 @@ msgid "Remove from batch"
msgstr ""
msgid "Remove from epic"
-msgstr ""
+msgstr "Fjern fra epic"
msgid "Remove group"
-msgstr ""
+msgstr "Fjern gruppe"
msgid "Remove header logo"
-msgstr ""
+msgstr "Fjern headerlogo"
msgid "Remove iteration"
-msgstr ""
+msgstr "Fjern gennemløb"
msgid "Remove license"
-msgstr ""
+msgstr "Fjern licens"
msgid "Remove limit"
-msgstr ""
+msgstr "Fjern grænse"
msgid "Remove link"
-msgstr ""
+msgstr "Fjern link"
msgid "Remove list"
-msgstr ""
+msgstr "Fjern liste"
msgid "Remove log"
-msgstr ""
+msgstr "Fjern log"
msgid "Remove logo"
-msgstr ""
+msgstr "Fjern logo"
msgid "Remove member"
-msgstr ""
+msgstr "Fjern medlem"
msgid "Remove milestone"
-msgstr ""
+msgstr "Fjern milepæl"
msgid "Remove parent epic from an epic"
msgstr ""
msgid "Remove priority"
-msgstr ""
+msgstr "Fjern prioritet"
msgid "Remove report"
-msgstr ""
+msgstr "Fjern rapport"
msgid "Remove reviewer"
-msgstr ""
+msgstr "Fjern kontrollant"
msgid "Remove runner"
msgstr ""
msgid "Remove secondary email"
-msgstr ""
+msgstr "Fjern sekundære e-mail"
msgid "Remove spent time"
msgstr ""
@@ -27731,49 +27938,49 @@ msgid "Remove time estimate"
msgstr ""
msgid "Remove user"
-msgstr ""
+msgstr "Fjern bruger"
msgid "Remove user & report"
-msgstr ""
+msgstr "Fjern bruger og rapport"
msgid "Remove user from group"
-msgstr ""
+msgstr "Fjern bruger fra gruppe"
msgid "Remove user from project"
-msgstr ""
+msgstr "Fjern bruger fra projekt"
msgid "Remove..."
-msgstr ""
+msgstr "Fjern ..."
msgid "Removed"
-msgstr ""
+msgstr "Fjernet"
msgid "Removed %{assignee_text} %{assignee_references}."
-msgstr ""
+msgstr "Fjernede %{assignee_text} %{assignee_references}."
msgid "Removed %{epic_ref} from child epics."
-msgstr ""
+msgstr "Fjernede %{epic_ref} fra underepics."
msgid "Removed %{iteration_reference} iteration."
msgstr ""
msgid "Removed %{label_references} %{label_text}."
-msgstr ""
+msgstr "Fjernede %{label_references} %{label_text}."
msgid "Removed %{milestone_reference} milestone."
msgstr ""
msgid "Removed %{reviewer_text} %{reviewer_references}."
-msgstr ""
+msgstr "Fjernede %{reviewer_text} %{reviewer_references}."
msgid "Removed %{type} with id %{id}"
-msgstr ""
+msgstr "Fjernede %{type} med id'et %{id}"
msgid "Removed all labels."
-msgstr ""
+msgstr "Fjernede alle etiketter."
msgid "Removed an issue from an epic."
-msgstr ""
+msgstr "Fjernede en problemstilling fra en epic."
msgid "Removed group can not be restored!"
msgstr ""
@@ -27785,7 +27992,7 @@ msgid "Removed spent time."
msgstr ""
msgid "Removed the due date."
-msgstr ""
+msgstr "Fjernede forfaldsdatoen."
msgid "Removed time estimate."
msgstr ""
@@ -27797,28 +28004,28 @@ msgid "RemovedProjects|You haven’t removed any projects."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
-msgstr ""
+msgstr "Fjerner %{assignee_text} %{assignee_references}."
msgid "Removes %{epic_ref} from child epics."
-msgstr ""
+msgstr "Fjerner %{epic_ref} fra underepics."
msgid "Removes %{iteration_reference} iteration."
msgstr ""
msgid "Removes %{label_references} %{label_text}."
-msgstr ""
+msgstr "Fjerner %{label_references} %{label_text}."
msgid "Removes %{milestone_reference} milestone."
msgstr ""
msgid "Removes %{reviewer_text} %{reviewer_references}."
-msgstr ""
+msgstr "Fjerner %{reviewer_text} %{reviewer_references}."
msgid "Removes all labels."
-msgstr ""
+msgstr "Fjerner alle etiketter."
msgid "Removes an issue from an epic."
-msgstr ""
+msgstr "Fjerner en problemstilling fra en epic."
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -27827,7 +28034,7 @@ msgid "Removes spent time."
msgstr ""
msgid "Removes the due date."
-msgstr ""
+msgstr "Fjerner forfaldsdatoen."
msgid "Removes time estimate."
msgstr ""
@@ -27836,34 +28043,34 @@ msgid "Removing this group also removes all child projects, including archived p
msgstr ""
msgid "Rename file"
-msgstr ""
+msgstr "Omdøb fil"
msgid "Rename folder"
-msgstr ""
+msgstr "Omdøb mappe"
msgid "Rename/Move"
-msgstr ""
+msgstr "Omdøb/flyt"
msgid "Render diagrams in your documents using PlantUML."
msgstr ""
msgid "Renew subscription"
-msgstr ""
+msgstr "Forny abonnement"
msgid "Reopen"
-msgstr ""
+msgstr "Genåbn"
msgid "Reopen %{issueType}"
-msgstr ""
+msgstr "Genåbn %{issueType}"
msgid "Reopen epic"
-msgstr ""
+msgstr "Genåbn epic"
msgid "Reopen milestone"
-msgstr ""
+msgstr "Genåbn milepæl"
msgid "Reopen test case"
-msgstr ""
+msgstr "Genåbn testsag"
msgid "Reopen this %{quick_action_target}"
msgstr ""
@@ -27875,19 +28082,19 @@ msgid "Reopens this %{quick_action_target}."
msgstr ""
msgid "Replace"
-msgstr ""
+msgstr "Erstat"
msgid "Replace %{name}"
-msgstr ""
+msgstr "Erstat %{name}"
msgid "Replace all label(s)"
-msgstr ""
+msgstr "Erstat alle etiketter"
msgid "Replace file"
-msgstr ""
+msgstr "Erstat fil"
msgid "Replaced all labels with %{label_references} %{label_text}."
-msgstr ""
+msgstr "Erstat alle etiketter med %{label_references} %{label_text}."
msgid "Replaces the clone URL root."
msgstr ""
@@ -27896,16 +28103,16 @@ msgid "Replication"
msgstr ""
msgid "Reply by email"
-msgstr ""
+msgstr "Besvar via e-mail"
msgid "Reply to comment"
-msgstr ""
+msgstr "Besvar kommentar"
msgid "Reply to this email directly or %{view_it_on_gitlab}."
-msgstr ""
+msgstr "Besvar e-mailen direkte eller %{view_it_on_gitlab}."
msgid "Reply…"
-msgstr ""
+msgstr "Besvar …"
msgid "Repo by URL"
msgstr ""
@@ -27914,25 +28121,25 @@ msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
msgstr ""
msgid "Report abuse"
-msgstr ""
+msgstr "Rapportér misbrug"
msgid "Report abuse to admin"
-msgstr ""
+msgstr "Rapportér misbrug til administrator"
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
msgid "Reported by"
-msgstr ""
+msgstr "Rapporteret af"
msgid "Reported by %{reporter}"
-msgstr ""
+msgstr "Rapporteret af %{reporter}"
msgid "Reporting"
-msgstr ""
+msgstr "Rapporterer"
msgid "Reports|%{combinedString} and %{resolvedString}"
-msgstr ""
+msgstr "%{combinedString} og %{resolvedString}"
msgid "Reports|%{recentlyFailed} out of %{failed} failed test has failed more than once in the last 14 days"
msgstr ""
@@ -27957,10 +28164,10 @@ msgid "Reports|Accessibility scanning results are being parsed"
msgstr ""
msgid "Reports|Actions"
-msgstr ""
+msgstr "Handlinger"
msgid "Reports|Activity"
-msgstr ""
+msgstr "Aktivitet"
msgid "Reports|An error occurred while loading %{name} results"
msgstr ""
@@ -27972,7 +28179,7 @@ msgid "Reports|Base report parsing error:"
msgstr ""
msgid "Reports|Classname"
-msgstr ""
+msgstr "Klassenavn"
msgid "Reports|Execution time"
msgstr ""
@@ -27991,7 +28198,7 @@ msgid "Reports|Failure"
msgstr ""
msgid "Reports|Filename"
-msgstr ""
+msgstr "Filnavn"
msgid "Reports|Head report parsing error:"
msgstr ""
@@ -28029,9 +28236,12 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
-msgid "Reports|Vulnerability"
+msgid "Reports|Tool"
msgstr ""
+msgid "Reports|Vulnerability"
+msgstr "SÃ¥rbarhed"
+
msgid "Reports|Vulnerability Name"
msgstr ""
@@ -28039,7 +28249,7 @@ msgid "Reports|no changed test results"
msgstr ""
msgid "Repositories"
-msgstr ""
+msgstr "Depoter"
msgid "Repositories Analytics"
msgstr ""
@@ -28075,7 +28285,7 @@ msgid "RepositoriesAnalytics|Jobs with Coverage"
msgstr ""
msgid "RepositoriesAnalytics|Last Update"
-msgstr ""
+msgstr "Sidste opdatering"
msgid "RepositoriesAnalytics|Latest test coverage results"
msgstr ""
@@ -28096,10 +28306,10 @@ msgid "RepositoriesAnalytics|Test Code Coverage"
msgstr ""
msgid "RepositoriesAnalytics|There was an error fetching the projects."
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af projekterne."
msgid "Repository"
-msgstr ""
+msgstr "Depot"
msgid "Repository Analytics"
msgstr ""
@@ -28111,7 +28321,7 @@ msgid "Repository Settings"
msgstr ""
msgid "Repository already read-only"
-msgstr ""
+msgstr "Depotet er allerede skrivebeskyttet"
msgid "Repository check"
msgstr ""
@@ -28216,7 +28426,7 @@ msgid "Requested states are invalid"
msgstr ""
msgid "Requests"
-msgstr ""
+msgstr "Forespørgelser"
msgid "Requests Profiles"
msgstr ""
@@ -28246,7 +28456,7 @@ msgid "Required approvals (%{approvals_given} given, you've approved)"
msgstr ""
msgid "Required in this project."
-msgstr ""
+msgstr "Kræves i projektet."
msgid "Requirement %{reference} has been added"
msgstr ""
@@ -28264,7 +28474,7 @@ msgid "Requirement title cannot have more than %{limit} characters."
msgstr ""
msgid "Requirements"
-msgstr ""
+msgstr "Krav"
msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
@@ -28286,25 +28496,25 @@ msgid "Requires your primary GitLab email address."
msgstr ""
msgid "Resend"
-msgstr ""
+msgstr "Send igen"
msgid "Resend Request"
msgstr ""
msgid "Resend confirmation email"
-msgstr ""
+msgstr "Send bekræftelses e-mail igen"
msgid "Resend invite"
-msgstr ""
+msgstr "Send invitation igen"
msgid "Resend it"
-msgstr ""
+msgstr "Send den igen"
msgid "Resend unlock instructions"
msgstr ""
msgid "Reset"
-msgstr ""
+msgstr "Nulstil"
msgid "Reset authorization key"
msgstr ""
@@ -28313,25 +28523,25 @@ msgid "Reset authorization key?"
msgstr ""
msgid "Reset filters"
-msgstr ""
+msgstr "Nulstil filtre"
msgid "Reset health check access token"
msgstr ""
msgid "Reset key"
-msgstr ""
+msgstr "Nulstil nøgle"
msgid "Reset link will be generated and sent to the user. %{break} User will be forced to set the password on first sign in."
msgstr ""
msgid "Reset password"
-msgstr ""
+msgstr "Nulstil adgangskode"
msgid "Reset registration token"
msgstr ""
msgid "Reset template"
-msgstr ""
+msgstr "Nulstil skabelon"
msgid "Reset to project defaults"
msgstr ""
@@ -28340,13 +28550,13 @@ msgid "Resetting the authorization key will invalidate the previous key. Existin
msgstr ""
msgid "Resolve"
-msgstr ""
+msgstr "Løs"
msgid "Resolve all threads in new issue"
-msgstr ""
+msgstr "Løs alle tråde i ny problemstilling"
msgid "Resolve conflicts"
-msgstr ""
+msgstr "Løs konflikter"
msgid "Resolve conflicts on source branch"
msgstr ""
@@ -28355,28 +28565,28 @@ msgid "Resolve these conflicts or ask someone with write access to this reposito
msgstr ""
msgid "Resolve thread"
-msgstr ""
+msgstr "Løs tråd"
msgid "Resolved"
-msgstr ""
+msgstr "Løst"
msgid "Resolved 1 discussion."
-msgstr ""
+msgstr "Løste 1 debat."
msgid "Resolved all discussions."
-msgstr ""
+msgstr "Løste alle debatter."
msgid "Resolved by"
-msgstr ""
+msgstr "Løst af"
msgid "Resolved by %{name}"
-msgstr ""
+msgstr "Løst af %{name}"
msgid "Resolves IP addresses once and uses them to submit requests"
msgstr ""
msgid "Response"
-msgstr ""
+msgstr "Svar"
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -28406,13 +28616,13 @@ msgid "Restart Terminal"
msgstr ""
msgid "Restore"
-msgstr ""
+msgstr "Gendan"
msgid "Restore group"
-msgstr ""
+msgstr "Gendan gruppe"
msgid "Restore project"
-msgstr ""
+msgstr "Gendan projekt"
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -28433,19 +28643,19 @@ msgid "Resume"
msgstr ""
msgid "Resync"
-msgstr ""
+msgstr "Synkroniser igen"
msgid "Retry"
-msgstr ""
+msgstr "Prøv igen"
msgid "Retry job"
-msgstr ""
+msgstr "Prøv job igen"
msgid "Retry migration"
msgstr ""
msgid "Retry this job"
-msgstr ""
+msgstr "Prøv jobbet igen"
msgid "Retry this job in order to create the necessary resources."
msgstr ""
@@ -28455,20 +28665,20 @@ msgstr ""
msgid "Reveal value"
msgid_plural "Reveal values"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Vis værdi"
+msgstr[1] "Vis værdier"
msgid "Reveal values"
-msgstr ""
+msgstr "Vis værdier"
msgid "Revert this commit"
-msgstr ""
+msgstr "Tilbagefør committen"
msgid "Revert this merge request"
msgstr ""
msgid "Review"
-msgstr ""
+msgstr "Kontrol"
msgid "Review App|View app"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28502,26 +28715,26 @@ msgstr ""
msgid "Reviewer"
msgid_plural "%d Reviewers"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Kontrollant"
+msgstr[1] "%d kontrollanter"
msgid "Reviewer(s)"
-msgstr ""
+msgstr "Kontrollanter"
msgid "Reviewers"
-msgstr ""
+msgstr "Kontrollanter"
msgid "Reviewing"
-msgstr ""
+msgstr "Kontrollerer"
msgid "Reviewing (merge request !%{mergeRequestId})"
msgstr ""
msgid "Revoke"
-msgstr ""
+msgstr "Tilbagekald"
msgid "Revoked"
-msgstr ""
+msgstr "Tilbagekaldt"
msgid "Revoked impersonation token %{token_name}!"
msgstr ""
@@ -28533,7 +28746,7 @@ msgid "Revoked project access token %{project_access_token_name}!"
msgstr ""
msgid "RightSidebar|Copy email address"
-msgstr ""
+msgstr "Kopiér e-mailadresse"
msgid "RightSidebar|Issue email"
msgstr ""
@@ -28542,7 +28755,7 @@ msgid "RightSidebar|adding a"
msgstr ""
msgid "RightSidebar|deleting the"
-msgstr ""
+msgstr "sletter"
msgid "Rnners|Don't see what you are looking for? See the full list of options, including a fully customizable option, %{linkStart}here%{linkEnd}."
msgstr ""
@@ -28551,13 +28764,13 @@ msgid "Roadmap"
msgstr ""
msgid "Role"
-msgstr ""
+msgstr "Rolle"
msgid "Rollback"
msgstr ""
msgid "Ruby"
-msgstr ""
+msgstr "Ruby"
msgid "Rule name is already taken."
msgstr ""
@@ -28635,10 +28848,10 @@ msgid "Runners|An error has occurred fetching instructions"
msgstr ""
msgid "Runners|Architecture"
-msgstr ""
+msgstr "Arkitektur"
msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
+msgstr "Er du sikker på, at du vil slette runneren?"
msgid "Runners|Can run untagged jobs"
msgstr ""
@@ -28653,7 +28866,7 @@ msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
msgid "Runners|Description"
-msgstr ""
+msgstr "Beskrivelse"
msgid "Runners|Download and install binary"
msgstr ""
@@ -28671,7 +28884,7 @@ msgid "Runners|Group Runners"
msgstr ""
msgid "Runners|IP Address"
-msgstr ""
+msgstr "IP-adresse"
msgid "Runners|If you do not select an AWS VPC, the runner will deploy to the Default VPC in the AWS Region you select. Please consult with your AWS administrator to understand if there are any security risks to deploying into the Default VPC in any given region in your AWS account."
msgstr ""
@@ -28683,7 +28896,7 @@ msgid "Runners|Last contact"
msgstr ""
msgid "Runners|Locked to this project"
-msgstr ""
+msgstr "LÃ¥st til projektet"
msgid "Runners|Maximum job timeout"
msgstr ""
@@ -28692,7 +28905,7 @@ msgid "Runners|Members of the %{type} can register runners"
msgstr ""
msgid "Runners|Name"
-msgstr ""
+msgstr "Navn"
msgid "Runners|New registration token generated!"
msgstr ""
@@ -28707,22 +28920,22 @@ msgid "Runners|Offline"
msgstr ""
msgid "Runners|Online"
-msgstr ""
+msgstr "Online"
msgid "Runners|Paused"
msgstr ""
msgid "Runners|Platform"
-msgstr ""
+msgstr "Platform"
msgid "Runners|Property Name"
msgstr ""
msgid "Runners|Protected"
-msgstr ""
+msgstr "Beskyttet"
msgid "Runners|Revision"
-msgstr ""
+msgstr "Revision"
msgid "Runners|Runner"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28761,7 +28977,7 @@ msgid "Runners|Stop the runner from accepting new jobs."
msgstr ""
msgid "Runners|Tags"
-msgstr ""
+msgstr "Mærkater"
msgid "Runners|This runner is associated with one or more projects."
msgstr ""
@@ -28794,10 +29010,10 @@ msgid "Runners|Use the runner on pipelines for protected branches only."
msgstr ""
msgid "Runners|Value"
-msgstr ""
+msgstr "Værdi"
msgid "Runners|Version"
-msgstr ""
+msgstr "Version"
msgid "Runners|View installation instructions"
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -28815,28 +29034,28 @@ msgid "Runners|You have used %{quotaUsed} out of %{quotaLimit} of your shared Ru
msgstr ""
msgid "Runners|group"
-msgstr ""
+msgstr "gruppe"
msgid "Runners|instance"
-msgstr ""
+msgstr "instans"
msgid "Runners|locked"
-msgstr ""
+msgstr "låst"
msgid "Runners|paused"
msgstr ""
msgid "Runners|project"
-msgstr ""
+msgstr "projekt"
msgid "Runners|shared"
-msgstr ""
+msgstr "delt"
msgid "Runners|specific"
msgstr ""
msgid "Running"
-msgstr ""
+msgstr "Kører"
msgid "Runs a number of housekeeping tasks within the current repository, such as compressing file revisions and removing unreachable objects."
msgstr ""
@@ -28851,7 +29070,7 @@ msgid "Runs jobs from assigned projects."
msgstr ""
msgid "SAML"
-msgstr ""
+msgstr "SAML"
msgid "SAML SSO"
msgstr ""
@@ -28869,16 +29088,16 @@ msgid "SAST Configuration"
msgstr ""
msgid "SHA256"
-msgstr ""
+msgstr "SHA256"
msgid "SSH Key"
-msgstr ""
+msgstr "SSH-nøgle"
msgid "SSH Keys"
-msgstr ""
+msgstr "SSH-nøgler"
msgid "SSH Keys Help"
-msgstr ""
+msgstr "Hjælp for SSH-nøgler"
msgid "SSH host key fingerprints"
msgstr ""
@@ -28890,10 +29109,10 @@ msgid "SSH host keys are not available on this system. Please use %{ssh_keyscan}
msgstr ""
msgid "SSH key"
-msgstr ""
+msgstr "SSH-nøgle"
msgid "SSH keys"
-msgstr ""
+msgstr "SSH-nøgler"
msgid "SSH keys allow you to establish a secure connection between your computer and GitLab."
msgstr ""
@@ -28929,43 +29148,43 @@ msgid "SastEntryPoints|How do I set up SAST?"
msgstr ""
msgid "SastEntryPoints|Learn more."
-msgstr ""
+msgstr "Lær mere."
msgid "Satisfied"
msgstr ""
msgid "Saturday"
-msgstr ""
+msgstr "Lørdag"
msgid "Save"
-msgstr ""
+msgstr "Gem"
msgid "Save %{name} size limits"
msgstr ""
msgid "Save Changes"
-msgstr ""
+msgstr "Gem ændringer"
msgid "Save Value Stream"
-msgstr ""
+msgstr "Gem Value Stream"
msgid "Save application"
-msgstr ""
+msgstr "Gem program"
msgid "Save changes"
-msgstr ""
+msgstr "Gem ændringer"
msgid "Save changes before testing"
msgstr ""
msgid "Save comment"
-msgstr ""
+msgstr "Gem kommentar"
msgid "Save deploy freeze"
msgstr ""
msgid "Save password"
-msgstr ""
+msgstr "Gem adgangskode"
msgid "Save pipeline schedule"
msgstr ""
@@ -28974,13 +29193,13 @@ msgid "Save space and find images in the container Registry. remove unneeded tag
msgstr ""
msgid "Saving"
-msgstr ""
+msgstr "Gemmer"
msgid "Saving project."
-msgstr ""
+msgstr "Gemmer projekt."
msgid "Scanner"
-msgstr ""
+msgstr "Skanner"
msgid "Scanner profile failed to delete"
msgstr ""
@@ -29019,52 +29238,52 @@ msgid "Scheduling Pipelines"
msgstr ""
msgid "Scope"
-msgstr ""
+msgstr "Omfang"
msgid "Scope board to current iteration"
msgstr ""
msgid "Scopes"
-msgstr ""
+msgstr "Omfang"
msgid "Scopes (select at least one)"
-msgstr ""
+msgstr "Omfang (vælg mindst en)"
msgid "Scopes can't be blank"
-msgstr ""
+msgstr "Omfang må ikke være tomt"
msgid "Scopes: %{scope_list}"
-msgstr ""
+msgstr "Omfang: %{scope_list}"
msgid "Scroll down"
-msgstr ""
+msgstr "Rul ned"
msgid "Scroll left"
-msgstr ""
+msgstr "Rul til venstre"
msgid "Scroll right"
-msgstr ""
+msgstr "Rul til højre"
msgid "Scroll to bottom"
-msgstr ""
+msgstr "Rul nederst"
msgid "Scroll to top"
-msgstr ""
+msgstr "Rul øverst"
msgid "Scroll up"
-msgstr ""
+msgstr "Rul op"
msgid "Search"
-msgstr ""
+msgstr "Søg"
msgid "Search GitLab"
-msgstr ""
+msgstr "Søg på GitLab"
msgid "Search Jira issues"
-msgstr ""
+msgstr "Søg efter Jura-problemstillinger"
msgid "Search a group"
-msgstr ""
+msgstr "Søg efter en gruppe"
msgid "Search an environment spec"
msgstr ""
@@ -29073,100 +29292,100 @@ msgid "Search assignees"
msgstr ""
msgid "Search authors"
-msgstr ""
+msgstr "Søg efter forfattere"
msgid "Search branches"
-msgstr ""
+msgstr "Søg efter grene"
msgid "Search branches and tags"
-msgstr ""
+msgstr "Søg efter grene og mærkater"
msgid "Search branches, tags, and commits"
-msgstr ""
+msgstr "Søg efter grene, mærkater og commits"
msgid "Search by Git revision"
-msgstr ""
+msgstr "Søg efter Git-revision"
msgid "Search by author"
-msgstr ""
+msgstr "Søg efter forfatter"
msgid "Search by commit title or SHA"
msgstr ""
msgid "Search by message"
-msgstr ""
+msgstr "Søg efter meddelelse"
msgid "Search by name"
-msgstr ""
+msgstr "Søg efter navn"
msgid "Search files"
-msgstr ""
+msgstr "Søg efter filer"
msgid "Search for Namespace"
-msgstr ""
+msgstr "Søg efter navnerum"
msgid "Search for a LDAP group"
-msgstr ""
+msgstr "Søg efter en LDAP-gruppe"
msgid "Search for a group"
-msgstr ""
+msgstr "Søg efter en gruppe"
msgid "Search for a user"
-msgstr ""
+msgstr "Søg efter en bruger"
msgid "Search for projects, issues, etc."
-msgstr ""
+msgstr "Søg efter projekter, problemstillinger osv."
msgid "Search for this text"
-msgstr ""
+msgstr "Søg efter teksten"
msgid "Search forks"
-msgstr ""
+msgstr "Søg efter forgreninger"
msgid "Search iterations"
-msgstr ""
+msgstr "Søg efter gennemløb"
msgid "Search labels"
-msgstr ""
+msgstr "Søg efter etiketter"
msgid "Search merge requests"
-msgstr ""
+msgstr "Søg efter sammenlægningsanmodninger"
msgid "Search milestones"
-msgstr ""
+msgstr "Søg efter milepæle"
msgid "Search or create tag"
-msgstr ""
+msgstr "Søg efter eller opret mærkat"
msgid "Search or filter results..."
-msgstr ""
+msgstr "Søg efter eller filtrér resultater ..."
msgid "Search or filter results…"
-msgstr ""
+msgstr "Søg efter eller filtrér resultater …"
msgid "Search project"
-msgstr ""
+msgstr "Søg efter projekt"
msgid "Search projects"
-msgstr ""
+msgstr "Søg efter projekter"
msgid "Search projects..."
-msgstr ""
+msgstr "Søg efter projekter ..."
msgid "Search refs"
msgstr ""
msgid "Search requirements"
-msgstr ""
+msgstr "Søg efter krav"
msgid "Search settings"
-msgstr ""
+msgstr "Søg efter indstillinger"
msgid "Search users"
-msgstr ""
+msgstr "Søg efter brugere"
msgid "Search users or groups"
-msgstr ""
+msgstr "Søg efter brugere eller grupper"
msgid "Search your project dependencies for their licenses and apply policies."
msgstr ""
@@ -29178,16 +29397,16 @@ msgid "SearchAutocomplete|All GitLab"
msgstr ""
msgid "SearchAutocomplete|Issues I've created"
-msgstr ""
+msgstr "Problemstillinger jeg har oprettet"
msgid "SearchAutocomplete|Issues assigned to me"
-msgstr ""
+msgstr "Problemstillinger tildelt til mig"
msgid "SearchAutocomplete|Merge requests I've created"
-msgstr ""
+msgstr "Sammenlægningsanmodninger jeg har oprettet"
msgid "SearchAutocomplete|Merge requests assigned to me"
-msgstr ""
+msgstr "Sammenlægningsanmodninger tildelt til mig"
msgid "SearchAutocomplete|Merge requests that I'm a reviewer"
msgstr ""
@@ -29196,10 +29415,10 @@ msgid "SearchAutocomplete|in all GitLab"
msgstr ""
msgid "SearchAutocomplete|in group %{groupName}"
-msgstr ""
+msgstr "i gruppen %{groupName}"
msgid "SearchAutocomplete|in project %{projectName}"
-msgstr ""
+msgstr "i projektet %{projectName}"
msgid "SearchCodeResults|of %{link_to_project}"
msgstr ""
@@ -29218,53 +29437,53 @@ msgstr ""
msgid "SearchResults|code result"
msgid_plural "SearchResults|code results"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "koderesultat"
+msgstr[1] "koderesultater"
msgid "SearchResults|comment"
msgid_plural "SearchResults|comments"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "kommentar"
+msgstr[1] "kommentarer"
msgid "SearchResults|commit"
msgid_plural "SearchResults|commits"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "commit"
+msgstr[1] "commits"
msgid "SearchResults|epic"
msgid_plural "SearchResults|epics"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "epic"
+msgstr[1] "epics"
msgid "SearchResults|issue"
msgid_plural "SearchResults|issues"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "problemstilling"
+msgstr[1] "problemstillinger"
msgid "SearchResults|merge request"
msgid_plural "SearchResults|merge requests"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "sammenlægningsanmodning"
+msgstr[1] "sammenlægningsanmodninger"
msgid "SearchResults|milestone"
msgid_plural "SearchResults|milestones"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "milepæl"
+msgstr[1] "milepæle"
msgid "SearchResults|project"
msgid_plural "SearchResults|projects"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "projekt"
+msgstr[1] "projekter"
msgid "SearchResults|snippet"
msgid_plural "SearchResults|snippets"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "uddrag"
+msgstr[1] "uddrag"
msgid "SearchResults|user"
msgid_plural "SearchResults|users"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "bruger"
+msgstr[1] "brugere"
msgid "SearchResults|wiki result"
msgid_plural "SearchResults|wiki results"
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29284,28 +29500,28 @@ msgid "Seats usage data is updated every day at 12:00pm UTC"
msgstr ""
msgid "Secondary"
-msgstr ""
+msgstr "Sekundær"
msgid "Secondary email:"
-msgstr ""
+msgstr "Sekundære e-mail:"
msgid "Seconds"
-msgstr ""
+msgstr "Sekunder"
msgid "Secret"
-msgstr ""
+msgstr "Hemmelig"
msgid "Secret Detection"
msgstr ""
msgid "Secret token"
-msgstr ""
+msgstr "Hemmelig token"
msgid "Secure token that identifies an external storage request."
msgstr ""
msgid "Security"
-msgstr ""
+msgstr "Sikkerhed"
msgid "Security & Compliance"
msgstr ""
@@ -29314,13 +29530,13 @@ msgid "Security Configuration"
msgstr ""
msgid "Security Dashboard"
-msgstr ""
+msgstr "Sikkerhedsbetjeningspanel"
msgid "Security dashboard"
-msgstr ""
+msgstr "Sikkerhedsbetjeningspanel"
msgid "Security navigation"
-msgstr ""
+msgstr "Sikkerhedsnavigation"
msgid "Security report is out of date. Please update your branch with the latest changes from the target branch (%{targetBranchName})"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29383,7 +29599,7 @@ msgid "SecurityConfiguration|An error occurred while creating the merge request.
msgstr ""
msgid "SecurityConfiguration|Available with Ultimate"
-msgstr ""
+msgstr "Tilgængelig med Ultimate"
msgid "SecurityConfiguration|By default, all analyzers are applied in order to cover all languages across your project, and only run if the language is detected in the Merge Request."
msgstr ""
@@ -29419,13 +29635,13 @@ msgid "SecurityConfiguration|Customize common SAST settings to suit your require
msgstr ""
msgid "SecurityConfiguration|Enable %{feature}"
-msgstr ""
+msgstr "Aktivér %{feature}"
msgid "SecurityConfiguration|Enable Auto DevOps"
-msgstr ""
+msgstr "Aktivér Auto DevOps"
msgid "SecurityConfiguration|Enabled"
-msgstr ""
+msgstr "Aktiveret"
msgid "SecurityConfiguration|High-level vulnerability statistics across projects and groups"
msgstr ""
@@ -29443,7 +29659,7 @@ msgid "SecurityConfiguration|More scan types, including Container Scanning, DAST
msgstr ""
msgid "SecurityConfiguration|Not enabled"
-msgstr ""
+msgstr "Ikke aktiveret"
msgid "SecurityConfiguration|Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
msgstr ""
@@ -29461,7 +29677,7 @@ msgid "SecurityConfiguration|SAST Configuration"
msgstr ""
msgid "SecurityConfiguration|Secure your project"
-msgstr ""
+msgstr "Sikr dit projekt"
msgid "SecurityConfiguration|Security testing"
msgstr ""
@@ -29470,7 +29686,7 @@ msgid "SecurityConfiguration|The status of the tools only applies to the default
msgstr ""
msgid "SecurityConfiguration|Upgrade or start a free trial"
-msgstr ""
+msgstr "Opgrader eller start en gratis prøveperiode"
msgid "SecurityConfiguration|Using custom settings. You won't receive automatic updates on this variable. %{anchorStart}Restore to default%{anchorEnd}"
msgstr ""
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
+msgstr ""
+
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select security project"
+msgstr "Vælg sikkerhedsprojekt"
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrhestration|No rules defined - policy will not run."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr "Miljøer"
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29539,10 +29824,10 @@ msgid "SecurityReports|Add or remove projects to monitor in the security area. P
msgstr ""
msgid "SecurityReports|Add projects"
-msgstr ""
+msgstr "Tilføj projekter"
msgid "SecurityReports|All activity"
-msgstr ""
+msgstr "Al aktivitet"
msgid "SecurityReports|Although it's rare to have no vulnerabilities, it can happen. Check your settings to make sure you've set up your dashboard correctly."
msgstr ""
@@ -29551,7 +29836,7 @@ msgid "SecurityReports|At GitLab, we're all about iteration and feedback. That's
msgstr ""
msgid "SecurityReports|Change status"
-msgstr ""
+msgstr "Ændr status"
msgid "SecurityReports|Comment added to '%{vulnerabilityName}'"
msgstr ""
@@ -29565,14 +29850,11 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
-msgstr ""
+msgstr "Opret Jira-problemstilling"
msgid "SecurityReports|Create issue"
-msgstr ""
+msgstr "Opret problemstilling"
msgid "SecurityReports|Dismiss vulnerability"
msgstr ""
@@ -29584,7 +29866,7 @@ msgid "SecurityReports|Dismissed '%{vulnerabilityName}'. Turn off the hide dismi
msgstr ""
msgid "SecurityReports|Download %{artifactName}"
-msgstr ""
+msgstr "Download %{artifactName}"
msgid "SecurityReports|Download results"
msgstr ""
@@ -29647,10 +29929,10 @@ msgid "SecurityReports|Monitored projects"
msgstr ""
msgid "SecurityReports|More info"
-msgstr ""
+msgstr "Mere information"
msgid "SecurityReports|No activity"
-msgstr ""
+msgstr "Ingen aktivitet"
msgid "SecurityReports|No longer detected"
msgstr ""
@@ -29665,25 +29947,22 @@ msgid "SecurityReports|Oops, something doesn't seem right."
msgstr ""
msgid "SecurityReports|Project"
-msgstr ""
+msgstr "Projekt"
msgid "SecurityReports|Project was not found or you do not have permission to add this project to Security Dashboards."
msgstr ""
msgid "SecurityReports|Projects added"
-msgstr ""
+msgstr "Projekter tilføjet"
msgid "SecurityReports|Remove project from dashboard"
-msgstr ""
+msgstr "Fjern projekt fra betjeningspanel"
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
-msgstr ""
+msgstr "Sikkerhedsbetjeningspanel"
msgid "SecurityReports|Security reports can only be accessed by authorized users."
msgstr ""
@@ -29698,10 +29977,10 @@ msgid "SecurityReports|Select a project to add by using the project search field
msgstr ""
msgid "SecurityReports|Set status"
-msgstr ""
+msgstr "Indstil status"
msgid "SecurityReports|Severity"
-msgstr ""
+msgstr "Alvorlighed"
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -29710,7 +29989,7 @@ msgid "SecurityReports|Sorry, your filter produced no results"
msgstr ""
msgid "SecurityReports|Status"
-msgstr ""
+msgstr "Status"
msgid "SecurityReports|Take survey"
msgstr ""
@@ -29719,16 +29998,16 @@ msgid "SecurityReports|The security reports below contain one or more vulnerabil
msgstr ""
msgid "SecurityReports|There was an error adding the comment."
-msgstr ""
+msgstr "Der opstod en fejl ved tilføjelse af kommentaren."
msgid "SecurityReports|There was an error creating the issue."
-msgstr ""
+msgstr "Der opstod en fejl ved oprettelse af problemstillingen."
msgid "SecurityReports|There was an error creating the merge request."
-msgstr ""
+msgstr "Der opstod en fejl ved oprettelse af sammenlægningsanmodningen."
msgid "SecurityReports|There was an error deleting the comment."
-msgstr ""
+msgstr "Der opstod en fejl ved sletning af kommentaren."
msgid "SecurityReports|There was an error dismissing the vulnerabilities."
msgstr ""
@@ -29743,11 +30022,14 @@ msgid "SecurityReports|There was an error reverting this dismissal."
msgstr ""
msgid "SecurityReports|There was an error while generating the report."
-msgstr ""
+msgstr "Der opstod en fejl under generering af rapporten."
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -29761,7 +30043,7 @@ msgid "SecurityReports|Upgrade to interact, track and shift left with vulnerabil
msgstr ""
msgid "SecurityReports|Upgrade to manage vulnerabilities"
-msgstr ""
+msgstr "Opgrader for at håndtere sårbarheder"
msgid "SecurityReports|Vulnerability Management feature survey"
msgstr ""
@@ -29773,7 +30055,7 @@ msgid "SecurityReports|While it's rare to have no vulnerabilities for your pipel
msgstr ""
msgid "SecurityReports|With issues"
-msgstr ""
+msgstr "Med problemstillinger"
msgid "SecurityReports|You do not have sufficient permissions to access this report"
msgstr ""
@@ -29788,7 +30070,7 @@ msgid "See example DevOps Score page in our documentation."
msgstr ""
msgid "See metrics"
-msgstr ""
+msgstr "Se målinger"
msgid "See our website for help"
msgstr ""
@@ -29806,22 +30088,22 @@ msgid "See vulnerability %{vulnerability_link} for any Solution details."
msgstr ""
msgid "Select"
-msgstr ""
+msgstr "Vælg"
msgid "Select Archive Format"
-msgstr ""
+msgstr "Vælg arkivformat"
msgid "Select Git revision"
-msgstr ""
+msgstr "Vælg Git-revision"
msgid "Select GitLab project to link with your Slack team"
msgstr ""
msgid "Select Page"
-msgstr ""
+msgstr "Vælg side"
msgid "Select a branch"
-msgstr ""
+msgstr "Vælg en gren"
msgid "Select a file from the left sidebar to begin editing. Afterwards, you'll be able to commit your changes."
msgstr ""
@@ -29830,169 +30112,169 @@ msgid "Select a framework that applies to this project. %{linkStart}How are thes
msgstr ""
msgid "Select a group to invite"
-msgstr ""
+msgstr "Vælg en gruppe som skal inviteres"
msgid "Select a label"
-msgstr ""
+msgstr "Vælg en etiket"
msgid "Select a milestone"
-msgstr ""
+msgstr "Vælg en milepæl"
msgid "Select a new namespace"
-msgstr ""
+msgstr "Vælg et nyt navnerum"
msgid "Select a project"
-msgstr ""
+msgstr "Vælg et projekt"
msgid "Select a project to read Insights configuration file"
msgstr ""
msgid "Select a reason"
-msgstr ""
+msgstr "Vælg en årsag"
msgid "Select a repository"
-msgstr ""
+msgstr "Vælg et depot"
msgid "Select a role"
-msgstr ""
+msgstr "Vælg en rolle"
msgid "Select a shared template repository for all projects on this instance."
msgstr ""
msgid "Select a template repository"
-msgstr ""
+msgstr "Vælg et skabelondepot"
msgid "Select a template type"
-msgstr ""
+msgstr "Vælg en skabelontype"
msgid "Select a time zone"
-msgstr ""
+msgstr "Vælg en tidszone"
msgid "Select a timezone"
-msgstr ""
+msgstr "Vælg en tidszone"
msgid "Select all"
-msgstr ""
+msgstr "Vælg alle"
msgid "Select an assignee"
msgstr ""
msgid "Select an iteration"
-msgstr ""
+msgstr "Vælg et gennemløb"
msgid "Select assignee"
msgstr ""
msgid "Select branch"
-msgstr ""
+msgstr "Vælg gren"
msgid "Select due date"
-msgstr ""
+msgstr "Vælg forfaldsdato"
msgid "Select epic"
-msgstr ""
+msgstr "Vælg epic"
msgid "Select file"
-msgstr ""
+msgstr "Vælg fil"
msgid "Select group"
-msgstr ""
+msgstr "Vælg gruppe"
msgid "Select group or project"
-msgstr ""
+msgstr "Vælg gruppe eller projekt"
msgid "Select groups to replicate"
msgstr ""
msgid "Select health status"
-msgstr ""
+msgstr "Vælg helbredsstatus"
msgid "Select iteration"
-msgstr ""
+msgstr "Vælg gennemløb"
msgid "Select label"
-msgstr ""
+msgstr "Vælg etiket"
msgid "Select labels"
-msgstr ""
+msgstr "Vælg etiketter"
msgid "Select merge moment"
msgstr ""
msgid "Select milestone"
-msgstr ""
+msgstr "Vælg milepæl"
msgid "Select private project"
-msgstr ""
+msgstr "Vælg privat projekt"
msgid "Select project"
-msgstr ""
+msgstr "Vælg projekt"
msgid "Select project and zone to choose machine type"
msgstr ""
msgid "Select project to choose zone"
-msgstr ""
+msgstr "Vælg projekt for at vælge zone"
msgid "Select projects"
-msgstr ""
+msgstr "Vælg projekter"
msgid "Select reviewer(s)"
-msgstr ""
+msgstr "Vælg kontrollanter"
msgid "Select shards to replicate"
msgstr ""
msgid "Select source"
-msgstr ""
+msgstr "Vælg kilde"
msgid "Select source branch"
msgstr ""
msgid "Select start date"
-msgstr ""
+msgstr "Vælg startdato"
msgid "Select status"
-msgstr ""
+msgstr "Vælg status"
msgid "Select strategy activation method"
msgstr ""
msgid "Select subgroup"
-msgstr ""
+msgstr "Vælg undergruppe"
msgid "Select subscription"
-msgstr ""
+msgstr "Vælg abonnement"
msgid "Select target branch"
-msgstr ""
+msgstr "Vælg målgren"
msgid "Select timezone"
-msgstr ""
+msgstr "Vælg tidszone"
msgid "Select type"
-msgstr ""
+msgstr "Vælg type"
msgid "Selected"
-msgstr ""
+msgstr "Valgte"
msgid "Selected commits"
-msgstr ""
+msgstr "Valgte commits"
msgid "Selected levels cannot be used by non-admin users for groups, projects or snippets. If the public level is restricted, user profiles are only visible to logged in users."
msgstr ""
msgid "Selected projects"
-msgstr ""
+msgstr "Valgte projekter"
msgid "Selecting a GitLab user will add a link to the GitLab user in the descriptions of issues and comments (e.g. \"By %{link_open}@johnsmith%{link_close}\"). It will also associate and/or assign these issues and comments with the selected user."
-msgstr ""
+msgstr "Valg af en GitLab-bruger vil tilføje et link til GitLab-brugeren i beskrivelserne af problemstillinger og kommentarer (f.eks. \"Af %{link_open}@ronnierev%{link_close}\"). Det vil også tilknytte og/eller tildele problemstillingerne og kommentarerne med den valgte bruger."
msgid "Selective synchronization"
msgstr ""
msgid "Self monitoring"
-msgstr ""
+msgstr "Selvovervågning"
msgid "Self monitoring project does not exist"
msgstr ""
@@ -30013,13 +30295,13 @@ msgid "SelfMonitoring|Activate self monitoring to create a project to use to mon
msgstr ""
msgid "SelfMonitoring|Deactivate self monitoring?"
-msgstr ""
+msgstr "Deaktivér selvovervågning?"
msgid "SelfMonitoring|Deactivating self monitoring deletes the self monitoring project. Are you sure you want to deactivate self monitoring and delete the project?"
msgstr ""
msgid "SelfMonitoring|Self monitoring"
-msgstr ""
+msgstr "Selvovervågning"
msgid "SelfMonitoring|Self monitoring is active. Use the %{projectLinkStart}self monitoring project%{projectLinkEnd} to monitor the health of your instance."
msgstr ""
@@ -30031,16 +30313,16 @@ msgid "SelfMonitoring|Self monitoring project successfully deleted."
msgstr ""
msgid "Send"
-msgstr ""
+msgstr "Send"
msgid "Send a single email notification to Owners and Maintainers for new alerts."
msgstr ""
msgid "Send confirmation email"
-msgstr ""
+msgstr "Send bekræftelses e-mail"
msgid "Send email"
-msgstr ""
+msgstr "Send e-mail"
msgid "Send email in multipart format (HTML and plain text). Uncheck to send email messages in plain text only."
msgstr ""
@@ -30052,7 +30334,7 @@ msgid "Send emails to help guide new users through the onboarding process."
msgstr ""
msgid "Send message"
-msgstr ""
+msgstr "Send meddelelse"
msgid "Send notifications about project events to Mattermost channels."
msgstr ""
@@ -30064,7 +30346,7 @@ msgid "Send notifications about project events to a Discord channel. %{docs_link
msgstr ""
msgid "Send report"
-msgstr ""
+msgstr "Send rapport"
msgid "Send service data"
msgstr ""
@@ -30073,16 +30355,16 @@ msgid "Sentry API URL"
msgstr ""
msgid "Sentry event"
-msgstr ""
+msgstr "Sentry-begivenhed"
msgid "Sep"
-msgstr ""
+msgstr "Sep."
msgid "Separate topics with commas."
-msgstr ""
+msgstr "Adskil emner med kommaer."
msgid "September"
-msgstr ""
+msgstr "September"
msgid "SeriesFinalConjunction|and"
msgstr ""
@@ -30091,25 +30373,25 @@ msgid "Serve repository static objects (for example, archives and blobs) from ex
msgstr ""
msgid "Server (optional)"
-msgstr ""
+msgstr "Server (valgfrit)"
msgid "Server supports batch API only, please update your Git LFS client to version 1.0.1 and up."
msgstr ""
msgid "Server version"
-msgstr ""
+msgstr "Serverversion"
msgid "Serverless"
-msgstr ""
+msgstr "Serverfri"
msgid "Serverless domain"
msgstr ""
msgid "Serverless platform"
-msgstr ""
+msgstr "Serverfri platform"
msgid "ServerlessDetails|Configure cluster."
-msgstr ""
+msgstr "Konfigurer klynge."
msgid "ServerlessDetails|Function invocation metrics require the Prometheus cluster integration."
msgstr ""
@@ -30124,7 +30406,7 @@ msgid "ServerlessDetails|Kubernetes Pods"
msgstr ""
msgid "ServerlessDetails|More information"
-msgstr ""
+msgstr "Mere information"
msgid "ServerlessDetails|No pods loaded at this time."
msgstr ""
@@ -30139,10 +30421,10 @@ msgid "ServerlessDetails|pods in use"
msgstr ""
msgid "ServerlessURL|Copy URL"
-msgstr ""
+msgstr "Kopiér URL"
msgid "Serverless|Getting started with serverless"
-msgstr ""
+msgstr "Kom godt i gang med serverfri"
msgid "Serverless|Help shape the future of Serverless at GitLab"
msgstr ""
@@ -30169,7 +30451,7 @@ msgid "Serverless|The functions listed in the %{startTag}serverless.yml%{endTag}
msgstr ""
msgid "Serverless|There is currently no function data available from Knative. This could be for a variety of reasons including:"
-msgstr ""
+msgstr "Der er på nuværende tidspunkt ingen funktionsdata tilgængelige fra Knative. Det kan der være flere årsager til, herunder:"
msgid "Serverless|We are continually striving to improve our Serverless functionality. As a Knative user, we would love to hear how we can make this experience better for you. Sign up for GitLab First Look today and we will be in touch shortly."
msgstr ""
@@ -30181,10 +30463,10 @@ msgid "Serverless|Your repository does not have a corresponding %{startTag}serve
msgstr ""
msgid "Service"
-msgstr ""
+msgstr "Tjeneste"
msgid "Service Desk"
-msgstr ""
+msgstr "Service Desk"
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
@@ -30196,7 +30478,7 @@ msgid "Service ping is disabled in your configuration file, and cannot be enable
msgstr ""
msgid "ServiceDesk|Enable Service Desk"
-msgstr ""
+msgstr "Aktivér Service Desk"
msgid "ServiceDesk|For help setting up the Service Desk for your instance, please contact an administrator."
msgstr ""
@@ -30208,13 +30490,13 @@ msgid "ServiceDesk|Issues created from Service Desk emails will appear here. Eac
msgstr ""
msgid "ServiceDesk|Service Desk is enabled but not yet active"
-msgstr ""
+msgstr "Service Desk er aktiveret men endnu ikke aktiv"
msgid "ServiceDesk|Service Desk is not enabled"
-msgstr ""
+msgstr "Service Desk er ikke aktiveret"
msgid "ServiceDesk|Service Desk is not supported"
-msgstr ""
+msgstr "Service Desk understøttes ikke"
msgid "ServiceDesk|To activate Service Desk on this instance, an instance administrator must first set up incoming email."
msgstr ""
@@ -30241,7 +30523,7 @@ msgid "ServicePing|Turn on service ping to review instance-level analytics."
msgstr ""
msgid "Session ID"
-msgstr ""
+msgstr "Session-id"
msgid "Session duration (minutes)"
msgstr ""
@@ -30268,22 +30550,22 @@ msgid "Set default and restrict visibility levels. Configure import sources and
msgstr ""
msgid "Set due date"
-msgstr ""
+msgstr "Indstil forfaldsdato"
msgid "Set iteration"
-msgstr ""
+msgstr "Indstil gennemløb"
msgid "Set limit to 0 to allow any file size."
-msgstr ""
+msgstr "Indstil grænse til 0 for at tillade alle filstørrelser."
msgid "Set max session time for web terminal."
msgstr ""
msgid "Set milestone"
-msgstr ""
+msgstr "Indstil milepæl"
msgid "Set new password"
-msgstr ""
+msgstr "Indstil ny adgangskode"
msgid "Set notification email for abuse reports."
msgstr ""
@@ -30295,7 +30577,7 @@ msgid "Set projects and maximum size limits, session duration, user options, and
msgstr ""
msgid "Set severity"
-msgstr ""
+msgstr "Indstil alvorlighed"
msgid "Set sign-in restrictions for all users."
msgstr ""
@@ -30304,16 +30586,16 @@ msgid "Set size limits for displaying diffs in the browser."
msgstr ""
msgid "Set target branch"
-msgstr ""
+msgstr "Indstil målgren"
msgid "Set target branch to %{branch_name}."
-msgstr ""
+msgstr "Indstil målgren til %{branch_name}."
msgid "Set the default branch for this project. All merge requests and commits are made against this branch unless you specify a different one."
msgstr ""
msgid "Set the due date to %{due_date}."
-msgstr ""
+msgstr "Indstil forfaldsdatoen til %{due_date}."
msgid "Set the iteration to %{iteration_reference}."
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30331,10 +30613,10 @@ msgid "Set time estimate to %{time_estimate}."
msgstr ""
msgid "Set up CI/CD"
-msgstr ""
+msgstr "Opsæt CI/CD"
msgid "Set up Jira Integration"
-msgstr ""
+msgstr "Opsæt Jira-integrering"
msgid "Set up a %{type} Runner for a project"
msgstr ""
@@ -30349,67 +30631,67 @@ msgid "Set up assertions/attributes/claims (email, first_name, last_name) and Na
msgstr ""
msgid "Set up new device"
-msgstr ""
+msgstr "Opsæt ny enhed"
msgid "Set up new password"
-msgstr ""
+msgstr "Opsæt ny adgangskode"
msgid "Set up shared runner availability"
msgstr ""
msgid "Set up your project to automatically push and/or pull changes to/from another repository. Branches, tags, and commits will be synced automatically."
-msgstr ""
+msgstr "Opsæt dit projekt til automatisk at bruge push og/eller pull på ændringer til/fra et andet depot. Grene, mærkater og commits synkroniseres automatisk."
msgid "Set verification limit and frequency."
msgstr ""
msgid "Set weight"
-msgstr ""
+msgstr "Indstil vægt"
msgid "Set weight to %{weight}."
-msgstr ""
+msgstr "Indstil vægt til %{weight}."
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
msgstr ""
msgid "SetStatusModal|A busy indicator is shown next to your name and avatar."
-msgstr ""
+msgstr "En optaget-indikator vises ved siden af dit navn og avatar."
msgid "SetStatusModal|Add status emoji"
-msgstr ""
+msgstr "Tilføj statusemoji"
msgid "SetStatusModal|Busy"
-msgstr ""
+msgstr "Optaget"
msgid "SetStatusModal|Clear status"
-msgstr ""
+msgstr "Ryd status"
msgid "SetStatusModal|Clear status after"
-msgstr ""
+msgstr "Ryd status efter"
msgid "SetStatusModal|Edit status"
-msgstr ""
+msgstr "Rediger status"
msgid "SetStatusModal|Remove status"
-msgstr ""
+msgstr "Fjern status"
msgid "SetStatusModal|Set a status"
-msgstr ""
+msgstr "Indstil en status"
msgid "SetStatusModal|Set status"
-msgstr ""
+msgstr "Indstil status"
msgid "SetStatusModal|Sorry, we weren't able to set your status. Please try again later."
msgstr ""
msgid "SetStatusModal|Status updated"
-msgstr ""
+msgstr "Status opdateret"
msgid "SetStatusModal|What's your status?"
-msgstr ""
+msgstr "Hvad er din status?"
msgid "SetStatusModal|Your status resets on %{date}."
msgstr ""
@@ -30421,7 +30703,7 @@ msgid "Sets target branch to %{branch_name}."
msgstr ""
msgid "Sets the due date to %{due_date}."
-msgstr ""
+msgstr "Indstiller forfaldsdatoen til %{due_date}."
msgid "Sets the iteration to %{iteration_reference}."
msgstr ""
@@ -30430,16 +30712,16 @@ msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
msgid "Sets the severity"
-msgstr ""
+msgstr "Indstiller alvorligheden"
msgid "Sets time estimate to %{time_estimate}."
msgstr ""
msgid "Sets weight to %{weight}."
-msgstr ""
+msgstr "Indstiller vægt til %{weight}."
msgid "Setting"
-msgstr ""
+msgstr "Indstilling"
msgid "Setting enforced"
msgstr ""
@@ -30448,34 +30730,34 @@ msgid "Setting this to 0 means using the system default timeout value."
msgstr ""
msgid "Settings"
-msgstr ""
+msgstr "Indstillinger"
msgid "Settings|Unable to load the merge request options settings. Try reloading the page."
msgstr ""
msgid "Setup"
-msgstr ""
+msgstr "Opsætning"
msgid "Severity"
-msgstr ""
+msgstr "Alvorlighed"
msgid "Severity updated to %{severity}."
-msgstr ""
+msgstr "Alvorlighed opdateret til %{severity}."
msgid "SeverityWidget|Severity"
-msgstr ""
+msgstr "Alvorlighed"
msgid "SeverityWidget|Severity: %{severity}"
-msgstr ""
+msgstr "Alvorlighed: %{severity}"
msgid "SeverityWidget|There was an error while updating severity."
-msgstr ""
+msgstr "Der opstod en fejl under opdatering af alvorlighed."
msgid "Shards to synchronize"
msgstr ""
msgid "Share"
-msgstr ""
+msgstr "Del"
msgid "Share the %{strong_open}GitLab single sign-on URL%{strong_close} with members so they can sign in to your group through your identity provider"
msgstr ""
@@ -30484,7 +30766,7 @@ msgid "Shared Runners"
msgstr ""
msgid "Shared projects"
-msgstr ""
+msgstr "Delte projekter"
msgid "Shared runners"
msgstr ""
@@ -30517,37 +30799,37 @@ msgid "Should you ever lose your phone or access to your one time password secre
msgstr ""
msgid "Show Pipeline ID"
-msgstr ""
+msgstr "Vis pipeline-id"
msgid "Show Pipeline IID"
-msgstr ""
+msgstr "Vis pipeline-iid"
msgid "Show all activity"
-msgstr ""
+msgstr "Vis al aktivitet"
msgid "Show all issues."
-msgstr ""
+msgstr "Vis alle problemstillinger."
msgid "Show all test cases."
msgstr ""
msgid "Show archived projects"
-msgstr ""
+msgstr "Vis arkiverede projekter"
msgid "Show archived projects only"
-msgstr ""
+msgstr "Vis kun arkiverede projekter"
msgid "Show command"
-msgstr ""
+msgstr "Vis kommando"
msgid "Show comments"
-msgstr ""
+msgstr "Vis kommentarer"
msgid "Show comments on this file"
-msgstr ""
+msgstr "Vis kommentarer til filen"
msgid "Show comments only"
-msgstr ""
+msgstr "Vis kun kommentarer"
msgid "Show commit description"
msgstr ""
@@ -30556,37 +30838,34 @@ msgid "Show complete raw log"
msgstr ""
msgid "Show details"
-msgstr ""
+msgstr "Vis detaljer"
msgid "Show file browser"
-msgstr ""
+msgstr "Vis filvælger"
msgid "Show file contents"
msgstr ""
msgid "Show labels"
-msgstr ""
+msgstr "Vis etiketter"
msgid "Show latest version"
-msgstr ""
-
-msgid "Show links anyways"
-msgstr ""
+msgstr "Vis seneste version"
msgid "Show list"
-msgstr ""
+msgstr "Vis liste"
msgid "Show me advanced features"
msgstr ""
msgid "Show me how to add a pipeline"
-msgstr ""
+msgstr "Vis mig hvordan en pipeline tilføjes"
msgid "Show me the basics"
-msgstr ""
+msgstr "Vis mig det grundlæggende"
msgid "Show one file at a time"
-msgstr ""
+msgstr "Vis én fil ad gangen"
msgid "Show parent pages"
msgstr ""
@@ -30595,29 +30874,29 @@ msgid "Show parent subgroups"
msgstr ""
msgid "Show the Closed list"
-msgstr ""
+msgstr "Vis den lukkede liste"
msgid "Show the Open list"
-msgstr ""
+msgstr "Vis den åbne liste"
msgid "Show whitespace changes"
msgstr ""
msgid "Showing %d event"
msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Viser %d begivenhed"
+msgstr[1] "Viser %d begivenheder"
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
msgid "Showing %{count} of %{total} projects"
-msgstr ""
+msgstr "Viser %{count} af %{total} projekter"
msgid "Showing %{count} project"
msgid_plural "Showing %{count} projects"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Viser %{count} projekt"
+msgstr[1] "Viser %{count} projekter"
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -30629,10 +30908,10 @@ msgid "Showing %{pageSize} of %{total} issues"
msgstr ""
msgid "Showing all epics"
-msgstr ""
+msgstr "Viser alle epics"
msgid "Showing all issues"
-msgstr ""
+msgstr "Viser alle problemstillinger"
msgid "Showing data for workflow items created in this date range. Date range cannot exceed %{maxDateRange} days."
msgstr ""
@@ -30644,16 +30923,16 @@ msgid "Showing last %{size} of log -"
msgstr ""
msgid "Showing latest version"
-msgstr ""
+msgstr "Viser seneste version"
msgid "Showing version #%{versionNumber}"
-msgstr ""
+msgstr "Viser version #%{versionNumber}"
msgid "Side-by-side"
-msgstr ""
+msgstr "Side om side"
msgid "Sidebar|%{name}: %{value}"
-msgstr ""
+msgstr "%{name}: %{value}"
msgid "Sidebar|Assign health status"
msgstr ""
@@ -30662,22 +30941,22 @@ msgid "Sidebar|Health status"
msgstr ""
msgid "Sidebar|No status"
-msgstr ""
+msgstr "Ingen status"
msgid "Sidebar|None"
-msgstr ""
+msgstr "Ingen"
msgid "Sidebar|Only numeral characters allowed"
msgstr ""
msgid "Sidebar|Weight"
-msgstr ""
+msgstr "Vægt"
msgid "Sign in"
-msgstr ""
+msgstr "Log ind"
msgid "Sign in / Register"
-msgstr ""
+msgstr "Log ind/tilmeld"
msgid "Sign in as a user with the matching email address, add the email to this account, or sign-up for a new account using the matching email."
msgstr ""
@@ -30689,16 +30968,16 @@ msgid "Sign in to \"%{group_name}\""
msgstr ""
msgid "Sign in to GitLab"
-msgstr ""
+msgstr "Log ind på GitLab"
msgid "Sign in using smart card"
msgstr ""
msgid "Sign in via 2FA code"
-msgstr ""
+msgstr "Log ind via 2FG-kode"
msgid "Sign in with"
-msgstr ""
+msgstr "Log ind med"
msgid "Sign in with Single Sign-On"
msgstr ""
@@ -30710,13 +30989,13 @@ msgid "Sign in/Sign up pages"
msgstr ""
msgid "Sign out"
-msgstr ""
+msgstr "Log ud"
msgid "Sign out & Register"
msgstr ""
msgid "Sign up"
-msgstr ""
+msgstr "Tilmeld"
msgid "Sign up was successful! Please confirm your email to sign in."
msgstr ""
@@ -30764,7 +31043,7 @@ msgid "SignUp|Username is too short (minimum is %{min_length} characters)."
msgstr ""
msgid "Signed in"
-msgstr ""
+msgstr "logget ind"
msgid "Signed in to GitLab as %{user_link}"
msgstr ""
@@ -30779,7 +31058,7 @@ msgid "Signing in using your %{label} account without a pre-existing GitLab acco
msgstr ""
msgid "Similar issues"
-msgstr ""
+msgstr "Lignende problemstillinger"
msgid "Simulate a pipeline created for the default branch"
msgstr ""
@@ -30794,6 +31073,9 @@ msgid "Site profile not found for given parameters"
msgstr ""
msgid "Size"
+msgstr "Størrelse"
+
+msgid "Size Limits"
msgstr ""
msgid "Size limit per repository (MB)"
@@ -30803,13 +31085,13 @@ msgid "Skip outdated deployment jobs"
msgstr ""
msgid "Skipped"
-msgstr ""
+msgstr "Sprunget over"
msgid "Skipped deployment to"
msgstr ""
msgid "Skype:"
-msgstr ""
+msgstr "Skype:"
msgid "Slack application"
msgstr ""
@@ -30839,46 +31121,46 @@ msgid "Slice multiplier"
msgstr ""
msgid "Smartcard"
-msgstr ""
+msgstr "Smartcard"
msgid "Smartcard authentication failed: client certificate header is missing."
msgstr ""
msgid "Snippets"
-msgstr ""
+msgstr "Uddrag"
msgid "Snippets with non-text files can only be edited via Git."
msgstr ""
msgid "SnippetsEmptyState|Code snippets"
-msgstr ""
+msgstr "Kodeuddrag"
msgid "SnippetsEmptyState|Documentation"
-msgstr ""
+msgstr "Dokumentation"
msgid "SnippetsEmptyState|New snippet"
-msgstr ""
+msgstr "Nyt uddrag"
msgid "SnippetsEmptyState|No snippets found"
-msgstr ""
+msgstr "Ingen uddrag fundet"
msgid "SnippetsEmptyState|Store, share, and embed small pieces of code and text."
msgstr ""
msgid "SnippetsEmptyState|There are no snippets to show."
-msgstr ""
+msgstr "Der er ingen uddrag at vise."
msgid "Snippets|Add another file %{num}/%{total}"
-msgstr ""
+msgstr "Tilføj endnu en fil %{num}/%{total}"
msgid "Snippets|Delete file"
-msgstr ""
+msgstr "Slet fil"
msgid "Snippets|Description (optional)"
-msgstr ""
+msgstr "Beskrivelse (valgfrit)"
msgid "Snippets|Files"
-msgstr ""
+msgstr "Filer"
msgid "Snippets|Give your file a name to add code highlighting, e.g. example.rb for Ruby"
msgstr ""
@@ -30887,13 +31169,13 @@ msgid "Snippets|Optionally add a description about what your snippet does or how
msgstr ""
msgid "Snowplow"
-msgstr ""
+msgstr "Snowplow"
msgid "Solution"
-msgstr ""
+msgstr "Løsning"
msgid "Some changes are not shown"
-msgstr ""
+msgstr "Nogle ændringer vises ikke"
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
@@ -30920,19 +31202,19 @@ msgid "Someone, hopefully you, has requested to reset the password for your GitL
msgstr ""
msgid "Something went wrong"
-msgstr ""
+msgstr "Noget gik galt"
msgid "Something went wrong on our end"
-msgstr ""
+msgstr "Noget gik galt i vores ende"
msgid "Something went wrong on our end."
-msgstr ""
+msgstr "Noget gik galt i vores ende."
msgid "Something went wrong on our end. Please try again!"
-msgstr ""
+msgstr "Noget gik galt i vores ende. Prøv venligst igen!"
msgid "Something went wrong on our end. Please try again."
-msgstr ""
+msgstr "Noget gik galt i vores ende. Prøv venligst igen."
msgid "Something went wrong trying to change the locked state of this %{issuableDisplayName}"
msgstr ""
@@ -30986,31 +31268,31 @@ msgid "Something went wrong while fetching %{listType} list"
msgstr ""
msgid "Something went wrong while fetching branches"
-msgstr ""
+msgstr "Noget gik galt under hentning af grene"
msgid "Something went wrong while fetching comments. Please try again."
-msgstr ""
+msgstr "Noget gik galt under hentning af kommentarer. Prøv venligst igen."
msgid "Something went wrong while fetching description changes. Please try again."
-msgstr ""
+msgstr "Noget gik galt under hentning af beskrivelsesændringer. Prøv venligst igen."
msgid "Something went wrong while fetching details"
-msgstr ""
+msgstr "Noget gik galt under hentning af detaljer"
msgid "Something went wrong while fetching group member contributions"
msgstr ""
msgid "Something went wrong while fetching latest comments."
-msgstr ""
+msgstr "Noget gik galt under hentning af seneste kommentarer."
msgid "Something went wrong while fetching projects"
-msgstr ""
+msgstr "Noget gik galt under hentning af projekter"
msgid "Something went wrong while fetching projects."
-msgstr ""
+msgstr "Noget gik galt under hentning af projekter."
msgid "Something went wrong while fetching related merge requests."
-msgstr ""
+msgstr "Noget gik galt under hentning af relaterede sammenlægningsanmodninger."
msgid "Something went wrong while fetching requirements count."
msgstr ""
@@ -31019,34 +31301,34 @@ msgid "Something went wrong while fetching requirements list."
msgstr ""
msgid "Something went wrong while fetching source branches."
-msgstr ""
+msgstr "Noget gik galt under hentning af kildegrene."
msgid "Something went wrong while fetching the environments for this merge request. Please try again."
-msgstr ""
+msgstr "Noget gik galt under hentning af miljøerne for sammenlægningsanmodningen. Prøv venligst igen."
msgid "Something went wrong while fetching the package."
-msgstr ""
+msgstr "Noget gik galt under hentning af pakken."
msgid "Something went wrong while fetching the packages list."
-msgstr ""
+msgstr "Noget gik galt under hentning af pakkelisten."
msgid "Something went wrong while initializing the OpenAPI viewer"
msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
-msgstr ""
+msgstr "Noget gik galt under indsættelse af dit billede. Prøv venligst igen."
msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
+msgstr "Noget gik galt under sammenlægning af sammenlægningsanmodningen. Prøv venligst igen."
msgid "Something went wrong while moving issues."
-msgstr ""
+msgstr "Noget gik galt under flytning af problemstillinger."
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
-msgstr ""
+msgstr "Noget gik galt under indhentelse af Let's Encrypt-certifikatet."
msgid "Something went wrong while performing the action."
-msgstr ""
+msgstr "Noget gik galt under udførsel af handlingen."
msgid "Something went wrong while promoting the issue to an epic. Please try again."
msgstr ""
@@ -31055,13 +31337,13 @@ msgid "Something went wrong while reopening a requirement."
msgstr ""
msgid "Something went wrong while reopening the epic. Please try again later."
-msgstr ""
+msgstr "Noget gik galt under genåbning af epicen. Prøv venligst igen senere."
msgid "Something went wrong while reopening the merge request. Please try again later."
-msgstr ""
+msgstr "Noget gik galt under genåbning af sammenlægningsanmodningen. Prøv venligst igen senere."
msgid "Something went wrong while resolving this discussion. Please try again."
-msgstr ""
+msgstr "Noget gik galt under løsning af debatten. Prøv venligst igen."
msgid "Something went wrong while setting %{issuableType} %{dateType} date."
msgstr ""
@@ -31082,43 +31364,43 @@ msgid "Something went wrong while setting %{issuableType} weight."
msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
-msgstr ""
+msgstr "Noget gik galt under stop af miljøet. Prøv venligst igen."
msgid "Something went wrong while updating a requirement."
-msgstr ""
+msgstr "Noget gik galt under opdatering af et krav."
msgid "Something went wrong while updating assignees"
msgstr ""
msgid "Something went wrong while updating your list settings"
-msgstr ""
+msgstr "Noget gik galt under opdatering af dine listeindstillinger"
msgid "Something went wrong with your automatic subscription renewal."
msgstr ""
msgid "Something went wrong, unable to add %{project} to dashboard"
-msgstr ""
+msgstr "Noget gik galt, kan ikke tilføje %{project} til betjeningspanel"
msgid "Something went wrong, unable to add projects to dashboard"
-msgstr ""
+msgstr "Noget gik galt, kan ikke tilføje projekter til betjeningspanel"
msgid "Something went wrong, unable to delete project"
-msgstr ""
+msgstr "Noget gik galt, kan ikke slette projekt"
msgid "Something went wrong, unable to get projects"
-msgstr ""
+msgstr "Noget gik galt, kan ikke hente projekter"
msgid "Something went wrong, unable to search projects"
msgstr ""
msgid "Something went wrong. Please try again later"
-msgstr ""
+msgstr "Noget gik galt. Prøv venligst igen senere"
msgid "Something went wrong. Please try again."
-msgstr ""
+msgstr "Noget gik galt. Prøv venligst igen."
msgid "Something went wrong. Try again later."
-msgstr ""
+msgstr "Noget gik galt. Prøv igen senere."
msgid "Sorry, no epics matched your search"
msgstr ""
@@ -31133,26 +31415,35 @@ msgid "Sorry, your filter produced no results"
msgstr ""
msgid "Sort by"
-msgstr ""
+msgstr "Sortér efter"
msgid "Sort direction"
-msgstr ""
+msgstr "Sorteringsretning"
msgid "Sort direction: Ascending"
-msgstr ""
+msgstr "Sorteringsretning: stigende"
msgid "Sort direction: Descending"
-msgstr ""
+msgstr "Sorteringsretning: faldende"
msgid "SortOptions|Blocking"
msgstr ""
-msgid "SortOptions|Created date"
+msgid "SortOptions|Closed date"
msgstr ""
-msgid "SortOptions|Due date"
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
msgstr ""
+msgid "SortOptions|Created date"
+msgstr "Oprettelsesdato"
+
+msgid "SortOptions|Due date"
+msgstr "Forfaldsdato"
+
msgid "SortOptions|Due later"
msgstr ""
@@ -31166,7 +31457,7 @@ msgid "SortOptions|Label priority"
msgstr ""
msgid "SortOptions|Largest group"
-msgstr ""
+msgstr "Største gruppe"
msgid "SortOptions|Largest repository"
msgstr ""
@@ -31178,13 +31469,13 @@ msgid "SortOptions|Last created"
msgstr ""
msgid "SortOptions|Last updated"
-msgstr ""
+msgstr "Sidst opdateret"
msgid "SortOptions|Least popular"
msgstr ""
msgid "SortOptions|Less weight"
-msgstr ""
+msgstr "Mindre vægt"
msgid "SortOptions|Manual"
msgstr ""
@@ -31196,7 +31487,7 @@ msgid "SortOptions|Merged earlier"
msgstr ""
msgid "SortOptions|Merged recently"
-msgstr ""
+msgstr "Sammenlagt for nyligt"
msgid "SortOptions|Milestone due date"
msgstr ""
@@ -31208,22 +31499,22 @@ msgid "SortOptions|Milestone due soon"
msgstr ""
msgid "SortOptions|More weight"
-msgstr ""
+msgstr "Mere vægt"
msgid "SortOptions|Most popular"
-msgstr ""
+msgstr "Mest populære"
msgid "SortOptions|Most stars"
-msgstr ""
+msgstr "Flest stjerner"
msgid "SortOptions|Name"
-msgstr ""
+msgstr "Navn"
msgid "SortOptions|Name, ascending"
-msgstr ""
+msgstr "Navn, stigende"
msgid "SortOptions|Name, descending"
-msgstr ""
+msgstr "Navn, faldende"
msgid "SortOptions|Oldest created"
msgstr ""
@@ -31232,97 +31523,97 @@ msgid "SortOptions|Oldest last activity"
msgstr ""
msgid "SortOptions|Oldest sign in"
-msgstr ""
+msgstr "Ældste indlogning"
msgid "SortOptions|Oldest starred"
-msgstr ""
+msgstr "Ældste med stjerne"
msgid "SortOptions|Oldest updated"
-msgstr ""
+msgstr "Ældste opdateret"
msgid "SortOptions|Popularity"
-msgstr ""
+msgstr "Popularitet"
msgid "SortOptions|Priority"
-msgstr ""
+msgstr "Prioritet"
msgid "SortOptions|Project"
-msgstr ""
+msgstr "Projekt"
msgid "SortOptions|Recent last activity"
msgstr ""
msgid "SortOptions|Recent sign in"
-msgstr ""
+msgstr "Seneste indlogning"
msgid "SortOptions|Recently starred"
-msgstr ""
+msgstr "Seneste med stjerne"
msgid "SortOptions|Size"
-msgstr ""
+msgstr "Størrelse"
msgid "SortOptions|Sort by:"
-msgstr ""
+msgstr "Sortér efter:"
msgid "SortOptions|Sort direction"
-msgstr ""
+msgstr "Sorteringsretning"
msgid "SortOptions|Stars"
-msgstr ""
+msgstr "Stjerner"
msgid "SortOptions|Start date"
-msgstr ""
+msgstr "Startdato"
msgid "SortOptions|Start later"
-msgstr ""
+msgstr "Start senere"
msgid "SortOptions|Start soon"
-msgstr ""
+msgstr "Start snart"
msgid "SortOptions|Title"
-msgstr ""
+msgstr "Titel"
msgid "SortOptions|Type"
-msgstr ""
+msgstr "Type"
msgid "SortOptions|Version"
-msgstr ""
+msgstr "Version"
msgid "SortOptions|Weight"
-msgstr ""
+msgstr "Vægt"
msgid "Source"
-msgstr ""
+msgstr "Kilde"
msgid "Source (branch or tag)"
msgstr ""
msgid "Source Branch"
-msgstr ""
+msgstr "Kildegren"
msgid "Source Editor instance is required to set up an extension."
msgstr ""
msgid "Source IP"
-msgstr ""
+msgstr "Kilde-IP"
msgid "Source branch"
-msgstr ""
+msgstr "Kildegren"
msgid "Source branch: %{source_branch_open}%{source_branch}%{source_branch_close}"
msgstr ""
msgid "Source code (%{fileExtension})"
-msgstr ""
+msgstr "Kildekode (%{fileExtension})"
msgid "Source is not available"
-msgstr ""
+msgstr "Kilden er ikke tilgængelig"
msgid "Source project cannot be found."
-msgstr ""
+msgstr "Kildeprojektet kan ikke findes."
msgid "Sourcegraph"
-msgstr ""
+msgstr "Sourcegraph"
msgid "SourcegraphAdmin|Block on private and internal projects"
msgstr ""
@@ -31340,10 +31631,10 @@ msgid "SourcegraphAdmin|If checked, only public projects will have code intellig
msgstr ""
msgid "SourcegraphAdmin|More information"
-msgstr ""
+msgstr "Mere information"
msgid "SourcegraphAdmin|Save changes"
-msgstr ""
+msgstr "Gem ændringer"
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
@@ -31352,25 +31643,25 @@ msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
-msgstr ""
+msgstr "Funktionen er eksperimentel og på nuværende tidspunkt begrænset til visse projekter."
msgid "SourcegraphPreferences|This feature is experimental and limited to public projects."
-msgstr ""
+msgstr "Funktionen er eksperimentel og begrænset til offentlige projekter."
msgid "SourcegraphPreferences|This feature is experimental."
-msgstr ""
+msgstr "Funktionen er eksperimentel."
msgid "SourcegraphPreferences|Uses %{linkStart}Sourcegraph.com%{linkEnd}."
-msgstr ""
+msgstr "Bruger %{linkStart}Sourcegraph.com%{linkEnd}."
msgid "SourcegraphPreferences|Uses a custom %{linkStart}Sourcegraph instance%{linkEnd}."
-msgstr ""
+msgstr "Bruger en tilpasset %{linkStart}Sourcegraph-instans%{linkEnd}."
msgid "Spam Check API Key"
msgstr ""
msgid "Spam Logs"
-msgstr ""
+msgstr "Spamlogge"
msgid "Spam and Anti-bot Protection"
msgstr ""
@@ -31409,7 +31700,7 @@ msgid "Stage"
msgstr ""
msgid "Standard"
-msgstr ""
+msgstr "Standard"
msgid "Star a label to make it a priority label. Order the prioritized labels to change their relative priority, by dragging."
msgstr ""
@@ -31424,13 +31715,13 @@ msgid "StarProject|Star"
msgstr ""
msgid "Starred Projects"
-msgstr ""
+msgstr "Projekter med stjerne"
msgid "Starred Projects' Activity"
-msgstr ""
+msgstr "Aktiviteter for projekter med stjerne"
msgid "Starred projects"
-msgstr ""
+msgstr "Projekter med stjerne"
msgid "StarredProjectsEmptyState|Visit a project page and press on a star icon. Then, you can find the project on this page."
msgstr ""
@@ -31442,25 +31733,25 @@ msgid "Starrers"
msgstr ""
msgid "Stars"
-msgstr ""
+msgstr "Stjerner"
msgid "Start Date"
-msgstr ""
+msgstr "Startdato"
msgid "Start Time"
-msgstr ""
+msgstr "Starttidspunkt"
msgid "Start Web Terminal"
msgstr ""
msgid "Start a %{new_merge_request} with these changes"
-msgstr ""
+msgstr "Start en %{new_merge_request} med disse ændringer"
msgid "Start a Free Ultimate Trial"
-msgstr ""
+msgstr "Start en gratis Ultimate-prøveperiode"
msgid "Start a new discussion…"
-msgstr ""
+msgstr "Start en ny debat …"
msgid "Start a new merge request"
msgstr ""
@@ -31469,19 +31760,19 @@ msgid "Start a new merge request with these changes"
msgstr ""
msgid "Start a review"
-msgstr ""
+msgstr "Start en kontrol"
msgid "Start and due date"
-msgstr ""
+msgstr "Start- og forfaldsdato"
msgid "Start by choosing a group to start exploring the merge requests in that group. You can then proceed to filter by projects, labels, milestones and authors."
msgstr ""
msgid "Start cleanup"
-msgstr ""
+msgstr "Start oprydning"
msgid "Start date"
-msgstr ""
+msgstr "Startdato"
msgid "Start merge train"
msgstr ""
@@ -31490,7 +31781,7 @@ msgid "Start merge train when pipeline succeeds"
msgstr ""
msgid "Start search"
-msgstr ""
+msgstr "Start søgning"
msgid "Start thread"
msgstr ""
@@ -31502,16 +31793,16 @@ msgid "Start thread & reopen %{noteable_name}"
msgstr ""
msgid "Start your Free Ultimate Trial"
-msgstr ""
+msgstr "Start din gratis Ultimate-prøveperiode"
msgid "Start your free trial"
-msgstr ""
+msgstr "Start din gratis prøveperiode"
msgid "Start your trial"
-msgstr ""
+msgstr "Start din prøveperiode"
msgid "Started"
-msgstr ""
+msgstr "Startet"
msgid "Started %{startsIn}"
msgstr ""
@@ -31520,19 +31811,19 @@ msgid "Started asynchronous removal of all repository check states."
msgstr ""
msgid "Starting..."
-msgstr ""
+msgstr "Starter ..."
msgid "Starts"
msgstr ""
msgid "Starts %{startsIn}"
-msgstr ""
+msgstr "Starter %{startsIn}"
msgid "Starts at (UTC)"
msgstr ""
msgid "Starts on"
-msgstr ""
+msgstr "Starter"
msgid "Starts: %{startsAt}"
msgstr ""
@@ -31607,19 +31898,19 @@ msgid "StaticSiteEditor|Your merge request has been created"
msgstr ""
msgid "Statistics"
-msgstr ""
+msgstr "Statistik"
msgid "Status"
-msgstr ""
+msgstr "Status"
msgid "Status was retried."
msgstr ""
msgid "Status:"
-msgstr ""
+msgstr "Status:"
msgid "Status: %{title}"
-msgstr ""
+msgstr "Status: %{title}"
msgid "StatusCheck|%{pending} pending"
msgstr ""
@@ -31646,7 +31937,7 @@ msgid "StatusCheck|Check for a status response in Merge Requests. Failures do no
msgstr ""
msgid "StatusCheck|Examples: QA, Security."
-msgstr ""
+msgstr "Eksempler: kvalitetssikring, sikkerhed."
msgid "StatusCheck|External API is already in use by another status check."
msgstr ""
@@ -31697,10 +31988,10 @@ msgid "StatusPage|AWS access key ID"
msgstr ""
msgid "StatusPage|AWS region"
-msgstr ""
+msgstr "AWS-region"
msgid "StatusPage|Active"
-msgstr ""
+msgstr "Aktiv"
msgid "StatusPage|Bucket %{docsLink}"
msgstr ""
@@ -31712,7 +32003,7 @@ msgid "StatusPage|S3 Bucket name"
msgstr ""
msgid "StatusPage|Status page"
-msgstr ""
+msgstr "Statusside"
msgid "StatusPage|Status page URL"
msgstr ""
@@ -31730,16 +32021,16 @@ msgid "Stay updated about the performance and health of your environment by conf
msgstr ""
msgid "Step 1."
-msgstr ""
+msgstr "Trin 1."
msgid "Step 2."
-msgstr ""
+msgstr "Trin 2."
msgid "Step 3."
-msgstr ""
+msgstr "Trin 3."
msgid "Step 4."
-msgstr ""
+msgstr "Trin 4."
msgid "Stop Terminal"
msgstr ""
@@ -31748,34 +32039,34 @@ msgid "Stop impersonation"
msgstr ""
msgid "Stop this environment"
-msgstr ""
+msgstr "Stop miljøet"
msgid "Stopped"
-msgstr ""
+msgstr "Stoppet"
msgid "Stopping..."
-msgstr ""
+msgstr "Stopper ..."
msgid "Storage"
-msgstr ""
+msgstr "Lager"
msgid "Storage nodes for new repositories"
msgstr ""
msgid "Storage:"
-msgstr ""
+msgstr "Lager"
msgid "StorageSize|Unknown"
-msgstr ""
+msgstr "Ukendt"
msgid "Strikethrough"
-msgstr ""
+msgstr "Gennemstreget"
msgid "Subgroup information"
msgstr ""
msgid "Subgroup milestone"
-msgstr ""
+msgstr "Undergruppemilepæl"
msgid "Subgroup navigation"
msgstr ""
@@ -31790,61 +32081,61 @@ msgid "SubgroupCreationlevel|Maintainers"
msgstr ""
msgid "SubgroupCreationlevel|Owners"
-msgstr ""
+msgstr "Ejere"
msgid "Subgroups"
-msgstr ""
+msgstr "Undergrupper"
msgid "Subgroups and projects"
-msgstr ""
+msgstr "Undergrupper og projekter"
msgid "Subject Key Identifier:"
msgstr ""
msgid "Subkeys"
-msgstr ""
+msgstr "Undernøgler"
msgid "Submit"
-msgstr ""
+msgstr "Indsend"
msgid "Submit a review"
-msgstr ""
+msgstr "Indsend en kontrol"
msgid "Submit as ham"
msgstr ""
msgid "Submit as spam"
-msgstr ""
+msgstr "Indsend som spam"
msgid "Submit changes"
-msgstr ""
+msgstr "Indsend ændringer"
msgid "Submit changes..."
-msgstr ""
+msgstr "Indsend ændringer ..."
msgid "Submit feedback"
-msgstr ""
+msgstr "Indsend feedback"
msgid "Submit review"
-msgstr ""
+msgstr "Indsend kontrol"
msgid "Submit search"
-msgstr ""
+msgstr "Indsend søgning"
msgid "Submit the current review."
-msgstr ""
+msgstr "Indsend den nuværende kontrol."
msgid "Submit your changes"
-msgstr ""
+msgstr "Indsend dine ændringer"
msgid "Submitted as ham"
msgstr ""
msgid "Submitted the current review."
-msgstr ""
+msgstr "Indsendte den nuværende kontrol."
msgid "Subscribe"
-msgstr ""
+msgstr "Abonner"
msgid "Subscribe at group level"
msgstr ""
@@ -31856,10 +32147,10 @@ msgid "Subscribe to RSS feed"
msgstr ""
msgid "Subscribe to calendar"
-msgstr ""
+msgstr "Abonner på kalender"
msgid "Subscribed"
-msgstr ""
+msgstr "Abonneret"
msgid "Subscribed to this %{quick_action_target}."
msgstr ""
@@ -31868,7 +32159,7 @@ msgid "Subscribes to this %{quick_action_target}."
msgstr ""
msgid "Subscription"
-msgstr ""
+msgstr "Abonnement"
msgid "Subscription History"
msgstr ""
@@ -31889,7 +32180,7 @@ msgid "Subscription successfully deleted."
msgstr ""
msgid "SubscriptionTable|Add seats"
-msgstr ""
+msgstr "Tilføj sæder"
msgid "SubscriptionTable|An error occurred while loading the subscription details."
msgstr ""
@@ -31898,7 +32189,7 @@ msgid "SubscriptionTable|Billing"
msgstr ""
msgid "SubscriptionTable|Free"
-msgstr ""
+msgstr "Gratis"
msgid "SubscriptionTable|GitLab allows you to continue using your subscription even if you exceed the number of seats you purchased. You will be required to pay for these seats upon renewal."
msgstr ""
@@ -31910,7 +32201,7 @@ msgid "SubscriptionTable|Loading subscriptions"
msgstr ""
msgid "SubscriptionTable|Manage"
-msgstr ""
+msgstr "HÃ¥ndter"
msgid "SubscriptionTable|Max seats used"
msgstr ""
@@ -31922,7 +32213,7 @@ msgid "SubscriptionTable|Refresh Seats"
msgstr ""
msgid "SubscriptionTable|Renew"
-msgstr ""
+msgstr "Forny"
msgid "SubscriptionTable|Seats currently in use"
msgstr ""
@@ -31958,16 +32249,16 @@ msgid "SubscriptionTable|This is the number of seats you will be required to pur
msgstr ""
msgid "SubscriptionTable|Trial"
-msgstr ""
+msgstr "Prøveperiode"
msgid "SubscriptionTable|Trial end date"
-msgstr ""
+msgstr "Slutdato for prøveperiode"
msgid "SubscriptionTable|Trial start date"
-msgstr ""
+msgstr "Startdato for prøveperiode"
msgid "SubscriptionTable|Upgrade"
-msgstr ""
+msgstr "Opgrader"
msgid "SubscriptionTable|Usage"
msgstr ""
@@ -31976,7 +32267,7 @@ msgid "SubscriptionTable|Usage count is performed once a day at 12:00 PM."
msgstr ""
msgid "Subscriptions"
-msgstr ""
+msgstr "Abonnementer"
msgid "Subtracted"
msgstr ""
@@ -31985,7 +32276,7 @@ msgid "Subtracts"
msgstr ""
msgid "Succeeded"
-msgstr ""
+msgstr "Lykkedes"
msgid "Successful purchase image"
msgstr ""
@@ -32042,22 +32333,22 @@ msgid "Suggest code changes which can be immediately applied in one click. Try i
msgstr ""
msgid "Suggested change"
-msgstr ""
+msgstr "Foreslået ændring"
msgid "SuggestedColors|Aztec Gold"
-msgstr ""
+msgstr "Aztekerguld"
msgid "SuggestedColors|Blue"
-msgstr ""
+msgstr "Blå"
msgid "SuggestedColors|Blue-gray"
-msgstr ""
+msgstr "Blågrå"
msgid "SuggestedColors|Carrot orange"
-msgstr ""
+msgstr "Gulderodsorange"
msgid "SuggestedColors|Champagne"
-msgstr ""
+msgstr "Champagne"
msgid "SuggestedColors|Charcoal grey"
msgstr ""
@@ -32069,7 +32360,7 @@ msgid "SuggestedColors|Dark coral"
msgstr ""
msgid "SuggestedColors|Dark green"
-msgstr ""
+msgstr "Mørkegrøn"
msgid "SuggestedColors|Dark sea green"
msgstr ""
@@ -32081,7 +32372,7 @@ msgid "SuggestedColors|Deep violet"
msgstr ""
msgid "SuggestedColors|Gray"
-msgstr ""
+msgstr "Grå"
msgid "SuggestedColors|Green screen"
msgstr ""
@@ -32093,16 +32384,16 @@ msgid "SuggestedColors|Lavendar"
msgstr ""
msgid "SuggestedColors|Magenta-pink"
-msgstr ""
+msgstr "Magentapink"
msgid "SuggestedColors|Medium sea green"
msgstr ""
msgid "SuggestedColors|Red"
-msgstr ""
+msgstr "Rød"
msgid "SuggestedColors|Rose red"
-msgstr ""
+msgstr "Rosenrød"
msgid "SuggestedColors|Titanium yellow"
msgstr ""
@@ -32120,22 +32411,22 @@ msgid "Suggestions must all be on the same branch."
msgstr ""
msgid "Suggestions:"
-msgstr ""
+msgstr "Forslag:"
msgid "Suite"
msgstr ""
msgid "Summary"
-msgstr ""
+msgstr "Opsummering"
msgid "Summary / Note"
-msgstr ""
+msgstr "Opsummering/bemærkning"
msgid "Sunday"
-msgstr ""
+msgstr "Søndag"
msgid "SuperSonics|Activate"
-msgstr ""
+msgstr "Aktivér"
msgid "SuperSonics|Activate cloud license"
msgstr ""
@@ -32147,7 +32438,7 @@ msgid "SuperSonics|Activated on"
msgstr ""
msgid "SuperSonics|Activation code"
-msgstr ""
+msgstr "Aktiveringskode"
msgid "SuperSonics|An error occurred while activating your subscription."
msgstr ""
@@ -32168,13 +32459,13 @@ msgid "SuperSonics|Cloud licensing is now available. It's an easier way to activ
msgstr ""
msgid "SuperSonics|Expires on"
-msgstr ""
+msgstr "Udløber"
msgid "SuperSonics|Export license usage file"
msgstr ""
msgid "SuperSonics|Free trial"
-msgstr ""
+msgstr "Gratis prøveperiode"
msgid "SuperSonics|Get help for the most common connectivity issues by %{linkStart}troubleshooting the activation code%{linkEnd}."
msgstr ""
@@ -32183,7 +32474,7 @@ msgid "SuperSonics|I agree that my use of the GitLab Software is subject to the
msgstr ""
msgid "SuperSonics|ID"
-msgstr ""
+msgstr "Id"
msgid "SuperSonics|Last Sync"
msgstr ""
@@ -32195,7 +32486,7 @@ msgid "SuperSonics|Licensed to"
msgstr ""
msgid "SuperSonics|Manage"
-msgstr ""
+msgstr "HÃ¥ndter"
msgid "SuperSonics|Maximum users"
msgstr ""
@@ -32204,19 +32495,19 @@ msgid "SuperSonics|Paste your activation code"
msgstr ""
msgid "SuperSonics|Plan"
-msgstr ""
+msgstr "Plan"
msgid "SuperSonics|Ready to get started? A GitLab plan is ideal for scaling organizations and for multi team usage."
msgstr ""
msgid "SuperSonics|Renews"
-msgstr ""
+msgstr "Fornyer"
msgid "SuperSonics|Seats"
-msgstr ""
+msgstr "Sæder"
msgid "SuperSonics|Start free trial"
-msgstr ""
+msgstr "Start gratis prøveperiode"
msgid "SuperSonics|Started"
msgstr ""
@@ -32249,10 +32540,10 @@ msgid "SuperSonics|To activate your subscription, connect to GitLab servers thro
msgstr ""
msgid "SuperSonics|Type"
-msgstr ""
+msgstr "Type"
msgid "SuperSonics|Upload a license file"
-msgstr ""
+msgstr "Upload en licensfil"
msgid "SuperSonics|Users in subscription"
msgstr ""
@@ -32264,7 +32555,7 @@ msgid "SuperSonics|Users with a Guest role or those who don't belong to a Projec
msgstr ""
msgid "SuperSonics|Valid From"
-msgstr ""
+msgstr "Gyldig fra"
msgid "SuperSonics|You can learn more about %{activationLinkStart}activating your subscription%{activationLinkEnd}. If you need further assistance, please %{supportLinkStart}contact GitLab Support%{supportLinkEnd}."
msgstr ""
@@ -32291,7 +32582,7 @@ msgid "SuperSonics|Your subscription was successfully activated. You can see the
msgstr ""
msgid "Support"
-msgstr ""
+msgstr "Support"
msgid "Support for custom certificates is disabled. Ask your system's administrator to enable it."
msgstr ""
@@ -32306,7 +32597,7 @@ msgid "Switch branch"
msgstr ""
msgid "Switch branch/tag"
-msgstr ""
+msgstr "Skift gren/mærkat"
msgid "Switch to GitLab Next"
msgstr ""
@@ -32315,43 +32606,43 @@ msgid "Switch to the source to copy the file contents"
msgstr ""
msgid "Symbolic link"
-msgstr ""
+msgstr "Symbolsk link"
msgid "Sync LDAP"
-msgstr ""
+msgstr "Synkroniser LDAP"
msgid "Sync now"
-msgstr ""
+msgstr "Synkroniser nu"
msgid "Synced"
-msgstr ""
+msgstr "Synkroniseret"
msgid "Synchronization settings"
msgstr ""
msgid "Synchronize LDAP"
-msgstr ""
+msgstr "Synkroniser LDAP"
msgid "Syncing…"
-msgstr ""
+msgstr "Synkroniserer …"
msgid "Syntax is correct."
-msgstr ""
+msgstr "Syntaksen er korrekt."
msgid "Syntax is incorrect."
-msgstr ""
+msgstr "Syntaksen er forkert."
msgid "System"
-msgstr ""
+msgstr "System"
msgid "System Hooks"
-msgstr ""
+msgstr "Systemhooks"
msgid "System Hooks Help"
-msgstr ""
+msgstr "Hjælp for systemhooks"
msgid "System Info"
-msgstr ""
+msgstr "Systeminformation"
msgid "System OAuth applications"
msgstr ""
@@ -32372,31 +32663,31 @@ msgid "System hooks are triggered on sets of events like creating a project or a
msgstr ""
msgid "System metrics (Custom)"
-msgstr ""
+msgstr "Systemmålinger (tilpasset)"
msgid "System metrics (Kubernetes)"
-msgstr ""
+msgstr "Systemmålinger (Kubernetes)"
msgid "System output"
-msgstr ""
+msgstr "Systemoutput"
msgid "Table of Contents"
-msgstr ""
+msgstr "Indholdsfortegnelse"
msgid "Table of contents"
-msgstr ""
+msgstr "Indholdsfortegnelse"
msgid "Tag"
-msgstr ""
+msgstr "Mærkat"
msgid "Tag list:"
-msgstr ""
+msgstr "Mærkatliste:"
msgid "Tag name"
-msgstr ""
+msgstr "Mærkatnavn"
msgid "Tag name is required"
-msgstr ""
+msgstr "Mærkatnavn kræves"
msgid "Tag push events"
msgstr ""
@@ -32405,7 +32696,7 @@ msgid "Tag this commit."
msgstr ""
msgid "Tag:"
-msgstr ""
+msgstr "Mærkat:"
msgid "Tagged this commit to %{tag_name} with \"%{message}\"."
msgstr ""
@@ -32414,7 +32705,7 @@ msgid "Tagged this commit to %{tag_name}."
msgstr ""
msgid "Tags"
-msgstr ""
+msgstr "Mærkater"
msgid "Tags are deleted until the timeout is reached. Any remaining tags are included the next time the policy runs. To remove the time limit, set it to 0."
msgstr ""
@@ -32429,28 +32720,28 @@ msgid "Tags this commit to %{tag_name}."
msgstr ""
msgid "Tags:"
-msgstr ""
+msgstr "Mærkater:"
msgid "TagsPage|Browse commits"
msgstr ""
msgid "TagsPage|Browse files"
-msgstr ""
+msgstr "Gennemse filer"
msgid "TagsPage|Can't find HEAD commit for this tag"
msgstr ""
msgid "TagsPage|Cancel"
-msgstr ""
+msgstr "Annuller"
msgid "TagsPage|Create tag"
-msgstr ""
+msgstr "Opret mærkat"
msgid "TagsPage|Delete tag"
-msgstr ""
+msgstr "Slet mærkat"
msgid "TagsPage|Deleting the %{tag_name} tag cannot be undone. Are you sure?"
-msgstr ""
+msgstr "Sletning af mærkatet %{tag_name} kan ikke fortrydes. Er du sikker?"
msgid "TagsPage|Edit release notes"
msgstr ""
@@ -32459,13 +32750,13 @@ msgid "TagsPage|Existing branch name, tag, or commit SHA"
msgstr ""
msgid "TagsPage|Filter by tag name"
-msgstr ""
+msgstr "Filtrér efter mærkatnavn"
msgid "TagsPage|New Tag"
msgstr ""
msgid "TagsPage|New tag"
-msgstr ""
+msgstr "Nyt mærkat"
msgid "TagsPage|Optionally, add a message to the tag. Leaving this blank creates a %{link_start}lightweight tag.%{link_end}"
msgstr ""
@@ -32480,7 +32771,7 @@ msgid "TagsPage|Repository has no tags yet."
msgstr ""
msgid "TagsPage|Tags"
-msgstr ""
+msgstr "Mærkater"
msgid "TagsPage|Tags give the ability to mark specific points in history as being important"
msgstr ""
@@ -32495,16 +32786,16 @@ msgid "TagsPage|Write your release notes or drag files here…"
msgstr ""
msgid "TagsPage|protected"
-msgstr ""
+msgstr "beskyttet"
msgid "Target Branch"
-msgstr ""
+msgstr "MÃ¥lgren"
msgid "Target Path"
-msgstr ""
+msgstr "MÃ¥lsti"
msgid "Target branch"
-msgstr ""
+msgstr "MÃ¥lgren"
msgid "Target-Branch"
msgstr ""
@@ -32513,7 +32804,7 @@ msgid "Task ID: %{elastic_task}"
msgstr ""
msgid "Team"
-msgstr ""
+msgstr "Team"
msgid "Team domain"
msgstr ""
@@ -32528,7 +32819,7 @@ msgid "Tell us your experiences with the new Markdown editor %{linkStart}in this
msgstr ""
msgid "Template"
-msgstr ""
+msgstr "Skabelon"
msgid "Template to append to all Service Desk issues"
msgstr ""
@@ -32537,13 +32828,13 @@ msgid "TemplateRepository|Select a repository to make its templates available to
msgstr ""
msgid "Templates"
-msgstr ""
+msgstr "Skabeloner"
msgid "TemporaryStorageIncrease|can only be set once"
msgstr ""
msgid "TemporaryStorageIncrease|can only be set with more than %{percentage}%% usage"
-msgstr ""
+msgstr "kan kun indstilles med mere end %{percentage}%% forbrug"
msgid "TemporaryStorage|GitLab allows you a %{strongStart}free, one-time storage increase%{strongEnd}. For 30 days your storage will be unlimited. This gives you time to reduce your storage usage. After 30 days, your original storage limit of %{limit} applies. If you are at maximum storage capacity, your account will be read-only. To continue using GitLab you'll have to purchase additional storage or decrease storage usage."
msgstr ""
@@ -32555,7 +32846,7 @@ msgid "TemporaryStorage|Temporarily increase storage now?"
msgstr ""
msgid "Terminal"
-msgstr ""
+msgstr "Terminal"
msgid "Terminal for environment"
msgstr ""
@@ -32570,7 +32861,7 @@ msgid "Terms of Service and Privacy Policy"
msgstr ""
msgid "Terraform"
-msgstr ""
+msgstr "Terraform"
msgid "TerraformBanner|Learn more about GitLab's Backend State"
msgstr ""
@@ -32604,7 +32895,7 @@ msgid "Terraform|A report was generated in your pipelines."
msgstr ""
msgid "Terraform|Actions"
-msgstr ""
+msgstr "Handlinger"
msgid "Terraform|An error occurred while changing the state file"
msgstr ""
@@ -32616,13 +32907,16 @@ msgid "Terraform|Are you sure you want to remove the Terraform State %{name}?"
msgstr ""
msgid "Terraform|Cancel"
+msgstr "Annuller"
+
+msgid "Terraform|Copy Terraform init command"
msgstr ""
msgid "Terraform|Details"
-msgstr ""
+msgstr "Detaljer"
msgid "Terraform|Download JSON"
-msgstr ""
+msgstr "Download JSON"
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -32634,13 +32928,13 @@ msgid "Terraform|How to use GitLab-managed Terraform State?"
msgstr ""
msgid "Terraform|Job status"
-msgstr ""
+msgstr "Jobstatus"
msgid "Terraform|Lock"
-msgstr ""
+msgstr "LÃ¥s"
msgid "Terraform|Locked"
-msgstr ""
+msgstr "LÃ¥st"
msgid "Terraform|Locked by %{user} %{timeAgo}"
msgstr ""
@@ -32649,19 +32943,19 @@ msgid "Terraform|Locking state"
msgstr ""
msgid "Terraform|Name"
-msgstr ""
+msgstr "Navn"
msgid "Terraform|Pipeline"
-msgstr ""
+msgstr "Pipeline"
msgid "Terraform|Remove"
-msgstr ""
+msgstr "Fjern"
msgid "Terraform|Remove state file and versions"
msgstr ""
msgid "Terraform|Removing"
-msgstr ""
+msgstr "Fjerner"
msgid "Terraform|Reported Resource Changes: %{addNum} to add, %{changeNum} to change, %{deleteNum} to delete"
msgstr ""
@@ -32669,35 +32963,41 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
msgid "Terraform|Unknown User"
-msgstr ""
+msgstr "Ukendt bruger"
msgid "Terraform|Unlock"
-msgstr ""
+msgstr "Oplås"
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
msgstr ""
msgid "Test"
-msgstr ""
+msgstr "Test"
msgid "Test Cases"
-msgstr ""
+msgstr "Testsager"
msgid "Test coverage parsing"
msgstr ""
@@ -32716,19 +33016,19 @@ msgid "Test settings"
msgstr ""
msgid "TestCases|Move test case"
-msgstr ""
+msgstr "Flyt testsag"
msgid "TestCases|Moving test case"
-msgstr ""
+msgstr "Flytter testsag"
msgid "TestCases|New Test Case"
-msgstr ""
+msgstr "Ny testsag"
msgid "TestCases|New test case"
-msgstr ""
+msgstr "Ny testsag"
msgid "TestCases|Search test cases"
-msgstr ""
+msgstr "Søg efter testsager"
msgid "TestCases|Something went wrong while adding test case to Todo."
msgstr ""
@@ -32755,7 +33055,7 @@ msgid "TestCases|Something went wrong while updating the test case."
msgstr ""
msgid "TestCases|Submit test case"
-msgstr ""
+msgstr "Indsend testsag"
msgid "TestHooks|Ensure one of your projects has merge requests."
msgstr ""
@@ -32785,7 +33085,7 @@ msgid "TestHooks|Ensure the wiki is enabled and has pages."
msgstr ""
msgid "TestReports|%{count} errors"
-msgstr ""
+msgstr "%{count} fejl"
msgid "TestReports|%{count} failures"
msgstr ""
@@ -32800,7 +33100,7 @@ msgid "TestReports|Attachment"
msgstr ""
msgid "TestReports|Jobs"
-msgstr ""
+msgstr "Job"
msgid "TestReports|Learn how to upload pipeline test reports"
msgstr ""
@@ -32827,7 +33127,7 @@ msgid "TestReports|There are no tests to display"
msgstr ""
msgid "TestReports|There was an error fetching the summary."
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af opsummeringen."
msgid "TestReports|There was an error fetching the test suite."
msgstr ""
@@ -32842,13 +33142,13 @@ msgid "Text added to the body of all email messages. %{character_limit} characte
msgstr ""
msgid "Text style"
-msgstr ""
+msgstr "Tekststil"
msgid "Thank you for your business."
msgstr ""
msgid "Thank you for your feedback!"
-msgstr ""
+msgstr "Tak for din feedback!"
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -32860,13 +33160,13 @@ msgid "Thanks for signing up to GitLab!"
msgstr ""
msgid "Thanks for your purchase!"
-msgstr ""
+msgstr "Tak for dit køb!"
msgid "That is ok, I do not want to renew"
-msgstr ""
+msgstr "Det er ok, jeg vil ikke forny"
msgid "That's it, well done!"
-msgstr ""
+msgstr "Det var det, godt gået!"
msgid "The \"%{group_path}\" group allows you to sign in with your Single Sign-On Account"
msgstr ""
@@ -32912,14 +33212,14 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
msgstr ""
msgid "The URL should start with http:// or https://"
-msgstr ""
+msgstr "URL'en skal begynde med http:// eller https://"
msgid "The URL to use for connecting to Elasticsearch. Use a comma-separated list to support clustering (e.g., \"http://localhost:9200, http://localhost:9201\")."
msgstr ""
@@ -32967,7 +33267,7 @@ msgid "The contents of this group, its subgroups and projects will be permanentl
msgstr ""
msgid "The current issue"
-msgstr ""
+msgstr "Den nuværende problemstilling"
msgid "The current user is not authorized to access the job log."
msgstr ""
@@ -33003,7 +33303,7 @@ msgid "The domain you entered is misformatted."
msgstr ""
msgid "The domain you entered is not allowed."
-msgstr ""
+msgstr "Det domæne du indtastede er ikke tilladt."
msgid "The download link will expire in 24 hours."
msgstr ""
@@ -33012,7 +33312,7 @@ msgid "The environment tier must be one of %{environment_tiers}."
msgstr ""
msgid "The errors we encountered were:"
-msgstr ""
+msgstr "Vi stødte på følgende fejl:"
msgid "The file containing the export is not available yet; it may still be transferring. Please try again later."
msgstr ""
@@ -33021,10 +33321,10 @@ msgid "The file could not be displayed because it is empty or larger than the ma
msgstr ""
msgid "The file has been successfully created."
-msgstr ""
+msgstr "Filen er blevet oprettet."
msgid "The file has been successfully deleted."
-msgstr ""
+msgstr "Filen er blevet slettet."
msgid "The file name should have a .yml extension"
msgstr ""
@@ -33059,10 +33359,10 @@ msgid "The fork relationship has been removed."
msgstr ""
msgid "The form contains the following errors:"
-msgstr ""
+msgstr "Formularen indeholder følgende fejl:"
msgid "The form contains the following warning:"
-msgstr ""
+msgstr "Formularen indeholder følgende advarsel:"
msgid "The global settings require you to enable Two-Factor Authentication for your account."
msgstr ""
@@ -33116,7 +33416,7 @@ msgid "The invitation could not be declined."
msgstr ""
msgid "The invitation has already been accepted."
-msgstr ""
+msgstr "Invitationen er allerede blevet accepteret."
msgid "The invitation was successfully resent."
msgstr ""
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33155,7 +33458,7 @@ msgid "The maximum file size in megabytes for individual job artifacts."
msgstr ""
msgid "The maximum file size is %{size}."
-msgstr ""
+msgstr "Den maksimale tilladte filstørrelse er %{size}."
msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33179,7 +33479,7 @@ msgid "The merge conflicts for this merge request have already been resolved. Pl
msgstr ""
msgid "The merge request can now be merged."
-msgstr ""
+msgstr "Sammenlægningsanmodningen kan nu sammenlægges."
msgid "The metric must be one of %{metrics}."
msgstr ""
@@ -33221,7 +33521,7 @@ msgid "The password for your GitLab account on %{link_to_gitlab} has successfull
msgstr ""
msgid "The pipeline has been deleted"
-msgstr ""
+msgstr "Pipelinen blev ikke slettet"
msgid "The pipelines schedule runs pipelines in the future, repeatedly, for specific branches or tags. Those scheduled pipelines will inherit limited project access based on their associated user."
msgstr ""
@@ -33299,7 +33599,7 @@ msgid "The snippet can be accessed without any authentication."
msgstr ""
msgid "The snippet is visible only to me."
-msgstr ""
+msgstr "Uddraget er kun tilsynligt for mig."
msgid "The snippet is visible only to project members."
msgstr ""
@@ -33308,7 +33608,7 @@ msgid "The snippet is visible to any logged in user except external users."
msgstr ""
msgid "The source branch will be deleted"
-msgstr ""
+msgstr "Kildegrenen vil blive slettet"
msgid "The specified tab is invalid, please select another"
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33329,7 +33632,7 @@ msgid "The uploaded file was invalid. Supported file extensions are %{extensions
msgstr ""
msgid "The user is being deleted."
-msgstr ""
+msgstr "Brugeren slettes."
msgid "The user map has been saved. Continue by selecting the projects you want to import."
msgstr ""
@@ -33344,7 +33647,7 @@ msgid "The user you are trying to deactivate has been active in the past %{minim
msgstr ""
msgid "The username for the Jenkins server."
-msgstr ""
+msgstr "Brugernavnet til Jenkins-serveren."
msgid "The value of the provided variable exceeds the %{count} character limit"
msgstr ""
@@ -33371,88 +33674,88 @@ msgid "There are no %{replicableTypeName} to show"
msgstr ""
msgid "There are no GPG keys associated with this account."
-msgstr ""
+msgstr "Der er ingen GPG-nøgler tilknyttet til kontoen."
msgid "There are no GPG keys with access to your account."
-msgstr ""
+msgstr "Der er ingen GPG-nøgler med adgang til din konto."
msgid "There are no SSH keys associated with this account."
-msgstr ""
+msgstr "Der er ingen SSH-nøgler tilknyttet til kontoen."
msgid "There are no SSH keys with access to your account."
-msgstr ""
+msgstr "Der er ingen SSH-nøgler med adgang til din konto."
msgid "There are no Spam Logs"
-msgstr ""
+msgstr "Der er ingen spamlogge"
msgid "There are no abuse reports!"
-msgstr ""
+msgstr "Der er ingen misbrugsrapporter!"
msgid "There are no archived projects yet"
-msgstr ""
+msgstr "Der er endnu ingen arkiverede projekter"
msgid "There are no archived requirements"
-msgstr ""
+msgstr "Der er ingen arkiverede krav"
msgid "There are no archived test cases"
-msgstr ""
+msgstr "Der er ingen arkiverede testsager"
msgid "There are no changes"
-msgstr ""
+msgstr "Der er ingen ændringer"
msgid "There are no charts configured for this page"
-msgstr ""
+msgstr "Der er ingen diagrammer konfigureret til siden"
msgid "There are no closed epics"
-msgstr ""
+msgstr "Der er ingen lukkede epics"
msgid "There are no closed issues"
-msgstr ""
+msgstr "Der er ingen lukkede problemstillinger"
msgid "There are no closed merge requests"
-msgstr ""
+msgstr "Der er ingen lukkede sammenlægningsanmodninger"
msgid "There are no commits yet."
-msgstr ""
+msgstr "Der er ingen commits endnu."
msgid "There are no custom project templates set up for this GitLab instance. They are enabled from GitLab's Admin Area. Contact your GitLab instance administrator to setup custom project templates."
msgstr ""
msgid "There are no issues to show"
-msgstr ""
+msgstr "Der er ingen problemstillinger at vise"
msgid "There are no issues with the selected labels"
msgstr ""
msgid "There are no labels yet"
-msgstr ""
+msgstr "Der er endnu ingen etiketter"
msgid "There are no matching files"
msgstr ""
msgid "There are no open epics"
-msgstr ""
+msgstr "Der er ingen åbne epics"
msgid "There are no open issues"
-msgstr ""
+msgstr "Der er ingen åbne problemstillinger"
msgid "There are no open merge requests"
-msgstr ""
+msgstr "Der er ingen åbne sammenlægningsanmodninger"
msgid "There are no open requirements"
-msgstr ""
+msgstr "Der er ingen åbne krav"
msgid "There are no open test cases"
-msgstr ""
+msgstr "Der er ingen åbne testsager"
msgid "There are no packages yet"
-msgstr ""
+msgstr "Der er endnu ingen pakker"
msgid "There are no projects shared with this group yet"
msgstr ""
msgid "There are no variables yet."
-msgstr ""
+msgstr "Der er endnu ingen variabler."
msgid "There are pending advanced search migrations which require indexing to be paused. Indexing must remain paused until the migrations are completed."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33476,7 +33785,7 @@ msgid "There is no chart data available."
msgstr ""
msgid "There is no data available."
-msgstr ""
+msgstr "Der er ingen tilgængelige data."
msgid "There is no data available. Please change your selection."
msgstr ""
@@ -33488,43 +33797,46 @@ msgid "There is too much data to calculate. Please change your selection."
msgstr ""
msgid "There was a problem communicating with your device."
-msgstr ""
+msgstr "Der var problemer med at kommunikere med din enhed."
msgid "There was a problem fetching branches."
-msgstr ""
+msgstr "Der var problemer med at hente grene."
msgid "There was a problem fetching emojis."
-msgstr ""
+msgstr "Der var problemer med at hente emojier."
msgid "There was a problem fetching epics."
-msgstr ""
+msgstr "Der var problemer med at hente epics."
msgid "There was a problem fetching groups."
-msgstr ""
+msgstr "Der var problemer med at hente grupper."
msgid "There was a problem fetching iterations."
-msgstr ""
+msgstr "Der var problemer med at hente gennemløb."
msgid "There was a problem fetching labels."
+msgstr "Der var problemer med at hente etiketter."
+
+msgid "There was a problem fetching linked pipelines."
msgstr ""
msgid "There was a problem fetching milestones."
-msgstr ""
+msgstr "Der var problemer med at hente milepæle."
msgid "There was a problem fetching project branches."
-msgstr ""
+msgstr "Der var problemer med at hente projektgrene."
msgid "There was a problem fetching project tags."
-msgstr ""
+msgstr "Der var problemer med at hente projektmærkater."
msgid "There was a problem fetching project users."
-msgstr ""
+msgstr "Der var problemer med at hente projektbrugere."
msgid "There was a problem fetching recent groups."
-msgstr ""
+msgstr "Der var problemer med at hente seneste grupper."
msgid "There was a problem fetching recent projects."
-msgstr ""
+msgstr "Der var problemer med at hente seneste projekter."
msgid "There was a problem fetching the job token scope value"
msgstr ""
@@ -33533,13 +33845,13 @@ msgid "There was a problem fetching the keep latest artifacts setting."
msgstr ""
msgid "There was a problem fetching the projects"
-msgstr ""
+msgstr "Der var problemer med at hente projekterne"
msgid "There was a problem fetching users."
-msgstr ""
+msgstr "Der var problemer med at hente brugere."
msgid "There was a problem sending the confirmation email"
-msgstr ""
+msgstr "Der var problemer med at sende bekræftelses e-mailen"
msgid "There was a problem updating the keep latest artifacts setting."
msgstr ""
@@ -33548,49 +33860,49 @@ msgid "There was an error %{message} todo."
msgstr ""
msgid "There was an error adding a To Do."
-msgstr ""
+msgstr "Der opstod en fejl ved tilføjelse af To Do."
msgid "There was an error creating the dashboard, branch name is invalid."
-msgstr ""
+msgstr "Der opstod en fejl ved oprettelse af betjeningspanelet, grennavn er ugyldigt."
msgid "There was an error creating the dashboard, branch named: %{branch} already exists."
-msgstr ""
+msgstr "Der opstod en fejl ved oprettelse af betjeningspanelet, grennavn: %{branch} findes allerede."
msgid "There was an error creating the issue"
-msgstr ""
+msgstr "Der opstod en fejl ved oprettelse af problemstillingen"
msgid "There was an error deleting the To Do."
-msgstr ""
+msgstr "Der opstod en fejl ved sletning af To Do'en."
msgid "There was an error fetching configuration for charts"
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af konfiguration til diagrammer"
msgid "There was an error fetching content, please refresh the page"
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af indhold, opdater venligst siden"
msgid "There was an error fetching data for the selected stage"
msgstr ""
msgid "There was an error fetching data for the tasks by type chart"
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af data til opgaverne efter typediagram"
msgid "There was an error fetching label data for the selected group"
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af etiketdata til den valgte gruppe"
msgid "There was an error fetching median data for stages"
msgstr ""
msgid "There was an error fetching projects"
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af projekter"
msgid "There was an error fetching stage total counts"
msgstr ""
msgid "There was an error fetching the %{replicableType}"
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af %{replicableType}"
msgid "There was an error fetching the Geo Settings"
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af Geo-indstillingerne"
msgid "There was an error fetching the Node's Groups"
msgstr ""
@@ -33599,40 +33911,40 @@ msgid "There was an error fetching the deploy freezes."
msgstr ""
msgid "There was an error fetching the environments information."
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af miljøinformationen."
msgid "There was an error fetching the jobs for your project."
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af jobbene for dit projekt."
msgid "There was an error fetching the top labels for the selected group"
msgstr ""
msgid "There was an error fetching the variables."
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af variablerne."
msgid "There was an error fetching value stream analytics stages."
msgstr ""
msgid "There was an error gathering the chart data"
-msgstr ""
+msgstr "Der opstod en fejl ved indsamling af diagramdataene"
msgid "There was an error getting the epic participants."
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af epicdeltagerne."
msgid "There was an error importing the Jira project."
-msgstr ""
+msgstr "Der opstod en fejl ved import af Jira-projektet."
msgid "There was an error loading related feature flags"
-msgstr ""
+msgstr "Der opstod en fejl ved indlæsning af relaterede funktionsflag"
msgid "There was an error loading users activity calendar."
msgstr ""
msgid "There was an error parsing the data for this graph."
-msgstr ""
+msgstr "Der opstod en fejl ved fortolkning af dataene til grafen."
msgid "There was an error removing the e-mail."
-msgstr ""
+msgstr "Der opstod en fejl ved fjernelse af e-mailen."
msgid "There was an error resetting group pipeline minutes."
msgstr ""
@@ -33641,37 +33953,37 @@ msgid "There was an error resetting user pipeline minutes."
msgstr ""
msgid "There was an error retrieving the Jira users."
-msgstr ""
+msgstr "Der opstod en fejl ved indhentning af Jira-brugerne."
msgid "There was an error saving this Geo Node."
msgstr ""
msgid "There was an error saving your changes."
-msgstr ""
+msgstr "Der opstod en fejl ved gemning af dine ændringer."
msgid "There was an error subscribing to this label."
msgstr ""
msgid "There was an error syncing project %{name}"
-msgstr ""
+msgstr "Der opstod en fejl ved synkronisering af projektet %{name}"
msgid "There was an error syncing the %{replicableType}"
-msgstr ""
+msgstr "Der opstod en fejl ved synkronisering af %{replicableType}"
msgid "There was an error trying to validate your query"
msgstr ""
msgid "There was an error updating the Geo Settings"
-msgstr ""
+msgstr "Der opstod en fejl ved opdatering af Geo-indstillingerne"
msgid "There was an error updating the Maintenance Mode Settings"
msgstr ""
msgid "There was an error updating the dashboard, branch name is invalid."
-msgstr ""
+msgstr "Der opstod en fejl ved opdatering af betjeningspanelet, grennavn er ugyldigt."
msgid "There was an error updating the dashboard, branch named: %{branch} already exists."
-msgstr ""
+msgstr "Der opstod en fejl ved opdatering af betjeningspanelet, grenen ved navn: %{branch} findes allerede."
msgid "There was an error when reseting email token."
msgstr ""
@@ -33683,13 +33995,10 @@ msgid "There was an error when unsubscribing from this label."
msgstr ""
msgid "There was an error while fetching the chart data. Please refresh the page to try again."
-msgstr ""
+msgstr "Der opstod en fejl under hentning af diagramdataene. Opdater venligst siden og prøv igen."
msgid "There was an error while fetching the table data. Please refresh the page to try again."
-msgstr ""
-
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
+msgstr "Der opstod en fejl under hentning af tabeldataene. Opdater venligst siden og prøv igen."
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33701,7 +34010,7 @@ msgid "There was an error while fetching value stream summary data."
msgstr ""
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
-msgstr ""
+msgstr "Der opstod en fejl med reCAPTCHA'en. Løs venligst reCAPTCHA'en igen."
msgid "These dates affect how your epics appear in the roadmap. Set a fixed date or one inherited from the milestones assigned to issues in this epic."
msgstr ""
@@ -33734,7 +34043,7 @@ msgid "Third Party Advisory Link"
msgstr ""
msgid "Third-party offers"
-msgstr ""
+msgstr "Tilbud fra tredjepart"
msgid "This %{issuableDisplayName} is locked. Only project members can comment."
msgstr ""
@@ -33755,7 +34064,7 @@ msgid "This %{viewer} could not be displayed because %{reason}. You can %{option
msgstr ""
msgid "This Cron pattern is invalid"
-msgstr ""
+msgstr "Cron-mønsteret er ugyldigt"
msgid "This GitLab instance does not provide any shared runners yet. Instance administrators can register shared runners in the admin area."
msgstr ""
@@ -33794,16 +34103,16 @@ msgid "This also resolves all related threads"
msgstr ""
msgid "This also resolves this thread"
-msgstr ""
+msgstr "Det løser også tråden"
msgid "This application was created by %{user_link}."
-msgstr ""
+msgstr "Programmet blev oprettet af %{user_link}."
msgid "This application was created for group %{group_link}."
-msgstr ""
+msgstr "Programmet blev oprettet til gruppen %{group_link}."
msgid "This application will be able to:"
-msgstr ""
+msgstr "Programmet vil være i stand til at:"
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -33869,7 +34178,7 @@ msgid "This device has not been registered with us."
msgstr ""
msgid "This diff is collapsed."
-msgstr ""
+msgstr "Diff'en er sammenfoldet."
msgid "This directory"
msgstr ""
@@ -33884,10 +34193,10 @@ msgid "This environment has no deployments yet."
msgstr ""
msgid "This environment is being deployed"
-msgstr ""
+msgstr "Miljøet udsendes"
msgid "This environment is being re-deployed"
-msgstr ""
+msgstr "Miljøet genudsendes"
msgid "This environment's canary ingress has been updated recently. Please retry later."
msgstr ""
@@ -33899,19 +34208,16 @@ msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
msgid "This feature is part of your GitLab Ultimate trial."
-msgstr ""
+msgstr "Funktionen er en del af din GitLab Ultimate-prøveperiode."
msgid "This feature requires local storage to be enabled"
msgstr ""
msgid "This field is required"
-msgstr ""
+msgstr "Feltet kræves"
msgid "This field is required."
-msgstr ""
-
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
+msgstr "Feltet kræves."
msgid "This group"
msgstr ""
@@ -33950,7 +34256,7 @@ msgid "This is a \"Ghost User\", created to hold all issues authored by users th
msgstr ""
msgid "This is a Jira user."
-msgstr ""
+msgstr "Det er en Jira-bruger."
msgid "This is a confidential %{noteableTypeText}."
msgstr ""
@@ -33980,11 +34286,14 @@ msgid "This is the number of %{billable_users_link_start}billable users%{link_en
msgstr ""
msgid "This is your current session"
-msgstr ""
+msgstr "Dette er din nuværende session"
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -33998,16 +34307,16 @@ msgid "This job does not have a trace."
msgstr ""
msgid "This job has been canceled"
-msgstr ""
+msgstr "Jobbet er blevet annulleret"
msgid "This job has been skipped"
-msgstr ""
+msgstr "Jobbet er sprunget over"
msgid "This job has not been triggered yet"
-msgstr ""
+msgstr "Jobbet er ikke udløst endnu"
msgid "This job has not started yet"
-msgstr ""
+msgstr "Jobbet er ikke startet endnu"
msgid "This job is an out-of-date deployment to %{environmentLink} using cluster %{clusterNameOrLink} and namespace %{kubernetesNamespace}."
msgstr ""
@@ -34055,7 +34364,7 @@ msgid "This job is deployed to %{environmentLink} using cluster %{clusterNameOrL
msgstr ""
msgid "This job is deployed to %{environmentLink}."
-msgstr ""
+msgstr "Jobbet er udsendt til %{environmentLink}."
msgid "This job is in pending state and is waiting to be picked by a runner"
msgstr ""
@@ -34067,10 +34376,10 @@ msgid "This job is preparing to start"
msgstr ""
msgid "This job is waiting for resource: "
-msgstr ""
+msgstr "Jobbet venter på ressource: "
msgid "This job requires a manual action"
-msgstr ""
+msgstr "Jobbet kræver en manuel handling"
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
@@ -34079,10 +34388,10 @@ msgid "This job will automatically run after its timer finishes. Often they are
msgstr ""
msgid "This license has already expired."
-msgstr ""
+msgstr "Licensen er allerede udløbet."
msgid "This link points to external content"
-msgstr ""
+msgstr "Linket peger til eksternt indhold"
msgid "This may expose confidential information as the selected fork is in another namespace that can have other members."
msgstr ""
@@ -34103,19 +34412,19 @@ msgid "This merge request is closed. To apply this suggestion, edit this file di
msgstr ""
msgid "This merge request is from a private project to a public project."
-msgstr ""
+msgstr "Sammenlægningsanmodningen er fra et privat projekt til et offentligt projekt."
msgid "This merge request is from a private project to an internal project."
-msgstr ""
+msgstr "Sammenlægningsanmodningen er fra et privat projekt til et internt projekt."
msgid "This merge request is from an internal project to a public project."
-msgstr ""
+msgstr "Sammenlægningsanmodningen er fra et internt projekt til et offentligt projekt."
msgid "This merge request is locked."
-msgstr ""
+msgstr "Sammenlægningsanmodningen er låst."
msgid "This merge request is still a draft."
-msgstr ""
+msgstr "Sammenlægningsanmodningen er stadigvæk et udkast."
msgid "This merge request was merged. To apply this suggestion, edit this file directly."
msgstr ""
@@ -34154,7 +34463,7 @@ msgid "This project does not have %{service_desk_link_start}Service Desk%{servic
msgstr ""
msgid "This project does not have a wiki homepage yet"
-msgstr ""
+msgstr "Projektet har endnu ikke en wikistartside"
msgid "This project has no active access tokens."
msgstr ""
@@ -34172,7 +34481,7 @@ msgid "This project path either does not exist or you do not have access."
msgstr ""
msgid "This project will be deleted on %{date}"
-msgstr ""
+msgstr "Projektet slettes %{date}"
msgid "This project will be deleted on %{date} since its parent group '%{parent_group_name}' has been scheduled for deletion."
msgstr ""
@@ -34223,10 +34532,10 @@ msgid "This user has an unconfirmed email address. You may force a confirmation.
msgstr ""
msgid "This user has no active %{type}."
-msgstr ""
+msgstr "Brugeren har ingen aktive %{type}."
msgid "This user has no identities"
-msgstr ""
+msgstr "Brugeren har ingen identiteter"
msgid "This user has no personal projects."
msgstr ""
@@ -34265,7 +34574,7 @@ msgid "ThreatMonitoring|Alerts"
msgstr ""
msgid "ThreatMonitoring|All Environments"
-msgstr ""
+msgstr "Alle miljøer"
msgid "ThreatMonitoring|Anomalous Requests"
msgstr ""
@@ -34280,7 +34589,7 @@ msgid "ThreatMonitoring|Container NetworkPolicies not detected"
msgstr ""
msgid "ThreatMonitoring|Date and time"
-msgstr ""
+msgstr "Dato og klokkeslæt"
msgid "ThreatMonitoring|Dismissed"
msgstr ""
@@ -34289,10 +34598,10 @@ msgid "ThreatMonitoring|Dropped Packets"
msgstr ""
msgid "ThreatMonitoring|Environment"
-msgstr ""
+msgstr "Miljø"
msgid "ThreatMonitoring|Events"
-msgstr ""
+msgstr "Begivenheder"
msgid "ThreatMonitoring|Failed to create incident, please try again."
msgstr ""
@@ -34307,7 +34616,7 @@ msgid "ThreatMonitoring|Incident"
msgstr ""
msgid "ThreatMonitoring|Name"
-msgstr ""
+msgstr "Navn"
msgid "ThreatMonitoring|No alerts available to display. See %{linkStart}enabling threat alerts%{linkEnd} for more information on adding alerts to the list."
msgstr ""
@@ -34334,7 +34643,7 @@ msgid "ThreatMonitoring|Resolved"
msgstr ""
msgid "ThreatMonitoring|Show last"
-msgstr ""
+msgstr "Vis sidste"
msgid "ThreatMonitoring|Something went wrong, unable to fetch environments"
msgstr ""
@@ -34343,10 +34652,10 @@ msgid "ThreatMonitoring|Something went wrong, unable to fetch statistics"
msgstr ""
msgid "ThreatMonitoring|Statistics"
-msgstr ""
+msgstr "Statistik"
msgid "ThreatMonitoring|Status"
-msgstr ""
+msgstr "Status"
msgid "ThreatMonitoring|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
@@ -34382,16 +34691,16 @@ msgid "Throughput"
msgstr ""
msgid "Thursday"
-msgstr ""
+msgstr "Torsdag"
msgid "Time"
-msgstr ""
+msgstr "Tid"
msgid "Time Spent"
-msgstr ""
+msgstr "Tid brugt"
msgid "Time based: Yes"
-msgstr ""
+msgstr "Tidsbaseret: Ja"
msgid "Time before an issue gets scheduled"
msgstr ""
@@ -34418,7 +34727,7 @@ msgid "Time from last commit to merge"
msgstr ""
msgid "Time in seconds"
-msgstr ""
+msgstr "Tid i sekunder"
msgid "Time in seconds GitLab will wait for a response from the external service. When the service does not respond in time, access will be denied."
msgstr ""
@@ -34427,10 +34736,10 @@ msgid "Time of import: %{importTime}"
msgstr ""
msgid "Time remaining"
-msgstr ""
+msgstr "Tilbageværende tid"
msgid "Time spent"
-msgstr ""
+msgstr "Tid brugt"
msgid "Time to merge"
msgstr ""
@@ -34448,7 +34757,7 @@ msgid "Time until first merge request"
msgstr ""
msgid "Time zone"
-msgstr ""
+msgstr "Tidszone"
msgid "TimeTrackingEstimated|Est"
msgstr ""
@@ -34463,127 +34772,127 @@ msgid "TimeTracking|Over by %{timeRemainingHumanReadable}"
msgstr ""
msgid "TimeTracking|Spent"
-msgstr ""
+msgstr "Brugt"
msgid "TimeTracking|Time remaining: %{timeRemainingHumanReadable}"
-msgstr ""
+msgstr "Tilbageværende tid: %{timeRemainingHumanReadable}"
msgid "Timeago|%s days ago"
-msgstr ""
+msgstr "%s dage siden"
msgid "Timeago|%s days remaining"
-msgstr ""
+msgstr "%s dage tilbage"
msgid "Timeago|%s hours ago"
-msgstr ""
+msgstr "%s timer siden"
msgid "Timeago|%s hours remaining"
-msgstr ""
+msgstr "%s timer tilbage"
msgid "Timeago|%s minutes ago"
-msgstr ""
+msgstr "%s minutter siden"
msgid "Timeago|%s minutes remaining"
-msgstr ""
+msgstr "%s minutter tilbage"
msgid "Timeago|%s months ago"
-msgstr ""
+msgstr "%s måneder siden"
msgid "Timeago|%s months remaining"
-msgstr ""
+msgstr "%s måneder tilbage"
msgid "Timeago|%s seconds remaining"
-msgstr ""
+msgstr "%s sekunder tilbage"
msgid "Timeago|%s weeks ago"
-msgstr ""
+msgstr "%s uger siden"
msgid "Timeago|%s weeks remaining"
-msgstr ""
+msgstr "%s uger tilbage"
msgid "Timeago|%s years ago"
-msgstr ""
+msgstr "%s år siden"
msgid "Timeago|%s years remaining"
-msgstr ""
+msgstr "%s år tilbage"
msgid "Timeago|1 day ago"
-msgstr ""
+msgstr "1 dag siden"
msgid "Timeago|1 day remaining"
-msgstr ""
+msgstr "1 dag tilbage"
msgid "Timeago|1 hour ago"
-msgstr ""
+msgstr "1 time siden"
msgid "Timeago|1 hour remaining"
-msgstr ""
+msgstr "1 time tilbage"
msgid "Timeago|1 minute ago"
-msgstr ""
+msgstr "1 minut siden"
msgid "Timeago|1 minute remaining"
-msgstr ""
+msgstr "1 minut tilbage"
msgid "Timeago|1 month ago"
-msgstr ""
+msgstr "1 måned siden"
msgid "Timeago|1 month remaining"
-msgstr ""
+msgstr "1 måned tilbage"
msgid "Timeago|1 week ago"
-msgstr ""
+msgstr "1 uge siden"
msgid "Timeago|1 week remaining"
-msgstr ""
+msgstr "1 uge tilbage"
msgid "Timeago|1 year ago"
-msgstr ""
+msgstr "1 år siden"
msgid "Timeago|1 year remaining"
-msgstr ""
+msgstr "1 år tilbage"
msgid "Timeago|Past due"
-msgstr ""
+msgstr "Overskredet"
msgid "Timeago|in %s days"
-msgstr ""
+msgstr "om %s dage"
msgid "Timeago|in %s hours"
-msgstr ""
+msgstr "om %s timer"
msgid "Timeago|in %s minutes"
-msgstr ""
+msgstr "om %s minutter"
msgid "Timeago|in %s months"
-msgstr ""
+msgstr "om %s måneder"
msgid "Timeago|in %s seconds"
-msgstr ""
+msgstr "om %s sekunder"
msgid "Timeago|in %s weeks"
-msgstr ""
+msgstr "om %s uger"
msgid "Timeago|in %s years"
-msgstr ""
+msgstr "om %s år"
msgid "Timeago|in 1 day"
-msgstr ""
+msgstr "om 1 dag"
msgid "Timeago|in 1 hour"
-msgstr ""
+msgstr "om 1 time"
msgid "Timeago|in 1 minute"
-msgstr ""
+msgstr "om 1 minut"
msgid "Timeago|in 1 month"
-msgstr ""
+msgstr "om 1 måned"
msgid "Timeago|in 1 week"
-msgstr ""
+msgstr "om 1 uge"
msgid "Timeago|in 1 year"
-msgstr ""
+msgstr "om 1 år"
msgid "Timeago|just now"
msgstr ""
@@ -34598,7 +34907,7 @@ msgid "Timeline|Turn timeline view on"
msgstr ""
msgid "Timeout"
-msgstr ""
+msgstr "Timeout"
msgid "Timeout connecting to the Google API. Please try again."
msgstr ""
@@ -34613,20 +34922,20 @@ msgid "Timeout for the fastest Gitaly operations (in seconds)."
msgstr ""
msgid "Timezone"
-msgstr ""
+msgstr "Tidszone"
msgid "Time|hr"
msgid_plural "Time|hrs"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "t"
+msgstr[1] "t"
msgid "Time|min"
msgid_plural "Time|mins"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "m"
+msgstr[1] "m"
msgid "Time|s"
-msgstr ""
+msgstr "s"
msgid "Tip: Hover over a job to see the jobs it depends on to run."
msgstr ""
@@ -34635,25 +34944,25 @@ msgid "Tip: add a %{linkStart}CODEOWNERS%{linkEnd} to automatically add approver
msgstr ""
msgid "Title"
-msgstr ""
+msgstr "Titel"
msgid "Title:"
-msgstr ""
+msgstr "Titel:"
msgid "Titles and Descriptions"
-msgstr ""
+msgstr "Titler og beskrivelser"
msgid "To"
-msgstr ""
+msgstr "Til"
msgid "To %{link_to_help} of your domain, add the above key to a TXT record within your DNS configuration."
msgstr ""
msgid "To Do"
-msgstr ""
+msgstr "To Do"
msgid "To GitLab"
-msgstr ""
+msgstr "Til GitLab"
msgid "To accept this invitation, create an account or sign in."
msgstr ""
@@ -34674,7 +34983,7 @@ msgid "To add the entry manually, provide the following details to the applicati
msgstr ""
msgid "To confirm, type %{phrase_code}"
-msgstr ""
+msgstr "Skriv %{phrase_code} for at bekræfte"
msgid "To connect GitHub repositories, you can use a %{personal_access_token_link}. When you create your Personal Access Token, you will need to select the %{code_open}repo%{code_close} scope, so we can display a list of your public and private repositories which are available to connect."
msgstr ""
@@ -34806,7 +35115,7 @@ msgid "To use the additional formats, you must start the required %{container_li
msgstr ""
msgid "To view all %{scannedResourcesCount} scanned URLs, %{linkStart}please download the CSV file%{linkEnd}"
-msgstr ""
+msgstr "%{linkStart}Download venligst CSV-filen%{linkEnd} for at vise alle %{scannedResourcesCount} skannede URL'er"
msgid "To widen your search, change or remove filters above"
msgstr ""
@@ -34818,28 +35127,28 @@ msgid "To widen your search, change or remove filters."
msgstr ""
msgid "To-Do List"
-msgstr ""
+msgstr "To-Do-liste"
msgid "To-do item successfully marked as done."
msgstr ""
msgid "Today"
-msgstr ""
+msgstr "I dag"
msgid "Toggle GitLab Next"
-msgstr ""
+msgstr "GitLab Next til/fra"
msgid "Toggle Markdown preview"
-msgstr ""
+msgstr "Markdown-forhåndsvisning til/fra"
msgid "Toggle Sidebar"
-msgstr ""
+msgstr "Sidebjælke til/fra"
msgid "Toggle backtrace"
msgstr ""
msgid "Toggle collapse"
-msgstr ""
+msgstr "Sammenfold til/fra"
msgid "Toggle comments for this file"
msgstr ""
@@ -34848,37 +35157,37 @@ msgid "Toggle commit description"
msgstr ""
msgid "Toggle commit list"
-msgstr ""
+msgstr "Commit-liste til/fra"
msgid "Toggle dropdown"
msgstr ""
msgid "Toggle emoji award"
-msgstr ""
+msgstr "Emojipris til/fra"
msgid "Toggle focus mode"
-msgstr ""
+msgstr "Fokustilstand til/fra"
msgid "Toggle keyboard shortcuts help dialog"
-msgstr ""
+msgstr "Hjælpedialogen for tastaturgenveje til/fra"
msgid "Toggle navigation"
-msgstr ""
+msgstr "Navigation til/fra"
msgid "Toggle project select"
msgstr ""
msgid "Toggle shortcuts"
-msgstr ""
+msgstr "Genveje til/fra"
msgid "Toggle sidebar"
-msgstr ""
+msgstr "Sidebjælke til/fra"
msgid "Toggle the Performance Bar"
msgstr ""
msgid "Toggle thread"
-msgstr ""
+msgstr "Tråd til/fra"
msgid "Toggled :%{name}: emoji award."
msgstr ""
@@ -34887,13 +35196,13 @@ msgid "Toggles :%{name}: emoji award."
msgstr ""
msgid "Token"
-msgstr ""
+msgstr "Token"
msgid "Token Access"
msgstr ""
msgid "Token name"
-msgstr ""
+msgstr "Tokennavn"
msgid "Token valid until revoked"
msgstr ""
@@ -34902,10 +35211,10 @@ msgid "Tokens|Scopes set the permission levels granted to the token."
msgstr ""
msgid "Tokens|Select scopes"
-msgstr ""
+msgstr "Vælg omfang"
msgid "Tomorrow"
-msgstr ""
+msgstr "I morgen"
msgid "Too many changes to show."
msgstr ""
@@ -34917,13 +35226,13 @@ msgid "Too many projects enabled. You will need to manage them via the console o
msgstr ""
msgid "TopNav|Go back"
-msgstr ""
+msgstr "GÃ¥ tilbage"
msgid "Topics (optional)"
-msgstr ""
+msgstr "Emner (valgfrit)"
msgid "Total"
-msgstr ""
+msgstr "I alt"
msgid "Total Contributions"
msgstr ""
@@ -34935,31 +35244,31 @@ msgid "Total artifacts size: %{total_size}"
msgstr ""
msgid "Total cores (CPUs)"
-msgstr ""
+msgstr "Kerner i alt (CPU'er)"
msgid "Total issues"
-msgstr ""
+msgstr "Problemstillinger i alt"
msgid "Total memory (GB)"
-msgstr ""
+msgstr "Hukommelse i alt (GB)"
msgid "Total test time for all commits/merges"
msgstr ""
msgid "Total users"
-msgstr ""
+msgstr "Brugere i alt"
msgid "Total weight"
-msgstr ""
+msgstr "Vægt i alt"
msgid "Total: %{total}"
-msgstr ""
+msgstr "I alt: %{total}"
msgid "TotalMilestonesIndicator|1000+"
-msgstr ""
+msgstr "1000+"
msgid "TotalRefCountIndicator|1000+"
-msgstr ""
+msgstr "1000+"
msgid "Tracing"
msgstr ""
@@ -34983,13 +35292,13 @@ msgid "Track your GitLab projects with GitLab for Slack."
msgstr ""
msgid "Transfer"
-msgstr ""
+msgstr "Overfør"
msgid "Transfer ownership"
-msgstr ""
+msgstr "Overfør ejerskab"
msgid "Transfer project"
-msgstr ""
+msgstr "Overfør projekt"
msgid "Transfer your project into another namespace. %{link_start}Learn more.%{link_end}"
msgstr ""
@@ -35001,7 +35310,7 @@ msgid "TransferGroup|Cannot update the path because there are projects under thi
msgstr ""
msgid "TransferGroup|Database is not supported."
-msgstr ""
+msgstr "Databasen understøttes ikke."
msgid "TransferGroup|Group contains projects with NPM packages."
msgstr ""
@@ -35022,7 +35331,7 @@ msgid "TransferGroup|You don't have enough permissions."
msgstr ""
msgid "TransferProject|Cannot move project"
-msgstr ""
+msgstr "Kan ikke flytte projekt"
msgid "TransferProject|Please select a new namespace for your project."
msgstr ""
@@ -35030,18 +35339,24 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
msgstr ""
-msgid "Tree view"
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
+msgid "Tree view"
+msgstr "Trævisning"
+
msgid "Trending"
msgstr ""
@@ -35057,16 +35372,16 @@ msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
msgid "Trials|Go back to GitLab"
-msgstr ""
+msgstr "GÃ¥ tilbage til GitLab"
msgid "Trials|Hey there"
-msgstr ""
+msgstr "Hej med dig"
msgid "Trials|Skip Trial"
-msgstr ""
+msgstr "Spring prøveperiode over"
msgid "Trials|Upgrade %{groupName} to %{planName}"
-msgstr ""
+msgstr "Opgrader %{groupName} til %{planName}"
msgid "Trials|You can always resume this process by selecting your avatar and choosing 'Start an Ultimate trial'"
msgstr ""
@@ -35081,49 +35396,49 @@ msgid "Trials|Your trial ends on %{boldStart}%{trialEndDate}%{boldEnd}. We hope
msgstr ""
msgid "Trial|Company name"
-msgstr ""
+msgstr "Virksomhedsnavn"
msgid "Trial|Continue"
-msgstr ""
+msgstr "Fortsæt"
msgid "Trial|Continue using the basic features of GitLab for free."
msgstr ""
msgid "Trial|Country"
-msgstr ""
+msgstr "Land"
msgid "Trial|Dismiss"
msgstr ""
msgid "Trial|First name"
-msgstr ""
+msgstr "Fornavn"
msgid "Trial|GitLab Ultimate trial (optional)"
-msgstr ""
+msgstr "GitLab Ultimate-prøveperiode (valgfrit)"
msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
msgstr ""
msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
+msgstr "Hvor mange medarbejdere kommer til at bruge Gitlab?"
msgid "Trial|How many users will be evaluating the trial?"
msgstr ""
msgid "Trial|Last name"
-msgstr ""
+msgstr "Efternavn"
msgid "Trial|Number of employees"
-msgstr ""
+msgstr "Antal ansatte"
msgid "Trial|Please select a country"
-msgstr ""
+msgstr "Vælg venligst et land"
msgid "Trial|Successful trial activation image"
msgstr ""
msgid "Trial|Telephone number"
-msgstr ""
+msgstr "Telefonnummer"
msgid "Trial|Upgrade to Ultimate to keep using GitLab with advanced features."
msgstr ""
@@ -35132,13 +35447,13 @@ msgid "Trial|We will activate your trial on your group after you complete this s
msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
-msgstr ""
+msgstr "Din GitLab Ultimate-prøveperiode varer 30 dage, men du kan beholde din gratis GitLab-konto for evigt. Vi har blot brug for nogle yderligere informationer for at aktivere din prøveperiode."
msgid "Trial|your company"
-msgstr ""
+msgstr "din virksomhed"
msgid "Trigger"
-msgstr ""
+msgstr "Udløser"
msgid "Trigger a pipeline for a branch or tag by generating a trigger token and using it with an API call. The token impersonates a user's project access and permissions."
msgstr ""
@@ -35159,7 +35474,7 @@ msgid "Trigger pipelines when branches or tags are updated in the upstream repos
msgstr ""
msgid "Trigger removed."
-msgstr ""
+msgstr "Udløser fjernet."
msgid "Trigger repository check"
msgstr ""
@@ -35189,10 +35504,10 @@ msgid "Trusted"
msgstr ""
msgid "Try again"
-msgstr ""
+msgstr "Prøv igen"
msgid "Try again?"
-msgstr ""
+msgstr "Prøv igen?"
msgid "Try all GitLab has to offer for 30 days."
msgstr ""
@@ -35204,7 +35519,7 @@ msgid "Try grouping with different labels"
msgstr ""
msgid "Try to fork again"
-msgstr ""
+msgstr "Prøv at forgrene igen"
msgid "Try to keep the first line under 52 characters and the others under 72."
msgstr ""
@@ -35219,22 +35534,22 @@ msgid "Trying to communicate with your device. Plug it in (if you haven't alread
msgstr ""
msgid "Tuesday"
-msgstr ""
+msgstr "Tirsdag"
msgid "Tuning settings"
msgstr ""
msgid "Turn off"
-msgstr ""
+msgstr "Sluk"
msgid "Turn on"
-msgstr ""
+msgstr "Tænd"
msgid "Twitter"
-msgstr ""
+msgstr "Twitter"
msgid "Twitter:"
-msgstr ""
+msgstr "Twitter:"
msgid "Two-Factor Authentication"
msgstr ""
@@ -35273,10 +35588,10 @@ msgid "Two-factor grace period"
msgstr ""
msgid "Type"
-msgstr ""
+msgstr "Type"
msgid "Type/State"
-msgstr ""
+msgstr "Type/tilstand"
msgid "U2F Devices (%{length})"
msgstr ""
@@ -35285,16 +35600,16 @@ msgid "U2F only works with HTTPS-enabled websites. Contact your administrator fo
msgstr ""
msgid "URL"
-msgstr ""
+msgstr "URL"
msgid "URL cannot be blank"
msgstr ""
msgid "URL is invalid"
-msgstr ""
+msgstr "URL'en er ugyldig"
msgid "URL is required"
-msgstr ""
+msgstr "URL kræves"
msgid "URL is triggered for each branch updated to the repository"
msgstr ""
@@ -35312,7 +35627,7 @@ msgid "URL must be percent-encoded if neccessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
-msgstr ""
+msgstr "URL'en skal begynde med %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd} eller %{codeStart}ftp://%{codeEnd}"
msgid "URL of the Grafana instance to link to from the Metrics Dashboard menu item."
msgstr ""
@@ -35327,16 +35642,16 @@ msgid "URL or request ID"
msgstr ""
msgid "USER %{user_name} WILL BE REMOVED! Are you sure?"
-msgstr ""
+msgstr "BRUGEREN %{user_name} FJERNES! Er du sikker?"
msgid "USER %{user} WILL BE REMOVED! Are you sure?"
-msgstr ""
+msgstr "BRUGEREN %{user} FJERNES! Er du sikker?"
msgid "USER WILL BE BLOCKED! Are you sure?"
-msgstr ""
+msgstr "BRUGEREN BLOKERES! Er du sikker?"
msgid "UTC"
-msgstr ""
+msgstr "UTC"
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -35345,31 +35660,31 @@ msgid "Unable to build Slack link."
msgstr ""
msgid "Unable to collect CPU info"
-msgstr ""
+msgstr "Kan ikke indsamle information om CPU"
msgid "Unable to collect memory info"
-msgstr ""
+msgstr "Kan ikke indsamle information om hukommelse"
msgid "Unable to connect to Elasticsearch"
-msgstr ""
+msgstr "Kan ikke oprette forbindelse til Elasticsearch"
msgid "Unable to connect to Prometheus server"
-msgstr ""
+msgstr "Kan ikke oprette forbindelse til Prometheus-server"
msgid "Unable to connect to server: %{error}"
-msgstr ""
+msgstr "Kan ikke oprette forbindelse til serveren: %{error}"
msgid "Unable to connect to the Jira instance. Please check your Jira integration configuration."
-msgstr ""
+msgstr "Kan ikke oprette forbindelse til Jira-instansen. Tjek venligst din konfiguration af Jira-integrering."
msgid "Unable to convert Kubernetes logs encoding to UTF-8"
-msgstr ""
+msgstr "Kan ikke konvertere kodning af Kubernetes-logge til UTF-8"
msgid "Unable to create link to vulnerability"
-msgstr ""
+msgstr "Kan ikke oprette link til sårbarhed"
msgid "Unable to fetch branch list for this project."
-msgstr ""
+msgstr "Kan ikke hente grenliste for projektet."
msgid "Unable to fetch branches list, please close the form and try again"
msgstr ""
@@ -35384,19 +35699,19 @@ msgid "Unable to find Jira project to import data from."
msgstr ""
msgid "Unable to generate new instance ID"
-msgstr ""
+msgstr "Kan ikke generere nyt instans-id"
msgid "Unable to load commits. Try again later."
-msgstr ""
+msgstr "Kan ikke indlæse commits. Prøv igen senere."
msgid "Unable to load file contents. Try again later."
-msgstr ""
+msgstr "Kan ikke indlæse filindholdet. Prøv igen senere."
msgid "Unable to load the diff"
-msgstr ""
+msgstr "Kan ikke indlæse diff'en"
msgid "Unable to load the diff. %{button_try_again}"
-msgstr ""
+msgstr "Kan ikke indlæse diff'en. %{button_try_again}"
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
@@ -35405,13 +35720,13 @@ msgid "Unable to save cadence. Please try again"
msgstr ""
msgid "Unable to save iteration. Please try again"
-msgstr ""
+msgstr "Kan ikke gemme gennemløb. Prøv venligst igen"
msgid "Unable to save your changes. Please try again."
-msgstr ""
+msgstr "Kan ikke gemme dine ændringer. Prøv venligst igen."
msgid "Unable to save your preference"
-msgstr ""
+msgstr "Kan ikke gemme din præference"
msgid "Unable to schedule a pipeline to run immediately"
msgstr ""
@@ -35426,10 +35741,10 @@ msgid "Unable to update label prioritization at this time"
msgstr ""
msgid "Unable to update this epic at this time."
-msgstr ""
+msgstr "Kan ikke opdatere epicen på nuværende tidspunkt."
msgid "Unable to update this issue at this time."
-msgstr ""
+msgstr "Kan ikke opdatere problemstillingen på nuværende tidspunkt."
msgid "Unarchive project"
msgstr ""
@@ -35441,7 +35756,7 @@ msgid "Unassign from commenting user"
msgstr ""
msgid "Unassigned"
-msgstr ""
+msgstr "Utildelt"
msgid "Unauthenticated API request rate limit"
msgstr ""
@@ -35456,16 +35771,16 @@ msgid "Unauthenticated requests"
msgstr ""
msgid "Undo"
-msgstr ""
+msgstr "Fortryd"
msgid "Undo Ignore"
-msgstr ""
+msgstr "Fortryd ignorer"
msgid "Undo ignore"
-msgstr ""
+msgstr "Fortryd ignorer"
msgid "Unexpected error"
-msgstr ""
+msgstr "Uventet fejl"
msgid "Unfollow"
msgstr ""
@@ -35477,61 +35792,61 @@ msgid "Unhappy?"
msgstr ""
msgid "Units|ms"
-msgstr ""
+msgstr "ms"
msgid "Units|s"
-msgstr ""
+msgstr "s"
msgid "Unknown"
-msgstr ""
+msgstr "Ukendt"
msgid "Unknown Error"
-msgstr ""
+msgstr "Ukendt fejl"
msgid "Unknown cache key"
-msgstr ""
+msgstr "Ukendt mellemlagernøgle"
msgid "Unknown encryption strategy: %{encrypted_strategy}!"
msgstr ""
msgid "Unknown format"
-msgstr ""
+msgstr "Ukendt format"
msgid "Unknown response text"
-msgstr ""
+msgstr "Ukendt svartekst"
msgid "Unknown user"
-msgstr ""
+msgstr "Ukendt bruger"
msgid "Unless otherwise agreed to in writing with GitLab, by clicking \"Upload License\" you agree that your use of GitLab Software is subject to the %{eula_link_start}Terms of Service%{eula_link_end}."
msgstr ""
msgid "Unlimited"
-msgstr ""
+msgstr "Ubegrænset"
msgid "Unlink"
msgstr ""
msgid "Unlock"
-msgstr ""
+msgstr "Oplås"
msgid "Unlock account"
-msgstr ""
+msgstr "Oplås konto"
msgid "Unlock the discussion"
-msgstr ""
+msgstr "Oplås debatten"
msgid "Unlock this %{issuableDisplayName}? %{strongStart}Everyone%{strongEnd} will be able to comment."
msgstr ""
msgid "Unlocked"
-msgstr ""
+msgstr "Oplåst"
msgid "Unlocked the discussion."
-msgstr ""
+msgstr "Oplåste debatten."
msgid "Unlocks the discussion."
-msgstr ""
+msgstr "Oplåser debatten."
msgid "Unmarked this %{noun} as a draft."
msgstr ""
@@ -35555,16 +35870,16 @@ msgid "Unresolved"
msgstr ""
msgid "UnscannedProjects|15 or more days"
-msgstr ""
+msgstr "15 eller flere dage"
msgid "UnscannedProjects|30 or more days"
-msgstr ""
+msgstr "30 eller flere dage"
msgid "UnscannedProjects|5 or more days"
-msgstr ""
+msgstr "5 eller flere dage"
msgid "UnscannedProjects|60 or more days"
-msgstr ""
+msgstr "60 eller flere dage"
msgid "Unschedule job"
msgstr ""
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35618,19 +35936,19 @@ msgid "Upcoming Release"
msgstr ""
msgid "Update"
-msgstr ""
+msgstr "Opdater"
msgid "Update %{sourcePath} file"
msgstr ""
msgid "Update Now"
-msgstr ""
+msgstr "Opdater nu"
msgid "Update Scheduled…"
msgstr ""
msgid "Update all"
-msgstr ""
+msgstr "Opdater alle"
msgid "Update appearance settings"
msgstr ""
@@ -35651,19 +35969,19 @@ msgid "Update it"
msgstr ""
msgid "Update iteration"
-msgstr ""
+msgstr "Opdater gennemløb"
msgid "Update milestone"
-msgstr ""
+msgstr "Opdater milepæl"
msgid "Update now"
-msgstr ""
+msgstr "Opdater nu"
msgid "Update username"
-msgstr ""
+msgstr "Opdater brugernavn"
msgid "Update variable"
-msgstr ""
+msgstr "Opdater variabel"
msgid "Update your bookmarked URLs as filtered/sorted branches URL has been changed."
msgstr ""
@@ -35693,40 +36011,40 @@ msgid "UpdateRepositoryStorage|Timeout waiting for %{type} repository pushes"
msgstr ""
msgid "Updated"
-msgstr ""
+msgstr "Opdateret"
msgid "Updated %{updated_at} by %{updated_by}"
msgstr ""
msgid "Updates"
-msgstr ""
+msgstr "Opdateringer"
msgid "Updating"
-msgstr ""
+msgstr "Opdaterer"
msgid "Updating…"
-msgstr ""
+msgstr "Opdaterer …"
msgid "Upgrade offers available!"
-msgstr ""
+msgstr "Der findes tilbud om opgradering!"
msgid "Upgrade your plan"
-msgstr ""
+msgstr "Opgrader din plan"
msgid "Upload"
-msgstr ""
+msgstr "Upload"
msgid "Upload CSV file"
-msgstr ""
+msgstr "Upload CSV-fil"
msgid "Upload File"
-msgstr ""
+msgstr "Upload fil"
msgid "Upload License"
-msgstr ""
+msgstr "Upload licens"
msgid "Upload New File"
-msgstr ""
+msgstr "Upload ny fil"
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -35735,28 +36053,28 @@ msgid "Upload a private key for your certificate"
msgstr ""
msgid "Upload an image"
-msgstr ""
+msgstr "Upload et billede"
msgid "Upload file"
-msgstr ""
+msgstr "Upload fil"
msgid "Upload image"
-msgstr ""
+msgstr "Upload billede"
msgid "Upload license"
-msgstr ""
+msgstr "Upload licens"
msgid "Upload object map"
msgstr ""
msgid "UploadLink|click to upload"
-msgstr ""
+msgstr "klik for at uploade"
msgid "Uploading changes to terminal"
msgstr ""
msgid "Uploads"
-msgstr ""
+msgstr "Uploads"
msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
msgstr ""
@@ -35765,13 +36083,13 @@ msgid "Upstream"
msgstr ""
msgid "Uptime"
-msgstr ""
+msgstr "Oppetid"
msgid "Upvotes"
msgstr ""
msgid "Usage"
-msgstr ""
+msgstr "Forbrug"
msgid "Usage Trends"
msgstr ""
@@ -35786,7 +36104,7 @@ msgid "UsageQuota|%{percentageLeft} of purchased storage is available"
msgstr ""
msgid "UsageQuota|Artifacts"
-msgstr ""
+msgstr "Artefakter"
msgid "UsageQuota|Artifacts is a sum of build and pipeline artifacts."
msgstr ""
@@ -35807,7 +36125,7 @@ msgid "UsageQuota|Increase storage temporarily"
msgstr ""
msgid "UsageQuota|LFS Objects"
-msgstr ""
+msgstr "LFS-objekter"
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -35818,17 +36136,14 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
-msgstr ""
+msgstr "Pakker"
msgid "UsageQuota|Pipelines"
msgstr ""
msgid "UsageQuota|Purchase more storage"
-msgstr ""
+msgstr "Køb mere lager"
msgid "UsageQuota|Purchased storage available"
msgstr ""
@@ -35839,11 +36154,17 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
+msgstr "Uddrag"
+
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
msgstr ""
msgid "UsageQuota|Storage"
-msgstr ""
+msgstr "Lager"
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -35876,7 +36197,7 @@ msgid "UsageQuota|Total namespace storage used"
msgstr ""
msgid "UsageQuota|Unlimited"
-msgstr ""
+msgstr "Ubegrænset"
msgid "UsageQuota|Uploads"
msgstr ""
@@ -35885,11 +36206,14 @@ msgid "UsageQuota|Usage"
msgstr ""
msgid "UsageQuota|Usage Quotas"
-msgstr ""
+msgstr "Forbrugskvoter"
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -35903,10 +36227,10 @@ msgid "UsageQuota|When you purchase additional storage, we automatically unlock
msgstr ""
msgid "UsageQuota|Wiki"
-msgstr ""
+msgstr "Wiki"
msgid "UsageQuota|Wikis"
-msgstr ""
+msgstr "Wikier"
msgid "UsageQuota|You have consumed all of your additional storage, please purchase more to unlock your projects over the free %{actualRepositorySizeLimit} limit."
msgstr ""
@@ -35933,7 +36257,7 @@ msgid "UsageTrends|Could not load the projects and groups chart. Please refresh
msgstr ""
msgid "UsageTrends|Groups"
-msgstr ""
+msgstr "Grupper"
msgid "UsageTrends|Issues"
msgstr ""
@@ -35942,13 +36266,13 @@ msgid "UsageTrends|Issues & merge requests"
msgstr ""
msgid "UsageTrends|Items"
-msgstr ""
+msgstr "Elementer"
msgid "UsageTrends|Merge requests"
msgstr ""
msgid "UsageTrends|Month"
-msgstr ""
+msgstr "MÃ¥ned"
msgid "UsageTrends|No data available."
msgstr ""
@@ -35957,7 +36281,7 @@ msgid "UsageTrends|Pipelines"
msgstr ""
msgid "UsageTrends|Pipelines canceled"
-msgstr ""
+msgstr "Pipelines annulleret"
msgid "UsageTrends|Pipelines failed"
msgstr ""
@@ -35972,25 +36296,25 @@ msgid "UsageTrends|Pipelines total"
msgstr ""
msgid "UsageTrends|Projects"
-msgstr ""
+msgstr "Projekter"
msgid "UsageTrends|There was an error fetching the cancelled pipelines. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af de annullerede pipelines. Prøv venligst igen."
msgid "UsageTrends|There was an error fetching the failed pipelines. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af de mislykkede pipelines. Prøv venligst igen."
msgid "UsageTrends|There was an error fetching the groups. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af grupperne. Prøv venligst igen."
msgid "UsageTrends|There was an error fetching the issues. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af problemstillingerne. Prøv venligst igen."
msgid "UsageTrends|There was an error fetching the merge requests. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af sammenlægningsanmodningerne. Prøv venligst igen."
msgid "UsageTrends|There was an error fetching the projects. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af projekterne. Prøv venligst igen."
msgid "UsageTrends|There was an error fetching the skipped pipelines. Please try again."
msgstr ""
@@ -36011,13 +36335,13 @@ msgid "UsageTrends|Total projects & groups"
msgstr ""
msgid "UsageTrends|Users"
-msgstr ""
+msgstr "Brugere"
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
msgid "Use .gitlab-ci.yml"
-msgstr ""
+msgstr "Brug .gitlab-ci.yml"
msgid "Use GitLab Runner in AWS"
msgstr ""
@@ -36029,7 +36353,7 @@ msgid "Use an AWS CloudFormation Template (CFT) to install and configure GitLab
msgstr ""
msgid "Use cURL"
-msgstr ""
+msgstr "Brug cURL"
msgid "Use custom color #FF0000"
msgstr ""
@@ -36046,14 +36370,17 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
-msgid "Use shortcuts"
+msgid "Use primary email (%{email})"
msgstr ""
+msgid "Use shortcuts"
+msgstr "Brug genveje"
+
msgid "Use slash commands."
msgstr ""
msgid "Use template"
-msgstr ""
+msgstr "Brug skabelon"
msgid "Use the link below to confirm your email address (%{email})"
msgstr ""
@@ -36071,7 +36398,7 @@ msgid "Use this token to validate received payloads."
msgstr ""
msgid "Use webhook"
-msgstr ""
+msgstr "Brug webhook"
msgid "Use your global notification setting"
msgstr ""
@@ -36089,7 +36416,7 @@ msgid "Used by more than 100,000 organizations, GitLab is the most popular solut
msgstr ""
msgid "Used programming language"
-msgstr ""
+msgstr "Anvendt programmeringssprog"
msgid "Used to calculate the number of slices during reindexing. The multiplier will be applied to the number of shards per index. Learn more about %{slice_multiplier_link_start}slice multiplier configuration%{slice_multiplier_link_end}."
msgstr ""
@@ -36098,7 +36425,7 @@ msgid "Used to help configure your identity provider"
msgstr ""
msgid "User"
-msgstr ""
+msgstr "Bruger"
msgid "User %{current_user_username} has started impersonating %{username}"
msgstr ""
@@ -36110,13 +36437,13 @@ msgid "User %{user} was removed from %{group}."
msgstr ""
msgid "User ID"
-msgstr ""
+msgstr "Bruger-id"
msgid "User OAuth applications"
msgstr ""
msgid "User Settings"
-msgstr ""
+msgstr "Brugerindstillinger"
msgid "User and IP Rate Limits"
msgstr ""
@@ -36134,25 +36461,25 @@ msgid "User is not allowed to resolve thread"
msgstr ""
msgid "User key"
-msgstr ""
+msgstr "Brugernøgle"
msgid "User key was successfully removed."
msgstr ""
msgid "User list %{name} will be removed. Are you sure?"
-msgstr ""
+msgstr "Brugerlisten %{name} fjernes. Er du sikker?"
msgid "User map"
-msgstr ""
+msgstr "Brugerkort"
msgid "User pipeline minutes were successfully reset."
msgstr ""
msgid "User restrictions"
-msgstr ""
+msgstr "Brugerrestriktioner"
msgid "User settings"
-msgstr ""
+msgstr "Brugerindstillinger"
msgid "User was successfully created."
msgstr ""
@@ -36173,37 +36500,37 @@ msgid "User-based escalation rules must have a user with access to the project"
msgstr ""
msgid "UserAvailability|%{author} %{spanStart}(Busy)%{spanEnd}"
-msgstr ""
+msgstr "%{author} %{spanStart}(optaget)%{spanEnd}"
msgid "UserAvailability|%{author} (Busy)"
-msgstr ""
+msgstr "%{author} (optaget)"
msgid "UserAvailability|(Busy)"
-msgstr ""
+msgstr "(optaget)"
msgid "UserLists|Add"
-msgstr ""
+msgstr "Tilføj"
msgid "UserLists|Add Users"
-msgstr ""
+msgstr "Tilføj brugere"
msgid "UserLists|Add users"
-msgstr ""
+msgstr "Tilføj brugere"
msgid "UserLists|Cancel"
-msgstr ""
+msgstr "Annuller"
msgid "UserLists|Create"
-msgstr ""
+msgstr "Opret"
msgid "UserLists|Define a set of users to be used within feature flag strategies"
msgstr ""
msgid "UserLists|Edit"
-msgstr ""
+msgstr "Rediger"
msgid "UserLists|Edit %{name}"
-msgstr ""
+msgstr "Rediger %{name}"
msgid "UserLists|Enter a comma separated list of user IDs. These IDs should be the users of the system in which the feature flag is set, not GitLab IDs"
msgstr ""
@@ -36212,82 +36539,82 @@ msgid "UserLists|Feature flag user list"
msgstr ""
msgid "UserLists|Get started with user lists"
-msgstr ""
+msgstr "Kom godt i gang med brugerlister"
msgid "UserLists|Lists allow you to define a set of users to be used with feature flags. %{linkStart}Read more about feature flag lists.%{linkEnd}"
msgstr ""
msgid "UserLists|Loading user lists"
-msgstr ""
+msgstr "Indlæser brugerlister"
msgid "UserLists|Name"
-msgstr ""
+msgstr "Navn"
msgid "UserLists|New list"
-msgstr ""
+msgstr "Ny liste"
msgid "UserLists|New user list"
-msgstr ""
+msgstr "Ny brugerliste"
msgid "UserLists|Save"
-msgstr ""
+msgstr "Gem"
msgid "UserLists|There are no users"
-msgstr ""
+msgstr "Der er ingen brugere"
msgid "UserLists|There was an error fetching the user lists."
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af brugerlisterne."
msgid "UserLists|User ID"
-msgstr ""
+msgstr "Bruger-id"
msgid "UserLists|User IDs"
-msgstr ""
+msgstr "Bruger-id'er"
msgid "UserLists|User Lists"
-msgstr ""
+msgstr "Brugerlister"
msgid "UserLists|User lists allow you to define a set of users to use with Feature Flags."
msgstr ""
msgid "UserList|Delete %{name}?"
-msgstr ""
+msgstr "Slet %{name}?"
msgid "UserList|created %{timeago}"
-msgstr ""
+msgstr "oprettet %{timeago}"
msgid "UserProfile|(Busy)"
-msgstr ""
+msgstr "(optaget)"
msgid "UserProfile|Activity"
-msgstr ""
+msgstr "Aktivitet"
msgid "UserProfile|Already reported for abuse"
msgstr ""
msgid "UserProfile|Blocked user"
-msgstr ""
+msgstr "Blokeret bruger"
msgid "UserProfile|Bot activity"
-msgstr ""
+msgstr "Botaktivitet"
msgid "UserProfile|Contributed projects"
msgstr ""
msgid "UserProfile|Edit profile"
-msgstr ""
+msgstr "Rediger profil"
msgid "UserProfile|Explore public groups to find projects to contribute to."
msgstr ""
msgid "UserProfile|Followers"
-msgstr ""
+msgstr "Følgere"
msgid "UserProfile|Following"
-msgstr ""
+msgstr "Følger"
msgid "UserProfile|Groups"
-msgstr ""
+msgstr "Grupper"
msgid "UserProfile|Groups are the best way to manage projects and members."
msgstr ""
@@ -36296,28 +36623,28 @@ msgid "UserProfile|Join or create a group to start contributing by commenting on
msgstr ""
msgid "UserProfile|Most Recent Activity"
-msgstr ""
+msgstr "Nyeste aktivitet"
msgid "UserProfile|No snippets found."
-msgstr ""
+msgstr "Ingen uddrag fundet."
msgid "UserProfile|Overview"
-msgstr ""
+msgstr "Oversigt"
msgid "UserProfile|Personal projects"
-msgstr ""
+msgstr "Personlige projekter"
msgid "UserProfile|Pronounced as: %{pronunciation}"
-msgstr ""
+msgstr "Udtales: %{pronunciation}"
msgid "UserProfile|Report abuse"
-msgstr ""
+msgstr "Rapportér misbrug"
msgid "UserProfile|Retry"
-msgstr ""
+msgstr "Prøv igen"
msgid "UserProfile|Snippets"
-msgstr ""
+msgstr "Uddrag"
msgid "UserProfile|Snippets in GitLab can either be private, internal, or public."
msgstr ""
@@ -36326,10 +36653,10 @@ msgid "UserProfile|Star projects to track their progress and show your appreciat
msgstr ""
msgid "UserProfile|Starred projects"
-msgstr ""
+msgstr "Projekter med stjerne"
msgid "UserProfile|Subscribe"
-msgstr ""
+msgstr "Abonner"
msgid "UserProfile|This user doesn't have any followers."
msgstr ""
@@ -36338,7 +36665,7 @@ msgid "UserProfile|This user doesn't have any personal projects"
msgstr ""
msgid "UserProfile|This user has a private profile"
-msgstr ""
+msgstr "Brugeren har en privat profil"
msgid "UserProfile|This user hasn't contributed to any projects"
msgstr ""
@@ -36347,34 +36674,34 @@ msgid "UserProfile|This user hasn't starred any projects"
msgstr ""
msgid "UserProfile|This user is blocked"
-msgstr ""
+msgstr "Brugeren er blokeret"
msgid "UserProfile|This user isn't following other users."
msgstr ""
msgid "UserProfile|Unconfirmed user"
-msgstr ""
+msgstr "Ubekræftet bruger"
msgid "UserProfile|View all"
-msgstr ""
+msgstr "Vis alle"
msgid "UserProfile|View user in admin area"
-msgstr ""
+msgstr "Vis bruger i administratorområde"
msgid "UserProfile|You are not following other users."
-msgstr ""
+msgstr "Du følger ikke andre brugere."
msgid "UserProfile|You can create a group for several dependent projects."
msgstr ""
msgid "UserProfile|You do not have any followers."
-msgstr ""
+msgstr "Du har ingen følgere."
msgid "UserProfile|You haven't created any personal projects."
msgstr ""
msgid "UserProfile|You haven't created any snippets."
-msgstr ""
+msgstr "Du har ikke oprettet nogle uddrag."
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
@@ -36386,31 +36713,31 @@ msgid "UserProfile|made a private contribution"
msgstr ""
msgid "Username"
-msgstr ""
+msgstr "Brugernavn"
msgid "Username (for password-protected Elasticsearch servers)"
msgstr ""
msgid "Username (optional)"
-msgstr ""
+msgstr "Brugernavn (valgfrit)"
msgid "Username is already taken."
-msgstr ""
+msgstr "Brugernavnet er allerede taget."
msgid "Username is available."
-msgstr ""
+msgstr "Brugernavnet er tilgængeligt."
msgid "Username or email"
-msgstr ""
+msgstr "Brugernavn eller e-mail"
msgid "Username:"
-msgstr ""
+msgstr "Brugernavn:"
msgid "Username: %{username}"
-msgstr ""
+msgstr "Brugernavn: %{username}"
msgid "Users"
-msgstr ""
+msgstr "Brugere"
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -36419,7 +36746,7 @@ msgid "Users can render diagrams in AsciiDoc, Markdown, reStructuredText, and Te
msgstr ""
msgid "Users in License"
-msgstr ""
+msgstr "Brugere i licens"
msgid "Users or groups set as approvers in the project's or merge request's settings."
msgstr ""
@@ -36449,7 +36776,7 @@ msgid "UsersSelect|No assignee - %{openingTag} assign yourself %{closingTag}"
msgstr ""
msgid "UsersSelect|Unassigned"
-msgstr ""
+msgstr "Utildelt"
msgid "Using %{code_start}::%{code_end} denotes a %{link_start}scoped label set%{link_end}"
msgstr ""
@@ -36473,7 +36800,7 @@ msgid "Validations failed."
msgstr ""
msgid "Value"
-msgstr ""
+msgstr "Værdi"
msgid "Value Stream Analytics"
msgstr ""
@@ -36488,13 +36815,13 @@ msgid "Value may contain a variable reference"
msgstr ""
msgid "Value stream"
-msgstr ""
+msgstr "Value stream"
msgid "ValueStreamAnalyticsStage|We don't have enough data to show this stage."
msgstr ""
msgid "ValueStreamAnalytics|%{stageCount}+ items"
-msgstr ""
+msgstr "%{stageCount}+ elementer"
msgid "ValueStreamAnalytics|%{value}M"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36536,16 +36869,16 @@ msgid "ValueStreamEvent|Stage time (median)"
msgstr ""
msgid "ValueStreamEvent|Start"
-msgstr ""
+msgstr "Start"
msgid "ValueStreamEvent|Stop"
-msgstr ""
+msgstr "Stop"
msgid "ValueStream|The Default Value Stream cannot be deleted"
msgstr ""
msgid "Variable"
-msgstr ""
+msgstr "Variabel"
msgid "Variable references indicated by %{codeStart}$%{codeEnd} may be expanded. If this is not what you want, consider %{docsLinkStart}using a workaround to prevent expansion%{docsLinkEnd}."
msgstr ""
@@ -36554,10 +36887,10 @@ msgid "Variable will be masked in job logs."
msgstr ""
msgid "Variables"
-msgstr ""
+msgstr "Variabler"
msgid "Variables can be:"
-msgstr ""
+msgstr "Variabler kan være:"
msgid "Variables store information, like passwords and secret keys, that you can use in job scripts."
msgstr ""
@@ -36593,16 +36926,16 @@ msgid "Verify configuration"
msgstr ""
msgid "Version"
-msgstr ""
+msgstr "Version"
msgid "Version %{versionNumber}"
-msgstr ""
+msgstr "Version %{versionNumber}"
msgid "Version %{versionNumber} (latest)"
-msgstr ""
+msgstr "Version %{versionNumber} (seneste)"
msgid "View Documentation"
-msgstr ""
+msgstr "Vis dokumentation"
msgid "View alert details at"
msgstr ""
@@ -36611,39 +36944,39 @@ msgid "View alert details."
msgstr ""
msgid "View all environments."
-msgstr ""
+msgstr "Vis alle miljøer."
msgid "View all issues"
-msgstr ""
+msgstr "Vis alle problemstillinger"
msgid "View blame prior to this change"
msgstr ""
msgid "View chart"
msgid_plural "View charts"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Vis diagram"
+msgstr[1] "Vis diagrammer"
msgid "View dependency details for your project"
-msgstr ""
+msgstr "Vis afhængighedsdetaljer for dit projekt"
msgid "View deployment"
-msgstr ""
+msgstr "Vis udsendelse"
msgid "View details"
-msgstr ""
+msgstr "Vis detaljer"
msgid "View details: %{details_url}"
-msgstr ""
+msgstr "Vis detaljer: %{details_url}"
msgid "View documentation"
-msgstr ""
+msgstr "Vis dokumentation"
msgid "View eligible approvers"
msgstr ""
msgid "View epics list"
-msgstr ""
+msgstr "Vis epicliste"
msgid "View exposed artifact"
msgid_plural "View %d exposed artifacts"
@@ -36651,7 +36984,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "View file @ "
-msgstr ""
+msgstr "Vis fil @ "
msgid "View file @ %{commitSha}"
msgstr ""
@@ -36663,76 +36996,81 @@ msgid "View full log"
msgstr ""
msgid "View group in admin area"
-msgstr ""
+msgstr "Vis gruppe i administratorområde"
msgid "View group labels"
-msgstr ""
+msgstr "Vis gruppeetiketter"
msgid "View incident issues."
msgstr ""
msgid "View issue"
-msgstr ""
+msgstr "Vis problemstilling"
msgid "View issues"
-msgstr ""
+msgstr "Vis problemstillinger"
msgid "View it on GitLab"
msgstr ""
msgid "View job"
-msgstr ""
+msgstr "Vis job"
msgid "View job log"
-msgstr ""
+msgstr "Vis joblog"
msgid "View jobs"
-msgstr ""
+msgstr "Vis job"
msgid "View labels"
-msgstr ""
+msgstr "Vis etiketter"
msgid "View log"
-msgstr ""
+msgstr "Vis log"
msgid "View logs"
-msgstr ""
+msgstr "Vis logge"
msgid "View merge request"
-msgstr ""
+msgstr "Vis sammenlægningsanmodning"
msgid "View on %{url}"
msgstr ""
msgid "View open merge request"
-msgstr ""
+msgstr "Vis åben sammenlægningsanmodning"
msgid "View page @ "
-msgstr ""
+msgstr "Vis side @ "
msgid "View performance dashboard."
-msgstr ""
+msgstr "Vis ydelsesbetjeningspanel."
msgid "View project"
-msgstr ""
+msgstr "Vis projekt"
msgid "View project in admin area"
-msgstr ""
+msgstr "Vis projekt i administratorområde"
msgid "View project labels"
-msgstr ""
+msgstr "Vis projektetiketter"
+
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
msgid "View replaced file @ "
-msgstr ""
+msgstr "Vis erstattede fil @ "
msgid "View setting"
-msgstr ""
+msgstr "Vis indstilling"
msgid "View supported languages and frameworks"
msgstr ""
msgid "View the documentation"
-msgstr ""
+msgstr "Vis dokumentationen"
msgid "View the latest successful deployment to this environment"
msgstr ""
@@ -36741,28 +37079,28 @@ msgid "View the performance dashboard at"
msgstr ""
msgid "View usage details"
-msgstr ""
+msgstr "Vis forbrugsdetaljer"
msgid "View users statistics"
-msgstr ""
+msgstr "Vis brugerstatistik"
msgid "Viewed"
-msgstr ""
+msgstr "Vist"
msgid "Viewing commit"
-msgstr ""
+msgstr "Viser commit"
msgid "Visibility"
-msgstr ""
+msgstr "Synlighed"
msgid "Visibility and access controls"
-msgstr ""
+msgstr "Synlighed og adgangsstyringer"
msgid "Visibility level"
-msgstr ""
+msgstr "Synlighedsniveau"
msgid "Visibility level:"
-msgstr ""
+msgstr "Synlighedsniveau:"
msgid "Visibility settings have been disabled by the administrator."
msgstr ""
@@ -36771,34 +37109,34 @@ msgid "Visibility, project features, permissions"
msgstr ""
msgid "Visibility:"
-msgstr ""
+msgstr "Synlighed:"
msgid "VisibilityLevel|Internal"
msgstr ""
msgid "VisibilityLevel|Private"
-msgstr ""
+msgstr "Privat"
msgid "VisibilityLevel|Public"
-msgstr ""
+msgstr "Offentlig"
msgid "VisibilityLevel|Unknown"
-msgstr ""
+msgstr "Ukendt"
msgid "Visit settings page"
-msgstr ""
+msgstr "Besøg indstillingsside"
msgid "Visual Studio Code (HTTPS)"
-msgstr ""
+msgstr "Visual Studio Code (HTTPS)"
msgid "Visual Studio Code (SSH)"
-msgstr ""
+msgstr "Visual Studio Code (SSH)"
msgid "Vulnerabilities"
-msgstr ""
+msgstr "SÃ¥rbarheder"
msgid "Vulnerabilities over time"
-msgstr ""
+msgstr "SÃ¥rbarheder over tid"
msgid "Vulnerability Report"
msgstr ""
@@ -36837,13 +37175,13 @@ msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
msgid "VulnerabilityManagement|Change status"
-msgstr ""
+msgstr "Ændr status"
msgid "VulnerabilityManagement|Could not process %{issueReference}: %{errorMessage}."
msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
-msgstr ""
+msgstr "Opret Jira-problemstilling"
msgid "VulnerabilityManagement|Detected"
msgstr ""
@@ -36894,7 +37232,7 @@ msgid "VulnerabilityStatusTypes|All statuses"
msgstr ""
msgid "VulnerabilityStatusTypes|Confirmed"
-msgstr ""
+msgstr "Bekræftet"
msgid "VulnerabilityStatusTypes|Detected"
msgstr ""
@@ -36909,7 +37247,7 @@ msgid "Vulnerability|%{scannerName} (version %{scannerVersion})"
msgstr ""
msgid "Vulnerability|Activity"
-msgstr ""
+msgstr "Aktivitet"
msgid "Vulnerability|Actual Response"
msgstr ""
@@ -36918,13 +37256,13 @@ msgid "Vulnerability|Actual received response is the one received when this faul
msgstr ""
msgid "Vulnerability|Additional Info"
-msgstr ""
+msgstr "Yderligere information"
msgid "Vulnerability|Class"
-msgstr ""
+msgstr "Klasse"
msgid "Vulnerability|Comments"
-msgstr ""
+msgstr "Kommentarer"
msgid "Vulnerability|Crash address"
msgstr ""
@@ -36936,7 +37274,7 @@ msgid "Vulnerability|Crash type"
msgstr ""
msgid "Vulnerability|Description"
-msgstr ""
+msgstr "Beskrivelse"
msgid "Vulnerability|Detected"
msgstr ""
@@ -36948,7 +37286,7 @@ msgid "Vulnerability|Evidence"
msgstr ""
msgid "Vulnerability|File"
-msgstr ""
+msgstr "Fil"
msgid "Vulnerability|Identifier"
msgstr ""
@@ -36957,19 +37295,19 @@ msgid "Vulnerability|Identifiers"
msgstr ""
msgid "Vulnerability|Image"
-msgstr ""
+msgstr "Billede"
msgid "Vulnerability|Links"
msgstr ""
msgid "Vulnerability|Method"
-msgstr ""
+msgstr "Metode"
msgid "Vulnerability|Namespace"
-msgstr ""
+msgstr "Navnerum"
msgid "Vulnerability|Project"
-msgstr ""
+msgstr "Projekt"
msgid "Vulnerability|Reproduction Assets"
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36990,16 +37325,19 @@ msgid "Vulnerability|Severity"
msgstr ""
msgid "Vulnerability|Status"
-msgstr ""
+msgstr "Status"
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
msgid "WARNING:"
-msgstr ""
+msgstr "ADVARSEL:"
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -37014,10 +37352,10 @@ msgid "Want to see the data? Please ask an administrator for access."
msgstr ""
msgid "Warning"
-msgstr ""
+msgstr "Advarsel"
msgid "Warning:"
-msgstr ""
+msgstr "Advarsel:"
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
@@ -37062,7 +37400,7 @@ msgid "We don't have enough data to show this stage."
msgstr ""
msgid "We have found the following errors:"
-msgstr ""
+msgstr "Vi har fundet følgende fejl:"
msgid "We heard back from your device. You have been authenticated."
msgstr ""
@@ -37100,11 +37438,14 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
-msgid "We've found no vulnerabilities"
+msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We've found no vulnerabilities"
+msgstr "Vi fandt ingen sårbarheder"
+
msgid "Web IDE"
-msgstr ""
+msgstr "Web IDE"
msgid "Web Terminal"
msgstr ""
@@ -37122,7 +37463,7 @@ msgid "WebIDE|Fork project"
msgstr ""
msgid "WebIDE|Go to fork"
-msgstr ""
+msgstr "GÃ¥ til forgrening"
msgid "WebIDE|Merge request"
msgstr ""
@@ -37152,25 +37493,25 @@ msgid "WebexTeamsService|Webex Teams"
msgstr ""
msgid "Webhook"
-msgstr ""
+msgstr "Webhook"
msgid "Webhook Logs"
-msgstr ""
+msgstr "Webhook-logge"
msgid "Webhook Settings"
msgstr ""
msgid "Webhook:"
-msgstr ""
+msgstr "Webhook:"
msgid "Webhooks"
-msgstr ""
+msgstr "Webhooks"
msgid "Webhooks Help"
-msgstr ""
+msgstr "Hjælp for webhooks"
msgid "Webhooks|Comments"
-msgstr ""
+msgstr "Kommentarer"
msgid "Webhooks|Confidential comments"
msgstr ""
@@ -37221,10 +37562,10 @@ msgid "Webhooks|Tag push events"
msgstr ""
msgid "Webhooks|Trigger"
-msgstr ""
+msgstr "Udløser"
msgid "Webhooks|URL"
-msgstr ""
+msgstr "URL"
msgid "Webhooks|URL is triggered by a push to the repository"
msgstr ""
@@ -37281,31 +37622,31 @@ msgid "Webhooks|Wiki page events"
msgstr ""
msgid "Website:"
-msgstr ""
+msgstr "Websted:"
msgid "Wednesday"
-msgstr ""
+msgstr "Onsdag"
msgid "Weekday"
-msgstr ""
+msgstr "Ugedag"
msgid "Weeks"
-msgstr ""
+msgstr "Uger"
msgid "Weight"
-msgstr ""
+msgstr "Vægt"
msgid "Weight %{weight}"
-msgstr ""
+msgstr "Vægt %{weight}"
msgid "Welcome back! Your account had been deactivated due to inactivity but is now reactivated."
msgstr ""
msgid "Welcome to GitLab"
-msgstr ""
+msgstr "Velkommen til GitLab"
msgid "Welcome to GitLab, %{first_name}!"
-msgstr ""
+msgstr "Velkommen til GitLab, %{first_name}!"
msgid "Welcome to GitLab,%{br_tag}%{name}!"
msgstr ""
@@ -37314,7 +37655,7 @@ msgid "Welcome to the guided GitLab tour"
msgstr ""
msgid "Welcome, %{name}!"
-msgstr ""
+msgstr "Velkommen, %{name}!"
msgid "What are group audit events?"
msgstr ""
@@ -37329,19 +37670,19 @@ msgid "What are shared runner pipeline minutes?"
msgstr ""
msgid "What are you searching for?"
-msgstr ""
+msgstr "Hvad søger du?"
msgid "What describes you best?"
-msgstr ""
+msgstr "Hvad beskriver dig bedst?"
msgid "What does this command do?"
-msgstr ""
+msgstr "Hvad gør kommandoen?"
msgid "What is Auto DevOps?"
msgstr ""
msgid "What is Markdown?"
-msgstr ""
+msgstr "Hvad er Markdown?"
msgid "What is repository mirroring?"
msgstr ""
@@ -37353,13 +37694,16 @@ msgid "What is time tracking?"
msgstr ""
msgid "What is your job title? (optional)"
+msgstr "Hvad er din jobtitel? (valgfrit)"
+
+msgid "What will you use this group for?"
msgstr ""
msgid "What's new"
-msgstr ""
+msgstr "Nyheder"
msgid "What’s your experience level?"
-msgstr ""
+msgstr "Hvad er dit erfaringsniveau?"
msgid "When a deployment job is successful, skip older deployment jobs that are still pending."
msgstr ""
@@ -37391,19 +37735,19 @@ msgid "When using the %{code_open}http://%{code_close} or %{code_open}https://%{
msgstr ""
msgid "When:"
-msgstr ""
+msgstr "NÃ¥r:"
msgid "While it's rare to have no vulnerabilities, it can happen. In any event, we ask that you please double check your settings to make sure you've set up your dashboard correctly."
msgstr ""
msgid "Who can approve?"
-msgstr ""
+msgstr "Hvem kan godkende?"
msgid "Who can see this group?"
-msgstr ""
+msgstr "Hvem kan se gruppen?"
msgid "Who will be able to see this group?"
-msgstr ""
+msgstr "Hvem vil være i stand til at se gruppen?"
msgid "Who will be using GitLab?"
msgstr ""
@@ -37414,11 +37758,14 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
-msgid "Why are you signing up? (Optional)"
+msgid "Who will be using this group?"
msgstr ""
+msgid "Why are you signing up? (Optional)"
+msgstr "Hvorfor tilmelder du dig? (valgfrit)"
+
msgid "Wiki"
-msgstr ""
+msgstr "Wiki"
msgid "Wiki page was successfully created."
msgstr ""
@@ -37430,16 +37777,16 @@ msgid "Wiki page was successfully updated."
msgstr ""
msgid "WikiClone|Clone your wiki"
-msgstr ""
+msgstr "Klon din wiki"
msgid "WikiClone|Git Access"
-msgstr ""
+msgstr "Git-adgang"
msgid "WikiClone|Install Gollum"
-msgstr ""
+msgstr "Installer Gollum"
msgid "WikiClone|Start Gollum and edit locally"
-msgstr ""
+msgstr "Start Gollum og rediger lokalt"
msgid "WikiEdit|There is already a page with the same title in that path."
msgstr ""
@@ -37469,7 +37816,7 @@ msgid "WikiEmpty|Confluence is enabled"
msgstr ""
msgid "WikiEmpty|Create your first page"
-msgstr ""
+msgstr "Opret din første side"
msgid "WikiEmpty|Enable the Confluence Wiki integration"
msgstr ""
@@ -37487,10 +37834,10 @@ msgid "WikiEmpty|The wiki lets you write documentation for your project"
msgstr ""
msgid "WikiEmpty|This group has no wiki pages"
-msgstr ""
+msgstr "Gruppen har ingen wikisider"
msgid "WikiEmpty|This project has no wiki pages"
-msgstr ""
+msgstr "Projektet har ingen wikisider"
msgid "WikiEmpty|You must be a group member in order to add wiki pages."
msgstr ""
@@ -37502,22 +37849,22 @@ msgid "WikiEmpty|You've enabled the Confluence Workspace integration. Your wiki
msgstr ""
msgid "WikiHistoricalPage|This is an old version of this page."
-msgstr ""
+msgstr "Der findes en ældre version af siden."
msgid "WikiHistoricalPage|You can view the %{most_recent_link} or browse the %{history_link}."
-msgstr ""
+msgstr "Du kan vise %{most_recent_link} eller gennemse %{history_link}."
msgid "WikiHistoricalPage|history"
-msgstr ""
+msgstr "historik"
msgid "WikiHistoricalPage|most recent version"
-msgstr ""
+msgstr "nyeste version"
msgid "WikiPageConfirmDelete|Are you sure you want to delete this page?"
-msgstr ""
+msgstr "Er du sikker på, at du vil slette siden?"
msgid "WikiPageConfirmDelete|Delete page"
-msgstr ""
+msgstr "Slet side"
msgid "WikiPageConfirmDelete|Delete page %{pageTitle}?"
msgstr ""
@@ -37529,25 +37876,25 @@ msgid "WikiPage|An error occured while trying to render the content editor. Plea
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
-msgstr ""
+msgstr "Er du sikker på, at du vil skifte tilbage til den klassiske editor?"
msgid "WikiPage|Cancel"
-msgstr ""
+msgstr "Annuller"
msgid "WikiPage|Commit message"
-msgstr ""
+msgstr "Commit-meddelelse"
msgid "WikiPage|Content"
-msgstr ""
+msgstr "Indhold"
msgid "WikiPage|Create %{pageTitle}"
-msgstr ""
+msgstr "Opret %{pageTitle}"
msgid "WikiPage|Create page"
-msgstr ""
+msgstr "Opret side"
msgid "WikiPage|Format"
-msgstr ""
+msgstr "Format"
msgid "WikiPage|Get a richer editing experience"
msgstr ""
@@ -37556,22 +37903,22 @@ msgid "WikiPage|Keep editing"
msgstr ""
msgid "WikiPage|More Information."
-msgstr ""
+msgstr "Mere information."
msgid "WikiPage|Page title"
-msgstr ""
+msgstr "Sidetitel"
msgid "WikiPage|Retry"
-msgstr ""
+msgstr "Prøv igen"
msgid "WikiPage|Save changes"
-msgstr ""
+msgstr "Gem ændringer"
msgid "WikiPage|Switch me back to the classic editor."
msgstr ""
msgid "WikiPage|Switch to classic editor"
-msgstr ""
+msgstr "Skift til klassisk editor"
msgid "WikiPage|Switching to the classic editor will discard any changes you've made in the new editor."
msgstr ""
@@ -37586,7 +37933,7 @@ msgid "WikiPage|Tip: You can specify the full path for the new file. We will aut
msgstr ""
msgid "WikiPage|Title"
-msgstr ""
+msgstr "Titel"
msgid "WikiPage|To link to a (new) page, simply type %{linkExample}. More examples are in the %{linkStart}documentation%{linkEnd}."
msgstr ""
@@ -37595,55 +37942,55 @@ msgid "WikiPage|Try the new visual Markdown editor. Read the %{linkStart}documen
msgstr ""
msgid "WikiPage|Try this later"
-msgstr ""
+msgstr "Prøv det senere"
msgid "WikiPage|Update %{pageTitle}"
-msgstr ""
+msgstr "Opdater %{pageTitle}"
msgid "WikiPage|Use the new editor"
-msgstr ""
+msgstr "Brug den nye editor"
msgid "WikiPage|Write your content or drag files here…"
msgstr ""
msgid "Wikis"
-msgstr ""
+msgstr "Wikier"
msgid "Wiki|Create New Page"
-msgstr ""
+msgstr "Opret ny side"
msgid "Wiki|Created date"
-msgstr ""
+msgstr "Oprettelsesdato"
msgid "Wiki|Edit Page"
-msgstr ""
+msgstr "Rediger side"
msgid "Wiki|New page"
-msgstr ""
+msgstr "Ny side"
msgid "Wiki|Page history"
-msgstr ""
+msgstr "Sidehistorik"
msgid "Wiki|Page version"
-msgstr ""
+msgstr "Sideversion"
msgid "Wiki|Pages"
-msgstr ""
+msgstr "Sider"
msgid "Wiki|The sidebar failed to load. You can reload the page to try again."
msgstr ""
msgid "Wiki|Title"
-msgstr ""
+msgstr "Titel"
msgid "Wiki|View All Pages"
-msgstr ""
+msgstr "Vis alle sider"
msgid "Wiki|Wiki Pages"
-msgstr ""
+msgstr "Wikisider"
msgid "Will be created"
-msgstr ""
+msgstr "Oprettes"
msgid "Will be mapped to"
msgstr ""
@@ -37670,19 +38017,19 @@ msgid "Work in progress Limit"
msgstr ""
msgid "Would you like to create a new branch?"
-msgstr ""
+msgstr "Vil du oprette en ny gren?"
msgid "Would you like to try auto-generating a branch name?"
msgstr ""
msgid "Write"
-msgstr ""
+msgstr "Skriv"
msgid "Write a comment or drag your files here…"
msgstr ""
msgid "Write a comment…"
-msgstr ""
+msgstr "Skriv en kommentar …"
msgid "Write a description or drag your files here…"
msgstr ""
@@ -37700,31 +38047,31 @@ msgid "Wrong extern UID provided. Make sure Auth0 is configured correctly."
msgstr ""
msgid "Xcode"
-msgstr ""
+msgstr "Xcode"
msgid "YYYY-MM-DD"
-msgstr ""
+msgstr "Ã…Ã…Ã…Ã…-MM-DD"
msgid "Yes"
-msgstr ""
+msgstr "Ja"
msgid "Yes or No"
-msgstr ""
+msgstr "Ja eller nej"
msgid "Yes, add it"
msgstr ""
msgid "Yes, close issue"
-msgstr ""
+msgstr "Ja, luk problemstilling"
msgid "Yes, delete project"
-msgstr ""
+msgstr "Ja, slet projektet"
msgid "Yesterday"
-msgstr ""
+msgstr "I går"
msgid "You"
-msgstr ""
+msgstr "Dig"
msgid "You already have pending todo for this alert"
msgstr ""
@@ -37760,13 +38107,13 @@ msgid "You are going to delete %{project_full_name}. Deleted projects CANNOT be
msgstr ""
msgid "You are going to remove %{group_name}. This will also delete all of its subgroups and projects. Removed groups CANNOT be restored! Are you ABSOLUTELY sure?"
-msgstr ""
+msgstr "Du er ved at fjerne %{group_name}. Det sletter også alle dens undergrupper og projekter. Fjernede grupper kan IKKE gendannes! Er du HELT SIKKER?"
msgid "You are going to remove the fork relationship from %{project_full_name}. Are you ABSOLUTELY sure?"
msgstr ""
msgid "You are going to transfer %{project_full_name} to another namespace. Are you ABSOLUTELY sure?"
-msgstr ""
+msgstr "Du er ved at overføre %{project_full_name} til et andet navnerum. Er du HELT SIKKER?"
msgid "You are going to turn off the confidentiality. This means %{strongStart}everyone%{strongEnd} will be able to see and leave a comment on this %{issuableType}."
msgstr ""
@@ -37775,10 +38122,10 @@ msgid "You are going to turn on confidentiality. Only team members with %{strong
msgstr ""
msgid "You are not allowed to %{action} a user"
-msgstr ""
+msgstr "Du har ikke tilladelse til at %{action} en bruger"
msgid "You are not allowed to approve a user"
-msgstr ""
+msgstr "Du har ikke tilladelse til at godkende en bruger"
msgid "You are not allowed to log in using password"
msgstr ""
@@ -37787,7 +38134,7 @@ msgid "You are not allowed to push into this branch. Create another branch or op
msgstr ""
msgid "You are not allowed to reject a user"
-msgstr ""
+msgstr "Du har ikke tilladelse til at afvise en bruger"
msgid "You are not allowed to unlink your primary login account"
msgstr ""
@@ -37811,28 +38158,28 @@ msgid "You are receiving this message because you are a GitLab administrator for
msgstr ""
msgid "You are signed in to GitLab as %{user_link}"
-msgstr ""
+msgstr "Du er logget ind på GitLab som %{user_link}"
msgid "You are trying to upload something other than an image. Please upload a .png, .jpg, .jpeg, .gif, .bmp, .tiff or .ico."
-msgstr ""
+msgstr "Du prøver på at uploade noget andet end et billede. Upload venligst en .png, .jpg, .jpeg, .gif, .bmp, .tiff eller .ico."
msgid "You are using PostgreSQL %{pg_version_current}, but PostgreSQL %{pg_version_minimum} is required for this version of GitLab. Please upgrade your environment to a supported PostgreSQL version, see %{pg_requirements_url} for details."
msgstr ""
msgid "You can %{gitlabLinkStart}resolve conflicts on GitLab%{gitlabLinkEnd} or %{resolveLocallyStart}resolve it locally%{resolveLocallyEnd}."
-msgstr ""
+msgstr "Du kan %{gitlabLinkStart}løse konflikter på GitLab%{gitlabLinkEnd} eller %{resolveLocallyStart}løse det lokalt%{resolveLocallyEnd}."
msgid "You can %{resolveLocallyStart}resolve it locally%{resolveLocallyEnd}."
-msgstr ""
+msgstr "Du kan %{resolveLocallyStart}løse det lokalt%{resolveLocallyEnd}."
msgid "You can also create a project from the command line."
-msgstr ""
+msgstr "Du kan også oprette et projekt fra kommandolinjen."
msgid "You can also press Ctrl-Enter"
-msgstr ""
+msgstr "Du kan også trykke på Ctrl-Enter"
msgid "You can also press ⌘-Enter"
-msgstr ""
+msgstr "Du kan også trykke på ⌘-Enter"
msgid "You can also star a label to make it a priority label."
msgstr ""
@@ -37847,7 +38194,7 @@ msgid "You can also use project access tokens with Git to authenticate over HTTP
msgstr ""
msgid "You can always edit this later"
-msgstr ""
+msgstr "Du kan altid ændre det senere"
msgid "You can create a new %{link}."
msgstr ""
@@ -37859,7 +38206,7 @@ msgid "You can create a new Personal Access Token by visiting %{link}"
msgstr ""
msgid "You can create a new SSH key by visiting %{link}"
-msgstr ""
+msgstr "Du kan oprette en ny SSH-nøgle ved at besøge %{link}"
msgid "You can create a new one or check them in your %{pat_link_start}personal access tokens%{pat_link_end} settings."
msgstr ""
@@ -37919,7 +38266,7 @@ msgid "You can notify the app / group or a project by sending them an email noti
msgstr ""
msgid "You can now close this window."
-msgstr ""
+msgstr "Du kan nu lukke vinduet."
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -37949,7 +38296,7 @@ msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
msgid "You can recover this project until %{date}"
-msgstr ""
+msgstr "Du kan gendanne projektet indtil %{date}"
msgid "You can register runners as separate users, on separate servers, and on your local machine. Register as many runners as you want."
msgstr ""
@@ -37958,7 +38305,7 @@ msgid "You can resolve the merge conflict using either the Interactive mode, by
msgstr ""
msgid "You can see your chat accounts."
-msgstr ""
+msgstr "Du kan se dine chatkontoer."
msgid "You can set up jobs to only use runners with specific tags. Separate tags with commas."
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -37997,7 +38350,7 @@ msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fo
msgstr ""
msgid "You could not create a new trigger."
-msgstr ""
+msgstr "Du kunne ikke oprette en ny udløser."
msgid "You didn't renew your subscription for %{strong}%{namespace_name}%{strong_close} so it was downgraded to the free plan."
msgstr ""
@@ -38045,7 +38398,7 @@ msgid "You don't have any projects available."
msgstr ""
msgid "You don't have any recent searches"
-msgstr ""
+msgstr "Du har ingen seneste søgninger"
msgid "You don't have any webhooks deliveries"
msgstr ""
@@ -38075,7 +38428,7 @@ msgid "You have been granted %{member_human_access} access to project %{name}."
msgstr ""
msgid "You have been invited by %{link_to_inviter} to join %{source_name} %{strong_open}%{link_to_source}%{strong_close} as %{role}"
-msgstr ""
+msgstr "Du er blevet inviteret af %{link_to_inviter} til at deltage i %{source_name} %{strong_open}%{link_to_source}%{strong_close} som %{role}"
msgid "You have been redirected to the only result; see the %{a_start}search results%{a_end} instead."
msgstr ""
@@ -38120,18 +38473,18 @@ msgid "You have insufficient permissions to view shifts for this rotation"
msgstr ""
msgid "You have no permissions"
-msgstr ""
+msgstr "Du har ingen tilladelser"
msgid "You have not added any approvers. Start by adding users or groups."
msgstr ""
msgid "You have reached your project limit"
-msgstr ""
+msgstr "Du har nået din projektgrænse"
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38141,7 +38494,7 @@ msgid "You left the \"%{membershipable_human_name}\" %{source_type}."
msgstr ""
msgid "You may close the milestone now."
-msgstr ""
+msgstr "Du kan nu lukke milepælen."
msgid "You must be logged in to search across all of GitLab"
msgstr ""
@@ -38237,7 +38590,7 @@ msgid "You won't be able to create new projects because you have reached your pr
msgstr ""
msgid "You won't be able to pull or push repositories via %{protocol} until you %{set_password_link} on your account"
-msgstr ""
+msgstr "Du vil ikke være i stand til at bruge pull eller push på depoter via %{protocol} før du %{set_password_link} på din konto"
msgid "You'll be charged for %{true_up_link_start}users over license%{link_end} on a quarterly or annual basis, depending on the terms of your agreement."
msgstr ""
@@ -38249,16 +38602,16 @@ msgid "You'll need to use different branch names to get a valid comparison."
msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end} in %{strong_start}%{group_name}%{strong_end}."
-msgstr ""
+msgstr "Du er ved at reducere synligheden af projektet %{strong_start}%{project_name}%{strong_end} i %{strong_start}%{group_name}%{strong_end}."
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
-msgstr ""
+msgstr "Du er ved at reducere synligheden af projektet %{strong_start}%{project_name}%{strong_end}."
msgid "You're at the first commit"
-msgstr ""
+msgstr "Du er ved den første commit"
msgid "You're at the last commit"
-msgstr ""
+msgstr "Du er ved den sidste commit"
msgid "You're not allowed to %{tag_start}edit%{tag_end} files in this project directly. Please fork this project, make your changes there, and submit a merge request."
msgstr ""
@@ -38270,13 +38623,13 @@ msgid "You're not allowed to make changes to this project directly. A fork of th
msgstr ""
msgid "You're receiving this email because of your account on %{host}."
-msgstr ""
+msgstr "Du modtager e-mailen pga. din konto på %{host}."
msgid "You're receiving this email because of your account on %{host}. %{manage_notifications_link} &middot; %{help_link}"
-msgstr ""
+msgstr "Du modtager e-mailen pga. din konto på %{host}. %{manage_notifications_link} &middot; %{help_link}"
msgid "You're receiving this email because of your activity on %{host}."
-msgstr ""
+msgstr "Du modtager e-mailen pga. din aktivitet på %{host}."
msgid "You're receiving this email because you have been assigned an item on %{host}."
msgstr ""
@@ -38288,13 +38641,13 @@ msgid "You've already enabled two-factor authentication using one time password
msgstr ""
msgid "You've rejected %{user}"
-msgstr ""
+msgstr "Du har afvist %{user}"
msgid "YouTube"
-msgstr ""
+msgstr "YouTube"
msgid "YouTube URL or ID"
-msgstr ""
+msgstr "URL eller id til YouTube"
msgid "Your %{group} membership will now expire in %{days}."
msgstr ""
@@ -38327,7 +38680,7 @@ msgid "Your DevOps Report gives an overview of how you are using GitLab from a f
msgstr ""
msgid "Your GPG keys (%{count})"
-msgstr ""
+msgstr "Dine GPG-nøgler (%{count})"
msgid "Your GitLab account has been locked due to an excessive amount of unsuccessful sign in attempts. Your account will automatically unlock in %{duration} or you may click the link below to unlock now."
msgstr ""
@@ -38336,34 +38689,34 @@ msgid "Your GitLab account request has been approved!"
msgstr ""
msgid "Your GitLab group"
-msgstr ""
+msgstr "Din GitLab-gruppe"
msgid "Your Groups"
-msgstr ""
+msgstr "Dine grupper"
msgid "Your Personal Access Token was revoked"
msgstr ""
msgid "Your Projects (default)"
-msgstr ""
+msgstr "Dine projekter (standard)"
msgid "Your Projects' Activity"
-msgstr ""
+msgstr "Aktiviteter for dine projekter"
msgid "Your SSH key has expired"
-msgstr ""
+msgstr "Din SSH-nøgle er udløbet"
msgid "Your SSH key is expiring soon."
-msgstr ""
+msgstr "Din SSH-nøgle udløber snart."
msgid "Your SSH key was deleted"
-msgstr ""
+msgstr "Din SSH-nøgle blev slettet"
msgid "Your SSH keys (%{count})"
-msgstr ""
+msgstr "Dine SSH-nøgler (%{count})"
msgid "Your To-Do List"
-msgstr ""
+msgstr "Din To-Do-liste"
msgid "Your U2F device did not send a valid JSON response."
msgstr ""
@@ -38381,25 +38734,25 @@ msgid "Your access request to the %{source_type} has been withdrawn."
msgstr ""
msgid "Your account has been deactivated"
-msgstr ""
+msgstr "Din konto er blevet deaktiveret"
msgid "Your account has been deactivated by your administrator. Please log back in to reactivate your account."
msgstr ""
msgid "Your account has been deactivated. You will not be able to: "
-msgstr ""
+msgstr "Din konto er blevet deaktiveret. Du vil ikke være i stand til at: "
msgid "Your account is locked."
-msgstr ""
+msgstr "Din konto er låst."
msgid "Your account uses dedicated credentials for the \"%{group_name}\" group and can only be updated through SSO."
msgstr ""
msgid "Your action succeeded."
-msgstr ""
+msgstr "Din handling lykkedes."
msgid "Your applications (%{size})"
-msgstr ""
+msgstr "Dine programmer (%{size})"
msgid "Your authorized applications"
msgstr ""
@@ -38420,7 +38773,7 @@ msgid "Your changes have been committed. Commit %{commitId} %{commitStats}"
msgstr ""
msgid "Your changes have been saved"
-msgstr ""
+msgstr "Diner ændringer er blevet gemt"
msgid "Your changes have been successfully committed."
msgstr ""
@@ -38435,7 +38788,7 @@ msgid "Your comment could not be updated! Please check your network connection a
msgstr ""
msgid "Your comment will be discarded."
-msgstr ""
+msgstr "Din kommentar kasseres."
msgid "Your commit email is used for web based operations, such as edits and merges."
msgstr ""
@@ -38444,7 +38797,7 @@ msgid "Your dashboard has been copied. You can %{web_ide_link_start}edit it here
msgstr ""
msgid "Your dashboard has been updated. You can %{web_ide_link_start}edit it here%{web_ide_link_end}."
-msgstr ""
+msgstr "Dit betjeningspanel er blevet opdateret. Du kan %{web_ide_link_start}redigere det her%{web_ide_link_end}."
msgid "Your default notification email is used for account notifications if a %{openingTag}group-specific email address%{closingTag} is not set."
msgstr ""
@@ -38465,10 +38818,10 @@ msgid "Your file must contain a column named %{codeStart}title%{codeEnd}. A %{co
msgstr ""
msgid "Your first project"
-msgstr ""
+msgstr "Dit første projekt"
msgid "Your groups"
-msgstr ""
+msgstr "Dine grupper"
msgid "Your instance has %{remaining_user_count} users remaining of the %{total_user_count} included in your subscription. You can add more users than the number included in your license, and we will include the overage in your next bill."
msgstr ""
@@ -38483,7 +38836,7 @@ msgid "Your issues are being imported. Once finished, you'll get a confirmation
msgstr ""
msgid "Your issues will be imported in the background. Once finished, you'll get a confirmation email."
-msgstr ""
+msgstr "Dine problemstillinger vil blive importeret i baggrunden. Du får en bekræftelses e-mail når det er færdigt."
msgid "Your license does not support on-call rotations"
msgstr ""
@@ -38492,25 +38845,25 @@ msgid "Your license does not support on-call schedules"
msgstr ""
msgid "Your license is valid from"
-msgstr ""
+msgstr "Din licens er gyldig fra"
msgid "Your membership in %{group} no longer expires."
msgstr ""
msgid "Your message here"
-msgstr ""
+msgstr "Din meddelelse her"
msgid "Your name"
-msgstr ""
+msgstr "Dit navn"
msgid "Your new %{type}"
-msgstr ""
+msgstr "Din nye %{type}"
msgid "Your new SCIM token"
msgstr ""
msgid "Your new comment"
-msgstr ""
+msgstr "Din nye kommentar"
msgid "Your new personal access token has been created."
msgstr ""
@@ -38531,16 +38884,16 @@ msgid "Your personal access tokens will expire in %{days_to_expire} days or less
msgstr ""
msgid "Your primary email is used for avatar detection. You can change it in your %{openingTag}profile settings%{closingTag}."
-msgstr ""
+msgstr "Din primære e-mail bruges til registrering af avatar. Du kan ændre den i dine %{openingTag}profilindstillinger%{closingTag}."
msgid "Your profile"
-msgstr ""
+msgstr "Din profil"
msgid "Your project limit is %{limit} projects! Please contact your administrator to increase it"
msgstr ""
msgid "Your projects"
-msgstr ""
+msgstr "Dine projekter"
msgid "Your public email will be displayed on your public profile."
msgstr ""
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38570,13 +38923,13 @@ msgid "Your search didn't match any commits. Try a different query."
msgstr ""
msgid "Your search timed out"
-msgstr ""
+msgstr "Din søgning fik timeout"
msgid "Your sign-in page is %{url}."
msgstr ""
msgid "Your subscription expired!"
-msgstr ""
+msgstr "Dit abonnement udløb!"
msgid "Your subscription has been downgraded."
msgstr ""
@@ -38585,14 +38938,38 @@ msgid "Your subscription will expire in %{remaining_days}."
msgstr ""
msgid "Your username is %{username}."
+msgstr "Dit brugernavn er %{username}."
+
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
msgstr ""
-msgid "Zoom meeting added"
+msgid "ZentaoIntegration|Enter API token"
msgstr ""
-msgid "Zoom meeting removed"
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
msgstr ""
+msgid "Zoom meeting added"
+msgstr "Zoom-møde tilføjet"
+
+msgid "Zoom meeting removed"
+msgstr "Zoom-møde fjernet"
+
msgid "[No reason]"
msgstr ""
@@ -38606,33 +38983,33 @@ msgid "`start_time` should precede `end_time`"
msgstr ""
msgid "a deleted user"
-msgstr ""
+msgstr "en slettet bruger"
msgid "a design"
-msgstr ""
+msgstr "et design"
msgid "about 1 hour"
msgid_plural "about %d hours"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "cirka 1 time"
+msgstr[1] "cirka %d timer"
msgid "access:"
-msgstr ""
+msgstr "adgang:"
msgid "added"
-msgstr ""
+msgstr "tilføjet"
msgid "added %{created_at_timeago}"
-msgstr ""
+msgstr "tilføjede %{created_at_timeago}"
msgid "added %{emails}"
-msgstr ""
+msgstr "tilføjede %{emails}"
msgid "added a Zoom call to this issue"
-msgstr ""
+msgstr "tilføjede et Zoom-opkald til problemstillingen"
msgid "ago"
-msgstr ""
+msgstr "siden"
msgid "alert"
msgstr ""
@@ -38650,10 +39027,10 @@ msgid "already has a \"created\" issue link"
msgstr ""
msgid "already shared with this group"
-msgstr ""
+msgstr "allerede delt med gruppen"
msgid "and"
-msgstr ""
+msgstr "og"
msgid "any-approver for the merge request already exists"
msgstr ""
@@ -38662,43 +39039,48 @@ msgid "any-approver for the project already exists"
msgstr ""
msgid "approved by: "
-msgstr ""
+msgstr "godkendt af: "
msgid "archived"
-msgstr ""
+msgstr "arkiveret"
msgid "archived:"
-msgstr ""
+msgstr "arkiveret:"
msgid "assign yourself"
-msgstr ""
+msgstr "tildel dig selv"
msgid "at"
-msgstr ""
+msgstr "klokken"
msgid "at risk"
msgstr ""
msgid "attach a new file"
-msgstr ""
+msgstr "vedhæft en ny fil"
msgid "authored"
-msgstr ""
+msgstr "forfattede"
msgid "banned user already exists"
-msgstr ""
+msgstr "udelukket bruger findes allerede"
msgid "blocks"
-msgstr ""
+msgstr "blokerer"
+
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
msgid "branch name"
-msgstr ""
+msgstr "grennavn"
msgid "by"
-msgstr ""
+msgstr "af"
msgid "cURL:"
-msgstr ""
+msgstr "cURL:"
msgid "can contain only letters of the Base64 alphabet (RFC4648) with the addition of '@', ':' and '.'"
msgstr ""
@@ -38722,7 +39104,7 @@ msgid "cannot be a date in the past"
msgstr ""
msgid "cannot be changed"
-msgstr ""
+msgstr "må ikke ændres"
msgid "cannot be changed if a personal project has container registry tags."
msgstr ""
@@ -38743,10 +39125,10 @@ msgid "cannot be enabled until a valid credit card is on file"
msgstr ""
msgid "cannot be modified"
-msgstr ""
+msgstr "kan ikke ændres"
msgid "cannot block others"
-msgstr ""
+msgstr "må ikke blokere andre"
msgid "cannot contain HTML/XML tags, including any word between angle brackets (&lt;,&gt;)."
msgstr ""
@@ -38755,10 +39137,10 @@ msgid "cannot include leading slash or directory traversal."
msgstr ""
msgid "cannot itself be blocked"
-msgstr ""
+msgstr "må ikke selv blokeres"
msgid "cannot merge"
-msgstr ""
+msgstr "kan ikke sammenlægge"
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -38776,13 +39158,13 @@ msgid "ciReport|%{linkStartTag}Learn more about Coverage Fuzzing %{linkEndTag}"
msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about DAST %{linkEndTag}"
-msgstr ""
+msgstr "%{linkStartTag}Lær mere om DAST %{linkEndTag}"
msgid "ciReport|%{linkStartTag}Learn more about Dependency Scanning %{linkEndTag}"
msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about SAST %{linkEndTag}"
-msgstr ""
+msgstr "%{linkStartTag}Lær mere om SAST %{linkEndTag}"
msgid "ciReport|%{linkStartTag}Learn more about Secret Detection %{linkEndTag}"
msgstr ""
@@ -38791,10 +39173,10 @@ msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
-msgstr ""
+msgstr "%{remainingPackagesCount} mere"
msgid "ciReport|%{reportType} is loading"
-msgstr ""
+msgstr "%{reportType} indlæses"
msgid "ciReport|%{reportType}: Loading resulted in an error"
msgstr ""
@@ -38812,12 +39194,12 @@ msgid "ciReport|API fuzzing"
msgstr ""
msgid "ciReport|All projects"
-msgstr ""
-
-msgid "ciReport|All scanners"
-msgstr ""
+msgstr "Alle projekter"
msgid "ciReport|All severities"
+msgstr "Alle alvorligheder"
+
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -38839,16 +39221,16 @@ msgid "ciReport|Cluster Image Scanning"
msgstr ""
msgid "ciReport|Code quality"
-msgstr ""
+msgstr "Kodekvalitet"
msgid "ciReport|Container Scanning"
-msgstr ""
+msgstr "Beholderskanning"
msgid "ciReport|Container scanning"
-msgstr ""
+msgstr "Beholderskanning"
msgid "ciReport|Container scanning detects known vulnerabilities in your docker images."
-msgstr ""
+msgstr "Beholderskanning registrerede kendte sårbarheder i dine docker-aftryk."
msgid "ciReport|Could not dismiss vulnerability because the associated pipeline no longer exists. Refresh the page and try again."
msgstr ""
@@ -38860,16 +39242,16 @@ msgid "ciReport|Coverage fuzzing"
msgstr ""
msgid "ciReport|Create Jira issue"
-msgstr ""
+msgstr "Opret Jira-problemstilling"
msgid "ciReport|Create a merge request to implement this solution, or download and apply the patch manually."
msgstr ""
msgid "ciReport|Create issue"
-msgstr ""
+msgstr "Opret problemstilling"
msgid "ciReport|DAST"
-msgstr ""
+msgstr "DAST"
msgid "ciReport|Dependency Scanning"
msgstr ""
@@ -38878,7 +39260,7 @@ msgid "ciReport|Dependency Scanning detects known vulnerabilities in your source
msgstr ""
msgid "ciReport|Dependency scanning"
-msgstr ""
+msgstr "Afhængighedsskanning"
msgid "ciReport|Download patch to resolve"
msgstr ""
@@ -38899,7 +39281,7 @@ msgid "ciReport|Fixed:"
msgstr ""
msgid "ciReport|Found %{issuesWithCount}"
-msgstr ""
+msgstr "Fandt %{issuesWithCount}"
msgid "ciReport|Investigate this vulnerability by creating an issue"
msgstr ""
@@ -38914,7 +39296,7 @@ msgid "ciReport|Loading %{reportName} report"
msgstr ""
msgid "ciReport|Manage licenses"
-msgstr ""
+msgstr "HÃ¥ndter licenser"
msgid "ciReport|New"
msgstr ""
@@ -38926,13 +39308,13 @@ msgid "ciReport|No code quality issues found"
msgstr ""
msgid "ciReport|RPS"
-msgstr ""
+msgstr "RPS"
msgid "ciReport|Resolve with merge request"
msgstr ""
msgid "ciReport|SAST"
-msgstr ""
+msgstr "SAST"
msgid "ciReport|Secret Detection"
msgstr ""
@@ -38944,34 +39326,34 @@ msgid "ciReport|Secret scanning detects secrets and credentials vulnerabilities
msgstr ""
msgid "ciReport|Security scanning"
-msgstr ""
+msgstr "Sikkerhedsskanning"
msgid "ciReport|Security scanning failed loading any results"
msgstr ""
msgid "ciReport|Solution"
-msgstr ""
+msgstr "Løsning"
msgid "ciReport|Static Application Security Testing (SAST) detects known vulnerabilities in your source code."
msgstr ""
msgid "ciReport|TTFB P90"
-msgstr ""
+msgstr "TTFB P90"
msgid "ciReport|TTFB P95"
-msgstr ""
+msgstr "TTFB P95"
msgid "ciReport|There was an error creating the issue. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl ved oprettelse af problemstillingen. Prøv venligst igen."
msgid "ciReport|There was an error creating the merge request. Please try again."
-msgstr ""
+msgstr "Der opstod en fejl ved oprettelse af sammenlægningsanmodningen. Prøv venligst igen."
msgid "ciReport|There was an error dismissing the vulnerability. Please try again."
msgstr ""
msgid "ciReport|There was an error fetching the codequality report."
-msgstr ""
+msgstr "Der opstod en fejl ved hentning af kodekvalitetsrapporten."
msgid "ciReport|There was an error reverting the dismissal. Please try again."
msgstr ""
@@ -38981,23 +39363,23 @@ msgstr ""
msgid "ciReport|Used by %{packagesString}"
msgid_plural "ciReport|Used by %{packagesString}, and %{lastPackage}"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Brugt af %{packagesString}"
+msgstr[1] "Brugt af %{packagesString} og %{lastPackage}"
msgid "ciReport|View full report"
msgstr ""
msgid "ciReport|is loading"
-msgstr ""
+msgstr "indlæser"
msgid "ciReport|is loading, errors when loading results"
msgstr ""
msgid "closed"
-msgstr ""
+msgstr "lukket"
msgid "closed issue"
-msgstr ""
+msgstr "lukket problemstilling"
msgid "codeQualityWalkthrough|A code quality job will now run every time you or your team members commit changes to your project. You can view the results of the code quality job in the job logs."
msgstr ""
@@ -39042,7 +39424,7 @@ msgid "collect usage information"
msgstr ""
msgid "comment"
-msgstr ""
+msgstr "kommentar"
msgid "commented on %{link_to_project}"
msgstr ""
@@ -39051,7 +39433,7 @@ msgid "commit %{commit_id}"
msgstr ""
msgid "committed"
-msgstr ""
+msgstr "committed"
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -39060,86 +39442,86 @@ msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
msgid "contribute to this project."
-msgstr ""
+msgstr "bidrag til projektet."
msgid "could not read private key, is the passphrase correct?"
msgstr ""
msgid "created"
-msgstr ""
+msgstr "oprettet"
msgid "created %{issuable_created} by %{author}"
msgstr ""
msgid "created %{timeAgoString} by %{email} via %{user}"
-msgstr ""
+msgstr "oprettet %{timeAgoString} af %{email} via %{user}"
msgid "created %{timeAgoString} by %{user}"
-msgstr ""
+msgstr "oprettet %{timeAgoString} af %{user}"
msgid "created %{timeAgoString} by %{user} in Jira"
-msgstr ""
+msgstr "oprettet %{timeAgoString} af %{user} i Jira"
msgid "created %{timeAgo}"
msgstr ""
msgid "created by"
-msgstr ""
+msgstr "oprettet af"
msgid "data"
-msgstr ""
+msgstr "data"
msgid "date must not be after 9999-12-31"
-msgstr ""
+msgstr "datoen må ikke være efter 9999-12-31"
msgid "day"
msgid_plural "days"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "dag"
+msgstr[1] "dage"
msgid "days"
-msgstr ""
+msgstr "dage"
msgid "default branch"
-msgstr ""
+msgstr "standardgren"
msgid "deleted"
-msgstr ""
+msgstr "slettet"
msgid "deploy"
-msgstr ""
+msgstr "udsend"
msgid "design"
-msgstr ""
+msgstr "design"
msgid "designs"
-msgstr ""
+msgstr "designs"
msgid "detached"
msgstr ""
msgid "disabled"
-msgstr ""
+msgstr "deaktiveret"
msgid "does not exist"
-msgstr ""
+msgstr "findes ikke"
msgid "does not have a supported extension. Only %{extension_list} are supported"
msgstr ""
msgid "domain is not authorized for sign-up."
-msgstr ""
+msgstr "domænet er ikke godkendt til tilmelding."
msgid "download it"
msgstr ""
msgid "draft"
msgid_plural "drafts"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "udkast"
+msgstr[1] "udkast"
msgid "e.g. %{token}"
-msgstr ""
+msgstr "f.eks. %{token}"
msgid "element is not a hierarchy"
msgstr ""
@@ -39149,11 +39531,11 @@ msgstr ""
msgid "email does not match the allowed domain of %{email_domains}"
msgid_plural "email does not match the allowed domains: %{email_domains}"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "e-mailen passer ikke med det tilladte domæne i %{email_domains}"
+msgstr[1] "e-mailen passer ikke med de tilladte domæner: %{email_domains}"
msgid "enabled"
-msgstr ""
+msgstr "aktiveret"
msgid "encrypted: needs to be a :required, :optional or :migrating!"
msgstr ""
@@ -39170,29 +39552,32 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
-msgid "epic"
+msgid "environment_id parameter is required when type is container_policy"
msgstr ""
+msgid "epic"
+msgstr "epic"
+
msgid "error"
-msgstr ""
+msgstr "fejl"
msgid "estimateCommand|%{slash_command} overwrites the total estimated time."
msgstr ""
msgid "exceeds the limit of %{bytes} bytes"
-msgstr ""
+msgstr "overstiger grænsen på %{bytes} byte"
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
-msgstr ""
+msgstr "overstiger grænsen på %{bytes} byte for mappenavnet \"%{dirname}\""
msgid "expired on %{timebox_due_date}"
-msgstr ""
+msgstr "udløb %{timebox_due_date}"
msgid "expires on %{timebox_due_date}"
-msgstr ""
+msgstr "udløber %{timebox_due_date}"
msgid "failed"
-msgstr ""
+msgstr "mislykkedes"
msgid "failed to dismiss associated finding(id=%{finding_id}): %{message}"
msgstr ""
@@ -39202,61 +39587,61 @@ msgstr ""
msgid "file"
msgid_plural "files"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "fil"
+msgstr[1] "filer"
msgid "finding is not found or is already attached to a vulnerability"
msgstr ""
msgid "following"
-msgstr ""
+msgstr "følger"
msgid "for %{link_to_merge_request} with %{link_to_merge_request_source_branch}"
-msgstr ""
+msgstr "for %{link_to_merge_request} med %{link_to_merge_request_source_branch}"
msgid "for %{link_to_merge_request} with %{link_to_merge_request_source_branch} into %{link_to_merge_request_target_branch}"
-msgstr ""
+msgstr "for %{link_to_merge_request} med %{link_to_merge_request_source_branch} i %{link_to_merge_request_target_branch}"
msgid "for %{link_to_pipeline_ref}"
-msgstr ""
+msgstr "for %{link_to_pipeline_ref}"
msgid "for %{ref}"
-msgstr ""
+msgstr "for %{ref}"
msgid "for this project"
-msgstr ""
+msgstr "for projektet"
msgid "fork"
msgstr ""
msgid "fork this project"
-msgstr ""
+msgstr "forgren projektet"
msgid "from"
-msgstr ""
+msgstr "fra"
msgid "from %d job"
msgid_plural "from %d jobs"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "fra %d job"
+msgstr[1] "fra %d job"
msgid "group"
-msgstr ""
+msgstr "gruppe"
msgid "group members"
-msgstr ""
+msgstr "gruppemedlemmer"
msgid "group's CI/CD settings."
-msgstr ""
+msgstr "gruppens CI-/CD-indstillinger."
msgid "groups"
-msgstr ""
+msgstr "grupper"
msgid "has already been linked to another vulnerability"
msgstr ""
msgid "has already been taken"
-msgstr ""
+msgstr "er allerede taget"
msgid "has already been taken as Codename"
msgstr ""
@@ -39265,25 +39650,25 @@ msgid "has already been taken as Suite"
msgstr ""
msgid "has been completed."
-msgstr ""
+msgstr "er fuldført."
msgid "help"
-msgstr ""
+msgstr "hjælp"
msgid "http:"
-msgstr ""
+msgstr "http:"
msgid "http://www.example.com"
-msgstr ""
+msgstr "http://www.example.com"
msgid "https://bamboo.example.com"
-msgstr ""
+msgstr "https://bamboo.example.com"
msgid "https://your-bitbucket-server"
-msgstr ""
+msgstr "https://din-bitbucket-server"
msgid "i18n|%{language} (%{percent_translated}%% translated)"
-msgstr ""
+msgstr "%{language} (%{percent_translated}%% oversat)"
msgid "image diff"
msgstr ""
@@ -39298,24 +39683,24 @@ msgid "import flow"
msgstr ""
msgid "in"
-msgstr ""
+msgstr "i"
msgid "in group %{link_to_group}"
-msgstr ""
+msgstr "i gruppen %{link_to_group}"
msgid "in project %{link_to_project}"
-msgstr ""
+msgstr "i projektet %{link_to_project}"
msgid "instance completed"
msgid_plural "instances completed"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "instans fuldført"
+msgstr[1] "instanser fuldført"
msgid "invalid milestone state `%{state}`"
msgstr ""
msgid "is"
-msgstr ""
+msgstr "er"
msgid "is already associated to a GitLab Issue. New issue will not be associated."
msgstr ""
@@ -39324,7 +39709,7 @@ msgid "is an invalid IP address range"
msgstr ""
msgid "is blocked by"
-msgstr ""
+msgstr "er blokeret af"
msgid "is forbidden by a top-level group"
msgstr ""
@@ -39336,13 +39721,13 @@ msgid "is invalid because there is upstream lock"
msgstr ""
msgid "is not"
-msgstr ""
+msgstr "er ikke"
msgid "is not a descendant of the Group owning the template"
msgstr ""
msgid "is not a valid X509 certificate."
-msgstr ""
+msgstr "er ikke et gyldigt X509-certifikat."
msgid "is not allowed since the group is not top-level group."
msgstr ""
@@ -39353,11 +39738,8 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
-msgstr ""
+msgstr "er ikke fra et tilladt domæne."
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
@@ -39366,7 +39748,7 @@ msgid "is not valid. The iteration group has to match the iteration cadence grou
msgstr ""
msgid "is read-only"
-msgstr ""
+msgstr "er skrivebeskyttet"
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -39381,7 +39763,7 @@ msgid "is too long (maximum is 1000 entries)"
msgstr ""
msgid "issue"
-msgstr ""
+msgstr "problemstilling"
msgid "issues at risk"
msgstr ""
@@ -39414,40 +39796,40 @@ msgid "kuromoji custom analyzer"
msgstr ""
msgid "last commit:"
-msgstr ""
+msgstr "sidste commit:"
msgid "latest"
-msgstr ""
+msgstr "seneste"
msgid "latest deployment"
-msgstr ""
+msgstr "seneste udsendelse"
msgid "latest version"
-msgstr ""
+msgstr "seneste version"
msgid "leave %{group_name}"
-msgstr ""
+msgstr "forlad %{group_name}"
msgid "less than a minute"
-msgstr ""
+msgstr "mindre end et minut"
msgid "level: %{level}"
-msgstr ""
+msgstr "niveau: %{level}"
msgid "limit of %{project_limit} reached"
msgstr ""
msgid "load it anyway"
-msgstr ""
+msgstr "indlæs det alligevel"
msgid "loading"
-msgstr ""
+msgstr "indlæser"
msgid "locked by %{path_lock_user_name} %{created_at}"
-msgstr ""
+msgstr "låst af %{path_lock_user_name} %{created_at}"
msgid "log in"
-msgstr ""
+msgstr "log ind"
msgid "manual"
msgstr ""
@@ -39460,8 +39842,8 @@ msgstr ""
msgid "merge request"
msgid_plural "merge requests"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "sammenlægningsanmodning"
+msgstr[1] "sammenlægningsanmodninger"
msgid "merged %{timeAgo}"
msgstr ""
@@ -39470,10 +39852,10 @@ msgid "metric_id must be unique across a project"
msgstr ""
msgid "missing"
-msgstr ""
+msgstr "mangler"
msgid "more information"
-msgstr ""
+msgstr "mere information"
msgid "most recent deployment"
msgstr ""
@@ -39497,10 +39879,10 @@ msgid "mrWidget| Please restore it or use a different %{missingBranchName} branc
msgstr ""
msgid "mrWidget|%{mergeError}."
-msgstr ""
+msgstr "%{mergeError}."
msgid "mrWidget|%{mergeError}. Try again."
-msgstr ""
+msgstr "%{mergeError}. Prøv igen."
msgid "mrWidget|%{metricsLinkStart} Memory %{metricsLinkEnd} usage %{emphasisStart} decreased %{emphasisEnd} from %{memoryFrom}MB to %{memoryTo}MB"
msgstr ""
@@ -39539,13 +39921,13 @@ msgid "mrWidget|Approval password is invalid."
msgstr ""
msgid "mrWidget|Approve"
-msgstr ""
+msgstr "Godkend"
msgid "mrWidget|Approve additionally"
-msgstr ""
+msgstr "Godkend yderligere"
msgid "mrWidget|Approved by"
-msgstr ""
+msgstr "Godkendt af"
msgid "mrWidget|Are you adding technical debt or code vulnerabilities?"
msgstr ""
@@ -39566,22 +39948,24 @@ msgid "mrWidget|Cherry-pick this merge request in a new merge request"
msgstr ""
msgid "mrWidget|Closed"
-msgstr ""
+msgstr "Lukket"
msgid "mrWidget|Closed by"
-msgstr ""
+msgstr "Lukket af"
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
-msgstr ""
+msgstr "Slet kildegren"
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
msgid "mrWidget|Did not close"
-msgstr ""
+msgstr "Lukkede ikke"
msgid "mrWidget|Email patches"
msgstr ""
@@ -39602,16 +39986,18 @@ msgid "mrWidget|Loading deployment statistics"
msgstr ""
msgid "mrWidget|Mark as ready"
-msgstr ""
+msgstr "Mærk som klar"
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
-msgstr ""
+msgstr "Sammenlæg"
msgid "mrWidget|Merge blocked: all threads must be resolved."
msgstr ""
@@ -39626,13 +40012,13 @@ msgid "mrWidget|Merge failed."
msgstr ""
msgid "mrWidget|Merge locally"
-msgstr ""
+msgstr "Sammenlæg lokalt"
msgid "mrWidget|Merge request approved."
msgstr ""
msgid "mrWidget|Merged by"
-msgstr ""
+msgstr "Sammenlagt af"
msgid "mrWidget|Merging! Changes are being shipped…"
msgstr ""
@@ -39653,10 +40039,13 @@ msgid "mrWidget|Merging! We're almost there…"
msgstr ""
msgid "mrWidget|More information"
+msgstr "Mere information"
+
+msgid "mrWidget|Open in Gitpod"
msgstr ""
msgid "mrWidget|Open in Web IDE"
-msgstr ""
+msgstr "Ã…bn i Web IDE"
msgid "mrWidget|Plain diff"
msgstr ""
@@ -39665,13 +40054,13 @@ msgid "mrWidget|Ready to be merged automatically. Ask someone with write access
msgstr ""
msgid "mrWidget|Refresh"
-msgstr ""
+msgstr "Opdater"
msgid "mrWidget|Refresh now"
-msgstr ""
+msgstr "Opdater nu"
msgid "mrWidget|Refreshing now"
-msgstr ""
+msgstr "Opdaterer nu"
msgid "mrWidget|Remove from merge train"
msgstr ""
@@ -39683,19 +40072,19 @@ msgid "mrWidget|Resolve all threads in new issue"
msgstr ""
msgid "mrWidget|Resolve conflicts"
-msgstr ""
+msgstr "Løs konflikter"
msgid "mrWidget|Resolve these conflicts or ask someone with write access to this repository to merge it locally"
msgstr ""
msgid "mrWidget|Revert"
-msgstr ""
+msgstr "Tilbagefør"
msgid "mrWidget|Revert this merge request in a new merge request"
msgstr ""
msgid "mrWidget|Revoke approval"
-msgstr ""
+msgstr "Tilbagekald godkendelse"
msgid "mrWidget|Set by %{merge_author} to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -39718,23 +40107,20 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
-msgstr ""
+msgstr "Kildegrenen er blevet slettet"
msgid "mrWidget|The source branch is %{link} the target branch"
msgstr ""
msgid "mrWidget|The source branch is being deleted"
-msgstr ""
+msgstr "Kildegrenen er ved at blive slettet"
msgid "mrWidget|The source branch will be deleted"
-msgstr ""
+msgstr "Kildegrenen vil blive slettet"
msgid "mrWidget|The source branch will not be deleted"
-msgstr ""
+msgstr "Kildegrenen vil ikke blive slettet"
msgid "mrWidget|There are merge conflicts"
msgstr ""
@@ -39760,107 +40146,110 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
msgid "mrWidget|Your password"
-msgstr ""
+msgstr "Din adgangskode"
msgid "mrWidget|branch does not exist."
-msgstr ""
+msgstr "Grenen findes ikke."
msgid "mrWidget|into"
msgstr ""
msgid "must be a Debian package"
-msgstr ""
+msgstr "skal være en Debian-pakke"
msgid "must be a boolean value"
-msgstr ""
+msgstr "skal være en boolesk værdi"
msgid "must be a root namespace"
-msgstr ""
+msgstr "skal være et rodnavneområde"
msgid "must be a valid IPv4 or IPv6 address"
-msgstr ""
+msgstr "skal være en gyldig IPv4- eller IPv6-adresse"
msgid "must be after start"
+msgstr "skal være efter start"
+
+msgid "must be an email you have verified"
msgstr ""
msgid "must be greater than start date"
-msgstr ""
+msgstr "skal være større end startdato"
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
msgid "my-awesome-group"
-msgstr ""
+msgstr "min-fantastiske-gruppe"
msgid "my-channel"
msgstr ""
msgid "n/a"
-msgstr ""
+msgstr "—"
msgid "need attention"
msgstr ""
msgid "needs to be between 10 minutes and 1 month"
-msgstr ""
+msgstr "skal være fra 10 minutter til 1 måned"
msgid "never"
-msgstr ""
+msgstr "aldrig"
msgid "never expires"
-msgstr ""
+msgstr "udløber aldrig"
msgid "new merge request"
-msgstr ""
+msgstr "ny sammenlægningsanmodning"
msgid "no approvers"
-msgstr ""
+msgstr "ingen godkendere"
msgid "no expiration"
-msgstr ""
+msgstr "ingen undtagelse"
msgid "no name set"
-msgstr ""
+msgstr "intet navn indstillet"
msgid "no one can merge"
-msgstr ""
+msgstr "ingen kan sammenlægge"
msgid "no scopes selected"
-msgstr ""
+msgstr "ingen omfang valgt"
msgid "none"
-msgstr ""
+msgstr "ingen"
msgid "not found"
-msgstr ""
+msgstr "ikke fundet"
msgid "nounSeries|%{firstItem} and %{lastItem}"
-msgstr ""
+msgstr "%{firstItem} og %{lastItem}"
msgid "nounSeries|%{item}"
-msgstr ""
+msgstr "%{item}"
msgid "nounSeries|%{item}, %{nextItem}"
-msgstr ""
+msgstr "%{item}, %{nextItem}"
msgid "nounSeries|%{item}, and %{lastItem}"
-msgstr ""
+msgstr "%{item} og %{lastItem}"
msgid "on track"
msgstr ""
msgid "only available on top-level groups."
-msgstr ""
+msgstr "kun tilgængelig på topniveaugrupper."
msgid "open issue"
msgstr ""
@@ -39869,15 +40258,15 @@ msgid "opened %{timeAgo}"
msgstr ""
msgid "or"
-msgstr ""
+msgstr "eller"
msgid "originating vulnerability"
msgstr ""
msgid "out of %d total test"
msgid_plural "out of %d total tests"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "ud af %d test i alt"
+msgstr[1] "ud af %d tests i alt"
msgid "parent"
msgid_plural "parents"
@@ -39885,25 +40274,25 @@ msgstr[0] ""
msgstr[1] ""
msgid "password"
-msgstr ""
+msgstr "adgangskode"
msgid "pending comment"
-msgstr ""
+msgstr "afventende kommentar"
msgid "pending deletion"
-msgstr ""
+msgstr "afventende sletning"
msgid "per day"
-msgstr ""
+msgstr "pr. dag"
msgid "personal access token"
-msgstr ""
+msgstr "personlig adgangstoken"
msgid "personal access tokens"
-msgstr ""
+msgstr "personlige adgangstokens"
msgid "pipeline"
-msgstr ""
+msgstr "pipeline"
msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -39913,25 +40302,25 @@ msgstr ""
msgid "point"
msgid_plural "points"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "point"
+msgstr[1] "point"
msgid "previously merged commits"
msgstr ""
msgid "private"
-msgstr ""
+msgstr "privat"
msgid "private key does not match certificate."
-msgstr ""
+msgstr "privat nøgle passer ikke med certifikat."
msgid "processing"
-msgstr ""
+msgstr "behandler"
msgid "project"
msgid_plural "projects"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "projekt"
+msgstr[1] "projekter"
msgid "project access token"
msgstr ""
@@ -39946,19 +40335,19 @@ msgid "project bots cannot be added to other groups / projects"
msgstr ""
msgid "project is read-only"
-msgstr ""
+msgstr "projektet er skrivebeskyttet"
msgid "project members"
-msgstr ""
+msgstr "projektmedlemmer"
msgid "project name"
-msgstr ""
+msgstr "projektnavn"
msgid "projects"
-msgstr ""
+msgstr "projekter"
msgid "quick actions"
-msgstr ""
+msgstr "hurtige handlinger"
msgid "reCAPTCHA Private Key"
msgstr ""
@@ -39967,54 +40356,54 @@ msgid "reCAPTCHA Site Key"
msgstr ""
msgid "recent activity"
-msgstr ""
+msgstr "seneste aktivitet"
msgid "register"
-msgstr ""
+msgstr "tilmeld"
msgid "relates to"
msgstr ""
msgid "remaining"
-msgstr ""
+msgstr "tilbage"
msgid "remove"
-msgstr ""
+msgstr "fjern"
msgid "remove due date"
-msgstr ""
+msgstr "fjern forfaldsdato"
msgid "remove start date"
-msgstr ""
+msgstr "fjern startdato"
msgid "remove weight"
-msgstr ""
+msgstr "fjern vægt"
msgid "removed"
-msgstr ""
+msgstr "fjernet"
msgid "removed a Zoom call from this issue"
-msgstr ""
+msgstr "fjernede et Zoom-opkald fra problemstillingen"
msgid "rendered diff"
msgstr ""
msgid "reply"
msgid_plural "replies"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "svar"
+msgstr[1] "svar"
msgid "repository:"
-msgstr ""
+msgstr "depot:"
msgid "required"
-msgstr ""
+msgstr "kræves"
msgid "reset it."
msgstr ""
msgid "satisfied"
-msgstr ""
+msgstr "tilfreds"
msgid "scan-execution-policy: policy not applied, %{policy_path} file is invalid"
msgstr ""
@@ -40023,37 +40412,37 @@ msgid "scan-execution-policy: policy not applied, %{policy_path} file is missing
msgstr ""
msgid "security Reports|There was an error creating the merge request"
-msgstr ""
+msgstr "Der opstod en fejl ved oprettelse af sammenlægningsanmodningen"
msgid "severity|Blocker"
msgstr ""
msgid "severity|Critical"
-msgstr ""
+msgstr "Kritisk"
msgid "severity|High"
-msgstr ""
+msgstr "Høj"
msgid "severity|Info"
-msgstr ""
+msgstr "Information"
msgid "severity|Low"
-msgstr ""
+msgstr "Lav"
msgid "severity|Major"
-msgstr ""
+msgstr "Større"
msgid "severity|Medium"
-msgstr ""
+msgstr "Mellem"
msgid "severity|Minor"
-msgstr ""
+msgstr "Mindre"
msgid "severity|None"
-msgstr ""
+msgstr "Ingen"
msgid "severity|Unknown"
-msgstr ""
+msgstr "Ukendt"
msgid "should be an array of %{object_name} objects"
msgstr ""
@@ -40062,25 +40451,25 @@ msgid "should be greater than or equal to %{access} inherited membership from gr
msgstr ""
msgid "show %{count} more"
-msgstr ""
+msgstr "vis %{count} mere"
msgid "show fewer"
-msgstr ""
+msgstr "vis færre"
msgid "show less"
-msgstr ""
+msgstr "vis mindre"
msgid "sign in"
-msgstr ""
+msgstr "log ind"
msgid "smartcn custom analyzer"
msgstr ""
msgid "sort:"
-msgstr ""
+msgstr "sortér:"
msgid "source"
-msgstr ""
+msgstr "kilde"
msgid "source diff"
msgstr ""
@@ -40092,7 +40481,7 @@ msgid "spendCommand|%{slash_command} adds or subtracts time already spent."
msgstr ""
msgid "ssh:"
-msgstr ""
+msgstr "ssh:"
msgid "started a discussion on %{design_link}"
msgstr ""
@@ -40107,10 +40496,10 @@ msgid "stuck"
msgstr ""
msgid "success"
-msgstr ""
+msgstr "lykkedes"
msgid "suggestPipeline|1/2: Choose a template"
-msgstr ""
+msgstr "1/2: Vælg en skabelon"
msgid "suggestPipeline|2/2: Commit your changes"
msgstr ""
@@ -40125,25 +40514,25 @@ msgid "suggestPipeline|We’re adding a GitLab CI configuration file to add a pi
msgstr ""
msgid "tag name"
-msgstr ""
+msgstr "mærkatnavn"
msgid "the correct format."
-msgstr ""
+msgstr "det korrekte format."
msgid "the file"
-msgstr ""
+msgstr "filen"
msgid "the following issue(s)"
-msgstr ""
+msgstr "følgende problemstillinger"
msgid "the wiki"
-msgstr ""
+msgstr "wikien"
msgid "then"
msgstr ""
msgid "this document"
-msgstr ""
+msgstr "dokumentet"
msgid "this issue cannot be assigned to a confidential epic since it is public"
msgstr ""
@@ -40155,49 +40544,49 @@ msgid "time summary"
msgstr ""
msgid "toggle collapse"
-msgstr ""
+msgstr "sammenfold til/fra"
msgid "train"
msgstr ""
msgid "triggered"
-msgstr ""
+msgstr "udløst"
msgid "two-factor authentication settings"
-msgstr ""
+msgstr "indstillinger for tofaktorgodkendelse"
msgid "type must be Debian"
-msgstr ""
+msgstr "Typen skal være Debian"
msgid "type parameter is missing and is required"
-msgstr ""
+msgstr "parameteren type mangler og kræves"
msgid "unicode domains should use IDNA encoding"
msgstr ""
msgid "updated"
-msgstr ""
+msgstr "opdateret"
msgid "updated %{timeAgo}"
-msgstr ""
+msgstr "opdateret %{timeAgo}"
msgid "updated %{time_ago}"
-msgstr ""
+msgstr "opdateret %{time_ago}"
msgid "uploads"
-msgstr ""
+msgstr "uploads"
msgid "user avatar"
-msgstr ""
+msgstr "brugeravatar"
msgid "user preferences"
-msgstr ""
+msgstr "brugerpræferencer"
msgid "username"
-msgstr ""
+msgstr "brugernavn"
msgid "v%{version} published %{timeAgo}"
-msgstr ""
+msgstr "v%{version} udgivet %{timeAgo}"
msgid "value for '%{storage}' must be an integer"
msgstr ""
@@ -40206,42 +40595,42 @@ msgid "value for '%{storage}' must be between 0 and 100"
msgstr ""
msgid "verify ownership"
-msgstr ""
+msgstr "bekræft ejerskab"
msgid "version %{versionIndex}"
-msgstr ""
+msgstr "version %{versionIndex}"
msgid "via %{closed_via}"
-msgstr ""
+msgstr "via %{closed_via}"
msgid "via merge request %{link}"
msgstr ""
msgid "view it on GitLab"
-msgstr ""
+msgstr "vis på GitLab"
msgid "view the blob"
-msgstr ""
+msgstr "vis blob'en"
msgid "view the source"
-msgstr ""
+msgstr "vis kilden"
msgid "visibility"
-msgstr ""
+msgstr "synlighed"
msgid "vulnerability"
msgid_plural "vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "sårbarhed"
+msgstr[1] "sårbarheder"
msgid "vulnerability|Add a comment"
-msgstr ""
+msgstr "Tilføj en kommentar"
msgid "vulnerability|Add a comment or reason for dismissal"
msgstr ""
msgid "vulnerability|Add comment"
-msgstr ""
+msgstr "Tilføj kommentar"
msgid "vulnerability|Add comment & dismiss"
msgstr ""
@@ -40253,7 +40642,7 @@ msgid "vulnerability|Dismiss vulnerability"
msgstr ""
msgid "vulnerability|Save comment"
-msgstr ""
+msgstr "Gem kommentar"
msgid "vulnerability|Undo dismiss"
msgstr ""
@@ -40265,7 +40654,7 @@ msgid "was scheduled to merge after pipeline succeeds by"
msgstr ""
msgid "wiki page"
-msgstr ""
+msgstr "wikiside"
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
@@ -40277,8 +40666,8 @@ msgid "with expiry remaining unchanged at %{old_expiry}"
msgstr ""
msgid "yaml invalid"
-msgstr ""
+msgstr "yaml ugyldig"
msgid "your settings"
-msgstr ""
+msgstr "dine indstillinger"
diff --git a/locale/de/gitlab.po b/locale/de/gitlab.po
index 73e1975083a..3dc94b39d3f 100644
--- a/locale/de/gitlab.po
+++ b/locale/de/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: de\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:27\n"
+"PO-Revision-Date: 2021-09-01 22:33\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] "%d nicht zugewiesenes Ticket"
@@ -517,6 +522,9 @@ msgstr[1] "%{count} Teilnehmer(innen)"
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr "%{count} verwandte %{pluralized_subject}: %{links}"
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -1655,7 +1666,7 @@ msgid "About GitLab"
msgstr "Ãœber GitLab"
msgid "About auto deploy"
-msgstr "Ãœber automatische Bereitstellung "
+msgstr ""
msgid "About this feature"
msgstr "Ãœber dieses Feature"
@@ -2338,8 +2349,8 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
-msgstr "Du bist dabei, alle Jobs zu stoppen. Dies hält alle aktuellen Jobs, die ausgeführt werden, an."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
+msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "Fehler beim Laden der Statistik. Bitte versuche es erneut"
@@ -2566,12 +2577,6 @@ msgstr "Blockiert"
msgid "AdminUsers|Blocking user has the following effects:"
msgstr "Benutzer(in) zu blockieren hat folgende Auswirkungen:"
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr "Das bist du!"
@@ -2701,6 +2709,12 @@ msgstr "E-Mail an Benutzer(innen) senden"
msgid "AdminUsers|Sort by"
msgstr "Sortiert nach"
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr "Benutzer(in) wird abgemeldet"
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr "Beim Abrufen der Board-Listen ist ein Fehler aufgetreten. Bitte versuche es erneut."
-
msgid "An error occurred while fetching the job log."
msgstr "Beim Abrufen des Jobprotokolls ist ein Fehler aufgetreten."
@@ -3630,9 +3641,6 @@ msgstr "Beim Abrufen der Jobs ist ein Fehler aufgetreten."
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr "Beim Abrufen der Pipeline ist ein Fehler aufgetreten."
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr "Beim Abrufen der Releases ist ein Fehler aufgetreten. Bitte versuche es erneut."
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] "%{count} Zustimmung von %{membersCount} nötig"
msgstr[1] "%{count} Zustimmungen von %{membersCount} nötig"
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr "Regelname"
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr "Möchtest du wirklich dieses Projekt aus dem Archiv zurückholen?"
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr "Möchtest du wirklich die Bearbeitung dieses Kommentars abbrechen?"
@@ -4499,9 +4537,6 @@ msgstr "Artefakt wurde erfolgreich gelöscht."
msgid "Artifacts"
msgstr "Artefakte"
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr "Zuweisungslisten sind mit deiner momentanen Lizenz nicht verfügbar"
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr "Zuweisungslisten zeigen alle dem ausgewählten Benutzer zugewiesenen Tickets an."
-
msgid "Assignee(s)"
msgstr "Zugewiesene Personen"
@@ -4634,7 +4666,7 @@ msgid "Assigns %{reviewer_users_sentence} as %{reviewer_text}."
msgstr ""
msgid "At least one approval from a code owner is required to change files matching the respective CODEOWNER rules."
-msgstr "Mindestens eine Zustimmung der Code-Eigentümer(innen) ist erforderlich, um Dateien zu ändern, auf die die entsprechenden CODEOWNER-Regeln zutreffen."
+msgstr ""
msgid "At least one field of %{one_of_required_fields} must be present"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr "Automatische Zertifikatsverwaltung mit Let's Encrypt"
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr "Mit dem ausgewählten Commit beginnen"
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr "Boards"
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr "Einklappen"
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr "CONTRIBUTING"
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6330,7 +6368,7 @@ msgid "ChangeTypeAction|Pick into project"
msgstr ""
msgid "ChangeTypeAction|Revert"
-msgstr "Wiederherstellen "
+msgstr ""
msgid "ChangeTypeAction|Revert in branch"
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr "Überprüfe Verfügbarkeit des Benutzernamens..."
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr "%{startDate} - %{endDate}"
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7242,7 +7287,7 @@ msgid "ClusterIntegration|Add Kubernetes cluster"
msgstr "Kubernetes-Cluster hinzufügen"
msgid "ClusterIntegration|Add a Kubernetes cluster integration"
-msgstr "ClusterIntegration|Eine Kubernetes-Cluster-Integration hinzufügen"
+msgstr ""
msgid "ClusterIntegration|Adding a Kubernetes cluster to your group will automatically share the cluster across all your projects. Use review apps, deploy your applications, and easily run your pipelines for all projects using the same cluster."
msgstr "Wenn du deiner Gruppe ein Kubernetes-Cluster hinzufügst, wird das Cluster automatisch von allen deinen Projekten geteilt. Benutze Review-Anwendungen, stelle deine Anwendungen bereit und führe einfach alle deine Pipelines für alle Projekte auf dem selben Cluster aus."
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr "Einschränkungen für Web- und API-Anfragen konfigurieren."
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -9524,7 +9566,7 @@ msgid "CreateGroup|You don’t have permission to create groups."
msgstr ""
msgid "CreateTag|Tag"
-msgstr "Tag "
+msgstr ""
msgid "CreateTokenToCloneLink|create a personal access token"
msgstr "Erstelle einen persönlichen Zugriffstoken"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr "Kommentar entfernen"
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr "Quellbranch löschen"
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr "Diesen Anhang löschen"
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr "Abhängigkeitsproxy"
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr "Label bearbeiten"
@@ -12074,6 +12164,9 @@ msgstr "Öffentlichen Bereitstellungsschlüssel bearbeiten"
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr "Bereitstellung"
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr "Umgebungen"
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr "Umgebungen sind Orte, an denen Code bereitgestellt wird, z. B. Staging oder Produktion."
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr "Umgebung stoppen"
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr "Aktualisiert"
msgid "Environments|You don't have any environments right now"
msgstr "Du hast momentan keine Umgebungen"
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr "geschützt"
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr "Nach Status filtern"
msgid "Geo|Geo Status"
msgstr "Geo-Status"
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr "Zuletzt überprüft"
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr "Noch nicht synchronisiert"
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr "Tracking-Datenbankeintrag entfernen"
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr "Status"
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr "Warte auf den Scheduler"
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr "GitLab-Import"
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr "Entschuldigung, keine Epics stimmen mit deiner Suche überein"
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr "Die Roadmap zeigt den Fortschritt deiner Epics anhand einer Zeitleiste an"
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16564,7 +16696,7 @@ msgid "I accept the %{terms_link}"
msgstr "Ich akzeptiere die %{terms_link}"
msgid "I accept the|Terms of Service and Privacy Policy"
-msgstr "Nutzungs- und Datenschutzbestimmungen"
+msgstr ""
msgid "I forgot my password"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr "Wenn diese Option deaktiviert ist, wird ein abweichender lokaler Branch
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr "In Bearbeitung"
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr "Label"
msgid "Label actions dropdown"
msgstr "Dropdown-Menü für die Label-Aktionen"
-msgid "Label lists show all issues with the selected label."
-msgstr "Labellisten zeigen alle Tickets mit dem gewählten Label."
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr "Letzte Antwort von"
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr "Maximale Job-Zeitüberschreitung"
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr "Maximale Seite erreicht"
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr "Beim Hinzufügen des Kommentarentwurfs ist ein Fehler aufgetreten."
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr "Speichern des Kommentars fehlgeschlagen"
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr "Meilensteinlisten ist mit deiner momentanen Lizenz nicht verfügbar"
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr "Meilensteinlisten zeigen alle Tickets des ausgewählten Meilensteins an."
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21722,7 +21896,7 @@ msgid "More information and share feedback"
msgstr ""
msgid "More information is available|here"
-msgstr "hier"
+msgstr ""
msgid "More information."
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr "Neuer Branch"
msgid "New branch unavailable"
msgstr "Neuer Branch ist nicht verfügbar"
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr "Neue Änderungen wurden hinzugefügt. %{linkStart}Lade die Seite neu, um sie zu überprüfen%{linkEnd}"
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr "November"
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr "Offen"
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,15 +25362,12 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
-msgstr ""
-
msgid "Prevent adding new members to project membership within this group"
msgstr "Verhindere das Hinzufügen neuer Mitglieder zur Projektmitgliedschaft in dieser Gruppe"
+msgid "Prevent editing approval rules in projects and merge requests."
+msgstr ""
+
msgid "Prevent environment from auto-stopping"
msgstr ""
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr "Zeige keine aktivitätsbezogenen persönlichen Informationen in deinem P
msgid "Profiles|Edit Profile"
msgstr "Profil bearbeiten"
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr "Benutzername erfolgreich geändert"
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr "Was ist dein Status?"
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr "Diese Funktion ist gesperrt."
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr "Projekt-Sichtbarkeit verringern"
@@ -27453,7 +27657,7 @@ msgid "Register"
msgstr ""
msgid "Register / Sign In"
-msgstr "Anmelden"
+msgstr ""
msgid "Register Two-Factor Authenticator"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr "Zugehörige Merge-Requests"
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr "Bezieht sich auf"
@@ -28029,6 +28236,9 @@ msgstr "Das Laden der Ergebnisse durch die Testzusammenfassung ist fehlgeschlage
msgid "Reports|Test summary results are being parsed"
msgstr "Ergebnisse der Testzusammenfassung werden analysiert"
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr "Sicherheitslücke"
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
+msgstr ""
+
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select security project"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityPolicies|Environment(s)"
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr "Neuste Version zeigen"
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr "Größe"
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr "Erstellungsdatum"
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr "Die Aktualisierungsaktion wird nach %{number_of_minutes} Minuten abgebrochen. Verwende für große Repositories eine Clone / Push-Kombination."
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr "Diese Gruppe"
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -34481,7 +34790,7 @@ msgid "Timeago|%s hours remaining"
msgstr "%s Stunden verbleibend"
msgid "Timeago|%s minutes ago"
-msgstr "vor %s Minuten "
+msgstr ""
msgid "Timeago|%s minutes remaining"
msgstr "%s Minuten verbleibend"
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr "Verwende eine Zeile pro URI"
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr "Projektlabels ansehen"
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr "Zeige ersetzte Datei @ "
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr "Du kannst deine .gitlab-ci.yml mit %{linkStart}CI Lint%{linkEnd} testen.
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr "Du kannst nicht auf eine schreibgeschützte sekundäre Gitlab Geo-Instanz schreiben. Bitte verwende stattdessen %{link_to_primary_node}."
@@ -38131,7 +38484,7 @@ msgstr "Du hast die Projektbegrenzung erreicht"
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr "Branch-Name"
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr "ist keine Ihrer E-Mails"
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr "Geschlossen"
msgid "mrWidget|Closed by"
msgstr "Geschlossen von"
-msgid "mrWidget|Closes"
-msgstr "Schließt"
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr "Quellbranch löschen"
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr "Erwähnungen"
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr "Merge"
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr "Weitere Informationen"
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr "In Web-IDE öffnen"
@@ -39718,9 +40107,6 @@ msgstr "Die Änderungen werden gemerged nach"
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr "Der HEAD des Quellbranches wurde kürzlich geändert. Bitte lade die Seite neu und überprüfe die Änderungen vor dem Mergen"
-
msgid "mrWidget|The source branch has been deleted"
msgstr "Der Quellbranch wurde gelöscht"
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr "Du darfst dieses Projekt nicht direkt bearbeiten. Bitte erstelle einen Fork, um Änderungen vorzunehmen."
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr "muss nach dem Anfangsdatum liegen"
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/el_GR/gitlab.po b/locale/el_GR/gitlab.po
index d7774fc3073..b6bb75d86a3 100644
--- a/locale/el_GR/gitlab.po
+++ b/locale/el_GR/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: el\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:27\n"
+"PO-Revision-Date: 2021-09-01 22:33\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/eo/gitlab.po b/locale/eo/gitlab.po
index b08404fce7c..d5b4a995434 100644
--- a/locale/eo/gitlab.po
+++ b/locale/eo/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: eo\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:17\n"
+"PO-Revision-Date: 2021-09-01 22:31\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr "Nova branĉo"
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33239,7 +33539,7 @@ msgid "The project can be accessed by anyone, regardless of authentication."
msgstr ""
msgid "The project can be accessed without any authentication."
-msgstr "Ĉiu povas havi atingon al la projekto, sen ensaluti"
+msgstr ""
msgid "The project has already been added to your dashboard."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr "Vi ne povas krei pliajn projektojn"
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/es/gitlab.po b/locale/es/gitlab.po
index bdbd4eef93a..d8677107446 100644
--- a/locale/es/gitlab.po
+++ b/locale/es/gitlab.po
@@ -14,10 +14,10 @@ msgstr ""
"X-Crowdin-Language: es-ES\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:24\n"
+"PO-Revision-Date: 2021-09-01 22:32\n"
msgid " %{name}, confirm your email address now! "
-msgstr ""
+msgstr " %{name}, ¡confirme su dirección de correo electrónico ahora! "
msgid " %{start} to %{end}"
msgstr " %{start} hasta %{end}"
@@ -32,16 +32,16 @@ msgid " Please sign in."
msgstr " Por favor, inicie sesión."
msgid " Target Path"
-msgstr ""
+msgstr " Ruta de destino"
msgid " Try to %{action} this file again."
msgstr " Intente %{action} este archivo de nuevo."
msgid " Type"
-msgstr ""
+msgstr " Tipo"
msgid " You need to do this before %{grace_period_deadline}."
-msgstr "Necesita hacer esto antes de %{grace_period_deadline}."
+msgstr ""
msgid " and"
msgstr " y"
@@ -78,24 +78,24 @@ msgid " or references (e.g. path/to/project!merge_request_id)"
msgstr " o referencias (e.j. path/to/project!merge_request_id)"
msgid " reacted with :%{name}:"
-msgstr ""
+msgstr " reaccionó con:%{name}:"
msgid "\"%{path}\" did not exist on \"%{ref}\""
msgstr "\"%{path}\" no existía en \"%{ref}\""
msgid "\"%{repository_name}\" size (%{repository_size}) is larger than the limit of %{limit}."
-msgstr ""
+msgstr "El tamaño de \"%{repository_name}(%{repository_size}) es mayor que el límite de %{limit}."
msgid "\"el\" parameter is required for createInstance()"
-msgstr ""
+msgstr "El parámetro \"el\" es necesario para createInstance()"
msgid "#general, #development"
-msgstr ""
+msgstr "#general, #desarrollo"
msgid "%d Approval"
msgid_plural "%d Approvals"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d autorización"
+msgstr[1] "%d autorizaciones"
msgid "%d Module"
msgid_plural "%d Modules"
@@ -139,8 +139,8 @@ msgstr[1] "%d archivos modificados"
msgid "%d character remaining"
msgid_plural "%d characters remaining"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d carácter restante"
+msgstr[1] "%d carácteres restantes"
msgid "%d child epic"
msgid_plural "%d child epics"
@@ -232,13 +232,13 @@ msgstr[1] "%d fallidos"
msgid "%d failed security job"
msgid_plural "%d failed security jobs"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d trabajo de seguridad fallido"
+msgstr[1] "%d trabajos de seguridad fallidos"
msgid "%d file"
msgid_plural "%d files"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d archivo"
+msgstr[1] "%d archivos"
msgid "%d fixed test result"
msgid_plural "%d fixed test results"
@@ -247,8 +247,8 @@ msgstr[1] "%d solucionados los resultados de la prueba"
msgid "%d group"
msgid_plural "%d groups"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d grupo"
+msgstr[1] "%d grupos"
msgid "%d group selected"
msgid_plural "%d groups selected"
@@ -327,8 +327,8 @@ msgstr[1] ""
msgid "%d personal project will be removed and cannot be restored."
msgid_plural "%d personal projects will be removed and cannot be restored."
-msgstr[0] "Se eliminará el proyecto personal %d y no podrá ser restaurado"
-msgstr[1] "Se eliminarán los proyectos personales %d y no podrán ser restaurados"
+msgstr[0] "Se eliminará el proyecto personal %d y no podrá ser restaurado."
+msgstr[1] "Se eliminarán los proyectos personales %d y no podrán ser restaurados."
msgid "%d previously merged commit"
msgid_plural "%d previously merged commits"
@@ -367,6 +367,11 @@ msgstr[1] "%d etiquetas"
msgid "%d tag per image name"
msgid_plural "%d tags per image name"
+msgstr[0] "%d etiqueta por nombre de imagen"
+msgstr[1] "%d etiquetas por nombre de imagen"
+
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
msgstr[0] ""
msgstr[1] ""
@@ -412,13 +417,13 @@ msgid "%{address} is an invalid IP address range"
msgstr "%{address} no es en un rango de direcciones IP válido"
msgid "%{anchorOpen}Learn more%{anchorClose} about how you can customize / disable registration on your instance."
-msgstr ""
+msgstr "%{anchorOpen}Obtenga más información%{anchorClose} sobre cómo puede personalizar/deshabilitar el registro en su instancia."
msgid "%{author_link} cloned %{original_issue} to %{new_issue}."
-msgstr ""
+msgstr "%{author_link} ha clonado %{original_issue} a %{new_issue}."
msgid "%{author_link} cloned %{original_issue}. You don't have access to the new project."
-msgstr ""
+msgstr "%{author_link} ha clonado %{original_issue}. No tiene acceso al nuevo proyecto."
msgid "%{author_link} wrote:"
msgstr "%{author_link} escribió:"
@@ -431,13 +436,13 @@ msgstr "%{board_target} no encontrado"
msgid "%{bold_start}%{count}%{bold_end} issue"
msgid_plural "%{bold_start}%{count}%{bold_end} issues"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{bold_start}%{count}%{bold_end} incidencia"
+msgstr[1] "%{bold_start}%{count}%{bold_end} incidencias"
msgid "%{bold_start}%{count}%{bold_end} member"
msgid_plural "%{bold_start}%{count}%{bold_end} members"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{bold_start}%{count}%{bold_end} miembro"
+msgstr[1] "%{bold_start}%{count}%{bold_end} miembros"
msgid "%{bold_start}%{count}%{bold_end} opened merge request"
msgid_plural "%{bold_start}%{count}%{bold_end} opened merge requests"
@@ -458,8 +463,8 @@ msgstr ""
msgid "%{completedCount} of %{count} task completed"
msgid_plural "%{completedCount} of %{count} tasks completed"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{completedCount} de %{count} tarea completada"
+msgstr[1] "%{completedCount} de %{count} tareas completadas"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr "%{completedWeight} de %{totalWeight} del peso completado"
@@ -486,11 +491,11 @@ msgstr "%{count} archivos modificados"
msgid "%{count} item"
msgid_plural "%{count} items"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{count} elemento"
+msgstr[1] "%{count} elementos"
msgid "%{count} items per page"
-msgstr ""
+msgstr "%{count} elementos por página"
msgid "%{count} more"
msgstr "%{count} más"
@@ -517,11 +522,14 @@ msgstr[1] "%{count} participantes"
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr "%{count} %{pluralized_subject} relacionados: %{links}"
-msgid "%{count} total weight"
+msgid "%{count} selected"
msgstr ""
+msgid "%{count} total weight"
+msgstr "%{count} peso total"
+
msgid "%{criticalStart}%{critical} Critical%{criticalEnd} %{highStart}%{high} High%{highEnd} and %{otherStart}%{otherMessage}%{otherEnd}"
-msgstr ""
+msgstr "%{criticalStart}%{critical} Crítico%{criticalEnd} %{highStart}%{high} Alto%{highEnd} y %{otherStart}%{otherMessage}%{otherEnd}"
msgid "%{dashboard_path} could not be found."
msgstr "%{dashboard_path} no se ha encontrado."
@@ -533,7 +541,7 @@ msgid "%{deployLinkStart}Use a template to deploy to ECS%{deployLinkEnd}, or use
msgstr "%{deployLinkStart}Utilice una plantilla para implementar en ECS%{deployLinkEnd}, o utilice una imagen de Docker para ejecutar %{commandsLinkStart}comandos de AWS en GitLab CI/CD%{commandsLinkEnd}."
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
-msgstr ""
+msgstr "%{description}- Evento de Sentry: %{errorUrl}- Visto por primera vez: %{firstSeen}- Visto por última vez: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
msgstr ""
@@ -560,10 +568,10 @@ msgid "%{edit_in_new_fork_notice} Try to upload a file again."
msgstr "%{edit_in_new_fork_notice} Intente subir un archivo de nuevo."
msgid "%{emailPrefix}@company.com"
-msgstr ""
+msgstr "%{emailPrefix}@empresa.com"
msgid "%{extra} more downstream pipelines"
-msgstr ""
+msgstr "%{extra} más downstream pipelines"
msgid "%{filePath} deleted"
msgstr "%{filePath} eliminado"
@@ -572,19 +580,19 @@ msgid "%{firstLabel} +%{labelCount} more"
msgstr "%{firstLabel} +%{labelCount} más"
msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
-msgstr ""
+msgstr "%{firstMilestoneName} +%{numberOfOtherMilestones} más"
msgid "%{gitlab_experience_text}. Don't worry, this information isn't shared outside of your self-managed GitLab instance."
-msgstr ""
+msgstr "%{gitlab_experience_text}. No se preocupe, esta información no se comparte fuera de su instancia de GitLab autogestionada."
msgid "%{gitlab_experience_text}. We won't share this information with anyone."
-msgstr ""
+msgstr "%{gitlab_experience_text}. No compartiremos esta información con nadie."
msgid "%{global_id} is not a valid ID for %{expected_types}."
-msgstr ""
+msgstr "%{global_id} no es un ID válido para %{expected_types}."
msgid "%{group_name} activity"
-msgstr ""
+msgstr "Actividad de %{group_name}"
msgid "%{group_name} group members"
msgstr "miembros del grupo %{group_name}"
@@ -593,7 +601,7 @@ msgid "%{group_name} uses group managed accounts. You need to create a new GitLa
msgstr "%{group_name} utiliza cuentas administradas de grupo. Debe crear una nueva cuenta de GitLab que será administrada por %{group_name}."
msgid "%{group_name}&%{epic_iid} &middot; created %{epic_created} by %{author}"
-msgstr ""
+msgstr "%{group_name}&%{epic_iid} &middot; creado %{epic_created} por %{author}"
msgid "%{hook_type} was deleted"
msgstr "%{hook_type} eliminado"
@@ -605,7 +613,7 @@ msgid "%{host} sign-in from new location"
msgstr "%{host} inicia sesión desde una nueva ubicación"
msgid "%{integrations_link_start}Integrations%{link_end} enable you to make third-party applications part of your GitLab workflow. If the available integrations don't meet your needs, consider using a %{webhooks_link_start}webhook%{link_end}."
-msgstr ""
+msgstr "Las %{integrations_link_start}integraciones%{link_end} le permiten el uso de aplicaciones de terceros ensu flujo de trabajo en GitLab. Si las integraciones disponibles no satisfacen sus necesidades. Puede considerar utilizar un %{webhooks_link_start}webhook%{link_end}."
msgid "%{issuableType} will be removed! Are you sure?"
msgstr "¡Va a eliminar %{issuableType}! ¿Está seguro de que desea realizar esta acción?"
@@ -614,22 +622,22 @@ msgid "%{issueType} actions"
msgstr "%{issueType} acciones"
msgid "%{issuesCount} issues with a limit of %{maxIssueCount}"
-msgstr ""
+msgstr "%{issuesCount} incidencias con un límite de %{maxIssueCount}"
msgid "%{issuesSize} with a limit of %{maxIssueCount}"
-msgstr ""
+msgstr "%{issuesSize} con un límite de %{maxIssueCount}"
msgid "%{italic_start}What's new%{italic_end} is inactive and cannot be viewed."
-msgstr ""
+msgstr "%{italic_start}Novedades%{italic_end} está inactivo y no se puede ver."
msgid "%{itemsCount} issues with a limit of %{maxIssueCount}"
-msgstr ""
+msgstr "%{itemsCount} incidencias con un límite de %{maxIssueCount}"
msgid "%{labelStart}Actual response:%{labelEnd} %{headers}"
-msgstr ""
+msgstr "%{labelStart}Respuesta actual:%{labelEnd} %{headers}"
msgid "%{labelStart}Assert:%{labelEnd} %{assertion}"
-msgstr ""
+msgstr "%{labelStart}Afirmar:%{labelEnd} %{assertion}"
msgid "%{labelStart}Class:%{labelEnd} %{class}"
msgstr "%{labelStart}Clase:%{labelEnd} %{class}"
@@ -655,9 +663,6 @@ msgstr "%{labelStart}Método:%{labelEnd} %{method}"
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr "%{labelStart}Espacio de nombres:%{labelEnd} %{namespace}"
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr "%{labelStart}Escáner:%{labelEnd} %{scanner}"
@@ -667,14 +672,17 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr "%{labelStart}Gravedad:%{labelEnd} %{severity}"
-msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
msgstr ""
+msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
+msgstr "%{labelStart}Respuesta sin modificar:%{labelEnd} %{headers}"
+
msgid "%{label_for_message} unavailable"
msgstr "%{label_for_message} no disponible"
msgid "%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} is a free, automated, and open certificate authority (CA) that issues digital certificates to enable HTTPS (SSL/TLS) for sites."
-msgstr ""
+msgstr "%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} es una autoridad de certificación gratuita, automatizada, y abierta que genera certificados digitales para habilitar HTTPS para sitios web."
msgid "%{level_name} is not allowed in a %{group_level_name} group."
msgstr "%{level_name} no está permitido en un grupo de %{group_level_name}."
@@ -683,7 +691,7 @@ msgid "%{level_name} is not allowed since the fork source project has lower visi
msgstr "%{level_name} no está permitido debido a que el fork del proyecto origen tiene menor visibilidad."
msgid "%{link_start}Learn more%{link_end} about roles."
-msgstr ""
+msgstr "%{link_start}Obtener más información%{link_end} sobre los roles."
msgid "%{link_start}Learn more%{link_end} about what information is shared with GitLab Inc."
msgstr "%{link_start}Más información%{link_end} sobre qué información se comparte con GitLab Inc."
@@ -695,22 +703,22 @@ msgid "%{link_start}Start the title with %{draft_snippet}%{link_end} to prevent
msgstr ""
msgid "%{listToShow}, and %{awardsListLength} more"
-msgstr ""
+msgstr "%{listToShow}, y %{awardsListLength} más"
msgid "%{location} is missing required keys: %{keys}"
-msgstr ""
+msgstr "%{location} no tiene claves requeridas: %{keys}"
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr "%{lock_path} está bloqueado por el usuario de GitLab %{lock_user_id}"
msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
-msgstr ""
+msgstr "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} y %{quickActionsDocsLinkStart}acciones rápidas%{quickActionsDocsLinkEnd} son compatibles"
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr "%{mergeLength}/%{usersLength} puede fusionarse"
msgid "%{message} showing first %{warnings_displayed}"
-msgstr ""
+msgstr "%{message} mostrando el primer %{warnings_displayed}"
msgid "%{milestone} (expired)"
msgstr "%{milestone} (expirado)"
@@ -719,7 +727,7 @@ msgid "%{milliseconds}ms"
msgstr "%{milliseconds} ms"
msgid "%{model_name} not found"
-msgstr ""
+msgstr "%{model_name} no encontrado"
msgid "%{mrText}, this issue will be closed automatically."
msgstr "%{mrText}, esta incidencia se cerrará automáticamente."
@@ -731,7 +739,7 @@ msgid "%{name_with_link} namespace has run out of Shared Runner Pipeline minutes
msgstr ""
msgid "%{name} (Busy)"
-msgstr ""
+msgstr "%{name} (Ocupado)"
msgid "%{name} contained %{resultsString}"
msgstr "%{name} contenido en %{resultsString}"
@@ -755,7 +763,7 @@ msgid "%{name}(%{url}) namespace has run out of Shared Runner Pipeline minutes s
msgstr ""
msgid "%{name}, confirm your email address now!"
-msgstr ""
+msgstr "%{name}, ¡confirme su dirección de correo electrónico ahora!"
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
@@ -766,13 +774,13 @@ msgid "%{number_commits_behind} commits behind %{default_branch}, %{number_commi
msgstr "%{number_commits_behind} commits detrás de %{default_branch}, %{number_commits_ahead} commits por delante"
msgid "%{oneMonthAgo} - %{today}"
-msgstr ""
+msgstr "%{oneMonthAgo} - %{today}"
msgid "%{oneWeekAgo} - %{today}"
-msgstr ""
+msgstr "%{oneWeekAgo} - %{today}"
msgid "%{oneYearAgo} - %{today}"
-msgstr ""
+msgstr "%{oneYearAgo} - %{today}"
msgid "%{openOrClose} %{noteable}"
msgstr "%{openOrClose} %{noteable}"
@@ -810,19 +818,19 @@ msgstr[0] "%{releases} lanzamiento"
msgstr[1] "%{releases} lanzamientos"
msgid "%{remaining_approvals} left"
-msgstr "quedan %{remaining_approvals} "
+msgstr "quedan %{remaining_approvals}"
msgid "%{reportType} %{status}"
msgstr "%{reportType} %{status}"
msgid "%{reportType} detected %{totalStart}%{total}%{totalEnd} potential %{vulnMessage}"
-msgstr ""
+msgstr "%{reportType} detectó %{totalStart}%{total}%{totalEnd} potencial %{vulnMessage}"
msgid "%{reportType} detected %{totalStart}no%{totalEnd} vulnerabilities."
-msgstr ""
+msgstr "%{reportType} detectó %{totalStart}no%{totalEnd} vulnerabilidades."
msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}."
-msgstr ""
+msgstr "%{retryButtonStart}Inténtelo de nuevo%{retryButtonEnd} o %{newFileButtonStart}adjunte un archivo nuevo%{newFileButtonEnd}."
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation_link}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr "%{seconds} s"
@@ -1004,13 +1015,13 @@ msgid "%{user} created a merge request: %{mr_link}"
msgstr ""
msgid "%{user} created an epic: %{epic_link}"
-msgstr ""
+msgstr "%{user} creó una épica: %{epic_link}"
msgid "%{user} created an issue: %{issue_link}"
-msgstr ""
+msgstr "%{user} creó una incidencia: %{issue_link}"
msgid "%{value} is not included in the list"
-msgstr ""
+msgstr "%{value} no está incluido en la lista"
msgid "%{value} s"
msgstr "%{value} s"
@@ -1081,7 +1092,7 @@ msgid "(+%{count}&nbsp;rules)"
msgstr "(+%{count}&nbsp;reglas)"
msgid "(Group Managed Account)"
-msgstr ""
+msgstr "(Cuenta administrada de grupo)"
msgid "(No changes)"
msgstr "(Sin cambios)"
@@ -1096,10 +1107,10 @@ msgid "(deleted)"
msgstr "(eliminado)"
msgid "(expired)"
-msgstr ""
+msgstr "(caducó)"
msgid "(leave blank if you don't want to change it)"
-msgstr ""
+msgstr "(Déjelo en blanco si no quiere cambiarlo)"
msgid "(max size 15 MB)"
msgstr "(tamaño máximo 15 MB)"
@@ -1111,7 +1122,7 @@ msgid "(revoked)"
msgstr "(revocado)"
msgid "(we need your current password to confirm your changes)"
-msgstr ""
+msgstr "(Necesitamos su contraseña actual para confirmar sus cambios)"
msgid "* * * * *"
msgstr "* * * * *"
@@ -1137,7 +1148,7 @@ msgid "+%{approvers} more approvers"
msgstr "+%{approvers} aprobadores más"
msgid "+%{extra} more"
-msgstr ""
+msgstr "+%{extra} más"
msgid "+%{more_assignees_count}"
msgstr "+%{more_assignees_count}"
@@ -1218,13 +1229,13 @@ msgstr[1] "%d días"
msgid "1 day remaining"
msgid_plural "%d days remaining"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Queda 1 día"
+msgstr[1] "Quedan %d días"
msgid "1 day selected"
msgid_plural "%d days selected"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 día seleccionado"
+msgstr[1] "%d días seleccionados"
msgid "1 deploy key"
msgid_plural "%d deploy keys"
@@ -1233,8 +1244,8 @@ msgstr[1] "%d claves de despliegue"
msgid "1 follower"
msgid_plural "%{count} followers"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 seguidor"
+msgstr[1] "%{count} seguidores"
msgid "1 group"
msgid_plural "%d groups"
@@ -1248,11 +1259,11 @@ msgstr[1] "%d horas"
msgid "1 issue selected"
msgid_plural "%d issues selected"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 petición seleccionada"
+msgstr[1] "%d peticiones seleccionadas"
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1268,8 +1279,8 @@ msgstr[1] "%d minutos"
msgid "1 month remaining"
msgid_plural "%d months remaining"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Queda 1 mes"
+msgstr[1] "Quedan %d meses"
msgid "1 open issue"
msgid_plural "%{issues} open issues"
@@ -1298,13 +1309,13 @@ msgstr[1] "%{num} usuarios"
msgid "1 week remaining"
msgid_plural "%d weeks remaining"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Queda 1 semana"
+msgstr[1] "Quedan %d semanas"
msgid "1 year remaining"
msgid_plural "%d years remaining"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Queda 1 año"
+msgstr[1] "Quedan %d años"
msgid "1-9 contributions"
msgstr "1-9 contribuciones"
@@ -1313,7 +1324,7 @@ msgid "10-19 contributions"
msgstr "10-19 contribuciones"
msgid "1000+"
-msgstr ""
+msgstr "1000+"
msgid "1st contribution!"
msgstr "¡1ra contribución!"
@@ -1376,19 +1387,19 @@ msgid "A CI/CD pipeline must run and be successful before merge."
msgstr ""
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "Un sitio basado en GitBook que utiliza Netlify como herramienta de CI/CD en lugar de GitLab, pero con todas las otras excelentes características de GitLab"
msgid "A Gitpod configured Webapplication in Spring and Java"
-msgstr ""
+msgstr "Una aplicación web configurada en Gitpod en Spring y Java"
msgid "A Hexo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "Un sitio basado en Hexo que utiliza Netlify como herramienta de CI/CD en lugar de GitLab, pero con todas las otras excelentes características de GitLab"
msgid "A Hugo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "Un sitio basado en Hugo que utiliza Netlify como herramienta de CI/CD en lugar de GitLab, pero con todas las otras excelentes características de GitLab"
msgid "A Jekyll site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "Un sitio basado en Jekyll que utiliza Netlify como herramienta de CI/CD en lugar de GitLab, pero con todas las otras excelentes características de GitLab"
msgid "A Let's Encrypt SSL certificate can not be obtained until your domain is verified."
msgstr "No se puede obtener un certificado SSL de Let's Encrypt hasta que se verifique su dominio."
@@ -1397,10 +1408,10 @@ msgid "A Metrics Dashboard menu item appears in the Monitoring section of the Ad
msgstr ""
msgid "A basic page and serverless function that uses AWS Lambda, AWS API Gateway, and GitLab Pages"
-msgstr ""
+msgstr "Una página básica y una función serverless que usa AWS Lambda, AWS API Gateway y GitLab Pages"
msgid "A basic template for developing Linux programs using Kotlin Native"
-msgstr ""
+msgstr "Una plantilla básica para desarrollar programas de Linux usando Kotlin Native"
msgid "A complete DevOps platform"
msgstr "Una plataforma DevOps completa"
@@ -1412,10 +1423,10 @@ msgid "A deleted user"
msgstr "Un usuario eliminado"
msgid "A description is required"
-msgstr ""
+msgstr "Es necesaria una descripción"
msgid "A different reason"
-msgstr ""
+msgstr "Una motivo diferente"
msgid "A file has been changed."
msgstr "Se ha modificado un archivo."
@@ -1433,13 +1444,13 @@ msgid "A group represents your organization in GitLab. Groups allow you to manag
msgstr "Un grupo representa a su organización en GitLab. Los grupos que le permiten administrar usuarios y colaborar a través de múltiples proyectos."
msgid "A job artifact is an archive of files and directories saved by a job when it finishes."
-msgstr ""
+msgstr "Un artefacto de trabajo es un archivo de archivos y directorios guardados por un trabajo cuando finaliza."
msgid "A limit of %{ci_project_subscriptions_limit} subscriptions to or from a project applies."
-msgstr ""
+msgstr "Se aplica un límite de %{ci_project_subscriptions_limit} suscripciones hacia o desde un proyecto."
msgid "A management, operational, or technical control (that is, safeguard or countermeasure) employed by an organization that provides equivalent or comparable protection for an information system."
-msgstr ""
+msgstr "Un control administrativo, operativo o técnico (es decir, salvaguarda o contramedida) empleado por una organización que proporciona protección equivalente o comparable para un sistema de información."
msgid "A member of the abuse team will review your report as soon as possible."
msgstr "Un miembro del equipo revisará su informe tan pronto como sea posible."
@@ -1448,7 +1459,7 @@ msgid "A merge request hasn't yet been merged"
msgstr ""
msgid "A new Auto DevOps pipeline has been created, go to %{pipelines_link_start}Pipelines page%{pipelines_link_end} for details"
-msgstr ""
+msgstr "Se ha creado un nuevo pipeline de Auto DevOps, vaya a la página de pipelines %{pipelines_link_start}%{pipelines_link_end} para más detalles"
msgid "A new Release %{tag} for %{name} was published. Visit the %{release_link_start}Releases page%{release_link_end} to read more about it."
msgstr "Se publicó una nueva versión %{tag} para %{name}. Visite la página de %{release_link_start}versiones%{release_link_end} para obtener más información al respecto."
@@ -1472,7 +1483,7 @@ msgid "A plain-text response to show to clients that hit the rate limit."
msgstr ""
msgid "A platform value can be web, mob or app."
-msgstr ""
+msgstr "Un valor de plataforma puede ser web, mob o aplicación."
msgid "A project boilerplate for Salesforce App development with Salesforce Developer tools"
msgstr ""
@@ -1484,10 +1495,10 @@ msgid "A project’s repository name defines its URL (the one you use to access
msgstr ""
msgid "A ready-to-go template for use with Android apps"
-msgstr ""
+msgstr "Una plantilla lista para utilizar con aplicaciones de Android"
msgid "A ready-to-go template for use with iOS Swift apps"
-msgstr ""
+msgstr "Una plantilla lista para usar con las aplicaciones iOS basadas en Swift"
msgid "A rebase is already in progress."
msgstr ""
@@ -1508,13 +1519,13 @@ msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt c
msgstr ""
msgid "API"
-msgstr ""
+msgstr "API"
msgid "API Fuzzing"
-msgstr ""
+msgstr "API Fuzzing"
msgid "API Fuzzing Configuration"
-msgstr ""
+msgstr "Configuración de API Fuzzing"
msgid "API Help"
msgstr "Ayuda de la API"
@@ -1523,28 +1534,28 @@ msgid "API Token"
msgstr "Token del API"
msgid "API key"
-msgstr ""
+msgstr "Clave API"
msgid "API?"
-msgstr ""
+msgstr "API?"
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
-msgstr ""
+msgstr "Configuración de API Fuzzing"
msgid "APIFuzzing|Base URL of API testing target. For example, http://www.example.com."
-msgstr ""
+msgstr "URL base del objetivo de prueba de API. Por ejemplo, http://www.example.com."
msgid "APIFuzzing|Choose a method"
-msgstr ""
+msgstr "Seleccione un método"
msgid "APIFuzzing|Choose a profile"
-msgstr ""
+msgstr "Seleccione un perfil"
msgid "APIFuzzing|Code snippet could not be generated. Try again later."
msgstr ""
@@ -1556,12 +1567,12 @@ msgid "APIFuzzing|Customize common API fuzzing settings to suit your requirement
msgstr ""
msgid "APIFuzzing|Enable authentication"
-msgstr ""
+msgstr "Habilitar autenticación"
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -1574,40 +1585,40 @@ msgid "APIFuzzing|File path or URL to requests to be tested. For example, folder
msgstr ""
msgid "APIFuzzing|Generate code snippet"
-msgstr ""
+msgstr "Generar fragmento de código"
msgid "APIFuzzing|Make sure your credentials are secured"
-msgstr ""
+msgstr "Asegúrese de que sus credenciales están seguras"
msgid "APIFuzzing|Password for basic authentication"
-msgstr ""
+msgstr "Contraseña para la autenticación básica"
msgid "APIFuzzing|Predefined profiles"
-msgstr ""
+msgstr "Perfiles predefinidos"
msgid "APIFuzzing|Scan mode"
-msgstr ""
+msgstr "Modo de escaneo"
msgid "APIFuzzing|Scan profile"
-msgstr ""
+msgstr "Perfil de escaneo"
msgid "APIFuzzing|Show code snippet for the profile"
-msgstr ""
+msgstr "Mostrar fragmento de código para el perfil"
msgid "APIFuzzing|Target URL"
-msgstr ""
+msgstr "URL de destino"
msgid "APIFuzzing|There are three ways to perform scans."
-msgstr ""
+msgstr "Hay tres maneras de realizar escaneos."
msgid "APIFuzzing|Tip: Insert the following variables anywhere below stages and include"
msgstr ""
msgid "APIFuzzing|Tip: Insert this part below all include"
-msgstr ""
+msgstr "Sugerencia: Inserte esta parte debajo de todos los include"
msgid "APIFuzzing|Tip: Insert this part below all stages"
-msgstr ""
+msgstr "Sugerencia: Inserte esta parte debajo de todas las etapas"
msgid "APIFuzzing|To prevent a security leak, authentication info must be added as a %{ciVariablesLinkStart}CI variable%{ciVariablesLinkEnd}. A user with maintainer access rights can manage CI variables in the %{ciSettingsLinkStart}Settings%{ciSettingsLinkEnd} area. We detected that you are not a maintainer. Commit your changes and assign them to a maintainer to update the credentials before merging."
msgstr ""
@@ -1619,31 +1630,31 @@ msgid "APIFuzzing|Use this tool to generate API fuzzing configuration YAML to co
msgstr ""
msgid "APIFuzzing|Username for basic authentication"
-msgstr ""
+msgstr "Nombre de usuario para autenticación básica"
msgid "APIFuzzing|You may need a maintainer's help to secure your credentials."
msgstr ""
msgid "APIFuzzing|folder/example.postman_collection.json"
-msgstr ""
+msgstr "folder/example.postman_collection.json"
msgid "APIFuzzing|folder/example_fuzz.har"
-msgstr ""
+msgstr "folder/ejemplo_fuzz.har"
msgid "APIFuzzing|folder/openapi.json"
-msgstr ""
+msgstr "folder/openapi.json"
msgid "AWS Access Key"
msgstr "AWS Access Key"
msgid "AWS Access Key. Only required if not using role instance credentials"
-msgstr ""
+msgstr "Clave de acceso de AWS. Solo se requiere si no se están utilizando credenciales de instancia de rol"
msgid "AWS Secret Access Key"
msgstr "AWS Secret Access Key"
msgid "AWS Secret Access Key. Only required if not using role instance credentials"
-msgstr ""
+msgstr "Clave de acceso secreta de AWS. Solo se requiere si no se utilizan credenciales de instancia de rol"
msgid "AWS service error: %{error}"
msgstr "Error de servicio de AWS: %{error}"
@@ -1667,10 +1678,10 @@ msgid "Abuse reports"
msgstr "Informar de un abuso"
msgid "Abuse reports notification email"
-msgstr ""
+msgstr "Correo de notificación de informes de abuso"
msgid "Abuse reports will be sent to this address if it is set. Abuse reports are always available in the admin area."
-msgstr ""
+msgstr "Si se configura los informes de abuso serán enviados a esta dirección. Los informes de abuso siempre están disponibles en el área de administración."
msgid "Accept invitation"
msgstr "Aceptar invitación"
@@ -1682,7 +1693,7 @@ msgid "Acceptable for use in this project"
msgstr "Aceptable para su utilización en este proyecto"
msgid "Access Git repositories or the API."
-msgstr ""
+msgstr "Acceder a los repositorios Git o a la API."
msgid "Access Tokens"
msgstr "Tokens de acceso"
@@ -1694,28 +1705,28 @@ msgid "Access denied! Please verify you can add deploy keys to this repository."
msgstr "¡Acceso denegado! Por favor, verifique que puede agregar las claves de despliegue a este repositorio."
msgid "Access denied: %{error}"
-msgstr ""
+msgstr "Acceso denegado: %{error}"
msgid "Access expiration date"
msgstr "Fecha de expiración del acceso"
msgid "Access expires"
-msgstr ""
+msgstr "El acceso expira"
msgid "Access forbidden. Check your access level."
msgstr "Acceso denegado. Por favor, compruebe su nivel de acceso."
msgid "Access granted"
-msgstr ""
+msgstr "Acceso permitido"
msgid "Access requests"
-msgstr ""
+msgstr "Peticiones de acceso"
msgid "Access to '%{classification_label}' not allowed"
msgstr "El acceso a '%{classification_label}' no está permitido"
msgid "AccessDropdown|Deploy Keys"
-msgstr ""
+msgstr "Desplegar claves"
msgid "AccessDropdown|Groups"
msgstr "Grupos"
@@ -1751,13 +1762,13 @@ msgid "AccessTokens|It cannot be used to access any other data."
msgstr "No se puede utilizar para acceder a ningún otro dato."
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
-msgstr ""
+msgstr "Mantenga este token en secreto. Cualquiera que lo tenga puede acceder a los objetos estáticos del repositorio como si fuera usted. Si eso sucede alguna vez, %{reset_link_start}reinice este token%{reset_link_end}."
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
-msgstr ""
+msgstr "Mantenga este token en secreto. Cualquiera que lo tenga puede crear incidencias como si fuera usted. Si eso sucede, %{link_reset_it}."
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
-msgstr ""
+msgstr "Mantenga este token en secreto. Cualquiera que lo tenga puede leer la actividad o crear anuncios RSS o anuncios en su calendario como si fuera usted. Si eso sucede, %{link_reset_it}."
msgid "AccessTokens|Personal Access Tokens"
msgstr "Tokens de acceso personal"
@@ -1778,16 +1789,16 @@ msgid "AccessTokens|Your feed token authenticates you when your RSS reader loads
msgstr ""
msgid "AccessTokens|Your incoming email token authenticates you when you create a new issue by email, and is included in your personal project-specific email addresses."
-msgstr ""
+msgstr "Su token de correo electrónico entrante lo autentica cuando crea una nueva incidencia por correo electrónico y se incluye en las direcciones de correo electrónico específicas de su proyecto personal."
msgid "AccessTokens|Your static object token authenticates you when repository static objects (such as archives or blobs) are served from an external storage."
msgstr ""
msgid "AccessTokens|reset this token"
-msgstr ""
+msgstr "reiniciar este token"
msgid "AccessibilityReport|Learn more"
-msgstr ""
+msgstr "Obtener más información"
msgid "AccessibilityReport|Message: %{message}"
msgstr "Mensaje: %{message}"
@@ -1808,13 +1819,13 @@ msgid "Account and limit"
msgstr "Cuenta y límite"
msgid "Account:"
-msgstr ""
+msgstr "Cuenta:"
msgid "Account: %{account}"
msgstr "Cuenta: %{account}"
msgid "Action"
-msgstr ""
+msgstr "Acción"
msgid "Action to take when receiving an alert. %{docsLink}"
msgstr ""
@@ -1913,7 +1924,7 @@ msgid "Add a homepage to your wiki that contains information about your project
msgstr "Añada una página de inicio a su wiki que contenga información sobre su proyecto y GitLab la mostrará aquí en lugar de este mensaje."
msgid "Add a horizontal rule"
-msgstr ""
+msgstr "Añadir una regla horizontal"
msgid "Add a line"
msgstr "Añadir una línea"
@@ -1922,7 +1933,7 @@ msgid "Add a link"
msgstr "Añadir un enlace"
msgid "Add a link to Grafana"
-msgstr ""
+msgstr "Agregar un enlace a Grafana"
msgid "Add a new issue"
msgstr "Añadir una nueva incidencia"
@@ -1931,7 +1942,7 @@ msgid "Add a numbered list"
msgstr "Añadir una lista numerada"
msgid "Add a related issue"
-msgstr ""
+msgstr "Añadir una incidencia relacionada"
msgid "Add a table"
msgstr "Añadir tabla"
@@ -1964,7 +1975,7 @@ msgid "Add bold text"
msgstr "Añadir texto en negrita"
msgid "Add broadcast message"
-msgstr ""
+msgstr "Añadir mensaje de difusión"
msgid "Add child epic to an epic"
msgstr "Añadir una tarea épica hija a otra tarea épica"
@@ -1973,7 +1984,7 @@ msgid "Add comment now"
msgstr "Añadir comentario ahora"
msgid "Add comment to design"
-msgstr ""
+msgstr "Añadir comentario al diseño"
msgid "Add commit messages as comments to Asana tasks. %{docs_link}"
msgstr ""
@@ -1994,7 +2005,7 @@ msgid "Add email address"
msgstr "Añadir dirección de correo electrónico"
msgid "Add email participant(s)"
-msgstr ""
+msgstr "Añadir correos electrónicos de los participantes"
msgid "Add environment"
msgstr "Añadir entorno"
@@ -2036,10 +2047,10 @@ msgid "Add previously merged commits"
msgstr ""
msgid "Add project"
-msgstr ""
+msgstr "Añadir proyecto"
msgid "Add projects"
-msgstr ""
+msgstr "Añadir proyectos"
msgid "Add reaction"
msgstr "Añadir reacción"
@@ -2063,7 +2074,7 @@ msgid "Add to Slack"
msgstr "Añadir a Slack"
msgid "Add to board"
-msgstr ""
+msgstr "Agregar al tablero"
msgid "Add to epic"
msgstr "Agregar a la tarea épica"
@@ -2081,7 +2092,7 @@ msgid "Add to tree"
msgstr "Agregar al árbol"
msgid "Add trigger"
-msgstr ""
+msgstr "Añadir disparador"
msgid "Add user(s) to the group:"
msgstr "Añadir usuario(s) al grupo:"
@@ -2105,10 +2116,10 @@ msgid "AddContextCommits|Add/remove"
msgstr "Añadir/eliminar"
msgid "AddMember|Emails cannot be blank"
-msgstr ""
+msgstr "Los correos electrónicos no pueden estar en blanco"
msgid "AddMember|Invite email is invalid"
-msgstr ""
+msgstr "El correo electrónico de invitación no es válido"
msgid "AddMember|Invite limit of %{daily_invites} per day exceeded"
msgstr ""
@@ -2156,22 +2167,22 @@ msgid "Additional minutes"
msgstr "Minutos adicionales"
msgid "Additional minutes:"
-msgstr ""
+msgstr "Minutos adicionales:"
msgid "Additional text"
msgstr "Texto adicional"
msgid "Additional text for the sign-in and Help page."
-msgstr ""
+msgstr "Texto adicional para mostrar en la página de inicio de sesión y ayuda."
msgid "Additional text to show on the Help page"
-msgstr ""
+msgstr "Texto adicional para mostrar en la página de ayuda"
msgid "Additional text to show on the sign-in page"
-msgstr ""
+msgstr "Texto adicional para mostrar en la página de inicio de sesión"
msgid "Address"
-msgstr ""
+msgstr "Dirección"
msgid "Adds"
msgstr "Añadir"
@@ -2192,22 +2203,22 @@ msgid "Adds an issue to an epic."
msgstr "Agregar una incidencia a una tarea épica."
msgid "Adds email participant(s)"
-msgstr ""
+msgstr "Añadir correos electrónicos de los participantes"
msgid "Adjust how frequently the GitLab UI polls for updates."
-msgstr ""
+msgstr "Ajusta la frecuencia con la que la interfaz de usuario de GitLab busca actualizaciones."
msgid "Adjust your filters/search criteria above. If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
-msgstr ""
+msgstr "Ajuste sus filtros/criterios de búsqueda arriba. Si cree que puede tratarse de un error, consulte la documentación %{linkStart}Geo Troubleshooting%{linkEnd} para obtener más información."
msgid "Admin"
-msgstr ""
+msgstr "Administrador"
msgid "Admin Area"
msgstr "Ãrea de administración"
msgid "Admin Mode"
-msgstr ""
+msgstr "Modo de administrador"
msgid "Admin Note"
msgstr "Nota del administrador"
@@ -2237,13 +2248,13 @@ msgid "Admin notes"
msgstr "Notas del administrador"
msgid "AdminArea|%{billable_users_link_start}Learn more%{billable_users_link_end} about what defines a billable user"
-msgstr ""
+msgstr "%{billable_users_link_start}Más información%{billable_users_link_end} sobre lo que define a un usuario facturable"
msgid "AdminArea|Active users"
msgstr "Usuarios activos"
msgid "AdminArea|All users created in the instance, including users who are not %{billable_users_link_start}billable users%{billable_users_link_end}."
-msgstr ""
+msgstr "Todos los usuarios creados en la instancia, incluyendo quienes no son %{billable_users_link_start}usuarios facturables%{billable_users_link_end}."
msgid "AdminArea|Billable users"
msgstr "Usuarios facturables"
@@ -2255,7 +2266,7 @@ msgid "AdminArea|Bots"
msgstr "Bots"
msgid "AdminArea|Components"
-msgstr "AdminArea|Componentes"
+msgstr "Componentes"
msgid "AdminArea|Developer"
msgstr "Desarrollador"
@@ -2264,40 +2275,40 @@ msgid "AdminArea|Features"
msgstr "Características"
msgid "AdminArea|Groups"
-msgstr ""
+msgstr "Grupos"
msgid "AdminArea|Guest"
msgstr "Invitado"
msgid "AdminArea|Included Free in license"
-msgstr "AdminArea|Incluido gratis en la licencia"
+msgstr "Incluido gratis en la licencia"
msgid "AdminArea|Latest groups"
-msgstr "AdminArea|Grupos más recientes"
+msgstr "Grupos más recientes"
msgid "AdminArea|Latest projects"
-msgstr "AdminArea|Proyectos más recientes"
+msgstr "Proyectos más recientes"
msgid "AdminArea|Latest users"
-msgstr "AdminArea|Usuarios más recientes"
+msgstr "Usuarios más recientes"
msgid "AdminArea|Maintainer"
msgstr "Mantenedor"
msgid "AdminArea|New group"
-msgstr "AdminArea|Nuevo grupo"
+msgstr "Nuevo grupo"
msgid "AdminArea|New project"
-msgstr "AdminArea|Nuevo proyecto"
+msgstr "Nuevo proyecto"
msgid "AdminArea|New user"
-msgstr "AdminArea|Nuevo usuario"
+msgstr "Nuevo usuario"
msgid "AdminArea|Owner"
msgstr "Propietario"
msgid "AdminArea|Projects"
-msgstr ""
+msgstr "Proyectos"
msgid "AdminArea|Reporter"
msgstr "Reportador"
@@ -2318,7 +2329,7 @@ msgid "AdminArea|Total users"
msgstr "Usuarios totales"
msgid "AdminArea|Users"
-msgstr ""
+msgstr "Usuarios"
msgid "AdminArea|Users statistics"
msgstr "Estadísticas de usuarios"
@@ -2330,16 +2341,16 @@ msgid "AdminArea|Users without a Group and Project"
msgstr "Usuarios sin grupo y proyecto"
msgid "AdminArea|View latest groups"
-msgstr ""
+msgstr "Ver grupos más recientes"
msgid "AdminArea|View latest projects"
-msgstr ""
+msgstr "Ver proyectos más recientes"
msgid "AdminArea|View latest users"
-msgstr ""
+msgstr "Ver usuarios más recientes"
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
-msgstr "Está a punto de detener todos los trabajos. Esto detendrá todos los trabajos que se están ejecutando actualmente."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
+msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "Se ha producido un error al cargar las estadísticas. Por favor, inténtalo de nuevo"
@@ -2363,10 +2374,10 @@ msgid "AdminSettings|Auto DevOps domain"
msgstr "Dominio Auto DevOps"
msgid "AdminSettings|Configure Let's Encrypt"
-msgstr ""
+msgstr "Configurar Let's Encrypt"
msgid "AdminSettings|Disable feed token"
-msgstr ""
+msgstr "Deshabilitar el token del feed"
msgid "AdminSettings|Disable public access to Pages sites"
msgstr ""
@@ -2381,16 +2392,16 @@ msgid "AdminSettings|Feed token"
msgstr ""
msgid "AdminSettings|I have read and agree to the Let's Encrypt %{link_start}Terms of Service%{link_end} (PDF)."
-msgstr ""
+msgstr "He leído y acepto los %{link_start}términos de servicio%{link_end}(PDF) de Let's Encrypt."
msgid "AdminSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
msgid "AdminSettings|Keep the latest artifacts for all jobs in the latest successful pipelines"
-msgstr ""
+msgstr "Mantener los últimos artefactos para todos los trabajos en los últimos pipelines ejecutados correctamente"
msgid "AdminSettings|Let's Encrypt email"
-msgstr ""
+msgstr "Correo electrónico de Let's Encrypt"
msgid "AdminSettings|Maximum duration of a session for Git operations when 2FA is enabled."
msgstr ""
@@ -2402,7 +2413,7 @@ msgid "AdminSettings|No required pipeline"
msgstr "No se requiere un pipeline"
msgid "AdminSettings|Protect CI/CD variables by default"
-msgstr ""
+msgstr "Proteger las variables de CI/CD de forma predeterminada"
msgid "AdminSettings|Require users to prove ownership of custom domains"
msgstr ""
@@ -2411,7 +2422,7 @@ msgid "AdminSettings|Required pipeline configuration"
msgstr "Configuración del pipeline requerida"
msgid "AdminSettings|Select a CI/CD template"
-msgstr ""
+msgstr "Seleccionar una plantilla de CI/CD"
msgid "AdminSettings|Select a group to use as the source for instance-level project templates."
msgstr ""
@@ -2471,22 +2482,22 @@ msgid "AdminStatistics|Snippets"
msgstr "Fragmentos de código"
msgid "AdminUsers|(Admin)"
-msgstr "AdminUsers|(Admin)"
+msgstr ""
msgid "AdminUsers|(Banned)"
-msgstr ""
+msgstr "(Baneado)"
msgid "AdminUsers|(Blocked)"
-msgstr "AdminUsers|(Bloqueado)"
+msgstr ""
msgid "AdminUsers|(Deactivated)"
-msgstr "AdminUsers|(Desactivado)"
+msgstr ""
msgid "AdminUsers|(Internal)"
-msgstr "AdminUsers|(Interno)"
+msgstr ""
msgid "AdminUsers|(Pending approval)"
-msgstr "AdminUsers|(Pendiente de aprobación)"
+msgstr ""
msgid "AdminUsers|2FA Disabled"
msgstr "2FA desactivado"
@@ -2507,10 +2518,10 @@ msgid "AdminUsers|Access the API"
msgstr "Acceder a la API"
msgid "AdminUsers|Activate"
-msgstr ""
+msgstr "Activar"
msgid "AdminUsers|Activate user %{username}?"
-msgstr ""
+msgstr "¿Activar usuario %{username}?"
msgid "AdminUsers|Active"
msgstr "Activo"
@@ -2531,7 +2542,7 @@ msgid "AdminUsers|Approve"
msgstr "Aprobar"
msgid "AdminUsers|Approve user %{username}?"
-msgstr ""
+msgstr "¿Aprobar al usuario %{username}?"
msgid "AdminUsers|Approved users can:"
msgstr "Los usuarios aprobados pueden:"
@@ -2540,13 +2551,13 @@ msgid "AdminUsers|Automatically marked as default internal user"
msgstr ""
msgid "AdminUsers|Ban user"
-msgstr ""
+msgstr "Banear usuario"
msgid "AdminUsers|Ban user %{username}?"
-msgstr ""
+msgstr "Banear al usuario %{username}?"
msgid "AdminUsers|Banned"
-msgstr ""
+msgstr "Baneado"
msgid "AdminUsers|Be added to groups and projects"
msgstr "Ser añadido a grupos y proyectos"
@@ -2566,14 +2577,8 @@ msgstr "Bloqueado"
msgid "AdminUsers|Blocking user has the following effects:"
msgstr "Bloquear usuario tiene los siguientes efectos:"
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
-msgstr ""
+msgstr "No se puede iniciar sesión ni accesar a la información de la instancia"
msgid "AdminUsers|Cannot unblock LDAP blocked users"
msgstr "No se pueden desbloquear los usuarios bloqueados de LDAP"
@@ -2582,10 +2587,10 @@ msgid "AdminUsers|Cohorts"
msgstr ""
msgid "AdminUsers|Confirm user"
-msgstr ""
+msgstr "Confirmar usuario"
msgid "AdminUsers|Confirm user %{username}?"
-msgstr ""
+msgstr "¿Confirmar usuario %{username}?"
msgid "AdminUsers|Could not load user group counts. Please refresh the page to try again."
msgstr ""
@@ -2594,7 +2599,7 @@ msgid "AdminUsers|Deactivate"
msgstr "Desactivar"
msgid "AdminUsers|Deactivate user %{username}?"
-msgstr ""
+msgstr "¿Desactivar usuario %{username}?"
msgid "AdminUsers|Deactivated"
msgstr "Desactivado"
@@ -2615,7 +2620,7 @@ msgid "AdminUsers|Delete user and contributions"
msgstr "Eliminar el usuario y sus colaboraciones"
msgid "AdminUsers|Export permissions as CSV"
-msgstr ""
+msgstr "Exportar permisos como CSV"
msgid "AdminUsers|External"
msgstr "Externos"
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr "Está utilizando un asiento"
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr "¡Es usted!"
@@ -2645,10 +2653,10 @@ msgid "AdminUsers|Learn more about %{link_start}banned users.%{link_end}"
msgstr ""
msgid "AdminUsers|Log in"
-msgstr ""
+msgstr "Iniciar sesión"
msgid "AdminUsers|Manage (accept/reject) pending user sign ups"
-msgstr ""
+msgstr "Administrar (aceptar/rechazar) registros de usuarios pendientes"
msgid "AdminUsers|New user"
msgstr "Nuevo usuario"
@@ -2672,19 +2680,19 @@ msgid "AdminUsers|Reactivating a user will:"
msgstr "Al reactivar un usuario:"
msgid "AdminUsers|Regular"
-msgstr ""
+msgstr "Habituales"
msgid "AdminUsers|Regular users have access to their groups and projects"
-msgstr ""
+msgstr "Los usuarios habituales tienen acceso a sus grupos y proyectos"
msgid "AdminUsers|Reject"
-msgstr ""
+msgstr "Rechazar"
msgid "AdminUsers|Reject user %{username}?"
-msgstr ""
+msgstr "¿Rechazar usuario %{username}?"
msgid "AdminUsers|Rejected users:"
-msgstr ""
+msgstr "Usuarios rechazados:"
msgid "AdminUsers|Restore user access to the account, including web, Git and API."
msgstr "Restaure el acceso del usuario a la cuenta, esto incluye la web, Git y API."
@@ -2701,6 +2709,12 @@ msgstr "Enviar correo electrónico a los usuarios"
msgid "AdminUsers|Sort by"
msgstr "Ordenar por"
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr "El usuario será desconectado"
@@ -2723,25 +2737,25 @@ msgid "AdminUsers|To confirm, type %{username}"
msgstr "Para confirmar, escriba %{username}"
msgid "AdminUsers|Unban user"
-msgstr ""
+msgstr "Desbloquear usuario"
msgid "AdminUsers|Unban user %{username}?"
-msgstr ""
+msgstr "¿Desbloquear usuario %{username}?"
msgid "AdminUsers|Unblock"
-msgstr ""
+msgstr "Desbloquear"
msgid "AdminUsers|Unblock user %{username}?"
-msgstr ""
+msgstr "¿Desbloquear usuario %{username}?"
msgid "AdminUsers|Unlock user %{username}?"
-msgstr ""
+msgstr "¿Desbloquear usuario %{username}?"
msgid "AdminUsers|User administration"
-msgstr ""
+msgstr "Administración de usuarios"
msgid "AdminUsers|User is validated and can use free CI minutes on shared runners."
-msgstr ""
+msgstr "El usuario está validado y puede utilizar minutos CI gratuitos en los ejecutores compartidos."
msgid "AdminUsers|User will not be able to access git repositories"
msgstr "El usuario no podrá acceder a los repositorios git"
@@ -2750,31 +2764,31 @@ msgid "AdminUsers|User will not be able to login"
msgstr "El usuario no podrá iniciar sesión"
msgid "AdminUsers|Users"
-msgstr ""
+msgstr "Usuarios"
msgid "AdminUsers|Users can still be invited to your instance and/or add themselves if permitted based on your settings. They will not have access to your instance, nor count towards your subscribed seat count until you %{approve_link}."
msgstr ""
msgid "AdminUsers|Validate user account"
-msgstr ""
+msgstr "Validar cuenta de usuario"
msgid "AdminUsers|View pending member requests"
-msgstr ""
+msgstr "Ver solicitudes pendientes de miembros"
msgid "AdminUsers|What can I do?"
-msgstr ""
+msgstr "¿Qué puedo hacer?"
msgid "AdminUsers|What does this mean?"
-msgstr ""
+msgstr "¿Qué significa esto?"
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
msgstr "Cuando el usuario vuelve a iniciar sesión, su cuenta se activará como una cuenta totalmente activa"
msgid "AdminUsers|Will be deleted"
-msgstr ""
+msgstr "Se eliminarán"
msgid "AdminUsers|Without projects"
msgstr "Sin proyectos"
@@ -2804,25 +2818,25 @@ msgid "AdminUsers|You can unban their account in the future. Their data remains
msgstr ""
msgid "AdminUsers|You cannot remove your own admin rights."
-msgstr ""
+msgstr "No puede eliminar sus propios derechos de administración."
msgid "AdminUsers|You must transfer ownership or delete the groups owned by this user before you can delete their account"
-msgstr ""
+msgstr "Debe transferir la propiedad o eliminar los grupos que son propiedad de este usuario antes de poder eliminar su cuenta"
msgid "AdminUsers|Your GitLab instance has reached the maximum allowed %{user_doc_link} set by an instance admin."
-msgstr ""
+msgstr "Su instancia de GitLab ha alcanzado el máximo permitido de %{user_doc_link} establecido por un administrador de instancia."
msgid "AdminUsers|approve them"
-msgstr ""
+msgstr "aprobarlos"
msgid "AdminUsers|contact our support team"
-msgstr ""
+msgstr "contacte con nuestro equipo de soporte"
msgid "AdminUsers|docs"
-msgstr ""
+msgstr "docs"
msgid "AdminUsers|user cap"
-msgstr ""
+msgstr "límite de usuarios"
msgid "Administration"
msgstr "‫Administración"
@@ -2831,16 +2845,16 @@ msgid "Admin|Additional users must be reviewed and approved by a system administ
msgstr ""
msgid "Admin|Admin notes"
-msgstr ""
+msgstr "Notas del administrador"
msgid "Admin|Learn more about quarterly reconciliation"
-msgstr ""
+msgstr "Obtenga más información sobre la conciliación trimestral"
msgid "Admin|Note"
-msgstr ""
+msgstr "Nota"
msgid "Admin|Quarterly reconciliation will occur on %{qrtlyDate}"
-msgstr ""
+msgstr "La conciliación trimestral se producirá el %{qrtlyDate}"
msgid "Admin|The number of max seats used for your namespace is currently exceeding the number of seats in your subscription. On %{qrtlyDate}, GitLab will process a quarterly reconciliation and automatically bill you a prorated amount for the overage. There is no action needed from you. If you have a credit card on file, it will be charged. Otherwise, you will receive an invoice."
msgstr ""
@@ -2849,10 +2863,10 @@ msgid "Admin|The number of maximum users for your instance is currently exceedin
msgstr ""
msgid "Admin|View pending user approvals"
-msgstr ""
+msgstr "Ver aprobaciones de usuarios pendientes."
msgid "Admin|Your instance has reached its user cap"
-msgstr ""
+msgstr "Tu instancia ha alcanzado su límite de usuarios"
msgid "Advanced"
msgstr "Avanzado"
@@ -2864,7 +2878,7 @@ msgid "Advanced Settings"
msgstr "Configuración avanzada"
msgid "Advanced export options"
-msgstr ""
+msgstr "Opciones de exportación avanzadas"
msgid "Advanced permissions, Large File Storage and Two-Factor authentication settings."
msgstr "Permisos avanzados, almacenamiento de grandes archivos y configuraciones de autenticación de dos factores."
@@ -2888,7 +2902,7 @@ msgid "After you've reviewed these contribution guidelines, you'll be all set to
msgstr ""
msgid "Akismet API Key"
-msgstr ""
+msgstr "Clave de API de Akismet"
msgid "Alert"
msgid_plural "Alerts"
@@ -2899,7 +2913,7 @@ msgid "AlertManagement|Acknowledged"
msgstr "Confirmado"
msgid "AlertManagement|Activity feed"
-msgstr ""
+msgstr "Feed de actividad"
msgid "AlertManagement|Alert"
msgstr "Alerta"
@@ -2932,7 +2946,7 @@ msgid "AlertManagement|Authorize external service"
msgstr "Autorizar un servicio externo"
msgid "AlertManagement|Create incident"
-msgstr ""
+msgstr "Crear incidente"
msgid "AlertManagement|Display alerts from all your monitoring tools directly within GitLab. Streamline the investigation of your alerts and the escalation of alerts to incidents."
msgstr ""
@@ -2941,7 +2955,7 @@ msgid "AlertManagement|Edit"
msgstr "Editar"
msgid "AlertManagement|Environment"
-msgstr "AlertManagement|Entorno"
+msgstr ""
msgid "AlertManagement|Events"
msgstr "Eventos"
@@ -2950,10 +2964,10 @@ msgid "AlertManagement|Incident"
msgstr "Incidente"
msgid "AlertManagement|Key"
-msgstr "AlertManagement|Clave"
+msgstr ""
msgid "AlertManagement|Metrics"
-msgstr "AlertManagement|Métricas"
+msgstr ""
msgid "AlertManagement|Metrics weren't available in the alerts payload."
msgstr ""
@@ -3037,7 +3051,7 @@ msgid "AlertManagement|Value"
msgstr "Valor"
msgid "AlertManagement|View incident"
-msgstr ""
+msgstr "Ver incidente"
msgid "AlertMappingBuilder|Define fallback"
msgstr ""
@@ -3046,13 +3060,13 @@ msgid "AlertMappingBuilder|GitLab alert key"
msgstr ""
msgid "AlertMappingBuilder|Make selection"
-msgstr ""
+msgstr "Hacer selección"
msgid "AlertMappingBuilder|Payload alert key"
msgstr ""
msgid "AlertMappingBuilder|Select key"
-msgstr ""
+msgstr "Seleccionar clave"
msgid "AlertMappingBuilder|Title is a required field for alerts in GitLab. Should the payload field you specified not be available, specifiy which field we should use instead. "
msgstr ""
@@ -3061,40 +3075,40 @@ msgid "AlertSettings|A webhook URL and authorization key is generated for the in
msgstr ""
msgid "AlertSettings|Add new integration"
-msgstr ""
+msgstr "Añadir nueva integración"
msgid "AlertSettings|Alert settings"
-msgstr ""
+msgstr "Configuración de alertas"
msgid "AlertSettings|Authorization key"
msgstr "Clave de autorización"
msgid "AlertSettings|Configure details"
-msgstr ""
+msgstr "Configurar detalles"
msgid "AlertSettings|Current integrations"
-msgstr ""
+msgstr "Integraciones actuales"
msgid "AlertSettings|Customize alert payload mapping (optional)"
msgstr ""
msgid "AlertSettings|Delete integration"
-msgstr ""
+msgstr "Eliminar integración"
msgid "AlertSettings|Edit integration"
-msgstr ""
+msgstr "Editar integración"
msgid "AlertSettings|Edit payload"
msgstr ""
msgid "AlertSettings|Enable integration"
-msgstr ""
+msgstr "Habilitar integración"
msgid "AlertSettings|Enter an example payload from your selected monitoring tool. This supports sending alerts to a GitLab endpoint."
msgstr ""
msgid "AlertSettings|Enter integration name"
-msgstr "Ajustes de Alertas|Introduce tu nombre de integración"
+msgstr "Introduce tu nombre de integración"
msgid "AlertSettings|Free versions of GitLab are limited to one integration per type. To add more, %{linkStart}upgrade your subscription%{linkEnd}."
msgstr ""
@@ -3103,7 +3117,7 @@ msgid "AlertSettings|GitLab has created a URL and authorization key for your int
msgstr ""
msgid "AlertSettings|HTTP Endpoint"
-msgstr ""
+msgstr "Endpoint HTTP"
msgid "AlertSettings|If you edit the payload, you must re-map the fields again."
msgstr ""
@@ -3124,40 +3138,40 @@ msgid "AlertSettings|Proceed with editing"
msgstr ""
msgid "AlertSettings|Prometheus"
-msgstr ""
+msgstr "Prometheus"
msgid "AlertSettings|Prometheus API base URL"
-msgstr ""
+msgstr "URL base del API de Prometheus"
msgid "AlertSettings|Reset Key"
msgstr "Restablecer clave"
msgid "AlertSettings|Reset the mapping"
-msgstr ""
+msgstr "Restablecer el mapeo"
msgid "AlertSettings|Sample payload has been parsed. You can now map the fields."
msgstr ""
msgid "AlertSettings|Save & create test alert"
-msgstr ""
+msgstr "Guardar y crear alerta de prueba"
msgid "AlertSettings|Save integration"
msgstr "Guardar integración"
msgid "AlertSettings|Save integration & send"
-msgstr ""
+msgstr "Guardar integración y enviar"
msgid "AlertSettings|Select integration type"
msgstr "Seleccionar tipo de integración"
msgid "AlertSettings|Send test alert"
-msgstr ""
+msgstr "Enviar alerta de prueba"
msgid "AlertSettings|Send without saving"
-msgstr ""
+msgstr "Enviar sin guardar"
msgid "AlertSettings|The form has unsaved changes"
-msgstr ""
+msgstr "El formulario tiene cambios sin guardar"
msgid "AlertSettings|The form has unsaved changes. How would you like to proceed?"
msgstr ""
@@ -3175,13 +3189,13 @@ msgid "AlertSettings|Use the URL and authorization key below to configure how an
msgstr ""
msgid "AlertSettings|View URL and authorization key"
-msgstr ""
+msgstr "Ver la URL y la clave de autorización"
msgid "AlertSettings|View credentials"
-msgstr ""
+msgstr "Ver credenciales"
msgid "AlertSettings|Webhook URL"
-msgstr "AlertSettings|URL del webhook"
+msgstr "URL del webhook"
msgid "AlertSettings|You can map default GitLab alert fields to your payload keys in the dropdowns below."
msgstr ""
@@ -3211,7 +3225,7 @@ msgid "AlertsIntegrations|Integration payload is invalid."
msgstr ""
msgid "AlertsIntegrations|No integrations have been added yet."
-msgstr ""
+msgstr "Todavía no se han agregado integraciones."
msgid "AlertsIntegrations|The current integration could not be updated. Please try again."
msgstr ""
@@ -3226,10 +3240,10 @@ msgid "AlertsIntegrations|The integration is currently inactive. Enable the inte
msgstr ""
msgid "AlertsIntegrations|The integration is deleted."
-msgstr ""
+msgstr "La integración está eliminada."
msgid "AlertsIntegrations|The integration is saved."
-msgstr ""
+msgstr "La integración está guardada."
msgid "AlertsIntegrations|The integration token could not be reset. Please try again."
msgstr ""
@@ -3325,13 +3339,13 @@ msgid "Allow owners to manage default branch protection per group"
msgstr ""
msgid "Allow owners to manually add users outside of LDAP"
-msgstr ""
+msgstr "Permitir a los propietarios añadir manualmente usuarios fuera de LDAP"
msgid "Allow password authentication for Git over HTTP(S)"
-msgstr ""
+msgstr "Permitir la autenticación con contraseña para Git a través de HTTP(S)"
msgid "Allow password authentication for the web interface"
-msgstr ""
+msgstr "Permitir la autenticación con contraseña para la interfaz web"
msgid "Allow project maintainers to configure repository mirroring"
msgstr ""
@@ -3358,7 +3372,7 @@ msgid "Allow subgroups to set up their own two-factor authentication rules"
msgstr "Permitir que los subgrupos configuren sus propias reglas de autenticación de dos factores"
msgid "Allow this key to push to this repository"
-msgstr ""
+msgstr "Permitir a esta clave hacer push a este repositorio"
msgid "Allow this secondary node to replicate content on Object Storage"
msgstr ""
@@ -3379,13 +3393,13 @@ msgid "Allowed Geo IP"
msgstr "Geo IP permitida"
msgid "Allowed characters: +, 0-9, -, and spaces."
-msgstr ""
+msgstr "Caracteres permitidos: +, 0-9, - y espacios."
msgid "Allowed email domain restriction only permitted for top-level groups"
msgstr "Sólo los grupos de nivel superior pueden restringir los dominios de correo electrónico permitidos"
msgid "Allowed to create:"
-msgstr ""
+msgstr "Autorizado a crear:"
msgid "Allowed to fail"
msgstr "Permitido fallar"
@@ -3400,13 +3414,13 @@ msgid "Almost there"
msgstr "¡Ya queda poco!"
msgid "Almost there..."
-msgstr ""
+msgstr "Falta poco..."
msgid "Already blocked"
msgstr "Ya está bloqueado"
msgid "Already have login and password?"
-msgstr ""
+msgstr "¿Ya tiene nombre de usuario y contraseña?"
msgid "Also called \"Issuer\" or \"Relying party trust identifier\""
msgstr "También llamado \"emisor\" o \"identificador de confianza\""
@@ -3451,7 +3465,7 @@ msgid "An administrator changed the password for your GitLab account on %{link_t
msgstr ""
msgid "An alert has been resolved in %{project_path}."
-msgstr ""
+msgstr "Se ha resuelto una alerta en %{project_path}."
msgid "An alert has been triggered in %{project_path}."
msgstr "Se ha disparado una alerta en %{project_path}."
@@ -3499,7 +3513,7 @@ msgid "An error occurred previewing the blob"
msgstr "Ha ocurrido un error visualizando el blob"
msgid "An error occurred when removing the label."
-msgstr ""
+msgstr "Se ha producido un error al eliminar la etiqueta."
msgid "An error occurred when toggling the notification subscription"
msgstr "Se produjo un error al activar/desactivar la suscripción de notificación"
@@ -3508,10 +3522,10 @@ msgid "An error occurred when updating the issue weight"
msgstr "Se ha producido un error al actualizar el tamaño de la incidencia"
msgid "An error occurred when updating the title"
-msgstr ""
+msgstr "Se ha producido un error al actualizar el título"
msgid "An error occurred while acknowledging the notification. Refresh the page and try again."
-msgstr ""
+msgstr "Se ha producido un error al confirmar la notificación. Actualice la página e intente nuevamente."
msgid "An error occurred while adding approvers"
msgstr "Se ha producido un error al añadir los aprobadores."
@@ -3520,7 +3534,7 @@ msgid "An error occurred while adding formatted title for epic"
msgstr "Se ha producido un error al añadir el título formateado para la tarea épica"
msgid "An error occurred while authorizing your role"
-msgstr ""
+msgstr "Se ha producido un error al autorizar su rol"
msgid "An error occurred while checking group path. Please refresh and try again."
msgstr "Se ha producido un error durante la comprobación de ruta del grupo. Por favor, actualice y vuelva a intentarlo."
@@ -3550,22 +3564,22 @@ msgid "An error occurred while dismissing the feature highlight. Refresh the pag
msgstr "Se ha producido un error al desactivar la función resaltar. Actualice la página y vuelva a intentarlo."
msgid "An error occurred while drawing job relationship links."
-msgstr ""
+msgstr "Se ha producido un error al representar los enlaces de relaciones del trabajo."
msgid "An error occurred while enabling Service Desk."
msgstr "Se ha producido un error al habilitar Service Desk."
msgid "An error occurred while fetching ancestors"
-msgstr ""
+msgstr "Se ha producido un error al obtener los ancestros"
msgid "An error occurred while fetching branches. Retry the search."
-msgstr ""
+msgstr "Se ha producido un error al recuperar las ramas. Por favor, vuelva a intentar la búsqueda."
msgid "An error occurred while fetching codequality mr diff reports."
msgstr ""
msgid "An error occurred while fetching commits. Retry the search."
-msgstr ""
+msgstr "Se ha producido un error al obtener los commits. Por favor, vuelva a intentar la búsqueda."
msgid "An error occurred while fetching coverage reports."
msgstr "Se ha producido un error al recuperar los informes de cobertura."
@@ -3589,10 +3603,10 @@ msgid "An error occurred while fetching markdown preview"
msgstr "Se ha producido un error al obtener la previsualización del markdown."
msgid "An error occurred while fetching participants"
-msgstr ""
+msgstr "Se ha producido un error al obtener los participantes"
msgid "An error occurred while fetching participants."
-msgstr ""
+msgstr "Se ha producido un error al obtener los participantes"
msgid "An error occurred while fetching pending comments"
msgstr "Se ha producido un error al recuperar los comentarios pendientes"
@@ -3601,25 +3615,22 @@ msgid "An error occurred while fetching projects autocomplete."
msgstr "Se ha producido un error al obtener la información de autocompletado de los proyectos."
msgid "An error occurred while fetching reference"
-msgstr ""
+msgstr "Se ha producido un error al obtener referencias"
msgid "An error occurred while fetching sidebar data"
msgstr "Se ha producido un error al obtener los datos de la barra lateral."
msgid "An error occurred while fetching tags. Retry the search."
-msgstr ""
+msgstr "Se ha producido un error al recuperar los tags. Por favor, vuelva a intentar la búsqueda."
msgid "An error occurred while fetching terraform reports."
msgstr "Se ha producido un error al obtener los informes de terraform."
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr "Se ha producido un error al obtener la lista de tableros. Por favor vuelva a intentarlo."
-
msgid "An error occurred while fetching the job log."
msgstr "Se ha producido un error al obtener el log del trabajo."
msgid "An error occurred while fetching the job logs."
-msgstr ""
+msgstr "Se ha producido un error al obtener los logs del trabajo."
msgid "An error occurred while fetching the job."
msgstr "Se ha producido un error al obtener el trabajo."
@@ -3630,9 +3641,6 @@ msgstr "Se ha producido un error al obtener los trabajos."
msgid "An error occurred while fetching the latest pipeline."
msgstr "Se ha producido un error al obtener el último pipeline."
-msgid "An error occurred while fetching the pipeline."
-msgstr "Se ha producido un error mientras se obtenía el pipeline."
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr "Se ha producido un error al obtener las versiones. Por favor, inténtelo de nuevo."
@@ -3643,13 +3651,13 @@ msgid "An error occurred while generating a username. Please try again."
msgstr "Se ha producido un error al generar un nombre de usuario. Por favor, inténtelo de nuevo."
msgid "An error occurred while getting autocomplete data. Please refresh the page and try again."
-msgstr ""
+msgstr "Se ha producido un error al obtener datos de autocompletado. Por favor, actualice la página e inténtelo de nuevo."
msgid "An error occurred while getting files for - %{branchId}"
msgstr "Se ha producido un error al obtener los archivos de - %{branchId}"
msgid "An error occurred while getting issue counts"
-msgstr ""
+msgstr "Se ha producido un error al obtener el número total de incidencias"
msgid "An error occurred while getting projects"
msgstr "Se ha producido un error al obtener los proyectos"
@@ -3658,7 +3666,7 @@ msgid "An error occurred while initializing path locks"
msgstr "Se ha producido un error al inicializar los bloqueos de ruta."
msgid "An error occurred while loading a section of this page."
-msgstr ""
+msgstr "Se ha producido un error al cargar una sección de esta página."
msgid "An error occurred while loading all the files."
msgstr "Se ha producido un error al cargar todos los archivos."
@@ -3687,9 +3695,15 @@ msgstr "Se ha producido un error al cargar las incidencias"
msgid "An error occurred while loading merge requests."
msgstr "Se ha producido un error al cargar los merge requests."
-msgid "An error occurred while loading the access tokens form, please try again."
+msgid "An error occurred while loading the Needs tab."
msgstr ""
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
+msgid "An error occurred while loading the access tokens form, please try again."
+msgstr "Se ha producido un error al cargar el formulario de tokens de acceso. Por favor, inténtelo de nuevo."
+
msgid "An error occurred while loading the data. Please try again."
msgstr "Se ha producido un error al cargar los datos. Por favor, inténtelo de nuevo."
@@ -3706,7 +3720,7 @@ msgid "An error occurred while loading the file. Please try again later."
msgstr "Se ha producido un error al cargar el archivo. Por favor, inténtelo más tarde."
msgid "An error occurred while loading the file. Please try again."
-msgstr ""
+msgstr "Se ha producido un error al cargar el archivo. Por favor, inténtelo de nuevo."
msgid "An error occurred while loading the merge request changes."
msgstr "Se ha producido un error al cargar los cambios del merge request."
@@ -3718,13 +3732,13 @@ msgid "An error occurred while loading the merge request."
msgstr "Se ha producido un error al cargar el merge request."
msgid "An error occurred while loading the notification settings. Please try again."
-msgstr ""
+msgstr "Se ha producido un error al cargar la configuración de notificaciones. Por favor, inténtelo de nuevo."
msgid "An error occurred while loading the pipeline."
-msgstr ""
+msgstr "Se ha producido un error al cargar el pipeline."
msgid "An error occurred while loading the pipelines jobs."
-msgstr "Se ha producido un error al cargar los trabajos de lo pipelines."
+msgstr "Se ha producido un error al cargar los trabajos de los pipelines."
msgid "An error occurred while loading your content. Please try again."
msgstr ""
@@ -3763,13 +3777,13 @@ msgid "An error occurred while retrieving diff"
msgstr "Se ha producido un error durante la recuperación de diff"
msgid "An error occurred while retrieving diff files"
-msgstr ""
+msgstr "Se ha producido un error al recuperar los archivos diff"
msgid "An error occurred while retrieving projects."
msgstr "Se ha producido un error al obtener los proyectos."
msgid "An error occurred while saving changes: %{error}"
-msgstr ""
+msgstr "Se ha producido un error al guardar los cambios: %{error}"
msgid "An error occurred while subscribing to notifications."
msgstr "Se ha producido un error al suscribirse a las notificaciones."
@@ -3790,7 +3804,7 @@ msgid "An error occurred while updating approvers"
msgstr "Se ha producido un error al actualizar los aprobadores"
msgid "An error occurred while updating assignees."
-msgstr ""
+msgstr "Se ha producido un error cuando se actualizaban los asignados"
msgid "An error occurred while updating configuration."
msgstr "Se ha producido un error al actualizar la configuración."
@@ -3802,16 +3816,16 @@ msgid "An error occurred while updating the comment"
msgstr "Se ha producido un error al actualizar el comentario"
msgid "An error occurred while updating the configuration."
-msgstr ""
+msgstr "Se ha producido un error mientras se actualizaba la configuración."
msgid "An error occurred while updating the notification settings. Please try again."
msgstr ""
msgid "An error occurred while uploading the file. Please try again."
-msgstr ""
+msgstr "Se ha producido un error al subir el archivo. Por favor, inténtelo de nuevo."
msgid "An error occurred while uploading the image. Please try again."
-msgstr ""
+msgstr "Se ha producido un error al subir la imagen. Por favor, inténtelo de nuevo."
msgid "An error occurred while validating group path"
msgstr "Se ha producido un error al validar la ruta del grupo"
@@ -3883,13 +3897,13 @@ msgid "Analyze your source code for known vulnerabilities."
msgstr "Analiza el código fuente en busca de vulnerabilidades conocidas."
msgid "Analyzing file…"
-msgstr ""
+msgstr "Analizando archivo…"
msgid "Ancestors"
msgstr "Antepasados"
msgid "And this registration token:"
-msgstr ""
+msgstr "Y este token de registro:"
msgid "Anonymous"
msgstr "Anónimo"
@@ -3913,7 +3927,7 @@ msgid "Any Author"
msgstr "Cualquier autor"
msgid "Any Milestone"
-msgstr ""
+msgstr "Cualquier hito"
msgid "Any branch"
msgstr "Cualquier rama"
@@ -3931,7 +3945,7 @@ msgid "Any label"
msgstr "Cualquier etiqueta"
msgid "Any member with at least Developer permissions on the project."
-msgstr ""
+msgstr "Cualquier miembro con al menos permisos de desarrollador en el proyecto."
msgid "Any milestone"
msgstr "Cualquier hito"
@@ -4013,10 +4027,10 @@ msgid "ApplicationSettings|Domain denylist"
msgstr ""
msgid "ApplicationSettings|Email restrictions"
-msgstr ""
+msgstr "Restricciones de correo electrónico"
msgid "ApplicationSettings|Email restrictions for sign-ups"
-msgstr ""
+msgstr "Restricciones de correo electrónico para los registros"
msgid "ApplicationSettings|Enable domain denylist for sign ups"
msgstr ""
@@ -4028,7 +4042,7 @@ msgid "ApplicationSettings|Enter denylist manually"
msgstr ""
msgid "ApplicationSettings|Markdown enabled"
-msgstr ""
+msgstr "Markdown habilitado"
msgid "ApplicationSettings|Minimum password length (number of characters)"
msgstr ""
@@ -4046,7 +4060,7 @@ msgid "ApplicationSettings|Restricts sign-ups for email addresses that match the
msgstr ""
msgid "ApplicationSettings|Save changes"
-msgstr ""
+msgstr "Guardar cambios"
msgid "ApplicationSettings|See GitLab's %{linkStart}Password Policy Guidelines%{linkEnd}"
msgstr ""
@@ -4061,7 +4075,7 @@ msgid "ApplicationSettings|Upload denylist file"
msgstr ""
msgid "ApplicationSettings|User cap"
-msgstr ""
+msgstr "Límite de usuarios"
msgid "ApplicationSettings|Users with e-mail addresses that match these domain(s) will NOT be able to sign-up. Wildcards allowed. Use separate lines for multiple entries. Ex: domain.com, *.domain.com"
msgstr ""
@@ -4127,7 +4141,7 @@ msgid "Applying suggestions..."
msgstr "Aplicando sugerencias..."
msgid "Approval Status"
-msgstr ""
+msgstr "Estado de aprobación"
msgid "Approval rules"
msgstr "Reglas de aprobación"
@@ -4136,7 +4150,7 @@ msgid "Approval rules reset to project defaults"
msgstr "Reglas de aprobación restablecidas a los valores predeterminados del proyecto"
msgid "Approval settings"
-msgstr ""
+msgstr "Configuración de aprobación"
msgid "ApprovalRuleRemove|%d member"
msgid_plural "ApprovalRuleRemove|%d members"
@@ -4158,32 +4172,38 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] "%{count} aprobación requerida para %{membersCount}"
msgstr[1] "%{count} aprobaciones requeridas para %{membersCount}"
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
-msgstr ""
+msgstr "Añadir aprobadores"
msgid "ApprovalRule|All scanners"
+msgstr "Todos los escáneres"
+
+msgid "ApprovalRule|All severity levels"
msgstr ""
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
-msgid "ApprovalRule|Approval rules"
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
msgstr ""
+msgid "ApprovalRule|Approval rules"
+msgstr "Reglas de aprobación"
+
msgid "ApprovalRule|Approvals required"
-msgstr ""
+msgstr "Aprobaciones requeridas"
msgid "ApprovalRule|Approver Type"
-msgstr ""
+msgstr "Tipo de aprobador"
msgid "ApprovalRule|Approvers"
msgstr "Aprobadores"
msgid "ApprovalRule|Examples: QA, Security."
-msgstr ""
+msgstr "Ejemplos: QA, Seguridad."
msgid "ApprovalRule|Name"
msgstr "Nombre"
@@ -4197,40 +4217,55 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr "Nombre de la regla"
msgid "ApprovalRule|Security scanners"
-msgstr ""
+msgstr "Escáneres de seguridad"
msgid "ApprovalRule|Select All"
-msgstr ""
+msgstr "Seleccionar todo"
msgid "ApprovalRule|Select scanners"
+msgstr "Seleccionar escáneres"
+
+msgid "ApprovalRule|Select severity levels"
msgstr ""
-msgid "ApprovalRule|Target branch"
+msgid "ApprovalRule|Severity levels"
msgstr ""
+msgid "ApprovalRule|Target branch"
+msgstr "Branch de destino"
+
msgid "ApprovalRule|Vulnerabilities allowed"
-msgstr ""
+msgstr "Vulnerabilidades permitidas"
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4312,7 +4347,7 @@ msgid "Archived"
msgstr "Archivado"
msgid "Archived (%{movedToStart}moved%{movedToEnd})"
-msgstr ""
+msgstr "Archivado (%{movedToStart}movido%{movedToEnd})"
msgid "Archived in this version"
msgstr "Archivado en esta versión"
@@ -4339,6 +4374,9 @@ msgid "Are you sure that you want to unarchive this project?"
msgstr "¿Está seguro de que desea desarchivar este proyecto?"
msgid "Are you sure you want to %{action} %{name}?"
+msgstr "¿Está seguro que desea %{action} %{name}?"
+
+msgid "Are you sure you want to attempt to merge?"
msgstr ""
msgid "Are you sure you want to cancel editing this comment?"
@@ -4357,7 +4395,7 @@ msgid "Are you sure you want to delete this %{typeOfComment}?"
msgstr "¿Esta seguro de que desea eliminar esto %{typeOfComment}?"
msgid "Are you sure you want to delete this SSH key?"
-msgstr ""
+msgstr "¿Está seguro de que desea eliminar la clave SSH?"
msgid "Are you sure you want to delete this device? This action cannot be undone."
msgstr "¿Está seguro de que desea borrar este dispositivo? Esta acción no se puede deshacer."
@@ -4375,21 +4413,21 @@ msgid "Are you sure you want to discard this comment?"
msgstr "¿Está seguro de que desea descartar este comentario?"
msgid "Are you sure you want to discard your changes?"
-msgstr ""
+msgstr "¿Está seguro de que desea descartar sus cambios?"
msgid "Are you sure you want to erase this build?"
msgstr "¿Estás seguro de que quieres borrar esta versión?"
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "¿Está seguro que desea importar el repositorio %d?"
+msgstr[1] "¿Está seguro que desea importar los repositorios %d?"
msgid "Are you sure you want to lock %{path}?"
-msgstr ""
+msgstr "¿Está seguro de que desea bloquear %{path}?"
msgid "Are you sure you want to lock this directory?"
-msgstr ""
+msgstr "¿Está seguro de que desea bloquear este directorio?"
msgid "Are you sure you want to lose unsaved changes?"
msgstr "¿Estás seguro de que deseas descartar los cambios no guardados?"
@@ -4407,10 +4445,10 @@ msgid "Are you sure you want to regenerate the public key? You will have to upda
msgstr "¿Seguro que quiere regenerar la clave pública? Deberá actualizar la clave pública en el servidor remoto antes de que la duplicación funcione nuevamente."
msgid "Are you sure you want to reindex?"
-msgstr ""
+msgstr "¿Está seguro de que desea reindexar?"
msgid "Are you sure you want to remove %{email}?"
-msgstr ""
+msgstr "¿Está seguro de que desea eliminar %{email}?"
msgid "Are you sure you want to remove %{group_name}?"
msgstr "¿Está seguro que desea eliminar %{group_name}?"
@@ -4422,13 +4460,13 @@ msgid "Are you sure you want to remove the license?"
msgstr "¿Está seguro de que desea eliminar la licencia?"
msgid "Are you sure you want to remove this deploy key? If anything is still using this key, it will stop working."
-msgstr ""
+msgstr "¿Está seguro de que desea eliminar esta clave de despliegue? Si algo todavía está usando esta clave, dejará de funcionar."
msgid "Are you sure you want to remove this identity?"
msgstr "¿Está seguro de que desea eliminar esta identidad?"
msgid "Are you sure you want to remove this list?"
-msgstr ""
+msgstr "¿Está seguro de que desea eliminar esta lista?"
msgid "Are you sure you want to reset the SCIM token? SCIM provisioning will stop working until the new token is updated."
msgstr "¿Está seguro de que desea restablecer el token SCIM? La provisión de SCIM dejará de funcionar hasta que se actualice el nuevo token."
@@ -4437,10 +4475,10 @@ msgid "Are you sure you want to reset the health check token?"
msgstr "¿Está seguro que desea restablecer el token de verificación de estado?"
msgid "Are you sure you want to reset the registration token?"
-msgstr ""
+msgstr "¿Estás seguro de que desea restablecer el token de registro?"
msgid "Are you sure you want to retry this migration?"
-msgstr ""
+msgstr "¿Está seguro de que desea volver a intentar esta migración?"
msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr "¿Está seguro de que desea revocar este token %{type}? Esta acción no se puede deshacer."
@@ -4449,7 +4487,7 @@ msgid "Are you sure you want to revoke this nickname?"
msgstr "¿Está seguro que desea revocar este nick?"
msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
-msgstr ""
+msgstr "¿Está seguro de que desea revocar el token de acceso token personal?. Esta acción no se puede deshacer."
msgid "Are you sure you want to stop this environment?"
msgstr "¿Está seguro de que desea detener este entorno?"
@@ -4458,10 +4496,10 @@ msgid "Are you sure you want to unlock %{path_lock_path}?"
msgstr "¿Está seguro que quieres desbloquear %{path_lock_path}?"
msgid "Are you sure you want to unlock %{path}?"
-msgstr ""
+msgstr "¿Estás seguro de que desea desbloquear %{path}?"
msgid "Are you sure you want to unlock this directory?"
-msgstr ""
+msgstr "¿Está seguro de que desea desbloquear este directorio?"
msgid "Are you sure you want to unsubscribe from the %{type}: %{link_to_noteable_text}?"
msgstr "¿Está seguro de que desea darse de baja de la %{type}: %{link_to_noteable_text}?"
@@ -4476,10 +4514,10 @@ msgid "Are you sure? Removing this GPG key does not affect already signed commit
msgstr "¿Está seguro? Eliminar esta clave GPG no afecta a los commits ya firmados."
msgid "Are you sure? The device will be signed out of GitLab and all remember me tokens revoked."
-msgstr ""
+msgstr "¿Está seguro de que desea continuar? Se cerrará la sesión en el dispositivo y todos los tokens serán revocados."
msgid "Are you sure? This will invalidate your registered applications and U2F / WebAuthn devices."
-msgstr ""
+msgstr "¿Está seguro de que desea continuar? Al hacer esto se invalidarán sus aplicaciones registradas y sus dispositivos U2F."
msgid "Are you sure? This will invalidate your registered applications and U2F devices."
msgstr "¿Está seguro?. Al hacer esto invalidará sus aplicaciones registradas y sus dispositivos U2F."
@@ -4499,11 +4537,8 @@ msgstr "El artefacto se ha eliminado correctamente."
msgid "Artifacts"
msgstr "Artefactos"
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
-msgstr ""
+msgstr "A medida que continuamos construyendo más características para SAST, nos gustaría conocer su opinión sobre la función de configuración SAST en %{linkStart}esta incidencia%{linkEnd}."
msgid "AsanaService|%{user} pushed to branch %{branch} of %{project_name} ( %{commit_url} ):"
msgstr "el %{user} hizo push a la rama %{branch} de %{project_name} ( %{commit_url} ):"
@@ -4521,10 +4556,10 @@ msgid "Ascending"
msgstr "Ascendente"
msgid "Ask again later"
-msgstr ""
+msgstr "Pregunta de nuevo más tarde"
msgid "Ask someone with write access to resolve it."
-msgstr ""
+msgstr "Pedir a alguien con acceso de escritura que lo resuelva."
msgid "Ask your group maintainer to set up a group runner."
msgstr ""
@@ -4605,7 +4640,7 @@ msgid "Assigned to me"
msgstr "Asignado a mí"
msgid "Assigned to you"
-msgstr ""
+msgstr "Asignado a ti"
msgid "Assignee"
msgid_plural "%d Assignees"
@@ -4618,9 +4653,6 @@ msgstr "El usuario asignado no tiene permisos"
msgid "Assignee lists not available with your current license"
msgstr "Las listas de asignaciones no se encuentran disponibles con su licencia actual"
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr "Las listas de asignados muestran todos las incidencias asignadas al usuario seleccionado."
-
msgid "Assignee(s)"
msgstr "Asignado(s)"
@@ -4658,7 +4690,7 @@ msgid "Attach a file by drag &amp; drop or %{upload_link}"
msgstr "Adjunte un archivo arrastrando &amp; soltando o %{upload_link}"
msgid "Attaching File - %{progress}"
-msgstr ""
+msgstr "Adjuntando archivo - %{progress}"
msgid "Attaching a file"
msgid_plural "Attaching %d files"
@@ -4732,25 +4764,31 @@ msgid "Authenticated API rate limit period in seconds"
msgstr ""
msgid "Authenticated API request rate limit"
-msgstr ""
+msgstr "Límite de peticiones de la API autenticadas"
msgid "Authenticated API requests"
+msgstr "Peticiones de API autenticadas"
+
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
msgstr ""
msgid "Authenticated web rate limit period in seconds"
msgstr ""
msgid "Authenticated web request rate limit"
-msgstr ""
+msgstr "Límite de peticiones web autenticadas"
msgid "Authenticated web requests"
-msgstr ""
+msgstr "Peticiones web autenticadas"
msgid "Authenticating"
msgstr "Autenticando"
msgid "Authentication"
-msgstr ""
+msgstr "Autenticación"
msgid "Authentication Failure"
msgstr "Error de autenticación"
@@ -4795,10 +4833,10 @@ msgid "Authorization key"
msgstr "Clave de autorización"
msgid "Authorization required"
-msgstr ""
+msgstr "Autorización requerida"
msgid "Authorization token duration (minutes)"
-msgstr ""
+msgstr "Duración del token de autorización (minutos)"
msgid "Authorization was granted by entering your username and password in the application."
msgstr "Se concedió la autorización al introducir su nombre de usuario y contraseña en la aplicación."
@@ -4834,10 +4872,10 @@ msgid "Auto stop successfully canceled."
msgstr "Parada automática cancelada con éxito."
msgid "Auto-cancel redundant pipelines"
-msgstr ""
+msgstr "Cancelar automáticamente los pipelines redundantes"
msgid "Auto-close referenced issues on default branch"
-msgstr ""
+msgstr "Cerrar automáticamente las incidencias referenciadas en el branch por defecto"
msgid "AutoDevOps|%{auto_devops_start}Automate building, testing, and deploying%{auto_devops_end} your applications based on your continuous integration and delivery configuration. %{quickstart_start}How do I get started?%{quickstart_end}"
msgstr ""
@@ -4849,7 +4887,7 @@ msgid "AutoDevOps|Auto DevOps documentation"
msgstr "Documentación de Auto DevOps"
msgid "AutoDevOps|Dismiss Auto DevOps box"
-msgstr ""
+msgstr "Descartar el cuadro Auto DevOps"
msgid "AutoDevOps|Enable in settings"
msgstr "Habilitar en la configuración"
@@ -4870,7 +4908,7 @@ msgid "AutoRemediation| 1 Merge Request"
msgstr ""
msgid "AutoRemediation|%{mrsCount} ready for review"
-msgstr ""
+msgstr "%{mrsCount} listo para revisión."
msgid "AutoRemediation|Auto-fix"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr "Gestión automática de los certificados utilizando Let's Encrypt"
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -4933,13 +4974,13 @@ msgid "Available ID"
msgstr "ID disponible"
msgid "Available group runners: %{runners}"
-msgstr ""
+msgstr "Grupo de ejecutores disponible: %{runners}"
msgid "Available runners: %{runners}"
-msgstr ""
+msgstr "Ejecutores disponibles: %{runners}"
msgid "Available shared runners:"
-msgstr ""
+msgstr "Ejecutores compartidos disponibles:"
msgid "Available specific runners"
msgstr "Ejecutores dedicados disponibles"
@@ -4957,16 +4998,16 @@ msgid "Average per day: %{average}"
msgstr "Promedio por día: %{average}"
msgid "Award added"
-msgstr ""
+msgstr "Premio añadido"
msgid "Award removed"
-msgstr ""
+msgstr "Premio eliminado"
msgid "AwardEmoji|No emojis found."
-msgstr ""
+msgstr "No se encontraron emojis."
msgid "Back"
-msgstr ""
+msgstr "Atrás"
msgid "Back to page %{number}"
msgstr "Volver a la página %{number}"
@@ -4978,7 +5019,7 @@ msgid "Background Jobs"
msgstr "Trabajos de fondo"
msgid "Background Migrations"
-msgstr ""
+msgstr "Migraciones en segundo plano"
msgid "Background color"
msgstr "Color de fondo"
@@ -4999,7 +5040,7 @@ msgid "Badges|Badge image preview"
msgstr "Vista previa de la imagen de la insignia"
msgid "Badges|Badge saved."
-msgstr ""
+msgstr "Insignia guardada."
msgid "Badges|Delete badge?"
msgstr "¿Desea eliminar la insignia?"
@@ -5008,10 +5049,10 @@ msgid "Badges|Deleting the badge failed, please try again."
msgstr "Se ha producido un error al eliminar la insignia. Inténtelo de nuevo."
msgid "Badges|Enter a valid URL"
-msgstr ""
+msgstr "Introduce una URL válida"
msgid "Badges|Example: %{exampleUrl}"
-msgstr ""
+msgstr "Ejemplo: %{exampleUrl}"
msgid "Badges|Group Badge"
msgstr "Insignia del grupo"
@@ -5023,7 +5064,7 @@ msgid "Badges|Name"
msgstr "Nombre"
msgid "Badges|New badge added."
-msgstr ""
+msgstr "Nueva insignia añadida."
msgid "Badges|No badge image"
msgstr "No hay imagen de insignia"
@@ -5065,16 +5106,16 @@ msgid "Balsamiq file could not be loaded."
msgstr "El archivo Balsamiq no se pudo cargar."
msgid "BambooService|Atlassian Bamboo"
-msgstr ""
+msgstr "Atlassian Bamboo"
msgid "BambooService|Bamboo URL"
-msgstr ""
+msgstr "URL de Bamboo"
msgid "BambooService|Bamboo build plan key."
msgstr ""
msgid "BambooService|Bamboo service root URL."
-msgstr ""
+msgstr "URL raíz del servicio Bamboo."
msgid "BambooService|Run CI/CD pipelines with Atlassian Bamboo."
msgstr ""
@@ -5106,14 +5147,11 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr "Iniciar con el commit seleccionado"
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr "A continuación se muestran las huellas de las claves SSH de la instancia actual."
msgid "Below are the settings for %{link_to_gitlab_pages}."
-msgstr ""
+msgstr "A continuación se muestran los ajustes relativos a %{link_to_gitlab_pages}."
msgid "Below you will find all the groups that are public."
msgstr "A continuación encontrará todos los grupos públicos."
@@ -5125,19 +5163,19 @@ msgid "Bi-weekly code coverage"
msgstr "Cobertura de código quincenal"
msgid "Billable Users"
-msgstr ""
+msgstr "Usuarios facturables"
msgid "Billing"
msgstr "Facturación"
msgid "BillingPlans|%{group_name} is currently using the %{plan_name}."
-msgstr ""
+msgstr "%{group_name} está actualmente usando el %{plan_name}."
msgid "BillingPlans|@%{user_name} you are currently using the %{plan_name}."
-msgstr ""
+msgstr "@%{user_name} está utilizando el %{plan_name}."
msgid "BillingPlans|Compare all plans"
-msgstr ""
+msgstr "Comparar todos los planes"
msgid "BillingPlans|Congratulations, your free trial is activated."
msgstr "Enhorabuena, su plan de prueba está activado."
@@ -5197,7 +5235,7 @@ msgid "BillingPlans|frequently asked questions"
msgstr "preguntas frecuentes"
msgid "BillingPlans|group"
-msgstr ""
+msgstr "grupo"
msgid "BillingPlans|monthly"
msgstr "mensual"
@@ -5212,16 +5250,16 @@ msgid "BillingPlan|Upgrade"
msgstr "Actualizar"
msgid "BillingPlan|Upgrade for free"
-msgstr ""
+msgstr "Actualizar gratuitamente"
msgid "Billings|%{planName} plan"
-msgstr ""
+msgstr "Plan %{planName}"
msgid "Billings|An error occurred while extending your trial."
-msgstr ""
+msgstr "Se ha producido un error al extender su periodo de prueba."
msgid "Billings|An error occurred while reactivating your trial."
-msgstr ""
+msgstr "Se ha producido un error al reactivar su periodo de prueba."
msgid "Billings|By extending your trial, you will receive an additional 30 days of %{planName}. Your trial can be only extended once."
msgstr ""
@@ -5230,10 +5268,10 @@ msgid "Billings|By reactivating your trial, you will receive an additional 30 da
msgstr ""
msgid "Billings|Extend trial"
-msgstr ""
+msgstr "Extender el periodo de prueba"
msgid "Billings|Reactivate trial"
-msgstr ""
+msgstr "Reactivar el periodo de prueba"
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
@@ -5245,16 +5283,16 @@ msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to
msgstr ""
msgid "Billings|User successfully validated"
-msgstr ""
+msgstr "Usuario validado correctamente"
msgid "Billings|User validation required"
-msgstr ""
+msgstr "Es necesaria la validación del usuario"
msgid "Billings|Validate account"
-msgstr ""
+msgstr "Validar la cuenta"
msgid "Billings|Validate user account"
-msgstr ""
+msgstr "Validar la cuenta de usuario"
msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
msgstr ""
@@ -5266,40 +5304,40 @@ msgid "Billing|An error occurred while getting a billable member details"
msgstr ""
msgid "Billing|An error occurred while loading billable members list"
-msgstr ""
+msgstr "Se ha producido un error al cargar la lista de miembros facturables"
msgid "Billing|An error occurred while removing a billable member"
-msgstr ""
+msgstr "Se ha producido un error al eliminar un miembro facturable"
msgid "Billing|Cannot remove user"
-msgstr ""
+msgstr "No es posible eliminar al usuario"
msgid "Billing|Direct memberships"
-msgstr ""
+msgstr "Membresías directas"
msgid "Billing|Enter at least three characters to search."
-msgstr ""
+msgstr "Introduzca al menos tres caracteres para buscar."
msgid "Billing|Export list"
-msgstr ""
+msgstr "Exportar lista"
msgid "Billing|Group"
-msgstr ""
+msgstr "Grupo"
msgid "Billing|Group invite"
-msgstr ""
+msgstr "Invitación de grupo"
msgid "Billing|Members who were invited via a group invitation cannot be removed. You can either remove the entire group, or ask an Owner of the invited group to remove the member."
msgstr ""
msgid "Billing|No users to display."
-msgstr ""
+msgstr "No hay usuarios para mostrar."
msgid "Billing|Private"
-msgstr ""
+msgstr "Privado"
msgid "Billing|Project invite"
-msgstr ""
+msgstr "Invitación al proyecto"
msgid "Billing|Remove user %{username} from your subscription"
msgstr ""
@@ -5308,16 +5346,16 @@ msgid "Billing|Toggle seat details"
msgstr ""
msgid "Billing|Type %{username} to confirm"
-msgstr ""
+msgstr "Escriba el %{username} para confirmar"
msgid "Billing|User was successfully removed"
-msgstr ""
+msgstr "Se ha eliminado correctamente a este usuario"
msgid "Billing|Users occupying seats in"
-msgstr ""
+msgstr "Usuarios que ocupan asientos en"
msgid "Billing|You are about to remove user %{username} from your subscription. If you continue, the user will be removed from the %{namespace} group and all its subgroups and projects. This action can't be undone."
-msgstr ""
+msgstr "Está a punto de eliminar al usuario %{username} de su suscripción. Si continua, el usuario será eliminado del grupo %{namespace} y todos sus subgrupos y proyectos. Esta acción no se puede deshacer."
msgid "Bitbucket Server Import"
msgstr "Importar desde un servidor de Bitbucket"
@@ -5339,17 +5377,17 @@ msgstr "Bloqueado"
msgid "Blocked by %d issue"
msgid_plural "Blocked by %d issues"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Bloqueado por %d la incidencia"
+msgstr[1] "Bloqueado por %d las incidencia"
msgid "Blocked issue"
msgstr "Incidencia bloqueada"
msgid "Blocking"
-msgstr ""
+msgstr "Bloqueando"
msgid "Blocking issues"
-msgstr ""
+msgstr "Incidencias bloqueantes"
msgid "Blocks"
msgstr ""
@@ -5361,16 +5399,16 @@ msgid "Board scope affects which issues are displayed for anyone who visits this
msgstr "El alcance del panel de control afecta qué problemas se muestran para cualquiera persona que visite este panel"
msgid "BoardNewIssue|No matching results"
-msgstr ""
+msgstr "No hay resultados coincidentes"
msgid "BoardNewIssue|Projects"
-msgstr ""
+msgstr "Proyectos"
msgid "BoardNewIssue|Search projects"
-msgstr ""
+msgstr "Buscar proyectos"
msgid "BoardNewIssue|Select a project"
-msgstr ""
+msgstr "Seleccionar un proyecto"
msgid "BoardScope|An error occurred while getting milestones, please try again."
msgstr ""
@@ -5379,39 +5417,42 @@ msgid "BoardScope|An error occurred while searching for users, please try again.
msgstr ""
msgid "BoardScope|Any Milestone"
-msgstr ""
+msgstr "Cualquier hito"
msgid "BoardScope|Any assignee"
-msgstr ""
+msgstr "Cualquier asignado"
msgid "BoardScope|Assignee"
-msgstr ""
+msgstr "Asignado"
msgid "BoardScope|Edit"
-msgstr ""
+msgstr "Editar"
msgid "BoardScope|Milestone"
-msgstr ""
-
-msgid "BoardScope|No matching results"
-msgstr ""
+msgstr "Hito"
msgid "BoardScope|No milestone"
-msgstr ""
+msgstr "No hay hito"
msgid "BoardScope|Search milestones"
-msgstr ""
+msgstr "Buscar hitos"
msgid "BoardScope|Select assignee"
-msgstr ""
+msgstr "Seleccionar asignado"
msgid "BoardScope|Select milestone"
+msgstr "Seleccionar hito"
+
+msgid "BoardScope|Select weight"
msgstr ""
msgid "BoardScope|Started"
-msgstr ""
+msgstr "Iniciado"
msgid "BoardScope|Upcoming"
+msgstr "Próximamente"
+
+msgid "BoardScope|Weight"
msgstr ""
msgid "Boards"
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr "Contraer"
@@ -5491,7 +5529,7 @@ msgid "Boards|Failed to fetch blocking %{issuableType}s"
msgstr ""
msgid "Boards|New epic"
-msgstr ""
+msgstr "Nueva épica"
msgid "Boards|Retrieving blocking %{issuableType}s"
msgstr ""
@@ -5509,16 +5547,16 @@ msgid "Board|Board scope"
msgstr ""
msgid "Board|Create board"
-msgstr ""
+msgstr "Crear tablero"
msgid "Board|Create new board"
-msgstr ""
+msgstr "Crear nuevo tablero"
msgid "Board|Delete board"
-msgstr ""
+msgstr "Eliminar tablero"
msgid "Board|Edit board"
-msgstr ""
+msgstr "Editar tablero"
msgid "Board|Enter board name"
msgstr ""
@@ -5527,16 +5565,16 @@ msgid "Board|Failed to delete board. Please try again."
msgstr ""
msgid "Board|Load more epics"
-msgstr ""
+msgstr "Cargar más épicas"
msgid "Board|Load more issues"
-msgstr ""
+msgstr "Cargar más incidencias"
msgid "Board|Loading epics"
-msgstr ""
+msgstr "Cargando épicas"
msgid "Bold text"
-msgstr ""
+msgstr "Negrita"
msgid "Both project and dashboard_path are required"
msgstr ""
@@ -5548,7 +5586,7 @@ msgid "Branch %{branchName} was not found in this project's repository."
msgstr "No se encontró la rama %{branchName} en el repositorio de este proyecto."
msgid "Branch %{branch_name} was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}"
-msgstr ""
+msgstr "Se creó la rama %{branch_name} . Para configurar la implementación automática, seleccione una plantilla de GitLab CI Yaml y confirme sus cambios. %{link_to_autodeploy_doc}"
msgid "Branch already exists"
msgstr ""
@@ -5770,7 +5808,7 @@ msgid "Bulk update"
msgstr ""
msgid "BulkImport|Existing groups"
-msgstr ""
+msgstr "Grupos existentes"
msgid "BulkImport|Filter by source group"
msgstr ""
@@ -5778,29 +5816,23 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
-msgstr ""
+msgid "BulkImport|Name already exists."
+msgstr "El nombre ya existe."
msgid "BulkImport|No parent"
-msgstr ""
-
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
+msgstr "No hay ningún padre"
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5812,7 +5844,7 @@ msgid "BulkImport|Showing %{start}-%{end} of %{total} matching filter \"%{filter
msgstr ""
msgid "BulkImport|To new group"
-msgstr ""
+msgstr "Para un nuevo grupo"
msgid "BulkImport|Update of import statuses with realtime changes failed"
msgstr ""
@@ -5851,9 +5883,12 @@ msgid "Business metrics (Custom)"
msgstr "Métricas de negocio (personalizadas)"
msgid "Busy"
-msgstr ""
+msgstr "Ocupado"
msgid "Buy CI Minutes"
+msgstr "Comprar minutos de CI"
+
+msgid "Buy Storage"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -5881,7 +5916,7 @@ msgid "CI configuration validated, including all configuration added with the %{
msgstr ""
msgid "CI minutes"
-msgstr ""
+msgstr "Minutos de CI"
msgid "CI settings"
msgstr "Configuración de CI"
@@ -5896,16 +5931,16 @@ msgid "CI/CD"
msgstr "CI/CD"
msgid "CI/CD Analytics"
-msgstr ""
+msgstr "Estadísticas de CI/CD"
msgid "CI/CD Settings"
-msgstr ""
+msgstr "Configuración de CI/CD"
msgid "CI/CD configuration"
msgstr "Configuración de CI/CD"
msgid "CI/CD configuration file"
-msgstr ""
+msgstr "Archivo de configuración de CI/CD"
msgid "CI/CD|No projects have been added to the scope"
msgstr ""
@@ -5920,7 +5955,7 @@ msgid "CICDAnalytics|Deployment frequency"
msgstr ""
msgid "CICDAnalytics|Lead time"
-msgstr ""
+msgstr "Tiempo de espera"
msgid "CICDAnalytics|Projects with releases"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr "CONTRIBUTING"
msgid "CPU"
msgstr "CPU"
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6021,28 +6059,28 @@ msgid "CVE|Enable CVE ID requests in the issue sidebar"
msgstr ""
msgid "CVE|Request CVE ID"
-msgstr ""
+msgstr "Solicitar ID de CVE"
msgid "CVE|Why Request a CVE ID?"
-msgstr ""
+msgstr "¿Por qué solicitar un ID de CVE?"
msgid "Cadence is not automated"
-msgstr ""
+msgstr "Cadence no está automatizado"
msgid "Callback URL"
msgstr "URL de callback"
msgid "Campfire room ID (optional)"
-msgstr ""
+msgstr "ID de sala de Campfire (opcional)"
msgid "Campfire subdomain (optional)"
-msgstr ""
+msgstr "Subdominio de Campfire (opcional)"
msgid "Campfire token"
-msgstr ""
+msgstr "Token de Campfire"
msgid "CampfireService|API authentication token from Campfire."
-msgstr ""
+msgstr "Token de autenticación de API de Campfire."
msgid "CampfireService|From the end of the room URL."
msgstr ""
@@ -6057,7 +6095,7 @@ msgid "Can be manually deployed to"
msgstr "Puede ser desplegado manualmente en"
msgid "Can create groups:"
-msgstr ""
+msgstr "Puede crear grupos:"
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6069,7 +6107,7 @@ msgid "Can't apply as this line was changed in a more recent version."
msgstr ""
msgid "Can't apply this suggestion."
-msgstr ""
+msgstr "No se puede aplicar esta sugerencia."
msgid "Can't be empty"
msgstr "No puede estar vacío"
@@ -6114,7 +6152,7 @@ msgid "CanaryIngress|Canary"
msgstr ""
msgid "CanaryIngress|Change ratio"
-msgstr ""
+msgstr "Cambiar ratio"
msgid "CanaryIngress|Change the ratio of canary deployments?"
msgstr ""
@@ -6132,10 +6170,10 @@ msgid "Cancel"
msgstr "Cancelar"
msgid "Cancel and close"
-msgstr ""
+msgstr "Cancelar y cerrar"
msgid "Cancel index deletion"
-msgstr ""
+msgstr "Cancelar la eliminación de índice"
msgid "Cancel running"
msgstr "Cancelar ejecución"
@@ -6144,22 +6182,22 @@ msgid "Cancel this job"
msgstr "Cancelar este trabajo"
msgid "Cancel your account"
-msgstr ""
+msgstr "Cancela su cuenta"
msgid "Cancel, keep project"
-msgstr ""
+msgstr "Cancelar, mantener el proyecto"
msgid "Canceled deployment to"
msgstr "Cancelado el despliegue a"
msgid "Cancelled"
-msgstr ""
+msgstr "Cancelado"
msgid "Cancelling Preview"
msgstr "Cancelando la vista previa"
msgid "Cannot be assigned to other projects."
-msgstr ""
+msgstr "No se puede asignar a otros proyectos."
msgid "Cannot be merged automatically"
msgstr "No se puede hacer merge automáticamente"
@@ -6171,7 +6209,7 @@ msgid "Cannot create the abuse report. This user has been blocked."
msgstr "No se puede crear el informe de abuso. Este usuario ha sido bloqueado."
msgid "Cannot delete %{profile_name} referenced in security policy"
-msgstr ""
+msgstr "No se puede eliminar %{profile_name} referenciado en la política de seguridad"
msgid "Cannot have multiple Jira imports running at the same time"
msgstr ""
@@ -6222,13 +6260,13 @@ msgid "Capacity threshold"
msgstr "Límite de capacidad"
msgid "CascadingSettings|Enforce for all subgroups"
-msgstr ""
+msgstr "Forzar para todos los subgrupos"
msgid "CascadingSettings|Setting enforced"
-msgstr ""
+msgstr "Configuración forzada"
msgid "CascadingSettings|Subgroups cannot change this setting."
-msgstr ""
+msgstr "Los subgrupos no pueden cambiar esta configuración."
msgid "CascadingSettings|This setting has been enforced by an instance admin."
msgstr ""
@@ -6273,7 +6311,7 @@ msgid "Change label"
msgstr "Cambiar la etiqueta"
msgid "Change made by"
-msgstr ""
+msgstr "Cambio realizado por"
msgid "Change milestone"
msgstr "Cambiar el hito"
@@ -6282,13 +6320,13 @@ msgid "Change path"
msgstr "Cambiar la ruta"
msgid "Change reviewer(s)"
-msgstr ""
+msgstr "Cambiar revisores"
msgid "Change reviewer(s)."
-msgstr ""
+msgstr "Cambiar revisores."
msgid "Change role"
-msgstr ""
+msgstr "Cambiar rol"
msgid "Change status"
msgstr "Cambiar estado"
@@ -6309,13 +6347,13 @@ msgid "Change your password or recover your current one"
msgstr "Cambia o recuperar su contraseña"
msgid "ChangeReviewer|Reviewer changed from %{old} to %{new}"
-msgstr ""
+msgstr "Revisor cambiado de %{old} a %{new}"
msgid "ChangeReviewer|Reviewer changed to %{new}"
msgstr ""
msgid "ChangeReviewer|Unassigned"
-msgstr ""
+msgstr "Sin asignar"
msgid "ChangeTypeAction|A new branch will be created in your fork and a new merge request will be started."
msgstr ""
@@ -6336,10 +6374,10 @@ msgid "ChangeTypeAction|Revert in branch"
msgstr ""
msgid "ChangeTypeAction|Search branches"
-msgstr ""
+msgstr "Buscar ramas"
msgid "ChangeTypeAction|Search projects"
-msgstr ""
+msgstr "Buscar proyectos"
msgid "ChangeTypeAction|Start a %{newMergeRequest} with these changes"
msgstr ""
@@ -6360,7 +6398,7 @@ msgid "Changed assignee(s)."
msgstr "Asignado(s) cambiado(s)."
msgid "Changed reviewer(s)."
-msgstr ""
+msgstr "Revisores cambiados."
msgid "Changed the title to \"%{title_param}\"."
msgstr "Título cambiado a \"%{title_param}\"."
@@ -6384,7 +6422,7 @@ msgid "Changes the title to \"%{title_param}\"."
msgstr "Cambia el título a \"%{title_param}\"."
msgid "Changes to the title have not been saved"
-msgstr ""
+msgstr "No se han guardado los cambios en el título"
msgid "Changing group URL can have unintended side effects."
msgstr ""
@@ -6453,7 +6491,7 @@ msgid "Check the %{docs_link_start}documentation%{docs_link_end}."
msgstr "Compruebe la documentación %{docs_link_start}%{docs_link_end}."
msgid "Check the current instance configuration "
-msgstr ""
+msgstr "Compruebe la configuración de la instancia actual "
msgid "Check the elasticsearch.log file to debug why the migration was halted and make any changes before retrying the migration. When you fix the cause of the failure, click \"Retry migration\", and the migration will be scheduled to be retried in the background."
msgstr ""
@@ -6477,7 +6515,7 @@ msgid "Checking branch availability..."
msgstr "Verificando disponibilidad de la rama..."
msgid "Checking group URL availability..."
-msgstr ""
+msgstr "Comprobando la disponibilidad de la URL del grupo..."
msgid "Checking group path availability..."
msgstr "Comprobando la disponibilidad de la ruta de grupo ..."
@@ -6488,32 +6526,39 @@ msgstr "Verificando la disponibilidad del nombres de usuario..."
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr "$%{selectedPlanPrice} por usuario y año"
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr "%{cardType} terminada en %{lastFourDigits}"
msgid "Checkout|%{name}'s CI minutes"
-msgstr ""
+msgstr "Minutos de IC de%{name}"
msgid "Checkout|%{name}'s GitLab subscription"
msgstr "Suscripción de GitLab de%{name}"
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr "plan %{selectedPlanText}"
msgid "Checkout|%{startDate} - %{endDate}"
msgstr "%{startDate} - %{endDate}"
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
-msgstr ""
+msgstr "%{totalCiMinutes} minutos de CI"
msgid "Checkout|(may be %{linkStart}charged upon purchase%{linkEnd})"
msgstr ""
@@ -6522,19 +6567,19 @@ msgid "Checkout|(x%{numberOfUsers})"
msgstr "(x%{numberOfUsers})"
msgid "Checkout|(x%{quantity})"
-msgstr ""
+msgstr "(x%{quantity})"
msgid "Checkout|Billing address"
msgstr "Dirección de facturación"
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
msgstr ""
msgid "Checkout|Checkout"
-msgstr " Checkout"
+msgstr ""
msgid "Checkout|City"
msgstr "Ciudad"
@@ -6567,19 +6612,19 @@ msgid "Checkout|Edit"
msgstr "Editar"
msgid "Checkout|Exp %{expirationMonth}/%{expirationYear}"
-msgstr "Checkout|Exp %{expirationMonth}/%{expirationYear}"
+msgstr ""
msgid "Checkout|Failed to confirm your order! Please try again."
-msgstr "Checkout|¡Se ha producido un error al confirmar su pedido!. Por favor, inténtalo de nuevo"
+msgstr ""
msgid "Checkout|Failed to confirm your order: %{message}. Please try again."
-msgstr "Checkout|Se ha producido un error al confirmar su pedido %{message}. Por favor, inténtalo de nuevo"
+msgstr ""
msgid "Checkout|Failed to load countries. Please try again."
-msgstr "Ckeckout|Se ha producido un error al cargar los países. Por favor, inténtalo de nuevo"
+msgstr ""
msgid "Checkout|Failed to load states. Please try again."
-msgstr "Ckeckout|Se ha producido un error al cargar los estados. Por favor, inténtalo de nuevo."
+msgstr ""
msgid "Checkout|Failed to load the payment form. Please try again."
msgstr ""
@@ -6615,7 +6660,7 @@ msgid "Checkout|Please select a state"
msgstr "Por favor, seleccione un estado"
msgid "Checkout|Purchase details"
-msgstr ""
+msgstr "Detalles de compra"
msgid "Checkout|Select"
msgstr "Seleccionar"
@@ -6642,7 +6687,7 @@ msgid "Checkout|Total"
msgstr "Total"
msgid "Checkout|Total minutes: %{quantity}"
-msgstr ""
+msgstr "Minutos totales: %{quantity}"
msgid "Checkout|Users"
msgstr "Usuarios"
@@ -6681,10 +6726,10 @@ msgid "Child epic doesn't exist."
msgstr "La subtarea épica no existe."
msgid "Chinese language support using"
-msgstr ""
+msgstr "Soporte para el idioma chino utilizando"
msgid "Choose File..."
-msgstr ""
+msgstr "Seleccione un archivo..."
msgid "Choose a branch/tag (e.g. %{branch}) or enter a commit (e.g. %{sha}) to see what's changed or to create a merge request."
msgstr ""
@@ -6705,25 +6750,25 @@ msgid "Choose a type..."
msgstr "Elegir un tipo..."
msgid "Choose any color"
-msgstr ""
+msgstr "Seleccione cualquier color"
msgid "Choose any color."
msgstr "Elegir cualquier color."
msgid "Choose any color. Or you can choose one of the suggested colors below"
-msgstr ""
+msgstr "Seleccione cualquier color. O puede seleccionar alguno de los qcolores sugeridos a continuación"
msgid "Choose file…"
msgstr "Seleccione un archivo…"
msgid "Choose labels"
-msgstr ""
+msgstr "Seleccione las etiquetas"
msgid "Choose specific groups or storage shards"
msgstr ""
msgid "Choose the preferred Runner and populate the AWS CFT."
-msgstr ""
+msgstr "Seleccione el ejecutor preferido y rellene el AWS CFT."
msgid "Choose the top-level group for your repository imports."
msgstr "Seleccione el grupo de nivel superior para las importaciones de su repositorio."
@@ -6903,7 +6948,7 @@ msgid "Clean up after running %{link_start}git filter-repo%{link_end} on the rep
msgstr ""
msgid "Clean up image tags"
-msgstr ""
+msgstr "Limpiar las etiquetas de las imágenes"
msgid "Cleanup policies are executed by background workers. This setting defines the maximum number of workers that can run concurrently. Set it to 0 to remove all workers and not execute the cleanup policies."
msgstr ""
@@ -6921,7 +6966,7 @@ msgid "Clear"
msgstr "Limpiar"
msgid "Clear all repository checks"
-msgstr ""
+msgstr "Borrar todas las comprobaciones del repositorio"
msgid "Clear chart filters"
msgstr "Borrar los filtros del gráfico"
@@ -6954,16 +6999,16 @@ msgid "Clears weight."
msgstr "Limpiar peso."
msgid "Click %{link_start}here%{link_end} to view the request."
-msgstr ""
+msgstr "Haga clic en %{link_start}aquí%{link_end} para ver la solicitud."
msgid "Click %{link_to} to view the request."
-msgstr ""
+msgstr "Haga clic en %{link_to} para ver la solicitud."
msgid "Click the link below to confirm your email address (%{email})"
-msgstr ""
+msgstr "Haga clic en el enlace a continuación para confirmar su dirección de correo electrónico (%{email})"
msgid "Click the link below to confirm your email address."
-msgstr ""
+msgstr "Haga clic en el enlace a continuación para confirmar su dirección de correo electrónico."
msgid "Click to expand it."
msgstr "Haga clic para expandir."
@@ -6975,7 +7020,7 @@ msgid "Click to hide"
msgstr ""
msgid "Click to reveal"
-msgstr ""
+msgstr "Haga clic para revelar"
msgid "Client authentication certificate"
msgstr "Certificado de autenticación del cliente"
@@ -7014,16 +7059,16 @@ msgid "Clone with SSH"
msgstr "Clonar con SSH"
msgid "CloneIssue|Cannot clone issue due to insufficient permissions!"
-msgstr ""
+msgstr "¡No se puede clonar la incidencia debido a que no tiene permisos insuficientes!"
msgid "CloneIssue|Cannot clone issue to target project as it is pending deletion."
-msgstr ""
+msgstr "No se puede clonar la incidencia en el proyecto de destino ya que está pendiente de eliminación."
msgid "Cloned this issue to %{path_to_project}."
-msgstr ""
+msgstr "Clonó esta incidencia en %{path_to_project}."
msgid "Clones this issue, without comments, to %{project}."
-msgstr ""
+msgstr "Clona este problema, sin comentarios, a %{project}."
msgid "Close"
msgstr "Cerrar"
@@ -7056,10 +7101,10 @@ msgid "Closed %{epicTimeagoDate}"
msgstr "Cerrado %{epicTimeagoDate}"
msgid "Closed MRs"
-msgstr ""
+msgstr "MRs cerrados"
msgid "Closed epics"
-msgstr ""
+msgstr "Épicas cerradas"
msgid "Closed issues"
msgstr "Incidencias cerradas"
@@ -7074,7 +7119,7 @@ msgid "Closes this %{quick_action_target}."
msgstr "Cierra este %{quick_action_target}."
msgid "Cloud licenses can not be removed."
-msgstr ""
+msgstr "No se pueden eliminar las licencias cloud."
msgid "Cluster"
msgstr "Clúster"
@@ -7098,91 +7143,91 @@ msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|Access tokens"
-msgstr ""
+msgstr "Tokens de acceso"
msgid "ClusterAgents|Alternative installation methods"
-msgstr ""
+msgstr "Métodos de instalación alternativos"
msgid "ClusterAgents|An error occurred while loading your GitLab Agents"
-msgstr ""
+msgstr "Se ha producido un error al cargar sus agentes de GitLab"
msgid "ClusterAgents|An error occurred while loading your agent"
-msgstr ""
+msgstr "Se ha producido un error al cargar su agente"
msgid "ClusterAgents|An unknown error occurred. Please try again."
-msgstr ""
+msgstr "Se ha producido un error desconocido. Por favor, inténtelo de nuevo."
msgid "ClusterAgents|Configuration"
-msgstr ""
+msgstr "Configuración"
msgid "ClusterAgents|Copy token"
-msgstr ""
+msgstr "Copiar token"
msgid "ClusterAgents|Created by"
-msgstr ""
+msgstr "Creado por"
msgid "ClusterAgents|Created by %{name} %{time}"
-msgstr ""
+msgstr "Creado por %{name} %{time}"
msgid "ClusterAgents|Date created"
-msgstr ""
+msgstr "Fecha de creación"
msgid "ClusterAgents|Description"
-msgstr ""
+msgstr "Descripción"
msgid "ClusterAgents|For alternative installation methods %{linkStart}go to the documentation%{linkEnd}."
-msgstr ""
+msgstr "Para métodos de instalación alternativos %{linkStart}vaya a la documentación%{linkEnd}."
msgid "ClusterAgents|Go to the repository"
+msgstr "Ir al repositorio"
+
+msgid "ClusterAgents|Install a new GitLab Agent"
msgstr ""
msgid "ClusterAgents|Install new Agent"
-msgstr ""
+msgstr "Instalar nuevo agente"
msgid "ClusterAgents|Integrate Kubernetes with a GitLab Agent"
-msgstr ""
+msgstr "Integrar Kubernetes con un agente de GitLab"
msgid "ClusterAgents|Integrate with the GitLab Agent"
-msgstr ""
+msgstr "Integrar con el agente de GitLab"
msgid "ClusterAgents|Last used"
-msgstr ""
+msgstr "Utilizado por última vez"
msgid "ClusterAgents|Learn how to create an agent access token"
-msgstr ""
-
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
+msgstr "Aprenda cómo crear un token de acceso del agente"
msgid "ClusterAgents|Name"
msgstr "Nombre"
msgid "ClusterAgents|Never"
-msgstr ""
+msgstr "Nunca"
msgid "ClusterAgents|Read more about getting started"
-msgstr ""
+msgstr "Más información sobre cómo empezar"
msgid "ClusterAgents|Recommended installation method"
-msgstr ""
+msgstr "Método de instalación recomendado"
msgid "ClusterAgents|Registering Agent"
-msgstr ""
+msgstr "Registrando agente"
msgid "ClusterAgents|Registration token"
-msgstr ""
+msgstr "Token de registro"
msgid "ClusterAgents|Select an Agent"
-msgstr ""
+msgstr "Seleccione un agente"
msgid "ClusterAgents|Select the Agent you want to register with GitLab and install on your cluster. To learn more about the Kubernetes Agent registration process %{linkStart}go to the documentation%{linkEnd}."
-msgstr ""
+msgstr "Seleccione el agente que desea registrar con GitLab e instálelo en su clúster. Para obtener más información sobre el proceso de registro de Kubernetes Agent %{linkStart}vaya a la documentación%{linkEnd}."
msgid "ClusterAgents|Select which Agent you want to install"
-msgstr ""
+msgstr "Seleccione qué agente desea instalar"
msgid "ClusterAgents|The GitLab Agent also requires %{linkStart}enabling the Agent Server%{linkEnd}"
-msgstr ""
+msgstr "El agente de GitLab también requiere %{linkStart}habilitar el servidor de agente%{linkEnd}"
msgid "ClusterAgents|The GitLab Kubernetes Agent allows an Infrastructure as Code, GitOps approach to integrating Kubernetes clusters with GitLab. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
@@ -7197,34 +7242,34 @@ msgid "ClusterAgents|The token value will not be shown again after you close thi
msgstr ""
msgid "ClusterAgents|This agent has no tokens"
-msgstr ""
+msgstr "Este agente no tiene tokens"
msgid "ClusterAgents|To install an Agent you should create an agent directory in the Repository first. We recommend that you add the Agent configuration to the directory before you start the installation process."
msgstr ""
msgid "ClusterAgents|Unknown user"
-msgstr ""
+msgstr "Usuario desconocido"
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
msgid "ClusterAgent|This feature is only available for premium plans"
-msgstr ""
+msgstr "Esta función sólo está disponible para planes premium"
msgid "ClusterAgent|User has insufficient permissions to create a token for this project"
-msgstr ""
+msgstr "El usuario no tiene permisos suficientes para crear un token para este proyecto"
msgid "ClusterAgent|You have insufficient permissions to create a cluster agent for this project"
-msgstr ""
+msgstr "No tiene permisos suficientes para crear un agente de clúster para este proyecto"
msgid "ClusterAgent|You have insufficient permissions to delete this cluster agent"
-msgstr ""
+msgstr "No tiene permisos suficientes para eliminar este agente de clúster"
msgid "ClusterApplicationsRemoved|One-click application management was removed in GitLab 14.0. Your applications are still installed in your cluster, and integrations continue working."
msgstr ""
msgid "ClusterIntegration|%{linkStart}More information%{linkEnd}"
-msgstr ""
+msgstr "%{linkStart}Más información%{linkEnd}"
msgid "ClusterIntegration|A cluster management project can be used to run deployment jobs with Kubernetes %{code_open}cluster-admin%{code_close} privileges."
msgstr ""
@@ -7242,7 +7287,7 @@ msgid "ClusterIntegration|Add Kubernetes cluster"
msgstr "Añadir cluster de Kubernetes"
msgid "ClusterIntegration|Add a Kubernetes cluster integration"
-msgstr "Añadir integración con cluster de Kubernetes "
+msgstr ""
msgid "ClusterIntegration|Adding a Kubernetes cluster to your group will automatically share the cluster across all your projects. Use review apps, deploy your applications, and easily run your pipelines for all projects using the same cluster."
msgstr "Agregar un cluster Kubernetes a su grupo compartirá automáticamente el cluster en todos sus proyectos. Utilice las aplicaciones de revisión, implemente sus aplicaciones y ejecute fácilmente los pipelines para todos los proyectos que utilizan el mismo clúster."
@@ -7317,10 +7362,10 @@ msgid "ClusterIntegration|Check your CA certificate"
msgstr ""
msgid "ClusterIntegration|Check your cluster status"
-msgstr ""
+msgstr "Verifique el estado de su clúster"
msgid "ClusterIntegration|Check your token"
-msgstr ""
+msgstr "Verifique su token"
msgid "ClusterIntegration|Choose the %{linkStart}security group %{linkEnd} to apply to the EKS-managed Elastic Network Interfaces that are created in your worker node subnets."
msgstr ""
@@ -7344,7 +7389,7 @@ msgid "ClusterIntegration|Cluster Region"
msgstr ""
msgid "ClusterIntegration|Cluster management project"
-msgstr ""
+msgstr "Proyecto de gestión de clúster"
msgid "ClusterIntegration|Cluster name is required."
msgstr "Se requiere el nombre del clúster."
@@ -7353,16 +7398,16 @@ msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancesto
msgstr ""
msgid "ClusterIntegration|Clusters connected with a certificate"
-msgstr ""
+msgstr "Clústeres conectados con un certificado"
msgid "ClusterIntegration|Connect cluster with certificate"
msgstr ""
msgid "ClusterIntegration|Connect existing cluster"
-msgstr ""
+msgstr "Conectar a un clúster existente"
msgid "ClusterIntegration|Connection Error"
-msgstr ""
+msgstr "Error de conexión"
msgid "ClusterIntegration|Copy API URL"
msgstr "Copiar la URL del API"
@@ -7491,7 +7536,7 @@ msgid "ClusterIntegration|Fetching zones"
msgstr "Obtener zonas"
msgid "ClusterIntegration|GitLab Agent managed clusters"
-msgstr ""
+msgstr "Clústeres administrados por un agente de GitLab"
msgid "ClusterIntegration|GitLab Integration"
msgstr "Integración GitLab"
@@ -7518,7 +7563,7 @@ msgid "ClusterIntegration|Google Kubernetes Engine project"
msgstr "Proyecto Google Kubernetes Engine"
msgid "ClusterIntegration|Group cluster"
-msgstr "ClusterIntegration|Grupo de clúster"
+msgstr ""
msgid "ClusterIntegration|HTTP Error"
msgstr "Error HTTP"
@@ -7548,7 +7593,7 @@ msgid "ClusterIntegration|Integration disabled"
msgstr ""
msgid "ClusterIntegration|Integration enabled"
-msgstr ""
+msgstr "Integración habilitada"
msgid "ClusterIntegration|Integrations allow you to use applications installed in your cluster as part of your GitLab workflow."
msgstr ""
@@ -7566,7 +7611,7 @@ msgid "ClusterIntegration|Kubernetes cluster was successfully created."
msgstr "El cluster Kubernetes se ha creado correctamente."
msgid "ClusterIntegration|Kubernetes clusters allow you to use review apps, deploy your applications, run your pipelines, and much more in an easy way."
-msgstr "ClusterIntegration | Los clústeres de Kubernetes le permiten utilizar aplicaciones de revisión, desplegar sus aplicaciones, ejecutar sus pipelines y mucho más de una manera sencilla."
+msgstr "Los clústeres de Kubernetes le permiten utilizar aplicaciones de revisión, desplegar sus aplicaciones, ejecutar sus pipelines y mucho más de una manera sencilla."
msgid "ClusterIntegration|Kubernetes version"
msgstr "Versión de Kubernetes"
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr "Subredes"
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -7890,13 +7935,13 @@ msgid "ClusterIntegration|Troubleshooting tips:"
msgstr ""
msgid "ClusterIntegration|Unable to Authenticate"
-msgstr ""
+msgstr "No se puede autenticar"
msgid "ClusterIntegration|Unable to Connect"
-msgstr ""
+msgstr "No se puede conectar"
msgid "ClusterIntegration|Unknown Error"
-msgstr ""
+msgstr "Error desconocido"
msgid "ClusterIntegration|Uses the Cloud Run, Istio, and HTTP Load Balancing addons for this cluster."
msgstr "Utiliza los complementos Cloud Run, Istio y balanceo de carga HTTP para este clúster."
@@ -7992,7 +8037,7 @@ msgid "Code Coverage|Couldn't fetch the code coverage data"
msgstr "No es posible recuperar los datos de la cobertura de código"
msgid "Code Owner"
-msgstr ""
+msgstr "Propietario del código"
msgid "Code Owners"
msgstr "Propietarios del código"
@@ -8016,16 +8061,16 @@ msgid "Code owners"
msgstr "Propietarios del código"
msgid "Code review"
-msgstr ""
+msgstr "Revisión de código"
msgid "Code snippet copied. Insert it in the correct location in the YAML file."
msgstr ""
msgid "CodeIntelligence|This is the definition"
-msgstr ""
+msgstr "Esta es la definición"
msgid "CodeNavigation|No references found"
-msgstr ""
+msgstr "No se encontraron referencias"
msgid "CodeOwner|Pattern"
msgstr "Patrón"
@@ -8055,13 +8100,13 @@ msgid "Collapse"
msgstr "Contraer"
msgid "Collapse all threads"
-msgstr ""
+msgstr "Contraer todos los hilos"
msgid "Collapse approvers"
msgstr "Contraer aprobadores"
msgid "Collapse issues"
-msgstr ""
+msgstr "Contraer las incidencias"
msgid "Collapse milestones"
msgstr "Contraer hitos"
@@ -8079,13 +8124,13 @@ msgid "Collector hostname"
msgstr "Nombre del recolector"
msgid "Colorize messages"
-msgstr ""
+msgstr "Colorear mensajes"
msgid "ComboSearch is not defined"
msgstr "ComboSearch no está definido"
msgid "Comma-separated list of email addresses."
-msgstr ""
+msgstr "Lista de direcciones de correo electrónico separadas por comas."
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr "Separados por comas, ej. '1.1.1.1, 2.2.2.0/24'"
@@ -8121,7 +8166,7 @@ msgid "Comment '%{label}' position"
msgstr "Comentario '%{label}' en la posición"
msgid "Comment form position"
-msgstr ""
+msgstr "Posición del formulario de comentarios"
msgid "Comment is being updated"
msgstr "El comentario está siendo actualizado"
@@ -8222,22 +8267,22 @@ msgid "Commit…"
msgstr "Commit..."
msgid "Community forum"
-msgstr ""
+msgstr "Foro de la comunidad"
msgid "Company"
-msgstr ""
+msgstr "Empresa"
msgid "Compare"
msgstr "Comparar"
msgid "Compare %{oldCommitId}...%{newCommitId}"
-msgstr ""
+msgstr "Comparar %{oldCommitId}...%{newCommitId}"
msgid "Compare Git revisions"
msgstr "Comparar revisiones de Git"
msgid "Compare GitLab editions"
-msgstr ""
+msgstr "Compare las ediciones de GitLab"
msgid "Compare Revisions"
msgstr "Comparar revisiones"
@@ -8267,28 +8312,28 @@ msgid "CompareRevisions|Branches"
msgstr ""
msgid "CompareRevisions|Compare"
-msgstr ""
+msgstr "Comparar"
msgid "CompareRevisions|Create merge request"
msgstr ""
msgid "CompareRevisions|Filter by Git revision"
-msgstr ""
+msgstr "Filtrar por revisión Git"
msgid "CompareRevisions|Select Git revision"
-msgstr ""
+msgstr "Seleccionar revisión Git"
msgid "CompareRevisions|Select branch/tag"
msgstr ""
msgid "CompareRevisions|Select target project"
-msgstr ""
+msgstr "Seleccione el proyecto objetivo"
msgid "CompareRevisions|Swap revisions"
msgstr ""
msgid "CompareRevisions|Tags"
-msgstr ""
+msgstr "Etiquetas"
msgid "CompareRevisions|There was an error while loading the branch/tag list. Please try again."
msgstr ""
@@ -8312,19 +8357,16 @@ msgid "Compliance"
msgstr "Cumplimiento"
msgid "Compliance Dashboard"
-msgstr ""
+msgstr "Panel de cumplimiento"
msgid "Compliance framework"
-msgstr ""
-
-msgid "Compliance framework (optional)"
-msgstr ""
+msgstr "Framework de cumplimiento"
msgid "ComplianceDashboard|created by:"
msgstr "Creado por:"
msgid "ComplianceFrameworks|Add framework"
-msgstr ""
+msgstr "Añadir framework"
msgid "ComplianceFrameworks|Combines with the CI configuration at runtime."
msgstr ""
@@ -8342,10 +8384,10 @@ msgid "ComplianceFrameworks|Delete compliance framework %{framework}"
msgstr ""
msgid "ComplianceFrameworks|Delete framework"
-msgstr ""
+msgstr "Eliminar framework"
msgid "ComplianceFrameworks|Edit framework"
-msgstr ""
+msgstr "Editar framework"
msgid "ComplianceFrameworks|Error deleting the compliance framework. Please try again"
msgstr ""
@@ -8384,7 +8426,7 @@ msgid "ComplianceFramework|New Compliance Framework"
msgstr ""
msgid "Component"
-msgstr ""
+msgstr "Componente"
msgid "Confidence"
msgstr "Confianza"
@@ -8399,7 +8441,7 @@ msgid "Configuration"
msgstr "Configuración"
msgid "Configuration help"
-msgstr ""
+msgstr "Ayuda de configuración"
msgid "Configure %{italic_start}What's new%{italic_end} drawer and content."
msgstr ""
@@ -8423,7 +8465,7 @@ msgid "Configure Gitaly timeouts."
msgstr "Configurar los tiempos de espera de Gitaly."
msgid "Configure Integrations"
-msgstr ""
+msgstr "Configurar integraciones"
msgid "Configure Prometheus"
msgstr "Configurar Prometheus"
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr "Configurar los límites para las peticiones web y las peticiones API."
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr "Configure el límite en el número de alertas entrantes que se pueden enviar a un proyecto."
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -8492,16 +8534,16 @@ msgid "Confirm"
msgstr "Confirmar"
msgid "Confirm new password"
-msgstr ""
+msgstr "Confirmar nueva contraseña"
msgid "Confirm user"
-msgstr ""
+msgstr "Confirmar usuario"
msgid "Confirm your account"
-msgstr ""
+msgstr "Confirma su cuenta"
msgid "Confirm your email address"
-msgstr ""
+msgstr "Confirma su correo electrónico"
msgid "Confirmation email sent to %{email}"
msgstr "Email de confirmación enviado a %{email}"
@@ -8510,10 +8552,10 @@ msgid "Confirmation required"
msgstr "Se requiere confirmación"
msgid "Confirmed at:"
-msgstr ""
+msgstr "Confirmado el:"
msgid "Confirmed:"
-msgstr ""
+msgstr "Confirmado:"
msgid "Conflict: This file was added both in the source and target branches, but with different contents."
msgstr ""
@@ -8537,7 +8579,7 @@ msgid "Conflict: This file was renamed in the source branch, but removed in the
msgstr ""
msgid "Confluence"
-msgstr ""
+msgstr "Confluence"
msgid "Confluence Cloud Workspace URL"
msgstr ""
@@ -8618,13 +8660,13 @@ msgid "Container registry is not enabled on this GitLab instance. Ask an adminis
msgstr "El registro de contenedores no está activado en esta instancia de GitLab. Solicite a un administrador que lo habilite para que Auto DevOps funcione."
msgid "Container repositories"
-msgstr ""
+msgstr "Repositorios de contenedores"
msgid "Container repositories synchronization concurrency limit"
msgstr ""
msgid "Container repository"
-msgstr ""
+msgstr "Repositorio de contenedores"
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
@@ -8766,16 +8808,16 @@ msgid "ContainerRegistry|Invalid tag: missing manifest digest"
msgstr ""
msgid "ContainerRegistry|Keep tags matching:"
-msgstr ""
+msgstr "Mantener etiquetas coincidentes:"
msgid "ContainerRegistry|Keep the most recent:"
-msgstr ""
+msgstr "Mantener el más reciente:"
msgid "ContainerRegistry|Keep these tags"
-msgstr ""
+msgstr "Mantener estas etiquetas"
msgid "ContainerRegistry|Last updated %{time}"
-msgstr ""
+msgstr "Última actualización %{time}"
msgid "ContainerRegistry|Login"
msgstr "Iniciar sesión"
@@ -9023,7 +9065,7 @@ msgid "ContributionAnalytics|No pushes for the selected time period."
msgstr ""
msgid "Contributions for %{calendar_date}"
-msgstr ""
+msgstr "Contribuciones para %{calendar_date}"
msgid "Contributions per group member"
msgstr "Contribuciones por cada miembro de un grupo"
@@ -9062,7 +9104,7 @@ msgid "Copy %{http_label} clone URL"
msgstr "Copiar la URL %{http_label} de clonado"
msgid "Copy %{name}"
-msgstr ""
+msgstr "Copiar %{name}"
msgid "Copy %{protocol} clone URL"
msgstr "Copiar la URL de clonado del protocolo %{protocol}"
@@ -9083,7 +9125,7 @@ msgid "Copy ID"
msgstr "Copiar el ID"
msgid "Copy IP Address"
-msgstr ""
+msgstr "Copiar dirección IP"
msgid "Copy KRB5 clone URL"
msgstr "Copiar la URL de clonado KRB5"
@@ -9152,13 +9194,13 @@ msgid "Copy the code below to implement tracking in your application:"
msgstr ""
msgid "Copy this registration token."
-msgstr ""
+msgstr "Copiar este token de registro."
msgid "Copy this value"
msgstr "Copiar este valor"
msgid "Copy to clipboard"
-msgstr ""
+msgstr "Copiar al portapapeles"
msgid "Copy token"
msgstr "Copiar el token"
@@ -9170,55 +9212,55 @@ msgid "Copy value"
msgstr "Copiar valor"
msgid "Corpus Management|Are you sure you want to delete the corpus?"
-msgstr ""
+msgstr "¿Está seguro de que desea eliminar el corpus?"
msgid "CorpusManagement|Actions"
-msgstr ""
+msgstr "Acciones"
msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
-msgstr ""
+msgstr "Los corpus se utilizan en las pruebas de tipo fuzz como fuente de mutación para mejorar futuras pruebas."
msgid "CorpusManagement|Corpus name"
-msgstr ""
+msgstr "Nombre del corpus"
msgid "CorpusManagement|Fuzz testing corpus management"
-msgstr ""
+msgstr "Administración de corpus de prueba de Fuzz"
msgid "CorpusManagement|Last updated"
-msgstr ""
+msgstr "Última actualización"
msgid "CorpusManagement|Last used"
-msgstr ""
+msgstr "Último uso"
msgid "CorpusManagement|Latest Job:"
-msgstr ""
+msgstr "Último trabajo:"
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
-msgstr ""
+msgstr "Nueva subida"
msgid "CorpusManagement|Not Set"
-msgstr ""
+msgstr "Sin establecer"
msgid "CorpusManagement|Target"
-msgstr ""
+msgstr "Destino"
msgid "CorpusManagement|To use this corpus, edit the corresponding YAML file"
msgstr ""
msgid "CorpusManagement|Total Size: %{totalSize}"
-msgstr ""
+msgstr "Tamaño total: %{totalSize}"
msgid "CorpusMnagement|New corpus"
-msgstr ""
+msgstr "Nuevo corpus"
msgid "Could not add admins as members"
msgstr "No se puede agregar administradores como miembros"
msgid "Could not apply %{name} command."
-msgstr ""
+msgstr "No se pudo aplicar el comando %{name}."
msgid "Could not archive %{design}. Please try again."
msgstr ""
@@ -9251,19 +9293,19 @@ msgid "Could not create group"
msgstr "Se ha producido un error al crear el grupo"
msgid "Could not create issue"
-msgstr ""
+msgstr "Se ha producido un error al crear la incidencia"
msgid "Could not create project"
msgstr "Se ha producido un error al crear el proyecto"
msgid "Could not create wiki page"
-msgstr ""
+msgstr "Se ha producido un error al crear la página wiki"
msgid "Could not delete chat nickname %{chat_name}."
msgstr "No es posible eliminar el apodo del chate %{chat_name}."
msgid "Could not delete wiki page"
-msgstr ""
+msgstr "Se ha producido un error al eliminar la página wiki"
msgid "Could not draw the lines for job relationships"
msgstr ""
@@ -9320,7 +9362,7 @@ msgid "Could not update the LDAP settings"
msgstr "No se pudo actualizar la configuración de LDAP"
msgid "Could not update wiki page"
-msgstr ""
+msgstr "Se ha producido un error al actualizar la página wiki"
msgid "Could not upload your designs as one or more files uploaded are not supported."
msgstr ""
@@ -9341,7 +9383,7 @@ msgid "Create %{environment}"
msgstr "Crear %{environment}"
msgid "Create %{humanized_resource_name}"
-msgstr ""
+msgstr "Crear %{humanized_resource_name}"
msgid "Create %{type}"
msgstr "Crear %{type}"
@@ -9425,7 +9467,7 @@ msgid "Create group label"
msgstr "Crear etiqueta de grupo"
msgid "Create incident"
-msgstr ""
+msgstr "Crear incidente"
msgid "Create issue"
msgstr "Crear incidencia"
@@ -9434,7 +9476,7 @@ msgid "Create iteration"
msgstr "Crear iteración"
msgid "Create list"
-msgstr ""
+msgstr "Crear lista"
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr "Crear listas desde las etiquetas. Las incidencias que contengan esa etiqueta aparecerán en esa lista."
@@ -9452,10 +9494,10 @@ msgid "Create new"
msgstr "Crear nuevo"
msgid "Create new %{name} by email"
-msgstr ""
+msgstr "Crear nuevo %{name} por correo electrónico"
msgid "Create new CI/CD pipeline"
-msgstr ""
+msgstr "Crear nuevo pipeline de CI/CD"
msgid "Create new Value Stream"
msgstr ""
@@ -9464,7 +9506,7 @@ msgid "Create new branch"
msgstr "Crear una nueva rama"
msgid "Create new confidential %{issuableType}"
-msgstr ""
+msgstr "Crear nuevo %{issuableType} confidencial"
msgid "Create new directory"
msgstr "Crear nuevo directorio"
@@ -9479,7 +9521,7 @@ msgid "Create new label"
msgstr "Crear nueva etiqueta"
msgid "Create new project"
-msgstr ""
+msgstr "Crear nuevo proyecto"
msgid "Create new..."
msgstr "Crear nuevo..."
@@ -9491,7 +9533,7 @@ msgid "Create project label"
msgstr "Crear etiqueta de proyecto"
msgid "Create release"
-msgstr ""
+msgstr "Crear versión"
msgid "Create requirement"
msgstr "Crear requisito"
@@ -9500,10 +9542,10 @@ msgid "Create snippet"
msgstr "Crear fragmento de código"
msgid "Create tag %{tagName}"
-msgstr ""
+msgstr "Crear etiqueta %{tagName}"
msgid "Create user"
-msgstr ""
+msgstr "Crear usuario"
msgid "Create wildcard: %{searchTerm}"
msgstr "Crear comodín: %{searchTerm}"
@@ -9530,7 +9572,7 @@ msgid "CreateTokenToCloneLink|create a personal access token"
msgstr "crear un token de acceso personal"
msgid "CreateValueStreamForm|%{name} (default)"
-msgstr ""
+msgstr "%{name} (por defecto)"
msgid "CreateValueStreamForm|'%{name}' Value Stream created"
msgstr ""
@@ -9542,7 +9584,7 @@ msgid "CreateValueStreamForm|Add another stage"
msgstr ""
msgid "CreateValueStreamForm|Add stage"
-msgstr ""
+msgstr "Añadir etapa"
msgid "CreateValueStreamForm|All default stages are currently visible"
msgstr ""
@@ -9659,7 +9701,7 @@ msgid "Created"
msgstr "Creado"
msgid "Created %{epicTimeagoDate}"
-msgstr ""
+msgstr "Creado %{epicTimeagoDate}"
msgid "Created %{timestamp}"
msgstr "Creado %{timestamp}"
@@ -9677,7 +9719,7 @@ msgid "Created branch '%{branch_name}' and a merge request to resolve this issue
msgstr "Creada una rama '%{branch_name}' y un merge request para resolver esta incidencia."
msgid "Created by %{job}"
-msgstr ""
+msgstr "Creado por %{job}"
msgid "Created by me"
msgstr "Creado por mí"
@@ -9704,7 +9746,7 @@ msgid "Created on"
msgstr "Creado en"
msgid "Created on %{created_at}"
-msgstr ""
+msgstr "Creado el %{created_at}"
msgid "Created on:"
msgstr "Creado sobre:"
@@ -9731,7 +9773,7 @@ msgid "Credentials"
msgstr "Credenciales"
msgid "CredentialsInventory|GPG Keys"
-msgstr ""
+msgstr "Claves GPG"
msgid "CredentialsInventory|No credentials found"
msgstr "No se encontraron credenciales"
@@ -9743,10 +9785,10 @@ msgid "CredentialsInventory|SSH Keys"
msgstr "Claves SSH"
msgid "Credit card validated at:"
-msgstr ""
+msgstr "Tarjeta de crédito validada el:"
msgid "Credit card validated:"
-msgstr ""
+msgstr "Tarjeta de crédito validada:"
msgid "Critical vulnerabilities present"
msgstr "Vulnerabilidades críticas presentes"
@@ -9755,7 +9797,7 @@ msgid "Cron Timezone"
msgstr "Zona horaria del Cron"
msgid "Cron time zone"
-msgstr ""
+msgstr "Zona horaria Cron"
msgid "Crowd"
msgstr ""
@@ -9767,10 +9809,10 @@ msgid "CsvParser|Quoted field unterminated"
msgstr ""
msgid "CsvParser|Too few fields"
-msgstr ""
+msgstr "Muy pocos campos"
msgid "CsvParser|Too many fields"
-msgstr ""
+msgstr "Demasiados campos"
msgid "CsvParser|Trailing quote on quoted field is malformed"
msgstr ""
@@ -9779,7 +9821,7 @@ msgid "CsvParser|Unable to auto-detect delimiter; defaulted to \",\""
msgstr ""
msgid "Current"
-msgstr ""
+msgstr "Actual"
msgid "Current Branch"
msgstr "Rama actual"
@@ -9815,7 +9857,7 @@ msgid "CurrentUser|One of your groups is running out"
msgstr ""
msgid "CurrentUser|Preferences"
-msgstr ""
+msgstr "Preferencias"
msgid "CurrentUser|Start an Ultimate trial"
msgstr ""
@@ -9836,7 +9878,7 @@ msgid "Custom hostname (for private commit emails)"
msgstr "Nombre de host personalizado (para los correos electrónicos privados de los commit)"
msgid "Custom metrics"
-msgstr ""
+msgstr "Métricas personalizadas"
msgid "Custom notification events"
msgstr "Eventos de notificaciones personalizadas"
@@ -9857,10 +9899,10 @@ msgid "Custom range (UTC)"
msgstr "Rango personalizado (UTC)"
msgid "Customizable by an administrator."
-msgstr ""
+msgstr "Personalizable por un administrador."
msgid "Customizable by owners."
-msgstr ""
+msgstr "Personalizable por los propietarios."
msgid "Customize CI/CD settings, including Auto DevOps, shared runners, and job artifacts."
msgstr ""
@@ -9890,7 +9932,7 @@ msgid "CustomizeHomepageBanner|Do you want to customize this page?"
msgstr ""
msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
+msgstr "Ir a las preferencias"
msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
msgstr ""
@@ -10004,7 +10046,7 @@ msgid "CycleAnalytics|All stages"
msgstr "Todas las etapas"
msgid "CycleAnalytics|Average days to completion"
-msgstr ""
+msgstr "Promedio de días hasta completar"
msgid "CycleAnalytics|Date"
msgstr "Fecha"
@@ -10013,7 +10055,7 @@ msgid "CycleAnalytics|Days to completion"
msgstr "Días hasta completar"
msgid "CycleAnalytics|Display chart filters"
-msgstr ""
+msgstr "Mostrar filtros de gráficos"
msgid "CycleAnalytics|No stages selected"
msgstr "Ninguna etapa seleccionada"
@@ -10125,7 +10167,7 @@ msgid "Dashboard"
msgstr "Panel de control"
msgid "Dashboard uid not found"
-msgstr ""
+msgstr "No se ha encontrado el uid del tablero no encontrado"
msgid "DashboardProjects|All"
msgstr "Todos"
@@ -10149,13 +10191,13 @@ msgid "DastConfig|Customize DAST settings to suit your requirements. Configurati
msgstr ""
msgid "DastConfig|DAST Settings"
-msgstr ""
+msgstr "Configuración de DAST"
msgid "DastConfig|Generate code snippet"
-msgstr ""
+msgstr "Generar fragmento de código"
msgid "DastConfig|Scan Configuration"
-msgstr ""
+msgstr "Configuración de escaneo"
msgid "DastProfiles|A passive scan monitors all HTTP messages (requests and responses) sent to the target. An active scan attacks the target to find potential vulnerabilities."
msgstr ""
@@ -10164,7 +10206,7 @@ msgid "DastProfiles|AJAX spider"
msgstr ""
msgid "DastProfiles|Active"
-msgstr ""
+msgstr "Activo"
msgid "DastProfiles|Additional request headers (Optional)"
msgstr ""
@@ -10173,10 +10215,10 @@ msgid "DastProfiles|Are you sure you want to delete this profile?"
msgstr ""
msgid "DastProfiles|Authentication"
-msgstr ""
+msgstr "Autentificación"
msgid "DastProfiles|Authentication URL"
-msgstr ""
+msgstr "URL de autentificación"
msgid "DastProfiles|Branch missing"
msgstr ""
@@ -10221,52 +10263,52 @@ msgid "DastProfiles|Could not update the site profile. Please try again."
msgstr ""
msgid "DastProfiles|DAST Scan"
-msgstr ""
+msgstr "Escaner DAST"
msgid "DastProfiles|Debug messages"
-msgstr ""
+msgstr "Mensajes de depuración"
msgid "DastProfiles|Delete profile"
-msgstr ""
+msgstr "Eliminar perfil"
msgid "DastProfiles|Do you want to discard this scanner profile?"
-msgstr ""
+msgstr "¿Desea descartar este perfil de escáner?"
msgid "DastProfiles|Do you want to discard this site profile?"
-msgstr ""
+msgstr "¿Desea descartar este perfil del sitio?"
msgid "DastProfiles|Do you want to discard your changes?"
-msgstr ""
+msgstr "¿Desea descartar sus cambios?"
msgid "DastProfiles|Edit profile"
-msgstr ""
+msgstr "Editar perfil"
msgid "DastProfiles|Edit scanner profile"
-msgstr ""
+msgstr "Editar perfil de escáner"
msgid "DastProfiles|Edit site profile"
-msgstr ""
+msgstr "Editar perfil del sitio"
msgid "DastProfiles|Enable Authentication"
-msgstr ""
+msgstr "Habilitar autenticación"
msgid "DastProfiles|Enter URLs in a comma-separated list."
-msgstr ""
+msgstr "Introduzca las URLs en una lista separada por comas."
msgid "DastProfiles|Enter headers in a comma-separated list."
-msgstr ""
+msgstr "Introduzca cabeceras en una lista separada por comas."
msgid "DastProfiles|Error Details"
-msgstr ""
+msgstr "Detalles del error"
msgid "DastProfiles|Excluded URLs"
-msgstr ""
+msgstr "URL excluidas"
msgid "DastProfiles|Excluded URLs (Optional)"
-msgstr ""
+msgstr "URL excluidas (opcional)"
msgid "DastProfiles|Hide debug messages"
-msgstr ""
+msgstr "Ocultar mensajes de depuración"
msgid "DastProfiles|Include debug messages in the DAST console output."
msgstr ""
@@ -10275,10 +10317,10 @@ msgid "DastProfiles|Manage DAST scans"
msgstr ""
msgid "DastProfiles|Manage profiles"
-msgstr ""
+msgstr "Administrar perfiles"
msgid "DastProfiles|Minimum = 0 (no timeout enabled), Maximum = 2880 minutes"
-msgstr ""
+msgstr "Mínimo = 0 (sin tiempo de espera habilitado), Máximo = 2880 minutos"
msgid "DastProfiles|Minimum = 1 second, Maximum = 3600 seconds"
msgstr ""
@@ -10299,13 +10341,13 @@ msgid "DastProfiles|No site profiles created yet"
msgstr ""
msgid "DastProfiles|Not Validated"
-msgstr ""
+msgstr "No validado"
msgid "DastProfiles|Passive"
msgstr ""
msgid "DastProfiles|Password"
-msgstr ""
+msgstr "Contraseña"
msgid "DastProfiles|Password form field"
msgstr ""
@@ -10338,49 +10380,49 @@ msgid "DastProfiles|Saved Scans"
msgstr ""
msgid "DastProfiles|Scan"
-msgstr ""
+msgstr "Escanear"
msgid "DastProfiles|Scan mode"
-msgstr ""
+msgstr "Modo de escaneo"
msgid "DastProfiles|Scanner Profile"
-msgstr ""
+msgstr "Perfil de escaneo"
msgid "DastProfiles|Scanner Profiles"
-msgstr ""
+msgstr "Perfiles de escaneo"
msgid "DastProfiles|Scanner name"
-msgstr ""
+msgstr "Nombre del escáner"
msgid "DastProfiles|Select branch"
-msgstr ""
+msgstr "Seleccionar branch"
msgid "DastProfiles|Show debug messages"
-msgstr ""
+msgstr "Mostrar mensajes de depuración"
msgid "DastProfiles|Site Profile"
-msgstr ""
+msgstr "Perfil del sitio"
msgid "DastProfiles|Site Profiles"
-msgstr ""
+msgstr "Perfiles del sitio"
msgid "DastProfiles|Site name"
-msgstr ""
+msgstr "Nombre del sitio"
msgid "DastProfiles|Site type"
-msgstr ""
+msgstr "Tipo de sitio"
msgid "DastProfiles|Spider timeout"
msgstr ""
msgid "DastProfiles|Target"
-msgstr ""
+msgstr "Destino"
msgid "DastProfiles|Target URL"
-msgstr ""
+msgstr "URL de destino"
msgid "DastProfiles|Target timeout"
-msgstr ""
+msgstr "Tiempo de espera de destino"
msgid "DastProfiles|The maximum number of minutes allowed for the spider to traverse the site."
msgstr ""
@@ -10401,7 +10443,7 @@ msgid "DastProfiles|Turn on AJAX spider"
msgstr ""
msgid "DastProfiles|URL"
-msgstr ""
+msgstr "URL"
msgid "DastProfiles|URLs to skip during the authenticated scan."
msgstr ""
@@ -10416,10 +10458,10 @@ msgid "DastProfiles|Validated"
msgstr "Validado"
msgid "DastProfiles|Validation status"
-msgstr ""
+msgstr "Estado de validación"
msgid "DastProfiles|Website"
-msgstr ""
+msgstr "Sitio web"
msgid "DastProfiles|You can either choose a passive scan or validate the target site in your chosen site profile. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10440,28 +10485,37 @@ msgid "DastSiteValidation|Download validation text file"
msgstr ""
msgid "DastSiteValidation|Header validation"
+msgstr "Validar encabezado"
+
+msgid "DastSiteValidation|Meta tag validation"
msgstr ""
msgid "DastSiteValidation|Retry validation"
-msgstr ""
+msgstr "Reintentar validación"
msgid "DastSiteValidation|Revoke validation"
-msgstr ""
+msgstr "Revocar validación"
msgid "DastSiteValidation|Step 1 - Choose site validation method"
-msgstr ""
+msgstr "Paso 1 - Elija el método de validación del sitio"
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
+msgstr "Paso 2 - Añada la siguiente cabecera HTTP a su sitio"
+
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
msgstr ""
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
-msgstr ""
+msgstr "Paso 2 - Añada el siguiente texto al sitio de destino"
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
+msgstr "Paso 3 - Confirme la ubicación del encabezado y valide"
+
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
-msgstr ""
+msgstr "Paso 3 - Confirme la ubicación de archivo de texto y valide"
msgid "DastSiteValidation|Text file validation"
msgstr ""
@@ -10477,20 +10531,23 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
-msgid "DastSiteValidation|Validate"
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
msgstr ""
+msgid "DastSiteValidation|Validate"
+msgstr "Validar"
+
msgid "DastSiteValidation|Validate target site"
msgstr ""
msgid "DastSiteValidation|Validated"
-msgstr ""
+msgstr "Validado"
msgid "DastSiteValidation|Validating..."
-msgstr ""
+msgstr "Validando..."
msgid "DastSiteValidation|Validation failed"
-msgstr ""
+msgstr "Se ha producido un error en la validación"
msgid "DastSiteValidation|Validation failed for %{url}. %{retryButtonStart}Retry validation%{retryButtonEnd}."
msgstr ""
@@ -10505,7 +10562,7 @@ msgid "Data is still calculating..."
msgstr "Los datos aún se están calculando..."
msgid "Data type"
-msgstr ""
+msgstr "Tipo de datos"
msgid "Database update failed"
msgstr "Se ha producido un error al actualizar la base de datos"
@@ -10517,10 +10574,10 @@ msgid "DatadogIntegration|(Advanced) The full URL for your Datadog site."
msgstr ""
msgid "DatadogIntegration|API URL"
-msgstr ""
+msgstr "URL del API"
msgid "DatadogIntegration|Environment"
-msgstr ""
+msgstr "Entorno"
msgid "DatadogIntegration|For self-managed deployments, set the %{codeOpen}env%{codeClose} tag for all the data sent to Datadog. %{linkOpen}How do I use tags?%{linkClose}"
msgstr ""
@@ -10532,7 +10589,7 @@ msgid "DatadogIntegration|Send CI/CD pipeline information to Datadog to monitor
msgstr ""
msgid "DatadogIntegration|Service"
-msgstr ""
+msgstr "Servicio"
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
@@ -10553,7 +10610,7 @@ msgid "Date picker"
msgstr "Selector de fecha"
msgid "Date range"
-msgstr ""
+msgstr "Rango de fechas"
msgid "Date range must be shorter than %{max_range} days."
msgstr ""
@@ -10607,13 +10664,10 @@ msgid "Decompressed archive size validation failed."
msgstr ""
msgid "Decrease"
-msgstr ""
-
-msgid "Default"
-msgstr ""
+msgstr "Reducir"
msgid "Default CI/CD configuration file"
-msgstr ""
+msgstr "Archivo de configuración por defecto de CI/CD"
msgid "Default artifacts expiration"
msgstr "Vencimiento predeterminado para los artefactos"
@@ -10661,7 +10715,7 @@ msgid "Default: Map a FogBugz account ID to a full name"
msgstr "Por defecto: Asignar un ID de cuenta de FogBugz a un nombre completo"
msgid "DefaultBranchLabel|default"
-msgstr ""
+msgstr "Por defecto"
msgid "Define a custom deploy freeze pattern with %{cronSyntaxStart}cron syntax%{cronSyntaxEnd}"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr "Definición"
@@ -10715,7 +10772,7 @@ msgid "Delete Comment"
msgstr "Eliminar el comentario"
msgid "Delete Key"
-msgstr ""
+msgstr "Eliminar clave"
msgid "Delete Value Stream"
msgstr ""
@@ -10729,14 +10786,20 @@ msgstr "Eliminar artefactos"
msgid "Delete badge"
msgstr "Eliminar insignia"
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr "Eliminar comentario"
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr "Eliminar dominio"
msgid "Delete file"
-msgstr ""
+msgstr "Eliminar el archivo"
msgid "Delete image repository"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr "Eliminar proyecto"
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr "Eliminar rama origen"
msgid "Delete subscription"
msgstr "Eliminar suscripción"
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr "Eliminar este adjunto"
@@ -10868,8 +10937,8 @@ msgstr[1] "%d vulnerabilidades adicionales no mostradas"
msgid "Dependencies|%d more"
msgid_plural "Dependencies|%d more"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d más"
+msgstr[1] "%d más"
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
@@ -10880,13 +10949,13 @@ msgid "Dependencies|%{remainingLicensesCount} more"
msgstr "%{remainingLicensesCount} más"
msgid "Dependencies|(top level)"
-msgstr ""
+msgstr "(nivel superior)"
msgid "Dependencies|All"
msgstr "Todas"
msgid "Dependencies|Based on the %{linkStart}latest successful%{linkEnd} scan"
-msgstr ""
+msgstr "Basado en el último escaneo de %{linkStart}%{linkEnd} correcto"
msgid "Dependencies|Component"
msgstr "Componente"
@@ -10895,7 +10964,7 @@ msgid "Dependencies|Component name"
msgstr "Nombre del componente"
msgid "Dependencies|Dependency path"
-msgstr ""
+msgstr "Ruta de dependencias"
msgid "Dependencies|Export as JSON"
msgstr "Exportar como JSON"
@@ -10951,12 +11020,12 @@ msgstr "Escaneo de dependencias"
msgid "Dependency proxy"
msgstr "Proxy de dependencias"
-msgid "Dependency proxy URL"
-msgstr "URL del proxy de dependencias"
-
msgid "Dependency proxy feature is limited to public groups for now."
msgstr "La funcionalidad del proxy de dependencias está limitada, por ahora, únicamente a grupos públicos."
+msgid "Dependency proxy image prefix"
+msgstr ""
+
msgid "DependencyProxy|Toggle Dependency Proxy"
msgstr "Cambiar el proxy de dependencias"
@@ -10985,7 +11054,7 @@ msgid "Deploy key was successfully updated."
msgstr "La clave de despliegue se actualizó correctamente."
msgid "Deploy keys"
-msgstr ""
+msgstr "Desplegar claves"
msgid "Deploy keys grant read/write access to all repositories in your instance"
msgstr ""
@@ -11002,9 +11071,21 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
-msgid "DeployFreeze|Edit"
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
msgstr ""
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
+msgid "DeployFreeze|Edit"
+msgstr "Editar"
+
msgid "DeployFreeze|Freeze end"
msgstr ""
@@ -11018,7 +11099,7 @@ msgid "DeployFreeze|Specify deploy freezes using %{cron_syntax_link_start}cron s
msgstr ""
msgid "DeployFreeze|Time zone"
-msgstr ""
+msgstr "Zona horaria"
msgid "DeployKeys|+%{count} others"
msgstr "+%{count} otros"
@@ -11165,10 +11246,10 @@ msgid "Deployed to"
msgstr "Desplegado en"
msgid "Deployed-after"
-msgstr ""
+msgstr "Desplegado después"
msgid "Deployed-before"
-msgstr ""
+msgstr "Desplegado antes"
msgid "Deploying to"
msgstr "Desplegando en"
@@ -11183,7 +11264,7 @@ msgid "Deployment frequency"
msgstr ""
msgid "Deployments"
-msgstr ""
+msgstr "Despliegues"
msgid "Deployments|%{deployments} environment impacted."
msgid_plural "Deployments|%{deployments} environments impacted."
@@ -11209,7 +11290,7 @@ msgid "Deployment|running"
msgstr "en ejecución"
msgid "Deployment|skipped"
-msgstr ""
+msgstr "omitido"
msgid "Deployment|success"
msgstr "exitoso"
@@ -11227,7 +11308,7 @@ msgid "Description"
msgstr "Descripción"
msgid "Description (optional)"
-msgstr ""
+msgstr "Descripción (opcional)"
msgid "Description parsed with %{link_start}GitLab Flavored Markdown%{link_end}"
msgstr "Descripción analizada con %{link_start}GitLab Flavored Markdown%{link_end}"
@@ -11236,7 +11317,7 @@ msgid "Description parsed with %{link_start}GitLab Flavored Markdown%{link_end}.
msgstr ""
msgid "Description template"
-msgstr ""
+msgstr "Plantilla de descripción"
msgid "Description:"
msgstr "Descripción:"
@@ -11248,10 +11329,10 @@ msgid "Design Management files and data"
msgstr ""
msgid "Design repositories"
-msgstr ""
+msgstr "Repositorios de diseño"
msgid "Design repository"
-msgstr ""
+msgstr "Repositorio de diseño"
msgid "DesignManagement|%{current_design} of %{designs_count}"
msgstr "%{current_design} de %{designs_count}"
@@ -11404,16 +11485,16 @@ msgid "Detect host keys"
msgstr "Detectar las claves del host"
msgid "DevOps Adoption"
-msgstr ""
+msgstr "Adopción DevOps"
msgid "DevOps Report"
msgstr "Informe DevOps"
msgid "DevOps adoption"
-msgstr ""
+msgstr "Adopción DevOps"
msgid "Devices (optional)"
-msgstr ""
+msgstr "Dispositivos (opcional)"
msgid "DevopsAdoption|%{adoptedCount}/%{featuresCount} %{title} features adopted"
msgstr ""
@@ -11428,6 +11509,12 @@ msgid "DevopsAdoption|Add or remove subgroups"
msgstr ""
msgid "DevopsAdoption|Adopted"
+msgstr "Adoptado"
+
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
msgstr ""
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
@@ -11464,10 +11551,10 @@ msgid "DevopsAdoption|Confirm remove Group"
msgstr ""
msgid "DevopsAdoption|DAST"
-msgstr ""
+msgstr "DAST"
msgid "DevopsAdoption|DAST enabled for at least one project"
-msgstr ""
+msgstr "DAST habilitado para al menos un proyecto"
msgid "DevopsAdoption|Dependency Scanning"
msgstr ""
@@ -11488,9 +11575,9 @@ msgid "DevopsAdoption|Edit groups"
msgstr ""
msgid "DevopsAdoption|Edit subgroups"
-msgstr ""
+msgstr "Editar subgrupos"
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11503,28 +11590,28 @@ msgid "DevopsAdoption|Issues"
msgstr "Incidencias"
msgid "DevopsAdoption|MRs"
-msgstr ""
+msgstr "MRs"
msgid "DevopsAdoption|No results…"
-msgstr ""
+msgstr "Sin resultados…"
msgid "DevopsAdoption|Not adopted"
-msgstr ""
+msgstr "No adoptado"
msgid "DevopsAdoption|Ops"
-msgstr ""
+msgstr "Ops"
msgid "DevopsAdoption|Overall adoption"
-msgstr ""
+msgstr "Adopción global"
msgid "DevopsAdoption|Pipelines"
-msgstr ""
+msgstr "Pipelines"
msgid "DevopsAdoption|Remove Group"
-msgstr ""
+msgstr "Eliminar grupo"
msgid "DevopsAdoption|Remove Group from the table."
-msgstr ""
+msgstr "Eliminar el grupo de la tabla."
msgid "DevopsAdoption|Runner configured for project/group"
msgstr ""
@@ -11533,25 +11620,25 @@ msgid "DevopsAdoption|Runners"
msgstr ""
msgid "DevopsAdoption|SAST"
-msgstr ""
+msgstr "SAST"
msgid "DevopsAdoption|SAST enabled for at least one project"
-msgstr ""
+msgstr "SAST habilitado para al menos un proyecto"
msgid "DevopsAdoption|Sec"
-msgstr ""
+msgstr "Sec"
msgid "DevopsAdoption|There was an error enabling the current group. Please refresh the page."
-msgstr ""
+msgstr "Se ha producido un error al activar el grupo actual. Por favor, actualice la página."
msgid "DevopsAdoption|There was an error fetching Group adoption data. Please refresh the page."
-msgstr ""
+msgstr "Se ha producido un error al recuperar los datos de adopción del grupo. Por favor, actualice la página."
msgid "DevopsAdoption|There was an error fetching Groups. Please refresh the page."
-msgstr ""
+msgstr "Se ha producido un error al recuperar los grupos. Por favor, actualice la página."
msgid "DevopsAdoption|This group has no subgroups"
-msgstr ""
+msgstr "Este grupo no tiene subgrupos"
msgid "DevopsAdoption|You cannot remove the group you are currently in."
msgstr ""
@@ -11563,31 +11650,31 @@ msgid "DevopsReport|DevOps score metrics are based on usage over the last 30 day
msgstr ""
msgid "DevopsReport|High"
-msgstr ""
+msgstr "Alto"
msgid "DevopsReport|Leader usage"
msgstr ""
msgid "DevopsReport|Low"
-msgstr ""
+msgstr "Bajo"
msgid "DevopsReport|Moderate"
-msgstr ""
+msgstr "Moderado"
msgid "DevopsReport|Overview"
-msgstr ""
+msgstr "Resumen"
msgid "DevopsReport|Score"
-msgstr ""
+msgstr "Puntuación"
msgid "DevopsReport|Your score"
-msgstr ""
+msgstr "Su puntuación"
msgid "DevopsReport|Your usage"
-msgstr ""
+msgstr "Su uso"
msgid "Didn't receive a confirmation email?"
-msgstr ""
+msgstr "¿No ha recibido un correo electrónico de confirmación?"
msgid "Didn't receive confirmation instructions?"
msgstr ""
@@ -11641,7 +11728,7 @@ msgid "Disable"
msgstr "Deshabilitar"
msgid "Disable Two-factor Authentication"
-msgstr ""
+msgstr "Deshabilitar la autenticación de doble factor"
msgid "Disable What's new"
msgstr ""
@@ -11650,7 +11737,7 @@ msgid "Disable for this project"
msgstr "Deshabilitar para este proyecto"
msgid "Disable group runners"
-msgstr ""
+msgstr "Desactivar grupo de ejecutores"
msgid "Disable two-factor authentication"
msgstr "Desactivar la autenticación de dos factores"
@@ -11659,7 +11746,7 @@ msgid "Disabled"
msgstr "Deshabilitado"
msgid "Disabled by %{parent} owner"
-msgstr ""
+msgstr "Desactivado por el propietario de %{parent}"
msgid "Disabled mirrors can only be enabled by instance owners. It is recommended that you delete them."
msgstr "Las réplicas deshabilitadas solo pueden ser habilitadas por los propietarios de las instancias. Se recomienda eliminarlas."
@@ -11689,7 +11776,7 @@ msgid "DiscordService|Send notifications about project events to a Discord chann
msgstr ""
msgid "Discover"
-msgstr ""
+msgstr "Descubrir"
msgid "Discover GitLab Geo"
msgstr "Descubra GitLab Geo"
@@ -11973,7 +12060,7 @@ msgid "Dynamic Application Security Testing (DAST)"
msgstr "Prueba de seguridad de aplicaciones dinámica (DAST)"
msgid "E-mail:"
-msgstr ""
+msgstr "Correo electrónico:"
msgid "Each project can also have an issue tracker and a wiki."
msgstr ""
@@ -11999,6 +12086,9 @@ msgstr "Editar nodo de Geo"
msgid "Edit Group Hook"
msgstr "Editar hook del grupo"
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr "Editar etiqueta"
@@ -12015,7 +12105,7 @@ msgid "Edit Release"
msgstr "Editar versión"
msgid "Edit Requirement"
-msgstr ""
+msgstr "Editar requisito"
msgid "Edit Slack integration"
msgstr "Editar la integración con Slack"
@@ -12074,6 +12164,9 @@ msgstr "Editar clave pública de despliegue"
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr "Editar solo este archivo."
@@ -12183,7 +12276,7 @@ msgid "Email updates (optional)"
msgstr ""
msgid "Email:"
-msgstr ""
+msgstr "Correo electrónico:"
msgid "Email: %{email}"
msgstr "Correo electrónico: %{email}"
@@ -12231,7 +12324,7 @@ msgid "Emails sent to %{email} are also supported."
msgstr ""
msgid "EmailsOnPushService|Disable code diffs"
-msgstr "EmailsOnPushService | Desactivar diferencias de código"
+msgstr "Desactivar diferencias de código"
msgid "EmailsOnPushService|Don't include possibly sensitive code diffs in notification body."
msgstr "No incluya información sensible en los diferencias de código que se envían en el cuerpo de la notificación."
@@ -12276,13 +12369,10 @@ msgid "Enable Git pack file bitmap creation"
msgstr ""
msgid "Enable Gitpod"
-msgstr ""
+msgstr "Habilitar Gitpod"
msgid "Enable Gitpod?"
-msgstr ""
-
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
+msgstr "Habilitar Gitpod?"
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12303,7 +12393,7 @@ msgid "Enable Registration Features"
msgstr ""
msgid "Enable SSL verification"
-msgstr ""
+msgstr "Habilitar verificación SSL"
msgid "Enable Snowplow tracking"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12348,7 +12441,7 @@ msgid "Enable delayed project deletion by default for newly-created groups."
msgstr ""
msgid "Enable email notification"
-msgstr ""
+msgstr "Habilitar notificaciones por correo electrónico"
msgid "Enable error tracking"
msgstr "Habilitar seguimiento de errores"
@@ -12369,6 +12462,9 @@ msgid "Enable health and performance metrics endpoint"
msgstr ""
msgid "Enable in-product marketing emails"
+msgstr "Habilitar correos electrónicos de marketing en el producto"
+
+msgid "Enable incident management inbound alert limit"
msgstr ""
msgid "Enable integration"
@@ -12399,10 +12495,10 @@ msgid "Enable proxy"
msgstr "Habilitar el proxy"
msgid "Enable reCAPTCHA"
-msgstr ""
+msgstr "Habilitar reCAPTCHA"
msgid "Enable reCAPTCHA for login"
-msgstr ""
+msgstr "Habilitar reCAPTCHA para iniciar sesión"
msgid "Enable reCAPTCHA, Invisible Captcha, Akismet and set IP limits. For reCAPTCHA, we currently only support %{recaptcha_v2_link_start}v2%{recaptcha_v2_link_end}"
msgstr ""
@@ -12585,7 +12681,7 @@ msgid "Enter your password to approve"
msgstr "Introduzca su contraseña para aprobar"
msgid "Enterprise"
-msgstr ""
+msgstr "Empresa"
msgid "Environment"
msgstr "Entorno"
@@ -12699,10 +12795,10 @@ msgid "Environments|Commit"
msgstr "Commit"
msgid "Environments|Currently showing %{fetched} results."
-msgstr "Environments|Mostrando %{fetched} resultados."
+msgstr "Mostrando %{fetched} resultados."
msgid "Environments|Currently showing all results."
-msgstr "Environments|Mostrando todos los resultados."
+msgstr "Mostrando todos los resultados."
msgid "Environments|Delete"
msgstr "Eliminar"
@@ -12725,6 +12821,9 @@ msgstr "Despliegue"
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr "Entornos"
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr "Los entornos son lugares en los que se despliega el código, como por ejemplo, los entornos de test o los entornos de producción."
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr "Instala Elastic Stack en su clúster para habilitar capacidades de consulta avanzadas, como búsqueda de texto completo."
@@ -12750,7 +12852,7 @@ msgid "Environments|Learn more about stopping environments"
msgstr "Obtenga más información sobre cómo detener los entornos"
msgid "Environments|Logs from %{start} to %{end}."
-msgstr "Environments|Logs desde %{start} hasta %{end}."
+msgstr "Logs desde %{start} hasta %{end}."
msgid "Environments|More information"
msgstr ""
@@ -12765,7 +12867,7 @@ msgid "Environments|No deployments yet"
msgstr "Todavía no hay despliegues"
msgid "Environments|No pod selected"
-msgstr "Environments|No hay nigún pod seleccionado"
+msgstr "No hay nigún pod seleccionado"
msgid "Environments|No pods to display"
msgstr "No hay pods para mostrar"
@@ -12774,7 +12876,7 @@ msgid "Environments|Note that this action will stop the environment, but it will
msgstr "Note que esta acción detendrá el entorno, pero %{emphasisStart}no%{emphasisEnd} tendrá ningún efecto sobre cualquier instancia debido a que no hay una \"acción para detener el entorno\" definida en el archivo %{ciConfigLinkStart}.gitlab-ci.yml%{ciConfigLinkEnd}."
msgid "Environments|Open live environment"
-msgstr ""
+msgstr "Entorno abierto"
msgid "Environments|Pod name"
msgstr "Nombre del Pod"
@@ -12812,6 +12914,9 @@ msgstr "Detener entorno"
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr "Actualizado"
msgid "Environments|You don't have any environments right now"
msgstr "No tiene ningún entorno ahora mismo"
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr "protegido"
@@ -12894,7 +13005,7 @@ msgid "Epics|Assign Epic"
msgstr ""
msgid "Epics|Enter a title for your epic"
-msgstr ""
+msgstr "Ingrese un título para su épica"
msgid "Epics|How can I solve this?"
msgstr "¿Cómo puedo resolver esto?"
@@ -12981,7 +13092,7 @@ msgid "Error creating epic"
msgstr "Error al crear la tarea épica"
msgid "Error creating label."
-msgstr ""
+msgstr "Se ha producido un error al crear la etiqueta."
msgid "Error creating new iteration"
msgstr ""
@@ -13092,7 +13203,7 @@ msgid "Error occurred. A blocked user must be unblocked to be activated"
msgstr "Se ha producido un error. No es posible activar un usuario bloqueado"
msgid "Error occurred. User was not banned"
-msgstr ""
+msgstr "Se ha producido un error. El usuario no estaba bloqueado"
msgid "Error occurred. User was not blocked"
msgstr "Se ha producido un error. No se ha bloqueado el usuario"
@@ -13101,7 +13212,7 @@ msgid "Error occurred. User was not confirmed"
msgstr "Se ha producido un error. No se ha confirmado el usuario"
msgid "Error occurred. User was not unbanned"
-msgstr ""
+msgstr "Se ha producido un error. El usuario no estaba desbloqueado"
msgid "Error occurred. User was not unblocked"
msgstr "Se ha producido un error. El usuario no estaba desbloqueado"
@@ -13161,14 +13272,17 @@ msgid "Error: %{error_message}"
msgstr "Error: %{error_message}"
msgid "Error: No AWS credentials were supplied"
-msgstr ""
+msgstr "Error: No se han proporcionado credenciales AWS"
msgid "Error: No AWS provision role found for user"
-msgstr ""
+msgstr "Error: No se ha encontrado el rol de provisión AWS para el usuario"
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -13212,10 +13326,10 @@ msgid "Errors:"
msgstr "Errores:"
msgid "Escalation Policies"
-msgstr ""
+msgstr "Políticas de escalado"
msgid "Escalation policies"
-msgstr ""
+msgstr "Políticas de escalado"
msgid "Escalation policies may not have more than %{rule_count} rules"
msgstr ""
@@ -13236,13 +13350,13 @@ msgid "EscalationPolicies|A user is required for adding an escalation policy."
msgstr ""
msgid "EscalationPolicies|Add an escalation policy"
-msgstr ""
+msgstr "Añadir una política de escalado"
msgid "EscalationPolicies|Add escalation policy"
-msgstr ""
+msgstr "Añadir política de escalado"
msgid "EscalationPolicies|Add policy"
-msgstr ""
+msgstr "Añadir política"
msgid "EscalationPolicies|Are you sure you want to delete the \"%{escalationPolicy}\" escalation policy? This action cannot be undone."
msgstr ""
@@ -13251,7 +13365,7 @@ msgid "EscalationPolicies|Create an escalation policy in GitLab"
msgstr ""
msgid "EscalationPolicies|Delete escalation policy"
-msgstr ""
+msgstr "Eliminar política de escalado"
msgid "EscalationPolicies|Edit escalation policy"
msgstr ""
@@ -13369,8 +13483,8 @@ msgstr "Cada dos semanas"
msgid "Every week"
msgid_plural "Every %d weeks"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Cada semana"
+msgstr[1] "Cada %d semanas"
msgid "Every week (%{weekday} at %{time})"
msgstr "Todas las semanas (%{weekday} a %{time})"
@@ -13424,10 +13538,10 @@ msgid "Except policy:"
msgstr "Extracto de la política:"
msgid "Exceptions"
-msgstr ""
+msgstr "Excepciones"
msgid "Excess storage"
-msgstr ""
+msgstr "Exceso de almacenamiento"
msgid "Excluding merge commits. Limited to %{limit} commits."
msgstr ""
@@ -13484,7 +13598,7 @@ msgid "Expand sidebar"
msgstr "Expandir barra lateral"
msgid "Expected documents: %{expected_documents}"
-msgstr ""
+msgstr "Documentos esperados: %{expected_documents}"
msgid "Experienced"
msgstr "Experiencia"
@@ -13499,7 +13613,7 @@ msgid "Expiration date"
msgstr "Fecha de vencimiento"
msgid "Expiration date (optional)"
-msgstr ""
+msgstr "Fecha de vencimiento (opcional)"
msgid "Expired"
msgstr "Caducó"
@@ -13829,7 +13943,7 @@ msgid "Failed to reset key. Please try again."
msgstr "Se ha producido un error al restablecer la clave. Por favor, inténtalo de nuevo."
msgid "Failed to retrieve page"
-msgstr ""
+msgstr "Se ha producido un error al recuperar la página"
msgid "Failed to save merge conflicts resolutions. Please try again!"
msgstr "Se ha producido un error al guardar las resoluciones de los conflictos producidos durante el merge. ¡Por favor, inténtelo de nuevo!"
@@ -13898,13 +14012,13 @@ msgid "Faster releases. Better code. Less pain."
msgstr "Lanzamientos más rápidos. Mejor código. Menos dolor."
msgid "Favicon"
-msgstr ""
+msgstr "Favicon"
msgid "Favicon was successfully removed."
msgstr "Se ha eliminado correctamente el Favicon."
msgid "Favicon will be removed. Are you sure?"
-msgstr ""
+msgstr "Se eliminará el favicon. ¿Seguro que quieres hacerlo?"
msgid "Feature Flags"
msgstr "Feature Flags"
@@ -14008,7 +14122,7 @@ msgid "FeatureFlags|Feature Flags"
msgstr "Feature Flags"
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
-msgstr "Se a a eliminar la Feature Flag%{name}. ¿Está seguro de que desea continuar?"
+msgstr "Se va a eliminar la Feature Flag%{name}. ¿Está seguro de que desea continuar?"
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
@@ -14059,7 +14173,7 @@ msgid "FeatureFlags|New feature flag"
msgstr ""
msgid "FeatureFlags|No user list selected"
-msgstr ""
+msgstr "No se ha seleccionado ninguna lista de usuarios"
msgid "FeatureFlags|Percent of users"
msgstr ""
@@ -14229,7 +14343,7 @@ msgid "Filter by Git revision"
msgstr "Filtrar por revisión de Git"
msgid "Filter by issues that are currently closed."
-msgstr "Filtrar por icincidencias que están actualmente cerradas."
+msgstr "Filtrar por incidencias que están actualmente cerradas."
msgid "Filter by issues that are currently opened."
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr "Forks"
msgid "Format: %{dateFormat}"
msgstr "Formato: %{dateFormat}"
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr "Se han encontrado errores en su archivo %{gitlab_ci_yml}:"
@@ -14583,7 +14700,7 @@ msgid "From merge request merge until deploy to production"
msgstr "Desde la integración de la solicitud de fusión hasta el despliegue a producción"
msgid "Full"
-msgstr ""
+msgstr "Completo"
msgid "Full name"
msgstr "Nombre completo"
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr "Filtrar por estado"
msgid "Geo|Geo Status"
msgstr "Estado de Geo"
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14805,9 +14925,9 @@ msgid "Geo|Last time verified"
msgstr "Verficado por última vez"
msgid "Geo|Learn more about Geo"
-msgstr ""
+msgstr "Más información acerca de Geo"
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr "El nombre del nodo no puede estar en blanco"
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr "El nombre del nodo debe tener entre 1 y 255 caracteres"
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr "Sin sincronizar aún"
@@ -14862,7 +14979,7 @@ msgid "Geo|Project"
msgstr "Proyecto"
msgid "Geo|Project (ID: %{project_id}) no longer exists on the primary. It is safe to remove this entry, as this will not remove any data on disk."
-msgstr "El proyecto Geo|(ID: %{project_id}) ya no existe en el nodo primario. Es seguro eliminar esta entrada, esta acción no eliminará ningún dato del disco."
+msgstr "El proyecto (ID: %{project_id}) ya no existe en el nodo primario. Es seguro eliminar esta entrada, esta acción no eliminará ningún dato del disco."
msgid "Geo|Projects in certain groups"
msgstr "Proyectos en determinados grupos"
@@ -14885,19 +15002,16 @@ msgstr "Eliminar entrada"
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr "Eliminar entrada de la base de datos de seguimiento"
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr "Volver a comprobar todo"
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr "Estado"
@@ -14978,11 +15095,11 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
-msgstr "La base de datos está %{db_lag} detrás del nodo primario."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
+msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
-msgstr "El nodo está %{minutes_behind} detrás del nodo primario."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
+msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
msgstr "No hay %{replicable_type} para mostrar"
@@ -15033,7 +15150,7 @@ msgid "Geo|Updated %{timeAgo}"
msgstr ""
msgid "Geo|Verification"
-msgstr ""
+msgstr "Verificación"
msgid "Geo|Verification failed - %{error}"
msgstr "Se ha producido un error durante la verificación - %{error}"
@@ -15042,7 +15159,7 @@ msgid "Geo|Verification information"
msgstr ""
msgid "Geo|Verification status"
-msgstr ""
+msgstr "Estado de la verificación"
msgid "Geo|Verified"
msgstr ""
@@ -15053,7 +15170,7 @@ msgstr "Esperando por el programador"
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15093,11 +15210,14 @@ msgid "Getting started with releases"
msgstr "Primeros pasos con las versiones"
msgid "Git"
-msgstr ""
+msgstr "Git"
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr "Git LFS no está habilitado en este servidor de GitLab, póngase en contacto con su administrador."
@@ -15152,9 +15272,6 @@ msgstr "Solicitud de cuenta de GitLab"
msgid "GitLab Billing Team."
msgstr "Equipo de facturación de GitLab."
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr "Importar desde GitLab"
@@ -15303,7 +15420,7 @@ msgid "GitLabPages|Remove"
msgstr "Eliminar"
msgid "GitLabPages|Remove pages"
-msgstr "GitLabPages|Eliminar páginas"
+msgstr "Eliminar páginas"
msgid "GitLabPages|Removing pages will prevent them from being exposed to the outside world."
msgstr "Al eliminar páginas evitará que estén expuestas al mundo exterior."
@@ -15404,6 +15521,9 @@ msgstr "Acceso concedido %{time_ago}"
msgid "Given epic is already related to this epic."
msgstr "La tarea épica indicada ya está relacionada con esta tarea épica."
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr "Accesos directos globales"
@@ -15423,7 +15543,7 @@ msgid "Go back (while searching for files)"
msgstr "Volver (mientras se buscan archivos)"
msgid "Go back to configuration"
-msgstr ""
+msgstr "Volver a la configuración"
msgid "Go full screen"
msgstr "Ir a pantalla completa"
@@ -15477,15 +15597,15 @@ msgid "Go to metrics"
msgstr "Ir a métricas"
msgid "Go to next page"
-msgstr ""
+msgstr "Ir a la página siguiente"
msgid "Go to parent"
msgstr "Ir al principal"
msgid "Go to previous page"
-msgstr ""
+msgstr "Ir a la página anterior"
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15825,7 +15945,7 @@ msgid "GroupRoadmap|Some of your epics might not be visible"
msgstr ""
msgid "GroupRoadmap|Something went wrong while fetching epics"
-msgstr " Se ha producido un error al obtener las tareas épicas"
+msgstr ""
msgid "GroupRoadmap|Something went wrong while fetching milestones"
msgstr ""
@@ -15836,6 +15956,12 @@ msgstr "Lo sentimos, no hay tareas épicas que coincidan con su búsqueda"
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr "La hoja de ruta muestra el progreso de sus tareas épicas a lo largo de una línea de tiempo"
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr "Para ver la hoja de ruta, agregue la fecha de inicio o la de vencimiento
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr "Para ampliar su búsqueda, cambie o elimine los filtros; desde %{startDate} a %{endDate}."
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15876,12 +16005,12 @@ msgid "GroupSAML|Could not create SAML group link: %{errors}."
msgstr ""
msgid "GroupSAML|Default membership role"
-msgstr ""
+msgstr "Rol de membresía predeterminado"
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -15972,7 +16101,7 @@ msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML ide
msgstr ""
msgid "GroupSAML|This will be set as the access level of users added to the group."
-msgstr ""
+msgstr "Esto se establecerá como el nivel de acceso de los usuarios añadidos al grupo."
msgid "GroupSAML|To be able to enable group-managed accounts, you first need to enable enforced SSO."
msgstr ""
@@ -16017,7 +16146,7 @@ msgid "GroupSettings|Auto DevOps pipeline was updated for the group"
msgstr "El pipeline Auto DevOps se actualizó para el grupo"
msgid "GroupSettings|Badges"
-msgstr "GroupSettings|Insignias"
+msgstr "Insignias"
msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
msgstr "Tenga cuidado. Cambiar el grupo principal puede tener %{side_effects_link_start}efectos secundarios no intencionados%{side_effects_link_end}."
@@ -16224,7 +16353,7 @@ msgid "GroupsNew|Contact an administrator to enable options for importing your g
msgstr ""
msgid "GroupsNew|Create group"
-msgstr ""
+msgstr "Crear grupo"
msgid "GroupsNew|Create new group"
msgstr ""
@@ -16239,13 +16368,13 @@ msgid "GroupsNew|Groups can also be nested by creating %{linkStart}subgroups%{li
msgstr ""
msgid "GroupsNew|Import group"
-msgstr ""
+msgstr "Importar grupo"
msgid "GroupsNew|Import groups from another instance of GitLab"
-msgstr ""
+msgstr "Importar grupos desde otra instancia de GitLab"
msgid "GroupsNew|My Awesome Group"
-msgstr ""
+msgstr "Mi impresionante grupo"
msgid "GroupsNew|Navigate to user settings to find your %{link_start}personal access token%{link_end}."
msgstr ""
@@ -16305,10 +16434,10 @@ msgid "Guideline"
msgstr "Guía"
msgid "HAR (HTTP Archive)"
-msgstr ""
+msgstr "HAR (archivo HTTP)"
msgid "HAR file path or URL"
-msgstr ""
+msgstr "Ruta del archivo HAR o URL"
msgid "HTTP Basic: Access denied\\nYou must use a personal access token with 'api' scope for Git over HTTP.\\nYou can generate one at %{profile_personal_access_tokens_url}"
msgstr "HTTP básico: Acceso denegado\\nDebe utilizar un token de acceso personal con alcance 'api' para Git a través de HTTP.\\nPuedes generar uno a %{profile_personal_access_tokens_url}"
@@ -16353,7 +16482,7 @@ msgid "Heading 4"
msgstr ""
msgid "Headings"
-msgstr ""
+msgstr "Encabezados"
msgid "Health"
msgstr "Salud"
@@ -16389,7 +16518,7 @@ msgid "Hello there"
msgstr "¡Hola!"
msgid "Hello, %{name}!"
-msgstr ""
+msgstr "¡Hola, %{name}!"
msgid "Hello, %{username}!"
msgstr "¡Hola, %{username}!"
@@ -16409,12 +16538,12 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
-msgstr "Ayuda a reducir el volumen de alertas (por ejemplo, si se crean demasiadas incidencias)"
-
msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
+msgstr ""
+
msgid "Helps reduce request volume for protected paths"
msgstr "Ayuda a reducir el volumen de solicitudes para rutas protegidas"
@@ -16425,7 +16554,7 @@ msgid "Hi %{username}!"
msgstr "Hola %{username}!"
msgid "Hide"
-msgstr ""
+msgstr "Ocultar"
msgid "Hide archived projects"
msgstr "Ocultar proyectos archivados"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16564,7 +16696,7 @@ msgid "I accept the %{terms_link}"
msgstr "Aceptar los %{terms_link}"
msgid "I accept the|Terms of Service and Privacy Policy"
-msgstr "Aceptar los términos de servicio y la política de privacidad"
+msgstr ""
msgid "I forgot my password"
msgstr "He olvidado mi contraseña"
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16762,7 +16894,7 @@ msgid "Image URL"
msgstr "URL de la imagen"
msgid "Image details"
-msgstr ""
+msgstr "Detalles de la imagen"
msgid "ImageDiffViewer|2-up"
msgstr "2-up"
@@ -16801,8 +16933,8 @@ msgstr[1] ""
msgid "Import %d repository"
msgid_plural "Import %d repositories"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Importar %d repositorio"
+msgstr[1] "Importar %d repositorios"
msgid "Import CSV"
msgstr "Importar CSV"
@@ -16971,6 +17103,9 @@ msgstr "En progreso"
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17338,7 +17473,7 @@ msgid "InProductMarketing|Used by more than 100,000 organizations from around th
msgstr ""
msgid "InProductMarketing|Very difficult"
-msgstr ""
+msgstr "Muy difícil"
msgid "InProductMarketing|Very easy"
msgstr ""
@@ -17359,58 +17494,58 @@ msgid "InProductMarketing|Working in GitLab = more efficient"
msgstr ""
msgid "InProductMarketing|YouTube"
-msgstr ""
+msgstr "YouTube"
msgid "InProductMarketing|Your teams can be more efficient"
-msgstr ""
+msgstr "Sus equipos pueden ser más eficientes"
msgid "InProductMarketing|comprehensive guide"
-msgstr ""
+msgstr "guía completa"
msgid "InProductMarketing|connect an external repository"
-msgstr ""
+msgstr "Conectar un repositorio externo"
msgid "InProductMarketing|create a project"
-msgstr ""
+msgstr "Crear un proyecto"
msgid "InProductMarketing|from Bitbucket"
-msgstr ""
+msgstr "Desde Bitbucket"
msgid "InProductMarketing|go to about.gitlab.com"
-msgstr ""
+msgstr "Ir a about.gitlab.com"
msgid "InProductMarketing|how easy it is to get started"
-msgstr ""
+msgstr "Qué fácil es empezar"
msgid "InProductMarketing|quick start guide"
-msgstr ""
+msgstr "Guía de inicio rápido"
msgid "InProductMarketing|repository mirroring"
-msgstr ""
+msgstr "Replicación del repositorio"
msgid "InProductMarketing|set up a repo"
-msgstr ""
+msgstr "Configurar un repositorio"
msgid "InProductMarketing|test and deploy"
-msgstr ""
+msgstr "probar y desplegar"
msgid "InProductMarketing|testing browser performance"
-msgstr ""
+msgstr "probar el rendimiento del navegador"
msgid "InProductMarketing|unsubscribe"
-msgstr ""
+msgstr "cancelar suscripción"
msgid "InProductMarketing|update your preferences"
-msgstr ""
+msgstr "actualizar sus preferencias"
msgid "InProductMarketing|using a CI/CD template"
-msgstr ""
+msgstr "utilizando una plantilla CI/CD"
msgid "InProductMarketing|you may %{unsubscribe_link} at any time."
msgstr ""
msgid "Inactive"
-msgstr ""
+msgstr "Inactivo"
msgid "Incident"
msgstr "Incidente"
@@ -17419,88 +17554,88 @@ msgid "Incident Management Limits"
msgstr "Límites de gestión de incidentes"
msgid "Incident template (optional)."
-msgstr ""
+msgstr "Plantilla de incidente (opcional)."
msgid "IncidentManagement|%{hours} hours, %{minutes} minutes remaining"
-msgstr ""
+msgstr "%{hours} horas, %{minutes} minutos restantes"
msgid "IncidentManagement|%{minutes} minutes remaining"
-msgstr ""
+msgstr "%{minutes} minutos restantes"
msgid "IncidentManagement|Achieved SLA"
-msgstr ""
+msgstr "SLA logrado"
msgid "IncidentManagement|All"
-msgstr ""
+msgstr "Todo"
msgid "IncidentManagement|All alerts promoted to incidents will automatically be displayed within the list. You can also create a new incident using the button below."
msgstr ""
msgid "IncidentManagement|Assignees"
-msgstr ""
+msgstr "Asignados"
msgid "IncidentManagement|Closed"
-msgstr ""
+msgstr "Cerrado"
msgid "IncidentManagement|Create incident"
-msgstr ""
+msgstr "Crear incidente"
msgid "IncidentManagement|Critical - S1"
-msgstr ""
+msgstr "Crítico - S1"
msgid "IncidentManagement|Date created"
-msgstr ""
+msgstr "Fecha de creación"
msgid "IncidentManagement|Display your incidents in a dedicated view"
-msgstr ""
+msgstr "Mostrar sus incidentes en una vista dedicada"
msgid "IncidentManagement|High - S2"
-msgstr ""
+msgstr "Alto - S2"
msgid "IncidentManagement|Incident"
-msgstr ""
+msgstr "Incidente"
msgid "IncidentManagement|Incidents"
-msgstr ""
+msgstr "Incidentes"
msgid "IncidentManagement|Low - S4"
-msgstr ""
+msgstr "Bajo - S4"
msgid "IncidentManagement|Medium - S3"
-msgstr ""
+msgstr "Medio - S3"
msgid "IncidentManagement|Missed SLA"
-msgstr ""
+msgstr "SLA omitido"
msgid "IncidentManagement|No incidents to display."
msgstr ""
msgid "IncidentManagement|Open"
-msgstr ""
+msgstr "Abierto"
msgid "IncidentManagement|Published"
-msgstr ""
+msgstr "Publicado"
msgid "IncidentManagement|Published to status page"
-msgstr ""
+msgstr "Publicado en la página de estado"
msgid "IncidentManagement|Severity"
-msgstr ""
+msgstr "Gravedad"
msgid "IncidentManagement|There are no closed incidents"
-msgstr ""
+msgstr "No hay incidentes cerrados"
msgid "IncidentManagement|There was an error displaying the incidents."
-msgstr ""
+msgstr "Se ha producido un error mostrando los incidentes."
msgid "IncidentManagement|Time to SLA"
-msgstr ""
+msgstr "Tiempo hasta el SLA"
msgid "IncidentManagement|Unassigned"
-msgstr ""
+msgstr "Sin asignar"
msgid "IncidentManagement|Unknown"
-msgstr ""
+msgstr "Desconocido"
msgid "IncidentManagement|Unpublished"
msgstr ""
@@ -17518,7 +17653,7 @@ msgid "IncidentSettings|Incident settings"
msgstr ""
msgid "IncidentSettings|Incidents"
-msgstr ""
+msgstr "Incidentes"
msgid "IncidentSettings|Introduce a countdown timer in incident issues to better track Service Level Agreements (SLAs). The timer starts automatically when the incident is created, and sets a time limit for resolving the incident. When activated, the time to SLA countdown appears on all new incidents."
msgstr ""
@@ -17635,22 +17770,22 @@ msgid "Incompatible project"
msgstr "Proyecto incompatible"
msgid "Incomplete"
-msgstr ""
+msgstr "Incompleto"
msgid "Increase"
-msgstr ""
+msgstr "Incrementar"
msgid "Indent"
msgstr "Indentar"
msgid "Index"
-msgstr ""
+msgstr "Ãndice"
msgid "Index all projects"
msgstr "Indexar todos los proyectos"
msgid "Index deletion is canceled"
-msgstr ""
+msgstr "Se ha cancelado la eliminación del índice"
msgid "Indicates whether this runner can pick jobs without tags"
msgstr "Indica si este ejecutor puede seleccionar trabajos sin etiquetas"
@@ -17659,16 +17794,16 @@ msgid "Inform users without uploaded SSH keys that they can't push over SSH unti
msgstr "Informa a los usuarios que no hayan cargado las claves SSH que no pueden hacer push sobre SSH hasta que se agregue una"
msgid "Infrastructure"
-msgstr ""
+msgstr "Infraestructura"
msgid "Infrastructure Registry"
-msgstr ""
+msgstr "Registro de infraestructura"
msgid "InfrastructureRegistry|Copy Terraform Command"
-msgstr ""
+msgstr "Copiar comando de Terraform"
msgid "InfrastructureRegistry|Copy Terraform Setup Command"
-msgstr ""
+msgstr "Copiar comando de configuración de Terraform"
msgid "InfrastructureRegistry|Copy and paste into your Terraform configuration, insert the variables, and run Terraform init:"
msgstr ""
@@ -17695,7 +17830,7 @@ msgid "InfrastructureRegistry|You have no Terraform modules in your project"
msgstr ""
msgid "Inherited"
-msgstr ""
+msgstr "Heredado"
msgid "Inherited:"
msgstr "Heredado:"
@@ -17707,13 +17842,13 @@ msgid "Input host keys manually"
msgstr "Introducir las claves del host manualmente"
msgid "Input the remote repository URL"
-msgstr ""
+msgstr "Introduzca la URL del repositorio remoto"
msgid "Insert"
-msgstr ""
+msgstr "Insertar"
msgid "Insert a %{rows}x%{cols} table."
-msgstr ""
+msgstr "Inserte una tabla de %{rows}x%{cols}"
msgid "Insert a code block"
msgstr "Insertar un bloque de código"
@@ -17730,6 +17865,12 @@ msgstr "Insertar una imagen"
msgid "Insert code"
msgstr "Insertar código"
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr "Insertar imagen"
@@ -17737,6 +17878,12 @@ msgid "Insert inline code"
msgstr "Insertar código en línea"
msgid "Insert link"
+msgstr "Insertar un enlace"
+
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
msgstr ""
msgid "Insert suggestion"
@@ -17811,13 +17958,13 @@ msgid "Integrations|%{integration} settings saved, but not active."
msgstr ""
msgid "Integrations|Active integrations"
-msgstr ""
+msgstr "Integraciones activas"
msgid "Integrations|Add an integration"
-msgstr ""
+msgstr "Añadir una integración"
msgid "Integrations|Add namespace"
-msgstr ""
+msgstr "Añadir espacio de nombres"
msgid "Integrations|Adding a namespace works only in browsers that allow cross‑site cookies. Use %{firefox_link_start}Firefox%{link_end}, %{chrome_link_start}Google Chrome%{link_end}, or enable cross‑site cookies in your browser, when adding a namespace."
msgstr ""
@@ -17828,9 +17975,12 @@ msgstr "Todos los detalles"
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
-msgid "Integrations|Browser limitations"
+msgid "Integrations|An error occurred while loading projects using custom settings."
msgstr ""
+msgid "Integrations|Browser limitations"
+msgstr "Limitaciones del navegador"
+
msgid "Integrations|Comment detail:"
msgstr "Detalles del comentario:"
@@ -17838,13 +17988,13 @@ msgid "Integrations|Comment settings:"
msgstr "Configuración de los comentarios:"
msgid "Integrations|Connection failed. Please check your settings."
-msgstr ""
+msgstr "Error de conexión. Por favor, compruebe su configuración."
msgid "Integrations|Connection successful."
-msgstr ""
+msgstr "Conexión exitosa."
msgid "Integrations|Create new issue in Jira"
-msgstr ""
+msgstr "Crear nueva incidencia en Jira"
msgid "Integrations|Default settings are inherited from the group level."
msgstr ""
@@ -17904,10 +18054,10 @@ msgid "Integrations|Namespaces are the GitLab groups and subgroups you link to t
msgstr ""
msgid "Integrations|No available namespaces."
-msgstr ""
+msgstr "No hay espacios de nombres disponibles."
msgid "Integrations|No linked namespaces"
-msgstr ""
+msgstr "No hay espacios de nombres vinculados"
msgid "Integrations|Note: this integration only works with accounts on GitLab.com (SaaS)."
msgstr ""
@@ -17931,7 +18081,7 @@ msgid "Integrations|Return to GitLab for Jira"
msgstr ""
msgid "Integrations|Save settings?"
-msgstr ""
+msgstr "¿Guardar configuración?"
msgid "Integrations|Saving will update the default settings for all projects that are not using custom settings."
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr "Estándar"
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18015,7 +18168,7 @@ msgid "Invalid Insights config file detected"
msgstr "Archivo de configuración de Insights no válido detectado"
msgid "Invalid OS"
-msgstr ""
+msgstr "SO no válido"
msgid "Invalid URL"
msgstr "URL no válida"
@@ -18051,7 +18204,7 @@ msgid "Invalid file."
msgstr "Archivo no válido."
msgid "Invalid hash"
-msgstr ""
+msgstr "Hash no válido"
msgid "Invalid import params"
msgstr "Parámetros de importación no válidos"
@@ -18063,16 +18216,16 @@ msgid "Invalid login or password"
msgstr "Nombre de usuario o contraseña no válidos"
msgid "Invalid period"
-msgstr ""
+msgstr "Período no válido"
msgid "Invalid pin code"
msgstr "Código PIN inválido."
msgid "Invalid pod_name"
-msgstr ""
+msgstr "Pod_name no válido"
msgid "Invalid policy type"
-msgstr ""
+msgstr "Tipo de política no válido"
msgid "Invalid query"
msgstr "Consulta no válida"
@@ -18102,31 +18255,31 @@ msgid "Invalid yaml"
msgstr "Yaml no válido"
msgid "Investigate vulnerability: %{title}"
-msgstr ""
+msgstr "Investigar vulnerabilidad: %{title}"
msgid "Invitation"
msgstr "Invitación"
msgid "Invitation declined"
-msgstr ""
+msgstr "Invitación rechazada"
msgid "Invite"
msgstr "Invitar"
msgid "Invite \"%{email}\" by email"
-msgstr ""
+msgstr "Invitar a \"%{email}\" por correo electrónico"
msgid "Invite \"%{trimmed}\" by email"
msgstr "Invitar a \"%{trimmed}\" por correo electrónico"
msgid "Invite Members"
-msgstr ""
+msgstr "Invitar miembros"
msgid "Invite a group"
-msgstr ""
+msgstr "Invitar a un grupo"
msgid "Invite email has already been taken"
-msgstr ""
+msgstr "El correo electrónico de invitación ya está en uso"
msgid "Invite group"
msgstr "Invitar al grupo"
@@ -18135,10 +18288,7 @@ msgid "Invite member"
msgstr "Invitar al miembro"
msgid "Invite members"
-msgstr ""
-
-msgid "Invite your team"
-msgstr ""
+msgstr "Invitar miembros"
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18189,7 +18339,7 @@ msgid "InviteMembersModal|Access expiration date (optional)"
msgstr ""
msgid "InviteMembersModal|Cancel"
-msgstr ""
+msgstr "Cancelar"
msgid "InviteMembersModal|Close invite team members"
msgstr ""
@@ -18198,7 +18348,7 @@ msgid "InviteMembersModal|Collaborate on open issues and merge requests"
msgstr ""
msgid "InviteMembersModal|Configure CI/CD"
-msgstr ""
+msgstr "Configurar CI/CD"
msgid "InviteMembersModal|Configure security features"
msgstr ""
@@ -18210,7 +18360,7 @@ msgid "InviteMembersModal|GitLab member or email address"
msgstr ""
msgid "InviteMembersModal|Invite"
-msgstr ""
+msgstr "Invitar"
msgid "InviteMembersModal|Invite a group"
msgstr ""
@@ -18222,7 +18372,7 @@ msgid "InviteMembersModal|Members were successfully added"
msgstr ""
msgid "InviteMembersModal|Other"
-msgstr ""
+msgstr "Otro"
msgid "InviteMembersModal|Search for a group to invite"
msgstr ""
@@ -18291,31 +18441,31 @@ msgid "InviteReminderEmail|%{inviter} is waiting for you to join the %{strong_st
msgstr ""
msgid "InviteReminderEmail|%{inviter}'s invitation to GitLab is pending"
-msgstr ""
+msgstr "%{inviter} la invitación a GitLab está pendiente"
msgid "InviteReminderEmail|Accept invitation"
-msgstr ""
+msgstr "Aceptar invitación"
msgid "InviteReminderEmail|Accept invitation: %{invite_url}"
-msgstr ""
+msgstr "Aceptar invitación: %{invite_url}"
msgid "InviteReminderEmail|Decline invitation"
-msgstr ""
+msgstr "Rechazar invitación"
msgid "InviteReminderEmail|Decline invitation: %{decline_url}"
-msgstr ""
+msgstr "Rechazar invitación: %{decline_url}"
msgid "InviteReminderEmail|Hey there %{wave_emoji}"
-msgstr ""
+msgstr "Hola %{wave_emoji}"
msgid "InviteReminderEmail|Hey there!"
-msgstr ""
+msgstr "¡Hola!"
msgid "InviteReminderEmail|In case you missed it..."
-msgstr ""
+msgstr "En caso de que se lo haya perdido..."
msgid "InviteReminderEmail|Invitation pending"
-msgstr ""
+msgstr "Invitación pendiente"
msgid "InviteReminderEmail|It's been %{invitation_age} days since %{inviter} invited you to join the %{strong_start}%{project_or_group_name}%{strong_end} %{project_or_group} as a %{role}. What would you like to do?"
msgstr ""
@@ -18348,10 +18498,10 @@ msgid "IrkerService|Send update messages to an irker server. Before you can use
msgstr ""
msgid "IrkerService|Server host (optional)"
-msgstr ""
+msgstr "Host del servidor (opcional)"
msgid "IrkerService|Server port (optional)"
-msgstr ""
+msgstr "Puerto del servidor (opcional)"
msgid "IrkerService|URI to add before each recipient."
msgstr ""
@@ -18597,7 +18747,7 @@ msgid "IssuesAnalytics|Avg/Month:"
msgstr "Promedio mensual:"
msgid "IssuesAnalytics|Issues opened"
-msgstr ""
+msgstr "Incidencias abiertas"
msgid "IssuesAnalytics|Issues opened per month"
msgstr ""
@@ -18642,10 +18792,10 @@ msgid "It's you"
msgstr "¡Es usted!"
msgid "Italic text"
-msgstr ""
+msgstr "Texto en cursiva"
msgid "Iteration"
-msgstr ""
+msgstr "Iteración"
msgid "Iteration changed to"
msgstr "Iteración cambiada a"
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -18684,7 +18837,7 @@ msgid "Iterations|Delete iteration cadence?"
msgstr ""
msgid "Iterations|Duration"
-msgstr ""
+msgstr "Duración"
msgid "Iterations|Edit cadence"
msgstr ""
@@ -18699,7 +18852,7 @@ msgid "Iterations|Error loading iteration cadences."
msgstr ""
msgid "Iterations|Future iterations"
-msgstr ""
+msgstr "Iteraciones futuras"
msgid "Iterations|Iteration cadences"
msgstr ""
@@ -18732,16 +18885,16 @@ msgid "Iterations|Save cadence"
msgstr ""
msgid "Iterations|Select duration"
-msgstr ""
+msgstr "Seleccionar la duración"
msgid "Iterations|Select number"
-msgstr ""
+msgstr "Seleccionar el número"
msgid "Iterations|Select start date"
-msgstr ""
+msgstr "Seleccionar la fecha de inicio"
msgid "Iterations|Start date"
-msgstr ""
+msgstr "Fecha de inicio"
msgid "Iterations|The duration for each iteration (in weeks)"
msgstr ""
@@ -18753,7 +18906,7 @@ msgid "Iterations|This will delete the cadence as well as all of the iterations
msgstr ""
msgid "Iterations|Title"
-msgstr ""
+msgstr "Título"
msgid "Iterations|Unable to find iteration."
msgstr ""
@@ -18768,13 +18921,13 @@ msgid "Iteration|cannot be more than 500 years in the future"
msgstr ""
msgid "I’m familiar with the basics of DevOps."
-msgstr ""
+msgstr "Estoy familiarizado con los conceptos básicos de DevOps."
msgid "I’m joining my team who’s already on GitLab"
-msgstr ""
+msgstr "Me estoy uniendo a mi equipo que ya está en GitLab"
msgid "I’m not familiar with the basics of DevOps."
-msgstr ""
+msgstr "No estoy familiarizado con los conceptos básicos de DevOps."
msgid "Jaeger URL"
msgstr "URL de Jaeger"
@@ -18786,31 +18939,31 @@ msgid "January"
msgstr "Enero"
msgid "Japanese language support using"
-msgstr ""
+msgstr "Soporte para japonés usando"
msgid "Jira Issues"
msgstr "Incidencias de Jira"
msgid "Jira display name"
-msgstr ""
+msgstr "Nombre para mostrar Jira"
msgid "Jira import is already running."
-msgstr ""
+msgstr "La importación de Jira ya se está ejecutando."
msgid "Jira integration not configured."
msgstr "Integración con Jira no configurada."
msgid "Jira project key is not configured."
-msgstr ""
+msgstr "La clave de proyecto Jira no está configurada."
msgid "Jira project: %{importProject}"
msgstr "Proyecto Jira: %{importProject}"
msgid "Jira service not configured."
-msgstr ""
+msgstr "El servicio de Jira no está configurado."
msgid "Jira user"
-msgstr ""
+msgstr "Usuario de Jira"
msgid "Jira users have been imported from the configured Jira instance. They can be mapped by selecting a GitLab user from the dropdown in the \"GitLab username\" column. When the form appears, the dropdown defaults to the user conducting the import."
msgstr ""
@@ -19104,10 +19257,10 @@ msgid "Jobs|Jobs are the building blocks of a GitLab CI/CD pipeline. Each job ha
msgstr ""
msgid "Jobs|No jobs to show"
-msgstr ""
+msgstr "No hay trabajos a mostrar"
msgid "Jobs|Use jobs to automate your tasks"
-msgstr ""
+msgstr "Utilice trabajos para automatizar sus tareas"
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
@@ -19287,7 +19440,7 @@ msgid "Ki"
msgstr ""
msgid "Kroki"
-msgstr ""
+msgstr "Kroki"
msgid "Kubernetes"
msgstr "Kubernetes"
@@ -19370,9 +19523,6 @@ msgstr "Etiqueta"
msgid "Label actions dropdown"
msgstr "Desplegable de acciones de las etiquetaa"
-msgid "Label lists show all issues with the selected label."
-msgstr "Las listas de etiquetas muestran todas las incidencias con las etiquetas seleccionadas."
-
msgid "Label priority"
msgstr ""
@@ -19389,7 +19539,7 @@ msgid "LabelSelect|%{firstLabelName} +%{remainingLabelCount} more"
msgstr "%{firstLabelName} +%{remainingLabelCount} más"
msgid "LabelSelect|%{labelsString}, and %{remainingLabelCount} more"
-msgstr "%{labelsString}} +%{remainingLabelCount} más"
+msgstr "%{labelsString} y %{remainingLabelCount} más"
msgid "LabelSelect|Labels"
msgstr "Etiquetas"
@@ -19495,9 +19645,6 @@ msgstr "Última respuesta por"
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr "Última comprobación de repositorio ejecutada"
-
msgid "Last seen"
msgstr "Visto por ùltima vez"
@@ -19516,6 +19663,9 @@ msgstr "Última sincronización correcta"
msgid "Last successful update"
msgstr "Última actualización con éxito"
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr "Verficado por última vez"
@@ -19577,10 +19727,10 @@ msgid "Learn GitLab|Trial only"
msgstr ""
msgid "Learn More"
-msgstr ""
+msgstr "Obtener mas información"
msgid "Learn More."
-msgstr ""
+msgstr "Obtener mas información."
msgid "Learn how to %{link_start}contribute to the built-in templates%{link_end}"
msgstr "Aprenda como contribuir %{link_start}a las plantillas integradas%{link_end}"
@@ -19616,7 +19766,7 @@ msgid "Learn more about custom project templates"
msgstr "Más información sobre las plantillas de proyecto personalizadas"
msgid "Learn more about deploying to AWS"
-msgstr ""
+msgstr "Obtener mas información sobre los despliegues en AWS"
msgid "Learn more about deploying to a cluster"
msgstr "Obtenga más información sobre los despliegues en un clúster"
@@ -19637,7 +19787,7 @@ msgid "Learn more in the|pipeline schedules documentation"
msgstr "documentación sobre la programación de pipelines"
msgid "Learn more."
-msgstr ""
+msgstr "Obtener mas información."
msgid "LearnGitLab|%{percentage}%{percentSymbol} completed"
msgstr ""
@@ -19817,7 +19967,7 @@ msgid "LicenseCompliance|Disallow merge request if detected and will instruct de
msgstr ""
msgid "LicenseCompliance|Learn more about %{linkStart}License Approvals%{linkEnd}"
-msgstr ""
+msgstr "Obtenga mas información sobre la %{linkStart}Aprobación de Licencias%{linkEnd}"
msgid "LicenseCompliance|License Approvals"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr "Limitar los espacios de nombres y los proyectos que se pueden indexar"
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
+msgstr ""
+
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -19972,7 +20125,7 @@ msgid "Line changes"
msgstr "Cambios de línea"
msgid "Link"
-msgstr ""
+msgstr "Enlace"
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -20116,7 +20269,7 @@ msgid "Lock %{issuableDisplayName}"
msgstr "Bloquear %{issuableDisplayName}"
msgid "Lock memberships to LDAP synchronization"
-msgstr ""
+msgstr "Bloquear membresías a la sincronización LDAP"
msgid "Lock not found"
msgstr "Bloqueo no encontrado"
@@ -20341,34 +20494,34 @@ msgid "Markdown"
msgstr "Markdown"
msgid "Markdown Help"
-msgstr ""
+msgstr "Ayuda de Markdown"
msgid "Markdown enabled."
-msgstr ""
+msgstr "Markdown habilitado."
msgid "Markdown is supported"
msgstr "Compatible con la sintaxis de Markdown"
msgid "Markdown supported."
-msgstr ""
+msgstr "Markdown soportado."
msgid "MarkdownEditor|Add a link (%{modifierKey}K)"
-msgstr ""
+msgstr "Añadir un enlace (%{modifierKey}K)"
msgid "MarkdownEditor|Add a link (%{modifier_key}K)"
-msgstr ""
+msgstr "Añadir un enlace (%{modifier_key}K)"
msgid "MarkdownEditor|Add bold text (%{modifierKey}B)"
-msgstr ""
+msgstr "Añadir texto en negrita (%{modifierKey}B)"
msgid "MarkdownEditor|Add bold text (%{modifier_key}B)"
-msgstr ""
+msgstr "Añadir texto en negrita (%{modifier_key}B)"
msgid "MarkdownEditor|Add italic text (%{modifierKey}I)"
-msgstr ""
+msgstr "Añadir texto en cursiva (%{modifierKey}I)"
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
-msgstr ""
+msgstr "Añadir texto en cursiva (%{modifier_key}I)"
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -20422,7 +20575,7 @@ msgid "MattermostService|Command trigger word"
msgstr ""
msgid "MattermostService|Fill in the word that works best for your team."
-msgstr "MattermostService|Escriba la palabra que mejor describa a su equipo."
+msgstr "Escriba la palabra que mejor describa a su equipo."
msgid "MattermostService|Request URL"
msgstr "URL de la petición"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr "Tamaño máximo de los artefactos (MB)"
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr "Tamaño máximo del archivo adjunto (MB)"
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr "Retraso máximo (minutos)"
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr "Longitud máxima del campo"
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr "Tiempo de espera máximo para el trabajo"
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr "Tamaño máximo para los archivos a subir al ejecutar un comando push (MB)"
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr "El tiempo máximo entre las actualizaciones que puede esperar una réplica cuando está programada para sincronizarse."
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20800,7 +20980,7 @@ msgid "Memory Usage"
msgstr "Uso de memoria"
msgid "Menu"
-msgstr ""
+msgstr "Menú"
msgid "Merge"
msgstr "Merge"
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr "Se ha producido un error al guardar el borrador del comentario."
@@ -20961,9 +21141,6 @@ msgstr "Resolver este hilo en una nueva incidencia"
msgid "MergeRequests|Saving the comment failed"
msgstr "Se ha producido un error al guardar el comentario"
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr "Tarea de squash cancelada: Ya hay otro squash en progreso."
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21205,7 +21382,7 @@ msgid "Metrics|Create your dashboard configuration file"
msgstr ""
msgid "Metrics|Current"
-msgstr ""
+msgstr "Actual"
msgid "Metrics|Dashboard files can be found in %{codeStart}.gitlab/dashboards%{codeEnd} at the root of this project."
msgstr ""
@@ -21261,7 +21438,7 @@ msgid "Metrics|Legend label (optional)"
msgstr "Leyenda de la etiqueta (opcional)"
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
-msgstr "Metrics|El link contiene una ventana de tiempo no válida, por favor compruébelo para poder ver el rango de tiempo solicitado."
+msgstr "El link contiene una ventana de tiempo no válida, por favor compruébelo para poder ver el rango de tiempo solicitado."
msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
msgstr ""
@@ -21312,7 +21489,7 @@ msgid "Metrics|Refresh dashboard"
msgstr "Actualizar el panel de control"
msgid "Metrics|Select a value"
-msgstr ""
+msgstr "Seleccione un valor"
msgid "Metrics|Set refresh rate"
msgstr ""
@@ -21381,7 +21558,7 @@ msgid "Metrics|Values"
msgstr "Nombre"
msgid "Metrics|View documentation"
-msgstr ""
+msgstr "Ver la documentación"
msgid "Metrics|View logs"
msgstr "Ver registros"
@@ -21417,7 +21594,7 @@ msgid "Metrics|e.g. req/sec"
msgstr "por ejemplo, req/seg."
msgid "Mi"
-msgstr ""
+msgstr "Mi"
msgid "Middleman project with Static Site Editor support"
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr "Las listas de hitos no están disponibles con tu licencia actual"
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr "Las listas de hitos muestran todas las incidencias desde el hito seleccionado."
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21569,7 +21743,7 @@ msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr "¿Promocionar %{milestoneTitle} para agrupar el hito?"
msgid "Milestones|Promote Milestone"
-msgstr "Hitos|Promover hito"
+msgstr ""
msgid "Milestones|Promote to Group Milestone"
msgstr ""
@@ -21722,7 +21896,7 @@ msgid "More information and share feedback"
msgstr "Más información y compartir comentarios"
msgid "More information is available|here"
-msgstr "Hay más información disponible | aquí"
+msgstr ""
msgid "More information."
msgstr ""
@@ -21826,11 +22000,11 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
-msgstr ""
+msgstr "Mi increíble grupo"
msgid "My company or team"
msgstr "Mi empresa o equipo"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr "Las políticas son una especificación de cómo se permite a los grupos de pods comunicarse con los extremos de red de los demás."
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr "Definición de la política"
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr "Algo salió mal, se ha producido un error al actualizar la política"
@@ -22180,7 +22333,7 @@ msgid "New"
msgstr "Nuevo"
msgid "New %{issueType}"
-msgstr ""
+msgstr "Nueva %{issueType}"
msgid "New Application"
msgstr "Nueva aplicación"
@@ -22256,9 +22409,6 @@ msgstr "Nueva rama"
msgid "New branch unavailable"
msgstr "Nueva rama no disponible"
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr "Se añadieron nuevos cambios. %{linkStart}Recargue la página para revisarlos%{linkEnd}"
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr "No se han encontrado application_settings"
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr "Noviembre"
msgid "Novice"
msgstr "Novato"
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr "Abierta"
msgid "Open Selection"
msgstr "Abrir la selección"
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23416,7 +23572,7 @@ msgid "Open sidebar"
msgstr "Abrir barra lateral"
msgid "Open: %{open}"
-msgstr ""
+msgstr "Abierto: %{open}"
msgid "OpenAPI"
msgstr ""
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr "La receta del paquete ya existe"
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr "El tipo de paquete debe ser Conan"
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25039,7 +25243,7 @@ msgid "Popularity"
msgstr ""
msgid "Port"
-msgstr ""
+msgstr "Puerto"
msgid "Postman collection"
msgstr ""
@@ -25060,13 +25264,13 @@ msgid "Preferences|Behavior"
msgstr "Comportamiento"
msgid "Preferences|Choose between fixed (max. 1280px) and fluid (%{percentage}) application layout."
-msgstr ""
+msgstr "Elija entre el diseño de aplicación fijo (máximo 1280px) y fluido (%{percentage})."
msgid "Preferences|Choose what content you want to see on a project’s overview page."
msgstr "Seleccione que contenido desea ver en la página de resumen de un proyecto."
msgid "Preferences|Choose what content you want to see on your homepage."
-msgstr ""
+msgstr "Seleccione qué contenido desea ver en su página de inicio."
msgid "Preferences|Configure how dates and times display for you."
msgstr ""
@@ -25090,7 +25294,7 @@ msgid "Preferences|Failed to save preferences."
msgstr ""
msgid "Preferences|For example: 30 minutes ago."
-msgstr ""
+msgstr "Por ejemplo: hace 30 minutos."
msgid "Preferences|Gitpod"
msgstr ""
@@ -25102,7 +25306,7 @@ msgid "Preferences|Instead of all the files changed, show only one file at a tim
msgstr ""
msgid "Preferences|Integrations"
-msgstr ""
+msgstr "Integraciones"
msgid "Preferences|Layout width"
msgstr "Ancho de diseño"
@@ -25126,7 +25330,7 @@ msgid "Preferences|Show whitespace changes in diffs"
msgstr ""
msgid "Preferences|Sourcegraph"
-msgstr ""
+msgstr "Sourcegraph"
msgid "Preferences|Surround text selection when typing quotes or brackets"
msgstr ""
@@ -25135,7 +25339,7 @@ msgid "Preferences|Syntax highlighting theme"
msgstr "Tema del resaltado de la sintaxis"
msgid "Preferences|Tab width"
-msgstr ""
+msgstr "Ancho de pestaña"
msgid "Preferences|This feature is experimental and translations are not complete yet"
msgstr "Esta función es experimental y las traducciones todavía no están completas"
@@ -25158,15 +25362,12 @@ msgstr "Presione %{key}-C para copiar"
msgid "Prev"
msgstr "Previo"
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
-msgstr ""
-
msgid "Prevent adding new members to project membership within this group"
msgstr "Impedir que se añadan nuevos miembros al proyecto dentro de este grupo"
+msgid "Prevent editing approval rules in projects and merge requests."
+msgstr ""
+
msgid "Prevent environment from auto-stopping"
msgstr ""
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25216,7 +25414,7 @@ msgid "Primary"
msgstr "Principal"
msgid "Primary Action"
-msgstr ""
+msgstr "Acción primaria"
msgid "Print codes"
msgstr ""
@@ -25330,7 +25528,7 @@ msgid "Profile image guideline"
msgstr ""
msgid "Profile page:"
-msgstr ""
+msgstr "Página del perfil:"
msgid "ProfileSession|on"
msgstr "Encendido"
@@ -25443,6 +25641,9 @@ msgstr "No mostrar información personal relacionada con su actividad en sus per
msgid "Profiles|Edit Profile"
msgstr "Editar perfil"
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25456,7 +25657,7 @@ msgid "Profiles|Expired key is not valid."
msgstr ""
msgid "Profiles|Expired:"
-msgstr ""
+msgstr "Expirado:"
msgid "Profiles|Expires at"
msgstr "Caduca el"
@@ -25489,7 +25690,7 @@ msgid "Profiles|Increase your account's security by enabling Two-Factor Authenti
msgstr "Aumente la seguridad de su cuenta al habilitar la autenticación de dos factores (2FA)"
msgid "Profiles|Invalid key."
-msgstr ""
+msgstr "Clave no válida."
msgid "Profiles|Invalid password"
msgstr "Contraseña no válida"
@@ -25591,7 +25792,7 @@ msgid "Profiles|This email will be displayed on your public profile"
msgstr "Esta dirección de correo electrónico se mostrará en su perfil público"
msgid "Profiles|This email will be used for web based operations, such as edits and merges. %{commit_email_link_start}Learn more%{commit_email_link_end}"
-msgstr "Perfiles | Este correo electrónico se usará para operaciones basadas en web, como ediciones y fusiones. %{commit_email_link_start}Aprende más%{commit_email_link_end}"
+msgstr "Este correo electrónico se utilizará para operaciones basadas en web, como ediciones y merges. %{commit_email_link_start}Obtenga más información%{commit_email_link_end}"
msgid "Profiles|This emoji and message will appear on your profile and throughout the interface."
msgstr "Este emoji y el mensaje se mostrarán en su perfil y en toda la interfaz."
@@ -25635,9 +25836,6 @@ msgstr "El nombre de usuario se cambió con éxito"
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr "El uso de emojis en los nombres parece divertido, pero por favor, intente establecer un mensaje de estado en su lugar"
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr "¿Cuál es su estado?"
@@ -25822,7 +26020,7 @@ msgid "Project info:"
msgstr ""
msgid "Project information"
-msgstr ""
+msgstr "Información del proyecto"
msgid "Project is required when cluster_type is :project"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr "Más información"
@@ -26829,9 +27027,6 @@ msgstr "Esta funcionalidad está bloqueada."
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr "Pruébelo gratis"
@@ -27333,6 +27528,12 @@ msgstr "Lea más acerca de las incidencias relacionadas"
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr "Reduce la visibilidad del proyecto"
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr "Solicitudes de fusión relacionadas"
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr "Relacionado con"
@@ -27653,7 +27860,7 @@ msgid "Remove deploy key"
msgstr ""
msgid "Remove description history"
-msgstr ""
+msgstr "Eliminar el historial de descripciones"
msgid "Remove due date"
msgstr "Eliminar la fecha de vencimiento"
@@ -27854,7 +28061,7 @@ msgid "Reopen"
msgstr "Volver a abrir"
msgid "Reopen %{issueType}"
-msgstr ""
+msgstr "Reabrir %{issueType}"
msgid "Reopen epic"
msgstr "Reabrir la tarea épica"
@@ -28029,6 +28236,9 @@ msgstr "Se ha producido un error al cargar los resultados de la prueba"
msgid "Reports|Test summary results are being parsed"
msgstr "Se están analizando los resultados de la prueba"
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr "Vulnerabilidad"
@@ -28286,7 +28496,7 @@ msgid "Requires your primary GitLab email address."
msgstr ""
msgid "Resend"
-msgstr ""
+msgstr "Volver a enviar"
msgid "Resend Request"
msgstr ""
@@ -28325,7 +28535,7 @@ msgid "Reset link will be generated and sent to the user. %{break} User will be
msgstr ""
msgid "Reset password"
-msgstr ""
+msgstr "Restablecer contraseña"
msgid "Reset registration token"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr "Ver aplicación"
msgid "Review App|View latest app"
msgstr "Ver la última aplicación"
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr "Revisión solicitada por %{name}"
@@ -28502,8 +28715,8 @@ msgstr ""
msgid "Reviewer"
msgid_plural "%d Reviewers"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Revisor"
+msgstr[1] "%d Revisores"
msgid "Reviewer(s)"
msgstr ""
@@ -28530,7 +28743,7 @@ msgid "Revoked personal access token %{personal_access_token_name}!"
msgstr "Se ha revocado el token de acceso personal %{personal_access_token_name}!"
msgid "Revoked project access token %{project_access_token_name}!"
-msgstr ""
+msgstr "¡Token de acceso al proyecto revocado %{project_access_token_name}!"
msgid "RightSidebar|Copy email address"
msgstr ""
@@ -28557,7 +28770,7 @@ msgid "Rollback"
msgstr "Restaurar"
msgid "Ruby"
-msgstr ""
+msgstr "Ruby"
msgid "Rule name is already taken."
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,14 +29024,17 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
msgid "Runners|You have used %{quotaUsed} out of %{quotaLimit} of your shared Runners pipeline minutes."
-msgstr ""
+msgstr "Ha utilizado %{quotaUsed} de %{quotaLimit} de sus minutos de ejecución de pipelines con Runners compartidos."
msgid "Runners|group"
-msgstr ""
+msgstr "grupo"
msgid "Runners|instance"
msgstr ""
@@ -28851,7 +29070,7 @@ msgid "Runs jobs from assigned projects."
msgstr ""
msgid "SAML"
-msgstr ""
+msgstr "SAML"
msgid "SAML SSO"
msgstr "SAML SSO"
@@ -29058,7 +29277,7 @@ msgid "Search"
msgstr "Buscar"
msgid "Search GitLab"
-msgstr ""
+msgstr "Buscar en GitLab"
msgid "Search Jira issues"
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] "Resultados de la wiki"
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29287,7 +29503,7 @@ msgid "Secondary"
msgstr "Secundario"
msgid "Secondary email:"
-msgstr ""
+msgstr "Correo secundario:"
msgid "Seconds"
msgstr "Segundos"
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr "Comentario editado en '%{vulnerabilityName}'"
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr "Eliminar proyecto del panel de control"
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -29956,7 +30238,7 @@ msgid "Select status"
msgstr "Seleccionar estado"
msgid "Select strategy activation method"
-msgstr ""
+msgstr "Seleccionar el método de activación de estrategia"
msgid "Select subgroup"
msgstr ""
@@ -30031,7 +30313,7 @@ msgid "SelfMonitoring|Self monitoring project successfully deleted."
msgstr ""
msgid "Send"
-msgstr ""
+msgstr "Enviar"
msgid "Send a single email notification to Owners and Maintainers for new alerts."
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr "Establece la iteración a %{iteration_reference}."
msgid "Set the milestone to %{milestone_reference}."
msgstr "Establecer el hito a %{milestone_reference}."
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr "Establecer el peso"
msgid "Set weight to %{weight}."
msgstr "Establecer el peso a %{weight}."
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30439,7 +30721,7 @@ msgid "Sets weight to %{weight}."
msgstr "Establecer el peso a %{weight}."
msgid "Setting"
-msgstr ""
+msgstr "Configuración"
msgid "Setting enforced"
msgstr ""
@@ -30526,7 +30808,7 @@ msgid "Show all activity"
msgstr "Mostrar toda la actividad"
msgid "Show all issues."
-msgstr ""
+msgstr "Mostrar todas las incidencias."
msgid "Show all test cases."
msgstr ""
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr "Mostrar la última versión"
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30698,7 +30977,7 @@ msgid "Sign in via 2FA code"
msgstr "Inicie sesión mediante un código 2FA"
msgid "Sign in with"
-msgstr ""
+msgstr "Iniciar sesión con"
msgid "Sign in with Single Sign-On"
msgstr "Inicie sesión mediante inicio de sesión único"
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr "Tamaño"
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr "Límite de tamaño por repositorio (MB)"
@@ -30827,7 +31109,7 @@ msgid "SlackService|3. Select the %{strong_open}Active%{strong_close} checkbox,
msgstr ""
msgid "SlackService|Fill in the word that works best for your team."
-msgstr ""
+msgstr "Escriba la palabra que mejor describa a su equipo."
msgid "SlackService|See list of available commands in Slack after setting up this service, by entering"
msgstr "Vea la lista de comandos disponibles en Slack después de configurar este servicio, introduciendo"
@@ -31147,6 +31429,15 @@ msgstr "Dirección de ordenación: Descendente"
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr "Fecha de creación"
@@ -31448,7 +31739,7 @@ msgid "Start Date"
msgstr ""
msgid "Start Time"
-msgstr ""
+msgstr "Hora de inicio"
msgid "Start Web Terminal"
msgstr "Iniciar Terminal web"
@@ -31721,7 +32012,7 @@ msgid "StatusPage|To publish incidents to an external status page, GitLab stores
msgstr ""
msgid "StatusPage|configuration documentation"
-msgstr ""
+msgstr "Documentación de configuración"
msgid "StatusPage|your status page frontend."
msgstr ""
@@ -31760,7 +32051,7 @@ msgid "Storage"
msgstr "Almacenamiento"
msgid "Storage nodes for new repositories"
-msgstr ""
+msgstr "Nodos de almacenamiento para los nuevos repositorios"
msgid "Storage:"
msgstr "Almacenamiento:"
@@ -31961,7 +32252,7 @@ msgid "SubscriptionTable|Trial"
msgstr "Prueba"
msgid "SubscriptionTable|Trial end date"
-msgstr "Tabla de suscripción | Fecha de finalización de prueba"
+msgstr "Fecha de finalización del periodo de prueba"
msgid "SubscriptionTable|Trial start date"
msgstr "Fecha de inicio de la versión de prueba"
@@ -31997,7 +32288,7 @@ msgid "Successfully approved"
msgstr "Aprobado con éxito"
msgid "Successfully banned"
-msgstr ""
+msgstr "Bloqueado con éxito"
msgid "Successfully blocked"
msgstr "Bloqueado con éxito"
@@ -32024,7 +32315,7 @@ msgid "Successfully synced %{synced_timeago}."
msgstr ""
msgid "Successfully unbanned"
-msgstr ""
+msgstr "Desbloqueado con éxito"
msgid "Successfully unblocked"
msgstr "Desbloqueado con éxito"
@@ -32405,7 +32696,7 @@ msgid "Tag this commit."
msgstr "Etiquetar este commit."
msgid "Tag:"
-msgstr ""
+msgstr "Etiqueta:"
msgid "Tagged this commit to %{tag_name} with \"%{message}\"."
msgstr "Se etiquetó a este commit a %{tag_name} con \"%{message}\"."
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32812,7 +33112,7 @@ msgid "TestReports|No test cases were found in the test report."
msgstr ""
msgid "TestReports|Tests"
-msgstr "TestReportes|Pruebas"
+msgstr "Pruebas"
msgid "TestReports|There are no test cases to display."
msgstr "No hay conjuntos de pruebas para mostrar."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -32934,7 +33234,7 @@ msgid "The application will be used where the client secret can be kept confiden
msgstr ""
msgid "The associated issue #%{issueId} has been closed as the error is now resolved."
-msgstr ""
+msgstr "Se ha cerrado la incidencia asociada #%{issueId} ya que se ha resuelto el error."
msgid "The branch for this project has no active pipeline configuration."
msgstr "La rama para este proyecto no tiene una configuración de un pipeline activa."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr "Los conflictos en el merge para este merge request no se pueden resolver a través de GitLab. Por favor, intente resolverlos localmente."
@@ -33200,7 +33500,7 @@ msgid "The number of merge requests merged by month."
msgstr ""
msgid "The number of times an upload record could not find its file"
-msgstr ""
+msgstr "El numero de veces que un registro de subida no pudo encontrar ese archivo"
msgid "The page could not be displayed because it timed out."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr "El proceso de actualización finalizará después de %{number_of_minutes} minutos. Para repositorios grandes, utilice una combinación de clone y push."
@@ -33368,7 +33671,7 @@ msgid "There are merge conflicts"
msgstr ""
msgid "There are no %{replicableTypeName} to show"
-msgstr ""
+msgstr "No hay %{replicableTypeName} para mostrar"
msgid "There are no GPG keys associated with this account."
msgstr "No hay claves GPG asociadas con esta cuenta."
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33545,7 +33857,7 @@ msgid "There was a problem updating the keep latest artifacts setting."
msgstr ""
msgid "There was an error %{message} todo."
-msgstr "Se ha producido un un error %{message} en la lista de tareas pendientes."
+msgstr "Se ha producido un error %{message} en la lista de tareas pendientes."
msgid "There was an error adding a To Do."
msgstr "Se ha producido un error al añadir la tarea a la lista de tareas pendientes."
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr "Este campo es obligatorio."
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr "Este grupo"
@@ -33985,6 +34291,9 @@ msgstr "Esta es su sesión actual"
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -34592,10 +34901,10 @@ msgid "Timeago|right now"
msgstr "justo ahora"
msgid "Timeline|Turn timeline view off"
-msgstr ""
+msgstr "Desactivar la vista de línea de tiempo"
msgid "Timeline|Turn timeline view on"
-msgstr ""
+msgstr "Activar la vista de la línea de tiempo"
msgid "Timeout"
msgstr "Tiempo de espera"
@@ -34613,7 +34922,7 @@ msgid "Timeout for the fastest Gitaly operations (in seconds)."
msgstr ""
msgid "Timezone"
-msgstr ""
+msgstr "Zona horaria"
msgid "Time|hr"
msgid_plural "Time|hrs"
@@ -34656,13 +34965,13 @@ msgid "To GitLab"
msgstr "A GitLab"
msgid "To accept this invitation, create an account or sign in."
-msgstr ""
+msgstr "Para aceptar esta invitación, cree una cuenta o inicie sesión."
msgid "To accept this invitation, sign in or create an account."
-msgstr ""
+msgstr "Para aceptar esta invitación, inicie sesión o cree una cuenta."
msgid "To accept this invitation, sign in."
-msgstr ""
+msgstr "Para aceptar esta invitación, inicie sesión."
msgid "To access this domain create a new DNS record"
msgstr "Para acceder a este dominio, cree un nuevo registro DNS"
@@ -34920,7 +35229,7 @@ msgid "TopNav|Go back"
msgstr ""
msgid "Topics (optional)"
-msgstr ""
+msgstr "Temas (opcional)"
msgid "Total"
msgstr "Total"
@@ -34941,13 +35250,13 @@ msgid "Total issues"
msgstr "Total de incidencias"
msgid "Total memory (GB)"
-msgstr ""
+msgstr "Memoria total (GB)"
msgid "Total test time for all commits/merges"
msgstr "Tiempo total de pruebas para todos los cambios o integraciones"
msgid "Total users"
-msgstr ""
+msgstr "Total de usuarios"
msgid "Total weight"
msgstr "Peso total"
@@ -34956,7 +35265,7 @@ msgid "Total: %{total}"
msgstr "Total: %{total}"
msgid "TotalMilestonesIndicator|1000+"
-msgstr ""
+msgstr "1000+"
msgid "TotalRefCountIndicator|1000+"
msgstr ""
@@ -34983,19 +35292,19 @@ msgid "Track your GitLab projects with GitLab for Slack."
msgstr "Haga el seguimiento de sus proyectos de GitLab con GitLab para Slack."
msgid "Transfer"
-msgstr ""
+msgstr "Transferir"
msgid "Transfer ownership"
-msgstr ""
+msgstr "Transferir la propiedad"
msgid "Transfer project"
msgstr "Transferir proyecto"
msgid "Transfer your project into another namespace. %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "Transfiere su proyecto a otro espacio de nombres. %{link_start}Obtenga más información.%{link_end}"
msgid "TransferGroup|Cannot transfer group to one of its subgroup."
-msgstr ""
+msgstr "No se puede transferir el grupo a uno de sus subgrupos."
msgid "TransferGroup|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
msgstr "No se puede actualizar la ruta porque hay proyectos bajo este grupo que contienen imágenes de Docker en su registro de contenedores. Por favor, elimine primero las imágenes de sus proyectos y vuelva a intentarlo."
@@ -35030,14 +35339,20 @@ msgstr "Por favor, seleccione un nuevo espacio de nombre para su proyecto."
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr "No se puede transferir el proyecto, porque hay etiquetas definidas en el registro de contenedores"
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr "Ya existe un proyecto con el mismo nombre o ruta en el espacio de nombres de destino"
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr "El espacio de nombres raíz no se puede actualizar si el proyecto tiene paquetes NPM"
-msgid "TransferProject|Transfer failed, please contact an admin."
-msgstr "Se ha producido un error durante el proceso de transferencia, por favor, contacte con un administrador."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
+msgstr ""
msgid "Tree view"
msgstr "Vista de árbol"
@@ -35051,7 +35366,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "Trials|Compare all plans"
-msgstr ""
+msgstr "Comparar todos los planes"
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
@@ -35060,13 +35375,13 @@ msgid "Trials|Go back to GitLab"
msgstr "Volver a GitLab"
msgid "Trials|Hey there"
-msgstr ""
+msgstr "Hola"
msgid "Trials|Skip Trial"
-msgstr ""
+msgstr "Saltar periodo de prueba"
msgid "Trials|Upgrade %{groupName} to %{planName}"
-msgstr ""
+msgstr "Actualizar %{groupName} a %{planName}"
msgid "Trials|You can always resume this process by selecting your avatar and choosing 'Start an Ultimate trial'"
msgstr ""
@@ -35078,10 +35393,10 @@ msgid "Trials|You won't get a free trial right now but you can always resume thi
msgstr ""
msgid "Trials|Your trial ends on %{boldStart}%{trialEndDate}%{boldEnd}. We hope you’re enjoying the features of GitLab %{planName}. To keep those features after your trial ends, you’ll need to buy a subscription. (You can also choose GitLab Premium if it meets your needs.)"
-msgstr ""
+msgstr "Su prueba termina el %{boldStart}%{trialEndDate}%{boldEnd}. Esperamos que estés disfrutando de las características de GitLab %{planName}. Para mantener esas funciones después de que termine tu prueba, tendrás que comprar una suscripción. (También puedes elegir GitLab Premium si se ajusta a tus necesidades)"
msgid "Trial|Company name"
-msgstr ""
+msgstr "Nombre de la empresa"
msgid "Trial|Continue"
msgstr ""
@@ -35090,22 +35405,22 @@ msgid "Trial|Continue using the basic features of GitLab for free."
msgstr ""
msgid "Trial|Country"
-msgstr ""
+msgstr "País"
msgid "Trial|Dismiss"
-msgstr ""
+msgstr "Descartar"
msgid "Trial|First name"
msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
-msgstr ""
+msgstr "GitLab Ultimate (opcional)"
msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
+msgstr "Hola%{salutation}, tu prueba de GitLab Ultimate dura 30 días, pero puedes mantener tu cuenta gratuita de GitLab para siempre. Solo necesitamos información adicional sobre %{company} para activar tu prueba."
msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
+msgstr "¿Cuántos empleados utilizarán Gitlab?"
msgid "Trial|How many users will be evaluating the trial?"
msgstr ""
@@ -35114,7 +35429,7 @@ msgid "Trial|Last name"
msgstr ""
msgid "Trial|Number of employees"
-msgstr ""
+msgstr "Número de empleados"
msgid "Trial|Please select a country"
msgstr ""
@@ -35123,10 +35438,10 @@ msgid "Trial|Successful trial activation image"
msgstr ""
msgid "Trial|Telephone number"
-msgstr ""
+msgstr "Número de teléfono"
msgid "Trial|Upgrade to Ultimate to keep using GitLab with advanced features."
-msgstr ""
+msgstr "Actualicese a Ultimate para seguir utilizando GitLab con funciones avanzadas."
msgid "Trial|We will activate your trial on your group after you complete this step. After 30 days, you can:"
msgstr ""
@@ -35135,7 +35450,7 @@ msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your
msgstr ""
msgid "Trial|your company"
-msgstr ""
+msgstr "su empresa"
msgid "Trigger"
msgstr "Disparador"
@@ -35186,7 +35501,7 @@ msgid "Troubleshoot and monitor your application with tracing"
msgstr "Solucione problemas y supervise su aplicación con el seguimiento"
msgid "Trusted"
-msgstr ""
+msgstr "Confiable"
msgid "Try again"
msgstr "Inténtelo de nuevo"
@@ -35201,19 +35516,19 @@ msgid "Try changing or removing filters."
msgstr "Intente cambiar o quitar los filtros."
msgid "Try grouping with different labels"
-msgstr ""
+msgstr "Intente agrupar con diferentes etiquetas"
msgid "Try to fork again"
msgstr "Intentar realizar el fork de nuevo"
msgid "Try to keep the first line under 52 characters and the others under 72."
-msgstr ""
+msgstr "Intente que la primera línea no supere los 52 caracteres y las demás no superen los 72."
msgid "Try using a different search term to find the file you are looking for."
msgstr "Intente usar un término de búsqueda diferente para encontrar el archivo que está buscando."
msgid "Trying to communicate with your device. Plug it in (if needed) and press the button on the device now."
-msgstr ""
+msgstr "Intente comunicarse con tu dispositivo. Enchúfelo (si es necesario) y pulse el botón del dispositivo ahora."
msgid "Trying to communicate with your device. Plug it in (if you haven't already) and press the button on the device now."
msgstr "Intentando comunicarse con su dispositivo. Conéctelo (si aún no lo ha hecho) y presione el botón en el dispositivo ahora."
@@ -35222,13 +35537,13 @@ msgid "Tuesday"
msgstr "Martes"
msgid "Tuning settings"
-msgstr ""
+msgstr "Ajustes"
msgid "Turn off"
-msgstr ""
+msgstr "Desactivar"
msgid "Turn on"
-msgstr ""
+msgstr "Activar"
msgid "Twitter"
msgstr "Twitter"
@@ -35255,19 +35570,19 @@ msgid "Two-factor authentication"
msgstr "Autenticación de doble factor"
msgid "Two-factor authentication disabled"
-msgstr ""
+msgstr "Autenticación de doble factor desactivada"
msgid "Two-factor authentication has been disabled for this user"
-msgstr ""
+msgstr "La autenticación de doble factor ha sido desactivada para este usuario"
msgid "Two-factor authentication has been disabled for your GitLab account."
-msgstr ""
+msgstr "La autenticación de doble factor ha sido deshabilitada para su cuenta de GitLab."
msgid "Two-factor authentication has been disabled successfully!"
-msgstr ""
+msgstr "La autenticación de doble factor se ha desactivado correctamente"
msgid "Two-factor authentication is not enabled for this user"
-msgstr ""
+msgstr "La autenticación de doble factor no está habilitada para este usuario"
msgid "Two-factor grace period"
msgstr ""
@@ -35288,10 +35603,10 @@ msgid "URL"
msgstr "URL"
msgid "URL cannot be blank"
-msgstr ""
+msgstr "La URL no puede estar en blanco"
msgid "URL is invalid"
-msgstr ""
+msgstr "La URL no es válida"
msgid "URL is required"
msgstr "Se requiere la URL"
@@ -35330,10 +35645,10 @@ msgid "USER %{user_name} WILL BE REMOVED! Are you sure?"
msgstr ""
msgid "USER %{user} WILL BE REMOVED! Are you sure?"
-msgstr ""
+msgstr "¡EL USUARIO %{user} SERà ELIMINADO! ¿Está seguro?"
msgid "USER WILL BE BLOCKED! Are you sure?"
-msgstr ""
+msgstr "¡EL USUARIO SERà BLOQUEADO! ¿Está usted seguro?"
msgid "UTC"
msgstr "UTC"
@@ -35366,7 +35681,7 @@ msgid "Unable to convert Kubernetes logs encoding to UTF-8"
msgstr "No se puede convertir la codificación de registros de Kubernetes a UTF-8"
msgid "Unable to create link to vulnerability"
-msgstr ""
+msgstr "No se puede crear un enlace a la vulnerabilidad"
msgid "Unable to fetch branch list for this project."
msgstr ""
@@ -35387,7 +35702,7 @@ msgid "Unable to generate new instance ID"
msgstr "No se puede generar un nuevo ID de instancia"
msgid "Unable to load commits. Try again later."
-msgstr ""
+msgstr "Se ha producido un error al cargar los commits. Por favor, inténtelo de nuevo más tarde."
msgid "Unable to load file contents. Try again later."
msgstr "No se puede cargar el contenido del archivo. Por favor, inténtalo de nuevo más tarde."
@@ -35411,7 +35726,7 @@ msgid "Unable to save your changes. Please try again."
msgstr "No se pueden guardar sus cambios. Por favor, inténtelo de nuevo."
msgid "Unable to save your preference"
-msgstr ""
+msgstr "Se ha producido un error al guardar su preferencia"
msgid "Unable to schedule a pipeline to run immediately"
msgstr "No se puede programar un pipeline para que se ejecute inmediatamente"
@@ -35420,7 +35735,7 @@ msgid "Unable to sign you in to the group with SAML due to \"%{reason}\""
msgstr "Se ha producido un error al iniciar la sesión en el grupo mediante SAML debido a \"%{reason}\""
msgid "Unable to suggest a path. Please refresh and try again."
-msgstr ""
+msgstr "No se puede sugerir una ruta. Por favor, actualice e inténtelo de nuevo."
msgid "Unable to update label prioritization at this time"
msgstr "No se puede actualizar la prioridad de la etiqueta en este momento"
@@ -35465,7 +35780,7 @@ msgid "Undo ignore"
msgstr "Deshacer ignorar"
msgid "Unexpected error"
-msgstr ""
+msgstr "Error inesperado"
msgid "Unfollow"
msgstr ""
@@ -35534,16 +35849,16 @@ msgid "Unlocks the discussion."
msgstr "Desbloquea la discusión."
msgid "Unmarked this %{noun} as a draft."
-msgstr ""
+msgstr "Desmarcado este %{noun} como borrador."
msgid "Unmarks this %{noun} as a draft."
-msgstr ""
+msgstr "Desmarca este %{noun} como borrador."
msgid "Unreachable"
msgstr "Inalcanzable"
msgid "Unrecognized cluster type"
-msgstr ""
+msgstr "Tipo de clúster no reconocido"
msgid "Unresolve"
msgstr "Sin resolver"
@@ -35573,7 +35888,7 @@ msgid "Unstar"
msgstr "No Destacar"
msgid "Unstarted"
-msgstr ""
+msgstr "Sin iniciar"
msgid "Unsubscribe"
msgstr "Eliminar suscripción"
@@ -35594,11 +35909,14 @@ msgid "Unsubscribes from this %{quick_action_target}."
msgstr "Cancelar la suscripción desde este %{quick_action_target}."
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
-msgstr ""
+msgstr "Tipo de tarea no soportada. Los tipos de tareas soportadas son: %{todo_types}"
msgid "Until"
msgstr "Hasta"
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35621,7 +35939,7 @@ msgid "Update"
msgstr "Actualizar"
msgid "Update %{sourcePath} file"
-msgstr ""
+msgstr "Actualizar el archivo %{sourcePath}"
msgid "Update Now"
msgstr ""
@@ -35639,7 +35957,7 @@ msgid "Update approval rule"
msgstr "Actualizar la regla de aprobación"
msgid "Update approvers"
-msgstr ""
+msgstr "Actualizar los aprobadores"
msgid "Update broadcast message"
msgstr ""
@@ -35651,7 +35969,7 @@ msgid "Update it"
msgstr "Actualícelo"
msgid "Update iteration"
-msgstr ""
+msgstr "Actualizar la iteración"
msgid "Update milestone"
msgstr ""
@@ -35660,7 +35978,7 @@ msgid "Update now"
msgstr "Actualizar ahora"
msgid "Update username"
-msgstr ""
+msgstr "Actualizar el nombre de usuario"
msgid "Update variable"
msgstr "Actualizar variable"
@@ -35708,19 +36026,19 @@ msgid "Updating…"
msgstr ""
msgid "Upgrade offers available!"
-msgstr ""
+msgstr "¡Ofertas de actualización disponibles!"
msgid "Upgrade your plan"
-msgstr ""
+msgstr "Actualice su plan"
msgid "Upload"
-msgstr ""
+msgstr "Subir"
msgid "Upload CSV file"
msgstr "Subir fichero CSV"
msgid "Upload File"
-msgstr ""
+msgstr "Subir archivo"
msgid "Upload License"
msgstr "Subir licencia"
@@ -35735,7 +36053,7 @@ msgid "Upload a private key for your certificate"
msgstr "Suba una clave privada para su certificado"
msgid "Upload an image"
-msgstr ""
+msgstr "Subir una imagen"
msgid "Upload file"
msgstr "Subir archivo"
@@ -35774,7 +36092,7 @@ msgid "Usage"
msgstr "Uso"
msgid "Usage Trends"
-msgstr ""
+msgstr "Tendencias de uso"
msgid "Usage statistics"
msgstr "Estadísticas de uso"
@@ -35783,7 +36101,7 @@ msgid "UsageQuota|%{help_link_start}Shared runners%{help_link_end} are disabled,
msgstr "%{help_link_start}Los ejecutores compartidos%{help_link_end} están deshabilitados, por lo que no hay límites establecidos para el uso de los pipelines"
msgid "UsageQuota|%{percentageLeft} of purchased storage is available"
-msgstr ""
+msgstr "%{percentageLeft} de almacenamiento comprado está disponible"
msgid "UsageQuota|Artifacts"
msgstr "Artefactos"
@@ -35807,7 +36125,7 @@ msgid "UsageQuota|Increase storage temporarily"
msgstr ""
msgid "UsageQuota|LFS Objects"
-msgstr "UsageQuota|LFS Objetos"
+msgstr "Objetos LFS"
msgid "UsageQuota|LFS Storage"
msgstr "Almacenamiento LFS"
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr "Paquetes"
@@ -35831,7 +36146,7 @@ msgid "UsageQuota|Purchase more storage"
msgstr "Comprar más almacenamiento"
msgid "UsageQuota|Purchased storage available"
-msgstr ""
+msgstr "Almacenamiento comprado disponible"
msgid "UsageQuota|Repositories"
msgstr "Repositorios"
@@ -35839,9 +36154,15 @@ msgstr "Repositorios"
msgid "UsageQuota|Repository"
msgstr "Repositorio"
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr "Fragmentos de código"
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr "Almacenamiento"
@@ -35861,13 +36182,13 @@ msgid "UsageQuota|This project is at risk of being locked because purchased stor
msgstr ""
msgid "UsageQuota|This project is locked because it is using %{actualRepositorySizeLimit} of free storage and there is no purchased storage available."
-msgstr ""
+msgstr "Este proyecto está bloqueado porque está utilizando %{actualRepositorySizeLimit} de almacenamiento gratuito y no hay almacenamiento comprado disponible."
msgid "UsageQuota|This project is locked because it used %{actualRepositorySizeLimit} of free storage and all the purchased storage."
-msgstr ""
+msgstr "Este proyecto está bloqueado porque ha utilizado %{actualRepositorySizeLimit} de almacenamiento libre y todo el almacenamiento comprado."
msgid "UsageQuota|This project is near the free %{actualRepositorySizeLimit} limit and at risk of being locked."
-msgstr ""
+msgstr "Este proyecto está cerca del límite gratuito de %{actualRepositorySizeLimit} y corre el riesgo de ser bloqueado."
msgid "UsageQuota|Total excess storage used"
msgstr ""
@@ -35876,10 +36197,10 @@ msgid "UsageQuota|Total namespace storage used"
msgstr ""
msgid "UsageQuota|Unlimited"
-msgstr "|Ilimitado"
+msgstr "Ilimitado"
msgid "UsageQuota|Uploads"
-msgstr ""
+msgstr "Subidas"
msgid "UsageQuota|Usage"
msgstr "Uso"
@@ -35890,6 +36211,9 @@ msgstr "Cuotas de uso"
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr "Uso de los recursos del grupo a través de los proyectos en el grupo %{strong_start}%{group_name}%{strong_end}"
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -35933,52 +36257,52 @@ msgid "UsageTrends|Could not load the projects and groups chart. Please refresh
msgstr ""
msgid "UsageTrends|Groups"
-msgstr ""
+msgstr "Grupos"
msgid "UsageTrends|Issues"
-msgstr ""
+msgstr "Incidencias"
msgid "UsageTrends|Issues & merge requests"
msgstr ""
msgid "UsageTrends|Items"
-msgstr ""
+msgstr "Elementos"
msgid "UsageTrends|Merge requests"
msgstr ""
msgid "UsageTrends|Month"
-msgstr ""
+msgstr "Mes"
msgid "UsageTrends|No data available."
-msgstr ""
+msgstr "No hay datos disponibles."
msgid "UsageTrends|Pipelines"
-msgstr ""
+msgstr "Pipelines"
msgid "UsageTrends|Pipelines canceled"
-msgstr ""
+msgstr "Pipelines cancelados"
msgid "UsageTrends|Pipelines failed"
-msgstr ""
+msgstr "Pipelines fallidos"
msgid "UsageTrends|Pipelines skipped"
msgstr ""
msgid "UsageTrends|Pipelines succeeded"
-msgstr ""
+msgstr "Pipelines exitosos"
msgid "UsageTrends|Pipelines total"
-msgstr ""
+msgstr "Total de pipelines"
msgid "UsageTrends|Projects"
-msgstr ""
+msgstr "Proyectos"
msgid "UsageTrends|There was an error fetching the cancelled pipelines. Please try again."
-msgstr ""
+msgstr "Se ha producido un error al obtener los pipelines cancelados. Por favor, inténtelo de nuevo."
msgid "UsageTrends|There was an error fetching the failed pipelines. Please try again."
-msgstr ""
+msgstr "Se ha producido un error al obtener los pipelines fallidos. Por favor, inténtelo de nuevo."
msgid "UsageTrends|There was an error fetching the groups. Please try again."
msgstr ""
@@ -35993,43 +36317,43 @@ msgid "UsageTrends|There was an error fetching the projects. Please try again."
msgstr ""
msgid "UsageTrends|There was an error fetching the skipped pipelines. Please try again."
-msgstr ""
+msgstr "Se ha producido un error al obtener los pipelines omitidos. Por favor, inténtelo de nuevo."
msgid "UsageTrends|There was an error fetching the successful pipelines. Please try again."
-msgstr ""
+msgstr "Se ha producido un error al obtener los pipelines exitosos. Por favor, inténtelo de nuevo."
msgid "UsageTrends|There was an error fetching the total pipelines. Please try again."
-msgstr ""
+msgstr "Se ha producido un error al obtener los pipelines. Por favor, inténtelo de nuevo."
msgid "UsageTrends|Total groups"
-msgstr ""
+msgstr "Total de grupos"
msgid "UsageTrends|Total projects"
-msgstr ""
+msgstr "Total de proyectos"
msgid "UsageTrends|Total projects & groups"
-msgstr ""
+msgstr "Total de proyectos y grupos"
msgid "UsageTrends|Users"
-msgstr ""
+msgstr "Usuarios"
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
msgid "Use .gitlab-ci.yml"
-msgstr ""
+msgstr "Utilice .gitlab-ci.yml"
msgid "Use GitLab Runner in AWS"
msgstr ""
msgid "Use a one-time password authenticator on your mobile device or computer to enable two-factor authentication (2FA)."
-msgstr ""
+msgstr "Utilice un autenticador de contraseña de un solo uso en su dispositivo móvil u ordenador para activar la autentificación de doble factor (2FA)."
msgid "Use an AWS CloudFormation Template (CFT) to install and configure GitLab Runner in AWS."
msgstr ""
msgid "Use cURL"
-msgstr ""
+msgstr "Utilice cURL"
msgid "Use custom color #FF0000"
msgstr "Utilizar un color personalizado #FF0000"
@@ -36038,7 +36362,7 @@ msgid "Use double quotes for multiple keywords, such as %{code_open}\"your searc
msgstr ""
msgid "Use hashed storage"
-msgstr ""
+msgstr "Utilizar almacenamiento hash"
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr "Utilice una línea por URI"
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36071,7 +36398,7 @@ msgid "Use this token to validate received payloads."
msgstr ""
msgid "Use webhook"
-msgstr ""
+msgstr "Utilizar un webhook"
msgid "Use your global notification setting"
msgstr "Utiliza tu configuración de notificación global"
@@ -36080,7 +36407,7 @@ msgid "Use your smart card to authenticate with the LDAP server."
msgstr "Utilice su tarjeta inteligente para autenticarse contra el servidor LDAP."
msgid "Used"
-msgstr ""
+msgstr "Utilizado"
msgid "Used by members to sign in to your group in GitLab"
msgstr "Utilizado por los miembros para iniciar sesión en su grupo en GitLab"
@@ -36107,10 +36434,10 @@ msgid "User %{username} was successfully removed."
msgstr "El usuario %{username} se ha eliminado correctamente."
msgid "User %{user} was removed from %{group}."
-msgstr ""
+msgstr "El usuario %{user} fue eliminado de %{group}."
msgid "User ID"
-msgstr ""
+msgstr "Id de usuario"
msgid "User OAuth applications"
msgstr "Aplicaciones OAuth del usuario"
@@ -36131,7 +36458,7 @@ msgid "User identity was successfully updated."
msgstr "La identidad de usuario se ha actualizado correctamente."
msgid "User is not allowed to resolve thread"
-msgstr ""
+msgstr "El usuario no está autorizado a resolver el hilo"
msgid "User key"
msgstr ""
@@ -36140,7 +36467,7 @@ msgid "User key was successfully removed."
msgstr "La clave de usuario se ha eliminado correctamente."
msgid "User list %{name} will be removed. Are you sure?"
-msgstr ""
+msgstr "Se eliminará la lista de usuarios %{name} ¿Está seguro?"
msgid "User map"
msgstr "Mapa de usuario"
@@ -36161,7 +36488,7 @@ msgid "User was successfully removed from group and any subgroups and projects."
msgstr ""
msgid "User was successfully removed from group."
-msgstr ""
+msgstr "El usuario fue eliminado correctamente del grupo."
msgid "User was successfully removed from project."
msgstr "Se ha eliminado el usuario correctamente del proyecto."
@@ -36176,34 +36503,34 @@ msgid "UserAvailability|%{author} %{spanStart}(Busy)%{spanEnd}"
msgstr ""
msgid "UserAvailability|%{author} (Busy)"
-msgstr ""
+msgstr "%{author} (Ocupado)"
msgid "UserAvailability|(Busy)"
-msgstr ""
+msgstr "(Ocupado)"
msgid "UserLists|Add"
-msgstr ""
+msgstr "Añadir"
msgid "UserLists|Add Users"
-msgstr ""
+msgstr "Añadir usuarios"
msgid "UserLists|Add users"
-msgstr ""
+msgstr "Añadir usuarios"
msgid "UserLists|Cancel"
-msgstr ""
+msgstr "Cancelar"
msgid "UserLists|Create"
-msgstr ""
+msgstr "Crear"
msgid "UserLists|Define a set of users to be used within feature flag strategies"
msgstr ""
msgid "UserLists|Edit"
-msgstr ""
+msgstr "Editar"
msgid "UserLists|Edit %{name}"
-msgstr ""
+msgstr "Edición %{name}"
msgid "UserLists|Enter a comma separated list of user IDs. These IDs should be the users of the system in which the feature flag is set, not GitLab IDs"
msgstr ""
@@ -36221,28 +36548,28 @@ msgid "UserLists|Loading user lists"
msgstr ""
msgid "UserLists|Name"
-msgstr ""
+msgstr "Nombre"
msgid "UserLists|New list"
-msgstr ""
+msgstr "Nueva lista"
msgid "UserLists|New user list"
msgstr ""
msgid "UserLists|Save"
-msgstr ""
+msgstr "Guardar"
msgid "UserLists|There are no users"
-msgstr ""
+msgstr "No hay usuarios"
msgid "UserLists|There was an error fetching the user lists."
msgstr ""
msgid "UserLists|User ID"
-msgstr ""
+msgstr "ID del usuario"
msgid "UserLists|User IDs"
-msgstr ""
+msgstr "IDs de los usuarios"
msgid "UserLists|User Lists"
msgstr ""
@@ -36257,7 +36584,7 @@ msgid "UserList|created %{timeago}"
msgstr "creado %{timeago}"
msgid "UserProfile|(Busy)"
-msgstr ""
+msgstr "(Ocupado)"
msgid "UserProfile|Activity"
msgstr "Actividad"
@@ -36269,7 +36596,7 @@ msgid "UserProfile|Blocked user"
msgstr "Usuario bloqueado"
msgid "UserProfile|Bot activity"
-msgstr ""
+msgstr "Actividad del bot"
msgid "UserProfile|Contributed projects"
msgstr "Proyectos contribuidos"
@@ -36281,10 +36608,10 @@ msgid "UserProfile|Explore public groups to find projects to contribute to."
msgstr "Explore los grupos públicos para encontrar proyectos en los que contribuir."
msgid "UserProfile|Followers"
-msgstr ""
+msgstr "Seguidores"
msgid "UserProfile|Following"
-msgstr ""
+msgstr "Siguiendo"
msgid "UserProfile|Groups"
msgstr "Grupos"
@@ -36314,7 +36641,7 @@ msgid "UserProfile|Report abuse"
msgstr "Informar de abuso"
msgid "UserProfile|Retry"
-msgstr ""
+msgstr "Reintentar"
msgid "UserProfile|Snippets"
msgstr "Fragmentos de código"
@@ -36332,7 +36659,7 @@ msgid "UserProfile|Subscribe"
msgstr "Suscribirse"
msgid "UserProfile|This user doesn't have any followers."
-msgstr ""
+msgstr "Este usuario no tiene seguidores."
msgid "UserProfile|This user doesn't have any personal projects"
msgstr "Este usuario no tiene ningún proyecto personal"
@@ -36350,10 +36677,10 @@ msgid "UserProfile|This user is blocked"
msgstr "Este usuario está bloqueado"
msgid "UserProfile|This user isn't following other users."
-msgstr ""
+msgstr "Este usuario no está siguiendo a otros usuarios."
msgid "UserProfile|Unconfirmed user"
-msgstr ""
+msgstr "Usuario no confirmado"
msgid "UserProfile|View all"
msgstr "Ver todo"
@@ -36362,13 +36689,13 @@ msgid "UserProfile|View user in admin area"
msgstr "Ver usuario en el área de administración"
msgid "UserProfile|You are not following other users."
-msgstr ""
+msgstr "No está siguiendo a otros usuarios."
msgid "UserProfile|You can create a group for several dependent projects."
msgstr "Puede crear un grupo que agrupe varios proyectos dependientes."
msgid "UserProfile|You do not have any followers."
-msgstr ""
+msgstr "No tiene seguidores."
msgid "UserProfile|You haven't created any personal projects."
msgstr "No ha creado ningún proyecto personal."
@@ -36407,7 +36734,7 @@ msgid "Username:"
msgstr ""
msgid "Username: %{username}"
-msgstr ""
+msgstr "Nombre de usuario: %{username}"
msgid "Users"
msgstr "Usuarios"
@@ -36419,7 +36746,7 @@ msgid "Users can render diagrams in AsciiDoc, Markdown, reStructuredText, and Te
msgstr ""
msgid "Users in License"
-msgstr ""
+msgstr "Usuarios con licencia"
msgid "Users or groups set as approvers in the project's or merge request's settings."
msgstr ""
@@ -36464,7 +36791,7 @@ msgid "Validate"
msgstr "Validar"
msgid "Validate your GitLab CI configuration"
-msgstr ""
+msgstr "Valide su configuración de GitLab CI"
msgid "Validate your GitLab CI configuration file"
msgstr "Valide su archivo de configuración de GitLab CI"
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36557,7 +36890,7 @@ msgid "Variables"
msgstr "Variables"
msgid "Variables can be:"
-msgstr ""
+msgstr "Las variables pueden ser:"
msgid "Variables store information, like passwords and secret keys, that you can use in job scripts."
msgstr ""
@@ -36596,22 +36929,22 @@ msgid "Version"
msgstr "Versión"
msgid "Version %{versionNumber}"
-msgstr ""
+msgstr "Versión %{versionNumber}"
msgid "Version %{versionNumber} (latest)"
-msgstr ""
+msgstr "Versión %{versionNumber} (última)"
msgid "View Documentation"
msgstr "Ver documentación"
msgid "View alert details at"
-msgstr ""
+msgstr "Ver los detalles de la alerta en"
msgid "View alert details."
-msgstr ""
+msgstr "Ver los detalles de la alerta."
msgid "View all environments."
-msgstr ""
+msgstr "Ver todos los entornos."
msgid "View all issues"
msgstr "Ver todas las incidencias"
@@ -36696,13 +37029,13 @@ msgid "View log"
msgstr "Ver log"
msgid "View logs"
-msgstr ""
+msgstr "Ver los logs"
msgid "View merge request"
msgstr ""
msgid "View on %{url}"
-msgstr ""
+msgstr "Ver en %{url}"
msgid "View open merge request"
msgstr "Ver solicitud de fusión abierta"
@@ -36722,11 +37055,16 @@ msgstr ""
msgid "View project labels"
msgstr "Ver etiquetas de proyectos"
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr "Ver archivo reemplazado @ "
msgid "View setting"
-msgstr ""
+msgstr "Ver configuración"
msgid "View supported languages and frameworks"
msgstr "Ver idiomas y marcos soportados"
@@ -36735,7 +37073,7 @@ msgid "View the documentation"
msgstr "Ver documentación"
msgid "View the latest successful deployment to this environment"
-msgstr ""
+msgstr "Vea la última despliegue con éxito en este entorno"
msgid "View the performance dashboard at"
msgstr "Ver el panel de control del rendimiento en"
@@ -36747,7 +37085,7 @@ msgid "View users statistics"
msgstr "Ver las estadísticas de usuarios"
msgid "Viewed"
-msgstr ""
+msgstr "Visto"
msgid "Viewing commit"
msgstr "Ver commit"
@@ -36786,7 +37124,7 @@ msgid "VisibilityLevel|Unknown"
msgstr "Desconocido"
msgid "Visit settings page"
-msgstr ""
+msgstr "Visitar la página de configuración"
msgid "Visual Studio Code (HTTPS)"
msgstr ""
@@ -36801,16 +37139,16 @@ msgid "Vulnerabilities over time"
msgstr "Vulnerabilidades a lo largo del tiempo"
msgid "Vulnerability Report"
-msgstr ""
+msgstr "Informe de vulnerabilidad"
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
msgid "Vulnerability resolved in %{branch}"
-msgstr ""
+msgstr "Vulnerabilidad resuelta en %{branch}"
msgid "Vulnerability resolved in the default branch"
-msgstr ""
+msgstr "Vulnerabilidad resuelta en la rama por defecto"
msgid "VulnerabilityChart|%{formattedStartDate} to today"
msgstr "%{formattedStartDate} hasta hoy"
@@ -36843,10 +37181,10 @@ msgid "VulnerabilityManagement|Could not process %{issueReference}: %{errorMessa
msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
-msgstr ""
+msgstr "Crear una incidencia en Jira"
msgid "VulnerabilityManagement|Detected"
-msgstr ""
+msgstr "Detectada"
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -36909,22 +37247,22 @@ msgid "Vulnerability|%{scannerName} (version %{scannerVersion})"
msgstr "%{scannerName} (versión %{scannerVersion})"
msgid "Vulnerability|Activity"
-msgstr ""
+msgstr "Actividad"
msgid "Vulnerability|Actual Response"
-msgstr ""
+msgstr "Respuesta"
msgid "Vulnerability|Actual received response is the one received when this fault was detected"
-msgstr ""
+msgstr "La respuesta recibida es la que se recibió cuando se detectó este fallo"
msgid "Vulnerability|Additional Info"
-msgstr ""
+msgstr "Información adicional"
msgid "Vulnerability|Class"
msgstr "Clase"
msgid "Vulnerability|Comments"
-msgstr ""
+msgstr "Comentarios"
msgid "Vulnerability|Crash address"
msgstr ""
@@ -36939,10 +37277,10 @@ msgid "Vulnerability|Description"
msgstr "Descripción"
msgid "Vulnerability|Detected"
-msgstr ""
+msgstr "Detectada"
msgid "Vulnerability|Download"
-msgstr ""
+msgstr "Descargar"
msgid "Vulnerability|Evidence"
msgstr "Evidencia"
@@ -36951,7 +37289,7 @@ msgid "Vulnerability|File"
msgstr "Archivo"
msgid "Vulnerability|Identifier"
-msgstr ""
+msgstr "Identificador"
msgid "Vulnerability|Identifiers"
msgstr "Identificadores"
@@ -36975,13 +37313,10 @@ msgid "Vulnerability|Reproduction Assets"
msgstr ""
msgid "Vulnerability|Request"
-msgstr ""
+msgstr "Solicitud"
msgid "Vulnerability|Request/Response"
-msgstr ""
-
-msgid "Vulnerability|Scanner"
-msgstr ""
+msgstr "Solicitud/Respuesta"
msgid "Vulnerability|Scanner Provider"
msgstr "Proveedor del escáner"
@@ -36995,6 +37330,9 @@ msgstr "Estado"
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37014,7 +37352,7 @@ msgid "Want to see the data? Please ask an administrator for access."
msgstr "¿Quieres ver los datos? Por favor pide acceso al administrador."
msgid "Warning"
-msgstr ""
+msgstr "Advertencia"
msgid "Warning:"
msgstr "Advertencia:"
@@ -37029,7 +37367,7 @@ msgid "We are currently unable to fetch data for the pipeline header."
msgstr ""
msgid "We are currently unable to fetch data for this graph."
-msgstr ""
+msgstr "Actualmente no podemos obtener datos para este gráfico."
msgid "We are currently unable to fetch data for this pipeline."
msgstr ""
@@ -37041,13 +37379,13 @@ msgid "We could not determine the path to remove the issue"
msgstr "No es posible determinar la ruta para eliminar esta incidencia"
msgid "We couldn't find any %{scope} matching %{term}"
-msgstr ""
+msgstr "No hemos podido encontrar ningún %{scope} que coincida con el %{term}"
msgid "We couldn't find any %{scope} matching %{term} in group %{group}"
-msgstr ""
+msgstr "No hemos podido encontrar ningún %{scope} que coincida con %{term} en el grupo %{group}"
msgid "We couldn't find any %{scope} matching %{term} in project %{project}"
-msgstr ""
+msgstr "No hemos podido encontrar ningún %{scope} que coincida con %{term} en el proyecto %{project}"
msgid "We couldn't reach the Prometheus server. Either the server no longer exists or the configuration details need updating."
msgstr "No ha sido posible conectar al servidor de Prometheus. O el servidor ya no existe o debe actualizar los detalles de configuración."
@@ -37092,12 +37430,15 @@ msgid "We want to be sure it is you, please confirm you are not a robot."
msgstr "Queremos asegurarnos de que sea usted, por favor, ayudenos a confirmar que no es un robot."
msgid "We will notify %{inviter} that you declined their invitation to join GitLab. You will stop receiving reminders."
-msgstr ""
+msgstr "Notificaremos a %{inviter} que ha rechazado su invitación para unirse a GitLab. Dejará de recibir recordatorios."
msgid "We would like to inform you that your subscription GitLab Enterprise Edition %{plan_name} is nearing its user limit. You have %{active_user_count} active users, which is almost at the user limit of %{maximum_user_count}."
-msgstr ""
+msgstr "Nos gustaría informarle de que su suscripción a GitLab Enterprise Edition %{plan_name} se está acercando a su límite de usuarios. Tiene %{active_user_count} usuarios activos, lo que casi alcanza el límite de usuarios de %{maximum_user_count}."
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
+msgstr "Validaremos continuamente la configuración de su pipeline. Los resultados de la validación aparecerán aquí."
+
+msgid "We'll use this to help surface the right features and information to you."
msgstr ""
msgid "We've found no vulnerabilities"
@@ -37113,10 +37454,10 @@ msgid "Web terminal"
msgstr "Terminal web"
msgid "WebAuthn Devices (%{length})"
-msgstr ""
+msgstr "Dispositivos WebAuthn (%{length})"
msgid "WebAuthn only works with HTTPS-enabled websites. Contact your administrator for more details."
-msgstr ""
+msgstr "WebAuthn sólo funciona con sitios web habilitados para HTTPS. Póngase en contacto con su administrador para obtener más detalles."
msgid "WebIDE|Fork project"
msgstr ""
@@ -37170,37 +37511,37 @@ msgid "Webhooks Help"
msgstr ""
msgid "Webhooks|Comments"
-msgstr ""
+msgstr "Comentarios"
msgid "Webhooks|Confidential comments"
-msgstr ""
+msgstr "Comentarios confidenciales"
msgid "Webhooks|Confidential issues events"
msgstr ""
msgid "Webhooks|Deployment events"
-msgstr ""
+msgstr "Eventos de despliegue"
msgid "Webhooks|Enable SSL verification"
-msgstr ""
+msgstr "Activar la verificación SSL"
msgid "Webhooks|Feature flag events"
msgstr ""
msgid "Webhooks|Issues events"
-msgstr ""
+msgstr "Eventos de las incidencias"
msgid "Webhooks|Job events"
-msgstr ""
+msgstr "Eventos de los trabajos"
msgid "Webhooks|Member events"
-msgstr ""
+msgstr "Eventos de los miembros"
msgid "Webhooks|Merge request events"
msgstr ""
msgid "Webhooks|Pipeline events"
-msgstr ""
+msgstr "Eventos de pipelines"
msgid "Webhooks|Push events"
msgstr ""
@@ -37209,7 +37550,7 @@ msgid "Webhooks|Releases events"
msgstr ""
msgid "Webhooks|SSL verification"
-msgstr ""
+msgstr "Verificación SSL"
msgid "Webhooks|Secret token"
msgstr ""
@@ -37221,10 +37562,10 @@ msgid "Webhooks|Tag push events"
msgstr ""
msgid "Webhooks|Trigger"
-msgstr ""
+msgstr "Disparador"
msgid "Webhooks|URL"
-msgstr ""
+msgstr "URL"
msgid "Webhooks|URL is triggered by a push to the repository"
msgstr ""
@@ -37308,7 +37649,7 @@ msgid "Welcome to GitLab, %{first_name}!"
msgstr "¡Bienvenido a GitLab %{first_name}!"
msgid "Welcome to GitLab,%{br_tag}%{name}!"
-msgstr ""
+msgstr "¡Bienvenido a GitLab,%{br_tag}%{name}!"
msgid "Welcome to the guided GitLab tour"
msgstr "Bienvenido a la visita guiada de GitLab"
@@ -37335,16 +37676,16 @@ msgid "What describes you best?"
msgstr "¿Qué le describe mejor?"
msgid "What does this command do?"
-msgstr ""
+msgstr "¿Qué hace este comando?"
msgid "What is Auto DevOps?"
msgstr ""
msgid "What is Markdown?"
-msgstr ""
+msgstr "¿Qué es Markdown?"
msgid "What is repository mirroring?"
-msgstr ""
+msgstr "¿Qué es la duplicación de repositorios?"
msgid "What is squashing?"
msgstr ""
@@ -37353,10 +37694,13 @@ msgid "What is time tracking?"
msgstr ""
msgid "What is your job title? (optional)"
+msgstr "¿Cuál es su cargo? (opcional)"
+
+msgid "What will you use this group for?"
msgstr ""
msgid "What's new"
-msgstr ""
+msgstr "¿Qué hay de nuevo?"
msgid "What’s your experience level?"
msgstr "¿Cuál es su nivel de experiencia?"
@@ -37397,7 +37741,7 @@ msgid "While it's rare to have no vulnerabilities, it can happen. In any event,
msgstr ""
msgid "Who can approve?"
-msgstr ""
+msgstr "¿Quién puede aprobarlo?"
msgid "Who can see this group?"
msgstr "¿Quién puede ver este grupo?"
@@ -37414,6 +37758,9 @@ msgstr "¿Quién utilizará esta suscripción de GitLab?"
msgid "Who will be using this GitLab trial?"
msgstr "¿Quién utilizará esta versión de prueba de GitLab?"
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37421,13 +37768,13 @@ msgid "Wiki"
msgstr "Wiki"
msgid "Wiki page was successfully created."
-msgstr ""
+msgstr "La página Wiki se ha creado con éxito."
msgid "Wiki page was successfully deleted."
-msgstr ""
+msgstr "La página Wiki se ha eliminado con éxito."
msgid "Wiki page was successfully updated."
-msgstr ""
+msgstr "La página Wiki se ha actualizado con éxito."
msgid "WikiClone|Clone your wiki"
msgstr "Clonar su wiki"
@@ -37466,13 +37813,13 @@ msgid "WikiEmpty|A wiki is where you can store all the details about your projec
msgstr "Un wiki es una herramienta en la que puede almacenar todos los detalles sobre su proyecto. Puede indicar por qué lo ha creado, sus principios, instrucciones sobre cómo utilizarlo, etc."
msgid "WikiEmpty|Confluence is enabled"
-msgstr ""
+msgstr "Confluence está habilitado"
msgid "WikiEmpty|Create your first page"
msgstr "Cree su primera página"
msgid "WikiEmpty|Enable the Confluence Wiki integration"
-msgstr ""
+msgstr "Activar la integración de Confluence Wiki"
msgid "WikiEmpty|Go to Confluence"
msgstr ""
@@ -37538,16 +37885,16 @@ msgid "WikiPage|Commit message"
msgstr ""
msgid "WikiPage|Content"
-msgstr ""
+msgstr "Contenido"
msgid "WikiPage|Create %{pageTitle}"
-msgstr ""
+msgstr "Crear %{pageTitle}"
msgid "WikiPage|Create page"
-msgstr ""
+msgstr "Crear página"
msgid "WikiPage|Format"
-msgstr ""
+msgstr "Formato"
msgid "WikiPage|Get a richer editing experience"
msgstr ""
@@ -37559,7 +37906,7 @@ msgid "WikiPage|More Information."
msgstr ""
msgid "WikiPage|Page title"
-msgstr ""
+msgstr "Título de la página"
msgid "WikiPage|Retry"
msgstr ""
@@ -37586,7 +37933,7 @@ msgid "WikiPage|Tip: You can specify the full path for the new file. We will aut
msgstr ""
msgid "WikiPage|Title"
-msgstr ""
+msgstr "Título"
msgid "WikiPage|To link to a (new) page, simply type %{linkExample}. More examples are in the %{linkStart}documentation%{linkEnd}."
msgstr ""
@@ -37676,7 +38023,7 @@ msgid "Would you like to try auto-generating a branch name?"
msgstr ""
msgid "Write"
-msgstr "Escritura"
+msgstr "Escribir"
msgid "Write a comment or drag your files here…"
msgstr "Escriba un comentario o arrastre sus archivos aquí…"
@@ -37685,7 +38032,7 @@ msgid "Write a comment…"
msgstr "Escriba un comentario…"
msgid "Write a description or drag your files here…"
-msgstr ""
+msgstr "Escriba una descripción o arrastre sus archivos aquí.."
msgid "Write milestone description..."
msgstr "Escriba la descripción del hito..."
@@ -37703,7 +38050,7 @@ msgid "Xcode"
msgstr ""
msgid "YYYY-MM-DD"
-msgstr ""
+msgstr "AAAA-MM-DD"
msgid "Yes"
msgstr "Si"
@@ -37718,7 +38065,7 @@ msgid "Yes, close issue"
msgstr "Sí, cerrar la incidencia"
msgid "Yes, delete project"
-msgstr ""
+msgstr "Sí, eliminar el proyecto"
msgid "Yesterday"
msgstr "Ayer"
@@ -37727,25 +38074,25 @@ msgid "You"
msgstr "Usted"
msgid "You already have pending todo for this alert"
-msgstr ""
+msgstr "Ya tiene una tarea pendiente para esta alerta"
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
-msgstr ""
+msgstr "Está a punto de añadir %{usersTag} personas a la discusión. Todas ellas recibirán una notificación."
msgid "You are about to delete %{domain} from your instance. This domain will no longer be available to any Knative application."
-msgstr ""
+msgstr "Está a punto de eliminar %{domain} de su instancia. Este dominio ya no estará disponible para ninguna aplicación Knative."
msgid "You are about to permanently delete this project"
-msgstr ""
+msgstr "Está a punto de eliminar definitivamente este proyecto"
msgid "You are about to transfer the control of your account to %{group_name} group. This action is NOT reversible, you won't be able to access any of your groups and projects outside of %{group_name} once this transfer is complete."
-msgstr ""
+msgstr "Está a punto de transferir el control de su cuenta al grupo %{group_name}. Esta acción NO es reversible, no podrá acceder a ninguno de sus grupos y proyectos fuera de %{group_name} una vez completada esta transferencia."
msgid "You are already a member of this %{member_source}."
msgstr ""
msgid "You are an admin, which means granting access to %{client_name} will allow them to interact with GitLab as an admin as well. Proceed with caution."
-msgstr ""
+msgstr "Es administrador, lo que significa que conceder acceso a %{client_name} les permitirá interactuar con GitLab como un administrador también. Proceda con precaución."
msgid "You are attempting to delete a file that has been previously updated."
msgstr "Está intentando eliminar un archivo que ha sido actualizado previamente."
@@ -37757,7 +38104,7 @@ msgid "You are connected to the Prometheus server, but there is currently no dat
msgstr "Está conectado al servidor de Prometheus, pero actualmente no hay datos disponibles para mostrar."
msgid "You are going to delete %{project_full_name}. Deleted projects CANNOT be restored! Are you ABSOLUTELY sure?"
-msgstr ""
+msgstr "Va a borrar %{project_full_name}. Los proyectos borrados NO SE PUEDEN restaurar ¿Está ABSOLUTAMENTE seguro?"
msgid "You are going to remove %{group_name}. This will also delete all of its subgroups and projects. Removed groups CANNOT be restored! Are you ABSOLUTELY sure?"
msgstr ""
@@ -37787,7 +38134,7 @@ msgid "You are not allowed to push into this branch. Create another branch or op
msgstr ""
msgid "You are not allowed to reject a user"
-msgstr ""
+msgstr "No tiene permiso para rechazar a un usuario"
msgid "You are not allowed to unlink your primary login account"
msgstr "No tiene permiso para desvincular su cuenta principal de inicio de sesión"
@@ -37817,7 +38164,7 @@ msgid "You are trying to upload something other than an image. Please upload a .
msgstr ""
msgid "You are using PostgreSQL %{pg_version_current}, but PostgreSQL %{pg_version_minimum} is required for this version of GitLab. Please upgrade your environment to a supported PostgreSQL version, see %{pg_requirements_url} for details."
-msgstr ""
+msgstr "Está utilizando PostgreSQL %{pg_version_current}, pero PostgreSQL %{pg_version_minimum} es necesario para esta versión de GitLab. Por favor, actualice su entorno a una versión de PostgreSQL compatible, vea %{pg_requirements_url} para más detalles."
msgid "You can %{gitlabLinkStart}resolve conflicts on GitLab%{gitlabLinkEnd} or %{resolveLocallyStart}resolve it locally%{resolveLocallyEnd}."
msgstr ""
@@ -37850,22 +38197,22 @@ msgid "You can always edit this later"
msgstr "Siempre puede editar esto más tarde"
msgid "You can create a new %{link}."
-msgstr ""
+msgstr "Puede crear un nuevo %{link}."
msgid "You can create a new %{name} inside this project by sending an email to the following email address:"
-msgstr ""
+msgstr "Puede crear un nuevo %{name} dentro de este proyecto enviando un correo electrónico a la siguiente dirección:"
msgid "You can create a new Personal Access Token by visiting %{link}"
-msgstr ""
+msgstr "Puede crear un nuevo token de acceso personal visitando %{link}"
msgid "You can create a new SSH key by visiting %{link}"
-msgstr ""
+msgstr "Puede crear una nueva clave SSH visitando %{link}"
msgid "You can create a new one or check them in your %{pat_link_start}personal access tokens%{pat_link_end} settings."
msgstr ""
msgid "You can create a new one or check them in your %{ssh_key_link_start}SSH keys%{ssh_key_link_end} settings."
-msgstr ""
+msgstr "Puedes crear uno nuevo o comprobarlo en la configuración de sus %{ssh_key_link_start}claves SSH%{ssh_key_link_end}."
msgid "You can create a new one or check them in your SSH keys settings %{ssh_key_link}."
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr "Puede probar su archivo .gitlab-ci.yml en %{linkStart}CI Lint%{linkEnd}.
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr "No puede acceder al archivo sin formato. Por favor, espere un minuto."
@@ -37987,6 +38337,9 @@ msgstr "No puede suplantar a un usuario interno"
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr "No puede ejecutar este pipeline programado en este momento. Por favor, espere un minuto."
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr "No puedes escribir en una instancia secundaria de sólo lectura de GitLab Geo. Utilice %{link_to_primary_node} en lugar de otro."
@@ -38117,7 +38470,7 @@ msgid "You have insufficient permissions to update this HTTP integration"
msgstr ""
msgid "You have insufficient permissions to view shifts for this rotation"
-msgstr ""
+msgstr "No tiene permisos suficientes para ver los turnos de esta rotación"
msgid "You have no permissions"
msgstr "No tiene permisos"
@@ -38131,7 +38484,7 @@ msgstr "Has alcanzado el límite de tu proyecto"
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38144,7 +38497,7 @@ msgid "You may close the milestone now."
msgstr "Puede cerrar el hito ahora."
msgid "You must be logged in to search across all of GitLab"
-msgstr ""
+msgstr "Debe estar conectado para buscar en todo GitLab"
msgid "You must disassociate %{domain} from all clusters it is attached to before deletion."
msgstr ""
@@ -38168,7 +38521,7 @@ msgid "You must provide your current password in order to change it."
msgstr "Debe introducir su contraseña actual para poder cambiarla."
msgid "You must solve the CAPTCHA in order to submit"
-msgstr ""
+msgstr "Debe resolver el CAPTCHA para poder enviar"
msgid "You must upload a file with the same file name when dropping onto an existing design."
msgstr ""
@@ -38195,13 +38548,13 @@ msgid "You need to upload a GitLab project export archive (ending in .gz)."
msgstr "Es necesario subir un archivo de exportación de proyecto de GitLab (en formato .gz)."
msgid "You successfully declined the invitation"
-msgstr ""
+msgstr "Ha rechazado con éxito la invitación"
msgid "You tried to fork %{link_to_the_project} but it failed for the following reason:"
msgstr "Trató de hacer un fork de %{link_to_the_project} pero falló por la siguiente razón:"
msgid "You will be removed from existing projects/groups"
-msgstr ""
+msgstr "Será eliminado de proyectos/grupos existentes"
msgid "You will be the author of all events in the activity feed that are the result of an update, like new branches being created or new commits being pushed to existing branches."
msgstr ""
@@ -38288,7 +38641,7 @@ msgid "You've already enabled two-factor authentication using one time password
msgstr "Ya ha habilitado la autenticación de dos pasos utilizando una contraseña de un solo uso. Para registrar un dispositivo diferente, primero debe desactivar la autenticación de dos factores."
msgid "You've rejected %{user}"
-msgstr ""
+msgstr "Ha rechazado a %{user}"
msgid "YouTube"
msgstr "YouTube"
@@ -38351,13 +38704,13 @@ msgid "Your Projects' Activity"
msgstr "Actividad de sus proyectos"
msgid "Your SSH key has expired"
-msgstr ""
+msgstr "Su clave SSH ha caducado"
msgid "Your SSH key is expiring soon."
msgstr ""
msgid "Your SSH key was deleted"
-msgstr ""
+msgstr "Su clave SSH fue eliminada"
msgid "Your SSH keys (%{count})"
msgstr "Sus Claves SSH (%{count})"
@@ -38495,7 +38848,7 @@ msgid "Your license is valid from"
msgstr "Su licencia es válida desde"
msgid "Your membership in %{group} no longer expires."
-msgstr ""
+msgstr "Su membresía en %{group} ya no caduca."
msgid "Your message here"
msgstr "Su mensaje aquí"
@@ -38525,10 +38878,10 @@ msgid "Your password reset token has expired."
msgstr "Su token para restablecer la contraseña ha caducado."
msgid "Your personal access token has expired"
-msgstr ""
+msgstr "Su token de acceso personal ha caducado"
msgid "Your personal access tokens will expire in %{days_to_expire} days or less"
-msgstr ""
+msgstr "Sus tokens de acceso personal caducarán en %{days_to_expire} días o menos"
msgid "Your primary email is used for avatar detection. You can change it in your %{openingTag}profile settings%{closingTag}."
msgstr ""
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38573,18 +38926,42 @@ msgid "Your search timed out"
msgstr ""
msgid "Your sign-in page is %{url}."
-msgstr ""
+msgstr "Su página de inicio de sesión es %{url}."
msgid "Your subscription expired!"
msgstr "¡Su suscripción ha caducado!"
msgid "Your subscription has been downgraded."
-msgstr ""
+msgstr "Su suscripción ha sido degradada."
msgid "Your subscription will expire in %{remaining_days}."
-msgstr ""
+msgstr "Su suscripción caducará en %{remaining_days}."
msgid "Your username is %{username}."
+msgstr "Su nombre de usuario es %{username}."
+
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
msgstr ""
msgid "Zoom meeting added"
@@ -38674,7 +39051,7 @@ msgid "assign yourself"
msgstr "asignar a ti mismo"
msgid "at"
-msgstr ""
+msgstr "en"
msgid "at risk"
msgstr "en riesgo"
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr "bloques"
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr "nombre de la rama"
@@ -38814,12 +39196,12 @@ msgstr ""
msgid "ciReport|All projects"
msgstr "Todos los proyectos"
-msgid "ciReport|All scanners"
-msgstr ""
-
msgid "ciReport|All severities"
msgstr "Todos los niveles de gravedad"
+msgid "ciReport|All tools"
+msgstr ""
+
msgid "ciReport|Automatically apply the patch in a new branch"
msgstr "Aplicar automáticamente el parche en una nueva rama"
@@ -38994,7 +39376,7 @@ msgid "ciReport|is loading, errors when loading results"
msgstr ""
msgid "closed"
-msgstr ""
+msgstr "cerrado"
msgid "closed issue"
msgstr "incidencia cerrada"
@@ -39072,13 +39454,13 @@ msgid "created %{issuable_created} by %{author}"
msgstr ""
msgid "created %{timeAgoString} by %{email} via %{user}"
-msgstr ""
+msgstr "creado %{timeAgoString} por %{email} través de %{user}"
msgid "created %{timeAgoString} by %{user}"
-msgstr ""
+msgstr "creado %{timeAgoString} por %{user}"
msgid "created %{timeAgoString} by %{user} in Jira"
-msgstr ""
+msgstr "creado %{timeAgoString} por %{user} en Jira"
msgid "created %{timeAgo}"
msgstr "creado el %{timeAgo}"
@@ -39087,7 +39469,7 @@ msgid "created by"
msgstr ""
msgid "data"
-msgstr ""
+msgstr "dato"
msgid "date must not be after 9999-12-31"
msgstr "la fecha no puede ser superior a 9999-12-31"
@@ -39098,7 +39480,7 @@ msgstr[0] "día"
msgstr[1] "días"
msgid "days"
-msgstr ""
+msgstr "días"
msgid "default branch"
msgstr "rama por defecto"
@@ -39156,7 +39538,7 @@ msgid "enabled"
msgstr "habilitado"
msgid "encrypted: needs to be a :required, :optional or :migrating!"
-msgstr "encriptado: debe ser :requerido, :opcional o :migrando"
+msgstr ""
msgid "ending with MIME type format is not allowed."
msgstr ""
@@ -39170,9 +39552,12 @@ msgstr "las entradas no pueden estar vacías"
msgid "entries cannot contain HTML tags"
msgstr "las entradas no pueden contener etiquetas HTML"
-msgid "epic"
+msgid "environment_id parameter is required when type is container_policy"
msgstr ""
+msgid "epic"
+msgstr "épica"
+
msgid "error"
msgstr "error"
@@ -39298,7 +39683,7 @@ msgid "import flow"
msgstr "flujo de importación"
msgid "in"
-msgstr ""
+msgstr "en"
msgid "in group %{link_to_group}"
msgstr "en el grupo %{link_to_group}"
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr "no es un correo electrónico de su propiedad"
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr "Cerrado"
msgid "mrWidget|Closed by"
msgstr "Cerrado por"
-msgid "mrWidget|Closes"
-msgstr "Cierra"
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr "Eliminar la rama de origen"
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr "Menciones"
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr "Merge"
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr "Más información"
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr "Abrir en Web IDE"
@@ -39718,9 +40107,6 @@ msgstr "Los cambios se fusionarán en"
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr "Se ha eliminado el branch de origen"
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr "No tiene permiso para editar este proyecto directamente. Por favor, haga un fork para hacer cambios."
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr "debe ser mayor que la fecha de inicio"
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
@@ -39824,10 +40213,10 @@ msgid "new merge request"
msgstr "nueva solicitud de fusión"
msgid "no approvers"
-msgstr ""
+msgstr "sin aprobadores"
msgid "no expiration"
-msgstr "Sin fecha de caducidad"
+msgstr "Sin fecha de vencimiento"
msgid "no name set"
msgstr ""
@@ -40092,7 +40481,7 @@ msgid "spendCommand|%{slash_command} adds or subtracts time already spent."
msgstr ""
msgid "ssh:"
-msgstr ""
+msgstr "ssh:"
msgid "started a discussion on %{design_link}"
msgstr "inició una discusión en %{design_link}"
@@ -40164,10 +40553,10 @@ msgid "triggered"
msgstr "disparado"
msgid "two-factor authentication settings"
-msgstr ""
+msgstr "configuración de la autenticación de doble factor"
msgid "type must be Debian"
-msgstr ""
+msgstr "el tipo debe ser Debian"
msgid "type parameter is missing and is required"
msgstr ""
@@ -40191,7 +40580,7 @@ msgid "user avatar"
msgstr "avatar del usuario"
msgid "user preferences"
-msgstr ""
+msgstr "preferencias de usuario"
msgid "username"
msgstr "usuario"
@@ -40200,10 +40589,10 @@ msgid "v%{version} published %{timeAgo}"
msgstr "v%{version} publicada %{timeAgo}"
msgid "value for '%{storage}' must be an integer"
-msgstr ""
+msgstr "el valor de '%{storage}' debe ser un número entero"
msgid "value for '%{storage}' must be between 0 and 100"
-msgstr ""
+msgstr "el valor de '%{storage}' debe estar entre 0 y 100"
msgid "verify ownership"
msgstr "verificar el propietario"
@@ -40231,8 +40620,8 @@ msgstr ""
msgid "vulnerability"
msgid_plural "vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "vulnerabilidad"
+msgstr[1] "vulnerabilidades"
msgid "vulnerability|Add a comment"
msgstr "Añadir un comentario"
@@ -40247,7 +40636,7 @@ msgid "vulnerability|Add comment & dismiss"
msgstr "Añadir comentario y descartar"
msgid "vulnerability|Add comment and dismiss"
-msgstr ""
+msgstr "Añadir comentario y descartar"
msgid "vulnerability|Dismiss vulnerability"
msgstr "Descartar vulnerabilidad"
@@ -40271,10 +40660,10 @@ msgid "with %{additions} additions, %{deletions} deletions."
msgstr "con %{additions} adiciones, %{deletions} eliminaciones."
msgid "with expiry changing from %{old_expiry} to %{new_expiry}"
-msgstr ""
+msgstr "con el vencimiento cambiado de %{old_expiry} a %{new_expiry}"
msgid "with expiry remaining unchanged at %{old_expiry}"
-msgstr ""
+msgstr "con el vencimiento que permanece sin cambios en %{old_expiry}"
msgid "yaml invalid"
msgstr "El fichero yaml no es válido"
diff --git a/locale/et_EE/gitlab.po b/locale/et_EE/gitlab.po
index 1162b77f0e1..aa0a7833b3d 100644
--- a/locale/et_EE/gitlab.po
+++ b/locale/et_EE/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: et\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:15\n"
+"PO-Revision-Date: 2021-09-01 22:30\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/fa_IR/gitlab.po b/locale/fa_IR/gitlab.po
index 3d04ae1e68b..7d43a9e9f83 100644
--- a/locale/fa_IR/gitlab.po
+++ b/locale/fa_IR/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: fa\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:14\n"
+"PO-Revision-Date: 2021-09-01 22:30\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/fi_FI/gitlab.po b/locale/fi_FI/gitlab.po
index 909f8c26261..93b21bb317a 100644
--- a/locale/fi_FI/gitlab.po
+++ b/locale/fi_FI/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: fi\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:27\n"
+"PO-Revision-Date: 2021-09-01 22:33\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/fil_PH/gitlab.po b/locale/fil_PH/gitlab.po
index 30fc5985974..f08e104b3f0 100644
--- a/locale/fil_PH/gitlab.po
+++ b/locale/fil_PH/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: fil\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:18\n"
+"PO-Revision-Date: 2021-09-01 22:31\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/fr/gitlab.po b/locale/fr/gitlab.po
index 507381ee262..0add0ed26e4 100644
--- a/locale/fr/gitlab.po
+++ b/locale/fr/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: fr\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:24\n"
+"PO-Revision-Date: 2021-09-01 22:32\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] "%{count} participant·e·s"
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,8 +2349,8 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
-msgstr "Vous êtes sur le point d’arrêter toutes les tâches. Toutes les tâches en cours seront interrompues."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
+msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "Erreur lors du chargement des statistiques. Veuillez réessayer"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr "Une erreur est survenue pendant la récupération du journal de la tâche."
@@ -3630,9 +3641,6 @@ msgstr "Une erreur est survenue pendant la récupération des tâches."
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr "Une erreur est survenue pendant la récupération du pipeline."
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr "Artéfacts"
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr "La liste des personnes assignées n’est pas disponible avec votre licence actuelle"
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr "Les listes d’assignation montrent tous les bogues assignés à l’utilisateur sélectionné."
-
msgid "Assignee(s)"
msgstr "Assigné·e(s)"
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr "Commencer avec le commit sélectionné"
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr "Tableaux"
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -6789,7 +6834,7 @@ msgid "CiStatusText|blocked"
msgstr "bloqué"
msgid "CiStatusText|canceled"
-msgstr "annulé "
+msgstr ""
msgid "CiStatusText|created"
msgstr "créé"
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr "Configurer les limites pour les requêtes Web et d’API."
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr "Supprimer le commentaire"
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr "Modifier l’étiquette"
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr "Déploiement"
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr "Environnements"
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr "Les environnements sont des endroits où le code est déployé, tel que l’étape ou la production."
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr "Arrêter l’environnement"
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr "Mis à jour"
msgid "Environments|You don't have any environments right now"
msgstr "Vous n’avez pour le moment aucun environnement"
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr "protégé"
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr "État de Geo"
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr "Dernière vérification"
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr "Pas encore synchronisé"
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr "Statut"
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr "En attente de planification"
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr "Importation depuis GitLab"
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr "Désolé, aucune épopée ne correspond à votre recherche"
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr "La feuille de route affiche la progression de vos épopées dans le temps"
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16564,7 +16696,7 @@ msgid "I accept the %{terms_link}"
msgstr "J’accepte les %{terms_link}"
msgid "I accept the|Terms of Service and Privacy Policy"
-msgstr "Conditions générales d’utilisation et politique de confidentialité"
+msgstr ""
msgid "I forgot my password"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr "Si cette option est désactivée, une branche locale divergente ne sera
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr "Étiquette"
msgid "Label actions dropdown"
msgstr "Menu déroulant des actions sur les étiquettes"
-msgid "Label lists show all issues with the selected label."
-msgstr "Les listes étiquetées affichent tous les tickets ayant l’étiquette sélectionnée."
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr "Dernière réponse de"
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr "Durée maximale d’exécution de la tâche"
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr "Une erreur est survenue lors de l’enregistrement du brouillon du commentaire."
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr "L’enregistrement du commentaire a échoué"
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr "La liste des jalons n’est pas disponible avec votre licence actuelle"
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr "Les listes de jalon affichent tous les tickets à partir du jalon sélectionné."
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21722,7 +21896,7 @@ msgid "More information and share feedback"
msgstr ""
msgid "More information is available|here"
-msgstr "ici"
+msgstr ""
msgid "More information."
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr "Nouvelle branche"
msgid "New branch unavailable"
msgstr "Nouvelle branche indisponible"
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr "novembre"
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr "Ouvert"
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,15 +25362,12 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
-msgstr ""
-
msgid "Prevent adding new members to project membership within this group"
msgstr "Empêcher l’ajout de nouveaux membres au projet au sein de ce groupe"
+msgid "Prevent editing approval rules in projects and merge requests."
+msgstr ""
+
msgid "Prevent environment from auto-stopping"
msgstr ""
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr "Ne pas afficher les informations personnelles liées à l’activité su
msgid "Profiles|Edit Profile"
msgstr "Modifier le profil"
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr "Changement de nom d’utilisateur effectué"
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr "Quel est votre statut ?"
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr "Cette fonctionnalité est verrouillée."
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr "Demandes de fusion liées"
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr "Échec du chargement des résultats de la synthèse des tests"
msgid "Reports|Test summary results are being parsed"
msgstr "Les résultats de la synthèse des tests sont en cours d’analyse"
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr "Vulnérabilité"
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrhestration|No rules defined - policy will not run."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr "Afficher la dernière version"
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr "Taille"
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr "Date de création décroissante"
@@ -31610,7 +31901,7 @@ msgid "Statistics"
msgstr ""
msgid "Status"
-msgstr "État "
+msgstr ""
msgid "Status was retried."
msgstr ""
@@ -32537,7 +32828,7 @@ msgid "TemplateRepository|Select a repository to make its templates available to
msgstr ""
msgid "Templates"
-msgstr "Modèles "
+msgstr ""
msgid "TemporaryStorageIncrease|can only be set once"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr "L’action de mise à jour expirera au bout de %{number_of_minutes} minutes. Pour les gros dépôts, utilisez une combinaison de clone et push."
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr "Ce groupe"
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr "Utilisez une ligne par URI"
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr "Afficher les labels de projet"
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr "Voir le fichier remplacé @ "
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr "Vous pouvez tester votre fichier « .gitlab-ci.yml » avec %{linkStart
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr "Vous ne pouvez pas écrire sur une instance GitLab Geo secondaire en lecture seule. Veuillez utiliser le %{link_to_primary_node} à la place."
@@ -38131,7 +38484,7 @@ msgstr "Vous avez atteint votre limite de projet"
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38632,7 +39009,7 @@ msgid "added a Zoom call to this issue"
msgstr ""
msgid "ago"
-msgstr "auparavant "
+msgstr ""
msgid "alert"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr "nom de la branche"
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr "Fermée"
msgid "mrWidget|Closed by"
msgstr "Fermée par"
-msgid "mrWidget|Closes"
-msgstr "Résout"
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr "Mentionne"
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr "Fusionner"
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr "Ouvrir dans l’EDI Web"
@@ -39718,9 +40107,6 @@ msgstr "Les modifications seront fusionnées dans"
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr "La branche source HEAD a changé récemment. Veuillez recharger la page et vérifier les modifications avant d’effectuer la fusion"
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr "Vous n’êtes pas autorisé à modifier directement ce projet. Veuillez créer un projet divergent afin d’effectuer des changements."
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 5c0a345e534..ae3fbe248bb 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -92,6 +92,16 @@ msgstr ""
msgid "#general, #development"
msgstr ""
+msgid "%d Alert"
+msgid_plural "%d Alerts"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d Alert:"
+msgid_plural "%d Alerts:"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d Approval"
msgid_plural "%d Approvals"
msgstr[0] ""
@@ -549,6 +559,9 @@ msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
msgstr ""
+msgid "%{docs_link_start}Learn about visibility levels.%{docs_link_end}"
+msgstr ""
+
msgid "%{due_date} (Past due)"
msgstr ""
@@ -621,9 +634,6 @@ msgstr ""
msgid "%{issueType} actions"
msgstr ""
-msgid "%{issuesCount} issues with a limit of %{maxIssueCount}"
-msgstr ""
-
msgid "%{issuesSize} with a limit of %{maxIssueCount}"
msgstr ""
@@ -890,6 +900,9 @@ msgstr ""
msgid "%{state} epics"
msgstr ""
+msgid "%{strongOpen}Warning:%{strongClose} SAML group links can cause GitLab to automatically remove members from groups."
+msgstr ""
+
msgid "%{strongStart}Tip:%{strongEnd} You can also checkout merge requests locally by %{linkStart}following these guidelines%{linkEnd}"
msgstr ""
@@ -1193,6 +1206,9 @@ msgstr ""
msgid "."
msgstr ""
+msgid "/"
+msgstr ""
+
msgid "0 bytes"
msgstr ""
@@ -1263,7 +1279,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1479,9 +1495,6 @@ msgstr ""
msgid "A plain HTML site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
msgstr ""
-msgid "A plain-text response to show to clients that hit the rate limit."
-msgstr ""
-
msgid "A platform value can be web, mob or app."
msgstr ""
@@ -1539,10 +1552,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1563,16 +1576,16 @@ msgstr ""
msgid "APIFuzzing|Configure HTTP basic authentication values. Other authentication methods are supported. %{linkStart}Learn more%{linkEnd}."
msgstr ""
-msgid "APIFuzzing|Customize common API fuzzing settings to suit your requirements. For details of more advanced configuration options, see the %{docsLinkStart}GitLab API Fuzzing documentation%{docsLinkEnd}."
+msgid "APIFuzzing|Customize your project's API fuzzing configuration options and copy the code snippet to your .gitlab-ci.yml file to apply any changes. Note that this tool does not reflect or update your .gitlab-ci.yml file automatically. For details of more advanced configuration options, see the %{docsLinkStart}GitLab API Fuzzing documentation%{docsLinkEnd}."
msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -1626,9 +1639,6 @@ msgstr ""
msgid "APIFuzzing|To prevent a security leak, authentication info must be added as a %{ciVariablesLinkStart}CI variable%{ciVariablesLinkEnd}. As a user with maintainer access rights, you can manage CI variables in the %{ciSettingsLinkStart}Settings%{ciSettingsLinkEnd} area."
msgstr ""
-msgid "APIFuzzing|Use this tool to generate API fuzzing configuration YAML to copy into your .gitlab-ci.yml file. This tool does not reflect or update your .gitlab-ci.yml file automatically."
-msgstr ""
-
msgid "APIFuzzing|Username for basic authentication"
msgstr ""
@@ -1719,12 +1729,18 @@ msgstr ""
msgid "Access granted"
msgstr ""
+msgid "Access key ID"
+msgstr ""
+
msgid "Access requests"
msgstr ""
msgid "Access to '%{classification_label}' not allowed"
msgstr ""
+msgid "Access tokens expire after 2 hours. A refresh token may be used at any time to generate a new access token. Non-expiring access tokens are deprecated. Clear this setting to enable backward compatibility."
+msgstr ""
+
msgid "AccessDropdown|Deploy Keys"
msgstr ""
@@ -2856,10 +2872,10 @@ msgstr ""
msgid "Admin|Quarterly reconciliation will occur on %{qrtlyDate}"
msgstr ""
-msgid "Admin|The number of max seats used for your namespace is currently exceeding the number of seats in your subscription. On %{qrtlyDate}, GitLab will process a quarterly reconciliation and automatically bill you a prorated amount for the overage. There is no action needed from you. If you have a credit card on file, it will be charged. Otherwise, you will receive an invoice."
+msgid "Admin|The number of max seats in your namespace exceeds the number of seats in your subscription. On %{qrtlyDate}, quarterly reconciliation occurs and you are automatically billed a prorated amount for the overage. No action is needed from you. If you have a credit card on file, it will be charged. Otherwise, you will receive an invoice. For more information about the timing of the invoicing process, view the documentation."
msgstr ""
-msgid "Admin|The number of maximum users for your instance is currently exceeding the number of users in license. On %{qrtlyDate}, GitLab will process a quarterly reconciliation and automatically bill you a prorated amount for the overage. There is no action needed from you. If you have a credit card on file, it will be charged. Otherwise, you will receive an invoice."
+msgid "Admin|The number of max users in your instance exceeds the number of users in your license. On %{qrtlyDate}, quarterly reconciliation occurs and you are automatically billed a prorated amount for the overage. No action is needed from you. If you have a credit card on file, it will be charged. Otherwise, you will receive an invoice. For more information about the timing of the invoicing process, view the documentation."
msgstr ""
msgid "Admin|View pending user approvals"
@@ -2904,11 +2920,6 @@ msgstr ""
msgid "Akismet API Key"
msgstr ""
-msgid "Alert"
-msgid_plural "Alerts"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3263,6 +3274,9 @@ msgstr ""
msgid "All (default)"
msgstr ""
+msgid "All GitLab"
+msgstr ""
+
msgid "All Members"
msgstr ""
@@ -3515,12 +3529,6 @@ msgstr ""
msgid "An error occurred when removing the label."
msgstr ""
-msgid "An error occurred when toggling the notification subscription"
-msgstr ""
-
-msgid "An error occurred when updating the issue weight"
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3617,18 +3625,12 @@ msgstr ""
msgid "An error occurred while fetching reference"
msgstr ""
-msgid "An error occurred while fetching sidebar data"
-msgstr ""
-
msgid "An error occurred while fetching tags. Retry the search."
msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3698,6 +3700,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4373,6 +4381,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4531,9 +4542,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4650,9 +4658,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4769,10 +4774,13 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
-msgid "Authenticated web rate limit period in seconds"
+msgid "Authenticated Git LFS rate limit period in seconds"
msgstr ""
-msgid "Authenticated web request rate limit"
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
+msgid "Authenticated web rate limit period in seconds"
msgstr ""
msgid "Authenticated web requests"
@@ -5141,9 +5149,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5395,6 +5400,21 @@ msgstr ""
msgid "Board scope affects which issues are displayed for anyone who visits this board"
msgstr ""
+msgid "BoardNewEpic|Groups"
+msgstr ""
+
+msgid "BoardNewEpic|Loading groups"
+msgstr ""
+
+msgid "BoardNewEpic|No matching results"
+msgstr ""
+
+msgid "BoardNewEpic|Search groups"
+msgstr ""
+
+msgid "BoardNewEpic|Select a group"
+msgstr ""
+
msgid "BoardNewIssue|No matching results"
msgstr ""
@@ -5472,6 +5492,9 @@ msgstr ""
msgid "Boards|An error occurred while creating the list. Please try again."
msgstr ""
+msgid "Boards|An error occurred while fetching child groups. Please try again."
+msgstr ""
+
msgid "Boards|An error occurred while fetching group projects. Please try again."
msgstr ""
@@ -5513,9 +5536,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5807,6 +5827,9 @@ msgstr ""
msgid "Bulk update"
msgstr ""
+msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Existing groups"
msgstr ""
@@ -5828,6 +5851,9 @@ msgstr ""
msgid "BulkImport|Importing the group failed"
msgstr ""
+msgid "BulkImport|Last imported to %{link}"
+msgstr ""
+
msgid "BulkImport|Name already exists."
msgstr ""
@@ -5888,6 +5914,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6193,6 +6222,9 @@ msgstr ""
msgid "Cancelling Preview"
msgstr ""
+msgid "Cannot assign a confidential epic to a non-confidential issue. Make the issue confidential and try again"
+msgstr ""
+
msgid "Cannot be assigned to other projects."
msgstr ""
@@ -6244,9 +6276,6 @@ msgstr ""
msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
-msgid "Cannot set confidential epic for a non-confidential issue"
-msgstr ""
-
msgid "Cannot show preview. For previews on sketch files, they must have the file format introduced by Sketch version 43 and above."
msgstr ""
@@ -7142,6 +7171,12 @@ msgstr ""
msgid "ClusterAgents|Access tokens"
msgstr ""
+msgid "ClusterAgents|Agent might not be connected to GitLab"
+msgstr ""
+
+msgid "ClusterAgents|Agent never connected to GitLab"
+msgstr ""
+
msgid "ClusterAgents|Alternative installation methods"
msgstr ""
@@ -7157,6 +7192,12 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
+msgid "ClusterAgents|Connected"
+msgstr ""
+
+msgid "ClusterAgents|Connection status"
+msgstr ""
+
msgid "ClusterAgents|Copy token"
msgstr ""
@@ -7175,6 +7216,9 @@ msgstr ""
msgid "ClusterAgents|For alternative installation methods %{linkStart}go to the documentation%{linkEnd}."
msgstr ""
+msgid "ClusterAgents|For more troubleshooting information go to"
+msgstr ""
+
msgid "ClusterAgents|Go to the repository"
msgstr ""
@@ -7190,18 +7234,33 @@ msgstr ""
msgid "ClusterAgents|Integrate with the GitLab Agent"
msgstr ""
+msgid "ClusterAgents|Last connected %{timeAgo}."
+msgstr ""
+
+msgid "ClusterAgents|Last contact"
+msgstr ""
+
msgid "ClusterAgents|Last used"
msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
+msgid "ClusterAgents|Make sure you are using a valid token."
+msgstr ""
+
msgid "ClusterAgents|Name"
msgstr ""
msgid "ClusterAgents|Never"
msgstr ""
+msgid "ClusterAgents|Never connected"
+msgstr ""
+
+msgid "ClusterAgents|Not connected"
+msgstr ""
+
msgid "ClusterAgents|Read more about getting started"
msgstr ""
@@ -7223,6 +7282,9 @@ msgstr ""
msgid "ClusterAgents|Select which Agent you want to install"
msgstr ""
+msgid "ClusterAgents|The Agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
+msgstr ""
+
msgid "ClusterAgents|The GitLab Agent also requires %{linkStart}enabling the Agent Server%{linkEnd}"
msgstr ""
@@ -7442,9 +7504,6 @@ msgstr ""
msgid "ClusterIntegration|Create Kubernetes cluster"
msgstr ""
-msgid "ClusterIntegration|Create a provision role on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the account and external ID above. %{startMoreInfoLink}More information%{endLink}"
-msgstr ""
-
msgid "ClusterIntegration|Create cluster on"
msgstr ""
@@ -7877,7 +7936,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{awsLinkStart}Amazon Web Services %{awsLinkEnd} using the above account and external IDs. %{moreInfoStart}More information%{moreInfoEnd}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8111,6 +8170,9 @@ msgstr ""
msgid "Collapse replies"
msgstr ""
+msgid "Collapse settings section"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -8129,6 +8191,9 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
+msgid "Comma-separated list of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -8485,19 +8550,10 @@ msgstr ""
msgid "Configure a %{codeStart}.gitlab-webide.yml%{codeEnd} file in the %{codeStart}.gitlab%{codeEnd} directory to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
-msgid "Configure existing installation"
+msgid "Configure approvals by authors and committers on all projects."
msgstr ""
-msgid "Configure limit for notes created per minute by web and API requests."
-msgstr ""
-
-msgid "Configure limits for Project/Group Import/Export."
-msgstr ""
-
-msgid "Configure limits for web and API requests."
-msgstr ""
-
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
+msgid "Configure existing installation"
msgstr ""
msgid "Configure paths to be protected by Rack Attack."
@@ -8512,7 +8568,10 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
-msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
+msgid "Configure specific limits for Files API requests that supersede the general user and IP rate limits."
+msgstr ""
+
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
msgstr ""
msgid "Configure the %{link} integration."
@@ -9208,6 +9267,9 @@ msgstr ""
msgid "Copy value"
msgstr ""
+msgid "Corpus Management"
+msgstr ""
+
msgid "Corpus Management|Are you sure you want to delete the corpus?"
msgstr ""
@@ -9469,6 +9531,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create issue to resolve all threads"
+msgstr ""
+
msgid "Create iteration"
msgstr ""
@@ -9523,6 +9588,9 @@ msgstr ""
msgid "Create new..."
msgstr ""
+msgid "Create or import your first project"
+msgstr ""
+
msgid "Create project"
msgstr ""
@@ -10316,6 +10384,9 @@ msgstr ""
msgid "DastProfiles|Manage profiles"
msgstr ""
+msgid "DastProfiles|Manage site profiles"
+msgstr ""
+
msgid "DastProfiles|Minimum = 0 (no timeout enabled), Maximum = 2880 minutes"
msgstr ""
@@ -10391,6 +10462,9 @@ msgstr ""
msgid "DastProfiles|Scanner name"
msgstr ""
+msgid "DastProfiles|Schedule"
+msgstr ""
+
msgid "DastProfiles|Select branch"
msgstr ""
@@ -10460,7 +10534,7 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
-msgid "DastProfiles|You can either choose a passive scan or validate the target site in your chosen site profile. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
+msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
@@ -10663,9 +10737,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10723,10 +10794,10 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
-msgid "Define approval settings."
+msgid "Define approval rules."
msgstr ""
-msgid "Define approval settings. %{linkStart}Learn more.%{linkEnd}"
+msgid "Define approval rules. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Define custom rules for what constitutes spam, independent of Akismet"
@@ -10735,6 +10806,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied to merge requests."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10747,6 +10821,12 @@ msgstr ""
msgid "DelayedJobs|Are you sure you want to run %{job_name} immediately? This job will run automatically after it's timer finishes."
msgstr ""
+msgid "DelayedJobs|Are you sure you want to run %{job_name} immediately? This job will run automatically after its timer finishes."
+msgstr ""
+
+msgid "DelayedJobs|Run the delayed job now?"
+msgstr ""
+
msgid "DelayedJobs|Start now"
msgstr ""
@@ -10783,6 +10863,9 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
@@ -10813,6 +10896,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10831,6 +10917,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -11059,6 +11148,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11487,6 +11588,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11667,6 +11774,16 @@ msgstr ""
msgid "DiffsCompareBaseBranch|(base)"
msgstr ""
+msgid "Diffs|%d addition"
+msgid_plural "Diffs|%d additions"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Diffs|%d deletion"
+msgid_plural "Diffs|%d deletions"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Diffs|No file name available"
msgstr ""
@@ -11676,9 +11793,17 @@ msgstr ""
msgid "Diffs|Show all unchanged lines"
msgstr ""
+msgid "Diffs|Showing %{dropdownStart}%{count} changed file%{dropdownEnd}"
+msgid_plural "Diffs|Showing %{dropdownStart}%{count} changed files%{dropdownEnd}"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Diffs|Something went wrong while fetching diff lines."
msgstr ""
+msgid "Diffs|with %{additions} and %{deletions}"
+msgstr ""
+
msgid "Direct member"
msgstr ""
@@ -11804,9 +11929,6 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
-msgid "Dismiss Value Stream Analytics introduction box"
-msgstr ""
-
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12056,6 +12178,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12131,6 +12256,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12326,6 +12454,9 @@ msgstr ""
msgid "Enable"
msgstr ""
+msgid "Enable Amazon EKS integration"
+msgstr ""
+
msgid "Enable Auto DevOps"
msgstr ""
@@ -12338,9 +12469,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12389,6 +12517,12 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
+msgid "Enable authenticated web request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12428,6 +12562,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12491,7 +12628,10 @@ msgstr ""
msgid "Enable unauthenticated API request rate limit"
msgstr ""
-msgid "Enable unauthenticated request rate limit"
+msgid "Enable unauthenticated web request rate limit"
+msgstr ""
+
+msgid "Enable user deactivation emails"
msgstr ""
msgid "Enable version check"
@@ -12782,9 +12922,6 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
-msgid "Environments|Dismiss"
-msgstr ""
-
msgid "Environments|Enable review app"
msgstr ""
@@ -12797,9 +12934,6 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
-msgid "Environments|Help us improve environments"
-msgstr ""
-
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12875,9 +13009,6 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
-msgid "Environments|Take the survey"
-msgstr ""
-
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12899,7 +13030,7 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
-msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgid "Environments|by %{avatar}"
msgstr ""
msgid "Environments|protected"
@@ -13229,6 +13360,9 @@ msgstr ""
msgid "Error: %{error_message}"
msgstr ""
+msgid "Error: Couldn't load some or all of the changes."
+msgstr ""
+
msgid "Error: No AWS credentials were supplied"
msgstr ""
@@ -13238,6 +13372,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -13259,6 +13396,9 @@ msgstr ""
msgid "ErrorTracking|Enable error tracking"
msgstr ""
+msgid "ErrorTracking|Error tracking backend"
+msgstr ""
+
msgid "ErrorTracking|If you self-host Sentry, enter your Sentry instance's full URL. If you use Sentry's hosted solution, enter https://sentry.io"
msgstr ""
@@ -13292,6 +13432,12 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
+msgstr ""
+
+msgid "EscalationPolicies|%{notificationIcon} THEN %{doAction} %{forScheduleOrUser}"
+msgstr ""
+
msgid "EscalationPolicies|+ Add an additional rule"
msgstr ""
@@ -13340,9 +13486,6 @@ msgstr ""
msgid "EscalationPolicies|Failed to load oncall-schedules"
msgstr ""
-msgid "EscalationPolicies|IF alert is not %{alertStatus} in %{minutes} %{then} THEN %{doAction} %{scheduleOrUser}"
-msgstr ""
-
msgid "EscalationPolicies|IF alert is not %{alertStatus} in %{minutes} minutes"
msgstr ""
@@ -13418,18 +13561,36 @@ msgstr ""
msgid "Every %{action} attempt has failed: %{job_error_message}. Please try again."
msgstr ""
+msgid "Every 3 months"
+msgstr ""
+
+msgid "Every 3 months on the %{day} at %{time} %{timezone}"
+msgstr ""
+
+msgid "Every 6 months"
+msgstr ""
+
+msgid "Every 6 months on the %{day} at %{time} %{timezone}"
+msgstr ""
+
msgid "Every day"
msgstr ""
msgid "Every day (at %{time})"
msgstr ""
+msgid "Every day at %{time} %{timezone}"
+msgstr ""
+
msgid "Every month"
msgstr ""
msgid "Every month (Day %{day} at %{time})"
msgstr ""
+msgid "Every month on the %{day} at %{time} %{timezone}"
+msgstr ""
+
msgid "Every three months"
msgstr ""
@@ -13444,6 +13605,15 @@ msgstr[1] ""
msgid "Every week (%{weekday} at %{time})"
msgstr ""
+msgid "Every week on %{day} at %{time} %{timezone}"
+msgstr ""
+
+msgid "Every year"
+msgstr ""
+
+msgid "Every year on %{day} at %{time} %{timezone}"
+msgstr ""
+
msgid "Everyone"
msgstr ""
@@ -13549,13 +13719,13 @@ msgstr ""
msgid "Expand pipeline"
msgstr ""
-msgid "Expand sidebar"
+msgid "Expand settings section"
msgstr ""
-msgid "Expected documents: %{expected_documents}"
+msgid "Expand sidebar"
msgstr ""
-msgid "Experienced"
+msgid "Expected documents: %{expected_documents}"
msgstr ""
msgid "ExperimentSubject|Must have exactly one of User, Namespace, or Project."
@@ -13840,9 +14010,6 @@ msgstr ""
msgid "Failed to load related branches"
msgstr ""
-msgid "Failed to load sidebar lock status"
-msgstr ""
-
msgid "Failed to load stacktrace."
msgstr ""
@@ -14267,6 +14434,9 @@ msgstr ""
msgid "Files"
msgstr ""
+msgid "Files API Rate Limits"
+msgstr ""
+
msgid "Files breadcrumb"
msgstr ""
@@ -14834,10 +15004,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14882,7 +15052,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14903,9 +15073,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14966,10 +15133,10 @@ msgstr ""
msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -15014,7 +15181,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -15026,6 +15193,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -15050,10 +15220,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15125,7 +15295,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15170,6 +15340,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15224,9 +15397,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15281,7 +15451,7 @@ msgstr ""
msgid "GitLab is open source software to collaborate on code."
msgstr ""
-msgid "GitLab is undergoing maintenance and is operating in a read-only mode."
+msgid "GitLab is undergoing maintenance and is operating in read-only mode."
msgstr ""
msgid "GitLab member or Email address"
@@ -15476,6 +15646,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15557,7 +15730,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15908,6 +16081,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15920,6 +16099,12 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
+msgid "GroupSAML|\"persistent\" recommended"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -16052,6 +16237,9 @@ msgstr ""
msgid "GroupSAML|To be able to prohibit outer forks, you first need to enforce dedicate group managed accounts."
msgstr ""
+msgid "GroupSAML|Use SAML group links to manage group membership using SAML."
+msgstr ""
+
msgid "GroupSAML|Valid SAML Response"
msgstr ""
@@ -16064,13 +16252,10 @@ msgstr ""
msgid "GroupSAML|as %{access_level}"
msgstr ""
-msgid "GroupSAML|must match stored NameID of \"%{extern_uid}\" as we use this to identify users. If the NameID changes users will be unable to sign in."
-msgstr ""
-
-msgid "GroupSAML|should be \"persistent\""
+msgid "GroupSAML|must match stored NameID of \"%{extern_uid}\" to identify user and allow sign in"
msgstr ""
-msgid "GroupSAML|should be a random persistent ID, emails are discouraged"
+msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
msgid "GroupSelect|No matching results"
@@ -16457,9 +16642,6 @@ msgstr ""
msgid "Hello %{name},"
msgstr ""
-msgid "Hello there"
-msgstr ""
-
msgid "Hello, %{name}!"
msgstr ""
@@ -16481,10 +16663,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16617,6 +16799,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16632,10 +16817,10 @@ msgstr ""
msgid "How many seconds an IP will be counted towards the limit"
msgstr ""
-msgid "I accept the %{terms_link}"
+msgid "How the job limiter handles jobs exceeding the thresholds specified below. The 'track' mode only logs the jobs. The 'compress' mode compresses the jobs and raises an exception if the compressed size exceeds the limit."
msgstr ""
-msgid "I accept the|Terms of Service and Privacy Policy"
+msgid "I accept the %{terms_link}"
msgstr ""
msgid "I forgot my password"
@@ -16740,6 +16925,9 @@ msgstr ""
msgid "If any indexed field exceeds this limit it will be truncated to this number of characters and the rest will not be indexed or searchable. This does not apply to repository and wiki indexing. Setting this to 0 means it is unlimited."
msgstr ""
+msgid "If blank, defaults to %{code_open}Retry later%{code_close}."
+msgstr ""
+
msgid "If blank, set allowable lifetime to %{instance_level_policy_in_words}, as defined by the instance admin. Once set, existing tokens for users in this group may be revoked."
msgstr ""
@@ -16755,7 +16943,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16791,6 +16979,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
+msgstr ""
+
msgid "If you did not initiate this change, please contact your administrator immediately."
msgstr ""
@@ -16882,10 +17073,10 @@ msgstr ""
msgid "Import Projects from Gitea"
msgstr ""
-msgid "Import a project"
+msgid "Import an exported GitLab project"
msgstr ""
-msgid "Import an exported GitLab project"
+msgid "Import and export rate limits"
msgstr ""
msgid "Import failed due to a GitHub error: %{original}"
@@ -16966,7 +17157,25 @@ msgstr ""
msgid "Import timed out. Import took longer than %{import_jobs_expiration} seconds"
msgstr ""
-msgid "Import/Export Rate Limits"
+msgid "ImportAProjectModal|Import from a project"
+msgstr ""
+
+msgid "ImportAProjectModal|Import members from another project"
+msgstr ""
+
+msgid "ImportAProjectModal|Import project members"
+msgstr ""
+
+msgid "ImportAProjectModal|Only project members (not group members) are imported, and they get the same permissions as the project you import from."
+msgstr ""
+
+msgid "ImportAProjectModal|Successfully imported"
+msgstr ""
+
+msgid "ImportAProjectModal|Unable to import project members"
+msgstr ""
+
+msgid "ImportAProjectModal|You're importing members to the %{strongStart}%{name}%{strongEnd} project."
msgstr ""
msgid "ImportButtons|Connect repositories from"
@@ -17028,9 +17237,6 @@ msgstr ""
msgid "Improves Git cloning performance."
msgstr ""
-msgid "In %{time_to_now}"
-msgstr ""
-
msgid "In case of pull mirroring, your user will be the author of all events in the activity feed that are the result of an update, like new branches being created or new commits being pushed to existing branches."
msgstr ""
@@ -17355,7 +17561,7 @@ msgstr ""
msgid "InProductMarketing|Team up in GitLab for greater efficiency"
msgstr ""
-msgid "InProductMarketing|Team work makes the dream work"
+msgid "InProductMarketing|Team work makes the dream work"
msgstr ""
msgid "InProductMarketing|Test, create, deploy"
@@ -17805,6 +18011,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17814,6 +18026,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -18086,9 +18304,6 @@ msgstr ""
msgid "Interval Pattern"
msgstr ""
-msgid "Introducing Value Stream Analytics"
-msgstr ""
-
msgid "Introducing Your DevOps Report"
msgstr ""
@@ -18638,12 +18853,18 @@ msgstr ""
msgid "Issues"
msgstr ""
+msgid "Issues I've created"
+msgstr ""
+
msgid "Issues Rate Limits"
msgstr ""
msgid "Issues and merge requests"
msgstr ""
+msgid "Issues assigned to me"
+msgstr ""
+
msgid "Issues can be bugs, tasks or ideas to be discussed. Also, issues are searchable and filterable."
msgstr ""
@@ -18755,12 +18976,18 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
msgid "Iterations|Delete iteration cadence?"
msgstr ""
+msgid "Iterations|Delete iteration?"
+msgstr ""
+
msgid "Iterations|Duration"
msgstr ""
@@ -18794,12 +19021,18 @@ msgstr ""
msgid "Iterations|New iteration cadence"
msgstr ""
+msgid "Iterations|No closed iterations."
+msgstr ""
+
msgid "Iterations|No iteration cadences to show."
msgstr ""
msgid "Iterations|No iterations in cadence."
msgstr ""
+msgid "Iterations|No open iterations."
+msgstr ""
+
msgid "Iterations|Number of future iterations you would like to have scheduled"
msgstr ""
@@ -18830,6 +19063,9 @@ msgstr ""
msgid "Iterations|This will delete the cadence as well as all of the iterations within it."
msgstr ""
+msgid "Iterations|This will remove the iteration from any issues that are assigned to it."
+msgstr ""
+
msgid "Iterations|Title"
msgstr ""
@@ -18845,15 +19081,9 @@ msgstr ""
msgid "Iteration|cannot be more than 500 years in the future"
msgstr ""
-msgid "I’m familiar with the basics of DevOps."
-msgstr ""
-
msgid "I’m joining my team who’s already on GitLab"
msgstr ""
-msgid "I’m not familiar with the basics of DevOps."
-msgstr ""
-
msgid "Jaeger URL"
msgstr ""
@@ -19118,6 +19348,9 @@ msgstr ""
msgid "Job"
msgstr ""
+msgid "Job %{jobName}"
+msgstr ""
+
msgid "Job Failed #%{build_id}"
msgstr ""
@@ -19448,9 +19681,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19573,9 +19803,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19594,6 +19821,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19711,9 +19941,6 @@ msgstr ""
msgid "Learn more in the"
msgstr ""
-msgid "Learn more in the|pipeline schedules documentation"
-msgstr ""
-
msgid "Learn more."
msgstr ""
@@ -20035,17 +20262,26 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
+msgid "Limit the size of Sidekiq jobs stored in Redis."
+msgstr ""
+
msgid "Limited to showing %d event at most"
msgid_plural "Limited to showing %d events at most"
msgstr[0] ""
msgstr[1] ""
+msgid "Limiting mode"
+msgstr ""
+
msgid "Line changes"
msgstr ""
@@ -20115,9 +20351,6 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
-msgid "List of users to be excluded from the limit"
-msgstr ""
-
msgid "List options"
msgstr ""
@@ -20157,9 +20390,6 @@ msgstr ""
msgid "Loading functions timed out. Please reload the page to try again."
msgstr ""
-msgid "Loading issues"
-msgstr ""
-
msgid "Loading more"
msgstr ""
@@ -20451,6 +20681,9 @@ msgstr ""
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
+msgid "Marked as ready. Merging is now allowed."
+msgstr ""
+
msgid "Marked this %{noun} as a draft."
msgstr ""
@@ -20526,45 +20759,18 @@ msgstr ""
msgid "Max 20 characters"
msgstr ""
-msgid "Max Group Export Download requests per minute per user"
-msgstr ""
-
-msgid "Max Group Export requests per minute per user"
-msgstr ""
-
-msgid "Max Group Import requests per minute per user"
-msgstr ""
-
-msgid "Max Project Export Download requests per minute per user"
-msgstr ""
-
-msgid "Max Project Export requests per minute per user"
-msgstr ""
-
-msgid "Max Project Import requests per minute per user"
-msgstr ""
-
-msgid "Max authenticated API requests per period per user"
-msgstr ""
-
-msgid "Max authenticated web requests per period per user"
+msgid "Max authenticated Git LFS requests per period per user"
msgstr ""
msgid "Max file size is 200 KB."
msgstr ""
-msgid "Max requests per minute per user"
-msgstr ""
-
msgid "Max role"
msgstr ""
msgid "Max session time"
msgstr ""
-msgid "Max unauthenticated requests per period per IP"
-msgstr ""
-
msgid "MaxBuilds"
msgstr ""
@@ -20595,9 +20801,18 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
+msgid "Maximum authenticated API requests per rate limit period per user"
+msgstr ""
+
+msgid "Maximum authenticated web requests per rate limit period per user"
+msgstr ""
+
msgid "Maximum bulk request size (MiB)"
msgstr ""
@@ -20613,6 +20828,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20640,9 +20858,24 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum group export download requests per minute"
+msgstr ""
+
+msgid "Maximum group export requests per minute"
+msgstr ""
+
+msgid "Maximum group import requests per minute"
+msgstr ""
+
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20676,9 +20909,27 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum project export download requests per minute"
+msgstr ""
+
+msgid "Maximum project export requests per minute"
+msgstr ""
+
+msgid "Maximum project import requests per minute"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per minute"
+msgstr ""
+
msgid "Maximum running slices"
msgstr ""
@@ -20700,6 +20951,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20709,6 +20963,12 @@ msgstr ""
msgid "Maximum time that users are allowed to skip the setup of two-factor authentication (in hours). Set to 0 (zero) to enforce at next sign in."
msgstr ""
+msgid "Maximum unauthenticated API requests per rate limit period per IP"
+msgstr ""
+
+msgid "Maximum unauthenticated web requests per rate limit period per IP"
+msgstr ""
+
msgid "May"
msgstr ""
@@ -20724,9 +20984,6 @@ msgstr ""
msgid "Medium vulnerabilities present"
msgstr ""
-msgid "Member lock"
-msgstr ""
-
msgid "Member since"
msgstr ""
@@ -20739,6 +20996,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20760,6 +21020,9 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "Membership"
+msgstr ""
+
msgid "Members|%{time} by %{user}"
msgstr ""
@@ -20940,9 +21203,6 @@ msgstr ""
msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
msgstr ""
-msgid "Merge request (MR) approvals"
-msgstr ""
-
msgid "Merge request analytics"
msgstr ""
@@ -20964,12 +21224,21 @@ msgstr ""
msgid "Merge requests"
msgstr ""
+msgid "Merge requests I've created"
+msgstr ""
+
msgid "Merge requests are a place to propose changes you've made to a project and discuss those changes with others"
msgstr ""
msgid "Merge requests are read-only in a secondary Geo node"
msgstr ""
+msgid "Merge requests assigned to me"
+msgstr ""
+
+msgid "Merge requests that I'm a reviewer"
+msgstr ""
+
msgid "Merge the branch and fix any conflicts that come up"
msgstr ""
@@ -21027,24 +21296,18 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Resolve this thread in a new issue"
+msgid "MergeRequests|Failed to squash. Should be done manually."
msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21526,9 +21789,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21907,7 +22167,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22023,9 +22283,6 @@ msgstr ""
msgid "Network"
msgstr ""
-msgid "Network Policy|New rule"
-msgstr ""
-
msgid "NetworkPolicies|%{ifLabelStart}if%{ifLabelEnd} %{ruleType} %{isLabelStart}is%{isLabelEnd} %{ruleDirection} %{ruleSelector} %{directionLabelStart}and is inbound from a%{directionLabelEnd} %{rule} %{portsLabelStart}on%{portsLabelEnd} %{ports}"
msgstr ""
@@ -22047,16 +22304,13 @@ msgstr ""
msgid "NetworkPolicies|%{strongOpen}any%{strongClose} port"
msgstr ""
-msgid "NetworkPolicies|+ Add alert"
-msgstr ""
-
msgid "NetworkPolicies|.yaml"
msgstr ""
msgid "NetworkPolicies|.yaml mode"
msgstr ""
-msgid "NetworkPolicies|Actions"
+msgid "NetworkPolicies|Add alert"
msgstr ""
msgid "NetworkPolicies|Alerts are intended to be selectively used for a limited number of events that are potentially concerning and warrant a manual review. Alerts should not be used as a substitute for a SIEM or a logging tool. High volume alerts are likely to be dropped so as to preserve the stability of GitLab's integration with Kubernetes."
@@ -22092,9 +22346,6 @@ msgstr ""
msgid "NetworkPolicies|Deny all traffic"
msgstr ""
-msgid "NetworkPolicies|Description"
-msgstr ""
-
msgid "NetworkPolicies|Edit policy"
msgstr ""
@@ -22119,10 +22370,13 @@ msgstr ""
msgid "NetworkPolicies|Kubernetes error: %{error}"
msgstr ""
-msgid "NetworkPolicies|Name"
+msgid "NetworkPolicies|Network"
+msgstr ""
+
+msgid "NetworkPolicies|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
msgstr ""
-msgid "NetworkPolicies|Network"
+msgid "NetworkPolicies|Network policy can be created after the environment is loaded successfully."
msgstr ""
msgid "NetworkPolicies|Network traffic"
@@ -22149,21 +22403,9 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
-msgid "NetworkPolicies|Policy preview"
-msgstr ""
-
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22173,9 +22415,6 @@ msgstr ""
msgid "NetworkPolicies|Rule mode is unavailable for this policy. In some cases, we cannot parse the YAML file back into the rules editor."
msgstr ""
-msgid "NetworkPolicies|Rules"
-msgstr ""
-
msgid "NetworkPolicies|Save changes"
msgstr ""
@@ -22188,9 +22427,6 @@ msgstr ""
msgid "NetworkPolicies|Traffic that does not match any rule will be blocked."
msgstr ""
-msgid "NetworkPolicies|Unable to parse policy"
-msgstr ""
-
msgid "NetworkPolicies|all DNS names"
msgstr ""
@@ -22763,8 +22999,10 @@ msgstr ""
msgid "No webhooks found, add one in the form above."
msgstr ""
-msgid "No worries, you can still use all the %{strong}%{plan_name}%{strong_close} features for now. You have %{remaining_days} to renew your subscription."
-msgstr ""
+msgid "No worries, you can still use all the %{strong}%{plan_name}%{strong_close} features for now. You have %{remaining_days} day to renew your subscription."
+msgid_plural "No worries, you can still use all the %{strong}%{plan_name}%{strong_close} features for now. You have %{remaining_days} days to renew your subscription."
+msgstr[0] ""
+msgstr[1] ""
msgid "No. of commits"
msgstr ""
@@ -22781,7 +23019,7 @@ msgstr ""
msgid "Nodes"
msgstr ""
-msgid "Non-admin users can sign in with read-only access and make read-only API requests."
+msgid "Non-admin users are restricted to read-only access, in both GitLab UI and API."
msgstr ""
msgid "None"
@@ -22862,7 +23100,7 @@ msgstr ""
msgid "NoteForm|Note"
msgstr ""
-msgid "Notes Rate Limits"
+msgid "Notes rate limit"
msgstr ""
msgid "Notes|Are you sure you want to cancel creating this comment?"
@@ -23029,7 +23267,7 @@ msgstr ""
msgid "November"
msgstr ""
-msgid "Novice"
+msgid "Now, personalize your GitLab experience"
msgstr ""
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
@@ -23344,22 +23582,22 @@ msgstr ""
msgid "OnDemandScans|Scanner profile"
msgstr ""
-msgid "OnDemandScans|Select one of the existing profiles"
+msgid "OnDemandScans|Schedule scan"
msgstr ""
-msgid "OnDemandScans|Site profile"
+msgid "OnDemandScans|Select one of the existing profiles"
msgstr ""
-msgid "OnDemandScans|Use existing scanner profile"
+msgid "OnDemandScans|Site profile"
msgstr ""
-msgid "OnDemandScans|Use existing site profile"
+msgid "OnDemandScans|Start time"
msgstr ""
-msgid "OnDemandScans|You can either choose a passive scan or validate the target site in your chosen site profile. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
+msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
-msgid "OnDemandScans|You cannot run an active scan against an unvalidated site."
+msgid "OnDemandScans|Use existing site profile"
msgstr ""
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
@@ -23628,9 +23866,6 @@ msgstr ""
msgid "Package Registry"
msgstr ""
-msgid "Package Registry Rate Limits"
-msgstr ""
-
msgid "Package Registry: authenticated API requests"
msgstr ""
@@ -23649,6 +23884,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package registry rate limits"
+msgstr ""
+
msgid "Package type"
msgstr ""
@@ -23715,6 +23953,9 @@ msgstr ""
msgid "PackageRegistry|Composer"
msgstr ""
+msgid "PackageRegistry|Composer.json with license: %{license} and version: %{version}"
+msgstr ""
+
msgid "PackageRegistry|Conan"
msgstr ""
@@ -23778,6 +24019,9 @@ msgstr ""
msgid "PackageRegistry|Copy require package include"
msgstr ""
+msgid "PackageRegistry|Copy target SHA"
+msgstr ""
+
msgid "PackageRegistry|Copy yarn command"
msgstr ""
@@ -23910,6 +24154,9 @@ msgstr ""
msgid "PackageRegistry|Remove package"
msgstr ""
+msgid "PackageRegistry|Required Python: %{pythonVersion}"
+msgstr ""
+
msgid "PackageRegistry|RubyGems"
msgstr ""
@@ -23952,6 +24199,9 @@ msgstr ""
msgid "PackageRegistry|Source project located at %{link}"
msgstr ""
+msgid "PackageRegistry|Target SHA: %{sha}"
+msgstr ""
+
msgid "PackageRegistry|There are no other versions of this package."
msgstr ""
@@ -24909,6 +25159,9 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plain-text response to send to clients that hit a rate limit"
+msgstr ""
+
msgid "Plan:"
msgstr ""
@@ -25290,7 +25543,7 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from performing write operations on GitLab while performing maintenance."
+msgid "Prevent users from performing write operations while GitLab maintenance is in progress."
msgstr ""
msgid "Preview"
@@ -25797,10 +26050,10 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|username"
+msgid "Profiles|https://website.com"
msgstr ""
-msgid "Profiles|website.com"
+msgid "Profiles|username"
msgstr ""
msgid "Profiles|your account"
@@ -26043,9 +26296,21 @@ msgstr ""
msgid "ProjectSelect| or group"
msgstr ""
+msgid "ProjectSelect|No matching results"
+msgstr ""
+
msgid "ProjectSelect|Search for project"
msgstr ""
+msgid "ProjectSelect|Search projects"
+msgstr ""
+
+msgid "ProjectSelect|Select a project"
+msgstr ""
+
+msgid "ProjectSelect|There was an error fetching the projects. Please try again."
+msgstr ""
+
msgid "ProjectService|Drone server URL"
msgstr ""
@@ -26133,6 +26398,9 @@ msgstr ""
msgid "ProjectService|Trigger event when a new, unique alert is recorded."
msgstr ""
+msgid "ProjectService|Trigger event when a new, unique vulnerability is recorded. (Note: This feature requires an Ultimate plan.)"
+msgstr ""
+
msgid "ProjectService|Trigger event when a pipeline status changes."
msgstr ""
@@ -26547,9 +26815,15 @@ msgstr ""
msgid "Projects are graded based on the highest severity vulnerability present"
msgstr ""
+msgid "Projects are organized into groups"
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
+msgid "Projects help you organize your work. They contain your file repository, issues, merge requests, and so much more."
+msgstr ""
+
msgid "Projects shared with %{group_name}"
msgstr ""
@@ -26784,10 +27058,10 @@ msgstr ""
msgid "PrometheusService|Prometheus cluster integration"
msgstr ""
-msgid "PrometheusService|PrometheusService|The ID of the IAP-secured resource."
+msgid "PrometheusService|Select this checkbox to override the auto configuration settings with your own settings."
msgstr ""
-msgid "PrometheusService|Select this checkbox to override the auto configuration settings with your own settings."
+msgid "PrometheusService|The ID of the IAP-secured resource."
msgstr ""
msgid "PrometheusService|The Prometheus API base URL."
@@ -27405,6 +27679,9 @@ msgstr ""
msgid "Rate limit"
msgstr ""
+msgid "Rate limits can help reduce request volume (like from crawlers or abusive bots)."
+msgstr ""
+
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -27417,6 +27694,9 @@ msgstr ""
msgid "Re-authentication required"
msgstr ""
+msgid "Re-import"
+msgstr ""
+
msgid "Re-request review"
msgstr ""
@@ -27441,6 +27721,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27510,6 +27796,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27605,9 +27894,6 @@ msgstr ""
msgid "Registry setup"
msgstr ""
-msgid "Regulate approvals by authors/committers. Affects all projects."
-msgstr ""
-
msgid "Reindexing Status: %{status} (Slice multiplier: %{multiplier}, Maximum running slices: %{max_slices})"
msgstr ""
@@ -27623,6 +27909,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -27700,6 +27989,9 @@ msgstr ""
msgid "Release|Something went wrong while saving the release details."
msgstr ""
+msgid "Reload page"
+msgstr ""
+
msgid "Remediations"
msgstr ""
@@ -27982,6 +28274,9 @@ msgstr ""
msgid "Reopens this %{quick_action_target}."
msgstr ""
+msgid "Repeats"
+msgstr ""
+
msgid "Replace"
msgstr ""
@@ -28344,7 +28639,7 @@ msgstr ""
msgid "Require additional authentication for administrative tasks."
msgstr ""
-msgid "Require all users in this group to setup Two-factor authentication"
+msgid "Require all users in this group to set up two-factor authentication"
msgstr ""
msgid "Require all users in this group to setup two-factor authentication"
@@ -28393,6 +28688,9 @@ msgstr[1] ""
msgid "Requires values to meet regular expression requirements."
msgstr ""
+msgid "Requires you to deploy or set up cloud-hosted Sentry."
+msgstr ""
+
msgid "Requires your primary GitLab email address."
msgstr ""
@@ -28453,9 +28751,6 @@ msgstr ""
msgid "Resolve"
msgstr ""
-msgid "Resolve all threads in new issue"
-msgstr ""
-
msgid "Resolve conflicts"
msgstr ""
@@ -28844,6 +29139,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner assigned to project."
+msgstr ""
+
msgid "Runners|Runner is offline, last contact was %{runner_contact} ago"
msgstr ""
@@ -28856,9 +29154,15 @@ msgstr ""
msgid "Runners|Runner registration"
msgstr ""
+msgid "Runners|Runner unassigned from project."
+msgstr ""
+
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28922,6 +29226,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29042,7 +29349,7 @@ msgstr ""
msgid "SastEntryPoints|How do I set up SAST?"
msgstr ""
-msgid "SastEntryPoints|Learn more."
+msgid "SastEntryPoints|Learn more"
msgstr ""
msgid "Satisfied"
@@ -29258,6 +29565,9 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
+msgid "Search or jump to..."
+msgstr ""
+
msgid "Search project"
msgstr ""
@@ -29409,6 +29719,9 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
+msgid "Secret access key"
+msgstr ""
+
msgid "Secret token"
msgstr ""
@@ -29472,7 +29785,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for Denied licenses. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
@@ -29544,6 +29857,12 @@ msgstr ""
msgid "SecurityConfiguration|Immediately begin risk analysis and remediation with application security features. Start with SAST and Secret Detection, available to all plans. Upgrade to Ultimate to get all features, including:"
msgstr ""
+msgid "SecurityConfiguration|Manage corpus"
+msgstr ""
+
+msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgstr ""
+
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
msgstr ""
@@ -29589,12 +29908,30 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|Actions"
+msgstr ""
+
+msgid "SecurityOrchestration|Add rule"
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
msgid "SecurityOrchestration|Edit policy"
msgstr ""
@@ -29604,6 +29941,18 @@ msgstr ""
msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
msgid "SecurityOrchestration|Network"
msgstr ""
@@ -29616,15 +29965,39 @@ msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy description"
+msgstr ""
+
msgid "SecurityOrchestration|Policy editor"
msgstr ""
+msgid "SecurityOrchestration|Policy preview"
+msgstr ""
+
+msgid "SecurityOrchestration|Policy status"
+msgstr ""
+
+msgid "SecurityOrchestration|Policy type"
+msgstr ""
+
+msgid "SecurityOrchestration|Rule"
+msgstr ""
+
+msgid "SecurityOrchestration|Rules"
+msgstr ""
+
msgid "SecurityOrchestration|Scan Execution"
msgstr ""
msgid "SecurityOrchestration|Scan execution"
msgstr ""
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
+msgstr ""
+
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
+msgstr ""
+
msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
@@ -29634,34 +30007,34 @@ msgstr ""
msgid "SecurityOrchestration|Select security project"
msgstr ""
-msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
msgstr ""
-msgid "SecurityOrchestration|Update scan execution policies"
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Update scan execution policies"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrhestration|No rules defined - policy will not run."
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityPolicies|+%{count} more"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityPolicies|Environment(s)"
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29721,6 +30094,9 @@ msgstr ""
msgid "SecurityReports|Download results"
msgstr ""
+msgid "SecurityReports|Download scanned URLs"
+msgstr ""
+
msgid "SecurityReports|Download scanned resources"
msgstr ""
@@ -30183,6 +30559,9 @@ msgstr ""
msgid "Send emails to help guide new users through the onboarding process."
msgstr ""
+msgid "Send emails to users upon account deactivation."
+msgstr ""
+
msgid "Send message"
msgstr ""
@@ -30201,6 +30580,9 @@ msgstr ""
msgid "Send service data"
msgstr ""
+msgid "Sentry"
+msgstr ""
+
msgid "Sentry API URL"
msgstr ""
@@ -30396,6 +30778,9 @@ msgstr ""
msgid "Set an instance-wide domain that will be available to all clusters when installing Knative."
msgstr ""
+msgid "Set any rate limit to %{code_open}0%{code_close} to disable the limit."
+msgstr ""
+
msgid "Set default and restrict visibility levels. Configure import sources and git access protocol."
msgstr ""
@@ -30408,6 +30793,9 @@ msgstr ""
msgid "Set limit to 0 to allow any file size."
msgstr ""
+msgid "Set limits for web and API requests."
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -30423,9 +30811,15 @@ msgstr ""
msgid "Set parent epic to an epic"
msgstr ""
+msgid "Set per-user rate limits for imports and exports of projects and groups."
+msgstr ""
+
msgid "Set projects and maximum size limits, session duration, user options, and check feature availability for namespace plan."
msgstr ""
+msgid "Set rate limits for package registry API requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Set severity"
msgstr ""
@@ -30444,6 +30838,9 @@ msgstr ""
msgid "Set the default branch for this project. All merge requests and commits are made against this branch unless you specify a different one."
msgstr ""
+msgid "Set the default expiration time for job artifacts in all projects. Set to %{code_open}0%{code_close} to never expire artifacts by default. If no unit is written, it defaults to seconds. For example, these are all equivalent: %{code_open}3600%{code_close}, %{code_open}60 minutes%{code_close}, or %{code_open}one hour%{code_close}."
+msgstr ""
+
msgid "Set the due date to %{due_date}."
msgstr ""
@@ -30453,7 +30850,10 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the per-user rate limit for notes created by web or API requests."
+msgstr ""
+
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30501,7 +30901,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30705,15 +31105,9 @@ msgstr ""
msgid "Show list"
msgstr ""
-msgid "Show me advanced features"
-msgstr ""
-
msgid "Show me how to add a pipeline"
msgstr ""
-msgid "Show me the basics"
-msgstr ""
-
msgid "Show one file at a time"
msgstr ""
@@ -30754,9 +31148,6 @@ msgstr ""
msgid "Showing %{pageSize} of %{total} %{issuableType}"
msgstr ""
-msgid "Showing %{pageSize} of %{total} issues"
-msgstr ""
-
msgid "Showing all epics"
msgstr ""
@@ -30802,6 +31193,15 @@ msgstr ""
msgid "Sidebar|Weight"
msgstr ""
+msgid "Sidekiq job compression threshold (bytes)"
+msgstr ""
+
+msgid "Sidekiq job size limit (bytes)"
+msgstr ""
+
+msgid "Sidekiq job size limits"
+msgstr ""
+
msgid "Sign in"
msgstr ""
@@ -30925,6 +31325,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -30949,19 +31352,22 @@ msgstr ""
msgid "SlackIntegration|Sends notifications about project events to Slack channels."
msgstr ""
-msgid "SlackService|2. Paste the %{strong_open}Token%{strong_close} into the field below"
+msgid "SlackService|1. %{slash_command_link_start}Add a slash command%{slash_command_link_end} in your Slack team using this information:"
msgstr ""
-msgid "SlackService|3. Select the %{strong_open}Active%{strong_close} checkbox, press %{strong_open}Save changes%{strong_close} and start using GitLab inside Slack!"
+msgid "SlackService|2. Paste the token from Slack in the %{strong_open}Token%{strong_close} field below."
msgstr ""
-msgid "SlackService|Fill in the word that works best for your team."
+msgid "SlackService|3. Select the %{strong_open}Active%{strong_close} checkbox, select %{strong_open}Save changes%{strong_close}, and start using slash commands in Slack!"
+msgstr ""
+
+msgid "SlackService|After setup, get a list of available Slack slash commands by entering"
msgstr ""
-msgid "SlackService|See list of available commands in Slack after setting up this service, by entering"
+msgid "SlackService|Fill in the word that works best for your team."
msgstr ""
-msgid "SlackService|This service allows users to perform common operations on this project by entering slash commands in Slack."
+msgid "SlackService|Perform common operations in this project by entering slash commands in Slack."
msgstr ""
msgid "Slice multiplier"
@@ -31111,9 +31517,6 @@ msgstr ""
msgid "Something went wrong while exporting requirements"
msgstr ""
-msgid "Something went wrong while fetching %{listType} list"
-msgstr ""
-
msgid "Something went wrong while fetching branches"
msgstr ""
@@ -31168,15 +31571,9 @@ msgstr ""
msgid "Something went wrong while merging this merge request. Please try again."
msgstr ""
-msgid "Something went wrong while moving issues."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
-msgid "Something went wrong while performing the action."
-msgstr ""
-
msgid "Something went wrong while promoting the issue to an epic. Please try again."
msgstr ""
@@ -32116,6 +32513,12 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscription|Renew your subscription"
+msgstr ""
+
+msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
+msgstr ""
+
msgid "Subtracted"
msgstr ""
@@ -32877,7 +33280,7 @@ msgstr ""
msgid "TestCases|Search test cases"
msgstr ""
-msgid "TestCases|Something went wrong while adding test case to Todo."
+msgid "TestCases|Something went wrong while adding test case to a to-do item."
msgstr ""
msgid "TestCases|Something went wrong while creating a test case."
@@ -32889,7 +33292,7 @@ msgstr ""
msgid "TestCases|Something went wrong while fetching test cases list."
msgstr ""
-msgid "TestCases|Something went wrong while marking test case todo as done."
+msgid "TestCases|Something went wrong while marking test case to-do item as done."
msgstr ""
msgid "TestCases|Something went wrong while moving test case."
@@ -33009,7 +33412,7 @@ msgstr ""
msgid "Thanks for your purchase!"
msgstr ""
-msgid "That is ok, I do not want to renew"
+msgid "That's OK, I don't want to renew"
msgstr ""
msgid "That's it, well done!"
@@ -33059,7 +33462,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33131,9 +33534,6 @@ msgstr ""
msgid "The default branch for this project has been changed. Please update your bookmarks."
msgstr ""
-msgid "The default expiration time for job artifacts. 0 for unlimited. The default unit is in seconds, but you can use other units, for example %{code_open}4 mins 2 sec%{code_close}, %{code_open}2h42min%{code_close}."
-msgstr ""
-
msgid "The dependency list details information about the components used within your project."
msgstr ""
@@ -33277,6 +33677,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33313,9 +33716,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33325,9 +33725,6 @@ msgstr ""
msgid "The merge conflicts for this merge request have already been resolved. Please return to the merge request."
msgstr ""
-msgid "The merge request can now be merged."
-msgstr ""
-
msgid "The metric must be one of %{metrics}."
msgstr ""
@@ -33349,6 +33746,9 @@ msgstr ""
msgid "The number of times an upload record could not find its file"
msgstr ""
+msgid "The package registry rate limits can help reduce request volume (like from crawlers or abusive bots)."
+msgstr ""
+
msgid "The page could not be displayed because it timed out."
msgstr ""
@@ -33469,6 +33869,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33613,6 +34016,9 @@ msgstr ""
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33697,7 +34103,7 @@ msgstr ""
msgid "There was a problem updating the keep latest artifacts setting."
msgstr ""
-msgid "There was an error %{message} todo."
+msgid "There was an error %{message} to-do item."
msgstr ""
msgid "There was an error adding a To Do."
@@ -34363,9 +34769,6 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user does not have a pending request"
-msgstr ""
-
msgid "This user has an unconfirmed email address (%{email}). You may force a confirmation."
msgstr ""
@@ -34528,6 +34931,12 @@ msgstr ""
msgid "ThreatMonitoring|View documentation"
msgstr ""
+msgid "Threshold in bytes at which to compress Sidekiq job arguments."
+msgstr ""
+
+msgid "Threshold in bytes at which to reject Sidekiq jobs. Set this to 0 to if you don't want to limit Sidekiq jobs."
+msgstr ""
+
msgid "Throughput"
msgstr ""
@@ -34817,6 +35226,9 @@ msgstr ""
msgid "To access this domain create a new DNS record"
msgstr ""
+msgid "To add a custom suffix, set up a Service Desk email address. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "To add an SSH key you need to %{generate_link_start}generate one%{link_end} or use an %{existing_link_start}existing key%{link_end}."
msgstr ""
@@ -34904,7 +35316,7 @@ msgstr ""
msgid "To preserve performance only %{strong_open}%{display_size} of %{real_size}%{strong_close} files are displayed."
msgstr ""
-msgid "To protect this issue's confidentiality, %{forkLink} and set the fork's visibility to private."
+msgid "To protect this issue's confidentiality, %{linkStart}fork this project%{linkEnd} and set the fork's visibility to private."
msgstr ""
msgid "To protect this issue's confidentiality, a private fork of this project was selected."
@@ -34937,7 +35349,7 @@ msgstr ""
msgid "To set up SAML authentication for your group through an identity provider like Azure, Okta, Onelogin, Ping Identity, or your custom SAML 2.0 provider:"
msgstr ""
-msgid "To set up this service:"
+msgid "To set up this integration:"
msgstr ""
msgid "To specify the notification level per project of a group you belong to, you need to visit project page and change notification level there."
@@ -35180,13 +35592,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35524,9 +35942,6 @@ msgstr ""
msgid "Unable to fetch branches list, please close the form and try again"
msgstr ""
-msgid "Unable to fetch unscanned projects"
-msgstr ""
-
msgid "Unable to fetch vulnerable projects"
msgstr ""
@@ -35581,6 +35996,15 @@ msgstr ""
msgid "Unable to update this issue at this time."
msgstr ""
+msgid "Unapprove a merge request"
+msgstr ""
+
+msgid "Unapprove the current merge request."
+msgstr ""
+
+msgid "Unapproved the current merge request."
+msgstr ""
+
msgid "Unarchive project"
msgstr ""
@@ -35593,16 +36017,16 @@ msgstr ""
msgid "Unassigned"
msgstr ""
-msgid "Unauthenticated API request rate limit"
+msgid "Unauthenticated API rate limit period in seconds"
msgstr ""
-msgid "Unauthenticated rate limit period in seconds"
+msgid "Unauthenticated API request rate limit"
msgstr ""
-msgid "Unauthenticated request rate limit"
+msgid "Unauthenticated requests"
msgstr ""
-msgid "Unauthenticated requests"
+msgid "Unauthenticated web rate limit period in seconds"
msgstr ""
msgid "Undo"
@@ -35704,18 +36128,6 @@ msgstr ""
msgid "Unresolved"
msgstr ""
-msgid "UnscannedProjects|15 or more days"
-msgstr ""
-
-msgid "UnscannedProjects|30 or more days"
-msgstr ""
-
-msgid "UnscannedProjects|5 or more days"
-msgstr ""
-
-msgid "UnscannedProjects|60 or more days"
-msgstr ""
-
msgid "Unschedule job"
msgstr ""
@@ -35935,6 +36347,9 @@ msgstr ""
msgid "UsageQuota|%{help_link_start}Shared runners%{help_link_end} are disabled, so there are no limits set on pipeline usage"
msgstr ""
+msgid "UsageQuota|%{linkTitle} help link"
+msgstr ""
+
msgid "UsageQuota|%{percentageLeft} of purchased storage is available"
msgstr ""
@@ -35944,6 +36359,9 @@ msgstr ""
msgid "UsageQuota|Artifacts is a sum of build and pipeline artifacts."
msgstr ""
+msgid "UsageQuota|Audio samples, videos, datasets, and graphics."
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
@@ -35953,9 +36371,21 @@ msgstr ""
msgid "UsageQuota|CI minutes usage by project"
msgstr ""
+msgid "UsageQuota|Code packages and container images."
+msgstr ""
+
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|File attachments and smaller design graphics."
+msgstr ""
+
+msgid "UsageQuota|Git repository, managed by the Gitaly service."
+msgstr ""
+
+msgid "UsageQuota|Includes project registry, artifacts, packages, wiki, uploads and other items."
+msgstr ""
+
msgid "UsageQuota|Increase storage temporarily"
msgstr ""
@@ -35971,10 +36401,10 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
+msgid "UsageQuota|Packages"
msgstr ""
-msgid "UsageQuota|Packages"
+msgid "UsageQuota|Pipeline artifacts and job artifacts, created with CI/CD."
msgstr ""
msgid "UsageQuota|Pipelines"
@@ -35995,12 +36425,24 @@ msgstr ""
msgid "UsageQuota|Seats"
msgstr ""
+msgid "UsageQuota|Shared bits of code and text."
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage type"
+msgstr ""
+
+msgid "UsageQuota|There is a known issue with Artifact storage where the total could be incorrect for some projects. More details and progress are available in %{warningLinkStart}the epic%{warningLinkEnd}."
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -36040,12 +36482,18 @@ msgstr ""
msgid "UsageQuota|Usage"
msgstr ""
+msgid "UsageQuota|Usage Breakdown"
+msgstr ""
+
msgid "UsageQuota|Usage Quotas"
msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36061,6 +36509,9 @@ msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wiki content."
+msgstr ""
+
msgid "UsageQuota|Wikis"
msgstr ""
@@ -36202,6 +36653,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36274,7 +36728,10 @@ msgstr ""
msgid "User Settings"
msgstr ""
-msgid "User and IP Rate Limits"
+msgid "User and IP rate limits"
+msgstr ""
+
+msgid "User does not have a pending request"
msgstr ""
msgid "User identity was successfully created."
@@ -36586,6 +37043,9 @@ msgstr ""
msgid "Users requesting access to"
msgstr ""
+msgid "Users to exclude from the rate limit"
+msgstr ""
+
msgid "Users were successfully added."
msgstr ""
@@ -36607,6 +37067,9 @@ msgstr ""
msgid "UsersSelect|Unassigned"
msgstr ""
+msgid "Uses GitLab as a lightweight alternative to Sentry."
+msgstr ""
+
msgid "Using %{code_start}::%{code_end} denotes a %{link_start}scoped label set%{link_end}"
msgstr ""
@@ -36637,10 +37100,7 @@ msgstr ""
msgid "Value Stream Analytics can help you determine your team’s velocity"
msgstr ""
-msgid "Value Stream Analytics gives an overview of how much time it takes to go from idea to production in your project."
-msgstr ""
-
-msgid "Value may contain a variable reference"
+msgid "Value might contain a variable reference"
msgstr ""
msgid "Value stream"
@@ -36706,10 +37166,10 @@ msgstr ""
msgid "ValueStream|The Default Value Stream cannot be deleted"
msgstr ""
-msgid "Variable"
+msgid "Values that contain the %{codeStart}$%{codeEnd} character can be considered a variable reference and expanded. %{docsLinkStart}Learn more.%{docsLinkEnd}"
msgstr ""
-msgid "Variable references indicated by %{codeStart}$%{codeEnd} may be expanded. If this is not what you want, consider %{docsLinkStart}using a workaround to prevent expansion%{docsLinkEnd}."
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -36884,6 +37344,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -37109,6 +37574,9 @@ msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|False positive detected"
+msgstr ""
+
msgid "Vulnerability|File"
msgstr ""
@@ -37142,9 +37610,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -37154,9 +37619,15 @@ msgstr ""
msgid "Vulnerability|Status"
msgstr ""
+msgid "Vulnerability|The scanner determined this vulnerability to be a false positive. Verify the evaluation before changing its status. %{linkStart}Learn more about false positive detection.%{linkEnd}"
+msgstr ""
+
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37262,6 +37733,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37472,9 +37946,6 @@ msgstr ""
msgid "Welcome to GitLab,%{br_tag}%{name}!"
msgstr ""
-msgid "Welcome to the guided GitLab tour"
-msgstr ""
-
msgid "Welcome, %{name}!"
msgstr ""
@@ -37493,9 +37964,6 @@ msgstr ""
msgid "What are you searching for?"
msgstr ""
-msgid "What describes you best?"
-msgstr ""
-
msgid "What does this command do?"
msgstr ""
@@ -37517,10 +37985,10 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
-msgid "What's new"
+msgid "What will you use this group for?"
msgstr ""
-msgid "What’s your experience level?"
+msgid "What's new"
msgstr ""
msgid "When a deployment job is successful, skip older deployment jobs that are still pending."
@@ -37576,6 +38044,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37831,6 +38302,9 @@ msgstr ""
msgid "Work in progress Limit"
msgstr ""
+msgid "WorkItem|Work Items"
+msgstr ""
+
msgid "Would you like to create a new branch?"
msgstr ""
@@ -38008,6 +38482,9 @@ msgstr ""
msgid "You can also use project access tokens with Git to authenticate over HTTP(S). %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "You can always change your URL later"
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -38134,6 +38611,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -38149,6 +38629,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38161,9 +38644,6 @@ msgstr ""
msgid "You could not create a new trigger."
msgstr ""
-msgid "You didn't renew your subscription for %{strong}%{namespace_name}%{strong_close} so it was downgraded to the free plan."
-msgstr ""
-
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -38329,6 +38809,12 @@ msgstr ""
msgid "You must provide your current password in order to change it."
msgstr ""
+msgid "You must sign in to search for specific projects."
+msgstr ""
+
+msgid "You must sign in to search for specific terms."
+msgstr ""
+
msgid "You must solve the CAPTCHA in order to submit"
msgstr ""
@@ -38356,6 +38842,9 @@ msgstr ""
msgid "You need to upload a GitLab project export archive (ending in .gz)."
msgstr ""
+msgid "You need to verify your primary email first before enabling Two-Factor Authentication."
+msgstr ""
+
msgid "You successfully declined the invitation"
msgstr ""
@@ -38464,10 +38953,10 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}."
+msgid "Your %{strong}%{plan_name}%{strong_close} subscription expires on %{strong}%{expires_on}%{strong_close}. After that date, you cannot create issues or merge requests, or use many other features."
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not be able to create issues or merge requests as well as many other features."
+msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}."
msgstr ""
msgid "Your CI/CD configuration syntax is invalid. View Lint tab for more details."
@@ -38491,7 +38980,7 @@ msgstr ""
msgid "Your GPG keys (%{count})"
msgstr ""
-msgid "Your GitLab account has been locked due to an excessive amount of unsuccessful sign in attempts. Your account will automatically unlock in %{duration} or you may click the link below to unlock now."
+msgid "Your GitLab account has been locked due to an excessive number of unsuccessful sign in attempts. You can wait for your account to automatically unlock in %{duration} or you can click the link below to unlock now."
msgstr ""
msgid "Your GitLab account request has been approved!"
@@ -38701,6 +39190,9 @@ msgstr ""
msgid "Your project limit is %{limit} projects! Please contact your administrator to increase it"
msgstr ""
+msgid "Your project will be created at:"
+msgstr ""
+
msgid "Your projects"
msgstr ""
@@ -38740,13 +39232,36 @@ msgstr ""
msgid "Your subscription expired!"
msgstr ""
-msgid "Your subscription has been downgraded."
+msgid "Your subscription will expire in %{remaining_days} day."
+msgid_plural "Your subscription will expire in %{remaining_days} days."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Your username is %{username}."
msgstr ""
-msgid "Your subscription will expire in %{remaining_days}."
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
msgstr ""
-msgid "Your username is %{username}."
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
msgstr ""
msgid "Zoom meeting added"
@@ -38853,6 +39368,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38922,6 +39442,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "cannot not be used for user namespace"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -39320,7 +39843,7 @@ msgstr ""
msgid "encrypted: needs to be a :required, :optional or :migrating!"
msgstr ""
-msgid "ending with MIME type format is not allowed."
+msgid "ending with a file extension is not allowed."
msgstr ""
msgid "entries cannot be larger than 255 characters"
@@ -39394,9 +39917,6 @@ msgstr ""
msgid "fork"
msgstr ""
-msgid "fork this project"
-msgstr ""
-
msgid "from"
msgstr ""
@@ -39432,6 +39952,9 @@ msgstr ""
msgid "has been completed."
msgstr ""
+msgid "has too deep level of nesting"
+msgstr ""
+
msgid "help"
msgstr ""
@@ -39465,9 +39988,18 @@ msgstr ""
msgid "in"
msgstr ""
+msgid "in all GitLab"
+msgstr ""
+
+msgid "in group"
+msgstr ""
+
msgid "in group %{link_to_group}"
msgstr ""
+msgid "in project"
+msgstr ""
+
msgid "in project %{link_to_project}"
msgstr ""
@@ -39658,6 +40190,9 @@ msgstr ""
msgid "mrWidget| Please restore it or use a different %{missingBranchName} branch"
msgstr ""
+msgid "mrWidget|%{linkStart}Set up now%{linkEnd} to analyze your source code for known security vulnerabilities."
+msgstr ""
+
msgid "mrWidget|%{mergeError}."
msgstr ""
@@ -39738,6 +40273,9 @@ msgid_plural "mrWidget|Closes issues"
msgstr[0] ""
msgstr[1] ""
+msgid "mrWidget|Create issue to resolve all threads"
+msgstr ""
+
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39747,6 +40285,9 @@ msgstr ""
msgid "mrWidget|Did not close"
msgstr ""
+msgid "mrWidget|Dismiss"
+msgstr ""
+
msgid "mrWidget|Email patches"
msgstr ""
@@ -39848,9 +40389,6 @@ msgstr ""
msgid "mrWidget|Request to merge"
msgstr ""
-msgid "mrWidget|Resolve all threads in new issue"
-msgstr ""
-
msgid "mrWidget|Resolve conflicts"
msgstr ""
@@ -39866,6 +40404,9 @@ msgstr ""
msgid "mrWidget|Revoke approval"
msgstr ""
+msgid "mrWidget|SAST and Secret Detection is not enabled."
+msgstr ""
+
msgid "mrWidget|Set by %{merge_author} to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -39887,6 +40428,9 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
+msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure."
+msgstr ""
+
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39929,6 +40473,9 @@ msgstr ""
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
+msgid "mrWidget|You can only merge once this merge request is approved."
+msgstr ""
+
msgid "mrWidget|Your password"
msgstr ""
@@ -39962,6 +40509,12 @@ msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
+msgid "must be set for a project namespace"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
@@ -40071,6 +40624,9 @@ msgstr ""
msgid "pipeline"
msgstr ""
+msgid "pipeline schedules documentation"
+msgstr ""
+
msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -40120,6 +40676,9 @@ msgstr ""
msgid "project name"
msgstr ""
+msgid "project namespace cannot be the parent of another namespace"
+msgstr ""
+
msgid "projects"
msgstr ""
@@ -40356,6 +40915,9 @@ msgstr ""
msgid "user avatar"
msgstr ""
+msgid "user namespace cannot be the parent of another namespace"
+msgstr ""
+
msgid "user preferences"
msgstr ""
@@ -40447,3 +41009,9 @@ msgstr ""
msgid "your settings"
msgstr ""
+
+msgid "{group}"
+msgstr ""
+
+msgid "{project}"
+msgstr ""
diff --git a/locale/gl_ES/gitlab.po b/locale/gl_ES/gitlab.po
index 2b833b0c172..52e5f0795f7 100644
--- a/locale/gl_ES/gitlab.po
+++ b/locale/gl_ES/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: gl\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:13\n"
+"PO-Revision-Date: 2021-09-01 22:30\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/he_IL/gitlab.po b/locale/he_IL/gitlab.po
index c1d54ad68af..fef2ae24708 100644
--- a/locale/he_IL/gitlab.po
+++ b/locale/he_IL/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: he\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:28\n"
+"PO-Revision-Date: 2021-09-02 01:27\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -23,31 +23,31 @@ msgid " %{start} to %{end}"
msgstr ""
msgid " (from %{timeoutSource})"
-msgstr ""
+msgstr " (מתוך %{timeoutSource})"
msgid " Collected %{time}"
-msgstr ""
+msgstr " × ×ספה ב־%{time}"
msgid " Please sign in."
-msgstr ""
+msgstr " × × ×œ×”×™×›× ×¡."
msgid " Target Path"
-msgstr ""
+msgstr " נתיב היעד"
msgid " Try to %{action} this file again."
msgstr ""
msgid " Type"
-msgstr ""
+msgstr " סוג"
msgid " You need to do this before %{grace_period_deadline}."
-msgstr ""
+msgstr " עליך לעשות ×–×ת לפני %{grace_period_deadline}."
msgid " and"
-msgstr ""
+msgstr " וג×"
msgid " and "
-msgstr ""
+msgstr " ×•×’× "
msgid " and %{sliced}"
msgstr ""
@@ -67,7 +67,7 @@ msgstr[2] ""
msgstr[3] ""
msgid " or "
-msgstr ""
+msgstr " ×ו "
msgid " or %{emphasisStart}!merge request id%{emphasisEnd}"
msgstr ""
@@ -119,10 +119,10 @@ msgstr[3] ""
msgid "%d Package"
msgid_plural "%d Packages"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "חבילה %d"
+msgstr[1] "%d חבילות"
+msgstr[2] "%d חבילות"
+msgstr[3] "%d חבילות"
msgid "%d Scanned URL"
msgid_plural "%d Scanned URLs"
@@ -484,6 +484,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -661,6 +668,9 @@ msgstr[3] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -799,9 +809,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -811,6 +818,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -945,10 +955,10 @@ msgid "%{placeholder} is not a valid theme"
msgstr ""
msgid "%{primary} (%{secondary})"
-msgstr ""
+msgstr "%{primary} (%{secondary})"
msgid "%{ref} cannot be added: %{error}"
-msgstr ""
+msgstr "×œ× × ×™×ª×Ÿ להוסיף ×ת %{ref}: %{error}"
msgid "%{releases} release"
msgid_plural "%{releases} releases"
@@ -978,6 +988,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -999,22 +1012,22 @@ msgid "%{service_ping_link_start}Learn more%{service_ping_link_end} about what i
msgstr ""
msgid "%{size} %{unit}"
-msgstr ""
+msgstr "%{size} %{unit}"
msgid "%{size} GiB"
-msgstr ""
+msgstr "%{size} GiB"
msgid "%{size} KiB"
-msgstr ""
+msgstr "%{size} KiB"
msgid "%{size} MiB"
-msgstr ""
+msgstr "%{size} MiB"
msgid "%{size} bytes"
-msgstr ""
+msgstr "%{size} בתי×"
msgid "%{sourceBranch} into %{targetBranch}"
-msgstr ""
+msgstr "%{sourceBranch} לתוך %{targetBranch}"
msgid "%{spammable_titlecase} was submitted to Akismet successfully."
msgstr ""
@@ -1090,7 +1103,7 @@ msgstr[2] ""
msgstr[3] ""
msgid "%{tabname} changed"
-msgstr ""
+msgstr "%{tabname} השתנתה"
msgid "%{tags} tag per image name"
msgstr ""
@@ -1112,7 +1125,7 @@ msgstr[2] ""
msgstr[3] ""
msgid "%{text} is available"
-msgstr ""
+msgstr "%{text} זמין"
msgid "%{timebox_name} should belong either to a project or a group."
msgstr ""
@@ -1254,7 +1267,7 @@ msgid "(Group Managed Account)"
msgstr ""
msgid "(No changes)"
-msgstr ""
+msgstr "(×ין שינויי×)"
msgid "(UTC %{offset}) %{timezone}"
msgstr ""
@@ -1452,7 +1465,7 @@ msgstr[2] ""
msgstr[3] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -1467,10 +1480,10 @@ msgstr[3] ""
msgid "1 minute"
msgid_plural "%d minutes"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "דקה"
+msgstr[1] "%d דקות"
+msgstr[2] "%d דקות"
+msgstr[3] "%d דקות"
msgid "1 month remaining"
msgid_plural "%d months remaining"
@@ -1532,34 +1545,34 @@ msgid "1-9 contributions"
msgstr ""
msgid "10-19 contributions"
-msgstr ""
+msgstr "10â€-19 תרומות"
msgid "1000+"
msgstr ""
msgid "1st contribution!"
-msgstr ""
+msgstr "תרומה ר×שונה!"
msgid "20-29 contributions"
-msgstr ""
+msgstr "20â€-29 תרומות"
msgid "2FA"
-msgstr ""
+msgstr "×ימות דו־שלבי"
msgid "2FADevice|Registered On"
msgstr ""
msgid "3 days"
-msgstr ""
+msgstr "3 ימי×"
msgid "3 hours"
-msgstr ""
+msgstr "3 שעות"
msgid "30 days"
-msgstr ""
+msgstr "30 ימי×"
msgid "30 minutes"
-msgstr ""
+msgstr "חצי שעה"
msgid "30+ contributions"
msgstr ""
@@ -1574,16 +1587,16 @@ msgid "404|Make sure the address is correct and the page hasn't moved."
msgstr ""
msgid "404|Page Not Found"
-msgstr ""
+msgstr "העמוד ×œ× × ×ž×¦×"
msgid "404|Please contact your GitLab administrator if you think this is a mistake."
-msgstr ""
+msgstr "× × ×œ×™×¦×•×¨ קשר ×¢× ×”× ×”×œ×ª ×”Ö¾GitLab שלך ×× ×œ×“×¢×ª×š מדובר בטעות."
msgid "7 days"
-msgstr ""
+msgstr "7 ימי×"
msgid "8 hours"
-msgstr ""
+msgstr "8 שעות"
msgid ":%{startLine} to %{endLine}"
msgstr ""
@@ -1643,7 +1656,7 @@ msgid "A file has been changed."
msgstr ""
msgid "A file was not found."
-msgstr ""
+msgstr "קובץ ×œ× × ×ž×¦×."
msgid "A file with '%{file_name}' already exists in %{branch} branch"
msgstr ""
@@ -1750,10 +1763,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1780,10 +1793,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -1868,25 +1881,25 @@ msgid "AWS Secret Access Key. Only required if not using role instance credentia
msgstr ""
msgid "AWS service error: %{error}"
-msgstr ""
+msgstr "שגי×ת שירות AWS:†%{error}"
msgid "Abort"
msgstr ""
msgid "About GitLab"
-msgstr ""
+msgstr "על ×ודות GitLab"
msgid "About auto deploy"
-msgstr ""
+msgstr "על הטמעה ×וטומטית"
msgid "About this feature"
-msgstr ""
+msgstr "על התכונה הזו"
msgid "Abuse Reports"
-msgstr ""
+msgstr "×“×™×•×•×—×™× ×¢×œ שימוש לרעה"
msgid "Abuse reports"
-msgstr ""
+msgstr "×“×™×•×•×—×™× ×¢×œ שימוש לרעה"
msgid "Abuse reports notification email"
msgstr ""
@@ -1895,7 +1908,7 @@ msgid "Abuse reports will be sent to this address if it is set. Abuse reports ar
msgstr ""
msgid "Accept invitation"
-msgstr ""
+msgstr "קבלת הזמנה"
msgid "Accept terms"
msgstr ""
@@ -1907,10 +1920,10 @@ msgid "Access Git repositories or the API."
msgstr ""
msgid "Access Tokens"
-msgstr ""
+msgstr "×סימוני גישה"
msgid "Access denied for your LDAP account."
-msgstr ""
+msgstr "הגישה לחשבון ה־LDAP שלך נדחתה."
msgid "Access denied! Please verify you can add deploy keys to this repository."
msgstr ""
@@ -1919,40 +1932,40 @@ msgid "Access denied: %{error}"
msgstr ""
msgid "Access expiration date"
-msgstr ""
+msgstr "ת×ריך תפוגת גישה"
msgid "Access expires"
msgstr ""
msgid "Access forbidden. Check your access level."
-msgstr ""
+msgstr "הגישה נדחתה. × × ×œ×‘×“×•×§ ×ת רמת הגישה שלך."
msgid "Access granted"
-msgstr ""
+msgstr "הוענקה גישה"
msgid "Access requests"
-msgstr ""
+msgstr "בקשות גישה"
msgid "Access to '%{classification_label}' not allowed"
-msgstr ""
+msgstr "הגישה ×ל ‚%{classification_label}’ ×סורה"
msgid "AccessDropdown|Deploy Keys"
-msgstr ""
+msgstr "מפתחות הטמעה"
msgid "AccessDropdown|Groups"
-msgstr ""
+msgstr "קבוצות"
msgid "AccessDropdown|Roles"
-msgstr ""
+msgstr "תפקידי×"
msgid "AccessDropdown|Users"
-msgstr ""
+msgstr "משתמשי×"
msgid "AccessTokens|Access Tokens"
-msgstr ""
+msgstr "×סימוני גישה"
msgid "AccessTokens|Are you sure?"
-msgstr ""
+msgstr "להמשיך?"
msgid "AccessTokens|Are you sure? Any RSS or calendar URLs currently in use will stop working."
msgstr ""
@@ -2042,31 +2055,31 @@ msgid "Action to take when receiving an alert. %{docsLink}"
msgstr ""
msgid "Actions"
-msgstr ""
+msgstr "פעולות"
msgid "Activate Service Desk"
-msgstr ""
+msgstr "הפעלת דלפק שירות"
msgid "Active"
-msgstr ""
+msgstr "פעיל"
msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
-msgstr ""
+msgstr "הפעלות פעילות"
msgid "Activity"
-msgstr ""
+msgstr "פעילות"
msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
-msgstr ""
+msgstr "×ירעה שגי××” בקבלת הפעילות. × × ×œ×¨×¢× ×Ÿ ×ת העמוד ולנסות שוב."
msgid "Add"
-msgstr ""
+msgstr "הוספה"
msgid "Add \"%{value}\""
-msgstr ""
+msgstr "הוספת „%{value}â€"
msgid "Add %{linkStart}assets%{linkEnd} to your Release. GitLab automatically includes read-only assets, like source code and release evidence."
msgstr ""
@@ -2075,34 +2088,34 @@ msgid "Add CHANGELOG"
msgstr ""
msgid "Add CONTRIBUTING"
-msgstr ""
+msgstr "הוספת CONTRIBUTING (הדרכה למתנדבי×)"
msgid "Add GitLab to Slack"
-msgstr ""
+msgstr "הוספת GitLab ל־Slack"
msgid "Add Jaeger URL"
-msgstr ""
+msgstr "הוספת כתובת Jaeger"
msgid "Add Kubernetes cluster"
-msgstr ""
+msgstr "הוספת מקבץ Kubernetes"
msgid "Add LICENSE"
-msgstr ""
+msgstr "הוספת LICENSE (רישיון)"
msgid "Add New Node"
msgstr ""
msgid "Add README"
-msgstr ""
+msgstr "הוספת README (הסבר)"
msgid "Add Zoom meeting"
-msgstr ""
+msgstr "הוספת פגישת Zoom"
msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
-msgstr ""
+msgstr "הוספת מפתח GPG"
msgid "Add a Jaeger URL to replace this page with a link to your Jaeger server. You first need to %{link_start_tag}install Jaeger%{link_end_tag}."
msgstr ""
@@ -2135,13 +2148,13 @@ msgid "Add a homepage to your wiki that contains information about your project
msgstr ""
msgid "Add a horizontal rule"
-msgstr ""
+msgstr "הוספת קו ×ופקי"
msgid "Add a line"
-msgstr ""
+msgstr "הוספת שורה"
msgid "Add a link"
-msgstr ""
+msgstr "הוספת קישור"
msgid "Add a link to Grafana"
msgstr ""
@@ -2150,16 +2163,16 @@ msgid "Add a new issue"
msgstr ""
msgid "Add a numbered list"
-msgstr ""
+msgstr "הוספת רשימה ממוספרת"
msgid "Add a related issue"
msgstr ""
msgid "Add a table"
-msgstr ""
+msgstr "הוספת טבלה"
msgid "Add a task list"
-msgstr ""
+msgstr "הוספת רשימת משימות"
msgid "Add a to do"
msgstr ""
@@ -2174,13 +2187,13 @@ msgid "Add an impersonation token"
msgstr ""
msgid "Add another link"
-msgstr ""
+msgstr "הוספת קישור נוסף"
msgid "Add approval rule"
msgstr ""
msgid "Add approvers"
-msgstr ""
+msgstr "הוספת מ×שרי×"
msgid "Add bold text"
msgstr "הוספת טקסט מודגש"
@@ -2210,16 +2223,16 @@ msgid "Add deploy keys to grant read/write access to this repository. %{link_sta
msgstr ""
msgid "Add domain"
-msgstr ""
+msgstr "הוספת ×©× ×ª×—×•×"
msgid "Add email address"
-msgstr ""
+msgstr "הוספת כתובת דו×״ל"
msgid "Add email participant(s)"
msgstr ""
msgid "Add environment"
-msgstr ""
+msgstr "הוספת סביבה"
msgid "Add existing confidential %{issuableType}"
msgstr ""
@@ -2228,10 +2241,10 @@ msgid "Add header and footer to emails. Please note that color settings will onl
msgstr ""
msgid "Add image comment"
-msgstr ""
+msgstr "הוספת הערה על תמונה"
msgid "Add italic text"
-msgstr ""
+msgstr "הוספת טקסט נטוי"
msgid "Add key"
msgstr ""
@@ -2261,34 +2274,34 @@ msgid "Add project"
msgstr ""
msgid "Add projects"
-msgstr ""
+msgstr "הוספת מיזמי×"
msgid "Add reaction"
-msgstr ""
+msgstr "הוספת סמל תגובה"
msgid "Add request manually"
-msgstr ""
+msgstr "הוספת בקשה ידנית"
msgid "Add strikethrough text"
-msgstr ""
+msgstr "הוספת טקסט ×¢× ×§×• חוצה"
msgid "Add suggestion to batch"
-msgstr ""
+msgstr "הוספת הצעה ל×וסף"
msgid "Add system hook"
-msgstr ""
+msgstr "הוספת התליית מערכת"
msgid "Add text to the sign-in page. Markdown enabled."
-msgstr ""
+msgstr "הוספת טקסט לעמוד הכניסה. ×פשר Markdown."
msgid "Add to Slack"
-msgstr ""
+msgstr "הוספה ל־Slack"
msgid "Add to board"
-msgstr ""
+msgstr "הוספה ללוח"
msgid "Add to epic"
-msgstr ""
+msgstr "הוספה ×œ× ×•×©× ×¢×œ"
msgid "Add to merge train"
msgstr ""
@@ -2297,10 +2310,10 @@ msgid "Add to merge train when pipeline succeeds"
msgstr ""
msgid "Add to review"
-msgstr ""
+msgstr "הוספה לסקירה"
msgid "Add to tree"
-msgstr ""
+msgstr "הוספה לעץ"
msgid "Add trigger"
msgstr ""
@@ -2309,16 +2322,16 @@ msgid "Add user(s) to the group:"
msgstr ""
msgid "Add users to group"
-msgstr ""
+msgstr "הוספת ×ž×©×ª×ž×©×™× ×œ×§×‘×•×¦×”"
msgid "Add variable"
msgstr ""
msgid "Add webhook"
-msgstr ""
+msgstr "הוספת התליית רשת"
msgid "Add/remove"
-msgstr ""
+msgstr "הוספה/הסרה"
msgid "AddContextCommits|Add previously merged commits"
msgstr ""
@@ -2375,13 +2388,13 @@ msgid "Additional Metadata"
msgstr ""
msgid "Additional minutes"
-msgstr ""
+msgstr "דקות נוספות"
msgid "Additional minutes:"
msgstr ""
msgid "Additional text"
-msgstr ""
+msgstr "טקסט נוסף"
msgid "Additional text for the sign-in and Help page."
msgstr ""
@@ -2393,7 +2406,7 @@ msgid "Additional text to show on the sign-in page"
msgstr ""
msgid "Address"
-msgstr ""
+msgstr "כתובת"
msgid "Adds"
msgstr ""
@@ -2423,22 +2436,22 @@ msgid "Adjust your filters/search criteria above. If you believe this may be an
msgstr ""
msgid "Admin"
-msgstr ""
+msgstr "ניהול"
msgid "Admin Area"
-msgstr ""
+msgstr "×זור ניהול"
msgid "Admin Mode"
-msgstr ""
+msgstr "מצב ניהול"
msgid "Admin Note"
-msgstr ""
+msgstr "הערות הנהלה"
msgid "Admin Notifications"
msgstr ""
msgid "Admin Overview"
-msgstr ""
+msgstr "סקירת הנהלה"
msgid "Admin Section"
msgstr ""
@@ -2462,7 +2475,7 @@ msgid "AdminArea|%{billable_users_link_start}Learn more%{billable_users_link_end
msgstr ""
msgid "AdminArea|Active users"
-msgstr ""
+msgstr "×ž×©×ª×ž×©×™× ×¤×¢×™×œ×™×"
msgid "AdminArea|All users created in the instance, including users who are not %{billable_users_link_start}billable users%{billable_users_link_end}."
msgstr ""
@@ -2471,22 +2484,22 @@ msgid "AdminArea|Billable users"
msgstr ""
msgid "AdminArea|Blocked users"
-msgstr ""
+msgstr "×ž×©×ª×ž×©×™× ×—×¡×•×ž×™×"
msgid "AdminArea|Bots"
msgstr ""
msgid "AdminArea|Components"
-msgstr ""
+msgstr "רכיבי×"
msgid "AdminArea|Developer"
msgstr ""
msgid "AdminArea|Features"
-msgstr ""
+msgstr "תכונות"
msgid "AdminArea|Groups"
-msgstr ""
+msgstr "קבוצות"
msgid "AdminArea|Guest"
msgstr ""
@@ -2513,43 +2526,43 @@ msgid "AdminArea|New project"
msgstr ""
msgid "AdminArea|New user"
-msgstr ""
+msgstr "משתמש חדש"
msgid "AdminArea|Owner"
-msgstr ""
+msgstr "בעלי×"
msgid "AdminArea|Projects"
-msgstr ""
+msgstr "מיזמי×"
msgid "AdminArea|Reporter"
msgstr ""
msgid "AdminArea|Stop all jobs"
-msgstr ""
+msgstr "לעצור ×ת כל המשימות"
msgid "AdminArea|Stop all jobs?"
-msgstr ""
+msgstr "לעצור ×ת כל המשימות?"
msgid "AdminArea|Stop jobs"
-msgstr ""
+msgstr "לעצור משימות"
msgid "AdminArea|Stopping jobs failed"
-msgstr ""
+msgstr "עצירת המשימות נכשלה"
msgid "AdminArea|Total users"
-msgstr ""
+msgstr "סך כל המשתמשי×"
msgid "AdminArea|Users"
-msgstr ""
+msgstr "משתמשי×"
msgid "AdminArea|Users statistics"
-msgstr ""
+msgstr "סטטיסטיקות משתמשי×"
msgid "AdminArea|Users with highest role"
-msgstr ""
+msgstr "×ž×©×ª×ž×©×™× ×¢× ×”×ª×¤×§×™×“ הבכיר ביותר"
msgid "AdminArea|Users without a Group and Project"
-msgstr ""
+msgstr "×ž×©×ª×ž×©×™× ×‘×œ×™ קבוצה ומיז×"
msgid "AdminArea|View latest groups"
msgstr ""
@@ -2560,7 +2573,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2687,7 +2700,7 @@ msgid "AdminStatistics|Notes"
msgstr ""
msgid "AdminStatistics|SSH Keys"
-msgstr ""
+msgstr "מפתחות SSH"
msgid "AdminStatistics|Snippets"
msgstr ""
@@ -2720,7 +2733,7 @@ msgid "AdminUsers|A user can validate themselves by inputting a credit/debit car
msgstr ""
msgid "AdminUsers|Access"
-msgstr ""
+msgstr "גישה"
msgid "AdminUsers|Access Git repositories"
msgstr ""
@@ -2788,12 +2801,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2831,7 +2838,7 @@ msgid "AdminUsers|Delete User %{username}?"
msgstr ""
msgid "AdminUsers|Delete user"
-msgstr ""
+msgstr "מחיקת משתמש"
msgid "AdminUsers|Delete user and contributions"
msgstr ""
@@ -2860,6 +2867,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2923,6 +2933,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2989,7 +3005,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3198,10 +3214,10 @@ msgid "AlertManagement|None"
msgstr ""
msgid "AlertManagement|Open"
-msgstr ""
+msgstr "פתוחה"
msgid "AlertManagement|Please try again."
-msgstr ""
+msgstr "× × ×œ× ×¡×•×ª שוב."
msgid "AlertManagement|Reported %{when}"
msgstr ""
@@ -3216,16 +3232,16 @@ msgid "AlertManagement|Runbook"
msgstr ""
msgid "AlertManagement|Service"
-msgstr ""
+msgstr "שירות"
msgid "AlertManagement|Severity"
-msgstr ""
+msgstr "חומרה"
msgid "AlertManagement|Start time"
-msgstr ""
+msgstr "מועד התחלה"
msgid "AlertManagement|Status"
-msgstr ""
+msgstr "מצב"
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
@@ -3252,16 +3268,16 @@ msgid "AlertManagement|This assignee cannot be assigned to this alert."
msgstr ""
msgid "AlertManagement|Tool"
-msgstr ""
+msgstr "כלי"
msgid "AlertManagement|Triggered"
msgstr ""
msgid "AlertManagement|Value"
-msgstr ""
+msgstr "ערך"
msgid "AlertManagement|View incident"
-msgstr ""
+msgstr "הצגת תקרית"
msgid "AlertMappingBuilder|Define fallback"
msgstr ""
@@ -3465,7 +3481,7 @@ msgid "Algorithm"
msgstr ""
msgid "All"
-msgstr ""
+msgstr "הכול"
msgid "All %{replicableType} are being scheduled for %{action}"
msgstr ""
@@ -3486,13 +3502,13 @@ msgid "All email addresses will be used to identify your commits."
msgstr ""
msgid "All environments"
-msgstr ""
+msgstr "כל הסביבות"
msgid "All epics"
msgstr ""
msgid "All groups and projects"
-msgstr ""
+msgstr "כל הקבוצות והמיזמי×"
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3510,10 +3526,10 @@ msgid "All paths are relative to the GitLab URL. Do not include %{relative_url_l
msgstr ""
msgid "All projects"
-msgstr ""
+msgstr "כל המיזמי×"
msgid "All projects selected"
-msgstr ""
+msgstr "כל ×”×ž×™×–×ž×™× × ×‘×—×¨×•"
msgid "All threads resolved"
msgstr ""
@@ -3621,16 +3637,16 @@ msgid "Allows you to add and manage Kubernetes clusters."
msgstr ""
msgid "Almost there"
-msgstr ""
+msgstr "כמעט סיימנו"
msgid "Almost there..."
-msgstr ""
+msgstr "כמעט סיימנו…"
msgid "Already blocked"
-msgstr ""
+msgstr "כבר חסו×"
msgid "Already have login and password?"
-msgstr ""
+msgstr "כבר יש לך ×©× ×ž×©×ª×ž×© וסיסמה?"
msgid "Also called \"Issuer\" or \"Relying party trust identifier\""
msgstr ""
@@ -3836,9 +3852,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3854,9 +3867,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3911,6 +3921,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4394,7 +4410,7 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4403,9 +4419,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4433,6 +4455,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4445,6 +4470,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4454,19 +4485,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4577,6 +4614,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4737,9 +4777,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4858,9 +4895,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4979,6 +5013,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -5156,6 +5196,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5348,9 +5391,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5637,9 +5677,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5652,12 +5689,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5723,9 +5766,6 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -6026,30 +6066,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6104,6 +6138,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6255,6 +6292,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6738,12 +6778,19 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6753,15 +6800,19 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6777,7 +6828,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7386,6 +7437,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7401,9 +7455,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -8085,7 +8136,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8569,9 +8620,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8710,9 +8758,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8725,6 +8770,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9451,7 +9499,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10692,6 +10740,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10704,6 +10755,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10716,12 +10770,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10741,6 +10801,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10873,9 +10936,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10945,6 +11005,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10993,9 +11056,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -11020,6 +11089,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -11038,6 +11110,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -11221,10 +11296,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11278,6 +11353,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11708,6 +11795,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11768,7 +11861,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -12279,6 +12372,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12354,6 +12450,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12561,9 +12660,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12612,6 +12708,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12651,6 +12750,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -13005,6 +13107,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -13017,6 +13122,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -13092,6 +13200,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -13113,6 +13224,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13449,6 +13566,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14826,6 +14946,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14913,6 +15036,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -15045,10 +15171,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -15093,7 +15219,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -15114,9 +15240,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -15171,19 +15294,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -15228,7 +15348,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -15240,6 +15360,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -15264,10 +15387,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15339,7 +15462,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15384,6 +15507,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15438,9 +15564,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15690,6 +15813,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15771,7 +15897,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -16122,6 +16248,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -16134,6 +16266,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -16167,7 +16302,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16695,10 +16830,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16835,6 +16970,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16973,7 +17111,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -17267,6 +17405,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -18026,6 +18167,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -18035,6 +18182,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -18126,6 +18279,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -18246,6 +18402,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18435,9 +18594,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18975,6 +19131,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19668,9 +19827,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19795,9 +19951,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19816,6 +19969,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -20269,10 +20425,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
+msgstr ""
+
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20783,6 +20942,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20831,6 +20993,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20849,6 +21014,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20861,7 +21029,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20876,9 +21044,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20912,6 +21086,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20936,6 +21116,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20975,6 +21158,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -21143,6 +21329,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -21260,9 +21449,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -21275,9 +21461,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21763,9 +21946,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -22144,7 +22324,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22337,12 +22517,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22385,9 +22559,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22397,21 +22568,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22427,9 +22589,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22578,9 +22737,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22764,6 +22920,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -23293,6 +23452,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23422,7 +23584,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23720,7 +23882,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23912,6 +24074,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -25049,6 +25214,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25490,13 +25700,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25508,9 +25715,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25775,6 +25979,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25967,9 +26174,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -27068,9 +27272,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -27122,6 +27323,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -27161,9 +27365,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27665,6 +27866,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27734,6 +27941,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27849,6 +28059,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28373,6 +28586,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28826,6 +29042,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -29097,6 +29316,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -29160,6 +29382,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29648,9 +29873,6 @@ msgstr[3] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29702,7 +29924,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29738,7 +29960,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29852,55 +30074,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29939,9 +30230,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -30053,9 +30341,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -30122,6 +30407,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30695,7 +30983,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30743,7 +31031,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30944,9 +31232,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -31174,6 +31459,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31525,6 +31813,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -33000,6 +33297,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -33051,12 +33351,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -33069,7 +33375,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -33300,7 +33606,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33520,6 +33826,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33556,9 +33865,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33712,6 +34018,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33850,9 +34159,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33898,6 +34213,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -34078,9 +34396,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -34300,9 +34615,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -34375,6 +34687,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35424,13 +35739,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35995,6 +36316,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -36214,9 +36538,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -36235,9 +36556,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -36286,6 +36613,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36442,6 +36772,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36919,9 +37252,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -37122,6 +37461,13 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -37380,9 +37726,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -37395,6 +37738,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37500,6 +37846,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37755,6 +38104,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37816,6 +38168,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -38374,6 +38729,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -38389,6 +38747,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38533,7 +38894,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38959,7 +39320,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38989,6 +39350,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -39095,6 +39480,13 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "branch name"
msgstr ""
@@ -39218,10 +39610,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39582,6 +39974,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39771,9 +40166,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39991,8 +40383,12 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -40027,8 +40423,12 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -40075,6 +40475,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -40138,9 +40541,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -40180,9 +40580,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -40210,12 +40607,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/hi_IN/gitlab.po b/locale/hi_IN/gitlab.po
index 65b0c4fdf4a..489c9899942 100644
--- a/locale/hi_IN/gitlab.po
+++ b/locale/hi_IN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: hi\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:16\n"
+"PO-Revision-Date: 2021-09-01 22:31\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/hr_HR/gitlab.po b/locale/hr_HR/gitlab.po
index e37c8a7a234..823d66635af 100644
--- a/locale/hr_HR/gitlab.po
+++ b/locale/hr_HR/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: hr\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:15\n"
+"PO-Revision-Date: 2021-09-01 22:30\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -427,6 +427,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -589,6 +595,9 @@ msgstr[2] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -727,9 +736,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -739,6 +745,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -904,6 +913,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1352,7 +1364,7 @@ msgstr[1] ""
msgstr[2] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -1639,10 +1651,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1669,10 +1681,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2449,7 +2461,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2677,12 +2689,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2749,6 +2755,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2812,6 +2821,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2878,7 +2893,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3724,9 +3739,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3742,9 +3754,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3799,6 +3808,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4276,7 +4291,7 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4285,9 +4300,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4315,6 +4336,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4327,6 +4351,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4336,19 +4366,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4459,6 +4495,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4618,9 +4657,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4738,9 +4774,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4858,6 +4891,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -5035,6 +5074,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5227,9 +5269,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5515,9 +5554,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5530,12 +5566,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5599,9 +5641,6 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5902,30 +5941,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5980,6 +6013,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6130,6 +6166,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6613,12 +6652,18 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6628,15 +6673,18 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6652,7 +6700,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7261,6 +7309,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7276,9 +7327,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7960,7 +8008,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8443,9 +8491,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8584,9 +8629,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8599,6 +8641,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9322,7 +9367,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10561,6 +10606,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10573,6 +10621,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10585,12 +10636,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10609,6 +10666,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10741,9 +10801,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10813,6 +10870,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10861,9 +10921,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10888,6 +10954,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10906,6 +10975,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -11086,10 +11158,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11140,6 +11212,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11569,6 +11653,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11629,7 +11719,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -12139,6 +12229,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12214,6 +12307,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12421,9 +12517,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12472,6 +12565,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12511,6 +12607,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12865,6 +12964,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12877,6 +12979,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12952,6 +13057,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12973,6 +13081,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13309,6 +13423,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14683,6 +14800,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14770,6 +14890,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14902,10 +15025,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14950,7 +15073,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14971,9 +15094,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -15028,19 +15148,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -15085,7 +15202,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -15097,6 +15214,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -15121,10 +15241,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15196,7 +15316,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15241,6 +15361,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15295,9 +15418,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15547,6 +15667,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15628,7 +15751,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15979,6 +16102,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15991,6 +16120,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -16024,7 +16156,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16552,10 +16684,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16690,6 +16822,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16828,7 +16963,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -17119,6 +17254,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17878,6 +18016,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17887,6 +18031,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17977,6 +18127,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -18097,6 +18250,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18286,9 +18442,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18826,6 +18979,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19519,9 +19675,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19645,9 +19798,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19666,6 +19816,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -20113,10 +20266,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20626,6 +20782,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20674,6 +20833,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20692,6 +20854,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20704,7 +20869,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20719,9 +20884,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20755,6 +20926,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20779,6 +20956,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20818,6 +20998,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20986,6 +21169,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -21103,9 +21289,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -21118,9 +21301,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21604,9 +21784,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21985,7 +22162,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22177,12 +22354,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22225,9 +22396,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22237,21 +22405,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22267,9 +22426,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22417,9 +22573,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22603,6 +22756,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -23128,6 +23284,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23257,7 +23416,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23554,7 +23713,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23746,6 +23905,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24883,6 +25045,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25324,13 +25531,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25342,9 +25546,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25609,6 +25810,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25801,9 +26005,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26902,9 +27103,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26956,6 +27154,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26995,9 +27196,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27499,6 +27697,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27568,6 +27772,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27682,6 +27889,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28201,6 +28411,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28651,6 +28864,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28921,6 +29137,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28984,6 +29203,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29461,9 +29683,6 @@ msgstr[2] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29515,7 +29734,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29551,7 +29770,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29665,55 +29884,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29752,9 +30040,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29866,9 +30151,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29935,6 +30217,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30508,7 +30793,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30556,7 +30841,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30757,9 +31042,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30985,6 +31267,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31336,6 +31621,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32809,6 +33103,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32860,12 +33157,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32878,7 +33181,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -33106,7 +33409,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33325,6 +33628,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33361,9 +33667,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33517,6 +33820,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33655,9 +33961,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33703,6 +34015,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33883,9 +34198,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -34105,9 +34417,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -34180,6 +34489,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35227,13 +35539,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35797,6 +36115,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -36016,9 +36337,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -36037,9 +36355,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -36088,6 +36412,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36244,6 +36571,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36721,9 +37051,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36922,6 +37258,12 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -37180,9 +37522,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -37195,6 +37534,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37300,6 +37642,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37555,6 +37900,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37615,6 +37963,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -38173,6 +38524,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -38188,6 +38542,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38332,7 +38689,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38758,7 +39115,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38788,6 +39145,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38893,6 +39274,12 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "branch name"
msgstr ""
@@ -39016,10 +39403,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39376,6 +39763,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39562,9 +39952,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39781,8 +40168,11 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39817,8 +40207,11 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39865,6 +40258,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39928,9 +40324,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39970,9 +40363,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -40000,12 +40390,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/hu_HU/gitlab.po b/locale/hu_HU/gitlab.po
index 43c8daa8040..b60bde8d7ea 100644
--- a/locale/hu_HU/gitlab.po
+++ b/locale/hu_HU/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: hu\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:28\n"
+"PO-Revision-Date: 2021-09-01 22:33\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/hy_AM/gitlab.po b/locale/hy_AM/gitlab.po
index 7a9becb430b..1d476cf73ba 100644
--- a/locale/hy_AM/gitlab.po
+++ b/locale/hy_AM/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: hy-AM\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:29\n"
+"PO-Revision-Date: 2021-09-01 22:33\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/id_ID/gitlab.po b/locale/id_ID/gitlab.po
index 11bb462a604..101e740fb4e 100644
--- a/locale/id_ID/gitlab.po
+++ b/locale/id_ID/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: id\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:14\n"
+"PO-Revision-Date: 2021-09-01 22:30\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -313,6 +313,10 @@ msgid "%d tag per image name"
msgid_plural "%d tags per image name"
msgstr[0] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -445,6 +449,9 @@ msgstr[0] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -583,9 +590,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -595,6 +599,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -756,6 +763,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1152,7 +1162,7 @@ msgid_plural "%d issues selected"
msgstr[0] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgid "1 merged merge request"
@@ -1417,10 +1427,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1447,10 +1457,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2227,7 +2237,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2455,12 +2465,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2527,6 +2531,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2590,6 +2597,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2656,7 +2669,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3500,9 +3513,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3518,9 +3528,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3575,6 +3582,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4040,7 +4053,7 @@ msgid "ApprovalRuleSummary|%{count} approval required from %{membersCount}"
msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCount}"
msgstr[0] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4049,9 +4062,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4079,6 +4098,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4091,6 +4113,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4100,19 +4128,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4223,6 +4257,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4380,9 +4417,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4498,9 +4532,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4616,6 +4647,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4793,6 +4830,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -4985,9 +5025,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5271,9 +5308,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5286,12 +5320,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5351,9 +5391,6 @@ msgid "Boards|Blocked by %{blockedByCount} %{issuableType}"
msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5654,30 +5691,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5732,6 +5763,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -5880,6 +5914,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6363,12 +6400,16 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6378,15 +6419,16 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6402,7 +6444,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7011,6 +7053,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7026,9 +7071,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7710,7 +7752,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8191,9 +8233,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8332,9 +8371,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8347,6 +8383,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9064,7 +9103,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10299,6 +10338,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10311,6 +10353,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10323,12 +10368,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10345,6 +10396,9 @@ msgid "DastSiteValidation|This will affect %d other profile targeting the same U
msgid_plural "DastSiteValidation|This will affect %d other profiles targeting the same URL."
msgstr[0] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10477,9 +10531,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10549,6 +10600,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10597,9 +10651,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10624,6 +10684,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10642,6 +10705,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10816,10 +10882,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -10864,6 +10930,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11291,6 +11369,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11351,7 +11435,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11859,6 +11943,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -11934,6 +12021,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12141,9 +12231,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12192,6 +12279,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12231,6 +12321,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12585,6 +12678,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12597,6 +12693,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12672,6 +12771,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12693,6 +12795,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13029,6 +13137,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14397,6 +14508,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14484,6 +14598,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14616,10 +14733,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14664,7 +14781,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14685,9 +14802,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14742,19 +14856,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14799,7 +14910,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14811,6 +14922,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14835,10 +14949,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -14910,7 +15024,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -14955,6 +15069,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15009,9 +15126,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15261,6 +15375,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15342,7 +15459,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15693,6 +15810,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15705,6 +15828,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15738,7 +15864,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16266,10 +16392,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16400,6 +16526,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16538,7 +16667,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16823,6 +16952,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17582,6 +17714,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17591,6 +17729,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17679,6 +17823,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17799,6 +17946,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -17988,9 +18138,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18528,6 +18675,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19221,9 +19371,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19345,9 +19492,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19366,6 +19510,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19801,10 +19948,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20312,6 +20462,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20360,6 +20513,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20378,6 +20534,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20390,7 +20549,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20405,9 +20564,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20441,6 +20606,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20465,6 +20636,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20504,6 +20678,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20672,6 +20849,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20789,9 +20969,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20804,9 +20981,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21286,9 +21460,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21667,7 +21838,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -21857,12 +22028,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -21905,9 +22070,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -21917,21 +22079,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -21947,9 +22100,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22095,9 +22245,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22281,6 +22428,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22798,6 +22948,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -22927,7 +23080,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23222,7 +23375,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23414,6 +23567,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24551,6 +24707,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -24992,13 +25193,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25010,9 +25208,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25277,6 +25472,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25469,9 +25667,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26570,9 +26765,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26624,6 +26816,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26663,9 +26858,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27167,6 +27359,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27236,6 +27434,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27348,6 +27549,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -27857,6 +28061,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28301,6 +28508,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28569,6 +28779,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28632,6 +28845,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29087,9 +29303,6 @@ msgstr[0] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29141,7 +29354,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29177,7 +29390,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29291,55 +29504,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityPolicies|Environment(s)"
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29378,9 +29660,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29492,9 +29771,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29561,6 +29837,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30134,7 +30413,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30182,7 +30461,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30383,9 +30662,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30607,6 +30883,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -30958,6 +31237,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32427,6 +32715,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32478,12 +32769,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32496,7 +32793,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32718,7 +33015,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -32935,6 +33232,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -32971,9 +33271,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33127,6 +33424,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33265,9 +33565,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33313,6 +33619,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33493,9 +33802,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33715,9 +34021,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33790,6 +34093,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -34833,13 +35139,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35401,6 +35713,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35620,9 +35935,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35641,9 +35953,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35692,6 +36010,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -35848,6 +36169,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36325,9 +36649,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36522,6 +36852,10 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36780,9 +37114,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36795,6 +37126,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -36900,6 +37234,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37155,6 +37492,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37213,6 +37553,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37771,6 +38114,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37786,6 +38132,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -37930,7 +38279,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38356,7 +38705,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38386,6 +38735,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38489,6 +38862,10 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+
msgid "branch name"
msgstr ""
@@ -38612,10 +38989,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -38964,6 +39341,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39144,9 +39524,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39361,8 +39738,9 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39397,8 +39775,9 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39445,6 +39824,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39508,9 +39890,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39550,9 +39929,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39580,12 +39956,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/ig_NG/gitlab.po b/locale/ig_NG/gitlab.po
index 9c2b8be147f..e2495654b0c 100644
--- a/locale/ig_NG/gitlab.po
+++ b/locale/ig_NG/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ig\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:23\n"
+"PO-Revision-Date: 2021-09-01 22:32\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -313,6 +313,10 @@ msgid "%d tag per image name"
msgid_plural "%d tags per image name"
msgstr[0] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -445,6 +449,9 @@ msgstr[0] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -583,9 +590,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -595,6 +599,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -756,6 +763,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1152,7 +1162,7 @@ msgid_plural "%d issues selected"
msgstr[0] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgid "1 merged merge request"
@@ -1417,10 +1427,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1447,10 +1457,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2227,7 +2237,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2455,12 +2465,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2527,6 +2531,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2590,6 +2597,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2656,7 +2669,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3500,9 +3513,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3518,9 +3528,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3575,6 +3582,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4040,7 +4053,7 @@ msgid "ApprovalRuleSummary|%{count} approval required from %{membersCount}"
msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCount}"
msgstr[0] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4049,9 +4062,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4079,6 +4098,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4091,6 +4113,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4100,19 +4128,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4223,6 +4257,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4380,9 +4417,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4498,9 +4532,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4616,6 +4647,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4793,6 +4830,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -4985,9 +5025,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5271,9 +5308,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5286,12 +5320,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5351,9 +5391,6 @@ msgid "Boards|Blocked by %{blockedByCount} %{issuableType}"
msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5654,30 +5691,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5732,6 +5763,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -5880,6 +5914,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6363,12 +6400,16 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6378,15 +6419,16 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6402,7 +6444,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7011,6 +7053,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7026,9 +7071,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7710,7 +7752,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8191,9 +8233,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8332,9 +8371,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8347,6 +8383,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9064,7 +9103,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10299,6 +10338,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10311,6 +10353,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10323,12 +10368,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10345,6 +10396,9 @@ msgid "DastSiteValidation|This will affect %d other profile targeting the same U
msgid_plural "DastSiteValidation|This will affect %d other profiles targeting the same URL."
msgstr[0] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10477,9 +10531,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10549,6 +10600,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10597,9 +10651,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10624,6 +10684,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10642,6 +10705,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10816,10 +10882,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -10864,6 +10930,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11291,6 +11369,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11351,7 +11435,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11859,6 +11943,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -11934,6 +12021,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12141,9 +12231,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12192,6 +12279,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12231,6 +12321,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12585,6 +12678,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12597,6 +12693,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12672,6 +12771,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12693,6 +12795,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13029,6 +13137,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14397,6 +14508,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14484,6 +14598,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14616,10 +14733,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14664,7 +14781,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14685,9 +14802,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14742,19 +14856,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14799,7 +14910,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14811,6 +14922,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14835,10 +14949,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -14910,7 +15024,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -14955,6 +15069,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15009,9 +15126,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15261,6 +15375,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15342,7 +15459,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15693,6 +15810,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15705,6 +15828,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15738,7 +15864,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16266,10 +16392,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16400,6 +16526,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16538,7 +16667,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16823,6 +16952,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17582,6 +17714,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17591,6 +17729,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17679,6 +17823,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17799,6 +17946,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -17988,9 +18138,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18528,6 +18675,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19221,9 +19371,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19345,9 +19492,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19366,6 +19510,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19801,10 +19948,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20312,6 +20462,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20360,6 +20513,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20378,6 +20534,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20390,7 +20549,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20405,9 +20564,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20441,6 +20606,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20465,6 +20636,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20504,6 +20678,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20672,6 +20849,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20789,9 +20969,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20804,9 +20981,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21286,9 +21460,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21667,7 +21838,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -21857,12 +22028,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -21905,9 +22070,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -21917,21 +22079,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -21947,9 +22100,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22095,9 +22245,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22281,6 +22428,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22798,6 +22948,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -22927,7 +23080,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23222,7 +23375,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23414,6 +23567,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24551,6 +24707,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -24992,13 +25193,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25010,9 +25208,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25277,6 +25472,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25469,9 +25667,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26570,9 +26765,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26624,6 +26816,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26663,9 +26858,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27167,6 +27359,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27236,6 +27434,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27348,6 +27549,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -27857,6 +28061,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28301,6 +28508,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28569,6 +28779,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28632,6 +28845,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29087,9 +29303,6 @@ msgstr[0] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29141,7 +29354,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29177,7 +29390,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29291,55 +29504,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityPolicies|Environment(s)"
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29378,9 +29660,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29492,9 +29771,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29561,6 +29837,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30134,7 +30413,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30182,7 +30461,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30383,9 +30662,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30607,6 +30883,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -30958,6 +31237,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32427,6 +32715,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32478,12 +32769,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32496,7 +32793,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32718,7 +33015,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -32935,6 +33232,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -32971,9 +33271,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33127,6 +33424,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33265,9 +33565,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33313,6 +33619,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33493,9 +33802,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33715,9 +34021,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33790,6 +34093,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -34833,13 +35139,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35401,6 +35713,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35620,9 +35935,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35641,9 +35953,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35692,6 +36010,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -35848,6 +36169,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36325,9 +36649,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36522,6 +36852,10 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36780,9 +37114,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36795,6 +37126,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -36900,6 +37234,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37155,6 +37492,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37213,6 +37553,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37771,6 +38114,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37786,6 +38132,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -37930,7 +38279,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38356,7 +38705,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38386,6 +38735,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38489,6 +38862,10 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+
msgid "branch name"
msgstr ""
@@ -38612,10 +38989,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -38964,6 +39341,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39144,9 +39524,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39361,8 +39738,9 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39397,8 +39775,9 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39445,6 +39824,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39508,9 +39890,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39550,9 +39929,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39580,12 +39956,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/is_IS/gitlab.po b/locale/is_IS/gitlab.po
index 30111efeade..91986148ea0 100644
--- a/locale/is_IS/gitlab.po
+++ b/locale/is_IS/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: is\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:13\n"
+"PO-Revision-Date: 2021-09-01 22:30\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/it/gitlab.po b/locale/it/gitlab.po
index 8576a6511db..14842248cbc 100644
--- a/locale/it/gitlab.po
+++ b/locale/it/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: it\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:29\n"
+"PO-Revision-Date: 2021-09-01 22:33\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] "%{count} partecipanti"
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1325,7 +1336,7 @@ msgid "2FA"
msgstr "2FA"
msgid "2FADevice|Registered On"
-msgstr "Disp. Autent. a 2 fattori (2FA)|Registrato su"
+msgstr ""
msgid "3 days"
msgstr "3 giorni"
@@ -1343,19 +1354,19 @@ msgid "30+ contributions"
msgstr ""
msgid "403|Please contact your GitLab administrator to get permission."
-msgstr "403|Contatta l'amministratore di GitLab per ottenere l'autorizzazione."
+msgstr ""
msgid "403|You don't have the permission to access this page."
-msgstr "403|Non hai i permessi per accedere a questa pagina."
+msgstr ""
msgid "404|Make sure the address is correct and the page hasn't moved."
-msgstr "404|Assicurarsi che l'indirizzo sia corretto e che la pagina non sia stata spostata."
+msgstr ""
msgid "404|Page Not Found"
-msgstr "404|Pagina non trovata"
+msgstr ""
msgid "404|Please contact your GitLab administrator if you think this is a mistake."
-msgstr "404 | Si prega di contattare il proprio amministratore GitLab se credi sia un errore."
+msgstr ""
msgid "7 days"
msgstr ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr "Artefatti"
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8216,7 +8261,7 @@ msgid "Commits|No related merge requests found"
msgstr ""
msgid "Committed by"
-msgstr "Committato da "
+msgstr ""
msgid "Commit…"
msgstr ""
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr "Rilascio"
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr "Ambienti"
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr "Aggiornato"
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr "Se disabilitato, un ramo locale divergente non verrà automaticamente ag
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21722,7 +21896,7 @@ msgid "More information and share feedback"
msgstr ""
msgid "More information is available|here"
-msgstr "Ulteriori informazioni sono disponibili | qui"
+msgstr ""
msgid "More information."
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr "Nuova Branch"
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr "Novembre"
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25339,7 +25537,7 @@ msgid "Profiles| You are about to permanently delete %{yourAccount}, and all of
msgstr ""
msgid "Profiles| You are going to change the username %{currentUsernameBold} to %{newUsernameBold}. Profile and projects will be redirected to the %{newUsername} namespace but this redirect will expire once the %{currentUsername} namespace is registered by another user or group. Please update your Git repository remotes as soon as possible."
-msgstr "Profiles| Stai per cambiare il nome utente %{currentUsernameBold} in %{newUsernameBold}. Profilo e progetti verranno reindirizzati allo spazio dei nomi %{newUsername} ma questo reindirizzamento scadrà quando lo spazio dei nomi %{currentUsername} viene registrato da un altro utente o gruppo. Per favore aggiorna i remote repository di Git il prima possibile."
+msgstr ""
msgid "Profiles|\"Busy\" will be shown next to your name"
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33056,7 +33356,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "The fork relationship has been removed."
-msgstr "La relazione del fork è stata rimossa"
+msgstr ""
msgid "The form contains the following errors:"
msgstr ""
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -34088,7 +34397,7 @@ msgid "This may expose confidential information as the selected fork is in anoth
msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
-msgstr "Questo significa che non è possibile effettuare push di codice fino a che non crei una repository vuota o ne importi una esistente"
+msgstr ""
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36074,7 +36401,7 @@ msgid "Use webhook"
msgstr ""
msgid "Use your global notification setting"
-msgstr "Usa le tue impostazioni globali "
+msgstr ""
msgid "Use your smart card to authenticate with the LDAP server."
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37059,7 +37397,7 @@ msgid "We detected potential spam in the %{humanized_resource_name}. Please solv
msgstr ""
msgid "We don't have enough data to show this stage."
-msgstr "Non ci sono sufficienti dati da mostrare su questo stadio"
+msgstr ""
msgid "We have found the following errors:"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr "Non puoi scrivere su un'istanza di GitLab Geo secondaria di sola lettura. Per favore utilizza invece %{link_to_primary_node}."
@@ -38131,7 +38484,7 @@ msgstr "Hai raggiunto il tuo limite di progetto"
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/ja/gitlab.po b/locale/ja/gitlab.po
index d702b7a03c3..d4e6ec7e03f 100644
--- a/locale/ja/gitlab.po
+++ b/locale/ja/gitlab.po
@@ -14,13 +14,13 @@ msgstr ""
"X-Crowdin-Language: ja\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:29\n"
+"PO-Revision-Date: 2021-09-01 22:33\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
msgid " %{start} to %{end}"
-msgstr " %{start} ã‹ã‚‰ %{end} "
+msgstr ""
msgid " (from %{timeoutSource})"
msgstr " (%{timeoutSource} ã‹ã‚‰)"
@@ -313,6 +313,10 @@ msgid "%d tag per image name"
msgid_plural "%d tags per image name"
msgstr[0] "ç”»åƒåã”ã¨ã«%d 件ã®ã‚¿ã‚°"
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] "%d 件ã®ã‚¤ã‚·ãƒ¥ãƒ¼ãŒæœªå‰²å½“"
@@ -445,6 +449,9 @@ msgstr[0] "%{count} 人ã®å‚加者"
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr "%{count} 件ã®é–¢é€£ã—㟠%{pluralized_subject}: %{links}"
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr "åˆè¨ˆã‚¦ã‚§ã‚¤ãƒˆ %{count}"
@@ -583,9 +590,6 @@ msgstr "%{labelStart}メソッド:%{labelEnd} %{method}"
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr "%{labelStart}åå‰ç©ºé–“:%{labelEnd} %{namespace}"
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr "%{labelStart} スキャンタイプ:%{labelEnd} %{reportType}"
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr "%{labelStart}スキャナー:%{labelEnd} %{scanner}"
@@ -595,6 +599,9 @@ msgstr "%{labelStart}é€ä¿¡ã—ãŸãƒªã‚¯ã‚¨ã‚¹ãƒˆ:%{labelEnd} %{headers}"
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr "%{labelStart}é‡è¦åº¦:%{labelEnd} %{severity}"
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr "%{labelStart}修正ã•ã‚Œã¦ã„ãªã„レスãƒãƒ³ã‚¹:%{labelEnd} %{headers}"
@@ -756,6 +763,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr "%{seconds} 秒"
@@ -1152,7 +1162,7 @@ msgid_plural "%d issues selected"
msgstr[0] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] "%d 件ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆãŒé¸æŠžã•ã‚Œã¾ã—ãŸ"
msgid "1 merged merge request"
@@ -1417,10 +1427,10 @@ msgstr "APIキー"
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1447,10 +1457,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2227,8 +2237,8 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
-msgstr "å…¨ã¦ã®ã‚¸ãƒ§ãƒ–ã‚’åœæ­¢ã—ã¾ã™ã€‚ã“ã‚Œã«ã‚ˆã‚Šç¾åœ¨å®Ÿè¡Œä¸­ã®ã‚¸ãƒ§ãƒ–ã¯åœæ­¢ã•ã‚Œã¾ã™ã€‚"
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
+msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "統計ã®èª­ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
@@ -2455,12 +2465,6 @@ msgstr "ブロック済ã¿"
msgid "AdminUsers|Blocking user has the following effects:"
msgstr "ユーザーã®ãƒ–ロックã«ã¯æ¬¡ã®åŠ¹æžœãŒã‚ã‚Šã¾ã™:"
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr "サインインã¾ãŸã¯ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹æƒ…å ±ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“"
@@ -2527,6 +2531,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr "シートを使用中"
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr "ã‚ãªãŸã§ã™ï¼"
@@ -2590,6 +2597,12 @@ msgstr "ユーザーã«Eメールをé€ä¿¡ã™ã‚‹"
msgid "AdminUsers|Sort by"
msgstr "並ã³æ›¿ãˆ"
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr "ユーザーã¯ãƒ­ã‚°ã‚¢ã‚¦ãƒˆã•ã‚Œã¾ã™"
@@ -2656,7 +2669,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -2669,10 +2682,10 @@ msgid "AdminUsers|Without projects"
msgstr "プロジェクトãªã—"
msgid "AdminUsers|You are about to permanently delete the user %{username}. Issues, merge requests, and groups linked to them will be transferred to a system-wide \"Ghost-user\". To avoid data loss, consider using the %{strongStart}block user%{strongEnd} feature instead. Once you %{strongStart}Delete user%{strongEnd}, it cannot be undone or recovered."
-msgstr "ã‚ãªãŸã¯ãƒ¦ãƒ¼ã‚¶ãƒ¼ %{username} を完全ã«å‰Šé™¤ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚ユーザーã«ãƒªãƒ³ã‚¯ã—ã¦ã„ã‚‹ã€èª²é¡Œã€ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã€ãŠã‚ˆã³ã‚°ãƒ«ãƒ¼ãƒ—ã¯ã€ã‚·ã‚¹ãƒ†ãƒ å…¨ä½“ã®ã€ŒGhost ユーザーã€ã«è»¢é€ã•ã‚Œã¾ã™ã€‚データã®æ失をé¿ã‘ã‚‹ãŸã‚ã«ã¯ã€å‰Šé™¤ã®ä»£ã‚ã‚Šã«%{strongEnd} ユーザーã®ãƒ–ロック機能%{strongStart}を使用ã™ã‚‹ã“ã¨ã‚’検討ã—ã¦ãã ã•ã„。%{strongEnd}] ユーザーã®å‰Šé™¤ %{strongStart}ã™ã‚‹ã¨ã€å…ƒã«æˆ»ã™ã“ã¨ã¯ã§ãã¾ã›ã‚“ã—復元もã§ãã¾ã›ã‚“。"
+msgstr ""
msgid "AdminUsers|You are about to permanently delete the user %{username}. This will delete all of the issues, merge requests, and groups linked to them. To avoid data loss, consider using the %{strongStart}block user%{strongEnd} feature instead. Once you %{strongStart}Delete user%{strongEnd}, it cannot be undone or recovered."
-msgstr "ã‚ãªãŸã¯ãƒ¦ãƒ¼ã‚¶ãƒ¼ %{username}を完全ã«å‰Šé™¤ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚ユーザーã«ãƒªãƒ³ã‚¯ã—ã¦ã„ã‚‹ã€èª²é¡Œã€ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã€ãŠã‚ˆã³ã‚°ãƒ«ãƒ¼ãƒ—ã¯å‰Šé™¤ã•ã‚Œã¾ã™ã€‚データã®æ失をé¿ã‘ã‚‹ãŸã‚ã«ã¯ã€å‰Šé™¤ã®ä»£ã‚ã‚Šã«%{strongEnd} ユーザーã®ãƒ–ロック機能%{strongStart}を使用ã™ã‚‹ã“ã¨ã‚’検討ã—ã¦ãã ã•ã„。%{strongEnd}] ユーザーã®å‰Šé™¤ %{strongStart}ã™ã‚‹ã¨ã€å…ƒã«æˆ»ã™ã“ã¨ã¯ã§ãã¾ã›ã‚“ã—復元もã§ãã¾ã›ã‚“。"
+msgstr ""
msgid "AdminUsers|You can always block their account again if needed."
msgstr "å¿…è¦ãªã¨ãã¯ã„ã¤ã§ã‚‚ã“れらã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’ブロックã§ãã¾ã™ã€‚"
@@ -3500,9 +3513,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr "ボードリストã®å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
-
msgid "An error occurred while fetching the job log."
msgstr "ã“ã®ã‚¸ãƒ§ãƒ–ã®ãƒ­ã‚°ã‚’フェッãƒã™ã‚‹é–“ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
@@ -3518,9 +3528,6 @@ msgstr "ジョブã®å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "An error occurred while fetching the latest pipeline."
msgstr "最新ã®ãƒ‘イプラインã®å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
-msgid "An error occurred while fetching the pipeline."
-msgstr "パイプラインã®å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr "リリースã®å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
@@ -3575,6 +3582,12 @@ msgstr "イシューã®èª­ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "An error occurred while loading merge requests."
msgstr "マージリクエストã®ãƒ­ãƒ¼ãƒ‰ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4040,7 +4053,7 @@ msgid "ApprovalRuleSummary|%{count} approval required from %{membersCount}"
msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCount}"
msgstr[0] "%{membersCount} åã®ã†ã¡ %{count} åã‹ã‚‰ã®æ‰¿èªãŒå¿…è¦"
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4049,9 +4062,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4079,6 +4098,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr "ルールå"
@@ -4091,6 +4113,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr "ターゲットブランãƒ"
@@ -4100,19 +4128,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4223,6 +4257,9 @@ msgstr "ã“ã®ãƒ—ロジェクトã®ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–を解除ã—ã¦ã‚ˆã‚ã—ã„ã§
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr "ã“ã®ã‚³ãƒ¡ãƒ³ãƒˆã®ç·¨é›†ã‚’キャンセルã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
@@ -4380,9 +4417,6 @@ msgstr "アーティファクトã¯æ­£å¸¸ã«å‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚"
msgid "Artifacts"
msgstr "アーティファクト"
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4498,9 +4532,6 @@ msgstr "担当者ã«æ¨©é™ãŒã‚ã‚Šã¾ã›ã‚“"
msgid "Assignee lists not available with your current license"
msgstr "ç¾åœ¨ã®ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã§ã¯æ‹…当者リストを利用ã§ãã¾ã›ã‚“"
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr "担当者一覧ã«ã¯ã€é¸æŠžã—ãŸãƒ¦ãƒ¼ã‚¶ãƒ¼ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ã‚‹ã™ã¹ã¦ã®ã‚¤ã‚·ãƒ¥ãƒ¼ãŒè¡¨ç¤ºã•ã‚Œã¾ã™ã€‚"
-
msgid "Assignee(s)"
msgstr "担当者"
@@ -4616,6 +4647,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4793,6 +4830,9 @@ msgstr "Let's Encryptを用ã„ãŸè‡ªå‹•è¨¼æ˜Žæ›¸ç®¡ç†"
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -4985,9 +5025,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr "é¸æŠžã—ãŸã‚³ãƒŸãƒƒãƒˆã§ã¯ã˜ã‚ã‚‹"
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr "ç¾åœ¨ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã®SSHホストキーã®ãƒ•ã‚£ãƒ³ã‚¬ãƒ¼ãƒ—リントã§ã™ã€‚"
@@ -5271,9 +5308,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5286,12 +5320,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr "ボード"
@@ -5351,9 +5391,6 @@ msgid "Boards|Blocked by %{blockedByCount} %{issuableType}"
msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr "折りãŸãŸã¿"
@@ -5654,30 +5691,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5732,6 +5763,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr "追加ã®ãƒ‘イプライン時間(分)を購入ã™ã‚‹"
@@ -5880,6 +5914,9 @@ msgstr "CONTRIBUTING"
msgid "CPU"
msgstr "CPU"
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6363,12 +6400,16 @@ msgstr "ユーザーåãŒåˆ©ç”¨å¯èƒ½ã‹ç¢ºèªã—ã¦ã„ã¾ã™..."
msgid "Checkout"
msgstr "Checkout"
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr "ユーザー・年間ã‚ãŸã‚Š %{selectedPlanPrice} ドル"
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6378,15 +6419,16 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr "%{name} 㮠GitLab サブスクリプション"
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr "%{selectedPlanText} プラン"
msgid "Checkout|%{startDate} - %{endDate}"
msgstr "%{startDate} ã‹ã‚‰ %{endDate} ã¾ã§"
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6402,7 +6444,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr "請求先ä½æ‰€"
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7011,6 +7053,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7026,9 +7071,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7710,7 +7752,7 @@ msgstr "ドメインを指定ã™ã‚‹ã¨ã€Auto Review App 㨠Auto Deployステãƒ
msgid "ClusterIntegration|Subnets"
msgstr "サブãƒãƒƒãƒˆ"
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8191,9 +8233,6 @@ msgstr "コンプライアンスダッシュボード"
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr "コンプライアンスフレームワーク(オプション)"
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8332,9 +8371,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr "ウェブãŠã‚ˆã³APIリクエストã®åˆ¶é™ã‚’設定ã™ã‚‹ã€‚"
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr "プロジェクトã«é€ä¿¡ã§ãるインãƒã‚¦ãƒ³ãƒ‰ã‚¢ãƒ©ãƒ¼ãƒˆã®æ•°ã«åˆ¶é™ã‚’設定ã—ã¾ã™ã€‚"
-
msgid "Configure paths to be protected by Rack Attack."
msgstr "Rack 攻撃を防御ã™ã‚‹ãƒ‘スを設定ã—ã¾ã™ã€‚"
@@ -8347,6 +8383,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9064,7 +9103,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10299,6 +10338,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10311,6 +10353,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10323,12 +10368,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10345,6 +10396,9 @@ msgid "DastSiteValidation|This will affect %d other profile targeting the same U
msgid_plural "DastSiteValidation|This will affect %d other profiles targeting the same URL."
msgstr[0] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10477,9 +10531,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10549,6 +10600,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10597,9 +10651,15 @@ msgstr "アーãƒãƒ•ã‚¡ã‚¯ãƒˆã‚’削除"
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr "コメントを削除"
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10624,6 +10684,9 @@ msgstr "プロジェクトã®å‰Šé™¤"
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10642,6 +10705,9 @@ msgstr "ソースブランãƒã‚’削除"
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr "ã“ã®æ·»ä»˜ãƒ•ã‚¡ã‚¤ãƒ«ã‚’削除"
@@ -10816,12 +10882,12 @@ msgstr "ä¾å­˜é–¢ä¿‚スキャン"
msgid "Dependency proxy"
msgstr "ä¾å­˜é–¢ä¿‚プロキシ"
-msgid "Dependency proxy URL"
-msgstr "ä¾å­˜é–¢ä¿‚プロキシURL"
-
msgid "Dependency proxy feature is limited to public groups for now."
msgstr "ä¾å­˜é–¢ä¿‚プロキシ機能ã¯ã€ç¾åœ¨å…¬é–‹ã‚°ãƒ«ãƒ¼ãƒ—ã«åˆ¶é™ã•ã‚Œã¦ã„ã¾ã™ã€‚"
+msgid "Dependency proxy image prefix"
+msgstr ""
+
msgid "DependencyProxy|Toggle Dependency Proxy"
msgstr "ä¾å­˜é–¢ä¿‚プロキシã®åˆ‡ã‚Šæ›¿ãˆ"
@@ -10864,6 +10930,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11291,6 +11369,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11351,7 +11435,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11859,6 +11943,9 @@ msgstr "ジオノードを編集"
msgid "Edit Group Hook"
msgstr "グループフックを編集"
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr "ラベルã®ç·¨é›†"
@@ -11934,6 +12021,9 @@ msgstr "公開デプロイキーã®ç·¨é›†"
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12141,9 +12231,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr "インシデント管ç†ã‚¤ãƒ³ãƒã‚¦ãƒ³ãƒ‰ã‚¢ãƒ©ãƒ¼ãƒˆåˆ¶é™ã‚’有効ã«ã™ã‚‹"
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12192,6 +12279,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12231,6 +12321,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12585,6 +12678,9 @@ msgstr "デプロイ"
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr "Review Appを有効ã«ã™ã‚‹"
@@ -12597,6 +12693,9 @@ msgstr "環境一覧"
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr "環境ã¨ã¯ã€staging ã‚„ production ã¨ã„ã£ãŸã‚³ãƒ¼ãƒ‰ã‚’デプロイã™ã‚‹å…ˆã§ã™ã€‚"
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr "クラスターã«Elastic Stackをインストールã—ã¦ã€å…¨æ–‡æ¤œç´¢ç­‰ã®é«˜åº¦ãªæ‹¡å¼µã‚¯ã‚¨ãƒªæ©Ÿèƒ½ã‚’有効ã«ã—ã¾ã™ã€‚"
@@ -12672,6 +12771,9 @@ msgstr "環境ã®åœæ­¢"
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12693,6 +12795,12 @@ msgstr "更新済ã¿"
msgid "Environments|You don't have any environments right now"
msgstr "ã¾ã ç’°å¢ƒãŒã‚ã‚Šã¾ã›ã‚“。"
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr "ä¿è­·"
@@ -13029,6 +13137,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14397,6 +14508,9 @@ msgstr "フォーク"
msgid "Format: %{dateFormat}"
msgstr "フォーマット:%{dateFormat}"
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr "%{gitlab_ci_yml} ã«ã‚¨ãƒ©ãƒ¼ãŒã‚ã‚Šã¾ã™"
@@ -14484,6 +14598,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14616,10 +14733,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr "ジオステータス"
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14664,7 +14781,7 @@ msgstr "å‰å›žã®ç¢ºèªæ—¥æ™‚"
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14685,9 +14802,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr "ã¾ã åŒæœŸã—ã¦ã„ã¾ã›ã‚“。"
@@ -14742,19 +14856,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14799,7 +14910,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14811,6 +14922,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr "状態"
@@ -14835,11 +14949,11 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
-msgstr "データベースã¯ç¾åœ¨ãƒ—ライマリーノードã®å¾Œã‚ã« %{db_lag} ã§ã™ã€‚"
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
+msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
-msgstr "ノードã¯ç¾åœ¨ã€ãƒ—ライマリノードã®å¾Œã‚ã« %{minutes_behind} ã§ã™ã€‚"
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
+msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
msgstr ""
@@ -14910,7 +15024,7 @@ msgstr "スケジューラ待ã¡"
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -14955,6 +15069,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr "ã“ã®GitLabサーãƒãƒ¼ã¯Git LFSãŒç„¡åŠ¹ã«ãªã£ã¦ã„ã¾ã™ã€‚管ç†è€…ã«é€£çµ¡ã—ã¦ãã ã•ã„。"
@@ -15009,9 +15126,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr "GitLab インãƒãƒ¼ãƒˆ"
@@ -15261,6 +15375,9 @@ msgstr "%{time_ago} ã«ã‚¢ã‚¯ã‚»ã‚¹è¨±å¯"
msgid "Given epic is already related to this epic."
msgstr "指定ã•ã‚ŒãŸã‚¨ãƒ”ックã¯ã™ã§ã«ã“ã®ã‚¨ãƒ”ックã¨é–¢é€£ã—ã¦ã„ã¾ã™ã€‚"
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr "グローãƒãƒ« ショートカット"
@@ -15342,7 +15459,7 @@ msgstr "親ã«ç§»å‹•"
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15693,6 +15810,12 @@ msgstr "申ã—訳ã‚ã‚Šã¾ã›ã‚“ã€æ¤œç´¢ã«ãƒžãƒƒãƒã™ã‚‹ã‚¨ãƒ”ックã¯ã‚ã‚Š
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr "ロードマップã¯æ™‚é–“ã®çµŒéŽã¨ã¨ã‚‚ã«ã‚¨ãƒ”ックã®é€²è¡Œã‚’表示ã—ã¾ã™"
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15705,6 +15828,9 @@ msgstr "ロードマップを表示ã™ã‚‹ã«ã¯ã€ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã¾ãŸã¯ã
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr "検索範囲を広ã’ã‚‹ã«ã¯ã€ãƒ•ã‚£ãƒ«ã‚¿ã‚’変更ã¾ãŸã¯å‰Šé™¤ã—ã¾ã™ã€‚ %{startDate} ã‹ã‚‰ %{endDate} ã¾ã§"
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15738,7 +15864,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16266,12 +16392,12 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
-msgstr "アラートã®é‡ã‚’減らã™ã®ã«å½¹ç«‹ã¡ã¾ã™(例:作æˆã™ã‚‹ã‚¤ã‚·ãƒ¥ãƒ¼ãŒå¤šã™ãŽã‚‹å ´åˆ)"
-
msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
+msgstr ""
+
msgid "Helps reduce request volume for protected paths"
msgstr "ä¿è­·ã•ã‚ŒãŸãƒ‘スã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆé‡ã‚’減らã™ã®ã«å½¹ç«‹ã¡ã¾ã™"
@@ -16400,6 +16526,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16419,7 +16548,7 @@ msgid "I accept the %{terms_link}"
msgstr "%{terms_link} ã«åŒæ„ã™ã‚‹"
msgid "I accept the|Terms of Service and Privacy Policy"
-msgstr "利用è¦ç´„ã¨ãƒ—ライãƒã‚·ãƒ¼ãƒãƒªã‚·ãƒ¼"
+msgstr ""
msgid "I forgot my password"
msgstr "パスワードを忘れã¾ã—ãŸ"
@@ -16538,7 +16667,7 @@ msgstr "無効ã«ã™ã‚‹ã¨ã€åˆ†å²ã—ãŸãƒ­ãƒ¼ã‚«ãƒ«ãƒ–ランãƒã¯ã€ãƒ­ãƒ¼ã‚«
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16823,6 +16952,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17582,6 +17714,12 @@ msgstr ""
msgid "Insert code"
msgstr "コードを挿入"
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17591,6 +17729,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr "候補を挿入ã™ã‚‹"
@@ -17679,6 +17823,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17799,6 +17946,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -17988,9 +18138,6 @@ msgstr "メンãƒãƒ¼ã‚’招待ã™ã‚‹"
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18528,6 +18675,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19221,9 +19371,6 @@ msgstr "ラベル"
msgid "Label actions dropdown"
msgstr "ラベルアクションドロップダウン"
-msgid "Label lists show all issues with the selected label."
-msgstr "ラベル一覧ã«ã¯ã€é¸æŠžã—ãŸãƒ©ãƒ™ãƒ«ãŒä»˜ã„ãŸã™ã¹ã¦ã®ã‚¤ã‚·ãƒ¥ãƒ¼ãŒè¡¨ç¤ºã•ã‚Œã¾ã™ã€‚"
-
msgid "Label priority"
msgstr ""
@@ -19345,9 +19492,6 @@ msgstr "最後ã®è¿”ä¿¡"
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr "最後ã®ãƒªãƒã‚¸ãƒˆãƒªãƒã‚§ãƒƒã‚¯ã‚’実行"
-
msgid "Last seen"
msgstr "最終閲覧"
@@ -19366,6 +19510,9 @@ msgstr "最後ã«æˆåŠŸã—ãŸåŒæœŸ"
msgid "Last successful update"
msgstr "最後ã®æˆåŠŸã—ãŸæ›´æ–°"
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr "å‰å›žã®ç¢ºèªæ—¥æ™‚"
@@ -19801,10 +19948,13 @@ msgstr "インデックスã§ãã‚‹åå‰ç©ºé–“ã¨ãƒ—ロジェクトを制é™ã™
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20312,6 +20462,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20360,6 +20513,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr "アーティファクトサイズã®ä¸Šé™ (MB)"
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr "添付ファイルサイズã®ä¸Šé™ (MB)"
@@ -20378,6 +20534,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr "最大é…延時間(分)"
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20390,7 +20549,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20405,9 +20564,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr "ジョブタイムアウトã®æœ€å¤§å€¤"
@@ -20441,6 +20606,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr "最大プッシュサイズ (MB)"
@@ -20465,6 +20636,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr "åŒæœŸãŒã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒ«ã•ã‚Œã¦ã„ã‚‹ã¨ãã«ãƒŸãƒ©ãƒ¼ãƒªãƒ³ã‚°ã®æ›´æ–°é–“ã®æœ€å¤§æ™‚間。"
@@ -20504,6 +20678,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20672,6 +20849,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20789,9 +20969,6 @@ msgstr "%{selectStart} ã‹ã‚‰ %{selectEnd} ã¾ã§ %{end} ã®è¡Œã¸ã®ã‚³ãƒ¡ãƒ³ãƒ
msgid "MergeRequestDiffs|Select comment starting line"
msgstr "コメントã®é–‹å§‹è¡Œã‚’é¸æŠž"
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr "別ã®ã‚¹ã‚«ãƒƒã‚·ãƒ¥ãŒé€²è¡Œä¸­ã‹ã©ã†ã‹ã‚’確èªä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr "下書ãコメントã®ä¿å­˜ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
@@ -20804,9 +20981,6 @@ msgstr "æ–°ã—ã„イシューã§ã“ã®ã‚¹ãƒ¬ãƒƒãƒ‰ã‚’解決ã™ã‚‹"
msgid "MergeRequests|Saving the comment failed"
msgstr "コメントã®ä¿å­˜ã«å¤±æ•—ã—ã¾ã—ãŸ"
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr "スカッシュタスクãŒå–り消ã•ã‚Œã¾ã—ãŸã€‚別ã®ã‚¹ã‚«ãƒƒã‚·ãƒ¥ãŒæ—¢ã«é€²è¡Œä¸­ã§ã™ã€‚"
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr "ã“ã®ãƒ—ロジェクトã§ã¯ã€ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’å—ã‘付ã‘ãŸã¨ãã«ã‚³ãƒŸãƒƒãƒˆã‚’スカッシュã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。"
@@ -21286,9 +21460,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr "ç¾åœ¨ã®ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã§ã¯ マイルストーンリストを利用ã§ãã¾ã›ã‚“"
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr "マイルストーンリストã«ã¯ã€é¸æŠžã—ãŸãƒžã‚¤ãƒ«ã‚¹ãƒˆãƒ¼ãƒ³ã®ã™ã¹ã¦ã®ã‚¤ã‚·ãƒ¥ãƒ¼ã‚’表示ã—ã¾ã™ã€‚"
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr "マイルストーンã®æ¤œç´¢ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
@@ -21563,7 +21734,7 @@ msgid "More information and share feedback"
msgstr "より詳細ãªæƒ…å ±ã¨ãƒ•ã‚£ãƒ¼ãƒ‰ãƒãƒƒã‚¯ã®å…±æœ‰"
msgid "More information is available|here"
-msgstr "ã“ã“ã‚’å‚ç…§"
+msgstr ""
msgid "More information."
msgstr ""
@@ -21667,7 +21838,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -21857,12 +22028,6 @@ msgstr "説明"
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -21905,9 +22070,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -21917,21 +22079,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr "ãƒãƒªã‚·ãƒ¼ã®èª¬æ˜Ž"
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -21947,9 +22100,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22095,9 +22245,6 @@ msgstr "æ–°è¦ãƒ–ランãƒ"
msgid "New branch unavailable"
msgstr "æ–°ã—ã„ブランãƒã¯åˆ©ç”¨ã§ãã¾ã›ã‚“"
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr "æ–°ã—ã„変更ãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸã€‚%{linkStart}ページをリロードã—ã¦ãƒ¬ãƒ“ューã—ã¦ãã ã•ã„%{linkEnd}"
-
msgid "New confidential epic title "
msgstr "æ–°ã—ã„éžå…¬é–‹ã®ã‚¨ãƒ”ックã®ã‚¿ã‚¤ãƒˆãƒ« "
@@ -22216,7 +22363,7 @@ msgid "New! Suggest changes directly"
msgstr "æ–°æ©Ÿèƒ½ï¼ å¤‰æ›´ã‚’ç›´æŽ¥æ案"
msgid "New..."
-msgstr "æ–°è¦...\t"
+msgstr ""
msgid "Newest first"
msgstr "æ–°ã—ã„é †"
@@ -22281,6 +22428,9 @@ msgstr "application_settings ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22798,6 +22948,9 @@ msgstr "11月"
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -22927,7 +23080,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23222,7 +23375,7 @@ msgstr "オープン"
msgid "Open Selection"
msgstr "é¸æŠžæ¸ˆã¿ã®ã‚‚ã®ã‚’é–‹ã"
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23414,6 +23567,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr "パッケージã®ãƒ¬ã‚·ãƒ”ã¯æ—¢ã«å­˜åœ¨ã—ã¦ã„ã¾ã™"
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr "パッケージタイプ㌠Conan ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“"
@@ -24551,6 +24707,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -24992,13 +25193,10 @@ msgstr "%{key} + C を押ã—ã¦ã‚³ãƒ”ーã™ã‚‹"
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25010,9 +25208,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr "ユーザーãŒãƒ—ロファイルåを変更ã§ããªã„よã†ã«è¨­å®šã™ã‚‹"
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr "ユーザーãŒãƒ¡ãƒ³ãƒ†ãƒŠãƒ³ã‚¹ã®é–“ã« GitLab ã§æ›¸ãè¾¼ã¿æ“作をã§ããªã„よã†ã«ã—ã¾ã™ã€‚"
@@ -25277,6 +25472,9 @@ msgstr "プロファイルã«æ“作ã«é–¢é€£ã—ãŸå€‹äººæƒ…報を表示ã—ãªã„
msgid "Profiles|Edit Profile"
msgstr "プロフィールを編集"
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25469,9 +25667,6 @@ msgstr "ユーザーåã¯æ­£å¸¸ã«å¤‰æ›´ã•ã‚Œã¾ã—ãŸ"
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr "åå‰ã«çµµæ–‡å­—を使ã†ã®ã¯æ¥½ã—ãã†ã§ã™ãŒã€ä»£ã‚ã‚Šã«ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’設定ã—ã¦ã¿ã¦ãã ã•ã„"
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr "ã‚ãªãŸã¯ã©ã‚“ãªã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã§ã™ã‹ï¼Ÿ"
@@ -26570,9 +26765,6 @@ msgstr "昇格ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“。"
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26624,6 +26816,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr "詳ã—ã見る"
@@ -26663,9 +26858,6 @@ msgstr "ã“ã®æ©Ÿèƒ½ã¯ãƒ­ãƒƒã‚¯ã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "Promotions|Track activity with Contribution Analytics."
msgstr "貢献度分æžã§ã‚¢ã‚¯ãƒ†ã‚£ãƒ“ティーを追跡ã™ã‚‹ã€‚"
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27167,6 +27359,12 @@ msgstr "関連ã™ã‚‹ã‚¤ã‚·ãƒ¥ãƒ¼ã«ã¤ã„ã¦ã‚‚ã£ã¨èª­ã‚€"
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27236,6 +27434,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr "プロジェクトã®å…¬é–‹ç¯„囲を狭ã‚ã‚‹"
@@ -27348,6 +27549,9 @@ msgstr ""
msgid "Related merge requests"
msgstr "関連ã™ã‚‹ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆ"
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr "以下ã«é–¢ä¿‚ã—ã¦ã„ã‚‹"
@@ -27857,6 +28061,9 @@ msgstr "テストè¦ç´„ã®çµæžœã®ãƒ­ãƒ¼ãƒ‰ã«å¤±æ•—"
msgid "Reports|Test summary results are being parsed"
msgstr "テストè¦ç´„ã®çµæžœã¯ãƒ‘ースã•ã‚Œã¦ã„ã¾ã™"
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr "脆弱性"
@@ -28208,19 +28415,19 @@ msgid "Response didn't include `service_desk_address`"
msgstr "応答㫠`service_desk_address`ã¯å«ã¾ã‚Œã¦ã„ã¾ã›ã‚“ã§ã—ãŸ"
msgid "Response metrics (AWS ELB)"
-msgstr "レスãƒãƒ³ã‚¹ メトリクス (AWS ELB)"
+msgstr ""
msgid "Response metrics (Custom)"
msgstr "レスãƒãƒ³ã‚¹ メトリクス(カスタム)"
msgid "Response metrics (HA Proxy)"
-msgstr "レスãƒãƒ³ã‚¹ãƒ¡ãƒˆãƒªã‚¯ã‚¹ (HA Proxy)"
+msgstr ""
msgid "Response metrics (NGINX Ingress VTS)"
msgstr "レスãƒãƒ³ã‚¹ãƒ¡ãƒˆãƒªã‚¯ã‚¹ (NGINX Ingress VTS)"
msgid "Response metrics (NGINX Ingress)"
-msgstr "レスãƒãƒ³ã‚¹ãƒ¡ãƒˆãƒªãƒƒã‚¯ (NGINX Ingress)"
+msgstr ""
msgid "Response metrics (NGINX)"
msgstr "レスãƒãƒ³ã‚¹ãƒ¡ãƒˆãƒªã‚¯ã‚¹ (NGINX)"
@@ -28301,6 +28508,9 @@ msgstr "アプリを表示"
msgid "Review App|View latest app"
msgstr "最新ã®ã‚¢ãƒ—リを表示"
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28569,6 +28779,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28632,6 +28845,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29087,9 +29303,6 @@ msgstr[0] "Wikiã®çµæžœ"
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29141,7 +29354,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29177,7 +29390,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29291,55 +29504,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
+msgstr ""
+
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select security project"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityPolicies|Environment(s)"
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29378,9 +29660,6 @@ msgstr "'%{vulnerabilityName}' ã®ç·¨é›†ã•ã‚ŒãŸã‚³ãƒ¡ãƒ³ãƒˆ"
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29492,9 +29771,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29561,6 +29837,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30134,7 +30413,7 @@ msgstr "イテレーションを %{iteration_reference} ã«è¨­å®šã—ã¾ã—ãŸã€‚
msgid "Set the milestone to %{milestone_reference}."
msgstr "マイルストーンを %{milestone_reference} ã«è¨­å®šã€‚"
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30182,7 +30461,7 @@ msgstr "ウェイトを設定"
msgid "Set weight to %{weight}."
msgstr "ウェイトを %{weight} ã«è¨­å®š"
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30383,9 +30662,6 @@ msgstr ""
msgid "Show latest version"
msgstr "最新ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’表示"
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30607,6 +30883,9 @@ msgstr ""
msgid "Size"
msgstr "サイズ"
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr "リãƒã‚¸ãƒˆãƒªæ¯Žã®ã‚µã‚¤ã‚ºåˆ¶é™ (MB)"
@@ -30958,6 +31237,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr "作æˆæ—¥é †"
@@ -32427,6 +32715,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32478,12 +32769,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32496,7 +32793,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32718,7 +33015,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -32935,6 +33232,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -32971,9 +33271,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr "ã“ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã«å¯¾ã™ã‚‹ãƒžãƒ¼ã‚¸ã®ç«¶åˆã¯ GitLab ã§ã¯è§£æ±ºã§ãã¾ã›ã‚“。ローカルã§è§£æ±ºã—ã¦ãã ã•ã„。"
@@ -33127,6 +33424,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr "アップデート㯠%{number_of_minutes} 分後ã«ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¾ã™ã€‚大ããªãƒªãƒã‚¸ãƒˆãƒªã«ã¯ã€clone 㨠push を組ã¿åˆã‚ã›ã¦ä½¿ã£ã¦ãã ã•ã„。"
@@ -33265,9 +33565,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33313,6 +33619,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr "マイルストーンã®å–得中ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
@@ -33493,9 +33802,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr "ãƒãƒªãƒ¥ãƒ¼ã‚¹ãƒˆãƒªãƒ¼ãƒ åˆ†æžãƒ‡ãƒ¼ã‚¿(%{requestTypeName})ã‚’å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
-
msgid "There was an error while fetching value stream analytics data."
msgstr "ãƒãƒªãƒ¥ãƒ¼ã‚¹ãƒˆãƒªãƒ¼ãƒ åˆ†æžãƒ‡ãƒ¼ã‚¿ã‚’å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
@@ -33715,9 +34021,6 @@ msgstr ""
msgid "This field is required."
msgstr "ã“ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã¯å¿…é ˆã§ã™ã€‚"
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr "ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—"
@@ -33790,6 +34093,9 @@ msgstr "ã“ã‚Œã¯ã‚ãªãŸã®ç¾åœ¨ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã§ã™"
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -34833,14 +35139,20 @@ msgstr "プロジェクトã®æ–°ã—ã„åå‰ç©ºé–“ã‚’é¸æŠžã—ã¦ãã ã•ã„。
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr "コンテナレジストリ内㫠tag ãŒå­˜åœ¨ã™ã‚‹ãŸã‚ã€ãƒ—ロジェクトを転é€ã§ãã¾ã›ã‚“。"
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr "移動先ã®åå‰ç©ºé–“ã«ã€åŒã˜åå‰ã¾ãŸã¯åŒã˜ãƒ‘スをæŒã¤ãƒ—ロジェクトãŒæ—¢ã«å­˜åœ¨ã—ã¾ã™"
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
-msgstr "転é€ã«å¤±æ•—ã—ã¾ã—ãŸã€ç®¡ç†è€…ã«é€£çµ¡ã—ã¦ãã ã•ã„。"
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
+msgstr ""
msgid "Tree view"
msgstr "ツリービュー"
@@ -35401,6 +35713,9 @@ msgstr ""
msgid "Until"
msgstr "ã¾ã§"
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35620,9 +35935,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr "パッケージ"
@@ -35641,9 +35953,15 @@ msgstr "リãƒã‚¸ãƒˆãƒª"
msgid "UsageQuota|Repository"
msgstr "リãƒã‚¸ãƒˆãƒª"
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr "スニペット"
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr "ストレージ"
@@ -35692,6 +36010,9 @@ msgstr "割当使用率"
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr "%{strong_start}%{group_name}%{strong_end} グループã®ãƒ—ロジェクト全体ã§ã®ã‚°ãƒ«ãƒ¼ãƒ—リソースã®ä½¿ç”¨çŽ‡"
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr "ã‚ãªãŸã®ãƒ—ロジェクトã§ã®ãƒªã‚½ãƒ¼ã‚¹ã®ä½¿ç”¨çŠ¶æ³"
@@ -35848,6 +36169,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr "URI ã”ã¨ã«1行使用"
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36325,9 +36649,15 @@ msgstr "イシューã®ä½œæˆã‹ã‚‰ã‚¯ãƒ­ãƒ¼ã‚ºã¾ã§ã®æ™‚é–“ã®ä¸­å¤®å€¤ã€‚"
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36522,6 +36852,10 @@ msgstr ""
msgid "View project labels"
msgstr "プロジェクトラベルを表示"
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+
msgid "View replaced file @ "
msgstr "変更後ファイルを表示 @ "
@@ -36780,9 +37114,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr "スキャナープロãƒã‚¤ãƒ€ãƒ¼"
@@ -36795,6 +37126,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -36900,6 +37234,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr "脆弱性ã¯ç™ºè¦‹ã•ã‚Œã¾ã›ã‚“ã§ã—ãŸ"
@@ -37155,6 +37492,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr "What's new"
@@ -37213,6 +37553,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37771,6 +38114,9 @@ msgstr "%{linkStart} CI Lint %{linkEnd} ã§.gitlab-ci.ymlをテストã™ã‚‹ã“ã
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr "ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã«ç›´æŽ¥ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。ã—ã°ã‚‰ããŠå¾…ã¡ãã ã•ã„。"
@@ -37786,6 +38132,9 @@ msgstr "内部ユーザーを代用ã§ãã¾ã›ã‚“"
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr "ç¾æ™‚点ã§ã¯ã“ã®ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒ«ã•ã‚ŒãŸãƒ‘イプラインを実行ã§ãã¾ã›ã‚“。少々ãŠå¾…ã¡ãã ã•ã„。"
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr "読ã¿å–り専用ã®ã‚»ã‚«ãƒ³ãƒ€ãƒª GitLab Geo インスタンスã«æ›¸ã込むã“ã¨ã¯ã§ãã¾ã›ã‚“。代ã‚ã‚Šã« %{link_to_primary_node} を使用ã—ã¦ãã ã•ã„。"
@@ -37930,7 +38279,7 @@ msgstr "プロジェクト数ã®ä¸Šé™ã«é”ã—ã¦ã„ã¾ã™"
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38356,7 +38705,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38386,6 +38735,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr "Zoom ミーティングを追加ã—ã¾ã—ãŸ"
@@ -38489,6 +38862,10 @@ msgstr ""
msgid "blocks"
msgstr "ブロック"
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+
msgid "branch name"
msgstr "ブランãƒå"
@@ -38612,12 +38989,12 @@ msgstr ""
msgid "ciReport|All projects"
msgstr "ã™ã¹ã¦ã®ãƒ—ロジェクト"
-msgid "ciReport|All scanners"
-msgstr ""
-
msgid "ciReport|All severities"
msgstr "ã™ã¹ã¦ã®é‡è¦åº¦"
+msgid "ciReport|All tools"
+msgstr ""
+
msgid "ciReport|Automatically apply the patch in a new branch"
msgstr "自動的ã«æ–°ã—ã„ブランãƒã«ã“ã®ãƒ‘ッãƒã‚’é©ç”¨ã™ã‚‹"
@@ -38964,6 +39341,9 @@ msgstr "エントリをnilã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
msgid "entries cannot contain HTML tags"
msgstr "エントリã«HTMLã‚¿ã‚°ã‚’å«ã‚られã¾ã›ã‚“。"
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39144,9 +39524,6 @@ msgstr "ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“。別ã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã§ã‚‚ã†ä¸€
msgid "is not allowed. We do not currently support project-level iterations"
msgstr "ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“。ç¾åœ¨ã€ãƒ—ロジェクトレベルã®ã‚¤ãƒ†ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“。"
-msgid "is not an email you own"
-msgstr "ã‚ãªãŸãŒæ‰€æœ‰ã™ã‚‹ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39361,8 +39738,9 @@ msgstr "クローズ済ã¿"
msgid "mrWidget|Closed by"
msgstr "クローズ作業者"
-msgid "mrWidget|Closes"
-msgstr "クローズ"
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
msgid "mrWidget|Delete source branch"
msgstr "ソースブランãƒã‚’削除"
@@ -39397,8 +39775,9 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr "メンション"
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
msgid "mrWidget|Merge"
msgstr "マージ"
@@ -39445,6 +39824,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr "詳ã—ã„情報"
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr "Web IDE ã§é–‹ã"
@@ -39508,9 +39890,6 @@ msgstr "ã“ã®å¤‰æ›´ã¯æ¬¡ã®ãƒ–ランãƒã«ãƒžãƒ¼ã‚¸ã•ã‚Œã¾ã™"
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr "ソースブランãƒã® HEAD ãŒæœ€è¿‘変更ã•ã‚Œã¾ã—ãŸã€‚ページをå†èª­ã¿è¾¼ã¿ã—ã¦ãƒžãƒ¼ã‚¸å‰ã«å¤‰æ›´ã‚’確èªã—ã¦ãã ã•ã„"
-
msgid "mrWidget|The source branch has been deleted"
msgstr "ã“ã®ã‚½ãƒ¼ã‚¹ãƒ–ランãƒã¯å‰Šé™¤ã•ã‚Œã¾ã—ãŸ"
@@ -39550,9 +39929,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr "ã“ã®ãƒ—ロジェクトを直接編集ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。変更ã™ã‚‹ã«ã¯ãƒ•ã‚©ãƒ¼ã‚¯ã—ã¦ãã ã•ã„。"
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39580,12 +39956,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr "開始日より後ã«ã—ã¦ãã ã•ã„。"
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/ka_GE/gitlab.po b/locale/ka_GE/gitlab.po
index 9ea02d12649..fab50f97d7c 100644
--- a/locale/ka_GE/gitlab.po
+++ b/locale/ka_GE/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ka\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:24\n"
+"PO-Revision-Date: 2021-09-01 22:32\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/kab/gitlab.po b/locale/kab/gitlab.po
index f17201fb5c2..d7e0bbce6ee 100644
--- a/locale/kab/gitlab.po
+++ b/locale/kab/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: kab\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:35\n"
+"PO-Revision-Date: 2021-09-01 22:34\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/ko/gitlab.po b/locale/ko/gitlab.po
index e1b9c3c03d4..b53f665fac0 100644
--- a/locale/ko/gitlab.po
+++ b/locale/ko/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ko\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:30\n"
+"PO-Revision-Date: 2021-09-01 22:33\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -313,6 +313,10 @@ msgid "%d tag per image name"
msgid_plural "%d tags per image name"
msgstr[0] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -445,6 +449,9 @@ msgstr[0] "%{count} ëª…ì˜ ì°¸ì—¬ìž"
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr "%{count} ê±´ê³¼ ê´€ë ¨ëœ %{pluralized_subject}: %{links}"
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -583,9 +590,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -595,6 +599,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -756,6 +763,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1152,7 +1162,7 @@ msgid_plural "%d issues selected"
msgstr[0] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgid "1 merged merge request"
@@ -1214,7 +1224,7 @@ msgid "2FA"
msgstr "2단계 ì¸ì¦(2FA)"
msgid "2FADevice|Registered On"
-msgstr "ë“±ë¡ ì‹œê¸°: "
+msgstr ""
msgid "3 days"
msgstr "3 ì¼"
@@ -1417,10 +1427,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1447,10 +1457,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -1628,7 +1638,7 @@ msgid "AccessTokens|Are you sure? Any issue email addresses currently in use wil
msgstr "확실한가요? 현재 ì‚¬ìš©ì¤‘ì¸ ì´ìŠˆ ì´ë©”ì¼ ì£¼ì†Œê°€ ìž‘ë™í•˜ì§€ 않게 ë©ë‹ˆë‹¤."
msgid "AccessTokens|Created"
-msgstr "액세스 í† í° | 만들어진"
+msgstr ""
msgid "AccessTokens|Feed token"
msgstr "피드 토í°"
@@ -2227,8 +2237,8 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
-msgstr "모든 ìž‘ì—…ì„ ì¤‘ì§€í•©ë‹ˆë‹¤. 현재 ì‹¤í–‰ì¤‘ì¸ ëª¨ë“  ìž‘ì—…ì´ ì¤‘ì§€ë©ë‹ˆë‹¤."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
+msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
@@ -2455,12 +2465,6 @@ msgstr "차단ë¨"
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2492,10 +2496,10 @@ msgid "AdminUsers|Deactivating a user has the following effects:"
msgstr ""
msgid "AdminUsers|Delete User %{username} and contributions?"
-msgstr " ì‚¬ìš©ìž %{username}와 기여를 삭제하시겠습니까?"
+msgstr ""
msgid "AdminUsers|Delete User %{username}?"
-msgstr " ì‚¬ìš©ìž %{username} (ì„)를 삭제하시겠습니까?"
+msgstr ""
msgid "AdminUsers|Delete user"
msgstr "ì‚¬ìš©ìž ì‚­ì œ"
@@ -2527,6 +2531,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr "ì´ê²ƒì€ 나!"
@@ -2590,6 +2597,12 @@ msgstr "유저ì—게 ì´ë©”ì¼ ë³´ë‚´ê¸°"
msgid "AdminUsers|Sort by"
msgstr "정렬 기준"
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2656,7 +2669,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3500,9 +3513,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr "ìž‘ì—… 로그를 가져 오는 ì¤‘ì— ì˜¤ë¥˜ê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤."
@@ -3518,9 +3528,6 @@ msgstr "ìž‘ì—…ì„ ê°€ì ¸ 오는 ì¤‘ì— ì˜¤ë¥˜ê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤."
msgid "An error occurred while fetching the latest pipeline."
msgstr "가장 ìµœê·¼ì˜ íŒŒì´í”„ ë¼ì¸ì„ 가져오는 ë„중 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤."
-msgid "An error occurred while fetching the pipeline."
-msgstr "파ì´í”„ë¼ì¸ì„ ë°˜ì˜í•˜ë˜ 중 오류가 ë°œìƒí•˜ì˜€ìŠµë‹ˆë‹¤."
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3575,6 +3582,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4040,7 +4053,7 @@ msgid "ApprovalRuleSummary|%{count} approval required from %{membersCount}"
msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCount}"
msgstr[0] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4049,9 +4062,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4079,6 +4098,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4091,6 +4113,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4100,19 +4128,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4223,6 +4257,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4380,9 +4417,6 @@ msgstr ""
msgid "Artifacts"
msgstr "결과물"
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4498,9 +4532,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr "ë‹´ë‹¹ìž ëª©ë¡ì€ 현재 ë¼ì´ì„¼ìŠ¤ë¡œëŠ” 사용할 수 없습니다."
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr "ë‹´ë‹¹ìž ëª©ë¡ì€ ì„ íƒëœ 사용ìžì—게 할당 ëœ ëª¨ë“  ì´ìŠˆê°€ 표시ë©ë‹ˆë‹¤."
-
msgid "Assignee(s)"
msgstr "담당ìž"
@@ -4616,6 +4647,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4695,7 +4732,7 @@ msgid "Authorized %{new_chat_name}"
msgstr ""
msgid "Authorized At"
-msgstr "권한 부여ë¨: "
+msgstr ""
msgid "Authorized applications (%{size})"
msgstr "ì¸ì¦ëœ 애플리케ì´ì…˜ (%{size})"
@@ -4722,7 +4759,7 @@ msgid "AutoDevOps|%{auto_devops_start}Automate building, testing, and deploying%
msgstr ""
msgid "AutoDevOps|Auto DevOps"
-msgstr "Auto DevOps|Auto DevOps"
+msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr "Auto DevOps 문서"
@@ -4793,6 +4830,9 @@ msgstr "Let's Encrypt를 사용하여 ì¸ì¦ì„œë¥¼ ìžë™ìœ¼ë¡œ 관리"
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -4985,9 +5025,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr "ì„ íƒí•œ 커밋으로 시작"
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5271,9 +5308,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5286,12 +5320,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr "보드"
@@ -5351,9 +5391,6 @@ msgid "Boards|Blocked by %{blockedByCount} %{issuableType}"
msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr "접기"
@@ -5654,30 +5691,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5732,6 +5763,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -5880,6 +5914,9 @@ msgstr "CONTRIBUTING"
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6363,12 +6400,16 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6378,15 +6419,16 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6402,7 +6444,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7011,6 +7053,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7026,9 +7071,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7111,7 +7153,7 @@ msgid "ClusterIntegration|API URL"
msgstr "API URL"
msgid "ClusterIntegration|API URL should be a valid http/https url."
-msgstr "í´ëŸ¬ìŠ¤í„° 통합 | API URLì€ ìœ íš¨í•œ http/https urlì´ì—¬ì•¼ 합니다."
+msgstr ""
msgid "ClusterIntegration|Add Kubernetes cluster"
msgstr "Kubernetes í´ëŸ¬ìŠ¤í„° 추가"
@@ -7156,7 +7198,7 @@ msgid "ClusterIntegration|An error occurred while trying to fetch project zones:
msgstr ""
msgid "ClusterIntegration|An error occurred while trying to fetch your projects: %{error}"
-msgstr "ClusterIntegration|프로ì íŠ¸ë¥¼ 가져오는 ë„중 오류가 ë°œìƒí•˜ì˜€ìŠµë‹ˆë‹¤. %{error}"
+msgstr ""
msgid "ClusterIntegration|An error occurred while trying to fetch zone machine types: %{error}"
msgstr ""
@@ -7621,7 +7663,7 @@ msgid "ClusterIntegration|Search networks"
msgstr ""
msgid "ClusterIntegration|Search projects"
-msgstr "ClusterIntegration|프로ì íŠ¸ 검색"
+msgstr ""
msgid "ClusterIntegration|Search security groups"
msgstr ""
@@ -7633,7 +7675,7 @@ msgid "ClusterIntegration|Search subnetworks"
msgstr ""
msgid "ClusterIntegration|Search zones"
-msgstr "ClusterIntegration|ì˜ì—­ 검색"
+msgstr ""
msgid "ClusterIntegration|Security group"
msgstr ""
@@ -7681,7 +7723,7 @@ msgid "ClusterIntegration|Select the region you want to create the new cluster i
msgstr ""
msgid "ClusterIntegration|Select zone"
-msgstr "ClusterIntegration|지역 ì„ íƒ"
+msgstr ""
msgid "ClusterIntegration|Select zone to choose machine type"
msgstr ""
@@ -7710,7 +7752,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -7822,7 +7864,7 @@ msgid "ClusterIntegration|meets the requirements"
msgstr "요구 ì‚¬í•­ì„ ì¶©ì¡±"
msgid "ClusterIntegration|sign up"
-msgstr "ClusterIntegration|가입"
+msgstr ""
msgid "ClusterIntergation|Select a VPC"
msgstr ""
@@ -7903,7 +7945,7 @@ msgid "CodeNavigation|No references found"
msgstr ""
msgid "CodeOwner|Pattern"
-msgstr "코드 ì†Œìœ ìž | 패턴"
+msgstr ""
msgid "CodeQuality|New code quality degradations on this line"
msgstr ""
@@ -8191,9 +8233,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8332,9 +8371,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr "웹 ë° API ìš”ì²­ì— ëŒ€í•œ ì œí•œì„ ì„¤ì •í•©ë‹ˆë‹¤."
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8347,6 +8383,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9064,7 +9103,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10006,7 +10045,7 @@ msgid "DashboardProjects|Trending"
msgstr "ì¸ê¸°"
msgid "Dashboard|%{firstProject} and %{secondProject}"
-msgstr "대시 보드 |%{firstProject} 과 %{secondProject}"
+msgstr ""
msgid "Dashboard|%{firstProject}, %{rest}, and %{secondProject}"
msgstr ""
@@ -10299,6 +10338,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10311,6 +10353,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10323,12 +10368,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10345,6 +10396,9 @@ msgid "DastSiteValidation|This will affect %d other profile targeting the same U
msgid_plural "DastSiteValidation|This will affect %d other profiles targeting the same URL."
msgstr[0] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10477,9 +10531,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10549,6 +10600,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10571,7 +10625,7 @@ msgid "DelayedJobs|delayed"
msgstr "지연ë¨"
msgid "Delete"
-msgstr "삭제 "
+msgstr ""
msgid "Delete %{issuableType}"
msgstr ""
@@ -10597,9 +10651,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr "댓글 삭제"
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10624,6 +10684,9 @@ msgstr "프로ì íŠ¸ ì‚­ì œ"
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10642,6 +10705,9 @@ msgstr "소스 브랜치 삭제"
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10655,7 +10721,7 @@ msgid "Delete variable"
msgstr ""
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
-msgstr "프로ì íŠ¸ ì‚­ì œ|프로ì íŠ¸ 저장소를 제거하지 못했습니다. ìž ì‹œ 후 다시 ì‹œë„하거나 관리ìžì—게 문ì˜í•˜ì„¸ìš”."
+msgstr ""
msgid "DeleteProject|Failed to remove project snippets. Please try again or contact administrator."
msgstr ""
@@ -10816,10 +10882,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -10864,6 +10930,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -10904,7 +10982,7 @@ msgid "DeployKeys|Error removing deploy key"
msgstr "ë°°í¬í‚¤ 제거 오류"
msgid "DeployKeys|Expand %{count} other projects"
-msgstr "DeployKeys|확장 %{count} 기타 프로ì íŠ¸"
+msgstr ""
msgid "DeployKeys|Grant write permissions to this key"
msgstr ""
@@ -11033,7 +11111,7 @@ msgid "Deployed-before"
msgstr ""
msgid "Deploying to"
-msgstr "다ìŒì— ë°°í¬ì¤‘: "
+msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
@@ -11291,6 +11369,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11351,7 +11435,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11481,7 +11565,7 @@ msgid "Diffs|Show all unchanged lines"
msgstr ""
msgid "Diffs|Something went wrong while fetching diff lines."
-msgstr "Diffs | ë³µìˆ˜ì˜ ì—´ì„ íŒ¨ì¹˜í•˜ëŠ” 중 문제가 ë°œìƒí–ˆìŠµë‹ˆë‹¤."
+msgstr ""
msgid "Direct member"
msgstr ""
@@ -11859,6 +11943,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr "ë¼ë²¨ 편집"
@@ -11934,6 +12021,9 @@ msgstr "공개 ë°°í¬ í‚¤ 편집"
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12141,9 +12231,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12192,6 +12279,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12231,6 +12321,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12585,6 +12678,9 @@ msgstr "ë°°í¬"
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12597,6 +12693,9 @@ msgstr "환경"
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr "í™˜ê²½ì€ ì½”ë“œê°€ ë°°í¬ë˜ëŠ” 장소(예: 스테ì´ì§• ë˜ëŠ” ìš´ì˜) 입니다."
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12672,6 +12771,9 @@ msgstr "중지 환경"
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12693,6 +12795,12 @@ msgstr "갱신ë¨"
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr "보호ë¨"
@@ -13029,6 +13137,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14397,6 +14508,9 @@ msgstr "í¬í¬"
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14467,7 +14581,7 @@ msgid "General pipelines"
msgstr "ì¼ë°˜ 파ì´í”„ë¼ì¸"
msgid "Generate a default set of labels"
-msgstr " 초기설정 ë ˆì´ë¸” 세트 ìƒì„±"
+msgstr ""
msgid "Generate key"
msgstr "키 ìƒì„±"
@@ -14484,6 +14598,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14616,10 +14733,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14664,7 +14781,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14685,9 +14802,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14742,19 +14856,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14799,7 +14910,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14811,6 +14922,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr "ìƒíƒœ"
@@ -14818,7 +14932,7 @@ msgid "Geo|Storage config"
msgstr ""
msgid "Geo|Synced"
-msgstr "Geo|ë™ê¸°í™” ë¨"
+msgstr ""
msgid "Geo|Synced at"
msgstr ""
@@ -14827,7 +14941,7 @@ msgid "Geo|Synchronization"
msgstr ""
msgid "Geo|Synchronization failed - %{error}"
-msgstr "Geo|ë™ê¸°í™” 실패 - %{error}"
+msgstr ""
msgid "Geo|Synchronization settings"
msgstr ""
@@ -14835,10 +14949,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -14910,7 +15024,7 @@ msgstr "스케줄러 대기 중"
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -14955,6 +15069,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15009,9 +15126,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr "GitLab 가져오기"
@@ -15261,6 +15375,9 @@ msgstr "%{time_ago} ì „ 엑세스 권한 부여ë¨"
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15342,7 +15459,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15693,6 +15810,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15705,6 +15828,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15738,7 +15864,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16234,7 +16360,7 @@ msgid "HealthCheck|Healthy"
msgstr "ê±´ê°•ë„"
msgid "HealthCheck|No Health Problems Detected"
-msgstr " 헬스 문제가 발견ë˜ì§€ 않았습니다."
+msgstr ""
msgid "HealthCheck|Unhealthy"
msgstr "비정ìƒ"
@@ -16266,10 +16392,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16400,6 +16526,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16419,7 +16548,7 @@ msgid "I accept the %{terms_link}"
msgstr "%{terms_link}ì— ë™ì˜í•©ë‹ˆë‹¤."
msgid "I accept the|Terms of Service and Privacy Policy"
-msgstr "서비스 약관 ë° ê°œì¸ì •ë³´ 보호 ì •ì±…"
+msgstr ""
msgid "I forgot my password"
msgstr "비밀번호를 잊었습니다."
@@ -16538,7 +16667,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16823,6 +16952,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17582,6 +17714,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17591,6 +17729,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17679,6 +17823,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17799,6 +17946,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -17988,9 +18138,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18528,6 +18675,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -18820,7 +18970,7 @@ msgid "JiraService|Open Jira"
msgstr ""
msgid "JiraService|Password or API token"
-msgstr "JiraService | 비밀번호 ë˜ëŠ” API 토í°"
+msgstr ""
msgid "JiraService|Project key changed, refresh list"
msgstr ""
@@ -19221,9 +19371,6 @@ msgstr "ë¼ë²¨"
msgid "Label actions dropdown"
msgstr "ë¼ë²¨ ìž‘ì—… 드롭 다운"
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19345,9 +19492,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19366,6 +19510,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19801,10 +19948,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
+msgstr ""
+
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20312,6 +20462,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20360,6 +20513,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20378,6 +20534,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20390,7 +20549,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20405,9 +20564,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr "최대 작업 시간 초과"
@@ -20441,6 +20606,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20465,6 +20636,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20504,6 +20678,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20672,6 +20849,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20789,9 +20969,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20804,9 +20981,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr "코멘트 저장 실패"
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21286,9 +21460,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr "현재 ë¼ì´ì„¼ìŠ¤ì—서는 마ì¼ìŠ¤í†¤ 목ë¡ì„ 사용할 수 없습니다."
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr "마ì¼ìŠ¤í†¤ 목ë¡ì—는 ì„ íƒí•œ 마ì¼ìŠ¤í†¤ì˜ 모든 문제가 표시ë©ë‹ˆë‹¤."
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21563,7 +21734,7 @@ msgid "More information and share feedback"
msgstr ""
msgid "More information is available|here"
-msgstr "여기"
+msgstr ""
msgid "More information."
msgstr ""
@@ -21667,7 +21838,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -21857,12 +22028,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -21905,9 +22070,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -21917,21 +22079,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -21947,9 +22100,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22095,9 +22245,6 @@ msgstr "새 브랜치"
msgid "New branch unavailable"
msgstr "새로운 브랜치 사용 불가능"
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22204,7 +22351,7 @@ msgid "New subgroup"
msgstr "새 서브그룹"
msgid "New tag"
-msgstr "새 태그 "
+msgstr ""
msgid "New test case"
msgstr ""
@@ -22281,6 +22428,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22798,6 +22948,9 @@ msgstr "11ì›”"
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -22927,7 +23080,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23222,7 +23375,7 @@ msgstr "열기"
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23316,7 +23469,7 @@ msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and
msgstr ""
msgid "Options"
-msgstr "옵션 "
+msgstr ""
msgid "Or you can choose one of the suggested colors below"
msgstr ""
@@ -23414,6 +23567,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24551,6 +24707,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -24992,13 +25193,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25010,9 +25208,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25277,6 +25472,9 @@ msgstr "í”„ë¡œí•„ì— í™œë™ ê´€ë ¨ ê°œì¸ ì •ë³´ 표시 안함"
msgid "Profiles|Edit Profile"
msgstr "프로필 편집"
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25458,7 +25656,7 @@ msgid "Profiles|Use a private email - %{email}"
msgstr "ê°œì¸ ì´ë©”ì¼ ì‚¬ìš© - %{email}"
msgid "Profiles|User ID"
-msgstr "프로필 | ì‚¬ìš©ìž ID"
+msgstr ""
msgid "Profiles|Username change failed - %{message}"
msgstr "ì‚¬ìš©ìž ì´ë¦„ 바꾸기 실패 - %{message}"
@@ -25467,9 +25665,6 @@ msgid "Profiles|Username successfully changed"
msgstr "ì‚¬ìš©ìž ì´ë¦„ì„ ì„±ê³µì ìœ¼ë¡œ 바꿨습니다"
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
-msgstr "프로필 | ì´ë¦„ì— ì´ëª¨ì§€ë¥¼ 사용하는 ê²ƒì€ ìž¬ë¯¸ 있지만 대신 ìƒíƒœ 메시지를 설정해보십시오."
-
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
msgstr ""
msgid "Profiles|What's your status?"
@@ -26570,9 +26765,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26624,6 +26816,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26663,9 +26858,6 @@ msgstr "ì´ ê¸°ëŠ¥ì€ ìž ê²¨ìžˆìŠµë‹ˆë‹¤."
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27167,6 +27359,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27236,6 +27434,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27348,6 +27549,9 @@ msgstr ""
msgid "Related merge requests"
msgstr "ê´€ë ¨ëœ ë¨¸ì§€ 리퀘스트(MR)"
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -27857,6 +28061,9 @@ msgstr "테스트 요약 로드 실패"
msgid "Reports|Test summary results are being parsed"
msgstr "테스트 요약 ê²°ê³¼ 분ì„중"
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr "취약ì "
@@ -28301,6 +28508,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28569,6 +28779,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28632,6 +28845,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29087,9 +29303,6 @@ msgstr[0] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29141,7 +29354,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29177,7 +29390,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29291,55 +29504,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
+msgstr ""
+
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select security project"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29378,9 +29660,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29492,9 +29771,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29561,6 +29837,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30134,7 +30413,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30182,7 +30461,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30383,9 +30662,6 @@ msgstr ""
msgid "Show latest version"
msgstr "최신 버전 보기"
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30607,6 +30883,9 @@ msgstr ""
msgid "Size"
msgstr "í¬ê¸°"
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -30958,6 +31237,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr "ìƒì„±ì¼"
@@ -31010,7 +31298,7 @@ msgid "SortOptions|Merged recently"
msgstr ""
msgid "SortOptions|Milestone due date"
-msgstr "ì •ë ¬ 옵션|마ì¼ìŠ¤í†¤ 마ê°ì¼"
+msgstr ""
msgid "SortOptions|Milestone due later"
msgstr "마ì¼ìŠ¤í†¤ 마ê°ì¼ì´ 먼"
@@ -32225,7 +32513,7 @@ msgid "Tagged this commit to %{tag_name}."
msgstr ""
msgid "Tags"
-msgstr "태그 "
+msgstr ""
msgid "Tags are deleted until the timeout is reached. Any remaining tags are included the next time the policy runs. To remove the time limit, set it to 0."
msgstr ""
@@ -32427,6 +32715,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32478,12 +32769,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32496,7 +32793,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32718,7 +33015,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -32935,6 +33232,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -32971,9 +33271,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33127,6 +33424,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33265,9 +33565,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33313,6 +33619,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33493,9 +33802,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33715,9 +34021,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr "ì´ ê·¸ë£¹"
@@ -33790,6 +34093,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -34833,13 +35139,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35401,6 +35713,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35620,9 +35935,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr "패키지"
@@ -35641,9 +35953,15 @@ msgstr "저장소"
msgid "UsageQuota|Repository"
msgstr "저장소"
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr "스니펫"
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr "저장 공간"
@@ -35692,6 +36010,9 @@ msgstr "사용량 제한"
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr "ë‚´ 프로ì íŠ¸ì˜ 리소스 사용량"
@@ -35848,6 +36169,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36325,9 +36649,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36522,6 +36852,10 @@ msgstr ""
msgid "View project labels"
msgstr "프로ì íŠ¸ ë¼ë²¨ 보기"
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+
msgid "View replaced file @ "
msgstr "êµì²´ëœ íŒŒì¼ ë³´ê¸° @ "
@@ -36780,9 +37114,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36795,6 +37126,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -36900,6 +37234,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37155,6 +37492,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37213,6 +37553,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37771,6 +38114,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37786,6 +38132,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -37930,7 +38279,7 @@ msgstr "프로ì íŠ¸ ìˆ«ìž í•œë„ì— ë„달했습니다."
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38356,7 +38705,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38386,6 +38735,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38489,6 +38862,10 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+
msgid "branch name"
msgstr "브랜치 ì´ë¦„"
@@ -38612,10 +38989,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -38964,6 +39341,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39144,9 +39524,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39326,7 +39703,7 @@ msgid "mrWidget|Approval is optional"
msgstr ""
msgid "mrWidget|Approval password is invalid."
-msgstr "mrWidget | ìŠ¹ì¸ ë¹„ë°€ë²ˆí˜¸ê°€ 잘못ë˜ì—ˆìŠµë‹ˆë‹¤."
+msgstr ""
msgid "mrWidget|Approve"
msgstr ""
@@ -39361,8 +39738,9 @@ msgstr "닫힘"
msgid "mrWidget|Closed by"
msgstr "ë‹«ìŒ:"
-msgid "mrWidget|Closes"
-msgstr "ë‹«ìŒ"
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39397,8 +39775,9 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr "멘션"
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
msgid "mrWidget|Merge"
msgstr "머지"
@@ -39445,6 +39824,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr "Web IDEì—ì„œ 열기"
@@ -39508,9 +39890,6 @@ msgstr "변경 ì‚¬í•­ì´ ë¨¸ì§€ë  ê²ƒ 입니다."
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39550,9 +39929,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39580,12 +39956,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/ku_TR/gitlab.po b/locale/ku_TR/gitlab.po
index 1b255671d50..95e5f8119d0 100644
--- a/locale/ku_TR/gitlab.po
+++ b/locale/ku_TR/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ku\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:30\n"
+"PO-Revision-Date: 2021-09-01 22:33\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/ky_KG/gitlab.po b/locale/ky_KG/gitlab.po
index 70c9950de94..b22ff2357f0 100644
--- a/locale/ky_KG/gitlab.po
+++ b/locale/ky_KG/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ky\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:17\n"
+"PO-Revision-Date: 2021-09-01 22:31\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/lt_LT/gitlab.po b/locale/lt_LT/gitlab.po
index 8a4effffd1b..376e4752a00 100644
--- a/locale/lt_LT/gitlab.po
+++ b/locale/lt_LT/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: lt\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:31\n"
+"PO-Revision-Date: 2021-09-01 22:33\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -484,6 +484,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -661,6 +668,9 @@ msgstr[3] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -799,9 +809,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -811,6 +818,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -978,6 +988,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1452,7 +1465,7 @@ msgstr[2] ""
msgstr[3] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -1750,10 +1763,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1780,10 +1793,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2560,7 +2573,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2788,12 +2801,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2860,6 +2867,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2923,6 +2933,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2989,7 +3005,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3836,9 +3852,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3854,9 +3867,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3911,6 +3921,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4394,7 +4410,7 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4403,9 +4419,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4433,6 +4455,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4445,6 +4470,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4454,19 +4485,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4577,6 +4614,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4737,9 +4777,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4858,9 +4895,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4979,6 +5013,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -5156,6 +5196,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5348,9 +5391,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5637,9 +5677,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5652,12 +5689,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5723,9 +5766,6 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -6026,30 +6066,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6104,6 +6138,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6255,6 +6292,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6738,12 +6778,19 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6753,15 +6800,19 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6777,7 +6828,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7386,6 +7437,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7401,9 +7455,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -8085,7 +8136,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8569,9 +8620,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8710,9 +8758,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8725,6 +8770,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9451,7 +9499,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10692,6 +10740,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10704,6 +10755,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10716,12 +10770,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10741,6 +10801,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10873,9 +10936,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10945,6 +11005,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10993,9 +11056,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -11020,6 +11089,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -11038,6 +11110,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -11221,10 +11296,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11278,6 +11353,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11708,6 +11795,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11768,7 +11861,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -12279,6 +12372,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12354,6 +12450,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12561,9 +12660,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12612,6 +12708,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12651,6 +12750,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -13005,6 +13107,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -13017,6 +13122,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -13092,6 +13200,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -13113,6 +13224,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13449,6 +13566,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14826,6 +14946,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14913,6 +15036,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -15045,10 +15171,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -15093,7 +15219,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -15114,9 +15240,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -15171,19 +15294,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -15228,7 +15348,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -15240,6 +15360,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -15264,10 +15387,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15339,7 +15462,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15384,6 +15507,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15438,9 +15564,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15690,6 +15813,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15771,7 +15897,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -16122,6 +16248,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -16134,6 +16266,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -16167,7 +16302,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16695,10 +16830,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16835,6 +16970,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16973,7 +17111,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -17267,6 +17405,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -18026,6 +18167,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -18035,6 +18182,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -18126,6 +18279,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -18246,6 +18402,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18435,9 +18594,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18975,6 +19131,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19668,9 +19827,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19795,9 +19951,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19816,6 +19969,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -20269,10 +20425,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20783,6 +20942,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20831,6 +20993,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20849,6 +21014,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20861,7 +21029,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20876,9 +21044,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20912,6 +21086,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20936,6 +21116,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20975,6 +21158,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -21143,6 +21329,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -21260,9 +21449,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -21275,9 +21461,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21763,9 +21946,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -22144,7 +22324,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22337,12 +22517,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22385,9 +22559,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22397,21 +22568,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22427,9 +22589,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22578,9 +22737,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22764,6 +22920,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -23293,6 +23452,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23422,7 +23584,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23720,7 +23882,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23912,6 +24074,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -25049,6 +25214,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25490,13 +25700,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25508,9 +25715,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25775,6 +25979,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25967,9 +26174,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -27068,9 +27272,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -27122,6 +27323,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -27161,9 +27365,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27665,6 +27866,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27734,6 +27941,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27849,6 +28059,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28373,6 +28586,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28826,6 +29042,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -29097,6 +29316,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -29160,6 +29382,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29648,9 +29873,6 @@ msgstr[3] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29702,7 +29924,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29738,7 +29960,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29852,55 +30074,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29939,9 +30230,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -30053,9 +30341,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -30122,6 +30407,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30695,7 +30983,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30743,7 +31031,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30944,9 +31232,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -31174,6 +31459,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31525,6 +31813,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -33000,6 +33297,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -33051,12 +33351,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -33069,7 +33375,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -33300,7 +33606,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33520,6 +33826,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33556,9 +33865,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33712,6 +34018,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33850,9 +34159,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33898,6 +34213,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -34078,9 +34396,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -34300,9 +34615,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -34375,6 +34687,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35424,13 +35739,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35995,6 +36316,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -36214,9 +36538,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -36235,9 +36556,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -36286,6 +36613,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36442,6 +36772,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36919,9 +37252,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -37122,6 +37461,13 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -37380,9 +37726,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -37395,6 +37738,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37500,6 +37846,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37755,6 +38104,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37816,6 +38168,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -38374,6 +38729,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -38389,6 +38747,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38533,7 +38894,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38959,7 +39320,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38989,6 +39350,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -39095,6 +39480,13 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "branch name"
msgstr ""
@@ -39218,10 +39610,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39582,6 +39974,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39771,9 +40166,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39991,8 +40383,12 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -40027,8 +40423,12 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -40075,6 +40475,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -40138,9 +40541,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -40180,9 +40580,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -40210,12 +40607,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/mk_MK/gitlab.po b/locale/mk_MK/gitlab.po
index 57c4a6c39e4..62aeda6d842 100644
--- a/locale/mk_MK/gitlab.po
+++ b/locale/mk_MK/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: mk\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:31\n"
+"PO-Revision-Date: 2021-09-01 22:33\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/mn_MN/gitlab.po b/locale/mn_MN/gitlab.po
index a11f238ea9f..e3b1a73c4a3 100644
--- a/locale/mn_MN/gitlab.po
+++ b/locale/mn_MN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: mn\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:31\n"
+"PO-Revision-Date: 2021-09-01 22:33\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/nb_NO/gitlab.po b/locale/nb_NO/gitlab.po
index 84949441586..06e91dda3b3 100644
--- a/locale/nb_NO/gitlab.po
+++ b/locale/nb_NO/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: nb\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:21\n"
+"PO-Revision-Date: 2021-09-01 22:31\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -44,7 +44,7 @@ msgid " You need to do this before %{grace_period_deadline}."
msgstr " Du er nødt til at gjøre dette, før %{grace_period_deadline}."
msgid " and"
-msgstr "og"
+msgstr ""
msgid " and "
msgstr " og "
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] "%d utildelt sak"
@@ -517,6 +522,9 @@ msgstr[1] "%{count} deltakere"
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr "%{count} relatert(e) %{pluralized_subject}: %{links}"
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr "%{labelStart}Metode:%{labelEnd} %{method}"
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr "%{labelStart}Navnefelt:%{labelEnd} %{namespace}"
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr "%{labelStart}Skanner:%{labelEnd} %{scanner}"
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr "%{labelStart}Alvorlighet:%{labelEnd} %{severity}"
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr "%{seconds}s"
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,8 +2349,8 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
-msgstr "Du er i ferd med å stoppe alle jobber. Dette stopper alle nåværende jobber som kjører."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
+msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "Feil under innlasting av statistikken. Vennligst prøv igjen"
@@ -2566,12 +2577,6 @@ msgstr "Blokkert"
msgid "AdminUsers|Blocking user has the following effects:"
msgstr "Å blokkere brukeren har følgende effekter:"
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr "Benytter setet"
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr "Det er deg!"
@@ -2701,6 +2709,12 @@ msgstr "Send E-post til brukere"
msgid "AdminUsers|Sort by"
msgstr "Sorter etter"
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr "Brukeren vil bli logget av"
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr "Det oppstod en feil under innhenting av etiketter. Prøv søket på nytt
msgid "An error occurred while fetching terraform reports."
msgstr "Det oppstod en feil under innhenting av terraformingsrapporter."
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr "En feil oppstod under innhenting av jobbloggføringen."
@@ -3630,9 +3641,6 @@ msgstr "En feil oppstod under innhenting av jobbene."
msgid "An error occurred while fetching the latest pipeline."
msgstr "En feil oppstod under innhenting av den nyeste rørledningen."
-msgid "An error occurred while fetching the pipeline."
-msgstr "En feil oppstod under innhenting av rørledningen."
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr "En feil oppstod under innhenting av lanseringene. Vennligst prøv igjen."
@@ -3687,6 +3695,12 @@ msgstr "En feil oppstod under innlasting av saker"
msgid "An error occurred while loading merge requests."
msgstr "Det oppstod en feil under innlasting av fletteforespørsler."
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] "%{count} godkjenning kreves fra %{membersCount}"
msgstr[1] "%{count} godkjenninger kreves fra %{membersCount}"
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr "Regelnavn"
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr "MÃ¥lgren"
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr "Er du sikker på at du vil oppheve arkiveringen av dette prosjektet?"
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr "Er du sikker på at du vil avbryte redigeringen av denne kommentaren?"
@@ -4499,9 +4537,6 @@ msgstr "Artifakten ble vellykket slettet."
msgid "Artifacts"
msgstr "Artefakter"
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr "Den tilordnede har ingen tillatelser"
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr "Tilordnet(e)"
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr "Automatisk sertifikatshåndtering med Let's Encrypt"
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr "Begynn med den valgte commiten"
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr "Bord"
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr "Klapp sammen"
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr "CONTRIBUTING"
msgid "CPU"
msgstr "CPU"
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr "Sjekker brukernavnets tilgjengelighet …"
msgid "Checkout"
msgstr "Kasse"
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr "US$%{selectedPlanPrice} per bruker per år"
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr "%{cardType} som slutter på %{lastFourDigits}"
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr "%{name} sitt GitLab-abonnement"
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr "%{selectedPlanText}-plan"
msgid "Checkout|%{startDate} - %{endDate}"
msgstr "%{startDate} - %{endDate}"
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr "Faktureringsadresse"
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,8 +7880,8 @@ msgstr "Ã… spesifisere et domene vil la deg bruke auto-gjennomgangsapper og auto
msgid "ClusterIntegration|Subnets"
msgstr "Undernett"
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
-msgstr "Amazon-ressursnavnet (ARN) som er tilknyttet din rolle. Hvis du ikke har en klargjøringsrolle, må du først opprette en på %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} ved hjelp av ovennevnte konto og eksterne IDer. %{startMoreInfoLink}Mer informasjon%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
msgstr ""
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr "opprettet av:"
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr "Konfigurer grenser for nett- og API-forespørsler."
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -9857,7 +9899,7 @@ msgid "Custom range (UTC)"
msgstr "Tilpasset område (UTC)"
msgid "Customizable by an administrator."
-msgstr "Justerbar av en administrator"
+msgstr ""
msgid "Customizable by owners."
msgstr ""
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr "Definisjon"
@@ -10729,9 +10786,15 @@ msgstr "Slett artefakter"
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr "Slett kommentar"
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr "Slett domene"
@@ -10756,6 +10819,9 @@ msgstr "Slett prosjekt"
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr "Slett prosjektet. Er du HELT SIKKER?"
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr "Slett kildegrenen"
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr "Slett dette vedlegget"
@@ -10951,10 +11020,10 @@ msgstr "Avhengighetsskanning"
msgid "Dependency proxy"
msgstr "Avhengighetsmellomtjener"
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr "Rediger gruppekrok"
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr "Rediger stempel"
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr "Skru på integrering"
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr "Miljøer"
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr "Stopp miljø"
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr "Det oppstod en feil under innhenting av loggfilene. Vennligst prøv igjen."
@@ -12833,6 +12938,12 @@ msgstr "Oppdatert"
msgid "Environments|You don't have any environments right now"
msgstr "Du har ingen miljøer akkurat nå"
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr "beskyttet"
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr "Utgreininger"
msgid "Format: %{dateFormat}"
msgstr "Format: %{dateFormat}"
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr "Fant feil i din %{gitlab_ci_yml}:"
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr "Filtrer etter status"
msgid "Geo|Geo Status"
msgstr "Geo Status"
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr "Sist bekreftet"
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr "Nodenavnet kan ikke være tomt"
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr "Ikke synkronisert enda"
@@ -14885,19 +15002,16 @@ msgstr "Fjern oppføring"
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr "Re-verifiser alle"
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr "Status"
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr "Venter på planlegger"
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr "GitLab-importering"
@@ -15404,6 +15521,9 @@ msgstr "Gitt tilgang %{time_ago}"
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr "Globale hurtigtaster"
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr "Standardrolle for nye brukere"
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr "Hvis det er deaktivert, vil en avvikende lokal gren ikke automatisk bli
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr "Under arbeid"
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr "Sett inn et bilde"
msgid "Insert code"
msgstr "Sett inn kode"
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr "Sett inn bilde"
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr "Sett inn forslag"
@@ -17828,6 +17975,9 @@ msgstr "Alle detaljer"
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17946,7 +18096,10 @@ msgid "Integrations|Sign in to add namespaces"
msgstr ""
msgid "Integrations|Standard"
-msgstr "Standard "
+msgstr ""
+
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr "Inviter medlem"
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr "Etikett"
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr "Siste svar fra"
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr "Sist sett"
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr "Forrige vellykkede oppdatering"
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr "Senest verifisert"
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr "Maks artefaktstørrelse (MB)"
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr "Maksforsinkelse (i minutter)"
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr "Maksimal feltlengde"
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr "Maks filstørrelse er 2MB. Vennligst velg en mindre fil."
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr "Maks importstørrelse (MB)"
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr "Maks-siden har blitt nådd"
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr "Maksimal pushstørrelse (MB)"
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr "Oppklar denne tråden i en ny sak"
msgid "MergeRequests|Saving the comment failed"
msgstr "Lagring av kommentaren mislyktes"
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21722,7 +21896,7 @@ msgid "More information and share feedback"
msgstr ""
msgid "More information is available|here"
-msgstr "her"
+msgstr ""
msgid "More information."
msgstr "Mere informasjon."
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr "Beskrivelse"
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr "Ingen valgt"
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr "%{policyName}-retningslinjen ble vellykket endret"
msgid "NetworkPolicies|Policy definition"
msgstr "Retningslinjedefinisjon"
-msgid "NetworkPolicies|Policy description"
-msgstr "Retningslinjebeskrivelse"
-
msgid "NetworkPolicies|Policy editor"
msgstr "Retningslinjeredigerer"
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr "Retningslinjestatus"
-
-msgid "NetworkPolicies|Policy type"
-msgstr "Retningslinjetype"
-
msgid "NetworkPolicies|Rule"
msgstr "Regel"
@@ -22107,9 +22263,6 @@ msgstr "Regler"
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr "Ny gren"
msgid "New branch unavailable"
msgstr "Ny gren utilgjengelig"
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr "Tittel på nytt konfidensielt epos "
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr "November"
msgid "Novice"
msgstr "Begynner"
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr "Ã…pne"
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr "Pakketypen må være Conan"
@@ -24717,6 +24876,51 @@ msgstr "Kjører"
msgid "Pipeline|Skipped"
msgstr "Hoppet over"
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr "Trykk %{key}-C for å kopiere"
msgid "Prev"
msgstr "Forrige"
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr "Ikke vis aktivitetsrelatert personlig informasjon på dine profiler"
msgid "Profiles|Edit Profile"
msgstr "Rediger profil"
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr "Hva er statusen din?"
@@ -26736,9 +26934,6 @@ msgstr "Forfremming er ikke støttet."
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr "Lær mer"
@@ -26824,12 +27022,9 @@ msgid "Promotions|The Advanced Search in GitLab is a powerful search service tha
msgstr ""
msgid "Promotions|This feature is locked."
-msgstr "Denne funksjonen er låst"
-
-msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
+msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
msgid "Promotions|Try it for free"
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr "Relaterte saker"
msgid "Related merge requests"
msgstr "Relaterte fletteforespørsler"
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr "Relatert til"
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr "SÃ¥rbarhet"
@@ -28476,6 +28686,9 @@ msgstr "Vis app"
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28560,7 +28773,7 @@ msgid "Ruby"
msgstr ""
msgid "Rule name is already taken."
-msgstr "Dette regelnavnet er allerede brukt"
+msgstr ""
msgid "Rules that define what git pushes are accepted for a project in this group. All newly created projects in this group will use these settings."
msgstr ""
@@ -28692,7 +28905,7 @@ msgid "Runners|Members of the %{type} can register runners"
msgstr ""
msgid "Runners|Name"
-msgstr "Runners|Navn"
+msgstr "Navn"
msgid "Runners|New registration token generated!"
msgstr ""
@@ -28713,10 +28926,10 @@ msgid "Runners|Paused"
msgstr ""
msgid "Runners|Platform"
-msgstr "Runners|Plattform"
+msgstr "Plattform"
msgid "Runners|Property Name"
-msgstr "Runners|Egenskapsnavn"
+msgstr "Egenskapsnavn"
msgid "Runners|Protected"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] "wiki-resultater"
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrhestration|No rules defined - policy will not run."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr "Fjern prosjekt fra kontrollpanelet"
msgid "SecurityReports|Scan details"
msgstr "Skanningsdetaljer"
-msgid "SecurityReports|Scanner"
-msgstr "Skanner"
-
msgid "SecurityReports|Security Dashboard"
msgstr "Sikkerhetskontrollpanel"
@@ -29748,6 +30027,9 @@ msgstr "En feil oppstod under generering av rapporten."
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr "Sett milepælen til %{milestone_reference}."
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr "Bestem vektlegging"
msgid "Set weight to %{weight}."
msgstr "Sett vektlegging til %{weight}."
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr "Vis nyeste versjon"
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr "Vis liste"
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr "Størrelse"
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr "Størrelsesgrense per kodelager (MB)"
@@ -30869,7 +31151,7 @@ msgid "SnippetsEmptyState|There are no snippets to show."
msgstr ""
msgid "Snippets|Add another file %{num}/%{total}"
-msgstr "Snippets|Legg til en annen fil %{num}/%{total}"
+msgstr ""
msgid "Snippets|Delete file"
msgstr "Slett fil"
@@ -31147,6 +31429,15 @@ msgstr "Sorter retning: synkende"
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr "Opprettelsesdato"
@@ -31421,7 +31712,7 @@ msgid "Star toggle failed. Try again later."
msgstr ""
msgid "StarProject|Star"
-msgstr "StarProject|Stjernemerk"
+msgstr "Stjernemerk"
msgid "Starred Projects"
msgstr "Stjernemerkede prosjekter"
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr "En feil oppstod under innhenting av stempler."
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr "En feil oppstod under innhenting av milepæler."
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr "Dette feltet er påkrevd."
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr "Denne gruppen"
@@ -33985,6 +34291,9 @@ msgstr "Dette er din nåværende økt"
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr "Frem til"
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr "Pakker"
@@ -35839,9 +36154,15 @@ msgstr "Kodelagre"
msgid "UsageQuota|Repository"
msgstr "Kodelager"
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr "Utdrag"
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr "Lagring"
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr "Bruk en linje per URI"
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr "Vis prosjektstempler"
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr "Vis erstattet fil @ "
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr "Skanner"
-
msgid "Vulnerability|Scanner Provider"
msgstr "Skannerleverandør"
@@ -36995,6 +37330,9 @@ msgstr "Status"
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr "Vi fant ingen sårbarheter"
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr "Hvem skal bruke dette GitLab-abonnementet?"
msgid "Who will be using this GitLab trial?"
msgstr "Hvem skal bruke denne GitLab-prøveversjonen?"
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr "Du kan ikke få tilgang til denne råfilen. Vennligst vent et minutt."
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr "Du har nådd prosjektgrensen"
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr "Zoom-møte lagt til"
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr "blokker"
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr "grennavn"
@@ -38814,12 +39196,12 @@ msgstr ""
msgid "ciReport|All projects"
msgstr "Alle prosjekter"
-msgid "ciReport|All scanners"
-msgstr "Alle skannere"
-
msgid "ciReport|All severities"
msgstr "Alle alvorlighetsgrader"
+msgid "ciReport|All tools"
+msgstr ""
+
msgid "ciReport|Automatically apply the patch in a new branch"
msgstr ""
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr "oppføringer kan ikke inneholde HTML-etiketter"
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr "epos"
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr "Lukket"
msgid "mrWidget|Closed by"
msgstr "Lukket av"
-msgid "mrWidget|Closes"
-msgstr "Lukker"
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr "Nevnelser"
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr "Flett"
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr "Mer informasjon"
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr "Ã…pne i nett-IDE"
@@ -39718,9 +40107,6 @@ msgstr "Endringene vil bli flettet inn i"
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr "Kildegrenen har blitt slettet"
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr "Bruk %{linkStart}CI-rørledninger til å teste koden%{linkEnd} ved å legge til en GitLab CI-konfigurasjonsfil i prosjektet ditt. Det tar bare et minutt å gjøre koden din mer sikker og robust."
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr "Du har ikke tillatelse til å redigere dette prosjektet direkte. Vennligst utgrein for å utføre endringer."
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr "må være høyere enn startdatoen"
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/nl_NL/gitlab.po b/locale/nl_NL/gitlab.po
index 19b4c83c413..b6bf6282d8f 100644
--- a/locale/nl_NL/gitlab.po
+++ b/locale/nl_NL/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: nl\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:32\n"
+"PO-Revision-Date: 2021-09-01 22:33\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] "%{count} deelnemers"
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5581,10 +5619,10 @@ msgid "Branches|Cancel, keep branch"
msgstr ""
msgid "Branches|Cant find HEAD commit for this branch"
-msgstr "Branches|Kan geen HEAD-commit vinden voor deze branch"
+msgstr ""
msgid "Branches|Compare"
-msgstr "Branches|Vergelijk"
+msgstr ""
msgid "Branches|Delete all branches that are merged into '%{default_branch}'"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
+msgstr ""
+
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityPolicies|Environment(s)"
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/pa_IN/gitlab.po b/locale/pa_IN/gitlab.po
index 121bfd702c9..8c05ee8d163 100644
--- a/locale/pa_IN/gitlab.po
+++ b/locale/pa_IN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: pa-IN\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:32\n"
+"PO-Revision-Date: 2021-09-01 22:34\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/pl_PL/gitlab.po b/locale/pl_PL/gitlab.po
index d4d19c49d88..ac331c805ee 100644
--- a/locale/pl_PL/gitlab.po
+++ b/locale/pl_PL/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: pl\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:32\n"
+"PO-Revision-Date: 2021-09-01 22:34\n"
msgid " %{name}, confirm your email address now! "
msgstr " %{name}, potwierdź teraz swój adres e-mail! "
@@ -484,6 +484,13 @@ msgstr[1] "%d tagi na nazwÄ™ obrazu"
msgstr[2] "%d tagów na nazwę obrazu"
msgstr[3] "%d tagu na nazwÄ™ obrazu"
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] "%d nieprzypisane zgłoszenie"
@@ -661,6 +668,9 @@ msgstr[3] "%{count} uczestnika"
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr "%{count} powiÄ…zanych %{pluralized_subject}: %{links}"
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr "%{count} całkowitej wagi"
@@ -799,9 +809,6 @@ msgstr "%{labelStart}Metoda:%{labelEnd} %{method}"
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr "%{labelStart}Przestrzeń nazw:%{labelEnd} %{namespace}"
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr "%{labelStart}Typ skanu:%{labelEnd} %{reportType}"
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr "%{labelStart}Skaner:%{labelEnd} %{scanner}"
@@ -811,6 +818,9 @@ msgstr "%{labelStart}Wysłano żądanie:%{labelEnd} %{headers}"
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr "%{labelStart}Ranga:%{labelEnd} %{severity}"
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr "%{labelStart}Zniezmodyfikowana odpowiedź:%{labelEnd} %{headers}"
@@ -978,6 +988,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr "%{seconds}s"
@@ -1452,7 +1465,7 @@ msgstr[2] ""
msgstr[3] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -1750,11 +1763,11 @@ msgstr "Klucz API"
msgid "API?"
msgstr "API?"
-msgid "APIFuzzing|$VariableWithPassword"
-msgstr "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
+msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
-msgstr "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
+msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
msgstr ""
@@ -1772,7 +1785,7 @@ msgid "APIFuzzing|Code snippet could not be generated. Try again later."
msgstr ""
msgid "APIFuzzing|Configure HTTP basic authentication values. Other authentication methods are supported. %{linkStart}Learn more%{linkEnd}."
-msgstr "APIFuzzing|Konfiguruj podstawowe wartości uwierzytelniania HTTP. Obsługiwane są inne metody uwierzytelniania. %{linkStart}Dowiedz się więcej%{linkEnd}."
+msgstr ""
msgid "APIFuzzing|Customize common API fuzzing settings to suit your requirements. For details of more advanced configuration options, see the %{docsLinkStart}GitLab API Fuzzing documentation%{docsLinkEnd}."
msgstr ""
@@ -1780,11 +1793,11 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr "WÅ‚Ä…cz uwierzytelnianie"
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
-msgstr "Wprowadź nazwę zmiennej zawierającej hasło. Na przykład $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
+msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
-msgstr "Wprowadź nazwę zmiennej zawierającej nazwę użytkownika. Na przykład: $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
+msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
msgstr ""
@@ -1832,10 +1845,10 @@ msgid "APIFuzzing|Tip: Insert this part below all stages"
msgstr "APIFuzzing|Wskazówka: wstaw tę część pod wszystkie etapy"
msgid "APIFuzzing|To prevent a security leak, authentication info must be added as a %{ciVariablesLinkStart}CI variable%{ciVariablesLinkEnd}. A user with maintainer access rights can manage CI variables in the %{ciSettingsLinkStart}Settings%{ciSettingsLinkEnd} area. We detected that you are not a maintainer. Commit your changes and assign them to a maintainer to update the credentials before merging."
-msgstr "APIFuzzing|Aby zapobiec wyciekowi informacji, informacje uwierzytelniające muszą być dodane jako %{ciVariablesLinkStart}zmienna CI%{ciVariablesLinkEnd}. Użytkownik z prawami dostępu opiekuna może zarządzać zmiennymi CI w obszarze %{ciSettingsLinkStart}ustawień%{ciSettingsLinkEnd} . Wykryliśmy, że nie jesteś opiekunem. Zacommituj swoje zmiany i przypisz je opiekunowi, aby zaktualizować poświadczenia przed zmergowaniem."
+msgstr ""
msgid "APIFuzzing|To prevent a security leak, authentication info must be added as a %{ciVariablesLinkStart}CI variable%{ciVariablesLinkEnd}. As a user with maintainer access rights, you can manage CI variables in the %{ciSettingsLinkStart}Settings%{ciSettingsLinkEnd} area."
-msgstr "APIFuzzing|Aby zapobiec wyciekom danych, informacje uwierzytelniające muszą być dodane jako %{ciVariablesLinkStart}zmienna CI%{ciVariablesLinkEnd}. Jako użytkownik z prawami dostępu opiekuna możesz zarządzać zmiennymi CI w obszarze %{ciSettingsLinkStart}ustawień%{ciSettingsLinkEnd}."
+msgstr ""
msgid "APIFuzzing|Use this tool to generate API fuzzing configuration YAML to copy into your .gitlab-ci.yml file. This tool does not reflect or update your .gitlab-ci.yml file automatically."
msgstr ""
@@ -2560,7 +2573,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2693,7 +2706,7 @@ msgid "AdminStatistics|Snippets"
msgstr "Kawałki kodu"
msgid "AdminUsers|(Admin)"
-msgstr "AdminUsers|(Administrator)"
+msgstr ""
msgid "AdminUsers|(Banned)"
msgstr ""
@@ -2788,12 +2801,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2860,6 +2867,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2923,6 +2933,12 @@ msgstr "Wyślij e-mail do użytkowników"
msgid "AdminUsers|Sort by"
msgstr "Sortuj według"
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr "Użytkownik zostanie wylogowany"
@@ -2989,7 +3005,7 @@ msgstr "Co mogę zrobić?"
msgid "AdminUsers|What does this mean?"
msgstr "Co to oznacza?"
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3836,9 +3852,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3854,9 +3867,6 @@ msgstr "Wystąpił błąd podczas pobierania zadań."
msgid "An error occurred while fetching the latest pipeline."
msgstr "Wystąpił błąd podczas wczytywania najnowszego potoku."
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr "Wystąpił błąd podczas pobierania wydań. Spróbuj ponownie."
@@ -3911,6 +3921,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr "Wystąpił błąd podczas ładowania merge requestów."
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr "Wystąpił błąd podczas ładowania formularza tokenów dostępu, proszę, spróbuj ponownie."
@@ -4394,7 +4410,7 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4403,9 +4419,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4433,6 +4455,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4445,6 +4470,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4454,19 +4485,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4577,6 +4614,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4737,9 +4777,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4858,9 +4895,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4979,6 +5013,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -5156,6 +5196,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5348,9 +5391,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5637,9 +5677,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5652,12 +5689,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5723,9 +5766,6 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -6026,30 +6066,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6104,6 +6138,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6255,6 +6292,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6738,12 +6778,19 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6753,15 +6800,19 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6777,7 +6828,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7386,6 +7437,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7401,9 +7455,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -8085,7 +8136,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8569,9 +8620,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8710,9 +8758,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8725,6 +8770,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9451,7 +9499,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10692,6 +10740,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10704,6 +10755,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10716,12 +10770,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10741,6 +10801,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10873,9 +10936,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10945,6 +11005,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10993,9 +11056,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -11020,6 +11089,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -11038,6 +11110,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -11221,10 +11296,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11278,6 +11353,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11708,6 +11795,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11768,7 +11861,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -12279,6 +12372,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12354,6 +12450,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12561,9 +12660,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12612,6 +12708,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12651,6 +12750,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -13005,6 +13107,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -13017,6 +13122,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -13092,6 +13200,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -13113,6 +13224,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13449,6 +13566,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14826,6 +14946,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14913,6 +15036,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -15045,10 +15171,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -15093,7 +15219,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -15114,9 +15240,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -15171,19 +15294,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -15228,7 +15348,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -15240,6 +15360,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -15264,10 +15387,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15339,7 +15462,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15384,6 +15507,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15438,9 +15564,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15690,6 +15813,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15771,7 +15897,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -16122,6 +16248,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -16134,6 +16266,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -16167,7 +16302,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16695,10 +16830,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16835,6 +16970,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16973,7 +17111,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -17267,6 +17405,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -18026,6 +18167,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -18035,6 +18182,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -18126,6 +18279,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -18246,6 +18402,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18435,9 +18594,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18975,6 +19131,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19668,9 +19827,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19795,9 +19951,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19816,6 +19969,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -20269,10 +20425,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
+msgstr ""
+
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20783,6 +20942,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20831,6 +20993,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20849,6 +21014,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20861,7 +21029,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20876,9 +21044,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20912,6 +21086,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20936,6 +21116,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20975,6 +21158,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -21143,6 +21329,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -21260,9 +21449,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -21275,9 +21461,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21763,9 +21946,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -22144,7 +22324,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22337,12 +22517,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22385,9 +22559,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22397,21 +22568,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22427,9 +22589,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22578,9 +22737,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22764,6 +22920,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -23293,6 +23452,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23422,7 +23584,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23720,7 +23882,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23912,6 +24074,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -25049,6 +25214,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25490,13 +25700,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25508,9 +25715,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25775,6 +25979,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25967,9 +26174,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -27068,9 +27272,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -27122,6 +27323,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -27161,9 +27365,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27665,6 +27866,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27734,6 +27941,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27849,6 +28059,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28373,6 +28586,9 @@ msgstr "Reports|Podsumowanie testu nie załadowało wyników"
msgid "Reports|Test summary results are being parsed"
msgstr "Wyniki podsumowania testu sÄ… analizowane"
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr "Wrażliwość"
@@ -28826,6 +29042,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -29097,6 +29316,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -29160,6 +29382,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29648,9 +29873,6 @@ msgstr[3] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29702,7 +29924,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29738,7 +29960,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29852,55 +30074,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityPolicies|Environment(s)"
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29939,9 +30230,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -30053,9 +30341,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -30122,6 +30407,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30695,7 +30983,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30743,7 +31031,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30944,9 +31232,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -31174,6 +31459,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31525,6 +31813,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -33000,6 +33297,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -33051,12 +33351,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -33069,7 +33375,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -33300,7 +33606,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33520,6 +33826,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33556,9 +33865,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33712,6 +34018,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr "Akcja aktualizacji zakończy się po upływie %{number_of_minutes} minut. W przypadku dużych repozytoriów użyj kombinacji klonuj/pchnij."
@@ -33850,9 +34159,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33898,6 +34213,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -34078,9 +34396,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -34300,9 +34615,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -34375,6 +34687,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35424,13 +35739,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35995,6 +36316,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -36214,9 +36538,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -36235,9 +36556,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -36286,6 +36613,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36442,6 +36772,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36919,9 +37252,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -37122,6 +37461,13 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -37380,9 +37726,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -37395,6 +37738,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37500,6 +37846,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37755,6 +38104,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37816,6 +38168,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -38374,6 +38729,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -38389,6 +38747,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38533,7 +38894,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38959,7 +39320,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38989,6 +39350,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -39095,6 +39480,13 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "branch name"
msgstr ""
@@ -39218,10 +39610,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39582,6 +39974,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39771,9 +40166,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39991,8 +40383,12 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -40027,8 +40423,12 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -40075,6 +40475,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -40138,9 +40541,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -40180,9 +40580,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -40210,12 +40607,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/pt_BR/gitlab.po b/locale/pt_BR/gitlab.po
index 6810402f032..e67e193e5cd 100644
--- a/locale/pt_BR/gitlab.po
+++ b/locale/pt_BR/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: pt-BR\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:13\n"
+"PO-Revision-Date: 2021-09-01 23:42\n"
msgid " %{name}, confirm your email address now! "
msgstr " %{name}, confirme seu endereço de e-mail agora! "
@@ -90,7 +90,7 @@ msgid "\"el\" parameter is required for createInstance()"
msgstr "O parâmetro \"el\" é necessário para createInstance()"
msgid "#general, #development"
-msgstr ""
+msgstr "#geral, #desenvolvimento"
msgid "%d Approval"
msgid_plural "%d Approvals"
@@ -262,8 +262,8 @@ msgstr[1] "%d horas"
msgid "%d inaccessible merge request"
msgid_plural "%d inaccessible merge requests"
-msgstr[0] "%d merge request inacessível"
-msgstr[1] "%d merge requests inacessíveis"
+msgstr[0] "%d solicitação de mesclagem inacessível"
+msgstr[1] "%d solicitações de mesclagem inacessíveis"
msgid "%d issue"
msgid_plural "%d issues"
@@ -287,13 +287,13 @@ msgstr[1] "%d camadas"
msgid "%d merge request"
msgid_plural "%d merge requests"
-msgstr[0] "%d merge request"
-msgstr[1] "%d merge requests"
+msgstr[0] "%d solicitação de mesclagem"
+msgstr[1] "%d solicitações de mesclagem"
msgid "%d merge request that you don't have access to."
msgid_plural "%d merge requests that you don't have access to."
-msgstr[0] "%d merge request que você não possui acesso."
-msgstr[1] "%d merge requests que você não tem acesso."
+msgstr[0] "%d solicitação de mesclagem que você não possui acesso."
+msgstr[1] "%d solicitações de mesclagem que você não tem acesso."
msgid "%d metric"
msgid_plural "%d metrics"
@@ -332,8 +332,8 @@ msgstr[1] "%d projetos pessoais serão removidos e não poderão ser restaurados
msgid "%d previously merged commit"
msgid_plural "%d previously merged commits"
-msgstr[0] "%d commit de merge realizado anteriormente"
-msgstr[1] "%d commits de merge realizados anteriormente"
+msgstr[0] "%d commit mesclado anteriormente"
+msgstr[1] "%d commits mesclados anteriormente"
msgid "%d project"
msgid_plural "%d projects"
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] "%d tag por nome de imagem"
msgstr[1] "%d tags por nome de imagem"
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] "%d token expirou"
+msgstr[1] "%d tokens expiraram"
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] "%d issue não atribuída"
@@ -431,18 +436,18 @@ msgstr "%{board_target} não encontrado"
msgid "%{bold_start}%{count}%{bold_end} issue"
msgid_plural "%{bold_start}%{count}%{bold_end} issues"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{bold_start}%{count}%{bold_end} issue"
+msgstr[1] "%{bold_start}%{count}%{bold_end} issues"
msgid "%{bold_start}%{count}%{bold_end} member"
msgid_plural "%{bold_start}%{count}%{bold_end} members"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{bold_start}%{count}%{bold_end} membro"
+msgstr[1] "%{bold_start}%{count}%{bold_end} membros"
msgid "%{bold_start}%{count}%{bold_end} opened merge request"
msgid_plural "%{bold_start}%{count}%{bold_end} opened merge requests"
-msgstr[0] "%{bold_start}%{count}%{bold_end} merge request aberto"
-msgstr[1] "%{bold_start}%{count}%{bold_end} merge requests abertos"
+msgstr[0] "%{bold_start}%{count}%{bold_end} solicitação de mesclagem aberta"
+msgstr[1] "%{bold_start}%{count}%{bold_end} solicitações de mesclagem abertas"
msgid "%{code_open}Masked:%{code_close} Hidden in job logs. Must match masking requirements."
msgstr "%{code_open}Mascarado:%{code_close} Escondidos nos logs de tarefas. Deve corresponder a requisitos de mascaramento."
@@ -500,8 +505,8 @@ msgstr "mais %{count} responsáveis"
msgid "%{count} more release"
msgid_plural "%{count} more releases"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{count} mais lançamentos"
+msgstr[1] "%{count} mais lançamentos"
msgid "%{count} of %{required} approvals from %{name}"
msgstr "%{count} de %{required} aprovações de %{name}"
@@ -517,6 +522,9 @@ msgstr[1] "%{count} participantes"
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr "%{count} %{pluralized_subject} relacionados: %{links}"
+msgid "%{count} selected"
+msgstr "%{count} selecionado"
+
msgid "%{count} total weight"
msgstr "%{count} peso total"
@@ -533,7 +541,7 @@ msgid "%{deployLinkStart}Use a template to deploy to ECS%{deployLinkEnd}, or use
msgstr "%{deployLinkStart}Use um modelo para fazer deploy em ECS%{deployLinkEnd} ou use uma imagem docker para %{commandsLinkStart}executar comandos de AWS no CI/CD GitLab%{commandsLinkEnd}."
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
-msgstr ""
+msgstr "%{description}- Evento Sentry: %{errorUrl}- Visto pela primeira vez: %{firstSeen}- Visto pela última vez: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
msgstr "%{doc_link_start}A pesquisa avançada%{doc_link_end} está desativada porque %{ref_elem} não é o branch padrão; %{default_branch_link_start}pesquise em %{default_branch} em vez de%{default_branch_link_end}."
@@ -560,7 +568,7 @@ msgid "%{edit_in_new_fork_notice} Try to upload a file again."
msgstr "%{edit_in_new_fork_notice} Tente carregar um arquivo novamente."
msgid "%{emailPrefix}@company.com"
-msgstr ""
+msgstr "%{emailPrefix}@empresa.com"
msgid "%{extra} more downstream pipelines"
msgstr "%{extra} mais downstream pipelines"
@@ -605,7 +613,7 @@ msgid "%{host} sign-in from new location"
msgstr "%{host} entrou a partir de um novo local"
msgid "%{integrations_link_start}Integrations%{link_end} enable you to make third-party applications part of your GitLab workflow. If the available integrations don't meet your needs, consider using a %{webhooks_link_start}webhook%{link_end}."
-msgstr ""
+msgstr "%{integrations_link_start}Integrações%{link_end} permitem que aplicativos de terceiros façam parte do seu fluxo de trabalho do GitLab. Se as integrações disponíveis não atenderem às suas necessidades, considere usar um %{webhooks_link_start}webhook%{link_end}."
msgid "%{issuableType} will be removed! Are you sure?"
msgstr "%{issuableType} será removido! Você tem certeza?"
@@ -614,13 +622,13 @@ msgid "%{issueType} actions"
msgstr "%{issueType} ações"
msgid "%{issuesCount} issues with a limit of %{maxIssueCount}"
-msgstr ""
+msgstr "%{issuesCount} issues com um limite de %{maxIssueCount}"
msgid "%{issuesSize} with a limit of %{maxIssueCount}"
msgstr "%{issuesSize} com um limite de %{maxIssueCount}"
msgid "%{italic_start}What's new%{italic_end} is inactive and cannot be viewed."
-msgstr ""
+msgstr "%{italic_start}Novidades%{italic_end} está inativo e não pode ser visto."
msgid "%{itemsCount} issues with a limit of %{maxIssueCount}"
msgstr "%{itemsCount} issues com um limite de %{maxIssueCount}"
@@ -629,7 +637,7 @@ msgid "%{labelStart}Actual response:%{labelEnd} %{headers}"
msgstr "%{labelStart}Resposta atual:%{labelEnd} %{headers}"
msgid "%{labelStart}Assert:%{labelEnd} %{assertion}"
-msgstr ""
+msgstr "%{labelStart}Afirmar:%{labelEnd} %{assertion}"
msgid "%{labelStart}Class:%{labelEnd} %{class}"
msgstr "%{labelStart}Classe:%{labelEnd} %{class}"
@@ -653,28 +661,28 @@ msgid "%{labelStart}Method:%{labelEnd} %{method}"
msgstr "%{labelStart}Método:%{labelEnd} %{method}"
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
-msgstr "%{labelStart}Namespace:%{labelEnd} %{namespace}"
-
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
+msgstr "%{labelStart}Espaço de nome:%{labelEnd} %{namespace}"
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
-msgstr ""
+msgstr "%{labelStart}Verificar:%{labelEnd} %{scanner}"
msgid "%{labelStart}Sent request:%{labelEnd} %{headers}"
-msgstr ""
+msgstr "%{labelStart}Requisição enviada:%{labelEnd} %{headers}"
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr "%{labelStart}Severidade:%{labelEnd} %{severity}"
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr "%{labelStart}Ferramenta:%{labelEnd} %{reportType}"
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
-msgstr ""
+msgstr "%{labelStart}Resposta não modificada:%{labelEnd} %{headers}"
msgid "%{label_for_message} unavailable"
msgstr "%{label_for_message} indisponível"
msgid "%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} is a free, automated, and open certificate authority (CA) that issues digital certificates to enable HTTPS (SSL/TLS) for sites."
-msgstr ""
+msgstr "%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} é uma autoridade certificadora (CA) gratuita, automatizada e aberta, que emite certificados digitais para habilitar o HTTPS (SSL/TLS) para sites."
msgid "%{level_name} is not allowed in a %{group_level_name} group."
msgstr "%{level_name} não é permitido em um grupo %{group_level_name}."
@@ -683,7 +691,7 @@ msgid "%{level_name} is not allowed since the fork source project has lower visi
msgstr "%{level_name} não é permitido, pois o projeto de origem do fork possui menor visibilidade."
msgid "%{link_start}Learn more%{link_end} about roles."
-msgstr ""
+msgstr "%{link_start}Saiba mais%{link_end} sobre cargos."
msgid "%{link_start}Learn more%{link_end} about what information is shared with GitLab Inc."
msgstr "%{link_start}Saiba mais%{link_end} sobre qual informação é compartilhada com GitLab Inc."
@@ -692,13 +700,13 @@ msgid "%{link_start}Remove the %{draft_snippet} prefix%{link_end} from the title
msgstr ""
msgid "%{link_start}Start the title with %{draft_snippet}%{link_end} to prevent a merge request that is a work in progress from being merged before it's ready."
-msgstr ""
+msgstr "%{link_start}Inicie o título com %{draft_snippet}%{link_end} para evitar que uma solicitação de mesclagem de código de um trabalho em andamento seja executada antes de estar pronta."
msgid "%{listToShow}, and %{awardsListLength} more"
-msgstr ""
+msgstr "%{listToShow}, e %{awardsListLength} mais"
msgid "%{location} is missing required keys: %{keys}"
-msgstr ""
+msgstr "%{location} está faltando as chaves necessárias: %{keys}"
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr "%{lock_path} está bloqueado pelo usuário do GitLab %{lock_user_id}"
@@ -707,10 +715,10 @@ msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActions
msgstr "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} e %{quickActionsDocsLinkStart}ações rápidas%{quickActionsDocsLinkEnd} são suportadas"
msgid "%{mergeLength}/%{usersLength} can merge"
-msgstr "%{mergeLength}/%{usersLength} podem fazer o merge"
+msgstr "%{mergeLength}/%{usersLength} podem mesclar"
msgid "%{message} showing first %{warnings_displayed}"
-msgstr ""
+msgstr "%{message} mostrando o primeiro %{warnings_displayed}"
msgid "%{milestone} (expired)"
msgstr "%{milestone} (expirado)"
@@ -755,7 +763,7 @@ msgid "%{name}(%{url}) namespace has run out of Shared Runner Pipeline minutes s
msgstr ""
msgid "%{name}, confirm your email address now!"
-msgstr ""
+msgstr "%{name}, confirme o seu endereço de e-mail agora!"
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
@@ -778,22 +786,22 @@ msgid "%{openOrClose} %{noteable}"
msgstr "%{openOrClose} %{noteable}"
msgid "%{openedEpics} open, %{closedEpics} closed"
-msgstr ""
+msgstr "%{openedEpics} abertos, %{closedEpics} fechados"
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr "%{openedIssues} aberta, %{closedIssues} fechada"
msgid "%{percentage}%% weight completed"
-msgstr ""
+msgstr "%{percentage}%% peso concluído"
msgid "%{percent}%% complete"
msgstr "%{percent}%% completado"
msgid "%{percent}%{percentSymbol} complete"
-msgstr ""
+msgstr "%{percent}%{percentSymbol} completo"
msgid "%{placeholder} is not a valid color scheme"
-msgstr ""
+msgstr "%{placeholder} não é um esquema de cores válido"
msgid "%{placeholder} is not a valid theme"
msgstr "%{placeholder} não é um tema válido"
@@ -806,11 +814,11 @@ msgstr "%{ref} não pode ser adicionado: %{error}"
msgid "%{releases} release"
msgid_plural "%{releases} releases"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{releases} lançamento"
+msgstr[1] "%{releases} lançamentos"
msgid "%{remaining_approvals} left"
-msgstr ""
+msgstr "faltam: %{remaining_approvals}"
msgid "%{reportType} %{status}"
msgstr "%{reportType} %{status}"
@@ -822,7 +830,7 @@ msgid "%{reportType} detected %{totalStart}no%{totalEnd} vulnerabilities."
msgstr ""
msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}."
-msgstr ""
+msgstr "%{retryButtonStart}Tente novamente%{retryButtonEnd} ou %{newFileButtonStart}anexe um novo arquivo%{newFileButtonEnd}."
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation_link}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr "%{scope} resultados para o termo '%{term}'"
+
msgid "%{seconds}s"
msgstr "%{seconds}s"
@@ -950,10 +961,10 @@ msgid "%{timebox_name} should belong either to a project or a group."
msgstr ""
msgid "%{timebox_type} does not support burnup charts"
-msgstr ""
+msgstr "%{timebox_type} não suporta o gráfico de burnup"
msgid "%{timebox_type} must have a start and due date"
-msgstr ""
+msgstr "%{timebox_type} deve ter uma data de início e de vencimento"
msgid "%{title} %{operator} %{threshold}"
msgstr "%{title} %{operator} %{threshold}"
@@ -980,7 +991,7 @@ msgid "%{total} warnings found: showing first %{warningsDisplayed}"
msgstr "%{total} avisos encontrados: mostrando os primeiros %{warningsDisplayed}"
msgid "%{userName} (cannot merge)"
-msgstr "%{userName} (não pode fazer o merge)"
+msgstr "%{userName} (não pode mesclar)"
msgid "%{userName}'s avatar"
msgstr "Avatar de %{userName}"
@@ -1001,7 +1012,7 @@ msgid "%{username}'s avatar"
msgstr "Avatar de %{username}"
msgid "%{user} created a merge request: %{mr_link}"
-msgstr "%{user} criou um merge request: %{mr_link}"
+msgstr "%{user} criou uma solicitação de mesclagem: %{mr_link}"
msgid "%{user} created an epic: %{epic_link}"
msgstr "%{user} criou um épico: %{epic_link}"
@@ -1025,7 +1036,7 @@ msgid "%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notif
msgstr "%{webhooks_link_start}%{webhook_type}%{link_end} permitem que você envie notificações para aplicativos da web em resposta a eventos de um grupo ou projeto. Recomendamos usar uma %{integrations_link_start}integração%{link_end} em vez de um webhook."
msgid "%{wildcards_link_start}Wildcards%{wildcards_link_end} such as %{code_tag_start}v*%{code_tag_end} or %{code_tag_start}*-release%{code_tag_end} are supported."
-msgstr ""
+msgstr "%{wildcards_link_start}Caracteres curinga%{wildcards_link_end} como %{code_tag_start}v*%{code_tag_end} ou %{code_tag_start}*release%{code_tag_end} são suportados."
msgid "&lt; 1 hour"
msgstr "&lt; 1 hora"
@@ -1072,7 +1083,7 @@ msgstr[0] "(%d fechado)"
msgstr[1] "(%d fechados)"
msgid "(%{mrCount} merged)"
-msgstr "(%{mrCount} merges realizados)"
+msgstr "(%{mrCount} mesclado)"
msgid "(%{value}) has already been taken"
msgstr "(%{value}) já está em uso"
@@ -1081,10 +1092,10 @@ msgid "(+%{count}&nbsp;rules)"
msgstr "(+%{count}&nbsp;regras)"
msgid "(Group Managed Account)"
-msgstr ""
+msgstr "(Conta gerenciada por grupo)"
msgid "(No changes)"
-msgstr "(Nenhuma mudança)"
+msgstr "(Nenhuma alteração)"
msgid "(UTC %{offset}) %{timezone}"
msgstr "(UTC %{offset}) %{timezone}"
@@ -1099,7 +1110,7 @@ msgid "(expired)"
msgstr "(expirado)"
msgid "(leave blank if you don't want to change it)"
-msgstr ""
+msgstr "(Deixe em branco se não quiser alterá-lo)"
msgid "(max size 15 MB)"
msgstr "(tamanho máximo de 15MB)"
@@ -1111,7 +1122,7 @@ msgid "(revoked)"
msgstr "(revogado)"
msgid "(we need your current password to confirm your changes)"
-msgstr ""
+msgstr "(precisamos da sua senha atual para confirmar as alterações)"
msgid "* * * * *"
msgstr "* * * * *"
@@ -1198,8 +1209,8 @@ msgstr[1] "%d dias"
msgid "1 Issue"
msgid_plural "%d Issues"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 Issue"
+msgstr[1] "%d Issues"
msgid "1 closed issue"
msgid_plural "%{issues} closed issues"
@@ -1208,8 +1219,8 @@ msgstr[1] "%{issues} issues fechadas"
msgid "1 closed merge request"
msgid_plural "%{merge_requests} closed merge requests"
-msgstr[0] "1 merge request fechado"
-msgstr[1] "%{merge_requests} merge requests fechados"
+msgstr[0] "1 solicitação de mesclagem fechada"
+msgstr[1] "%{merge_requests} solicitações de mesclagem fechadas"
msgid "1 day"
msgid_plural "%d days"
@@ -1228,8 +1239,8 @@ msgstr[1] "%d dias selecionados"
msgid "1 deploy key"
msgid_plural "%d deploy keys"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 chave de implantação"
+msgstr[1] "%d chaves de implantação"
msgid "1 follower"
msgid_plural "%{count} followers"
@@ -1252,14 +1263,14 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
-msgstr[0] "1 merge request selecionado"
-msgstr[1] "%d merge request selecionado"
+msgid_plural "%d merge requests selected"
+msgstr[0] "1 solicitação de mesclagem selecionada"
+msgstr[1] "%d solicitação de mesclagem selecionada"
msgid "1 merged merge request"
msgid_plural "%{merge_requests} merged merge requests"
-msgstr[0] "1 merge request com merge"
-msgstr[1] "%{merge_requests} merge requests com merge"
+msgstr[0] "1 solicitação de mesclagem mesclada"
+msgstr[1] "%{merge_requests} solicitações de mesclagem mescladas"
msgid "1 minute"
msgid_plural "%d minutes"
@@ -1367,28 +1378,28 @@ msgid ":%{startLine} to %{endLine}"
msgstr ":%{startLine} a %{endLine}"
msgid "A %{incident_docs_start}modified issue%{incident_docs_end} to guide the resolution of incidents."
-msgstr ""
+msgstr "Uma %{incident_docs_start}issue modificada%{incident_docs_end} para orientar a resolução de incidentes."
msgid "A .NET Core console application template, customizable for any .NET Core project"
-msgstr "Um template de aplicação console .NET Core customizável para qualquer projeto .NET Code"
+msgstr "Um modelo de aplicação console .NET Core personalizável para qualquer projeto .NET Code"
msgid "A CI/CD pipeline must run and be successful before merge."
msgstr ""
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "Um site GitBook que usa Netlify para CI/CD em vez do Gitlab, mas ainda com todas as outras ótimas funcionalidades do GitLab"
msgid "A Gitpod configured Webapplication in Spring and Java"
-msgstr ""
+msgstr "Um aplicativo web configurado por Gitpod em Spring e Java"
msgid "A Hexo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "Um site Hexo que usa Netlify para CI/CD em vez do Gitlab, mas ainda com todas as outras ótimas funcionalidades do GitLab"
msgid "A Hugo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "Um site Hugo que usa Netlify para CI/CD em vez do Gitlab, mas ainda com todas as outras ótimas funcionalidades do GitLab"
msgid "A Jekyll site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "Um site do Jekyll que usa Netlify para CI/CD em vez do Gitlab, mas ainda com todas as outras ótimas funcionalidades do GitLab"
msgid "A Let's Encrypt SSL certificate can not be obtained until your domain is verified."
msgstr "Um certificado SSL Let's Encrypt não pode ser obtido até que seu domínio seja verificado."
@@ -1397,13 +1408,13 @@ msgid "A Metrics Dashboard menu item appears in the Monitoring section of the Ad
msgstr ""
msgid "A basic page and serverless function that uses AWS Lambda, AWS API Gateway, and GitLab Pages"
-msgstr ""
+msgstr "Uma página básica e função serverless que usa AWS Lambda, o AWS API Gateway e GitLab Pages"
msgid "A basic template for developing Linux programs using Kotlin Native"
-msgstr ""
+msgstr "Um modelo básico para o desenvolvimento de programas Linux usando o Kotlin Native"
msgid "A complete DevOps platform"
-msgstr ""
+msgstr "Uma plataforma completa de DevOps"
msgid "A default branch cannot be chosen for an empty project."
msgstr "Um branch padrão não pode ser escolhido para um projeto vazio."
@@ -1412,10 +1423,10 @@ msgid "A deleted user"
msgstr "Um usuário excluído"
msgid "A description is required"
-msgstr ""
+msgstr "é necessária uma descrição"
msgid "A different reason"
-msgstr ""
+msgstr "Um motivo diferente"
msgid "A file has been changed."
msgstr "Um arquivo foi alterado."
@@ -1424,22 +1435,22 @@ msgid "A file was not found."
msgstr "O arquivo não foi encontrado."
msgid "A file with '%{file_name}' already exists in %{branch} branch"
-msgstr ""
+msgstr "Um arquivo com '%{file_name}' já existe na ramificação %{branch}"
msgid "A group is a collection of several projects"
-msgstr ""
+msgstr "Um grupo é uma coleção de vários projetos"
msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
-msgstr ""
+msgstr "Um grupo representa sua organização no GitLab. Os grupos permitem que você gerencie usuários e colabore em vários projetos."
msgid "A job artifact is an archive of files and directories saved by a job when it finishes."
-msgstr ""
+msgstr "Um artefato de tarefa é um arquivo de arquivos e diretórios salvos por uma tarefa quando ela terminar."
msgid "A limit of %{ci_project_subscriptions_limit} subscriptions to or from a project applies."
-msgstr ""
+msgstr "Um limite de %{ci_project_subscriptions_limit} assinaturas de ou de um projeto se aplica."
msgid "A management, operational, or technical control (that is, safeguard or countermeasure) employed by an organization that provides equivalent or comparable protection for an information system."
-msgstr ""
+msgstr "Uma controle de gestão, operacional ou técnico (ou seja, salvaguarda ou contramedida) empregada por uma organização que fornece uma proteção equivalente ou comparável para um sistema de informação."
msgid "A member of the abuse team will review your report as soon as possible."
msgstr "Um membro da equipe de abusos irá rever a sua avaliação assim que possível."
@@ -1448,7 +1459,7 @@ msgid "A merge request hasn't yet been merged"
msgstr ""
msgid "A new Auto DevOps pipeline has been created, go to %{pipelines_link_start}Pipelines page%{pipelines_link_end} for details"
-msgstr ""
+msgstr "Um novo pipeline de Auto DevOps foi criado, vá para a página de Pipelines %{pipelines_link_start}%{pipelines_link_end} para obter detalhes"
msgid "A new Release %{tag} for %{name} was published. Visit the %{release_link_start}Releases page%{release_link_end} to read more about it."
msgstr ""
@@ -1481,13 +1492,13 @@ msgid "A project containing issues for each audit inquiry in the HIPAA Audit Pro
msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "O nome do repositório de um projeto define sua URL (aquele que você usa para acessar o projeto através de um navegador) e seu lugar no disco de arquivos onde o GitLab está instalado. %{link_start}Saber mais.%{link_end}"
msgid "A ready-to-go template for use with Android apps"
-msgstr ""
+msgstr "Um modelo pronto para uso com aplicativos do Android"
msgid "A ready-to-go template for use with iOS Swift apps"
-msgstr ""
+msgstr "Um modelo pronto para uso com aplicativos do iOS baseados em Swift"
msgid "A rebase is already in progress."
msgstr ""
@@ -1511,10 +1522,10 @@ msgid "API"
msgstr "API"
msgid "API Fuzzing"
-msgstr ""
+msgstr "Fuzzing API"
msgid "API Fuzzing Configuration"
-msgstr ""
+msgstr "Configuração de Fuzzing API"
msgid "API Help"
msgstr "Ajuda da API"
@@ -1528,23 +1539,23 @@ msgstr "Chave de API"
msgid "API?"
msgstr "API?"
-msgid "APIFuzzing|$VariableWithPassword"
-msgstr ""
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
+msgstr "$VARIABLE_WITH_PASSWORD"
-msgid "APIFuzzing|$VariableWithUsername"
-msgstr ""
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
+msgstr "$VARIABLE_WITH_USERNAME"
msgid "APIFuzzing|API Fuzzing Configuration"
-msgstr ""
+msgstr "Configuração de API Fuzzing"
msgid "APIFuzzing|Base URL of API testing target. For example, http://www.example.com."
msgstr ""
msgid "APIFuzzing|Choose a method"
-msgstr ""
+msgstr "Escolha um método"
msgid "APIFuzzing|Choose a profile"
-msgstr ""
+msgstr "Escolha um perfil"
msgid "APIFuzzing|Code snippet could not be generated. Try again later."
msgstr ""
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr "Ativar autenticação"
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -1574,31 +1585,31 @@ msgid "APIFuzzing|File path or URL to requests to be tested. For example, folder
msgstr ""
msgid "APIFuzzing|Generate code snippet"
-msgstr ""
+msgstr "Gerar snippet de código"
msgid "APIFuzzing|Make sure your credentials are secured"
msgstr ""
msgid "APIFuzzing|Password for basic authentication"
-msgstr ""
+msgstr "Senha para autenticação básica"
msgid "APIFuzzing|Predefined profiles"
-msgstr ""
+msgstr "Perfis predefinidos."
msgid "APIFuzzing|Scan mode"
-msgstr ""
+msgstr "Modo de verificação"
msgid "APIFuzzing|Scan profile"
-msgstr ""
+msgstr "Perfil de verificação"
msgid "APIFuzzing|Show code snippet for the profile"
msgstr ""
msgid "APIFuzzing|Target URL"
-msgstr ""
+msgstr "URL de destino"
msgid "APIFuzzing|There are three ways to perform scans."
-msgstr ""
+msgstr "Existem três formas de realizar a verificação."
msgid "APIFuzzing|Tip: Insert the following variables anywhere below stages and include"
msgstr ""
@@ -1625,25 +1636,25 @@ msgid "APIFuzzing|You may need a maintainer's help to secure your credentials."
msgstr ""
msgid "APIFuzzing|folder/example.postman_collection.json"
-msgstr ""
+msgstr "folder/example.postman_collection.json"
msgid "APIFuzzing|folder/example_fuzz.har"
-msgstr ""
+msgstr "folder/ejemplo_fuzz.har"
msgid "APIFuzzing|folder/openapi.json"
-msgstr ""
+msgstr "folder/openapi.json"
msgid "AWS Access Key"
msgstr "Chave de acesso AWS"
msgid "AWS Access Key. Only required if not using role instance credentials"
-msgstr ""
+msgstr "Chave de acesso AWS. Apenas necessário se não usar credenciais de instância do papel"
msgid "AWS Secret Access Key"
msgstr "Chave de acesso secreta da AWS"
msgid "AWS Secret Access Key. Only required if not using role instance credentials"
-msgstr ""
+msgstr "Chave de Acesso secreto AWS. Necessária apenas se não estiver usando credenciais de função da instância"
msgid "AWS service error: %{error}"
msgstr "Erro de serviço de AWS: %{error}"
@@ -1655,7 +1666,7 @@ msgid "About GitLab"
msgstr "Sobre o GitLab"
msgid "About auto deploy"
-msgstr "Sobre o deploy automático"
+msgstr "Sobre a implantação automática"
msgid "About this feature"
msgstr "Sobre essa funcionalidade"
@@ -1667,10 +1678,10 @@ msgid "Abuse reports"
msgstr "Relatórios de abuso"
msgid "Abuse reports notification email"
-msgstr ""
+msgstr "E-mail de notificação de relatórios de abuso"
msgid "Abuse reports will be sent to this address if it is set. Abuse reports are always available in the admin area."
-msgstr ""
+msgstr "Relatórios de abuso serão enviados para este endereço se estiver definido. Relatórios de abuso estão sempre disponíveis na área de administração."
msgid "Accept invitation"
msgstr "Aceitar convite"
@@ -1682,7 +1693,7 @@ msgid "Acceptable for use in this project"
msgstr "Aceitável para uso neste projeto"
msgid "Access Git repositories or the API."
-msgstr ""
+msgstr "Acessar repositórios Git ou a API."
msgid "Access Tokens"
msgstr "Tokens de acesso"
@@ -1694,7 +1705,7 @@ msgid "Access denied! Please verify you can add deploy keys to this repository."
msgstr "Acesso negado! Por favor, verifique se você pode adicionar chaves de deploy neste repositório."
msgid "Access denied: %{error}"
-msgstr ""
+msgstr "Acesso negado: %{error}"
msgid "Access expiration date"
msgstr "Data de expiração do acesso"
@@ -1715,7 +1726,7 @@ msgid "Access to '%{classification_label}' not allowed"
msgstr "Acesso a '%{classification_label}' não permitido"
msgid "AccessDropdown|Deploy Keys"
-msgstr ""
+msgstr "Implementar chaves"
msgid "AccessDropdown|Groups"
msgstr "Grupos"
@@ -1751,13 +1762,13 @@ msgid "AccessTokens|It cannot be used to access any other data."
msgstr "Ele não pode ser usado para acessar outros dados."
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
-msgstr ""
+msgstr "Mantenha este token em segredo. Qualquer pessoa que o tiver poderá acessar objetos estáticos do repositório como se fosse você. Se isso acontecer,%{reset_link_start} reinicie este token%{reset_link_end}."
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
-msgstr ""
+msgstr "Mantenha este token em segredo. Qualquer pessoa que o tiver poderá criar issues como se fosse você. Se isso acontecer %{link_reset_it}."
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
-msgstr ""
+msgstr "Mantenha este token em segredo. Qualquer pessoa que o tenha pode ler a atividade e emitir feeds RSS ou o feed do seu calendário como se fosse você. Se isso acontecer, %{link_reset_it}."
msgid "AccessTokens|Personal Access Tokens"
msgstr "Token de acesso pessoal"
@@ -1778,7 +1789,7 @@ msgid "AccessTokens|Your feed token authenticates you when your RSS reader loads
msgstr ""
msgid "AccessTokens|Your incoming email token authenticates you when you create a new issue by email, and is included in your personal project-specific email addresses."
-msgstr ""
+msgstr "Seu token de e-mail de entrada autentica você quando você cria um novo problema por e-mail e é incluído em seus endereços de e-mail pessoais específicos do projeto."
msgid "AccessTokens|Your static object token authenticates you when repository static objects (such as archives or blobs) are served from an external storage."
msgstr ""
@@ -1790,13 +1801,13 @@ msgid "AccessibilityReport|Learn more"
msgstr "Saiba mais"
msgid "AccessibilityReport|Message: %{message}"
-msgstr ""
+msgstr "Mensagem: %{message}"
msgid "AccessibilityReport|New"
msgstr "Novo"
msgid "AccessibilityReport|The accessibility scanning found an error of the following type: %{code}"
-msgstr ""
+msgstr "A verificação de acessibilidade encontrou um erro do seguinte tipo: %{code}"
msgid "Account"
msgstr "Conta"
@@ -1949,7 +1960,7 @@ msgid "Add an existing issue"
msgstr "Adicionar uma issue existente"
msgid "Add an impersonation token"
-msgstr ""
+msgstr "Adicionar um token de representação"
msgid "Add another link"
msgstr "Adicionar outro link"
@@ -1964,7 +1975,7 @@ msgid "Add bold text"
msgstr "Adicionar texto em negrito"
msgid "Add broadcast message"
-msgstr ""
+msgstr "Adicionar mensagem de transmissão"
msgid "Add child epic to an epic"
msgstr "Adicionar épico filho a um épico"
@@ -1973,7 +1984,7 @@ msgid "Add comment now"
msgstr "Adicionar comentário agora"
msgid "Add comment to design"
-msgstr ""
+msgstr "Adicionar comentário ao design"
msgid "Add commit messages as comments to Asana tasks. %{docs_link}"
msgstr ""
@@ -1985,7 +1996,7 @@ msgid "Add deploy freeze"
msgstr ""
msgid "Add deploy keys to grant read/write access to this repository. %{link_start}What are deploy keys?%{link_end}"
-msgstr ""
+msgstr "Adicionar chaves de implantação para conceder acesso de leitura/gravação a este repositório. %{link_start}O que são chaves de implantação?%{link_end}"
msgid "Add domain"
msgstr "Adicionar domínio"
@@ -1994,7 +2005,7 @@ msgid "Add email address"
msgstr "Adicionar endereço de e-mail"
msgid "Add email participant(s)"
-msgstr ""
+msgstr "Adicionar participantes de e-mail"
msgid "Add environment"
msgstr "Adicionar ambiente"
@@ -2054,7 +2065,7 @@ msgid "Add suggestion to batch"
msgstr "Adicionar sugestão ao lote"
msgid "Add system hook"
-msgstr ""
+msgstr "Adicionar system hook"
msgid "Add text to the sign-in page. Markdown enabled."
msgstr ""
@@ -2081,7 +2092,7 @@ msgid "Add to tree"
msgstr "Adicionar à árvore"
msgid "Add trigger"
-msgstr ""
+msgstr "Adicionar gatilho"
msgid "Add user(s) to the group:"
msgstr "Adicionar usuário(s) ao grupo:"
@@ -2105,10 +2116,10 @@ msgid "AddContextCommits|Add/remove"
msgstr "Adicionar/remover"
msgid "AddMember|Emails cannot be blank"
-msgstr ""
+msgstr "E-mail não pode ficar em branco"
msgid "AddMember|Invite email is invalid"
-msgstr ""
+msgstr "E-mail de Convite é inválido"
msgid "AddMember|Invite limit of %{daily_invites} per day exceeded"
msgstr ""
@@ -2126,7 +2137,7 @@ msgid "Added"
msgstr "Adicionado"
msgid "Added %{epic_ref} as a child epic."
-msgstr ""
+msgstr "Adicionado %{epic_ref} como um épico filho."
msgid "Added %{label_references} %{label_text}."
msgstr "Adicionado %{label_references} %{label_text}."
@@ -2150,13 +2161,13 @@ msgid "Adding new applications is disabled in your GitLab instance. Please conta
msgstr "A adição de novos aplicativos está desativada na sua instância do GitLab. Entre em contato com seu administrador do GitLab para obter a permissão"
msgid "Additional Metadata"
-msgstr ""
+msgstr "Metadados adicionais"
msgid "Additional minutes"
msgstr "Minutos adicionais"
msgid "Additional minutes:"
-msgstr ""
+msgstr "Minutos adicionais:"
msgid "Additional text"
msgstr "Texto adicional"
@@ -2171,7 +2182,7 @@ msgid "Additional text to show on the sign-in page"
msgstr "Texto adicional para mostrar na página de entrada"
msgid "Address"
-msgstr ""
+msgstr "Endereço"
msgid "Adds"
msgstr "Adiciona"
@@ -2192,10 +2203,10 @@ msgid "Adds an issue to an epic."
msgstr "Adicionado uma issue a um épico."
msgid "Adds email participant(s)"
-msgstr ""
+msgstr "Adiciona participantes de e-mail"
msgid "Adjust how frequently the GitLab UI polls for updates."
-msgstr ""
+msgstr "Ajuste a frequência com que a interface do usuário do GitLab para atualizações."
msgid "Adjust your filters/search criteria above. If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
msgstr ""
@@ -2207,7 +2218,7 @@ msgid "Admin Area"
msgstr "Ãrea do Administrador"
msgid "Admin Mode"
-msgstr ""
+msgstr "Modo administrador"
msgid "Admin Note"
msgstr "Nota do administrador"
@@ -2300,7 +2311,7 @@ msgid "AdminArea|Projects"
msgstr "Projetos"
msgid "AdminArea|Reporter"
-msgstr ""
+msgstr "Relatante"
msgid "AdminArea|Stop all jobs"
msgstr "Parar todas as tarefas"
@@ -2338,7 +2349,7 @@ msgstr "Ver projetos recentes"
msgid "AdminArea|View latest users"
msgstr "Usuários recentes"
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr "Você parará todas as tarefas. Os processos em execução serão abruptamente interrompidos."
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2357,7 +2368,7 @@ msgid "AdminSettings|A Let's Encrypt account will be configured for this GitLab
msgstr "Uma conta do Let's Encrypt será configurada parra essa instância do GitLab usando esse endereço de e-mail. Você receberá e-mails para avisar sobre a expiração do certificado. %{link_start}Saiba mais.%{link_end}"
msgid "AdminSettings|All new projects can use the instance's shared runners by default."
-msgstr ""
+msgstr "Todos os novos projetos podem usar os executores compartilhados da instância por padrão."
msgid "AdminSettings|Auto DevOps domain"
msgstr "Domínio de Auto DevOps"
@@ -2366,43 +2377,43 @@ msgid "AdminSettings|Configure Let's Encrypt"
msgstr "Configurar Let's Encrypt"
msgid "AdminSettings|Disable feed token"
-msgstr ""
+msgstr "Desativar token de feed"
msgid "AdminSettings|Disable public access to Pages sites"
msgstr "Desativar o acesso público ao Gitlab Pages"
msgid "AdminSettings|Domain verification is an essential security measure for public GitLab sites. Users are required to demonstrate they control a domain before it is enabled. %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "A verificação de domínio é uma medida de segurança essencial para sites GitLab públicos. Os usuários devem demonstrar que controlam um domínio antes de habilitá-lo. %{link_start}Saiba mais.%{link_end}"
msgid "AdminSettings|Enable shared runners for new projects"
-msgstr "Ativar runners compartilhados para novos projetos"
+msgstr "Ativar executores compartilhados para novos projetos"
msgid "AdminSettings|Feed token"
-msgstr ""
+msgstr "Token de feed"
msgid "AdminSettings|I have read and agree to the Let's Encrypt %{link_start}Terms of Service%{link_end} (PDF)."
-msgstr ""
+msgstr "Li e concordo com os termos de serviço%{link_end} %{link_start}(PDF) de Let's Encrypt."
msgid "AdminSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
-msgstr ""
+msgstr "Se não for especificado no nível de grupo ou instância, o padrão é %{default_initial_branch_name}. Não afeta os repositórios existentes."
msgid "AdminSettings|Keep the latest artifacts for all jobs in the latest successful pipelines"
-msgstr ""
+msgstr "Manter os artefatos mais recentes para todas as tarefas nos pipelines de sucesso mais recentes"
msgid "AdminSettings|Let's Encrypt email"
-msgstr ""
+msgstr "E-mail de Let's Encrypt"
msgid "AdminSettings|Maximum duration of a session for Git operations when 2FA is enabled."
msgstr ""
msgid "AdminSettings|New CI/CD variables in projects and groups default to protected."
-msgstr ""
+msgstr "Novas variáveis CI/CD em projetos e grupos padrão para protegidos."
msgid "AdminSettings|No required pipeline"
msgstr "Nenhum pipeline necessário"
msgid "AdminSettings|Protect CI/CD variables by default"
-msgstr ""
+msgstr "Proteger variáveis CI/CD por padrão"
msgid "AdminSettings|Require users to prove ownership of custom domains"
msgstr "Exigir que os usuários comprovem a propriedade de domínios personalizados"
@@ -2456,7 +2467,7 @@ msgid "AdminStatistics|Issues"
msgstr "Issues"
msgid "AdminStatistics|Merge requests"
-msgstr "Merge requests"
+msgstr "Solicitações de mesclagem"
msgid "AdminStatistics|Milestones"
msgstr "Marcos"
@@ -2566,14 +2577,8 @@ msgstr "Bloqueado"
msgid "AdminUsers|Blocking user has the following effects:"
msgstr "Bloquear o usuário tem os seguintes efeitos:"
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
-msgstr ""
+msgstr "Não é possível entrar ou acessar informações da instância"
msgid "AdminUsers|Cannot unblock LDAP blocked users"
msgstr "Não é possível desbloquear usuários bloqueados pelo LDAP"
@@ -2615,7 +2620,7 @@ msgid "AdminUsers|Delete user and contributions"
msgstr "Excluir o usuário e suas contribuições"
msgid "AdminUsers|Export permissions as CSV"
-msgstr ""
+msgstr "Exportar permissões como CSV"
msgid "AdminUsers|External"
msgstr "Externo"
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr "Está usando acento"
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr "É você!"
@@ -2648,7 +2656,7 @@ msgid "AdminUsers|Log in"
msgstr "Entrar"
msgid "AdminUsers|Manage (accept/reject) pending user sign ups"
-msgstr ""
+msgstr "Gerenciar (aceitar/rejeitar) inscrições pendentes de usuários"
msgid "AdminUsers|New user"
msgstr "Novo usuário"
@@ -2701,6 +2709,12 @@ msgstr "Enviar e-mail para usuários"
msgid "AdminUsers|Sort by"
msgstr "Ordenar por"
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr "O usuário não pode entrar."
+
msgid "AdminUsers|The user will be logged out"
msgstr "O usuário será desconectado"
@@ -2738,10 +2752,10 @@ msgid "AdminUsers|Unlock user %{username}?"
msgstr "Desbloquear usuário %{username}?"
msgid "AdminUsers|User administration"
-msgstr ""
+msgstr "Administração de usuários"
msgid "AdminUsers|User is validated and can use free CI minutes on shared runners."
-msgstr ""
+msgstr "Usuário é validado e pode usar minutos de CI gratuitos em executores compartilhados."
msgid "AdminUsers|User will not be able to access git repositories"
msgstr "Usuário não será capaz de acessar repositórios do git"
@@ -2759,22 +2773,22 @@ msgid "AdminUsers|Validate user account"
msgstr "Validar conta do usuário"
msgid "AdminUsers|View pending member requests"
-msgstr ""
+msgstr "Ver solicitações de membros pendentes"
msgid "AdminUsers|What can I do?"
-msgstr ""
+msgstr "O que posso fazer?"
msgid "AdminUsers|What does this mean?"
-msgstr ""
+msgstr "O que isto significa?"
-msgid "AdminUsers|When banned, users:"
-msgstr ""
+msgid "AdminUsers|When banned:"
+msgstr "Quando banido:"
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
msgstr "Quando o usuário faz login novamente, a sua conta estará reativada como uma conta totalmente ativa"
msgid "AdminUsers|Will be deleted"
-msgstr ""
+msgstr "Será excluído"
msgid "AdminUsers|Without projects"
msgstr "Sem projetos"
@@ -2786,31 +2800,31 @@ msgid "AdminUsers|You are about to permanently delete the user %{username}. This
msgstr ""
msgid "AdminUsers|You can always block their account again if needed."
-msgstr ""
+msgstr "Você sempre pode bloquear suas contas novamente, se necessário."
msgid "AdminUsers|You can always deactivate their account again if needed."
-msgstr ""
+msgstr "Você sempre pode desativar sua conta novamente, se necessário."
msgid "AdminUsers|You can always re-activate their account, their data will remain intact."
-msgstr ""
+msgstr "Você sempre pode reativar sua conta, seus dados permanecerão intactos."
msgid "AdminUsers|You can always unblock their account, their data will remain intact."
-msgstr ""
+msgstr "Você sempre pode desbloquear sua conta, seus dados permanecerão intactos."
msgid "AdminUsers|You can ban their account in the future if necessary."
-msgstr ""
+msgstr "Você pode banir suas contas no futuro, se necessário."
msgid "AdminUsers|You can unban their account in the future. Their data remains intact."
-msgstr ""
+msgstr "Você pode reverter o banimento dessas contas no futuro. Os dados permanecerão intactos."
msgid "AdminUsers|You cannot remove your own admin rights."
-msgstr ""
+msgstr "Você não pode remover seus próprios direitos de administrador."
msgid "AdminUsers|You must transfer ownership or delete the groups owned by this user before you can delete their account"
-msgstr ""
+msgstr "Você deve transferir a propriedade ou excluir os grupos pertencentes a este usuário antes de excluir sua conta"
msgid "AdminUsers|Your GitLab instance has reached the maximum allowed %{user_doc_link} set by an instance admin."
-msgstr ""
+msgstr "Sua instância do GitLab atingiu o máximo %{user_doc_link} definido por um administrador de instância."
msgid "AdminUsers|approve them"
msgstr ""
@@ -2822,7 +2836,7 @@ msgid "AdminUsers|docs"
msgstr "docs"
msgid "AdminUsers|user cap"
-msgstr ""
+msgstr "limite de usuários"
msgid "Administration"
msgstr "Administração"
@@ -2834,13 +2848,13 @@ msgid "Admin|Admin notes"
msgstr "Notas de administrador"
msgid "Admin|Learn more about quarterly reconciliation"
-msgstr ""
+msgstr "Saiba mais sobre a reconciliação trimestral"
msgid "Admin|Note"
msgstr "Nota"
msgid "Admin|Quarterly reconciliation will occur on %{qrtlyDate}"
-msgstr ""
+msgstr "A reconciliação trimestral ocorrerá em %{qrtlyDate}"
msgid "Admin|The number of max seats used for your namespace is currently exceeding the number of seats in your subscription. On %{qrtlyDate}, GitLab will process a quarterly reconciliation and automatically bill you a prorated amount for the overage. There is no action needed from you. If you have a credit card on file, it will be charged. Otherwise, you will receive an invoice."
msgstr ""
@@ -2849,10 +2863,10 @@ msgid "Admin|The number of maximum users for your instance is currently exceedin
msgstr ""
msgid "Admin|View pending user approvals"
-msgstr ""
+msgstr "Ver aprovações de usuários pendentes"
msgid "Admin|Your instance has reached its user cap"
-msgstr ""
+msgstr "Sua instância atingiu o limite de usuários"
msgid "Advanced"
msgstr "Avançado"
@@ -2965,7 +2979,7 @@ msgid "AlertManagement|No alert data to display."
msgstr "Nenhum dado de alerta para exibir."
msgid "AlertManagement|No alerts available to display. See %{linkStart}enabling alert management%{linkEnd} for more information on adding alerts to the list."
-msgstr ""
+msgstr "Não há alerta disponível para exibir. Veja %{linkStart}ativando o gerenciamento de alertas%{linkEnd} para mais informações sobre a adição de alerta à lista."
msgid "AlertManagement|No alerts to display."
msgstr "Nenhum alerta para exibir."
@@ -3004,7 +3018,7 @@ msgid "AlertManagement|Status"
msgstr "Status"
msgid "AlertManagement|Surface alerts in GitLab"
-msgstr ""
+msgstr "Alertas de superfície do GitLab"
msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
msgstr ""
@@ -3139,7 +3153,7 @@ msgid "AlertSettings|Sample payload has been parsed. You can now map the fields.
msgstr ""
msgid "AlertSettings|Save & create test alert"
-msgstr ""
+msgstr "Salvar e criar alerta de teste"
msgid "AlertSettings|Save integration"
msgstr "Salvar integração"
@@ -3157,7 +3171,7 @@ msgid "AlertSettings|Send without saving"
msgstr "Enviar sem salvar"
msgid "AlertSettings|The form has unsaved changes"
-msgstr ""
+msgstr "O formulário tem alterações não salvas"
msgid "AlertSettings|The form has unsaved changes. How would you like to proceed?"
msgstr ""
@@ -3244,7 +3258,7 @@ msgid "All"
msgstr "Todos"
msgid "All %{replicableType} are being scheduled for %{action}"
-msgstr ""
+msgstr "Todos os %{replicableType} estão sendo agendados para %{action}"
msgid "All (default)"
msgstr "Todos (padrão)"
@@ -3253,7 +3267,7 @@ msgid "All Members"
msgstr "Todos os membros"
msgid "All branches"
-msgstr "Todos os branches"
+msgstr "Todas as ramificações"
msgid "All changes are committed"
msgstr "Houve commit com todas as mudanças"
@@ -3280,7 +3294,7 @@ msgid "All merge conflicts were resolved. The merge request can now be merged."
msgstr "Todos os conflitos de merge foram resolvidos. A merge request pode agora ter o merge realizado."
msgid "All merge request dependencies have been merged"
-msgstr ""
+msgstr "Todas as dependências da solicitação de mesclagem tiveram foram mescladas"
msgid "All paths are relative to the GitLab URL. Do not include %{relative_url_link_start}relative URL%{relative_url_link_end}."
msgstr ""
@@ -3307,10 +3321,10 @@ msgid "Allow access to members of the following group"
msgstr "Permitir o acesoaos membros do seguinte grupo"
msgid "Allow access to the following IP addresses"
-msgstr ""
+msgstr "Permitir acesso aos seguintes endereços de IP"
msgid "Allow commits from members who can merge to the target branch."
-msgstr "Permitir commits de membros que podem fazer merge ao branch de destino."
+msgstr "Permitir commits de membros que podem mesclar na ramificação de destino."
msgid "Allow group owners to manage LDAP-related settings"
msgstr "Permitir que proprietários de grupos gerenciem configurações relacionadas ao LDAP"
@@ -3328,10 +3342,10 @@ msgid "Allow owners to manually add users outside of LDAP"
msgstr ""
msgid "Allow password authentication for Git over HTTP(S)"
-msgstr ""
+msgstr "Permitir autenticação de senha para Git sobre HTTP(S)"
msgid "Allow password authentication for the web interface"
-msgstr ""
+msgstr "Permitir autenticação de senha para a interface web"
msgid "Allow project maintainers to configure repository mirroring"
msgstr "Permitir mantenedores do projeto de configurar o espelhamento do projeto"
@@ -3343,7 +3357,7 @@ msgid "Allow projects within this group to use Git LFS"
msgstr "Permitir que projetos dentro deste grupo usem o Git LFS"
msgid "Allow public access to pipelines and job details, including output logs and artifacts."
-msgstr ""
+msgstr "Permitir o acesso público a pipelines e detalhes de tarefas, incluindo logs de saída e artefatos."
msgid "Allow requests to the local network from hooks and services."
msgstr "Permitir requisições de hooks e serviços para a rede local."
@@ -3358,7 +3372,7 @@ msgid "Allow subgroups to set up their own two-factor authentication rules"
msgstr "Permitir que subgrupos configurem suas próprias regras de autenticação de dois fatores"
msgid "Allow this key to push to this repository"
-msgstr ""
+msgstr "Permitir que esta chave faça push para este repositório"
msgid "Allow this secondary node to replicate content on Object Storage"
msgstr ""
@@ -3400,7 +3414,7 @@ msgid "Almost there"
msgstr "Quase lá"
msgid "Almost there..."
-msgstr ""
+msgstr "Quase lá..."
msgid "Already blocked"
msgstr "Já bloqueado"
@@ -3430,7 +3444,7 @@ msgid "Amazon EKS"
msgstr "Amazon EKS"
msgid "Amazon EKS integration allows you to provision EKS clusters from GitLab."
-msgstr ""
+msgstr "A integração do Amazon EKS permite provisionar clusters EKS do GitLab."
msgid "Amazon Web Services Logo"
msgstr "Logotipo do Amazon Web Services"
@@ -3475,7 +3489,7 @@ msgid "An error in reporting in which a test result incorrectly indicates the pr
msgstr ""
msgid "An error occurred adding a draft to the thread."
-msgstr ""
+msgstr "Ocorreu um erro ao adicionar um rascunho à discussão."
msgid "An error occurred adding a new draft."
msgstr "Ocorreu um erro ao adicionar um novo rascunho."
@@ -3493,13 +3507,13 @@ msgid "An error occurred fetching the dropdown data."
msgstr "Erro ao buscar os dados do dropdown."
msgid "An error occurred fetching the project authors."
-msgstr ""
+msgstr "Ocorreu um erro ao buscar os autores do projeto."
msgid "An error occurred previewing the blob"
msgstr "Erro ao pré-visualizar o blob"
msgid "An error occurred when removing the label."
-msgstr ""
+msgstr "Ocorreu um erro ao remover a etiqueta."
msgid "An error occurred when toggling the notification subscription"
msgstr "Erro ao modificar notificação de assinatura"
@@ -3508,10 +3522,10 @@ msgid "An error occurred when updating the issue weight"
msgstr "Ocorreu um erro ao atualizar o peso do issue"
msgid "An error occurred when updating the title"
-msgstr ""
+msgstr "Ocorreu um erro ao atualizar o título"
msgid "An error occurred while acknowledging the notification. Refresh the page and try again."
-msgstr ""
+msgstr "Ocorreu um erro ao confirmar a notificação. Atualize a página e tente novamente."
msgid "An error occurred while adding approvers"
msgstr "Ocorreu um erro ao adicionar aprovadores"
@@ -3520,7 +3534,7 @@ msgid "An error occurred while adding formatted title for epic"
msgstr "Ocorreu um erro ao adicionar o título formatado para épico"
msgid "An error occurred while authorizing your role"
-msgstr ""
+msgstr "Ocorreu um erro ao autorizar sua função"
msgid "An error occurred while checking group path. Please refresh and try again."
msgstr "Ocorreu um erro ao verificar o diretório do grupo. Atualize e tente novamente."
@@ -3550,22 +3564,22 @@ msgid "An error occurred while dismissing the feature highlight. Refresh the pag
msgstr "Erro ao remover alerta. Atualize a página e tente novamente."
msgid "An error occurred while drawing job relationship links."
-msgstr ""
+msgstr "Ocorreu um erro ao desenhar links de relação de trabalho."
msgid "An error occurred while enabling Service Desk."
msgstr "Um erro ocorreu ao habilitar a Central de serviços."
msgid "An error occurred while fetching ancestors"
-msgstr ""
+msgstr "Ocorreu um erro ao obter antepassados"
msgid "An error occurred while fetching branches. Retry the search."
-msgstr ""
+msgstr "Ocorreu um erro ao obter as ramificações. Tente novamente a pesquisa."
msgid "An error occurred while fetching codequality mr diff reports."
msgstr ""
msgid "An error occurred while fetching commits. Retry the search."
-msgstr ""
+msgstr "Ocorreu um erro ao obter os commits. Tente novamente a pesquisa."
msgid "An error occurred while fetching coverage reports."
msgstr "Ocorreu um erro ao obter relatórios de cobertura."
@@ -3589,10 +3603,10 @@ msgid "An error occurred while fetching markdown preview"
msgstr "Erro ao gerar pré-visualização do markdown"
msgid "An error occurred while fetching participants"
-msgstr ""
+msgstr "Ocorreu um erro ao buscar os participantes"
msgid "An error occurred while fetching participants."
-msgstr ""
+msgstr "Ocorreu um erro ao buscar os participantes."
msgid "An error occurred while fetching pending comments"
msgstr "Ocorreu um erro ao recuperar os comentários pendentes"
@@ -3601,22 +3615,19 @@ msgid "An error occurred while fetching projects autocomplete."
msgstr "Ocorreu um erro ao buscar o autocomplemento de projetos."
msgid "An error occurred while fetching reference"
-msgstr ""
+msgstr "Ocorreu um erro ao obter referência"
msgid "An error occurred while fetching sidebar data"
msgstr "Erro ao recuperar informações da barra lateral"
msgid "An error occurred while fetching tags. Retry the search."
-msgstr ""
+msgstr "Ocorreu um erro ao obter as tags. Tente novamente a pesquisa."
msgid "An error occurred while fetching terraform reports."
msgstr "Ocorreu um erro ao obter os relatórios de terraform."
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr "Ocorreu um erro ao buscar lista de painéis. Por favor, tente novamente."
-
msgid "An error occurred while fetching the job log."
-msgstr "Ocorreu um erro na recuperação de logs da tarefa."
+msgstr "Ocorreu um erro na recuperação de registros da tarefa."
msgid "An error occurred while fetching the job logs."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr "Ocorreu um erro ao recuperar as tarefas."
msgid "An error occurred while fetching the latest pipeline."
msgstr "Ocorreu um erro ao recuperar o último pipeline."
-msgid "An error occurred while fetching the pipeline."
-msgstr "Erro ao recuperar informações da pipeline."
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr "Ocorreu um erro ao buscar as releases. Por favor, tente novamente."
@@ -3685,7 +3693,13 @@ msgid "An error occurred while loading issues"
msgstr "Ocorreu um erro ao carregar as issues"
msgid "An error occurred while loading merge requests."
-msgstr "Ocorreu um erro ao carregar os merge requests."
+msgstr "Ocorreu um erro ao carregar as solicitações de mesclagem"
+
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -3709,13 +3723,13 @@ msgid "An error occurred while loading the file. Please try again."
msgstr "Ocorreu um erro ao carregar os dados. Por favor, tente novamente."
msgid "An error occurred while loading the merge request changes."
-msgstr "Ocorreu um erro ao carregar as alterações do merge request."
+msgstr "Ocorreu um erro ao carregar as alterações da solicitação de mesclagem."
msgid "An error occurred while loading the merge request version data."
-msgstr "Ocorreu um erro ao carregar dados de versão do merge request."
+msgstr "Ocorreu um erro ao carregar dados de versão da solicitação de mesclagem."
msgid "An error occurred while loading the merge request."
-msgstr "Ocorreu um erro ao carregar o merge request."
+msgstr "Ocorreu um erro ao carregar a solicitação de mesclagem."
msgid "An error occurred while loading the notification settings. Please try again."
msgstr ""
@@ -3769,7 +3783,7 @@ msgid "An error occurred while retrieving projects."
msgstr "Ocorreu um erro ao recuperar projetos."
msgid "An error occurred while saving changes: %{error}"
-msgstr ""
+msgstr "Ocorreu um erro ao salvar as alterações: %{error}"
msgid "An error occurred while subscribing to notifications."
msgstr "Ocorreu um erro ao inscrever às notificações."
@@ -3790,7 +3804,7 @@ msgid "An error occurred while updating approvers"
msgstr "Ocorreu um erro ao atualizar os aprovadores"
msgid "An error occurred while updating assignees."
-msgstr ""
+msgstr "Ocorreu um erro ao atualizar os responsáveis."
msgid "An error occurred while updating configuration."
msgstr "Ocorreu um erro ao atualizar a configuração."
@@ -3802,13 +3816,13 @@ msgid "An error occurred while updating the comment"
msgstr "Ocorreu um erro durante a atualização do comentário"
msgid "An error occurred while updating the configuration."
-msgstr ""
+msgstr "Ocorreu um erro ao atualizar a configuração."
msgid "An error occurred while updating the notification settings. Please try again."
msgstr ""
msgid "An error occurred while uploading the file. Please try again."
-msgstr ""
+msgstr "Ocorreu um erro ao enviar o arquivo. Por favor, tente novamente."
msgid "An error occurred while uploading the image. Please try again."
msgstr "Ocorreu um erro ao enviar a imagem. Por favor, tente novamente"
@@ -3826,7 +3840,7 @@ msgid "An error occurred. Please try again."
msgstr "Ocorreu um erro. Tente novamente."
msgid "An example project for managing Kubernetes clusters integrated with GitLab"
-msgstr ""
+msgstr "Um projeto de exemplo para gerenciar clusters Kubernetes integrados ao GitLab"
msgid "An example project that shows off the best practices for setting up GitLab for your own organization, including sample issues, merge requests, and milestones"
msgstr ""
@@ -3835,7 +3849,7 @@ msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines
msgstr ""
msgid "An instance-level serverless domain already exists."
-msgstr ""
+msgstr "Um domínio serverless a nível de instância já existe."
msgid "An issue already exists"
msgstr "Uma issue já existe"
@@ -3847,7 +3861,7 @@ msgid "An unexpected error occurred while checking the project environment."
msgstr "Um erro inesperado ocorreu enquanto verificava o ambiente de projeto."
msgid "An unexpected error occurred while checking the project runners."
-msgstr "Ocorreu um erro inesperado ao verificar os runners do projeto."
+msgstr "Ocorreu um erro inesperado ao verificar os executores do projeto."
msgid "An unexpected error occurred while communicating with the Web Terminal."
msgstr "Ocorreu um erro inesperado durante a comunicação com o terminal da web."
@@ -3862,7 +3876,7 @@ msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr "Ocorreu um erro inesperado ao parar o terminal da web."
msgid "An unknown error occurred while loading this graph."
-msgstr ""
+msgstr "Ocorreu um erro desconhecido ao carregar este gráfico."
msgid "An unknown error occurred."
msgstr "Ocorreu um erro desconhecido."
@@ -3871,16 +3885,16 @@ msgid "Analytics"
msgstr "Telemetria"
msgid "Analyze a review version of your web application."
-msgstr ""
+msgstr "Analise uma versão de revisão da sua aplicação web."
msgid "Analyze your dependencies for known vulnerabilities."
-msgstr ""
+msgstr "Analise suas dependências em busca de vulnerabilidades conhecidas."
msgid "Analyze your source code and git history for secrets."
-msgstr ""
+msgstr "Analise seu código-fonte e histórico git para segredos."
msgid "Analyze your source code for known vulnerabilities."
-msgstr ""
+msgstr "Analise seu código-fonte em busca de vulnerabilidades conhecidas."
msgid "Analyzing file…"
msgstr "Analisando arquivo..."
@@ -3889,16 +3903,16 @@ msgid "Ancestors"
msgstr "Ancestrais"
msgid "And this registration token:"
-msgstr ""
+msgstr "E esse token de registro:"
msgid "Anonymous"
msgstr "Anônimo"
msgid "Another action is currently in progress"
-msgstr ""
+msgstr "Outra ação está atualmente em progresso"
msgid "Another issue tracker is already in use. Only one issue tracker service can be active at a time"
-msgstr ""
+msgstr "Outro rastreador de issue já está em uso. Somente um serviço de rastreador de issue pode estar ativo por vez"
msgid "Anti-spam verification"
msgstr "Verificação anti-spam"
@@ -3916,7 +3930,7 @@ msgid "Any Milestone"
msgstr "Qualquer marco"
msgid "Any branch"
-msgstr "Qualquer branch"
+msgstr "Qualquer ramificação"
msgid "Any eligible user"
msgstr "Qualquer usuário elegível"
@@ -3931,13 +3945,13 @@ msgid "Any label"
msgstr "Qualquer etiqueta"
msgid "Any member with at least Developer permissions on the project."
-msgstr ""
+msgstr "Qualquer membro com permissões de desenvolvedor ou superior no projeto."
msgid "Any milestone"
msgstr "Qualquer marco"
msgid "Any namespace"
-msgstr "Qualquer namespace"
+msgstr "Qualquer espaço de nome"
msgid "App ID"
msgstr "App ID"
@@ -4158,18 +4172,24 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] "%{count} aprovação obrigatória de %{membersCount}"
msgstr[1] "%{count} aprovações obrigatórias de %{membersCount}"
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
msgstr "Adicionar aprovadores"
msgid "ApprovalRule|All scanners"
-msgstr ""
+msgstr "Todas as verificações"
+
+msgid "ApprovalRule|All severity levels"
+msgstr "Todos os níveis de severidade"
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr "Aplique esta regra de aprovação para considerar apenas os níveis de severidade selecionados."
+
msgid "ApprovalRule|Approval rules"
msgstr "Regras de aprovação"
@@ -4197,40 +4217,55 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr "Selecione pelo menos um nível de severidade"
+
msgid "ApprovalRule|Rule name"
msgstr "Nome da regra"
msgid "ApprovalRule|Security scanners"
-msgstr ""
+msgstr "Verificações de segurança"
msgid "ApprovalRule|Select All"
msgstr "Selecionar tudo"
msgid "ApprovalRule|Select scanners"
-msgstr ""
+msgstr "Selecionar verificação"
+
+msgid "ApprovalRule|Select severity levels"
+msgstr "Selecione os níveis de severidade"
+
+msgid "ApprovalRule|Severity levels"
+msgstr "Níveis de severidade"
msgid "ApprovalRule|Target branch"
-msgstr "Branch de destino"
+msgstr "Ramificação de destino"
msgid "ApprovalRule|Vulnerabilities allowed"
-msgstr ""
+msgstr "Vulnerabilidades permitidas"
msgid "ApprovalSettings|Merge request approval settings have been updated."
-msgstr "As configurações de merge request foram atualizadas"
+msgstr "As configurações de solicitação de mesclagem foram atualizadas"
+
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
-msgstr "Prevenir as aprovações de MR pelo criador"
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
+msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
-msgstr "Prevenir que os usuários modifiquem as regras de aprovação do MR."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
-msgstr "Remover todas as aprovações em uma merge request quando novos commits são enviadas para seu branch de origem."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4240,7 +4275,7 @@ msgid "ApprovalSettings|There was an error updating merge request approval setti
msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
-msgstr ""
+msgstr "Esta configuração está caracterizada no nível de instância e pode ser somente alterada por um administrador."
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
msgstr ""
@@ -4261,7 +4296,7 @@ msgid "Approve"
msgstr "Aprovar"
msgid "Approve a merge request"
-msgstr "Aprovar um merge request"
+msgstr "Aprovar uma solicitação de mesclagem"
msgid "Approve the current merge request."
msgstr "Aprovar o merge request atual."
@@ -4294,7 +4329,7 @@ msgid "April"
msgstr "Abril"
msgid "Architecture not found for OS"
-msgstr ""
+msgstr "Arquitetura não encontrada para SO"
msgid "Archive"
msgstr "Arquivar"
@@ -4324,7 +4359,7 @@ msgid "Archived projects"
msgstr "Projetos arquivados"
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "Arquivar o projeto fará com que ele seja apenas para leitura. Estará oculto do painel e não aparece nas pesquisas. %{strong_start}O repositório não pode ter novos commits, e nenhuma issues, comentário ou outras entidades que possam ser criadas.%{strong_end} %{link_start}Saiba mais.%{link_end}"
msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
msgstr "VOCÊ TEM ABSOLUTA CERTEZA que deseja excluir esse projeto?"
@@ -4341,6 +4376,9 @@ msgstr "Tem certeza que deseja desarquivar este projeto?"
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr "Tem certeza de que deseja tentar mesclar?"
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr "Tem certeza de que deseja cancelar a edição deste comentário?"
@@ -4375,7 +4413,7 @@ msgid "Are you sure you want to discard this comment?"
msgstr "Tem certeza de que deseja descartar este comentário?"
msgid "Are you sure you want to discard your changes?"
-msgstr ""
+msgstr "Tem certeza de que deseja descartar suas alterações?"
msgid "Are you sure you want to erase this build?"
msgstr "Tem certeza de que deseja limpar este build?"
@@ -4422,13 +4460,13 @@ msgid "Are you sure you want to remove the license?"
msgstr "Tem certeza que deseja remover a licença?"
msgid "Are you sure you want to remove this deploy key? If anything is still using this key, it will stop working."
-msgstr ""
+msgstr "Tem certeza de que quer remover esta chave de implantação? Se algo ainda estiver utilizando esta chave, irá parar de funcionar."
msgid "Are you sure you want to remove this identity?"
msgstr "Você tem certeza de que deseja excluir este item?"
msgid "Are you sure you want to remove this list?"
-msgstr ""
+msgstr "Tem certeza que deseja remover esta lista?"
msgid "Are you sure you want to reset the SCIM token? SCIM provisioning will stop working until the new token is updated."
msgstr "Tem certeza de que deseja redefinir o token SCIM? O provisionamento SCIM irá parar de funcionar até que o novo token seja atualizado."
@@ -4437,10 +4475,10 @@ msgid "Are you sure you want to reset the health check token?"
msgstr "Você tem certeza que quer reiniciar o token de status de saúde?"
msgid "Are you sure you want to reset the registration token?"
-msgstr ""
+msgstr "Você tem certeza que quer recriar o token de registro?"
msgid "Are you sure you want to retry this migration?"
-msgstr ""
+msgstr "Tem certeza de que deseja repetir esta migração?"
msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr "Tem certeza de que deseja revogar este %{type}? Essa ação não pode ser desfeita."
@@ -4449,7 +4487,7 @@ msgid "Are you sure you want to revoke this nickname?"
msgstr "Tem a certeza que deseja revogar este apelido?"
msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
-msgstr ""
+msgstr "Tem certeza de que deseja revogar este token de acesso pessoal? Esta ação não pode ser desfeita."
msgid "Are you sure you want to stop this environment?"
msgstr "Você tem certeza de que deseja parar este ambiente?"
@@ -4476,10 +4514,10 @@ msgid "Are you sure? Removing this GPG key does not affect already signed commit
msgstr "Você tem certeza? A remoção dessa chave GPG não afeta commits já assinados."
msgid "Are you sure? The device will be signed out of GitLab and all remember me tokens revoked."
-msgstr ""
+msgstr "Tem certeza? O dispositivo será desconectado do GitLab e todas os tokens de lembrar-me revogados."
msgid "Are you sure? This will invalidate your registered applications and U2F / WebAuthn devices."
-msgstr ""
+msgstr "Você tem certeza? Isso invalidará seus aplicativos registrados e dispositivos U2F / WebAuthn."
msgid "Are you sure? This will invalidate your registered applications and U2F devices."
msgstr "Você tem certeza? Isso invalidará seus aplicativos registrados e dispositivos U2F."
@@ -4499,11 +4537,8 @@ msgstr "O artefato foi excluído com sucesso."
msgid "Artifacts"
msgstr "Artefatos"
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
-msgstr ""
+msgstr "À medida que continuamos a construir mais recursos para SAST, adoraríamos seu feedback sobre o recurso de configuração SAST %{linkStart}nessa issue%{linkEnd}."
msgid "AsanaService|%{user} pushed to branch %{branch} of %{project_name} ( %{commit_url} ):"
msgstr "%{user} enviou para o branch %{branch} do projeto %{project_name} ( %{commit_url} ):"
@@ -4521,7 +4556,7 @@ msgid "Ascending"
msgstr "Ascendente"
msgid "Ask again later"
-msgstr ""
+msgstr "Pergunte novamente mais tarde"
msgid "Ask someone with write access to resolve it."
msgstr ""
@@ -4536,7 +4571,7 @@ msgid "Assets"
msgstr "Recursos"
msgid "Assets:"
-msgstr ""
+msgstr "Ativos:"
msgid "Assign"
msgstr "Atribuir"
@@ -4587,7 +4622,7 @@ msgid "Assigned Issues"
msgstr "Issues atribuídas"
msgid "Assigned merge requests"
-msgstr "Merge request atribuídos"
+msgstr "Solicitações de mesclagem atribuídas"
msgid "Assigned projects"
msgstr "Projetos atribuídos"
@@ -4618,9 +4653,6 @@ msgstr "O responsável não tem acesso"
msgid "Assignee lists not available with your current license"
msgstr "Quadro de responsáveis não disponível com sua licença atual"
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr "Listas de responsáveis mostram todas as issues atribuídas ao usuário selecionado."
-
msgid "Assignee(s)"
msgstr "Responsável(is)"
@@ -4628,7 +4660,7 @@ msgid "Assignees"
msgstr "Responsáveis"
msgid "Assigns %{assignee_users_sentence}."
-msgstr ""
+msgstr "Atribui %{assignee_users_sentence}."
msgid "Assigns %{reviewer_users_sentence} as %{reviewer_text}."
msgstr ""
@@ -4735,16 +4767,22 @@ msgid "Authenticated API request rate limit"
msgstr ""
msgid "Authenticated API requests"
+msgstr "Requisições de API autenticadas"
+
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
msgstr ""
msgid "Authenticated web rate limit period in seconds"
msgstr ""
msgid "Authenticated web request rate limit"
-msgstr ""
+msgstr "Limite da taxa de solicitação das requisições web autenticada"
msgid "Authenticated web requests"
-msgstr ""
+msgstr "Requisições de web autenticadas"
msgid "Authenticating"
msgstr "Autenticando"
@@ -4774,7 +4812,7 @@ msgid "Authentication via U2F device failed."
msgstr "Autenticação via dispositivo U2F falhou."
msgid "Authentication via WebAuthn device failed."
-msgstr ""
+msgstr "A autenticação via dispositivo WebAuthn falhou."
msgid "Author"
msgstr "Autor"
@@ -4795,10 +4833,10 @@ msgid "Authorization key"
msgstr "Chave de autorização"
msgid "Authorization required"
-msgstr ""
+msgstr "Autorização necessária"
msgid "Authorization token duration (minutes)"
-msgstr ""
+msgstr "Duração do token de autorização (minutos)"
msgid "Authorization was granted by entering your username and password in the application."
msgstr "A autorização foi concedida digitando seu nome de usuário e senha no aplicativo."
@@ -4834,10 +4872,10 @@ msgid "Auto stop successfully canceled."
msgstr "Parada automática cancelada com sucesso."
msgid "Auto-cancel redundant pipelines"
-msgstr ""
+msgstr "Cancelar automaticamente os pipelines redundantes"
msgid "Auto-close referenced issues on default branch"
-msgstr ""
+msgstr "Fechar automaticamente as issues referenciadas na ramificação padrão"
msgid "AutoDevOps|%{auto_devops_start}Automate building, testing, and deploying%{auto_devops_end} your applications based on your continuous integration and delivery configuration. %{quickstart_start}How do I get started?%{quickstart_end}"
msgstr ""
@@ -4849,7 +4887,7 @@ msgid "AutoDevOps|Auto DevOps documentation"
msgstr "Documentação de auto DevOps"
msgid "AutoDevOps|Dismiss Auto DevOps box"
-msgstr ""
+msgstr "Dispensar caixa de Auto DevOps"
msgid "AutoDevOps|Enable in settings"
msgstr "Habilitar nas configurações"
@@ -4870,7 +4908,7 @@ msgid "AutoRemediation| 1 Merge Request"
msgstr ""
msgid "AutoRemediation|%{mrsCount} ready for review"
-msgstr ""
+msgstr "%{mrsCount} pronto para revisão"
msgid "AutoRemediation|Auto-fix"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr "Gerenciamento automático de certificado usando Let's Encrypt"
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -4933,16 +4974,16 @@ msgid "Available ID"
msgstr "ID disponível"
msgid "Available group runners: %{runners}"
-msgstr ""
+msgstr "Executores de grupo disponíveis: %{runners}"
msgid "Available runners: %{runners}"
-msgstr ""
+msgstr "Executores disponíveis: %{runners}"
msgid "Available shared runners:"
-msgstr ""
+msgstr "Executores compartilhados disponíveis:"
msgid "Available specific runners"
-msgstr "Runners específicos disponíveis"
+msgstr "Executores específicos disponíveis"
msgid "Avatar for %{assigneeName}"
msgstr "Imagem de perfil para %{assigneeName}"
@@ -5008,7 +5049,7 @@ msgid "Badges|Deleting the badge failed, please try again."
msgstr "Erro ao apagar selo, por favor, tente novamente."
msgid "Badges|Enter a valid URL"
-msgstr ""
+msgstr "Digite uma URL válida"
msgid "Badges|Example: %{exampleUrl}"
msgstr "Exemplo: %{exampleUrl}"
@@ -5089,7 +5130,7 @@ msgid "Based on"
msgstr "Baseado em"
msgid "Be careful. Changing the project's namespace can have unintended side effects."
-msgstr "Cuidado. Alterar o namespace do projeto pode ter efeitos colaterais indesejados."
+msgstr "Cuidado. Alterar o espaço de nome do projeto pode ter efeitos colaterais indesejados."
msgid "Be careful. Renaming a project's repository can have unintended side effects."
msgstr "Tenha cuidado. Renomear o repositório de um projeto pode ter efeitos colaterais indesejados."
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr "Comece com o commit selecionado"
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr "Abaixo estão as impressões digitais das chaves do host SSH da instância atual."
@@ -5131,10 +5169,10 @@ msgid "Billing"
msgstr "Cobrança"
msgid "BillingPlans|%{group_name} is currently using the %{plan_name}."
-msgstr ""
+msgstr "%{group_name} está atualmente usando o %{plan_name}."
msgid "BillingPlans|@%{user_name} you are currently using the %{plan_name}."
-msgstr ""
+msgstr "@%{user_name} você está usando atualmente o %{plan_name}."
msgid "BillingPlans|Compare all plans"
msgstr "Comparar todos os planos"
@@ -5146,7 +5184,7 @@ msgid "BillingPlans|End of availability for the Bronze Plan"
msgstr ""
msgid "BillingPlans|Free upgrade!"
-msgstr ""
+msgstr "Atualização grátis!"
msgid "BillingPlans|If you would like to downgrade your plan please contact %{support_link_start}Customer Support%{support_link_end}."
msgstr "Se você gostaria de diminuir o seu plano, por favor entre em contato com o %{support_link_start}Suporte ao Cliente%{support_link_end}."
@@ -5158,7 +5196,7 @@ msgid "BillingPlans|Learn more about each plan by visiting our %{pricing_page_li
msgstr "Saiba mais sobre cada plano visitando nossa %{pricing_page_link}."
msgid "BillingPlans|Looking to purchase or manage a subscription for your group? Navigate to your %{groups_link} and go to %{strong_open}Settings &gt; Billing.%{strong_close}"
-msgstr ""
+msgstr "Procurando comprar ou gerenciar uma assinatura para seu grupo? Navegue até seu %{groups_link} e vá para %{strong_open}Configurações &gt; Cobrança.%{strong_close}"
msgid "BillingPlans|Manage plan"
msgstr "Gerenciar plano"
@@ -5212,7 +5250,7 @@ msgid "BillingPlan|Upgrade"
msgstr "Atualizar"
msgid "BillingPlan|Upgrade for free"
-msgstr ""
+msgstr "Atualizar gratuitamente"
msgid "Billings|%{planName} plan"
msgstr "Plano %{planName}"
@@ -5275,13 +5313,13 @@ msgid "Billing|Cannot remove user"
msgstr "Não é possível remover usuário"
msgid "Billing|Direct memberships"
-msgstr ""
+msgstr "Membros diretos"
msgid "Billing|Enter at least three characters to search."
msgstr ""
msgid "Billing|Export list"
-msgstr ""
+msgstr "Exportar lista"
msgid "Billing|Group"
msgstr "Grupo"
@@ -5293,10 +5331,10 @@ msgid "Billing|Members who were invited via a group invitation cannot be removed
msgstr ""
msgid "Billing|No users to display."
-msgstr ""
+msgstr "Nenhum usuário para exibir"
msgid "Billing|Private"
-msgstr ""
+msgstr "Privado"
msgid "Billing|Project invite"
msgstr "Convite de projeto"
@@ -5308,13 +5346,13 @@ msgid "Billing|Toggle seat details"
msgstr ""
msgid "Billing|Type %{username} to confirm"
-msgstr ""
+msgstr "Digite %{username} para confirmar"
msgid "Billing|User was successfully removed"
-msgstr ""
+msgstr "O usuário foi removido com sucesso"
msgid "Billing|Users occupying seats in"
-msgstr ""
+msgstr "Usuários que ocupam assentos em"
msgid "Billing|You are about to remove user %{username} from your subscription. If you continue, the user will be removed from the %{namespace} group and all its subgroups and projects. This action can't be undone."
msgstr ""
@@ -5323,7 +5361,7 @@ msgid "Bitbucket Server Import"
msgstr "Importação de Servidores Bitbucket"
msgid "Bitbucket Server import"
-msgstr ""
+msgstr "Importar um servidor de Bitbucket"
msgid "Bitbucket import"
msgstr "Importar do Bitbucket"
@@ -5349,7 +5387,7 @@ msgid "Blocking"
msgstr "Bloqueando"
msgid "Blocking issues"
-msgstr "Bloqueando problemas"
+msgstr "Issues bloqueadas"
msgid "Blocks"
msgstr ""
@@ -5361,7 +5399,7 @@ msgid "Board scope affects which issues are displayed for anyone who visits this
msgstr "O escopo do painel afeta quais issues são exibidas para qualquer um que visite este painel"
msgid "BoardNewIssue|No matching results"
-msgstr ""
+msgstr "Nenhum resultado correspondente"
msgid "BoardNewIssue|Projects"
msgstr "Projetos"
@@ -5370,7 +5408,7 @@ msgid "BoardNewIssue|Search projects"
msgstr "Pesquisar projetos"
msgid "BoardNewIssue|Select a project"
-msgstr ""
+msgstr "Selecione um projeto"
msgid "BoardScope|An error occurred while getting milestones, please try again."
msgstr "Ocorreu um erro ao obter os marcos, por favor, tente novamente."
@@ -5393,9 +5431,6 @@ msgstr "Editar"
msgid "BoardScope|Milestone"
msgstr "Marco"
-msgid "BoardScope|No matching results"
-msgstr "Nenhum resultado correspondente"
-
msgid "BoardScope|No milestone"
msgstr "Nenhum marco"
@@ -5408,22 +5443,28 @@ msgstr "Selecionar responsável"
msgid "BoardScope|Select milestone"
msgstr "Selecionar marco"
-msgid "BoardScope|Started"
+msgid "BoardScope|Select weight"
msgstr ""
+msgid "BoardScope|Started"
+msgstr "Iniciado"
+
msgid "BoardScope|Upcoming"
msgstr "Em breve"
+msgid "BoardScope|Weight"
+msgstr "Peso"
+
msgid "Boards"
msgstr "Painéis"
msgid "Boards and Board Lists"
-msgstr ""
+msgstr "Painéis e listas de painéis"
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
msgid_plural "Boards|+ %{displayedIssuablesCount} more %{issuableType}s"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "+ %{displayedIssuablesCount} mais %{issuableType}"
+msgstr[1] "+ %{displayedIssuablesCount} mais %{issuableType}s"
msgid "Boards|An error occurred while creating the epic. Please try again."
msgstr ""
@@ -5468,16 +5509,13 @@ msgid "Boards|An error occurred while removing the list. Please try again."
msgstr ""
msgid "Boards|An error occurred while updating the board list. Please try again."
-msgstr "Painéis | Ocorreu um erro ao atualizar a lista de painel. Por favor, tente novamente."
+msgstr ""
msgid "Boards|Blocked by %{blockedByCount} %{issuableType}"
msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr "Painel"
-
msgid "Boards|Collapse"
msgstr "Recolher"
@@ -5521,7 +5559,7 @@ msgid "Board|Edit board"
msgstr "Editar painel"
msgid "Board|Enter board name"
-msgstr ""
+msgstr "Digite o nome do painel"
msgid "Board|Failed to delete board. Please try again."
msgstr ""
@@ -5542,13 +5580,13 @@ msgid "Both project and dashboard_path are required"
msgstr ""
msgid "Branch"
-msgstr "Branch"
+msgstr "Ramificação"
msgid "Branch %{branchName} was not found in this project's repository."
msgstr "O branch %{branchName} não foi encontrado no repositório deste projeto."
msgid "Branch %{branch_name} was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}"
-msgstr ""
+msgstr "A ramificação %{branch_name} foi criada. Para configurar implantação automática, escolha um modelo de GitLab CI Yaml e comente suas mudanças. %{link_to_autodeploy_doc}"
msgid "Branch already exists"
msgstr ""
@@ -5560,19 +5598,19 @@ msgid "Branch is already taken"
msgstr "Branch já utilizada"
msgid "Branch name"
-msgstr "Nome da branch"
+msgstr "Nome da ramificação"
msgid "Branch not loaded - %{branchId}"
msgstr "Branch não carregado - %{branchId}"
msgid "Branches"
-msgstr "Branches"
+msgstr "Ramificações"
msgid "Branches|Active"
msgstr "Ativos"
msgid "Branches|Active branches"
-msgstr "Branches ativos"
+msgstr "Ramificações ativas"
msgid "Branches|All"
msgstr "Todos"
@@ -5587,52 +5625,52 @@ msgid "Branches|Compare"
msgstr "Comparar"
msgid "Branches|Delete all branches that are merged into '%{default_branch}'"
-msgstr "Apagar todas as branches que foi feito merge em '%{default_branch}'"
+msgstr "Apagar todos as ramificações que foram mesclados em '%{default_branch}'"
msgid "Branches|Delete branch"
-msgstr "Apagar branch"
+msgstr "Apagar ramificação"
msgid "Branches|Delete branch. Are you ABSOLUTELY SURE?"
msgstr ""
msgid "Branches|Delete merged branches"
-msgstr "Apagar branches que foram feito merge"
+msgstr "Apagar ramificações que foram mescladas"
msgid "Branches|Delete protected branch"
-msgstr "Apagar branch protegida"
+msgstr "Apagar ramificação protegida"
msgid "Branches|Delete protected branch '%{branch_name}'?"
-msgstr "Apagar branch protegida '%{branch_name}'?"
+msgstr "Apagar ramificação protegida '%{branch_name}'?"
msgid "Branches|Delete protected branch. Are you ABSOLUTELY SURE?"
msgstr ""
msgid "Branches|Deleting the %{strongStart}%{branchName}%{strongEnd} branch cannot be undone. Are you sure?"
-msgstr ""
+msgstr "Excluir a ramificação %{strongStart}%{branchName}%{strongEnd} não pode ser desfeito. Você tem certeza?"
msgid "Branches|Deleting the '%{branch_name}' branch cannot be undone. Are you sure?"
-msgstr "Apagar a branch '%{branch_name}' não pode ser desfeito. Você tem certeza?"
+msgstr "Apagar a ramificação '%{branch_name}' não pode ser desfeito. Você tem certeza?"
msgid "Branches|Deleting the merged branches cannot be undone. Are you sure?"
-msgstr "Apagar branches que foram feito merge não pode ser desfeito. Você tem certeza?"
+msgstr "Apagar ramificações mescladas não pode ser desfeita. Você tem certeza?"
msgid "Branches|Filter by branch name"
-msgstr "Filtrar por nome de branch"
+msgstr "Filtrar por nome de ramificação"
msgid "Branches|Merged into %{default_branch}"
-msgstr "Merge feito na branch '%{default_branch}'"
+msgstr "Mesclados para %{default_branch}"
msgid "Branches|New branch"
-msgstr "Nova branch"
+msgstr "Nova ramificação"
msgid "Branches|No branches to show"
-msgstr "Nenhuma branch para mostrar"
+msgstr "Nenhuma ramificação para mostrar"
msgid "Branches|Once you confirm and press %{delete_protected_branch}, it cannot be undone or recovered."
msgstr "Uma vez que você confirmar e pressionar %{delete_protected_branch}, não pode ser desfeito ou recuperado."
msgid "Branches|Once you confirm and press %{strongStart}%{buttonText},%{strongEnd} it cannot be undone or recovered."
-msgstr ""
+msgstr "Uma vez que você confirmar e pressionar %{strongStart}%{buttonText},%{strongEnd} isso não poderá ser desfeito ou recuperado."
msgid "Branches|Only a project maintainer or owner can delete a protected branch"
msgstr "Somente um mantenedor ou dono do projeto poderá apagar branches protegidas"
@@ -5668,19 +5706,19 @@ msgid "Branches|Stale"
msgstr "Obsoleto"
msgid "Branches|Stale branches"
-msgstr "Branches obsoletos"
+msgstr "Ramificações obsoletas"
msgid "Branches|The branch could not be updated automatically because it has diverged from its upstream counterpart."
msgstr "O brach não pôde ser atualizado automaticamente porque ele divergiu de sua contraparte upstream."
msgid "Branches|The default branch cannot be deleted"
-msgstr "A branch padrão não pode ser apagada"
+msgstr "A ramificação padrão não pode ser apagada"
msgid "Branches|This branch hasn’t been merged into %{defaultBranchName}. To avoid data loss, consider merging this branch before deleting it."
-msgstr ""
+msgstr "Essa ramificação não foi mesclado para %{defaultBranchName}. Para evitar perca de dados, considere fazer o merge dessa ramificação antes de deletá-lo."
msgid "Branches|This branch hasn’t been merged into %{default_branch}."
-msgstr "Essa branch não teve o merge realizado na '%{default_branch}'."
+msgstr "Essa ramificação não foi mesclado para '%{default_branch}'."
msgid "Branches|To avoid data loss, consider merging this branch before deleting it."
msgstr "Para evitar perda de dados, considere fazer um merge dessa branch antes de apagá-la."
@@ -5698,10 +5736,10 @@ msgid "Branches|Yes, delete protected branch"
msgstr "Sim, apagar o branch protegido"
msgid "Branches|You're about to permanently delete the branch %{strongStart}%{branchName}.%{strongEnd}"
-msgstr ""
+msgstr "Você está prestes a excluir permanentemente a ramificação %{strongStart}%{branchName}.%{strongEnd}"
msgid "Branches|You're about to permanently delete the protected branch %{strongStart}%{branchName}.%{strongEnd}"
-msgstr ""
+msgstr "Você está prestes a excluir permanentemente a ramificação protegida %{strongStart}%{branchName}.%{strongEnd}"
msgid "Branches|You’re about to permanently delete the protected branch %{branch_name}."
msgstr "Você irá apagar irreparavelmente a branch protegida '%{branch_name}'."
@@ -5710,7 +5748,7 @@ msgid "Branches|diverged from upstream"
msgstr "divergido do upstream"
msgid "Branches|merged"
-msgstr "merge realizado"
+msgstr "mesclado"
msgid "Branches|project settings"
msgstr "configurações do projeto"
@@ -5778,30 +5816,24 @@ msgstr "Filtrar por grupo de fonte"
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr "Importar %{groups}"
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
+msgid "BulkImport|Import selected"
+msgstr "Importar selecionado"
+
msgid "BulkImport|Importing the group failed"
msgstr ""
msgid "BulkImport|Name already exists."
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
-msgstr ""
-
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5812,7 +5844,7 @@ msgid "BulkImport|Showing %{start}-%{end} of %{total} matching filter \"%{filter
msgstr ""
msgid "BulkImport|To new group"
-msgstr ""
+msgstr "Para um novo grupo"
msgid "BulkImport|Update of import statuses with realtime changes failed"
msgstr ""
@@ -5836,7 +5868,7 @@ msgid "BurndownChartLabel|Open issue weight"
msgstr ""
msgid "BurndownChartLabel|Open issues"
-msgstr "Abrir issues"
+msgstr "Issues abertas"
msgid "Burnup chart"
msgstr "Gráfico de burnup"
@@ -5854,7 +5886,10 @@ msgid "Busy"
msgstr "Ocupado"
msgid "Buy CI Minutes"
-msgstr ""
+msgstr "Comprar minutos de CI"
+
+msgid "Buy Storage"
+msgstr "Comprar armazenamento"
msgid "Buy more Pipeline minutes"
msgstr "Compre mais minutos de pipeline"
@@ -5863,7 +5898,7 @@ msgid "By %{user_name}"
msgstr "Por %{user_name}"
msgid "By authenticating with an account tied to an Enterprise e-mail address, it is understood that this account is an Enterprise User. "
-msgstr ""
+msgstr "Ao autenticar com uma conta vinculada a um endereço de e-mail corporativo, entende-se que essa conta é um usuário corporativo (Enterprise). "
msgid "By default, all projects and groups will use the global notifications setting."
msgstr "Por padrão, todos os projetos e grupos usarão as configurações de notificações globais."
@@ -5878,10 +5913,10 @@ msgid "CI Lint"
msgstr "Checar syntaxe de CI"
msgid "CI configuration validated, including all configuration added with the %{codeStart}includes%{codeEnd} keyword. %{link}"
-msgstr ""
+msgstr "Configuração de CI validada, incluindo todas as configurações adicionadas com a palavra-chave %{codeStart}includes%{codeEnd}. %{link}"
msgid "CI minutes"
-msgstr ""
+msgstr "Minutos de CI"
msgid "CI settings"
msgstr "Configurações de CI"
@@ -5905,7 +5940,7 @@ msgid "CI/CD configuration"
msgstr "Configuração de CI/CD"
msgid "CI/CD configuration file"
-msgstr ""
+msgstr "Arquivo de configuração de CI/CD"
msgid "CI/CD|No projects have been added to the scope"
msgstr ""
@@ -5917,7 +5952,7 @@ msgid "CICDAnalytics|All time"
msgstr ""
msgid "CICDAnalytics|Deployment frequency"
-msgstr "Frequência de deployment"
+msgstr "Frequência de implantação"
msgid "CICDAnalytics|Lead time"
msgstr ""
@@ -5967,7 +6002,7 @@ msgid "CICD|Default to Auto DevOps pipeline for all projects"
msgstr "Padrão para pipeline de Auto DevOps para todos os projetos"
msgid "CICD|Deployment strategy"
-msgstr "Estratégia de deploy"
+msgstr "Estratégia de implantação"
msgid "CICD|Jobs"
msgstr "Tarefas"
@@ -5982,7 +6017,7 @@ msgid "CICD|The Auto DevOps pipeline runs by default in all projects with no CI/
msgstr ""
msgid "CICD|The Auto DevOps pipeline runs if no alternative CI configuration file is found."
-msgstr ""
+msgstr "O pipeline de Auto DevOps será executado se nenhum arquivo de configuração de CI alternativo for encontrado."
msgid "CICD|group enabled"
msgstr "grupo habilitado"
@@ -6005,6 +6040,9 @@ msgstr "CONTRIBUINDO"
msgid "CPU"
msgstr "CPU"
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6018,10 +6056,10 @@ msgid "CVE|Create CVE ID Request"
msgstr ""
msgid "CVE|Enable CVE ID requests in the issue sidebar"
-msgstr ""
+msgstr "Ativar requisições de CVE ID na barra lateral de issue"
msgid "CVE|Request CVE ID"
-msgstr ""
+msgstr "Solicitar ID de CVE"
msgid "CVE|Why Request a CVE ID?"
msgstr ""
@@ -6054,7 +6092,7 @@ msgid "CampfireService|The %{code_open}.campfirenow.com%{code_close} subdomain."
msgstr ""
msgid "Can be manually deployed to"
-msgstr "Pode fazer deploy manualmente para"
+msgstr "Pode ser implantado manualmente para"
msgid "Can create groups:"
msgstr "Pode criar grupos:"
@@ -6105,10 +6143,10 @@ msgid "Canary weight must be specified and valid range (0..100)."
msgstr ""
msgid "CanaryIngress|%{boldStart}Canary:%{boldEnd} %{canary}"
-msgstr ""
+msgstr "%{boldStart}Canary:%{boldEnd} %{canary}"
msgid "CanaryIngress|%{boldStart}Stable:%{boldEnd} %{stable}"
-msgstr ""
+msgstr "%{boldStart}Stable:%{boldEnd} %{stable}"
msgid "CanaryIngress|Canary"
msgstr "Canary"
@@ -6150,7 +6188,7 @@ msgid "Cancel, keep project"
msgstr "Cancelar, manter projeto"
msgid "Canceled deployment to"
-msgstr "Deployment cancelado para"
+msgstr "Implantação cancelada para"
msgid "Cancelled"
msgstr "Cancelado"
@@ -6162,7 +6200,7 @@ msgid "Cannot be assigned to other projects."
msgstr "Não pode ser atribuído a outros projetos."
msgid "Cannot be merged automatically"
-msgstr "Não pode ser feito o merge automaticamente"
+msgstr "Não pode ser mesclado automaticamente"
msgid "Cannot create the abuse report. The user has been deleted."
msgstr "Não é possível criar o relatório de abuso. O usuário foi excluído."
@@ -6189,7 +6227,7 @@ msgid "Cannot make the epic confidential if it contains non-confidential issues"
msgstr ""
msgid "Cannot merge"
-msgstr "Não é possível fazer merge"
+msgstr "Não é possível mesclar"
msgid "Cannot modify %{profile_name} referenced in security policy"
msgstr ""
@@ -6288,7 +6326,7 @@ msgid "Change reviewer(s)."
msgstr "Alterar revisor(es)"
msgid "Change role"
-msgstr ""
+msgstr "Alterar cargo"
msgid "Change status"
msgstr "Alterar status"
@@ -6345,7 +6383,7 @@ msgid "ChangeTypeAction|Start a %{newMergeRequest} with these changes"
msgstr ""
msgid "ChangeTypeAction|Switch branch"
-msgstr ""
+msgstr "Trocar branch"
msgid "ChangeTypeAction|Switch project"
msgstr "Alternar projeto"
@@ -6444,7 +6482,7 @@ msgid "Check again"
msgstr "Verifique Novamente"
msgid "Check feature availability on namespace plan"
-msgstr "Verificar disponibilidade de funcionalidades no plano de namespace"
+msgstr "Verificar disponibilidade de funcionalidades no plano de espaço de nome"
msgid "Check out, review, and merge locally"
msgstr ""
@@ -6459,7 +6497,7 @@ msgid "Check the elasticsearch.log file to debug why the migration was halted an
msgstr ""
msgid "Check your Docker images for known vulnerabilities."
-msgstr ""
+msgstr "Verifique suas imagens do Docker quanto a vulnerabilidades conhecidas."
msgid "Check your Kubernetes cluster images for known vulnerabilities."
msgstr ""
@@ -6488,32 +6526,39 @@ msgstr "Verificando disponibilidade do nome de usuário..."
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
-msgstr "$%{selectedPlanPrice} por pacote por ano"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
+msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
-msgstr ""
+msgstr "$%{selectedPlanPrice} por usuário e ano"
+
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] "Pacote de %d minutos de CI"
+msgstr[1] "Pacotes de %d minutos de CI"
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
-msgstr ""
+msgstr "%{cardType} terminando em %{lastFourDigits}"
msgid "Checkout|%{name}'s CI minutes"
-msgstr ""
+msgstr "Minutos de CI de%{name}"
msgid "Checkout|%{name}'s GitLab subscription"
-msgstr ""
-
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
+msgstr "Assinatura do GitLab de %{name}"
msgid "Checkout|%{selectedPlanText} plan"
msgstr "plano %{selectedPlanText}"
msgid "Checkout|%{startDate} - %{endDate}"
-msgstr ""
+msgstr "%{startDate} - %{endDate}"
+
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] "%{totalCiMinutes} minuto de CI"
+msgstr[1] "%{totalCiMinutes} minutos de CI"
msgid "Checkout|%{totalCiMinutes} CI minutes"
-msgstr ""
+msgstr "%{totalCiMinutes} minutos de CI"
msgid "Checkout|(may be %{linkStart}charged upon purchase%{linkEnd})"
msgstr ""
@@ -6527,14 +6572,14 @@ msgstr "(x%{quantity})"
msgid "Checkout|Billing address"
msgstr "Endereço de cobrança"
-msgid "Checkout|CI minute packs"
-msgstr ""
+msgid "Checkout|CI minute pack"
+msgstr "Pacote de minutos de CI"
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
msgstr ""
msgid "Checkout|Checkout"
-msgstr ""
+msgstr "Checkout"
msgid "Checkout|City"
msgstr "Cidade"
@@ -6579,7 +6624,7 @@ msgid "Checkout|Failed to load countries. Please try again."
msgstr ""
msgid "Checkout|Failed to load states. Please try again."
-msgstr ""
+msgstr "Falha ao carregar estados. Por favor, tente novamente."
msgid "Checkout|Failed to load the payment form. Please try again."
msgstr ""
@@ -6597,7 +6642,7 @@ msgid "Checkout|Group"
msgstr "Grupo"
msgid "Checkout|Name of company or organization using GitLab"
-msgstr ""
+msgstr "Nome da empresa ou organização usando GitLab"
msgid "Checkout|Need more users? Purchase GitLab for your %{company}."
msgstr ""
@@ -6663,7 +6708,7 @@ msgid "Checkout|company or team"
msgstr "empresa ou equipe"
msgid "Checkout|x 1,000 minutes per pack = %{strong}"
-msgstr ""
+msgstr "1.000 minuto por pacote = %{strong}"
msgid "Cherry-pick this commit"
msgstr "Cherry-pick esse commit"
@@ -6735,7 +6780,7 @@ msgid "Choose what content you want to see on a group’s overview page."
msgstr "Escolha o conteúdo que você deseja ver na página de visão geral de um grupo."
msgid "Choose which Git strategy to use when fetching the project."
-msgstr ""
+msgstr "Escolha qual estratégia de Git usar ao buscar o projeto."
msgid "Choose which repositories you want to connect and run CI/CD pipelines."
msgstr "Escolha quais repositórios você deseja se conectar e executar pipelines de CI/CD."
@@ -6744,7 +6789,7 @@ msgid "Choose your framework"
msgstr "Escolha seu framework"
msgid "CiCdAnalytics|Date range: %{range}"
-msgstr ""
+msgstr "Intervalo de datas: %{range}"
msgid "CiStatusLabel|canceled"
msgstr "cancelado"
@@ -6903,7 +6948,7 @@ msgid "Clean up after running %{link_start}git filter-repo%{link_end} on the rep
msgstr ""
msgid "Clean up image tags"
-msgstr "Limpar as marcações de imagem"
+msgstr "Limpar as tags de imagem"
msgid "Cleanup policies are executed by background workers. This setting defines the maximum number of workers that can run concurrently. Set it to 0 to remove all workers and not execute the cleanup policies."
msgstr ""
@@ -6927,7 +6972,7 @@ msgid "Clear chart filters"
msgstr "Limpar filtros do gráfico"
msgid "Clear due date"
-msgstr "Limpar data limite"
+msgstr "Limpar validade"
msgid "Clear recent searches"
msgstr "Limpar pesquisas recentes"
@@ -7020,10 +7065,10 @@ msgid "CloneIssue|Cannot clone issue to target project as it is pending deletion
msgstr ""
msgid "Cloned this issue to %{path_to_project}."
-msgstr ""
+msgstr "Clonou esta issue para %{path_to_project}."
msgid "Clones this issue, without comments, to %{project}."
-msgstr ""
+msgstr "Clone essa issue, sem comentários, para %{project}."
msgid "Close"
msgstr "Fechar"
@@ -7056,13 +7101,13 @@ msgid "Closed %{epicTimeagoDate}"
msgstr "Fechado %{epicTimeagoDate}"
msgid "Closed MRs"
-msgstr ""
+msgstr "MRs fechados"
msgid "Closed epics"
msgstr "Épicos fechados"
msgid "Closed issues"
-msgstr "Issues Fechadas"
+msgstr "Issues fechadas"
msgid "Closed this %{quick_action_target}."
msgstr "Fechado este %{quick_action_target}."
@@ -7074,7 +7119,7 @@ msgid "Closes this %{quick_action_target}."
msgstr "Fecha este %{quick_action_target}."
msgid "Cloud licenses can not be removed."
-msgstr ""
+msgstr "Licenças em nuvem não podem ser removidas."
msgid "Cluster"
msgstr "Cluster"
@@ -7083,10 +7128,10 @@ msgid "Cluster Health"
msgstr "Saúde do cluster"
msgid "Cluster cache cleared."
-msgstr ""
+msgstr "Cache do cluster limpo."
msgid "Cluster does not exist"
-msgstr ""
+msgstr "Cluster não existe"
msgid "Cluster is required for Stages::ClusterEndpointInserter"
msgstr ""
@@ -7098,22 +7143,22 @@ msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|Access tokens"
-msgstr ""
+msgstr "Tokens de acesso"
msgid "ClusterAgents|Alternative installation methods"
msgstr "Métodos de instalação alternativos"
msgid "ClusterAgents|An error occurred while loading your GitLab Agents"
-msgstr ""
+msgstr "Ocorreu um erro ao carregar seu GitLab Agents"
msgid "ClusterAgents|An error occurred while loading your agent"
-msgstr ""
+msgstr "Ocorreu um erro ao carregar seu agente."
msgid "ClusterAgents|An unknown error occurred. Please try again."
msgstr "Ocorreu um erro desconhecido. Por favor, tente novamente."
msgid "ClusterAgents|Configuration"
-msgstr ""
+msgstr "Configuração"
msgid "ClusterAgents|Copy token"
msgstr "Copiar token"
@@ -7125,7 +7170,7 @@ msgid "ClusterAgents|Created by %{name} %{time}"
msgstr "Criado por %{name} %{time}"
msgid "ClusterAgents|Date created"
-msgstr ""
+msgstr "Data de criação"
msgid "ClusterAgents|Description"
msgstr "Descrição"
@@ -7134,25 +7179,25 @@ msgid "ClusterAgents|For alternative installation methods %{linkStart}go to the
msgstr ""
msgid "ClusterAgents|Go to the repository"
-msgstr ""
+msgstr "Ir para o repositório"
+
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr "Instale um novo agente do GitLab"
msgid "ClusterAgents|Install new Agent"
-msgstr ""
+msgstr "Instalar novo agente."
msgid "ClusterAgents|Integrate Kubernetes with a GitLab Agent"
-msgstr ""
+msgstr "Integrar Kubernetes com um GitLab Agent"
msgid "ClusterAgents|Integrate with the GitLab Agent"
-msgstr ""
+msgstr "Integrar com o GitLab Agent"
msgid "ClusterAgents|Last used"
-msgstr ""
+msgstr "Último uso"
msgid "ClusterAgents|Learn how to create an agent access token"
-msgstr ""
-
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
+msgstr "Aprenda a criar um token de acesso do agente"
msgid "ClusterAgents|Name"
msgstr "Nome"
@@ -7161,31 +7206,31 @@ msgid "ClusterAgents|Never"
msgstr "Nunca"
msgid "ClusterAgents|Read more about getting started"
-msgstr ""
+msgstr "Leia mais sobre como começar"
msgid "ClusterAgents|Recommended installation method"
-msgstr ""
+msgstr "Método de instalação recomendado"
msgid "ClusterAgents|Registering Agent"
-msgstr ""
+msgstr "Registrando o agente"
msgid "ClusterAgents|Registration token"
-msgstr ""
+msgstr "Token de registro"
msgid "ClusterAgents|Select an Agent"
-msgstr ""
+msgstr "Selecione um agente"
msgid "ClusterAgents|Select the Agent you want to register with GitLab and install on your cluster. To learn more about the Kubernetes Agent registration process %{linkStart}go to the documentation%{linkEnd}."
-msgstr ""
+msgstr "Selecione o agente que deseja registrar com o GitLab e instale em seu cluster. Para saber mais sobre o processo de registro do agente do Kubernetes %{linkStart}siga para a documentação%{linkEnd}."
msgid "ClusterAgents|Select which Agent you want to install"
-msgstr ""
+msgstr "Selecione o agente que deseja instalar"
msgid "ClusterAgents|The GitLab Agent also requires %{linkStart}enabling the Agent Server%{linkEnd}"
-msgstr ""
+msgstr "O agente do GitLab também requer %{linkStart}a ativação do servidor do agente%{linkEnd}"
msgid "ClusterAgents|The GitLab Kubernetes Agent allows an Infrastructure as Code, GitOps approach to integrating Kubernetes clusters with GitLab. %{linkStart}Learn more.%{linkEnd}"
-msgstr ""
+msgstr "O agente Kubernetes do GitLab permite abordagens GitOps de infraestrutura como código para integração de clusters Kubernetes com o GitLab. %{linkStart}Saiba mais.%{linkEnd}"
msgid "ClusterAgents|The recommended installation method provided below includes the token. If you want to follow the alternative installation method provided in the docs make sure you save the token value before you close the window."
msgstr ""
@@ -7194,19 +7239,19 @@ msgid "ClusterAgents|The registration token will be used to connect the Agent on
msgstr ""
msgid "ClusterAgents|The token value will not be shown again after you close this window."
-msgstr ""
+msgstr "O valor do token não será mostrado novamente após fechar esta janela."
msgid "ClusterAgents|This agent has no tokens"
-msgstr ""
+msgstr "Este agente não tem tokens"
msgid "ClusterAgents|To install an Agent you should create an agent directory in the Repository first. We recommend that you add the Agent configuration to the directory before you start the installation process."
-msgstr ""
+msgstr "Para instalar um agente, você deve criar primeiro um diretório de agente no repositório. Recomendamos adicionar a configuração do agente ao diretório antes de iniciar o processo de instalação."
msgid "ClusterAgents|Unknown user"
msgstr "Usuário desconhecido"
msgid "ClusterAgents|You will need to create a token to connect to your agent"
-msgstr ""
+msgstr "Você precisará criar um token para conectar ao seu agente"
msgid "ClusterAgent|This feature is only available for premium plans"
msgstr ""
@@ -7257,13 +7302,13 @@ msgid "ClusterIntegration|Adding an integration will share the cluster across al
msgstr "A adição de uma integração irá compartilhar o cluster entre todos os projetos."
msgid "ClusterIntegration|Advanced options on this Kubernetes cluster’s integration"
-msgstr ""
+msgstr "Opções avançadas na integração deste cluster Kubernetes"
msgid "ClusterIntegration|Allow GitLab to manage namespace and service accounts for this cluster. %{linkStart}More information%{linkEnd}"
msgstr ""
msgid "ClusterIntegration|Allow GitLab to manage namespaces and service accounts for this cluster."
-msgstr ""
+msgstr "Permitir ao GitLab gerenciar espaços de nome e contas de serviço para este cluster."
msgid "ClusterIntegration|Allows GitLab to query a specifically configured in-cluster Elasticsearch for pod logs."
msgstr ""
@@ -7299,7 +7344,7 @@ msgid "ClusterIntegration|Authenticate with AWS"
msgstr "Autenticar com o AWS"
msgid "ClusterIntegration|Authenticate with Amazon Web Services"
-msgstr ""
+msgstr "Autenticar com o Amazon Web Services"
msgid "ClusterIntegration|Authentication Error"
msgstr "Erro de autenticação"
@@ -7335,16 +7380,16 @@ msgid "ClusterIntegration|Choose which of your environments will use this cluste
msgstr "Escolha quais dos seus ambientes usarão esse cluster."
msgid "ClusterIntegration|Clear cluster cache"
-msgstr ""
+msgstr "Limpar cluster de cache"
msgid "ClusterIntegration|Clear the local cache of namespace and service accounts."
msgstr ""
msgid "ClusterIntegration|Cluster Region"
-msgstr ""
+msgstr "Região de cluster"
msgid "ClusterIntegration|Cluster management project"
-msgstr ""
+msgstr "Projeto de gerenciamento de cluster"
msgid "ClusterIntegration|Cluster name is required."
msgstr "O nome do cluster é obrigatório."
@@ -7359,7 +7404,7 @@ msgid "ClusterIntegration|Connect cluster with certificate"
msgstr ""
msgid "ClusterIntegration|Connect existing cluster"
-msgstr ""
+msgstr "Conectar um cluster existente"
msgid "ClusterIntegration|Connection Error"
msgstr "Erro de conexão"
@@ -7377,19 +7422,19 @@ msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
msgid "ClusterIntegration|Could not load Key Pairs"
-msgstr ""
+msgstr "Não foi possível carregar as pares de chaves"
msgid "ClusterIntegration|Could not load VPCs for the selected region"
-msgstr ""
+msgstr "Não foi possível carregar os VPCs para a região selecionada"
msgid "ClusterIntegration|Could not load instance types"
-msgstr ""
+msgstr "Não foi possível carregar os tipos de instância"
msgid "ClusterIntegration|Could not load networks"
-msgstr ""
+msgstr "Não foi possível carregar as redes"
msgid "ClusterIntegration|Could not load security groups for the selected VPC"
-msgstr ""
+msgstr "Não foi possível carregar grupos de segurança para o VPC selecionado"
msgid "ClusterIntegration|Could not load subnets for the selected VPC"
msgstr ""
@@ -7413,10 +7458,10 @@ msgid "ClusterIntegration|Create new cluster on EKS"
msgstr "Criar um novo cluster no EKS"
msgid "ClusterIntegration|Create new cluster on GKE"
-msgstr ""
+msgstr "Criar novo cluster no GKE"
msgid "ClusterIntegration|Creating Kubernetes cluster"
-msgstr ""
+msgstr "Criando cluster de Kubernetes"
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
msgstr ""
@@ -7434,13 +7479,13 @@ msgid "ClusterIntegration|Elastic Kubernetes Service"
msgstr "Elastic Kubernetes Service"
msgid "ClusterIntegration|Enable Cloud Run for Anthos"
-msgstr ""
+msgstr "Ativar Cloud Run para Anthos"
msgid "ClusterIntegration|Enable Elastic Stack integration"
-msgstr ""
+msgstr "Ativar integração do Elastic Stack"
msgid "ClusterIntegration|Enable Prometheus integration"
-msgstr ""
+msgstr "Ativar integração do Prometheus"
msgid "ClusterIntegration|Enable or disable GitLab's connection to your Kubernetes cluster."
msgstr "Ative ou desative conexão do GitLab com seu cluster Kubernetes."
@@ -7452,7 +7497,7 @@ msgid "ClusterIntegration|Enter new Service Token"
msgstr ""
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
-msgstr ""
+msgstr "Digite detalhes para seu cluster Amazon EKS Kubernetes"
msgid "ClusterIntegration|Enter the details for your Kubernetes cluster"
msgstr "Digite detalhes para seu cluster Kubernetes"
@@ -7461,16 +7506,16 @@ msgid "ClusterIntegration|Environment scope"
msgstr "Escopo de ambiente"
msgid "ClusterIntegration|Environment scope is required."
-msgstr ""
+msgstr "Escopo de ambiente é necessário."
msgid "ClusterIntegration|Every new Google Cloud Platform (GCP) account receives $300 in credit upon %{sign_up_link}. In partnership with Google, GitLab is able to offer an additional $200 for both new and existing GCP accounts to get started with GitLab's Google Kubernetes Engine Integration."
msgstr "Cada nova conta no Google Cloud Plataform (GCP) recebe US$300 em créditos por se %{sign_up_link}. Em parceria com o Google, o GitLab pode oferecer um adicional de US$200 para novas contas do GCP para começar a usar a integração GKE do GitLab."
msgid "ClusterIntegration|Failed to configure EKS provider: %{message}"
-msgstr ""
+msgstr "Falha ao configurar o provedor EKS: %{message}"
msgid "ClusterIntegration|Failed to configure Google Kubernetes Engine Cluster: %{message}"
-msgstr ""
+msgstr "Falha ao configurar o Google Kubernetes Engine Cluster: %{message}"
msgid "ClusterIntegration|Failed to fetch CloudFormation stack: %{message}"
msgstr ""
@@ -7479,7 +7524,7 @@ msgid "ClusterIntegration|Failed to request to Google Cloud Platform: %{message}
msgstr "Falha ao requisitar ao Google Cloud Platform: %{message}"
msgid "ClusterIntegration|Failed to run Kubeclient: %{message}"
-msgstr ""
+msgstr "Falha ao executar Kubeclient: %{message}"
msgid "ClusterIntegration|Fetching machine types"
msgstr "Recuperando tipos de máquina"
@@ -7491,16 +7536,16 @@ msgid "ClusterIntegration|Fetching zones"
msgstr "Recuperando zonas"
msgid "ClusterIntegration|GitLab Agent managed clusters"
-msgstr ""
+msgstr "Clusters administrados por um agente do GitLab"
msgid "ClusterIntegration|GitLab Integration"
msgstr "Integração GitLab"
msgid "ClusterIntegration|GitLab failed to authenticate."
-msgstr ""
+msgstr "Falha na autenticação do GitLab."
msgid "ClusterIntegration|GitLab failed to connect to the cluster."
-msgstr ""
+msgstr "Falha ao conectar GitLab ao cluster."
msgid "ClusterIntegration|GitLab-managed cluster"
msgstr "Cluster gerenciado pelo GitLab"
@@ -7527,7 +7572,7 @@ msgid "ClusterIntegration|If you are setting up multiple clusters and are using
msgstr "Se você está configurando múltiplos clusters e você está usando auto DevOps, %{help_link_start}leia isso primeiro%{help_link_end}."
msgid "ClusterIntegration|If you do not wish to delete all associated GitLab resources, you can simply remove the integration."
-msgstr ""
+msgstr "Se você não deseja excluir todos os recursos do GitLab associados, pode simplesmente remover a integração."
msgid "ClusterIntegration|In order to view the health of your cluster, you must first enable Prometheus in the Integrations tab."
msgstr ""
@@ -7539,10 +7584,10 @@ msgid "ClusterIntegration|Instance type"
msgstr "Tipo de instância"
msgid "ClusterIntegration|Integrate Kubernetes with a cluster certificate"
-msgstr ""
+msgstr "Integrar Kubernetes com uma certificação de cluster"
msgid "ClusterIntegration|Integrate with a cluster certificate"
-msgstr ""
+msgstr "Integrar com uma certificação de cluster"
msgid "ClusterIntegration|Integration disabled"
msgstr "Integração desativada"
@@ -7572,7 +7617,7 @@ msgid "ClusterIntegration|Kubernetes version"
msgstr "Versão do Kubernetes"
msgid "ClusterIntegration|Kubernetes version not found"
-msgstr ""
+msgstr "Versão do Kubernetes não encontrada"
msgid "ClusterIntegration|Learn more about %{help_link_start_machine_type}machine types%{help_link_end} and %{help_link_start_pricing}pricing%{help_link_end}."
msgstr "Saiba mais sobre os %{help_link_start_machine_type}tipos de máquinas%{help_link_end} e seus %{help_link_start_pricing}preços%{help_link_end}."
@@ -7590,7 +7635,7 @@ msgid "ClusterIntegration|Learn more about instance Kubernetes clusters"
msgstr "Saiba mais sobre instância de cluster Kubernetes"
msgid "ClusterIntegration|Loading IAM Roles"
-msgstr ""
+msgstr "Carregando funções do IAM"
msgid "ClusterIntegration|Loading Key Pairs"
msgstr "Carregando pares de chaves"
@@ -7599,19 +7644,19 @@ msgid "ClusterIntegration|Loading VPCs"
msgstr "Carregando VPCs"
msgid "ClusterIntegration|Loading instance types"
-msgstr ""
+msgstr "Carregando tipos de instância"
msgid "ClusterIntegration|Loading networks"
msgstr "Carregando redes"
msgid "ClusterIntegration|Loading security groups"
-msgstr ""
+msgstr "Carregando grupos de segurança"
msgid "ClusterIntegration|Loading subnets"
msgstr "Carregando sub-redes"
msgid "ClusterIntegration|Loading subnetworks"
-msgstr ""
+msgstr "Carregando sub-redes"
msgid "ClusterIntegration|Machine type"
msgstr "Tipo de máquina"
@@ -7623,13 +7668,13 @@ msgid "ClusterIntegration|Make sure your account %{link_to_requirements} to crea
msgstr "Tenha certeza de que sua conta %{link_to_requirements} para criar clusters Kubernetes"
msgid "ClusterIntegration|Manage your Kubernetes cluster by visiting %{provider_link}"
-msgstr ""
+msgstr "Gerencie seu cluster Kubernetes visitando %{provider_link}"
msgid "ClusterIntegration|Namespace per environment"
-msgstr ""
+msgstr "Espaço de nome por ambiente"
msgid "ClusterIntegration|No IAM Roles found"
-msgstr ""
+msgstr "Nenhuma função do IAM encontrada"
msgid "ClusterIntegration|No Key Pairs found"
msgstr "Nenhum par de chaves encontrado"
@@ -7683,25 +7728,25 @@ msgid "ClusterIntegration|Project cluster"
msgstr "Cluster do Projeto"
msgid "ClusterIntegration|Project namespace (optional, unique)"
-msgstr "Namespace do projeto (opcional, único)"
+msgstr "Espaço de nome do projeto (opcional, único)"
msgid "ClusterIntegration|Project namespace prefix (optional, unique)"
-msgstr "Prefixo do namespace do projeto (opcional, único)"
+msgstr "Prefixo do espaço de nome do projeto (opcional, único)"
msgid "ClusterIntegration|Provider details"
msgstr "Detalhes do provedor"
msgid "ClusterIntegration|Provision Role ARN"
-msgstr ""
+msgstr "ARN de função de provisão"
msgid "ClusterIntegration|RBAC-enabled cluster"
msgstr "Cluster habilitado para RBAC"
msgid "ClusterIntegration|Read our %{linkStart}help page%{linkEnd} on Kubernetes cluster integration."
-msgstr ""
+msgstr "Leia nossa %{linkStart}página de ajuda%{linkEnd} sobre integração de cluster do Kubernetes."
msgid "ClusterIntegration|Read our %{link_start}help page%{link_end} on Kubernetes cluster integration."
-msgstr ""
+msgstr "Leia nossa %{link_start}página de ajuda%{link_end} sobre integração de cluster do Kubernetes."
msgid "ClusterIntegration|Remove Kubernetes cluster integration"
msgstr "Remover integração com o cluster Kubernetes"
@@ -7710,10 +7755,10 @@ msgid "ClusterIntegration|Remove integration"
msgstr "Remover integração"
msgid "ClusterIntegration|Remove integration and resources"
-msgstr ""
+msgstr "Remover integração e recursos"
msgid "ClusterIntegration|Remove integration and resources?"
-msgstr ""
+msgstr "Remover integração e recursos?"
msgid "ClusterIntegration|Remove integration?"
msgstr "Remover integração?"
@@ -7722,7 +7767,7 @@ msgid "ClusterIntegration|Remove this Kubernetes cluster's configuration from th
msgstr "Remover configuração desse cluster Kubernetes para esse projeto. Isso não apagará seu cluster Kubernetes atual."
msgid "ClusterIntegration|Removes cluster from project but keeps associated resources"
-msgstr ""
+msgstr "Remove o cluster do projeto, mas mantém recursos associados"
msgid "ClusterIntegration|Save changes"
msgstr "Salvar alterações"
@@ -7767,25 +7812,25 @@ msgid "ClusterIntegration|See and edit the details for your Kubernetes cluster"
msgstr "Veja e edite os detalhes de seus cluster Kubernetes"
msgid "ClusterIntegration|Select a VPC to choose a security group"
-msgstr ""
+msgstr "Selecione um VPC para escolher um grupo de segurança"
msgid "ClusterIntegration|Select a VPC to choose a subnet"
-msgstr ""
+msgstr "Selecione um VPC para escolher uma sub-rede"
msgid "ClusterIntegration|Select a VPC to use for your EKS Cluster resources. To use a new VPC, first create one on %{linkStart}Amazon Web Services %{linkEnd}."
msgstr ""
msgid "ClusterIntegration|Select a network to choose a subnetwork"
-msgstr ""
+msgstr "Selecione uma rede para escolher uma sub-rede"
msgid "ClusterIntegration|Select a region to choose a Key Pair"
-msgstr ""
+msgstr "Selecione uma região para escolher um par de chaves"
msgid "ClusterIntegration|Select a region to choose a VPC"
-msgstr ""
+msgstr "Selecione uma região para escolher um VPC"
msgid "ClusterIntegration|Select a zone to choose a network"
-msgstr ""
+msgstr "Selecione uma zona para escolher uma rede"
msgid "ClusterIntegration|Select machine type"
msgstr "Selecionar tipo de máquina"
@@ -7827,7 +7872,7 @@ msgid "ClusterIntegration|Something went wrong on our end."
msgstr "Alguma coisa deu errado do nosso lado."
msgid "ClusterIntegration|Something went wrong while creating your Kubernetes cluster"
-msgstr ""
+msgstr "Algo deu errado ao criar seu cluster do Kubernetes"
msgid "ClusterIntegration|Specifying a domain will allow you to use Auto Review Apps and Auto Deploy stages for %{linkStart}Auto DevOps.%{linkEnd} The domain should have a wildcard DNS configured matching the domain. "
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr "Sub-redes"
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -7851,10 +7896,10 @@ msgid "ClusterIntegration|The region the new cluster will be created in. You mus
msgstr ""
msgid "ClusterIntegration|There was a problem authenticating with your cluster. Please ensure your CA Certificate and Token are valid."
-msgstr ""
+msgstr "Houve um problema ao autenticar com seu cluster. Por favor, assegure-se de que seu Certificado da CA e o Token sejam válidos."
msgid "ClusterIntegration|There was an HTTP error when connecting to your cluster."
-msgstr ""
+msgstr "Ocorreu um erro de HTTP ao se conectar ao seu cluster."
msgid "ClusterIntegration|This account must have permissions to create a Kubernetes cluster in the %{link_to_container_project} specified below"
msgstr "Essa conta precisa de permissões para criar um cluster Kubernetes no %{link_to_container_project} especificado"
@@ -7872,16 +7917,16 @@ msgid "ClusterIntegration|This project does not have billing enabled. To create
msgstr ""
msgid "ClusterIntegration|This will permanently delete the following resources:"
-msgstr ""
+msgstr "Isso apagará permanentemente os seguintes recursos:"
msgid "ClusterIntegration|To create a cluster, first create a project on %{docsLinkStart}Google Cloud Platform%{docsLinkEnd}."
msgstr ""
msgid "ClusterIntegration|To remove your integration and resources, type %{clusterName} to confirm:"
-msgstr ""
+msgstr "Para remover sua integração e recursos, digite %{clusterName} para confirmar:"
msgid "ClusterIntegration|To remove your integration, type %{clusterName} to confirm:"
-msgstr ""
+msgstr "Para remover sua integração, digite %{clusterName} para confirmar:"
msgid "ClusterIntegration|To use a new project, first create one on %{docsLinkStart}Google Cloud Platform%{docsLinkEnd}."
msgstr ""
@@ -7890,7 +7935,7 @@ msgid "ClusterIntegration|Troubleshooting tips:"
msgstr ""
msgid "ClusterIntegration|Unable to Authenticate"
-msgstr ""
+msgstr "Incapaz de autenticar"
msgid "ClusterIntegration|Unable to Connect"
msgstr "Impossível de conectar"
@@ -7899,7 +7944,7 @@ msgid "ClusterIntegration|Unknown Error"
msgstr "Erro desconhecido"
msgid "ClusterIntegration|Uses the Cloud Run, Istio, and HTTP Load Balancing addons for this cluster."
-msgstr ""
+msgstr "Usa os complementos Cloud Run, Istio, e Balanceamento de Carga HTTP para este cluster."
msgid "ClusterIntegration|VPC"
msgstr "VPC"
@@ -7917,22 +7962,22 @@ msgid "ClusterIntegration|With a Kubernetes cluster associated to this project,
msgstr "Com um cluster Kubernetes associado a esse projeto, você pode utilizar apps de revisão, publicar suas aplicações, executar suas pipelines e muito mais de um jeito simples."
msgid "ClusterIntegration|You are about to remove your cluster integration and all GitLab-created resources associated with this cluster."
-msgstr ""
+msgstr "Você está prestes a remover a integração do cluster e todos os recursos criados pelo GitLab associados a este cluster."
msgid "ClusterIntegration|You are about to remove your cluster integration."
-msgstr ""
+msgstr "Você está prestes a remover sua integração com o cluster."
msgid "ClusterIntegration|You must grant access to your organization’s AWS resources in order to create a new EKS cluster. To grant access, create a provision role using the account and external ID below and provide us the ARN."
-msgstr ""
+msgstr "Você deve conceder acesso aos recursos AWS da sua organização para criar um novo cluster EKS. Para conceder acesso, crie uma função de provisão usando a conta e o ID externo abaixo e nos forneça o ARN."
msgid "ClusterIntegration|You should select at least two subnets"
-msgstr ""
+msgstr "Você deve selecionar pelo menos duas sub-redes"
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr "Sua conta precisa de %{link_to_kubernetes_engine}"
msgid "ClusterIntegration|Your cluster API is unreachable. Please ensure your API URL is correct."
-msgstr ""
+msgstr "Sua API de cluster está inacessível. Por favor, verifique se o URL da sua API está correta."
msgid "ClusterIntegration|Your service role is distinct from the provision role used when authenticating. It will allow Amazon EKS and the Kubernetes control plane to manage AWS resources on your behalf. To use a new role, first create one on %{linkStart}Amazon Web Services%{linkEnd}."
msgstr ""
@@ -7962,10 +8007,10 @@ msgid "ClusterIntergation|Select a subnet"
msgstr "Selecione uma sub-redes"
msgid "ClusterIntergation|Select a subnetwork"
-msgstr ""
+msgstr "Selecione uma sub-rede"
msgid "ClusterIntergation|Select an instance type"
-msgstr ""
+msgstr "Selecione um tipo de instância"
msgid "ClusterIntergation|Select key pair"
msgstr "Selecione o par de chaves"
@@ -7974,7 +8019,7 @@ msgid "ClusterIntergation|Select service role"
msgstr "Selecione a função de serviço"
msgid "Clusters|An error occurred while loading clusters"
-msgstr ""
+msgstr "Ocorreu um erro ao carregar os clusters"
msgid "Code"
msgstr "Código"
@@ -7989,7 +8034,7 @@ msgid "Code Coverage| Empty code coverage data"
msgstr "Dados de cobertura de código vazio"
msgid "Code Coverage|Couldn't fetch the code coverage data"
-msgstr ""
+msgstr "Não foi possível buscar os dados de cobertura de código"
msgid "Code Owner"
msgstr "Proprietário do código"
@@ -8046,7 +8091,7 @@ msgid "Cohorts|Registration month"
msgstr "Mês de registro"
msgid "Cohorts|Returning users"
-msgstr ""
+msgstr "Usuários recorrentes"
msgid "Cohorts|User cohorts are shown for the last %{months_included} months. Only users with activity are counted in the 'New users' column; inactive users are counted separately."
msgstr ""
@@ -8156,7 +8201,7 @@ msgid "Commit Message"
msgstr "Mensagem de Commit"
msgid "Commit changes"
-msgstr ""
+msgstr "Fazer commit das alterações"
msgid "Commit deleted"
msgstr "Commit excluído"
@@ -8207,13 +8252,13 @@ msgid "Commits you select appear here. Go to the first tab and select commits to
msgstr ""
msgid "Commits|An error occurred while fetching merge requests data."
-msgstr "Erro ao recuperar dados do merge request."
+msgstr "Erro ao recuperar dados da solicitação de mesclagem."
msgid "Commits|History"
msgstr "Histórico"
msgid "Commits|No related merge requests found"
-msgstr "Nenhum merge request relacionado foi encontrado"
+msgstr "Nenhuma solicitação de mesclagem relacionada foi encontrada"
msgid "Committed by"
msgstr "Commit feito por"
@@ -8249,7 +8294,7 @@ msgid "Compare changes with the last commit"
msgstr "Compare as mudanças do último commit"
msgid "Compare changes with the merge request target branch"
-msgstr "Compare as mudanças do merge request com o branch de destino"
+msgstr "Compare as mudanças da solicitação de mesclagem com a ramificação de destino"
msgid "Compare submodule commit revisions"
msgstr ""
@@ -8270,7 +8315,7 @@ msgid "CompareRevisions|Compare"
msgstr "Comparar"
msgid "CompareRevisions|Create merge request"
-msgstr "Criar merge request"
+msgstr "Criar solicitações de mesclagem"
msgid "CompareRevisions|Filter by Git revision"
msgstr "Filtrar por revisão do Git"
@@ -8294,13 +8339,13 @@ msgid "CompareRevisions|There was an error while loading the branch/tag list. Pl
msgstr ""
msgid "CompareRevisions|There was an error while searching the branch/tag list. Please try again."
-msgstr ""
+msgstr "Ocorreu um erro ao pesquisar a lista de tags/ramificações. Por favor, tente novamente."
msgid "CompareRevisions|There was an error while updating the branch/tag list. Please try again."
msgstr ""
msgid "CompareRevisions|View open merge request"
-msgstr "Ver merge request aberto"
+msgstr "Ver solicitação de mesclagem aberta"
msgid "Complete"
msgstr "Completo"
@@ -8315,16 +8360,13 @@ msgid "Compliance Dashboard"
msgstr "Painel de conformidade"
msgid "Compliance framework"
-msgstr ""
-
-msgid "Compliance framework (optional)"
-msgstr ""
+msgstr "Framework de conformidade"
msgid "ComplianceDashboard|created by:"
msgstr "Criado por"
msgid "ComplianceFrameworks|Add framework"
-msgstr ""
+msgstr "Adicionar framework"
msgid "ComplianceFrameworks|Combines with the CI configuration at runtime."
msgstr ""
@@ -8339,7 +8381,7 @@ msgid "ComplianceFrameworks|Could not find this configuration location, please t
msgstr ""
msgid "ComplianceFrameworks|Delete compliance framework %{framework}"
-msgstr ""
+msgstr "Excluir framework de conformidade %{framework}"
msgid "ComplianceFrameworks|Delete framework"
msgstr "Excluir framework"
@@ -8378,10 +8420,10 @@ msgid "ComplianceFrameworks|e.g. include-gitlab.ci.yml@group-name/project-name"
msgstr ""
msgid "ComplianceFramework|Edit Compliance Framework"
-msgstr ""
+msgstr "Editar framework de conformidade"
msgid "ComplianceFramework|New Compliance Framework"
-msgstr ""
+msgstr "Novo framework de conformidade"
msgid "Component"
msgstr "Componente"
@@ -8417,7 +8459,7 @@ msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if
msgstr ""
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
-msgstr "Configure os runners do GitLab para começar a usar o Terminal da Web. %{helpStart}Saiba mais.%{helpEnd}"
+msgstr "Configure os executores do GitLab para começar a usar o terminal da web. %{helpStart}Saiba mais.%{helpEnd}"
msgid "Configure Gitaly timeouts."
msgstr "Configurar timeouts do Gitaly."
@@ -8444,7 +8486,7 @@ msgid "Configure Tracing"
msgstr "Configurar rastreamento"
msgid "Configure a %{codeStart}.gitlab-webide.yml%{codeEnd} file in the %{codeStart}.gitlab%{codeEnd} directory to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
-msgstr ""
+msgstr "Configure um arquivo %{codeStart}.gitlab-webide.yml%{codeEnd} no %{codeStart}.gitLab%{codeEnd} para começar a usar o Terminal Web. %{helpStart}Saiba mais.%{helpEnd}"
msgid "Configure existing installation"
msgstr "Configurar instalação existente"
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr "Configurar limites para web e requisições para API."
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr "Configure os limites para o número de alertas de entrada que podem ser enviados para um projeto."
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr "Configurar armazenamento de repositório."
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -8486,7 +8528,7 @@ msgid "Configure the way a user creates a new account."
msgstr "Configurar a forma como o usuário cria uma nova conta."
msgid "Configure which lists are shown for anyone who visits this board"
-msgstr ""
+msgstr "Configure quais listas são mostradas para qualquer pessoa que visita este painel"
msgid "Confirm"
msgstr "Confirmar"
@@ -8537,7 +8579,7 @@ msgid "Conflict: This file was renamed in the source branch, but removed in the
msgstr ""
msgid "Confluence"
-msgstr ""
+msgstr "Confluence"
msgid "Confluence Cloud Workspace URL"
msgstr ""
@@ -8600,10 +8642,10 @@ msgid "Contact support"
msgstr "Contatar suporte"
msgid "Container Registry"
-msgstr "Container Registry"
+msgstr "Registro de contêiner"
msgid "Container Scanning"
-msgstr ""
+msgstr "Verificação de container"
msgid "Container does not exist"
msgstr "O container não existe"
@@ -8612,10 +8654,10 @@ msgid "Container must be a project or a group."
msgstr ""
msgid "Container registry images"
-msgstr "Imagens do container registry"
+msgstr "Imagens do registro de contêiner"
msgid "Container registry is not enabled on this GitLab instance. Ask an administrator to enable it in order for Auto DevOps to work."
-msgstr ""
+msgstr "O registro de contêiner não está ativado nesta instância do GitLab. Peça a um administrador para ativá-lo para que o Auto DevOps funcione."
msgid "Container repositories"
msgstr "Repositórios do container"
@@ -8706,7 +8748,7 @@ msgid "ContainerRegistry|Configuration digest: %{digest}"
msgstr ""
msgid "ContainerRegistry|Container Registry"
-msgstr "Container registry"
+msgstr "Registro de contêiner"
msgid "ContainerRegistry|Copy build command"
msgstr "Copiar comando de construção"
@@ -8727,7 +8769,7 @@ msgid "ContainerRegistry|Deleting the image repository will delete all images an
msgstr ""
msgid "ContainerRegistry|Deletion disabled due to missing or insufficient permissions."
-msgstr ""
+msgstr "Exclusão desabilitada devido à falta de permissões ou insuficientes."
msgid "ContainerRegistry|Digest: %{imageId}"
msgstr ""
@@ -8748,13 +8790,13 @@ msgid "ContainerRegistry|If you are not already logged in, you need to authentic
msgstr ""
msgid "ContainerRegistry|Image repository deletion failed"
-msgstr ""
+msgstr "Falha na exclusão do repositório de imagens"
msgid "ContainerRegistry|Image repository not found"
msgstr "Repositório de imagem não encontrado"
msgid "ContainerRegistry|Image repository will be deleted"
-msgstr ""
+msgstr "O repositório de imagens será excluído"
msgid "ContainerRegistry|Image repository with no name located at the project URL."
msgstr ""
@@ -8766,16 +8808,16 @@ msgid "ContainerRegistry|Invalid tag: missing manifest digest"
msgstr ""
msgid "ContainerRegistry|Keep tags matching:"
-msgstr ""
+msgstr "Manter as tags correspondentes:"
msgid "ContainerRegistry|Keep the most recent:"
-msgstr ""
+msgstr "Manter o mais recente:"
msgid "ContainerRegistry|Keep these tags"
-msgstr ""
+msgstr "Manter estas tags"
msgid "ContainerRegistry|Last updated %{time}"
-msgstr ""
+msgstr "Última atualização em %{time}"
msgid "ContainerRegistry|Login"
msgstr "Entrar"
@@ -8784,19 +8826,19 @@ msgid "ContainerRegistry|Manifest digest: %{digest}"
msgstr ""
msgid "ContainerRegistry|Missing or insufficient permission, delete button disabled"
-msgstr ""
+msgstr "Permissão ausente ou insuficiente, botão de exclusão desativado"
msgid "ContainerRegistry|Next cleanup scheduled to run on:"
-msgstr ""
+msgstr "Próxima limpeza agendada para execução em:"
msgid "ContainerRegistry|Not yet scheduled"
-msgstr ""
+msgstr "Ainda não agendado"
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
msgid "ContainerRegistry|Published %{timeInfo}"
-msgstr ""
+msgstr "Publicado em %{timeInfo}"
msgid "ContainerRegistry|Published to the %{repositoryPath} image repository at %{time} on %{date}"
msgstr ""
@@ -8822,13 +8864,13 @@ msgid "ContainerRegistry|Remove tags older than:"
msgstr ""
msgid "ContainerRegistry|Remove these tags"
-msgstr ""
+msgstr "Remover essas tags"
msgid "ContainerRegistry|Root image"
msgstr ""
msgid "ContainerRegistry|Run cleanup:"
-msgstr ""
+msgstr "Executar limpeza:"
msgid "ContainerRegistry|Some tags were not deleted"
msgstr "Algumas tag não foram excluídas"
@@ -8906,10 +8948,10 @@ msgid "ContainerRegistry|There was an error during the deletion of this image re
msgstr ""
msgid "ContainerRegistry|This image has no active tags"
-msgstr ""
+msgstr "Esta imagem não tem tags ativas"
msgid "ContainerRegistry|This image repository has failed to be deleted"
-msgstr ""
+msgstr "Não foi possível excluir este repositório de imagem"
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
@@ -8918,7 +8960,7 @@ msgid "ContainerRegistry|This image repository will be deleted. %{linkStart}Lear
msgstr ""
msgid "ContainerRegistry|This project's cleanup policy for tags is not enabled."
-msgstr ""
+msgstr "A política de limpeza deste projeto para tags não está ativada."
msgid "ContainerRegistry|To widen your search, change or remove the filters above."
msgstr ""
@@ -8927,13 +8969,13 @@ msgid "ContainerRegistry|We are having trouble connecting to the Registry, which
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
-msgstr ""
+msgstr "Com o registro de contêiner, cada projeto pode ter seu próprio espaço para armazenar suas imagens do Docker. %{docLinkStart}Mais informações%{docLinkEnd}"
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. Push at least one Docker image in one of this group's projects in order to show up here. %{docLinkStart}More Information%{docLinkEnd}"
-msgstr ""
+msgstr "Com o registro de contêiner, cada projeto pode ter seu próprio espaço para armazenar suas imagens do Docker. Envie pelo menos uma imagem Docker em um dos projetos deste grupo para aparecer aqui. %{docLinkStart}Mais informações%{docLinkEnd}"
msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
-msgstr ""
+msgstr "Com o registro de contêiner do GitLab, cada projeto pode ter seu próprio espaço para armazenar imagens. %{docLinkStart}Mais informações%{docLinkEnd}"
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
msgstr ""
@@ -8945,7 +8987,7 @@ msgid "ContainerRegistry|You are about to remove repository %{title}. Once you c
msgstr ""
msgid "ContainerRegistry|You can add an image to this registry with the following commands:"
-msgstr ""
+msgstr "Você pode adicionar uma imagem a este registro com os seguintes comandos:"
msgid "Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -8996,7 +9038,7 @@ msgid "ContributionAnalytics|%{pushes} pushes, more than %{commits} commits by %
msgstr ""
msgid "ContributionAnalytics|Contribution analytics for issues, merge requests and push events since %{start_date}"
-msgstr "Análises de contribuição para issues, merge requests e eventos de push desde %{start_date}"
+msgstr "Análises de contribuição para issues, solicitações de mesclagem e eventos de push desde %{start_date}"
msgid "ContributionAnalytics|Issues"
msgstr "Issues"
@@ -9011,13 +9053,13 @@ msgid "ContributionAnalytics|Last week"
msgstr "Semana passada"
msgid "ContributionAnalytics|Merge requests"
-msgstr "Merge requests"
+msgstr "Solicitações de mesclagem"
msgid "ContributionAnalytics|No issues for the selected time period."
msgstr "Nenhuma issues para o período selecionado."
msgid "ContributionAnalytics|No merge requests for the selected time period."
-msgstr "Nenhum merge requests para o período selecionado."
+msgstr "Nenhuma solicitação de mesclagem para o período selecionado."
msgid "ContributionAnalytics|No pushes for the selected time period."
msgstr "Nenhum push para o período selecionado."
@@ -9188,12 +9230,12 @@ msgid "CorpusManagement|Last updated"
msgstr "Última atualização"
msgid "CorpusManagement|Last used"
-msgstr ""
+msgstr "Último uso"
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -9365,7 +9407,7 @@ msgid "Create a merge request"
msgstr "Criar um merge request"
msgid "Create a new %{codeStart}.gitlab-ci.yml%{codeEnd} file at the root of the repository to get started."
-msgstr ""
+msgstr "Crie um novo arquivo %{codeStart}.gitlab-ci.yml%{codeEnd} na raiz do repositório para começar."
msgid "Create a new branch"
msgstr "Criar uma nova branch"
@@ -9455,7 +9497,7 @@ msgid "Create new %{name} by email"
msgstr "Criar novo %{name} por e-mail"
msgid "Create new CI/CD pipeline"
-msgstr ""
+msgstr "Criar novo pipeline CI/CD"
msgid "Create new Value Stream"
msgstr ""
@@ -9539,7 +9581,7 @@ msgid "CreateValueStreamForm|'%{name}' Value Stream saved"
msgstr ""
msgid "CreateValueStreamForm|Add another stage"
-msgstr ""
+msgstr "Adicionar outro estágio"
msgid "CreateValueStreamForm|Add stage"
msgstr "Adicionar estágio"
@@ -9599,7 +9641,7 @@ msgid "CreateValueStreamForm|Name is required"
msgstr ""
msgid "CreateValueStreamForm|New stage"
-msgstr ""
+msgstr "Novo estágio"
msgid "CreateValueStreamForm|Plan stage start"
msgstr ""
@@ -9698,7 +9740,7 @@ msgid "Created merge request %{mergeRequestLink}"
msgstr "Criado o merge request %{mergeRequestLink}"
msgid "Created merge request %{mergeRequestLink} at %{projectLink}"
-msgstr "Criado o merge request %{mergeRequestLink} em %{projectLink}"
+msgstr "Criado a solicitação de mesclagem %{mergeRequestLink} em %{projectLink}"
msgid "Created on"
msgstr "Criado em"
@@ -9710,10 +9752,10 @@ msgid "Created on:"
msgstr "Criado em:"
msgid "Creates a branch and a merge request to resolve this issue."
-msgstr "Cria um branch e um merge request para resolver esta issue."
+msgstr "Cria uma ramificação e uma solicitação de mesclagem para resolver esta issue."
msgid "Creates branch '%{branch_name}' and a merge request to resolve this issue."
-msgstr "Cria a branch '%{branch_name}' e um merge request para resolver esta issue."
+msgstr "Cria a ramificação '%{branch_name}' e uma solicitação de mesclagem para resolver esta issue."
msgid "Creating"
msgstr "Criando"
@@ -9734,31 +9776,31 @@ msgid "CredentialsInventory|GPG Keys"
msgstr "Chaves GPG"
msgid "CredentialsInventory|No credentials found"
-msgstr ""
+msgstr "Nenhuma credencial encontrada"
msgid "CredentialsInventory|Personal Access Tokens"
-msgstr ""
+msgstr "Tokens de acesso pessoal"
msgid "CredentialsInventory|SSH Keys"
msgstr "Chaves SSH"
msgid "Credit card validated at:"
-msgstr ""
+msgstr "Cartão de crédito validado em:"
msgid "Credit card validated:"
-msgstr ""
+msgstr "Cartão de crédito validado:"
msgid "Critical vulnerabilities present"
-msgstr ""
+msgstr "Vulnerabilidades críticas presentes"
msgid "Cron Timezone"
msgstr "Fuso horário do cron"
msgid "Cron time zone"
-msgstr ""
+msgstr "Fuso horário cron"
msgid "Crowd"
-msgstr ""
+msgstr "Crowd"
msgid "CsvParser|Failed to render the CSV file for the following reasons:"
msgstr ""
@@ -9782,7 +9824,7 @@ msgid "Current"
msgstr "Atual"
msgid "Current Branch"
-msgstr "Branch atual"
+msgstr "Ramificação atual"
msgid "Current Project"
msgstr "Projeto atual"
@@ -9854,7 +9896,7 @@ msgid "Custom range"
msgstr "Intervalo personalizado"
msgid "Custom range (UTC)"
-msgstr "Intervalo personalizado) (UTC)"
+msgstr "Intervalo personalizado (UTC)"
msgid "Customizable by an administrator."
msgstr "Personalizado por um administrador"
@@ -9881,7 +9923,7 @@ msgid "Customize name"
msgstr "Customizar nome"
msgid "Customize your pipeline configuration and coverage report."
-msgstr ""
+msgstr "Personalize a sua configuração de pipeline e relatório de cobertura."
msgid "Customize your pipeline configuration."
msgstr ""
@@ -9893,22 +9935,22 @@ msgid "CustomizeHomepageBanner|Go to preferences"
msgstr ""
msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr "Essa página mostra uma lista de seus projetos por padrão, mas pode ser alterada para mostrar atividade de projetos, grupos, sua lista de tarefas pendentes, issues atribuídas, merge request atribuídos, e muito mais. Você pode alterar isso em \"Conteúdo da página inicial\" nas suas preferências."
+msgstr "Essa página mostra uma lista de seus projetos por padrão, mas pode ser alterada para mostrar atividade de projetos, grupos, sua lista de tarefas pendentes, issues atribuídas, solicitações de mesclagem atribuídas, e muito mais. Você pode alterar isso em \"Conteúdo da página inicial\" nas suas preferências."
msgid "Cycle Time"
-msgstr ""
+msgstr "Tempo de ciclo"
msgid "CycleAnalyticsEvent|%{label_reference} label was added to the issue"
msgstr "%{label_reference} etiqueta foi adicionada para a issue"
msgid "CycleAnalyticsEvent|%{label_reference} label was added to the merge request"
-msgstr "%{label_reference} etiqueta foi adicionada para o merge request"
+msgstr "%{label_reference} etiqueta foi adicionada para a solicitação de mesclagem"
msgid "CycleAnalyticsEvent|%{label_reference} label was removed from the issue"
msgstr "%{label_reference} etiqueta foi removida da issue"
msgid "CycleAnalyticsEvent|%{label_reference} label was removed from the merge request"
-msgstr "%{label_reference} etiqueta foi removida do merge request"
+msgstr "%{label_reference} etiqueta foi removida da solicitação de mesclagem"
msgid "CycleAnalyticsEvent|Issue closed"
msgstr "Issue fechada"
@@ -9923,7 +9965,7 @@ msgid "CycleAnalyticsEvent|Issue first associated with a milestone"
msgstr "Issue associada pela primeira com um marcos"
msgid "CycleAnalyticsEvent|Issue first associated with a milestone or issue first added to a board"
-msgstr ""
+msgstr "Issue associada primeiro a um marco ou issue adicionada primeiro a um painel"
msgid "CycleAnalyticsEvent|Issue first mentioned in a commit"
msgstr "Issue mencionada primeiro em um commit"
@@ -9938,22 +9980,22 @@ msgid "CycleAnalyticsEvent|Issue last edited"
msgstr "Última edição da issue"
msgid "CycleAnalyticsEvent|Merge request closed"
-msgstr "Merge request fechado"
+msgstr "Solicitação de mesclagem fechada"
msgid "CycleAnalyticsEvent|Merge request created"
-msgstr "Merge request criado"
+msgstr "Solicitação de mesclagem criada"
msgid "CycleAnalyticsEvent|Merge request first commit time"
msgstr ""
msgid "CycleAnalyticsEvent|Merge request first deployed to production"
-msgstr "Merge request deploy primeiro para produção"
+msgstr "Solicitação de mesclagem implantada primeira para produção"
msgid "CycleAnalyticsEvent|Merge request label was added"
-msgstr "Etiqueta do merge request foi adicionado"
+msgstr "Etiqueta da solicitação de mesclagem foi adicionada"
msgid "CycleAnalyticsEvent|Merge request label was removed"
-msgstr "Etiqueta do merge request foi removido"
+msgstr "Etiqueta da solicitação de mesclagem foi removida"
msgid "CycleAnalyticsEvent|Merge request last build finish time"
msgstr ""
@@ -9962,10 +10004,10 @@ msgid "CycleAnalyticsEvent|Merge request last build start time"
msgstr ""
msgid "CycleAnalyticsEvent|Merge request last edited"
-msgstr "Última edição do merge request"
+msgstr "Última edição da solicitação de mesclagem"
msgid "CycleAnalyticsEvent|Merge request merged"
-msgstr "Merge request realizado"
+msgstr "Solicitação de mesclagem realizada"
msgid "CycleAnalyticsStage|Code"
msgstr "Código"
@@ -10077,25 +10119,25 @@ msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
msgid "DAST Configuration"
-msgstr ""
+msgstr "Cconfiguração de DAST"
msgid "DAST Scans"
-msgstr ""
+msgstr "Verificações de DAST"
msgid "DNS"
msgstr "DNS"
msgid "DORA4Metrics|%{startDate} - %{endDate}"
-msgstr ""
+msgstr "%{startDate} - %{endDate}"
msgid "DORA4Metrics|Date"
-msgstr ""
+msgstr "Data"
msgid "DORA4Metrics|Days from merge to deploy"
msgstr ""
msgid "DORA4Metrics|Deployment frequency"
-msgstr "Frequência de deployment"
+msgstr "Frequência de implantação"
msgid "DORA4Metrics|Lead time"
msgstr ""
@@ -10107,7 +10149,7 @@ msgid "DORA4Metrics|No merge requests were deployed during this period"
msgstr ""
msgid "DORA4Metrics|Number of deployments"
-msgstr ""
+msgstr "Número de implantações"
msgid "DORA4Metrics|Something went wrong while getting deployment frequency data."
msgstr ""
@@ -10149,13 +10191,13 @@ msgid "DastConfig|Customize DAST settings to suit your requirements. Configurati
msgstr ""
msgid "DastConfig|DAST Settings"
-msgstr ""
+msgstr "Configurações de DAST"
msgid "DastConfig|Generate code snippet"
-msgstr ""
+msgstr "Gerar snippet de código"
msgid "DastConfig|Scan Configuration"
-msgstr ""
+msgstr "Configuração de verificação"
msgid "DastProfiles|A passive scan monitors all HTTP messages (requests and responses) sent to the target. An active scan attacks the target to find potential vulnerabilities."
msgstr ""
@@ -10164,7 +10206,7 @@ msgid "DastProfiles|AJAX spider"
msgstr ""
msgid "DastProfiles|Active"
-msgstr ""
+msgstr "Ativo"
msgid "DastProfiles|Additional request headers (Optional)"
msgstr ""
@@ -10221,10 +10263,10 @@ msgid "DastProfiles|Could not update the site profile. Please try again."
msgstr ""
msgid "DastProfiles|DAST Scan"
-msgstr ""
+msgstr "Verificações de DAST"
msgid "DastProfiles|Debug messages"
-msgstr ""
+msgstr "Mensagens de depuração"
msgid "DastProfiles|Delete profile"
msgstr "Excluir perfil"
@@ -10242,10 +10284,10 @@ msgid "DastProfiles|Edit profile"
msgstr "Editar perfil"
msgid "DastProfiles|Edit scanner profile"
-msgstr ""
+msgstr "Editar perfil de verificação"
msgid "DastProfiles|Edit site profile"
-msgstr ""
+msgstr "Editar perfil de site"
msgid "DastProfiles|Enable Authentication"
msgstr "Ativar autenticação"
@@ -10266,13 +10308,13 @@ msgid "DastProfiles|Excluded URLs (Optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
-msgstr ""
+msgstr "Ocultar mensagens de depuração"
msgid "DastProfiles|Include debug messages in the DAST console output."
msgstr ""
msgid "DastProfiles|Manage DAST scans"
-msgstr ""
+msgstr "Gerenciar verificações de DAST"
msgid "DastProfiles|Manage profiles"
msgstr ""
@@ -10284,25 +10326,25 @@ msgid "DastProfiles|Minimum = 1 second, Maximum = 3600 seconds"
msgstr ""
msgid "DastProfiles|New scanner profile"
-msgstr ""
+msgstr "Novo perfil de verificação"
msgid "DastProfiles|New site profile"
-msgstr ""
+msgstr "Novo perfil de site"
msgid "DastProfiles|No scanner profiles created yet"
-msgstr ""
+msgstr "Nenhum perfil de verificação criado ainda"
msgid "DastProfiles|No scans saved yet"
-msgstr ""
+msgstr "Nenhuma verificação salva ainda"
msgid "DastProfiles|No site profiles created yet"
-msgstr ""
+msgstr "Nenhum perfil de site criado ainda"
msgid "DastProfiles|Not Validated"
msgstr "Não validado"
msgid "DastProfiles|Passive"
-msgstr ""
+msgstr "Passivo"
msgid "DastProfiles|Password"
msgstr "Senha"
@@ -10323,7 +10365,7 @@ msgid "DastProfiles|Rest API"
msgstr ""
msgid "DastProfiles|Run scan"
-msgstr ""
+msgstr "Executar verificação"
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -10335,34 +10377,34 @@ msgid "DastProfiles|Save profile"
msgstr "Salvar perfil"
msgid "DastProfiles|Saved Scans"
-msgstr ""
+msgstr "Verificações salvas"
msgid "DastProfiles|Scan"
-msgstr ""
+msgstr "Verificar"
msgid "DastProfiles|Scan mode"
-msgstr ""
+msgstr "Modo de verificação"
msgid "DastProfiles|Scanner Profile"
-msgstr ""
+msgstr "Perfil de verificação"
msgid "DastProfiles|Scanner Profiles"
-msgstr ""
+msgstr "Perfis de verificação"
msgid "DastProfiles|Scanner name"
-msgstr ""
+msgstr "Nome da verificação"
msgid "DastProfiles|Select branch"
msgstr "Selecionar branch"
msgid "DastProfiles|Show debug messages"
-msgstr ""
+msgstr "Mostrar mensagens de depuração"
msgid "DastProfiles|Site Profile"
-msgstr ""
+msgstr "Perfil de site"
msgid "DastProfiles|Site Profiles"
-msgstr ""
+msgstr "Perfis de site"
msgid "DastProfiles|Site name"
msgstr "Nome do site"
@@ -10380,7 +10422,7 @@ msgid "DastProfiles|Target URL"
msgstr ""
msgid "DastProfiles|Target timeout"
-msgstr ""
+msgstr "Tempo limite de destino"
msgid "DastProfiles|The maximum number of minutes allowed for the spider to traverse the site."
msgstr ""
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr "Validação de metatag"
+
msgid "DastSiteValidation|Retry validation"
msgstr "Tentar novamente a validação"
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,9 +10531,12 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
-msgid "DastSiteValidation|Validate"
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
msgstr ""
+msgid "DastSiteValidation|Validate"
+msgstr "Validar"
+
msgid "DastSiteValidation|Validate target site"
msgstr ""
@@ -10505,7 +10562,7 @@ msgid "Data is still calculating..."
msgstr "Os dados ainda estão a ser calculados..."
msgid "Data type"
-msgstr ""
+msgstr "Tipo de dados"
msgid "Database update failed"
msgstr "Falha na atualização do banco de dados"
@@ -10517,10 +10574,10 @@ msgid "DatadogIntegration|(Advanced) The full URL for your Datadog site."
msgstr ""
msgid "DatadogIntegration|API URL"
-msgstr ""
+msgstr "URL da API"
msgid "DatadogIntegration|Environment"
-msgstr ""
+msgstr "Ambiente"
msgid "DatadogIntegration|For self-managed deployments, set the %{codeOpen}env%{codeClose} tag for all the data sent to Datadog. %{linkOpen}How do I use tags?%{linkClose}"
msgstr ""
@@ -10532,7 +10589,7 @@ msgid "DatadogIntegration|Send CI/CD pipeline information to Datadog to monitor
msgstr ""
msgid "DatadogIntegration|Service"
-msgstr ""
+msgstr "Serviço"
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
@@ -10577,13 +10634,13 @@ msgid "Days"
msgstr "Dias"
msgid "Days to merge"
-msgstr "Dias para realizar merge"
+msgstr "Dias para mesclar"
msgid "Deactivate dormant users after 90 days of inactivity. Users can return to active status by signing in to their account. While inactive, a user is not counted as an active user in the instance."
msgstr ""
msgid "Dear Administrator,"
-msgstr ""
+msgstr "Caro Administrador,"
msgid "Debian package already exists in Distribution"
msgstr ""
@@ -10607,19 +10664,16 @@ msgid "Decompressed archive size validation failed."
msgstr ""
msgid "Decrease"
-msgstr ""
-
-msgid "Default"
-msgstr "Padrão"
+msgstr "Diminuir"
msgid "Default CI/CD configuration file"
-msgstr ""
+msgstr "Arquivo de configuração padrão de CI/CD"
msgid "Default artifacts expiration"
msgstr ""
msgid "Default branch"
-msgstr "Branch padrão"
+msgstr "Ramificação padrão"
msgid "Default branch and protected branches"
msgstr "Branch padrão e branches protegidos"
@@ -10637,7 +10691,7 @@ msgid "Default description template for issues"
msgstr "Modelo de descrição padrão para issues"
msgid "Default description template for merge requests"
-msgstr "Modelo de descrição padrão para merge requests"
+msgstr "Modelo de descrição padrão para solicitações de mesclagem"
msgid "Default first day of the week"
msgstr "Primeiro dia da semana padrão"
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr "Definição"
@@ -10729,9 +10786,15 @@ msgstr "Excluir artefatos"
msgid "Delete badge"
msgstr "Excluir selo"
+msgid "Delete column"
+msgstr "Excluir coluna"
+
msgid "Delete comment"
msgstr "Excluir comentário"
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr "Excluir domínio"
@@ -10756,6 +10819,9 @@ msgstr "Excluir projeto"
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr "Excluir projeto. VOCÊ TEM CERTEZA ABSOLUTA DISSO?"
+msgid "Delete row"
+msgstr "Excluir linha"
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10769,11 +10835,14 @@ msgid "Delete snippet?"
msgstr "Excluir snippet?"
msgid "Delete source branch"
-msgstr "Excluir branch de origem"
+msgstr "Excluir ramificação de origem"
msgid "Delete subscription"
msgstr "Excluir assinatura"
+msgid "Delete table"
+msgstr "Excluir tabela"
+
msgid "Delete this attachment"
msgstr "Excluir este anexo"
@@ -10880,7 +10949,7 @@ msgid "Dependencies|%{remainingLicensesCount} more"
msgstr ""
msgid "Dependencies|(top level)"
-msgstr ""
+msgstr "(nível superior)"
msgid "Dependencies|All"
msgstr "Todas"
@@ -10943,20 +11012,20 @@ msgid "Dependency List has no entries"
msgstr ""
msgid "Dependency Proxy"
-msgstr "Proxy de Dependências"
+msgstr "Proxy de dependências"
msgid "Dependency Scanning"
-msgstr ""
+msgstr "Verificação de dependência"
msgid "Dependency proxy"
msgstr "Proxy de dependências"
-msgid "Dependency proxy URL"
-msgstr "URL de proxy de dependências"
-
msgid "Dependency proxy feature is limited to public groups for now."
msgstr "A funcionalidade de proxy de dependências está limitada a grupos públicos por hora."
+msgid "Dependency proxy image prefix"
+msgstr ""
+
msgid "DependencyProxy|Toggle Dependency Proxy"
msgstr "Alternar proxy de dependências"
@@ -10972,20 +11041,20 @@ msgstr[1] ""
msgid "Deploy"
msgid_plural "Deploys"
-msgstr[0] "Deploy"
-msgstr[1] "Deploys"
+msgstr[0] "Implantar"
+msgstr[1] "Implantações"
msgid "Deploy Keys"
-msgstr "Chaves para deploy"
+msgstr "Chave de implantação"
msgid "Deploy freezes"
msgstr ""
msgid "Deploy key was successfully updated."
-msgstr "A chave de deploy foi atualizada com sucesso."
+msgstr "A chave de implantação foi atualizada com sucesso."
msgid "Deploy keys"
-msgstr ""
+msgstr "Chaves de implantação"
msgid "Deploy keys grant read/write access to all repositories in your instance"
msgstr ""
@@ -10994,7 +11063,7 @@ msgid "Deploy progress not found. To see pods, ensure your environment matches %
msgstr ""
msgid "Deploy to..."
-msgstr "Deploy em..."
+msgstr "Implantar em..."
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr "Excluir"
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr "Editar"
@@ -11027,19 +11108,19 @@ msgid "DeployKeys|Current project"
msgstr "Projeto Atual"
msgid "DeployKeys|Deploy key"
-msgstr "Chave de deploy"
+msgstr "Chave de implantação"
msgid "DeployKeys|Enabled deploy keys"
-msgstr "Chaves de deploy ativas"
+msgstr "Chaves de implantação ativas"
msgid "DeployKeys|Error enabling deploy key"
-msgstr "Erro ao ativar chaves de deploy"
+msgstr "Erro ao ativar chaves de implantação"
msgid "DeployKeys|Error getting deploy keys"
-msgstr "Erro ao obter chaves de deploy"
+msgstr "Erro ao obter chaves de implantação"
msgid "DeployKeys|Error removing deploy key"
-msgstr "Erro ao remover chave de deploy"
+msgstr "Erro ao remover chave de implantação"
msgid "DeployKeys|Expand %{count} other projects"
msgstr "Expandir %{count} outros projetos"
@@ -11048,25 +11129,25 @@ msgid "DeployKeys|Grant write permissions to this key"
msgstr ""
msgid "DeployKeys|Loading deploy keys"
-msgstr "Carregando chaves de deploy"
+msgstr "Carregando chaves de implantação"
msgid "DeployKeys|No deploy keys found. Create one with the form above."
-msgstr "Nenhuma chave de deploy encontrada. Crie uma com o formulário acima."
+msgstr "Nenhuma chave de implantação encontrada. Crie uma com o formulário acima."
msgid "DeployKeys|Privately accessible deploy keys"
-msgstr "Chaves de deploy acessíveis de forma privada"
+msgstr "Chaves de implantação acessíveis de forma privada"
msgid "DeployKeys|Project usage"
msgstr "Uso do projeto"
msgid "DeployKeys|Publicly accessible deploy keys"
-msgstr "Chaves de deploy acessíveis publicamente"
+msgstr "Chaves de implantação acessíveis publicamente"
msgid "DeployKeys|Read access only"
msgstr "Apenas acesso de leitura"
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
-msgstr "Tokens de deploy ativos (%{active_tokens})"
+msgstr "Tokens de implantação ativos (%{active_tokens})"
msgid "DeployTokens|Allows read and write access to registry images."
msgstr ""
@@ -11084,34 +11165,34 @@ msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
msgid "DeployTokens|Copy deploy token"
-msgstr "Copiar token de deploy"
+msgstr "Copiar token de implantação"
msgid "DeployTokens|Copy username"
msgstr "Copiar nome de usuário"
msgid "DeployTokens|Create a new deploy token for all projects in this group. %{link_start}What are deploy tokens?%{link_end}"
-msgstr ""
+msgstr "Cria um novo token de inplantação para todos os projetos neste grupo. %{link_start}O que são tokens de implantação?%{link_end}"
msgid "DeployTokens|Create deploy token"
-msgstr "Criar token de deploy"
+msgstr "Criar token de implantação"
msgid "DeployTokens|Created"
msgstr "Criado"
msgid "DeployTokens|Deploy tokens"
-msgstr ""
+msgstr "Tokens de inplantação"
msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
-msgstr ""
+msgstr "Tokens de inplantação permitem acesso a pacotes, seu repositório e imagens do registro."
msgid "DeployTokens|Enter a unique name for your deploy token."
-msgstr ""
+msgstr "Digite um nome exclusivo para o seu token de implantação."
msgid "DeployTokens|Enter a username for your token. Defaults to %{code_start}gitlab+deploy-token-{n}%{code_end}."
msgstr ""
msgid "DeployTokens|Enter an expiration date for your token. Defaults to never expire."
-msgstr ""
+msgstr "Digite uma data de expiração para o seu token. O padrão é nunca expirar."
msgid "DeployTokens|Expires"
msgstr "Expira"
@@ -11123,7 +11204,7 @@ msgid "DeployTokens|Name"
msgstr "Nome"
msgid "DeployTokens|New deploy token"
-msgstr "Novo token de deploy"
+msgstr "Novo token de implantação"
msgid "DeployTokens|Revoke"
msgstr "Revogar"
@@ -11153,37 +11234,37 @@ msgid "DeployTokens|Your new Deploy Token username"
msgstr ""
msgid "DeployTokens|Your new group deploy token has been created."
-msgstr ""
+msgstr "Seu novo token de inplantação de grupo foi criado."
msgid "DeployTokens|Your new project deploy token has been created."
-msgstr "Seu novo token de deploy de projeto foi criado."
+msgstr "Seu novo token de implantação de projeto foi criado."
msgid "Deployed"
-msgstr "Deploy concluído"
+msgstr "Implantado"
msgid "Deployed to"
-msgstr "Deploy para"
+msgstr "Implantado para"
msgid "Deployed-after"
-msgstr ""
+msgstr "Implantado depois"
msgid "Deployed-before"
-msgstr ""
+msgstr "Implantado antes"
msgid "Deploying to"
-msgstr "Fazer deploy para"
+msgstr "Implantando para"
msgid "Deploying to AWS is easy with GitLab"
-msgstr ""
+msgstr "Implantar em AWS é fácil com GitLab"
msgid "Deployment Frequency"
-msgstr "Frequência de deployment"
+msgstr "Frequência de implantação"
msgid "Deployment frequency"
-msgstr "Frequência de deployment"
+msgstr "Frequência de implantação"
msgid "Deployments"
-msgstr ""
+msgstr "Implementações"
msgid "Deployments|%{deployments} environment impacted."
msgid_plural "Deployments|%{deployments} environments impacted."
@@ -11230,10 +11311,10 @@ msgid "Description (optional)"
msgstr "Descrição (opcional)"
msgid "Description parsed with %{link_start}GitLab Flavored Markdown%{link_end}"
-msgstr ""
+msgstr "Descrição analisada com %{link_start}GitLab Flavored Markdown%{link_end}"
msgid "Description parsed with %{link_start}GitLab Flavored Markdown%{link_end}."
-msgstr ""
+msgstr "Descrição analisada com %{link_start}GitLab Flavored Markdown%{link_end}."
msgid "Description template"
msgstr "Modelo de descrição"
@@ -11317,7 +11398,7 @@ msgid "DesignManagement|Deselect all"
msgstr "Desmarcar tudo"
msgid "DesignManagement|Designs"
-msgstr ""
+msgstr "Designs"
msgid "DesignManagement|Discard comment"
msgstr "Descartar comentário"
@@ -11338,10 +11419,10 @@ msgid "DesignManagement|Go to previous design"
msgstr "Ir para o design anterior"
msgid "DesignManagement|Keep changes"
-msgstr ""
+msgstr "Manter as alterações"
msgid "DesignManagement|Keep comment"
-msgstr ""
+msgstr "Manter o comentário"
msgid "DesignManagement|Learn more about resolving comments"
msgstr ""
@@ -11404,13 +11485,13 @@ msgid "Detect host keys"
msgstr "Detectar chaves de host"
msgid "DevOps Adoption"
-msgstr ""
+msgstr "Adoção de DevOps"
msgid "DevOps Report"
-msgstr ""
+msgstr "Relatório de DevOps"
msgid "DevOps adoption"
-msgstr ""
+msgstr "Adoção de DevOps"
msgid "Devices (optional)"
msgstr "Dispositivos (opcional)"
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr "Adotado"
+msgid "DevopsAdoption|Adoption by group"
+msgstr "Adoção por grupo"
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr "Adoção por subgrupo"
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr "Ocorreu um erro ao remover o grupo. Por favor, tente novamente."
@@ -11490,7 +11577,7 @@ msgstr "Editar grupos"
msgid "DevopsAdoption|Edit subgroups"
msgstr "Editar subgrupos"
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11509,7 +11596,7 @@ msgid "DevopsAdoption|No results…"
msgstr "Sem resultados…"
msgid "DevopsAdoption|Not adopted"
-msgstr ""
+msgstr "Não adotado"
msgid "DevopsAdoption|Ops"
msgstr ""
@@ -11521,7 +11608,7 @@ msgid "DevopsAdoption|Pipelines"
msgstr "Pipelines"
msgid "DevopsAdoption|Remove Group"
-msgstr ""
+msgstr "Remover grupo"
msgid "DevopsAdoption|Remove Group from the table."
msgstr ""
@@ -11530,7 +11617,7 @@ msgid "DevopsAdoption|Runner configured for project/group"
msgstr ""
msgid "DevopsAdoption|Runners"
-msgstr ""
+msgstr "Executores"
msgid "DevopsAdoption|SAST"
msgstr ""
@@ -11650,7 +11737,7 @@ msgid "Disable for this project"
msgstr "Desativar para este projeto"
msgid "Disable group runners"
-msgstr ""
+msgstr "Desativar executores de grupo"
msgid "Disable two-factor authentication"
msgstr "Desativar autenticação de dois fatores"
@@ -11659,7 +11746,7 @@ msgid "Disabled"
msgstr "Desativado"
msgid "Disabled by %{parent} owner"
-msgstr ""
+msgstr "Desativado pelo proprietário de %{parent}"
msgid "Disabled mirrors can only be enabled by instance owners. It is recommended that you delete them."
msgstr "Os espelhos desativados só podem ser ativados por donos de instâncias. É recomendável que você os exclua."
@@ -11760,7 +11847,7 @@ msgid "Dismiss trial promotion"
msgstr "Ignorar promoção de avaliação"
msgid "Dismissable"
-msgstr ""
+msgstr "Dispensável"
msgid "Dismissed"
msgstr "Descartado"
@@ -11775,16 +11862,16 @@ msgid "Dismissed on pipeline %{pipelineLink} at %{projectLink}"
msgstr "Descartado no pipeline %{pipelineLink} em %{projectLink}"
msgid "Display alerts from all configured monitoring tools."
-msgstr ""
+msgstr "Exibir alertas de todas as ferramentas de monitoramento configuradas."
msgid "Display name"
msgstr "Nome de exibição"
msgid "Display rendered file"
-msgstr ""
+msgstr "Exibir arquivo renderizado"
msgid "Display source"
-msgstr ""
+msgstr "Exibir fonte"
msgid "Display time tracking in issues in total hours only."
msgstr ""
@@ -11796,7 +11883,7 @@ msgid "Do not force push over diverged refs. After the mirror is created, this s
msgstr ""
msgid "Do you want to remove this deploy key?"
-msgstr ""
+msgstr "Você quer remover essa chave de implantação?"
msgid "Dockerfile"
msgstr "Dockerfile"
@@ -11895,7 +11982,7 @@ msgid "Download image"
msgstr "Baixar imagem"
msgid "Download raw data (.csv)"
-msgstr ""
+msgstr "Baixar dados raw (.csv)"
msgid "Download source code"
msgstr "Baixar código-fonte"
@@ -11922,7 +12009,7 @@ msgid "Draft"
msgstr "Rascunho"
msgid "Draft merge requests can't be merged."
-msgstr "Merge request de rascunho não pode ter merge."
+msgstr "Solicitações de mesclagem de rascunho não pode ser mesclado"
msgid "Drag your designs here or %{linkStart}click to upload%{linkEnd}."
msgstr "Arraste seus projetos aqui ou %{linkStart}clique para enviar%{linkEnd}."
@@ -11958,7 +12045,7 @@ msgid "DropdownWidget|No %{issuableAttribute} found"
msgstr ""
msgid "Due Date"
-msgstr "Data limite"
+msgstr "Validade"
msgid "Due date"
msgstr "Validade"
@@ -11991,7 +12078,7 @@ msgid "Edit Comment"
msgstr "Editar comentário"
msgid "Edit Deploy Key"
-msgstr "Editar chave de deploy"
+msgstr "Editar chave de implantação"
msgid "Edit Geo Node"
msgstr ""
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr "Editar identidade"
+
msgid "Edit Label"
msgstr "Editar etiqueta"
@@ -12069,11 +12159,14 @@ msgid "Edit issues"
msgstr "Editar issues"
msgid "Edit public deploy key"
-msgstr "Editar chave de deploy pública"
+msgstr "Editar chave de implantação pública"
msgid "Edit sidebar"
msgstr "Editar barra lateral"
+msgid "Edit table"
+msgstr "Editar tabela"
+
msgid "Edit this file only."
msgstr "Editar somente esse arquivo"
@@ -12135,7 +12228,7 @@ msgid "Elasticsearch zero-downtime reindexing"
msgstr ""
msgid "Elastic|None. Select namespaces to index."
-msgstr "Nenhum. Selecione namespaces para indexar."
+msgstr "Nenhum. Selecione espaços de nome para indexar."
msgid "Elastic|None. Select projects to index."
msgstr "Nenhum. Selecione projetos para indexar."
@@ -12144,7 +12237,7 @@ msgid "Email"
msgstr "E-mail"
msgid "Email %{number}"
-msgstr ""
+msgstr "E-mail %{number}"
msgid "Email Notification"
msgstr "Notificação por e-mail"
@@ -12153,13 +12246,13 @@ msgid "Email a new %{name} to this project"
msgstr ""
msgid "Email address to use for Support Desk"
-msgstr ""
+msgstr "Endereço de e-mail para usar na central de serviços"
msgid "Email could not be sent"
msgstr "E-mail não pode ser enviado"
msgid "Email display name"
-msgstr ""
+msgstr "Nome de exibição no e-mail"
msgid "Email from GitLab - email users right from the Admin Area. %{link_start}Learn more%{link_end}."
msgstr ""
@@ -12225,7 +12318,7 @@ msgid "Emails"
msgstr "E-mails"
msgid "Emails sent from Service Desk have this name."
-msgstr ""
+msgstr "OS e-mails enviados pela central de serviços tem esse nome."
msgid "Emails sent to %{email} are also supported."
msgstr ""
@@ -12243,7 +12336,7 @@ msgid "EmailsOnPushService|Emails on push"
msgstr ""
msgid "EmailsOnPushService|Emails separated by whitespace."
-msgstr ""
+msgstr "E-mails separados por espaço em branco."
msgid "EmailsOnPushService|Send from committer"
msgstr "Enviar do committer"
@@ -12281,9 +12374,6 @@ msgstr "Ativar Gitpod"
msgid "Enable Gitpod?"
msgstr "Ativar Gitpod?"
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12324,7 +12414,7 @@ msgid "Enable access to the performance bar for non-administrators in a given gr
msgstr ""
msgid "Enable admin mode"
-msgstr ""
+msgstr "Ativar modo administrativo"
msgid "Enable and disable Service Desk. Some additional configuration might be required. %{link_start}Learn more%{link_end}."
msgstr "Ativar e e desativar a central de serviços. Algumas configurações adicionais podem ser necessárias. %{link_start}Saiba mais%{link_end}."
@@ -12332,6 +12422,9 @@ msgstr "Ativar e e desativar a central de serviços. Algumas configurações adi
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr "Ativar autenticação"
@@ -12348,7 +12441,7 @@ msgid "Enable delayed project deletion by default for newly-created groups."
msgstr ""
msgid "Enable email notification"
-msgstr ""
+msgstr "Ativar notificações por e-mail"
msgid "Enable error tracking"
msgstr "Ativar rastreamento de erros"
@@ -12360,7 +12453,7 @@ msgid "Enable for this project"
msgstr "Ativar para este projeto"
msgid "Enable group runners"
-msgstr ""
+msgstr "Ativar executores de grupo"
msgid "Enable header and footer in emails"
msgstr "Ativar cabeçalho e rodapé em e-mails"
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr "Ativar integração"
@@ -12417,10 +12513,10 @@ msgid "Enable shared runners for all projects and subgroups in this group."
msgstr ""
msgid "Enable shared runners for this group"
-msgstr ""
+msgstr "Ativar executores compartilhados para este grupo"
msgid "Enable shared runners for this project"
-msgstr ""
+msgstr "Ativar executores compartilhados para este projeto"
msgid "Enable smartcn custom analyzer: Indexing"
msgstr ""
@@ -12456,7 +12552,7 @@ msgid "EnableReviewApp|Close"
msgstr "Fechar"
msgid "EnableReviewApp|Copy snippet text"
-msgstr ""
+msgstr "Copiar texto do snippet"
msgid "Enabled"
msgstr "Habilitado"
@@ -12471,7 +12567,7 @@ msgid "Enabled sources for code import during project creation. OmniAuth must be
msgstr "As fontes para importação de código durante a criação de projetos foram ativadas. O OmniAuth deve ser configurado para o GitHub."
msgid "Enabling this will only make licensed EE features available to projects if the project namespace's plan includes the feature or if the project is public."
-msgstr "Ativar isto apenas disponibilizará os recursos EE licenciados para projetos se o plano do namespace do projeto incluir o recurso ou se o projeto for público."
+msgstr "Ativar isto apenas disponibilizará os recursos EE licenciados para projetos se o plano do espaço de nome do projeto incluir o recurso ou se o projeto for público."
msgid "Encountered an error while rendering: %{err}"
msgstr ""
@@ -12501,10 +12597,10 @@ msgid "Enforce personal access token expiration"
msgstr ""
msgid "Enforce two-factor authentication"
-msgstr ""
+msgstr "Forçar autenticação de dois fatores"
msgid "Enforce two-factor authentication for all user sign-ins."
-msgstr ""
+msgstr "Forçar Autenticação de dois fatores para todos os logins de usuários"
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -12546,7 +12642,7 @@ msgid "Enter in your Phabricator Server URL and personal access token below"
msgstr "Informe o URL do servidor do Phabricator e o token de acesso pessoal abaixo"
msgid "Enter merge request URLs"
-msgstr "Digite as URLs de merge requests"
+msgstr "Digite as URLs de solicitações de mesclagem"
msgid "Enter new AWS Secret Access Key"
msgstr "Digite a nova chave do AWS Secret Access Key"
@@ -12567,7 +12663,7 @@ msgid "Enter the code from the two-factor app on your mobile device. If you've l
msgstr ""
msgid "Enter the name of your application, and we'll return a unique %{type}."
-msgstr ""
+msgstr "Digite o nome da sua aplicação e devolveremos um %{type} único."
msgid "Enter the number of seconds, or other human-readable input, like \"1 hour\". This timeout takes precedence over lower timeouts set for the project."
msgstr ""
@@ -12585,7 +12681,7 @@ msgid "Enter your password to approve"
msgstr "Digite sua senha para aprovar"
msgid "Enterprise"
-msgstr ""
+msgstr "Empresa"
msgid "Environment"
msgstr "Ambiente"
@@ -12618,7 +12714,7 @@ msgid "EnvironmentDashboard|API"
msgstr "API"
msgid "EnvironmentDashboard|Created through the Deployment API"
-msgstr "Criado por meio da API de deploy"
+msgstr "Criado por meio da API de implantação"
msgid "EnvironmentDashboard|You are looking at the last updated environment"
msgstr ""
@@ -12630,13 +12726,13 @@ msgid "Environments Dashboard"
msgstr "Painel de ambientes"
msgid "Environments allow you to track deployments of your application. %{linkStart}More information%{linkEnd}."
-msgstr ""
+msgstr "Os ambientes permitem que você acompanhe as implantações do seu aplicativo. %{linkStart}Mais informações%{linkEnd}."
msgid "Environments in %{name}"
msgstr "Ambientes em %{name}"
msgid "EnvironmentsAlert|%{severity} • %{title} %{text}. %{linkStart}View Details%{linkEnd} · %{startedAt} "
-msgstr ""
+msgstr "%{severity} • %{title} %{text}. %{linkStart}Ver detalhes%{linkEnd} · %{startedAt} "
msgid "EnvironmentsDashboard|Add a project to the dashboard"
msgstr "Adicionar um projeto ao dashboard"
@@ -12717,16 +12813,19 @@ msgid "Environments|Deleting the '%{environmentName}' environment cannot be undo
msgstr ""
msgid "Environments|Deploy to..."
-msgstr "Deploy para..."
+msgstr "Implantar para..."
msgid "Environments|Deployment"
-msgstr "Deploy"
+msgstr "Implantação"
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr "Dispensar"
+
msgid "Environments|Enable review app"
-msgstr ""
+msgstr "Ativar app de revisão"
msgid "Environments|Environment"
msgstr "Ambiente"
@@ -12735,7 +12834,10 @@ msgid "Environments|Environments"
msgstr "Ambientes"
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
-msgstr "Ambientes são locais onde o deploy é feito, tais como homologação ou produção."
+msgstr "Ambientes são locais onde a implantação é feita, tais como homologação ou produção."
+
+msgid "Environments|Help us improve environments"
+msgstr "Ajude-nos a melhorar os ambientes"
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12759,10 +12861,10 @@ msgid "Environments|New environment"
msgstr "Novo ambiente"
msgid "Environments|No deployed environments"
-msgstr "Nenhum ambiente de deployed"
+msgstr "Nenhum ambiente de implantação"
msgid "Environments|No deployments yet"
-msgstr "Nenhum deploy"
+msgstr "Nenhuma implantação ainda"
msgid "Environments|No pod selected"
msgstr "Nenhum pod selecionado"
@@ -12812,6 +12914,9 @@ msgstr "Parar ambiente"
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr "Participe da pesquisa"
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12825,7 +12930,7 @@ msgid "Environments|Upcoming"
msgstr "Em breve"
msgid "Environments|Upcoming deployment"
-msgstr "Deploy em breve"
+msgstr "Implantação em breve"
msgid "Environments|Updated"
msgstr "Atualizado"
@@ -12833,6 +12938,12 @@ msgstr "Atualizado"
msgid "Environments|You don't have any environments right now"
msgstr "Você não tem nenhum ambiente no momento"
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr "por %{avatar}"
+
msgid "Environments|protected"
msgstr "protegido"
@@ -12840,16 +12951,16 @@ msgid "Epic"
msgstr "Épico"
msgid "Epic Boards"
-msgstr ""
+msgstr "Quadros épicos"
msgid "Epic cannot be found."
msgstr "Épico não pode ser encontrado."
msgid "Epic details"
-msgstr ""
+msgstr "Detalhes épicos"
msgid "Epic events"
-msgstr ""
+msgstr "Eventos épicos"
msgid "Epic not found for given params"
msgstr ""
@@ -12867,13 +12978,13 @@ msgid "Epics let you manage your portfolio of projects more efficiently and with
msgstr "Epics permitem gerenciar seu portfólio de projetos de forma mais eficiente e com menos esforço"
msgid "Epics, issues, and merge requests"
-msgstr ""
+msgstr "Épicos, issues e solicitações de mesclagem"
msgid "Epics|%{startDate} – %{dueDate}"
-msgstr ""
+msgstr "%{startDate} – %{dueDate}"
msgid "Epics|%{startDate} – No due date"
-msgstr ""
+msgstr "%{startDate} – Sem validade"
msgid "Epics|Add a new epic"
msgstr "Adicionar um novo épico"
@@ -12885,7 +12996,7 @@ msgid "Epics|An error occurred while saving the %{epicDateType} date"
msgstr "Ocorreu um erro ao salvar a data de %{epicDateType}"
msgid "Epics|An error occurred while updating labels."
-msgstr ""
+msgstr "Ocorreu um erro ao atualizar as etiquetas."
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr "Você tem certeza de que quer remover %{bStart}%{targetIssueTitle}%{bEnd} de %{bStart}%{parentEpicTitle}%{bEnd}?"
@@ -12894,7 +13005,7 @@ msgid "Epics|Assign Epic"
msgstr "Atribuir épico"
msgid "Epics|Enter a title for your epic"
-msgstr ""
+msgstr "Digite um título para o seu épico"
msgid "Epics|How can I solve this?"
msgstr "Como posso resolver isso?"
@@ -12903,7 +13014,7 @@ msgid "Epics|Leave empty to inherit from milestone dates"
msgstr ""
msgid "Epics|No start date – %{dueDate}"
-msgstr ""
+msgstr "Sem data de início - %{dueDate}"
msgid "Epics|Remove epic"
msgstr "Remover épico"
@@ -13026,7 +13137,7 @@ msgid "Error loading branch data. Please try again."
msgstr "Erro ao carregar dados de branch. Por favor, tente novamente."
msgid "Error loading branches."
-msgstr "Erro ao carregar os branches."
+msgstr "Erro ao carregar as ramificações."
msgid "Error loading burndown chart data"
msgstr "Erro ao carregar dados do gráfico de burndown"
@@ -13050,7 +13161,7 @@ msgid "Error loading markdown preview"
msgstr "Erro ao carregar a pré-visualização do markdown"
msgid "Error loading merge requests."
-msgstr "Erro ao carregar merge requests."
+msgstr "Erro ao carregar solicitações de mesclagem"
msgid "Error loading milestone tab"
msgstr "Erro ao carregar a aba de marco"
@@ -13122,7 +13233,7 @@ msgid "Error setting up editor. Please try again."
msgstr "Ocorreu um erro ao configurar o editor. Por favor, tente novamente."
msgid "Error tracking"
-msgstr ""
+msgstr "Rastreamento de erros"
msgid "Error updating %{issuableType}"
msgstr "Erro ao atualizar %{issuableType}"
@@ -13146,7 +13257,7 @@ msgid "Error uploading file: %{stripped}"
msgstr "Erro ao enviar o arquivo: %{stripped}"
msgid "Error while loading the merge request. Please try again."
-msgstr "Erro ao carregar o merge request. Por favor, tente novamente."
+msgstr "Erro ao carregar a solicitação de mesclagem. Por favor, tente novamente."
msgid "Error while loading the project data. Please try again."
msgstr "Ocorreu um erro ao carregar os dados do projeto. Por favor, tente novamente."
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -13188,7 +13302,7 @@ msgid "ErrorTracking|Connection failed. Check Auth Token and try again."
msgstr ""
msgid "ErrorTracking|Enable error tracking"
-msgstr ""
+msgstr "Ativar rastreamento de erros"
msgid "ErrorTracking|If you self-host Sentry, enter your Sentry instance's full URL. If you use Sentry's hosted solution, enter https://sentry.io"
msgstr ""
@@ -13212,10 +13326,10 @@ msgid "Errors:"
msgstr "Erros:"
msgid "Escalation Policies"
-msgstr ""
+msgstr "Políticas de escalação"
msgid "Escalation policies"
-msgstr ""
+msgstr "Políticas de escalação"
msgid "Escalation policies may not have more than %{rule_count} rules"
msgstr ""
@@ -13224,13 +13338,13 @@ msgid "Escalation policies must have at least one rule"
msgstr ""
msgid "EscalationPolicies|+ Add an additional rule"
-msgstr ""
+msgstr "+ Adicionar uma regra adicional"
msgid "EscalationPolicies|A schedule is required for adding an escalation policy."
msgstr ""
msgid "EscalationPolicies|A schedule is required for adding an escalation policy. Please create an on-call schedule first."
-msgstr ""
+msgstr "Um agendamento é necessário para adicionar uma política de escalação. Por favor, crie um agendamento de plantão."
msgid "EscalationPolicies|A user is required for adding an escalation policy."
msgstr ""
@@ -13248,34 +13362,34 @@ msgid "EscalationPolicies|Are you sure you want to delete the \"%{escalationPoli
msgstr ""
msgid "EscalationPolicies|Create an escalation policy in GitLab"
-msgstr ""
+msgstr "Crie uma política de escalação no GitLab"
msgid "EscalationPolicies|Delete escalation policy"
-msgstr ""
+msgstr "Excluir política de escalação"
msgid "EscalationPolicies|Edit escalation policy"
-msgstr ""
+msgstr "Editar política de escalação"
msgid "EscalationPolicies|Email on-call user in schedule"
-msgstr ""
+msgstr "Enviar um e-mail para o usuário de plantão no agendamento"
msgid "EscalationPolicies|Email user"
-msgstr ""
+msgstr "Enviar e-mail"
msgid "EscalationPolicies|Escalation policies"
-msgstr ""
+msgstr "Políticas de escalação"
msgid "EscalationPolicies|Escalation rules"
-msgstr ""
+msgstr "Regras de escalação"
msgid "EscalationPolicies|Failed to load oncall-schedules"
msgstr ""
msgid "EscalationPolicies|IF alert is not %{alertStatus} in %{minutes} %{then} THEN %{doAction} %{scheduleOrUser}"
-msgstr ""
+msgstr "Se alerta não for %{alertStatus} em %{minutes} %{then} ENTÃO %{doAction} %{scheduleOrUser}"
msgid "EscalationPolicies|IF alert is not %{alertStatus} in %{minutes} minutes"
-msgstr ""
+msgstr "Se alerta não for %{alertStatus} em %{minutes} minutos"
msgid "EscalationPolicies|Maximum of 10 rules has been reached."
msgstr ""
@@ -13287,16 +13401,16 @@ msgid "EscalationPolicies|Remove escalation rule"
msgstr ""
msgid "EscalationPolicies|Search for user"
-msgstr ""
+msgstr "Pesquisar usuário"
msgid "EscalationPolicies|Select schedule"
-msgstr ""
+msgstr "Selecionar agendamento"
msgid "EscalationPolicies|Set up escalation policies to define who is paged, and when, in the event the first users paged don't respond."
msgstr ""
msgid "EscalationPolicies|THEN %{doAction} %{scheduleOrUser}"
-msgstr ""
+msgstr "ENTÃO %{doAction} %{scheduleOrUser}"
msgid "EscalationPolicies|The escalation policy could not be deleted. Please try again."
msgstr ""
@@ -13311,7 +13425,7 @@ msgid "EscalationPolicies|mins"
msgstr ""
msgid "Estimate"
-msgstr ""
+msgstr "Estimativa"
msgid "Estimated"
msgstr "Estimativa"
@@ -13332,7 +13446,7 @@ msgid "EventFilterBy|Filter by issue events"
msgstr "Filtrar por eventos de issue"
msgid "EventFilterBy|Filter by merge events"
-msgstr "Filtrar por eventos de merge"
+msgstr "Filtrar por eventos de mesclar"
msgid "EventFilterBy|Filter by push events"
msgstr "Filtrar por eventos de push"
@@ -13406,7 +13520,7 @@ msgid "Everything you need to create a GitLab Pages site using plain HTML"
msgstr "Tudo o que você precisa para criar um site do GitLab Pages usando HTML simples"
msgid "Evidence collection"
-msgstr ""
+msgstr "Coleção de provas"
msgid "Exactly one of %{attributes} is required"
msgstr ""
@@ -13430,10 +13544,10 @@ msgid "Excess storage"
msgstr "Armazenamento em excesso"
msgid "Excluding merge commits. Limited to %{limit} commits."
-msgstr "Excluindo commits de merge. Limitado a %{limit} commits."
+msgstr "Excluindo commits de mesclar. Limitado a %{limit} commits."
msgid "Excluding merge commits. Limited to 6,000 commits."
-msgstr "Excluindo commits de merge. Limitado a 6.000 commits."
+msgstr "Excluindo commits de mesclar. Limitado a 6.000 commits."
msgid "Execution time"
msgstr "Tempo de execução"
@@ -13478,7 +13592,7 @@ msgid "Expand panel"
msgstr "Expandir painel"
msgid "Expand pipeline"
-msgstr ""
+msgstr "Expandir pipeline"
msgid "Expand sidebar"
msgstr "Expandir barra lateral"
@@ -13487,7 +13601,7 @@ msgid "Expected documents: %{expected_documents}"
msgstr ""
msgid "Experienced"
-msgstr ""
+msgstr "Experiência"
msgid "ExperimentSubject|Must have exactly one of User, Namespace, or Project."
msgstr ""
@@ -13697,7 +13811,7 @@ msgid "Failed to create wiki"
msgstr "Falha ao criar a wiki"
msgid "Failed to deploy to"
-msgstr "Falha ao fazer deploy para"
+msgstr "Falha ao implantar para"
msgid "Failed to enqueue the rebase operation, possibly due to a long-lived transaction. Try again later."
msgstr ""
@@ -13712,7 +13826,7 @@ msgid "Failed to find import label for Jira import."
msgstr ""
msgid "Failed to generate export, please try again later."
-msgstr ""
+msgstr "Não foi possível exportar, tente novamente mais tarde"
msgid "Failed to generate report, please try again after sometime"
msgstr ""
@@ -13736,7 +13850,7 @@ msgid "Failed to load branches. Please try again."
msgstr "Falha ao carregar os branchs. Por favor, tente novamente."
msgid "Failed to load deploy keys."
-msgstr "Falha ao carregar a chave de deploy."
+msgstr "Falha ao carregar a chave de implantação."
msgid "Failed to load emoji list."
msgstr "Falha ao carregar a lista de emojis."
@@ -13805,7 +13919,7 @@ msgid "Failed to publish issue on status page."
msgstr ""
msgid "Failed to register Agent"
-msgstr ""
+msgstr "Falha ao registrar agente"
msgid "Failed to remove a Zoom meeting"
msgstr "Falha ao remover uma reunião do Zoom"
@@ -13832,7 +13946,7 @@ msgid "Failed to retrieve page"
msgstr "Falha ao recuperar a página"
msgid "Failed to save merge conflicts resolutions. Please try again!"
-msgstr "Falha ao salvar resoluções de conflitos de merge. Por favor, tente novamente!"
+msgstr "Falha ao salvar resoluções de conflitos de mesclar. Por favor, tente novamente!"
msgid "Failed to save new settings"
msgstr "Falha ao salvar novas configurações"
@@ -13981,7 +14095,7 @@ msgid "FeatureFlags|Edit Feature Flag"
msgstr "Editar feature flag"
msgid "FeatureFlags|Edit User List"
-msgstr ""
+msgstr "Editar lista de usuários"
msgid "FeatureFlags|Enable features for specific users and environments by configuring feature flag strategies."
msgstr ""
@@ -14029,7 +14143,7 @@ msgid "FeatureFlags|Inactive flag for %{scope}"
msgstr "Sinalizador inativo para %{scope}"
msgid "FeatureFlags|Install a %{docsLinkAnchoredStart}compatible client library%{docsLinkAnchoredEnd} and specify the API URL, application name, and instance ID during the configuration setup. %{docsLinkStart}More Information%{docsLinkEnd}"
-msgstr ""
+msgstr "Instale uma %{docsLinkAnchoredStart}biblioteca de cliente compatível%{docsLinkAnchoredEnd} e especifique o URL da API, o nome do aplicativo e o ID da instância durante a configuração. %{docsLinkStart}Mais informações%{docsLinkEnd}"
msgid "FeatureFlags|Instance ID"
msgstr "ID da instância"
@@ -14059,7 +14173,7 @@ msgid "FeatureFlags|New feature flag"
msgstr "Nova feature flag"
msgid "FeatureFlags|No user list selected"
-msgstr ""
+msgstr "Nenhuma lista de usuários selecionada"
msgid "FeatureFlags|Percent of users"
msgstr ""
@@ -14086,7 +14200,7 @@ msgid "FeatureFlags|There was an error fetching the feature flags."
msgstr "Ocorreu um erro ao buscar as feature flag."
msgid "FeatureFlags|To prevent accidental actions we ask you to confirm your intention. Please type %{projectName} to proceed or close this modal to cancel."
-msgstr ""
+msgstr "Para evitar ações acidentais, pedimos que você confirme sua intenção. Digite %{projectName} para continuar ou feche este modal para cancelar."
msgid "FeatureFlags|Try again in a few moments or contact your support team."
msgstr "Tente novamente daqui a pouco ou entre em contato com a sua equipe de suporte."
@@ -14229,7 +14343,7 @@ msgid "Filter by Git revision"
msgstr "Filtrar pela revisão do Git"
msgid "Filter by issues that are currently closed."
-msgstr ""
+msgstr "Filtrar por issues que estão atualmente fechadas."
msgid "Filter by issues that are currently opened."
msgstr "Filtrar por issues que estão atualmente abertas."
@@ -14292,7 +14406,7 @@ msgid "Find File"
msgstr "Localizar arquivo"
msgid "Find bugs in your code with API fuzzing."
-msgstr ""
+msgstr "Encontre erros no seu código com o API fuzzing."
msgid "Find bugs in your code with coverage-guided fuzzing."
msgstr ""
@@ -14415,13 +14529,13 @@ msgid "For additional information, review your group membership: %{link_to} or c
msgstr ""
msgid "For each job, clone the repository."
-msgstr ""
+msgstr "Para cada tarefa, clone o repositório."
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
msgid "For example, the application using the token or the purpose of the token."
-msgstr ""
+msgstr "Por exemplo, a aplicação usando o token ou o propósito do token."
msgid "For general work"
msgstr ""
@@ -14484,7 +14598,7 @@ msgid "ForkProject|Internal"
msgstr "Interno"
msgid "ForkProject|Please select a namespace"
-msgstr "Por favor selecione um namespace"
+msgstr "Por favor selecione um espaço de nome"
msgid "ForkProject|Please select a visibility level"
msgstr "Por favor selecione o nível de visibilidade"
@@ -14502,7 +14616,7 @@ msgid "ForkProject|Select a namespace"
msgstr "Selecionar um espaço nominal"
msgid "ForkProject|Select a namespace to fork the project"
-msgstr "Selecione um namespace para realizar o fork do projeto"
+msgstr "Selecione um espaço de nome para realizar o fork do projeto"
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr "Forks"
msgid "Format: %{dateFormat}"
msgstr "Formato: %{dateFormat}"
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr "Erros encontrados em seu %{gitlab_ci_yml}:"
@@ -14580,7 +14697,7 @@ msgid "From issue creation until deploy to production"
msgstr "Da abertura de tarefas até a implantação para a produção"
msgid "From merge request merge until deploy to production"
-msgstr "Do merge request até a implantação em produção"
+msgstr "Da solicitação de mesclagem até a implantação em produção"
msgid "Full"
msgstr ""
@@ -14607,7 +14724,7 @@ msgid "General Settings"
msgstr "Configurações gerais"
msgid "General pipelines"
-msgstr "Pipelines Gerais"
+msgstr "Pipelines gerais"
msgid "Generate a default set of labels"
msgstr "Gerar etiquetas padrão"
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr "Genérico"
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr "Filtrar por status"
msgid "Geo|Geo Status"
msgstr "Geo Status"
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr "Última vez verificada"
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr "Status do nó foi atualizado em %{timeAgo}."
-
msgid "Geo|Not synced yet"
msgstr "Ainda não sincronizado"
@@ -14871,7 +14988,7 @@ msgid "Geo|Projects in certain storage shards"
msgstr "Projetos em certos pedaços de armazenamento"
msgid "Geo|Queued"
-msgstr ""
+msgstr "Na fila"
msgid "Geo|Redownload"
msgstr "Baixar novamente"
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr "Remover nó"
-msgid "Geo|Remove secondary node"
-msgstr "Remover nó secundário"
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr "Site secundário"
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr "O status do site foi atualizado em %{timeAgo}."
+
msgid "Geo|Status"
msgstr "Status"
@@ -14978,10 +15095,10 @@ msgstr "Configurações de sincronização"
msgid "Geo|Synchronization status"
msgstr "Status da sincronização"
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr "Aguardando o agendador"
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr "Git"
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr "Git LFS não está habilitado neste servidor GitLab, contate seu administrador."
@@ -15120,7 +15240,7 @@ msgid "Git shallow clone"
msgstr ""
msgid "Git strategy"
-msgstr ""
+msgstr "Estratégia de Git"
msgid "Git transfer in progress"
msgstr ""
@@ -15135,7 +15255,7 @@ msgid "GitHub import"
msgstr "Importação do GitHub"
msgid "GitHubImporter|*Merged by: %{author} at %{timestamp}*"
-msgstr "Merge realizado por: %{author} em %{timestamp}*"
+msgstr "Mesclado por: %{author} em %{timestamp}*"
msgid "GitLab"
msgstr "GitLab"
@@ -15152,9 +15272,6 @@ msgstr "Solicitação de conta do GitLab"
msgid "GitLab Billing Team."
msgstr "Equipe de cobrança do GitLab."
-msgid "GitLab CI"
-msgstr "GitLab CI"
-
msgid "GitLab Import"
msgstr "Importação do GitLab"
@@ -15309,7 +15426,7 @@ msgid "GitLabPages|Removing pages will prevent them from being exposed to the ou
msgstr "Remover páginas evitará que seja exportas ao mundo exterior."
msgid "GitLabPages|Save changes"
-msgstr ""
+msgstr "Salvar alterações"
msgid "GitLabPages|Something went wrong while obtaining the Let's Encrypt certificate for %{domain}. To retry visit your %{link_start}domain details%{link_end}."
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr "Acesso concedido %{time_ago}"
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr "A pesquisa global está desativada para este escopo"
+
msgid "Global Shortcuts"
msgstr "Atalhos Globais"
@@ -15429,7 +15549,7 @@ msgid "Go full screen"
msgstr "Tela cheia"
msgid "Go to %{source_name}"
-msgstr ""
+msgstr "Ir para %{source_name}"
msgid "Go to commits"
msgstr "Ir para commits"
@@ -15471,7 +15591,7 @@ msgid "Go to kubernetes"
msgstr "Ir para kubernetes"
msgid "Go to merge requests"
-msgstr "Ir para merge requests"
+msgstr "Ir para solicitações de mesclagem"
msgid "Go to metrics"
msgstr "Ir para métricas"
@@ -15485,8 +15605,8 @@ msgstr ""
msgid "Go to previous page"
msgstr "Voltar para a página anterior"
-msgid "Go to primary node"
-msgstr "Ir para o nó primário"
+msgid "Go to primary site"
+msgstr "Ir para o site primário"
msgid "Go to project"
msgstr "Ir para o projeto"
@@ -15531,7 +15651,7 @@ msgid "Go to your issues"
msgstr "Ir para seus issues"
msgid "Go to your merge requests"
-msgstr "Ir para seus merge requests"
+msgstr "Ir para suas solicitações de mesclagem"
msgid "Go to your projects"
msgstr "Ir para seus projetos"
@@ -15672,7 +15792,7 @@ msgid "Group export link has expired. Please generate a new export from your gro
msgstr ""
msgid "Group export requests"
-msgstr ""
+msgstr "Requisições de exportação de grupo"
msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
@@ -15687,7 +15807,7 @@ msgid "Group import could not be scheduled"
msgstr ""
msgid "Group import requests"
-msgstr ""
+msgstr "Requisições de importação de grupo"
msgid "Group info:"
msgstr "Info. do grupo:"
@@ -15702,7 +15822,7 @@ msgid "Group jobs by"
msgstr "Grupo de tarefas por"
msgid "Group maintainers can register group runners in the %{link}"
-msgstr "Os mantenedores podem registrar grupos de runners em %{link}"
+msgstr "Os mantenedores podem registrar grupos de executores em %{link}"
msgid "Group members"
msgstr "Membros do grupo"
@@ -15747,7 +15867,7 @@ msgid "Group requires separate account"
msgstr "Grupo requer uma conta separada"
msgid "Group runners"
-msgstr ""
+msgstr "Executores de grupo"
msgid "Group runners can be managed with the %{link}."
msgstr ""
@@ -15780,7 +15900,7 @@ msgid "GroupActivityMetrics|Members added"
msgstr "Membros adicionados"
msgid "GroupActivityMetrics|Merge Requests opened"
-msgstr ""
+msgstr "Solicitações de mesclagem abertas"
msgid "GroupActivityMetrics|Recent activity"
msgstr "Atividade recente"
@@ -15836,6 +15956,12 @@ msgstr "Desculpe, nenhum epic corresponde à sua pesquisa"
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr "O roadmap mostra o progresso de seus epics ao longo de uma linha do tempo"
+msgid "GroupRoadmap|This quarter"
+msgstr "Este trimestre"
+
+msgid "GroupRoadmap|This year"
+msgstr "Este ano"
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr "Para visualizar o planejamento, adicione uma data de início ou de venci
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr "Para expandir a sua pesquisa, altere ou remova filtros; de %{startDate} para %{endDate}."
+msgid "GroupRoadmap|Within 3 years"
+msgstr "Dentro de 3 anos"
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16032,7 +16161,7 @@ msgid "GroupSettings|Changing group URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
-msgstr ""
+msgstr "Frameworks de conformidade"
msgid "GroupSettings|Configure frameworks to apply enforceable rules to projects."
msgstr ""
@@ -16044,7 +16173,7 @@ msgid "GroupSettings|Customize this group's badges."
msgstr ""
msgid "GroupSettings|Default to Auto DevOps pipeline for all projects within this group"
-msgstr ""
+msgstr "Padrão para pipeline de Auto DevOps para todos os projetos dentro deste grupo"
msgid "GroupSettings|Disable email notifications"
msgstr ""
@@ -16065,7 +16194,7 @@ msgid "GroupSettings|If the parent group's visibility is lower than the group cu
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
-msgstr ""
+msgstr "Um novo token de registro de executores foi gerado!"
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16098,7 +16227,7 @@ msgid "GroupSettings|Set the maximum size of GitLab Pages for this group. %{link
msgstr ""
msgid "GroupSettings|The Auto DevOps pipeline runs if no alternative CI configuration file is found."
-msgstr ""
+msgstr "O pipeline de Auto DevOps é executado se nenhum arquivo de configuração de CI for encontrado."
msgid "GroupSettings|The default name for the initial branch of new repositories created in the group."
msgstr ""
@@ -16107,7 +16236,7 @@ msgid "GroupSettings|The projects in this subgroup can be selected as templates
msgstr ""
msgid "GroupSettings|There was a problem updating Auto DevOps pipeline: %{error_messages}."
-msgstr ""
+msgstr "Houve um problema ao atualizar o pipeline de Auto DevOps: %{error_messages}."
msgid "GroupSettings|There was a problem updating the pipeline settings: %{error_messages}."
msgstr ""
@@ -16230,13 +16359,13 @@ msgid "GroupsNew|Create new group"
msgstr "Criar novo grupo"
msgid "GroupsNew|Export groups with all their related data and move to a new GitLab instance."
-msgstr ""
+msgstr "Exportar grupos com todos os seus dados relacionados e mova para uma nova instância do GitLab."
msgid "GroupsNew|GitLab source URL"
msgstr "URL da fonte do GitLab"
msgid "GroupsNew|Groups can also be nested by creating %{linkStart}subgroups%{linkEnd}."
-msgstr ""
+msgstr "Grupos também podem ser aninhados criando %{linkStart}subgrupos%{linkEnd}."
msgid "GroupsNew|Import group"
msgstr "Importar grupo"
@@ -16266,7 +16395,7 @@ msgid "GroupsNew|Please fill in your personal access token."
msgstr "Por favor preencha o seu token de acesso pessoal"
msgid "GroupsNew|Provide credentials for another instance of GitLab to import your groups directly."
-msgstr ""
+msgstr "Forneça as credenciais para outra instância do GitLab para importar seus grupos diretamente."
msgid "GroupsNew|To import a group, navigate to the group settings for the GitLab source instance, %{link_start}generate an export file%{link_end}, and upload it here."
msgstr ""
@@ -16341,19 +16470,19 @@ msgid "Header must be associated with a request or response"
msgstr ""
msgid "Heading 1"
-msgstr ""
+msgstr "Título 1"
msgid "Heading 2"
-msgstr ""
+msgstr "Título 2"
msgid "Heading 3"
-msgstr ""
+msgstr "Título 3"
msgid "Heading 4"
-msgstr ""
+msgstr "Título 4"
msgid "Headings"
-msgstr ""
+msgstr "Títulos"
msgid "Health"
msgstr ""
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16534,7 +16663,7 @@ msgid "Housekeeping, export, path, transfer, remove, archive."
msgstr "Manutenção, exportação, caminho, transferência, remoção e arquivamento."
msgid "How do I configure runners?"
-msgstr ""
+msgstr "Como eu configuro os executores?"
msgid "How do I configure this integration?"
msgstr ""
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr "Como faço para renomear um ambiente?"
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16564,7 +16696,7 @@ msgid "I accept the %{terms_link}"
msgstr "Eu aceito o %{terms_link}"
msgid "I accept the|Terms of Service and Privacy Policy"
-msgstr "Termos de Serviço e Política de Privacidade"
+msgstr "Eu aceito os|termos de serviço e política de privacidade"
msgid "I forgot my password"
msgstr "Esqueci minha senha"
@@ -16683,7 +16815,7 @@ msgstr "Se desativada, um branch local divergente não será atualizada automati
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16904,7 +17036,7 @@ msgid "ImportProjects|%{provider} rate limit exceeded. Try again later"
msgstr ""
msgid "ImportProjects|Blocked import URL: %{message}"
-msgstr ""
+msgstr "URL de importação bloqueada: %{message}"
msgid "ImportProjects|Error importing repository %{project_safe_import_url} into %{project_full_path} - %{message}"
msgstr ""
@@ -16971,6 +17103,9 @@ msgstr "Em andamento"
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17089,7 +17224,7 @@ msgid "InProductMarketing|Follow our steps"
msgstr ""
msgid "InProductMarketing|Free 30-day trial"
-msgstr ""
+msgstr "Avaliação gratuita de 30 dias"
msgid "InProductMarketing|Get going with CI/CD quickly using our %{quick_start_link}. Start with an available runner and then create a CI .yml file – it's really that easy."
msgstr ""
@@ -17104,7 +17239,7 @@ msgid "InProductMarketing|Get started today with a 30-day GitLab Ultimate trial,
msgstr ""
msgid "InProductMarketing|Get started with GitLab CI/CD"
-msgstr ""
+msgstr "Primeiros passos com GitLab CI/CD"
msgid "InProductMarketing|Get to know GitLab CI/CD"
msgstr ""
@@ -17371,7 +17506,7 @@ msgid "InProductMarketing|connect an external repository"
msgstr ""
msgid "InProductMarketing|create a project"
-msgstr ""
+msgstr "criar um projeto"
msgid "InProductMarketing|from Bitbucket"
msgstr ""
@@ -17443,7 +17578,7 @@ msgid "IncidentManagement|Closed"
msgstr "Fechado"
msgid "IncidentManagement|Create incident"
-msgstr ""
+msgstr "Criar incidente"
msgid "IncidentManagement|Critical - S1"
msgstr ""
@@ -17452,7 +17587,7 @@ msgid "IncidentManagement|Date created"
msgstr ""
msgid "IncidentManagement|Display your incidents in a dedicated view"
-msgstr ""
+msgstr "Exibir seus incidentes em uma visão dedicada"
msgid "IncidentManagement|High - S2"
msgstr ""
@@ -17479,7 +17614,7 @@ msgid "IncidentManagement|Open"
msgstr ""
msgid "IncidentManagement|Published"
-msgstr ""
+msgstr "Publicado"
msgid "IncidentManagement|Published to status page"
msgstr ""
@@ -17503,7 +17638,7 @@ msgid "IncidentManagement|Unknown"
msgstr ""
msgid "IncidentManagement|Unpublished"
-msgstr ""
+msgstr "Não publicado"
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -17599,7 +17734,7 @@ msgid "Include description in commit message"
msgstr ""
msgid "Include merge request description"
-msgstr "Incluir a descrição do merge request"
+msgstr "Incluir a descrição da solicitação de mesclagem"
msgid "Include new features from all tiers."
msgstr ""
@@ -17614,13 +17749,13 @@ msgid "Includes LFS objects. It can be overridden per group, or per project. 0 f
msgstr "Inclui objetos LFS. Pode ser substituído individualmente por grupo ou por projeto. 0 para ilimitado."
msgid "Includes an MVC structure to help you get started"
-msgstr ""
+msgstr "Inclui uma estrutura MVC para ajudar você a começar"
msgid "Includes an MVC structure, Gemfile, Rakefile, along with many others, to help you get started"
-msgstr ""
+msgstr "Inclui uma estrutura MVC, um Gemfile, um Rakefile e muito mais para ajudar você a começar"
msgid "Includes an MVC structure, mvnw and pom.xml to help you get started"
-msgstr ""
+msgstr "Inclui uma estrutura MVC, mvnw e um pom.xml para ajudar você a começar"
msgid "Incoming email"
msgstr ""
@@ -17653,13 +17788,13 @@ msgid "Index deletion is canceled"
msgstr ""
msgid "Indicates whether this runner can pick jobs without tags"
-msgstr "Indica se este runner pode escolher tarefas sem tags"
+msgstr "Indica se este executor pode escolher tarefas sem tags"
msgid "Inform users without uploaded SSH keys that they can't push over SSH until one is added"
msgstr "Informar aos usuários sem chaves SSH configuradas que eles não podem realizar pushes por SSH até que uma seja adicionada"
msgid "Infrastructure"
-msgstr ""
+msgstr "Infraestrutura"
msgid "Infrastructure Registry"
msgstr "Registro de infraestrutura"
@@ -17680,10 +17815,10 @@ msgid "InfrastructureRegistry|Infrastructure Registry"
msgstr "Registro de infraestrutura"
msgid "InfrastructureRegistry|Publish and share your modules. %{docLinkStart}More information%{docLinkEnd}"
-msgstr ""
+msgstr "Publique e compartilhe seus módulos. %{docLinkStart}Mais informações%{docLinkEnd}"
msgid "InfrastructureRegistry|Terraform"
-msgstr ""
+msgstr "Terraform"
msgid "InfrastructureRegistry|Terraform modules are the main way to package and reuse resource configurations with Terraform. Learn more about how to %{noPackagesLinkStart}create Terraform modules%{noPackagesLinkEnd} in GitLab."
msgstr ""
@@ -17692,7 +17827,7 @@ msgid "InfrastructureRegistry|To authorize access to the Terraform registry:"
msgstr ""
msgid "InfrastructureRegistry|You have no Terraform modules in your project"
-msgstr ""
+msgstr "Você não tem módulos do Terraform em seu projeto"
msgid "Inherited"
msgstr "Herdado"
@@ -17713,7 +17848,7 @@ msgid "Insert"
msgstr "Inserir"
msgid "Insert a %{rows}x%{cols} table."
-msgstr ""
+msgstr "Inserir uma tabela %{rows}x%{cols}."
msgid "Insert a code block"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr "Inserir uma imagem"
msgid "Insert code"
msgstr "Inserir código"
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr "Insira coluna antes"
+
msgid "Insert image"
msgstr "Inserir imagem"
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr "Inserir linha acima"
+
+msgid "Insert row before"
+msgstr "Inserir linha abaixo"
+
msgid "Insert suggestion"
msgstr "Inserir sugestão"
@@ -17755,7 +17902,7 @@ msgid "Insights|This project is filtered out in the insights.yml file (see the p
msgstr ""
msgid "Install GitLab Runner and ensure it's running."
-msgstr ""
+msgstr "Instale o GitLab Runner e verifique se está em execução."
msgid "Install on clusters"
msgstr "Instalar em clusters"
@@ -17817,7 +17964,7 @@ msgid "Integrations|Add an integration"
msgstr "Adicionar uma integração"
msgid "Integrations|Add namespace"
-msgstr "Adicionar namespace"
+msgstr "Adicionar espaço de nome"
msgid "Integrations|Adding a namespace works only in browsers that allow cross‑site cookies. Use %{firefox_link_start}Firefox%{link_end}, %{chrome_link_start}Google Chrome%{link_end}, or enable cross‑site cookies in your browser, when adding a namespace."
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr "Todos os detalhes"
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr "Limitações do navegador"
@@ -17928,7 +18078,7 @@ msgid "Integrations|Resetting this integration will clear the settings and deact
msgstr ""
msgid "Integrations|Return to GitLab for Jira"
-msgstr ""
+msgstr "Voltar ao GitLab para Jira"
msgid "Integrations|Save settings?"
msgstr "Salvar configurações?"
@@ -17937,22 +18087,25 @@ msgid "Integrations|Saving will update the default settings for all projects tha
msgstr ""
msgid "Integrations|Search Jira issues"
-msgstr ""
+msgstr "Pesquisar issues do Jira"
msgid "Integrations|Send notifications about project events to Unify Circuit."
msgstr ""
msgid "Integrations|Sign in to add namespaces"
-msgstr "Entre para adicionar namespaces"
+msgstr "Entre para adicionar espaço de nome"
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
msgid "Integrations|To keep this project going, create a new issue."
-msgstr ""
+msgstr "Para manter este projeto em andamento, crie uma nova issue."
msgid "Integrations|Use custom settings"
msgstr "Usar configurações personalizadas"
@@ -17967,7 +18120,7 @@ msgid "Integrations|You can now close this window and return to the GitLab for J
msgstr ""
msgid "Integrations|You haven't activated any integrations yet."
-msgstr ""
+msgstr "Você ainda não ativou nenhuma integração."
msgid "Integrations|You must have owner or maintainer permissions to link namespaces."
msgstr ""
@@ -17991,7 +18144,7 @@ msgid "Internal - The group and any internal projects can be viewed by any logge
msgstr ""
msgid "Internal - The project can be accessed by any logged in user except external users."
-msgstr ""
+msgstr "Interno - O projeto pode ser acessado por qualquer usuário entrado, exceto usuários externos."
msgid "Internal URL (optional)"
msgstr "URL interno (opcional)"
@@ -18036,7 +18189,7 @@ msgid "Invalid date format. Please use UTC format as YYYY-MM-DD"
msgstr ""
msgid "Invalid date range"
-msgstr ""
+msgstr "Intervalo de datas inválido"
msgid "Invalid feature"
msgstr "Funcionalidade inválida"
@@ -18072,7 +18225,7 @@ msgid "Invalid pod_name"
msgstr ""
msgid "Invalid policy type"
-msgstr ""
+msgstr "Tipo de política inválido"
msgid "Invalid query"
msgstr "Consulta inválida"
@@ -18137,9 +18290,6 @@ msgstr "Convidar membro"
msgid "Invite members"
msgstr "Convidar membros"
-msgid "Invite your team"
-msgstr "Convidar sua equipe"
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18198,13 +18348,13 @@ msgid "InviteMembersModal|Collaborate on open issues and merge requests"
msgstr ""
msgid "InviteMembersModal|Configure CI/CD"
-msgstr ""
+msgstr "Configurar CI/CD"
msgid "InviteMembersModal|Configure security features"
-msgstr ""
+msgstr "Configurar funcionalidades de segurança"
msgid "InviteMembersModal|Contribute to the codebase"
-msgstr ""
+msgstr "Contribua com a base de código"
msgid "InviteMembersModal|GitLab member or email address"
msgstr "Membro do GitLab ou endereço de e-mail"
@@ -18222,7 +18372,7 @@ msgid "InviteMembersModal|Members were successfully added"
msgstr "Membros foram adicionados com sucesso"
msgid "InviteMembersModal|Other"
-msgstr ""
+msgstr "Outro"
msgid "InviteMembersModal|Search for a group to invite"
msgstr ""
@@ -18267,7 +18417,7 @@ msgid "InviteMember|Invite Member"
msgstr ""
msgid "InviteMember|Invite Members (optional)"
-msgstr ""
+msgstr "Convidar membros (opcional)"
msgid "InviteMember|Invite another member"
msgstr ""
@@ -18279,7 +18429,7 @@ msgid "InviteMember|Invite your team"
msgstr ""
msgid "InviteMember|Invited users will be added with developer level permissions. %{linkStart}View the documentation%{linkEnd} to see how to change this later."
-msgstr ""
+msgstr "Os usuários convidados serão adicionados com permissões de nível de desenvolvedor. %{linkStart}Veja a documentação%{linkEnd} para ver como alterar isso mais tarde."
msgid "InviteReminderEmail|%{inviter} is still waiting for you to join GitLab"
msgstr ""
@@ -18417,7 +18567,7 @@ msgid "Issue created from vulnerability %{vulnerability_link}"
msgstr ""
msgid "Issue creation requests"
-msgstr ""
+msgstr "Requisições de criação de issue"
msgid "Issue details"
msgstr ""
@@ -18459,7 +18609,7 @@ msgid "IssueAnalytics|Assignees"
msgstr "Responsáveis"
msgid "IssueAnalytics|Due date"
-msgstr "Data limite"
+msgstr "Validade"
msgid "IssueAnalytics|Failed to load issues. Please try again."
msgstr "Falha ao carregar as issues. Por favor, tente novamente."
@@ -18510,7 +18660,7 @@ msgid "IssueTracker|Issue URL"
msgstr "URL do issue"
msgid "IssueTracker|New issue URL"
-msgstr ""
+msgstr "Novo URL da issue"
msgid "IssueTracker|The URL to create an issue in the external issue tracker."
msgstr ""
@@ -18564,7 +18714,7 @@ msgid "Issues Rate Limits"
msgstr ""
msgid "Issues and merge requests"
-msgstr ""
+msgstr "Issues e solicitações de mesclagem"
msgid "Issues can be bugs, tasks or ideas to be discussed. Also, issues are searchable and filterable."
msgstr "Issues podem ser bugs, tarefas ou ideias a serem discutidas. Além disso, issues são pesquisáveis e filtráveis."
@@ -18579,16 +18729,16 @@ msgid "Issues must match this scope to appear in this list."
msgstr ""
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
-msgstr "Issues com comentários, merge requests com diffs e comentários, etiquetas, marcos, snippets e outras entidades do projeto"
+msgstr "Issues com comentários, solicitações de mesclagem com diffs e comentários, etiquetas, marcos, snippets e outras entidades do projeto"
msgid "Issues with label %{label}"
-msgstr ""
+msgstr "Issues com a etiqueta %{label}"
msgid "Issues with no epic assigned"
-msgstr ""
+msgstr "Issues com nenhum épico atribuído"
msgid "Issues, merge requests, pushes, and comments."
-msgstr "Issues, merge requests, pushes e comentários."
+msgstr "Issues, solicitações de mesclagem, pushes e comentários."
msgid "IssuesAnalytics|After you begin creating issues for your projects, we can start tracking and displaying metrics for them"
msgstr "Depois que você começa a criar issues para seus projetos, podemos começar a acompanhar e exibir métricas para elas"
@@ -18636,7 +18786,7 @@ msgid "It seems like the Dependency Scanning job ran successfully, but no depend
msgstr ""
msgid "It seems that there is currently no available data for code coverage"
-msgstr ""
+msgstr "Parece que atualmente não há dados disponíveis para cobertura de código"
msgid "It's you"
msgstr "É você"
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr "Crie sua primeira iteração"
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -18690,7 +18843,7 @@ msgid "Iterations|Edit cadence"
msgstr ""
msgid "Iterations|Edit iteration"
-msgstr ""
+msgstr "Editar iteração"
msgid "Iterations|Edit iteration cadence"
msgstr ""
@@ -18792,25 +18945,25 @@ msgid "Jira Issues"
msgstr "Issues do Jira"
msgid "Jira display name"
-msgstr ""
+msgstr "Nome de exibição Jira"
msgid "Jira import is already running."
-msgstr ""
+msgstr "A importação do Jira já está em execução."
msgid "Jira integration not configured."
msgstr "Integração com o Jira não configurada."
msgid "Jira project key is not configured."
-msgstr ""
+msgstr "A chave do projeto do Jira não está configurada."
msgid "Jira project: %{importProject}"
msgstr "Projeto Jira: %{importProject}"
msgid "Jira service not configured."
-msgstr ""
+msgstr "Serviço do Jira não está configurado."
msgid "Jira user"
-msgstr ""
+msgstr "Usuário do Jira"
msgid "Jira users have been imported from the configured Jira instance. They can be mapped by selecting a GitLab user from the dropdown in the \"GitLab username\" column. When the form appears, the dropdown defaults to the user conducting the import."
msgstr ""
@@ -18858,19 +19011,19 @@ msgid "JiraRequest|The credentials for accessing Jira are not valid. Check your
msgstr ""
msgid "JiraService| on branch %{branch_link}"
-msgstr ""
+msgstr "na ramificação %{branch_link}"
msgid "JiraService|%{jiraDocsLinkStart}Enable the Jira integration%{jiraDocsLinkEnd} to view your Jira issues in GitLab."
-msgstr ""
+msgstr "%{jiraDocsLinkStart}Ativar integração do Jira%{jiraDocsLinkEnd} para visualizar suas issues do Jira no GitLab."
msgid "JiraService|%{jira_docs_link_start}Enable the Jira integration%{jira_docs_link_end} to view your Jira issues in GitLab."
-msgstr ""
+msgstr "%{jira_docs_link_start}Ativar integração do Jira%{jira_docs_link_end} para visualizar suas issues do Jira no GitLab."
msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr "%{user_link} mensionou essa issue em %{entity_link} de %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgid "JiraService|An error occurred while fetching issue list"
-msgstr ""
+msgstr "Ocorreu um erro ao obter a lista de issue"
msgid "JiraService|Automatically transitions Jira issues to the \"Done\" category. %{linkStart}Learn more%{linkEnd}"
msgstr ""
@@ -18885,16 +19038,16 @@ msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functio
msgstr ""
msgid "JiraService|Enable Jira issues"
-msgstr ""
+msgstr "Ativar issues do Jira"
msgid "JiraService|Enable Jira issues creation from vulnerabilities"
msgstr ""
msgid "JiraService|Enable Jira transitions"
-msgstr ""
+msgstr "Ativar transições do Jira"
msgid "JiraService|Enter new password or API token"
-msgstr ""
+msgstr "Digite uma nova senha ou token de API"
msgid "JiraService|Events for %{noteable_model_name} are disabled."
msgstr "Eventos para %{noteable_model_name} estão desabilitados."
@@ -18915,13 +19068,13 @@ msgid "JiraService|Fetch issue types for this Jira project"
msgstr ""
msgid "JiraService|For example, 12, 24"
-msgstr ""
+msgstr "Por exemplo, 12, 24"
msgid "JiraService|For example, AB"
-msgstr ""
+msgstr "Por exemplo, AB"
msgid "JiraService|GitLab for Jira Configuration"
-msgstr ""
+msgstr "GitLab para configuração do Jira"
msgid "JiraService|IDs must be a list of numbers that can be split with , or ;"
msgstr ""
@@ -18930,7 +19083,7 @@ msgid "JiraService|If different from Web URL."
msgstr ""
msgid "JiraService|Issue List"
-msgstr ""
+msgstr "Lista de issue"
msgid "JiraService|Issues created from vulnerabilities in this project will be Jira issues, even if GitLab issues are enabled."
msgstr ""
@@ -18939,7 +19092,7 @@ msgid "JiraService|Jira API URL"
msgstr "URL da API do JIRA"
msgid "JiraService|Jira Issues"
-msgstr ""
+msgstr "Issues do Jira"
msgid "JiraService|Jira comments are created when an issue is referenced in a commit."
msgstr ""
@@ -18948,25 +19101,25 @@ msgid "JiraService|Jira comments are created when an issue is referenced in a me
msgstr ""
msgid "JiraService|Jira issue type"
-msgstr ""
+msgstr "Tipo de issue do Jira"
msgid "JiraService|Jira project key"
-msgstr ""
+msgstr "Chave do projeto do Jira"
msgid "JiraService|Leave blank to use your current password or API token."
msgstr ""
msgid "JiraService|Move to Done"
-msgstr ""
+msgstr "Mover para Concluído"
msgid "JiraService|No available statuses"
-msgstr ""
+msgstr "Nenhum status disponível"
msgid "JiraService|Not all data may be displayed here. To view more details or make changes to this issue, go to %{linkStart}Jira%{linkEnd}."
msgstr ""
msgid "JiraService|Open Jira"
-msgstr ""
+msgstr "Abrir Jira"
msgid "JiraService|Password or API token"
msgstr "Senha ou token de API"
@@ -18978,25 +19131,25 @@ msgid "JiraService|Project key is required to generate issue types"
msgstr ""
msgid "JiraService|Select issue type"
-msgstr ""
+msgstr "Selecionar tipo de issue"
msgid "JiraService|Set a custom final state by using transition IDs. %{linkStart}Learn about transition IDs%{linkEnd}"
msgstr ""
msgid "JiraService|Sign in to GitLab.com to get started."
-msgstr ""
+msgstr "Entre no GitLab.com para começar."
msgid "JiraService|This feature requires a Premium plan."
-msgstr ""
+msgstr "Essa funcionalidade requer um plano Premium."
msgid "JiraService|This is a Premium feature"
-msgstr ""
+msgstr "Este é um recurso Premium"
msgid "JiraService|This is an Ultimate feature"
-msgstr ""
+msgstr "Este é um recurso Ultimate"
msgid "JiraService|This issue is synchronized with Jira"
-msgstr ""
+msgstr "Essa issue está sincronizado com o Jira"
msgid "JiraService|Transition Jira issues to their final state:"
msgstr ""
@@ -19014,13 +19167,13 @@ msgid "JiraService|Use a username for server version and an email for cloud vers
msgstr ""
msgid "JiraService|Use custom transitions"
-msgstr ""
+msgstr "Usar transições personalizadas"
msgid "JiraService|Username or Email"
msgstr "Nome de usuário ou e-mail"
msgid "JiraService|Using Jira for issue tracking?"
-msgstr ""
+msgstr "Usando Jira para rastreamento de problemas?"
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
@@ -19065,10 +19218,10 @@ msgid "Job is missing the `model_type` argument."
msgstr "A tarefa não possui o argumento `model_type`."
msgid "Job is stuck. Check runners."
-msgstr "A tarefa travou. Verifique os runners."
+msgstr "A tarefa travou. Verifique os executores."
msgid "Job logs and artifacts"
-msgstr "Logs e artefatos da tarefa"
+msgstr "Registros e artefatos da tarefa"
msgid "Job to create self-monitoring project is in progress"
msgstr ""
@@ -19095,7 +19248,7 @@ msgid "Jobs|Are you sure you want to retry this job?"
msgstr ""
msgid "Jobs|Create CI/CD configuration file"
-msgstr ""
+msgstr "Criar arquivo de configuração de CI/CD"
msgid "Jobs|Job is stuck. Check runners."
msgstr ""
@@ -19104,7 +19257,7 @@ msgid "Jobs|Jobs are the building blocks of a GitLab CI/CD pipeline. Each job ha
msgstr ""
msgid "Jobs|No jobs to show"
-msgstr ""
+msgstr "Nenhuma tarefa para mostrar"
msgid "Jobs|Use jobs to automate your tasks"
msgstr ""
@@ -19131,7 +19284,7 @@ msgid "Job|Job has been erased"
msgstr "A tarefa foi apagada"
msgid "Job|Job has been erased by %{userLink}"
-msgstr ""
+msgstr "Ttarefa foi apagada por %{userLink}"
msgid "Job|Keep"
msgstr "Manter"
@@ -19161,7 +19314,7 @@ msgid "Job|This job failed because the necessary resources were not successfully
msgstr "Esta tarefa falhou porque os recursos necessários não foram criados com sucesso."
msgid "Job|This job is stuck because the project doesn't have any runners online assigned to it."
-msgstr "Essa tarefa travou porque o projeto não tem qualquer runner online atribuído a ela."
+msgstr "Essa tarefa travou porque o projeto não tem qualquer executor online atribuído a ela."
msgid "Job|This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
@@ -19170,10 +19323,10 @@ msgid "Job|This job is stuck because you don't have any active runners that can
msgstr ""
msgid "Job|allowed to fail"
-msgstr ""
+msgstr "permitido falhar"
msgid "Job|delayed"
-msgstr ""
+msgstr "atrasado"
msgid "Job|for"
msgstr "para"
@@ -19182,7 +19335,7 @@ msgid "Job|into"
msgstr "para"
msgid "Job|manual"
-msgstr ""
+msgstr "manual"
msgid "Job|triggered"
msgstr ""
@@ -19218,7 +19371,7 @@ msgid "June"
msgstr "Junho"
msgid "Just me"
-msgstr ""
+msgstr "Apenas eu"
msgid "K8s pod health"
msgstr ""
@@ -19230,13 +19383,13 @@ msgid "Keep"
msgstr ""
msgid "Keep artifacts from most recent successful jobs"
-msgstr ""
+msgstr "Manter artefatos de tarefas com sucesso mais recentes"
msgid "Keep divergent refs"
msgstr ""
msgid "Keep editing"
-msgstr ""
+msgstr "Manter edição"
msgid "Keeping all SAST analyzers enabled future-proofs the project in case new languages are added later on. Determining which analyzers apply is a process that consumes minimal resources and adds minimal time to the pipeline. Leaving all SAST analyzers enabled ensures maximum coverage."
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr "Etiqueta"
msgid "Label actions dropdown"
msgstr "Dropdown de ações de etiqueta"
-msgid "Label lists show all issues with the selected label."
-msgstr "Listas de etiqueta mostram todas as issues com a etiqueta selecionada."
-
msgid "Label priority"
msgstr ""
@@ -19401,10 +19551,10 @@ msgid "Labels can be applied to %{features}. Group labels are available for any
msgstr "Etiquetas podem ser aplicadas à %{features}. Etiquetas de grupo estão disponíveis para qualquer projeto dentro do grupo."
msgid "Labels can be applied to issues and merge requests to categorize them."
-msgstr "Etiquetas podem ser aplicadas a issues e merge requests para categorizá-los."
+msgstr "Etiquetas podem ser aplicadas a issues e solicitações de mesclagem para categorizá-los."
msgid "Labels can be applied to issues and merge requests."
-msgstr "Etiquetas podem ser aplicadas a issues e merge requests."
+msgstr "Etiquetas podem ser aplicadas a issues e solicitações de mesclagem."
msgid "Labels with no issues in this iteration:"
msgstr "Etiquetas sem issues nesta iteração:"
@@ -19430,10 +19580,10 @@ msgstr[0] "Último %d dia"
msgstr[1] "Últimos %d dias"
msgid "Last %{days} days"
-msgstr ""
+msgstr "Últimos %{days} dias"
msgid "Last 2 weeks"
-msgstr ""
+msgstr "Últimas 2 semanas"
msgid "Last 30 days"
msgstr "Últimos 30 dias"
@@ -19445,7 +19595,7 @@ msgid "Last 90 days"
msgstr "Últimos 90 dias"
msgid "Last Accessed On"
-msgstr ""
+msgstr "Acessado pela última vez em"
msgid "Last Activity"
msgstr "Última atividade"
@@ -19484,7 +19634,7 @@ msgid "Last modified"
msgstr "Última modificação"
msgid "Last month"
-msgstr ""
+msgstr "Último mês"
msgid "Last name"
msgstr "Último nome"
@@ -19495,9 +19645,6 @@ msgstr "Última resposta de"
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr "Visto pela última vez"
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr "Última atualização bem-sucedida"
+msgid "Last time checked"
+msgstr "Última vez verificado"
+
msgid "Last time verified"
msgstr ""
@@ -19538,10 +19688,10 @@ msgid "Last used on:"
msgstr "Última utilização em:"
msgid "Last week"
-msgstr ""
+msgstr "Última semana"
msgid "Last year"
-msgstr ""
+msgstr "Último ano"
msgid "LastCommit|authored"
msgstr "Autor"
@@ -19574,7 +19724,7 @@ msgid "Learn GitLab - Ultimate trial"
msgstr ""
msgid "Learn GitLab|Trial only"
-msgstr ""
+msgstr "Apenas para avaliação"
msgid "Learn More"
msgstr "Saiba mais"
@@ -19619,7 +19769,7 @@ msgid "Learn more about deploying to AWS"
msgstr ""
msgid "Learn more about deploying to a cluster"
-msgstr ""
+msgstr "Saiba mais sobre como fazer deploy para um cluster"
msgid "Learn more about group-level project templates"
msgstr "Saiba mais sobre os modelos de projeto de nível de grupo"
@@ -19652,22 +19802,22 @@ msgid "LearnGitLab|Complete these tasks first so you can enjoy GitLab's features
msgstr ""
msgid "LearnGitLab|Create a workflow for your new workspace, and learn how GitLab features work together:"
-msgstr ""
+msgstr "Crie um fluxo de trabalho para seu novo espaço de trabalho e aprenda como os recursos do GitLab funcionam juntos:"
msgid "LearnGitLab|Create an issue"
msgstr ""
msgid "LearnGitLab|Create or import a repository"
-msgstr ""
+msgstr "Criar ou importar um repositório"
msgid "LearnGitLab|Create or import your first repository into your new project."
-msgstr ""
+msgstr "Crie ou importe seu primeiro repositório em seu novo projeto."
msgid "LearnGitLab|Create/import issues (tickets) to collaborate on ideas and plan work."
msgstr ""
msgid "LearnGitLab|Deploy"
-msgstr "Deploy"
+msgstr "Implantar"
msgid "LearnGitLab|Enable require merge approvals"
msgstr ""
@@ -19778,7 +19928,7 @@ msgid "Let's talk!"
msgstr ""
msgid "License Compliance"
-msgstr ""
+msgstr "License Compliance"
msgid "License file"
msgstr ""
@@ -19829,8 +19979,8 @@ msgstr[1] ""
msgid "LicenseCompliance|License Compliance detected %d license and policy violation for the source branch only; approval required"
msgid_plural "LicenseCompliance|License Compliance detected %d licenses and policy violations for the source branch only; approval required"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "License Compliance detectou %d violação de licença e política apenas para a filial de origem; aprovação necessária"
+msgstr[1] "License Compliance detectou %d licenças e violações de política apenas para a filial de origem; aprovação necessária"
msgid "LicenseCompliance|License Compliance detected %d license for the source branch only"
msgid_plural "LicenseCompliance|License Compliance detected %d licenses for the source branch only"
@@ -19839,8 +19989,8 @@ msgstr[1] "License Compliance detectou %d licenças apenas para o branch de orig
msgid "LicenseCompliance|License Compliance detected %d new license"
msgid_plural "LicenseCompliance|License Compliance detected %d new licenses"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "License Compliance detectou %d nova licença"
+msgstr[1] "License Compliance detectou %d novas licenças"
msgid "LicenseCompliance|License Compliance detected %d new license and policy violation"
msgid_plural "LicenseCompliance|License Compliance detected %d new licenses and policy violations"
@@ -19925,7 +20075,7 @@ msgid "Licenses|Error fetching the license list. Please check your network conne
msgstr ""
msgid "Licenses|License Compliance"
-msgstr ""
+msgstr "Licença de conformidade"
msgid "Licenses|Name"
msgstr "Nome"
@@ -19943,10 +20093,10 @@ msgid "Licenses|Specified policies in this project"
msgstr ""
msgid "Licenses|The license list details information about the licenses used within your project."
-msgstr ""
+msgstr "A lista de licenças detalha informações sobre as licenças usadas em seu projeto."
msgid "Licenses|View license details for your project"
-msgstr ""
+msgstr "Ver os detalhes da licença do seu projeto"
msgid "Limit display of time tracking units to hours."
msgstr "Limita a exibição de unidades de acompanhamento de tempo a horas."
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -19969,7 +20122,7 @@ msgstr[0] "Limitado a mostrar %d evento, no máximo"
msgstr[1] "Limitado a mostrar %d eventos, no máximo"
msgid "Line changes"
-msgstr ""
+msgstr "Alterações de linha"
msgid "Link"
msgstr ""
@@ -19993,10 +20146,10 @@ msgid "Link text"
msgstr "Texto do link"
msgid "Link title"
-msgstr ""
+msgstr "Título do link"
msgid "Link title is required"
-msgstr ""
+msgstr "Título do link é obrigatório"
msgid "Link to an image"
msgstr ""
@@ -20041,7 +20194,7 @@ msgid "List of users to be excluded from the limit"
msgstr ""
msgid "List options"
-msgstr ""
+msgstr "Opções de lista"
msgid "List settings"
msgstr ""
@@ -20161,10 +20314,10 @@ msgid "Logo will be removed. Are you sure?"
msgstr ""
msgid "Logs"
-msgstr "Logs"
+msgstr "Registros"
msgid "Logs|To see the logs, deploy your code to an environment."
-msgstr ""
+msgstr "Para ver os registros, implante o seu código em um ambiente."
msgid "Low vulnerabilities present"
msgstr ""
@@ -20230,7 +20383,7 @@ msgid "Maintenance mode"
msgstr ""
msgid "Make and review changes in the browser with the Web IDE"
-msgstr ""
+msgstr "Faça e revise alterações no navegador com o IDE Web"
msgid "Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
msgstr "Faça com que todos em sua equipe sejam mais produtivos, independentemente da localização deles. O GitLab Geo cria espelhos somente leitura de sua instância do GitLab para que você possa reduzir o tempo necessário para clonar e buscar grandes repositórios."
@@ -20245,7 +20398,7 @@ msgid "Makes this issue confidential."
msgstr "Torna esta issue confidencial."
msgid "Manage Web IDE features."
-msgstr ""
+msgstr "Gerenciar recursos do IDE Web."
msgid "Manage access"
msgstr "Gerenciar acesso"
@@ -20287,7 +20440,7 @@ msgid "Manage your license"
msgstr ""
msgid "Manage your project's triggers"
-msgstr ""
+msgstr "Gerenciar os gatilhos do seu projeto"
msgid "Managed Account"
msgstr "Conta gerenciada"
@@ -20344,7 +20497,7 @@ msgid "Markdown Help"
msgstr "Ajuda do Markdown"
msgid "Markdown enabled."
-msgstr ""
+msgstr "Markdown ativado."
msgid "Markdown is supported"
msgstr "Markdown é suportado"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr "Tamanho máximo dos artefatos (MB)"
+msgid "Maximum attachment size"
+msgstr "Tamanho máximo do anexo"
+
msgid "Maximum attachment size (MB)"
msgstr "Tamanho máximo de anexos (MB)"
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr "Atraso máximo (minutos)"
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr "Tamanho máximo de importação"
+
msgid "Maximum import size (MB)"
msgstr "Tamanho máximo de importação (MB)"
+msgid "Maximum job artifact size"
+msgstr "Tamanho máximo do artefato de tarefa"
+
msgid "Maximum job timeout"
msgstr "Tempo limite máximo da tarefa"
@@ -20578,7 +20746,7 @@ msgid "Maximum lines in a diff"
msgstr ""
msgid "Maximum npm package file size in bytes"
-msgstr ""
+msgstr "Tamanho máximo de arquivo para pacote npm em bytes"
msgid "Maximum number of %{name} (%{count}) exceeded"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr "Tamanho máximo da página"
+
+msgid "Maximum push size"
+msgstr "Tamanho máximo de push"
+
msgid "Maximum push size (MB)"
msgstr "Tamanho máximo de push (MB)"
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr "Tamanho máximo de snippet"
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr "Tempo máximo entre as atualizações que o espelho pode ter quando programado para sincronizar."
@@ -20635,10 +20812,10 @@ msgid "May"
msgstr "Mai"
msgid "Mean time to merge"
-msgstr ""
+msgstr "Tempo médio para mesclar"
msgid "Measured in bytes of code. Excludes generated and vendored code."
-msgstr ""
+msgstr "Medido em bytes de código. Exclui código gerado e fornecido."
msgid "Medium timeout"
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20776,7 +20956,7 @@ msgid "Members|Reverted to LDAP group sync settings."
msgstr ""
msgid "Members|Role updated successfully."
-msgstr ""
+msgstr "Cargo atualizado com sucesso."
msgid "Members|Search groups"
msgstr "Pesquisar grupos"
@@ -20806,19 +20986,19 @@ msgid "Merge"
msgstr "Merge"
msgid "Merge Conflicts"
-msgstr ""
+msgstr "Conflitos de mesclagem"
msgid "Merge Request"
-msgstr "Merge Request"
+msgstr "Solicitações de mesclagem"
msgid "Merge Request Analytics"
msgstr ""
msgid "Merge Requests"
-msgstr "Merge Requests"
+msgstr "Solicitações de mesclagem"
msgid "Merge Requests created"
-msgstr "Merge Requests criadas"
+msgstr "Solicitações de mesclagem criadas"
msgid "Merge Requests in Review"
msgstr ""
@@ -20827,6 +21007,9 @@ msgid "Merge Requests merged"
msgstr ""
msgid "Merge automatically (%{strategy})"
+msgstr "Mesclar automaticamente (%{strategy})"
+
+msgid "Merge blocked: new changes were just added."
msgstr ""
msgid "Merge blocked: the source branch must be rebased onto the target branch."
@@ -20836,40 +21019,40 @@ msgid "Merge commit SHA"
msgstr ""
msgid "Merge commit message"
-msgstr "Mensagem do commit de merge"
+msgstr "Mensagem do commit mesclado"
msgid "Merge events"
-msgstr "Eventos de merge"
+msgstr "Eventos de mesclagem"
msgid "Merge immediately"
-msgstr "Fazer merge imediatamente"
+msgstr "Fazer mesclagem imediatamente"
msgid "Merge in progress"
-msgstr "Merge em andamento"
+msgstr "Mesclagem em andamento"
msgid "Merge locally"
-msgstr ""
+msgstr "Mesclar localmente"
msgid "Merge options"
-msgstr "Opções de merge"
+msgstr "Opções de mesclagem"
msgid "Merge request"
-msgstr "Merge requests"
+msgstr "Solicitação de mesclagem"
msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
-msgstr ""
+msgstr "A solicitação de mesclagem %{mr_link} foi revisada por %{mr_author}"
msgid "Merge request (MR) approvals"
-msgstr "Aprovações de merge request (MR)"
+msgstr "Aprovações de solicitação de mesclagem (MR)"
msgid "Merge request analytics"
-msgstr ""
+msgstr "Análise de solicitação de mesclagem"
msgid "Merge request approvals"
-msgstr "Aprovações de merge request"
+msgstr "Aprovações de solicitação de mesclagem"
msgid "Merge request commits"
-msgstr ""
+msgstr "Commits de solicitação de mesclagem"
msgid "Merge request dependencies"
msgstr ""
@@ -20881,10 +21064,10 @@ msgid "Merge request was scheduled to merge after pipeline succeeds"
msgstr ""
msgid "Merge requests"
-msgstr "Merge requests"
+msgstr "Solicitações de mesclagem"
msgid "Merge requests are a place to propose changes you've made to a project and discuss those changes with others"
-msgstr "A tela de Merge request é um lugar para propor mudanças em um projeto e discutir essas mudanças com outros"
+msgstr "A tela de solicitação de mesclagem é um lugar para propor mudanças em um projeto e discutir essas mudanças com outros"
msgid "Merge requests are read-only in a secondary Geo node"
msgstr ""
@@ -20926,16 +21109,16 @@ msgid "MergeRequestAnalytics|Date Merged"
msgstr ""
msgid "MergeRequestAnalytics|Line changes"
-msgstr ""
+msgstr "Alterações de linha"
msgid "MergeRequestAnalytics|Merge Request"
-msgstr ""
+msgstr "Solicitação de mesclagem"
msgid "MergeRequestAnalytics|Milestone"
msgstr "Marco"
msgid "MergeRequestAnalytics|Pipelines"
-msgstr ""
+msgstr "Pipelines"
msgid "MergeRequestAnalytics|Time to merge"
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr "Ocorreu um erro ao salvar o rascunho do comentário."
@@ -20961,9 +21141,6 @@ msgstr "Resolve este tópico em uma nova issue"
msgid "MergeRequests|Saving the comment failed"
msgstr "Falha ao salvar comentário"
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21022,7 +21199,7 @@ msgid "MergeRequest|Search files (%{modifier_key}P)"
msgstr ""
msgid "Merged"
-msgstr "Merge realizado"
+msgstr "Mesclado"
msgid "Merged MRs"
msgstr ""
@@ -21037,7 +21214,7 @@ msgid "Merged this merge request."
msgstr ""
msgid "Merged: %{merged}"
-msgstr ""
+msgstr "Mesclado: %{merged}"
msgid "Merges this merge request immediately."
msgstr ""
@@ -21133,28 +21310,28 @@ msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to thi
msgstr ""
msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
-msgstr ""
+msgstr "Adicionar um botão ao painel de métricas vinculando diretamente ao seu painel externo existente."
msgid "MetricsSettings|Choose whether to display dashboard metrics in UTC or the user's local timezone."
-msgstr ""
+msgstr "Escolha se deseja exibir as métricas do painel em UTC ou no fuso horário local do usuário."
msgid "MetricsSettings|Dashboard timezone"
-msgstr ""
+msgstr "Fuso horário do painel"
msgid "MetricsSettings|External dashboard URL"
-msgstr ""
+msgstr "URL do painel externo"
msgid "MetricsSettings|Manage metrics dashboard settings."
-msgstr ""
+msgstr "Gerenciar configurações do painel de métricas."
msgid "MetricsSettings|Metrics"
msgstr "Métricas"
msgid "MetricsSettings|UTC (Coordinated Universal Time)"
-msgstr ""
+msgstr "UTC (Tempo Universal Coordenado)"
msgid "MetricsSettings|User's local timezone"
-msgstr ""
+msgstr "Fuso horário local do usuário"
msgid "Metrics|1. Define and preview panel"
msgstr ""
@@ -21172,7 +21349,7 @@ msgid "Metrics|Avg"
msgstr ""
msgid "Metrics|Back to dashboard"
-msgstr ""
+msgstr "Voltar para o painel"
msgid "Metrics|Cancel"
msgstr "Cancelar"
@@ -21339,7 +21516,7 @@ msgid "Metrics|There was an error getting dashboard validation warnings informat
msgstr ""
msgid "Metrics|There was an error getting deployment information."
-msgstr "Houve um erro ao obter informações de deploy."
+msgstr "Houve um erro ao obter informações de implantação."
msgid "Metrics|There was an error getting environments information."
msgstr "Houve um erro ao obter informações dos ambientes."
@@ -21417,7 +21594,7 @@ msgid "Metrics|e.g. req/sec"
msgstr ""
msgid "Mi"
-msgstr ""
+msgstr "Mi"
msgid "Middleman project with Static Site Editor support"
msgstr ""
@@ -21440,14 +21617,11 @@ msgstr[0] "Marco"
msgstr[1] "Marcos"
msgid "Milestone due date"
-msgstr "Data limite do marco"
+msgstr "Validade do marco"
msgid "Milestone lists not available with your current license"
msgstr "Listas de marcos não estão disponíveis para a sua licença atual"
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr "As listas de marcos mostram todas as issues do marco selecionado."
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21479,7 +21653,7 @@ msgid "MilestoneSidebar|Copy reference"
msgstr "Copiar referência"
msgid "MilestoneSidebar|Due date"
-msgstr "Data limite"
+msgstr "Validade"
msgid "MilestoneSidebar|Edit"
msgstr "Editar"
@@ -21494,7 +21668,7 @@ msgid "MilestoneSidebar|Merge requests"
msgstr "Merge request"
msgid "MilestoneSidebar|Merged:"
-msgstr "Merge realizado:"
+msgstr "Mesclado:"
msgid "MilestoneSidebar|New Issue"
msgstr "Nova issue"
@@ -21503,7 +21677,7 @@ msgid "MilestoneSidebar|New issue"
msgstr "Nova issue"
msgid "MilestoneSidebar|No due date"
-msgstr "Sem data limite"
+msgstr "Sem validade"
msgid "MilestoneSidebar|No start date"
msgstr "Sem data de início"
@@ -21512,7 +21686,7 @@ msgid "MilestoneSidebar|None"
msgstr "Nenhum"
msgid "MilestoneSidebar|Open:"
-msgstr "Aberto:"
+msgstr "Abrir:"
msgid "MilestoneSidebar|Reference:"
msgstr "Referência:"
@@ -21536,7 +21710,7 @@ msgid "Milestones| You’re about to permanently delete the milestone %{mileston
msgstr "Você está prestes a excluir permanentemente o marco %{milestoneTitle} e removê-lo de %{issuesWithCount} e %{mergeRequestsWithCount}. Uma vez excluído, não será possível desfazer ou recuperar."
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
-msgstr "Você está prestes a excluir permanentemente o marco %{milestoneTitle}. Este marco não é usado atualmente em nenhuma issue ou merge requests."
+msgstr "Você está prestes a excluir permanentemente o marco %{milestoneTitle}. Este marco não é usado atualmente em nenhuma issue ou solicitações de mesclagem."
msgid "Milestones|Close Milestone"
msgstr "Fechar marco"
@@ -21689,7 +21863,7 @@ msgid "Monitor the health and performance of GitLab with Prometheus."
msgstr ""
msgid "Monitor your errors by integrating with Sentry."
-msgstr ""
+msgstr "Monitore seus erros através da integração com o Sentry."
msgid "Monitoring"
msgstr "Monitoramento"
@@ -21722,7 +21896,7 @@ msgid "More information and share feedback"
msgstr ""
msgid "More information is available|here"
-msgstr "aqui"
+msgstr "Mais informações disponíveis|aqui"
msgid "More information."
msgstr ""
@@ -21731,7 +21905,7 @@ msgid "More than %{number_commits_distance} commits different with %{default_bra
msgstr "Mais de %{number_commits_distance} diferentes commits com %{default_branch}"
msgid "More topics"
-msgstr ""
+msgstr "Mais tópicos"
msgid "Most relevant"
msgstr ""
@@ -21826,14 +22000,14 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
msgstr "Meu grupo incrível"
msgid "My company or team"
-msgstr ""
+msgstr "Minha empresa ou equipe"
msgid "My-Reaction"
msgstr ""
@@ -21904,7 +22078,7 @@ msgid "Namespaces"
msgstr ""
msgid "Namespaces to index"
-msgstr "Namespaces para indexar"
+msgstr "Espaços de nome para indexar"
msgid "Naming, topics, avatar"
msgstr "Nomes, tópicos, avatar"
@@ -22017,12 +22191,6 @@ msgstr "Descrição"
msgid "NetworkPolicies|Edit policy"
msgstr "Editar política"
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr "Descrição da política"
-
msgid "NetworkPolicies|Policy editor"
-msgstr ""
+msgstr "Editor de política"
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22105,10 +22261,7 @@ msgid "NetworkPolicies|Rules"
msgstr ""
msgid "NetworkPolicies|Save changes"
-msgstr ""
-
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
+msgstr "Salvar alterações"
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22150,13 +22303,13 @@ msgid "NetworkPolicies|outbound from"
msgstr ""
msgid "NetworkPolicies|pod with labels"
-msgstr ""
+msgstr "pod com etiquetas"
msgid "NetworkPolicies|pods %{pods}"
msgstr ""
msgid "NetworkPolicies|pods with labels"
-msgstr ""
+msgstr "pods com etiquetas"
msgid "NetworkPolicies|ports %{ports}"
msgstr ""
@@ -22168,7 +22321,7 @@ msgid "NetworkPolicy|Policy"
msgstr "Política"
msgid "NetworkPolicy|Search by policy name"
-msgstr ""
+msgstr "Pesquisar por nome de política"
msgid "NetworkPolicy|Status"
msgstr ""
@@ -22180,7 +22333,7 @@ msgid "New"
msgstr "Novo"
msgid "New %{issueType}"
-msgstr ""
+msgstr "Nova %{issueType}"
msgid "New Application"
msgstr "Novo aplicativo"
@@ -22215,7 +22368,7 @@ msgstr[0] "Nova Issue"
msgstr[1] "Novas Issues"
msgid "New Jira import"
-msgstr ""
+msgstr "Nova importação do Jira"
msgid "New Label"
msgstr "Nova etiqueta"
@@ -22239,10 +22392,10 @@ msgid "New Requirement"
msgstr "Novo requisito"
msgid "New Snippet"
-msgstr "Novo Snippet"
+msgstr "Novo snippet"
msgid "New Test Case"
-msgstr ""
+msgstr "Novo caso de teste"
msgid "New User"
msgstr "Novo usuário"
@@ -22251,22 +22404,19 @@ msgid "New application"
msgstr "Nova aplicação"
msgid "New branch"
-msgstr "Novo branch"
+msgstr "Nova ramificação"
msgid "New branch unavailable"
-msgstr "Novo branch indisponível"
-
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
+msgstr "Nova ramificação indisponível"
msgid "New confidential epic title "
msgstr ""
msgid "New confidential issue title"
-msgstr ""
+msgstr "Novo título de issue confidencial"
msgid "New deploy key"
-msgstr "Nova chave de deploy"
+msgstr "Nova chave de implantação"
msgid "New directory"
msgstr "Novo diretório"
@@ -22317,7 +22467,7 @@ msgid "New list"
msgstr "Nova lista"
msgid "New merge request"
-msgstr "Novo merge request"
+msgstr "Nova solicitação de mesclagem"
msgid "New milestone"
msgstr "Novo marco"
@@ -22326,7 +22476,7 @@ msgid "New password"
msgstr "Nova senha"
msgid "New pipelines cause older pending or running pipelines on the same branch to be cancelled."
-msgstr ""
+msgstr "Novos pipelines fazem com que os pipelines mais antigos pendentes ou rodando na mesma ramificação sejam cancelados."
msgid "New project"
msgstr "Novo projeto"
@@ -22350,7 +22500,7 @@ msgid "New requirement"
msgstr "Novo requisito"
msgid "New response for issue #%{issue_iid}:"
-msgstr ""
+msgstr "Nova resposta para a issue #%{issue_iid}:"
msgid "New runners registration token has been generated!"
msgstr ""
@@ -22368,7 +22518,7 @@ msgid "New tag"
msgstr "Nova tag"
msgid "New test case"
-msgstr ""
+msgstr "Novo caso de teste"
msgid "New users set to external"
msgstr "Novos usuários definidos para uso externo"
@@ -22413,7 +22563,7 @@ msgid "No %{providerTitle} repositories found"
msgstr "Nenhum repositório %{providerTitle} encontrado"
msgid "No CSV data to display."
-msgstr ""
+msgstr "Nenhum dado CSV para exibir."
msgid "No Epic"
msgstr "Nenhuma épico"
@@ -22442,6 +22592,9 @@ msgstr "Nenhum application_settings encontrado"
msgid "No approvers"
msgstr "Nenhum aprovadores"
+msgid "No artifacts found"
+msgstr "Nenhum artefato encontrado"
+
msgid "No assignee"
msgstr "Nenhum responsável"
@@ -22449,13 +22602,13 @@ msgid "No authentication methods configured."
msgstr "Nenhum método de autenticação configurado."
msgid "No available branches"
-msgstr "Nenhum branch disponível"
+msgstr "Nenhuma ramificação disponível"
msgid "No available groups to fork the project."
msgstr "Nenhum grupo disponível para fazer fork do projeto."
msgid "No branches found"
-msgstr "Nenhuma branch encontrada"
+msgstr "Nenhuma ramificação encontrada"
msgid "No changes"
msgstr "Sem alterarções"
@@ -22476,16 +22629,16 @@ msgid "No committers"
msgstr "Nenhum committers"
msgid "No compliance frameworks are in use."
-msgstr ""
+msgstr "Nenhum frameworks de conformidade em uso"
msgid "No compliance frameworks are in use. Create one from the %{link} section in Group Settings."
-msgstr ""
+msgstr "Nenhum frameworks de conformidade em uso. Crie um na seção %{link} em Configurações de grupo."
msgid "No confirmation email received? Please check your spam folder or"
msgstr ""
msgid "No connection could be made to a Gitaly Server, please check your logs!"
-msgstr "Nenhuma conexão pode ser feita para um servidor Gitaly, por favor check os logs!"
+msgstr "Nenhuma conexão pode ser feita para um servidor Gitaly, por favor verifique os registros!"
msgid "No containers available"
msgstr ""
@@ -22509,7 +22662,7 @@ msgid "No deployments detected. Use environments to control your software's cont
msgstr ""
msgid "No deployments found"
-msgstr "Nenhum deploy encontrado"
+msgstr "Nenhuma implantação encontrada"
msgid "No due date"
msgstr "Sem validade"
@@ -22581,7 +22734,7 @@ msgid "No matching issue found. Make sure that you are adding a valid issue URL.
msgstr ""
msgid "No matching labels"
-msgstr ""
+msgstr "Nenhuma etiqueta correspondente"
msgid "No matching results"
msgstr "Nenhum resultado correspondente"
@@ -22596,7 +22749,7 @@ msgid "No members found"
msgstr "Nenhum membro encontrado"
msgid "No merge requests found"
-msgstr "Nenhum merge requests encontrado"
+msgstr "Nenhuma solicitação de mesclagem encontrada"
msgid "No messages were logged"
msgstr "Nenhuma mensagem foi registrada"
@@ -22629,7 +22782,7 @@ msgid "No preview for this file type"
msgstr "Nenhuma pré-visualização disponível para este tipo de arquivo"
msgid "No prioritized labels with such name or description"
-msgstr ""
+msgstr "Sem etiquetas priorizadas com esse nome ou descrição"
msgid "No profiles found"
msgstr "Nenhum perfil encontrado"
@@ -22653,7 +22806,7 @@ msgid "No runner executable"
msgstr ""
msgid "No runners found"
-msgstr "Nenhum runner encontrado"
+msgstr "Nenhum executor encontrado"
msgid "No schedules"
msgstr "Nenhum agendamento"
@@ -22686,13 +22839,13 @@ msgid "No test coverage"
msgstr "Nenhuma cobertura de teste"
msgid "No triggers exist yet. Use the form above to create one."
-msgstr ""
+msgstr "Nenhum gatilho existe ainda. Use o formulário acima para criar um."
msgid "No vulnerabilities present"
msgstr ""
msgid "No webhooks found, add one in the form above."
-msgstr ""
+msgstr "Nenhum webhooks encontrados, adicione um no formulário acima."
msgid "No worries, you can still use all the %{strong}%{plan_name}%{strong_close} features for now. You have %{remaining_days} to renew your subscription."
msgstr ""
@@ -22722,13 +22875,13 @@ msgid "None of the group milestones have the same project as the release"
msgstr ""
msgid "Normal text"
-msgstr ""
+msgstr "Texto normal"
msgid "Not Implemented"
msgstr ""
msgid "Not all browsers support U2F devices. Therefore, we require that you set up a two-factor authentication app first. That way you'll always be able to sign in - even when you're using an unsupported browser."
-msgstr ""
+msgstr "Nem todos os navegadores suportam dispositivos U2F. Portanto, exigimos que você configure um aplicativo de autenticação de dois fatores primeiro. Dessa forma, você sempre será capaz de entrar - mesmo quando você estiver usando um navegador não suportado."
msgid "Not all browsers support WebAuthn. Therefore, we require that you set up a two-factor authentication app first. That way you'll always be able to sign in - even from an unsupported browser."
msgstr ""
@@ -22743,7 +22896,7 @@ msgid "Not available for private projects"
msgstr "Não disponível para projetos privados"
msgid "Not available for protected branches"
-msgstr "Não disponível para Branches protegidas"
+msgstr "Não disponível para ramificações protegidas"
msgid "Not available to run jobs."
msgstr ""
@@ -22770,7 +22923,7 @@ msgid "Note"
msgstr "Nota"
msgid "Note creation requests"
-msgstr ""
+msgstr "Requisições de criação de nota"
msgid "Note parameters are invalid: %{errors}"
msgstr ""
@@ -22862,13 +23015,13 @@ msgstr[0] "Revisor: %{users}"
msgstr[1] "Revisores: %{users}"
msgid "NotificationEvent|Change reviewer merge request"
-msgstr "Alterar revisor de merge request"
+msgstr "Alterar revisor de solicitação de mesclagem"
msgid "NotificationEvent|Close issue"
msgstr "Fechar issue"
msgid "NotificationEvent|Close merge request"
-msgstr "Fechar merge request"
+msgstr "Fechar solicitação de mesclagem"
msgid "NotificationEvent|Failed pipeline"
msgstr "Falha no pipeline"
@@ -22880,7 +23033,7 @@ msgid "NotificationEvent|Issue due"
msgstr ""
msgid "NotificationEvent|Merge merge request"
-msgstr "Aceitar merge request"
+msgstr "Aceitar solicitação de mesclagem"
msgid "NotificationEvent|Merge when pipeline succeeds"
msgstr ""
@@ -22895,7 +23048,7 @@ msgid "NotificationEvent|New issue"
msgstr "Nova issue"
msgid "NotificationEvent|New merge request"
-msgstr "Novo merge request"
+msgstr "Nova solicitação de mesclagem"
msgid "NotificationEvent|New note"
msgstr "Novo comentário"
@@ -22910,13 +23063,13 @@ msgid "NotificationEvent|Reassign issue"
msgstr "Reatribuir issue"
msgid "NotificationEvent|Reassign merge request"
-msgstr "Reatribuir merge request"
+msgstr "Reatribuir solicitação de mesclagem"
msgid "NotificationEvent|Reopen issue"
msgstr "Reabrir issue"
msgid "NotificationEvent|Reopen merge request"
-msgstr "Reabrir merge request"
+msgstr "Reabrir solicitação de mesclagem"
msgid "NotificationEvent|Successful pipeline"
msgstr "Pipeline bem sucedido"
@@ -22952,7 +23105,7 @@ msgid "Notifications on"
msgstr "Notificações ligadas"
msgid "Notify users by email when sign-in location is not recognized."
-msgstr ""
+msgstr "Notificar usuários por e-mail quando o local de login não for reconhecido"
msgid "Nov"
msgstr "Nov"
@@ -22963,6 +23116,9 @@ msgstr "Novembro"
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr "Agora, personalize sua experiência do GitLab"
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23054,10 +23210,10 @@ msgid "On track"
msgstr "Sob controle"
msgid "On-call Schedules"
-msgstr ""
+msgstr "Agendamento de plantão"
msgid "On-call schedules"
-msgstr ""
+msgstr "Agendamento de plantão"
msgid "OnCallScheduless|Any escalation rules that are using this schedule will also be deleted."
msgstr ""
@@ -23092,8 +23248,8 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
-msgstr ""
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgstr "Crie agendamentos de plantão no GitLab"
msgid "OnCallSchedules|Currently no rotation."
msgstr ""
@@ -23108,7 +23264,7 @@ msgid "OnCallSchedules|Edit rotation"
msgstr ""
msgid "OnCallSchedules|Edit schedule"
-msgstr ""
+msgstr "Editar agendamento"
msgid "OnCallSchedules|Enable end date"
msgstr ""
@@ -23123,7 +23279,7 @@ msgid "OnCallSchedules|Failed to add schedule"
msgstr ""
msgid "OnCallSchedules|Failed to edit schedule"
-msgstr ""
+msgstr "Falha ao editar o agendamento"
msgid "OnCallSchedules|For this rotation, on-call will be:"
msgstr ""
@@ -23174,7 +23330,7 @@ msgid "OnCallSchedules|Select timezone"
msgstr "Selecionar fuso horário"
msgid "OnCallSchedules|Sets the default timezone for the schedule, for all participants"
-msgstr ""
+msgstr "Definir o fuso horário padrão para o agendamento, para todos os participantes"
msgid "OnCallSchedules|Successfully created a new rotation"
msgstr ""
@@ -23222,10 +23378,10 @@ msgid "OnDemandScans|Could not run the scan. Please try again."
msgstr ""
msgid "OnDemandScans|Create new scanner profile"
-msgstr ""
+msgstr "Criar novo perfil de verificação"
msgid "OnDemandScans|Create new site profile"
-msgstr ""
+msgstr "Criar novo perfil de site"
msgid "OnDemandScans|Description (optional)"
msgstr "Descrição (opcional)"
@@ -23237,7 +23393,7 @@ msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
msgid "OnDemandScans|Manage DAST scans"
-msgstr ""
+msgstr "Gerenciar verificações de DAST"
msgid "OnDemandScans|Manage scanner profiles"
msgstr ""
@@ -23252,13 +23408,13 @@ msgid "OnDemandScans|New on-demand DAST scan"
msgstr ""
msgid "OnDemandScans|No profile yet. In order to create a new scan, you need to have at least one completed scanner profile."
-msgstr ""
+msgstr "Não há nenhum perfil ainda. Para criar uma nova verificação, você precisa ter pelo menos um perfil completo de verificação."
msgid "OnDemandScans|No profile yet. In order to create a new scan, you need to have at least one completed site profile."
-msgstr ""
+msgstr "Não há nenhum perfil ainda. Para criar uma nova verificação, você precisa ter pelo menos um perfil completo de site."
msgid "OnDemandScans|On-demand Scans"
-msgstr ""
+msgstr "Verificação sob demanda"
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
@@ -23270,16 +23426,16 @@ msgid "OnDemandScans|Save scan"
msgstr ""
msgid "OnDemandScans|Scan name"
-msgstr ""
+msgstr "Nome da verificação"
msgid "OnDemandScans|Scanner profile"
-msgstr ""
+msgstr "Perfil de verificação"
msgid "OnDemandScans|Select one of the existing profiles"
msgstr ""
msgid "OnDemandScans|Site profile"
-msgstr ""
+msgstr "Perfil de site"
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
@@ -23306,7 +23462,7 @@ msgid "Once imported, repositories can be mirrored over SSH. Read more %{link_st
msgstr "Uma vez importados, os repositórios podem ser espelhados por SSH. Leia mais %{link_start}aqui%{link_end}."
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
-msgstr "Uma vez removido. o relacionamento do fork não pode ser restaurado. Esse projeto não poderá mais receber ou enviar merge requests para o projeto original ou outros forks."
+msgstr "Uma vez removido. o relacionamento do fork não pode ser restaurado. Esse projeto não poderá mais receber ou enviar solicitações de mesclagem para o projeto original ou outros forks."
msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
msgstr "Quando o arquivo exportado estiver pronto, você receberá um e-mail de notificação com um link para download ou poderá fazer o download a partir desta página."
@@ -23383,12 +23539,12 @@ msgid "Oops, are you sure?"
msgstr "Oops, você tem certeza?"
msgid "Open"
-msgstr "Aberto"
+msgstr "Aberta"
msgid "Open Selection"
msgstr "Abrir seleção"
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23440,13 +23596,13 @@ msgid "Opens in a new window"
msgstr "Abrir em nova janela"
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
-msgstr "A operação falhou. Verifique os logs do pod para %{pod_name} para mais detalhes."
+msgstr "A operação falhou. Verifique os registros do pod para %{pod_name} para mais detalhes."
msgid "Operation not allowed"
msgstr "Operação não permitida"
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
-msgstr "A operação expirou. Verifique os logs do pod para %{pod_name} para mais detalhes."
+msgstr "A operação expirou. Verifique os registros do pod para %{pod_name} para mais detalhes."
msgid "Operations"
msgstr "Operações"
@@ -23500,7 +23656,7 @@ msgid "Other information"
msgstr "Outra informação"
msgid "Other merge requests block this MR"
-msgstr "Outras merge requests bloqueiam essa MR"
+msgstr "Outras solicitações de mesclagem bloqueiam essa MR"
msgid "Other versions"
msgstr "Outras versões"
@@ -23539,10 +23695,10 @@ msgid "Overview"
msgstr "Visão geral"
msgid "Overwrite diverged branches"
-msgstr "Substituir branches divergentes"
+msgstr "Substituir ramificações divergentes"
msgid "Owned by %{image_tag}"
-msgstr ""
+msgstr "Propriedade de %{image_tag}"
msgid "Owned by anyone"
msgstr "Possuído por qualquer pessoa"
@@ -23551,7 +23707,7 @@ msgid "Owned by me"
msgstr "Possuído por mim"
msgid "Owned by:"
-msgstr ""
+msgstr "Propriedade de:"
msgid "Owner"
msgstr "Proprietário"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr "Tipo de pacote"
+
msgid "Package type must be Conan"
msgstr ""
@@ -23776,7 +23935,7 @@ msgid "PackageRegistry|Invalid Package: failed metadata extraction"
msgstr ""
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
-msgstr ""
+msgstr "Saiba como %{noPackagesLinkStart}publicar e compartilhar seus pacotes%{noPackagesLinkEnd} com o GitLab."
msgid "PackageRegistry|License information located at %{link}"
msgstr ""
@@ -23818,7 +23977,7 @@ msgid "PackageRegistry|Pip Command"
msgstr ""
msgid "PackageRegistry|Publish and share packages for a variety of common package managers. %{docLinkStart}More information%{docLinkEnd}"
-msgstr ""
+msgstr "Publique e compartilhe pacotes para uma variedade de gerenciadores de pacotes comuns. %{docLinkStart}Mais informações%{docLinkEnd}"
msgid "PackageRegistry|Publish packages if their name or version matches this regex."
msgstr ""
@@ -23839,7 +23998,7 @@ msgid "PackageRegistry|Remove package"
msgstr "Remover pacote"
msgid "PackageRegistry|RubyGems"
-msgstr ""
+msgstr "RubyGems"
msgid "PackageRegistry|Settings for Generic packages"
msgstr ""
@@ -23884,7 +24043,7 @@ msgid "PackageRegistry|There are no other versions of this package."
msgstr ""
msgid "PackageRegistry|There are no packages yet"
-msgstr ""
+msgstr "Ainda não há pacotes"
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr "Houve um problema ao buscar os detalhes deste pacote."
@@ -24010,7 +24169,7 @@ msgid "Parsing error for param :embed_json. %{message}"
msgstr ""
msgid "Part of merge request changes"
-msgstr "Parte das mudanças do merge request"
+msgstr "Parte das mudanças da solicitação de mesclagem"
msgid "Participants"
msgstr "Participantes"
@@ -24055,10 +24214,10 @@ msgid "Past due"
msgstr "Atrasado"
msgid "Paste a public key here."
-msgstr ""
+msgstr "Cole uma chave pública aqui."
msgid "Paste a public key here. %{link_start}How do I generate it?%{link_end}"
-msgstr ""
+msgstr "Cole uma chave pública aqui. %{link_start}Como eu gero?%{link_end}"
msgid "Paste confidential epic link"
msgstr ""
@@ -24199,7 +24358,7 @@ msgid "Permanently delete project"
msgstr ""
msgid "Permanently remove group"
-msgstr ""
+msgstr "Remover grupo permanentemente"
msgid "Permissions"
msgstr "Permissões"
@@ -24247,13 +24406,13 @@ msgid "Pipeline"
msgstr "Pipeline"
msgid "Pipeline %{label}"
-msgstr ""
+msgstr "Pipeline %{label}"
msgid "Pipeline %{label} for \"%{dataTitle}\""
-msgstr ""
+msgstr "Pipeline %{label} para \"%{dataTitle}\""
msgid "Pipeline ID"
-msgstr ""
+msgstr "ID do pipeline"
msgid "Pipeline IID"
msgstr ""
@@ -24265,16 +24424,16 @@ msgid "Pipeline Schedules"
msgstr "Agendamentos da Pipeline"
msgid "Pipeline URL"
-msgstr ""
+msgstr "URL do pipeline"
msgid "Pipeline durations for the last 30 commits"
-msgstr ""
+msgstr "Durações de pipeline dos últimos 30 commits"
msgid "Pipeline minutes quota"
-msgstr ""
+msgstr "Quota de minutos de pipeline"
msgid "Pipeline minutes quota:"
-msgstr ""
+msgstr "Quota de minutos de pipeline:"
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -24331,7 +24490,7 @@ msgid "PipelineEditorTutorial|Commit the file to your repository. The pipeline t
msgstr ""
msgid "PipelineEditorTutorial|Get started with GitLab CI/CD"
-msgstr ""
+msgstr "Primeiros passos com GitLab CI/CD"
msgid "PipelineEditorTutorial|GitLab CI/CD can automatically build, test, and deploy your application."
msgstr ""
@@ -24421,7 +24580,7 @@ msgid "PipelineSchedules|Variables"
msgstr "Variáveis"
msgid "PipelineStatusTooltip|Pipeline: %{ciStatus}"
-msgstr ""
+msgstr "Pipeline: %{ciStatus}"
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
@@ -24442,10 +24601,10 @@ msgid "Pipelines|API"
msgstr "API"
msgid "Pipelines|Add a code quality job"
-msgstr ""
+msgstr "Adicionar uma tarefa de qualidade de código"
msgid "Pipelines|Are you sure you want to run this pipeline?"
-msgstr ""
+msgstr "Tem certeza de que deseja executar este pipeline?"
msgid "Pipelines|Build with confidence"
msgstr "Construa com confiança"
@@ -24457,22 +24616,22 @@ msgid "Pipelines|CI lint"
msgstr ""
msgid "Pipelines|CI/CD template to test and deploy your %{name} project."
-msgstr ""
+msgstr "Modelo CI/CD para testar e implantar no seu projeto %{name}."
msgid "Pipelines|Child pipeline"
-msgstr ""
+msgstr "Pipeline filho"
msgid "Pipelines|Clear runner caches"
-msgstr ""
+msgstr "Limpar cache dos executores"
msgid "Pipelines|Copy trigger token"
-msgstr ""
+msgstr "Copiar token de gatilho"
msgid "Pipelines|Could not load artifacts."
msgstr "Não foi possível carregar os artefatos"
msgid "Pipelines|Could not load merged YAML content"
-msgstr ""
+msgstr "Não foi possível carregar conteúdo do YAML mesclado"
msgid "Pipelines|Description"
msgstr "Descrição"
@@ -24487,7 +24646,7 @@ msgid "Pipelines|Get familiar with GitLab CI/CD syntax by starting with a basic
msgstr ""
msgid "Pipelines|Get started with GitLab CI/CD"
-msgstr ""
+msgstr "Primeiros passos com GitLab CI/CD"
msgid "Pipelines|GitLab CI/CD can automatically build, test, and deploy your code. Let GitLab take care of time consuming tasks, so you can spend more time creating."
msgstr ""
@@ -24499,7 +24658,7 @@ msgid "Pipelines|Improve code quality with GitLab CI/CD"
msgstr ""
msgid "Pipelines|Install GitLab Runners"
-msgstr ""
+msgstr "Instalar GitLab Runners"
msgid "Pipelines|It is recommended the code is reviewed thoroughly before running this pipeline with the parent project's CI resource."
msgstr ""
@@ -24508,7 +24667,7 @@ msgid "Pipelines|Last Used"
msgstr "Último uso"
msgid "Pipelines|Learn about Runners"
-msgstr ""
+msgstr "Saiba mais sobre Executores"
msgid "Pipelines|Lint"
msgstr ""
@@ -24520,7 +24679,7 @@ msgid "Pipelines|Loading pipelines"
msgstr "Carregando pipelines"
msgid "Pipelines|Merged YAML is view only"
-msgstr ""
+msgstr "YAML mesclado é apenas a visualização"
msgid "Pipelines|More Information"
msgstr "Mais informações"
@@ -24532,10 +24691,10 @@ msgid "Pipelines|No triggers have been created yet. Add one using the form above
msgstr ""
msgid "Pipelines|Owner"
-msgstr ""
+msgstr "Proprietário"
msgid "Pipelines|Pipeline Editor"
-msgstr ""
+msgstr "Editor de pipeline"
msgid "Pipelines|Project cache successfully reset."
msgstr "Cache do projeto redefinido com sucesso."
@@ -24544,16 +24703,16 @@ msgid "Pipelines|Revoke"
msgstr "Revogar"
msgid "Pipelines|Something went wrong while cleaning runners cache."
-msgstr "Algo deu errado ao limpar o cache dos runners."
+msgstr "Algo deu errado ao limpar o cache dos executores."
msgid "Pipelines|The %{namespace_name} namespace has %{percentage}%% or less Shared Runner Pipeline minutes remaining. After it runs out, no new jobs or pipelines in its projects will run."
msgstr ""
msgid "Pipelines|The %{namespace_name} namespace has exceeded its pipeline minutes quota. Buy additional pipeline minutes, or no new jobs or pipelines in its projects will run."
-msgstr ""
+msgstr "O espaço de nome %{namespace_name} excedeu sua cota de minutos de pipeline. Compre minutos de pipeline adicionais, ou nenhuma nova tarefa ou pipeline será executado em seus projetos."
msgid "Pipelines|The CI configuration was not loaded, please try again."
-msgstr ""
+msgstr "A configuração do CI não foi carregada, tente novamente."
msgid "Pipelines|The GitLab CI configuration could not be updated."
msgstr ""
@@ -24580,7 +24739,7 @@ msgid "Pipelines|This GitLab CI configuration is valid."
msgstr "Essa configuração do GitLab CI é válida."
msgid "Pipelines|This is a child pipeline within the parent pipeline"
-msgstr ""
+msgstr "Este é um pipeline filho dentro do pipeline pai"
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -24592,7 +24751,7 @@ msgid "Pipelines|To keep your codebase simple, readable, and accessible to contr
msgstr ""
msgid "Pipelines|Token"
-msgstr ""
+msgstr "Token"
msgid "Pipelines|Trigger user has insufficient permissions to project"
msgstr ""
@@ -24601,49 +24760,49 @@ msgid "Pipelines|Use a CI/CD template"
msgstr "Usar um modelo CI/CD"
msgid "Pipelines|Use a sample %{codeStart}.gitlab-ci.yml%{codeEnd} template file to explore how CI/CD works."
-msgstr ""
+msgstr "Usar um arquivo de modelo %{codeStart}.gitlab-ci.yml%{codeEnd} para explorar como funciona o CI/CD."
msgid "Pipelines|Use a sample CI/CD template"
-msgstr ""
+msgstr "Usar um modelo CI/CD de exemplo"
msgid "Pipelines|Use a template based on your project's language or framework to get started with GitLab CI/CD."
msgstr ""
msgid "Pipelines|Use template"
-msgstr ""
+msgstr "Usar modelo"
msgid "Pipelines|Validating GitLab CI configuration…"
-msgstr ""
+msgstr "Validando a configuração do GitLab CI…"
msgid "Pipelines|View merged YAML"
-msgstr ""
+msgstr "Análise de YAML mesclado"
msgid "Pipelines|Visualize"
msgstr "Visualizar"
msgid "Pipelines|invalid"
-msgstr ""
+msgstr "Inválido"
msgid "Pipelines|parent"
-msgstr ""
+msgstr "pai"
msgid "Pipeline|Actions"
msgstr "Ações"
msgid "Pipeline|Branch name"
-msgstr "Nome do branch"
+msgstr "Nome da ramificação"
msgid "Pipeline|Branches or tags could not be loaded."
msgstr ""
msgid "Pipeline|Canceled"
-msgstr ""
+msgstr "Cancelado"
msgid "Pipeline|Checking pipeline status"
-msgstr ""
+msgstr "Verificando status do pipeline"
msgid "Pipeline|Checking pipeline status."
-msgstr ""
+msgstr "Verificando status do pipeline."
msgid "Pipeline|Commit"
msgstr "Commit"
@@ -24655,16 +24814,16 @@ msgid "Pipeline|Created"
msgstr "Criado"
msgid "Pipeline|Date"
-msgstr ""
+msgstr "Data"
msgid "Pipeline|Detached merge request pipeline"
-msgstr "Pipeline de merge request desanexada"
+msgstr "Pipeline de solicitação de mesclagem desanexada"
msgid "Pipeline|Duration"
msgstr "Duração"
msgid "Pipeline|Failed"
-msgstr ""
+msgstr "Falhou"
msgid "Pipeline|In progress"
msgstr "Em progresso"
@@ -24673,34 +24832,34 @@ msgid "Pipeline|Key"
msgstr "Chave"
msgid "Pipeline|Manual"
-msgstr ""
+msgstr "Manual"
msgid "Pipeline|Merge train pipeline"
-msgstr ""
+msgstr "Pipeline de merge train"
msgid "Pipeline|Merge train pipeline jobs can not be retried"
msgstr ""
msgid "Pipeline|Merged result pipeline"
-msgstr ""
+msgstr "Pipeline de resultado mesclado"
msgid "Pipeline|Passed"
msgstr "Passou"
msgid "Pipeline|Pending"
-msgstr ""
+msgstr "Pendente"
msgid "Pipeline|Pipeline"
msgstr "Pipeline"
msgid "Pipeline|Pipeline %{idStart}#%{idEnd} %{statusStart}%{statusEnd} for %{commitStart}%{commitEnd}"
-msgstr ""
+msgstr "Pipeline %{idStart}#%{idEnd} %{statusStart}%{statusEnd} para %{commitStart}%{commitEnd}"
msgid "Pipeline|Pipeline cannot be run."
msgstr ""
msgid "Pipeline|Pipelines"
-msgstr ""
+msgstr "Pipelines"
msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr "Executando"
msgid "Pipeline|Skipped"
msgstr "Ignorado"
+msgid "Pipeline|Source"
+msgstr "Fonte"
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -24733,7 +24937,7 @@ msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr "Parar pipeline #%{pipelineId}?"
msgid "Pipeline|Tag name"
-msgstr ""
+msgstr "Nome da tag"
msgid "Pipeline|Test coverage"
msgstr "Cobertura de teste"
@@ -24760,7 +24964,7 @@ msgid "Pipeline|Variables"
msgstr "Variáveis"
msgid "Pipeline|View pipeline"
-msgstr ""
+msgstr "Ver pipeline"
msgid "Pipeline|We are currently unable to fetch pipeline data"
msgstr ""
@@ -24973,7 +25177,7 @@ msgid "Please select at least one filter to see results"
msgstr "Por favor selecione pelo menos um filtro para ver os resultados"
msgid "Please select what should be included in each exported requirement."
-msgstr ""
+msgstr "Selecione o que deve ser incluído em cada requisito exportado."
msgid "Please select..."
msgstr "Por favor selecione..."
@@ -24994,7 +25198,7 @@ msgid "Please try and refresh the page. If the problem persists please contact s
msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
-msgstr ""
+msgstr "Por favor, digite %{phrase_code} para continuar ou feche este modal para cancelar."
msgid "Please type the following to confirm:"
msgstr "Por favor, digite o seguinte para confirmar"
@@ -25060,7 +25264,7 @@ msgid "Preferences|Behavior"
msgstr "Comportamento"
msgid "Preferences|Choose between fixed (max. 1280px) and fluid (%{percentage}) application layout."
-msgstr ""
+msgstr "Escolha entre layout do aplicativo fixo (máx. 1280px) ou fluido (%{percentage})."
msgid "Preferences|Choose what content you want to see on a project’s overview page."
msgstr "Escolha o conteúdo que você quer ver na página de visão geral de um projeto."
@@ -25158,15 +25362,12 @@ msgstr "Pressione %{key}-C para copiar"
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr "Prevenir as aprovações de MR pelo criador"
-
-msgid "Prevent MR approvals from users who make commits to the MR."
-msgstr ""
-
msgid "Prevent adding new members to project membership within this group"
msgstr "Impede a adição de novos membros ao projeto pertencentes a este grupo"
+msgid "Prevent editing approval rules in projects and merge requests."
+msgstr ""
+
msgid "Prevent environment from auto-stopping"
msgstr ""
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25258,7 +25456,7 @@ msgid "Private projects Minutes cost factor"
msgstr ""
msgid "Private projects can be created in your personal namespace with:"
-msgstr "Projetos privados podem ser criados em seu namespace pessoal com:"
+msgstr "Projetos privados podem ser criados em seu espaço de nome pessoal com:"
msgid "Proceed"
msgstr "Prosseguir"
@@ -25279,7 +25477,7 @@ msgid "Productivity analytics can help identify the problems that are delaying y
msgstr "A análise de produtividade pode ajudar a identificar os problemas que estão atrasando a sua equipe"
msgid "ProductivityAanalytics|Merge requests"
-msgstr ""
+msgstr "Solicitações de mesclagem"
msgid "ProductivityAanalytics|is earlier than the allowed minimum date"
msgstr ""
@@ -25291,7 +25489,7 @@ msgid "ProductivityAnalytics|Days"
msgstr "Dias"
msgid "ProductivityAnalytics|Days to merge"
-msgstr "Dias para o merge"
+msgstr "Dias para mesclar"
msgid "ProductivityAnalytics|Descending"
msgstr "Descendente"
@@ -25303,13 +25501,13 @@ msgid "ProductivityAnalytics|List"
msgstr ""
msgid "ProductivityAnalytics|Merge Requests"
-msgstr ""
+msgstr "Solicitações de mesclagem"
msgid "ProductivityAnalytics|Merge date"
-msgstr ""
+msgstr "Data de mesclagem"
msgid "ProductivityAnalytics|Merge requests"
-msgstr ""
+msgstr "Solicitações de mesclagem"
msgid "ProductivityAnalytics|Time to merge"
msgstr ""
@@ -25336,7 +25534,7 @@ msgid "ProfileSession|on"
msgstr ""
msgid "Profiles| You are about to permanently delete %{yourAccount}, and all of the issues, merge requests, and groups linked to your account. Once you confirm %{deleteAccount}, it cannot be undone or recovered."
-msgstr "Você está prestes a excluir permanentemente a %{yourAccount}, e todas as issues, merge requests e grupos vinculados a sua conta. Depois de confirmar clicando em %{deleteAccount}, isso não poderá ser desfeito ou recuperado."
+msgstr "Você está prestes a excluir permanentemente a %{yourAccount}, e todas as issues, solicitações de mesclagem e grupos vinculados a sua conta. Depois de confirmar clicando em %{deleteAccount}, isso não poderá ser desfeito ou recuperado."
msgid "Profiles| You are going to change the username %{currentUsernameBold} to %{newUsernameBold}. Profile and projects will be redirected to the %{newUsername} namespace but this redirect will expire once the %{currentUsername} namespace is registered by another user or group. Please update your Git repository remotes as soon as possible."
msgstr "Você vai alterar o nome de usuário %{currentUsernameBold} para %{newUsernameBold}. O perfil e os projetos serão redirecionados para %{newUsername} mas esse redirecionamento expirará quando %{currentUsername} for registrado por outro usuário ou grupo. Por favor, atualize seus repositórios remotos Git o mais rápido possível."
@@ -25408,7 +25606,7 @@ msgid "Profiles|Commit email"
msgstr "E-mail de commit"
msgid "Profiles|Connect %{provider}"
-msgstr "Conectar do %{provider}"
+msgstr "Conectar %{provider}"
msgid "Profiles|Connected Accounts"
msgstr "Contas conectadas"
@@ -25432,7 +25630,7 @@ msgid "Profiles|Disconnect"
msgstr "Desconectar"
msgid "Profiles|Disconnect %{provider}"
-msgstr "Desconectar do %{provider}"
+msgstr "Desconectar %{provider}"
msgid "Profiles|Do not show on profile"
msgstr "Não mostrar no perfil"
@@ -25443,9 +25641,12 @@ msgstr "Não exibir informações pessoais relacionadas à atividade em seus per
msgid "Profiles|Edit Profile"
msgstr "Editar perfil"
-msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
msgstr ""
+msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
+msgstr "Digite como seu nome é pronunciado para ajudar as pessoas a tratá-lo corretamente"
+
msgid "Profiles|Enter your name, so people you know can recognize you"
msgstr "Digite seu nome, então as pessoas que você conhece podem reconhecê-lo"
@@ -25474,7 +25675,7 @@ msgid "Profiles|GitLab is unable to verify your identity automatically. For secu
msgstr ""
msgid "Profiles|Give your individual key a title. This will be publicly visible."
-msgstr ""
+msgstr "Dê um título à sua chave individual. Isto será visível publicamente."
msgid "Profiles|If after setting a password, the option to delete your account is still not available, please email %{data_request} to begin the account deletion process."
msgstr ""
@@ -25525,7 +25726,7 @@ msgid "Profiles|Main settings"
msgstr "Configurações principais"
msgid "Profiles|Manage two-factor authentication"
-msgstr ""
+msgstr "Gerenciar autenticação de dois fatores"
msgid "Profiles|No file chosen."
msgstr "Nenhum arquivo escolhido."
@@ -25567,7 +25768,7 @@ msgid "Profiles|Set new profile picture"
msgstr "Definir nova foto de perfil"
msgid "Profiles|Set your local time zone"
-msgstr ""
+msgstr "Definir seu fuso horário local"
msgid "Profiles|Social sign-in"
msgstr "Entrar com rede social"
@@ -25635,9 +25836,6 @@ msgstr "Alteração de nome de usuário realizada com sucesso"
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr "Usar emojis em nomes parece divertido, mas tente definir uma mensagem de status"
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr "Qual é o seu status?"
@@ -25696,7 +25894,7 @@ msgid "Profiles|your account"
msgstr "sua conta"
msgid "Profile|%{job_title} at %{organization}"
-msgstr "Profile|%{job_title} em %{organization}"
+msgstr "%{job_title} em %{organization}"
msgid "Profiling - Performance bar"
msgstr "Barra de performance"
@@ -25729,7 +25927,7 @@ msgid "Project '%{project_name}' is restored."
msgstr ""
msgid "Project '%{project_name}' queued for deletion."
-msgstr "Projeto'%{project_name}' marcado para exclusão."
+msgstr "Projeto '%{project_name}' marcado para exclusão."
msgid "Project '%{project_name}' was successfully created."
msgstr "Projeto '%{project_name}' criado com sucesso."
@@ -25789,13 +25987,13 @@ msgid "Project does not exist or you don't have permission to perform this actio
msgstr "O projeto não existe ou você não tem permissão para realizar essa ação"
msgid "Project does not have a policy configuration"
-msgstr ""
+msgstr "Projeto não tem uma configuração de política"
msgid "Project export could not be deleted."
msgstr "A exportação do projeto não pôde ser excluída."
msgid "Project export download requests"
-msgstr ""
+msgstr "Requisições de download de exportação de projeto"
msgid "Project export enabled"
msgstr "Exportação de projetos ativada"
@@ -25861,7 +26059,7 @@ msgid "Project uploads"
msgstr "Projetos enviados"
msgid "Project visibility level will be changed to match namespace rules when transferring to a group."
-msgstr "O nível de visibilidade do projeto será alterado para coincidir com as regras do namespace ao transferir para um grupo."
+msgstr "O nível de visibilidade do projeto será alterado para coincidir com as regras do espaço de nome ao transferir para um grupo."
msgid "Project was not found or you do not have permission to add this project to Security Dashboards."
msgstr ""
@@ -26050,13 +26248,13 @@ msgid "ProjectSettings|Analytics"
msgstr "Análises"
msgid "ProjectSettings|Automatically resolve merge request diff discussions when they become outdated"
-msgstr "Resolver automaticamente discussões de diff do merge request quando elas se tornam desatualizadas"
+msgstr "Resolver automaticamente discussões de diff da solicitação de mesclagem quando elas se tornam desatualizadas"
msgid "ProjectSettings|Badges"
msgstr "Selos"
msgid "ProjectSettings|Build, test, and deploy your changes."
-msgstr "Construir, testar e deploy suas mudanças."
+msgstr "Construir, testar e implantar suas mudanças."
msgid "ProjectSettings|Checkbox is visible and selected by default."
msgstr ""
@@ -26092,25 +26290,25 @@ msgid "ProjectSettings|Do not allow"
msgstr "Não permitir"
msgid "ProjectSettings|Enable \"Delete source branch\" option by default"
-msgstr "Ativar a opção \"Excluir branch de origem\" por padrão"
+msgstr "Ativar a opção \"Excluir ramificação de origem\" por padrão"
msgid "ProjectSettings|Enable merge trains"
msgstr "Ativar merge train"
msgid "ProjectSettings|Enable merged results pipelines"
-msgstr ""
+msgstr "Ativar pipelines de resultados mesclados"
msgid "ProjectSettings|Encourage"
msgstr ""
msgid "ProjectSettings|Every merge creates a merge commit."
-msgstr "Cada merge cria um commit de merge."
+msgstr "Cada merge cria um commit de mesclagem."
msgid "ProjectSettings|Every project can have its own space to store its Docker images"
-msgstr ""
+msgstr "Cada projeto pode ter seu próprio espaço de armazenar suas imagens Docker"
msgid "ProjectSettings|Every project can have its own space to store its packages."
-msgstr ""
+msgstr "Cada projeto pode ter seu próprio espaço de armazenar seus pacotes."
msgid "ProjectSettings|Everyone"
msgstr "Todos"
@@ -26125,7 +26323,7 @@ msgid "ProjectSettings|Failed to update tag!"
msgstr "Falha ao atualizar a tag!"
msgid "ProjectSettings|Fast-forward merge"
-msgstr "Executar merge com fast-forward"
+msgstr "Executar mesclagem com fast-forward"
msgid "ProjectSettings|Fast-forward merges only."
msgstr ""
@@ -26155,34 +26353,34 @@ msgid "ProjectSettings|LFS objects from this repository are available to forks.
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
-msgstr ""
+msgstr "Gerencia arquivos grandes, como arquivos de áudio, vídeo e gráficos."
msgid "ProjectSettings|Merge checks"
-msgstr "Verificações de merge"
+msgstr "Verificações de mesclagem"
msgid "ProjectSettings|Merge commit"
-msgstr "Commit de merge"
+msgstr "Commit de mesclagem"
msgid "ProjectSettings|Merge commit with semi-linear history"
-msgstr "Commit de merge com uma história semilinear"
+msgstr "Commit de mesclagem com uma história semilinear"
msgid "ProjectSettings|Merge method"
-msgstr "Método de merge"
+msgstr "Método de mesclagem"
msgid "ProjectSettings|Merge options"
-msgstr "Opções de merge"
+msgstr "Opções de mesclagem"
msgid "ProjectSettings|Merge requests"
-msgstr "Merge request"
+msgstr "Solicitações de mesclagem"
msgid "ProjectSettings|Merge requests approved for merge are queued, and pipelines validate the combined results of the source and target branches before merge. %{link_start}What are merge trains?%{link_end}"
msgstr ""
msgid "ProjectSettings|Merge suggestions"
-msgstr "Sugestões de merge"
+msgstr "Sugestões de mesclagem"
msgid "ProjectSettings|No merge commits are created."
-msgstr "Nenhum commit de merge foi criado."
+msgstr "Nenhum commit de mesclagem foi criado."
msgid "ProjectSettings|Note: The container registry is always visible when a project is public and the container registry is set to '%{access_level_description}'"
msgstr "Observação: o container registry está sempre visível quando um projeto é público e o container registry está definido como '%{access_level_description}'"
@@ -26266,7 +26464,7 @@ msgid "ProjectSettings|Squashing is never performed and the checkbox is hidden."
msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
-msgstr ""
+msgstr "Enviar alterações para serem mescladas no upstream."
msgid "ProjectSettings|Supported variables:"
msgstr "Variáveis suportadas"
@@ -26281,7 +26479,7 @@ msgid "ProjectSettings|The default target project for merge requests created in
msgstr ""
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
-msgstr ""
+msgstr "Essas verificações devem passar antes que solicitações de mesclagem possam ter seus merge realizados."
msgid "ProjectSettings|This project"
msgstr ""
@@ -26338,7 +26536,7 @@ msgid "ProjectSettings|When pipelines for merge requests are enabled in the CI/C
msgstr ""
msgid "ProjectSettings|When there is a merge conflict, the user is given the option to rebase."
-msgstr ""
+msgstr "Quando há um conflito de mesclagem, o usuário tem a opção de rebase."
msgid "ProjectSettings|Wiki"
msgstr "Wiki"
@@ -26353,19 +26551,19 @@ msgid "ProjectTemplates|Android"
msgstr "Android"
msgid "ProjectTemplates|GitLab Cluster Management"
-msgstr ""
+msgstr "Gerenciamento de cluster do GitLab"
msgid "ProjectTemplates|Gitpod/Spring Petclinic"
-msgstr ""
+msgstr "Gitpod/Spring Petclinic"
msgid "ProjectTemplates|Go Micro"
msgstr "Go Micro"
msgid "ProjectTemplates|HIPAA Audit Protocol"
-msgstr ""
+msgstr "Protocolo de auditoria HIPAA"
msgid "ProjectTemplates|Kotlin Native for Linux"
-msgstr ""
+msgstr "Kotlin Native para Linux"
msgid "ProjectTemplates|Netlify/GitBook"
msgstr "Netlify/GitBook"
@@ -26386,7 +26584,7 @@ msgid "ProjectTemplates|NodeJS Express"
msgstr "NodeJS Express"
msgid "ProjectTemplates|Pages/Gatsby"
-msgstr ""
+msgstr "Pages/Gatsby"
msgid "ProjectTemplates|Pages/GitBook"
msgstr "Pages/GitBook"
@@ -26407,19 +26605,19 @@ msgid "ProjectTemplates|Ruby on Rails"
msgstr "Ruby on Rails"
msgid "ProjectTemplates|SalesforceDX"
-msgstr ""
+msgstr "SalesforceDX"
msgid "ProjectTemplates|Sample GitLab Project"
-msgstr ""
+msgstr "Exemplo de projeto do GitLab"
msgid "ProjectTemplates|Serverless Framework/JS"
-msgstr ""
+msgstr "Serverless Framework/JS"
msgid "ProjectTemplates|Spring"
msgstr "Spring"
msgid "ProjectTemplates|Static Site Editor/Middleman"
-msgstr ""
+msgstr "Editor de site estático/Middleman"
msgid "ProjectTemplates|iOS (Swift)"
msgstr "iOS (Swift)"
@@ -26443,7 +26641,7 @@ msgid "Projects shared with %{group_name}"
msgstr "Projetos compartilhados com %{group_name}"
msgid "Projects that can be accessed"
-msgstr ""
+msgstr "Projetos podem ser acessos"
msgid "Projects to index"
msgstr "Projetos para indexar"
@@ -26509,7 +26707,7 @@ msgid "ProjectsNew|Create a blank project to house your files, plan your work, a
msgstr "Crie um projeto em branco para armazenar seus arquivos, planejar seu trabalho e colaborar no código, entre outras coisas"
msgid "ProjectsNew|Create a project pre-populated with the necessary files to get you started quickly."
-msgstr ""
+msgstr "Crie um projeto pré-preenchido com os arquivos necessários para você começar rapidamente."
msgid "ProjectsNew|Create blank project"
msgstr "Criar projeto em branco"
@@ -26548,7 +26746,7 @@ msgid "ProjectsNew|Visibility Level"
msgstr "Nível de visibilidade"
msgid "ProjectsNew|Want to house several dependent projects under the same namespace? %{link_start}Create a group.%{link_end}"
-msgstr "Quer abrigar vários projetos dependentes no mesmo namespace? %{link_start}Crie um grupo.%{link_end}"
+msgstr "Quer abrigar vários projetos dependentes no mesmo espaço de nome? %{link_start}Crie um grupo.%{link_end}"
msgid "Prometheus"
msgstr ""
@@ -26736,11 +26934,8 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr "Eventos de auditoria é uma maneira de acompanhar eventos importantes que aconteceram no GitLab."
-
msgid "Promotions|Better Protected Branches"
-msgstr "Branchs protegidos com a melhor proteção"
+msgstr "Ramificações protegidas com a melhor proteção"
msgid "Promotions|Burndown Charts are visual representations of the progress of completing a milestone. At a glance, you see the current state for the completion a given milestone. Without them, you would have to organize the data from the milestone and plot it yourself to have the same sense of progress."
msgstr ""
@@ -26767,7 +26962,7 @@ msgid "Promotions|Dismiss burndown charts promotion"
msgstr ""
msgid "Promotions|Dismiss repository features promotion"
-msgstr ""
+msgstr "Dispensar promoção de funcionalidades de repositório"
msgid "Promotions|Don't show me this again"
msgstr "Não me mostre isso novamente"
@@ -26779,7 +26974,7 @@ msgid "Promotions|Improve issues management with Issue weight and GitLab Enterpr
msgstr "Melhore o gerenciamento de issues com o peso de issues e GitLab Enterprise Edition."
msgid "Promotions|Improve merge requests and customer support with GitLab Enterprise Edition."
-msgstr "Melhore merge requests e suporte ao cliente com o GitLab Enterprise Edition."
+msgstr "Melhore a solicitação de mesclagem e suporte ao cliente com o GitLab Enterprise Edition."
msgid "Promotions|Improve milestones with Burndown Charts."
msgstr "Melhore os marcos com os gráficos de Burndown"
@@ -26790,11 +26985,14 @@ msgstr "Melhore os repositórios com GitLab Enterprise Edition."
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr "Melhore a pesquisa com pesquisa avançada e GitLab Enterprise Edition."
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr "Saiba mais"
msgid "Promotions|Merge request approvals"
-msgstr "Aprovações de merge request"
+msgstr "Aprovações de solicitação de mesclagem"
msgid "Promotions|Not now, thanks!"
msgstr "Agora não, obrigado!"
@@ -26829,9 +27027,6 @@ msgstr "Esse recurso está bloqueado."
msgid "Promotions|Track activity with Contribution Analytics."
msgstr "Acompanhe atividades com a análises de contribuição."
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr "Experimente grátis"
@@ -26851,7 +27046,7 @@ msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
msgid "Promotions|Upgrade your plan to improve merge requests."
-msgstr "Aprimore seu plano para melhorar as merge requests."
+msgstr "Aprimore seu plano para melhorar as solicitações de mesclagem."
msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
msgstr "Aprimore seu plano para melhorar os marcos com os gráficos de Burndown"
@@ -26872,7 +27067,7 @@ msgid "Promotions|When you have a lot of issues, it can be hard to get an overvi
msgstr ""
msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr "Com as análises de contribuição você pode ter uma visão geral da atividade de issues, merge request e eventos de push para sua organização e seus membros."
+msgstr "Com as análises de contribuição você pode ter uma visão geral da atividade de issues, solicitação de mesclagem e eventos de push para sua organização e seus membros."
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr "você pode restringir o acesso a branchs protegidos escolhendo um cargo (Mantenedores, Desenvolveres) e também determinados usuários."
@@ -26899,10 +27094,10 @@ msgid "Protected"
msgstr "Protegido"
msgid "Protected Branch"
-msgstr "Branch protegido"
+msgstr "Ramificação protegida"
msgid "Protected Branches"
-msgstr "Branches protegidos"
+msgstr "Ramificações protegidas"
msgid "Protected Environment"
msgstr "Ambiente protegido"
@@ -26920,7 +27115,7 @@ msgid "Protected Tags"
msgstr "Tags protegidas"
msgid "Protected branches"
-msgstr "Branches protegidos"
+msgstr "Ramificações protegidas"
msgid "Protected environments"
msgstr "Ambientes protegidos"
@@ -26929,22 +27124,22 @@ msgid "ProtectedBranch|%{wildcards_link_start}Wildcards%{wildcards_link_end} suc
msgstr ""
msgid "ProtectedBranch|Allow all users with push access to %{tag_start}force push%{tag_end}."
-msgstr ""
+msgstr "Permitir que todos os usuários com acesso %{tag_start}forcem o push%{tag_end}."
msgid "ProtectedBranch|Allow all users with push access to force push."
-msgstr ""
+msgstr "Permitir que todos os usuários com acesso push forcem o push."
msgid "ProtectedBranch|Allowed to force push"
msgstr ""
msgid "ProtectedBranch|Allowed to force push:"
-msgstr ""
+msgstr "Permitido forçar um push:"
msgid "ProtectedBranch|Allowed to merge"
-msgstr ""
+msgstr "Permitido para mesclar"
msgid "ProtectedBranch|Allowed to merge:"
-msgstr "Permitido para merge:"
+msgstr "Permitido para mesclar:"
msgid "ProtectedBranch|Allowed to push"
msgstr ""
@@ -26953,13 +27148,13 @@ msgid "ProtectedBranch|Allowed to push:"
msgstr "Permitido para push:"
msgid "ProtectedBranch|Branch"
-msgstr "Branch"
+msgstr "Ramificação"
msgid "ProtectedBranch|Branch:"
-msgstr "Branch:"
+msgstr "Ramificação:"
msgid "ProtectedBranch|By default, protected branches restrict who can modify the branch."
-msgstr ""
+msgstr "Proteção de ramificações protegidas por padrão restringem quem pode modificar a ramificação."
msgid "ProtectedBranch|Code owner approval"
msgstr ""
@@ -26968,7 +27163,7 @@ msgid "ProtectedBranch|Does not apply to users allowed to push. Optional section
msgstr ""
msgid "ProtectedBranch|Keep stable branches secure and force developers to use merge requests."
-msgstr ""
+msgstr "Mantenha ramificações estáveis seguras e força os desenvolvedores a usar as solicitações de mesclagem"
msgid "ProtectedBranch|Learn more."
msgstr "Saiba mais."
@@ -26977,13 +27172,13 @@ msgid "ProtectedBranch|Protect"
msgstr "Proteger"
msgid "ProtectedBranch|Protect a branch"
-msgstr "Proteger um branch"
+msgstr "Proteger uma ramificação"
msgid "ProtectedBranch|Protected branch (%{protected_branches_count})"
-msgstr "Branch protegido (%{protected_branches_count})"
+msgstr "Ramificação protegida (%{protected_branches_count})"
msgid "ProtectedBranch|Protected branches"
-msgstr "Branchs protegidos"
+msgstr "Ramificações protegidas"
msgid "ProtectedBranch|Reject code pushes that change files listed in the CODEOWNERS file."
msgstr ""
@@ -27001,19 +27196,19 @@ msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
msgid "ProtectedBranch|What are protected branches?"
-msgstr ""
+msgstr "O que são ramificações protegidas?"
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr "%{environment_name} poderá ser editado por desenvolvedores. Tem certeza disso?"
msgid "ProtectedEnvironment|Allowed to deploy"
-msgstr "Permitido fazer deploy"
+msgstr "Permitido para implantar"
msgid "ProtectedEnvironment|Environment"
msgstr "Ambiente"
msgid "ProtectedEnvironment|Only specified users can execute deployments in a protected environment."
-msgstr ""
+msgstr "Apenas usuários especificados podem executar implantações em um ambiente protegido."
msgid "ProtectedEnvironment|Protect"
msgstr "Proteger"
@@ -27031,7 +27226,7 @@ msgid "ProtectedEnvironment|Select users"
msgstr "Selecionar usuários"
msgid "ProtectedEnvironment|There are currently no protected environments. Protect an environment with this form."
-msgstr ""
+msgstr "Atualmente não há ambientes protegidos. Proteja um ambiente com este formulário."
msgid "ProtectedEnvironment|Unprotect"
msgstr "Desproteger"
@@ -27046,7 +27241,7 @@ msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr "Seu ambiente foi desprotegido"
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
-msgstr "Por padrão, branches protegidos restringem quem pode modificar a tag."
+msgstr "Por padrão, ramificações protegidas restringem quem pode modificar a tag."
msgid "ProtectedTag|Learn more."
msgstr ""
@@ -27070,7 +27265,7 @@ msgid "Provision instructions"
msgstr ""
msgid "Provisioned by:"
-msgstr ""
+msgstr "Provisionado por:"
msgid "Proxy support for this API is not available currently"
msgstr ""
@@ -27091,7 +27286,7 @@ msgid "Public Access Help"
msgstr ""
msgid "Public deploy keys (%{deploy_keys_count})"
-msgstr "Chaves de deploy públicas (%{deploy_keys_count})"
+msgstr "Chaves de implantação públicas (%{deploy_keys_count})"
msgid "Public pipelines"
msgstr "Pipelines públicos"
@@ -27100,13 +27295,13 @@ msgid "Public projects Minutes cost factor"
msgstr ""
msgid "Publish to status page"
-msgstr ""
+msgstr "Publicar na página de status"
msgid "Published"
-msgstr ""
+msgstr "Publicado"
msgid "Published on status page"
-msgstr ""
+msgstr "Publicado na página de status"
msgid "Publishes this issue to the associated status page."
msgstr ""
@@ -27178,7 +27373,7 @@ msgid "PushRules|Commit messages cannot match this %{wiki_syntax_link_start}regu
msgstr ""
msgid "PushRules|Do not allow users to remove Git tags with %{code_block_start}git push%{code_block_end}"
-msgstr ""
+msgstr "Não permitir que os usuários removam tags do Git com %{code_block_start}git push%{code_block_end}"
msgid "PushRules|Reject any files likely to contain secrets. %{secret_files_link_start}What secret files are rejected?%{secret_files_link_end}"
msgstr ""
@@ -27199,7 +27394,7 @@ msgid "PushRules|Select push rules"
msgstr ""
msgid "PushRules|Users can still delete tags through the GitLab UI."
-msgstr ""
+msgstr "Os usuários ainda podem excluir tags por meio da interface de usuário do GitLab."
msgid "PushRule|Push rules"
msgstr "Regras de push"
@@ -27244,7 +27439,7 @@ msgid "PushoverService|Lowest priority"
msgstr ""
msgid "PushoverService|Normal priority"
-msgstr ""
+msgstr "Prioridade normal"
msgid "PushoverService|See project %{project_full_name}"
msgstr "Ver projeto %{project_full_name}"
@@ -27265,10 +27460,10 @@ msgid "Query is valid"
msgstr "A consulta é válida"
msgid "Queued"
-msgstr ""
+msgstr "Na fila"
msgid "Quick actions can be used in description and comment boxes."
-msgstr ""
+msgstr "Ações rápidas podem ser usadas nas descrições e nas caixas de comentário."
msgid "Quick help"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr "Leia mais sobre issues relacionadas"
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr "Pronto para mesclar!"
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27343,7 +27544,7 @@ msgid "Rebase in progress"
msgstr "Rebase em andamento"
msgid "Rebase source branch"
-msgstr ""
+msgstr "ramificação de origem de rebase"
msgid "Rebase source branch on the target branch."
msgstr ""
@@ -27376,7 +27577,7 @@ msgid "Recent Searches Service is unavailable"
msgstr ""
msgid "Recent jobs served by this runner"
-msgstr ""
+msgstr "Tarefas recentes servidos por este executor"
msgid "Recent searches"
msgstr "Pesquisas recentes"
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27465,7 +27669,7 @@ msgid "Register WebAuthn Device"
msgstr ""
msgid "Register as many runners as you want. You can register runners as separate users, on separate servers, and on your local machine. Runners are either:"
-msgstr ""
+msgstr "Registre quantos executores você quiser. Você pode registrar executores como usuários separados, em servidores separados e em sua máquina local. Os executores também são:"
msgid "Register device"
msgstr ""
@@ -27474,7 +27678,7 @@ msgid "Register now"
msgstr ""
msgid "Register the runner with this URL:"
-msgstr ""
+msgstr "Registre o executor com este URL:"
msgid "Register with two-factor app"
msgstr "Registre-se com aplicativo de dois fatores"
@@ -27513,7 +27717,10 @@ msgid "Related issues"
msgstr "Issues relacionadas"
msgid "Related merge requests"
-msgstr "Merge requests relacionados"
+msgstr "Solicitações de mesclagem relacionadas"
+
+msgid "Related to #%{issue_id}."
+msgstr "Relacionado a #%{issue_id}."
msgid "Relates to"
msgstr "Relacionado com"
@@ -27533,13 +27740,13 @@ msgid "Release does not have the same project as the milestone"
msgstr ""
msgid "Release notes"
-msgstr ""
+msgstr "Notas de lançamento"
msgid "Release notes:"
-msgstr ""
+msgstr "Notas de lançamento:"
msgid "Release title"
-msgstr ""
+msgstr "Título da versão"
msgid "Release with tag \"%{tag}\" was not found"
msgstr ""
@@ -27653,7 +27860,7 @@ msgid "Remove deploy key"
msgstr ""
msgid "Remove description history"
-msgstr ""
+msgstr "Remover histórico de descrição"
msgid "Remove due date"
msgstr "Remover data limite"
@@ -27752,7 +27959,7 @@ msgid "Removed %{assignee_text} %{assignee_references}."
msgstr "Removido %{assignee_text} %{assignee_references}."
msgid "Removed %{epic_ref} from child epics."
-msgstr ""
+msgstr "Removido %{epic_ref} dos épicos filhos."
msgid "Removed %{iteration_reference} iteration."
msgstr "Interação %{iteration_reference} removida."
@@ -27779,7 +27986,7 @@ msgid "Removed group can not be restored!"
msgstr "O grupo removido não pode ser restaurado!"
msgid "Removed parent epic %{epic_ref}."
-msgstr ""
+msgstr "Épico pai %{epic_ref} foi removido."
msgid "Removed spent time."
msgstr "Tempo gasto removido."
@@ -27821,13 +28028,13 @@ msgid "Removes an issue from an epic."
msgstr "Remover uma issue de um épico."
msgid "Removes parent epic %{epic_ref}."
-msgstr ""
+msgstr "Remove o épico pai %{epic_ref}."
msgid "Removes spent time."
msgstr "Remove o tempo gasto."
msgid "Removes the due date."
-msgstr "Remove a data limite."
+msgstr "Remove a validade."
msgid "Removes time estimate."
msgstr "Remove o tempo estimado."
@@ -27842,7 +28049,7 @@ msgid "Rename folder"
msgstr "Renomear pasta"
msgid "Rename/Move"
-msgstr ""
+msgstr "Renomear/Mover"
msgid "Render diagrams in your documents using PlantUML."
msgstr ""
@@ -27926,7 +28133,7 @@ msgid "Reported by"
msgstr "Reportado por"
msgid "Reported by %{reporter}"
-msgstr ""
+msgstr "Reportado por %{reporter}"
msgid "Reporting"
msgstr "Reportando"
@@ -28029,6 +28236,9 @@ msgstr "Resumo do teste falhou ao carregar os resultados"
msgid "Reports|Test summary results are being parsed"
msgstr "Os resultados do resumo de teste estão sendo analisados"
+msgid "Reports|Tool"
+msgstr "Ferramenta"
+
msgid "Reports|Vulnerability"
msgstr "Vulnerabilidade"
@@ -28045,7 +28255,7 @@ msgid "Repositories Analytics"
msgstr "Análises de repositórios"
msgid "RepositoriesAnalytics|Average Coverage by Job"
-msgstr ""
+msgstr "Cobertura média por tarefa"
msgid "RepositoriesAnalytics|Average coverage"
msgstr ""
@@ -28129,7 +28339,7 @@ msgid "Repository cleanup has started. You will receive an email once the cleanu
msgstr "A limpeza do repositório já começou. Você receberá um e-mail assim que a operação de limpeza for concluída."
msgid "Repository clone URL"
-msgstr ""
+msgstr "URL de clone do repositório"
msgid "Repository files count over the limit"
msgstr ""
@@ -28286,7 +28496,7 @@ msgid "Requires your primary GitLab email address."
msgstr ""
msgid "Resend"
-msgstr ""
+msgstr "Reenviar"
msgid "Resend Request"
msgstr ""
@@ -28328,7 +28538,7 @@ msgid "Reset password"
msgstr ""
msgid "Reset registration token"
-msgstr ""
+msgstr "Redefinir token de registro"
msgid "Reset template"
msgstr "Redefinir modelo"
@@ -28352,7 +28562,7 @@ msgid "Resolve conflicts on source branch"
msgstr "Resolver conflitos na branch de origem"
msgid "Resolve these conflicts or ask someone with write access to this repository to merge it locally."
-msgstr "Resolva estes conflitos ou peça a alguém com acesso de escrita para este repositório realizar o merge localmente"
+msgstr "Resolva estes conflitos ou peça a alguém com acesso de escrita para este repositório realizar a mesclagem localmente"
msgid "Resolve thread"
msgstr "Resolver tópico"
@@ -28421,7 +28631,7 @@ msgid "Restoring the project will prevent the project from being removed on this
msgstr ""
msgid "Restrict membership by email domain"
-msgstr ""
+msgstr "Restringir a participação por domínio de e-mail"
msgid "Restrict projects for this runner"
msgstr ""
@@ -28465,7 +28675,7 @@ msgid "Revert this commit"
msgstr "Reverter este commit"
msgid "Revert this merge request"
-msgstr "Reverter esse merge request"
+msgstr "Reverter essa solicitação de mesclagem"
msgid "Review"
msgstr "Revisar"
@@ -28476,11 +28686,14 @@ msgstr "Ver aplicativo"
msgid "Review App|View latest app"
msgstr "Ver último aplicativo"
+msgid "Review changes"
+msgstr "Revisar alterações"
+
msgid "Review requested from %{name}"
msgstr "Revisão requisitada por %{name}"
msgid "Review requests for you"
-msgstr ""
+msgstr "Requisições de revisão atribuídos a você"
msgid "Review the changes locally"
msgstr ""
@@ -28492,13 +28705,13 @@ msgid "Review the target project before submitting to avoid exposing %{source} c
msgstr ""
msgid "Review time"
-msgstr ""
+msgstr "Tempo de revisão"
msgid "Review time is defined as the time it takes from first comment until merged."
msgstr ""
msgid "ReviewApp|Enable Review App"
-msgstr ""
+msgstr "Ativar app de revisão"
msgid "Reviewer"
msgid_plural "%d Reviewers"
@@ -28515,7 +28728,7 @@ msgid "Reviewing"
msgstr "Revisão"
msgid "Reviewing (merge request !%{mergeRequestId})"
-msgstr "Revisando (merge request !%{mergeRequestId})"
+msgstr "Revisando (solicitação de mesclagem !%{mergeRequestId})"
msgid "Revoke"
msgstr "Revogar"
@@ -28524,7 +28737,7 @@ msgid "Revoked"
msgstr ""
msgid "Revoked impersonation token %{token_name}!"
-msgstr ""
+msgstr "Revogado o token de representação %{token_name}!"
msgid "Revoked personal access token %{personal_access_token_name}!"
msgstr "Revogado o token de acesso pessoal %{personal_access_token_name}!"
@@ -28551,13 +28764,13 @@ msgid "Roadmap"
msgstr "Planejamento"
msgid "Role"
-msgstr ""
+msgstr "Cargo"
msgid "Rollback"
msgstr "Reverter"
msgid "Ruby"
-msgstr ""
+msgstr "Ruby"
msgid "Rule name is already taken."
msgstr ""
@@ -28602,16 +28815,16 @@ msgid "Runner was not deleted because it is assigned to multiple projects."
msgstr ""
msgid "Runner was not updated."
-msgstr "Runner não foi atualizado."
+msgstr "Executor não foi atualizado."
msgid "Runner was successfully updated."
-msgstr "Runner foi atualizado com sucesso."
+msgstr "Executor foi atualizado com sucesso."
msgid "Runners"
-msgstr "Runners"
+msgstr "Executores"
msgid "Runners are processes that pick up and execute CI/CD jobs for GitLab."
-msgstr ""
+msgstr "Executores são processos que selecionam e executam Tarefas de CI /CD para o GitLab."
msgid "Runners can be:"
msgstr ""
@@ -28620,10 +28833,10 @@ msgid "Runners currently online: %{active_runners_count}"
msgstr "Executores online no momento: %{active_runners_count}"
msgid "Runners page."
-msgstr "Página de runners."
+msgstr "Página de executores."
msgid "Runners|Active"
-msgstr ""
+msgstr "Ativo"
msgid "Runners|Amazon Linux 2 Docker HA with manual scaling and optional scheduling. %{percentage} spot."
msgstr ""
@@ -28635,7 +28848,7 @@ msgid "Runners|An error has occurred fetching instructions"
msgstr ""
msgid "Runners|Architecture"
-msgstr ""
+msgstr "Arquitetura"
msgid "Runners|Are you sure you want to delete this runner?"
msgstr ""
@@ -28644,7 +28857,7 @@ msgid "Runners|Can run untagged jobs"
msgstr ""
msgid "Runners|Command to register runner"
-msgstr ""
+msgstr "Comando para registrar o executor"
msgid "Runners|Copy instructions"
msgstr "Copiar instruções"
@@ -28656,10 +28869,10 @@ msgid "Runners|Description"
msgstr "Descrição"
msgid "Runners|Download and install binary"
-msgstr ""
+msgstr "Baixar e instalar o binário"
msgid "Runners|Download latest binary"
-msgstr ""
+msgstr "Baixar o último binário"
msgid "Runners|Enter the number of seconds. This timeout takes precedence over lower timeouts set for the project."
msgstr ""
@@ -28668,7 +28881,7 @@ msgid "Runners|For each solution, you will choose a capacity. 1 enables warm HA
msgstr ""
msgid "Runners|Group Runners"
-msgstr ""
+msgstr "Executores de grupo"
msgid "Runners|IP Address"
msgstr "Endereço de IP"
@@ -28677,22 +28890,22 @@ msgid "Runners|If you do not select an AWS VPC, the runner will deploy to the De
msgstr ""
msgid "Runners|Install a runner"
-msgstr ""
+msgstr "Instalar um executor"
msgid "Runners|Last contact"
msgstr "Último contato"
msgid "Runners|Locked to this project"
-msgstr ""
+msgstr "Travado para este projeto"
msgid "Runners|Maximum job timeout"
-msgstr ""
+msgstr "Tempo limite máximo da tarefa"
msgid "Runners|Members of the %{type} can register runners"
msgstr ""
msgid "Runners|Name"
-msgstr ""
+msgstr "Nome"
msgid "Runners|New registration token generated!"
msgstr ""
@@ -28713,22 +28926,22 @@ msgid "Runners|Paused"
msgstr "Pausado"
msgid "Runners|Platform"
-msgstr ""
+msgstr "Plataforma"
msgid "Runners|Property Name"
-msgstr ""
+msgstr "Nome da propriedade"
msgid "Runners|Protected"
-msgstr ""
+msgstr "Protegido"
msgid "Runners|Revision"
-msgstr ""
+msgstr "Revisão"
msgid "Runners|Runner"
-msgstr ""
+msgstr "Executor"
msgid "Runners|Runner #%{runner_id}"
-msgstr ""
+msgstr "Executor #%{runner_id}"
msgid "Runners|Runner is offline, last contact was %{runner_contact} ago"
msgstr ""
@@ -28740,16 +28953,19 @@ msgid "Runners|Runner is paused, last contact was %{runner_contact} ago"
msgstr ""
msgid "Runners|Runner registration"
-msgstr ""
+msgstr "Registro de executor"
msgid "Runners|Runners"
+msgstr "Executores"
+
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
msgstr ""
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
msgid "Runners|Show Runner installation instructions"
-msgstr ""
+msgstr "Mostrar instruções de instalação do executor"
msgid "Runners|Something went wrong while fetching runner data."
msgstr ""
@@ -28761,7 +28977,7 @@ msgid "Runners|Stop the runner from accepting new jobs."
msgstr ""
msgid "Runners|Tags"
-msgstr ""
+msgstr "Tags"
msgid "Runners|This runner is associated with one or more projects."
msgstr ""
@@ -28794,13 +29010,13 @@ msgid "Runners|Use the runner on pipelines for protected branches only."
msgstr ""
msgid "Runners|Value"
-msgstr ""
+msgstr "Valor"
msgid "Runners|Version"
-msgstr ""
+msgstr "Versão"
msgid "Runners|View installation instructions"
-msgstr ""
+msgstr "Ver instruções de instalação do executor"
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. %{percentage} spot."
msgstr ""
@@ -28808,32 +29024,35 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
msgid "Runners|You have used %{quotaUsed} out of %{quotaLimit} of your shared Runners pipeline minutes."
-msgstr ""
+msgstr "Você usou %{quotaUsed} dos seus %{quotaLimit} minutos dos executores compartilhados."
msgid "Runners|group"
-msgstr ""
+msgstr "grupo"
msgid "Runners|instance"
msgstr ""
msgid "Runners|locked"
-msgstr ""
+msgstr "bloqueado"
msgid "Runners|paused"
-msgstr ""
+msgstr "pausado"
msgid "Runners|project"
-msgstr ""
+msgstr "projeto"
msgid "Runners|shared"
-msgstr ""
+msgstr "compartilhado"
msgid "Runners|specific"
-msgstr ""
+msgstr "específicos"
msgid "Running"
msgstr "Executando"
@@ -28866,7 +29085,7 @@ msgid "SAML for %{group_name}"
msgstr "SAML para %{group_name}"
msgid "SAST Configuration"
-msgstr ""
+msgstr "Configuração de SAST"
msgid "SHA256"
msgstr ""
@@ -29022,13 +29241,13 @@ msgid "Scope"
msgstr "Escopo"
msgid "Scope board to current iteration"
-msgstr ""
+msgstr "Escopo do painel para a iteração atual"
msgid "Scopes"
msgstr "Escopos"
msgid "Scopes (select at least one)"
-msgstr ""
+msgstr "Escopos (selecione pelo menos um)"
msgid "Scopes can't be blank"
msgstr ""
@@ -29061,7 +29280,7 @@ msgid "Search GitLab"
msgstr "Pesquisar no GitLab"
msgid "Search Jira issues"
-msgstr ""
+msgstr "Pesquisar issues do Jira"
msgid "Search a group"
msgstr "Pesquisar um grupo"
@@ -29076,16 +29295,16 @@ msgid "Search authors"
msgstr "Pesquisar autores"
msgid "Search branches"
-msgstr "Pesquisar branches"
+msgstr "Pesquisar ramificações"
msgid "Search branches and tags"
-msgstr "Procurar branch e tags"
+msgstr "Procurar ramificação e tags"
msgid "Search branches, tags, and commits"
msgstr ""
msgid "Search by Git revision"
-msgstr ""
+msgstr "Pesquisar por revisão do Git"
msgid "Search by author"
msgstr "Pesquisar por autor"
@@ -29103,7 +29322,7 @@ msgid "Search files"
msgstr "Procurar arquivos"
msgid "Search for Namespace"
-msgstr "Pesquisar por namespace"
+msgstr "Pesquisar por espaço de nome"
msgid "Search for a LDAP group"
msgstr "Pesquisar por um grupo LDAP"
@@ -29130,7 +29349,7 @@ msgid "Search labels"
msgstr "Pesquisar etiquetas"
msgid "Search merge requests"
-msgstr "Pesquisar merge requests"
+msgstr "Pesquisar solicitações de mesclagem"
msgid "Search milestones"
msgstr "Pesquisar marcos"
@@ -29169,7 +29388,7 @@ msgid "Search users or groups"
msgstr "Procurar usuários ou grupos"
msgid "Search your project dependencies for their licenses and apply policies."
-msgstr ""
+msgstr "Pesquise as dependências do seu projeto por suas licenças e aplique políticas."
msgid "Search your projects"
msgstr "Pesquisar nos seus projetos"
@@ -29274,9 +29493,6 @@ msgstr[1] "resultados em wiki"
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29287,7 +29503,7 @@ msgid "Secondary"
msgstr ""
msgid "Secondary email:"
-msgstr ""
+msgstr "E-mail Secundário:"
msgid "Seconds"
msgstr ""
@@ -29296,7 +29512,7 @@ msgid "Secret"
msgstr "Secreto"
msgid "Secret Detection"
-msgstr ""
+msgstr "Detecção de secreto"
msgid "Secret token"
msgstr "Token secreto"
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29341,16 +29557,16 @@ msgid "SecurityApprovals|Configurable if security scanners are enabled. %{linkSt
msgstr ""
msgid "SecurityApprovals|Coverage-Check"
-msgstr ""
+msgstr "Verificação de cobertura"
msgid "SecurityApprovals|Learn more about Coverage-Check"
-msgstr ""
+msgstr "Saiba mais sobre a verificação de cobertura"
msgid "SecurityApprovals|Learn more about License-Check"
-msgstr ""
+msgstr "Saiba mais sobre a verificação de licença"
msgid "SecurityApprovals|Learn more about Vulnerability-Check"
-msgstr ""
+msgstr "Saiba mais sobre a verificação de vulnerabilidade"
msgid "SecurityApprovals|License Scanning must be enabled. %{linkStart}Learn more%{linkEnd}."
msgstr "A verificação de licença deve estar ativado. %{linkStart}Saiba mais%{linkEnd}."
@@ -29362,10 +29578,10 @@ msgid "SecurityApprovals|Requires approval for Denied licenses. %{linkStart}More
msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
-msgstr ""
+msgstr "Requer aprovação para reduções de cobertura de teste. %{linkStart}Mais informações%{linkEnd}"
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
-msgstr "Requer aprovação para vulnerabilidades de severidade crítica, alta ou desconhecida. %{linkStart}Saiba mais.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
+msgstr "Requer aprovação para vulnerabilidades. %{linkStart}Saiba mais.%{linkEnd}"
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
msgstr ""
@@ -29389,13 +29605,13 @@ msgid "SecurityConfiguration|By default, all analyzers are applied in order to c
msgstr ""
msgid "SecurityConfiguration|Compliance"
-msgstr ""
+msgstr "Conformidade"
msgid "SecurityConfiguration|Configuration guide"
-msgstr ""
+msgstr "Guia de configuração"
msgid "SecurityConfiguration|Configuration history"
-msgstr ""
+msgstr "Histórico de configuração"
msgid "SecurityConfiguration|Configure %{feature}"
msgstr ""
@@ -29407,7 +29623,7 @@ msgid "SecurityConfiguration|Copy code and open .gitlab-ci.yml file"
msgstr ""
msgid "SecurityConfiguration|Copy code only"
-msgstr ""
+msgstr "Copiar apenas o código"
msgid "SecurityConfiguration|Could not retrieve configuration data. Please refresh the page, or try again later."
msgstr ""
@@ -29434,10 +29650,10 @@ msgid "SecurityConfiguration|Immediately begin risk analysis and remediation wit
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
-msgstr ""
+msgstr "Gerenciar perfis para uso pelas verificações de DAST."
msgid "SecurityConfiguration|Manage scans"
-msgstr ""
+msgstr "Gerenciar verificações"
msgid "SecurityConfiguration|More scan types, including Container Scanning, DAST, Dependency Scanning, Fuzzing, and Licence Compliance"
msgstr ""
@@ -29455,10 +29671,10 @@ msgid "SecurityConfiguration|Runtime security metrics for application environmen
msgstr ""
msgid "SecurityConfiguration|SAST Analyzers"
-msgstr ""
+msgstr "Análises de SAST"
msgid "SecurityConfiguration|SAST Configuration"
-msgstr ""
+msgstr "Configuração de SAST"
msgid "SecurityConfiguration|Secure your project"
msgstr ""
@@ -29478,12 +29694,87 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr "Ação"
+
+msgid "SecurityOrchestration|All policies"
+msgstr "Todas as políticas"
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr "Descrição"
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr "Editar política"
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr "Editar projeto de política"
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr "Aplicar segurança para este projeto. %{linkStart}Mais informações.%{linkEnd}"
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr "Última verificação"
+
+msgid "SecurityOrchestration|Network"
+msgstr "Rede"
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr "Nova política"
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
+msgid "SecurityOrchestration|Policies"
+msgstr "Políticas"
+
+msgid "SecurityOrchestration|Policy description"
+msgstr "Descrição da política"
+
+msgid "SecurityOrchestration|Policy editor"
+msgstr "Editor de política"
+
+msgid "SecurityOrchestration|Policy status"
+msgstr "Status da política"
+
+msgid "SecurityOrchestration|Policy type"
+msgstr "Tipo de política"
+
+msgid "SecurityOrchestration|Rule"
+msgstr "Regra"
+
+msgid "SecurityOrchestration|Scan Execution"
+msgstr ""
+
+msgid "SecurityOrchestration|Scan execution"
+msgstr ""
+
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
+msgstr ""
+
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
+msgstr ""
+
msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
@@ -29493,50 +29784,44 @@ msgstr ""
msgid "SecurityOrchestration|Select security project"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
msgstr ""
-msgid "SecurityPolicies|All policies"
-msgstr "Todas as políticas"
-
-msgid "SecurityPolicies|Description"
-msgstr "Descrição"
-
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Update scan execution policies"
msgstr ""
-msgid "SecurityPolicies|Network"
-msgstr "Rede"
+msgid "SecurityOrchestration|view results"
+msgstr "ver resultados"
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrhestration|No rules defined - policy will not run."
msgstr ""
-msgid "SecurityPolicies|Policy type"
-msgstr "Tipo de política"
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityPolicies|Environment(s)"
msgstr ""
-msgid "SecurityPolicies|view results"
-msgstr "Ver resultados"
+msgid "SecurityPolicies|Policy type"
+msgstr "Tipo de política"
msgid "SecurityReports|%{firstProject} and %{secondProject}"
-msgstr ""
+msgstr "%{firstProject} e %{secondProject}"
msgid "SecurityReports|%{firstProject}, %{secondProject}, and %{rest}"
-msgstr ""
+msgstr "%{firstProject}, %{secondProject} e %{rest}"
msgid "SecurityReports|Add or remove projects to monitor in the security area. Projects included in this list will have their results displayed in the security dashboard and vulnerability report."
-msgstr ""
+msgstr "Adicionar ou remover projetos para monitorar na área de segurança. Projetos incluídos nessa lista terão seus resultados exibidos no painel de segurança e relatório de vulnerabilidade."
msgid "SecurityReports|Add projects"
msgstr "Adicionar projetos"
@@ -29563,13 +29848,10 @@ msgid "SecurityReports|Comment edited on '%{vulnerabilityName}'"
msgstr ""
msgid "SecurityReports|Configure security testing"
-msgstr ""
-
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
+msgstr "Configurar teste de segurança"
msgid "SecurityReports|Create Jira issue"
-msgstr ""
+msgstr "Criar uma Jira do Jira"
msgid "SecurityReports|Create issue"
msgstr "Criar issue"
@@ -29578,13 +29860,13 @@ msgid "SecurityReports|Dismiss vulnerability"
msgstr "Dispensar vulnerabilidade"
msgid "SecurityReports|Dismissed '%{vulnerabilityName}'"
-msgstr ""
+msgstr "Dispensar '%{vulnerabilityName}'"
msgid "SecurityReports|Dismissed '%{vulnerabilityName}'. Turn off the hide dismissed toggle to view."
msgstr ""
msgid "SecurityReports|Download %{artifactName}"
-msgstr ""
+msgstr "Baixar %{artifactName}"
msgid "SecurityReports|Download results"
msgstr "Baixar os resultados"
@@ -29626,7 +29908,7 @@ msgid "SecurityReports|Manage and track vulnerabilities identified in projects w
msgstr ""
msgid "SecurityReports|Manage and track vulnerabilities identified in your project. Vulnerabilities are shown here when security testing is configured."
-msgstr ""
+msgstr "Gerenciar e acompanhar vulnerabilidades identificadas em seu projeto. Vulnerabilidades são mostradas aqui quando o teste de segurança é configurado."
msgid "SecurityReports|Manage and track vulnerabilities identified in your selected projects. Vulnerabilities for selected projects with security testing configured are shown here."
msgstr ""
@@ -29644,7 +29926,7 @@ msgid "SecurityReports|Monitor vulnerabilities in your project"
msgstr "Monitore vulnerabilidades em seu projeto"
msgid "SecurityReports|Monitored projects"
-msgstr ""
+msgstr "Projetos monitorados"
msgid "SecurityReports|More info"
msgstr "Mais informações"
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr "Painel de segurança"
@@ -29695,7 +29974,7 @@ msgid "SecurityReports|Security scans have run"
msgstr "As análises de segurança foram executadas"
msgid "SecurityReports|Select a project to add by using the project search field above."
-msgstr ""
+msgstr "Selecione um projeto para adicionar usando o campo de pesquisa acima."
msgid "SecurityReports|Set status"
msgstr "Definir status"
@@ -29713,7 +29992,7 @@ msgid "SecurityReports|Status"
msgstr "Status"
msgid "SecurityReports|Take survey"
-msgstr ""
+msgstr "Responder pesquisa"
msgid "SecurityReports|The security reports below contain one or more vulnerability findings that could not be parsed and were not recorded. Download the artifacts in the job output to investigate. Ensure any security report created conforms to the relevant %{helpPageLinkStart}JSON schema%{helpPageLinkEnd}."
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr "Ferramenta"
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -29764,10 +30046,10 @@ msgid "SecurityReports|Upgrade to manage vulnerabilities"
msgstr ""
msgid "SecurityReports|Vulnerability Management feature survey"
-msgstr ""
+msgstr "Pesquisa de funcionalidade de gerenciamento de vulnerabilidades"
msgid "SecurityReports|Vulnerability Report"
-msgstr ""
+msgstr "Relatório de vulnerabilidade"
msgid "SecurityReports|While it's rare to have no vulnerabilities for your pipeline, it can happen. In any event, we ask that you double check your settings to make sure all security scanning jobs have passed successfully."
msgstr ""
@@ -29821,13 +30103,13 @@ msgid "Select Page"
msgstr "Selecionar Página"
msgid "Select a branch"
-msgstr "Selecionar um branch"
+msgstr "Selecionar uma ramificação"
msgid "Select a file from the left sidebar to begin editing. Afterwards, you'll be able to commit your changes."
msgstr "Selecione um arquivo da barra lateral na esquerda para começar a editar. Depois, você poderá fazer commit das suas alterações."
msgid "Select a framework that applies to this project. %{linkStart}How are these added?%{linkEnd}"
-msgstr ""
+msgstr "Selecionar um framework que se aplique a esse projeto. %{linkStart}Como são adicionados?%{linkEnd}"
msgid "Select a group to invite"
msgstr "Selecione um grupo para convidar"
@@ -29839,7 +30121,7 @@ msgid "Select a milestone"
msgstr "Selecionar um marco"
msgid "Select a new namespace"
-msgstr "Selecione um novo namespace"
+msgstr "Selecione um novo espaço de nome"
msgid "Select a project"
msgstr "Selecione um projeto"
@@ -29866,7 +30148,7 @@ msgid "Select a template type"
msgstr "Selecione um tipo de modelo"
msgid "Select a time zone"
-msgstr ""
+msgstr "Selecione um fuso horário"
msgid "Select a timezone"
msgstr "Selecionar fuso horário"
@@ -29884,10 +30166,10 @@ msgid "Select assignee"
msgstr "Selecionar responsável"
msgid "Select branch"
-msgstr "Selecionar branch"
+msgstr "Selecionar ramificação"
msgid "Select due date"
-msgstr "Selecionar data limite"
+msgstr "Selecionar validade"
msgid "Select epic"
msgstr "Selecionar épico"
@@ -29947,7 +30229,7 @@ msgid "Select source"
msgstr "Selecionar fonte"
msgid "Select source branch"
-msgstr "Selecionar branch de origem"
+msgstr "Selecionar ramificação de origem"
msgid "Select start date"
msgstr "Selecionar data de início"
@@ -29965,7 +30247,7 @@ msgid "Select subscription"
msgstr "Selecionar assinatura"
msgid "Select target branch"
-msgstr "Selecionar branch de destino"
+msgstr "Selecionar ramificação de destino"
msgid "Select timezone"
msgstr "Selecionar fuso horário"
@@ -30145,13 +30427,13 @@ msgid "Serverless|Getting started with serverless"
msgstr "Primeiros passos com serverless"
msgid "Serverless|Help shape the future of Serverless at GitLab"
-msgstr ""
+msgstr "Ajude a moldar o futuro do Serverless no GitLab"
msgid "Serverless|If you believe none of these apply, please check back later as the function data may be in the process of becoming available."
msgstr "Se você acredita que nenhum destes se aplica, por favor, volte mais tarde, pois os dados da função podem estar no processo de se tornarem disponíveis."
msgid "Serverless|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
+msgstr "Para começar a usar funções como um serviço, você deve primeiro instalar Knative em seu cluster de Kubernetes. %{linkStart}Mais informações%{linkEnd}"
msgid "Serverless|Learn more about Serverless"
msgstr "Saiba mais sobre Serverless"
@@ -30160,25 +30442,25 @@ msgid "Serverless|No functions available"
msgstr "Nenhuma função disponível"
msgid "Serverless|Sign up for First Look"
-msgstr ""
+msgstr "Inscreva-se para First Look"
msgid "Serverless|The deploy job has not finished."
-msgstr "A tarefa de deploy ainda não terminou."
+msgstr "A tarefa de implantação ainda não terminou."
msgid "Serverless|The functions listed in the %{startTag}serverless.yml%{endTag} file don't match the namespace of your cluster."
-msgstr "As funções listadas no arquivo %{startTag}serverless.yml%{endTag} não coincidem com o namespace do seu cluster."
+msgstr "As funções listadas no arquivo %{startTag}serverless.yml%{endTag} não coincidem com o espaço de nome do seu cluster."
msgid "Serverless|There is currently no function data available from Knative. This could be for a variety of reasons including:"
msgstr "No momento não há dados de função disponíveis a partir do Knative. Isso pode ocorrer por uma variedade de motivos, incluindo:"
msgid "Serverless|We are continually striving to improve our Serverless functionality. As a Knative user, we would love to hear how we can make this experience better for you. Sign up for GitLab First Look today and we will be in touch shortly."
-msgstr ""
+msgstr "Estamos continuamente nos esforçando para melhorar nossa funcionalidade de Serverless. Como usuário do Knative, adoraríamos saber como podemos tornar essa experiência melhor para você. Inscreva-se no GitLab First Look hoje e entraremos em contato em breve."
msgid "Serverless|Your %{startTag}.gitlab-ci.yml%{endTag} file is not properly configured."
-msgstr ""
+msgstr "Seu arquivo %{startTag}.gitlab-ci,yml%{endTag} não está configurado adequadamente."
msgid "Serverless|Your repository does not have a corresponding %{startTag}serverless.yml%{endTag} file."
-msgstr ""
+msgstr "Seu repositório não possui um arquivo %{startTag}serverless.yml%{endTag} correspondente."
msgid "Service"
msgstr "Serviço"
@@ -30226,7 +30508,7 @@ msgid "ServiceDesk|Use Service Desk to connect with your users and offer custome
msgstr "Use a central de serviços para conectar com seus usuários e oferecer suporte ao cliente por e-mail dentro do GitLab"
msgid "ServiceDesk|Your users can send emails to this address:"
-msgstr ""
+msgstr "Seus usuários podem enviar e-mails para este endereço:"
msgid "ServicePing|Service ping is off"
msgstr ""
@@ -30268,7 +30550,7 @@ msgid "Set default and restrict visibility levels. Configure import sources and
msgstr "Definir padrão e restringir os níveis de visibilidade. Configurar fontes de importação e protocolo de acesso git."
msgid "Set due date"
-msgstr "Definir data limite"
+msgstr "Definir validade"
msgid "Set iteration"
msgstr ""
@@ -30304,13 +30586,13 @@ msgid "Set size limits for displaying diffs in the browser."
msgstr ""
msgid "Set target branch"
-msgstr "Selecionar branch de destino"
+msgstr "Selecionar ramificação de destino"
msgid "Set target branch to %{branch_name}."
-msgstr "Definir branch de destino à %{branch_name}."
+msgstr "Definir ramificação de destino à %{branch_name}."
msgid "Set the default branch for this project. All merge requests and commits are made against this branch unless you specify a different one."
-msgstr ""
+msgstr "Defina a ramificação padrão para este projeto. Todas as merge requests e commits são feitos nessa ramificação, a menos que você especifique um diferente."
msgid "Set the due date to %{due_date}."
msgstr "Definir a data limite para %{due_date}."
@@ -30321,7 +30603,7 @@ msgstr "Define a interação como %{iteration_reference}."
msgid "Set the milestone to %{milestone_reference}."
msgstr "Definir o marco como %{milestone_reference}."
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30334,7 +30616,7 @@ msgid "Set up CI/CD"
msgstr "Configurar CI/CD"
msgid "Set up Jira Integration"
-msgstr ""
+msgstr "Configurar integração do Jira"
msgid "Set up a %{type} Runner for a project"
msgstr ""
@@ -30343,7 +30625,7 @@ msgid "Set up a %{type} runner manually"
msgstr ""
msgid "Set up a hardware device as a second factor to sign in."
-msgstr ""
+msgstr "Definir um dispositivo de hardware como o segundo fator para entrar."
msgid "Set up assertions/attributes/claims (email, first_name, last_name) and NameID according to %{docsLinkStart}the documentation %{icon}%{docsLinkEnd}"
msgstr "Configurar asserções/atributos/alegações (email, first_name, last_name) e NameID de acordo com %{docsLinkStart}a documentação %{icon}%{docsLinkEnd}"
@@ -30369,7 +30651,7 @@ msgstr "Definir peso"
msgid "Set weight to %{weight}."
msgstr "Define o peso para %{weight}."
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30415,10 +30697,10 @@ msgid "SetStatusModal|Your status resets on %{date}."
msgstr ""
msgid "Sets %{epic_ref} as parent epic."
-msgstr ""
+msgstr "Definir %{epic_ref} como épico pai."
msgid "Sets target branch to %{branch_name}."
-msgstr "Definir branch de destino à %{branch_name}."
+msgstr "Definir ramificação de destino à %{branch_name}."
msgid "Sets the due date to %{due_date}."
msgstr "Definir a data limite para %{due_date}."
@@ -30430,7 +30712,7 @@ msgid "Sets the milestone to %{milestone_reference}."
msgstr "Define o marco como %{milestone_reference}."
msgid "Sets the severity"
-msgstr ""
+msgstr "Definir a severidade"
msgid "Sets time estimate to %{time_estimate}."
msgstr "Define a estimativa de tempo como %{time_estimate}."
@@ -30481,13 +30763,13 @@ msgid "Share the %{strong_open}GitLab single sign-on URL%{strong_close} with mem
msgstr ""
msgid "Shared Runners"
-msgstr "Runners Compartilhados"
+msgstr "Executores compartilhados"
msgid "Shared projects"
msgstr "Projetos compartilhados"
msgid "Shared runners"
-msgstr ""
+msgstr "Executores compartilhados"
msgid "Shared runners are disabled for the parent group"
msgstr ""
@@ -30499,7 +30781,7 @@ msgid "Shared runners details"
msgstr ""
msgid "Shared runners help link"
-msgstr "Link de ajuda de runners compartilhados"
+msgstr "Link de ajuda de executores compartilhados"
msgid "SharedRunnersMinutesSettings|By resetting the pipeline minutes for this namespace, the currently used minutes will be set to zero."
msgstr "Ao redefinir os minutos de pipeline para esse espaço de nomes, os minutos atualmente usados serão definido para zero."
@@ -30517,10 +30799,10 @@ msgid "Should you ever lose your phone or access to your one time password secre
msgstr "Se você perder seu telefone ou acessar o seu segredo de senha de uso único, cada um desses códigos de recuperação poderá ser usado uma vez para recuperar o acesso à sua conta. Guarde-os em um lugar seguro, ou você %{boldStart}irá%{boldEnd} perder o acesso à sua conta."
msgid "Show Pipeline ID"
-msgstr ""
+msgstr "Mostrar ID do pipeline"
msgid "Show Pipeline IID"
-msgstr ""
+msgstr "Mostrar IID do pipeline"
msgid "Show all activity"
msgstr "Mostrar todas as atividades"
@@ -30570,9 +30852,6 @@ msgstr "Mostrar etiquetas"
msgid "Show latest version"
msgstr "Mostrar a versão mais recente"
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30595,10 +30874,10 @@ msgid "Show parent subgroups"
msgstr "Mostrar subgrupos acima"
msgid "Show the Closed list"
-msgstr ""
+msgstr "Mostra a lista fechada"
msgid "Show the Open list"
-msgstr ""
+msgstr "Mostrar a lista aberta"
msgid "Show whitespace changes"
msgstr "Mostrar as alterações de espaço em branco"
@@ -30653,7 +30932,7 @@ msgid "Side-by-side"
msgstr "Lado a lado"
msgid "Sidebar|%{name}: %{value}"
-msgstr ""
+msgstr "%{name}: %{value}"
msgid "Sidebar|Assign health status"
msgstr "Atribuir status de saúde"
@@ -30662,7 +30941,7 @@ msgid "Sidebar|Health status"
msgstr "Status de saúde"
msgid "Sidebar|No status"
-msgstr ""
+msgstr "Nenhum status"
msgid "Sidebar|None"
msgstr "Nenhum"
@@ -30698,7 +30977,7 @@ msgid "Sign in via 2FA code"
msgstr "Entrar via código da A2F"
msgid "Sign in with"
-msgstr ""
+msgstr "Entrar com"
msgid "Sign in with Single Sign-On"
msgstr "Entre com logon único"
@@ -30796,11 +31075,14 @@ msgstr ""
msgid "Size"
msgstr "Tamanho"
+msgid "Size Limits"
+msgstr "Limite de tamanho"
+
msgid "Size limit per repository (MB)"
msgstr "Limite de tamanho por repositório (MB)"
msgid "Skip outdated deployment jobs"
-msgstr ""
+msgstr "Pular tarefas de implantação desatualizados"
msgid "Skipped"
msgstr "Ignorado"
@@ -30905,10 +31187,10 @@ msgid "Some of the designs you tried uploading did not change:"
msgstr ""
msgid "Someone edited the issue at the same time you did. Please check out %{linkStart}the issue%{linkEnd} and make sure your changes will not unintentionally remove theirs."
-msgstr ""
+msgstr "Alguém editou a issue ao mesmo tempo que você. Por favor, verifique %{linkStart}a issue%{linkEnd} e tenha certeza de que suas alterações não irão intencionalmente remover as alterações da outra pessoa."
msgid "Someone edited this %{issueType} at the same time you did. The description has been updated and you will need to make your changes again."
-msgstr ""
+msgstr "Alguém editou este %{issueType} ao mesmo tempo que você. A descrição foi atualizada e você precisará fazer as alterações novamente."
msgid "Someone edited this merge request at the same time you did. Please refresh the page to see changes."
msgstr "Alguém editou este merge request ao mesmo tempo que você. Por favor, atualize a página para ver as alterações."
@@ -31019,7 +31301,7 @@ msgid "Something went wrong while fetching requirements list."
msgstr ""
msgid "Something went wrong while fetching source branches."
-msgstr "Algo deu errado ao buscar os branchs de origem."
+msgstr "Algo deu errado ao buscar as ramificações de origem."
msgid "Something went wrong while fetching the environments for this merge request. Please try again."
msgstr "Algo deu errado ao buscar os ambientes para esse merge request. Por favor, tente novamente."
@@ -31139,13 +31421,22 @@ msgid "Sort direction"
msgstr ""
msgid "Sort direction: Ascending"
-msgstr ""
+msgstr "Sentido da ordenação: Acrescente"
msgid "Sort direction: Descending"
-msgstr ""
+msgstr "Sentido da ordenação: Decrescente"
msgid "SortOptions|Blocking"
-msgstr ""
+msgstr "Bloqueado"
+
+msgid "SortOptions|Closed date"
+msgstr "Data de fechamento"
+
+msgid "SortOptions|Closed earlier"
+msgstr "Fechado anteriormente"
+
+msgid "SortOptions|Closed recently"
+msgstr "Fechado recentemente"
msgid "SortOptions|Created date"
msgstr "Data de criação"
@@ -31229,13 +31520,13 @@ msgid "SortOptions|Oldest created"
msgstr "Criação mais antiga"
msgid "SortOptions|Oldest last activity"
-msgstr ""
+msgstr "Última atividade mais antiga"
msgid "SortOptions|Oldest sign in"
msgstr "Assinados mais antigos"
msgid "SortOptions|Oldest starred"
-msgstr ""
+msgstr "Favoritado mais antigo"
msgid "SortOptions|Oldest updated"
msgstr "Atualização mais antiga"
@@ -31250,7 +31541,7 @@ msgid "SortOptions|Project"
msgstr "Projeto"
msgid "SortOptions|Recent last activity"
-msgstr ""
+msgstr "Atividade mais recente"
msgid "SortOptions|Recent sign in"
msgstr "Assinados mais novos"
@@ -31280,7 +31571,7 @@ msgid "SortOptions|Start soon"
msgstr "Iniciar mais próximo"
msgid "SortOptions|Title"
-msgstr ""
+msgstr "Título"
msgid "SortOptions|Type"
msgstr "Tipo"
@@ -31295,10 +31586,10 @@ msgid "Source"
msgstr "Origem"
msgid "Source (branch or tag)"
-msgstr "Fonte (branch or tag)"
+msgstr "Fonte (ramificação ou tag)"
msgid "Source Branch"
-msgstr "Branch de origem"
+msgstr "Ramificação de origem"
msgid "Source Editor instance is required to set up an extension."
msgstr ""
@@ -31307,7 +31598,7 @@ msgid "Source IP"
msgstr ""
msgid "Source branch"
-msgstr "Branch de origem"
+msgstr "Ramificação de origem"
msgid "Source branch: %{source_branch_open}%{source_branch}%{source_branch_close}"
msgstr "Branch de origem: %{source_branch_open}%{source_branch}%{source_branch_close}"
@@ -31343,7 +31634,7 @@ msgid "SourcegraphAdmin|More information"
msgstr ""
msgid "SourcegraphAdmin|Save changes"
-msgstr ""
+msgstr "Salvar alterações"
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
@@ -31370,7 +31661,7 @@ msgid "Spam Check API Key"
msgstr ""
msgid "Spam Logs"
-msgstr "Logs de spam"
+msgstr "Registros de spam"
msgid "Spam and Anti-bot Protection"
msgstr "Proteção contra spam e anti-bot"
@@ -31379,7 +31670,7 @@ msgid "Spam log successfully submitted as ham."
msgstr ""
msgid "Specific runners"
-msgstr ""
+msgstr "Executores específicos"
msgid "Specified URL cannot be used: \"%{reason}\""
msgstr ""
@@ -31565,7 +31856,7 @@ msgid "StaticSiteEditor|Branch could not be created."
msgstr ""
msgid "StaticSiteEditor|Copy update"
-msgstr ""
+msgstr "Copiar atualização"
msgid "StaticSiteEditor|Could not commit the content changes."
msgstr ""
@@ -31577,7 +31868,7 @@ msgid "StaticSiteEditor|Creating your merge request"
msgstr ""
msgid "StaticSiteEditor|Incompatible file content"
-msgstr ""
+msgstr "Conteúdo de arquivo incompatível"
msgid "StaticSiteEditor|Markdown formatting preferences introduced by the Static Site Editor"
msgstr ""
@@ -31586,7 +31877,7 @@ msgid "StaticSiteEditor|Return to site"
msgstr "Voltar ao site"
msgid "StaticSiteEditor|Static site editor"
-msgstr ""
+msgstr "Editor estático de site"
msgid "StaticSiteEditor|The Static Site Editor is currently configured to only edit Markdown content on pages generated from Middleman. Visit the documentation to learn more about configuring your site to use the Static Site Editor."
msgstr ""
@@ -31598,7 +31889,7 @@ msgid "StaticSiteEditor|Update %{sourcePath} file"
msgstr ""
msgid "StaticSiteEditor|View documentation"
-msgstr ""
+msgstr "Ver documentação"
msgid "StaticSiteEditor|You can set an assignee to get your changes reviewed and deployed once your merge request is created."
msgstr ""
@@ -31628,7 +31919,7 @@ msgid "StatusCheck|API to check"
msgstr ""
msgid "StatusCheck|Add status check"
-msgstr ""
+msgstr "Adicionar verificação de status"
msgid "StatusCheck|All passed"
msgstr ""
@@ -31667,10 +31958,10 @@ msgid "StatusCheck|Remove status check?"
msgstr ""
msgid "StatusCheck|Service name"
-msgstr ""
+msgstr "Nome do serviço"
msgid "StatusCheck|Status checks"
-msgstr ""
+msgstr "Verificações de status"
msgid "StatusCheck|Status to check"
msgstr ""
@@ -31691,16 +31982,16 @@ msgid "StatusPage|AWS %{docsLink}"
msgstr ""
msgid "StatusPage|AWS Secret access key"
-msgstr ""
+msgstr "Chave de acesso secreta do AWS"
msgid "StatusPage|AWS access key ID"
-msgstr ""
+msgstr "ID da chave de acesso do AWS"
msgid "StatusPage|AWS region"
-msgstr ""
+msgstr "Região do AWS"
msgid "StatusPage|Active"
-msgstr ""
+msgstr "Ativo"
msgid "StatusPage|Bucket %{docsLink}"
msgstr ""
@@ -31712,10 +32003,10 @@ msgid "StatusPage|S3 Bucket name"
msgstr ""
msgid "StatusPage|Status page"
-msgstr ""
+msgstr "Página de status"
msgid "StatusPage|Status page URL"
-msgstr ""
+msgstr "URL da página de status"
msgid "StatusPage|To publish incidents to an external status page, GitLab stores a JSON file in your Amazon S3 account at a location that your external status page service can access. Make sure to also set up %{docsLink}"
msgstr ""
@@ -31817,10 +32108,10 @@ msgid "Submit as spam"
msgstr "Enviar como spam"
msgid "Submit changes"
-msgstr ""
+msgstr "Enviar alterações"
msgid "Submit changes..."
-msgstr ""
+msgstr "Enviar alterações..."
msgid "Submit feedback"
msgstr "Enviar feedback"
@@ -31835,7 +32126,7 @@ msgid "Submit the current review."
msgstr ""
msgid "Submit your changes"
-msgstr ""
+msgstr "Enviar suas alterações"
msgid "Submitted as ham"
msgstr ""
@@ -32303,7 +32594,7 @@ msgid "Survey Response"
msgstr ""
msgid "Switch branch"
-msgstr ""
+msgstr "Trocar ramificação"
msgid "Switch branch/tag"
msgstr "Trocar branch/tag"
@@ -32336,10 +32627,10 @@ msgid "Syncing…"
msgstr ""
msgid "Syntax is correct."
-msgstr ""
+msgstr "A sintaxe está correta."
msgid "Syntax is incorrect."
-msgstr ""
+msgstr "A sintaxe está incorreta."
msgid "System"
msgstr "Sistema"
@@ -32393,10 +32684,10 @@ msgid "Tag list:"
msgstr "Lista de tags:"
msgid "Tag name"
-msgstr ""
+msgstr "Nome da tag"
msgid "Tag name is required"
-msgstr ""
+msgstr "Nome da tag é obrigatória"
msgid "Tag push events"
msgstr ""
@@ -32498,16 +32789,16 @@ msgid "TagsPage|protected"
msgstr "protegido"
msgid "Target Branch"
-msgstr "Branch de destino"
+msgstr "Ramificação de destino"
msgid "Target Path"
msgstr ""
msgid "Target branch"
-msgstr "Branch de destino"
+msgstr "Ramificação de destino"
msgid "Target-Branch"
-msgstr "Branch de destino"
+msgstr "Ramificação de destino"
msgid "Task ID: %{elastic_task}"
msgstr "ID da tarefa: %{elastic_task}"
@@ -32525,7 +32816,7 @@ msgid "TeamcityIntegration|Trigger TeamCity CI after every push to the repositor
msgstr ""
msgid "Tell us your experiences with the new Markdown editor %{linkStart}in this feedback issue%{linkEnd}."
-msgstr ""
+msgstr "Conte-nos as suas experiências com o novo editor Markdown %{linkStart}nessa issue%{linkEnd}."
msgid "Template"
msgstr "Modelo"
@@ -32570,7 +32861,7 @@ msgid "Terms of Service and Privacy Policy"
msgstr "Termos de Serviço e Política de Privacidade"
msgid "Terraform"
-msgstr ""
+msgstr "Terraform"
msgid "TerraformBanner|Learn more about GitLab's Backend State"
msgstr ""
@@ -32616,10 +32907,13 @@ msgid "Terraform|Are you sure you want to remove the Terraform State %{name}?"
msgstr ""
msgid "Terraform|Cancel"
-msgstr ""
+msgstr "Cancelar"
+
+msgid "Terraform|Copy Terraform init command"
+msgstr "Copiar o comando init do Terraform"
msgid "Terraform|Details"
-msgstr ""
+msgstr "Detalhes"
msgid "Terraform|Download JSON"
msgstr "Baixar JSON"
@@ -32628,10 +32922,10 @@ msgid "Terraform|Generating the report caused an error."
msgstr ""
msgid "Terraform|Get started with Terraform"
-msgstr ""
+msgstr "Primeiros passos com Terraform"
msgid "Terraform|How to use GitLab-managed Terraform State?"
-msgstr ""
+msgstr "Como usar o Terraform State gerenciado pelo GitLab?"
msgid "Terraform|Job status"
msgstr ""
@@ -32640,7 +32934,7 @@ msgid "Terraform|Lock"
msgstr ""
msgid "Terraform|Locked"
-msgstr ""
+msgstr "Bloqueado"
msgid "Terraform|Locked by %{user} %{timeAgo}"
msgstr "Bloqueado por %{user} em %{timeAgo}"
@@ -32649,25 +32943,28 @@ msgid "Terraform|Locking state"
msgstr ""
msgid "Terraform|Name"
-msgstr ""
+msgstr "Nome"
msgid "Terraform|Pipeline"
-msgstr ""
+msgstr "Pipeline"
msgid "Terraform|Remove"
-msgstr ""
+msgstr "Remover"
msgid "Terraform|Remove state file and versions"
msgstr ""
msgid "Terraform|Removing"
-msgstr ""
+msgstr "Removendo"
msgid "Terraform|Reported Resource Changes: %{addNum} to add, %{changeNum} to change, %{deleteNum} to delete"
msgstr ""
msgid "Terraform|States"
-msgstr ""
+msgstr "Estados"
+
+msgid "Terraform|Terraform init command"
+msgstr "Comando init do Terraform"
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
@@ -32675,11 +32972,14 @@ msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
msgid "Terraform|Unknown User"
-msgstr ""
+msgstr "Usuário desconhecido"
msgid "Terraform|Unlock"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32848,7 +33148,7 @@ msgid "Thank you for your business."
msgstr ""
msgid "Thank you for your feedback!"
-msgstr ""
+msgstr "Obrigado pela sua opinião!"
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr "Obrigado pelo seu relatório. Um administrador do GitLab irá analisá-lo em breve."
@@ -32898,10 +33198,10 @@ msgid "The ID of the application."
msgstr ""
msgid "The Issue Tracker is the place to add things that need to be improved or solved in a project"
-msgstr "O Rastreador de Issue é o lugar para adicionar coisas que precisam ser melhoradas ou resolvidas em um projeto"
+msgstr "O rastreador de issue é o lugar para adicionar coisas que precisam ser melhoradas ou resolvidas em um projeto"
msgid "The Issue Tracker is the place to add things that need to be improved or solved in a project. You can register or sign in to create issues for this project."
-msgstr "O Rastreador de Issue é o lugar para adicionar coisas que precisam ser melhoradas ou resolvidas em um projeto. Você pode se registrar ou entrar para criar issues para este projeto."
+msgstr "O rastreador de issue é o lugar para adicionar coisas que precisam ser melhoradas ou resolvidas em um projeto. Você pode se registrar ou entrar para criar issues para este projeto."
msgid "The Prometheus server responded with \"bad request\". Please check your queries are correct and are supported in your Prometheus version. %{documentationLink}"
msgstr ""
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -32991,7 +33291,7 @@ msgid "The dependency list details information about the components used within
msgstr "A lista de dependências detalha informações sobre os componentes usados em seu projeto."
msgid "The deployment of this job to %{environmentLink} did not succeed."
-msgstr "O deploy desta tarefa para o ambiente %{environmentLink} foi mal sucedida."
+msgstr "A implantação desta tarefa para o ambiente %{environmentLink} foi mal sucedida."
msgid "The designs you tried uploading did not change."
msgstr ""
@@ -33065,7 +33365,7 @@ msgid "The form contains the following warning:"
msgstr ""
msgid "The global settings require you to enable Two-Factor Authentication for your account."
-msgstr ""
+msgstr "As configurações globais exigem que você habilite a autenticação de dois fatores para sua conta."
msgid "The group and any internal projects can be viewed by any logged in user except external users."
msgstr ""
@@ -33125,11 +33425,14 @@ msgid "The issue was successfully promoted to an epic. Redirecting to epic..."
msgstr ""
msgid "The latest artifacts created by jobs in the most recent successful pipeline will be stored."
-msgstr ""
+msgstr "Os artefatos mais recentes criados por tarefas no pipeline mais recente e bem-sucedido serão armazenados."
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33155,7 +33458,7 @@ msgid "The maximum file size in megabytes for individual job artifacts."
msgstr ""
msgid "The maximum file size is %{size}."
-msgstr ""
+msgstr "O tamanho máximo de arquivo é %{size}."
msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
msgstr ""
@@ -33166,17 +33469,14 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr "Os conflitos de merge para esta merge request não podem ser resolvidos pelo GitLab. Por favor, tente resolvê-los localmente."
msgid "The merge conflicts for this merge request have already been resolved."
-msgstr ""
+msgstr "Os conflitos de mesclagem para esta solicitação de mesclagem já foram resolvidos."
msgid "The merge conflicts for this merge request have already been resolved. Please return to the merge request."
-msgstr ""
+msgstr "Os conflitos de mesclagem para esta solicitação de mesclagem já foram resolvidos. Por favor, retorne para a solicitação de mesclagem."
msgid "The merge request can now be merged."
msgstr ""
@@ -33188,7 +33488,7 @@ msgid "The name \"%{name}\" is already taken in this directory."
msgstr ""
msgid "The name of the CI/CD configuration file. A path relative to the root directory is optional (for example %{code_open}my/path/.myfile.yml%{code_close})."
-msgstr ""
+msgstr "O nome do arquivo de configuração de CI/CD. Um caminho relativo ao diretório raiz é opcional (por exemplo, %{code_open}my/path/.myfile.yml%{code_close})."
msgid "The name of the Jenkins project. Copy the name from the end of the URL to the project."
msgstr ""
@@ -33308,7 +33608,7 @@ msgid "The snippet is visible to any logged in user except external users."
msgstr ""
msgid "The source branch will be deleted"
-msgstr "O branch de origem será excluído"
+msgstr "A ramificação de origem será excluída"
msgid "The specified tab is invalid, please select another"
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr "A ação de atualização irá expirar depois de %{number_of_minutes} minutos. Para grandes repositórios, use uma combinação de clone/push."
@@ -33437,7 +33740,7 @@ msgid "There are no open issues"
msgstr "Não há issues abertas"
msgid "There are no open merge requests"
-msgstr "Não há merge requests em aberto"
+msgstr "Não há solicitações de mesclagem em aberto"
msgid "There are no open requirements"
msgstr "Não há requisitos em aberto"
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33545,7 +33857,7 @@ msgid "There was a problem updating the keep latest artifacts setting."
msgstr ""
msgid "There was an error %{message} todo."
-msgstr ""
+msgstr "Houve um erro %{message} na tarefa pendente."
msgid "There was an error adding a To Do."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33716,19 +34025,19 @@ msgid "These paths are protected for POST requests."
msgstr ""
msgid "These runners are shared across projects in this group."
-msgstr ""
+msgstr "Esses executores são compartilhados entre projetos neste grupo."
msgid "These runners are shared across this GitLab instance."
msgstr ""
msgid "These runners are specific to this project."
-msgstr ""
+msgstr "Esses executores são específicos para este projeto."
msgid "These variables are inherited from the parent group."
msgstr ""
msgid "These will be sent to %{email} in an attachment once finished."
-msgstr ""
+msgstr "Estes serão enviados para %{email} em um anexo quando terminado."
msgid "Third Party Advisory Link"
msgstr ""
@@ -33773,7 +34082,7 @@ msgid "This URL is already used for another link; duplicate URLs are not allowed
msgstr ""
msgid "This action can lead to data loss. To prevent accidental actions we ask you to confirm your intention."
-msgstr ""
+msgstr "Essa ação pode levar à perda de dados. Para evitar ações acidentais, pedimos que você confirme sua intenção."
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
@@ -33818,7 +34127,7 @@ msgid "This attachment has been truncated to avoid exceeding the maximum allowed
msgstr ""
msgid "This block is self-referential"
-msgstr ""
+msgstr "Esse bloco é autorreferencial"
msgid "This board's scope is reduced"
msgstr "O escopo deste painel está reduzido"
@@ -33881,7 +34190,7 @@ msgid "This endpoint has been requested too many times. Try again later."
msgstr ""
msgid "This environment has no deployments yet."
-msgstr "Este ambiente tem nenhum deploy."
+msgstr "Este ambiente tem nenhuma implantação."
msgid "This environment is being deployed"
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr "Este campo é obrigatório"
msgid "This field is required."
msgstr "Este campo é obrigatório."
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr "Esse grupo"
@@ -33950,7 +34256,7 @@ msgid "This is a \"Ghost User\", created to hold all issues authored by users th
msgstr ""
msgid "This is a Jira user."
-msgstr ""
+msgstr "Este é um usuário do Jira."
msgid "This is a confidential %{noteableTypeText}."
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr "Esta é a sua sessão atual"
msgid "This issue is currently blocked by the following issues:"
msgstr "Essa issue está atualmente bloqueada pelas seguintes issues:"
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -34022,7 +34331,7 @@ msgid "This job is an out-of-date deployment to %{environmentLink} using cluster
msgstr ""
msgid "This job is an out-of-date deployment to %{environmentLink}."
-msgstr "Esta tarefa é um deploy desatualizado para o ambiente %{environmentLink}."
+msgstr "Esta tarefa é uma implantação desatualizado para o ambiente %{environmentLink}."
msgid "This job is an out-of-date deployment to %{environmentLink}. View the %{deploymentLink}."
msgstr ""
@@ -34043,7 +34352,7 @@ msgid "This job is creating a deployment to %{environmentLink} using cluster %{c
msgstr ""
msgid "This job is creating a deployment to %{environmentLink}."
-msgstr "Esta tarefa está criando um deploy para %{environmentLink}."
+msgstr "Esta tarefa está criando uma implantação para %{environmentLink}."
msgid "This job is creating a deployment to %{environmentLink}. This will overwrite the %{deploymentLink}."
msgstr ""
@@ -34058,7 +34367,7 @@ msgid "This job is deployed to %{environmentLink}."
msgstr ""
msgid "This job is in pending state and is waiting to be picked by a runner"
-msgstr "Esta tarefa está em estado pendente e está esperando para ser escolhido por um runner"
+msgstr "Esta tarefa está em estado pendente e está esperando para ser escolhido por um executor"
msgid "This job is performing tasks that must complete before it can start"
msgstr ""
@@ -34112,10 +34421,10 @@ msgid "This merge request is from an internal project to a public project."
msgstr ""
msgid "This merge request is locked."
-msgstr "Esse merge request está bloqueado."
+msgstr "Essa solicitação de mesclagem está bloqueado."
msgid "This merge request is still a draft."
-msgstr "Este merge request ainda é um rascunho."
+msgstr "Essa solicitação de mesclagem ainda é um rascunho."
msgid "This merge request was merged. To apply this suggestion, edit this file directly."
msgstr ""
@@ -34133,13 +34442,13 @@ msgid "This page is unavailable because you are not allowed to read information
msgstr "Esta página não está disponível porque você não tem permissão para ler informações de vários projetos."
msgid "This page sends a payload. Go back to the events page to see a newly created event."
-msgstr ""
+msgstr "Esta página envia uma carga útil. Volte para a página de eventos para ver um evento recém-criado."
msgid "This pipeline makes use of a predefined CI/CD configuration enabled by %{b_open}Auto DevOps.%{b_close}"
msgstr ""
msgid "This pipeline makes use of a predefined CI/CD configuration enabled by %{strongStart}Auto DevOps.%{strongEnd}"
-msgstr ""
+msgstr "Este pipeline faz uso de uma configuração de CI/CD predefinida habilitada por %{strongStart}Auto DevOps.%{strongEnd}"
msgid "This pipeline was triggered by a schedule."
msgstr ""
@@ -34148,7 +34457,7 @@ msgid "This project"
msgstr "Este projeto"
msgid "This project does not belong to a group and cannot make use of group runners."
-msgstr ""
+msgstr "Este projeto não pertence a um grupo e não pode usar executores de grupo."
msgid "This project does not have %{service_desk_link_start}Service Desk%{service_desk_link_end} enabled, so the user who created the issue will no longer receive email notifications about new activity."
msgstr ""
@@ -34163,7 +34472,7 @@ msgid "This project is archived and cannot be commented on."
msgstr "Este projeto está arquivado e não pode ser comentado."
msgid "This project is licensed under the %{strong_start}%{license_name}%{strong_end}."
-msgstr ""
+msgstr "Este projeto está licenciado sob o %{strong_start}%{license_name}%{strong_end}."
msgid "This project manages its dependencies using %{strong_start}%{manager_name}%{strong_end}"
msgstr ""
@@ -34187,7 +34496,7 @@ msgid "This repository has never been checked."
msgstr ""
msgid "This repository is currently empty. A new Auto DevOps pipeline will be created after a new file has been pushed to a branch."
-msgstr ""
+msgstr "Este repositório está vazio no momento. Um novo pipeline do Auto DevOps será criado depois que um novo arquivo for enviado para uma ramificação."
msgid "This repository was last checked %{last_check_timestamp}. The check %{strong_start}failed.%{strong_end} See the 'repocheck.log' file for error messages."
msgstr ""
@@ -34196,7 +34505,7 @@ msgid "This repository was last checked %{last_check_timestamp}. The check passe
msgstr ""
msgid "This runner will only run on pipelines triggered on protected branches"
-msgstr "Este Runner somente será executado em Pipelines acionados em branches protegidos"
+msgstr "Este executor somente será executado em Pipelines acionados em ramificações protegidas"
msgid "This service allows users to perform common operations on this project by entering slash commands in Slack."
msgstr ""
@@ -34211,7 +34520,7 @@ msgid "This suggestion already matches its content."
msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
-msgstr ""
+msgstr "Este usuário não pode ser desbloqueado manualmente a partir do GitLab"
msgid "This user does not have a pending request"
msgstr ""
@@ -34256,13 +34565,13 @@ msgid "Thread to reply to cannot be found"
msgstr ""
msgid "Threat Monitoring"
-msgstr ""
+msgstr "Monitoramento de ameaças"
msgid "ThreatMonitoring|Alert Details"
-msgstr ""
+msgstr "Detalhes de alerta"
msgid "ThreatMonitoring|Alerts"
-msgstr ""
+msgstr "Alertas"
msgid "ThreatMonitoring|All Environments"
msgstr "Todos os ambientes"
@@ -34280,10 +34589,10 @@ msgid "ThreatMonitoring|Container NetworkPolicies not detected"
msgstr ""
msgid "ThreatMonitoring|Date and time"
-msgstr ""
+msgstr "Data e hora"
msgid "ThreatMonitoring|Dismissed"
-msgstr ""
+msgstr "Dispensado"
msgid "ThreatMonitoring|Dropped Packets"
msgstr ""
@@ -34292,7 +34601,7 @@ msgid "ThreatMonitoring|Environment"
msgstr "Ambiente"
msgid "ThreatMonitoring|Events"
-msgstr ""
+msgstr "Eventos"
msgid "ThreatMonitoring|Failed to create incident, please try again."
msgstr ""
@@ -34301,37 +34610,37 @@ msgid "ThreatMonitoring|Hide dismissed alerts"
msgstr ""
msgid "ThreatMonitoring|In review"
-msgstr ""
+msgstr "Em revisão"
msgid "ThreatMonitoring|Incident"
-msgstr ""
+msgstr "Incidente"
msgid "ThreatMonitoring|Name"
-msgstr ""
+msgstr "Nome"
msgid "ThreatMonitoring|No alerts available to display. See %{linkStart}enabling threat alerts%{linkEnd} for more information on adding alerts to the list."
-msgstr ""
+msgstr "Não há alerta disponível para exibir. Veja %{linkStart}ativando as alertas de ameaças%{linkEnd} para mais informações sobre a adição de alerta à lista."
msgid "ThreatMonitoring|No alerts to display."
-msgstr ""
+msgstr "Nenhum alerta para exibir."
msgid "ThreatMonitoring|No environments detected"
msgstr "Nenhum ambiente detectado"
msgid "ThreatMonitoring|Operations Per Second"
-msgstr ""
+msgstr "Operações por segundo"
msgid "ThreatMonitoring|Packet Activity"
-msgstr ""
+msgstr "Atividade de pacote"
msgid "ThreatMonitoring|Policies"
-msgstr ""
+msgstr "Políticas"
msgid "ThreatMonitoring|Requests"
-msgstr ""
+msgstr "Requisições"
msgid "ThreatMonitoring|Resolved"
-msgstr ""
+msgstr "Resolvido"
msgid "ThreatMonitoring|Show last"
msgstr "Mostrar último"
@@ -34343,10 +34652,10 @@ msgid "ThreatMonitoring|Something went wrong, unable to fetch statistics"
msgstr ""
msgid "ThreatMonitoring|Statistics"
-msgstr ""
+msgstr "Estatísticas"
msgid "ThreatMonitoring|Status"
-msgstr ""
+msgstr "Status"
msgid "ThreatMonitoring|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
@@ -34355,28 +34664,28 @@ msgid "ThreatMonitoring|There was an error while updating the status of the aler
msgstr ""
msgid "ThreatMonitoring|Threat Monitoring"
-msgstr ""
+msgstr "Monitoramento de ameaças"
msgid "ThreatMonitoring|Threat Monitoring help page link"
msgstr ""
msgid "ThreatMonitoring|Time"
-msgstr ""
+msgstr "Tempo"
msgid "ThreatMonitoring|To view this data, ensure you have configured an environment for this project and that at least one threat monitoring feature is enabled. %{linkStart}More information%{linkEnd}"
msgstr ""
msgid "ThreatMonitoring|Total Packets"
-msgstr ""
+msgstr "Total de pacotes"
msgid "ThreatMonitoring|Total Requests"
-msgstr ""
+msgstr "Total de requisições"
msgid "ThreatMonitoring|Unreviewed"
-msgstr ""
+msgstr "Não revisado"
msgid "ThreatMonitoring|View documentation"
-msgstr ""
+msgstr "Ver documentação"
msgid "Throughput"
msgstr ""
@@ -34433,7 +34742,7 @@ msgid "Time spent"
msgstr "Tempo gasto"
msgid "Time to merge"
-msgstr "Tempo para fazer o merge"
+msgstr "Tempo para mesclar"
msgid "Time to subtract exceeds the total time spent"
msgstr ""
@@ -34460,7 +34769,7 @@ msgid "TimeTracking|Estimated:"
msgstr "Estimado:"
msgid "TimeTracking|Over by %{timeRemainingHumanReadable}"
-msgstr ""
+msgstr "Mais de %{timeRemainingHumanReadable}"
msgid "TimeTracking|Spent"
msgstr "Gasto"
@@ -34656,13 +34965,13 @@ msgid "To GitLab"
msgstr "Para o GitLab"
msgid "To accept this invitation, create an account or sign in."
-msgstr ""
+msgstr "Para aceitar este convite, crie uma conta ou entre."
msgid "To accept this invitation, sign in or create an account."
-msgstr ""
+msgstr "Para aceitar este convite, entre ou crie uma conta."
msgid "To accept this invitation, sign in."
-msgstr ""
+msgstr "Para aceitar este convite, entre."
msgid "To access this domain create a new DNS record"
msgstr "Para acessar este domínio crie um novo registro DNS"
@@ -34704,10 +35013,10 @@ msgid "To find the state of this project's repository at the time of any of thes
msgstr ""
msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
-msgstr ""
+msgstr "Para proteger ainda mais sua conta, considere configurar um método de %{mfa_link_start}autenticação de dois fatores%{mfa_link_end}"
msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
-msgstr ""
+msgstr "Para proteger ainda mais sua conta, considere configurar um método de autenticação de dois fatores:%{mfa_link}."
msgid "To get started you enter your FogBugz URL and login information below. In the next steps, you'll be able to map users and select the projects you want to import."
msgstr "Para começar, insira seu URL do FogBugz e as informações de entrada abaixo. Nas próximas etapas, você poderá associar usuários e selecionar os projetos que deseja importar."
@@ -34734,7 +35043,7 @@ msgid "To keep this project going, create a new issue"
msgstr "Para manter este projeto em andamento, crie uma nova issue"
msgid "To keep this project going, create a new merge request"
-msgstr "Para manter este projeto em andamento, crie uma nova merge request"
+msgstr "Para manter este projeto em andamento, crie uma nova solicitação de mesclagem"
msgid "To learn more about this project, read %{link_to_wiki}."
msgstr ""
@@ -34893,7 +35202,7 @@ msgid "Token Access"
msgstr "Token de acesso"
msgid "Token name"
-msgstr ""
+msgstr "Nome do token"
msgid "Token valid until revoked"
msgstr ""
@@ -34911,13 +35220,13 @@ msgid "Too many changes to show."
msgstr "Alterações demais para mostrar."
msgid "Too many namespaces enabled. You will need to manage them via the console or the API."
-msgstr "Muitos namespaces ativos. Você precisará gerenciá-los através do console ou da API."
+msgstr "Muitos espaços de nome ativos. Você precisará gerenciá-los através do console ou da API."
msgid "Too many projects enabled. You will need to manage them via the console or the API."
msgstr "Muitos projetos ativos. Você precisará gerenciá-los através do console ou da API."
msgid "TopNav|Go back"
-msgstr ""
+msgstr "Voltar"
msgid "Topics (optional)"
msgstr "Tópicos (opcional)"
@@ -34941,7 +35250,7 @@ msgid "Total issues"
msgstr ""
msgid "Total memory (GB)"
-msgstr ""
+msgstr "Memória total (GB)"
msgid "Total test time for all commits/merges"
msgstr "Tempo de teste total para todos os commits/merges"
@@ -34974,7 +35283,7 @@ msgid "Track important events in your group."
msgstr ""
msgid "Track important events in your project."
-msgstr ""
+msgstr "Acompanhe eventos importantes no seu projeto."
msgid "Track time with quick actions"
msgstr "Acompanhe o tempo com ações rápidas"
@@ -34983,7 +35292,7 @@ msgid "Track your GitLab projects with GitLab for Slack."
msgstr ""
msgid "Transfer"
-msgstr ""
+msgstr "Transferir"
msgid "Transfer ownership"
msgstr "Transferir a propriedade"
@@ -34992,7 +35301,7 @@ msgid "Transfer project"
msgstr "Transferir projeto"
msgid "Transfer your project into another namespace. %{link_start}Learn more.%{link_end}"
-msgstr "Transfira seu projeto projeto para outro namespace. %{link_start}Saiba mais.%{link_end}"
+msgstr "Transfira seu projeto projeto para outro espaço de nome. %{link_start}Saiba mais.%{link_end}"
msgid "TransferGroup|Cannot transfer group to one of its subgroup."
msgstr ""
@@ -35025,19 +35334,25 @@ msgid "TransferProject|Cannot move project"
msgstr "Não é possível mover o projeto"
msgid "TransferProject|Please select a new namespace for your project."
-msgstr "Por favor, selecione um novo namespace para o seu projeto."
+msgstr "Por favor, selecione um novo espaço de nome para o seu projeto."
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr "O projeto não pode ser transferido porque as tags estão presentes em seu container registry"
+msgid "TransferProject|Project is already in this namespace."
+msgstr "O projeto já está neste espaço de nome."
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
-msgstr "Um projeto com o mesmo nome ou caminho no namespace de destino já existe"
+msgstr "Um projeto com o mesmo nome ou caminho no espaço de nome de destino já existe"
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
-msgstr "A transferência falhou, por favor contate um administrador."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
+msgstr ""
msgid "Tree view"
msgstr "Visão em árvore"
@@ -35084,7 +35399,7 @@ msgid "Trial|Company name"
msgstr ""
msgid "Trial|Continue"
-msgstr ""
+msgstr "Continuar"
msgid "Trial|Continue using the basic features of GitLab for free."
msgstr ""
@@ -35096,7 +35411,7 @@ msgid "Trial|Dismiss"
msgstr ""
msgid "Trial|First name"
-msgstr ""
+msgstr "Nome"
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
@@ -35111,13 +35426,13 @@ msgid "Trial|How many users will be evaluating the trial?"
msgstr ""
msgid "Trial|Last name"
-msgstr ""
+msgstr "Sobrenome"
msgid "Trial|Number of employees"
msgstr ""
msgid "Trial|Please select a country"
-msgstr ""
+msgstr "Por favor selecione um país"
msgid "Trial|Successful trial activation image"
msgstr ""
@@ -35135,7 +35450,7 @@ msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your
msgstr ""
msgid "Trial|your company"
-msgstr ""
+msgstr "sua empresa"
msgid "Trigger"
msgstr ""
@@ -35213,10 +35528,10 @@ msgid "Try using a different search term to find the file you are looking for."
msgstr "Tente pesquisar usando um termo diferente para encontrar o arquivo que você está procurando."
msgid "Trying to communicate with your device. Plug it in (if needed) and press the button on the device now."
-msgstr ""
+msgstr "Tentando se comunicar com seu dispositivo. Conecte (se necessário) e pressione o botão no dispositivo agora."
msgid "Trying to communicate with your device. Plug it in (if you haven't already) and press the button on the device now."
-msgstr ""
+msgstr "Tentando se comunicar com seu dispositivo. Conecte (se você ainda não fez) e pressione o botão no dispositivo agora."
msgid "Tuesday"
msgstr "Terça-feira"
@@ -35255,19 +35570,19 @@ msgid "Two-factor authentication"
msgstr "Autenticação de dois fatores"
msgid "Two-factor authentication disabled"
-msgstr ""
+msgstr "Autenticação de dois fatores desativada"
msgid "Two-factor authentication has been disabled for this user"
-msgstr ""
+msgstr "A autenticação de dois fatores foi desativada para este usuário"
msgid "Two-factor authentication has been disabled for your GitLab account."
-msgstr ""
+msgstr "A autenticação de dois fatores foi desativada para sua conta do GitLab."
msgid "Two-factor authentication has been disabled successfully!"
-msgstr ""
+msgstr "A autenticação de dois fatores foi desativada com sucesso!"
msgid "Two-factor authentication is not enabled for this user"
-msgstr ""
+msgstr "A autenticação de dois fatores não está ativado para este usuário"
msgid "Two-factor grace period"
msgstr ""
@@ -35309,7 +35624,7 @@ msgid "URL is triggered when repository is updated"
msgstr ""
msgid "URL must be percent-encoded if neccessary."
-msgstr ""
+msgstr "O URL deve ser codificado em porcentagem, se necessário."
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
@@ -35465,7 +35780,7 @@ msgid "Undo ignore"
msgstr ""
msgid "Unexpected error"
-msgstr ""
+msgstr "Erro inesperado"
msgid "Unfollow"
msgstr ""
@@ -35516,7 +35831,7 @@ msgid "Unlock"
msgstr "Desbloquear"
msgid "Unlock account"
-msgstr ""
+msgstr "Desbloquear conta"
msgid "Unlock the discussion"
msgstr "Desbloquear a discussão"
@@ -35531,13 +35846,13 @@ msgid "Unlocked the discussion."
msgstr "Desbloqueou a discussão."
msgid "Unlocks the discussion."
-msgstr ""
+msgstr "Desbloqueia a discussão."
msgid "Unmarked this %{noun} as a draft."
-msgstr ""
+msgstr "Desmarcou este %{noun} como rascunho."
msgid "Unmarks this %{noun} as a draft."
-msgstr ""
+msgstr "Desmarca este %{noun} como um rascunho."
msgid "Unreachable"
msgstr ""
@@ -35573,7 +35888,7 @@ msgid "Unstar"
msgstr "Desmarcar como favorito"
msgid "Unstarted"
-msgstr ""
+msgstr "Sem iniciar"
msgid "Unsubscribe"
msgstr "Cancelar inscrição"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr "Até"
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35651,7 +35969,7 @@ msgid "Update it"
msgstr "Atualizar"
msgid "Update iteration"
-msgstr ""
+msgstr "Atualizar iteração"
msgid "Update milestone"
msgstr "Atualizar marco"
@@ -35660,7 +35978,7 @@ msgid "Update now"
msgstr "Atualizar agora"
msgid "Update username"
-msgstr ""
+msgstr "Atualizar nome de usuário"
msgid "Update variable"
msgstr "Atualizar variável"
@@ -35708,7 +36026,7 @@ msgid "Updating…"
msgstr ""
msgid "Upgrade offers available!"
-msgstr ""
+msgstr "Ofertas de atualização disponível!"
msgid "Upgrade your plan"
msgstr ""
@@ -35780,7 +36098,7 @@ msgid "Usage statistics"
msgstr "Estatísticas de uso"
msgid "UsageQuota|%{help_link_start}Shared runners%{help_link_end} are disabled, so there are no limits set on pipeline usage"
-msgstr "%{help_link_start}Runners compartilhados%{help_link_end} estão desativados, então não há limites definidos no uso de pipeline"
+msgstr "%{help_link_start}Executores compartilhados%{help_link_end} estão desativados, então não há limites definidos no uso de pipeline"
msgid "UsageQuota|%{percentageLeft} of purchased storage is available"
msgstr "%{percentageLeft} de armazenamento comprado está disponível"
@@ -35789,7 +36107,7 @@ msgid "UsageQuota|Artifacts"
msgstr "Artefatos"
msgid "UsageQuota|Artifacts is a sum of build and pipeline artifacts."
-msgstr ""
+msgstr "Artefatos é uma soma de artefatos de construção e pipeline."
msgid "UsageQuota|Buy additional minutes"
msgstr "Comprar minutos adicionais"
@@ -35798,16 +36116,16 @@ msgid "UsageQuota|CI minutes usage by month"
msgstr "Uso de minutos de CI por mês"
msgid "UsageQuota|CI minutes usage by project"
-msgstr ""
+msgstr "Uso de minutos de CI por projeto"
msgid "UsageQuota|Current period usage"
msgstr "Uso do período atual"
msgid "UsageQuota|Increase storage temporarily"
-msgstr ""
+msgstr "Aumentar o armazenamento temporariamente"
msgid "UsageQuota|LFS Objects"
-msgstr ""
+msgstr "Objetos LFS"
msgid "UsageQuota|LFS Storage"
msgstr "Armazenamento LFS"
@@ -35818,9 +36136,6 @@ msgstr "Saiba mais sobre o armazenamento em excesso"
msgid "UsageQuota|Learn more about usage quotas"
msgstr "Saiba mais sobre as cotas de uso"
-msgid "UsageQuota|Other Storage"
-msgstr "Outro armazenamento"
-
msgid "UsageQuota|Packages"
msgstr "Pacotes"
@@ -35839,9 +36154,15 @@ msgstr "Repositórios"
msgid "UsageQuota|Repository"
msgstr "Repositório"
+msgid "UsageQuota|Seats"
+msgstr "Assentos"
+
msgid "UsageQuota|Snippets"
msgstr "Snippets"
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr "Armazenamento"
@@ -35855,7 +36176,7 @@ msgid "UsageQuota|This namespace contains locked projects"
msgstr ""
msgid "UsageQuota|This namespace has no projects which use shared runners"
-msgstr "Este namespace não possui projetos que usam runners compartilhados"
+msgstr "Este espaço de nome não possui projetos que usam executores compartilhados"
msgid "UsageQuota|This project is at risk of being locked because purchased storage is running low."
msgstr ""
@@ -35873,13 +36194,13 @@ msgid "UsageQuota|Total excess storage used"
msgstr "Total de armazenamento em excesso usado"
msgid "UsageQuota|Total namespace storage used"
-msgstr "Total de armazenamento de namespace usado"
+msgstr "Total de armazenamento de espaço de nome usado"
msgid "UsageQuota|Unlimited"
msgstr "Ilimitado"
msgid "UsageQuota|Uploads"
-msgstr ""
+msgstr "Envios"
msgid "UsageQuota|Usage"
msgstr "Uso"
@@ -35890,11 +36211,14 @@ msgstr "Cotas de uso"
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr "Uso de recursos de grupo entre os projetos no grupo %{strong_start}%{group_name}%{strong_end}"
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr "Uso de recursos em seus projetos"
msgid "UsageQuota|Usage quotas help link"
-msgstr ""
+msgstr "Link de ajuda de cotas de uso"
msgid "UsageQuota|Usage since"
msgstr "Uso desde"
@@ -35906,7 +36230,7 @@ msgid "UsageQuota|Wiki"
msgstr "Wiki"
msgid "UsageQuota|Wikis"
-msgstr ""
+msgstr "Wikis"
msgid "UsageQuota|You have consumed all of your additional storage, please purchase more to unlock your projects over the free %{actualRepositorySizeLimit} limit."
msgstr ""
@@ -35915,7 +36239,7 @@ msgid "UsageQuota|You have reached the free storage limit of %{actualRepositoryS
msgstr ""
msgid "UsageQuota|You used: %{usage} %{limit}"
-msgstr ""
+msgstr "Você usou: %{usage} %{limit}"
msgid "UsageQuota|Your purchased storage is running low. To avoid locked projects, please purchase more storage."
msgstr ""
@@ -35939,40 +36263,40 @@ msgid "UsageTrends|Issues"
msgstr "Issues"
msgid "UsageTrends|Issues & merge requests"
-msgstr ""
+msgstr "Issues e solicitações de mesclagem"
msgid "UsageTrends|Items"
msgstr "Itens"
msgid "UsageTrends|Merge requests"
-msgstr "Merge request"
+msgstr "Solicitações de mesclagem"
msgid "UsageTrends|Month"
-msgstr ""
+msgstr "Mês"
msgid "UsageTrends|No data available."
-msgstr ""
+msgstr "Nenhum dado disponível."
msgid "UsageTrends|Pipelines"
-msgstr ""
+msgstr "Pipelines"
msgid "UsageTrends|Pipelines canceled"
-msgstr ""
+msgstr "Pipelines cancelados"
msgid "UsageTrends|Pipelines failed"
-msgstr ""
+msgstr "Pipelines falhou"
msgid "UsageTrends|Pipelines skipped"
-msgstr ""
+msgstr "Pipelines ignorados"
msgid "UsageTrends|Pipelines succeeded"
-msgstr ""
+msgstr "Pipelines bem-sucedidos"
msgid "UsageTrends|Pipelines total"
-msgstr ""
+msgstr "Total de pipelines"
msgid "UsageTrends|Projects"
-msgstr ""
+msgstr "Projetos"
msgid "UsageTrends|There was an error fetching the cancelled pipelines. Please try again."
msgstr ""
@@ -36002,13 +36326,13 @@ msgid "UsageTrends|There was an error fetching the total pipelines. Please try a
msgstr ""
msgid "UsageTrends|Total groups"
-msgstr ""
+msgstr "Total de grupos"
msgid "UsageTrends|Total projects"
-msgstr ""
+msgstr "Total de projetos"
msgid "UsageTrends|Total projects & groups"
-msgstr ""
+msgstr "Total de projetos e grupos"
msgid "UsageTrends|Users"
msgstr "Usuários"
@@ -36017,7 +36341,7 @@ msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%
msgstr ""
msgid "Use .gitlab-ci.yml"
-msgstr ""
+msgstr "Usar .gitlab-ci.yml"
msgid "Use GitLab Runner in AWS"
msgstr ""
@@ -36029,7 +36353,7 @@ msgid "Use an AWS CloudFormation Template (CFT) to install and configure GitLab
msgstr ""
msgid "Use cURL"
-msgstr ""
+msgstr "Usar cURL"
msgid "Use custom color #FF0000"
msgstr ""
@@ -36038,7 +36362,7 @@ msgid "Use double quotes for multiple keywords, such as %{code_open}\"your searc
msgstr ""
msgid "Use hashed storage"
-msgstr ""
+msgstr "Usar armazenamento hash"
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr "Use uma linha por URI"
+msgid "Use primary email (%{email})"
+msgstr "Usar e-mail principal (%{email})"
+
msgid "Use shortcuts"
msgstr "Usar atalhos"
@@ -36080,7 +36407,7 @@ msgid "Use your smart card to authenticate with the LDAP server."
msgstr ""
msgid "Used"
-msgstr ""
+msgstr "Usado"
msgid "Used by members to sign in to your group in GitLab"
msgstr "Utilizado pelos membros para entrar em seu grupo no GitLab"
@@ -36161,7 +36488,7 @@ msgid "User was successfully removed from group and any subgroups and projects."
msgstr ""
msgid "User was successfully removed from group."
-msgstr ""
+msgstr "Usuário removido com sucesso do grupo."
msgid "User was successfully removed from project."
msgstr "Usuário removido com sucesso do projeto."
@@ -36176,10 +36503,10 @@ msgid "UserAvailability|%{author} %{spanStart}(Busy)%{spanEnd}"
msgstr ""
msgid "UserAvailability|%{author} (Busy)"
-msgstr ""
+msgstr "%{author} (Ocupado)"
msgid "UserAvailability|(Busy)"
-msgstr ""
+msgstr "(Ocupado)"
msgid "UserLists|Add"
msgstr "Adicionar"
@@ -36197,7 +36524,7 @@ msgid "UserLists|Create"
msgstr "Criar"
msgid "UserLists|Define a set of users to be used within feature flag strategies"
-msgstr ""
+msgstr "Definir um conjunto de usuários a ser usado nas estratégias de feature flag"
msgid "UserLists|Edit"
msgstr "Editar"
@@ -36206,16 +36533,16 @@ msgid "UserLists|Edit %{name}"
msgstr "Edição %{name}"
msgid "UserLists|Enter a comma separated list of user IDs. These IDs should be the users of the system in which the feature flag is set, not GitLab IDs"
-msgstr ""
+msgstr "nsira uma lista separada por vírgulas de IDs de usuário. Esses IDs devem ser os usuários do sistema no qual o feature flag está definido, não os IDs do GitLab"
msgid "UserLists|Feature flag user list"
msgstr ""
msgid "UserLists|Get started with user lists"
-msgstr ""
+msgstr "Comece com as listas de usuários"
msgid "UserLists|Lists allow you to define a set of users to be used with feature flags. %{linkStart}Read more about feature flag lists.%{linkEnd}"
-msgstr ""
+msgstr "Lists permitem definir um conjunto de usuários a serem usados com feature flags. %{linkStart}Leia mais sobre listas de feature flags.%{linkEnd}"
msgid "UserLists|Loading user lists"
msgstr "Carregando a lista de usuários"
@@ -36248,7 +36575,7 @@ msgid "UserLists|User Lists"
msgstr "Listas de usuários"
msgid "UserLists|User lists allow you to define a set of users to use with Feature Flags."
-msgstr ""
+msgstr "As listas de usuários permitem que você defina um conjunto de usuários para usar com Feature Flags."
msgid "UserList|Delete %{name}?"
msgstr ""
@@ -36308,7 +36635,7 @@ msgid "UserProfile|Personal projects"
msgstr "Projetos pessoais"
msgid "UserProfile|Pronounced as: %{pronunciation}"
-msgstr ""
+msgstr "Pronunciado como: %{pronunciation}"
msgid "UserProfile|Report abuse"
msgstr "Denunciar abuso"
@@ -36332,7 +36659,7 @@ msgid "UserProfile|Subscribe"
msgstr "Inscrever-se"
msgid "UserProfile|This user doesn't have any followers."
-msgstr ""
+msgstr "Este usuário não possui nenhum seguidor."
msgid "UserProfile|This user doesn't have any personal projects"
msgstr "Este usuário não tem nenhum projeto pessoal"
@@ -36350,10 +36677,10 @@ msgid "UserProfile|This user is blocked"
msgstr "Este usuário está bloqueado"
msgid "UserProfile|This user isn't following other users."
-msgstr ""
+msgstr "Este usuário não está seguindo outros usuários."
msgid "UserProfile|Unconfirmed user"
-msgstr ""
+msgstr "Usuário não confirmado"
msgid "UserProfile|View all"
msgstr "Ver tudo"
@@ -36419,7 +36746,7 @@ msgid "Users can render diagrams in AsciiDoc, Markdown, reStructuredText, and Te
msgstr ""
msgid "Users in License"
-msgstr ""
+msgstr "Usuários com licença"
msgid "Users or groups set as approvers in the project's or merge request's settings."
msgstr ""
@@ -36464,7 +36791,7 @@ msgid "Validate"
msgstr "Validar"
msgid "Validate your GitLab CI configuration"
-msgstr ""
+msgstr "Valide sua configuração do GitLab CI"
msgid "Validate your GitLab CI configuration file"
msgstr "Valide seu arquivo de configuração de GitLab CI"
@@ -36494,7 +36821,7 @@ msgid "ValueStreamAnalyticsStage|We don't have enough data to show this stage."
msgstr ""
msgid "ValueStreamAnalytics|%{stageCount}+ items"
-msgstr ""
+msgstr "%{stageCount}+ itens"
msgid "ValueStreamAnalytics|%{value}M"
msgstr ""
@@ -36523,23 +36850,29 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
msgid "ValueStreamEvent|Items in stage"
-msgstr ""
+msgstr "Itens no estágio"
msgid "ValueStreamEvent|Stage time (median)"
msgstr "Tempo do estágio (mediana)"
msgid "ValueStreamEvent|Start"
-msgstr ""
+msgstr "Iniciar"
msgid "ValueStreamEvent|Stop"
-msgstr ""
+msgstr "Parar"
msgid "ValueStream|The Default Value Stream cannot be deleted"
msgstr ""
@@ -36557,7 +36890,7 @@ msgid "Variables"
msgstr "Variáveis"
msgid "Variables can be:"
-msgstr ""
+msgstr "As variáveis podem ser:"
msgid "Variables store information, like passwords and secret keys, that you can use in job scripts."
msgstr ""
@@ -36566,7 +36899,7 @@ msgid "Variables store information, like passwords and secret keys, that you can
msgstr ""
msgid "Various container registry settings."
-msgstr "Várias configurações de registry container."
+msgstr "Várias configurações de registro de contêiner."
msgid "Various email settings."
msgstr "Várias configurações de email."
@@ -36596,16 +36929,16 @@ msgid "Version"
msgstr "Versão"
msgid "Version %{versionNumber}"
-msgstr ""
+msgstr "Versão %{versionNumber}"
msgid "Version %{versionNumber} (latest)"
-msgstr ""
+msgstr "Versão %{versionNumber} (última)"
msgid "View Documentation"
msgstr "Ver documentação"
msgid "View alert details at"
-msgstr ""
+msgstr "Veja os detalhes do alerta em"
msgid "View alert details."
msgstr ""
@@ -36614,7 +36947,7 @@ msgid "View all environments."
msgstr "Ver todos os ambientes."
msgid "View all issues"
-msgstr ""
+msgstr "Ver todas as issues"
msgid "View blame prior to this change"
msgstr ""
@@ -36628,7 +36961,7 @@ msgid "View dependency details for your project"
msgstr "Ver detalhes de dependências para seu projeto"
msgid "View deployment"
-msgstr "Ver deploy"
+msgstr "Ver implantação"
msgid "View details"
msgstr "Ver detalhes"
@@ -36696,16 +37029,16 @@ msgid "View log"
msgstr "Visualizar log"
msgid "View logs"
-msgstr "Visualizar logs"
+msgstr "Ver registros"
msgid "View merge request"
-msgstr ""
+msgstr "Ver solicitação de mesclagem"
msgid "View on %{url}"
msgstr ""
msgid "View open merge request"
-msgstr "Ver merge request aberto"
+msgstr "Ver solicitação de mesclagem aberta"
msgid "View page @ "
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr "Ver etiquetas de projeto"
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr "Ver arquivo substituído @ "
@@ -36906,7 +37244,7 @@ msgid "VulnerabilityStatusTypes|Resolved"
msgstr ""
msgid "Vulnerability|%{scannerName} (version %{scannerVersion})"
-msgstr ""
+msgstr "%{scannerName} (versão %{scannerVersion})"
msgid "Vulnerability|Activity"
msgstr "Atividade"
@@ -36966,7 +37304,7 @@ msgid "Vulnerability|Method"
msgstr ""
msgid "Vulnerability|Namespace"
-msgstr "Namespace"
+msgstr "Espaço de nome"
msgid "Vulnerability|Project"
msgstr "Projeto"
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr "Ferramenta"
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37014,7 +37352,7 @@ msgid "Want to see the data? Please ask an administrator for access."
msgstr "Precisa visualizar os dados? Solicite acesso ao administrador."
msgid "Warning"
-msgstr ""
+msgstr "Aviso"
msgid "Warning:"
msgstr "Aviso:"
@@ -37029,7 +37367,7 @@ msgid "We are currently unable to fetch data for the pipeline header."
msgstr ""
msgid "We are currently unable to fetch data for this graph."
-msgstr ""
+msgstr "No momento, não podemos buscar dados para este gráfico."
msgid "We are currently unable to fetch data for this pipeline."
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr "Nenhuma vulnerabilidade encontrada"
@@ -37122,10 +37463,10 @@ msgid "WebIDE|Fork project"
msgstr "Fork projeto"
msgid "WebIDE|Go to fork"
-msgstr ""
+msgstr "Ir para o fork"
msgid "WebIDE|Merge request"
-msgstr ""
+msgstr "Solicitação de mesclagem"
msgid "WebIDE|This project does not accept unsigned commits."
msgstr ""
@@ -37134,13 +37475,13 @@ msgid "WebIDE|This project does not accept unsigned commits. You can’t commit
msgstr ""
msgid "WebIDE|You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr "Você não pode editar arquivos diretamente nesse projeto. Faça um fork nesse projeto e envie um merge request com suas alterações."
+msgstr "Você não pode editar arquivos diretamente nesse projeto. Faça um fork nesse projeto e envie uma solicitação de mesclagem com suas alterações."
msgid "WebIDE|You can’t edit files directly in this project. Go to your fork and submit a merge request with your changes."
-msgstr "Você não pode editar arquivos diretamente nesse projeto. Vá para o seu fork e envie um merge request com suas alterações."
+msgstr "Você não pode editar arquivos diretamente nesse projeto. Vá para o seu fork e envie uma solicitação de mesclagem com suas alterações."
msgid "WebIDE|You need permission to edit files directly in this project."
-msgstr ""
+msgstr "Você precisa de permissão para editar arquivos diretamente neste projeto."
msgid "WebexTeamsService|Send notifications about project events to Webex Teams."
msgstr ""
@@ -37155,7 +37496,7 @@ msgid "Webhook"
msgstr "Webhook"
msgid "Webhook Logs"
-msgstr "Logs de webhook"
+msgstr "Registros de webhook"
msgid "Webhook Settings"
msgstr "Configurações de webhook"
@@ -37179,7 +37520,7 @@ msgid "Webhooks|Confidential issues events"
msgstr "Eventos de issue confidencial"
msgid "Webhooks|Deployment events"
-msgstr "Eventos de deploy"
+msgstr "Eventos de implantação"
msgid "Webhooks|Enable SSL verification"
msgstr "Ativar verificação SSL"
@@ -37197,7 +37538,7 @@ msgid "Webhooks|Member events"
msgstr ""
msgid "Webhooks|Merge request events"
-msgstr "Eventos de merge request"
+msgstr "Eventos de solicitação de mesclagem"
msgid "Webhooks|Pipeline events"
msgstr "Eventos de pipeline"
@@ -37323,7 +37664,7 @@ msgid "What are instance audit events?"
msgstr ""
msgid "What are project audit events?"
-msgstr ""
+msgstr "O que são eventos de auditoria de projetos?"
msgid "What are shared runner pipeline minutes?"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr "Para que você usará este grupo?"
+
msgid "What's new"
msgstr "Novidades"
@@ -37362,10 +37706,10 @@ msgid "What’s your experience level?"
msgstr ""
msgid "When a deployment job is successful, skip older deployment jobs that are still pending."
-msgstr ""
+msgstr "Quando uma tarefa de implantação é bem-sucedida, pule as tarefas de implantação mais antigos que ainda estão pendentes."
msgid "When a runner is locked, it cannot be assigned to other projects"
-msgstr "Quando um runner está bloqueado, não pode ser atribuído a outros projetos"
+msgstr "Quando um executor está bloqueado, não pode ser atribuído a outros projetos"
msgid "When an event in GitLab triggers a webhook, you can use the request details to figure out if something went wrong."
msgstr ""
@@ -37377,7 +37721,7 @@ msgid "When leaving the URL blank, classification labels can still be specified
msgstr "Ao deixar o URL em branco, a classificação das etiquetas ainda podem ser especificadas sem desativar os recursos do projeto ou executar verificações de autorização externas."
msgid "When merge requests and commits in the default branch close, any issues they reference also close."
-msgstr ""
+msgstr "Quando as solicitações de mesclagem e commits na ramificação padrão são fechadas, todas as issues aos quais eles fazem referência também são encerrados."
msgid "When this merge request is accepted"
msgid_plural "When these merge requests are accepted"
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr "Quem usará esse grupo?"
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37472,13 +37819,13 @@ msgid "WikiEmpty|Create your first page"
msgstr "Crie sua primeira página"
msgid "WikiEmpty|Enable the Confluence Wiki integration"
-msgstr ""
+msgstr "Ativar a integração de Confluence Wiki"
msgid "WikiEmpty|Go to Confluence"
msgstr ""
msgid "WikiEmpty|Suggest wiki improvement"
-msgstr "Sugira a melhoria da wiki"
+msgstr "Sugerir melhoria da wiki"
msgid "WikiEmpty|The wiki lets you write documentation for your group"
msgstr ""
@@ -37529,10 +37876,10 @@ msgid "WikiPage|An error occured while trying to render the content editor. Plea
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
-msgstr ""
+msgstr "Tem certeza de que deseja voltar para o editor clássico?"
msgid "WikiPage|Cancel"
-msgstr ""
+msgstr "Cancelar"
msgid "WikiPage|Commit message"
msgstr "Mensagem de commit"
@@ -37541,64 +37888,64 @@ msgid "WikiPage|Content"
msgstr "Conteúdo"
msgid "WikiPage|Create %{pageTitle}"
-msgstr ""
+msgstr "Criar %{pageTitle}"
msgid "WikiPage|Create page"
-msgstr ""
+msgstr "Criar página"
msgid "WikiPage|Format"
msgstr "Formato"
msgid "WikiPage|Get a richer editing experience"
-msgstr ""
+msgstr "Obtenha uma experiência de edição mais rica"
msgid "WikiPage|Keep editing"
-msgstr ""
+msgstr "Manter edição"
msgid "WikiPage|More Information."
msgstr ""
msgid "WikiPage|Page title"
-msgstr ""
+msgstr "Título da página"
msgid "WikiPage|Retry"
msgstr ""
msgid "WikiPage|Save changes"
-msgstr ""
+msgstr "Salvar alterações"
msgid "WikiPage|Switch me back to the classic editor."
-msgstr ""
+msgstr "Voltar para o editor clássico."
msgid "WikiPage|Switch to classic editor"
-msgstr "Mudar para o editor clássico"
+msgstr "Voltar para o editor clássico"
msgid "WikiPage|Switching to the classic editor will discard any changes you've made in the new editor."
-msgstr ""
+msgstr "Voltar para o editor clássico descartará todas as alterações feitas no novo editor."
msgid "WikiPage|This editor is in beta and may not display the page's contents properly. Switching back to the classic editor will discard changes you've made in the new editor."
-msgstr ""
+msgstr "Este editor está em beta e pode não exibir o conteúdo da página corretamente. Mudar de volta para o editor clássico irá descartar as alterações feitas no novo editor."
msgid "WikiPage|Tip: You can move this page by adding the path to the beginning of the title."
msgstr ""
msgid "WikiPage|Tip: You can specify the full path for the new file. We will automatically create any missing directories."
-msgstr ""
+msgstr "Dica: Você pode especificar o caminho completo para o novo arquivo. Nós vamos criar automaticamente quaisquer diretórios ainda não existentes."
msgid "WikiPage|Title"
-msgstr ""
+msgstr "Título"
msgid "WikiPage|To link to a (new) page, simply type %{linkExample}. More examples are in the %{linkStart}documentation%{linkEnd}."
-msgstr ""
+msgstr "Para criar um link para uma (nova) página, simplesmente digitar %{linkExample}. Mais exemplos estão na %{linkStart}documentação%{linkEnd}."
msgid "WikiPage|Try the new visual Markdown editor. Read the %{linkStart}documentation%{linkEnd} to learn what's currently supported."
-msgstr ""
+msgstr "Experimente o novo editor Markdown visual. Leia a %{linkStart}documentação%{linkEnd} para saber o que atualmente é suportado."
msgid "WikiPage|Try this later"
-msgstr ""
+msgstr "Experimentar mais tarde"
msgid "WikiPage|Update %{pageTitle}"
-msgstr ""
+msgstr "Atualização de %{pageTitle}"
msgid "WikiPage|Use the new editor"
msgstr "Usar o novo editor"
@@ -37655,7 +38002,7 @@ msgid "With requirements, you can set criteria to check your products against."
msgstr "Com os requisitos, pode estabelecer critérios para comprovar sus produtos."
msgid "With test cases, you can define conditions for your project to meet in determining quality"
-msgstr ""
+msgstr "Com casos de teste, você pode definir condições para seu projeto atender na determinação da qualidade"
msgid "Withdraw Access Request"
msgstr "Remover requisição de acesso"
@@ -37739,7 +38086,7 @@ msgid "You are about to permanently delete this project"
msgstr "Você está prestes a excluir permanentemente este projeto"
msgid "You are about to transfer the control of your account to %{group_name} group. This action is NOT reversible, you won't be able to access any of your groups and projects outside of %{group_name} once this transfer is complete."
-msgstr ""
+msgstr "Você está prestes a transferir o controle da sua conta para o grupo %{group_name} . Esta ação NÃO é reversível, você não poderá acessar nenhum dos seus grupos e projetos fora do %{group_name} assim que a transferência for concluída."
msgid "You are already a member of this %{member_source}."
msgstr ""
@@ -37757,16 +38104,16 @@ msgid "You are connected to the Prometheus server, but there is currently no dat
msgstr "Você está conectado ao servidor Prometheus, mas atualmente não há dados para exibir."
msgid "You are going to delete %{project_full_name}. Deleted projects CANNOT be restored! Are you ABSOLUTELY sure?"
-msgstr ""
+msgstr "Você irá excluir %{project_full_name}. Os projetos excluídos NÃO PODEM ser restaurados! Tem certeza ABSOLUTA?"
msgid "You are going to remove %{group_name}. This will also delete all of its subgroups and projects. Removed groups CANNOT be restored! Are you ABSOLUTELY sure?"
-msgstr ""
+msgstr "Você removerá %{group_name}. Isso também excluirá todos os seus subgrupos e projetos. Grupos removidos NÃO PODEM ser restaurados! Você tem certeza?"
msgid "You are going to remove the fork relationship from %{project_full_name}. Are you ABSOLUTELY sure?"
-msgstr ""
+msgstr "Você está prestes a remover a relação de fork do %{project_full_name}. Você tem CERTEZA disso?"
msgid "You are going to transfer %{project_full_name} to another namespace. Are you ABSOLUTELY sure?"
-msgstr ""
+msgstr "Você irá transferir %{project_full_name} para outro espaço de nome. Tem certeza ABSOLUTA?"
msgid "You are going to turn off the confidentiality. This means %{strongStart}everyone%{strongEnd} will be able to see and leave a comment on this %{issuableType}."
msgstr ""
@@ -37787,7 +38134,7 @@ msgid "You are not allowed to push into this branch. Create another branch or op
msgstr ""
msgid "You are not allowed to reject a user"
-msgstr ""
+msgstr "Você não tem permissão para rejeitar um usuário"
msgid "You are not allowed to unlink your primary login account"
msgstr "Você não tem permissão para desvincular sua conta de login principal"
@@ -37847,7 +38194,7 @@ msgid "You can also use project access tokens with Git to authenticate over HTTP
msgstr ""
msgid "You can always edit this later"
-msgstr ""
+msgstr "Você pode editar isto depois"
msgid "You can create a new %{link}."
msgstr ""
@@ -37901,13 +38248,13 @@ msgid "You can group test cases using labels. To learn about the future directio
msgstr ""
msgid "You can invite a new member to %{project_name} or invite another group."
-msgstr ""
+msgstr "Você pode convidar um novo membro para %{project_name} ou convidar outro grupo."
msgid "You can invite a new member to %{project_name}."
-msgstr ""
+msgstr "Você pode convidar um novo membro para %{project_name}."
msgid "You can invite a new member to %{strong_start}%{group_name}%{strong_end}."
-msgstr ""
+msgstr "Você pode convidar um novo membro para %{strong_start}%{group_name}%{strong_end}."
msgid "You can invite another group to %{project_name}."
msgstr ""
@@ -37928,22 +38275,22 @@ msgid "You can now submit a merge request to get this change into the original b
msgstr ""
msgid "You can now submit a merge request to get this change into the original project."
-msgstr "Agora você pode enviar um merge request para fazer esta mudança no projeto original."
+msgstr "Agora você pode enviar uma solicitação de mesclagem para fazer esta mudança no projeto original."
msgid "You can only %{action} files when you are on a branch"
msgstr ""
msgid "You can only edit files when you are on a branch"
-msgstr "Você só pode editar arquivos quando estiver em um branch"
+msgstr "Você só pode editar arquivos quando estiver em uma ramificação"
msgid "You can only merge once the items above are resolved."
msgstr ""
msgid "You can only merge once this merge request is approved."
-msgstr "Você só pode fazer o merge quando este merge request for aprovado."
+msgstr "Você só pode fazer a mesclagem quando essa solicitação de mesclagem for aprovada."
msgid "You can only transfer the project to namespaces you manage."
-msgstr "Você só pode transferir o projeto para namespaces que você gerencia."
+msgstr "Você só pode transferir o projeto para espaços de nome que você gerencia."
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
@@ -37955,7 +38302,7 @@ msgid "You can register runners as separate users, on separate servers, and on y
msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
-msgstr "Você pode resolver o conflito de merge usando o modo Interativo, escolhendo os botões %{use_ours} ou %{use_theirs} ou editando os arquivos diretamente. Confirme essas alterações em %{branch_name}"
+msgstr "Você pode resolver o conflito de mesclagem usando o modo Interativo, escolhendo os botões %{use_ours} ou %{use_theirs} ou editando os arquivos diretamente. Confirme essas alterações em %{branch_name}"
msgid "You can see your chat accounts."
msgstr "Você pode ver suas contas de bate-papo."
@@ -37970,6 +38317,9 @@ msgid "You can test your .gitlab-ci.yml in %{linkStart}CI Lint%{linkEnd}."
msgstr "Você pode testar o seu .gitlab-ci.yml no %{linkStart}CI Lint%{linkEnd}."
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
+msgstr "Você pode ver a fonte ou %{linkStart}%{cloneIcon} clonar o repositório%{linkEnd}"
+
+msgid "You cannot %{action} %{state} users."
msgstr ""
msgid "You cannot access the raw file. Please wait a minute."
@@ -37987,6 +38337,9 @@ msgstr "Você não pode se passar por um usuário interno"
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr "Você não pode escrever numa instância secundária de somente leitura do GitLab Geo. Por favor use %{link_to_primary_node} em vez disso."
@@ -37994,7 +38347,7 @@ msgid "You cannot write to this read-only GitLab instance."
msgstr "Você não pode escrever nesta instância somente-leitura do GitLab."
msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr "Você não pode %{tag_start}editar%{tag_end} arquivos diretamente nesse projeto. Faça um fork nesse projeto e envie um merge request com suas alterações."
+msgstr "Você não pode %{tag_start}editar%{tag_end} arquivos diretamente nesse projeto. Faça um fork nesse projeto e envie uma solicitação de mesclagem com suas alterações."
msgid "You could not create a new trigger."
msgstr "Você não pôde criar um novo gatilho."
@@ -38039,7 +38392,7 @@ msgid "You don't have any deployments right now."
msgstr ""
msgid "You don't have any open merge requests"
-msgstr ""
+msgstr "Você não tem nenhuma solicitação de mesclagem em aberto"
msgid "You don't have any projects available."
msgstr ""
@@ -38117,7 +38470,7 @@ msgid "You have insufficient permissions to update this HTTP integration"
msgstr ""
msgid "You have insufficient permissions to view shifts for this rotation"
-msgstr ""
+msgstr "Você não tem permissões suficientes para ver turnos para esta rotação"
msgid "You have no permissions"
msgstr "Você não tem permissão"
@@ -38131,7 +38484,7 @@ msgstr "Você atingiu o limite de seu projeto"
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38144,7 +38497,7 @@ msgid "You may close the milestone now."
msgstr ""
msgid "You must be logged in to search across all of GitLab"
-msgstr ""
+msgstr "Você deve estar conectado para pesquisar em todo o GitLab"
msgid "You must disassociate %{domain} from all clusters it is attached to before deletion."
msgstr ""
@@ -38159,7 +38512,7 @@ msgid "You must have permission to create a project in a group before forking."
msgstr "Você deve ter permissão para criar um projeto em um grupo antes de criar o fork."
msgid "You must have permission to create a project in a namespace before forking."
-msgstr "Você deve ter permissão para criar um projeto em um namespace antes de criar o fork."
+msgstr "Você deve ter permissão para criar um projeto em um espaço de nome antes de criar o fork."
msgid "You must provide a valid current password"
msgstr "Você deve fornecer uma senha atual válida"
@@ -38195,13 +38548,13 @@ msgid "You need to upload a GitLab project export archive (ending in .gz)."
msgstr ""
msgid "You successfully declined the invitation"
-msgstr ""
+msgstr "Você recusou o convite com sucesso."
msgid "You tried to fork %{link_to_the_project} but it failed for the following reason:"
msgstr "Você tentou criar o fork %{link_to_the_project}, mas ocorreu uma falha pelo seguinte motivo:"
msgid "You will be removed from existing projects/groups"
-msgstr ""
+msgstr "Você será removido de projetos/grupos existentes"
msgid "You will be the author of all events in the activity feed that are the result of an update, like new branches being created or new commits being pushed to existing branches."
msgstr ""
@@ -38261,13 +38614,13 @@ msgid "You're at the last commit"
msgstr ""
msgid "You're not allowed to %{tag_start}edit%{tag_end} files in this project directly. Please fork this project, make your changes there, and submit a merge request."
-msgstr "Você não está permitido de %{tag_start}editar%{tag_end} arquivos nesse projeto diretamente. Por favor faça um fork nesse projeto, faça suas alterações lá, e envie um merge request."
+msgstr "Você não está permitido de %{tag_start}editar%{tag_end} arquivos nesse projeto diretamente. Por favor faça um fork nesse projeto, faça suas alterações lá, e envie uma solicitação de mesclagem."
msgid "You're not allowed to make changes to this project directly. A fork of this project has been created that you can make changes in, so you can submit a merge request."
-msgstr "Você não tem permissão para fazer alterações neste projeto diretamente. Um fork deste projeto foi criado para que você possa fazer alterações e então enviar um merge request."
+msgstr "Você não tem permissão para fazer alterações neste projeto diretamente. Um fork deste projeto foi criado para que você possa fazer alterações e então enviar uma solicitação de mesclagem."
msgid "You're not allowed to make changes to this project directly. A fork of this project is being created that you can make changes in, so you can submit a merge request."
-msgstr "Você não tem permissão para fazer alterações neste projeto diretamente. Um fork deste projeto está sendo criado para que você possa fazer alterações e então enviar um merge request."
+msgstr "Você não tem permissão para fazer alterações neste projeto diretamente. Um fork deste projeto está sendo criado para que você possa fazer alterações e então enviar uma solicitação de mesclagem."
msgid "You're receiving this email because of your account on %{host}."
msgstr "Você está recebendo este e-mail devido à sua conta no %{host}."
@@ -38390,7 +38743,7 @@ msgid "Your account has been deactivated. You will not be able to: "
msgstr ""
msgid "Your account is locked."
-msgstr ""
+msgstr "A sua conta está bloqueada."
msgid "Your account uses dedicated credentials for the \"%{group_name}\" group and can only be updated through SSO."
msgstr ""
@@ -38414,7 +38767,7 @@ msgid "Your browser doesn't support WebAuthn. Please use a supported browser, e.
msgstr ""
msgid "Your changes can be committed to %{branch_name} because a merge request is open."
-msgstr "Você pode fazer commit de suas alterações para %{branch_name} porque um merge request está aberto."
+msgstr "Você pode fazer commit de suas alterações para %{branch_name} porque uma solicitação de mesclagem está aberto."
msgid "Your changes have been committed. Commit %{commitId} %{commitStats}"
msgstr "Commit com suas alterações realizado. Commit %{commitId} %{commitStats}"
@@ -38438,7 +38791,7 @@ msgid "Your comment will be discarded."
msgstr ""
msgid "Your commit email is used for web based operations, such as edits and merges."
-msgstr ""
+msgstr "Seu e-mail de commit é usado para operações baseadas na web, como edições e merges."
msgid "Your dashboard has been copied. You can %{web_ide_link_start}edit it here%{web_ide_link_end}."
msgstr ""
@@ -38447,7 +38800,7 @@ msgid "Your dashboard has been updated. You can %{web_ide_link_start}edit it her
msgstr ""
msgid "Your default notification email is used for account notifications if a %{openingTag}group-specific email address%{closingTag} is not set."
-msgstr ""
+msgstr "Seu e-mail de notificação padrão é usado para notificações de conta se um %{openingTag}endereço de e-mail específico de em grupo%{closingTag} não estiver definido."
msgid "Your deployment services will be broken, you will need to manually fix the services after renaming."
msgstr ""
@@ -38456,13 +38809,13 @@ msgid "Your device is not compatible with GitLab. Please try another device"
msgstr ""
msgid "Your device needs to be set up. Plug it in (if needed) and click the button on the left."
-msgstr ""
+msgstr "Seu dispositivo precisa ser configurado. Conecte (se necessário) e clique no botão à esquerda."
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
msgid "Your file must contain a column named %{codeStart}title%{codeEnd}. A %{codeStart}description%{codeEnd} column is optional. The maximum file size allowed is 10 MB."
-msgstr ""
+msgstr "Seu arquivo deve conter uma coluna chamada %{codeStart}title%{codeEnd}. Uma coluna de %{codeStart}description%{codeEnd} é opcional. O tamanho máximo de arquivo permitido é 10 MB."
msgid "Your first project"
msgstr ""
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr "Insira o token de API"
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr "Reunião do Zoom adicionada"
@@ -38638,7 +39015,7 @@ msgid "alert"
msgstr ""
msgid "allowed to fail"
-msgstr ""
+msgstr "permitido falhar"
msgid "already being used for another group or project %{timebox_name}."
msgstr ""
@@ -38689,7 +39066,12 @@ msgid "banned user already exists"
msgstr ""
msgid "blocks"
-msgstr ""
+msgstr "blocos"
+
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] "ramificação"
+msgstr[1] "ramificações"
msgid "branch name"
msgstr "nome da branch"
@@ -38722,7 +39104,7 @@ msgid "cannot be a date in the past"
msgstr ""
msgid "cannot be changed"
-msgstr ""
+msgstr "não pode ser alterado"
msgid "cannot be changed if a personal project has container registry tags."
msgstr ""
@@ -38814,12 +39196,12 @@ msgstr ""
msgid "ciReport|All projects"
msgstr "Todos os projetos"
-msgid "ciReport|All scanners"
-msgstr ""
-
msgid "ciReport|All severities"
msgstr ""
+msgid "ciReport|All tools"
+msgstr "Todas as ferramentas"
+
msgid "ciReport|Automatically apply the patch in a new branch"
msgstr ""
@@ -38842,13 +39224,13 @@ msgid "ciReport|Code quality"
msgstr "Qualidade do código"
msgid "ciReport|Container Scanning"
-msgstr ""
+msgstr "Verificação de container"
msgid "ciReport|Container scanning"
-msgstr "Fazer scan no container"
+msgstr "Verificação de container"
msgid "ciReport|Container scanning detects known vulnerabilities in your docker images."
-msgstr "A varredura de contêiner detectou vulnerabilidades conhecidas em suas imagens docker."
+msgstr "A varredura de container detectou vulnerabilidades conhecidas em suas imagens docker."
msgid "ciReport|Could not dismiss vulnerability because the associated pipeline no longer exists. Refresh the page and try again."
msgstr ""
@@ -38860,7 +39242,7 @@ msgid "ciReport|Coverage fuzzing"
msgstr ""
msgid "ciReport|Create Jira issue"
-msgstr ""
+msgstr "Criar issue do Jira"
msgid "ciReport|Create a merge request to implement this solution, or download and apply the patch manually."
msgstr ""
@@ -38872,7 +39254,7 @@ msgid "ciReport|DAST"
msgstr "DAST"
msgid "ciReport|Dependency Scanning"
-msgstr ""
+msgstr "Verificação de dependência"
msgid "ciReport|Dependency Scanning detects known vulnerabilities in your source code's dependencies."
msgstr "A verificação de dependência detecta vulnerabilidades conhecidas nas dependências do seu código-fonte."
@@ -38929,13 +39311,13 @@ msgid "ciReport|RPS"
msgstr ""
msgid "ciReport|Resolve with merge request"
-msgstr "Resolver com merge request"
+msgstr "Resolver com solicitação de mesclagem"
msgid "ciReport|SAST"
msgstr "SAST"
msgid "ciReport|Secret Detection"
-msgstr ""
+msgstr "Detecção de secreto"
msgid "ciReport|Secret scanning"
msgstr ""
@@ -39101,13 +39483,13 @@ msgid "days"
msgstr "dias"
msgid "default branch"
-msgstr ""
+msgstr "ramificação padrão"
msgid "deleted"
msgstr ""
msgid "deploy"
-msgstr "deploy"
+msgstr "implantar"
msgid "design"
msgstr "design"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr "épico"
@@ -39177,10 +39562,10 @@ msgid "error"
msgstr "erro"
msgid "estimateCommand|%{slash_command} overwrites the total estimated time."
-msgstr ""
+msgstr "%{slash_command} substitui o tempo total estimado."
msgid "exceeds the limit of %{bytes} bytes"
-msgstr ""
+msgstr "excede o limite de %{bytes} bytes"
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39420,7 +39802,7 @@ msgid "latest"
msgstr "último"
msgid "latest deployment"
-msgstr "deploy mais recente"
+msgstr "implantação mais recente"
msgid "latest version"
msgstr "versão mais recente"
@@ -39460,11 +39842,11 @@ msgstr ""
msgid "merge request"
msgid_plural "merge requests"
-msgstr[0] "merge request"
-msgstr[1] "merge requests"
+msgstr[0] "solicitação de mesclagem"
+msgstr[1] "solicitações de mesclagem"
msgid "merged %{timeAgo}"
-msgstr "merge realizado em %{timeAgo}"
+msgstr "mesclado em %{timeAgo}"
msgid "metric_id must be unique across a project"
msgstr ""
@@ -39485,10 +39867,10 @@ msgid "mrWidgetCommitsAdded|%{commitCount} will be added to %{targetBranch}."
msgstr "%{commitCount} será adicionado à %{targetBranch}."
msgid "mrWidgetCommitsAdded|1 merge commit"
-msgstr ""
+msgstr "1 merge commit"
msgid "mrWidgetNothingToMerge|This merge request contains no changes."
-msgstr ""
+msgstr "Essa solicitação de mesclagem não contém alterações"
msgid "mrWidgetNothingToMerge|Use merge requests to propose changes to your project and discuss them with your team. To make changes, push a commit or edit this merge request to use a different branch. With %{linkStart}CI/CD%{linkEnd}, automatically test your changes before merging."
msgstr ""
@@ -39497,10 +39879,10 @@ msgid "mrWidget| Please restore it or use a different %{missingBranchName} branc
msgstr "Por favor, restaurar ou usar um branch %{missingBranchName} diferente"
msgid "mrWidget|%{mergeError}."
-msgstr ""
+msgstr "%{mergeError}."
msgid "mrWidget|%{mergeError}. Try again."
-msgstr ""
+msgstr "%{mergeError}. Tente novamente."
msgid "mrWidget|%{metricsLinkStart} Memory %{metricsLinkEnd} usage %{emphasisStart} decreased %{emphasisEnd} from %{memoryFrom}MB to %{memoryTo}MB"
msgstr "%{metricsLinkStart} Memória %{metricsLinkEnd} uso %{emphasisStart} diminuição %{emphasisEnd} de %{memoryFrom}MB para %{memoryTo}MB"
@@ -39533,7 +39915,7 @@ msgid "mrWidget|An error occurred while submitting your approval."
msgstr "Ocorreu um erro ao enviar sua aprovação."
msgid "mrWidget|Approval is optional"
-msgstr ""
+msgstr "A aprovação é opcional"
msgid "mrWidget|Approval password is invalid."
msgstr "A senha de aprovação é inválida."
@@ -39542,7 +39924,7 @@ msgid "mrWidget|Approve"
msgstr "Aprovar"
msgid "mrWidget|Approve additionally"
-msgstr ""
+msgstr "Aprovar adicionalmente"
msgid "mrWidget|Approved by"
msgstr "Aprovado por"
@@ -39551,13 +39933,13 @@ msgid "mrWidget|Are you adding technical debt or code vulnerabilities?"
msgstr ""
msgid "mrWidget|Cancel auto-merge"
-msgstr ""
+msgstr "Cancelar mesclagem automática"
msgid "mrWidget|Check out branch"
msgstr "Checkout branch"
msgid "mrWidget|Checking if merge request can be merged…"
-msgstr "Verificando se o merge request pode ser feito o merge…"
+msgstr "Verificando se a solicitação de mesclagem pode ser feito a mesclagem…"
msgid "mrWidget|Cherry-pick"
msgstr "Cherry-pick"
@@ -39571,14 +39953,16 @@ msgstr "Fechado"
msgid "mrWidget|Closed by"
msgstr "Fechado por"
-msgid "mrWidget|Closes"
-msgstr "Fecha"
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr "Excluir branch de origem"
msgid "mrWidget|Deployment statistics are not available currently"
-msgstr "Estatísticas de deploy não estão disponíveis atualmente"
+msgstr "Estatísticas de implantação não estão disponíveis atualmente"
msgid "mrWidget|Did not close"
msgstr "Não foi possível fechar"
@@ -39587,7 +39971,7 @@ msgid "mrWidget|Email patches"
msgstr "Email patches"
msgid "mrWidget|Failed to load deployment statistics"
-msgstr "Falha ao carregar estatísticas de deploy"
+msgstr "Falha ao carregar estatísticas de implantação"
msgid "mrWidget|If the %{missingBranchName} branch exists in your local repository, you can merge this merge request manually using the command line"
msgstr "Se o branch %{missingBranchName} existir em seu repositório local, você poderá fazer merge request manualmente usando a linha de comando"
@@ -39599,22 +39983,24 @@ msgid "mrWidget|Jump to first unresolved thread"
msgstr ""
msgid "mrWidget|Loading deployment statistics"
-msgstr "Carregando estatísticas de deploy"
+msgstr "Carregando estatísticas de implantação"
msgid "mrWidget|Mark as ready"
-msgstr ""
+msgstr "Marcar como pronto"
msgid "mrWidget|Members who can merge are allowed to add commits."
-msgstr "Membros que podem fazer o merge e tem a permissão de adicionar commits."
+msgstr "Membros que podem fazer a mesclagem e tem a permissão de adicionar commits."
-msgid "mrWidget|Mentions"
-msgstr "Menções"
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
-msgstr "Fazer merge"
+msgstr "Mesclar"
msgid "mrWidget|Merge blocked: all threads must be resolved."
-msgstr "Merge bloqueado: todos os tópicos devem ser resolvidos."
+msgstr "Mesclagem bloqueada: todos os tópicos devem ser resolvidos."
msgid "mrWidget|Merge blocked: fast-forward merge is not possible. To merge this request, first rebase locally."
msgstr ""
@@ -39623,16 +40009,16 @@ msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual
msgstr ""
msgid "mrWidget|Merge failed."
-msgstr "Falha ao fazer merge."
+msgstr "Falha ao mesclar."
msgid "mrWidget|Merge locally"
-msgstr "Fazer merge localmente"
+msgstr "Mesclar localmente"
msgid "mrWidget|Merge request approved."
-msgstr "Merge request aprovado."
+msgstr "Solicitação de mesclagem aprovada."
msgid "mrWidget|Merged by"
-msgstr "Merge realizado por"
+msgstr "Mesclado por"
msgid "mrWidget|Merging! Changes are being shipped…"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr "Mais informações"
+msgid "mrWidget|Open in Gitpod"
+msgstr "Abrir no Gitpod"
+
msgid "mrWidget|Open in Web IDE"
msgstr "Abrir no IDE Web"
@@ -39662,7 +40051,7 @@ msgid "mrWidget|Plain diff"
msgstr "Diff em texto"
msgid "mrWidget|Ready to be merged automatically. Ask someone with write access to this repository to merge this request"
-msgstr "Pronto para ser feito merge automaticamente. Peça a alguém com acesso de gravação a este repositório para dar merge nesse request"
+msgstr "Pronto para ser mesclado automaticamente. Peça a alguém com acesso de gravação a este repositório para mesclar nessa requisição"
msgid "mrWidget|Refresh"
msgstr "Atualizar"
@@ -39674,10 +40063,10 @@ msgid "mrWidget|Refreshing now"
msgstr "Atualizando agora"
msgid "mrWidget|Remove from merge train"
-msgstr ""
+msgstr "Remover do merge train"
msgid "mrWidget|Request to merge"
-msgstr "Merge de"
+msgstr "Solicitar mesclagem"
msgid "mrWidget|Resolve all threads in new issue"
msgstr ""
@@ -39686,13 +40075,13 @@ msgid "mrWidget|Resolve conflicts"
msgstr "Resolver conflitos"
msgid "mrWidget|Resolve these conflicts or ask someone with write access to this repository to merge it locally"
-msgstr "Resolva estes conflitos ou peça a alguém com acesso de escrita para este repositório realizar o merge localmente"
+msgstr "Resolva estes conflitos ou peça a alguém com acesso de escrita para este repositório realizar a mesclagem localmente"
msgid "mrWidget|Revert"
msgstr "Reverter"
msgid "mrWidget|Revert this merge request in a new merge request"
-msgstr "Reverter esse merge request com um novo merge request"
+msgstr "Reverter essa solicitação de mesclagem com um nova solicitação de mesclagem"
msgid "mrWidget|Revoke approval"
msgstr "Revogar aprovação"
@@ -39718,23 +40107,20 @@ msgstr "Será feito merge das alterações em"
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr "O pipeline para essse merge request não foi concluído. Faça um push em um novo commit para corrigir a falha, ou verifique a %{linkStart}documentação de solução de problemas%{linkEnd} para ver as possíveis ações."
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr "O HEAD do branch origem foi modificado recentemente. Por favor, recarregue a página e revise as alterações antes de realizar o merge"
-
msgid "mrWidget|The source branch has been deleted"
msgstr "O branch de origem foi excluído"
msgid "mrWidget|The source branch is %{link} the target branch"
-msgstr "O branch de origem é %{link} do branch de destino"
+msgstr "A ramificação de origem é %{link} da ramificação de destino"
msgid "mrWidget|The source branch is being deleted"
msgstr ""
msgid "mrWidget|The source branch will be deleted"
-msgstr "O branch de origem será excluído"
+msgstr "A ramificação de origem será excluída"
msgid "mrWidget|The source branch will not be deleted"
-msgstr "O branch de origem não será excluído"
+msgstr "A ramificação de origem não será excluída"
msgid "mrWidget|There are merge conflicts"
msgstr "Existem conflitos de merge"
@@ -39760,17 +40146,14 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr "Você não tem permissão para editar este projeto diretamente. Por favor, faça fork no projeto para fazer alterações."
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
msgid "mrWidget|Your password"
-msgstr ""
+msgstr "Sua senha"
msgid "mrWidget|branch does not exist."
-msgstr "branch não existe."
+msgstr "ramificação não existe."
msgid "mrWidget|into"
msgstr "para"
@@ -39790,12 +40173,18 @@ msgstr "deve ser um endereço IPv4 ou IPv6 válido"
msgid "must be after start"
msgstr "deve ser depois do início"
+msgid "must be an email you have verified"
+msgstr "deve ser um email verificado"
+
msgid "must be greater than start date"
msgstr "deve ser maior que a data de início"
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
@@ -40029,31 +40418,31 @@ msgid "severity|Blocker"
msgstr ""
msgid "severity|Critical"
-msgstr ""
+msgstr "Crítico"
msgid "severity|High"
-msgstr ""
+msgstr "Alto"
msgid "severity|Info"
msgstr "Informação"
msgid "severity|Low"
-msgstr ""
+msgstr "Baixo"
msgid "severity|Major"
-msgstr ""
+msgstr "Maior"
msgid "severity|Medium"
-msgstr ""
+msgstr "Médio"
msgid "severity|Minor"
-msgstr ""
+msgstr "Menor"
msgid "severity|None"
msgstr "Nenhuma"
msgid "severity|Unknown"
-msgstr ""
+msgstr "Desconhecido"
msgid "should be an array of %{object_name} objects"
msgstr ""
@@ -40089,7 +40478,7 @@ msgid "specified top is not part of the tree"
msgstr ""
msgid "spendCommand|%{slash_command} adds or subtracts time already spent."
-msgstr ""
+msgstr "%{slash_command} adiciona ou subtrai o tempo já gasto."
msgid "ssh:"
msgstr ""
@@ -40125,7 +40514,7 @@ msgid "suggestPipeline|We’re adding a GitLab CI configuration file to add a pi
msgstr ""
msgid "tag name"
-msgstr ""
+msgstr "nome da tag"
msgid "the correct format."
msgstr ""
@@ -40215,7 +40604,7 @@ msgid "via %{closed_via}"
msgstr ""
msgid "via merge request %{link}"
-msgstr "via merge request %{link}"
+msgstr "vía solicitação de mesclagem %{link}"
msgid "view it on GitLab"
msgstr "ver no GitLab"
diff --git a/locale/pt_PT/gitlab.po b/locale/pt_PT/gitlab.po
index 69e8cd9d9b7..17452860e76 100644
--- a/locale/pt_PT/gitlab.po
+++ b/locale/pt_PT/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: pt-PT\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:33\n"
+"PO-Revision-Date: 2021-09-01 22:34\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] "%{count} participantes"
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,8 +2349,8 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
-msgstr "Estás prestes a parar todos os trabalhos. Isto irá interromper todos os trabalhos em execução."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
+msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
@@ -2566,12 +2577,6 @@ msgstr "Bloqueado"
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr "És tu!"
@@ -2701,6 +2709,12 @@ msgstr "Enviar email aos utilizadores"
msgid "AdminUsers|Sort by"
msgstr "Ordenar por"
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr "Ocorreu um erro ao buscar as listas do painel. Por favor, tenta novamente."
-
msgid "An error occurred while fetching the job log."
msgstr "Ocorreu um erro ao buscar o registo do trabalho."
@@ -3630,9 +3641,6 @@ msgstr "Ocorreu um erro ao buscar os trabalhos."
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr "Ocorreu um erro ao buscar a pipeline."
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr "Ocorreu um erro ao buscar os lançamentos. Por favor, tenta novamente."
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] "%{count} aprovação obrigatória de %{membersCount}"
msgstr[1] "%{count} aprovações obrigatórias de %{membersCount}"
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr "Tens a certeza de que desejas desarquivar este projeto?"
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr "Tens a certeza de que desejas cancelar a edição deste comentário?"
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr "Artefactos"
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr "Listas de responsáveis não disponíveis com a tua licença atual"
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr "As listas de responsáveis mostram todos os problemas atribuídos ao utilizador selecionado."
-
msgid "Assignee(s)"
msgstr "Responsável(eis)"
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr "Gestão automática de certificados ao usar Vamos Criptografar"
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr "Começar com o envio selecionado"
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr "Painéis"
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr "Colapsar"
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr "CONTRIBUTING"
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr "A verificar a disponibilidade do nome de utilizador..."
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7365,7 +7410,7 @@ msgid "ClusterIntegration|Connection Error"
msgstr ""
msgid "ClusterIntegration|Copy API URL"
-msgstr " Copiar URL da API"
+msgstr ""
msgid "ClusterIntegration|Copy CA Certificate"
msgstr "Copiar Certificado CA"
@@ -7455,7 +7500,7 @@ msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes clust
msgstr ""
msgid "ClusterIntegration|Enter the details for your Kubernetes cluster"
-msgstr " Insere os detalhes do teu cluster do Kubernetes"
+msgstr ""
msgid "ClusterIntegration|Environment scope"
msgstr "Alcance de ambiente"
@@ -7512,10 +7557,10 @@ msgid "ClusterIntegration|Google GKE"
msgstr ""
msgid "ClusterIntegration|Google Kubernetes Engine"
-msgstr " Google Kubernetes Engine"
+msgstr ""
msgid "ClusterIntegration|Google Kubernetes Engine project"
-msgstr " Projeto do Google Kubernetes Engine"
+msgstr ""
msgid "ClusterIntegration|Group cluster"
msgstr "Cluster de grupo"
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr "Os Ambientes são lugares onde o código é implantado, como preparação ou produção."
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr "Erros encontrados no teu %{gitlab_ci_yml}:"
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr "Estado Geo"
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr "Listas de etiquetas que mostram todos os problemas com a etiqueta selecionada."
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
+msgstr ""
+
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr "Não está disponível as listas de objetivos com a tua licença atual"
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr "As listas de objetivos mostram todos os problemas do objetivo selecionado."
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr "nome do ramo"
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/ro_RO/gitlab.po b/locale/ro_RO/gitlab.po
index d21b0cc3350..a686a80c8b5 100644
--- a/locale/ro_RO/gitlab.po
+++ b/locale/ro_RO/gitlab.po
@@ -14,1372 +14,1384 @@ msgstr ""
"X-Crowdin-Language: ro\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:11\n"
+"PO-Revision-Date: 2021-09-02 01:24\n"
msgid " %{name}, confirm your email address now! "
-msgstr ""
+msgstr " %{name}, confirmă adresa de e-mail acum! "
msgid " %{start} to %{end}"
-msgstr ""
+msgstr " de la %{start} până la %{end}"
msgid " (from %{timeoutSource})"
-msgstr ""
+msgstr " (de la %{timeoutSource})"
msgid " Collected %{time}"
-msgstr ""
+msgstr " %{time} colectat"
msgid " Please sign in."
-msgstr ""
+msgstr " Vă rugăm să vă autentificați."
msgid " Target Path"
-msgstr ""
+msgstr " Traiectoria țintă"
msgid " Try to %{action} this file again."
-msgstr ""
+msgstr " Încercați să %{action} acest fișier din nou."
msgid " Type"
-msgstr ""
+msgstr " Tip"
msgid " You need to do this before %{grace_period_deadline}."
-msgstr ""
+msgstr " Trebuie să faceți asta înainte de %{grace_period_deadline}."
msgid " and"
-msgstr ""
+msgstr " și"
msgid " and "
-msgstr ""
+msgstr " și "
msgid " and %{sliced}"
-msgstr ""
+msgstr " și %{sliced}"
msgid " degraded on %d point"
msgid_plural " degraded on %d points"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] " degradat la %d punct"
+msgstr[1] " degradat la %d puncte"
+msgstr[2] " degradat la %d de puncte"
msgid " improved on %d point"
msgid_plural " improved on %d points"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] " îmbunătățit în %d punct"
+msgstr[1] " îmbunătățit în %d puncte"
+msgstr[2] " îmbunătățit în %d de puncte"
msgid " or "
-msgstr ""
+msgstr " sau "
msgid " or %{emphasisStart}!merge request id%{emphasisEnd}"
-msgstr ""
+msgstr " sau %{emphasisStart}!ID-ul cererii de îmbinare%{emphasisEnd}"
msgid " or %{emphasisStart}#issue id%{emphasisEnd}"
-msgstr ""
+msgstr " sau %{emphasisStart}#ID problemă%{emphasisEnd}"
msgid " or %{emphasisStart}&epic id%{emphasisEnd}"
-msgstr ""
+msgstr " sau %{emphasisStart}&ID epică%{emphasisEnd}"
msgid " or references (e.g. path/to/project!merge_request_id)"
-msgstr ""
+msgstr " sau referințe (de exemplu, cale/către/project!merge_request_id)"
msgid " reacted with :%{name}:"
-msgstr ""
+msgstr " a reacționat cu :%{name}:"
msgid "\"%{path}\" did not exist on \"%{ref}\""
-msgstr ""
+msgstr "\"%{path}\" nu a existat pe \"%{ref}\""
msgid "\"%{repository_name}\" size (%{repository_size}) is larger than the limit of %{limit}."
-msgstr ""
+msgstr "\"%{repository_name}\" dimensiunea (%{repository_size}) este mai mare decât limita de %{limit}."
msgid "\"el\" parameter is required for createInstance()"
-msgstr ""
+msgstr "Parametrul \"el\" este necesar pentru createInstance()"
msgid "#general, #development"
-msgstr ""
+msgstr "#general, #development"
msgid "%d Approval"
msgid_plural "%d Approvals"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d Aprobare"
+msgstr[1] "%d Aprobări"
+msgstr[2] "%d de Aprobări"
msgid "%d Module"
msgid_plural "%d Modules"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d Modul"
+msgstr[1] "%d Module"
+msgstr[2] "%d de Module"
msgid "%d Other"
msgid_plural "%d Others"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d Altul"
+msgstr[1] "%d Altele"
+msgstr[2] "%d Altele"
msgid "%d Package"
msgid_plural "%d Packages"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d Pachet"
+msgstr[1] "%d Pachete"
+msgstr[2] "%d de Pachete"
msgid "%d Scanned URL"
msgid_plural "%d Scanned URLs"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d URL scanat"
+msgstr[1] "%d URL-uri scanate"
+msgstr[2] "%d de URL-uri scanate"
msgid "%d URL scanned"
msgid_plural "%d URLs scanned"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d URL scanat"
+msgstr[1] "%d URL-uri scanate"
+msgstr[2] "%d de URL-uri scanate"
msgid "%d approver"
msgid_plural "%d approvers"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d aprobator"
+msgstr[1] "%d aprobatori"
+msgstr[2] "%d de aprobatori"
msgid "%d approver (you've approved)"
msgid_plural "%d approvers (you've approved)"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d aprobator (ați aprobat)"
+msgstr[1] "%d aprobatori (ați aprobat)"
+msgstr[2] "%d de aprobatori (ați aprobat)"
msgid "%d changed file"
msgid_plural "%d changed files"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d fișier modificat"
+msgstr[1] "%d fișiere modificate"
+msgstr[2] "%d de fișiere modificate"
msgid "%d character remaining"
msgid_plural "%d characters remaining"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d caracter rămas"
+msgstr[1] "%d caractere rămase"
+msgstr[2] "%d de caractere rămase"
msgid "%d child epic"
msgid_plural "%d child epics"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d epică copil"
+msgstr[1] "%d epici copil"
+msgstr[2] "%d de epici copil"
msgid "%d code quality issue"
msgid_plural "%d code quality issues"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d problemă de calitate a codului"
+msgstr[1] "%d probleme de calitate a codului"
+msgstr[2] "%d de probleme de calitate a codului"
msgid "%d comment"
msgid_plural "%d comments"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d comentariu"
+msgstr[1] "%d comentarii"
+msgstr[2] "%d de comentarii"
msgid "%d comment on this commit"
msgid_plural "%d comments on this commit"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d comentariu la acest commit"
+msgstr[1] "%d comentarii la acest commit"
+msgstr[2] "%d de comentarii la acest commit"
msgid "%d commenter"
msgid_plural "%d commenters"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d comentator"
+msgstr[1] "%d comentatori"
+msgstr[2] "%d de comentatori"
msgid "%d commit"
msgid_plural "%d commits"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d commit"
+msgstr[1] "%d commit-uri"
+msgstr[2] "%d de commit-uri"
msgid "%d commit author"
msgid_plural "%d commit authors"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d autor comitere"
+msgstr[1] "%d autori comitere"
+msgstr[2] "%d de autori comitere"
msgid "%d commit behind"
msgid_plural "%d commits behind"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d commit în urmă"
+msgstr[1] "%d commit-uri în urmă"
+msgstr[2] "%d de commit-uri în urmă"
msgid "%d commit,"
msgid_plural "%d commits,"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d commit,"
+msgstr[1] "%d commit-uri,"
+msgstr[2] "%d de commit-uri,"
msgid "%d commits"
-msgstr ""
+msgstr "%d (de) commit-uri"
msgid "%d completed issue"
msgid_plural "%d completed issues"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d problemă completată"
+msgstr[1] "%d probleme completate"
+msgstr[2] "%d de probleme completate"
msgid "%d contribution"
msgid_plural "%d contributions"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d contribuție"
+msgstr[1] "%d contribuții"
+msgstr[2] "%d de contribuții"
msgid "%d day"
msgid_plural "%d days"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d zi"
+msgstr[1] "%d zile"
+msgstr[2] "%d de zile"
msgid "%d epic"
msgid_plural "%d epics"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d epică"
+msgstr[1] "%d de epici"
+msgstr[2] "%d de epici"
msgid "%d error"
msgid_plural "%d errors"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d eroare"
+msgstr[1] "%d erori"
+msgstr[2] "%d de erori"
msgid "%d error found:"
msgid_plural "%d errors found:"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d eroare găsită:"
+msgstr[1] "%d erori găsite:"
+msgstr[2] "%d de erori găsite:"
msgid "%d exporter"
msgid_plural "%d exporters"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d exportator"
+msgstr[1] "%d exportatori"
+msgstr[2] "%d de exportatori"
msgid "%d failed"
msgid_plural "%d failed"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d eșuare"
+msgstr[1] "%d eșuări"
+msgstr[2] "%d de eșuări"
msgid "%d failed security job"
msgid_plural "%d failed security jobs"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d job de securitate eșuat"
+msgstr[1] "%d joburi de securitate eșuate"
+msgstr[2] "%d de joburi de securitate eșuate"
msgid "%d file"
msgid_plural "%d files"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d fișier"
+msgstr[1] "%d fișiere"
+msgstr[2] "%d de fișiere"
msgid "%d fixed test result"
msgid_plural "%d fixed test results"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d rezultat de test rezolvat"
+msgstr[1] "%d rezultate de test rezolvate"
+msgstr[2] "%d de rezultate de test rezolvate"
msgid "%d group"
msgid_plural "%d groups"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d grup"
+msgstr[1] "%d grupuri"
+msgstr[2] "%d de grupuri"
msgid "%d group selected"
msgid_plural "%d groups selected"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d grup selectat"
+msgstr[1] "%d grupuri selectate"
+msgstr[2] "%d de grupuri selectate"
msgid "%d hour"
msgid_plural "%d hours"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d oră"
+msgstr[1] "%d ore"
+msgstr[2] "%d de ore"
msgid "%d inaccessible merge request"
msgid_plural "%d inaccessible merge requests"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d cerere de îmbinare inaccesibilă"
+msgstr[1] "%d cereri de îmbinare inaccesibile"
+msgstr[2] "%d de cereri de îmbinare inaccesibile"
msgid "%d issue"
msgid_plural "%d issues"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d problemă"
+msgstr[1] "%d probleme"
+msgstr[2] "%d de probleme"
msgid "%d issue in this group"
msgid_plural "%d issues in this group"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d problemă în acest grup"
+msgstr[1] "%d probleme în acest grup"
+msgstr[2] "%d de probleme în acest grup"
msgid "%d issue successfully imported with the label"
msgid_plural "%d issues successfully imported with the label"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d problemă importată cu succes cu eticheta"
+msgstr[1] "%d probleme importate cu succes cu eticheta"
+msgstr[2] "%d de probleme importate cu succes cu eticheta"
msgid "%d layer"
msgid_plural "%d layers"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d nivel"
+msgstr[1] "%d nivele"
+msgstr[2] "%d de nivele"
msgid "%d merge request"
msgid_plural "%d merge requests"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d cerere de îmbinare"
+msgstr[1] "%d cereri de îmbinare"
+msgstr[2] "%d de cereri de îmbinare"
msgid "%d merge request that you don't have access to."
msgid_plural "%d merge requests that you don't have access to."
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d cerere de îmbinare la care nu aveți acces."
+msgstr[1] "%d cereri de îmbinare la care nu aveți acces."
+msgstr[2] "%d de cereri de îmbinare la care nu aveți acces."
msgid "%d metric"
msgid_plural "%d metrics"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d măsurătoare"
+msgstr[1] "%d măsurători"
+msgstr[2] "%d de măsurători"
msgid "%d milestone"
msgid_plural "%d milestones"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d obiectiv"
+msgstr[1] "%d obiective"
+msgstr[2] "%d de obiective"
msgid "%d minute"
msgid_plural "%d minutes"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d minut"
+msgstr[1] "%d minute"
+msgstr[2] "%d de minute"
msgid "%d more comment"
msgid_plural "%d more comments"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "Încă %d comentariu"
+msgstr[1] "Încă %d comentarii"
+msgstr[2] "Încă %d de comentarii"
msgid "%d open issue"
msgid_plural "%d open issues"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d problemă deschisă"
+msgstr[1] "%d probleme deschise"
+msgstr[2] "%d de probleme deschise"
msgid "%d pending comment"
msgid_plural "%d pending comments"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d comentariu în așteptare"
+msgstr[1] "%d comentarii în așteptare"
+msgstr[2] "%d de comentarii în așteptare"
msgid "%d personal project will be removed and cannot be restored."
msgid_plural "%d personal projects will be removed and cannot be restored."
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d proiectul personal va fi eliminat și nu va putea fi restaurat."
+msgstr[1] "%d proiecte personale vor fi eliminate și nu vor putea fi restaurate."
+msgstr[2] "%d de proiecte personale vor fi eliminate și nu vor putea fi restaurate."
msgid "%d previously merged commit"
msgid_plural "%d previously merged commits"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d commit îmbinat anterior"
+msgstr[1] "%d commit-uri îmbinate anterior"
+msgstr[2] "%d de commit-uri îmbinate anterior"
msgid "%d project"
msgid_plural "%d projects"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d proiect"
+msgstr[1] "%d proiecte"
+msgstr[2] "%d de proiecte"
msgid "%d project selected"
msgid_plural "%d projects selected"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d proiect selectat"
+msgstr[1] "%d proiecte selectate"
+msgstr[2] "%d de proiecte selectate"
msgid "%d request with warnings"
msgid_plural "%d requests with warnings"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d cerere cu avertismente"
+msgstr[1] "%d cereri cu avertismente"
+msgstr[2] "%d de cereri cu avertismente"
msgid "%d second"
msgid_plural "%d seconds"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d secundă"
+msgstr[1] "%d secunde"
+msgstr[2] "%d de secunde"
msgid "%d shard selected"
msgid_plural "%d shards selected"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d fragment selectat"
+msgstr[1] "%d fragmente selectate"
+msgstr[2] "%d de fragmente selectate"
msgid "%d tag"
msgid_plural "%d tags"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d etichetă"
+msgstr[1] "%d etichete"
+msgstr[2] "%d de etichete"
msgid "%d tag per image name"
msgid_plural "%d tags per image name"
+msgstr[0] "%d etichetă pe nume de imagine"
+msgstr[1] "%d etichete pe nume de imagine"
+msgstr[2] "%d de etichete pe nume de imagine"
+
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d problemă neatribuită"
+msgstr[1] "%d probleme neatribuite"
+msgstr[2] "%d de probleme neatribuite"
msgid "%d unresolved thread"
msgid_plural "%d unresolved threads"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d subiect nerezolvat"
+msgstr[1] "%d subiecte nerezolvate"
+msgstr[2] "%d de subiecte nerezolvate"
msgid "%d vulnerability"
msgid_plural "%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d vulnerabilitate"
+msgstr[1] "%d vulnerabilități"
+msgstr[2] "%d de vulnerabilități"
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d vulnerabilitate respinsă"
+msgstr[1] "%d vulnerabilități respinse"
+msgstr[2] "%d de vulnerabilități respinse"
msgid "%d vulnerability updated"
msgid_plural "%d vulnerabilities updated"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d vulnerabilitate actualizată"
+msgstr[1] "%d vulnerabilități actualizate"
+msgstr[2] "%d de vulnerabilități actualizate"
msgid "%d warning found:"
msgid_plural "%d warnings found:"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d avertisment găsit:"
+msgstr[1] "%d avertismente găsite:"
+msgstr[2] "%d de avertismente găsite:"
msgid "%s additional commit has been omitted to prevent performance issues."
msgid_plural "%s additional commits have been omitted to prevent performance issues."
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%s commit suplimentar a fost omis pentru a preveni problemele de performanță."
+msgstr[1] "%s commit-uri suplimentare au fost omise pentru a preveni probleme de performanță."
+msgstr[2] "%s de commit-uri suplimentare au fost omise pentru a preveni problemele de performanță."
msgid "%{actionText} & %{openOrClose} %{noteable}"
-msgstr ""
+msgstr "%{actionText} & %{openOrClose} %{noteable}"
msgid "%{address} is an invalid IP address range"
-msgstr ""
+msgstr "%{address} este un interval de adrese IP invalid"
msgid "%{anchorOpen}Learn more%{anchorClose} about how you can customize / disable registration on your instance."
-msgstr ""
+msgstr "%{anchorOpen}Învățați mai multe%{anchorClose} despre modul în care puteți personaliza / dezactiva înregistrarea în instanța dvs."
msgid "%{author_link} cloned %{original_issue} to %{new_issue}."
-msgstr ""
+msgstr "%{author_link} a clonat %{original_issue} în %{new_issue}."
msgid "%{author_link} cloned %{original_issue}. You don't have access to the new project."
-msgstr ""
+msgstr "%{author_link} a clonat %{original_issue}. Nu aveți acces la noul proiect."
msgid "%{author_link} wrote:"
-msgstr ""
+msgstr "%{author_link} a scris:"
msgid "%{authorsName}'s thread"
-msgstr ""
+msgstr "Subiectul lui %{authorsName}"
msgid "%{board_target} not found"
-msgstr ""
+msgstr "%{board_target} nu a fost găsit"
msgid "%{bold_start}%{count}%{bold_end} issue"
msgid_plural "%{bold_start}%{count}%{bold_end} issues"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%{bold_start}%{count}%{bold_end} problemă"
+msgstr[1] "%{bold_start}%{count}%{bold_end} probleme"
+msgstr[2] "%{bold_start}%{count}%{bold_end} de probleme"
msgid "%{bold_start}%{count}%{bold_end} member"
msgid_plural "%{bold_start}%{count}%{bold_end} members"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%{bold_start}%{count}%{bold_end} membru"
+msgstr[1] "%{bold_start}%{count}%{bold_end} membrii"
+msgstr[2] "%{bold_start}%{count}%{bold_end} de membrii"
msgid "%{bold_start}%{count}%{bold_end} opened merge request"
msgid_plural "%{bold_start}%{count}%{bold_end} opened merge requests"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%{bold_start}%{count}%{bold_end} cerere de îmbinare deschisă"
+msgstr[1] "%{bold_start}%{count}%{bold_end} cereri de îmbinare deschise"
+msgstr[2] "%{bold_start}%{count}%{bold_end} de cereri de îmbinare deschise"
msgid "%{code_open}Masked:%{code_close} Hidden in job logs. Must match masking requirements."
-msgstr ""
+msgstr "%{code_open}Mascat:%{code_close} Ascuns în jurnalele de joburi. Trebuie să corespundă cerințelor de mascare."
msgid "%{code_open}Protected:%{code_close} Only exposed to protected branches or tags."
-msgstr ""
+msgstr "%{code_open}Protejat:%{code_close} Este expus numai la ramurile sau etichetele protejate."
msgid "%{commit_author_link} authored %{commit_timeago}"
-msgstr ""
+msgstr "%{commit_author_link} redactat %{commit_timeago}"
msgid "%{completedCount} completed weight"
-msgstr ""
+msgstr "%{completedCount} greutate finalizată"
msgid "%{completedCount} of %{count} task completed"
msgid_plural "%{completedCount} of %{count} tasks completed"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%{completedCount} din %{count} sarcini completată"
+msgstr[1] "%{completedCount} din %{count} sarcini completate"
+msgstr[2] "%{completedCount} din %{count} de sarcini completate"
msgid "%{completedWeight} of %{totalWeight} weight completed"
-msgstr ""
+msgstr "%{completedWeight} din %{totalWeight} greutate finalizată"
msgid "%{cores} cores"
-msgstr ""
+msgstr "%{cores} nuclee"
msgid "%{count} %{scope} for term '%{term}'"
-msgstr ""
+msgstr "%{count} %{scope} pentru termenul '%{term}'"
msgid "%{count} LOC/commit"
-msgstr ""
+msgstr "%{count} LOC/commit"
msgid "%{count} approval required from %{name}"
msgid_plural "%{count} approvals required from %{name}"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%{count} aprobare cerută de %{name}"
+msgstr[1] "%{count} aprobări cerute de %{name}"
+msgstr[2] "%{count} de aprobări cerute de %{name}"
msgid "%{count} approvals from %{name}"
-msgstr ""
+msgstr "%{count} aprobări de la %{name}"
msgid "%{count} files touched"
-msgstr ""
+msgstr "%{count} fișiere atinse"
msgid "%{count} item"
msgid_plural "%{count} items"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%{count} element"
+msgstr[1] "%{count} elemente"
+msgstr[2] "%{count} de elemente"
msgid "%{count} items per page"
-msgstr ""
+msgstr "%{count} articole pe pagină"
msgid "%{count} more"
-msgstr ""
+msgstr "%{count} mai mult"
msgid "%{count} more assignees"
-msgstr ""
+msgstr "Încă %{count} cesionari"
msgid "%{count} more release"
msgid_plural "%{count} more releases"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "încă %{count} lansare"
+msgstr[1] "încă %{count} lansări"
+msgstr[2] "încă %{count} de lansări"
msgid "%{count} of %{required} approvals from %{name}"
-msgstr ""
+msgstr "%{count} din %{required} aprobări de la %{name}"
msgid "%{count} of %{total}"
-msgstr ""
+msgstr "%{count} din %{total}"
msgid "%{count} participant"
msgid_plural "%{count} participants"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%{count} participant"
+msgstr[1] "%{count} participanți"
+msgstr[2] "%{count} de participanți"
msgid "%{count} related %{pluralized_subject}: %{links}"
+msgstr "%{count} legate de %{pluralized_subject}: %{links}"
+
+msgid "%{count} selected"
msgstr ""
msgid "%{count} total weight"
-msgstr ""
+msgstr "%{count} greutate totală"
msgid "%{criticalStart}%{critical} Critical%{criticalEnd} %{highStart}%{high} High%{highEnd} and %{otherStart}%{otherMessage}%{otherEnd}"
-msgstr ""
+msgstr "%{criticalStart}%{critical} Critic%{criticalEnd} %{highStart}%{high} Înalt%{highEnd} și %{otherStart}%{otherMessage}%{otherEnd}"
msgid "%{dashboard_path} could not be found."
-msgstr ""
+msgstr "%{dashboard_path} nu a putut fi găsit."
msgid "%{days} days until tags are automatically removed"
-msgstr ""
+msgstr "%{days} zile până când etichetele sunt eliminate automat"
msgid "%{deployLinkStart}Use a template to deploy to ECS%{deployLinkEnd}, or use a docker image to %{commandsLinkStart}run AWS commands in GitLab CI/CD%{commandsLinkEnd}."
-msgstr ""
+msgstr "%{deployLinkStart}Folosește un șablon pentru a implementa în ECS%{deployLinkEnd}, sau folosește o imagine docker pentru a%{commandsLinkStart}executa comenzi AWS în GitLab CI/CD%{commandsLinkEnd}."
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
-msgstr ""
+msgstr "%{description}- Eveniment Sentry: %{errorUrl}- Prima dată când a fost văzut: %{firstSeen}- Ultima dată când a fost văzut: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
-msgstr ""
+msgstr "%{doc_link_start}Căutarea avansată%{doc_link_end} este dezactivată deoarece %{ref_elem} nu este ramura implicită; %{default_branch_link_start}căutați pe %{default_branch} în schimb%{default_branch_link_end}."
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
-msgstr ""
+msgstr "%{doc_link_start}Căutarea avansată%{doc_link_end} este activată."
msgid "%{due_date} (Past due)"
-msgstr ""
+msgstr "%{due_date} (Cu scadență depășită)"
msgid "%{duration}ms"
-msgstr ""
+msgstr "%{duration}ms"
msgid "%{edit_in_new_fork_notice} Try to cherry-pick this commit again."
-msgstr ""
+msgstr "%{edit_in_new_fork_notice} Încercați să cherry-pick acest commit din nou."
msgid "%{edit_in_new_fork_notice} Try to create a new directory again."
-msgstr ""
+msgstr "%{edit_in_new_fork_notice} Încercați să creați iar un director nou."
msgid "%{edit_in_new_fork_notice} Try to revert this commit again."
-msgstr ""
+msgstr "%{edit_in_new_fork_notice} Încercați să reveniți din nou la acest commit."
msgid "%{edit_in_new_fork_notice} Try to upload a file again."
-msgstr ""
+msgstr "%{edit_in_new_fork_notice} Încercați să încărcați iar un fișier."
msgid "%{emailPrefix}@company.com"
-msgstr ""
+msgstr "%{emailPrefix}@company.com"
msgid "%{extra} more downstream pipelines"
-msgstr ""
+msgstr "%{extra} mai multe conducte downstream"
msgid "%{filePath} deleted"
-msgstr ""
+msgstr "%{filePath} șters"
msgid "%{firstLabel} +%{labelCount} more"
-msgstr ""
+msgstr "%{firstLabel} + %{labelCount} mai mult"
msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
-msgstr ""
+msgstr "%{firstMilestoneName} + %{numberOfOtherMilestones} mai mult"
msgid "%{gitlab_experience_text}. Don't worry, this information isn't shared outside of your self-managed GitLab instance."
-msgstr ""
+msgstr "%{gitlab_experience_text}. Nu vă faceți griji, aceste informații nu sunt partajate în afara instanței GitLab autogestionate."
msgid "%{gitlab_experience_text}. We won't share this information with anyone."
-msgstr ""
+msgstr "%{gitlab_experience_text}. Nu vom împărtăși aceste informații cu nimeni."
msgid "%{global_id} is not a valid ID for %{expected_types}."
-msgstr ""
+msgstr "%{global_id} nu este un ID valid pentru %{expected_types}."
msgid "%{group_name} activity"
-msgstr ""
+msgstr "%{group_name} activitate"
msgid "%{group_name} group members"
-msgstr ""
+msgstr "%{group_name} membri ai grupului"
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
-msgstr ""
+msgstr "%{group_name} utilizează conturi gestionate de grup. Trebuie să creați un nou cont GitLab care va fi gestionat de %{group_name}."
msgid "%{group_name}&%{epic_iid} &middot; created %{epic_created} by %{author}"
-msgstr ""
+msgstr "%{group_name}&%{epic_iid} &middot; au creat %{epic_created} de %{author}"
msgid "%{hook_type} was deleted"
-msgstr ""
+msgstr "%{hook_type} a fost șters"
msgid "%{hook_type} was scheduled for deletion"
-msgstr ""
+msgstr "%{hook_type} a fost programat pentru ștergere"
msgid "%{host} sign-in from new location"
-msgstr ""
+msgstr "%{host} autentificare dintr-o locație nouă"
msgid "%{integrations_link_start}Integrations%{link_end} enable you to make third-party applications part of your GitLab workflow. If the available integrations don't meet your needs, consider using a %{webhooks_link_start}webhook%{link_end}."
-msgstr ""
+msgstr "%{integrations_link_start}Integrations%{link_end} vă permit să faceți aplicații terțe parte din fluxul de lucru GitLab. Dacă integrările disponibile nu vă satisfac nevoile, luați în considerare utilizarea unui %{webhooks_link_start}webhook%{link_end}."
msgid "%{issuableType} will be removed! Are you sure?"
msgstr "%{issuableType} va fi eliminat! Esti sigur?"
msgid "%{issueType} actions"
-msgstr ""
+msgstr "%{issueType} acțiuni"
msgid "%{issuesCount} issues with a limit of %{maxIssueCount}"
-msgstr ""
+msgstr "%{issuesCount} probleme cu o limită de %{maxIssueCount}"
msgid "%{issuesSize} with a limit of %{maxIssueCount}"
-msgstr ""
+msgstr "%{issuesSize} cu o limită de %{maxIssueCount}"
msgid "%{italic_start}What's new%{italic_end} is inactive and cannot be viewed."
-msgstr ""
+msgstr "%{italic_start}Ce este nou%{italic_end} este inactiv și nu poate fi vizualizat."
msgid "%{itemsCount} issues with a limit of %{maxIssueCount}"
-msgstr ""
+msgstr "%{itemsCount} probleme cu o limită de %{maxIssueCount}"
msgid "%{labelStart}Actual response:%{labelEnd} %{headers}"
-msgstr ""
+msgstr "%{labelStart}Răspunsul real:%{labelEnd} %{headers}"
msgid "%{labelStart}Assert:%{labelEnd} %{assertion}"
-msgstr ""
+msgstr "%{labelStart}Assert:%{labelEnd} %{assertion}"
msgid "%{labelStart}Class:%{labelEnd} %{class}"
-msgstr ""
+msgstr "%{labelStart}Clasa:%{labelEnd} %{class}"
msgid "%{labelStart}Crash Address:%{labelEnd} %{crash_address}"
-msgstr ""
+msgstr "%{labelStart}Adresa conflictului:%{labelEnd} %{crash_address}"
msgid "%{labelStart}Crash State:%{labelEnd} %{stacktrace_snippet}"
-msgstr ""
+msgstr "%{labelStart}Stare de avarie:%{labelEnd} %{stacktrace_snippet}"
msgid "%{labelStart}Evidence:%{labelEnd} %{evidence}"
-msgstr ""
+msgstr "%{labelStart}Evidență:%{labelEnd} %{evidence}"
msgid "%{labelStart}File:%{labelEnd} %{file}"
-msgstr ""
+msgstr "%{labelStart}Fișierul:%{labelEnd} %{file}"
msgid "%{labelStart}Image:%{labelEnd} %{image}"
-msgstr ""
+msgstr "%{labelStart}Imagine:%{labelEnd} %{image}"
msgid "%{labelStart}Method:%{labelEnd} %{method}"
-msgstr ""
+msgstr "%{labelStart}Metodă:%{labelEnd} %{method}"
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
-msgstr ""
-
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
+msgstr "%{labelStart}Spațiu de nume:%{labelEnd} %{namespace}"
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
-msgstr ""
+msgstr "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgid "%{labelStart}Sent request:%{labelEnd} %{headers}"
-msgstr ""
+msgstr "%{labelStart}Solicitare trimisă:%{labelEnd} %{headers}"
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr "%{labelStart}Severitate:%{labelEnd} %{severity}"
+
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
msgstr ""
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
-msgstr ""
+msgstr "%{labelStart}Răspuns nemodificat:%{labelEnd} %{headers}"
msgid "%{label_for_message} unavailable"
msgstr "%{label_for_message} indisponibil"
msgid "%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} is a free, automated, and open certificate authority (CA) that issues digital certificates to enable HTTPS (SSL/TLS) for sites."
-msgstr ""
+msgstr "%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} este o autoritate de certificare gratuită, automată și deschisă (CA) care emite certificate digitale pentru a activa HTTPS (SSL/TLS) pentru site-uri."
msgid "%{level_name} is not allowed in a %{group_level_name} group."
-msgstr ""
+msgstr "%{level_name} nu este permisă într-un grup %{group_level_name}."
msgid "%{level_name} is not allowed since the fork source project has lower visibility."
-msgstr ""
+msgstr "%{level_name} nu este permis, deoarece proiectul sursă al bifurcației are o vizibilitate mai mică."
msgid "%{link_start}Learn more%{link_end} about roles."
-msgstr ""
+msgstr "%{link_start}Învățați mai multe%{link_end} despre roluri."
msgid "%{link_start}Learn more%{link_end} about what information is shared with GitLab Inc."
-msgstr ""
+msgstr "%{link_start}Învățați mai multe%{link_end} despre ce informații sunt partajate cu GitLab Inc."
msgid "%{link_start}Remove the %{draft_snippet} prefix%{link_end} from the title to allow this merge request to be merged when it's ready."
-msgstr ""
+msgstr "%{link_start}Eliminați %{draft_snippet} prefixul%{link_end} din titlu pentru a permite ca această solicitare de îmbinare să fie îmbinată când este gata."
msgid "%{link_start}Start the title with %{draft_snippet}%{link_end} to prevent a merge request that is a work in progress from being merged before it's ready."
-msgstr ""
+msgstr "%{link_start}Porniți titlul cu %{draft_snippet}%{link_end} pentru a împiedica îmbinarea unei cereri de îmbinare care este o lucrare în curs înainte de a fi gata."
msgid "%{listToShow}, and %{awardsListLength} more"
-msgstr ""
+msgstr "%{listToShow}, și încă %{awardsListLength} mai multe"
msgid "%{location} is missing required keys: %{keys}"
-msgstr ""
+msgstr "%{location} nu are cheile necesare: %{keys}"
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr "%{lock_path} este blocat de utilizatorul GitLab %{lock_user_id}"
msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
-msgstr ""
+msgstr "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} și %{quickActionsDocsLinkStart}acțiuni rapide%{quickActionsDocsLinkEnd} sunt acceptate"
msgid "%{mergeLength}/%{usersLength} can merge"
-msgstr ""
+msgstr "%{mergeLength}/%{usersLength} poate îmbina"
msgid "%{message} showing first %{warnings_displayed}"
-msgstr ""
+msgstr "%{message} afișează primul %{warnings_displayed}"
msgid "%{milestone} (expired)"
-msgstr ""
+msgstr "%{milestone} (expirat)"
msgid "%{milliseconds}ms"
-msgstr ""
+msgstr "%{milliseconds}ms"
msgid "%{model_name} not found"
-msgstr ""
+msgstr "%{model_name} nu a fost găsit"
msgid "%{mrText}, this issue will be closed automatically."
-msgstr ""
+msgstr "%{mrText}, această problemă va fi închisă automat."
msgid "%{name_with_link} namespace has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
-msgstr ""
+msgstr "Spațiul de nume %{name_with_link} are %{percent} sau mai puține minute Shared Runner Pipeline rămase. Odată ce se termină, nu se vor executa noi joburi sau conducte în proiectele sale."
msgid "%{name_with_link} namespace has run out of Shared Runner Pipeline minutes. No new jobs or pipelines in its projects will run."
-msgstr ""
+msgstr "Spațiul de nume %{name_with_link} a rămas fără minute Shared Runner Pipeline. Nu vor exista noi lucrări sau conducte în proiectele sale."
msgid "%{name} (Busy)"
-msgstr ""
+msgstr "%{name} (Ocupat)"
msgid "%{name} contained %{resultsString}"
-msgstr ""
+msgstr "%{name} a conținut %{resultsString}"
msgid "%{name} found %{resultsString}"
-msgstr ""
+msgstr "%{name} a găsit %{resultsString}"
msgid "%{name} is already being used for another emoji"
-msgstr ""
+msgstr "%{name} este deja folosit pentru un alt emoji"
msgid "%{name} is scheduled for %{action}"
-msgstr ""
+msgstr "%{name} este programat pentru %{action}"
msgid "%{name}'s avatar"
-msgstr ""
+msgstr "Avatarul lui %{name}"
msgid "%{name}(%{url}) namespace has %{percent} or less Shared Runner Pipeline minutes remaining. After it runs out, no new jobs or pipelines in its projects will run."
-msgstr ""
+msgstr "Spațiul de nume %{name}(%{url}) are %{percent} sau mai puține minute Shared Runner Pipeline rămase. Odată ce se termină, nu vor mai exista noi joburi sau conducte în proiectele sale."
msgid "%{name}(%{url}) namespace has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
-msgstr ""
+msgstr "Spațiul de nume %{name}(%{url}) a rămas fără minute Shared Runner Pipeline, astfel încât nu vor exista noi joburi sau conducte în proiectele sale."
msgid "%{name}, confirm your email address now!"
-msgstr ""
+msgstr "%{name}, confirmați-vă adresa de e-mail acum!"
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%{no_of_days} zi"
+msgstr[1] "%{no_of_days} zile"
+msgstr[2] "%{no_of_days} de zile"
msgid "%{number_commits_behind} commits behind %{default_branch}, %{number_commits_ahead} commits ahead"
-msgstr ""
+msgstr "%{number_commits_behind} commit-uri în spatele %{default_branch}, %{number_commits_ahead} commit-uri înainte"
msgid "%{oneMonthAgo} - %{today}"
-msgstr ""
+msgstr "%{oneMonthAgo} - %{today}"
msgid "%{oneWeekAgo} - %{today}"
-msgstr ""
+msgstr "%{oneWeekAgo} - %{today}"
msgid "%{oneYearAgo} - %{today}"
-msgstr ""
+msgstr "%{oneYearAgo} - %{today}"
msgid "%{openOrClose} %{noteable}"
msgstr "%{openOrClose} %{noteable}"
msgid "%{openedEpics} open, %{closedEpics} closed"
-msgstr ""
+msgstr "%{openedEpics} deschise, %{closedEpics} închise"
msgid "%{openedIssues} open, %{closedIssues} closed"
-msgstr ""
+msgstr "%{openedIssues} deschis, %{closedIssues} închis"
msgid "%{percentage}%% weight completed"
-msgstr ""
+msgstr "%{percentage}%% greutate finalizată"
msgid "%{percent}%% complete"
-msgstr ""
+msgstr "%{percent}%% completat"
msgid "%{percent}%{percentSymbol} complete"
-msgstr ""
+msgstr "%{percent}%{percentSymbol} completat"
msgid "%{placeholder} is not a valid color scheme"
-msgstr ""
+msgstr "%{placeholder} nu este o schemă de culori validă"
msgid "%{placeholder} is not a valid theme"
-msgstr ""
+msgstr "%{placeholder} nu este o temă validă"
msgid "%{primary} (%{secondary})"
-msgstr ""
+msgstr "%{primary} (%{secondary})"
msgid "%{ref} cannot be added: %{error}"
-msgstr ""
+msgstr "%{ref} nu poate fi adăugat: %{error}"
msgid "%{releases} release"
msgid_plural "%{releases} releases"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%{releases} versiune"
+msgstr[1] "%{releases} versiuni"
+msgstr[2] "%{releases} de versiuni"
msgid "%{remaining_approvals} left"
-msgstr ""
+msgstr "%{remaining_approvals} rămase"
msgid "%{reportType} %{status}"
-msgstr ""
+msgstr "%{reportType} %{status}"
msgid "%{reportType} detected %{totalStart}%{total}%{totalEnd} potential %{vulnMessage}"
-msgstr ""
+msgstr "%{reportType} a detectat %{totalStart}%{total}%{totalEnd} potențiale %{vulnMessage}"
msgid "%{reportType} detected %{totalStart}no%{totalEnd} vulnerabilities."
-msgstr ""
+msgstr "%{reportType} nu a detectat %{totalStart}nicio%{totalEnd} vulnerabilitate."
msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}."
-msgstr ""
+msgstr "%{retryButtonStart}Încercați din nou%{retryButtonEnd} sau %{newFileButtonStart}atașați un nou fișier%{newFileButtonEnd}."
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation_link}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
-msgstr ""
+msgstr "%{rotation} a fost recalculat cu participanții rămași. Vă rugăm să examinați noua configurare pentru %{rotation_link}. Este recomandat să luați legătura cu respondentul de apel curent pentru a asigura continuitatea acoperirii de apel."
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr "%{rotation} a fost recalculat cu participanții rămași. Vă rugăm să examinați noua configurare pentru %{rotation}. Este recomandat să luați legătura cu respondentul de apel curent pentru a asigura continuitatea acoperirii de apel."
+
+msgid "%{scope} results for term '%{term}'"
msgstr ""
msgid "%{seconds}s"
-msgstr ""
+msgstr "%{seconds}s"
msgid "%{securityScanner} is not enabled for this project. %{linkStart}More information%{linkEnd}"
msgid_plural "%{securityScanner} are not enabled for this project. %{linkStart}More information%{linkEnd}"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%{securityScanner} nu este activat pentru acest proiect. %{linkStart}Mai multe informații%{linkEnd}"
+msgstr[1] "%{securityScanner} nu sunt activate pentru acest proiect. %{linkStart}Mai multe informații%{linkEnd}"
+msgstr[2] "%{securityScanner} nu sunt activate pentru acest proiect. %{linkStart}Mai multe informații%{linkEnd}"
msgid "%{securityScanner} result is not available because a pipeline has not been run since it was enabled. %{linkStart}Run a pipeline%{linkEnd}"
msgid_plural "%{securityScanner} results are not available because a pipeline has not been run since it was enabled. %{linkStart}Run a pipeline%{linkEnd}"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "Rezultatul %{securityScanner} nu este disponibil deoarece nu a fost rulată o conductă de când a fost activată. %{linkStart}Executați o conductă%{linkEnd}"
+msgstr[1] "Rezultatele %{securityScanner} nu sunt disponibile deoarece nu a fost rulată o conductă de când a fost activată. %{linkStart}Executați o conductă%{linkEnd}"
+msgstr[2] "Rezultatele %{securityScanner} nu sunt disponibile deoarece nu a fost rulată o conductă de când a fost activată. %{linkStart}Executați o conductă%{linkEnd}"
msgid "%{service_ping_link_start}Learn more%{service_ping_link_end} about what information is shared with GitLab Inc."
-msgstr ""
+msgstr "%{service_ping_link_start}Învățați mai multe%{service_ping_link_end} despre ce informații sunt partajate cu GitLab Inc."
msgid "%{size} %{unit}"
-msgstr ""
+msgstr "%{size} %{unit}"
msgid "%{size} GiB"
-msgstr ""
+msgstr "%{size} GiB"
msgid "%{size} KiB"
-msgstr ""
+msgstr "%{size} KiB"
msgid "%{size} MiB"
-msgstr ""
+msgstr "%{size} MiB"
msgid "%{size} bytes"
-msgstr ""
+msgstr "%{size} biți"
msgid "%{sourceBranch} into %{targetBranch}"
-msgstr ""
+msgstr "%{sourceBranch} în %{targetBranch}"
msgid "%{spammable_titlecase} was submitted to Akismet successfully."
-msgstr ""
+msgstr "%{spammable_titlecase} a fost trimis la Akismet cu succes."
msgid "%{spanStart}at line%{spanEnd} %{errorLine}%{errorColumn}"
-msgstr ""
+msgstr "%{spanStart}la linia%{spanEnd} %{errorLine}%{errorColumn}"
msgid "%{spanStart}in%{spanEnd} %{errorFn}"
-msgstr ""
+msgstr "%{spanStart}în%{spanEnd} %{errorFn}"
msgid "%{start} to %{end}"
-msgstr ""
+msgstr "de la %{start} până la %{end}"
msgid "%{state} epics"
-msgstr ""
+msgstr "%{state} epice"
msgid "%{strongStart}Tip:%{strongEnd} You can also checkout merge requests locally by %{linkStart}following these guidelines%{linkEnd}"
-msgstr ""
+msgstr "%{strongStart}Sfat:%{strongEnd} Puteți de asemenea să verificați cererile de îmbinare la nivel local %{linkStart}urmând aceste instrucțiuni%{linkEnd}"
msgid "%{strong_start}%{branch_count}%{strong_end} Branch"
msgid_plural "%{strong_start}%{branch_count}%{strong_end} Branches"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%{strong_start}%{branch_count}%{strong_end} Ramură"
+msgstr[1] "%{strong_start}%{branch_count}%{strong_end} Ramuri"
+msgstr[2] "%{strong_start}%{branch_count}%{strong_end} de Ramuri"
msgid "%{strong_start}%{commit_count}%{strong_end} Commit"
msgid_plural "%{strong_start}%{commit_count}%{strong_end} Commits"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%{strong_start}%{commit_count}%{strong_end} Commit"
+msgstr[1] "%{strong_start}%{commit_count}%{strong_end} Commit-uri"
+msgstr[2] "%{strong_start}%{commit_count}%{strong_end} de Commit-uri"
msgid "%{strong_start}%{count} approval rule%{strong_end} requires eligible members to approve before merging."
msgid_plural "%{strong_start}%{count} approval rules%{strong_end} require eligible members to approve before merging."
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%{strong_start}%{count} regulă de aprobare%{strong_end} cere membrilor eligibili să aprobe înainte de îmbinare."
+msgstr[1] "%{strong_start}%{count} reguli de aprobare%{strong_end} cer ca membrii eligibili să aprobe înainte de fuziune."
+msgstr[2] "%{strong_start}%{count} de reguli de aprobare%{strong_end} cer ca membrii eligibili să aprobe înainte de fuziune."
msgid "%{strong_start}%{count} eligible member%{strong_end} must approve to merge."
msgid_plural "%{strong_start}%{count} eligible members%{strong_end} must approve to merge."
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%{strong_start}%{count} membru eligibil%{strong_end} trebuie să aprobe îmbinarea."
+msgstr[1] "%{strong_start}%{count} membri eligibili%{strong_end} trebuie să aprobe îmbinarea."
+msgstr[2] "%{strong_start}%{count} de membri eligibili%{strong_end} trebuie să aprobe îmbinarea."
msgid "%{strong_start}%{count} member%{strong_end} must approve to merge. Anyone with role Developer or higher can approve."
msgid_plural "%{strong_start}%{count} members%{strong_end} must approve to merge. Anyone with role Developer or higher can approve."
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%{strong_start}%{count} membru%{strong_end} trebuie să aprobe îmbinarea. Oricine cu rol de Dezvoltator sau mai înalt poate aproba."
+msgstr[1] "%{strong_start}%{count} membri%{strong_end} trebuie să aprobe îmbinarea. Oricine cu rol de Dezvoltator sau mai înalt poate aproba."
+msgstr[2] "%{strong_start}%{count} de membri%{strong_end} trebuie să aprobe îmbinarea. Oricine cu rol de Dezvoltator sau mai înalt poate aproba."
msgid "%{strong_start}%{human_size}%{strong_end} Files"
-msgstr ""
+msgstr "%{strong_start}%{human_size}%{strong_end} Fișiere"
msgid "%{strong_start}%{human_size}%{strong_end} Storage"
-msgstr ""
+msgstr "%{strong_start}%{human_size}%{strong_end} Stocare"
msgid "%{strong_start}%{release_count}%{strong_end} Release"
msgid_plural "%{strong_start}%{release_count}%{strong_end} Releases"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%{strong_start}%{release_count}%{strong_end} Lansare"
+msgstr[1] "%{strong_start}%{release_count}%{strong_end} Lansări"
+msgstr[2] "%{strong_start}%{release_count}%{strong_end} de Lansări"
msgid "%{strong_start}%{tag_count}%{strong_end} Tag"
msgid_plural "%{strong_start}%{tag_count}%{strong_end} Tags"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%{strong_start}%{tag_count}%{strong_end} Etichetă"
+msgstr[1] "%{strong_start}%{tag_count}%{strong_end} Etichete"
+msgstr[2] "%{strong_start}%{tag_count}%{strong_end} de Etichete"
msgid "%{tabname} changed"
-msgstr ""
+msgstr "%{tabname} schimbat"
msgid "%{tags} tag per image name"
-msgstr ""
+msgstr "%{tags} etichetă pentru fiecare nume de imagine"
msgid "%{tags} tags per image name"
-msgstr ""
+msgstr "%{tags} etichete pe nume de imagine"
msgid "%{tag}-%{evidence}-%{filename}"
-msgstr ""
+msgstr "%{tag}-%{evidence}-%{filename}"
msgid "%{template_project_id} is unknown or invalid"
-msgstr ""
+msgstr "%{template_project_id} este necunoscut sau invalid"
msgid "%{text} %{files}"
msgid_plural "%{text} %{files} files"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%{text} %{files}"
+msgstr[1] "%{text} %{files} fișiere"
+msgstr[2] "%{text} %{files} de fișiere"
msgid "%{text} is available"
msgstr "%{text} este disponibil"
msgid "%{timebox_name} should belong either to a project or a group."
-msgstr ""
+msgstr "%{timebox_name} trebuie să aparțină fie unui proiect, fie unui grup."
msgid "%{timebox_type} does not support burnup charts"
-msgstr ""
+msgstr "%{timebox_type} nu acceptă diagrame burnup"
msgid "%{timebox_type} must have a start and due date"
-msgstr ""
+msgstr "%{timebox_type} trebuie să aibă o dată de început și o dată scadentă"
msgid "%{title} %{operator} %{threshold}"
-msgstr ""
+msgstr "%{title} %{operator} %{threshold}"
msgid "%{title} changes"
-msgstr ""
+msgstr "Modificările %{title}"
msgid "%{totalCpu} (%{freeSpacePercentage}%{percentSymbol} free)"
-msgstr ""
+msgstr "%{totalCpu} (%{freeSpacePercentage}%{percentSymbol} gratuit)"
msgid "%{totalMemory} (%{freeSpacePercentage}%{percentSymbol} free)"
-msgstr ""
+msgstr "%{totalMemory} (%{freeSpacePercentage}%{percentSymbol} gratuit)"
msgid "%{totalWeight} total weight"
-msgstr ""
+msgstr "%{totalWeight} greutate totală"
msgid "%{total_warnings} warning(s) found:"
-msgstr ""
+msgstr "%{total_warnings} avertisment(e) găsit(e):"
msgid "%{total} open issue weight"
-msgstr ""
+msgstr "%{total} greutate problemă deschisă"
msgid "%{total} warnings found: showing first %{warningsDisplayed}"
-msgstr ""
+msgstr "%{total} avertismente găsite: se afișează primul %{warningsDisplayed}"
msgid "%{userName} (cannot merge)"
-msgstr ""
+msgstr "%{userName} (nu se poate îmbina)"
msgid "%{userName}'s avatar"
-msgstr ""
+msgstr "Avatarul lui %{userName}"
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
-msgstr ""
+msgstr "%{user_name} (%{user_username}) a fost îndepărtat de la %{rotation} la %{schedule} la %{project}. "
msgid "%{user_name} profile page"
-msgstr ""
+msgstr "pagina de profil a lui %{user_name}"
msgid "%{username} changed the draft status of merge request %{mr_link}"
-msgstr ""
+msgstr "%{username} a modificat starea de schiță a cererii de îmbinare %{mr_link}"
msgid "%{username} has asked for a GitLab account on your instance %{host}:"
-msgstr ""
+msgstr "%{username} a solicitat un cont GitLab în instanța dvs. %{host}:"
msgid "%{username}'s avatar"
-msgstr ""
+msgstr "Avatarul lui %{username}"
msgid "%{user} created a merge request: %{mr_link}"
-msgstr ""
+msgstr "%{user} a creat o cerere de îmbinare: %{mr_link}"
msgid "%{user} created an epic: %{epic_link}"
-msgstr ""
+msgstr "%{user} a creat o epică: %{epic_link}"
msgid "%{user} created an issue: %{issue_link}"
-msgstr ""
+msgstr "%{user} a creat o problemă: %{issue_link}"
msgid "%{value} is not included in the list"
-msgstr ""
+msgstr "%{value} nu este inclusă în listă"
msgid "%{value} s"
-msgstr ""
+msgstr "%{value} s"
msgid "%{verb} %{time_spent_value} spent time."
-msgstr ""
+msgstr "%{verb} %{time_spent_value} a consumat timp."
msgid "%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notifications to web applications in response to events in a group or project."
-msgstr ""
+msgstr "%{webhooks_link_start}%{webhook_type}%{link_end} vă permit să trimiteți notificări către aplicațiile web ca răspuns la evenimente dintr-un grup sau proiect."
msgid "%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notifications to web applications in response to events in a group or project. We recommend using an %{integrations_link_start}integration%{link_end} in preference to a webhook."
-msgstr ""
+msgstr "%{webhooks_link_start}%{webhook_type}%{link_end} vă permit să trimiteți notificări aplicațiilor web ca răspuns la evenimente dintr-un grup sau proiect. Vă recomandăm să utilizați o %{integrations_link_start}integrație%{link_end} de preferință față de un webhook."
msgid "%{wildcards_link_start}Wildcards%{wildcards_link_end} such as %{code_tag_start}v*%{code_tag_end} or %{code_tag_start}*-release%{code_tag_end} are supported."
-msgstr ""
+msgstr "%{wildcards_link_start}Jokerii%{wildcards_link_end} cum ar fi %{code_tag_start}v*%{code_tag_end} sau %{code_tag_start}*-lansare%{code_tag_end} sunt acceptați."
msgid "&lt; 1 hour"
-msgstr ""
+msgstr "&lt; 1 oră"
msgid "'%{data}' at %{location} does not match format: %{format}"
-msgstr ""
+msgstr "'%{data}' la %{location} nu se potrivește cu formatul: %{format}"
msgid "'%{data}' at %{location} does not match pattern: %{pattern}"
-msgstr ""
+msgstr "'%{data}' la %{location} nu se potrivește cu modelul: %{pattern}"
msgid "'%{data}' at %{location} is invalid: error_type=%{type}"
-msgstr ""
+msgstr "'%{data}' la %{location} nu este valid: error_type=%{type}"
msgid "'%{data}' at %{location} is not of type: %{type}"
-msgstr ""
+msgstr "'%{data}' la %{location} nu este de tipul: %{type}"
msgid "'%{data}' at %{location} is not one of: %{enum}"
-msgstr ""
+msgstr "'%{data}' la %{location} nu este unul dintre: %{enum}"
msgid "'%{data}' at %{location} is not: %{const}"
-msgstr ""
+msgstr "'%{data}' la %{location} nu este: %{const}"
msgid "'%{level}' is not a valid visibility level"
-msgstr ""
+msgstr "'%{level}' nu este un nivel de vizibilitate valid"
msgid "'%{name}' Value Stream created"
-msgstr ""
+msgstr "'%{name}' Value Stream creat"
msgid "'%{name}' Value Stream deleted"
-msgstr ""
+msgstr "'%{name}' Value Stream șters"
msgid "'%{name}' Value Stream saved"
-msgstr ""
+msgstr "'%{name}' Value Stream salvat"
msgid "'%{source}' is not a import source"
-msgstr ""
+msgstr "'%{source}' nu este o sursă de import"
msgid "'%{template_name}' is unknown or invalid"
-msgstr ""
+msgstr "'%{template_name}' este necunoscut sau invalid"
msgid "(%d closed)"
msgid_plural "(%d closed)"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "(%d închis)"
+msgstr[1] "(%d închise)"
+msgstr[2] "(%d de închise)"
msgid "(%{mrCount} merged)"
-msgstr ""
+msgstr "(%{mrCount} îmbinate)"
msgid "(%{value}) has already been taken"
-msgstr ""
+msgstr "(%{value}) a fost deja luată"
msgid "(+%{count}&nbsp;rules)"
-msgstr ""
+msgstr "(+%{count}&nbsp;reguli)"
msgid "(Group Managed Account)"
-msgstr ""
+msgstr "(Cont gestionat de grup)"
msgid "(No changes)"
-msgstr ""
+msgstr "(Nicio schimbare)"
msgid "(UTC %{offset}) %{timezone}"
-msgstr ""
+msgstr "(UTC %{offset}) %{timezone}"
msgid "(check progress)"
-msgstr ""
+msgstr "(verificați progresul)"
msgid "(deleted)"
-msgstr ""
+msgstr "(șters)"
msgid "(expired)"
-msgstr ""
+msgstr "(expirat)"
msgid "(leave blank if you don't want to change it)"
-msgstr ""
+msgstr "(lăsați necompletat dacă nu doriți să o modificați)"
msgid "(max size 15 MB)"
-msgstr ""
+msgstr "(dimensiunea maximă 15 MB)"
msgid "(removed)"
-msgstr ""
+msgstr "(eliminat)"
msgid "(revoked)"
-msgstr ""
+msgstr "(revocat)"
msgid "(we need your current password to confirm your changes)"
-msgstr ""
+msgstr "(avem nevoie de parola curentă pentru a confirma modificările)"
msgid "* * * * *"
-msgstr ""
+msgstr "* * * * *"
msgid "+ %{amount} more"
-msgstr ""
+msgstr "+ %{amount} mai mult"
msgid "+ %{count} more"
-msgstr ""
+msgstr "+ %{count} mai mult"
msgid "+ %{moreCount} more"
-msgstr ""
+msgstr "+ %{moreCount} mai mult"
msgid "+ %{numberOfHiddenAssignees} more"
-msgstr ""
+msgstr "+ %{numberOfHiddenAssignees} în plus"
msgid "+%d more"
msgid_plural "+%d more"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "+%d mai mult"
+msgstr[1] "+%d mai multe"
+msgstr[2] "+%d mai multe"
msgid "+%{approvers} more approvers"
-msgstr ""
+msgstr "+%{approvers} mai mulți aprobatori"
msgid "+%{extra} more"
-msgstr ""
+msgstr "+%{extra} mai mult"
msgid "+%{more_assignees_count}"
-msgstr ""
+msgstr "+%{more_assignees_count}"
msgid "+%{more_assignees_count} more assignees"
-msgstr ""
+msgstr "+%{more_assignees_count} alți utilizatori asignați"
msgid "+%{more_reviewers_count}"
-msgstr ""
+msgstr "+%{more_reviewers_count}"
msgid "+%{more_reviewers_count} more reviewers"
-msgstr ""
+msgstr "+%{more_reviewers_count} mai mulți recenzori"
msgid "+%{tags} more"
-msgstr ""
+msgstr "+%{tags} mai mult"
msgid ", or "
-msgstr ""
+msgstr ", sau "
msgid "- Available to run jobs."
-msgstr ""
+msgstr "- Disponibil pentru a executa joburi."
msgid "- Event"
msgid_plural "- Events"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "- Eveniment"
+msgstr[1] "- Evenimente"
+msgstr[2] "- Evenimente"
msgid "- Not available to run jobs."
-msgstr ""
+msgstr "- Nedisponibil pentru a executa joburi."
msgid "- User"
msgid_plural "- Users"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "- Utilizator"
+msgstr[1] "- Utilizatori"
+msgstr[2] "- Utilizatori"
msgid "- of - weight completed"
-msgstr ""
+msgstr "- de - greutate realizată"
msgid "- show less"
-msgstr ""
+msgstr "- arătați mai puțin"
msgid "."
-msgstr ""
+msgstr "."
msgid "0 bytes"
-msgstr ""
+msgstr "0 octeți"
msgid "0 for unlimited, only effective with remote storage enabled."
-msgstr ""
+msgstr "0 pentru nelimitat, doar cu stocarea la distanță activată."
msgid "0t1DgySidms"
-msgstr ""
+msgstr "0t1DgySidms"
msgid "1 Day"
msgid_plural "%d Days"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "1 Zi"
+msgstr[1] "%d Zile"
+msgstr[2] "%d de Zile"
msgid "1 Issue"
msgid_plural "%d Issues"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "O Problemă"
+msgstr[1] "%d Probleme"
+msgstr[2] "%d de Probleme"
msgid "1 closed issue"
msgid_plural "%{issues} closed issues"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "1 problemă închisă"
+msgstr[1] "%{issues} probleme închise"
+msgstr[2] "%{issues} de probleme închise"
msgid "1 closed merge request"
msgid_plural "%{merge_requests} closed merge requests"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "Un merge request închis"
+msgstr[1] "%{merge_requests} merge request-uri închise"
+msgstr[2] "%{merge_requests} de merge request-uri închise"
msgid "1 day"
msgid_plural "%d days"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "O Zi"
+msgstr[1] "%d Zile"
+msgstr[2] "%d de Zile"
msgid "1 day remaining"
msgid_plural "%d days remaining"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "1 zi rămasă"
+msgstr[1] "%d zile rămase"
+msgstr[2] "%d de zile rămase"
msgid "1 day selected"
msgid_plural "%d days selected"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "1 zi selectată"
+msgstr[1] "%d zile selectate"
+msgstr[2] "%d de zile selectate"
msgid "1 deploy key"
msgid_plural "%d deploy keys"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "1 cheie de implementare"
+msgstr[1] "%d chei de implementare"
+msgstr[2] "%d de chei de implementare"
msgid "1 follower"
msgid_plural "%{count} followers"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "Un urmăritor"
+msgstr[1] "%{count} urmăritori"
+msgstr[2] "%{count} de urmăritori"
msgid "1 group"
msgid_plural "%d groups"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "1 grup"
+msgstr[1] "%d grupuri"
+msgstr[2] "%d de grupuri"
msgid "1 hour"
msgid_plural "%d hours"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "1 oră"
+msgstr[1] "%d ore"
+msgstr[2] "%d de ore"
msgid "1 issue selected"
msgid_plural "%d issues selected"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "1 problemă selectată"
+msgstr[1] "%d probleme selectate"
+msgstr[2] "%d de probleme selectate"
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgid_plural "%d merge requests selected"
+msgstr[0] "1 cerere de îmbinare selectată"
+msgstr[1] "%d cereri de îmbinare selectate"
+msgstr[2] "%d de cereri de îmbinare selectate"
msgid "1 merged merge request"
msgid_plural "%{merge_requests} merged merge requests"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "1 cerere de îmbinare îmbinată"
+msgstr[1] "%{merge_requests} cereri de îmbinare îmbinate"
+msgstr[2] "%{merge_requests} de cereri de îmbinare îmbinate"
msgid "1 minute"
msgid_plural "%d minutes"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "1 minut"
+msgstr[1] "%d minute"
+msgstr[2] "%d de minute"
msgid "1 month remaining"
msgid_plural "%d months remaining"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "1 lună rămasă"
+msgstr[1] "%d luni rămase"
+msgstr[2] "%d de luni rămase"
msgid "1 open issue"
msgid_plural "%{issues} open issues"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "1 problemă deschisă"
+msgstr[1] "%{issues} probleme deschise"
+msgstr[2] "%{issues} de probleme deschise"
msgid "1 open merge request"
msgid_plural "%{merge_requests} open merge requests"
@@ -1389,3114 +1401,3141 @@ msgstr[2] ""
msgid "1 pipeline"
msgid_plural "%d pipelines"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "1 conductă"
+msgstr[1] "%d conducte"
+msgstr[2] "%d de conducte"
msgid "1 role"
msgid_plural "%d roles"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "1 rol"
+msgstr[1] "%d roluri"
+msgstr[2] "%d de roluri"
msgid "1 user"
msgid_plural "%{num} users"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "1 utilizator"
+msgstr[1] "%{num} utilizatori"
+msgstr[2] "%{num} de utilizatori"
msgid "1 week remaining"
msgid_plural "%d weeks remaining"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "1 săptămână rămasă"
+msgstr[1] "%d săptămâni rămase"
+msgstr[2] "%d de săptămâni rămase"
msgid "1 year remaining"
msgid_plural "%d years remaining"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "1 an rămas"
+msgstr[1] "%d ani rămași"
+msgstr[2] "%d de ani rămași"
msgid "1-9 contributions"
-msgstr ""
+msgstr "1-9 contribuții"
msgid "10-19 contributions"
-msgstr ""
+msgstr "10-19 contribuții"
msgid "1000+"
-msgstr ""
+msgstr "1000+"
msgid "1st contribution!"
-msgstr ""
+msgstr "Prima contribuție!"
msgid "20-29 contributions"
-msgstr ""
+msgstr "20-29 contribuții"
msgid "2FA"
-msgstr ""
+msgstr "2FA"
msgid "2FADevice|Registered On"
-msgstr ""
+msgstr "ÃŽnregistrat pe"
msgid "3 days"
-msgstr ""
+msgstr "3 zile"
msgid "3 hours"
-msgstr ""
+msgstr "3 ore"
msgid "30 days"
-msgstr ""
+msgstr "30 zile"
msgid "30 minutes"
-msgstr ""
+msgstr "30 de minute"
msgid "30+ contributions"
-msgstr ""
+msgstr "30+ contribuții"
msgid "403|Please contact your GitLab administrator to get permission."
-msgstr ""
+msgstr "Contactați administratorul dvs. GitLab pentru a obține permisiunea."
msgid "403|You don't have the permission to access this page."
-msgstr ""
+msgstr "Nu aveți permisiunea de a accesa această pagină."
msgid "404|Make sure the address is correct and the page hasn't moved."
-msgstr ""
+msgstr "Asigurați-vă că adresa este corectă și pagina nu s-a mutat."
msgid "404|Page Not Found"
-msgstr ""
+msgstr "Pagină inexistentă"
msgid "404|Please contact your GitLab administrator if you think this is a mistake."
-msgstr ""
+msgstr "Contactați administratorul dvs. GitLab dacă credeți că este o greșeală."
msgid "7 days"
-msgstr ""
+msgstr "7 zile"
msgid "8 hours"
-msgstr ""
+msgstr "8 ore"
msgid ":%{startLine} to %{endLine}"
-msgstr ""
+msgstr ":%{startLine} la %{endLine}"
msgid "A %{incident_docs_start}modified issue%{incident_docs_end} to guide the resolution of incidents."
-msgstr ""
+msgstr "O %{incident_docs_start}problemă modificată%{incident_docs_end} pentru a ghida rezolvarea incidentelor."
msgid "A .NET Core console application template, customizable for any .NET Core project"
-msgstr ""
+msgstr "Un șablon de aplicație consolă .NET Core, personalizabil pentru orice proiect .NET Core"
msgid "A CI/CD pipeline must run and be successful before merge."
-msgstr ""
+msgstr "O conductă CI / CD trebuie să ruleze și să aibă succes înainte de îmbinare."
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "Un site GitBook care folosește Netlify pentru CI/CD în loc de GitLab, dar cu toate celelalte funcții excelente ale GitLab."
msgid "A Gitpod configured Webapplication in Spring and Java"
-msgstr ""
+msgstr "O aplicație web configurată cu Gitpod în Spring și Java"
msgid "A Hexo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "Un site Hexo care folosește Netlify pentru CI/CD în loc de GitLab, dar tot cu toate celelalte funcții excelente ale GitLab"
msgid "A Hugo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "Un site Hugo care folosește Netlify pentru CI/CD în loc de GitLab, dar tot cu toate celelalte funcții excelente ale GitLab"
msgid "A Jekyll site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "Un site Jekyll care folosește Netlify pentru CI / CD în loc de GitLab, dar tot cu toate celelalte funcții grozave ale GitLab"
msgid "A Let's Encrypt SSL certificate can not be obtained until your domain is verified."
-msgstr ""
+msgstr "Un certificat SSL Let's Encrypt nu poate fi obținut până când domeniul dvs. nu este verificat."
msgid "A Metrics Dashboard menu item appears in the Monitoring section of the Admin Area."
-msgstr ""
+msgstr "Un obiect de meniu Metrics Dashboard apare în secția de Monitorizare a Area Admin."
msgid "A basic page and serverless function that uses AWS Lambda, AWS API Gateway, and GitLab Pages"
-msgstr ""
+msgstr "O pagină de bază și funcție serverless care utilizează AWS Lambda, AWS API Gateway și GitLab Pages"
msgid "A basic template for developing Linux programs using Kotlin Native"
-msgstr ""
+msgstr "Un șablon de bază pentru dezvoltarea de programe Linux folosind Kotlin Native"
msgid "A complete DevOps platform"
-msgstr ""
+msgstr "O platformă DevOps completă"
msgid "A default branch cannot be chosen for an empty project."
-msgstr ""
+msgstr "O ramură implicită nu poate fi aleasă pentru un proiect gol."
msgid "A deleted user"
-msgstr ""
+msgstr "Un utilizator șters"
msgid "A description is required"
-msgstr ""
+msgstr "Descrierea este necesară"
msgid "A different reason"
-msgstr ""
+msgstr "Un motiv diferit"
msgid "A file has been changed."
-msgstr ""
+msgstr "Un fișier a fost modificat."
msgid "A file was not found."
-msgstr ""
+msgstr "Un fișier nu a fost găsit."
msgid "A file with '%{file_name}' already exists in %{branch} branch"
-msgstr ""
+msgstr "Un fișier cu '%{file_name}' există deja în ramura %{branch}"
msgid "A group is a collection of several projects"
-msgstr ""
+msgstr "Un grup este o colecție de mai multe proiecte"
msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
-msgstr ""
+msgstr "Un grup reprezintă organizația ta în GitLab. Grupurile vă permit să gestionați utilizatorii și să colaborați în cadrul mai multor proiecte."
msgid "A job artifact is an archive of files and directories saved by a job when it finishes."
-msgstr ""
+msgstr "Artefactul unei lucrări este o arhivă de fișiere și directoare salvate de un job când se termină."
msgid "A limit of %{ci_project_subscriptions_limit} subscriptions to or from a project applies."
-msgstr ""
+msgstr "Se aplică o limită de %{ci_project_subscriptions_limit} abonamente la sau de la un proiect."
msgid "A management, operational, or technical control (that is, safeguard or countermeasure) employed by an organization that provides equivalent or comparable protection for an information system."
-msgstr ""
+msgstr "Un control managerial, operațional sau tehnic (adică o măsură de protecție sau o contramăsură) utilizat de o organizație care asigură o protecție echivalentă sau comparabilă pentru un sistem informatic."
msgid "A member of the abuse team will review your report as soon as possible."
-msgstr ""
+msgstr "Un membru al echipei de combatere a abuzurilor va analiza raportul dumneavoastră cât mai curând posibil."
msgid "A merge request hasn't yet been merged"
-msgstr ""
+msgstr "O cerere de îmbinare nu a fost încă îmbinată"
msgid "A new Auto DevOps pipeline has been created, go to %{pipelines_link_start}Pipelines page%{pipelines_link_end} for details"
-msgstr ""
+msgstr "O nouă conductă Auto DevOps a fost creată, mergeți pe %{pipelines_link_start}pagina Conducte%{pipelines_link_end} pentru detalii."
msgid "A new Release %{tag} for %{name} was published. Visit the %{release_link_start}Releases page%{release_link_end} to read more about it."
-msgstr ""
+msgstr "A fost publicată o nouă versiune %{tag} pentru %{name}. Vizitați pagina %{release_link_start}pagina Lansări%{release_link_end} pentru a citi mai multe despre aceasta."
msgid "A new Release %{tag} for %{name} was published. Visit the Releases page to read more about it:"
-msgstr ""
+msgstr "A fost publicată o nouă versiune %{tag} pentru %{name}. Vizitați pagina Lansări pentru a citi mai multe despre aceasta:"
msgid "A new branch will be created in your fork and a new merge request will be started."
-msgstr ""
+msgstr "O nouă ramură va fi creată în bifurcația dvs. și va fi inițiată o nouă cerere de îmbinare."
msgid "A new impersonation token has been created."
-msgstr ""
+msgstr "A fost creat un nou token de impersonare."
msgid "A non-confidential epic cannot be assigned to a confidential parent epic"
-msgstr ""
+msgstr "O epică neconfidențială nu poate fi atribuită unei epice părinte confidențială"
msgid "A plain HTML site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "Un site HTML simplu care folosește Netlify pentru CI / CD în loc de GitLab, dar cu toate celelalte funcții GitLab."
msgid "A plain-text response to show to clients that hit the rate limit."
-msgstr ""
+msgstr "Un răspuns în text simplu care se afișează clienților care au atins limita frecvenței."
msgid "A platform value can be web, mob or app."
-msgstr ""
+msgstr "O valoare a platformei poate fi web, mob sau aplicație."
msgid "A project boilerplate for Salesforce App development with Salesforce Developer tools"
-msgstr ""
+msgstr "Un cazan proiect pentru o dezvoltarea unei aplicații Salesforce cu unelte de dezvoltatori Salesforce"
msgid "A project containing issues for each audit inquiry in the HIPAA Audit Protocol published by the U.S. Department of Health & Human Services"
-msgstr ""
+msgstr "Un proiect care să conțină aspecte pentru fiecare anchetă de audit din Protocolul de audit HIPAA publicat de Departamentul de Sănătate și Servicii Umane al SUA."
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "Numele de repozitoriu al unui proiect îi definește URL-ul (cel pe care îl folosiți pentru a accesa proiectul via un browser) și locul său pe discul de fișier unde este instalat GitLab. %{link_start}Aflați mai multe.%{link_end}"
msgid "A ready-to-go template for use with Android apps"
-msgstr ""
+msgstr "Un șablon gata de utilizare pentru utilizare cu aplicații Android"
msgid "A ready-to-go template for use with iOS Swift apps"
-msgstr ""
+msgstr "Un șablon gata de utilizare pentru utilizare cu aplicații iOS Swift"
msgid "A rebase is already in progress."
-msgstr ""
+msgstr "O rebazare este deja în curs de desfășurare."
msgid "A sign-in to your account has been made from the following IP address: %{ip}"
-msgstr ""
+msgstr "A fost efectuată o autentificare în contul dvs. de la următoarea adresă IP: %{ip}"
msgid "A string appended to the project path to form the Service Desk email address."
-msgstr ""
+msgstr "Un șir de caractere adăugat la traiectoria proiectului pentru a forma adresa de e-mail a Biroului de Asistență."
msgid "A title is required"
-msgstr ""
+msgstr "Este necesar un titlu"
msgid "A user with write access to the source branch selected this option"
-msgstr ""
+msgstr "Un utilizator cu acces de scriere la ramura sursă a selectat această opțiune"
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
-msgstr ""
+msgstr "ACȚIUNE NECESARĂ: Ceva nu a mers bine în timpul obținerii certificatului Let's Encrypt pentru domeniul GitLab Pages '%{domain}'"
msgid "API"
-msgstr ""
+msgstr "API"
msgid "API Fuzzing"
-msgstr ""
+msgstr "API Fuzzing"
msgid "API Fuzzing Configuration"
-msgstr ""
+msgstr "Configurare API Fuzzing"
msgid "API Help"
-msgstr ""
+msgstr "Ajutor API"
msgid "API Token"
-msgstr ""
+msgstr "Token API"
msgid "API key"
-msgstr ""
+msgstr "Cheie API"
msgid "API?"
-msgstr ""
+msgstr "API?"
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
-msgstr ""
+msgstr "API Fuzzing Configuration"
msgid "APIFuzzing|Base URL of API testing target. For example, http://www.example.com."
-msgstr ""
+msgstr "Adresa URL de bază a țintei de testare API. De exemplu, http://www.example.com."
msgid "APIFuzzing|Choose a method"
-msgstr ""
+msgstr "Alegeți o metodă"
msgid "APIFuzzing|Choose a profile"
-msgstr ""
+msgstr "Alegeți un profil"
msgid "APIFuzzing|Code snippet could not be generated. Try again later."
-msgstr ""
+msgstr "Fragmentul de cod nu a putut fi generat. Încercați mai târziu."
msgid "APIFuzzing|Configure HTTP basic authentication values. Other authentication methods are supported. %{linkStart}Learn more%{linkEnd}."
-msgstr ""
+msgstr "Configurați valorile de autentificare de bază HTTP. Sunt acceptate și alte metode de autentificare. %{linkStart}Aflați mai multe%{linkEnd}."
msgid "APIFuzzing|Customize common API fuzzing settings to suit your requirements. For details of more advanced configuration options, see the %{docsLinkStart}GitLab API Fuzzing documentation%{docsLinkEnd}."
-msgstr ""
+msgstr "Personalizați setările comune de fuzzing API pentru a se potrivi cerințelor dumneavoastră. Pentru detalii despre opțiunile de configurare mai avansate, consultați %{docsLinkStart}documentația GitLab API Fuzzing%{docsLinkEnd}."
msgid "APIFuzzing|Enable authentication"
-msgstr ""
+msgstr "Activați autentificarea"
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
-msgstr ""
+msgstr "Calea fișierului sau adresa URL către API-urile de testat. De exemplu, folder/example_fuzz.har. Fișierele HAR pot conține informații sensibile, cum ar fi token-uri de autentificare, chei API și cookie-uri de sesiune. Vă recomandăm să examinați conținutul fișierelor HAR înainte de a le adăuga la un depozit."
msgid "APIFuzzing|File path or URL to OpenAPI specification. For example, folder/openapi.json or http://www.example.com/openapi.json."
-msgstr ""
+msgstr "Calea fișierului sau adresa URL către specificația OpenAPI. De exemplu, folder/openapi.json sau http://www.example.com/openapi.json."
msgid "APIFuzzing|File path or URL to requests to be tested. For example, folder/example.postman_collection.json."
-msgstr ""
+msgstr "Calea fișierului sau adresa URL către solicitările de testat. De exemplu, folder/example.postman_collection.json."
msgid "APIFuzzing|Generate code snippet"
-msgstr ""
+msgstr "Generați un fragment de cod"
msgid "APIFuzzing|Make sure your credentials are secured"
-msgstr ""
+msgstr "Asigurați-vă că acreditările dvs. sunt securizate"
msgid "APIFuzzing|Password for basic authentication"
-msgstr ""
+msgstr "Parolă pentru autentificare de bază"
msgid "APIFuzzing|Predefined profiles"
-msgstr ""
+msgstr "Profile predefinite"
msgid "APIFuzzing|Scan mode"
-msgstr ""
+msgstr "Mod scanare"
msgid "APIFuzzing|Scan profile"
-msgstr ""
+msgstr "Profil scanare"
msgid "APIFuzzing|Show code snippet for the profile"
-msgstr ""
+msgstr "Afișați fragmentul de cod pentru profil"
msgid "APIFuzzing|Target URL"
-msgstr ""
+msgstr "URL țintă"
msgid "APIFuzzing|There are three ways to perform scans."
-msgstr ""
+msgstr "Există trei moduri de a efectua scanări."
msgid "APIFuzzing|Tip: Insert the following variables anywhere below stages and include"
-msgstr ""
+msgstr "Sfat: Introduceți următoarele variabile oriunde sub etape și includeți"
msgid "APIFuzzing|Tip: Insert this part below all include"
-msgstr ""
+msgstr "Sfat: Inserați această parte sub toate includerile"
msgid "APIFuzzing|Tip: Insert this part below all stages"
-msgstr ""
+msgstr "Sfat: Inserați această parte sub toate stagiile"
msgid "APIFuzzing|To prevent a security leak, authentication info must be added as a %{ciVariablesLinkStart}CI variable%{ciVariablesLinkEnd}. A user with maintainer access rights can manage CI variables in the %{ciSettingsLinkStart}Settings%{ciSettingsLinkEnd} area. We detected that you are not a maintainer. Commit your changes and assign them to a maintainer to update the credentials before merging."
-msgstr ""
+msgstr "Pentru a preveni o breșă de securitate, informațiile de autentificare trebuie adăugate ca o %{ciVariablesLinkStart}variabilă CI%{ciVariablesLinkEnd}. Un utilizator cu drepturi de acces de tip întreținător poate gestiona variabilele CI în zona %{ciSettingsLinkStart}Setări%{ciSettingsLinkEnd}. Am detectat că nu sunteți un întreținător. Confirmați modificările și atribuiți-le unui întreținător pentru a actualiza acreditările înainte de îmbinare."
msgid "APIFuzzing|To prevent a security leak, authentication info must be added as a %{ciVariablesLinkStart}CI variable%{ciVariablesLinkEnd}. As a user with maintainer access rights, you can manage CI variables in the %{ciSettingsLinkStart}Settings%{ciSettingsLinkEnd} area."
-msgstr ""
+msgstr "Pentru a preveni o breșă de securitate, informațiile de autentificare trebuie adăugate ca o %{ciVariablesLinkStart}variabilă CI%{ciVariablesLinkEnd}. În calitate de utilizator cu drepturi de acces de tip întreținător, puteți gestiona variabilele CI în zona %{ciSettingsLinkStart}Setări%{ciSettingsLinkEnd}."
msgid "APIFuzzing|Use this tool to generate API fuzzing configuration YAML to copy into your .gitlab-ci.yml file. This tool does not reflect or update your .gitlab-ci.yml file automatically."
-msgstr ""
+msgstr "Utilizați acest instrument pentru a genera configurația YAML de API fuzzing pentru a o copia în fișierul .gitlab-ci.yml. Acest instrument nu reflectă sau actualizează automat fișierul .gitlab-ci.yml."
msgid "APIFuzzing|Username for basic authentication"
-msgstr ""
+msgstr "Nume utilizator pentru autentificare de bază"
msgid "APIFuzzing|You may need a maintainer's help to secure your credentials."
-msgstr ""
+msgstr "Este posibil să aveți nevoie de ajutorul unui întreținător pentru a vă securiza acreditările."
msgid "APIFuzzing|folder/example.postman_collection.json"
-msgstr ""
+msgstr "folder/example.postman_collection.json"
msgid "APIFuzzing|folder/example_fuzz.har"
-msgstr ""
+msgstr "folder/example_fuzz.har"
msgid "APIFuzzing|folder/openapi.json"
-msgstr ""
+msgstr "folder/openapi.json"
msgid "AWS Access Key"
-msgstr ""
+msgstr "Cheia de acces AWS"
msgid "AWS Access Key. Only required if not using role instance credentials"
-msgstr ""
+msgstr "Cheia de acces AWS. Necesară numai dacă nu se utilizează acreditările instanței de rol"
msgid "AWS Secret Access Key"
-msgstr ""
+msgstr "Cheia secretă de acces AWS"
msgid "AWS Secret Access Key. Only required if not using role instance credentials"
-msgstr ""
+msgstr "Cheia de acces secret AWS. Necesară numai dacă nu se utilizează acreditările instanței de rol"
msgid "AWS service error: %{error}"
-msgstr ""
+msgstr "Eroare de serviciu AWS: %{error}"
msgid "Abort"
-msgstr ""
+msgstr "Renunțați"
msgid "About GitLab"
-msgstr ""
+msgstr "Despre GitLab"
msgid "About auto deploy"
-msgstr ""
+msgstr "Despre implementarea automată"
msgid "About this feature"
-msgstr ""
+msgstr "Despre această funcție"
msgid "Abuse Reports"
-msgstr ""
+msgstr "Rapoarte Abuz"
msgid "Abuse reports"
-msgstr ""
+msgstr "Rapoarte abuz"
msgid "Abuse reports notification email"
-msgstr ""
+msgstr "Notificare e-mail rapoarte abuz"
msgid "Abuse reports will be sent to this address if it is set. Abuse reports are always available in the admin area."
-msgstr ""
+msgstr "Rapoartele de abuz vor fi trimise la această adresă, dacă aceasta este setată. Rapoartele de abuzuri sunt întotdeauna disponibile în zona de administrare."
msgid "Accept invitation"
-msgstr ""
+msgstr "Acceptați invitația"
msgid "Accept terms"
-msgstr ""
+msgstr "Acceptați termenii"
msgid "Acceptable for use in this project"
-msgstr ""
+msgstr "Acceptabil pentru utilizare în acest proiect"
msgid "Access Git repositories or the API."
-msgstr ""
+msgstr "Accesați repozitorii Git sau API-ul."
msgid "Access Tokens"
-msgstr ""
+msgstr "Token-uri de acces"
msgid "Access denied for your LDAP account."
-msgstr ""
+msgstr "Accesul a fost refuzat pentru contul dvs. LDAP."
msgid "Access denied! Please verify you can add deploy keys to this repository."
-msgstr ""
+msgstr "Acces interzis! Verificați dacă puteți adăuga chei de implementare în acest repozitoriu."
msgid "Access denied: %{error}"
-msgstr ""
+msgstr "Acces interzis: %{error}"
msgid "Access expiration date"
-msgstr ""
+msgstr "Data de expirare a accesului"
msgid "Access expires"
-msgstr ""
+msgstr "Accesul expiră"
msgid "Access forbidden. Check your access level."
-msgstr ""
+msgstr "Accesul interzis. Verificați nivelul de acces."
msgid "Access granted"
-msgstr ""
+msgstr "Acces acordat"
msgid "Access requests"
-msgstr ""
+msgstr "Cereri de acces"
msgid "Access to '%{classification_label}' not allowed"
-msgstr ""
+msgstr "Accesul la \"%{classification_label}\" nu este permis"
msgid "AccessDropdown|Deploy Keys"
-msgstr ""
+msgstr "Chei de implementare"
msgid "AccessDropdown|Groups"
-msgstr ""
+msgstr "Grupuri"
msgid "AccessDropdown|Roles"
-msgstr ""
+msgstr "Roluri"
msgid "AccessDropdown|Users"
-msgstr ""
+msgstr "Utilizatori"
msgid "AccessTokens|Access Tokens"
-msgstr ""
+msgstr "Token-uri de access"
msgid "AccessTokens|Are you sure?"
-msgstr ""
+msgstr "Sunteți sigur?"
msgid "AccessTokens|Are you sure? Any RSS or calendar URLs currently in use will stop working."
-msgstr ""
+msgstr "Sunteți sigur? Orice URL RSS sau calendar utilizat în prezent nu va mai funcționa."
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
-msgstr ""
+msgstr "Sunteți sigur? Orice adresă de e-mail folosită în prezent nu va mai funcționa."
msgid "AccessTokens|Created"
-msgstr ""
+msgstr "Create"
msgid "AccessTokens|Feed token"
-msgstr ""
+msgstr "Token flux"
msgid "AccessTokens|Incoming email token"
-msgstr ""
+msgstr "Token e-mail primit"
msgid "AccessTokens|It cannot be used to access any other data."
-msgstr ""
+msgstr "Nu poate fi utilizat pentru a accesa alte date."
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
-msgstr ""
+msgstr "Păstrați acest token secret. Oricine îl are poate accesa obiectele statice ale depozitului ca și cum ar fi în locul dvs. Dacă se întâmplă asta vreodată, %{reset_link_start}resetați acest token%{reset_link_end}."
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
-msgstr ""
+msgstr "Păstrați acest simbol secret. Oricine îl are poate crea probleme ca și cum ar fi în locul dvs. Dacă se întâmplă acest lucru, %{link_reset_it}."
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
-msgstr ""
+msgstr "Păstrați acest simbol secret. Oricine îl are poate citi fluxurile RSS de activități și de probleme sau fluxul de calendar ca și cum ar fi în locul dvs. Dacă se întâmplă acest lucru, %{link_reset_it}."
msgid "AccessTokens|Personal Access Tokens"
-msgstr ""
+msgstr "Token-uri de acces personal"
msgid "AccessTokens|Static object token"
-msgstr ""
+msgstr "Token obiect static"
msgid "AccessTokens|They are the only accepted password when you have Two-Factor Authentication (2FA) enabled."
-msgstr ""
+msgstr "Sunt singurele parole acceptate când aveți activată Autentificarea în doi pași."
msgid "AccessTokens|You can also use personal access tokens to authenticate against Git over HTTP."
-msgstr ""
+msgstr "De asemenea, puteți folosi token-uri de acces personal pentru a vă autentifica la Git prin HTTP."
msgid "AccessTokens|You can generate a personal access token for each application you use that needs access to the GitLab API."
-msgstr ""
+msgstr "Puteți genera un token de acces personal pentru fiecare aplicație pe care o folosiți și necesită acces la GitLab API."
msgid "AccessTokens|Your feed token authenticates you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar. It is visible in those feed URLs."
-msgstr ""
+msgstr "Token-urile de flux vă autentifică atunci când cititorul RSS încarcă un flux RSS personalizat sau când aplicația de calendar încarcă un calendar personalizat. Acesta este vizibil în aceste URL-uri de flux."
msgid "AccessTokens|Your incoming email token authenticates you when you create a new issue by email, and is included in your personal project-specific email addresses."
-msgstr ""
+msgstr "Tokenul dvs. de e-mail primit vă autentifică atunci când creați o nouă problemă prin e-mail și este inclus în adresele dvs. personale de e-mail specifice proiectului."
msgid "AccessTokens|Your static object token authenticates you when repository static objects (such as archives or blobs) are served from an external storage."
-msgstr ""
+msgstr "Tokenul dvs. pentru obiecte statice vă autentifică atunci când obiectele statice din depozit (cum ar fi arhivele sau blob-urile) sunt servite dintr-un depozit extern."
msgid "AccessTokens|reset this token"
-msgstr ""
+msgstr "resetează acest token"
msgid "AccessibilityReport|Learn more"
-msgstr ""
+msgstr "Aflați mai multe"
msgid "AccessibilityReport|Message: %{message}"
-msgstr ""
+msgstr "Mesaj: %{message}"
msgid "AccessibilityReport|New"
-msgstr ""
+msgstr "Nou"
msgid "AccessibilityReport|The accessibility scanning found an error of the following type: %{code}"
-msgstr ""
+msgstr "Scanarea de accesibilitate a găsit o eroare de tipul următor: %{code}"
msgid "Account"
-msgstr ""
+msgstr "Cont"
msgid "Account ID"
-msgstr ""
+msgstr "ID cont"
msgid "Account and limit"
-msgstr ""
+msgstr "Contul și limita"
msgid "Account:"
-msgstr ""
+msgstr "Cont:"
msgid "Account: %{account}"
-msgstr ""
+msgstr "Cont: %{account}"
msgid "Action"
-msgstr ""
+msgstr "Acțiune"
msgid "Action to take when receiving an alert. %{docsLink}"
-msgstr ""
+msgstr "Acțiune de întreprins când primiți o alertă. %{docsLink}"
msgid "Actions"
-msgstr ""
+msgstr "Acțiuni"
msgid "Activate Service Desk"
-msgstr ""
+msgstr "Activați Biroul de Servicii"
msgid "Active"
-msgstr ""
+msgstr "Activ"
msgid "Active %{type} (%{token_length})"
-msgstr ""
+msgstr "Activ %{type} (%{token_length})"
msgid "Active Sessions"
-msgstr ""
+msgstr "Sesiuni active"
msgid "Activity"
-msgstr ""
+msgstr "Activitate"
msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
-msgstr ""
+msgstr "A apărut o eroare în timpul recuperării activității. Reîncărcați pagina pentru a încerca din nou."
msgid "Add"
-msgstr ""
+msgstr "Adaugă"
msgid "Add \"%{value}\""
-msgstr ""
+msgstr "Adaugă \"%{value}\""
msgid "Add %{linkStart}assets%{linkEnd} to your Release. GitLab automatically includes read-only assets, like source code and release evidence."
-msgstr ""
+msgstr "Adăugați %{linkStart}resurse%{linkEnd} la lansarea dumneavoastră. GitLab include în mod automat resurse doar-citire, ca și codul sursă și evidența lansării."
msgid "Add CHANGELOG"
-msgstr ""
+msgstr "Adăugați CHANGELOG"
msgid "Add CONTRIBUTING"
-msgstr ""
+msgstr "Adăugați CONTRIBUTING"
msgid "Add GitLab to Slack"
-msgstr ""
+msgstr "Adaugă GitLab la Slack"
msgid "Add Jaeger URL"
-msgstr ""
+msgstr "Adăugați URL Jaeger"
msgid "Add Kubernetes cluster"
-msgstr ""
+msgstr "Adăugați cluster Kubernetes"
msgid "Add LICENSE"
-msgstr ""
+msgstr "Adăugați LICENȚĂ"
msgid "Add New Node"
-msgstr ""
+msgstr "Adăugați un nou nod"
msgid "Add README"
-msgstr ""
+msgstr "Adăugați README"
msgid "Add Zoom meeting"
-msgstr ""
+msgstr "Adăugați o întâlnire Zoom"
msgid "Add a %{type}"
-msgstr ""
+msgstr "Adăugați un %{type}"
msgid "Add a GPG key"
-msgstr ""
+msgstr "Adăugați o cheie GPG"
msgid "Add a Jaeger URL to replace this page with a link to your Jaeger server. You first need to %{link_start_tag}install Jaeger%{link_end_tag}."
-msgstr ""
+msgstr "Adăugați un URL Jaeger pentru a înlocui această pagină cu un link către serverul Jaeger. Mai întâi trebuie să %{link_start_tag}instalați Jaeger%{link_end_tag}."
msgid "Add a Terms of Service agreement and Privacy Policy for users of this GitLab instance."
-msgstr ""
+msgstr "Adăugați un contract de Termeni și servicii și Politică de confidențialitate pentru utilizatorii acestei instanțe de GitLab."
msgid "Add a bullet list"
-msgstr ""
+msgstr "Adăugați o listă de puncte"
msgid "Add a collapsible section"
-msgstr ""
+msgstr "Adăugați o secțiune pliabilă"
msgid "Add a comment to this line"
-msgstr ""
+msgstr "Adăugați un comentariu la această linie"
msgid "Add a comment to this line or drag for multiple lines"
-msgstr ""
+msgstr "Adăugați un comentariu la această linie sau trageți pentru mai multe linii"
msgid "Add a custom message with details about the instance's shared runners. The message is visible in group and project CI/CD settings, in the Runners section. Markdown is supported."
-msgstr ""
+msgstr "Adăugați un mesaj personalizat cu detalii despre rulourile partajate ale instanței. Mesajul este vizibil în setările CI / CD ale grupului și proiectului, în secțiunea Runners. Se acceptă Markdown."
msgid "Add a general comment to this %{noteableDisplayName}."
-msgstr ""
+msgstr "Adăugați un comentariu general la acest %{noteableDisplayName}."
msgid "Add a general comment to this %{noteable_name}."
-msgstr ""
+msgstr "Adăugați un comentariu general la acest %{noteable_name}."
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
-msgstr ""
+msgstr "Adăugați o pagină de pornire în wiki-ul dvs care conține informații despre proiectul dvs, iar GitLab îl va afișa aici în locul acestui mesaj."
msgid "Add a horizontal rule"
-msgstr ""
+msgstr "Adăugați o regulă orizontală"
msgid "Add a line"
-msgstr ""
+msgstr "Adăugați o linie"
msgid "Add a link"
-msgstr ""
+msgstr "Adăugați un link"
msgid "Add a link to Grafana"
-msgstr ""
+msgstr "Adăugați un link către Grafana"
msgid "Add a new issue"
-msgstr ""
+msgstr "Adăugați o nouă problemă"
msgid "Add a numbered list"
-msgstr ""
+msgstr "Adăugați o listă numerotată"
msgid "Add a related issue"
-msgstr ""
+msgstr "Adăugați o problemă conexă"
msgid "Add a table"
-msgstr ""
+msgstr "Adăugați un tabel"
msgid "Add a task list"
-msgstr ""
+msgstr "Adăugați o listă de sarcini"
msgid "Add a to do"
-msgstr ""
+msgstr "Adăugați o acțiune de făcut"
msgid "Add an SSH key"
-msgstr ""
+msgstr "Adăugați o cheie SSH"
msgid "Add an existing issue"
-msgstr ""
+msgstr "Adăugați o problemă existentă"
msgid "Add an impersonation token"
-msgstr ""
+msgstr "Adăugați un token de impersonare"
msgid "Add another link"
-msgstr ""
+msgstr "Adăugați un alt link"
msgid "Add approval rule"
-msgstr ""
+msgstr "Adăugați o regulă de aprobare"
msgid "Add approvers"
-msgstr ""
+msgstr "Adăugați aprobatori"
msgid "Add bold text"
-msgstr ""
+msgstr "Adăugați text bold"
msgid "Add broadcast message"
-msgstr ""
+msgstr "Adăugați un mesaj de difuzare"
msgid "Add child epic to an epic"
-msgstr ""
+msgstr "Adaugați o epică copil la o epică"
msgid "Add comment now"
-msgstr ""
+msgstr "Adăugați un comentariu acum"
msgid "Add comment to design"
-msgstr ""
+msgstr "Adăugați un comentariu la design"
msgid "Add commit messages as comments to Asana tasks. %{docs_link}"
-msgstr ""
+msgstr "Adăugați mesaje de confirmare ca comentarii la sarcinile Asana. %{docs_link}"
msgid "Add commit messages as comments to Pivotal Tracker stories. %{docs_link}"
-msgstr ""
+msgstr "Adăugați mesaje de comitere ca și comentarii la povești Pivotal Tracker. %{docs_link}"
msgid "Add deploy freeze"
-msgstr ""
+msgstr "Adăugați înghețarea implementării"
msgid "Add deploy keys to grant read/write access to this repository. %{link_start}What are deploy keys?%{link_end}"
-msgstr ""
+msgstr "Adăugați chei de implementare pentru a acorda acces de citire/scriere la acest repozitoriu. %{link_start}Ce sunt cheile de implementare?%{link_end}"
msgid "Add domain"
-msgstr ""
+msgstr "Adăugați domeniu"
msgid "Add email address"
-msgstr ""
+msgstr "Adăugați adresă e-mail"
msgid "Add email participant(s)"
-msgstr ""
+msgstr "Adăugați participant(ți) la e-mail"
msgid "Add environment"
-msgstr ""
+msgstr "Adăugați mediu"
msgid "Add existing confidential %{issuableType}"
-msgstr ""
+msgstr "Adăugați confidențial existent %{issuableType}"
msgid "Add header and footer to emails. Please note that color settings will only be applied within the application interface"
-msgstr ""
+msgstr "Adăugați antetul și subsolul la e-mailuri. Rețineți că setările de culoare vor fi aplicate numai în interfața aplicației"
msgid "Add image comment"
-msgstr ""
+msgstr "Adauga comentariu la imagine"
msgid "Add italic text"
-msgstr ""
+msgstr "Adăugați text italic"
msgid "Add key"
-msgstr ""
+msgstr "Adăugați cheie"
msgid "Add label(s)"
-msgstr ""
+msgstr "Adăugați etichetă(e)"
msgid "Add list"
-msgstr ""
+msgstr "Adăugați listă"
msgid "Add new application"
-msgstr ""
+msgstr "Adăugați o aplicație nouă"
msgid "Add new directory"
-msgstr ""
+msgstr "Adăugați un director nou"
msgid "Add or remove previously merged commits"
-msgstr ""
+msgstr "Adăugați sau eliminați comiteri îmbinate anterior"
msgid "Add or subtract spent time"
-msgstr ""
+msgstr "Adăugați sau scădeți timpul consumat"
msgid "Add previously merged commits"
-msgstr ""
+msgstr "Adăugați commit-uri îmbinate anterior"
msgid "Add project"
-msgstr ""
+msgstr "Adăugare proiect"
msgid "Add projects"
-msgstr ""
+msgstr "Adăugare proiecte"
msgid "Add reaction"
-msgstr ""
+msgstr "Adăugați reacție"
msgid "Add request manually"
-msgstr ""
+msgstr "Adăugați cererea manual"
msgid "Add strikethrough text"
-msgstr ""
+msgstr "Adăugați text strikethrough"
msgid "Add suggestion to batch"
-msgstr ""
+msgstr "Adăugați o sugestie la lot"
msgid "Add system hook"
-msgstr ""
+msgstr "Adăugare hook sistem"
msgid "Add text to the sign-in page. Markdown enabled."
-msgstr ""
+msgstr "Adăugați text paginii de autentificare. Markdown activat."
msgid "Add to Slack"
-msgstr ""
+msgstr "Adăugare la Slack"
msgid "Add to board"
-msgstr ""
+msgstr "Adăugare la bord"
msgid "Add to epic"
-msgstr ""
+msgstr "Adăugați la epic"
msgid "Add to merge train"
-msgstr ""
+msgstr "Adăugare la merge train"
msgid "Add to merge train when pipeline succeeds"
-msgstr ""
+msgstr "Adăugare la merge train când conducta reușește"
msgid "Add to review"
-msgstr ""
+msgstr "Adăugați pentru revizuire"
msgid "Add to tree"
-msgstr ""
+msgstr "Adăugare la arbore"
msgid "Add trigger"
-msgstr ""
+msgstr "Adăugare declanșator"
msgid "Add user(s) to the group:"
-msgstr ""
+msgstr "Adăugați utilizator(i) la grup:"
msgid "Add users to group"
-msgstr ""
+msgstr "Adăugați utilizatorii în grup"
msgid "Add variable"
-msgstr ""
+msgstr "Adăugare variabilă"
msgid "Add webhook"
-msgstr ""
+msgstr "Adăugare webhook"
msgid "Add/remove"
-msgstr ""
+msgstr "Adăugare/eliminare"
msgid "AddContextCommits|Add previously merged commits"
-msgstr ""
+msgstr "Adăugați commit-uri îmbinate anterior"
msgid "AddContextCommits|Add/remove"
-msgstr ""
+msgstr "Adăugare / eliminare"
msgid "AddMember|Emails cannot be blank"
-msgstr ""
+msgstr "E-mail-urile nu pot fi goale"
msgid "AddMember|Invite email is invalid"
-msgstr ""
+msgstr "E-mailul de invitație nu este valid"
msgid "AddMember|Invite limit of %{daily_invites} per day exceeded"
-msgstr ""
+msgstr "Limita de invitații de %{daily_invites} pe zi a fost depășită"
msgid "AddMember|No invite source provided."
-msgstr ""
+msgstr "Nu a fost furnizată nicio sursă de invitație."
msgid "AddMember|No users specified."
-msgstr ""
+msgstr "Nu au fost specificați utilizatori."
msgid "AddMember|Too many users specified (limit is %{user_limit})"
-msgstr ""
+msgstr "Prea mulți utilizatori specificați (limita este %{user_limit})"
msgid "Added"
-msgstr ""
+msgstr "Adăugat"
msgid "Added %{epic_ref} as a child epic."
-msgstr ""
+msgstr "S-a adăugat %{epic_ref} ca o epică copil."
msgid "Added %{label_references} %{label_text}."
-msgstr ""
+msgstr "S-a adăugat %{label_references} %{label_text}."
msgid "Added a to do."
-msgstr ""
+msgstr "S-a adăugat un to do."
msgid "Added an issue to an epic."
-msgstr ""
+msgstr "Problemă adăugată la o epică."
msgid "Added at"
-msgstr ""
+msgstr "Adăugat la"
msgid "Added for this merge request"
-msgstr ""
+msgstr "Adăugat pentru acest merge request"
msgid "Added in this version"
-msgstr ""
+msgstr "Adăugat în această versiune"
msgid "Adding new applications is disabled in your GitLab instance. Please contact your GitLab administrator to get the permission"
-msgstr ""
+msgstr "Adăugarea de noi aplicații este dezactivată în instanța dvs. GitLab. Contactați administratorul dvs. GitLab pentru a obține permisiunea"
msgid "Additional Metadata"
-msgstr ""
+msgstr "Metadate suplimentare"
msgid "Additional minutes"
-msgstr ""
+msgstr "Minute suplimentare"
msgid "Additional minutes:"
-msgstr ""
+msgstr "Minute suplimentare:"
msgid "Additional text"
-msgstr ""
+msgstr "Text suplimentar"
msgid "Additional text for the sign-in and Help page."
-msgstr ""
+msgstr "Text suplimentar pentru pagina de autentificare și pagina de Ajutor."
msgid "Additional text to show on the Help page"
-msgstr ""
+msgstr "Text suplimentar pentru a fi afișat pe pagina de Ajutor"
msgid "Additional text to show on the sign-in page"
-msgstr ""
+msgstr "Text suplimentar pentru a arăta pe pagina de autentificare"
msgid "Address"
-msgstr ""
+msgstr "Adresă"
msgid "Adds"
-msgstr ""
+msgstr "Adaugă"
msgid "Adds %{epic_ref} as child epic."
-msgstr ""
+msgstr "Adaugă %{epic_ref} ca epică secundară."
msgid "Adds %{labels} %{label_text}."
-msgstr ""
+msgstr "Adaugă %{labels} %{label_text}."
msgid "Adds a Zoom meeting"
-msgstr ""
+msgstr "Adaugă o întâlnire Zoom"
msgid "Adds a to do."
-msgstr ""
+msgstr "Adaugă un to do."
msgid "Adds an issue to an epic."
-msgstr ""
+msgstr "Adaugă o problemă la o epică."
msgid "Adds email participant(s)"
-msgstr ""
+msgstr "Adăugați participant(ți) e-mail"
msgid "Adjust how frequently the GitLab UI polls for updates."
-msgstr ""
+msgstr "Ajustați cât de frecvent GitLab UI votează pentru actualizări."
msgid "Adjust your filters/search criteria above. If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
-msgstr ""
+msgstr "Ajustați filtrele/criteriile de căutare de mai sus. Dacă credeți că este vorba de o eroare, consultați documentația %{linkStart}Geo Troubleshooting%{linkEnd} pentru mai multe informații."
msgid "Admin"
-msgstr ""
+msgstr "Administrator"
msgid "Admin Area"
-msgstr ""
+msgstr "Zona Admin"
msgid "Admin Mode"
-msgstr ""
+msgstr "Modul administrator"
msgid "Admin Note"
-msgstr ""
+msgstr "Notă administrativă"
msgid "Admin Notifications"
-msgstr ""
+msgstr "Notificări administrator"
msgid "Admin Overview"
-msgstr ""
+msgstr "Prezentare generală a administratorilor"
msgid "Admin Section"
-msgstr ""
+msgstr "Secțiunea Admin"
msgid "Admin mode already enabled"
-msgstr ""
+msgstr "Modul administrator este deja activat"
msgid "Admin mode disabled"
-msgstr ""
+msgstr "Modul administrator dezactivat"
msgid "Admin mode enabled"
-msgstr ""
+msgstr "Modul administrator activat"
msgid "Admin navigation"
-msgstr ""
+msgstr "Navigare administrator"
msgid "Admin notes"
-msgstr ""
+msgstr "Note administrative"
msgid "AdminArea|%{billable_users_link_start}Learn more%{billable_users_link_end} about what defines a billable user"
-msgstr ""
+msgstr "%{billable_users_link_start}Aflați mai multe%{billable_users_link_end} despre ce definește un utilizator facturabil"
msgid "AdminArea|Active users"
-msgstr ""
+msgstr "Utilizatori activi"
msgid "AdminArea|All users created in the instance, including users who are not %{billable_users_link_start}billable users%{billable_users_link_end}."
-msgstr ""
+msgstr "Toți utilizatorii creați în instanță, inclusiv utilizatorii care nu sunt %{billable_users_link_start}utilizatori facturabili%{billable_users_link_end}."
msgid "AdminArea|Billable users"
-msgstr ""
+msgstr "Utilizatori facturabili"
msgid "AdminArea|Blocked users"
-msgstr ""
+msgstr "Utilizatori blocați"
msgid "AdminArea|Bots"
-msgstr ""
+msgstr "Boți"
msgid "AdminArea|Components"
-msgstr ""
+msgstr "Componente"
msgid "AdminArea|Developer"
-msgstr ""
+msgstr "Dezvoltator"
msgid "AdminArea|Features"
-msgstr ""
+msgstr "Funcții"
msgid "AdminArea|Groups"
-msgstr ""
+msgstr "Grupuri"
msgid "AdminArea|Guest"
-msgstr ""
+msgstr "Invitat"
msgid "AdminArea|Included Free in license"
-msgstr ""
+msgstr "Inclus gratuit în licență"
msgid "AdminArea|Latest groups"
-msgstr ""
+msgstr "Ultimele grupuri"
msgid "AdminArea|Latest projects"
-msgstr ""
+msgstr "Ultimele proiecte"
msgid "AdminArea|Latest users"
-msgstr ""
+msgstr "Ultimii utilizatori"
msgid "AdminArea|Maintainer"
-msgstr ""
+msgstr "Întreținător"
msgid "AdminArea|New group"
-msgstr ""
+msgstr "Grup nou"
msgid "AdminArea|New project"
-msgstr ""
+msgstr "Proiect nou"
msgid "AdminArea|New user"
-msgstr ""
+msgstr "Utilizator nou"
msgid "AdminArea|Owner"
-msgstr ""
+msgstr "Proprietar"
msgid "AdminArea|Projects"
-msgstr ""
+msgstr "Proiecte"
msgid "AdminArea|Reporter"
-msgstr ""
+msgstr "Reporter"
msgid "AdminArea|Stop all jobs"
-msgstr ""
+msgstr "Opriți toate joburile"
msgid "AdminArea|Stop all jobs?"
-msgstr ""
+msgstr "Opriți toate joburile?"
msgid "AdminArea|Stop jobs"
-msgstr ""
+msgstr "Opriți joburile"
msgid "AdminArea|Stopping jobs failed"
-msgstr ""
+msgstr "Oprirea joburilor a eșuat"
msgid "AdminArea|Total users"
-msgstr ""
+msgstr "Total utilizatori"
msgid "AdminArea|Users"
-msgstr ""
+msgstr "Utilizatori"
msgid "AdminArea|Users statistics"
-msgstr ""
+msgstr "Statisticile utilizatorilor"
msgid "AdminArea|Users with highest role"
-msgstr ""
+msgstr "Utilizatori cu cel mai mare rol"
msgid "AdminArea|Users without a Group and Project"
-msgstr ""
+msgstr "Utilizatori fără grup și proiect"
msgid "AdminArea|View latest groups"
-msgstr ""
+msgstr "Vedeți cele mai recente grupuri"
msgid "AdminArea|View latest projects"
-msgstr ""
+msgstr "Vedeți cele mai recente proiecte"
msgid "AdminArea|View latest users"
-msgstr ""
+msgstr "Vedeți cei mai noi utilizatori"
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
-msgstr ""
+msgstr "Eroare la încărcarea statisticilor. Vă rugăm încercați din nou"
msgid "AdminProjects| You’re about to permanently delete the project %{projectName}, its repository, and all related resources, including issues and merge requests. Once you confirm and press %{strong_start}Delete project%{strong_end}, it cannot be undone or recovered."
-msgstr ""
+msgstr "Sigur doriți să ștergeți proiectul %{projectName}, repozitoriul lui, și toate obiectele relatate, incluzând probleme și cereri de îmbinare? Odată ce confirmați și apăsați %{strong_start}Șterge proiectul%{strong_end}, nu puteți da înapoi."
msgid "AdminProjects|Delete"
-msgstr ""
+msgstr "Ștergeți"
msgid "AdminProjects|Delete Project %{projectName}?"
-msgstr ""
+msgstr "Ștergeți proiectul %{projectName}?"
msgid "AdminSettings|A Let's Encrypt account will be configured for this GitLab instance using this email address. You will receive emails to warn of expiring certificates. %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "Un cont Let's Encrypt va fi configurat pentru această instanță de GitLab folosind această adresă de mail. Veți primi e-mailuri pentru a vă avertiza de certificate pe cale de expirare. %{link_start}Aflați mai multe.%{link_end}"
msgid "AdminSettings|All new projects can use the instance's shared runners by default."
-msgstr ""
+msgstr "Toate proiectele noi pot folosi executorii împărțiți ai acestei instanțe în mod implicit."
msgid "AdminSettings|Auto DevOps domain"
-msgstr ""
+msgstr "Domeniu Auto DevOps"
msgid "AdminSettings|Configure Let's Encrypt"
-msgstr ""
+msgstr "Configurați Let's Encrypt"
msgid "AdminSettings|Disable feed token"
-msgstr ""
+msgstr "Dezactivare token feed"
msgid "AdminSettings|Disable public access to Pages sites"
-msgstr ""
+msgstr "Dezactivați accesul public către site-uri Pagini"
msgid "AdminSettings|Domain verification is an essential security measure for public GitLab sites. Users are required to demonstrate they control a domain before it is enabled. %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "Verificarea de domeniu este o măsură de securitate esențială pentru site-urile publice GitLab. Utilizatorii trebuie să demonstreze că controlează un domeniu înainte ca acesta să fie activat. %{link_start}Aflați mai multe.%{link_end}"
msgid "AdminSettings|Enable shared runners for new projects"
-msgstr ""
+msgstr "Activați executori comuni pentru proiecte noi"
msgid "AdminSettings|Feed token"
-msgstr ""
+msgstr "Token feed"
msgid "AdminSettings|I have read and agree to the Let's Encrypt %{link_start}Terms of Service%{link_end} (PDF)."
-msgstr ""
+msgstr "Am citit și sunt de acord cu %{link_start}Termenii și condițiile%{link_end} Let's Encrypt (PDF)."
msgid "AdminSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
-msgstr ""
+msgstr "Dacă nespecificată la nivel de grup/instanță, valoarea implicită este %{default_initial_branch_name}. Nu afectează repozitorii existente."
msgid "AdminSettings|Keep the latest artifacts for all jobs in the latest successful pipelines"
-msgstr ""
+msgstr "Păstrați cele mai recente artefacte pentru toate joburile în cele mai recente conducte de succes"
msgid "AdminSettings|Let's Encrypt email"
-msgstr ""
+msgstr "E-mail Let's Encrypt"
msgid "AdminSettings|Maximum duration of a session for Git operations when 2FA is enabled."
-msgstr ""
+msgstr "Durata maximă a unei sesiuni pentru operațiunile Git atunci când 2FA este activată."
msgid "AdminSettings|New CI/CD variables in projects and groups default to protected."
-msgstr ""
+msgstr "Variabilele CI / CD noi din proiecte și grupuri sunt în mod implicit protejate."
msgid "AdminSettings|No required pipeline"
-msgstr ""
+msgstr "Nicio conductă necesară"
msgid "AdminSettings|Protect CI/CD variables by default"
-msgstr ""
+msgstr "Protejați în mod implicit variabilele CI / CD"
msgid "AdminSettings|Require users to prove ownership of custom domains"
-msgstr ""
+msgstr "Obligați utilizatorii să demonstreze proprietariatul domeniilor personalizate"
msgid "AdminSettings|Required pipeline configuration"
-msgstr ""
+msgstr "Configurație necesară conductă"
msgid "AdminSettings|Select a CI/CD template"
-msgstr ""
+msgstr "Selectați un șablon CI / CD"
msgid "AdminSettings|Select a group to use as the source for instance-level project templates."
-msgstr ""
+msgstr "Selectați un grup pentru a fi folosit ca sursă pentru șabloanele de proiecte la nivel de instanță"
msgid "AdminSettings|Select to disable public access for Pages sites, which requires users to sign in for access to the Pages sites in your instance. %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "Selectați pentru a dezactiva accesul public către site-uri Pagini, ceea ce înseamnă că utilizatorii trebuie să se conecteze pentru acces la site-urile Pagini din instanța dumneavoastră. %{link_start}Aflați mai multe.%{link_end}"
msgid "AdminSettings|Session duration for Git operations when 2FA is enabled (minutes)"
-msgstr ""
+msgstr "Durata sesiunii pentru operațiunile Git atunci când 2FA este activată (minute)"
msgid "AdminSettings|Set a CI/CD template as the required pipeline configuration for all projects in the instance. Project CI/CD configuration merges into the required pipeline configuration when the pipeline runs. %{link_start}What is a required pipeline configuration?%{link_end}"
-msgstr ""
+msgstr "Setați un șablon CI / CD ca fiind configurația necesară a conductei pentru toate proiectele din instanță. Configurația CI / CD a proiectului se îmbină în configurația necesară a conductei atunci când se execută conducta. %{link_start}Ce este o configurație de conductă necesară?%{link_end}"
msgid "AdminSettings|Set the maximum size of GitLab Pages per project (0 for unlimited). %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "Setați mărimea maximă a Paginilor GitLab per proiect (0 pentru nelimitate). %{link_start}Aflați mai multe.%{link_end}"
msgid "AdminSettings|Size and domain settings for Pages static sites."
-msgstr ""
+msgstr "Setări mărime și domeniu pentru site-uri statice Pagini."
msgid "AdminSettings|The default domain to use for Auto Review Apps and Auto Deploy stages in all projects."
-msgstr ""
+msgstr "Domeniul prestabilit folosit pentru aplicații Auto Review și stagii Auto Deploy in toate proiectele."
msgid "AdminSettings|The default name for the initial branch of new repositories created in the instance."
-msgstr ""
+msgstr "Numele prestabilit pentru ramura inițială a noilor repozitorii create în instanță."
msgid "AdminSettings|The latest artifacts for all jobs in the most recent successful pipelines in each project are stored and do not expire."
-msgstr ""
+msgstr "Cele mai recente artefacte pentru toate lucrările din cele mai recente conducte de succes din fiecare proiect sunt stocate și nu expiră."
msgid "AdminSettings|The projects in this group can be selected as templates for new projects created on the instance. %{link_start}Learn more.%{link_end} "
-msgstr ""
+msgstr "Proiectele în acest grup pot fi selectate ca șabloane pentru proiectele noi create în această instanță. %{link_start}Aflați mai multe.%{link_end} "
msgid "AdminSettings|The template for the required pipeline configuration can be one of the GitLab-provided templates, or a custom template added to an instance template repository. %{link_start}How do I create an instance template repository?%{link_end}"
-msgstr ""
+msgstr "Șablonul pentru configurația necesară a conductei poate fi unul dintre șabloanele furnizate de GitLab sau un șablon personalizat adăugat la un depozit de șabloane de instanță. %{link_start}Cum se creează un depozit de șabloane de instanță?%{link_end}"
msgid "AdminStatistics|Active Users"
-msgstr ""
+msgstr "Utilizatori activi"
msgid "AdminStatistics|Forks"
-msgstr ""
+msgstr "Ramificații"
msgid "AdminStatistics|Issues"
-msgstr ""
+msgstr "Probleme"
msgid "AdminStatistics|Merge requests"
-msgstr ""
+msgstr "Merge request-uri"
msgid "AdminStatistics|Milestones"
-msgstr ""
+msgstr "Obiective"
msgid "AdminStatistics|Notes"
-msgstr ""
+msgstr "Notițe"
msgid "AdminStatistics|SSH Keys"
-msgstr ""
+msgstr "Chei SSH"
msgid "AdminStatistics|Snippets"
-msgstr ""
+msgstr "Fragmente de cod"
msgid "AdminUsers|(Admin)"
-msgstr ""
+msgstr "(Admin)"
msgid "AdminUsers|(Banned)"
-msgstr ""
+msgstr "(Banat)"
msgid "AdminUsers|(Blocked)"
-msgstr ""
+msgstr "(Blocat)"
msgid "AdminUsers|(Deactivated)"
-msgstr ""
+msgstr "(Dezactivat)"
msgid "AdminUsers|(Internal)"
-msgstr ""
+msgstr "(Intern)"
msgid "AdminUsers|(Pending approval)"
-msgstr ""
+msgstr "(Aprobare în așteptare)"
msgid "AdminUsers|2FA Disabled"
-msgstr ""
+msgstr "2FA dezactivată"
msgid "AdminUsers|2FA Enabled"
-msgstr ""
+msgstr "2FA activată"
msgid "AdminUsers|A user can validate themselves by inputting a credit/debit card, or an admin can manually validate a user."
-msgstr ""
+msgstr "Un utilizator se poate valida introducând un card de credit / debit sau un administrator poate valida manual un utilizator."
msgid "AdminUsers|Access"
-msgstr ""
+msgstr "Acces"
msgid "AdminUsers|Access Git repositories"
-msgstr ""
+msgstr "Accesați depozitele Git"
msgid "AdminUsers|Access the API"
-msgstr ""
+msgstr "Accesați API-ul"
msgid "AdminUsers|Activate"
-msgstr ""
+msgstr "Activare"
msgid "AdminUsers|Activate user %{username}?"
-msgstr ""
+msgstr "Activați utilizatorul %{username}?"
msgid "AdminUsers|Active"
-msgstr ""
+msgstr "Activ"
msgid "AdminUsers|Adjust the user cap setting on your instance"
-msgstr ""
+msgstr "Ajustați setarea plafonului de utilizatori pe instanța dvs."
msgid "AdminUsers|Admin"
-msgstr ""
+msgstr "Administrator"
msgid "AdminUsers|Administrators have access to all groups, projects and users and can manage all features in this installation"
-msgstr ""
+msgstr "Administratorii au acces la toate grupurile, proiectele și utilizatorii și pot gestiona toate funcțiile din această instalație."
msgid "AdminUsers|Admins"
-msgstr ""
+msgstr "Administratori"
msgid "AdminUsers|Approve"
-msgstr ""
+msgstr "Aprobare"
msgid "AdminUsers|Approve user %{username}?"
-msgstr ""
+msgstr "Aprobați utilizatorul %{username}?"
msgid "AdminUsers|Approved users can:"
-msgstr ""
+msgstr "Utilizatorii aprobați pot:"
msgid "AdminUsers|Automatically marked as default internal user"
-msgstr ""
+msgstr "Marcat automat ca utilizator intern implicit"
msgid "AdminUsers|Ban user"
-msgstr ""
+msgstr "Banare utilizator"
msgid "AdminUsers|Ban user %{username}?"
-msgstr ""
+msgstr "Banați utilizatorul %{username}?"
msgid "AdminUsers|Banned"
-msgstr ""
+msgstr "Banat"
msgid "AdminUsers|Be added to groups and projects"
-msgstr ""
+msgstr "Să fie adăugat la grupuri și proiecte"
msgid "AdminUsers|Block"
-msgstr ""
+msgstr "Blocare"
msgid "AdminUsers|Block user"
-msgstr ""
+msgstr "Blocați utilizatorul"
msgid "AdminUsers|Block user %{username}?"
-msgstr ""
+msgstr "Blocați utilizatorul %{username}?"
msgid "AdminUsers|Blocked"
-msgstr ""
+msgstr "Blocat"
msgid "AdminUsers|Blocking user has the following effects:"
-msgstr ""
-
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
+msgstr "Blocarea unui utilizator are următoarele efecte:"
msgid "AdminUsers|Cannot sign in or access instance information"
-msgstr ""
+msgstr "Imposibil de autentificat sau accesat informațiile despre instanță"
msgid "AdminUsers|Cannot unblock LDAP blocked users"
-msgstr ""
+msgstr "Nu se pot debloca utilizatorii blocați LDAP"
msgid "AdminUsers|Cohorts"
-msgstr ""
+msgstr "Cohorte"
msgid "AdminUsers|Confirm user"
-msgstr ""
+msgstr "Confirmați utilizatorul"
msgid "AdminUsers|Confirm user %{username}?"
-msgstr ""
+msgstr "Confirmați utilizatorul %{username}?"
msgid "AdminUsers|Could not load user group counts. Please refresh the page to try again."
-msgstr ""
+msgstr "Nu s-a putut încărca numărul de grupuri de utilizatori. Vă rugăm să reîmprospătați pagina pentru a încerca din nou."
msgid "AdminUsers|Deactivate"
-msgstr ""
+msgstr "Dezactivați"
msgid "AdminUsers|Deactivate user %{username}?"
-msgstr ""
+msgstr "Deactivați utilizatorul %{username}?"
msgid "AdminUsers|Deactivated"
-msgstr ""
+msgstr "Dezactivat"
msgid "AdminUsers|Deactivating a user has the following effects:"
-msgstr ""
+msgstr "Dezactivarea unui utilizator are următoarele efecte:"
msgid "AdminUsers|Delete User %{username} and contributions?"
-msgstr ""
+msgstr "Ștergeți utilizatorul %{username} și contribuțiile?"
msgid "AdminUsers|Delete User %{username}?"
-msgstr ""
+msgstr "Ștergeți utilizatorul %{username}?"
msgid "AdminUsers|Delete user"
-msgstr ""
+msgstr "Ștergeți utilizatorul"
msgid "AdminUsers|Delete user and contributions"
-msgstr ""
+msgstr "Ștergeți utilizatorul și contribuțiile"
msgid "AdminUsers|Export permissions as CSV"
-msgstr ""
+msgstr "Exportați permisiunile ca CSV"
msgid "AdminUsers|External"
-msgstr ""
+msgstr "Extern"
msgid "AdminUsers|External users cannot see internal or private projects unless access is explicitly granted. Also, external users cannot create projects, groups, or personal snippets."
-msgstr ""
+msgstr "Utilizatorii externi nu pot vedea proiectele interne sau private decât dacă accesul este acordat în mod explicit. De asemenea, utilizatorii externi nu pot crea proiecte, grupuri sau fragmente personale."
msgid "AdminUsers|For more information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
-msgstr ""
+msgstr "Pentru mai multe informații, vă rugăm să consultați %{link_start}documentația de ștergere a contului de utilizator.%{link_end}"
msgid "AdminUsers|Here are some helpful links to help you manage your instance:"
-msgstr ""
+msgstr "Iată câteva linkuri utile pentru a vă ajuta să vă administrați instanța:"
msgid "AdminUsers|If you have any questions about this process please consult our %{doc_link} or %{support_link}."
-msgstr ""
+msgstr "Dacă aveți întrebări cu privire la acest proces, vă rugăm să consultați %{doc_link} sau %{support_link}."
msgid "AdminUsers|Important information about usage on your GitLab instance"
-msgstr ""
+msgstr "Informații importante despre utilizarea instanței dvs. GitLab"
msgid "AdminUsers|Is using seat"
+msgstr "Utilizează locul"
+
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
msgstr ""
msgid "AdminUsers|It's you!"
-msgstr ""
+msgstr "Dvs. sunteți!"
msgid "AdminUsers|Learn more about %{link_start}banned users.%{link_end}"
-msgstr ""
+msgstr "Aflați mai multe despre %{link_start}utilizatori interziși.%{link_end}"
msgid "AdminUsers|Log in"
-msgstr ""
+msgstr "Autentificare"
msgid "AdminUsers|Manage (accept/reject) pending user sign ups"
-msgstr ""
+msgstr "Gestionați (acceptați/respingeți) înregistrările de utilizatori în așteptare"
msgid "AdminUsers|New user"
-msgstr ""
+msgstr "Utilizator nou"
msgid "AdminUsers|No users found"
-msgstr ""
+msgstr "Nu au fost găsiți utilizatori"
msgid "AdminUsers|Owned groups will be left"
-msgstr ""
+msgstr "Grupurile deținute vor fi lăsate"
msgid "AdminUsers|Pending approval"
-msgstr ""
+msgstr "În așteptarea aprobării"
msgid "AdminUsers|Personal projects will be left"
-msgstr ""
+msgstr "Proiectele personale vor fi lăsate"
msgid "AdminUsers|Personal projects, group and user history will be left intact"
-msgstr ""
+msgstr "Proiectele personale, istoricul grupurilor și al utilizatorilor vor fi lăsate intacte."
msgid "AdminUsers|Reactivating a user will:"
-msgstr ""
+msgstr "Reactivarea unui utilizator va:"
msgid "AdminUsers|Regular"
-msgstr ""
+msgstr "Regular"
msgid "AdminUsers|Regular users have access to their groups and projects"
-msgstr ""
+msgstr "Utilizatorii obișnuiți au acces la grupurile și proiectele lor"
msgid "AdminUsers|Reject"
-msgstr ""
+msgstr "Respingere"
msgid "AdminUsers|Reject user %{username}?"
-msgstr ""
+msgstr "Respingeți utilizatorul %{username}?"
msgid "AdminUsers|Rejected users:"
-msgstr ""
+msgstr "Utilizatori respinși:"
msgid "AdminUsers|Restore user access to the account, including web, Git and API."
-msgstr ""
+msgstr "Restabiliți accesul utilizatorului la cont, inclusiv la web, Git și API."
msgid "AdminUsers|Search by name, email or username"
-msgstr ""
+msgstr "Căutare după nume, e-mail sau nume de utilizator"
msgid "AdminUsers|Search users"
-msgstr ""
+msgstr "Căutați utilizatori"
msgid "AdminUsers|Send email to users"
-msgstr ""
+msgstr "Trimiteți e-mail utilizatorilor"
msgid "AdminUsers|Sort by"
+msgstr "Sortează după"
+
+msgid "AdminUsers|The user can't access git repositories."
msgstr ""
-msgid "AdminUsers|The user will be logged out"
+msgid "AdminUsers|The user can't log in."
msgstr ""
+msgid "AdminUsers|The user will be logged out"
+msgstr "Utilizatorul va fi deconectat"
+
msgid "AdminUsers|The user will not be able to access git repositories"
-msgstr ""
+msgstr "Utilizatorul nu va putea accesa repozitorii git"
msgid "AdminUsers|The user will not be able to access the API"
-msgstr ""
+msgstr "Utilizatorul nu va putea accesa API-ul"
msgid "AdminUsers|The user will not be able to use slash commands"
-msgstr ""
+msgstr "Utilizatorul nu va putea folosi comenzi slash"
msgid "AdminUsers|The user will not receive any notifications"
-msgstr ""
+msgstr "Utilizatorul nu va primi nicio notificare"
msgid "AdminUsers|To confirm, type %{projectName}"
-msgstr ""
+msgstr "Pentru a confirma, tastați %{projectName}"
msgid "AdminUsers|To confirm, type %{username}"
-msgstr ""
+msgstr "Pentru a confirma, tastați %{username}"
msgid "AdminUsers|Unban user"
-msgstr ""
+msgstr "Debanați utilizatorul"
msgid "AdminUsers|Unban user %{username}?"
-msgstr ""
+msgstr "Debanați utilizatorul %{username}?"
msgid "AdminUsers|Unblock"
-msgstr ""
+msgstr "Deblocare"
msgid "AdminUsers|Unblock user %{username}?"
-msgstr ""
+msgstr "Deblocați utilizatorul %{username}?"
msgid "AdminUsers|Unlock user %{username}?"
-msgstr ""
+msgstr "Deblocați utilizatorul %{username}?"
msgid "AdminUsers|User administration"
-msgstr ""
+msgstr "Administrație utilizator"
msgid "AdminUsers|User is validated and can use free CI minutes on shared runners."
-msgstr ""
+msgstr "Utilizatorul este validat și poate utiliza minutele gratuite CI pe executori partajați."
msgid "AdminUsers|User will not be able to access git repositories"
-msgstr ""
+msgstr "User nu va putea accesa repozitoriile git"
msgid "AdminUsers|User will not be able to login"
-msgstr ""
+msgstr "Utilizatorul nu se va putea autentifica"
msgid "AdminUsers|Users"
-msgstr ""
+msgstr "Utilizatori"
msgid "AdminUsers|Users can still be invited to your instance and/or add themselves if permitted based on your settings. They will not have access to your instance, nor count towards your subscribed seat count until you %{approve_link}."
-msgstr ""
+msgstr "Utilizatorii pot fi invitați în continuare la instanța dvs. și/sau se pot adăuga singuri, dacă acest lucru este permis în funcție de setările dvs. Aceștia nu vor avea acces la instanța dvs. și nici nu vor fi luați în calcul pentru numărul de locuri abonate până când nu %{approve_link}."
msgid "AdminUsers|Validate user account"
-msgstr ""
+msgstr "Validați contul de utilizator"
msgid "AdminUsers|View pending member requests"
-msgstr ""
+msgstr "Vezi cererile membrilor în așteptare"
msgid "AdminUsers|What can I do?"
-msgstr ""
+msgstr "Ce pot face?"
msgid "AdminUsers|What does this mean?"
-msgstr ""
+msgstr "Ce înseamnă acest lucru?"
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
-msgstr ""
+msgstr "Când utilizatorul se autentifică din nou, contul său va fi reactivat ca un cont complet activ"
msgid "AdminUsers|Will be deleted"
-msgstr ""
+msgstr "Va fi șters"
msgid "AdminUsers|Without projects"
-msgstr ""
+msgstr "Fără proiecte"
msgid "AdminUsers|You are about to permanently delete the user %{username}. Issues, merge requests, and groups linked to them will be transferred to a system-wide \"Ghost-user\". To avoid data loss, consider using the %{strongStart}block user%{strongEnd} feature instead. Once you %{strongStart}Delete user%{strongEnd}, it cannot be undone or recovered."
-msgstr ""
+msgstr "Sunteți pe cale să ștergeți definitiv utilizatorul %{username}. Problemele, merge request-urile și grupurile legate de acestea vor fi transferate către un \"Utilizator-fantomă\" la nivel de sistem. Pentru a evita pierderea de date, luați în considerare utilizarea în schimb a funcției %{strongStart}blocare utilizator%{strongEnd}. Odată ce ați %{strongStart}ștergeți utilizatorul%{strongEnd}, această acțiune nu poate fi anulată sau contul recuperat."
msgid "AdminUsers|You are about to permanently delete the user %{username}. This will delete all of the issues, merge requests, and groups linked to them. To avoid data loss, consider using the %{strongStart}block user%{strongEnd} feature instead. Once you %{strongStart}Delete user%{strongEnd}, it cannot be undone or recovered."
-msgstr ""
+msgstr "Sunteți pe cale să ștergeți definitiv utilizatorul %{username}. Problemele, merge request-urile și grupurile legate de acestea vor fi șterse. Pentru a evita pierderea de date, luați în considerare utilizarea în schimb a funcției %{strongStart}blocare utilizator%{strongEnd}. Odată ce ați %{strongStart}ștergeți utilizatorul%{strongEnd}, această acțiune nu poate fi anulată sau contul recuperat."
msgid "AdminUsers|You can always block their account again if needed."
-msgstr ""
+msgstr "Puteți mereu să le blocați iarăși contul dacă este necesar."
msgid "AdminUsers|You can always deactivate their account again if needed."
-msgstr ""
+msgstr "Puteți mereu să le dezactivați iarăși contul dacă este necesar."
msgid "AdminUsers|You can always re-activate their account, their data will remain intact."
-msgstr ""
+msgstr "Puteți mereu să le reactivați iarăși contul dacă este necesar, datele lor vor rămâne intacte."
msgid "AdminUsers|You can always unblock their account, their data will remain intact."
-msgstr ""
+msgstr "Puteți mereu să le deblocați iarăși contul dacă este necesar, datele lor vor rămâne intacte."
msgid "AdminUsers|You can ban their account in the future if necessary."
-msgstr ""
+msgstr "Le puteți bana contul în viitor dacă este necesar."
msgid "AdminUsers|You can unban their account in the future. Their data remains intact."
-msgstr ""
+msgstr "Puteți mereu să le debanați contul dacă este necesar. Datele lor vor rămâne intacte."
msgid "AdminUsers|You cannot remove your own admin rights."
-msgstr ""
+msgstr "Nu vă puteți elimina propriile drepturi administrative."
msgid "AdminUsers|You must transfer ownership or delete the groups owned by this user before you can delete their account"
-msgstr ""
+msgstr "Trebuie să transferați proprietatea sau să ștergeți grupurile deținute de acest utilizator înainte de a le șterge contul."
msgid "AdminUsers|Your GitLab instance has reached the maximum allowed %{user_doc_link} set by an instance admin."
-msgstr ""
+msgstr "Instanța dvs. GitLab a atins numărul maxim permis de %{user_doc_link} stabilit de un administrator de instanță."
msgid "AdminUsers|approve them"
-msgstr ""
+msgstr "aprobați-le"
msgid "AdminUsers|contact our support team"
-msgstr ""
+msgstr "contactați echipa noastră de asistență"
msgid "AdminUsers|docs"
-msgstr ""
+msgstr "documente"
msgid "AdminUsers|user cap"
-msgstr ""
+msgstr "limită utilizator"
msgid "Administration"
-msgstr ""
+msgstr "Administrare"
msgid "Admin|Additional users must be reviewed and approved by a system administrator. Learn more about %{help_link_start}usage caps%{help_link_end}."
-msgstr ""
+msgstr "Utilizatorii suplimentari trebuie să fie examinați și aprobați de un administrator de sistem. Aflați mai multe despre %{help_link_start}plafoane de utilzare%{help_link_end}."
msgid "Admin|Admin notes"
-msgstr ""
+msgstr "Note administrative"
msgid "Admin|Learn more about quarterly reconciliation"
-msgstr ""
+msgstr "Aflați mai multe despre reconcilierea trimestrială"
msgid "Admin|Note"
-msgstr ""
+msgstr "Notă"
msgid "Admin|Quarterly reconciliation will occur on %{qrtlyDate}"
-msgstr ""
+msgstr "Reconcilierea trimestrială va avea loc la %{qrtlyDate}"
msgid "Admin|The number of max seats used for your namespace is currently exceeding the number of seats in your subscription. On %{qrtlyDate}, GitLab will process a quarterly reconciliation and automatically bill you a prorated amount for the overage. There is no action needed from you. If you have a credit card on file, it will be charged. Otherwise, you will receive an invoice."
-msgstr ""
+msgstr "Numărul maxim de locuri utilizate pentru spațiul dvs. de nume depășește în prezent numărul de locuri din abonament. La data de %{qrtlyDate}, GitLab va procesa o reconciliere trimestrială și vă va factura automat o sumă proporțională pentru depășirea numărului de locuri. Nu este necesară nicio acțiune din partea dvs. Dacă aveți un card de credit la dosar, acesta va fi debitat. În caz contrar, veți primi o factură."
msgid "Admin|The number of maximum users for your instance is currently exceeding the number of users in license. On %{qrtlyDate}, GitLab will process a quarterly reconciliation and automatically bill you a prorated amount for the overage. There is no action needed from you. If you have a credit card on file, it will be charged. Otherwise, you will receive an invoice."
-msgstr ""
+msgstr "Numărul maxim de utilizatori pentru instanța dvs. depășește în prezent numărul de utilizatori din licență. La data de %{qrtlyDate}, GitLab va procesa o reconciliere trimestrială și vă va factura automat o sumă proporțională pentru depășirea numărului de utilizatori. Nu este necesară nicio acțiune din partea dvs. Dacă aveți un card de credit la dosar, acesta va fi debitat. În caz contrar, veți primi o factură."
msgid "Admin|View pending user approvals"
-msgstr ""
+msgstr "Vedeți aprobările în așteptare ale utilizatorilor"
msgid "Admin|Your instance has reached its user cap"
-msgstr ""
+msgstr "Instanța dvs. a atins plafonul de utilizatori"
msgid "Advanced"
-msgstr ""
+msgstr "Avansat"
msgid "Advanced Search"
-msgstr ""
+msgstr "Căutare avansată"
msgid "Advanced Settings"
-msgstr ""
+msgstr "Setări avansate"
msgid "Advanced export options"
-msgstr ""
+msgstr "Opțiuni avansate de export"
msgid "Advanced permissions, Large File Storage and Two-Factor authentication settings."
-msgstr ""
+msgstr "Permisiuni avansate, Setări Large File Storage și Autentificare în doi pași."
msgid "After a successful password update you will be redirected to login screen."
-msgstr ""
+msgstr "După o actualizare cu succes a parolei, veți fi redirecționat către ecranul de autentificare."
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
-msgstr ""
+msgstr "După o actualizare cu succes a parolei, veți fi redirecționat către pagina de autentificare, unde vă puteți autentifica cu noua parolă."
msgid "After that, you will not be able to use merge approvals or code quality as well as many other features."
-msgstr ""
+msgstr "După aceea, nu veți mai putea utiliza aprobările de îmbinare sau calitatea codului, precum și multe alte funcții."
msgid "After that, you will not be able to use merge approvals or epics as well as many other features."
-msgstr ""
+msgstr "După aceea, nu veți mai putea utiliza aprobări de îmbinare sau epice, precum și multe alte funcții."
msgid "After that, you will not be able to use merge approvals or epics as well as many security features."
-msgstr ""
+msgstr "După aceea, nu veți mai putea folosi aprobări de îmbinare sau epice precum și multe alte funcții de securitate."
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
-msgstr ""
+msgstr "După ce ați analizat instrucțiunile privind contribuțiile, veți fi gata să"
msgid "Akismet API Key"
-msgstr ""
+msgstr "Cheia API Akismet"
msgid "Alert"
msgid_plural "Alerts"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "Alertă"
+msgstr[1] "Alerte"
+msgstr[2] "Alerte"
msgid "AlertManagement|Acknowledged"
-msgstr ""
+msgstr "Recunoscut"
msgid "AlertManagement|Activity feed"
-msgstr ""
+msgstr "Feed activitate"
msgid "AlertManagement|Alert"
-msgstr ""
+msgstr "Alertă"
msgid "AlertManagement|Alert assignee(s): %{assignees}"
-msgstr ""
+msgstr "Responsabili alertă: %{assignees}"
msgid "AlertManagement|Alert detail"
-msgstr ""
+msgstr "Detalii alertă"
msgid "AlertManagement|Alert details"
-msgstr ""
+msgstr "Detalii alertă"
msgid "AlertManagement|Alert status: %{status}"
-msgstr ""
+msgstr "Stare alertă: %{status}"
msgid "AlertManagement|Alerts"
-msgstr ""
+msgstr "Alerte"
msgid "AlertManagement|All alerts"
-msgstr ""
+msgstr "Toate alertele"
msgid "AlertManagement|Assign status"
-msgstr ""
+msgstr "Atribuiți statusul"
msgid "AlertManagement|Assignees"
-msgstr ""
+msgstr "Responsabili"
msgid "AlertManagement|Authorize external service"
-msgstr ""
+msgstr "Autorizați serviciu extern"
msgid "AlertManagement|Create incident"
-msgstr ""
+msgstr "Creare incident"
msgid "AlertManagement|Display alerts from all your monitoring tools directly within GitLab. Streamline the investigation of your alerts and the escalation of alerts to incidents."
-msgstr ""
+msgstr "Afișare alerte din toate instrumentele de monitorizare direct în GitLab. Simplificați investigarea alertelor dvs. și transformarea alertelor în incidente."
msgid "AlertManagement|Edit"
-msgstr ""
+msgstr "Editare"
msgid "AlertManagement|Environment"
-msgstr ""
+msgstr "Mediu"
msgid "AlertManagement|Events"
-msgstr ""
+msgstr "Evenimente"
msgid "AlertManagement|Incident"
-msgstr ""
+msgstr "Incident"
msgid "AlertManagement|Key"
-msgstr ""
+msgstr "Cheie"
msgid "AlertManagement|Metrics"
-msgstr ""
+msgstr "Măsurători"
msgid "AlertManagement|Metrics weren't available in the alerts payload."
-msgstr ""
+msgstr "Măsuratorile nu erau disponibile în payload-ul alertelor."
msgid "AlertManagement|More information"
-msgstr ""
+msgstr "Mai multe informații"
msgid "AlertManagement|No alert data to display."
-msgstr ""
+msgstr "Nu există date alerte de afișat."
msgid "AlertManagement|No alerts available to display. See %{linkStart}enabling alert management%{linkEnd} for more information on adding alerts to the list."
-msgstr ""
+msgstr "Nu există alerte disponibile de afișat. Consultați %{linkStart}activarea gestionării alertelor%{linkEnd} pentru mai multe informații despre adăugarea alertelor în listă."
msgid "AlertManagement|No alerts to display."
-msgstr ""
+msgstr "Nu există alerte de afișat."
msgid "AlertManagement|None"
-msgstr ""
+msgstr "Niciuna"
msgid "AlertManagement|Open"
-msgstr ""
+msgstr "Deschisă"
msgid "AlertManagement|Please try again."
-msgstr ""
+msgstr "Vă rugăm să încercați din nou."
msgid "AlertManagement|Reported %{when}"
-msgstr ""
+msgstr "Raportat %{when}"
msgid "AlertManagement|Reported %{when} by %{tool}"
-msgstr ""
+msgstr "Raportat %{when} de %{tool}"
msgid "AlertManagement|Resolved"
-msgstr ""
+msgstr "Rezolvată"
msgid "AlertManagement|Runbook"
-msgstr ""
+msgstr "Runbook"
msgid "AlertManagement|Service"
-msgstr ""
+msgstr "Serviciu"
msgid "AlertManagement|Severity"
-msgstr ""
+msgstr "Severitate"
msgid "AlertManagement|Start time"
-msgstr ""
+msgstr "Ora de start"
msgid "AlertManagement|Status"
-msgstr ""
+msgstr "Status"
msgid "AlertManagement|Surface alerts in GitLab"
-msgstr ""
+msgstr "Surface alerte în GitLab"
msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
-msgstr ""
+msgstr "A apărut o eroare la afișarea alertei. Vă rugăm reîmprospătați pagina pentru a încerca din nou."
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
-msgstr ""
+msgstr "S-a produs o eroare la afișarea alertelor. Confirmați detaliile de configurare a punctului final pentru a vă asigura că alertele apar."
msgid "AlertManagement|There was an error while updating the assignee(s) list. Please try again."
-msgstr ""
+msgstr "A apărut o eroare la actualizarea listei de responsabili. Vă rugăm încercați din nou."
msgid "AlertManagement|There was an error while updating the assignee(s) of the alert. Please try again."
-msgstr ""
+msgstr "A apărut o eroare la actualizarea celor responsabili la această alertă. Vă rugăm să încercați din nou."
msgid "AlertManagement|There was an error while updating the status of the alert."
-msgstr ""
+msgstr "S-a produs o eroare în timpul actualizării stării alertei."
msgid "AlertManagement|There was an error while updating the to-do item of the alert."
-msgstr ""
+msgstr "S-a produs o eroare în timpul actualizării elementului to-do al alertei."
msgid "AlertManagement|This assignee cannot be assigned to this alert."
-msgstr ""
+msgstr "Acest responsabil nu poate fi atribuit acestei alerte"
msgid "AlertManagement|Tool"
-msgstr ""
+msgstr "Unealtă"
msgid "AlertManagement|Triggered"
-msgstr ""
+msgstr "Declanșat"
msgid "AlertManagement|Value"
-msgstr ""
+msgstr "Valoare"
msgid "AlertManagement|View incident"
-msgstr ""
+msgstr "Vizualizați incidentul"
msgid "AlertMappingBuilder|Define fallback"
-msgstr ""
+msgstr "Definiți alternativă"
msgid "AlertMappingBuilder|GitLab alert key"
-msgstr ""
+msgstr "Cheie de alertă GitLab"
msgid "AlertMappingBuilder|Make selection"
-msgstr ""
+msgstr "Efectuați selecția"
msgid "AlertMappingBuilder|Payload alert key"
-msgstr ""
+msgstr "Cheie de alertă de plată"
msgid "AlertMappingBuilder|Select key"
-msgstr ""
+msgstr "Selectare cheie"
msgid "AlertMappingBuilder|Title is a required field for alerts in GitLab. Should the payload field you specified not be available, specifiy which field we should use instead. "
-msgstr ""
+msgstr "Title este un câmp obligatoriu pentru alertele din GitLab. În cazul în care câmpul payload pe care l-ați specificat nu este disponibil, specificați ce câmp ar trebui să folosim în schimb. "
msgid "AlertSettings|A webhook URL and authorization key is generated for the integration. After you save the integration, both are visible under the “View credentials†tab."
-msgstr ""
+msgstr "Se generează o adresă URL de webhook și o cheie de autorizare pentru integrare. După ce salvați integrarea, ambele sunt vizibile în fila \"Vizualizare acreditări\"."
msgid "AlertSettings|Add new integration"
-msgstr ""
+msgstr "Adăugați o nouă integrare"
msgid "AlertSettings|Alert settings"
-msgstr ""
+msgstr "Setări de alertă"
msgid "AlertSettings|Authorization key"
-msgstr ""
+msgstr "Cheie de autorizare"
msgid "AlertSettings|Configure details"
-msgstr ""
+msgstr "Configurați detaliile"
msgid "AlertSettings|Current integrations"
-msgstr ""
+msgstr "Integrări curente"
msgid "AlertSettings|Customize alert payload mapping (optional)"
-msgstr ""
+msgstr "Personalizați cartografierea payload-ului alertei (opțional)"
msgid "AlertSettings|Delete integration"
-msgstr ""
+msgstr "Ștergere integrare"
msgid "AlertSettings|Edit integration"
-msgstr ""
+msgstr "Editare integrare"
msgid "AlertSettings|Edit payload"
-msgstr ""
+msgstr "Editare payload"
msgid "AlertSettings|Enable integration"
-msgstr ""
+msgstr "Activare integrare"
msgid "AlertSettings|Enter an example payload from your selected monitoring tool. This supports sending alerts to a GitLab endpoint."
-msgstr ""
+msgstr "Introduceți un payload exemplu de la instrumentul de monitorizare selectat. Aceasta acceptă trimiterea de alerte către un punct final GitLab."
msgid "AlertSettings|Enter integration name"
-msgstr ""
+msgstr "Introducere nume integrare"
msgid "AlertSettings|Free versions of GitLab are limited to one integration per type. To add more, %{linkStart}upgrade your subscription%{linkEnd}."
-msgstr ""
+msgstr "Versiunile gratuite ale GitLab sunt limitate la o singură integrare pe tip. Pentru a adăuga mai multe, %{linkStart}actualizați-vă abonamentul%{linkEnd}."
msgid "AlertSettings|GitLab has created a URL and authorization key for your integration. You can use them to set up a webhook and authorize your endpoint to send alerts to GitLab."
-msgstr ""
+msgstr "GitLab a creat un URL și o cheie de autorizare pentru integrarea dvs. Le puteți utiliza pentru a configura un webhook și pentru a vă autoriza punctul final să trimită alerte către GitLab."
msgid "AlertSettings|HTTP Endpoint"
-msgstr ""
+msgstr "Punct final HTTP"
msgid "AlertSettings|If you edit the payload, you must re-map the fields again."
-msgstr ""
+msgstr "Dacă editați payload-ul, trebuie să modificați din nou câmpurile."
msgid "AlertSettings|If you reset the authorization key for this project, you must update the key in every enabled alert source."
-msgstr ""
+msgstr "Dacă resetați cheia de autorizare pentru acest proiect, trebuie să actualizați cheia în fiecare sursă de alertă activată."
msgid "AlertSettings|Integration successfully saved"
-msgstr ""
+msgstr "Integrarea salvată cu succes"
msgid "AlertSettings|Name integration"
-msgstr ""
+msgstr "Numire integrare"
msgid "AlertSettings|Parse payload fields"
-msgstr ""
+msgstr "Analizare câmpuri payload"
msgid "AlertSettings|Proceed with editing"
-msgstr ""
+msgstr "Continuați cu editarea"
msgid "AlertSettings|Prometheus"
-msgstr ""
+msgstr "Prometheus"
msgid "AlertSettings|Prometheus API base URL"
-msgstr ""
+msgstr "Adresa URL de bază a API-ului Prometheus"
msgid "AlertSettings|Reset Key"
-msgstr ""
+msgstr "Resetare cheie"
msgid "AlertSettings|Reset the mapping"
-msgstr ""
+msgstr "Resetare cartografiere"
msgid "AlertSettings|Sample payload has been parsed. You can now map the fields."
-msgstr ""
+msgstr "Payload-ul mostră a fost analizat. Acum puteți cartografia câmpurile."
msgid "AlertSettings|Save & create test alert"
-msgstr ""
+msgstr "Salvare și creare alertă de test"
msgid "AlertSettings|Save integration"
-msgstr ""
+msgstr "Salvare integrare"
msgid "AlertSettings|Save integration & send"
-msgstr ""
+msgstr "Salvare integrare și trimitere"
msgid "AlertSettings|Select integration type"
-msgstr ""
+msgstr "Selectare tip integrare"
msgid "AlertSettings|Send test alert"
-msgstr ""
+msgstr "Trimitere alertă test"
msgid "AlertSettings|Send without saving"
-msgstr ""
+msgstr "Trimitere fără salvare"
msgid "AlertSettings|The form has unsaved changes"
-msgstr ""
+msgstr "Formularul are modificări nesalvate"
msgid "AlertSettings|The form has unsaved changes. How would you like to proceed?"
-msgstr ""
+msgstr "Formularul are modificări nesalvate. Cum doriți să continuați?"
msgid "AlertSettings|To create a custom mapping, enter an example payload from your monitoring tool, in JSON format. Select the \"Parse payload fields\" button to continue."
-msgstr ""
+msgstr "Pentru a crea o cartografiere personalizată, introduceți un exemplu de sarcină utilă de la instrumentul de monitorizare, în format JSON. Selectați butonul \"Analizați câmpurile payload\" pentru a continua."
msgid "AlertSettings|URL cannot be blank and must start with http: or https:."
-msgstr ""
+msgstr "URL nu poate fi gol și trebuie să înceapă cu http: sau https:."
msgid "AlertSettings|Use the URL and authorization key below to configure how Prometheus sends alerts to GitLab. Review the %{linkStart}GitLab documentation%{linkEnd} to learn how to configure your endpoint."
-msgstr ""
+msgstr "Utilizați URL-ul și cheia de autorizare de mai jos pentru a configura modul în care Prometheus trimite alerte către GitLab. Consultați %{linkStart}documentația GitLab%{linkEnd} pentru a afla cum să vă configurați punctul final."
msgid "AlertSettings|Use the URL and authorization key below to configure how an external service sends alerts to GitLab. %{linkStart}How do I configure the endpoint?%{linkEnd}"
-msgstr ""
+msgstr "Utilizați URL-ul și cheia de autorizare de mai jos pentru a configura modul în care un serviciu extern trimite alerte către GitLab. %{linkStart}Cum configurez punctul final?%{linkEnd}"
msgid "AlertSettings|View URL and authorization key"
-msgstr ""
+msgstr "Vizualizare URL și cheie de autorizare"
msgid "AlertSettings|View credentials"
-msgstr ""
+msgstr "Vezi acreditările"
msgid "AlertSettings|Webhook URL"
-msgstr ""
+msgstr "URL webhook"
msgid "AlertSettings|You can map default GitLab alert fields to your payload keys in the dropdowns below."
-msgstr ""
+msgstr "Puteți să asociați câmpurile implicite de alertă GitLab cu cheile de payload în dropdown-urile de mai jos."
msgid "AlertSettings|You can now set up alert endpoints for manually configured Prometheus instances in the Alerts section on the Operations settings page. Alert endpoint fields on this page have been deprecated."
-msgstr ""
+msgstr "Acum puteți configura puncte finale de alertă pentru instanțele Prometheus configurate manual în secțiunea Alerte din pagina de setări Operațiuni. Câmpurile de puncte finale de alertă din această pagină au fost învechite."
msgid "AlertSettings|{ \"events\": [{ \"application\": \"Name of application\" }] }"
-msgstr ""
+msgstr "{ \"events\": [{ \"application\": \"Name of application\" }] }"
msgid "Alerts"
-msgstr ""
+msgstr "Alerte"
msgid "AlertsIntegrations|Alerts will be created through this integration"
-msgstr ""
+msgstr "Alertele vor fi create prin această integrare"
msgid "AlertsIntegrations|Alerts will not be created through this integration"
-msgstr ""
+msgstr "Alertele nu vor fi create prin această integrare"
msgid "AlertsIntegrations|If you delete the %{integrationName} integration, alerts are no longer sent from this endpoint. This action cannot be undone."
-msgstr ""
+msgstr "Dacă ștergeți integrarea %{integrationName}, alertele nu mai sunt trimise de la acest punct final. Această acțiune nu poate fi anulată."
msgid "AlertsIntegrations|Integration Name"
-msgstr ""
+msgstr "Nume integrare"
msgid "AlertsIntegrations|Integration payload is invalid."
-msgstr ""
+msgstr "Payload-ul integrării nu este valid."
msgid "AlertsIntegrations|No integrations have been added yet."
-msgstr ""
+msgstr "Încă nu au fost adăugate integrări."
msgid "AlertsIntegrations|The current integration could not be updated. Please try again."
-msgstr ""
+msgstr "Integrarea curentă nu a putut fi actualizată. Vă rugăm să încercați din nou."
msgid "AlertsIntegrations|The integration could not be added. Please try again."
-msgstr ""
+msgstr "Integrarea nu a putut fi adăugată. Vă rugăm să încercați din nou."
msgid "AlertsIntegrations|The integration could not be deleted. Please try again."
-msgstr ""
+msgstr "Integrarea nu a putut fi ștearsă. Vă rugăm să încercați din nou."
msgid "AlertsIntegrations|The integration is currently inactive. Enable the integration to send the test alert."
-msgstr ""
+msgstr "Integrarea este în prezent inactivă. Activați integrarea pentru a trimite alerta de testare."
msgid "AlertsIntegrations|The integration is deleted."
-msgstr ""
+msgstr "Integrarea este ștearsă."
msgid "AlertsIntegrations|The integration is saved."
-msgstr ""
+msgstr "Integrarea este salvată."
msgid "AlertsIntegrations|The integration token could not be reset. Please try again."
-msgstr ""
+msgstr "Nu a fost posibilă resetarea token-ului de integrare. Vă rugăm să încercați din nou."
msgid "AlertsIntegrations|The test alert should now be visible in your alerts list."
-msgstr ""
+msgstr "Alerta de test ar trebui să fie acum vizibilă în lista de alerte."
msgid "Algorithm"
-msgstr ""
+msgstr "Algoritm"
msgid "All"
-msgstr ""
+msgstr "Toate"
msgid "All %{replicableType} are being scheduled for %{action}"
-msgstr ""
+msgstr "Toate %{replicableType} sunt programate pentru %{action}."
msgid "All (default)"
-msgstr ""
+msgstr "Toate (implicit)"
msgid "All Members"
-msgstr ""
+msgstr "Toți membrii"
msgid "All branches"
-msgstr ""
+msgstr "Toate ramurile"
msgid "All changes are committed"
-msgstr ""
+msgstr "Toate schimbările sunt comise"
msgid "All email addresses will be used to identify your commits."
-msgstr ""
+msgstr "Toate adresele de e-mail vor fi folosite pentru a vă identifica contribuțiile."
msgid "All environments"
-msgstr ""
+msgstr "Toate mediile"
msgid "All epics"
-msgstr ""
+msgstr "Toate epicele"
msgid "All groups and projects"
-msgstr ""
+msgstr "Toate grupurile și proiectele"
msgid "All issues for this milestone are closed."
-msgstr ""
+msgstr "Toate problemele pentru acest obiectiv sunt închise."
msgid "All issues for this milestone are closed. You may close this milestone now."
-msgstr ""
+msgstr "Toate problemele legate de acest obiectiv sunt închise. Puteți închide acum acest obiectiv."
msgid "All merge conflicts were resolved. The merge request can now be merged."
-msgstr ""
+msgstr "Toate conflictele merge au fost rezolvate. Merge request-ul poate fi acum îmbinat."
msgid "All merge request dependencies have been merged"
-msgstr ""
+msgstr "Toate dependențele din merge request au fost îmbinate."
msgid "All paths are relative to the GitLab URL. Do not include %{relative_url_link_start}relative URL%{relative_url_link_end}."
-msgstr ""
+msgstr "Toate căile de acces sunt relative la URL-ul GitLab. Nu includeți %{relative_url_link_start}URL relativ%{relative_url_link_end}."
msgid "All projects"
-msgstr ""
+msgstr "Toate proiectele"
msgid "All projects selected"
-msgstr ""
+msgstr "Toate proiectele selectate"
msgid "All threads resolved"
-msgstr ""
+msgstr "Toate subiectele sunt rezolvate"
msgid "All users must accept the Terms of Service and Privacy Policy to access GitLab"
-msgstr ""
+msgstr "Toți utilizatorii trebuie să accepte Termenii și condițiile și Politica de confidențialitate pentru a accesa GitLab"
msgid "All users must have a name."
-msgstr ""
+msgstr "Toți utilizatorii trebuie să aibă un nume."
msgid "Allow \"%{group_name}\" to sign you in"
-msgstr ""
+msgstr "Permiteți \"%{group_name}\" să vă conecteze"
msgid "Allow access to members of the following group"
-msgstr ""
+msgstr "Permiteți accesul membrilor din grupul următor"
msgid "Allow access to the following IP addresses"
-msgstr ""
+msgstr "Permiteți accesul la următoarele adrese IP"
msgid "Allow commits from members who can merge to the target branch."
-msgstr ""
+msgstr "Permiteți commit-uri de la membri care pot îmbina la ramura țintă."
msgid "Allow group owners to manage LDAP-related settings"
-msgstr ""
+msgstr "Permiteți proprietarilor de grup să gestioneze setările legate de LDAP"
msgid "Allow non-administrators to access to the performance bar"
-msgstr ""
+msgstr "Permiteți non-administratorilor accesul la bara de performanță"
msgid "Allow only the selected protocols to be used for Git access."
-msgstr ""
+msgstr "Permiteți utilizarea numai protocoalelor selectate pentru accesul Git."
msgid "Allow owners to manage default branch protection per group"
-msgstr ""
+msgstr "Permiteți proprietarilor să gestioneze protecția implicită a ramurii pentru fiecare grup"
msgid "Allow owners to manually add users outside of LDAP"
-msgstr ""
+msgstr "Permiteți proprietarilor să adauge manual utilizatori în afara LDAP"
msgid "Allow password authentication for Git over HTTP(S)"
-msgstr ""
+msgstr "Permiteți autentificarea prin parolă pentru Git prin HTTP(S)"
msgid "Allow password authentication for the web interface"
-msgstr ""
+msgstr "Permiteți autentificarea prin parolă pentru interfața web"
msgid "Allow project maintainers to configure repository mirroring"
-msgstr ""
+msgstr "Permiteți întreținătorilor proiectului să configureze replicarea repozitoriului"
msgid "Allow projects and subgroups to override the group setting"
-msgstr ""
+msgstr "Permiteți proiectelor și subgrupurilor să suprascrie setarea grupului"
msgid "Allow projects within this group to use Git LFS"
-msgstr ""
+msgstr "Permiteți proiectelor din cadrul acestui grup să utilizeze Git LFS"
msgid "Allow public access to pipelines and job details, including output logs and artifacts."
-msgstr ""
+msgstr "Permiteți accesul public la conducte și detalii de joburi, inclusiv la jurnalele de ieșire și la artefacte."
msgid "Allow requests to the local network from hooks and services."
-msgstr ""
+msgstr "Permiteți solicitări către rețeaua locală din hook-uri și servicii."
msgid "Allow requests to the local network from system hooks"
-msgstr ""
+msgstr "Permitere solicitări către rețeaua locală din hook-uri sistem"
msgid "Allow requests to the local network from web hooks and services"
-msgstr ""
+msgstr "Permiteți solicitări către rețeaua locală de la hook-uri și servicii web"
msgid "Allow subgroups to set up their own two-factor authentication rules"
-msgstr ""
+msgstr "Permiteți subgrupurilor să își configureze propriile reguli de autentificare cu doi factori"
msgid "Allow this key to push to this repository"
-msgstr ""
+msgstr "Permiteți acestei chei să facă push către acest repozitoriu"
msgid "Allow this secondary node to replicate content on Object Storage"
-msgstr ""
+msgstr "Permiteți acestui nod secundar să reproducă conținutul pe Object Storage"
msgid "Allow users to dismiss the broadcast message"
-msgstr ""
+msgstr "Permiteți utilizatorilor să respingă mesajul difuzat"
msgid "Allow users to register any application to use GitLab as an OAuth provider"
-msgstr ""
+msgstr "Permiteți utilizatorilor să înregistreze orice aplicație pentru a utiliza GitLab ca furnizor OAuth"
msgid "Allow users to request access (if visibility is public or internal)"
-msgstr ""
+msgstr "Permiteți utilizatorilor să solicite accesul (dacă vizibilitatea este publică sau internă)"
msgid "Allowed"
-msgstr ""
+msgstr "Permis"
msgid "Allowed Geo IP"
-msgstr ""
+msgstr "Geo IP permis"
msgid "Allowed characters: +, 0-9, -, and spaces."
-msgstr ""
+msgstr "Caracterele permise: +, 0-9, - și spații."
msgid "Allowed email domain restriction only permitted for top-level groups"
-msgstr ""
+msgstr "Restricția domeniului de e-mail permisă numai pentru grupurile de nivel superior"
msgid "Allowed to create:"
-msgstr ""
+msgstr "Permis să creeze:"
msgid "Allowed to fail"
-msgstr ""
+msgstr "Permis să eșueze"
msgid "Allows projects or subgroups in this group to override the global setting."
-msgstr ""
+msgstr "Permite proiectelor sau subgrupurilor din acest grup să suprascrie setarea globală."
msgid "Allows you to add and manage Kubernetes clusters."
-msgstr ""
+msgstr "Vă permite adăugarea și gestionarea clusterelor Kubernetes."
msgid "Almost there"
-msgstr ""
+msgstr "Aproape acolo"
msgid "Almost there..."
-msgstr ""
+msgstr "Aproape acolo..."
msgid "Already blocked"
-msgstr ""
+msgstr "Deja blocat"
msgid "Already have login and password?"
-msgstr ""
+msgstr "Aveți deja login și parolă?"
msgid "Also called \"Issuer\" or \"Relying party trust identifier\""
-msgstr ""
+msgstr "De asemenea, numit \"Emitent\" sau \"Identificator de încredere în partea invocată\""
msgid "Also called \"Relying party service URL\" or \"Reply URL\""
-msgstr ""
+msgstr "De asemenea, numit \"Adresa URL a serviciului parte invocată\" sau \"Adresa URL de răspuns\""
msgid "Also remove direct user membership from subgroups and projects"
-msgstr ""
+msgstr "De asemenea, eliminați apartenența directă a utilizatorilor la subgrupuri și proiecte"
msgid "Also unassign this user from related issues and merge requests"
-msgstr ""
+msgstr "De asemenea anulați afectarea acestui utilizator de la problemele asociate și merge request-uri"
msgid "Alternate support URL for Help page and Help dropdown."
-msgstr ""
+msgstr "URL alternativ de asistență pentru pagina de Ajutor și lista derulantă Ajutor."
msgid "Alternatively, you can convert your account to a managed account by the %{group_name} group."
-msgstr ""
+msgstr "Alternativ, puteți converti contul dvs. într-un cont administrat de grupul %{group_name}."
msgid "Amazon EKS"
-msgstr ""
+msgstr "Amazon EKS"
msgid "Amazon EKS integration allows you to provision EKS clusters from GitLab."
-msgstr ""
+msgstr "Integrarea Amazon EKS vă permite să furnizați clustere EKS din GitLab."
msgid "Amazon Web Services Logo"
-msgstr ""
+msgstr "Logo Amazon Web Services"
msgid "Amazon authentication is not %{link_start}correctly configured%{link_end}. Ask your GitLab administrator if you want to use this service."
-msgstr ""
+msgstr "Autentificarea Amazon nu este %{link_start}configurată corect%{link_end}. Întrebați administratorul GitLab dacă doriți să utilizați acest serviciu."
msgid "Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication"
-msgstr ""
+msgstr "Cantitatea de timp (în ore) în care utilizatorii au voie să sară peste configurația forțată a autentificării în doi pași"
msgid "An %{link_start}alert%{link_end} with the same fingerprint is already open. To change the status of this alert, resolve the linked alert."
-msgstr ""
+msgstr "O alertă %{link_start}alert%{link_end} cu aceeași amprentă digitală este deja deschisă. Pentru a schimba statutul acestei alerte, rezolvați alerta legată."
msgid "An Enterprise User GitLab account has been created for you by your organization:"
-msgstr ""
+msgstr "Un cont GitLab Enterprise a fost creat pentru dvs. de către organizația dvs:"
msgid "An administrator changed the password for your GitLab account on %{link_to}."
-msgstr ""
+msgstr "Un administrator a schimbat parola pentru contul tău GitLab pe %{link_to}."
msgid "An alert has been resolved in %{project_path}."
-msgstr ""
+msgstr "O alertă a fost rezolvată în %{project_path}."
msgid "An alert has been triggered in %{project_path}."
-msgstr ""
+msgstr "O alertă a fost declanșată în %{project_path}."
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
-msgstr ""
+msgstr "O aplicație numită %{link_to_client} solicită accesul la contul dvs GitLab."
msgid "An email notification was recently sent from the admin panel. Please wait %{wait_time_in_words} before attempting to send another message."
-msgstr ""
+msgstr "O notificare prin e-mail a fost trimisă recent din panoul de administrare. Vă rugăm să așteptați %{wait_time_in_words} înainte de a încerca să trimiteți un alt mesaj."
msgid "An empty GitLab User field will add the FogBugz user's full name (e.g. \"By John Smith\") in the description of all issues and comments. It will also associate and/or assign these issues and comments with the project creator."
-msgstr ""
+msgstr "Un câmp gol al utilizatorului GitLab va adăuga numele complet al utilizatorului FogBugz (de ex. \"de John Smith\") în descrierea tuturor problemelor și comentariilor. De asemenea, va asocia și / sau va atribui aceste probleme și comentarii cu creatorul de proiect."
msgid "An empty index will be created if one does not already exist"
-msgstr ""
+msgstr "Se va crea un index gol dacă nu există deja unul"
msgid "An error has occurred"
-msgstr ""
+msgstr "A apărut o eroare"
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
-msgstr ""
+msgstr "O eroare de raportare în care rezultatul unui test indică incorect prezența unei vulnerabilități într-un sistem, când vulnerabilitatea nu este prezentă."
msgid "An error occurred adding a draft to the thread."
-msgstr ""
+msgstr "A apărut o eroare adăugând o schiță la subiect."
msgid "An error occurred adding a new draft."
-msgstr ""
+msgstr "A apărut o eroare adăugând o nouă schiță."
msgid "An error occurred creating the new branch."
-msgstr ""
+msgstr "A apărut o eroare creând ramura nouă."
msgid "An error occurred fetching the approval rules."
-msgstr ""
+msgstr "A apărut o eroare la preluarea regulilor de aprobare."
msgid "An error occurred fetching the approvers for the new rule."
-msgstr ""
+msgstr "A apărut o eroare la preluarea aprobatorilor pentru noua regulă."
msgid "An error occurred fetching the dropdown data."
-msgstr ""
+msgstr "A apărut o eroare la preluarea datelor listei verticale."
msgid "An error occurred fetching the project authors."
-msgstr ""
+msgstr "A apărut o eroare preluând autorii proiectului."
msgid "An error occurred previewing the blob"
-msgstr ""
+msgstr "A apărut o eroare de previzualizare a blobului"
msgid "An error occurred when removing the label."
-msgstr ""
+msgstr "A apărut o eroare la îndepărtarea etichetei."
msgid "An error occurred when toggling the notification subscription"
-msgstr ""
+msgstr "A apărut o eroare la comutarea abonamentului de notificare"
msgid "An error occurred when updating the issue weight"
-msgstr ""
+msgstr "A apărut o eroare la actualizarea greutății problemei"
msgid "An error occurred when updating the title"
-msgstr ""
+msgstr "A apărut o eroare la actualizarea titlului"
msgid "An error occurred while acknowledging the notification. Refresh the page and try again."
-msgstr ""
+msgstr "A apărut o eroare la confirmarea notificării. Reîmprospătați pagina și încercați din nou."
msgid "An error occurred while adding approvers"
-msgstr ""
+msgstr "A apărut o eroare în timpul adăugării aprobatorilor"
msgid "An error occurred while adding formatted title for epic"
-msgstr ""
+msgstr "S-a produs o eroare la adăugarea titlului formatat pentru epică"
msgid "An error occurred while authorizing your role"
-msgstr ""
+msgstr "A apărut o eroare în timpul autorizării rolului dvs."
msgid "An error occurred while checking group path. Please refresh and try again."
-msgstr ""
+msgstr "A apărut o eroare în timpul verificării căii grupului. Vă rugăm reîmprospătați și să încercați din nou."
msgid "An error occurred while decoding the file."
-msgstr ""
+msgstr "A apărut o eroare în timpul decodării fișierului."
msgid "An error occurred while deleting the approvers group"
-msgstr ""
+msgstr "A apărut o eroare la ștergerea grupului de aprobatori"
msgid "An error occurred while deleting the comment"
-msgstr ""
+msgstr "A apărut o eroare la ștergerea comentariului"
msgid "An error occurred while deleting the pipeline."
-msgstr ""
+msgstr "A survenit o eroare la ștergerea conductei."
msgid "An error occurred while detecting host keys"
-msgstr ""
+msgstr "A apărut o eroare la detectarea cheilor gazdă"
msgid "An error occurred while disabling Service Desk."
-msgstr ""
+msgstr "A apărut o eroare la dezactivarea Biroului de Servicii."
msgid "An error occurred while dismissing the alert. Refresh the page and try again."
-msgstr ""
+msgstr "A apărut o eroare la respingerea alertei. Reîmprospătați pagina și încercați din nou."
msgid "An error occurred while dismissing the feature highlight. Refresh the page and try dismissing again."
-msgstr ""
+msgstr "A apărut o eroare la respingerea evidențierii funcțiilor. Reîmprospătați pagina și încercați din nou."
msgid "An error occurred while drawing job relationship links."
-msgstr ""
+msgstr "A apărut o eroare în timpul trasării legăturilor de relații de muncă."
msgid "An error occurred while enabling Service Desk."
-msgstr ""
+msgstr "A apărut o eroare la activarea Biroului de Servicii."
msgid "An error occurred while fetching ancestors"
-msgstr ""
+msgstr "A apărut o eroare în timpul obținerii predecesorilor"
msgid "An error occurred while fetching branches. Retry the search."
-msgstr ""
+msgstr "S-a produs o eroare în timpul preluării ramurilor. Reîncercați căutarea."
msgid "An error occurred while fetching codequality mr diff reports."
-msgstr ""
+msgstr "A apărut o eroare în timpul preluării rapoartelor codequality diff cerere de îmbinare."
msgid "An error occurred while fetching commits. Retry the search."
-msgstr ""
+msgstr "A apărut o eroare în timpul preluării comiterilor. Reîncercați căutarea."
msgid "An error occurred while fetching coverage reports."
-msgstr ""
+msgstr "S-a produs o eroare în timpul obținerii rapoartelor de acoperire."
msgid "An error occurred while fetching environments."
-msgstr ""
+msgstr "S-a produs o eroare în timpul preluării mediilor."
msgid "An error occurred while fetching exposed artifacts."
-msgstr ""
+msgstr "S-a produs o eroare în timpul preluării artefactelor expuse."
msgid "An error occurred while fetching folder content."
-msgstr ""
+msgstr "S-a produs o eroare la preluarea conținutului dosarului."
msgid "An error occurred while fetching issues."
-msgstr ""
+msgstr "S-a produs o eroare în timpul preluării problemelor."
msgid "An error occurred while fetching label colors."
-msgstr ""
+msgstr "A apărut o eroare la preluarea culorilor etichetelor."
msgid "An error occurred while fetching markdown preview"
-msgstr ""
+msgstr "A apărut o eroare la preluarea previzualizării markdown"
msgid "An error occurred while fetching participants"
-msgstr ""
+msgstr "A apărut o eroare în timpul preluării participanților"
msgid "An error occurred while fetching participants."
-msgstr ""
+msgstr "A apărut o eroare în timpul preluării participanților"
msgid "An error occurred while fetching pending comments"
-msgstr ""
+msgstr "A apărut o eroare la preluarea comentariilor în așteptare"
msgid "An error occurred while fetching projects autocomplete."
-msgstr ""
+msgstr "A apărut o eroare în timpul preluării autocompletării proiectelor."
msgid "An error occurred while fetching reference"
-msgstr ""
+msgstr "A apărut o eroare în timpul preluării referinței"
msgid "An error occurred while fetching sidebar data"
-msgstr ""
+msgstr "A apărut o eroare la preluarea datelor barei laterale"
msgid "An error occurred while fetching tags. Retry the search."
-msgstr ""
+msgstr "S-a produs o eroare în timpul preluării etichetelor. Reîncercați căutarea."
msgid "An error occurred while fetching terraform reports."
-msgstr ""
-
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
+msgstr "S-a produs o eroare în timpul preluării rapoartelor terraform."
msgid "An error occurred while fetching the job log."
-msgstr ""
+msgstr "A apărut o eroare la preluarea jurnalului de job."
msgid "An error occurred while fetching the job logs."
-msgstr ""
+msgstr "A apărut o eroare în timpul preluării jurnalelor de lucru."
msgid "An error occurred while fetching the job."
-msgstr ""
+msgstr "A apărut o eroare la preluarea jobului."
msgid "An error occurred while fetching the jobs."
-msgstr ""
+msgstr "A apărut o eroare la preluarea joburilor."
msgid "An error occurred while fetching the latest pipeline."
-msgstr ""
-
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
+msgstr "A apărut o eroare la preluarea celei mai recente conducte."
msgid "An error occurred while fetching the releases. Please try again."
-msgstr ""
+msgstr "A apărut o eroare la preluarea lansărilor. Vă rugăm încercați din nou."
msgid "An error occurred while fetching this tab."
-msgstr ""
+msgstr "A apărut o eroare la preluarea acestei file."
msgid "An error occurred while generating a username. Please try again."
-msgstr ""
+msgstr "A apărut o eroare în timpul generării unui nume de utilizator. Vă rugăm să încercați din nou."
msgid "An error occurred while getting autocomplete data. Please refresh the page and try again."
-msgstr ""
+msgstr "S-a produs o eroare în timpul obținerii datelor de autocompletare. Vă rugăm să reîmprospătați pagina și să încercați din nou."
msgid "An error occurred while getting files for - %{branchId}"
-msgstr ""
+msgstr "A apărut o eroare în timpul obținerii fișierelor pentru - %{branchId}"
msgid "An error occurred while getting issue counts"
-msgstr ""
+msgstr "S-a produs o eroare în timpul obținerii contoarelor de probleme"
msgid "An error occurred while getting projects"
-msgstr ""
+msgstr "A apărut o eroare la primirea proiectelor"
msgid "An error occurred while initializing path locks"
-msgstr ""
+msgstr "A apărut o eroare inițializând lacătele căii"
msgid "An error occurred while loading a section of this page."
-msgstr ""
+msgstr "S-a produs o eroare în timpul încărcării unei secțiuni a acestei pagini."
msgid "An error occurred while loading all the files."
-msgstr ""
+msgstr "A apărut o eroare în timpul încărcării tuturor fișierelor."
msgid "An error occurred while loading chart data"
-msgstr ""
+msgstr "A apărut o eroare la încărcarea datelor din diagramă"
msgid "An error occurred while loading commit signatures"
-msgstr ""
+msgstr "A apărut o eroare la încărcarea semnăturilor commit-ului"
msgid "An error occurred while loading designs. Please try again."
-msgstr ""
+msgstr "A apărut o eroare la încărcarea design-urilor. Vă rugăm să încercați din nou."
msgid "An error occurred while loading diff"
-msgstr ""
+msgstr "A apărut o eroare la încărcarea diff-ului"
msgid "An error occurred while loading filenames"
-msgstr ""
+msgstr "A apărut o eroare la încărcarea numelor de fișiere"
msgid "An error occurred while loading group members."
-msgstr ""
+msgstr "S-a produs o eroare în timpul încărcării membrilor grupului."
msgid "An error occurred while loading issues"
-msgstr ""
+msgstr "S-a produs o eroare în timpul încărcării problemelor"
msgid "An error occurred while loading merge requests."
+msgstr "S-a produs o eroare în timpul încărcării merge request-urilor."
+
+msgid "An error occurred while loading the Needs tab."
msgstr ""
-msgid "An error occurred while loading the access tokens form, please try again."
+msgid "An error occurred while loading the Test Reports tab."
msgstr ""
+msgid "An error occurred while loading the access tokens form, please try again."
+msgstr "A apărut o eroare în timpul încărcării formularului cu token-uri de acces, vă rugăm să încercați din nou."
+
msgid "An error occurred while loading the data. Please try again."
-msgstr ""
+msgstr "S-a produs o eroare în timpul încărcării datelor. Vă rugăm să încercați din nou."
msgid "An error occurred while loading the file"
-msgstr ""
+msgstr "A apărut o eroare la încărcarea fișierului"
msgid "An error occurred while loading the file content."
-msgstr ""
+msgstr "A apărut o eroare la încărcarea conținutului fișierului."
msgid "An error occurred while loading the file."
-msgstr ""
+msgstr "A apărut o eroare la încărcarea fișierului."
msgid "An error occurred while loading the file. Please try again later."
-msgstr ""
+msgstr "A apărut o eroare la încărcarea fișierului. Vă rugăm să încercați din nou mai târziu."
msgid "An error occurred while loading the file. Please try again."
-msgstr ""
+msgstr "A apărut o eroare la încărcarea fișierului. Vă rugăm să încercați din nou."
msgid "An error occurred while loading the merge request changes."
-msgstr ""
+msgstr "A apărut o eroare la încărcarea modificărilor merge request-ului."
msgid "An error occurred while loading the merge request version data."
-msgstr ""
+msgstr "S-a produs o eroare la încărcarea datelor privind versiunea merge request-ului."
msgid "An error occurred while loading the merge request."
-msgstr ""
+msgstr "A apărut o eroare la încărcarea merge request-ului."
msgid "An error occurred while loading the notification settings. Please try again."
-msgstr ""
+msgstr "A apărut o eroare la încărcarea setărilor de notificare. Vă rugăm să încercați din nou."
msgid "An error occurred while loading the pipeline."
-msgstr ""
+msgstr "A apărut o eroare la încărcarea conductei."
msgid "An error occurred while loading the pipelines jobs."
-msgstr ""
+msgstr "A apărut o eroare la încărcarea joburilor conductei."
msgid "An error occurred while loading your content. Please try again."
-msgstr ""
+msgstr "S-a produs o eroare în timpul încărcării conținutului dvs. Vă rugăm să încercați din nou."
msgid "An error occurred while making the request."
-msgstr ""
+msgstr "A apărut o eroare la momentul solicitării."
msgid "An error occurred while moving the issue."
-msgstr ""
+msgstr "A apărut o eroare la mutarea problemei."
msgid "An error occurred while parsing recent searches"
-msgstr ""
+msgstr "A apărut o eroare la analizarea căutărilor recente"
msgid "An error occurred while parsing the file."
-msgstr ""
+msgstr "A apărut o eroare în timpul analizării fișierului."
msgid "An error occurred while removing epics."
-msgstr ""
+msgstr "A apărut o eroare la eliminarea epicelor."
msgid "An error occurred while removing issues."
-msgstr ""
+msgstr "A apărut o eroare la eliminarea problemelor."
msgid "An error occurred while rendering preview broadcast message"
-msgstr ""
+msgstr "A apărut o eroare în timpul redării mesajului de transmisie de previzualizare"
msgid "An error occurred while rendering the editor"
-msgstr ""
+msgstr "A apărut o eroare în timpul redării editorului"
msgid "An error occurred while reordering issues."
-msgstr ""
+msgstr "A apărut o eroare în timpul reordonării problemelor."
msgid "An error occurred while retrieving calendar activity"
-msgstr ""
+msgstr "A apărut o eroare la preluarea activităților din calendar"
msgid "An error occurred while retrieving diff"
-msgstr ""
+msgstr "A apărut o eroare în timpul preluării diff"
msgid "An error occurred while retrieving diff files"
-msgstr ""
+msgstr "S-a produs o eroare în timpul recuperării fișierelor diff"
msgid "An error occurred while retrieving projects."
-msgstr ""
+msgstr "A apărut o eroare în timpul recuperării proiectelor."
msgid "An error occurred while saving changes: %{error}"
-msgstr ""
+msgstr "A apărut o eroare în timpul salvării modificărilor: %{error}"
msgid "An error occurred while subscribing to notifications."
-msgstr ""
+msgstr "A apărut o eroare la abonarea la notificări."
msgid "An error occurred while triggering the job."
-msgstr ""
+msgstr "A apărut o eroare la declanșarea lucrării."
msgid "An error occurred while trying to generate the report. Please try again later."
-msgstr ""
+msgstr "A apărut o eroare în timpul încercării de generare a raportului. Vă rugăm să încercați din nou mai târziu."
msgid "An error occurred while trying to run a new pipeline for this merge request."
-msgstr ""
+msgstr "A apărut o eroare în timpul încercării de a rula o nouă conductă pentru acest merge request."
msgid "An error occurred while unsubscribing to notifications."
-msgstr ""
+msgstr "A apărut o eroare la dezabonarea notificărilor."
msgid "An error occurred while updating approvers"
-msgstr ""
+msgstr "A apărut o eroare la actualizarea aprobatorilor"
msgid "An error occurred while updating assignees."
-msgstr ""
+msgstr "A apărut o eroare la actualizarea responsabililor."
msgid "An error occurred while updating configuration."
-msgstr ""
+msgstr "S-a produs o eroare în timpul actualizării configurației."
msgid "An error occurred while updating labels."
-msgstr ""
+msgstr "S-a produs o eroare în timpul actualizării etichetelor."
msgid "An error occurred while updating the comment"
-msgstr ""
+msgstr "A apărut o eroare la actualizarea comentariului"
msgid "An error occurred while updating the configuration."
-msgstr ""
+msgstr "A apărut o eroare în timpul actualizării configurației."
msgid "An error occurred while updating the notification settings. Please try again."
-msgstr ""
+msgstr "A apărut o eroare în timpul actualizării setărilor de notificare. Vă rugăm să încercați din nou."
msgid "An error occurred while uploading the file. Please try again."
-msgstr ""
+msgstr "S-a întâmplat o eroare în timpul încărcării fișierului. Vă rugăm încercați din nou."
msgid "An error occurred while uploading the image. Please try again."
-msgstr ""
+msgstr "S-a întâmplat o eroare în timpul încărcării imaginii. Vă rugăm încercați din nou."
msgid "An error occurred while validating group path"
-msgstr ""
+msgstr "A apărut o eroare în timpul validării căii de acces la grup"
msgid "An error occurred while validating username"
-msgstr ""
+msgstr "A apărut o eroare la validarea numelui de utilizator"
msgid "An error occurred. Please sign in again."
-msgstr ""
+msgstr "S-a produs o eroare. Vă rugăm să vă autentificați din nou."
msgid "An error occurred. Please try again."
-msgstr ""
+msgstr "A apărut o eroare. Vă rugăm să încercați din nou."
msgid "An example project for managing Kubernetes clusters integrated with GitLab"
-msgstr ""
+msgstr "Un exemplu de proiect pentru gestionarea clusterelor Kubernetes integrat cu GitLab"
msgid "An example project that shows off the best practices for setting up GitLab for your own organization, including sample issues, merge requests, and milestones"
-msgstr ""
+msgstr "Un proiect de exemplu care prezintă cele mai bune practici pentru configurarea GitLab pentru propria organizație, inclusiv exemple de probleme, merge request-uri și obiectivuri."
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
-msgstr ""
+msgstr "Un exemplu care arată cum să utilizați Jsonnet cu conducte dinamice copii ale GitLab"
msgid "An instance-level serverless domain already exists."
-msgstr ""
+msgstr "Există deja un domeniu fără server la nivel de instanță."
msgid "An issue already exists"
-msgstr ""
+msgstr "Există deja o problemă"
msgid "An unauthenticated user"
-msgstr ""
+msgstr "Un utilizator neautentificat"
msgid "An unexpected error occurred while checking the project environment."
-msgstr ""
+msgstr "A apărut o eroare neașteptată în timpul verificării mediului de proiect."
msgid "An unexpected error occurred while checking the project runners."
-msgstr ""
+msgstr "A apărut o eroare neașteptată în timpul verificării participanților la proiect."
msgid "An unexpected error occurred while communicating with the Web Terminal."
-msgstr ""
+msgstr "A apărut o eroare neașteptată în timpul comunicării cu Terminalul Web."
msgid "An unexpected error occurred while loading the code quality diff."
-msgstr ""
+msgstr "S-a întâmplat o eroare neașteptată în timpul încărcării quality diff-ul codului."
msgid "An unexpected error occurred while starting the Web Terminal."
-msgstr ""
+msgstr "A apărut o eroare neașteptată la pornirea Terminalului Web."
msgid "An unexpected error occurred while stopping the Web Terminal."
-msgstr ""
+msgstr "A apărut o eroare neașteptată în timpul opririi Terminalului Web."
msgid "An unknown error occurred while loading this graph."
-msgstr ""
+msgstr "A apărut o eroare necunoscută la încărcarea acestui grafic."
msgid "An unknown error occurred."
-msgstr ""
+msgstr "A apărut o eroare necunoscută."
msgid "Analytics"
-msgstr ""
+msgstr "Statistici"
msgid "Analyze a review version of your web application."
-msgstr ""
+msgstr "Analizați o versiune de revizuire a aplicației dvs. web."
msgid "Analyze your dependencies for known vulnerabilities."
-msgstr ""
+msgstr "Analizați-vă dependențele pentru vulnerabilități cunoscute."
msgid "Analyze your source code and git history for secrets."
-msgstr ""
+msgstr "Analizați-vă codul sursă și istoricul git pentru a găsi secrete."
msgid "Analyze your source code for known vulnerabilities."
-msgstr ""
+msgstr "Analizați-vă codul sursă pentru vulnerabilități cunoscute."
msgid "Analyzing file…"
-msgstr ""
+msgstr "Se analizează fișierul…"
msgid "Ancestors"
-msgstr ""
+msgstr "Ancestori"
msgid "And this registration token:"
-msgstr ""
+msgstr "Și acest token de înregistrare:"
msgid "Anonymous"
-msgstr ""
+msgstr "Anonim"
msgid "Another action is currently in progress"
-msgstr ""
+msgstr "O altă acțiune este în curs de desfășurare"
msgid "Another issue tracker is already in use. Only one issue tracker service can be active at a time"
-msgstr ""
+msgstr "Un alt sistem de urmărire a problemelor este deja în uz. Un singur serviciu de urmărire a problemelor poate fi activ în același timp"
msgid "Anti-spam verification"
-msgstr ""
+msgstr "Verificare anti-spam"
msgid "Any"
-msgstr ""
+msgstr "Orice"
msgid "Any %{header}"
-msgstr ""
+msgstr "Orice %{header}"
msgid "Any Author"
-msgstr ""
+msgstr "Orice autor"
msgid "Any Milestone"
-msgstr ""
+msgstr "Orice obiectiv"
msgid "Any branch"
-msgstr ""
+msgstr "Orice ramură"
msgid "Any eligible user"
-msgstr ""
+msgstr "Orice utilizator eligibil"
msgid "Any encrypted tokens"
-msgstr ""
+msgstr "Orice token-uri criptate"
msgid "Any files larger than this limit only index the file name. The file content is neither indexed nor searchable."
-msgstr ""
+msgstr "Orice fișiere mai mari decât această limită indexează numele fișierului. Conținutul fișierului nu este nici indexat, nici disponibil pentru căutare."
msgid "Any label"
-msgstr ""
+msgstr "Orice etichetă"
msgid "Any member with at least Developer permissions on the project."
-msgstr ""
+msgstr "Orice membru cu cel puțin permisiuni de dezvoltator pentru proiect."
msgid "Any milestone"
-msgstr ""
+msgstr "Orice obiectiv"
msgid "Any namespace"
-msgstr ""
+msgstr "Orice spațiu de nume"
msgid "App ID"
-msgstr ""
+msgstr "ID Aplicație"
msgid "Appearance"
-msgstr ""
+msgstr "Aspect"
msgid "Appearance was successfully created."
-msgstr ""
+msgstr "Aspectul a fost creat cu succes."
msgid "Appearance was successfully updated."
-msgstr ""
+msgstr "Aspectul a fost actualizat cu succes."
msgid "Append the comment with %{shrug}"
-msgstr ""
+msgstr "Adăugați comentariul cu %{shrug}"
msgid "Append the comment with %{tableflip}"
-msgstr ""
+msgstr "Adăugați comentariul la %{tableflip}"
msgid "Application"
-msgstr ""
+msgstr "Aplicație"
msgid "Application ID"
-msgstr ""
+msgstr "ID aplicație"
msgid "Application limits saved successfully"
-msgstr ""
+msgstr "Limitele aplicației au fost salvate cu succes"
msgid "Application settings saved successfully"
-msgstr ""
+msgstr "Setările aplicației au fost salvate cu succes"
msgid "Application settings update failed"
-msgstr ""
+msgstr "Actualizarea setărilor aplicației a eșuat"
msgid "Application uninstalled but failed to destroy: %{error_message}"
-msgstr ""
+msgstr "Aplicație dezinstalată, dar nu a reușit să distrugă: %{error_message}"
msgid "Application was successfully destroyed."
-msgstr ""
+msgstr "Aplicația a fost distrusă cu succes."
msgid "Application was successfully updated."
-msgstr ""
+msgstr "Aplicația a fost actualizată cu succes."
msgid "Application: %{name}"
-msgstr ""
+msgstr "Aplicație: %{name}"
msgid "ApplicationSettings|After sign up text"
-msgstr ""
+msgstr "După înregistrarea textului"
msgid "ApplicationSettings|Allowed domains for sign-ups"
-msgstr ""
+msgstr "Domenii permise pentru înscrieri"
msgid "ApplicationSettings|Approve %d user"
msgid_plural "ApplicationSettings|Approve %d users"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "Aprobați %d utilizatori"
+msgstr[1] "Aprobați %d utilizatori"
+msgstr[2] "Aprobați %d de utilizatori"
msgid "ApplicationSettings|Approve users in the pending approval status?"
-msgstr ""
+msgstr "Aprobați utilizatorii în statusul de aprobare în așteptare?"
msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "Făcând această modificare, veți aproba automat %d utilizator cu statusul de aprobare în așteptare."
+msgstr[1] "Făcând această modificare, veți aproba automat %d utilizatori cu statusul de aprobare în așteptare."
+msgstr[2] "Făcând această modificare, veți aproba automat %d de utilizatori cu statusul de aprobare în așteptare."
msgid "ApplicationSettings|Denied domains for sign-ups"
-msgstr ""
+msgstr "Domenii refuzate pentru înscrieri"
msgid "ApplicationSettings|Denylist file"
-msgstr ""
+msgstr "Fișier denylist"
msgid "ApplicationSettings|Domain denylist"
-msgstr ""
+msgstr "Denylist domeniu"
msgid "ApplicationSettings|Email restrictions"
-msgstr ""
+msgstr "Restricții de e-mail"
msgid "ApplicationSettings|Email restrictions for sign-ups"
-msgstr ""
+msgstr "Restricții de e-mail pentru înscrieri"
msgid "ApplicationSettings|Enable domain denylist for sign ups"
-msgstr ""
+msgstr "Activați denylist-ul domeniului pentru înscrieri"
msgid "ApplicationSettings|Enable email restrictions for sign ups"
-msgstr ""
+msgstr "Activați restricțiile de e-mail pentru înscrieri"
msgid "ApplicationSettings|Enter denylist manually"
-msgstr ""
+msgstr "Introduceți manual denylist-ul"
msgid "ApplicationSettings|Markdown enabled"
-msgstr ""
+msgstr "Markdown activat"
msgid "ApplicationSettings|Minimum password length (number of characters)"
-msgstr ""
+msgstr "Lungimea minimă a parolei (număr de caractere)"
msgid "ApplicationSettings|ONLY users with e-mail addresses that match these domain(s) will be able to sign-up. Wildcards allowed. Use separate lines for multiple entries. Ex: domain.com, *.domain.com"
-msgstr ""
+msgstr "DOAR utilizatorii cu adrese de e-mail care se potrivesc cu aceste domenii vor putea să se înscrie. Sunt permise wildcard-uri. Folosiți linii separate pentru intrări multiple. Ex: domain.com, *.domain.com"
msgid "ApplicationSettings|Once the instance reaches the user cap, any user who is added or requests access will have to be approved by an admin. Leave the field empty for unlimited."
-msgstr ""
+msgstr "După ce instanța atinge limita de utilizatori, orice utilizator care este adăugat sau solicită acces va trebui să fie aprobat de un administrator. Lăsați câmpul gol pentru nelimitat."
msgid "ApplicationSettings|Require admin approval for new sign-ups"
-msgstr ""
+msgstr "Necesită aprobarea administratorului pentru noile înscrieri"
msgid "ApplicationSettings|Restricts sign-ups for email addresses that match the given regex. See the %{linkStart}supported syntax%{linkEnd} for more information."
-msgstr ""
+msgstr "Restrânge înscrierile pentru adresele de e-mail care se potrivesc cu regex-ul dat. Pentru mai multe informații, consultați sintaxa %{linkStart}supported%{linkEnd}."
msgid "ApplicationSettings|Save changes"
-msgstr ""
+msgstr "Salvare modificări"
msgid "ApplicationSettings|See GitLab's %{linkStart}Password Policy Guidelines%{linkEnd}"
-msgstr ""
+msgstr "Vezi %{linkStart}Instrucțiunile politicilor de parolă%{linkEnd} ale GitLab"
msgid "ApplicationSettings|Send confirmation email on sign-up"
-msgstr ""
+msgstr "Trimiteți un e-mail de confirmare la înscriere"
msgid "ApplicationSettings|Sign-up enabled"
-msgstr ""
+msgstr "Înregistrare activată"
msgid "ApplicationSettings|Upload denylist file"
-msgstr ""
+msgstr "Încărcați fișierul denylist"
msgid "ApplicationSettings|User cap"
-msgstr ""
+msgstr "Limită utilizatori"
msgid "ApplicationSettings|Users with e-mail addresses that match these domain(s) will NOT be able to sign-up. Wildcards allowed. Use separate lines for multiple entries. Ex: domain.com, *.domain.com"
-msgstr ""
+msgstr "Utilizatorii cu adrese de e-mail care se potrivesc cu aceste domenii NU se vor putea înscrie. Sunt permise wildcard-uri. Folosiți linii separate pentru intrări multiple. Ex: domain.com, *.domain.com"
msgid "ApplicationSettings|Users with e-mail addresses that match these domain(s) will NOT be able to sign-up. Wildcards allowed. Use separate lines or commas for multiple entries."
-msgstr ""
+msgstr "Utilizatorii cu adrese de e-mail care se potrivesc cu aceste domenii NU se vor putea înscrie. Sunt permise wildcard-uri. Utilizați linii separate sau virgule pentru intrări multiple."
msgid "ApplicationSettings|When enabled, any user visiting %{host} and creating an account will have to be explicitly approved by an admin before they can sign in. This setting is effective only if sign-ups are enabled."
-msgstr ""
+msgstr "Atunci când este activat, orice utilizator care vizitează %{host} și creează un cont va trebui să fie aprobat în mod explicit de către un administrator înainte de a se putea conecta. Această setare este eficientă numai înscrierile sunt activate."
msgid "ApplicationSettings|When enabled, any user visiting %{host} will be able to create an account."
-msgstr ""
+msgstr "Când este activat, orice utilizator care vizitează %{host} va putea crea un cont."
msgid "ApplicationSettings|domain.com"
-msgstr ""
+msgstr "domain.com"
msgid "Applications"
-msgstr ""
+msgstr "Aplicații"
msgid "Applied"
-msgstr ""
+msgstr "Aplicat"
msgid "Apply"
-msgstr ""
+msgstr "Aplică"
msgid "Apply a label"
-msgstr ""
+msgstr "Aplicați o etichetă"
msgid "Apply a template"
-msgstr ""
+msgstr "Aplicați un șablon"
msgid "Apply suggestion"
-msgstr ""
+msgstr "Aplicați sugestia"
msgid "Apply suggestions"
-msgstr ""
+msgstr "Aplică sugestii"
msgid "Apply template"
-msgstr ""
+msgstr "Aplicați șablonul"
msgid "Apply this approval rule to any branch or a specific protected branch."
-msgstr ""
+msgstr "Aplicați această regulă de aprobare la orice ramură sau la o anumită ramură protejată."
msgid "Applying"
-msgstr ""
+msgstr "Aplicare"
msgid "Applying a template will replace the existing issue description. Any changes you have made will be lost."
-msgstr ""
+msgstr "Aplicarea unui șablon va înlocui descrierea existentă a problemei. Toate modificările pe care le-ați făcut vor fi pierdute."
msgid "Applying command"
-msgstr ""
+msgstr "Aplicarea comenzii"
msgid "Applying command to %{commandDescription}"
-msgstr ""
+msgstr "Aplicarea comenzii la %{commandDescription}"
msgid "Applying multiple commands"
-msgstr ""
+msgstr "Aplicarea mai multor comenzi"
msgid "Applying suggestion..."
-msgstr ""
+msgstr "Aplicând sugestia..."
msgid "Applying suggestions..."
-msgstr ""
+msgstr "Aplicarea sugestiilor..."
msgid "Approval Status"
-msgstr ""
+msgstr "Statusul aprobării"
msgid "Approval rules"
-msgstr ""
+msgstr "Reguli de aprobare"
msgid "Approval rules reset to project defaults"
-msgstr ""
+msgstr "Regulile de aprobare se resetează la valorile implicite ale proiectului"
msgid "Approval settings"
-msgstr ""
+msgstr "Setări de aprobare"
msgid "ApprovalRuleRemove|%d member"
msgid_plural "ApprovalRuleRemove|%d members"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d membru"
+msgstr[1] "%d membri"
+msgstr[2] "%d de membrii"
msgid "ApprovalRuleRemove|You are about to remove the %{name} approver group which has %{strongStart}%{count} member%{strongEnd}. Approvals from this member are not revoked."
msgid_plural "ApprovalRuleRemove|You are about to remove the %{name} approver group which has %{strongStart}%{count} members%{strongEnd}. Approvals from these members are not revoked."
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "Sunteți pe cale de a elimina grupul de aprobatori %{name} care are %{strongStart}%{count} membru%{strongEnd}. Aprobările de la acest membru nu sunt revocate."
+msgstr[1] "Sunteți pe cale de a elimina grupul de aprobatori %{name} care are %{strongStart}%{count} membri%{strongEnd}. Aprobările de la acești membri nu sunt revocate."
+msgstr[2] "Sunteți pe cale de a elimina grupul de aprobatori %{name} care are %{strongStart}%{count} de membri%{strongEnd}. Aprobările de la acești membri nu sunt revocate."
msgid "ApprovalRuleSummary|%d member"
msgid_plural "ApprovalRuleSummary|%d members"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%d membru"
+msgstr[1] "%d membri"
+msgstr[2] "%d de membrii"
msgid "ApprovalRuleSummary|%{count} approval required from %{membersCount}"
msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCount}"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "%{count} aprobare necesară de la %{membersCount}"
+msgstr[1] "%{count} aprobări necesare de la %{membersCount}"
+msgstr[2] "%{count} de aprobări necesare de la %{membersCount}"
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
-msgstr ""
+msgstr "Adăugați aprobatori"
msgid "ApprovalRule|All scanners"
+msgstr "Toate scanerele"
+
+msgid "ApprovalRule|All severity levels"
msgstr ""
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
+msgstr "Aplicați această regulă de aprobare pentru a lua în considerare doar scanerele de securitate selectate."
+
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
msgstr ""
msgid "ApprovalRule|Approval rules"
-msgstr ""
+msgstr "Reguli de aprobare"
msgid "ApprovalRule|Approvals required"
-msgstr ""
+msgstr "Aprobări necesare"
msgid "ApprovalRule|Approver Type"
-msgstr ""
+msgstr "Tip aprobator"
msgid "ApprovalRule|Approvers"
-msgstr ""
+msgstr "Aprobatori"
msgid "ApprovalRule|Examples: QA, Security."
-msgstr ""
+msgstr "Exemple: QA, Securitate."
msgid "ApprovalRule|Name"
-msgstr ""
+msgstr "Nume"
msgid "ApprovalRule|Number of vulnerabilities allowed before approval rule is triggered."
-msgstr ""
+msgstr "Numărul de vulnerabilități permise înainte de declanșarea regulii de aprobare."
msgid "ApprovalRule|Please enter a number equal or greater than zero"
-msgstr ""
+msgstr "Vă rugăm să introduceți un număr egal sau mai mare decât zero"
msgid "ApprovalRule|Please select at least one security scanner"
+msgstr "Vă rugăm să selectați cel puțin un scaner de securitate"
+
+msgid "ApprovalRule|Please select at least one severity level"
msgstr ""
msgid "ApprovalRule|Rule name"
-msgstr ""
+msgstr "Numele regulii"
msgid "ApprovalRule|Security scanners"
-msgstr ""
+msgstr "Scanere de securitate"
msgid "ApprovalRule|Select All"
-msgstr ""
+msgstr "Selectați tot"
msgid "ApprovalRule|Select scanners"
+msgstr "Selectați scanerele"
+
+msgid "ApprovalRule|Select severity levels"
msgstr ""
-msgid "ApprovalRule|Target branch"
+msgid "ApprovalRule|Severity levels"
msgstr ""
+msgid "ApprovalRule|Target branch"
+msgstr "Ramura țintă"
+
msgid "ApprovalRule|Vulnerabilities allowed"
-msgstr ""
+msgstr "Vulnerabilități permise"
msgid "ApprovalSettings|Merge request approval settings have been updated."
+msgstr "Setările de aprobare a cererilor de îmbinare au fost actualizate."
+
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
msgstr ""
-msgid "ApprovalSettings|There was an error loading merge request approval settings."
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
+msgid "ApprovalSettings|There was an error loading merge request approval settings."
+msgstr "S-a întâmplat o eroare încărcând setările de aprobare a cererilor de îmbinare."
+
msgid "ApprovalSettings|There was an error updating merge request approval settings."
-msgstr ""
+msgstr "S-a întâmplat o eroare actualizând setările de aprobare a cererilor de îmbinare."
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
-msgstr ""
+msgstr "Această setare este configurată la nivel de instanță și poate fi schimbată doar de un administrator."
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
-msgstr ""
+msgstr "Aderă la separarea sarcinilor"
msgid "ApprovalStatusTooltip|At least one rule does not adhere to separation of duties"
-msgstr ""
+msgstr "Cel puțin o regulă nu respectă separarea atribuțiilor"
msgid "ApprovalStatusTooltip|Fails to adhere to separation of duties"
-msgstr ""
+msgstr "Nu respectă separarea atribuțiilor"
msgid "Approvals are optional."
-msgstr ""
+msgstr "Aprobările sunt opționale."
msgid "Approvals|Section: %section"
-msgstr ""
+msgstr "Secțiunea: %secțiune"
msgid "Approve"
-msgstr ""
+msgstr "Aprobați"
msgid "Approve a merge request"
-msgstr ""
+msgstr "Aprobați un merge request"
msgid "Approve the current merge request."
-msgstr ""
+msgstr "Aprobați merge request-ul actual."
msgid "Approved"
-msgstr ""
+msgstr "Aprobat"
msgid "Approved MRs"
-msgstr ""
+msgstr "MR-uri aprobate"
msgid "Approved the current merge request."
-msgstr ""
+msgstr "A fost aprobat merge request-ul actual."
msgid "Approved-By"
-msgstr ""
+msgstr "Aprobat de"
msgid "Approver"
-msgstr ""
+msgstr "Aprobator"
msgid "Approvers"
-msgstr ""
+msgstr "Aprobatori"
msgid "Approvers from private group(s) not shown"
-msgstr ""
+msgstr "Aprobatorii din grupul (grupurile) privat(e) nu sunt afișați"
msgid "Apr"
-msgstr ""
+msgstr "apr"
msgid "April"
-msgstr ""
+msgstr "Aprilie"
msgid "Architecture not found for OS"
-msgstr ""
+msgstr "Arhitectura nu a fost găsită pentru OS"
msgid "Archive"
-msgstr ""
+msgstr "Arhiva"
msgid "Archive jobs"
-msgstr ""
+msgstr "Arhivare joburi"
msgid "Archive project"
-msgstr ""
+msgstr "Arhivare proiect"
msgid "Archive test case"
-msgstr ""
+msgstr "Arhivare caz testare"
msgid "Archived"
-msgstr ""
+msgstr "Arhivat"
msgid "Archived (%{movedToStart}moved%{movedToEnd})"
-msgstr ""
+msgstr "Arhivat (%{movedToStart}mutat%{movedToEnd})"
msgid "Archived in this version"
-msgstr ""
+msgstr "Arhivat în această versiune"
msgid "Archived project! Repository and other project resources are read-only"
-msgstr ""
+msgstr "Proiect arhivat! Depozitul și alte resurse ale proiectului sunt doar-citire"
msgid "Archived projects"
-msgstr ""
+msgstr "Proiecte arhivate"
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "Arhivarea proiectului va face ca acesta să fie în întregime numai pentru citire. Acesta este ascuns din tabloul de bord și nu apare în căutări. %{strong_start}repozitoriul nu poate accepta commit-uri și nu pot fi create probleme, comentarii sau alte entități.%{strong_end} %{link_start}Aflați mai multe.%{link_end}"
msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
-msgstr ""
+msgstr "Sunteți ABSOLUT SIGUR că doriți să ștergeți acest proiect?"
msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
-msgstr ""
+msgstr "Sunteți ABSOLUT SIGUR că doriți să ștergeți acest grup?"
msgid "Are you sure that you want to archive this project?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să arhivați acest proiect?"
msgid "Are you sure that you want to unarchive this project?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să dezarhivați acest proiect?"
msgid "Are you sure you want to %{action} %{name}?"
+msgstr "Sunteți sigur că doriți să %{action} %{name}?"
+
+msgid "Are you sure you want to attempt to merge?"
msgstr ""
msgid "Are you sure you want to cancel editing this comment?"
-msgstr ""
+msgstr "Sigur doriți să anulați editarea acestui comentariu?"
msgid "Are you sure you want to close this blocked issue?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să închideți această problemă blocată?"
msgid "Are you sure you want to delete %{name}?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să ștergeți %{name}?"
msgid "Are you sure you want to delete these artifacts?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să ștergeți aceste artefacte?"
msgid "Are you sure you want to delete this %{typeOfComment}?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să ștergeți acest %{typeOfComment}?"
msgid "Are you sure you want to delete this SSH key?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să ștergeți această cheie SSH?"
msgid "Are you sure you want to delete this device? This action cannot be undone."
-msgstr ""
+msgstr "Sunteți sigur că doriți să ștergeți acest dispozitiv? Această acțiune nu poate fi anulată."
msgid "Are you sure you want to delete this pipeline schedule?"
-msgstr ""
+msgstr "Sigur doriți să ștergeți acest program al conductei?"
msgid "Are you sure you want to delete this pipeline? Doing so will expire all pipeline caches and delete all related objects, such as builds, logs, artifacts, and triggers. This action cannot be undone."
-msgstr ""
+msgstr "Sigur doriți să ștergeți această conductă? Aceasta va expira toate cache-urile conductei și va șterge toate obiectele conexe, cum ar fi build-urile, jurnalele, artefactele și declanșatoarele. Această acțiune nu poate fi anulată."
msgid "Are you sure you want to deploy this environment?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să implementați acest mediu?"
msgid "Are you sure you want to discard this comment?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să renunțați la acest comentariu?"
msgid "Are you sure you want to discard your changes?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să renunțați la modificările dvs.?"
msgid "Are you sure you want to erase this build?"
-msgstr ""
+msgstr "Sigur doriți să ștergeți acest build?"
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
@@ -4505,454 +4544,454 @@ msgstr[1] ""
msgstr[2] ""
msgid "Are you sure you want to lock %{path}?"
-msgstr ""
+msgstr "Sunteți sigur că vreți să blocați %{path}?"
msgid "Are you sure you want to lock this directory?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să blocați acest director?"
msgid "Are you sure you want to lose unsaved changes?"
-msgstr ""
+msgstr "Sigur doriți să pierdeți modificările nesalvate?"
msgid "Are you sure you want to lose your issue information?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să vă pierdeți informațiile privind problema?"
msgid "Are you sure you want to merge immediately?"
-msgstr ""
+msgstr "Sunteți sigur că vreți să îmbinați imediat?"
msgid "Are you sure you want to re-deploy this environment?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să implementați din nou acest mediu?"
msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
+msgstr "Sunteți sigur că doriți să regenerați cheia publică? Va trebui să actualizați cheia publică pe serverul la distanță înainte ca replicarea să funcționeze din nou."
msgid "Are you sure you want to reindex?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să reindexați?"
msgid "Are you sure you want to remove %{email}?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să eliminați %{email}?"
msgid "Are you sure you want to remove %{group_name}?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să eliminați %{group_name}?"
msgid "Are you sure you want to remove the attachment?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să eliminați atașamentul?"
msgid "Are you sure you want to remove the license?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să eliminați licența?"
msgid "Are you sure you want to remove this deploy key? If anything is still using this key, it will stop working."
-msgstr ""
+msgstr "Sunteți sigur că doriți să eliminați această cheie de implementare? Dacă mai există ceva care utilizează această cheie, nu va mai funcționa."
msgid "Are you sure you want to remove this identity?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să eliminați această identitate?"
msgid "Are you sure you want to remove this list?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să eliminați această listă?"
msgid "Are you sure you want to reset the SCIM token? SCIM provisioning will stop working until the new token is updated."
-msgstr ""
+msgstr "Sunteți sigur că doriți să resetați tokenul SCIM? Asigurarea accesului SCIM nu va mai funcționa până când noul token este actualizat."
msgid "Are you sure you want to reset the health check token?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să resetați tokenul de verificare a sănătății?"
msgid "Are you sure you want to reset the registration token?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să resetați token-ul de înregistrare?"
msgid "Are you sure you want to retry this migration?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să reîncercați această migrare?"
msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
-msgstr ""
+msgstr "Sunteți sigur că doriți să revocați acest %{type}? Această acțiune nu poate fi anulată."
msgid "Are you sure you want to revoke this nickname?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să eliminați această poreclă?"
msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
-msgstr ""
+msgstr "Sunteți sigur că doriți să revocați acest token de acces personal? Această acțiune nu poate fi anulată."
msgid "Are you sure you want to stop this environment?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să opriți acest mediu?"
msgid "Are you sure you want to unlock %{path_lock_path}?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să deblocați %{path_lock_path}?"
msgid "Are you sure you want to unlock %{path}?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să deblocați %{path}?"
msgid "Are you sure you want to unlock this directory?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să deblocați acest director?"
msgid "Are you sure you want to unsubscribe from the %{type}: %{link_to_noteable_text}?"
-msgstr ""
+msgstr "Sunteți sigur că doriți să vă dezabonați de la %{type}: %{link_to_noteable_text}?"
msgid "Are you sure?"
-msgstr ""
+msgstr "Sunteți sigur?"
msgid "Are you sure? All commits that were signed with this GPG key will be unverified."
-msgstr ""
+msgstr "Sunteți sigur? Toate modificările care au fost semnate cu această cheie GPG vor fi neverificate."
msgid "Are you sure? Removing this GPG key does not affect already signed commits."
-msgstr ""
+msgstr "Sunteți sigur? Eliminarea acestei chei GPG nu afectează commit-urile deja semnate."
msgid "Are you sure? The device will be signed out of GitLab and all remember me tokens revoked."
-msgstr ""
+msgstr "Sunteți sigur? Dispozitivul va fi deconectat de la GitLab și toate token-urile de tip \"remember me\" vor fi revocate."
msgid "Are you sure? This will invalidate your registered applications and U2F / WebAuthn devices."
-msgstr ""
+msgstr "Ești sigur? Acest lucru va invalida aplicațiile înregistrate și dispozitivele U2F / WebAuthn."
msgid "Are you sure? This will invalidate your registered applications and U2F devices."
-msgstr ""
+msgstr "Ești sigur? Acest lucru va invalida aplicațiile și dispozitivele U2F înregistrate."
msgid "Arrange charts"
-msgstr ""
+msgstr "Aranjați diagramele"
msgid "Artifact"
-msgstr ""
+msgstr "Artefact"
msgid "Artifact could not be deleted."
-msgstr ""
+msgstr "Artefactul nu a putut fi șters."
msgid "Artifact was successfully deleted."
-msgstr ""
+msgstr "Artefactul a fost șters cu succes."
msgid "Artifacts"
-msgstr ""
-
-msgid "Artifacts maximum size"
-msgstr ""
+msgstr "Artefacte"
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
-msgstr ""
+msgstr "Pe măsură ce continuăm să dezvoltăm mai multe funcții pentru SAST, ne-ar plăcea să primim feedback-ul dvs. cu privire la funcția de configurare SAST din %{linkStart}acest număr%{linkEnd}."
msgid "AsanaService|%{user} pushed to branch %{branch} of %{project_name} ( %{commit_url} ):"
-msgstr ""
+msgstr "%{user} a publicat commit-ul la ramura %{branch} a %{project_name} ( %{commit_url} ):"
msgid "AsanaService|Add commit messages as comments to Asana tasks."
-msgstr ""
+msgstr "Adaugați mesaje de confirmare ca și comentarii la sarcinile Asana."
msgid "AsanaService|Comma-separated list of branches to be automatically inspected. Leave blank to include all branches."
-msgstr ""
+msgstr "Listă de ramuri separate prin virgulă care urmează să fie inspectate automat. Lăsați necompletat pentru a include toate ramurile."
msgid "AsanaService|User Personal Access Token. User must have access to the task. All comments are attributed to this user."
-msgstr ""
+msgstr "Token de Acces Personal al Utilizatorului. Utilizatorul trebuie să aibă acces la activitate. Toate comentariile sunt atribuite acestui utilizator."
msgid "Ascending"
-msgstr ""
+msgstr "Ascendent"
msgid "Ask again later"
-msgstr ""
+msgstr "Întrebați din nou mai târziu"
msgid "Ask someone with write access to resolve it."
-msgstr ""
+msgstr "Rugați pe cineva cu permisiuni de scriere să o rezolve."
msgid "Ask your group maintainer to set up a group runner."
-msgstr ""
+msgstr "Solicitați întreținătorului grupului să configureze un executor de grup."
msgid "Assertion consumer service URL"
-msgstr ""
+msgstr "URL aserțiune serviciu consumator"
msgid "Assets"
-msgstr ""
+msgstr "Resurse"
msgid "Assets:"
-msgstr ""
+msgstr "Resursele:"
msgid "Assign"
-msgstr ""
+msgstr "Atribuire"
msgid "Assign Iteration"
-msgstr ""
+msgstr "Atribuire Iterație"
msgid "Assign To"
-msgstr ""
+msgstr "Atribuire către"
msgid "Assign custom color like #FF0000"
-msgstr ""
+msgstr "Atribuiți culoarea personalizată, cum ar fi # FF0000"
msgid "Assign labels"
-msgstr ""
+msgstr "Atribuiți etichete"
msgid "Assign milestone"
-msgstr ""
+msgstr "Atribuire obiectiv"
msgid "Assign reviewer"
-msgstr ""
+msgstr "Atribuiți un evaluator"
msgid "Assign reviewer(s)"
-msgstr ""
+msgstr "Atribuiți evaluator(i)"
msgid "Assign some issues to this milestone."
-msgstr ""
+msgstr "Atribuiți câteva probleme acestui obiectiv."
msgid "Assign to"
-msgstr ""
+msgstr "Atribuire către"
msgid "Assign to commenting user"
-msgstr ""
+msgstr "Atribuire unui utilizator comentator"
msgid "Assign yourself to these issues"
-msgstr ""
+msgstr "Atribuiți-vă acestor probleme"
msgid "Assign yourself to this issue"
-msgstr ""
+msgstr "Atribuiți-vă acestei probleme"
msgid "Assigned %{assignee_users_sentence}."
-msgstr ""
+msgstr "Atribuit %{assignee_users_sentence}."
msgid "Assigned %{reviewer_users_sentence} as %{reviewer_text}."
-msgstr ""
+msgstr "Atribuit %{reviewer_users_sentence} ca %{reviewer_text}."
msgid "Assigned Issues"
-msgstr ""
+msgstr "Probleme atribuite"
msgid "Assigned merge requests"
-msgstr ""
+msgstr "Merge request-uri atribuite"
msgid "Assigned projects"
-msgstr ""
+msgstr "Proiecte atribuite"
msgid "Assigned to %{assigneeName}"
-msgstr ""
+msgstr "Atribuit lui %{assigneeName}"
msgid "Assigned to %{assignee_name}"
-msgstr ""
+msgstr "Atribuit lui %{assignee_name}"
msgid "Assigned to %{name}"
-msgstr ""
+msgstr "Atribuit la %{name}"
msgid "Assigned to me"
-msgstr ""
+msgstr "Atribuit mie"
msgid "Assigned to you"
-msgstr ""
+msgstr "Atribuit dvs."
msgid "Assignee"
msgid_plural "%d Assignees"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "Responsabil"
+msgstr[1] "%d Responsabili"
+msgstr[2] "%d de Responsabili"
msgid "Assignee has no permissions"
-msgstr ""
+msgstr "Responsabil nu are permisiuni"
msgid "Assignee lists not available with your current license"
-msgstr ""
-
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
+msgstr "Listele de responsabili nu sunt disponibile cu licența dvs. curentă"
msgid "Assignee(s)"
-msgstr ""
+msgstr "Responsabil(i)"
msgid "Assignees"
-msgstr ""
+msgstr "Responsabili"
msgid "Assigns %{assignee_users_sentence}."
-msgstr ""
+msgstr "Se atribuie %{assignee_users_sentence}."
msgid "Assigns %{reviewer_users_sentence} as %{reviewer_text}."
-msgstr ""
+msgstr "Se atribuie %{reviewer_users_sentence} ca %{reviewer_text}."
msgid "At least one approval from a code owner is required to change files matching the respective CODEOWNER rules."
-msgstr ""
+msgstr "Cel puțin o aprobare din partea unui proprietar de cod este necesară pentru a schimba fișierele care corespund regulilor respective CODEOWNER."
msgid "At least one field of %{one_of_required_fields} must be present"
-msgstr ""
+msgstr "Măcar un câmp de %{one_of_required_fields} trebuie să fie prezent."
msgid "At least one of group_id or project_id must be specified"
-msgstr ""
+msgstr "Cel puțin unul dintre group_id sau project_id trebuie să fie specificat"
msgid "At least one of your Personal Access Tokens is expired, but expiration enforcement is disabled. %{generate_new}"
-msgstr ""
+msgstr "Cel puțin unul dintre token-urile personale de acces a expirat, dar aplicarea expirării este dezactivată. %{generate_new}"
msgid "At least one of your Personal Access Tokens will expire soon, but expiration enforcement is disabled. %{generate_new}"
-msgstr ""
+msgstr "Cel puțin unul dintre token-urile personale de acces a expirat, dar aplicarea expirării este dezactivată. %{generate_new}"
msgid "At risk"
-msgstr ""
+msgstr "ÃŽn pericol"
msgid "Attach a file"
-msgstr ""
+msgstr "Atașați un fișier"
msgid "Attach a file by drag &amp; drop or %{upload_link}"
-msgstr ""
+msgstr "Atașați un fișier prin tragere &amp; lăsare sau %{upload_link}"
msgid "Attaching File - %{progress}"
-msgstr ""
+msgstr "Atașarea fișierului - %{progress}"
msgid "Attaching a file"
msgid_plural "Attaching %d files"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "Se atașează un fișier"
+msgstr[1] "Se atașează %d fișiere"
+msgstr[2] "Se atașează %d de fișiere"
msgid "Attaching the file failed."
-msgstr ""
+msgstr "Atașarea fișierului a eșuat."
msgid "Audit Events"
-msgstr ""
+msgstr "Evenimente de audit"
msgid "AuditLogs|(removed)"
-msgstr ""
+msgstr "(eliminat)"
msgid "AuditLogs|Action"
-msgstr ""
+msgstr "Acțiune"
msgid "AuditLogs|Author"
-msgstr ""
+msgstr "Autor"
msgid "AuditLogs|Date"
-msgstr ""
+msgstr "Data"
msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
-msgstr ""
+msgstr "Nu s-a găsit %{type}. Vă rugăm să căutați un alt %{type}."
msgid "AuditLogs|Failed to find %{type}. Please try again."
-msgstr ""
+msgstr "Nu s-a găsit %{type}. Vă rugăm să încercați din nou."
msgid "AuditLogs|Group Events"
-msgstr ""
+msgstr "Evenimente de grup"
msgid "AuditLogs|IP Address"
-msgstr ""
+msgstr "Adresă IP"
msgid "AuditLogs|Member Events"
-msgstr ""
+msgstr "Evenimente pentru membri"
msgid "AuditLogs|No matching %{type} found."
-msgstr ""
+msgstr "Nu s-a găsit nicio potrivire %{type}."
msgid "AuditLogs|Object"
-msgstr ""
+msgstr "Obiect"
msgid "AuditLogs|Project Events"
-msgstr ""
+msgstr "Evenimente de proiect"
msgid "AuditLogs|Target"
-msgstr ""
+msgstr "Țintă"
msgid "AuditLogs|This month"
-msgstr ""
+msgstr "Luna aceasta"
msgid "AuditLogs|User Events"
-msgstr ""
+msgstr "Evenimente utilizator"
msgid "Aug"
-msgstr ""
+msgstr "Aug"
msgid "August"
-msgstr ""
+msgstr "August"
msgid "Authenticate"
-msgstr ""
+msgstr "Autentificare"
msgid "Authenticate with GitHub"
-msgstr ""
+msgstr "Autentificare cu GitHub"
msgid "Authenticated API rate limit period in seconds"
-msgstr ""
+msgstr "Perioada de limitare a ratei API autentificate în secunde"
msgid "Authenticated API request rate limit"
-msgstr ""
+msgstr "Limita ratei de solicitare API autentificată"
msgid "Authenticated API requests"
+msgstr "Solicitări API autentificate"
+
+msgid "Authenticated Git LFS rate limit period in seconds"
msgstr ""
-msgid "Authenticated web rate limit period in seconds"
+msgid "Authenticated Git LFS request rate limit"
msgstr ""
+msgid "Authenticated web rate limit period in seconds"
+msgstr "Perioada de limitare a vitezei web autentificate în secunde"
+
msgid "Authenticated web request rate limit"
-msgstr ""
+msgstr "Limita ratei de solicitare web autentificată"
msgid "Authenticated web requests"
-msgstr ""
+msgstr "Solicitări autentificate web"
msgid "Authenticating"
-msgstr ""
+msgstr "Autentificarea"
msgid "Authentication"
-msgstr ""
+msgstr "Autentificare"
msgid "Authentication Failure"
-msgstr ""
+msgstr "Eroare la autentificare"
msgid "Authentication Log"
-msgstr ""
+msgstr "Jurnal autentificare"
msgid "Authentication failed: %{error_message}"
-msgstr ""
+msgstr "Autentificarea nu a reușit: %{error_message}"
msgid "Authentication log"
-msgstr ""
+msgstr "Jurnal autentificare"
msgid "Authentication method"
-msgstr ""
+msgstr "Metoda de autentificare"
msgid "Authentication method updated"
-msgstr ""
+msgstr "Metoda de autentificare a fost actualizată"
msgid "Authentication via U2F device failed."
-msgstr ""
+msgstr "Autentificarea prin intermediul dispozitivului U2F a eșuat."
msgid "Authentication via WebAuthn device failed."
-msgstr ""
+msgstr "Autentificarea prin intermediul dispozitivului WebAuthn a eșuat."
msgid "Author"
-msgstr ""
+msgstr "Autor"
msgid "Author: %{author_name}"
-msgstr ""
+msgstr "Autor: %{author_name}"
msgid "Authored %{timeago}"
-msgstr ""
+msgstr "Redactat %{timeago}"
msgid "Authored %{timeago} by %{author}"
-msgstr ""
+msgstr "Redactat %{timeago} de %{author}"
msgid "Authorization code:"
-msgstr ""
+msgstr "Cod de autorizare:"
msgid "Authorization key"
-msgstr ""
+msgstr "Cheie de autorizare"
msgid "Authorization required"
-msgstr ""
+msgstr "Autorizație necesară"
msgid "Authorization token duration (minutes)"
msgstr ""
msgid "Authorization was granted by entering your username and password in the application."
-msgstr ""
+msgstr "Autorizarea a fost acordată introducând numele de utilizator și parola în aplicație."
msgid "Authorize"
-msgstr ""
+msgstr "Autorizează"
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
msgid "Authorize %{user} to use your account?"
-msgstr ""
+msgstr "Autorizați %{user} să vă folosească contul?"
msgid "Authorized %{new_chat_name}"
-msgstr ""
+msgstr "Autorizat %{new_chat_name}"
msgid "Authorized At"
-msgstr ""
+msgstr "Autorizat la"
msgid "Authorized applications (%{size})"
-msgstr ""
+msgstr "Aplicații autorizate (%{size})"
msgid "Authors: %{authors}"
-msgstr ""
+msgstr "Autori: %{authors}"
msgid "Auto DevOps"
-msgstr ""
+msgstr "Auto DevOps"
msgid "Auto DevOps enabled"
-msgstr ""
+msgstr "Auto DevOps activat"
msgid "Auto stop successfully canceled."
-msgstr ""
+msgstr "Oprirea automată a fost anulată cu succes."
msgid "Auto-cancel redundant pipelines"
msgstr ""
@@ -4964,28 +5003,28 @@ msgid "AutoDevOps|%{auto_devops_start}Automate building, testing, and deploying%
msgstr ""
msgid "AutoDevOps|Auto DevOps"
-msgstr ""
+msgstr "Auto DevOps"
msgid "AutoDevOps|Auto DevOps documentation"
-msgstr ""
+msgstr "Documentație Auto DevOps"
msgid "AutoDevOps|Dismiss Auto DevOps box"
msgstr ""
msgid "AutoDevOps|Enable in settings"
-msgstr ""
+msgstr "Activați în setări"
msgid "AutoDevOps|It will automatically build, test, and deploy your application based on a predefined CI/CD configuration."
-msgstr ""
+msgstr "Va construi, testa și implementa automat aplicația dvs pe baza unei configurații predefinite CI/CD."
msgid "AutoDevOps|Learn more in the %{link_to_documentation}"
-msgstr ""
+msgstr "Aflați mai multe în %{link_to_documentation}"
msgid "AutoDevOps|The Auto DevOps pipeline has been enabled and will be used if no alternative CI configuration file is found."
msgstr ""
msgid "AutoDevopsAlert|Security testing tools enabled with %{linkStart}Auto DevOps%{linkEnd}"
-msgstr ""
+msgstr "Uneltele de testare a securității sunt activate cu %{linkStart}Auto DevOps%{linkEnd}"
msgid "AutoRemediation| 1 Merge Request"
msgstr ""
@@ -5015,259 +5054,259 @@ msgid "AutoRollback|Enable automatic rollbacks"
msgstr ""
msgid "Autocomplete"
-msgstr ""
+msgstr "Autocompletare"
msgid "Autocomplete description"
-msgstr ""
+msgstr "Descriere autocompletare"
msgid "Autocomplete hint"
-msgstr ""
+msgstr "Sugestie autocompletare"
msgid "Autocomplete usage hint"
-msgstr ""
+msgstr "Sugestie utilizare autocompletare"
msgid "Automatic certificate management using %{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end}"
-msgstr ""
+msgstr "Gestionarea automată a certificatelor utilizând %{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end}"
msgid "Automatic certificate management using Let's Encrypt"
-msgstr ""
+msgstr "Gestionarea automată a certificatelor utilizând Let's Encrypt"
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
msgid "Automatically resolved"
-msgstr ""
+msgstr "Rezolvată automat"
msgid "Automatically update this project's branches and tags from the upstream repository every hour."
-msgstr ""
+msgstr "Actualizare automată a ramurilor și etichetelor acestui proiect din repozitoriul upstream din oră în oră."
msgid "Autosave|Note"
-msgstr ""
+msgstr "Notă"
msgid "Available"
-msgstr ""
+msgstr "Disponibil"
msgid "Available ID"
-msgstr ""
+msgstr "ID disponibil"
msgid "Available group runners: %{runners}"
-msgstr ""
+msgstr "Executori de grup disponibili: %{runners}"
msgid "Available runners: %{runners}"
-msgstr ""
+msgstr "Executori disponibili: %{runners}"
msgid "Available shared runners:"
-msgstr ""
+msgstr "Executori partajați disponibili:"
msgid "Available specific runners"
-msgstr ""
+msgstr "Executori specifici disponibili"
msgid "Avatar for %{assigneeName}"
-msgstr ""
+msgstr "Avatar pentru %{assigneeName}"
msgid "Avatar for %{name}"
-msgstr ""
+msgstr "Avatar pentru %{name}"
msgid "Avatar will be removed. Are you sure?"
-msgstr ""
+msgstr "Avatarul va fi eliminat. Sunteți sigur?"
msgid "Average per day: %{average}"
-msgstr ""
+msgstr "Media pe zi: %{average}"
msgid "Award added"
-msgstr ""
+msgstr "Premiu adăugat"
msgid "Award removed"
-msgstr ""
+msgstr "Premiu eliminat"
msgid "AwardEmoji|No emojis found."
-msgstr ""
+msgstr "Nu s-au găsit emoji-uri."
msgid "Back"
-msgstr ""
+msgstr "ÃŽnapoi"
msgid "Back to page %{number}"
-msgstr ""
+msgstr "ÃŽnapoi la pagina %{number}"
msgid "Background Color"
-msgstr ""
+msgstr "Culoare fundal"
msgid "Background Jobs"
-msgstr ""
+msgstr "Lucrări de fundal"
msgid "Background Migrations"
-msgstr ""
+msgstr "Migrații de fundal"
msgid "Background color"
-msgstr ""
+msgstr "Culoare fundal"
msgid "Badges"
-msgstr ""
+msgstr "Insigne"
msgid "Badges|Add badge"
-msgstr ""
+msgstr "Adaugă insignă"
msgid "Badges|Adding the badge failed, please check the entered URLs and try again."
-msgstr ""
+msgstr "Adăugarea insignei nu a reușit, verificați adresele URL introduse și încercați din nou."
msgid "Badges|Badge image URL"
-msgstr ""
+msgstr "Adresa URL a imaginii insignei"
msgid "Badges|Badge image preview"
-msgstr ""
+msgstr "Previzualizare imagine insignă"
msgid "Badges|Badge saved."
-msgstr ""
+msgstr "Insigne salvate."
msgid "Badges|Delete badge?"
-msgstr ""
+msgstr "Ștergeți insigna?"
msgid "Badges|Deleting the badge failed, please try again."
-msgstr ""
+msgstr "Ștergerea insignei nu a reușit, încercați din nou."
msgid "Badges|Enter a valid URL"
-msgstr ""
+msgstr "Introduceți un URL valid"
msgid "Badges|Example: %{exampleUrl}"
-msgstr ""
+msgstr "Exemplu: %{exampleUrl}"
msgid "Badges|Group Badge"
-msgstr ""
+msgstr "Insigna grupului"
msgid "Badges|Link"
-msgstr ""
+msgstr "Link"
msgid "Badges|Name"
-msgstr ""
+msgstr "Nume"
msgid "Badges|New badge added."
-msgstr ""
+msgstr "Insignă nouă adăugată."
msgid "Badges|No badge image"
-msgstr ""
+msgstr "Nicio imagine insignă"
msgid "Badges|No image to preview"
-msgstr ""
+msgstr "Nu există imagini pentru previzualizare"
msgid "Badges|Project Badge"
-msgstr ""
+msgstr "Insigne de proiect"
msgid "Badges|Reload badge image"
-msgstr ""
+msgstr "Reîncărcați imaginea insignei"
msgid "Badges|Save changes"
-msgstr ""
+msgstr "Salvați modificările"
msgid "Badges|Saving the badge failed, please check the entered URLs and try again."
-msgstr ""
+msgstr "Salvarea insignei nu a reușit, verificați adresele URL introduse și încercați din nou."
msgid "Badges|Supported %{docsLinkStart}variables%{docsLinkEnd}: %{placeholders}"
-msgstr ""
+msgstr "Suportate %{docsLinkStart}variabile%{docsLinkEnd}: %{placeholders}"
msgid "Badges|The badge was deleted."
-msgstr ""
+msgstr "Insigna a fost ștearsă."
msgid "Badges|This group has no badges"
-msgstr ""
+msgstr "Acest grup nu are insigne"
msgid "Badges|This project has no badges"
-msgstr ""
+msgstr "Acest proiect nu are insigne"
msgid "Badges|You are going to delete this badge. Deleted badges %{strongStart}cannot%{strongEnd} be restored."
-msgstr ""
+msgstr "Sunteți pe cale de a șterge această insignă. Insignele șterse %{strongStart}nu%{strongEnd} pot fi recuperate."
msgid "Badges|Your badges"
-msgstr ""
+msgstr "Insignele tale"
msgid "Balsamiq file could not be loaded."
-msgstr ""
+msgstr "Fișierul Balsamiq nu a putut fi încărcat."
msgid "BambooService|Atlassian Bamboo"
-msgstr ""
+msgstr "Atlassian Bamboo"
msgid "BambooService|Bamboo URL"
-msgstr ""
+msgstr "URL Bamboo"
msgid "BambooService|Bamboo build plan key."
-msgstr ""
+msgstr "Cheia planului de construire Bamboo."
msgid "BambooService|Bamboo service root URL."
-msgstr ""
+msgstr "Adresa URL rădăcină a serviciului Bamboo."
msgid "BambooService|Run CI/CD pipelines with Atlassian Bamboo."
-msgstr ""
+msgstr "Executați conducte CI/CD cu Atlassian Bamboo."
msgid "BambooService|Run CI/CD pipelines with Atlassian Bamboo. You must set up automatic revision labeling and a repository trigger in Bamboo. %{docs_link}"
-msgstr ""
+msgstr "Executați conductele CI / CD cu Atlassian Bamboo. Trebuie să configurați etichetarea automată a revizuirilor și un declanșator de depozit în Bamboo. %{docs_link}"
msgid "BambooService|The user with API access to the Bamboo server."
-msgstr ""
+msgstr "Utilizatorul cu acces API la serverul Bamboo."
msgid "Based on"
-msgstr ""
+msgstr "Bazat pe"
msgid "Be careful. Changing the project's namespace can have unintended side effects."
-msgstr ""
+msgstr "Fiți atent. Schimbarea spațiului de nume al proiectului poate avea efecte secundare nedorite."
msgid "Be careful. Renaming a project's repository can have unintended side effects."
-msgstr ""
+msgstr "Fiți atent. Redenumirea unui repozitoriu al unui proiect poate avea efecte secundare nedorite."
msgid "Before enabling this integration, create a webhook for the room in Google Chat where you want to receive notifications from this project. %{docs_link}"
-msgstr ""
+msgstr "Înainte de a activa această integrare, creați un webhook pentru camera din Google Chat în care doriți să primiți notificări de la acest proiect. %{docs_link}"
msgid "Before inserting code, be sure to read the comment that separated each code group."
-msgstr ""
+msgstr "Înainte de a insera codul, asigurați-vă că ați citit comentariul care separă fiecare grup de cod."
msgid "Before this can be merged, a Jira issue must be linked in the title or description"
msgstr ""
msgid "Begin with the selected commit"
-msgstr ""
-
-msgid "Below are the current settings regarding"
-msgstr ""
+msgstr "Începeți cu commit-ul selectat"
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
msgid "Below are the settings for %{link_to_gitlab_pages}."
-msgstr ""
+msgstr "Mai jos sunt setările pentru %{link_to_gitlab_pages}."
msgid "Below you will find all the groups that are public."
-msgstr ""
+msgstr "Mai jos veți găsi toate grupurile care sunt publice."
msgid "Beta"
-msgstr ""
+msgstr "Beta"
msgid "Bi-weekly code coverage"
-msgstr ""
+msgstr "Acoperire bi-săptămânală a codului"
msgid "Billable Users"
msgstr ""
msgid "Billing"
-msgstr ""
+msgstr "Facturare"
msgid "BillingPlans|%{group_name} is currently using the %{plan_name}."
-msgstr ""
+msgstr "%{group_name} utilizează în prezent %{plan_name}."
msgid "BillingPlans|@%{user_name} you are currently using the %{plan_name}."
-msgstr ""
+msgstr "@%{user_name} utilizați în prezent %{plan_name}."
msgid "BillingPlans|Compare all plans"
-msgstr ""
+msgstr "Comparați toate planurile"
msgid "BillingPlans|Congratulations, your free trial is activated."
-msgstr ""
+msgstr "Felicitări, evaluarea dvs. gratuită este activată."
msgid "BillingPlans|End of availability for the Bronze Plan"
msgstr ""
msgid "BillingPlans|Free upgrade!"
-msgstr ""
+msgstr "Actualizare gratuită!"
msgid "BillingPlans|If you would like to downgrade your plan please contact %{support_link_start}Customer Support%{support_link_end}."
msgstr ""
@@ -5282,22 +5321,22 @@ msgid "BillingPlans|Looking to purchase or manage a subscription for your group?
msgstr ""
msgid "BillingPlans|Manage plan"
-msgstr ""
+msgstr "Gestionați planul"
msgid "BillingPlans|Pricing page"
-msgstr ""
+msgstr " Pagina de prețuri"
msgid "BillingPlans|See all %{plan_name} features"
-msgstr ""
+msgstr "Vizualizați toate funcțiile %{plan_name}"
msgid "BillingPlans|This group uses the plan associated with its parent group."
-msgstr ""
+msgstr "Acest grup utilizează planul asociat grupului său părinte."
msgid "BillingPlans|To manage the plan for this group, visit the billing section of %{parent_billing_page_link}."
-msgstr ""
+msgstr "Pentru a gestiona planul pentru acest grup, vizitați secțiunea de facturare a %{parent_billing_page_link}."
msgid "BillingPlans|Upgrade to GitLab %{planNameForUpgrade}"
-msgstr ""
+msgstr "Actualizați la GitLab %{planNameForUpgrade}"
msgid "BillingPlans|While GitLab is ending availability of the Bronze plan, you can still renew your Bronze subscription one additional time before %{eoa_bronze_plan_end_date}. We are also offering a limited time free upgrade to our Premium Plan (up to 25 users)! Learn more about the changes and offers in our %{announcement_link}."
msgstr ""
@@ -5309,25 +5348,25 @@ msgid "BillingPlans|Your GitLab.com trial expired on %{expiration_date}. You can
msgstr ""
msgid "BillingPlans|billed annually at %{price_per_year}"
-msgstr ""
+msgstr "facturat anual la %{price_per_year}"
msgid "BillingPlans|for the remainder of your subscription"
-msgstr ""
+msgstr "pentru restul abonamentului"
msgid "BillingPlans|frequently asked questions"
-msgstr ""
+msgstr "întrebări frecvente"
msgid "BillingPlans|group"
-msgstr ""
+msgstr "grup"
msgid "BillingPlans|monthly"
-msgstr ""
+msgstr "lunar"
msgid "BillingPlans|per user"
-msgstr ""
+msgstr "per utilizator"
msgid "BillingPlan|Contact sales"
-msgstr ""
+msgstr "Contact vânzări"
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5336,25 +5375,25 @@ msgid "BillingPlan|Upgrade for free"
msgstr ""
msgid "Billings|%{planName} plan"
-msgstr ""
+msgstr "Plan %{planName}"
msgid "Billings|An error occurred while extending your trial."
-msgstr ""
+msgstr "S-a întâmplat o eroare prelungind perioada de încercare."
msgid "Billings|An error occurred while reactivating your trial."
-msgstr ""
+msgstr "A apărut o eroare la reactivarea perioadei dvs. de încercare."
msgid "Billings|By extending your trial, you will receive an additional 30 days of %{planName}. Your trial can be only extended once."
-msgstr ""
+msgstr "Prin prelungirea perioadei de încercare, veți primi încă 30 de zile de %{planName}. Perioada dvs. de încercare poate fi prelungită o singură dată."
msgid "Billings|By reactivating your trial, you will receive an additional 30 days of %{planName}. Your trial can be only reactivated once."
-msgstr ""
+msgstr "Prin reactivarea perioadei de încercare, veți primi încă 30 de zile de %{planName}. Perioada dvs. de încercare poate fi prelungită o singură dată."
msgid "Billings|Extend trial"
-msgstr ""
+msgstr "Extindeți perioada de evaluare"
msgid "Billings|Reactivate trial"
-msgstr ""
+msgstr "Reactivați perioada de încercare"
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
@@ -5366,22 +5405,22 @@ msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to
msgstr ""
msgid "Billings|User successfully validated"
-msgstr ""
+msgstr "Utilizator validat cu succes"
msgid "Billings|User validation required"
-msgstr ""
+msgstr "Este necesară validarea utilizatorului"
msgid "Billings|Validate account"
-msgstr ""
+msgstr "Validați contul"
msgid "Billings|Validate user account"
-msgstr ""
+msgstr "Validați contul de utilizator"
msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
-msgstr ""
+msgstr "Contul dvs. de utilizator a fost validat cu succes. Acum puteți folosi minute gratuite pentru conducte."
msgid "Billing|An email address is only visible for users with public emails."
-msgstr ""
+msgstr "O adresă de e-mail este vizibilă doar pentru utilizatorii cu e-mailuri publice."
msgid "Billing|An error occurred while getting a billable member details"
msgstr ""
@@ -5393,34 +5432,34 @@ msgid "Billing|An error occurred while removing a billable member"
msgstr ""
msgid "Billing|Cannot remove user"
-msgstr ""
+msgstr "Nu se poate elimina utilizatorul"
msgid "Billing|Direct memberships"
msgstr ""
msgid "Billing|Enter at least three characters to search."
-msgstr ""
+msgstr "Introduceți cel puțin trei caractere pentru a căuta."
msgid "Billing|Export list"
-msgstr ""
+msgstr "Exportă lista"
msgid "Billing|Group"
-msgstr ""
+msgstr "Grup"
msgid "Billing|Group invite"
-msgstr ""
+msgstr "Invitație de grup"
msgid "Billing|Members who were invited via a group invitation cannot be removed. You can either remove the entire group, or ask an Owner of the invited group to remove the member."
-msgstr ""
+msgstr "Membrii care au fost invitați printr-o invitație de grup nu pot fi eliminați. Puteți fie să eliminați întregul grup, fie să solicitați unui proprietar al grupului invitat să îl elimine pe membru."
msgid "Billing|No users to display."
-msgstr ""
+msgstr "Niciun utilizator de afișat."
msgid "Billing|Private"
-msgstr ""
+msgstr "Privat"
msgid "Billing|Project invite"
-msgstr ""
+msgstr "Invitație proiect"
msgid "Billing|Remove user %{username} from your subscription"
msgstr ""
@@ -5429,10 +5468,10 @@ msgid "Billing|Toggle seat details"
msgstr ""
msgid "Billing|Type %{username} to confirm"
-msgstr ""
+msgstr "Tastați %{username} pentru a confirma"
msgid "Billing|User was successfully removed"
-msgstr ""
+msgstr "Utilizatorul a fost eliminat cu succes"
msgid "Billing|Users occupying seats in"
msgstr ""
@@ -5453,19 +5492,19 @@ msgid "Blame"
msgstr ""
msgid "Block user"
-msgstr ""
+msgstr "Blocați utilizatorul"
msgid "Blocked"
-msgstr ""
+msgstr "Blocat"
msgid "Blocked by %d issue"
msgid_plural "Blocked by %d issues"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "Blocat de %d problemă"
+msgstr[1] "Blocat de %d probleme"
+msgstr[2] "Blocat de %d probleme"
msgid "Blocked issue"
-msgstr ""
+msgstr "Problemă blocată"
msgid "Blocking"
msgstr ""
@@ -5474,10 +5513,10 @@ msgid "Blocking issues"
msgstr ""
msgid "Blocks"
-msgstr ""
+msgstr "Blocuri"
msgid "Blog"
-msgstr ""
+msgstr "Blog"
msgid "Board scope affects which issues are displayed for anyone who visits this board"
msgstr ""
@@ -5486,54 +5525,57 @@ msgid "BoardNewIssue|No matching results"
msgstr ""
msgid "BoardNewIssue|Projects"
-msgstr ""
+msgstr "Proiecte"
msgid "BoardNewIssue|Search projects"
-msgstr ""
+msgstr "Căutați proiecte"
msgid "BoardNewIssue|Select a project"
-msgstr ""
+msgstr "Selectați un proiect"
msgid "BoardScope|An error occurred while getting milestones, please try again."
-msgstr ""
+msgstr "S-a întâmplat o eroare preluând obiective, vă rugăm încercați din nou."
msgid "BoardScope|An error occurred while searching for users, please try again."
-msgstr ""
+msgstr "S-a întâmplat o eroare căutând utilizatori, vă rugăm încercați din nou."
msgid "BoardScope|Any Milestone"
-msgstr ""
+msgstr "Orice obiectiv"
msgid "BoardScope|Any assignee"
-msgstr ""
+msgstr "Orice responsabil"
msgid "BoardScope|Assignee"
-msgstr ""
+msgstr "Responsabil"
msgid "BoardScope|Edit"
-msgstr ""
+msgstr "Editare"
msgid "BoardScope|Milestone"
-msgstr ""
-
-msgid "BoardScope|No matching results"
-msgstr ""
+msgstr "Obiectiv"
msgid "BoardScope|No milestone"
-msgstr ""
+msgstr "Niciun obiectiv"
msgid "BoardScope|Search milestones"
-msgstr ""
+msgstr "Căutați obiective"
msgid "BoardScope|Select assignee"
-msgstr ""
+msgstr "Selectați responsabilul"
msgid "BoardScope|Select milestone"
+msgstr "Selectați obiectivul"
+
+msgid "BoardScope|Select weight"
msgstr ""
msgid "BoardScope|Started"
-msgstr ""
+msgstr "Început/ă"
msgid "BoardScope|Upcoming"
+msgstr "ÃŽn viitor"
+
+msgid "BoardScope|Weight"
msgstr ""
msgid "Boards"
@@ -5544,9 +5586,9 @@ msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
msgid_plural "Boards|+ %{displayedIssuablesCount} more %{issuableType}s"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "+ %{displayedIssuablesCount} mai mult %{issuableType}"
+msgstr[1] "+ %{displayedIssuablesCount} mai multe %{issuableType}s"
+msgstr[2] "+ %{displayedIssuablesCount} de mai multe %{issuableType}s"
msgid "Boards|An error occurred while creating the epic. Please try again."
msgstr ""
@@ -5561,7 +5603,7 @@ msgid "Boards|An error occurred while fetching group projects. Please try again.
msgstr ""
msgid "Boards|An error occurred while fetching issues. Please reload the page."
-msgstr ""
+msgstr "S-a întâmplat o eroare preluând problemele. Vă rugăm reîncărcați pagina."
msgid "Boards|An error occurred while fetching labels. Please reload the page."
msgstr ""
@@ -5591,7 +5633,7 @@ msgid "Boards|An error occurred while removing the list. Please try again."
msgstr ""
msgid "Boards|An error occurred while updating the board list. Please try again."
-msgstr ""
+msgstr "S-a întâmplat o eroare actualizând lista bordului. Vă rugăm încercați din nou."
msgid "Boards|Blocked by %{blockedByCount} %{issuableType}"
msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
@@ -5599,17 +5641,14 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
msgid "Boards|Edit board"
-msgstr ""
+msgstr "Editați panoul"
msgid "Boards|Expand"
-msgstr ""
+msgstr "Extindeți"
msgid "Boards|Failed to fetch blocking %{issuableType}s"
msgstr ""
@@ -5651,13 +5690,13 @@ msgid "Board|Failed to delete board. Please try again."
msgstr ""
msgid "Board|Load more epics"
-msgstr ""
+msgstr "Încărcați mai multe epice"
msgid "Board|Load more issues"
-msgstr ""
+msgstr "Încărcați mai multe probleme"
msgid "Board|Loading epics"
-msgstr ""
+msgstr "Se încarcă epicele"
msgid "Bold text"
msgstr ""
@@ -5666,7 +5705,7 @@ msgid "Both project and dashboard_path are required"
msgstr ""
msgid "Branch"
-msgstr ""
+msgstr "Ramură"
msgid "Branch %{branchName} was not found in this project's repository."
msgstr ""
@@ -5675,58 +5714,58 @@ msgid "Branch %{branch_name} was created. To set up auto deploy, choose a GitLab
msgstr ""
msgid "Branch already exists"
-msgstr ""
+msgstr "Ramura există deja"
msgid "Branch changed"
-msgstr ""
+msgstr "Ramură schimbată"
msgid "Branch is already taken"
msgstr ""
msgid "Branch name"
-msgstr ""
+msgstr "Numele ramurii"
msgid "Branch not loaded - %{branchId}"
-msgstr ""
+msgstr "Ramura nu a fost încărcată - %{branchId}"
msgid "Branches"
-msgstr ""
+msgstr "Ramuri"
msgid "Branches|Active"
-msgstr ""
+msgstr "Activ"
msgid "Branches|Active branches"
-msgstr ""
+msgstr "Ramuri active"
msgid "Branches|All"
-msgstr ""
+msgstr "Toate"
msgid "Branches|Cancel, keep branch"
-msgstr ""
+msgstr "Anulați, păstrați ramura"
msgid "Branches|Cant find HEAD commit for this branch"
-msgstr ""
+msgstr "Nu se poate găsi commit-ul HEAD pentru această ramură"
msgid "Branches|Compare"
-msgstr ""
+msgstr "Comparați"
msgid "Branches|Delete all branches that are merged into '%{default_branch}'"
-msgstr ""
+msgstr "Ștergeți toate ramurile care sunt îmbinate în '%{default_branch}'"
msgid "Branches|Delete branch"
-msgstr ""
+msgstr "Ștergeți ramura"
msgid "Branches|Delete branch. Are you ABSOLUTELY SURE?"
msgstr ""
msgid "Branches|Delete merged branches"
-msgstr ""
+msgstr "Ștergeți ramurile îmbinate"
msgid "Branches|Delete protected branch"
-msgstr ""
+msgstr "Ștergeți ramura protejată"
msgid "Branches|Delete protected branch '%{branch_name}'?"
-msgstr ""
+msgstr "Ștergeți ramura protejată '%{branch_name}'?"
msgid "Branches|Delete protected branch. Are you ABSOLUTELY SURE?"
msgstr ""
@@ -5738,16 +5777,16 @@ msgid "Branches|Deleting the '%{branch_name}' branch cannot be undone. Are you s
msgstr ""
msgid "Branches|Deleting the merged branches cannot be undone. Are you sure?"
-msgstr ""
+msgstr "Ștergerea ramurilor îmbinate nu poate fi anulată. Sunteți sigur?"
msgid "Branches|Filter by branch name"
msgstr ""
msgid "Branches|Merged into %{default_branch}"
-msgstr ""
+msgstr "Îmbinat în %{default_branch}"
msgid "Branches|New branch"
-msgstr ""
+msgstr "Ramură nouă"
msgid "Branches|No branches to show"
msgstr ""
@@ -5762,16 +5801,16 @@ msgid "Branches|Only a project maintainer or owner can delete a protected branch
msgstr ""
msgid "Branches|Overview"
-msgstr ""
+msgstr "Prezentare generală"
msgid "Branches|Please type the following to confirm:"
-msgstr ""
+msgstr "Vă rugăm să tastați următoarele pentru a confirma:"
msgid "Branches|Protected branches can be managed in %{project_settings_link}."
-msgstr ""
+msgstr "Ramurile protejate pot fi gestionate în %{project_settings_link}."
msgid "Branches|Show active branches"
-msgstr ""
+msgstr "Afișați ramurile active"
msgid "Branches|Show all branches"
msgstr ""
@@ -5789,7 +5828,7 @@ msgid "Branches|Show stale branches"
msgstr ""
msgid "Branches|Stale"
-msgstr ""
+msgstr "Vechi"
msgid "Branches|Stale branches"
msgstr ""
@@ -5810,25 +5849,25 @@ msgid "Branches|To avoid data loss, consider merging this branch before deleting
msgstr ""
msgid "Branches|To confirm, type %{branch_name_confirmation}:"
-msgstr ""
+msgstr "Pentru a confirma, tastați %{branch_name_confirmation}:"
msgid "Branches|To discard the local changes and overwrite the branch with the upstream version, delete it here and choose 'Update Now' above."
msgstr ""
msgid "Branches|Yes, delete branch"
-msgstr ""
+msgstr "Da, ștergeți ramura"
msgid "Branches|Yes, delete protected branch"
-msgstr ""
+msgstr "Da, ștergeți ramura protejată"
msgid "Branches|You're about to permanently delete the branch %{strongStart}%{branchName}.%{strongEnd}"
-msgstr ""
+msgstr "Sunteți pe cale să ștergeți definitiv ramura %{strongStart}%{branchName}.%{strongEnd}"
msgid "Branches|You're about to permanently delete the protected branch %{strongStart}%{branchName}.%{strongEnd}"
-msgstr ""
+msgstr "Sunteți pe cale să ștergeți definitiv ramura protejată %{strongStart}%{branchName}.%{strongEnd}"
msgid "Branches|You’re about to permanently delete the protected branch %{branch_name}."
-msgstr ""
+msgstr "Sunteți pe cale să ștergeți definitiv ramura protejată %{branch_name}."
msgid "Branches|diverged from upstream"
msgstr ""
@@ -5837,16 +5876,16 @@ msgid "Branches|merged"
msgstr ""
msgid "Branches|project settings"
-msgstr ""
+msgstr "setările proiectului"
msgid "Branches|protected"
-msgstr ""
+msgstr "protejat"
msgid "Breadcrumbs"
msgstr ""
msgid "Brief title about the change"
-msgstr ""
+msgstr "Titlu scurt despre schimbare"
msgid "Broadcast Message was successfully created."
msgstr ""
@@ -5891,46 +5930,40 @@ msgid "Bulk request concurrency"
msgstr ""
msgid "Bulk update"
-msgstr ""
+msgstr "Actualizare în bloc"
msgid "BulkImport|Existing groups"
-msgstr ""
+msgstr "Grupuri existente"
msgid "BulkImport|Filter by source group"
-msgstr ""
+msgstr "Filtrați după grupul sursă"
msgid "BulkImport|From source group"
-msgstr ""
-
-msgid "BulkImport|Import %{groups}"
-msgstr ""
+msgstr "Din grupul sursă"
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
-msgstr ""
+msgstr "Import eșuat: Destinația nu poate fi un subgrup al grupului sursă. Schimbați destinația și încercați din nou."
msgid "BulkImport|Import groups from GitLab"
+msgstr "Import grupuri din GitLab"
+
+msgid "BulkImport|Import selected"
msgstr ""
msgid "BulkImport|Importing the group failed"
-msgstr ""
+msgstr "Importul grupului a eșuat"
msgid "BulkImport|Name already exists."
-msgstr ""
-
-msgid "BulkImport|No groups on this page are available for import"
-msgstr ""
+msgstr "Numele există deja."
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
-msgstr ""
+msgstr "Se afișează %{start}-%{end} din %{total}"
msgid "BulkImport|Showing %{start}-%{end} of %{total} from %{link}"
-msgstr ""
+msgstr "Se afișează %{start}-%{end} din %{total} de la %{link}"
msgid "BulkImport|Showing %{start}-%{end} of %{total} matching filter \"%{filter}\" from %{link}"
msgstr ""
@@ -5942,7 +5975,7 @@ msgid "BulkImport|Update of import statuses with realtime changes failed"
msgstr ""
msgid "BulkImport|You have no groups to import"
-msgstr ""
+msgstr "Nu aveți grupuri de importat"
msgid "BulkImport|expected an associated Group but has an associated Project"
msgstr ""
@@ -5951,7 +5984,7 @@ msgid "BulkImport|expected an associated Project but has an associated Group"
msgstr ""
msgid "BulkImport|must be a group"
-msgstr ""
+msgstr "trebuie să fie un grup"
msgid "Burndown chart"
msgstr ""
@@ -5975,67 +6008,70 @@ msgid "Business metrics (Custom)"
msgstr ""
msgid "Busy"
-msgstr ""
+msgstr "Ocupat"
msgid "Buy CI Minutes"
+msgstr "Cumpărați minute CI"
+
+msgid "Buy Storage"
msgstr ""
msgid "Buy more Pipeline minutes"
msgstr ""
msgid "By %{user_name}"
-msgstr ""
+msgstr "De %{user_name}"
msgid "By authenticating with an account tied to an Enterprise e-mail address, it is understood that this account is an Enterprise User. "
-msgstr ""
+msgstr "Prin autentificarea cu un cont legat de o adresă de e-mail Întreprindere, se înțelege că acest cont este un utilizator Întreprindere. "
msgid "By default, all projects and groups will use the global notifications setting."
msgstr ""
msgid "ByAuthor|by"
-msgstr ""
+msgstr "de"
msgid "CHANGELOG"
-msgstr ""
+msgstr "CHANGELOG"
msgid "CI Lint"
-msgstr ""
+msgstr "CI Lint"
msgid "CI configuration validated, including all configuration added with the %{codeStart}includes%{codeEnd} keyword. %{link}"
msgstr ""
msgid "CI minutes"
-msgstr ""
+msgstr "Minute CI"
msgid "CI settings"
-msgstr ""
+msgstr "Setări CI"
msgid "CI variables"
-msgstr ""
+msgstr "Variabilele CI"
msgid "CI will run using the credentials assigned above."
msgstr ""
msgid "CI/CD"
-msgstr ""
+msgstr "CI/CD"
msgid "CI/CD Analytics"
-msgstr ""
+msgstr "Analize CI/CD"
msgid "CI/CD Settings"
-msgstr ""
+msgstr "Setări CI/CD"
msgid "CI/CD configuration"
-msgstr ""
+msgstr "Configurația CI/CD"
msgid "CI/CD configuration file"
-msgstr ""
+msgstr "Fișier de configurare CI/CD"
msgid "CI/CD|No projects have been added to the scope"
-msgstr ""
+msgstr "Niciun proiect nu a fost adăugat la domeniul de aplicare"
msgid "CICDAnalytics|%{percent}%{percentSymbol}"
-msgstr ""
+msgstr "%{percent}%{percentSymbol}"
msgid "CICDAnalytics|All time"
msgstr ""
@@ -6071,7 +6107,7 @@ msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration
msgstr ""
msgid "CICD|Add an existing project to the scope"
-msgstr ""
+msgstr "Adăugați un proiect existent la domeniul de aplicare"
msgid "CICD|Auto DevOps"
msgstr ""
@@ -6086,10 +6122,10 @@ msgid "CICD|Continuous deployment to production using timed incremental rollout"
msgstr ""
msgid "CICD|Default to Auto DevOps pipeline"
-msgstr ""
+msgstr "Implicit la conducta Auto DevOps"
msgid "CICD|Default to Auto DevOps pipeline for all projects"
-msgstr ""
+msgstr "Implicit la conducta Auto DevOps pentru toate proiectele"
msgid "CICD|Deployment strategy"
msgstr ""
@@ -6098,10 +6134,10 @@ msgid "CICD|Jobs"
msgstr ""
msgid "CICD|Limit CI_JOB_TOKEN access"
-msgstr ""
+msgstr "Limitați accesul CI_JOB_TOKEN"
msgid "CICD|Select projects that can be accessed by API requests authenticated with this project's CI_JOB_TOKEN CI/CD variable."
-msgstr ""
+msgstr "Selectați proiecte ce pot fi accesate prin solicitări API autentificate cu variabila CI/CD CI_JOB_TOKEN a acestui proiect."
msgid "CICD|The Auto DevOps pipeline runs by default in all projects with no CI/CD configuration file."
msgstr ""
@@ -6116,18 +6152,21 @@ msgid "CICD|instance enabled"
msgstr ""
msgid "CLOSED"
-msgstr ""
+msgstr "ÃŽNCHIS"
msgid "CLOSED (MOVED)"
-msgstr ""
+msgstr "ÃŽNCHIS (MUTAT)"
msgid "CODEOWNERS rule violation"
-msgstr ""
+msgstr "Încălcarea regulilor CODEOWNERS"
msgid "CONTRIBUTING"
msgstr ""
msgid "CPU"
+msgstr "CPU"
+
+msgid "CSV is being generated and will be emailed to you upon completion."
msgstr ""
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
@@ -6146,7 +6185,7 @@ msgid "CVE|Enable CVE ID requests in the issue sidebar"
msgstr ""
msgid "CVE|Request CVE ID"
-msgstr ""
+msgstr "Solicitați ID-ul CVE"
msgid "CVE|Why Request a CVE ID?"
msgstr ""
@@ -6158,28 +6197,28 @@ msgid "Callback URL"
msgstr ""
msgid "Campfire room ID (optional)"
-msgstr ""
+msgstr "ID cameră Campfire (opțional)"
msgid "Campfire subdomain (optional)"
-msgstr ""
+msgstr "Subdomeniu Campfire (opțional)"
msgid "Campfire token"
-msgstr ""
+msgstr "Token Campfire"
msgid "CampfireService|API authentication token from Campfire."
-msgstr ""
+msgstr "Token autentificare API de la Campfire."
msgid "CampfireService|From the end of the room URL."
-msgstr ""
+msgstr "De la sfârșitul URL-ului camerei."
msgid "CampfireService|Send notifications about push events to Campfire chat rooms. %{docs_link}"
-msgstr ""
+msgstr "Trimiteți notificări despre evenimente push către camere chat Campfire. %{docs_link}"
msgid "CampfireService|The %{code_open}.campfirenow.com%{code_close} subdomain."
-msgstr ""
+msgstr "Subdomeniul %{code_open}.campfirenow.com%{code_close}."
msgid "Can be manually deployed to"
-msgstr ""
+msgstr "Poate fi implementat manual la"
msgid "Can create groups:"
msgstr ""
@@ -6188,34 +6227,34 @@ msgid "Can't apply as the source branch was deleted."
msgstr ""
msgid "Can't apply as these lines were changed in a more recent version."
-msgstr ""
+msgstr "Nu se poate aplica, deoarece aceste linii au fost modificate într-o versiune mai recentă."
msgid "Can't apply as this line was changed in a more recent version."
-msgstr ""
+msgstr "Nu se poate aplica, deoarece această linie a fost modificată într-o versiune mai recentă."
msgid "Can't apply this suggestion."
-msgstr ""
+msgstr "Nu pot aplica această sugestie."
msgid "Can't be empty"
-msgstr ""
+msgstr "Nu poate fi gol"
msgid "Can't create snippet: %{err}"
msgstr ""
msgid "Can't fetch content for the blob: %{err}"
-msgstr ""
+msgstr "Nu se poate prelua conținutul pentru blob: %{err}"
msgid "Can't find HEAD commit for this branch"
-msgstr ""
+msgstr "Nu se poate găsi commit-ul HEAD pentru această ramură"
msgid "Can't find variable: ZiteReader"
-msgstr ""
+msgstr "Nu se poate găsi variabila: ZiteReader"
msgid "Can't load mermaid module: %{err}"
-msgstr ""
+msgstr "Nu se poate încărca modulul mermaid: %{err}"
msgid "Can't scan the code?"
-msgstr ""
+msgstr "Nu puteți scana codul?"
msgid "Can't update snippet: %{err}"
msgstr ""
@@ -6254,16 +6293,16 @@ msgid "CanaryIngress|You are changing the ratio of the canary rollout for %{envi
msgstr ""
msgid "Cancel"
-msgstr ""
+msgstr "Anulează"
msgid "Cancel and close"
-msgstr ""
+msgstr "Anulați și închideți"
msgid "Cancel index deletion"
msgstr ""
msgid "Cancel running"
-msgstr ""
+msgstr "Anulați rularea"
msgid "Cancel this job"
msgstr ""
@@ -6272,16 +6311,16 @@ msgid "Cancel your account"
msgstr ""
msgid "Cancel, keep project"
-msgstr ""
+msgstr "Anulați, păstrați proiectul"
msgid "Canceled deployment to"
msgstr ""
msgid "Cancelled"
-msgstr ""
+msgstr "Anulat"
msgid "Cancelling Preview"
-msgstr ""
+msgstr "Previzualizare anulare"
msgid "Cannot be assigned to other projects."
msgstr ""
@@ -6371,16 +6410,16 @@ msgid "Certain user content will be moved to a system-wide \"Ghost User\" in ord
msgstr ""
msgid "Certificate"
-msgstr ""
+msgstr "Certificat"
msgid "Certificate (PEM)"
-msgstr ""
+msgstr "Certificat (PEM)"
msgid "Certificate Issuer"
-msgstr ""
+msgstr "Emitent certificat"
msgid "Certificate Subject"
-msgstr ""
+msgstr "Subiect certificat"
msgid "Change assignee"
msgstr ""
@@ -6392,19 +6431,19 @@ msgid "Change assignee(s)."
msgstr ""
msgid "Change branches"
-msgstr ""
+msgstr "Schimbați ramurile"
msgid "Change label"
-msgstr ""
+msgstr "Schimbați eticheta"
msgid "Change made by"
-msgstr ""
+msgstr "Modificare făcută de"
msgid "Change milestone"
msgstr ""
msgid "Change path"
-msgstr ""
+msgstr "Schimbă calea"
msgid "Change reviewer(s)"
msgstr ""
@@ -6425,10 +6464,10 @@ msgid "Change template"
msgstr ""
msgid "Change title"
-msgstr ""
+msgstr "Schimbați titlul"
msgid "Change your password"
-msgstr ""
+msgstr "Schimbă-ți parola"
msgid "Change your password or recover your current one"
msgstr ""
@@ -6440,7 +6479,7 @@ msgid "ChangeReviewer|Reviewer changed to %{new}"
msgstr ""
msgid "ChangeReviewer|Unassigned"
-msgstr ""
+msgstr "Neatribuit"
msgid "ChangeTypeAction|A new branch will be created in your fork and a new merge request will be started."
msgstr ""
@@ -6464,7 +6503,7 @@ msgid "ChangeTypeAction|Search branches"
msgstr ""
msgid "ChangeTypeAction|Search projects"
-msgstr ""
+msgstr "Căutați proiecte"
msgid "ChangeTypeAction|Start a %{newMergeRequest} with these changes"
msgstr ""
@@ -6476,7 +6515,7 @@ msgid "ChangeTypeAction|Switch project"
msgstr ""
msgid "ChangeTypeAction|This will create a new commit in order to revert the existing changes."
-msgstr ""
+msgstr "Acest lucru va crea un nou commit pentru reversarea modificările existente."
msgid "ChangeTypeAction|Your changes will be committed to %{branchName} because a merge request is open."
msgstr ""
@@ -6512,7 +6551,7 @@ msgid "Changes to the title have not been saved"
msgstr ""
msgid "Changing group URL can have unintended side effects."
-msgstr ""
+msgstr "Schimbarea adresei URL a grupului poate avea efecte secundare neintenționate."
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6524,10 +6563,10 @@ msgid "ChatMessage|%{project_link}: Pipeline %{pipeline_link} of %{ref_type} %{r
msgstr ""
msgid "ChatMessage|Branch"
-msgstr ""
+msgstr "Ramură"
msgid "ChatMessage|Commit"
-msgstr ""
+msgstr "Commit"
msgid "ChatMessage|Failed job"
msgstr ""
@@ -6545,28 +6584,28 @@ msgid "ChatMessage|Pipeline %{pipeline_link} of %{ref_type} %{ref_link} by %{use
msgstr ""
msgid "ChatMessage|Tag"
-msgstr ""
+msgstr "Etichetă"
msgid "ChatMessage|and [%{count} more](%{pipeline_failed_jobs_url})"
-msgstr ""
+msgstr "și [%{count} altele](%{pipeline_failed_jobs_url})"
msgid "ChatMessage|has failed"
-msgstr ""
+msgstr "a eșuat"
msgid "ChatMessage|has passed"
-msgstr ""
+msgstr "a trecut"
msgid "ChatMessage|has passed with warnings"
-msgstr ""
+msgstr "a trecut cu avertismente"
msgid "ChatMessage|in %{duration}"
-msgstr ""
+msgstr "în %{duration}"
msgid "ChatMessage|in %{project_link}"
-msgstr ""
+msgstr "în %{project_link}"
msgid "Check again"
-msgstr ""
+msgstr "Verificați din nou"
msgid "Check feature availability on namespace plan"
msgstr ""
@@ -6578,7 +6617,7 @@ msgid "Check the %{docs_link_start}documentation%{docs_link_end}."
msgstr ""
msgid "Check the current instance configuration "
-msgstr ""
+msgstr "Verificați configurația instanței curente "
msgid "Check the elasticsearch.log file to debug why the migration was halted and make any changes before retrying the migration. When you fix the cause of the failure, click \"Retry migration\", and the migration will be scheduled to be retried in the background."
msgstr ""
@@ -6587,10 +6626,10 @@ msgid "Check your Docker images for known vulnerabilities."
msgstr ""
msgid "Check your Kubernetes cluster images for known vulnerabilities."
-msgstr ""
+msgstr "Verificați imaginile cluster Kubernetes pentru vulnerabilități cunoscute."
msgid "Check your source instance permissions."
-msgstr ""
+msgstr "Verificați permisiunile instanței sursă."
msgid "Checking %{text} availability…"
msgstr ""
@@ -6608,67 +6647,76 @@ msgid "Checking group path availability..."
msgstr ""
msgid "Checking username availability..."
-msgstr ""
+msgstr "Se verifică disponibilitatea numelui de utilizator..."
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
-msgstr ""
+msgstr "%{cardType} care se termină în %{lastFourDigits}"
msgid "Checkout|%{name}'s CI minutes"
-msgstr ""
+msgstr "Minutele CI ale %{name}"
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
-msgstr ""
+msgstr "%{startDate} - %{endDate}"
+
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
msgid "Checkout|%{totalCiMinutes} CI minutes"
-msgstr ""
+msgstr "%{totalCiMinutes} minute CI"
msgid "Checkout|(may be %{linkStart}charged upon purchase%{linkEnd})"
-msgstr ""
+msgstr "(poate fi %{linkStart}plătit la achiziție%{linkEnd})"
msgid "Checkout|(x%{numberOfUsers})"
-msgstr ""
+msgstr "(x%{numberOfUsers})"
msgid "Checkout|(x%{quantity})"
-msgstr ""
+msgstr "(x%{quantity})"
msgid "Checkout|Billing address"
-msgstr ""
+msgstr "Adresa de facturare"
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
-msgstr ""
+msgstr "Pachete minute CI sunt folosite numai după ce v-ați utilizat cota lunară a abonamentului dvs. Minutele suplimentare se vor roti din lună-n-lună și sunt valide pentru un an."
msgid "Checkout|Checkout"
msgstr ""
msgid "Checkout|City"
-msgstr ""
+msgstr " OraÈ™"
msgid "Checkout|Confirm purchase"
-msgstr ""
+msgstr " Confirmați achiziția"
msgid "Checkout|Confirming..."
-msgstr ""
+msgstr "Se confirmă..."
msgid "Checkout|Continue to billing"
msgstr ""
@@ -6716,10 +6764,10 @@ msgid "Checkout|GitLab group"
msgstr ""
msgid "Checkout|GitLab plan"
-msgstr ""
+msgstr "Plan GitLab"
msgid "Checkout|Group"
-msgstr ""
+msgstr "Grup"
msgid "Checkout|Name of company or organization using GitLab"
msgstr ""
@@ -6728,7 +6776,7 @@ msgid "Checkout|Need more users? Purchase GitLab for your %{company}."
msgstr ""
msgid "Checkout|Number of users"
-msgstr ""
+msgstr "Număr de utilizatori"
msgid "Checkout|Payment method"
msgstr ""
@@ -6743,7 +6791,7 @@ msgid "Checkout|Purchase details"
msgstr ""
msgid "Checkout|Select"
-msgstr ""
+msgstr "Selectați"
msgid "Checkout|State"
msgstr ""
@@ -6752,52 +6800,52 @@ msgid "Checkout|Street address"
msgstr ""
msgid "Checkout|Submitting the credit card form failed with code %{errorCode}: %{errorMessage}"
-msgstr ""
+msgstr "Trimiterea formularului de card de credit a eșuat cu codul %{errorCode}: %{errorMessage}"
msgid "Checkout|Subscription details"
msgstr ""
msgid "Checkout|Subtotal"
-msgstr ""
+msgstr "Subtotal"
msgid "Checkout|Tax"
msgstr ""
msgid "Checkout|Total"
-msgstr ""
+msgstr "Total"
msgid "Checkout|Total minutes: %{quantity}"
-msgstr ""
+msgstr "Total minute: %{quantity}"
msgid "Checkout|Users"
-msgstr ""
+msgstr "Utilizatori"
msgid "Checkout|You'll create your new group after checkout"
msgstr ""
msgid "Checkout|Your organization"
-msgstr ""
+msgstr "Organizația dvs."
msgid "Checkout|Your subscription will be applied to this group"
-msgstr ""
+msgstr "Abonamentul dvs. va fi aplicat la acest grup"
msgid "Checkout|Zip code"
-msgstr ""
+msgstr "Cod poștal"
msgid "Checkout|company or team"
-msgstr ""
+msgstr "companie sau echipă"
msgid "Checkout|x 1,000 minutes per pack = %{strong}"
msgstr ""
msgid "Cherry-pick this commit"
-msgstr ""
+msgstr "Cherry-pick acest commit"
msgid "Cherry-pick this merge request"
-msgstr ""
+msgstr "Cherry-pick acest merge request"
msgid "Child"
-msgstr ""
+msgstr "Copil"
msgid "Child epic does not exist."
msgstr ""
@@ -6806,40 +6854,40 @@ msgid "Child epic doesn't exist."
msgstr ""
msgid "Chinese language support using"
-msgstr ""
+msgstr "Suport pentru limba chineză folosind"
msgid "Choose File..."
-msgstr ""
+msgstr "Alegeți Fișierul..."
msgid "Choose a branch/tag (e.g. %{branch}) or enter a commit (e.g. %{sha}) to see what's changed or to create a merge request."
-msgstr ""
+msgstr "Alegeți o ramură/etichetă (de exemplu, %{branch}) sau introduceți un commit (de exemplu, %{sha}) pentru a vedea ce s-a schimbat sau pentru a crea o cerere de îmbinare."
msgid "Choose a file"
-msgstr ""
+msgstr "Alegeți un fisier"
msgid "Choose a group"
-msgstr ""
+msgstr "Alegeți un grup"
msgid "Choose a template"
-msgstr ""
+msgstr "Alegeți un șablon"
msgid "Choose a template..."
-msgstr ""
+msgstr "Alegeți un șablon…"
msgid "Choose a type..."
-msgstr ""
+msgstr "Alegeți un tip…"
msgid "Choose any color"
-msgstr ""
+msgstr "Alegeți orice culoare"
msgid "Choose any color."
-msgstr ""
+msgstr "Alegeți orice culoare."
msgid "Choose any color. Or you can choose one of the suggested colors below"
-msgstr ""
+msgstr "Alegeți orice culoare. Sau puteți alege una dintre culorile sugerate mai jos"
msgid "Choose file…"
-msgstr ""
+msgstr "Alegeți fișierul…"
msgid "Choose labels"
msgstr ""
@@ -6872,157 +6920,157 @@ msgid "CiCdAnalytics|Date range: %{range}"
msgstr ""
msgid "CiStatusLabel|canceled"
-msgstr ""
+msgstr "anulat"
msgid "CiStatusLabel|created"
-msgstr ""
+msgstr "creat"
msgid "CiStatusLabel|delayed"
-msgstr ""
+msgstr "întârziat"
msgid "CiStatusLabel|failed"
-msgstr ""
+msgstr "eșuat"
msgid "CiStatusLabel|manual action"
-msgstr ""
+msgstr "acțiune manuală"
msgid "CiStatusLabel|passed"
-msgstr ""
+msgstr "a trecut"
msgid "CiStatusLabel|passed with warnings"
-msgstr ""
+msgstr "a trecut cu avertismente"
msgid "CiStatusLabel|pending"
-msgstr ""
+msgstr "în așteptare"
msgid "CiStatusLabel|preparing"
-msgstr ""
+msgstr "se pregătește"
msgid "CiStatusLabel|skipped"
-msgstr ""
+msgstr "sărit"
msgid "CiStatusLabel|waiting for delayed job"
-msgstr ""
+msgstr "în așteptarea unei lucrări întârziate"
msgid "CiStatusLabel|waiting for manual action"
-msgstr ""
+msgstr "așteptare pentru acțiunea manuală"
msgid "CiStatusLabel|waiting for resource"
-msgstr ""
+msgstr "în așteptarea resursei"
msgid "CiStatusText|blocked"
-msgstr ""
+msgstr "blocat"
msgid "CiStatusText|canceled"
-msgstr ""
+msgstr "anulat"
msgid "CiStatusText|created"
-msgstr ""
+msgstr "creat"
msgid "CiStatusText|delayed"
-msgstr ""
+msgstr "întârziat"
msgid "CiStatusText|failed"
-msgstr ""
+msgstr "eșuat"
msgid "CiStatusText|manual"
-msgstr ""
+msgstr "manual"
msgid "CiStatusText|passed"
-msgstr ""
+msgstr "a trecut"
msgid "CiStatusText|pending"
-msgstr ""
+msgstr "în așteptare"
msgid "CiStatusText|preparing"
-msgstr ""
+msgstr "se pregătește"
msgid "CiStatusText|skipped"
-msgstr ""
+msgstr "sărit"
msgid "CiStatusText|waiting"
-msgstr ""
+msgstr "în așteptare"
msgid "CiStatus|running"
-msgstr ""
+msgstr "rulează"
msgid "CiVariables|Cannot use Masked Variable with current value"
-msgstr ""
+msgstr "Nu se poate utiliza Variabilă mascată cu valoarea curentă"
msgid "CiVariables|Environments"
-msgstr ""
+msgstr "Medii"
msgid "CiVariables|Input variable key"
-msgstr ""
+msgstr "Cheie variabilă de intrare"
msgid "CiVariables|Input variable value"
-msgstr ""
+msgstr "Valoarea variabilei de intrare"
msgid "CiVariables|Key"
-msgstr ""
+msgstr "Cheie"
msgid "CiVariables|Masked"
-msgstr ""
+msgstr "Mascat"
msgid "CiVariables|Protected"
-msgstr ""
+msgstr "Protejat"
msgid "CiVariables|Remove variable"
-msgstr ""
+msgstr "Eliminați variabila"
msgid "CiVariables|Remove variable row"
-msgstr ""
+msgstr "Eliminați rândul variabil"
msgid "CiVariables|Scope"
-msgstr ""
+msgstr "Domeniul de aplicare"
msgid "CiVariables|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used as default"
msgstr ""
msgid "CiVariables|State"
-msgstr ""
+msgstr "Statut"
msgid "CiVariables|Type"
-msgstr ""
+msgstr "Tip"
msgid "CiVariables|Value"
-msgstr ""
+msgstr "Valoare"
msgid "CiVariables|Variables"
-msgstr ""
+msgstr "Variabile"
msgid "CiVariable|* (All environments)"
-msgstr ""
+msgstr "* (Toate mediile)"
msgid "CiVariable|All environments"
-msgstr ""
+msgstr "Toate mediile"
msgid "CiVariable|Create wildcard"
-msgstr ""
+msgstr "Creați un wildcard"
msgid "CiVariable|Masked"
-msgstr ""
+msgstr "Mascat"
msgid "CiVariable|New environment"
-msgstr ""
+msgstr "Mediu nou"
msgid "CiVariable|Protected"
-msgstr ""
+msgstr "Protejat"
msgid "CiVariable|Search environments"
-msgstr ""
+msgstr "Căutați medii"
msgid "CiVariable|Toggle masked"
-msgstr ""
+msgstr "Comutator mascat"
msgid "CiVariable|Toggle protected"
-msgstr ""
+msgstr "Comutator protejat"
msgid "Classification Label (optional)"
msgstr ""
msgid "ClassificationLabelUnavailable|is unavailable: %{reason}"
-msgstr ""
+msgstr "nu este disponibil: %{reason}"
msgid "Clean up after running %{link_start}git filter-repo%{link_end} on the repository."
msgstr ""
@@ -7058,7 +7106,7 @@ msgid "Clear recent searches"
msgstr ""
msgid "Clear search"
-msgstr ""
+msgstr "Ștergeți căutarea"
msgid "Clear search input"
msgstr ""
@@ -7097,10 +7145,10 @@ msgid "Click to expand text"
msgstr ""
msgid "Click to hide"
-msgstr ""
+msgstr "Clic pentru ascundere"
msgid "Click to reveal"
-msgstr ""
+msgstr "Faceți clic pentru afișare"
msgid "Client authentication certificate"
msgstr ""
@@ -7115,7 +7163,7 @@ msgid "Client request timeout"
msgstr ""
msgid "Clients"
-msgstr ""
+msgstr "Clienți"
msgid "Clone"
msgstr ""
@@ -7124,10 +7172,10 @@ msgid "Clone repository"
msgstr ""
msgid "Clone this issue"
-msgstr ""
+msgstr "Clonați această problemă"
msgid "Clone with %{http_label}"
-msgstr ""
+msgstr "Clonați cu %{http_label}"
msgid "Clone with %{protocol}"
msgstr ""
@@ -7139,7 +7187,7 @@ msgid "Clone with SSH"
msgstr ""
msgid "CloneIssue|Cannot clone issue due to insufficient permissions!"
-msgstr ""
+msgstr "Nu se poate clona problema din cauza permisiunilor insuficiente!"
msgid "CloneIssue|Cannot clone issue to target project as it is pending deletion."
msgstr ""
@@ -7154,7 +7202,7 @@ msgid "Close"
msgstr ""
msgid "Close %{issueType}"
-msgstr ""
+msgstr "Închideți %{issueType}"
msgid "Close %{tabname}"
msgstr ""
@@ -7169,19 +7217,19 @@ msgid "Close milestone"
msgstr ""
msgid "Close sidebar"
-msgstr ""
+msgstr "Închideți bara laterală"
msgid "Close this %{quick_action_target}"
-msgstr ""
+msgstr "Închideți această %{quick_action_target}"
msgid "Closed"
msgstr ""
msgid "Closed %{epicTimeagoDate}"
-msgstr ""
+msgstr "ÃŽnchis %{epicTimeagoDate}"
msgid "Closed MRs"
-msgstr ""
+msgstr "Cereri de îmbinare închise"
msgid "Closed epics"
msgstr ""
@@ -7193,16 +7241,16 @@ msgid "Closed this %{quick_action_target}."
msgstr ""
msgid "Closed: %{closed}"
-msgstr ""
+msgstr "ÃŽnchis: %{closed}"
msgid "Closes this %{quick_action_target}."
-msgstr ""
+msgstr "Închide această %{quick_action_target}."
msgid "Cloud licenses can not be removed."
msgstr ""
msgid "Cluster"
-msgstr ""
+msgstr "Cluster"
msgid "Cluster Health"
msgstr ""
@@ -7220,91 +7268,91 @@ msgid "Cluster level"
msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
-msgstr ""
+msgstr "Tipul de cluster trebuie să fie specificat pentru Stages::ClusterEndpointInserter"
msgid "ClusterAgents|Access tokens"
msgstr ""
msgid "ClusterAgents|Alternative installation methods"
-msgstr ""
+msgstr "Metode alternative de instalare"
msgid "ClusterAgents|An error occurred while loading your GitLab Agents"
msgstr ""
msgid "ClusterAgents|An error occurred while loading your agent"
-msgstr ""
+msgstr "A apărut o eroare la încărcarea agentului dumneavoastră"
msgid "ClusterAgents|An unknown error occurred. Please try again."
-msgstr ""
+msgstr "A apărut o eroare necunoscută. Vă rugăm să încercați din nou."
msgid "ClusterAgents|Configuration"
msgstr ""
msgid "ClusterAgents|Copy token"
-msgstr ""
+msgstr "Copiați token"
msgid "ClusterAgents|Created by"
-msgstr ""
+msgstr "Creat de"
msgid "ClusterAgents|Created by %{name} %{time}"
-msgstr ""
+msgstr "Creat de %{name} %{time}"
msgid "ClusterAgents|Date created"
-msgstr ""
+msgstr "Data creării"
msgid "ClusterAgents|Description"
-msgstr ""
+msgstr "Descriere"
msgid "ClusterAgents|For alternative installation methods %{linkStart}go to the documentation%{linkEnd}."
-msgstr ""
+msgstr "Pentru metodele alternative de instalare %{linkStart}mergeți la documentație%{linkEnd}."
msgid "ClusterAgents|Go to the repository"
+msgstr "Mergeți la repozitoriu"
+
+msgid "ClusterAgents|Install a new GitLab Agent"
msgstr ""
msgid "ClusterAgents|Install new Agent"
-msgstr ""
+msgstr "Instalați un nou agent"
msgid "ClusterAgents|Integrate Kubernetes with a GitLab Agent"
-msgstr ""
+msgstr "Integrează Kubernetes cu un agent GitLab"
msgid "ClusterAgents|Integrate with the GitLab Agent"
msgstr ""
msgid "ClusterAgents|Last used"
-msgstr ""
+msgstr "Ultima utilizare"
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
-msgstr ""
+msgstr "Nume"
msgid "ClusterAgents|Never"
-msgstr ""
+msgstr "Niciodată"
msgid "ClusterAgents|Read more about getting started"
-msgstr ""
+msgstr "Citiți mai multe despre procedura de start"
msgid "ClusterAgents|Recommended installation method"
-msgstr ""
+msgstr "Metoda de instalare recomandată"
msgid "ClusterAgents|Registering Agent"
-msgstr ""
+msgstr "ÃŽnregistrarea Agentului"
msgid "ClusterAgents|Registration token"
-msgstr ""
+msgstr "Token de înregistrare"
msgid "ClusterAgents|Select an Agent"
-msgstr ""
+msgstr "Selectați un agent"
msgid "ClusterAgents|Select the Agent you want to register with GitLab and install on your cluster. To learn more about the Kubernetes Agent registration process %{linkStart}go to the documentation%{linkEnd}."
-msgstr ""
+msgstr "Selectați agentul pe care doriți să îl înregistrați împreună cu GitLab și instalați-l pe cluster. Pentru a afla mai multe despre procesul de înregistrare a agentului Kubernetes %{linkStart} accesați documentația%{linkEnd}."
msgid "ClusterAgents|Select which Agent you want to install"
-msgstr ""
+msgstr "Selectați care agent doriți să îl instalați"
msgid "ClusterAgents|The GitLab Agent also requires %{linkStart}enabling the Agent Server%{linkEnd}"
msgstr ""
@@ -7313,28 +7361,28 @@ msgid "ClusterAgents|The GitLab Kubernetes Agent allows an Infrastructure as Cod
msgstr ""
msgid "ClusterAgents|The recommended installation method provided below includes the token. If you want to follow the alternative installation method provided in the docs make sure you save the token value before you close the window."
-msgstr ""
+msgstr "Metoda recomandată de instalare furnizată mai jos include tokenul. Dacă doriți să urmați metoda de instalare alternativă furnizată în documentație, asigurați-vă că salvați valoarea tokenului înainte de a închide fereastra."
msgid "ClusterAgents|The registration token will be used to connect the Agent on your cluster to GitLab. To learn more about the registration tokens and how they are used %{linkStart}go to the documentation%{linkEnd}."
-msgstr ""
+msgstr "Tokenul de înregistrare va fi utilizat pentru a conecta agentul pe clusterul dvs. la GitLab. Pentru a afla mai multe despre token-urile de înregistrare și modul în care acestea sunt utilizate %{linkStart} Du-te la documentația%{linkEnd}."
msgid "ClusterAgents|The token value will not be shown again after you close this window."
-msgstr ""
+msgstr "Valoarea tokenului nu va fi afișată din nou după închiderea acestei ferestre."
msgid "ClusterAgents|This agent has no tokens"
msgstr ""
msgid "ClusterAgents|To install an Agent you should create an agent directory in the Repository first. We recommend that you add the Agent configuration to the directory before you start the installation process."
-msgstr ""
+msgstr "Pentru a instala un agent, ar trebui să creați mai întâi un director de agent în repozitoriu. Vă recomandăm să adăugați configurația agentului în director înainte de a începe procesul de instalare."
msgid "ClusterAgents|Unknown user"
-msgstr ""
+msgstr "Utilizator necunoscut"
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
msgid "ClusterAgent|This feature is only available for premium plans"
-msgstr ""
+msgstr "Această funcție este disponibilă numai pentru planurile premium"
msgid "ClusterAgent|User has insufficient permissions to create a token for this project"
msgstr ""
@@ -7355,31 +7403,31 @@ msgid "ClusterIntegration|A cluster management project can be used to run deploy
msgstr ""
msgid "ClusterIntegration|A service token scoped to %{code}kube-system%{end_code} with %{code}cluster-admin%{end_code} privileges."
-msgstr ""
+msgstr "Un token de serviciu care oferă acces la %{code}kube-system%{end_code} cu privilegii de %{code}cluster-admin%{end_code}."
msgid "ClusterIntegration|API URL"
-msgstr ""
+msgstr "URL API"
msgid "ClusterIntegration|API URL should be a valid http/https url."
-msgstr ""
+msgstr "URL-ul API trebuie să fie un URL HTTP/HTTPS valid."
msgid "ClusterIntegration|Add Kubernetes cluster"
-msgstr ""
+msgstr "Adăugați clusterul Kubernetes"
msgid "ClusterIntegration|Add a Kubernetes cluster integration"
-msgstr ""
+msgstr "Adăugați o integrare a clusterului Kubernetes"
msgid "ClusterIntegration|Adding a Kubernetes cluster to your group will automatically share the cluster across all your projects. Use review apps, deploy your applications, and easily run your pipelines for all projects using the same cluster."
-msgstr ""
+msgstr "Adăugarea unui cluster Kubernetes la grupul dvs. va partaja automat clusterul în toate proiectele dvs. Utilizați aplicații de analiză de cod, implementați-vă aplicațiile și executați cu ușurință pipeline-urile dvs. pentru toate proiectele care utilizează același cluster."
msgid "ClusterIntegration|Adding a Kubernetes cluster will automatically share the cluster across all projects. Use review apps, deploy your applications, and easily run your pipelines for all projects using the same cluster."
-msgstr ""
+msgstr "Adăugarea unui cluster Kubernetes va partaja automat clusterul în toate proiectele dvs. Utilizați aplicații de analiză, implementați-vă aplicațiile și executați cu ușurință pipeline-urile dvs. pentru toate proiectele care utilizează același cluster."
msgid "ClusterIntegration|Adding an integration to your group will share the cluster across all your projects."
-msgstr ""
+msgstr "Adăugarea unei grupări de integrare va împărți grupul în toate proiectele dvs."
msgid "ClusterIntegration|Adding an integration will share the cluster across all projects."
-msgstr ""
+msgstr "Adăugarea unei integrări va împărți grupul în toate proiectele."
msgid "ClusterIntegration|Advanced options on this Kubernetes cluster’s integration"
msgstr ""
@@ -7400,16 +7448,16 @@ msgid "ClusterIntegration|Amazon EKS"
msgstr ""
msgid "ClusterIntegration|An error occurred when trying to contact the Google Cloud API. Please try again later."
-msgstr ""
+msgstr "A apărut o eroare la încercarea de a contacta API-ul Google Cloud. Vă rugăm să încercați din nou mai târziu."
msgid "ClusterIntegration|An error occurred while trying to fetch project zones: %{error}"
-msgstr ""
+msgstr "A apărut o eroare la încercarea de a prelua zonele de proiect: %{error}"
msgid "ClusterIntegration|An error occurred while trying to fetch your projects: %{error}"
-msgstr ""
+msgstr "A apărut o eroare la încercarea de a prelua proiectele dvs: %{error}"
msgid "ClusterIntegration|An error occurred while trying to fetch zone machine types: %{error}"
-msgstr ""
+msgstr "A apărut o eroare la încercarea de a prelua tipurile de mașini de zonă: %{error}"
msgid "ClusterIntegration|An unknown error occurred while attempting to connect to Kubernetes."
msgstr ""
@@ -7418,7 +7466,7 @@ msgid "ClusterIntegration|Any project namespaces"
msgstr ""
msgid "ClusterIntegration|Apply for credit"
-msgstr ""
+msgstr "Solicitați credit"
msgid "ClusterIntegration|Authenticate with AWS"
msgstr ""
@@ -7430,13 +7478,13 @@ msgid "ClusterIntegration|Authentication Error"
msgstr ""
msgid "ClusterIntegration|Base domain"
-msgstr ""
+msgstr "Domeniu de bază"
msgid "ClusterIntegration|CA Certificate"
-msgstr ""
+msgstr "Certificat CA"
msgid "ClusterIntegration|Certificate Authority bundle (PEM format)"
-msgstr ""
+msgstr "Pachetul autorității de certificare (format PEM)"
msgid "ClusterIntegration|Check your CA certificate"
msgstr ""
@@ -7457,7 +7505,7 @@ msgid "ClusterIntegration|Choose the worker node %{linkStart}instance type%{link
msgstr ""
msgid "ClusterIntegration|Choose which of your environments will use this cluster."
-msgstr ""
+msgstr "Alegeți care dintre mediile dvs. vor utiliza acest cluster."
msgid "ClusterIntegration|Clear cluster cache"
msgstr ""
@@ -7691,7 +7739,7 @@ msgid "ClusterIntegration|Kubernetes cluster was successfully created."
msgstr ""
msgid "ClusterIntegration|Kubernetes clusters allow you to use review apps, deploy your applications, run your pipelines, and much more in an easy way."
-msgstr ""
+msgstr "Clusterele Kubernetes vă permit să utilizați aplicații de revizuire, să implementați aplicațiile, să vă rulați conductele și multe altele într-un mod ușor."
msgid "ClusterIntegration|Kubernetes version"
msgstr ""
@@ -7960,7 +8008,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8039,7 +8087,7 @@ msgid "ClusterIntegration|We were unable to fetch any projects. Ensure that you
msgstr ""
msgid "ClusterIntegration|With a Kubernetes cluster associated to this project, you can use review apps, deploy your applications, run your pipelines, and much more in an easy way."
-msgstr ""
+msgstr "Cu un cluster Kubernetes asociat acestui proiect, puteți utiliza aplicațiile de revizuire, puteți implementa aplicațiile, puteți executa pipeline-uri și multe altele într-un mod ușor."
msgid "ClusterIntegration|You are about to remove your cluster integration and all GitLab-created resources associated with this cluster."
msgstr ""
@@ -8204,7 +8252,7 @@ msgid "Collector hostname"
msgstr ""
msgid "Colorize messages"
-msgstr ""
+msgstr "Colorează mesajele"
msgid "ComboSearch is not defined"
msgstr ""
@@ -8268,27 +8316,27 @@ msgstr ""
msgid "Commit"
msgid_plural "Commits"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "Commit"
+msgstr[1] "Commit-uri"
+msgstr[2] "Commit-uri"
msgid "Commit %{commit_id}"
-msgstr ""
+msgstr "Commit %{commit_id}"
msgid "Commit (when editing commit message)"
-msgstr ""
+msgstr "Commit (la editarea mesajului de commit)"
msgid "Commit Message"
-msgstr ""
+msgstr "Commit mesaj"
msgid "Commit changes"
msgstr ""
msgid "Commit deleted"
-msgstr ""
+msgstr "Commit șters"
msgid "Commit message"
-msgstr ""
+msgstr "Commit mesaj"
msgid "Commit message (optional)"
msgstr ""
@@ -8300,16 +8348,16 @@ msgid "Commit to %{branchName} branch"
msgstr ""
msgid "CommitBoxTitle|Commit"
-msgstr ""
+msgstr "Commit"
msgid "CommitMessage|Add %{file_name}"
-msgstr ""
+msgstr "Adăugați %{file_name}"
msgid "CommitMessage|Add %{file_name} and create a code quality job"
msgstr ""
msgid "CommitWidget|authored"
-msgstr ""
+msgstr "redactat"
msgid "Commits"
msgstr ""
@@ -8333,13 +8381,13 @@ msgid "Commits you select appear here. Go to the first tab and select commits to
msgstr ""
msgid "Commits|An error occurred while fetching merge requests data."
-msgstr ""
+msgstr "A apărut o eroare la preluarea datelor cererii de îmbinare."
msgid "Commits|History"
msgstr ""
msgid "Commits|No related merge requests found"
-msgstr ""
+msgstr "Nu au fost găsite merge request-uri asociate"
msgid "Committed by"
msgstr ""
@@ -8426,7 +8474,7 @@ msgid "CompareRevisions|There was an error while updating the branch/tag list. P
msgstr ""
msgid "CompareRevisions|View open merge request"
-msgstr ""
+msgstr "Vizualizați merge request-ul deschis"
msgid "Complete"
msgstr ""
@@ -8443,9 +8491,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8528,19 +8573,19 @@ msgid "Configuration help"
msgstr ""
msgid "Configure %{italic_start}What's new%{italic_end} drawer and content."
-msgstr ""
+msgstr "Configurați %{italic_start} Ce este noul %{italic_end} sertar și conținut."
msgid "Configure %{link} to track events. %{link_start}Learn more.%{link_end}"
msgstr ""
msgid "Configure %{repository_checks_link_start}repository checks%{link_end} and %{housekeeping_link_start}housekeeping%{link_end} on repositories."
-msgstr ""
+msgstr "Configurați %{repository_checks_link_start} controalele de repozitoriu%{link_end} și %{housekeeping_link_start} curățenia%{link_end} în depozite."
msgid "Configure Dependency Scanning in `.gitlab-ci.yml` using the GitLab managed template. You can [add variable overrides](https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings) to customize Dependency Scanning settings."
-msgstr ""
+msgstr "Configurați scanarea dependenței în `.gitLab-ci.yml` utilizând șablonul gestionat Gitlab. Puteți [adăuga suprascrieri variabile] (https://docs.gitlab.com/ee/user/application_security/dependendice_scanning/#Customizing-he-dependendice-scanning-settings) pentru a personaliza setările de scanare a dependenței."
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
-msgstr ""
+msgstr "Configurați scanarea dependenței în `.gitlab-ci.yml`, creând acest fișier dacă nu există deja"
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -8584,9 +8629,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8594,11 +8636,14 @@ msgid "Configure repository mirroring."
msgstr ""
msgid "Configure repository storage."
-msgstr ""
+msgstr "Configurați stocarea repozitoriului."
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -8606,7 +8651,7 @@ msgid "Configure the %{link} integration."
msgstr ""
msgid "Configure the default first day of the week and time tracking units."
-msgstr ""
+msgstr "Configurați prima zi implicită a săptămânii și unitățile de urmărire a timpului."
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -8618,7 +8663,7 @@ msgid "Confirm"
msgstr ""
msgid "Confirm new password"
-msgstr ""
+msgstr "Confirmați noua parolă"
msgid "Confirm user"
msgstr ""
@@ -8642,25 +8687,25 @@ msgid "Confirmed:"
msgstr ""
msgid "Conflict: This file was added both in the source and target branches, but with different contents."
-msgstr ""
+msgstr "Conflict: Acest fișier a fost adăugat atât în ramurile sursei, cât și în cele țintă, dar cu conținut diferit."
msgid "Conflict: This file was modified in both the source and target branches."
-msgstr ""
+msgstr "Conflict: Acest fișier a fost modificat atât în ramurile sursă, cât și în ramurile țintă."
msgid "Conflict: This file was modified in the source branch, but removed in the target branch."
-msgstr ""
+msgstr "Conflict: Acest fișier a fost modificat în ramura sursă, dar eliminat în ramura țintă."
msgid "Conflict: This file was removed in the source branch, but modified in the target branch."
-msgstr ""
+msgstr "Conflict: Acest fișier a fost eliminat în ramura sursă, dar modificat în ramura țintă."
msgid "Conflict: This file was removed in the source branch, but renamed in the target branch."
-msgstr ""
+msgstr "Conflict: Acest fișier a fost eliminat în ramura sursă, dar redenumit în ramura țintă."
msgid "Conflict: This file was renamed differently in the source and target branches."
-msgstr ""
+msgstr "Conflict: Acest fișier a fost redenumit diferit în ramurile sursă și țintă."
msgid "Conflict: This file was renamed in the source branch, but removed in the target branch."
-msgstr ""
+msgstr "Conflict: Acest fișier a fost redenumit în ramura sursă, dar eliminat în ramura țintă."
msgid "Confluence"
msgstr ""
@@ -8801,7 +8846,7 @@ msgid "ContainerRegistry|Cleanup is disabled for this project"
msgstr ""
msgid "ContainerRegistry|Cleanup is ongoing"
-msgstr ""
+msgstr "Curățare în desfășurare"
msgid "ContainerRegistry|Cleanup pending"
msgstr ""
@@ -8819,7 +8864,7 @@ msgid "ContainerRegistry|Cleanup ran but some tags were not removed"
msgstr ""
msgid "ContainerRegistry|Cleanup timed out"
-msgstr ""
+msgstr "Curățarea a expirat"
msgid "ContainerRegistry|Cleanup timed out before it could delete all tags"
msgstr ""
@@ -8852,7 +8897,7 @@ msgid "ContainerRegistry|Delete selected tags"
msgstr ""
msgid "ContainerRegistry|Deleting the image repository will delete all images and tags inside. This action cannot be undone. Please type the following to confirm: %{code}"
-msgstr ""
+msgstr "Ștergerea depozitului de imagine va șterge toate imaginile și etichetele din interior. Această acțiune nu poate fi anulată. Introduceți următoarele pentru a confirma: %{code}"
msgid "ContainerRegistry|Deletion disabled due to missing or insufficient permissions."
msgstr ""
@@ -9167,13 +9212,13 @@ msgid "Control emails linked to your account"
msgstr ""
msgid "Control how the GitLab Package Registry functions."
-msgstr ""
+msgstr "Controlați modul în care funcționează Registrul Pachetului GitLab."
msgid "Control whether to display third-party offers in GitLab."
msgstr ""
msgid "Control which projects can be accessed by API requests authenticated with this project's CI_JOB_TOKEN CI/CD variable. It is a security risk to disable this feature, because unauthorized projects might attempt to retrieve an active token and access the API."
-msgstr ""
+msgstr "Controlați ce proiecte pot fi accesate prin cereri API autentificate cu variabila CI_JOB_TOKEN CI/CD a acestui proiect. Este un risc de securitate să dezactivați această funcție, deoarece proiectele neautorizate ar putea încerca să regăsească un token activ și să acceseze API-ul."
msgid "Cookie domain"
msgstr ""
@@ -9322,7 +9367,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -9335,7 +9380,7 @@ msgid "CorpusManagement|Target"
msgstr ""
msgid "CorpusManagement|To use this corpus, edit the corresponding YAML file"
-msgstr ""
+msgstr "Pentru a utiliza acest corpus, editați fișierul YAML corespunzător"
msgid "CorpusManagement|Total Size: %{totalSize}"
msgstr ""
@@ -9398,7 +9443,7 @@ msgid "Could not draw the lines for job relationships"
msgstr ""
msgid "Could not fetch policy because existing policy YAML is invalid"
-msgstr ""
+msgstr "Nu s-a putut prelua politica, deoarece politica existentă YAML este invalidă"
msgid "Could not find design."
msgstr ""
@@ -9569,10 +9614,10 @@ msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
msgid "Create merge request"
-msgstr ""
+msgstr "Creați un merge request"
msgid "Create merge request and branch"
-msgstr ""
+msgstr "Creați un merge request și o ramură"
msgid "Create milestone"
msgstr ""
@@ -9890,22 +9935,22 @@ msgid "Crowd"
msgstr ""
msgid "CsvParser|Failed to render the CSV file for the following reasons:"
-msgstr ""
+msgstr "Nu s-a putut reda fișierul CSV din următoarele motive:"
msgid "CsvParser|Quoted field unterminated"
-msgstr ""
+msgstr "Câmpul citat neterminat"
msgid "CsvParser|Too few fields"
-msgstr ""
+msgstr "Prea puține câmpuri"
msgid "CsvParser|Too many fields"
-msgstr ""
+msgstr "Prea multe câmpuri"
msgid "CsvParser|Trailing quote on quoted field is malformed"
-msgstr ""
+msgstr "Citatul final pe câmpul citat este incorect"
msgid "CsvParser|Unable to auto-detect delimiter; defaulted to \",\""
-msgstr ""
+msgstr "Imposibil de detectat automat delimitatorul; implicit la \",\""
msgid "Current"
msgstr ""
@@ -10031,13 +10076,13 @@ msgid "CycleAnalyticsEvent|%{label_reference} label was added to the issue"
msgstr ""
msgid "CycleAnalyticsEvent|%{label_reference} label was added to the merge request"
-msgstr ""
+msgstr "Eticheta %{label_reference} a fost adăugată la merge request"
msgid "CycleAnalyticsEvent|%{label_reference} label was removed from the issue"
msgstr ""
msgid "CycleAnalyticsEvent|%{label_reference} label was removed from the merge request"
-msgstr ""
+msgstr "Eticheta %{label_reference} a fost eliminată din merge request"
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -10250,7 +10295,7 @@ msgid "DORA4Metrics|The chart displays the frequency of deployments to productio
msgstr ""
msgid "DORA4Metrics|The chart displays the median time between a merge request being merged and deployed to production environment(s) that are based on the %{linkStart}deployment_tier%{linkEnd} value."
-msgstr ""
+msgstr "Graficul afișează timpul mediu dintre îmbinarea unui merge request și implementarea în mediul (mediile) de producție care se bazează pe valoarea %{linkStart}deployment_tier%{linkEnd}."
msgid "Dashboard"
msgstr ""
@@ -10553,14 +10598,17 @@ msgid "DastProfiles|Website"
msgstr ""
msgid "DastProfiles|You can either choose a passive scan or validate the target site in your chosen site profile. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
-msgstr ""
+msgstr "Puteți alege fie o scanare pasivă, fie să validați site-ul țintă în profilul site-ului ales. %{docsLinkStart} Aflați mai multe despre validarea site-ului.%{docsLinkEnd}"
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
-msgstr ""
+msgstr "Nu puteți rula o scanare activă pe un site nevalidat."
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10573,6 +10621,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10585,12 +10636,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10609,6 +10666,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10643,37 +10703,37 @@ msgid "Database update failed"
msgstr ""
msgid "DatadogIntegration|%{linkOpen}API key%{linkClose} used for authentication with Datadog."
-msgstr ""
+msgstr "%{linkOpen}cheie API %{linkClose} folosită pentru autentificarea cu Datadog."
msgid "DatadogIntegration|(Advanced) The full URL for your Datadog site."
-msgstr ""
+msgstr "(Avansat) Adresa URL completă pentru site-ul dvs. Datadog."
msgid "DatadogIntegration|API URL"
-msgstr ""
+msgstr "API URL"
msgid "DatadogIntegration|Environment"
-msgstr ""
+msgstr "Mediu"
msgid "DatadogIntegration|For self-managed deployments, set the %{codeOpen}env%{codeClose} tag for all the data sent to Datadog. %{linkOpen}How do I use tags?%{linkClose}"
-msgstr ""
+msgstr "Pentru implementări auto-gestionate, setați %{codeOpen}mediul%{codeClose} etichetei pentru toate datele trimise către Datadog. %{linkOpen}Cum folosesc etichetele?%{linkClose}"
msgid "DatadogIntegration|How do I set up this integration?"
-msgstr ""
+msgstr "Cum pot configura această integrare?"
msgid "DatadogIntegration|Send CI/CD pipeline information to Datadog to monitor for job failures and troubleshoot performance issues. %{docs_link}"
-msgstr ""
+msgstr "Trimiteți informații despre conducta CI / CD către Datadog pentru a monitoriza eșecurile lucrărilor și a depana problemele de performanță. %{docs_link}"
msgid "DatadogIntegration|Service"
-msgstr ""
+msgstr "Serviciu"
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
-msgstr ""
+msgstr "Etichetați toate datele din această instanță GitLab în Datadog. Util la gestionarea mai multor implementări autogestionate."
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
-msgstr ""
+msgstr "Site-ul Datadog către care trimiteți date. Pentru a trimite date către site-ul UE, utilizați %{codeOpen}datadoghq.eu%{codeClose}."
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
-msgstr ""
+msgstr "Urmăriți conductele GitLab cu Datadog."
msgid "Datasource name not found"
msgstr ""
@@ -10741,9 +10801,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10760,7 +10817,7 @@ msgid "Default classification label"
msgstr ""
msgid "Default delayed project deletion"
-msgstr ""
+msgstr "Ștergerea pretabilită întârziată a proiectului"
msgid "Default deletion delay"
msgstr ""
@@ -10787,7 +10844,7 @@ msgid "Default projects limit"
msgstr ""
msgid "Default timeout"
-msgstr ""
+msgstr "Expirare implicită"
msgid "Default: Map a FogBugz account ID to a full name"
msgstr ""
@@ -10813,6 +10870,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10861,9 +10921,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10888,9 +10954,12 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
-msgid "Delete self monitoring project"
+msgid "Delete row"
msgstr ""
+msgid "Delete self monitoring project"
+msgstr "Ștergeți proiectul de auto-monitorizare"
+
msgid "Delete serverless domain?"
msgstr ""
@@ -10906,6 +10975,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10970,10 +11042,10 @@ msgid "Deleting a project places it into a read-only state until %{date}, at whi
msgstr ""
msgid "Deleting the project will delete its repository and all related resources, including issues and merge requests."
-msgstr ""
+msgstr "Ștergerea proiectului va șterge depozitul și toate resursele conexe, inclusiv problemele și cererile de îmbinare."
msgid "Deletion pending. This project will be deleted on %{date}. Repository and other project resources are read-only."
-msgstr ""
+msgstr "Ștergere în așteptare. Acest proiect va fi șters pe %{date}. Depozitul și alte resurse ale proiectului pot fi doar citite."
msgid "Denied"
msgstr ""
@@ -11086,10 +11158,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11140,6 +11212,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11207,16 +11291,16 @@ msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
+msgstr "Permite citire și scriere la imaginile din registru."
msgid "DeployTokens|Allows read and write access to the package registry."
-msgstr ""
+msgstr "Permite acces de citire și scriere la registrul de pachete."
msgid "DeployTokens|Allows read-only access to registry images."
msgstr ""
msgid "DeployTokens|Allows read-only access to the package registry."
-msgstr ""
+msgstr "Permite numai acces de citire la registrul de pachete."
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
@@ -11228,7 +11312,7 @@ msgid "DeployTokens|Copy username"
msgstr ""
msgid "DeployTokens|Create a new deploy token for all projects in this group. %{link_start}What are deploy tokens?%{link_end}"
-msgstr ""
+msgstr "Creați un token de implementare nou pentru toate proiectele în acest grup. %{link_start}Ce sunt token-urile de implementare?%{link_end}"
msgid "DeployTokens|Create deploy token"
msgstr ""
@@ -11243,13 +11327,13 @@ msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and
msgstr ""
msgid "DeployTokens|Enter a unique name for your deploy token."
-msgstr ""
+msgstr "Introduceți un nume unic pentru token-ul dvs. de implementare."
msgid "DeployTokens|Enter a username for your token. Defaults to %{code_start}gitlab+deploy-token-{n}%{code_end}."
-msgstr ""
+msgstr "Introduceți un utilizator pentru token-ul dvs. Valoarea implicită este %{code_start}gitlab+deploy-token{n}%{code_end}"
msgid "DeployTokens|Enter an expiration date for your token. Defaults to never expire."
-msgstr ""
+msgstr "Introduceți o dată de expirare pentru token-ul dvs. În mod implicit, nu expiră niciodată."
msgid "DeployTokens|Expires"
msgstr ""
@@ -11261,7 +11345,7 @@ msgid "DeployTokens|Name"
msgstr ""
msgid "DeployTokens|New deploy token"
-msgstr ""
+msgstr "Token de implementare nou"
msgid "DeployTokens|Revoke"
msgstr ""
@@ -11297,7 +11381,7 @@ msgid "DeployTokens|Your new project deploy token has been created."
msgstr ""
msgid "Deployed"
-msgstr ""
+msgstr "Implementat"
msgid "Deployed to"
msgstr ""
@@ -11552,7 +11636,7 @@ msgid "DevOps adoption"
msgstr ""
msgid "Devices (optional)"
-msgstr ""
+msgstr "Dispozitive (opțional)"
msgid "DevopsAdoption|%{adoptedCount}/%{featuresCount} %{title} features adopted"
msgstr ""
@@ -11561,14 +11645,20 @@ msgid "DevopsAdoption|Add a group to get started"
msgstr ""
msgid "DevopsAdoption|Add or remove groups"
-msgstr ""
+msgstr "Adăugați sau eliminați grupuri"
msgid "DevopsAdoption|Add or remove subgroups"
-msgstr ""
+msgstr "Adăugați sau eliminați subgrupuri"
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11579,7 +11669,7 @@ msgid "DevopsAdoption|Are you sure that you would like to remove %{name} from th
msgstr ""
msgid "DevopsAdoption|At least one approval on a merge request"
-msgstr ""
+msgstr "Măcar o aprobare pe o cerere de îmbinare"
msgid "DevopsAdoption|At least one deploy"
msgstr ""
@@ -11588,7 +11678,7 @@ msgid "DevopsAdoption|At least one issue opened"
msgstr ""
msgid "DevopsAdoption|At least one merge request opened"
-msgstr ""
+msgstr "Măcar o cerere de îmbinare deschisă"
msgid "DevopsAdoption|At least one pipeline successfully run"
msgstr ""
@@ -11603,16 +11693,16 @@ msgid "DevopsAdoption|Confirm remove Group"
msgstr ""
msgid "DevopsAdoption|DAST"
-msgstr ""
+msgstr "DAST"
msgid "DevopsAdoption|DAST enabled for at least one project"
-msgstr ""
+msgstr "DAST activat pentru măcar un proiect"
msgid "DevopsAdoption|Dependency Scanning"
-msgstr ""
+msgstr "Scanare Dependență"
msgid "DevopsAdoption|Dependency Scanning enabled for at least one project"
-msgstr ""
+msgstr "Scanare Dependență activată pentru măcar un proiect"
msgid "DevopsAdoption|Deploys"
msgstr ""
@@ -11624,19 +11714,19 @@ msgid "DevopsAdoption|DevOps adoption tracks the use of key features across your
msgstr ""
msgid "DevopsAdoption|Edit groups"
-msgstr ""
+msgstr "Editați grupuri"
msgid "DevopsAdoption|Edit subgroups"
-msgstr ""
+msgstr "Editați subgrupuri"
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
-msgstr ""
+msgstr "Testare Fuzz"
msgid "DevopsAdoption|Fuzz Testing enabled for at least one project"
-msgstr ""
+msgstr "Testare Fuzz activată pentru măcar un proiect"
msgid "DevopsAdoption|Issues"
msgstr ""
@@ -11672,10 +11762,10 @@ msgid "DevopsAdoption|Runners"
msgstr ""
msgid "DevopsAdoption|SAST"
-msgstr ""
+msgstr "SAST"
msgid "DevopsAdoption|SAST enabled for at least one project"
-msgstr ""
+msgstr "SAST activat pentru măcar un proiect"
msgid "DevopsAdoption|Sec"
msgstr ""
@@ -11690,7 +11780,7 @@ msgid "DevopsAdoption|There was an error fetching Groups. Please refresh the pag
msgstr ""
msgid "DevopsAdoption|This group has no subgroups"
-msgstr ""
+msgstr "Acest grup nu are subgrupuri"
msgid "DevopsAdoption|You cannot remove the group you are currently in."
msgstr ""
@@ -11765,10 +11855,10 @@ msgid "Direct member"
msgstr ""
msgid "Direct non-authenticated users to this page."
-msgstr ""
+msgstr "Direcționați utilizatorii neautentificați către această pagină."
msgid "Direct users to this page after they sign out."
-msgstr ""
+msgstr "Direcționați utilizatorii către această pagină după ce se deconectează."
msgid "Direction"
msgstr ""
@@ -11927,13 +12017,13 @@ msgid "Display source"
msgstr ""
msgid "Display time tracking in issues in total hours only."
-msgstr ""
+msgstr "Afișați urmărirea timpului în probleme în ore totale numai."
msgid "Do not display offers from third parties"
msgstr ""
msgid "Do not force push over diverged refs. After the mirror is created, this setting can only be modified using the API. %{mirroring_docs_link_start}Learn more about this option%{link_closing_tag} and %{mirroring_api_docs_link_start}the API.%{link_closing_tag}"
-msgstr ""
+msgstr "Nu împingeți forțat referințe divergente. După ce replica este creată, această setare poate fi modifcată numai folosind API-ul. %{mirroring_docs_link_start}Aflați mai multe despre această opțiune%{link_closing_tag} și %{mirroring_api_docs_link_start}API-ul%{link_closing_tag}"
msgid "Do you want to remove this deploy key?"
msgstr ""
@@ -11954,7 +12044,7 @@ msgid "Documents reindexed: %{processed_documents} (%{percentage}%%)"
msgstr ""
msgid "Does not apply to projects in personal namespaces, which are deleted immediately on request."
-msgstr ""
+msgstr "Nu se aplică proiectelor în spații de nume personale, ce sunt șterse imediat după solicitare."
msgid "Domain"
msgstr ""
@@ -12008,7 +12098,7 @@ msgid "Download %{name} artifact"
msgstr ""
msgid "Download (%{fileSizeReadable})"
-msgstr ""
+msgstr "Descărcați (%{fileSizeReadable})"
msgid "Download (%{size})"
msgstr ""
@@ -12044,10 +12134,10 @@ msgid "Download this directory"
msgstr ""
msgid "DownloadCommit|Email Patches"
-msgstr ""
+msgstr "Patch-uri e-mail"
msgid "DownloadCommit|Plain Diff"
-msgstr ""
+msgstr "Diff plain"
msgid "DownloadSource|Download"
msgstr ""
@@ -12125,7 +12215,7 @@ msgid "Edit %{issuable}"
msgstr ""
msgid "Edit %{name}"
-msgstr ""
+msgstr "Editați %{name}"
msgid "Edit Comment"
msgstr ""
@@ -12139,6 +12229,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12214,6 +12307,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12266,7 +12362,7 @@ msgid "Elasticsearch reindexing triggered"
msgstr ""
msgid "Elasticsearch reindexing was not started: %{errors}"
-msgstr ""
+msgstr "Reindexarea Elasticsearch nu a fost pornită: %{errors}"
msgid "Elasticsearch returned status code: %{status_code}"
msgstr ""
@@ -12329,28 +12425,28 @@ msgid "Email: %{email}"
msgstr ""
msgid "EmailError|It appears that the email is blank. Make sure your reply is at the top of the email, we can't process inline replies."
-msgstr ""
+msgstr "Se pare că e-mailul este gol. Asigurați-vă că răspunsul dvs se află în partea de sus a e-mailului, nu putem procesa răspunsurile inline."
msgid "EmailError|The thread you are replying to no longer exists, perhaps it was deleted? If you believe this is in error, contact a staff member."
-msgstr ""
+msgstr "Subiectul la care răspundeți nu mai există, poate că a fost șters? Dacă credeți că este o eroare, contactați un membru al personalului."
msgid "EmailError|We couldn't figure out what the email is for. Please create your issue or comment through the web interface."
-msgstr ""
+msgstr "Nu ne-am putut da seama pentru ce este e-mailul. Vă rugăm să creați problema sau comentariul dvs. prin interfața web."
msgid "EmailError|We couldn't figure out what the email is in reply to. Please create your comment through the web interface."
-msgstr ""
+msgstr "Nu am putut să ne dăm seama la ce răspunde acest e-mail. Vă rugăm să vă creați comentariul prin intermediul interfeței web."
msgid "EmailError|We couldn't figure out what user corresponds to the email. Please create your comment through the web interface."
-msgstr ""
+msgstr "Nu ne-am putut da seama ce utilizator corespunde e-mailului. Vă rugăm să vă creați comentariul prin intermediul interfeței web."
msgid "EmailError|We couldn't find the project. Please check if there's any typo."
-msgstr ""
+msgstr "Nu am putut găsi proiectul. Verificați dacă există vreo greșeală de scriere."
msgid "EmailError|You are not allowed to perform this action. If you believe this is in error, contact a staff member."
-msgstr ""
+msgstr "Nu aveți voie să efectuați această acțiune. Dacă credeți că este o eroare, contactați un reprezentant al personalului."
msgid "EmailError|Your account has been blocked. If you believe this is in error, contact a staff member."
-msgstr ""
+msgstr "Contul dvs. a fost blocat. Dacă credeți că acest lucru este o eroare, contactați un membru al personalului."
msgid "EmailParticipantsWarning|%{emails} will be notified of your comment."
msgstr ""
@@ -12377,7 +12473,7 @@ msgid "EmailsOnPushService|Don't include possibly sensitive code diffs in notifi
msgstr ""
msgid "EmailsOnPushService|Email the commits and diff of each push to a list of recipients."
-msgstr ""
+msgstr "Trimiteți prin e-mail commit-urile și diff-ul fiecărui push la o listă de destinatari."
msgid "EmailsOnPushService|Emails on push"
msgstr ""
@@ -12421,9 +12517,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12458,13 +12551,13 @@ msgid "Enable What's new: Current tier only"
msgstr ""
msgid "Enable a Prometheus endpoint that exposes health and performance statistics. The Health Check menu item appears in the Monitoring section of the Admin Area. Restart required."
-msgstr ""
+msgstr "Activați un punct final Prometheus care expune statistici de sănătate și performanță. Elementul-meniu Health Check apare în secția de Monitorizare a Admin Area."
msgid "Enable access to the performance bar for non-administrators in a given group."
-msgstr ""
+msgstr "Activați acces la bara de performanță pentru non-administratori într-un grup specificat."
msgid "Enable admin mode"
-msgstr ""
+msgstr "Activați modul administrator"
msgid "Enable and disable Service Desk. Some additional configuration might be required. %{link_start}Learn more%{link_end}."
msgstr ""
@@ -12472,11 +12565,14 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
msgid "Enable automatic repository housekeeping"
-msgstr ""
+msgstr "Activați menajul automat al repozitoriului"
msgid "Enable classification control using an external service"
msgstr ""
@@ -12485,10 +12581,10 @@ msgid "Enable container expiration and retention policies for projects created e
msgstr ""
msgid "Enable delayed project deletion by default for newly-created groups."
-msgstr ""
+msgstr "Activați eliminarea întârziată a proiectului în mod implicit pentru grupuri nou-create."
msgid "Enable email notification"
-msgstr ""
+msgstr "Activați notificare e-mail"
msgid "Enable error tracking"
msgstr ""
@@ -12506,11 +12602,14 @@ msgid "Enable header and footer in emails"
msgstr ""
msgid "Enable health and performance metrics endpoint"
-msgstr ""
+msgstr "Activați punctul final de metrici sănătate și performanță"
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12524,7 +12623,7 @@ msgid "Enable maintenance mode"
msgstr ""
msgid "Enable multipart emails"
-msgstr ""
+msgstr "Activați e-mailuri multipart"
msgid "Enable or disable the Pseudonymizer data collection."
msgstr ""
@@ -12548,7 +12647,7 @@ msgid "Enable reCAPTCHA, Invisible Captcha, Akismet and set IP limits. For reCAP
msgstr ""
msgid "Enable repository checks"
-msgstr ""
+msgstr "Activați verificările repozitoriului"
msgid "Enable service ping"
msgstr ""
@@ -12590,7 +12689,7 @@ msgid "EnableReviewApp|%{stepStart}Step 3%{stepEnd}. Add it to the project %{lin
msgstr ""
msgid "EnableReviewApp|%{stepStart}Step 4 (optional)%{stepEnd}. Enable Visual Reviews by following the %{linkStart}setup instructions%{linkEnd}."
-msgstr ""
+msgstr "%{stepStart}Pasul 4 (opțional)%{stepEnd}. Activați Recenzii Vizuale urmărind %{linkStart}instrucțiunile de setare%{linkEnd}."
msgid "EnableReviewApp|Close"
msgstr ""
@@ -12605,7 +12704,7 @@ msgid "Enabled Git access protocols"
msgstr ""
msgid "Enabled OAuth authentication sources"
-msgstr ""
+msgstr "Surse de autentificare OAuth activate"
msgid "Enabled sources for code import during project creation. OmniAuth must be configured for GitHub"
msgstr ""
@@ -12641,10 +12740,10 @@ msgid "Enforce personal access token expiration"
msgstr ""
msgid "Enforce two-factor authentication"
-msgstr ""
+msgstr "Impuneți autentificarea în doi pași"
msgid "Enforce two-factor authentication for all user sign-ins."
-msgstr ""
+msgstr "Impuneți autentificarea în doi pași pentru toate autentificările utilizatorilor."
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -12653,7 +12752,7 @@ msgid "Ensure your %{linkStart}environment is part of the deploy stage%{linkEnd}
msgstr ""
msgid "Enter %{weights_link_start}weights%{weights_link_end} for storages for new repositories. Configured storages appear below."
-msgstr ""
+msgstr "Introduceți %{weights_link_start}greutăți%{weights_link_end} pentru stocări pentru repozitoriile noi. Stocări configurate apar mai jos."
msgid "Enter 2FA for Admin Mode"
msgstr ""
@@ -12713,13 +12812,13 @@ msgid "Enter the number of seconds, or other human-readable input, like \"1 hour
msgstr ""
msgid "Enter your Packagist server. Defaults to https://packagist.org."
-msgstr ""
+msgstr "Introduceți server-ul dvs. Packagist. Valoarea implicită este https://packagist.org."
msgid "Enter your Packagist token."
-msgstr ""
+msgstr "Introduceți tokenul dvs. Packagist"
msgid "Enter your Packagist username."
-msgstr ""
+msgstr "Introduceți numele dvs. de utilizator Packagist."
msgid "Enter your password to approve"
msgstr ""
@@ -12770,7 +12869,7 @@ msgid "Environments Dashboard"
msgstr ""
msgid "Environments allow you to track deployments of your application. %{linkStart}More information%{linkEnd}."
-msgstr ""
+msgstr "Mediile vă permit să urmăriți implementări ale aplicației dvs. %{linkStart}Mai multe informații%{linkEnd}"
msgid "Environments in %{name}"
msgstr ""
@@ -12800,7 +12899,7 @@ msgid "EnvironmentsDashboard|Remove"
msgstr ""
msgid "EnvironmentsDashboard|The environments dashboard provides a summary of each project's environments' status, including pipeline and alert statuses."
-msgstr ""
+msgstr "Panoul de control al mediilor oferă un rezumat al stării mediului fiecărui proiect, inclusiv starea conductelor și a alertelor."
msgid "EnvironmentsDashboard|This dashboard displays 3 environments per project, and is linked to the Operations Dashboard. When you add or remove a project from one dashboard, GitLab adds or removes the project from the other. %{readMoreLink}"
msgstr ""
@@ -12833,10 +12932,10 @@ msgid "Environments|Auto stop in"
msgstr ""
msgid "Environments|Auto stops %{autoStopAt}"
-msgstr ""
+msgstr "Se oprește automat %{autoStopAt}"
msgid "Environments|Commit"
-msgstr ""
+msgstr "Commit"
msgid "Environments|Currently showing %{fetched} results."
msgstr ""
@@ -12865,6 +12964,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12877,6 +12979,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12952,14 +13057,17 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
msgid "Environments|This action will relaunch the job for commit %{linkStart}%{commitId}%{linkEnd}, putting the environment in a previous version. Are you sure you want to continue?"
-msgstr ""
+msgstr "Această acțiune va relansa jobul pentru commit-ul %{linkStart}%{commitId}%{linkEnd}, punând mediul într-o versiune anterioară. Sigur doriți să continuați?"
msgid "Environments|This action will run the job defined by %{name} for commit %{linkStart}%{commitId}%{linkEnd} putting the environment in a previous version. You can revert it by re-deploying the latest version of your application. Are you sure you want to continue?"
-msgstr ""
+msgstr "Această acțiune va rula jobul definit de %{name} pentru commit-ul %{linkStart}%{commitId}%{linkEnd} punând mediul într-o versiune anterioară. Reversarea se poate face prin reimplementarea celei mai recente versiuni a aplicației. Sigur doriți să continuați?"
msgid "Environments|Upcoming"
msgstr ""
@@ -12973,6 +13081,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13022,7 +13136,7 @@ msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
-msgstr ""
+msgstr "A apărut o eroare la salvarea datei %{epicDateType}"
msgid "Epics|An error occurred while updating labels."
msgstr ""
@@ -13037,7 +13151,7 @@ msgid "Epics|Enter a title for your epic"
msgstr ""
msgid "Epics|How can I solve this?"
-msgstr ""
+msgstr "Cum pot rezolva asta?"
msgid "Epics|Leave empty to inherit from milestone dates"
msgstr ""
@@ -13097,7 +13211,7 @@ msgid "Epics|This will also remove any descendents of %{bStart}%{targetEpicTitle
msgstr ""
msgid "Epics|To schedule your epic's %{epicDateType} date based on milestones, assign a milestone with a %{epicDateType} date to any issue in the epic."
-msgstr ""
+msgstr "Pentru a programa data epicei %{epicDateType} pe baza unor obiective, atribuiți un obiectiv cu o dată %{epicDateType} oricărei probleme din epică."
msgid "Epics|Unable to save epic. Please try again"
msgstr ""
@@ -13217,7 +13331,7 @@ msgid "Error occurred when saving reviewers"
msgstr ""
msgid "Error occurred while updating the %{issuableType} status"
-msgstr ""
+msgstr "A apărut o eroare actualizând statusul %{issuableType}"
msgid "Error occurred while updating the issue status"
msgstr ""
@@ -13292,13 +13406,13 @@ msgid "Error while loading the project data. Please try again."
msgstr ""
msgid "Error while migrating %{upload_id}: %{error_message}"
-msgstr ""
+msgstr "Eroare la migrarea %{upload_id}: %{error_message}"
msgid "Error with Akismet. Please check the logs for more info."
msgstr ""
msgid "Error: %{error_message}"
-msgstr ""
+msgstr "Eroare: %{error_message}"
msgid "Error: No AWS credentials were supplied"
msgstr ""
@@ -13309,17 +13423,20 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
msgid "ErrorTracking|Active"
-msgstr ""
+msgstr "Activ"
msgid "ErrorTracking|After adding your Auth Token, select the Connect button to load projects."
msgstr ""
msgid "ErrorTracking|Auth Token"
-msgstr ""
+msgstr "Token de autentificare"
msgid "ErrorTracking|Click Connect to reestablish the connection to Sentry and activate the dropdown."
msgstr ""
@@ -13346,7 +13463,7 @@ msgid "Errors"
msgstr ""
msgid "Errors found on line %{line_number}: %{error_lines}. Please check if these lines have a requirement title."
-msgstr ""
+msgstr "Erori găsite pe linia %{line_number}: %{error_lines}. Vă rugăm să verificați dacă aceste rânduri au o cerință pentru titlu."
msgid "Errors:"
msgstr ""
@@ -13358,7 +13475,7 @@ msgid "Escalation policies"
msgstr ""
msgid "Escalation policies may not have more than %{rule_count} rules"
-msgstr ""
+msgstr "Politicile de escaladare nu pot avea mai mult de %{rule_count} reguli"
msgid "Escalation policies must have at least one rule"
msgstr ""
@@ -13373,7 +13490,7 @@ msgid "EscalationPolicies|A schedule is required for adding an escalation policy
msgstr ""
msgid "EscalationPolicies|A user is required for adding an escalation policy."
-msgstr ""
+msgstr "Un utilizator este necesar pentru adăugarea unei politici de escaladare."
msgid "EscalationPolicies|Add an escalation policy"
msgstr ""
@@ -13400,7 +13517,7 @@ msgid "EscalationPolicies|Email on-call user in schedule"
msgstr ""
msgid "EscalationPolicies|Email user"
-msgstr ""
+msgstr "Utilizator e-mail"
msgid "EscalationPolicies|Escalation policies"
msgstr ""
@@ -13412,22 +13529,22 @@ msgid "EscalationPolicies|Failed to load oncall-schedules"
msgstr ""
msgid "EscalationPolicies|IF alert is not %{alertStatus} in %{minutes} %{then} THEN %{doAction} %{scheduleOrUser}"
-msgstr ""
+msgstr "DACĂ alerta nu este %{alertStatus} în %{minutes} %{then} ATUNCI %{doAction} %{scheduleOrUser}"
msgid "EscalationPolicies|IF alert is not %{alertStatus} in %{minutes} minutes"
msgstr ""
msgid "EscalationPolicies|Maximum of 10 rules has been reached."
-msgstr ""
+msgstr "Limita maximă de 10 reguli a fost atinsă."
msgid "EscalationPolicies|Minutes must be between 0 and 1440."
-msgstr ""
+msgstr "Minutele trebuie să fie între 0 și 1440."
msgid "EscalationPolicies|Remove escalation rule"
msgstr ""
msgid "EscalationPolicies|Search for user"
-msgstr ""
+msgstr "Căutați pentru utilizator"
msgid "EscalationPolicies|Select schedule"
msgstr ""
@@ -13436,7 +13553,7 @@ msgid "EscalationPolicies|Set up escalation policies to define who is paged, and
msgstr ""
msgid "EscalationPolicies|THEN %{doAction} %{scheduleOrUser}"
-msgstr ""
+msgstr "ATUNCI %{doAction} %{scheduleOrUser}"
msgid "EscalationPolicies|The escalation policy could not be deleted. Please try again."
msgstr ""
@@ -13445,7 +13562,7 @@ msgid "EscalationPolicies|The escalation policy could not be updated. Please try
msgstr ""
msgid "EscalationPolicies|This policy has no escalation rules."
-msgstr ""
+msgstr "Această politică nu are reguli de escaladare."
msgid "EscalationPolicies|mins"
msgstr ""
@@ -13472,7 +13589,7 @@ msgid "EventFilterBy|Filter by issue events"
msgstr ""
msgid "EventFilterBy|Filter by merge events"
-msgstr ""
+msgstr "Filtrați după evenimente de îmbinare"
msgid "EventFilterBy|Filter by push events"
msgstr ""
@@ -13487,7 +13604,7 @@ msgid "Events"
msgstr ""
msgid "Every %{action} attempt has failed: %{job_error_message}. Please try again."
-msgstr ""
+msgstr "Toate încercările %{action} au eșuat: %{job_error_message}. Vă rugăm să încercați din nou."
msgid "Every day"
msgstr ""
@@ -13499,7 +13616,7 @@ msgid "Every month"
msgstr ""
msgid "Every month (Day %{day} at %{time})"
-msgstr ""
+msgstr "Fiecare lună (Ziua %{day} la %{time})"
msgid "Every three months"
msgstr ""
@@ -13640,7 +13757,7 @@ msgid "Expiration date"
msgstr ""
msgid "Expiration date (optional)"
-msgstr ""
+msgstr "Data expirării (opțional)"
msgid "Expired"
msgstr ""
@@ -13709,7 +13826,7 @@ msgid "Export this group with all related data to a new GitLab instance. Once co
msgstr ""
msgid "Export this project with all its related data in order to move it to a new GitLab instance. When the exported file is ready, you can download it from this page or from the download link in the email notification you will receive. You can then import it when creating a new project. %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "Exportați acest proiect cu toate datele sale aferente pentru a-l muta într-o nouă instanță GitLab. Când fișierul exportat este gata, îl puteți descărca de pe această pagină sau de pe linkul de descărcare din notificarea prin e-mail pe care o veți primi. Apoi îl puteți importa atunci când creați un proiect nou. %{link_start}Aflați mai multe.%{link_end}"
msgid "Export variable to pipelines running on protected branches and tags only."
msgstr ""
@@ -13745,7 +13862,7 @@ msgid "External storage authentication token"
msgstr ""
msgid "External storage for repository static objects"
-msgstr ""
+msgstr "Stocare externă pentru obiecte statice din repozitoriu."
msgid "ExternalAuthorizationService|Classification label"
msgstr ""
@@ -13778,7 +13895,7 @@ msgid "Failed on"
msgstr ""
msgid "Failed to add a Zoom meeting"
-msgstr ""
+msgstr "Adăugarea unei întâlniri Zoom a eșuat"
msgid "Failed to apply commands."
msgstr ""
@@ -13853,7 +13970,7 @@ msgid "Failed to find import label for Jira import."
msgstr ""
msgid "Failed to generate export, please try again later."
-msgstr ""
+msgstr "Generarea exportului a eșuat, vă rugăm încercați mai târziu."
msgid "Failed to generate report, please try again after sometime"
msgstr ""
@@ -13946,7 +14063,7 @@ msgid "Failed to publish issue on status page."
msgstr ""
msgid "Failed to register Agent"
-msgstr ""
+msgstr "Înregistrarea Agentului a eșuat."
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -13979,7 +14096,7 @@ msgid "Failed to save new settings"
msgstr ""
msgid "Failed to save preferences (%{error_message})."
-msgstr ""
+msgstr "Salvarea preferințelor a eșuat (%{error_message})."
msgid "Failed to save preferences."
msgstr ""
@@ -14030,7 +14147,7 @@ msgid "False positive"
msgstr ""
msgid "Fast timeout"
-msgstr ""
+msgstr "Expirare rapidă"
msgid "Fast-forward merge without a merge commit"
msgstr ""
@@ -14339,7 +14456,7 @@ msgid "Filename"
msgstr ""
msgid "Files"
-msgstr ""
+msgstr "Fișiere"
msgid "Files breadcrumb"
msgstr ""
@@ -14423,7 +14540,7 @@ msgid "Filter results..."
msgstr ""
msgid "Filter users"
-msgstr ""
+msgstr "Filtrați utilizatorii"
msgid "Filter your repositories by name"
msgstr ""
@@ -14683,6 +14800,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14705,7 +14825,7 @@ msgid "Frequency"
msgstr ""
msgid "Frequently searched"
-msgstr ""
+msgstr "Căutate frecvent"
msgid "Friday"
msgstr ""
@@ -14770,6 +14890,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14902,10 +15025,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14950,7 +15073,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14971,9 +15094,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -15028,19 +15148,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -15085,7 +15202,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -15097,6 +15214,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -15113,7 +15233,7 @@ msgid "Geo|Synchronization"
msgstr ""
msgid "Geo|Synchronization failed - %{error}"
-msgstr ""
+msgstr "Sincronizarea a eșuat - %{error}"
msgid "Geo|Synchronization settings"
msgstr ""
@@ -15121,10 +15241,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15179,7 +15299,7 @@ msgid "Geo|Verification"
msgstr ""
msgid "Geo|Verification failed - %{error}"
-msgstr ""
+msgstr "Verificarea a eșuat - %{error}"
msgid "Geo|Verification information"
msgstr ""
@@ -15196,7 +15316,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15241,6 +15361,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15295,9 +15418,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15452,7 +15572,7 @@ msgid "GitLabPages|Removing pages will prevent them from being exposed to the ou
msgstr ""
msgid "GitLabPages|Save changes"
-msgstr ""
+msgstr "Salvați modificările"
msgid "GitLabPages|Something went wrong while obtaining the Let's Encrypt certificate for %{domain}. To retry visit your %{link_start}domain details%{link_end}."
msgstr ""
@@ -15494,7 +15614,7 @@ msgid "Gitaly storage name:"
msgstr ""
msgid "Gitaly timeouts"
-msgstr ""
+msgstr "Expirări Gitaly"
msgid "Gitaly|Address"
msgstr ""
@@ -15547,6 +15667,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15572,7 +15695,7 @@ msgid "Go full screen"
msgstr ""
msgid "Go to %{source_name}"
-msgstr ""
+msgstr "Mergeți la %{source_name}"
msgid "Go to commits"
msgstr ""
@@ -15628,7 +15751,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15806,7 +15929,7 @@ msgid "Group export could not be started."
msgstr ""
msgid "Group export download requests"
-msgstr ""
+msgstr "Solicitări descărcare export grup"
msgid "Group export error"
msgstr ""
@@ -15815,7 +15938,7 @@ msgid "Group export link has expired. Please generate a new export from your gro
msgstr ""
msgid "Group export requests"
-msgstr ""
+msgstr "Solicitări export grup"
msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
@@ -15830,7 +15953,7 @@ msgid "Group import could not be scheduled"
msgstr ""
msgid "Group import requests"
-msgstr ""
+msgstr "Solicitări import grup"
msgid "Group info:"
msgstr ""
@@ -15935,7 +16058,7 @@ msgid "GroupImport|Group '%{group_name}' is being imported."
msgstr ""
msgid "GroupImport|Group could not be imported: %{errors}"
-msgstr ""
+msgstr "Grupul nu a putut fi importat: %{errors}"
msgid "GroupImport|Please wait while we import the group for you. Refresh at will."
msgstr ""
@@ -15953,7 +16076,7 @@ msgid "GroupRoadmap|%{startDateInWords} – %{endDateInWords}"
msgstr ""
msgid "GroupRoadmap|Loading epics"
-msgstr ""
+msgstr "Se încarcă epicele"
msgid "GroupRoadmap|No start and end date"
msgstr ""
@@ -15979,6 +16102,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15991,6 +16120,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -16016,7 +16148,7 @@ msgid "GroupSAML|Copy SAML Response XML"
msgstr ""
msgid "GroupSAML|Could not create SAML group link: %{errors}."
-msgstr ""
+msgstr "Nu s-a putut crea legătura de grup SAML: %{errors}."
msgid "GroupSAML|Default membership role"
msgstr ""
@@ -16024,7 +16156,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16157,7 +16289,7 @@ msgid "GroupSettings|Allow project access token creation"
msgstr ""
msgid "GroupSettings|Auto DevOps pipeline was updated for the group"
-msgstr ""
+msgstr "Pipeline-ul Auto DevOps a fost actualizată pentru grup"
msgid "GroupSettings|Badges"
msgstr ""
@@ -16187,7 +16319,7 @@ msgid "GroupSettings|Customize this group's badges."
msgstr ""
msgid "GroupSettings|Default to Auto DevOps pipeline for all projects within this group"
-msgstr ""
+msgstr "Implicit la conducta Auto DevOps pentru toate proiectele din acest grup"
msgid "GroupSettings|Disable email notifications"
msgstr ""
@@ -16196,13 +16328,13 @@ msgid "GroupSettings|Disable group mentions"
msgstr ""
msgid "GroupSettings|Enable delayed project deletion"
-msgstr ""
+msgstr "Activați eliminarea întârziată a proiectului"
msgid "GroupSettings|Export group"
msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
-msgstr ""
+msgstr "Dacă nespecificată la nivel de grup sau instanță, valoarea implicită este %{default_initial_branch_name}. Nu afectează repozitorii existente."
msgid "GroupSettings|If the parent group's visibility is lower than the group current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
@@ -16214,7 +16346,7 @@ msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
msgid "GroupSettings|Please choose a group URL with no special characters or spaces."
-msgstr ""
+msgstr "Vă rugăm alegeți un URL grup fără litere speciale sau spații."
msgid "GroupSettings|Prevent forking outside of the group"
msgstr ""
@@ -16235,25 +16367,25 @@ msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_peri
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
-msgstr ""
+msgstr "Selectați un subgrup de utilizat ca sursă pentru șabloane de proiect personalizate pentru acest grup."
msgid "GroupSettings|Set the maximum size of GitLab Pages for this group. %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "Setați mărimea maximă a Pagini GitLab pentru acest grup. %{link_start}Aflați mai multe.%{link_end}"
msgid "GroupSettings|The Auto DevOps pipeline runs if no alternative CI configuration file is found."
msgstr ""
msgid "GroupSettings|The default name for the initial branch of new repositories created in the group."
-msgstr ""
+msgstr "Numele implicit pentru ramura inițială ale noi repozitorii create în acest grup."
msgid "GroupSettings|The projects in this subgroup can be selected as templates for new projects created in the group. %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "Proiectele din acest subgrup pot fi selectate ca șabloane pentru proiecte noi create în grup. %{link_start}Aflați mai multe.%{link_end}"
msgid "GroupSettings|There was a problem updating Auto DevOps pipeline: %{error_messages}."
-msgstr ""
+msgstr "A apărut o problemă la actualizarea conductei Auto DevOps: %{error_messages}."
msgid "GroupSettings|There was a problem updating the pipeline settings: %{error_messages}."
-msgstr ""
+msgstr "A apărut o problemă la actualizarea setărilor conductei: %{error_messages}"
msgid "GroupSettings|This setting is applied on %{ancestor_group} and has been overridden on this subgroup."
msgstr ""
@@ -16451,7 +16583,7 @@ msgid "HAR (HTTP Archive)"
msgstr ""
msgid "HAR file path or URL"
-msgstr ""
+msgstr "Traiectoria fișierului HAR sau URL-ul"
msgid "HTTP Basic: Access denied\\nYou must use a personal access token with 'api' scope for Git over HTTP.\\nYou can generate one at %{profile_personal_access_tokens_url}"
msgstr ""
@@ -16552,10 +16684,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16598,7 +16730,7 @@ msgid "Hide list"
msgstr ""
msgid "Hide marketing-related entries from the Help page"
-msgstr ""
+msgstr "Ascundeți intrările legate de marketing din pagina de Ajutor"
msgid "Hide payload"
msgstr ""
@@ -16664,7 +16796,7 @@ msgid "Hostname"
msgstr ""
msgid "Hostname used in private commit emails. %{learn_more}"
-msgstr ""
+msgstr "Hostname utilizat în e-mailuri comitere private. %{learn_more}"
msgid "Hour (UTC)"
msgstr ""
@@ -16690,6 +16822,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16715,25 +16850,25 @@ msgid "I forgot my password"
msgstr ""
msgid "I want to explore GitLab to see if it’s worth switching to"
-msgstr ""
+msgstr "Vreau să explorez GitLab pentru a vedea dacă merită să fac schimbarea"
msgid "I want to learn the basics of Git"
-msgstr ""
+msgstr "Vreau să învăț elementele de bază ale Git"
msgid "I want to move my repository to GitLab from somewhere else"
-msgstr ""
+msgstr "Vreau să mut depozitul meu în GitLab din altă parte"
msgid "I want to store my code"
-msgstr ""
+msgstr "Doresc să-mi stochez codul"
msgid "I want to use GitLab CI with my existing repository"
-msgstr ""
+msgstr "Vreau să folosesc GitLab CI cu repozitoriul meu existent"
msgid "I'd like to receive updates about GitLab via email"
msgstr ""
msgid "I'm signing up for GitLab because:"
-msgstr ""
+msgstr "Mă înscriu la GitLab pentru că:"
msgid "ID"
msgstr ""
@@ -16748,7 +16883,7 @@ msgid "IDE|Back"
msgstr ""
msgid "IDE|Commit"
-msgstr ""
+msgstr "Commit"
msgid "IDE|Commit to %{branchName} branch"
msgstr ""
@@ -16826,9 +16961,9 @@ msgid "If disabled, a diverged local branch will not be automatically updated wi
msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
-msgstr ""
+msgstr "Dacă dezactivat, numai administratorii pot configura replicarea repozitoriului."
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16877,7 +17012,7 @@ msgid "If you did not recently sign in, you should immediately change your passw
msgstr ""
msgid "If you get a lot of false alarms from repository checks, you can clear all repository check information from the database."
-msgstr ""
+msgstr "Dacă primiți o mulțime de alarme false din verificările repozitoriului, puteți șterge toate informațiile verificării repozitoriului din baza de date."
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
msgstr ""
@@ -16892,7 +17027,7 @@ msgid "If you want to re-enable two-factor authentication, visit the %{settings_
msgstr ""
msgid "If you've purchased or renewed your subscription and have an activation code, please enter it below to start the activation process."
-msgstr ""
+msgstr "Dacă ați achiziționat sau ați reînnoit abonamentul și aveți un cod de activare, vă rugăm să îl introduceți mai jos pentru a începe procesul de activare."
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -17096,13 +17231,13 @@ msgid "Importing..."
msgstr ""
msgid "Import|A repository URL usually ends in a .git suffix, although this is not required. Double check to make sure your repository URL is correct."
-msgstr ""
+msgstr "Un URL repozitoriu se termină de obicei într-un subfix .git, dar acest lucru nu este necesar. Verificați atent pentru a vă asigura că URL-ul repozitoriului dvs. este corect."
msgid "Improve customer support with Service Desk"
msgstr ""
msgid "Improves Git cloning performance."
-msgstr ""
+msgstr "Îmbunătățește performanța de clonare Git."
msgid "In %{time_to_now}"
msgstr ""
@@ -17114,11 +17249,14 @@ msgid "In each example, replace %{code_start}TOKEN%{code_end} with the trigger t
msgstr ""
msgid "In progress"
-msgstr ""
+msgstr "În desfășurare"
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17135,7 +17273,7 @@ msgid "InProductMarketing|%{strong_start}Multiple approval roles%{strong_end} â€
msgstr ""
msgid "InProductMarketing|%{strong_start}Overall, how difficult or easy was it to get started with GitLab?%{strong_end}"
-msgstr ""
+msgstr "%{strong_start}În general, cât de dificil sau ușor a fost să începi cu GitLab?%{strong_end}"
msgid "InProductMarketing|*GitLab*, noun: a synonym for efficient teams"
msgstr ""
@@ -17159,7 +17297,7 @@ msgid "InProductMarketing|Automated security scans directly within GitLab"
msgstr ""
msgid "InProductMarketing|Be a DevOps hero"
-msgstr ""
+msgstr "Devino un erou DevOps"
msgid "InProductMarketing|Beef up your security"
msgstr ""
@@ -17174,16 +17312,16 @@ msgid "InProductMarketing|By enabling code owners and required merge approvals t
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
-msgstr ""
+msgstr "Faceți clic pe numărul de mai jos care corespunde răspunsului dvs. - 1 fiind foarte dificil, 5 fiind foarte ușor."
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
-msgstr ""
+msgstr "Creați un executor CI personalizat cu doar câteva clicuri"
msgid "InProductMarketing|Create a custom runner"
-msgstr ""
+msgstr "Creați un executor personalizat"
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
@@ -17192,25 +17330,25 @@ msgid "InProductMarketing|Create your first project!"
msgstr ""
msgid "InProductMarketing|Deliver Better Products Faster"
-msgstr ""
+msgstr "Livrați Produse mai Bune, mai Repede"
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
msgid "InProductMarketing|Difficult"
-msgstr ""
+msgstr "Dificil"
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
msgid "InProductMarketing|Do you have a minute?"
-msgstr ""
+msgstr "Aveți un minut?"
msgid "InProductMarketing|Easy"
-msgstr ""
+msgstr "Ușor"
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
-msgstr ""
+msgstr "Extindeți-vă parcursul DevOps cu o perioadă de încercare gratuită GitLab"
msgid "InProductMarketing|Explore GitLab CI/CD"
msgstr ""
@@ -17225,7 +17363,7 @@ msgid "InProductMarketing|Facebook"
msgstr ""
msgid "InProductMarketing|Feedback from users like you really improves our product. Thanks for your help!"
-msgstr ""
+msgstr "Feedback-ul utilizatorilor ca dvs. îmbunătățește cu adevărat produsul nostru. Mulțumim pentru ajutor!"
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
@@ -17237,7 +17375,7 @@ msgid "InProductMarketing|Follow our steps"
msgstr ""
msgid "InProductMarketing|Free 30-day trial"
-msgstr ""
+msgstr "Perioadă de încercare de 30 de zile gratuită"
msgid "InProductMarketing|Get going with CI/CD quickly using our %{quick_start_link}. Start with an available runner and then create a CI .yml file – it's really that easy."
msgstr ""
@@ -17318,7 +17456,7 @@ msgid "InProductMarketing|Improve code quality and streamline reviews"
msgstr ""
msgid "InProductMarketing|Increase Operational Efficiencies"
-msgstr ""
+msgstr "Sporiți Eficiența Operațională"
msgid "InProductMarketing|Invite your colleagues and start shipping code faster."
msgstr ""
@@ -17336,7 +17474,7 @@ msgid "InProductMarketing|Invite your team now"
msgstr ""
msgid "InProductMarketing|Invite your team today to build better code (and processes) together"
-msgstr ""
+msgstr "Invitați-vă echipa astăzi pentru a construi cod mai bun (și procese) împreună"
msgid "InProductMarketing|It's all in the stats"
msgstr ""
@@ -17363,10 +17501,10 @@ msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
msgid "InProductMarketing|Neutral"
-msgstr ""
+msgstr "Neutru"
msgid "InProductMarketing|No credit card required."
-msgstr ""
+msgstr "Nu este necesar un card de credit."
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
@@ -17375,7 +17513,7 @@ msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
-msgstr ""
+msgstr "Reduceți Riscul de Securitate și Conformitate"
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
@@ -17417,7 +17555,7 @@ msgid "InProductMarketing|Streamline code review, know at a glance who's unavail
msgstr ""
msgid "InProductMarketing|Take this 1-question survey!"
-msgstr ""
+msgstr "Faceți acest sondaj cu 1 întrebare!"
msgid "InProductMarketing|Take your first steps with GitLab"
msgstr ""
@@ -17438,7 +17576,7 @@ msgid "InProductMarketing|That's all it takes to get going with GitLab, but if y
msgstr ""
msgid "InProductMarketing|This is email %{current_series} of %{total_series} in the %{track} series."
-msgstr ""
+msgstr "Acesta este e-mailul %{current_series} din %{total_series} în seria %{track}."
msgid "InProductMarketing|This is email %{current_series} of %{total_series} in the %{track} series. To disable notification emails sent by your local GitLab instance, either contact your administrator or %{unsubscribe_link}."
msgstr ""
@@ -17465,7 +17603,7 @@ msgid "InProductMarketing|Try it yourself"
msgstr ""
msgid "InProductMarketing|Turn coworkers into collaborators"
-msgstr ""
+msgstr "Transformați colegii în colaboratori"
msgid "InProductMarketing|Twitter"
msgstr ""
@@ -17480,10 +17618,10 @@ msgid "InProductMarketing|Use GitLab CI/CD"
msgstr ""
msgid "InProductMarketing|Use our AWS cloudformation template to spin up your runners in just a few clicks!"
-msgstr ""
+msgstr "Utilizați șablonul nostru de cloudformation AWS pentru a vă dezvolta executorii în doar câteva clicuri!"
msgid "InProductMarketing|Used by more than 100,000 organizations from around the globe:"
-msgstr ""
+msgstr "Utilizat de peste 100.000 de organizații din întreaga lume:"
msgid "InProductMarketing|Very difficult"
msgstr ""
@@ -17750,10 +17888,10 @@ msgid "Include merge request description"
msgstr ""
msgid "Include new features from all tiers."
-msgstr ""
+msgstr "Include funcții noi din toate nivelurile."
msgid "Include the name of the author of the issue, merge request or comment in the email body. By default, GitLab overrides the email sender's name. Some email servers don't support that option."
-msgstr ""
+msgstr "Includeți numele autorului acestei probleme, cereri de îmbinare sau comentariu în corpul e-mailului. În mod implicit, GitLab suprascrie numele expeditorului. Unele servere de e-mail nu suportă acea opțiuni."
msgid "Include the username in the URL if required: %{code_open}https://username@gitlab.company.com/group/project.git%{code_close}."
msgstr ""
@@ -17807,7 +17945,7 @@ msgid "Inform users without uploaded SSH keys that they can't push over SSH unti
msgstr ""
msgid "Infrastructure"
-msgstr ""
+msgstr "Infrastructură"
msgid "Infrastructure Registry"
msgstr ""
@@ -17858,10 +17996,10 @@ msgid "Input the remote repository URL"
msgstr ""
msgid "Insert"
-msgstr ""
+msgstr "Inserați"
msgid "Insert a %{rows}x%{cols} table."
-msgstr ""
+msgstr "Inserați un tabel %{rows}x%{cols}"
msgid "Insert a code block"
msgstr ""
@@ -17878,6 +18016,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17887,6 +18031,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17969,7 +18119,7 @@ msgid "Integrations|Add namespace"
msgstr ""
msgid "Integrations|Adding a namespace works only in browsers that allow cross‑site cookies. Use %{firefox_link_start}Firefox%{link_end}, %{chrome_link_start}Google Chrome%{link_end}, or enable cross‑site cookies in your browser, when adding a namespace."
-msgstr ""
+msgstr "Adăugarea unui spațiu de nume funcționează numai în browsere care permit cookie-uri cross-site. Utilizați %{firefox_link_start}Firefox%{link_end}, %{chrome_link_start}Google Chrome%{link_end}, sau activați cookie-urile cross-site în browserul dvs., când adăugați un spațiu de nume."
msgid "Integrations|All details"
msgstr ""
@@ -17977,6 +18127,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -18038,7 +18191,7 @@ msgid "Integrations|Issues created in Jira are shown here once you have created
msgstr ""
msgid "Integrations|Keep your PHP dependencies updated on Packagist."
-msgstr ""
+msgstr "Păstrați-vă dependențele PHP actualizate pe Packagist."
msgid "Integrations|Link namespaces"
msgstr ""
@@ -18062,7 +18215,7 @@ msgid "Integrations|Note: this integration only works with accounts on GitLab.co
msgstr ""
msgid "Integrations|Projects using custom settings"
-msgstr ""
+msgstr "Proiecte utilizând setări personalizate"
msgid "Integrations|Projects using custom settings will not be affected."
msgstr ""
@@ -18097,6 +18250,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18221,7 +18377,7 @@ msgid "Invalid pod_name"
msgstr ""
msgid "Invalid policy type"
-msgstr ""
+msgstr "Tip politică invalid"
msgid "Invalid query"
msgstr ""
@@ -18275,7 +18431,7 @@ msgid "Invite a group"
msgstr ""
msgid "Invite email has already been taken"
-msgstr ""
+msgstr "E-mail invitație a fost preluat deja"
msgid "Invite group"
msgstr ""
@@ -18286,9 +18442,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18305,10 +18458,10 @@ msgid "InviteEmail|Join now"
msgstr ""
msgid "InviteEmail|Join your team on GitLab! %{inviter} invited you to %{project_or_group_name}"
-msgstr ""
+msgstr "Alăturați-vă echipei dvs. pe GitLab! %{inviter} v-a invitat în %{project_or_group_name}"
msgid "InviteEmail|Join your team on GitLab! You are invited to %{project_or_group_name}"
-msgstr ""
+msgstr "Alăturați-vă echipei dvs. pe GitLab! Sunteți invitat în %{project_or_group_name}"
msgid "InviteEmail|Projects are used to host and collaborate on code, track issues, and continuously build, test, and deploy your app with built-in GitLab CI/CD."
msgstr ""
@@ -18332,7 +18485,7 @@ msgid "InviteMembersBanner|We noticed that you haven't invited anyone to this gr
msgstr ""
msgid "InviteMembersModal|%{linkStart}Read more%{linkEnd} about role permissions"
-msgstr ""
+msgstr "%{linkStart}Citiți mai multe%{linkEnd} despre permisiuni rol"
msgid "InviteMembersModal|Access expiration date (optional)"
msgstr ""
@@ -18344,16 +18497,16 @@ msgid "InviteMembersModal|Close invite team members"
msgstr ""
msgid "InviteMembersModal|Collaborate on open issues and merge requests"
-msgstr ""
+msgstr "Colaborați pe probleme și cereri de îmbinare deschise"
msgid "InviteMembersModal|Configure CI/CD"
-msgstr ""
+msgstr "Configurați CI/CD"
msgid "InviteMembersModal|Configure security features"
-msgstr ""
+msgstr "Configurați funcțiile de securitate"
msgid "InviteMembersModal|Contribute to the codebase"
-msgstr ""
+msgstr "Contribuiți la baza de cod"
msgid "InviteMembersModal|GitLab member or email address"
msgstr ""
@@ -18371,7 +18524,7 @@ msgid "InviteMembersModal|Members were successfully added"
msgstr ""
msgid "InviteMembersModal|Other"
-msgstr ""
+msgstr "Altele"
msgid "InviteMembersModal|Search for a group to invite"
msgstr ""
@@ -18386,10 +18539,10 @@ msgid "InviteMembersModal|Select members or type email addresses"
msgstr ""
msgid "InviteMembersModal|Something went wrong"
-msgstr ""
+msgstr "Ceva nu a mers bine"
msgid "InviteMembersModal|What would you like new member(s) to focus on? (optional)"
-msgstr ""
+msgstr "Pe ce ați vrea să se concentreze membri noi? (opțional)"
msgid "InviteMembersModal|You're inviting a group to the %{strongStart}%{name}%{strongEnd} group."
msgstr ""
@@ -18479,40 +18632,40 @@ msgid "Invocations"
msgstr ""
msgid "IrkerService|Channels and users separated by whitespaces. %{recipients_docs_link}"
-msgstr ""
+msgstr "Canale și utilizatori separați prin spații albe. %{recipients_docs_link}"
msgid "IrkerService|Default IRC URI (optional)"
-msgstr ""
+msgstr "URL IRC prestabilit (opțional)"
msgid "IrkerService|How to enter channels or users?"
-msgstr ""
+msgstr "Cum se introduc canale sau utilizatori?"
msgid "IrkerService|Recipients"
-msgstr ""
+msgstr "Destinatari"
msgid "IrkerService|Send update messages to an irker server."
-msgstr ""
+msgstr "Trimiteți mesaje actualizare către un server irker."
msgid "IrkerService|Send update messages to an irker server. Before you can use this, you need to set up the irker daemon. %{docs_link}"
-msgstr ""
+msgstr "Trimiteți mesaje actualizare către un server irker. Înainte de a putea folosi asta, trebuie să setați daemon-ul irker. %{docs_link}"
msgid "IrkerService|Server host (optional)"
-msgstr ""
+msgstr "Gazdă server (opțional)"
msgid "IrkerService|Server port (optional)"
-msgstr ""
+msgstr "Port server (opțional)"
msgid "IrkerService|URI to add before each recipient."
-msgstr ""
+msgstr "URI de adăugat înaintea fiecărui destinatar."
msgid "IrkerService|irker (IRC gateway)"
-msgstr ""
+msgstr "irker (poartă IRC)"
msgid "IrkerService|irker daemon hostname (defaults to localhost)."
-msgstr ""
+msgstr "hostname daemon irker (valoarea implicită este localhost)."
msgid "IrkerService|irker daemon port (defaults to 6659)."
-msgstr ""
+msgstr "port daemon irker (valoarea implicită este 6659)."
msgid "Is blocked by"
msgstr ""
@@ -18554,7 +18707,7 @@ msgid "Issue Boards"
msgstr ""
msgid "Issue Type"
-msgstr ""
+msgstr "Tip Problemă"
msgid "Issue already promoted to epic."
msgstr ""
@@ -18566,7 +18719,7 @@ msgid "Issue created from vulnerability %{vulnerability_link}"
msgstr ""
msgid "Issue creation requests"
-msgstr ""
+msgstr "Cereri de creare problemă"
msgid "Issue details"
msgstr ""
@@ -18656,7 +18809,7 @@ msgid "IssueTracker|Custom issue tracker"
msgstr ""
msgid "IssueTracker|Issue URL"
-msgstr ""
+msgstr "URL-ul problemei"
msgid "IssueTracker|New issue URL"
msgstr ""
@@ -18826,6 +18979,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -18839,7 +18995,7 @@ msgid "Iterations|Edit cadence"
msgstr ""
msgid "Iterations|Edit iteration"
-msgstr ""
+msgstr "Editați iterația"
msgid "Iterations|Edit iteration cadence"
msgstr ""
@@ -18851,7 +19007,7 @@ msgid "Iterations|Future iterations"
msgstr ""
msgid "Iterations|Iteration cadences"
-msgstr ""
+msgstr "Cadențe iterații"
msgid "Iterations|Iteration scheduling will be handled automatically"
msgstr ""
@@ -18860,7 +19016,7 @@ msgid "Iterations|Move incomplete issues to the next iteration"
msgstr ""
msgid "Iterations|New iteration"
-msgstr ""
+msgstr "Iterație nouă"
msgid "Iterations|New iteration cadence"
msgstr ""
@@ -18911,7 +19067,7 @@ msgid "Iteration|Dates cannot overlap with other existing Iterations within this
msgstr ""
msgid "Iteration|Dates cannot overlap with other existing Iterations within this iterations cadence"
-msgstr ""
+msgstr "Datele nu se pot suprapune cu alte iterații în cadența acestei iterații"
msgid "Iteration|cannot be more than 500 years in the future"
msgstr ""
@@ -18968,19 +19124,19 @@ msgid "Jira-GitLab user mapping template"
msgstr ""
msgid "JiraConnect|Create branch for Jira issue %{jiraIssue}"
-msgstr ""
+msgstr "Creați ramură pentru problemă Jira %{jiraIssue}"
msgid "JiraConnect|Failed to create branch."
-msgstr ""
+msgstr "Crearea ramurii a eșuat."
msgid "JiraConnect|Failed to create branch. Please try again."
-msgstr ""
+msgstr "Crearea ramurii a eșuat. Vă rugăm încercați din nou."
msgid "JiraConnect|New branch was successfully created."
-msgstr ""
+msgstr "Ramura nouă a fost creată cu succes."
msgid "JiraConnect|You can now close this window and return to Jira."
-msgstr ""
+msgstr "Puteți închide această fereastră acum și să vă întoarceți la Jira."
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -18992,16 +19148,16 @@ msgid "JiraRequest|An SSL error occurred while connecting to Jira: %{message}. T
msgstr ""
msgid "JiraRequest|An error occurred while requesting data from Jira. Check your Jira integration configuration and try again."
-msgstr ""
+msgstr "A apărut o eroare în timp ce se solicitau date de la Jira. Verificați configurația integrației Jira și încercați din nou."
msgid "JiraRequest|An error occurred while requesting data from Jira: %{messages}. Check your Jira integration configuration and try again."
-msgstr ""
+msgstr "A apărut o eroare în timp ce se solicitau date de la Jira: %{messages}. Verificați configurația integrației Jira și încercați din nou."
msgid "JiraRequest|The Jira API URL for connecting to Jira is not valid. Check your Jira integration API URL and try again."
-msgstr ""
+msgstr "URL-ul API Jira pentru conectarea la Jira nu este valid. Verificați-vă URL-ul API Integrație Jira și încercați din nou."
msgid "JiraRequest|The credentials for accessing Jira are not allowed to access the data. Check your Jira integration credentials and try again."
-msgstr ""
+msgstr "Acreditările pentru accesarea Jira nu au permisiunea de a accesa datele. Verificați-vă acreditările integrației Jira și încercați din nou."
msgid "JiraRequest|The credentials for accessing Jira are not valid. Check your Jira integration credentials and try again."
msgstr ""
@@ -19094,7 +19250,7 @@ msgid "JiraService|Jira comments are created when an issue is referenced in a co
msgstr ""
msgid "JiraService|Jira comments are created when an issue is referenced in a merge request."
-msgstr ""
+msgstr "Comentariile Jira sunt create atunci când se face referire la o problemă într-un merge request."
msgid "JiraService|Jira issue type"
msgstr ""
@@ -19265,7 +19421,7 @@ msgid "Job|Browse"
msgstr ""
msgid "Job|Complete Raw"
-msgstr ""
+msgstr "Brut complet"
msgid "Job|Download"
msgstr ""
@@ -19280,7 +19436,7 @@ msgid "Job|Job has been erased"
msgstr ""
msgid "Job|Job has been erased by %{userLink}"
-msgstr ""
+msgstr "Jobul a fost șters de %{userLink}"
msgid "Job|Keep"
msgstr ""
@@ -19295,7 +19451,7 @@ msgid "Job|Scroll to top"
msgstr ""
msgid "Job|Show complete raw"
-msgstr ""
+msgstr "Afișați brut complet"
msgid "Job|The artifacts were removed"
msgstr ""
@@ -19442,7 +19598,7 @@ msgid "Kubernetes"
msgstr ""
msgid "Kubernetes API returned status code: %{error_code}"
-msgstr ""
+msgstr "API-ul Kubernetes a returnat codul de stare: %{error_code}"
msgid "Kubernetes Cluster"
msgstr ""
@@ -19472,7 +19628,7 @@ msgid "Kubernetes deployment not found"
msgstr ""
msgid "Kubernetes error: %{error_code}"
-msgstr ""
+msgstr "Eroare Kubernetes: %{error_code}"
msgid "LDAP"
msgstr ""
@@ -19519,9 +19675,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19598,7 +19751,7 @@ msgid "Last Accessed On"
msgstr ""
msgid "Last Activity"
-msgstr ""
+msgstr "Ultima activitate"
msgid "Last Pipeline"
msgstr ""
@@ -19631,7 +19784,7 @@ msgid "Last item before this page loaded in your browser:"
msgstr ""
msgid "Last modified"
-msgstr ""
+msgstr "Ultima dată modificat"
msgid "Last month"
msgstr ""
@@ -19645,9 +19798,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19666,6 +19816,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19730,7 +19883,7 @@ msgid "Learn More"
msgstr ""
msgid "Learn More."
-msgstr ""
+msgstr "Aflați mai multe."
msgid "Learn how to %{link_start}contribute to the built-in templates%{link_end}"
msgstr ""
@@ -19868,10 +20021,10 @@ msgid "LearnGitLab|Start a free Ultimate trial"
msgstr ""
msgid "LearnGitLab|Submit a merge request"
-msgstr ""
+msgstr "Trimiteți un merge request"
msgid "LearnGitLab|Submit a merge request (MR)"
-msgstr ""
+msgstr "Trimiteți un merge request (MR)"
msgid "LearnGitLab|Try GitLab Ultimate for free"
msgstr ""
@@ -19913,7 +20066,7 @@ msgid "Leave zen mode"
msgstr ""
msgid "Leaving this setting enabled is recommended."
-msgstr ""
+msgstr "Este recomandat să lăsați această setare activată."
msgid "Legacy burndown chart"
msgstr ""
@@ -20113,10 +20266,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20162,7 +20318,7 @@ msgid "Link to go to GitLab pipeline documentation"
msgstr ""
msgid "Link to your Grafana instance."
-msgstr ""
+msgstr "Link către instanța dvs. Grafana."
msgid "Linked emails (%{email_count})"
msgstr ""
@@ -20501,13 +20657,13 @@ msgid "Markdown Help"
msgstr ""
msgid "Markdown enabled."
-msgstr ""
+msgstr "Markdown activat."
msgid "Markdown is supported"
msgstr ""
msgid "Markdown supported."
-msgstr ""
+msgstr "Markdown suportat."
msgid "MarkdownEditor|Add a link (%{modifierKey}K)"
msgstr ""
@@ -20576,7 +20732,7 @@ msgid "MattermostService|After you configure the integration, view your new Matt
msgstr ""
msgid "MattermostService|Command trigger word"
-msgstr ""
+msgstr "Comandă cuvânt de declanșare"
msgid "MattermostService|Fill in the word that works best for your team."
msgstr ""
@@ -20615,7 +20771,7 @@ msgid "Max Group Import requests per minute per user"
msgstr ""
msgid "Max Project Export Download requests per minute per user"
-msgstr ""
+msgstr "Cereri maxime de descărcare export proiect/minut pe utilizator"
msgid "Max Project Export requests per minute per user"
msgstr ""
@@ -20626,6 +20782,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20674,6 +20833,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20692,6 +20854,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20704,7 +20869,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20719,9 +20884,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20755,6 +20926,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20779,6 +20956,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20786,7 +20966,7 @@ msgid "Maximum time for web terminal websocket connection (in seconds). 0 for un
msgstr ""
msgid "Maximum time that users are allowed to skip the setup of two-factor authentication (in hours). Set to 0 (zero) to enforce at next sign in."
-msgstr ""
+msgstr "Timpul maxim în care utilizatorii au permisiunea de a sări peste setarea autentificării prin doi pași (în ore). Setați la 0 (zero) pentru a forța la următoarea conectare."
msgid "May"
msgstr ""
@@ -20798,7 +20978,7 @@ msgid "Measured in bytes of code. Excludes generated and vendored code."
msgstr ""
msgid "Medium timeout"
-msgstr ""
+msgstr "Timp de expirare mediu"
msgid "Medium vulnerabilities present"
msgstr ""
@@ -20818,6 +20998,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20986,9 +21169,12 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
-msgid "Merge blocked: the source branch must be rebased onto the target branch."
+msgid "Merge blocked: new changes were just added."
msgstr ""
+msgid "Merge blocked: the source branch must be rebased onto the target branch."
+msgstr "Îmbinare blocată: ramura sursă trebuie să fie rebazată pe ramura țintă."
+
msgid "Merge commit SHA"
msgstr ""
@@ -21103,9 +21289,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -21118,9 +21301,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21179,7 +21359,7 @@ msgid "MergeRequest|Search files (%{modifier_key}P)"
msgstr ""
msgid "Merged"
-msgstr ""
+msgstr "ÃŽmbinat"
msgid "Merged MRs"
msgstr ""
@@ -21188,7 +21368,7 @@ msgid "Merged branches are being deleted. This can take some time depending on t
msgstr ""
msgid "Merged by"
-msgstr ""
+msgstr "ÃŽmbinat de"
msgid "Merged this merge request."
msgstr ""
@@ -21212,7 +21392,7 @@ msgid "Method"
msgstr ""
msgid "Method call threshold (ms)"
-msgstr ""
+msgstr "Prag metodă apel (ms)"
msgid "Metric was successfully added."
msgstr ""
@@ -21482,7 +21662,7 @@ msgid "Metrics|There was an error creating the dashboard."
msgstr ""
msgid "Metrics|There was an error creating the dashboard. %{error}"
-msgstr ""
+msgstr "A apărut o eroare la crearea panoului de control. %{error}"
msgid "Metrics|There was an error fetching annotations. Please try again."
msgstr ""
@@ -21604,9 +21784,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21845,7 +22022,7 @@ msgid "Monitor Settings"
msgstr ""
msgid "Monitor the health and performance of GitLab with Prometheus."
-msgstr ""
+msgstr "Monitorizați sănătatea și performanța GitLab cu Prometheus."
msgid "Monitor your errors by integrating with Sentry."
msgstr ""
@@ -21890,7 +22067,7 @@ msgid "More than %{number_commits_distance} commits different with %{default_bra
msgstr ""
msgid "More topics"
-msgstr ""
+msgstr "Mai multe subiecte"
msgid "Most relevant"
msgstr ""
@@ -21980,12 +22157,12 @@ msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
msgid "Multiplier to apply to polling intervals. Decimal values are supported. Defaults to 1."
-msgstr ""
+msgstr "Multiplicator aplicabil intervalelor de sondaj. Valori decimale sunt suportate. Valoarea implicită este 1."
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22177,12 +22354,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22199,10 +22370,10 @@ msgid "NetworkPolicies|Invalid or empty policy"
msgstr ""
msgid "NetworkPolicies|Invalid or unsupported policy kind"
-msgstr ""
+msgstr "Tip politică invalid sau nesuportat"
msgid "NetworkPolicies|Kubernetes error: %{error}"
-msgstr ""
+msgstr "Eroare Kubernetes: %{error}"
msgid "NetworkPolicies|Name"
msgstr ""
@@ -22225,9 +22396,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22237,21 +22405,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22267,9 +22426,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22417,9 +22573,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22478,7 +22631,7 @@ msgid "New list"
msgstr ""
msgid "New merge request"
-msgstr ""
+msgstr "Merge request nou"
msgid "New milestone"
msgstr ""
@@ -22574,7 +22727,7 @@ msgid "No %{providerTitle} repositories found"
msgstr ""
msgid "No CSV data to display."
-msgstr ""
+msgstr "Nu există date CSV de afișat."
msgid "No Epic"
msgstr ""
@@ -22583,7 +22736,7 @@ msgid "No Matching Results"
msgstr ""
msgid "No Milestone"
-msgstr ""
+msgstr "Niciun Obiectiv"
msgid "No Scopes"
msgstr ""
@@ -22601,6 +22754,9 @@ msgid "No application_settings found"
msgstr ""
msgid "No approvers"
+msgstr "Niciun aprobator"
+
+msgid "No artifacts found"
msgstr ""
msgid "No assignee"
@@ -22628,13 +22784,13 @@ msgid "No child epics match applied filters"
msgstr ""
msgid "No commenters"
-msgstr ""
+msgstr "Niciun comentator"
msgid "No commits present here"
msgstr ""
msgid "No committers"
-msgstr ""
+msgstr "Niciun comitent"
msgid "No compliance frameworks are in use."
msgstr ""
@@ -22820,7 +22976,7 @@ msgid "No schedules"
msgstr ""
msgid "No severity matches the provided parameter"
-msgstr ""
+msgstr "Nicio severitate nu corespunde parametrului furnizat"
msgid "No source selected"
msgstr ""
@@ -22931,10 +23087,10 @@ msgid "Note"
msgstr ""
msgid "Note creation requests"
-msgstr ""
+msgstr "Solicitări creare notă"
msgid "Note parameters are invalid: %{errors}"
-msgstr ""
+msgstr "Parametrii notei nu sunt valabili: %{errors}"
msgid "Note that pushing to GitLab requires write access to this repository."
msgstr ""
@@ -23045,7 +23201,7 @@ msgid "NotificationEvent|Issue due"
msgstr ""
msgid "NotificationEvent|Merge merge request"
-msgstr ""
+msgstr "Îmbinați merge request"
msgid "NotificationEvent|Merge when pipeline succeeds"
msgstr ""
@@ -23117,7 +23273,7 @@ msgid "Notifications on"
msgstr ""
msgid "Notify users by email when sign-in location is not recognized."
-msgstr ""
+msgstr "Notificați utilizatorii prin e-mail când locația de autentificare nu este recunoscută."
msgid "Nov"
msgstr ""
@@ -23128,6 +23284,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23135,13 +23294,13 @@ msgid "Number of Elasticsearch shards and replicas (per index)"
msgstr ""
msgid "Number of Git pushes after which %{code_start}git gc%{code_end} is run."
-msgstr ""
+msgstr "Numărul de împingeri Git după ce %{code_start}git gc%{code_end} este executat."
msgid "Number of Git pushes after which a full %{code_start}git repack%{code_end} is run."
-msgstr ""
+msgstr "Numărul de împingeri Git după ce un %{code_start}git repack%{code_end} complet este executat."
msgid "Number of Git pushes after which an incremental %{code_start}git repack%{code_end} is run."
-msgstr ""
+msgstr "Numărul de împingeri Git după ce un %{code_start}git repack%{code_end} incremental este executat."
msgid "Number of LOCs per commit"
msgstr ""
@@ -23225,7 +23384,7 @@ msgid "On-call schedules"
msgstr ""
msgid "OnCallScheduless|Any escalation rules that are using this schedule will also be deleted."
-msgstr ""
+msgstr "Orice regulă de escaladare care folosește acest program va fi, de asemenea, ștearsă."
msgid "OnCallSchedules|1 day"
msgstr ""
@@ -23257,7 +23416,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23375,7 +23534,7 @@ msgid "OnCallSchedules|You are currently a part of:"
msgstr ""
msgid "OnCallSchedules|Your schedule has been successfully created. To add individual users to this schedule, use the Add a rotation button. To enable notifications for this schedule, you must also create an %{linkStart}escalation policy%{linkEnd}."
-msgstr ""
+msgstr "Programul dvs. a fost creat cu succes. Pentru a adăuga utilizatori individuali la acest program, utilizați butonul Adăugați o rotație. Pentru a activa notificări pentru acest program, trebuie să creați și o %{linkStart}politică de escaladare%{linkEnd}."
msgid "OnDemandScans|Could not fetch scanner profiles. Please refresh the page, or try again later."
msgstr ""
@@ -23465,7 +23624,7 @@ msgid "Once a project is permanently deleted, it %{strongStart}cannot be recover
msgstr ""
msgid "Once a project is permanently deleted, it cannot be recovered. You will lose this project's repository and all related resources, including issues and merge requests."
-msgstr ""
+msgstr "După ce un proiect este șters permanent, nu mai poate fi recuperat. Veți pierde repozitoriul acestui proiect și toate resursele aferente, incluzând probleme și cereri de îmbinare."
msgid "Once imported, repositories can be mirrored over SSH. Read more %{link_start}here%{link_end}."
msgstr ""
@@ -23504,7 +23663,7 @@ msgid "One or more of your personal access tokens will expire in %{days_to_expir
msgstr ""
msgid "Only 'Reporter' roles and above on tiers Premium and above can see Value Stream Analytics."
-msgstr ""
+msgstr "Doar rolurile 'Reporter' și mai sus pe niveluri Premium și mai sus pot vedea analitici Value Stream."
msgid "Only 1 appearances row can exist"
msgstr ""
@@ -23516,13 +23675,13 @@ msgid "Only Project Members"
msgstr ""
msgid "Only active projects show up in the search and on the dashboard."
-msgstr ""
+msgstr "Doar proiectele active sunt afișate în căutare și în panoul de control."
msgid "Only admins can delete project"
msgstr ""
msgid "Only include features new to your current subscription tier."
-msgstr ""
+msgstr "Includeți doar funcții noi pentru nivelul abonamentului dvs. curent"
msgid "Only policy:"
msgstr ""
@@ -23554,7 +23713,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23729,10 +23888,10 @@ msgid "Package Registry Rate Limits"
msgstr ""
msgid "Package Registry: authenticated API requests"
-msgstr ""
+msgstr "Registru de pachete: solicitări API autentificate"
msgid "Package Registry: unauthenticated API requests"
-msgstr ""
+msgstr "Registru pachete: solicitări API neautentificate"
msgid "Package already exists"
msgstr ""
@@ -23746,6 +23905,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -23894,7 +24056,7 @@ msgid "PackageRegistry|Delete package"
msgstr ""
msgid "PackageRegistry|Failed to load the package data"
-msgstr ""
+msgstr "Încărcarea datelor pachetului a eșuat"
msgid "PackageRegistry|For more information on Composer packages in GitLab, %{linkStart}see the documentation.%{linkEnd}"
msgstr ""
@@ -23927,7 +24089,7 @@ msgid "PackageRegistry|Gradle Kotlin DSL install command"
msgstr ""
msgid "PackageRegistry|Helm"
-msgstr ""
+msgstr "Helm"
msgid "PackageRegistry|If you haven't already done so, you will need to add the below to your %{codeStart}.pypirc%{codeEnd} file."
msgstr ""
@@ -24239,7 +24401,7 @@ msgid "Paste issue link"
msgstr ""
msgid "Paste project path (i.e. gitlab-org/gitlab)"
-msgstr ""
+msgstr "Inserați traiectoria proiectului (i.e. gitlab-org/gitlab)"
msgid "Paste your public SSH key, which is usually contained in the file '~/.ssh/id_ed25519.pub' or '~/.ssh/id_rsa.pub' and begins with 'ssh-ed25519' or 'ssh-rsa'. Do not paste your private SSH key, as that can compromise your identity."
msgstr ""
@@ -24269,7 +24431,7 @@ msgid "Paused runners don't accept new jobs"
msgstr ""
msgid "Peer review by"
-msgstr ""
+msgstr "Recenzie peer de"
msgid "Pending"
msgstr ""
@@ -24359,13 +24521,13 @@ msgid "PerformanceBar|Trace"
msgstr ""
msgid "Period in seconds"
-msgstr ""
+msgstr "Perioadă în secunde"
msgid "Permanently delete project"
msgstr ""
msgid "Permanently remove group"
-msgstr ""
+msgstr "Eliminați definitiv grupul"
msgid "Permissions"
msgstr ""
@@ -24383,7 +24545,7 @@ msgid "Personal Access Token prefix"
msgstr ""
msgid "Personal access tokens are not revoked upon expiration."
-msgstr ""
+msgstr "Token-urile acces personal nu sunt revocate la expirare."
msgid "Personal project creation is not allowed. Please contact your administrator with questions"
msgstr ""
@@ -24410,7 +24572,7 @@ msgid "Pin code"
msgstr ""
msgid "Pipeline"
-msgstr ""
+msgstr "Conductă"
msgid "Pipeline %{label}"
msgstr ""
@@ -24419,10 +24581,10 @@ msgid "Pipeline %{label} for \"%{dataTitle}\""
msgstr ""
msgid "Pipeline ID"
-msgstr ""
+msgstr "ID conductă"
msgid "Pipeline IID"
-msgstr ""
+msgstr "IID conductă"
msgid "Pipeline Schedule"
msgstr ""
@@ -24431,7 +24593,7 @@ msgid "Pipeline Schedules"
msgstr ""
msgid "Pipeline URL"
-msgstr ""
+msgstr "URL conductă"
msgid "Pipeline durations for the last 30 commits"
msgstr ""
@@ -24476,7 +24638,7 @@ msgid "PipelineCharts|Failed:"
msgstr ""
msgid "PipelineCharts|Overall statistics"
-msgstr ""
+msgstr "Statistici generale"
msgid "PipelineCharts|Success ratio:"
msgstr ""
@@ -24883,6 +25045,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25190,7 +25397,7 @@ msgid "Point to any links you like: documentation, built binaries, or other rela
msgstr ""
msgid "Policies"
-msgstr ""
+msgstr "Politici"
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
@@ -25324,13 +25531,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25342,9 +25546,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25580,7 +25781,7 @@ msgid "Profiles|Connected Accounts"
msgstr ""
msgid "Profiles|Current path: %{path}"
-msgstr ""
+msgstr "Calea curentă: %{path}"
msgid "Profiles|Current status"
msgstr ""
@@ -25609,6 +25810,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25801,9 +26005,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -25961,7 +26162,7 @@ msgid "Project export could not be deleted."
msgstr ""
msgid "Project export download requests"
-msgstr ""
+msgstr "Solicitări descărcare export proiect"
msgid "Project export enabled"
msgstr ""
@@ -25973,16 +26174,16 @@ msgid "Project export link has expired. Please generate a new export from your p
msgstr ""
msgid "Project export requests"
-msgstr ""
+msgstr "Solicitări export proiect"
msgid "Project export started. A download link will be sent by email and made available on this page."
-msgstr ""
+msgstr "A început exportul proiectului. Un link de descărcare va fi trimis prin e-mail și pus la dispoziție pe această pagină."
msgid "Project has too many %{label_for_message} to search"
msgstr ""
msgid "Project import requests"
-msgstr ""
+msgstr "Solicitări import proiect"
msgid "Project info:"
msgstr ""
@@ -26027,7 +26228,7 @@ msgid "Project uploads"
msgstr ""
msgid "Project visibility level will be changed to match namespace rules when transferring to a group."
-msgstr ""
+msgstr "Nivelul vizibilității proiectului va fi modificat pentru a se potrivi cu regulile spațiului de nume atunci când se transferă la un grup."
msgid "Project was not found or you do not have permission to add this project to Security Dashboards."
msgstr ""
@@ -26138,7 +26339,7 @@ msgid "ProjectService|Perform common operations on GitLab project: %{project_nam
msgstr ""
msgid "ProjectService|Run CI/CD pipelines with Buildkite."
-msgstr ""
+msgstr "Executați conducte CI/CD cu Buildkite."
msgid "ProjectService|Run CI/CD pipelines with Drone."
msgstr ""
@@ -26153,7 +26354,7 @@ msgid "ProjectService|The build configuration ID of the TeamCity project."
msgstr ""
msgid "ProjectService|The token you get after you create a Buildkite pipeline with a GitLab repository."
-msgstr ""
+msgstr "Tokenul pe care îl primiți după ce creați o conductă Buildkite cu un repozitoriu GitLab."
msgid "ProjectService|To configure this integration, you should:"
msgstr ""
@@ -26183,7 +26384,7 @@ msgid "ProjectService|Trigger event when a deployment starts or finishes."
msgstr ""
msgid "ProjectService|Trigger event when a merge request is created, updated, or merged."
-msgstr ""
+msgstr "Declanșați evenimentul atunci când un merge request este creat, actualizat sau îmbinat."
msgid "ProjectService|Trigger event when a new, unique alert is recorded."
msgstr ""
@@ -26249,7 +26450,7 @@ msgid "ProjectSettings|Customize this project's badges."
msgstr ""
msgid "ProjectSettings|Determine what happens to the commit history when you merge a merge request."
-msgstr ""
+msgstr "Determinați ce se întâmplă cu istoricul de commit-uri atunci când îmbinați un merge request."
msgid "ProjectSettings|Disable email notifications"
msgstr ""
@@ -26297,7 +26498,7 @@ msgid "ProjectSettings|Fast-forward merges only."
msgstr ""
msgid "ProjectSettings|Flexible tool to collaboratively develop ideas and plan work in this project."
-msgstr ""
+msgstr "Unealtă flexibilă pentru a dezvolta idei colaborativ și de a planifica muncă în acest proiect."
msgid "ProjectSettings|Forks"
msgstr ""
@@ -26351,7 +26552,7 @@ msgid "ProjectSettings|No merge commits are created."
msgstr ""
msgid "ProjectSettings|Note: The container registry is always visible when a project is public and the container registry is set to '%{access_level_description}'"
-msgstr ""
+msgstr "Notă: Registrul containerului este întotdeauna vizibil când un proiect este public și registrul containerului este setat la \"%{access_level_description}\""
msgid "ProjectSettings|Only signed commits can be pushed to this repository."
msgstr ""
@@ -26414,7 +26615,7 @@ msgid "ProjectSettings|Show default award emojis"
msgstr ""
msgid "ProjectSettings|Show link to create or view a merge request when pushing from the command line"
-msgstr ""
+msgstr "Afișați linkul pentru a crea sau a vizualiza un merge request atunci când publicați din linia de comandă"
msgid "ProjectSettings|Skipped pipelines are considered successful"
msgstr ""
@@ -26441,7 +26642,7 @@ msgid "ProjectSettings|Target project"
msgstr ""
msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
-msgstr ""
+msgstr "Mesajul commit utilizat atunci când se aplică sugestii merge request. %{link_start}Aflați mai multe despre sugestii.%{link_end}"
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
@@ -26471,7 +26672,7 @@ msgid "ProjectSettings|Upstream project"
msgstr ""
msgid "ProjectSettings|Used for every new merge request."
-msgstr ""
+msgstr "Folosit pentru fiecare merge request nou."
msgid "ProjectSettings|Users can copy the repository to a new project."
msgstr ""
@@ -26609,7 +26810,7 @@ msgid "Projects shared with %{group_name}"
msgstr ""
msgid "Projects that can be accessed"
-msgstr ""
+msgstr "Proiecte ce pot fi accesate"
msgid "Projects to index"
msgstr ""
@@ -26774,7 +26975,7 @@ msgid "PrometheusAlerts|is less than"
msgstr ""
msgid "PrometheusService|%{exporters} with %{metrics} were found"
-msgstr ""
+msgstr "%{exporters} cu %{metrics} au fost găsiți"
msgid "PrometheusService|Active"
msgstr ""
@@ -26861,7 +27062,7 @@ msgid "PrometheusService|Waiting for your first deployment to an environment to
msgstr ""
msgid "PrometheusService|You can now manage your Prometheus settings on the %{operations_link_start}Operations%{operations_link_end} page. Fields on this page have been deprecated."
-msgstr ""
+msgstr "Puteți acum să vă gestionați setările Prometheus pe pagina de %{operations_link_start}Operațiuni%{operations_link_end}. Câmpurile de pe această pagină sunt învechite."
msgid "PrometheusService|You have a cluster with the Prometheus integration enabled."
msgstr ""
@@ -26900,13 +27101,10 @@ msgid "Promotion is not supported."
msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
-msgstr ""
-
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
+msgstr "Adăugați webhook-uri grup și GitLab Enterprise Edition."
msgid "Promotions|Better Protected Branches"
-msgstr ""
+msgstr "Ramuri mai bine protejate"
msgid "Promotions|Burndown Charts are visual representations of the progress of completing a milestone. At a glance, you see the current state for the completion a given milestone. Without them, you would have to organize the data from the milestone and plot it yourself to have the same sense of progress."
msgstr ""
@@ -26927,13 +27125,13 @@ msgid "Promotions|Contact your Administrator to upgrade your license."
msgstr ""
msgid "Promotions|Description templates allow you to define context-specific templates for issue and merge request description fields for your project."
-msgstr ""
+msgstr "Șablonuri descriere vă permit să definiți șabloane specifice pentru câmpuri de probleme și cereri de îmbinare pentru proiectul dvs."
msgid "Promotions|Dismiss burndown charts promotion"
msgstr ""
msgid "Promotions|Dismiss repository features promotion"
-msgstr ""
+msgstr "Respingeți promovarea funcțiilor repozitoriului"
msgid "Promotions|Don't show me this again"
msgstr ""
@@ -26945,49 +27143,52 @@ msgid "Promotions|Improve issues management with Issue weight and GitLab Enterpr
msgstr ""
msgid "Promotions|Improve merge requests and customer support with GitLab Enterprise Edition."
-msgstr ""
+msgstr "Îmbunătățiți cererile de îmbinare și asistența pentru clienți cu GitLab Enterprise Edition."
msgid "Promotions|Improve milestones with Burndown Charts."
msgstr ""
msgid "Promotions|Improve repositories with GitLab Enterprise Edition."
-msgstr ""
+msgstr "Îmbunătățiți repozitoriile cu GitLab Enterprise Edition."
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
+msgstr "Îmbunătățiți căutarea cu Căutare Avansată și GitLab Enterprise Edition."
+
+msgid "Promotions|Keep track of events in your project"
msgstr ""
msgid "Promotions|Learn more"
msgstr ""
msgid "Promotions|Merge request approvals"
-msgstr ""
+msgstr "Aprobări cereri de îmbinare"
msgid "Promotions|Not now, thanks!"
msgstr ""
msgid "Promotions|Push Rules"
-msgstr ""
+msgstr "Reguli împingere"
msgid "Promotions|Push Rules are defined per project so you can have different rules applied to different projects depends on your needs."
-msgstr ""
+msgstr "Regulile de împingere sunt definite pe proiect așa că puteți avea reguli diferite aplicate unor proiecte diferite, depinzând de nevoile dvs."
msgid "Promotions|Repository Mirroring"
-msgstr ""
+msgstr "Replicare repozitoriu"
msgid "Promotions|Repository Mirroring is a way to mirror repositories from external sources. It can be used to mirror all branches, tags, and commits that you have in your repository."
-msgstr ""
+msgstr "Replicare repozitoriu este o cale de a replica repozitorii din surse externe. Poate fi folosit pentru a replica toate ramurile, etichetele și comiterile din repozitoriul dvs."
msgid "Promotions|See the other features in the %{subscription_link_start}Premium plan%{subscription_link_end}"
msgstr ""
msgid "Promotions|Set the number of necessary approvals and define a list of approvers needed for every merge request in a project."
-msgstr ""
+msgstr "Setați numărul de aprobări necesare și definiți o listă de aprobatori necesari pentru toate cererile de îmbinare dintr-un proiect."
msgid "Promotions|Start GitLab Ultimate trial"
msgstr ""
msgid "Promotions|The Advanced Search in GitLab is a powerful search service that saves you time. Instead of creating duplicate code and wasting time, you can now search for code within other teams that can help your own project."
-msgstr ""
+msgstr "Căutarea Avansată în GitLab este un serviciu puternic de căutare care vă salvează timp. În loc să creați cod duplicat și să irosiți timpul, puteți acum să căutați pentru cod în alte echipe ce poate să vă ajute proiectul."
msgid "Promotions|This feature is locked."
msgstr ""
@@ -26995,9 +27196,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27005,28 +27203,28 @@ msgid "Promotions|Upgrade plan"
msgstr ""
msgid "Promotions|Upgrade your plan to activate Advanced Search."
-msgstr ""
+msgstr "Actualizați-vă planul pentru a activa Căutarea Avansată."
msgid "Promotions|Upgrade your plan to activate Audit Events."
-msgstr ""
+msgstr "Actualizați-vă planul pentru a activa Evenimentele Audit."
msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
msgstr ""
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
-msgstr ""
+msgstr "Actualizați-vă planul pentru a activa webhook-uri grup."
msgid "Promotions|Upgrade your plan to improve merge requests."
-msgstr ""
+msgstr "Actualizați-vă planul pentru a îmbunătăți cererile de îmbinare."
msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
msgstr ""
msgid "Promotions|Upgrade your plan to improve repositories."
-msgstr ""
+msgstr "Actualizați-vă planul pentru a îmbunătăți repozitoriile."
msgid "Promotions|Webhooks allow you to trigger a URL if, for example, new code is pushed or a new issue is created. You can configure webhooks to listen for specific events like pushes, issues or merge requests. Group webhooks will apply to all projects in a group, allowing you to standardize webhook functionality across your entire group."
-msgstr ""
+msgstr "Webhook-urile vă permit să declanșați un URL dacă, de exemplu, cod nou este împins sau o nouă problemă este creată. Puteți configura webhook-urile să asculte pentru evenimente specifice, ca împingeri, probleme, sau cereri de îmbinare. Webhook-uri de grup se aplică la toate proiectele dintr-un grup, permițându-vă să standardizați funcționalitatea webhook în intregul dvs. grup."
msgid "Promotions|Weight"
msgstr ""
@@ -27041,13 +27239,13 @@ msgid "Promotions|With Contribution Analytics you can have an overview for the a
msgstr ""
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
-msgstr ""
+msgstr "Puteți restricționa accesul la ramuri protejate alegând un rol (Întreținători, Dezvoltatori) sau utilizatori individuali."
msgid "Promotions|description templates"
-msgstr ""
+msgstr "Șabloane descriere"
msgid "Promotions|to help your contributors communicate effectively!"
-msgstr ""
+msgstr "pentru a vă ajuta contributorii să comunice eficient!"
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -27077,7 +27275,7 @@ msgid "Protected Paths"
msgstr ""
msgid "Protected Paths: requests"
-msgstr ""
+msgstr "Traiectorii protejate: cereri"
msgid "Protected Tag"
msgstr ""
@@ -27389,28 +27587,28 @@ msgid "PushoverService|%{user_name} pushed new branch \"%{ref}\"."
msgstr ""
msgid "PushoverService|Enter your application key."
-msgstr ""
+msgstr "Introduceți-vă cheia de aplicație."
msgid "PushoverService|Enter your user key."
-msgstr ""
+msgstr "Introduceți-vă cheia de utilizator."
msgid "PushoverService|Get real-time notifications on your device."
msgstr ""
msgid "PushoverService|High priority"
-msgstr ""
+msgstr "Prioritate ridicată"
msgid "PushoverService|Leave blank for all active devices."
-msgstr ""
+msgstr "Lăsați necompletat pentru toate dispozitivele active."
msgid "PushoverService|Low priority"
-msgstr ""
+msgstr "Prioritate redusă"
msgid "PushoverService|Lowest priority"
-msgstr ""
+msgstr "Prioritate minimă"
msgid "PushoverService|Normal priority"
-msgstr ""
+msgstr "Prioritate normală"
msgid "PushoverService|See project %{project_full_name}"
msgstr ""
@@ -27431,10 +27629,10 @@ msgid "Query is valid"
msgstr ""
msgid "Queued"
-msgstr ""
+msgstr "În așteptare"
msgid "Quick actions can be used in description and comment boxes."
-msgstr ""
+msgstr "Acțiuni rapide pot fi folosite în chenare de descriere și comentarii."
msgid "Quick help"
msgstr ""
@@ -27458,16 +27656,16 @@ msgid "Random"
msgstr ""
msgid "Rate Limits"
-msgstr ""
+msgstr "Limite frecvență"
msgid "Rate limit"
-msgstr ""
+msgstr "Limită frecvență"
msgid "Raw blob request rate limit per minute"
msgstr ""
msgid "Raw blob requests"
-msgstr ""
+msgstr "Solicitări brute blob"
msgid "Re-authentication period expired or never requested. Please try again"
msgstr ""
@@ -27485,7 +27683,7 @@ msgid "Read documentation"
msgstr ""
msgid "Read more"
-msgstr ""
+msgstr "Citiți mai mult"
msgid "Read more about GitLab at %{link_to_promo}."
msgstr ""
@@ -27499,6 +27697,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27521,7 +27725,7 @@ msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
msgid "Receive any notifications from GitLab."
-msgstr ""
+msgstr "Primiți orice notificare de la GitLab."
msgid "Receive notifications about your own activity"
msgstr ""
@@ -27568,6 +27772,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27581,7 +27788,7 @@ msgid "References"
msgstr ""
msgid "Refine your search criteria (select a %{strong_open}group%{strong_close} and %{strong_open}project%{strong_close} when possible)"
-msgstr ""
+msgstr "Rafinați-vă criteriul de căutare (selectați un %{strong_open}grup%{strong_close} și %{strong_open}proiect%{strong_close} când este posibil)"
msgid "Refresh"
msgstr ""
@@ -27682,6 +27889,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -27830,7 +28040,7 @@ msgid "Remove favicon"
msgstr ""
msgid "Remove file"
-msgstr ""
+msgstr "Ștergeți fișierul"
msgid "Remove fork relationship"
msgstr ""
@@ -27860,7 +28070,7 @@ msgid "Remove link"
msgstr ""
msgid "Remove list"
-msgstr ""
+msgstr "Ștergeți lista"
msgid "Remove log"
msgstr ""
@@ -28013,7 +28223,7 @@ msgid "Rename/Move"
msgstr ""
msgid "Render diagrams in your documents using PlantUML."
-msgstr ""
+msgstr "Redați diagrame în documentele dvs. utilizând PlantUML."
msgid "Renew subscription"
msgstr ""
@@ -28052,7 +28262,7 @@ msgid "Replace all label(s)"
msgstr ""
msgid "Replace file"
-msgstr ""
+msgstr "Înlocuiți fișierul"
msgid "Replaced all labels with %{label_references} %{label_text}."
msgstr ""
@@ -28201,6 +28411,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28325,7 +28538,7 @@ msgid "Repository mirroring"
msgstr ""
msgid "Repository mirroring configuration"
-msgstr ""
+msgstr "Configurație replicare repozitoriu"
msgid "Repository must contain at least 1 file."
msgstr ""
@@ -28394,16 +28607,16 @@ msgid "Requests Profiles"
msgstr ""
msgid "Requests for pages at %{code_start}%{help_text_url}%{code_end} redirect to the URL. The destination must meet certain requirements. %{docs_link_start}Learn more.%{docs_link_end}"
-msgstr ""
+msgstr "Solicitări pentru pagini la %{code_start}%{help_text_url}%{code_end} sunt redirecționate către URL. Destinația trebuie să întâlnească anumite cerințe. %{docs_link_start}Aflați mai multe.%{docs_link_end}"
msgid "Requests per period"
-msgstr ""
+msgstr "Solicitări pe perioadă"
msgid "Requests to these domain(s)/address(es) on the local network will be allowed when local requests from hooks and services are not allowed. IP ranges such as 1:0:0:0:0:0:0:0/124 or 127.0.0.0/28 are supported. Domain wildcards are not supported currently. Use comma, semicolon, or newline to separate multiple entries. The allowlist can hold a maximum of 1000 entries. Domains should use IDNA encoding. Ex: example.com, 192.168.1.1, 127.0.0.0/28, xn--itlab-j1a.com."
msgstr ""
msgid "Require additional authentication for administrative tasks."
-msgstr ""
+msgstr "Necesită autentificare suplimentară pentru sarcini administrative."
msgid "Require all users in this group to setup Two-factor authentication"
msgstr ""
@@ -28640,7 +28853,7 @@ msgid "Revert this commit"
msgstr ""
msgid "Revert this merge request"
-msgstr ""
+msgstr "Anulați acest merge request"
msgid "Review"
msgstr ""
@@ -28651,6 +28864,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28691,7 +28907,7 @@ msgid "Reviewing"
msgstr ""
msgid "Reviewing (merge request !%{mergeRequestId})"
-msgstr ""
+msgstr "Se revizuiește (merge request !%{mergeRequestId})"
msgid "Revoke"
msgstr ""
@@ -28745,13 +28961,13 @@ msgid "Rules that define what git pushes are accepted for a project. All newly c
msgstr ""
msgid "Run %{code_start}git fsck%{code_end} periodically in all project and wiki repositories to look for silent disk corruption issues."
-msgstr ""
+msgstr "Executați %{code_start}git fsck%{code_end} periodic în toate proiectele și repozitoriile wiki pentru a căuta probleme de corupție disc silențioase."
msgid "Run CI/CD pipelines for external repositories"
msgstr ""
msgid "Run CI/CD pipelines with Jenkins when you push to a repository, or when a merge request is created, updated, or merged. %{docs_link}"
-msgstr ""
+msgstr "Rulați conducte CI / CD cu Jenkins atunci când publicați lîntr-un repozitoriu sau când un merge request este creat, actualizat sau îmbinat. %{docs_link}"
msgid "Run CI/CD pipelines with Jenkins."
msgstr ""
@@ -28844,7 +29060,7 @@ msgid "Runners|For each solution, you will choose a capacity. 1 enables warm HA
msgstr ""
msgid "Runners|Group Runners"
-msgstr ""
+msgstr "Executori grup"
msgid "Runners|IP Address"
msgstr ""
@@ -28919,6 +29135,9 @@ msgid "Runners|Runner registration"
msgstr ""
msgid "Runners|Runners"
+msgstr "Executori"
+
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
msgstr ""
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
@@ -28928,19 +29147,19 @@ msgid "Runners|Show Runner installation instructions"
msgstr ""
msgid "Runners|Something went wrong while fetching runner data."
-msgstr ""
+msgstr "Ceva nu a mers bine în timpul preluării datelor executorilor."
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
msgid "Runners|Stop the runner from accepting new jobs."
-msgstr ""
+msgstr "Opriți executorul din a accepta noi joburi."
msgid "Runners|Tags"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
-msgstr ""
+msgstr "Acest executor este asociat cu unul sau mai multe proiecte."
msgid "Runners|This runner is associated with specific projects."
msgstr ""
@@ -28961,13 +29180,13 @@ msgid "Runners|Use Group runners when you want all projects in a group to have a
msgstr ""
msgid "Runners|Use the runner for jobs without tags, in addition to tagged jobs."
-msgstr ""
+msgstr "Utilizați executorul pentru joburi fără etichete, în adiția joburilor etichetate."
msgid "Runners|Use the runner for the currently assigned projects only."
-msgstr ""
+msgstr "Utilizați executorul numai pentru proiecte atribuite în prezent."
msgid "Runners|Use the runner on pipelines for protected branches only."
-msgstr ""
+msgstr "Utilizați executorul pe conducte numai pentru ramuri protejate."
msgid "Runners|Value"
msgstr ""
@@ -28984,6 +29203,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -28994,16 +29216,16 @@ msgid "Runners|group"
msgstr ""
msgid "Runners|instance"
-msgstr ""
+msgstr "instanță"
msgid "Runners|locked"
-msgstr ""
+msgstr "blocat"
msgid "Runners|paused"
-msgstr ""
+msgstr "întrerupt"
msgid "Runners|project"
-msgstr ""
+msgstr "proiect"
msgid "Runners|shared"
msgstr ""
@@ -29093,19 +29315,19 @@ msgid "SVG illustration"
msgstr ""
msgid "SastEntryPoints|Add Security Testing"
-msgstr ""
+msgstr "Adăugați Testare de Securitate"
msgid "SastEntryPoints|Catch your security vulnerabilities ahead of time!"
-msgstr ""
+msgstr "Prindeți vulnerabilitățile dvs. de securitate înainte să fie prea târziu!"
msgid "SastEntryPoints|GitLab can scan your code for security vulnerabilities. Static Application Security Testing (SAST) helps you worry less and build more."
-msgstr ""
+msgstr "GitLab vă poate scana codul pentru vulnerabilități de securitate. Testarea de Securitate Statică Aplicație (SAST) vă ajută să vă faceți mai puține griji și să construiți mai mult."
msgid "SastEntryPoints|How do I set up SAST?"
-msgstr ""
+msgstr "Cum setez SAST?"
msgid "SastEntryPoints|Learn more."
-msgstr ""
+msgstr "Aflați mai multe."
msgid "Satisfied"
msgstr ""
@@ -29168,7 +29390,7 @@ msgid "Schedule a new pipeline"
msgstr ""
msgid "Schedule-based escalation rules must have a schedule in the same project as the policy"
-msgstr ""
+msgstr "Regulile de escaladare bazate pe un program trebuie să aibă un program în același proiect cu politica"
msgid "Scheduled"
msgstr ""
@@ -29204,7 +29426,7 @@ msgid "Scopes"
msgstr ""
msgid "Scopes (select at least one)"
-msgstr ""
+msgstr "Domenii de aplicare (selectați măcar unul)"
msgid "Scopes can't be blank"
msgstr ""
@@ -29461,9 +29683,6 @@ msgstr[2] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29489,7 +29708,7 @@ msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
-msgstr ""
+msgstr "Token sigur care identifică o solicitare stocare externă."
msgid "Security"
msgstr ""
@@ -29515,50 +29734,50 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
-msgstr ""
+msgstr "O aprobare de cerere de îmbinare este necesară când acoperirea testului scade."
msgid "SecurityApprovals|A merge request approval is required when the license compliance report contains a denied license."
-msgstr ""
+msgstr "O aprobare de cerere de îmbinare este necesară când raportul de conformitate a licenței conține o licență refuzată."
msgid "SecurityApprovals|Configurable if security scanners are enabled. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Coverage-Check"
-msgstr ""
+msgstr "Verificarea acoperirii"
msgid "SecurityApprovals|Learn more about Coverage-Check"
-msgstr ""
+msgstr "Aflați mai multe despre verificarea acoperirii"
msgid "SecurityApprovals|Learn more about License-Check"
-msgstr ""
+msgstr "Aflați mai multe despre verificarea licenței"
msgid "SecurityApprovals|Learn more about Vulnerability-Check"
-msgstr ""
+msgstr "Aflați mai multe despre verificarea vulnerabilităților"
msgid "SecurityApprovals|License Scanning must be enabled. %{linkStart}Learn more%{linkEnd}."
msgstr ""
msgid "SecurityApprovals|License-Check"
-msgstr ""
+msgstr "Verificarea licenței"
msgid "SecurityApprovals|Requires approval for Denied licenses. %{linkStart}More information%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
-msgstr ""
+msgstr "Aprobare necesară pentru scăderi în acoperirea testului. %{linkStart}Mai multe informații%{linkEnd}"
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
-msgstr ""
+msgstr "Acoperirea testului trebuie să fie activată. %{linkStart}Aflați mai multe.%{linkEnd}"
msgid "SecurityApprovals|Vulnerability-Check"
-msgstr ""
+msgstr "Verificarea vulnerabilității"
msgid "SecurityConfiguration|%{featureName} merge request creation mutation failed"
msgstr ""
@@ -29609,16 +29828,16 @@ msgid "SecurityConfiguration|Enable %{feature}"
msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
-msgstr ""
+msgstr "Activați Auto DevOps"
msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|High-level vulnerability statistics across projects and groups"
-msgstr ""
+msgstr "Statistici vulnerabilități nivel-înalt de-a lungul proiectelor și grupurilor"
msgid "SecurityConfiguration|Immediately begin risk analysis and remediation with application security features. Start with SAST and Secret Detection, available to all plans. Upgrade to Ultimate to get all features, including:"
-msgstr ""
+msgstr "Începeți imediat analiza riscului și remedierea cu funcții de securitate aplicație. Începeți cu SAST și Detecție Secretă, disponibile pentru toate planurile. Faceți upgrade la Ultimate pentru a primi funcționalitate integrală, incluzând:"
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
msgstr ""
@@ -29627,7 +29846,7 @@ msgid "SecurityConfiguration|Manage scans"
msgstr ""
msgid "SecurityConfiguration|More scan types, including Container Scanning, DAST, Dependency Scanning, Fuzzing, and Licence Compliance"
-msgstr ""
+msgstr "Mai multe tipuri de scanări, incluzând Scanarea Containerului, DAST, Scanarea dependenței, Testarea Fuzz și Conformitatea Licențelor"
msgid "SecurityConfiguration|Not enabled"
msgstr ""
@@ -29636,10 +29855,10 @@ msgid "SecurityConfiguration|Once you've enabled a scan for the default branch,
msgstr ""
msgid "SecurityConfiguration|Quickly enable all continuous testing and compliance tools by enabling %{linkStart}Auto DevOps%{linkEnd}"
-msgstr ""
+msgstr "Activați rapid toate uneltele de conformitate și testare continuă activând %{linkStart}Auto DevOps%{linkEnd}"
msgid "SecurityConfiguration|Runtime security metrics for application environments"
-msgstr ""
+msgstr "Măsurători securitate în timpul executării pentru medii de aplicații"
msgid "SecurityConfiguration|SAST Analyzers"
msgstr ""
@@ -29648,7 +29867,7 @@ msgid "SecurityConfiguration|SAST Configuration"
msgstr ""
msgid "SecurityConfiguration|Secure your project"
-msgstr ""
+msgstr "Securizați-vă proiectul"
msgid "SecurityConfiguration|Security testing"
msgstr ""
@@ -29663,57 +29882,126 @@ msgid "SecurityConfiguration|Using custom settings. You won't receive automatic
msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
+msgstr "Detalii vulnerabilitate și statistici în cererea de îmbinare"
+
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
msgstr ""
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
+msgstr "A apărut o eroare la desemnarea proiectului dvs. al politicii de securitate"
+
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
msgstr ""
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
+msgstr "Doar proprietarii pot actualiza Proiectul Politicii de Securitate"
+
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
+msgstr ""
+
+msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgstr "Proiectul politicii de securitate a fost conectat cu succes"
+
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgstr "Selectați un proiect în care veți stoca politicile de securitate. %{linkStart}Mai multe informații.%{linkEnd}"
+
+msgid "SecurityOrchestration|Select security project"
+msgstr "Selectați proiect de securitate"
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Update scan execution policies"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr "+%{count} mai mult"
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr "Mediu (medii)"
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29752,9 +30040,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29819,7 +30104,7 @@ msgid "SecurityReports|Manage and track vulnerabilities identified in your selec
msgstr ""
msgid "SecurityReports|Maximum selected projects limit reached"
-msgstr ""
+msgstr "Limita maximă de proiecte selectate a fost atinsă"
msgid "SecurityReports|Monitor vulnerabilities in all of your projects"
msgstr ""
@@ -29866,9 +30151,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29935,9 +30217,12 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
-msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
+msgid "SecurityReports|Tool"
msgstr ""
+msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
+msgstr "Nu se poate adăuga %{invalidProjectsMessage}: %{errorMessage}"
+
msgid "SecurityReports|Unable to add %{invalidProjects}"
msgstr ""
@@ -29978,7 +30263,7 @@ msgid "See metrics"
msgstr ""
msgid "See our website for help"
-msgstr ""
+msgstr "Vizitați site-ul nostru pentru ajutor"
msgid "See the affected projects in the GitLab admin panel"
msgstr ""
@@ -30014,7 +30299,7 @@ msgid "Select a file from the left sidebar to begin editing. Afterwards, you'll
msgstr ""
msgid "Select a framework that applies to this project. %{linkStart}How are these added?%{linkEnd}"
-msgstr ""
+msgstr "Selectați un cadru care se aplică acestui proiect. %{linkStart}Cum se adaugă acestea?%{linkEnd}"
msgid "Select a group to invite"
msgstr ""
@@ -30053,7 +30338,7 @@ msgid "Select a template type"
msgstr ""
msgid "Select a time zone"
-msgstr ""
+msgstr "Selectați un fus orar"
msgid "Select a timezone"
msgstr ""
@@ -30083,7 +30368,7 @@ msgid "Select file"
msgstr ""
msgid "Select group"
-msgstr ""
+msgstr "Selectați grup"
msgid "Select group or project"
msgstr ""
@@ -30146,7 +30431,7 @@ msgid "Select strategy activation method"
msgstr ""
msgid "Select subgroup"
-msgstr ""
+msgstr "Selectați subgrup"
msgid "Select subscription"
msgstr ""
@@ -30179,7 +30464,7 @@ msgid "Selective synchronization"
msgstr ""
msgid "Self monitoring"
-msgstr ""
+msgstr "Auto-monitorizare"
msgid "Self monitoring project does not exist"
msgstr ""
@@ -30194,25 +30479,25 @@ msgid "Self-monitoring project was not deleted. Please check logs for any error
msgstr ""
msgid "SelfMonitoring|Activate or deactivate instance self monitoring."
-msgstr ""
+msgstr "Activați sau dezactivați auto-monitorizarea instanței."
msgid "SelfMonitoring|Activate self monitoring to create a project to use to monitor the health of your instance."
-msgstr ""
+msgstr "Activați auto-monitorizarea pentru a crea un proiect pentru a utiliza pentru a monitoriza sănătatea instanței dvs."
msgid "SelfMonitoring|Deactivate self monitoring?"
-msgstr ""
+msgstr "Dezactivați auto-monitorizarea?"
msgid "SelfMonitoring|Deactivating self monitoring deletes the self monitoring project. Are you sure you want to deactivate self monitoring and delete the project?"
-msgstr ""
+msgstr "Dezactivarea auto-monitorizării șterge proiectul auto-monitorizării. Sunteți sigur că doriți să dezactivați auto-monitorizarea și să ștergeți proiectul?"
msgid "SelfMonitoring|Self monitoring"
msgstr ""
msgid "SelfMonitoring|Self monitoring is active. Use the %{projectLinkStart}self monitoring project%{projectLinkEnd} to monitor the health of your instance."
-msgstr ""
+msgstr "Auto-monitorizarea este activă. Utilizați %{projectLinkStart}proiectul auto-monitorizării%{projectLinkEnd} pentru a monitoriza sănătatea instanței dvs."
msgid "SelfMonitoring|Self monitoring project successfully created."
-msgstr ""
+msgstr "Proiectul de auto-monitorizare a fost creat cu succes."
msgid "SelfMonitoring|Self monitoring project successfully deleted."
msgstr ""
@@ -30230,13 +30515,13 @@ msgid "Send email"
msgstr ""
msgid "Send email in multipart format (HTML and plain text). Uncheck to send email messages in plain text only."
-msgstr ""
+msgstr "Trimiteți e-mail în format multipart (HTML și text brut). Debifați pentru a trimite mesaje e-mail numai în text brut."
msgid "Send email notification"
msgstr ""
msgid "Send emails to help guide new users through the onboarding process."
-msgstr ""
+msgstr "Trimiteți e-mailuri pentru a ghida utilizatorii noi prin procesul de integrare."
msgid "Send message"
msgstr ""
@@ -30275,10 +30560,10 @@ msgid "SeriesFinalConjunction|and"
msgstr ""
msgid "Serve repository static objects (for example, archives and blobs) from external storage."
-msgstr ""
+msgstr "Serviți obiecte statice repozitoriu (de exemplu, arhive și bloburi) din stocare externă."
msgid "Server (optional)"
-msgstr ""
+msgstr "Server (opțional)"
msgid "Server supports batch API only, please update your Git LFS client to version 1.0.1 and up."
msgstr ""
@@ -30380,7 +30665,7 @@ msgid "Service URL"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
-msgstr ""
+msgstr "Ping serviciu este dezactivat în fișierul dvs. de configurație și nu poate fi activat prin acest formular."
msgid "ServiceDesk|Enable Service Desk"
msgstr ""
@@ -30416,16 +30701,16 @@ msgid "ServiceDesk|Your users can send emails to this address:"
msgstr ""
msgid "ServicePing|Service ping is off"
-msgstr ""
+msgstr "Ping serviciu este oprit"
msgid "ServicePing|To view instance-level analytics, ask an admin to turn on %{docLinkStart}service ping%{docLinkEnd}."
-msgstr ""
+msgstr "Pentru a vizualiza analitici la nivel instanță, rugați un administrator să pornească %{docLinkStart}ping serviciu%{docLinkEnd}."
msgid "ServicePing|Turn on service ping"
-msgstr ""
+msgstr "Activați ping serviciu"
msgid "ServicePing|Turn on service ping to review instance-level analytics."
-msgstr ""
+msgstr "Porniți ping serviciu pentru a revizui analitici la nivel instanță."
msgid "Session ID"
msgstr ""
@@ -30508,7 +30793,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30556,7 +30841,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30757,9 +31042,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30827,7 +31109,7 @@ msgid "Showing data for workflow items created in this date range. Date range ca
msgstr ""
msgid "Showing graphs based on events of the last %{timerange} days."
-msgstr ""
+msgstr "Se afișaează grafice pe baza evenimentelor din ultimele %{timerange} zile."
msgid "Showing last %{size} of log -"
msgstr ""
@@ -30985,6 +31267,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31100,7 +31385,7 @@ msgid "Someone edited this %{issueType} at the same time you did. The descriptio
msgstr ""
msgid "Someone edited this merge request at the same time you did. Please refresh the page to see changes."
-msgstr ""
+msgstr "Cineva a editat acest merge request în același timp cu dvs. Actualizați pagina pentru a vedea modificările."
msgid "Someone edited this test case at the same time you did. The description has been updated and you will need to make your changes again."
msgstr ""
@@ -31211,7 +31496,7 @@ msgid "Something went wrong while fetching source branches."
msgstr ""
msgid "Something went wrong while fetching the environments for this merge request. Please try again."
-msgstr ""
+msgstr "Ceva nu a mers bine în timpul preluării mediilor pentru acest merge request. Vă rugăm încercați din nou."
msgid "Something went wrong while fetching the package."
msgstr ""
@@ -31226,7 +31511,7 @@ msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
+msgstr "Ceva nu a mers bine în timpul îmbinării acestui merge request. Vă rugăm încercați din nou."
msgid "Something went wrong while moving issues."
msgstr ""
@@ -31336,6 +31621,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -31643,7 +31937,7 @@ msgid "Start Web Terminal"
msgstr ""
msgid "Start a %{new_merge_request} with these changes"
-msgstr ""
+msgstr "Porniți un %{new_merge_request} cu aceste modificări"
msgid "Start a Free Ultimate Trial"
msgstr ""
@@ -32690,7 +32984,7 @@ msgid "Target Branch"
msgstr ""
msgid "Target Path"
-msgstr ""
+msgstr "Traiectoria țintă"
msgid "Target branch"
msgstr ""
@@ -32708,7 +33002,7 @@ msgid "Team domain"
msgstr ""
msgid "TeamcityIntegration|Trigger TeamCity CI after a merge request has been created or updated"
-msgstr ""
+msgstr "Declanșați TeamCity CI după ce un merge request a fost creat sau actualizat"
msgid "TeamcityIntegration|Trigger TeamCity CI after every push to the repository, except branch delete"
msgstr ""
@@ -32720,7 +33014,7 @@ msgid "Template"
msgstr ""
msgid "Template to append to all Service Desk issues"
-msgstr ""
+msgstr "Șablon de adăugat la toate problemele Birou de Servicii"
msgid "TemplateRepository|Select a repository to make its templates available to all projects. %{link_start}What should the repository contain?%{link_end} "
msgstr ""
@@ -32809,6 +33103,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32860,12 +33157,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32878,7 +33181,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -33106,7 +33409,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33325,6 +33628,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33361,11 +33667,8 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
-msgstr ""
+msgstr "Conflictele de îmbinare pentru acest merge request nu pot fi rezolvate prin GitLab. Încercați să le rezolvați pe plan local."
msgid "The merge conflicts for this merge request have already been resolved."
msgstr ""
@@ -33517,6 +33820,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33623,7 +33929,7 @@ msgid "There are no labels yet"
msgstr ""
msgid "There are no matching files"
-msgstr ""
+msgstr "Nu există fișiere potrivite"
msgid "There are no open epics"
msgstr ""
@@ -33650,12 +33956,18 @@ msgid "There are no variables yet."
msgstr ""
msgid "There are pending advanced search migrations which require indexing to be paused. Indexing must remain paused until the migrations are completed."
-msgstr ""
+msgstr "Există migrații căutare avansată în așteptare care necesită indexarea să fie întreruptă. Indexarea trebuie să rămână întreruptă până când migrațiile sunt completate."
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
+msgstr "Există mai multe limite de rată pentru a proteja sistemul."
+
+msgid "There are several size limits in place."
msgstr ""
msgid "There is a halted Elasticsearch migration"
@@ -33703,6 +34015,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33716,19 +34031,19 @@ msgid "There was a problem fetching project users."
msgstr ""
msgid "There was a problem fetching recent groups."
-msgstr ""
+msgstr "A apărut o problemă în timpul preluării grupurilor recente."
msgid "There was a problem fetching recent projects."
-msgstr ""
+msgstr "A apărut o problemă în timpul preluării proiectelor recente."
msgid "There was a problem fetching the job token scope value"
-msgstr ""
+msgstr "A apărut o problemă în timpul preluării valorii domeniului de aplicare al tokenului jobului"
msgid "There was a problem fetching the keep latest artifacts setting."
msgstr ""
msgid "There was a problem fetching the projects"
-msgstr ""
+msgstr "A apărut o problemă în timpul preluării proiectelor"
msgid "There was a problem fetching users."
msgstr ""
@@ -33779,7 +34094,7 @@ msgid "There was an error fetching projects"
msgstr ""
msgid "There was an error fetching stage total counts"
-msgstr ""
+msgstr "A apărut o eroare preluând numărătoarea totală a stagiilor"
msgid "There was an error fetching the %{replicableType}"
msgstr ""
@@ -33883,9 +34198,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33947,7 +34259,7 @@ msgid "This %{noteableTypeText} is locked."
msgstr ""
msgid "This %{viewer} could not be displayed because %{reason}. You can %{options} instead."
-msgstr ""
+msgstr "Acest %{viewer} nu a putut fi afișat din cauza %{reason}. În schimb, poți să ai %{options}."
msgid "This Cron pattern is invalid"
msgstr ""
@@ -33977,10 +34289,10 @@ msgid "This action has been performed too many times. Try again later."
msgstr ""
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
-msgstr ""
+msgstr "Această acțiune va %{strongOpen}șterge definitiv%{strongClose}%{codeOpen}%{project}%{codeClose}%{strongOpen}imediat%{strongClose}, inclusiv toate repozitoriile și toate resursele asociate, inclusiv problemele și cererile de îmbinare."
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
-msgstr ""
+msgstr "Această acțiune va %{strongOpen}șterge definitiv%{strongClose}%{codeOpen}%{project}%{codeClose}%{strongOpen}pe%{date}%{strongClose}, inclusiv toate repozitoriile și toate resursele asociate, inclusiv problemele și cererile de îmbinare."
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
msgstr ""
@@ -34022,7 +34334,7 @@ msgid "This chart could not be displayed"
msgstr ""
msgid "This clears repository check states for all projects in the database and cannot be undone. Are you sure?"
-msgstr ""
+msgstr "Acest lucru va șterge statuturile verificărilor de repozitoriu pentru toate proiectele din baza de date. Acest lucru nu poate fi anulat. Sunteți sigur?"
msgid "This code snippet contains everything reflected in the configuration form. Copy and paste it into %{linkStart}.gitlab-ci.yml%{linkEnd} file and save your changes. Future %{scanType} scans will use these settings."
msgstr ""
@@ -34031,7 +34343,7 @@ msgid "This comment changed after you started editing it. Review the %{startTag}
msgstr ""
msgid "This commit is part of merge request %{link_to_merge_request}. Comments created here will be created in the context of that merge request."
-msgstr ""
+msgstr "Acest commit face parte din merge request-ul %{link_to_merge_request}. Comentariile create aici vor fi create în contextul acelui merge request."
msgid "This commit was signed with a %{strong_open}verified%{strong_close} signature and the committer email is verified to belong to the same user."
msgstr ""
@@ -34100,14 +34412,11 @@ msgid "This feature requires local storage to be enabled"
msgstr ""
msgid "This field is required"
-msgstr ""
+msgstr "Acest câmp este obligatoriu"
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -34180,6 +34489,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -34640,7 +34952,7 @@ msgid "Time tracking report"
msgstr ""
msgid "Time until first merge request"
-msgstr ""
+msgstr "Timp până la primul merge request"
msgid "Time zone"
msgstr ""
@@ -34799,7 +35111,7 @@ msgid "Timeout connecting to the Google API. Please try again."
msgstr ""
msgid "Timeout for moderately fast Gitaly operations (in seconds). Provide a value between Default timeout and Fast timeout."
-msgstr ""
+msgstr "Timp expirare pentru operațiuni moderat rapide Gitaly (în secunde). Furnizați o valoare între Timp expirare implicit și Timp expirare rapid."
msgid "Timeout for most Gitaly operations (in seconds)."
msgstr ""
@@ -34967,7 +35279,7 @@ msgid "To receive alerts from manually configured Prometheus services, add the f
msgstr ""
msgid "To resolve this, try to:"
-msgstr ""
+msgstr "Pentru a rezolva asta, încercați:"
msgid "To run CI/CD pipelines with JetBrains TeamCity, input the GitLab project details in the TeamCity project Version Control Settings."
msgstr ""
@@ -34976,7 +35288,7 @@ msgid "To see all the user's personal access tokens you must impersonate them fi
msgstr ""
msgid "To see this project's operational details, %{linkStart}upgrade its group plan to Premium%{linkEnd}. You can also remove the project from the dashboard."
-msgstr ""
+msgstr "Pentru a vedea detaliile operaționale ale acestui proiect, faceți %{linkStart}upgrade planului său la Premium%{linkEnd}. De asemenea, puteți elimina proiectul de pe panoul de control."
msgid "To see this project's operational details, contact an owner of group %{groupName} to upgrade the plan. You can also remove the project from the dashboard."
msgstr ""
@@ -35000,7 +35312,7 @@ msgid "To use Gitpod you must first enable the feature in the integrations secti
msgstr ""
msgid "To use the additional formats, you must start the required %{container_link_start}companion containers%{container_link_end}."
-msgstr ""
+msgstr "Pentru a folosi formate suplimentare, trebuie să porniți %{container_link_start}containerele însoțitoare%{container_link_end}."
msgid "To view all %{scannedResourcesCount} scanned URLs, %{linkStart}please download the CSV file%{linkEnd}"
msgstr ""
@@ -35087,7 +35399,7 @@ msgid "Token"
msgstr ""
msgid "Token Access"
-msgstr ""
+msgstr "Acces token"
msgid "Token name"
msgstr ""
@@ -35150,7 +35462,7 @@ msgid "Total weight"
msgstr ""
msgid "Total: %{total}"
-msgstr ""
+msgstr "Total: %{total}"
msgid "TotalMilestonesIndicator|1000+"
msgstr ""
@@ -35213,7 +35525,7 @@ msgid "TransferGroup|The parent group already has a subgroup with the same path.
msgstr ""
msgid "TransferGroup|Transfer failed: %{error_message}"
-msgstr ""
+msgstr "Transferul a eșuat: %{error_message}"
msgid "TransferGroup|You don't have enough permissions."
msgstr ""
@@ -35227,13 +35539,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
-msgid "TransferProject|Project with same name or path in target namespace already exists"
+msgid "TransferProject|Project is already in this namespace."
msgstr ""
+msgid "TransferProject|Project with same name or path in target namespace already exists"
+msgstr "Există deja un proiect cu același nume sau traiectorie în spațiul de nume țintă"
+
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35294,13 +35612,13 @@ msgid "Trial|Dismiss"
msgstr ""
msgid "Trial|First name"
-msgstr ""
+msgstr "Prenume"
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
+msgstr "Bună ziua%{salutation}, perioada dvs. de încercare GitLab Ultimate ține 30 de zile, dar vă puteți păstra contul gratuit GitLab pentru totdeauna. Doar avem nevoie de câteva informații suplimentare despre %{company} pentru a vă activa perioada de încercare."
msgid "Trial|How many employees will use Gitlab?"
msgstr ""
@@ -35309,13 +35627,13 @@ msgid "Trial|How many users will be evaluating the trial?"
msgstr ""
msgid "Trial|Last name"
-msgstr ""
+msgstr "Nume"
msgid "Trial|Number of employees"
msgstr ""
msgid "Trial|Please select a country"
-msgstr ""
+msgstr "Vă rugăm să selectați o țară"
msgid "Trial|Successful trial activation image"
msgstr ""
@@ -35333,7 +35651,7 @@ msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your
msgstr ""
msgid "Trial|your company"
-msgstr ""
+msgstr "compania dvs."
msgid "Trigger"
msgstr ""
@@ -35468,7 +35786,7 @@ msgid "Two-factor authentication is not enabled for this user"
msgstr ""
msgid "Two-factor grace period"
-msgstr ""
+msgstr "Perioadă de grație cu doi factori"
msgid "Type"
msgstr ""
@@ -35513,7 +35831,7 @@ msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{
msgstr ""
msgid "URL of the Grafana instance to link to from the Metrics Dashboard menu item."
-msgstr ""
+msgstr "URL-ul instanței Grafana care are să fie conectat din elementul-meniu Măsurători din Panoul de control."
msgid "URL of the external Spam Check endpoint"
msgstr ""
@@ -35699,7 +36017,7 @@ msgid "Unknown response text"
msgstr ""
msgid "Unknown user"
-msgstr ""
+msgstr "Utilizator necunoscut"
msgid "Unless otherwise agreed to in writing with GitLab, by clicking \"Upload License\" you agree that your use of GitLab Software is subject to the %{eula_link_start}Terms of Service%{eula_link_end}."
msgstr ""
@@ -35797,6 +36115,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35939,7 +36260,7 @@ msgid "Upload file"
msgstr ""
msgid "Upload image"
-msgstr ""
+msgstr "încărcați o imagine"
msgid "Upload license"
msgstr ""
@@ -35957,7 +36278,7 @@ msgid "Uploads"
msgstr ""
msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
+msgstr "După efectuarea acestei acțiuni, conținutul acestui grup, al subgrupului său și proiectele vor fi șterse permanent după %{deletion_adjourned_period} zile pe %{date}. Până atunci:"
msgid "Upstream"
msgstr ""
@@ -35993,10 +36314,10 @@ msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|CI minutes usage by month"
-msgstr ""
+msgstr "Utilizare minute CI după lună"
msgid "UsageQuota|CI minutes usage by project"
-msgstr ""
+msgstr "Utilizare minute CI după proiect"
msgid "UsageQuota|Current period usage"
msgstr ""
@@ -36016,9 +36337,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -36037,9 +36355,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -36088,6 +36412,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36173,7 +36500,7 @@ msgid "UsageTrends|Projects"
msgstr ""
msgid "UsageTrends|There was an error fetching the cancelled pipelines. Please try again."
-msgstr ""
+msgstr "A apărut o eroare la preluarea conductelor anulate. Vă rugăm să încercați din nou."
msgid "UsageTrends|There was an error fetching the failed pipelines. Please try again."
msgstr ""
@@ -36233,22 +36560,25 @@ msgid "Use custom color #FF0000"
msgstr ""
msgid "Use double quotes for multiple keywords, such as %{code_open}\"your search\"%{code_close}"
-msgstr ""
+msgstr "Utilizați ghilimele duble pentru multiple cuvinte-cheie, ca %{code_open}\"căutarea dvs.\"%{code_close}"
msgid "Use hashed storage"
msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
-msgstr ""
+msgstr "Utilizați traiectorii de stocare hashed pentru repozitorii nou-create și redenumite. Activat mereu din versiunea 13.0."
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
msgid "Use slash commands."
-msgstr ""
+msgstr "Utilizați comenzi slash."
msgid "Use template"
msgstr ""
@@ -36260,7 +36590,7 @@ msgid "Use the link below to confirm your email address."
msgstr ""
msgid "Use the public cloud instance URL (%{kroki_public_url}) or %{install_link_start}install Kroki%{install_link_end} on your own infrastructure and use your own instance URL."
-msgstr ""
+msgstr "Utilizați URL-ul instanței cloud publice (%{kroki_public_url}) sau %{install_link_start}instalați Kroki%{install_link_end} pe infrastructura dvs. și utilizați URL-ul instanței dvs."
msgid "Use the search bar on the top of this page"
msgstr ""
@@ -36332,7 +36662,7 @@ msgid "User is not allowed to resolve thread"
msgstr ""
msgid "User key"
-msgstr ""
+msgstr "Cheie utilizator"
msgid "User key was successfully removed."
msgstr ""
@@ -36368,7 +36698,7 @@ msgid "User was successfully updated."
msgstr ""
msgid "User-based escalation rules must have a user with access to the project"
-msgstr ""
+msgstr "Reguli de escaladare bazate pe utilizator trebuie să aibă un utilizator cu acces la proiect"
msgid "UserAvailability|%{author} %{spanStart}(Busy)%{spanEnd}"
msgstr ""
@@ -36506,7 +36836,7 @@ msgid "UserProfile|Personal projects"
msgstr ""
msgid "UserProfile|Pronounced as: %{pronunciation}"
-msgstr ""
+msgstr "Pronunțat ca: %{pronunciation}"
msgid "UserProfile|Report abuse"
msgstr ""
@@ -36584,7 +36914,7 @@ msgid "UserProfile|made a private contribution"
msgstr ""
msgid "Username"
-msgstr ""
+msgstr "Nume utilizator"
msgid "Username (for password-protected Elasticsearch servers)"
msgstr ""
@@ -36614,7 +36944,7 @@ msgid "Users can launch a development environment from a GitLab browser tab when
msgstr ""
msgid "Users can render diagrams in AsciiDoc, Markdown, reStructuredText, and Textile documents using Kroki."
-msgstr ""
+msgstr "Utilizatorii pot reda diagrame în documente AsciiDoc, Markdown, reStructuredText, și Textile utilizând Kroki."
msgid "Users in License"
msgstr ""
@@ -36683,7 +37013,7 @@ msgid "Value Stream Analytics gives an overview of how much time it takes to go
msgstr ""
msgid "Value may contain a variable reference"
-msgstr ""
+msgstr "Valoarea poate conține o referință variabilă"
msgid "Value stream"
msgstr ""
@@ -36719,11 +37049,17 @@ msgid "ValueStreamAnalytics|Median time from issue created to issue closed."
msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
+msgstr "Timpul mediu de la primul merge request creat până la închiderea problemei."
+
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
msgstr ""
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36746,7 +37082,7 @@ msgid "Variable"
msgstr ""
msgid "Variable references indicated by %{codeStart}$%{codeEnd} may be expanded. If this is not what you want, consider %{docsLinkStart}using a workaround to prevent expansion%{docsLinkEnd}."
-msgstr ""
+msgstr "Referințele variabile indicate de %{codeStart}$%{codeEnd} pot fi extinse. Dacă nu doriți acest lucru, luați în considerare %{docsLinkStart}utilizarea unei soluții alternative pentru a preveni extinderea%{docsLinkEnd}."
msgid "Variable will be masked in job logs."
msgstr ""
@@ -36905,7 +37241,7 @@ msgid "View on %{url}"
msgstr ""
msgid "View open merge request"
-msgstr ""
+msgstr "Vizualizați merge request-ul deschis"
msgid "View page @ "
msgstr ""
@@ -36922,6 +37258,12 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -37040,7 +37382,7 @@ msgid "VulnerabilityManagement|Change status"
msgstr ""
msgid "VulnerabilityManagement|Could not process %{issueReference}: %{errorMessage}."
-msgstr ""
+msgstr "Nu s-a putut procesa %{issueReference}: %{errorMessage}."
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
@@ -37180,9 +37522,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -37195,11 +37534,14 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
msgid "WARNING:"
-msgstr ""
+msgstr "ATENÈšIE:"
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -37277,10 +37619,10 @@ msgid "We recommend leaving all SAST analyzers enabled"
msgstr ""
msgid "We recommend that you buy additional Pipeline minutes to avoid any interruption of service."
-msgstr ""
+msgstr "Vă recomandăm să cumpărați minute suplimentare de conducte pentru a evita orice întrerupere a serviciului."
msgid "We recommend that you buy additional Pipeline minutes to resume normal service."
-msgstr ""
+msgstr "Vă recomandăm să cumpărați minute suplimentare de conducte pentru a relua serviciul normal."
msgid "We sent you an email with reset password instructions"
msgstr ""
@@ -37300,6 +37642,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37442,7 +37787,7 @@ msgid "Webhooks|URL is triggered when a group member is created, updated, or rem
msgstr ""
msgid "Webhooks|URL is triggered when a merge request is created, updated, or merged"
-msgstr ""
+msgstr "URL-ul este declanșat atunci când este creat, actualizat sau îmbinat un merge request."
msgid "Webhooks|URL is triggered when a new tag is pushed to the repository"
msgstr ""
@@ -37526,7 +37871,7 @@ msgid "What are project audit events?"
msgstr ""
msgid "What are shared runner pipeline minutes?"
-msgstr ""
+msgstr "Ce sunt minutele de conducte executori partajați?"
msgid "What are you searching for?"
msgstr ""
@@ -37541,7 +37886,7 @@ msgid "What is Auto DevOps?"
msgstr ""
msgid "What is Markdown?"
-msgstr ""
+msgstr "Ce este Markdown?"
msgid "What is repository mirroring?"
msgstr ""
@@ -37550,11 +37895,14 @@ msgid "What is squashing?"
msgstr ""
msgid "What is time tracking?"
-msgstr ""
+msgstr "Ce este urmărirea timpului?"
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37571,7 +37919,7 @@ msgid "When an event in GitLab triggers a webhook, you can use the request detai
msgstr ""
msgid "When inactive, an external authentication provider must be used."
-msgstr ""
+msgstr "Când inactiv, un furnizor de autentificare extern trebuie utilizat."
msgid "When leaving the URL blank, classification labels can still be specified without disabling cross project features or performing external authorization checks."
msgstr ""
@@ -37581,9 +37929,9 @@ msgstr ""
msgid "When this merge request is accepted"
msgid_plural "When these merge requests are accepted"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "Când acest merge request este acceptat"
+msgstr[1] "Când aceste merge request-uri sunt acceptate"
+msgstr[2] "Când aceste merge request-uri sunt acceptate"
msgid "When using the %{code_open}http://%{code_close} or %{code_open}https://%{code_close} protocols, please provide the exact URL to the repository. HTTP redirects will not be followed."
msgstr ""
@@ -37615,6 +37963,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37943,7 +38294,7 @@ msgid "You are about to transfer the control of your account to %{group_name} gr
msgstr ""
msgid "You are already a member of this %{member_source}."
-msgstr ""
+msgstr "Sunteți deja un membru al acestui %{member_source}."
msgid "You are an admin, which means granting access to %{client_name} will allow them to interact with GitLab as an admin as well. Proceed with caution."
msgstr ""
@@ -37961,7 +38312,7 @@ msgid "You are going to delete %{project_full_name}. Deleted projects CANNOT be
msgstr ""
msgid "You are going to remove %{group_name}. This will also delete all of its subgroups and projects. Removed groups CANNOT be restored! Are you ABSOLUTELY sure?"
-msgstr ""
+msgstr "Veți elimina %{group_name}. Această acțiune va elimina de asemenea și toate subgrupurile și proiectele sale. Grupuri șterse NU pot fi restaurate! Sunteți ABSOLUT sigur?"
msgid "You are going to remove the fork relationship from %{project_full_name}. Are you ABSOLUTELY sure?"
msgstr ""
@@ -37976,7 +38327,7 @@ msgid "You are going to turn on confidentiality. Only team members with %{strong
msgstr ""
msgid "You are not allowed to %{action} a user"
-msgstr ""
+msgstr "Nu aveți permisiunea de a %{action} un utilizator"
msgid "You are not allowed to approve a user"
msgstr ""
@@ -38021,10 +38372,10 @@ msgid "You are using PostgreSQL %{pg_version_current}, but PostgreSQL %{pg_versi
msgstr ""
msgid "You can %{gitlabLinkStart}resolve conflicts on GitLab%{gitlabLinkEnd} or %{resolveLocallyStart}resolve it locally%{resolveLocallyEnd}."
-msgstr ""
+msgstr "Puteți %{gitlabLinkStart}rezolva conflicte pe GitLab%{gitlabLinkEnd} sau să %{resolveLocallyStart}rezolvați local%{resolveLocallyEnd}."
msgid "You can %{resolveLocallyStart}resolve it locally%{resolveLocallyEnd}."
-msgstr ""
+msgstr "Puteți să %{resolveLocallyStart}rezolvați local%{resolveLocallyEnd}."
msgid "You can also create a project from the command line."
msgstr ""
@@ -38063,7 +38414,7 @@ msgid "You can create a new SSH key by visiting %{link}"
msgstr ""
msgid "You can create a new one or check them in your %{pat_link_start}personal access tokens%{pat_link_end} settings."
-msgstr ""
+msgstr "Puteți crea unul nou sau să le verificați în setările %{pat_link_start}token-urilor dvs. de acces personal%{pat_link_end}."
msgid "You can create a new one or check them in your %{ssh_key_link_start}SSH keys%{ssh_key_link_end} settings."
msgstr ""
@@ -38072,7 +38423,7 @@ msgid "You can create a new one or check them in your SSH keys settings %{ssh_ke
msgstr ""
msgid "You can create a new one or check them in your personal access tokens settings %{pat_link}."
-msgstr ""
+msgstr "Puteți crea unul nou sau să le verificați în setările token-urilor dvs. de acces personal %{pat_link}."
msgid "You can create new ones at your %{pat_link_start}Personal Access Tokens%{pat_link_end} settings"
msgstr ""
@@ -38084,7 +38435,7 @@ msgid "You can easily contribute to them by requesting to join these groups."
msgstr ""
msgid "You can enable Registration Features because Service Ping is enabled. To continue using Registration Features in the future, you will also need to register with GitLab via a new cloud licensing service."
-msgstr ""
+msgstr "Puteți activa Funcțiile de Înregistrare pentru că Ping Serviciu este activat. Pentru a continua să folosiți Funcțiile de Întregistrare în viitor, va trebui de asemenea să vă înregistrați cu GitLab printr-un nou serviciu de licențiere cloud."
msgid "You can enable project access token creation in %{link_start}group settings%{link_end}."
msgstr ""
@@ -38144,7 +38495,7 @@ msgid "You can only merge once this merge request is approved."
msgstr ""
msgid "You can only transfer the project to namespaces you manage."
-msgstr ""
+msgstr "Puteți transfera proiectul numai în spațiile de nume pe care le gestionați."
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
@@ -38173,6 +38524,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -38188,6 +38542,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38276,7 +38633,7 @@ msgid "You have been granted %{member_human_access} access to project %{name}."
msgstr ""
msgid "You have been invited by %{link_to_inviter} to join %{source_name} %{strong_open}%{link_to_source}%{strong_close} as %{role}"
-msgstr ""
+msgstr "Ați fost invitat de către %{link_to_inviter} să vă alăturați %{source_name} %{strong_open}%{link_to_source}%{strong_close} ca %{role}"
msgid "You have been redirected to the only result; see the %{a_start}search results%{a_end} instead."
msgstr ""
@@ -38332,7 +38689,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38525,7 +38882,7 @@ msgid "Your CSV import for project"
msgstr ""
msgid "Your DevOps Report gives an overview of how you are using GitLab from a feature perspective. Use it to view how you compare with other organizations."
-msgstr ""
+msgstr "Raportul dvs. DevOps vă oferă o prezentare generală a cum utilizați GitLab dintr-o perspectivă a funcțiilor. Utilizați-l pentru a vizualiza cum vă comparați cu alte organizații."
msgid "Your GPG keys (%{count})"
msgstr ""
@@ -38546,49 +38903,49 @@ msgid "Your Personal Access Token was revoked"
msgstr ""
msgid "Your Projects (default)"
-msgstr ""
+msgstr "Proiectele dvs. (implicit)"
msgid "Your Projects' Activity"
msgstr ""
msgid "Your SSH key has expired"
-msgstr ""
+msgstr "Cheia dvs. SSH a expirat"
msgid "Your SSH key is expiring soon."
-msgstr ""
+msgstr "Cheia dvs. SSH expiră în curând."
msgid "Your SSH key was deleted"
-msgstr ""
+msgstr "Cheia dvs. SSH a fost ștearsă"
msgid "Your SSH keys (%{count})"
-msgstr ""
+msgstr "Cheile dvs. SSH (%{count})"
msgid "Your To-Do List"
-msgstr ""
+msgstr "Lista dvs. de sarcini"
msgid "Your U2F device did not send a valid JSON response."
-msgstr ""
+msgstr "Dispozitivul dvs. U2F nu a trimis un răspuns valid JSON."
msgid "Your U2F device was registered!"
-msgstr ""
+msgstr "Dispozitivul dvs. U2F a fost înregistrat!"
msgid "Your WebAuthn device did not send a valid JSON response."
-msgstr ""
+msgstr "Dispozitivul dvs. WebAuthn nu a trimis un răspuns JSON valid."
msgid "Your WebAuthn device was registered!"
-msgstr ""
+msgstr "Dispozitivul dvs. WebAuthn a fost înregistrat!"
msgid "Your access request to the %{source_type} has been withdrawn."
-msgstr ""
+msgstr "Solicitarea dvs. de acces la %{source_type} a fost retrasă."
msgid "Your account has been deactivated"
-msgstr ""
+msgstr "Contul dvs. a fost dezactivat."
msgid "Your account has been deactivated by your administrator. Please log back in to reactivate your account."
-msgstr ""
+msgstr "Contul dvs. a fost dezactivat de administrator. Vă rugăm să vă conectați din nou pentru a vă reactiva contul."
msgid "Your account has been deactivated. You will not be able to: "
-msgstr ""
+msgstr "Contul dvs. a fost dezactivat. Nu veți mai putea să: "
msgid "Your account is locked."
msgstr ""
@@ -38597,10 +38954,10 @@ msgid "Your account uses dedicated credentials for the \"%{group_name}\" group a
msgstr ""
msgid "Your action succeeded."
-msgstr ""
+msgstr "Acțiunea dvs. a reușit."
msgid "Your applications (%{size})"
-msgstr ""
+msgstr "Aplicațiile dvs. (%{size})"
msgid "Your authorized applications"
msgstr ""
@@ -38693,22 +39050,22 @@ msgid "Your license does not support on-call schedules"
msgstr ""
msgid "Your license is valid from"
-msgstr ""
+msgstr "Licența dvs. este valabilă de la"
msgid "Your membership in %{group} no longer expires."
-msgstr ""
+msgstr "Abonamentul dvs. la %{group} nu mai expiră."
msgid "Your message here"
-msgstr ""
+msgstr "Mesajul dvs. aici"
msgid "Your name"
msgstr ""
msgid "Your new %{type}"
-msgstr ""
+msgstr "Noul tău %{type}"
msgid "Your new SCIM token"
-msgstr ""
+msgstr "Noul dvs. token SCIM"
msgid "Your new comment"
msgstr ""
@@ -38758,7 +39115,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38771,7 +39128,7 @@ msgid "Your search didn't match any commits. Try a different query."
msgstr ""
msgid "Your search timed out"
-msgstr ""
+msgstr "Căutarea dvs. a expirat"
msgid "Your sign-in page is %{url}."
msgstr ""
@@ -38788,6 +39145,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38795,10 +39176,10 @@ msgid "Zoom meeting removed"
msgstr ""
msgid "[No reason]"
-msgstr ""
+msgstr "[Fără motiv]"
msgid "[Redacted]"
-msgstr ""
+msgstr "[Redacted]"
msgid "`end_time` should not exceed one month after `start_time`"
msgstr ""
@@ -38807,28 +39188,28 @@ msgid "`start_time` should precede `end_time`"
msgstr ""
msgid "a deleted user"
-msgstr ""
+msgstr "un utilizator șters"
msgid "a design"
msgstr ""
msgid "about 1 hour"
msgid_plural "about %d hours"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "cam 1 oră"
+msgstr[1] "aproximativ %d ore"
+msgstr[2] "aproximativ %d de ore"
msgid "access:"
-msgstr ""
+msgstr "acces:"
msgid "added"
-msgstr ""
+msgstr "adăugat(ă)"
msgid "added %{created_at_timeago}"
-msgstr ""
+msgstr "adăugat %{created_at_timeago}"
msgid "added %{emails}"
-msgstr ""
+msgstr "adăugat %{emails}"
msgid "added a Zoom call to this issue"
msgstr ""
@@ -38837,7 +39218,7 @@ msgid "ago"
msgstr ""
msgid "alert"
-msgstr ""
+msgstr "alertă"
msgid "allowed to fail"
msgstr ""
@@ -38855,7 +39236,7 @@ msgid "already shared with this group"
msgstr ""
msgid "and"
-msgstr ""
+msgstr "și"
msgid "any-approver for the merge request already exists"
msgstr ""
@@ -38864,52 +39245,58 @@ msgid "any-approver for the project already exists"
msgstr ""
msgid "approved by: "
-msgstr ""
+msgstr "aprobat de: "
msgid "archived"
-msgstr ""
+msgstr "arhivat"
msgid "archived:"
-msgstr ""
+msgstr "arhivat:"
msgid "assign yourself"
msgstr ""
msgid "at"
-msgstr ""
+msgstr "la"
msgid "at risk"
msgstr ""
msgid "attach a new file"
-msgstr ""
+msgstr "atașați un fișier nou"
msgid "authored"
msgstr ""
msgid "banned user already exists"
-msgstr ""
+msgstr "utilizatorul interzis există deja"
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "branch name"
-msgstr ""
+msgstr "numele ramurii"
msgid "by"
-msgstr ""
+msgstr "de"
msgid "cURL:"
-msgstr ""
+msgstr "cURL:"
msgid "can contain only letters of the Base64 alphabet (RFC4648) with the addition of '@', ':' and '.'"
msgstr ""
msgid "can contain only lowercase letters, digits, and '_'."
-msgstr ""
+msgstr "poate conține doar litere mici, cifre și '_'."
msgid "can only be changed by a group admin."
-msgstr ""
+msgstr "poate fi schimbat doar de un administrator de grup."
msgid "can only have one escalation policy"
msgstr ""
@@ -38918,13 +39305,13 @@ msgid "can't be the same as the source project"
msgstr ""
msgid "can't include: %{invalid_storages}"
-msgstr ""
+msgstr "nu poate include: %{invalid_storages}"
msgid "cannot be a date in the past"
-msgstr ""
+msgstr "nu poate fi o dată în trecut"
msgid "cannot be changed"
-msgstr ""
+msgstr "nu poate fi schimbat"
msgid "cannot be changed if a personal project has container registry tags."
msgstr ""
@@ -38933,7 +39320,7 @@ msgid "cannot be changed if shared runners are enabled"
msgstr ""
msgid "cannot be enabled because parent group does not allow it"
-msgstr ""
+msgstr "nu poate fi activat deoarece grupul părinte nu o permite"
msgid "cannot be enabled because parent group has shared Runners disabled"
msgstr ""
@@ -38945,7 +39332,7 @@ msgid "cannot be enabled until a valid credit card is on file"
msgstr ""
msgid "cannot be modified"
-msgstr ""
+msgstr "nu poate fi modificat"
msgid "cannot block others"
msgstr ""
@@ -38963,13 +39350,13 @@ msgid "cannot merge"
msgstr ""
msgid "ciReport|%{degradedNum} degraded"
-msgstr ""
+msgstr "%{degradedNum} degradat"
msgid "ciReport|%{improvedNum} improved"
-msgstr ""
+msgstr "%{improvedNum} îmbunătățit"
msgid "ciReport|%{linkStartTag}Learn more about API Fuzzing%{linkEndTag}"
-msgstr ""
+msgstr "%{linkStartTag}Aflați mai multe despre API Fuzzing%{linkEndTag}"
msgid "ciReport|%{linkStartTag}Learn more about Container Scanning %{linkEndTag}"
msgstr ""
@@ -38978,13 +39365,13 @@ msgid "ciReport|%{linkStartTag}Learn more about Coverage Fuzzing %{linkEndTag}"
msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about DAST %{linkEndTag}"
-msgstr ""
+msgstr "%{linkStartTag} Aflați mai multe despre DAST %{linkEndTag}"
msgid "ciReport|%{linkStartTag}Learn more about Dependency Scanning %{linkEndTag}"
msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about SAST %{linkEndTag}"
-msgstr ""
+msgstr "%{linkStartTag} Aflați mai multe despre SAST %{linkEndTag}"
msgid "ciReport|%{linkStartTag}Learn more about Secret Detection %{linkEndTag}"
msgstr ""
@@ -39005,21 +39392,21 @@ msgid "ciReport|%{sameNum} same"
msgstr ""
msgid "ciReport|: Loading resulted in an error"
-msgstr ""
+msgstr ": Încărcarea a dus la o eroare"
msgid "ciReport|API Fuzzing"
-msgstr ""
+msgstr "API Fuzzing"
msgid "ciReport|API fuzzing"
-msgstr ""
+msgstr "API fuzzing"
msgid "ciReport|All projects"
-msgstr ""
-
-msgid "ciReport|All scanners"
-msgstr ""
+msgstr "Toate proiectele"
msgid "ciReport|All severities"
+msgstr "Toate severitățile"
+
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39035,25 +39422,25 @@ msgid "ciReport|Browser performance test metrics: No changes"
msgstr ""
msgid "ciReport|Checks"
-msgstr ""
+msgstr "Verificări"
msgid "ciReport|Cluster Image Scanning"
-msgstr ""
+msgstr "Scanare Imagini Cluster"
msgid "ciReport|Code quality"
-msgstr ""
+msgstr "Calitatea codului"
msgid "ciReport|Container Scanning"
-msgstr ""
+msgstr "Scanare container"
msgid "ciReport|Container scanning"
-msgstr ""
+msgstr "Scanare container"
msgid "ciReport|Container scanning detects known vulnerabilities in your docker images."
msgstr ""
msgid "ciReport|Could not dismiss vulnerability because the associated pipeline no longer exists. Refresh the page and try again."
-msgstr ""
+msgstr "Nu s-a putut respinge vulnerabilitatea deoarece conducta asociată nu mai există. Reîmprospătați pagina și încercați din nou."
msgid "ciReport|Coverage Fuzzing"
msgstr ""
@@ -39062,7 +39449,7 @@ msgid "ciReport|Coverage fuzzing"
msgstr ""
msgid "ciReport|Create Jira issue"
-msgstr ""
+msgstr "Creați problema Jira"
msgid "ciReport|Create a merge request to implement this solution, or download and apply the patch manually."
msgstr ""
@@ -39071,7 +39458,7 @@ msgid "ciReport|Create issue"
msgstr ""
msgid "ciReport|DAST"
-msgstr ""
+msgstr "DAST"
msgid "ciReport|Dependency Scanning"
msgstr ""
@@ -39113,13 +39500,13 @@ msgid "ciReport|Load performance test metrics: No changes"
msgstr ""
msgid "ciReport|Loading %{reportName} report"
-msgstr ""
+msgstr "Încarcă raportul %{reportName}"
msgid "ciReport|Manage licenses"
msgstr ""
msgid "ciReport|New"
-msgstr ""
+msgstr "Nou"
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -39128,13 +39515,13 @@ msgid "ciReport|No code quality issues found"
msgstr ""
msgid "ciReport|RPS"
-msgstr ""
+msgstr "RPS"
msgid "ciReport|Resolve with merge request"
msgstr ""
msgid "ciReport|SAST"
-msgstr ""
+msgstr "SAST"
msgid "ciReport|Secret Detection"
msgstr ""
@@ -39152,16 +39539,16 @@ msgid "ciReport|Security scanning failed loading any results"
msgstr ""
msgid "ciReport|Solution"
-msgstr ""
+msgstr "Soluție"
msgid "ciReport|Static Application Security Testing (SAST) detects known vulnerabilities in your source code."
msgstr ""
msgid "ciReport|TTFB P90"
-msgstr ""
+msgstr "TTFB P90"
msgid "ciReport|TTFB P95"
-msgstr ""
+msgstr "TTFB P95"
msgid "ciReport|There was an error creating the issue. Please try again."
msgstr ""
@@ -39188,16 +39575,16 @@ msgstr[1] ""
msgstr[2] ""
msgid "ciReport|View full report"
-msgstr ""
+msgstr "Vizualizați raportul complet"
msgid "ciReport|is loading"
-msgstr ""
+msgstr "se încarcă"
msgid "ciReport|is loading, errors when loading results"
msgstr ""
msgid "closed"
-msgstr ""
+msgstr "închis"
msgid "closed issue"
msgstr ""
@@ -39245,7 +39632,7 @@ msgid "collect usage information"
msgstr ""
msgid "comment"
-msgstr ""
+msgstr "comentariu"
msgid "commented on %{link_to_project}"
msgstr ""
@@ -39269,46 +39656,46 @@ msgid "could not read private key, is the passphrase correct?"
msgstr ""
msgid "created"
-msgstr ""
+msgstr "creat"
msgid "created %{issuable_created} by %{author}"
msgstr ""
msgid "created %{timeAgoString} by %{email} via %{user}"
-msgstr ""
+msgstr "creat %{timeAgoString} de %{email} prin %{user}"
msgid "created %{timeAgoString} by %{user}"
-msgstr ""
+msgstr "creat %{timeAgoString} de %{user}"
msgid "created %{timeAgoString} by %{user} in Jira"
-msgstr ""
+msgstr "creat %{timeAgoString} de %{user} în Jira"
msgid "created %{timeAgo}"
msgstr ""
msgid "created by"
-msgstr ""
+msgstr "creat de"
msgid "data"
msgstr ""
msgid "date must not be after 9999-12-31"
-msgstr ""
+msgstr "data nu trebuie să fie după 9999-12-31"
msgid "day"
msgid_plural "days"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "zi"
+msgstr[1] "zile"
+msgstr[2] "zilele"
msgid "days"
-msgstr ""
+msgstr "zile"
msgid "default branch"
msgstr ""
msgid "deleted"
-msgstr ""
+msgstr "șterse"
msgid "deploy"
msgstr ""
@@ -39320,19 +39707,19 @@ msgid "designs"
msgstr ""
msgid "detached"
-msgstr ""
+msgstr "detașat"
msgid "disabled"
-msgstr ""
+msgstr "dezactivat"
msgid "does not exist"
-msgstr ""
+msgstr "nu există"
msgid "does not have a supported extension. Only %{extension_list} are supported"
-msgstr ""
+msgstr "nu are o extensie acceptată. Doar %{extension_list} sunt acceptate"
msgid "domain is not authorized for sign-up."
-msgstr ""
+msgstr "domeniul nu este autorizat pentru înregistrare."
msgid "download it"
msgstr ""
@@ -39347,19 +39734,19 @@ msgid "e.g. %{token}"
msgstr ""
msgid "element is not a hierarchy"
-msgstr ""
+msgstr "elementul nu este o ierarhie"
msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "email does not match the allowed domain of %{email_domains}"
msgid_plural "email does not match the allowed domains: %{email_domains}"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "e-mail-ul nu se potrivește cu domeniul permis de %{email_domains}"
+msgstr[1] "e-mail-ul nu se potrivește cu domeniile permise: %{email_domains}"
+msgstr[2] "e-mail-ul nu se potrivește cu domeniile permise: %{email_domains}"
msgid "enabled"
-msgstr ""
+msgstr "activat"
msgid "encrypted: needs to be a :required, :optional or :migrating!"
msgstr ""
@@ -39371,19 +39758,22 @@ msgid "entries cannot be larger than 255 characters"
msgstr ""
msgid "entries cannot be nil"
-msgstr ""
+msgstr "intrările nu pot fi nule"
msgid "entries cannot contain HTML tags"
msgstr ""
-msgid "epic"
+msgid "environment_id parameter is required when type is container_policy"
msgstr ""
+msgid "epic"
+msgstr "epic"
+
msgid "error"
-msgstr ""
+msgstr "eroare"
msgid "estimateCommand|%{slash_command} overwrites the total estimated time."
-msgstr ""
+msgstr "%{slash_command}suprascrie timpul total estimat."
msgid "exceeds the limit of %{bytes} bytes"
msgstr ""
@@ -39392,10 +39782,10 @@ msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
msgid "expired on %{timebox_due_date}"
-msgstr ""
+msgstr "a expirat la %{timebox_due_date}"
msgid "expires on %{timebox_due_date}"
-msgstr ""
+msgstr "expiră la %{timebox_due_date}"
msgid "failed"
msgstr ""
@@ -39408,9 +39798,9 @@ msgstr ""
msgid "file"
msgid_plural "files"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "fișier"
+msgstr[1] "fișiere"
+msgstr[2] "de fișiere"
msgid "finding is not found or is already attached to a vulnerability"
msgstr ""
@@ -39419,19 +39809,19 @@ msgid "following"
msgstr ""
msgid "for %{link_to_merge_request} with %{link_to_merge_request_source_branch}"
-msgstr ""
+msgstr "pentru %{link_to_merge_request} cu %{link_to_merge_request_source_branch}"
msgid "for %{link_to_merge_request} with %{link_to_merge_request_source_branch} into %{link_to_merge_request_target_branch}"
-msgstr ""
+msgstr "pentru %{link_to_merge_request} cu %{link_to_merge_request_source_branch} în %{link_to_merge_request_target_branch}"
msgid "for %{link_to_pipeline_ref}"
-msgstr ""
+msgstr "pentru %{link_to_pipeline_ref}"
msgid "for %{ref}"
-msgstr ""
+msgstr "pentru %{ref}"
msgid "for this project"
-msgstr ""
+msgstr "pentru acest proiect"
msgid "fork"
msgstr ""
@@ -39440,7 +39830,7 @@ msgid "fork this project"
msgstr ""
msgid "from"
-msgstr ""
+msgstr "de la"
msgid "from %d job"
msgid_plural "from %d jobs"
@@ -39449,19 +39839,19 @@ msgstr[1] ""
msgstr[2] ""
msgid "group"
-msgstr ""
+msgstr "grup"
msgid "group members"
-msgstr ""
+msgstr "membrii grupului"
msgid "group's CI/CD settings."
msgstr ""
msgid "groups"
-msgstr ""
+msgstr "grupuri"
msgid "has already been linked to another vulnerability"
-msgstr ""
+msgstr "a fost deja legat de o altă vulnerabilitate"
msgid "has already been taken"
msgstr ""
@@ -39476,22 +39866,22 @@ msgid "has been completed."
msgstr ""
msgid "help"
-msgstr ""
+msgstr "ajutor"
msgid "http:"
-msgstr ""
+msgstr "http:"
msgid "http://www.example.com"
-msgstr ""
+msgstr "http://www.example.com"
msgid "https://bamboo.example.com"
-msgstr ""
+msgstr "https://bamboo.example.com"
msgid "https://your-bitbucket-server"
-msgstr ""
+msgstr "https://serverul-tău-bitbucket"
msgid "i18n|%{language} (%{percent_translated}%% translated)"
-msgstr ""
+msgstr "%{language} (%{percent_translated}%% tradus)"
msgid "image diff"
msgstr ""
@@ -39503,40 +39893,40 @@ msgid "impersonation tokens"
msgstr ""
msgid "import flow"
-msgstr ""
+msgstr "fluxul de import"
msgid "in"
-msgstr ""
+msgstr "în"
msgid "in group %{link_to_group}"
-msgstr ""
+msgstr "în grupul %{link_to_group}"
msgid "in project %{link_to_project}"
msgstr ""
msgid "instance completed"
msgid_plural "instances completed"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "instanță finalizată"
+msgstr[1] "instanțe finalizate"
+msgstr[2] "instanțe finalizate"
msgid "invalid milestone state `%{state}`"
msgstr ""
msgid "is"
-msgstr ""
+msgstr "este"
msgid "is already associated to a GitLab Issue. New issue will not be associated."
msgstr ""
msgid "is an invalid IP address range"
-msgstr ""
+msgstr "este un interval de adrese IP invalide"
msgid "is blocked by"
-msgstr ""
+msgstr "este blocat de"
msgid "is forbidden by a top-level group"
-msgstr ""
+msgstr "este interzisă de un grup de nivel superior"
msgid "is invalid because there is downstream lock"
msgstr ""
@@ -39545,16 +39935,16 @@ msgid "is invalid because there is upstream lock"
msgstr ""
msgid "is not"
-msgstr ""
+msgstr "nu este"
msgid "is not a descendant of the Group owning the template"
msgstr ""
msgid "is not a valid X509 certificate."
-msgstr ""
+msgstr "nu este un certificat X509 valid."
msgid "is not allowed since the group is not top-level group."
-msgstr ""
+msgstr "nu este permis, deoarece grupul nu este un grup de nivel superior."
msgid "is not allowed. Try again with a different email address, or contact your GitLab admin."
msgstr ""
@@ -39562,11 +39952,8 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
-msgstr ""
+msgstr "nu provine dintr-un domeniu permis."
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
@@ -39578,13 +39965,13 @@ msgid "is read-only"
msgstr ""
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
-msgstr ""
+msgstr "este prea lung (%{current_value}). Dimensiunea maximă este %{max_size}."
msgid "is too long (maximum is %{count} characters)"
msgstr ""
msgid "is too long (maximum is 100 entries)"
-msgstr ""
+msgstr "este prea lung (maximum 100 de intrări)"
msgid "is too long (maximum is 1000 entries)"
msgstr ""
@@ -39602,25 +39989,25 @@ msgid "issues on track"
msgstr ""
msgid "it is larger than %{limit}"
-msgstr ""
+msgstr "este mai mare de %{limit}"
msgid "it is stored as a job artifact"
msgstr ""
msgid "it is stored externally"
-msgstr ""
+msgstr "este stocat extern"
msgid "it is stored in LFS"
-msgstr ""
+msgstr "este stocat în LFS"
msgid "it is too large"
-msgstr ""
+msgstr "este prea mare"
msgid "jigsaw is not defined"
msgstr ""
msgid "kuromoji custom analyzer"
-msgstr ""
+msgstr "analizor personalizat kuromoji"
msgid "last commit:"
msgstr ""
@@ -39638,28 +40025,28 @@ msgid "leave %{group_name}"
msgstr ""
msgid "less than a minute"
-msgstr ""
+msgstr "mai putin de un minut"
msgid "level: %{level}"
-msgstr ""
+msgstr "nivel: %{level}"
msgid "limit of %{project_limit} reached"
msgstr ""
msgid "load it anyway"
-msgstr ""
+msgstr "încărcați-l oricum"
msgid "loading"
-msgstr ""
+msgstr "se încarcă"
msgid "locked by %{path_lock_user_name} %{created_at}"
-msgstr ""
+msgstr "blocat de %{path_lock_user_name} %{created_at}"
msgid "log in"
-msgstr ""
+msgstr "autentificare"
msgid "manual"
-msgstr ""
+msgstr "manual"
msgid "math|Displaying this math block may cause performance issues on this page"
msgstr ""
@@ -39677,13 +40064,13 @@ msgid "merged %{timeAgo}"
msgstr ""
msgid "metric_id must be unique across a project"
-msgstr ""
+msgstr "metric_id trebuie să fie unic în cadrul unui proiect"
msgid "missing"
-msgstr ""
+msgstr "lipsește"
msgid "more information"
-msgstr ""
+msgstr "mai multe informații"
msgid "most recent deployment"
msgstr ""
@@ -39728,7 +40115,7 @@ msgid "mrWidget|A new merge train has started and this merge request is the firs
msgstr ""
msgid "mrWidget|Added to the merge train by %{merge_author}"
-msgstr ""
+msgstr "Adăugat la merge train de %{merge_author}"
msgid "mrWidget|Added to the merge train. There are %{mergeTrainPosition} merge requests waiting to be merged"
msgstr ""
@@ -39743,25 +40130,25 @@ msgid "mrWidget|An error occurred while submitting your approval."
msgstr ""
msgid "mrWidget|Approval is optional"
-msgstr ""
+msgstr "Aprobarea este opțională"
msgid "mrWidget|Approval password is invalid."
msgstr ""
msgid "mrWidget|Approve"
-msgstr ""
+msgstr "Aprobați"
msgid "mrWidget|Approve additionally"
msgstr ""
msgid "mrWidget|Approved by"
-msgstr ""
+msgstr "Aprobat de"
msgid "mrWidget|Are you adding technical debt or code vulnerabilities?"
msgstr ""
msgid "mrWidget|Cancel auto-merge"
-msgstr ""
+msgstr "Anulați auto-îmbinarea"
msgid "mrWidget|Check out branch"
msgstr ""
@@ -39776,13 +40163,16 @@ msgid "mrWidget|Cherry-pick this merge request in a new merge request"
msgstr ""
msgid "mrWidget|Closed"
-msgstr ""
+msgstr "ÃŽnchis"
msgid "mrWidget|Closed by"
-msgstr ""
+msgstr "ÃŽnchis de"
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39817,8 +40207,11 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39827,7 +40220,7 @@ msgid "mrWidget|Merge blocked: all threads must be resolved."
msgstr ""
msgid "mrWidget|Merge blocked: fast-forward merge is not possible. To merge this request, first rebase locally."
-msgstr ""
+msgstr "Îmbinare blocată: îmbinarea fast-forward nu este posibilă. Pentru a îmbina acest request, mai întâi rebazați pe plan local."
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
@@ -39863,13 +40256,16 @@ msgid "mrWidget|Merging! We're almost there…"
msgstr ""
msgid "mrWidget|More information"
+msgstr "Mai multe informații"
+
+msgid "mrWidget|Open in Gitpod"
msgstr ""
msgid "mrWidget|Open in Web IDE"
-msgstr ""
+msgstr "Deschideți în Web IDE"
msgid "mrWidget|Plain diff"
-msgstr ""
+msgstr "Diff simplu"
msgid "mrWidget|Ready to be merged automatically. Ask someone with write access to this repository to merge this request"
msgstr ""
@@ -39905,16 +40301,16 @@ msgid "mrWidget|Revert this merge request in a new merge request"
msgstr ""
msgid "mrWidget|Revoke approval"
-msgstr ""
+msgstr "Revocați aprobarea"
msgid "mrWidget|Set by %{merge_author} to be added to the merge train when the pipeline succeeds"
-msgstr ""
+msgstr "Setat de %{merge_author} pentru a fi adăugat merge train-ului automat când conducta reușește"
msgid "mrWidget|Set by %{merge_author} to be merged automatically when the pipeline succeeds"
msgstr ""
msgid "mrWidget|Set by %{merge_author} to start a merge train when the pipeline succeeds"
-msgstr ""
+msgstr "Setat de %{merge_author} pentru a începe un merge train când conducta reușește"
msgid "mrWidget|The changes were merged into"
msgstr ""
@@ -39928,9 +40324,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39970,9 +40363,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39980,32 +40370,38 @@ msgid "mrWidget|Your password"
msgstr ""
msgid "mrWidget|branch does not exist."
-msgstr ""
+msgstr "ramura nu există."
msgid "mrWidget|into"
msgstr ""
msgid "must be a Debian package"
-msgstr ""
+msgstr "trebuie să fie un pachet Debian"
msgid "must be a boolean value"
-msgstr ""
+msgstr "trebuie să fie o valoare booleană"
msgid "must be a root namespace"
msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
-msgstr ""
+msgstr "trebuie să fie o adresă IPv4 sau IPv6 validă"
msgid "must be after start"
msgstr ""
-msgid "must be greater than start date"
+msgid "must be an email you have verified"
msgstr ""
+msgid "must be greater than start date"
+msgstr "trebuie să fie mai mare decât data de începere"
+
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
@@ -40013,22 +40409,22 @@ msgid "my-awesome-group"
msgstr ""
msgid "my-channel"
-msgstr ""
+msgstr "canalul meu"
msgid "n/a"
-msgstr ""
+msgstr "n/a"
msgid "need attention"
-msgstr ""
+msgstr "au nevoie de atenție"
msgid "needs to be between 10 minutes and 1 month"
-msgstr ""
+msgstr "trebuie să fie între 10 minute și 1 lună"
msgid "never"
-msgstr ""
+msgstr "niciodată"
msgid "never expires"
-msgstr ""
+msgstr "nu expiră niciodată"
msgid "new merge request"
msgstr ""
@@ -40052,19 +40448,19 @@ msgid "none"
msgstr ""
msgid "not found"
-msgstr ""
+msgstr "nu a fost găsit"
msgid "nounSeries|%{firstItem} and %{lastItem}"
-msgstr ""
+msgstr "%{firstItem} și %{lastItem}"
msgid "nounSeries|%{item}"
-msgstr ""
+msgstr "%{item}"
msgid "nounSeries|%{item}, %{nextItem}"
-msgstr ""
+msgstr "%{item}, %{nextItem}"
msgid "nounSeries|%{item}, and %{lastItem}"
-msgstr ""
+msgstr "%{item} și %{lastItem}"
msgid "on track"
msgstr ""
@@ -40076,10 +40472,10 @@ msgid "open issue"
msgstr ""
msgid "opened %{timeAgo}"
-msgstr ""
+msgstr "deschis %{timeAgo}"
msgid "or"
-msgstr ""
+msgstr "sau"
msgid "originating vulnerability"
msgstr ""
@@ -40097,16 +40493,16 @@ msgstr[1] ""
msgstr[2] ""
msgid "password"
-msgstr ""
+msgstr "parolă"
msgid "pending comment"
-msgstr ""
+msgstr "comentariu în așteptare"
msgid "pending deletion"
-msgstr ""
+msgstr "în așteptarea ștergerii"
msgid "per day"
-msgstr ""
+msgstr "pe zi"
msgid "personal access token"
msgstr ""
@@ -40133,19 +40529,19 @@ msgid "previously merged commits"
msgstr ""
msgid "private"
-msgstr ""
+msgstr "privat"
msgid "private key does not match certificate."
-msgstr ""
+msgstr "cheia privată nu se potrivește cu certificatul."
msgid "processing"
msgstr ""
msgid "project"
msgid_plural "projects"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "proiect"
+msgstr[1] "proiecte"
+msgstr[2] "proiectele"
msgid "project access token"
msgstr ""
@@ -40163,31 +40559,31 @@ msgid "project is read-only"
msgstr ""
msgid "project members"
-msgstr ""
+msgstr "membrii proiectului"
msgid "project name"
msgstr ""
msgid "projects"
-msgstr ""
+msgstr "proiecte"
msgid "quick actions"
-msgstr ""
+msgstr "acțiuni rapide"
msgid "reCAPTCHA Private Key"
-msgstr ""
+msgstr "cheie privată reCAPTCHA"
msgid "reCAPTCHA Site Key"
-msgstr ""
+msgstr "cheia site-ului reCAPTCHA"
msgid "recent activity"
-msgstr ""
+msgstr "activitate recentă"
msgid "register"
msgstr ""
msgid "relates to"
-msgstr ""
+msgstr "se referă la"
msgid "remaining"
msgstr ""
@@ -40199,37 +40595,37 @@ msgid "remove due date"
msgstr ""
msgid "remove start date"
-msgstr ""
+msgstr "eliminați data de începere"
msgid "remove weight"
msgstr ""
msgid "removed"
-msgstr ""
+msgstr "eliminat"
msgid "removed a Zoom call from this issue"
-msgstr ""
+msgstr "a eliminat un apel Zoom din această problemă"
msgid "rendered diff"
msgstr ""
msgid "reply"
msgid_plural "replies"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "răspuns"
+msgstr[1] "răspunsuri"
+msgstr[2] "răspunsurile"
msgid "repository:"
-msgstr ""
+msgstr "repozitoriu:"
msgid "required"
msgstr ""
msgid "reset it."
-msgstr ""
+msgstr "resetați-l."
msgid "satisfied"
-msgstr ""
+msgstr "satisfăcut"
msgid "scan-execution-policy: policy not applied, %{policy_path} file is invalid"
msgstr ""
@@ -40244,31 +40640,31 @@ msgid "severity|Blocker"
msgstr ""
msgid "severity|Critical"
-msgstr ""
+msgstr "Critică"
msgid "severity|High"
-msgstr ""
+msgstr "Ridicată"
msgid "severity|Info"
-msgstr ""
+msgstr "Info"
msgid "severity|Low"
-msgstr ""
+msgstr "Scăzută"
msgid "severity|Major"
-msgstr ""
+msgstr "Majoră"
msgid "severity|Medium"
-msgstr ""
+msgstr "Medie"
msgid "severity|Minor"
-msgstr ""
+msgstr "Minoră"
msgid "severity|None"
-msgstr ""
+msgstr "Niciuna"
msgid "severity|Unknown"
-msgstr ""
+msgstr "Necunoscută"
msgid "should be an array of %{object_name} objects"
msgstr ""
@@ -40286,16 +40682,16 @@ msgid "show less"
msgstr ""
msgid "sign in"
-msgstr ""
+msgstr "autentificare"
msgid "smartcn custom analyzer"
-msgstr ""
+msgstr "analizor personalizat smartcn"
msgid "sort:"
-msgstr ""
+msgstr "sortare:"
msgid "source"
-msgstr ""
+msgstr "sursă"
msgid "source diff"
msgstr ""
@@ -40304,25 +40700,25 @@ msgid "specified top is not part of the tree"
msgstr ""
msgid "spendCommand|%{slash_command} adds or subtracts time already spent."
-msgstr ""
+msgstr "%{slash_command}adaugă sau scade timpul deja cheltuit."
msgid "ssh:"
-msgstr ""
+msgstr "ssh:"
msgid "started a discussion on %{design_link}"
-msgstr ""
+msgstr "a început o discuție pe %{design_link}"
msgid "started on %{timebox_start_date}"
-msgstr ""
+msgstr "a început la %{timebox_start_date}"
msgid "starts on %{timebox_start_date}"
-msgstr ""
+msgstr "începe la %{timebox_start_date}"
msgid "stuck"
-msgstr ""
+msgstr "blocat"
msgid "success"
-msgstr ""
+msgstr "succes"
msgid "suggestPipeline|1/2: Choose a template"
msgstr ""
@@ -40343,28 +40739,28 @@ msgid "tag name"
msgstr ""
msgid "the correct format."
-msgstr ""
+msgstr "formatul corect."
msgid "the file"
-msgstr ""
+msgstr "fișierul"
msgid "the following issue(s)"
-msgstr ""
+msgstr "următoarea (următoarele) problemă(e)"
msgid "the wiki"
-msgstr ""
+msgstr "wiki"
msgid "then"
-msgstr ""
+msgstr "atunci"
msgid "this document"
-msgstr ""
+msgstr "acest document"
msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
+msgstr "această problemă nu poate fi atribuită unui epic confidențial deoarece este publică"
msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
+msgstr "această problemă nu poate fi făcută publică deoarece aparține unui epic confidențial"
msgid "time summary"
msgstr ""
@@ -40373,19 +40769,19 @@ msgid "toggle collapse"
msgstr ""
msgid "train"
-msgstr ""
+msgstr "tren"
msgid "triggered"
msgstr ""
msgid "two-factor authentication settings"
-msgstr ""
+msgstr "setări de autentificare cu doi factori"
msgid "type must be Debian"
msgstr ""
msgid "type parameter is missing and is required"
-msgstr ""
+msgstr "parametrul tipului lipsește și este necesar"
msgid "unicode domains should use IDNA encoding"
msgstr ""
@@ -40400,16 +40796,16 @@ msgid "updated %{time_ago}"
msgstr ""
msgid "uploads"
-msgstr ""
+msgstr "încărcări"
msgid "user avatar"
msgstr ""
msgid "user preferences"
-msgstr ""
+msgstr "preferințele utilizatorului"
msgid "username"
-msgstr ""
+msgstr "utilizator"
msgid "v%{version} published %{timeAgo}"
msgstr ""
@@ -40424,7 +40820,7 @@ msgid "verify ownership"
msgstr ""
msgid "version %{versionIndex}"
-msgstr ""
+msgstr "versiunea %{versionIndex}"
msgid "via %{closed_via}"
msgstr ""
@@ -40436,28 +40832,28 @@ msgid "view it on GitLab"
msgstr ""
msgid "view the blob"
-msgstr ""
+msgstr "vizualizați blob-ul"
msgid "view the source"
-msgstr ""
+msgstr "vizualizați sursa"
msgid "visibility"
-msgstr ""
+msgstr "vizibilitate"
msgid "vulnerability"
msgid_plural "vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgstr[0] "vulnerabilitate"
+msgstr[1] "vulnerabilități"
+msgstr[2] "de vulnerabilități"
msgid "vulnerability|Add a comment"
-msgstr ""
+msgstr "Adăugați un comentariu"
msgid "vulnerability|Add a comment or reason for dismissal"
-msgstr ""
+msgstr "Adăugați un comentariu sau un motiv pentru respingere"
msgid "vulnerability|Add comment"
-msgstr ""
+msgstr "Adăugați comentariu"
msgid "vulnerability|Add comment & dismiss"
msgstr ""
@@ -40469,7 +40865,7 @@ msgid "vulnerability|Dismiss vulnerability"
msgstr ""
msgid "vulnerability|Save comment"
-msgstr ""
+msgstr "Salvați comentariul"
msgid "vulnerability|Undo dismiss"
msgstr ""
@@ -40481,7 +40877,7 @@ msgid "was scheduled to merge after pipeline succeeds by"
msgstr ""
msgid "wiki page"
-msgstr ""
+msgstr "pagina wiki"
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
@@ -40493,8 +40889,8 @@ msgid "with expiry remaining unchanged at %{old_expiry}"
msgstr ""
msgid "yaml invalid"
-msgstr ""
+msgstr "yaml invalid"
msgid "your settings"
-msgstr ""
+msgstr "setările dvs."
diff --git a/locale/ru/gitlab.po b/locale/ru/gitlab.po
index 2a9da0df3fd..eb56db731af 100644
--- a/locale/ru/gitlab.po
+++ b/locale/ru/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ru\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:33\n"
+"PO-Revision-Date: 2021-09-01 22:34\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -29,7 +29,7 @@ msgid " Collected %{time}"
msgstr " Получено %{time}"
msgid " Please sign in."
-msgstr "ПожалуйÑта, войдите."
+msgstr " ПожалуйÑта, войдите."
msgid " Target Path"
msgstr ""
@@ -38,7 +38,7 @@ msgid " Try to %{action} this file again."
msgstr " Попробуйте %{action} Ñтот файл еще раз."
msgid " Type"
-msgstr ""
+msgstr " Тип"
msgid " You need to do this before %{grace_period_deadline}."
msgstr " Вам нужно Ñделать Ñто до %{grace_period_deadline}."
@@ -98,24 +98,24 @@ msgstr ""
msgid "%d Approval"
msgid_plural "%d Approvals"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "%d ÑоглаÑование"
+msgstr[1] "%d ÑоглаÑованиÑ"
+msgstr[2] "%d ÑоглаÑований"
+msgstr[3] "%d ÑоглаÑованиÑ"
msgid "%d Module"
msgid_plural "%d Modules"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "%d модуль"
+msgstr[1] "%d модулÑ"
+msgstr[2] "%d модулей"
+msgstr[3] "%d модулей"
msgid "%d Other"
msgid_plural "%d Others"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "%d другой"
+msgstr[1] "%d других"
+msgstr[2] "%d других"
+msgstr[3] "%d другие"
msgid "%d Package"
msgid_plural "%d Packages"
@@ -126,10 +126,10 @@ msgstr[3] "%d пакетов"
msgid "%d Scanned URL"
msgid_plural "%d Scanned URLs"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "%d отÑÐºÐ°Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð°Ñ ÑÑылка"
+msgstr[1] "%d отÑканированные ÑÑылки"
+msgstr[2] "%d отÑканированных ÑÑылок"
+msgstr[3] "%d отÑканированных ÑÑылок"
msgid "%d URL scanned"
msgid_plural "%d URLs scanned"
@@ -161,10 +161,10 @@ msgstr[3] "%d измененных файлов"
msgid "%d character remaining"
msgid_plural "%d characters remaining"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "ОÑталÑÑ %d Ñимвол"
+msgstr[1] "ОÑталоÑÑŒ %d Ñимвола"
+msgstr[2] "ОÑталоÑÑŒ %d Ñимволов"
+msgstr[3] "ОÑталоÑÑŒ %d Ñимволов"
msgid "%d child epic"
msgid_plural "%d child epics"
@@ -297,10 +297,10 @@ msgstr[3] ""
msgid "%d file"
msgid_plural "%d files"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "%d файл"
+msgstr[1] "%d файла"
+msgstr[2] "%d файлов"
+msgstr[3] "%d файлов"
msgid "%d fixed test result"
msgid_plural "%d fixed test results"
@@ -311,10 +311,10 @@ msgstr[3] "%d иÑправленные результаты теÑта"
msgid "%d group"
msgid_plural "%d groups"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "%d группа"
+msgstr[1] "%d группы"
+msgstr[2] "%d групп"
+msgstr[3] "%d групп"
msgid "%d group selected"
msgid_plural "%d groups selected"
@@ -484,6 +484,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -566,10 +573,10 @@ msgstr[3] ""
msgid "%{bold_start}%{count}%{bold_end} member"
msgid_plural "%{bold_start}%{count}%{bold_end} members"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "%{bold_start}%{count}%{bold_end} пользователь"
+msgstr[1] "%{bold_start}%{count}%{bold_end} пользователÑ"
+msgstr[2] "%{bold_start}%{count}%{bold_end} пользователей"
+msgstr[3] "%{bold_start}%{count}%{bold_end} пользователей"
msgid "%{bold_start}%{count}%{bold_end} opened merge request"
msgid_plural "%{bold_start}%{count}%{bold_end} opened merge requests"
@@ -661,6 +668,9 @@ msgstr[3] "%{count} учаÑтников"
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr "%{count} ÑвÑзанный %{pluralized_subject}: %{links}"
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -799,9 +809,6 @@ msgstr "%{labelStart}Метод:%{labelEnd} %{method}"
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr "%{labelStart}ПроÑтранÑтво имён:%{labelEnd} %{namespace}"
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr "%{labelStart}Сканер:%{labelEnd} %{scanner}"
@@ -811,6 +818,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -978,6 +988,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr "%{seconds}Ñ"
@@ -1452,7 +1465,7 @@ msgstr[2] ""
msgstr[3] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -1750,10 +1763,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1780,10 +1793,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2560,8 +2573,8 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
-msgstr "Ð’Ñ‹ ÑобираетеÑÑŒ оÑтановить вÑе заданиÑ. Это дейÑтвие оÑтановит вÑе текущие заданиÑ, находÑщиеÑÑ Ð² процеÑÑе выполнениÑ."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
+msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "Ошибка загрузки ÑтатиÑтики. ПожалуйÑта, попробуйте еще раз"
@@ -2788,12 +2801,6 @@ msgstr "Заблокированные"
msgid "AdminUsers|Blocking user has the following effects:"
msgstr "Блокировка Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð¼ÐµÐµÑ‚ Ñледующие Ñффекты:"
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2860,6 +2867,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr "ИÑпользует меÑто"
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr "Это вы!"
@@ -2923,6 +2933,12 @@ msgstr "Отправить Ñлектронные пиÑьма пользоваÑ
msgid "AdminUsers|Sort by"
msgstr "Сортировать по"
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr "Пользователь выйдет из ÑиÑтемы"
@@ -2989,7 +3005,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3201,7 +3217,7 @@ msgid "AlertManagement|Open"
msgstr ""
msgid "AlertManagement|Please try again."
-msgstr ""
+msgstr "ПожалуйÑта, попробуйте еще раз."
msgid "AlertManagement|Reported %{when}"
msgstr ""
@@ -3836,9 +3852,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr "Произошла ошибка при получении отчётов Terraform."
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr "Произошла ошибка при получении ÑпиÑка панелей управлениÑ. ПожалуйÑта, попробуйте ещё раз."
-
msgid "An error occurred while fetching the job log."
msgstr "Произошла ошибка при получении журнала заданий."
@@ -3854,9 +3867,6 @@ msgstr "Ошибка при извлечении заданий."
msgid "An error occurred while fetching the latest pipeline."
msgstr "Произошла ошибка при извлечении поÑледней Ñборочной линии."
-msgid "An error occurred while fetching the pipeline."
-msgstr "Произошла ошибка при получении Ñборочной линии."
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr "Произошла ошибка при выборке релизов. ПожалуйÑта, попробуйте ещё раз."
@@ -3888,7 +3898,7 @@ msgid "An error occurred while loading all the files."
msgstr "Произошла ошибка при загрузке вÑех файлов."
msgid "An error occurred while loading chart data"
-msgstr "Произошла ошибка при загрузке данных диаграммы "
+msgstr ""
msgid "An error occurred while loading commit signatures"
msgstr "Произошла ошибка при загрузке подпиÑей коммита"
@@ -3911,6 +3921,12 @@ msgstr "Произошла ошибка при загрузке обÑужден
msgid "An error occurred while loading merge requests."
msgstr "Произошла ошибка при загрузке запроÑов на ÑлиÑние."
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4394,7 +4410,7 @@ msgstr[1] "Ðеобходимо %{count} одобрений из %{membersCount}
msgstr[2] "Ðеобходимо %{count} одобрений из %{membersCount}"
msgstr[3] "Ðеобходимо %{count} одобрений из %{membersCount}"
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4403,9 +4419,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4433,6 +4455,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr "Ðазвание правила"
@@ -4445,6 +4470,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr "Ð¦ÐµÐ»ÐµÐ²Ð°Ñ Ð²ÐµÑ‚ÐºÐ°"
@@ -4454,19 +4485,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4577,6 +4614,9 @@ msgstr "Ð’Ñ‹ уверены, что хотите воÑÑтановить Ñто
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr "Ð’Ñ‹ уверены, что хотите отменить редактирование данного комментариÑ?"
@@ -4737,9 +4777,6 @@ msgstr "Ðртефакт был уÑпешно удален."
msgid "Artifacts"
msgstr "Ðртефакты"
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4783,7 +4820,7 @@ msgid "Assign Iteration"
msgstr "Ðазначить итерацию"
msgid "Assign To"
-msgstr "Ðазначить на "
+msgstr ""
msgid "Assign custom color like #FF0000"
msgstr "Ðазначьте пользовательÑкий цвет, например #FF0000"
@@ -4858,9 +4895,6 @@ msgstr "ОтветÑтвенный не имеет доÑтупа"
msgid "Assignee lists not available with your current license"
msgstr "СпиÑки ответÑтвенных не доÑтупны Ñ Ð²Ð°ÑˆÐµÐ¹ текущей лицензией"
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr "СпиÑки ответÑтвенных показывают вÑе обÑуждениÑ, назначенные выбранному пользователю."
-
msgid "Assignee(s)"
msgstr "ОтветÑтвенный(ые)"
@@ -4979,6 +5013,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -5156,6 +5196,9 @@ msgstr "ÐвтоматичеÑкое управление Ñертификата
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5348,9 +5391,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr "Ðачать Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð¾Ð³Ð¾ коммита"
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr "Ðиже приведены отпечатки ключей SSH текущего ÑкземплÑра."
@@ -5637,9 +5677,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5652,12 +5689,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr "ДоÑки"
@@ -5723,9 +5766,6 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr "Свернуть"
@@ -6026,30 +6066,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6104,6 +6138,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr "Купить минут Ð´Ð»Ñ CI"
@@ -6255,6 +6292,9 @@ msgstr "CONTRIBUTING"
msgid "CPU"
msgstr "CPU"
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6738,12 +6778,19 @@ msgstr "Проверка доÑтупноÑти имени пользоватеÐ
msgid "Checkout"
msgstr "Оформление заказа"
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6753,15 +6800,19 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr "план %{selectedPlanText}"
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6777,7 +6828,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr "Платёжный адреÑ"
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7117,7 +7168,7 @@ msgid "CiVariables|Variables"
msgstr "Переменные"
msgid "CiVariable|* (All environments)"
-msgstr " * (Ð’Ñе Ñреды)"
+msgstr ""
msgid "CiVariable|All environments"
msgstr "Ð’Ñе Ñреды"
@@ -7386,6 +7437,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7401,9 +7455,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -8074,7 +8125,7 @@ msgid "ClusterIntegration|Set a prefix for your namespaces. If not set, defaults
msgstr ""
msgid "ClusterIntegration|Something went wrong on our end."
-msgstr " У Ð½Ð°Ñ Ñ‡Ñ‚Ð¾-то пошло не так."
+msgstr ""
msgid "ClusterIntegration|Something went wrong while creating your Kubernetes cluster"
msgstr "Что-то пошло не так при Ñоздании вашего клаÑтера Kubernetes"
@@ -8085,7 +8136,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr "ПодÑети"
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8107,7 +8158,7 @@ msgid "ClusterIntegration|There was an HTTP error when connecting to your cluste
msgstr ""
msgid "ClusterIntegration|This account must have permissions to create a Kubernetes cluster in the %{link_to_container_project} specified below"
-msgstr " У Ñтой учетной запиÑи должны быть Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð½Ð° Ñоздание клаÑтера Kubernetes в %{link_to_container_project} указанных ниже"
+msgstr ""
msgid "ClusterIntegration|This is necessary if your integration has become out of sync. The cache is repopulated during the next CI job that requires namespace and service accounts."
msgstr ""
@@ -8569,9 +8620,6 @@ msgstr "Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñлужбы комплаенÑа"
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr "Фреймворк комплаенÑа (необÑзательно)"
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8710,9 +8758,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr "ÐаÑтройка ограничений Ð´Ð»Ñ Web и API запроÑов."
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr "ÐаÑтройте Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð½Ð° количеÑтво входÑщих оповещений, которые могут быть отправлены в проект."
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8725,6 +8770,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9451,7 +9499,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10692,6 +10740,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10704,6 +10755,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10716,12 +10770,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10741,6 +10801,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10873,9 +10936,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10945,6 +11005,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10993,9 +11056,15 @@ msgstr "Удалить артефакты"
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr "Удалить комментарий"
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -11020,6 +11089,9 @@ msgstr "Удалить проект"
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -11038,6 +11110,9 @@ msgstr "Удалить иÑходную ветку"
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr "Удалить вложение"
@@ -11221,12 +11296,12 @@ msgstr "Сканирование ЗавиÑимоÑтей"
msgid "Dependency proxy"
msgstr "ПрокÑи завиÑимоÑтей"
-msgid "Dependency proxy URL"
-msgstr "URL прокÑи-Ñервера завиÑимоÑтей"
-
msgid "Dependency proxy feature is limited to public groups for now."
msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ñ€Ð¾ÐºÑи-завиÑимоÑтей на данный момент ограничиваетÑÑ Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ñ‹Ð¼Ð¸ группами."
+msgid "Dependency proxy image prefix"
+msgstr ""
+
msgid "DependencyProxy|Toggle Dependency Proxy"
msgstr "Переключить прокÑи-завиÑимоÑÑ‚ÑŒ"
@@ -11278,6 +11353,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11708,6 +11795,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11768,7 +11861,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -12279,6 +12372,9 @@ msgstr "Редактировать узел Geo"
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr "Редактировать метку"
@@ -12354,6 +12450,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12561,9 +12660,6 @@ msgstr "Включить Gitpod"
msgid "Enable Gitpod?"
msgstr "Включить Gitpod?"
-msgid "Enable Incident Management inbound alert limit"
-msgstr "Включить ограничение на количеÑтво входÑщих оповещений в Управлении инцидентами"
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12612,6 +12708,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12651,6 +12750,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -13005,6 +13107,9 @@ msgstr "Развертывание"
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -13017,6 +13122,9 @@ msgstr "ОкружениÑ"
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr "ÐžÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ - Ñто меÑта где код развёртываетÑÑ, например теÑтовое окружение или продакшн."
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -13092,6 +13200,9 @@ msgstr "ОÑтановить окружение"
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr "Произошла ошибка при извлечении журналов. ПожалуйÑта, попробуйте ещё раз."
@@ -13113,6 +13224,12 @@ msgstr "Обновлено"
msgid "Environments|You don't have any environments right now"
msgstr "У Ð²Ð°Ñ Ð½ÐµÑ‚ ни одного Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ Ð½Ð° данный момент"
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr "защищённое"
@@ -13449,6 +13566,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14826,6 +14946,9 @@ msgstr "ОтветвлениÑ"
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14913,6 +15036,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -15045,10 +15171,10 @@ msgstr "Фильтр по ÑоÑтоÑнию"
msgid "Geo|Geo Status"
msgstr "Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Geo"
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -15093,7 +15219,7 @@ msgstr "ПоÑледний раз проверено"
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -15114,9 +15240,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr "Ðе Ñинхронизировано"
@@ -15171,19 +15294,16 @@ msgstr "Убрать запиÑÑŒ"
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr "Удалить запиÑÑŒ базы данных отÑлеживаниÑ"
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -15228,7 +15348,7 @@ msgstr "Cверить вÑе"
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -15240,6 +15360,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr "СтатуÑ"
@@ -15264,11 +15387,11 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
-msgstr "Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð±Ð°Ð·Ð° данных отÑтает от оÑновного узла на %{db_lag}."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
+msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
-msgstr "Узел в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð¾Ñ‚Ñтает от оÑновного узла на %{minutes_behind}."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
+msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
msgstr ""
@@ -15339,7 +15462,7 @@ msgstr "Ожидание планировщика"
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15384,6 +15507,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr "Git LFS не включен на Ñтом GitLab Ñервере, ÑвÑжитеÑÑŒ Ñ Ð²Ð°ÑˆÐ¸Ð¼ админиÑтратором."
@@ -15438,9 +15564,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15690,6 +15813,9 @@ msgstr "ДоÑтуп предоÑтавлен %{time_ago}"
msgid "Given epic is already related to this epic."
msgstr "Ð”Ð°Ð½Ð½Ð°Ñ Ñ†ÐµÐ»ÑŒ уже ÑвÑзана Ñ Ñтой целью."
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr "Глобальные ÑÐ¾Ñ‡ÐµÑ‚Ð°Ð½Ð¸Ñ ÐºÐ»Ð°Ð²Ð¸Ñˆ"
@@ -15771,7 +15897,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -16122,6 +16248,12 @@ msgstr "К Ñожалению, по вашему запроÑу цели не н
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -16134,6 +16266,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr "Чтобы раÑширить поиÑк, измените или удалите фильтры; Ñ %{startDate} до %{endDate}."
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -16167,7 +16302,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16657,7 +16792,7 @@ msgid "Health status cannot be edited because this issue is closed"
msgstr ""
msgid "HealthCheck|Access token is"
-msgstr "Ключ доÑтупа - "
+msgstr ""
msgid "HealthCheck|Healthy"
msgstr "Стабильно"
@@ -16695,12 +16830,12 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
-msgstr "Помогает уменьшить объем оповещений (напр., еÑли ÑоздаетÑÑ Ñлишком много обÑуждений)"
-
msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
+msgstr ""
+
msgid "Helps reduce request volume for protected paths"
msgstr ""
@@ -16835,6 +16970,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16854,7 +16992,7 @@ msgid "I accept the %{terms_link}"
msgstr ""
msgid "I accept the|Terms of Service and Privacy Policy"
-msgstr "уÑÐ»Ð¾Ð²Ð¸Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ политику конфиденциальноÑти"
+msgstr ""
msgid "I forgot my password"
msgstr "Я забыл пароль"
@@ -16973,7 +17111,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -17267,6 +17405,9 @@ msgstr "Ð’ процеÑÑе"
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -18026,6 +18167,12 @@ msgstr ""
msgid "Insert code"
msgstr "Ð’Ñтавить код"
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -18035,6 +18182,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -18126,6 +18279,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -18246,6 +18402,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18435,9 +18594,6 @@ msgstr "ПриглаÑить учаÑтников"
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18975,6 +19131,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19668,9 +19827,6 @@ msgstr "Метка"
msgid "Label actions dropdown"
msgstr "Выпадающее меню дейÑтвий над метками"
-msgid "Label lists show all issues with the selected label."
-msgstr "СпиÑки меток отображают вÑе обÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð¾Ð¹ меткой."
-
msgid "Label priority"
msgstr ""
@@ -19795,9 +19951,6 @@ msgstr "ПоÑледний ответ от"
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr "ПоÑледнее поÑещение"
@@ -19816,6 +19969,9 @@ msgstr ""
msgid "Last successful update"
msgstr "ПоÑледнее уÑпешное обновление"
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -20269,10 +20425,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20783,6 +20942,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20831,6 +20993,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr "МакÑимальный размер артефактов (Мбайт)"
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr "МакÑимальный размер Ð²Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ (Мбайт)"
@@ -20849,6 +21014,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr "МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð·Ð°Ð´ÐµÑ€Ð¶ÐºÐ° (в минутах)"
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20861,7 +21029,7 @@ msgstr "МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° полÑ"
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20876,9 +21044,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr "МакÑимальное Ð²Ñ€ÐµÐ¼Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð´Ð°Ð½Ð¸Ñ"
@@ -20912,6 +21086,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr "МакÑимальный размер отправки (Мбайт)"
@@ -20936,6 +21116,9 @@ msgstr "МакÑимальный размер отдельных вложениÐ
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr "МакÑимальное Ð²Ñ€ÐµÐ¼Ñ Ð¼ÐµÐ¶Ð´Ñƒ обновлениÑми, которое может иметь зеркало при Ñинхронизации по раÑпиÑанию."
@@ -20975,6 +21158,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -21143,6 +21329,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -21260,9 +21449,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -21275,9 +21461,6 @@ msgstr "Решить Ñту тему в новом обÑуждении"
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr "Задача Ð¾Ð±ÑŠÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ð¼ÐµÐ½ÐµÐ½Ð°: Ð´Ñ€ÑƒÐ³Ð°Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ð¾Ð±ÑŠÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ ÑƒÐ¶Ðµ выполнÑетÑÑ."
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21763,9 +21946,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -22040,7 +22220,7 @@ msgid "More information and share feedback"
msgstr ""
msgid "More information is available|here"
-msgstr "тут"
+msgstr ""
msgid "More information."
msgstr ""
@@ -22144,7 +22324,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22337,12 +22517,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22385,9 +22559,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22397,21 +22568,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22427,9 +22589,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22578,9 +22737,6 @@ msgstr "ÐÐ¾Ð²Ð°Ñ Ð²ÐµÑ‚ÐºÐ°"
msgid "New branch unavailable"
msgstr "ÐÐ¾Ð²Ð°Ñ Ð²ÐµÑ‚ÐºÐ° недоÑтупна"
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22764,6 +22920,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -23293,6 +23452,9 @@ msgstr "ÐоÑбрь"
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23422,7 +23584,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23720,7 +23882,7 @@ msgstr "Открыто"
msgid "Open Selection"
msgstr "Открыть выбранное"
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23912,6 +24074,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24375,7 +24540,7 @@ msgid "Password confirmation"
msgstr "Подтверждение паролÑ"
msgid "Password successfully changed"
-msgstr ""
+msgstr "Пароль уÑпешно изменён"
msgid "Password was successfully updated. Please sign in again."
msgstr ""
@@ -24402,13 +24567,13 @@ msgid "Paste epic link"
msgstr "Ð’Ñтавить ÑÑылку на цель"
msgid "Paste issue link"
-msgstr ""
+msgstr "Ð’Ñтавить ÑÑылку на обÑуждение"
msgid "Paste project path (i.e. gitlab-org/gitlab)"
msgstr ""
msgid "Paste your public SSH key, which is usually contained in the file '~/.ssh/id_ed25519.pub' or '~/.ssh/id_rsa.pub' and begins with 'ssh-ed25519' or 'ssh-rsa'. Do not paste your private SSH key, as that can compromise your identity."
-msgstr ""
+msgstr "Ð’Ñтавьте публичный SSH-ключ, который обычно ÑодержитÑÑ Ð² файле '~/.ssh/id_ed25519.pub' или '~/.ssh/id_rsa.pub' и начинаетÑÑ Ñ 'ssh-ed25519' или 'ssh-rsa'. Ðе вÑтавлÑйте закрытый SSH-ключ, так как Ñто может поÑтавить под угрозу ваши личные данные."
msgid "Patch to apply"
msgstr ""
@@ -24447,10 +24612,10 @@ msgid "Pending sync…"
msgstr ""
msgid "People without permission will never get a notification and won't be able to comment."
-msgstr ""
+msgstr "Люди без доÑтупа не получают уведомлений и не могут комментировать."
msgid "People without permission will never get a notification."
-msgstr ""
+msgstr "Люди без доÑтупа не получают уведомлений."
msgid "Percent rollout must be an integer number between 0 and 100"
msgstr ""
@@ -24492,22 +24657,22 @@ msgid "PerformanceBar|First Contentful Paint"
msgstr ""
msgid "PerformanceBar|Frontend resources"
-msgstr ""
+msgstr "РеÑурÑÑ‹ фронтенда"
msgid "PerformanceBar|Gitaly calls"
-msgstr ""
+msgstr "Вызовы Gitaly"
msgid "PerformanceBar|Memory"
msgstr ""
msgid "PerformanceBar|Redis calls"
-msgstr ""
+msgstr "Вызовы Redis"
msgid "PerformanceBar|Rugged calls"
msgstr ""
msgid "PerformanceBar|SQL queries"
-msgstr ""
+msgstr "SQL-запроÑÑ‹"
msgid "PerformanceBar|Sort by duration"
msgstr ""
@@ -24537,7 +24702,7 @@ msgid "Permissions"
msgstr "Права доÑтупа"
msgid "Permissions Help"
-msgstr ""
+msgstr "Справка по разрешениÑм"
msgid "Permissions, LFS, 2FA"
msgstr "РазрешениÑ, LFS, 2FA"
@@ -24570,7 +24735,7 @@ msgid "Phabricator Tasks"
msgstr ""
msgid "Pick a name"
-msgstr ""
+msgstr "Выберите имÑ"
msgid "Pin code"
msgstr "Пин-код"
@@ -24579,10 +24744,10 @@ msgid "Pipeline"
msgstr "Ð¡Ð±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ"
msgid "Pipeline %{label}"
-msgstr ""
+msgstr "Ð¡Ð±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ %{label}"
msgid "Pipeline %{label} for \"%{dataTitle}\""
-msgstr ""
+msgstr "Ð¡Ð±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ %{label} Ð´Ð»Ñ %{dataTitle}\""
msgid "Pipeline ID"
msgstr ""
@@ -24792,7 +24957,7 @@ msgid "Pipelines|CI/CD template to test and deploy your %{name} project."
msgstr ""
msgid "Pipelines|Child pipeline"
-msgstr ""
+msgstr "ДочернÑÑ ÑÐ±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ"
msgid "Pipelines|Clear runner caches"
msgstr ""
@@ -24813,7 +24978,7 @@ msgid "Pipelines|Edit"
msgstr ""
msgid "Pipelines|Editor"
-msgstr ""
+msgstr "Редактор"
msgid "Pipelines|Get familiar with GitLab CI/CD syntax by starting with a basic 3 stage CI/CD pipeline."
msgstr ""
@@ -24957,7 +25122,7 @@ msgid "Pipelines|invalid"
msgstr ""
msgid "Pipelines|parent"
-msgstr ""
+msgstr "родительÑкаÑ"
msgid "Pipeline|Actions"
msgstr ""
@@ -24987,13 +25152,13 @@ msgid "Pipeline|Created"
msgstr ""
msgid "Pipeline|Date"
-msgstr ""
+msgstr "Дата"
msgid "Pipeline|Detached merge request pipeline"
msgstr "Ð¡Ð±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ Ð¾Ñ‚ÑоединившегоÑÑ Ð·Ð°Ð¿Ñ€Ð¾Ñа на ÑлиÑние"
msgid "Pipeline|Duration"
-msgstr ""
+msgstr "ДлительноÑÑ‚ÑŒ"
msgid "Pipeline|Failed"
msgstr ""
@@ -25002,7 +25167,7 @@ msgid "Pipeline|In progress"
msgstr ""
msgid "Pipeline|Key"
-msgstr ""
+msgstr "Ключ"
msgid "Pipeline|Manual"
msgstr ""
@@ -25023,7 +25188,7 @@ msgid "Pipeline|Pending"
msgstr ""
msgid "Pipeline|Pipeline"
-msgstr ""
+msgstr "Ð¡Ð±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ"
msgid "Pipeline|Pipeline %{idStart}#%{idEnd} %{statusStart}%{statusEnd} for %{commitStart}%{commitEnd}"
msgstr ""
@@ -25049,6 +25214,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25143,13 +25353,13 @@ msgid "Please %{link_to_register} or %{link_to_sign_in} to comment"
msgstr "ПожалуйÑта, %{link_to_register} или %{link_to_sign_in} чтобы прокомментировать"
msgid "Please %{startTagRegister}register%{endRegisterTag} or %{startTagSignIn}sign in%{endSignInTag} to reply"
-msgstr ""
+msgstr "ПожалуйÑта, %{startTagRegister}зарегиÑтрируйтеÑÑŒ%{endRegisterTag} или %{startTagSignIn}войдите%{endSignInTag}, чтобы ответить"
msgid "Please accept the Terms of Service before continuing."
-msgstr ""
+msgstr "ПожалуйÑта, примите УÑÐ»Ð¾Ð²Ð¸Ñ Ð¿Ñ€ÐµÐ´Ð¾ÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ ÑƒÑлуг, прежде чем продолжить."
msgid "Please add a comment in the text area above"
-msgstr ""
+msgstr "ПожалуйÑта, добавьте комментарий в текÑтовой облаÑти выше"
msgid "Please check the configuration file for this chart"
msgstr "ПожалуйÑта, проверьте конфигурационный файл Ð´Ð»Ñ Ñтой диаграммы"
@@ -25158,19 +25368,19 @@ msgid "Please check the configuration file to ensure that a collection of charts
msgstr "ПожалуйÑта, проверьте файл конфигурации, чтобы убедитьÑÑ, что набор диаграмм объÑвлен."
msgid "Please check the configuration file to ensure that it is available and the YAML is valid"
-msgstr ""
+msgstr "ПожалуйÑта, проверьте файл конфигурации, чтобы убедитьÑÑ, что он доÑтупен, а YAML корректен"
msgid "Please check your email %{email} to confirm your account"
msgstr ""
msgid "Please check your email (%{email}) to verify that you own this address and unlock the power of CI/CD. Didn't receive it? %{resend_link}. Wrong email address? %{update_link}."
-msgstr ""
+msgstr "ПожалуйÑта, проверьте почту (%{email}), чтобы подтвердить, что вы владеете Ñтим адреÑом и открыть Ð´Ð»Ñ ÑÐµÐ±Ñ Ñилу CI/CD. Ðе получили пиÑьмо? %{resend_link}. Ðеверный Ð°Ð´Ñ€ÐµÑ Ð¿Ð¾Ñ‡Ñ‚Ñ‹? %{update_link}."
msgid "Please choose a file"
-msgstr ""
+msgstr "ПожалуйÑта, выберите файл"
msgid "Please complete your profile with email address"
-msgstr ""
+msgstr "ПожалуйÑта, заполните Ð°Ð´Ñ€ÐµÑ Ñлектронной почты в Ñвоем профиле"
msgid "Please confirm your email address"
msgstr ""
@@ -25194,13 +25404,13 @@ msgid "Please copy, download, or print your recovery codes before proceeding."
msgstr ""
msgid "Please create a password for your new account."
-msgstr ""
+msgstr "ПожалуйÑта, Ñоздайте пароль Ð´Ð»Ñ Ñвоей новой учётной запиÑи."
msgid "Please create a username with only alphanumeric characters."
-msgstr ""
+msgstr "ПожалуйÑта, Ñоздайте Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ буквы латинÑкого алфавита и цифры."
msgid "Please create an index before enabling indexing"
-msgstr ""
+msgstr "ПожалуйÑта, Ñоздайте Ð¸Ð½Ð´ÐµÐºÑ Ð¿ÐµÑ€ÐµÐ´ включением индекÑированиÑ"
msgid "Please delete your current license if you want to downgrade to the free plan."
msgstr ""
@@ -25209,10 +25419,10 @@ msgid "Please enable and migrate to hashed storage to avoid security issues and
msgstr ""
msgid "Please enter a non-negative number"
-msgstr ""
+msgstr "ПожалуйÑта, введите неотрицательное чиÑло"
msgid "Please enter a number greater than %{number} (from the project settings)"
-msgstr ""
+msgstr "ПожалуйÑта, введите чиÑло больше %{number} (из наÑтроек проекта)"
msgid "Please enter a valid URL format, ex: http://www.example.com/home"
msgstr ""
@@ -25230,7 +25440,7 @@ msgid "Please fill in a descriptive name for your group."
msgstr ""
msgid "Please fill out this field."
-msgstr ""
+msgstr "ПожалуйÑта, заполните Ñто поле."
msgid "Please follow the %{link_start}Let's Encrypt troubleshooting instructions%{link_end} to re-obtain your Let's Encrypt certificate."
msgstr ""
@@ -25263,7 +25473,7 @@ msgid "Please provide a valid YouTube URL or ID"
msgstr ""
msgid "Please provide a valid email address."
-msgstr ""
+msgstr "ПожалуйÑта, укажите корректный Ð°Ð´Ñ€ÐµÑ Ñлектронной почты."
msgid "Please provide attributes to update"
msgstr ""
@@ -25278,13 +25488,13 @@ msgid "Please refer to %{docs_url}"
msgstr ""
msgid "Please select"
-msgstr ""
+msgstr "ПожалуйÑта, выберите"
msgid "Please select a Jira project"
msgstr "ПожалуйÑта, выберите проект Jira"
msgid "Please select a country"
-msgstr ""
+msgstr "ПожалуйÑта, выберите Ñтрану"
msgid "Please select a file"
msgstr "ПожалуйÑта, выберите файл"
@@ -25293,7 +25503,7 @@ msgid "Please select a group."
msgstr "ПожалуйÑта, выберите группу."
msgid "Please select a valid target branch"
-msgstr ""
+msgstr "ПожалуйÑта, выберите дейÑтвительную целевую ветку"
msgid "Please select a valid target branch."
msgstr ""
@@ -25311,7 +25521,7 @@ msgid "Please select..."
msgstr ""
msgid "Please set a new password before proceeding."
-msgstr ""
+msgstr "ПожалуйÑта, уÑтановите новый пароль, прежде чем продолжить."
msgid "Please share your feedback about %{featureName} %{linkStart}in this issue%{linkEnd} to help us improve the experience."
msgstr ""
@@ -25332,13 +25542,13 @@ msgid "Please type the following to confirm:"
msgstr ""
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
-msgstr ""
+msgstr "ПожалуйÑта, иÑпользуйте Ñту форму Ð´Ð»Ñ Ð¾Ð¿Ð¾Ð²ÐµÑ‰ÐµÐ½Ð¸Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñтраторов о пользователÑÑ…, Ñоздающих задачи и комментарии, Ñодержащие Ñпам или ведущих ÑÐµÐ±Ñ Ð½ÐµÐ°Ð´ÐµÐºÐ²Ð°Ñ‚Ð½Ð¾."
msgid "Please wait a moment, this page will automatically refresh when ready."
-msgstr ""
+msgstr "ПожалуйÑта, подождите, Ñта Ñтраница автоматичеÑки обновитÑÑ, когда вÑÑ‘ будет готово."
msgid "Please wait while we connect to your repository. Refresh at will."
-msgstr ""
+msgstr "ПожалуйÑта, подождите, пока мы не подключимÑÑ Ðº вашему репозиторию. Можете обновить Ñтраницу в любой момент."
msgid "Please wait while we import the repository for you. Refresh at will."
msgstr "ПожалуйÑта, подождите пока мы импортируем к ваш репозиторий. ОбновлÑйте Ñтраницу по желанию."
@@ -25490,15 +25700,12 @@ msgstr ""
msgid "Prev"
msgstr "Пред."
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
-msgstr ""
-
msgid "Prevent adding new members to project membership within this group"
msgstr "Запретить добавление новых учаÑтников в проектах Ñтой группы"
+msgid "Prevent editing approval rules in projects and merge requests."
+msgstr ""
+
msgid "Prevent environment from auto-stopping"
msgstr ""
@@ -25508,9 +25715,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25775,6 +25979,9 @@ msgstr "Ðе отображать информацию о перÑонально
msgid "Profiles|Edit Profile"
msgstr "Изменить профиль"
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25967,9 +26174,6 @@ msgstr "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ ÑƒÑпешно изменено"
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr "ИÑпользовать Ñмайлы в имени - веÑьма ÐºÑ€ÐµÐ°Ñ‚Ð¸Ð²Ð½Ð°Ñ Ð¼Ñ‹Ñль, но лучше попробуйте изменить ÑÑ‚Ð°Ñ‚ÑƒÑ Ð² профиле"
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr "Как у Ð²Ð°Ñ Ð´ÐµÐ»Ð°?"
@@ -27068,9 +27272,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -27122,6 +27323,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr "Узнать больше"
@@ -27161,9 +27365,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27636,7 +27837,7 @@ msgid "Raw blob requests"
msgstr ""
msgid "Re-authentication period expired or never requested. Please try again"
-msgstr ""
+msgstr "Период повторной аутентификации иÑтёк или никогда не запрашивалÑÑ. ПожалуйÑта, попробуйте ещё раз"
msgid "Re-authentication required"
msgstr ""
@@ -27665,6 +27866,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27734,6 +27941,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr "Уменьшить облаÑÑ‚ÑŒ видимоÑти проекта"
@@ -27849,6 +28059,9 @@ msgstr ""
msgid "Related merge requests"
msgstr "СвÑзанные запроÑÑ‹ на ÑлиÑние"
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr "ОтноÑитÑÑ Ðº"
@@ -28373,6 +28586,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28826,6 +29042,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -29097,6 +29316,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -29160,6 +29382,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29648,9 +29873,6 @@ msgstr[3] "Результат Wiki"
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29697,12 +29919,12 @@ msgid "Security navigation"
msgstr ""
msgid "Security report is out of date. Please update your branch with the latest changes from the target branch (%{targetBranchName})"
-msgstr ""
+msgstr "Отчет безопаÑноÑти уÑтарел. ПожалуйÑта, включите в Ñвою ветку поÑледние Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¸Ð· целевой ветки (%{targetBranchName})"
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr "Отчет о безопаÑноÑти уÑтарел. ЗапуÑтите %{newPipelineLinkStart}новую Ñборочную линию%{newPipelineLinkEnd} в целевой ветке (%{targetBranchName})"
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29738,7 +29960,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29852,55 +30074,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityPolicies|Environment(s)"
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29939,9 +30230,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -30053,9 +30341,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -30122,6 +30407,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30695,7 +30983,7 @@ msgstr "Задать итерацию %{iteration_reference}."
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30743,7 +31031,7 @@ msgstr "УÑтановить приоритет"
msgid "Set weight to %{weight}."
msgstr "УÑтановить приоритет на %{weight}."
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30944,9 +31232,6 @@ msgstr ""
msgid "Show latest version"
msgstr "Показать поÑледнюю верÑию"
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -31097,7 +31382,7 @@ msgid "Sign up"
msgstr "Войдите"
msgid "Sign up was successful! Please confirm your email to sign in."
-msgstr ""
+msgstr "РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð¿Ñ€Ð¾ÑˆÐ»Ð° уÑпешно! ПожалуйÑта, подтвердите Ñлектронную почту, чтобы войти."
msgid "Sign-in and Help page"
msgstr ""
@@ -31174,6 +31459,9 @@ msgstr ""
msgid "Size"
msgstr "Размер"
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr "Лимит размера на репозиторий (Мбайт)"
@@ -31283,13 +31571,13 @@ msgid "Some of the designs you tried uploading did not change:"
msgstr ""
msgid "Someone edited the issue at the same time you did. Please check out %{linkStart}the issue%{linkEnd} and make sure your changes will not unintentionally remove theirs."
-msgstr ""
+msgstr "Кто-то отредактировал обÑуждение одновременно Ñ Ð²Ð°Ð¼Ð¸. ПожалуйÑта, проверьте %{linkStart}обÑуждение%{linkEnd} и убедитеÑÑŒ, что внеÑённые Вами Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñлучайно не затёрли чужие."
msgid "Someone edited this %{issueType} at the same time you did. The description has been updated and you will need to make your changes again."
msgstr ""
msgid "Someone edited this merge request at the same time you did. Please refresh the page to see changes."
-msgstr ""
+msgstr "Кто-то отредактировал Ñтот Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° ÑлиÑние одновременно Ñ Ð²Ð°Ð¼Ð¸. ПожалуйÑта, обновите Ñтраницу, чтобы увидеть изменениÑ."
msgid "Someone edited this test case at the same time you did. The description has been updated and you will need to make your changes again."
msgstr ""
@@ -31307,7 +31595,7 @@ msgid "Something went wrong on our end."
msgstr "Что-то пошло не так Ñ Ð½Ð°ÑˆÐµÐ¹ Ñтороны."
msgid "Something went wrong on our end. Please try again!"
-msgstr ""
+msgstr "Что-то пошло не так на нашей Ñтороне. ПожалуйÑта, попробуйте ещё раз!"
msgid "Something went wrong on our end. Please try again."
msgstr "Что-то пошло не так на нашей Ñтороне. ПожалуйÑта, попробуйте ещё раз."
@@ -31343,7 +31631,7 @@ msgid "Something went wrong while creating a requirement."
msgstr "Что-то пошло не так при Ñоздании требованиÑ."
msgid "Something went wrong while deleting description changes. Please try again."
-msgstr ""
+msgstr "Что-то пошло не так при удалении изменений опиÑаниÑ. ПожалуйÑта, попробуйте ещё раз."
msgid "Something went wrong while deleting the source branch. Please try again."
msgstr "Что-то пошло не так при удалении иÑходной ветки. ПожалуйÑта, попробуйте еще раз."
@@ -31525,6 +31813,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr "Дата ÑозданиÑ"
@@ -33000,6 +33297,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -33051,12 +33351,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -33069,7 +33375,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -33300,7 +33606,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33520,6 +33826,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr "Лицензионный ключ недейÑтвителен. УдоÑтоверьтеÑÑŒ, что он Ñовпадает Ñ Ñ‚ÐµÐ¼, что вы получили от GitLab Inc."
@@ -33556,9 +33865,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr "Конфликты ÑлиÑÐ½Ð¸Ñ Ð´Ð»Ñ Ñтого запроÑа на ÑлиÑние не могут быть разрешены Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ GitLab. ПожалуйÑта, попробуйте разрешить их локально."
@@ -33712,6 +34018,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð´ÐµÐ¹ÑÑ‚Ð²Ð¸Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸Ñтечет через %{number_of_minutes} минут. Ð”Ð»Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ñ… репозиториев иÑпользуйте комбинацию clone/push."
@@ -33850,9 +34159,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33898,6 +34213,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -34078,9 +34396,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr "Произошла ошибка при получении данных аналитики потока значений типа %{requestTypeName}."
-
msgid "There was an error while fetching value stream analytics data."
msgstr "Произошла ошибка при получении данных аналитики потока ценноÑти."
@@ -34300,9 +34615,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr "Эта группа"
@@ -34375,6 +34687,9 @@ msgstr "Это ваша Ñ‚ÐµÐºÑƒÑ‰Ð°Ñ ÑеÑÑиÑ"
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35424,14 +35739,20 @@ msgstr "ПожалуйÑта, выберите новое проÑтранÑтв
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr "Проект Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ½ÐµÑти, потому что в его рееÑтре контейнеров объÑвлены теги"
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr "Проект Ñ Ñ‚Ð°ÐºÐ¸Ð¼ именем или путем в целевом проÑтранÑтве имен уже ÑущеÑтвует"
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr "Корневое проÑтранÑтво имён не может быть обновлено, пока проект Ñодержит NPM пакеты"
-msgid "TransferProject|Transfer failed, please contact an admin."
-msgstr "ÐŸÐµÑ€ÐµÐ½Ð¾Ñ Ð½Ðµ удалÑÑ, пожалуйÑта, ÑвÑжитеÑÑŒ Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñтратором."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
+msgstr ""
msgid "Tree view"
msgstr ""
@@ -35995,6 +36316,9 @@ msgstr ""
msgid "Until"
msgstr "До"
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -36214,9 +36538,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr "Пакеты"
@@ -36235,9 +36556,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr "Репозиторий"
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr "Хранилище"
@@ -36286,6 +36613,9 @@ msgstr "Квоты иÑпользованиÑ"
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr "ИÑпользование групповых реÑурÑов по проектам в группе %{strong_start}%{group_name}%{strong_end}"
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr "ИÑпользование реÑурÑов в ваших проектах"
@@ -36442,6 +36772,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36919,9 +37252,15 @@ msgstr "Медианное Ð²Ñ€ÐµÐ¼Ñ Ð¾Ñ‚ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¾Ð±ÑуждениÑ
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -37122,6 +37461,13 @@ msgstr ""
msgid "View project labels"
msgstr "ПроÑмотр меток проекта"
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "View replaced file @ "
msgstr "ПроÑмотр заменённого файла @ "
@@ -37380,9 +37726,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -37395,6 +37738,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37500,6 +37846,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37755,6 +38104,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37816,6 +38168,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -38374,6 +38729,9 @@ msgstr "Ð’Ñ‹ можете протеÑтировать Ñвой файл .gitlab
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -38389,6 +38747,9 @@ msgstr "Ð’Ñ‹ не можете выдать ÑÐµÐ±Ñ Ð·Ð° внутреннего
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr "Ð’Ñ‹ не можете вноÑить Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð²Ð¾ вторичный ÑкземплÑÑ€ GitLab Geo, доÑтупный только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ. ВмеÑто него, пожалуйÑта, иÑпользуйте %{link_to_primary_node}."
@@ -38533,7 +38894,7 @@ msgstr "Ð’Ñ‹ доÑтигли Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð² вашем проектÐ
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38959,7 +39320,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38989,6 +39350,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -39095,6 +39480,13 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "branch name"
msgstr "Ð¸Ð¼Ñ Ð²ÐµÑ‚Ð²Ð¸"
@@ -39218,10 +39610,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr "Ð’Ñе проекты"
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39582,6 +39974,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr "цель"
@@ -39771,9 +40166,6 @@ msgstr "не разрешено. Попробуйте ещё раз Ñ Ð´Ñ€ÑƒÐ³Ð
msgid "is not allowed. We do not currently support project-level iterations"
msgstr "невозможно. Ðа данный момент мы не поддерживаем итерации ÑƒÑ€Ð¾Ð²Ð½Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°"
-msgid "is not an email you own"
-msgstr "не Ñ Ñлектронной почты, которой вы владеете"
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39914,7 +40306,7 @@ msgid "mrWidgetNothingToMerge|Use merge requests to propose changes to your proj
msgstr ""
msgid "mrWidget| Please restore it or use a different %{missingBranchName} branch"
-msgstr " ПожалуйÑта, воÑÑтановите её или иÑпользуйте другую ветку %{missingBranchName}"
+msgstr ""
msgid "mrWidget|%{mergeError}."
msgstr ""
@@ -39991,8 +40383,12 @@ msgstr "Закрыт"
msgid "mrWidget|Closed by"
msgstr "закрыто"
-msgid "mrWidget|Closes"
-msgstr "Закрывает"
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -40027,8 +40423,12 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr "УпоминаниÑ"
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
msgid "mrWidget|Merge"
msgstr "Слить"
@@ -40075,6 +40475,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr "Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ"
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr "Открыть в Web IDE"
@@ -40138,9 +40541,6 @@ msgstr "Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð±ÑƒÐ´ÑƒÑ‚ Ñлиты в"
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr "СÑылка HEAD иÑходной ветви недавно изменилаÑÑŒ. ПожалуйÑта, обновите Ñтраницу и проÑмотрите Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿ÐµÑ€ÐµÐ´ ÑлиÑнием"
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -40180,9 +40580,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -40210,12 +40607,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/si_LK/gitlab.po b/locale/si_LK/gitlab.po
index 20a203da4b8..9e44c97db8c 100644
--- a/locale/si_LK/gitlab.po
+++ b/locale/si_LK/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: si-LK\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:19\n"
+"PO-Revision-Date: 2021-09-01 22:31\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/sk_SK/gitlab.po b/locale/sk_SK/gitlab.po
index bef2cf9e14c..5541412403e 100644
--- a/locale/sk_SK/gitlab.po
+++ b/locale/sk_SK/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: sk\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:34\n"
+"PO-Revision-Date: 2021-09-01 22:34\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -484,6 +484,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -661,6 +668,9 @@ msgstr[3] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -799,9 +809,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -811,6 +818,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -978,6 +988,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1452,7 +1465,7 @@ msgstr[2] ""
msgstr[3] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -1750,10 +1763,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1780,10 +1793,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2560,7 +2573,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2788,12 +2801,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2860,6 +2867,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2923,6 +2933,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2989,7 +3005,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3836,9 +3852,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3854,9 +3867,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3911,6 +3921,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4394,7 +4410,7 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4403,9 +4419,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4433,6 +4455,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4445,6 +4470,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4454,19 +4485,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4577,6 +4614,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4737,9 +4777,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4858,9 +4895,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4979,6 +5013,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -5156,6 +5196,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5348,9 +5391,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5637,9 +5677,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5652,12 +5689,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5723,9 +5766,6 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -6026,30 +6066,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6104,6 +6138,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6255,6 +6292,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6738,12 +6778,19 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6753,15 +6800,19 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6777,7 +6828,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7386,6 +7437,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7401,9 +7455,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -8085,7 +8136,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8569,9 +8620,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8710,9 +8758,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8725,6 +8770,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9451,7 +9499,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10692,6 +10740,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10704,6 +10755,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10716,12 +10770,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10741,6 +10801,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10873,9 +10936,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10945,6 +11005,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10993,9 +11056,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -11020,6 +11089,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -11038,6 +11110,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -11221,10 +11296,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11278,6 +11353,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11708,6 +11795,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11768,7 +11861,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -12279,6 +12372,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12354,6 +12450,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12561,9 +12660,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12612,6 +12708,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12651,6 +12750,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -13005,6 +13107,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -13017,6 +13122,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -13092,6 +13200,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -13113,6 +13224,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13449,6 +13566,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14826,6 +14946,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14913,6 +15036,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -15045,10 +15171,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -15093,7 +15219,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -15114,9 +15240,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -15171,19 +15294,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -15228,7 +15348,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -15240,6 +15360,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -15264,10 +15387,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15339,7 +15462,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15384,6 +15507,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15438,9 +15564,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15690,6 +15813,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15771,7 +15897,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -16122,6 +16248,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -16134,6 +16266,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -16167,7 +16302,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16695,10 +16830,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16835,6 +16970,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16973,7 +17111,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -17267,6 +17405,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -18026,6 +18167,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -18035,6 +18182,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -18126,6 +18279,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -18246,6 +18402,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18435,9 +18594,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18975,6 +19131,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19668,9 +19827,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19795,9 +19951,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19816,6 +19969,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -20269,10 +20425,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20783,6 +20942,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20831,6 +20993,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20849,6 +21014,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20861,7 +21029,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20876,9 +21044,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20912,6 +21086,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20936,6 +21116,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20975,6 +21158,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -21143,6 +21329,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -21260,9 +21449,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -21275,9 +21461,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21763,9 +21946,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -22144,7 +22324,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22337,12 +22517,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22385,9 +22559,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22397,21 +22568,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22427,9 +22589,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22578,9 +22737,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22764,6 +22920,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -23293,6 +23452,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23422,7 +23584,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23720,7 +23882,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23912,6 +24074,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -25049,6 +25214,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25490,13 +25700,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25508,9 +25715,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25775,6 +25979,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25967,9 +26174,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -27068,9 +27272,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -27122,6 +27323,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -27161,9 +27365,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27665,6 +27866,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27734,6 +27941,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27849,6 +28059,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28373,6 +28586,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28826,6 +29042,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -29097,6 +29316,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -29160,6 +29382,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29648,9 +29873,6 @@ msgstr[3] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29702,7 +29924,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29738,7 +29960,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29852,55 +30074,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29939,9 +30230,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -30053,9 +30341,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -30122,6 +30407,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30695,7 +30983,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30743,7 +31031,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30944,9 +31232,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -31174,6 +31459,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31525,6 +31813,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -33000,6 +33297,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -33051,12 +33351,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -33069,7 +33375,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -33300,7 +33606,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33520,6 +33826,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33556,9 +33865,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33712,6 +34018,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33850,9 +34159,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33898,6 +34213,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -34078,9 +34396,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -34300,9 +34615,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -34375,6 +34687,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35424,13 +35739,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35995,6 +36316,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -36214,9 +36538,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -36235,9 +36556,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -36286,6 +36613,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36442,6 +36772,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36919,9 +37252,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -37122,6 +37461,13 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -37380,9 +37726,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -37395,6 +37738,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37500,6 +37846,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37755,6 +38104,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37816,6 +38168,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -38374,6 +38729,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -38389,6 +38747,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38533,7 +38894,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38959,7 +39320,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38989,6 +39350,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -39095,6 +39480,13 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "branch name"
msgstr ""
@@ -39218,10 +39610,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39582,6 +39974,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39771,9 +40166,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39991,8 +40383,12 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -40027,8 +40423,12 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -40075,6 +40475,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -40138,9 +40541,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -40180,9 +40580,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -40210,12 +40607,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/sl_SI/gitlab.po b/locale/sl_SI/gitlab.po
index 76dd4be8270..1c0a3428157 100644
--- a/locale/sl_SI/gitlab.po
+++ b/locale/sl_SI/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: sl\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:34\n"
+"PO-Revision-Date: 2021-09-01 22:34\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -484,6 +484,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -661,6 +668,9 @@ msgstr[3] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -799,9 +809,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -811,6 +818,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -978,6 +988,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1452,7 +1465,7 @@ msgstr[2] ""
msgstr[3] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -1750,10 +1763,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1780,10 +1793,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2560,7 +2573,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2788,12 +2801,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2860,6 +2867,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2923,6 +2933,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2989,7 +3005,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3836,9 +3852,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3854,9 +3867,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3911,6 +3921,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4394,7 +4410,7 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4403,9 +4419,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4433,6 +4455,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4445,6 +4470,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4454,19 +4485,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4577,6 +4614,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4737,9 +4777,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4858,9 +4895,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4979,6 +5013,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -5156,6 +5196,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5348,9 +5391,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5637,9 +5677,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5652,12 +5689,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5723,9 +5766,6 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -6026,30 +6066,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6104,6 +6138,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6255,6 +6292,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6738,12 +6778,19 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6753,15 +6800,19 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6777,7 +6828,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7386,6 +7437,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7401,9 +7455,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -8085,7 +8136,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8569,9 +8620,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8710,9 +8758,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8725,6 +8770,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9451,7 +9499,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10692,6 +10740,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10704,6 +10755,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10716,12 +10770,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10741,6 +10801,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10873,9 +10936,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10945,6 +11005,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10993,9 +11056,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -11020,6 +11089,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -11038,6 +11110,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -11221,10 +11296,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11278,6 +11353,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11708,6 +11795,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11768,7 +11861,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -12279,6 +12372,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12354,6 +12450,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12561,9 +12660,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12612,6 +12708,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12651,6 +12750,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -13005,6 +13107,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -13017,6 +13122,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -13092,6 +13200,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -13113,6 +13224,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13449,6 +13566,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14826,6 +14946,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14913,6 +15036,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -15045,10 +15171,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -15093,7 +15219,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -15114,9 +15240,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -15171,19 +15294,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -15228,7 +15348,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -15240,6 +15360,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -15264,10 +15387,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15339,7 +15462,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15384,6 +15507,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15438,9 +15564,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15690,6 +15813,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15771,7 +15897,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -16122,6 +16248,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -16134,6 +16266,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -16167,7 +16302,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16695,10 +16830,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16835,6 +16970,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16973,7 +17111,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -17267,6 +17405,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -18026,6 +18167,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -18035,6 +18182,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -18126,6 +18279,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -18246,6 +18402,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18435,9 +18594,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18975,6 +19131,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19668,9 +19827,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19795,9 +19951,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19816,6 +19969,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -20269,10 +20425,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20783,6 +20942,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20831,6 +20993,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20849,6 +21014,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20861,7 +21029,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20876,9 +21044,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20912,6 +21086,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20936,6 +21116,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20975,6 +21158,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -21143,6 +21329,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -21260,9 +21449,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -21275,9 +21461,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21763,9 +21946,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -22144,7 +22324,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22337,12 +22517,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22385,9 +22559,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22397,21 +22568,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22427,9 +22589,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22578,9 +22737,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22764,6 +22920,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -23293,6 +23452,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23422,7 +23584,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23720,7 +23882,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23912,6 +24074,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -25049,6 +25214,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25490,13 +25700,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25508,9 +25715,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25775,6 +25979,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25967,9 +26174,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -27068,9 +27272,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -27122,6 +27323,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -27161,9 +27365,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27665,6 +27866,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27734,6 +27941,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27849,6 +28059,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28373,6 +28586,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28826,6 +29042,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -29097,6 +29316,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -29160,6 +29382,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29648,9 +29873,6 @@ msgstr[3] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29702,7 +29924,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29738,7 +29960,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29852,55 +30074,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29939,9 +30230,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -30053,9 +30341,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -30122,6 +30407,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30695,7 +30983,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30743,7 +31031,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30944,9 +31232,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -31174,6 +31459,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31525,6 +31813,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -33000,6 +33297,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -33051,12 +33351,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -33069,7 +33375,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -33300,7 +33606,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33520,6 +33826,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33556,9 +33865,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33712,6 +34018,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33850,9 +34159,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33898,6 +34213,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -34078,9 +34396,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -34300,9 +34615,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -34375,6 +34687,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35424,13 +35739,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35995,6 +36316,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -36214,9 +36538,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -36235,9 +36556,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -36286,6 +36613,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36442,6 +36772,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36919,9 +37252,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -37122,6 +37461,13 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -37380,9 +37726,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -37395,6 +37738,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37500,6 +37846,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37755,6 +38104,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37816,6 +38168,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -38374,6 +38729,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -38389,6 +38747,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38533,7 +38894,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38959,7 +39320,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38989,6 +39350,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -39095,6 +39480,13 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "branch name"
msgstr ""
@@ -39218,10 +39610,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39582,6 +39974,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39771,9 +40166,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39991,8 +40383,12 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -40027,8 +40423,12 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -40075,6 +40475,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -40138,9 +40541,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -40180,9 +40580,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -40210,12 +40607,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/sq_AL/gitlab.po b/locale/sq_AL/gitlab.po
index 4e34a6a8be5..996c6d40828 100644
--- a/locale/sq_AL/gitlab.po
+++ b/locale/sq_AL/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: sq\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:34\n"
+"PO-Revision-Date: 2021-09-01 22:34\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/sr_CS/gitlab.po b/locale/sr_CS/gitlab.po
index 9ec89204932..64def04007f 100644
--- a/locale/sr_CS/gitlab.po
+++ b/locale/sr_CS/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: sr-CS\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:21\n"
+"PO-Revision-Date: 2021-09-01 22:32\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -427,6 +427,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -589,6 +595,9 @@ msgstr[2] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -727,9 +736,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -739,6 +745,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -904,6 +913,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1352,7 +1364,7 @@ msgstr[1] ""
msgstr[2] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -1639,10 +1651,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1669,10 +1681,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2449,7 +2461,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2677,12 +2689,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2749,6 +2755,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2812,6 +2821,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2878,7 +2893,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3724,9 +3739,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3742,9 +3754,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3799,6 +3808,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4276,7 +4291,7 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4285,9 +4300,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4315,6 +4336,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4327,6 +4351,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4336,19 +4366,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4459,6 +4495,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4618,9 +4657,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4738,9 +4774,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4858,6 +4891,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -5035,6 +5074,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5227,9 +5269,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5515,9 +5554,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5530,12 +5566,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5599,9 +5641,6 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5902,30 +5941,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5980,6 +6013,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6130,6 +6166,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6613,12 +6652,18 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6628,15 +6673,18 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6652,7 +6700,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7261,6 +7309,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7276,9 +7327,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7960,7 +8008,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8443,9 +8491,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8584,9 +8629,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8599,6 +8641,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9322,7 +9367,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10561,6 +10606,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10573,6 +10621,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10585,12 +10636,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10609,6 +10666,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10741,9 +10801,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10813,6 +10870,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10861,9 +10921,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10888,6 +10954,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10906,6 +10975,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -11086,10 +11158,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11140,6 +11212,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11569,6 +11653,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11629,7 +11719,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -12139,6 +12229,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12214,6 +12307,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12421,9 +12517,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12472,6 +12565,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12511,6 +12607,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12865,6 +12964,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12877,6 +12979,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12952,6 +13057,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12973,6 +13081,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13309,6 +13423,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14683,6 +14800,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14770,6 +14890,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14902,10 +15025,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14950,7 +15073,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14971,9 +15094,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -15028,19 +15148,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -15085,7 +15202,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -15097,6 +15214,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -15121,10 +15241,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15196,7 +15316,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15241,6 +15361,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15295,9 +15418,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15547,6 +15667,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15628,7 +15751,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15979,6 +16102,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15991,6 +16120,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -16024,7 +16156,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16552,10 +16684,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16690,6 +16822,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16828,7 +16963,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -17119,6 +17254,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17878,6 +18016,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17887,6 +18031,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17977,6 +18127,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -18097,6 +18250,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18286,9 +18442,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18826,6 +18979,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19519,9 +19675,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19645,9 +19798,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19666,6 +19816,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -20113,10 +20266,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20626,6 +20782,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20674,6 +20833,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20692,6 +20854,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20704,7 +20869,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20719,9 +20884,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20755,6 +20926,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20779,6 +20956,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20818,6 +20998,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20986,6 +21169,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -21103,9 +21289,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -21118,9 +21301,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21604,9 +21784,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21985,7 +22162,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22177,12 +22354,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22225,9 +22396,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22237,21 +22405,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22267,9 +22426,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22417,9 +22573,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22603,6 +22756,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -23128,6 +23284,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23257,7 +23416,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23554,7 +23713,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23746,6 +23905,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24883,6 +25045,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25324,13 +25531,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25342,9 +25546,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25609,6 +25810,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25801,9 +26005,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26902,9 +27103,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26956,6 +27154,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26995,9 +27196,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27499,6 +27697,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27568,6 +27772,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27682,6 +27889,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28201,6 +28411,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28651,6 +28864,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28921,6 +29137,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28984,6 +29203,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29461,9 +29683,6 @@ msgstr[2] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29515,7 +29734,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29551,7 +29770,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29665,55 +29884,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29752,9 +30040,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29866,9 +30151,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29935,6 +30217,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30508,7 +30793,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30556,7 +30841,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30757,9 +31042,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30985,6 +31267,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31336,6 +31621,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32809,6 +33103,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32860,12 +33157,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32878,7 +33181,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -33106,7 +33409,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33325,6 +33628,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33361,9 +33667,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33517,6 +33820,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33655,9 +33961,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33703,6 +34015,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33883,9 +34198,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -34105,9 +34417,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -34180,6 +34489,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35227,13 +35539,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35797,6 +36115,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -36016,9 +36337,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -36037,9 +36355,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -36088,6 +36412,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36244,6 +36571,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36721,9 +37051,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36922,6 +37258,12 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -37180,9 +37522,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -37195,6 +37534,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37300,6 +37642,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37555,6 +37900,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37615,6 +37963,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -38173,6 +38524,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -38188,6 +38542,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38332,7 +38689,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38758,7 +39115,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38788,6 +39145,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38893,6 +39274,12 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "branch name"
msgstr ""
@@ -39016,10 +39403,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39376,6 +39763,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39562,9 +39952,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39781,8 +40168,11 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39817,8 +40207,11 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39865,6 +40258,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39928,9 +40324,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39970,9 +40363,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -40000,12 +40390,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/sr_SP/gitlab.po b/locale/sr_SP/gitlab.po
index e5195b4ae11..677bd00bc92 100644
--- a/locale/sr_SP/gitlab.po
+++ b/locale/sr_SP/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: sr\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:35\n"
+"PO-Revision-Date: 2021-09-01 22:34\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -427,6 +427,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -589,6 +595,9 @@ msgstr[2] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -727,9 +736,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -739,6 +745,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -904,6 +913,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1352,7 +1364,7 @@ msgstr[1] ""
msgstr[2] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -1639,10 +1651,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1669,10 +1681,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2449,7 +2461,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2677,12 +2689,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2749,6 +2755,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2812,6 +2821,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2878,7 +2893,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3724,9 +3739,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3742,9 +3754,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3799,6 +3808,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4276,7 +4291,7 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4285,9 +4300,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4315,6 +4336,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4327,6 +4351,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4336,19 +4366,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4459,6 +4495,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4618,9 +4657,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4738,9 +4774,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4858,6 +4891,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -5035,6 +5074,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5227,9 +5269,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5515,9 +5554,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5530,12 +5566,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5599,9 +5641,6 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5902,30 +5941,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5980,6 +6013,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6130,6 +6166,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6613,12 +6652,18 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6628,15 +6673,18 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6652,7 +6700,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7261,6 +7309,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7276,9 +7327,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7960,7 +8008,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8443,9 +8491,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8584,9 +8629,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8599,6 +8641,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9322,7 +9367,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10561,6 +10606,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10573,6 +10621,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10585,12 +10636,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10609,6 +10666,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10741,9 +10801,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10813,6 +10870,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10861,9 +10921,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10888,6 +10954,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10906,6 +10975,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -11086,10 +11158,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11140,6 +11212,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11569,6 +11653,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11629,7 +11719,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -12139,6 +12229,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12214,6 +12307,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12421,9 +12517,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12472,6 +12565,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12511,6 +12607,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12865,6 +12964,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12877,6 +12979,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12952,6 +13057,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12973,6 +13081,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13309,6 +13423,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14683,6 +14800,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14770,6 +14890,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14902,10 +15025,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14950,7 +15073,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14971,9 +15094,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -15028,19 +15148,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -15085,7 +15202,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -15097,6 +15214,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -15121,10 +15241,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15196,7 +15316,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15241,6 +15361,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15295,9 +15418,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15547,6 +15667,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15628,7 +15751,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15979,6 +16102,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15991,6 +16120,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -16024,7 +16156,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16552,10 +16684,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16690,6 +16822,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16828,7 +16963,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -17119,6 +17254,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17878,6 +18016,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17887,6 +18031,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17977,6 +18127,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -18097,6 +18250,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18286,9 +18442,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18826,6 +18979,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19519,9 +19675,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19645,9 +19798,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19666,6 +19816,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -20113,10 +20266,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20626,6 +20782,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20674,6 +20833,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20692,6 +20854,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20704,7 +20869,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20719,9 +20884,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20755,6 +20926,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20779,6 +20956,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20818,6 +20998,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20986,6 +21169,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -21103,9 +21289,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -21118,9 +21301,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21604,9 +21784,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21985,7 +22162,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22177,12 +22354,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22225,9 +22396,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22237,21 +22405,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22267,9 +22426,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22417,9 +22573,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22603,6 +22756,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -23128,6 +23284,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23257,7 +23416,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23554,7 +23713,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23746,6 +23905,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24883,6 +25045,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25324,13 +25531,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25342,9 +25546,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25609,6 +25810,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25801,9 +26005,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26902,9 +27103,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26956,6 +27154,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26995,9 +27196,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27499,6 +27697,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27568,6 +27772,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27682,6 +27889,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28201,6 +28411,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28651,6 +28864,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28921,6 +29137,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28984,6 +29203,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29461,9 +29683,6 @@ msgstr[2] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29515,7 +29734,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29551,7 +29770,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29665,55 +29884,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29752,9 +30040,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29866,9 +30151,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29935,6 +30217,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30508,7 +30793,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30556,7 +30841,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30757,9 +31042,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30985,6 +31267,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31336,6 +31621,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32809,6 +33103,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32860,12 +33157,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32878,7 +33181,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -33106,7 +33409,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33325,6 +33628,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33361,9 +33667,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33517,6 +33820,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33655,9 +33961,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33703,6 +34015,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33883,9 +34198,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -34105,9 +34417,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -34180,6 +34489,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35227,13 +35539,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35797,6 +36115,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -36016,9 +36337,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -36037,9 +36355,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -36088,6 +36412,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36244,6 +36571,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36721,9 +37051,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36922,6 +37258,12 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -37180,9 +37522,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -37195,6 +37534,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37300,6 +37642,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37555,6 +37900,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37615,6 +37963,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -38173,6 +38524,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -38188,6 +38542,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38332,7 +38689,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38758,7 +39115,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38788,6 +39145,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38893,6 +39274,12 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "branch name"
msgstr ""
@@ -39016,10 +39403,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39376,6 +39763,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39562,9 +39952,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39781,8 +40168,11 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39817,8 +40207,11 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39865,6 +40258,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39928,9 +40324,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39970,9 +40363,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -40000,12 +40390,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/sv_SE/gitlab.po b/locale/sv_SE/gitlab.po
index ee6cc9c7352..1a297be986d 100644
--- a/locale/sv_SE/gitlab.po
+++ b/locale/sv_SE/gitlab.po
@@ -14,13 +14,13 @@ msgstr ""
"X-Crowdin-Language: sv-SE\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:35\n"
+"PO-Revision-Date: 2021-09-01 22:34\n"
msgid " %{name}, confirm your email address now! "
msgstr " %{name}, bekräfta din e-postadress nu! "
msgid " %{start} to %{end}"
-msgstr "%{start} till %{end}"
+msgstr ""
msgid " (from %{timeoutSource})"
msgstr " (från %{timeoutSource})"
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] "%{count} deltagare"
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr "%{count} relaterade %{pluralized_subject}: %{links}"
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
+msgstr ""
+
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityPolicies|Environment(s)"
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/sw_KE/gitlab.po b/locale/sw_KE/gitlab.po
index 7bcb2f80767..eed9747487e 100644
--- a/locale/sw_KE/gitlab.po
+++ b/locale/sw_KE/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: sw\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:20\n"
+"PO-Revision-Date: 2021-09-01 22:31\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/ta_IN/gitlab.po b/locale/ta_IN/gitlab.po
index ffca900ba72..b3ed544da02 100644
--- a/locale/ta_IN/gitlab.po
+++ b/locale/ta_IN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ta\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:14\n"
+"PO-Revision-Date: 2021-09-01 22:30\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/tr_TR/gitlab.po b/locale/tr_TR/gitlab.po
index eff30509754..35e0ffa24d3 100644
--- a/locale/tr_TR/gitlab.po
+++ b/locale/tr_TR/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: tr\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:30\n"
+"PO-Revision-Date: 2021-09-01 22:33\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] "%{count} katılımcı"
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr "%{labelStart}Yöntem:%{labelEnd} %{method}"
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr "%{labelStart}İsim alanları:%{labelEnd} %{namespace}"
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr "%{labelStart}Tarayıcı:%{labelEnd}%{scanner}"
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr "%{labelStart}Önem derecesi:%{labelEnd} %{severity}"
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr "%{seconds}sn"
@@ -1252,7 +1263,7 @@ msgstr[0] "1 sorun seçildi"
msgstr[1] "%d sorun seçildi"
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] "1 birleştirme isteği seçildi"
msgstr[1] "%d birleştirme isteği seçildi"
@@ -1412,7 +1423,7 @@ msgid "A deleted user"
msgstr "Silinmiş kullanıcı"
msgid "A description is required"
-msgstr ""
+msgstr "Bir açıklama gerekli"
msgid "A different reason"
msgstr ""
@@ -1508,7 +1519,7 @@ msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt c
msgstr ""
msgid "API"
-msgstr ""
+msgstr "API"
msgid "API Fuzzing"
msgstr ""
@@ -1528,11 +1539,11 @@ msgstr "API anahtarı"
msgid "API?"
msgstr "API?"
-msgid "APIFuzzing|$VariableWithPassword"
-msgstr "$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
+msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
-msgstr "$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
+msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
msgstr "API Fuzzing Yapılandırması"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -1694,19 +1705,19 @@ msgid "Access denied! Please verify you can add deploy keys to this repository."
msgstr "Erişim reddedildi! Lütfen bu depoya dağıtım anahtarlarını ekleyebileceğinizi doğrulayın."
msgid "Access denied: %{error}"
-msgstr ""
+msgstr "EriÅŸim reddedildi: %{error}"
msgid "Access expiration date"
msgstr "EriÅŸim bitiÅŸ tarihi"
msgid "Access expires"
-msgstr ""
+msgstr "EriÅŸim sona eriyor"
msgid "Access forbidden. Check your access level."
msgstr "Erişim yasaklandı. Erişim seviyenizi kontrol edin."
msgid "Access granted"
-msgstr ""
+msgstr "Erişim onaylandı"
msgid "Access requests"
msgstr "EriÅŸim istekleri"
@@ -1808,7 +1819,7 @@ msgid "Account and limit"
msgstr "Hesap ve sınırı"
msgid "Account:"
-msgstr ""
+msgstr "Hesap:"
msgid "Account: %{account}"
msgstr "Hesap: %{account}"
@@ -1940,7 +1951,7 @@ msgid "Add a task list"
msgstr "Görev listesi ekle"
msgid "Add a to do"
-msgstr ""
+msgstr "Bir yapılacak ekle"
msgid "Add an SSH key"
msgstr "Bir SSH anahtarı ekle"
@@ -1964,7 +1975,7 @@ msgid "Add bold text"
msgstr "Kalın metin ekle"
msgid "Add broadcast message"
-msgstr ""
+msgstr "Yayın mesajı ekle"
msgid "Add child epic to an epic"
msgstr "Bir epiÄŸe alt epik ekle"
@@ -2036,10 +2047,10 @@ msgid "Add previously merged commits"
msgstr ""
msgid "Add project"
-msgstr ""
+msgstr "Proje ekle"
msgid "Add projects"
-msgstr ""
+msgstr "Projeler ekle"
msgid "Add reaction"
msgstr "Tepki ekle"
@@ -2063,7 +2074,7 @@ msgid "Add to Slack"
msgstr "Slack'e ekle"
msgid "Add to board"
-msgstr ""
+msgstr "Panoya ekle"
msgid "Add to epic"
msgstr "EpiÄŸe ekle"
@@ -2081,7 +2092,7 @@ msgid "Add to tree"
msgstr "AÄŸaca ekle"
msgid "Add trigger"
-msgstr ""
+msgstr "Tetikleyici ekle"
msgid "Add user(s) to the group:"
msgstr "Gruba kullanıcı(lar) ekleyin:"
@@ -2132,7 +2143,7 @@ msgid "Added %{label_references} %{label_text}."
msgstr "%{label_references} %{label_text} eklendi."
msgid "Added a to do."
-msgstr ""
+msgstr "Yapılacaklara ekle"
msgid "Added an issue to an epic."
msgstr "EpiÄŸe bir sorun eklendi."
@@ -2156,7 +2167,7 @@ msgid "Additional minutes"
msgstr "Ek dakika"
msgid "Additional minutes:"
-msgstr ""
+msgstr "Ek dakikalar:"
msgid "Additional text"
msgstr "Ek metin"
@@ -2171,7 +2182,7 @@ msgid "Additional text to show on the sign-in page"
msgstr ""
msgid "Address"
-msgstr ""
+msgstr "Adres"
msgid "Adds"
msgstr "Ekler"
@@ -2201,13 +2212,13 @@ msgid "Adjust your filters/search criteria above. If you believe this may be an
msgstr ""
msgid "Admin"
-msgstr ""
+msgstr "Yönetici"
msgid "Admin Area"
msgstr "Yönetici alanı"
msgid "Admin Mode"
-msgstr ""
+msgstr "Yönetici Modu"
msgid "Admin Note"
msgstr "Yönetici Mesajı"
@@ -2231,7 +2242,7 @@ msgid "Admin mode enabled"
msgstr "Yönetici modu etkinleştirildi"
msgid "Admin navigation"
-msgstr ""
+msgstr "Yönetici navigasyonu"
msgid "Admin notes"
msgstr "Yönetici notları"
@@ -2255,16 +2266,16 @@ msgid "AdminArea|Bots"
msgstr "Botlar"
msgid "AdminArea|Components"
-msgstr ""
+msgstr "BileÅŸenler"
msgid "AdminArea|Developer"
msgstr "GeliÅŸtirici"
msgid "AdminArea|Features"
-msgstr ""
+msgstr "Özellikler"
msgid "AdminArea|Groups"
-msgstr ""
+msgstr "Gruplar"
msgid "AdminArea|Guest"
msgstr "Misafir"
@@ -2273,31 +2284,31 @@ msgid "AdminArea|Included Free in license"
msgstr "Lisansa ücretsiz dahildir"
msgid "AdminArea|Latest groups"
-msgstr ""
+msgstr "Son gruplar"
msgid "AdminArea|Latest projects"
-msgstr ""
+msgstr "Son projeler"
msgid "AdminArea|Latest users"
-msgstr ""
+msgstr "Son üyeler"
msgid "AdminArea|Maintainer"
msgstr "Sorumlu"
msgid "AdminArea|New group"
-msgstr ""
+msgstr "Yeni grup"
msgid "AdminArea|New project"
-msgstr ""
+msgstr "Yeni proje"
msgid "AdminArea|New user"
-msgstr ""
+msgstr "Yeni kullanıcı"
msgid "AdminArea|Owner"
msgstr "Sahibi"
msgid "AdminArea|Projects"
-msgstr ""
+msgstr "Projeler"
msgid "AdminArea|Reporter"
msgstr "Raporlayıcı"
@@ -2338,8 +2349,8 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
-msgstr "Bütün işleri durdurmak üzeresiniz. Bu işlem, çalışan tüm mevcut işleri durduracaktır."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
+msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "İstatistikler yüklenirken hata oluştu. Lütfen tekrar deneyin"
@@ -2471,13 +2482,13 @@ msgid "AdminStatistics|Snippets"
msgstr "Parçacıklar"
msgid "AdminUsers|(Admin)"
-msgstr ""
+msgstr "(Yönetici)"
msgid "AdminUsers|(Banned)"
msgstr ""
msgid "AdminUsers|(Blocked)"
-msgstr ""
+msgstr "(Engellendi)"
msgid "AdminUsers|(Deactivated)"
msgstr ""
@@ -2486,7 +2497,7 @@ msgid "AdminUsers|(Internal)"
msgstr ""
msgid "AdminUsers|(Pending approval)"
-msgstr ""
+msgstr "(Onay bekliyor)"
msgid "AdminUsers|2FA Disabled"
msgstr "2FA Devre dışı"
@@ -2528,7 +2539,7 @@ msgid "AdminUsers|Admins"
msgstr "Yöneticiler"
msgid "AdminUsers|Approve"
-msgstr ""
+msgstr "Onayla"
msgid "AdminUsers|Approve user %{username}?"
msgstr ""
@@ -2540,13 +2551,13 @@ msgid "AdminUsers|Automatically marked as default internal user"
msgstr ""
msgid "AdminUsers|Ban user"
-msgstr ""
+msgstr "Kullanıcıyı yasakla"
msgid "AdminUsers|Ban user %{username}?"
-msgstr ""
+msgstr "%{username} kullanıcısı yasaklansın mı?"
msgid "AdminUsers|Banned"
-msgstr ""
+msgstr "Yasaklandı"
msgid "AdminUsers|Be added to groups and projects"
msgstr ""
@@ -2566,26 +2577,20 @@ msgstr "Engellendi"
msgid "AdminUsers|Blocking user has the following effects:"
msgstr "Kullanıcıyı engelleme aşağıdaki etkilere sahiptir:"
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
-msgstr ""
+msgstr "Oturum açamaz veya örnek bilgilerine erişemez"
msgid "AdminUsers|Cannot unblock LDAP blocked users"
msgstr "LDAP engelli kullanıcıların engellemesini kaldıramıyor"
msgid "AdminUsers|Cohorts"
-msgstr ""
+msgstr "Topluluklar"
msgid "AdminUsers|Confirm user"
-msgstr ""
+msgstr "Kullanıcıyı onayla"
msgid "AdminUsers|Confirm user %{username}?"
-msgstr ""
+msgstr "%{username} kullanıcısı onaylansın mı?"
msgid "AdminUsers|Could not load user group counts. Please refresh the page to try again."
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr "Koltuğu kullanıyor"
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr "Bu sensin!"
@@ -2660,7 +2668,7 @@ msgid "AdminUsers|Owned groups will be left"
msgstr "Sahip olunan gruplar bırakılacak"
msgid "AdminUsers|Pending approval"
-msgstr ""
+msgstr "Onay bekliyor"
msgid "AdminUsers|Personal projects will be left"
msgstr "Kişisel projeler bırakılacak"
@@ -2701,6 +2709,12 @@ msgstr "Kullanıcılara e-posta gönder"
msgid "AdminUsers|Sort by"
msgstr "Sıralama"
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr "Kullanıcının oturumu kapatılacak"
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr "Terraform raporu alınırken bir hata oluştu."
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr "Pano listeleri alınırken bir hata oluştu. Lütfen tekrar deneyin."
-
msgid "An error occurred while fetching the job log."
msgstr "İş kayıtları alınırken bir hata oluştu."
@@ -3630,9 +3641,6 @@ msgstr "İşler alınırken bir hata oluştu."
msgid "An error occurred while fetching the latest pipeline."
msgstr "En son iş hattı getirilirken bir hata oluştu."
-msgid "An error occurred while fetching the pipeline."
-msgstr "İş hattı alınırken bir hata oluştu."
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr "Sürümler alınırken bir hata oluştu. Lütfen tekrar deneyin."
@@ -3687,6 +3695,12 @@ msgstr "Sorunlar yüklenirken bir sorun oluştu"
msgid "An error occurred while loading merge requests."
msgstr "Birleştirme istekleri yüklenirken bir hata oluştu."
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] "%{membersCount} tarafından %{count} onay gerekli"
msgstr[1] "%{membersCount} tarafından %{count} onay gerekli"
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr "Kural adı"
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr "Hedef dal"
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr "Bu projeyi arşivden kaldırmak istediğinizden emin misiniz?"
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr "Bu yorumu oluşturmayı iptal etmek istediğinizden emin misiniz?"
@@ -4499,9 +4537,6 @@ msgstr "Artifact başarıyla silindi."
msgid "Artifacts"
msgstr "Yapılar"
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4605,7 +4640,7 @@ msgid "Assigned to me"
msgstr "Bana atanan"
msgid "Assigned to you"
-msgstr "Size atandı"
+msgstr "Size atanan"
msgid "Assignee"
msgid_plural "%d Assignees"
@@ -4618,9 +4653,6 @@ msgstr "Atananın izni yok"
msgid "Assignee lists not available with your current license"
msgstr "Atanan listeleri mevcut lisansınızla birlikte kullanılamıyor"
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr "Atanan listeleri, seçilen kullanıcıya atanan tüm sorunları gösterir."
-
msgid "Assignee(s)"
msgstr "Vekil(ler)"
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr "Let's Encrypt kullanarak otomatik sertifika yönetimi"
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr "Seçili işlem ile başla"
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr "Panolar"
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr "Daralt"
@@ -5778,30 +5816,24 @@ msgstr "Kaynak gruba göre filtrele"
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr "CI Dakikası Satın Al"
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr "Daha fazla İş Hattı dakikası satın al"
@@ -6005,6 +6040,9 @@ msgstr "KATKI"
msgid "CPU"
msgstr "CPU"
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr "Kullanıcı adının geçerliliği denetleniyor..."
msgid "Checkout"
msgstr "Ödeme"
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr "%{selectedPlanText} planı"
msgid "Checkout|%{startDate} - %{endDate}"
msgstr "%{startDate} - %{endDate}"
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr "Fatura adresi"
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -6810,7 +6855,7 @@ msgid "CiStatusText|pending"
msgstr "bekliyor"
msgid "CiStatusText|preparing"
-msgstr "CiStatusText|hazırlanıyor"
+msgstr ""
msgid "CiStatusText|skipped"
msgstr "atlandı"
@@ -6855,7 +6900,7 @@ msgid "CiVariables|Specify variable values to be used in this run. The values sp
msgstr ""
msgid "CiVariables|State"
-msgstr "CiVariables|Durum"
+msgstr ""
msgid "CiVariables|Type"
msgstr "Tür"
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -9479,7 +9521,7 @@ msgid "Create new label"
msgstr "Yeni etiket oluÅŸtur"
msgid "Create new project"
-msgstr ""
+msgstr "Yeni proje oluÅŸtur"
msgid "Create new..."
msgstr "Yeni oluÅŸtur..."
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr "Yorumu sil"
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr "Etki alanını sil"
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr "Kaynak dalı sil"
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr "Bu eki sil"
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr "Etiketi Düzenle"
@@ -12074,6 +12164,9 @@ msgstr "Genel dağıtım anahtarını düzenle"
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr "Entegrasyonu etkinleÅŸtir"
@@ -12725,6 +12821,9 @@ msgstr "Dağıtım"
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr "Ortamlar"
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr "Ortamı durdur"
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr "Güncellendi"
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr "Hata: Dağıtım dondurma oluşturulamıyor"
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -13293,7 +13407,7 @@ msgid "EscalationPolicies|Select schedule"
msgstr ""
msgid "EscalationPolicies|Set up escalation policies to define who is paged, and when, in the event the first users paged don't respond."
-msgstr ""
+msgstr "Sayfalanan ilk kullanıcıların yanıt vermemesi durumunda kimin ne zaman sayfalanacağını tanımlamak için yükseltme ilkeleri ayarlayın."
msgid "EscalationPolicies|THEN %{doAction} %{scheduleOrUser}"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr "Çatallar"
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr "Duruma göre filtrele"
msgid "Geo|Geo Status"
msgstr "Geo Durumu"
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14865,7 +14982,7 @@ msgid "Geo|Project (ID: %{project_id}) no longer exists on the primary. It is sa
msgstr ""
msgid "Geo|Projects in certain groups"
-msgstr "Geo|Belli gruplardaki projeler"
+msgstr ""
msgid "Geo|Projects in certain storage shards"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr "Durum"
@@ -14978,11 +15095,11 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
-msgstr "Düğüm şu anda %{minutes_behind} birincil düğümün gerisinde."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
+msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
msgstr ""
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr "GitLab içe aktarma"
@@ -15404,6 +15521,9 @@ msgstr "%{time_ago} eriÅŸim verildi"
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr "Genel Kısayollar"
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr "Üzgünüz, aramanızla eşleşen bir epik yok"
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr "Yol haritası, epiklerinizin bir zaman çizelgesi boyunca ilerlemesini gösterir"
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr "Aramanızı genişletmek için süzgeçleri değiştirin veya kaldırın; %{startDate} - %{endDate}."
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16170,10 +16299,10 @@ msgid "Groups (%{count})"
msgstr ""
msgid "Groups and projects"
-msgstr ""
+msgstr "Gruplar ve projeler"
msgid "Groups and subgroups"
-msgstr ""
+msgstr "Gruplar ve alt gruplar"
msgid "Groups to synchronize"
msgstr ""
@@ -16227,7 +16356,7 @@ msgid "GroupsNew|Create group"
msgstr "Grup oluÅŸtur"
msgid "GroupsNew|Create new group"
-msgstr ""
+msgstr "Yeni grup oluÅŸtur"
msgid "GroupsNew|Export groups with all their related data and move to a new GitLab instance."
msgstr ""
@@ -16272,7 +16401,7 @@ msgid "GroupsNew|To import a group, navigate to the group settings for the GitLa
msgstr ""
msgid "GroupsNew|Upload file"
-msgstr ""
+msgstr "Dosya yükle"
msgid "GroupsNew|e.g. h8d3f016698e..."
msgstr ""
@@ -16287,10 +16416,10 @@ msgid "GroupsTree|Failed to leave the group. Please make sure you are not the on
msgstr ""
msgid "GroupsTree|Leave this group"
-msgstr "GruplarAğacı|Bu gruptan ayrıl"
+msgstr ""
msgid "GroupsTree|Loading groups"
-msgstr "GruplarAğacı|Gruplar yükleniyor"
+msgstr ""
msgid "GroupsTree|No groups matched your search"
msgstr "Aramanızla eşleşen grup yok"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16564,7 +16696,7 @@ msgid "I accept the %{terms_link}"
msgstr ""
msgid "I accept the|Terms of Service and Privacy Policy"
-msgstr "Hizmet Şartları ve Gizlilik Politikasını"
+msgstr ""
msgid "I forgot my password"
msgstr "Åžifremi unuttum"
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr "Kod ekle"
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr "Öneri ekle"
@@ -17828,6 +17975,9 @@ msgstr "Tüm ayrıntılar"
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr "Standart"
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr "Ãœye davet et"
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr "Etiket"
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr "Etiket listeleri, seçilen etiket ile ilgili tüm sorunları gösterir."
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr "Son cevap:"
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr "Son başarılı güncelleme"
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19550,7 +19700,7 @@ msgid "LastPushEvent|You pushed to"
msgstr "Şuna yolladınız:"
msgid "LastPushEvent|at"
-msgstr " "
+msgstr ""
msgid "Latest changes"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr "En yüksek ek boyutu (MB)"
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr "Maksimum gecikme (dakika)"
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr "Maksimum içe aktarma boyutu (MB)"
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20800,7 +20980,7 @@ msgid "Memory Usage"
msgstr ""
msgid "Menu"
-msgstr ""
+msgstr "Menü"
msgid "Merge"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr "Taslak yorum kaydedilirken bir hata oluÅŸtu."
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr "Yorum kaydedilemedi"
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21722,7 +21896,7 @@ msgid "More information and share feedback"
msgstr ""
msgid "More information is available|here"
-msgstr "burada mevcuttur"
+msgstr ""
msgid "More information."
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr "Yeni dal"
msgid "New branch unavailable"
msgstr "Yeni dal kullanılamaz"
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr "Kasım"
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr "Açık"
msgid "Open Selection"
msgstr "Seçimi Aç"
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23461,7 +23617,7 @@ msgid "OperationsDashboard|Add projects"
msgstr ""
msgid "OperationsDashboard|More information"
-msgstr "OperationsDashboard|Daha fazla bilgi"
+msgstr ""
msgid "OperationsDashboard|Operations Dashboard"
msgstr ""
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr "Önceki"
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr "Etkinliklerle ile ilgili kişisel bilgileri profiliniz üstünde göster
msgid "Profiles|Edit Profile"
msgstr "Profili Düzenle"
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr "Kullanıcı adı başarıyla değiştirildi"
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr "İsimlerdeki ifadeleri kullanmak eğlenceli görünüyor. Ancak bunun yerine durum mesajı ayarlamayı deneyin"
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr "İki adımlı kimlik doğrulamanın etkinleştirildiğinden ve ayarların güncel olduğundan emin olmanızı öneririz."
-
msgid "Profiles|What's your status?"
msgstr "Durumunuz nedir?"
@@ -26491,7 +26689,7 @@ msgid "ProjectsDropdown|Sorry, no projects matched your search"
msgstr "Üzgünüz, aramanızla eşleşen hiçbir proje yok"
msgid "ProjectsDropdown|This feature requires browser localStorage support"
-msgstr "ProjectsDropdown|Bu özellik tarayıcıda yerel Depolama desteği gerektiriyor"
+msgstr ""
msgid "ProjectsNew|Allows you to immediately clone this project’s repository. Skip this if you plan to push up an existing repository."
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr "İlgili sorunlar hakkında daha fazla bilgi edinin"
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] "viki sonucu"
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr "OluÅŸturulma tarihi"
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr "Bu grup"
@@ -33985,6 +34291,9 @@ msgstr "Bu sizin mevcut oturumunuz"
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,14 +35339,20 @@ msgstr "Lütfen projeniz için yeni isim alanı seçin."
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
-msgstr "Aktarım başarısız oldu, lütfen bir yöneticiyle iletişim kurun."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
+msgstr ""
msgid "Tree view"
msgstr ""
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr "Paketler"
@@ -35839,9 +36154,15 @@ msgstr "Depolar"
msgid "UsageQuota|Repository"
msgstr "Depo"
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr "Parçacıklar"
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr "Depolama"
@@ -35890,6 +36211,9 @@ msgstr "Kullanım Kotaları"
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr "Grup kaynaklarının gruptaki projeler arasında %{strong_start}%{group_name}%{strong_end} kullanılması"
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr "Projelerinizdeki kaynakların kullanımı"
@@ -35933,7 +36257,7 @@ msgid "UsageTrends|Could not load the projects and groups chart. Please refresh
msgstr ""
msgid "UsageTrends|Groups"
-msgstr ""
+msgstr "Gruplar"
msgid "UsageTrends|Issues"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr "Proje etiketlerini görüntüle"
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr "Değiştirilen @ dosyayı görüntüle "
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr "İş ünvanınız nedir? (isteğe bağlı)"
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr "Yenilikler"
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr "Proje sınırınıza ulaştınız"
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38219,7 +38572,7 @@ msgid "You will need to update your local repositories to point to the new locat
msgstr ""
msgid "You will not get any notifications via email"
-msgstr "E-posta yoluyla herhangi bir bildirim almazsınız "
+msgstr ""
msgid "You will only receive notifications for the events you choose"
msgstr "Yalnızca seçtiğiniz etkinlikler için bildirim alacaksınız"
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr "dal adı"
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr "Tüm projeler"
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr "giriÅŸler boÅŸ olamaz"
msgid "entries cannot contain HTML tags"
msgstr "girişler HTML etiketleri içeremez"
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39283,7 +39668,7 @@ msgid "https://your-bitbucket-server"
msgstr "https://sizin-bitbucket-sunucunuz"
msgid "i18n|%{language} (%{percent_translated}%% translated)"
-msgstr "i18n|%{language} (%%%{percent_translated} çevrildi)"
+msgstr ""
msgid "image diff"
msgstr "resim deÄŸiÅŸikliÄŸi"
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr "Kapalı"
msgid "mrWidget|Closed by"
msgstr "Kapatan:"
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr "Kaynak dalı sil"
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr "Bahsetmeler"
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr "BirleÅŸtir"
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr "Daha fazla bilgi"
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr "Web IDE'de aç"
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr "Kaynak dal silindi"
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/uk/gitlab.po b/locale/uk/gitlab.po
index a7fddf12c55..7eadbcca8b7 100644
--- a/locale/uk/gitlab.po
+++ b/locale/uk/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: uk\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:23\n"
+"PO-Revision-Date: 2021-09-01 22:32\n"
msgid " %{name}, confirm your email address now! "
msgstr " %{name}, підтвердьте Ñвою адреÑу електронної пошти зараз! "
@@ -82,7 +82,7 @@ msgid " or references (e.g. path/to/project!merge_request_id)"
msgstr " або поÑÐ¸Ð»Ð°Ð½Ð½Ñ (напр. шлÑÑ…/до/проєкту!id_запиту_на_злиттÑ)"
msgid " reacted with :%{name}:"
-msgstr ""
+msgstr " відреагував:%{name}:"
msgid "\"%{path}\" did not exist on \"%{ref}\""
msgstr "\"%{path}\" не Ñ–Ñнував у \"%{ref}\""
@@ -484,6 +484,13 @@ msgstr[1] "%d теги відповідно до імені образу"
msgstr[2] "%d тегів відповідно до імені образу"
msgstr[3] "%d тегів відповідно до імені образу"
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -661,6 +668,9 @@ msgstr[3] "%{count} учаÑтників"
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr "%{count} пов’Ñзаних %{pluralized_subject}: %{links}"
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr "%{count} загальна вага"
@@ -799,9 +809,6 @@ msgstr "%{labelStart}Метод:%{labelEnd} %{method}"
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr "%{labelStart}проÑÑ‚Ñ–Ñ€ імен:%{labelEnd} %{namespace}"
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr "%{labelStart}Тип ÑкануваннÑ:%{labelEnd} %{reportType}"
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr "%{labelStart}Сканер:%{labelEnd} %{scanner}"
@@ -811,6 +818,9 @@ msgstr "%{labelStart}ÐадіÑланий запит:%{labelEnd} %{headers}"
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr "%{labelStart}Рівень:%{labelEnd} %{severity}"
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -978,6 +988,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr "%{seconds}Ñ"
@@ -1178,7 +1191,7 @@ msgid "%{user} created an issue: %{issue_link}"
msgstr "%{user} Ñтворив задачу: %{issue_link}"
msgid "%{value} is not included in the list"
-msgstr ""
+msgstr "%{value} не включено до ÑпиÑку"
msgid "%{value} s"
msgstr "%{value} Ñ"
@@ -1220,10 +1233,10 @@ msgid "'%{level}' is not a valid visibility level"
msgstr "\"%{level}\" не Ñ” допуÑтимим рівнем видимоÑÑ‚Ñ–"
msgid "'%{name}' Value Stream created"
-msgstr ""
+msgstr "'%{name}' Value Stream Ñтворено"
msgid "'%{name}' Value Stream deleted"
-msgstr ""
+msgstr "'%{name}' Value Stream видалено"
msgid "'%{name}' Value Stream saved"
msgstr "'%{name}' Value Stream збережено"
@@ -1362,7 +1375,7 @@ msgid "0 bytes"
msgstr "0 байт"
msgid "0 for unlimited, only effective with remote storage enabled."
-msgstr ""
+msgstr "0 Ð´Ð»Ñ Ð½ÐµÐ¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð¾Ð³Ð¾ запиÑу, ефективне лише Ð´Ð»Ñ ÑƒÐ²Ñ–Ð¼ÐºÐ½ÐµÐ½Ð¾Ð³Ð¾ віддаленого Ñховища."
msgid "0t1DgySidms"
msgstr "0t1DgySidms"
@@ -1446,13 +1459,13 @@ msgstr[3] "%d годин"
msgid "1 issue selected"
msgid_plural "%d issues selected"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "Вибрана 1 задача"
+msgstr[1] "Вибрані %d задачі"
+msgstr[2] "Вибрано %d задач"
+msgstr[3] "Вибрано %d задач"
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -1625,7 +1638,7 @@ msgid "A basic template for developing Linux programs using Kotlin Native"
msgstr "ОÑновний шаблон розробки програм Linux за допомогою Kotlin Native"
msgid "A complete DevOps platform"
-msgstr "Повноцінна DevOps платформа "
+msgstr "Повноцінна DevOps платформа"
msgid "A default branch cannot be chosen for an empty project."
msgstr "Ðе можна обирати уÑтавну гілку Ð´Ð»Ñ Ð¿Ð¾Ñ€Ð¾Ð¶Ð½ÑŒÐ¾Ð³Ð¾ проєкту."
@@ -1637,7 +1650,7 @@ msgid "A description is required"
msgstr "Потрібен опиÑ"
msgid "A different reason"
-msgstr ""
+msgstr "Інша причина"
msgid "A file has been changed."
msgstr "Файл змінено."
@@ -1703,7 +1716,7 @@ msgid "A project containing issues for each audit inquiry in the HIPAA Audit Pro
msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "Ім'Ñ Ñховища проєкту визначає його URL-адреÑу (ту, Ñку ви викориÑтовуєте Ð´Ð»Ñ Ð´Ð¾Ñтупу до проєкту через браузер) та його міÑце на файловому диÑку, де вÑтановлено GitLab. %{link_start}ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ.%{link_end}"
msgid "A ready-to-go template for use with Android apps"
msgstr "Готовий шаблон Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð· Android заÑтоÑунками"
@@ -1718,7 +1731,7 @@ msgid "A sign-in to your account has been made from the following IP address: %{
msgstr "Вхід до вашого облікового запиÑу був зроблений з наÑтупної IP-адреÑи: %{ip}"
msgid "A string appended to the project path to form the Service Desk email address."
-msgstr ""
+msgstr "РÑдок додаєтьÑÑ Ð´Ð¾ шлÑху проєкту Ð´Ð»Ñ Ñ„Ð¾Ñ€Ð¼Ð¸ email-адреÑи Service Desk."
msgid "A title is required"
msgstr "Ðеобхідно вказати заголовок"
@@ -1750,11 +1763,11 @@ msgstr "API ключ"
msgid "API?"
msgstr "API?"
-msgid "APIFuzzing|$VariableWithPassword"
-msgstr "$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
+msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
-msgstr "$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
+msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
msgstr ""
@@ -1772,7 +1785,7 @@ msgid "APIFuzzing|Code snippet could not be generated. Try again later."
msgstr ""
msgid "APIFuzzing|Configure HTTP basic authentication values. Other authentication methods are supported. %{linkStart}Learn more%{linkEnd}."
-msgstr ""
+msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ñновних значень автентифікації HTTP. ПідтримуютьÑÑ Ñ–Ð½ÑˆÑ– методи автентифікації. %{linkStart}Докладніше%{linkEnd}."
msgid "APIFuzzing|Customize common API fuzzing settings to suit your requirements. For details of more advanced configuration options, see the %{docsLinkStart}GitLab API Fuzzing documentation%{docsLinkEnd}."
msgstr ""
@@ -1780,11 +1793,11 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr "Увімкнути автентифікацію"
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
-msgstr "Введіть ім'Ñ Ð·Ð¼Ñ–Ð½Ð½Ð¾Ñ—, що міÑтить пароль. Ðаприклад, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
+msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
-msgstr "Введіть ім'Ñ Ð·Ð¼Ñ–Ð½Ð½Ð¾Ñ—, що міÑтить ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача. Ðаприклад, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
+msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
msgstr ""
@@ -2018,7 +2031,7 @@ msgid "AccessibilityReport|New"
msgstr "Ðовий"
msgid "AccessibilityReport|The accessibility scanning found an error of the following type: %{code}"
-msgstr ""
+msgstr "Перевірка доÑтупноÑÑ‚Ñ– виÑвила помилку такого типу: %{code}"
msgid "Account"
msgstr "Обліковий запиÑ"
@@ -2560,8 +2573,8 @@ msgstr "ПереглÑнути оÑтанні проєкти"
msgid "AdminArea|View latest users"
msgstr "ПереглÑнути оÑтанніх кориÑтувачів"
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
-msgstr "Зараз ви зупинете вÑÑ– завданнÑ. Це обірве уÑÑ– запущені завданнÑ."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
+msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "Помилка при завантаженні ÑтатиÑтики. Будь лаÑка, Ñпробуйте знову"
@@ -2788,12 +2801,6 @@ msgstr "Заблоковано"
msgid "AdminUsers|Blocking user has the following effects:"
msgstr "Ð‘Ð»Ð¾ÐºÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувача має наÑтупні наÑлідки:"
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2860,6 +2867,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr "ВикориÑтовує міÑце"
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr "Це ви!"
@@ -2897,7 +2907,7 @@ msgid "AdminUsers|Regular"
msgstr ""
msgid "AdminUsers|Regular users have access to their groups and projects"
-msgstr ""
+msgstr "Звичайні кориÑтувачі мають доÑтуп до Ñвоїх груп та проєктів"
msgid "AdminUsers|Reject"
msgstr "Відхилити"
@@ -2923,6 +2933,12 @@ msgstr "Відправити Ð¿Ð¾Ð²Ñ–Ð´Ð¼Ð¾Ð»ÐµÐ½Ð½Ñ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾Ñ— пÐ
msgid "AdminUsers|Sort by"
msgstr "Сортувати за"
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr "КориÑтувач вийде із ÑиÑтеми"
@@ -2989,7 +3005,7 @@ msgstr "Що Ñ Ð¼Ð¾Ð¶Ñƒ зробити?"
msgid "AdminUsers|What does this mean?"
msgstr "Що це означає?"
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3836,9 +3852,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr "Помилка при отриманні ÑпиÑків дошки. Будь лаÑка, Ñпробуйте знову."
-
msgid "An error occurred while fetching the job log."
msgstr "Помилка при отриманні логів завданнÑ."
@@ -3854,9 +3867,6 @@ msgstr "Помилка при отриманні завдань."
msgid "An error occurred while fetching the latest pipeline."
msgstr "Помилка при отриманні оÑтаннього конвеєра."
-msgid "An error occurred while fetching the pipeline."
-msgstr "Помилка при отриманні данних конвеєра."
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr "Помилка при отриманні релізів. Будь лаÑка, Ñпробуйте знову."
@@ -3911,6 +3921,12 @@ msgstr "Помилка при завантаженні задач"
msgid "An error occurred while loading merge requests."
msgstr "Помилка при завантаженні результатів злиттÑ."
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4364,7 +4380,7 @@ msgid "Approval rules reset to project defaults"
msgstr "Відновлено типові Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð» Ð·Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚Ñƒ"
msgid "Approval settings"
-msgstr ""
+msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ"
msgid "ApprovalRuleRemove|%d member"
msgid_plural "ApprovalRuleRemove|%d members"
@@ -4394,7 +4410,7 @@ msgstr[1] "Потрібно %{count} Ð·Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð²Ñ–Ð´ %{membersCo
msgstr[2] "Потрібно %{count} затверджень від %{membersCount}"
msgstr[3] "Потрібно %{count} затверджень від %{membersCount}"
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4403,12 +4419,18 @@ msgstr "Додати затверджувачів"
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
-msgid "ApprovalRule|Approval rules"
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
msgstr ""
+msgid "ApprovalRule|Approval rules"
+msgstr "Правила затвердженнÑ"
+
msgid "ApprovalRule|Approvals required"
msgstr ""
@@ -4433,6 +4455,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr "Ð†Ð¼â€™Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»Ð°"
@@ -4445,6 +4470,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr "Цільова гілка"
@@ -4454,19 +4485,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4577,6 +4614,9 @@ msgstr "Ви впевнені, що хочете розархівувати це
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr "Ви впевнені, що хочете ÑкаÑувати Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ коментарÑ?"
@@ -4737,9 +4777,6 @@ msgstr "Ðртефакт було уÑпішно видалено."
msgid "Artifacts"
msgstr "Ðртефакти"
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4858,9 +4895,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr "СпиÑки виконавців не доÑтупні з вашою поточною ліцензією"
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr "СпиÑки виконавців показують уÑÑ– задачі, призначені вибраному кориÑтувачу."
-
msgid "Assignee(s)"
msgstr "Виконавець(ці)"
@@ -4979,6 +5013,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -5156,6 +5196,9 @@ msgstr "Ðвтоматичне ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ñертифікатами зÐ
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5348,9 +5391,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr "Почати із виділеного коміту"
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr "Ðижче наведено відбитки SSH-ключів хоÑта поточного інÑтанÑу."
@@ -5382,7 +5422,7 @@ msgid "BillingPlans|Compare all plans"
msgstr ""
msgid "BillingPlans|Congratulations, your free trial is activated."
-msgstr ""
+msgstr "Вітаємо, ваша безкоштовна пробна верÑÑ–Ñ Ð°ÐºÑ‚Ð¸Ð²Ð¾Ð²Ð°Ð½Ð°."
msgid "BillingPlans|End of availability for the Bronze Plan"
msgstr ""
@@ -5632,16 +5672,13 @@ msgid "BoardScope|Assignee"
msgstr ""
msgid "BoardScope|Edit"
-msgstr ""
+msgstr "Редагувати"
msgid "BoardScope|Milestone"
-msgstr ""
-
-msgid "BoardScope|No matching results"
-msgstr ""
+msgstr "Етап"
msgid "BoardScope|No milestone"
-msgstr ""
+msgstr "Етап відÑутній"
msgid "BoardScope|Search milestones"
msgstr ""
@@ -5652,12 +5689,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr "Дошки"
@@ -5723,9 +5766,6 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Boards|Board"
-msgstr "Дошка"
-
msgid "Boards|Collapse"
msgstr "Згорнути"
@@ -6026,30 +6066,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr "Імпортувати %{groups}"
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
+msgid "BulkImport|Import selected"
+msgstr ""
+
msgid "BulkImport|Importing the group failed"
msgstr ""
msgid "BulkImport|Name already exists."
msgstr "Ім'Ñ Ð²Ð¶Ðµ Ñ–Ñнує."
-msgid "BulkImport|No groups on this page are available for import"
-msgstr ""
-
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6104,6 +6138,9 @@ msgstr "ЗайнÑтий(-а)"
msgid "Buy CI Minutes"
msgstr "Придбати CI Хвилин"
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr "Купити більше хвилин конвеєра"
@@ -6255,6 +6292,9 @@ msgstr "CONTRIBUTING"
msgid "CPU"
msgstr "ЦП"
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6738,12 +6778,19 @@ msgstr "Перевірка доÑтупноÑÑ‚Ñ– імені кориÑтуваÑ
msgid "Checkout"
msgstr "ÐžÑ„Ð¾Ñ€Ð¼Ð»ÐµÐ½Ð½Ñ Ð·Ð°Ð¼Ð¾Ð²Ð»ÐµÐ½Ð½Ñ"
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr "$%{selectedPlanPrice} на кориÑтувача на рік"
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr "%{cardType} закінчуєтьÑÑ Ð½Ð° %{lastFourDigits}"
@@ -6753,15 +6800,19 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr "ПідпиÑка GitLab Ð´Ð»Ñ %{name}"
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr "%{selectedPlanText} план"
msgid "Checkout|%{startDate} - %{endDate}"
msgstr "%{startDate} - %{endDate}"
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6777,7 +6828,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr "Платіжна адреÑа"
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7363,19 +7414,19 @@ msgid "ClusterAgents|An unknown error occurred. Please try again."
msgstr ""
msgid "ClusterAgents|Configuration"
-msgstr ""
+msgstr "КонфігураціÑ"
msgid "ClusterAgents|Copy token"
msgstr ""
msgid "ClusterAgents|Created by"
-msgstr ""
+msgstr "Створено"
msgid "ClusterAgents|Created by %{name} %{time}"
msgstr "Створено %{name} %{time}"
msgid "ClusterAgents|Date created"
-msgstr ""
+msgstr "Дата ÑтвореннÑ"
msgid "ClusterAgents|Description"
msgstr "ОпиÑ"
@@ -7386,6 +7437,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7401,14 +7455,11 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr "Ім'Ñ"
msgid "ClusterAgents|Never"
-msgstr ""
+msgstr "Ðіколи"
msgid "ClusterAgents|Read more about getting started"
msgstr ""
@@ -7453,7 +7504,7 @@ msgid "ClusterAgents|To install an Agent you should create an agent directory in
msgstr ""
msgid "ClusterAgents|Unknown user"
-msgstr ""
+msgstr "Ðевідомий кориÑтувач"
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
@@ -7594,7 +7645,7 @@ msgid "ClusterIntegration|Cluster Region"
msgstr ""
msgid "ClusterIntegration|Cluster management project"
-msgstr ""
+msgstr "Проєкт ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ ÐºÐ»Ð°Ñтером"
msgid "ClusterIntegration|Cluster name is required."
msgstr "Ім'Ñ ÐºÐ»Ð°Ñтера Ñ” обов'Ñзковим."
@@ -7672,7 +7723,7 @@ msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster
msgstr ""
msgid "ClusterIntegration|Deploy each environment to its own namespace. Otherwise, environments within a project share a project-wide namespace. Note that anyone who can trigger a deployment of a namespace can read its secrets. If modified, existing environments will use their current namespaces until the cluster cache is cleared."
-msgstr ""
+msgstr "Розгортати кожне Ñередовище в Ñвій влаÑний проÑÑ‚Ñ–Ñ€ імен. Ð’ іншому випадку Ñередовища в межах проєкту поділÑÑŽÑ‚ÑŒ проÑÑ‚Ñ–Ñ€ імен по вÑьому проєкту. Зверніть увагу, що кожен, хто може викликати Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ñтору імен може читати його Ñекрети. Якщо змінено, Ñ–Ñнуючі Ñередовища будуть викориÑтовувати Ñвої поточні проÑтори імен допоки кеш клаÑтерів не буде очищений."
msgid "ClusterIntegration|Deploy each environment to its own namespace. Otherwise, environments within a project share a project-wide namespace. Note that anyone who can trigger a deployment of a namespace can read its secrets. If modified, existing environments will use their current namespaces until the cluster cache is cleared. %{linkStart}More information%{linkEnd}"
msgstr ""
@@ -8085,8 +8136,8 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr "Підмережі"
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
-msgstr "Ð†Ð¼â€™Ñ Ñ€ÐµÑурÑу Amazon (ARN), пов’Ñазане із вашою роллю. Якщо у Ð²Ð°Ñ Ð½ÐµÐ¼Ð°Ñ” ролі Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²Ñ–Ð·Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ, Ñпочатку Ñтворіть Ñ—Ñ— в %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} за допомогою облікового запиÑу та external ID вказаних вище %{startMoreInfoLink}Додаткова інформаціÑ%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
msgstr "Сертифікат Kubernetes, що викориÑтовуєтьÑÑ Ð´Ð»Ñ Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ— в клаÑтері."
@@ -8242,7 +8293,7 @@ msgid "Code Coverage|Couldn't fetch the code coverage data"
msgstr ""
msgid "Code Owner"
-msgstr ""
+msgstr "ВлаÑник коду"
msgid "Code Owners"
msgstr "ВлаÑники коду"
@@ -8569,9 +8620,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8710,9 +8758,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr "Ðалаштуйте Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð²ÐµÐ± та API запитів."
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr "Ðалаштувати Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ ÐºÑ–Ð»ÑŒÐºÐ¾ÑÑ‚Ñ– вхідних попереджень, Ñкі можна надіÑлати у проєкт."
-
msgid "Configure paths to be protected by Rack Attack."
msgstr "Ðалаштуйте шлÑхи Ð´Ð»Ñ Ð·Ð°Ñ…Ð¸Ñту від атак Rack Attack."
@@ -8725,6 +8770,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -8807,7 +8855,7 @@ msgid "ConfluenceService|Your GitLab wiki is still available at %{wiki_link}. To
msgstr ""
msgid "Congratulations, your free trial is activated."
-msgstr ""
+msgstr "Вітаємо, ваша безкоштовна пробна верÑÑ–Ñ Ð°ÐºÑ‚Ð¸Ð²Ð¾Ð²Ð°Ð½Ð°."
msgid "Connect"
msgstr "Підключити"
@@ -8914,10 +8962,10 @@ msgid "ContainerRegistry|CLI Commands"
msgstr "Команди CLI"
msgid "ContainerRegistry|Cleanup disabled"
-msgstr ""
+msgstr "ÐžÑ‡Ð¸Ñ‰ÐµÐ½Ð½Ñ Ð²Ð¸Ð¼ÐºÐ½ÐµÐ½Ð¾"
msgid "ContainerRegistry|Cleanup in progress"
-msgstr ""
+msgstr "ВиконуєтьÑÑ Ð¾Ñ‡Ð¸Ñ‰ÐµÐ½Ð½Ñ"
msgid "ContainerRegistry|Cleanup incomplete"
msgstr ""
@@ -9451,7 +9499,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10692,6 +10740,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10704,6 +10755,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr "Перевірка заголовка"
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10716,12 +10770,18 @@ msgstr "Крок 1 - Виберіть метод перевірки Ñайту"
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10741,6 +10801,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10873,9 +10936,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr "За замовчуваннÑм"
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10945,6 +11005,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr "ВизначеннÑ"
@@ -10993,9 +11056,15 @@ msgstr "Видалити артефакти"
msgid "Delete badge"
msgstr "Видалити значок"
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr "Видалити коментар"
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr "Видалити домен"
@@ -11020,6 +11089,9 @@ msgstr "Видалити проєкт"
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -11038,6 +11110,9 @@ msgstr "Видалити гілку-джерело"
msgid "Delete subscription"
msgstr "Видалити підпиÑку"
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr "Видалити це вкладеннÑ"
@@ -11221,12 +11296,12 @@ msgstr "Ð¡ÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð»ÐµÐ¶Ð½Ð¾Ñтей"
msgid "Dependency proxy"
msgstr "ПрокÑÑ– залежноÑтей"
-msgid "Dependency proxy URL"
-msgstr "URL-адреÑа прокÑÑ– залежноÑтей"
-
msgid "Dependency proxy feature is limited to public groups for now."
msgstr "Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð¿Ñ€Ð¾ÐºÑÑ– залежноÑтей наразі доÑтупна тільки Ð´Ð»Ñ Ð¿ÑƒÐ±Ð»Ñ–Ñ‡Ð½Ð¸Ñ… груп."
+msgid "Dependency proxy image prefix"
+msgstr ""
+
msgid "DependencyProxy|Toggle Dependency Proxy"
msgstr "Увімкнути/вимкнути прокÑÑ– залежноÑтей"
@@ -11278,6 +11353,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr "Редагувати"
@@ -11708,6 +11795,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11763,12 +11856,12 @@ msgid "DevopsAdoption|DevOps adoption tracks the use of key features across your
msgstr ""
msgid "DevopsAdoption|Edit groups"
-msgstr ""
+msgstr "Редагувати групи"
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -12112,7 +12205,7 @@ msgid "Domain was successfully deleted."
msgstr "Домен уÑпішно видалено."
msgid "Domain was successfully updated."
-msgstr "Домен уÑпішно оновлено. "
+msgstr ""
msgid "Don't have an account yet?"
msgstr "Ще не зареєÑтровані?"
@@ -12279,6 +12372,9 @@ msgstr "Редагувати Гео-вузол"
msgid "Edit Group Hook"
msgstr "Редагувати хук групи"
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr "Редагувати мітку"
@@ -12354,6 +12450,9 @@ msgstr "Редагувати публічний ключ Ð´Ð»Ñ Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°
msgid "Edit sidebar"
msgstr "Редагувати бічну панель"
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12561,9 +12660,6 @@ msgstr "Увімкнути Gitpod"
msgid "Enable Gitpod?"
msgstr "Увімкнути Gitpo?"
-msgid "Enable Incident Management inbound alert limit"
-msgstr "Увімкнути ліміти попереджень Ð´Ð»Ñ Ð£Ð¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ Ñ–Ð½Ñ†Ð¸Ð´ÐµÐ½Ñ‚Ð°Ð¼Ð¸"
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12612,6 +12708,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12651,6 +12750,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr "Увімкнути інтеграцію"
@@ -13005,6 +13107,9 @@ msgstr "РозгортаннÑ"
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -13017,6 +13122,9 @@ msgstr "Середовища"
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr "Середовища — це міÑцÑ, куди можна розгорнути код, наприклад staging або production."
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -13092,6 +13200,9 @@ msgstr "Зупинити Ñередовище"
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° під Ñ‡Ð°Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð»Ð¾Ð³Ñ–Ð². Будь лаÑка, Ñпробуйте ще раз."
@@ -13113,6 +13224,12 @@ msgstr "Оновлено"
msgid "Environments|You don't have any environments right now"
msgstr "Ви поки не налаштували жодного Ñередовища"
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr "захищені"
@@ -13449,6 +13566,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14826,6 +14946,9 @@ msgstr "Форки"
msgid "Format: %{dateFormat}"
msgstr "Формат: %{dateFormat}"
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr "Знайдено помилки у вашому %{gitlab_ci_yml}:"
@@ -14913,6 +15036,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -15045,10 +15171,10 @@ msgstr "Фільтр за ÑтатуÑом"
msgid "Geo|Geo Status"
msgstr "Geo ÑтатуÑ"
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -15093,7 +15219,7 @@ msgstr "ОÑтанній Ñ‡Ð°Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸"
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -15114,9 +15240,6 @@ msgstr "Ім'Ñ Ð²ÑƒÐ·Ð»Ð° не може бути пуÑтим"
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr "Ðе Ñинхронізовано"
@@ -15171,19 +15294,16 @@ msgstr "Видалити запиÑ"
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -15228,7 +15348,7 @@ msgstr "Повторно перевірити вÑе"
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -15240,6 +15360,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr "СтатуÑ"
@@ -15264,11 +15387,11 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
-msgstr "База даних зараз %{db_lag} позаду оÑновного вузла."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
+msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
-msgstr "Вузол зараз %{minutes_behind} позаду оÑновного вузла."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
+msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
msgstr ""
@@ -15339,7 +15462,7 @@ msgstr "ÐžÑ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð»Ð°Ð½ÑƒÐ²Ð°Ð»ÑŒÐ½Ð¸ÐºÐ°"
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15384,6 +15507,9 @@ msgstr "Git"
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr "Git LFS не увімкнено на цьому Ñервері GitLab, звернітьÑÑ Ð´Ð¾ адмініÑтратора."
@@ -15438,9 +15564,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr "Команда оплати GitLab."
-msgid "GitLab CI"
-msgstr "GitLab CI"
-
msgid "GitLab Import"
msgstr "Імпорт з GitLab"
@@ -15690,6 +15813,9 @@ msgstr "Ðадано доÑтуп %{time_ago}"
msgid "Given epic is already related to this epic."
msgstr "Даний епік уже пов’Ñзаний із цим епіком."
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr "Глобальні комбінації клавіш"
@@ -15771,7 +15897,7 @@ msgstr "Перейти на рівень вище"
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15829,7 +15955,7 @@ msgid "Goal of the changes and what reviewers should be aware of"
msgstr ""
msgid "Google authentication is not %{link_start}properly configured%{link_end}. Ask your GitLab administrator if you want to use this service."
-msgstr "ÐÐ²Ñ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ Google не %{link_start}налаштована належним чином%{link_end}. ЗвернітьÑÑ Ð´Ð¾ вашого адмініÑтратора GitLab Ñкщо хочете викориÑтовувати цю Ñлужбу. "
+msgstr ""
msgid "Got it"
msgstr "Зрозуміло"
@@ -16122,6 +16248,12 @@ msgstr "Вибачте, жоден епік не задовольнÑÑ” крит
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr "План-графік епіків відображає Ñтан ваших епіків у чаÑÑ–"
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -16134,6 +16266,9 @@ msgstr "Ð”Ð»Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду плану-графіку, додайте да
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr "Щоб розширити пошук, змініть або видаліть фільтри; від %{startDate} до %{endDate}."
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -16167,7 +16302,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16695,12 +16830,12 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
-msgstr "Допомагає зменшити об’єм попереджень (напр. при великій кількоÑÑ‚Ñ– проблем)"
-
msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
+msgstr ""
+
msgid "Helps reduce request volume for protected paths"
msgstr "Допомагає зменшити об’єм запитів Ð´Ð»Ñ Ð·Ð°Ñ…Ð¸Ñ‰ÐµÐ½Ð¸Ñ… шлÑхів"
@@ -16835,6 +16970,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16854,7 +16992,7 @@ msgid "I accept the %{terms_link}"
msgstr "Я приймаю %{terms_link}"
msgid "I accept the|Terms of Service and Privacy Policy"
-msgstr "Я погоджуюÑÑŒ з Правилами кориÑÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÑервіÑом Ñ– політикою конфіденційноÑÑ‚Ñ–"
+msgstr ""
msgid "I forgot my password"
msgstr "Я забув пароль"
@@ -16973,7 +17111,7 @@ msgstr "Якщо вимкнено, локальна гілка зі змінам
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -17267,6 +17405,9 @@ msgstr "Ð’ процеÑÑ–"
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -18026,6 +18167,12 @@ msgstr "Ð’Ñтавити малюнок"
msgid "Insert code"
msgstr "Ð’Ñтавити код"
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -18035,6 +18182,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr "Додати пропозицію"
@@ -18126,6 +18279,9 @@ msgstr "Ð’ÑÑ– деталі"
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -18246,6 +18402,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18435,9 +18594,6 @@ msgstr "ЗапроÑити учаÑника"
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr "ЗапроÑити Ñвою команду"
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18975,6 +19131,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19009,7 +19168,7 @@ msgid "Iterations|Move incomplete issues to the next iteration"
msgstr ""
msgid "Iterations|New iteration"
-msgstr ""
+msgstr "Ðова ітераціÑ"
msgid "Iterations|New iteration cadence"
msgstr ""
@@ -19668,9 +19827,6 @@ msgstr "Мітка"
msgid "Label actions dropdown"
msgstr "Випадаючий ÑпиÑок дій із мітками"
-msgid "Label lists show all issues with the selected label."
-msgstr "Ð’ ÑпиÑках на оÑнові міток відображаютьÑÑ Ð»Ð¸ÑˆÐµ Ñ‚Ñ– задачі, Ñкі мають вибрану мітку."
-
msgid "Label priority"
msgstr "Мітка пріоритет"
@@ -19795,9 +19951,6 @@ msgstr "ОÑÑ‚Ð°Ð½Ð½Ñ Ð²Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´ÑŒ від"
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr "ОÑтанній запуÑк перевірки репозиторію"
-
msgid "Last seen"
msgstr "ОÑÑ‚Ð°Ð½Ð½Ñ Ð°ÐºÑ‚Ð¸Ð²Ð½Ñ–ÑÑ‚ÑŒ"
@@ -19816,6 +19969,9 @@ msgstr "ОÑÑ‚Ð°Ð½Ð½Ñ ÑƒÑпішна ÑинхронізаціÑ"
msgid "Last successful update"
msgstr "ОÑтаннє уÑпішне оновленнÑ"
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr "ОÑтанній раз перевірено"
@@ -20269,10 +20425,13 @@ msgstr "Обмежити проÑтори імен та проєкти Ñкі м
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
+msgstr ""
+
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20783,6 +20942,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20831,6 +20993,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr "МакÑимальний розмір артефактів (МБ)"
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr "МакÑимальний розмір Ð²ÐºÐ»Ð°Ð´ÐµÐ½Ð½Ñ (МБ)"
@@ -20849,6 +21014,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr "МакÑимальна затримка (хвилини)"
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20861,7 +21029,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20876,9 +21044,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr "МакÑимальний розмір Ð´Ð»Ñ Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚Ñƒ (МБ)"
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr "МакÑимальний Ñ‡Ð°Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ"
@@ -20912,6 +21086,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr "МакÑимальний розмір Ð´Ð»Ñ Ð²Ñ–Ð´Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ (МБ)"
@@ -20936,6 +21116,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr "МакÑимальний можливий Ñ‡Ð°Ñ Ð¼Ñ–Ð¶ оновленнÑми Ð´Ð»Ñ Ð´Ð·ÐµÑ€ÐºÐ°Ð»Ð° при запланованій Ñинхронізації."
@@ -20975,6 +21158,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -21143,6 +21329,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -21260,9 +21449,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr "Виникла помилка під Ñ‡Ð°Ñ Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ñ‡ÐµÑ€Ð½ÐµÑ‚ÐºÐ¸ коментарÑ."
@@ -21275,9 +21461,6 @@ msgstr "Вирішити це Ð¾Ð±Ð³Ð¾Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð² новій задачі"
msgid "MergeRequests|Saving the comment failed"
msgstr "Помилка при збереженні коментарÑ"
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr "ÐžÐ±â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ ÐºÐ¾Ð¼Ñ–Ñ‚Ñ–Ð² відхилено: інше Ð¾Ð±â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð²Ð¶Ðµ відбуваєтьÑÑ."
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21763,9 +21946,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr "СпиÑки етапів не доÑтупні з вашою поточною ліцензією"
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr "У ÑпиÑках етапу відображаютьÑÑ Ð²ÑÑ– задачі Ð´Ð»Ñ Ð²Ð¸Ð±Ñ€Ð°Ð½Ð¾Ð³Ð¾ етапу."
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -22040,7 +22220,7 @@ msgid "More information and share feedback"
msgstr "Ðадати більше інформації Ñ– поділитиÑÑ Ð²Ñ–Ð´Ð³ÑƒÐºÐ¾Ð¼"
msgid "More information is available|here"
-msgstr "тут"
+msgstr ""
msgid "More information."
msgstr "Докладніше."
@@ -22144,7 +22324,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22337,12 +22517,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr "Редагувати політику"
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22385,9 +22559,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22397,21 +22568,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22427,9 +22589,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22500,7 +22659,7 @@ msgid "New"
msgstr "Ðовий"
msgid "New %{issueType}"
-msgstr ""
+msgstr "Ðовий %{issueType}"
msgid "New Application"
msgstr "Ðовий додаток"
@@ -22515,7 +22674,7 @@ msgid "New Environment"
msgstr "Ðове Ñередовище"
msgid "New Epic"
-msgstr ""
+msgstr "Ðовий Епік"
msgid "New File"
msgstr "Ðовий файл"
@@ -22578,9 +22737,6 @@ msgstr "Ðова гілка"
msgid "New branch unavailable"
msgstr "Ðова гілка недоÑтупна"
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr "Додано нові зміни. %{linkStart}Оновіть Ñторінку, щоб переглÑнути Ñ—Ñ…%{linkEnd}"
-
msgid "New confidential epic title "
msgstr ""
@@ -22764,6 +22920,9 @@ msgstr "Ðе знайдено application_settings"
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr "Ðемає виконавцÑ"
@@ -23246,7 +23405,7 @@ msgid "NotificationEvent|Reopen issue"
msgstr "Повторне Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ð·Ð°Ð´Ð°Ñ‡Ñ–"
msgid "NotificationEvent|Reopen merge request"
-msgstr ""
+msgstr "Повторно відкрити запит на злиттÑ"
msgid "NotificationEvent|Successful pipeline"
msgstr "УÑпішно в Конвеєрі"
@@ -23293,6 +23452,9 @@ msgstr "лиÑтопад"
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23411,7 +23573,7 @@ msgid "OnCallSchedules|Add rotation"
msgstr ""
msgid "OnCallSchedules|Add schedule"
-msgstr ""
+msgstr "Додати розклад"
msgid "OnCallSchedules|Are you sure you want to delete the \"%{deleteRotation}\" rotation? This action cannot be undone."
msgstr ""
@@ -23422,7 +23584,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23459,10 +23621,10 @@ msgid "OnCallSchedules|For this rotation, on-call will be:"
msgstr ""
msgid "OnCallSchedules|On-call schedule %{schedule} in Project %{project}"
-msgstr ""
+msgstr "Розклад викликів %{schedule} в проєкті %{project}"
msgid "OnCallSchedules|On-call schedules"
-msgstr ""
+msgstr "Розклад Ð´Ð»Ñ Ð²Ð¸ÐºÐ»Ð¸ÐºÑƒ"
msgid "OnCallSchedules|Please note, rotations with shifts that are less than four hours are currently not supported in the weekly view."
msgstr ""
@@ -23658,7 +23820,7 @@ msgid "One or more of you personal access tokens were revoked"
msgstr "Один або декілька ваших токенів оÑобиÑтого доÑтупу були анульовані"
msgid "One or more of your %{provider} projects cannot be imported into GitLab directly because they use Subversion or Mercurial for version control, rather than Git."
-msgstr ""
+msgstr "Один або декілька ваших проєктів %{provider} не можна імпортувати безпоÑередньо в GitLab, оÑкільки вони викориÑтовують Subversion або Mercurial Ð´Ð»Ñ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŽ верÑій заміÑÑ‚ÑŒ Git."
msgid "One or more of your dependency files are not supported, and the dependency list may be incomplete. Below is a list of supported file types."
msgstr "Один або кілька з ваших файлів залежноÑтей не підтримуютьÑÑ, тому ÑпиÑок залежноÑтей може бути неповним. Ðижче наведено ÑпиÑок підтримуваних типів файлі."
@@ -23720,7 +23882,7 @@ msgstr "Відкриті"
msgid "Open Selection"
msgstr "Відкрити виділеннÑ"
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23802,7 +23964,7 @@ msgid "OperationsDashboard|The operations dashboard provides a summary of each p
msgstr "Панель ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñми міÑтить інформацію про Ñтан кожного з проєктів разом зі Ñтаном його конвеєрів та попереджень."
msgid "Optimize your workflow with CI/CD Pipelines"
-msgstr ""
+msgstr "Оптимізувати ваш робочий Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð·Ð° допомогою CI/CD конвеєрів"
msgid "Optional"
msgstr "Ðеобов'Ñзково"
@@ -23912,6 +24074,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24585,7 +24750,7 @@ msgid "Pipeline %{label} for \"%{dataTitle}\""
msgstr "Конвеєр %{label} Ð´Ð»Ñ \"%{dataTitle}\""
msgid "Pipeline ID"
-msgstr ""
+msgstr "Ідентифікатор конвеєра"
msgid "Pipeline IID"
msgstr ""
@@ -25049,6 +25214,51 @@ msgstr "Запущено"
msgid "Pipeline|Skipped"
msgstr "Пропущено"
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25092,7 +25302,7 @@ msgid "Pipeline|Variables"
msgstr "Змінні"
msgid "Pipeline|View pipeline"
-msgstr ""
+msgstr "ПереглÑнути конвеєр"
msgid "Pipeline|We are currently unable to fetch pipeline data"
msgstr ""
@@ -25404,7 +25614,7 @@ msgid "Preferences|Configure how dates and times display for you."
msgstr ""
msgid "Preferences|Customize integrations with third party services."
-msgstr ""
+msgstr "Ðалаштуйте інтеграцію зі Ñторонніми Ñлужбами."
msgid "Preferences|Customize the appearance of the application header and navigation sidebar."
msgstr "Ðалаштувати зовнішній виглÑд заголовку заÑтоÑунку та навігаційної бічної панелі."
@@ -25490,15 +25700,12 @@ msgstr "ÐатиÑніть %{key}-C, щоб Ñкопіювати"
msgid "Prev"
msgstr "Ðазад"
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
-msgstr ""
-
msgid "Prevent adding new members to project membership within this group"
msgstr "Заборонити Ð´Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ð½Ð¾Ð²Ð¸Ñ… учаÑників до членÑтва в цій групі"
+msgid "Prevent editing approval rules in projects and merge requests."
+msgstr ""
+
msgid "Prevent environment from auto-stopping"
msgstr ""
@@ -25508,9 +25715,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr "Заборонити кориÑтувачам змінювати ім'Ñ Ñвого профілю"
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25775,6 +25979,9 @@ msgstr "Ðе відображати оÑобиÑту інформацію, поÐ
msgid "Profiles|Edit Profile"
msgstr "Редагувати профіль"
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25860,7 +26067,7 @@ msgid "Profiles|Manage two-factor authentication"
msgstr ""
msgid "Profiles|No file chosen."
-msgstr ""
+msgstr "Файл не вибрано."
msgid "Profiles|Notification email"
msgstr "ÐдреÑа електронної пошти Ð´Ð»Ñ Ñповіщень"
@@ -25967,9 +26174,6 @@ msgstr "Ð†Ð¼â€™Ñ ÐºÐ¾Ñ€Ð¸Ñтувача уÑпішно збережено"
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr "ВикориÑÑ‚Ð°Ð½Ð½Ñ Ñмайликів в іменах виглÑдає дотепно, але, будь лаÑка, краще викориÑтовуйте Ñ—Ñ… в повідомленнÑÑ… про ÑтатуÑ"
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr "Який ваш ÑтатуÑ?"
@@ -27068,9 +27272,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -27122,6 +27323,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr "ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ"
@@ -27161,9 +27365,6 @@ msgstr "Ð¦Ñ Ñ„ÑƒÐ½ÐºÑ†Ñ–Ñ Ð·Ð°Ð±Ð»Ð¾ÐºÐ¾Ð²Ð°Ð½Ð°."
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27564,13 +27765,13 @@ msgid "PushoverService|Get real-time notifications on your device."
msgstr ""
msgid "PushoverService|High priority"
-msgstr ""
+msgstr "ВиÑокий пріоритет"
msgid "PushoverService|Leave blank for all active devices."
msgstr ""
msgid "PushoverService|Low priority"
-msgstr ""
+msgstr "Ðизький пріоритет"
msgid "PushoverService|Lowest priority"
msgstr ""
@@ -27609,7 +27810,7 @@ msgid "Quick range"
msgstr "Швидкий діапазон"
msgid "Quickly and easily edit multiple files in your project."
-msgstr ""
+msgstr "Швидко і легко редагувати декілька файлів у вашому проєкті."
msgid "README"
msgstr "ІнÑÑ‚Ñ€ÑƒÐºÑ†Ñ–Ñ (README)"
@@ -27665,6 +27866,12 @@ msgstr "ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про пов’Ñзані задачі"
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27720,7 +27927,7 @@ msgid "Reconfigure"
msgstr "Переналаштувати"
msgid "Recovering projects"
-msgstr ""
+msgstr "Ð’Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚Ñ–Ð²"
msgid "Recovery Codes"
msgstr "Коди відновленнÑ"
@@ -27734,6 +27941,9 @@ msgstr ""
msgid "Redis"
msgstr "Redis"
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr "Знизити видиміÑÑ‚ÑŒ проєкту"
@@ -27849,6 +28059,9 @@ msgstr "ПовʼÑзані задачі"
msgid "Related merge requests"
msgstr "Пов'Ñзані запити на злиттÑ"
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr "ВідноÑитьÑÑ Ð´Ð¾"
@@ -28373,6 +28586,9 @@ msgstr "Помилка при завантаженні результатів д
msgid "Reports|Test summary results are being parsed"
msgstr "Результати Ð´Ð»Ñ Ñ‚ÐµÑтового звіту оброблÑÑŽÑ‚ÑŒÑÑ"
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr "ВразливіÑÑ‚ÑŒ"
@@ -28826,6 +29042,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -29020,7 +29239,7 @@ msgid "Runners|For each solution, you will choose a capacity. 1 enables warm HA
msgstr ""
msgid "Runners|Group Runners"
-msgstr ""
+msgstr "Групові Runner'и"
msgid "Runners|IP Address"
msgstr "IP-адреÑа"
@@ -29095,6 +29314,9 @@ msgid "Runners|Runner registration"
msgstr ""
msgid "Runners|Runners"
+msgstr "Runner'и"
+
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
msgstr ""
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
@@ -29116,7 +29338,7 @@ msgid "Runners|Tags"
msgstr "Теги"
msgid "Runners|This runner is associated with one or more projects."
-msgstr ""
+msgstr "Цей runner пов'Ñзаний з одним або кількома проєктами."
msgid "Runners|This runner is associated with specific projects."
msgstr ""
@@ -29160,6 +29382,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29179,7 +29404,7 @@ msgid "Runners|paused"
msgstr ""
msgid "Runners|project"
-msgstr ""
+msgstr "проєкт"
msgid "Runners|shared"
msgstr ""
@@ -29437,7 +29662,7 @@ msgid "Search branches, tags, and commits"
msgstr ""
msgid "Search by Git revision"
-msgstr ""
+msgstr "Пошук за верÑією Git"
msgid "Search by author"
msgstr ""
@@ -29648,9 +29873,6 @@ msgstr[3] "результатів у вікі"
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29702,7 +29924,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29738,7 +29960,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29852,55 +30074,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29939,9 +30230,6 @@ msgstr "Коментар відредаговано в \"%{vulnerabilityName}\""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -30053,9 +30341,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr "Панель ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÐµÐ·Ð¿ÐµÐºÐ¸"
@@ -30122,6 +30407,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30465,7 +30753,7 @@ msgid "Serve repository static objects (for example, archives and blobs) from ex
msgstr ""
msgid "Server (optional)"
-msgstr ""
+msgstr "Сервер (необов'Ñзково)"
msgid "Server supports batch API only, please update your Git LFS client to version 1.0.1 and up."
msgstr "Сервер підтримує лише груповий API. Будь лаÑка, оновіть ваш клієнт Git LFS до верÑÑ–Ñ— 1.0.1 або вище."
@@ -30695,7 +30983,7 @@ msgstr "Ð’Ñтановлено ітерацію %{iteration_reference}."
msgid "Set the milestone to %{milestone_reference}."
msgstr "Ð’Ñтановити етап %{milestone_reference}."
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30743,7 +31031,7 @@ msgstr "Ð’Ñтановити вагу"
msgid "Set weight to %{weight}."
msgstr "Ð’Ñтановити вагу %{weight}."
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30944,9 +31232,6 @@ msgstr ""
msgid "Show latest version"
msgstr "Показати оÑтанню верÑÑ–ÑŽ"
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr "Показати ÑпиÑок"
@@ -31174,6 +31459,9 @@ msgstr ""
msgid "Size"
msgstr "Розмір"
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr "МакÑимальний розмір Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ репозиторію (МБ)"
@@ -31193,7 +31481,7 @@ msgid "Slack application"
msgstr "заÑтоÑунок Slack"
msgid "Slack integration allows you to interact with GitLab via slash commands in a chat window."
-msgstr "Slack Ñ–Ð½Ñ‚ÐµÐ³Ñ€Ð°Ñ†Ñ–Ñ Ð´Ð¾Ð·Ð²Ð¾Ð»Ð¸Ñ‚ÑŒ вам взаємодіÑти з GitLab через чат за домогою команд зі Ñлешем ( / )"
+msgstr "Slack Ñ–Ð½Ñ‚ÐµÐ³Ñ€Ð°Ñ†Ñ–Ñ Ð´Ð¾Ð·Ð²Ð¾Ð»Ð¸Ñ‚ÑŒ вам взаємодіÑти з GitLab через чат за домогою команд зі Ñлешем ( / )."
msgid "SlackIntegration|Sends notifications about project events to Slack channels."
msgstr ""
@@ -31382,7 +31670,7 @@ msgid "Something went wrong while fetching latest comments."
msgstr "Помилка при отриманні оÑтанніх коментарів."
msgid "Something went wrong while fetching projects"
-msgstr "Помилка при отриманні проєктів "
+msgstr "Помилка при отриманні проєктів"
msgid "Something went wrong while fetching projects."
msgstr ""
@@ -31525,6 +31813,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr "Дата ÑтвореннÑ"
@@ -32432,7 +32729,7 @@ msgid "SuggestedColors|Blue-gray"
msgstr ""
msgid "SuggestedColors|Carrot orange"
-msgstr ""
+msgstr "МорквÑно-апельÑиновий"
msgid "SuggestedColors|Champagne"
msgstr ""
@@ -33000,6 +33297,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr "СкаÑувати"
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr "Деталі"
@@ -33051,12 +33351,18 @@ msgstr ""
msgid "Terraform|States"
msgstr "Стан"
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -33069,7 +33375,7 @@ msgstr "Розблокувати"
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -33300,7 +33606,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33520,6 +33826,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr "Ваш ліцензійний ключ недійÑний. ПереконайтеÑÑ, що він збігаєтьÑÑ Ð· тим, що ви отримали від GitLab Inc."
@@ -33556,9 +33865,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr "Конфлікти у цьому запитті на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð½Ðµ можуть бути вирішені через GitLab. Будь лаÑка, Ñпробуйте зробити це локально."
@@ -33712,6 +34018,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr "Ð§Ð°Ñ Ð´Ñ–Ñ— Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ñплине через %{number_of_minutes} хвилин. Ð”Ð»Ñ Ð²ÐµÐ»Ð¸ÐºÐ¸Ñ… репозиторіїв викориÑтовуйте комбінацію clone/push."
@@ -33850,9 +34159,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33898,6 +34213,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -34078,9 +34396,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -34300,9 +34615,6 @@ msgstr ""
msgid "This field is required."
msgstr "Це поле Ñ” обов'Ñзковим."
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr "Ð¦Ñ Ð³Ñ€ÑƒÐ¿Ð°"
@@ -34375,6 +34687,9 @@ msgstr "Це ваш поточний ÑеанÑ"
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35424,14 +35739,20 @@ msgstr "Будь лаÑка, виберіть новий проÑÑ‚Ñ–Ñ€ імен
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr "Проект не може бути переміщений, тому що в реєÑтрі контейнерів приÑутні теги"
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr "Ð’ цільовому проÑторі імен вже Ñ–Ñнує проєкт із таким же іменем або шлÑхом"
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr "Кореневий проÑÑ‚Ñ–Ñ€ імен не може бути змінено, Ñкщо проєкт міÑтить пакети NPM"
-msgid "TransferProject|Transfer failed, please contact an admin."
-msgstr "ПеренеÑÐµÐ½Ð½Ñ Ð½ÐµÐ²Ð´Ð°Ð»Ðµ, будь лаÑка, зв'ÑжітьÑÑ Ñ–Ð· адмініÑтратором."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
+msgstr ""
msgid "Tree view"
msgstr "У виглÑді дерева"
@@ -35876,7 +36197,7 @@ msgid "Units|ms"
msgstr ""
msgid "Units|s"
-msgstr ""
+msgstr "Ñ"
msgid "Unknown"
msgstr "Ðевідомо"
@@ -35995,6 +36316,9 @@ msgstr ""
msgid "Until"
msgstr "До"
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -36214,9 +36538,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr "Пакети"
@@ -36235,9 +36556,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr "Репозиторій"
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr "Сніпети"
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr "Сховище"
@@ -36286,6 +36613,9 @@ msgstr "Квоти на викориÑтаннÑ"
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr "ВикориÑÑ‚Ð°Ð½Ð½Ñ Ð³Ñ€ÑƒÐ¿Ð¾Ð²Ð¸Ñ… реÑурÑів у проєктах групи %{strong_start}%{group_name}%{strong_end}"
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36442,6 +36772,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr "ВикориÑтовуйте один Ñ€Ñдок Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ URI"
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36919,9 +37252,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -37122,6 +37461,13 @@ msgstr ""
msgid "View project labels"
msgstr "ПереглÑнути мітки проєкту"
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "View replaced file @ "
msgstr "ПереглÑд заміненого файлу @ "
@@ -37380,9 +37726,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -37395,6 +37738,9 @@ msgstr "СтатуÑ"
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37500,6 +37846,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr "Ми не виÑвили вразливоÑтей"
@@ -37755,6 +38104,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr "Що нового"
@@ -37816,6 +38168,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -38374,6 +38729,9 @@ msgstr "Ви можете перевірити Ñвій .gitlab-ci.yml у %{link
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr "Ви не можете отримати доÑтуп до неформатованого файлу. Будь лаÑка, зачекайте хвилину."
@@ -38389,6 +38747,9 @@ msgstr "Ви не можете імітувати внутрішнього коÑ
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr "Зараз ви не можете запуÑтити цей запланований конвеєр. Будь лаÑка, почекайте хвилину."
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr "Ви не можете запиÑувати на вторинні інÑтанÑи \"тільки Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ\" GitLab Geo. Будь лаÑка викориÑтовуйте %{link_to_primary_node}."
@@ -38533,7 +38894,7 @@ msgstr "Ви доÑÑгли Ñвого ліміту по кількоÑÑ‚Ñ– пр
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38555,7 +38916,7 @@ msgid "You must have developer or higher permissions in the associated project t
msgstr ""
msgid "You must have maintainer access to force delete a lock"
-msgstr "Ви повинні мати доÑтуп керівника Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÑƒÑового Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð±Ð»Ð¾ÐºÑƒÐ²Ð°Ð½Ð½Ñ "
+msgstr "Ви повинні мати доÑтуп керівника Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÑƒÑового Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð±Ð»Ð¾ÐºÑƒÐ²Ð°Ð½Ð½Ñ"
msgid "You must have permission to create a project in a group before forking."
msgstr ""
@@ -38582,7 +38943,7 @@ msgid "You need git-lfs version %{min_git_lfs_version} (or greater) to continue.
msgstr "Вам потрібна верÑÑ–Ñ git-lfs верÑÑ–Ñ— %{min_git_lfs_version} (або новіша), щоб продовжити. Будь лаÑка, відвідайте Ñторінку https://git-lfs.github.com"
msgid "You need permission."
-msgstr "Вам потрібен дозвіл"
+msgstr "Вам потрібен дозвіл."
msgid "You need to register a two-factor authentication app before you can set up a device."
msgstr ""
@@ -38959,7 +39320,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38989,6 +39350,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr "Zoom-зуÑтріч додано"
@@ -39095,6 +39480,13 @@ msgstr ""
msgid "blocks"
msgstr "блокує"
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "branch name"
msgstr "ім'Ñ Ð³Ñ–Ð»ÐºÐ¸"
@@ -39218,12 +39610,12 @@ msgstr ""
msgid "ciReport|All projects"
msgstr "Ð’ÑÑ– проєкти"
-msgid "ciReport|All scanners"
-msgstr "Ð’ÑÑ– Ñканери"
-
msgid "ciReport|All severities"
msgstr "Ð’ÑÑ– рівні"
+msgid "ciReport|All tools"
+msgstr ""
+
msgid "ciReport|Automatically apply the patch in a new branch"
msgstr "Ðвтоматично заÑтоÑувати патч у новій гілці"
@@ -39582,6 +39974,9 @@ msgstr "елементи не можуть бути порожніми"
msgid "entries cannot contain HTML tags"
msgstr "елементи не можуть міÑтити тегів HTML"
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr "епік"
@@ -39771,9 +40166,6 @@ msgstr "не дозволено. Спробуйте ще раз з іншою а
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr "не Ñ” адреÑою електронної пошти, Ñкою ви володієте"
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39991,8 +40383,12 @@ msgstr "Закриті"
msgid "mrWidget|Closed by"
msgstr "Закритий"
-msgid "mrWidget|Closes"
-msgstr "Закриває"
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
msgid "mrWidget|Delete source branch"
msgstr "Видалити гілку-джерело"
@@ -40027,8 +40423,12 @@ msgstr "Позначити Ñк готове"
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr "Згадки"
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
msgid "mrWidget|Merge"
msgstr "ЗлиттÑ"
@@ -40075,6 +40475,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr "Детальніше"
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr "Відкрити у Web IDE"
@@ -40138,9 +40541,6 @@ msgstr "Зміни будуть злиті в"
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr "HEAD гілки-джерела нещодавно було змінено. Будь лаÑка оновіть Ñторінку Ñ– переглÑньте зміни перед злиттÑм"
-
msgid "mrWidget|The source branch has been deleted"
msgstr "Гілку-джерело видалено"
@@ -40180,9 +40580,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr "Ви не можете безпоÑередньо редагувати цей проєкт. Будь лаÑка, зробіть форк, щоб внеÑти зміни."
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -40210,12 +40607,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr "повинна бути пізніша за дату початку"
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
@@ -40444,7 +40847,7 @@ msgid "reset it."
msgstr "Ñкинути його."
msgid "satisfied"
-msgstr ""
+msgstr "задоволено"
msgid "scan-execution-policy: policy not applied, %{policy_path} file is invalid"
msgstr ""
diff --git a/locale/ur_PK/gitlab.po b/locale/ur_PK/gitlab.po
index db226a0dbcc..392a9f3a524 100644
--- a/locale/ur_PK/gitlab.po
+++ b/locale/ur_PK/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ur-PK\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:12\n"
+"PO-Revision-Date: 2021-09-01 22:30\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/uz_UZ/gitlab.po b/locale/uz_UZ/gitlab.po
index 9d28ae5bbfa..324d9f79a54 100644
--- a/locale/uz_UZ/gitlab.po
+++ b/locale/uz_UZ/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: uz\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:20\n"
+"PO-Revision-Date: 2021-09-01 22:31\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -370,6 +370,11 @@ msgid_plural "%d tags per image name"
msgstr[0] ""
msgstr[1] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -517,6 +522,9 @@ msgstr[1] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -655,9 +663,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -667,6 +672,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -830,6 +838,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1252,7 +1263,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgstr[1] ""
@@ -1528,10 +1539,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1558,10 +1569,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2338,7 +2349,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2566,12 +2577,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2638,6 +2643,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2701,6 +2709,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2767,7 +2781,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3612,9 +3626,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3630,9 +3641,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3687,6 +3695,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4158,7 +4172,7 @@ msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCoun
msgstr[0] ""
msgstr[1] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4167,9 +4181,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4197,6 +4217,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4209,6 +4232,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4218,19 +4247,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4341,6 +4376,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4499,9 +4537,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4618,9 +4653,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4737,6 +4769,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4914,6 +4952,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5106,9 +5147,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5393,9 +5431,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5408,12 +5443,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5475,9 +5516,6 @@ msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
msgstr[1] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5778,30 +5816,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5856,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -6005,6 +6040,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6488,12 +6526,17 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6503,15 +6546,17 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6527,7 +6572,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7136,6 +7181,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7151,9 +7199,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7835,7 +7880,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8317,9 +8362,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8458,9 +8500,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8473,6 +8512,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9193,7 +9235,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10430,6 +10472,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10442,6 +10487,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10454,12 +10502,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10477,6 +10531,9 @@ msgid_plural "DastSiteValidation|This will affect %d other profiles targeting th
msgstr[0] ""
msgstr[1] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10609,9 +10666,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10681,6 +10735,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10729,9 +10786,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10756,6 +10819,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10774,6 +10840,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10951,10 +11020,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -11002,6 +11071,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11430,6 +11511,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11490,7 +11577,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11999,6 +12086,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -12074,6 +12164,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12281,9 +12374,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12332,6 +12422,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12371,6 +12464,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12725,6 +12821,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12737,6 +12836,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12812,6 +12914,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12833,6 +12938,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13169,6 +13280,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14540,6 +14654,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14627,6 +14744,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14759,10 +14879,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14807,7 +14927,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14828,9 +14948,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14885,19 +15002,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14942,7 +15056,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14954,6 +15068,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14978,10 +15095,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -15053,7 +15170,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -15098,6 +15215,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15152,9 +15272,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15404,6 +15521,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15485,7 +15605,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15836,6 +15956,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15848,6 +15974,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15881,7 +16010,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16409,10 +16538,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16545,6 +16674,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16683,7 +16815,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16971,6 +17103,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17730,6 +17865,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17739,6 +17880,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17828,6 +17975,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17948,6 +18098,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -18137,9 +18290,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18677,6 +18827,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19370,9 +19523,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19495,9 +19645,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19516,6 +19663,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19957,10 +20107,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20469,6 +20622,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20517,6 +20673,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20535,6 +20694,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20547,7 +20709,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20562,9 +20724,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20598,6 +20766,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20622,6 +20796,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20661,6 +20838,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20829,6 +21009,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20946,9 +21129,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20961,9 +21141,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21445,9 +21622,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21826,7 +22000,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -22017,12 +22191,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -22065,9 +22233,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -22077,21 +22242,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -22107,9 +22263,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22256,9 +22409,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22442,6 +22592,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22963,6 +23116,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -23092,7 +23248,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23388,7 +23544,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23580,6 +23736,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24717,6 +24876,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -25158,13 +25362,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25176,9 +25377,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25443,6 +25641,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25635,9 +25836,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26736,9 +26934,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26790,6 +26985,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26829,9 +27027,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27333,6 +27528,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27402,6 +27603,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27515,6 +27719,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -28029,6 +28236,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28476,6 +28686,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28745,6 +28958,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28808,6 +29024,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29274,9 +29493,6 @@ msgstr[1] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29328,7 +29544,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29364,7 +29580,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29478,55 +29694,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29565,9 +29850,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29679,9 +29961,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29748,6 +30027,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30321,7 +30603,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30369,7 +30651,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30570,9 +30852,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30796,6 +31075,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -31147,6 +31429,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32618,6 +32909,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32669,12 +32963,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32687,7 +32987,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32912,7 +33212,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -33130,6 +33430,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -33166,9 +33469,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33322,6 +33622,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33460,9 +33763,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33508,6 +33817,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33688,9 +34000,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33910,9 +34219,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33985,6 +34291,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -35030,13 +35339,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35599,6 +35914,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35818,9 +36136,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35839,9 +36154,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35890,6 +36211,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -36046,6 +36370,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36523,9 +36850,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36722,6 +37055,11 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36980,9 +37318,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36995,6 +37330,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -37100,6 +37438,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37355,6 +37696,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37414,6 +37758,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37972,6 +38319,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37987,6 +38337,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -38131,7 +38484,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38557,7 +38910,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38587,6 +38940,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38691,6 +39068,11 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "branch name"
msgstr ""
@@ -38814,10 +39196,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -39170,6 +39552,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39353,9 +39738,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39571,8 +39953,10 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39607,8 +39991,10 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
+msgstr[1] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39655,6 +40041,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39718,9 +40107,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39760,9 +40146,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39790,12 +40173,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/vi_VN/gitlab.po b/locale/vi_VN/gitlab.po
index 6e89dd6fafa..9a748d881ad 100644
--- a/locale/vi_VN/gitlab.po
+++ b/locale/vi_VN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: vi\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:12\n"
+"PO-Revision-Date: 2021-09-01 22:30\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -313,6 +313,10 @@ msgid "%d tag per image name"
msgid_plural "%d tags per image name"
msgstr[0] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -445,6 +449,9 @@ msgstr[0] ""
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -583,9 +590,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -595,6 +599,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -756,6 +763,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1152,7 +1162,7 @@ msgid_plural "%d issues selected"
msgstr[0] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgid "1 merged merge request"
@@ -1417,10 +1427,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1447,10 +1457,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2227,7 +2237,7 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
@@ -2455,12 +2465,6 @@ msgstr ""
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2527,6 +2531,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2590,6 +2597,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2656,7 +2669,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3500,9 +3513,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3518,9 +3528,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr ""
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3575,6 +3582,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4040,7 +4053,7 @@ msgid "ApprovalRuleSummary|%{count} approval required from %{membersCount}"
msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCount}"
msgstr[0] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4049,9 +4062,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4079,6 +4098,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4091,6 +4113,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4100,19 +4128,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
+msgstr ""
+
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4223,6 +4257,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4380,9 +4417,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4498,9 +4532,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4616,6 +4647,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4793,6 +4830,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -4985,9 +5025,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5271,9 +5308,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5286,12 +5320,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5351,9 +5391,6 @@ msgid "Boards|Blocked by %{blockedByCount} %{issuableType}"
msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5654,30 +5691,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5732,6 +5763,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -5880,6 +5914,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6363,12 +6400,16 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6378,15 +6419,16 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6402,7 +6444,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7011,6 +7053,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7026,9 +7071,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7710,7 +7752,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8191,9 +8233,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8332,9 +8371,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8347,6 +8383,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9064,7 +9103,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10299,6 +10338,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10311,6 +10353,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10323,12 +10368,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10345,6 +10396,9 @@ msgid "DastSiteValidation|This will affect %d other profile targeting the same U
msgid_plural "DastSiteValidation|This will affect %d other profiles targeting the same URL."
msgstr[0] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10477,9 +10531,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10549,6 +10600,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10597,9 +10651,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10624,6 +10684,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10642,6 +10705,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10816,10 +10882,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -10864,6 +10930,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11291,6 +11369,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11351,7 +11435,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11859,6 +11943,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -11934,6 +12021,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12141,9 +12231,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12192,6 +12279,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12231,6 +12321,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12585,6 +12678,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12597,6 +12693,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12672,6 +12771,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12693,6 +12795,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13029,6 +13137,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14397,6 +14508,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14484,6 +14598,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14616,10 +14733,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14664,7 +14781,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14685,9 +14802,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14742,19 +14856,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14799,7 +14910,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14811,6 +14922,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14835,10 +14949,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -14910,7 +15024,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -14955,6 +15069,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15009,9 +15126,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15261,6 +15375,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15342,7 +15459,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15693,6 +15810,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15705,6 +15828,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15738,7 +15864,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16266,10 +16392,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16400,6 +16526,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16538,7 +16667,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16823,6 +16952,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17582,6 +17714,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17591,6 +17729,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17679,6 +17823,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17799,6 +17946,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -17988,9 +18138,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18528,6 +18675,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19221,9 +19371,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19345,9 +19492,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19366,6 +19510,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19801,10 +19948,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20312,6 +20462,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20360,6 +20513,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20378,6 +20534,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20390,7 +20549,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20405,9 +20564,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20441,6 +20606,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20465,6 +20636,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20504,6 +20678,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20672,6 +20849,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20789,9 +20969,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20804,9 +20981,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21286,9 +21460,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21667,7 +21838,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -21857,12 +22028,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -21905,9 +22070,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -21917,21 +22079,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -21947,9 +22100,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22095,9 +22245,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22281,6 +22428,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22798,6 +22948,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -22927,7 +23080,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23222,7 +23375,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23414,6 +23567,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24551,6 +24707,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -24992,13 +25193,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25010,9 +25208,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25277,6 +25472,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25469,9 +25667,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26570,9 +26765,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26624,6 +26816,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26663,9 +26858,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27167,6 +27359,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27236,6 +27434,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27348,6 +27549,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -27857,6 +28061,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28301,6 +28508,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28569,6 +28779,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28632,6 +28845,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29087,9 +29303,6 @@ msgstr[0] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29141,7 +29354,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29177,7 +29390,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29291,55 +29504,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityPolicies|Environment(s)"
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29378,9 +29660,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29492,9 +29771,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29561,6 +29837,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30134,7 +30413,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30182,7 +30461,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30383,9 +30662,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30607,6 +30883,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -30958,6 +31237,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32427,6 +32715,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32478,12 +32769,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32496,7 +32793,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32718,7 +33015,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -32935,6 +33232,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -32971,9 +33271,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33127,6 +33424,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33265,9 +33565,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33313,6 +33619,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33493,9 +33802,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33715,9 +34021,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33790,6 +34093,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -34833,13 +35139,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35401,6 +35713,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35620,9 +35935,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35641,9 +35953,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35692,6 +36010,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -35848,6 +36169,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36325,9 +36649,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36522,6 +36852,10 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36780,9 +37114,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36795,6 +37126,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -36900,6 +37234,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37155,6 +37492,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37213,6 +37553,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37771,6 +38114,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37786,6 +38132,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -37930,7 +38279,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38356,7 +38705,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38386,6 +38735,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38489,6 +38862,10 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+
msgid "branch name"
msgstr ""
@@ -38612,10 +38989,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -38964,6 +39341,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39144,9 +39524,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39361,8 +39738,9 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39397,8 +39775,9 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39445,6 +39824,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39508,9 +39890,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39550,9 +39929,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39580,12 +39956,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/zh_CN/gitlab.po b/locale/zh_CN/gitlab.po
index 46bc3f99089..5a011c2be95 100644
--- a/locale/zh_CN/gitlab.po
+++ b/locale/zh_CN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: zh-CN\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:17\n"
+"PO-Revision-Date: 2021-09-01 22:31\n"
msgid " %{name}, confirm your email address now! "
msgstr " %{name},现在确认您的电å­é‚®ä»¶åœ°å€ï¼ "
@@ -76,7 +76,7 @@ msgid " or references (e.g. path/to/project!merge_request_id)"
msgstr "或引用 (例如: path/to/project!merge_request_id)"
msgid " reacted with :%{name}:"
-msgstr ""
+msgstr " 回应为:%{name}:"
msgid "\"%{path}\" did not exist on \"%{ref}\""
msgstr "“%{ref}â€ä¸Šä¸å­˜åœ¨â€œ%{path}â€"
@@ -313,6 +313,10 @@ msgid "%d tag per image name"
msgid_plural "%d tags per image name"
msgstr[0] "æ¯ä¸ªé•œåƒå称有%d个标签"
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] "%d个未分é…的议题"
@@ -378,10 +382,10 @@ msgid_plural "%{bold_start}%{count}%{bold_end} opened merge requests"
msgstr[0] "%{bold_start}%{count}%{bold_end} 个开放中的åˆå¹¶è¯·æ±‚"
msgid "%{code_open}Masked:%{code_close} Hidden in job logs. Must match masking requirements."
-msgstr ""
+msgstr "%{code_open}éšè—:%{code_close} éšè—在作业日志中。必须符åˆéšè—è¦æ±‚。"
msgid "%{code_open}Protected:%{code_close} Only exposed to protected branches or tags."
-msgstr ""
+msgstr "%{code_open}å—ä¿æŠ¤ï¼š%{code_close} 仅暴露于å—ä¿æŠ¤çš„分支或标签。"
msgid "%{commit_author_link} authored %{commit_timeago}"
msgstr "由%{commit_author_link}编写于%{commit_timeago}"
@@ -391,7 +395,7 @@ msgstr "%{completedCount}已完æˆæƒé‡"
msgid "%{completedCount} of %{count} task completed"
msgid_plural "%{completedCount} of %{count} tasks completed"
-msgstr[0] ""
+msgstr[0] "%{completedCount}/%{count} 任务已完æˆ"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr "总æƒé‡%{totalWeight}中的%{completedWeight}已完æˆ"
@@ -445,6 +449,9 @@ msgstr[0] "%{count}ä½å‚与者"
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr "%{count}个相关的%{pluralized_subject}: %{links}"
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr "总æƒé‡%{count}"
@@ -503,7 +510,7 @@ msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
msgstr "%{firstMilestoneName} + 其余%{numberOfOtherMilestones}项"
msgid "%{gitlab_experience_text}. Don't worry, this information isn't shared outside of your self-managed GitLab instance."
-msgstr ""
+msgstr "%{gitlab_experience_text}。别担心,此信æ¯ä¸ä¼šåœ¨æ‚¨è‡ªå·±ç®¡ç†çš„ GitLab 实例之外共享。"
msgid "%{gitlab_experience_text}. We won't share this information with anyone."
msgstr "%{gitlab_experience_text}。我们ä¸ä¼šä¸Žä»»ä½•äººåˆ†äº«è¿™ä¸ªä¿¡æ¯ã€‚"
@@ -512,7 +519,7 @@ msgid "%{global_id} is not a valid ID for %{expected_types}."
msgstr "%{global_id} ä¸æ˜¯ %{expected_types} 的有效ID。"
msgid "%{group_name} activity"
-msgstr ""
+msgstr "%{group_name} 动æ€"
msgid "%{group_name} group members"
msgstr "%{group_name}群组æˆå‘˜"
@@ -521,7 +528,7 @@ msgid "%{group_name} uses group managed accounts. You need to create a new GitLa
msgstr "%{group_name}使用由群组托管å¸æˆ·ã€‚您需è¦åˆ›å»ºä¸€ä¸ªæ–°çš„GitLabå¸æˆ·ï¼Œè¯¥å¸æˆ·å°†é€šè¿‡%{group_name}组æ¥ç®¡ç†ã€‚"
msgid "%{group_name}&%{epic_iid} &middot; created %{epic_created} by %{author}"
-msgstr ""
+msgstr "%{group_name}&%{epic_iid} &middot; %{epic_created}由%{author}创建"
msgid "%{hook_type} was deleted"
msgstr "%{hook_type}已删除"
@@ -548,7 +555,7 @@ msgid "%{issuesSize} with a limit of %{maxIssueCount}"
msgstr "%{issuesSize}个,上é™ä¸º%{maxIssueCount}"
msgid "%{italic_start}What's new%{italic_end} is inactive and cannot be viewed."
-msgstr ""
+msgstr "%{italic_start}新增功能%{italic_end} 处于未激活状æ€ä¸”无法查看。"
msgid "%{itemsCount} issues with a limit of %{maxIssueCount}"
msgstr "%{itemsCount}个议题,上é™ä¸º%{maxIssueCount}"
@@ -583,9 +590,6 @@ msgstr "%{labelStart}方法: %{labelEnd}%{method}"
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr "%{labelStart}命å空间: %{labelEnd}%{namespace}"
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr "%{labelStart}扫æ类型: %{labelEnd}%{reportType}"
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr "%{labelStart}扫æ工具:%{labelEnd} %{scanner}"
@@ -595,6 +599,9 @@ msgstr "%{labelStart}å‘é€è¯·æ±‚:%{labelEnd} %{headers}"
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr "%{labelStart}严é‡ç¨‹åº¦ :%{labelEnd}%{severity}"
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr "%{labelStart}未修改的å“应:%{labelEnd} %{headers}"
@@ -602,7 +609,7 @@ msgid "%{label_for_message} unavailable"
msgstr "%{label_for_message}ä¸å¯ç”¨"
msgid "%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} is a free, automated, and open certificate authority (CA) that issues digital certificates to enable HTTPS (SSL/TLS) for sites."
-msgstr ""
+msgstr "%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} 是一个å…费的ã€è‡ªåŠ¨åŒ–çš„ã€å¼€æ”¾çš„è¯ä¹¦é¢å‘机构(CA),æ供数字è¯ä¹¦ï¼Œä»¥ä¾¿ä¸ºç½‘ç«™å¯ç”¨ HTTPS(SSL / TLS)。"
msgid "%{level_name} is not allowed in a %{group_level_name} group."
msgstr "%{level_name} ä¸å…许在 %{group_level_name} 组。"
@@ -611,19 +618,19 @@ msgid "%{level_name} is not allowed since the fork source project has lower visi
msgstr "由于派生的æºé¡¹ç›®å¯è§æ€§è¾ƒä½Žï¼Œå› æ­¤ä¸å…许使用%{level_name}。"
msgid "%{link_start}Learn more%{link_end} about roles."
-msgstr ""
+msgstr "%{link_start}查看更多%{link_end} 关于角色的信æ¯ã€‚"
msgid "%{link_start}Learn more%{link_end} about what information is shared with GitLab Inc."
msgstr "%{link_start}了解更多%{link_end}哪些信æ¯ä¼šåˆ†äº«ç»™GitLab Inc.。"
msgid "%{link_start}Remove the %{draft_snippet} prefix%{link_end} from the title to allow this merge request to be merged when it's ready."
-msgstr ""
+msgstr "%{link_start}从标题中删除%{draft_snippet}å‰ç¼€%{link_end},å…许此åˆå¹¶è¯·æ±‚在准备就绪时被åˆå¹¶ã€‚"
msgid "%{link_start}Start the title with %{draft_snippet}%{link_end} to prevent a merge request that is a work in progress from being merged before it's ready."
-msgstr ""
+msgstr "%{link_start}以%{draft_snippet}作为标题的开头%{link_end} ,以防止正在工作进程中的åˆå¹¶è¯·æ±‚在准备就绪之å‰è¢«åˆå¹¶ã€‚"
msgid "%{listToShow}, and %{awardsListLength} more"
-msgstr ""
+msgstr "%{listToShow},还有 %{awardsListLength} 个。"
msgid "%{location} is missing required keys: %{keys}"
msgstr "%{location}缺少必需的键: %{keys}"
@@ -653,10 +660,10 @@ msgid "%{mrText}, this issue will be closed automatically."
msgstr "%{mrText},此议题将自动关闭。"
msgid "%{name_with_link} namespace has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
-msgstr ""
+msgstr "%{name_with_link}当å‰å‰©ä½™%{percent}或更少的共享 Runner æµæ°´çº¿åˆ†é’Ÿæ•°ã€‚一旦用完,其下项目将无法è¿è¡Œæ–°çš„作业或æµæ°´çº¿ã€‚"
msgid "%{name_with_link} namespace has run out of Shared Runner Pipeline minutes. No new jobs or pipelines in its projects will run."
-msgstr ""
+msgstr "%{name_with_link}的共享 Runner æµæ°´çº¿åˆ†é’Ÿæ•°å·²ç”¨å®Œï¼Œå…¶ä¸‹é¡¹ç›®å°†æ— æ³•è¿è¡Œæ–°çš„作业或æµæ°´çº¿ã€‚"
msgid "%{name} (Busy)"
msgstr "%{name} (忙碌中)"
@@ -677,13 +684,13 @@ msgid "%{name}'s avatar"
msgstr "%{name} 的头åƒ"
msgid "%{name}(%{url}) namespace has %{percent} or less Shared Runner Pipeline minutes remaining. After it runs out, no new jobs or pipelines in its projects will run."
-msgstr ""
+msgstr "%{name}(%{url})当å‰å‰©ä½™%{percent}或更少的共享 Runner æµæ°´çº¿åˆ†é’Ÿæ•°ã€‚一旦用完,其下项目将无法è¿è¡Œæ–°çš„作业或æµæ°´çº¿ã€‚"
msgid "%{name}(%{url}) namespace has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
-msgstr ""
+msgstr "%{name}(%{url})的共享 Runner æµæ°´çº¿åˆ†é’Ÿæ•°å·²ç”¨å®Œï¼Œå…¶ä¸‹é¡¹ç›®å°†æ— æ³•è¿è¡Œæ–°çš„作业或æµæ°´çº¿ã€‚"
msgid "%{name}, confirm your email address now!"
-msgstr ""
+msgstr "%{name},请确认您的电å­é‚®ä»¶åœ°å€ï¼"
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
@@ -751,9 +758,12 @@ msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}att
msgstr "%{retryButtonStart}é‡è¯•%{retryButtonEnd}或%{newFileButtonStart}添加新文件%{newFileButtonEnd}。"
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation_link}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
-msgstr ""
+msgstr "%{rotation} 已与其余å‚与者é‡æ–°è®¡ç®—。请审查 %{rotation_link} 的新设置。建议您与目å‰çš„on-call人员å–å¾—è”系,以确ä¿on-call工作的连续性。"
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr "%{rotation} 已与其余å‚与者é‡æ–°è®¡ç®—。请审查 %{rotation} 的新设置。建议您与目å‰çš„on-call人员å–å¾—è”系,以确ä¿on-call工作的连续性。"
+
+msgid "%{scope} results for term '%{term}'"
msgstr ""
msgid "%{seconds}s"
@@ -902,13 +912,13 @@ msgid "%{userName}'s avatar"
msgstr "%{userName} 的头åƒ"
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
-msgstr ""
+msgstr "%{user_name}(%{user_username})已从%{project}项目中的%{schedule}计划中的%{rotation} è½®æ¢ä¸­åˆ é™¤ 。 "
msgid "%{user_name} profile page"
msgstr "%{user_name}的个人资料"
msgid "%{username} changed the draft status of merge request %{mr_link}"
-msgstr ""
+msgstr "%{username} 更改了åˆå¹¶è¯·æ±‚%{mr_link}çš„è‰ç¨¿çŠ¶æ€"
msgid "%{username} has asked for a GitLab account on your instance %{host}:"
msgstr "%{username}请求在您的实例 %{host}创建一个GitLab å¸æˆ·ï¼š"
@@ -917,16 +927,16 @@ msgid "%{username}'s avatar"
msgstr "%{username} 的头åƒ"
msgid "%{user} created a merge request: %{mr_link}"
-msgstr ""
+msgstr "%{user} 创建了åˆå¹¶è¯·æ±‚:%{mr_link}"
msgid "%{user} created an epic: %{epic_link}"
-msgstr ""
+msgstr "%{user} 创建了一个å²è¯—:%{epic_link}"
msgid "%{user} created an issue: %{issue_link}"
-msgstr ""
+msgstr "%{user} 创建了一个议题:%{issue_link}"
msgid "%{value} is not included in the list"
-msgstr ""
+msgstr "列表中ä¸åŒ…å«%{value}"
msgid "%{value} s"
msgstr "%{value}秒"
@@ -941,7 +951,7 @@ msgid "%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notif
msgstr "%{webhooks_link_start}%{webhook_type}%{link_end}å…许您针对æŸä¸ªç¾¤ç»„或项目中的事件å‘é€é€šçŸ¥åˆ°web应用程åºã€‚ 如需使用webhook, 我们推è优先使用已有%{integrations_link_start}集æˆ%{link_end}。"
msgid "%{wildcards_link_start}Wildcards%{wildcards_link_end} such as %{code_tag_start}v*%{code_tag_end} or %{code_tag_start}*-release%{code_tag_end} are supported."
-msgstr ""
+msgstr "支æŒ%{wildcards_link_start}通é…符%{wildcards_link_end} ,例如 %{code_tag_start}v *%{code_tag_end} 或 %{code_tag_start}* -release%{code_tag_end}。"
msgid "&lt; 1 hour"
msgstr "&lt; 1å°æ—¶"
@@ -974,7 +984,7 @@ msgid "'%{name}' Value Stream deleted"
msgstr "“%{name}â€ä»·å€¼æµå·²åˆ é™¤"
msgid "'%{name}' Value Stream saved"
-msgstr ""
+msgstr "'%{name}'价值æµå·²ä¿å­˜"
msgid "'%{source}' is not a import source"
msgstr "'%{source}'ä¸æ˜¯ä¸€ä¸ªå¯¼å…¥æº"
@@ -1011,7 +1021,7 @@ msgid "(deleted)"
msgstr "(已删除)"
msgid "(expired)"
-msgstr ""
+msgstr "(已过期)"
msgid "(leave blank if you don't want to change it)"
msgstr "(如果您ä¸æƒ³æ›´æ”¹ï¼Œè¯·ç•™ç©º)"
@@ -1051,7 +1061,7 @@ msgid "+%{approvers} more approvers"
msgstr "+å¦å¤–%{approvers}个核准人"
msgid "+%{extra} more"
-msgstr ""
+msgstr "+%{extra} 更多"
msgid "+%{more_assignees_count}"
msgstr "+%{more_assignees_count}"
@@ -1125,11 +1135,11 @@ msgstr[0] "%d天"
msgid "1 day remaining"
msgid_plural "%d days remaining"
-msgstr[0] ""
+msgstr[0] "剩余%d天"
msgid "1 day selected"
msgid_plural "%d days selected"
-msgstr[0] ""
+msgstr[0] "已选择 %d 天"
msgid "1 deploy key"
msgid_plural "%d deploy keys"
@@ -1137,7 +1147,7 @@ msgstr[0] "%d个部署密钥"
msgid "1 follower"
msgid_plural "%{count} followers"
-msgstr[0] ""
+msgstr[0] "%{count} ä½å…³æ³¨è€…"
msgid "1 group"
msgid_plural "%d groups"
@@ -1149,11 +1159,11 @@ msgstr[0] "%då°æ—¶"
msgid "1 issue selected"
msgid_plural "%d issues selected"
-msgstr[0] ""
+msgstr[0] "已选择 %d 个问题"
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
-msgstr[0] ""
+msgid_plural "%d merge requests selected"
+msgstr[0] "%d 个åˆå¹¶è¯·æ±‚已选择"
msgid "1 merged merge request"
msgid_plural "%{merge_requests} merged merge requests"
@@ -1283,7 +1293,7 @@ msgid "A Let's Encrypt SSL certificate can not be obtained until your domain is
msgstr "验è¯ä½ çš„域å之å‰ï¼Œæˆ‘ä»¬æ— æ³•èŽ·å– Encrype SSL è¯ä¹¦ã€‚"
msgid "A Metrics Dashboard menu item appears in the Monitoring section of the Admin Area."
-msgstr ""
+msgstr "指标仪表盘èœå•é¡¹åœ¨ç®¡ç†ä¸­å¿ƒçš„监控部分。"
msgid "A basic page and serverless function that uses AWS Lambda, AWS API Gateway, and GitLab Pages"
msgstr "使用AWS Lambda,AWS API网关和GitLab Pages的基本页é¢å’Œæ— æœåŠ¡å™¨åŠŸèƒ½"
@@ -1301,10 +1311,10 @@ msgid "A deleted user"
msgstr "已删除的用户"
msgid "A description is required"
-msgstr ""
+msgstr "需è¦æè¿°"
msgid "A different reason"
-msgstr ""
+msgstr "一个ä¸åŒçš„原因"
msgid "A file has been changed."
msgstr "文件已更改。"
@@ -1322,13 +1332,13 @@ msgid "A group represents your organization in GitLab. Groups allow you to manag
msgstr "群组在GitLab中代表您的组织。群组å¯ä»¥ç”¨æ¥ç®¡ç†ç”¨æˆ·å¹¶åœ¨è¿›è¡Œè·¨é¡¹ç›®åˆä½œã€‚"
msgid "A job artifact is an archive of files and directories saved by a job when it finishes."
-msgstr ""
+msgstr "作业产物是作业完æˆåŽä¿å­˜çš„文件和目录的归档。"
msgid "A limit of %{ci_project_subscriptions_limit} subscriptions to or from a project applies."
-msgstr ""
+msgstr "项目应用的订阅和被订阅数é‡ä¸Šé™ä¸º %{ci_project_subscriptions_limit}。"
msgid "A management, operational, or technical control (that is, safeguard or countermeasure) employed by an organization that provides equivalent or comparable protection for an information system."
-msgstr ""
+msgstr "为信æ¯ç³»ç»Ÿæä¾›åŒç­‰æˆ–类似ä¿æŠ¤çš„组织所采用的管ç†ï¼Œæ“作或技术控制(å³ï¼Œä¿æŠ¤æŽªæ–½æˆ–对策)。"
msgid "A member of the abuse team will review your report as soon as possible."
msgstr "GitLab滥用审查团队æˆå‘˜å°†ä¼šå°½å¿«æŸ¥çœ‹æ‚¨çš„报告。"
@@ -1364,19 +1374,19 @@ msgid "A platform value can be web, mob or app."
msgstr "å¹³å°å€¼å¯ä»¥æ˜¯web, mob或app。"
msgid "A project boilerplate for Salesforce App development with Salesforce Developer tools"
-msgstr ""
+msgstr "使用 Salesforce Developer å·¥å…·å¼€å‘ Salesforce App 的项目样æ¿"
msgid "A project containing issues for each audit inquiry in the HIPAA Audit Protocol published by the U.S. Department of Health & Human Services"
msgstr "项目包å«ç¾Žå›½å«ç”Ÿä¸Žå…¬å…±æœåŠ¡éƒ¨å‘布的HIPAA审计å议中æ¯ä¸ªå®¡è®¡æŸ¥è¯¢çš„议题"
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "一个项目的仓库å称定义了它的URL(用æ¥é€šè¿‡æµè§ˆå™¨è®¿é—®é¡¹ç›®ï¼‰ä»¥åŠå®ƒåœ¨å®‰è£…GitLab 的文件ç£ç›˜ä¸Šçš„ä½ç½®ã€‚ %{link_start}了解更多。%{link_end}"
msgid "A ready-to-go template for use with Android apps"
-msgstr ""
+msgstr "适用于 Android 应用的éšæ—¶å¯ç”¨çš„模æ¿"
msgid "A ready-to-go template for use with iOS Swift apps"
-msgstr ""
+msgstr "适用于 iOS Swift 应用的éšæ—¶å¯ç”¨çš„模æ¿"
msgid "A rebase is already in progress."
msgstr "å˜åŸº(rebase)正在进行中"
@@ -1403,7 +1413,7 @@ msgid "API Fuzzing"
msgstr "API模糊测试"
msgid "API Fuzzing Configuration"
-msgstr ""
+msgstr "API 模糊é…ç½®"
msgid "API Help"
msgstr "API帮助"
@@ -1417,56 +1427,56 @@ msgstr "API密钥"
msgid "API?"
msgstr "API?"
-msgid "APIFuzzing|$VariableWithPassword"
-msgstr "$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
+msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
-msgstr "$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
+msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
msgstr "API Fuzzingé…ç½®"
msgid "APIFuzzing|Base URL of API testing target. For example, http://www.example.com."
-msgstr ""
+msgstr "API测试目标的基础URL。例如,http://www.example.com。"
msgid "APIFuzzing|Choose a method"
-msgstr ""
+msgstr "选择一ç§æ–¹æ³•"
msgid "APIFuzzing|Choose a profile"
msgstr "选择一个é…置文件"
msgid "APIFuzzing|Code snippet could not be generated. Try again later."
-msgstr ""
+msgstr "无法生æˆä»£ç ç‰‡æ–­ã€‚请ç¨åŽå†è¯•ã€‚"
msgid "APIFuzzing|Configure HTTP basic authentication values. Other authentication methods are supported. %{linkStart}Learn more%{linkEnd}."
-msgstr ""
+msgstr "é…ç½®HTTP基本身份验è¯å€¼ã€‚支æŒå…¶å®ƒèº«ä»½éªŒè¯æ–¹æ³•ã€‚ %{linkStart}了解更多%{linkEnd}。"
msgid "APIFuzzing|Customize common API fuzzing settings to suit your requirements. For details of more advanced configuration options, see the %{docsLinkStart}GitLab API Fuzzing documentation%{docsLinkEnd}."
-msgstr ""
+msgstr "自定义常è§çš„API模糊设置以适åˆæ‚¨çš„è¦æ±‚。有关更多高级é…置选项的详细信æ¯ï¼Œè¯·å‚è§ %{docsLinkStart}GitLab API Fuzzing文档%{docsLinkEnd}。"
msgid "APIFuzzing|Enable authentication"
msgstr "å¯ç”¨èº«ä»½éªŒè¯"
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
-msgstr "输入包å«å¯†ç çš„å˜é‡çš„å称。例如, $VariableWithPassword。"
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
+msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
-msgstr "输入包å«ç”¨æˆ·åçš„å˜é‡çš„å称。例如, $VariableWithUsername。"
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
+msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
-msgstr ""
+msgstr "è¦æµ‹è¯•çš„ API 的文件路径或 URL。例如,folder/example_fuzz.har。 HAR 文件å¯èƒ½åŒ…å«æ•æ„Ÿä¿¡æ¯ï¼Œä¾‹å¦‚身份验è¯ä»¤ç‰Œã€API å¯†é’¥å’Œä¼šè¯ cookie。我们建议您在将 HAR 文件添加到仓库之å‰æŸ¥çœ‹å®ƒä»¬çš„内容。"
msgid "APIFuzzing|File path or URL to OpenAPI specification. For example, folder/openapi.json or http://www.example.com/openapi.json."
-msgstr ""
+msgstr "OpenAPI 规范的文件路径或 URL。例如,folder/openapi.json 或 http://www.example.com/openapi.json。"
msgid "APIFuzzing|File path or URL to requests to be tested. For example, folder/example.postman_collection.json."
-msgstr ""
+msgstr "请求测试的文件路径或 URL。例如,folder/example.postman_collection.json。"
msgid "APIFuzzing|Generate code snippet"
msgstr "生æˆä»£ç ç‰‡æ®µ"
msgid "APIFuzzing|Make sure your credentials are secured"
-msgstr ""
+msgstr "请确ä¿æ‚¨çš„凭æ®æ˜¯å®‰å…¨çš„"
msgid "APIFuzzing|Password for basic authentication"
msgstr "用于基本身份验è¯çš„密ç "
@@ -1481,7 +1491,7 @@ msgid "APIFuzzing|Scan profile"
msgstr "扫æé…置文件"
msgid "APIFuzzing|Show code snippet for the profile"
-msgstr ""
+msgstr "显示é…置文件的代ç ç‰‡æ®µ"
msgid "APIFuzzing|Target URL"
msgstr "目标 URL"
@@ -1490,37 +1500,37 @@ msgid "APIFuzzing|There are three ways to perform scans."
msgstr "执行扫æçš„æ–¹å¼æœ‰ä¸‰ç§ã€‚"
msgid "APIFuzzing|Tip: Insert the following variables anywhere below stages and include"
-msgstr ""
+msgstr "æ示:在 stages å’Œ include 下方的任æ„ä½ç½®æ’入以下å˜é‡"
msgid "APIFuzzing|Tip: Insert this part below all include"
-msgstr ""
+msgstr "æ示:在所有 include 下é¢æ’入这部分"
msgid "APIFuzzing|Tip: Insert this part below all stages"
-msgstr ""
+msgstr "æ示:在所有 stages 下é¢æ’入这部分"
msgid "APIFuzzing|To prevent a security leak, authentication info must be added as a %{ciVariablesLinkStart}CI variable%{ciVariablesLinkEnd}. A user with maintainer access rights can manage CI variables in the %{ciSettingsLinkStart}Settings%{ciSettingsLinkEnd} area. We detected that you are not a maintainer. Commit your changes and assign them to a maintainer to update the credentials before merging."
-msgstr ""
+msgstr "为了防止安全æ¼æ´žï¼Œèº«ä»½éªŒè¯ä¿¡æ¯å¿…须添加为 %{ciVariablesLinkStart}CI å˜é‡%{ciVariablesLinkEnd}。 拥有维护者访问æƒé™çš„用户å¯ä»¥åœ¨ %{ciSettingsLinkStart}设置%{ciSettingsLinkEnd} 区域管ç†CI å˜é‡ã€‚ 我们检测到您ä¸æ˜¯ç»´æŠ¤è€…。æ交您的更改并分é…给维护者在åˆå¹¶å‰æ›´æ–°å‡­è¯ã€‚"
msgid "APIFuzzing|To prevent a security leak, authentication info must be added as a %{ciVariablesLinkStart}CI variable%{ciVariablesLinkEnd}. As a user with maintainer access rights, you can manage CI variables in the %{ciSettingsLinkStart}Settings%{ciSettingsLinkEnd} area."
-msgstr ""
+msgstr "为了防止安全æ¼æ´žï¼Œèº«ä»½éªŒè¯ä¿¡æ¯å¿…须添加为 %{ciVariablesLinkStart}CI å˜é‡%{ciVariablesLinkEnd}。 拥有维护者访问æƒé™çš„用户å¯ä»¥åœ¨ %{ciSettingsLinkStart}设置%{ciSettingsLinkEnd} 区域管ç†CI å˜é‡ã€‚"
msgid "APIFuzzing|Use this tool to generate API fuzzing configuration YAML to copy into your .gitlab-ci.yml file. This tool does not reflect or update your .gitlab-ci.yml file automatically."
-msgstr ""
+msgstr "使用此工具生æˆAPI模糊é…ç½®YAML,以å¤åˆ¶åˆ°æ‚¨çš„.gitlab-ci.yml文件中。该工具ä¸ä¼šè‡ªåŠ¨å映或更新您的.gitlab-ci.yml文件。"
msgid "APIFuzzing|Username for basic authentication"
msgstr "用于基本身份验è¯çš„用户å"
msgid "APIFuzzing|You may need a maintainer's help to secure your credentials."
-msgstr ""
+msgstr "您å¯èƒ½éœ€è¦ç»´æŠ¤äººå‘˜çš„帮助æ¥ä¿æŠ¤æ‚¨çš„凭æ®ã€‚"
msgid "APIFuzzing|folder/example.postman_collection.json"
-msgstr ""
+msgstr "文件夹/example.postman_collection.json"
msgid "APIFuzzing|folder/example_fuzz.har"
-msgstr ""
+msgstr "文件夹/example_fuzz.har"
msgid "APIFuzzing|folder/openapi.json"
-msgstr ""
+msgstr "文件夹/openapi.json"
msgid "AWS Access Key"
msgstr "AWS访问密钥"
@@ -1571,7 +1581,7 @@ msgid "Acceptable for use in this project"
msgstr "å¯æŽ¥å—用于此项目"
msgid "Access Git repositories or the API."
-msgstr ""
+msgstr "访问 Git 仓库或 API。"
msgid "Access Tokens"
msgstr "访问令牌"
@@ -1640,13 +1650,13 @@ msgid "AccessTokens|It cannot be used to access any other data."
msgstr "该令牌无法用于访问其它数æ®ã€‚"
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
-msgstr ""
+msgstr "请确ä¿è¯¥ä»¤ç‰Œçš„安全。任何æŒæœ‰è¯¥ä»¤ç‰Œçš„人,都å¯ä»¥ä»¥æ‚¨çš„身份æ¥åˆ›å»ºè®®é¢˜ã€‚如果令牌泄露,您应该%{reset_link_start}é‡ç½®ä»¤ç‰Œ %{reset_link_end} 。"
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
-msgstr ""
+msgstr "将此令牌ä¿å¯†ã€‚任何拥有它的人都å¯ä»¥åƒæ‚¨ä¸€æ ·åˆ›å»ºè®®é¢˜ã€‚如果å‘生这ç§æƒ…况, %{link_reset_it}。"
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
-msgstr ""
+msgstr "将此令牌ä¿å¯†ã€‚任何拥有它的人都å¯ä»¥åƒæ‚¨ä¸€æ ·åˆ›å»ºè®®é¢˜ã€‚如果å‘生这ç§æƒ…况,访问%{link_reset_it}。"
msgid "AccessTokens|Personal Access Tokens"
msgstr "个人访问令牌"
@@ -1664,13 +1674,13 @@ msgid "AccessTokens|You can generate a personal access token for each applicatio
msgstr "您å¯ä»¥ä¸ºéœ€è¦è®¿é—®GitLab APIçš„æ¯ä¸ªåº”用程åºç”Ÿæˆä¸ªäººè®¿é—®ä»¤ç‰Œã€‚"
msgid "AccessTokens|Your feed token authenticates you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar. It is visible in those feed URLs."
-msgstr ""
+msgstr "当您的 RSS 阅读器加载个性化的 RSS 订阅æºæˆ–当您的日历应用程åºåŠ è½½ä¸ªæ€§åŒ–日历时,您的订阅令牌会验è¯æ‚¨ã€‚ 它在这些新闻æºç½‘å€ä¸­å¯è§ã€‚"
msgid "AccessTokens|Your incoming email token authenticates you when you create a new issue by email, and is included in your personal project-specific email addresses."
-msgstr ""
+msgstr "当您通过电å­é‚®ä»¶åˆ›å»ºä¸€ä¸ªæ–°è®®é¢˜æ—¶ï¼Œæ‚¨çš„接收电å­é‚®ä»¶ä»¤ç‰Œä¼šéªŒè¯æ‚¨ï¼Œå…¶åŒ…å«åœ¨æ‚¨çš„个人特定项目的电å­é‚®ä»¶åœ°å€ä¸­ã€‚"
msgid "AccessTokens|Your static object token authenticates you when repository static objects (such as archives or blobs) are served from an external storage."
-msgstr ""
+msgstr "当仓库é™æ€å¯¹è±¡(例如归档或åšå®¢)从外部存储æœåŠ¡æ—¶ï¼Œæ‚¨çš„é™æ€å¯¹è±¡ä»¤ç‰Œä¼šéªŒè¯æ‚¨ã€‚"
msgid "AccessTokens|reset this token"
msgstr "é‡ç½®æ­¤ä»¤ç‰Œ"
@@ -1697,13 +1707,13 @@ msgid "Account and limit"
msgstr "å¸æˆ·å’Œé™åˆ¶"
msgid "Account:"
-msgstr ""
+msgstr "账户:"
msgid "Account: %{account}"
msgstr "å¸æˆ·ï¼š%{account}"
msgid "Action"
-msgstr ""
+msgstr "æ“作"
msgid "Action to take when receiving an alert. %{docsLink}"
msgstr "接收警报时è¦æ‰§è¡Œçš„æ“作。%{docsLink}"
@@ -1727,7 +1737,7 @@ msgid "Activity"
msgstr "动æ€"
msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
-msgstr ""
+msgstr "获å–动æ€æ—¶å‘生错误,é‡æ–°åŠ è½½é¡µé¢ä»¥é‡è¯•ã€‚"
msgid "Add"
msgstr "添加"
@@ -1772,25 +1782,25 @@ msgid "Add a GPG key"
msgstr "添加GPG密钥"
msgid "Add a Jaeger URL to replace this page with a link to your Jaeger server. You first need to %{link_start_tag}install Jaeger%{link_end_tag}."
-msgstr ""
+msgstr "添加一个Jaeger URL,用指å‘您的JaegeræœåŠ¡å™¨çš„链接替æ¢æ­¤é¡µé¢ã€‚æ‚¨é¦–å…ˆéœ€è¦ %{link_start_tag}安装Jaeger%{link_end_tag}。"
msgid "Add a Terms of Service agreement and Privacy Policy for users of this GitLab instance."
-msgstr ""
+msgstr "为此 GitLab 实例的用户添加æœåŠ¡æ¡æ¬¾å议和éšç§æ”¿ç­–。"
msgid "Add a bullet list"
msgstr "添加一个符å·åˆ—表"
msgid "Add a collapsible section"
-msgstr ""
+msgstr "添加å¯æŠ˜å éƒ¨åˆ†"
msgid "Add a comment to this line"
msgstr "å‘此行添加评论"
msgid "Add a comment to this line or drag for multiple lines"
-msgstr ""
+msgstr "在此行添加评论或拖动以编辑多行"
msgid "Add a custom message with details about the instance's shared runners. The message is visible in group and project CI/CD settings, in the Runners section. Markdown is supported."
-msgstr ""
+msgstr "添加一个自定义消æ¯ï¼ŒåŒ…å«å®žä¾‹å…±äº«Runner的详细信æ¯ã€‚ 消æ¯åœ¨ç¾¤ç»„和项目 CI/CD 设置中å¯è§ï¼Œåœ¨Runner部分。支æŒMarkdown。"
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr "添加一般评论 %{noteableDisplayName}。"
@@ -1802,7 +1812,7 @@ msgid "Add a homepage to your wiki that contains information about your project
msgstr "在wiki中添加一个主页,其中包å«æœ‰å…³é¡¹ç›®çš„ä¿¡æ¯ï¼ŒGitLab将在此处显示该主页,而ä¸æ˜¯æ­¤æ¶ˆæ¯ã€‚"
msgid "Add a horizontal rule"
-msgstr ""
+msgstr "添加水平规则"
msgid "Add a line"
msgstr "添加一行"
@@ -1868,13 +1878,13 @@ msgid "Add commit messages as comments to Asana tasks. %{docs_link}"
msgstr "å°†æ交消æ¯æ·»åŠ ä¸ºAsana任务的评论。 %{docs_link}"
msgid "Add commit messages as comments to Pivotal Tracker stories. %{docs_link}"
-msgstr ""
+msgstr "å°†æ交消æ¯ä½œä¸ºè¯„论添加到 Pivotal Tracker 故事。 %{docs_link}"
msgid "Add deploy freeze"
msgstr "添加部署冻结"
msgid "Add deploy keys to grant read/write access to this repository. %{link_start}What are deploy keys?%{link_end}"
-msgstr ""
+msgstr "添加部署密钥以授予对此存储库的读/写访问æƒé™ã€‚ %{link_start}什么是部署密钥?%{link_end}"
msgid "Add domain"
msgstr "添加域å"
@@ -1883,7 +1893,7 @@ msgid "Add email address"
msgstr "添加电å­é‚®ä»¶åœ°å€"
msgid "Add email participant(s)"
-msgstr ""
+msgstr "添加电å­é‚®ä»¶å‚与者"
msgid "Add environment"
msgstr "添加环境"
@@ -1928,7 +1938,7 @@ msgid "Add project"
msgstr "添加项目"
msgid "Add projects"
-msgstr ""
+msgstr "添加项目"
msgid "Add reaction"
msgstr "添加回应"
@@ -1946,7 +1956,7 @@ msgid "Add system hook"
msgstr "添加系统钩å­"
msgid "Add text to the sign-in page. Markdown enabled."
-msgstr ""
+msgstr "将文本添加到登录页é¢ã€‚Markdownå·²å¯ç”¨ã€‚"
msgid "Add to Slack"
msgstr "添加到Slack"
@@ -2000,7 +2010,7 @@ msgid "AddMember|Invite email is invalid"
msgstr "邀请邮件无效"
msgid "AddMember|Invite limit of %{daily_invites} per day exceeded"
-msgstr ""
+msgstr "æ¯å¤©é™åˆ¶%{daily_invites}次邀请"
msgid "AddMember|No invite source provided."
msgstr "没有æ供邀请æºã€‚"
@@ -2045,19 +2055,19 @@ msgid "Additional minutes"
msgstr "更多的分钟数"
msgid "Additional minutes:"
-msgstr ""
+msgstr "é¢å¤–的分钟数:"
msgid "Additional text"
msgstr "附加文本"
msgid "Additional text for the sign-in and Help page."
-msgstr ""
+msgstr "登录和帮助页é¢çš„附加文本。"
msgid "Additional text to show on the Help page"
-msgstr ""
+msgstr "在帮助页é¢ä¸Šæ˜¾ç¤ºçš„附加文本"
msgid "Additional text to show on the sign-in page"
-msgstr ""
+msgstr "è¦åœ¨ç™»å½•é¡µé¢ä¸Šæ˜¾ç¤ºçš„附加文本"
msgid "Address"
msgstr "地å€"
@@ -2081,10 +2091,10 @@ msgid "Adds an issue to an epic."
msgstr "将议题添加到å²è¯—。"
msgid "Adds email participant(s)"
-msgstr ""
+msgstr "添加电å­é‚®ä»¶å‚与者"
msgid "Adjust how frequently the GitLab UI polls for updates."
-msgstr ""
+msgstr "调整 GitLab UI 轮询更新的频率。"
msgid "Adjust your filters/search criteria above. If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
msgstr "请您调整上é¢çš„筛选器/æœç´¢æ¡ä»¶ã€‚如果您认为此处有误,请å‚阅 %{linkStart}Geo故障排除%{linkEnd}文档以获å–更多信æ¯ã€‚"
@@ -2227,14 +2237,14 @@ msgstr "查看最新项目"
msgid "AdminArea|View latest users"
msgstr "查看最新的用户"
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
-msgstr "您å³å°†åœæ­¢æ‰€æœ‰ä½œä¸šã€‚这会中断并结æŸæ‰€æœ‰æ­£åœ¨è¿è¡Œçš„作业。"
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
+msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "加载统计数æ®æ—¶å‡ºé”™ã€‚请å†è¯•ä¸€æ¬¡"
msgid "AdminProjects| You’re about to permanently delete the project %{projectName}, its repository, and all related resources, including issues and merge requests. Once you confirm and press %{strong_start}Delete project%{strong_end}, it cannot be undone or recovered."
-msgstr ""
+msgstr "您å³å°†æ°¸ä¹…删除项目 %{projectName},其仓库以åŠæ‰€æœ‰ç›¸å…³èµ„æºï¼ŒåŒ…括议题ã€åˆå¹¶è¯·æ±‚等。一旦确认并点击 %{strong_start}删除项目%{strong_end},将无法撤消或æ¢å¤ã€‚"
msgid "AdminProjects|Delete"
msgstr "删除"
@@ -2243,25 +2253,25 @@ msgid "AdminProjects|Delete Project %{projectName}?"
msgstr "删除项目 %{projectName}?"
msgid "AdminSettings|A Let's Encrypt account will be configured for this GitLab instance using this email address. You will receive emails to warn of expiring certificates. %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "我们将为此GitLab 实例使用此电å­é‚®ä»¶åœ°å€é…置一个Let's Encryptè´¦å·ã€‚ 您将收到电å­é‚®ä»¶è¯ä¹¦è¿‡æœŸè­¦å‘Šã€‚ %{link_start}了解更多信æ¯ã€‚%{link_end}"
msgid "AdminSettings|All new projects can use the instance's shared runners by default."
-msgstr ""
+msgstr "默认情况下,所有新项目都å¯ä»¥ä½¿ç”¨å®žä¾‹çš„共享Runner。"
msgid "AdminSettings|Auto DevOps domain"
msgstr "Auto DevOps 域"
msgid "AdminSettings|Configure Let's Encrypt"
-msgstr ""
+msgstr "é…ç½® Let's Encrypt"
msgid "AdminSettings|Disable feed token"
msgstr "ç¦ç”¨ä¿¡æ¯æµä»¤ç‰Œ"
msgid "AdminSettings|Disable public access to Pages sites"
-msgstr ""
+msgstr "ç¦æ­¢å…¬å¼€è®¿é—® Pages 站点"
msgid "AdminSettings|Domain verification is an essential security measure for public GitLab sites. Users are required to demonstrate they control a domain before it is enabled. %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "域å验è¯æ˜¯å…¬å…± GitLab 站点的基本安全措施。用户需è¦è¯æ˜Žä»–们在å¯ç”¨åŸŸå之å‰æ‹¥æœ‰åŸŸå的所有æƒã€‚%{link_start}了解更多。%{link_end}"
msgid "AdminSettings|Enable shared runners for new projects"
msgstr "为新项目å¯ç”¨å…±äº«Runner"
@@ -2270,70 +2280,70 @@ msgid "AdminSettings|Feed token"
msgstr "ä¿¡æ¯æµä»¤ç‰Œ"
msgid "AdminSettings|I have read and agree to the Let's Encrypt %{link_start}Terms of Service%{link_end} (PDF)."
-msgstr ""
+msgstr "我已ç»é˜…读并åŒæ„ %{link_start}æœåŠ¡æ¡æ¬¾%{link_end} (PDF)。"
msgid "AdminSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
-msgstr ""
+msgstr "如果未指定群组或实例级别,默认值为 %{default_initial_branch_name}。ä¸å½±å“现有的仓库。"
msgid "AdminSettings|Keep the latest artifacts for all jobs in the latest successful pipelines"
msgstr "在最新æˆåŠŸçš„æµæ°´çº¿ä¸­ï¼Œä¿ç•™æ‰€æœ‰ä½œä¸šçš„最新产物"
msgid "AdminSettings|Let's Encrypt email"
-msgstr ""
+msgstr "Let's Encrypt 电å­é‚®ä»¶"
msgid "AdminSettings|Maximum duration of a session for Git operations when 2FA is enabled."
msgstr "å¯ç”¨2FA时,Gitæ“作会è¯çš„最大有效期é™ã€‚"
msgid "AdminSettings|New CI/CD variables in projects and groups default to protected."
-msgstr ""
+msgstr "项目和群组中的新 CI/CD å˜é‡é»˜è®¤ä¸ºå—ä¿æŠ¤ã€‚"
msgid "AdminSettings|No required pipeline"
msgstr "没有必需的æµæ°´çº¿"
msgid "AdminSettings|Protect CI/CD variables by default"
-msgstr ""
+msgstr "默认ä¿æŠ¤ CI/CD å˜é‡"
msgid "AdminSettings|Require users to prove ownership of custom domains"
-msgstr ""
+msgstr "è¦æ±‚用户è¯æ˜Žè‡ªå®šä¹‰åŸŸå的所有æƒ"
msgid "AdminSettings|Required pipeline configuration"
msgstr "强制æµæ°´çº¿é…ç½®"
msgid "AdminSettings|Select a CI/CD template"
-msgstr ""
+msgstr "选择一个 CI/CD 模æ¿"
msgid "AdminSettings|Select a group to use as the source for instance-level project templates."
-msgstr ""
+msgstr "选择一个群组作为实例级项目模æ¿çš„æ¥æºã€‚"
msgid "AdminSettings|Select to disable public access for Pages sites, which requires users to sign in for access to the Pages sites in your instance. %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "选择ç¦ç”¨Pages站点的公开访问æƒé™ï¼Œè¿™éœ€è¦ç”¨æˆ·ç™»å½•æ‰èƒ½è®¿é—®æ‚¨çš„Pages站点。 %{link_start}了解更多。%{link_end}"
msgid "AdminSettings|Session duration for Git operations when 2FA is enabled (minutes)"
-msgstr ""
+msgstr "å¯ç”¨2FAæ—¶Gitæ“作的会è¯æŒç»­æ—¶é—´ï¼ˆåˆ†é’Ÿï¼‰"
msgid "AdminSettings|Set a CI/CD template as the required pipeline configuration for all projects in the instance. Project CI/CD configuration merges into the required pipeline configuration when the pipeline runs. %{link_start}What is a required pipeline configuration?%{link_end}"
-msgstr ""
+msgstr "å°†CI/CD模æ¿è®¾ç½®ä¸ºå®žä¾‹ä¸­æ‰€æœ‰é¡¹ç›®æ‰€éœ€çš„æµæ°´çº¿é…置。当æµæ°´çº¿è¿è¡Œæ—¶ï¼Œé¡¹ç›®CI/CDé…ç½®åˆå¹¶åˆ°æ‰€éœ€çš„æµæ°´çº¿é…置中。%{link_start}什么是必需的æµæ°´çº¿é…ç½®?%{link_end}"
msgid "AdminSettings|Set the maximum size of GitLab Pages per project (0 for unlimited). %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "设置æ¯ä¸ªé¡¹ç›®çš„GitLab Pagesçš„æœ€å¤§å¤§å° ï¼ˆ0表示无é™åˆ¶ï¼‰ã€‚%{link_start}了解更多信æ¯ã€‚%{link_end}"
msgid "AdminSettings|Size and domain settings for Pages static sites."
-msgstr ""
+msgstr "Pages é™æ€ç«™ç‚¹çš„大å°å’ŒåŸŸå设置。"
msgid "AdminSettings|The default domain to use for Auto Review Apps and Auto Deploy stages in all projects."
-msgstr ""
+msgstr "在所有项目中,自动评审应用和自动部署阶段使用的默认域å。"
msgid "AdminSettings|The default name for the initial branch of new repositories created in the instance."
-msgstr ""
+msgstr "实例中创建的新仓库的åˆå§‹åˆ†æ”¯çš„默认å称。"
msgid "AdminSettings|The latest artifacts for all jobs in the most recent successful pipelines in each project are stored and do not expire."
-msgstr ""
+msgstr "存储了æ¯ä¸ªé¡¹ç›®ä¸­æœ€è¿‘æˆåŠŸå®Œæˆçš„æµæ°´çº¿ä¸­æ‰€æœ‰ä½œä¸šçš„最新产物,并且ä¸ä¼šè¿‡æœŸã€‚"
msgid "AdminSettings|The projects in this group can be selected as templates for new projects created on the instance. %{link_start}Learn more.%{link_end} "
-msgstr ""
+msgstr "å¯ä»¥é€‰æ‹©è¯¥ç¾¤ç»„中的项目作为在实例中创建新项目的模æ¿ã€‚ %{link_start}了解更多。%{link_end} "
msgid "AdminSettings|The template for the required pipeline configuration can be one of the GitLab-provided templates, or a custom template added to an instance template repository. %{link_start}How do I create an instance template repository?%{link_end}"
-msgstr ""
+msgstr "所需æµæ°´çº¿é…置的模æ¿å¯ä»¥æ˜¯GitLabæ供的模æ¿ä¹‹ä¸€ï¼Œä¹Ÿå¯ä»¥æ˜¯æ·»åŠ åˆ°å®žä¾‹æ¨¡æ¿ä»“库的自定义模æ¿ã€‚%{link_start}如何创建实例模æ¿ä»“库?%{link_end}"
msgid "AdminStatistics|Active Users"
msgstr "激活用户"
@@ -2363,7 +2373,7 @@ msgid "AdminUsers|(Admin)"
msgstr "管ç†å‘˜"
msgid "AdminUsers|(Banned)"
-msgstr ""
+msgstr "(已å°ç¦ï¼‰"
msgid "AdminUsers|(Blocked)"
msgstr "å·²å±è”½"
@@ -2384,7 +2394,7 @@ msgid "AdminUsers|2FA Enabled"
msgstr "å¯ç”¨åŒé‡è®¤è¯"
msgid "AdminUsers|A user can validate themselves by inputting a credit/debit card, or an admin can manually validate a user."
-msgstr ""
+msgstr "用户å¯ä»¥è¾“入信用å¡/借记å¡è¿›è¡ŒéªŒè¯ï¼Œæˆ–者管ç†å‘˜å¯ä»¥æ‰‹åŠ¨éªŒè¯ç”¨æˆ·ã€‚"
msgid "AdminUsers|Access"
msgstr "访问类型"
@@ -2405,7 +2415,7 @@ msgid "AdminUsers|Active"
msgstr "激活"
msgid "AdminUsers|Adjust the user cap setting on your instance"
-msgstr ""
+msgstr "在您的实例上调整用户上é™è®¾ç½®"
msgid "AdminUsers|Admin"
msgstr "管ç†å‘˜"
@@ -2455,12 +2465,6 @@ msgstr "å·²ç¦ç”¨"
msgid "AdminUsers|Blocking user has the following effects:"
msgstr "ç¦ç”¨ç”¨æˆ·å…·æœ‰ä»¥ä¸‹æ•ˆæžœï¼š"
-msgid "AdminUsers|Can't access Git repositories."
-msgstr "无法访问 Git 仓库。"
-
-msgid "AdminUsers|Can't log in."
-msgstr "无法登录。"
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr "无法登录或访问实例信æ¯"
@@ -2527,6 +2531,9 @@ msgstr "有关您的GitLab实例使用情况的é‡è¦ä¿¡æ¯"
msgid "AdminUsers|Is using seat"
msgstr "正在使用许å¯å¸­ä½"
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr "自己ï¼"
@@ -2590,6 +2597,12 @@ msgstr "å‘用户å‘é€ç”µå­é‚®ä»¶"
msgid "AdminUsers|Sort by"
msgstr "排åºæ–¹å¼"
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr "此用户将被注销"
@@ -2615,7 +2628,7 @@ msgid "AdminUsers|Unban user"
msgstr "解ç¦ç”¨æˆ·"
msgid "AdminUsers|Unban user %{username}?"
-msgstr ""
+msgstr "解ç¦ç”¨æˆ· %{username}?"
msgid "AdminUsers|Unblock"
msgstr "å–消ç¦ç”¨"
@@ -2642,7 +2655,7 @@ msgid "AdminUsers|Users"
msgstr "用户"
msgid "AdminUsers|Users can still be invited to your instance and/or add themselves if permitted based on your settings. They will not have access to your instance, nor count towards your subscribed seat count until you %{approve_link}."
-msgstr ""
+msgstr "用户å¯ä»¥è¢«é‚€è¯·è¿›å…¥æ‚¨çš„实例,和/或在您的设置å…许的情况下添加自己(根æ®æ‚¨çš„设置)。他们将无法访问您的实例,也ä¸ä¼šè®¡å…¥æ‚¨çš„已订阅席ä½æ•°ï¼Œç›´åˆ°æ‚¨%{approve_link}为止。"
msgid "AdminUsers|Validate user account"
msgstr "验è¯ç”¨æˆ·å¸æˆ·"
@@ -2656,7 +2669,7 @@ msgstr "我å¯ä»¥åšä»€ä¹ˆï¼Ÿ"
msgid "AdminUsers|What does this mean?"
msgstr "这是什么æ„æ€ï¼Ÿ"
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -2687,7 +2700,7 @@ msgid "AdminUsers|You can always unblock their account, their data will remain i
msgstr "您å¯ä»¥éšæ—¶è§£é™¤å±è”½ä»–们的å¸æˆ·ï¼Œä»–们的数æ®å°†ä¿æŒä¸å˜ã€‚"
msgid "AdminUsers|You can ban their account in the future if necessary."
-msgstr ""
+msgstr "如有必è¦ï¼Œæ‚¨å¯ä»¥åœ¨å°†æ¥å°ç¦ä»–们的账户。"
msgid "AdminUsers|You can unban their account in the future. Their data remains intact."
msgstr "未æ¥ï¼Œæ‚¨å¯ä»¥è§£ç¦ä»–们的å¸æˆ·ã€‚他们的数æ®å°†ä¼šä¿æŒå®Œå¥½ã€‚"
@@ -2723,19 +2736,19 @@ msgid "Admin|Admin notes"
msgstr "管ç†å‘˜å¤‡æ³¨"
msgid "Admin|Learn more about quarterly reconciliation"
-msgstr ""
+msgstr "了解更多关于季度对账的信æ¯"
msgid "Admin|Note"
msgstr "备注"
msgid "Admin|Quarterly reconciliation will occur on %{qrtlyDate}"
-msgstr ""
+msgstr "季度对账将在 %{qrtlyDate}"
msgid "Admin|The number of max seats used for your namespace is currently exceeding the number of seats in your subscription. On %{qrtlyDate}, GitLab will process a quarterly reconciliation and automatically bill you a prorated amount for the overage. There is no action needed from you. If you have a credit card on file, it will be charged. Otherwise, you will receive an invoice."
-msgstr ""
+msgstr "您的命å空间使用的最大席ä½æ•°é‡ç›®å‰è¶…过您订阅的席ä½æ•°é‡ã€‚ 在 %{qrtlyDate},将处ç†ä¸€ä¸ªå­£åº¦è°ƒèŠ‚,并自动å‘您å‘é€ä¸€ä¸ªæŒ‰æ¯”例计算的支付金é¢è´¦å•ã€‚ 您无需æ“作。如果您在文件上有信用å¡ï¼Œå®ƒå°†è¢«æ”¶å–费用。å¦åˆ™ï¼Œæ‚¨å°†æ”¶åˆ°è´¹ç”¨æ¸…å•ã€‚"
msgid "Admin|The number of maximum users for your instance is currently exceeding the number of users in license. On %{qrtlyDate}, GitLab will process a quarterly reconciliation and automatically bill you a prorated amount for the overage. There is no action needed from you. If you have a credit card on file, it will be charged. Otherwise, you will receive an invoice."
-msgstr ""
+msgstr "您的实例的最大用户数é‡ç›®å‰è¶…过了许å¯è¯ä¸­çš„用户数é‡ã€‚ 在 %{qrtlyDate},将处ç†ä¸€ä¸ªå­£åº¦è°ƒèŠ‚,并自动å‘您å‘é€ä¸€ä¸ªæŒ‰æ¯”例计算的支付金é¢è´¦å•ã€‚ 您无需æ“作。如果您在文件上有信用å¡ï¼Œå®ƒå°†è¢«æ”¶å–费用。å¦åˆ™ï¼Œæ‚¨å°†æ”¶åˆ°è´¹ç”¨æ¸…å•ã€‚"
msgid "Admin|View pending user approvals"
msgstr "查看等待中的用户批准"
@@ -2774,7 +2787,7 @@ msgid "After that, you will not be able to use merge approvals or epics as well
msgstr "在那之åŽï¼Œæ‚¨å°†æ— æ³•ä½¿ç”¨åˆå¹¶æ‰¹å‡†æˆ–å²è¯—以åŠä¼—多安全功能。"
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
-msgstr ""
+msgstr "在您审阅了这些贡献指å—åŽï¼Œæ‚¨å°†è¢«è®¾ç½®ä¸º"
msgid "Akismet API Key"
msgstr "Akismet API 密钥"
@@ -2946,7 +2959,7 @@ msgid "AlertMappingBuilder|Title is a required field for alerts in GitLab. Shoul
msgstr "标题为在 GitLab中警报的必填字段。如果您指定的负载字段ä¸å¯ç”¨ï¼Œè¯·æŒ‡æ˜Žåº”该使用哪个字段。"
msgid "AlertSettings|A webhook URL and authorization key is generated for the integration. After you save the integration, both are visible under the “View credentials†tab."
-msgstr ""
+msgstr "集æˆç”ŸæˆWebhook URL 和授æƒå¯†é’¥ã€‚您ä¿å­˜é›†æˆåŽï¼Œä¸¤è€…都在“查看凭æ®â€é€‰é¡¹å¡ä¸‹å¯è§ã€‚"
msgid "AlertSettings|Add new integration"
msgstr "添加新的集æˆ"
@@ -2964,7 +2977,7 @@ msgid "AlertSettings|Current integrations"
msgstr "当å‰é›†æˆ"
msgid "AlertSettings|Customize alert payload mapping (optional)"
-msgstr ""
+msgstr "自定义警报负载映射(å¯é€‰ï¼‰"
msgid "AlertSettings|Delete integration"
msgstr "删除集æˆ"
@@ -2979,34 +2992,34 @@ msgid "AlertSettings|Enable integration"
msgstr "å¯ç”¨é›†æˆ"
msgid "AlertSettings|Enter an example payload from your selected monitoring tool. This supports sending alerts to a GitLab endpoint."
-msgstr ""
+msgstr "从您选定的监测工具中输入一个示例负载。这将支æŒå‘GitLab 端点å‘é€è­¦æŠ¥ã€‚"
msgid "AlertSettings|Enter integration name"
msgstr "输入集æˆå称"
msgid "AlertSettings|Free versions of GitLab are limited to one integration per type. To add more, %{linkStart}upgrade your subscription%{linkEnd}."
-msgstr ""
+msgstr "å…费版的 GitLab ä»…é™æ¯ç§ç±»åž‹ä¸€ä¸ªé›†æˆã€‚è‹¥è¦æ·»åŠ æ›´å¤šï¼Œ %{linkStart}å‡çº§æ‚¨çš„订阅%{linkEnd}。"
msgid "AlertSettings|GitLab has created a URL and authorization key for your integration. You can use them to set up a webhook and authorize your endpoint to send alerts to GitLab."
-msgstr ""
+msgstr "GitLab 已为您的集æˆåˆ›å»ºäº†ä¸€ä¸ª URL 和授æƒå¯†é’¥ã€‚ 您å¯ä»¥ä½¿ç”¨å®ƒä»¬æ¥è®¾ç½®ä¸€ä¸ªwebhook并授æƒæ‚¨çš„端点å‘GitLabå‘é€è­¦æŠ¥ã€‚"
msgid "AlertSettings|HTTP Endpoint"
msgstr "HTTP 端点"
msgid "AlertSettings|If you edit the payload, you must re-map the fields again."
-msgstr ""
+msgstr "如果您编辑有效载è·ï¼Œæ‚¨å¿…é¡»é‡æ–°æ˜ å°„字段。"
msgid "AlertSettings|If you reset the authorization key for this project, you must update the key in every enabled alert source."
-msgstr ""
+msgstr "如果您é‡ç½®æ­¤é¡¹ç›®çš„授æƒå¯†é’¥ï¼Œæ‚¨å¿…须在æ¯ä¸ªå¯ç”¨çš„警报æºä¸­æ›´æ–°è¯¥å¯†é’¥ã€‚"
msgid "AlertSettings|Integration successfully saved"
msgstr "集æˆæˆåŠŸä¿å­˜"
msgid "AlertSettings|Name integration"
-msgstr ""
+msgstr "命å集æˆ"
msgid "AlertSettings|Parse payload fields"
-msgstr ""
+msgstr "解æžè´Ÿè½½å­—段"
msgid "AlertSettings|Proceed with editing"
msgstr "继续编辑"
@@ -3051,16 +3064,16 @@ msgid "AlertSettings|The form has unsaved changes. How would you like to proceed
msgstr "表å•æœ‰æœªä¿å­˜çš„更改。您想如何继续?"
msgid "AlertSettings|To create a custom mapping, enter an example payload from your monitoring tool, in JSON format. Select the \"Parse payload fields\" button to continue."
-msgstr ""
+msgstr "è‹¥è¦åˆ›å»ºè‡ªå®šä¹‰æ˜ å°„,请以JSONæ ¼å¼ä»Žæ‚¨çš„监测工具输入示例有效载è·ï¼Œè¯·é€‰æ‹©â€œè§£æžè´Ÿè½½å­—段â€æŒ‰é’®ç»§ç»­ã€‚"
msgid "AlertSettings|URL cannot be blank and must start with http: or https:."
msgstr "URL ä¸èƒ½ä¸ºç©ºï¼Œå¿…须以 http: 或 https: 开头。"
msgid "AlertSettings|Use the URL and authorization key below to configure how Prometheus sends alerts to GitLab. Review the %{linkStart}GitLab documentation%{linkEnd} to learn how to configure your endpoint."
-msgstr ""
+msgstr "使用下é¢çš„ URL 和授æƒå¯†é’¥æ¥é…ç½® Prometheus 如何å‘GitLabå‘é€è­¦æŠ¥ã€‚ 查看 %{linkStart}GitLab 文档%{linkEnd} æ¥å­¦ä¹ å¦‚何é…置您的端点。"
msgid "AlertSettings|Use the URL and authorization key below to configure how an external service sends alerts to GitLab. %{linkStart}How do I configure the endpoint?%{linkEnd}"
-msgstr ""
+msgstr "使用下é¢çš„ URL 和授æƒå¯†é’¥æ¥é…置外部æœåŠ¡å¦‚何å‘GitLabå‘é€è­¦æŠ¥ã€‚ %{linkStart}我如何é…置端点?%{linkEnd}"
msgid "AlertSettings|View URL and authorization key"
msgstr "查看 URL 和授æƒå¯†é’¥"
@@ -3072,7 +3085,7 @@ msgid "AlertSettings|Webhook URL"
msgstr "Webhook网å€"
msgid "AlertSettings|You can map default GitLab alert fields to your payload keys in the dropdowns below."
-msgstr ""
+msgstr "您å¯ä»¥åœ¨ä¸‹æ–¹ä¸‹æ‹‰èœå•ä¸­æ˜ å°„默认的GitLab 警报字段到您的负载密钥。"
msgid "AlertSettings|You can now set up alert endpoints for manually configured Prometheus instances in the Alerts section on the Operations settings page. Alert endpoint fields on this page have been deprecated."
msgstr "您现在å¯ä»¥åœ¨è¿ç»´è®¾ç½®é¡µé¢ä¸Šçš„警报部分中为手动é…置的Prometheus实例设置警报端点。此页é¢ä¸Šçš„警报端点字段已被弃用。"
@@ -3090,13 +3103,13 @@ msgid "AlertsIntegrations|Alerts will not be created through this integration"
msgstr "警报将ä¸ä¼šé€šè¿‡æ­¤é›†æˆåˆ›å»º"
msgid "AlertsIntegrations|If you delete the %{integrationName} integration, alerts are no longer sent from this endpoint. This action cannot be undone."
-msgstr ""
+msgstr "如果您删除了 %{integrationName} 集æˆï¼Œåˆ™ä¸å†ä»Žæ­¤ç«¯ç‚¹å‘é€è­¦æŠ¥ã€‚æ­¤æ“作无法撤消。"
msgid "AlertsIntegrations|Integration Name"
msgstr "集æˆå称"
msgid "AlertsIntegrations|Integration payload is invalid."
-msgstr ""
+msgstr "集æˆè´Ÿè½½æ— æ•ˆã€‚"
msgid "AlertsIntegrations|No integrations have been added yet."
msgstr "尚未添加集æˆã€‚"
@@ -3111,19 +3124,19 @@ msgid "AlertsIntegrations|The integration could not be deleted. Please try again
msgstr "无法删除集æˆã€‚请é‡è¯•ã€‚"
msgid "AlertsIntegrations|The integration is currently inactive. Enable the integration to send the test alert."
-msgstr ""
+msgstr "集æˆå½“å‰æœªæ¿€æ´»ã€‚å¯ç”¨é›†æˆä»¥å‘é€æµ‹è¯•è­¦æŠ¥ã€‚"
msgid "AlertsIntegrations|The integration is deleted."
-msgstr ""
+msgstr "集æˆå·²åˆ é™¤ã€‚"
msgid "AlertsIntegrations|The integration is saved."
-msgstr ""
+msgstr "集æˆå·²ä¿å­˜ã€‚"
msgid "AlertsIntegrations|The integration token could not be reset. Please try again."
msgstr "无法é‡ç½®é›†æˆä»¤ç‰Œã€‚请é‡è¯•ã€‚"
msgid "AlertsIntegrations|The test alert should now be visible in your alerts list."
-msgstr ""
+msgstr "测试警报现在应该在您的警报列表中å¯è§ã€‚"
msgid "Algorithm"
msgstr "算法"
@@ -3183,7 +3196,7 @@ msgid "All threads resolved"
msgstr "所有主题已解决"
msgid "All users must accept the Terms of Service and Privacy Policy to access GitLab"
-msgstr ""
+msgstr "所有用户必须接å—æœåŠ¡æ¡æ¬¾å’Œéšç§æ”¿ç­–æ‰èƒ½è®¿é—® GitLab"
msgid "All users must have a name."
msgstr "所有的用户都必须具有å称。"
@@ -3192,7 +3205,7 @@ msgid "Allow \"%{group_name}\" to sign you in"
msgstr "å…许“%{group_name}â€ä»¥æ‚¨çš„身份登录"
msgid "Allow access to members of the following group"
-msgstr ""
+msgstr "å…许访问以下群组的æˆå‘˜"
msgid "Allow access to the following IP addresses"
msgstr "å…许访问以下IP地å€"
@@ -3204,7 +3217,7 @@ msgid "Allow group owners to manage LDAP-related settings"
msgstr "å…许群组所有者管ç†LDAP相关的设置"
msgid "Allow non-administrators to access to the performance bar"
-msgstr ""
+msgstr "å…许éžç®¡ç†å‘˜è®¿é—®æ€§èƒ½æ "
msgid "Allow only the selected protocols to be used for Git access."
msgstr "ä»…å…许所选å议用于 Git 访问。"
@@ -3216,13 +3229,13 @@ msgid "Allow owners to manually add users outside of LDAP"
msgstr "å…许负责人手动添加LDAP之外的用户"
msgid "Allow password authentication for Git over HTTP(S)"
-msgstr ""
+msgstr "å…许通过 HTTP(S) 对 Git 进行密ç éªŒè¯"
msgid "Allow password authentication for the web interface"
-msgstr ""
+msgstr "å…许 Web ç•Œé¢çš„密ç èº«ä»½éªŒè¯"
msgid "Allow project maintainers to configure repository mirroring"
-msgstr ""
+msgstr "å…许项目维护者é…置仓库镜åƒ"
msgid "Allow projects and subgroups to override the group setting"
msgstr "å…许项目和å­ç¾¤ç»„覆盖群组设置"
@@ -3231,7 +3244,7 @@ msgid "Allow projects within this group to use Git LFS"
msgstr "å…许该群组中的项目使用Git LFS"
msgid "Allow public access to pipelines and job details, including output logs and artifacts."
-msgstr ""
+msgstr "å…许所有人访问æµæ°´çº¿å’Œä½œä¸šè¯¦æƒ…,包括输出日志和产物。"
msgid "Allow requests to the local network from hooks and services."
msgstr "å…许æ¥è‡ªé’©å­å’ŒæœåŠ¡çš„对本地网络的请求。"
@@ -3246,7 +3259,7 @@ msgid "Allow subgroups to set up their own two-factor authentication rules"
msgstr "å…许副组设置自己的åŒé‡èº«ä»½éªŒè¯è§„则"
msgid "Allow this key to push to this repository"
-msgstr ""
+msgstr "å…许此密钥推é€åˆ°è¿™ä¸ªä»“库"
msgid "Allow this secondary node to replicate content on Object Storage"
msgstr "å…许此次è¦èŠ‚点在对象存储上å¤åˆ¶å†…容"
@@ -3288,7 +3301,7 @@ msgid "Almost there"
msgstr "å³å°†å®Œæˆ"
msgid "Almost there..."
-msgstr ""
+msgstr "å³å°†å®Œæˆ..."
msgid "Already blocked"
msgstr "已被阻止"
@@ -3303,13 +3316,13 @@ msgid "Also called \"Relying party service URL\" or \"Reply URL\""
msgstr "也称为“ä¾èµ–æ–¹æœåŠ¡URLâ€æˆ–“回å¤URLâ€"
msgid "Also remove direct user membership from subgroups and projects"
-msgstr ""
+msgstr "åŒæ—¶ä»Žå­ç»„和项目中删除直接用户æˆå‘˜èº«ä»½"
msgid "Also unassign this user from related issues and merge requests"
msgstr "åŒæ—¶ä»Žç›¸å…³çš„议题和åˆå¹¶è¯·æ±‚中å–消指派此用户"
msgid "Alternate support URL for Help page and Help dropdown."
-msgstr ""
+msgstr "用于帮助页é¢å’Œå¸®åŠ©ä¸‹æ‹‰åˆ—è¡¨çš„å¤‡ç”¨æ”¯æŒ URL。"
msgid "Alternatively, you can convert your account to a managed account by the %{group_name} group."
msgstr "此外,你å¯ä»¥å°†ä½ çš„è´¦å·è½¬åŒ–为%{group_name}群组的托管账å·"
@@ -3360,7 +3373,7 @@ msgid "An error has occurred"
msgstr "å‘生错误"
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
-msgstr ""
+msgstr "在报告测试结果时出现的错误,错误地表明在没有æ¼æ´žçš„情况下系统中存在æ¼æ´žã€‚"
msgid "An error occurred adding a draft to the thread."
msgstr "å‘主题添加è‰ç¨¿æ—¶å‡ºé”™ã€‚"
@@ -3444,13 +3457,13 @@ msgid "An error occurred while enabling Service Desk."
msgstr "å¯ç”¨æœåŠ¡å°æ—¶å‘生错误。"
msgid "An error occurred while fetching ancestors"
-msgstr ""
+msgstr "获å–上级时å‘生错误"
msgid "An error occurred while fetching branches. Retry the search."
msgstr "获å–分支时å‘生错误,请é‡è¯•æœç´¢ã€‚"
msgid "An error occurred while fetching codequality mr diff reports."
-msgstr ""
+msgstr "获å–代ç è´¨é‡åˆå¹¶è¯·æ±‚差异报告时å‘生错误。"
msgid "An error occurred while fetching commits. Retry the search."
msgstr "获å–æ交时å‘生错误,请é‡è¯•æœç´¢ã€‚"
@@ -3489,7 +3502,7 @@ msgid "An error occurred while fetching projects autocomplete."
msgstr "获å–项目自动完æˆæ—¶å‡ºé”™ã€‚"
msgid "An error occurred while fetching reference"
-msgstr ""
+msgstr "获å–å‚考时å‘生错误"
msgid "An error occurred while fetching sidebar data"
msgstr "获å–侧边æ æ•°æ®æ—¶å‘生错误"
@@ -3500,9 +3513,6 @@ msgstr "获å–标签时å‘生错误,请é‡è¯•æœç´¢ã€‚"
msgid "An error occurred while fetching terraform reports."
msgstr "获å–terraform报告时å‘生错误。"
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr "读å–看æ¿åˆ—表时出错。请å†è¯•ä¸€æ¬¡ã€‚"
-
msgid "An error occurred while fetching the job log."
msgstr "获å–作业日志时å‘生错误。"
@@ -3518,9 +3528,6 @@ msgstr "获å–作业列表时å‘生错误"
msgid "An error occurred while fetching the latest pipeline."
msgstr "获å–最新æµæ°´çº¿æ—¶å‘生错误。"
-msgid "An error occurred while fetching the pipeline."
-msgstr "获å–æµæ°´çº¿æ—¶å‘生错误"
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr "获å–å‘布时å‘生错误。请é‡è¯•ã€‚"
@@ -3575,9 +3582,15 @@ msgstr "加载议题时å‘生错误。"
msgid "An error occurred while loading merge requests."
msgstr "加载åˆå¹¶è¯·æ±‚æ—¶å‘生错误。"
-msgid "An error occurred while loading the access tokens form, please try again."
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
msgstr ""
+msgid "An error occurred while loading the access tokens form, please try again."
+msgstr "加载访问令牌表å•æ—¶å‘生错误,请é‡è¯•ã€‚"
+
msgid "An error occurred while loading the data. Please try again."
msgstr "加载数æ®æ—¶å‡ºé”™ã€‚请é‡è¯•ã€‚"
@@ -3594,7 +3607,7 @@ msgid "An error occurred while loading the file. Please try again later."
msgstr "加载文件时出错。请ç¨åŽå†è¯•ã€‚"
msgid "An error occurred while loading the file. Please try again."
-msgstr ""
+msgstr "加载文件时å‘生错误。请å†è¯•ä¸€æ¬¡ã€‚"
msgid "An error occurred while loading the merge request changes."
msgstr "加载åˆå¹¶è¯·æ±‚çš„å˜æ›´å†…容时å‘生错误。"
@@ -3606,7 +3619,7 @@ msgid "An error occurred while loading the merge request."
msgstr "加载åˆå¹¶è¯·æ±‚æ—¶å‘生错误。"
msgid "An error occurred while loading the notification settings. Please try again."
-msgstr ""
+msgstr "加载通知设置时å‘生错误。请å†è¯•ä¸€æ¬¡ã€‚"
msgid "An error occurred while loading the pipeline."
msgstr "加载æµæ°´çº¿æ—¶å‡ºé”™ã€‚"
@@ -3657,7 +3670,7 @@ msgid "An error occurred while retrieving projects."
msgstr "获å–项目时å‘生错误。"
msgid "An error occurred while saving changes: %{error}"
-msgstr ""
+msgstr "ä¿å­˜æ›´æ”¹æ—¶å‘生错误:%{error}"
msgid "An error occurred while subscribing to notifications."
msgstr "订阅通知时å‘生错误。"
@@ -3696,10 +3709,10 @@ msgid "An error occurred while updating the notification settings. Please try ag
msgstr "更新通知设置时å‘生错误。请é‡è¯•ã€‚"
msgid "An error occurred while uploading the file. Please try again."
-msgstr ""
+msgstr "上传文件时出错。请é‡è¯•ã€‚"
msgid "An error occurred while uploading the image. Please try again."
-msgstr ""
+msgstr "上传图片时出错。请é‡è¯•ã€‚"
msgid "An error occurred while validating group path"
msgstr "验è¯ç¾¤ç»„路径时å‘生错误"
@@ -3741,7 +3754,7 @@ msgid "An unexpected error occurred while communicating with the Web Terminal."
msgstr "与Web终端通信时å‘生æ„外错误。"
msgid "An unexpected error occurred while loading the code quality diff."
-msgstr ""
+msgstr "加载代ç è´¨é‡å·®å¼‚æ—¶å‘生æ„外错误。"
msgid "An unexpected error occurred while starting the Web Terminal."
msgstr "å¯åŠ¨Web终端时å‘生æ„外错误。"
@@ -3777,7 +3790,7 @@ msgid "Ancestors"
msgstr "祖先"
msgid "And this registration token:"
-msgstr ""
+msgstr "以åŠæ­¤æ³¨å†Œä»¤ç‰Œï¼š"
msgid "Anonymous"
msgstr "匿å"
@@ -3813,7 +3826,7 @@ msgid "Any encrypted tokens"
msgstr "任何加密的令牌"
msgid "Any files larger than this limit only index the file name. The file content is neither indexed nor searchable."
-msgstr ""
+msgstr "任何大于此é™åˆ¶çš„文件åªç´¢å¼•æ–‡ä»¶å。文件内容ä¸ä¼šç´¢å¼•ï¼Œä¹Ÿä¸å¯æœç´¢ã€‚"
msgid "Any label"
msgstr "任何标记"
@@ -3873,27 +3886,27 @@ msgid "Application: %{name}"
msgstr "应用:%{name}"
msgid "ApplicationSettings|After sign up text"
-msgstr ""
+msgstr "注册åŽæ–‡æœ¬"
msgid "ApplicationSettings|Allowed domains for sign-ups"
msgstr "å…许注册的域"
msgid "ApplicationSettings|Approve %d user"
msgid_plural "ApplicationSettings|Approve %d users"
-msgstr[0] ""
+msgstr[0] "批准 %d ä½ç”¨æˆ·"
msgid "ApplicationSettings|Approve users in the pending approval status?"
-msgstr ""
+msgstr "批准处于待批准状æ€çš„用户?"
msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
-msgstr[0] ""
+msgstr[0] "通过进行此更改,您将自动批准 %d å处于待批准状æ€çš„用户。"
msgid "ApplicationSettings|Denied domains for sign-ups"
msgstr "æ‹’ç»æ³¨å†Œçš„域"
msgid "ApplicationSettings|Denylist file"
-msgstr ""
+msgstr "æ‹’ç»åå•æ–‡ä»¶"
msgid "ApplicationSettings|Domain denylist"
msgstr "域å黑åå•"
@@ -3911,31 +3924,31 @@ msgid "ApplicationSettings|Enable email restrictions for sign ups"
msgstr "注册时å¯ç”¨é‚®ç®±é»‘åå•"
msgid "ApplicationSettings|Enter denylist manually"
-msgstr ""
+msgstr "手动输入拒ç»åˆ—表"
msgid "ApplicationSettings|Markdown enabled"
-msgstr ""
+msgstr "Markdownå·²å¯ç”¨"
msgid "ApplicationSettings|Minimum password length (number of characters)"
-msgstr ""
+msgstr "最å°å¯†ç é•¿åº¦ï¼ˆå­—符数)"
msgid "ApplicationSettings|ONLY users with e-mail addresses that match these domain(s) will be able to sign-up. Wildcards allowed. Use separate lines for multiple entries. Ex: domain.com, *.domain.com"
msgstr "åªæœ‰ç”µå­é‚®ä»¶åœ°å€ä¸Žè¿™äº›åŸŸå匹é…的用户æ‰èƒ½æ³¨å†Œã€‚å…许使用通é…符。对多个æ¡ç›®ä½¿ç”¨å•ç‹¬çš„行。例如:domain.comã€*.domain.com"
msgid "ApplicationSettings|Once the instance reaches the user cap, any user who is added or requests access will have to be approved by an admin. Leave the field empty for unlimited."
-msgstr ""
+msgstr "一旦实例达到用户上é™ï¼Œä»»ä½•æ·»åŠ æˆ–请求访问的用户都必须得到管ç†å‘˜çš„批准。将该字段留空以表示无é™åˆ¶ã€‚"
msgid "ApplicationSettings|Require admin approval for new sign-ups"
msgstr "新的注册需è¦ç®¡ç†å‘˜æ‰¹å‡†"
msgid "ApplicationSettings|Restricts sign-ups for email addresses that match the given regex. See the %{linkStart}supported syntax%{linkEnd} for more information."
-msgstr ""
+msgstr "é™åˆ¶æ³¨å†Œçš„电å­é‚®ä»¶åœ°å€éœ€ä¸Žç»™å®šæ­£åˆ™è¡¨è¾¾å¼åŒ¹é…。请å‚阅%{linkStart}支æŒçš„语法%{linkEnd}获å–更多信æ¯ã€‚"
msgid "ApplicationSettings|Save changes"
msgstr "ä¿å­˜æ›´æ”¹"
msgid "ApplicationSettings|See GitLab's %{linkStart}Password Policy Guidelines%{linkEnd}"
-msgstr ""
+msgstr "查看GitLabçš„ %{linkStart}密ç ç­–略指å—%{linkEnd}"
msgid "ApplicationSettings|Send confirmation email on sign-up"
msgstr "注册时å‘é€ç¡®è®¤é‚®ä»¶"
@@ -3944,7 +3957,7 @@ msgid "ApplicationSettings|Sign-up enabled"
msgstr "å·²å¯ç”¨æ³¨å†ŒåŠŸèƒ½"
msgid "ApplicationSettings|Upload denylist file"
-msgstr ""
+msgstr "上传拒ç»åå•æ–‡ä»¶"
msgid "ApplicationSettings|User cap"
msgstr "用户上é™"
@@ -3956,10 +3969,10 @@ msgid "ApplicationSettings|Users with e-mail addresses that match these domain(s
msgstr "电å­é‚®ä»¶åœ°å€ä¸Žè¿™äº›åŸŸå匹é…的用户将无法注册。å…许使用通é…符。多个æ¡ç›®ä½¿ç”¨å•ç‹¬çš„行或逗å·ã€‚"
msgid "ApplicationSettings|When enabled, any user visiting %{host} and creating an account will have to be explicitly approved by an admin before they can sign in. This setting is effective only if sign-ups are enabled."
-msgstr ""
+msgstr "å¯ç”¨åŽï¼Œä»»ä½•è®¿é—® %{host} 并创建账å·çš„用户都必须ç»è¿‡ç®¡ç†å‘˜æ˜Žç¡®æ‰¹å‡†æ‰èƒ½ç™»å½•ã€‚此设置仅在å¯ç”¨æ³¨å†Œæ—¶æœ‰æ•ˆã€‚"
msgid "ApplicationSettings|When enabled, any user visiting %{host} will be able to create an account."
-msgstr ""
+msgstr "å¯ç”¨åŽï¼Œä»»ä½•è®¿é—® %{host} 用户都å¯ä»¥åˆ›å»ºè´¦å·ã€‚"
msgid "ApplicationSettings|domain.com"
msgstr "domain.com"
@@ -4030,7 +4043,7 @@ msgstr[0] "%d æˆå‘˜"
msgid "ApprovalRuleRemove|You are about to remove the %{name} approver group which has %{strongStart}%{count} member%{strongEnd}. Approvals from this member are not revoked."
msgid_plural "ApprovalRuleRemove|You are about to remove the %{name} approver group which has %{strongStart}%{count} members%{strongEnd}. Approvals from these members are not revoked."
-msgstr[0] ""
+msgstr[0] "您将è¦åˆ é™¤åŒ…å«%{strongStart}%{count} 个æˆå‘˜%{strongEnd}çš„%{name} 核准人组。这些æˆå‘˜çš„批准ä¸ä¼šè¢«æ’¤é”€ã€‚"
msgid "ApprovalRuleSummary|%d member"
msgid_plural "ApprovalRuleSummary|%d members"
@@ -4040,7 +4053,7 @@ msgid "ApprovalRuleSummary|%{count} approval required from %{membersCount}"
msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCount}"
msgstr[0] "%{membersCount} éœ€è¦ %{count} 个核准"
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4049,7 +4062,13 @@ msgstr "添加核准人"
msgid "ApprovalRule|All scanners"
msgstr "所有扫æ工具"
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
+msgstr "应用此审批规则åªè€ƒè™‘选定的安全扫æ工具。"
+
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
msgstr ""
msgid "ApprovalRule|Approval rules"
@@ -4071,19 +4090,22 @@ msgid "ApprovalRule|Name"
msgstr "å称"
msgid "ApprovalRule|Number of vulnerabilities allowed before approval rule is triggered."
-msgstr ""
+msgstr "在触å‘批准规则之å‰å…许的æ¼æ´žæ•°é‡ã€‚"
msgid "ApprovalRule|Please enter a number equal or greater than zero"
-msgstr ""
+msgstr "请输入一个等于或大于零的数字"
msgid "ApprovalRule|Please select at least one security scanner"
+msgstr "请选择至少一个安全扫æ工具"
+
+msgid "ApprovalRule|Please select at least one severity level"
msgstr ""
msgid "ApprovalRule|Rule name"
msgstr "规则å称"
msgid "ApprovalRule|Security scanners"
-msgstr ""
+msgstr "安全扫æ工具"
msgid "ApprovalRule|Select All"
msgstr "选择全部"
@@ -4091,38 +4113,50 @@ msgstr "选择全部"
msgid "ApprovalRule|Select scanners"
msgstr "选择扫æ工具"
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr "目标分支"
msgid "ApprovalRule|Vulnerabilities allowed"
-msgstr ""
+msgstr "å…许的æ¼æ´ž"
msgid "ApprovalSettings|Merge request approval settings have been updated."
+msgstr "åˆå¹¶è¯·æ±‚核准设置已更新。"
+
+msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
-msgstr "ç¦æ­¢ä½œè€…核准åˆå¹¶è¯·æ±‚"
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
+msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
-msgstr "ç¦æ­¢ç”¨æˆ·ä¿®æ”¹åˆå¹¶è¯·æ±‚核准规则"
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
+msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
msgstr ""
-msgid "ApprovalSettings|There was an error loading merge request approval settings."
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
+msgid "ApprovalSettings|There was an error loading merge request approval settings."
+msgstr "加载åˆå¹¶è¯·æ±‚批准设置时出错。"
+
msgid "ApprovalSettings|There was an error updating merge request approval settings."
msgstr "æ›´æ–°åˆå¹¶è¯·æ±‚审批设置时出错。"
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
-msgstr ""
+msgstr "此设置在实例级别é…置,åªèƒ½ç”±ç®¡ç†å‘˜æ›´æ”¹ã€‚"
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
msgstr "éµå®ˆèŒè´£åˆ†ç¦»"
@@ -4206,13 +4240,13 @@ msgid "Archived projects"
msgstr "归档项目"
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "归档项目将使其完全åªè¯»ã€‚仪表æ¿ä¸­å’Œæœç´¢ç»“果中都ä¸ä¼šå‡ºçŽ°è¯¥é¡¹ç›®ã€‚%{strong_start}代ç å°†æ— æ³•æ交到仓库,也无法创建任何议题ã€è¯„论或其它对象。%{strong_end}%{link_start}了解详情。%{link_end}"
msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
msgstr "您确定è¦åˆ é™¤æ­¤é¡¹ç›®å—?"
msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
-msgstr ""
+msgstr "您ç»å¯¹ç¡®å®šè¦åˆ é™¤æ­¤ç¾¤ç»„å—?"
msgid "Are you sure that you want to archive this project?"
msgstr "确定è¦å½’档此项目å—?"
@@ -4221,6 +4255,9 @@ msgid "Are you sure that you want to unarchive this project?"
msgstr "确定è¦å–消归档此项目å—?"
msgid "Are you sure you want to %{action} %{name}?"
+msgstr "æ‚¨ç¡®å®šè¦ %{action} %{name}å—?"
+
+msgid "Are you sure you want to attempt to merge?"
msgstr ""
msgid "Are you sure you want to cancel editing this comment?"
@@ -4380,9 +4417,6 @@ msgstr "产物已æˆåŠŸåˆ é™¤ã€‚"
msgid "Artifacts"
msgstr "产物"
-msgid "Artifacts maximum size"
-msgstr "产物最大大å°"
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr "éšç€æˆ‘们继续为SAST添加更多的功能,我们éžå¸¸æ¬¢è¿Žæ‚¨é€šè¿‡%{linkStart}此议题%{linkEnd}为SASTé…置功能æä¾›å馈。"
@@ -4405,7 +4439,7 @@ msgid "Ask again later"
msgstr "ç¨åŽå†é—®"
msgid "Ask someone with write access to resolve it."
-msgstr ""
+msgstr "请有写入æƒé™çš„人æ¥è§£å†³å®ƒã€‚"
msgid "Ask your group maintainer to set up a group runner."
msgstr "请è”系群组维护者设置一个群组级 Runner。"
@@ -4498,9 +4532,6 @@ msgstr "å—让人没有æƒé™"
msgid "Assignee lists not available with your current license"
msgstr "当å‰è®¸å¯è¯æ— æ³•ä½¿ç”¨æŒ‡æ´¾åˆ—表"
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr "指派列表显示分é…给选定用户的所有议题。"
-
msgid "Assignee(s)"
msgstr "指派人"
@@ -4517,7 +4548,7 @@ msgid "At least one approval from a code owner is required to change files match
msgstr "至少需è¦ä¸€ä¸ªä»£ç æ‰€æœ‰è€…批准,以便更改符åˆç›¸åº”çš„ CODEEWNER 规则的文件。"
msgid "At least one field of %{one_of_required_fields} must be present"
-msgstr ""
+msgstr "至少一个 %{one_of_required_fields} 字段必须存在"
msgid "At least one of group_id or project_id must be specified"
msgstr "必须指定至少一个group_id或 project_id"
@@ -4538,7 +4569,7 @@ msgid "Attach a file by drag &amp; drop or %{upload_link}"
msgstr "拖放文件到此处或%{upload_link}"
msgid "Attaching File - %{progress}"
-msgstr ""
+msgstr "附加文件中 - %{progress}"
msgid "Attaching a file"
msgid_plural "Attaching %d files"
@@ -4608,22 +4639,28 @@ msgid "Authenticate with GitHub"
msgstr "使用GitHub身份验è¯"
msgid "Authenticated API rate limit period in seconds"
-msgstr ""
+msgstr "以秒为å•ä½çš„èº«ä»½éªŒè¯ API 速率é™åˆ¶æœŸé™"
msgid "Authenticated API request rate limit"
msgstr "ç»è¿‡èº«ä»½éªŒè¯çš„API请求速率é™åˆ¶"
msgid "Authenticated API requests"
+msgstr "ç»è¿‡èº«ä»½éªŒè¯çš„ API 请求"
+
+msgid "Authenticated Git LFS rate limit period in seconds"
msgstr ""
-msgid "Authenticated web rate limit period in seconds"
+msgid "Authenticated Git LFS request rate limit"
msgstr ""
+msgid "Authenticated web rate limit period in seconds"
+msgstr "认è¯çš„网页速率é™åˆ¶æ—¶é—´ï¼ˆç§’)"
+
msgid "Authenticated web request rate limit"
msgstr "ç»è¿‡èº«ä»½éªŒè¯çš„web请求速率é™åˆ¶"
msgid "Authenticated web requests"
-msgstr ""
+msgstr "ç»è¿‡èº«ä»½éªŒè¯çš„ Web 请求"
msgid "Authenticating"
msgstr "认è¯"
@@ -4677,7 +4714,7 @@ msgid "Authorization required"
msgstr "需è¦æŽˆæƒ"
msgid "Authorization token duration (minutes)"
-msgstr ""
+msgstr "授æƒä»¤ç‰ŒæœŸé™ (分钟)"
msgid "Authorization was granted by entering your username and password in the application."
msgstr "在应用中输入您的用户å和密ç å³å®ŒæˆæŽˆæƒã€‚"
@@ -4713,13 +4750,13 @@ msgid "Auto stop successfully canceled."
msgstr "自动åœæ­¢å·²æˆåŠŸå–消。"
msgid "Auto-cancel redundant pipelines"
-msgstr ""
+msgstr "自动å–消多余的æµæ°´çº¿"
msgid "Auto-close referenced issues on default branch"
msgstr "自动关闭默认分支上的引用问题"
msgid "AutoDevOps|%{auto_devops_start}Automate building, testing, and deploying%{auto_devops_end} your applications based on your continuous integration and delivery configuration. %{quickstart_start}How do I get started?%{quickstart_end}"
-msgstr ""
+msgstr "æ ¹æ®æŒç»­çš„集æˆå’Œäº¤ä»˜é…置,%{auto_devops_start}自动构建,测试和部署%{auto_devops_end}您的应用程åºã€‚%{quickstart_start}我该如何开始?%{quickstart_end}"
msgid "AutoDevOps|Auto DevOps"
msgstr "Auto DevOps"
@@ -4743,7 +4780,7 @@ msgid "AutoDevOps|The Auto DevOps pipeline has been enabled and will be used if
msgstr "Auto DevOpsæµæ°´çº¿å·²å¯ç”¨ã€‚如果未找到CIé…置文件,将使用该æµæ°´çº¿ã€‚"
msgid "AutoDevopsAlert|Security testing tools enabled with %{linkStart}Auto DevOps%{linkEnd}"
-msgstr ""
+msgstr "å¯ç”¨å®‰å…¨æµ‹è¯•å·¥å…·åŠ %{linkStart}Auto DevOps%{linkEnd}"
msgid "AutoRemediation| 1 Merge Request"
msgstr "1个åˆå¹¶è¯·æ±‚"
@@ -4793,9 +4830,12 @@ msgstr "使用Let's Encrypt自动管ç†è¯ä¹¦"
msgid "Automatic deployment rollbacks"
msgstr "自动部署回滚"
-msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
+msgid "Automatic event tracking provides a traceable history for audits."
msgstr ""
+msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
+msgstr "当æ¢å¤è­¦æŠ¥é€šçŸ¥è§£å†³è­¦æŠ¥æ—¶è‡ªåŠ¨å…³é—­ç›¸å…³äº‹ä»¶"
+
msgid "Automatically resolved"
msgstr "自动解决"
@@ -4962,7 +5002,7 @@ msgid "BambooService|Run CI/CD pipelines with Atlassian Bamboo. You must set up
msgstr "使用Atlassian Bambooè¿è¡ŒCI/CDæµæ°´çº¿ã€‚您必须在Bamboo中设置自动修订标签和仓库触å‘器。 %{docs_link}"
msgid "BambooService|The user with API access to the Bamboo server."
-msgstr ""
+msgstr "对 Bamboo æœåŠ¡å™¨å…·æœ‰ API 访问æƒé™çš„用户。"
msgid "Based on"
msgstr "基于"
@@ -4974,10 +5014,10 @@ msgid "Be careful. Renaming a project's repository can have unintended side effe
msgstr "请注æ„,é‡å‘½å项目的仓库å¯èƒ½ä¼šäº§ç”Ÿéžé¢„期的副作用。"
msgid "Before enabling this integration, create a webhook for the room in Google Chat where you want to receive notifications from this project. %{docs_link}"
-msgstr ""
+msgstr "在å¯ç”¨æ­¤é›†æˆä¹‹å‰ï¼Œè¯·åœ¨ Google Chat 中为您希望从该项目接收通知的房间创建一个 webhook。 %{docs_link}"
msgid "Before inserting code, be sure to read the comment that separated each code group."
-msgstr ""
+msgstr "在æ’入代ç ä¹‹å‰ï¼Œè¯·åŠ¡å¿…阅读分隔æ¯ä¸ªä»£ç ç»„的注释。"
msgid "Before this can be merged, a Jira issue must be linked in the title or description"
msgstr "在åˆå¹¶ä¹‹å‰ï¼Œå¿…须在标题或æ述中链接Jira议题"
@@ -4985,9 +5025,6 @@ msgstr "在åˆå¹¶ä¹‹å‰ï¼Œå¿…须在标题或æ述中链接Jira议题"
msgid "Begin with the selected commit"
msgstr "从选定的æ交开始"
-msgid "Below are the current settings regarding"
-msgstr "以下是当å‰è®¾ç½®"
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr "下é¢æ˜¯å½“å‰å®žä¾‹SSH主机密钥的指纹。"
@@ -5022,7 +5059,7 @@ msgid "BillingPlans|Congratulations, your free trial is activated."
msgstr "æ­å–œï¼Œæ‚¨çš„试用计划已å¯ç”¨ã€‚"
msgid "BillingPlans|End of availability for the Bronze Plan"
-msgstr ""
+msgstr "Bronze方案已ä¸å¯ç”¨"
msgid "BillingPlans|Free upgrade!"
msgstr "å…è´¹å‡çº§ï¼"
@@ -5031,13 +5068,13 @@ msgid "BillingPlans|If you would like to downgrade your plan please contact %{su
msgstr "如果您想è¦é™çº§æ‚¨çš„订阅计划,请è”ç³»%{support_link_start}客户支æŒ%{support_link_end}。"
msgid "BillingPlans|Learn more about each plan by reading our %{faq_link}, or start a free 30-day trial of GitLab.com Ultimate."
-msgstr ""
+msgstr "å¯ä»¥é˜…读%{faq_link}了解更多付费方案细节,或者开始为期30天的试用。"
msgid "BillingPlans|Learn more about each plan by visiting our %{pricing_page_link}."
msgstr "通过阅读我们的 %{pricing_page_link} 了解有关æ¯ä¸ªè®¡åˆ’的更多信æ¯ã€‚"
msgid "BillingPlans|Looking to purchase or manage a subscription for your group? Navigate to your %{groups_link} and go to %{strong_open}Settings &gt; Billing.%{strong_close}"
-msgstr ""
+msgstr "想è¦ä¸ºæ‚¨çš„群组购买或管ç†è®¢é˜…?导航到您的 %{groups_link} 并转到 %{strong_open}设置 &gt; 计费。%{strong_close}"
msgid "BillingPlans|Manage plan"
msgstr "管ç†è®¡åˆ’"
@@ -5055,10 +5092,10 @@ msgid "BillingPlans|To manage the plan for this group, visit the billing section
msgstr "访问%{parent_billing_page_link}的计费部分以管ç†è¯¥é¡¹ç›®çš„订阅计划。"
msgid "BillingPlans|Upgrade to GitLab %{planNameForUpgrade}"
-msgstr ""
+msgstr "å‡çº§åˆ° %{planNameForUpgrade}"
msgid "BillingPlans|While GitLab is ending availability of the Bronze plan, you can still renew your Bronze subscription one additional time before %{eoa_bronze_plan_end_date}. We are also offering a limited time free upgrade to our Premium Plan (up to 25 users)! Learn more about the changes and offers in our %{announcement_link}."
-msgstr ""
+msgstr "虽然 GitLab å°†åœæ­¢ä½¿ç”¨ Bronze 方案,但您ä»ç„¶å¯ä»¥åœ¨ %{eoa_bronze_plan_end_date} 之å‰å†ç»­è®¢ä¸€æ¬¡ Bronze 订阅。 我们还æä¾›é™æ—¶å…è´¹å‡çº§åˆ°æˆ‘们的高级方案(最多 25 ä¸ªç”¨æˆ·ï¼‰ï¼ åœ¨æˆ‘ä»¬çš„ %{announcement_link} 中了解有关改å˜å’Œä¼˜æƒ çš„更多信æ¯ã€‚"
msgid "BillingPlans|Your GitLab.com %{plan} trial will %{strong_open}expire after %{expiration_date}%{strong_close}. You can retain access to the %{plan} features by upgrading below."
msgstr "您的GitLab.com%{plan}试用将在%{strong_open}%{expiration_date}过期%{strong_close}。您å¯ä»¥é€šè¿‡ä»¥ä¸‹æ–¹å¼å‡çº§ä»¥ä¿ç•™å¯¹%{plan}功能的访问æƒé™ã€‚"
@@ -5070,13 +5107,13 @@ msgid "BillingPlans|billed annually at %{price_per_year}"
msgstr "æ¯å¹´æ”¯ä»˜%{price_per_year}"
msgid "BillingPlans|for the remainder of your subscription"
-msgstr ""
+msgstr "适用于您订阅的剩余时间"
msgid "BillingPlans|frequently asked questions"
msgstr "常è§é—®é¢˜"
msgid "BillingPlans|group"
-msgstr ""
+msgstr "群组"
msgid "BillingPlans|monthly"
msgstr "æ¯æœˆ"
@@ -5094,40 +5131,40 @@ msgid "BillingPlan|Upgrade for free"
msgstr "å…è´¹å‡çº§"
msgid "Billings|%{planName} plan"
-msgstr ""
+msgstr "%{planName} 方案"
msgid "Billings|An error occurred while extending your trial."
-msgstr ""
+msgstr "延长试用期时出错。"
msgid "Billings|An error occurred while reactivating your trial."
-msgstr ""
+msgstr "é‡æ–°æ¿€æ´»æ‚¨çš„试用版时出错。"
msgid "Billings|By extending your trial, you will receive an additional 30 days of %{planName}. Your trial can be only extended once."
-msgstr ""
+msgstr "通过延长您的试用期,您将收到é¢å¤–30 天的 %{planName}。您的试用åªèƒ½å»¶é•¿ä¸€æ¬¡ã€‚"
msgid "Billings|By reactivating your trial, you will receive an additional 30 days of %{planName}. Your trial can be only reactivated once."
-msgstr ""
+msgstr "通过é‡æ–°æ¿€æ´»æ‚¨çš„试用,您将收到é¢å¤–30 天的 %{planName}。您的试用åªèƒ½é‡æ–°æ¿€æ´»ä¸€æ¬¡ã€‚"
msgid "Billings|Extend trial"
-msgstr ""
+msgstr "延长试用期"
msgid "Billings|Reactivate trial"
-msgstr ""
+msgstr "é‡æ–°æ¿€æ´»è¯•ç”¨"
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
-msgstr ""
+msgstr "Shared runners 无法å¯ç”¨ï¼Œç›´åˆ°æœ‰æ•ˆçš„信用å¡åœ¨æ¡£ã€‚"
msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
-msgstr ""
+msgstr "è¦åœ¨shared runners上使用å…è´¹æµæ°´çº¿æ—¶é•¿ï¼Œæ‚¨éœ€è¦ä½¿ç”¨ä¿¡ç”¨å¡æˆ–借记å¡éªŒè¯æ‚¨çš„å¸æˆ·ã€‚如果您ä¸æƒ³æ供,您å¯ä»¥é€šè¿‡ä¸ºæ‚¨çš„项目带æ¥è‡ªå·±çš„runner并ç¦ç”¨shared runnersæ¥è¿è¡Œæµæ°´çº¿ã€‚这是阻止和å‡å°‘对 GitLab 基础设施的滥用所必需的。 %{strongStart}GitLab ä¸ä¼šæ”¶è´¹æˆ–存储您的银行å¡ä¿¡æ¯ï¼Œå®ƒåªä¼šç”¨äºŽéªŒè¯æ‚¨çš„身份。%{strongEnd} %{linkStart}了解更多%{linkEnd}"
msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
+msgstr "è¦åœ¨shared runners上使用å…费的æµæ°´çº¿æ—¶é—´ï¼Œæ‚¨éœ€è¦ä½¿ç”¨ä¿¡ç”¨å¡æˆ–借记å¡éªŒè¯æ‚¨çš„è´¦å·ã€‚这样åšçš„目的是为了阻止和å‡å°‘GitLab 基础设施的滥用。 %{strongStart}GitLab ä¸ä¼šæ”¶è´¹æˆ–存储您的å¡å·ï¼Œå®ƒä»…用于验è¯ã€‚%{strongEnd}"
msgid "Billings|User successfully validated"
msgstr "用户验è¯æˆåŠŸ"
msgid "Billings|User validation required"
-msgstr ""
+msgstr "需è¦ç”¨æˆ·éªŒè¯"
msgid "Billings|Validate account"
msgstr "验è¯å¸æˆ·"
@@ -5142,13 +5179,13 @@ msgid "Billing|An email address is only visible for users with public emails."
msgstr "åªæœ‰ç”¨æˆ·è®¾ç½®äº†å…¬å¼€ç”µå­é‚®ä»¶ï¼Œä»–们的邮件æ‰å¯¹å¤–å¯è§ã€‚"
msgid "Billing|An error occurred while getting a billable member details"
-msgstr ""
+msgstr "获å–计费会员详细信æ¯æ—¶å‘生错误"
msgid "Billing|An error occurred while loading billable members list"
msgstr "加载收费æˆå‘˜åˆ—表时å‘生错误"
msgid "Billing|An error occurred while removing a billable member"
-msgstr ""
+msgstr "移除计费æˆå‘˜æ—¶å‡ºé”™"
msgid "Billing|Cannot remove user"
msgstr "无法删除用户"
@@ -5160,7 +5197,7 @@ msgid "Billing|Enter at least three characters to search."
msgstr "请至少输入三个字符æ‰å¯æœç´¢ã€‚"
msgid "Billing|Export list"
-msgstr ""
+msgstr "导出列表"
msgid "Billing|Group"
msgstr "群组"
@@ -5169,7 +5206,7 @@ msgid "Billing|Group invite"
msgstr "群组邀请"
msgid "Billing|Members who were invited via a group invitation cannot be removed. You can either remove the entire group, or ask an Owner of the invited group to remove the member."
-msgstr ""
+msgstr "无法删除通过群组邀请而邀请的æˆå‘˜ã€‚您å¯ä»¥ç§»é™¤æ•´ä¸ªç¾¤ç»„,也å¯ä»¥è¦æ±‚å—邀群组的所有者移除æˆå‘˜ã€‚"
msgid "Billing|No users to display."
msgstr "无用户å¯æ˜¾ç¤ºã€‚"
@@ -5178,16 +5215,16 @@ msgid "Billing|Private"
msgstr "ç§æœ‰"
msgid "Billing|Project invite"
-msgstr ""
+msgstr "项目邀请"
msgid "Billing|Remove user %{username} from your subscription"
-msgstr ""
+msgstr "从您的订阅中删除用户 %{username}"
msgid "Billing|Toggle seat details"
msgstr "切æ¢å¸­ä½è¯¦æƒ…"
msgid "Billing|Type %{username} to confirm"
-msgstr ""
+msgstr "输入 %{username} 进行确认"
msgid "Billing|User was successfully removed"
msgstr "用户已æˆåŠŸåˆ é™¤"
@@ -5196,7 +5233,7 @@ msgid "Billing|Users occupying seats in"
msgstr "å ç”¨å¸­ä½çš„用户于"
msgid "Billing|You are about to remove user %{username} from your subscription. If you continue, the user will be removed from the %{namespace} group and all its subgroups and projects. This action can't be undone."
-msgstr ""
+msgstr "您将è¦ä»Žè®¢é˜…中删除用户%{username}。如果继续,该用户将从 %{namespace} 群组åŠå…¶æ‰€æœ‰å­ç»„和项目中删除。此æ“作无法撤消。"
msgid "Bitbucket Server Import"
msgstr "BitbucketæœåŠ¡å™¨å¯¼å…¥"
@@ -5224,7 +5261,7 @@ msgid "Blocked issue"
msgstr "å—阻的议题"
msgid "Blocking"
-msgstr ""
+msgstr "阻塞"
msgid "Blocking issues"
msgstr "阻塞议题"
@@ -5251,10 +5288,10 @@ msgid "BoardNewIssue|Select a project"
msgstr "选择一个项目"
msgid "BoardScope|An error occurred while getting milestones, please try again."
-msgstr ""
+msgstr "获å–里程碑时å‘生错误,请é‡è¯•ã€‚"
msgid "BoardScope|An error occurred while searching for users, please try again."
-msgstr ""
+msgstr "æœç´¢ç”¨æˆ·æ—¶å‘生错误,请é‡è¯•ã€‚"
msgid "BoardScope|Any Milestone"
msgstr "任何里程碑"
@@ -5271,25 +5308,28 @@ msgstr "编辑"
msgid "BoardScope|Milestone"
msgstr "里程碑"
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
-msgstr ""
+msgstr "无里程碑"
msgid "BoardScope|Search milestones"
-msgstr ""
+msgstr "æœç´¢é‡Œç¨‹ç¢‘"
msgid "BoardScope|Select assignee"
-msgstr ""
+msgstr "选择指派人"
msgid "BoardScope|Select milestone"
+msgstr "选择里程碑"
+
+msgid "BoardScope|Select weight"
msgstr ""
msgid "BoardScope|Started"
-msgstr ""
+msgstr "已开始"
msgid "BoardScope|Upcoming"
+msgstr "å³å°†åˆ°æ¥"
+
+msgid "BoardScope|Weight"
msgstr ""
msgid "Boards"
@@ -5300,7 +5340,7 @@ msgstr "看æ¿å’Œçœ‹æ¿åˆ—表"
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
msgid_plural "Boards|+ %{displayedIssuablesCount} more %{issuableType}s"
-msgstr[0] ""
+msgstr[0] "+ %{displayedIssuablesCount} 更多 %{issuableType}"
msgid "Boards|An error occurred while creating the epic. Please try again."
msgstr "创建å²è¯—æ—¶å‘生了错误。请é‡è¯•ã€‚"
@@ -5351,9 +5391,6 @@ msgid "Boards|Blocked by %{blockedByCount} %{issuableType}"
msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] "被 %{blockedByCount} %{issuableType}ç¦ç”¨"
-msgid "Boards|Board"
-msgstr "看æ¿"
-
msgid "Boards|Collapse"
msgstr "收起"
@@ -5364,16 +5401,16 @@ msgid "Boards|Expand"
msgstr "展开"
msgid "Boards|Failed to fetch blocking %{issuableType}s"
-msgstr ""
+msgstr "无法获å–ç¦ç”¨çš„ %{issuableType}"
msgid "Boards|New epic"
msgstr "新建å²è¯—"
msgid "Boards|Retrieving blocking %{issuableType}s"
-msgstr ""
+msgstr "正在获å–阻塞的%{issuableType}"
msgid "Boards|View all blocking %{issuableType}s"
-msgstr ""
+msgstr "查看所有阻塞的%{issuableType}"
msgid "Boards|View scope"
msgstr "查看范围"
@@ -5649,43 +5686,37 @@ msgid "BulkImport|Existing groups"
msgstr "现有群组"
msgid "BulkImport|Filter by source group"
-msgstr ""
+msgstr "按æºç¾¤ç»„过滤"
msgid "BulkImport|From source group"
msgstr "从æºç¾¤ç»„"
-msgid "BulkImport|Import %{groups}"
-msgstr "导入 %{groups}"
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
-msgstr ""
+msgstr "导入失败:目标ä¸èƒ½æ˜¯æºç»„çš„å­ç»„。更改目标,然åŽé‡è¯•ã€‚"
msgid "BulkImport|Import groups from GitLab"
msgstr "从GitLab导入群组"
+msgid "BulkImport|Import selected"
+msgstr ""
+
msgid "BulkImport|Importing the group failed"
msgstr "导入群组失败"
msgid "BulkImport|Name already exists."
msgstr "å称已存在。"
-msgid "BulkImport|No groups on this page are available for import"
-msgstr ""
-
msgid "BulkImport|No parent"
msgstr "没有父级"
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr "显示 %{start}-%{end} / %{total}"
msgid "BulkImport|Showing %{start}-%{end} of %{total} from %{link}"
-msgstr ""
+msgstr "显示 %{start}-%{end} / %{total} - %{link}"
msgid "BulkImport|Showing %{start}-%{end} of %{total} matching filter \"%{filter}\" from %{link}"
-msgstr ""
+msgstr "显示从%{link}中匹é…筛选器“%{filter}†的 %{start}-%{end} / %{total}"
msgid "BulkImport|To new group"
msgstr "到新群组"
@@ -5694,7 +5725,7 @@ msgid "BulkImport|Update of import statuses with realtime changes failed"
msgstr "更新具有实时å˜æ›´çš„导入状æ€å¤±è´¥"
msgid "BulkImport|You have no groups to import"
-msgstr ""
+msgstr "您没有è¦å¯¼å…¥çš„群组"
msgid "BulkImport|expected an associated Group but has an associated Project"
msgstr "需与群组关è”但是当å‰ä¸Žé¡¹ç›®å…³è”"
@@ -5727,11 +5758,14 @@ msgid "Business metrics (Custom)"
msgstr "业务指标(自定义)"
msgid "Busy"
-msgstr ""
+msgstr "忙碌"
msgid "Buy CI Minutes"
msgstr "购买CI分钟数"
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr "购买更多æµæ°´çº¿æ—¶é—´"
@@ -5799,7 +5833,7 @@ msgid "CICDAnalytics|Lead time"
msgstr "交付时间"
msgid "CICDAnalytics|Projects with releases"
-msgstr ""
+msgstr "å‘布版本的项目"
msgid "CICDAnalytics|Release"
msgid_plural "CICDAnalytics|Releases"
@@ -5848,10 +5882,10 @@ msgid "CICD|Jobs"
msgstr "作业"
msgid "CICD|Limit CI_JOB_TOKEN access"
-msgstr ""
+msgstr "é™åˆ¶ CI_JOB_TOKEN 访问"
msgid "CICD|Select projects that can be accessed by API requests authenticated with this project's CI_JOB_TOKEN CI/CD variable."
-msgstr ""
+msgstr "选择å¯ä»¥é€šè¿‡ API 访问的项目请求验è¯æ­¤é¡¹ç›®çš„ CI_JOB_TOKEN CI/CD å˜é‡ã€‚"
msgid "CICD|The Auto DevOps pipeline runs by default in all projects with no CI/CD configuration file."
msgstr "Auto DevOps æµæ°´çº¿é»˜è®¤åœ¨æ²¡æœ‰CI/CDé…置文件的所有项目中è¿è¡Œã€‚"
@@ -5880,9 +5914,12 @@ msgstr "贡献信æ¯"
msgid "CPU"
msgstr "CPU"
-msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
+msgid "CSV is being generated and will be emailed to you upon completion."
msgstr ""
+msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
+msgstr "作为维护者,为您的项目中的æ¼æ´žè¯·æ±‚CVE将有助于您的用户ä¿æŒå®‰å…¨å’ŒçŸ¥æƒ…。"
+
msgid "CVE|CVE ID Request"
msgstr "CVE ID请求"
@@ -5908,25 +5945,25 @@ msgid "Callback URL"
msgstr "回调 URL"
msgid "Campfire room ID (optional)"
-msgstr ""
+msgstr "Campfire ID(å¯é€‰ï¼‰"
msgid "Campfire subdomain (optional)"
-msgstr ""
+msgstr "Campfire å­åŸŸï¼ˆå¯é€‰ï¼‰"
msgid "Campfire token"
-msgstr ""
+msgstr "Campfire 令牌"
msgid "CampfireService|API authentication token from Campfire."
-msgstr ""
+msgstr "æ¥è‡ª Campfire çš„ API 身份验è¯ä»¤ç‰Œã€‚"
msgid "CampfireService|From the end of the room URL."
-msgstr ""
+msgstr "从房间 URL 的末尾开始。"
msgid "CampfireService|Send notifications about push events to Campfire chat rooms. %{docs_link}"
-msgstr ""
+msgstr "å‘ Campfire èŠå¤©å®¤å‘é€æœ‰å…³æŽ¨é€äº‹ä»¶çš„通知。 %{docs_link}"
msgid "CampfireService|The %{code_open}.campfirenow.com%{code_close} subdomain."
-msgstr ""
+msgstr "%{code_open}.campfirenow.com%{code_close} å­åŸŸå。"
msgid "Can be manually deployed to"
msgstr "å¯ä»¥æ‰‹åŠ¨éƒ¨ç½²åˆ°"
@@ -5995,7 +6032,7 @@ msgid "CanaryIngress|Change the ratio of canary deployments?"
msgstr "更改canary部署比例?"
msgid "CanaryIngress|Doing so will set a deployment change in progress. This temporarily blocks any further configuration until the deployment is finished."
-msgstr ""
+msgstr "这样åšå°†è®¾ç½®æ­£åœ¨è¿›è¡Œçš„部署更改。这将暂时阻止任何进一步的é…置,直到部署完æˆã€‚"
msgid "CanaryIngress|Stable"
msgstr "Stable"
@@ -6019,7 +6056,7 @@ msgid "Cancel this job"
msgstr "å–消此作业"
msgid "Cancel your account"
-msgstr ""
+msgstr "å–消您的账户"
msgid "Cancel, keep project"
msgstr "å–消,ä¿ç•™é¡¹ç›®"
@@ -6046,7 +6083,7 @@ msgid "Cannot create the abuse report. This user has been blocked."
msgstr "无法创建滥用报告。此用户已被ç¦ç”¨ã€‚"
msgid "Cannot delete %{profile_name} referenced in security policy"
-msgstr ""
+msgstr "ä¸èƒ½åˆ é™¤å®‰å…¨ç­–略中引用的 %{profile_name}"
msgid "Cannot have multiple Jira imports running at the same time"
msgstr "ä¸èƒ½åŒæ—¶è¿è¡Œå¤šä¸ªJira导入"
@@ -6067,7 +6104,7 @@ msgid "Cannot merge"
msgstr "无法åˆå¹¶"
msgid "Cannot modify %{profile_name} referenced in security policy"
-msgstr ""
+msgstr "无法修改安全策略中引用的 %{profile_name}"
msgid "Cannot modify managed Kubernetes cluster"
msgstr "无法修改托管的 Kubernetes 集群"
@@ -6109,7 +6146,7 @@ msgid "CascadingSettings|This setting has been enforced by an instance admin."
msgstr "此设置已由实例管ç†å‘˜å¼ºåˆ¶æ‰§è¡Œã€‚"
msgid "CascadingSettings|This setting has been enforced by an owner of %{link}."
-msgstr ""
+msgstr "此设置已由%{link}的所有者强制执行。"
msgid "CascadingSettings|cannot be changed because it is locked by an ancestor"
msgstr "无法更改,因为它被父级é”定"
@@ -6337,7 +6374,7 @@ msgid "Check your Docker images for known vulnerabilities."
msgstr "检查您的Dockeré•œåƒæ˜¯å¦å­˜åœ¨å·²çŸ¥æ¼æ´ž."
msgid "Check your Kubernetes cluster images for known vulnerabilities."
-msgstr ""
+msgstr "检查您的 Kubernetes 集群镜åƒæ˜¯å¦å­˜åœ¨å·²çŸ¥æ¼æ´žã€‚"
msgid "Check your source instance permissions."
msgstr "检查您的æºå®žä¾‹æƒé™ã€‚"
@@ -6363,32 +6400,37 @@ msgstr "检查用户å是å¦å¯ç”¨..."
msgid "Checkout"
msgstr "支付"
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr "æ¯ä¸ªç”¨æˆ·æ¯å¹´%{selectedPlanPrice}美元"
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr "以%{lastFourDigits}结尾的%{cardType} "
msgid "Checkout|%{name}'s CI minutes"
-msgstr ""
+msgstr "%{name}的 CI 分钟"
msgid "Checkout|%{name}'s GitLab subscription"
msgstr "%{name}的GitLab订阅"
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr "%{selectedPlanText}计划"
msgid "Checkout|%{startDate} - %{endDate}"
msgstr "%{startDate} - %{endDate}"
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
-msgstr ""
+msgstr "%{totalCiMinutes} CI 分钟"
msgid "Checkout|(may be %{linkStart}charged upon purchase%{linkEnd})"
msgstr ""
@@ -6397,16 +6439,16 @@ msgid "Checkout|(x%{numberOfUsers})"
msgstr "(x%{numberOfUsers})"
msgid "Checkout|(x%{quantity})"
-msgstr ""
+msgstr "(x%{quantity})"
msgid "Checkout|Billing address"
msgstr "å¸å•åœ°å€"
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
-msgstr ""
+msgstr "CI 分钟包仅在您使用完订阅的æ¯æœˆé…é¢åŽä½¿ç”¨ã€‚é¢å¤–的分钟数将é€æœˆæ»šåŠ¨ï¼Œæœ‰æ•ˆæœŸä¸ºä¸€å¹´ã€‚"
msgid "Checkout|Checkout"
msgstr " 支付"
@@ -6490,7 +6532,7 @@ msgid "Checkout|Please select a state"
msgstr "请选择州"
msgid "Checkout|Purchase details"
-msgstr ""
+msgstr "购买详情"
msgid "Checkout|Select"
msgstr "选择"
@@ -6517,7 +6559,7 @@ msgid "Checkout|Total"
msgstr "总计"
msgid "Checkout|Total minutes: %{quantity}"
-msgstr ""
+msgstr "总分钟数:%{quantity}"
msgid "Checkout|Users"
msgstr "用户"
@@ -6538,7 +6580,7 @@ msgid "Checkout|company or team"
msgstr "å…¬å¸æˆ–团队"
msgid "Checkout|x 1,000 minutes per pack = %{strong}"
-msgstr ""
+msgstr "æ¯ä¸ªåŒ…x 1000分钟 = %{strong}"
msgid "Cherry-pick this commit"
msgstr "拣选此æ交"
@@ -6604,13 +6646,13 @@ msgid "Choose the top-level group for your repository imports."
msgstr "选择仓库导入的顶级群组。"
msgid "Choose visibility level, enable/disable project features and their permissions, disable email notifications, and show default award emoji."
-msgstr ""
+msgstr "选择å¯è§æ€§çº§åˆ«ï¼Œå¯ç”¨/ç¦ç”¨é¡¹ç›®åŠŸèƒ½åŠå…¶æƒé™ï¼Œç¦ç”¨ç”µå­é‚®ä»¶é€šçŸ¥ï¼Œå¹¶æ˜¾ç¤ºé»˜è®¤èµžèµè¡¨æƒ…符å·ã€‚"
msgid "Choose what content you want to see on a group’s overview page."
msgstr "选择您想è¦åœ¨ç¾¤ç»„概览页é¢æŸ¥çœ‹çš„内容。"
msgid "Choose which Git strategy to use when fetching the project."
-msgstr ""
+msgstr "选择获å–项目时è¦ä½¿ç”¨çš„ Git 策略。"
msgid "Choose which repositories you want to connect and run CI/CD pipelines."
msgstr "请选择è¦è¿žæŽ¥å¹¶è¿è¡Œ CI/CD æµæ°´çº¿çš„代ç ä»“库。"
@@ -6775,13 +6817,13 @@ msgid "ClassificationLabelUnavailable|is unavailable: %{reason}"
msgstr "ä¸å¯ç”¨: %{reason}"
msgid "Clean up after running %{link_start}git filter-repo%{link_end} on the repository."
-msgstr ""
+msgstr "在仓库上è¿è¡Œ %{link_start}git filter-repo%{link_end} åŽè¿›è¡Œæ¸…ç†ã€‚"
msgid "Clean up image tags"
msgstr "清ç†é•œåƒæ ‡ç­¾"
msgid "Cleanup policies are executed by background workers. This setting defines the maximum number of workers that can run concurrently. Set it to 0 to remove all workers and not execute the cleanup policies."
-msgstr ""
+msgstr "清ç†ç­–略由åŽå°worker执行。此设置定义了å¯ä»¥åŒæ—¶è¿è¡Œçš„最大worker数。将其设置为 0 以删除所有worker并且ä¸æ‰§è¡Œæ¸…ç†ç­–略。"
msgid "Cleanup policy maximum number of tags to be deleted"
msgstr "清ç†ç­–ç•¥è¦åˆ é™¤çš„最大标签数"
@@ -6790,7 +6832,7 @@ msgid "Cleanup policy maximum processing time (seconds)"
msgstr "清ç†ç­–略最大处ç†æ—¶é—´(秒)"
msgid "Cleanup policy maximum workers running concurrently"
-msgstr ""
+msgstr "清ç†ç­–略最大并å‘è¿è¡Œçš„workeræ•°é‡"
msgid "Clear"
msgstr "清除"
@@ -6976,22 +7018,22 @@ msgid "ClusterAgents|Access tokens"
msgstr "访问令牌"
msgid "ClusterAgents|Alternative installation methods"
-msgstr ""
+msgstr "其他安装方法"
msgid "ClusterAgents|An error occurred while loading your GitLab Agents"
msgstr "加载您的GitLab Agentæ—¶å‘生错误"
msgid "ClusterAgents|An error occurred while loading your agent"
-msgstr ""
+msgstr "加载代ç†æ—¶å‡ºé”™"
msgid "ClusterAgents|An unknown error occurred. Please try again."
-msgstr ""
+msgstr "å‘生未知错误。请é‡è¯•ã€‚"
msgid "ClusterAgents|Configuration"
msgstr "é…ç½®"
msgid "ClusterAgents|Copy token"
-msgstr ""
+msgstr "å¤åˆ¶ä»¤ç‰Œ"
msgid "ClusterAgents|Created by"
msgstr "创建人"
@@ -7006,11 +7048,14 @@ msgid "ClusterAgents|Description"
msgstr "æè¿°"
msgid "ClusterAgents|For alternative installation methods %{linkStart}go to the documentation%{linkEnd}."
-msgstr ""
+msgstr "关于替代安装方法,%{linkStart}转到文档%{linkEnd}。"
msgid "ClusterAgents|Go to the repository"
msgstr "转到仓库"
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr "安装新代ç†"
@@ -7026,9 +7071,6 @@ msgstr "上次使用"
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr "了解如何创建一个 agent 访问令牌"
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr "了解有关安装 GitLab Agent 的更多信æ¯"
-
msgid "ClusterAgents|Name"
msgstr "å称"
@@ -7426,7 +7468,7 @@ msgid "ClusterIntegration|Integration enabled"
msgstr "集æˆå·²å¯ç”¨"
msgid "ClusterIntegration|Integrations allow you to use applications installed in your cluster as part of your GitLab workflow."
-msgstr ""
+msgstr "集æˆå…许您使用安装在集群中的应用程åºä½œä¸º GitLab 工作æµç¨‹çš„一部分。"
msgid "ClusterIntegration|Key pair name"
msgstr "密钥对å"
@@ -7710,8 +7752,8 @@ msgstr "指定域将å…许您使用%{linkStart}Auto DevOps%{linkEnd}中的自动
msgid "ClusterIntegration|Subnets"
msgstr "å­ç½‘"
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
-msgstr "与您的角色关è”çš„Amazon资æºå称(ARN)。如果您没有é…置角色,请首先使用上述å¸æˆ·å’Œå¤–部ID在 %{startAwsLink}Amazon Web Services%{externalLinkIcon}%{endLink} 上创建一个。了解%{startMoreInfoLink}更多信æ¯%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
msgstr "用于对群集进行身份验è¯çš„ Kubernetes è¯ä¹¦ã€‚"
@@ -7948,13 +7990,13 @@ msgid "Collapse sidebar"
msgstr "收起侧边æ "
msgid "Collapses this file (only for you) until it’s changed again."
-msgstr ""
+msgstr "折å æ­¤æ–‡ä»¶ï¼ˆä»…适用于您),直到它å†æ¬¡å˜æ›´ã€‚"
msgid "Collector hostname"
msgstr "Collector主机å"
msgid "Colorize messages"
-msgstr ""
+msgstr "为消æ¯ç€è‰²"
msgid "ComboSearch is not defined"
msgstr "ComboSearch未定义"
@@ -8111,7 +8153,7 @@ msgid "Compare Git revisions"
msgstr "比较Gitæ交版本"
msgid "Compare GitLab editions"
-msgstr ""
+msgstr "比较 GitLab 版本"
msgid "Compare Revisions"
msgstr "比较版本"
@@ -8168,10 +8210,10 @@ msgid "CompareRevisions|There was an error while loading the branch/tag list. Pl
msgstr "加载分支/标签列表时å‘生错误。请é‡è¯•ã€‚"
msgid "CompareRevisions|There was an error while searching the branch/tag list. Please try again."
-msgstr ""
+msgstr "æœç´¢åˆ†æ”¯/标签列表时å‘生错误。请é‡è¯•ã€‚"
msgid "CompareRevisions|There was an error while updating the branch/tag list. Please try again."
-msgstr ""
+msgstr "更新分支/标签列表时å‘生错误。请é‡è¯•ã€‚"
msgid "CompareRevisions|View open merge request"
msgstr "查看开放的åˆå¹¶è¯·æ±‚"
@@ -8191,9 +8233,6 @@ msgstr "åˆè§„仪表æ¿"
msgid "Compliance framework"
msgstr "åˆè§„框架"
-msgid "Compliance framework (optional)"
-msgstr "åˆè§„框架(å¯é€‰)"
-
msgid "ComplianceDashboard|created by:"
msgstr "创建人:"
@@ -8201,16 +8240,16 @@ msgid "ComplianceFrameworks|Add framework"
msgstr "添加框架"
msgid "ComplianceFrameworks|Combines with the CI configuration at runtime."
-msgstr ""
+msgstr "è¿è¡Œæ—¶ä¸ŽCIé…置组åˆã€‚"
msgid "ComplianceFrameworks|Compliance framework deleted successfully"
msgstr "åˆè§„框架已æˆåŠŸåˆ é™¤"
msgid "ComplianceFrameworks|Compliance pipeline configuration location (optional)"
-msgstr ""
+msgstr "åˆè§„æµæ°´çº¿é…ç½®ä½ç½®ï¼ˆå¯é€‰ï¼‰"
msgid "ComplianceFrameworks|Could not find this configuration location, please try a different location"
-msgstr ""
+msgstr "找ä¸åˆ°æ­¤é…ç½®ä½ç½®ï¼Œè¯·å°è¯•å…¶å®ƒä½ç½®"
msgid "ComplianceFrameworks|Delete compliance framework %{framework}"
msgstr "删除åˆè§„框架%{framework}"
@@ -8246,7 +8285,7 @@ msgid "ComplianceFrameworks|Use %{codeStart}::%{codeEnd} to create a %{linkStart
msgstr "使用%{codeStart}::%{codeEnd}创建一个%{linkStart}范围集%{linkEnd} (例如 %{codeStart}SOX::AWS%{codeEnd})"
msgid "ComplianceFrameworks|You are about to permanently delete the compliance framework %{framework} from all projects which currently have it applied, which may remove other functionality. This cannot be undone."
-msgstr ""
+msgstr "您å³å°†ä»Žæ‰€æœ‰å½“å‰åº”用的项目中永久删除åˆè§„框架 %{framework} ,这å¯èƒ½ä¼šåˆ é™¤å…¶å®ƒåŠŸèƒ½ã€‚æ­¤æ“作无法撤消。"
msgid "ComplianceFrameworks|e.g. include-gitlab.ci.yml@group-name/project-name"
msgstr "例如include-gitlab.ci.yml@group-name/project-name"
@@ -8282,13 +8321,13 @@ msgid "Configure %{link} to track events. %{link_start}Learn more.%{link_end}"
msgstr "é…ç½® %{link} æ¥è·Ÿè¸ªäº‹ä»¶ã€‚ %{link_start}了解更多信æ¯ã€‚%{link_end}"
msgid "Configure %{repository_checks_link_start}repository checks%{link_end} and %{housekeeping_link_start}housekeeping%{link_end} on repositories."
-msgstr ""
+msgstr "在仓库上é…ç½® %{repository_checks_link_start}仓库检查%{link_end} å’Œ %{housekeeping_link_start}例行维护%{link_end}。"
msgid "Configure Dependency Scanning in `.gitlab-ci.yml` using the GitLab managed template. You can [add variable overrides](https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings) to customize Dependency Scanning settings."
msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
-msgstr ""
+msgstr "在`.gitlab-ci.yml`中é…ç½®ä¾èµ–扫æ,如果该文件ä¸å­˜åœ¨åˆ™åˆ›å»ºè¯¥æ–‡ä»¶"
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr "é…ç½® GitLab Runner 以开始使用Web终端。 %{helpStart}了解更多。%{helpEnd}"
@@ -8306,13 +8345,13 @@ msgid "Configure SAST in `.gitlab-ci.yml` using the GitLab managed template. You
msgstr ""
msgid "Configure SAST in `.gitlab-ci.yml`, creating this file if it does not already exist"
-msgstr ""
+msgstr "在 `.gitlab-ci.yml` 中é…ç½® SAST,如果该文件ä¸å­˜åœ¨åˆ™åˆ›å»ºæ­¤æ–‡ä»¶"
msgid "Configure Secret Detection in `.gitlab-ci.yml` using the GitLab managed template. You can [add variable overrides](https://docs.gitlab.com/ee/user/application_security/secret_detection/#customizing-settings) to customize Secret Detection settings."
msgstr ""
msgid "Configure Secret Detection in `.gitlab-ci.yml`, creating this file if it does not already exist"
-msgstr ""
+msgstr "在 `.gitlab-ci.yml` 中é…ç½® Secret Detection,如果该文件ä¸å­˜åœ¨åˆ™åˆ›å»ºæ­¤æ–‡ä»¶"
msgid "Configure Tracing"
msgstr "é…置跟踪"
@@ -8324,7 +8363,7 @@ msgid "Configure existing installation"
msgstr "é…置现有安装"
msgid "Configure limit for notes created per minute by web and API requests."
-msgstr ""
+msgstr "é…置由网页和API请求创建的æ¯åˆ†é’Ÿå¤‡æ³¨æ•°é‡é™åˆ¶ã€‚"
msgid "Configure limits for Project/Group Import/Export."
msgstr "é…置项目/群组的导入/导出é™åˆ¶ã€‚"
@@ -8332,9 +8371,6 @@ msgstr "é…置项目/群组的导入/导出é™åˆ¶ã€‚"
msgid "Configure limits for web and API requests."
msgstr "é…ç½® web å’Œ API 请求é™åˆ¶ã€‚"
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr "é…ç½®å¯ä»¥å‘é€åˆ°é¡¹ç›®çš„传入警报的数é‡ã€‚"
-
msgid "Configure paths to be protected by Rack Attack."
msgstr "é…ç½®è¦ä¿æŠ¤æœºæž¶æ”»å‡»çš„路径。"
@@ -8347,6 +8383,9 @@ msgstr "é…置仓库存储。"
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr "使用 Elasticsearch é…置高级æœç´¢çš„设置。"
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -8354,7 +8393,7 @@ msgid "Configure the %{link} integration."
msgstr "é…ç½® %{link} 集æˆã€‚"
msgid "Configure the default first day of the week and time tracking units."
-msgstr ""
+msgstr "é…置默认的æ¯å‘¨ç¬¬ä¸€å¤©å’Œæ—¶é—´è·Ÿè¸ªå•ä½ã€‚"
msgid "Configure the way a user creates a new account."
msgstr "é…置用户创建新å¸æˆ·çš„æ–¹å¼ã€‚"
@@ -8390,43 +8429,43 @@ msgid "Confirmed:"
msgstr "已确认:"
msgid "Conflict: This file was added both in the source and target branches, but with different contents."
-msgstr ""
+msgstr "冲çªï¼šæ­¤æ–‡ä»¶å·²æ·»åŠ åˆ°æºåˆ†æ”¯å’Œç›®æ ‡åˆ†æ”¯ä¸­ï¼Œä½†å†…容ä¸åŒã€‚"
msgid "Conflict: This file was modified in both the source and target branches."
-msgstr ""
+msgstr "冲çªï¼šæ­¤æ–‡ä»¶åœ¨æºåˆ†æ”¯å’Œç›®æ ‡åˆ†æ”¯ä¸­éƒ½è¢«ä¿®æ”¹ã€‚"
msgid "Conflict: This file was modified in the source branch, but removed in the target branch."
-msgstr ""
+msgstr "冲çªï¼šæ­¤æ–‡ä»¶åœ¨æºåˆ†æ”¯ä¸­è¢«ä¿®æ”¹ï¼Œä½†åœ¨ç›®æ ‡åˆ†æ”¯ä¸­è¢«åˆ é™¤ã€‚"
msgid "Conflict: This file was removed in the source branch, but modified in the target branch."
-msgstr ""
+msgstr "冲çªï¼šæ­¤æ–‡ä»¶åœ¨æºåˆ†æ”¯ä¸­è¢«åˆ é™¤ï¼Œä½†åœ¨ç›®æ ‡åˆ†æ”¯ä¸­è¢«ä¿®æ”¹ã€‚"
msgid "Conflict: This file was removed in the source branch, but renamed in the target branch."
-msgstr ""
+msgstr "冲çªï¼šæ­¤æ–‡ä»¶åœ¨æºåˆ†æ”¯ä¸­è¢«åˆ é™¤ï¼Œä½†åœ¨ç›®æ ‡åˆ†æ”¯ä¸­è¢«é‡å‘½å。"
msgid "Conflict: This file was renamed differently in the source and target branches."
-msgstr ""
+msgstr "冲çªï¼šæ­¤æ–‡ä»¶åœ¨æºåˆ†æ”¯å’Œç›®æ ‡åˆ†æ”¯ä¸­çš„é‡å‘½åä¸åŒã€‚"
msgid "Conflict: This file was renamed in the source branch, but removed in the target branch."
-msgstr ""
+msgstr "冲çªï¼šæ­¤æ–‡ä»¶åœ¨æºåˆ†æ”¯ä¸­è¢«é‡å‘½å,但在目标分支中被删除。"
msgid "Confluence"
msgstr "Confluence"
msgid "Confluence Cloud Workspace URL"
-msgstr ""
+msgstr "Confluence 云工作区 URL"
msgid "ConfluenceService|Confluence Workspace"
msgstr "Confluence工作区"
msgid "ConfluenceService|Link to a Confluence Workspace from the sidebar."
-msgstr ""
+msgstr "从侧边æ é“¾æŽ¥åˆ° Confluence 工作区。"
msgid "ConfluenceService|Link to a Confluence Workspace from the sidebar. Enabling this integration replaces the \"Wiki\" sidebar link with a link to the Confluence Workspace. The GitLab wiki is still available at the original URL."
-msgstr ""
+msgstr "从侧边æ é“¾æŽ¥åˆ° Confluence 工作区。å¯ç”¨æ­¤é›†æˆä¼šå°†â€œWikiâ€ä¾§è¾¹æ é“¾æŽ¥æ›¿æ¢ä¸º Confluence 工作区的链接。 GitLab wiki ä»ç„¶åœ¨åŽŸå§‹ URL 上å¯ç”¨ã€‚"
msgid "ConfluenceService|Your GitLab wiki is still available at %{wiki_link}. To re-enable the link to the GitLab wiki, disable this integration."
-msgstr ""
+msgstr "您的 GitLab wiki 在 %{wiki_link}ä»ç„¶å¯ç”¨ã€‚è¦é‡æ–°å¯ç”¨ GitLab wiki 的链接,请ç¦ç”¨æ­¤é›†æˆã€‚"
msgid "Congratulations, your free trial is activated."
msgstr "æ­å–œï¼Œæ‚¨çš„å…费试用已激活。"
@@ -8629,7 +8668,7 @@ msgid "ContainerRegistry|Image repository will be deleted"
msgstr "é•œåƒä»“库将被删除"
msgid "ContainerRegistry|Image repository with no name located at the project URL."
-msgstr ""
+msgstr "ä½äºŽé¡¹ç›® URL 中的没有å称的镜åƒä»“库。"
msgid "ContainerRegistry|Image tags"
msgstr "é•œåƒæ ‡ç­¾"
@@ -8786,7 +8825,7 @@ msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr "此镜åƒä»“库已安排删除"
msgid "ContainerRegistry|This image repository will be deleted. %{linkStart}Learn more.%{linkEnd}"
-msgstr ""
+msgstr "这个镜åƒä»“库将被删除。 %{linkStart}了解更多。%{linkEnd}"
msgid "ContainerRegistry|This project's cleanup policy for tags is not enabled."
msgstr "此项目的标签清ç†ç­–略未å¯ç”¨ã€‚"
@@ -8822,10 +8861,10 @@ msgid "Contains %{count} blobs of images (%{size})"
msgstr "包å«é•œåƒ(%{size})çš„%{count}个blob"
msgid "Content parsed with %{link}."
-msgstr ""
+msgstr "%{link}解æžçš„内容。"
msgid "ContentEditor|You have to provide a renderMarkdown function or a custom serializer"
-msgstr ""
+msgstr "您必须æä¾›renderMarkdown 函数或自定义åºåˆ—化程åº"
msgid "Contents of .gitlab-ci.yml"
msgstr ".gitlab-ci.yml的内容"
@@ -8861,7 +8900,7 @@ msgid "ContributionAnalytics|%{created_count} created, %{closed_count} closed."
msgstr "创建%{created_count}个,关闭%{closed_count}个。"
msgid "ContributionAnalytics|%{created_count} created, %{merged_count} merged, %{closed_count} closed."
-msgstr ""
+msgstr "已创建%{created_count}个,已åˆå¹¶%{merged_count}个,已关闭%{closed_count}个。"
msgid "ContributionAnalytics|%{pushes} pushes, more than %{commits} commits by %{people} contributors."
msgstr "%{pushes}次推é€ï¼Œè¶…过%{people}个贡献者的%{commits}次æ交。"
@@ -8909,13 +8948,13 @@ msgid "Control emails linked to your account"
msgstr "控制与您å¸æˆ·å…³è”的电å­é‚®ä»¶"
msgid "Control how the GitLab Package Registry functions."
-msgstr ""
+msgstr "控制 GitLab 软件包仓库是如何è¿ä½œçš„。"
msgid "Control whether to display third-party offers in GitLab."
-msgstr ""
+msgstr "控制是å¦åœ¨ GitLab中显示第三方è¦çº¦ã€‚"
msgid "Control which projects can be accessed by API requests authenticated with this project's CI_JOB_TOKEN CI/CD variable. It is a security risk to disable this feature, because unauthorized projects might attempt to retrieve an active token and access the API."
-msgstr ""
+msgstr "控制使用此项目的 CI_JOB_TOKEN CI/CD å˜é‡è¿›è¡Œèº«ä»½éªŒè¯çš„ API 请求å¯ä»¥è®¿é—®å“ªäº›é¡¹ç›®ã€‚ç¦ç”¨æ­¤åŠŸèƒ½å­˜åœ¨å®‰å…¨é£Žé™©ï¼Œå› ä¸ºæœªç»æŽˆæƒçš„项目å¯èƒ½ä¼šå°è¯•æ£€ç´¢æ´»åŠ¨ä»¤ç‰Œå¹¶è®¿é—® API。"
msgid "Cookie domain"
msgstr "Cookie域"
@@ -9044,16 +9083,16 @@ msgid "Corpus Management|Are you sure you want to delete the corpus?"
msgstr "确定è¦åˆ é™¤è¯­æ–™åº“å—?"
msgid "CorpusManagement|Actions"
-msgstr ""
+msgstr "动作"
msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
-msgstr ""
+msgstr "语料库在模糊测试中用作å˜å¼‚æºä»¥æ”¹è¿›æœªæ¥çš„测试。"
msgid "CorpusManagement|Corpus name"
-msgstr ""
+msgstr "语料库å称"
msgid "CorpusManagement|Fuzz testing corpus management"
-msgstr ""
+msgstr "模糊测试语料库管ç†"
msgid "CorpusManagement|Last updated"
msgstr "最åŽæ›´æ–°"
@@ -9064,7 +9103,7 @@ msgstr "最åŽä½¿ç”¨"
msgid "CorpusManagement|Latest Job:"
msgstr "最新作业:"
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -9077,19 +9116,19 @@ msgid "CorpusManagement|Target"
msgstr "目标"
msgid "CorpusManagement|To use this corpus, edit the corresponding YAML file"
-msgstr ""
+msgstr "è¦ä½¿ç”¨è¿™ä¸ªè¯­æ–™åº“,编辑对应的YAML文件"
msgid "CorpusManagement|Total Size: %{totalSize}"
-msgstr ""
+msgstr "总大å°ï¼š %{totalSize}"
msgid "CorpusMnagement|New corpus"
-msgstr ""
+msgstr "新建语料库"
msgid "Could not add admins as members"
msgstr "无法将管ç†å‘˜æ·»åŠ ä¸ºæˆå‘˜"
msgid "Could not apply %{name} command."
-msgstr ""
+msgstr "无法应用 %{name} 命令。"
msgid "Could not archive %{design}. Please try again."
msgstr "无法归档%{design}。请é‡è¯•ã€‚"
@@ -9140,7 +9179,7 @@ msgid "Could not draw the lines for job relationships"
msgstr "无法绘制代表作业关系的线"
msgid "Could not fetch policy because existing policy YAML is invalid"
-msgstr ""
+msgstr "无法获å–策略,因为现有的策略 YAML 无效"
msgid "Could not find design."
msgstr "未找到设计."
@@ -9149,19 +9188,19 @@ msgid "Could not find iteration"
msgstr "未找到迭代"
msgid "Could not get the data properly"
-msgstr ""
+msgstr "无法正确获å–æ•°æ®"
msgid "Could not load the user chart. Please refresh the page to try again."
msgstr "无法加载用户图表。请刷新页é¢ä»¥é‡è¯•ã€‚"
msgid "Could not load usage counts. Please refresh the page to try again."
-msgstr ""
+msgstr "无法加载使用计数。请刷新页é¢é‡è¯•ã€‚"
msgid "Could not remove %{user} from %{group}. Cannot remove last group owner."
-msgstr ""
+msgstr "无法将 %{user} 从 %{group}中移除。无法移除最åŽä¸€ä¸ªç¾¤ç»„所有者。"
msgid "Could not remove %{user} from %{group}. User is not a group member."
-msgstr ""
+msgstr "无法从%{group}中移除%{user}。用户ä¸æ˜¯ç¾¤ç»„æˆå‘˜ã€‚"
msgid "Could not remove the trigger."
msgstr "无法删除触å‘器。"
@@ -9197,7 +9236,7 @@ msgid "Could not upload your designs as one or more files uploaded are not suppo
msgstr "无法上传您的设计,因为ä¸æ”¯æŒå·²ä¸Šä¼ ä¸€ä¸ªæˆ–多个的文件。"
msgid "Couldn't assign policy to project"
-msgstr ""
+msgstr "无法将策略分é…给项目"
msgid "Coverage"
msgstr "覆盖率"
@@ -9212,7 +9251,7 @@ msgid "Create %{environment}"
msgstr "创建%{environment}"
msgid "Create %{humanized_resource_name}"
-msgstr ""
+msgstr "创建%{humanized_resource_name}"
msgid "Create %{type}"
msgstr "创建%{type}"
@@ -9236,7 +9275,7 @@ msgid "Create a merge request"
msgstr "创建一个åˆå¹¶ç”³è¯·"
msgid "Create a new %{codeStart}.gitlab-ci.yml%{codeEnd} file at the root of the repository to get started."
-msgstr ""
+msgstr "在仓库的根目录创建一个新的 %{codeStart}.gitlab-ci.yml%{codeEnd} 文件以开始æ“作。"
msgid "Create a new branch"
msgstr "创建一个新分支"
@@ -9257,7 +9296,7 @@ msgid "Create an account using:"
msgstr "使用以下方å¼åˆ›å»ºå¸æˆ·ï¼š"
msgid "Create an incident. Incidents are created for each alert triggered."
-msgstr ""
+msgstr "创建一个事件,æ¯æ¬¡è§¦å‘的警报都会创建事件。"
msgid "Create and provide your GitHub %{link_start}Personal Access Token%{link_end}. You will need to select the %{code_open}repo%{code_close} scope, so we can display a list of your public and private repositories which are available to import."
msgstr "请创建并æ供您的GitHub%{link_start}个人访问令牌%{link_end}。您需è¦é€‰æ‹©%{code_open}repo%{code_close}范围,这样我们æ‰å¯ä»¥å‘您显示å¯å¯¼å…¥çš„公共和ç§æœ‰ä»“库的列表。"
@@ -9404,10 +9443,10 @@ msgid "CreateValueStreamForm|%{name} (default)"
msgstr "%{name} (默认)"
msgid "CreateValueStreamForm|'%{name}' Value Stream created"
-msgstr ""
+msgstr "'%{name}' 价值æµå·²åˆ›å»º"
msgid "CreateValueStreamForm|'%{name}' Value Stream saved"
-msgstr ""
+msgstr "'%{name}' 价值æµå·²ä¿å­˜"
msgid "CreateValueStreamForm|Add another stage"
msgstr "添加å¦ä¸€ä¸ªé˜¶æ®µ"
@@ -9422,25 +9461,25 @@ msgid "CreateValueStreamForm|Code stage start"
msgstr "代ç é˜¶æ®µå¼€å§‹"
msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
+msgstr "创建价值æµ"
msgid "CreateValueStreamForm|Create from default template"
msgstr "从默认模æ¿åˆ›å»º"
msgid "CreateValueStreamForm|Create from no template"
-msgstr ""
+msgstr "从无模æ¿åˆ›å»º"
msgid "CreateValueStreamForm|Create new Value Stream"
-msgstr ""
+msgstr "创建新的价值æµ"
msgid "CreateValueStreamForm|Default stages"
msgstr "默认阶段"
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
-msgstr ""
+msgstr "默认阶段åªèƒ½è¢«éšè—或é‡æ–°æŽ’åº"
msgid "CreateValueStreamForm|Edit Value Stream"
-msgstr ""
+msgstr "编辑价值æµ"
msgid "CreateValueStreamForm|Editing stage"
msgstr "编辑阶段"
@@ -9458,10 +9497,10 @@ msgid "CreateValueStreamForm|Enter stage name"
msgstr "输入阶段å称"
msgid "CreateValueStreamForm|Enter value stream name"
-msgstr ""
+msgstr "输入价值æµå称"
msgid "CreateValueStreamForm|Issue stage end"
-msgstr ""
+msgstr "å‘行阶段结æŸ"
msgid "CreateValueStreamForm|Maximum length %{maxLength} characters"
msgstr "最大长度%{maxLength}个字符"
@@ -9491,7 +9530,7 @@ msgid "CreateValueStreamForm|Restore stage"
msgstr "æ¢å¤é˜¶æ®µ"
msgid "CreateValueStreamForm|Save Value Stream"
-msgstr ""
+msgstr "ä¿å­˜ä»·å€¼æµ"
msgid "CreateValueStreamForm|Select end event"
msgstr "选择结æŸäº‹ä»¶"
@@ -9506,7 +9545,7 @@ msgid "CreateValueStreamForm|Stage name already exists"
msgstr "阶段å称已存在"
msgid "CreateValueStreamForm|Stage name is required"
-msgstr ""
+msgstr "阶段å称是必需的"
msgid "CreateValueStreamForm|Start event"
msgstr "开始事件"
@@ -9524,13 +9563,13 @@ msgid "CreateValueStreamForm|Update stage"
msgstr "更新阶段"
msgid "CreateValueStreamForm|Value Stream name"
-msgstr ""
+msgstr "价值æµå称"
msgid "Created"
msgstr "创建于"
msgid "Created %{epicTimeagoDate}"
-msgstr ""
+msgstr "创建于 %{epicTimeagoDate}"
msgid "Created %{timestamp}"
msgstr "创建于%{timestamp}"
@@ -9602,7 +9641,7 @@ msgid "Credentials"
msgstr "凭æ®"
msgid "CredentialsInventory|GPG Keys"
-msgstr ""
+msgstr "GPG密钥"
msgid "CredentialsInventory|No credentials found"
msgstr "找ä¸åˆ°å‡­è¯"
@@ -9632,22 +9671,22 @@ msgid "Crowd"
msgstr "Crowd"
msgid "CsvParser|Failed to render the CSV file for the following reasons:"
-msgstr ""
+msgstr "由于以下原因未能呈现 CSV 文件:"
msgid "CsvParser|Quoted field unterminated"
-msgstr ""
+msgstr "带引å·çš„字段未终止"
msgid "CsvParser|Too few fields"
-msgstr ""
+msgstr "字段太少"
msgid "CsvParser|Too many fields"
-msgstr ""
+msgstr "字段太多"
msgid "CsvParser|Trailing quote on quoted field is malformed"
-msgstr ""
+msgstr "带引å·å­—段的尾éšå¼•å·æ ¼å¼ä¸æ­£ç¡®"
msgid "CsvParser|Unable to auto-detect delimiter; defaulted to \",\""
-msgstr ""
+msgstr "无法自动检测分隔符;默认为“,â€"
msgid "Current"
msgstr "当å‰"
@@ -9659,7 +9698,7 @@ msgid "Current Project"
msgstr "当å‰é¡¹ç›®"
msgid "Current forks will keep their visibility level."
-msgstr ""
+msgstr "当å‰æ´¾ç”Ÿï¼ˆfork)将ä¿æŒå…¶å¯è§ç­‰çº§ã€‚"
msgid "Current node must be the primary node or you will be locking yourself out"
msgstr "当å‰èŠ‚点必须是主节点,å¦åˆ™æ‚¨å°†ä¼šé”定自己。"
@@ -9713,7 +9752,7 @@ msgid "Custom notification events"
msgstr "自定义通知事件"
msgid "Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notificationLinkStart} notification emails%{notificationLinkEnd}."
-msgstr ""
+msgstr "自定义通知级别与å‚与级别相åŒã€‚通过自定义通知级别,您也会收到所选事件的通知。è¦æŸ¥æ‰¾æ›´å¤šä¿¡æ¯ï¼Œè¯·æŸ¥çœ‹ %{notificationLinkStart} 通知电å­é‚®ä»¶%{notificationLinkEnd}。"
msgid "Custom project templates"
msgstr "自定义项目模æ¿"
@@ -9731,7 +9770,7 @@ msgid "Customizable by an administrator."
msgstr "å¯ç”±ç®¡ç†å‘˜è‡ªå®šä¹‰ã€‚"
msgid "Customizable by owners."
-msgstr ""
+msgstr "由所有者自定义。"
msgid "Customize CI/CD settings, including Auto DevOps, shared runners, and job artifacts."
msgstr "自定义 CI/CD 设置,包括 Auto DevOpsã€å…±äº«Runner和作业产物。"
@@ -9752,7 +9791,7 @@ msgid "Customize name"
msgstr "自定义å称"
msgid "Customize your pipeline configuration and coverage report."
-msgstr ""
+msgstr "自定义您的æµæ°´çº¿é…置和覆盖率报告。"
msgid "Customize your pipeline configuration."
msgstr "自定义您的æµæ°´çº¿é…置。"
@@ -9770,16 +9809,16 @@ msgid "Cycle Time"
msgstr "周期时间"
msgid "CycleAnalyticsEvent|%{label_reference} label was added to the issue"
-msgstr ""
+msgstr "%{label_reference} 标记已添加到议题"
msgid "CycleAnalyticsEvent|%{label_reference} label was added to the merge request"
-msgstr ""
+msgstr "%{label_reference} 标记已添加到åˆå¹¶è¯·æ±‚"
msgid "CycleAnalyticsEvent|%{label_reference} label was removed from the issue"
-msgstr ""
+msgstr "%{label_reference} 标记已从议题中删除"
msgid "CycleAnalyticsEvent|%{label_reference} label was removed from the merge request"
-msgstr ""
+msgstr "%{label_reference} 标记已从åˆå¹¶è¯·æ±‚中删除"
msgid "CycleAnalyticsEvent|Issue closed"
msgstr "议题关闭"
@@ -9907,7 +9946,7 @@ msgstr "显示"
msgid "CycleAnalytics|Showing %{subjectFilterText} and %{selectedLabelsCount} label"
msgid_plural "CycleAnalytics|Showing %{subjectFilterText} and %{selectedLabelsCount} labels"
-msgstr[0] ""
+msgstr[0] "显示 %{subjectFilterText} 和 %{selectedLabelsCount} 标记"
msgid "CycleAnalytics|Showing data for group '%{groupName}' and %{selectedProjectCount} projects from %{startDate} to %{endDate}"
msgstr "显示群组'%{groupName}'å’Œ%{selectedProjectCount}个项目从%{startDate}到%{endDate}çš„æ•°æ®"
@@ -9922,7 +9961,7 @@ msgid "CycleAnalytics|Tasks by type"
msgstr "按类型的任务"
msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
-msgstr ""
+msgstr "æ¯ä¸ªæ—¥æœŸå®Œæˆçš„项目在选定阶段花费的平å‡æ—¶é—´ã€‚æ•°æ®ä»…é™äºŽæœ€è¿‘ 500 项。"
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr "给定的日期范围大于180天"
@@ -9970,7 +10009,7 @@ msgid "DORA4Metrics|Lead time"
msgstr "交付时间"
msgid "DORA4Metrics|Median lead time"
-msgstr ""
+msgstr "中ä½äº¤ä»˜æ—¶é—´"
msgid "DORA4Metrics|No merge requests were deployed during this period"
msgstr "在此期间没有部署åˆå¹¶è¯·æ±‚"
@@ -9982,13 +10021,13 @@ msgid "DORA4Metrics|Something went wrong while getting deployment frequency data
msgstr "获å–部署频率数æ®æ—¶å‡ºé”™ã€‚"
msgid "DORA4Metrics|Something went wrong while getting lead time data."
-msgstr ""
+msgstr "获å–交付时间数æ®æ—¶å‡ºäº†é”™ã€‚"
msgid "DORA4Metrics|The chart displays the frequency of deployments to production environment(s) that are based on the %{linkStart}deployment_tier%{linkEnd} value."
-msgstr ""
+msgstr "该图表显示基于 %{linkStart}deployment_tier%{linkEnd} 值的生产环境部署频率。"
msgid "DORA4Metrics|The chart displays the median time between a merge request being merged and deployed to production environment(s) that are based on the %{linkStart}deployment_tier%{linkEnd} value."
-msgstr ""
+msgstr "该图表显示åˆå¹¶è¯·æ±‚被åˆå¹¶å’Œéƒ¨ç½²åˆ°ç”Ÿäº§çŽ¯å¢ƒä¹‹é—´çš„中间值时间,这些时间基于 %{linkStart}deployment_tier%{linkEnd} 值。"
msgid "Dashboard"
msgstr "仪表æ¿"
@@ -10012,10 +10051,10 @@ msgid "Dashboard|%{firstProject}, %{rest}, and %{secondProject}"
msgstr "%{firstProject}ã€%{rest} å’Œ %{secondProject}"
msgid "Dashboard|Unable to add %{invalidProjects}. This dashboard is available for public projects, and private projects in groups with a Premium plan."
-msgstr ""
+msgstr "无法添加 %{invalidProjects}。此仪表æ¿å¯ç”¨äºŽå…¬å…±é¡¹ç›®å’Œå…·æœ‰ä¸“业版的群组中的ç§äººé¡¹ç›®ã€‚"
msgid "DastConfig|Customize DAST settings to suit your requirements. Configuration changes made here override those provided by GitLab and are excluded from updates. For details of more advanced configuration options, see the %{docsLinkStart}GitLab DAST documentation%{docsLinkEnd}."
-msgstr ""
+msgstr "自定义 DAST 设置以满足您的è¦æ±‚。此处所åšçš„é…置更改会覆盖 GitLab æ供的é…置更改,并从更新中排除。有关更高级é…置选项的详细信æ¯ï¼Œè¯·å‚阅 %{docsLinkStart}GitLab DAST 文档%{docsLinkEnd}。"
msgid "DastConfig|DAST Settings"
msgstr "DAST 设置"
@@ -10108,7 +10147,7 @@ msgid "DastProfiles|Do you want to discard your changes?"
msgstr "您è¦æ”¾å¼ƒæ›´æ”¹å—?"
msgid "DastProfiles|Edit profile"
-msgstr ""
+msgstr "编辑é…置文件"
msgid "DastProfiles|Edit scanner profile"
msgstr "编辑扫æ工具é…ç½®"
@@ -10291,14 +10330,17 @@ msgid "DastProfiles|Website"
msgstr "网站"
msgid "DastProfiles|You can either choose a passive scan or validate the target site in your chosen site profile. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
-msgstr ""
+msgstr "您å¯ä»¥é€‰æ‹©è¢«åŠ¨æ‰«æ或验è¯æ‰€é€‰ç«™ç‚¹é…置文件中的目标站点。 %{docsLinkStart}了解有关站点验è¯çš„更多信æ¯ã€‚%{docsLinkEnd}"
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
-msgstr ""
+msgstr "ä¸èƒ½å¯¹æœªç»éªŒè¯çš„站点è¿è¡Œä¸»åŠ¨æ‰«æ。"
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr "å¤åˆ¶HTTP报头到剪贴æ¿"
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr "无法创建验è¯ä»¤ç‰Œã€‚请é‡è¯•ã€‚"
@@ -10311,6 +10353,9 @@ msgstr "下载验è¯æ–‡æœ¬æ–‡ä»¶"
msgid "DastSiteValidation|Header validation"
msgstr "报头验è¯"
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr "é‡è¯•éªŒè¯"
@@ -10323,12 +10368,18 @@ msgstr "步骤 1 - 选择站点验è¯æ–¹æ³•"
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr "步骤2 - 将以下HTTP标头添加到您的网站"
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr "步骤 2 - 将以下文本添加到目标站点"
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr "步骤 3 - 确认报头ä½ç½®å¹¶éªŒè¯"
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr "步骤 3 - 确认文本文件ä½ç½®å¹¶éªŒè¯"
@@ -10345,6 +10396,9 @@ msgid "DastSiteValidation|This will affect %d other profile targeting the same U
msgid_plural "DastSiteValidation|This will affect %d other profiles targeting the same URL."
msgstr[0] "è¿™å°†å½±å“ %d 个针对åŒä¸€ URL 的其他é…置文件。"
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr "验è¯"
@@ -10361,13 +10415,13 @@ msgid "DastSiteValidation|Validation failed"
msgstr "验è¯å¤±è´¥"
msgid "DastSiteValidation|Validation failed for %{url}. %{retryButtonStart}Retry validation%{retryButtonEnd}."
-msgstr ""
+msgstr "%{url}验è¯å¤±è´¥ï¼Œ%{retryButtonStart}é‡è¯•éªŒè¯%{retryButtonEnd}。"
msgid "DastSiteValidation|Validation succeeded. Both active and passive scans can be run against the target site."
msgstr "验è¯æˆåŠŸã€‚å¯å¯¹ç›®æ ‡ç«™ç‚¹è¿›è¡Œä¸»åŠ¨æ‰«æ和被动扫æ。"
msgid "DastSiteValidation|You will not be able to run active scans against %{url}."
-msgstr ""
+msgstr "您将无法对%{url}è¿è¡Œä¸»åŠ¨æ‰«æ。"
msgid "Data is still calculating..."
msgstr "æ•°æ®ä»åœ¨è®¡ç®—中……"
@@ -10379,37 +10433,37 @@ msgid "Database update failed"
msgstr "æ•°æ®åº“更新失败"
msgid "DatadogIntegration|%{linkOpen}API key%{linkClose} used for authentication with Datadog."
-msgstr ""
+msgstr "用于Datadog身份验è¯çš„%{linkOpen}API key%{linkClose}。"
msgid "DatadogIntegration|(Advanced) The full URL for your Datadog site."
-msgstr ""
+msgstr "(高级)您的Datadog站点的完整URL"
msgid "DatadogIntegration|API URL"
-msgstr ""
+msgstr "API URL"
msgid "DatadogIntegration|Environment"
-msgstr ""
+msgstr "环境"
msgid "DatadogIntegration|For self-managed deployments, set the %{codeOpen}env%{codeClose} tag for all the data sent to Datadog. %{linkOpen}How do I use tags?%{linkClose}"
-msgstr ""
+msgstr "对于自助管ç†éƒ¨ç½²ï¼Œä¸ºæ‰€æœ‰å‘é€åˆ°Datadogçš„æ•°æ®è®¾ç½®%{codeOpen}env%{codeClose}标签。%{linkOpen}我应该如何使用标签?%{linkClose}"
msgid "DatadogIntegration|How do I set up this integration?"
-msgstr ""
+msgstr "我应如何设置此集æˆï¼Ÿ"
msgid "DatadogIntegration|Send CI/CD pipeline information to Datadog to monitor for job failures and troubleshoot performance issues. %{docs_link}"
-msgstr ""
+msgstr "å‘é€CI/CDæµæ°´çº¿ä¿¡æ¯åˆ°Datadog,监控作业失败并对性能问题进行故障排查。%{docs_link}"
msgid "DatadogIntegration|Service"
-msgstr ""
+msgstr "Service"
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
-msgstr ""
+msgstr "在Datadog中,为æ¥è‡ªæ­¤GitLab实例的所有数æ®æ‰“标签。当管ç†å¤šä¸ªè‡ªåŠ©ç®¡ç†éƒ¨ç½²æ—¶å¾ˆæœ‰ç”¨ã€‚"
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
-msgstr ""
+msgstr "è¦å‘å…¶å‘é€æ•°æ®çš„Datadog站点。è¦å°†æ•°æ®å‘é€åˆ°EU站点,请使用%{codeOpen}datadoghq.eu%{codeClose}。"
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
-msgstr ""
+msgstr "使用Datadog跟踪您的GitLabæµæ°´çº¿ã€‚"
msgid "Datasource name not found"
msgstr "找ä¸åˆ°æ•°æ®æºå称"
@@ -10424,7 +10478,7 @@ msgid "Date range"
msgstr "日期范围"
msgid "Date range must be shorter than %{max_range} days."
-msgstr ""
+msgstr "日期范围必须å°äºŽ %{max_range} 天。"
msgid "Day of month"
msgstr "一个月中的æ¯å¤©"
@@ -10448,13 +10502,13 @@ msgid "Days to merge"
msgstr "åˆå¹¶æ‰€éœ€å¤©æ•°"
msgid "Deactivate dormant users after 90 days of inactivity. Users can return to active status by signing in to their account. While inactive, a user is not counted as an active user in the instance."
-msgstr ""
+msgstr "闲置 90 天åŽåœç”¨ä¼‘眠用户。用户å¯ä»¥é€šè¿‡ç™»å½•å…¶è´¦å·æ¥æ¢å¤æ¿€æ´»ã€‚处于未激活状æ€æ—¶ï¼Œç”¨æˆ·ä¸è®¡ä¸ºå®žä¾‹ä¸­çš„激活用户。"
msgid "Dear Administrator,"
msgstr "亲爱的管ç†å‘˜ï¼Œ"
msgid "Debian package already exists in Distribution"
-msgstr ""
+msgstr "Debian 软件包已ç»å­˜åœ¨äºŽåˆ†å‘中"
msgid "Debug"
msgstr "调试"
@@ -10477,11 +10531,8 @@ msgstr "解压归档大å°éªŒè¯å¤±è´¥ã€‚"
msgid "Decrease"
msgstr "å‡å°‘"
-msgid "Default"
-msgstr "默认"
-
msgid "Default CI/CD configuration file"
-msgstr ""
+msgstr "默认 CI/CD é…置文件"
msgid "Default artifacts expiration"
msgstr "默认产物过期时间"
@@ -10496,7 +10547,7 @@ msgid "Default classification label"
msgstr "默认分类标记"
msgid "Default delayed project deletion"
-msgstr ""
+msgstr "默认延迟删除项目"
msgid "Default deletion delay"
msgstr "默认删除延迟"
@@ -10523,7 +10574,7 @@ msgid "Default projects limit"
msgstr "默认项目é™åˆ¶"
msgid "Default timeout"
-msgstr ""
+msgstr "默认超时"
msgid "Default: Map a FogBugz account ID to a full name"
msgstr "默认:将FogBugzå¸æˆ·ID映射为全å"
@@ -10541,7 +10592,7 @@ msgid "Define approval settings."
msgstr "定义核准设置。"
msgid "Define approval settings. %{linkStart}Learn more.%{linkEnd}"
-msgstr ""
+msgstr "定义审批设置。 %{linkStart}了解更多。%{linkEnd}"
msgid "Define custom rules for what constitutes spam, independent of Akismet"
msgstr "定义独立于Akismet的垃圾邮件自定义规则"
@@ -10549,6 +10600,9 @@ msgstr "定义独立于Akismet的垃圾邮件自定义规则"
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr "在%{code_open}.githab-ci.yml%{code_close}的部署阶段中定义环境æ¥è·Ÿè¸ªéƒ¨ç½²ã€‚"
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr "定义"
@@ -10574,7 +10628,7 @@ msgid "Delete"
msgstr "删除"
msgid "Delete %{issuableType}"
-msgstr ""
+msgstr "删除 %{issuableType}"
msgid "Delete %{name}"
msgstr "删除%{name}"
@@ -10583,7 +10637,7 @@ msgid "Delete Comment"
msgstr "删除评论"
msgid "Delete Key"
-msgstr ""
+msgstr "删除密钥"
msgid "Delete Value Stream"
msgstr "删除值æµ"
@@ -10597,9 +10651,15 @@ msgstr "删除产物"
msgid "Delete badge"
msgstr "删除徽章"
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr "删除评论"
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr "删除域"
@@ -10613,7 +10673,7 @@ msgid "Delete label"
msgstr "删除标签"
msgid "Delete label: %{labelName}"
-msgstr ""
+msgstr "删除标记:%{labelName}"
msgid "Delete pipeline"
msgstr "删除æµæ°´çº¿"
@@ -10624,9 +10684,12 @@ msgstr "删除项目"
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr "删除项目。您ç»å¯¹ç¡®å®šå—?"
-msgid "Delete self monitoring project"
+msgid "Delete row"
msgstr ""
+msgid "Delete self monitoring project"
+msgstr "删除自监控项目"
+
msgid "Delete serverless domain?"
msgstr "删除无æœåŠ¡å™¨çš„域å?"
@@ -10642,11 +10705,14 @@ msgstr "删除æºåˆ†æ”¯"
msgid "Delete subscription"
msgstr "删除订阅"
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr "删除此附件"
msgid "Delete this epic and all descendants?"
-msgstr ""
+msgstr "删除此å²è¯—和所有下级?"
msgid "Delete user list"
msgstr "删除用户列表"
@@ -10676,10 +10742,10 @@ msgid "DeleteProject|Failed to restore wiki repository. Please contact the admin
msgstr "æ¢å¤wiki仓库失败。请è”系管ç†å‘˜ã€‚"
msgid "DeleteValueStream|'%{name}' Value Stream deleted"
-msgstr ""
+msgstr "'%{name}' 价值æµå·²åˆ é™¤"
msgid "DeleteValueStream|Are you sure you want to delete the \"%{name}\" Value Stream?"
-msgstr ""
+msgstr "您确定è¦åˆ é™¤ \"%{name}\" 价值æµå—?"
msgid "DeleteValueStream|Delete %{name}"
msgstr "删除 %{name}"
@@ -10706,10 +10772,10 @@ msgid "Deleting a project places it into a read-only state until %{date}, at whi
msgstr "删除项目会将其置于åªè¯»çŠ¶æ€ç›´è‡³%{date}。届时项目将被永久删除。确定è¦åˆ é™¤å—?"
msgid "Deleting the project will delete its repository and all related resources, including issues and merge requests."
-msgstr ""
+msgstr "删除该项目将删除其仓库和所有相关资æºï¼ŒåŒ…括议题和åˆå¹¶è¯·æ±‚。"
msgid "Deletion pending. This project will be deleted on %{date}. Repository and other project resources are read-only."
-msgstr ""
+msgstr "删除æ“作等待处ç†ã€‚此项目将于%{date}被删除。仓库和其他项目资æºä¸ºåªè¯»ã€‚"
msgid "Denied"
msgstr "已拒ç»"
@@ -10816,12 +10882,12 @@ msgstr "ä¾èµ–项扫æ"
msgid "Dependency proxy"
msgstr "ä¾èµ–项代ç†"
-msgid "Dependency proxy URL"
-msgstr "ä¾èµ–项代ç†URL"
-
msgid "Dependency proxy feature is limited to public groups for now."
msgstr "ä¾èµ–项代ç†åŠŸèƒ½ç›®å‰ä»…é™äºŽå…¬å¼€ç¾¤ç»„。"
+msgid "Dependency proxy image prefix"
+msgstr ""
+
msgid "DependencyProxy|Toggle Dependency Proxy"
msgstr " 开关ä¾èµ–项代ç†"
@@ -10847,10 +10913,10 @@ msgid "Deploy key was successfully updated."
msgstr "部署密钥已æˆåŠŸæ›´æ–°ã€‚"
msgid "Deploy keys"
-msgstr ""
+msgstr "部署密钥"
msgid "Deploy keys grant read/write access to all repositories in your instance"
-msgstr ""
+msgstr "部署密钥授予对实例中所有仓库的读/写访问æƒé™"
msgid "Deploy progress not found. To see pods, ensure your environment matches %{linkStart}deploy board criteria%{linkEnd}."
msgstr "未找到部署进度。è¦æŸ¥çœ‹pod,请确ä¿æ‚¨çš„环境符åˆ%{linkStart}部署看æ¿æ¡ä»¶%{linkEnd}。"
@@ -10859,11 +10925,23 @@ msgid "Deploy to..."
msgstr "部署到 ..."
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
-msgstr ""
+msgstr "添加冻结期以防止在给定环境的一段时间内æ„外å‘布。您必须根æ®æ­¤å¤„添加的部署冻结更新%{filename}的部署作业。%{freeze_period_link_start}了解更多。%{freeze_period_link_end}"
msgid "DeployFreeze|Add deploy freeze"
msgstr "添加部署冻结"
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr "编辑"
@@ -10874,10 +10952,10 @@ msgid "DeployFreeze|Freeze start"
msgstr "冻结开始"
msgid "DeployFreeze|No deploy freezes exist for this project. To add one, select %{strongStart}Add deploy freeze%{strongEnd}"
-msgstr ""
+msgstr "此项目ä¸å­˜åœ¨éƒ¨ç½²å†»ç»“。è¦æ·»åŠ ä¸€ä¸ªï¼Œè¯·é€‰æ‹© %{strongStart}添加部署冻结%{strongEnd}"
msgid "DeployFreeze|Specify deploy freezes using %{cron_syntax_link_start}cron syntax%{cron_syntax_link_end}."
-msgstr ""
+msgstr "使用 %{cron_syntax_link_start}cron 语法%{cron_syntax_link_end} 指定部署冻结。"
msgid "DeployFreeze|Time zone"
msgstr "时区"
@@ -10907,7 +10985,7 @@ msgid "DeployKeys|Expand %{count} other projects"
msgstr "展开 %{count} 个其他项目"
msgid "DeployKeys|Grant write permissions to this key"
-msgstr ""
+msgstr "授予此密钥写入æƒé™"
msgid "DeployKeys|Loading deploy keys"
msgstr "加载部署密钥"
@@ -10931,16 +11009,16 @@ msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr "å¯ç”¨éƒ¨ç½²ä»¤ç‰Œï¼ˆ%{active_tokens})"
msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
+msgstr "å…许对容器仓库镜åƒè¿›è¡Œè¯»å†™è®¿é—®ã€‚"
msgid "DeployTokens|Allows read and write access to the package registry."
-msgstr ""
+msgstr "å…许对软件包仓库进行读写访问。"
msgid "DeployTokens|Allows read-only access to registry images."
msgstr "å…许以åªè¯»æƒé™è®¿é—®ä»“库中的镜åƒã€‚"
msgid "DeployTokens|Allows read-only access to the package registry."
-msgstr ""
+msgstr "å…许对软件包仓库进行åªè¯»è®¿é—®ã€‚"
msgid "DeployTokens|Allows read-only access to the repository."
msgstr "å…许以åªè¯»æƒé™è®¿é—®é•œåƒä»“库。"
@@ -10952,7 +11030,7 @@ msgid "DeployTokens|Copy username"
msgstr "å¤åˆ¶ç”¨æˆ·å"
msgid "DeployTokens|Create a new deploy token for all projects in this group. %{link_start}What are deploy tokens?%{link_end}"
-msgstr ""
+msgstr "为该组中的所有项目创建一个新的部署令牌。 %{link_start}什么是部署令牌?%{link_end}"
msgid "DeployTokens|Create deploy token"
msgstr "创建部署令牌"
@@ -10967,13 +11045,13 @@ msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and
msgstr "部署令牌å…许访问软件包,您的代ç ä»“库和镜åƒåº“中的镜åƒã€‚"
msgid "DeployTokens|Enter a unique name for your deploy token."
-msgstr ""
+msgstr "为您的部署令牌输入唯一å称。"
msgid "DeployTokens|Enter a username for your token. Defaults to %{code_start}gitlab+deploy-token-{n}%{code_end}."
-msgstr ""
+msgstr "为您的令牌输入用户å。默认为 %{code_start}gitlab+deploy-token-{n}%{code_end}。"
msgid "DeployTokens|Enter an expiration date for your token. Defaults to never expire."
-msgstr ""
+msgstr "输入令牌的到期日期。默认为永ä¸è¿‡æœŸã€‚"
msgid "DeployTokens|Expires"
msgstr "到期"
@@ -10985,7 +11063,7 @@ msgid "DeployTokens|Name"
msgstr "å称"
msgid "DeployTokens|New deploy token"
-msgstr ""
+msgstr "新建部署令牌"
msgid "DeployTokens|Revoke"
msgstr "撤销"
@@ -11003,16 +11081,16 @@ msgid "DeployTokens|This action cannot be undone."
msgstr "æ­¤æ“作无法撤消。"
msgid "DeployTokens|This username supports access. %{link_start}What kind of access?%{link_end}"
-msgstr ""
+msgstr "此用户å支æŒè®¿é—®æƒé™ã€‚ %{link_start}什么类型的访问æƒé™ï¼Ÿ%{link_end}"
msgid "DeployTokens|Use this token as a password. Save it. This password can %{i_start}not%{i_end} be recovered."
-msgstr ""
+msgstr "使用此令牌作为密ç ã€‚æ­¤å¯†ç  %{i_start}ä¸èƒ½%{i_end} 找回。"
msgid "DeployTokens|Username"
msgstr "用户å"
msgid "DeployTokens|Your new Deploy Token username"
-msgstr ""
+msgstr "您的新部署令牌用户å"
msgid "DeployTokens|Your new group deploy token has been created."
msgstr "您的新群租部署令牌已创建。"
@@ -11045,11 +11123,11 @@ msgid "Deployment frequency"
msgstr "部署频率"
msgid "Deployments"
-msgstr ""
+msgstr "部署"
msgid "Deployments|%{deployments} environment impacted."
msgid_plural "Deployments|%{deployments} environments impacted."
-msgstr[0] ""
+msgstr[0] "%{deployments} 环境å—到影å“。"
msgid "Deployment|API"
msgstr "API"
@@ -11229,7 +11307,7 @@ msgid "DesignManagement|There was an error moving your designs. Please upload yo
msgstr "移动您的设计时出错。请在上传以下设计。"
msgid "DesignManagement|To upload designs, you'll need to enable LFS and have an admin enable hashed storage. %{requirements_link_start}More information%{requirements_link_end}"
-msgstr ""
+msgstr "è¦ä¸Šä¼ è®¾è®¡ï¼Œæ‚¨éœ€è¦å¯ç”¨ LFS 并让管ç†å‘˜å¯ç”¨å“ˆå¸Œå­˜å‚¨ã€‚ %{requirements_link_start}更多信æ¯%{requirements_link_end}"
msgid "DesignManagement|Unresolve thread"
msgstr "将主题置为未解决"
@@ -11265,22 +11343,22 @@ msgid "Detect host keys"
msgstr "检测主机密钥"
msgid "DevOps Adoption"
-msgstr ""
+msgstr "DevOps Adoption"
msgid "DevOps Report"
msgstr "DevOps报告"
msgid "DevOps adoption"
-msgstr ""
+msgstr "DevOps adoption"
msgid "Devices (optional)"
msgstr "设备(å¯é€‰ï¼‰"
msgid "DevopsAdoption|%{adoptedCount}/%{featuresCount} %{title} features adopted"
-msgstr ""
+msgstr "%{adoptedCount}/%{featuresCount} %{title} 功能已采用"
msgid "DevopsAdoption|Add a group to get started"
-msgstr ""
+msgstr "以添加一个群组开始"
msgid "DevopsAdoption|Add or remove groups"
msgstr "添加或删除群组"
@@ -11289,16 +11367,22 @@ msgid "DevopsAdoption|Add or remove subgroups"
msgstr "添加或删除å­ç»„"
msgid "DevopsAdoption|Adopted"
+msgstr "已采用"
+
+msgid "DevopsAdoption|Adoption by group"
msgstr ""
-msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
+msgid "DevopsAdoption|Adoption by subgroup"
msgstr ""
+msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
+msgstr "删除群组时出错,请é‡è¯•ã€‚"
+
msgid "DevopsAdoption|Approvals"
msgstr "核准"
msgid "DevopsAdoption|Are you sure that you would like to remove %{name} from the table?"
-msgstr ""
+msgstr "您确定è¦ä»Žè¡¨ä¸­åˆ é™¤ %{name} å—?"
msgid "DevopsAdoption|At least one approval on a merge request"
msgstr "在åˆå¹¶è¯·æ±‚上至少有一次批准"
@@ -11307,10 +11391,10 @@ msgid "DevopsAdoption|At least one deploy"
msgstr "至少部署一次"
msgid "DevopsAdoption|At least one issue opened"
-msgstr ""
+msgstr "至少开放了一个议题"
msgid "DevopsAdoption|At least one merge request opened"
-msgstr ""
+msgstr "至少开放一个åˆå¹¶è¯·æ±‚"
msgid "DevopsAdoption|At least one pipeline successfully run"
msgstr "至少有一æ¡æµæ°´çº¿è¿è¡ŒæˆåŠŸ"
@@ -11319,7 +11403,7 @@ msgid "DevopsAdoption|Code owners"
msgstr "代ç æ‰€æœ‰è€…"
msgid "DevopsAdoption|Code owners enabled for at least one project"
-msgstr ""
+msgstr "至少一个项目å¯ç”¨äº†ä»£ç æ‰€æœ‰è€…"
msgid "DevopsAdoption|Confirm remove Group"
msgstr "确认移除群组"
@@ -11343,7 +11427,7 @@ msgid "DevopsAdoption|Dev"
msgstr "å¼€å‘"
msgid "DevopsAdoption|DevOps adoption tracks the use of key features across your favorite groups. Add a group to the table to begin."
-msgstr ""
+msgstr "DevOps Adoption跟踪您最喜欢群组中关键功能的使用情况,开始添加群组到表。"
msgid "DevopsAdoption|Edit groups"
msgstr "编辑群组"
@@ -11351,14 +11435,14 @@ msgstr "编辑群组"
msgid "DevopsAdoption|Edit subgroups"
msgstr "编辑å­ç»„"
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
-msgstr ""
+msgstr "模糊测试"
msgid "DevopsAdoption|Fuzz Testing enabled for at least one project"
-msgstr ""
+msgstr "至少为一个项目å¯ç”¨äº†æ¨¡ç³Šæµ‹è¯•"
msgid "DevopsAdoption|Issues"
msgstr "议题"
@@ -11370,22 +11454,22 @@ msgid "DevopsAdoption|No results…"
msgstr "没有结果…"
msgid "DevopsAdoption|Not adopted"
-msgstr ""
+msgstr "未采用"
msgid "DevopsAdoption|Ops"
msgstr "è¿ç»´"
msgid "DevopsAdoption|Overall adoption"
-msgstr ""
+msgstr "å…¨é¢é‡‡ç”¨"
msgid "DevopsAdoption|Pipelines"
msgstr "æµæ°´çº¿"
msgid "DevopsAdoption|Remove Group"
-msgstr ""
+msgstr "删除群组"
msgid "DevopsAdoption|Remove Group from the table."
-msgstr ""
+msgstr "从表中删除群组。"
msgid "DevopsAdoption|Runner configured for project/group"
msgstr "为项目/群组é…置的Runner"
@@ -11403,25 +11487,25 @@ msgid "DevopsAdoption|Sec"
msgstr "安全"
msgid "DevopsAdoption|There was an error enabling the current group. Please refresh the page."
-msgstr ""
+msgstr "å¯ç”¨å½“å‰ç¾¤ç»„æ—¶å‘生错误,请刷新页é¢ã€‚"
msgid "DevopsAdoption|There was an error fetching Group adoption data. Please refresh the page."
-msgstr ""
+msgstr "获å–群组采用数æ®æ—¶å‘生错误,请刷新页é¢ã€‚"
msgid "DevopsAdoption|There was an error fetching Groups. Please refresh the page."
-msgstr ""
+msgstr "获å–群组时å‘生错误,请刷新页é¢ã€‚"
msgid "DevopsAdoption|This group has no subgroups"
-msgstr ""
+msgstr "此群组没有å­ç¾¤ç»„"
msgid "DevopsAdoption|You cannot remove the group you are currently in."
-msgstr ""
+msgstr "您ä¸èƒ½åˆ é™¤æ‚¨å½“å‰æ‰€åœ¨çš„群组。"
msgid "DevopsReport|DevOps Score"
msgstr "DevOps分数"
msgid "DevopsReport|DevOps score metrics are based on usage over the last 30 days. Last updated: %{timestamp}."
-msgstr ""
+msgstr "DevOps 评分指标基于过去 30 天的使用情况,最åŽæ›´æ–°ï¼š%{timestamp}。"
msgid "DevopsReport|High"
msgstr "高"
@@ -11454,10 +11538,10 @@ msgid "Didn't receive confirmation instructions?"
msgstr "没有收到确认说明?"
msgid "Didn't receive unlock instructions?"
-msgstr ""
+msgstr "没有收到解é”说明?"
msgid "Diff files surpassing this limit will be presented as 'too large' and won't be expandable."
-msgstr ""
+msgstr "超过此é™åˆ¶çš„差异文件将显示为“太大â€å¹¶ä¸”无法扩展。"
msgid "Diff limits"
msgstr "差异é™åˆ¶"
@@ -11487,10 +11571,10 @@ msgid "Direct member"
msgstr "直接æˆå‘˜"
msgid "Direct non-authenticated users to this page."
-msgstr ""
+msgstr "将未ç»èº«ä»½éªŒè¯çš„用户定å‘到此页é¢ã€‚"
msgid "Direct users to this page after they sign out."
-msgstr ""
+msgstr "用户退出åŽï¼Œå°†ç”¨æˆ·é‡å®šå‘到此页é¢ã€‚"
msgid "Direction"
msgstr "æ–¹å‘"
@@ -11505,7 +11589,7 @@ msgid "Disable Two-factor Authentication"
msgstr "ç¦ç”¨åŒé‡è®¤è¯"
msgid "Disable What's new"
-msgstr ""
+msgstr "ç¦ç”¨æœ€è¿‘æ›´æ–°"
msgid "Disable for this project"
msgstr "在此项目中ç¦ç”¨"
@@ -11520,7 +11604,7 @@ msgid "Disabled"
msgstr "å·²ç¦ç”¨"
msgid "Disabled by %{parent} owner"
-msgstr ""
+msgstr "被 %{parent} 所有者ç¦ç”¨"
msgid "Disabled mirrors can only be enabled by instance owners. It is recommended that you delete them."
msgstr "å·²ç¦ç”¨é•œåƒåªèƒ½ç”±å®žä¾‹æ‰€æœ‰è€…å¯ç”¨ã€‚建议删除此项。"
@@ -11547,7 +11631,7 @@ msgid "DiscordService|Discord Notifications"
msgstr "Discord 通知"
msgid "DiscordService|Send notifications about project events to a Discord channel."
-msgstr ""
+msgstr "å‘ Discord 频é“å‘é€æœ‰å…³é¡¹ç›®äº‹ä»¶çš„通知。"
msgid "Discover"
msgstr "å‘现"
@@ -11574,7 +11658,7 @@ msgid "Discover|Security capabilities, integrated into your development lifecycl
msgstr "安全能力,整åˆåˆ°æ‚¨çš„å¼€å‘生命周期中"
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
-msgstr ""
+msgstr "查看 %{linkStart}旗舰版方案%{linkEnd} 的其它功能"
msgid "Discover|Start a free trial"
msgstr "开始å…费试用"
@@ -11635,7 +11719,7 @@ msgid "Dismissed on pipeline %{pipelineLink} at %{projectLink}"
msgstr "在%{projectLink} 中的æµæ°´çº¿ %{pipelineLink}上忽略"
msgid "Display alerts from all configured monitoring tools."
-msgstr ""
+msgstr "显示æ¥è‡ªæ‰€æœ‰é…置的监控工具的警报。"
msgid "Display name"
msgstr "显示å称"
@@ -11647,13 +11731,13 @@ msgid "Display source"
msgstr "显示æº"
msgid "Display time tracking in issues in total hours only."
-msgstr ""
+msgstr "仅以总å°æ—¶æ•°æ˜¾ç¤ºè®®é¢˜ä¸­çš„时间跟踪。"
msgid "Do not display offers from third parties"
msgstr "ä¸æ˜¾ç¤ºæ¥è‡ªç¬¬ä¸‰æ–¹çš„优惠"
msgid "Do not force push over diverged refs. After the mirror is created, this setting can only be modified using the API. %{mirroring_docs_link_start}Learn more about this option%{link_closing_tag} and %{mirroring_api_docs_link_start}the API.%{link_closing_tag}"
-msgstr ""
+msgstr "ä¸è¦å¼ºè¡ŒæŽ¨åŠ¨åˆ†æ­§çš„ref。创建镜åƒåŽï¼Œåªèƒ½ä½¿ç”¨ API 修改此设置。 %{mirroring_docs_link_start}了解有关此选项%{link_closing_tag} å’Œ %{mirroring_api_docs_link_start}API 的更多信æ¯ã€‚%{link_closing_tag}"
msgid "Do you want to remove this deploy key?"
msgstr "您想è¦ç§»é™¤æ­¤éƒ¨ç½²å¯†é’¥å—?"
@@ -11674,7 +11758,7 @@ msgid "Documents reindexed: %{processed_documents} (%{percentage}%%)"
msgstr "文档é‡å»ºç´¢å¼•: %{processed_documents} (%{percentage}%%)"
msgid "Does not apply to projects in personal namespaces, which are deleted immediately on request."
-msgstr ""
+msgstr "ä¸é€‚用于个人命å空间中的项目,这些项目会根æ®è¦æ±‚ç«‹å³åˆ é™¤ã€‚"
msgid "Domain"
msgstr "域å"
@@ -11785,10 +11869,10 @@ msgid "Draft merge requests can't be merged."
msgstr "è‰ç¨¿åˆå¹¶è¯·æ±‚ä¸èƒ½åˆå¹¶ã€‚"
msgid "Drag your designs here or %{linkStart}click to upload%{linkEnd}."
-msgstr ""
+msgstr "将您的设计拖到此处,或 %{linkStart}点击上传%{linkEnd}。"
msgid "Drop or %{linkStart}upload%{linkEnd} file to attach"
-msgstr ""
+msgstr "拖放或 %{linkStart}上传%{linkEnd} 文件以附加文件"
msgid "Drop or %{linkStart}upload%{linkEnd} files to attach"
msgstr "拖放或%{linkStart}上传%{linkEnd}文件以附加"
@@ -11800,22 +11884,22 @@ msgid "Drop your files to start your upload."
msgstr "拖放您的文件以å¯åŠ¨ä¸Šä¼ ã€‚"
msgid "DropdownWidget|An error occurred while fetching the assigned %{issuableAttribute} of the selected %{issuableType}."
-msgstr ""
+msgstr "获å–所选%{issuableType}çš„%{issuableAttribute}æ—¶å‘生错误。"
msgid "DropdownWidget|Assign %{issuableAttribute}"
-msgstr ""
+msgstr "åˆ†é… %{issuableAttribute}"
msgid "DropdownWidget|Failed to fetch the %{issuableAttribute} for this %{issuableType}. Please try again."
-msgstr ""
+msgstr "无法为此%{issuableType}获å–%{issuableAttribute},请é‡è¯•ã€‚"
msgid "DropdownWidget|Failed to set %{issuableAttribute} on this %{issuableType}. Please try again."
-msgstr ""
+msgstr "在 %{issuableType}设置 %{issuableAttribute} 失败,请é‡è¯•ã€‚"
msgid "DropdownWidget|No %{issuableAttribute}"
msgstr "æ—  %{issuableAttribute}"
msgid "DropdownWidget|No %{issuableAttribute} found"
-msgstr ""
+msgstr "未找到 %{issuableAttribute}"
msgid "Due Date"
msgstr "截止日期"
@@ -11859,6 +11943,9 @@ msgstr "编辑Geo节点"
msgid "Edit Group Hook"
msgstr "编辑群组钩å­"
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr "编辑标签"
@@ -11934,6 +12021,9 @@ msgstr "编辑公共部署密钥"
msgid "Edit sidebar"
msgstr "编辑侧边æ "
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr "仅编辑此文件。"
@@ -11962,7 +12052,7 @@ msgid "Editing"
msgstr "编辑中"
msgid "Elapsed time"
-msgstr ""
+msgstr "已用时间"
msgid "Elasticsearch AWS IAM credentials"
msgstr "Elasticsearch AWS IAM凭æ®"
@@ -11986,7 +12076,7 @@ msgid "Elasticsearch reindexing triggered"
msgstr "Elasticsearché‡å»ºç´¢å¼•å·²è§¦å‘"
msgid "Elasticsearch reindexing was not started: %{errors}"
-msgstr ""
+msgstr "Elasticsearch é‡å»ºç´¢å¼•å°šæœªå¼€å§‹ï¼š%{errors}"
msgid "Elasticsearch returned status code: %{status_code}"
msgstr "Elasticsearch返回状æ€ä»£ç : %{status_code}"
@@ -12010,7 +12100,7 @@ msgid "Email Notification"
msgstr "电å­é‚®ä»¶é€šçŸ¥"
msgid "Email a new %{name} to this project"
-msgstr ""
+msgstr "通过电å­é‚®ä»¶å‘该项目å‘é€ %{name}"
msgid "Email address to use for Support Desk"
msgstr "用于技术支æŒçš„电å­é‚®ä»¶åœ°å€"
@@ -12022,7 +12112,7 @@ msgid "Email display name"
msgstr "电å­é‚®ä»¶æ˜¾ç¤ºå称"
msgid "Email from GitLab - email users right from the Admin Area. %{link_start}Learn more%{link_end}."
-msgstr ""
+msgstr "æ¥è‡ª GitLab 的电å­é‚®ä»¶ - æ¥è‡ªç®¡ç†ä¸­å¿ƒçš„用户。 %{link_start}了解更多%{link_end}。"
msgid "Email not verified. Please verify your email in Salesforce."
msgstr "电å­é‚®ä»¶æœªéªŒè¯ã€‚请在Salesforce中验è¯æ‚¨çš„电å­é‚®ä»¶ã€‚"
@@ -12079,7 +12169,7 @@ msgid "EmailParticipantsWarning|%{emails}, %{andMore} will be notified of your c
msgstr "%{emails},%{andMore} 将收到您的评论通知。"
msgid "EmailParticipantsWarning|and %{moreCount} more"
-msgstr ""
+msgstr "还有 %{moreCount} 个"
msgid "Emails"
msgstr "电å­é‚®ä»¶"
@@ -12103,7 +12193,7 @@ msgid "EmailsOnPushService|Emails on push"
msgstr "推é€æ—¶å‘é€ç”µå­é‚®ä»¶"
msgid "EmailsOnPushService|Emails separated by whitespace."
-msgstr ""
+msgstr "用空格分隔的电å­é‚®ä»¶ã€‚"
msgid "EmailsOnPushService|Send from committer"
msgstr "å‘é€è‡ªæ交者"
@@ -12112,7 +12202,7 @@ msgid "EmailsOnPushService|Send notifications from the committer's email address
msgstr ""
msgid "EmailsOnPushService|can't exceed %{recipients_limit}"
-msgstr ""
+msgstr "ä¸èƒ½è¶…过 %{recipients_limit}"
msgid "EmailsOnPushService|tanuki@example.com gitlab@example.com"
msgstr "tanuki@example.com gitlab@example.com"
@@ -12133,7 +12223,7 @@ msgid "Enable Auto DevOps"
msgstr "å¯ç”¨Auto DevOps"
msgid "Enable Git pack file bitmap creation"
-msgstr ""
+msgstr "å¯ç”¨ Git 包文件ä½å›¾åˆ›å»º"
msgid "Enable Gitpod"
msgstr "å¯ç”¨Gitpod"
@@ -12141,17 +12231,14 @@ msgstr "å¯ç”¨Gitpod"
msgid "Enable Gitpod?"
msgstr "å¯ç”¨Gitpodå—?"
-msgid "Enable Incident Management inbound alert limit"
-msgstr "å¯ç”¨äº‹ä»¶ç®¡ç†ä¼ å…¥è­¦æŠ¥é™åˆ¶"
-
msgid "Enable Invisible Captcha during sign up"
-msgstr ""
+msgstr "注册时å¯ç”¨éšå½¢éªŒè¯ç "
msgid "Enable Kroki"
msgstr "å¯ç”¨Kroki"
msgid "Enable Mailgun event receiver"
-msgstr ""
+msgstr "å¯ç”¨ Mailgun 事件接收器"
msgid "Enable PlantUML"
msgstr "å¯ç”¨PlantUML"
@@ -12160,7 +12247,7 @@ msgid "Enable Pseudonymizer data collection"
msgstr "å¯ç”¨åŒ¿å化的数æ®æ”¶é›†"
msgid "Enable Registration Features"
-msgstr ""
+msgstr "å¯ç”¨æ³¨å†ŒåŠŸèƒ½"
msgid "Enable SSL verification"
msgstr "å¯ç”¨ SSL 验è¯"
@@ -12172,31 +12259,34 @@ msgid "Enable Spam Check via external API endpoint"
msgstr "通过外部API端点å¯ç”¨åžƒåœ¾ä¿¡æ¯æ£€æŸ¥"
msgid "Enable What's new: All tiers"
-msgstr ""
+msgstr "å¯ç”¨æ–°åŠŸèƒ½ï¼šæ‰€æœ‰çº§åˆ«"
msgid "Enable What's new: Current tier only"
-msgstr ""
+msgstr "å¯ç”¨æ–°åŠŸèƒ½ï¼šä»…当å‰çº§åˆ«"
msgid "Enable a Prometheus endpoint that exposes health and performance statistics. The Health Check menu item appears in the Monitoring section of the Admin Area. Restart required."
-msgstr ""
+msgstr "å¯ç”¨å…¬å¼€å¥åº·å’Œæ€§èƒ½ç»Ÿè®¡ä¿¡æ¯çš„ Prometheus 端点。 å¥åº·æ£€æŸ¥èœå•é¡¹å‡ºçŽ°åœ¨ç®¡ç†ä¸­å¿ƒçš„监控部分。需è¦é‡æ–°å¯åŠ¨ã€‚"
msgid "Enable access to the performance bar for non-administrators in a given group."
-msgstr ""
+msgstr "å…许给定群组中的éžç®¡ç†å‘˜è®¿é—®æ€§èƒ½æ ã€‚"
msgid "Enable admin mode"
-msgstr ""
+msgstr "å¯ç”¨ç®¡ç†æ¨¡å¼"
msgid "Enable and disable Service Desk. Some additional configuration might be required. %{link_start}Learn more%{link_end}."
msgstr "å¯ç”¨å’Œç¦ç”¨æœåŠ¡å°ã€‚å¯èƒ½éœ€è¦ä¸€äº›é¢å¤–çš„é…置。 %{link_start}了解更多%{link_end}。"
msgid "Enable authenticated API request rate limit"
+msgstr "å¯ç”¨å·²èº«ä»½éªŒè¯çš„ API 请求速率é™åˆ¶"
+
+msgid "Enable authenticated Git LFS request rate limit"
msgstr ""
msgid "Enable authentication"
msgstr "å¯ç”¨èº«ä»½éªŒè¯"
msgid "Enable automatic repository housekeeping"
-msgstr ""
+msgstr "å¯ç”¨è‡ªåŠ¨ä»“库例行维护"
msgid "Enable classification control using an external service"
msgstr "使用外部æœåŠ¡å¯ç”¨åˆ†ç±»æŽ§åˆ¶"
@@ -12205,10 +12295,10 @@ msgid "Enable container expiration and retention policies for projects created e
msgstr "为创建于早于GitLab 12.7版本的项目å¯ç”¨å®¹å™¨è¿‡æœŸå’Œä¿ç•™ç­–略。"
msgid "Enable delayed project deletion by default for newly-created groups."
-msgstr ""
+msgstr "默认情况下为新创建的群组å¯ç”¨å»¶è¿Ÿé¡¹ç›®åˆ é™¤ã€‚"
msgid "Enable email notification"
-msgstr ""
+msgstr "å¯ç”¨ç”µå­é‚®ä»¶é€šçŸ¥"
msgid "Enable error tracking"
msgstr "å¯ç”¨é”™è¯¯è·Ÿè¸ª"
@@ -12226,11 +12316,14 @@ msgid "Enable header and footer in emails"
msgstr "在电å­é‚®ä»¶ä¸­å¯ç”¨é¡µçœ‰å’Œé¡µè„š"
msgid "Enable health and performance metrics endpoint"
-msgstr ""
+msgstr "å¯ç”¨è¿è¡ŒçŠ¶å†µå’Œæ€§èƒ½æŒ‡æ ‡ç«¯ç‚¹"
msgid "Enable in-product marketing emails"
msgstr "接收产å“è¥é”€ç”µå­é‚®ä»¶"
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr "å¯ç”¨é›†æˆ"
@@ -12244,13 +12337,13 @@ msgid "Enable maintenance mode"
msgstr "å¯ç”¨ç»´æŠ¤æ¨¡å¼"
msgid "Enable multipart emails"
-msgstr ""
+msgstr "å¯ç”¨ multipart 邮件"
msgid "Enable or disable the Pseudonymizer data collection."
msgstr "å¯ç”¨æˆ–ç¦ç”¨åŒ¿å化数æ®æ”¶é›†."
msgid "Enable or disable version check and service ping."
-msgstr ""
+msgstr "å¯ç”¨æˆ–ç¦ç”¨ç‰ˆæœ¬æ£€æŸ¥å’ŒæœåŠ¡ ping。"
msgid "Enable protected paths rate limit"
msgstr "å¯ç”¨ä¿æŠ¤è·¯å¾„速率é™åˆ¶"
@@ -12259,19 +12352,19 @@ msgid "Enable proxy"
msgstr "å¯ç”¨ä»£ç†"
msgid "Enable reCAPTCHA"
-msgstr ""
+msgstr "å¯ç”¨ reCAPTCHA"
msgid "Enable reCAPTCHA for login"
-msgstr ""
+msgstr "å¯ç”¨ reCAPTCHA 进行登录"
msgid "Enable reCAPTCHA, Invisible Captcha, Akismet and set IP limits. For reCAPTCHA, we currently only support %{recaptcha_v2_link_start}v2%{recaptcha_v2_link_end}"
-msgstr ""
+msgstr "å¯ç”¨ reCAPTCHAã€Invisible Captchaã€Akismet 并设置 IP é™åˆ¶ã€‚对于 reCAPTCHA,我们目å‰ä»…æ”¯æŒ %{recaptcha_v2_link_start}v2%{recaptcha_v2_link_end}"
msgid "Enable repository checks"
msgstr "å¯ç”¨ä»“库检查"
msgid "Enable service ping"
-msgstr ""
+msgstr "å¯ç”¨æœåŠ¡ Ping"
msgid "Enable shared runners for all projects and subgroups in this group."
msgstr "为该组中的所有项目和å­ç»„å¯ç”¨å…±äº«Runner。"
@@ -12292,13 +12385,13 @@ msgid "Enable two-factor authentication"
msgstr "å¯ç”¨åŒé‡è®¤è¯"
msgid "Enable unauthenticated API request rate limit"
-msgstr ""
+msgstr "å¯ç”¨æœªç»èº«ä»½éªŒè¯çš„ API 请求速率é™åˆ¶"
msgid "Enable unauthenticated request rate limit"
-msgstr ""
+msgstr "å¯ç”¨æœªç»éªŒè¯çš„请求速率é™åˆ¶"
msgid "Enable version check"
-msgstr ""
+msgstr "å¯ç”¨ç‰ˆæœ¬æ£€æŸ¥"
msgid "EnableReviewApp|%{stepStart}Step 1%{stepEnd}. Ensure you have Kubernetes set up and have a base domain for your %{linkStart}cluster%{linkEnd}."
msgstr "%{stepStart}第一步%{stepEnd}: ç¡®ä¿æ‚¨å·²è®¾ç½®Kubernetes并为您的%{linkStart}集群%{linkEnd}æ供了基本域。"
@@ -12310,7 +12403,7 @@ msgid "EnableReviewApp|%{stepStart}Step 3%{stepEnd}. Add it to the project %{lin
msgstr "%{stepStart}第3步%{stepEnd}: 将其添加到项目的%{linkStart}gitlab-ci.yml%{linkEnd}文件。"
msgid "EnableReviewApp|%{stepStart}Step 4 (optional)%{stepEnd}. Enable Visual Reviews by following the %{linkStart}setup instructions%{linkEnd}."
-msgstr ""
+msgstr "%{stepStart}第 4 步(å¯é€‰ï¼‰%{stepEnd}. %{linkStart}。根æ®è®¾ç½®è¯´æ˜Žå¯ç”¨å¯è§†åŒ–评审%{linkEnd}。"
msgid "EnableReviewApp|Close"
msgstr "关闭"
@@ -12325,7 +12418,7 @@ msgid "Enabled Git access protocols"
msgstr "å¯ç”¨ Git 访问åè®®"
msgid "Enabled OAuth authentication sources"
-msgstr ""
+msgstr "å¯ç”¨ OAuth 身份验è¯æº"
msgid "Enabled sources for code import during project creation. OmniAuth must be configured for GitHub"
msgstr "è¦åœ¨é¡¹ç›®åˆ›å»ºæœŸé—´å¯ç”¨ä»£ç å¯¼å…¥æºã€‚必须为 GitHub é…ç½® OmniAuth"
@@ -12340,13 +12433,13 @@ msgid "End Time"
msgstr "结æŸæ—¶é—´"
msgid "Ends"
-msgstr ""
+msgstr "结æŸ"
msgid "Ends at (UTC)"
msgstr "结æŸäºŽ(UTC)"
msgid "Ends on"
-msgstr ""
+msgstr "结æŸäºŽ"
msgid "Ends: %{endsAt}"
msgstr "结æŸäºŽï¼š%{endsAt}"
@@ -12361,10 +12454,10 @@ msgid "Enforce personal access token expiration"
msgstr "强制个人访问令牌过期"
msgid "Enforce two-factor authentication"
-msgstr ""
+msgstr "强制执行åŒé‡è®¤è¯"
msgid "Enforce two-factor authentication for all user sign-ins."
-msgstr ""
+msgstr "对所有用户登录强制执行åŒé‡è®¤è¯ã€‚"
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr "ç¡®ä¿ä»ŽGitLabæœåŠ¡å™¨åˆ°PrometheusæœåŠ¡å™¨çš„连接"
@@ -12373,7 +12466,7 @@ msgid "Ensure your %{linkStart}environment is part of the deploy stage%{linkEnd}
msgstr "如需跟踪到群集的部署,请确ä¿æ‚¨çš„%{linkStart}环境包å«äºŽCIæµæ°´çº¿çš„部署阶段%{linkEnd}。"
msgid "Enter %{weights_link_start}weights%{weights_link_end} for storages for new repositories. Configured storages appear below."
-msgstr ""
+msgstr "为新仓库的存储输入 %{weights_link_start}æƒé‡%{weights_link_end}。é…置的存储如下所示。"
msgid "Enter 2FA for Admin Mode"
msgstr "输入管ç†å‘˜æ¨¡å¼çš„åŒé‡éªŒè¯ç "
@@ -12430,16 +12523,16 @@ msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr "输入您的应用程åºçš„å称,我们会返回唯一的%{type}。"
msgid "Enter the number of seconds, or other human-readable input, like \"1 hour\". This timeout takes precedence over lower timeouts set for the project."
-msgstr ""
+msgstr "输入秒数或其它å¯è¯»çš„输入,如“1 å°æ—¶â€ã€‚此超时优先于为项目设置的较低超时。"
msgid "Enter your Packagist server. Defaults to https://packagist.org."
-msgstr ""
+msgstr "输入您的 Packagist æœåŠ¡å™¨ã€‚默认为 https://packagist.org。"
msgid "Enter your Packagist token."
-msgstr ""
+msgstr "输入您的 Packagist 令牌。"
msgid "Enter your Packagist username."
-msgstr ""
+msgstr "输入您的 Packagist 用户å。"
msgid "Enter your password to approve"
msgstr "输入批准密ç "
@@ -12463,13 +12556,13 @@ msgid "Environment scope"
msgstr "环境范围"
msgid "Environment variable %{code_start}%{environment_variable}%{code_end} does not exist or is not pointing to a valid directory."
-msgstr ""
+msgstr "环境å˜é‡ %{code_start}%{environment_variable}%{code_end} ä¸å­˜åœ¨æˆ–未指å‘有效目录。"
msgid "Environment variables are configured by your administrator to be %{link_start}protected%{link_end} by default."
-msgstr ""
+msgstr "默认情况下,环境å˜é‡ç”±ç®¡ç†å‘˜é…置为 %{link_start}ä¿æŠ¤%{link_end}"
msgid "Environment variables on this GitLab instance are configured to be %{link_start}protected%{link_end} by default."
-msgstr ""
+msgstr "æ­¤GitLab实例上的环境å˜é‡è¢«é»˜è®¤é…置为%{link_start}å—ä¿æŠ¤%{link_end}."
msgid "Environment:"
msgstr "环境:"
@@ -12490,7 +12583,7 @@ msgid "Environments Dashboard"
msgstr "环境仪表æ¿"
msgid "Environments allow you to track deployments of your application. %{linkStart}More information%{linkEnd}."
-msgstr ""
+msgstr "环境å…许您跟踪您应用程åºçš„部署。 %{linkStart}更多信æ¯%{linkEnd}。"
msgid "Environments in %{name}"
msgstr "%{name}中的环境"
@@ -12553,7 +12646,7 @@ msgid "Environments|Auto stop in"
msgstr "自动终止于"
msgid "Environments|Auto stops %{autoStopAt}"
-msgstr ""
+msgstr "自动åœæ­¢äºŽ %{autoStopAt}"
msgid "Environments|Commit"
msgstr "æ交"
@@ -12585,6 +12678,9 @@ msgstr "部署"
msgid "Environments|Deployment %{status}"
msgstr "部署%{status}"
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr "å¯ç”¨å®¡æ ¸åº”用"
@@ -12597,6 +12693,9 @@ msgstr "环境"
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr "环境是指部署代ç çš„ä½ç½®ï¼Œä¾‹å¦‚预å‘布或生产。"
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr "在群集上安装Elastic Stack,以å¯ç”¨é«˜çº§æŸ¥è¯¢åŠŸèƒ½ï¼Œä¾‹å¦‚全文æœç´¢ã€‚"
@@ -12672,6 +12771,9 @@ msgstr "终止环境"
msgid "Environments|Stopping %{environmentName}"
msgstr "终止%{environmentName}"
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr "获å–日志时出错。请é‡è¯•ã€‚"
@@ -12682,10 +12784,10 @@ msgid "Environments|This action will run the job defined by %{name} for commit %
msgstr "æ­¤æ“作将è¿è¡Œç”± %{name} 定义的作业,用于æ交 %{linkStart}%{commitId}%{linkEnd} 将环境置于先å‰ç‰ˆæœ¬ä¸­ã€‚您å¯ä»¥é€šè¿‡é‡æ–°éƒ¨ç½²æœ€æ–°ç‰ˆæœ¬çš„应用程åºæ¥è¿˜åŽŸå®ƒã€‚你确定你è¦ç»§ç»­å—?"
msgid "Environments|Upcoming"
-msgstr ""
+msgstr "å³å°†æŽ¨å‡º"
msgid "Environments|Upcoming deployment"
-msgstr ""
+msgstr "å³å°†éƒ¨ç½²"
msgid "Environments|Updated"
msgstr "更新于"
@@ -12693,6 +12795,12 @@ msgstr "更新于"
msgid "Environments|You don't have any environments right now"
msgstr "当å‰æœªè®¾ç½®çŽ¯å¢ƒ"
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr "å—ä¿æŠ¤çš„"
@@ -12793,7 +12901,7 @@ msgid "Epics|Something went wrong while fetching child epics."
msgstr "获å–å­å²è¯—时出错。"
msgid "Epics|Something went wrong while fetching epics list."
-msgstr ""
+msgstr "获å–å²è¯—列表时出错。"
msgid "Epics|Something went wrong while fetching group epics."
msgstr "获å–群组å²è¯—时出错。"
@@ -12937,7 +13045,7 @@ msgid "Error occurred when saving reviewers"
msgstr "ä¿å­˜å®¡æ ¸è€…时出错"
msgid "Error occurred while updating the %{issuableType} status"
-msgstr ""
+msgstr "æ›´æ–° %{issuableType} 状æ€æ—¶å‡ºé”™"
msgid "Error occurred while updating the issue status"
msgstr "更新议题状æ€æ—¶å‡ºé”™"
@@ -13029,6 +13137,9 @@ msgstr "错误:未找到用户的 AWS é…置角色"
msgid "Error: Unable to create deploy freeze"
msgstr "错误:无法创建部署冻结。"
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr "错误:找ä¸åˆ°å½“å‰ç”¨æˆ·çš„AWS角色"
@@ -13036,22 +13147,22 @@ msgid "ErrorTracking|Active"
msgstr "å¯ç”¨"
msgid "ErrorTracking|After adding your Auth Token, select the Connect button to load projects."
-msgstr ""
+msgstr "添加您的身份验è¯ä»¤ç‰ŒåŽï¼Œé€‰æ‹©â€œè¿žæŽ¥â€æŒ‰é’®ä»¥åŠ è½½é¡¹ç›®ã€‚"
msgid "ErrorTracking|Auth Token"
msgstr "验è¯ä»¤ç‰Œ"
msgid "ErrorTracking|Click Connect to reestablish the connection to Sentry and activate the dropdown."
-msgstr ""
+msgstr "å•å‡»â€œè¿žæŽ¥â€ä»¥é‡æ–°å»ºç«‹ä¸Ž Sentry 的连接并激活下拉列表。"
msgid "ErrorTracking|Connection failed. Check Auth Token and try again."
-msgstr ""
+msgstr "连接失败,请å†æ¬¡æ£€æŸ¥éªŒè¯ä»¤ç‰Œï¼Œå¹¶é‡è¯•ã€‚"
msgid "ErrorTracking|Enable error tracking"
msgstr "å¯ç”¨é”™è¯¯è·Ÿè¸ª"
msgid "ErrorTracking|If you self-host Sentry, enter your Sentry instance's full URL. If you use Sentry's hosted solution, enter https://sentry.io"
-msgstr ""
+msgstr "如果您自托管 Sentry,请输入您的 Sentry 实例的完整 URL。如果您使用 Sentry 的托管解决方案,请输入 https://sentry.io"
msgid "ErrorTracking|No projects available"
msgstr "æ— å¯ç”¨çš„项目"
@@ -13060,7 +13171,7 @@ msgid "ErrorTracking|Select project"
msgstr "选择项目"
msgid "ErrorTracking|To enable project selection, enter a valid Auth Token."
-msgstr ""
+msgstr "è¦å¯ç”¨é€‰æ‹©çš„项目,请输入有效的身份验è¯ä»¤ç‰Œã€‚"
msgid "Errors"
msgstr "错误"
@@ -13072,28 +13183,28 @@ msgid "Errors:"
msgstr "错误:"
msgid "Escalation Policies"
-msgstr ""
+msgstr "å‡çº§ç­–ç•¥"
msgid "Escalation policies"
-msgstr ""
+msgstr "å‡çº§ç­–ç•¥"
msgid "Escalation policies may not have more than %{rule_count} rules"
-msgstr ""
+msgstr "å‡çº§ç­–ç•¥ä¸èƒ½è¶…过 %{rule_count} 个规则"
msgid "Escalation policies must have at least one rule"
-msgstr ""
+msgstr "å‡çº§ç­–略必须至少有一个规则"
msgid "EscalationPolicies|+ Add an additional rule"
-msgstr ""
+msgstr "+ 添加附加规则"
msgid "EscalationPolicies|A schedule is required for adding an escalation policy."
-msgstr ""
+msgstr "添加å‡çº§ç­–略需è¦ä¸€ä¸ªè®¡åˆ’。"
msgid "EscalationPolicies|A schedule is required for adding an escalation policy. Please create an on-call schedule first."
-msgstr ""
+msgstr "添加å‡çº§ç­–略需è¦ä¸€ä¸ªè®¡åˆ’,请先创建一个on-call计划。"
msgid "EscalationPolicies|A user is required for adding an escalation policy."
-msgstr ""
+msgstr "添加å‡çº§ç­–略需è¦ç”¨æˆ·ã€‚"
msgid "EscalationPolicies|Add an escalation policy"
msgstr "添加å‡çº§ç­–ç•¥"
@@ -13117,10 +13228,10 @@ msgid "EscalationPolicies|Edit escalation policy"
msgstr "编辑å‡çº§ç­–ç•¥"
msgid "EscalationPolicies|Email on-call user in schedule"
-msgstr ""
+msgstr "æŒ‰è®¡åˆ’å‘ on-call 用户å‘é€ç”µå­é‚®ä»¶"
msgid "EscalationPolicies|Email user"
-msgstr ""
+msgstr "电å­é‚®ä»¶ç”¨æˆ·"
msgid "EscalationPolicies|Escalation policies"
msgstr "å‡çº§ç­–ç•¥"
@@ -13129,46 +13240,46 @@ msgid "EscalationPolicies|Escalation rules"
msgstr "å‡çº§è§„则"
msgid "EscalationPolicies|Failed to load oncall-schedules"
-msgstr ""
+msgstr "加载 on-call 计划失败"
msgid "EscalationPolicies|IF alert is not %{alertStatus} in %{minutes} %{then} THEN %{doAction} %{scheduleOrUser}"
-msgstr ""
+msgstr "如果警报在%{minutes}中ä¸æ˜¯%{alertStatus},%{then} 那么 %{doAction} %{scheduleOrUser}"
msgid "EscalationPolicies|IF alert is not %{alertStatus} in %{minutes} minutes"
-msgstr ""
+msgstr "如果警报在%{minutes}分钟内ä¸æ˜¯%{alertStatus}"
msgid "EscalationPolicies|Maximum of 10 rules has been reached."
-msgstr ""
+msgstr "已达到最多10æ¡è§„则。"
msgid "EscalationPolicies|Minutes must be between 0 and 1440."
-msgstr ""
+msgstr "分钟数必须在 0 到 1440 之间。"
msgid "EscalationPolicies|Remove escalation rule"
msgstr "删除å‡çº§è§„则"
msgid "EscalationPolicies|Search for user"
-msgstr ""
+msgstr "æœç´¢ç”¨æˆ·"
msgid "EscalationPolicies|Select schedule"
-msgstr ""
+msgstr "选择计划"
msgid "EscalationPolicies|Set up escalation policies to define who is paged, and when, in the event the first users paged don't respond."
msgstr ""
msgid "EscalationPolicies|THEN %{doAction} %{scheduleOrUser}"
-msgstr ""
+msgstr "然åŽ%{doAction}%{scheduleOrUser}"
msgid "EscalationPolicies|The escalation policy could not be deleted. Please try again."
-msgstr ""
+msgstr "无法删除å‡çº§ç­–略,请é‡è¯•ã€‚"
msgid "EscalationPolicies|The escalation policy could not be updated. Please try again"
-msgstr ""
+msgstr "无法更新å‡çº§ç­–略,请é‡è¯•ã€‚"
msgid "EscalationPolicies|This policy has no escalation rules."
-msgstr ""
+msgstr "此策略没有å‡çº§è§„则。"
msgid "EscalationPolicies|mins"
-msgstr ""
+msgstr "最å°å€¼"
msgid "Estimate"
msgstr "预计"
@@ -13283,7 +13394,7 @@ msgid "Except policy:"
msgstr "除外(Except)æ¡ä»¶ï¼š"
msgid "Exceptions"
-msgstr ""
+msgstr "例外"
msgid "Excess storage"
msgstr "超é¢å­˜å‚¨"
@@ -13427,7 +13538,7 @@ msgid "Export this group with all related data to a new GitLab instance. Once co
msgstr "将所有相关数æ®å¯¼å‡ºåˆ°æ–°çš„GitLab实例。完æˆåŽï¼Œæ‚¨å¯ä»¥ä»Ž\"创建新群组\"页é¢å¯¼å…¥æ•°æ®æ–‡ä»¶ã€‚"
msgid "Export this project with all its related data in order to move it to a new GitLab instance. When the exported file is ready, you can download it from this page or from the download link in the email notification you will receive. You can then import it when creating a new project. %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "导出此项目åŠå…¶æ‰€æœ‰ç›¸å…³æ•°æ®ï¼Œä»¥ä¾¿å°†å…¶ç§»åŠ¨åˆ°æ–°çš„ GitLab 实例。导出的文件准备就绪åŽï¼Œæ‚¨å¯ä»¥ä»Žæ­¤é¡µé¢æˆ–从您将收到的电å­é‚®ä»¶é€šçŸ¥ä¸­çš„下载链接下载它。然åŽï¼Œæ‚¨å¯ä»¥åœ¨åˆ›å»ºæ–°é¡¹ç›®æ—¶å°†å…¶å¯¼å…¥ã€‚ %{link_start}了解更多。%{link_end}"
msgid "Export variable to pipelines running on protected branches and tags only."
msgstr "仅导出å˜é‡åˆ°ä¿æŠ¤åˆ†æ”¯å’Œæ ‡ç­¾ä¸Šè¿è¡Œçš„æµæ°´çº¿ã€‚"
@@ -13463,7 +13574,7 @@ msgid "External storage authentication token"
msgstr "外部存储认è¯ä»¤ç‰Œ"
msgid "External storage for repository static objects"
-msgstr ""
+msgstr "仓库é™æ€å¯¹è±¡çš„外部存储"
msgid "ExternalAuthorizationService|Classification label"
msgstr "分类标签"
@@ -13571,7 +13682,7 @@ msgid "Failed to find import label for Jira import."
msgstr "找ä¸åˆ°ç”¨äºŽJira导入的导入标记。"
msgid "Failed to generate export, please try again later."
-msgstr ""
+msgstr "生æˆå¯¼å‡ºå¤±è´¥ï¼Œè¯·ç¨åŽå†è¯•ã€‚"
msgid "Failed to generate report, please try again after sometime"
msgstr "生æˆæŠ¥å‘Šå¤±è´¥ï¼Œè¯·ç¨åŽå†è¯•"
@@ -13664,7 +13775,7 @@ msgid "Failed to publish issue on status page."
msgstr "在状æ€é¡µä¸Šå‘布议题失败。"
msgid "Failed to register Agent"
-msgstr ""
+msgstr "注册代ç†å¤±è´¥"
msgid "Failed to remove a Zoom meeting"
msgstr "无法删除Zoom会议"
@@ -13748,7 +13859,7 @@ msgid "False positive"
msgstr "误报"
msgid "Fast timeout"
-msgstr ""
+msgstr "快速超时"
msgid "Fast-forward merge without a merge commit"
msgstr "æ— åˆå¹¶æ交的快进å¼åˆå¹¶"
@@ -13757,13 +13868,13 @@ msgid "Faster releases. Better code. Less pain."
msgstr "æ›´å¿«çš„å‘布。更好的代ç ã€‚更少的烦æ¼ã€‚"
msgid "Favicon"
-msgstr ""
+msgstr "图标"
msgid "Favicon was successfully removed."
msgstr "网站图标已被æˆåŠŸåˆ é™¤ã€‚"
msgid "Favicon will be removed. Are you sure?"
-msgstr ""
+msgstr "图标将被删除。您确定å—?"
msgid "Feature Flags"
msgstr "功能标志"
@@ -13984,10 +14095,10 @@ msgstr "用户列表"
msgid "FeatureHighlight|%{daysRemaining} day remaining to enjoy %{featureName}"
msgid_plural "FeatureHighlight|%{daysRemaining} days remaining to enjoy %{featureName}"
-msgstr[0] ""
+msgstr[0] "剩余%{daysRemaining}天å¯ä»¥ä½¿ç”¨%{featureName}"
msgid "FeatureHighlight|Enjoying your GitLab %{planNameForTrial} trial? To continue using %{featureName} after your trial ends, upgrade to GitLab %{planNameForUpgrade}."
-msgstr ""
+msgstr "享å—您的%{planNameForTrial}试用å—?è¦åœ¨è¯•ç”¨ç»“æŸåŽç»§ç»­ä½¿ç”¨ %{featureName} ,请å‡çº§åˆ°%{planNameForUpgrade}。"
msgid "Feb"
msgstr "2月"
@@ -14077,10 +14188,10 @@ msgid "Filter by %{issuable_type} that are currently closed."
msgstr "筛选器%{issuable_type}当å‰å…³é—­ã€‚"
msgid "Filter by %{issuable_type} that are currently open."
-msgstr ""
+msgstr "筛选当å‰å¼€æ”¾çš„ %{issuable_type}"
msgid "Filter by %{page_context_word} that are currently open."
-msgstr ""
+msgstr "筛选当å‰å¼€æ”¾çš„ %{page_context_word}"
msgid "Filter by Git revision"
msgstr "按Git版本筛选"
@@ -14110,7 +14221,7 @@ msgid "Filter by test cases that are currently archived."
msgstr "按当å‰å·²å½’档的测试用例筛选。"
msgid "Filter by test cases that are currently open."
-msgstr ""
+msgstr "按当å‰å¼€æ”¾çš„测试用例进行过滤。"
msgid "Filter by two-factor authentication"
msgstr "按åŒé‡è®¤è¯ç­›é€‰"
@@ -14137,7 +14248,7 @@ msgid "Filter results..."
msgstr "筛选结果..."
msgid "Filter users"
-msgstr ""
+msgstr "过滤用户"
msgid "Filter your repositories by name"
msgstr "按å称筛选您的仓库"
@@ -14209,25 +14320,25 @@ msgid "Flags"
msgstr "标记"
msgid "FloC|Configure whether you want to participate in FloC."
-msgstr ""
+msgstr "é…置是å¦è¦å‚与FloC。"
msgid "FloC|Enable FloC (Federated Learning of Cohorts)"
-msgstr ""
+msgstr "å¯ç”¨ FloC(Federated Learning of Cohorts)"
msgid "FloC|Federated Learning of Cohorts"
msgstr ""
msgid "FlowdockService|1b609b52537..."
-msgstr ""
+msgstr "1b609b52537..."
msgid "FlowdockService|Send event notifications from GitLab to Flowdock flows."
-msgstr ""
+msgstr "从 GitLab å‘é€äº‹ä»¶é€šçŸ¥åˆ° Flowdock æµã€‚"
msgid "FlowdockService|Send event notifications from GitLab to Flowdock flows. %{docs_link}"
-msgstr ""
+msgstr "从 GitLab å‘ Flowdock æµå‘é€äº‹ä»¶é€šçŸ¥ã€‚ %{docs_link}"
msgid "Focus filter bar"
-msgstr ""
+msgstr "èšç„¦è¿‡æ»¤æ "
msgid "FogBugz Email"
msgstr "FogBugz电å­é‚®ä»¶"
@@ -14248,13 +14359,13 @@ msgid "Folder/%{name}"
msgstr "文件夹/%{name}"
msgid "Follow"
-msgstr ""
+msgstr "关注"
msgid "Followed Users' Activity"
-msgstr ""
+msgstr "关注用户的动æ€"
msgid "Followed users"
-msgstr ""
+msgstr "关注的用户"
msgid "Font Color"
msgstr "字体颜色"
@@ -14266,28 +14377,28 @@ msgid "For a faster browsing experience, some files are collapsed by default."
msgstr "为了更快的æµè§ˆä½“验,一些文件默认会被折å ã€‚"
msgid "For additional information, review your %{link_to} or contact your group owner."
-msgstr ""
+msgstr "有关其他信æ¯ï¼Œè¯·æŸ¥çœ‹æ‚¨çš„ %{link_to} 或è”系您的群组所有者。"
msgid "For additional information, review your group membership: %{link_to} or contact your group owner."
-msgstr ""
+msgstr "有关其他信æ¯ï¼Œè¯·æŸ¥çœ‹æ‚¨çš„群组æˆå‘˜èº«ä»½ï¼š %{link_to} 或è”系您的群组所有者。"
msgid "For each job, clone the repository."
msgstr "为æ¯ä¸ªä½œä¸šï¼Œå…‹éš†ä»“库。"
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
-msgstr ""
+msgstr "对于æ¯ä¸ªä½œä¸šï¼Œé‡æ–°ä½¿ç”¨é¡¹ç›®å·¥ä½œåŒºï¼Œå¦‚果工作区ä¸å­˜åœ¨ï¼Œè¯·ä½¿ç”¨ %{code_open}git clone%{code_close}。"
msgid "For example, the application using the token or the purpose of the token."
-msgstr ""
+msgstr "例如,应用程åºä½¿ç”¨ä»¤ç‰Œæˆ–令牌的用途。"
msgid "For general work"
-msgstr ""
+msgstr "关于一般性工作"
msgid "For individual use, create a separate account under your personal email address, not tied to the Enterprise email domain or group."
-msgstr ""
+msgstr "对于个人使用,请在您的个人电å­é‚®ä»¶åœ°å€ä¸‹åˆ›å»ºä¸€ä¸ªå•ç‹¬çš„è´¦å·ï¼Œä¸è¦ç»‘定到ä¼ä¸šç”µå­é‚®ä»¶åŸŸæˆ–组。"
msgid "For investigating IT service disruptions or outages"
-msgstr ""
+msgstr "用于调查 IT æœåŠ¡ä¸­æ–­æˆ–åœé¡¿"
msgid "For more info, read the documentation."
msgstr "有关详细信æ¯ï¼Œè¯·é˜…读文档。"
@@ -14302,7 +14413,7 @@ msgid "For more information, see the File Hooks documentation."
msgstr "欲了解更多信æ¯ï¼Œè¯·å‚阅文件钩å­æ–‡æ¡£ã€‚"
msgid "For more information, see the documentation on %{deactivating_service_ping_link_start}deactivating service ping%{deactivating_service_ping_link_end}."
-msgstr ""
+msgstr "有关更多信æ¯ï¼Œè¯·å‚阅有关 %{deactivating_service_ping_link_start}åœç”¨æœåŠ¡ ping%{deactivating_service_ping_link_end}的文档。"
msgid "Forgot your password?"
msgstr "忘记密ç ï¼Ÿ"
@@ -14320,10 +14431,10 @@ msgid "Fork project?"
msgstr "派生项目?"
msgid "ForkProject|A fork is a copy of a project."
-msgstr ""
+msgstr "派生(fork)是一个项目的副本。"
msgid "ForkProject|An error occurred while forking the project. Please try again."
-msgstr ""
+msgstr "派生(fork)项目时出错,请é‡è¯•ã€‚"
msgid "ForkProject|Cancel"
msgstr "å–消"
@@ -14335,7 +14446,7 @@ msgid "ForkProject|Fork project"
msgstr "派生(Fork)项目"
msgid "ForkProject|Forking a repository allows you to make changes without affecting the original project."
-msgstr ""
+msgstr "派生(Fork)一个仓库,å…许您在ä¸å½±å“原始项目的情况下进行更改。"
msgid "ForkProject|Internal"
msgstr "内部"
@@ -14344,13 +14455,13 @@ msgid "ForkProject|Please select a namespace"
msgstr "请选择命å空间"
msgid "ForkProject|Please select a visibility level"
-msgstr ""
+msgstr "请选择一个å¯è§çº§åˆ«"
msgid "ForkProject|Private"
msgstr "ç§æœ‰"
msgid "ForkProject|Project access must be granted explicitly to each user. If this project is part of a group, access will be granted to members of the group."
-msgstr ""
+msgstr "项目访问æƒé™å¿…须明确授予æ¯ä¸ªç”¨æˆ·ï¼Œå¦‚果此项目属于æŸä¸ªç¾¤ç»„,则将授予该组æˆå‘˜è®¿é—®æƒé™ã€‚"
msgid "ForkProject|Public"
msgstr "公开"
@@ -14371,16 +14482,16 @@ msgid "ForkProject|Visibility level"
msgstr "å¯è§æ€§çº§åˆ«"
msgid "ForkProject|Want to house several dependent projects under the same namespace?"
-msgstr ""
+msgstr "想在åŒä¸€ä¸ªå‘½å空间下容纳多个ä¾èµ–项目?"
msgid "ForkSuggestion|Cancel"
msgstr "å–消"
msgid "ForkSuggestion|Fork"
-msgstr ""
+msgstr "派生"
msgid "ForkSuggestion|You can’t %{edit_start}edit%{edit_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
+msgstr "您ä¸èƒ½åœ¨è¿™ä¸ªé¡¹ç›®ä¸­ç›´æŽ¥ %{edit_start}编辑%{edit_end} 文件,请派生(Fork)这个项目并æ交åˆå¹¶è¯·æ±‚。"
msgid "ForkedFromProjectPath|Forked from"
msgstr "派生自"
@@ -14397,6 +14508,9 @@ msgstr "派生"
msgid "Format: %{dateFormat}"
msgstr "æ ¼å¼ï¼š%{dateFormat}"
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr "在您的 %{gitlab_ci_yml} 中找到错误:"
@@ -14419,7 +14533,7 @@ msgid "Frequency"
msgstr "频率"
msgid "Frequently searched"
-msgstr ""
+msgstr "ç»å¸¸æœç´¢çš„"
msgid "Friday"
msgstr "星期五"
@@ -14440,7 +14554,7 @@ msgid "From merge request merge until deploy to production"
msgstr "从åˆå¹¶è¯·æ±‚被åˆå¹¶åŽåˆ°éƒ¨ç½²è‡³ç”Ÿäº§çŽ¯å¢ƒ"
msgid "Full"
-msgstr ""
+msgstr "全部"
msgid "Full name"
msgstr "å…¨å"
@@ -14479,22 +14593,25 @@ msgid "Generate new token"
msgstr "生æˆæ–°çš„令牌"
msgid "Generate project access tokens scoped to this project for your applications that need access to the GitLab API."
-msgstr ""
+msgstr "为您需è¦è®¿é—®GitLab API的应用程åºç”Ÿæˆé¡¹ç›®è®¿é—®ä»¤ç‰Œã€‚"
msgid "Generate site and private keys at"
+msgstr "生æˆç«™ç‚¹å’Œç§é’¥åœ¨"
+
+msgid "Generic"
msgstr ""
msgid "Generic package file size in bytes"
msgstr "通用文件包大å°ï¼ˆå­—节)"
msgid "GenericReport|After"
-msgstr ""
+msgstr "之åŽ"
msgid "GenericReport|Before"
-msgstr ""
+msgstr "之å‰"
msgid "GenericReport|Diff"
-msgstr ""
+msgstr "差异"
msgid "Geo"
msgstr "Geo"
@@ -14512,10 +14629,10 @@ msgid "Geo sites"
msgstr "Geo站点"
msgid "Geo|%{component} synced"
-msgstr ""
+msgstr "%{component} å·²åŒæ­¥"
msgid "Geo|%{component} verified"
-msgstr ""
+msgstr "%{component} 已验è¯"
msgid "Geo|%{label} can't be blank"
msgstr "%{label}ä¸èƒ½ä¸ºç©º"
@@ -14533,10 +14650,10 @@ msgid "Geo|%{name} is scheduled for re-verify"
msgstr "%{name}已计划é‡æ–°éªŒè¯"
msgid "Geo|%{timeAgoStr} (%{pendingEvents} events)"
-msgstr ""
+msgstr "%{timeAgoStr} (%{pendingEvents} 事件)"
msgid "Geo|%{title} checksum progress"
-msgstr ""
+msgstr "%{title} 校验进度"
msgid "Geo|(%{timeAgo})"
msgstr "(%{timeAgo})"
@@ -14569,7 +14686,7 @@ msgid "Geo|Allowed Geo IP should contain valid IP addresses"
msgstr "å…许的Geo IP应该包å«æœ‰æ•ˆçš„IP地å€"
msgid "Geo|Checksummed"
-msgstr ""
+msgstr "已校验"
msgid "Geo|Connection timeout can't be blank"
msgstr "连接超时ä¸èƒ½ä¸ºç©º"
@@ -14581,7 +14698,7 @@ msgid "Geo|Connection timeout should be between 1-120"
msgstr "连接超时应介于1-120之间"
msgid "Geo|Consult Geo troubleshooting information"
-msgstr ""
+msgstr "查询Geo故障排除信æ¯"
msgid "Geo|Could not remove tracking entry for an existing project."
msgstr "无法删除现有项目的跟踪æ¡ç›®ã€‚"
@@ -14590,7 +14707,7 @@ msgid "Geo|Could not remove tracking entry for an existing upload."
msgstr "无法删除现有上传的跟踪æ¡ç›®ã€‚"
msgid "Geo|Data replication lag"
-msgstr ""
+msgstr "æ•°æ®å¤åˆ¶æ»žåŽ"
msgid "Geo|Data type"
msgstr "æ•°æ®ç±»åž‹"
@@ -14599,10 +14716,10 @@ msgid "Geo|Disabled"
msgstr "å·²ç¦ç”¨"
msgid "Geo|Discover GitLab Geo"
-msgstr ""
+msgstr "探索GitLab Geo"
msgid "Geo|Does not match the primary storage configuration"
-msgstr ""
+msgstr "与主存储é…ç½®ä¸ä¸€è‡´"
msgid "Geo|Failed"
msgstr "失败"
@@ -14616,12 +14733,12 @@ msgstr "按状æ€ç­›é€‰"
msgid "Geo|Geo Status"
msgstr "Geo状æ€"
-msgid "Geo|Geo nodes are paused using a command run on the node"
-msgstr ""
-
msgid "Geo|Geo sites"
msgstr "Geo站点"
+msgid "Geo|Geo sites are paused using a command run on the site"
+msgstr ""
+
msgid "Geo|Geo supports replication of many data types."
msgstr "Geo 支æŒå¤šç§æ•°æ®ç±»åž‹çš„å¤åˆ¶ã€‚"
@@ -14644,10 +14761,10 @@ msgid "Geo|Internal URL"
msgstr "内部 URL"
msgid "Geo|Last event ID from primary"
-msgstr ""
+msgstr "主节点中最新的事件ID"
msgid "Geo|Last event ID processed by cursor"
-msgstr ""
+msgstr "处ç†çš„最åŽäº‹ä»¶ ID"
msgid "Geo|Last repository check run"
msgstr "上次仓库的è¿è¡Œæ£€æŸ¥"
@@ -14664,11 +14781,11 @@ msgstr "最近一次验è¯"
msgid "Geo|Learn more about Geo"
msgstr "了解更多关于Geo"
-msgid "Geo|Learn more about Geo node statuses"
-msgstr "了解更多关于Geo节点状æ€"
+msgid "Geo|Learn more about Geo site statuses"
+msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
-msgstr ""
+msgstr "GitLab Geo å¯ä»¥åˆ›å»º GitLab 实例的åªè¯»é•œåƒ, 使得从远端克隆和拉å–大型代ç ä»“库的时间大大缩短,从而æ高团队æˆå‘˜çš„工作效率。"
msgid "Geo|Never"
msgstr "从ä¸"
@@ -14677,7 +14794,7 @@ msgid "Geo|Next sync scheduled at"
msgstr "下一次åŒæ­¥å®‰æŽ’在"
msgid "Geo|No available replication slots"
-msgstr ""
+msgstr "没有å¯ç”¨çš„å¤åˆ¶æ§½"
msgid "Geo|Node name can't be blank"
msgstr "节点å称ä¸èƒ½ä¸ºç©º"
@@ -14685,17 +14802,14 @@ msgstr "节点å称ä¸èƒ½ä¸ºç©º"
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr "节点å称应该介于1到255个字符之间"
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr "尚未åŒæ­¥"
msgid "Geo|Nothing to checksum"
-msgstr ""
+msgstr "无需校验和"
msgid "Geo|Nothing to synchronize"
-msgstr ""
+msgstr "没有è¦åŒæ­¥çš„内容"
msgid "Geo|Nothing to verify"
msgstr "无需验è¯"
@@ -14742,19 +14856,16 @@ msgstr "移除æ¡ç›®"
msgid "Geo|Remove node"
msgstr "删除节点"
-msgid "Geo|Remove secondary node"
-msgstr "删除次è¦èŠ‚点"
-
msgid "Geo|Remove tracking database entry"
msgstr "移除跟踪数æ®åº“æ¡ç›®"
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14764,16 +14875,16 @@ msgid "Geo|Replication details"
msgstr "å¤åˆ¶è¯¦æƒ…"
msgid "Geo|Replication slot WAL"
-msgstr ""
+msgstr "å¤åˆ¶æ§½WAL"
msgid "Geo|Replication slots"
-msgstr ""
+msgstr "å¤åˆ¶æ§½"
msgid "Geo|Replication status"
-msgstr ""
+msgstr "å¤åˆ¶çŠ¶æ€"
msgid "Geo|Replication summary"
-msgstr ""
+msgstr "å¤åˆ¶æ‘˜è¦"
msgid "Geo|Resync"
msgstr "é‡æ–°åŒæ­¥"
@@ -14782,10 +14893,10 @@ msgid "Geo|Resync all"
msgstr "é‡æ–°åŒæ­¥æ‰€æœ‰"
msgid "Geo|Resync all %{replicableType}"
-msgstr ""
+msgstr "é‡æ–°åŒæ­¥æ‰€æœ‰ %{replicableType}"
msgid "Geo|Resync all projects"
-msgstr ""
+msgstr "é‡æ–°åŒæ­¥æ‰€æœ‰é¡¹ç›®"
msgid "Geo|Retry count"
msgstr "é‡è¯•è®¡æ•°"
@@ -14797,18 +14908,21 @@ msgid "Geo|Reverify all"
msgstr "é‡æ–°æ ¡éªŒæ‰€æœ‰"
msgid "Geo|Reverify all projects"
-msgstr ""
+msgstr "é‡æ–°æ ¡éªŒæ‰€æœ‰é¡¹ç›®"
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
-msgstr "查看å¤åˆ¶çŠ¶æ€å¹¶ä¸Žä¸»è¦èŠ‚点é‡æ–°åŒæ­¥å’Œé‡æ–°éªŒè¯é¡¹ç›®ã€‚"
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
+msgstr ""
msgid "Geo|Secondary node"
msgstr "次节点"
msgid "Geo|Secondary site"
-msgstr ""
+msgstr "次è¦ç«™ç‚¹"
msgid "Geo|Selective (%{syncLabel})"
+msgstr "选择性 (%{syncLabel})"
+
+msgid "Geo|Site's status was updated %{timeAgo}."
msgstr ""
msgid "Geo|Status"
@@ -14835,11 +14949,11 @@ msgstr "åŒæ­¥è®¾ç½®"
msgid "Geo|Synchronization status"
msgstr "åŒæ­¥çŠ¶æ€"
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
-msgstr "æ•°æ®åº“当å‰è½åŽäºŽä¸»èŠ‚点%{db_lag}。"
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
+msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
-msgstr "当å‰èŠ‚点è½åŽäºŽä¸»èŠ‚点%{minutes_behind}。"
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
+msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
msgstr "没有%{replicable_type}å¯æ˜¾ç¤º"
@@ -14910,8 +15024,8 @@ msgstr "等待调度"
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr "使用 GitLab Geo,您å¯ä»¥åœ¨ä»»ä½•åœ°æ–¹å®‰è£…特殊的ã€åªè¯»çš„å¤åˆ¶å®žä¾‹ã€‚ %{linkStart}了解更多%{linkEnd}"
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
-msgstr "当å‰å¤„于一个次è¦ï¼Œ%{b_open}åªè¯»çš„%{b_close}Geo节点。"
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
+msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
msgstr "您å¯ä»¥åœ¨æ­¤é¡µé¢ä¸Šè¿›è¡Œæœ‰é™çš„更改或执行有é™çš„æ“作。"
@@ -14953,6 +15067,9 @@ msgid "Git"
msgstr "Git"
msgid "Git GC period"
+msgstr "Git GC 周期"
+
+msgid "Git LFS Rate Limits"
msgstr ""
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
@@ -15009,9 +15126,6 @@ msgstr "GitLabå¸æˆ·åˆ›å»ºè¯·æ±‚"
msgid "GitLab Billing Team."
msgstr "GitLab计费团队。"
-msgid "GitLab CI"
-msgstr "GitLab CI"
-
msgid "GitLab Import"
msgstr "GitLab导入"
@@ -15064,7 +15178,7 @@ msgid "GitLab is obtaining a Let's Encrypt SSL certificate for this domain. This
msgstr "GitLab正在为该域获å–Let's Encrypt SSLè¯ä¹¦ã€‚这个过程å¯èƒ½éœ€è¦ä¸€äº›æ—¶é—´ã€‚请ç¨åŽå†è¯•ã€‚"
msgid "GitLab is open source software to collaborate on code."
-msgstr ""
+msgstr "GitLab 是用于代ç å作的开æºè½¯ä»¶ã€‚"
msgid "GitLab is undergoing maintenance and is operating in a read-only mode."
msgstr "GitLab正在维护中,处于åªè¯»æ¨¡å¼ã€‚"
@@ -15091,13 +15205,13 @@ msgid "GitLab uses %{jaeger_link} to monitor distributed systems."
msgstr "GitLabå¯ä½¿ç”¨ %{jaeger_link}æ¥ç›‘控分布å¼ç³»ç»Ÿã€‚"
msgid "GitLab uses %{linkStart}Sidekiq%{linkEnd} to process background jobs"
-msgstr ""
+msgstr "GitLab 使用 %{linkStart}Sidekiq%{linkEnd} 处ç†åŽå°ä½œä¸š"
msgid "GitLab version"
msgstr "GitLab 版本"
msgid "GitLab will inform you if a new version is available."
-msgstr ""
+msgstr "如果有新版本,GitLab 将通知您。"
msgid "GitLab will run a background job that will produce pseudonymized CSVs of the GitLab database that will be uploaded to your configured object storage directory."
msgstr "GitLabå°†è¿è¡ŒåŽå°ä»»åŠ¡ï¼Œç”Ÿæˆæ•°æ®åº“的匿å化CSV,并上传到预先设定的对象存储目录。"
@@ -15145,7 +15259,7 @@ msgid "GitLabPages|GitLab Pages are disabled for this project. You can enable th
msgstr "GitLab Pages在此项目中ç¦ç”¨ã€‚您å¯ä»¥åœ¨æ‚¨çš„项目的%{strong_start}设置 &gt; 常规 &gt; å¯è§æ€§%{strong_end}页é¢å¯ç”¨ã€‚"
msgid "GitLabPages|Maximum size of pages (MB)"
-msgstr "页é¢æœ€å¤§å¤§å° (MB)"
+msgstr "pages æœ€å¤§å¤§å° (MB)"
msgid "GitLabPages|New Domain"
msgstr "新域å"
@@ -15154,7 +15268,7 @@ msgid "GitLabPages|Only project maintainers can remove pages"
msgstr "åªæœ‰é¡¹ç›®ç»´æŠ¤è€…å¯ä»¥åˆ é™¤é¡µé¢"
msgid "GitLabPages|Pages"
-msgstr ""
+msgstr "Pages"
msgid "GitLabPages|Remove"
msgstr "删除"
@@ -15166,7 +15280,7 @@ msgid "GitLabPages|Removing pages will prevent them from being exposed to the ou
msgstr "删除页é¢åŽå¤–部将无法访问。"
msgid "GitLabPages|Save changes"
-msgstr ""
+msgstr "ä¿å­˜æ›´æ”¹"
msgid "GitLabPages|Something went wrong while obtaining the Let's Encrypt certificate for %{domain}. To retry visit your %{link_start}domain details%{link_end}."
msgstr "在获å–域å%{domain}çš„Let's Encryptè¯ä¹¦æ—¶å‡ºé”™ã€‚如需é‡è¯•ï¼Œè¯·è®¿é—®æ‚¨çš„%{link_start}域详细信æ¯%{link_end}。"
@@ -15190,10 +15304,10 @@ msgid "GitLabPages|When using Pages under the general domain of a GitLab instanc
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "使用 GitLab Pages,您å¯ä»¥ç›´æŽ¥ä»Žæ‚¨çš„ GitLab 仓库托管您的é™æ€ç½‘站。%{docs_link_start}了解更多。%{link_end}"
msgid "GitLabPages|Your Pages site is not configured yet. See the %{docs_link_start}GitLab Pages documentation%{link_end} to learn how to upload your static site and have GitLab serve it. You can also take some inspiration from the %{samples_link_start}sample Pages projects%{link_end}."
-msgstr ""
+msgstr "您的Pages站点尚未é…置。请å‚阅 %{docs_link_start}GitLab Pages 文档%{link_end} 以了解如何上传您的é™æ€ç«™ç‚¹å¹¶è®© GitLab 为其æä¾›æœåŠ¡ã€‚您还å¯ä»¥ä»Ž %{samples_link_start}示例 Pages 项目%{link_end}获å–一些çµæ„Ÿã€‚"
msgid "GitLabPages|Your pages are served under:"
msgstr "您的网页æœåŠ¡å¯é€šè¿‡ä»¥ä¸‹åœ°å€è®¿é—®:"
@@ -15208,7 +15322,7 @@ msgid "Gitaly storage name:"
msgstr "Gitaly存储å称:"
msgid "Gitaly timeouts"
-msgstr ""
+msgstr "Gitaly 超时"
msgid "Gitaly|Address"
msgstr "地å€"
@@ -15220,22 +15334,22 @@ msgid "Gitea Import"
msgstr "从Gitea导入"
msgid "GithubIntegration|Create a %{token_link_start}personal access token%{token_link_end} with %{status_html} access granted and paste it here."
-msgstr ""
+msgstr "创建一个具有%{status_html}访问æƒé™çš„%{token_link_start}个人访问令牌%{token_link_end},并将其粘贴到此处。"
msgid "GithubIntegration|Obtain statuses for commits and pull requests."
-msgstr ""
+msgstr "获å–æ交和拉å–请求的状æ€ã€‚"
msgid "GithubIntegration|Repository URL"
msgstr "仓库URL"
msgid "GithubIntegration|Select this if you want GitHub to mark status checks as \"Required\". %{learn_more_link_start}Learn more%{learn_more_link_end}."
-msgstr ""
+msgstr "如果您希望 GitHub 将状æ€æ£€æŸ¥æ ‡è®°ä¸ºâ€œå¿…需â€ï¼Œè¯·é€‰æ‹©æ­¤é¡¹ã€‚%{learn_more_link_start}了解更多%{learn_more_link_end}。"
msgid "GithubIntegration|Static status check names (optional)"
-msgstr ""
+msgstr "é™æ€çŠ¶æ€æ£€æŸ¥å称(å¯é€‰ï¼‰"
msgid "GithubIntegration|This requires mirroring your GitHub repository to this project. %{docs_link}"
-msgstr ""
+msgstr "这需è¦å°†æ‚¨çš„ GitHub 仓库镜åƒåˆ°æ­¤é¡¹ç›®ã€‚ %{docs_link}"
msgid "Gitpod"
msgstr "Gitpod"
@@ -15247,10 +15361,10 @@ msgid "Gitpod|Gitpod URL"
msgstr "Gitpod网å€"
msgid "Gitpod|The URL to your Gitpod instance configured to read your GitLab projects, such as https://gitpod.example.com."
-msgstr ""
+msgstr "é…ç½®ä¸ºè¯»å– GitLab 项目的 Gitpod 实例的 URL,例如 https://gitpod.example.com。"
msgid "Gitpod|To use the integration, each user must also enable Gitpod on their GitLab account. %{link_start}How do I enable it?%{link_end} "
-msgstr ""
+msgstr "è¦ä½¿ç”¨é›†æˆï¼Œæ¯ä¸ªç”¨æˆ·è¿˜å¿…须在其 GitLab è´¦å·ä¸Šå¯ç”¨ Gitpod。 %{link_start}如何å¯ç”¨å®ƒï¼Ÿ%{link_end} "
msgid "Gitpod|https://gitpod.example.com"
msgstr "https://gitpod.example.com"
@@ -15261,6 +15375,9 @@ msgstr "%{time_ago}授æƒè®¿é—®"
msgid "Given epic is already related to this epic."
msgstr "给定å²è¯—å·²ç»ä¸Žæ­¤å²è¯—å…³è”。"
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr "全局快æ·é”®"
@@ -15286,7 +15403,7 @@ msgid "Go full screen"
msgstr "å…¨å±æ¨¡å¼"
msgid "Go to %{source_name}"
-msgstr ""
+msgstr "转到 %{source_name}"
msgid "Go to commits"
msgstr "转到æ交"
@@ -15342,8 +15459,8 @@ msgstr "转到上一级"
msgid "Go to previous page"
msgstr "转到上一页"
-msgid "Go to primary node"
-msgstr "转到主节点"
+msgid "Go to primary site"
+msgstr ""
msgid "Go to project"
msgstr "跳转到项目"
@@ -15421,7 +15538,7 @@ msgid "GrafanaIntegration|Active"
msgstr "å¯ç”¨"
msgid "GrafanaIntegration|Enter the %{docLinkStart}Grafana API token%{docLinkEnd}."
-msgstr ""
+msgstr "输入 %{docLinkStart}Grafana API 令牌%{docLinkEnd}。"
msgid "GrafanaIntegration|Enter the base URL of the Grafana instance."
msgstr "输入Grafana实例的基础URL。"
@@ -15433,13 +15550,13 @@ msgid "GrafanaIntegration|Grafana authentication"
msgstr "Grafana身份验è¯"
msgid "GrafanaIntegration|Set up Grafana authentication to embed Grafana panels in GitLab Flavored Markdown."
-msgstr ""
+msgstr "设置 Grafana 身份验è¯ä»¥åœ¨ GitLab Flavored Markdown 中嵌入 Grafana é¢æ¿ã€‚"
msgid "Grant access"
msgstr "å…许访问"
msgid "Grant write permissions to this key"
-msgstr ""
+msgstr "授予此密钥写入æƒé™"
msgid "Graph"
msgstr "分支图"
@@ -15496,7 +15613,7 @@ msgid "Group URL"
msgstr "群组URL"
msgid "Group Wikis"
-msgstr ""
+msgstr "群组 Wiki"
msgid "Group application: %{name}"
msgstr "群组应用程åºï¼š%{name}"
@@ -15520,7 +15637,7 @@ msgid "Group export could not be started."
msgstr "群组导出无法å¯åŠ¨ã€‚"
msgid "Group export download requests"
-msgstr ""
+msgstr "群组导出下载请求"
msgid "Group export error"
msgstr "群组导出错误"
@@ -15529,7 +15646,7 @@ msgid "Group export link has expired. Please generate a new export from your gro
msgstr "群组导出链接已过期。请从群组设置生æˆæ–°çš„导出。"
msgid "Group export requests"
-msgstr ""
+msgstr "群组导出请求"
msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr "群组导出已ç»å¼€å§‹ã€‚下载链接将通过电å­é‚®ä»¶å‘é€å¹¶åœ¨æ­¤é¡µé¢ä¸Šæ供。"
@@ -15544,7 +15661,7 @@ msgid "Group import could not be scheduled"
msgstr "无法安排群组导入"
msgid "Group import requests"
-msgstr ""
+msgstr "群组导入请求"
msgid "Group info:"
msgstr "群组信æ¯"
@@ -15556,7 +15673,7 @@ msgid "Group is required when cluster_type is :group"
msgstr "cluster_type为:group时群组为必需"
msgid "Group jobs by"
-msgstr ""
+msgstr "分组作业按"
msgid "Group maintainers can register group runners in the %{link}"
msgstr "群组维护者å¯ä»¥åœ¨é€šè¿‡ %{link} 注册群组级 Runner"
@@ -15565,10 +15682,10 @@ msgid "Group members"
msgstr "群组æˆå‘˜"
msgid "Group membership expiration date changed"
-msgstr ""
+msgstr "群组æˆå‘˜èµ„格到期日期已更改"
msgid "Group membership expiration date removed"
-msgstr ""
+msgstr "群组æˆå‘˜èµ„格到期日期已删除"
msgid "Group milestone"
msgstr "群组里程碑"
@@ -15586,7 +15703,7 @@ msgid "Group overview content"
msgstr "群组概述内容"
msgid "Group path is already taken. We've suggested one that is available."
-msgstr ""
+msgstr "群组路径已被å ç”¨ï¼Œæˆ‘们已ç»æŽ¨è了一个å¯ç”¨çš„。"
msgid "Group path is available."
msgstr "群组路径å¯ç”¨ã€‚"
@@ -15607,10 +15724,10 @@ msgid "Group runners"
msgstr "群组Runner"
msgid "Group runners can be managed with the %{link}."
-msgstr ""
+msgstr "群组 Runner å¯ä»¥ä½¿ç”¨ %{link} 管ç†ã€‚"
msgid "Group sharing provides access to all group members (including members who inherited group membership from a parent group)."
-msgstr ""
+msgstr "群组共享æ供对所有群组æˆå‘˜ï¼ˆåŒ…括从上级群组继承群组æˆå‘˜èµ„格的æˆå‘˜ï¼‰çš„访问。"
msgid "Group variables (inherited)"
msgstr "群组å˜é‡ (继承)"
@@ -15667,7 +15784,7 @@ msgid "GroupRoadmap|%{startDateInWords} – %{endDateInWords}"
msgstr "%{startDateInWords} – %{endDateInWords}"
msgid "GroupRoadmap|Loading epics"
-msgstr ""
+msgstr "正在加载å²è¯—"
msgid "GroupRoadmap|No start and end date"
msgstr "无开始和结æŸæ—¥æœŸ"
@@ -15693,9 +15810,15 @@ msgstr "对ä¸èµ·ï¼Œæœªæœç´¢åˆ°ä»»ä½•ç¬¦åˆæ¡ä»¶çš„ å²è¯—"
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr "路线图显示了å²è¯— 沿ç€æ—¶é—´çº¿çš„进展情况"
-msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
msgstr ""
+msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
+msgstr "è¦ä½¿æ‚¨çš„å²è¯—出现在路线图中,请为其添加开始日期或截止日期。"
+
msgid "GroupRoadmap|To view the roadmap, add a start or due date to one of the %{linkStart}child epics%{linkEnd}."
msgstr "è¦æŸ¥çœ‹è·¯çº¿å›¾ï¼Œè¯·è‡³å°‘为一个%{linkStart}å­å²è¯—%{linkEnd}添加开始或截止日期。"
@@ -15705,9 +15828,12 @@ msgstr "è¦æŸ¥çœ‹è·¯çº¿å›¾ï¼Œè¯·åœ¨æ­¤ç¾¤ç»„或其å­ç¾¤ç»„中的一个 å²è¯— ä
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr "è¦æ‰©å¤§æ‚¨çš„æœç´¢ï¼Œè¯·æ›´æ”¹æˆ–移除筛选器,从 %{startDate} 到 %{endDate}。"
-msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
+msgid "GroupRoadmap|Within 3 years"
msgstr ""
+msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
+msgstr "%{strongOpen}警告%{strongClose} - å¯ç”¨ %{linkStart}SSO 执行%{linkEnd} å¯ä»¥é™ä½Žå®‰å…¨é£Žé™©ã€‚"
+
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr "å¯ç”¨çš„SAML群组链接(%{count})"
@@ -15715,7 +15841,7 @@ msgid "GroupSAML|Are you sure you want to remove the SAML group link?"
msgstr "您确定è¦åˆ é™¤SAML群组链接å—?"
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
-msgstr ""
+msgstr "在执行SSO之å‰ï¼Œå¯ç”¨SAML身份验è¯ã€‚"
msgid "GroupSAML|Before enforcing SSO-only authentication for Git activity, enable SSO-only authentication for web activity."
msgstr ""
@@ -15736,16 +15862,16 @@ msgid "GroupSAML|Default membership role"
msgstr "默认æˆå‘˜è§’色"
msgid "GroupSAML|Enable SAML authentication for this group"
-msgstr ""
+msgstr "为此群组å¯ç”¨ SAML 身份认è¯"
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
-msgstr ""
+msgstr "对该群组的 Web 活动强制执行仅 SSO 身份验è¯"
msgid "GroupSAML|Enforce users to have dedicated group-managed accounts for this group"
-msgstr ""
+msgstr "强制用户为此组拥有专用的组管ç†å¸æˆ·"
msgid "GroupSAML|Generate a SCIM token"
msgstr "ç”Ÿæˆ SCIM 令牌"
@@ -15784,7 +15910,7 @@ msgid "GroupSAML|No active SAML group links"
msgstr "没有å¯ç”¨çš„SAML群组链接"
msgid "GroupSAML|Prohibit outer forks for this group"
-msgstr ""
+msgstr "ç¦æ­¢ä»Žæ­¤ç¾¤ç»„å‘外派生。"
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr "指定此SAML群组æˆå‘˜çš„角色。"
@@ -15832,7 +15958,7 @@ msgid "GroupSAML|This will be set as the access level of users added to the grou
msgstr "这将被设置为添加到群组的用户的访问级别。"
msgid "GroupSAML|To be able to enable group-managed accounts, you first need to enable enforced SSO."
-msgstr ""
+msgstr "为了能够å¯ç”¨ç»„管ç†å¸æˆ·ï¼Œæ‚¨é¦–先需è¦å¯ç”¨æ‰§è¡Œ SSO。"
msgid "GroupSAML|To be able to prohibit outer forks, you first need to enforce dedicate group managed accounts."
msgstr "如需ç¦æ­¢å¤–部派生,您首先需è¦å¼ºåˆ¶æ‰§è¡ŒæŒ‡å®šç¾¤ç»„托管账户。"
@@ -15859,7 +15985,7 @@ msgid "GroupSAML|should be a random persistent ID, emails are discouraged"
msgstr "应为éšæœºçš„永久性ID,ä¸å»ºè®®ä½¿ç”¨ç”µå­é‚®ç®±"
msgid "GroupSelect|No matching results"
-msgstr ""
+msgstr "没有匹é…的结果"
msgid "GroupSelect|Search groups"
msgstr "æœç´¢ç¾¤ç»„"
@@ -15868,7 +15994,7 @@ msgid "GroupSelect|Select a group"
msgstr "选择一个群组"
msgid "GroupSettings|Allow project access token creation"
-msgstr ""
+msgstr "å…许创建项目访问令牌"
msgid "GroupSettings|Auto DevOps pipeline was updated for the group"
msgstr "已为群组更新 Auto DevOps æµæ°´çº¿"
@@ -15892,7 +16018,7 @@ msgid "GroupSettings|Compliance frameworks"
msgstr "åˆè§„框架"
msgid "GroupSettings|Configure frameworks to apply enforceable rules to projects."
-msgstr ""
+msgstr "é…置框架以将å¯æ‰§è¡Œè§„则应用于项目。"
msgid "GroupSettings|Custom project templates"
msgstr "自定义项目模æ¿"
@@ -15910,13 +16036,13 @@ msgid "GroupSettings|Disable group mentions"
msgstr "ç¦ç”¨ç¾¤ç»„æåŠ"
msgid "GroupSettings|Enable delayed project deletion"
-msgstr ""
+msgstr "å¯ç”¨å»¶è¿Ÿé¡¹ç›®åˆ é™¤"
msgid "GroupSettings|Export group"
msgstr "导出群组"
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
-msgstr ""
+msgstr "如果未在群组或实例级别指定,则默认为 %{default_initial_branch_name}。ä¸å½±å“现有仓库。"
msgid "GroupSettings|If the parent group's visibility is lower than the group current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr "如果新父群组的å¯è§æ€§ä½ŽäºŽå½“å‰ç¾¤ç»„çš„å¯è§æ€§ï¼Œå­ç¾¤ç»„和项目的å¯è§åº¦å°†ä¼šæ”¹å˜ï¼Œä»¥ä¾¿ä¸Žæ–°çˆ¶ç¾¤ç»„çš„å¯è§æ€§ç›¸åŒ¹é…。"
@@ -15928,7 +16054,7 @@ msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr "群组æµæ°´çº¿è®¾ç½®å·²æ›´æ–°"
msgid "GroupSettings|Please choose a group URL with no special characters or spaces."
-msgstr ""
+msgstr "请选择一个没有特殊字符或空格的群组URL。"
msgid "GroupSettings|Prevent forking outside of the group"
msgstr "阻止派生到群组外。"
@@ -15937,31 +16063,31 @@ msgid "GroupSettings|Prevent forking setting was not saved"
msgstr "阻止派生设置未ä¿å­˜"
msgid "GroupSettings|Prevent members from sending invitations to groups outside of %{group} and its subgroups."
-msgstr ""
+msgstr "ç¦æ­¢æˆå‘˜å‘é€é‚€è¯·åˆ° %{group} åŠå…¶å­ç¾¤ç»„。"
msgid "GroupSettings|Prevent sharing a project within %{group} with other groups"
msgstr "ç¦æ­¢ä¸Žå…¶ä»–群组共享 %{group} 中的项目"
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. Inherited by subgroups."
-msgstr ""
+msgstr "项目将在 %{waiting_period}天延迟åŽæ°¸ä¹…删除,由å­ç»„继承。"
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
-msgstr ""
+msgstr "项目将在%{waiting_period}天延迟åŽæ°¸ä¹…删除,此延迟在实例设置中%{link_start}å¯ä»¥ç”±ç®¡ç†å‘˜å®šä¹‰%{link_end} ,由å­ç¾¤ç»„继承。"
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
-msgstr ""
+msgstr "选择一个å­ç»„用作该组的自定义项目模æ¿çš„æºã€‚"
msgid "GroupSettings|Set the maximum size of GitLab Pages for this group. %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "为该群组设置GitLab Pages的最大大å°ã€‚ %{link_start}了解更多。%{link_end}"
msgid "GroupSettings|The Auto DevOps pipeline runs if no alternative CI configuration file is found."
-msgstr ""
+msgstr "如果找ä¸åˆ°æ›¿ä»£ CI é…置文件,则Auto DevOps æµæ°´çº¿å°†è¿è¡Œã€‚"
msgid "GroupSettings|The default name for the initial branch of new repositories created in the group."
-msgstr ""
+msgstr "群组中创建的新仓库的åˆå§‹åˆ†æ”¯çš„默认å称。"
msgid "GroupSettings|The projects in this subgroup can be selected as templates for new projects created in the group. %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "å¯ä»¥é€‰æ‹©è¯¥å­ç»„中的项目作为该组中创建的新项目的模æ¿ã€‚ %{link_start}了解更多。%{link_end}"
msgid "GroupSettings|There was a problem updating Auto DevOps pipeline: %{error_messages}."
msgstr "æ›´æ–° Auto DevOps æµæ°´çº¿æ—¶å‡ºçŽ°é—®é¢˜ï¼š %{error_messages}。"
@@ -15979,7 +16105,7 @@ msgid "GroupSettings|This setting is applied on %{ancestor_group}. You can overr
msgstr "此设置已应用于 %{ancestor_group}。 您å¯ä»¥è¦†ç›–此设置或 %{remove_ancestor_share_with_group_lock}。"
msgid "GroupSettings|This setting is only available on the top-level group and it applies to all subgroups. Groups that have already been shared with a group outside %{group} will still be shared, and this access will have to be revoked manually."
-msgstr ""
+msgstr "此设置仅适用于顶级群组并且应用于所有å­ç»„。%{group}以外的其它群组所共享的群组ä»å°†è¢«å…±äº«ï¼Œå¿…须手动撤消此访问æƒé™ã€‚"
msgid "GroupSettings|This setting will be applied to all subgroups unless overridden by a group owner. Groups that already have access to the project will continue to have access unless removed manually."
msgstr "此设置将应用于所有å­ç¾¤ç»„。å­ç¾¤ç»„所有者å¯åœ¨å…¶å±‚级更改此设置。在访问æƒé™è¢«æ‰‹åŠ¨ç§»é™¤å‰ï¼Œå·²æœ‰æƒè®¿é—®è¯¥é¡¹ç›®çš„群组将继续ä¿æŒè®¿é—®æƒé™ã€‚"
@@ -15997,7 +16123,7 @@ msgid "GroupSettings|Transfer group"
msgstr "转移群组"
msgid "GroupSettings|Users can create %{link_start}project access tokens%{link_end} for projects in this group."
-msgstr ""
+msgstr "用户å¯ä»¥ä¸ºè¯¥ç¾¤ç»„中的项目创建 %{link_start}项目访问令牌%{link_end}。"
msgid "GroupSettings|What are badges?"
msgstr "什么是徽章?"
@@ -16069,10 +16195,10 @@ msgid "GroupsEmptyState|You can manage your group member’s permissions and acc
msgstr "您å¯ä»¥ç®¡ç†ç¾¤ç»„æˆå‘˜çš„æƒé™å¹¶è®¿é—®ç¾¤ç»„中的æ¯ä¸ªé¡¹ç›®ã€‚"
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects. Groups can also be nested by creating subgroups."
-msgstr ""
+msgstr "%{linkStart}群组%{linkEnd}å…许您在多个项目之间进行管ç†ä¸Žå作。群组的æˆå‘˜æ‹¥æœ‰è®¿é—®å…¶ä¸­æ‰€æœ‰é¡¹ç›®çš„æƒé™ã€‚群组也å¯ä»¥é€šè¿‡åˆ›å»ºå­ç¾¤ç»„æ¥è¿›è¡ŒåµŒå¥—。"
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
-msgstr ""
+msgstr "将相关项目组åˆåœ¨ä¸€èµ·å¹¶ä¸€æ¬¡æŽˆäºˆæˆå‘˜è®¿é—®å¤šä¸ªé¡¹ç›®çš„æƒé™ã€‚"
msgid "GroupsNew|Connect instance"
msgstr "连接实例"
@@ -16087,13 +16213,13 @@ msgid "GroupsNew|Create new group"
msgstr "创建新的群组"
msgid "GroupsNew|Export groups with all their related data and move to a new GitLab instance."
-msgstr ""
+msgstr "导出群组åŠå…¶æ‰€æœ‰ç›¸å…³æ•°æ®å¹¶ç§»åŠ¨åˆ°æ–°çš„ GitLab 实例。"
msgid "GroupsNew|GitLab source URL"
msgstr "GitLabæºURL"
msgid "GroupsNew|Groups can also be nested by creating %{linkStart}subgroups%{linkEnd}."
-msgstr ""
+msgstr "通过创建 %{linkStart}å­ç»„%{linkEnd} 也å¯ä»¥åµŒå¥—群组。"
msgid "GroupsNew|Import group"
msgstr "导入群组"
@@ -16105,13 +16231,13 @@ msgid "GroupsNew|My Awesome Group"
msgstr "My Awesome Group"
msgid "GroupsNew|Navigate to user settings to find your %{link_start}personal access token%{link_end}."
-msgstr ""
+msgstr "导航到用户设置以查找您的 %{link_start}个人访问令牌%{link_end}。"
msgid "GroupsNew|No import options available"
msgstr "æ— å¯ç”¨çš„导入选项"
msgid "GroupsNew|Not all related objects are migrated, as %{docs_link_start}described here%{docs_link_end}. Please %{feedback_link_start}leave feedback%{feedback_link_end} on this feature."
-msgstr ""
+msgstr "并éžæ‰€æœ‰ç›¸å…³å¯¹è±¡éƒ½è¢«è¿ç§»ï¼Œå¦‚%{docs_link_start}此处æè¿°%{docs_link_end}。请留下关于此功能的%{feedback_link_start}å馈%{feedback_link_end}。"
msgid "GroupsNew|Personal access token"
msgstr "个人访问令牌"
@@ -16123,10 +16249,10 @@ msgid "GroupsNew|Please fill in your personal access token."
msgstr "请填写个人访问令牌。"
msgid "GroupsNew|Provide credentials for another instance of GitLab to import your groups directly."
-msgstr ""
+msgstr "为å¦ä¸€ä¸ª GitLab 实例æ供凭æ®ä»¥ç›´æŽ¥å¯¼å…¥æ‚¨çš„群组。"
msgid "GroupsNew|To import a group, navigate to the group settings for the GitLab source instance, %{link_start}generate an export file%{link_end}, and upload it here."
-msgstr ""
+msgstr "è¦å¯¼å…¥ç¾¤ç»„,请导航到 GitLab æºå®žä¾‹çš„群组设置, %{link_start}生æˆå¯¼å‡ºæ–‡ä»¶%{link_end},然åŽåœ¨æ­¤å¤„上传。"
msgid "GroupsNew|Upload file"
msgstr "上传文件"
@@ -16162,10 +16288,10 @@ msgid "Guideline"
msgstr "å‚考"
msgid "HAR (HTTP Archive)"
-msgstr ""
+msgstr "HAR(HTTP 存档)"
msgid "HAR file path or URL"
-msgstr ""
+msgstr "HAR 文件路径或 URL"
msgid "HTTP Basic: Access denied\\nYou must use a personal access token with 'api' scope for Git over HTTP.\\nYou can generate one at %{profile_personal_access_tokens_url}"
msgstr "HTTP Basic:访问被拒ç»\\n您必须使用具有'api'æƒé™çš„个人访问令牌。\\n您å¯ä»¥åœ¨ %{profile_personal_access_tokens_url}中生æˆä¸€ä¸ª"
@@ -16180,22 +16306,22 @@ msgid "Hashed storage can't be disabled anymore for new projects"
msgstr "新项目ä¸èƒ½å†ç¦ç”¨å“ˆå¸Œå­˜å‚¨"
msgid "Header cannot be associated with both a request and a response"
-msgstr ""
+msgstr "Header ä¸èƒ½åŒæ—¶ä¸Žè¯·æ±‚å’Œå“应相关è”"
msgid "Header logo"
-msgstr ""
+msgstr "Header logo"
msgid "Header logo was successfully removed."
msgstr "标题徽标已æˆåŠŸåˆ é™¤ã€‚"
msgid "Header logo will be removed. Are you sure?"
-msgstr ""
+msgstr "Header logo将被删除。您确定å—?"
msgid "Header message"
msgstr "页头消æ¯"
msgid "Header must be associated with a request or response"
-msgstr ""
+msgstr "Header必须与请求或å“应相关è”"
msgid "Heading 1"
msgstr "标题 1"
@@ -16246,7 +16372,7 @@ msgid "Hello there"
msgstr "你好"
msgid "Hello, %{name}!"
-msgstr ""
+msgstr "%{name},您好!"
msgid "Hello, %{username}!"
msgstr "%{username},您好!"
@@ -16261,15 +16387,15 @@ msgid "Helps prevent bots from creating accounts."
msgstr "有助于防止机器人程åºåˆ›å»ºè´¦æˆ·ã€‚"
msgid "Helps prevent bots from creating issues"
-msgstr ""
+msgstr "有助于防止机器人创建议题"
msgid "Helps prevent malicious users hide their activity"
-msgstr ""
-
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
-msgstr "有助于å‡å°‘警报数é‡ï¼ˆä¾‹å¦‚,如果创建太多议题)"
+msgstr "帮助防止æ¶æ„用户éšè—其活动"
msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgstr "帮助å‡å°‘请求é‡ï¼ˆä¾‹å¦‚æ¥è‡ªçˆ¬è™«æˆ–滥用机器人的请求)"
+
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16282,7 +16408,7 @@ msgid "Hi %{username}!"
msgstr "%{username},您好!"
msgid "Hide"
-msgstr ""
+msgstr "éšè—"
msgid "Hide archived projects"
msgstr "éšè—已归档的项目"
@@ -16310,7 +16436,7 @@ msgid "Hide list"
msgstr "éšè—列表"
msgid "Hide marketing-related entries from the Help page"
-msgstr ""
+msgstr "在帮助页é¢éšè—与市场è¥é”€ç›¸å…³çš„æ¡ç›®"
msgid "Hide payload"
msgstr "éšè—有效数æ®"
@@ -16319,7 +16445,7 @@ msgid "Hide shared projects"
msgstr "éšè—共享项目"
msgid "Hide tooltips or popovers"
-msgstr ""
+msgstr "éšè—工具æ示或弹出窗å£"
msgid "Hide value"
msgid_plural "Hide values"
@@ -16356,7 +16482,7 @@ msgid "History of authentications"
msgstr "身份验è¯çš„历å²"
msgid "Home page URL"
-msgstr ""
+msgstr "首页URL"
msgid "Homepage"
msgstr "主页"
@@ -16374,7 +16500,7 @@ msgid "Hostname"
msgstr "主机å"
msgid "Hostname used in private commit emails. %{learn_more}"
-msgstr ""
+msgstr "ç§äººæ交电å­é‚®ä»¶ä¸­ä½¿ç”¨çš„主机å。 %{learn_more}"
msgid "Hour (UTC)"
msgstr "å°æ—¶(UTC)"
@@ -16389,22 +16515,25 @@ msgid "Housekeeping, export, path, transfer, remove, archive."
msgstr "管家,导出,路径,转移,删除,存档。"
msgid "How do I configure runners?"
-msgstr ""
+msgstr "如何é…ç½® Runner?"
msgid "How do I configure this integration?"
-msgstr ""
+msgstr "如何é…置此集æˆï¼Ÿ"
msgid "How do I generate it?"
-msgstr ""
+msgstr "我如何生æˆå®ƒï¼Ÿ"
msgid "How do I mirror repositories?"
+msgstr "如何镜åƒä»“库?"
+
+msgid "How do I rename an environment?"
msgstr ""
msgid "How do I set up a Google Chat webhook?"
-msgstr ""
+msgstr "如何设置 Google Chat webhook?"
msgid "How do I set up this service?"
-msgstr ""
+msgstr "如何设置此æœåŠ¡ï¼Ÿ"
msgid "How it works"
msgstr "工作原ç†"
@@ -16419,31 +16548,31 @@ msgid "I accept the %{terms_link}"
msgstr "æˆ‘æŽ¥å— %{terms_link}"
msgid "I accept the|Terms of Service and Privacy Policy"
-msgstr "æœåŠ¡æ¡æ¬¾å’Œéšç§æ”¿ç­–"
+msgstr ""
msgid "I forgot my password"
msgstr "我忘记了密ç "
msgid "I want to explore GitLab to see if it’s worth switching to"
-msgstr ""
+msgstr "我想探索 GitLab,看看是å¦å€¼å¾—切æ¢åˆ°è¿™é‡Œ"
msgid "I want to learn the basics of Git"
-msgstr ""
+msgstr "我想学习Git基础知识"
msgid "I want to move my repository to GitLab from somewhere else"
-msgstr ""
+msgstr "我想把我的仓库从其它地方移动到GitLab"
msgid "I want to store my code"
-msgstr ""
+msgstr "我想存储我的代ç "
msgid "I want to use GitLab CI with my existing repository"
-msgstr ""
+msgstr "我想在我的现有仓库上使用GitLab CI"
msgid "I'd like to receive updates about GitLab via email"
msgstr "我希望通过电å­é‚®ä»¶æŽ¥æ”¶GitLabçš„æ›´æ–°"
msgid "I'm signing up for GitLab because:"
-msgstr ""
+msgstr "我注册GitLab是因为:"
msgid "ID"
msgstr "ID"
@@ -16509,7 +16638,7 @@ msgid "IP subnet restriction only allowed for top-level groups"
msgstr "åªå…许在最顶层群组设置IPå­ç½‘é™åˆ¶"
msgid "IPs per user"
-msgstr ""
+msgstr "æ¯ä¸ªç”¨æˆ·çš„ IP"
msgid "Identifier"
msgstr "身份标识"
@@ -16536,19 +16665,19 @@ msgid "If disabled, a diverged local branch will not be automatically updated wi
msgstr "如果ç¦ç”¨ï¼Œåˆ™ä¸ä¼šä½¿ç”¨è¿œç¨‹å‰¯æœ¬çš„æ交自动更新分å‰çš„本地分支,以防止本地数æ®ä¸¢å¤±ã€‚如果默认分支 (%{default_branch}) 已分å‰ä¸”无法更新,则镜åƒå°†å¤±è´¥ã€‚其他分å‰çš„分支默默被忽略。"
msgid "If disabled, only administrators can configure repository mirroring."
-msgstr ""
+msgstr "如果ç¦ç”¨ï¼Œåˆ™åªæœ‰ç®¡ç†å‘˜å¯ä»¥é…置仓库镜åƒã€‚"
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
-msgstr "如果å¯ç”¨ï¼ŒGitLab将使用Geo处ç†å¯¹è±¡å­˜å‚¨å¤åˆ¶ã€‚ %{linkStart}更多信æ¯%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
+msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
msgstr "如果å¯ç”¨ï¼Œåˆ™ä½¿ç”¨å¤–部æœåŠ¡ä¸Šçš„分类标签æ¥éªŒè¯å¯¹é¡¹ç›®çš„访问æƒé™ã€‚"
msgid "If enabled, only protected branches will be mirrored."
-msgstr ""
+msgstr "如果å¯ç”¨ï¼Œåˆ™åªä¼šé•œåƒå—ä¿æŠ¤çš„分支。"
msgid "If no options are selected, only administrators can register runners."
-msgstr ""
+msgstr "如果没有选定选项,åªæœ‰ç®¡ç†å‘˜å¯ä»¥æ³¨å†ŒRunner。"
msgid "If the YouTube URL is https://www.youtube.com/watch?v=0t1DgySidms then the video ID is %{id}"
msgstr "如果YouTube网å€ä¸ºhttps://www.youtube.com/watch?v=0t1DgySidms,则视频ID为%{id}"
@@ -16557,10 +16686,10 @@ msgid "If the number of active users exceeds the user limit, you will be charged
msgstr "如果活跃用户数é‡è¶…过了用户é™åˆ¶ï¼Œæ‚¨ä¸‹æ¬¡çš„许å¯è¯å¯¹è´¦æ—¶å°†ä¼šæ”¶å–%{users_over_license_link}个席ä½çš„费用。"
msgid "If this email was added in error, you can remove it here:"
-msgstr ""
+msgstr "如果此电å­é‚®ä»¶è¢«é”™è¯¯æ·»åŠ ï¼Œæ‚¨å¯ä»¥åœ¨è¿™é‡Œåˆ é™¤ï¼š"
msgid "If this email was added in error, you can remove it here: %{profile_emails_url}"
-msgstr ""
+msgstr "如果此电å­é‚®ä»¶è¢«é”™è¯¯æ·»åŠ ï¼Œæ‚¨å¯ä»¥åœ¨è¿™é‡Œåˆ é™¤å®ƒï¼š %{profile_emails_url}"
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr "如果这是一个错误,你å¯ä»¥%{leave_link_start}退出%{source_type}%{link_end}。"
@@ -16575,10 +16704,10 @@ msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be
msgstr "如果将%{codeStart}needs%{codeEnd}加到æµæ°´çº¿çš„作业里é¢ï¼Œæ‚¨å°†å¯ä»¥åœ¨%{linkStart}有å‘无环图 (DAG)%{linkEnd}页é¢çœ‹åˆ°ä½œä¸šä¹‹é—´çš„%{codeStart}needs%{codeEnd}关系。"
msgid "If you did not initiate this change, please contact your administrator immediately."
-msgstr ""
+msgstr "如果您没有å‘起此更改,请立å³è”系您的管ç†å‘˜ã€‚"
msgid "If you did not perform this request, you can safely ignore this email."
-msgstr ""
+msgstr "如果您没有执行此请求,您å¯ä»¥å®‰å…¨åœ°å¿½ç•¥æ­¤ç”µå­é‚®ä»¶ã€‚"
msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
msgstr "å¦‚æžœæ‚¨æœ€è¿‘æ²¡æœ‰ç™»å½•ï¼Œè¯·ç«‹å³ %{password_link_start}更改密ç %{password_link_end}。"
@@ -16587,7 +16716,7 @@ msgid "If you did not recently sign in, you should immediately change your passw
msgstr "如果您最近没有登录,请立å³æ›´æ”¹å¯†ç : %{password_link}。"
msgid "If you get a lot of false alarms from repository checks, you can clear all repository check information from the database."
-msgstr ""
+msgstr "如果您从仓库检查中得到大é‡è¯¯æŠ¥ï¼Œæ‚¨å¯ä»¥ä»Žæ•°æ®åº“中清除所有仓库检查信æ¯ã€‚"
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
msgstr "如果您丢失了æ¢å¤ç ï¼Œæ‚¨å¯ä»¥ç”Ÿæˆæ–°çš„æ¢å¤ç ï¼Œæ‰€æœ‰ä»¥å‰çš„æ¢å¤ç å°†å¤±æ•ˆã€‚"
@@ -16602,7 +16731,7 @@ msgid "If you want to re-enable two-factor authentication, visit the %{settings_
msgstr "如果您想è¦é‡æ–°å¯ç”¨åŒé‡èº«ä»½éªŒè¯ï¼Œè¯·è®¿é—®%{settings_link_to}页é¢ã€‚"
msgid "If you've purchased or renewed your subscription and have an activation code, please enter it below to start the activation process."
-msgstr ""
+msgstr "如果您已购买或续订订阅并拥有激活ç ï¼Œè¯·åœ¨ä¸‹æ–¹è¾“入激活ç ä»¥å¼€å§‹æ¿€æ´»è¿‡ç¨‹ã€‚"
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr "如果您的HTTP仓库无法公开访问,需在地å€ä¸­æ·»åŠ å‡­æ®ã€‚"
@@ -16635,10 +16764,10 @@ msgid "ImageViewerDimensions|W"
msgstr "宽"
msgid "Images with incorrect dimensions are not resized automatically, and may result in unexpected behavior."
-msgstr ""
+msgstr "尺寸ä¸æ­£ç¡®çš„图åƒä¸ä¼šè‡ªåŠ¨è°ƒæ•´å¤§å°ï¼Œå¹¶ä¸”å¯èƒ½ä¼šå¯¼è‡´æ„外行为。"
msgid "Impersonate"
-msgstr ""
+msgstr "模拟"
msgid "Impersonation Tokens"
msgstr "身份模拟令牌"
@@ -16800,295 +16929,298 @@ msgid "Importing..."
msgstr "导入中..."
msgid "Import|A repository URL usually ends in a .git suffix, although this is not required. Double check to make sure your repository URL is correct."
-msgstr ""
+msgstr "仓库 URL 通常以 .git åŽç¼€ç»“尾,尽管这ä¸æ˜¯å¿…需的。仔细检查以确ä¿æ‚¨çš„仓库 URL 正确。"
msgid "Improve customer support with Service Desk"
msgstr "通过æœåŠ¡å°æ”¹å–„客户支æŒ"
msgid "Improves Git cloning performance."
-msgstr ""
+msgstr "æ高 Git 克隆性能。"
msgid "In %{time_to_now}"
msgstr "%{time_to_now}åŽ"
msgid "In case of pull mirroring, your user will be the author of all events in the activity feed that are the result of an update, like new branches being created or new commits being pushed to existing branches."
-msgstr ""
+msgstr "在拉å–é•œåƒçš„情况下,您的用户将æˆä¸ºæ´»åŠ¨æè¦ä¸­æ‰€æœ‰ä½œä¸ºæ›´æ–°ç»“果的事件的作者,例如创建新分支或将新æ交推é€åˆ°çŽ°æœ‰åˆ†æ”¯ã€‚"
msgid "In each example, replace %{code_start}TOKEN%{code_end} with the trigger token you generated and replace %{code_start}REF_NAME%{code_end} with the branch or tag name."
-msgstr ""
+msgstr "在æ¯ä¸ªç¤ºä¾‹ä¸­ï¼Œå°† %{code_start}TOKEN%{code_end} 替æ¢ä¸ºæ‚¨ç”Ÿæˆçš„触å‘令牌,并将 %{code_start}REF_NAME%{code_end} 替æ¢ä¸ºåˆ†æ”¯æˆ–标签å称。"
msgid "In progress"
msgstr "进行中"
msgid "In this page you will find information about the settings that are used in your current instance."
+msgstr "在此页é¢ä¸­ï¼Œæ‚¨å°†æ‰¾åˆ°æœ‰å…³å½“å‰å®žä¾‹ä¸­ä½¿ç”¨çš„设置的信æ¯ã€‚"
+
+msgid "InProductMarketing|%{organization_name} logo"
msgstr ""
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
-msgstr ""
+msgstr "%{strong_start}高级应用程åºå®‰å…¨%{strong_end} — 包括 SASTã€DAST 扫æã€FUZZ 测试ã€ä¾èµ–性扫æã€è®¸å¯è¯åˆè§„性ã€ç§˜å¯†æ£€æµ‹"
msgid "InProductMarketing|%{strong_start}Company wide portfolio management%{strong_end} — including multi-level epics, scoped labels"
-msgstr ""
+msgstr "%{strong_start}å…¬å¸èŒƒå›´å†…的组åˆç®¡ç†%{strong_end} — 包括多级å²è¯—ã€èŒƒå›´æ ‡ç­¾"
msgid "InProductMarketing|%{strong_start}Executive level insights%{strong_end} — including reporting on productivity, tasks by type, days to completion, value stream"
-msgstr ""
+msgstr "%{strong_start}高管级洞察%{strong_end} — 包括生产力报告ã€ä»»åŠ¡ç±»åž‹ã€å®Œæˆå¤©æ•°ã€ä»·å€¼æµ"
msgid "InProductMarketing|%{strong_start}GitLab Inc.%{strong_end} 268 Bush Street, #350, San Francisco, CA 94104, USA"
msgstr ""
msgid "InProductMarketing|%{strong_start}Multiple approval roles%{strong_end} — including code owners and required merge approvals"
-msgstr ""
+msgstr "%{strong_start}多个批准角色%{strong_end} — 包括代ç æ‰€æœ‰è€…和所需的åˆå¹¶æ‰¹å‡†"
msgid "InProductMarketing|%{strong_start}Overall, how difficult or easy was it to get started with GitLab?%{strong_end}"
-msgstr ""
+msgstr "%{strong_start}总体而言,开始使用 GitLab 的难易程度如何?%{strong_end}"
msgid "InProductMarketing|*GitLab*, noun: a synonym for efficient teams"
msgstr ""
msgid "InProductMarketing|...and you can get a free trial of GitLab Ultimate"
-msgstr ""
+msgstr "...您å¯ä»¥èŽ·å¾—旗舰版的å…费试用"
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
-msgstr ""
+msgstr "深入了解 GitLab CI/CD çš„ 3 ç§æ–¹æ³•"
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
-msgstr ""
+msgstr "实际上,GitLab 使团队能够工作更好"
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
-msgstr ""
+msgstr "æœ€åŽ %{deploy_link} 一个 Python 应用程åºã€‚"
msgid "InProductMarketing|Are your runners ready?"
-msgstr ""
+msgstr "您的Runner准备好了å—?"
msgid "InProductMarketing|Automated security scans directly within GitLab"
-msgstr ""
+msgstr "直接在 GitLab 中自动进行安全扫æ"
msgid "InProductMarketing|Be a DevOps hero"
-msgstr ""
+msgstr "æˆä¸ºDevOps英雄"
msgid "InProductMarketing|Beef up your security"
-msgstr ""
+msgstr "增强您的安全性"
msgid "InProductMarketing|Better code in less time"
-msgstr ""
+msgstr "用更少的时间编写更好的代ç "
msgid "InProductMarketing|Blog"
msgstr "åšå®¢"
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
-msgstr ""
+msgstr "通过å¯ç”¨ä»£ç æ‰€æœ‰è€…和所需的åˆå¹¶æ‰¹å‡†ï¼Œåˆé€‚的人将审查åˆé€‚çš„ MR。这是åŒèµ¢çš„:更干净的代ç å’Œæ›´æœ‰æ•ˆçš„审查过程。"
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
-msgstr ""
+msgstr "å•å‡»ä¸‹é¢ä¸Žæ‚¨çš„答案相对应的数字 - 1 表示éžå¸¸å›°éš¾ï¼Œ5 表示éžå¸¸å®¹æ˜“。"
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
-msgstr ""
+msgstr "代ç æ‰€æœ‰è€…和所需的åˆå¹¶æ‰¹å‡†æ˜¯ GitLab 付费版的一部分。您å¯ä»¥å¼€å§‹å…费试用 GitLab 旗舰版 30 天,并在 5 分钟内å¯ç”¨è¿™äº›åŠŸèƒ½ï¼Œæ— éœ€ä¿¡ç”¨å¡ã€‚"
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
-msgstr ""
+msgstr "åªéœ€å•å‡»å‡ ä¸‹å³å¯åˆ›å»ºè‡ªå®šä¹‰ CI Runner"
msgid "InProductMarketing|Create a custom runner"
-msgstr ""
+msgstr "创建自定义Runner"
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
-msgstr ""
+msgstr "在5分钟内在 GitLab 中创建一个项目"
msgid "InProductMarketing|Create your first project!"
-msgstr ""
+msgstr "创建您的第一个项目ï¼"
msgid "InProductMarketing|Deliver Better Products Faster"
-msgstr ""
+msgstr "更快地交付更好的产å“"
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
-msgstr ""
+msgstr "您知é“使用 GitLab 的团队效率更高å—?"
msgid "InProductMarketing|Difficult"
msgstr "å›°éš¾"
msgid "InProductMarketing|Dig in and create a project and a repo"
-msgstr ""
+msgstr "深入并创建一个项目和仓库"
msgid "InProductMarketing|Do you have a minute?"
-msgstr ""
+msgstr "有空å—?"
msgid "InProductMarketing|Easy"
-msgstr ""
+msgstr "简å•"
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
-msgstr ""
+msgstr "通过å…费的 GitLab 试用扩展您的 DevOps 之旅"
msgid "InProductMarketing|Explore GitLab CI/CD"
-msgstr ""
+msgstr "探索GitLab CI/CD"
msgid "InProductMarketing|Explore the options"
-msgstr ""
+msgstr "探索选项"
msgid "InProductMarketing|Explore the power of GitLab CI/CD"
-msgstr ""
+msgstr "探索 GitLab CI/CD 的力é‡"
msgid "InProductMarketing|Facebook"
-msgstr ""
+msgstr "Facebook"
msgid "InProductMarketing|Feedback from users like you really improves our product. Thanks for your help!"
-msgstr ""
+msgstr "æ¥è‡ªåƒæ‚¨è¿™æ ·çš„用户的å馈真正改善了我们的产å“,感谢您的帮助ï¼"
msgid "InProductMarketing|Feel the need for speed?"
-msgstr ""
+msgstr "感觉需è¦é€Ÿåº¦å—?"
msgid "InProductMarketing|Find out how your teams are really doing"
-msgstr ""
+msgstr "了解您的团队的实际情况"
msgid "InProductMarketing|Follow our steps"
-msgstr ""
+msgstr "è·Ÿéšæˆ‘们的步骤"
msgid "InProductMarketing|Free 30-day trial"
-msgstr ""
+msgstr "30 天å…费试用"
msgid "InProductMarketing|Get going with CI/CD quickly using our %{quick_start_link}. Start with an available runner and then create a CI .yml file – it's really that easy."
-msgstr ""
+msgstr "用我们的%{quick_start_link}快速开始使用 CI/CD。从一个å¯ç”¨çš„è¿è¡Œå™¨å¼€å§‹ï¼Œç„¶åŽåˆ›å»ºä¸€ä¸ª CI .yml 文件——这真的很容易。"
msgid "InProductMarketing|Get our import guides"
-msgstr ""
+msgstr "获å–导入指å—"
msgid "InProductMarketing|Get started today"
-msgstr ""
+msgstr "ç«‹å³å¼€å§‹"
msgid "InProductMarketing|Get started today with a 30-day GitLab Ultimate trial, no credit card required."
-msgstr ""
+msgstr "ç«‹å³å¼€å§‹ä¸ºæœŸ 30 天的 GitLab 旗舰版 试用,无需信用å¡ã€‚"
msgid "InProductMarketing|Get started with GitLab CI/CD"
-msgstr ""
+msgstr "开始使用 GitLab CI/CD"
msgid "InProductMarketing|Get to know GitLab CI/CD"
-msgstr ""
+msgstr "了解GitLab CI/CD"
msgid "InProductMarketing|Get your team set up on GitLab"
-msgstr ""
+msgstr "在 GitLab 上建立您的团队"
msgid "InProductMarketing|Git basics"
-msgstr ""
+msgstr "Git 基础知识"
msgid "InProductMarketing|GitHub Enterprise projects to GitLab"
-msgstr ""
+msgstr "GitHub ä¼ä¸šé¡¹ç›®åˆ° GitLab"
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
-msgstr ""
+msgstr "GitLab æä¾›é™æ€åº”用程åºå®‰å…¨æµ‹è¯•ï¼ˆSAST)ã€åŠ¨æ€åº”用程åºå®‰å…¨æµ‹è¯•ï¼ˆDAST)ã€å®¹å™¨æ‰«æå’Œä¾èµ–扫æ以帮助您æ供安全的应用程åºä»¥åŠéµå®ˆè®¸å¯å议。"
msgid "InProductMarketing|GitLab's CI/CD makes software development easier. Don't believe us? Here are three ways you can take it for a fast (and satisfying) test drive:"
-msgstr ""
+msgstr "GitLab çš„ CI/CD 使软件开å‘更容易。ä¸ç›¸ä¿¡æˆ‘们?您å¯ä»¥é€šè¿‡ä»¥ä¸‹ä¸‰ç§æ–¹å¼è¿›è¡Œå¿«é€Ÿï¼ˆä¸”令人满æ„)的测试驱动:"
msgid "InProductMarketing|GitLab's premium tiers are designed to make you, your team and your application more efficient and more secure with features including but not limited to:"
-msgstr ""
+msgstr "专业版是为了使您ã€æ‚¨çš„团队和您的应用程åºæ›´æœ‰æ•ˆçŽ‡å’Œæ›´å®‰å…¨è€Œè®¾è®¡ï¼Œå¹¶ä¸”包括但ä¸é™äºŽï¼š"
msgid "InProductMarketing|Give us one minute..."
-msgstr ""
+msgstr "给我们一分钟..."
msgid "InProductMarketing|Go farther with GitLab"
-msgstr ""
+msgstr "用 GitLab 走得更远"
msgid "InProductMarketing|Goldman Sachs went from 1 build every two weeks to thousands of builds a day"
-msgstr ""
+msgstr "Goldman Sachs 从æ¯ä¸¤å‘¨ä¸€æ¬¡æž„建到æ¯å¤©æ•°åƒæ¬¡æž„建"
msgid "InProductMarketing|Have a different instance you'd like to import? Here's our %{import_link}."
-msgstr ""
+msgstr "è¦å¯¼å…¥ä¸åŒçš„实例å—?这是我们的 %{import_link}。"
msgid "InProductMarketing|Here's what you need to know"
-msgstr ""
+msgstr "这是你需è¦çŸ¥é“çš„"
msgid "InProductMarketing|How (and why) mirroring makes sense"
-msgstr ""
+msgstr "é•œåƒå¦‚何(以åŠä¸ºä»€ä¹ˆï¼‰æœ‰æ„义"
msgid "InProductMarketing|How long does it take us to close issues/MRs by types like feature requests, bugs, tech debt, security?"
-msgstr ""
+msgstr "关闭功能请求ã€bugã€æŠ€æœ¯å€ºåŠ¡ã€å®‰å…¨æ€§ç­‰ç±»åž‹çš„议题/MR 需è¦å¤šé•¿æ—¶é—´ï¼Ÿ"
msgid "InProductMarketing|How many days does it take our team to complete various tasks?"
-msgstr ""
+msgstr "我们的团队完æˆå„ç§ä»»åŠ¡éœ€è¦å¤šå°‘天?"
msgid "InProductMarketing|How to build and test faster"
msgstr "如何更快地构建和测试"
msgid "InProductMarketing|If you don't want to receive marketing emails directly from GitLab, %{marketing_preference_link}."
-msgstr ""
+msgstr "如果您ä¸æƒ³ç›´æŽ¥æŽ¥æ”¶æˆ‘们的è¥é”€ç”µå­é‚®ä»¶ï¼Œåˆ™ %{marketing_preference_link}."
msgid "InProductMarketing|If you no longer wish to receive marketing emails from us,"
-msgstr ""
+msgstr "如果您ä¸å†å¸Œæœ›æ”¶åˆ°æˆ‘们的è¥é”€ç”µå­é‚®ä»¶ï¼Œ"
msgid "InProductMarketing|Import your project and code from GitHub, Bitbucket and others"
-msgstr ""
+msgstr "从 GitHubã€Bitbucket 等导入您的项目和代ç "
msgid "InProductMarketing|Improve app security with a 30-day trial"
-msgstr ""
+msgstr "通过 30 天试用æ高应用安全性"
msgid "InProductMarketing|Improve code quality and streamline reviews"
-msgstr ""
+msgstr "æ高代ç è´¨é‡å¹¶ç®€åŒ–审查"
msgid "InProductMarketing|Increase Operational Efficiencies"
-msgstr ""
+msgstr "æ高è¿è¥æ•ˆçŽ‡"
msgid "InProductMarketing|Invite your colleagues and start shipping code faster."
-msgstr ""
+msgstr "邀请您的åŒäº‹å¹¶å¼€å§‹æ›´å¿«åœ°å‘é€ä»£ç ã€‚"
msgid "InProductMarketing|Invite your colleagues to join in less than one minute"
-msgstr ""
+msgstr "ä¸åˆ°ä¸€åˆ†é’Ÿé‚€è¯·æ‚¨çš„åŒäº‹åŠ å…¥"
msgid "InProductMarketing|Invite your colleagues today"
-msgstr ""
+msgstr "ç«‹å³é‚€è¯·æ‚¨çš„åŒäº‹"
msgid "InProductMarketing|Invite your team in less than 60 seconds"
-msgstr ""
+msgstr "60 秒内邀请您的团队"
msgid "InProductMarketing|Invite your team now"
-msgstr ""
+msgstr "ç«‹å³é‚€è¯·æ‚¨çš„团队"
msgid "InProductMarketing|Invite your team today to build better code (and processes) together"
-msgstr ""
+msgstr "ç«‹å³é‚€è¯·æ‚¨çš„团队一起构建更好的代ç ï¼ˆå’Œæµç¨‹ï¼‰"
msgid "InProductMarketing|It's all in the stats"
-msgstr ""
+msgstr "一切尽在统计中"
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
-msgstr ""
+msgstr "在 20 分钟或更短的时间内å¯åŠ¨ GitLab CI/CD"
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
-msgstr ""
+msgstr "掌æ¡å¯¼å…¥çš„艺术ï¼"
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
-msgstr ""
+msgstr "继续轻æ¾åˆ›å»º Pages 网站 %{ci_template_link}"
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
-msgstr ""
+msgstr "多个所有者,混乱的工作æµï¼Ÿæˆ‘们已为您æä¾›ä¿éšœ"
msgid "InProductMarketing|Need an alternative to importing?"
-msgstr ""
+msgstr "需è¦æ›¿ä»£å¯¼å…¥çš„方法å—?"
msgid "InProductMarketing|Neutral"
-msgstr ""
+msgstr "中性"
msgid "InProductMarketing|No credit card required."
-msgstr ""
+msgstr "ä¸éœ€è¦ä¿¡ç”¨å¡ã€‚"
msgid "InProductMarketing|Our tool brings all the things together"
-msgstr ""
+msgstr "我们的工具将所有东西整åˆåœ¨ä¸€èµ·"
msgid "InProductMarketing|Rapid development, simplified"
-msgstr ""
+msgstr "快速开å‘,简化"
msgid "InProductMarketing|Reduce Security & Compliance Risk"
-msgstr ""
+msgstr "é™ä½Žå®‰å…¨ä¸Žåˆè§„风险"
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
-msgstr ""
+msgstr "集æˆåˆ°æ‚¨çš„å¼€å‘生命周期中的安全性"
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
-msgstr ""
+msgstr "在 GitLab 中å¯åŠ¨è‡ªåŠ¨ç¼©æ”¾Runner"
msgid "InProductMarketing|Start a GitLab Ultimate trial today in less than one minute, no credit card required."
msgstr ""
@@ -17097,13 +17229,13 @@ msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no CC requir
msgstr ""
msgid "InProductMarketing|Start a trial"
-msgstr ""
+msgstr "开始试用"
msgid "InProductMarketing|Start by %{performance_link}"
-msgstr ""
+msgstr "从%{performance_link}开始"
msgid "InProductMarketing|Start by importing your projects"
-msgstr ""
+msgstr "从导入您的项目开始"
msgid "InProductMarketing|Start with a GitLab Ultimate free trial"
msgstr ""
@@ -17172,13 +17304,13 @@ msgid "InProductMarketing|Turn coworkers into collaborators"
msgstr ""
msgid "InProductMarketing|Twitter"
-msgstr ""
+msgstr "Twitter"
msgid "InProductMarketing|Understand repository mirroring"
-msgstr ""
+msgstr "了解仓库镜åƒ"
msgid "InProductMarketing|Understand your project options"
-msgstr ""
+msgstr "了解您的项目选项"
msgid "InProductMarketing|Use GitLab CI/CD"
msgstr "使用 GitLab CI/CD"
@@ -17217,10 +17349,10 @@ msgid "InProductMarketing|Your teams can be more efficient"
msgstr "您的团队å¯ä»¥æ›´å…·æ•ˆçŽ‡"
msgid "InProductMarketing|comprehensive guide"
-msgstr ""
+msgstr "综åˆæŒ‡å—"
msgid "InProductMarketing|connect an external repository"
-msgstr ""
+msgstr "连接外部仓库"
msgid "InProductMarketing|create a project"
msgstr "创建一个项目"
@@ -17253,7 +17385,7 @@ msgid "InProductMarketing|unsubscribe"
msgstr "å–消订阅"
msgid "InProductMarketing|update your preferences"
-msgstr ""
+msgstr "更新您的å好"
msgid "InProductMarketing|using a CI/CD template"
msgstr "使用 CI/CD 模æ¿"
@@ -17262,7 +17394,7 @@ msgid "InProductMarketing|you may %{unsubscribe_link} at any time."
msgstr "您å¯ä»¥éšæ—¶%{unsubscribe_link}。"
msgid "Inactive"
-msgstr ""
+msgstr "未激活"
msgid "Incident"
msgstr "事件"
@@ -17271,7 +17403,7 @@ msgid "Incident Management Limits"
msgstr "事件管ç†é™åˆ¶"
msgid "Incident template (optional)."
-msgstr ""
+msgstr "事件模æ¿ï¼ˆå¯é€‰ï¼‰ã€‚"
msgid "IncidentManagement|%{hours} hours, %{minutes} minutes remaining"
msgstr "剩余%{hours}å°æ—¶%{minutes} 分钟"
@@ -17280,7 +17412,7 @@ msgid "IncidentManagement|%{minutes} minutes remaining"
msgstr "剩余%{minutes}分钟"
msgid "IncidentManagement|Achieved SLA"
-msgstr ""
+msgstr "已实现 SLA"
msgid "IncidentManagement|All"
msgstr "全部"
@@ -17322,7 +17454,7 @@ msgid "IncidentManagement|Medium - S3"
msgstr "中-S3"
msgid "IncidentManagement|Missed SLA"
-msgstr ""
+msgstr "已错过的SLA"
msgid "IncidentManagement|No incidents to display."
msgstr "没有è¦æ˜¾ç¤ºçš„事件。"
@@ -17361,7 +17493,7 @@ msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr "å¯ç”¨â€è·SLA时间â€å€’计时器"
msgid "IncidentSettings|Fine-tune incident settings and set up integrations with external tools to help better manage incidents."
-msgstr ""
+msgstr "微调事件设置并设置与外部工具的集æˆï¼Œä»¥å¸®åŠ©æ›´å¥½åœ°ç®¡ç†äº‹ä»¶ã€‚"
msgid "IncidentSettings|Grafana integration"
msgstr "Grafana集æˆ"
@@ -17373,7 +17505,7 @@ msgid "IncidentSettings|Incidents"
msgstr "事件"
msgid "IncidentSettings|Introduce a countdown timer in incident issues to better track Service Level Agreements (SLAs). The timer starts automatically when the incident is created, and sets a time limit for resolving the incident. When activated, the time to SLA countdown appears on all new incidents."
-msgstr ""
+msgstr "在事件议题中引入倒计时,以便更好地跟踪æœåŠ¡çº§åˆ«å议(SLA)。计时器在创建事件时自动å¯åŠ¨ï¼Œå¹¶è®¾ç½®è§£å†³äº‹ä»¶çš„时间é™åˆ¶ã€‚激活时,所有新事件都会显示SLA倒计时时间。"
msgid "IncidentSettings|PagerDuty integration"
msgstr "PagerDuty集æˆ"
@@ -17382,7 +17514,7 @@ msgid "IncidentSettings|Time limit"
msgstr "时间é™åˆ¶"
msgid "IncidentSettings|Time limit must be a multiple of 15 minutes."
-msgstr ""
+msgstr "时间é™åˆ¶å¿…须是15分钟的å€æ•°ã€‚"
msgid "IncidentSettings|Time limit must be a valid number."
msgstr "时间é™åˆ¶å¿…须是有效的数字。"
@@ -17391,7 +17523,7 @@ msgid "IncidentSettings|Time limit must be greater than 0."
msgstr "时间é™åˆ¶å¿…须大于 0。"
msgid "IncidentSettings|When activated, this applies to all new incidents in the project."
-msgstr ""
+msgstr "当激活åŽï¼Œè¿™é€‚用于项目中的所有新事件。"
msgid "IncidentSettings|hours"
msgstr "å°æ—¶"
@@ -17409,19 +17541,19 @@ msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to att
msgstr ""
msgid "Incidents|Must start with http or https"
-msgstr ""
+msgstr "必须以http或https开头"
msgid "Incidents|There was an issue deleting the image."
-msgstr ""
+msgstr "删除镜åƒæ—¶å‡ºçŽ°é—®é¢˜ã€‚"
msgid "Incidents|There was an issue loading metric images."
-msgstr ""
+msgstr "加载指标图片时出现问题。"
msgid "Incidents|There was an issue uploading your image."
-msgstr ""
+msgstr "上传您的镜åƒæ—¶å‡ºçŽ°é—®é¢˜ã€‚"
msgid "Incidents|You can optionally add a URL to link users to the original graph."
-msgstr ""
+msgstr "您å¯ä»¥é€‰æ‹©æ·»åŠ  URL 以将用户链接到原始图表。"
msgid "Incident|Alert details"
msgstr "警报详情"
@@ -17433,7 +17565,7 @@ msgid "Incident|Deleting %{filename}"
msgstr "删除%{filename}"
msgid "Incident|Metrics"
-msgstr ""
+msgstr "指标"
msgid "Incident|Summary"
msgstr "摘è¦"
@@ -17454,7 +17586,7 @@ msgid "Include merge request description"
msgstr "包å«åˆå¹¶è¯·æ±‚æè¿°"
msgid "Include new features from all tiers."
-msgstr ""
+msgstr "包å«æ‰€æœ‰çº§åˆ«çš„新功能。"
msgid "Include the name of the author of the issue, merge request or comment in the email body. By default, GitLab overrides the email sender's name. Some email servers don't support that option."
msgstr ""
@@ -17466,7 +17598,7 @@ msgid "Includes LFS objects. It can be overridden per group, or per project. 0 f
msgstr "åŒ…å« LFS 对象。它å¯ä»¥æŒ‰ç¾¤ç»„或项目覆盖。 0 表示无é™åˆ¶ã€‚"
msgid "Includes an MVC structure to help you get started"
-msgstr ""
+msgstr "åŒ…å« MVC 结构以帮助您入门"
msgid "Includes an MVC structure, Gemfile, Rakefile, along with many others, to help you get started"
msgstr ""
@@ -17496,7 +17628,7 @@ msgid "Indent"
msgstr "缩进"
msgid "Index"
-msgstr ""
+msgstr "索引"
msgid "Index all projects"
msgstr "索引所有项目"
@@ -17514,25 +17646,25 @@ msgid "Infrastructure"
msgstr "基础设施"
msgid "Infrastructure Registry"
-msgstr ""
+msgstr "基础设施库"
msgid "InfrastructureRegistry|Copy Terraform Command"
-msgstr ""
+msgstr "å¤åˆ¶ Terraform 命令"
msgid "InfrastructureRegistry|Copy Terraform Setup Command"
-msgstr ""
+msgstr "å¤åˆ¶ Terraform 设置命令"
msgid "InfrastructureRegistry|Copy and paste into your Terraform configuration, insert the variables, and run Terraform init:"
-msgstr ""
+msgstr "å¤åˆ¶å¹¶ç²˜è´´åˆ°æ‚¨çš„ Terraform é…置中,æ’å…¥å˜é‡ï¼Œç„¶åŽè¿è¡Œ Terraform init:"
msgid "InfrastructureRegistry|For more information on the Terraform registry, %{linkStart}see our documentation%{linkEnd}."
-msgstr ""
+msgstr "有关Terraform库的信æ¯ï¼Œ%{linkStart}å‚è§æˆ‘们的文档%{linkEnd}。"
msgid "InfrastructureRegistry|Infrastructure Registry"
-msgstr ""
+msgstr "基础设施库"
msgid "InfrastructureRegistry|Publish and share your modules. %{docLinkStart}More information%{docLinkEnd}"
-msgstr ""
+msgstr "å‘布和共享您的模å—。 %{docLinkStart}更多信æ¯%{docLinkEnd}"
msgid "InfrastructureRegistry|Terraform"
msgstr "Terraform"
@@ -17541,10 +17673,10 @@ msgid "InfrastructureRegistry|Terraform modules are the main way to package and
msgstr "Terraform 模å—是使用 Terraform 打包和é‡ç”¨èµ„æºé…置的主è¦æ–¹å¼ã€‚了解有关如何在 GitLab 中 %{noPackagesLinkStart}创建 Terraform 模å—%{noPackagesLinkEnd}。"
msgid "InfrastructureRegistry|To authorize access to the Terraform registry:"
-msgstr ""
+msgstr "è¦æŽˆæƒè®¿é—®Terraform库:"
msgid "InfrastructureRegistry|You have no Terraform modules in your project"
-msgstr ""
+msgstr "您的项目中没有 Terraform 模å—"
msgid "Inherited"
msgstr "已继承"
@@ -17559,13 +17691,13 @@ msgid "Input host keys manually"
msgstr "手动输入主机密钥"
msgid "Input the remote repository URL"
-msgstr ""
+msgstr "输入远端仓库URL"
msgid "Insert"
-msgstr ""
+msgstr "æ’å…¥"
msgid "Insert a %{rows}x%{cols} table."
-msgstr ""
+msgstr "æ’å…¥ %{rows}x%{cols} 的表格。"
msgid "Insert a code block"
msgstr "æ’入代ç å—"
@@ -17582,6 +17714,12 @@ msgstr "æ’入图片"
msgid "Insert code"
msgstr "æ’入代ç "
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr "æ’入图片"
@@ -17591,6 +17729,12 @@ msgstr "æ’入内è”代ç "
msgid "Insert link"
msgstr "æ’入链接"
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr "æ’入建议"
@@ -17653,7 +17797,7 @@ msgid "Integrations"
msgstr "集æˆ"
msgid "Integrations|%{integrationTitle}: active"
-msgstr ""
+msgstr "%{integrationTitle}:激活"
msgid "Integrations|%{integration} settings saved and active."
msgstr "%{integration}设置已ä¿å­˜å¹¶å¯ç”¨ã€‚"
@@ -17671,7 +17815,7 @@ msgid "Integrations|Add namespace"
msgstr "添加命å空间"
msgid "Integrations|Adding a namespace works only in browsers that allow cross‑site cookies. Use %{firefox_link_start}Firefox%{link_end}, %{chrome_link_start}Google Chrome%{link_end}, or enable cross‑site cookies in your browser, when adding a namespace."
-msgstr ""
+msgstr "添加命å空间仅适用于å…许跨站点 cookie çš„æµè§ˆå™¨ã€‚添加命å空间时,请使用 %{firefox_link_start}Firefox%{link_end} %{chrome_link_start}Google Chrome%{link_end},或在æµè§ˆå™¨ä¸­å¯ç”¨è·¨ç«™ç‚¹ cookie。"
msgid "Integrations|All details"
msgstr "所有详细信æ¯"
@@ -17679,6 +17823,9 @@ msgstr "所有详细信æ¯"
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr "继承这些设置的所有项目也将被é‡ç½®ã€‚"
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr "æµè§ˆå™¨é™åˆ¶"
@@ -17719,28 +17866,28 @@ msgid "Integrations|Failed to unlink namespace. Please try again."
msgstr "无法å–消链接命å空间,请é‡è¯•ã€‚"
msgid "Integrations|GitLab administrators can set up integrations that all groups and projects inherit and use by default. These integrations apply to all groups and projects that don't already use custom settings. You can override custom settings for a group or project if the settings are necessary at that level. Learn more about %{integrations_link_start}instance-level integration management%{link_end}."
-msgstr ""
+msgstr "GitLab 管ç†å‘˜å¯ä»¥è®¾ç½®æ‰€æœ‰ç¾¤ç»„和项目默认继承和使用的集æˆï¼Œ 这些集æˆåº”用于所有尚未使用自定义设置的组和项目, 如果需è¦è®¾ç½®ï¼Œæ‚¨å¯ä»¥è¦†ç›–一个组或项目的自定义设置。 了解更多关于 %{integrations_link_start}实例级集æˆç®¡ç†%{link_end}。"
msgid "Integrations|GitLab administrators can set up integrations that all projects in a group inherit and use by default. These integrations apply to all projects that don't already use custom settings. You can override custom settings for a project if the settings are necessary at that level. Learn more about %{integrations_link_start}group-level integration management%{link_end}."
-msgstr ""
+msgstr "GitLab 管ç†å‘˜å¯ä»¥è®¾ç½®ä¸€ä¸ªç¾¤ç»„中所有项目默认继承和使用的集æˆï¼Œè¿™äº›é›†æˆåº”用于所有尚未使用自定义设置的项目, 如果项目需è¦è®¾ç½®ï¼Œæ‚¨å¯ä»¥è¦†ç›–自定义设置。 了解更多关于 %{integrations_link_start}群组级集æˆç®¡ç†%{link_end}。"
msgid "Integrations|Group-level integration management"
-msgstr ""
+msgstr "群组级集æˆç®¡ç†"
msgid "Integrations|Includes Standard, plus the entire commit message, commit hash, and issue IDs"
msgstr ""
msgid "Integrations|Includes commit title and branch."
-msgstr ""
+msgstr "包括æ交标题和分支。"
msgid "Integrations|Instance-level integration management"
-msgstr ""
+msgstr "实例级集æˆç®¡ç†"
msgid "Integrations|Issues created in Jira are shown here once you have created the issues in project setup in Jira."
msgstr "当议题在Jira中设定的项目中创建åŽï¼ŒJira中创建的议题会显示于此。"
msgid "Integrations|Keep your PHP dependencies updated on Packagist."
-msgstr ""
+msgstr "在 Packagist 上更新您的 PHP ä¾èµ–项。"
msgid "Integrations|Link namespaces"
msgstr "链接命å空间"
@@ -17752,7 +17899,7 @@ msgid "Integrations|Namespace successfully linked"
msgstr "命å空间链接æˆåŠŸ"
msgid "Integrations|Namespaces are the GitLab groups and subgroups you link to this Jira instance."
-msgstr ""
+msgstr "命å空间是您链接到此 Jira 实例的 GitLab 群组和å­ç¾¤ç»„。"
msgid "Integrations|No available namespaces."
msgstr "没有å¯ç”¨çš„命å空间。"
@@ -17764,7 +17911,7 @@ msgid "Integrations|Note: this integration only works with accounts on GitLab.co
msgstr ""
msgid "Integrations|Projects using custom settings"
-msgstr ""
+msgstr "使用自定义设置的项目"
msgid "Integrations|Projects using custom settings will not be affected."
msgstr "使用自定义设置的项目ä¸ä¼šå—到影å“。"
@@ -17791,7 +17938,7 @@ msgid "Integrations|Search Jira issues"
msgstr "æœç´¢Jira议题"
msgid "Integrations|Send notifications about project events to Unify Circuit."
-msgstr ""
+msgstr "将有关项目事件的通知å‘é€åˆ° Unify Circuit。"
msgid "Integrations|Sign in to add namespaces"
msgstr "登录以添加命å空间"
@@ -17799,6 +17946,9 @@ msgstr "登录以添加命å空间"
msgid "Integrations|Standard"
msgstr "标准"
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr "此集æˆå’Œç»§æ‰¿é¡¹ç›®å·²è¢«é‡ç½®ã€‚"
@@ -17812,22 +17962,22 @@ msgid "Integrations|Use default settings"
msgstr "使用默认设置"
msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
+msgstr "当您在æ交或åˆå¹¶è¯·æ±‚中æåŠ Jira 议题时,GitLab 会创建一个远程链接和评论(如果å¯ç”¨ï¼‰ã€‚"
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr "您现在å¯ä»¥å…³é—­æ­¤çª—å£å¹¶è¿”回GitLab for Jira应用。"
msgid "Integrations|You haven't activated any integrations yet."
-msgstr ""
+msgstr "您尚未激活任何集æˆã€‚"
msgid "Integrations|You must have owner or maintainer permissions to link namespaces."
-msgstr ""
+msgstr "您必须拥有所有者或维护者æƒé™æ‰èƒ½é“¾æŽ¥å‘½å空间。"
msgid "Integrations|You should now see GitLab.com activity inside your Jira Cloud issues. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "Integrations|You've activated every integration 🎉"
-msgstr ""
+msgstr "æ‚¨å·²æ¿€æ´»æ‰€æœ‰é›†æˆ ðŸŽ‰"
msgid "Interactive mode"
msgstr "交互模å¼"
@@ -17923,7 +18073,7 @@ msgid "Invalid pod_name"
msgstr "无效的pod_name"
msgid "Invalid policy type"
-msgstr ""
+msgstr "无效的策略类型"
msgid "Invalid query"
msgstr "无效的查询"
@@ -17974,10 +18124,10 @@ msgid "Invite Members"
msgstr "邀请æˆå‘˜"
msgid "Invite a group"
-msgstr ""
+msgstr "邀请群组"
msgid "Invite email has already been taken"
-msgstr ""
+msgstr "邀请邮件已被使用"
msgid "Invite group"
msgstr "邀请群组"
@@ -17988,9 +18138,6 @@ msgstr "邀请æˆå‘˜"
msgid "Invite members"
msgstr "邀请æˆå‘˜"
-msgid "Invite your team"
-msgstr "邀请您的团队"
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr "%{inviter}邀请您作为%{role}加入%{project_or_group_name}%{project_or_group}"
@@ -17998,25 +18145,25 @@ msgid "InviteEmail|%{inviter} invited you to join the %{strong_start}%{project_o
msgstr "%{inviter}邀请您作为%{role}加入%{strong_start}%{project_or_group_name}%{strong_end}%{project_or_group}%{br_tag}"
msgid "InviteEmail|%{project_or_group} details"
-msgstr ""
+msgstr "%{project_or_group} 详情"
msgid "InviteEmail|Groups assemble related projects together and grant members access to several projects at once."
-msgstr ""
+msgstr "群组汇集相关项目并åŒæ—¶æŽˆäºˆæˆå‘˜å¯¹è‹¥å¹²é¡¹ç›®çš„访问æƒé™ã€‚"
msgid "InviteEmail|Join now"
msgstr "ç«‹å³åŠ å…¥"
msgid "InviteEmail|Join your team on GitLab! %{inviter} invited you to %{project_or_group_name}"
-msgstr ""
+msgstr "加入您的 GitLab å›¢é˜Ÿï¼ %{inviter} 邀请您加入 %{project_or_group_name}"
msgid "InviteEmail|Join your team on GitLab! You are invited to %{project_or_group_name}"
-msgstr ""
+msgstr "加入您的 GitLab 团队ï¼æ‚¨è¢«é‚€è¯·åŠ å…¥ %{project_or_group_name}"
msgid "InviteEmail|Projects are used to host and collaborate on code, track issues, and continuously build, test, and deploy your app with built-in GitLab CI/CD."
-msgstr ""
+msgstr "项目用于托管和å作代ç ï¼Œè·Ÿè¸ªè®®é¢˜ï¼Œä»¥åŠä½¿ç”¨å†…置的GitLab CI/CDæŒç»­æž„建ã€æµ‹è¯•å’Œéƒ¨ç½²æ‚¨çš„应用程åºã€‚"
msgid "InviteEmail|What's it about?"
-msgstr ""
+msgstr "这是什么?"
msgid "InviteEmail|You are invited to join the %{strong_start}%{project_or_group_name}%{strong_end}%{br_tag}%{project_or_group} as a %{role}"
msgstr "您被邀请以%{role}身份加入%{strong_start}%{project_or_group_name}%{strong_end}%{project_or_group}%{br_tag}"
@@ -18034,7 +18181,7 @@ msgid "InviteMembersBanner|We noticed that you haven't invited anyone to this gr
msgstr "ç›®å‰æ‚¨è¿˜æ²¡æœ‰é‚€è¯·ä»»ä½•äººåŠ å…¥è¿™ä¸ªç¾¤ç»„。 您å¯ä»¥é‚€è¯·æ‚¨çš„åŒäº‹åˆ°ç¾¤ç»„ç§ï¼Œä»¥æ–¹ä¾¿è®¨è®ºé—®é¢˜ï¼Œåœ¨åˆå¹¶è¯·æ±‚中进行å作,以åŠåˆ†äº«æ‚¨çš„知识。"
msgid "InviteMembersModal|%{linkStart}Read more%{linkEnd} about role permissions"
-msgstr ""
+msgstr "%{linkStart}了解更多%{linkEnd}关于角色æƒé™çš„ä¿¡æ¯"
msgid "InviteMembersModal|Access expiration date (optional)"
msgstr "访问到期日期(å¯é€‰)"
@@ -18046,67 +18193,67 @@ msgid "InviteMembersModal|Close invite team members"
msgstr "关闭邀请团队æˆå‘˜"
msgid "InviteMembersModal|Collaborate on open issues and merge requests"
-msgstr ""
+msgstr "在未解决的议题和åˆå¹¶è¯·æ±‚上进行å作"
msgid "InviteMembersModal|Configure CI/CD"
-msgstr ""
+msgstr "é…ç½® CI/CD"
msgid "InviteMembersModal|Configure security features"
-msgstr ""
+msgstr "é…置安全功能"
msgid "InviteMembersModal|Contribute to the codebase"
-msgstr ""
+msgstr "为代ç åº“贡献"
msgid "InviteMembersModal|GitLab member or email address"
-msgstr ""
+msgstr "GitLab用户或电å­é‚®ä»¶åœ°å€"
msgid "InviteMembersModal|Invite"
msgstr "邀请"
msgid "InviteMembersModal|Invite a group"
-msgstr ""
+msgstr "邀请群组"
msgid "InviteMembersModal|Invite members"
-msgstr ""
+msgstr "邀请æˆå‘˜"
msgid "InviteMembersModal|Members were successfully added"
msgstr "æˆå‘˜å·²æˆåŠŸæ·»åŠ "
msgid "InviteMembersModal|Other"
-msgstr ""
+msgstr "其它"
msgid "InviteMembersModal|Search for a group to invite"
-msgstr ""
+msgstr "æœç´¢è¦é‚€è¯·çš„群组"
msgid "InviteMembersModal|Select a group to invite"
-msgstr ""
+msgstr "选择è¦é‚€è¯·çš„群组"
msgid "InviteMembersModal|Select a role"
msgstr "选择角色"
msgid "InviteMembersModal|Select members or type email addresses"
-msgstr ""
+msgstr "选择æˆå‘˜æˆ–输入电å­é‚®ä»¶åœ°å€"
msgid "InviteMembersModal|Something went wrong"
-msgstr ""
+msgstr "出现错误"
msgid "InviteMembersModal|What would you like new member(s) to focus on? (optional)"
-msgstr ""
+msgstr "您希望新æˆå‘˜å…³æ³¨ä»€ä¹ˆï¼Ÿï¼ˆå¯é€‰ï¼‰"
msgid "InviteMembersModal|You're inviting a group to the %{strongStart}%{name}%{strongEnd} group."
-msgstr ""
+msgstr "您正在邀请一个群组加入 %{strongStart}%{name}%{strongEnd} 群组。"
msgid "InviteMembersModal|You're inviting a group to the %{strongStart}%{name}%{strongEnd} project."
-msgstr ""
+msgstr "您正在邀请一个å°ç»„加入 %{strongStart}%{name}%{strongEnd} 项目。"
msgid "InviteMembersModal|You're inviting members to the %{strongStart}%{name}%{strongEnd} group."
-msgstr ""
+msgstr "您正在邀请æˆå‘˜åŠ å…¥ %{strongStart}%{name}%{strongEnd} 群组。"
msgid "InviteMembersModal|You're inviting members to the %{strongStart}%{name}%{strongEnd} project."
-msgstr ""
+msgstr "您正在邀请æˆå‘˜åŠ å…¥ %{strongStart}%{name}%{strongEnd} 项目。"
msgid "InviteMembers|Invite a group"
-msgstr ""
+msgstr "邀请群组"
msgid "InviteMembers|Invite team members"
msgstr "邀请团队æˆå‘˜"
@@ -18169,7 +18316,7 @@ msgid "InviteReminderEmail|Invitation pending"
msgstr "邀请等待中"
msgid "InviteReminderEmail|It's been %{invitation_age} days since %{inviter} invited you to join the %{strong_start}%{project_or_group_name}%{strong_end} %{project_or_group} as a %{role}. What would you like to do?"
-msgstr "è·%{inviter}邀请您作为%{role}加%{strong_start}%{project_or_group_name}%{strong_end}%{project_or_group}}已有%{invitation_age}天。您有什么计划å—?"
+msgstr "è·%{inviter}邀请您作为%{role}加入%{strong_start}%{project_or_group_name}%{strong_end}%{project_or_group}已有%{invitation_age}天。您有什么计划å—?"
msgid "InviteReminderEmail|This is a friendly reminder that %{inviter} invited you to join the %{strong_start}%{project_or_group_name}%{strong_end} %{project_or_group} as a %{role}."
msgstr "这是一个å‹æƒ…æ醒。%{inviter}邀请您作为%{role}加入%{strong_start}%{project_or_group_name}%{strong_end} %{project_or_group}。"
@@ -18181,40 +18328,40 @@ msgid "Invocations"
msgstr "调用"
msgid "IrkerService|Channels and users separated by whitespaces. %{recipients_docs_link}"
-msgstr ""
+msgstr "用空格分隔的频é“和用户。 %{recipients_docs_link}"
msgid "IrkerService|Default IRC URI (optional)"
-msgstr ""
+msgstr "默认 IRC URI (å¯é€‰)"
msgid "IrkerService|How to enter channels or users?"
-msgstr ""
+msgstr "如何输入频é“或用户?"
msgid "IrkerService|Recipients"
-msgstr ""
+msgstr "收件人"
msgid "IrkerService|Send update messages to an irker server."
-msgstr ""
+msgstr "å‘ irker æœåŠ¡å™¨å‘é€æ›´æ–°æ¶ˆæ¯ã€‚"
msgid "IrkerService|Send update messages to an irker server. Before you can use this, you need to set up the irker daemon. %{docs_link}"
-msgstr ""
+msgstr "å‘ irker æœåŠ¡å™¨å‘é€æ›´æ–°æ¶ˆæ¯ã€‚在使用它之å‰ï¼Œæ‚¨éœ€è¦è®¾ç½® irker 守护进程。 %{docs_link}"
msgid "IrkerService|Server host (optional)"
-msgstr ""
+msgstr "æœåŠ¡å™¨ä¸»æœºï¼ˆå¯é€‰ï¼‰"
msgid "IrkerService|Server port (optional)"
-msgstr ""
+msgstr "æœåŠ¡å™¨ç«¯å£(å¯é€‰)"
msgid "IrkerService|URI to add before each recipient."
-msgstr ""
+msgstr "è¦åœ¨æ¯ä¸ªæ”¶ä»¶äººä¹‹å‰æ·»åŠ çš„ URI。"
msgid "IrkerService|irker (IRC gateway)"
-msgstr ""
+msgstr "irker (IRC网关)"
msgid "IrkerService|irker daemon hostname (defaults to localhost)."
-msgstr ""
+msgstr "irker 守护进程主机å(默认为 localhost)。"
msgid "IrkerService|irker daemon port (defaults to 6659)."
-msgstr ""
+msgstr "irker 守护进程端å£ï¼ˆé»˜è®¤ä¸º 6659)。"
msgid "Is blocked by"
msgstr "已被阻止。阻止项为"
@@ -18268,7 +18415,7 @@ msgid "Issue created from vulnerability %{vulnerability_link}"
msgstr "从æ¼æ´ž %{vulnerability_link}创建的议题"
msgid "Issue creation requests"
-msgstr ""
+msgstr "议题创建请求"
msgid "Issue details"
msgstr "议题详情"
@@ -18283,7 +18430,7 @@ msgid "Issue label"
msgstr "议题标记"
msgid "Issue or merge request ID is required"
-msgstr ""
+msgstr "问题或åˆå¹¶è¯·æ±‚ ID 是必需的"
msgid "Issue published on status page."
msgstr "议题å‘布在状æ€é¡µé¢ä¸Šã€‚"
@@ -18361,22 +18508,22 @@ msgid "IssueTracker|Issue URL"
msgstr "议题 URL"
msgid "IssueTracker|New issue URL"
-msgstr ""
+msgstr "新建议题URL"
msgid "IssueTracker|The URL to create an issue in the external issue tracker."
-msgstr ""
+msgstr "在外部议题跟踪器中创建议题的 URL。"
msgid "IssueTracker|The URL to the project in YouTrack."
-msgstr ""
+msgstr "YouTrack 中项目的 URL。"
msgid "IssueTracker|The URL to the project in the external issue tracker."
-msgstr ""
+msgstr "外部议题跟踪器中项目的 URL。"
msgid "IssueTracker|The URL to view an issue in the YouTrack project. Must contain %{colon_id}."
-msgstr ""
+msgstr "用于查看 YouTrack 项目中议题的 URLã€‚å¿…é¡»åŒ…å« %{colon_id}。"
msgid "IssueTracker|The URL to view an issue in the external issue tracker. Must contain %{colon_id}."
-msgstr ""
+msgstr "在外部议题跟踪器中查看议题的 URLã€‚å¿…é¡»åŒ…å« %{colon_id}。"
msgid "IssueTracker|Use Bugzilla as this project's issue tracker."
msgstr "使用 Bugzilla 作为该项目的议题追踪器。"
@@ -18424,10 +18571,10 @@ msgid "Issues closed"
msgstr "关闭议题"
msgid "Issues manual ordering is temporarily disabled for technical reasons."
-msgstr ""
+msgstr "由于技术原因暂时ç¦ç”¨æ‰‹åŠ¨è®¢é˜…议题。"
msgid "Issues must match this scope to appear in this list."
-msgstr ""
+msgstr "议题必须与此范围匹é…æ‰èƒ½å‡ºçŽ°åœ¨æ­¤åˆ—表中。"
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr "议题评论,åˆå¹¶è¯·æ±‚的差异和评论,标记,里程碑,代ç ç‰‡æ®µå’Œå…¶ä»–项目实体"
@@ -18472,7 +18619,7 @@ msgid "Issue|Title"
msgstr "标题"
msgid "It is not possible to %{action} files that are stored in LFS using the web interface"
-msgstr ""
+msgstr "无法使用 Web ç•Œé¢ %{action} 存储在 LFS 中的文件"
msgid "It looks like you have some draft commits in this branch."
msgstr "看起æ¥ä½ åœ¨è¿™ä¸ªåˆ†æ”¯ä¸Šæœ‰ä¸€äº›è‰ç¨¿æ交。"
@@ -18514,79 +18661,82 @@ msgid "Iterations"
msgstr "迭代"
msgid "Iterations|Add iteration"
-msgstr ""
+msgstr "添加迭代"
msgid "Iterations|Automated scheduling"
-msgstr ""
+msgstr "自动调度计划"
msgid "Iterations|Cadence name"
-msgstr ""
+msgstr "周期å称"
msgid "Iterations|Couldn't find iteration cadence"
-msgstr ""
+msgstr "找ä¸åˆ°è¿­ä»£å‘¨æœŸ"
msgid "Iterations|Create cadence"
+msgstr "创建周期"
+
+msgid "Iterations|Create your first iteration"
msgstr ""
msgid "Iterations|Delete cadence"
-msgstr ""
+msgstr "删除周期"
msgid "Iterations|Delete iteration cadence?"
-msgstr ""
+msgstr "删除迭代周期?"
msgid "Iterations|Duration"
msgstr "时长"
msgid "Iterations|Edit cadence"
-msgstr ""
+msgstr "编辑周期"
msgid "Iterations|Edit iteration"
-msgstr ""
+msgstr "编辑迭代"
msgid "Iterations|Edit iteration cadence"
-msgstr ""
+msgstr "编辑迭代周期"
msgid "Iterations|Error loading iteration cadences."
-msgstr ""
+msgstr "加载迭代周期时出错。"
msgid "Iterations|Future iterations"
-msgstr ""
+msgstr "未æ¥è¿­ä»£"
msgid "Iterations|Iteration cadences"
-msgstr ""
+msgstr "迭代周期"
msgid "Iterations|Iteration scheduling will be handled automatically"
-msgstr ""
+msgstr "迭代调度会自动处ç†"
msgid "Iterations|Move incomplete issues to the next iteration"
-msgstr ""
+msgstr "将未完æˆçš„议题移至下一次迭代"
msgid "Iterations|New iteration"
-msgstr ""
+msgstr "新建迭代"
msgid "Iterations|New iteration cadence"
-msgstr ""
+msgstr "新建迭代周期"
msgid "Iterations|No iteration cadences to show."
-msgstr ""
+msgstr "没有è¦æ˜¾ç¤ºçš„迭代周期。"
msgid "Iterations|No iterations in cadence."
-msgstr ""
+msgstr "周期中没有迭代。"
msgid "Iterations|Number of future iterations you would like to have scheduled"
-msgstr ""
+msgstr "您希望安排的未æ¥è¿­ä»£æ¬¡æ•°"
msgid "Iterations|Roll over issues"
-msgstr ""
+msgstr "滚动议题"
msgid "Iterations|Save cadence"
-msgstr ""
+msgstr "ä¿å­˜å‘¨æœŸ"
msgid "Iterations|Select duration"
-msgstr ""
+msgstr "选择æŒç»­æ—¶é—´"
msgid "Iterations|Select number"
-msgstr ""
+msgstr "选择数é‡"
msgid "Iterations|Select start date"
msgstr "选择开始日期"
@@ -18595,25 +18745,25 @@ msgid "Iterations|Start date"
msgstr "开始日期"
msgid "Iterations|The duration for each iteration (in weeks)"
-msgstr ""
+msgstr "æ¯æ¬¡è¿­ä»£çš„æŒç»­æ—¶é—´ï¼ˆä»¥å‘¨ä¸ºå•ä½ï¼‰"
msgid "Iterations|The start date of your first iteration"
-msgstr ""
+msgstr "第一次迭代的开始日期"
msgid "Iterations|This will delete the cadence as well as all of the iterations within it."
-msgstr ""
+msgstr "这将删除周期以åŠå…¶ä¸­çš„所有迭代。"
msgid "Iterations|Title"
-msgstr ""
+msgstr "标题"
msgid "Iterations|Unable to find iteration."
-msgstr ""
+msgstr "无法找到迭代。"
msgid "Iteration|Dates cannot overlap with other existing Iterations within this group"
-msgstr ""
+msgstr "日期ä¸èƒ½ä¸Žè¯¥ç¾¤ç»„内的其它现有迭代é‡å "
msgid "Iteration|Dates cannot overlap with other existing Iterations within this iterations cadence"
-msgstr ""
+msgstr "日期ä¸èƒ½ä¸Žæ­¤è¿­ä»£å‘¨æœŸå†…的其他现有迭代é‡å "
msgid "Iteration|cannot be more than 500 years in the future"
msgstr "ä¸èƒ½è¶…过未æ¥çš„500å¹´"
@@ -18622,7 +18772,7 @@ msgid "I’m familiar with the basics of DevOps."
msgstr "我熟悉Devops的基本知识。"
msgid "I’m joining my team who’s already on GitLab"
-msgstr ""
+msgstr "我è¦åŠ å…¥æˆ‘å·²ç»åœ¨ GitLab 上的团队"
msgid "I’m not familiar with the basics of DevOps."
msgstr "我ä¸ç†Ÿæ‚‰Devops的基本知识。"
@@ -18652,7 +18802,7 @@ msgid "Jira integration not configured."
msgstr "未é…ç½®Jira集æˆã€‚"
msgid "Jira project key is not configured."
-msgstr ""
+msgstr "未é…ç½® Jira 项目密钥。"
msgid "Jira project: %{importProject}"
msgstr "Jira项目: %{importProject}"
@@ -18661,7 +18811,7 @@ msgid "Jira service not configured."
msgstr "未é…ç½®JiraæœåŠ¡ã€‚"
msgid "Jira user"
-msgstr ""
+msgstr "Jira用户"
msgid "Jira users have been imported from the configured Jira instance. They can be mapped by selecting a GitLab user from the dropdown in the \"GitLab username\" column. When the form appears, the dropdown defaults to the user conducting the import."
msgstr "已从é…置的Jira实例中导入了Jira用户。å¯ä»¥é€šè¿‡ä»Žâ€œ GitLab用户åâ€åˆ—的下拉列表中选择一个GitLab用户æ¥æ˜ å°„它们。当表å•å‡ºçŽ°æ—¶ï¼Œä¸‹æ‹‰èœå•é»˜è®¤ä¸ºæ‰§è¡Œå¯¼å…¥çš„用户。"
@@ -18670,49 +18820,49 @@ msgid "Jira-GitLab user mapping template"
msgstr "Jira-GitLab用户映射模æ¿"
msgid "JiraConnect|Create branch for Jira issue %{jiraIssue}"
-msgstr ""
+msgstr "为Jira议题%{jiraIssue}创建分支"
msgid "JiraConnect|Failed to create branch."
-msgstr ""
+msgstr "创建分支失败。"
msgid "JiraConnect|Failed to create branch. Please try again."
-msgstr ""
+msgstr "创建分支失败。请é‡è¯•ã€‚"
msgid "JiraConnect|New branch was successfully created."
-msgstr ""
+msgstr "æˆåŠŸåˆ›å»ºæ–°åˆ†æ”¯ã€‚"
msgid "JiraConnect|You can now close this window and return to Jira."
-msgstr ""
+msgstr "您现在å¯ä»¥å…³é—­æ­¤çª—å£å¹¶è¿”回Jira。"
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
-msgstr ""
+msgstr "连接到 Jira æ—¶å‘生连接错误。请您å†æ¬¡å°è¯•è¯·æ±‚。"
msgid "JiraRequest|A timeout error occurred while connecting to Jira. Try your request again."
-msgstr ""
+msgstr "连接到 Jira æ—¶å‘生超时错误。请您å†æ¬¡å°è¯•è¯·æ±‚。"
msgid "JiraRequest|An SSL error occurred while connecting to Jira: %{message}. Try your request again."
-msgstr ""
+msgstr "连接到 Jira æ—¶å‘生 SSL 错误: %{message}。å†æ¬¡å°è¯•æ‚¨çš„请求。"
msgid "JiraRequest|An error occurred while requesting data from Jira. Check your Jira integration configuration and try again."
-msgstr ""
+msgstr "从 Jira 请求数æ®æ—¶å‡ºé”™ã€‚检查您的 Jira 集æˆé…置并é‡è¯•ã€‚"
msgid "JiraRequest|An error occurred while requesting data from Jira: %{messages}. Check your Jira integration configuration and try again."
-msgstr ""
+msgstr "从 Jira 请求数æ®æ—¶å‡ºé”™ï¼š%{messages}。检查您的 Jira 集æˆé…置并é‡è¯•ã€‚"
msgid "JiraRequest|The Jira API URL for connecting to Jira is not valid. Check your Jira integration API URL and try again."
-msgstr ""
+msgstr "用于连接到 Jira çš„ Jira API URL 无效。检查您的 Jira é›†æˆ API URL,然åŽé‡è¯•ã€‚"
msgid "JiraRequest|The credentials for accessing Jira are not allowed to access the data. Check your Jira integration credentials and try again."
-msgstr ""
+msgstr "访问Jira的凭æ®ä¸å…许访问数æ®ã€‚检查您的Jira集æˆå‡­æ®ï¼Œç„¶åŽé‡è¯•ã€‚"
msgid "JiraRequest|The credentials for accessing Jira are not valid. Check your Jira integration credentials and try again."
-msgstr ""
+msgstr "访问Jira的凭æ®æ— æ•ˆã€‚检查您的Jira集æˆå‡­æ®ï¼Œç„¶åŽé‡è¯•ã€‚"
msgid "JiraService| on branch %{branch_link}"
msgstr "于分支%{branch_link}"
msgid "JiraService|%{jiraDocsLinkStart}Enable the Jira integration%{jiraDocsLinkEnd} to view your Jira issues in GitLab."
-msgstr ""
+msgstr "%{jiraDocsLinkStart}å¯ç”¨Jira集æˆ%{jiraDocsLinkEnd} ,在GitLab中查看您的Jira议题。"
msgid "JiraService|%{jira_docs_link_start}Enable the Jira integration%{jira_docs_link_end} to view your Jira issues in GitLab."
msgstr "%{jira_docs_link_start}å¯ç”¨Jira集æˆ%{jira_docs_link_end}以在GitLab中查看您的Jira议题。"
@@ -18721,10 +18871,10 @@ msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{proj
msgstr "%{user_link}在%{project_link}%{branch}中的%{entity_link}中æåŠæ­¤è®®é¢˜: {quote}%{entity_message}{quote}"
msgid "JiraService|An error occurred while fetching issue list"
-msgstr ""
+msgstr "获å–议题列表时出错"
msgid "JiraService|Automatically transitions Jira issues to the \"Done\" category. %{linkStart}Learn more%{linkEnd}"
-msgstr ""
+msgstr "自动将 Jira 问题转æ¢ä¸ºâ€œå®Œæˆâ€ç±»åˆ«ã€‚ %{linkStart}了解更多%{linkEnd}"
msgid "JiraService|Base URL of the Jira instance."
msgstr "Jira 实例的基础 URL。"
@@ -18757,7 +18907,7 @@ msgid "JiraService|Failed to load Jira issue. View the issue in Jira, or reload
msgstr "无法加载 Jira 议题。在 Jira 中查看议题,或é‡æ–°åŠ è½½é¡µé¢ã€‚"
msgid "JiraService|Failed to update Jira issue labels. View the issue in Jira, or reload the page."
-msgstr ""
+msgstr "无法更新Jira议题状æ€ã€‚在Jira中查看议题,或é‡æ–°åŠ è½½é¡µé¢ã€‚"
msgid "JiraService|Failed to update Jira issue status. View the issue in Jira, or reload the page."
msgstr "无法更新 Jira 议题状æ€ã€‚在 Jira 中查看议题,或é‡æ–°åŠ è½½é¡µé¢ã€‚"
@@ -18772,19 +18922,19 @@ msgid "JiraService|For example, AB"
msgstr "例如:AB"
msgid "JiraService|GitLab for Jira Configuration"
-msgstr ""
+msgstr "用于 Jira é…置的 GitLab"
msgid "JiraService|IDs must be a list of numbers that can be split with , or ;"
-msgstr ""
+msgstr "ID 必须是å¯ä»¥ç”¨ , 或 ; 分割的数字列表"
msgid "JiraService|If different from Web URL."
-msgstr ""
+msgstr "如果与 Web URL ä¸åŒã€‚"
msgid "JiraService|Issue List"
msgstr "议题列表"
msgid "JiraService|Issues created from vulnerabilities in this project will be Jira issues, even if GitLab issues are enabled."
-msgstr ""
+msgstr "由该项目中的æ¼æ´žåˆ›å»ºçš„问题将是 Jira 问题,å³ä½¿å¯ç”¨äº† GitLab 问题。"
msgid "JiraService|Jira API URL"
msgstr "Jira API URL"
@@ -18793,10 +18943,10 @@ msgid "JiraService|Jira Issues"
msgstr "Jira议题"
msgid "JiraService|Jira comments are created when an issue is referenced in a commit."
-msgstr ""
+msgstr "Jira 评论是在æ交中引用议题时创建的。"
msgid "JiraService|Jira comments are created when an issue is referenced in a merge request."
-msgstr ""
+msgstr "Jira 评论是在åˆå¹¶è¯·æ±‚中引用议题时创建的。"
msgid "JiraService|Jira issue type"
msgstr "Jira 议题类型"
@@ -18823,16 +18973,16 @@ msgid "JiraService|Password or API token"
msgstr "密ç æˆ– API 令牌"
msgid "JiraService|Project key changed, refresh list"
-msgstr ""
+msgstr "项目密钥已更改,刷新列表"
msgid "JiraService|Project key is required to generate issue types"
-msgstr ""
+msgstr "需è¦é¡¹ç›®å¯†é’¥ä»¥ç”Ÿæˆè®®é¢˜ç±»åž‹"
msgid "JiraService|Select issue type"
msgstr "选择问题类型"
msgid "JiraService|Set a custom final state by using transition IDs. %{linkStart}Learn about transition IDs%{linkEnd}"
-msgstr ""
+msgstr "ä½¿ç”¨è½¬æ¢ ID 设置自定义最终状æ€ã€‚ %{linkStart}äº†è§£è½¬æ¢ ID%{linkEnd}"
msgid "JiraService|Sign in to GitLab.com to get started."
msgstr ""
@@ -18841,31 +18991,31 @@ msgid "JiraService|This feature requires a Premium plan."
msgstr "此功能需è¦é«˜çº§è®¡åˆ’。"
msgid "JiraService|This is a Premium feature"
-msgstr ""
+msgstr "这是专业版功能"
msgid "JiraService|This is an Ultimate feature"
msgstr "这是一个旗舰版功能"
msgid "JiraService|This issue is synchronized with Jira"
-msgstr ""
+msgstr "此议题与JiraåŒæ­¥"
msgid "JiraService|Transition Jira issues to their final state:"
-msgstr ""
+msgstr "å°† Jira 议题转æ¢ä¸ºæœ€ç»ˆçŠ¶æ€ï¼š"
msgid "JiraService|Upgrade your plan to enable this feature of the Jira Integration."
-msgstr ""
+msgstr "å‡çº§æ‚¨çš„计划以å¯ç”¨ Jira 集æˆçš„此功能。"
msgid "JiraService|Use Jira as this project's issue tracker."
-msgstr ""
+msgstr "使用 Jira 作为此项目的议题跟踪器。"
msgid "JiraService|Use a password for server version and an API token for cloud version."
-msgstr ""
+msgstr "æœåŠ¡å™¨ç‰ˆæœ¬ä½¿ç”¨å¯†ç ï¼Œäº‘版本使用 API 令牌。"
msgid "JiraService|Use a username for server version and an email for cloud version."
-msgstr ""
+msgstr "æœåŠ¡å™¨ç‰ˆæœ¬ä½¿ç”¨ç”¨æˆ·å,云版本使用电å­é‚®ä»¶ã€‚"
msgid "JiraService|Use custom transitions"
-msgstr ""
+msgstr "使用自定义转æ¢"
msgid "JiraService|Username or Email"
msgstr "用户å或电å­é‚®ä»¶"
@@ -18877,7 +19027,7 @@ msgid "JiraService|View Jira issues in GitLab"
msgstr "在GitLab查看Jira议题"
msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
-msgstr ""
+msgstr "警告:有æƒè®¿é—®æ­¤ GitLab 项目的所有 GitLab 用户都能够查看æ¥è‡ªä¸‹é¢æŒ‡å®šçš„ Jira 项目的所有问题。"
msgid "JiraService|Web URL"
msgstr "Web URL"
@@ -18886,7 +19036,7 @@ msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu
msgstr "在ä¸ç¦»å¼€GitLab的情况下处ç†Jira议题。添加一个Jiraèœå•æ¥è®¿é—®æ‚¨çš„Jira议题列表,并å¯ä»¥ä»¥åªè¯»æ¨¡å¼æŸ¥çœ‹ä»»ä½•è®®é¢˜ã€‚"
msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
-msgstr ""
+msgstr "您需è¦åœ¨å¯ç”¨æ­¤é›†æˆä¹‹å‰é…ç½® Jira。有关更多详细信æ¯ï¼Œè¯·é˜…读 %{jira_doc_link_start}Jira 集æˆæ–‡æ¡£%{link_end}。"
msgid "Job"
msgstr "作业"
@@ -18934,7 +19084,7 @@ msgid "Jobs"
msgstr "作业"
msgid "Jobs fail if they run longer than the timeout time. Input value is in seconds by default. Human readable input is also accepted, for example %{code_open}1 hour%{code_close}."
-msgstr ""
+msgstr "如果作业è¿è¡Œæ—¶é—´è¶…过超时时间,则作业将失败。默认情况下,输入值以秒为å•ä½ã€‚也接å—å¯è¯»çš„输入,例如 %{code_open}1 å°æ—¶%{code_close}。"
msgid "Jobs older than the configured time are considered expired and are archived. Archived jobs can no longer be retried. Leave empty to never archive jobs automatically. The default unit is in days, but you can use other units, for example %{code_open}15 days%{code_close}, %{code_open}1 month%{code_close}, %{code_open}2 years%{code_close}. Minimum value is 1 day."
msgstr ""
@@ -19048,10 +19198,10 @@ msgid "Joined %{time_ago}"
msgstr "加入于%{time_ago}"
msgid "Joined %{user_created_time}"
-msgstr ""
+msgstr "加入于%{user_created_time}"
msgid "Joined projects (%{projects_count})"
-msgstr ""
+msgstr "已加入的项目 (%{projects_count})"
msgid "Jul"
msgstr "7月"
@@ -19075,13 +19225,13 @@ msgid "K8s pod health"
msgstr "K8s podå¥åº·"
msgid "KEY"
-msgstr ""
+msgstr "密钥"
msgid "Keep"
-msgstr ""
+msgstr "ä¿æŒ"
msgid "Keep artifacts from most recent successful jobs"
-msgstr ""
+msgstr "ä¿ç•™æœ€è¿‘æˆåŠŸä½œä¸šçš„产物"
msgid "Keep divergent refs"
msgstr "ä¿ç•™åˆ†å‰çš„refs"
@@ -19090,7 +19240,7 @@ msgid "Keep editing"
msgstr "继续编辑"
msgid "Keeping all SAST analyzers enabled future-proofs the project in case new languages are added later on. Determining which analyzers apply is a process that consumes minimal resources and adds minimal time to the pipeline. Leaving all SAST analyzers enabled ensures maximum coverage."
-msgstr ""
+msgstr "ä¿æŒæ‰€æœ‰ SAST 分æžå™¨å·²å¯ç”¨ï¼Œä»¥ç¡®ä¿é¡¹ç›®åœ¨ä»¥åŽæ·»åŠ æ–°è¯­è¨€æ—¶ä¸ä¼šè¿‡æ—¶ã€‚确定应用哪些分æžå™¨æ˜¯ä¸€ä¸ªæ¶ˆè€—最少资æºå¹¶ä¸ºæµæ°´çº¿å¢žåŠ æœ€å°‘时间的过程。å¯ç”¨æ‰€æœ‰ SAST 分æžå™¨å¯ç¡®ä¿æœ€å¤§è¦†ç›–范围。"
msgid "Kerberos access denied"
msgstr "Kerberos访问被拒ç»"
@@ -19126,10 +19276,10 @@ msgid "KeyboardKey|Shift"
msgstr "Shift"
msgid "KeyboardShortcuts|No shortcuts matched your search"
-msgstr ""
+msgstr "没有与您的æœç´¢åŒ¹é…çš„å¿«æ·é”®"
msgid "KeyboardShortcuts|Search keyboard shortcuts"
-msgstr ""
+msgstr "æœç´¢é”®ç›˜å¿«æ·é”®"
msgid "Keys"
msgstr "é”®"
@@ -19198,7 +19348,7 @@ msgid "LDAP synchronizations"
msgstr "LDAPåŒæ­¥"
msgid "LDAP uid:"
-msgstr ""
+msgstr "LDAP uid:"
msgid "LFS"
msgstr "LFS"
@@ -19221,9 +19371,6 @@ msgstr "标记"
msgid "Label actions dropdown"
msgstr "标记æ“作下拉èœå•"
-msgid "Label lists show all issues with the selected label."
-msgstr "标记列表显示具有所选标记的所有议题。"
-
msgid "Label priority"
msgstr "标记优先级"
@@ -19298,7 +19445,7 @@ msgid "Last Accessed On"
msgstr "最åŽè®¿é—®äºŽ"
msgid "Last Activity"
-msgstr ""
+msgstr "最近活动"
msgid "Last Pipeline"
msgstr "最新æµæ°´çº¿"
@@ -19325,16 +19472,16 @@ msgid "Last edited %{date}"
msgstr "最åŽä¿®æ”¹äºŽ%{date}"
msgid "Last edited by %{link_start}%{avatar} %{name}%{link_end}"
-msgstr ""
+msgstr "最åŽä¸€æ¬¡ç”± %{link_start}%{avatar} %{name}%{link_end} 编辑"
msgid "Last item before this page loaded in your browser:"
msgstr "此页é¢åœ¨æ‚¨çš„æµè§ˆå™¨ä¸­è½½å…¥å‰çš„最åŽä¸€ä¸ªé¡¹ç›®ï¼š"
msgid "Last modified"
-msgstr ""
+msgstr "最近修改"
msgid "Last month"
-msgstr ""
+msgstr "上个月"
msgid "Last name"
msgstr "姓"
@@ -19345,9 +19492,6 @@ msgstr "最åŽå›žå¤æ¥è‡ªäºŽ"
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr "最åŽä¸€æ¬¡ä»“库检查(%{last_check_timestamp})失败。请查看\"repocheck.log\"文件以获å–错误消æ¯ã€‚"
-msgid "Last repository check run"
-msgstr "上次仓库检查"
-
msgid "Last seen"
msgstr "最åŽå‡ºçŽ°"
@@ -19366,6 +19510,9 @@ msgstr "上次æˆåŠŸåŒæ­¥"
msgid "Last successful update"
msgstr "最近æˆåŠŸçš„æ›´æ–°"
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr "最近一次验è¯"
@@ -19430,7 +19577,7 @@ msgid "Learn More"
msgstr "了解更多"
msgid "Learn More."
-msgstr ""
+msgstr "了解更多。"
msgid "Learn how to %{link_start}contribute to the built-in templates%{link_end}"
msgstr "了解如何 %{link_start}贡献到内置的模æ¿%{link_end}"
@@ -19442,7 +19589,7 @@ msgid "Learn more"
msgstr "进一步了解"
msgid "Learn more about %{link_start_tag}Jaeger configuration%{link_end_tag}."
-msgstr ""
+msgstr "了解更多关于 %{link_start_tag}Jaeger é…ç½®%{link_end_tag}。"
msgid "Learn more about %{username}"
msgstr "进一步了解%{username}"
@@ -19475,7 +19622,7 @@ msgid "Learn more about group-level project templates"
msgstr "了解更多关于群组级项目模æ¿"
msgid "Learn more about shards and replicas in the %{configuration_link_start}Advanced search configuration%{configuration_link_end} documentation. Changes won't take place until the index is %{recreated_link_start}recreated%{recreated_link_end}."
-msgstr ""
+msgstr "%{configuration_link_start}高级æœç´¢é…ç½®%{configuration_link_end} 文档中了解有关分片和副本的更多信æ¯ã€‚直到索引%{recreated_link_start}é‡æ–°åˆ›å»º%{recreated_link_end}æ‰ä¼šå‘生更改。"
msgid "Learn more about signing commits"
msgstr "了解更多有关签åæ交的详细信æ¯"
@@ -19490,46 +19637,46 @@ msgid "Learn more."
msgstr "了解更多。"
msgid "LearnGitLab|%{percentage}%{percentSymbol} completed"
-msgstr ""
+msgstr "%{percentage}%{percentSymbol} 已完æˆ"
msgid "LearnGitLab|Add code owners"
-msgstr ""
+msgstr "添加代ç æ‰€æœ‰è€…"
msgid "LearnGitLab|Add merge request approval"
-msgstr ""
+msgstr "添加åˆå¹¶è¯·æ±‚批准"
msgid "LearnGitLab|Complete these tasks first so you can enjoy GitLab's features to their fullest:"
-msgstr ""
+msgstr "首先完æˆè¿™äº›ä»»åŠ¡ï¼Œä»¥ä¾¿æ‚¨å¯ä»¥å……åˆ†äº«å— GitLab 的功能:"
msgid "LearnGitLab|Create a workflow for your new workspace, and learn how GitLab features work together:"
-msgstr ""
+msgstr "为您的新工作区创建工作æµï¼Œå¹¶äº†è§£ GitLab 功能如何ååŒå·¥ä½œï¼š"
msgid "LearnGitLab|Create an issue"
-msgstr ""
+msgstr "创建议题"
msgid "LearnGitLab|Create or import a repository"
-msgstr ""
+msgstr "创建或导入仓库"
msgid "LearnGitLab|Create or import your first repository into your new project."
-msgstr ""
+msgstr "创建或导入您的第一个仓库到您的新项目中。"
msgid "LearnGitLab|Create/import issues (tickets) to collaborate on ideas and plan work."
-msgstr ""
+msgstr "创建/导入议题(工å•ï¼‰ä»¥ååŒåˆ›æ„和工作计划。"
msgid "LearnGitLab|Deploy"
msgstr "部署"
msgid "LearnGitLab|Enable require merge approvals"
-msgstr ""
+msgstr "å¯ç”¨éœ€è¦åˆå¹¶æ‰¹å‡†"
msgid "LearnGitLab|GitLab works best as a team. Invite your colleague to enjoy all features."
-msgstr ""
+msgstr "GitLab 团队工作上佳。邀请您的åŒäº‹äº«å—所有功能。"
msgid "LearnGitLab|Invite your colleagues"
msgstr "邀请你的åŒäº‹"
msgid "LearnGitLab|Learn GitLab"
-msgstr ""
+msgstr "学习 GitLab"
msgid "LearnGitLab|Plan and execute"
msgstr "计划和执行"
@@ -19538,43 +19685,43 @@ msgid "LearnGitLab|Prevent unexpected changes to important assets by assigning o
msgstr "通过分é…文件和路径的所有æƒæ¥é˜²æ­¢å¯¹é‡è¦èµ„产进行æ„外更改。"
msgid "LearnGitLab|Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
-msgstr ""
+msgstr "准备好开始使用 GitLab 了å—?按照以下步骤设置您的工作区ã€è®¡åˆ’å’Œæ交更改以åŠéƒ¨ç½²æ‚¨çš„项目。"
msgid "LearnGitLab|Review and edit proposed changes to source code."
-msgstr ""
+msgstr "审核和编辑对æºä»£ç çš„æ议更改。"
msgid "LearnGitLab|Route code reviews to the right reviewers, every time."
-msgstr ""
+msgstr "æ¯æ¬¡éƒ½å°†ä»£ç å®¡æŸ¥ä¼ é€’ç»™åˆé€‚的审查者。"
msgid "LearnGitLab|Run a Security scan using CI/CD"
msgstr "使用 CI/CD è¿è¡Œå®‰å…¨æ‰«æ"
msgid "LearnGitLab|Save time by automating your integration and deployment tasks."
-msgstr ""
+msgstr "通过自动化您的集æˆå’Œéƒ¨ç½²ä»»åŠ¡æ¥èŠ‚çœæ—¶é—´ã€‚"
msgid "LearnGitLab|Scan your code to uncover vulnerabilities before deploying."
-msgstr ""
+msgstr "在部署之å‰æ‰«æ您的代ç ä»¥å‘现æ¼æ´žã€‚"
msgid "LearnGitLab|Set up CI/CD"
msgstr "设置 CI/CD"
msgid "LearnGitLab|Set up your workspace"
-msgstr ""
+msgstr "设置您的工作区"
msgid "LearnGitLab|Set-up CI/CD"
-msgstr ""
+msgstr "设置 CI/CD"
msgid "LearnGitLab|Start a free Ultimate trial"
msgstr "开始å…费试用"
msgid "LearnGitLab|Submit a merge request"
-msgstr ""
+msgstr "æ交åˆå¹¶è¯·æ±‚"
msgid "LearnGitLab|Submit a merge request (MR)"
-msgstr ""
+msgstr "æ交åˆå¹¶è¯·æ±‚ (MR)"
msgid "LearnGitLab|Try GitLab Ultimate for free"
-msgstr ""
+msgstr "å…费试用旗舰版"
msgid "LearnGitLab|Try all GitLab features for 30 days, no credit card required."
msgstr ""
@@ -19583,13 +19730,13 @@ msgid "LearnGitLab|Use your new GitLab workflow to deploy your application, moni
msgstr ""
msgid "LearnGitlab|Creating your onboarding experience..."
-msgstr ""
+msgstr "正在创建您的入门体验..."
msgid "LearnGitlab|Ok, let's go"
msgstr ""
msgid "LearnGitlab|Trial only"
-msgstr ""
+msgstr "ä»…é™è¯•ç”¨"
msgid "Leave"
msgstr "退出"
@@ -19613,7 +19760,7 @@ msgid "Leave zen mode"
msgstr "离开禅模å¼"
msgid "Leaving this setting enabled is recommended."
-msgstr ""
+msgstr "建议å¯ç”¨æ­¤è®¾ç½®ã€‚"
msgid "Legacy burndown chart"
msgstr "旧版燃尽图"
@@ -19625,13 +19772,13 @@ msgid "Let's Encrypt is a free, automated, and open certificate authority (CA) t
msgstr "Let's Encrypt是一个å…è´¹ã€è‡ªåŠ¨åŒ–和开放的è¯ä¹¦æŽˆæƒ(CA)机构。它å¯ä»¥æ供网站å¯ç”¨HTTPS (SSL/TLS)所需的数字è¯ä¹¦ã€‚通过%{docs_link_start}GitLab Pages上的文档%{docs_link_end}æ¥äº†è§£Let's Encrypté…置的更多信æ¯ã€‚"
msgid "Let's talk!"
-msgstr ""
+msgstr "让我们æ¥è°ˆè°ˆï¼"
msgid "License Compliance"
msgstr "许å¯è¯åˆè§„"
msgid "License file"
-msgstr ""
+msgstr "许å¯è¯æ–‡ä»¶"
msgid "License overview"
msgstr "许å¯è¯æ¦‚览"
@@ -19799,12 +19946,15 @@ msgid "Limit namespaces and projects that can be indexed"
msgstr "é™åˆ¶å¯ç´¢å¼•å‘½å空间和项目"
msgid "Limit sign in from multiple ips"
+msgstr "é™åˆ¶ä»Žå¤šä¸ªIP登录"
+
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
-msgstr "é™åˆ¶æ­¤æ¬¡è¦èŠ‚点在åŽå°è¿è¡Œçš„并行æ“作数é‡ã€‚"
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
+msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -19848,7 +19998,7 @@ msgid "Link to go to GitLab pipeline documentation"
msgstr "链接以转到GitLaæµæ°´çº¿æ–‡æ¡£"
msgid "Link to your Grafana instance."
-msgstr ""
+msgstr "链接到您的 Grafana 实例。"
msgid "Linked emails (%{email_count})"
msgstr "链接的电å­é‚®ä»¶ (%{email_count})"
@@ -19881,7 +20031,7 @@ msgid "List of all merge commits"
msgstr "所有åˆå¹¶æ交列表"
msgid "List of users to be excluded from the limit"
-msgstr ""
+msgstr "è¦æŽ’除在é™åˆ¶èŒƒå›´ä¹‹å¤–的用户列表"
msgid "List options"
msgstr "列表选项"
@@ -20061,13 +20211,13 @@ msgid "Made this issue confidential."
msgstr "将此议题设置为ç§å¯†."
msgid "Mailgun"
-msgstr ""
+msgstr "Mailgun"
msgid "Mailgun HTTP webhook signing key"
-msgstr ""
+msgstr "Mailgun HTTP webhook ç­¾å密钥"
msgid "Mailgun events"
-msgstr ""
+msgstr "Mailgun事件"
msgid "Maintenance mode"
msgstr "维护模å¼"
@@ -20088,7 +20238,7 @@ msgid "Makes this issue confidential."
msgstr "将此议题设置为ç§å¯†."
msgid "Manage Web IDE features."
-msgstr ""
+msgstr "ç®¡ç† Web IDE 功能。"
msgid "Manage access"
msgstr "管ç†æƒé™"
@@ -20100,13 +20250,13 @@ msgid "Manage applications that can use GitLab as an OAuth provider, and applica
msgstr "管ç†å¯ä»¥å°†GitLab用作OAuthæ供程åºçš„应用程åºï¼Œä»¥åŠæ‚¨å·²æŽˆæƒä½¿ç”¨æ‚¨çš„å¸æˆ·çš„应用程åºã€‚"
msgid "Manage applications that can use GitLab as an OAuth provider."
-msgstr ""
+msgstr "管ç†å¯ä»¥ä½¿ç”¨ GitLab 作为 OAuth æ供者的应用程åºã€‚"
msgid "Manage applications that you've authorized to use your account."
msgstr "管ç†æ‚¨æŽˆæƒä½¿ç”¨å¸æˆ·çš„应用程åºã€‚"
msgid "Manage git repositories with fine-grained access controls that keep your code secure."
-msgstr ""
+msgstr "使用精细的访问控制æ¥ç®¡ç†git仓库,确ä¿æ‚¨çš„代ç å®‰å…¨ã€‚"
msgid "Manage group labels"
msgstr "管ç†ç¾¤ç»„标记"
@@ -20187,13 +20337,13 @@ msgid "Markdown Help"
msgstr "Markdown帮助"
msgid "Markdown enabled."
-msgstr ""
+msgstr "Markdownå·²å¯ç”¨ã€‚"
msgid "Markdown is supported"
msgstr "支æŒMarkdown"
msgid "Markdown supported."
-msgstr ""
+msgstr "æ”¯æŒ Markdown。"
msgid "MarkdownEditor|Add a link (%{modifierKey}K)"
msgstr "添加链接(%{modifierKey}K)"
@@ -20283,7 +20433,7 @@ msgid "MattermostService|Suggestions:"
msgstr "建议:"
msgid "MattermostService|Use this service to perform common tasks in your project by entering slash commands in Mattermost."
-msgstr ""
+msgstr "通过在 Mattermost 中输入斜æ å‘½ä»¤ï¼Œä½¿ç”¨æ­¤æœåŠ¡æ‰§è¡Œé¡¹ç›®ä¸­çš„常è§ä»»åŠ¡ã€‚"
msgid "Max 100,000 events"
msgstr "最多100,000个事件"
@@ -20312,6 +20462,9 @@ msgstr "æ¯ä¸ªç”¨æˆ·æ¯åˆ†é’Ÿæœ€å¤§é¡¹ç›®å¯¼å…¥è¯·æ±‚æ•°"
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20319,7 +20472,7 @@ msgid "Max file size is 200 KB."
msgstr "最大文件大å°ä¸º200 KB。"
msgid "Max requests per minute per user"
-msgstr ""
+msgstr "æ¯ä¸ªç”¨æˆ·æ¯åˆ†é’Ÿæœ€å¤§è¯·æ±‚æ•°"
msgid "Max role"
msgstr "最大角色"
@@ -20346,7 +20499,7 @@ msgid "Maximum PyPI package file size in bytes"
msgstr "最大PyPI文件包大å°ï¼ˆå­—节)"
msgid "Maximum Terraform Module package file size in bytes"
-msgstr ""
+msgstr "最大 Terraform 模å—包文件大å°ï¼ˆä»¥å­—节为å•ä½ï¼‰"
msgid "Maximum Users"
msgstr "最大用户数"
@@ -20360,6 +20513,9 @@ msgstr "最大工件大å°"
msgid "Maximum artifacts size (MB)"
msgstr "最大产物大å°ï¼ˆMB)"
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr "æœ€å¤§é™„ä»¶å¤§å° (MB)"
@@ -20378,9 +20534,12 @@ msgstr "æ¯ä¸ªç´¢å¼•æ“作的Elasticsearch批é‡è¯·æ±‚的最大并å‘性。"
msgid "Maximum delay (Minutes)"
msgstr "最大延迟 (分钟)"
-msgid "Maximum diff patch size (Bytes)"
+msgid "Maximum diff patch size"
msgstr ""
+msgid "Maximum diff patch size (Bytes)"
+msgstr "最大差异补ä¸å¤§å°ï¼ˆå­—节)"
+
msgid "Maximum duration of a session."
msgstr "会è¯çš„最大有效期é™ã€‚"
@@ -20390,8 +20549,8 @@ msgstr "最大字段长度"
msgid "Maximum file size indexed (KiB)"
msgstr "索引的最大文件大å°(KiB)"
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
-msgstr "最大文件大å°ä¸º 1MB。图片大å°å¿…须为 32x32 åƒç´ ã€‚å…许的图åƒæ ¼å¼ä¸º %{favicon_extension_whitelist}。"
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
+msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
msgstr "最大文件大å°ä¸º 1MB,页é¢é’ˆå¯¹ 28 åƒç´ é«˜çš„标题LOGO进行了优化"
@@ -20405,9 +20564,15 @@ msgstr "最大文件大å°ä¸º 2MB。请选择一个较å°çš„文件。"
msgid "Maximum files in a diff"
msgstr "差异中的最大文件数"
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr "æœ€å¤§å¯¼å…¥å¤§å° (MB)"
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr "最大作业超时"
@@ -20441,11 +20606,17 @@ msgstr "æ¯ä¸ªç”¨æˆ·æœ€å¤§å•ä¸€IPæ•°"
msgid "Maximum page reached"
msgstr "已达到最大页é¢"
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr "最大推é€å¤§å° (MB)"
msgid "Maximum running slices"
-msgstr ""
+msgstr "最大è¿è¡Œåˆ‡ç‰‡"
msgid "Maximum size limit for a single commit."
msgstr "å•æ¬¡æ交的最大大å°é™åˆ¶ã€‚"
@@ -20465,6 +20636,9 @@ msgstr "评论中å•ä¸ªé™„件的最大大å°ã€‚"
msgid "Maximum size of pages (MB)"
msgstr "最大页é¢å¤§å°ï¼ˆMB)"
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr "åŒæ­¥é•œåƒè®¡åˆ’的最大时间间隔。"
@@ -20504,6 +20678,9 @@ msgstr "æˆå‘˜è‡ªï¼š"
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr "%{member_name}邀请您使用GitLab"
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr "邀请加入%{project_or_group}%{project_or_group_name}"
@@ -20514,7 +20691,7 @@ msgid "Members can be added by project %{i_open}Maintainers%{i_close} or %{i_ope
msgstr "æˆå‘˜å¯ç”±é¡¹ç›®çš„%{i_open}维护者%{i_close} 或 %{i_open}所有者%{i_close}添加"
msgid "Members listed as CODEOWNERS of affected files."
-msgstr ""
+msgstr "列为å—å½±å“文件的CODEOWNERSçš„æˆå‘˜ã€‚"
msgid "Members of %{group} can also merge into this branch: %{branch}"
msgstr "%{group}çš„æˆå‘˜ä¹Ÿå¯ä»¥åˆå¹¶åˆ°æ­¤åˆ†æ”¯: %{branch}"
@@ -20556,10 +20733,10 @@ msgid "Members|Are you sure you want to remove \"%{groupName}\"?"
msgstr "您确定è¦åˆ é™¤\"%{groupName}\"å—?"
msgid "Members|Are you sure you want to remove %{usersName} from \"%{source}\"?"
-msgstr ""
+msgstr "您确定è¦ä»Žâ€œ%{source}â€ä¸­åˆ é™¤%{usersName}å—?"
msgid "Members|Are you sure you want to remove this orphaned member from \"%{source}\"?"
-msgstr ""
+msgstr "您确定è¦ä»Žâ€œ%{source}â€ä¸­åˆ é™¤è¿™ä¸ªå­¤ç«‹çš„æˆå‘˜å—?"
msgid "Members|Are you sure you want to revoke the invitation for %{inviteEmail} to join \"%{source}\""
msgstr "你确定è¦æ’¤é”€%{inviteEmail}加入\"%{source}\"的邀请å—"
@@ -20622,7 +20799,7 @@ msgid "Members|Role updated successfully."
msgstr "å·²æˆåŠŸæ›´æ–°è§’色。"
msgid "Members|Search groups"
-msgstr ""
+msgstr "æœç´¢ç¾¤ç»„"
msgid "Members|Search invited"
msgstr "æœç´¢å·²é‚€è¯·"
@@ -20672,9 +20849,12 @@ msgstr "åˆå¹¶è¯·æ±‚å·²åˆå¹¶"
msgid "Merge automatically (%{strategy})"
msgstr "自动åˆå¹¶(%{strategy})"
-msgid "Merge blocked: the source branch must be rebased onto the target branch."
+msgid "Merge blocked: new changes were just added."
msgstr ""
+msgid "Merge blocked: the source branch must be rebased onto the target branch."
+msgstr "åˆå¹¶å—阻:æºåˆ†æ”¯å¿…é¡»å˜åŸºï¼ˆrebase)到目标分支。"
+
msgid "Merge commit SHA"
msgstr "åˆå¹¶æ交SHA"
@@ -20712,7 +20892,7 @@ msgid "Merge request approvals"
msgstr "åˆå¹¶è¯·æ±‚批准"
msgid "Merge request commits"
-msgstr ""
+msgstr "åˆå¹¶è¯·æ±‚æ交"
msgid "Merge request dependencies"
msgstr "åˆå¹¶è¯·æ±‚ä¾èµ–"
@@ -20789,9 +20969,6 @@ msgstr "对%{selectStart}开始于%{selectEnd}到%{end}è¡Œå‘表评论"
msgid "MergeRequestDiffs|Select comment starting line"
msgstr "选择评论起始行"
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr "检查是å¦æ­£åœ¨æ‰§è¡Œå¦ä¸€ä¸ªåŽ‹ç¼©æ—¶å‡ºé”™ã€‚"
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr "ä¿å­˜è¯„论è‰ç¨¿æ—¶å‘生错误。"
@@ -20804,9 +20981,6 @@ msgstr "创建新议题以解决此主题"
msgid "MergeRequests|Saving the comment failed"
msgstr "ä¿å­˜è¯„论失败"
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr "压缩(Squash)任务已å–消:å¦ä¸€ä¸ªåŽ‹ç¼©å·²åœ¨è¿›è¡Œä¸­ã€‚"
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr "此项目ä¸å…许在接å—åˆå¹¶è¯·æ±‚时压缩æ交。"
@@ -20874,7 +21048,7 @@ msgid "Merged branches are being deleted. This can take some time depending on t
msgstr "å·²åˆå¹¶åˆ†æ”¯æ­£åœ¨è¢«åˆ é™¤ã€‚该æ“作å¯èƒ½éœ€è¦ä¸€äº›æ—¶é—´ï¼Œå…·ä½“å–决于分支的数é‡ã€‚请刷新页é¢ä»¥æŸ¥çœ‹æ›´æ–°ã€‚"
msgid "Merged by"
-msgstr ""
+msgstr "åˆå¹¶è€…"
msgid "Merged this merge request."
msgstr "å·²åˆå¹¶æ­¤åˆå¹¶è¯·æ±‚。"
@@ -20898,7 +21072,7 @@ msgid "Method"
msgstr "方法"
msgid "Method call threshold (ms)"
-msgstr ""
+msgstr "方法调用阈值(毫秒)"
msgid "Metric was successfully added."
msgstr "指标已æˆåŠŸæ·»åŠ ã€‚"
@@ -20988,7 +21162,7 @@ msgid "MetricsSettings|External dashboard URL"
msgstr "外部仪表盘URL"
msgid "MetricsSettings|Manage metrics dashboard settings."
-msgstr ""
+msgstr "管ç†æŒ‡æ ‡ä»ªè¡¨ç›˜è®¾ç½®"
msgid "MetricsSettings|Metrics"
msgstr "指标"
@@ -21286,9 +21460,6 @@ msgstr "里程碑截止日期"
msgid "Milestone lists not available with your current license"
msgstr "当å‰è®¸å¯è¯æ— æ³•ä½¿ç”¨é‡Œç¨‹ç¢‘列表"
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr "里程碑列表显示所选里程碑的所有议题。"
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr "æœç´¢é‡Œç¨‹ç¢‘时出错"
@@ -21440,7 +21611,7 @@ msgid "Mirror direction"
msgstr "é•œåƒæ–¹å‘"
msgid "Mirror only protected branches"
-msgstr ""
+msgstr "ä»…é•œåƒå—ä¿æŠ¤çš„分支"
msgid "Mirror repository"
msgstr "é•œåƒä»“库"
@@ -21470,7 +21641,7 @@ msgid "Mirroring will only be available if the feature is included in the plan o
msgstr "åªæœ‰åœ¨æ‰€é€‰ç¾¤ç»„或用户的计划中包å«é•œåƒåŠŸèƒ½æ—¶ï¼Œæ‰èƒ½ä½¿ç”¨ã€‚"
msgid "Miscellaneous"
-msgstr ""
+msgstr "æ‚项"
msgid "Missing"
msgstr ""
@@ -21527,7 +21698,7 @@ msgid "Monitor Settings"
msgstr "监控设置"
msgid "Monitor the health and performance of GitLab with Prometheus."
-msgstr ""
+msgstr "用Prometheus监控 GitLab çš„å¥åº·å’Œæ€§èƒ½ã€‚"
msgid "Monitor your errors by integrating with Sentry."
msgstr "通过与Sentry集æˆæ¥ç›‘控您的错误。"
@@ -21563,7 +21734,7 @@ msgid "More information and share feedback"
msgstr "更多信æ¯å’Œå…±äº«å馈"
msgid "More information is available|here"
-msgstr "帮助文档"
+msgstr ""
msgid "More information."
msgstr "更多信æ¯ã€‚"
@@ -21572,10 +21743,10 @@ msgid "More than %{number_commits_distance} commits different with %{default_bra
msgstr "è¶…å‰ %{number_commits_distance} 个æ交与 %{default_branch} ä¸åŒ"
msgid "More topics"
-msgstr ""
+msgstr "更多主题"
msgid "Most relevant"
-msgstr ""
+msgstr "相关度最高"
msgid "Most stars"
msgstr "最多星标"
@@ -21587,7 +21758,7 @@ msgid "Move"
msgstr "移动"
msgid "Move down"
-msgstr ""
+msgstr "下移"
msgid "Move issue"
msgstr "移动议题"
@@ -21608,7 +21779,7 @@ msgid "Move this issue to another project."
msgstr "将此议题移至å¦ä¸€ä¸ªé¡¹ç›®ã€‚"
msgid "Move up"
-msgstr ""
+msgstr "上移"
msgid "MoveIssue|Cannot move issue due to insufficient permissions!"
msgstr "由于æƒé™ä¸è¶³è€Œæ— æ³•ç§»åŠ¨è®®é¢˜!"
@@ -21667,8 +21838,8 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr "必须匹é…%{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}中的%{codeStart}external_url%{codeEnd}。"
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
-msgstr "必须匹é…%{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}中的%{codeStart}geo_node_name%{codeEnd}。%{linkStart}更多信æ¯%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
+msgstr ""
msgid "My Awesome Group"
msgstr "My Awesome Group"
@@ -21692,7 +21863,7 @@ msgid "Name has already been taken"
msgstr "å称已被使用"
msgid "Name is already taken."
-msgstr ""
+msgstr "å称已被å ç”¨ã€‚"
msgid "Name new label"
msgstr "命å新标记"
@@ -21732,13 +21903,13 @@ msgid "NamespaceStorageSize|You have reached %{usage_in_percent} of %{namespace_
msgstr "你已使用了%{namespace_name}存储空间的%{usage_in_percent}(总计%{storage_limit},已使用%{used_storage})"
msgid "NamespaceStorageSize|You have reached the free storage limit of %{free_size_limit} on one or more projects."
-msgstr ""
+msgstr "您已ç»è¾¾åˆ°äº†ä¸€ä¸ªæˆ–多个项目的 %{free_size_limit} çš„å…费存储é™åˆ¶ã€‚"
msgid "NamespaceStorageSize|push to your repository, create pipelines, create issues or add comments. To reduce storage capacity, delete unused repositories, artifacts, wikis, issues, and pipelines."
msgstr "推é€åˆ°æ‚¨çš„仓库,创建æµæ°´çº¿ï¼Œåˆ›å»ºè®®é¢˜æˆ–添加评论。如需å‡å°‘存储使用,请删除未使用的仓库,产物,wiki,议题和æµæ°´çº¿ã€‚"
msgid "NamespaceStorageSize|push to your repository, create pipelines, create issues or add comments. To reduce storage capacity, delete unused repositories, artifacts, wikis, issues, and pipelines. To learn more about reducing storage capacity please visit our docs."
-msgstr ""
+msgstr "推é€åˆ°æ‚¨çš„仓库ã€åˆ›å»ºæµæ°´çº¿ã€åˆ›å»ºè®®é¢˜æˆ–添加评论。è¦å‡å°‘存储容é‡ï¼Œè¯·åˆ é™¤æœªä½¿ç”¨çš„仓库ã€äº§ç‰©ã€wikiã€è®®é¢˜å’Œæµæ°´çº¿ã€‚è¦äº†è§£æœ‰å…³å‡å°‘存储容é‡çš„更多信æ¯ï¼Œè¯·è®¿é—®æˆ‘们的文档。"
msgid "Namespaces"
msgstr "命å空间"
@@ -21792,7 +21963,7 @@ msgid "NetworkPolicies|%{ifLabelStart}if%{ifLabelEnd} %{ruleType} %{isLabelStart
msgstr "%{ifLabelStart}如果%{ifLabelEnd}%{ruleType}%{isLabelStart}为%{isLabelEnd}%{ruleDirection}%{ruleSelector}%{directionLabelStart}且å‘%{directionLabelEnd}%{rule}%{portsLabelStart}在%{portsLabelEnd} %{ports}外å‘。"
msgid "NetworkPolicies|%{labelStart}And%{labelEnd} %{spanStart}send an Alert to GitLab.%{spanEnd}"
-msgstr ""
+msgstr "%{labelStart}å’Œ%{labelEnd} %{spanStart}å‘é€è­¦æŠ¥åˆ° GitLab。%{spanEnd}"
msgid "NetworkPolicies|%{labelStart}Then%{labelEnd} %{action} %{spanStart}the network traffic.%{spanEnd}"
msgstr "%{labelStart}然åŽ%{labelEnd}%{action}%{spanStart}网络æµé‡ã€‚%{spanEnd}"
@@ -21807,7 +21978,7 @@ msgid "NetworkPolicies|%{strongOpen}any%{strongClose} port"
msgstr "%{strongOpen}任何%{strongClose}端å£"
msgid "NetworkPolicies|+ Add alert"
-msgstr ""
+msgstr "+ 添加警报"
msgid "NetworkPolicies|.yaml"
msgstr ".yaml"
@@ -21828,10 +21999,10 @@ msgid "NetworkPolicies|Allow"
msgstr "å…许"
msgid "NetworkPolicies|Allow all inbound traffic to %{selector} from %{ruleSelector} on %{ports}"
-msgstr ""
+msgstr "å…许所有入站æµé‡ä»Ž%{ports}端å£çš„%{ruleSelector}到%{selector}"
msgid "NetworkPolicies|Allow all outbound traffic from %{selector} to %{ruleSelector} on %{ports}"
-msgstr ""
+msgstr "å…许所有出站æµé‡ä»Ž%{ports}端å£çš„%{selector}到%{ruleSelector}"
msgid "NetworkPolicies|Are you sure you want to delete this policy? This action cannot be undone."
msgstr "您确定è¦åˆ é™¤æ­¤ç­–ç•¥å—?此æ“作ä¸èƒ½æ’¤æ¶ˆã€‚"
@@ -21857,12 +22028,6 @@ msgstr "æè¿°"
msgid "NetworkPolicies|Edit policy"
msgstr "编辑策略"
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr "强制执行状æ€"
@@ -21879,7 +22044,7 @@ msgid "NetworkPolicies|Invalid or empty policy"
msgstr "无效或空策略"
msgid "NetworkPolicies|Invalid or unsupported policy kind"
-msgstr ""
+msgstr "无效或ä¸æ”¯æŒçš„策略类型"
msgid "NetworkPolicies|Kubernetes error: %{error}"
msgstr "Kubernetes错误: %{error}"
@@ -21888,7 +22053,7 @@ msgid "NetworkPolicies|Name"
msgstr "å称"
msgid "NetworkPolicies|Network"
-msgstr ""
+msgstr "网络"
msgid "NetworkPolicies|Network traffic"
msgstr "网络æµé‡"
@@ -21903,10 +22068,7 @@ msgid "NetworkPolicies|None selected"
msgstr "未选择"
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
-msgstr ""
-
-msgid "NetworkPolicies|Policies"
-msgstr ""
+msgstr "请%{installLinkStart}安装%{installLinkEnd}并%{configureLinkStart}为该项目é…ç½® Kubernetes 代ç†%{configureLinkEnd}以å¯ç”¨è­¦æŠ¥ã€‚"
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr "策略具体定义了pod组如何与其他组中的pod进行网络端点通信。"
@@ -21917,21 +22079,12 @@ msgstr "å·²æˆåŠŸæ›´æ”¹ç­–ç•¥%{policyName}"
msgid "NetworkPolicies|Policy definition"
msgstr "策略定义"
-msgid "NetworkPolicies|Policy description"
-msgstr "ç­–ç•¥æè¿°"
-
msgid "NetworkPolicies|Policy editor"
msgstr "策略编辑"
msgid "NetworkPolicies|Policy preview"
msgstr "策略预览"
-msgid "NetworkPolicies|Policy status"
-msgstr "策略状æ€"
-
-msgid "NetworkPolicies|Policy type"
-msgstr "策略类型"
-
msgid "NetworkPolicies|Rule"
msgstr "规则"
@@ -21947,9 +22100,6 @@ msgstr "规则"
msgid "NetworkPolicies|Save changes"
msgstr "ä¿å­˜æ›´æ”¹"
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr "出现错误,未能更新策略"
@@ -22008,10 +22158,10 @@ msgid "NetworkPolicy|Policy"
msgstr "ç­–ç•¥"
msgid "NetworkPolicy|Search by policy name"
-msgstr ""
+msgstr "按策略å称æœç´¢"
msgid "NetworkPolicy|Status"
-msgstr ""
+msgstr "状æ€"
msgid "Never"
msgstr "从ä¸"
@@ -22087,7 +22237,7 @@ msgid "New User"
msgstr "新建用户"
msgid "New application"
-msgstr ""
+msgstr "新建应用"
msgid "New branch"
msgstr "新建分支"
@@ -22095,9 +22245,6 @@ msgstr "新建分支"
msgid "New branch unavailable"
msgstr "新分支ä¸å¯ç”¨"
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr "添加了新的å˜æ›´ã€‚ %{linkStart}é‡æ–°åŠ è½½é¡µé¢ä»¥æŸ¥çœ‹%{linkEnd}"
-
msgid "New confidential epic title "
msgstr "新建ç§å¯†å²è¯—标题 "
@@ -22111,7 +22258,7 @@ msgid "New directory"
msgstr "新建目录"
msgid "New discussion"
-msgstr ""
+msgstr "新建讨论"
msgid "New environment"
msgstr "新环境"
@@ -22153,7 +22300,7 @@ msgid "New label"
msgstr "新建标记"
msgid "New list"
-msgstr ""
+msgstr "新建列表"
msgid "New merge request"
msgstr "新建åˆå¹¶è¯·æ±‚"
@@ -22165,22 +22312,22 @@ msgid "New password"
msgstr "新密ç "
msgid "New pipelines cause older pending or running pipelines on the same branch to be cancelled."
-msgstr ""
+msgstr "æ–°æµæ°´çº¿ä¼šå¯¼è‡´åŒä¸€åˆ†æ”¯ä¸Šè¾ƒæ—§çš„挂起或正在è¿è¡Œçš„æµæ°´çº¿è¢«å–消。"
msgid "New project"
msgstr "新建项目"
msgid "New project page"
-msgstr ""
+msgstr "新建项目页é¢"
msgid "New project pages"
-msgstr ""
+msgstr "新建项目页é¢"
msgid "New project/repository"
-msgstr ""
+msgstr "新建项目/仓库"
msgid "New public deploy key"
-msgstr ""
+msgstr "新建公共部署密钥"
msgid "New release"
msgstr "新建å‘布"
@@ -22225,13 +22372,13 @@ msgid "Newly registered users will by default be external"
msgstr "默认情况下,新注册的用户将是外部用户"
msgid "Next"
-msgstr "预览版"
+msgstr "下一页"
msgid "Next commit"
msgstr "下一次æ交"
msgid "Next design"
-msgstr ""
+msgstr "下一个设计"
msgid "Next file in diff"
msgstr "差异中的下一个文件"
@@ -22252,7 +22399,7 @@ msgid "No %{providerTitle} repositories found"
msgstr "找ä¸åˆ°%{providerTitle}的仓库"
msgid "No CSV data to display."
-msgstr ""
+msgstr "没有è¦æ˜¾ç¤ºçš„ CSV æ•°æ®ã€‚"
msgid "No Epic"
msgstr "æ— å²è¯—"
@@ -22261,7 +22408,7 @@ msgid "No Matching Results"
msgstr "无匹é…结果"
msgid "No Milestone"
-msgstr ""
+msgstr "没有里程碑"
msgid "No Scopes"
msgstr "无范围"
@@ -22279,6 +22426,9 @@ msgid "No application_settings found"
msgstr "未找到应用程åºè®¾ç½®"
msgid "No approvers"
+msgstr "没有核准人"
+
+msgid "No artifacts found"
msgstr ""
msgid "No assignee"
@@ -22345,7 +22495,7 @@ msgid "No data to display"
msgstr "没有å¯æ˜¾ç¤ºçš„æ•°æ®"
msgid "No deployments detected. Use environments to control your software's continuous deployment. %{linkStart}Learn more about deployment jobs.%{linkEnd}"
-msgstr ""
+msgstr "未检测到部署。使用环境æ¥æŽ§åˆ¶è½¯ä»¶çš„æŒç»­éƒ¨ç½²ã€‚ %{linkStart}了解有关部署作业的更多信æ¯ã€‚%{linkEnd}"
msgid "No deployments found"
msgstr "没有找到部署"
@@ -22354,7 +22504,7 @@ msgid "No due date"
msgstr "无截止日期"
msgid "No email participants were added. Either none were provided, or they already exist."
-msgstr ""
+msgstr "没有添加电å­é‚®ä»¶å‚与者。没有æ供或它们已ç»å­˜åœ¨ã€‚"
msgid "No endpoint provided"
msgstr "未æ供端点"
@@ -22498,7 +22648,7 @@ msgid "No schedules"
msgstr "无计划"
msgid "No severity matches the provided parameter"
-msgstr ""
+msgstr "没有与æ供的å‚数匹é…的严é‡ç¨‹åº¦"
msgid "No source selected"
msgstr "未选择æº"
@@ -22525,7 +22675,7 @@ msgid "No test coverage"
msgstr "无测试覆盖率"
msgid "No triggers exist yet. Use the form above to create one."
-msgstr ""
+msgstr "尚无触å‘器。使用上é¢çš„表å•åˆ›å»ºä¸€ä¸ªã€‚"
msgid "No vulnerabilities present"
msgstr "æ— æ¼æ´ž"
@@ -22609,7 +22759,7 @@ msgid "Note"
msgstr "备注"
msgid "Note creation requests"
-msgstr ""
+msgstr "备注创建请求"
msgid "Note parameters are invalid: %{errors}"
msgstr "说明å‚数无效: %{errors}"
@@ -22633,7 +22783,7 @@ msgid "NoteForm|Note"
msgstr "注æ„"
msgid "Notes Rate Limits"
-msgstr ""
+msgstr "备注速率é™åˆ¶"
msgid "Notes|Are you sure you want to cancel creating this comment?"
msgstr "确定è¦å–消此评论å—?"
@@ -22645,7 +22795,7 @@ msgid "Notes|Confidential comments are only visible to project members"
msgstr "ç§å¯†è¯„论åªå¯¹é¡¹ç›®æˆå‘˜å¯è§"
msgid "Notes|Make this comment confidential"
-msgstr ""
+msgstr "将此评论ä¿å¯†"
msgid "Notes|Show all activity"
msgstr "显示所有活动"
@@ -22660,7 +22810,7 @@ msgid "Notes|This comment has changed since you started editing, please review t
msgstr "自您开始编辑以æ¥ï¼Œæ­¤è¯„论已更改,请查看 %{open_link}更新过的评论%{close_link} 以确ä¿ä¿¡æ¯ä¸ä¼šä¸¢å¤±"
msgid "Notes|This comment is confidential and only visible to project members"
-msgstr ""
+msgstr "此评论是ä¿å¯†çš„,åªå¯¹é¡¹ç›®æˆå‘˜å¯è§"
msgid "Notes|You're only seeing %{boldStart}other activity%{boldEnd} in the feed. To add a comment, switch to one of the following options."
msgstr "您åªèƒ½åœ¨ä¿¡æ¯æµä¸­çœ‹åˆ°%{boldStart}其他活动%{boldEnd} 。è¦æ·»åŠ è¯„论,请切æ¢åˆ°ä»¥ä¸‹é€‰é¡¹ä¹‹ä¸€ã€‚"
@@ -22787,7 +22937,7 @@ msgid "Notifications on"
msgstr "å¯ç”¨é€šçŸ¥"
msgid "Notify users by email when sign-in location is not recognized."
-msgstr ""
+msgstr "无法识别登录ä½ç½®æ—¶é€šè¿‡ç”µå­é‚®ä»¶é€šçŸ¥ç”¨æˆ·ã€‚"
msgid "Nov"
msgstr "11月"
@@ -22798,6 +22948,9 @@ msgstr "11月"
msgid "Novice"
msgstr "新手"
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr "Nuget元数æ®å¿…须至少设置了license_url,project_url或icon_url"
@@ -22927,8 +23080,8 @@ msgstr "确定è¦åˆ é™¤â€œ%{deleteSchedule}â€è®¡åˆ’å—?此æ“作无法撤消ã
msgid "OnCallSchedules|Collapse schedule"
msgstr "折å è®¡åˆ’"
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
-msgstr "在GitLab中创建待命计划"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgstr ""
msgid "OnCallSchedules|Currently no rotation."
msgstr "ç›®å‰æ²¡æœ‰è½®æ¢ã€‚"
@@ -22979,31 +23132,31 @@ msgid "OnCallSchedules|Removing yourself may put your on-call team at risk of mi
msgstr "移除您自己å¯èƒ½ä¼šä½¿æ‚¨çš„待命团队é¢ä¸´é”™è¿‡é€šçŸ¥çš„风险。"
msgid "OnCallSchedules|Restrict to time intervals"
-msgstr ""
+msgstr "é™åˆ¶æ—¶é—´é—´éš”"
msgid "OnCallSchedules|Rotation end date/time must come after start date/time"
-msgstr ""
+msgstr "è½®æ¢ç»“æŸæ—¥æœŸ/时间必须晚于开始日期/时间"
msgid "OnCallSchedules|Rotation length"
-msgstr ""
+msgstr "è½®æ¢é•¿åº¦"
msgid "OnCallSchedules|Rotation name cannot be empty"
-msgstr ""
+msgstr "è½®æ¢å称ä¸èƒ½ä¸ºç©º"
msgid "OnCallSchedules|Rotation participants cannot be empty"
-msgstr ""
+msgstr "è½®æ¢å‚与者ä¸èƒ½ä¸ºç©º"
msgid "OnCallSchedules|Rotation start date cannot be empty"
-msgstr ""
+msgstr "è½®æ¢å¼€å§‹æ—¥æœŸä¸èƒ½ä¸ºç©º"
msgid "OnCallSchedules|Rotations"
-msgstr ""
+msgstr "è½®æ¢"
msgid "OnCallSchedules|Route alerts directly to specific members of your team"
msgstr "将警报直接分é…给特定的团队æˆå‘˜"
msgid "OnCallSchedules|Select participant"
-msgstr ""
+msgstr "选择å‚与者"
msgid "OnCallSchedules|Select timezone"
msgstr "选择时区"
@@ -23012,40 +23165,40 @@ msgid "OnCallSchedules|Sets the default timezone for the schedule, for all parti
msgstr "设置所有å‚与者的默认时区"
msgid "OnCallSchedules|Successfully created a new rotation"
-msgstr ""
+msgstr "æˆåŠŸåˆ›å»ºæ–°è½®æ¢"
msgid "OnCallSchedules|Successfully edited your rotation"
-msgstr ""
+msgstr "å·²æˆåŠŸç¼–辑您的轮æ¢"
msgid "OnCallSchedules|The rotation could not be deleted. Please try again."
-msgstr ""
+msgstr "无法删除轮æ¢ã€‚请å†è¯•ä¸€æ¬¡ã€‚"
msgid "OnCallSchedules|The rotation could not be updated. Please try again."
-msgstr ""
+msgstr "无法更新轮æ¢ã€‚请å†è¯•ä¸€æ¬¡ã€‚"
msgid "OnCallSchedules|The schedule could not be deleted. Please try again."
-msgstr ""
+msgstr "无法删除计划,请é‡è¯•ã€‚"
msgid "OnCallSchedules|The schedule could not be updated. Please try again."
-msgstr ""
+msgstr "无法更新计划,请é‡è¯•ã€‚"
msgid "OnCallSchedules|Try adding a rotation"
-msgstr ""
+msgstr "å°è¯•æ·»åŠ è½®æ¢"
msgid "OnCallSchedules|User %{name} is currently part of:"
-msgstr ""
+msgstr "用户 %{name} 当å‰å±žäºŽï¼š"
msgid "OnCallSchedules|View next timeframe"
-msgstr ""
+msgstr "查看下一个时间表"
msgid "OnCallSchedules|View previous timeframe"
-msgstr ""
+msgstr "查看上一个时间表"
msgid "OnCallSchedules|You are currently a part of:"
-msgstr ""
+msgstr "您目å‰å±žäºŽï¼š"
msgid "OnCallSchedules|Your schedule has been successfully created. To add individual users to this schedule, use the Add a rotation button. To enable notifications for this schedule, you must also create an %{linkStart}escalation policy%{linkEnd}."
-msgstr ""
+msgstr "您的日程已æˆåŠŸåˆ›å»ºã€‚è¦å°†å•ä¸ªç”¨æˆ·æ·»åŠ åˆ°æ­¤è®¡åˆ’,请使用添加轮æ¢æŒ‰é’®ã€‚è¦ä¸ºæ­¤è®¡åˆ’å¯ç”¨é€šçŸ¥ï¼Œæ‚¨è¿˜å¿…须创建 %{linkStart}å‡çº§ç­–ç•¥%{linkEnd}。"
msgid "OnDemandScans|Could not fetch scanner profiles. Please refresh the page, or try again later."
msgstr "无法获å–扫æ工具é…置文件。请刷新页é¢æˆ–ç¨åŽå†è¯•ã€‚"
@@ -23057,10 +23210,10 @@ msgid "OnDemandScans|Could not run the scan. Please try again."
msgstr "无法è¿è¡Œæ‰«æ。请é‡è¯•ã€‚"
msgid "OnDemandScans|Create new scanner profile"
-msgstr ""
+msgstr "创建新的扫æ工具é…置文件"
msgid "OnDemandScans|Create new site profile"
-msgstr ""
+msgstr "创建新的站点é…置文件"
msgid "OnDemandScans|Description (optional)"
msgstr "æè¿° (å¯é€‰)"
@@ -23075,10 +23228,10 @@ msgid "OnDemandScans|Manage DAST scans"
msgstr "ç®¡ç† DAST 扫æ"
msgid "OnDemandScans|Manage scanner profiles"
-msgstr ""
+msgstr "管ç†æ‰«æ工具é…置文件"
msgid "OnDemandScans|Manage site profiles"
-msgstr ""
+msgstr "管ç†ç«™ç‚¹é…置文件"
msgid "OnDemandScans|My daily scan"
msgstr "我的æ¯æ—¥æ‰«æ"
@@ -23129,13 +23282,13 @@ msgid "OnDemandScans|You cannot run an active scan against an unvalidated site."
msgstr "您ä¸èƒ½å¯¹æœªéªŒè¯çš„网站上è¿è¡Œä¸»åŠ¨æ‰«æ。"
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
-msgstr ""
+msgstr "您必须在项目中创建仓库æ‰èƒ½è¿è¡ŒæŒ‰éœ€æ‰«æ。"
msgid "Once a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
msgstr "一旦项目被永久删除,%{strongStart}无法æ¢å¤%{strongEnd}。执行永久删除项目æ“作,将%{strongStart}ç«‹å³åˆ é™¤%{strongEnd}仓库和%{strongStart}所有关è”资æº%{strongEnd},包括议题ã€åˆå¹¶è¯·æ±‚等。"
msgid "Once a project is permanently deleted, it cannot be recovered. You will lose this project's repository and all related resources, including issues and merge requests."
-msgstr ""
+msgstr "一旦项目被永久删除,无法æ¢å¤ã€‚您将失去项目中的仓库和所有关è”资æºï¼ŒåŒ…括议题ã€åˆå¹¶è¯·æ±‚等。"
msgid "Once imported, repositories can be mirrored over SSH. Read more %{link_start}here%{link_end}."
msgstr "仓库导入åŽï¼Œå¯ä»¥é€šè¿‡SSH进行镜åƒã€‚点击%{link_start}此处%{link_end}了解更多."
@@ -23169,7 +23322,7 @@ msgid "One or more of your personal access tokens has expired."
msgstr "您的一个或多个个人访问令牌已过期。"
msgid "One or more of your personal access tokens will expire in %{days_to_expire} days or less:"
-msgstr ""
+msgstr "您的一个或多个个人访问令牌将在 %{days_to_expire} 天或更短的时间内到期:"
msgid "Only 'Reporter' roles and above on tiers Premium and above can see Value Stream Analytics."
msgstr ""
@@ -23178,19 +23331,19 @@ msgid "Only 1 appearances row can exist"
msgstr "åªèƒ½å­˜åœ¨ä¸€ä¸ªå¤–观行"
msgid "Only Issue ID or merge request ID is required"
-msgstr ""
+msgstr "仅需è¦è®®é¢˜ ID 或åˆå¹¶è¯·æ±‚ ID"
msgid "Only Project Members"
msgstr "仅项目æˆå‘˜"
msgid "Only active projects show up in the search and on the dashboard."
-msgstr ""
+msgstr "仅活动的项目显示在æœç´¢å’Œä»ªè¡¨æ¿ä¸Šã€‚"
msgid "Only admins can delete project"
msgstr "åªæœ‰ç®¡ç†å‘˜å¯ä»¥åˆ é™¤é¡¹ç›®"
msgid "Only include features new to your current subscription tier."
-msgstr ""
+msgstr "仅包括您当å‰è®¢é˜…级别的新功能。"
msgid "Only policy:"
msgstr "ä»…ä»…(Only)æ¡ä»¶ï¼š"
@@ -23205,7 +23358,7 @@ msgid "Only project members will be imported. Group members will be skipped."
msgstr "仅导入项目æˆå‘˜ã€‚群组æˆå‘˜å°†è¢«è·³è¿‡ã€‚"
msgid "Only projects created under a Ultimate license are available in Security Dashboards."
-msgstr ""
+msgstr "åªæœ‰åœ¨æ——舰版许å¯ä¸‹åˆ›å»ºçš„项目æ‰èƒ½åœ¨å®‰å…¨ä»ªè¡¨æ¿ä¸­ä½¿ç”¨ã€‚"
msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr "åªæœ‰å…·æœ‰è¿™äº›åŸŸå电å­é‚®ä»¶åœ°å€çš„已验è¯ç”¨æˆ·æ‰èƒ½æ·»åŠ åˆ°ç¾¤ç»„。"
@@ -23222,7 +23375,7 @@ msgstr "开放中"
msgid "Open Selection"
msgstr "打开所选项"
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23238,7 +23391,7 @@ msgid "Open in file view"
msgstr "在文件视图中打开"
msgid "Open in your IDE"
-msgstr ""
+msgstr "在您的IDE中打开"
msgid "Open raw"
msgstr "打开原始文件"
@@ -23253,10 +23406,10 @@ msgid "Open: %{open}"
msgstr "å¼€å¯: %{open}"
msgid "OpenAPI"
-msgstr ""
+msgstr "OpenAPI"
msgid "OpenAPI Specification file path or URL"
-msgstr ""
+msgstr "OpenAPI 规范文件路径或 URL"
msgid "Opened"
msgstr "已打开"
@@ -23304,7 +23457,7 @@ msgid "OperationsDashboard|The operations dashboard provides a summary of each p
msgstr "è¿ç»´ä»ªè¡¨æ¿æä¾›æ¯ä¸ªé¡¹ç›®çš„è¿è¡ŒçŠ¶å†µçš„摘è¦ï¼ŒåŒ…括æµæ°´çº¿å’Œè­¦æŠ¥çŠ¶æ€ã€‚"
msgid "Optimize your workflow with CI/CD Pipelines"
-msgstr ""
+msgstr "使用 CI/CD æµæ°´çº¿ä¼˜åŒ–您的工作æµç¨‹"
msgid "Optional"
msgstr "å¯é€‰"
@@ -23343,13 +23496,13 @@ msgid "Other visibility settings have been disabled by the administrator."
msgstr "其他å¯è§æ€§è®¾ç½®å·²è¢«ç®¡ç†å‘˜ç¦ç”¨ã€‚"
msgid "Otherwise, click the link below to complete the process."
-msgstr ""
+msgstr "å¦åˆ™ï¼Œç‚¹å‡»ä¸‹é¢çš„链接æ¥å®Œæˆè¿™ä¸€è¿›ç¨‹ã€‚"
msgid "Otherwise, click the link below to complete the process:"
-msgstr ""
+msgstr "å¦åˆ™ï¼Œç‚¹å‡»ä¸‹é¢çš„链接æ¥å®Œæˆè¿›ç¨‹ï¼š"
msgid "Our team has been notified. Please try again."
-msgstr ""
+msgstr "我们的团队已收到通知,请é‡è¯•ã€‚"
msgid "Out-of-compliance with this project's policies and should be removed"
msgstr "ä¸ç¬¦åˆè¯¥é¡¹ç›®æ”¿ç­–,应予以删除"
@@ -23397,10 +23550,10 @@ msgid "Package Registry Rate Limits"
msgstr "软件包仓库速率é™åˆ¶"
msgid "Package Registry: authenticated API requests"
-msgstr ""
+msgstr "软件包库:ç»è¿‡èº«ä»½éªŒè¯çš„ API 请求"
msgid "Package Registry: unauthenticated API requests"
-msgstr ""
+msgstr "软件包库:未ç»èº«ä»½éªŒè¯çš„ API 请求"
msgid "Package already exists"
msgstr "软件包已存在"
@@ -23414,6 +23567,9 @@ msgstr "软件包文件大å°é™åˆ¶"
msgid "Package recipe already exists"
msgstr "软件包构æˆå·²å­˜åœ¨"
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr "包类型必须是Conan"
@@ -23433,7 +23589,7 @@ msgid "Package type must be PyPi"
msgstr "包类型必须是PyPi"
msgid "Package type must be RubyGems"
-msgstr ""
+msgstr "包类型必须是 RubyGems"
msgid "PackageRegistry|%{boldStart}Allow duplicates%{boldEnd} - Accept packages with the same name and version."
msgstr "%{boldStart}å…许é‡å¤%{boldEnd} - 接å—具有相åŒå称和版本的软件包。"
@@ -23448,10 +23604,10 @@ msgid "PackageRegistry|Add Conan Remote"
msgstr "添加Conan远端"
msgid "PackageRegistry|Add Gradle Groovy DSL repository command"
-msgstr ""
+msgstr "添加 Gradle Groovy DSL 版本库命令"
msgid "PackageRegistry|Add Gradle Kotlin DSL repository command"
-msgstr ""
+msgstr "添加 Gradle Kotlin DSL 版本库命令"
msgid "PackageRegistry|Add NuGet Source"
msgstr "添加Nugetæº"
@@ -23472,7 +23628,7 @@ msgid "PackageRegistry|App name: %{name}"
msgstr "应用å称: %{name}"
msgid "PackageRegistry|Built by pipeline %{link} triggered %{datetime} by %{author}"
-msgstr ""
+msgstr "ç”±%{author}在%{datetime}触å‘çš„æµæ°´çº¿%{link}所构建"
msgid "PackageRegistry|Composer"
msgstr "Composer"
@@ -23520,10 +23676,10 @@ msgid "PackageRegistry|Copy SHA"
msgstr "å¤åˆ¶SHA"
msgid "PackageRegistry|Copy add Gradle Groovy DSL repository command"
-msgstr ""
+msgstr "å¤åˆ¶æ·»åŠ  Gradle Groovy DSL 版本库命令"
msgid "PackageRegistry|Copy add Gradle Kotlin DSL repository command"
-msgstr ""
+msgstr "å¤åˆ¶æ·»åŠ  Gradle Kotlin DSL 版本库命令"
msgid "PackageRegistry|Copy and paste this inside your %{codeStart}pom.xml%{codeEnd} %{codeStart}dependencies%{codeEnd} block."
msgstr "将其å¤åˆ¶å¹¶ç²˜è´´åˆ°æ‚¨çš„%{codeStart}pom.xml%{codeEnd}文件的%{codeStart}dependencies%{codeEnd}å—中。"
@@ -23562,7 +23718,7 @@ msgid "PackageRegistry|Delete package"
msgstr "删除软件包"
msgid "PackageRegistry|Failed to load the package data"
-msgstr ""
+msgstr "加载软件包数æ®å¤±è´¥"
msgid "PackageRegistry|For more information on Composer packages in GitLab, %{linkStart}see the documentation.%{linkEnd}"
msgstr "关于Composer注册表的更多信æ¯ï¼Œ%{linkStart}请è§æ–‡æ¡£ã€‚%{linkEnd}"
@@ -23595,7 +23751,7 @@ msgid "PackageRegistry|Gradle Kotlin DSL install command"
msgstr "Gradle Kotlin DSL安装命令"
msgid "PackageRegistry|Helm"
-msgstr ""
+msgstr "Helm"
msgid "PackageRegistry|If you haven't already done so, you will need to add the below to your %{codeStart}.pypirc%{codeEnd} file."
msgstr "如果尚未é…置,需è¦å°†ä»¥ä¸‹å†…容添加到%{codeStart}.pypirc%{codeEnd}文件中。"
@@ -23646,7 +23802,7 @@ msgid "PackageRegistry|Package has %{number} archived updates"
msgstr "软件包有%{number}个存档更新"
msgid "PackageRegistry|Package updated by commit %{link} on branch %{branch}, built by pipeline %{pipeline}, and published to the registry %{datetime}"
-msgstr ""
+msgstr "软件包由分支%{branch}上的%{link}æ交所更新,由æµæ°´çº¿%{pipeline}构建并于%{datetime}å‘布到库"
msgid "PackageRegistry|Pip Command"
msgstr "Pip命令"
@@ -23853,7 +24009,7 @@ msgid "Pass job variables"
msgstr "传递作业å˜é‡"
msgid "Pass the header %{codeOpen} X-Profile-Token: %{profile_token} %{codeClose} to profile the request"
-msgstr ""
+msgstr "传递标头 %{codeOpen} X-Profile-Token: %{profile_token} %{codeClose} æ¥ä»‹ç»è¯·æ±‚"
msgid "Passed"
msgstr "通过"
@@ -23865,7 +24021,7 @@ msgid "Password"
msgstr "密ç "
msgid "Password (for password-protected Elasticsearch servers)"
-msgstr ""
+msgstr "密ç ï¼ˆç”¨äºŽå—密ç ä¿æŠ¤çš„ Elasticsearch æœåŠ¡å™¨ï¼‰"
msgid "Password (optional)"
msgstr "å¯†ç  (å¯é€‰)"
@@ -23937,7 +24093,7 @@ msgid "Paused runners don't accept new jobs"
msgstr "æš‚åœçš„Runnerä¸æŽ¥å—新作业"
msgid "Peer review by"
-msgstr ""
+msgstr "åŒè¡Œè¯„审"
msgid "Pending"
msgstr "等待中"
@@ -24033,7 +24189,7 @@ msgid "Permanently delete project"
msgstr "永久删除项目"
msgid "Permanently remove group"
-msgstr ""
+msgstr "永久删除群组"
msgid "Permissions"
msgstr "æƒé™"
@@ -24087,10 +24243,10 @@ msgid "Pipeline %{label} for \"%{dataTitle}\""
msgstr "“%{dataTitle}â€çš„æµæ°´çº¿%{label}"
msgid "Pipeline ID"
-msgstr ""
+msgstr "æµæ°´çº¿ID"
msgid "Pipeline IID"
-msgstr ""
+msgstr "æµæ°´çº¿IID"
msgid "Pipeline Schedule"
msgstr "æµæ°´çº¿è®¡åˆ’"
@@ -24120,7 +24276,7 @@ msgid "Pipeline subscriptions"
msgstr "æµæ°´çº¿è®¢é˜…"
msgid "Pipeline subscriptions trigger a new pipeline on the default branch of this project when a pipeline successfully completes for a new tag on the %{default_branch_docs} of the subscribed project."
-msgstr ""
+msgstr "当订阅项目 %{default_branch_docs} 上的新标签æˆåŠŸå®Œæˆæµæ°´çº¿æ—¶ï¼Œæµæ°´çº¿è®¢é˜…会在此项目的默认分支上触å‘æ–°æµæ°´çº¿ã€‚"
msgid "Pipeline triggers"
msgstr "æµæ°´çº¿è§¦å‘器"
@@ -24129,10 +24285,10 @@ msgid "Pipeline: %{status}"
msgstr "æµæ°´çº¿: %{status}"
msgid "PipelineCharts|An error has occurred when retrieving the analytics data"
-msgstr ""
+msgstr "检索分æžæ•°æ®æ—¶å‡ºé”™"
msgid "PipelineCharts|An error has occurred when retrieving the pipelines data"
-msgstr ""
+msgstr "检索æµæ°´çº¿æ•°æ®æ—¶å‡ºé”™"
msgid "PipelineCharts|An unknown error occurred while processing CI/CD analytics."
msgstr "处ç†CI/CD分æžæ—¶å‘生未知错误。"
@@ -24159,67 +24315,67 @@ msgid "PipelineCharts|Total:"
msgstr "总计:"
msgid "PipelineEditorTutorial|Browse %{linkStart}CI/CD examples and templates%{linkEnd}"
-msgstr ""
+msgstr "æµè§ˆ %{linkStart}CI/CD 示例和模æ¿%{linkEnd}"
msgid "PipelineEditorTutorial|Commit the file to your repository. The pipeline then runs automatically."
-msgstr ""
+msgstr "将文件æ交到您的仓库。然åŽæµæ°´çº¿è‡ªåŠ¨è¿è¡Œã€‚"
msgid "PipelineEditorTutorial|Get started with GitLab CI/CD"
-msgstr ""
+msgstr "GitLab CI/CD 入门"
msgid "PipelineEditorTutorial|GitLab CI/CD can automatically build, test, and deploy your application."
-msgstr ""
+msgstr "GitLab CI/CD å¯ä»¥è‡ªåŠ¨æž„建ã€æµ‹è¯•å’Œéƒ¨ç½²æ‚¨çš„应用程åºã€‚"
msgid "PipelineEditorTutorial|If you’re using a self-managed GitLab instance, %{linkStart}make sure your instance has runners available.%{linkEnd}"
-msgstr ""
+msgstr "如果您使用的是自助管ç†çš„ GitLab 实例,请%{linkStart}ç¡®ä¿æ‚¨çš„实例具有å¯ç”¨çš„Runner。%{linkEnd}"
msgid "PipelineEditorTutorial|Learn more about %{linkStart}GitLab CI/CD concepts%{linkEnd}"
-msgstr ""
+msgstr "了解更多关于%{linkStart}GitLab CI/CD 概念%{linkEnd}çš„ä¿¡æ¯"
msgid "PipelineEditorTutorial|Make your pipeline more efficient with the %{linkStart}Needs keyword%{linkEnd}"
-msgstr ""
+msgstr "%{linkStart}Needs 关键字%{linkEnd}让您的æµæ°´çº¿æ›´é«˜æ•ˆ"
msgid "PipelineEditorTutorial|Resources to help with your CI/CD configuration:"
-msgstr ""
+msgstr "帮助您进行 CI/CD é…置的资æºï¼š"
msgid "PipelineEditorTutorial|Select the pipeline ID to view the full details about your first pipeline run."
-msgstr ""
+msgstr "选择æµæ°´çº¿ ID 以查看有关第一次æµæ°´çº¿è¿è¡Œçš„完整详细信æ¯ã€‚"
msgid "PipelineEditorTutorial|The pipeline stages and jobs are defined in a %{codeStart}.gitlab-ci.yml%{codeEnd} file. You can edit, visualize and validate the syntax in this file by using the Pipeline Editor."
-msgstr ""
+msgstr "æµæ°´çº¿çš„阶段和作业在 %{codeStart}.gitlab-ci.yml%{codeEnd} 文件中定义,您å¯ä»¥ä½¿ç”¨æµæ°´çº¿ç¼–辑器编辑ã€å¯è§†åŒ–和验è¯æ­¤æ–‡ä»¶ä¸­çš„语法。"
msgid "PipelineEditorTutorial|The pipeline status is at the top of the page."
-msgstr ""
+msgstr "æµæ°´çº¿çŠ¶æ€åœ¨é¡µé¢é¡¶éƒ¨ã€‚"
msgid "PipelineEditorTutorial|This template creates a simple test pipeline. To use it:"
-msgstr ""
+msgstr "这个模æ¿åˆ›å»ºäº†ä¸€ä¸ªç®€å•çš„测试æµæ°´çº¿ï¼Œè¦ä½¿ç”¨å®ƒï¼š"
msgid "PipelineEditorTutorial|Use the Visualize and Lint tabs in the Pipeline Editor to visualize your pipeline and check for any errors or warnings before committing your changes."
-msgstr ""
+msgstr "使用æµæ°´çº¿ç¼–辑器中的 Visualize å’Œ Lint 标签æ¥å¯è§†åŒ–您的æµæ°´çº¿å¹¶æ£€æŸ¥ä»»ä½•é”™è¯¯æˆ–警告,然åŽå†è¿›è¡Œæ›´æ”¹ã€‚"
msgid "PipelineEditorTutorial|View %{linkStart}.gitlab-ci.yml syntax reference%{linkEnd}"
-msgstr ""
+msgstr "查看 %{linkStart}.gitlab-ci.yml 语法å‚考%{linkEnd}"
msgid "PipelineEditorTutorial|âš™ï¸ Pipeline configuration reference"
-msgstr ""
+msgstr "âš™ï¸ æµæ°´çº¿é…置引用"
msgid "PipelineEditorTutorial|💡 Tip: Visualize and validate your pipeline"
-msgstr ""
+msgstr "💡 æ示:å¯è§†åŒ–并验è¯æ‚¨çš„æµæ°´çº¿"
msgid "PipelineEditorTutorial|🚀 Run your first pipeline"
-msgstr ""
+msgstr "🚀 è¿è¡Œæ‚¨çš„第一个æµæ°´çº¿"
msgid "PipelineEditor|The CI/CD configuration is continuously validated. Errors and warnings are displayed when the CI/CD configuration file is not empty."
-msgstr ""
+msgstr "æŒç»­éªŒè¯ CI/CD é…置。当 CI/CD é…置文件ä¸ä¸ºç©ºæ—¶ï¼Œä¼šæ˜¾ç¤ºé”™è¯¯å’Œè­¦å‘Šã€‚"
msgid "PipelineEditor|The merged YAML view is displayed when the CI/CD configuration file has valid syntax."
-msgstr ""
+msgstr "当 CI/CD é…置文件具有有效语法时,将显示åˆå¹¶çš„ YAML 视图。"
msgid "PipelineEditor|The pipeline visualization is displayed when the CI/CD configuration file has valid syntax."
-msgstr ""
+msgstr "当 CI/CD é…置文件具有有效语法时显示æµæ°´çº¿å¯è§†åŒ–。"
msgid "PipelineEditor|This tab will be usable when the CI/CD configuration file is populated with valid syntax."
-msgstr ""
+msgstr "当 CI/CD é…置文件使用有效语法填写时,此选项å¡å°†å¯ç”¨ã€‚"
msgid "PipelineScheduleIntervalPattern|Custom (%{linkStart}Cron syntax%{linkEnd})"
msgstr "自定义(%{linkStart}Cron 语法%{linkEnd})"
@@ -24276,7 +24432,7 @@ msgid "Pipelines|API"
msgstr "API"
msgid "Pipelines|Add a code quality job"
-msgstr ""
+msgstr "添加代ç è´¨é‡ä½œä¸š"
msgid "Pipelines|Are you sure you want to run this pipeline?"
msgstr "您确定è¦è¿è¡Œè¿™æ¡æµæ°´çº¿å—?"
@@ -24288,16 +24444,16 @@ msgid "Pipelines|By revoking a trigger you will break any processes making use o
msgstr "通过撤销触å‘器将会影å“任何正在调用它的应用。您确定å—?"
msgid "Pipelines|CI lint"
-msgstr ""
+msgstr "CI lint"
msgid "Pipelines|CI/CD template to test and deploy your %{name} project."
-msgstr ""
+msgstr "用于测试和部署您的 %{name} 项目的 CI/CD 模æ¿ã€‚"
msgid "Pipelines|Child pipeline"
msgstr "å­æµæ°´çº¿"
msgid "Pipelines|Clear runner caches"
-msgstr ""
+msgstr "清除Runner缓存"
msgid "Pipelines|Copy trigger token"
msgstr "å¤åˆ¶è§¦å‘令牌"
@@ -24318,10 +24474,10 @@ msgid "Pipelines|Editor"
msgstr "编辑器"
msgid "Pipelines|Get familiar with GitLab CI/CD syntax by starting with a basic 3 stage CI/CD pipeline."
-msgstr ""
+msgstr "从基本的 3 阶段 CI/CD æµæ°´çº¿å¼€å§‹ï¼Œç†Ÿæ‚‰ GitLab CI/CD 语法。"
msgid "Pipelines|Get started with GitLab CI/CD"
-msgstr ""
+msgstr "开始使用 GitLab CI/CD"
msgid "Pipelines|GitLab CI/CD can automatically build, test, and deploy your code. Let GitLab take care of time consuming tasks, so you can spend more time creating."
msgstr "GitLab CI/CDå¯ä»¥è‡ªåŠ¨æž„建,测试和部署您的代ç ã€‚让GitLab处ç†è´¹æ—¶çš„任务,您就有花更多的时间进行创造性的工作。"
@@ -24330,7 +24486,7 @@ msgid "Pipelines|If you are unsure, please ask a project maintainer to review it
msgstr "如果您ä¸ç¡®å®šï¼Œè¯·é¡¹ç›®ç»´æŠ¤è€…为您审核。"
msgid "Pipelines|Improve code quality with GitLab CI/CD"
-msgstr ""
+msgstr "使用 GitLab CI/CD æ高代ç è´¨é‡"
msgid "Pipelines|Install GitLab Runners"
msgstr "安装 GitLab Runners"
@@ -24354,13 +24510,13 @@ msgid "Pipelines|Loading pipelines"
msgstr "正在加载æµæ°´çº¿"
msgid "Pipelines|Merged YAML is view only"
-msgstr ""
+msgstr "åˆå¹¶åŽçš„ YAML ä»…ä¾›æµè§ˆ"
msgid "Pipelines|More Information"
msgstr "更多信æ¯"
msgid "Pipelines|No artifacts available"
-msgstr ""
+msgstr "没有å¯ç”¨çš„产物"
msgid "Pipelines|No triggers have been created yet. Add one using the form above."
msgstr "尚未创建触å‘器。请使用上é¢çš„表å•æ·»åŠ è§¦å‘器。"
@@ -24381,10 +24537,10 @@ msgid "Pipelines|Something went wrong while cleaning runners cache."
msgstr "清ç†runner缓存时å‘生错误。"
msgid "Pipelines|The %{namespace_name} namespace has %{percentage}%% or less Shared Runner Pipeline minutes remaining. After it runs out, no new jobs or pipelines in its projects will run."
-msgstr ""
+msgstr "%{namespace_name} 命å空间还有 %{percentage}%% 或更少的共享Runneræµæ°´çº¿å‰©ä½™åˆ†é’Ÿæ•°ã€‚它用完åŽï¼Œå…¶é¡¹ç›®ä¸­çš„新作业或æµæ°´çº¿å°†ä¸ä¼šè¿è¡Œã€‚"
msgid "Pipelines|The %{namespace_name} namespace has exceeded its pipeline minutes quota. Buy additional pipeline minutes, or no new jobs or pipelines in its projects will run."
-msgstr ""
+msgstr "%{namespace_name} 命å空间已超出其æµæ°´çº¿åˆ†é’Ÿé…é¢ã€‚è´­ä¹°é¢å¤–çš„æµæ°´çº¿åˆ†é’Ÿæ•°ï¼Œå¦åˆ™å…¶é¡¹ç›®ä¸­å°†ä¸ä¼šè¿è¡Œæ–°çš„作业或æµæ°´çº¿ã€‚"
msgid "Pipelines|The CI configuration was not loaded, please try again."
msgstr "CIé…置未加载,请é‡è¯•ã€‚"
@@ -24423,7 +24579,7 @@ msgid "Pipelines|This project is not currently set up to run pipelines."
msgstr "此项目当å‰æœªé…ç½®è¿è¡Œæµæ°´çº¿ã€‚"
msgid "Pipelines|To keep your codebase simple, readable, and accessible to contributors, use GitLab CI/CD to analyze your code quality with every push to your project."
-msgstr ""
+msgstr "为了使您的代ç åº“ä¿æŒç®€å•ã€å¯è¯»å¹¶å¯ä¾›è´¡çŒ®è€…访问,å¯ä»¥ä½¿ç”¨ GitLab CI/CD æ¥åˆ†æžæ‚¨æ¯æ¬¡æŽ¨é€åˆ°é¡¹ç›®çš„代ç è´¨é‡ã€‚"
msgid "Pipelines|Token"
msgstr "令牌"
@@ -24435,13 +24591,13 @@ msgid "Pipelines|Use a CI/CD template"
msgstr "使用 CI/CD 模æ¿"
msgid "Pipelines|Use a sample %{codeStart}.gitlab-ci.yml%{codeEnd} template file to explore how CI/CD works."
-msgstr ""
+msgstr "使用 %{codeStart}.gitlab-ci.yml%{codeEnd} 模æ¿æ–‡ä»¶æ¥æŽ¢ç´¢CI/CD 如何工作。"
msgid "Pipelines|Use a sample CI/CD template"
-msgstr ""
+msgstr "使用 CI/CD 模æ¿"
msgid "Pipelines|Use a template based on your project's language or framework to get started with GitLab CI/CD."
-msgstr ""
+msgstr "使用基于您的项目语言或框架的模æ¿å¼€å§‹ä½¿ç”¨ GitLab CI/CD。"
msgid "Pipelines|Use template"
msgstr "使用模æ¿"
@@ -24450,7 +24606,7 @@ msgid "Pipelines|Validating GitLab CI configuration…"
msgstr "验è¯GitLab CIé…置中…"
msgid "Pipelines|View merged YAML"
-msgstr ""
+msgstr "查看åˆå¹¶çš„ YAML"
msgid "Pipelines|Visualize"
msgstr "å¯è§†åŒ–"
@@ -24468,13 +24624,13 @@ msgid "Pipeline|Branch name"
msgstr "分支å称"
msgid "Pipeline|Branches or tags could not be loaded."
-msgstr ""
+msgstr "无法加载分支或标签。"
msgid "Pipeline|Canceled"
msgstr "å·²å–消"
msgid "Pipeline|Checking pipeline status"
-msgstr ""
+msgstr "检查æµæ°´çº¿çŠ¶æ€"
msgid "Pipeline|Checking pipeline status."
msgstr "检查æµæ°´çº¿çŠ¶æ€ã€‚"
@@ -24501,7 +24657,7 @@ msgid "Pipeline|Failed"
msgstr "失败"
msgid "Pipeline|In progress"
-msgstr ""
+msgstr "进行中"
msgid "Pipeline|Key"
msgstr "é”®"
@@ -24513,7 +24669,7 @@ msgid "Pipeline|Merge train pipeline"
msgstr "åˆå¹¶é˜Ÿåˆ—æµæ°´çº¿"
msgid "Pipeline|Merge train pipeline jobs can not be retried"
-msgstr ""
+msgstr "åˆå¹¶é˜Ÿåˆ—æµæ°´çº¿ä½œä¸šæ— æ³•é‡è¯•"
msgid "Pipeline|Merged result pipeline"
msgstr "åˆå¹¶ç»“æžœæµæ°´çº¿"
@@ -24531,7 +24687,7 @@ msgid "Pipeline|Pipeline %{idStart}#%{idEnd} %{statusStart}%{statusEnd} for %{co
msgstr ""
msgid "Pipeline|Pipeline cannot be run."
-msgstr ""
+msgstr "æµæ°´çº¿æ— æ³•è¿è¡Œã€‚"
msgid "Pipeline|Pipelines"
msgstr "æµæ°´çº¿"
@@ -24540,7 +24696,7 @@ msgid "Pipeline|Raw text search is not currently supported. Please use the avail
msgstr "ç›®å‰ä¸æ”¯æŒåŽŸå§‹æ–‡æœ¬æœç´¢ã€‚请使用å¯ç”¨çš„æœç´¢ä»¤ç‰Œã€‚"
msgid "Pipeline|Run for branch name or tag"
-msgstr ""
+msgstr "è¿è¡Œåˆ†æ”¯å称或标签"
msgid "Pipeline|Run pipeline"
msgstr "è¿è¡Œæµæ°´çº¿"
@@ -24551,6 +24707,51 @@ msgstr "è¿è¡Œä¸­"
msgid "Pipeline|Skipped"
msgstr "已跳过"
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr "指定è¦åœ¨æ­¤æ¬¡è¿è¡Œä¸­ä½¿ç”¨çš„å˜é‡å€¼ã€‚%{linkStart}CI/CD设置%{linkEnd}中指定的值将用作默认值."
@@ -24594,7 +24795,7 @@ msgid "Pipeline|Variables"
msgstr "å˜é‡"
msgid "Pipeline|View pipeline"
-msgstr ""
+msgstr "查看æµæ°´çº¿"
msgid "Pipeline|We are currently unable to fetch pipeline data"
msgstr "我们目å‰æ— æ³•èŽ·å–æµæ°´çº¿æ•°æ®"
@@ -24615,13 +24816,13 @@ msgid "Pipeline|with stages"
msgstr ",包å«é˜¶æ®µ"
msgid "PivotalTrackerService|Add commit messages as comments to Pivotal Tracker stories."
-msgstr ""
+msgstr "å°†æ交消æ¯ä½œä¸ºè¯„论添加到 Pivotal Tracker 故事。"
msgid "PivotalTrackerService|Comma-separated list of branches to automatically inspect. Leave blank to include all branches."
msgstr "è¦è‡ªåŠ¨æ£€æŸ¥çš„以逗å·åˆ†éš”的分支列表。留空以包括所有分支。"
msgid "PivotalTrackerService|Pivotal Tracker API token. User must have access to the story. All comments are attributed to this user."
-msgstr ""
+msgstr "Pivotal Tracker API 令牌。用户必须有æƒè®¿é—®æ•…事。所有评论都归于该用户。"
msgid "Plain diff"
msgstr "文本差异"
@@ -24678,7 +24879,7 @@ msgid "Please confirm your email address"
msgstr "请确认您的电å­é‚®ä»¶åœ°å€"
msgid "Please contact an admin to register runners."
-msgstr ""
+msgstr "请è”系管ç†å‘˜æ³¨å†ŒRunner。"
msgid "Please contact your GitLab administrator if you think this is an error."
msgstr "如果您认为这是一个错误,请è”系您的GitLab 管ç†å‘˜ã€‚"
@@ -24705,7 +24906,7 @@ msgid "Please create an index before enabling indexing"
msgstr "å¯ç”¨ç´¢å¼•å‰è¯·å…ˆåˆ›å»ºç´¢å¼•"
msgid "Please delete your current license if you want to downgrade to the free plan."
-msgstr ""
+msgstr "如果您想é™çº§åˆ°æ ‡å‡†ç‰ˆï¼Œè¯·åˆ é™¤æ‚¨å½“å‰çš„许å¯è¯ã€‚"
msgid "Please enable and migrate to hashed storage to avoid security issues and ensure data integrity. %{migrate_link}"
msgstr "请å¯ç”¨å¹¶è¿ç§»åˆ°æ•£åˆ—存储以é¿å…安全问题并确ä¿æ•°æ®å®Œæ•´æ€§ã€‚ %{migrate_link}"
@@ -24861,16 +25062,16 @@ msgid "Policies"
msgstr "ç­–ç•¥"
msgid "Policy management project does have any policies in %{policy_path}"
-msgstr ""
+msgstr "策略管ç†é¡¹ç›®çš„任何策略ä½äºŽ%{policy_path}"
msgid "Policy project doesn't exist"
msgstr "策略项目ä¸å­˜åœ¨"
msgid "Polling interval multiplier"
-msgstr ""
+msgstr "轮询间隔å€æ•°"
msgid "Popularity"
-msgstr ""
+msgstr "人气"
msgid "Port"
msgstr "端å£"
@@ -24990,17 +25191,14 @@ msgid "Press %{key}-C to copy"
msgstr "按 %{key}-C å¤åˆ¶"
msgid "Prev"
-msgstr "上一个"
-
-msgid "Prevent MR approvals by author."
-msgstr "ç¦æ­¢ä½œè€…核准MR"
-
-msgid "Prevent MR approvals from users who make commits to the MR."
-msgstr "ç¦æ­¢æ交到MR的用户进行核准。"
+msgstr "上一页"
msgid "Prevent adding new members to project membership within this group"
msgstr "ç¦æ­¢å‘当å‰ç¾¤ç»„中的项目添加新æˆå‘˜"
+msgid "Prevent editing approval rules in projects and merge requests."
+msgstr ""
+
msgid "Prevent environment from auto-stopping"
msgstr "防止环境自动终止"
@@ -25010,9 +25208,6 @@ msgstr "阻止项目派生到当å‰ç¾¤ç»„以外"
msgid "Prevent users from changing their profile name"
msgstr "ç¦æ­¢ç”¨æˆ·æ›´æ”¹é…置文件å称"
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr "阻止用户修改项目和åˆå¹¶è¯·æ±‚中的 MR 核准规则。"
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr "阻止用户在GitLab进行维护时进行写入æ“作。"
@@ -25277,9 +25472,12 @@ msgstr "ä¸åœ¨ä¸ªäººèµ„料中显示与活动相关的个人信æ¯"
msgid "Profiles|Edit Profile"
msgstr "编辑个人资料"
-msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
msgstr ""
+msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
+msgstr "输入您姓åçš„å‘音以帮助人们正确称呼您"
+
msgid "Profiles|Enter your name, so people you know can recognize you"
msgstr "输入您的姓å,以便大家认识您"
@@ -25308,10 +25506,10 @@ msgid "Profiles|GitLab is unable to verify your identity automatically. For secu
msgstr ""
msgid "Profiles|Give your individual key a title. This will be publicly visible."
-msgstr ""
+msgstr "为您的个人密钥命å。这将是公开å¯è§çš„。"
msgid "Profiles|If after setting a password, the option to delete your account is still not available, please email %{data_request} to begin the account deletion process."
-msgstr ""
+msgstr "如果设置密ç åŽï¼Œåˆ é™¤è´¦å·çš„选项ä»ç„¶ä¸å¯ç”¨ï¼Œè¯·å‘é€ç”µå­é‚®ä»¶ %{data_request} 开始账å·åˆ é™¤æµç¨‹ã€‚"
msgid "Profiles|Include private contributions on my profile"
msgstr "在个人资料中包å«éžå…¬å¼€è´¡çŒ®"
@@ -25338,10 +25536,10 @@ msgid "Profiles|Key can still be used after expiration."
msgstr "密钥到期åŽä»å¯ä½¿ç”¨ã€‚"
msgid "Profiles|Key usable beyond expiration date."
-msgstr ""
+msgstr "密钥在过期日期åŽä»å¯ä½¿ç”¨ã€‚"
msgid "Profiles|Key will be deleted on this date."
-msgstr ""
+msgstr "密钥将在此日期被删除。"
msgid "Profiles|Last used:"
msgstr "最近使用:"
@@ -25359,7 +25557,7 @@ msgid "Profiles|Main settings"
msgstr "主è¦è®¾ç½®"
msgid "Profiles|Manage two-factor authentication"
-msgstr ""
+msgstr "管ç†åŒé‡èº«ä»½éªŒè¯"
msgid "Profiles|No file chosen."
msgstr "未选择文件。"
@@ -25386,13 +25584,13 @@ msgid "Profiles|Profile was successfully updated"
msgstr "个人资料已æˆåŠŸæ›´æ–°"
msgid "Profiles|Public avatar"
-msgstr ""
+msgstr "公开头åƒ"
msgid "Profiles|Public email"
msgstr "公开邮件"
msgid "Profiles|Publicly visible private SSH keys can compromise your system."
-msgstr ""
+msgstr "公开å¯è§çš„ç§æœ‰SSH密钥å¯èƒ½ä¼šæŸå®³æ‚¨çš„系统。"
msgid "Profiles|Remove avatar"
msgstr "删除头åƒ"
@@ -25401,7 +25599,7 @@ msgid "Profiles|Set new profile picture"
msgstr "设置新个人资料图片"
msgid "Profiles|Set your local time zone"
-msgstr ""
+msgstr "设置本地时区"
msgid "Profiles|Social sign-in"
msgstr "社交登录"
@@ -25469,9 +25667,6 @@ msgstr "用户å更改æˆåŠŸ"
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr "姓å中使用表情符å·è™½ç„¶æœ‰è¶£ï¼Œä½†è¯·è½¬åˆ°çŠ¶æ€ä¿¡æ¯é‡Œä½¿ç”¨å®ƒ"
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr "您当å‰çš„状æ€ï¼Ÿ"
@@ -25587,7 +25782,7 @@ msgid "Project ID"
msgstr "项目ID"
msgid "Project Templates"
-msgstr ""
+msgstr "项目模æ¿"
msgid "Project URL"
msgstr "项目 URL"
@@ -25596,7 +25791,7 @@ msgid "Project access must be granted explicitly to each user. If this project i
msgstr "项目访问必须明确授予æ¯ä¸ªç”¨æˆ·ã€‚ 如果此项目是在一个群组中,群组æˆå‘˜å°†ä¼šèŽ·å¾—访问æƒé™ã€‚"
msgid "Project access token creation is disabled in this group. You can still use and manage existing tokens. %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "项目访问令牌创建在此群组中被ç¦ç”¨ã€‚您ä»ç„¶å¯ä»¥ä½¿ç”¨å’Œç®¡ç†çŽ°æœ‰ä»¤ç‰Œã€‚ %{link_start}了解更多信æ¯ã€‚%{link_end}"
msgid "Project already deleted"
msgstr "项目已被删除"
@@ -25605,7 +25800,7 @@ msgid "Project and wiki repositories"
msgstr "项目和wiki仓库"
msgid "Project audit events"
-msgstr ""
+msgstr "项目审计事件"
msgid "Project avatar"
msgstr "项目头åƒ"
@@ -25623,13 +25818,13 @@ msgid "Project does not exist or you don't have permission to perform this actio
msgstr "项目ä¸å­˜åœ¨æˆ–您没有æƒé™æ‰§è¡Œæ­¤æ“作"
msgid "Project does not have a policy configuration"
-msgstr ""
+msgstr "项目没有策略é…ç½®"
msgid "Project export could not be deleted."
msgstr "无法删除项目导出。"
msgid "Project export download requests"
-msgstr ""
+msgstr "项目导出下载请求"
msgid "Project export enabled"
msgstr "å¯ç”¨é¡¹ç›®å¯¼å‡º"
@@ -25641,7 +25836,7 @@ msgid "Project export link has expired. Please generate a new export from your p
msgstr "项目导出链接已过期。请从项目设置中é‡æ–°ç”Ÿæˆé¡¹ç›®å¯¼å‡ºã€‚"
msgid "Project export requests"
-msgstr ""
+msgstr "项目导出请求"
msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr "项目导出已ç»å¼€å§‹ã€‚下载链接将通过电å­é‚®ä»¶å‘é€å¹¶åœ¨æ­¤é¡µé¢ä¸Šæ供。"
@@ -25650,13 +25845,13 @@ msgid "Project has too many %{label_for_message} to search"
msgstr "项目有太多个 %{label_for_message} è¦æœç´¢"
msgid "Project import requests"
-msgstr ""
+msgstr "项目导入请求"
msgid "Project info:"
msgstr "项目信æ¯ï¼š"
msgid "Project information"
-msgstr ""
+msgstr "项目信æ¯"
msgid "Project is required when cluster_type is :project"
msgstr "cluster_type为:project时项目为必需"
@@ -25674,7 +25869,7 @@ msgid "Project name suffix"
msgstr "项目å称åŽç¼€"
msgid "Project navigation"
-msgstr ""
+msgstr "项目导航"
msgid "Project order will not be saved as local storage is not available."
msgstr "由于本地存储ä¸å¯ç”¨ï¼Œå› æ­¤ä¸ä¼šä¿å­˜é¡¹ç›®é¡ºåºã€‚"
@@ -25770,106 +25965,106 @@ msgid "ProjectSelect|Search for project"
msgstr "æœç´¢é¡¹ç›®"
msgid "ProjectService|Drone server URL"
-msgstr ""
+msgstr "Drone æœåŠ¡å™¨URL"
msgid "ProjectService|Enter new API key"
-msgstr ""
+msgstr "输入新的 API 密钥"
msgid "ProjectService|Enter new password"
-msgstr ""
+msgstr "输入新密ç "
msgid "ProjectService|Enter new password."
-msgstr ""
+msgstr "输入新密ç ã€‚"
msgid "ProjectService|Issue URL"
-msgstr ""
+msgstr "议题 URL"
msgid "ProjectService|Jenkins server URL"
-msgstr ""
+msgstr "Jenkins æœåŠ¡å™¨ URL"
msgid "ProjectService|Leave blank to use your current API key"
-msgstr ""
+msgstr "留空时,使用您当å‰çš„ API 密钥"
msgid "ProjectService|Leave blank to use your current password"
-msgstr ""
+msgstr "留空时,使用您当å‰çš„密ç "
msgid "ProjectService|Leave blank to use your current password."
-msgstr ""
+msgstr "留空时,使用您当å‰çš„密ç ã€‚"
msgid "ProjectService|Mock service URL"
-msgstr ""
+msgstr "模拟æœåŠ¡URL"
msgid "ProjectService|Must have permission to trigger a manual build in TeamCity."
-msgstr ""
+msgstr "必须具有在 TeamCity 中触å‘手动构建的æƒé™ã€‚"
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr "在GitLab项目上执行常è§æ“作: %{project_name}"
msgid "ProjectService|Run CI/CD pipelines with Buildkite."
-msgstr ""
+msgstr "使用 Buildkite è¿è¡Œ CI/CD æµæ°´çº¿ã€‚"
msgid "ProjectService|Run CI/CD pipelines with Drone."
-msgstr ""
+msgstr "使用 Drone è¿è¡Œ CI/CD 管é“。"
msgid "ProjectService|Run CI/CD pipelines with JetBrains TeamCity."
-msgstr ""
+msgstr "使用 JetBrains TeamCity è¿è¡Œ CI/CD æµæ°´çº¿ã€‚"
msgid "ProjectService|TeamCity server URL"
-msgstr ""
+msgstr "TeamCity æœåŠ¡å™¨ URL"
msgid "ProjectService|The build configuration ID of the TeamCity project."
-msgstr ""
+msgstr "TeamCity 项目的构建é…ç½® ID。"
msgid "ProjectService|The token you get after you create a Buildkite pipeline with a GitLab repository."
-msgstr ""
+msgstr "使用 GitLab 仓库创建 Buildkite æµæ°´çº¿åŽèŽ·å¾—的令牌。"
msgid "ProjectService|To configure this integration, you should:"
-msgstr ""
+msgstr "è¦é…置此集æˆï¼Œæ‚¨åº”该:"
msgid "ProjectService|Token for the Drone project."
-msgstr ""
+msgstr "Drone项目的令牌。"
msgid "ProjectService|Trigger event for new comments on confidential issues."
-msgstr ""
+msgstr "针对ç§å¯†é—®é¢˜çš„新评论触å‘事件。"
msgid "ProjectService|Trigger event for new comments."
-msgstr ""
+msgstr "新评论的触å‘事件。"
msgid "ProjectService|Trigger event for new tags pushed to the repository."
-msgstr ""
+msgstr "推é€åˆ°ä»“库的新标签的触å‘事件。"
msgid "ProjectService|Trigger event for pushes to the repository."
-msgstr ""
+msgstr "推é€åˆ°ä»“库的触å‘事件。"
msgid "ProjectService|Trigger event when a commit is created or updated."
-msgstr ""
+msgstr "在创建或更新æ交时触å‘事件。"
msgid "ProjectService|Trigger event when a confidential issue is created, updated, or closed."
-msgstr ""
+msgstr "在创建ã€æ›´æ–°æˆ–关闭ç§å¯†è®®é¢˜æ—¶è§¦å‘事件。"
msgid "ProjectService|Trigger event when a deployment starts or finishes."
-msgstr ""
+msgstr "在部署开始或完æˆæ—¶è§¦å‘事件。"
msgid "ProjectService|Trigger event when a merge request is created, updated, or merged."
-msgstr ""
+msgstr "在创建ã€æ›´æ–°æˆ–åˆå¹¶åˆå¹¶è¯·æ±‚时触å‘事件。"
msgid "ProjectService|Trigger event when a new, unique alert is recorded."
-msgstr ""
+msgstr "在记录新的ã€å”¯ä¸€çš„警报时触å‘事件。"
msgid "ProjectService|Trigger event when a pipeline status changes."
-msgstr ""
+msgstr "æµæ°´çº¿çŠ¶æ€æ›´æ”¹æ—¶è§¦å‘事件。"
msgid "ProjectService|Trigger event when a wiki page is created or updated."
-msgstr ""
+msgstr "在创建或更新 wiki 页é¢æ—¶è§¦å‘事件。"
msgid "ProjectService|Trigger event when an issue is created, updated, or closed."
-msgstr ""
+msgstr "在创建ã€æ›´æ–°æˆ–关闭议题时触å‘事件。"
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
-msgstr ""
+msgstr "%{link_start}什么是æ述模æ¿ï¼Ÿ%{link_end}"
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
-msgstr ""
+msgstr "å½±å“åˆå¹¶å®Œæˆçš„æ–¹å¼å’Œæ—¶é—´çš„其他设置。"
msgid "ProjectSettings|All discussions must be resolved"
msgstr "所有讨论都必须解决"
@@ -25878,7 +26073,7 @@ msgid "ProjectSettings|Allow"
msgstr "å…许"
msgid "ProjectSettings|Always show thumbs-up and thumbs-down award emoji buttons on issues, merge requests, and snippets."
-msgstr ""
+msgstr "始终在议题ã€åˆå¹¶è¯·æ±‚和代ç ç‰‡æ®µä¸Šæ˜¾ç¤ºèµžè®¸å’Œä¸èµžè®¸è¡¨æƒ…符å·æŒ‰é’®ã€‚"
msgid "ProjectSettings|Analytics"
msgstr "分æž"
@@ -25890,7 +26085,7 @@ msgid "ProjectSettings|Badges"
msgstr "徽章"
msgid "ProjectSettings|Build, test, and deploy your changes."
-msgstr ""
+msgstr "构建ã€æµ‹è¯•å’Œéƒ¨ç½²æ‚¨çš„更改。"
msgid "ProjectSettings|Checkbox is visible and selected by default."
msgstr "默认情况下,å¤é€‰æ¡†æ˜¯å¯è§å’Œé€‰ä¸­çš„。"
@@ -25905,7 +26100,7 @@ msgid "ProjectSettings|Choose your merge method, merge options, merge checks, me
msgstr "选择åˆå¹¶æ–¹æ³•ã€åˆå¹¶é€‰é¡¹ã€åˆå¹¶æ£€æŸ¥ã€åˆå¹¶å»ºè®®ä»¥åŠè®¾ç½®é»˜è®¤åˆå¹¶è¯·æ±‚æ述模æ¿"
msgid "ProjectSettings|Configure your project resources and monitor their health."
-msgstr ""
+msgstr "é…置您的项目资æºå¹¶ç›‘控它们的è¿è¡ŒçŠ¶å†µã€‚"
msgid "ProjectSettings|Contact an admin to change this setting."
msgstr "è”系管ç†å‘˜æ›´æ”¹æ­¤è®¾ç½®ã€‚"
@@ -25917,7 +26112,7 @@ msgid "ProjectSettings|Customize this project's badges."
msgstr "自定义此项目的徽章。"
msgid "ProjectSettings|Determine what happens to the commit history when you merge a merge request."
-msgstr ""
+msgstr "确定åˆå¹¶åˆå¹¶è¯·æ±‚时,æ交历å²è®°å½•ä¼šå‘生什么。"
msgid "ProjectSettings|Disable email notifications"
msgstr "ç¦ç”¨ç”µå­é‚®ä»¶é€šçŸ¥"
@@ -25926,13 +26121,13 @@ msgid "ProjectSettings|Do not allow"
msgstr "ä¸å…许"
msgid "ProjectSettings|Enable \"Delete source branch\" option by default"
-msgstr ""
+msgstr "默认å¯ç”¨â€œåˆ é™¤æºåˆ†æ”¯â€é€‰é¡¹"
msgid "ProjectSettings|Enable merge trains"
-msgstr ""
+msgstr "å¯ç”¨åˆå¹¶é˜Ÿåˆ—"
msgid "ProjectSettings|Enable merged results pipelines"
-msgstr ""
+msgstr "å¯ç”¨åˆå¹¶ç»“æžœæµæ°´çº¿"
msgid "ProjectSettings|Encourage"
msgstr "建议"
@@ -25944,13 +26139,13 @@ msgid "ProjectSettings|Every project can have its own space to store its Docker
msgstr "æ¯ä¸ªé¡¹ç›®éƒ½å¯ä»¥æœ‰è‡ªå·±çš„空间æ¥å­˜å‚¨å…¶Dockeré•œåƒ"
msgid "ProjectSettings|Every project can have its own space to store its packages."
-msgstr ""
+msgstr "æ¯ä¸ªé¡¹ç›®éƒ½å¯ä»¥æœ‰è‡ªå·±çš„空间æ¥å­˜å‚¨å®ƒçš„软件包。"
msgid "ProjectSettings|Everyone"
msgstr "所有人"
msgid "ProjectSettings|Existing merge requests and protected branches are not affected."
-msgstr ""
+msgstr "现有åˆå¹¶è¯·æ±‚å’Œå—ä¿æŠ¤åˆ†æ”¯ä¸å—å½±å“。"
msgid "ProjectSettings|Failed to protect the tag"
msgstr "ä¿æŠ¤æ ‡ç­¾å¤±è´¥"
@@ -25962,10 +26157,10 @@ msgid "ProjectSettings|Fast-forward merge"
msgstr "å¿«è¿›å¼(Fast-forward)åˆå¹¶"
msgid "ProjectSettings|Fast-forward merges only."
-msgstr ""
+msgstr "ä»…å¿«è¿›å¼ï¼ˆFast-forward)åˆå¹¶ã€‚"
msgid "ProjectSettings|Flexible tool to collaboratively develop ideas and plan work in this project."
-msgstr ""
+msgstr "用于在此项目中å作开å‘想法和计划工作的çµæ´»å·¥å…·ã€‚"
msgid "ProjectSettings|Forks"
msgstr "派生"
@@ -25980,16 +26175,16 @@ msgid "ProjectSettings|Internal"
msgstr "内部"
msgid "ProjectSettings|Introduces the risk of merging changes that do not pass the pipeline."
-msgstr ""
+msgstr "介ç»åˆå¹¶æœªé€šè¿‡æµæ°´çº¿çš„更改的风险。"
msgid "ProjectSettings|Issues"
msgstr "议题"
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
-msgstr ""
+msgstr "此仓库中的 LFS 对象å¯ä¾›æ´¾ç”Ÿã€‚ %{linkStart}我如何移除它们?%{linkEnd}"
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
-msgstr ""
+msgstr "管ç†å¤§åž‹æ–‡ä»¶ï¼Œä¾‹å¦‚音频ã€è§†é¢‘和图形文件。"
msgid "ProjectSettings|Merge checks"
msgstr "åˆå¹¶æ£€æŸ¥"
@@ -26010,16 +26205,16 @@ msgid "ProjectSettings|Merge requests"
msgstr "åˆå¹¶è¯·æ±‚"
msgid "ProjectSettings|Merge requests approved for merge are queued, and pipelines validate the combined results of the source and target branches before merge. %{link_start}What are merge trains?%{link_end}"
-msgstr ""
+msgstr "已批准的åˆå¹¶è¯·æ±‚已排队,æµæ°´çº¿åœ¨åˆå¹¶å‰éªŒè¯æºå’Œç›®æ ‡åˆ†æ”¯çš„åˆå¹¶ç»“果。 %{link_start}什么是åˆå¹¶é˜Ÿåˆ—?%{link_end}"
msgid "ProjectSettings|Merge suggestions"
msgstr "åˆå¹¶å»ºè®®"
msgid "ProjectSettings|No merge commits are created."
-msgstr ""
+msgstr "没有创建åˆå¹¶æ交。"
msgid "ProjectSettings|Note: The container registry is always visible when a project is public and the container registry is set to '%{access_level_description}'"
-msgstr ""
+msgstr "注æ„:当项目是公共的并且容器镜åƒåº“设置为“%{access_level_description}â€æ—¶ï¼Œå®¹å™¨é•œåƒåº“始终å¯è§"
msgid "ProjectSettings|Only signed commits can be pushed to this repository."
msgstr "åªæœ‰å·²ç­¾ç½²æ交æ‰å¯ä»¥æŽ¨é€åˆ°æ­¤ä»“库。"
@@ -26028,7 +26223,7 @@ msgid "ProjectSettings|Operations"
msgstr "è¿ç»´"
msgid "ProjectSettings|Override user notification preferences for all project members."
-msgstr ""
+msgstr "覆盖所有项目æˆå‘˜çš„用户通知首选项。"
msgid "ProjectSettings|Packages"
msgstr "软件包"
@@ -26037,7 +26232,7 @@ msgid "ProjectSettings|Pages"
msgstr "Pages"
msgid "ProjectSettings|Pages for project documentation."
-msgstr ""
+msgstr "项目Pages的文档。"
msgid "ProjectSettings|Pipelines must succeed"
msgstr "æµæ°´çº¿å¿…é¡»æˆåŠŸ"
@@ -26058,7 +26253,7 @@ msgid "ProjectSettings|Require"
msgstr "å¿…é¡»"
msgid "ProjectSettings|Require an associated issue from Jira"
-msgstr ""
+msgstr "需è¦æ¥è‡ª Jira 的相关议题"
msgid "ProjectSettings|Requirements"
msgstr "需求"
@@ -26073,7 +26268,7 @@ msgid "ProjectSettings|Security & Compliance for this project"
msgstr "此项目的安全与åˆè§„"
msgid "ProjectSettings|Set the default behavior of this option in merge requests. Changes to this are also applied to existing merge requests."
-msgstr ""
+msgstr "在åˆå¹¶è¯·æ±‚中设置此选项的默认行为。对此的更改也适用于现有的åˆå¹¶è¯·æ±‚。"
msgid "ProjectSettings|Share code with others outside the project."
msgstr "与项目外的其它人共享代ç ã€‚"
@@ -26082,7 +26277,7 @@ msgid "ProjectSettings|Show default award emojis"
msgstr "显示默认的奖励表情符å·"
msgid "ProjectSettings|Show link to create or view a merge request when pushing from the command line"
-msgstr ""
+msgstr "从命令行推é€æ—¶æ˜¾ç¤ºç”¨äºŽåˆ›å»ºæˆ–查看åˆå¹¶è¯·æ±‚的链接"
msgid "ProjectSettings|Skipped pipelines are considered successful"
msgstr "跳过的æµæ°´çº¿è§†ä¸ºæˆåŠŸ"
@@ -26100,7 +26295,7 @@ msgid "ProjectSettings|Squashing is never performed and the checkbox is hidden."
msgstr "永远ä¸ä¼šæ‰§è¡ŒåŽ‹ç¼©ï¼Œå¹¶ä¸”该å¤é€‰æ¡†æ˜¯éšè—的。"
msgid "ProjectSettings|Submit changes to be merged upstream."
-msgstr ""
+msgstr "æ交è¦åˆå¹¶åˆ°ä¸Šæ¸¸çš„更改。"
msgid "ProjectSettings|Supported variables:"
msgstr "支æŒçš„å˜é‡ï¼š"
@@ -26109,13 +26304,13 @@ msgid "ProjectSettings|Target project"
msgstr "目标项目"
msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
-msgstr ""
+msgstr "应用åˆå¹¶è¯·æ±‚建议时使用的æ交消æ¯ã€‚ %{link_start}了解有关建议的更多信æ¯ã€‚%{link_end}"
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
-msgstr ""
+msgstr "在此派生项目中创建的åˆå¹¶è¯·æ±‚的默认目标项目。"
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
-msgstr ""
+msgstr "必须通过这些检查æ‰èƒ½åˆå¹¶åˆå¹¶è¯·æ±‚。"
msgid "ProjectSettings|This project"
msgstr "此项目"
@@ -26130,7 +26325,7 @@ msgid "ProjectSettings|This setting will be applied to all projects unless overr
msgstr "此设置将应用于所有项目,除éžè¢«ç®¡ç†å‘˜è¦†ç›–。"
msgid "ProjectSettings|To enable this feature, configure pipelines. %{link_start}How to configure pipelines for merge requests?%{link_end}"
-msgstr ""
+msgstr "è¦å¯ç”¨æ­¤åŠŸèƒ½ï¼Œè¯·é…ç½®æµæ°´çº¿ã€‚ %{link_start}如何为åˆå¹¶è¯·æ±‚é…ç½®æµæ°´çº¿ï¼Ÿ%{link_end}"
msgid "ProjectSettings|Transfer project"
msgstr "转移项目"
@@ -26139,10 +26334,10 @@ msgid "ProjectSettings|Upstream project"
msgstr "上游项目"
msgid "ProjectSettings|Used for every new merge request."
-msgstr ""
+msgstr "用于æ¯ä¸ªæ–°çš„åˆå¹¶è¯·æ±‚。"
msgid "ProjectSettings|Users can copy the repository to a new project."
-msgstr ""
+msgstr "用户å¯ä»¥å°†ä»“库å¤åˆ¶åˆ°æ–°é¡¹ç›®ã€‚"
msgid "ProjectSettings|Users can only push commits to this repository that were committed with one of their own verified emails."
msgstr "用户åªèƒ½é€šè¿‡è‡ªå·±å·²éªŒè¯çš„电å­é‚®ä»¶åœ°å€å°†æ交到此仓库中。"
@@ -26154,31 +26349,31 @@ msgid "ProjectSettings|View and edit files in this project."
msgstr "查看和编辑此项目中的文件。"
msgid "ProjectSettings|View and edit files in this project. Non-project members will only have read access."
-msgstr ""
+msgstr "查看和编辑此项目中的文件。éžé¡¹ç›®æˆå‘˜å°†åªæœ‰è¯»å–æƒé™ã€‚"
msgid "ProjectSettings|View project analytics."
msgstr "查看项目分æžã€‚"
msgid "ProjectSettings|Visibility options for this fork are limited by the current visibility of the source project."
-msgstr ""
+msgstr "此派生的å¯è§æ€§é€‰é¡¹å—æºé¡¹ç›®å½“å‰å¯è§æ€§çš„é™åˆ¶ã€‚"
msgid "ProjectSettings|Visualize the project's performance metrics."
-msgstr ""
+msgstr "å¯è§†åŒ–项目的性能指标。"
msgid "ProjectSettings|What are badges?"
msgstr "什么是徽章?"
msgid "ProjectSettings|When pipelines for merge requests are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure pipelines for merge requests?%{link_end}"
-msgstr ""
+msgstr "在 CI/CD é…置文件中å¯ç”¨åˆå¹¶è¯·æ±‚çš„æµæ°´çº¿æ—¶ï¼Œæµæ°´çº¿ä¼šéªŒè¯æºåˆ†æ”¯å’Œç›®æ ‡åˆ†æ”¯çš„组åˆç»“果。 %{link_start}如何为åˆå¹¶è¯·æ±‚é…ç½®æµæ°´çº¿ï¼Ÿ%{link_end}"
msgid "ProjectSettings|When there is a merge conflict, the user is given the option to rebase."
-msgstr ""
+msgstr "当出现åˆå¹¶å†²çªæ—¶ï¼Œç”¨æˆ·å¯ä»¥é€‰æ‹©å˜åŸºï¼ˆrebase)。"
msgid "ProjectSettings|Wiki"
msgstr "Wiki"
msgid "ProjectSettings|With GitLab Pages you can host your static websites on GitLab."
-msgstr ""
+msgstr "使用GitLab Pages,您å¯ä»¥åœ¨GitLab上托管é™æ€ç½‘站。"
msgid "ProjectTemplates|.NET Core"
msgstr ".NET Core"
@@ -26271,7 +26466,7 @@ msgid "Projects are graded based on the highest severity vulnerability present"
msgstr "按项目所包å«æœ€é«˜å±é™©ç¨‹åº¦å®‰å…¨æ¼æ´žåˆ†çº§"
msgid "Projects contributed to"
-msgstr ""
+msgstr "贡献的项目"
msgid "Projects shared with %{group_name}"
msgstr "与 %{group_name} 共享的项目"
@@ -26343,7 +26538,7 @@ msgid "ProjectsNew|Create a blank project to house your files, plan your work, a
msgstr "创建一个空白项目æ¥å­˜æ”¾æ‚¨çš„文件,规划您的工作,并在代ç ç­‰æ–¹é¢è¿›è¡Œå作。"
msgid "ProjectsNew|Create a project pre-populated with the necessary files to get you started quickly."
-msgstr ""
+msgstr "创建一个预先填充了必è¦æ–‡ä»¶çš„项目,以帮助您快速入门。"
msgid "ProjectsNew|Create blank project"
msgstr "创建空白项目"
@@ -26457,7 +26652,7 @@ msgid "PrometheusService|Common metrics are automatically monitored based on a l
msgstr "常用指标会根æ®åº”用广泛的导出器指标库自动监控。"
msgid "PrometheusService|Configure GitLab to query a Prometheus installed in one of your clusters."
-msgstr ""
+msgstr "é…ç½® GitLab 以查询安装在您的集群之一中的 Prometheus。"
msgid "PrometheusService|Custom metrics"
msgstr "自定义指标"
@@ -26475,7 +26670,7 @@ msgid "PrometheusService|Finding custom metrics..."
msgstr "查找自定义指标..."
msgid "PrometheusService|IAP_CLIENT_ID.apps.googleusercontent.com"
-msgstr ""
+msgstr "IAP_CLIENT_ID.apps.googleusercontent.com"
msgid "PrometheusService|Manage clusters"
msgstr "管ç†é›†ç¾¤"
@@ -26490,7 +26685,7 @@ msgid "PrometheusService|Missing environment variable"
msgstr "无环境å˜é‡"
msgid "PrometheusService|Monitor application health with Prometheus metrics and dashboards"
-msgstr ""
+msgstr "使用 Prometheus 指标和仪表æ¿ç›‘控应用程åºè¿è¡ŒçŠ¶å†µ"
msgid "PrometheusService|More information"
msgstr "更多的信æ¯"
@@ -26508,37 +26703,37 @@ msgid "PrometheusService|Prometheus cluster integration"
msgstr "Prometheus集群集æˆ"
msgid "PrometheusService|PrometheusService|The ID of the IAP-secured resource."
-msgstr ""
+msgstr "IAP 安全资æºçš„ ID。"
msgid "PrometheusService|Select this checkbox to override the auto configuration settings with your own settings."
-msgstr ""
+msgstr "选中此å¤é€‰æ¡†å¯ä½¿ç”¨æ‚¨è‡ªå·±çš„设置覆盖自动é…置设置。"
msgid "PrometheusService|The Prometheus API base URL."
msgstr "Prometheus API 基本 URL。"
msgid "PrometheusService|The contents of the credentials.json file of your service account."
-msgstr ""
+msgstr "您的æœåŠ¡å¸æˆ·çš„credentials.json文件的内容。"
msgid "PrometheusService|These metrics will only be monitored after your first deployment to an environment"
msgstr "在首次部署到环境之åŽ, 这些指标æ‰ä¼šè¢«ç›‘控"
msgid "PrometheusService|To use a Prometheus installed on a cluster, deactivate the manual configuration."
-msgstr ""
+msgstr "è¦ä½¿ç”¨å®‰è£…在集群上的 Prometheus,请åœç”¨æ‰‹åŠ¨é…置。"
msgid "PrometheusService|Waiting for your first deployment to an environment to find common metrics"
msgstr "等待首次部署到环境以查找常用指标"
msgid "PrometheusService|You can now manage your Prometheus settings on the %{operations_link_start}Operations%{operations_link_end} page. Fields on this page have been deprecated."
-msgstr ""
+msgstr "您现在å¯ä»¥åœ¨ %{operations_link_start}è¿ç»´%{operations_link_end} 页é¢ä¸Šç®¡ç†æ‚¨çš„ Prometheus 设置。此页é¢ä¸Šçš„字段已被弃用。"
msgid "PrometheusService|You have a cluster with the Prometheus integration enabled."
-msgstr ""
+msgstr "您有一个å¯ç”¨äº† Prometheus 集æˆçš„集群。"
msgid "PrometheusService|https://prometheus.example.com/"
-msgstr ""
+msgstr "https://prometheus.example.com/"
msgid "PrometheusService|{ \"type\": \"service_account\", \"project_id\": ... }"
-msgstr ""
+msgstr "{ \"type\": \"service_account\", \"project_id\": ... }"
msgid "Promote"
msgstr "å‡çº§"
@@ -26570,11 +26765,8 @@ msgstr "ä¸æ”¯æŒå‡çº§ã€‚"
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
-msgstr ""
+msgstr "更好的å—ä¿æŠ¤çš„分支"
msgid "Promotions|Burndown Charts are visual representations of the progress of completing a milestone. At a glance, you see the current state for the completion a given milestone. Without them, you would have to organize the data from the milestone and plot it yourself to have the same sense of progress."
msgstr "燃尽图是里程碑完æˆè¿›åº¦çš„视觉呈现。通过燃尽图,您å¯ä»¥é©¬ä¸Šç›´è§‚了解对应的里程碑的完æˆè¿›åº¦ã€‚没有燃尽图的è¯ï¼Œæ‚¨éœ€è¦è‡ªå·±ä»Žé‡Œç¨‹ç¢‘æœé›†æ•°æ®æ¥åˆ¶ä½œè¡¨è¾¾åŒæ ·å«ä¹‰çš„进度图。"
@@ -26613,43 +26805,46 @@ msgid "Promotions|Improve issues management with Issue weight and GitLab Enterpr
msgstr "使用GitLabä¼ä¸šç‰ˆä¸­è®®é¢˜æƒé‡å¸¦æ¥çš„增强议题管ç†åŠŸèƒ½ã€‚"
msgid "Promotions|Improve merge requests and customer support with GitLab Enterprise Edition."
-msgstr ""
+msgstr "使用æžç‹GitLab改进åˆå¹¶è¯·æ±‚和客户支æŒã€‚"
msgid "Promotions|Improve milestones with Burndown Charts."
msgstr "通过燃尽图增强里程碑。"
msgid "Promotions|Improve repositories with GitLab Enterprise Edition."
-msgstr ""
+msgstr "使用æžç‹GitLabæå‡ä»“库能力。"
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
+msgstr "使用高级æœç´¢å’Œæžç‹GitLabæå‡æœç´¢èƒ½åŠ›ã€‚"
+
+msgid "Promotions|Keep track of events in your project"
msgstr ""
msgid "Promotions|Learn more"
msgstr "了解更多"
msgid "Promotions|Merge request approvals"
-msgstr ""
+msgstr "åˆå¹¶è¯·æ±‚批准"
msgid "Promotions|Not now, thanks!"
msgstr "æš‚æ—¶ä¸ç”¨ï¼Œè°¢è°¢ï¼"
msgid "Promotions|Push Rules"
-msgstr ""
+msgstr "推é€è§„则"
msgid "Promotions|Push Rules are defined per project so you can have different rules applied to different projects depends on your needs."
-msgstr ""
+msgstr "推é€è§„则是按æ¯ä¸ªé¡¹ç›®å®šä¹‰çš„,因此您å¯ä»¥æ ¹æ®æ‚¨çš„需è¦ï¼Œå¯¹ä¸åŒçš„项目适用ä¸åŒçš„规则。"
msgid "Promotions|Repository Mirroring"
-msgstr ""
+msgstr "仓库镜åƒ"
msgid "Promotions|Repository Mirroring is a way to mirror repositories from external sources. It can be used to mirror all branches, tags, and commits that you have in your repository."
-msgstr ""
+msgstr "仓库镜åƒæ˜¯ä¸€ç§ä»Žå¤–部æºé•œåƒä»“库的方法。它å¯ç”¨äºŽé•œåƒä»“库中的所有分支ã€æ ‡ç­¾å’Œæ交。"
msgid "Promotions|See the other features in the %{subscription_link_start}Premium plan%{subscription_link_end}"
-msgstr ""
+msgstr "查看 %{subscription_link_start}专业版%{subscription_link_end} 中的其它功能"
msgid "Promotions|Set the number of necessary approvals and define a list of approvers needed for every merge request in a project."
-msgstr ""
+msgstr "设置必è¦çš„批准数é‡å¹¶å®šä¹‰é¡¹ç›®ä¸­æ¯ä¸ªåˆå¹¶è¯·æ±‚所需的批准者列表。"
msgid "Promotions|Start GitLab Ultimate trial"
msgstr "å¯åŠ¨GitLab Ultimate试用"
@@ -26663,9 +26858,6 @@ msgstr "此功能已é”定"
msgid "Promotions|Track activity with Contribution Analytics."
msgstr "使用贡献分æžè·Ÿè¸ªæ´»åŠ¨ã€‚"
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr "å…费试用"
@@ -26673,25 +26865,25 @@ msgid "Promotions|Upgrade plan"
msgstr "å‡çº§è®¢é˜…计划"
msgid "Promotions|Upgrade your plan to activate Advanced Search."
-msgstr ""
+msgstr "å‡çº§æ‚¨çš„方案以激活高级æœç´¢ã€‚"
msgid "Promotions|Upgrade your plan to activate Audit Events."
-msgstr ""
+msgstr "å‡çº§æ‚¨çš„方案以激活审计事件。"
msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
msgstr "å‡çº§æ‚¨çš„订阅计划以å¯ç”¨è´¡çŒ®åº¦åˆ†æžã€‚"
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
-msgstr ""
+msgstr "å‡çº§æ‚¨çš„方案以激活群组Webhooks。"
msgid "Promotions|Upgrade your plan to improve merge requests."
-msgstr ""
+msgstr "å‡çº§æ‚¨çš„方案以æå‡åˆå¹¶è¯·æ±‚功能。"
msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
msgstr "å‡çº§ä½ çš„订阅计划,以使用燃尽图æ¥å¢žå¼ºé‡Œç¨‹ç¢‘。"
msgid "Promotions|Upgrade your plan to improve repositories."
-msgstr ""
+msgstr "å‡çº§æ‚¨çš„方案以æå‡ä»“库功能。"
msgid "Promotions|Webhooks allow you to trigger a URL if, for example, new code is pushed or a new issue is created. You can configure webhooks to listen for specific events like pushes, issues or merge requests. Group webhooks will apply to all projects in a group, allowing you to standardize webhook functionality across your entire group."
msgstr ""
@@ -26712,7 +26904,7 @@ msgid "Promotions|You can restrict access to protected branches by choosing a ro
msgstr ""
msgid "Promotions|description templates"
-msgstr ""
+msgstr "æ述模æ¿"
msgid "Promotions|to help your contributors communicate effectively!"
msgstr ""
@@ -26745,7 +26937,7 @@ msgid "Protected Paths"
msgstr "å—ä¿æŠ¤çš„路径"
msgid "Protected Paths: requests"
-msgstr ""
+msgstr "å—ä¿æŠ¤çš„路径:请求"
msgid "Protected Tag"
msgstr "å—ä¿æŠ¤çš„标签"
@@ -26799,10 +26991,10 @@ msgid "ProtectedBranch|Code owner approval"
msgstr "代ç æ‰€æœ‰è€…批准"
msgid "ProtectedBranch|Does not apply to users allowed to push. Optional sections are not enforced."
-msgstr ""
+msgstr "ä¸é€‚用于å…许推é€çš„用户。ä¸å¼ºåˆ¶æ‰§è¡Œå¯é€‰éƒ¨åˆ†ã€‚"
msgid "ProtectedBranch|Keep stable branches secure and force developers to use merge requests."
-msgstr ""
+msgstr "ä¿æŒç¨³å®šçš„分支安全并强制开å‘人员使用åˆå¹¶è¯·æ±‚。"
msgid "ProtectedBranch|Learn more."
msgstr "了解更多。"
@@ -26820,7 +27012,7 @@ msgid "ProtectedBranch|Protected branches"
msgstr "å—ä¿æŠ¤åˆ†æ”¯"
msgid "ProtectedBranch|Reject code pushes that change files listed in the CODEOWNERS file."
-msgstr ""
+msgstr "æ‹’ç»ä»£ç æŽ¨é€æ›´æ”¹ CODEOWNERS 文件中列出的文件。"
msgid "ProtectedBranch|Require approval from code owners:"
msgstr "需è¦ä»£ç æ‰€æœ‰è€…的批准:"
@@ -26847,7 +27039,7 @@ msgid "ProtectedEnvironment|Environment"
msgstr "环境"
msgid "ProtectedEnvironment|Only specified users can execute deployments in a protected environment."
-msgstr ""
+msgstr "åªæœ‰æŒ‡å®šçš„用户æ‰èƒ½åœ¨å—ä¿æŠ¤çš„环境中执行部署。"
msgid "ProtectedEnvironment|Protect"
msgstr "ä¿æŠ¤"
@@ -26880,13 +27072,13 @@ msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr "环境已ç»ä¸è¢«ä¿æŠ¤"
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
-msgstr ""
+msgstr "默认情况下,å—ä¿æŠ¤çš„分支会é™åˆ¶è°å¯ä»¥ä¿®æ”¹æ ‡ç­¾ã€‚"
msgid "ProtectedTag|Learn more."
msgstr "了解更多。"
msgid "ProtectedTag|Limit access to creating and updating tags."
-msgstr ""
+msgstr "é™åˆ¶åˆ›å»ºå’Œæ›´æ–°æ ‡ç­¾çš„访问。"
msgid "ProtectedTag|Protected tags"
msgstr "å—ä¿æŠ¤çš„标签"
@@ -26895,7 +27087,7 @@ msgid "ProtectedTag|What are protected tags?"
msgstr "什么是å—ä¿æŠ¤çš„标签?"
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
-msgstr ""
+msgstr "æ示:%{linkStart}Auto DevOps%{linkEnd} 使用 Kubernetes 集群æ¥éƒ¨ç½²æ‚¨çš„代ç ï¼"
msgid "Provider"
msgstr "æ供者"
@@ -26997,28 +27189,28 @@ msgid "Push to create a project"
msgstr "通过推é€åˆ›å»ºé¡¹ç›®"
msgid "PushRules|All branch names must match this %{wiki_syntax_link_start}regular expression%{wiki_syntax_link_end}. If empty, any branch name is allowed."
-msgstr ""
+msgstr "所有分支å称必须与此 %{wiki_syntax_link_start}正则表达å¼%{wiki_syntax_link_end}匹é…。如果为空,则å…许任何分支å称。"
msgid "PushRules|All commit author's email must match this %{wiki_syntax_link_start}regular expression%{wiki_syntax_link_end}. If empty, any email is allowed."
-msgstr ""
+msgstr "所有æ交作者的电å­é‚®ä»¶å¿…须与此 %{wiki_syntax_link_start}正则表达å¼%{wiki_syntax_link_end}匹é…。如果为空,则å…许任何电å­é‚®ä»¶ã€‚"
msgid "PushRules|All commit messages must match this %{wiki_syntax_link_start}regular expression%{wiki_syntax_link_end}. If empty, commit messages are not required to match any expression."
-msgstr ""
+msgstr "所有æ交消æ¯å¿…须匹é…这个 %{wiki_syntax_link_start}正则表达å¼%{wiki_syntax_link_end}。如果为空,则æ交消æ¯ä¸éœ€è¦åŒ¹é…任何表达å¼ã€‚"
msgid "PushRules|All committed filenames cannot match this %{wiki_syntax_link_start}regular expression%{wiki_syntax_link_end}. If empty, any filename is allowed."
-msgstr ""
+msgstr "所有æ交的文件å都ä¸èƒ½åŒ¹é…这个 %{wiki_syntax_link_start}正则表达å¼%{wiki_syntax_link_end}。如果为空,则å…许使用任何文件å。"
msgid "PushRules|Commit messages cannot match this %{wiki_syntax_link_start}regular expression%{wiki_syntax_link_end}. If empty, commit messages are not rejected based on any expression."
-msgstr ""
+msgstr "æ交消æ¯ä¸èƒ½åŒ¹é…这个 %{wiki_syntax_link_start}正则表达å¼%{wiki_syntax_link_end}。如果为空,则ä¸ä¼šæ ¹æ®ä»»ä½•è¡¨è¾¾å¼æ‹’ç»æ交消æ¯ã€‚"
msgid "PushRules|Do not allow users to remove Git tags with %{code_block_start}git push%{code_block_end}"
-msgstr ""
+msgstr "ä¸å…许用户使用 %{code_block_start}git push%{code_block_end}时删除Git标签。"
msgid "PushRules|Reject any files likely to contain secrets. %{secret_files_link_start}What secret files are rejected?%{secret_files_link_end}"
-msgstr ""
+msgstr "æ‹’ç»ä»»ä½•å¯èƒ½åŒ…å« secret 的文件。 %{secret_files_link_start}哪些 secret 文件会被拒ç»ï¼Ÿ%{secret_files_link_end}"
msgid "PushRules|Reject file sizes equal to or greater than this size. If set to 0, files of any size are allowed. This rule does not apply to files tracked by Git LFS."
-msgstr ""
+msgstr "æ‹’ç»ç­‰äºŽæˆ–大于此大å°çš„文件。如果设置为 0,则å…许任何大å°çš„文件。此规则ä¸é€‚用于 Git LFS 跟踪的文件。"
msgid "PushRules|Restrict commits to existing GitLab users."
msgstr "é™åˆ¶å¯¹çŽ°æœ‰ GitLab 用户的æ交。"
@@ -27057,28 +27249,28 @@ msgid "PushoverService|%{user_name} pushed new branch \"%{ref}\"."
msgstr "%{user_name} 已推é€æ–°åˆ†æ”¯ \"%{ref}\"。"
msgid "PushoverService|Enter your application key."
-msgstr ""
+msgstr "输入您的应用程åºå¯†é’¥ã€‚"
msgid "PushoverService|Enter your user key."
-msgstr ""
+msgstr "输入您的用户密钥。"
msgid "PushoverService|Get real-time notifications on your device."
-msgstr ""
+msgstr "在您的设备上获å–实时通知。"
msgid "PushoverService|High priority"
-msgstr ""
+msgstr "高优先级"
msgid "PushoverService|Leave blank for all active devices."
-msgstr ""
+msgstr "留空为所有活动设备."
msgid "PushoverService|Low priority"
-msgstr ""
+msgstr "低优先级"
msgid "PushoverService|Lowest priority"
-msgstr ""
+msgstr "最低优先级"
msgid "PushoverService|Normal priority"
-msgstr ""
+msgstr "正常优先级"
msgid "PushoverService|See project %{project_full_name}"
msgstr "å‚è§é¡¹ç›® %{project_full_name}"
@@ -27102,7 +27294,7 @@ msgid "Queued"
msgstr "队列中"
msgid "Quick actions can be used in description and comment boxes."
-msgstr ""
+msgstr "å¯ä»¥åœ¨æ述和评论框中使用快速æ“作。"
msgid "Quick help"
msgstr "快速帮助"
@@ -27126,10 +27318,10 @@ msgid "Random"
msgstr "éšæœº"
msgid "Rate Limits"
-msgstr ""
+msgstr "速率é™åˆ¶"
msgid "Rate limit"
-msgstr ""
+msgstr "速率é™åˆ¶"
msgid "Raw blob request rate limit per minute"
msgstr "æ¯åˆ†é’ŸåŽŸå§‹Blob请求速率é™åˆ¶"
@@ -27144,7 +27336,7 @@ msgid "Re-authentication required"
msgstr "需è¦é‡æ–°è®¤è¯"
msgid "Re-request review"
-msgstr ""
+msgstr "é‡æ–°è¯·æ±‚审核"
msgid "Re-verification interval"
msgstr "é‡æ–°éªŒè¯é—´éš”"
@@ -27156,7 +27348,7 @@ msgid "Read more"
msgstr "进一步了解"
msgid "Read more about GitLab at %{link_to_promo}."
-msgstr ""
+msgstr "在%{link_to_promo}上阅读更多关于 GitLab çš„ä¿¡æ¯ã€‚"
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr "于%{help_link_open}此处%{help_link_close}了解有关项目æƒé™çš„更多信æ¯"
@@ -27165,11 +27357,17 @@ msgid "Read more about related issues"
msgstr "了解更多关于相关议题的信æ¯"
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
+msgstr "准备好开始使用 GitLab 了å—?按照以下步骤设置您的工作区ã€è®¡åˆ’å’Œæ交更改以åŠéƒ¨ç½²æ‚¨çš„项目。"
+
+msgid "Ready to merge by members who can write to the target branch."
msgstr ""
-msgid "Reauthenticating with SAML provider."
+msgid "Ready to merge!"
msgstr ""
+msgid "Reauthenticating with SAML provider."
+msgstr "正在与 SAML æ供商é‡æ–°éªŒè¯ã€‚"
+
msgid "Rebase"
msgstr "å˜åŸº"
@@ -27189,7 +27387,7 @@ msgid "Receive alerts from manually configured Prometheus servers."
msgstr "从手动é…置的 Prometheus æœåŠ¡å™¨æŽ¥æ”¶è­¦æŠ¥ã€‚"
msgid "Receive any notifications from GitLab."
-msgstr ""
+msgstr "接收æ¥è‡ª GitLab 的任何通知。"
msgid "Receive notifications about your own activity"
msgstr "接收关于您自己活动的通知"
@@ -27201,7 +27399,7 @@ msgid "Recent"
msgstr "最近"
msgid "Recent Deliveries"
-msgstr ""
+msgstr "最近传é€"
msgid "Recent Project Activity"
msgstr "最近的项目动æ€"
@@ -27236,6 +27434,9 @@ msgstr "é‡å®šå‘中"
msgid "Redis"
msgstr "Redis"
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr "é™ä½Žé¡¹ç›®å¯è§æ€§"
@@ -27298,7 +27499,7 @@ msgid "Register WebAuthn Device"
msgstr "注册WebAuthn设备"
msgid "Register as many runners as you want. You can register runners as separate users, on separate servers, and on your local machine. Runners are either:"
-msgstr ""
+msgstr "注册尽å¯èƒ½å¤šçš„runner。您å¯ä»¥ä»¥å•ç‹¬çš„用户,或者在ä¸åŒçš„æœåŠ¡å™¨æˆ–者本地计算机上注册runner。runnerå¯ä»¥æ˜¯ï¼š"
msgid "Register device"
msgstr "注册设备"
@@ -27313,7 +27514,7 @@ msgid "Register with two-factor app"
msgstr "使用åŒé‡è®¤è¯åº”用注册"
msgid "Registration Features include:"
-msgstr ""
+msgstr "注册功能包括:"
msgid "Registration|Checkout"
msgstr "支付"
@@ -27331,7 +27532,7 @@ msgid "Registry setup"
msgstr "é•œåƒåº“设置"
msgid "Regulate approvals by authors/committers. Affects all projects."
-msgstr ""
+msgstr "监管作者/æ交者的批准。影å“所有项目。"
msgid "Reindexing Status: %{status} (Slice multiplier: %{multiplier}, Maximum running slices: %{max_slices})"
msgstr ""
@@ -27340,7 +27541,7 @@ msgid "Rejected (closed)"
msgstr "已拒ç»(关闭)"
msgid "Related feature flags"
-msgstr ""
+msgstr "相关的功能标志"
msgid "Related issues"
msgstr "相关议题"
@@ -27348,6 +27549,9 @@ msgstr "相关议题"
msgid "Related merge requests"
msgstr "相关åˆå¹¶è¯·æ±‚"
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr "å…³è”到"
@@ -27374,7 +27578,7 @@ msgid "Release title"
msgstr "å‘布标题"
msgid "Release with tag \"%{tag}\" was not found"
-msgstr ""
+msgstr "找ä¸åˆ°å¸¦æ ‡ç­¾ä¸ºâ€œ%{tag}â€çš„版本"
msgid "ReleaseAssetLinkType|Image"
msgstr "é•œåƒ"
@@ -27416,13 +27620,13 @@ msgid "Releases|New Release"
msgstr "新版本"
msgid "Release|Something went wrong while creating a new release."
-msgstr ""
+msgstr "创建新å‘布时出错。"
msgid "Release|Something went wrong while getting the release details."
-msgstr ""
+msgstr "获å–å‘布详情时出现问题。"
msgid "Release|Something went wrong while saving the release details."
-msgstr ""
+msgstr "ä¿å­˜å‘布详细信æ¯æ—¶å‡ºé”™ã€‚"
msgid "Remediations"
msgstr "ä¿®å¤æŽªæ–½"
@@ -27491,7 +27695,7 @@ msgid "Remove due date"
msgstr "删除截止日期"
msgid "Remove favicon"
-msgstr ""
+msgstr "删除图标"
msgid "Remove file"
msgstr "删除文件"
@@ -27677,7 +27881,7 @@ msgid "Rename/Move"
msgstr "é‡å‘½å/移动"
msgid "Render diagrams in your documents using PlantUML."
-msgstr ""
+msgstr "使用 PlantUML 在您的文档中渲染图表。"
msgid "Renew subscription"
msgstr "续订"
@@ -27799,7 +28003,7 @@ msgid "Reports|An error occurred while loading report"
msgstr "加载报告时出错"
msgid "Reports|Base report parsing error:"
-msgstr ""
+msgstr "基础报告分æžé”™è¯¯ï¼š"
msgid "Reports|Classname"
msgstr "ç±»å"
@@ -27822,7 +28026,7 @@ msgid "Reports|Filename"
msgstr "文件å"
msgid "Reports|Head report parsing error:"
-msgstr ""
+msgstr "HEAD 报告解æžé”™è¯¯ï¼š"
msgid "Reports|Identifier"
msgstr "标识符"
@@ -27857,6 +28061,9 @@ msgstr "测试总结报告加载失败"
msgid "Reports|Test summary results are being parsed"
msgstr "测试总结报告解æžä¸­"
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr "æ¼æ´ž"
@@ -27900,7 +28107,7 @@ msgid "RepositoriesAnalytics|Historic Test Coverage Data is available in raw for
msgstr "历å²æµ‹è¯•è¦†ç›–率数æ®åŽŸå§‹æ ¼å¼(.csv)已就绪,å¯ä¾›è¿›ä¸€æ­¥åˆ†æžã€‚"
msgid "RepositoriesAnalytics|Jobs with Coverage"
-msgstr ""
+msgstr "覆盖范围内的作业"
msgid "RepositoriesAnalytics|Last Update"
msgstr "最新更新"
@@ -27918,7 +28125,7 @@ msgid "RepositoriesAnalytics|Please select projects to display."
msgstr "请选择è¦æ˜¾ç¤ºçš„项目。"
msgid "RepositoriesAnalytics|Projects with Coverage"
-msgstr ""
+msgstr "覆盖范围内的项目"
msgid "RepositoriesAnalytics|Test Code Coverage"
msgstr "测试代ç è¦†ç›–率"
@@ -27948,7 +28155,7 @@ msgid "Repository check was triggered."
msgstr "已触å‘仓库检查。"
msgid "Repository checks"
-msgstr ""
+msgstr "仓库检查"
msgid "Repository cleanup"
msgstr "仓库清ç†"
@@ -27981,7 +28188,7 @@ msgid "Repository mirroring"
msgstr "仓库镜åƒ"
msgid "Repository mirroring configuration"
-msgstr ""
+msgstr "仓库镜åƒé…ç½®"
msgid "Repository must contain at least 1 file."
msgstr "仓库必须包å«è‡³å°‘1个文件。"
@@ -27996,7 +28203,7 @@ msgid "Repository synchronization concurrency limit"
msgstr "仓库åŒæ­¥å¹¶å‘é™åˆ¶"
msgid "Repository update events"
-msgstr ""
+msgstr "仓库更新事件"
msgid "Repository: %{counter_repositories} / Wikis: %{counter_wikis} / Build Artifacts: %{counter_build_artifacts} / LFS: %{counter_lfs_objects} / Snippets: %{counter_snippets} / Packages: %{counter_packages} / Uploads: %{counter_uploads}"
msgstr "仓库: %{counter_repositories} /Wikis: %{counter_wikis} /构建产物: %{counter_build_artifacts} /LFS: %{counter_lfs_objects} /代ç ç‰‡æ®µ: %{counter_snippets} /软件包: %{counter_packages} /上传: %{counter_uploads}"
@@ -28008,13 +28215,13 @@ msgid "Request Access"
msgstr "申请æƒé™"
msgid "Request a new one"
-msgstr ""
+msgstr "请求一个新的"
msgid "Request details"
msgstr "请求详情"
msgid "Request new confirmation email"
-msgstr ""
+msgstr "请求新的确认电å­é‚®ä»¶"
msgid "Request parameter %{param} is missing."
msgstr "请求å‚æ•°%{param}缺失。"
@@ -28023,7 +28230,7 @@ msgid "Request review from"
msgstr "请求审核æ¥è‡ª"
msgid "Request time"
-msgstr ""
+msgstr "请求时间"
msgid "Request to link SAML account must be authorized"
msgstr "链接SAMLå¸æˆ·çš„请求必须ç»è¿‡æŽˆæƒ"
@@ -28038,7 +28245,7 @@ msgid "Requested design version does not exist."
msgstr "请求的设计版本ä¸å­˜åœ¨."
msgid "Requested review"
-msgstr ""
+msgstr "请求审核"
msgid "Requested states are invalid"
msgstr "请求的状æ€æ— æ•ˆ"
@@ -28053,16 +28260,16 @@ msgid "Requests for pages at %{code_start}%{help_text_url}%{code_end} redirect t
msgstr ""
msgid "Requests per period"
-msgstr ""
+msgstr "æ¯ä¸ªå‘¨æœŸçš„请求"
msgid "Requests to these domain(s)/address(es) on the local network will be allowed when local requests from hooks and services are not allowed. IP ranges such as 1:0:0:0:0:0:0:0/124 or 127.0.0.0/28 are supported. Domain wildcards are not supported currently. Use comma, semicolon, or newline to separate multiple entries. The allowlist can hold a maximum of 1000 entries. Domains should use IDNA encoding. Ex: example.com, 192.168.1.1, 127.0.0.0/28, xn--itlab-j1a.com."
msgstr "当ä¸å…许æ¥è‡ªé’©å­å’ŒæœåŠ¡çš„本地请求时,将å…许对本地网络上这些域/地å€çš„请求。å¯æ”¯æŒIP范围,例如1:0:0:0:0:0:0:0/124或127.0.0.0/28。当å‰ä¸æ”¯æŒåŸŸé€šé…符。多个æ¡ç›®éœ€ä½¿ç”¨é€—å·ï¼Œåˆ†å·æˆ–æ¢è¡Œç¬¦åˆ†éš”。å…许åå•æœ€å¤šå¯å®¹çº³1000个æ¡ç›®ã€‚域应使用IDNAç¼–ç ã€‚例如:example.com,192.168.1.1ã€127.0.0.0/28, xn--itlab-j1a.com。"
msgid "Require additional authentication for administrative tasks."
-msgstr ""
+msgstr "需è¦å¯¹ç®¡ç†ä»»åŠ¡è¿›è¡Œé¢å¤–的身份验è¯ã€‚"
msgid "Require all users in this group to setup Two-factor authentication"
-msgstr ""
+msgstr "è¦æ±‚此群组中的所有用户都设置åŒé‡èº«ä»½éªŒè¯"
msgid "Require all users in this group to setup two-factor authentication"
msgstr "è¦æ±‚此群组中的所有用户都å¯ç”¨åŒé‡è®¤è¯"
@@ -28109,10 +28316,10 @@ msgid "Requires values to meet regular expression requirements."
msgstr "需è¦å€¼åŒ¹é…正则表达å¼ã€‚"
msgid "Requires your primary GitLab email address."
-msgstr ""
+msgstr "需è¦æ‚¨çš„主GitLab电å­é‚®ä»¶åœ°å€ã€‚"
msgid "Resend"
-msgstr ""
+msgstr "é‡æ–°å‘é€"
msgid "Resend Request"
msgstr "é‡æ–°å‘é€è¯·æ±‚"
@@ -28127,7 +28334,7 @@ msgid "Resend it"
msgstr "é‡æ–°å‘é€"
msgid "Resend unlock instructions"
-msgstr ""
+msgstr "é‡æ–°å‘é€è§£é”说明"
msgid "Reset"
msgstr "é‡ç½®"
@@ -28148,13 +28355,13 @@ msgid "Reset key"
msgstr "é‡ç½®å¯†é’¥"
msgid "Reset link will be generated and sent to the user. %{break} User will be forced to set the password on first sign in."
-msgstr ""
+msgstr "将生æˆé‡ç½®é“¾æŽ¥å¹¶å‘é€ç»™ç”¨æˆ·ã€‚ %{break} 用户将被迫在首次登录时设置密ç ã€‚"
msgid "Reset password"
-msgstr ""
+msgstr "é‡ç½®å¯†ç "
msgid "Reset registration token"
-msgstr ""
+msgstr "é‡ç½®æ³¨å†Œä»¤ç‰Œ"
msgid "Reset template"
msgstr "é‡ç½®æ¨¡æ¿"
@@ -28226,7 +28433,7 @@ msgid "Response metrics (NGINX)"
msgstr "å“应指标(NGINX)"
msgid "Response text"
-msgstr ""
+msgstr "å“应文本"
msgid "Restart Terminal"
msgstr "é‡å¯ç»ˆç«¯"
@@ -28268,7 +28475,7 @@ msgid "Retry job"
msgstr "é‡è¯•ä½œä¸š"
msgid "Retry migration"
-msgstr ""
+msgstr "é‡è¯•è¿ç§»"
msgid "Retry this job"
msgstr "é‡è¯•å½“å‰ä½œä¸š"
@@ -28301,11 +28508,14 @@ msgstr "查看应用"
msgid "Review App|View latest app"
msgstr "查看最新应用"
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr "æ¥è‡ª%{name}的审核请求"
msgid "Review requests for you"
-msgstr ""
+msgstr "审核您的请求"
msgid "Review the changes locally"
msgstr "在本地查看更改"
@@ -28314,7 +28524,7 @@ msgid "Review the process for configuring service providers in your identity pro
msgstr "查看在您的身份验è¯æ供商中é…ç½®æœåŠ¡æ供商的æµç¨‹ - 在这里,GitLab是“æœåŠ¡æ供商â€æˆ–“ä¾èµ–æ–¹â€ã€‚"
msgid "Review the target project before submitting to avoid exposing %{source} changes."
-msgstr ""
+msgstr "在æ交å‰å®¡æŸ¥ç›®æ ‡é¡¹ç›®ï¼Œä»¥é¿å…暴露 %{source} 的更改。"
msgid "Review time"
msgstr "审核时间"
@@ -28357,10 +28567,10 @@ msgid "Revoked project access token %{project_access_token_name}!"
msgstr "撤销项目访问令牌%{project_access_token_name}ï¼"
msgid "RightSidebar|Copy email address"
-msgstr ""
+msgstr "å¤åˆ¶ç”µå­é‚®ä»¶åœ°å€"
msgid "RightSidebar|Issue email"
-msgstr ""
+msgstr "å‘邮件"
msgid "RightSidebar|adding a"
msgstr "添加"
@@ -28369,7 +28579,7 @@ msgid "RightSidebar|deleting the"
msgstr "删除"
msgid "Rnners|Don't see what you are looking for? See the full list of options, including a fully customizable option, %{linkStart}here%{linkEnd}."
-msgstr ""
+msgstr "没看到您è¦å¯»æ‰¾çš„?%{linkStart}点击此处%{linkEnd}查看完整的选项列表,包括完全å¯å®šåˆ¶çš„选项。"
msgid "Roadmap"
msgstr "路线图"
@@ -28393,16 +28603,16 @@ msgid "Rules that define what git pushes are accepted for a project. All newly c
msgstr "定义项目所接å—çš„git推é€è§„则。所有新创建的项目都将使用这些设置。"
msgid "Run %{code_start}git fsck%{code_end} periodically in all project and wiki repositories to look for silent disk corruption issues."
-msgstr ""
+msgstr "在所有项目和 wiki 存储库中定期è¿è¡Œ %{code_start}git fsck%{code_end}"
msgid "Run CI/CD pipelines for external repositories"
msgstr "使用外部仓库的CI/CDæµæ°´çº¿"
msgid "Run CI/CD pipelines with Jenkins when you push to a repository, or when a merge request is created, updated, or merged. %{docs_link}"
-msgstr ""
+msgstr "当您推é€åˆ°ä»“库时,或者当一个åˆå¹¶è¯·æ±‚被创建ã€æ›´æ–°æˆ–åˆå¹¶æ—¶ï¼Œä½¿ç”¨ Jenkins è¿è¡ŒCI/CD æµæ°´çº¿ã€‚ %{docs_link}"
msgid "Run CI/CD pipelines with Jenkins."
-msgstr ""
+msgstr "使用 Jenkins è¿è¡Œ CI/CD æµæ°´çº¿ã€‚"
msgid "Run housekeeping"
msgstr "è¿è¡Œä¾‹è¡Œç»´æŠ¤"
@@ -28417,7 +28627,7 @@ msgid "Run untagged jobs"
msgstr "è¿è¡Œæœªæ ‡è®°çš„作业"
msgid "Runner API"
-msgstr ""
+msgstr "Runner API"
msgid "Runner tokens"
msgstr "Runner令牌"
@@ -28435,10 +28645,10 @@ msgid "Runners"
msgstr "Runner"
msgid "Runners are processes that pick up and execute CI/CD jobs for GitLab."
-msgstr ""
+msgstr "Runner用于接收和执行GitLab的CI/CD作业的进程。"
msgid "Runners can be:"
-msgstr ""
+msgstr "Runnerå¯ä»¥æ˜¯ï¼š"
msgid "Runners currently online: %{active_runners_count}"
msgstr "当å‰åœ¨çº¿Runner: %{active_runners_count}"
@@ -28456,7 +28666,7 @@ msgid "Runners|Amazon Linux 2 Docker HA with manual scaling and optional schedul
msgstr ""
msgid "Runners|An error has occurred fetching instructions"
-msgstr ""
+msgstr "获å–指令时å‘生错误"
msgid "Runners|Architecture"
msgstr "架构"
@@ -28492,7 +28702,7 @@ msgid "Runners|For each solution, you will choose a capacity. 1 enables warm HA
msgstr ""
msgid "Runners|Group Runners"
-msgstr ""
+msgstr "群组Runner"
msgid "Runners|IP Address"
msgstr "IP地å€"
@@ -28567,55 +28777,58 @@ msgid "Runners|Runner registration"
msgstr "Runner 注册"
msgid "Runners|Runners"
+msgstr "Runner"
+
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
msgstr ""
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
-msgstr ""
+msgstr "共享Runnerå¯ç”¨äºŽ GitLab 实例中的æ¯ä¸ªé¡¹ç›®ã€‚如果您希望Runner仅构建特定项目,请é™åˆ¶ä¸‹è¡¨ä¸­çš„项目。当é™åˆ¶Runner的特定项目åŽï¼Œæ‚¨æ— æ³•å°†å…¶æ”¹å›žå…±äº«Runner。"
msgid "Runners|Show Runner installation instructions"
-msgstr ""
+msgstr "显示Runner安装说明"
msgid "Runners|Something went wrong while fetching runner data."
-msgstr ""
+msgstr "获å–Runneræ•°æ®æ—¶å‡ºé”™ã€‚"
msgid "Runners|Something went wrong while fetching the tags suggestions"
-msgstr ""
+msgstr "获å–标签建议时出现问题"
msgid "Runners|Stop the runner from accepting new jobs."
-msgstr ""
+msgstr "åœæ­¢ Runner 接收新的作业。"
msgid "Runners|Tags"
msgstr "标签"
msgid "Runners|This runner is associated with one or more projects."
-msgstr ""
+msgstr "æ­¤Runner与一个或多个项目相关è”。"
msgid "Runners|This runner is associated with specific projects."
msgstr "æ­¤Runner与特定项目相关è”。"
msgid "Runners|This runner is available to all groups and projects in your GitLab instance."
-msgstr ""
+msgstr "此Runner适用于您的 GitLab 实例中的所有群组和项目。"
msgid "Runners|This runner is available to all projects and subgroups in a group."
-msgstr ""
+msgstr "æ­¤Runner适用于一个群组中的所有项目和å­ç¾¤ç»„。"
msgid "Runners|To install Runner in Kubernetes follow the instructions described in the GitLab documentation."
-msgstr ""
+msgstr "è¦åœ¨ Kubernetes 中安装Runner,请éµå¾ª GitLab 文档中æ述的说明。"
msgid "Runners|To install Runner in a container follow the instructions described in the GitLab documentation"
-msgstr ""
+msgstr "è¦åœ¨å®¹å™¨ä¸­å®‰è£…Runner,请éµå¾ª GitLab 文档中æ述的说明。"
msgid "Runners|Use Group runners when you want all projects in a group to have access to a set of runners."
-msgstr ""
+msgstr "当您希望群组中的所有项目都å¯ä»¥è®¿é—®ä¸€ç»„Runner时,请使用群组Runner。"
msgid "Runners|Use the runner for jobs without tags, in addition to tagged jobs."
-msgstr ""
+msgstr "除了带标签的作业外,还å¯ä»¥å°†Runner用于没有标签的作业。"
msgid "Runners|Use the runner for the currently assigned projects only."
-msgstr ""
+msgstr "ä»…å°†Runner用于当å‰åˆ†é…的项目。"
msgid "Runners|Use the runner on pipelines for protected branches only."
-msgstr ""
+msgstr "åªä¸ºå—ä¿æŠ¤çš„分支使用æµæ°´çº¿ä¸Šçš„Runner。"
msgid "Runners|Value"
msgstr "值"
@@ -28624,7 +28837,7 @@ msgid "Runners|Version"
msgstr "版本"
msgid "Runners|View installation instructions"
-msgstr ""
+msgstr "查看安装说明"
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. %{percentage} spot."
msgstr ""
@@ -28632,9 +28845,12 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
-msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
msgstr ""
+msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
+msgstr "您å¯ä»¥è®¾ç½®ä¸€ä¸ªç‰¹å®šçš„Runner供多个项目使用,但是您ä¸èƒ½è®©å®ƒæˆä¸ºä¸€ä¸ªå…±äº«çš„Runner。"
+
msgid "Runners|You have used %{quotaUsed} out of %{quotaLimit} of your shared Runners pipeline minutes."
msgstr "您已使用了%{quotaUsed},超出了共享æµæ°´çº¿æ—¶é—´é…é¢é™åˆ¶ï¼ˆ%{quotaLimit} )。"
@@ -28642,16 +28858,16 @@ msgid "Runners|group"
msgstr "群组"
msgid "Runners|instance"
-msgstr ""
+msgstr "实例"
msgid "Runners|locked"
-msgstr ""
+msgstr "å·²é”定"
msgid "Runners|paused"
-msgstr ""
+msgstr "已暂åœ"
msgid "Runners|project"
-msgstr ""
+msgstr "项目"
msgid "Runners|shared"
msgstr "共享"
@@ -28666,10 +28882,10 @@ msgid "Runs a number of housekeeping tasks within the current repository, such a
msgstr "在当å‰ä»“库中è¿è¡Œä¸€äº›ä¾‹è¡Œç»´æŠ¤ä»»åŠ¡ï¼Œä¾‹å¦‚压缩文件修订和删除无法访问的对象。"
msgid "Runs jobs from all unassigned projects in its group."
-msgstr ""
+msgstr "从所在群组的所有未分é…项目中执行任务。"
msgid "Runs jobs from all unassigned projects."
-msgstr ""
+msgstr "从所有未分é…项目中执行任务。"
msgid "Runs jobs from assigned projects."
msgstr "è¿è¡ŒæŒ‡å®šé¡¹ç›®çš„作业。"
@@ -28738,22 +28954,22 @@ msgid "SSL verification"
msgstr "SSL 验è¯"
msgid "SVG illustration"
-msgstr ""
+msgstr "SVG图形"
msgid "SastEntryPoints|Add Security Testing"
-msgstr ""
+msgstr "添加安全测试"
msgid "SastEntryPoints|Catch your security vulnerabilities ahead of time!"
-msgstr ""
+msgstr "æå‰æŠ“ä½å®‰å…¨æ¼æ´žï¼"
msgid "SastEntryPoints|GitLab can scan your code for security vulnerabilities. Static Application Security Testing (SAST) helps you worry less and build more."
-msgstr ""
+msgstr "GitLab å¯ä»¥æ‰«æ您的代ç ä»¥æŸ¥æ‰¾å®‰å…¨æ¼æ´žã€‚SAST å¯å¸®åŠ©æ‚¨å‡å°‘担心,增加构建。"
msgid "SastEntryPoints|How do I set up SAST?"
-msgstr ""
+msgstr "如何设置 SAST?"
msgid "SastEntryPoints|Learn more."
-msgstr ""
+msgstr "了解更多。"
msgid "Satisfied"
msgstr "满足"
@@ -28795,7 +29011,7 @@ msgid "Save pipeline schedule"
msgstr "ä¿å­˜æµæ°´çº¿è®¡åˆ’"
msgid "Save space and find images in the container Registry. remove unneeded tags and keep only the ones you want. %{linkStart}How does cleanup work?%{linkEnd}"
-msgstr ""
+msgstr "ä¿ç•™ç©ºé—´å¹¶åœ¨å®¹å™¨é•œåƒåº“中找到镜åƒã€‚删除ä¸éœ€è¦çš„标签,仅ä¿ç•™æ‚¨æƒ³è¦çš„。%{linkStart}清ç†å¦‚何工作?%{linkEnd}"
msgid "Saving"
msgstr "ä¿å­˜ä¸­"
@@ -28807,10 +29023,10 @@ msgid "Scanner"
msgstr "扫æ工具"
msgid "Scanner profile failed to delete"
-msgstr ""
+msgstr "扫æ工具é…置文件删除失败"
msgid "Scanner profile not found for given parameters"
-msgstr ""
+msgstr "找ä¸åˆ°æŒ‡å®šå‚数的扫æ工具é…置文件"
msgid "Schedule a new pipeline"
msgstr "新建æµæ°´çº¿è®¡åˆ’"
@@ -28825,7 +29041,7 @@ msgid "Scheduled Deletion At - %{permanent_deletion_time}"
msgstr "计划删除于 - %{permanent_deletion_time}"
msgid "Scheduled a rebase of branch %{branch}."
-msgstr ""
+msgstr "计划了分支%{branch}çš„å˜åŸºï¼ˆrebase)。"
msgid "Scheduled pipelines cannot run more frequently than once per %{limit} minutes. A pipeline configured to run more frequently only starts after %{limit} minutes have elapsed since the last time it ran."
msgstr ""
@@ -28846,13 +29062,13 @@ msgid "Scope"
msgstr "范围"
msgid "Scope board to current iteration"
-msgstr ""
+msgstr "范围æ¿åˆ°å½“å‰è¿­ä»£"
msgid "Scopes"
msgstr "范围"
msgid "Scopes (select at least one)"
-msgstr ""
+msgstr "范围(至少选择一项)"
msgid "Scopes can't be blank"
msgstr "范围ä¸èƒ½ä¸ºç©º"
@@ -28882,7 +29098,7 @@ msgid "Search"
msgstr "æœç´¢"
msgid "Search GitLab"
-msgstr ""
+msgstr "æœç´¢ GitLab"
msgid "Search Jira issues"
msgstr "æœç´¢Jira议题"
@@ -29087,9 +29303,6 @@ msgstr[0] "wiki结果"
msgid "Searching by both author and message is currently not supported."
msgstr "ç›®å‰ä¸æ”¯æŒä½œè€…和消æ¯åŒæ—¶æœç´¢ã€‚"
-msgid "SeatUsage|Seat usage"
-msgstr "席ä½ä½¿ç”¨æƒ…况"
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr "席ä½ä½¿ç”¨æƒ…况数æ®ï¼Œæˆªè‡³ %{last_enqueue_time} (æ¯å¤©æ›´æ–°ï¼‰"
@@ -29100,7 +29313,7 @@ msgid "Secondary"
msgstr "次è¦"
msgid "Secondary email:"
-msgstr ""
+msgstr "次è¦é‚®ç®±ï¼š"
msgid "Seconds"
msgstr "秒"
@@ -29112,10 +29325,10 @@ msgid "Secret Detection"
msgstr "密ç æ£€æµ‹"
msgid "Secret token"
-msgstr ""
+msgstr "Secret令牌"
msgid "Secure token that identifies an external storage request."
-msgstr ""
+msgstr "识别外部存储请求的安全令牌。"
msgid "Security"
msgstr "安全"
@@ -29141,50 +29354,50 @@ msgstr "安全报告已过时。请使用目标分支(%{targetBranchName})中的
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr "安全报告已过时。请在目标分支(%{targetBranchName})上è¿è¡Œ%{newPipelineLinkStart}æ–°çš„æµæ°´çº¿%{newPipelineLinkEnd}"
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
-msgstr ""
+msgstr "当测试覆盖率下é™æ—¶éœ€è¦åˆå¹¶è¯·æ±‚批准。"
msgid "SecurityApprovals|A merge request approval is required when the license compliance report contains a denied license."
-msgstr ""
+msgstr "当许å¯è¯åˆè§„性报告包å«åˆ—å…¥ç¦æ­¢åå•çš„许å¯è¯æ—¶ï¼Œåˆå¹¶è¯·æ±‚批准为必需。"
msgid "SecurityApprovals|Configurable if security scanners are enabled. %{linkStart}Learn more.%{linkEnd}"
msgstr "如果å¯ç”¨äº†å®‰å…¨æ‰«æ程åºï¼Œåˆ™å¯é…置。 %{linkStart}了解更多。%{linkEnd}"
msgid "SecurityApprovals|Coverage-Check"
-msgstr ""
+msgstr "覆盖范围检查"
msgid "SecurityApprovals|Learn more about Coverage-Check"
-msgstr ""
+msgstr "了解更多关于覆盖范围检查的信æ¯"
msgid "SecurityApprovals|Learn more about License-Check"
-msgstr ""
+msgstr "了解更多关于许å¯è¯æ£€æŸ¥çš„ä¿¡æ¯"
msgid "SecurityApprovals|Learn more about Vulnerability-Check"
-msgstr ""
+msgstr "了解更多关于æ¼æ´žæ£€æŸ¥çš„ä¿¡æ¯"
msgid "SecurityApprovals|License Scanning must be enabled. %{linkStart}Learn more%{linkEnd}."
msgstr "å¿…é¡»å¯ç”¨è®¸å¯è¯æ‰«æ。 %{linkStart}了解更多%{linkEnd}."
msgid "SecurityApprovals|License-Check"
-msgstr ""
+msgstr "许å¯è¯æ£€æŸ¥"
msgid "SecurityApprovals|Requires approval for Denied licenses. %{linkStart}More information%{linkEnd}"
msgstr "当结果中包å«æ‹’ç»çš„许å¯è¯æ—¶æ ¸å‡†ä¸ºå¿…须。%{linkStart}更多信æ¯%{linkEnd}"
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
-msgstr ""
+msgstr "需è¦å®¡æ ¸æ‰èƒ½å‡å°‘测试覆盖范围。 %{linkStart}更多信æ¯%{linkEnd}"
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
-msgstr "需è¦æ‰¹å‡†ä¸¥é‡ã€é«˜æˆ–未知严é‡æ€§çš„æ¼æ´žã€‚ %{linkStart}了解更多。%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
-msgstr ""
+msgstr "å¿…é¡»å¯ç”¨æµ‹è¯•è¦†ç›–范围。%{linkStart}了解更多%{linkEnd}。"
msgid "SecurityApprovals|Vulnerability-Check"
-msgstr ""
+msgstr "æ¼æ´žæ£€æŸ¥"
msgid "SecurityConfiguration|%{featureName} merge request creation mutation failed"
msgstr ""
@@ -29235,13 +29448,13 @@ msgid "SecurityConfiguration|Enable %{feature}"
msgstr "å¯ç”¨ %{feature}"
msgid "SecurityConfiguration|Enable Auto DevOps"
-msgstr ""
+msgstr "å¯ç”¨Auto DevOps"
msgid "SecurityConfiguration|Enabled"
msgstr "å¯ç”¨"
msgid "SecurityConfiguration|High-level vulnerability statistics across projects and groups"
-msgstr ""
+msgstr "跨项目和群组的高级别æ¼æ´žç»Ÿè®¡"
msgid "SecurityConfiguration|Immediately begin risk analysis and remediation with application security features. Start with SAST and Secret Detection, available to all plans. Upgrade to Ultimate to get all features, including:"
msgstr ""
@@ -29253,13 +29466,13 @@ msgid "SecurityConfiguration|Manage scans"
msgstr "管ç†æ‰«æ"
msgid "SecurityConfiguration|More scan types, including Container Scanning, DAST, Dependency Scanning, Fuzzing, and Licence Compliance"
-msgstr ""
+msgstr "更多扫æ类型,包括容器扫æ,DAST,ä¾èµ–扫æ,模糊和许å¯è¯åˆè§„。"
msgid "SecurityConfiguration|Not enabled"
msgstr "未å¯ç”¨"
msgid "SecurityConfiguration|Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
+msgstr "一旦您å¯ç”¨äº†é»˜è®¤åˆ†æ”¯æ‰«æ,éšåŽåˆ›å»ºçš„任何功能分支将包括扫æ。"
msgid "SecurityConfiguration|Quickly enable all continuous testing and compliance tools by enabling %{linkStart}Auto DevOps%{linkEnd}"
msgstr ""
@@ -29274,73 +29487,142 @@ msgid "SecurityConfiguration|SAST Configuration"
msgstr "SASTé…ç½®"
msgid "SecurityConfiguration|Secure your project"
-msgstr ""
+msgstr "ä¿æŠ¤æ‚¨çš„项目"
msgid "SecurityConfiguration|Security testing"
msgstr "安全测试"
msgid "SecurityConfiguration|The status of the tools only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}."
-msgstr ""
+msgstr "工具的状æ€ä»…适用于默认分支,并基于 %{linkStart}最新æµæ°´çº¿%{linkEnd}。"
msgid "SecurityConfiguration|Upgrade or start a free trial"
-msgstr ""
+msgstr "å‡çº§æˆ–开始å…费试用"
msgid "SecurityConfiguration|Using custom settings. You won't receive automatic updates on this variable. %{anchorStart}Restore to default%{anchorEnd}"
msgstr "使用自定义设置。您ä¸ä¼šæ”¶åˆ°æ­¤å˜é‡çš„自动更新。 %{anchorStart}还原到默认%{anchorEnd}"
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
+msgstr "åˆå¹¶è¯·æ±‚中的æ¼æ´žè¯¦ç»†ä¿¡æ¯å’Œç»Ÿè®¡"
+
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
msgstr ""
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
+msgstr "分é…您的安全策略项目时出错"
+
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
msgstr ""
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
+msgstr "åªæœ‰æ‰€æœ‰è€…å¯ä»¥æ›´æ–°å®‰å…¨ç­–略项目"
+
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Description"
-msgstr "æè¿°"
+msgid "SecurityOrchestration|Scan Execution"
+msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
-msgstr "强制执行状æ€"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
+msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
-msgstr "最新扫æ"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgstr "安全策略项目已æˆåŠŸè¿žæŽ¥"
-msgid "SecurityPolicies|Network"
-msgstr "网络"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgstr "选择一个项目æ¥å­˜å‚¨æ‚¨çš„安全策略。 %{linkStart}更多信æ¯ã€‚%{linkEnd}"
+
+msgid "SecurityOrchestration|Select security project"
+msgstr "选择安全项目"
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
msgstr ""
-msgid "SecurityPolicies|Policy type"
-msgstr "策略类型"
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
-msgid "SecurityPolicies|Scan execution"
-msgstr "扫æ执行"
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
-msgid "SecurityPolicies|view results"
-msgstr "查看结果"
+msgid "SecurityPolicies|Environment(s)"
+msgstr "环境"
+
+msgid "SecurityPolicies|Policy type"
+msgstr "策略类型"
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr "%{firstProject}和%{secondProject}"
@@ -29355,10 +29637,10 @@ msgid "SecurityReports|Add projects"
msgstr "添加项目"
msgid "SecurityReports|All activity"
-msgstr ""
+msgstr "所有活动"
msgid "SecurityReports|Although it's rare to have no vulnerabilities, it can happen. Check your settings to make sure you've set up your dashboard correctly."
-msgstr ""
+msgstr "虽然没有æ¼æ´žçš„情况很少è§ï¼Œä½†å®ƒå¯èƒ½ä¼šå‘生。检查您的设置以确ä¿æ‚¨å·²æ­£ç¡®è®¾ç½®ä»ªè¡¨æ¿ã€‚"
msgid "SecurityReports|At GitLab, we're all about iteration and feedback. That's why we are reaching out to customers like you to help guide what we work on this year for Vulnerability Management. We have a lot of exciting ideas and ask that you assist us by taking a short survey %{boldStart}no longer than 10 minutes%{boldEnd} to evaluate a few of our potential features."
msgstr ""
@@ -29376,10 +29658,7 @@ msgid "SecurityReports|Comment edited on '%{vulnerabilityName}'"
msgstr "在'%{vulnerabilityName}' 上的评论已编辑"
msgid "SecurityReports|Configure security testing"
-msgstr ""
-
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
+msgstr "é…置安全测试"
msgid "SecurityReports|Create Jira issue"
msgstr "创建 Jira 议题"
@@ -29403,7 +29682,7 @@ msgid "SecurityReports|Download results"
msgstr "下载结果"
msgid "SecurityReports|Download scanned resources"
-msgstr ""
+msgstr "下载扫æ资æº"
msgid "SecurityReports|Either you don't have permission to view this dashboard or the dashboard has not been setup. Please check your permission settings with your administrator or check your dashboard configurations to proceed."
msgstr "您无æƒæŸ¥çœ‹æ­¤ä»ªè¡¨æ¿æˆ–尚未设置仪表æ¿ã€‚请å‘管ç†å‘˜æŸ¥è¯¢æ‚¨çš„æƒé™è®¾ç½®ï¼Œæˆ–检查仪表æ¿é…置以继续。"
@@ -29418,7 +29697,7 @@ msgid "SecurityReports|Error fetching the vulnerability list. Please check your
msgstr "获å–æ¼æ´žåˆ—表时出错。请检查您的网络连接,然åŽé‡è¯•ã€‚"
msgid "SecurityReports|Error parsing security reports"
-msgstr ""
+msgstr "解æžå®‰å…¨æŠ¥å‘Šæ—¶å‡ºé”™"
msgid "SecurityReports|Failed to get security report information. Please reload the page or try again later."
msgstr "无法获å–安全报告信æ¯ã€‚请é‡æ–°åŠ è½½é¡µé¢æˆ–ç¨åŽå†è¯•ã€‚"
@@ -29436,25 +29715,25 @@ msgid "SecurityReports|Learn more about setting up your dashboard"
msgstr "了解更多关于仪表æ¿åˆ›å»ºçš„ä¿¡æ¯"
msgid "SecurityReports|Manage and track vulnerabilities identified in projects within your group. Vulnerabilities in projects are shown here when security testing is configured."
-msgstr ""
+msgstr "管ç†å’Œè·Ÿè¸ªæ‚¨ç»„内项目中å‘现的æ¼æ´žã€‚é…置安全测试时,此处显示项目中的æ¼æ´žã€‚"
msgid "SecurityReports|Manage and track vulnerabilities identified in your project. Vulnerabilities are shown here when security testing is configured."
-msgstr ""
+msgstr "管ç†å’Œè·Ÿè¸ªæ‚¨çš„项目中å‘现的æ¼æ´žã€‚é…置安全测试时,此处会显示æ¼æ´žã€‚"
msgid "SecurityReports|Manage and track vulnerabilities identified in your selected projects. Vulnerabilities for selected projects with security testing configured are shown here."
-msgstr ""
+msgstr "管ç†å’Œè·Ÿè¸ªåœ¨æ‚¨é€‰æ‹©çš„项目中å‘现的æ¼æ´žã€‚此处显示了é…置了安全测试的选定项目的æ¼æ´žã€‚"
msgid "SecurityReports|Maximum selected projects limit reached"
-msgstr ""
+msgstr "已达到最大选定项目é™åˆ¶"
msgid "SecurityReports|Monitor vulnerabilities in all of your projects"
msgstr "监控您所有项目中的æ¼æ´ž"
msgid "SecurityReports|Monitor vulnerabilities in your group"
-msgstr ""
+msgstr "监控您的群组中的æ¼æ´ž"
msgid "SecurityReports|Monitor vulnerabilities in your project"
-msgstr ""
+msgstr "监控您的项目中的æ¼æ´ž"
msgid "SecurityReports|Monitored projects"
msgstr "监控的项目"
@@ -29463,10 +29742,10 @@ msgid "SecurityReports|More info"
msgstr "更多信æ¯"
msgid "SecurityReports|No activity"
-msgstr ""
+msgstr "无动æ€"
msgid "SecurityReports|No longer detected"
-msgstr ""
+msgstr "ä¸å†æ£€æµ‹"
msgid "SecurityReports|No vulnerabilities found"
msgstr "未å‘现æ¼æ´ž"
@@ -29492,9 +29771,6 @@ msgstr "从仪表æ¿åˆ é™¤é¡¹ç›®"
msgid "SecurityReports|Scan details"
msgstr "扫æ详情"
-msgid "SecurityReports|Scanner"
-msgstr "扫æ工具"
-
msgid "SecurityReports|Security Dashboard"
msgstr "安全仪表æ¿"
@@ -29505,19 +29781,19 @@ msgid "SecurityReports|Security reports help page link"
msgstr "安全报告帮助页é¢é“¾æŽ¥"
msgid "SecurityReports|Security scans have run"
-msgstr ""
+msgstr "安全扫æå·²è¿è¡Œ"
msgid "SecurityReports|Select a project to add by using the project search field above."
msgstr "请使用上é¢çš„项目æœç´¢å­—段æ¥é€‰æ‹©è¦æ·»åŠ çš„项目。"
msgid "SecurityReports|Set status"
-msgstr ""
+msgstr "设置状æ€"
msgid "SecurityReports|Severity"
msgstr "严é‡ç¨‹åº¦"
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
-msgstr ""
+msgstr "有时扫æ工具无法确定调查结果的严é‡æ€§ï¼Œè¿™äº›ç»“æžœå¯èƒ½ä»ç„¶æ˜¯æ½œåœ¨çš„风险æ¥æºï¼Œè¯·æ‰‹åŠ¨æŸ¥çœ‹"
msgid "SecurityReports|Sorry, your filter produced no results"
msgstr "对ä¸èµ·ï¼Œæ²¡æœ‰ç¬¦åˆç­›é€‰å™¨çš„任何结果"
@@ -29526,10 +29802,10 @@ msgid "SecurityReports|Status"
msgstr "状æ€"
msgid "SecurityReports|Take survey"
-msgstr ""
+msgstr "å‚加调查"
msgid "SecurityReports|The security reports below contain one or more vulnerability findings that could not be parsed and were not recorded. Download the artifacts in the job output to investigate. Ensure any security report created conforms to the relevant %{helpPageLinkStart}JSON schema%{helpPageLinkEnd}."
-msgstr ""
+msgstr "下é¢çš„安全报告包å«ä¸€ä¸ªæˆ–多个无法解æžä¸”未记录的æ¼æ´žå‘现。下载作业输出中的产物以进行调查。确ä¿åˆ›å»ºçš„任何安全报告都符åˆç›¸å…³çš„ %{helpPageLinkStart}JSON schema%{helpPageLinkEnd}。"
msgid "SecurityReports|There was an error adding the comment."
msgstr "添加评论时出错。"
@@ -29561,6 +29837,9 @@ msgstr "生æˆæŠ¥å‘Šæ—¶å‡ºé”™ã€‚"
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr "è¦æ‰©å¤§æœç´¢èŒƒå›´ï¼Œè¯·æ›´æ”¹æˆ–删除上é¢çš„筛选器。"
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr "无法添加%{invalidProjectsMessage}: %{errorMessage}"
@@ -29571,13 +29850,13 @@ msgid "SecurityReports|Undo dismiss"
msgstr "å–消忽略"
msgid "SecurityReports|Upgrade to interact, track and shift left with vulnerability management features in the UI."
-msgstr ""
+msgstr "å‡çº§ä»¥ä¾¿åœ¨UI中使用æ¼æ´žç®¡ç†åŠŸèƒ½è¿›è¡Œäº¤äº’ã€è·Ÿè¸ªå’Œç§»åŠ¨ã€‚"
msgid "SecurityReports|Upgrade to manage vulnerabilities"
-msgstr ""
+msgstr "å‡çº§ä»¥ç®¡ç†æ¼æ´ž"
msgid "SecurityReports|Vulnerability Management feature survey"
-msgstr ""
+msgstr "æ¼æ´žç®¡ç†åŠŸèƒ½è°ƒæŸ¥"
msgid "SecurityReports|Vulnerability Report"
msgstr "æ¼æ´žæŠ¥å‘Š"
@@ -29586,7 +29865,7 @@ msgid "SecurityReports|While it's rare to have no vulnerabilities for your pipel
msgstr "虽然您的æµæ°´çº¿ä¸­æ²¡æœ‰æ¼æ´žï¼Œè¿™ç§çŽ°è±¡å¾ˆç½•è§ï¼Œä½†ä¹Ÿæ˜¯æœ‰å¯èƒ½çš„。无论如何,建议您仔细检查设置以确ä¿ä»ªè¡¨æ¿çš„é…置正确。"
msgid "SecurityReports|With issues"
-msgstr ""
+msgstr "有问题"
msgid "SecurityReports|You do not have sufficient permissions to access this report"
msgstr "您没有足够的æƒé™è®¿é—®æ­¤æŠ¥å‘Š"
@@ -29595,22 +29874,22 @@ msgid "SecurityReports|You must sign in as an authorized user to see this report
msgstr "您必须以授æƒç”¨æˆ·èº«ä»½ç™»å½•æ‰èƒ½æŸ¥çœ‹æ­¤æŠ¥å‘Š"
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
-msgstr ""
+msgstr "您的å馈对我们很é‡è¦ï¼æˆ‘们将在一周内å†æ¬¡è¯¢é—®ã€‚"
msgid "See example DevOps Score page in our documentation."
-msgstr ""
+msgstr "请å‚阅我们文档中的示例 DevOps Score 页é¢ã€‚"
msgid "See metrics"
msgstr "查看指标"
msgid "See our website for help"
-msgstr ""
+msgstr "查看我们的网站以获å–帮助"
msgid "See the affected projects in the GitLab admin panel"
msgstr "查看 GitLab 管ç†é¢æ¿ä¸­çš„å—å½±å“项目"
msgid "See the list of available commands in Slack after setting up this service by entering"
-msgstr ""
+msgstr "通过输入设置此æœåŠ¡åŽï¼ŒæŸ¥çœ‹ Slack 中å¯ç”¨å‘½ä»¤çš„列表"
msgid "See vulnerability %{vulnerability_link} for any Remediation details."
msgstr "有关任何修å¤çš„详细信æ¯ï¼Œè¯·å‚è§æ¼æ´ž%{vulnerability_link}。"
@@ -29640,7 +29919,7 @@ msgid "Select a file from the left sidebar to begin editing. Afterwards, you'll
msgstr "请先从左侧边æ é€‰æ‹©ä¸€ä¸ªæ–‡ä»¶å¼€å§‹ç¼–辑,然åŽå°±å¯ä»¥æ交您的更改了。"
msgid "Select a framework that applies to this project. %{linkStart}How are these added?%{linkEnd}"
-msgstr ""
+msgstr "选择适用于该项目的框架。 %{linkStart}这些是如何添加的?%{linkEnd}"
msgid "Select a group to invite"
msgstr "选择è¦é‚€è¯·çš„组"
@@ -29667,10 +29946,10 @@ msgid "Select a repository"
msgstr "选择一个仓库"
msgid "Select a role"
-msgstr ""
+msgstr "选择一个角色"
msgid "Select a shared template repository for all projects on this instance."
-msgstr ""
+msgstr "为该实例上的所有项目选择一个共享模æ¿ä»“库。"
msgid "Select a template repository"
msgstr "选择模æ¿ä»“库"
@@ -29679,7 +29958,7 @@ msgid "Select a template type"
msgstr "选择模æ¿ç±»åž‹"
msgid "Select a time zone"
-msgstr ""
+msgstr "选择时区"
msgid "Select a timezone"
msgstr "选择时区"
@@ -29688,10 +29967,10 @@ msgid "Select all"
msgstr "选择全部"
msgid "Select an assignee"
-msgstr ""
+msgstr "选择指派人"
msgid "Select an iteration"
-msgstr ""
+msgstr "选择迭代"
msgid "Select assignee"
msgstr "选择指派人"
@@ -29709,7 +29988,7 @@ msgid "Select file"
msgstr "选择文件"
msgid "Select group"
-msgstr ""
+msgstr "选择群组"
msgid "Select group or project"
msgstr "选择群组或项目"
@@ -29721,7 +30000,7 @@ msgid "Select health status"
msgstr "选择å¥åº·çŠ¶å†µ"
msgid "Select iteration"
-msgstr ""
+msgstr "选择迭代"
msgid "Select label"
msgstr "选择标记"
@@ -29772,7 +30051,7 @@ msgid "Select strategy activation method"
msgstr "选择策略激活方å¼"
msgid "Select subgroup"
-msgstr ""
+msgstr "选择å­ç¾¤ç»„"
msgid "Select subscription"
msgstr "选择订阅"
@@ -29805,7 +30084,7 @@ msgid "Selective synchronization"
msgstr "选择性åŒæ­¥"
msgid "Self monitoring"
-msgstr ""
+msgstr "自我监控"
msgid "Self monitoring project does not exist"
msgstr "自我监控项目ä¸å­˜åœ¨"
@@ -29820,28 +30099,28 @@ msgid "Self-monitoring project was not deleted. Please check logs for any error
msgstr "自我监控项目未被删除。请检查日志中是å¦æœ‰ä»»ä½•é”™è¯¯æ¶ˆæ¯"
msgid "SelfMonitoring|Activate or deactivate instance self monitoring."
-msgstr ""
+msgstr "激活或åœç”¨å®žä¾‹è‡ªæˆ‘监测。"
msgid "SelfMonitoring|Activate self monitoring to create a project to use to monitor the health of your instance."
-msgstr ""
+msgstr "激活自我监控以创建用于监控实例è¿è¡ŒçŠ¶å†µçš„项目。"
msgid "SelfMonitoring|Deactivate self monitoring?"
msgstr "åœç”¨è‡ªæˆ‘监控?"
msgid "SelfMonitoring|Deactivating self monitoring deletes the self monitoring project. Are you sure you want to deactivate self monitoring and delete the project?"
-msgstr ""
+msgstr "åœç”¨è‡ªç›‘控将删除自监控项目。您确定è¦åœç”¨è‡ªæˆ‘监控并删除项目å—?"
msgid "SelfMonitoring|Self monitoring"
msgstr "自我监控"
msgid "SelfMonitoring|Self monitoring is active. Use the %{projectLinkStart}self monitoring project%{projectLinkEnd} to monitor the health of your instance."
-msgstr ""
+msgstr "自我监控已å¯ç”¨ã€‚使用 %{projectLinkStart}自我监控项目%{projectLinkEnd} æ¥ç›‘控您的实例的è¿è¡ŒçŠ¶å†µã€‚"
msgid "SelfMonitoring|Self monitoring project successfully created."
-msgstr ""
+msgstr "æˆåŠŸåˆ›å»ºäº†è‡ªæˆ‘监测项目。"
msgid "SelfMonitoring|Self monitoring project successfully deleted."
-msgstr ""
+msgstr "æˆåŠŸåˆ é™¤äº†è‡ªæˆ‘监测项目。"
msgid "Send"
msgstr "å‘é€"
@@ -29856,13 +30135,13 @@ msgid "Send email"
msgstr "å‘é€ç”µå­é‚®ä»¶"
msgid "Send email in multipart format (HTML and plain text). Uncheck to send email messages in plain text only."
-msgstr ""
+msgstr "以多部分格å¼ï¼ˆHTML 和纯文本)å‘é€ç”µå­é‚®ä»¶ã€‚å–消选中仅以纯文本形å¼å‘é€ç”µå­é‚®ä»¶ã€‚"
msgid "Send email notification"
msgstr "å‘é€ç”µå­é‚®ä»¶é€šçŸ¥"
msgid "Send emails to help guide new users through the onboarding process."
-msgstr ""
+msgstr "å‘é€ç”µå­é‚®ä»¶ä»¥å¸®åŠ©æŒ‡å¯¼æ–°ç”¨æˆ·å®Œæˆæ–°äººæµç¨‹ã€‚"
msgid "Send message"
msgstr "å‘é€ä¿¡æ¯â€‹â€‹â€‹â€‹â€‹â€‹â€‹â€‹"
@@ -29904,7 +30183,7 @@ msgid "Serve repository static objects (for example, archives and blobs) from ex
msgstr ""
msgid "Server (optional)"
-msgstr ""
+msgstr "æœåŠ¡å™¨ï¼ˆå¯é€‰ï¼‰"
msgid "Server supports batch API only, please update your Git LFS client to version 1.0.1 and up."
msgstr "æœåŠ¡å™¨ä»…支æŒæ‰¹å¤„ç†API,请将您的Git LFS客户端更新到1.0.1åŠæ›´é«˜ç‰ˆæœ¬ã€‚"
@@ -30000,25 +30279,25 @@ msgid "Service Desk"
msgstr "æœåŠ¡å°"
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
-msgstr ""
+msgstr "æœåŠ¡å°å…许人们在没有自己的用户账å·çš„情况下在您的 GitLab 实例中创建议题。它为最终用户在项目中创建议题æ供了一个唯一的电å­é‚®ä»¶åœ°å€ã€‚回å¤å¯ä»¥é€šè¿‡ GitLab ç•Œé¢æˆ–通过电å­é‚®ä»¶å‘é€ã€‚最终用户åªèƒ½é€šè¿‡ç”µå­é‚®ä»¶æŸ¥çœ‹ä¸»é¢˜ã€‚"
msgid "Service URL"
msgstr "æœåŠ¡ URL"
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
-msgstr ""
+msgstr "æœåŠ¡ ping 在您的é…置文件中被ç¦ç”¨ï¼Œå¹¶ä¸”无法通过此表å•å¯ç”¨ã€‚"
msgid "ServiceDesk|Enable Service Desk"
msgstr "å¯ç”¨æœåŠ¡å°"
msgid "ServiceDesk|For help setting up the Service Desk for your instance, please contact an administrator."
-msgstr ""
+msgstr "有关为您的实例设置æœåŠ¡å°çš„帮助,请è”系管ç†å‘˜ã€‚"
msgid "ServiceDesk|Issues created from Service Desk emails appear here. Each comment becomes part of the email conversation."
-msgstr ""
+msgstr "从æœåŠ¡å°ç”µå­é‚®ä»¶åˆ›å»ºçš„议题显示在此处,æ¯æ¡è¯„论都æˆä¸ºç”µå­é‚®ä»¶å¯¹è¯çš„一部分。"
msgid "ServiceDesk|Issues created from Service Desk emails will appear here. Each comment becomes part of the email conversation."
-msgstr ""
+msgstr "从æœåŠ¡å°ç”µå­é‚®ä»¶åˆ›å»ºçš„议题将显示在此处,æ¯æ¡è¯„论都æˆä¸ºç”µå­é‚®ä»¶å¯¹è¯çš„一部分。"
msgid "ServiceDesk|Service Desk is enabled but not yet active"
msgstr "æœåŠ¡å°å·²å¯ç”¨ä½†å°šæœªæ¿€æ´»"
@@ -30042,16 +30321,16 @@ msgid "ServiceDesk|Your users can send emails to this address:"
msgstr "您的用户å¯ä»¥å‘以下地å€å‘é€ç”µå­é‚®ä»¶ï¼š"
msgid "ServicePing|Service ping is off"
-msgstr ""
+msgstr "æœåŠ¡ping已关闭"
msgid "ServicePing|To view instance-level analytics, ask an admin to turn on %{docLinkStart}service ping%{docLinkEnd}."
-msgstr ""
+msgstr "è¦æŸ¥çœ‹å®žä¾‹çº§åˆ†æžï¼Œè¯·è®©ç®¡ç†å‘˜æ‰“å¼€%{docLinkStart}æœåŠ¡ ping%{docLinkEnd}。"
msgid "ServicePing|Turn on service ping"
-msgstr ""
+msgstr "å¼€å¯æœåŠ¡ ping"
msgid "ServicePing|Turn on service ping to review instance-level analytics."
-msgstr ""
+msgstr "打开æœåŠ¡ping以查看实例级分æžã€‚"
msgid "Session ID"
msgstr "ä¼šè¯ ID"
@@ -30111,7 +30390,7 @@ msgid "Set severity"
msgstr "设置严é‡æ€§"
msgid "Set sign-in restrictions for all users."
-msgstr ""
+msgstr "为所有用户设置登录é™åˆ¶ã€‚"
msgid "Set size limits for displaying diffs in the browser."
msgstr "设置在æµè§ˆå™¨ä¸­æ˜¾ç¤ºå·®å¼‚的大å°é™åˆ¶ã€‚"
@@ -30134,8 +30413,8 @@ msgstr "将迭代设置为%{iteration_reference}。"
msgid "Set the milestone to %{milestone_reference}."
msgstr "将里程碑设置为%{milestone_reference}。"
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
-msgstr "设置å‘主节点å‘é€æ¬¡è¦èŠ‚点状æ€å’Œå…许次è¦èŠ‚点的IP的超时时间(秒)。"
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
+msgstr ""
msgid "Set time estimate"
msgstr "设置时间估计"
@@ -30150,7 +30429,7 @@ msgid "Set up Jira Integration"
msgstr "设置Jira集æˆ"
msgid "Set up a %{type} Runner for a project"
-msgstr ""
+msgstr "为项目设置一个 %{type}的Runner"
msgid "Set up a %{type} runner manually"
msgstr "手动设置一个%{type}的Runner"
@@ -30182,8 +30461,8 @@ msgstr "设置æƒé‡"
msgid "Set weight to %{weight}."
msgstr "å°†æƒé‡è®¾ç½®ä¸º%{weight}。"
-msgid "Set what should be replicated by this secondary node."
-msgstr "设置此次è¦èŠ‚点应该å¤åˆ¶çš„内容。"
+msgid "Set what should be replicated by this secondary site."
+msgstr ""
msgid "SetPasswordToCloneLink|set a password"
msgstr "设置密ç "
@@ -30225,7 +30504,7 @@ msgid "SetStatusModal|What's your status?"
msgstr "您的状æ€æ˜¯ä»€ä¹ˆï¼Ÿ"
msgid "SetStatusModal|Your status resets on %{date}."
-msgstr ""
+msgstr "您的状æ€åœ¨ %{date} æ—¶é‡ç½®ã€‚"
msgid "Sets %{epic_ref} as parent epic."
msgstr "å°†%{epic_ref}设置为父å²è¯—。"
@@ -30243,7 +30522,7 @@ msgid "Sets the milestone to %{milestone_reference}."
msgstr "将里程碑设置为 %{milestone_reference}。"
msgid "Sets the severity"
-msgstr ""
+msgstr "设置严é‡ç¨‹åº¦"
msgid "Sets time estimate to %{time_estimate}."
msgstr "将时间估计设置为 %{time_estimate}。"
@@ -30255,7 +30534,7 @@ msgid "Setting"
msgstr "设置"
msgid "Setting enforced"
-msgstr ""
+msgstr "强制设置"
msgid "Setting this to 0 means using the system default timeout value."
msgstr "设置为 0 æ„味ç€ä½¿ç”¨ç³»ç»Ÿé»˜è®¤è¶…时值。"
@@ -30264,7 +30543,7 @@ msgid "Settings"
msgstr "设置"
msgid "Settings|Unable to load the merge request options settings. Try reloading the page."
-msgstr ""
+msgstr "无法加载åˆå¹¶è¯·æ±‚选项设置。å°è¯•é‡æ–°åŠ è½½é¡µé¢ã€‚"
msgid "Setup"
msgstr "设置"
@@ -30273,7 +30552,7 @@ msgid "Severity"
msgstr "严é‡ç¨‹åº¦"
msgid "Severity updated to %{severity}."
-msgstr ""
+msgstr "严é‡ç¨‹åº¦å·²æ›´æ–°ä¸º%{severity}。"
msgid "SeverityWidget|Severity"
msgstr "严é‡æ€§"
@@ -30330,10 +30609,10 @@ msgid "Should you ever lose your phone or access to your one time password secre
msgstr "如果您丢失手机或访问一次性密ç ï¼Œæ¯ä¸ªæ¢å¤ç éƒ½å¯ä»¥ä½¿ç”¨ä¸€æ¬¡ï¼Œä»¥é‡æ–°èŽ·å¾—您的å¸æˆ·è®¿é—®æƒé™ã€‚请将它们ä¿å­˜åœ¨å®‰å…¨çš„地方,å¦åˆ™æ‚¨%{boldStart}å°†%{boldEnd}无法访问您的å¸æˆ·ã€‚"
msgid "Show Pipeline ID"
-msgstr ""
+msgstr "显示æµæ°´çº¿ID"
msgid "Show Pipeline IID"
-msgstr ""
+msgstr "显示æµæ°´çº¿IID"
msgid "Show all activity"
msgstr "显示所有活动"
@@ -30383,9 +30662,6 @@ msgstr "显示标记"
msgid "Show latest version"
msgstr "显示最新版本"
-msgid "Show links anyways"
-msgstr "ä»ç„¶æ˜¾ç¤ºé“¾æŽ¥"
-
msgid "Show list"
msgstr "显示列表"
@@ -30434,7 +30710,7 @@ msgid "Showing %{limit} of %{total_count} issues. "
msgstr "显示%{total_count}个议题中的%{limit}项. "
msgid "Showing %{pageSize} of %{total} %{issuableType}"
-msgstr ""
+msgstr "显示 %{pageSize} / %{total} %{issuableType}"
msgid "Showing %{pageSize} of %{total} issues"
msgstr "显示%{total}议题中的%{pageSize}项"
@@ -30548,16 +30824,16 @@ msgid "Sign-in text"
msgstr "登录文本"
msgid "Sign-out page URL"
-msgstr ""
+msgstr "退出页é¢URL"
msgid "Sign-up restrictions"
msgstr "注册é™åˆ¶"
msgid "SignUp|By clicking %{button_text}, I agree that I have read and accepted the %{link_start}Terms of Use and Privacy Policy%{link_end}"
-msgstr ""
+msgstr "通过点击 %{button_text},我åŒæ„æˆ‘å·²é˜…è¯»å¹¶æŽ¥å— %{link_start}使用æ¡æ¬¾å’Œéšç§æ”¿ç­–%{link_end}"
msgid "SignUp|By clicking %{button_text}, I agree that I have read and accepted the GitLab %{link_start}Terms of Use and Privacy Policy%{link_end}"
-msgstr ""
+msgstr "点击 %{button_text},我åŒæ„æˆ‘å·²é˜…è¯»å¹¶æŽ¥å— GitLab %{link_start}使用æ¡æ¬¾å’Œéšç§æ”¿ç­–%{link_end}"
msgid "SignUp|First name is too long (maximum is %{max_length} characters)."
msgstr "å字太长(最多%{max_length}字符)。"
@@ -30599,14 +30875,17 @@ msgid "Single or combined queries"
msgstr "å•ä¸ªæˆ–组åˆæŸ¥è¯¢"
msgid "Site profile failed to delete"
-msgstr ""
+msgstr "网站é…置文件删除失败"
msgid "Site profile not found for given parameters"
-msgstr ""
+msgstr "找ä¸åˆ°ç»™å®šå‚数的站点é…置文件"
msgid "Size"
msgstr "大å°"
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr "æ¯ä¸ªä»“库的大å°é™åˆ¶ (MB)"
@@ -30629,7 +30908,7 @@ msgid "Slack integration allows you to interact with GitLab via slash commands i
msgstr "Slack集æˆå…许您通过èŠå¤©çª—å£ä¸­çš„shash命令与GitLab交互。"
msgid "SlackIntegration|Sends notifications about project events to Slack channels."
-msgstr ""
+msgstr "å‘ Slack 频é“å‘é€æœ‰å…³é¡¹ç›®äº‹ä»¶çš„通知。"
msgid "SlackService|2. Paste the %{strong_open}Token%{strong_close} into the field below"
msgstr "2. å°†%{strong_open}Token%{strong_close}粘贴到下é¢çš„字段中"
@@ -30647,7 +30926,7 @@ msgid "SlackService|This service allows users to perform common operations on th
msgstr "æ­¤æœåŠ¡å…许用户通过在Slack中输入斜æ å‘½ä»¤æ¥å¯¹è¯¥é¡¹ç›®æ‰§è¡Œå¸¸è§æ“作。"
msgid "Slice multiplier"
-msgstr ""
+msgstr "切片å€æ•°"
msgid "Smartcard"
msgstr "智能å¡"
@@ -30725,10 +31004,10 @@ msgid "Someone edited this merge request at the same time you did. Please refres
msgstr "有人您åŒæ—¶ç¼–辑了这一åˆå¹¶è¯·æ±‚。请刷新页é¢æŸ¥çœ‹æ›´æ”¹ã€‚"
msgid "Someone edited this test case at the same time you did. The description has been updated and you will need to make your changes again."
-msgstr ""
+msgstr "有人在你编辑的åŒæ—¶ç¼–辑了这个测试用例。æ述已更新,您需è¦å†æ¬¡è¿›è¡Œæ›´æ”¹ã€‚"
msgid "Someone, hopefully you, has requested to reset the password for your GitLab account on %{link_to_gitlab}."
-msgstr ""
+msgstr "有人(希望是您)è¦æ±‚在 %{link_to_gitlab}上é‡ç½®æ‚¨çš„ GitLab è´¦å·çš„密ç ã€‚"
msgid "Something went wrong"
msgstr "出错了"
@@ -30791,7 +31070,7 @@ msgid "Something went wrong while editing your comment. Please try again."
msgstr "编辑评论时出错。请é‡è¯•ã€‚"
msgid "Something went wrong while exporting requirements"
-msgstr ""
+msgstr "导出需求时出现问题"
msgid "Something went wrong while fetching %{listType} list"
msgstr "åœ¨èŽ·å– %{listType} 列表时出错了"
@@ -30806,7 +31085,7 @@ msgid "Something went wrong while fetching description changes. Please try again
msgstr "获å–æè¿°å˜æ›´æ—¶å‡ºé”™äº†ï¼Œè¯·ç¨åŽé‡è¯•ã€‚"
msgid "Something went wrong while fetching details"
-msgstr ""
+msgstr "获å–详细信æ¯æ—¶å‡ºé”™"
msgid "Something went wrong while fetching group member contributions"
msgstr "获å–群组æˆå‘˜è´¡çŒ®æ—¶å‡ºé”™"
@@ -30830,7 +31109,7 @@ msgid "Something went wrong while fetching requirements list."
msgstr "获å–需求列表时出了错。"
msgid "Something went wrong while fetching source branches."
-msgstr ""
+msgstr "获å–æºåˆ†æ”¯æ—¶å‡ºé”™ã€‚"
msgid "Something went wrong while fetching the environments for this merge request. Please try again."
msgstr "获å–æ­¤åˆå¹¶è¯·æ±‚的环境时出错,请ç¨åŽé‡è¯•ã€‚"
@@ -30881,7 +31160,7 @@ msgid "Something went wrong while setting %{issuableType} confidentiality."
msgstr "设置%{issuableType}çš„ç§å¯†æ€§æ—¶å‡ºé”™ã€‚"
msgid "Something went wrong while setting %{issuableType} health status."
-msgstr ""
+msgstr "设置 %{issuableType} å¥åº·çŠ¶æ€æ—¶å‡ºé”™ã€‚"
msgid "Something went wrong while setting %{issuableType} notifications."
msgstr "设置%{issuableType}的通知时出错。"
@@ -30890,7 +31169,7 @@ msgid "Something went wrong while setting %{issuableType} to-do item."
msgstr "设置%{issuableType}的待办事项时出错。"
msgid "Something went wrong while setting %{issuableType} weight."
-msgstr ""
+msgstr "设置 %{issuableType} æƒé‡æ—¶å‡ºäº†é”™ã€‚"
msgid "Something went wrong while stopping this environment. Please try again."
msgstr "åœæ­¢çŽ¯å¢ƒæ—¶å‡ºé”™ã€‚请é‡è¯•ã€‚"
@@ -30958,6 +31237,15 @@ msgstr "排åºæ–¹å‘:é™åº"
msgid "SortOptions|Blocking"
msgstr "阻塞议题数"
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr "创建日期"
@@ -31001,13 +31289,13 @@ msgid "SortOptions|Manual"
msgstr "手动"
msgid "SortOptions|Merged date"
-msgstr ""
+msgstr "åˆå¹¶æ—¥æœŸ"
msgid "SortOptions|Merged earlier"
-msgstr ""
+msgstr "较早åˆå¹¶"
msgid "SortOptions|Merged recently"
-msgstr ""
+msgstr "最近åˆå¹¶"
msgid "SortOptions|Milestone due date"
msgstr "里程碑截止日期"
@@ -31091,7 +31379,7 @@ msgid "SortOptions|Start soon"
msgstr "现在开始"
msgid "SortOptions|Title"
-msgstr ""
+msgstr "标题"
msgid "SortOptions|Type"
msgstr "类型"
@@ -31115,10 +31403,10 @@ msgid "Source Editor instance is required to set up an extension."
msgstr ""
msgid "Source IP"
-msgstr ""
+msgstr "æºIP"
msgid "Source branch"
-msgstr ""
+msgstr "æºåˆ†æ”¯"
msgid "Source branch: %{source_branch_open}%{source_branch}%{source_branch_close}"
msgstr "æºåˆ†æ”¯: %{source_branch_open}%{source_branch}%{source_branch_close}"
@@ -31178,7 +31466,7 @@ msgid "SourcegraphPreferences|Uses a custom %{linkStart}Sourcegraph instance%{li
msgstr "使用自定义的%{linkStart}Sourcegraph实例%{linkEnd}。"
msgid "Spam Check API Key"
-msgstr ""
+msgstr "垃圾邮件检查 API 密钥"
msgid "Spam Logs"
msgstr "垃圾信æ¯æ—¥å¿—"
@@ -31190,7 +31478,7 @@ msgid "Spam log successfully submitted as ham."
msgstr "垃圾信æ¯æ—¥å¿—å·²æˆåŠŸæ”¹ä¸ºæœ‰æ•ˆä¿¡æ¯æ交。"
msgid "Specific runners"
-msgstr ""
+msgstr "指定Runner"
msgid "Specified URL cannot be used: \"%{reason}\""
msgstr "无法使用指定的URL:“%{reason}â€"
@@ -31268,16 +31556,16 @@ msgid "Start a %{new_merge_request} with these changes"
msgstr "由此更改 %{new_merge_request}"
msgid "Start a Free Ultimate Trial"
-msgstr ""
+msgstr "开始å…费试用旗舰版"
msgid "Start a new discussion…"
-msgstr ""
+msgstr "开始一个新的讨论..."
msgid "Start a new merge request"
msgstr "å¯åŠ¨æ–°çš„åˆå¹¶è¯·æ±‚"
msgid "Start a new merge request with these changes"
-msgstr ""
+msgstr "使用这些更改开始新的åˆå¹¶è¯·æ±‚"
msgid "Start a review"
msgstr "å¯åŠ¨è¯„审"
@@ -31313,7 +31601,7 @@ msgid "Start thread & reopen %{noteable_name}"
msgstr "å¼€å¯ä¸»é¢˜å¹¶é‡æ–°æ‰“å¼€%{noteable_name}"
msgid "Start your Free Ultimate Trial"
-msgstr ""
+msgstr "开始您的å…费试用"
msgid "Start your free trial"
msgstr "开始å…费试用"
@@ -31334,7 +31622,7 @@ msgid "Starting..."
msgstr "正在å¯åŠ¨..."
msgid "Starts"
-msgstr ""
+msgstr "开始"
msgid "Starts %{startsIn}"
msgstr "开始 %{startsIn}"
@@ -31346,7 +31634,7 @@ msgid "Starts on"
msgstr "开始于"
msgid "Starts: %{startsAt}"
-msgstr ""
+msgstr "开始于: %{startsAt}"
msgid "State your message to activate"
msgstr "输入消æ¯ä»¥å¯ç”¨"
@@ -31436,55 +31724,55 @@ msgid "StatusCheck|%{pending} pending"
msgstr ""
msgid "StatusCheck|API to check"
-msgstr ""
+msgstr "API检查"
msgid "StatusCheck|Add status check"
-msgstr ""
+msgstr "添加状æ€æ£€æŸ¥"
msgid "StatusCheck|All passed"
-msgstr ""
+msgstr "全部通过"
msgid "StatusCheck|An error occurred deleting the %{name} status check."
-msgstr ""
+msgstr "删除 %{name} 状æ€æ£€æŸ¥æ—¶å‡ºé”™ã€‚"
msgid "StatusCheck|An error occurred fetching the status checks."
-msgstr ""
+msgstr "获å–状æ€æ£€æŸ¥æ—¶å‡ºé”™ã€‚"
msgid "StatusCheck|Apply this status check to any branch or a specific protected branch."
-msgstr ""
+msgstr "将此状æ€æ£€æŸ¥åº”用于任何分支或特定的å—ä¿æŠ¤åˆ†æ”¯ã€‚"
msgid "StatusCheck|Check for a status response in Merge Requests. Failures do not block merges. %{link_start}Learn more%{link_end}."
-msgstr ""
+msgstr "检查åˆå¹¶è¯·æ±‚中的状æ€å“应,失败ä¸ä¼šé˜»æ­¢åˆå¹¶ã€‚ %{link_start}了解更多%{link_end}."
msgid "StatusCheck|Examples: QA, Security."
-msgstr ""
+msgstr "示例:QAã€å®‰å…¨ã€‚"
msgid "StatusCheck|External API is already in use by another status check."
-msgstr ""
+msgstr "外部 API 已被å¦ä¸€ä¸ªçŠ¶æ€æ£€æŸ¥ä½¿ç”¨ã€‚"
msgid "StatusCheck|Failed to load status checks."
-msgstr ""
+msgstr "无法加载状æ€æ£€æŸ¥ã€‚"
msgid "StatusCheck|Invoke an external API as part of the pipeline process."
-msgstr ""
+msgstr "调用外部 API 作为æµæ°´çº¿è¿‡ç¨‹çš„一部分。"
msgid "StatusCheck|No status checks are defined yet."
-msgstr ""
+msgstr "尚未定义状æ€æ£€æŸ¥ã€‚"
msgid "StatusCheck|Remove status check"
-msgstr ""
+msgstr "移除状æ€æ£€æŸ¥"
msgid "StatusCheck|Remove status check?"
-msgstr ""
+msgstr "移除状æ€æ£€æŸ¥ï¼Ÿ"
msgid "StatusCheck|Service name"
msgstr "æœåŠ¡å称"
msgid "StatusCheck|Status checks"
-msgstr ""
+msgstr "状æ€æ£€æŸ¥"
msgid "StatusCheck|Status to check"
-msgstr ""
+msgstr "è¦æ£€æŸ¥çš„状æ€"
msgid "StatusCheck|Target branch"
msgstr "目标分支"
@@ -31982,124 +32270,124 @@ msgid "SuperSonics|Expires on"
msgstr "到期"
msgid "SuperSonics|Export license usage file"
-msgstr ""
+msgstr "导出许å¯è¯ä½¿ç”¨æ–‡ä»¶"
msgid "SuperSonics|Free trial"
msgstr "å…费试用"
msgid "SuperSonics|Get help for the most common connectivity issues by %{linkStart}troubleshooting the activation code%{linkEnd}."
-msgstr ""
+msgstr "通过 %{linkStart}激活ç æ•…障排查%{linkEnd},获å–最常è§çš„连接问题的帮助。"
msgid "SuperSonics|I agree that my use of the GitLab Software is subject to the Subscription Agreement located at the %{linkStart}Terms of Service%{linkEnd}, unless otherwise agreed to in writing with GitLab."
msgstr ""
msgid "SuperSonics|ID"
-msgstr ""
+msgstr "ID"
msgid "SuperSonics|Last Sync"
-msgstr ""
+msgstr "上次åŒæ­¥"
msgid "SuperSonics|Learn how to %{linkStart}activate your subscription%{linkEnd}."
-msgstr ""
+msgstr "了解如何 %{linkStart}激活您的订阅%{linkEnd}。"
msgid "SuperSonics|Licensed to"
msgstr ""
msgid "SuperSonics|Manage"
-msgstr ""
+msgstr "管ç†"
msgid "SuperSonics|Maximum users"
-msgstr ""
+msgstr "最大用户数"
msgid "SuperSonics|Paste your activation code"
-msgstr ""
+msgstr "粘贴您的激活ç "
msgid "SuperSonics|Plan"
-msgstr ""
+msgstr "方案"
msgid "SuperSonics|Ready to get started? A GitLab plan is ideal for scaling organizations and for multi team usage."
msgstr ""
msgid "SuperSonics|Renews"
-msgstr ""
+msgstr "续订"
msgid "SuperSonics|Seats"
msgstr "席ä½"
msgid "SuperSonics|Start free trial"
-msgstr ""
+msgstr "开始å…费试用"
msgid "SuperSonics|Started"
-msgstr ""
+msgstr "å·²å¯åŠ¨"
msgid "SuperSonics|Subscription"
-msgstr ""
+msgstr "订阅"
msgid "SuperSonics|Subscription details"
-msgstr ""
+msgstr "订阅详情"
msgid "SuperSonics|Sync subscription details"
-msgstr ""
+msgstr "åŒæ­¥è®¢é˜…详情"
msgid "SuperSonics|Sync subscription request."
-msgstr ""
+msgstr "åŒæ­¥è®¢é˜…请求。"
msgid "SuperSonics|The activation code is not valid. Please make sure to copy it exactly from the Customers Portal or confirmation email. Learn more about %{linkStart}activating your subscription%{linkEnd}."
-msgstr ""
+msgstr "激活ç æ— æ•ˆã€‚请确ä¿ä»Žå®¢æˆ·ç«¯é—¨æˆ·æˆ–确认电å­é‚®ä»¶å¤åˆ¶å®ƒã€‚ 了解更多关于 %{linkStart}激活您的订阅%{linkEnd}。"
msgid "SuperSonics|There is a connectivity issue."
-msgstr ""
+msgstr "存在连接问题。"
msgid "SuperSonics|This is the highest peak of users on your installation since the license started."
-msgstr ""
+msgstr "这是自许å¯è¯å¯åŠ¨ä»¥æ¥ç”¨æˆ·æ•°çš„最高峰。"
msgid "SuperSonics|This is the number of %{billableUsersLinkStart}billable users%{billableUsersLinkEnd} on your installation, and this is the minimum number you need to purchase when you renew your license."
-msgstr ""
+msgstr "这是 %{billableUsersLinkStart}计费用户%{billableUsersLinkEnd} çš„æ•°é‡ï¼Œä¹Ÿæ˜¯æ‚¨ç»­è®¢è®¸å¯è¯æ—¶éœ€è¦è´­ä¹°çš„最å°æ•°é‡ã€‚"
msgid "SuperSonics|To activate your subscription, connect to GitLab servers through the %{linkStart}Cloud Licensing%{linkEnd} service, a hassle-free way to manage your subscription."
-msgstr ""
+msgstr "è¦æ¿€æ´»æ‚¨çš„订阅,请通过 %{linkStart}Cloud Licensing%{linkEnd} æœåŠ¡è¿žæŽ¥åˆ° GitLab æœåŠ¡å™¨ï¼Œè¿™æ˜¯ä¸€ç§è½»æ¾ç®¡ç†è®¢é˜…çš„æ–¹å¼ã€‚"
msgid "SuperSonics|Type"
-msgstr ""
+msgstr "类型"
msgid "SuperSonics|Upload a license file"
-msgstr ""
+msgstr "上传许å¯æ–‡ä»¶"
msgid "SuperSonics|Users in subscription"
-msgstr ""
+msgstr "订阅数内的用户"
msgid "SuperSonics|Users over subscription"
-msgstr ""
+msgstr "超过订阅的用户"
msgid "SuperSonics|Users with a Guest role or those who don't belong to a Project or Group will not use a seat from your license."
-msgstr ""
+msgstr "具有访客角色的用户或ä¸å±žäºŽé¡¹ç›®æˆ–组的用户将ä¸ä¼šä½¿ç”¨æ‚¨çš„许å¯è¯ä¸­çš„席ä½ã€‚"
msgid "SuperSonics|Valid From"
-msgstr ""
+msgstr "有效期自"
msgid "SuperSonics|You can learn more about %{activationLinkStart}activating your subscription%{activationLinkEnd}. If you need further assistance, please %{supportLinkStart}contact GitLab Support%{supportLinkEnd}."
-msgstr ""
+msgstr "您å¯ä»¥äº†è§£æ›´å¤šå…³äºŽ %{activationLinkStart}激活您的订阅%{activationLinkEnd}。如果您需è¦è¿›ä¸€æ­¥çš„帮助,请 %{supportLinkStart}è”系技术支æŒ%{supportLinkEnd}。"
msgid "SuperSonics|You can no longer sync your subscription details with GitLab. Get help for the most common connectivity issues by %{connectivityHelpLinkStart}troubleshooting the activation code%{connectivityHelpLinkEnd}."
-msgstr ""
+msgstr "您无法å†å°†è®¢é˜…详细信æ¯ä¸Ž GitLab åŒæ­¥ã€‚ %{connectivityHelpLinkStart}通过对激活ç è¿›è¡Œæ•…障排除%{connectivityHelpLinkEnd},获å–有关最常è§è¿žæŽ¥é—®é¢˜çš„帮助。"
msgid "SuperSonics|You can start a free trial of GitLab Ultimate without any obligation or payment details."
-msgstr ""
+msgstr "您å¯ä»¥å¼€å§‹å…费试用 GitLab 旗舰版,无需任何承诺或付款信æ¯ã€‚"
msgid "SuperSonics|You do not have an active subscription"
-msgstr ""
+msgstr "您没有有效订阅"
msgid "SuperSonics|You'll be charged for %{trueUpLinkStart}users over license%{trueUpLinkEnd} on a quarterly or annual basis, depending on the terms of your agreement."
-msgstr ""
+msgstr "æ ¹æ®æ‚¨çš„åè®®æ¡æ¬¾ï¼Œæ‚¨å°†æŒ‰å­£åº¦æˆ–æ¯å¹´ä¸º %{trueUpLinkStart}超过许å¯è¯çš„用户%{trueUpLinkEnd}付费。"
msgid "SuperSonics|Your subscription"
-msgstr ""
+msgstr "您的订阅"
msgid "SuperSonics|Your subscription details will sync shortly."
-msgstr ""
+msgstr "您的订阅信æ¯å°†å¾ˆå¿«åŒæ­¥"
msgid "SuperSonics|Your subscription was successfully activated. You can see the details below."
-msgstr ""
+msgstr "您的订阅已æˆåŠŸæ¿€æ´»ã€‚您å¯ä»¥åœ¨ä¸‹é¢æŸ¥çœ‹è¯¦ç»†ä¿¡æ¯ã€‚"
msgid "Support"
msgstr "支æŒ"
@@ -32195,7 +32483,7 @@ msgid "Table of Contents"
msgstr "目录"
msgid "Table of contents"
-msgstr ""
+msgstr "目录"
msgid "Tag"
msgstr "标签"
@@ -32210,13 +32498,13 @@ msgid "Tag name is required"
msgstr "标签å称为必填项"
msgid "Tag push events"
-msgstr ""
+msgstr "标签推é€äº‹ä»¶"
msgid "Tag this commit."
msgstr "为此æ交打标签。"
msgid "Tag:"
-msgstr ""
+msgstr "标签:"
msgid "Tagged this commit to %{tag_name} with \"%{message}\"."
msgstr "使用“%{message}â€ä¸ºæ­¤æ交设置%{tag_name} 标签。"
@@ -32330,13 +32618,13 @@ msgid "Team domain"
msgstr "团队域"
msgid "TeamcityIntegration|Trigger TeamCity CI after a merge request has been created or updated"
-msgstr ""
+msgstr "在创建或更新åˆå¹¶è¯·æ±‚åŽè§¦å‘ TeamCity CI"
msgid "TeamcityIntegration|Trigger TeamCity CI after every push to the repository, except branch delete"
-msgstr ""
+msgstr "æ¯æ¬¡æŽ¨é€åˆ°å­˜å‚¨åº“åŽè§¦å‘ TeamCity CI,分支删除除外"
msgid "Tell us your experiences with the new Markdown editor %{linkStart}in this feedback issue%{linkEnd}."
-msgstr ""
+msgstr "%{linkStart}在此å馈议题中%{linkEnd},告诉我们您对新 Markdown 编辑器的体验。"
msgid "Template"
msgstr "模æ¿"
@@ -32345,7 +32633,7 @@ msgid "Template to append to all Service Desk issues"
msgstr "附加到所有æœåŠ¡å°ç”Ÿæˆè®®é¢˜çš„模æ¿"
msgid "TemplateRepository|Select a repository to make its templates available to all projects. %{link_start}What should the repository contain?%{link_end} "
-msgstr ""
+msgstr "选择一个仓库以使其模æ¿å¯ç”¨äºŽæ‰€æœ‰é¡¹ç›®ã€‚ %{link_start}仓库应该包å«ä»€ä¹ˆï¼Ÿ%{link_end} "
msgid "Templates"
msgstr "模æ¿"
@@ -32384,7 +32672,7 @@ msgid "Terraform"
msgstr "Terraform"
msgid "TerraformBanner|Learn more about GitLab's Backend State"
-msgstr ""
+msgstr "了解有关 GitLab åŽç«¯çŠ¶æ€çš„更多信æ¯"
msgid "TerraformBanner|The GitLab managed Terraform state backend can store your Terraform state easily and securely, and spares you from setting up additional remote resources. Its features include: versioning, encryption of the state file both in transit and at rest, locking, and remote Terraform plan/apply execution."
msgstr ""
@@ -32410,13 +32698,13 @@ msgid "Terraform|A report failed to generate."
msgstr "无法生æˆæŠ¥å‘Šã€‚"
msgid "Terraform|A report was generated in your pipelines."
-msgstr ""
+msgstr "在您的æµæ°´çº¿ä¸­ç”Ÿæˆäº†ä¸€ä»½æŠ¥å‘Šã€‚"
msgid "Terraform|Actions"
msgstr "æ“作"
msgid "Terraform|An error occurred while changing the state file"
-msgstr ""
+msgstr "更改状æ€æ–‡ä»¶æ—¶å‘生错误"
msgid "Terraform|An error occurred while loading your Terraform States"
msgstr "加载您的Terraform状æ€æ—¶å‘生错误"
@@ -32427,6 +32715,9 @@ msgstr "确定è¦åˆ é™¤Terraform状æ€%{name}å—?"
msgid "Terraform|Cancel"
msgstr "å–消"
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr "详细信æ¯"
@@ -32455,7 +32746,7 @@ msgid "Terraform|Locked by %{user} %{timeAgo}"
msgstr "ç”±%{user}于%{timeAgo}é”定"
msgid "Terraform|Locking state"
-msgstr ""
+msgstr "é”定状æ€"
msgid "Terraform|Name"
msgstr "å称"
@@ -32470,7 +32761,7 @@ msgid "Terraform|Remove state file and versions"
msgstr "删除状æ€æ–‡ä»¶å’Œç‰ˆæœ¬"
msgid "Terraform|Removing"
-msgstr ""
+msgstr "正在删除"
msgid "Terraform|Reported Resource Changes: %{addNum} to add, %{changeNum} to change, %{deleteNum} to delete"
msgstr "报告资æºæ›´æ”¹: 添加%{addNum}项, 更改%{changeNum}项, 删除%{deleteNum}项"
@@ -32478,10 +32769,16 @@ msgstr "报告资æºæ›´æ”¹: 添加%{addNum}项, 更改%{changeNum}项, 删除%{d
msgid "Terraform|States"
msgstr "状æ€"
-msgid "Terraform|The report %{name} failed to generate."
+msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|The report %{name} failed to generate."
+msgstr "报告%{name}生æˆå¤±è´¥ã€‚"
+
msgid "Terraform|The report %{name} was generated in your pipelines."
+msgstr "报告 %{name} 是在您的æµæ°´çº¿ä¸­ç”Ÿæˆçš„。"
+
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
@@ -32496,8 +32793,8 @@ msgstr "解é”"
msgid "Terraform|Unlocking state"
msgstr "解é”状æ€"
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
-msgstr "您将è¦åˆ é™¤çŠ¶æ€æ–‡ä»¶ %{name}。这将永久删除所有 State 版本和历å²è®°å½•ã€‚之å‰æ供的基础设施将ä¿æŒä¸å˜ï¼Œåªæœ‰çŠ¶æ€æ–‡ä»¶åŠå…¶æ‰€æœ‰ç‰ˆæœ¬å°†è¢«åˆ é™¤ã€‚æ­¤æ“作ä¸å¯æ¢å¤ã€‚"
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
+msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
msgstr "无法删除状æ€æ–‡ä»¶ï¼Œå› ä¸ºå®ƒå·²è¢«é”定。在删除之å‰å…ˆè§£é”状æ€æ–‡ä»¶ã€‚"
@@ -32685,7 +32982,7 @@ msgid "The %{link_start}true-up model%{link_end} allows having more users, and a
msgstr "%{link_start}校准模å¼%{link_end}å…许有é¢å¤–用户,这些é¢å¤–用户在更新订阅时将会产生追溯费用。"
msgid "The %{plan_name} is no longer available to purchase. For more information about how this will impact you, check our %{faq_link_start}frequently asked questions%{faq_link_end}."
-msgstr ""
+msgstr "%{plan_name} 已无法购买。欲了解更多关于这将如何影å“您的信æ¯ï¼Œè¯·æŸ¥çœ‹æˆ‘们的 %{faq_link_start}常è§é—®é¢˜%{faq_link_end}。"
msgid "The %{type} contains the following error:"
msgid_plural "The %{type} contains the following errors:"
@@ -32713,19 +33010,19 @@ msgid "The Prometheus server responded with \"bad request\". Please check your q
msgstr "PrometheusæœåŠ¡å™¨ä»¥â€œé”™è¯¯è¯·æ±‚â€å“应。请检查您的查询是å¦æ­£ç¡®ï¼Œå¹¶ä¸”当å‰çš„Prometheus版本支æŒã€‚ %{documentationLink}"
msgid "The Snowplow cookie domain."
-msgstr ""
+msgstr "Snowplow cookie 域å。"
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr "在主节点上定义的URL,次è¦èŠ‚点应使用该URL与其è”系。"
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
-msgstr "在主节点上定义的URL,从节点将用此网å€æ¥è”络主节点。%{linkStart}更多信æ¯%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
+msgstr ""
msgid "The URL of the Jenkins server."
-msgstr ""
+msgstr "Jenkins æœåŠ¡å™¨çš„ URL。"
msgid "The URL should start with http:// or https://"
-msgstr ""
+msgstr "URL 应该以 http:// 或 https:// 开头"
msgid "The URL to use for connecting to Elasticsearch. Use a comma-separated list to support clustering (e.g., \"http://localhost:9200, http://localhost:9201\")."
msgstr "用于连接到Elasticsearchçš„URL。使用逗å·åˆ†éš”的列表æ¥æ”¯æŒç¾¤é›†(例如,“http://localhost:9200, http://localhost:9201â€)。"
@@ -32752,7 +33049,7 @@ msgid "The character highlighter helps you keep the subject line to %{titleLengt
msgstr "字符çªå‡ºæ˜¾ç¤ºå™¨å¸®åŠ©æ‚¨å°†ä¸»é¢˜è¡Œä¿æŒä¸º %{titleLength} 字符并将正文包装为 %{bodyLength} 以便它们在git中å¯è¯»ã€‚"
msgid "The comment you are editing has been changed by another user. Would you like to keep your changes and overwrite the new description or discard your changes?"
-msgstr ""
+msgstr "您正在编辑的评论已被其他用户更改。您想ä¿ç•™æ‚¨çš„更改并覆盖新的æ述还是放弃您的更改?"
msgid "The commit does not exist"
msgstr "æ­¤æ交ä¸å­˜åœ¨"
@@ -32761,7 +33058,7 @@ msgid "The comparison view may be inaccurate due to merge conflicts."
msgstr "由于存在åˆå¹¶å†²çªï¼Œå¯¹æ¯”视图å¯èƒ½ä¸å‡†ç¡®ã€‚"
msgid "The compliance report captures merged changes that violate compliance best practices."
-msgstr ""
+msgstr "åˆè§„报告æ•èŽ·è¿ååˆè§„最佳实践的åˆå¹¶æ›´æ”¹ã€‚"
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr "该连接将在 %{timeout}åŽè¶…时。如仓库导入耗时超过该时间,请使用克隆/推é€ç»„åˆã€‚"
@@ -32791,7 +33088,7 @@ msgid "The default branch for this project has been changed. Please update your
msgstr "此项目的默认分支已更改,请更新您的书签。"
msgid "The default expiration time for job artifacts. 0 for unlimited. The default unit is in seconds, but you can use other units, for example %{code_open}4 mins 2 sec%{code_close}, %{code_open}2h42min%{code_close}."
-msgstr ""
+msgstr "作业产物的默认过期时间。 0 表示无é™åˆ¶ã€‚默认å•ä½ä¸ºç§’,但您å¯ä»¥ä½¿ç”¨å…¶ä»–å•ä½ï¼Œä¾‹å¦‚ %{code_open}4 mins 2 sec%{code_close}〠%{code_open}2h42min%{code_close}。"
msgid "The dependency list details information about the components used within your project."
msgstr "ä¾èµ–项列表详细说明了项目中使用组件的信æ¯ã€‚"
@@ -32815,16 +33112,16 @@ msgid "The download link will expire in 24 hours."
msgstr "下载链接将于24å°æ—¶åŽè¿‡æœŸã€‚"
msgid "The environment tier must be one of %{environment_tiers}."
-msgstr ""
+msgstr "环境级别必须是%{environment_tiers}之一。"
msgid "The errors we encountered were:"
msgstr "我们é‡åˆ°çš„错误是:"
msgid "The file containing the export is not available yet; it may still be transferring. Please try again later."
-msgstr ""
+msgstr "包å«å¯¼å‡ºçš„文件尚ä¸å¯ç”¨ï¼›å®ƒå¯èƒ½ä»åœ¨è½¬ç§»ã€‚请ç¨åŽå†è¯•ã€‚"
msgid "The file could not be displayed because it is empty or larger than the maximum file size indexed (%{size})."
-msgstr ""
+msgstr "æ— æ³•æ˜¾ç¤ºè¯¥æ–‡ä»¶ï¼Œå› ä¸ºå®ƒä¸ºç©ºæˆ–å¤§äºŽç´¢å¼•çš„æœ€å¤§æ–‡ä»¶å¤§å° (%{size})。"
msgid "The file has been successfully created."
msgstr "文件已æˆåŠŸåˆ›å»ºã€‚"
@@ -32836,7 +33133,7 @@ msgid "The file name should have a .yml extension"
msgstr "文件å应以.yml扩展"
msgid "The finding is not a vulnerability because it is part of a test or is test data."
-msgstr ""
+msgstr "该å‘现ä¸æ˜¯æ¼æ´žï¼Œå› ä¸ºå®ƒæ˜¯æµ‹è¯•çš„一部分或测试数æ®ã€‚"
msgid "The following %{user} can also merge into this branch: %{branch}"
msgstr "以下%{user}也å¯ä»¥åˆå¹¶åˆ°è¯¥åˆ†æ”¯ä¸­: %{branch}"
@@ -32894,16 +33191,16 @@ msgid "The group settings for %{group_links} require you to enable Two-Factor Au
msgstr "%{group_links} 的群组设置è¦æ±‚您为å¸æˆ·å¯ç”¨åŒé‡è®¤è¯ã€‚你也å¯ä»¥ %{leave_group_links}。"
msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
+msgstr "该群组将处于“待删除â€çŠ¶æ€"
msgid "The group_project_ids parameter is only allowed for a group"
-msgstr ""
+msgstr "group_project_ids å‚æ•°åªå…许用于一个群组"
msgid "The hostname of your PlantUML server."
-msgstr ""
+msgstr "您的 PlantUML æœåŠ¡å™¨çš„主机å。"
msgid "The hostname of your Snowplow collector."
-msgstr ""
+msgstr "您的 Snowplow 收集器的主机å。"
msgid "The import will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr "该导入过程将在 %{timeout}åŽè¶…时。对于需è¦é•¿äºŽè¯¥æ—¶é—´æ‰èƒ½å¯¼å…¥çš„仓库,请使用克隆/推é€ç»„åˆã€‚"
@@ -32930,11 +33227,14 @@ msgid "The issue was successfully promoted to an epic. Redirecting to epic..."
msgstr "该问题被æˆåŠŸæå‡ä¸ºå²è¯—。é‡å®šå‘到å²è¯—..."
msgid "The latest artifacts created by jobs in the most recent successful pipeline will be stored."
-msgstr ""
+msgstr "将存储由最近æˆåŠŸæµæ°´çº¿ä¸­çš„作业创建的最新产物。"
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr "æ­¤åˆå¹¶è¯·æ±‚的最新æµæ°´çº¿æœªæˆåŠŸå®Œæˆã€‚"
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr "许å¯è¯å¯†é’¥æ— æ•ˆã€‚请确ä¿å®ƒä¸Žæ‚¨ä»ŽGitLab Inc.收到的一致。"
@@ -32954,25 +33254,22 @@ msgid "The maximum file size allowed is %{size}."
msgstr "å…许的最大文件大å°ä¸º %{size}。"
msgid "The maximum file size for job artifacts."
-msgstr ""
+msgstr "作业产物的最大文件大å°ã€‚"
msgid "The maximum file size in megabytes for individual job artifacts."
-msgstr ""
+msgstr "个别作业产物的最大文件大å°ï¼Œä»¥å…†å­—节(MB)计算。"
msgid "The maximum file size is %{size}."
msgstr "最大文件大å°ä¸º %{size}。"
msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
-msgstr ""
+msgstr "一个群组æ¯æœˆå¯ä»¥åœ¨å…±äº«runner上使用的最大æµæ°´çº¿åˆ†é’Ÿæ•°ã€‚ 0 表示无é™åˆ¶ã€‚"
msgid "The maximum number of slices allowed to run concurrently during Elasticsearch reindexing. Learn more about %{max_slices_running_link_start}maximum running slices configuration%{max_slices_link_end}."
-msgstr ""
+msgstr "在 Elasticsearch é‡æ–°ç´¢å¼•æœŸé—´å…许åŒæ—¶è¿è¡Œçš„最大切片数。了解有关 %{max_slices_running_link_start}最大è¿è¡Œåˆ‡ç‰‡é…ç½®%{max_slices_link_end}更多信æ¯ã€‚"
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
-msgstr ""
-
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
+msgstr "å•ä¸ªworker接å—清ç†çš„最大标签数。如果标签数é‡è¶…过此é™åˆ¶ï¼Œåˆ™è¦åˆ é™¤çš„标签列表将被截断为该数é‡ã€‚è¦å–消此é™åˆ¶ï¼Œè¯·å°†å…¶è®¾ç½®ä¸º 0。"
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr "GitLab无法解决此åˆå¹¶è¯·æ±‚çš„åˆå¹¶å†²çªã€‚请å°è¯•åœ¨æœ¬åœ°è§£å†³å®ƒä»¬ã€‚"
@@ -33122,11 +33419,14 @@ msgid "The start date must be ealier than the end date."
msgstr "开始日期必须早于结æŸæ—¥æœŸã€‚"
msgid "The subject will be used as the title of the new issue, and the message will be the description. %{quickActionsLinkStart}Quick actions%{quickActionsLinkEnd} and styling with %{markdownLinkStart}Markdown%{markdownLinkEnd} are supported."
-msgstr ""
+msgstr "该主题将用作新议题的标题,信æ¯å°†ä½œä¸ºè¯´æ˜Žã€‚ æ”¯æŒ %{quickActionsLinkStart}快速æ“作%{quickActionsLinkEnd} 并使用支æŒçš„ %{markdownLinkStart}Markdown%{markdownLinkEnd} 风格。"
msgid "The tag name can't be changed for an existing release."
msgstr "对于现有å‘布,ä¸èƒ½æ›´æ”¹æ ‡ç­¾å称。"
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr "æ›´æ–°æ“作将在 %{number_of_minutes} 分钟åŽè¶…时。对于大型仓库,请使用clone/push组åˆã€‚"
@@ -33155,10 +33455,10 @@ msgid "The value of the provided variable exceeds the %{count} character limit"
msgstr "æä¾›å˜é‡çš„值超过了%{count}字符é™åˆ¶"
msgid "The vulnerability is known, and has not been remediated or mitigated, but is considered to be an acceptable business risk."
-msgstr ""
+msgstr "该æ¼æ´žæ˜¯å·²çŸ¥çš„,尚未修å¤æˆ–缓解,但被视为å¯æŽ¥å—的业务风险。"
msgid "The vulnerability is known, and has not been remediated or mitigated, but is considered to be in a part of the application that will not be updated."
-msgstr ""
+msgstr "该æ¼æ´žæ˜¯å·²çŸ¥çš„,尚未修å¤æˆ–缓解,但被认为存在于ä¸ä¼šæ›´æ–°çš„应用程åºéƒ¨åˆ†ä¸­ã€‚"
msgid "The vulnerability is no longer detected. Verify the vulnerability has been fixed or removed before changing its status."
msgstr "æ¼æ´žå·²ä¸å†è¢«æ£€æµ‹åˆ°ã€‚请在更改其状æ€å‰ç¡®ä¿æ¼æ´žå·²ä¿®å¤æˆ–移除。"
@@ -33227,7 +33527,7 @@ msgid "There are no issues to show"
msgstr "当å‰æ— è®®é¢˜"
msgid "There are no issues with the selected labels"
-msgstr ""
+msgstr "所选标记没有问题"
msgid "There are no labels yet"
msgstr "ç›®å‰æ— æ ‡è®°"
@@ -33265,17 +33565,23 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr "环境上有正在è¿è¡Œçš„部署。请ç¨åŽé‡è¯•ã€‚"
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
+msgstr "为了ä¿æŠ¤è¯¥ç³»ç»Ÿï¼Œå®žè¡Œäº†å‡ ç§é€ŸçŽ‡é™åˆ¶ã€‚"
+
+msgid "There are several size limits in place."
msgstr ""
msgid "There is a halted Elasticsearch migration"
-msgstr ""
+msgstr "Elasticsearch è¿ç§»å·²åœæ­¢"
msgid "There is already a repository with that name on disk"
msgstr "ç£ç›˜ä¸Šå·²å­˜åœ¨å…·æœ‰è¯¥å称的仓库"
msgid "There is already a to-do item for this design."
-msgstr ""
+msgstr "这个设计已ç»æœ‰ä¸€ä¸ªå¾…办事项。"
msgid "There is no chart data available."
msgstr "没有å¯ç”¨çš„图表数æ®ã€‚"
@@ -33299,7 +33605,7 @@ msgid "There was a problem fetching branches."
msgstr "获å–分支时出现问题。"
msgid "There was a problem fetching emojis."
-msgstr ""
+msgstr "获å–表情符å·æ—¶å‡ºçŽ°é—®é¢˜ã€‚"
msgid "There was a problem fetching epics."
msgstr "获å–å²è¯—时出现问题。"
@@ -33308,11 +33614,14 @@ msgid "There was a problem fetching groups."
msgstr "获å–群组时出现问题。"
msgid "There was a problem fetching iterations."
-msgstr ""
+msgstr "获å–迭代时出现问题。"
msgid "There was a problem fetching labels."
msgstr "获å–标记时出错。"
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr "获å–里程碑时出错。"
@@ -33326,19 +33635,19 @@ msgid "There was a problem fetching project users."
msgstr "获å–项目用户时出错。"
msgid "There was a problem fetching recent groups."
-msgstr ""
+msgstr "获å–最近的群组时出现问题。"
msgid "There was a problem fetching recent projects."
-msgstr ""
+msgstr "获å–最近的项目时出现问题。"
msgid "There was a problem fetching the job token scope value"
-msgstr ""
+msgstr "获å–作业令牌范围值时出现问题"
msgid "There was a problem fetching the keep latest artifacts setting."
-msgstr ""
+msgstr "获å–ä¿æŒæœ€æ–°çš„产物设置时出现问题。"
msgid "There was a problem fetching the projects"
-msgstr ""
+msgstr "获å–项目时出现问题"
msgid "There was a problem fetching users."
msgstr "获å–用户时出现问题。"
@@ -33347,7 +33656,7 @@ msgid "There was a problem sending the confirmation email"
msgstr "å‘é€ç¡®è®¤é‚®ä»¶æ—¶å‡ºçŽ°é—®é¢˜"
msgid "There was a problem updating the keep latest artifacts setting."
-msgstr ""
+msgstr "æ›´æ–°ä¿æŒæœ€æ–°äº§ç‰©è®¾ç½®æ—¶å‡ºçŽ°é—®é¢˜ã€‚"
msgid "There was an error %{message} todo."
msgstr "%{message}待办事项时出现错误"
@@ -33371,7 +33680,7 @@ msgid "There was an error fetching configuration for charts"
msgstr "获å–图表的é…置时出错"
msgid "There was an error fetching content, please refresh the page"
-msgstr ""
+msgstr "获å–内容时出错,请刷新页é¢"
msgid "There was an error fetching data for the selected stage"
msgstr "获å–选定阶段的数æ®æ—¶å‡ºé”™"
@@ -33389,7 +33698,7 @@ msgid "There was an error fetching projects"
msgstr "获å–项目时出错"
msgid "There was an error fetching stage total counts"
-msgstr ""
+msgstr "获å–阶段总计数时出错"
msgid "There was an error fetching the %{replicableType}"
msgstr "获å–%{replicableType}时出错"
@@ -33407,7 +33716,7 @@ msgid "There was an error fetching the environments information."
msgstr "获å–环境信æ¯æ—¶å‡ºé”™ã€‚"
msgid "There was an error fetching the jobs for your project."
-msgstr ""
+msgstr "为您的项目获å–作业时出错。"
msgid "There was an error fetching the top labels for the selected group"
msgstr "获å–选中群组的顶级标记时出错"
@@ -33428,7 +33737,7 @@ msgid "There was an error importing the Jira project."
msgstr "导入Jira项目时出错。"
msgid "There was an error loading related feature flags"
-msgstr ""
+msgstr "加载相关功能标志时出错"
msgid "There was an error loading users activity calendar."
msgstr "加载用户活动日历时出错。"
@@ -33493,9 +33802,6 @@ msgstr "获å–图表数æ®æ—¶å‡ºé”™ã€‚请刷新页é¢ä»¥é‡è¯•ã€‚"
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr "获å–表格数æ®æ—¶å‡ºé”™ã€‚请刷新页é¢ä»¥é‡è¯•ã€‚"
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr "æå–价值æµåˆ†æž%{requestTypeName}æ•°æ®æ—¶å‡ºé”™ã€‚"
-
msgid "There was an error while fetching value stream analytics data."
msgstr "获å–值æµåˆ†æžæ•°æ®æ—¶å‡ºé”™ã€‚"
@@ -33503,7 +33809,7 @@ msgid "There was an error while fetching value stream analytics duration data."
msgstr "获å–价值æµåˆ†æžæŒç»­æ—¶é—´æ—¶å‡ºé”™ã€‚"
msgid "There was an error while fetching value stream summary data."
-msgstr ""
+msgstr "获å–价值æµæ±‡æ€»æ•°æ®æ—¶å‡ºé”™ã€‚"
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr "reCAPTCHA 验è¯é”™è¯¯ã€‚请å†æ¬¡éªŒè¯ reCAPTCHA。"
@@ -33512,7 +33818,7 @@ msgid "These dates affect how your epics appear in the roadmap. Set a fixed date
msgstr ""
msgid "These examples show how to trigger this project's pipeline for a branch or tag."
-msgstr ""
+msgstr "这些示例显示了如何为分支或标记触å‘此项目的æµæ°´çº¿ã€‚"
msgid "These existing issues have a similar title. It might be better to comment there instead of creating another similar issue."
msgstr "这些现有的议题具有类似的标题。在那里评论å¯èƒ½æ›´å¥½ï¼Œè€Œä¸æ˜¯åˆ›å»ºå¦ä¸€ä¸ªç±»ä¼¼çš„问题。"
@@ -33521,19 +33827,19 @@ msgid "These paths are protected for POST requests."
msgstr "这些路径å—POST请求ä¿æŠ¤ã€‚"
msgid "These runners are shared across projects in this group."
-msgstr ""
+msgstr "这些Runner在该群组中的项目之间共享。"
msgid "These runners are shared across this GitLab instance."
-msgstr ""
+msgstr "这些Runner在此 GitLab 实例中共享。"
msgid "These runners are specific to this project."
-msgstr ""
+msgstr "这些Runner是该项目所指定的。"
msgid "These variables are inherited from the parent group."
-msgstr ""
+msgstr "这些å˜é‡æ˜¯ä»Žä¸Šçº§ç¾¤ç»„继承的。"
msgid "These will be sent to %{email} in an attachment once finished."
-msgstr ""
+msgstr "这些将在附件完æˆåŽå‘é€è‡³ %{email}。"
msgid "Third Party Advisory Link"
msgstr "第三方建议链接"
@@ -33563,7 +33869,7 @@ msgid "This Cron pattern is invalid"
msgstr "æ­¤Cronæ ¼å¼æ— æ•ˆ"
msgid "This GitLab instance does not provide any shared runners yet. Instance administrators can register shared runners in the admin area."
-msgstr ""
+msgstr "æ­¤ GitLab 实例尚未æ供任何共享 Runner,实例管ç†å‘˜å¯ä»¥åœ¨ç®¡ç†ä¸­å¿ƒæ³¨å†Œå…±äº«Runner。"
msgid "This GitLab instance is licensed at the %{insufficient_license} tier. Geo is only available for users who have at least a Premium license."
msgstr "该GitLab实例的许å¯ä¸º%{insufficient_license}级别。拥有高级版或更高级别许å¯è¯çš„用户æ‰èƒ½ä½¿ç”¨Geo。"
@@ -33587,13 +33893,13 @@ msgid "This action has been performed too many times. Try again later."
msgstr "æ­¤æ“作已执行太多次。ç¨åŽå†è¯•ã€‚"
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
-msgstr ""
+msgstr "æ­¤æ“作将 %{strongOpen}ç«‹å³%{strongClose}%{strongOpen}永久删除%{strongClose} %{codeOpen}%{project}%{codeClose} ,包括其仓库和所有相关资æºï¼ŒåŒ…括议题和åˆå¹¶è¯·æ±‚。"
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
-msgstr ""
+msgstr "æ­¤æ“作将%{strongOpen}于 %{date}%{strongClose} %{strongOpen}永久删除%{strongClose} %{codeOpen}%{project}%{codeClose} ,包括其仓库和所有相关资æºï¼ŒåŒ…括议题和åˆå¹¶è¯·æ±‚。"
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
-msgstr ""
+msgstr "æ­¤æ“作将%{strongOpen}ç«‹å³%{strongClose}%{strongOpen}永久删除%{strongClose} %{codeOpen}%{group}%{codeClose}。"
msgid "This also resolves all related threads"
msgstr "这也会åŒæ—¶è§£å†³æ‰€æœ‰ç›¸å…³ä¸»é¢˜"
@@ -33602,25 +33908,25 @@ msgid "This also resolves this thread"
msgstr "这也会åŒæ—¶è§£å†³æ­¤ä¸»é¢˜"
msgid "This application was created by %{user_link}."
-msgstr ""
+msgstr "此应用程åºç”±%{user_link}创建。"
msgid "This application was created for group %{group_link}."
-msgstr ""
+msgstr "此应用程åºæ˜¯ä¸º%{group_link}群组创建的。"
msgid "This application will be able to:"
msgstr "此应用程åºå°†å¯ä»¥ï¼š"
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
-msgstr ""
+msgstr "此附件已被截断,以é¿å…超过最大å…è®¸çš„é™„ä»¶å¤§å° %{size_limit}。 其中包括%{count} 个%{issuables} 中的%{written_count}个。考虑缩å°é€‰æ‹©çš„ %{issuables} å†å¯¼å‡ºã€‚"
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{issues_count} issues have been included. Consider re-exporting with a narrower selection of issues."
-msgstr ""
+msgstr "此附件已被截断,以é¿å…超过最大å…è®¸çš„é™„ä»¶å¤§å° %{size_limit}。 其中包括了 %{issues_count} 个议题中的 %{written_count} 个,考虑缩å°å¯¼å‡ºçš„选择范围。"
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{merge_requests_count} merge requests have been included. Consider re-exporting with a narrower selection of merge requests."
-msgstr ""
+msgstr "此附件已被截断,以é¿å…超过最大å…è®¸çš„é™„ä»¶å¤§å° %{size_limit}。 其中包括%{merge_requests_count} 个åˆå¹¶è¯·æ±‚中的%{written_count}个。考虑缩å°åˆå¹¶è¯·æ±‚的选择范围。"
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{requirements_count} requirements have been included. Consider re-exporting with a narrower selection of requirements."
-msgstr ""
+msgstr "此附件已被截断,以é¿å…超过最大å…è®¸çš„é™„ä»¶å¤§å° %{size_limit}。 其中包括了 %{requirements_count} 项è¦æ±‚中的 %{written_count} 项;考虑缩å°å¯¼å‡ºçš„选择范围。"
msgid "This block is self-referential"
msgstr "该阻塞为自我引用"
@@ -33632,13 +33938,13 @@ msgid "This chart could not be displayed"
msgstr "无法显示此图表"
msgid "This clears repository check states for all projects in the database and cannot be undone. Are you sure?"
-msgstr ""
+msgstr "这会清除数æ®åº“中所有项目的仓库检查状æ€å¹¶ä¸”无法撤消。您确定å—?"
msgid "This code snippet contains everything reflected in the configuration form. Copy and paste it into %{linkStart}.gitlab-ci.yml%{linkEnd} file and save your changes. Future %{scanType} scans will use these settings."
-msgstr ""
+msgstr "此代ç æ®µåŒ…å«å映在é…置表å•ä¸­çš„所有内容。将其å¤åˆ¶å¹¶ç²˜è´´åˆ° %{linkStart}.gitlab-ci.yml%{linkEnd} 文件中并ä¿å­˜æ‚¨çš„更改。以åŽçš„ %{scanType} 扫æ将使用这些设置。"
msgid "This comment changed after you started editing it. Review the %{startTag}updated comment%{endTag} to ensure information is not lost."
-msgstr ""
+msgstr "此评论在您开始编辑åŽå‘生了å˜åŒ–。查看 %{startTag}更新评论%{endTag} 以确ä¿ä¿¡æ¯ä¸ä¼šä¸¢å¤±ã€‚"
msgid "This commit is part of merge request %{link_to_merge_request}. Comments created here will be created in the context of that merge request."
msgstr "æ­¤æ交是åˆå¹¶è¯·æ±‚ %{link_to_merge_request} 的一部分。此处创建的评论将在该åˆå¹¶è¯·æ±‚的上下文中创建。"
@@ -33704,40 +34010,37 @@ msgid "This epic does not exist or you don't have sufficient permission."
msgstr "æ­¤å²è¯—ä¸å­˜åœ¨æˆ–者您没有足够的æƒé™ã€‚"
msgid "This feature is part of your GitLab Ultimate trial."
-msgstr ""
+msgstr "此功能是旗舰版试用的一部分。"
msgid "This feature requires local storage to be enabled"
msgstr "此功能需è¦æœ¬åœ°å­˜å‚¨ä»¥å¯ç”¨"
msgid "This field is required"
-msgstr ""
+msgstr "此字段为必填项"
msgid "This field is required."
msgstr "该字段是必填字段。"
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr "当å‰ç¾¤ç»„"
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
-msgstr ""
+msgstr "此群组ä¸èƒ½è¢«åˆ é™¤ï¼Œå› ä¸ºå®ƒå·²é“¾æŽ¥åˆ°ä¸€ä¸ªè®¢é˜…,è¦åˆ é™¤æ­¤ç¾¤ç»„, %{linkStart}将订阅%{linkEnd} 链接到å¦ä¸€ä¸ªç¾¤ç»„。"
msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
-msgstr ""
+msgstr "无法转移此群组,因为它已链接到订阅。è¦è½¬ç§»è¿™ä¸ªç»„,与ä¸åŒçš„组%{linkStart}链接订阅%{linkEnd}。"
msgid "This group cannot be invited to a project inside a group with enforced SSO"
msgstr "此群组ä¸èƒ½è¢«é‚€è¯·åˆ°å¼ºåˆ¶SSO的群组中"
msgid "This group does not have any group runners yet."
-msgstr ""
+msgstr "此群组尚无任何群组Runner。"
msgid "This group has been scheduled for permanent removal on %{date}"
msgstr "此群组已安排在%{date}永久删除"
msgid "This group is linked to a subscription"
-msgstr ""
+msgstr "此群组已链接到订阅"
msgid "This group, including all subgroups, projects and git repositories, will be reachable from only the specified IP address ranges."
msgstr "此群组,包括所有å­ç¾¤ç»„ã€é¡¹ç›®å’Œgit仓库,将åªèƒ½ä»ŽæŒ‡å®šçš„IP地å€èŒƒå›´å†…访问。"
@@ -33749,13 +34052,13 @@ msgid "This group, its subgroups and projects will be removed on %{date} since i
msgstr "此群组ã€å…¶å­ç¾¤ç»„和项目将于%{date}被删除,因为其父群组'%{parent_group_name}‘已被安排移除。"
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
-msgstr ""
+msgstr "此邀请已å‘é€è‡³ %{mail_to_invite_email},但您以 %{link_to_current_user} 身份使用电å­é‚®ä»¶ %{mail_to_current_user}登录。"
msgid "This is a \"Ghost User\", created to hold all issues authored by users that have since been deleted. This user cannot be removed."
msgstr "此用户为“幽çµç”¨æˆ·â€ï¼Œç”¨äºŽæŒæœ‰è¢«åˆ é™¤ç”¨æˆ·çš„所有议题。该用户无法被删除。"
msgid "This is a Jira user."
-msgstr ""
+msgstr "这是一个 Jira 用户。"
msgid "This is a confidential %{noteableTypeText}."
msgstr "这是一个ç§å¯†%{noteableTypeText}。"
@@ -33767,10 +34070,10 @@ msgid "This is a list of devices that have logged into your account. Revoke any
msgstr "这是已登录到您å¸æˆ·çš„设备列表。您å¯ä»¥åˆ é™¤ä»»ä½•æ‚¨æ— æ³•è¯†åˆ«çš„会è¯ã€‚"
msgid "This is a merge train pipeline"
-msgstr ""
+msgstr "这是一个åˆå¹¶é˜Ÿåˆ—æµæ°´çº¿"
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
-msgstr ""
+msgstr "这是专为您生æˆçš„ç§äººç”µå­é‚®ä»¶åœ°å€ %{helpIcon} 任何拥有它的人都å¯ä»¥åƒæ‚¨ä¸€æ ·åˆ›å»ºé—®é¢˜æˆ–åˆå¹¶è¯·æ±‚。如果å‘生这ç§æƒ…况, %{resetLinkStart}é‡ç½®è¿™ä¸ªä»¤ç‰Œ%{resetLinkEnd}。"
msgid "This is a security log of important events involving your account."
msgstr "这是一个涉åŠæ‚¨çš„å¸æˆ·é‡è¦äº‹ä»¶çš„安全日志。"
@@ -33790,6 +34093,9 @@ msgstr "这是您当å‰çš„会è¯"
msgid "This issue is currently blocked by the following issues:"
msgstr "此问题目å‰è¢«ä»¥ä¸‹é—®é¢˜é˜»æ­¢ï¼š"
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr "此议题在筛选å²è¯—çš„å­å²è¯—中"
@@ -33980,7 +34286,7 @@ msgid "This project will be deleted on %{date}"
msgstr "此项目将于 %{date} 删除"
msgid "This project will be deleted on %{date} since its parent group '%{parent_group_name}' has been scheduled for deletion."
-msgstr ""
+msgstr "此项目将于 %{date} 删除,因为它的父组 '%{parent_group_name}'已计划删除。"
msgid "This project will live in your group %{strong_open}%{namespace}%{strong_close}. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
msgstr "该项目将存在于您的群组%{strong_open}%{namespace}%{strong_close}中。在项目中,您å¯ä»¥å­˜æ”¾æ–‡ä»¶(仓库),计划工作(议题),å‘布文档(Wiki)等等。"
@@ -34004,7 +34310,7 @@ msgid "This runner will only run on pipelines triggered on protected branches"
msgstr "æ­¤Runner仅在å—ä¿æŠ¤åˆ†æ”¯ä¸Šè§¦å‘çš„æµæ°´çº¿ä¸Šè¿è¡Œ"
msgid "This service allows users to perform common operations on this project by entering slash commands in Slack."
-msgstr ""
+msgstr "æ­¤æœåŠ¡å…许用户通过在Slack输入 slash command æ¥æ‰§è¡Œæ­¤é¡¹ç›®çš„常è§æ“作。"
msgid "This setting can be overridden in each project."
msgstr "当å‰è®¾ç½®å¯åœ¨æ¯ä¸ªé¡¹ç›®ä¸­è¿›è¡Œæ›´æ”¹è¦†ç›–。"
@@ -34022,10 +34328,10 @@ msgid "This user does not have a pending request"
msgstr "此用户没有待处ç†è¯·æ±‚"
msgid "This user has an unconfirmed email address (%{email}). You may force a confirmation."
-msgstr ""
+msgstr "此用户有一个未ç»ç¡®è®¤çš„电å­é‚®ä»¶åœ°å€ (%{email})。您å¯ä»¥å¼ºåˆ¶ç¡®è®¤ã€‚"
msgid "This user has an unconfirmed email address. You may force a confirmation."
-msgstr ""
+msgstr "此用户有一个未ç»ç¡®è®¤çš„电å­é‚®ä»¶åœ°å€ã€‚您å¯ä»¥å¼ºåˆ¶ç¡®è®¤ã€‚"
msgid "This user has no active %{type}."
msgstr "此用户没有有效的%{type}。"
@@ -34034,7 +34340,7 @@ msgid "This user has no identities"
msgstr "该用户无身份标识"
msgid "This user has no personal projects."
-msgstr ""
+msgstr "该用户没有个人项目。"
msgid "This user has previously committed to the %{name} project."
msgstr "该用户曾ç»æ交到%{name}项目。"
@@ -34088,7 +34394,7 @@ msgid "ThreatMonitoring|Date and time"
msgstr "日期和时间"
msgid "ThreatMonitoring|Dismissed"
-msgstr ""
+msgstr "已解除"
msgid "ThreatMonitoring|Dropped Packets"
msgstr "丢弃数æ®åŒ…"
@@ -34103,10 +34409,10 @@ msgid "ThreatMonitoring|Failed to create incident, please try again."
msgstr "无法创建事件,请é‡è¯•ã€‚"
msgid "ThreatMonitoring|Hide dismissed alerts"
-msgstr ""
+msgstr "éšè—已解除的警报"
msgid "ThreatMonitoring|In review"
-msgstr ""
+msgstr "审查中"
msgid "ThreatMonitoring|Incident"
msgstr "事件"
@@ -34115,7 +34421,7 @@ msgid "ThreatMonitoring|Name"
msgstr "å称"
msgid "ThreatMonitoring|No alerts available to display. See %{linkStart}enabling threat alerts%{linkEnd} for more information on adding alerts to the list."
-msgstr ""
+msgstr "没有å¯æ˜¾ç¤ºçš„警报。有关将警报添加到列表的详细信æ¯ï¼Œè¯·å‚阅 %{linkStart}å¯ç”¨å¨èƒè­¦æŠ¥%{linkEnd}"
msgid "ThreatMonitoring|No alerts to display."
msgstr "没有è¦æ˜¾ç¤ºçš„警报。"
@@ -34154,10 +34460,10 @@ msgid "ThreatMonitoring|Status"
msgstr "状æ€"
msgid "ThreatMonitoring|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
-msgstr ""
+msgstr "显示警报时å‘生错误,请确认您的终端é…置详细信æ¯ä»¥ç¡®ä¿è­¦æŠ¥å¯ä»¥æ­£å¸¸æ˜¾ç¤ºã€‚"
msgid "ThreatMonitoring|There was an error while updating the status of the alert. Please try again."
-msgstr ""
+msgstr "更新警报状æ€æ—¶å‡ºé”™ï¼Œè¯·é‡å†è¯•ã€‚"
msgid "ThreatMonitoring|Threat Monitoring"
msgstr "å¨èƒç›‘测"
@@ -34169,7 +34475,7 @@ msgid "ThreatMonitoring|Time"
msgstr "时间"
msgid "ThreatMonitoring|To view this data, ensure you have configured an environment for this project and that at least one threat monitoring feature is enabled. %{linkStart}More information%{linkEnd}"
-msgstr ""
+msgstr "è¦æŸ¥çœ‹æ­¤æ•°æ®ï¼Œè¯·ç¡®ä¿æ‚¨å·²ä¸ºæ­¤é¡¹ç›®é…置环境并且至少å¯ç”¨äº†ä¸€é¡¹å¨èƒç›‘控功能。 %{linkStart}更多信æ¯%{linkEnd}"
msgid "ThreatMonitoring|Total Packets"
msgstr "总数æ®åŒ…"
@@ -34178,7 +34484,7 @@ msgid "ThreatMonitoring|Total Requests"
msgstr "总请求"
msgid "ThreatMonitoring|Unreviewed"
-msgstr ""
+msgstr "未审核"
msgid "ThreatMonitoring|View documentation"
msgstr "查看文档"
@@ -34394,7 +34700,7 @@ msgid "Timeago|just now"
msgstr "刚刚"
msgid "Timeago|right now"
-msgstr "ç«‹å³"
+msgstr "刚刚"
msgid "Timeline|Turn timeline view off"
msgstr "关闭时间线视图"
@@ -34435,7 +34741,7 @@ msgid "Tip: Hover over a job to see the jobs it depends on to run."
msgstr "æ示:将鼠标悬åœåœ¨ä½œä¸šä¸Šå¯æŸ¥çœ‹å…¶è¿è¡Œæ‰€ä¾èµ–的作业。"
msgid "Tip: add a %{linkStart}CODEOWNERS%{linkEnd} to automatically add approvers based on file paths and file types."
-msgstr ""
+msgstr "æ示:添加 %{linkStart}CODEOWNERS%{linkEnd} 以根æ®æ–‡ä»¶è·¯å¾„和文件类型自动添加审批人。"
msgid "Title"
msgstr "标题"
@@ -34492,7 +34798,7 @@ msgid "To connect an SVN repository, check out %{svn_link}."
msgstr "如è¦è¿žæŽ¥SVN仓库,请查看 %{svn_link}。"
msgid "To continue, you need to select the link in the confirmation email we sent to verify your email address. If you didn't get our email, select %{strongStart}Resend confirmation email.%{strongEnd}"
-msgstr ""
+msgstr "è¦ç»§ç»­ï¼Œæ‚¨éœ€è¦é€‰æ‹©æˆ‘们å‘é€çš„确认电å­é‚®ä»¶ä¸­çš„链接以验è¯æ‚¨çš„电å­é‚®ä»¶åœ°å€ã€‚如果您没有收到我们的电å­é‚®ä»¶ï¼Œè¯·é€‰æ‹© %{strongStart}é‡æ–°å‘é€ç¡®è®¤ç”µå­é‚®ä»¶ã€‚%{strongEnd}"
msgid "To define internal users, first enable new users set to external"
msgstr "è¦å®šä¹‰å†…部用户,请首先å¯ç”¨è®¾ç½®ä¸ºå¤–部的新用户"
@@ -34504,7 +34810,7 @@ msgid "To ensure no loss of personal content, this account should only be used f
msgstr "为ä¿è¯ä¸ªäººå†…容ä¸ä¸¢å¤±ï¼Œæœ¬è´¦å·ä»…用于与 %{group_name}相关的事项。"
msgid "To find the state of this project's repository at the time of any of these versions, check out %{link_start}the tags%{link_end}."
-msgstr ""
+msgstr "è¦åœ¨ä»»ä½•è¿™äº›ç‰ˆæœ¬ä¸­æŸ¥æ‰¾æ­¤é¡¹ç›®å­˜å‚¨åº“的状æ€ï¼Œè¯·æ£€æŸ¥ %{link_start}标签%{link_end}。"
msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
msgstr "为了进一步ä¿æŠ¤æ‚¨çš„å¸æˆ·ï¼Œè¯·è€ƒè™‘é…置一个%{mfa_link_start}åŒé‡èº«ä»½éªŒè¯%{mfa_link_end}方法。"
@@ -34549,10 +34855,10 @@ msgid "To only use CI/CD features for an external repository, choose %{strong_op
msgstr "如需外部仓库仅使用CI/CD功能时,请选择%{strong_open}使用外部仓库è¿è¡ŒCI/CD%{strong_close}。"
msgid "To pass variables to the triggered pipeline, add %{code_start}variables[VARIABLE]=VALUE%{code_end} to the API request."
-msgstr ""
+msgstr "è‹¥è¦å°†å˜é‡ä¼ é€’到触å‘æµæ°´çº¿ï¼Œè¯·åœ¨ API 请求中添加 %{code_start}å˜é‡[VARIABLE]=VALUE%{code_end}。"
msgid "To personalize your GitLab experience, we'd like to know a bit more about you"
-msgstr ""
+msgstr "为了个性化您的GitLab体验,我们想了解更多关于您的信æ¯"
msgid "To preserve performance only %{strong_open}%{display_size} of %{real_size}%{strong_close} files are displayed."
msgstr "为了ä¿è¯æ€§èƒ½ï¼Œä»…显示文件中的总计%{strong_open}%{real_size}中的%{display_size}%{strong_close}。"
@@ -34564,10 +34870,10 @@ msgid "To protect this issue's confidentiality, a private fork of this project w
msgstr "为了ä¿è¯æ­¤è®®é¢˜çš„ç§å¯†æ€§ï¼Œé€‰æ‹©äº†è¯¥é¡¹ç›®çš„ç§æœ‰æ´¾ç”Ÿã€‚"
msgid "To reactivate your account, %{gitlab_link_start}sign in to GitLab.%{link_end}"
-msgstr ""
+msgstr "è¦é‡æ–°æ¿€æ´»æ‚¨çš„å¸æˆ·ï¼Œ %{gitlab_link_start}登录到 GitLab。%{link_end}"
msgid "To reactivate your account, sign in to GitLab at %{gitlab_url}."
-msgstr ""
+msgstr "è¦é‡æ–°æ¿€æ´»æ‚¨çš„å¸æˆ·ï¼Œè¯·åœ¨ %{gitlab_url}登录 GitLab。"
msgid "To receive alerts from manually configured Prometheus services, add the following URL and Authorization key to your Prometheus webhook config file. Learn more about %{linkStart}configuring Prometheus%{linkEnd} to send alerts to GitLab."
msgstr "è¦ä»Žæ‰‹åŠ¨é…置的PrometheusæœåŠ¡æŽ¥æ”¶è­¦æŠ¥ï¼Œè¯·å°†ä»¥ä¸‹URL和授æƒå¯†é’¥æ·»åŠ åˆ°Prometheus webhooké…置文件中。了解更多关于 %{linkStart}é…ç½®Prometheus%{linkEnd} 将警报å‘é€åˆ°GitLab。"
@@ -34582,7 +34888,7 @@ msgid "To see all the user's personal access tokens you must impersonate them fi
msgstr "è¦æŸ¥çœ‹ç”¨æˆ·çš„所有个人访问令牌,您必须先模拟其身份。"
msgid "To see this project's operational details, %{linkStart}upgrade its group plan to Premium%{linkEnd}. You can also remove the project from the dashboard."
-msgstr ""
+msgstr "è¦æŸ¥çœ‹æ­¤é¡¹ç›®çš„æ“作详情, %{linkStart}将群组方案å‡çº§åˆ°ä¸“业版%{linkEnd}。您也å¯ä»¥ä»Žä»ªè¡¨ç›˜ä¸­åˆ é™¤è¯¥é¡¹ç›®ã€‚"
msgid "To see this project's operational details, contact an owner of group %{groupName} to upgrade the plan. You can also remove the project from the dashboard."
msgstr "è¦æŸ¥çœ‹è¯¥é¡¹ç›®çš„è¿ç»´è¯¦ç»†ä¿¡æ¯ï¼Œè¯·ä¸Ž%{groupName}群组的所有者è”系以å‡çº§è®¢é˜…计划。或者您也å¯ä»¥ä»Žä»ªè¡¨æ¿ä¸Šåˆ é™¤æ­¤é¡¹ç›®ã€‚"
@@ -34606,7 +34912,7 @@ msgid "To use Gitpod you must first enable the feature in the integrations secti
msgstr "è¦ä½¿ç”¨Gitpod,您必须首先在 %{user_prefs}的“集æˆâ€éƒ¨åˆ†ä¸­å¯ç”¨è¯¥åŠŸèƒ½ã€‚"
msgid "To use the additional formats, you must start the required %{container_link_start}companion containers%{container_link_end}."
-msgstr ""
+msgstr "è¦ä½¿ç”¨å…¶å®ƒæ ¼å¼ï¼Œæ‚¨å¿…é¡»å¯åŠ¨æ‰€éœ€çš„ %{container_link_start}ä¼´éšå®¹å™¨%{container_link_end}。"
msgid "To view all %{scannedResourcesCount} scanned URLs, %{linkStart}please download the CSV file%{linkEnd}"
msgstr "如需查看所有%{scannedResourcesCount}已扫æ网å€ï¼Œ%{linkStart}请下载CSV文件%{linkEnd}"
@@ -34615,7 +34921,7 @@ msgid "To widen your search, change or remove filters above"
msgstr "è¦æ‰©å¤§æœç´¢èŒƒå›´ï¼Œè¯·æ›´æ”¹æˆ–删除上é¢çš„筛选器"
msgid "To widen your search, change or remove filters above."
-msgstr ""
+msgstr "è¦æ‰©å¤§æœç´¢èŒƒå›´ï¼Œè¯·æ›´æ”¹æˆ–删除上é¢çš„筛选器。"
msgid "To widen your search, change or remove filters."
msgstr "需è¦æ‰©å¤§æœç´¢èŒƒå›´ï¼Œè¯·æ›´æ”¹æˆ–移除筛选æ¡ä»¶ã€‚"
@@ -34702,7 +35008,7 @@ msgid "Token valid until revoked"
msgstr "令牌有效直至被撤销"
msgid "Tokens|Scopes set the permission levels granted to the token."
-msgstr ""
+msgstr "范围设置授予令牌的æƒé™çº§åˆ«ã€‚"
msgid "Tokens|Select scopes"
msgstr "选择范围"
@@ -34771,13 +35077,13 @@ msgid "Track groups of issues that share a theme, across projects and milestones
msgstr "在ä¸åŒé¡¹ç›®å’Œé‡Œç¨‹ç¢‘中跟踪具有åŒä¸€ä¸»é¢˜çš„议题组"
msgid "Track important events in your GitLab instance."
-msgstr ""
+msgstr "跟踪您的 GitLab 实例中的é‡è¦äº‹ä»¶ã€‚"
msgid "Track important events in your group."
-msgstr ""
+msgstr "跟踪您的群组中的é‡è¦äº‹ä»¶ã€‚"
msgid "Track important events in your project."
-msgstr ""
+msgstr "跟踪您的项目中的é‡è¦äº‹ä»¶ã€‚"
msgid "Track time with quick actions"
msgstr "使用快æ·æ“作æ¥ç»Ÿè®¡å·¥æ—¶"
@@ -34795,7 +35101,7 @@ msgid "Transfer project"
msgstr "转移项目"
msgid "Transfer your project into another namespace. %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "将您的项目转移到å¦ä¸€ä¸ªå‘½å空间。 %{link_start}了解更多。%{link_end}"
msgid "TransferGroup|Cannot transfer group to one of its subgroup."
msgstr "无法将群组转移到其å­ç¾¤ç»„。"
@@ -34833,14 +35139,20 @@ msgstr "请为项目选择新命å空间。"
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr "项目无法转移,因为标签存在于其容器镜åƒåº“中"
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr "目标命å空间中已存在具有相åŒå称或路径的项目"
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr "如果项目具有NPM软件包,则无法更新根命å空间"
-msgid "TransferProject|Transfer failed, please contact an admin."
-msgstr "转移失败,请è”系管ç†å‘˜ã€‚"
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
+msgstr ""
msgid "Tree view"
msgstr "树形视图"
@@ -34850,13 +35162,13 @@ msgstr "热门"
msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
+msgstr[0] "%{planName} 试用版 %{enDash} 剩下 %{num} 天"
msgid "Trials|Compare all plans"
-msgstr ""
+msgstr "比较所有方案"
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
-msgstr ""
+msgstr "创建一个新群组以开始您的旗舰版试用。"
msgid "Trials|Go back to GitLab"
msgstr "返回GitLab"
@@ -34868,28 +35180,28 @@ msgid "Trials|Skip Trial"
msgstr "跳过试用"
msgid "Trials|Upgrade %{groupName} to %{planName}"
-msgstr ""
+msgstr "å‡çº§ %{groupName} 到 %{planName}"
msgid "Trials|You can always resume this process by selecting your avatar and choosing 'Start an Ultimate trial'"
-msgstr ""
+msgstr "您å¯ä»¥é€šè¿‡é€‰æ‹©æ‚¨çš„头åƒå¹¶é€‰æ‹©â€œå¼€å§‹è¯•ç”¨â€æ¥æ¢å¤æ­¤è¿›ç¨‹ã€‚"
msgid "Trials|You can apply your trial to a new group or an existing group."
msgstr "您å¯ä»¥å°†æ‚¨åœ¨ä¸€ä¸ªæ–°ç¾¤ç»„或一个现有群组上é¢è¿›è¡Œè¯•ç”¨ã€‚"
msgid "Trials|You won't get a free trial right now but you can always resume this process by selecting your avatar and choosing 'Start an Ultimate trial'"
-msgstr ""
+msgstr "您现在无法获得å…费试用,但您å¯ä»¥éšæ—¶é€šè¿‡é€‰æ‹©æ‚¨çš„头åƒå¹¶é€‰æ‹©â€œå¼€å§‹æ——舰版试用â€æ¥æ¢å¤æ­¤è¿›ç¨‹ã€‚"
msgid "Trials|Your trial ends on %{boldStart}%{trialEndDate}%{boldEnd}. We hope you’re enjoying the features of GitLab %{planName}. To keep those features after your trial ends, you’ll need to buy a subscription. (You can also choose GitLab Premium if it meets your needs.)"
-msgstr ""
+msgstr "您的试用版在 %{boldStart}%{trialEndDate}%{boldEnd}结æŸï¼Œæˆ‘们希望您能享å—GitLab %{planName}的功能,为了在试用结æŸåŽä¿ç•™è¿™äº›åŠŸèƒ½ï¼Œæ‚¨éœ€è¦è´­ä¹°è®¢é˜…。(如果您满足您的需è¦ï¼Œæ‚¨ä¹Ÿå¯ä»¥é€‰æ‹©ä¸“业版。)"
msgid "Trial|Company name"
msgstr "å…¬å¸å称"
msgid "Trial|Continue"
-msgstr ""
+msgstr "继续"
msgid "Trial|Continue using the basic features of GitLab for free."
-msgstr ""
+msgstr "继续å…费使用基本功能。"
msgid "Trial|Country"
msgstr ""
@@ -34898,7 +35210,7 @@ msgid "Trial|Dismiss"
msgstr ""
msgid "Trial|First name"
-msgstr ""
+msgstr "åå­—"
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
@@ -34913,10 +35225,10 @@ msgid "Trial|How many users will be evaluating the trial?"
msgstr ""
msgid "Trial|Last name"
-msgstr ""
+msgstr "姓æ°"
msgid "Trial|Number of employees"
-msgstr ""
+msgstr "员工人数"
msgid "Trial|Please select a country"
msgstr ""
@@ -34943,7 +35255,7 @@ msgid "Trigger"
msgstr "触å‘器"
msgid "Trigger a pipeline for a branch or tag by generating a trigger token and using it with an API call. The token impersonates a user's project access and permissions."
-msgstr ""
+msgstr "通过生æˆè§¦å‘令牌并将其与 API 调用一起使用,为分支或标签触å‘æµæ°´çº¿ã€‚令牌模拟用户的项目访问和æƒé™ã€‚"
msgid "Trigger cluster reindexing"
msgstr "触å‘集群é‡å»ºç´¢å¼•"
@@ -34988,7 +35300,7 @@ msgid "Troubleshoot and monitor your application with tracing"
msgstr "使用跟踪对应用程åºè¿›è¡Œæ•…障排除与监控"
msgid "Trusted"
-msgstr ""
+msgstr "å¯ä¿¡çš„"
msgid "Try again"
msgstr "请é‡è¯•"
@@ -35003,7 +35315,7 @@ msgid "Try changing or removing filters."
msgstr "请å°è¯•æ›´æ”¹æˆ–删除筛选器。"
msgid "Try grouping with different labels"
-msgstr ""
+msgstr "å°è¯•ä½¿ç”¨ä¸åŒçš„标记分组"
msgid "Try to fork again"
msgstr "å°è¯•å†æ¬¡æ´¾ç”Ÿ"
@@ -35099,19 +35411,19 @@ msgid "URL is required"
msgstr "URL是必需的"
msgid "URL is triggered for each branch updated to the repository"
-msgstr ""
+msgstr "为æ¯ä¸ªæ›´æ–°åˆ°ä»“åº“çš„åˆ†æ”¯è§¦å‘ URL"
msgid "URL is triggered when a merge request is created, updated, or merged"
-msgstr ""
+msgstr "创建ã€æ›´æ–°æˆ–åˆå¹¶åˆå¹¶è¯·æ±‚æ—¶è§¦å‘ URL"
msgid "URL is triggered when a new tag is pushed to the repository"
-msgstr ""
+msgstr "将新标签推é€åˆ°ä»“åº“æ—¶ä¼šè§¦å‘ URL"
msgid "URL is triggered when repository is updated"
-msgstr ""
+msgstr "æ›´æ–°ä»“åº“æ—¶è§¦å‘ URL"
msgid "URL must be percent-encoded if neccessary."
-msgstr ""
+msgstr "如有必è¦ï¼ŒURL 必须进行百分比编ç ã€‚"
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr "URL必须以%{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}或%{codeStart}ftp://%{codeEnd}开始"
@@ -35171,10 +35483,10 @@ msgid "Unable to create link to vulnerability"
msgstr "无法创建到æ¼æ´žçš„链接"
msgid "Unable to fetch branch list for this project."
-msgstr ""
+msgstr "无法获å–此项目的分支列表。"
msgid "Unable to fetch branches list, please close the form and try again"
-msgstr ""
+msgstr "无法获å–分支列表,请关闭表å•å¹¶é‡è¯•"
msgid "Unable to fetch unscanned projects"
msgstr "无法获å–未扫æ的项目"
@@ -35204,7 +35516,7 @@ msgid "Unable to load the merge request widget. Try reloading the page."
msgstr "无法加载åˆå¹¶è¯·æ±‚部件。请å°è¯•é‡æ–°åŠ è½½é¡µé¢ã€‚"
msgid "Unable to save cadence. Please try again"
-msgstr ""
+msgstr "无法ä¿å­˜å‘¨æœŸã€‚请å†è¯•ä¸€æ¬¡"
msgid "Unable to save iteration. Please try again"
msgstr "无法ä¿å­˜è¿­ä»£ã€‚请é‡è¯•"
@@ -35246,10 +35558,10 @@ msgid "Unassigned"
msgstr "未分é…"
msgid "Unauthenticated API request rate limit"
-msgstr ""
+msgstr "未ç»èº«ä»½éªŒè¯çš„ API 请求速率é™åˆ¶"
msgid "Unauthenticated rate limit period in seconds"
-msgstr ""
+msgstr "未ç»èº«ä»½éªŒè¯çš„速率é™åˆ¶æ—¶é—´ï¼ˆä»¥ç§’为å•ä½ï¼‰"
msgid "Unauthenticated request rate limit"
msgstr "无身份验è¯çš„API请求速率é™åˆ¶"
@@ -35401,6 +35713,9 @@ msgstr "传入了ä¸æ”¯æŒçš„待办事项类型。支æŒçš„待办事项类型为
msgid "Until"
msgstr "直到"
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr "未使用"
@@ -35615,14 +35930,11 @@ msgid "UsageQuota|LFS Storage"
msgstr "LFS存储"
msgid "UsageQuota|Learn more about excess storage usage"
-msgstr ""
+msgstr "了解有关超é¢å­˜å‚¨ä½¿ç”¨é‡çš„更多信æ¯"
msgid "UsageQuota|Learn more about usage quotas"
msgstr "了解有关使用é…é¢çš„更多信æ¯"
-msgid "UsageQuota|Other Storage"
-msgstr "其他存储"
-
msgid "UsageQuota|Packages"
msgstr "软件包"
@@ -35641,9 +35953,15 @@ msgstr "仓库"
msgid "UsageQuota|Repository"
msgstr "仓库"
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr "代ç ç‰‡æ®µ"
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr "存储"
@@ -35692,6 +36010,9 @@ msgstr "使用é‡é…é¢"
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr "%{strong_start}%{group_name}%{strong_end}群组中的项目使用群组资æºçŠ¶å†µ"
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr "您的项目中资æºä½¿ç”¨æƒ…况"
@@ -35777,31 +36098,31 @@ msgid "UsageTrends|Projects"
msgstr "项目"
msgid "UsageTrends|There was an error fetching the cancelled pipelines. Please try again."
-msgstr ""
+msgstr "获å–å·²å–消的æµæ°´çº¿æ—¶å‡ºé”™ï¼Œè¯·é‡è¯•ã€‚"
msgid "UsageTrends|There was an error fetching the failed pipelines. Please try again."
-msgstr ""
+msgstr "获å–失败的æµæ°´çº¿æ—¶å‡ºé”™ã€‚请é‡è¯•ã€‚"
msgid "UsageTrends|There was an error fetching the groups. Please try again."
-msgstr ""
+msgstr "获å–群组时出错,请é‡è¯•ã€‚"
msgid "UsageTrends|There was an error fetching the issues. Please try again."
-msgstr ""
+msgstr "获å–议题时出错,请é‡è¯•ã€‚"
msgid "UsageTrends|There was an error fetching the merge requests. Please try again."
-msgstr ""
+msgstr "获å–åˆå¹¶è¯·æ±‚时出错,请é‡è¯•ã€‚"
msgid "UsageTrends|There was an error fetching the projects. Please try again."
-msgstr ""
+msgstr "获å–项目时出错,请é‡è¯•ã€‚"
msgid "UsageTrends|There was an error fetching the skipped pipelines. Please try again."
-msgstr ""
+msgstr "获å–跳过的æµæ°´çº¿æ—¶å‡ºé”™ï¼Œè¯·é‡è¯•ã€‚"
msgid "UsageTrends|There was an error fetching the successful pipelines. Please try again."
-msgstr ""
+msgstr "获å–æˆåŠŸçš„æµæ°´çº¿æ—¶å‡ºé”™ï¼Œè¯·é‡è¯•ã€‚"
msgid "UsageTrends|There was an error fetching the total pipelines. Please try again."
-msgstr ""
+msgstr "获å–æµæ°´çº¿æ€»æ•°æ—¶å‡ºé”™ï¼Œè¯·å†è¯•ã€‚"
msgid "UsageTrends|Total groups"
msgstr "群组总数"
@@ -35822,22 +36143,22 @@ msgid "Use .gitlab-ci.yml"
msgstr "使用 .gitlab-ci.yml"
msgid "Use GitLab Runner in AWS"
-msgstr ""
+msgstr "在 AWS 中使用 GitLab Runner"
msgid "Use a one-time password authenticator on your mobile device or computer to enable two-factor authentication (2FA)."
-msgstr ""
+msgstr "在您的移动设备或计算机上使用一次性密ç éªŒè¯å™¨æ¥å¯ç”¨åŒé‡éªŒè¯ (2FA)。"
msgid "Use an AWS CloudFormation Template (CFT) to install and configure GitLab Runner in AWS."
msgstr ""
msgid "Use cURL"
-msgstr ""
+msgstr "使用 cURL"
msgid "Use custom color #FF0000"
msgstr "使用自定义颜色#FF0000"
msgid "Use double quotes for multiple keywords, such as %{code_open}\"your search\"%{code_close}"
-msgstr ""
+msgstr "对多个关键字使用åŒå¼•å·ï¼Œä¾‹å¦‚ %{code_open}\"您的æœç´¢\"%{code_close}"
msgid "Use hashed storage"
msgstr "使用哈希存储"
@@ -35848,32 +36169,35 @@ msgstr ""
msgid "Use one line per URI"
msgstr "æ¯ä¸ªURIå ä¸€è¡Œ"
-msgid "Use shortcuts"
+msgid "Use primary email (%{email})"
msgstr ""
+msgid "Use shortcuts"
+msgstr "使用快æ·é”®"
+
msgid "Use slash commands."
-msgstr ""
+msgstr "使用斜线命令。"
msgid "Use template"
msgstr "使用模æ¿"
msgid "Use the link below to confirm your email address (%{email})"
-msgstr ""
+msgstr "使用以下链接确认您的电å­é‚®ä»¶åœ°å€ (%{email})"
msgid "Use the link below to confirm your email address."
-msgstr ""
+msgstr "使用下é¢çš„链接确认您的电å­é‚®ä»¶åœ°å€ã€‚"
msgid "Use the public cloud instance URL (%{kroki_public_url}) or %{install_link_start}install Kroki%{install_link_end} on your own infrastructure and use your own instance URL."
-msgstr ""
+msgstr "使用公共云实例 URL (%{kroki_public_url}) 或 %{install_link_start}在您自己的基础架构上安装 Kroki%{install_link_end} 并使用您自己的实例 URL。"
msgid "Use the search bar on the top of this page"
-msgstr ""
+msgstr "使用本页顶部的æœç´¢æ "
msgid "Use this token to validate received payloads."
-msgstr ""
+msgstr "使用此令牌æ¥éªŒè¯æ”¶åˆ°çš„有效数æ®ã€‚"
msgid "Use webhook"
-msgstr ""
+msgstr "使用 webhook"
msgid "Use your global notification setting"
msgstr "使用全局通知设置"
@@ -35882,13 +36206,13 @@ msgid "Use your smart card to authenticate with the LDAP server."
msgstr "使用智能å¡å¯¹LDAPæœåŠ¡å™¨è¿›è¡Œèº«ä»½éªŒè¯ã€‚"
msgid "Used"
-msgstr ""
+msgstr "已使用"
msgid "Used by members to sign in to your group in GitLab"
msgstr "ä¾›æˆå‘˜ç™»å½•æ‚¨çš„GitLab群组"
msgid "Used by more than 100,000 organizations, GitLab is the most popular solution to manage git repositories on-premises."
-msgstr ""
+msgstr "我们被超过 100,000 个组织使用,是管ç†æœ¬åœ° git 存储库的最å—欢迎的解决方案。"
msgid "Used programming language"
msgstr "使用的编程语言"
@@ -35909,7 +36233,7 @@ msgid "User %{username} was successfully removed."
msgstr "用户 %{username} å·²æˆåŠŸåˆ é™¤ã€‚"
msgid "User %{user} was removed from %{group}."
-msgstr ""
+msgstr "用户 %{user} 已从 %{group} 移除。"
msgid "User ID"
msgstr "用户ID"
@@ -35936,7 +36260,7 @@ msgid "User is not allowed to resolve thread"
msgstr "用户ä¸å…许解决主题"
msgid "User key"
-msgstr ""
+msgstr "用户密钥"
msgid "User key was successfully removed."
msgstr "用户密钥已æˆåŠŸåˆ é™¤ã€‚"
@@ -35960,10 +36284,10 @@ msgid "User was successfully created."
msgstr "用户已æˆåŠŸåˆ›å»ºã€‚"
msgid "User was successfully removed from group and any subgroups and projects."
-msgstr ""
+msgstr "å·²æˆåŠŸä»Žç¾¤ç»„ã€å­ç¾¤ç»„和项目中移除该用户。"
msgid "User was successfully removed from group."
-msgstr ""
+msgstr "用户已æˆåŠŸä»Žç¾¤ç»„中删除。"
msgid "User was successfully removed from project."
msgstr "用户已æˆåŠŸä»Žé¡¹ç›®ä¸­åˆ é™¤ã€‚"
@@ -35975,7 +36299,7 @@ msgid "User-based escalation rules must have a user with access to the project"
msgstr ""
msgid "UserAvailability|%{author} %{spanStart}(Busy)%{spanEnd}"
-msgstr ""
+msgstr "%{author} %{spanStart}(忙碌)%{spanEnd}"
msgid "UserAvailability|%{author} (Busy)"
msgstr "%{author} (忙碌)"
@@ -36029,7 +36353,7 @@ msgid "UserLists|New list"
msgstr "新建列表"
msgid "UserLists|New user list"
-msgstr ""
+msgstr "新建用户列表"
msgid "UserLists|Save"
msgstr "ä¿å­˜"
@@ -36050,7 +36374,7 @@ msgid "UserLists|User Lists"
msgstr "用户列表"
msgid "UserLists|User lists allow you to define a set of users to use with Feature Flags."
-msgstr ""
+msgstr "用户列表å…许您定义一组与功能标志一起使用的用户。"
msgid "UserList|Delete %{name}?"
msgstr "删除%{name}å—?"
@@ -36215,10 +36539,10 @@ msgid "Users"
msgstr "用户"
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
-msgstr ""
+msgstr "%{linkStart}Gitpod%{linkEnd} 集æˆåŽï¼Œç”¨æˆ·å¯ä»¥ä»Ž GitLab æµè§ˆå™¨é€‰é¡¹å¡å¯åŠ¨å¼€å‘环境。"
msgid "Users can render diagrams in AsciiDoc, Markdown, reStructuredText, and Textile documents using Kroki."
-msgstr ""
+msgstr "用户å¯ä»¥ä½¿ç”¨ Kroki 在 AsciiDocã€Markdownã€reStructuredText å’Œ Textile 文档中渲染图表。"
msgid "Users in License"
msgstr "许å¯è¯ä¸­çš„用户数"
@@ -36227,7 +36551,7 @@ msgid "Users or groups set as approvers in the project's or merge request's sett
msgstr "在项目或åˆå¹¶è¯·æ±‚的设置中设为审批人的用户或群组。"
msgid "Users over License"
-msgstr ""
+msgstr "超出许å¯è¯çš„用户数"
msgid "Users requesting access to"
msgstr "请求访问的用户"
@@ -36287,7 +36611,7 @@ msgid "Value Stream Analytics gives an overview of how much time it takes to go
msgstr "价值æµåˆ†æžæ¦‚述了项目从想法到产å“实现的å„阶段所需的时间。"
msgid "Value may contain a variable reference"
-msgstr ""
+msgstr "值å¯èƒ½åŒ…å«å˜é‡å¼•ç”¨"
msgid "Value stream"
msgstr "价值æµ"
@@ -36296,46 +36620,52 @@ msgid "ValueStreamAnalyticsStage|We don't have enough data to show this stage."
msgstr "我们没有足够的数æ®æ¥æ˜¾ç¤ºæ­¤é˜¶æ®µã€‚"
msgid "ValueStreamAnalytics|%{stageCount}+ items"
-msgstr ""
+msgstr "%{stageCount}+ 项"
msgid "ValueStreamAnalytics|%{value}M"
-msgstr ""
+msgstr "%{value}月"
msgid "ValueStreamAnalytics|%{value}d"
-msgstr ""
+msgstr "%{value}天"
msgid "ValueStreamAnalytics|%{value}h"
-msgstr ""
+msgstr "%{value}å°æ—¶"
msgid "ValueStreamAnalytics|%{value}m"
-msgstr ""
+msgstr "%{value}分钟"
msgid "ValueStreamAnalytics|%{value}w"
-msgstr ""
+msgstr "%{value}周"
msgid "ValueStreamAnalytics|&lt;1m"
-msgstr ""
+msgstr "&lt;1m"
msgid "ValueStreamAnalytics|Average number of deployments to production per day."
-msgstr ""
+msgstr "æ¯å¤©ç”Ÿäº§çŽ¯å¢ƒéƒ¨ç½²çš„å¹³å‡æ•°ã€‚"
msgid "ValueStreamAnalytics|Median time from issue created to issue closed."
msgstr "从议题创建到关闭的中ä½æ•°æ—¶é—´ã€‚"
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
+msgstr "从议题的第一个åˆå¹¶è¯·æ±‚创建到议题关闭的中ä½æ—¶é—´ã€‚"
+
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
msgstr ""
msgid "ValueStreamAnalytics|Number of new issues created."
+msgstr "创建新议题的数é‡"
+
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
msgstr ""
msgid "ValueStreamAnalytics|Total number of deploys to production."
-msgstr ""
+msgstr "生产环境部署的总数。"
msgid "ValueStreamEvent|Items in stage"
msgstr ""
msgid "ValueStreamEvent|Stage time (median)"
-msgstr ""
+msgstr "阶段时间(中ä½æ•°ï¼‰"
msgid "ValueStreamEvent|Start"
msgstr "开始"
@@ -36359,13 +36689,13 @@ msgid "Variables"
msgstr "å˜é‡"
msgid "Variables can be:"
-msgstr ""
+msgstr "å˜é‡å¯ä»¥æ˜¯ï¼š"
msgid "Variables store information, like passwords and secret keys, that you can use in job scripts."
-msgstr ""
+msgstr "å˜é‡å­˜å‚¨ä¿¡æ¯ï¼Œå¦‚密ç å’Œå¯†é’¥ï¼Œæ‚¨å¯ä»¥åœ¨ä½œä¸šè„šæœ¬ä¸­ä½¿ç”¨ã€‚"
msgid "Variables store information, like passwords and secret keys, that you can use in job scripts. All projects on the instance can use these variables."
-msgstr ""
+msgstr "å˜é‡å­˜å‚¨ä¿¡æ¯ï¼Œå¦‚密ç å’Œå¯†é’¥ï¼Œæ‚¨å¯ä»¥åœ¨ä½œä¸šè„šæœ¬ä¸­ä½¿ç”¨ã€‚实例上的所有项目都å¯ä»¥ä½¿ç”¨è¿™äº›å˜é‡ã€‚"
msgid "Various container registry settings."
msgstr "容器镜åƒåº“相关设置。"
@@ -36522,6 +36852,10 @@ msgstr "在管ç†ä¸­å¿ƒæŸ¥çœ‹é¡¹ç›®"
msgid "View project labels"
msgstr "查看项目标记"
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+
msgid "View replaced file @ "
msgstr "查看替æ¢æ–‡ä»¶ @ "
@@ -36772,7 +37106,7 @@ msgid "Vulnerability|Project"
msgstr "项目"
msgid "Vulnerability|Reproduction Assets"
-msgstr ""
+msgstr "å†ç”Ÿèµ„产"
msgid "Vulnerability|Request"
msgstr "请求"
@@ -36780,9 +37114,6 @@ msgstr "请求"
msgid "Vulnerability|Request/Response"
msgstr "请求/å“应"
-msgid "Vulnerability|Scanner"
-msgstr "扫æ工具"
-
msgid "Vulnerability|Scanner Provider"
msgstr "扫æ工具æ供者"
@@ -36795,6 +37126,9 @@ msgstr "状æ€"
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr "未修改的å“应是原始å“应没有对请求进行çªå˜çš„å“应"
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr "未修改的å“应"
@@ -36868,19 +37202,19 @@ msgid "We heard back from your device. You have been authenticated."
msgstr "我们收到了您设备的å“应。您已通过身份验è¯ã€‚"
msgid "We love speaking to our users. Got more to say about your GitLab experiences?"
-msgstr ""
+msgstr "我们喜欢与用户交谈,关于您的体验,有更多è¦è¯´çš„å—?"
msgid "We recommend cloud-based mobile authenticator apps such as Authy, Duo Mobile, and LastPass. They can restore access if you lose your hardware device."
-msgstr ""
+msgstr "我们推è基于云端的移动身份验è¯å™¨åº”用,例如Authyã€Duo Mobileå’ŒLastPas。如果您丢失了硬件设备,他们å¯ä»¥æ¢å¤è®¿é—®ã€‚"
msgid "We recommend leaving all SAST analyzers enabled"
msgstr "我们建议å¯ç”¨æ‰€æœ‰ SAST 分æžå™¨"
msgid "We recommend that you buy additional Pipeline minutes to avoid any interruption of service."
-msgstr ""
+msgstr "我们建议您购买更多的æµæ°´çº¿æ—¶é—´ï¼Œä»¥é¿å…任何æœåŠ¡ä¸­æ–­ã€‚"
msgid "We recommend that you buy additional Pipeline minutes to resume normal service."
-msgstr ""
+msgstr "我们建议您购买更多的æµæ°´çº¿æ—¶é—´ï¼Œä»¥æ¢å¤æ­£å¸¸æœåŠ¡ã€‚"
msgid "We sent you an email with reset password instructions"
msgstr "我们å‘é€äº†ä¸€å°å¸¦æœ‰é‡ç½®å¯†ç ä¿¡æ¯çš„电å­é‚®ä»¶"
@@ -36898,6 +37232,9 @@ msgid "We would like to inform you that your subscription GitLab Enterprise Edit
msgstr "我们在此通知您,您的GitLab ä¼ä¸šç‰ˆè®¢é˜…%{plan_name}已接近其用户上é™ã€‚您当å‰æœ‰%{active_user_count}个活跃用户,å³å°†è¾¾åˆ°%{maximum_user_count}的用户é™åˆ¶ã€‚"
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
+msgstr "我们将ä¸æ–­éªŒè¯æ‚¨çš„æµæ°´çº¿é…置。验è¯ç»“果将显示在此处。"
+
+msgid "We'll use this to help surface the right features and information to you."
msgstr ""
msgid "We've found no vulnerabilities"
@@ -36919,7 +37256,7 @@ msgid "WebAuthn only works with HTTPS-enabled websites. Contact your administrat
msgstr "WebAuthnåªæ”¯æŒå¯ç”¨äº†HTTPS的网站。您å¯ä»¥è”系管ç†å‘˜èŽ·å¾—更多信æ¯"
msgid "WebIDE|Fork project"
-msgstr ""
+msgstr "Fork 项目"
msgid "WebIDE|Go to fork"
msgstr ""
@@ -36928,28 +37265,28 @@ msgid "WebIDE|Merge request"
msgstr "åˆå¹¶è¯·æ±‚"
msgid "WebIDE|This project does not accept unsigned commits."
-msgstr ""
+msgstr "此项目ä¸æŽ¥å—未签åçš„æ交。"
msgid "WebIDE|This project does not accept unsigned commits. You can’t commit changes through the Web IDE."
-msgstr ""
+msgstr "此项目ä¸æŽ¥å—未签åçš„æ交,您无法通过 Web IDE æ交更改。"
msgid "WebIDE|You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
+msgstr "您ä¸èƒ½åœ¨è¿™ä¸ªé¡¹ç›®ä¸­ç›´æŽ¥ç¼–辑文件,请派生(Fork)这个项目并æ交åˆå¹¶è¯·æ±‚。"
msgid "WebIDE|You can’t edit files directly in this project. Go to your fork and submit a merge request with your changes."
-msgstr ""
+msgstr "ä¸èƒ½ç›´æŽ¥åœ¨è¿™ä¸ªé¡¹ç›®ä¸­ç¼–辑文件,转到您的分支并æ交包å«æ›´æ”¹çš„åˆå¹¶è¯·æ±‚。"
msgid "WebIDE|You need permission to edit files directly in this project."
-msgstr ""
+msgstr "您需è¦æƒé™æ‰èƒ½ç›´æŽ¥åœ¨æ­¤é¡¹ç›®ä¸­ç¼–辑文件。"
msgid "WebexTeamsService|Send notifications about project events to Webex Teams."
-msgstr ""
+msgstr "å‘ Webex Teams å‘é€æœ‰å…³é¡¹ç›®äº‹ä»¶çš„通知。"
msgid "WebexTeamsService|Send notifications about project events to a Webex Teams conversation. %{docs_link}"
-msgstr ""
+msgstr "å‘ Webex Teams 对è¯å‘é€æœ‰å…³é¡¹ç›®äº‹ä»¶çš„通知。 %{docs_link}"
msgid "WebexTeamsService|Webex Teams"
-msgstr ""
+msgstr "Webex 团队"
msgid "Webhook"
msgstr "Webhook"
@@ -36961,7 +37298,7 @@ msgid "Webhook Settings"
msgstr "Webhook设置"
msgid "Webhook:"
-msgstr ""
+msgstr "Webhook:"
msgid "Webhooks"
msgstr "Webhooks"
@@ -36973,10 +37310,10 @@ msgid "Webhooks|Comments"
msgstr "评论"
msgid "Webhooks|Confidential comments"
-msgstr ""
+msgstr "ç§å¯†è¯„论"
msgid "Webhooks|Confidential issues events"
-msgstr ""
+msgstr "ç§å¯†è®®é¢˜äº‹ä»¶"
msgid "Webhooks|Deployment events"
msgstr "部署事件"
@@ -36994,7 +37331,7 @@ msgid "Webhooks|Job events"
msgstr "作业事件"
msgid "Webhooks|Member events"
-msgstr ""
+msgstr "æˆå‘˜äº‹ä»¶"
msgid "Webhooks|Merge request events"
msgstr "åˆå¹¶è¯·æ±‚事件"
@@ -37012,7 +37349,7 @@ msgid "Webhooks|SSL verification"
msgstr "SSL验è¯"
msgid "Webhooks|Secret token"
-msgstr ""
+msgstr "Secret 令牌"
msgid "Webhooks|Subgroup events"
msgstr "å­ç¾¤ç»„事件"
@@ -37027,61 +37364,61 @@ msgid "Webhooks|URL"
msgstr "网å€"
msgid "Webhooks|URL is triggered by a push to the repository"
-msgstr ""
+msgstr "推é€åˆ°ä»“åº“æ—¶è§¦å‘ URL"
msgid "Webhooks|URL is triggered when a confidential issue is created, updated, closed, or reopened"
-msgstr ""
+msgstr "在创建ã€æ›´æ–°ã€å…³é—­æˆ–é‡æ–°æ‰“å¼€ç§å¯†è®®é¢˜æ—¶è§¦å‘ URL"
msgid "Webhooks|URL is triggered when a deployment starts, finishes, fails, or is canceled"
-msgstr ""
+msgstr "在部署开始ã€å®Œæˆã€å¤±è´¥æˆ–å–æ¶ˆæ—¶è§¦å‘ URL"
msgid "Webhooks|URL is triggered when a feature flag is turned on or off"
-msgstr ""
+msgstr "åœ¨æ‰“å¼€æˆ–å…³é—­åŠŸèƒ½æ ‡å¿—æ—¶è§¦å‘ URL"
msgid "Webhooks|URL is triggered when a group member is created, updated, or removed"
-msgstr ""
+msgstr "在创建ã€æ›´æ–°æˆ–删除群组æˆå‘˜æ—¶è§¦å‘ URL"
msgid "Webhooks|URL is triggered when a merge request is created, updated, or merged"
-msgstr ""
+msgstr "在创建ã€æ›´æ–°æˆ–åˆå¹¶åˆå¹¶è¯·æ±‚æ—¶è§¦å‘ URL"
msgid "Webhooks|URL is triggered when a new tag is pushed to the repository"
-msgstr ""
+msgstr "在新标签被推é€åˆ°ä»“åº“æ—¶è§¦å‘ URL"
msgid "Webhooks|URL is triggered when a release is created or updated"
-msgstr ""
+msgstr "URL 在创建或更新版本时触å‘"
msgid "Webhooks|URL is triggered when a subgroup is created or removed"
-msgstr ""
+msgstr "在创建或删除å­ç¾¤ç»„æ—¶è§¦å‘ URL"
msgid "Webhooks|URL is triggered when a wiki page is created or updated"
-msgstr ""
+msgstr "在创建或更新 wiki 页é¢æ—¶è§¦å‘ URL"
msgid "Webhooks|URL is triggered when an issue is created, updated, closed, or reopened"
-msgstr ""
+msgstr "在创建ã€æ›´æ–°ã€å…³é—­æˆ–é‡æ–°æ‰“å¼€è®®é¢˜æ—¶è§¦å‘ URL"
msgid "Webhooks|URL is triggered when someone adds a comment"
-msgstr ""
+msgstr "åœ¨æœ‰äººæ·»åŠ è¯„è®ºæ—¶è§¦å‘ URL"
msgid "Webhooks|URL is triggered when someone adds a comment on a confidential issue"
-msgstr ""
+msgstr "在有人对ç§å¯†è®®é¢˜æ·»åŠ è¯„è®ºæ—¶è§¦å‘ URL"
msgid "Webhooks|URL is triggered when the job status changes"
-msgstr ""
+msgstr "作业状æ€æ”¹å˜æ—¶è§¦å‘URL"
msgid "Webhooks|URL is triggered when the pipeline status changes"
-msgstr ""
+msgstr "当æµæ°´çº¿çŠ¶æ€æ”¹å˜æ—¶è§¦å‘URL"
msgid "Webhooks|URL must be percent-encoded if neccessary."
-msgstr ""
+msgstr "如有必è¦ï¼ŒURL 必须进行百分比编ç ã€‚"
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
-msgstr ""
+msgstr "使用此令牌æ¥éªŒè¯æ”¶åˆ°çš„有效负载。它与 X-Gitlab-Token HTTP 标头中的请求一起å‘é€ã€‚"
msgid "Webhooks|Wiki page events"
msgstr "Wiki页é¢äº‹ä»¶"
msgid "Website:"
-msgstr ""
+msgstr "网站:"
msgid "Wednesday"
msgstr "星期三"
@@ -37114,7 +37451,7 @@ msgid "Welcome to the guided GitLab tour"
msgstr "欢迎æ¥åˆ°GitLab导览"
msgid "Welcome, %{name}!"
-msgstr ""
+msgstr "欢迎, %{name}ï¼"
msgid "What are group audit events?"
msgstr "什么是群组审计事件?"
@@ -37150,11 +37487,14 @@ msgid "What is squashing?"
msgstr "什么是压缩?"
msgid "What is time tracking?"
-msgstr ""
+msgstr "什么是时间追踪?"
msgid "What is your job title? (optional)"
msgstr "您的工作èŒä½æ˜¯ä»€ä¹ˆï¼Ÿ(å¯é€‰)"
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr "新增功能"
@@ -37162,16 +37502,16 @@ msgid "What’s your experience level?"
msgstr "您的体验水平是多少?"
msgid "When a deployment job is successful, skip older deployment jobs that are still pending."
-msgstr ""
+msgstr "部署作业æˆåŠŸæ—¶ï¼Œè·³è¿‡å°šæœªå®Œæˆçš„旧部署任务。"
msgid "When a runner is locked, it cannot be assigned to other projects"
msgstr "当Runner被é”定时,ä¸èƒ½å°†å…¶åˆ†é…给其他项目"
msgid "When an event in GitLab triggers a webhook, you can use the request details to figure out if something went wrong."
-msgstr ""
+msgstr "å½“äº‹ä»¶è§¦å‘ webhook 时,您å¯ä»¥ä½¿ç”¨è¯·æ±‚详细信æ¯æ¥ç¡®å®šæ˜¯å¦å‡ºçŽ°é—®é¢˜ã€‚"
msgid "When inactive, an external authentication provider must be used."
-msgstr ""
+msgstr "当未激活时,必须使用外部身份验è¯æ供程åºã€‚"
msgid "When leaving the URL blank, classification labels can still be specified without disabling cross project features or performing external authorization checks."
msgstr "å°†URLä¿ç•™ä¸ºç©ºç™½æ—¶ï¼Œä»å¯æŒ‡å®šåˆ†ç±»æ ‡ç­¾ï¼Œè€Œæ— éœ€ç¦ç”¨è·¨é¡¹ç›®åŠŸèƒ½æˆ–执行外部授æƒæ£€æŸ¥ã€‚"
@@ -37213,6 +37553,9 @@ msgstr "è°å°†ä½¿ç”¨æ­¤GitLab订阅?"
msgid "Who will be using this GitLab trial?"
msgstr "è°å°†ä½¿ç”¨æ­¤GitLab试用?"
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr "您为什么è¦æ³¨å†Œï¼Ÿ(å¯é€‰)"
@@ -37322,13 +37665,13 @@ msgid "WikiPageConfirmDelete|Delete page %{pageTitle}?"
msgstr "删除页é¢%{pageTitle}?"
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
-msgstr ""
+msgstr "有人在您编辑页é¢çš„åŒæ—¶ç¼–辑了页é¢ã€‚请查看%{wikiLinkStart}页é¢%{wikiLinkEnd}并确ä¿æ‚¨çš„更改ä¸ä¼šæ— æ„中删除它们的更改。"
msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
-msgstr ""
+msgstr "å°è¯•æ¸²æŸ“内容编辑器时å‘生错误。请ç¨åŽå†è¯•ã€‚"
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
-msgstr ""
+msgstr "确定è¦åˆ‡æ¢å›žç»å…¸ç¼–辑器å—?"
msgid "WikiPage|Cancel"
msgstr "å–消"
@@ -37379,19 +37722,19 @@ msgid "WikiPage|This editor is in beta and may not display the page's contents p
msgstr ""
msgid "WikiPage|Tip: You can move this page by adding the path to the beginning of the title."
-msgstr ""
+msgstr "æ示:您å¯ä»¥é€šè¿‡åœ¨æ ‡é¢˜å¼€å¤´æ·»åŠ è·¯å¾„æ¥ç§»åŠ¨æ­¤é¡µé¢ã€‚"
msgid "WikiPage|Tip: You can specify the full path for the new file. We will automatically create any missing directories."
-msgstr ""
+msgstr "æ示:您å¯ä»¥ä¸ºæ–°æ–‡ä»¶æŒ‡å®šå®Œæ•´è·¯å¾„。我们将自动创建任何缺失的目录。"
msgid "WikiPage|Title"
msgstr "标题"
msgid "WikiPage|To link to a (new) page, simply type %{linkExample}. More examples are in the %{linkStart}documentation%{linkEnd}."
-msgstr ""
+msgstr "è¦é“¾æŽ¥åˆ°ï¼ˆæ–°ï¼‰é¡µé¢ï¼Œåªéœ€é”®å…¥ %{linkExample}。更多示例请查看 %{linkStart}文档%{linkEnd}。"
msgid "WikiPage|Try the new visual Markdown editor. Read the %{linkStart}documentation%{linkEnd} to learn what's currently supported."
-msgstr ""
+msgstr "试用新的å¯è§†åŒ– Markdown 编辑器。阅读 %{linkStart}文档%{linkEnd} 以了解当å‰æ”¯æŒçš„功能。"
msgid "WikiPage|Try this later"
msgstr "ç¨åŽå†è¯•"
@@ -37541,7 +37884,7 @@ msgid "You are about to transfer the control of your account to %{group_name} gr
msgstr "您å³å°†æŠŠå¸æˆ·æŽ§åˆ¶æƒè½¬ç§»åˆ°%{group_name}群组。此æ“作ä¸å¯æ’¤æ¶ˆï¼Œè½¬ç§»å®ŒæˆåŽï¼Œæ‚¨å°†æ— æ³•è®¿é—®%{group_name}以外的任何群组和项目。"
msgid "You are already a member of this %{member_source}."
-msgstr ""
+msgstr "您已ç»æ˜¯%{member_source}çš„æˆå‘˜ã€‚"
msgid "You are an admin, which means granting access to %{client_name} will allow them to interact with GitLab as an admin as well. Proceed with caution."
msgstr "您是管ç†å‘˜ï¼Œè¿™æ„味ç€èµ‹äºˆ%{client_name}æƒé™å°†å…许他们作为管ç†å‘˜æ¥å¯¹GitLab进行æ“作。请谨慎行事。"
@@ -37559,7 +37902,7 @@ msgid "You are going to delete %{project_full_name}. Deleted projects CANNOT be
msgstr "å³å°†è¦åˆ é™¤%{project_full_name}。已删除的项目无法æ¢å¤ï¼ç¡®å®šç»§ç»­å—?"
msgid "You are going to remove %{group_name}. This will also delete all of its subgroups and projects. Removed groups CANNOT be restored! Are you ABSOLUTELY sure?"
-msgstr ""
+msgstr "您将删除 %{group_name}。这也将删除其所有å­ç»„和项目。删除的群组无法æ¢å¤ï¼æ‚¨ç»å¯¹ç¡®å®šå—?"
msgid "You are going to remove the fork relationship from %{project_full_name}. Are you ABSOLUTELY sure?"
msgstr "å³å°†åˆ é™¤ä¸Žæºé¡¹ç›®%{project_full_name}的派生关系。确定继续å—?"
@@ -37574,7 +37917,7 @@ msgid "You are going to turn on confidentiality. Only team members with %{strong
msgstr ""
msgid "You are not allowed to %{action} a user"
-msgstr ""
+msgstr "您无æƒ%{action}一å用户"
msgid "You are not allowed to approve a user"
msgstr "您无æƒæ‰¹å‡†ç”¨æˆ·"
@@ -37622,7 +37965,7 @@ msgid "You can %{gitlabLinkStart}resolve conflicts on GitLab%{gitlabLinkEnd} or
msgstr ""
msgid "You can %{resolveLocallyStart}resolve it locally%{resolveLocallyEnd}."
-msgstr ""
+msgstr "您å¯ä»¥ %{resolveLocallyStart}在本地解决它%{resolveLocallyEnd}。"
msgid "You can also create a project from the command line."
msgstr "您也å¯ä»¥é€šè¿‡å‘½ä»¤è¡Œæ¥åˆ›å»ºæ–°é¡¹ç›®ã€‚"
@@ -37643,7 +37986,7 @@ msgid "You can also upload existing files from your computer using the instructi
msgstr "您还å¯ä»¥æŒ‰ç…§ä»¥ä¸‹è¯´æ˜Žä»Žè®¡ç®—机中上传现有文件。"
msgid "You can also use project access tokens with Git to authenticate over HTTP(S). %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "您还å¯ä»¥å°†é¡¹ç›®è®¿é—®ä»¤ç‰Œä¸Ž Git 结åˆä½¿ç”¨ä»¥é€šè¿‡ HTTP(S) 进行身份验è¯ã€‚ %{link_start}了解更多。%{link_end}"
msgid "You can always edit this later"
msgstr "您也å¯ä»¥ç¨åŽç¼–辑此选项。"
@@ -37661,16 +38004,16 @@ msgid "You can create a new SSH key by visiting %{link}"
msgstr "您å¯ä»¥é€šè¿‡è®¿é—®%{link}创建一个新的SSH密钥"
msgid "You can create a new one or check them in your %{pat_link_start}personal access tokens%{pat_link_end} settings."
-msgstr ""
+msgstr "您å¯ä»¥åœ¨æ‚¨çš„ %{pat_link_start}个人访问令牌%{pat_link_end} 设置中创建一个新的或检查它们。"
msgid "You can create a new one or check them in your %{ssh_key_link_start}SSH keys%{ssh_key_link_end} settings."
-msgstr ""
+msgstr "您å¯ä»¥åœ¨æ‚¨çš„ %{ssh_key_link_start}SSH 密钥%{ssh_key_link_end} 设置中创建一个新的密钥或检查它们。"
msgid "You can create a new one or check them in your SSH keys settings %{ssh_key_link}."
-msgstr ""
+msgstr "您å¯ä»¥åœ¨æ‚¨çš„ SSH 密钥设置 %{ssh_key_link} 中创建一个新的密钥或检查它们。"
msgid "You can create a new one or check them in your personal access tokens settings %{pat_link}."
-msgstr ""
+msgstr "您å¯ä»¥åœ¨æ‚¨çš„个人访问令牌设置%{pat_link}中创建一个新的令牌或检查它们。"
msgid "You can create new ones at your %{pat_link_start}Personal Access Tokens%{pat_link_end} settings"
msgstr "您å¯ä»¥åœ¨%{pat_link_start}个人访问令牌%{pat_link_end}设置中创建新的令牌"
@@ -37685,7 +38028,7 @@ msgid "You can enable Registration Features because Service Ping is enabled. To
msgstr ""
msgid "You can enable project access token creation in %{link_start}group settings%{link_end}."
-msgstr ""
+msgstr "您å¯ä»¥åœ¨ %{link_start}群组设置%{link_end} 中å¯ç”¨é¡¹ç›®è®¿é—®ä»¤ç‰Œåˆ›å»ºã€‚"
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr "您å¯ä»¥é€šè¿‡å•å‡»å›¾è¡¨ä¸­çš„列æ¥æŒ‰â€œåˆå¹¶å¤©æ•°â€è¿›è¡Œç­›é€‰ã€‚"
@@ -37706,7 +38049,7 @@ msgid "You can invite a new member to %{project_name}."
msgstr "您å¯ä»¥é‚€è¯·ä¸€ä¸ªæ–°æˆå‘˜åŠ å…¥%{project_name}。"
msgid "You can invite a new member to %{strong_start}%{group_name}%{strong_end}."
-msgstr ""
+msgstr "您å¯ä»¥é‚€è¯·æ–°æˆå‘˜åŠ å…¥ %{strong_start}%{group_name}%{strong_end}。"
msgid "You can invite another group to %{project_name}."
msgstr "您å¯ä»¥é‚€è¯·å¦ä¸€ä¸ªç¾¤ç»„加入%{project_name}。"
@@ -37730,7 +38073,7 @@ msgid "You can now submit a merge request to get this change into the original p
msgstr "您现在å¯ä»¥æ交åˆå¹¶è¯·æ±‚以将此更改添加到æºé¡¹ç›®ä¸­ã€‚"
msgid "You can only %{action} files when you are on a branch"
-msgstr ""
+msgstr "当处于分支时,您åªèƒ½ %{action} 文件"
msgid "You can only edit files when you are on a branch"
msgstr "åªèƒ½åœ¨åˆ†æ”¯ä¸Šç¼–辑文件"
@@ -37751,7 +38094,7 @@ msgid "You can recover this project until %{date}"
msgstr "您å¯ä»¥åœ¨%{date}之å‰æ¢å¤æ­¤é¡¹ç›®"
msgid "You can register runners as separate users, on separate servers, and on your local machine. Register as many runners as you want."
-msgstr ""
+msgstr "您å¯ä»¥ä¸ºå•ä¸ªç”¨æˆ·ï¼Œå•ä¸ªæœåŠ¡å™¨ä»¥åŠæ‚¨çš„本地机器注册Runner。注册Runnerçš„æ•°é‡ä¸å—é™åˆ¶ã€‚"
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr "您å¯ä»¥ä½¿ç”¨äº¤äº’模å¼ï¼Œé€šè¿‡é€‰æ‹© %{use_ours} 或 %{use_theirs} 按钮æ¥è§£å†³åˆå¹¶å†²çªã€‚也å¯ä»¥é€šè¿‡ç›´æŽ¥ç¼–辑文件æ¥è§£å†³åˆå¹¶å†²çªã€‚然åŽå°†è¿™äº›æ›´æ”¹æ交到 %{branch_name}"
@@ -37760,7 +38103,7 @@ msgid "You can see your chat accounts."
msgstr "您å¯ä»¥æŸ¥çœ‹æ‚¨çš„èŠå¤©è´¦æˆ·ã€‚"
msgid "You can set up jobs to only use runners with specific tags. Separate tags with commas."
-msgstr ""
+msgstr "您å¯ä»¥è®¾ç½®ä½œä¸šä»…使用具有特定标签的Runner。用逗å·åˆ†éš”标签。"
msgid "You can specify notification level per group or per project."
msgstr "您å¯ä»¥æŒ‡å®šæ¯ä¸ªç¾¤ç»„或æ¯ä¸ªé¡¹ç›®çš„通知级别。"
@@ -37771,6 +38114,9 @@ msgstr "您也å¯ä»¥é€šè¿‡%{linkStart}Lint%{linkEnd}测试.gitlab-ci.yml."
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr "您å¯ä»¥æŸ¥çœ‹æºä»£ç æˆ–%{linkStart}%{cloneIcon}克隆仓库%{linkEnd}"
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr "您ä¸èƒ½è®¿é—®åŽŸå§‹æ–‡ä»¶ã€‚请ç¨å€™ã€‚"
@@ -37786,6 +38132,9 @@ msgstr "您无法使用内部用户的身份"
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr "您目å‰æ— æ³•è¿è¡Œæ­¤æµæ°´çº¿è®¡åˆ’。请ç¨å€™ã€‚"
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr "您ä¸èƒ½å†™å…¥åªè¯»çš„æ¬¡è¦ GitLab Geo 实例。请改用%{link_to_primary_node}。"
@@ -37793,7 +38142,7 @@ msgid "You cannot write to this read-only GitLab instance."
msgstr "您ä¸èƒ½å†™å…¥è¿™ä¸ªåªè¯»çš„ GitLab 实例。"
msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
+msgstr "您ä¸èƒ½åœ¨æ­¤é¡¹ç›®ä¸­ç›´æŽ¥ %{tag_start}编辑%{tag_end},派生(fork)这个项目并æ交一个包å«æ‚¨çš„更改的åˆå¹¶è¯·æ±‚。"
msgid "You could not create a new trigger."
msgstr "您无法创建新的触å‘器。"
@@ -37847,7 +38196,7 @@ msgid "You don't have any recent searches"
msgstr "您没有任何近期的æœç´¢"
msgid "You don't have any webhooks deliveries"
-msgstr ""
+msgstr "您没有任何Webhook交付"
msgid "You don't have sufficient permission to perform this action."
msgstr "你没有足够的æƒé™æ¥æ‰§è¡Œæ­¤æ“作。"
@@ -37868,13 +38217,13 @@ msgid "You have been granted %{access_level} access to the %{source_name} %{sour
msgstr "你已被授予 %{access_level} 访问 %{source_name} %{source_type} çš„æƒé™ã€‚"
msgid "You have been granted %{member_human_access} access to group %{name}."
-msgstr ""
+msgstr "您已被授予了%{name}群组的%{member_human_access}æƒé™ã€‚"
msgid "You have been granted %{member_human_access} access to project %{name}."
-msgstr ""
+msgstr "您已被授予了%{name}项目的%{member_human_access}æƒé™ã€‚"
msgid "You have been invited by %{link_to_inviter} to join %{source_name} %{strong_open}%{link_to_source}%{strong_close} as %{role}"
-msgstr ""
+msgstr "您已被 %{link_to_inviter} 邀请加入 %{source_name} %{strong_open}%{link_to_source}%{strong_close} 作为 %{role}"
msgid "You have been redirected to the only result; see the %{a_start}search results%{a_end} instead."
msgstr "您已被é‡å®šå‘到唯一的结果;改为查看 %{a_start}æœç´¢ç»“æžœ%{a_end}。"
@@ -37889,7 +38238,7 @@ msgid "You have imported from this project %{numberOfPreviousImports} times befo
msgstr "您已从该项目导入%{numberOfPreviousImports} 次。æ¯æ¬¡å¯¼å…¥éƒ½ä¼šäº§ç”Ÿé‡å¤çš„议题。"
msgid "You have insufficient permissions to configure escalation policies for this project"
-msgstr ""
+msgstr "您没有足够的æƒé™ä¸ºæ­¤é¡¹ç›®é…ç½®å‡çº§ç­–ç•¥"
msgid "You have insufficient permissions to create a Todo for this alert"
msgstr "您没有足够的æƒé™ä¸ºè¿™ä¸ªè­¦æŠ¥åˆ›å»ºå¾…办事项"
@@ -37901,22 +38250,22 @@ msgid "You have insufficient permissions to create an on-call schedule for this
msgstr "您没有足够的æƒé™æ¥åˆ›å»ºæ­¤é¡¹ç›®çš„待命计划"
msgid "You have insufficient permissions to remove an on-call rotation from this project"
-msgstr ""
+msgstr "您的æƒé™ä¸è¶³ï¼Œæ— æ³•ä»Žæ­¤é¡¹ç›®ä¸­åˆ é™¤on-callè½®æ¢"
msgid "You have insufficient permissions to remove an on-call schedule from this project"
-msgstr "您没有足够的æƒé™ä»Žæ­¤é¡¹ç›®ä¸­åˆ é™¤é€šè¯è®¡åˆ’"
+msgstr "您没有足够的æƒé™ä»Žæ­¤é¡¹ç›®ä¸­åˆ é™¤ on-call 计划"
msgid "You have insufficient permissions to remove this HTTP integration"
msgstr "您没有足够的æƒé™åˆ é™¤æ­¤HTTP集æˆ"
msgid "You have insufficient permissions to update an on-call schedule for this project"
-msgstr ""
+msgstr "您没有足够的æƒé™æ¥æ›´æ–°æ­¤é¡¹ç›®çš„on-call计划"
msgid "You have insufficient permissions to update this HTTP integration"
msgstr "您没有足够的æƒé™æ¥æ›´æ–°æ­¤HTTP集æˆ"
msgid "You have insufficient permissions to view shifts for this rotation"
-msgstr ""
+msgstr "您没有足够的æƒé™æŸ¥çœ‹æ­¤è½®æ¢çš„ç­æ¬¡"
msgid "You have no permissions"
msgstr "没有æƒé™"
@@ -37930,7 +38279,7 @@ msgstr "您已达到项目数é‡é™åˆ¶"
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -37967,7 +38316,7 @@ msgid "You must provide your current password in order to change it."
msgstr "您必须æ供当å‰å¯†ç æ‰èƒ½è¿›è¡Œæ›´æ”¹ã€‚"
msgid "You must solve the CAPTCHA in order to submit"
-msgstr ""
+msgstr "您必须解决验è¯ç æ‰èƒ½æ交"
msgid "You must upload a file with the same file name when dropping onto an existing design."
msgstr "当拖放到现有设计时,您必须上传具有相åŒæ–‡ä»¶å的文件。"
@@ -38096,7 +38445,7 @@ msgid "YouTube URL or ID"
msgstr "YouTube URL或ID"
msgid "Your %{group} membership will now expire in %{days}."
-msgstr ""
+msgstr "您的%{group}æˆå‘˜èµ„格将在%{days}天内到期。"
msgid "Your %{host} account was signed in to from a new location"
msgstr "您在%{host}上的å¸æˆ·å·²ä»Žä¸€ä¸ªæ–°çš„ä½ç½®ç™»å½•"
@@ -38108,7 +38457,7 @@ msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{s
msgstr "您的%{strong}%{plan_name}%{strong_close}订阅将于%{strong}%{expires_on}%{strong_close}到期。此åŽï¼Œæ‚¨å°†æ— æ³•åˆ›å»ºè®®é¢˜æˆ–åˆå¹¶è¯·æ±‚,åŒæ—¶ä¹Ÿæ— æ³•è®¿é—®å…¶ä»–众多功能。"
msgid "Your CI/CD configuration syntax is invalid. View Lint tab for more details."
-msgstr ""
+msgstr "您的 CI/CD é…置语法无效。查看 Lint 选项å¡ä»¥èŽ·å–更多详细信æ¯ã€‚"
msgid "Your CSV export has started. It will be emailed to %{email} when complete."
msgstr "CSV导出已ç»å¼€å§‹ã€‚完æˆåŽå°†å‘é€ç”µå­é‚®ä»¶è‡³%{email}。"
@@ -38186,7 +38535,7 @@ msgid "Your account has been deactivated by your administrator. Please log back
msgstr "您的å¸æˆ·å·²è¢«ç®¡ç†å‘˜å†»ç»“。请é‡æ–°ç™»å½•ä»¥é‡æ–°æ¿€æ´»æ‚¨çš„å¸æˆ·ã€‚"
msgid "Your account has been deactivated. You will not be able to: "
-msgstr ""
+msgstr "您的账å·å·²è¢«åœç”¨ã€‚您将无法: "
msgid "Your account is locked."
msgstr "您的å¸å·å·²è¢«é”定。"
@@ -38195,7 +38544,7 @@ msgid "Your account uses dedicated credentials for the \"%{group_name}\" group a
msgstr "您的å¸æˆ·ä½¿ç”¨ç¾¤ç»„“%{group_name}â€çš„专用凭æ®ï¼Œå¹¶ä¸”åªèƒ½é€šè¿‡SSO进行更新。"
msgid "Your action succeeded."
-msgstr ""
+msgstr "您的æ“作æˆåŠŸã€‚"
msgid "Your applications (%{size})"
msgstr "您的应用程åº(%{size})"
@@ -38204,7 +38553,7 @@ msgid "Your authorized applications"
msgstr "您已授æƒçš„应用"
msgid "Your browser does not support iFrames"
-msgstr ""
+msgstr "您的æµè§ˆå™¨ä¸æ”¯æŒ iFrame"
msgid "Your browser doesn't support U2F. Please use Google Chrome desktop (version 41 or newer)."
msgstr "您的æµè§ˆå™¨ä¸æ”¯æŒU2F。请使用Google Chromeæ¡Œé¢ç‰ˆï¼ˆ41或更高版本)。"
@@ -38237,7 +38586,7 @@ msgid "Your comment will be discarded."
msgstr "您的评论将被丢弃。"
msgid "Your commit email is used for web based operations, such as edits and merges."
-msgstr ""
+msgstr "您的æ交电å­é‚®ä»¶ç”¨äºŽåŸºäºŽ web çš„æ“作,例如编辑和åˆå¹¶ã€‚"
msgid "Your dashboard has been copied. You can %{web_ide_link_start}edit it here%{web_ide_link_end}."
msgstr "仪表æ¿å·²ç»è¢«å¤åˆ¶ã€‚ ä½ å¯ä»¥%{web_ide_link_start}在这里进行编辑%{web_ide_link_end}。"
@@ -38246,7 +38595,7 @@ msgid "Your dashboard has been updated. You can %{web_ide_link_start}edit it her
msgstr "您的仪表æ¿å·²æ›´æ–°ã€‚ä½ å¯ä»¥%{web_ide_link_start}在这里进行编辑%{web_ide_link_end}。"
msgid "Your default notification email is used for account notifications if a %{openingTag}group-specific email address%{closingTag} is not set."
-msgstr ""
+msgstr "如果没有设置 %{openingTag}针对特定群组的电å­é‚®ä»¶åœ°å€%{closingTag},您的默认通知电å­é‚®ä»¶å°†ç”¨äºŽè´¦å·é€šçŸ¥ã€‚"
msgid "Your deployment services will be broken, you will need to manually fix the services after renaming."
msgstr "您的部署æœåŠ¡å°†å¤±æ•ˆï¼Œéœ€è¦åœ¨é‡å‘½ååŽæ‰‹åŠ¨ä¿®å¤æœåŠ¡ã€‚"
@@ -38285,7 +38634,7 @@ msgid "Your issues will be imported in the background. Once finished, you'll get
msgstr "您的议题将在åŽå°å¯¼å…¥ã€‚完æˆåŽï¼Œæ‚¨å°†æ”¶åˆ°ä¸€å°ç¡®è®¤ç”µå­é‚®ä»¶ã€‚"
msgid "Your license does not support on-call rotations"
-msgstr ""
+msgstr "您的许å¯è¯ä¸æ”¯æŒ on-call è½®æ¢"
msgid "Your license does not support on-call schedules"
msgstr "您的许å¯è¯ä¸æ”¯æŒå¾…命计划"
@@ -38294,7 +38643,7 @@ msgid "Your license is valid from"
msgstr "您的许å¯è¯æœ‰æ•ˆæœŸè‡ª"
msgid "Your membership in %{group} no longer expires."
-msgstr ""
+msgstr "您在 %{group} 中的æˆå‘˜èµ„æ ¼ä¸å†è¿‡æœŸã€‚"
msgid "Your message here"
msgstr "您的消æ¯æ˜¾ç¤ºäºŽæ­¤"
@@ -38309,7 +38658,7 @@ msgid "Your new SCIM token"
msgstr "您的新 SCIM 令牌"
msgid "Your new comment"
-msgstr ""
+msgstr "您的新评论"
msgid "Your new personal access token has been created."
msgstr "您的新个人访问令牌已创建。"
@@ -38327,10 +38676,10 @@ msgid "Your personal access token has expired"
msgstr "您的个人访问令牌已过期"
msgid "Your personal access tokens will expire in %{days_to_expire} days or less"
-msgstr ""
+msgstr "您的个人访问令牌将在 %{days_to_expire} 天或更短的时间内到期"
msgid "Your primary email is used for avatar detection. You can change it in your %{openingTag}profile settings%{closingTag}."
-msgstr ""
+msgstr "您的主è¦ç”µå­é‚®ä»¶ç”¨äºŽå¤´åƒæ£€æµ‹ã€‚您å¯ä»¥åœ¨æ‚¨çš„ %{openingTag}个人资料设置%{closingTag}更改它。"
msgid "Your profile"
msgstr "个人资料"
@@ -38342,7 +38691,7 @@ msgid "Your projects"
msgstr "您的项目"
msgid "Your public email will be displayed on your public profile."
-msgstr ""
+msgstr "您的公开电å­é‚®ä»¶å°†æ˜¾ç¤ºåœ¨æ‚¨çš„公开个人资料中。"
msgid "Your request for access could not be processed: %{error_meesage}"
msgstr "您的访问请求无法处ç†: %{error_meesage}"
@@ -38356,8 +38705,8 @@ msgstr "您在%{host}上注册账户的请求已被拒ç»ã€‚"
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr "您的需求正在导入。导入完æˆæ—¶æ‚¨å°†æ”¶åˆ°ä¸€å°ç¡®è®¤ç”µå­é‚®ä»¶ã€‚"
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
-msgstr "您的需求将在åŽå°å¯¼å…¥ã€‚完æˆåŽï¼Œæ‚¨å°†æ”¶åˆ°ä¸€å°ç¡®è®¤ç”µå­é‚®ä»¶ã€‚"
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
+msgstr ""
msgid "Your response has been recorded."
msgstr "ä½ çš„å馈已被记录。"
@@ -38369,7 +38718,7 @@ msgid "Your search didn't match any commits. Try a different query."
msgstr "您的æœç´¢ä¸ŽæœªåŒ¹é…任何æ交。请å°è¯•å…¶ä»–查询。"
msgid "Your search timed out"
-msgstr ""
+msgstr "您的æœç´¢å·²è¶…æ—¶"
msgid "Your sign-in page is %{url}."
msgstr "您的登录页é¢ä¸º%{url}。"
@@ -38386,6 +38735,30 @@ msgstr "您的订阅将在%{remaining_days}åŽè¿‡æœŸ."
msgid "Your username is %{username}."
msgstr "您的用户å是%{username}。"
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr "已添加Zoom会议"
@@ -38396,13 +38769,13 @@ msgid "[No reason]"
msgstr "[无原因]"
msgid "[Redacted]"
-msgstr ""
+msgstr "[Redacted]"
msgid "`end_time` should not exceed one month after `start_time`"
-msgstr ""
+msgstr "`end_time` ä¸åº”超过 `start_time` åŽçš„一个月"
msgid "`start_time` should precede `end_time`"
-msgstr ""
+msgstr "`start_time` 应该在 `end_time` 之å‰"
msgid "a deleted user"
msgstr "已删除的用户"
@@ -38418,13 +38791,13 @@ msgid "access:"
msgstr "访问:"
msgid "added"
-msgstr ""
+msgstr "已添加"
msgid "added %{created_at_timeago}"
msgstr "创建于 %{created_at_timeago}"
msgid "added %{emails}"
-msgstr ""
+msgstr "添加了 %{emails}"
msgid "added a Zoom call to this issue"
msgstr "添加Zoom通è¯åˆ°æ­¤è®®é¢˜"
@@ -38442,7 +38815,7 @@ msgid "already being used for another group or project %{timebox_name}."
msgstr "已用于å¦ä¸€ç¾¤ç§Ÿæˆ–项目%{timebox_name}。"
msgid "already being used for another iteration within this cadence."
-msgstr ""
+msgstr "已用于此周期中的å¦ä¸€æ¬¡è¿­ä»£ã€‚"
msgid "already has a \"created\" issue link"
msgstr "å·²ç»æœ‰â€œå·²åˆ›å»ºâ€çš„议题链接"
@@ -38472,7 +38845,7 @@ msgid "assign yourself"
msgstr "分é…给自己"
msgid "at"
-msgstr ""
+msgstr "于"
msgid "at risk"
msgstr "存在风险"
@@ -38484,11 +38857,15 @@ msgid "authored"
msgstr "编辑于"
msgid "banned user already exists"
-msgstr ""
+msgstr "å°ç¦çš„用户已ç»å­˜åœ¨"
msgid "blocks"
msgstr "阻止"
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+
msgid "branch name"
msgstr "分支å称"
@@ -38496,25 +38873,25 @@ msgid "by"
msgstr "æ¥è‡ª"
msgid "cURL:"
-msgstr ""
+msgstr "cURL:"
msgid "can contain only letters of the Base64 alphabet (RFC4648) with the addition of '@', ':' and '.'"
msgstr "åªèƒ½åŒ…å«Base64å­—æ¯è¡¨(RFC4648)中的字æ¯ï¼Œä»¥åŠâ€œ@â€ã€â€œ:â€å’Œâ€œ.â€ã€‚"
msgid "can contain only lowercase letters, digits, and '_'."
-msgstr ""
+msgstr "åªèƒ½åŒ…å«å°å†™å­—æ¯ã€æ•°å­—和“_â€ã€‚"
msgid "can only be changed by a group admin."
-msgstr ""
+msgstr "åªèƒ½ç”±ç¾¤ç»„管ç†å‘˜æ›´æ”¹ã€‚"
msgid "can only have one escalation policy"
-msgstr ""
+msgstr "åªèƒ½æœ‰ä¸€ä¸ªå‡çº§ç­–ç•¥"
msgid "can't be the same as the source project"
-msgstr ""
+msgstr "ä¸èƒ½å’Œæºé¡¹ç›®ç›¸åŒ"
msgid "can't include: %{invalid_storages}"
-msgstr ""
+msgstr "ä¸èƒ½åŒ…括: %{invalid_storages}"
msgid "cannot be a date in the past"
msgstr "ä¸èƒ½æ˜¯è¿‡åŽ»çš„日期"
@@ -38538,7 +38915,7 @@ msgid "cannot be enabled unless all domains have TLS certificates"
msgstr "除éžæ‰€æœ‰åŸŸéƒ½å…·æœ‰TLSè¯ä¹¦ï¼Œå¦åˆ™æ— æ³•å¯ç”¨"
msgid "cannot be enabled until a valid credit card is on file"
-msgstr ""
+msgstr "在有效的信用å¡å­˜æ¡£ä¹‹å‰æ— æ³•å¯ç”¨"
msgid "cannot be modified"
msgstr "无法修改"
@@ -38565,7 +38942,7 @@ msgid "ciReport|%{improvedNum} improved"
msgstr "已改进%{improvedNum}"
msgid "ciReport|%{linkStartTag}Learn more about API Fuzzing%{linkEndTag}"
-msgstr ""
+msgstr "%{linkStartTag}了解有关 API 模糊测试的更多信æ¯%{linkEndTag}"
msgid "ciReport|%{linkStartTag}Learn more about Container Scanning %{linkEndTag}"
msgstr "%{linkStartTag}了解更多有关容器安全扫æçš„ä¿¡æ¯ %{linkEndTag}"
@@ -38607,17 +38984,17 @@ msgid "ciReport|API Fuzzing"
msgstr "API模糊测试"
msgid "ciReport|API fuzzing"
-msgstr ""
+msgstr "API 模糊测试"
msgid "ciReport|All projects"
msgstr "所有项目"
-msgid "ciReport|All scanners"
-msgstr "所有扫æ工具"
-
msgid "ciReport|All severities"
msgstr "全部严é‡çº§åˆ«"
+msgid "ciReport|All tools"
+msgstr ""
+
msgid "ciReport|Automatically apply the patch in a new branch"
msgstr "在新分支中自动应用补ä¸"
@@ -38634,7 +39011,7 @@ msgid "ciReport|Checks"
msgstr "检查"
msgid "ciReport|Cluster Image Scanning"
-msgstr ""
+msgstr "集群镜åƒæ‰«æ"
msgid "ciReport|Code quality"
msgstr "代ç è´¨é‡"
@@ -38658,7 +39035,7 @@ msgid "ciReport|Coverage fuzzing"
msgstr "Coverage Fuzzing"
msgid "ciReport|Create Jira issue"
-msgstr ""
+msgstr "创建 Jira 议题"
msgid "ciReport|Create a merge request to implement this solution, or download and apply the patch manually."
msgstr "创建一个åˆå¹¶è¯·æ±‚æ¥æ‰§è¡Œè¿™ä¸ªè§£å†³æ–¹æ¡ˆï¼Œæˆ–者下载并手动应用补ä¸ã€‚"
@@ -38797,43 +39174,43 @@ msgid "closed issue"
msgstr "已关闭议题"
msgid "codeQualityWalkthrough|A code quality job will now run every time you or your team members commit changes to your project. You can view the results of the code quality job in the job logs."
-msgstr ""
+msgstr "æ¯å½“您或您的团队æˆå‘˜å¯¹æ‚¨çš„项目进行更改时,都会è¿è¡Œä»£ç è´¨é‡ä½œä¸šã€‚ 您å¯ä»¥åœ¨ä½œä¸šæ—¥å¿—中查看代ç è´¨é‡ä½œä¸šçš„结果。"
msgid "codeQualityWalkthrough|Congrats! Your first pipeline is running %{emojiStart}zap%{emojiEnd}"
-msgstr ""
+msgstr "æ­å–œï¼æ‚¨çš„第一个æµæ°´çº¿æ­£åœ¨è¿è¡Œ %{emojiStart}zap%{emojiEnd}"
msgid "codeQualityWalkthrough|Got it"
-msgstr ""
+msgstr "知é“了"
msgid "codeQualityWalkthrough|Let's start by creating a new CI file."
-msgstr ""
+msgstr "让我们从创建一个新的 CI 文件开始。"
msgid "codeQualityWalkthrough|Not sure how to fix your failed job? We have compiled some tips on how to troubleshoot code quality jobs in the documentation."
-msgstr ""
+msgstr "ä¸çŸ¥é“如何修å¤å¤±è´¥çš„作业?我们在文档中汇编了一些有关如何对代ç è´¨é‡ä½œä¸šè¿›è¡Œæ•…障排除的技巧。"
msgid "codeQualityWalkthrough|Read the documentation"
msgstr "阅读文档"
msgid "codeQualityWalkthrough|Something went wrong. %{emojiStart}thinking%{emojiEnd} Let's fix it."
-msgstr ""
+msgstr "出错了, %{emojiStart}thinking%{emojiEnd} 让我们æ¥ä¿®å¤å®ƒã€‚"
msgid "codeQualityWalkthrough|To begin with code quality, we first need to create a new CI file using our code editor. We added a code quality template in the code editor to help you get started %{emojiStart}wink%{emojiEnd} .%{lineBreak}Take some time to review the template, when you are ready, use the %{strongStart}commit changes%{strongEnd} button at the bottom of the page."
-msgstr ""
+msgstr "è¦å¼€å§‹å¤„ç†ä»£ç è´¨é‡, 我们首先需è¦ä½¿ç”¨æˆ‘们的代ç ç¼–辑器创建一个新的 CI 文件。 我们在代ç ç¼–辑器中添加了一个代ç è´¨é‡æ¨¡æ¿ï¼Œä»¥å¸®åŠ©æ‚¨å¯åŠ¨ %{emojiStart}wink%{emojiEnd} 。%{lineBreak}在准备就绪时花一些时间查看模æ¿ï¼Œå‡†å¤‡å®ŒæˆåŽï¼Œä½¿ç”¨é¡µé¢åº•éƒ¨çš„ %{strongStart}æ交更改%{strongEnd} 按钮。"
msgid "codeQualityWalkthrough|Troubleshoot your code quality job"
-msgstr ""
+msgstr "代ç è´¨é‡ä½œä¸šæ•…障排查"
msgid "codeQualityWalkthrough|View the logs"
msgstr "查看日志"
msgid "codeQualityWalkthrough|Well done! You've just automated your code quality review. %{emojiStart}raised_hands%{emojiEnd}"
-msgstr ""
+msgstr "干得好ï¼æ‚¨åˆšåˆšå®žçŽ°äº†ä»£ç è´¨é‡å®¡æŸ¥çš„自动化。 %{emojiStart}raised_hands%{emojiEnd}"
msgid "codeQualityWalkthrough|Your job failed. No worries - this happens. Let's view the logs, and see how we can fix it."
-msgstr ""
+msgstr "您的作业失败了,ä¸ç”¨æ‹…心å‘生这ç§æƒ…况,让我们查看日志,看看如何修å¤å®ƒã€‚"
msgid "codeQualityWalkthrough|Your pipeline can take a few minutes to run. If you enabled email notifications, you'll receive an email with your pipeline status. In the meantime, why don't you get some coffee? You earned it!"
-msgstr ""
+msgstr "您的æµæ°´çº¿å¯èƒ½éœ€è¦å‡ åˆ†é’Ÿæ‰èƒ½è¿è¡Œï¼Œå¦‚果您å¯ç”¨äº†ç”µå­é‚®ä»¶é€šçŸ¥ï¼Œæ‚¨å°†æ”¶åˆ°ä¸€å°åŒ…å«æµæ°´çº¿çŠ¶æ€çš„电å­é‚®ä»¶ã€‚"
msgid "collect usage information"
msgstr "收集使用信æ¯"
@@ -38857,7 +39234,7 @@ msgid "container_name cannot be larger than %{max_length} chars"
msgstr "container_nameä¸èƒ½è¶…过%{max_length}个字符"
msgid "contribute to this project."
-msgstr ""
+msgstr "为此项目åšå‡ºè´¡çŒ®ã€‚"
msgid "could not read private key, is the passphrase correct?"
msgstr "无法读å–ç§é’¥ï¼Œå¯†ç çŸ­è¯­æ˜¯å¦æ­£ç¡®ï¼Ÿ"
@@ -38866,16 +39243,16 @@ msgid "created"
msgstr "已创建"
msgid "created %{issuable_created} by %{author}"
-msgstr ""
+msgstr "%{issuable_created}由%{author}创建"
msgid "created %{timeAgoString} by %{email} via %{user}"
msgstr ""
msgid "created %{timeAgoString} by %{user}"
-msgstr ""
+msgstr "于 %{timeAgoString} å‰ç”±%{user}创建"
msgid "created %{timeAgoString} by %{user} in Jira"
-msgstr ""
+msgstr "在 Jira 中,由%{user}于%{timeAgoString}å‰åˆ›å»º"
msgid "created %{timeAgo}"
msgstr "创建于%{timeAgo}"
@@ -38894,7 +39271,7 @@ msgid_plural "days"
msgstr[0] "天"
msgid "days"
-msgstr ""
+msgstr "天"
msgid "default branch"
msgstr "默认分支"
@@ -38924,7 +39301,7 @@ msgid "does not have a supported extension. Only %{extension_list} are supported
msgstr "当å‰æ‰©å±•åä¸æ”¯æŒã€‚åªæ”¯æŒ%{extension_list}"
msgid "domain is not authorized for sign-up."
-msgstr ""
+msgstr "域å未被授æƒæ³¨å†Œã€‚"
msgid "download it"
msgstr "下载"
@@ -38953,7 +39330,7 @@ msgid "encrypted: needs to be a :required, :optional or :migrating!"
msgstr "加密:必须是 :requiredã€:optional 或 :migrating 之一"
msgid "ending with MIME type format is not allowed."
-msgstr ""
+msgstr "ä¸å…许以 MIME 类型格å¼ç»“尾。"
msgid "entries cannot be larger than 255 characters"
msgstr "æ¡ç›®ä¸èƒ½è¶…过255个字符"
@@ -38964,6 +39341,9 @@ msgstr "æ¡ç›®ä¸èƒ½ä¸ºç©º"
msgid "entries cannot contain HTML tags"
msgstr "æ¡ç›®ä¸èƒ½åŒ…å«HTML标记"
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr "å²è¯—"
@@ -38971,7 +39351,7 @@ msgid "error"
msgstr "错误"
msgid "estimateCommand|%{slash_command} overwrites the total estimated time."
-msgstr ""
+msgstr "%{slash_command} 覆盖总估计时间。"
msgid "exceeds the limit of %{bytes} bytes"
msgstr "超过%{bytes}字节的é™åˆ¶"
@@ -39002,7 +39382,7 @@ msgid "finding is not found or is already attached to a vulnerability"
msgstr "结果无法找到或已与æ¼æ´žå…³è”。"
msgid "following"
-msgstr ""
+msgstr "已关注"
msgid "for %{link_to_merge_request} with %{link_to_merge_request_source_branch}"
msgstr "使用%{link_to_merge_request}于%{link_to_merge_request_source_branch}"
@@ -39054,7 +39434,7 @@ msgid "has already been taken as Codename"
msgstr ""
msgid "has already been taken as Suite"
-msgstr ""
+msgstr "在Suite中已ç»è¢«ä½¿ç”¨"
msgid "has been completed."
msgstr "已完æˆã€‚"
@@ -39066,16 +39446,16 @@ msgid "http:"
msgstr "http:"
msgid "http://www.example.com"
-msgstr ""
+msgstr "http://www.example.com"
msgid "https://bamboo.example.com"
-msgstr ""
+msgstr "https://bambo.example.com"
msgid "https://your-bitbucket-server"
msgstr "https://your-bitbucket-server"
msgid "i18n|%{language} (%{percent_translated}%% translated)"
-msgstr ""
+msgstr "%{language} (%{percent_translated}%% 已翻译)"
msgid "image diff"
msgstr "图åƒå·®å¼‚"
@@ -39144,20 +39524,17 @@ msgstr "ä¸è¢«å…许。请使用其他电å­é‚®ä»¶åœ°å€é‡è¯•ï¼Œæˆ–与您的Git
msgid "is not allowed. We do not currently support project-level iterations"
msgstr "ä¸è¢«å…许。我们目å‰ä¸æ”¯æŒé¡¹ç›®çº§è¿­ä»£"
-msgid "is not an email you own"
-msgstr "ä¸æ˜¯æ‚¨è‡ªå·±çš„电å­é‚®ä»¶"
-
msgid "is not from an allowed domain."
-msgstr ""
+msgstr "ä¸æ˜¯æ¥è‡ªå…许的域å。"
msgid "is not in the group enforcing Group Managed Account"
msgstr "ä¸åœ¨å¼ºåˆ¶æ‰§è¡Œç¾¤ç»„托管账户的群组"
msgid "is not valid. The iteration group has to match the iteration cadence group."
-msgstr ""
+msgstr "无效。迭代群组必须与迭代周期组匹é…。"
msgid "is read-only"
-msgstr ""
+msgstr "åªè¯»"
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr "太长(%{current_value})。最大值为%{max_size}。"
@@ -39278,7 +39655,7 @@ msgid "mrWidgetCommitsAdded|1 merge commit"
msgstr "1个åˆå¹¶æ交"
msgid "mrWidgetNothingToMerge|This merge request contains no changes."
-msgstr ""
+msgstr "æ­¤åˆå¹¶è¯·æ±‚ä¸åŒ…å«ä»»ä½•æ›´æ”¹ã€‚"
msgid "mrWidgetNothingToMerge|Use merge requests to propose changes to your project and discuss them with your team. To make changes, push a commit or edit this merge request to use a different branch. With %{linkStart}CI/CD%{linkEnd}, automatically test your changes before merging."
msgstr ""
@@ -39287,10 +39664,10 @@ msgid "mrWidget| Please restore it or use a different %{missingBranchName} branc
msgstr "请æ¢å¤æ­¤åˆ†æ”¯æˆ–使用其他的 %{missingBranchName} 分支"
msgid "mrWidget|%{mergeError}."
-msgstr ""
+msgstr "%{mergeError}。"
msgid "mrWidget|%{mergeError}. Try again."
-msgstr ""
+msgstr "%{mergeError},å†è¯•ä¸€æ¬¡ã€‚"
msgid "mrWidget|%{metricsLinkStart} Memory %{metricsLinkEnd} usage %{emphasisStart} decreased %{emphasisEnd} from %{memoryFrom}MB to %{memoryTo}MB"
msgstr "%{metricsLinkStart} 内存 %{metricsLinkEnd} å ç”¨ %{emphasisStart} ä¸‹é™ %{emphasisEnd},从 %{memoryFrom}MB 到 %{memoryTo}MB"
@@ -39308,7 +39685,7 @@ msgid "mrWidget|A new merge train has started and this merge request is the firs
msgstr "æ–°åˆå¹¶åˆ—车已ç»å¯åŠ¨ï¼Œæ­¤åˆå¹¶è¯·æ±‚ä½äºŽåˆå¹¶é˜Ÿåˆ—中的第一ä½ã€‚"
msgid "mrWidget|Added to the merge train by %{merge_author}"
-msgstr ""
+msgstr "ç”± %{merge_author} 添加到åˆå¹¶é˜Ÿåˆ—"
msgid "mrWidget|Added to the merge train. There are %{mergeTrainPosition} merge requests waiting to be merged"
msgstr "已添加到åˆå¹¶åˆ—车。当å‰æœ‰%{mergeTrainPosition}个åˆå¹¶è¯·æ±‚等待åˆå¹¶"
@@ -39341,7 +39718,7 @@ msgid "mrWidget|Are you adding technical debt or code vulnerabilities?"
msgstr "您会增加技术债务或引入代ç æ¼æ´žå—?"
msgid "mrWidget|Cancel auto-merge"
-msgstr ""
+msgstr "å–消自动åˆå¹¶"
msgid "mrWidget|Check out branch"
msgstr "检出分支"
@@ -39361,8 +39738,9 @@ msgstr "已关闭"
msgid "mrWidget|Closed by"
msgstr "关闭:"
-msgid "mrWidget|Closes"
-msgstr "关闭"
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
msgid "mrWidget|Delete source branch"
msgstr "删除æºåˆ†æ”¯"
@@ -39383,7 +39761,7 @@ msgid "mrWidget|If the %{missingBranchName} branch exists in your local reposito
msgstr "如果 %{missingBranchName} 分支存在于本地仓库中,则å¯ä»¥é€šè¿‡ä»¥ä¸‹å‘½ä»¤è¡Œæ‰‹åŠ¨åˆå¹¶è¯¥åˆå¹¶è¯·æ±‚。"
msgid "mrWidget|If the last pipeline ran in the fork project, it may be inaccurate. Before merge, we advise running a pipeline in this project."
-msgstr ""
+msgstr "如果最åŽä¸€ä¸ªæµæ°´çº¿è¿è¡Œåœ¨æ´¾ç”Ÿé¡¹ç›®ä¸­ï¼Œå®ƒå¯èƒ½ä¸å‡†ç¡®ã€‚åˆå¹¶å‰ï¼Œæˆ‘们建议在这个项目中è¿è¡Œä¸€æ¡æµæ°´çº¿ã€‚"
msgid "mrWidget|Jump to first unresolved thread"
msgstr "跳转到第一个未解决的主题"
@@ -39395,22 +39773,23 @@ msgid "mrWidget|Mark as ready"
msgstr "标记为已就绪"
msgid "mrWidget|Members who can merge are allowed to add commits."
-msgstr ""
+msgstr "å…许å¯ä»¥åˆå¹¶çš„æˆå‘˜æ·»åŠ æ交。"
-msgid "mrWidget|Mentions"
-msgstr "æåŠ"
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
msgid "mrWidget|Merge"
msgstr "åˆå¹¶"
msgid "mrWidget|Merge blocked: all threads must be resolved."
-msgstr ""
+msgstr "åˆå¹¶è¢«é˜»æ­¢ï¼šå¿…须解决所有主题。"
msgid "mrWidget|Merge blocked: fast-forward merge is not possible. To merge this request, first rebase locally."
-msgstr ""
+msgstr "åˆå¹¶è¢«é˜»æ­¢ï¼šå¿«è¿›åˆå¹¶æ˜¯ä¸å¯èƒ½çš„。è¦åˆå¹¶è¿™ä¸ªè¯·æ±‚,首先在本地å˜åŸºã€‚"
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
-msgstr ""
+msgstr "åˆå¹¶è¢«é˜»æ­¢ï¼šæµæ°´çº¿å¿…é¡»æˆåŠŸã€‚等待手动完æˆæ“作。"
msgid "mrWidget|Merge failed."
msgstr "åˆå¹¶å¤±è´¥ã€‚"
@@ -39425,26 +39804,29 @@ msgid "mrWidget|Merged by"
msgstr "åˆå¹¶è€…:"
msgid "mrWidget|Merging! Changes are being shipped…"
-msgstr ""
+msgstr "åˆå¹¶ä¸­ï¼æ­£åœ¨å‘é€æ›´æ”¹â€¦"
msgid "mrWidget|Merging! Changes will land soon…"
-msgstr ""
+msgstr "åˆå¹¶ä¸­ï¼å˜åŒ–å³å°†å®Œæˆâ€¦"
msgid "mrWidget|Merging! Drum roll, please…"
-msgstr ""
+msgstr "åˆå¹¶ä¸­ï¼è¯·ç¨åŽâ€¦"
msgid "mrWidget|Merging! Everything's good…"
-msgstr ""
+msgstr "正在åˆå¹¶ï¼ä¸€åˆ‡éƒ½å¾ˆå¥½â€¦"
msgid "mrWidget|Merging! This is going to be great…"
-msgstr ""
+msgstr "åˆå¹¶ä¸­ï¼è¯·ç¨åŽâ€¦"
msgid "mrWidget|Merging! We're almost there…"
-msgstr ""
+msgstr "正在åˆå¹¶ï¼æˆ‘们快完æˆäº†â€¦"
msgid "mrWidget|More information"
msgstr "更多信æ¯"
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr "在Web IDE中打开"
@@ -39488,13 +39870,13 @@ msgid "mrWidget|Revoke approval"
msgstr "撤销核准"
msgid "mrWidget|Set by %{merge_author} to be added to the merge train when the pipeline succeeds"
-msgstr ""
+msgstr "ç”±%{merge_author}设置为在æµæ°´çº¿æˆåŠŸæ—¶æ·»åŠ åˆ°åˆå¹¶é˜Ÿåˆ—中"
msgid "mrWidget|Set by %{merge_author} to be merged automatically when the pipeline succeeds"
-msgstr ""
+msgstr "ç”±%{merge_author}设置为æµæ°´çº¿æˆåŠŸæ—¶è‡ªåŠ¨åˆå¹¶"
msgid "mrWidget|Set by %{merge_author} to start a merge train when the pipeline succeeds"
-msgstr ""
+msgstr "ç”±%{merge_author}设置为在æµæ°´çº¿æˆåŠŸæ—¶å¯åŠ¨åˆå¹¶é˜Ÿåˆ—"
msgid "mrWidget|The changes were merged into"
msgstr "更改已åˆå¹¶åˆ°"
@@ -39506,10 +39888,7 @@ msgid "mrWidget|The changes will be merged into"
msgstr "更改将被åˆå¹¶åˆ°"
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr "æºåˆ†æ”¯HEAD最近已更改。请在é‡æ–°åˆå¹¶ä¹‹å‰é‡æ–°åŠ è½½é¡µé¢å¹¶æŸ¥çœ‹æ›´æ”¹"
+msgstr "æ­¤åˆå¹¶è¯·æ±‚çš„æµæ°´çº¿æœªå®Œæˆã€‚推é€æ–°çš„æ交以修å¤å¤±è´¥ï¼Œæˆ–检查 %{linkStart}故障排查文档%{linkEnd} 以查看其它å¯èƒ½çš„æ“作。"
msgid "mrWidget|The source branch has been deleted"
msgstr "æºåˆ†æ”¯å·²åˆ é™¤"
@@ -39545,14 +39924,11 @@ msgid "mrWidget|To approve this merge request, please enter your password. This
msgstr "è¦æ‰¹å‡†æ­¤åˆå¹¶è¯·æ±‚,请输入您的密ç ã€‚此项目需è¦æ‰€æœ‰æ‰¹å‡†æ‰èƒ½è®¤è¯ã€‚"
msgid "mrWidget|To merge, a Jira issue key must be mentioned in the title or description."
-msgstr ""
+msgstr "è¦åˆå¹¶ï¼Œå¿…须在标题或æ述中æ到Jira议题的key。"
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr "使用%{linkStart}CIæµæ°´çº¿æµ‹è¯•ä½ çš„代ç %{linkEnd},åªéœ€ç®€å•åœ°å‘项目添加一个GitLab CIé…置文件。åªéœ€è¦ä¸€åˆ†é’Ÿï¼Œå°±å¯ä»¥ä½¿ä½ çš„代ç çš„更加安全å¯é ã€‚"
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr "ä¸å…许直接编辑此项目。请派生(fork)åŽè¿›è¡Œæ›´æ”¹ã€‚"
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr "您å¯ä»¥åœ¨åˆ é™¤æ‹’ç»çš„许å¯è¯åŽåˆå¹¶"
@@ -39578,12 +39954,18 @@ msgid "must be a valid IPv4 or IPv6 address"
msgstr "必须是有效的IPv4或IPv6地å€"
msgid "must be after start"
+msgstr "必须在开始之åŽ"
+
+msgid "must be an email you have verified"
msgstr ""
msgid "must be greater than start date"
msgstr "必须大于开始日期"
msgid "must be inside the fork network"
+msgstr "必须在派生(fork)网络内"
+
+msgid "must be less than the limit of %{tag_limit} tags"
msgstr ""
msgid "must be unique by status and elapsed time within a policy"
@@ -39593,7 +39975,7 @@ msgid "my-awesome-group"
msgstr "my-awesome-group"
msgid "my-channel"
-msgstr ""
+msgstr "我的频é“"
msgid "n/a"
msgstr "ä¸é€‚用"
@@ -39650,7 +40032,7 @@ msgid "on track"
msgstr "按计划进行"
msgid "only available on top-level groups."
-msgstr ""
+msgstr "åªèƒ½åœ¨æœ€é¡¶çº§ç¾¤ç»„中使用。"
msgid "open issue"
msgstr "å¼€å¯çš„议题"
@@ -39679,7 +40061,7 @@ msgid "pending comment"
msgstr "待处ç†çš„评论"
msgid "pending deletion"
-msgstr ""
+msgstr "待删除"
msgid "per day"
msgstr "æ¯æ—¥"
@@ -39704,7 +40086,7 @@ msgid_plural "points"
msgstr[0] "点"
msgid "previously merged commits"
-msgstr ""
+msgstr "å…ˆå‰åˆå¹¶çš„æ交"
msgid "private"
msgstr "ç§æœ‰"
@@ -39771,13 +40153,13 @@ msgid "remove due date"
msgstr "删除截止日期"
msgid "remove start date"
-msgstr ""
+msgstr "删除开始日期"
msgid "remove weight"
msgstr "移除æƒé‡"
msgid "removed"
-msgstr ""
+msgstr "已删除"
msgid "removed a Zoom call from this issue"
msgstr "从当å‰è®®é¢˜ä¸­ç§»é™¤Zoom通è¯"
@@ -39793,7 +40175,7 @@ msgid "repository:"
msgstr "仓库:"
msgid "required"
-msgstr ""
+msgstr "å¿…å¡«"
msgid "reset it."
msgstr "é‡ç½®å®ƒã€‚"
@@ -39802,10 +40184,10 @@ msgid "satisfied"
msgstr "满足"
msgid "scan-execution-policy: policy not applied, %{policy_path} file is invalid"
-msgstr ""
+msgstr "扫æ执行策略:策略未应用, %{policy_path} 文件无效"
msgid "scan-execution-policy: policy not applied, %{policy_path} file is missing"
-msgstr ""
+msgstr "扫æ执行策略:策略未应用,缺少 %{policy_path} 文件"
msgid "security Reports|There was an error creating the merge request"
msgstr "创建åˆå¹¶è¯·æ±‚时出错"
@@ -39874,7 +40256,7 @@ msgid "specified top is not part of the tree"
msgstr "指定的顶级ä¸å±žäºŽç¾¤ç»„层级"
msgid "spendCommand|%{slash_command} adds or subtracts time already spent."
-msgstr ""
+msgstr "%{slash_command} 增加或å‡å°‘å·²ç»èŠ±è´¹çš„时间。"
msgid "ssh:"
msgstr "ssh:"
@@ -39916,25 +40298,25 @@ msgid "the correct format."
msgstr "正确的格å¼ã€‚"
msgid "the file"
-msgstr ""
+msgstr "文件"
msgid "the following issue(s)"
msgstr "下列议题"
msgid "the wiki"
-msgstr ""
+msgstr "wiki"
msgid "then"
-msgstr ""
+msgstr "然åŽ"
msgid "this document"
msgstr "此文档"
msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
+msgstr "此议题ä¸èƒ½åˆ†é…ç»™ä¿å¯†çš„å²è¯—,因为它是公开的"
msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
+msgstr "此议题ä¸èƒ½å…¬å¼€ï¼Œå› ä¸ºå®ƒå±žäºŽä¿å¯†çš„å²è¯—"
msgid "time summary"
msgstr "时间总计"
@@ -39943,7 +40325,7 @@ msgid "toggle collapse"
msgstr "切æ¢æŠ˜å "
msgid "train"
-msgstr ""
+msgstr "队列"
msgid "triggered"
msgstr "已触å‘"
@@ -39955,7 +40337,7 @@ msgid "type must be Debian"
msgstr "类型必须是 Debian"
msgid "type parameter is missing and is required"
-msgstr ""
+msgstr "缺少类型å‚数并且是必需的"
msgid "unicode domains should use IDNA encoding"
msgstr "unicode域å应使用IDNAç¼–ç "
@@ -39985,10 +40367,10 @@ msgid "v%{version} published %{timeAgo}"
msgstr "v%{version}å‘布于%{timeAgo}"
msgid "value for '%{storage}' must be an integer"
-msgstr ""
+msgstr "“%{storage}â€çš„值必须是整数"
msgid "value for '%{storage}' must be between 0 and 100"
-msgstr ""
+msgstr "“%{storage}â€çš„值必须在 0 到 100 之间"
msgid "verify ownership"
msgstr "验è¯æ‰€æœ‰æƒ"
@@ -40012,7 +40394,7 @@ msgid "view the source"
msgstr "查看æºä»£ç "
msgid "visibility"
-msgstr ""
+msgstr "å¯è§æ€§"
msgid "vulnerability"
msgid_plural "vulnerabilities"
diff --git a/locale/zh_HK/gitlab.po b/locale/zh_HK/gitlab.po
index 671a4eb68b5..e98b5ac1a6e 100644
--- a/locale/zh_HK/gitlab.po
+++ b/locale/zh_HK/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: zh-HK\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:18\n"
+"PO-Revision-Date: 2021-09-01 22:31\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -313,6 +313,10 @@ msgid "%d tag per image name"
msgid_plural "%d tags per image name"
msgstr[0] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -445,6 +449,9 @@ msgstr[0] "%{count} ä½åƒèˆ‡è€…"
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr ""
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -583,9 +590,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -595,6 +599,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -756,6 +763,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1152,7 +1162,7 @@ msgid_plural "%d issues selected"
msgstr[0] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgid "1 merged merge request"
@@ -1232,19 +1242,19 @@ msgid "30+ contributions"
msgstr ""
msgid "403|Please contact your GitLab administrator to get permission."
-msgstr "403|è«‹å‘ä½ çš„ GitLab 管ç†å“¡ç”³è«‹ä½¿ç”¨æ¬Šé™ã€‚"
+msgstr ""
msgid "403|You don't have the permission to access this page."
msgstr "您無權使用這個é é¢ã€‚"
msgid "404|Make sure the address is correct and the page hasn't moved."
-msgstr "404 |請確ä¿ç¶²å€æ­£ç¢ºä¸”網é ä½ç½®æ²’有被更改。"
+msgstr ""
msgid "404|Page Not Found"
msgstr "無法找到網é "
msgid "404|Please contact your GitLab administrator if you think this is a mistake."
-msgstr "404 |如果您èªç‚ºé€™æ˜¯éŒ¯èª¤ï¼Œè«‹è¯ç¹«æ‚¨çš„GitLab管ç†å“¡ã€‚"
+msgstr ""
msgid "7 days"
msgstr ""
@@ -1417,10 +1427,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1447,10 +1457,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2227,8 +2237,8 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
-msgstr "您將åœæ­¢æ‰€æœ‰ä»»å‹™ï¼Œé€™å°‡æœƒæš«åœæ‰€æœ‰æ­£åœ¨é‹è¡Œçš„任務。"
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
+msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
@@ -2455,12 +2465,6 @@ msgstr "å·²å°éŽ–"
msgid "AdminUsers|Blocking user has the following effects:"
msgstr ""
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2527,6 +2531,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr ""
@@ -2590,6 +2597,12 @@ msgstr ""
msgid "AdminUsers|Sort by"
msgstr ""
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr ""
@@ -2656,7 +2669,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3500,9 +3513,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr ""
-
msgid "An error occurred while fetching the job log."
msgstr ""
@@ -3518,9 +3528,6 @@ msgstr ""
msgid "An error occurred while fetching the latest pipeline."
msgstr ""
-msgid "An error occurred while fetching the pipeline."
-msgstr "讀å–æµæ°´ç·šæ™‚發生錯誤"
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr ""
@@ -3575,6 +3582,12 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4040,7 +4053,7 @@ msgid "ApprovalRuleSummary|%{count} approval required from %{membersCount}"
msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCount}"
msgstr[0] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4049,9 +4062,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4079,6 +4098,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4091,6 +4113,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4100,19 +4128,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4223,6 +4257,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr ""
@@ -4380,9 +4417,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4498,9 +4532,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr "您目å‰çš„許å¯è­‰ä¸æ”¯æ´æŒ‡æ´¾äººåå–®"
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr "指派人å單顯示了分é…給é¸å®šä½¿ç”¨è€…的所有議題。"
-
msgid "Assignee(s)"
msgstr "指派人"
@@ -4616,6 +4647,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4793,6 +4830,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -4985,9 +5025,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr "從é¸å®šçš„變更紀錄開始"
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5271,9 +5308,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5286,12 +5320,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5351,9 +5391,6 @@ msgid "Boards|Blocked by %{blockedByCount} %{issuableType}"
msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5654,30 +5691,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5732,6 +5763,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -5880,6 +5914,9 @@ msgstr ""
msgid "CPU"
msgstr ""
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6363,12 +6400,16 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6378,15 +6419,16 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6402,7 +6444,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7011,6 +7053,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7026,9 +7071,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7710,7 +7752,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8191,9 +8233,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8332,9 +8371,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8347,6 +8383,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9064,7 +9103,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10299,6 +10338,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10311,6 +10353,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10323,12 +10368,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10345,6 +10396,9 @@ msgid "DastSiteValidation|This will affect %d other profile targeting the same U
msgid_plural "DastSiteValidation|This will affect %d other profiles targeting the same URL."
msgstr[0] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10477,9 +10531,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10549,6 +10600,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10597,9 +10651,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr "刪除留言"
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10624,6 +10684,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10642,6 +10705,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10816,10 +10882,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -10864,6 +10930,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11291,6 +11369,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11351,7 +11435,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11859,6 +11943,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -11934,6 +12021,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12141,9 +12231,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12192,6 +12279,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12231,6 +12321,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12585,6 +12678,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12597,6 +12693,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12672,6 +12771,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12693,6 +12795,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13029,6 +13137,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14397,6 +14508,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14484,6 +14598,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14616,10 +14733,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14664,7 +14781,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14685,9 +14802,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14742,19 +14856,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14799,7 +14910,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14811,6 +14922,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14835,10 +14949,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -14910,7 +15024,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -14955,6 +15069,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15009,9 +15126,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15261,6 +15375,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15342,7 +15459,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15693,6 +15810,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15705,6 +15828,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15738,7 +15864,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16266,10 +16392,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16400,6 +16526,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16538,7 +16667,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16823,6 +16952,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17582,6 +17714,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17591,6 +17729,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17679,6 +17823,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17799,6 +17946,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -17988,9 +18138,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18528,6 +18675,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19221,9 +19371,6 @@ msgstr "標籤"
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19345,9 +19492,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19366,6 +19510,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19801,10 +19948,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
+msgstr ""
+
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20312,6 +20462,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20360,6 +20513,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20378,6 +20534,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20390,7 +20549,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20405,9 +20564,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20441,6 +20606,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20465,6 +20636,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20504,6 +20678,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20672,6 +20849,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20789,9 +20969,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20804,9 +20981,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21286,9 +21460,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr "ç›®å‰è¨±å¯è­‰ç„¡æ³•ä½¿ç”¨é‡Œç¨‹ç¢‘列表"
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr "里程碑列表將顯示所é¸é‡Œç¨‹ç¢‘的所有議題"
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21563,7 +21734,7 @@ msgid "More information and share feedback"
msgstr ""
msgid "More information is available|here"
-msgstr "幫助文檔"
+msgstr ""
msgid "More information."
msgstr ""
@@ -21667,7 +21838,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -21857,12 +22028,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -21905,9 +22070,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -21917,21 +22079,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -21947,9 +22100,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22095,9 +22245,6 @@ msgstr "新增分支"
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22281,6 +22428,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22798,6 +22948,9 @@ msgstr "å一月"
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -22927,7 +23080,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23222,7 +23375,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23414,6 +23567,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24551,6 +24707,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -24992,13 +25193,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25010,9 +25208,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25277,6 +25472,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25469,9 +25667,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26570,9 +26765,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26624,6 +26816,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26663,9 +26858,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -26985,7 +27177,7 @@ msgid "Push commits to the source branch or add previously merged commits to rev
msgstr ""
msgid "Push events"
-msgstr "推é€äº‹ä»¶ (push event) "
+msgstr ""
msgid "Push project from command line"
msgstr ""
@@ -27167,6 +27359,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27236,6 +27434,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27348,6 +27549,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -27857,6 +28061,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28301,6 +28508,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28569,6 +28779,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28632,6 +28845,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29087,9 +29303,6 @@ msgstr[0] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29141,7 +29354,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29177,7 +29390,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29291,55 +29504,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|Select security project"
+msgstr ""
+
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
+msgstr ""
+
+msgid "SecurityOrchestration|This project does not contain any security policies."
+msgstr ""
+
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29378,9 +29660,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29492,9 +29771,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29561,6 +29837,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30134,7 +30413,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30182,7 +30461,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30383,9 +30662,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30607,6 +30883,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -30958,6 +31237,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32427,6 +32715,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32478,12 +32769,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32496,7 +32793,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32718,7 +33015,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -32935,6 +33232,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -32971,9 +33271,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33127,6 +33424,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33265,9 +33565,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33313,6 +33619,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33493,9 +33802,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33715,9 +34021,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33790,6 +34093,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -34833,13 +35139,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35401,6 +35713,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35620,9 +35935,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35641,9 +35953,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35692,6 +36010,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -35848,6 +36169,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36325,9 +36649,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36522,6 +36852,10 @@ msgstr ""
msgid "View project labels"
msgstr "查看專案標籤"
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+
msgid "View replaced file @ "
msgstr "檢視已å–代檔案 @ "
@@ -36780,9 +37114,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36795,6 +37126,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -36900,6 +37234,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37155,6 +37492,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37213,6 +37553,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37771,6 +38114,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37786,6 +38132,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -37930,7 +38279,7 @@ msgstr "您已é”到項目數é‡é™åˆ¶"
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38356,7 +38705,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38386,6 +38735,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38489,6 +38862,10 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+
msgid "branch name"
msgstr "分支å稱"
@@ -38612,10 +38989,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -38964,6 +39341,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39144,9 +39524,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39361,8 +39738,9 @@ msgstr "關閉"
msgid "mrWidget|Closed by"
msgstr "關閉"
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39397,8 +39775,9 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr "æ到"
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39445,6 +39824,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr "åœ¨ç¶²é  IDE 中開啟"
@@ -39508,9 +39890,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39550,9 +39929,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39580,12 +39956,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/locale/zh_TW/gitlab.po b/locale/zh_TW/gitlab.po
index 080710286fc..b4ea86b9b53 100644
--- a/locale/zh_TW/gitlab.po
+++ b/locale/zh_TW/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: zh-TW\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-08-10 22:23\n"
+"PO-Revision-Date: 2021-09-01 22:32\n"
msgid " %{name}, confirm your email address now! "
msgstr ""
@@ -313,6 +313,10 @@ msgid "%d tag per image name"
msgid_plural "%d tags per image name"
msgstr[0] ""
+msgid "%d token has expired"
+msgid_plural "%d tokens have expired"
+msgstr[0] ""
+
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
msgstr[0] ""
@@ -445,6 +449,9 @@ msgstr[0] "%{count} ä½åƒèˆ‡è€…"
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr "%{count} 個相關的 %{pluralized_subject}:%{links}"
+msgid "%{count} selected"
+msgstr ""
+
msgid "%{count} total weight"
msgstr ""
@@ -583,9 +590,6 @@ msgstr ""
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
msgstr ""
-msgid "%{labelStart}Scan Type:%{labelEnd} %{reportType}"
-msgstr ""
-
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
msgstr ""
@@ -595,6 +599,9 @@ msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr ""
+msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -756,6 +763,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{scope} results for term '%{term}'"
+msgstr ""
+
msgid "%{seconds}s"
msgstr ""
@@ -1152,7 +1162,7 @@ msgid_plural "%d issues selected"
msgstr[0] ""
msgid "1 merge request selected"
-msgid_plural "%d merge request selected"
+msgid_plural "%d merge requests selected"
msgstr[0] ""
msgid "1 merged merge request"
@@ -1417,10 +1427,10 @@ msgstr ""
msgid "API?"
msgstr ""
-msgid "APIFuzzing|$VariableWithPassword"
+msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
-msgid "APIFuzzing|$VariableWithUsername"
+msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
@@ -1447,10 +1457,10 @@ msgstr ""
msgid "APIFuzzing|Enable authentication"
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the password. For example, $VariableWithPassword."
+msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
-msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
+msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
msgstr ""
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
@@ -2227,8 +2237,8 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
-msgstr "您å³å°‡åœæ­¢æ‰€æœ‰ä½œæ¥­ã€‚這會中斷並çµæŸæ‰€æœ‰æ­£åœ¨åŸ·è¡Œçš„作業。"
+msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
+msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "載入統計資料時發生錯誤。請å†è©¦ä¸€æ¬¡"
@@ -2455,12 +2465,6 @@ msgstr "å·²å°éŽ–"
msgid "AdminUsers|Blocking user has the following effects:"
msgstr "å°éŽ–使用者具有以下效果:"
-msgid "AdminUsers|Can't access Git repositories."
-msgstr ""
-
-msgid "AdminUsers|Can't log in."
-msgstr ""
-
msgid "AdminUsers|Cannot sign in or access instance information"
msgstr ""
@@ -2527,6 +2531,9 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
+msgid "AdminUsers|Issues authored by this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|It's you!"
msgstr "這就是你ï¼"
@@ -2590,6 +2597,12 @@ msgstr "å‘使用者傳é€é›»å­éƒµä»¶"
msgid "AdminUsers|Sort by"
msgstr "排åºæ–¹å¼"
+msgid "AdminUsers|The user can't access git repositories."
+msgstr ""
+
+msgid "AdminUsers|The user can't log in."
+msgstr ""
+
msgid "AdminUsers|The user will be logged out"
msgstr "此使用者將會登出"
@@ -2656,7 +2669,7 @@ msgstr ""
msgid "AdminUsers|What does this mean?"
msgstr ""
-msgid "AdminUsers|When banned, users:"
+msgid "AdminUsers|When banned:"
msgstr ""
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
@@ -3500,9 +3513,6 @@ msgstr ""
msgid "An error occurred while fetching terraform reports."
msgstr ""
-msgid "An error occurred while fetching the board lists. Please try again."
-msgstr "抓å–看æ¿åˆ—表時發生錯誤。請å†è©¦ä¸€æ¬¡ã€‚"
-
msgid "An error occurred while fetching the job log."
msgstr "抓å–作業日誌時發生錯誤。"
@@ -3518,9 +3528,6 @@ msgstr "抓å–作業時發生錯誤。"
msgid "An error occurred while fetching the latest pipeline."
msgstr "抓å–最後一個æµæ°´ç·šæ™‚發生錯誤。"
-msgid "An error occurred while fetching the pipeline."
-msgstr "抓å–æµæ°´ç·šæ™‚發生錯誤。"
-
msgid "An error occurred while fetching the releases. Please try again."
msgstr "抓å–發行版本時發生錯誤。請é‡è©¦ã€‚"
@@ -3575,6 +3582,12 @@ msgstr "載入議題時發生錯誤"
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading the Needs tab."
+msgstr ""
+
+msgid "An error occurred while loading the Test Reports tab."
+msgstr ""
+
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
@@ -4040,7 +4053,7 @@ msgid "ApprovalRuleSummary|%{count} approval required from %{membersCount}"
msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCount}"
msgstr[0] ""
-msgid "ApprovalRule|%{scanner} +%{additionalScanners} more"
+msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
msgid "ApprovalRule|Add approvers"
@@ -4049,9 +4062,15 @@ msgstr ""
msgid "ApprovalRule|All scanners"
msgstr ""
+msgid "ApprovalRule|All severity levels"
+msgstr ""
+
msgid "ApprovalRule|Apply this approval rule to consider only the selected security scanners."
msgstr ""
+msgid "ApprovalRule|Apply this approval rule to consider only the selected severity levels."
+msgstr ""
+
msgid "ApprovalRule|Approval rules"
msgstr ""
@@ -4079,6 +4098,9 @@ msgstr ""
msgid "ApprovalRule|Please select at least one security scanner"
msgstr ""
+msgid "ApprovalRule|Please select at least one severity level"
+msgstr ""
+
msgid "ApprovalRule|Rule name"
msgstr ""
@@ -4091,6 +4113,12 @@ msgstr ""
msgid "ApprovalRule|Select scanners"
msgstr ""
+msgid "ApprovalRule|Select severity levels"
+msgstr ""
+
+msgid "ApprovalRule|Severity levels"
+msgstr ""
+
msgid "ApprovalRule|Target branch"
msgstr ""
@@ -4100,19 +4128,25 @@ msgstr ""
msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
-msgid "ApprovalSettings|Prevent MR approvals by the author."
+msgid "ApprovalSettings|Prevent approval by author."
+msgstr ""
+
+msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr ""
-msgid "ApprovalSettings|Prevent approval of merge requests by merge request committers."
+msgid "ApprovalSettings|Prevent editing approval rules in merge requests."
msgstr ""
-msgid "ApprovalSettings|Prevent users from modifying MR approval rules."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr ""
-msgid "ApprovalSettings|Remove all approvals in a merge request when new commits are pushed to its source branch."
+msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests. "
msgstr ""
-msgid "ApprovalSettings|Require user password for approvals."
+msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch."
+msgstr ""
+
+msgid "ApprovalSettings|Require user password to approve."
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -4223,6 +4257,9 @@ msgstr "確定è¦å–消歸檔此專案嗎?"
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to attempt to merge?"
+msgstr ""
+
msgid "Are you sure you want to cancel editing this comment?"
msgstr "確定è¦å–消編輯此留言嗎?"
@@ -4380,9 +4417,6 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Artifacts maximum size"
-msgstr ""
-
msgid "As we continue to build more features for SAST, we'd love your feedback on the SAST configuration feature in %{linkStart}this issue%{linkEnd}."
msgstr ""
@@ -4498,9 +4532,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
-msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
-
msgid "Assignee(s)"
msgstr ""
@@ -4616,6 +4647,12 @@ msgstr ""
msgid "Authenticated API requests"
msgstr ""
+msgid "Authenticated Git LFS rate limit period in seconds"
+msgstr ""
+
+msgid "Authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Authenticated web rate limit period in seconds"
msgstr ""
@@ -4793,6 +4830,9 @@ msgstr ""
msgid "Automatic deployment rollbacks"
msgstr ""
+msgid "Automatic event tracking provides a traceable history for audits."
+msgstr ""
+
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -4985,9 +5025,6 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
-msgid "Below are the current settings regarding"
-msgstr ""
-
msgid "Below are the fingerprints for the current instance SSH host keys."
msgstr ""
@@ -5271,9 +5308,6 @@ msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
-msgid "BoardScope|No matching results"
-msgstr ""
-
msgid "BoardScope|No milestone"
msgstr ""
@@ -5286,12 +5320,18 @@ msgstr ""
msgid "BoardScope|Select milestone"
msgstr ""
+msgid "BoardScope|Select weight"
+msgstr ""
+
msgid "BoardScope|Started"
msgstr ""
msgid "BoardScope|Upcoming"
msgstr ""
+msgid "BoardScope|Weight"
+msgstr ""
+
msgid "Boards"
msgstr ""
@@ -5351,9 +5391,6 @@ msgid "Boards|Blocked by %{blockedByCount} %{issuableType}"
msgid_plural "Boards|Blocked by %{blockedByCount} %{issuableType}s"
msgstr[0] ""
-msgid "Boards|Board"
-msgstr ""
-
msgid "Boards|Collapse"
msgstr ""
@@ -5654,30 +5691,24 @@ msgstr ""
msgid "BulkImport|From source group"
msgstr ""
-msgid "BulkImport|Import %{groups}"
-msgstr ""
-
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import groups from GitLab"
msgstr ""
-msgid "BulkImport|Importing the group failed"
+msgid "BulkImport|Import selected"
msgstr ""
-msgid "BulkImport|Name already exists."
+msgid "BulkImport|Importing the group failed"
msgstr ""
-msgid "BulkImport|No groups on this page are available for import"
+msgid "BulkImport|Name already exists."
msgstr ""
msgid "BulkImport|No parent"
msgstr ""
-msgid "BulkImport|One or more groups has validation errors"
-msgstr ""
-
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5732,6 +5763,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
+msgid "Buy Storage"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -5880,6 +5914,9 @@ msgstr ""
msgid "CPU"
msgstr "CPU"
+msgid "CSV is being generated and will be emailed to you upon completion."
+msgstr ""
+
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6363,12 +6400,16 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per pack per year"
+msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
+msgid "Checkout|%d CI minute pack"
+msgid_plural "Checkout|%d CI minute packs"
+msgstr[0] ""
+
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
@@ -6378,15 +6419,16 @@ msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
-msgid "Checkout|%{quantity} CI minute packs"
-msgstr ""
-
msgid "Checkout|%{selectedPlanText} plan"
msgstr ""
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
+msgid "Checkout|%{totalCiMinutes} CI minute"
+msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
+msgstr[0] ""
+
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
@@ -6402,7 +6444,7 @@ msgstr ""
msgid "Checkout|Billing address"
msgstr ""
-msgid "Checkout|CI minute packs"
+msgid "Checkout|CI minute pack"
msgstr ""
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
@@ -7011,6 +7053,9 @@ msgstr ""
msgid "ClusterAgents|Go to the repository"
msgstr ""
+msgid "ClusterAgents|Install a new GitLab Agent"
+msgstr ""
+
msgid "ClusterAgents|Install new Agent"
msgstr ""
@@ -7026,9 +7071,6 @@ msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
-msgid "ClusterAgents|Learn more about installing the GitLab Agent"
-msgstr ""
-
msgid "ClusterAgents|Name"
msgstr ""
@@ -7710,7 +7752,7 @@ msgstr ""
msgid "ClusterIntegration|Subnets"
msgstr ""
-msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provision role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
+msgid "ClusterIntegration|The Amazon Resource Name (ARN) associated with your role. If you do not have a provisioned role, first create one on %{startAwsLink}Amazon Web Services %{externalLinkIcon}%{endLink} using the above account and external IDs. %{startMoreInfoLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
@@ -8191,9 +8233,6 @@ msgstr ""
msgid "Compliance framework"
msgstr ""
-msgid "Compliance framework (optional)"
-msgstr ""
-
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8332,9 +8371,6 @@ msgstr ""
msgid "Configure limits for web and API requests."
msgstr ""
-msgid "Configure limits on the number of inbound alerts able to be sent to a project."
-msgstr ""
-
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -8347,6 +8383,9 @@ msgstr ""
msgid "Configure settings for Advanced Search with Elasticsearch."
msgstr ""
+msgid "Configure specific limits for Git LFS requests that supersede the general user and IP rate limits."
+msgstr ""
+
msgid "Configure specific limits for Packages API requests that supersede the general user and IP rate limits."
msgstr ""
@@ -9064,7 +9103,7 @@ msgstr ""
msgid "CorpusManagement|Latest Job:"
msgstr ""
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10Gib"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
msgstr ""
msgid "CorpusManagement|New upload"
@@ -10299,6 +10338,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
+msgid "DastSiteValidation|Copy Meta tag to clipboard"
+msgstr ""
+
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
@@ -10311,6 +10353,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
+msgid "DastSiteValidation|Meta tag validation"
+msgstr ""
+
msgid "DastSiteValidation|Retry validation"
msgstr ""
@@ -10323,12 +10368,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
+msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
+msgstr ""
+
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
+msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
+msgstr ""
+
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
msgstr ""
@@ -10345,6 +10396,9 @@ msgid "DastSiteValidation|This will affect %d other profile targeting the same U
msgid_plural "DastSiteValidation|This will affect %d other profiles targeting the same URL."
msgstr[0] ""
+msgid "DastSiteValidation|To run an active scan, validate your target site. All site profiles that share the same base URL share the same validation status."
+msgstr ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -10477,9 +10531,6 @@ msgstr ""
msgid "Decrease"
msgstr ""
-msgid "Default"
-msgstr ""
-
msgid "Default CI/CD configuration file"
msgstr ""
@@ -10549,6 +10600,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
msgstr ""
+msgid "Define how approval rules are applied as a merge request moves toward completion."
+msgstr ""
+
msgid "Definition"
msgstr ""
@@ -10597,9 +10651,15 @@ msgstr ""
msgid "Delete badge"
msgstr ""
+msgid "Delete column"
+msgstr ""
+
msgid "Delete comment"
msgstr ""
+msgid "Delete corpus"
+msgstr ""
+
msgid "Delete domain"
msgstr ""
@@ -10624,6 +10684,9 @@ msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
+msgid "Delete row"
+msgstr ""
+
msgid "Delete self monitoring project"
msgstr ""
@@ -10642,6 +10705,9 @@ msgstr ""
msgid "Delete subscription"
msgstr ""
+msgid "Delete table"
+msgstr ""
+
msgid "Delete this attachment"
msgstr ""
@@ -10816,10 +10882,10 @@ msgstr ""
msgid "Dependency proxy"
msgstr ""
-msgid "Dependency proxy URL"
+msgid "Dependency proxy feature is limited to public groups for now."
msgstr ""
-msgid "Dependency proxy feature is limited to public groups for now."
+msgid "Dependency proxy image prefix"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
@@ -10864,6 +10930,18 @@ msgstr ""
msgid "DeployFreeze|Add deploy freeze"
msgstr ""
+msgid "DeployFreeze|Delete"
+msgstr ""
+
+msgid "DeployFreeze|Delete deploy freeze?"
+msgstr ""
+
+msgid "DeployFreeze|Delete freeze period"
+msgstr ""
+
+msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?"
+msgstr ""
+
msgid "DeployFreeze|Edit"
msgstr ""
@@ -11291,6 +11369,12 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
+msgid "DevopsAdoption|Adoption by group"
+msgstr ""
+
+msgid "DevopsAdoption|Adoption by subgroup"
+msgstr ""
+
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -11351,7 +11435,7 @@ msgstr ""
msgid "DevopsAdoption|Edit subgroups"
msgstr ""
-msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Last updated: %{timestamp}."
+msgid "DevopsAdoption|Feature adoption is based on usage in the previous calendar month. Data is updated at the beginning of each month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Fuzz Testing"
@@ -11859,6 +11943,9 @@ msgstr ""
msgid "Edit Group Hook"
msgstr ""
+msgid "Edit Identity"
+msgstr ""
+
msgid "Edit Label"
msgstr ""
@@ -11934,6 +12021,9 @@ msgstr ""
msgid "Edit sidebar"
msgstr ""
+msgid "Edit table"
+msgstr ""
+
msgid "Edit this file only."
msgstr ""
@@ -12141,9 +12231,6 @@ msgstr ""
msgid "Enable Gitpod?"
msgstr ""
-msgid "Enable Incident Management inbound alert limit"
-msgstr ""
-
msgid "Enable Invisible Captcha during sign up"
msgstr ""
@@ -12192,6 +12279,9 @@ msgstr ""
msgid "Enable authenticated API request rate limit"
msgstr ""
+msgid "Enable authenticated Git LFS request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12231,6 +12321,9 @@ msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
+msgid "Enable incident management inbound alert limit"
+msgstr ""
+
msgid "Enable integration"
msgstr ""
@@ -12585,6 +12678,9 @@ msgstr ""
msgid "Environments|Deployment %{status}"
msgstr ""
+msgid "Environments|Dismiss"
+msgstr ""
+
msgid "Environments|Enable review app"
msgstr ""
@@ -12597,6 +12693,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
+msgid "Environments|Help us improve environments"
+msgstr ""
+
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@@ -12672,6 +12771,9 @@ msgstr ""
msgid "Environments|Stopping %{environmentName}"
msgstr ""
+msgid "Environments|Take the survey"
+msgstr ""
+
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr ""
@@ -12693,6 +12795,12 @@ msgstr ""
msgid "Environments|You don't have any environments right now"
msgstr ""
+msgid "Environments|Your feedback helps GitLab make environments better for you and other users. Participate and enter a sweepstake to win a USD 30 gift card."
+msgstr ""
+
+msgid "Environments|by %{avatar}"
+msgstr ""
+
msgid "Environments|protected"
msgstr ""
@@ -13029,6 +13137,9 @@ msgstr ""
msgid "Error: Unable to create deploy freeze"
msgstr ""
+msgid "Error: Unable to delete deploy freeze"
+msgstr ""
+
msgid "Error: Unable to find AWS role for current user"
msgstr ""
@@ -14397,6 +14508,9 @@ msgstr ""
msgid "Format: %{dateFormat}"
msgstr ""
+msgid "Forward %{package_type} package requests to the %{registry_type} Registry if the packages are not found in the GitLab Package Registry"
+msgstr ""
+
msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr ""
@@ -14484,6 +14598,9 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
+msgid "Generic"
+msgstr ""
+
msgid "Generic package file size in bytes"
msgstr ""
@@ -14616,10 +14733,10 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
-msgid "Geo|Geo nodes are paused using a command run on the node"
+msgid "Geo|Geo sites"
msgstr ""
-msgid "Geo|Geo sites"
+msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
@@ -14664,7 +14781,7 @@ msgstr ""
msgid "Geo|Learn more about Geo"
msgstr ""
-msgid "Geo|Learn more about Geo node statuses"
+msgid "Geo|Learn more about Geo site statuses"
msgstr ""
msgid "Geo|Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
@@ -14685,9 +14802,6 @@ msgstr ""
msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
-msgid "Geo|Node's status was updated %{timeAgo}."
-msgstr ""
-
msgid "Geo|Not synced yet"
msgstr ""
@@ -14742,19 +14856,16 @@ msgstr ""
msgid "Geo|Remove node"
msgstr ""
-msgid "Geo|Remove secondary node"
-msgstr ""
-
msgid "Geo|Remove tracking database entry"
msgstr ""
-msgid "Geo|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgid "Geo|Removing a Geo node stops the synchronization to and from that node. Are you sure?"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums"
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
msgstr ""
-msgid "Geo|Replicated data is verified with the secondary node(s) using checksums."
+msgid "Geo|Replicated data is verified with the secondary site(s) using checksums."
msgstr ""
msgid "Geo|Replication Details"
@@ -14799,7 +14910,7 @@ msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
-msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary site."
msgstr ""
msgid "Geo|Secondary node"
@@ -14811,6 +14922,9 @@ msgstr ""
msgid "Geo|Selective (%{syncLabel})"
msgstr ""
+msgid "Geo|Site's status was updated %{timeAgo}."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -14835,10 +14949,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
-msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgid "Geo|The database is currently %{db_lag} behind the primary site."
msgstr ""
-msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgid "Geo|The site is currently %{minutes_behind} behind the primary site."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
@@ -14910,7 +15024,7 @@ msgstr ""
msgid "Geo|With GitLab Geo, you can install a special read-only and replicated instance anywhere. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo node."
+msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
@@ -14955,6 +15069,9 @@ msgstr ""
msgid "Git GC period"
msgstr ""
+msgid "Git LFS Rate Limits"
+msgstr ""
+
msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr ""
@@ -15009,9 +15126,6 @@ msgstr ""
msgid "GitLab Billing Team."
msgstr ""
-msgid "GitLab CI"
-msgstr ""
-
msgid "GitLab Import"
msgstr ""
@@ -15261,6 +15375,9 @@ msgstr ""
msgid "Given epic is already related to this epic."
msgstr ""
+msgid "Global Search is disabled for this scope"
+msgstr ""
+
msgid "Global Shortcuts"
msgstr ""
@@ -15342,7 +15459,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
-msgid "Go to primary node"
+msgid "Go to primary site"
msgstr ""
msgid "Go to project"
@@ -15693,6 +15810,12 @@ msgstr ""
msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
msgstr ""
+msgid "GroupRoadmap|This quarter"
+msgstr ""
+
+msgid "GroupRoadmap|This year"
+msgstr ""
+
msgid "GroupRoadmap|To make your epics appear in the roadmap, add start or due dates to them."
msgstr ""
@@ -15705,6 +15828,9 @@ msgstr ""
msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
msgstr ""
+msgid "GroupRoadmap|Within 3 years"
+msgstr ""
+
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enabling %{linkStart}SSO enforcement%{linkEnd} can reduce security risks."
msgstr ""
@@ -15738,7 +15864,7 @@ msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
-msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
+msgid "GroupSAML|Enforce SSO-only authentication for Git and Dependency Proxy activity for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
@@ -16266,10 +16392,10 @@ msgstr ""
msgid "Helps prevent malicious users hide their activity"
msgstr ""
-msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
msgstr ""
-msgid "Helps reduce request volume (e.g. from crawlers or abusive bots)"
+msgid "Helps reduce request volume (for example, from crawlers or abusive bots)"
msgstr ""
msgid "Helps reduce request volume for protected paths"
@@ -16400,6 +16526,9 @@ msgstr ""
msgid "How do I mirror repositories?"
msgstr ""
+msgid "How do I rename an environment?"
+msgstr ""
+
msgid "How do I set up a Google Chat webhook?"
msgstr ""
@@ -16538,7 +16667,7 @@ msgstr ""
msgid "If disabled, only administrators can configure repository mirroring."
msgstr ""
-msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}More information%{linkEnd}"
+msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
@@ -16823,6 +16952,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
+msgid "InProductMarketing|%{organization_name} logo"
+msgstr ""
+
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -17582,6 +17714,12 @@ msgstr ""
msgid "Insert code"
msgstr ""
+msgid "Insert column after"
+msgstr ""
+
+msgid "Insert column before"
+msgstr ""
+
msgid "Insert image"
msgstr ""
@@ -17591,6 +17729,12 @@ msgstr ""
msgid "Insert link"
msgstr ""
+msgid "Insert row after"
+msgstr ""
+
+msgid "Insert row before"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
@@ -17679,6 +17823,9 @@ msgstr ""
msgid "Integrations|All projects inheriting these settings will also be reset."
msgstr ""
+msgid "Integrations|An error occurred while loading projects using custom settings."
+msgstr ""
+
msgid "Integrations|Browser limitations"
msgstr ""
@@ -17799,6 +17946,9 @@ msgstr ""
msgid "Integrations|Standard"
msgstr ""
+msgid "Integrations|There are no projects using custom settings"
+msgstr ""
+
msgid "Integrations|This integration, and inheriting projects were reset."
msgstr ""
@@ -17988,9 +18138,6 @@ msgstr ""
msgid "Invite members"
msgstr ""
-msgid "Invite your team"
-msgstr ""
-
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
@@ -18528,6 +18675,9 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
+msgid "Iterations|Create your first iteration"
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -19221,9 +19371,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
-msgid "Label lists show all issues with the selected label."
-msgstr ""
-
msgid "Label priority"
msgstr ""
@@ -19345,9 +19492,6 @@ msgstr ""
msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
msgstr ""
-msgid "Last repository check run"
-msgstr ""
-
msgid "Last seen"
msgstr ""
@@ -19366,6 +19510,9 @@ msgstr ""
msgid "Last successful update"
msgstr ""
+msgid "Last time checked"
+msgstr ""
+
msgid "Last time verified"
msgstr ""
@@ -19801,10 +19948,13 @@ msgstr ""
msgid "Limit sign in from multiple ips"
msgstr ""
-msgid "Limit the number of concurrent operations this secondary node can run in the background."
+msgid "Limit the number of concurrent operations this secondary site can run in the background."
+msgstr ""
+
+msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
-msgid "Limit the number of issues per minute a user can create through web and API requests."
+msgid "Limit the number of issues and epics per minute a user can create through web and API requests."
msgstr ""
msgid "Limited to showing %d event at most"
@@ -20312,6 +20462,9 @@ msgstr ""
msgid "Max authenticated API requests per period per user"
msgstr ""
+msgid "Max authenticated Git LFS requests per period per user"
+msgstr ""
+
msgid "Max authenticated web requests per period per user"
msgstr ""
@@ -20360,6 +20513,9 @@ msgstr ""
msgid "Maximum artifacts size (MB)"
msgstr ""
+msgid "Maximum attachment size"
+msgstr ""
+
msgid "Maximum attachment size (MB)"
msgstr ""
@@ -20378,6 +20534,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum diff patch size"
+msgstr ""
+
msgid "Maximum diff patch size (Bytes)"
msgstr ""
@@ -20390,7 +20549,7 @@ msgstr ""
msgid "Maximum file size indexed (KiB)"
msgstr ""
-msgid "Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}."
+msgid "Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}."
msgstr ""
msgid "Maximum file size is 1MB. Pages are optimized for a 28px tall header logo"
@@ -20405,9 +20564,15 @@ msgstr ""
msgid "Maximum files in a diff"
msgstr ""
+msgid "Maximum import size"
+msgstr ""
+
msgid "Maximum import size (MB)"
msgstr ""
+msgid "Maximum job artifact size"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -20441,6 +20606,12 @@ msgstr ""
msgid "Maximum page reached"
msgstr ""
+msgid "Maximum page size"
+msgstr ""
+
+msgid "Maximum push size"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -20465,6 +20636,9 @@ msgstr ""
msgid "Maximum size of pages (MB)"
msgstr ""
+msgid "Maximum snippet size"
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -20504,6 +20678,9 @@ msgstr ""
msgid "MemberInviteEmail|%{member_name} invited you to join GitLab"
msgstr ""
+msgid "MemberInviteEmail|I've invited you to join me in GitLab"
+msgstr ""
+
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
@@ -20672,6 +20849,9 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
+msgid "Merge blocked: new changes were just added."
+msgstr ""
+
msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
@@ -20789,9 +20969,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line"
msgstr ""
-msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
-msgstr ""
-
msgid "MergeRequests|An error occurred while saving the draft comment."
msgstr ""
@@ -20804,9 +20981,6 @@ msgstr ""
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Squash task canceled: another squash is already in progress."
-msgstr ""
-
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21286,9 +21460,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
-msgid "Milestone lists show all issues from the selected milestone."
-msgstr ""
-
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
@@ -21667,7 +21838,7 @@ msgstr ""
msgid "Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
-msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}More information%{linkEnd}"
+msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "My Awesome Group"
@@ -21857,12 +22028,6 @@ msgstr ""
msgid "NetworkPolicies|Edit policy"
msgstr ""
-msgid "NetworkPolicies|Edit policy project"
-msgstr ""
-
-msgid "NetworkPolicies|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -21905,9 +22070,6 @@ msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr ""
-msgid "NetworkPolicies|Policies"
-msgstr ""
-
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
@@ -21917,21 +22079,12 @@ msgstr ""
msgid "NetworkPolicies|Policy definition"
msgstr ""
-msgid "NetworkPolicies|Policy description"
-msgstr ""
-
msgid "NetworkPolicies|Policy editor"
msgstr ""
msgid "NetworkPolicies|Policy preview"
msgstr ""
-msgid "NetworkPolicies|Policy status"
-msgstr ""
-
-msgid "NetworkPolicies|Policy type"
-msgstr ""
-
msgid "NetworkPolicies|Rule"
msgstr ""
@@ -21947,9 +22100,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
-msgid "NetworkPolicies|Scan Execution"
-msgstr ""
-
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -22095,9 +22245,6 @@ msgstr ""
msgid "New branch unavailable"
msgstr ""
-msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
-
msgid "New confidential epic title "
msgstr ""
@@ -22281,6 +22428,9 @@ msgstr ""
msgid "No approvers"
msgstr ""
+msgid "No artifacts found"
+msgstr ""
+
msgid "No assignee"
msgstr ""
@@ -22798,6 +22948,9 @@ msgstr ""
msgid "Novice"
msgstr ""
+msgid "Now, personalize your GitLab experience"
+msgstr ""
+
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
@@ -22927,7 +23080,7 @@ msgstr ""
msgid "OnCallSchedules|Collapse schedule"
msgstr ""
-msgid "OnCallSchedules|Create on-call schedules in GitLab"
+msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Currently no rotation."
@@ -23222,7 +23375,7 @@ msgstr ""
msgid "Open Selection"
msgstr ""
-msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimise any manual steps.The token is already included in the command."
+msgid "Open a CLI and connect to the cluster you want to install the Agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open comment type dropdown"
@@ -23414,6 +23567,9 @@ msgstr ""
msgid "Package recipe already exists"
msgstr ""
+msgid "Package type"
+msgstr ""
+
msgid "Package type must be Conan"
msgstr ""
@@ -24551,6 +24707,51 @@ msgstr ""
msgid "Pipeline|Skipped"
msgstr ""
+msgid "Pipeline|Source"
+msgstr ""
+
+msgid "Pipeline|Source|API"
+msgstr ""
+
+msgid "Pipeline|Source|Chat"
+msgstr ""
+
+msgid "Pipeline|Source|External"
+msgstr ""
+
+msgid "Pipeline|Source|External Pull Request"
+msgstr ""
+
+msgid "Pipeline|Source|Merge Request"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Scan"
+msgstr ""
+
+msgid "Pipeline|Source|On-Demand DAST Validation"
+msgstr ""
+
+msgid "Pipeline|Source|Parent Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Source|Push"
+msgstr ""
+
+msgid "Pipeline|Source|Schedule"
+msgstr ""
+
+msgid "Pipeline|Source|Trigger"
+msgstr ""
+
+msgid "Pipeline|Source|Web"
+msgstr ""
+
+msgid "Pipeline|Source|Web IDE"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr ""
@@ -24992,13 +25193,10 @@ msgstr ""
msgid "Prev"
msgstr ""
-msgid "Prevent MR approvals by author."
-msgstr ""
-
-msgid "Prevent MR approvals from users who make commits to the MR."
+msgid "Prevent adding new members to project membership within this group"
msgstr ""
-msgid "Prevent adding new members to project membership within this group"
+msgid "Prevent editing approval rules in projects and merge requests."
msgstr ""
msgid "Prevent environment from auto-stopping"
@@ -25010,9 +25208,6 @@ msgstr ""
msgid "Prevent users from changing their profile name"
msgstr ""
-msgid "Prevent users from modifying MR approval rules in projects and merge requests."
-msgstr ""
-
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
@@ -25277,6 +25472,9 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
+msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
+msgstr ""
+
msgid "Profiles|Enter how your name is pronounced to help people address you correctly"
msgstr ""
@@ -25469,9 +25667,6 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
-msgid "Profiles|We recommend you ensure two-factor authentication is enabled and the settings are up to date."
-msgstr ""
-
msgid "Profiles|What's your status?"
msgstr ""
@@ -26570,9 +26765,6 @@ msgstr ""
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
-msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab."
-msgstr ""
-
msgid "Promotions|Better Protected Branches"
msgstr ""
@@ -26624,6 +26816,9 @@ msgstr ""
msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition."
msgstr ""
+msgid "Promotions|Keep track of events in your project"
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
@@ -26663,9 +26858,6 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
-msgid "Promotions|Track your project with Audit Events."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27167,6 +27359,12 @@ msgstr ""
msgid "Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project."
msgstr ""
+msgid "Ready to merge by members who can write to the target branch."
+msgstr ""
+
+msgid "Ready to merge!"
+msgstr ""
+
msgid "Reauthenticating with SAML provider."
msgstr ""
@@ -27236,6 +27434,9 @@ msgstr ""
msgid "Redis"
msgstr ""
+msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
+msgstr ""
+
msgid "Reduce project visibility"
msgstr ""
@@ -27348,6 +27549,9 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
+msgid "Related to #%{issue_id}."
+msgstr ""
+
msgid "Relates to"
msgstr ""
@@ -27857,6 +28061,9 @@ msgstr ""
msgid "Reports|Test summary results are being parsed"
msgstr ""
+msgid "Reports|Tool"
+msgstr ""
+
msgid "Reports|Vulnerability"
msgstr ""
@@ -28301,6 +28508,9 @@ msgstr ""
msgid "Review App|View latest app"
msgstr ""
+msgid "Review changes"
+msgstr ""
+
msgid "Review requested from %{name}"
msgstr ""
@@ -28569,6 +28779,9 @@ msgstr ""
msgid "Runners|Runners"
msgstr ""
+msgid "Runners|Runners in this group: %{groupRunnersCount}"
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -28632,6 +28845,9 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
msgstr ""
+msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
+msgstr ""
+
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
@@ -29087,9 +29303,6 @@ msgstr[0] ""
msgid "Searching by both author and message is currently not supported."
msgstr ""
-msgid "SeatUsage|Seat usage"
-msgstr ""
-
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -29141,7 +29354,7 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
msgid "SecurityApprovals|A merge request approval is required when test coverage declines."
@@ -29177,7 +29390,7 @@ msgstr ""
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityApprovals|Requires approval for vulnerabilities. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "SecurityApprovals|Test coverage must be enabled. %{linkStart}Learn more%{linkEnd}."
@@ -29291,55 +29504,124 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration|%{branches} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
+msgstr ""
+
+msgid "SecurityOrchestration|Action"
+msgstr ""
+
+msgid "SecurityOrchestration|All policies"
+msgstr ""
+
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
+msgid "SecurityOrchestration|Description"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy"
+msgstr ""
+
+msgid "SecurityOrchestration|Edit policy project"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgstr ""
+
+msgid "SecurityOrchestration|Enforcement Status"
+msgstr ""
+
+msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgstr ""
+
+msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
+msgstr ""
+
+msgid "SecurityOrchestration|Latest scan"
+msgstr ""
+
+msgid "SecurityOrchestration|Network"
+msgstr ""
+
+msgid "SecurityOrchestration|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
+msgstr ""
+
+msgid "SecurityOrchestration|New policy"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
-msgid "SecurityOrchestration|Security policy project was linked successfully"
+msgid "SecurityOrchestration|Policies"
msgstr ""
-msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Policy description"
msgstr ""
-msgid "SecurityOrchestration|Select security project"
+msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityPolicies|+%{count} more"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityPolicies|All policies"
+msgid "SecurityOrchestration|Policy type"
msgstr ""
-msgid "SecurityPolicies|Description"
+msgid "SecurityOrchestration|Rule"
msgstr ""
-msgid "SecurityPolicies|Edit policy"
+msgid "SecurityOrchestration|Scan Execution"
msgstr ""
-msgid "SecurityPolicies|Enforcement status"
+msgid "SecurityOrchestration|Scan execution"
msgstr ""
-msgid "SecurityPolicies|Environment(s)"
+msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}"
+msgstr ""
+
+msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
+msgstr ""
+
+msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
-msgid "SecurityPolicies|Latest scan"
+msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityPolicies|Network"
+msgid "SecurityOrchestration|Select security project"
msgstr ""
-msgid "SecurityPolicies|Policies"
+msgid "SecurityOrchestration|Sorry, your filter produced no results."
msgstr ""
-msgid "SecurityPolicies|Policy type"
+msgid "SecurityOrchestration|There was a problem creating the new security policy"
msgstr ""
-msgid "SecurityPolicies|Scan execution"
+msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
-msgid "SecurityPolicies|view results"
+msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
+msgstr ""
+
+msgid "SecurityOrchestration|Update scan execution policies"
+msgstr ""
+
+msgid "SecurityOrchestration|view results"
+msgstr ""
+
+msgid "SecurityOrhestration|No rules defined - policy will not run."
+msgstr ""
+
+msgid "SecurityPolicies|+%{count} more"
+msgstr ""
+
+msgid "SecurityPolicies|Environment(s)"
+msgstr ""
+
+msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -29378,9 +29660,6 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
-msgid "SecurityReports|Coverage fuzzing"
-msgstr ""
-
msgid "SecurityReports|Create Jira issue"
msgstr ""
@@ -29492,9 +29771,6 @@ msgstr ""
msgid "SecurityReports|Scan details"
msgstr ""
-msgid "SecurityReports|Scanner"
-msgstr ""
-
msgid "SecurityReports|Security Dashboard"
msgstr ""
@@ -29561,6 +29837,9 @@ msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
+msgid "SecurityReports|Tool"
+msgstr ""
+
msgid "SecurityReports|Unable to add %{invalidProjectsMessage}: %{errorMessage}"
msgstr ""
@@ -30134,7 +30413,7 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
-msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes."
+msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
msgid "Set time estimate"
@@ -30182,7 +30461,7 @@ msgstr ""
msgid "Set weight to %{weight}."
msgstr ""
-msgid "Set what should be replicated by this secondary node."
+msgid "Set what should be replicated by this secondary site."
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
@@ -30383,9 +30662,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show links anyways"
-msgstr ""
-
msgid "Show list"
msgstr ""
@@ -30607,6 +30883,9 @@ msgstr ""
msgid "Size"
msgstr ""
+msgid "Size Limits"
+msgstr ""
+
msgid "Size limit per repository (MB)"
msgstr ""
@@ -30958,6 +31237,15 @@ msgstr ""
msgid "SortOptions|Blocking"
msgstr ""
+msgid "SortOptions|Closed date"
+msgstr ""
+
+msgid "SortOptions|Closed earlier"
+msgstr ""
+
+msgid "SortOptions|Closed recently"
+msgstr ""
+
msgid "SortOptions|Created date"
msgstr ""
@@ -32427,6 +32715,9 @@ msgstr ""
msgid "Terraform|Cancel"
msgstr ""
+msgid "Terraform|Copy Terraform init command"
+msgstr ""
+
msgid "Terraform|Details"
msgstr ""
@@ -32478,12 +32769,18 @@ msgstr ""
msgid "Terraform|States"
msgstr ""
+msgid "Terraform|Terraform init command"
+msgstr ""
+
msgid "Terraform|The report %{name} failed to generate."
msgstr ""
msgid "Terraform|The report %{name} was generated in your pipelines."
msgstr ""
+msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
+msgstr ""
+
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
msgstr ""
@@ -32496,7 +32793,7 @@ msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
-msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
+msgid "Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone."
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
@@ -32718,7 +33015,7 @@ msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}More information%{linkEnd}"
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
@@ -32935,6 +33232,9 @@ msgstr ""
msgid "The latest pipeline for this merge request did not complete successfully."
msgstr ""
+msgid "The latest pipeline for this merge request has failed."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -32971,9 +33271,6 @@ msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr ""
-msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}."
-msgstr ""
-
msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
msgstr ""
@@ -33127,6 +33424,9 @@ msgstr ""
msgid "The tag name can't be changed for an existing release."
msgstr ""
+msgid "The time period in seconds that the maximum requests per project limit applies to."
+msgstr ""
+
msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
msgstr ""
@@ -33265,9 +33565,15 @@ msgstr ""
msgid "There are running deployments on the environment. Please retry later."
msgstr ""
+msgid "There are several file size limits in place for the Package Registry."
+msgstr ""
+
msgid "There are several rate limits in place to protect the system."
msgstr ""
+msgid "There are several size limits in place."
+msgstr ""
+
msgid "There is a halted Elasticsearch migration"
msgstr ""
@@ -33313,6 +33619,9 @@ msgstr ""
msgid "There was a problem fetching labels."
msgstr ""
+msgid "There was a problem fetching linked pipelines."
+msgstr ""
+
msgid "There was a problem fetching milestones."
msgstr ""
@@ -33493,9 +33802,6 @@ msgstr ""
msgid "There was an error while fetching the table data. Please refresh the page to try again."
msgstr ""
-msgid "There was an error while fetching value stream analytics %{requestTypeName} data."
-msgstr ""
-
msgid "There was an error while fetching value stream analytics data."
msgstr ""
@@ -33715,9 +34021,6 @@ msgstr ""
msgid "This field is required."
msgstr ""
-msgid "This graph has a large number of jobs and showing the links between them may have performance implications."
-msgstr ""
-
msgid "This group"
msgstr ""
@@ -33790,6 +34093,9 @@ msgstr ""
msgid "This issue is currently blocked by the following issues:"
msgstr ""
+msgid "This issue is hidden because its author has been banned"
+msgstr ""
+
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -34833,13 +35139,19 @@ msgstr ""
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
msgstr ""
+msgid "TransferProject|Project is already in this namespace."
+msgstr ""
+
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
-msgid "TransferProject|Transfer failed, please contact an admin."
+msgid "TransferProject|You don't have permission to transfer projects into that namespace."
+msgstr ""
+
+msgid "TransferProject|You don't have permission to transfer this project."
msgstr ""
msgid "Tree view"
@@ -35401,6 +35713,9 @@ msgstr ""
msgid "Until"
msgstr ""
+msgid "Until revoked, expired personal access tokens pose a security risk."
+msgstr ""
+
msgid "Unused"
msgstr ""
@@ -35620,9 +35935,6 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
msgstr ""
-msgid "UsageQuota|Other Storage"
-msgstr ""
-
msgid "UsageQuota|Packages"
msgstr ""
@@ -35641,9 +35953,15 @@ msgstr ""
msgid "UsageQuota|Repository"
msgstr ""
+msgid "UsageQuota|Seats"
+msgstr ""
+
msgid "UsageQuota|Snippets"
msgstr ""
+msgid "UsageQuota|Something went wrong while fetching project storage statistics"
+msgstr ""
+
msgid "UsageQuota|Storage"
msgstr ""
@@ -35692,6 +36010,9 @@ msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
msgstr ""
+msgid "UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project"
+msgstr ""
+
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
@@ -35848,6 +36169,9 @@ msgstr ""
msgid "Use one line per URI"
msgstr ""
+msgid "Use primary email (%{email})"
+msgstr ""
+
msgid "Use shortcuts"
msgstr ""
@@ -36325,9 +36649,15 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue first merge request created to issue closed."
msgstr ""
+msgid "ValueStreamAnalytics|Number of commits pushed to the default branch"
+msgstr ""
+
msgid "ValueStreamAnalytics|Number of new issues created."
msgstr ""
+msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
+msgstr ""
+
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
@@ -36522,6 +36852,10 @@ msgstr ""
msgid "View project labels"
msgstr ""
+msgid "View public GPG key"
+msgid_plural "View public GPG keys"
+msgstr[0] ""
+
msgid "View replaced file @ "
msgstr ""
@@ -36780,9 +37114,6 @@ msgstr ""
msgid "Vulnerability|Request/Response"
msgstr ""
-msgid "Vulnerability|Scanner"
-msgstr ""
-
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -36795,6 +37126,9 @@ msgstr ""
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
msgstr ""
+msgid "Vulnerability|Tool"
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -36900,6 +37234,9 @@ msgstr ""
msgid "We'll continuously validate your pipeline configuration. The validation results will appear here."
msgstr ""
+msgid "We'll use this to help surface the right features and information to you."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -37155,6 +37492,9 @@ msgstr ""
msgid "What is your job title? (optional)"
msgstr ""
+msgid "What will you use this group for?"
+msgstr ""
+
msgid "What's new"
msgstr ""
@@ -37213,6 +37553,9 @@ msgstr ""
msgid "Who will be using this GitLab trial?"
msgstr ""
+msgid "Who will be using this group?"
+msgstr ""
+
msgid "Why are you signing up? (Optional)"
msgstr ""
@@ -37771,6 +38114,9 @@ msgstr ""
msgid "You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}"
msgstr ""
+msgid "You cannot %{action} %{state} users."
+msgstr ""
+
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
@@ -37786,6 +38132,9 @@ msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr ""
+msgid "You cannot rename an environment after it's created."
+msgstr ""
+
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
msgstr ""
@@ -37930,7 +38279,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by mail."
+msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -38356,7 +38705,7 @@ msgstr ""
msgid "Your requirements are being imported. Once finished, you'll receive a confirmation email."
msgstr ""
-msgid "Your requirements will be imported in the background. Once it's finished, you'll get a confirmation email. "
+msgid "Your requirements will be imported in the background. After it's finished, you'll get a confirmation email."
msgstr ""
msgid "Your response has been recorded."
@@ -38386,6 +38735,30 @@ msgstr ""
msgid "Your username is %{username}."
msgstr ""
+msgid "ZentaoIntegration|Base URL of the Zentao instance."
+msgstr ""
+
+msgid "ZentaoIntegration|Enter API token"
+msgstr ""
+
+msgid "ZentaoIntegration|If different from Web URL."
+msgstr ""
+
+msgid "ZentaoIntegration|Use Zentao as this project's issue tracker."
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API URL (optional)"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao API token"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Product ID"
+msgstr ""
+
+msgid "ZentaoIntegration|Zentao Web URL"
+msgstr ""
+
msgid "Zoom meeting added"
msgstr ""
@@ -38489,6 +38862,10 @@ msgstr ""
msgid "blocks"
msgstr ""
+msgid "branch"
+msgid_plural "branches"
+msgstr[0] ""
+
msgid "branch name"
msgstr ""
@@ -38612,10 +38989,10 @@ msgstr ""
msgid "ciReport|All projects"
msgstr ""
-msgid "ciReport|All scanners"
+msgid "ciReport|All severities"
msgstr ""
-msgid "ciReport|All severities"
+msgid "ciReport|All tools"
msgstr ""
msgid "ciReport|Automatically apply the patch in a new branch"
@@ -38964,6 +39341,9 @@ msgstr ""
msgid "entries cannot contain HTML tags"
msgstr ""
+msgid "environment_id parameter is required when type is container_policy"
+msgstr ""
+
msgid "epic"
msgstr ""
@@ -39144,9 +39524,6 @@ msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
-msgid "is not an email you own"
-msgstr ""
-
msgid "is not from an allowed domain."
msgstr ""
@@ -39361,8 +39738,9 @@ msgstr ""
msgid "mrWidget|Closed by"
msgstr ""
-msgid "mrWidget|Closes"
-msgstr ""
+msgid "mrWidget|Closes issue"
+msgid_plural "mrWidget|Closes issues"
+msgstr[0] ""
msgid "mrWidget|Delete source branch"
msgstr ""
@@ -39397,8 +39775,9 @@ msgstr ""
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
-msgid "mrWidget|Mentions"
-msgstr ""
+msgid "mrWidget|Mentions issue"
+msgid_plural "mrWidget|Mentions issues"
+msgstr[0] ""
msgid "mrWidget|Merge"
msgstr ""
@@ -39445,6 +39824,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
+msgid "mrWidget|Open in Gitpod"
+msgstr ""
+
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -39508,9 +39890,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -39550,9 +39929,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
-msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr ""
-
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""
@@ -39580,12 +39956,18 @@ msgstr ""
msgid "must be after start"
msgstr ""
+msgid "must be an email you have verified"
+msgstr ""
+
msgid "must be greater than start date"
msgstr ""
msgid "must be inside the fork network"
msgstr ""
+msgid "must be less than the limit of %{tag_limit} tags"
+msgstr ""
+
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/package.json b/package.json
index 6db536c2372..28ed6bf9393 100644
--- a/package.json
+++ b/package.json
@@ -13,12 +13,10 @@
"prejest": "yarn check-dependencies",
"jest": "jest --config jest.config.js",
"jest-debug": "node --inspect-brk node_modules/.bin/jest --runInBand",
+ "jest:ci": "jest --config jest.config.js --ci --coverage --testSequencer ./scripts/frontend/parallel_ci_sequencer.js",
+ "jest:ci:minimal": "jest --config jest.config.js --ci --coverage --findRelatedTests $(cat tmp/changed_files.txt) --passWithNoTests --testSequencer ./scripts/frontend/parallel_ci_sequencer.js",
"jest:integration": "jest --config jest.config.integration.js",
"jsdoc": "jsdoc -c config/jsdocs.config.js",
- "prekarma": "yarn check-dependencies",
- "karma": "BABEL_ENV=${BABEL_ENV:=karma} karma start --single-run true config/karma.config.js",
- "karma-coverage": "BABEL_ENV=coverage karma start --single-run true config/karma.config.js",
- "karma-start": "BABEL_ENV=karma karma start config/karma.config.js",
"lint:eslint": "yarn run internal:eslint",
"lint:eslint:fix": "yarn run internal:eslint --fix",
"lint:eslint:all": "yarn run internal:eslint .",
@@ -57,44 +55,44 @@
"@babel/preset-env": "^7.10.1",
"@gitlab/at.js": "1.5.7",
"@gitlab/favicon-overlay": "2.0.0",
- "@gitlab/svgs": "1.211.0",
+ "@gitlab/svgs": "1.212.0",
"@gitlab/tributejs": "1.0.0",
- "@gitlab/ui": "32.2.1",
+ "@gitlab/ui": "32.11.0",
"@gitlab/visual-review-tools": "1.6.1",
"@rails/actioncable": "6.1.3-2",
"@rails/ujs": "6.1.3-2",
- "@sentry/browser": "5.26.0",
- "@sourcegraph/code-host-integration": "0.0.59",
- "@tiptap/core": "^2.0.0-beta.86",
- "@tiptap/extension-blockquote": "^2.0.0-beta.14",
- "@tiptap/extension-bold": "^2.0.0-beta.14",
- "@tiptap/extension-bullet-list": "^2.0.0-beta.14",
- "@tiptap/extension-code": "^2.0.0-beta.14",
- "@tiptap/extension-code-block-lowlight": "2.0.0-beta.32",
- "@tiptap/extension-document": "^2.0.0-beta.12",
- "@tiptap/extension-dropcursor": "^2.0.0-beta.17",
- "@tiptap/extension-gapcursor": "^2.0.0-beta.18",
- "@tiptap/extension-hard-break": "^2.0.0-beta.14",
- "@tiptap/extension-heading": "^2.0.0-beta.14",
- "@tiptap/extension-history": "^2.0.0-beta.14",
- "@tiptap/extension-horizontal-rule": "^2.0.0-beta.17",
- "@tiptap/extension-image": "^2.0.0-beta.14",
- "@tiptap/extension-italic": "^2.0.0-beta.14",
- "@tiptap/extension-link": "^2.0.0-beta.18",
- "@tiptap/extension-list-item": "^2.0.0-beta.13",
- "@tiptap/extension-ordered-list": "^2.0.0-beta.14",
- "@tiptap/extension-paragraph": "^2.0.0-beta.15",
- "@tiptap/extension-strike": "^2.0.0-beta.16",
+ "@sentry/browser": "5.30.0",
+ "@sourcegraph/code-host-integration": "0.0.60",
+ "@tiptap/core": "^2.0.0-beta.105",
+ "@tiptap/extension-blockquote": "^2.0.0-beta.15",
+ "@tiptap/extension-bold": "^2.0.0-beta.15",
+ "@tiptap/extension-bullet-list": "^2.0.0-beta.15",
+ "@tiptap/extension-code": "^2.0.0-beta.16",
+ "@tiptap/extension-code-block-lowlight": "2.0.0-beta.37",
+ "@tiptap/extension-document": "^2.0.0-beta.13",
+ "@tiptap/extension-dropcursor": "^2.0.0-beta.19",
+ "@tiptap/extension-gapcursor": "^2.0.0-beta.19",
+ "@tiptap/extension-hard-break": "^2.0.0-beta.16",
+ "@tiptap/extension-heading": "^2.0.0-beta.15",
+ "@tiptap/extension-history": "^2.0.0-beta.16",
+ "@tiptap/extension-horizontal-rule": "^2.0.0-beta.19",
+ "@tiptap/extension-image": "^2.0.0-beta.15",
+ "@tiptap/extension-italic": "^2.0.0-beta.15",
+ "@tiptap/extension-link": "^2.0.0-beta.20",
+ "@tiptap/extension-list-item": "^2.0.0-beta.14",
+ "@tiptap/extension-ordered-list": "^2.0.0-beta.16",
+ "@tiptap/extension-paragraph": "^2.0.0-beta.17",
+ "@tiptap/extension-strike": "^2.0.0-beta.17",
"@tiptap/extension-subscript": "^2.0.0-beta.4",
"@tiptap/extension-superscript": "^2.0.0-beta.4",
- "@tiptap/extension-table": "^2.0.0-beta.25",
- "@tiptap/extension-table-cell": "^2.0.0-beta.13",
- "@tiptap/extension-table-header": "^2.0.0-beta.15",
- "@tiptap/extension-table-row": "^2.0.0-beta.13",
- "@tiptap/extension-task-item": "^2.0.0-beta.17",
+ "@tiptap/extension-table": "^2.0.0-beta.30",
+ "@tiptap/extension-table-cell": "^2.0.0-beta.15",
+ "@tiptap/extension-table-header": "^2.0.0-beta.17",
+ "@tiptap/extension-table-row": "^2.0.0-beta.14",
+ "@tiptap/extension-task-item": "^2.0.0-beta.18",
"@tiptap/extension-task-list": "^2.0.0-beta.17",
- "@tiptap/extension-text": "^2.0.0-beta.12",
- "@tiptap/vue-2": "^2.0.0-beta.39",
+ "@tiptap/extension-text": "^2.0.0-beta.13",
+ "@tiptap/vue-2": "^2.0.0-beta.50",
"@toast-ui/editor": "^2.5.2",
"@toast-ui/vue-editor": "^2.5.2",
"apollo-cache-inmemory": "^1.6.6",
@@ -115,7 +113,7 @@
"codesandbox-api": "0.0.23",
"compression-webpack-plugin": "^5.0.2",
"copy-webpack-plugin": "^6.4.1",
- "core-js": "^3.16.2",
+ "core-js": "^3.17.3",
"cron-validator": "^1.1.1",
"cropper": "^2.3.0",
"css-loader": "^2.1.1",
@@ -125,7 +123,7 @@
"dateformat": "^4.5.1",
"deckar01-task_list": "^2.3.1",
"diff": "^3.4.0",
- "dompurify": "^2.3.1",
+ "dompurify": "^2.3.2",
"dropzone": "^4.2.0",
"editorconfig": "^0.15.3",
"emoji-regex": "^7.0.3",
@@ -140,7 +138,6 @@
"jed": "^1.1.1",
"jquery": "^3.6.0",
"jquery.caret": "^0.3.1",
- "jquery.waitforimages": "^2.2.0",
"js-cookie": "^2.2.1",
"js-yaml": "^3.13.1",
"jszip": "^3.1.3",
@@ -150,7 +147,7 @@
"lowlight": "^1.20.0",
"marked": "^0.3.12",
"mathjax": "3",
- "mermaid": "^8.10.2",
+ "mermaid": "^8.11.5",
"minimatch": "^3.0.4",
"monaco-editor": "^0.25.2",
"monaco-editor-webpack-plugin": "^4.0.0",
@@ -163,9 +160,10 @@
"portal-vue": "^2.1.7",
"prismjs": "^1.21.0",
"prosemirror-inputrules": "^1.1.3",
- "prosemirror-markdown": "^1.5.1",
- "prosemirror-model": "^1.13.3",
+ "prosemirror-markdown": "^1.5.2",
+ "prosemirror-model": "^1.14.3",
"prosemirror-state": "^1.3.4",
+ "prosemirror-tables": "^1.1.1",
"raphael": "^2.2.7",
"raw-loader": "^4.0.2",
"scrollparent": "^2.0.1",
@@ -180,8 +178,8 @@
"three-orbit-controls": "^82.1.0",
"three-stl-loader": "^1.0.4",
"timeago.js": "^4.0.2",
- "tiptap": "^1.32.1",
- "tiptap-extensions": "^1.35.1",
+ "tiptap": "^1.32.2",
+ "tiptap-extensions": "^1.35.2",
"url-loader": "^4.1.1",
"uuid": "8.1.0",
"visibilityjs": "^1.2.4",
@@ -205,7 +203,7 @@
},
"devDependencies": {
"@babel/plugin-transform-modules-commonjs": "^7.10.1",
- "@gitlab/eslint-plugin": "9.0.2",
+ "@gitlab/eslint-plugin": "9.3.0",
"@gitlab/stylelint-config": "2.3.0",
"@testing-library/dom": "^7.16.2",
"@vue/test-utils": "1.2.0",
@@ -219,10 +217,9 @@
"commander": "^2.20.3",
"custom-jquery-matchers": "^2.1.0",
"docdash": "^1.0.2",
- "eslint": "7.31.0",
+ "eslint": "7.32.0",
"eslint-import-resolver-jest": "3.0.0",
"eslint-import-resolver-webpack": "0.13.1",
- "eslint-plugin-jasmine": "4.1.2",
"eslint-plugin-no-jquery": "2.6.0",
"gettext-extractor": "^3.5.3",
"gettext-extractor-vue": "^5.0.0",
@@ -230,9 +227,6 @@
"istanbul-lib-coverage": "^3.0.0",
"istanbul-lib-report": "^3.0.0",
"istanbul-reports": "^3.0.0",
- "jasmine-core": "^2.9.0",
- "jasmine-diff": "^0.1.3",
- "jasmine-jquery": "^2.1.1",
"jest": "^26.5.2",
"jest-canvas-mock": "^2.1.2",
"jest-environment-jsdom": "^26.5.2",
@@ -242,14 +236,6 @@
"jest-util": "^26.5.2",
"jsdoc": "^3.5.5",
"jsdoc-vue": "^1.0.0",
- "karma": "^4.2.0",
- "karma-chrome-launcher": "^3.0.0",
- "karma-coverage-istanbul-reporter": "^2.1.0",
- "karma-jasmine": "^1.1.2",
- "karma-junit-reporter": "^1.2.0",
- "karma-mocha-reporter": "^2.2.5",
- "karma-sourcemap-loader": "^0.3.7",
- "karma-webpack": "^4.0.2",
"markdownlint-cli": "0.26.0",
"md5": "^2.2.1",
"miragejs": "^0.1.40",
@@ -258,6 +244,7 @@
"postcss": "^7.0.14",
"prettier": "2.2.1",
"prosemirror-schema-basic": "^1.1.2",
+ "prosemirror-schema-list": "^1.1.5",
"prosemirror-test-builder": "^1.0.4",
"purgecss": "^4.0.3",
"purgecss-from-html": "^4.0.3",
@@ -277,7 +264,7 @@
"chokidar": "^3.4.0"
},
"engines": {
- "node": ">=10.13.0",
+ "node": ">=12.22.1",
"yarn": "^1.10.0"
}
}
diff --git a/qa/Dockerfile b/qa/Dockerfile
index ad4bffb3bf2..13213c7c8c8 100644
--- a/qa/Dockerfile
+++ b/qa/Dockerfile
@@ -76,6 +76,7 @@ COPY ./config/initializers/0_inject_enterprise_edition_module.rb /home/gitlab/co
# Copy VERSION to ensure the COPY succeeds to copy at least one file since ee/app/models/license.rb isn't present in FOSS
# The [b] part makes ./ee/app/models/license.r[b] a pattern that is allowed to return no files (which is the case in FOSS)
COPY VERSION ./ee/app/models/license.r[b] /home/gitlab/ee/app/models/
+COPY ./config/bundler_setup.rb /home/gitlab/config/
COPY ./lib/gitlab.rb /home/gitlab/lib/
COPY ./lib/gitlab/utils.rb /home/gitlab/lib/gitlab/
COPY ./INSTALLATION_TYPE ./VERSION /home/gitlab/
diff --git a/qa/Gemfile b/qa/Gemfile
index 3ba1244d17e..cc2355cdfa3 100644
--- a/qa/Gemfile
+++ b/qa/Gemfile
@@ -2,20 +2,19 @@
source 'https://rubygems.org'
-gem 'gitlab-qa'
+gem 'gitlab-qa', require: 'gitlab/qa'
gem 'activesupport', '~> 6.1.3.2' # This should stay in sync with the root's Gemfile
-gem 'allure-rspec', '~> 2.14.1'
+gem 'allure-rspec', '~> 2.14.5'
gem 'capybara', '~> 3.35.0'
gem 'capybara-screenshot', '~> 1.0.23'
gem 'rake', '~> 12.3.3'
gem 'rspec', '~> 3.10'
gem 'selenium-webdriver', '~> 4.0.0.beta4'
-gem 'airborne', '~> 0.3.4'
+gem 'airborne', '~> 0.3.4', require: false # airborne is messing with rspec sandboxed mode so not requiring by default
gem 'rest-client', '~> 2.1.0'
-gem 'nokogiri', '~> 1.11.7'
-gem 'rspec-retry', '~> 0.6.1'
+gem 'rspec-retry', '~> 0.6.1', require: 'rspec/retry'
gem 'rspec_junit_formatter', '~> 0.4.1'
-gem 'faker', '~> 1.6', '>= 1.6.6'
+gem 'faker', '~> 2.19', '>= 2.19.0'
gem 'knapsack', '~> 1.17'
gem 'parallel_tests', '~> 2.29'
gem 'rotp', '~> 3.1.0'
@@ -24,6 +23,8 @@ gem 'parallel', '~> 1.19'
gem 'rspec-parameterized', '~> 0.4.2'
gem 'octokit', '~> 4.21'
gem 'webdrivers', '~> 4.6'
+gem 'zeitwerk', '~> 2.4'
+gem 'influxdb-client', '~> 1.17'
gem 'chemlab', '~> 0.7'
gem 'chemlab-library-www-gitlab-com', '~> 0.1'
diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock
index 66b635868f8..5f33afaa77b 100644
--- a/qa/Gemfile.lock
+++ b/qa/Gemfile.lock
@@ -19,10 +19,10 @@ GEM
rack-test (>= 1.1.0, < 2.0)
rest-client (>= 2.0.2, < 3.0)
rspec (~> 3.8)
- allure-rspec (2.14.2)
- allure-ruby-commons (= 2.14.2)
+ allure-rspec (2.14.5)
+ allure-ruby-commons (= 2.14.5)
rspec-core (>= 3.8, < 4)
- allure-ruby-commons (2.14.2)
+ allure-ruby-commons (2.14.5)
mime-types (>= 3.3, < 4)
oj (>= 3.10, < 4)
require_all (>= 2, < 4)
@@ -62,8 +62,8 @@ GEM
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
equalizer (0.0.11)
- faker (1.9.3)
- i18n (>= 0.7)
+ faker (2.19.0)
+ i18n (>= 1.6, < 2)
faraday (1.5.1)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
@@ -88,6 +88,7 @@ GEM
i18n (1.8.10)
concurrent-ruby (~> 1.0)
ice_nine (0.11.2)
+ influxdb-client (1.17.0)
knapsack (1.17.1)
rake
launchy (2.4.3)
@@ -111,7 +112,7 @@ GEM
octokit (4.21.0)
faraday (>= 0.9)
sawyer (~> 0.8.0, >= 0.5.3)
- oj (3.12.1)
+ oj (3.13.2)
parallel (1.19.2)
parallel_tests (2.29.0)
parallel
@@ -212,16 +213,16 @@ PLATFORMS
DEPENDENCIES
activesupport (~> 6.1.3.2)
airborne (~> 0.3.4)
- allure-rspec (~> 2.14.1)
+ allure-rspec (~> 2.14.5)
capybara (~> 3.35.0)
capybara-screenshot (~> 1.0.23)
chemlab (~> 0.7)
chemlab-library-www-gitlab-com (~> 0.1)
deprecation_toolkit (~> 1.5.1)
- faker (~> 1.6, >= 1.6.6)
+ faker (~> 2.19, >= 2.19.0)
gitlab-qa
+ influxdb-client (~> 1.17)
knapsack (~> 1.17)
- nokogiri (~> 1.11.7)
octokit (~> 4.21)
parallel (~> 1.19)
parallel_tests (~> 2.29)
@@ -237,6 +238,7 @@ DEPENDENCIES
selenium-webdriver (~> 4.0.0.beta4)
timecop (~> 0.9.1)
webdrivers (~> 4.6)
+ zeitwerk (~> 2.4)
BUNDLED WITH
2.2.22
diff --git a/qa/README.md b/qa/README.md
index dc4a64fb8a9..c380a5b6770 100644
--- a/qa/README.md
+++ b/qa/README.md
@@ -124,7 +124,7 @@ GITLAB_USERNAME=jsmith GITLAB_PASSWORD=password bundle exec bin/qa Test::Instanc
```
Some QA tests require logging in as an admin user. By default, the QA
-tests will use the the same `root` user seeded by the GDK.
+tests will use the same `root` user seeded by the GDK.
If you need to authenticate with different admin credentials, you can
provide the `GITLAB_ADMIN_USERNAME` and `GITLAB_ADMIN_PASSWORD`
diff --git a/qa/knapsack/master_report.json b/qa/knapsack/master_report.json
index 47c6099a36d..152b17a0577 100644
--- a/qa/knapsack/master_report.json
+++ b/qa/knapsack/master_report.json
@@ -12,37 +12,26 @@
"qa/specs/features/browser_ui/3_create/snippet/create_snippet_spec.rb": 5.812374591827393,
"qa/specs/features/browser_ui/3_create/wiki/create_edit_clone_push_wiki_spec.rb": 17.273863554000854,
"qa/specs/features/browser_ui/4_verify/ci_variable/add_ci_variable_spec.rb": 8.31815505027771,
- "qa/specs/features/browser_ui/non_devops/performance_bar_spec.rb": 8.810423135757446,
"qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb": 51.81568956375122,
"qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb": 30.373554468154907,
"qa/specs/features/sanity/version_spec.rb": 0.0004665851593017578,
"qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb": 22.993898630142212,
- "qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb": 58.383920192718506,
- "qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb": 58.99856781959534,
"qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb": 36.358747243881226,
"qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb": 9.079580068588257,
"qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb": 39.412545919418335,
"qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb": 27.905837297439575,
- "qa/specs/features/browser_ui/6_release/pages/pages_pipeline_spec.rb": 130.09448766708374,
- "qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb": 36.39329433441162,
"qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb": 99.71209812164307,
- "qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb": 34.64759969711304,
"qa/specs/features/ee/browser_ui/2_plan/epic/promote_issue_to_epic_spec.rb": 25.72262978553772,
"qa/specs/features/ee/browser_ui/2_plan/issue_boards/project_issue_boards_spec.rb": 44.536749839782715,
"qa/specs/features/browser_ui/2_plan/milestone/create_group_milestone_spec.rb": 18.482256174087524,
- "qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb": 107.76105904579163,
"qa/specs/features/browser_ui/2_plan/issue/comment_issue_spec.rb": 16.314701795578003,
"qa/specs/features/ee/browser_ui/2_plan/issue_boards/read_only_board_configuration_spec.rb": 36.934654235839844,
"qa/specs/features/ee/browser_ui/2_plan/iterations/create_group_iteration_spec.rb": 17.103047847747803,
- "qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb": 43.9788339138031,
- "qa/specs/features/ee/browser_ui/2_plan/issue_boards/configurable_issue_board_spec.rb": 27.46922779083252,
"qa/specs/features/browser_ui/2_plan/milestone/create_project_milestone_spec.rb": 28.352823495864868,
"qa/specs/features/ee/browser_ui/2_plan/issue_boards/configure_issue_board_by_label_spec.rb": 20.208287954330444,
"qa/specs/features/ee/browser_ui/2_plan/burndown_chart/burndown_chart_spec.rb": 13.733941793441772,
- "qa/specs/features/ee/browser_ui/2_plan/issue_boards/sum_of_issues_weights_spec.rb": 21.879905223846436,
"qa/specs/features/browser_ui/2_plan/issue/collapse_comments_in_discussions_spec.rb": 16.376311540603638,
"qa/specs/features/ee/browser_ui/2_plan/epic/epics_management_spec.rb": 98.71593880653381,
- "qa/specs/features/ee/browser_ui/2_plan/multiple_assignees_for_issues/four_assignees_spec.rb": 39.15917229652405,
"qa/specs/features/browser_ui/2_plan/related_issues/related_issues_spec.rb": 21.307689666748047,
"qa/specs/features/ee/browser_ui/2_plan/multiple_assignees_for_issues/more_than_four_assignees_spec.rb": 39.39231467247009,
"qa/specs/features/ee/browser_ui/2_plan/issue_boards/create_group_issue_board_spec.rb": 18.50350284576416,
@@ -52,7 +41,6 @@
"qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb": 38.93913507461548,
"qa/specs/features/ee/browser_ui/2_plan/epic/roadmap_spec.rb": 12.087258100509644,
"qa/specs/features/ee/browser_ui/2_plan/issue_boards/group_issue_boards_spec.rb": 17.309232473373413,
- "qa/specs/features/browser_ui/2_plan/milestone/assign_milestone_spec.rb": 67.43084001541138,
"qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_dependent_relationship_spec.rb": 70.75156497955322,
"qa/specs/features/browser_ui/2_plan/issue/export_as_csv_spec.rb": 22.20275855064392,
"qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb": 24.21539831161499,
@@ -60,103 +48,66 @@
"qa/specs/features/ee/browser_ui/2_plan/iterations/assign_group_iteration_spec.rb": 31.00749373435974,
"qa/specs/features/ee/browser_ui/2_plan/issue/default_issue_template_spec.rb": 18.430193424224854,
"qa/specs/features/browser_ui/3_create/wiki/project_based_page_deletion_spec.rb": 13.615312337875366,
- "qa/specs/features/ee/browser_ui/1_manage/project/project_templates_spec.rb": 54.21430277824402,
- "qa/specs/features/ee/browser_ui/3_create/repository/merge_with_code_owner_in_subgroup_spec.rb": 189.6901969909668,
"qa/specs/features/browser_ui/1_manage/project/protected_tags_spec.rb": 94.04865074157715,
"qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb": 59.575963258743286,
- "qa/specs/features/api/3_create/merge_request/push_options_labels_spec.rb": 12.545408725738525,
"qa/specs/features/ee/browser_ui/1_manage/group/share_group_with_group_spec.rb": 25.6483793258667,
- "qa/specs/features/browser_ui/4_verify/pipeline/include_multiple_files_from_a_project_spec.rb": 48.9726402759552,
"qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb": 26.07162046432495,
"qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb": 8.41316819190979,
"qa/specs/features/ee/browser_ui/secure/merge_request_license_widget_spec.rb": 73.56247329711914,
- "qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb": 70.19135999679565,
"qa/specs/features/api/3_create/repository/files_spec.rb": 6.235261917114258,
"qa/specs/features/browser_ui/5_package/container_registry_spec.rb": 7.263134717941284,
"qa/specs/features/api/3_create/repository/default_branch_name_setting_spec.rb": 10.079012870788574,
"qa/specs/features/browser_ui/3_create/repository/file/delete_file_via_web_spec.rb": 16.52791404724121,
"qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb": 10.684799909591675,
"qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb": 72.14465713500977,
- "qa/specs/features/api/1_manage/project_access_token_spec.rb": 1.7818918228149414,
- "qa/specs/features/ee/browser_ui/4_verify/pipeline_subscription_with_group_owned_project_spec.rb": 46.62651777267456,
- "qa/specs/features/browser_ui/4_verify/pipeline/trigger_child_pipeline_with_manual_spec.rb": 41.63330125808716,
"qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_with_multiple_files_spec.rb": 15.664107322692871,
"qa/specs/features/browser_ui/3_create/snippet/add_file_to_snippet_spec.rb": 34.32576060295105,
"qa/specs/features/browser_ui/3_create/design_management/archive_design_content_spec.rb": 31.586787939071655,
- "qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb": 27.983626127243042,
"qa/specs/features/ee/browser_ui/secure/project_security_dashboard_spec.rb": 27.6742160320282,
- "qa/specs/features/browser_ui/4_verify/pipeline/trigger_matrix_spec.rb": 33.06922268867493,
- "qa/specs/features/ee/browser_ui/3_create/wiki/create_group_wiki_page_spec.rb": 22.77417540550232,
"qa/specs/features/api/1_manage/rate_limits_spec.rb": 11.836639165878296,
"qa/specs/features/ee/browser_ui/1_manage/user/minimal_access_user_spec.rb": 15.691015005111694,
- "qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_spec.rb": 26.72679090499878,
"qa/specs/features/api/3_create/merge_request/push_options_mwps_spec.rb": 38.80854368209839,
"qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb": 15.07186245918274,
"qa/specs/features/ee/browser_ui/3_create/repository/pull_mirroring_over_http_spec.rb": 41.58929800987244,
- "qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb": 101.82257866859436,
- "qa/specs/features/ee/browser_ui/4_verify/pipelines_for_merged_results_and_merge_trains_spec.rb": 114.47506761550903,
"qa/specs/features/api/3_create/repository/push_postreceive_idempotent_spec.rb": 13.438591957092285,
"qa/specs/features/ee/browser_ui/3_create/merge_request/default_merge_request_template_spec.rb": 30.66688632965088,
"qa/specs/features/browser_ui/1_manage/user/user_access_termination_spec.rb": 25.137597799301147,
- "qa/specs/features/ee/browser_ui/1_manage/group/group_audit_logs_1_spec.rb": 72.90312123298645,
"qa/specs/features/browser_ui/3_create/repository/clone_spec.rb": 8.731743574142456,
"qa/specs/features/browser_ui/7_configure/auto_devops/auto_devops_templates_spec.rb": 0.0008337497711181641,
"qa/specs/features/browser_ui/3_create/merge_request/suggestions/custom_commit_suggestion_spec.rb": 40.60329842567444,
- "qa/specs/features/browser_ui/4_verify/pipeline/locked_artifacts_spec.rb": 48.4540741443634,
"qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb": 39.090237617492676,
"qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb": 22.633376359939575,
"qa/specs/features/browser_ui/3_create/design_management/modify_design_content_spec.rb": 18.457061767578125,
"qa/specs/features/browser_ui/3_create/wiki/project_based_content_creation_spec.rb": 49.273433685302734,
"qa/specs/features/browser_ui/1_manage/group/transfer_group_spec.rb": 14.6923348903656,
- "qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb": 81.94199562072754,
"qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb": 38.44519090652466,
"qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb": 46.04780888557434,
"qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb": 27.77385425567627,
"qa/specs/features/ee/browser_ui/1_manage/insights/default_insights_spec.rb": 28.850987195968628,
"qa/specs/features/browser_ui/3_create/repository/file/edit_file_via_web_spec.rb": 19.598198413848877,
- "qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb": 65.70130896568298,
"qa/specs/features/browser_ui/3_create/repository/file/file_with_unusual_name_spec.rb": 15.17819595336914,
- "qa/specs/features/ee/browser_ui/1_manage/instance/instance_audit_logs_spec.rb": 104.32384181022644,
- "qa/specs/features/ee/browser_ui/3_create/repository/code_owners_with_protected_branch_and_squashed_commits_spec.rb": 50.42676067352295,
"qa/specs/features/api/1_manage/user_access_termination_spec.rb": 6.3396782875061035,
"qa/specs/features/ee/browser_ui/secure/create_merge_request_with_secure_spec.rb": 71.55253982543945,
- "qa/specs/features/browser_ui/4_verify/pipeline/merge_mr_when_pipline_is_blocked_spec.rb": 58.73203682899475,
- "qa/specs/features/ee/browser_ui/4_verify/new_discussion_not_dropping_merge_trains_mr_spec.rb": 65.0450668334961,
"qa/specs/features/browser_ui/4_verify/testing/view_code_coverage_spec.rb": 42.83795666694641,
- "qa/specs/features/ee/browser_ui/3_create/repository/pull_mirroring_over_ssh_with_key_spec.rb": 60.95837211608887,
"qa/specs/features/api/3_create/merge_request/push_options_remove_source_branch_spec.rb": 17.03721809387207,
"qa/specs/features/browser_ui/3_create/wiki/project_based_content_manipulation_spec.rb": 25.14606213569641,
"qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb": 70.44876503944397,
"qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb": 52.93111038208008,
"qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb": 48.3312201499939,
- "qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb": 52.52523970603943,
- "qa/specs/features/ee/browser_ui/secure/security_reports_spec.rb": 49.19262075424194,
- "qa/specs/features/browser_ui/4_verify/ci_variable/pipeline_with_protected_variable_spec.rb": 120.86664414405823,
- "qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_with_multiple_files_spec.rb": 38.46292161941528,
"qa/specs/features/ee/browser_ui/1_manage/group/group_audit_logs_2_spec.rb": 100.1787781715393,
"qa/specs/features/browser_ui/3_create/repository/user_views_commit_diff_patch_spec.rb": 22.37237572669983,
"qa/specs/features/ee/browser_ui/1_manage/group/group_file_template_spec.rb": 69.36870694160461,
- "qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb": 69.17281556129456,
"qa/specs/features/api/3_create/merge_request/push_options_target_branch_spec.rb": 13.524356126785278,
"qa/specs/features/ee/browser_ui/1_manage/group/prevent_forking_outside_group_spec.rb": 37.17233395576477,
"qa/specs/features/api/2_plan/closes_issue_via_pushing_a_commit_spec.rb": 6.892294406890869,
- "qa/specs/features/browser_ui/4_verify/pipeline/pass_dotenv_variables_to_downstream_via_bridge_spec.rb": 40.91694402694702,
"qa/specs/features/browser_ui/2_plan/issue_boards/focus_mode_spec.rb": 12.628767013549805,
"qa/specs/features/ee/browser_ui/secure/enable_sast_from_configuration_spec.rb": 86.38991785049438,
- "qa/specs/features/ee/browser_ui/3_create/repository/push_rules_spec.rb": 79.2712254524231,
- "qa/specs/features/ee/browser_ui/3_create/repository/file_locking_spec.rb": 161.1801998615265,
"qa/specs/features/ee/browser_ui/4_verify/pipeline_for_project_mirror_github_spec.rb": 12.684113502502441,
- "qa/specs/features/browser_ui/3_create/snippet/copy_snippet_file_contents_spec.rb": 31.481987714767456,
- "qa/specs/features/ee/browser_ui/secure/vulnerability_management_spec.rb": 80.21465563774109,
- "qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb": 12.836287260055542,
- "qa/specs/features/browser_ui/1_manage/login/2fa_ssh_recovery_spec.rb": 38.852850675582886,
- "qa/specs/features/ee/browser_ui/3_create/repository/assign_code_owners_spec.rb": 34.88499307632446,
"qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb": 35.340261459350586,
"qa/specs/features/browser_ui/2_plan/issue/custom_issue_template_spec.rb": 19.719850540161133,
"qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_diff_patch_spec.rb": 38.779794216156006,
"qa/specs/features/api/4_verify/cancel_pipeline_when_block_user_spec.rb": 6.86094856262207,
"qa/specs/features/browser_ui/3_create/snippet/delete_file_from_snippet_spec.rb": 51.54451298713684,
- "qa/specs/features/ee/browser_ui/3_create/merge_request/add_batch_comments_in_merge_request_spec.rb": 25.940913677215576,
"qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb": 18.586050033569336,
"qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb": 35.587294578552246,
"qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb": 14.01547122001648,
@@ -164,9 +115,7 @@
"qa/specs/features/browser_ui/3_create/wiki/project_based_directory_management_spec.rb": 15.297787427902222,
"qa/specs/features/browser_ui/3_create/snippet/add_comment_to_snippet_spec.rb": 42.507469177246094,
"qa/specs/features/ee/browser_ui/4_verify/pipeline_status_on_operation_dashboard_spec.rb": 46.77937316894531,
- "qa/specs/features/ee/browser_ui/3_create/repository/merge_with_code_owner_in_root_group_spec.rb": 131.23758912086487,
"qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb": 20.96509575843811,
- "qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_a_merge_spec.rb": 44.40894651412964,
"qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_spec.rb": 12.62861156463623,
"qa/specs/features/browser_ui/3_create/merge_request/revert/reverting_merge_request_spec.rb": 49.85329723358154,
"qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb": 84.63548684120178,
@@ -174,10 +123,8 @@
"qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb": 30.72457480430603,
"qa/specs/features/api/3_create/merge_request/push_options_title_description_spec.rb": 10.70707631111145,
"qa/specs/features/ee/api/1_manage/user/minimal_access_user_spec.rb": 4.82462477684021,
- "qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb": 16.23528742790222,
"qa/specs/features/browser_ui/3_create/snippet/share_snippet_spec.rb": 32.49313712120056,
"qa/specs/features/browser_ui/3_create/wiki/project_based_list_spec.rb": 32.37481236457825,
- "qa/specs/features/browser_ui/3_create/design_management/add_design_content_spec.rb": 15.82662057876587,
"qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb": 16.573434114456177,
"qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb": 43.15674066543579,
"qa/specs/features/ee/browser_ui/secure/license_compliance_spec.rb": 31.000027179718018,
@@ -186,10 +133,77 @@
"qa/specs/features/browser_ui/1_manage/login/register_spec.rb": 145.5431580543518,
"qa/specs/features/browser_ui/3_create/repository/file/create_file_via_web_spec.rb": 19.418848514556885,
"qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb": 18.54582905769348,
- "qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb": 65.43303656578064,
"qa/specs/features/api/5_package/container_registry_spec.rb": 3.93778920173645,
"qa/specs/features/ee/browser_ui/3_create/repository/restrict_push_protected_branch_spec.rb": 148.70570707321167,
"qa/specs/features/ee/browser_ui/6_release/multi-project_pipelines_spec.rb": 52.770936250686646,
"qa/specs/features/ee/browser_ui/3_create/contribution_analytics_spec.rb": 45.81806302070618,
- "qa/specs/features/browser_ui/4_verify/pipeline/include_local_config_file_paths_with_wildcard_spec.rb": 20.386794805526733
+ "qa/specs/features/browser_ui/4_verify/pipeline/include_local_config_file_paths_with_wildcard_spec.rb": 20.386794805526733,
+ "qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb": 21.968912363052368,
+ "qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb": 71.7951602935791,
+ "qa/specs/features/api/1_manage/bulk_import_group_spec.rb": 50.21021842956543,
+ "qa/specs/features/ee/browser_ui/2_plan/issue_boards/configurable_issue_board_spec.rb": 16.42144775390625,
+ "qa/specs/features/ee/browser_ui/3_create/repository/merge_with_code_owner_in_root_group_spec.rb": 173.84056043624878,
+ "qa/specs/features/ee/browser_ui/1_manage/project/project_templates_spec.rb": 86.48439168930054,
+ "qa/specs/features/ee/browser_ui/3_create/repository/pull_mirroring_over_ssh_with_key_spec.rb": 56.275856018066406,
+ "qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb": 87.7243127822876,
+ "qa/specs/features/browser_ui/4_verify/pipeline/include_multiple_files_from_a_project_spec.rb": 98.70601177215576,
+ "qa/specs/features/ee/browser_ui/secure/vulnerability_management_spec.rb": 91.42165040969849,
+ "qa/specs/features/ee/browser_ui/3_create/repository/merge_with_code_owner_in_subgroup_spec.rb": 176.7654173374176,
+ "qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb": 17.273313283920288,
+ "qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb": 15.879833459854126,
+ "qa/specs/features/ee/browser_ui/2_plan/issue_boards/sum_of_issues_weights_spec.rb": 16.24162793159485,
+ "qa/specs/features/browser_ui/1_manage/group/bulk_import_group_spec.rb": 55.61779570579529,
+ "qa/specs/features/ee/browser_ui/2_plan/multiple_assignees_for_issues/four_assignees_spec.rb": 15.482072830200195,
+ "qa/specs/features/browser_ui/4_verify/pipeline/pass_dotenv_variables_to_downstream_via_bridge_spec.rb": 54.22519111633301,
+ "qa/specs/features/ee/browser_ui/3_create/repository/push_rules_spec.rb": 85.68487024307251,
+ "qa/specs/features/ee/browser_ui/3_create/web_ide/web_terminal_spec.rb": 63.027522802352905,
+ "qa/specs/features/ee/browser_ui/3_create/wiki/create_group_wiki_page_spec.rb": 26.17377734184265,
+ "qa/specs/features/browser_ui/3_create/design_management/add_design_content_spec.rb": 16.853343725204468,
+ "qa/specs/features/api/1_manage/project_access_token_spec.rb": 2.8215739727020264,
+ "qa/specs/features/ee/browser_ui/1_manage/instance/instance_audit_logs_spec.rb": 109.0079870223999,
+ "qa/specs/features/browser_ui/6_release/pages/pages_pipeline_spec.rb": 73.78986692428589,
+ "qa/specs/features/browser_ui/4_verify/pipeline/locked_artifacts_spec.rb": 34.84124970436096,
+ "qa/specs/features/api/1_manage/import_github_repo_spec.rb": 11.330891609191895,
+ "qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_with_multiple_files_spec.rb": 36.70389533042908,
+ "qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb": 25.407151699066162,
+ "qa/specs/features/browser_ui/7_configure/kubernetes/kubernetes_integration_spec.rb": 109.88336181640625,
+ "qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb": 24.014917373657227,
+ "qa/specs/features/ee/browser_ui/3_create/repository/code_owners_with_protected_branch_and_squashed_commits_spec.rb": 42.596492767333984,
+ "qa/specs/features/browser_ui/3_create/snippet/snippet_index_page_spec.rb": 60.067442893981934,
+ "qa/specs/features/ee/browser_ui/3_create/repository/file_locking_spec.rb": 185.41551113128662,
+ "qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_spec.rb": 30.03315234184265,
+ "qa/specs/features/browser_ui/2_plan/milestone/assign_milestone_spec.rb": 76.58771228790283,
+ "qa/specs/features/browser_ui/3_create/snippet/copy_snippet_file_contents_spec.rb": 28.64104723930359,
+ "qa/specs/features/browser_ui/4_verify/ci_variable/pipeline_with_protected_variable_spec.rb": 198.37600350379944,
+ "qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb": 35.098846435546875,
+ "qa/specs/features/browser_ui/4_verify/pipeline/trigger_matrix_spec.rb": 51.25122785568237,
+ "qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb": 61.072656869888306,
+ "qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb": 135.90494751930237,
+ "qa/specs/features/ee/browser_ui/4_verify/cancelling_merge_request_in_merge_train_spec.rb": 59.57308530807495,
+ "qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb": 32.462252140045166,
+ "qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb": 53.246745586395264,
+ "qa/specs/features/browser_ui/4_verify/pipeline/mr_event_rule_pipeline_spec.rb": 79.99787259101868,
+ "qa/specs/features/browser_ui/1_manage/login/2fa_ssh_recovery_spec.rb": 57.00465273857117,
+ "qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb": 77.2134940624237,
+ "qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb": 48.472514390945435,
+ "qa/specs/features/api/3_create/merge_request/push_options_labels_spec.rb": 17.153425455093384,
+ "qa/specs/features/ee/browser_ui/1_manage/group/group_audit_logs_1_spec.rb": 96.45902276039124,
+ "qa/specs/features/browser_ui/4_verify/pipeline/merge_mr_when_pipline_is_blocked_spec.rb": 64.81094217300415,
+ "qa/specs/features/browser_ui/non_devops/performance_bar_spec.rb": 27.902702569961548,
+ "qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_branch_switcher_spec.rb": 23.476325750350952,
+ "qa/specs/features/ee/browser_ui/10_protect/policy_list_spec.rb": 14.327334642410278,
+ "qa/specs/features/ee/browser_ui/secure/security_reports_spec.rb": 26.599382877349854,
+ "qa/specs/features/browser_ui/4_verify/pipeline/trigger_child_pipeline_with_manual_spec.rb": 39.33750772476196,
+ "qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb": 50.194467306137085,
+ "qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_a_merge_spec.rb": 59.395915508270264,
+ "qa/specs/features/ee/browser_ui/4_verify/pipelines_for_merged_results_and_merge_trains_spec.rb": 203.04975271224976,
+ "qa/specs/features/ee/browser_ui/3_create/repository/assign_code_owners_spec.rb": 42.03165292739868,
+ "qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb": 18.495836973190308,
+ "qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb": 17.1261248588562,
+ "qa/specs/features/ee/browser_ui/4_verify/pipeline_subscription_with_group_owned_project_spec.rb": 53.17536449432373,
+ "qa/specs/features/ee/browser_ui/3_create/merge_request/add_batch_comments_in_merge_request_spec.rb": 62.42040038108826,
+ "qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb": 90.16095304489136,
+ "qa/specs/features/ee/browser_ui/4_verify/new_discussion_not_dropping_merge_trains_mr_spec.rb": 91.91785287857056,
+ "qa/specs/features/browser_ui/5_package/maven_repository_spec.rb": 687.8482820987701,
+ "qa/specs/features/browser_ui/5_package/npm_registry_spec.rb": 225.33412504196167
}
diff --git a/qa/qa.rb b/qa/qa.rb
index 965cc88e50c..cc83efb90e8 100644
--- a/qa/qa.rb
+++ b/qa/qa.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-$: << File.expand_path(__dir__)
-
Encoding.default_external = 'UTF-8'
require_relative '../lib/gitlab'
@@ -10,683 +8,50 @@ require_relative '../config/initializers/0_inject_enterprise_edition_module'
require_relative 'lib/gitlab'
-require 'chemlab'
+require_relative '../config/bundler_setup'
+Bundler.require(:default)
module QA
- ##
- # Helper classes to represent frequently used sequences of actions
- # (e.g., login)
- #
- module Flow
- autoload :Login, 'qa/flow/login'
- autoload :Project, 'qa/flow/project'
- autoload :Saml, 'qa/flow/saml'
- autoload :User, 'qa/flow/user'
- autoload :MergeRequest, 'qa/flow/merge_request'
- autoload :Pipeline, 'qa/flow/pipeline'
- autoload :SignUp, 'qa/flow/sign_up'
- end
-
- ##
- # GitLab QA runtime classes, mostly singletons.
- #
- module Runtime
- autoload :Release, 'qa/runtime/release'
- autoload :User, 'qa/runtime/user'
- autoload :Namespace, 'qa/runtime/namespace'
- autoload :Scenario, 'qa/runtime/scenario'
- autoload :Browser, 'qa/runtime/browser'
- autoload :Env, 'qa/runtime/env'
- autoload :Address, 'qa/runtime/address'
- autoload :Path, 'qa/runtime/path'
- autoload :Feature, 'qa/runtime/feature'
- autoload :Fixtures, 'qa/runtime/fixtures'
- autoload :Logger, 'qa/runtime/logger'
- autoload :GPG, 'qa/runtime/gpg'
- autoload :MailHog, 'qa/runtime/mail_hog'
- autoload :IPAddress, 'qa/runtime/ip_address'
- autoload :Search, 'qa/runtime/search'
- autoload :ApplicationSettings, 'qa/runtime/application_settings'
- autoload :AllureReport, 'qa/runtime/allure_report'
-
- module API
- autoload :Client, 'qa/runtime/api/client'
- autoload :RepositoryStorageMoves, 'qa/runtime/api/repository_storage_moves'
- autoload :Request, 'qa/runtime/api/request'
- end
-
- module Key
- autoload :Base, 'qa/runtime/key/base'
- autoload :RSA, 'qa/runtime/key/rsa'
- autoload :ECDSA, 'qa/runtime/key/ecdsa'
- autoload :ED25519, 'qa/runtime/key/ed25519'
- end
- end
-
- ##
- # GitLab QA fabrication mechanisms
- #
- module Resource
- autoload :ApiFabricator, 'qa/resource/api_fabricator'
- autoload :Base, 'qa/resource/base'
-
- autoload :GroupBase, 'qa/resource/group_base'
- autoload :Sandbox, 'qa/resource/sandbox'
- autoload :Group, 'qa/resource/group'
- autoload :BulkImportGroup, 'qa/resource/bulk_import_group'
- autoload :Issue, 'qa/resource/issue'
- autoload :ProjectIssueNote, 'qa/resource/project_issue_note'
- autoload :Project, 'qa/resource/project'
- autoload :LabelBase, 'qa/resource/label_base'
- autoload :ProjectLabel, 'qa/resource/project_label'
- autoload :GroupLabel, 'qa/resource/group_label'
- autoload :MergeRequest, 'qa/resource/merge_request'
- autoload :ProjectImportedFromGithub, 'qa/resource/project_imported_from_github'
- autoload :ProjectImportedFromURL, 'qa/resource/project_imported_from_url'
- autoload :MergeRequestFromFork, 'qa/resource/merge_request_from_fork'
- autoload :DeployKey, 'qa/resource/deploy_key'
- autoload :DeployToken, 'qa/resource/deploy_token'
- autoload :ProtectedBranch, 'qa/resource/protected_branch'
- autoload :Pipeline, 'qa/resource/pipeline'
- autoload :CiVariable, 'qa/resource/ci_variable'
- autoload :Runner, 'qa/resource/runner'
- autoload :PersonalAccessToken, 'qa/resource/personal_access_token'
- autoload :PersonalAccessTokenCache, 'qa/resource/personal_access_token_cache'
- autoload :ProjectAccessToken, 'qa/resource/project_access_token'
- autoload :User, 'qa/resource/user'
- autoload :ProjectMilestone, 'qa/resource/project_milestone'
- autoload :GroupMilestone, 'qa/resource/group_milestone'
- autoload :Members, 'qa/resource/members'
- autoload :File, 'qa/resource/file'
- autoload :Fork, 'qa/resource/fork'
- autoload :SSHKey, 'qa/resource/ssh_key'
- autoload :Snippet, 'qa/resource/snippet'
- autoload :Tag, 'qa/resource/tag'
- autoload :ProjectMember, 'qa/resource/project_member'
- autoload :ProjectSnippet, 'qa/resource/project_snippet'
- autoload :UserGPG, 'qa/resource/user_gpg'
- autoload :Visibility, 'qa/resource/visibility'
- autoload :ProjectSnippet, 'qa/resource/project_snippet'
- autoload :Design, 'qa/resource/design'
- autoload :RegistryRepository, 'qa/resource/registry_repository'
- autoload :Package, 'qa/resource/package'
- autoload :PipelineSchedules, 'qa/resource/pipeline_schedules'
- autoload :ImportProject, 'qa/resource/import_project'
-
- module KubernetesCluster
- autoload :Base, 'qa/resource/kubernetes_cluster/base'
- autoload :ProjectCluster, 'qa/resource/kubernetes_cluster/project_cluster'
- end
-
- module Clusters
- autoload :Agent, 'qa/resource/clusters/agent.rb'
- autoload :AgentToken, 'qa/resource/clusters/agent_token.rb'
- end
-
- module Events
- autoload :Base, 'qa/resource/events/base'
- autoload :Project, 'qa/resource/events/project'
- end
-
- module Repository
- autoload :Commit, 'qa/resource/repository/commit'
- autoload :Push, 'qa/resource/repository/push'
- autoload :ProjectPush, 'qa/resource/repository/project_push'
- autoload :WikiPush, 'qa/resource/repository/wiki_push'
- end
-
- module Wiki
- autoload :ProjectPage, 'qa/resource/wiki/project_page'
- autoload :GroupPage, 'qa/resource/wiki/group_page'
- end
- end
-
- ##
- # GitLab QA Scenarios
- #
- module Scenario
- ##
- # Support files
- #
- autoload :Bootable, 'qa/scenario/bootable'
- autoload :Actable, 'qa/scenario/actable'
- autoload :Template, 'qa/scenario/template'
- autoload :SharedAttributes, 'qa/scenario/shared_attributes'
-
- ##
- # Test scenario entrypoints.
- #
- module Test
- autoload :Instance, 'qa/scenario/test/instance'
- module Instance
- autoload :All, 'qa/scenario/test/instance/all'
- autoload :Smoke, 'qa/scenario/test/instance/smoke'
- autoload :Airgapped, 'qa/scenario/test/instance/airgapped'
- end
-
- module Integration
- autoload :Github, 'qa/scenario/test/integration/github'
- autoload :LDAPNoTLS, 'qa/scenario/test/integration/ldap_no_tls'
- autoload :LDAPNoServer, 'qa/scenario/test/integration/ldap_no_server'
- autoload :LDAPTLS, 'qa/scenario/test/integration/ldap_tls'
- autoload :InstanceSAML, 'qa/scenario/test/integration/instance_saml'
- autoload :Kubernetes, 'qa/scenario/test/integration/kubernetes'
- autoload :Mattermost, 'qa/scenario/test/integration/mattermost'
- autoload :ObjectStorage, 'qa/scenario/test/integration/object_storage'
- autoload :SMTP, 'qa/scenario/test/integration/smtp'
- autoload :SSHTunnel, 'qa/scenario/test/integration/ssh_tunnel'
- autoload :Registry, 'qa/scenario/test/integration/registry'
- end
-
- module Sanity
- autoload :Framework, 'qa/scenario/test/sanity/framework'
- autoload :Selectors, 'qa/scenario/test/sanity/selectors'
- end
- end
- end
-
- ##
- # Classes describing structure of GitLab, pages, menus etc.
- #
- # Needed to execute click-driven-only black-box tests.
- #
- module Page
- autoload :Base, 'qa/page/base'
- autoload :View, 'qa/page/view'
- autoload :Element, 'qa/page/element'
- autoload :PageConcern, 'qa/page/page_concern'
- autoload :Validator, 'qa/page/validator'
- autoload :Validatable, 'qa/page/validatable'
-
- module SubMenus
- autoload :Common, 'qa/page/sub_menus/common'
- end
-
- module Main
- autoload :Login, 'qa/page/main/login'
- autoload :Menu, 'qa/page/main/menu'
- autoload :OAuth, 'qa/page/main/oauth'
- autoload :TwoFactorAuth, 'qa/page/main/two_factor_auth'
- autoload :Terms, 'qa/page/main/terms'
- end
-
- module Registration
- autoload :SignUp, 'qa/page/registration/sign_up'
- autoload :Welcome, 'qa/page/registration/welcome'
- end
-
- module Settings
- autoload :Common, 'qa/page/settings/common'
- end
-
- module Dashboard
- autoload :Projects, 'qa/page/dashboard/projects'
- autoload :Groups, 'qa/page/dashboard/groups'
- autoload :Welcome, 'qa/page/dashboard/welcome'
- autoload :Todos, 'qa/page/dashboard/todos'
-
- module Snippet
- autoload :New, 'qa/page/dashboard/snippet/new'
- autoload :Index, 'qa/page/dashboard/snippet/index'
- autoload :Show, 'qa/page/dashboard/snippet/show'
- autoload :Edit, 'qa/page/dashboard/snippet/edit'
- end
- end
-
- module Group
- autoload :New, 'qa/page/group/new'
- autoload :Show, 'qa/page/group/show'
- autoload :Menu, 'qa/page/group/menu'
- autoload :Members, 'qa/page/group/members'
- autoload :BulkImport, 'qa/page/group/bulk_import'
- autoload :DependencyProxy, 'qa/page/group/dependency_proxy'
-
- module Milestone
- autoload :Index, 'qa/page/group/milestone/index'
- autoload :New, 'qa/page/group/milestone/new'
- end
-
- module SubMenus
- autoload :Common, 'qa/page/group/sub_menus/common'
- end
-
- module Settings
- autoload :General, 'qa/page/group/settings/general'
- autoload :PackageRegistries, 'qa/page/group/settings/package_registries'
- end
- end
-
- module Milestone
- autoload :Index, 'qa/page/milestone/index'
- autoload :New, 'qa/page/milestone/new'
- autoload :Show, 'qa/page/milestone/show'
- end
-
- module File
- autoload :Form, 'qa/page/file/form'
- autoload :Show, 'qa/page/file/show'
- autoload :Edit, 'qa/page/file/edit'
-
- module Shared
- autoload :CommitMessage, 'qa/page/file/shared/commit_message'
- autoload :CommitButton, 'qa/page/file/shared/commit_button'
- autoload :Editor, 'qa/page/file/shared/editor'
- end
- end
-
- module Project
- autoload :New, 'qa/page/project/new'
- autoload :Show, 'qa/page/project/show'
- autoload :Activity, 'qa/page/project/activity'
- autoload :Menu, 'qa/page/project/menu'
- autoload :Members, 'qa/page/project/members'
-
- module Artifact
- autoload :Show, 'qa/page/project/artifact/show'
- end
-
- module Branches
- autoload :Show, 'qa/page/project/branches/show'
- end
-
- module Commit
- autoload :Show, 'qa/page/project/commit/show'
- end
-
- module Import
- autoload :Github, 'qa/page/project/import/github'
- autoload :RepoByURL, 'qa/page/project/import/repo_by_url'
- end
-
- module Pipeline
- autoload :Index, 'qa/page/project/pipeline/index'
- autoload :Show, 'qa/page/project/pipeline/show'
- autoload :New, 'qa/page/project/pipeline/new'
- end
-
- module PipelineEditor
- autoload :Show, 'qa/page/project/pipeline_editor/show'
- end
-
- module Tag
- autoload :Index, 'qa/page/project/tag/index'
- autoload :New, 'qa/page/project/tag/new'
- autoload :Show, 'qa/page/project/tag/show'
- end
-
- module Job
- autoload :Show, 'qa/page/project/job/show'
- end
-
- module Packages
- autoload :Index, 'qa/page/project/packages/index'
- autoload :Show, 'qa/page/project/packages/show'
- end
-
- module Registry
- autoload :Show, 'qa/page/project/registry/show'
- end
-
- module Settings
- autoload :Advanced, 'qa/page/project/settings/advanced'
- autoload :Main, 'qa/page/project/settings/main'
- autoload :Repository, 'qa/page/project/settings/repository'
- autoload :CICD, 'qa/page/project/settings/ci_cd'
- autoload :Integrations, 'qa/page/project/settings/integrations'
- autoload :GeneralPipelines, 'qa/page/project/settings/general_pipelines'
- autoload :AutoDevops, 'qa/page/project/settings/auto_devops'
- autoload :DeployKeys, 'qa/page/project/settings/deploy_keys'
- autoload :DeployTokens, 'qa/page/project/settings/deploy_tokens'
- autoload :ProtectedBranches, 'qa/page/project/settings/protected_branches'
- autoload :CiVariables, 'qa/page/project/settings/ci_variables'
- autoload :Runners, 'qa/page/project/settings/runners'
- autoload :MergeRequest, 'qa/page/project/settings/merge_request'
- autoload :MirroringRepositories, 'qa/page/project/settings/mirroring_repositories'
- autoload :ProtectedTags, 'qa/page/project/settings/protected_tags'
- autoload :DefaultBranch, 'qa/page/project/settings/default_branch'
- autoload :VisibilityFeaturesPermissions, 'qa/page/project/settings/visibility_features_permissions'
- autoload :AccessTokens, 'qa/page/project/settings/access_tokens'
-
- module Services
- autoload :Jira, 'qa/page/project/settings/services/jira'
- autoload :Jenkins, 'qa/page/project/settings/services/jenkins'
- autoload :Prometheus, 'qa/page/project/settings/services/prometheus'
- end
- autoload :Monitor, 'qa/page/project/settings/monitor'
- autoload :Alerts, 'qa/page/project/settings/alerts'
- autoload :Integrations, 'qa/page/project/settings/integrations'
- end
-
- module SubMenus
- autoload :CiCd, 'qa/page/project/sub_menus/ci_cd'
- autoload :Common, 'qa/page/project/sub_menus/common'
- autoload :Issues, 'qa/page/project/sub_menus/issues'
- autoload :Monitor, 'qa/page/project/sub_menus/monitor'
- autoload :Deployments, 'qa/page/project/sub_menus/deployments'
- autoload :Infrastructure, 'qa/page/project/sub_menus/infrastructure'
- autoload :Repository, 'qa/page/project/sub_menus/repository'
- autoload :Settings, 'qa/page/project/sub_menus/settings'
- autoload :Project, 'qa/page/project/sub_menus/project'
- autoload :Packages, 'qa/page/project/sub_menus/packages'
- end
-
- module Issue
- autoload :New, 'qa/page/project/issue/new'
- autoload :Show, 'qa/page/project/issue/show'
- autoload :Index, 'qa/page/project/issue/index'
- autoload :JiraImport, 'qa/page/project/issue/jira_import'
- end
-
- module Fork
- autoload :New, 'qa/page/project/fork/new'
- end
-
- module Milestone
- autoload :New, 'qa/page/project/milestone/new'
- autoload :Index, 'qa/page/project/milestone/index'
- end
-
- module Deployments
- module Environments
- autoload :Index, 'qa/page/project/deployments/environments/index'
- end
- end
-
- module Infrastructure
- module Kubernetes
- autoload :Index, 'qa/page/project/infrastructure/kubernetes/index'
- autoload :Add, 'qa/page/project/infrastructure/kubernetes/add'
- autoload :AddExisting, 'qa/page/project/infrastructure/kubernetes/add_existing'
- autoload :Show, 'qa/page/project/infrastructure/kubernetes/show'
- end
- end
-
- module Monitor
- module Metrics
- autoload :Show, 'qa/page/project/monitor/metrics/show'
- end
-
- module Incidents
- autoload :Index, 'qa/page/project/monitor/incidents/index'
- end
- end
-
- module Wiki
- autoload :Edit, 'qa/page/project/wiki/edit'
- autoload :Show, 'qa/page/project/wiki/show'
- autoload :GitAccess, 'qa/page/project/wiki/git_access'
- autoload :List, 'qa/page/project/wiki/list'
- end
-
- module WebIDE
- autoload :Edit, 'qa/page/project/web_ide/edit'
- end
-
- module Snippet
- autoload :New, 'qa/page/project/snippet/new'
- autoload :Show, 'qa/page/project/snippet/show'
- autoload :Index, 'qa/page/project/snippet/index'
- end
-
- module Secure
- autoload :ConfigurationForm, 'qa/page/project/secure/configuration_form'
- end
- end
-
- module Profile
- autoload :Menu, 'qa/page/profile/menu'
- autoload :PersonalAccessTokens, 'qa/page/profile/personal_access_tokens'
- autoload :SSHKeys, 'qa/page/profile/ssh_keys'
- autoload :Emails, 'qa/page/profile/emails'
- autoload :Password, 'qa/page/profile/password'
- autoload :TwoFactorAuth, 'qa/page/profile/two_factor_auth'
-
- module Accounts
- autoload :Show, 'qa/page/profile/accounts/show'
- end
- end
-
- module User
- autoload :Show, 'qa/page/user/show'
- end
-
- module Issuable
- autoload :New, 'qa/page/issuable/new'
- end
-
- module Alert
- autoload :AutoDevopsAlert, 'qa/page/alert/auto_devops_alert'
- autoload :FreeTrial, 'qa/page/alert/free_trial'
- end
-
- module Layout
- autoload :Banner, 'qa/page/layout/banner'
- autoload :Flash, 'qa/page/layout/flash'
- autoload :PerformanceBar, 'qa/page/layout/performance_bar'
- end
-
- module Label
- autoload :New, 'qa/page/label/new'
- autoload :Index, 'qa/page/label/index'
- end
-
- module MergeRequest
- autoload :New, 'qa/page/merge_request/new'
- autoload :Show, 'qa/page/merge_request/show'
- end
-
- module Admin
- autoload :Menu, 'qa/page/admin/menu'
- autoload :NewSession, 'qa/page/admin/new_session'
-
- module Settings
- autoload :General, 'qa/page/admin/settings/general'
- autoload :MetricsAndProfiling, 'qa/page/admin/settings/metrics_and_profiling'
- autoload :Network, 'qa/page/admin/settings/network'
-
- module Component
- autoload :IpLimits, 'qa/page/admin/settings/component/ip_limits'
- autoload :OutboundRequests, 'qa/page/admin/settings/component/outbound_requests'
- autoload :AccountAndLimit, 'qa/page/admin/settings/component/account_and_limit'
- autoload :PerformanceBar, 'qa/page/admin/settings/component/performance_bar'
- autoload :SignUpRestrictions, 'qa/page/admin/settings/component/sign_up_restrictions'
- end
- end
-
- module Overview
- module Users
- autoload :Index, 'qa/page/admin/overview/users/index'
- autoload :Show, 'qa/page/admin/overview/users/show'
- end
-
- module Groups
- autoload :Index, 'qa/page/admin/overview/groups/index'
- autoload :Show, 'qa/page/admin/overview/groups/show'
- autoload :Edit, 'qa/page/admin/overview/groups/edit'
- end
- end
- end
-
- module Mattermost
- autoload :Main, 'qa/page/mattermost/main'
- autoload :Login, 'qa/page/mattermost/login'
- end
-
- module Search
- autoload :Results, 'qa/page/search/results'
- end
-
- ##
- # Classes describing components that are used by several pages.
- #
- module Component
- autoload :Breadcrumbs, 'qa/page/component/breadcrumbs'
- autoload :CiBadgeLink, 'qa/page/component/ci_badge_link'
- autoload :ClonePanel, 'qa/page/component/clone_panel'
- autoload :DesignManagement, 'qa/page/component/design_management'
- autoload :LazyLoader, 'qa/page/component/lazy_loader'
- autoload :LegacyClonePanel, 'qa/page/component/legacy_clone_panel'
- autoload :Dropzone, 'qa/page/component/dropzone'
- autoload :GroupsFilter, 'qa/page/component/groups_filter'
- autoload :Select2, 'qa/page/component/select2'
- autoload :DropdownFilter, 'qa/page/component/dropdown_filter'
- autoload :UsersSelect, 'qa/page/component/users_select'
- autoload :Note, 'qa/page/component/note'
- autoload :ConfirmModal, 'qa/page/component/confirm_modal'
- autoload :CustomMetric, 'qa/page/component/custom_metric'
- autoload :DesignManagement, 'qa/page/component/design_management'
- autoload :ProjectSelector, 'qa/page/component/project_selector'
- autoload :Snippet, 'qa/page/component/snippet'
- autoload :NewSnippet, 'qa/page/component/new_snippet'
- autoload :InviteMembersModal, 'qa/page/component/invite_members_modal'
- autoload :Wiki, 'qa/page/component/wiki'
- autoload :WikiSidebar, 'qa/page/component/wiki_sidebar'
- autoload :WikiPageForm, 'qa/page/component/wiki_page_form'
- autoload :AccessTokens, 'qa/page/component/access_tokens'
- autoload :CommitModal, 'qa/page/component/commit_modal'
- autoload :VisibilitySetting, 'qa/page/component/visibility_setting'
- autoload :ContentEditor, 'qa/page/component/content_editor'
-
- module Import
- autoload :Gitlab, 'qa/page/component/import/gitlab'
- autoload :Selection, 'qa/page/component/import/selection'
- end
-
- module Issuable
- autoload :Common, 'qa/page/component/issuable/common'
- autoload :Sidebar, 'qa/page/component/issuable/sidebar'
- end
-
- module IssueBoard
- autoload :Show, 'qa/page/component/issue_board/show'
- end
-
- module WebIDE
- autoload :Alert, 'qa/page/component/web_ide/alert'
-
- module Modal
- autoload :CreateNewFile, 'qa/page/component/web_ide/modal/create_new_file'
- end
- end
-
- module Project
- autoload :Templates, 'qa/page/component/project/templates'
- end
- end
-
- module Trials
- autoload :New, 'qa/page/trials/new'
- autoload :Select, 'qa/page/trials/select'
- end
-
- module Modal
- autoload :DeleteWiki, 'qa/page/modal/delete_wiki'
- end
- end
-
- ##
- # Classes describing operations on Git repositories.
- #
- module Git
- autoload :Repository, 'qa/git/repository'
- autoload :Location, 'qa/git/location'
- end
-
- ##
- # Classes describing services being part of GitLab and how we can interact
- # with these services, like through the shell.
- #
- module Service
- autoload :Shellout, 'qa/service/shellout'
- autoload :KubernetesCluster, 'qa/service/kubernetes_cluster'
- autoload :Omnibus, 'qa/service/omnibus'
- autoload :PraefectManager, 'qa/service/praefect_manager'
-
- module ClusterProvider
- autoload :Base, 'qa/service/cluster_provider/base'
- autoload :Gcloud, 'qa/service/cluster_provider/gcloud'
- autoload :Minikube, 'qa/service/cluster_provider/minikube'
- autoload :K3d, 'qa/service/cluster_provider/k3d'
- autoload :K3s, 'qa/service/cluster_provider/k3s'
- autoload :K3sCilium, 'qa/service/cluster_provider/k3s_cilium'
- end
-
- module DockerRun
- autoload :Base, 'qa/service/docker_run/base'
- autoload :Jenkins, 'qa/service/docker_run/jenkins'
- autoload :LDAP, 'qa/service/docker_run/ldap'
- autoload :Maven, 'qa/service/docker_run/maven'
- autoload :NodeJs, 'qa/service/docker_run/node_js'
- autoload :GitlabRunner, 'qa/service/docker_run/gitlab_runner'
- autoload :MailHog, 'qa/service/docker_run/mail_hog'
- autoload :SamlIdp, 'qa/service/docker_run/saml_idp'
- autoload :K3s, 'qa/service/docker_run/k3s'
- end
- end
-
- ##
- # Classes that make it possible to execute features tests.
- #
- module Specs
- autoload :Config, 'qa/specs/config'
- autoload :Runner, 'qa/specs/runner'
- autoload :ParallelRunner, 'qa/specs/parallel_runner'
- autoload :LoopRunner, 'qa/specs/loop_runner'
-
- module Helpers
- autoload :ContextSelector, 'qa/specs/helpers/context_selector'
- autoload :ContextFormatter, 'qa/specs/helpers/context_formatter'
- autoload :Quarantine, 'qa/specs/helpers/quarantine'
- autoload :QuarantineFormatter, 'qa/specs/helpers/quarantine_formatter'
- autoload :RSpec, 'qa/specs/helpers/rspec'
- end
- end
-
- ##
- # Classes that describe the structure of vendor/third party application pages
- #
- module Vendor
- module SAMLIdp
- module Page
- autoload :Base, 'qa/vendor/saml_idp/page/base'
- autoload :Login, 'qa/vendor/saml_idp/page/login'
- end
- end
-
- module Jenkins
- module Page
- autoload :Base, 'qa/vendor/jenkins/page/base'
- autoload :Login, 'qa/vendor/jenkins/page/login'
- autoload :Configure, 'qa/vendor/jenkins/page/configure'
- autoload :NewCredentials, 'qa/vendor/jenkins/page/new_credentials'
- autoload :NewJob, 'qa/vendor/jenkins/page/new_job'
- autoload :LastJobConsole, 'qa/vendor/jenkins/page/last_job_console'
- autoload :ConfigureJob, 'qa/vendor/jenkins/page/configure_job'
- end
- end
-
- module Jira
- autoload :JiraAPI, 'qa/vendor/jira/jira_api'
- end
- end
-
- # Classes that provide support to other parts of the framework.
- #
- module Support
- module Page
- autoload :Logging, 'qa/support/page/logging'
- end
- autoload :Api, 'qa/support/api'
- autoload :Dates, 'qa/support/dates'
- autoload :Repeater, 'qa/support/repeater'
- autoload :Run, 'qa/support/run'
- autoload :Retrier, 'qa/support/retrier'
- autoload :Waiter, 'qa/support/waiter'
- autoload :WaitForRequests, 'qa/support/wait_for_requests'
- autoload :OTP, 'qa/support/otp'
- autoload :SSH, 'qa/support/ssh'
- autoload :AllureMetadataFormatter, 'qa/support/allure_metadata_formatter.rb'
- end
+ root = "#{__dir__}/qa"
+
+ loader = Zeitwerk::Loader.new
+ loader.push_dir(root, namespace: QA)
+
+ loader.ignore("#{root}/specs/features")
+
+ loader.inflector.inflect(
+ "ce" => "CE",
+ "ee" => "EE",
+ "api" => "API",
+ "ssh" => "SSH",
+ "ssh_key" => "SSHKey",
+ "ssh_keys" => "SSHKeys",
+ "ecdsa" => "ECDSA",
+ "ed25519" => "ED25519",
+ "rsa" => "RSA",
+ "ldap" => "LDAP",
+ "ldap_tls" => "LDAPTLS",
+ "ldap_no_tls" => "LDAPNoTLS",
+ "ldap_no_server" => "LDAPNoServer",
+ "rspec" => "RSpec",
+ "web_ide" => "WebIDE",
+ "ci_cd" => "CiCd",
+ "project_imported_from_url" => "ProjectImportedFromURL",
+ "repo_by_url" => "RepoByURL",
+ "oauth" => "OAuth",
+ "saml_sso_sign_in" => "SamlSSOSignIn",
+ "saml_sso_sign_up" => "SamlSSOSignUp",
+ "group_saml" => "GroupSAML",
+ "instance_saml" => "InstanceSAML",
+ "saml_sso" => "SamlSSO",
+ "ldap_sync" => "LDAPSync",
+ "ip_address" => "IPAddress",
+ "gpg" => "GPG",
+ "user_gpg" => "UserGPG",
+ "smtp" => "SMTP",
+ "otp" => "OTP",
+ "jira_api" => "JiraAPI"
+ )
+
+ loader.setup
end
-
-QA::Runtime::Release.extend_autoloads!
diff --git a/qa/qa/ce/strategy.rb b/qa/qa/ce/strategy.rb
index 018a1eb1bfc..71c538c20a0 100644
--- a/qa/qa/ce/strategy.rb
+++ b/qa/qa/ce/strategy.rb
@@ -5,10 +5,6 @@ module QA
module Strategy
extend self
- def extend_autoloads!
- # noop
- end
-
def perform_before_hooks
# The login page could take some time to load the first time it is visited.
# We visit the login page and wait for it to properly load only once before the tests.
diff --git a/qa/qa/flow/login.rb b/qa/qa/flow/login.rb
index d23d8eaf097..05a509588f1 100644
--- a/qa/qa/flow/login.rb
+++ b/qa/qa/flow/login.rb
@@ -5,10 +5,10 @@ module QA
module Login
module_function
- def while_signed_in(as: nil, address: :gitlab)
+ def while_signed_in(as: nil, address: :gitlab, admin: false)
Page::Main::Menu.perform(&:sign_out_if_signed_in)
- sign_in(as: as, address: address)
+ sign_in(as: as, address: address, admin: admin)
result = yield
@@ -17,19 +17,25 @@ module QA
end
def while_signed_in_as_admin(address: :gitlab)
- while_signed_in(as: Runtime::User.admin, address: address) do
+ while_signed_in(address: address, admin: true) do
yield
end
end
- def sign_in(as: nil, address: :gitlab, skip_page_validation: false)
+ def sign_in(as: nil, address: :gitlab, skip_page_validation: false, admin: false)
Page::Main::Menu.perform(&:sign_out) if Page::Main::Menu.perform(&:signed_in?)
Runtime::Browser.visit(address, Page::Main::Login)
- Page::Main::Login.perform { |login| login.sign_in_using_credentials(user: as, skip_page_validation: skip_page_validation) }
+ Page::Main::Login.perform do |login|
+ if admin
+ login.sign_in_using_admin_credentials
+ else
+ login.sign_in_using_credentials(user: as, skip_page_validation: skip_page_validation)
+ end
+ end
end
def sign_in_as_admin(address: :gitlab)
- sign_in(as: Runtime::User.admin, address: address)
+ sign_in(as: Runtime::User.admin, address: address, admin: true)
end
def sign_in_unless_signed_in(as: nil, address: :gitlab)
diff --git a/qa/qa/flow/saml.rb b/qa/qa/flow/saml.rb
index 7cbaba9fbd5..1280f59c3c2 100644
--- a/qa/qa/flow/saml.rb
+++ b/qa/qa/flow/saml.rb
@@ -67,7 +67,7 @@ module QA
end
def login_to_idp_if_required(username, password)
- Vendor::SAMLIdp::Page::Login.perform { |login_page| login_page.login_if_required(username, password) }
+ Vendor::SamlIdp::Page::Login.perform { |login_page| login_page.login_if_required(username, password) }
end
end
end
diff --git a/qa/qa/git/repository.rb b/qa/qa/git/repository.rb
index 24a148e9330..356e509a81d 100644
--- a/qa/qa/git/repository.rb
+++ b/qa/qa/git/repository.rb
@@ -4,7 +4,6 @@ require 'cgi'
require 'uri'
require 'fileutils'
require 'tmpdir'
-require 'securerandom'
module QA
module Git
diff --git a/qa/qa/page/admin/settings/component/ip_limits.rb b/qa/qa/page/admin/settings/component/ip_limits.rb
index 1f9bd113cab..a85b96014b3 100644
--- a/qa/qa/page/admin/settings/component/ip_limits.rb
+++ b/qa/qa/page/admin/settings/component/ip_limits.rb
@@ -7,16 +7,18 @@ module QA
module Component
class IpLimits < Page::Base
view 'app/views/admin/application_settings/_ip_limits.html.haml' do
- element :throttle_unauthenticated_checkbox
+ element :throttle_unauthenticated_api_checkbox
+ element :throttle_unauthenticated_web_checkbox
element :throttle_authenticated_api_checkbox
element :throttle_authenticated_web_checkbox
element :save_changes_button
end
def enable_throttles
- check_element(:throttle_unauthenticated_checkbox)
- check_element(:throttle_authenticated_api_checkbox)
- check_element(:throttle_authenticated_web_checkbox)
+ check_element(:throttle_unauthenticated_api_checkbox, true)
+ check_element(:throttle_unauthenticated_web_checkbox, true)
+ check_element(:throttle_authenticated_api_checkbox, true)
+ check_element(:throttle_authenticated_web_checkbox, true)
end
def save_settings
diff --git a/qa/qa/page/component/note.rb b/qa/qa/page/component/note.rb
index 67583f71bf3..7c733a231f1 100644
--- a/qa/qa/page/component/note.rb
+++ b/qa/qa/page/component/note.rb
@@ -14,8 +14,11 @@ module QA
end
base.view 'app/assets/javascripts/notes/components/comment_form.vue' do
- element :comment_button
element :comment_field
+ end
+
+ base.view 'app/assets/javascripts/notes/components/comment_type_dropdown.vue' do
+ element :comment_button
element :discussion_menu_item
end
diff --git a/qa/qa/page/component/wiki_page_form.rb b/qa/qa/page/component/wiki_page_form.rb
index 6b7452b0e0f..fd536ff1dd3 100644
--- a/qa/qa/page/component/wiki_page_form.rb
+++ b/qa/qa/page/component/wiki_page_form.rb
@@ -47,6 +47,7 @@ module QA
within_element(:try_new_editor_container) do
click_button('Use the new editor')
end
+ has_element?(:content_editor_container)
end
end
end
diff --git a/qa/qa/page/dashboard/snippet/index.rb b/qa/qa/page/dashboard/snippet/index.rb
index d8314509b1f..088fff17578 100644
--- a/qa/qa/page/dashboard/snippet/index.rb
+++ b/qa/qa/page/dashboard/snippet/index.rb
@@ -35,8 +35,10 @@ module QA
end
def has_number_of_files?(snippet_title, number)
- within_element(:snippet_link, snippet_title: snippet_title) do
- has_element?(:snippet_file_count_content, snippet_files: number)
+ retry_until(max_attempts: 5, reload: true, sleep_interval: 1) do # snippet statistics computation can take a few moments
+ within_element(:snippet_link, snippet_title: snippet_title) do
+ has_element?(:snippet_file_count_content, snippet_files: number, wait: 5)
+ end
end
end
end
diff --git a/qa/qa/page/group/bulk_import.rb b/qa/qa/page/group/bulk_import.rb
index 9ba80abf21c..b9497aeb6e5 100644
--- a/qa/qa/page/group/bulk_import.rb
+++ b/qa/qa/page/group/bulk_import.rb
@@ -7,7 +7,6 @@ module QA
view "app/assets/javascripts/import_entities/import_groups/components/import_table.vue" do
element :import_table
element :import_item
- element :import_group_button
element :import_status_indicator
end
@@ -19,6 +18,10 @@ module QA
element :target_namespace_selector_dropdown
end
+ view "app/assets/javascripts/import_entities/import_groups/components/import_actions_cell.vue" do
+ element :import_group_button
+ end
+
# Import source group in to target group
#
# @param [String] source_group_name
diff --git a/qa/qa/page/group/menu.rb b/qa/qa/page/group/menu.rb
index c997598e25a..be877e56713 100644
--- a/qa/qa/page/group/menu.rb
+++ b/qa/qa/page/group/menu.rb
@@ -68,8 +68,25 @@ module QA
end
end
+ def go_to_repository_settings
+ hover_group_settings do
+ within_submenu do
+ click_element(:sidebar_menu_item_link, menu_item: 'Repository')
+ end
+ end
+ end
+
private
+ def hover_settings
+ within_sidebar do
+ scroll_to_element(:sidebar_menu_link, menu_item: 'Settings')
+ find_element(:sidebar_menu_link, menu_item: 'Settings').hover
+
+ yield
+ end
+ end
+
def hover_issues
within_sidebar do
scroll_to_element(:sidebar_menu_link, menu_item: 'Issues')
diff --git a/qa/qa/page/group/settings/group_deploy_tokens.rb b/qa/qa/page/group/settings/group_deploy_tokens.rb
new file mode 100644
index 00000000000..65ee3fc72eb
--- /dev/null
+++ b/qa/qa/page/group/settings/group_deploy_tokens.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Group
+ module Settings
+ class GroupDeployTokens < Page::Base
+ view 'app/views/shared/deploy_tokens/_form.html.haml' do
+ element :deploy_token_name_field
+ element :deploy_token_expires_at_field
+ element :deploy_token_read_repository_checkbox
+ element :deploy_token_read_package_registry_checkbox
+ element :deploy_token_read_registry_checkbox
+ element :deploy_token_write_package_registry_checkbox
+ element :create_deploy_token_button
+ end
+
+ view 'app/views/shared/deploy_tokens/_new_deploy_token.html.haml' do
+ element :created_deploy_token_container
+ element :deploy_token_user_field
+ element :deploy_token_field
+ end
+
+ def fill_token_name(name)
+ fill_element(:deploy_token_name_field, name)
+ end
+
+ def fill_token_expires_at(expires_at)
+ fill_element(:deploy_token_expires_at_field, expires_at.to_s + "\n")
+ end
+
+ def fill_scopes(read_repository: false, read_registry: false, read_package_registry: false, write_package_registry: false )
+ check_element(:deploy_token_read_repository_checkbox) if read_repository
+ check_element(:deploy_token_read_package_registry_checkbox) if read_package_registry
+ check_element(:deploy_token_read_registry_checkbox) if read_registry
+ check_element(:deploy_token_write_package_registry_checkbox) if write_package_registry
+ end
+
+ def add_token
+ click_element(:create_deploy_token_button)
+ end
+
+ def token_username
+ within_new_project_deploy_token do
+ find_element(:deploy_token_user_field).value
+ end
+ end
+
+ def token_password
+ within_new_project_deploy_token do
+ find_element(:deploy_token_field).value
+ end
+ end
+
+ private
+
+ def within_new_project_deploy_token
+ has_element?(:created_deploy_token_container, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
+
+ within_element(:created_deploy_token_container) do
+ yield
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/group/settings/repository.rb b/qa/qa/page/group/settings/repository.rb
new file mode 100644
index 00000000000..2cc80ef26c6
--- /dev/null
+++ b/qa/qa/page/group/settings/repository.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Group
+ module Settings
+ class Repository < Page::Base
+ include QA::Page::Settings::Common
+
+ view 'app/views/shared/deploy_tokens/_index.html.haml' do
+ element :deploy_tokens_settings_content
+ end
+
+ def expand_deploy_tokens(&block)
+ expand_content(:deploy_tokens_settings_content) do
+ Settings::GroupDeployTokens.perform(&block)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/main/login.rb b/qa/qa/page/main/login.rb
index 2c7ce69e4e5..c3170478733 100644
--- a/qa/qa/page/main/login.rb
+++ b/qa/qa/page/main/login.rb
@@ -53,7 +53,7 @@ module QA
set_initial_password_if_present
if Runtime::User.ldap_user? && user && user.username != Runtime::User.ldap_username
- raise 'If an LDAP user is provided, it must be used for sign-in', QA::Resource::User::InvalidUserError
+ raise QA::Resource::User::InvalidUserError, 'If an LDAP user is provided, it must be used for sign-in'
end
if Runtime::User.ldap_user?
diff --git a/qa/qa/page/main/menu.rb b/qa/qa/page/main/menu.rb
index 760741a9630..ad5cd971afc 100644
--- a/qa/qa/page/main/menu.rb
+++ b/qa/qa/page/main/menu.rb
@@ -11,6 +11,7 @@ module QA
view 'app/views/layouts/header/_default.html.haml' do
element :navbar, required: true
+ element :canary_badge_link
element :user_avatar, required: true
element :user_menu, required: true
element :stop_impersonation_link
@@ -168,6 +169,16 @@ module QA
click_element(:stop_impersonation_link)
end
+ # To verify whether the user has been directed to a canary web node
+ # @return [Boolean] result of checking existence of :canary_badge_link element
+ # @example:
+ # Menu.perform do |menu|
+ # expect(menu.canary?).to be(true)
+ # end
+ def canary?
+ has_element?(:canary_badge_link)
+ end
+
private
def within_top_menu(&block)
diff --git a/qa/qa/page/merge_request/show.rb b/qa/qa/page/merge_request/show.rb
index afe88fc0cdc..1d8d9ed6859 100644
--- a/qa/qa/page/merge_request/show.rb
+++ b/qa/qa/page/merge_request/show.rb
@@ -136,14 +136,14 @@ module QA
end
def submit_pending_reviews
+ has_element?(:submit_review_button)
within_element(:review_bar_content) do
click_element(:review_preview_dropdown)
click_element(:submit_review_button)
-
- # After clicking the button, wait for it to disappear
- # before moving on to the next part of the test
- has_no_element?(:submit_review_button)
end
+ # After clicking the button, wait for it to disappear
+ # before moving on to the next part of the test
+ has_no_element?(:submit_review_button)
end
def add_comment_to_diff(text)
@@ -287,6 +287,17 @@ module QA
raise "Rebase did not appear to be successful" unless success
end
+ def merge_immediately!
+ merge_moment_dropdown_found = has_element?(:merge_moment_dropdown, wait: 0)
+
+ if merge_moment_dropdown_found
+ click_element(:merge_moment_dropdown)
+ click_element(:merge_immediately_menu_item)
+ else
+ click_element(:merge_button)
+ end
+ end
+
def try_to_merge!
# Revisit after merge page re-architect is done https://gitlab.com/gitlab-org/gitlab/-/issues/300042
# To remove page refresh logic if possible
diff --git a/qa/qa/page/project/monitor/metrics/show.rb b/qa/qa/page/project/monitor/metrics/show.rb
index 07ceb108fa3..0129ee06cb6 100644
--- a/qa/qa/page/project/monitor/metrics/show.rb
+++ b/qa/qa/page/project/monitor/metrics/show.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
module Page
module Project
diff --git a/qa/qa/page/project/settings/ci_cd.rb b/qa/qa/page/project/settings/ci_cd.rb
index c537db34a51..6df285cdd93 100644
--- a/qa/qa/page/project/settings/ci_cd.rb
+++ b/qa/qa/page/project/settings/ci_cd.rb
@@ -4,7 +4,7 @@ module QA
module Page
module Project
module Settings
- class CICD < Page::Base
+ class CiCd < Page::Base
include QA::Page::Settings::Common
view 'app/views/projects/settings/ci_cd/show.html.haml' do
@@ -43,4 +43,4 @@ module QA
end
end
-QA::Page::Project::Settings::CICD.prepend_mod_with("Page::Project::Settings::CICD", namespace: QA)
+QA::Page::Project::Settings::CiCd.prepend_mod_with("Page::Project::Settings::CiCd", namespace: QA)
diff --git a/qa/qa/page/project/settings/deploy_tokens.rb b/qa/qa/page/project/settings/deploy_tokens.rb
index db1f6f68ec6..7b61c81154a 100644
--- a/qa/qa/page/project/settings/deploy_tokens.rb
+++ b/qa/qa/page/project/settings/deploy_tokens.rb
@@ -10,6 +10,7 @@ module QA
element :deploy_token_expires_at_field
element :deploy_token_read_repository_checkbox
element :deploy_token_read_package_registry_checkbox
+ element :deploy_token_write_package_registry_checkbox
element :deploy_token_read_registry_checkbox
element :create_deploy_token_button
end
@@ -28,9 +29,10 @@ module QA
fill_element(:deploy_token_expires_at_field, expires_at.to_s + "\n")
end
- def fill_scopes(read_repository: false, read_registry: false, read_package_registry: false)
+ def fill_scopes(read_repository: false, read_registry: false, read_package_registry: false, write_package_registry: false)
check_element(:deploy_token_read_repository_checkbox) if read_repository
check_element(:deploy_token_read_package_registry_checkbox) if read_package_registry
+ check_element(:deploy_token_write_package_registry_checkbox) if write_package_registry
check_element(:deploy_token_read_registry_checkbox) if read_registry
end
diff --git a/qa/qa/page/view.rb b/qa/qa/page/view.rb
index 613059b2d32..fa17b8fe302 100644
--- a/qa/qa/page/view.rb
+++ b/qa/qa/page/view.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'pathname'
-
module QA
module Page
class View
diff --git a/qa/qa/resource/api_fabricator.rb b/qa/qa/resource/api_fabricator.rb
index 034feb4e90f..c1533577657 100644
--- a/qa/qa/resource/api_fabricator.rb
+++ b/qa/qa/resource/api_fabricator.rb
@@ -55,7 +55,7 @@ module QA
end
end
- include Support::Api
+ include Support::API
attr_writer :api_resource, :api_response
def api_put(body = api_put_body)
diff --git a/qa/qa/resource/ci_variable.rb b/qa/qa/resource/ci_variable.rb
index 0b9f4eb6635..ef663bb613f 100644
--- a/qa/qa/resource/ci_variable.rb
+++ b/qa/qa/resource/ci_variable.rb
@@ -22,7 +22,7 @@ module QA
Page::Project::Menu.perform(&:go_to_ci_cd_settings)
- Page::Project::Settings::CICD.perform do |setting|
+ Page::Project::Settings::CiCd.perform do |setting|
setting.expand_ci_variables do |page|
page.click_add_variable
page.fill_variable(key, value, masked)
diff --git a/qa/qa/resource/deploy_token.rb b/qa/qa/resource/deploy_token.rb
index cd638ad2f85..151454c37b1 100644
--- a/qa/qa/resource/deploy_token.rb
+++ b/qa/qa/resource/deploy_token.rb
@@ -37,7 +37,7 @@ module QA
setting.expand_deploy_tokens do |page|
page.fill_token_name(name)
page.fill_token_expires_at(expires_at)
- page.fill_scopes(read_repository: true, read_package_registry: true)
+ page.fill_scopes(read_repository: true, read_package_registry: true, write_package_registry: true)
page.add_token
end
diff --git a/qa/qa/resource/group_base.rb b/qa/qa/resource/group_base.rb
index b937b704613..a1e5b19f409 100644
--- a/qa/qa/resource/group_base.rb
+++ b/qa/qa/resource/group_base.rb
@@ -30,6 +30,22 @@ module QA
end
end
+ # Get group milestones
+ #
+ # @return [Array<QA::Resource::GroupMilestone>]
+ def milestones
+ parse_body(api_get_from("#{api_get_path}/milestones")).map do |milestone|
+ GroupMilestone.init do |resource|
+ resource.api_client = api_client
+ resource.group = self
+ resource.id = milestone[:id]
+ resource.iid = milestone[:iid]
+ resource.title = milestone[:title]
+ resource.description = milestone[:description]
+ end
+ end
+ end
+
# API get path
#
# @return [String]
diff --git a/qa/qa/resource/group_deploy_token.rb b/qa/qa/resource/group_deploy_token.rb
new file mode 100644
index 00000000000..410a7e6253f
--- /dev/null
+++ b/qa/qa/resource/group_deploy_token.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+module QA
+ module Resource
+ class GroupDeployToken < Base
+ attr_accessor :name, :expires_at
+
+ attribute :username do
+ Page::Group::Settings::Repository.perform do |repository_page|
+ repository_page.expand_deploy_tokens(&:token_username)
+ end
+ end
+
+ attribute :password do
+ Page::Group::Settings::Repository.perform do |repository_page|
+ repository_page.expand_deploy_tokens(&:token_password)
+ end
+ end
+
+ attribute :group do
+ Group.fabricate! do |resource|
+ resource.name = 'group-with-deploy-token'
+ resource.description = 'group for adding deploy token test'
+ end
+ end
+
+ attribute :project do
+ Project.fabricate! do |resource|
+ resource.name = 'project-to-deploy'
+ resource.description = 'project for adding deploy token test'
+ end
+ end
+
+ def fabricate!
+ group.visit!
+
+ Page::Group::Menu.perform(&:go_to_repository_settings)
+
+ Page::Group::Settings::Repository.perform do |setting|
+ setting.expand_deploy_tokens do |page|
+ page.fill_token_name(name)
+ page.fill_token_expires_at(expires_at)
+ page.fill_scopes(read_repository: true, read_package_registry: true, write_package_registry: true)
+
+ page.add_token
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/resource/group_milestone.rb b/qa/qa/resource/group_milestone.rb
index 1fb07fdbd0b..880ca2b9721 100644
--- a/qa/qa/resource/group_milestone.rb
+++ b/qa/qa/resource/group_milestone.rb
@@ -3,11 +3,14 @@
module QA
module Resource
class GroupMilestone < Base
- attr_writer :start_date, :due_date
-
- attribute :id
- attribute :title
- attribute :description
+ attributes :id,
+ :iid,
+ :title,
+ :description,
+ :start_date,
+ :due_date,
+ :updated_at,
+ :created_at
attribute :group do
Group.fabricate_via_api! do |resource|
@@ -20,6 +23,21 @@ module QA
@description = "My awesome group milestone."
end
+ def fabricate!
+ group.visit!
+
+ Page::Group::Menu.perform(&:go_to_milestones)
+ Page::Group::Milestone::Index.perform(&:click_new_milestone_link)
+
+ Page::Group::Milestone::New.perform do |new_milestone|
+ new_milestone.set_title(@title)
+ new_milestone.set_description(@description)
+ new_milestone.set_start_date(@start_date) if @start_date
+ new_milestone.set_due_date(@due_date) if @due_date
+ new_milestone.click_create_milestone_button
+ end
+ end
+
def api_get_path
"/groups/#{group.id}/milestones/#{id}"
end
@@ -38,19 +56,36 @@ module QA
end
end
- def fabricate!
- group.visit!
+ # Object comparison
+ #
+ # @param [QA::Resource::GroupMilestone] other
+ # @return [Boolean]
+ def ==(other)
+ other.is_a?(GroupMilestone) && comparable_milestone == other.comparable_milestone
+ end
- Page::Group::Menu.perform(&:go_to_milestones)
- Page::Group::Milestone::Index.perform(&:click_new_milestone_link)
+ # Override inspect for a better rspec failure diff output
+ #
+ # @return [String]
+ def inspect
+ JSON.pretty_generate(comparable_milestone)
+ end
- Page::Group::Milestone::New.perform do |new_milestone|
- new_milestone.set_title(@title)
- new_milestone.set_description(@description)
- new_milestone.set_start_date(@start_date) if @start_date
- new_milestone.set_due_date(@due_date) if @due_date
- new_milestone.click_create_milestone_button
- end
+ protected
+
+ # Return subset of fields for comparing milestones
+ #
+ # @return [Hash]
+ def comparable_milestone
+ reload! unless api_response
+
+ api_response.slice(
+ :title,
+ :description,
+ :state,
+ :due_date,
+ :start_date
+ )
end
end
end
diff --git a/qa/qa/resource/issue.rb b/qa/qa/resource/issue.rb
index c45ab7593b6..9214d4eff4a 100644
--- a/qa/qa/resource/issue.rb
+++ b/qa/qa/resource/issue.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
module Resource
class Issue < Base
@@ -18,12 +16,14 @@ module QA
:iid,
:assignee_ids,
:labels,
- :title
+ :title,
+ :description
def initialize
@assignee_ids = []
@labels = []
@title = "Issue title #{SecureRandom.hex(8)}"
+ @description = "Issue description #{SecureRandom.hex(8)}"
end
def fabricate!
@@ -34,7 +34,7 @@ module QA
Page::Project::Issue::New.perform do |new_page|
new_page.fill_title(@title)
new_page.choose_template(@template) if @template
- new_page.fill_description(@description) if @description
+ new_page.fill_description(@description) if @description && !@template
new_page.choose_milestone(@milestone) if @milestone
new_page.create_new_issue
end
@@ -64,6 +64,7 @@ module QA
}.tap do |hash|
hash[:milestone_id] = @milestone.id if @milestone
hash[:weight] = @weight if @weight
+ hash[:description] = @description if @description
end
end
diff --git a/qa/qa/resource/kubernetes_cluster/base.rb b/qa/qa/resource/kubernetes_cluster/base.rb
index 38bca48be17..b3812d60431 100644
--- a/qa/qa/resource/kubernetes_cluster/base.rb
+++ b/qa/qa/resource/kubernetes_cluster/base.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
module Resource
module KubernetesCluster
diff --git a/qa/qa/resource/label_base.rb b/qa/qa/resource/label_base.rb
index 14ddd0809ea..b1af0e23561 100644
--- a/qa/qa/resource/label_base.rb
+++ b/qa/qa/resource/label_base.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
module Resource
# Base label class for GroupLabel and ProjectLabel
@@ -66,9 +64,9 @@ module QA
JSON.pretty_generate(comparable_label)
end
- # protected
+ protected
- # Return subset of fields for comparing groups
+ # Return subset of fields for comparing labels
#
# @return [Hash]
def comparable_label
diff --git a/qa/qa/resource/members.rb b/qa/qa/resource/members.rb
index c8f9feeca15..83adb10c3a0 100644
--- a/qa/qa/resource/members.rb
+++ b/qa/qa/resource/members.rb
@@ -12,7 +12,7 @@ module QA
QA::Runtime::Logger.debug(%Q[Adding user #{user.username} to #{full_path} #{self.class.name}])
response = post Runtime::API::Request.new(api_client, api_members_path).url, { user_id: user.id, access_level: access_level }
- response.code == QA::Support::Api::HTTP_STATUS_CREATED
+ response.code == QA::Support::API::HTTP_STATUS_CREATED
end
end
@@ -31,7 +31,7 @@ module QA
QA::Runtime::Logger.debug(%Q[Sharing #{self.class.name} with #{group.name}])
response = post Runtime::API::Request.new(api_client, api_share_path).url, { group_id: group.id, group_access: access_level }
- response.code == QA::Support::Api::HTTP_STATUS_CREATED
+ response.code == QA::Support::API::HTTP_STATUS_CREATED
end
end
diff --git a/qa/qa/resource/merge_request.rb b/qa/qa/resource/merge_request.rb
index 8c313f5d518..1fea6feb910 100644
--- a/qa/qa/resource/merge_request.rb
+++ b/qa/qa/resource/merge_request.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
module Resource
class MergeRequest < Base
@@ -25,7 +23,7 @@ module QA
:state
attribute :project do
- Project.fabricate! do |resource|
+ Project.fabricate_via_api! do |resource|
resource.name = 'project-with-merge-request'
end
end
diff --git a/qa/qa/resource/merge_request_from_fork.rb b/qa/qa/resource/merge_request_from_fork.rb
index b0367df64ed..4eebbdf0a52 100644
--- a/qa/qa/resource/merge_request_from_fork.rb
+++ b/qa/qa/resource/merge_request_from_fork.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
module Resource
class MergeRequestFromFork < MergeRequest
diff --git a/qa/qa/resource/package.rb b/qa/qa/resource/package.rb
index 0e8c3ee95de..b3decb1e2ab 100644
--- a/qa/qa/resource/package.rb
+++ b/qa/qa/resource/package.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
module Resource
class Package < Base
diff --git a/qa/qa/resource/project.rb b/qa/qa/resource/project.rb
index 53b8a9b0246..5ad55090f8c 100644
--- a/qa/qa/resource/project.rb
+++ b/qa/qa/resource/project.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
module Resource
class Project < Base
diff --git a/qa/qa/resource/project_imported_from_github.rb b/qa/qa/resource/project_imported_from_github.rb
index 8aa19555d50..cffeed7a64b 100644
--- a/qa/qa/resource/project_imported_from_github.rb
+++ b/qa/qa/resource/project_imported_from_github.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'octokit'
-
module QA
module Resource
class ProjectImportedFromGithub < Resource::Project
@@ -68,7 +66,7 @@ module QA
response = post(request_url(api_trigger_mirror_pull_path), nil)
Runtime::Logger.info "Mirror pull request response: #{response}"
- response.code == Support::Api::HTTP_STATUS_OK
+ response.code == Support::API::HTTP_STATUS_OK
end
end
diff --git a/qa/qa/resource/project_imported_from_url.rb b/qa/qa/resource/project_imported_from_url.rb
index f159a174840..9880504d886 100644
--- a/qa/qa/resource/project_imported_from_url.rb
+++ b/qa/qa/resource/project_imported_from_url.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
module Resource
class ProjectImportedFromURL < Resource::Project
diff --git a/qa/qa/resource/project_issue_note.rb b/qa/qa/resource/project_issue_note.rb
index 0eb34380332..a68c68c660a 100644
--- a/qa/qa/resource/project_issue_note.rb
+++ b/qa/qa/resource/project_issue_note.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
module Resource
class ProjectIssueNote < Base
diff --git a/qa/qa/resource/protected_branch.rb b/qa/qa/resource/protected_branch.rb
index 7eb5442a964..7db6450acf8 100644
--- a/qa/qa/resource/protected_branch.rb
+++ b/qa/qa/resource/protected_branch.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
module Resource
class ProtectedBranch < Base
diff --git a/qa/qa/resource/registry_repository.rb b/qa/qa/resource/registry_repository.rb
index 3de409232dd..148af353a25 100644
--- a/qa/qa/resource/registry_repository.rb
+++ b/qa/qa/resource/registry_repository.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
module Resource
class RegistryRepository < Base
diff --git a/qa/qa/resource/repository/project_push.rb b/qa/qa/resource/repository/project_push.rb
index ef4873e9483..d0e94951f3b 100644
--- a/qa/qa/resource/repository/project_push.rb
+++ b/qa/qa/resource/repository/project_push.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
module Resource
module Repository
diff --git a/qa/qa/resource/repository/push.rb b/qa/qa/resource/repository/push.rb
index f5b6040d927..00bed7ed546 100644
--- a/qa/qa/resource/repository/push.rb
+++ b/qa/qa/resource/repository/push.rb
@@ -1,8 +1,5 @@
# frozen_string_literal: true
-require 'pathname'
-require 'securerandom'
-
module QA
module Resource
module Repository
diff --git a/qa/qa/resource/runner.rb b/qa/qa/resource/runner.rb
index 2a0823d648e..3c448816100 100644
--- a/qa/qa/resource/runner.rb
+++ b/qa/qa/resource/runner.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
module Resource
class Runner < Base
diff --git a/qa/qa/resource/ssh_key.rb b/qa/qa/resource/ssh_key.rb
index 52526275cb0..9e178a425dd 100644
--- a/qa/qa/resource/ssh_key.rb
+++ b/qa/qa/resource/ssh_key.rb
@@ -72,7 +72,7 @@ module QA
Support::Retrier.retry_until(max_duration: QA::EE::Runtime::Geo.max_db_replication_time, sleep_interval: 3) do
response = get Runtime::API::Request.new(api_client, api_get_path).url
- response.code == QA::Support::Api::HTTP_STATUS_OK &&
+ response.code == QA::Support::API::HTTP_STATUS_OK &&
parse_body(response)[:title].include?(title)
end
end
diff --git a/qa/qa/resource/user.rb b/qa/qa/resource/user.rb
index c424d7319fe..811ce5e0505 100644
--- a/qa/qa/resource/user.rb
+++ b/qa/qa/resource/user.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
module Resource
class User < Base
@@ -117,6 +115,10 @@ module QA
'/users'
end
+ def api_put_path
+ "/users/#{id}"
+ end
+
def api_block_path
"/users/#{id}/block"
end
@@ -153,6 +155,16 @@ module QA
raise ResourceUpdateFailedError, "Failed to block user. Request returned (#{response.code}): `#{response}`."
end
+ def set_public_email
+ response = put(Runtime::API::Request.new(api_client, api_put_path).url, { public_email: email })
+ return if response.code == HTTP_STATUS_OK
+
+ raise(
+ ResourceUpdateFailedError,
+ "Failed to set public email. Request returned (#{response.code}): `#{response}`."
+ )
+ end
+
private
def ldap_post_body
@@ -175,7 +187,8 @@ module QA
end
def fetching_own_data?
- api_user&.username == username || Runtime::User.username == username
+ runtime_username = Runtime::User.ldap_user? ? Runtime::User.ldap_username : Runtime::User.username
+ api_user&.username == username || runtime_username == username
end
end
end
diff --git a/qa/qa/resource/wiki/group_page.rb b/qa/qa/resource/wiki/group_page.rb
index 83beaf097ca..1e40426a389 100644
--- a/qa/qa/resource/wiki/group_page.rb
+++ b/qa/qa/resource/wiki/group_page.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
module Resource
module Wiki
diff --git a/qa/qa/runtime/allure_report.rb b/qa/qa/runtime/allure_report.rb
index bf49141566a..5b0456dc607 100644
--- a/qa/qa/runtime/allure_report.rb
+++ b/qa/qa/runtime/allure_report.rb
@@ -12,8 +12,6 @@ module QA
def configure!
return unless Env.generate_allure_report?
- require 'allure-rspec'
-
configure_allure
configure_attachments
configure_rspec
@@ -31,6 +29,13 @@ module QA
AllureRspec.configure do |config|
config.results_directory = 'tmp/allure-results'
config.clean_results_directory = true
+
+ # automatically attach links to testcases and issues
+ config.tms_tag = :testcase
+ config.link_tms_pattern = '{}'
+ config.issue_tag = :issue
+ config.link_issue_pattern = '{}'
+
config.environment_properties = environment_info if Env.running_in_ci?
# Set custom environment name to separate same specs executed on different environments
@@ -68,7 +73,7 @@ module QA
def configure_rspec
RSpec.configure do |config|
config.add_formatter(AllureRspecFormatter)
- config.add_formatter(QA::Support::AllureMetadataFormatter)
+ config.add_formatter(QA::Support::Formatters::AllureMetadataFormatter)
end
end
diff --git a/qa/qa/runtime/api/client.rb b/qa/qa/runtime/api/client.rb
index 4126ff9ff5a..8a5e22fbc37 100644
--- a/qa/qa/runtime/api/client.rb
+++ b/qa/qa/runtime/api/client.rb
@@ -36,16 +36,28 @@ module QA
if Runtime::Env.admin_personal_access_token
Runtime::API::Client.new(:gitlab, personal_access_token: Runtime::Env.admin_personal_access_token)
else
- user = Resource::User.fabricate_via_api! do |user|
- user.username = Runtime::User.admin_username
- user.password = Runtime::User.admin_password
+ # To return an API client that has admin access, we need a user with admin access to confirm that
+ # the API client user has admin access.
+ client = nil
+ Flow::Login.while_signed_in_as_admin do
+ admin_token = Resource::PersonalAccessToken.fabricate! do |pat|
+ pat.user = Runtime::User.admin
+ end.token
+
+ client = Runtime::API::Client.new(:gitlab, personal_access_token: admin_token)
+
+ user = QA::Resource::User.init do |user|
+ user.username = QA::Runtime::User.admin_username
+ user.password = QA::Runtime::User.admin_password
+ user.api_client = client
+ end.reload!
+
+ unless user.admin? # rubocop: disable Cop/UserAdmin
+ raise AuthorizationError, "User '#{user.username}' is not an administrator."
+ end
end
- unless user.admin?
- raise AuthorizationError, "User '#{user.username}' is not an administrator."
- end
-
- Runtime::API::Client.new(:gitlab, user: user)
+ client
end
end
end
diff --git a/qa/qa/runtime/api/repository_storage_moves.rb b/qa/qa/runtime/api/repository_storage_moves.rb
index d1d44bd1ab5..c3b2095be32 100644
--- a/qa/qa/runtime/api/repository_storage_moves.rb
+++ b/qa/qa/runtime/api/repository_storage_moves.rb
@@ -5,7 +5,7 @@ module QA
module API
module RepositoryStorageMoves
extend self
- extend Support::Api
+ extend Support::API
RepositoryStorageMovesError = Class.new(RuntimeError)
diff --git a/qa/qa/runtime/application_settings.rb b/qa/qa/runtime/application_settings.rb
index 0b2aef47576..55a5ae9d06c 100644
--- a/qa/qa/runtime/application_settings.rb
+++ b/qa/qa/runtime/application_settings.rb
@@ -4,7 +4,7 @@ module QA
module Runtime
class ApplicationSettings
class << self
- include Support::Api
+ include Support::API
APPLICATION_SETTINGS_PATH = '/application/settings'
@@ -18,7 +18,7 @@ module QA
QA::Runtime::Logger.info("Setting application settings: #{application_settings}")
r = put(Runtime::API::Request.new(api_client, APPLICATION_SETTINGS_PATH).url, **application_settings)
- raise "Couldn't set application settings #{application_settings.inspect}" unless r.code == QA::Support::Api::HTTP_STATUS_OK
+ raise "Couldn't set application settings #{application_settings.inspect}" unless r.code == QA::Support::API::HTTP_STATUS_OK
end
def get_application_settings
diff --git a/qa/qa/runtime/browser.rb b/qa/qa/runtime/browser.rb
index 9097690de57..0566bc237bb 100644
--- a/qa/qa/runtime/browser.rb
+++ b/qa/qa/runtime/browser.rb
@@ -4,7 +4,6 @@ require 'rspec/core'
require 'rspec/expectations'
require 'capybara/rspec'
require 'capybara-screenshot/rspec'
-require 'selenium-webdriver'
require 'webdrivers/chromedriver'
require 'webdrivers/geckodriver'
@@ -220,6 +219,28 @@ module QA
yield.tap { clear! } if block_given?
end
+ # To redirect the browser to a canary or non-canary web node
+ # after loading a subject test page
+ # @param [Boolean] Send to canary true or false
+ # @example:
+ # Runtime::Browser::Session.target_canary(true)
+ def self.target_canary(enable_canary)
+ if QA::Runtime::Env.qa_cookies.to_s.include?("gitlab_canary=true")
+ QA::Runtime::Logger.warn("WARNING: Setting cookie through QA_COOKIES var is incompatible with this method.")
+ return
+ end
+
+ browser = Capybara.current_session.driver.browser
+
+ if enable_canary
+ browser.manage.add_cookie name: "gitlab_canary", value: "true"
+ else
+ browser.manage.delete_cookie("gitlab_canary")
+ end
+
+ browser.navigate.refresh
+ end
+
##
# Selenium allows to reset session cookies for current domain only.
#
diff --git a/qa/qa/runtime/env.rb b/qa/qa/runtime/env.rb
index a076d8db9e0..cdfa95457c7 100644
--- a/qa/qa/runtime/env.rb
+++ b/qa/qa/runtime/env.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
require 'active_support/deprecation'
-require 'gitlab/qa'
require 'uri'
module QA
@@ -404,6 +403,10 @@ module QA
ENV['GITLAB_TLS_CERTIFICATE']
end
+ def export_metrics?
+ running_in_ci? && enabled?(ENV['QA_EXPORT_TEST_METRICS'], default: true)
+ end
+
private
def remote_grid_credentials
diff --git a/qa/qa/runtime/feature.rb b/qa/qa/runtime/feature.rb
index 7011f46542b..58408524f54 100644
--- a/qa/qa/runtime/feature.rb
+++ b/qa/qa/runtime/feature.rb
@@ -8,7 +8,7 @@ module QA
class << self
# Documentation: https://docs.gitlab.com/ee/api/features.html
- include Support::Api
+ include Support::API
SetFeatureError = Class.new(RuntimeError)
AuthorizationError = Class.new(RuntimeError)
@@ -17,7 +17,7 @@ module QA
def remove(key)
request = Runtime::API::Request.new(api_client, "/features/#{key}")
response = delete(request.url)
- unless response.code == QA::Support::Api::HTTP_STATUS_NO_CONTENT
+ unless response.code == QA::Support::API::HTTP_STATUS_NO_CONTENT
raise SetFeatureError, "Deleting feature flag #{key} failed with `#{response}`."
end
end
@@ -100,7 +100,7 @@ module QA
scopes[:user] = scopes[:user].username if scopes.key?(:user)
request = Runtime::API::Request.new(api_client, "/features/#{key}")
response = post(request.url, scopes.merge({ value: value }))
- unless response.code == QA::Support::Api::HTTP_STATUS_CREATED
+ unless response.code == QA::Support::API::HTTP_STATUS_CREATED
raise SetFeatureError, "Setting feature flag #{key} to #{value} failed with `#{response}`."
end
end
diff --git a/qa/qa/runtime/fixtures.rb b/qa/qa/runtime/fixtures.rb
index ed051b18a9a..05dee4bfce5 100644
--- a/qa/qa/runtime/fixtures.rb
+++ b/qa/qa/runtime/fixtures.rb
@@ -5,7 +5,7 @@ require 'tmpdir'
module QA
module Runtime
module Fixtures
- include Support::Api
+ include Support::API
TemplateNotFoundError = Class.new(RuntimeError)
diff --git a/qa/qa/runtime/ip_address.rb b/qa/qa/runtime/ip_address.rb
index f370882e5c7..bec5c412a6a 100644
--- a/qa/qa/runtime/ip_address.rb
+++ b/qa/qa/runtime/ip_address.rb
@@ -4,7 +4,7 @@ require 'socket'
module QA
module Runtime
module IPAddress
- include Support::Api
+ include Support::API
HostUnreachableError = Class.new(StandardError)
LOOPBACK_ADDRESS = '127.0.0.1'
@@ -15,7 +15,7 @@ module QA
# we use the public facing IP address
ip_address = if Env.running_in_ci? && !URI.parse(Scenario.gitlab_address).host.include?('test')
response = get(PUBLIC_IP_ADDRESS_API)
- raise HostUnreachableError, "#{PUBLIC_IP_ADDRESS_API} is unreachable" unless response.code == Support::Api::HTTP_STATUS_OK
+ raise HostUnreachableError, "#{PUBLIC_IP_ADDRESS_API} is unreachable" unless response.code == Support::API::HTTP_STATUS_OK
response.body
elsif page.current_host.include?('localhost')
diff --git a/qa/qa/runtime/release.rb b/qa/qa/runtime/release.rb
index 029c8fc037e..c0a090ef552 100644
--- a/qa/qa/runtime/release.rb
+++ b/qa/qa/runtime/release.rb
@@ -13,10 +13,6 @@ module QA
# CE to EE.
#
class Release
- def initialize
- require "qa/#{version.downcase}/strategy"
- end
-
def version
@version ||= ::File.directory?("#{__dir__}/../ee") ? :EE : :CE
end
diff --git a/qa/qa/runtime/search.rb b/qa/qa/runtime/search.rb
index f7f87d96e68..a0ad84285be 100644
--- a/qa/qa/runtime/search.rb
+++ b/qa/qa/runtime/search.rb
@@ -1,12 +1,14 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
module Runtime
module Search
extend self
- extend Support::Api
+ extend Support::API
+
+ RETRY_MAX_ITERATION = 10
+ RETRY_SLEEP_INTERVAL = 12
+ INSERT_RECALL_THRESHOLD = RETRY_MAX_ITERATION * RETRY_SLEEP_INTERVAL
ElasticSearchServerError = Class.new(RuntimeError)
@@ -85,7 +87,7 @@ module QA
private
def find_target_in_scope(scope, search_term)
- QA::Support::Retrier.retry_until(max_attempts: 10, sleep_interval: 10, raise_on_failure: true, retry_on_exception: true) do
+ QA::Support::Retrier.retry_until(max_attempts: RETRY_MAX_ITERATION, sleep_interval: RETRY_SLEEP_INTERVAL, raise_on_failure: true, retry_on_exception: true) do
result = search(scope, search_term)
result && result.any? { |record| yield record }
end
diff --git a/qa/qa/runtime/user.rb b/qa/qa/runtime/user.rb
index a836206034d..0af42470a7c 100644
--- a/qa/qa/runtime/user.rb
+++ b/qa/qa/runtime/user.rb
@@ -34,7 +34,7 @@ module QA
end
def ldap_user?
- Runtime::Env.ldap_username && Runtime::Env.ldap_password
+ Runtime::Env.ldap_username.present? && Runtime::Env.ldap_password.present?
end
def ldap_username
diff --git a/qa/qa/service/docker_run/gitlab_runner.rb b/qa/qa/service/docker_run/gitlab_runner.rb
index 63fbf758231..595d47bf162 100644
--- a/qa/qa/service/docker_run/gitlab_runner.rb
+++ b/qa/qa/service/docker_run/gitlab_runner.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
require 'resolv'
-require 'securerandom'
module QA
module Service
diff --git a/qa/qa/service/kubernetes_cluster.rb b/qa/qa/service/kubernetes_cluster.rb
index adef1b46af2..674bcdca9bb 100644
--- a/qa/qa/service/kubernetes_cluster.rb
+++ b/qa/qa/service/kubernetes_cluster.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true
-require 'securerandom'
require 'mkmf'
-require 'pathname'
module QA
module Service
diff --git a/qa/qa/specs/features/api/1_manage/bulk_import_group_spec.rb b/qa/qa/specs/features/api/1_manage/bulk_import_group_spec.rb
index 6bbb859b3ee..1422dd5a029 100644
--- a/qa/qa/specs/features/api/1_manage/bulk_import_group_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/bulk_import_group_spec.rb
@@ -5,6 +5,7 @@ module QA
describe 'Bulk group import' do
let!(:staging?) { Runtime::Scenario.gitlab_address.include?('staging.gitlab.com') }
+ let(:import_wait_duration) { { max_duration: 300, sleep_interval: 2 } }
let(:admin_api_client) { Runtime::API::Client.as_admin }
let(:user) do
Resource::User.fabricate_via_api! do |usr|
@@ -14,7 +15,6 @@ module QA
end
let(:api_client) { Runtime::API::Client.new(user: user) }
- let(:personal_access_token) { api_client.personal_access_token }
let(:sandbox) do
Resource::Sandbox.fabricate_via_api! do |group|
@@ -29,22 +29,6 @@ module QA
end
end
- let(:subgroup) do
- Resource::Group.fabricate_via_api! do |group|
- group.api_client = api_client
- group.sandbox = source_group
- group.path = "subgroup-for-import-#{SecureRandom.hex(4)}"
- end
- end
-
- let(:imported_subgroup) do
- Resource::Group.init do |group|
- group.api_client = api_client
- group.sandbox = imported_group
- group.path = subgroup.path
- end
- end
-
let(:imported_group) do
Resource::BulkImportGroup.fabricate_via_api! do |group|
group.api_client = api_client
@@ -54,47 +38,88 @@ module QA
end
before do
- Runtime::Feature.enable(:bulk_import) unless staging?
Runtime::Feature.enable(:top_level_group_creation_enabled) if staging?
sandbox.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
+ end
- Resource::GroupLabel.fabricate_via_api! do |label|
- label.api_client = api_client
- label.group = source_group
- label.title = "source-group-#{SecureRandom.hex(4)}"
+ context 'with subgroups and labels' do
+ let(:subgroup) do
+ Resource::Group.fabricate_via_api! do |group|
+ group.api_client = api_client
+ group.sandbox = source_group
+ group.path = "subgroup-for-import-#{SecureRandom.hex(4)}"
+ end
end
- Resource::GroupLabel.fabricate_via_api! do |label|
- label.api_client = api_client
- label.group = subgroup
- label.title = "subgroup-#{SecureRandom.hex(4)}"
+
+ let(:imported_subgroup) do
+ Resource::Group.init do |group|
+ group.api_client = api_client
+ group.sandbox = imported_group
+ group.path = subgroup.path
+ end
+ end
+
+ before do
+ Resource::GroupLabel.fabricate_via_api! do |label|
+ label.api_client = api_client
+ label.group = source_group
+ label.title = "source-group-#{SecureRandom.hex(4)}"
+ end
+ Resource::GroupLabel.fabricate_via_api! do |label|
+ label.api_client = api_client
+ label.group = subgroup
+ label.title = "subgroup-#{SecureRandom.hex(4)}"
+ end
+ end
+
+ it(
+ 'successfully imports groups and labels',
+ testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1873'
+ ) do
+ expect { imported_group.import_status }.to eventually_eq('finished').within(import_wait_duration)
+
+ aggregate_failures do
+ expect(imported_group.reload!).to eq(source_group)
+ expect(imported_group.labels).to include(*source_group.labels)
+
+ expect(imported_subgroup.reload!).to eq(subgroup)
+ expect(imported_subgroup.labels).to include(*subgroup.labels)
+ end
end
end
- # Non blocking issues:
- # https://gitlab.com/gitlab-org/gitlab/-/issues/331252
- # https://gitlab.com/gitlab-org/gitlab/-/issues/333678 <- can cause 500 when creating user and group back to back
- it(
- 'imports group with subgroups and labels',
- testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1871'
- ) do
- expect { imported_group.import_status }.to(
- eventually_eq('finished').within(max_duration: 300, sleep_interval: 2)
- )
-
- aggregate_failures do
- expect(imported_group.reload!).to eq(source_group)
- expect(imported_group.labels).to include(*source_group.labels)
-
- expect(imported_subgroup.reload!).to eq(subgroup)
- expect(imported_subgroup.labels).to include(*subgroup.labels)
+ context 'with milestones' do
+ let(:source_milestone) do
+ Resource::GroupMilestone.fabricate_via_api! do |milestone|
+ milestone.api_client = api_client
+ milestone.group = source_group
+ end
+ end
+
+ before do
+ source_milestone
+ end
+
+ it(
+ 'successfully imports group milestones',
+ testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/2245'
+ ) do
+ expect { imported_group.import_status }.to eventually_eq('finished').within(import_wait_duration)
+
+ imported_milestone = imported_group.reload!.milestones.find { |ml| ml.title == source_milestone.title }
+ aggregate_failures do
+ expect(imported_milestone).to eq(source_milestone)
+ expect(imported_milestone.iid).to eq(source_milestone.iid)
+ expect(imported_milestone.created_at).to eq(source_milestone.created_at)
+ expect(imported_milestone.updated_at).to eq(source_milestone.updated_at)
+ end
end
end
after do
user.remove_via_api!
ensure
- Runtime::Feature.disable(:bulk_import) unless staging?
Runtime::Feature.disable(:top_level_group_creation_enabled) if staging?
end
end
diff --git a/qa/qa/specs/features/api/1_manage/import_github_repo_spec.rb b/qa/qa/specs/features/api/1_manage/import_github_repo_spec.rb
index 72a0a761294..744f39525b9 100644
--- a/qa/qa/specs/features/api/1_manage/import_github_repo_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/import_github_repo_spec.rb
@@ -30,7 +30,7 @@ module QA
user.remove_via_api!
end
- it 'imports Github repo via api', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1858' do
+ it 'imports Github repo via api', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1878' do
imported_project # import the project
expect { imported_project.reload!.import_status }.to eventually_eq('finished').within(max_duration: 90)
diff --git a/qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb b/qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb
index 385908f2176..b51a79f239c 100644
--- a/qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'octokit'
-
# rubocop:disable Rails/Pluck
module QA
# Only executes in custom job/pipeline
@@ -130,10 +128,10 @@ module QA
)
end
- it 'imports large Github repo via api' do
+ it 'imports large Github repo via api', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1880' do
start = Time.now
- imported_project # import the project
+ Runtime::Logger.info("Importing project '#{imported_project.full_path}'") # import the project and log path
fetch_github_objects # fetch all objects right after import has started
import_status = lambda do
@@ -221,32 +219,39 @@ module QA
# @return [void]
def verify_mrs_or_issues(type)
msg = ->(title) { "expected #{type} with title '#{title}' to have" }
+
+ # Compare length to have easy to read overview how many objects are missing
expected = type == 'mr' ? mrs : gl_issues
actual = type == 'mr' ? gh_prs : gh_issues
+ count_msg = "Expected to contain same amount of #{type}s. Gitlab: #{expected.length}, Github: #{actual.length}"
+ expect(expected.length).to eq(actual.length), count_msg
- # Compare length to have easy to read overview how many objects are missing
- expect(expected.length).to(
- eq(actual.length),
- "Expected to contain same amount of #{type}s. Expected: #{expected.length}, actual: #{actual.length}"
- )
logger.debug("= Comparing #{type}s =")
actual.each do |title, actual_item|
print "." # indicate that it is still going but don't spam the output with newlines
expected_item = expected[title]
+ # Print title in the error message to see which object is missing
expect(expected_item).to be_truthy, "#{msg.call(title)} been imported"
next unless expected_item
- expect(expected_item[:body]).to(
- include(actual_item[:body]),
- "#{msg.call(title)} same description. diff:\n#{differ.diff(expected_item[:body], actual_item[:body])}"
- )
- expect(expected_item[:comments].length).to(
- eq(actual_item[:comments].length),
- "#{msg.call(title)} same amount of comments"
- )
- expect(expected_item[:comments]).to match_array(actual_item[:comments])
+ # Print difference in the description
+ expected_body = expected_item[:body]
+ actual_body = actual_item[:body]
+ body_msg = <<~MSG
+ #{msg.call(title)} same description. diff:\n#{differ.diff(expected_item[:body], actual_item[:body])}
+ MSG
+ expect(expected_body).to include(actual_body), body_msg
+
+ # Print amount difference first
+ expected_comments = expected_item[:comments]
+ actual_comments = actual_item[:comments]
+ comment_count_msg = <<~MSG
+ #{msg.call(title)} same amount of comments. Gitlab: #{expected_comments.length}, Github: #{actual_comments.length}
+ MSG
+ expect(expected_comments.length).to eq(actual_comments.length), comment_count_msg
+ expect(expected_comments).to match_array(actual_comments)
end
puts # print newline after last print to make output pretty
end
diff --git a/qa/qa/specs/features/api/1_manage/project_access_token_spec.rb b/qa/qa/specs/features/api/1_manage/project_access_token_spec.rb
index 6024c8658d5..47c07875257 100644
--- a/qa/qa/specs/features/api/1_manage/project_access_token_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/project_access_token_spec.rb
@@ -9,7 +9,7 @@ module QA
end
context 'for the same project' do
- it 'can be used to create a file via the project API', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1734' do
+ it 'can be used to create a file via the project API', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1823' do
expect do
Resource::File.fabricate_via_api! do |file|
file.api_client = @user_api_client
@@ -22,7 +22,7 @@ module QA
end.not_to raise_error
end
- it 'can be used to commit via the API', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1735' do
+ it 'can be used to commit via the API', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1822' do
expect do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.api_client = @user_api_client
@@ -43,7 +43,7 @@ module QA
@different_project = Resource::Project.fabricate!
end
- it 'cannot be used to create a file via the project API', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1736' do
+ it 'cannot be used to create a file via the project API', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1821' do
expect do
Resource::File.fabricate_via_api! do |file|
file.api_client = @user_api_client
@@ -56,7 +56,7 @@ module QA
end.to raise_error(Resource::ApiFabricator::ResourceFabricationFailedError, /403 Forbidden/)
end
- it 'cannot be used to commit via the API', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1737' do
+ it 'cannot be used to commit via the API', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1820' do
expect do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.api_client = @user_api_client
diff --git a/qa/qa/specs/features/api/1_manage/rate_limits_spec.rb b/qa/qa/specs/features/api/1_manage/rate_limits_spec.rb
index ae1c3a9fbcc..9eb1bd985ea 100644
--- a/qa/qa/specs/features/api/1_manage/rate_limits_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/rate_limits_spec.rb
@@ -8,7 +8,7 @@ module QA
let(:api_client) { Runtime::API::Client.new(:gitlab, ip_limits: true) }
let(:request) { Runtime::API::Request.new(api_client, '/users') }
- it 'GET /users', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/441' do
+ it 'GET /users', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1567' do
5.times do
get request.url
expect_status(200)
diff --git a/qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb b/qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb
index a069b94f4da..a149c42877f 100644
--- a/qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb
@@ -30,7 +30,7 @@ module QA
@group.sandbox.remove_member(@user)
end
- it 'is not allowed to push code via the CLI', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1660' do
+ it 'is not allowed to push code via the CLI', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1712' do
expect do
Resource::Repository::Push.fabricate! do |push|
push.repository_http_uri = @project.repository_http_location.uri
@@ -43,7 +43,7 @@ module QA
end.to raise_error(QA::Support::Run::CommandError, /You are not allowed to push code to this project/)
end
- it 'is not allowed to create a file via the API', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1661' do
+ it 'is not allowed to create a file via the API', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1711' do
expect do
Resource::File.fabricate_via_api! do |file|
file.api_client = @user_api_client
@@ -56,7 +56,7 @@ module QA
end.to raise_error(Resource::ApiFabricator::ResourceFabricationFailedError, /403 Forbidden/)
end
- it 'is not allowed to commit via the API', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1662' do
+ it 'is not allowed to commit via the API', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1710' do
expect do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.api_client = @user_api_client
diff --git a/qa/qa/specs/features/api/1_manage/users_spec.rb b/qa/qa/specs/features/api/1_manage/users_spec.rb
index bca0e1f67e8..b705ce9e174 100644
--- a/qa/qa/specs/features/api/1_manage/users_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/users_spec.rb
@@ -8,13 +8,13 @@ module QA
let(:api_client) { Runtime::API::Client.new(:gitlab) }
let(:request) { Runtime::API::Request.new(api_client, '/users') }
- it 'GET /users', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/460' do
+ it 'GET /users', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1552' do
get request.url
expect_status(200)
end
- it 'GET /users/:username with a valid username', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/480' do
+ it 'GET /users/:username with a valid username', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1544' do
get request.url, { params: { username: Runtime::User.username } }
expect_status(200)
@@ -23,7 +23,7 @@ module QA
)
end
- it 'GET /users/:username with an invalid username', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/462' do
+ it 'GET /users/:username with an invalid username', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1551' do
get request.url, { params: { username: SecureRandom.hex(10) } }
expect_status(200)
diff --git a/qa/qa/specs/features/api/2_plan/closes_issue_via_pushing_a_commit_spec.rb b/qa/qa/specs/features/api/2_plan/closes_issue_via_pushing_a_commit_spec.rb
index 8b8c9b4c8b1..dabd97d69d0 100644
--- a/qa/qa/specs/features/api/2_plan/closes_issue_via_pushing_a_commit_spec.rb
+++ b/qa/qa/specs/features/api/2_plan/closes_issue_via_pushing_a_commit_spec.rb
@@ -4,7 +4,7 @@ require 'airborne'
module QA
RSpec.describe 'Plan' do
- include Support::Api
+ include Support::API
describe 'Issue' do
let(:issue) do
@@ -22,7 +22,7 @@ module QA
push_commit('Initial commit')
end
- it 'closes via pushing a commit', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/423' do
+ it 'closes via pushing a commit', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1579' do
push_commit("Closes ##{issue_id}", false)
Support::Retrier.retry_until(max_duration: 10, sleep_interval: 1) do
diff --git a/qa/qa/specs/features/api/3_create/gitaly/automatic_failover_and_recovery_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/automatic_failover_and_recovery_spec.rb
index 223ed02bb47..19fdb37f788 100644
--- a/qa/qa/specs/features/api/3_create/gitaly/automatic_failover_and_recovery_spec.rb
+++ b/qa/qa/specs/features/api/3_create/gitaly/automatic_failover_and_recovery_spec.rb
@@ -28,7 +28,7 @@ module QA
praefect_manager.reset_primary_to_original
end
- it 'automatically fails over', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/976' do
+ it 'automatically fails over', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1267' do
# Create a new project with a commit and wait for it to replicate
Resource::Repository::ProjectPush.fabricate! do |push|
push.project = project
@@ -66,7 +66,7 @@ module QA
end
context 'when recovering from dataloss after failover' do
- it 'automatically reconciles', quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/238187', type: :stale }, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/977' do
+ it 'automatically reconciles', quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/238187', type: :stale }, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1266' do
# Start the old primary node again
praefect_manager.start_primary_node
praefect_manager.wait_for_health_check_current_primary_node
diff --git a/qa/qa/specs/features/api/3_create/gitaly/backend_node_recovery_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/backend_node_recovery_spec.rb
index c90f8546f91..f00321ee3f5 100644
--- a/qa/qa/specs/features/api/3_create/gitaly/backend_node_recovery_spec.rb
+++ b/qa/qa/specs/features/api/3_create/gitaly/backend_node_recovery_spec.rb
@@ -22,7 +22,7 @@ module QA
praefect_manager.reset_primary_to_original
end
- it 'recovers from dataloss', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/978' do
+ it 'recovers from dataloss', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1265' do
# Create a new project with a commit and wait for it to replicate
praefect_manager.wait_for_replication(project.id)
diff --git a/qa/qa/specs/features/api/3_create/gitaly/changing_repository_storage_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/changing_repository_storage_spec.rb
index 176f1139a7a..a4251475e97 100644
--- a/qa/qa/specs/features/api/3_create/gitaly/changing_repository_storage_spec.rb
+++ b/qa/qa/specs/features/api/3_create/gitaly/changing_repository_storage_spec.rb
@@ -24,7 +24,7 @@ module QA
end
end
- context 'when moving from one Gitaly storage to another', :orchestrated, :repository_storage, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/973' do
+ context 'when moving from one Gitaly storage to another', :orchestrated, :repository_storage, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1270' do
let(:source_storage) { { type: :gitaly, name: 'default' } }
let(:destination_storage) { { type: :gitaly, name: QA::Runtime::Env.additional_repository_storage } }
let(:project) do
@@ -45,7 +45,7 @@ module QA
# Note: This test doesn't have the :orchestrated tag because it runs in the Test::Integration::Praefect
# scenario with other tests that aren't considered orchestrated.
# It also runs on staging using nfs-file07 as non-cluster storage and nfs-file22 as cluster/praefect storage
- context 'when moving from Gitaly to Gitaly Cluster', :requires_praefect, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1755', quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/284645', type: :investigating } do
+ context 'when moving from Gitaly to Gitaly Cluster', :requires_praefect, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1269', quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/284645', type: :investigating } do
let(:source_storage) { { type: :gitaly, name: QA::Runtime::Env.non_cluster_repository_storage } }
let(:destination_storage) { { type: :praefect, name: QA::Runtime::Env.praefect_repository_storage } }
let(:project) do
diff --git a/qa/qa/specs/features/api/3_create/gitaly/distributed_reads_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/distributed_reads_spec.rb
index 6c70c09c7ab..1aea1bd1189 100644
--- a/qa/qa/specs/features/api/3_create/gitaly/distributed_reads_spec.rb
+++ b/qa/qa/specs/features/api/3_create/gitaly/distributed_reads_spec.rb
@@ -19,7 +19,7 @@ module QA
praefect_manager.wait_for_replication(project.id)
end
- it 'reads from each node', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/979' do
+ it 'reads from each node', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1264' do
pre_read_data = praefect_manager.query_read_distribution
wait_for_reads_to_increase(project, number_of_reads_per_loop, pre_read_data)
@@ -47,7 +47,7 @@ module QA
praefect_manager.wait_for_reliable_connection
end
- it 'does not read from the unhealthy node', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/980' do
+ it 'does not read from the unhealthy node', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1263' do
pre_read_data = praefect_manager.query_read_distribution
read_from_project(project, number_of_reads_per_loop * 10)
diff --git a/qa/qa/specs/features/api/3_create/gitaly/gitaly_mtls_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/gitaly_mtls_spec.rb
index 8c3b8d88a29..237b8055d94 100644
--- a/qa/qa/specs/features/api/3_create/gitaly/gitaly_mtls_spec.rb
+++ b/qa/qa/specs/features/api/3_create/gitaly/gitaly_mtls_spec.rb
@@ -8,7 +8,7 @@ module QA
let(:first_added_commit_message) { 'commit over git' }
let(:second_added_commit_message) { 'commit over api' }
- it 'pushes to gitaly', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1118' do
+ it 'pushes to gitaly', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1843' do
project = Resource::Project.fabricate! do |project|
project.name = "mTLS"
project.initialize_with_readme = true
diff --git a/qa/qa/specs/features/api/3_create/gitaly/praefect_replication_queue_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/praefect_replication_queue_spec.rb
index 7e924475437..cd60f3fdf7c 100644
--- a/qa/qa/specs/features/api/3_create/gitaly/praefect_replication_queue_spec.rb
+++ b/qa/qa/specs/features/api/3_create/gitaly/praefect_replication_queue_spec.rb
@@ -19,7 +19,7 @@ module QA
praefect_manager.clear_replication_queue
end
- it 'allows replication of different repository after interruption', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/975' do
+ it 'allows replication of different repository after interruption', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1268' do
# We want to fill the replication queue with 10 `in_progress` jobs,
# while a lock has been acquired, which is when the problem occurred
# as reported in https://gitlab.com/gitlab-org/gitaly/-/issues/2801
diff --git a/qa/qa/specs/features/api/3_create/merge_request/push_options_labels_spec.rb b/qa/qa/specs/features/api/3_create/merge_request/push_options_labels_spec.rb
index 2391154030b..26ca6de29f7 100644
--- a/qa/qa/specs/features/api/3_create/merge_request/push_options_labels_spec.rb
+++ b/qa/qa/specs/features/api/3_create/merge_request/push_options_labels_spec.rb
@@ -31,7 +31,7 @@ module QA
end
end
- it 'sets labels', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1032' do
+ it 'sets labels', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1244' do
create_new_mr_via_push
merge_request = project.merge_request_with_title(title)
@@ -45,7 +45,7 @@ module QA
create_new_mr_via_push
end
- it 'removes them on subsequent push', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1033' do
+ it 'removes them on subsequent push', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1243' do
Resource::Repository::ProjectPush.fabricate! do |push|
push.project = project
push.file_content = "Unlabel test #{SecureRandom.hex(8)}"
diff --git a/qa/qa/specs/features/api/3_create/merge_request/push_options_mwps_spec.rb b/qa/qa/specs/features/api/3_create/merge_request/push_options_mwps_spec.rb
index 157a9e92817..164507d8fca 100644
--- a/qa/qa/specs/features/api/3_create/merge_request/push_options_mwps_spec.rb
+++ b/qa/qa/specs/features/api/3_create/merge_request/push_options_mwps_spec.rb
@@ -29,7 +29,7 @@ module QA
runner.remove_via_api!
end
- it 'sets merge when pipeline succeeds', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1037' do
+ it 'sets merge when pipeline succeeds', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1240' do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.commit_message = 'Add .gitlab-ci.yml'
@@ -72,7 +72,7 @@ module QA
expect(merge_request.merge_when_pipeline_succeeds).to be true
end
- it 'merges when pipeline succeeds', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1036' do
+ it 'merges when pipeline succeeds', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1241' do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.commit_message = 'Add .gitlab-ci.yml'
diff --git a/qa/qa/specs/features/api/3_create/merge_request/push_options_remove_source_branch_spec.rb b/qa/qa/specs/features/api/3_create/merge_request/push_options_remove_source_branch_spec.rb
index eb93f4cd5cb..32c7196e9fb 100644
--- a/qa/qa/specs/features/api/3_create/merge_request/push_options_remove_source_branch_spec.rb
+++ b/qa/qa/specs/features/api/3_create/merge_request/push_options_remove_source_branch_spec.rb
@@ -17,7 +17,7 @@ module QA
end
end
- it 'removes the source branch', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1035' do
+ it 'removes the source branch', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1242' do
Resource::Repository::ProjectPush.fabricate! do |push|
push.project = project
push.branch_name = branch
diff --git a/qa/qa/specs/features/api/3_create/merge_request/push_options_target_branch_spec.rb b/qa/qa/specs/features/api/3_create/merge_request/push_options_target_branch_spec.rb
index 9ac27a2ca06..b0e616c2d1d 100644
--- a/qa/qa/specs/features/api/3_create/merge_request/push_options_target_branch_spec.rb
+++ b/qa/qa/specs/features/api/3_create/merge_request/push_options_target_branch_spec.rb
@@ -16,7 +16,7 @@ module QA
end
end
- it 'sets a target branch', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1034' do
+ it 'sets a target branch', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1646' do
target_branch = "push-options-test-target-#{SecureRandom.hex(8)}"
Resource::Repository::ProjectPush.fabricate! do |push|
diff --git a/qa/qa/specs/features/api/3_create/merge_request/push_options_title_description_spec.rb b/qa/qa/specs/features/api/3_create/merge_request/push_options_title_description_spec.rb
index 62e6290183f..c898646c0de 100644
--- a/qa/qa/specs/features/api/3_create/merge_request/push_options_title_description_spec.rb
+++ b/qa/qa/specs/features/api/3_create/merge_request/push_options_title_description_spec.rb
@@ -14,7 +14,7 @@ module QA
end
end
- it 'sets title and description', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1038' do
+ it 'sets title and description', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1239' do
description = "This is a test of MR push options"
title = "MR push options test #{SecureRandom.hex(8)}"
diff --git a/qa/qa/specs/features/api/3_create/repository/default_branch_name_setting_spec.rb b/qa/qa/specs/features/api/3_create/repository/default_branch_name_setting_spec.rb
index f86bbee05c2..b2a184c2374 100644
--- a/qa/qa/specs/features/api/3_create/repository/default_branch_name_setting_spec.rb
+++ b/qa/qa/specs/features/api/3_create/repository/default_branch_name_setting_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
RSpec.describe 'Create' do
describe 'Default branch name instance setting', :requires_admin, :skip_live_env do
@@ -13,7 +11,7 @@ module QA
Runtime::ApplicationSettings.restore_application_settings(:default_branch_name)
end
- it 'sets the default branch name for a new project', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1018' do
+ it 'sets the default branch name for a new project', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1247' do
project = Resource::Project.fabricate_via_api! do |project|
project.name = "default-branch-name"
project.initialize_with_readme = true
@@ -32,7 +30,7 @@ module QA
end
end
- it 'allows a project to be created via the CLI with a different default branch name', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1019' do
+ it 'allows a project to be created via the CLI with a different default branch name', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1246' do
project_name = "default-branch-name-via-cli-#{SecureRandom.hex(8)}"
group = Resource::Group.fabricate_via_api!
diff --git a/qa/qa/specs/features/api/3_create/repository/files_spec.rb b/qa/qa/specs/features/api/3_create/repository/files_spec.rb
index 1099234537a..4141b4343a0 100644
--- a/qa/qa/specs/features/api/3_create/repository/files_spec.rb
+++ b/qa/qa/specs/features/api/3_create/repository/files_spec.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
require 'airborne'
-require 'securerandom'
module QA
RSpec.describe 'API basics' do
@@ -12,7 +11,7 @@ module QA
let(:project_name) { "api-basics-#{SecureRandom.hex(8)}" }
let(:sanitized_project_path) { CGI.escape("#{Runtime::User.username}/#{project_name}") }
- it 'user creates a project with a file and deletes them afterwards', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/420' do
+ it 'user creates a project with a file and deletes them afterwards', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1581' do
create_project_request = Runtime::API::Request.new(@api_client, '/projects')
post create_project_request.url, path: project_name, name: project_name
@@ -78,7 +77,7 @@ module QA
SVG
end
- it 'sets no-cache headers as expected', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/421' do
+ it 'sets no-cache headers as expected', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1580' do
create_project_request = Runtime::API::Request.new(@api_client, '/projects')
post create_project_request.url, path: project_name, name: project_name
diff --git a/qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb b/qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb
index c65d981d99a..caaa615149d 100644
--- a/qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb
+++ b/qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb
@@ -1,13 +1,12 @@
# frozen_string_literal: true
require 'airborne'
-require 'securerandom'
require 'digest'
module QA
RSpec.describe 'Create' do
describe 'Compare archives of different user projects with the same name and check they\'re different' do
- include Support::Api
+ include Support::API
let(:project_name) { "project-archive-download-#{SecureRandom.hex(8)}" }
let(:archive_types) { %w(tar.gz tar.bz2 tar zip) }
@@ -28,7 +27,7 @@ module QA
end
end
- it 'download archives of each user project then check they are different', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/427' do
+ it 'download archives of each user project then check they are different', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1575' do
archive_checksums = {}
users.each do |user_key, user_info|
diff --git a/qa/qa/specs/features/api/3_create/repository/push_postreceive_idempotent_spec.rb b/qa/qa/specs/features/api/3_create/repository/push_postreceive_idempotent_spec.rb
index c06e3b9f162..34254d579cb 100644
--- a/qa/qa/specs/features/api/3_create/repository/push_postreceive_idempotent_spec.rb
+++ b/qa/qa/specs/features/api/3_create/repository/push_postreceive_idempotent_spec.rb
@@ -17,11 +17,11 @@ module QA
project&.remove_via_api!
end
- it 'pushes and creates a single push event three times', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1744' do
+ it 'pushes and creates a single push event three times', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1840' do
verify_single_event_per_push(repeat: 3)
end
- it 'repeatedly pushes and creates a single push event several times', :transient, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1744' do
+ it 'repeatedly pushes and creates a single push event several times', :transient, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1915' do
verify_single_event_per_push(repeat: Runtime::Env.transient_trials) do |i|
QA::Runtime::Logger.info("Transient bug test action - Trial #{i}")
end
diff --git a/qa/qa/specs/features/api/3_create/snippet/snippet_repository_storage_move_spec.rb b/qa/qa/specs/features/api/3_create/snippet/snippet_repository_storage_move_spec.rb
index 7b82a872fc0..4b0dc9d431b 100644
--- a/qa/qa/specs/features/api/3_create/snippet/snippet_repository_storage_move_spec.rb
+++ b/qa/qa/specs/features/api/3_create/snippet/snippet_repository_storage_move_spec.rb
@@ -21,7 +21,7 @@ module QA
praefect_manager.gitlab = 'gitlab'
end
- it 'moves snippet repository from one Gitaly storage to another', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1700' do
+ it 'moves snippet repository from one Gitaly storage to another', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1912' do
expect(snippet).to have_file('original_file')
expect { snippet.change_repository_storage(destination_storage[:name]) }.not_to raise_error
expect { praefect_manager.verify_storage_move(source_storage, destination_storage, repo_type: :snippet) }.not_to raise_error
diff --git a/qa/qa/specs/features/api/4_verify/cancel_pipeline_when_block_user_spec.rb b/qa/qa/specs/features/api/4_verify/cancel_pipeline_when_block_user_spec.rb
index ecca0f94604..5d153e7736a 100644
--- a/qa/qa/specs/features/api/4_verify/cancel_pipeline_when_block_user_spec.rb
+++ b/qa/qa/specs/features/api/4_verify/cancel_pipeline_when_block_user_spec.rb
@@ -34,7 +34,7 @@ module QA
project.remove_via_api!
end
- it 'pipeline schedule is canceled', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1730' do
+ it 'pipeline schedule is canceled', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1825' do
user.block!
expect(pipeline_schedule[:active]).not_to be_truthy, "Expected schedule active state to be false - active state #{pipeline_schedule[:active]}"
diff --git a/qa/qa/specs/features/api/5_package/container_registry_spec.rb b/qa/qa/specs/features/api/5_package/container_registry_spec.rb
index f79a3ebbe03..5847ffa1419 100644
--- a/qa/qa/specs/features/api/5_package/container_registry_spec.rb
+++ b/qa/qa/specs/features/api/5_package/container_registry_spec.rb
@@ -4,7 +4,7 @@ require 'airborne'
module QA
RSpec.describe 'Package', only: { subdomain: %i[staging pre] } do
- include Support::Api
+ include Support::API
describe 'Container Registry' do
let(:api_client) { Runtime::API::Client.new(:gitlab) }
@@ -72,7 +72,7 @@ module QA
registry&.remove_via_api!
end
- it 'pushes, pulls image to the registry and deletes image blob, manifest and tag', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1738' do
+ it 'pushes, pulls image to the registry and deletes image blob, manifest and tag', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1819' do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.api_client = api_client
commit.commit_message = 'Add .gitlab-ci.yml'
diff --git a/qa/qa/specs/features/browser_ui/1_manage/group/bulk_import_group_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/group/bulk_import_group_spec.rb
index fe17b5c34e1..c3be58fda74 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/group/bulk_import_group_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/group/bulk_import_group_spec.rb
@@ -38,7 +38,6 @@ module QA
end
before do
- Runtime::Feature.enable(:bulk_import) unless staging?
Runtime::Feature.enable(:top_level_group_creation_enabled) if staging?
sandbox.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
@@ -54,10 +53,14 @@ module QA
end
end
- # Non blocking issues:
- # https://gitlab.com/gitlab-org/gitlab/-/issues/331252
- # https://gitlab.com/gitlab-org/gitlab/-/issues/333678 <- can cause 500 when creating user and group back to back
- it 'imports group from UI', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1785' do
+ it(
+ 'imports group from UI',
+ testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1806',
+ issue_1: 'https://gitlab.com/gitlab-org/gitlab/-/issues/331252',
+ issue_2: 'https://gitlab.com/gitlab-org/gitlab/-/issues/333678',
+ # mostly impacts testing as it makes small groups import slower
+ issue_3: 'https://gitlab.com/gitlab-org/gitlab/-/issues/332351'
+ ) do
Page::Group::BulkImport.perform do |import_page|
import_page.import_group(imported_group.path, imported_group.sandbox.path)
@@ -73,7 +76,6 @@ module QA
after do
user.remove_via_api!
ensure
- Runtime::Feature.disable(:bulk_import) unless staging?
Runtime::Feature.disable(:top_level_group_creation_enabled) if staging?
end
end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/group/create_group_with_mattermost_team_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/group/create_group_with_mattermost_team_spec.rb
index 192c1a3908b..eae8e1b7e12 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/group/create_group_with_mattermost_team_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/group/create_group_with_mattermost_team_spec.rb
@@ -3,7 +3,7 @@
module QA
RSpec.describe 'Configure', :orchestrated, :mattermost do
describe 'Mattermost support' do
- it 'user creates a group with a mattermost team', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/665' do
+ it 'user creates a group with a mattermost team', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1459' do
Flow::Login.sign_in
Page::Main::Menu.perform(&:go_to_groups)
diff --git a/qa/qa/specs/features/browser_ui/1_manage/group/transfer_group_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/group/transfer_group_spec.rb
index 84464f7174a..2550fc86ef2 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/group/transfer_group_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/group/transfer_group_spec.rb
@@ -28,7 +28,7 @@ module QA
end
it 'transfers a subgroup to another group',
- testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1724' do
+ testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1828' do
Page::Group::Menu.perform(&:click_group_general_settings_item)
Page::Group::Settings::General.perform do |general|
general.transfer_group(target_group.path)
diff --git a/qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb
index 7ab5ffdf014..87ac136d802 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb
@@ -44,7 +44,7 @@ module QA
end
it 'user transfers a project between groups',
- testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1703' do
+ testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1592' do
# Retry is needed here as the target group is not avaliable for transfer right away.
QA::Support::Retrier.retry_on_exception(reload_page: page) do
Page::File::Show.perform(&:go_to_general_settings)
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb
index 8e03444b113..a3235543998 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb
@@ -33,7 +33,7 @@ module QA
group.add_member(developer_user, Resource::Members::AccessLevel::DEVELOPER)
end
- it 'allows using 2FA recovery code once only', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/972' do
+ it 'allows using 2FA recovery code once only', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1271' do
recovery_code = enable_2fa_for_user_and_fetch_recovery_code(developer_user)
Flow::Login.sign_in(as: developer_user, skip_page_validation: true)
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/2fa_ssh_recovery_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/2fa_ssh_recovery_spec.rb
index 3702f95158c..8a2bbc92eca 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/2fa_ssh_recovery_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/2fa_ssh_recovery_spec.rb
@@ -19,7 +19,7 @@ module QA
enable_2fa_for_user(user)
end
- it 'allows 2FA code recovery via ssh' do
+ it 'allows 2FA code recovery via ssh', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1227' do
recovery_code = Support::SSH.perform do |ssh|
ssh.key = ssh_key
ssh.uri = address.gsub(/(?<=:)(#{uri.port})/, ssh_port)
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb
index 9b2540f67c7..ca95d567316 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb
@@ -3,7 +3,7 @@
module QA
RSpec.describe 'Manage', :smoke do
describe 'basic user login' do
- it 'user logs in using basic credentials and logs out', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1690' do
+ it 'user logs in using basic credentials and logs out', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1578' do
Flow::Login.sign_in
Page::Main::Menu.perform do |menu|
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb
index a8650d633c8..2fe1cbabee3 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb
@@ -35,7 +35,7 @@ module QA
group.add_member(developer_user, Resource::Members::AccessLevel::DEVELOPER)
end
- it 'allows enforcing 2FA via UI and logging in with 2FA', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/898' do
+ it 'allows enforcing 2FA via UI and logging in with 2FA', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1320' do
enforce_two_factor_authentication_on_group(group)
enable_two_factor_authentication_for_user(developer_user)
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb
index cc12dd4e315..b4b1632dfbf 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb
@@ -3,7 +3,7 @@
module QA
RSpec.describe 'Manage', :orchestrated, :ldap_no_tls, :ldap_tls do
describe 'LDAP login' do
- it 'user logs into GitLab using LDAP credentials', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/668' do
+ it 'user logs into GitLab using LDAP credentials', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1456' do
Flow::Login.sign_in
Page::Main::Menu.perform do |menu|
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb
index 366f150bcd1..f06ded7ba53 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb
@@ -3,7 +3,7 @@
module QA
RSpec.describe 'Manage', :orchestrated, :mattermost do
describe 'Mattermost login' do
- it 'user logs into Mattermost using GitLab OAuth', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/666' do
+ it 'user logs into Mattermost using GitLab OAuth', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1458' do
Flow::Login.sign_in
Support::Retrier.retry_on_exception do
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/login_via_instance_wide_saml_sso_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/login_via_instance_wide_saml_sso_spec.rb
index 6cd486bc84b..e3b73906fe5 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/login_via_instance_wide_saml_sso_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/login_via_instance_wide_saml_sso_spec.rb
@@ -3,12 +3,15 @@
module QA
RSpec.describe 'Manage', :orchestrated, :instance_saml do
describe 'Instance wide SAML SSO' do
- it 'user logs in to gitlab with SAML SSO', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/671' do
+ it(
+ 'user logs in to gitlab with SAML SSO',
+ testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1453'
+ ) do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.perform(&:sign_in_with_saml)
- Vendor::SAMLIdp::Page::Login.perform do |login_page|
+ Vendor::SamlIdp::Page::Login.perform do |login_page|
login_page.login('user1', 'user1pass')
end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/maintain_log_in_mixed_env_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/maintain_log_in_mixed_env_spec.rb
new file mode 100644
index 00000000000..2b1c956039f
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/maintain_log_in_mixed_env_spec.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Manage', :mixed_env, :smoke, only: { subdomain: :staging } do
+ describe 'basic user' do
+ it 'remains logged in when redirected from canary to non-canary node', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/2251' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+
+ Support::Retrier.retry_until(sleep_interval: 0.5) do
+ Page::Main::Login.perform(&:can_sign_in?)
+ end
+
+ Runtime::Browser::Session.target_canary(true)
+ Flow::Login.sign_in
+
+ verify_session_on_canary(true)
+
+ Runtime::Browser::Session.target_canary(false)
+
+ verify_session_on_canary(false)
+
+ Support::Retrier.retry_until(sleep_interval: 0.5) do
+ Page::Main::Menu.perform(&:sign_out)
+
+ Page::Main::Login.perform(&:can_sign_in?)
+ end
+ end
+
+ def verify_session_on_canary(enable_canary)
+ Page::Main::Menu.perform do |menu|
+ aggregate_failures 'testing session log in' do
+ expect(menu.canary?).to be(enable_canary)
+ expect(menu).to have_personal_area
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb
index 696bbc2a7b7..45d01d0f00a 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb
@@ -14,7 +14,7 @@ module QA
end
RSpec.describe 'Manage', :skip_signup_disabled, :requires_admin do
- describe 'while LDAP is enabled', :orchestrated, :ldap_no_tls, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/935' do
+ describe 'while LDAP is enabled', :orchestrated, :ldap_no_tls, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1300' do
before do
# When LDAP is enabled, a previous test might have created a token for the LDAP 'tanuki' user who is not an admin
# So we need to set it to nil in order to create a new token for admin user so that we are able to set_application_settings
@@ -39,7 +39,7 @@ module QA
end
end
- describe 'standard', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/936' do
+ describe 'standard', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1652' do
context 'when admin approval is not required' do
before(:all) do
set_require_admin_approval_after_user_signup_via_api(false)
@@ -66,7 +66,7 @@ module QA
end
end
- it 'allows recreating with same credentials', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/937' do
+ it 'allows recreating with same credentials', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1651' do
expect(Page::Main::Menu.perform(&:signed_in?)).to be_falsy
Flow::Login.sign_in(as: user, skip_page_validation: true)
@@ -106,7 +106,7 @@ module QA
end
end
- it 'allows user login after approval', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1076' do
+ it 'allows user login after approval', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1639' do
expect(page).to have_text(signed_up_waiting_approval_text)
Flow::Login.sign_in(as: @user, skip_page_validation: true)
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb
index bf59dcfcc4c..3eb0a5457c0 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb
@@ -7,7 +7,7 @@ module QA
Runtime::Feature.enable(:invite_members_group_modal)
end
- it 'user adds project member', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/482' do
+ it 'user adds project member', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1543' do
Flow::Login.sign_in
user = Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb
index 564b14a872f..974d9b02f4d 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb
@@ -21,7 +21,7 @@ module QA
project
end
- context 'in group', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1857' do
+ context 'in group', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1620' do
let(:project_name) { "project-in-group-#{SecureRandom.hex(8)}" }
let(:project) do
Resource::Project.fabricate_via_browser_ui! do |project|
@@ -33,7 +33,7 @@ module QA
it_behaves_like 'successful project creation'
end
- context 'in personal namespace', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1888' do
+ context 'in personal namespace', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1914' do
let(:project_name) { "project-in-personal-namespace-#{SecureRandom.hex(8)}" }
let(:project) do
Resource::Project.fabricate_via_browser_ui! do |project|
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/dashboard_images_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/dashboard_images_spec.rb
index 6e0ed4adb63..e48a03b5661 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/dashboard_images_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/dashboard_images_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'nokogiri'
-
module QA
RSpec.describe 'Manage', quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/212145', type: :stale } do
describe 'Check for broken images', :requires_admin do
@@ -41,13 +39,13 @@ module QA
end
end
- context 'when logged in as a new user', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1693' do
+ context 'when logged in as a new user', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1549' do
it_behaves_like 'loads all images' do
let(:new_user) { @new_user }
end
end
- context 'when logged in as a new admin', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1727' do
+ context 'when logged in as a new admin', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1550' do
it_behaves_like 'loads all images' do
let(:new_user) { @new_admin }
end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb
index c55ecb28361..4e3739a7672 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb
@@ -40,7 +40,7 @@ module QA
user.remove_via_api!
end
- it 'imports a GitHub repo', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1762' do
+ it 'imports a GitHub repo', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1607' do
Page::Project::Import::Github.perform do |import_page|
import_page.add_personal_access_token(Runtime::Env.github_access_token)
import_page.import!(github_repo, group.full_path, imported_project_name)
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb
index 00d1b829150..dcf72c1cafc 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb
@@ -5,7 +5,7 @@ module QA
describe 'Project access tokens' do
let(:project_access_token) {QA::Resource::ProjectAccessToken.fabricate_via_browser_ui!}
- it 'can be created and revoked via the UI' do
+ it 'can be created and revoked via the UI', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1832' do
expect(project_access_token.token).not_to be_nil
project_access_token.revoke_via_ui!
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb
index db96c2d4ad3..e5faebd2a80 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb
@@ -3,7 +3,7 @@
module QA
RSpec.describe 'Manage' do
describe 'Project activity' do
- it 'user creates an event in the activity page upon Git push', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/407' do
+ it 'user creates an event in the activity page upon Git push', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1591' do
Flow::Login.sign_in
project = Resource::Repository::ProjectPush.fabricate! do |push|
diff --git a/qa/qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb
index 964cd453049..d0a57b95df4 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb
@@ -61,7 +61,7 @@ module QA
user_api_client.personal_access_token
end
- it 'can be followed and their activity seen', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1773' do
+ it 'can be followed and their activity seen', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1842' do
Flow::Login.sign_in
page.visit Runtime::Scenario.gitlab_address + "/#{user.username}"
Page::User::Show.perform(&:click_follow_user_link)
diff --git a/qa/qa/specs/features/browser_ui/1_manage/user/user_access_termination_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/user/user_access_termination_spec.rb
index d9b5ffcdc47..1158e65c3f3 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/user/user_access_termination_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/user/user_access_termination_spec.rb
@@ -39,7 +39,7 @@ module QA
end
end
- it 'is not allowed to edit the project files', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1663' do
+ it 'is not allowed to edit the project files', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1709' do
Flow::Login.sign_in(as: user)
project.visit!
diff --git a/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb
index d561e5d113c..27c16898c43 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb
@@ -3,7 +3,7 @@
module QA
RSpec.describe 'Plan', :orchestrated, :smtp, :requires_admin do
describe 'Email Notification' do
- include Support::Api
+ include Support::API
let!(:user) do
Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
@@ -20,7 +20,7 @@ module QA
Flow::Login.sign_in
end
- it 'is received by a user for project invitation', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/676' do
+ it 'is received by a user for project invitation', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1448' do
project.visit!
Page::Project::Menu.perform(&:click_members)
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb
index 9129584d110..7c4e10dc2b3 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb
@@ -33,7 +33,7 @@ module QA
user&.remove_via_api!
end
- it 'mentions a user in a comment', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/452' do
+ it 'mentions a user in a comment', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1559' do
Page::Project::Issue::Show.perform do |show|
show.select_all_activities_filter
show.comment("cc-ing you here @#{user.username}")
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/collapse_comments_in_discussions_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/collapse_comments_in_discussions_spec.rb
index 72c990cbbc2..95272bae9c2 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/collapse_comments_in_discussions_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/collapse_comments_in_discussions_spec.rb
@@ -13,7 +13,7 @@ module QA
issue.visit!
end
- it 'collapses and expands reply for comments in an issue', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1163' do
+ it 'collapses and expands reply for comments in an issue', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1189' do
Page::Project::Issue::Show.perform do |show|
show.select_all_activities_filter
show.start_discussion('My first discussion')
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/comment_issue_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/comment_issue_spec.rb
index c5cd495f607..b4df43cb235 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/comment_issue_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/comment_issue_spec.rb
@@ -9,7 +9,7 @@ module QA
Resource::Issue.fabricate_via_api!.visit!
end
- it 'comments on an issue and edits the comment', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1151' do
+ it 'comments on an issue and edits the comment', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1200' do
Page::Project::Issue::Show.perform do |show|
first_version_of_comment = 'First version of the comment'
second_version_of_comment = 'Second version of the comment'
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb
index 2243437fc71..7519f4daae2 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb
@@ -9,7 +9,7 @@ module QA
Flow::Login.sign_in
end
- it 'creates an issue', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1793' do
+ it 'creates an issue', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1185' do
issue = Resource::Issue.fabricate_via_browser_ui!
Page::Project::Menu.perform(&:click_issues)
@@ -19,7 +19,7 @@ module QA
end
end
- it 'closes an issue', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1792' do
+ it 'closes an issue', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1222' do
closed_issue.visit!
Page::Project::Issue::Show.perform do |issue_page|
@@ -51,7 +51,7 @@ module QA
# The following example is excluded from running in `review-qa-smoke` job
# as it proved to be flaky when running against Review App
# See https://gitlab.com/gitlab-com/www-gitlab-com/-/issues/11568#note_621999351
- it 'comments on an issue with an attachment', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1742', except: { job: 'review-qa-smoke' } do
+ it 'comments on an issue with an attachment', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1599', except: { job: 'review-qa-smoke' } do
Page::Project::Issue::Show.perform do |show|
show.comment('See attached image for scale', attachment: file_to_attach)
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/custom_issue_template_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/custom_issue_template_spec.rb
index 5f5fe161e71..5ad590f4011 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/custom_issue_template_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/custom_issue_template_spec.rb
@@ -28,7 +28,7 @@ module QA
end
end
- it 'creates an issue via custom template', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1229' do
+ it 'creates an issue via custom template', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1612' do
Resource::Issue.fabricate_via_browser_ui! do |issue|
issue.project = template_project
issue.template = template_name
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/export_as_csv_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/export_as_csv_spec.rb
index a23474ad6f2..3914dbf4cd2 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/export_as_csv_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/export_as_csv_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
RSpec.describe 'Plan', :reliable do
describe 'Issues list' do
@@ -24,7 +22,7 @@ module QA
Page::Project::Menu.perform(&:click_issues)
end
- it 'successfully exports issues list as CSV', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1141' do
+ it 'successfully exports issues list as CSV', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1210' do
Page::Project::Issue::Index.perform do |index|
index.click_export_as_csv_button
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb
index e275c3decd3..f31a8e69f83 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb
@@ -9,7 +9,7 @@ module QA
Resource::Issue.fabricate_via_api!.visit!
end
- it 'filters comments and activities in an issue', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/425' do
+ it 'filters comments and activities in an issue', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1577' do
Page::Project::Issue::Show.perform do |show|
my_own_comment = "My own comment"
made_the_issue_confidential = "made the issue confidential"
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb
index ff33f9d4824..8cef592029e 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb
@@ -13,7 +13,7 @@ module QA
end.project.visit!
end
- it 'shows issue suggestions when creating a new issue', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1175' do
+ it 'shows issue suggestions when creating a new issue', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1179' do
Page::Project::Show.perform(&:go_to_new_issue)
Page::Project::Issue::New.perform do |new_page|
new_page.fill_title("issue")
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/jira_issue_import_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/jira_issue_import_spec.rb
index 1455847277e..57ef09ab347 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/jira_issue_import_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/jira_issue_import_spec.rb
@@ -14,7 +14,7 @@ module QA
end
end
- it 'imports issues from Jira', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/896' do
+ it 'imports issues from Jira', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1321' do
set_up_jira_integration
import_jira_issues
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb
index 45222d2ec7e..2d7fe6864aa 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb
@@ -23,7 +23,7 @@ module QA
end.visit!
end
- it 'mentions another user in an issue', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1166' do
+ it 'mentions another user in an issue', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1186' do
Page::Project::Issue::Show.perform do |show|
at_username = "@#{user.username}"
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/real_time_assignee_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/real_time_assignee_spec.rb
index 44a361df34d..268ea975d32 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/real_time_assignee_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/real_time_assignee_spec.rb
@@ -28,7 +28,7 @@ module QA
Runtime::Feature.disable(:invite_members_group_modal, project: project)
end
- it 'update without refresh', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1048' do
+ it 'update without refresh', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1644' do
issue = Resource::Issue.fabricate_via_api! do |issue|
issue.project = project
issue.assignee_ids = [user1.id]
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue_boards/focus_mode_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue_boards/focus_mode_spec.rb
index 8f17a25012b..63e707a4d27 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue_boards/focus_mode_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue_boards/focus_mode_spec.rb
@@ -13,7 +13,7 @@ module QA
Flow::Login.sign_in
end
- it 'focuses on issue board', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1176' do
+ it 'focuses on issue board', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1178' do
project.visit!
Page::Project::Menu.perform(&:go_to_boards)
diff --git a/qa/qa/specs/features/browser_ui/2_plan/milestone/create_group_milestone_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/milestone/create_group_milestone_spec.rb
index 8c328abcbe9..9097dc07b04 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/milestone/create_group_milestone_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/milestone/create_group_milestone_spec.rb
@@ -14,7 +14,7 @@ module QA
Flow::Login.sign_in
end
- it 'creates a group milestone', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1148' do
+ it 'creates a group milestone', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1203' do
group_milestone = Resource::GroupMilestone.fabricate_via_browser_ui! do |milestone|
milestone.title = title
milestone.description = description
diff --git a/qa/qa/specs/features/browser_ui/2_plan/milestone/create_project_milestone_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/milestone/create_project_milestone_spec.rb
index 78d1471f484..a6aee3e2b06 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/milestone/create_project_milestone_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/milestone/create_project_milestone_spec.rb
@@ -14,7 +14,7 @@ module QA
Flow::Login.sign_in
end
- it 'creates a project milestone', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1165' do
+ it 'creates a project milestone', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1187' do
project_milestone = Resource::ProjectMilestone.fabricate_via_browser_ui! do |milestone|
milestone.title = title
milestone.description = description
diff --git a/qa/qa/specs/features/browser_ui/2_plan/related_issues/related_issues_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/related_issues/related_issues_spec.rb
index d907cfaab6d..2bb686c2694 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/related_issues/related_issues_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/related_issues/related_issues_spec.rb
@@ -25,7 +25,7 @@ module QA
Flow::Login.sign_in
end
- it 'relates and unrelates one issue to/from another', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1172' do
+ it 'relates and unrelates one issue to/from another', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1180' do
issue_1.visit!
Page::Project::Issue::Show.perform do |show|
diff --git a/qa/qa/specs/features/browser_ui/2_plan/transient/comment_on_discussion_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/transient/comment_on_discussion_spec.rb
index f2e4a320e04..6d73848b8f8 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/transient/comment_on_discussion_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/transient/comment_on_discussion_spec.rb
@@ -16,7 +16,7 @@ module QA
Flow::Login.sign_in
end
- it 'comments with mention on a discussion in an issue', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1753' do
+ it 'comments with mention on a discussion in an issue', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1816' do
Runtime::Env.transient_trials.times do |i|
QA::Runtime::Logger.info("Transient bug test action - Trial #{i}")
diff --git a/qa/qa/specs/features/browser_ui/3_create/design_management/add_design_content_spec.rb b/qa/qa/specs/features/browser_ui/3_create/design_management/add_design_content_spec.rb
index 2e48899742b..b26f2338f45 100644
--- a/qa/qa/specs/features/browser_ui/3_create/design_management/add_design_content_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/design_management/add_design_content_spec.rb
@@ -12,7 +12,7 @@ module QA
Flow::Login.sign_in
end
- it 'user adds a design and annotates it', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1692' do
+ it 'user adds a design and annotates it', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1290' do
issue.visit!
Page::Project::Issue::Show.perform do |issue|
diff --git a/qa/qa/specs/features/browser_ui/3_create/design_management/archive_design_content_spec.rb b/qa/qa/specs/features/browser_ui/3_create/design_management/archive_design_content_spec.rb
index 6afc7549c59..e7954cefffc 100644
--- a/qa/qa/specs/features/browser_ui/3_create/design_management/archive_design_content_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/design_management/archive_design_content_spec.rb
@@ -23,7 +23,7 @@ module QA
Flow::Login.sign_in
end
- it 'user archives a design', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1761' do
+ it 'user archives a design', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1812' do
third_design.issue.visit!
Page::Project::Issue::Show.perform do |issue|
diff --git a/qa/qa/specs/features/browser_ui/3_create/design_management/modify_design_content_spec.rb b/qa/qa/specs/features/browser_ui/3_create/design_management/modify_design_content_spec.rb
index dfdc9b7c9b4..7192e68d1cd 100644
--- a/qa/qa/specs/features/browser_ui/3_create/design_management/modify_design_content_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/design_management/modify_design_content_spec.rb
@@ -13,7 +13,7 @@ module QA
Flow::Login.sign_in
end
- it 'user adds a design and modifies it', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1760' do
+ it 'user adds a design and modifies it', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1813' do
design.issue.visit!
Page::Project::Issue::Show.perform do |issue|
diff --git a/qa/qa/specs/features/browser_ui/3_create/jenkins/jenkins_build_status_spec.rb b/qa/qa/specs/features/browser_ui/3_create/jenkins/jenkins_build_status_spec.rb
index 734ff160937..245b33c6691 100644
--- a/qa/qa/specs/features/browser_ui/3_create/jenkins/jenkins_build_status_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/jenkins/jenkins_build_status_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require 'securerandom'
module QA
RSpec.describe 'Create', :requires_admin, :skip_live_env, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/195179', type: :flaky } do
@@ -26,7 +25,7 @@ module QA
setup_jenkins
end
- it 'integrates and displays build status for MR pipeline in GitLab', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/719' do
+ it 'integrates and displays build status for MR pipeline in GitLab', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1410' do
login_to_gitlab
setup_project_integration_with_jenkins
diff --git a/qa/qa/specs/features/browser_ui/3_create/jira/jira_basic_integration_spec.rb b/qa/qa/specs/features/browser_ui/3_create/jira/jira_basic_integration_spec.rb
index 449795f9707..b2efdb11e9a 100644
--- a/qa/qa/specs/features/browser_ui/3_create/jira/jira_basic_integration_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/jira/jira_basic_integration_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- include Support::Api
+ include Support::API
describe 'Jira integration', :jira, :orchestrated, :requires_admin do
let(:jira_project_key) { 'JITP' }
@@ -36,7 +36,7 @@ module QA
expect(page).not_to have_text("Requests to the local network are not allowed")
end
- it 'closes an issue via pushing a commit', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/827' do
+ it 'closes an issue via pushing a commit', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1362' do
issue_key = Vendor::Jira::JiraAPI.perform do |jira_api|
jira_api.create_issue(jira_project_key)
end
@@ -46,7 +46,7 @@ module QA
expect_issue_done(issue_key)
end
- it 'closes an issue via a merge request', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/828' do
+ it 'closes an issue via a merge request', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1361' do
issue_key = Vendor::Jira::JiraAPI.perform do |jira_api|
jira_api.create_issue(jira_project_key)
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_a_merge_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_a_merge_spec.rb
index 16afa3be62a..826c1a45ff4 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_a_merge_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_a_merge_spec.rb
@@ -22,7 +22,7 @@ module QA
Flow::Login.sign_in
end
- it 'creates a merge request', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1616' do
+ it 'creates a merge request', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1836' do
feature_mr.visit!
Page::MergeRequest::Show.perform do |merge_request|
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb
index 41746e84862..b2e54680560 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb
@@ -29,7 +29,7 @@ module QA
commit.visit!
end
- it 'creates a merge request', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1752' do
+ it 'creates a merge request', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1817' do
Page::Project::Commit::Show.perform(&:cherry_pick_commit)
Page::MergeRequest::New.perform(&:create_merge_request)
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb
index 082d001b716..79cc91acc79 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb
@@ -19,11 +19,12 @@ module QA
it(
'creates a basic merge request',
:smoke,
- testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1850'
+ testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1590'
) do
Resource::MergeRequest.fabricate_via_browser_ui! do |merge_request|
merge_request.project = project
merge_request.title = merge_request_title
+ merge_request.assignee = 'me'
merge_request.description = merge_request_description
end
@@ -35,7 +36,7 @@ module QA
it(
'creates a merge request with a milestone and label',
- testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/514'
+ testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1542'
) do
gitlab_account_username = "@#{Runtime::User.username}"
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb
index d8341eff41d..01c75d95683 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb
@@ -29,7 +29,7 @@ module QA
end
end
- it 'creates a merge request via custom template', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1230' do
+ it 'creates a merge request via custom template', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1680' do
Resource::MergeRequest.fabricate_via_browser_ui! do |merge_request|
merge_request.project = template_project
merge_request.title = merge_request_title
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb
index a2b011bc61c..4090837d5c9 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb
@@ -4,7 +4,7 @@ module QA
RSpec.describe 'Create', quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/332588', type: :investigating } do
describe 'Merge request creation from fork' do
# TODO: Please add this back to :smoke suite as soon as https://gitlab.com/gitlab-org/gitlab/-/issues/332588 is addressed
- it 'can merge feature branch fork to mainline', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1701' do
+ it 'can merge feature branch fork to mainline', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1305' do
merge_request = Resource::MergeRequestFromFork.fabricate_via_browser_ui! do |merge_request|
merge_request.fork_branch = 'feature-branch'
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb
index 2b1ac75b9f5..3a5850c0047 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb
@@ -30,7 +30,7 @@ module QA
content: <<~EOF
test:
tags: ["runner-for-#{project.name}"]
- script: sleep 10
+ script: sleep 20
only:
- merge_requests
EOF
@@ -87,11 +87,11 @@ module QA
end
end
- context 'when merging once', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1684' do
+ context 'when merging once', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1834' do
it_behaves_like 'merge when pipeline succeeds'
end
- context 'when merging several times', :transient, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1684' do
+ context 'when merging several times', :transient, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1917' do
it_behaves_like 'merge when pipeline succeeds', repeat: Runtime::Env.transient_trials
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb
index ca0eeb2403c..81fb187df85 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb
@@ -1,15 +1,16 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create', quarantine: { only: { subdomain: :staging }, issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/323990', type: :flaky } do
+ RSpec.describe 'Create' do
describe 'Merge request rebasing' do
- it 'user rebases source branch of merge request', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1800' do
+ let(:merge_request) { Resource::MergeRequest.fabricate_via_api! }
+
+ before do
Flow::Login.sign_in
+ end
- project = Resource::Project.fabricate_via_api! do |project|
- project.name = "only-fast-forward"
- end
- project.visit!
+ it 'user rebases source branch of merge request', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1596' do
+ merge_request.project.visit!
Page::Project::Menu.perform(&:go_to_general_settings)
Page::Project::Settings::Main.perform do |main|
@@ -18,13 +19,8 @@ module QA
end
end
- merge_request = Resource::MergeRequest.fabricate! do |merge_request|
- merge_request.project = project
- merge_request.title = 'Needs rebasing'
- end
-
Resource::Repository::ProjectPush.fabricate! do |push|
- push.project = project
+ push.project = merge_request.project
push.file_name = "other.txt"
push.file_content = "New file added!"
push.new_branch = false
@@ -33,7 +29,7 @@ module QA
merge_request.visit!
Page::MergeRequest::Show.perform do |merge_request|
- expect(merge_request).to have_content('Needs rebasing')
+ expect(merge_request).to have_content('Merge blocked: the source branch must be rebased onto the target branch.')
expect(merge_request).to be_fast_forward_not_possible
expect(merge_request).not_to have_merge_button
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb
index 089b87be423..a24ba9ac45a 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb
@@ -27,7 +27,7 @@ module QA
commit.visit!
end
- it 'creates a merge request', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1784' do
+ it 'creates a merge request', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1807' do
Page::Project::Commit::Show.perform(&:revert_commit)
Page::MergeRequest::New.perform(&:create_merge_request)
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/reverting_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/reverting_merge_request_spec.rb
index c05a3610b99..0ea294b8e51 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/reverting_merge_request_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/reverting_merge_request_spec.rb
@@ -1,7 +1,11 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
+ RSpec.describe 'Create', quarantine: {
+ only: { job: 'large-setup' },
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338324',
+ type: :stale
+ } do
describe 'Merged merge request' do
let(:project) do
Resource::Project.fabricate_via_api! do |project|
@@ -19,7 +23,7 @@ module QA
Flow::Login.sign_in
end
- it 'can be reverted', :can_use_large_setup, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1745' do
+ it 'can be reverted', :can_use_large_setup, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1818' do
revertable_merge_request.visit!
Page::MergeRequest::Show.perform do |merge_request|
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb
index 366671d3385..9fcf6b3db71 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb
@@ -31,7 +31,7 @@ module QA
merge_request.visit!
end
- it 'user squashes commits while merging', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/418' do
+ it 'user squashes commits while merging', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1583' do
Page::MergeRequest::Show.perform do |merge_request_page|
merge_request_page.retry_on_exception(reload: true) do
expect(merge_request_page).to have_text('to be squashed')
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/batch_suggestion_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/batch_suggestion_spec.rb
index 05e274de820..5cebbb32ade 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/batch_suggestion_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/batch_suggestion_spec.rb
@@ -46,7 +46,7 @@ module QA
merge_request.visit!
end
- it 'applies multiple suggestions', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1177' do
+ it 'applies multiple suggestions', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1838' do
Page::MergeRequest::Show.perform do |merge_request|
merge_request.click_diffs_tab
4.times { merge_request.add_suggestion_to_batch }
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/custom_commit_suggestion_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/custom_commit_suggestion_spec.rb
index ad12a3ec334..339010cd1df 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/custom_commit_suggestion_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/custom_commit_suggestion_spec.rb
@@ -43,7 +43,7 @@ module QA
merge_request.visit!
end
- it 'applies a single suggestion with a custom message' do
+ it 'applies a single suggestion with a custom message', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1815' do
Page::MergeRequest::Show.perform do |merge_request|
merge_request.click_diffs_tab
merge_request.apply_suggestion_with_message(commit_message)
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_diff_patch_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_diff_patch_spec.rb
index 37008e6d507..fb30d47135e 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_diff_patch_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_diff_patch_spec.rb
@@ -15,7 +15,7 @@ module QA
merge_request.visit!
end
- it 'views the merge request email patches', :can_use_large_setup, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1689' do
+ it 'views the merge request email patches', :can_use_large_setup, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1585' do
Page::MergeRequest::Show.perform(&:view_email_patches)
expect(page.text).to start_with('From')
@@ -23,7 +23,7 @@ module QA
expect(page).to have_content("diff --git a/#{merge_request.file_name} b/#{merge_request.file_name}")
end
- it 'views the merge request plain diff', :can_use_large_setup, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/417' do
+ it 'views the merge request plain diff', :can_use_large_setup, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1584' do
Page::MergeRequest::Show.perform(&:view_plain_diff)
expect(page.text).to start_with('diff')
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_merge_ref_diff_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_merge_ref_diff_spec.rb
index 24b92164060..c7942c5c2e4 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_merge_ref_diff_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_merge_ref_diff_spec.rb
@@ -32,7 +32,7 @@ module QA
merge_request.visit!
end
- it 'views the merge-ref diff by default' do
+ it 'views the merge-ref diff by default', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1902' do
Page::MergeRequest::Show.perform do |mr_page|
mr_page.click_diffs_tab
mr_page.click_target_version_dropdown
@@ -57,7 +57,7 @@ module QA
merge_request.visit!
end
- it 'views the merge-base diff by default' do
+ it 'views the merge-base diff by default', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1903' do
Page::MergeRequest::Show.perform do |mr_page|
mr_page.click_diffs_tab
mr_page.click_target_version_dropdown
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb
index c02632c2c60..3da73c8fa72 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
RSpec.describe 'Create' do
describe 'File templates' do
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb
index 639702f9148..9448cd13f53 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb
@@ -61,7 +61,7 @@ module QA
project.visit!
end
- it 'lists branches correctly after CRUD operations', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1688' do
+ it 'lists branches correctly after CRUD operations', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1588' do
Page::Project::Menu.perform(&:go_to_repository_branches)
expect(page).to have_content(master_branch)
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb
index db31cadb37d..39fb18f2051 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb
@@ -16,7 +16,7 @@ module QA
end
context 'when branch name contains slash, hash, double dash, and capital letter' do
- it 'renders repository file tree correctly', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1780' do
+ it 'renders repository file tree correctly', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1809' do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.branch = branch_name
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb
index fb9e42a6960..1fa95eda3f0 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb
@@ -28,7 +28,7 @@ module QA
project.wait_for_push_new_branch
end
- it 'user performs a deep clone', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/475' do
+ it 'user performs a deep clone', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1546' do
Git::Repository.perform do |repository|
repository.uri = project.repository_http_location.uri
repository.use_default_credentials
@@ -39,7 +39,7 @@ module QA
end
end
- it 'user performs a shallow clone', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/411' do
+ it 'user performs a shallow clone', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1589' do
Git::Repository.perform do |repository|
repository.uri = project.repository_http_location.uri
repository.use_default_credentials
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/file/create_file_via_web_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/file/create_file_via_web_spec.rb
index cd333b3cea2..6d7e1b4f6df 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/file/create_file_via_web_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/file/create_file_via_web_spec.rb
@@ -11,7 +11,7 @@ module QA
Flow::Login.sign_in
end
- it 'user creates a file via the Web', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1093' do
+ it 'user creates a file via the Web', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1633' do
Resource::File.fabricate_via_browser_ui! do |file|
file.name = file_name
file.content = file_content
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/file/delete_file_via_web_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/file/delete_file_via_web_spec.rb
index 903001aa4f0..4667dccb9a1 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/file/delete_file_via_web_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/file/delete_file_via_web_spec.rb
@@ -12,7 +12,7 @@ module QA
file.visit!
end
- it 'user deletes a file via the Web', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1095' do
+ it 'user deletes a file via the Web', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1631' do
Page::File::Show.perform do |file|
file.click_delete
file.add_commit_message(commit_message_for_delete)
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/file/edit_file_via_web_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/file/edit_file_via_web_spec.rb
index 0da774b557f..47aebcbf349 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/file/edit_file_via_web_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/file/edit_file_via_web_spec.rb
@@ -13,7 +13,7 @@ module QA
file.visit!
end
- it 'user edits a file via the Web', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1094' do
+ it 'user edits a file via the Web', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1632' do
Page::File::Show.perform(&:click_edit)
Page::File::Form.perform do |file|
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/file/file_with_unusual_name_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/file/file_with_unusual_name_spec.rb
index 98d0a3c5706..0a01afd97d8 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/file/file_with_unusual_name_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/file/file_with_unusual_name_spec.rb
@@ -16,7 +16,7 @@ module QA
end
context 'when file name starts with a dash and contains hash, semicolon, colon, and question mark' do
- it 'renders repository file tree correctly', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1779' do
+ it 'renders repository file tree correctly', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1810' do
Resource::File.fabricate_via_api! do |file|
file.project = project
file.commit_message = 'Add new file'
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb
index 0f6edca654b..a53bb197b09 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb
@@ -23,7 +23,7 @@ module QA
parent_project.add_member(user)
end
- it 'creates a 2nd fork after moving the parent project', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/713' do
+ it 'creates a 2nd fork after moving the parent project', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1413' do
Flow::Login.sign_in(as: user)
fork_project.visit!
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb
index 3440b462302..48bfe56e91e 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb
@@ -3,7 +3,7 @@
module QA
RSpec.describe 'Create' do
describe 'Push over HTTP using Git protocol version 2', :requires_git_protocol_v2 do
- it 'user pushes to the repository', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/469' do
+ it 'user pushes to the repository', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1548' do
Flow::Login.sign_in
# Create a project to push to
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb
index ef3d45724db..467d9b2487d 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb
@@ -27,7 +27,7 @@ module QA
Page::Main::Menu.perform(&:sign_out_if_signed_in)
end
- it 'user pushes to the repository', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1763' do
+ it 'user pushes to the repository', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1606' do
project = Resource::Project.fabricate_via_api! do |project|
project.name = 'git-protocol-project'
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb
index 41fc20cfa5c..6fdf7f424ee 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb
@@ -3,7 +3,7 @@
module QA
RSpec.describe 'Create' do
describe 'Git push over HTTP', :smoke do
- it 'user using a personal access token pushes code to the repository', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1848' do
+ it 'user using a personal access token pushes code to the repository', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1573' do
Flow::Login.sign_in
access_token = Resource::PersonalAccessToken.fabricate!.token
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb
index e4a492d3487..d8972d4f37a 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb
@@ -3,7 +3,7 @@
module QA
RSpec.describe 'Create' do
describe 'Push mirror a repository over HTTP' do
- it 'configures and syncs LFS objects for a (push) mirrored repository', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1075' do
+ it 'configures and syncs LFS objects for a (push) mirrored repository', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1224' do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.perform(&:sign_in_using_credentials)
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb
index f01a3b21eee..ec63ed9cdf1 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb
@@ -3,7 +3,7 @@
module QA
RSpec.describe 'Create' do
describe 'Push mirror a repository over HTTP' do
- it 'configures and syncs a (push) mirrored repository', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/414' do
+ it 'configures and syncs a (push) mirrored repository', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1587' do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.perform(&:sign_in_using_credentials)
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb
index 1423e3c45ce..727a9e27c63 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb
@@ -9,7 +9,7 @@ module QA
# tests are run in parallel).
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/218620#note_361634705
- include Support::Api
+ include Support::API
before(:context) do
@project = Resource::Project.fabricate_via_api! do |p|
@@ -26,7 +26,7 @@ module QA
set_file_size_limit(nil)
end
- it 'push successful when the file size is under the limit', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/456' do
+ it 'push successful when the file size is under the limit', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1556' do
set_file_size_limit(5)
retry_on_fail do
@@ -36,7 +36,7 @@ module QA
end
end
- it 'push fails when the file size is above the limit', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/458' do
+ it 'push fails when the file size is above the limit', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1554' do
set_file_size_limit(2)
retry_on_fail do
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb
index 861efa8b45a..4c294f21859 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb
@@ -3,7 +3,7 @@
module QA
RSpec.describe 'Create' do
describe 'Git push over HTTP' do
- it 'user pushes code to the repository', :smoke, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1702' do
+ it 'user pushes code to the repository', :smoke, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1576' do
Flow::Login.sign_in
Resource::Repository::ProjectPush.fabricate! do |push|
@@ -18,7 +18,7 @@ module QA
end
end
- it 'pushes to a project using a specific Praefect repository storage', :smoke, :requires_admin, :requires_praefect, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/742' do
+ it 'pushes to a project using a specific Praefect repository storage', :smoke, :requires_admin, :requires_praefect, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1389' do
Flow::Login.sign_in_as_admin
project = Resource::Project.fabricate_via_api! do |storage_project|
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb
index 9eeb762e548..be0d48e5ab9 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb
@@ -26,7 +26,7 @@ module QA
Flow::Login.sign_in
end
- it 'pushes code to the repository via SSH', :smoke, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1678' do
+ it 'pushes code to the repository via SSH', :smoke, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1283' do
Resource::Repository::ProjectPush.fabricate! do |push|
push.project = project
push.ssh_key = @key
@@ -41,7 +41,7 @@ module QA
end
end
- it 'pushes multiple branches and tags together', :smoke, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1679' do
+ it 'pushes multiple branches and tags together', :smoke, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1282' do
branches = []
tags = []
Git::Repository.perform do |repository|
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb
index ce7fdf379a4..318d905c149 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb
@@ -18,24 +18,24 @@ module QA
end
context 'when developers and maintainers are allowed to push to a protected branch' do
- it 'user with push rights successfully pushes to the protected branch', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/447' do
+ it 'user with push rights successfully pushes to the protected branch', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1563' do
create_protected_branch(allowed_to_push: {
roles: Resource::ProtectedBranch::Roles::DEVS_AND_MAINTAINERS
})
push = push_new_file(branch_name)
- expect(push.output).to match(/remote: To create a merge request for protected-branch, visit/)
+ expect(push.output).to match(/To create a merge request for protected-branch, visit/)
end
end
context 'when developers and maintainers are not allowed to push to a protected branch' do
- it 'user without push rights fails to push to the protected branch', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/449' do
+ it 'user without push rights fails to push to the protected branch', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1562' do
create_protected_branch(allowed_to_push: {
roles: Resource::ProtectedBranch::Roles::NO_ONE
})
- expect { push_new_file(branch_name) }.to raise_error(QA::Support::Run::CommandError, /remote: GitLab: You are not allowed to push code to protected branches on this project\.([\s\S]+)\[remote rejected\] #{branch_name} -> #{branch_name} \(pre-receive hook declined\)/)
+ expect { push_new_file(branch_name) }.to raise_error(QA::Support::Run::CommandError, /You are not allowed to push code to protected branches on this project\.([\s\S]+)\[remote rejected\] #{branch_name} -> #{branch_name} \(pre-receive hook declined\)/)
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb
index a90bb920107..3f488a1610d 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb
@@ -9,7 +9,7 @@ module QA
Flow::Login.sign_in
end
- it 'user can add an SSH key', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1685' do
+ it 'user can add an SSH key', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1304' do
key = Resource::SSHKey.fabricate_via_browser_ui! do |resource|
resource.title = key_title
end
@@ -20,7 +20,7 @@ module QA
# Note this context ensures that the example it contains is executed after the example above. Be aware of the order of execution if you add new examples in either context.
context 'after adding an ssh key' do
- it 'can delete an ssh key', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1686' do
+ it 'can delete an ssh key', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1303' do
Page::Main::Menu.perform(&:click_edit_profile_link)
Page::Profile::Menu.perform(&:click_ssh_keys)
Page::Profile::SSHKeys.perform do |ssh_keys|
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/user_views_commit_diff_patch_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/user_views_commit_diff_patch_spec.rb
index cd6ffdf4571..d445f4d091b 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/user_views_commit_diff_patch_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/user_views_commit_diff_patch_spec.rb
@@ -43,7 +43,7 @@ module QA
find('pre').text
end
- it 'user views raw email patch', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/442' do
+ it 'user views raw email patch', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1566' do
view_commit
Page::Project::Commit::Show.perform(&:select_email_patches)
@@ -53,7 +53,7 @@ module QA
expect(page).to have_content('diff --git a/second b/second')
end
- it 'user views raw commit diff', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/439' do
+ it 'user views raw commit diff', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1568' do
view_commit
Page::Project::Commit::Show.perform(&:select_plain_diff)
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb
index 70880011985..b41e90fa834 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb
@@ -39,7 +39,7 @@ module QA
ssh_key.remove_via_api!
end
- it 'clones, pushes, and pulls a snippet over HTTP, edits via UI', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1748' do
+ it 'clones, pushes, and pulls a snippet over HTTP, edits via UI', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1363' do
push = Resource::Repository::Push.fabricate! do |push|
push.repository_http_uri = repository_uri_http
push.file_name = new_file
@@ -70,7 +70,7 @@ module QA
snippet.remove_via_api!
end
- it 'clones, pushes, and pulls a snippet over SSH, deletes via UI', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1747' do
+ it 'clones, pushes, and pulls a snippet over SSH, deletes via UI', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1364' do
push = Resource::Repository::Push.fabricate! do |push|
push.repository_ssh_uri = repository_uri_ssh
push.ssh_key = ssh_key
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb
index 9d90ff189c6..e8b2ffe1f14 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb
@@ -40,7 +40,7 @@ module QA
ssh_key.remove_via_api!
end
- it 'clones, pushes, and pulls a project snippet over HTTP, edits via UI', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1725' do
+ it 'clones, pushes, and pulls a project snippet over HTTP, edits via UI', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1359' do
Resource::Repository::Push.fabricate! do |push|
push.repository_http_uri = repository_uri_http
push.file_name = new_file
@@ -71,7 +71,7 @@ module QA
snippet.remove_via_api!
end
- it 'clones, pushes, and pulls a project snippet over SSH, deletes via UI', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1794' do
+ it 'clones, pushes, and pulls a project snippet over SSH, deletes via UI', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1360' do
Resource::Repository::Push.fabricate! do |push|
push.repository_ssh_uri = repository_uri_ssh
push.ssh_key = ssh_key
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_spec.rb
index ae8f34f9845..1080d8ab849 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_spec.rb
@@ -3,7 +3,7 @@
module QA
RSpec.describe 'Create' do # convert back to a smoke test once proved to be stable
describe 'Personal snippet creation' do
- it 'user creates a personal snippet', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1704' do
+ it 'user creates a personal snippet', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1357' do
Flow::Login.sign_in
Page::Main::Menu.perform do |menu|
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_with_multiple_files_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_with_multiple_files_spec.rb
index 8ff3222f065..525fc5799a9 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_with_multiple_files_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_with_multiple_files_spec.rb
@@ -3,7 +3,7 @@
module QA
RSpec.describe 'Create' do
describe 'Multiple file snippet' do
- it 'creates a personal snippet with multiple files', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/842' do
+ it 'creates a personal snippet with multiple files', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1654' do
Flow::Login.sign_in
Page::Main::Menu.perform do |menu|
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_spec.rb
index 8c44cd6d642..e4c2488e8df 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_spec.rb
@@ -3,7 +3,7 @@
module QA
RSpec.describe 'Create' do # to be converted to a smoke test once proved to be stable
describe 'Project snippet creation' do
- it 'user creates a project snippet', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/839' do
+ it 'user creates a project snippet', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1358' do
Flow::Login.sign_in
Resource::ProjectSnippet.fabricate_via_browser_ui! do |snippet|
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_with_multiple_files_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_with_multiple_files_spec.rb
index 7b4ec573f53..3298989cc12 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_with_multiple_files_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_with_multiple_files_spec.rb
@@ -3,7 +3,7 @@
module QA
RSpec.describe 'Create' do
describe 'Multiple file snippet' do
- it 'creates a project snippet with multiple files', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1024' do
+ it 'creates a project snippet with multiple files', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1648' do
Flow::Login.sign_in
Resource::ProjectSnippet.fabricate_via_browser_ui! do |snippet|
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/share_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/share_snippet_spec.rb
index 3973e0aacad..53e1e8e2e02 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/share_snippet_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/share_snippet_spec.rb
@@ -21,7 +21,7 @@ module QA
end
context 'when the snippet is public' do
- it 'can be shared with not signed-in users', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1016' do
+ it 'can be shared with not signed-in users', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1248' do
snippet.visit!
sharing_link = Page::Dashboard::Snippet::Show.perform do |snippet|
@@ -43,7 +43,7 @@ module QA
end
context 'when the snippet is changed to private' do
- it 'does not display Embed/Share dropdown', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1015' do
+ it 'does not display Embed/Share dropdown', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1249' do
snippet.visit!
Page::Dashboard::Snippet::Show.perform do |snippet|
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb
index 1e3cb0e2ffc..70c9c9beeb8 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
RSpec.describe 'Create' do
describe 'Web IDE file templates' do
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb
index 293c9043266..b92c8e881ab 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb
@@ -35,7 +35,7 @@ module QA
Page::Project::Show.perform(&:open_web_ide!)
end
- it 'throws an error', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1615' do
+ it 'throws an error', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1618' do
Page::Project::WebIDE::Edit.perform do |ide|
ide.add_directory(directory_name)
end
@@ -51,7 +51,7 @@ module QA
Page::Project::Show.perform(&:open_web_ide!)
end
- it 'shows in the tree view but cannot be committed', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1614' do
+ it 'shows in the tree view but cannot be committed', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1619' do
Page::Project::WebIDE::Edit.perform do |ide|
ide.add_directory(directory_name)
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb
index f7a2e3081fb..2e37cc98555 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb
@@ -16,7 +16,7 @@ module QA
Flow::Login.sign_in
end
- it "creates the first file in an empty project via Web IDE", testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/847' do
+ it "creates the first file in an empty project via Web IDE", testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1353' do
project.visit!
Page::Project::Show.perform(&:create_first_new_file!)
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb
index c7fc01303b7..c648fecf847 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb
@@ -18,7 +18,7 @@ module QA
project.remove_via_api!
end
- it 'can link to a specific line of code in Web IDE', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1102' do
+ it 'can link to a specific line of code in Web IDE', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1844' do
project.visit!
Page::Project::Show.perform(&:open_web_ide!)
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb
index ce1b6f4a3ec..99a9bc5b2d0 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb
@@ -14,7 +14,7 @@ module QA
let(:user) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) }
context 'when no fork is present' do
- it 'suggests to create a fork when a user clicks Web IDE in the main project', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1697' do
+ it 'suggests to create a fork when a user clicks Web IDE in the main project', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1289' do
Flow::Login.sign_in(as: user)
parent_project.visit!
@@ -34,7 +34,7 @@ module QA
end
end
- it 'opens the fork when a user clicks Web IDE in the main project', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1698' do
+ it 'opens the fork when a user clicks Web IDE in the main project', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1288' do
Flow::Login.sign_in(as: user)
fork_project.upstream.visit!
Page::Project::Show.perform do |project_page|
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb
index 1789e20e216..061ab66b271 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb
@@ -49,7 +49,7 @@ module QA
merge_request.visit!
end
- it 'opens and edits a multi-file merge request in Web IDE from Diff Tab', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/997' do
+ it 'opens and edits a multi-file merge request in Web IDE from Diff Tab', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1649' do
Page::MergeRequest::Show.perform do |show|
show.click_diffs_tab
show.edit_file_in_web_ide('file1')
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb
index 4e1b6b6094e..7135e04e457 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb
@@ -20,7 +20,7 @@ module QA
merge_request.visit!
end
- it 'opens and edits a merge request in Web IDE', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/705' do
+ it 'opens and edits a merge request in Web IDE', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1420' do
Page::MergeRequest::Show.perform do |show|
show.click_open_in_web_ide
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb
index 0a342664dd2..705ee954bcb 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb
@@ -22,7 +22,7 @@ module QA
context 'when a file with the same name already exists' do
let(:file_name) { 'README.md' }
- it 'throws an error', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1136' do
+ it 'throws an error', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1214' do
Page::Project::WebIDE::Edit.perform do |ide|
ide.upload_file(file_path)
end
@@ -34,7 +34,7 @@ module QA
context 'when the file is a text file' do
let(:file_name) { 'text_file.txt' }
- it 'shows the Edit tab with the text', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1138' do
+ it 'shows the Edit tab with the text', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1212' do
Page::Project::WebIDE::Edit.perform do |ide|
ide.upload_file(file_path)
@@ -52,7 +52,7 @@ module QA
context 'when the file is binary' do
let(:file_name) { 'logo_sample.svg' }
- it 'shows a Download button', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1137' do
+ it 'shows a Download button', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1213' do
Page::Project::WebIDE::Edit.perform do |ide|
ide.upload_file(file_path)
@@ -70,7 +70,7 @@ module QA
context 'when the file is an image' do
let(:file_name) { 'dk.png' }
- it 'shows an image viewer', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1139' do
+ it 'shows an image viewer', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1211' do
Page::Project::WebIDE::Edit.perform do |ide|
ide.upload_file(file_path)
diff --git a/qa/qa/specs/features/browser_ui/3_create/wiki/content_editor_spec.rb b/qa/qa/specs/features/browser_ui/3_create/wiki/content_editor_spec.rb
index 2a46604f8ac..bd4b82d8ea0 100644
--- a/qa/qa/specs/features/browser_ui/3_create/wiki/content_editor_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/wiki/content_editor_spec.rb
@@ -16,7 +16,7 @@ module QA
initial_wiki.project.remove_via_api!
end
- it 'creates a formatted Wiki page with an image uploaded', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1861' do
+ it 'creates a formatted Wiki page with an image uploaded', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1919' do
initial_wiki.visit!
Page::Project::Wiki::Show.perform(&:click_new_page)
diff --git a/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_content_creation_spec.rb b/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_content_creation_spec.rb
index 70959dd0200..40188fae06c 100644
--- a/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_content_creation_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_content_creation_spec.rb
@@ -15,7 +15,7 @@ module QA
Flow::Login.sign_in
end
- it 'by adding a home page to the wiki', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/856' do
+ it 'by adding a home page to the wiki', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1347' do
project.visit!
Page::Project::Menu.perform(&:click_wiki)
@@ -35,7 +35,7 @@ module QA
end
end
- it 'by adding a second page to the wiki', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/855' do
+ it 'by adding a second page to the wiki', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1348' do
wiki.visit!
Page::Project::Wiki::Show.perform(&:click_new_page)
@@ -54,7 +54,7 @@ module QA
end
end
- it 'by adding a home page to the wiki using git push', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/853' do
+ it 'by adding a home page to the wiki using git push', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1350' do
empty_wiki = Resource::Wiki::ProjectPage.new do |empty_wiki|
empty_wiki.project = project
end
@@ -73,7 +73,7 @@ module QA
end
end
- it 'by adding a second page to the wiki using git push', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/854' do
+ it 'by adding a second page to the wiki using git push', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1349' do
Resource::Repository::WikiPush.fabricate! do |push|
push.file_name = "#{new_wiki_title}.md"
push.file_content = new_wiki_content
diff --git a/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_content_manipulation_spec.rb b/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_content_manipulation_spec.rb
index 9a6d7d08e7b..5b277d07fea 100644
--- a/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_content_manipulation_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_content_manipulation_spec.rb
@@ -14,7 +14,7 @@ module QA
Flow::Login.sign_in
end
- it 'by manipulating content on the page', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/857' do
+ it 'by manipulating content on the page', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1346' do
wiki.visit!
Page::Project::Wiki::Show.perform(&:click_edit)
@@ -33,7 +33,7 @@ module QA
end
end
- it 'by manipulating content on the page using git push', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/858' do
+ it 'by manipulating content on the page using git push', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1345' do
Resource::Repository::WikiPush.fabricate! do |push|
push.file_content = new_wiki_content
push.commit_message = commit_message
diff --git a/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_directory_management_spec.rb b/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_directory_management_spec.rb
index 1a46322d283..9784ad2e9c1 100644
--- a/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_directory_management_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_directory_management_spec.rb
@@ -10,7 +10,7 @@ module QA
Flow::Login.sign_in
end
- it 'has changed the directory', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/948' do
+ it 'has changed the directory', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1293' do
initial_wiki.visit!
Page::Project::Wiki::Show.perform(&:click_edit)
diff --git a/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_list_spec.rb b/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_list_spec.rb
index dcf52f7c744..c91fc8e10f7 100644
--- a/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_list_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_list_spec.rb
@@ -15,7 +15,7 @@ module QA
end
context 'Sidebar' do
- it 'has all expected links that work', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/903' do
+ it 'has all expected links that work', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1317' do
small_wiki.visit!
small_number_of_pages.times do |index|
@@ -35,7 +35,7 @@ module QA
end
context 'Page List' do
- it 'has all expected links that work', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/902' do
+ it 'has all expected links that work', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1318' do
large_wiki.visit!
Page::Project::Wiki::Show.perform(&:click_view_all_pages)
diff --git a/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_page_deletion_spec.rb b/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_page_deletion_spec.rb
index d2b18d81670..71ce042f0a3 100644
--- a/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_page_deletion_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_page_deletion_spec.rb
@@ -10,7 +10,7 @@ module QA
end
context 'Page deletion' do
- it 'has removed the deleted page correctly', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/921' do
+ it 'has removed the deleted page correctly', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1310' do
initial_wiki.visit!
Page::Project::Wiki::Show.perform(&:click_edit)
diff --git a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb
index 39cbd0028c0..c8b308d53ef 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb
@@ -16,7 +16,7 @@ module QA
add_ci_variable
end
- it 'user adds a CI variable', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1759' do
+ it 'user adds a CI variable', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1597' do
Page::Project::Settings::CiVariables.perform do |ci_variable|
expect(ci_variable).to have_text('VARIABLE_KEY')
expect(ci_variable).not_to have_text('some_CI_variable')
@@ -27,7 +27,7 @@ module QA
end
end
- it 'user removes a CI variable', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1758' do
+ it 'user removes a CI variable', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1598' do
Page::Project::Settings::CiVariables.perform do |ci_variable|
ci_variable.click_edit_ci_variable
ci_variable.click_ci_variable_delete_button
diff --git a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/pipeline_with_protected_variable_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/pipeline_with_protected_variable_spec.rb
index 4938ae3f969..4d21a98e072 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/pipeline_with_protected_variable_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/pipeline_with_protected_variable_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'faker'
-
module QA
RSpec.describe 'Verify', :runner do
describe 'Pipeline with protected variable' do
@@ -63,7 +61,7 @@ module QA
runner.remove_via_api!
end
- it 'exposes variable on protected branch', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/156' do
+ it 'exposes variable on protected branch', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1714' do
create_protected_branch
[developer, maintainer].each do |user|
@@ -76,7 +74,7 @@ module QA
end
end
- it 'does not expose variable on unprotected branch', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/156' do
+ it 'does not expose variable on unprotected branch', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1885' do
[developer, maintainer].each do |user|
create_merge_request(Runtime::API::Client.new(:gitlab, user: user))
go_to_pipeline_job(user)
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb
index 7a81318f158..47117ae751f 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb
@@ -24,7 +24,7 @@ module QA
runner.remove_via_api!
end
- it 'users creates a pipeline which gets processed', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1849' do
+ it 'users creates a pipeline which gets processed', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1601' do
# TODO: Convert back to :smoke once proved to be stable. Related issue: https://gitlab.com/gitlab-org/gitlab/-/issues/300909
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_local_config_file_paths_with_wildcard_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_local_config_file_paths_with_wildcard_spec.rb
index 5b3949f9c3a..27b45d1a2a0 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_local_config_file_paths_with_wildcard_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_local_config_file_paths_with_wildcard_spec.rb
@@ -20,7 +20,7 @@ module QA
project.remove_via_api!
end
- it 'runs the pipeline with composed config', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1757' do
+ it 'runs the pipeline with composed config', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1814' do
Page::Project::Pipeline::Show.perform do |pipeline|
aggregate_failures 'pipeline has all expected jobs' do
expect(pipeline).to have_job('build')
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_multiple_files_from_a_project_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_multiple_files_from_a_project_spec.rb
index c2ea568dbad..9d145a3becf 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_multiple_files_from_a_project_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_multiple_files_from_a_project_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'faker'
-
module QA
RSpec.describe 'Verify', :runner do
describe 'Include multiple files from a project' do
@@ -41,7 +39,7 @@ module QA
runner.remove_via_api!
end
- it 'runs the pipeline with composed config', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1082' do
+ it 'runs the pipeline with composed config', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1223' do
Page::Project::Pipeline::Show.perform do |pipeline|
aggregate_failures 'pipeline has all expected jobs' do
expect(pipeline).to have_job('build')
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/locked_artifacts_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/locked_artifacts_spec.rb
index 253b5fb2af4..7faf4114d02 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/locked_artifacts_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/locked_artifacts_spec.rb
@@ -30,7 +30,7 @@ module QA
runner.remove_via_api!
end
- it 'can be browsed' do
+ it 'can be browsed', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1808' do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.commit_message = 'Add .gitlab-ci.yml'
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/merge_mr_when_pipline_is_blocked_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/merge_mr_when_pipline_is_blocked_spec.rb
index b43581289ef..8dfd485bbf1 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/merge_mr_when_pipline_is_blocked_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/merge_mr_when_pipline_is_blocked_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'faker'
-
module QA
RSpec.describe 'Verify', :runner do
context 'When pipeline is blocked' do
@@ -70,7 +68,7 @@ module QA
runner.remove_via_api!
end
- it 'can still merge MR successfully', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/971' do
+ it 'can still merge MR successfully', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1281' do
Page::MergeRequest::Show.perform do |show|
# waiting for manual action status shows status badge 'blocked' on pipelines page
show.has_pipeline_status?('waiting for manual action')
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/mr_event_rule_pipeline_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/mr_event_rule_pipeline_spec.rb
index 47b36b55c8c..0ddfcf8cafb 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/mr_event_rule_pipeline_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/mr_event_rule_pipeline_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'faker'
-
module QA
RSpec.describe 'Verify', :runner do
context 'When job is configured to only run on merge_request_events' do
@@ -68,7 +66,7 @@ module QA
project.remove_via_api!
end
- it 'only runs the job configured to run on merge requests', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/170' do
+ it 'only runs the job configured to run on merge requests', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1890' do
Page::Project::Pipeline::Show.perform do |pipeline|
aggregate_failures do
expect(pipeline).to have_job(mr_only_job_name)
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pass_dotenv_variables_to_downstream_via_bridge_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pass_dotenv_variables_to_downstream_via_bridge_spec.rb
index adacedb36ab..9fd54251411 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pass_dotenv_variables_to_downstream_via_bridge_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pass_dotenv_variables_to_downstream_via_bridge_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'faker'
-
module QA
RSpec.describe 'Verify', :runner do
describe 'Pass dotenv variables to downstream via bridge' do
@@ -44,7 +42,7 @@ module QA
[upstream_project, downstream_project].each(&:remove_via_api!)
end
- it 'runs the pipeline with composed config', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1086' do
+ it 'runs the pipeline with composed config', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1221' do
Page::Project::Pipeline::Show.perform do |parent_pipeline|
Support::Waiter.wait_until { parent_pipeline.has_child_pipeline? }
parent_pipeline.expand_child_pipeline
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_branch_switcher_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_branch_switcher_spec.rb
index bb9b5feed2e..1a2d450f7eb 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_branch_switcher_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_branch_switcher_spec.rb
@@ -58,19 +58,17 @@ module QA
end
before do
- Runtime::Feature.enable(:pipeline_editor_branch_switcher)
Flow::Login.sign_in
project.visit!
Page::Project::Menu.perform(&:go_to_pipeline_editor)
end
after do
- Runtime::Feature.disable(:pipeline_editor_branch_switcher)
project.remove_via_api!
Page::Main::Menu.perform(&:sign_out)
end
- it 'can switch branches and target branch field updates accordingly', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1856' do
+ it 'can switch branches and target branch field updates accordingly', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1891' do
Page::Project::PipelineEditor::Show.perform do |show|
expect(show).to have_branch_selector_button
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb
index 5f3ec3ec870..f599d6b6251 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb
@@ -40,7 +40,7 @@ module QA
Page::Project::Menu.perform(&:click_ci_cd_pipelines)
end
- it 'can trigger pipeline', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/946' do
+ it 'can trigger pipeline', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1650' do
Page::Project::Pipeline::Index.perform do |index|
expect(index).not_to have_pipeline # should not auto trigger pipeline
index.click_run_pipeline_button
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/trigger_child_pipeline_with_manual_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/trigger_child_pipeline_with_manual_spec.rb
index c89cda73711..f803cfdb714 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/trigger_child_pipeline_with_manual_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/trigger_child_pipeline_with_manual_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'faker'
-
module QA
RSpec.describe 'Verify', :runner do
describe "Trigger child pipeline with 'when:manual'" do
@@ -32,7 +30,7 @@ module QA
runner.remove_via_api!
end
- it 'can trigger bridge job', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1049' do
+ it 'can trigger bridge job', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1237' do
Page::Project::Pipeline::Show.perform do |parent_pipeline|
expect(parent_pipeline).not_to have_child_pipeline
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/trigger_matrix_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/trigger_matrix_spec.rb
index d87fa0f5127..0bfbd164331 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/trigger_matrix_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/trigger_matrix_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'faker'
-
module QA
RSpec.describe 'Verify', :runner do
describe 'Trigger matrix' do
@@ -33,7 +31,7 @@ module QA
project.remove_via_api!
end
- it 'creates 2 trigger jobs and passes corresponding matrix variables', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1732' do
+ it 'creates 2 trigger jobs and passes corresponding matrix variables', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1824' do
Page::Project::Pipeline::Show.perform do |parent_pipeline|
trigger_title1 = 'deploy: [ovh, monitoring]'
trigger_title2 = 'deploy: [ovh, app]'
diff --git a/qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb
index 916b809ebc1..42aec99d6cf 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb
@@ -15,13 +15,13 @@ module QA
runner.remove_via_api!
end
- it 'user registers a new specific runner', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1764' do
+ it 'user registers a new specific runner', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1600' do
Flow::Login.sign_in
runner.project.visit!
Page::Project::Menu.perform(&:go_to_ci_cd_settings)
- Page::Project::Settings::CICD.perform do |settings|
+ Page::Project::Settings::CiCd.perform do |settings|
sleep 5 # Runner should register within 5 seconds
settings.expand_runners_settings do |page|
diff --git a/qa/qa/specs/features/browser_ui/4_verify/testing/view_code_coverage_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/testing/view_code_coverage_spec.rb
index 7d3f8f2b1d4..c85920d98ec 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/testing/view_code_coverage_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/testing/view_code_coverage_spec.rb
@@ -33,7 +33,7 @@ module QA
runner.remove_via_api!
end
- it 'creates an MR with code coverage statistics', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1740' do
+ it 'creates an MR with code coverage statistics', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1373' do
runner.project.visit!
configure_code_coverage(simplecov)
merge_request.visit!
@@ -49,7 +49,7 @@ module QA
def configure_code_coverage(coverage_tool_pattern)
Page::Project::Menu.perform(&:go_to_ci_cd_settings)
- Page::Project::Settings::CICD.perform do |settings|
+ Page::Project::Settings::CiCd.perform do |settings|
settings.expand_general_pipelines do |coverage|
coverage.configure_coverage_regex(coverage_tool_pattern)
end
diff --git a/qa/qa/specs/features/browser_ui/5_package/composer_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/composer_registry_spec.rb
index 61c71b062ae..9ddf485870d 100644
--- a/qa/qa/specs/features/browser_ui/5_package/composer_registry_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/composer_registry_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
RSpec.describe 'Package', :orchestrated, :packages, :object_storage do
describe 'Composer Repository' do
@@ -104,7 +102,7 @@ module QA
package.remove_via_api!
end
- it 'publishes a composer package and deletes it', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1088' do
+ it 'publishes a composer package and deletes it', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1634' do
Page::Project::Menu.perform(&:click_packages_link)
Page::Project::Packages::Index.perform do |index|
diff --git a/qa/qa/specs/features/browser_ui/5_package/conan_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/conan_repository_spec.rb
index 668a1524b1c..a8f1fc2a7de 100644
--- a/qa/qa/specs/features/browser_ui/5_package/conan_repository_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/conan_repository_spec.rb
@@ -41,7 +41,7 @@ module QA
package.remove_via_api!
end
- it 'publishes, installs, and deletes a Conan package', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1077' do
+ it 'publishes, installs, and deletes a Conan package', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1638' do
Flow::Login.sign_in
Resource::Repository::Commit.fabricate_via_api! do |commit|
diff --git a/qa/qa/specs/features/browser_ui/5_package/container_registry_omnibus_spec.rb b/qa/qa/specs/features/browser_ui/5_package/container_registry_omnibus_spec.rb
index 375a371c2b1..3d02c2884a2 100644
--- a/qa/qa/specs/features/browser_ui/5_package/container_registry_omnibus_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/container_registry_omnibus_spec.rb
@@ -28,7 +28,7 @@ module QA
runner.remove_via_api!
end
- it "pushes image and deletes tag", testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1743' do
+ it "pushes image and deletes tag", testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1911' do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.commit_message = 'Add .gitlab-ci.yml'
diff --git a/qa/qa/specs/features/browser_ui/5_package/container_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/container_registry_spec.rb
index 9131cad7244..65519cdebec 100644
--- a/qa/qa/specs/features/browser_ui/5_package/container_registry_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/container_registry_spec.rb
@@ -49,7 +49,7 @@ module QA
registry_repository&.remove_via_api!
end
- it 'pushes project image to the container registry and deletes tag', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1699' do
+ it 'pushes project image to the container registry and deletes tag', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1833' do
Flow::Login.sign_in
project.visit!
diff --git a/qa/qa/specs/features/browser_ui/5_package/dependency_proxy_spec.rb b/qa/qa/specs/features/browser_ui/5_package/dependency_proxy_spec.rb
index be1d0dd8e81..bfcc49885a0 100644
--- a/qa/qa/specs/features/browser_ui/5_package/dependency_proxy_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/dependency_proxy_spec.rb
@@ -44,7 +44,7 @@ module QA
end
with_them do
- it "pulls an image using the dependency proxy", testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1862' do
+ it "pulls an image using the dependency proxy" do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.commit_message = 'Add .gitlab-ci.yml'
diff --git a/qa/qa/specs/features/browser_ui/5_package/generic_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/generic_repository_spec.rb
index ef5965b29e5..2e5fa2c2904 100644
--- a/qa/qa/specs/features/browser_ui/5_package/generic_repository_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/generic_repository_spec.rb
@@ -98,7 +98,7 @@ module QA
package.remove_via_api!
end
- it 'uploads a generic package, downloads and deletes it', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1108' do
+ it 'uploads a generic package, downloads and deletes it', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1628' do
Page::Project::Menu.perform(&:click_packages_link)
Page::Project::Packages::Index.perform do |index|
diff --git a/qa/qa/specs/features/browser_ui/5_package/maven_gradle_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/maven_gradle_repository_spec.rb
index 32a0670e342..fb3f2abd87a 100644
--- a/qa/qa/specs/features/browser_ui/5_package/maven_gradle_repository_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/maven_gradle_repository_spec.rb
@@ -194,7 +194,7 @@ module QA
}
end
- it "pushes and pulls a maven package via gradle using #{params[:authentication_token_type]}", testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1074' do
+ it "pushes and pulls a maven package via gradle using #{params[:authentication_token_type]}" do
# pushing
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = package_project
diff --git a/qa/qa/specs/features/browser_ui/5_package/maven_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/maven_repository_spec.rb
index fb92616ffc5..bf1d2a04dba 100644
--- a/qa/qa/specs/features/browser_ui/5_package/maven_repository_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/maven_repository_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
RSpec.describe 'Package', :orchestrated, :packages, :reliable, :object_storage do
describe 'Maven Repository' do
@@ -185,7 +183,7 @@ module QA
another_project.remove_via_api!
end
- it 'pushes and pulls a Maven package via CI and deletes it', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1115' do
+ it 'pushes and pulls a Maven package via CI and deletes it', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1627' do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.commit_message = 'Add .gitlab-ci.yml'
@@ -258,7 +256,7 @@ module QA
Page::Group::Settings::PackageRegistries.perform(&:set_allow_duplicates_disabled)
end
- it 'prevents users from publishing duplicate Maven packages at the group level', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1717' do
+ it 'prevents users from publishing duplicate Maven packages at the group level', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1830' do
with_fixtures([pom_xml, settings_xml]) do |dir|
Service::DockerRun::Maven.new(dir).publish!
end
@@ -303,7 +301,7 @@ module QA
Page::Group::Settings::PackageRegistries.perform(&:set_allow_duplicates_enabled)
end
- it 'allows users to publish duplicate Maven packages at the group level', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1722' do
+ it 'allows users to publish duplicate Maven packages at the group level', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1829' do
with_fixtures([pom_xml, settings_xml]) do |dir|
Service::DockerRun::Maven.new(dir).publish!
end
diff --git a/qa/qa/specs/features/browser_ui/5_package/npm_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/npm_registry_spec.rb
index 2322d18a9ba..5a3b4388f0c 100644
--- a/qa/qa/specs/features/browser_ui/5_package/npm_registry_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/npm_registry_spec.rb
@@ -3,10 +3,11 @@
module QA
RSpec.describe 'Package', :orchestrated, :packages, :reliable, :object_storage do
describe 'npm registry' do
+ using RSpec::Parameterized::TableSyntax
include Runtime::Fixtures
let!(:registry_scope) { Runtime::Namespace.sandbox_name }
- let(:auth_token) do
+ let!(:personal_access_token) do
unless Page::Main::Menu.perform(&:signed_in?)
Flow::Login.sign_in
end
@@ -14,6 +15,13 @@ module QA
Resource::PersonalAccessToken.fabricate!.token
end
+ let(:project_deploy_token) do
+ Resource::DeployToken.fabricate_via_browser_ui! do |deploy_token|
+ deploy_token.name = 'npm-deploy-token'
+ deploy_token.project = project
+ end
+ end
+
let(:uri) { URI.parse(Runtime::Scenario.gitlab_address) }
let(:gitlab_address_with_port) { "#{uri.scheme}://#{uri.host}:#{uri.port}" }
let(:gitlab_host_with_port) { "#{uri.host}:#{uri.port}" }
@@ -109,16 +117,6 @@ module QA
}
end
- let(:npmrc) do
- {
- file_path: '.npmrc',
- content: <<~NPMRC
- //#{gitlab_host_with_port}/api/v4/projects/#{project.id}/packages/npm/:_authToken=#{auth_token}
- @#{registry_scope}:registry=#{gitlab_address_with_port}/api/v4/projects/#{project.id}/packages/npm/
- NPMRC
- }
- end
-
let(:package) do
Resource::Package.init do |package|
package.name = "@#{registry_scope}/#{project.name}"
@@ -133,72 +131,101 @@ module QA
another_project.remove_via_api!
end
- it 'push and pull a npm package via CI', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1772' do
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- commit.project = project
- commit.commit_message = 'Add .gitlab-ci.yml'
- commit.add_files([
- gitlab_ci_deploy_yaml,
- npmrc,
- package_json
- ])
- end
-
- project.visit!
- Flow::Pipeline.visit_latest_pipeline
-
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('deploy')
- end
-
- Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 800)
- end
-
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- commit.project = another_project
- commit.commit_message = 'Add .gitlab-ci.yml'
- commit.add_files([
- gitlab_ci_install_yaml
- ])
- end
-
- another_project.visit!
- Flow::Pipeline.visit_latest_pipeline
-
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('install')
- end
-
- Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 800)
- job.click_browse_button
- end
-
- Page::Project::Artifact::Show.perform do |artifacts|
- artifacts.go_to_directory('node_modules')
- artifacts.go_to_directory("@#{registry_scope}")
- expect(artifacts).to have_content( "#{project.name}")
- end
-
- project.visit!
- Page::Project::Menu.perform(&:click_packages_link)
-
- Page::Project::Packages::Index.perform do |index|
- expect(index).to have_package(package.name)
+ where(:authentication_token_type, :token_name) do
+ :personal_access_token | 'Personal Access Token'
+ :ci_job_token | 'CI Job Token'
+ :project_deploy_token | 'Deploy Token'
+ end
- index.click_package(package.name)
+ with_them do
+ let(:auth_token) do
+ case authentication_token_type
+ when :personal_access_token
+ "\"#{personal_access_token}\""
+ when :ci_job_token
+ '${CI_JOB_TOKEN}'
+ when :project_deploy_token
+ "\"#{project_deploy_token.password}\""
+ end
end
- Page::Project::Packages::Show.perform do |show|
- expect(show).to have_package_info(package.name, "1.0.0")
-
- show.click_delete
+ let(:npmrc) do
+ {
+ file_path: '.npmrc',
+ content: <<~NPMRC
+ //#{gitlab_host_with_port}/api/v4/projects/#{project.id}/packages/npm/:_authToken=#{auth_token}
+ @#{registry_scope}:registry=#{gitlab_address_with_port}/api/v4/projects/#{project.id}/packages/npm/
+ NPMRC
+ }
end
- Page::Project::Packages::Index.perform do |index|
- expect(index).to have_content("Package deleted successfully")
- expect(index).not_to have_package(package.name)
+ it "push and pull a npm package via CI using a #{params[:token_name]}", testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1772' do
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ commit.project = project
+ commit.commit_message = 'Add .gitlab-ci.yml'
+ commit.add_files([
+ gitlab_ci_deploy_yaml,
+ npmrc,
+ package_json
+ ])
+ end
+
+ project.visit!
+ Flow::Pipeline.visit_latest_pipeline
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('deploy')
+ end
+
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+ end
+
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ commit.project = another_project
+ commit.commit_message = 'Add .gitlab-ci.yml'
+ commit.add_files([
+ gitlab_ci_install_yaml
+ ])
+ end
+
+ another_project.visit!
+ Flow::Pipeline.visit_latest_pipeline
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('install')
+ end
+
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+ job.click_browse_button
+ end
+
+ Page::Project::Artifact::Show.perform do |artifacts|
+ artifacts.go_to_directory('node_modules')
+ artifacts.go_to_directory("@#{registry_scope}")
+ expect(artifacts).to have_content( "#{project.name}")
+ end
+
+ project.visit!
+ Page::Project::Menu.perform(&:click_packages_link)
+
+ Page::Project::Packages::Index.perform do |index|
+ expect(index).to have_package(package.name)
+
+ index.click_package(package.name)
+ end
+
+ Page::Project::Packages::Show.perform do |show|
+ expect(show).to have_package_info(package.name, "1.0.0")
+
+ show.click_delete
+ end
+
+ Page::Project::Packages::Index.perform do |index|
+ expect(index).to have_content("Package deleted successfully")
+ expect(index).not_to have_package(package.name)
+ end
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/5_package/nuget_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/nuget_repository_spec.rb
index 1f62b285798..8a6752ed817 100644
--- a/qa/qa/specs/features/browser_ui/5_package/nuget_repository_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/nuget_repository_spec.rb
@@ -1,10 +1,9 @@
# frozen_string_literal: true
-require 'securerandom'
-
module QA
RSpec.describe 'Package', :orchestrated, :packages, :object_storage do
describe 'NuGet Repository' do
+ using RSpec::Parameterized::TableSyntax
include Runtime::Fixtures
let(:project) do
Resource::Project.fabricate_via_api! do |project|
@@ -13,6 +12,21 @@ module QA
end
end
+ let(:personal_access_token) do
+ unless Page::Main::Menu.perform(&:signed_in?)
+ Flow::Login.sign_in
+ end
+
+ Resource::PersonalAccessToken.fabricate!
+ end
+
+ let(:group_deploy_token) do
+ Resource::GroupDeployToken.fabricate_via_browser_ui! do |deploy_token|
+ deploy_token.name = 'nuget-group-deploy-token'
+ deploy_token.group = project.group
+ end
+ end
+
let(:package) do
Resource::Package.init do |package|
package.name = "dotnetcore-#{SecureRandom.hex(8)}"
@@ -42,123 +56,153 @@ module QA
package.remove_via_api!
end
- it 'publishes a nuget package at the project level, installs and deletes it at the group level', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1073' do
- Flow::Login.sign_in
-
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- commit.project = project
- commit.commit_message = 'Add .gitlab-ci.yml'
- commit.update_files(
- [
- {
- file_path: '.gitlab-ci.yml',
- content: <<~YAML
- image: mcr.microsoft.com/dotnet/sdk:5.0
-
- stages:
- - deploy
-
- deploy:
- stage: deploy
- script:
- - dotnet restore -p:Configuration=Release
- - dotnet build -c Release
- - dotnet pack -c Release -p:PackageID=#{package.name}
- - dotnet nuget add source "$CI_SERVER_URL/api/v4/projects/$CI_PROJECT_ID/packages/nuget/index.json" --name gitlab --username gitlab-ci-token --password $CI_JOB_TOKEN --store-password-in-clear-text
- - dotnet nuget push "bin/Release/*.nupkg" --source gitlab
- only:
- - "#{project.default_branch}"
- tags:
- - "runner-for-#{project.group.name}"
- YAML
- }
- ]
- )
- end
-
- project.visit!
- Flow::Pipeline.visit_latest_pipeline
+ where(:authentication_token_type, :token_name) do
+ :personal_access_token | 'Personal Access Token'
+ :ci_job_token | 'CI Job Token'
+ :group_deploy_token | 'Deploy Token'
+ end
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('deploy')
+ with_them do
+ let(:auth_token_password) do
+ case authentication_token_type
+ when :personal_access_token
+ "\"#{personal_access_token.token}\""
+ when :ci_job_token
+ '${CI_JOB_TOKEN}'
+ when :group_deploy_token
+ "\"#{group_deploy_token.password}\""
+ end
end
- Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 800)
+ let(:auth_token_username) do
+ case authentication_token_type
+ when :personal_access_token
+ "\"#{personal_access_token.user.username}\""
+ when :ci_job_token
+ 'gitlab-ci-token'
+ when :group_deploy_token
+ "\"#{group_deploy_token.username}\""
+ end
end
- another_project.visit!
-
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- commit.project = another_project
- commit.commit_message = 'Add new csproj file'
- commit.add_files(
- [
- {
- file_path: 'otherdotnet.csproj',
- content: <<~EOF
- <Project Sdk="Microsoft.NET.Sdk">
-
- <PropertyGroup>
- <OutputType>Exe</OutputType>
- <TargetFramework>net5.0</TargetFramework>
- </PropertyGroup>
-
- </Project>
- EOF
- }
- ]
- )
- commit.update_files(
- [
- {
- file_path: '.gitlab-ci.yml',
- content: <<~YAML
+ it "publishes a nuget package at the project level, installs and deletes it at the group level using a #{params[:token_name]}", testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1073' do
+ Flow::Login.sign_in
+
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ commit.project = project
+ commit.commit_message = 'Add .gitlab-ci.yml'
+ commit.update_files(
+ [
+ {
+ file_path: '.gitlab-ci.yml',
+ content: <<~YAML
image: mcr.microsoft.com/dotnet/sdk:5.0
stages:
- - install
+ - deploy
- install:
- stage: install
+ deploy:
+ stage: deploy
script:
- - dotnet nuget locals all --clear
- - dotnet nuget add source "$CI_SERVER_URL/api/v4/groups/#{another_project.group.id}/-/packages/nuget/index.json" --name gitlab --username gitlab-ci-token --password $CI_JOB_TOKEN --store-password-in-clear-text
- - "dotnet add otherdotnet.csproj package #{package.name} --version 1.0.0"
- only:
- - "#{another_project.default_branch}"
+ - dotnet restore -p:Configuration=Release
+ - dotnet build -c Release
+ - dotnet pack -c Release -p:PackageID=#{package.name}
+ - dotnet nuget add source "$CI_SERVER_URL/api/v4/projects/$CI_PROJECT_ID/packages/nuget/index.json" --name gitlab --username #{auth_token_username} --password #{auth_token_password} --store-password-in-clear-text
+ - dotnet nuget push "bin/Release/*.nupkg" --source gitlab
+ rules:
+ - if: '$CI_COMMIT_BRANCH == "#{project.default_branch}"'
tags:
- "runner-for-#{project.group.name}"
- YAML
- }
- ]
- )
- end
-
- Flow::Pipeline.visit_latest_pipeline
-
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('install')
- end
-
- Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 800)
- end
-
- project.group.visit!
-
- Page::Group::Menu.perform(&:go_to_group_packages)
-
- Page::Project::Packages::Index.perform do |index|
- expect(index).to have_package(package.name)
- index.click_package(package.name)
- end
-
- Page::Project::Packages::Show.perform(&:click_delete)
-
- Page::Project::Packages::Index.perform do |index|
- expect(index).to have_content("Package deleted successfully")
- expect(index).not_to have_package(package.name)
+ YAML
+ }
+ ]
+ )
+ end
+
+ project.visit!
+ Flow::Pipeline.visit_latest_pipeline
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('deploy')
+ end
+
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+ end
+
+ another_project.visit!
+
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ commit.project = another_project
+ commit.commit_message = 'Add new csproj file'
+ commit.add_files(
+ [
+ {
+ file_path: 'otherdotnet.csproj',
+ content: <<~EOF
+ <Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ <TargetFramework>net5.0</TargetFramework>
+ </PropertyGroup>
+
+ </Project>
+ EOF
+ }
+ ]
+ )
+ commit.update_files(
+ [
+ {
+ file_path: '.gitlab-ci.yml',
+ content: <<~YAML
+ image: mcr.microsoft.com/dotnet/sdk:5.0
+
+ stages:
+ - install
+
+ install:
+ stage: install
+ script:
+ - dotnet nuget locals all --clear
+ - dotnet nuget add source "$CI_SERVER_URL/api/v4/groups/#{another_project.group.id}/-/packages/nuget/index.json" --name gitlab --username #{auth_token_username} --password #{auth_token_password} --store-password-in-clear-text
+ - "dotnet add otherdotnet.csproj package #{package.name} --version 1.0.0"
+ only:
+ - "#{another_project.default_branch}"
+ tags:
+ - "runner-for-#{project.group.name}"
+ YAML
+ }
+ ]
+ )
+ end
+
+ Flow::Pipeline.visit_latest_pipeline
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('install')
+ end
+
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+ end
+
+ project.group.visit!
+
+ Page::Group::Menu.perform(&:go_to_group_packages)
+
+ Page::Project::Packages::Index.perform do |index|
+ expect(index).to have_package(package.name)
+ index.click_package(package.name)
+ end
+
+ Page::Project::Packages::Show.perform(&:click_delete)
+
+ Page::Project::Packages::Index.perform do |index|
+ expect(index).to have_content('Package deleted successfully')
+ expect(index).not_to have_package(package.name)
+ end
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/5_package/online_garbage_collection_spec.rb b/qa/qa/specs/features/browser_ui/5_package/online_garbage_collection_spec.rb
index 8c686e65e33..3ec76e8afad 100644
--- a/qa/qa/specs/features/browser_ui/5_package/online_garbage_collection_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/online_garbage_collection_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Package' do
- describe 'Container Registry Online Garbage Collection', :registry_gc, only: { subdomain: %i[pre] }, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/337791', type: :waiting_on } do
+ describe 'Container Registry Online Garbage Collection', :registry_gc, only: { subdomain: %i[pre] } do
let(:group) { Resource::Group.fabricate_via_api! }
let(:imported_project) do
@@ -90,7 +90,7 @@ module QA
end
end
- it 'runs the online garbage collector tool', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1854' do
+ it 'runs the online garbage collector tool', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1889' do
imported_project.visit!
Flow::Pipeline.visit_latest_pipeline
diff --git a/qa/qa/specs/features/browser_ui/5_package/pypi_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/pypi_repository_spec.rb
index 7b924f1b52b..dfc9202ebed 100644
--- a/qa/qa/specs/features/browser_ui/5_package/pypi_repository_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/pypi_repository_spec.rb
@@ -117,7 +117,7 @@ module QA
end
context 'when at the project level' do
- it 'publishes and installs a pypi package and deletes it', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1087' do
+ it 'publishes and installs a pypi package and deletes it', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1635' do
Page::Project::Menu.perform(&:click_packages_link)
Page::Project::Packages::Index.perform do |index|
@@ -137,7 +137,7 @@ module QA
end
context 'Geo', :orchestrated, :geo do
- it 'replicates a published pypi package to the Geo secondary site', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1120', quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/325556', type: :investigating } do
+ it 'replicates a published pypi package to the Geo secondary site', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1219', quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/325556', type: :investigating } do
QA::Runtime::Logger.debug('Visiting the secondary Geo site')
QA::Flow::Login.while_signed_in(address: :geo_secondary) do
diff --git a/qa/qa/specs/features/browser_ui/5_package/rubygems_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/rubygems_registry_spec.rb
index 530a3243766..9a45b072eed 100644
--- a/qa/qa/specs/features/browser_ui/5_package/rubygems_registry_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/rubygems_registry_spec.rb
@@ -43,7 +43,7 @@ module QA
project.remove_via_api!
end
- it 'publishes and deletes a Ruby gem', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1131' do
+ it 'publishes and deletes a Ruby gem', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1906' do
Flow::Login.sign_in
Resource::Repository::ProjectPush.fabricate! do |push|
diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb
index 713b32de217..8878b719a21 100644
--- a/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb
+++ b/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb
@@ -3,7 +3,7 @@
module QA
RSpec.describe 'Release' do
describe 'Deploy key creation' do
- it 'user adds a deploy key', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1765' do
+ it 'user adds a deploy key', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1602' do
Flow::Login.sign_in
key = Runtime::Key::RSA.new
diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb
index 10795654617..23625ab645d 100644
--- a/qa/qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb
+++ b/qa/qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb
@@ -3,7 +3,7 @@
module QA
RSpec.describe 'Release' do
describe 'Deploy token creation' do
- it 'user adds a deploy token', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/419' do
+ it 'user adds a deploy token', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1582' do
Flow::Login.sign_in
deploy_token_name = 'deploy token name'
diff --git a/qa/qa/specs/features/browser_ui/6_release/pages/pages_pipeline_spec.rb b/qa/qa/specs/features/browser_ui/6_release/pages/pages_pipeline_spec.rb
index 1502e1ab924..97f52ea7ec1 100644
--- a/qa/qa/specs/features/browser_ui/6_release/pages/pages_pipeline_spec.rb
+++ b/qa/qa/specs/features/browser_ui/6_release/pages/pages_pipeline_spec.rb
@@ -31,7 +31,7 @@ module QA
pipeline.visit!
end
- it 'runs a Pages-specific pipeline', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1783' do
+ it 'runs a Pages-specific pipeline', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1879' do
Page::Project::Pipeline::Show.perform do |show|
expect(show).to have_job(:pages)
show.click_job(:pages)
diff --git a/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_dependent_relationship_spec.rb b/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_dependent_relationship_spec.rb
index 0ef3715db5e..46640b1a540 100644
--- a/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_dependent_relationship_spec.rb
+++ b/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_dependent_relationship_spec.rb
@@ -25,7 +25,7 @@ module QA
runner.remove_via_api!
end
- it 'parent pipelines passes if child passes', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1153' do
+ it 'parent pipelines passes if child passes', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1198' do
add_ci_files(success_child_ci_file)
Flow::Pipeline.visit_latest_pipeline(pipeline_condition: 'completed')
@@ -35,7 +35,7 @@ module QA
end
end
- it 'parent pipeline fails if child fails', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1152' do
+ it 'parent pipeline fails if child fails', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1199' do
add_ci_files(fail_child_ci_file)
Flow::Pipeline.visit_latest_pipeline(pipeline_condition: 'completed')
diff --git a/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb b/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb
index 6c7ab9f2f72..dac89663f84 100644
--- a/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb
+++ b/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb
@@ -25,7 +25,7 @@ module QA
runner.remove_via_api!
end
- it 'parent pipelines passes if child passes', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1161' do
+ it 'parent pipelines passes if child passes', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1191' do
add_ci_files(success_child_ci_file)
Flow::Pipeline.visit_latest_pipeline(pipeline_condition: 'completed')
@@ -35,7 +35,7 @@ module QA
end
end
- it 'parent pipeline passes even if child fails', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1162' do
+ it 'parent pipeline passes even if child fails', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1190' do
add_ci_files(fail_child_ci_file)
Flow::Pipeline.visit_latest_pipeline(pipeline_condition: 'completed')
diff --git a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
index 1dcc02095f6..655c806a37a 100644
--- a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
+++ b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'pathname'
-
module QA
RSpec.describe 'Configure' do
let(:project) do
@@ -23,7 +21,7 @@ module QA
cluster&.remove!
end
- it 'runs auto devops', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1715' do
+ it 'runs auto devops', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1422' do
Flow::Login.sign_in
# Set an application secret CI variable (prefixed with K8S_SECRET_)
@@ -102,7 +100,7 @@ module QA
project.visit!
Page::Project::Menu.perform(&:go_to_ci_cd_settings)
- Page::Project::Settings::CICD.perform(&:expand_auto_devops)
+ Page::Project::Settings::CiCd.perform(&:expand_auto_devops)
Page::Project::Settings::AutoDevops.perform(&:enable_autodevops)
# Create AutoDevOps repo
@@ -115,7 +113,7 @@ module QA
end
end
- it 'runs an AutoDevOps pipeline', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1847' do
+ it 'runs an AutoDevOps pipeline', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1564' do
Flow::Pipeline.visit_latest_pipeline
Page::Project::Pipeline::Show.perform do |pipeline|
diff --git a/qa/qa/specs/features/browser_ui/7_configure/kubernetes/kubernetes_integration_spec.rb b/qa/qa/specs/features/browser_ui/7_configure/kubernetes/kubernetes_integration_spec.rb
index 3a59efe645a..ba41285ebca 100644
--- a/qa/qa/specs/features/browser_ui/7_configure/kubernetes/kubernetes_integration_spec.rb
+++ b/qa/qa/specs/features/browser_ui/7_configure/kubernetes/kubernetes_integration_spec.rb
@@ -20,7 +20,7 @@ module QA
cluster.remove!
end
- it 'can create and associate a project cluster', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/707' do
+ it 'can create and associate a project cluster', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1419' do
Resource::KubernetesCluster::ProjectCluster.fabricate_via_browser_ui! do |k8s_cluster|
k8s_cluster.project = project
k8s_cluster.cluster = cluster
diff --git a/qa/qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb b/qa/qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb
index 1511f74c883..14bd6af815e 100644
--- a/qa/qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb
+++ b/qa/qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb
@@ -10,13 +10,13 @@ module QA
@project.visit!
end
- it 'configures custom metrics', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/872' do
+ it 'configures custom metrics', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1334' do
verify_add_custom_metric
verify_edit_custom_metric
verify_delete_custom_metric
end
- it 'duplicates to create dashboard to custom', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/871' do
+ it 'duplicates to create dashboard to custom', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1335' do
Page::Project::Menu.perform(&:go_to_monitor_metrics)
Page::Project::Monitor::Metrics::Show.perform do |on_dashboard|
@@ -27,7 +27,7 @@ module QA
end
end
- it 'verifies data on filtered deployed environment', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/874' do
+ it 'verifies data on filtered deployed environment', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1332' do
Page::Project::Menu.perform(&:go_to_monitor_metrics)
Page::Project::Monitor::Metrics::Show.perform do |on_dashboard|
@@ -37,7 +37,7 @@ module QA
end
end
- it 'filters using the quick range', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/873' do
+ it 'filters using the quick range', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1333' do
Page::Project::Menu.perform(&:go_to_monitor_metrics)
Page::Project::Monitor::Metrics::Show.perform do |on_dashboard|
@@ -52,7 +52,7 @@ module QA
end
end
- it 'observes cluster health graph', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/920' do
+ it 'observes cluster health graph', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1311' do
Page::Project::Menu.perform(&:go_to_infrastructure_kubernetes)
Page::Project::Infrastructure::Kubernetes::Index.perform do |cluster_list|
@@ -65,7 +65,7 @@ module QA
end
end
- it 'uses templating variables for metrics dashboards' do
+ it 'uses templating variables for metrics dashboards', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1926' do
templating_dashboard_yml = Pathname
.new(__dir__)
.join('../../../../fixtures/metrics_dashboards/templating.yml')
diff --git a/qa/qa/specs/features/browser_ui/non_devops/performance_bar_spec.rb b/qa/qa/specs/features/browser_ui/non_devops/performance_bar_spec.rb
index a0f613cfda2..9d84658da76 100644
--- a/qa/qa/specs/features/browser_ui/non_devops/performance_bar_spec.rb
+++ b/qa/qa/specs/features/browser_ui/non_devops/performance_bar_spec.rb
@@ -20,7 +20,7 @@ module QA
end
end
- it 'shows results for the original request and AJAX requests', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/478' do
+ it 'shows results for the original request and AJAX requests', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1545' do
# Issue pages always make AJAX requests
Resource::Issue.fabricate_via_browser_ui! do |issue|
issue.title = 'Performance bar test'
diff --git a/qa/qa/specs/helpers/context_formatter.rb b/qa/qa/specs/helpers/context_formatter.rb
deleted file mode 100644
index 26db7c3b67e..00000000000
--- a/qa/qa/specs/helpers/context_formatter.rb
+++ /dev/null
@@ -1,68 +0,0 @@
-# frozen_string_literal: true
-
-require 'rspec/core'
-require "rspec/core/formatters/base_formatter"
-
-module QA
- module Specs
- module Helpers
- class ContextFormatter < ::RSpec::Core::Formatters::BaseFormatter
- include ContextSelector
-
- ::RSpec::Core::Formatters.register(
- self,
- :example_group_started,
- :example_started
- )
-
- # Starts example group
- # @param [RSpec::Core::Notifications::GroupNotification] example_group_notification
- # @return [void]
- def example_group_started(example_group_notification)
- set_skip_metadata(example_group_notification.group)
- end
-
- # Starts example
- # @param [RSpec::Core::Notifications::ExampleNotification] example_notification
- # @return [void]
- def example_started(example_notification)
- example = example_notification.example
-
- # if skip propagated from example_group, do not reset skip metadata
- set_skip_metadata(example_notification.example) unless example.metadata[:skip]
- end
-
- private
-
- # Skip example_group or example
- #
- # @param [<RSpec::Core::ExampleGroup, RSpec::Core::Example>] example
- # @return [void]
- def set_skip_metadata(example)
- return skip_only(example.metadata) if example.metadata.key?(:only)
- return skip_except(example.metadata) if example.metadata.key?(:except)
- end
-
- # Skip based on 'only' condition
- #
- # @param [Hash] metadata
- # @return [void]
- def skip_only(metadata)
- return if context_matches?(metadata[:only])
-
- metadata[:skip] = 'Test is not compatible with this environment or pipeline'
- end
-
- # Skip based on 'except' condition
- #
- # @param [Hash] metadata
- # @return [void]
- def skip_except(metadata)
- return unless except?(metadata[:except])
-
- metadata[:skip] = 'Test is excluded in this job'
- end
- end
- end
- end
-end
diff --git a/qa/qa/specs/helpers/quarantine_formatter.rb b/qa/qa/specs/helpers/quarantine_formatter.rb
deleted file mode 100644
index c42debee07c..00000000000
--- a/qa/qa/specs/helpers/quarantine_formatter.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-# frozen_string_literal: true
-
-require 'rspec/core'
-require "rspec/core/formatters/base_formatter"
-
-module QA
- module Specs
- module Helpers
- class QuarantineFormatter < ::RSpec::Core::Formatters::BaseFormatter
- include Quarantine
-
- ::RSpec::Core::Formatters.register(
- self,
- :example_group_started,
- :example_started
- )
-
- # Starts example group
- # @param [RSpec::Core::Notifications::GroupNotification] example_group_notification
- # @return [void]
- def example_group_started(example_group_notification)
- group = example_group_notification.group
-
- skip_or_run_quarantined_tests_or_contexts(filters, group)
- end
-
- # Starts example
- # @param [RSpec::Core::Notifications::ExampleNotification] example_notification
- # @return [void]
- def example_started(example_notification)
- example = example_notification.example
-
- # if skip propagated from example_group, do not reset skip metadata
- skip_or_run_quarantined_tests_or_contexts(filters, example) unless example.metadata[:skip]
- end
-
- private
-
- def filters
- @filters ||= ::RSpec.configuration.inclusion_filter.rules
- end
- end
- end
- end
-end
diff --git a/qa/qa/specs/helpers/rspec.rb b/qa/qa/specs/helpers/rspec.rb
index 853dfbfd1b6..3e97dbd118a 100644
--- a/qa/qa/specs/helpers/rspec.rb
+++ b/qa/qa/specs/helpers/rspec.rb
@@ -19,13 +19,22 @@ module QA
# expanding into the global state
# See: https://github.com/rspec/rspec-core/issues/2603
def describe_successfully(*args, &describe_body)
- reporter = ::RSpec.configuration.reporter
-
- example_group = RSpec.describe(*args, &describe_body)
+ example_group = ::RSpec.describe(*args, &describe_body)
ran_successfully = example_group.run reporter
expect(ran_successfully).to eq true
example_group
end
+
+ def send_stop_notification
+ reporter.notify(
+ :stop,
+ ::RSpec::Core::Notifications::ExamplesNotification.new(reporter)
+ )
+ end
+
+ def reporter
+ ::RSpec.configuration.reporter
+ end
end
end
end
diff --git a/qa/qa/specs/runner.rb b/qa/qa/specs/runner.rb
index bd9907611c7..d7d64834e7a 100644
--- a/qa/qa/specs/runner.rb
+++ b/qa/qa/specs/runner.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true
-require 'knapsack'
require 'rspec/core'
require 'rspec/expectations'
diff --git a/qa/qa/support/allure_metadata_formatter.rb b/qa/qa/support/allure_metadata_formatter.rb
deleted file mode 100644
index 8a18eeca839..00000000000
--- a/qa/qa/support/allure_metadata_formatter.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-# frozen_string_literal: true
-
-require 'rspec/core'
-require "rspec/core/formatters/base_formatter"
-
-module QA
- module Support
- class AllureMetadataFormatter < ::RSpec::Core::Formatters::BaseFormatter
- ::RSpec::Core::Formatters.register(
- self,
- :example_started
- )
-
- # Starts example
- # @param [RSpec::Core::Notifications::ExampleNotification] example_notification
- # @return [void]
- def example_started(example_notification)
- example = example_notification.example
-
- testcase = example.metadata[:testcase]
- example.tms('Testcase', testcase) if testcase
-
- quarantine_issue = example.metadata.dig(:quarantine, :issue)
- example.issue('Quarantine issue', quarantine_issue) if quarantine_issue
-
- spec_file = example.file_path.split('/').last
- example.issue(
- 'Failure issues',
- "https://gitlab.com/gitlab-org/gitlab/-/issues?scope=all&state=opened&search=#{spec_file}"
- )
- return unless Runtime::Env.running_in_ci?
-
- example.add_link(name: "Job(#{Runtime::Env.ci_job_name})", url: Runtime::Env.ci_job_url)
- end
- end
- end
-end
diff --git a/qa/qa/support/api.rb b/qa/qa/support/api.rb
index 579227b4f7a..205ddf7ad3a 100644
--- a/qa/qa/support/api.rb
+++ b/qa/qa/support/api.rb
@@ -1,10 +1,8 @@
# frozen_string_literal: true
-require 'rest-client'
-
module QA
module Support
- module Api
+ module API
HTTP_STATUS_OK = 200
HTTP_STATUS_CREATED = 201
HTTP_STATUS_NO_CONTENT = 204
diff --git a/qa/qa/support/formatters/allure_metadata_formatter.rb b/qa/qa/support/formatters/allure_metadata_formatter.rb
new file mode 100644
index 00000000000..10769ba5c57
--- /dev/null
+++ b/qa/qa/support/formatters/allure_metadata_formatter.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module QA
+ module Support
+ module Formatters
+ class AllureMetadataFormatter < ::RSpec::Core::Formatters::BaseFormatter
+ ::RSpec::Core::Formatters.register(
+ self,
+ :example_started
+ )
+
+ # Starts example
+ # @param [RSpec::Core::Notifications::ExampleNotification] example_notification
+ # @return [void]
+ def example_started(example_notification)
+ example = example_notification.example
+
+ quarantine_issue = example.metadata.dig(:quarantine, :issue)
+ example.issue('Quarantine issue', quarantine_issue) if quarantine_issue
+
+ spec_file = example.file_path.split('/').last
+ example.issue(
+ 'Failure issues',
+ "https://gitlab.com/gitlab-org/gitlab/-/issues?scope=all&state=opened&search=#{spec_file}"
+ )
+ return unless Runtime::Env.running_in_ci?
+
+ example.add_link(name: "Job(#{Runtime::Env.ci_job_name})", url: Runtime::Env.ci_job_url)
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/support/formatters/context_formatter.rb b/qa/qa/support/formatters/context_formatter.rb
new file mode 100644
index 00000000000..c8991561f45
--- /dev/null
+++ b/qa/qa/support/formatters/context_formatter.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+module QA
+ module Support
+ module Formatters
+ class ContextFormatter < ::RSpec::Core::Formatters::BaseFormatter
+ include Specs::Helpers::ContextSelector
+
+ ::RSpec::Core::Formatters.register(
+ self,
+ :example_group_started,
+ :example_started
+ )
+
+ # Starts example group
+ # @param [RSpec::Core::Notifications::GroupNotification] example_group_notification
+ # @return [void]
+ def example_group_started(example_group_notification)
+ set_skip_metadata(example_group_notification.group)
+ end
+
+ # Starts example
+ # @param [RSpec::Core::Notifications::ExampleNotification] example_notification
+ # @return [void]
+ def example_started(example_notification)
+ example = example_notification.example
+
+ # if skip propagated from example_group, do not reset skip metadata
+ set_skip_metadata(example_notification.example) unless example.metadata[:skip]
+ end
+
+ private
+
+ # Skip example_group or example
+ #
+ # @param [<RSpec::Core::ExampleGroup, RSpec::Core::Example>] example
+ # @return [void]
+ def set_skip_metadata(example)
+ return skip_only(example.metadata) if example.metadata.key?(:only)
+ return skip_except(example.metadata) if example.metadata.key?(:except)
+ end
+
+ # Skip based on 'only' condition
+ #
+ # @param [Hash] metadata
+ # @return [void]
+ def skip_only(metadata)
+ return if context_matches?(metadata[:only])
+
+ metadata[:skip] = 'Test is not compatible with this environment or pipeline'
+ end
+
+ # Skip based on 'except' condition
+ #
+ # @param [Hash] metadata
+ # @return [void]
+ def skip_except(metadata)
+ return unless except?(metadata[:except])
+
+ metadata[:skip] = 'Test is excluded in this job'
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/support/formatters/formatters.rb b/qa/qa/support/formatters/formatters.rb
new file mode 100644
index 00000000000..f0abf98001f
--- /dev/null
+++ b/qa/qa/support/formatters/formatters.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'rspec/core'
+require 'rspec/core/formatters/base_formatter'
+
+module QA
+ module Support
+ module Formatters
+ end
+ end
+end
diff --git a/qa/qa/support/formatters/quarantine_formatter.rb b/qa/qa/support/formatters/quarantine_formatter.rb
new file mode 100644
index 00000000000..c5d16988dbd
--- /dev/null
+++ b/qa/qa/support/formatters/quarantine_formatter.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+module QA
+ module Support
+ module Formatters
+ class QuarantineFormatter < ::RSpec::Core::Formatters::BaseFormatter
+ include Specs::Helpers::Quarantine
+
+ ::RSpec::Core::Formatters.register(
+ self,
+ :example_group_started,
+ :example_started
+ )
+
+ # Starts example group
+ # @param [RSpec::Core::Notifications::GroupNotification] example_group_notification
+ # @return [void]
+ def example_group_started(example_group_notification)
+ group = example_group_notification.group
+
+ skip_or_run_quarantined_tests_or_contexts(filters, group)
+ end
+
+ # Starts example
+ # @param [RSpec::Core::Notifications::ExampleNotification] example_notification
+ # @return [void]
+ def example_started(example_notification)
+ example = example_notification.example
+
+ # if skip propagated from example_group, do not reset skip metadata
+ skip_or_run_quarantined_tests_or_contexts(filters, example) unless example.metadata[:skip]
+ end
+
+ private
+
+ def filters
+ @filters ||= ::RSpec.configuration.inclusion_filter.rules
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/support/formatters/test_stats_formatter.rb b/qa/qa/support/formatters/test_stats_formatter.rb
new file mode 100644
index 00000000000..0f76a924b10
--- /dev/null
+++ b/qa/qa/support/formatters/test_stats_formatter.rb
@@ -0,0 +1,156 @@
+# frozen_string_literal: true
+
+module QA
+ module Support
+ module Formatters
+ class TestStatsFormatter < RSpec::Core::Formatters::BaseFormatter
+ RSpec::Core::Formatters.register(self, :stop)
+
+ # Finish test execution
+ #
+ # @param [RSpec::Core::Notifications::ExamplesNotification] notification
+ # @return [void]
+ def stop(notification)
+ return log(:warn, 'Missing QA_INFLUXDB_URL, skipping metrics export!') unless influxdb_url
+ return log(:warn, 'Missing QA_INFLUXDB_TOKEN, skipping metrics export!') unless influxdb_token
+
+ data = notification.examples.map { |example| test_stats(example) }.compact
+ influx_client.create_write_api.write(data: data)
+ log(:info, "Pushed #{data.length} entries to influxdb")
+ rescue StandardError => e
+ log(:error, "Failed to push data to influxdb, error: #{e}")
+ end
+
+ private
+
+ # InfluxDb client
+ #
+ # @return [InfluxDB2::Client]
+ def influx_client
+ @influx_client ||= InfluxDB2::Client.new(
+ influxdb_url,
+ influxdb_token,
+ bucket: 'e2e-test-stats',
+ org: 'gitlab-qa',
+ use_ssl: false,
+ precision: InfluxDB2::WritePrecision::NANOSECOND
+ )
+ end
+
+ # InfluxDb instance url
+ #
+ # @return [String]
+ def influxdb_url
+ @influxdb_url ||= env('QA_INFLUXDB_URL')
+ end
+
+ # Influxdb token
+ #
+ # @return [String]
+ def influxdb_token
+ @influxdb_token ||= env('QA_INFLUXDB_TOKEN')
+ end
+
+ # Transform example to influxdb compatible metrics data
+ # https://github.com/influxdata/influxdb-client-ruby#data-format
+ #
+ # @param [RSpec::Core::Example] example
+ # @return [Hash]
+ def test_stats(example)
+ {
+ name: 'test-stats',
+ time: time,
+ tags: {
+ name: example.full_description,
+ file_path: example.metadata[:file_path].gsub('./qa/specs/features', ''),
+ status: example.execution_result.status,
+ reliable: example.metadata.key?(:reliable).to_s,
+ quarantined: example.metadata.key?(:quarantine).to_s,
+ retried: ((example.metadata[:retry_attempts] || 0) > 0).to_s,
+ job_name: job_name,
+ merge_request: merge_request,
+ run_type: env('QA_RUN_TYPE') || run_type
+ },
+ fields: {
+ id: example.id,
+ run_time: (example.execution_result.run_time * 1000).round,
+ retry_attempts: example.metadata[:retry_attempts] || 0,
+ job_url: QA::Runtime::Env.ci_job_url,
+ pipeline_url: env('CI_PIPELINE_URL'),
+ pipeline_id: env('CI_PIPELINE_ID')
+ }
+ }
+ rescue StandardError => e
+ log(:error, "Failed to transform example '#{example.id}', error: #{e}")
+ nil
+ end
+
+ # Project name
+ #
+ # @return [String]
+ def project_name
+ @project_name ||= QA::Runtime::Env.ci_project_name
+ end
+
+ # Base ci job name
+ #
+ # @return [String]
+ def job_name
+ @job_name ||= QA::Runtime::Env.ci_job_name.gsub(%r{ \d{1,2}/\d{1,2}}, '')
+ end
+
+ # Single common timestamp for all exported example metrics to keep data points consistently grouped
+ #
+ # @return [Time]
+ def time
+ @time ||= DateTime.strptime(env('CI_PIPELINE_CREATED_AT')).to_time
+ end
+
+ # Is a merge request execution
+ #
+ # @return [String]
+ def merge_request
+ @merge_request ||= (!!env('CI_MERGE_REQUEST_IID') || !!env('TOP_UPSTREAM_MERGE_REQUEST_IID')).to_s
+ end
+
+ # Test run type from staging, canary or production env
+ #
+ # @return [String>, nil]
+ def run_type
+ return unless %w[staging canary production].include?(project_name)
+
+ @run_type ||= begin
+ test_subset = if env('NO_ADMIN') == 'true'
+ 'sanity-no-admin'
+ elsif env('SMOKE_ONLY') == 'true'
+ 'sanity'
+ else
+ 'full'
+ end
+
+ "#{project_name}-#{test_subset}"
+ end
+ end
+
+ # Print log message
+ #
+ # @param [Symbol] level
+ # @param [String] message
+ # @return [void]
+ def log(level, message)
+ QA::Runtime::Logger.public_send(level, "influxdb exporter: #{message}")
+ end
+
+ # Return non empty environment variable value
+ #
+ # @param [String] name
+ # @return [String, nil]
+ def env(name)
+ return unless ENV[name] && !ENV[name].empty?
+
+ ENV[name]
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/support/helpers/stub_env.rb b/qa/qa/support/helpers/stub_env.rb
new file mode 100644
index 00000000000..d6514788c24
--- /dev/null
+++ b/qa/qa/support/helpers/stub_env.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+# Inspired by https://github.com/ljkbennett/stub_env/blob/master/lib/stub_env/helpers.rb
+module QA
+ module Support
+ module Helpers
+ module StubEnv
+ def stub_env(key_or_hash, value = nil)
+ init_stub unless env_stubbed?
+
+ if key_or_hash.is_a? Hash
+ key_or_hash.each { |k, v| add_stubbed_value(k, v) }
+ else
+ add_stubbed_value key_or_hash, value
+ end
+ end
+
+ private
+
+ STUBBED_KEY = '__STUBBED__'
+
+ def add_stubbed_value(key, value)
+ allow(ENV).to receive(:[]).with(key).and_return(value)
+ allow(ENV).to receive(:key?).with(key).and_return(true)
+ allow(ENV).to receive(:fetch).with(key).and_return(value)
+ allow(ENV).to receive(:fetch).with(key, anything) do |_, default_val|
+ value || default_val
+ end
+ end
+
+ def env_stubbed?
+ ENV[STUBBED_KEY]
+ end
+
+ def init_stub
+ allow(ENV).to receive(:[]).and_call_original
+ allow(ENV).to receive(:key?).and_call_original
+ allow(ENV).to receive(:fetch).and_call_original
+ # Prevent secrets from leaking in CI
+ allow(ENV).to receive(:inspect).and_return([])
+ add_stubbed_value(STUBBED_KEY, true)
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/support/matchers/eventually_matcher.rb b/qa/qa/support/matchers/eventually_matcher.rb
new file mode 100644
index 00000000000..ff8adab424b
--- /dev/null
+++ b/qa/qa/support/matchers/eventually_matcher.rb
@@ -0,0 +1,138 @@
+# frozen_string_literal: true
+
+# Rspec matcher with build in retry logic
+#
+# USAGE:
+#
+# Basic
+# expect { Something.that.takes.time.to_appear }.to eventually_eq(expected_result)
+# expect { Something.that.takes.time.to_appear }.not_to eventually_eq(expected_result)
+#
+# With duration and attempts override
+# expect { Something.that.takes.time.to_appear }.to(
+# eventually_eq(expected_result).within(max_duration: 10, max_attempts: 5)
+# )
+
+module QA
+ module Support
+ module Matchers
+ module EventuallyMatcher
+ %w[
+ eq
+ be
+ include
+ be_truthy
+ be_falsey
+ be_empty
+ ].each do |op|
+ RSpec::Matchers.define(:"eventually_#{op}") do |*expected|
+ chain(:within) do |kwargs = {}|
+ @retry_args = kwargs
+ @retry_args[:sleep_interval] = 0.5 unless @retry_args[:sleep_interval]
+ end
+
+ def supports_block_expectations?
+ true
+ end
+
+ match { |actual| wait_and_check(actual, :default_expectation) }
+
+ match_when_negated { |actual| wait_and_check(actual, :when_negated_expectation) }
+
+ description do
+ "eventually #{operator_msg} #{expected.inspect}"
+ end
+
+ failure_message do
+ "#{e}:\nexpected to #{description}, last attempt was #{@result.nil? ? 'nil' : @result}"
+ end
+
+ failure_message_when_negated do
+ "#{e}:\nexpected not to #{description}, last attempt was #{@result.nil? ? 'nil' : @result}"
+ end
+
+ # Execute rspec expectation within retrier
+ #
+ # @param [Proc] actual
+ # @param [Symbol] expectation_name
+ # @return [Boolean]
+ def wait_and_check(actual, expectation_name)
+ attempt = 0
+
+ QA::Runtime::Logger.debug("Running eventually matcher with '#{operator_msg}' operator")
+ QA::Support::Retrier.retry_until(**@retry_args) do
+ QA::Runtime::Logger.debug("evaluating expectation, attempt: #{attempt += 1}")
+
+ public_send(expectation_name, actual)
+ rescue RSpec::Expectations::ExpectationNotMetError, QA::Resource::ApiFabricator::ResourceNotFoundError
+ false
+ end
+ rescue QA::Support::Repeater::RetriesExceededError, QA::Support::Repeater::WaitExceededError => e
+ @e = e
+ false
+ end
+
+ # Execute rspec expectation
+ #
+ # @param [Proc] actual
+ # @return [void]
+ def default_expectation(actual)
+ expect(result(&actual)).to public_send(*expectation_args)
+ end
+
+ # Execute negated rspec expectation
+ #
+ # @param [Proc] actual
+ # @return [void]
+ def when_negated_expectation(actual)
+ expect(result(&actual)).not_to public_send(*expectation_args)
+ end
+
+ # Result of actual block
+ #
+ # @return [Object]
+ def result
+ @result = yield
+ end
+
+ # Error message placeholder to indicate waiter did not fail properly
+ # This message should not appear under normal circumstances since it should
+ # always be assigned from repeater
+ #
+ # @return [String]
+ def e
+ @e ||= 'Waiter did not fail!'
+ end
+
+ # Operator message
+ #
+ # @return [String]
+ def operator_msg
+ operator == 'eq' ? 'equal' : operator
+ end
+
+ # Expect operator
+ #
+ # @return [String]
+ def operator
+ @operator ||= name.to_s.match(/eventually_(.+?)$/).to_a[1].to_s
+ end
+
+ # Expectation args
+ #
+ # @return [String, Array]
+ def expectation_args
+ if operator.include?('truthy') || operator.include?('falsey') || operator.include?('empty')
+ operator
+ elsif operator == 'include' && expected.is_a?(Array)
+ [operator, *expected]
+ else
+ [operator, expected]
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/support/matchers/have_matcher.rb b/qa/qa/support/matchers/have_matcher.rb
new file mode 100644
index 00000000000..7001f53a7b7
--- /dev/null
+++ b/qa/qa/support/matchers/have_matcher.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module QA
+ module Support
+ module Matchers
+ module HaveMatcher
+ PREDICATE_TARGETS = %w[
+ element
+ file_content
+ assignee
+ child_pipeline
+ content
+ design
+ file
+ issue
+ job
+ package
+ pipeline
+ related_issue_item
+ snippet_description
+ tag
+ ].each do |predicate|
+ RSpec::Matchers.define "have_#{predicate}" do |*args, **kwargs|
+ match do |page_object|
+ page_object.public_send("has_#{predicate}?", *args, **kwargs)
+ end
+
+ match_when_negated do |page_object|
+ page_object.public_send("has_no_#{predicate}?", *args, **kwargs)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/support/matchers/have_text.rb b/qa/qa/support/matchers/have_text.rb
new file mode 100644
index 00000000000..2bae2971be3
--- /dev/null
+++ b/qa/qa/support/matchers/have_text.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+module QA
+ module Support
+ module Matchers
+ class HaveText
+ def initialize(expected_text, **kwargs)
+ @expected_text = expected_text
+ @kwargs = kwargs
+ end
+
+ def matches?(actual)
+ @actual = wrap(actual)
+ @actual.has_text?(@expected_text, **@kwargs)
+ end
+
+ def does_not_match?(actual)
+ @actual = wrap(actual)
+ @actual.has_no_text?(@expected_text, **@kwargs)
+ end
+
+ def failure_message
+ "expected to find text \"#{@expected_text}\" in \"#{normalized_actual_text}\""
+ end
+
+ def failure_message_when_negated
+ "expected not to find text \"#{@expected_text}\" in \"#{normalized_actual_text}\""
+ end
+
+ def normalized_actual_text
+ @actual.text.gsub(/\s+/, " ")
+ end
+
+ # From https://github.com/teamcapybara/capybara/blob/fe5940c6afbfe32152df936ce03ad1371ae05354/lib/capybara/rspec/matchers/base.rb#L66
+ def wrap(actual)
+ actual = actual.to_capybara_node if actual.respond_to?(:to_capybara_node)
+ @context_el = if actual.respond_to?(:has_selector?)
+ actual
+ else
+ Capybara.string(actual.to_s)
+ end
+ end
+ end
+
+ def have_text(text, **kwargs) # rubocop:disable Naming/PredicateName
+ HaveText.new(text, **kwargs)
+ end
+
+ alias_method :have_content, :have_text
+ end
+ end
+end
diff --git a/qa/qa/tools/delete_projects.rb b/qa/qa/tools/delete_projects.rb
index 8a690373a37..240901eea6f 100644
--- a/qa/qa/tools/delete_projects.rb
+++ b/qa/qa/tools/delete_projects.rb
@@ -10,7 +10,7 @@ require_relative '../../qa'
module QA
module Tools
class DeleteProjects
- include Support::Api
+ include Support::API
def initialize
raise ArgumentError, "Please provide GITLAB_ADDRESS environment variable" unless ENV['GITLAB_ADDRESS']
diff --git a/qa/qa/tools/delete_subgroups.rb b/qa/qa/tools/delete_subgroups.rb
index b9e3ed66013..2734a702536 100644
--- a/qa/qa/tools/delete_subgroups.rb
+++ b/qa/qa/tools/delete_subgroups.rb
@@ -10,7 +10,7 @@ require_relative '../../qa'
module QA
module Tools
class DeleteSubgroups
- include Support::Api
+ include Support::API
def initialize
raise ArgumentError, "Please provide GITLAB_ADDRESS" unless ENV['GITLAB_ADDRESS']
diff --git a/qa/qa/tools/delete_test_ssh_keys.rb b/qa/qa/tools/delete_test_ssh_keys.rb
index dea6930de1e..58ab4865336 100644
--- a/qa/qa/tools/delete_test_ssh_keys.rb
+++ b/qa/qa/tools/delete_test_ssh_keys.rb
@@ -15,7 +15,7 @@ require_relative '../../qa'
module QA
module Tools
class DeleteTestSSHKeys
- include Support::Api
+ include Support::API
ITEMS_PER_PAGE = '100'
diff --git a/qa/qa/tools/generate_perf_testdata.rb b/qa/qa/tools/generate_perf_testdata.rb
index ec1aa20c3b8..8e5da94e7e6 100644
--- a/qa/qa/tools/generate_perf_testdata.rb
+++ b/qa/qa/tools/generate_perf_testdata.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'securerandom'
-require 'faker'
require 'yaml'
require_relative '../../qa'
# This script generates testdata for Performance Testing.
@@ -12,7 +10,7 @@ require_relative '../../qa'
module QA
module Tools
class GeneratePerfTestdata
- include Support::Api
+ include Support::API
def initialize
raise ArgumentError, "Please provide GITLAB_ADDRESS" unless ENV['GITLAB_ADDRESS']
diff --git a/qa/qa/vendor/jira/jira_api.rb b/qa/qa/vendor/jira/jira_api.rb
index 65b080df3d0..64af824418d 100644
--- a/qa/qa/vendor/jira/jira_api.rb
+++ b/qa/qa/vendor/jira/jira_api.rb
@@ -5,7 +5,7 @@ module QA
module Jira
class JiraAPI
include Scenario::Actable
- include Support::Api
+ include Support::API
def base_url
host = QA::Runtime::Env.jira_hostname || 'localhost'
diff --git a/qa/qa/vendor/saml_idp/page/base.rb b/qa/qa/vendor/saml_idp/page/base.rb
index 286cb0a8cd8..39413a64d5a 100644
--- a/qa/qa/vendor/saml_idp/page/base.rb
+++ b/qa/qa/vendor/saml_idp/page/base.rb
@@ -2,7 +2,7 @@
module QA
module Vendor
- module SAMLIdp
+ module SamlIdp
module Page
class Base
include Capybara::DSL
diff --git a/qa/qa/vendor/saml_idp/page/login.rb b/qa/qa/vendor/saml_idp/page/login.rb
index 041b4a0feee..dc6925109f7 100644
--- a/qa/qa/vendor/saml_idp/page/login.rb
+++ b/qa/qa/vendor/saml_idp/page/login.rb
@@ -4,7 +4,7 @@ require 'capybara/dsl'
module QA
module Vendor
- module SAMLIdp
+ module SamlIdp
module Page
class Login < Page::Base
def login(username, password)
diff --git a/qa/spec/git/repository_spec.rb b/qa/spec/git/repository_spec.rb
index 77639c54b79..6b100f9dc16 100644
--- a/qa/spec/git/repository_spec.rb
+++ b/qa/spec/git/repository_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
RSpec.describe QA::Git::Repository do
- include Helpers::StubENV
+ include QA::Support::Helpers::StubEnv
shared_context 'unresolvable git directory' do
let(:repo_uri) { 'http://foo/bar.git' }
diff --git a/qa/spec/page/logging_spec.rb b/qa/spec/page/logging_spec.rb
index 3e1011dcd2a..7c521f60b84 100644
--- a/qa/spec/page/logging_spec.rb
+++ b/qa/spec/page/logging_spec.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
require 'capybara/dsl'
-require 'logger'
RSpec.describe QA::Support::Page::Logging do
let(:page) { double.as_null_object }
diff --git a/qa/spec/qa_deprecation_toolkit_env.rb b/qa/spec/qa_deprecation_toolkit_env.rb
index cdd5d954b20..2a21961d89e 100644
--- a/qa/spec/qa_deprecation_toolkit_env.rb
+++ b/qa/spec/qa_deprecation_toolkit_env.rb
@@ -12,7 +12,7 @@ module QaDeprecationToolkitEnv
end
def self.configure!
- # Enable ruby deprecations for keywords, it's suppressed by default in Ruby 2.7.2
+ # Enable ruby deprecations for keywords, it's suppressed by default in Ruby 2.7
Warning[:deprecated] = true
DeprecationToolkit::Configuration.test_runner = :rspec
diff --git a/qa/spec/resource/base_spec.rb b/qa/spec/resource/base_spec.rb
index c6dd56b5f47..b24ced9e310 100644
--- a/qa/spec/resource/base_spec.rb
+++ b/qa/spec/resource/base_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
RSpec.describe QA::Resource::Base do
- include Helpers::StubENV
+ include QA::Support::Helpers::StubEnv
let(:resource) { spy('resource') }
let(:location) { 'http://location' }
diff --git a/qa/spec/runtime/api/client_spec.rb b/qa/spec/runtime/api/client_spec.rb
index 36ee563de39..c8439df3b35 100644
--- a/qa/spec/runtime/api/client_spec.rb
+++ b/qa/spec/runtime/api/client_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
RSpec.describe QA::Runtime::API::Client do
- include Helpers::StubENV
+ include QA::Support::Helpers::StubEnv
describe 'initialization' do
it 'defaults to :gitlab address' do
diff --git a/qa/spec/runtime/env_spec.rb b/qa/spec/runtime/env_spec.rb
index 1d702b70d10..fb18311bb52 100644
--- a/qa/spec/runtime/env_spec.rb
+++ b/qa/spec/runtime/env_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
RSpec.describe QA::Runtime::Env do
- include Helpers::StubENV
+ include QA::Support::Helpers::StubEnv
shared_examples 'boolean method' do |**kwargs|
it_behaves_like 'boolean method with parameter', kwargs
diff --git a/qa/spec/runtime/namespace_spec.rb b/qa/spec/runtime/namespace_spec.rb
index 92836862864..04d4769b07b 100644
--- a/qa/spec/runtime/namespace_spec.rb
+++ b/qa/spec/runtime/namespace_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
RSpec.describe QA::Runtime::Namespace do
- include Helpers::StubENV
+ include QA::Support::Helpers::StubEnv
describe '.name' do
context 'when CACHE_NAMESPACE_NAME is not defined' do
diff --git a/qa/spec/runtime/release_spec.rb b/qa/spec/runtime/release_spec.rb
index b4e278fb546..29871cbe301 100644
--- a/qa/spec/runtime/release_spec.rb
+++ b/qa/spec/runtime/release_spec.rb
@@ -30,23 +30,4 @@ RSpec.describe QA::Runtime::Release do
end
end
end
-
- context 'when release version does not have extension strategy' do
- before do
- allow_any_instance_of(described_class)
- .to receive(:version).and_return('something')
- end
-
- describe '#strategy' do
- it 'raises error' do
- expect { subject.strategy }.to raise_error(LoadError)
- end
- end
-
- describe 'delegated class methods' do
- it 'raises error' do
- expect { described_class.some_method(2, 3) }.to raise_error(LoadError)
- end
- end
- end
end
diff --git a/qa/spec/spec_helper.rb b/qa/spec/spec_helper.rb
index 0df7b94b894..4f0f93bf020 100644
--- a/qa/spec/spec_helper.rb
+++ b/qa/spec/spec_helper.rb
@@ -1,33 +1,30 @@
# frozen_string_literal: true
require_relative '../qa'
-require 'rspec/retry'
-require 'rspec-parameterized'
+
+require 'securerandom'
+require 'pathname'
require 'active_support/core_ext/hash'
require 'active_support/core_ext/object/blank'
require_relative 'qa_deprecation_toolkit_env'
QaDeprecationToolkitEnv.configure!
-if ENV['CI'] && QA::Runtime::Env.knapsack? && !ENV['NO_KNAPSACK']
- require 'knapsack'
- Knapsack::Adapters::RSpecAdapter.bind
-end
+Knapsack::Adapters::RSpecAdapter.bind if ENV['CI'] && QA::Runtime::Env.knapsack? && !ENV['NO_KNAPSACK']
QA::Runtime::Browser.configure!
QA::Runtime::AllureReport.configure!
QA::Runtime::Scenario.from_env(QA::Runtime::Env.runtime_scenario_attributes)
-Dir[::File.join(__dir__, "support/helpers/*.rb")].sort.each { |f| require f }
-Dir[::File.join(__dir__, "support/matchers/*.rb")].sort.each { |f| require f }
-Dir[::File.join(__dir__, "support/shared_contexts/*.rb")].sort.each { |f| require f }
Dir[::File.join(__dir__, "support/shared_examples/*.rb")].sort.each { |f| require f }
RSpec.configure do |config|
- config.include ::Matchers
+ config.include QA::Support::Matchers::EventuallyMatcher
+ config.include QA::Support::Matchers::HaveMatcher
- config.add_formatter QA::Specs::Helpers::ContextFormatter
- config.add_formatter QA::Specs::Helpers::QuarantineFormatter
+ config.add_formatter QA::Support::Formatters::ContextFormatter
+ config.add_formatter QA::Support::Formatters::QuarantineFormatter
+ config.add_formatter QA::Support::Formatters::TestStatsFormatter if QA::Runtime::Env.export_metrics?
config.before do |example|
QA::Runtime::Logger.debug("\nStarting test: #{example.full_description}\n")
diff --git a/qa/spec/specs/allure_report_spec.rb b/qa/spec/specs/allure_report_spec.rb
index 27bc0dd3d1d..34116ca6cbd 100644
--- a/qa/spec/specs/allure_report_spec.rb
+++ b/qa/spec/specs/allure_report_spec.rb
@@ -1,9 +1,7 @@
# frozen_string_literal: true
-require 'allure-rspec'
-
describe QA::Runtime::AllureReport do
- include Helpers::StubENV
+ include QA::Support::Helpers::StubEnv
let(:rspec_config) { double('RSpec::Core::Configuration', 'add_formatter': nil, after: nil) }
@@ -70,7 +68,8 @@ describe QA::Runtime::AllureReport do
it 'adds rspec and metadata formatter' do
expect(rspec_config).to have_received(:add_formatter).with(AllureRspecFormatter).ordered
- expect(rspec_config).to have_received(:add_formatter).with(QA::Support::AllureMetadataFormatter).ordered
+ expect(rspec_config).to have_received(:add_formatter)
+ .with(QA::Support::Formatters::AllureMetadataFormatter).ordered
end
it 'configures screenshot saving' do
diff --git a/qa/spec/specs/helpers/context_selector_spec.rb b/qa/spec/specs/helpers/context_selector_spec.rb
index cbdbe6698ae..0152fee6f5b 100644
--- a/qa/spec/specs/helpers/context_selector_spec.rb
+++ b/qa/spec/specs/helpers/context_selector_spec.rb
@@ -3,14 +3,14 @@
require 'rspec/core/sandbox'
RSpec.describe QA::Specs::Helpers::ContextSelector do
- include Helpers::StubENV
+ include QA::Support::Helpers::StubEnv
include QA::Specs::Helpers::RSpec
around do |ex|
QA::Runtime::Scenario.define(:gitlab_address, 'https://staging.gitlab.com')
RSpec::Core::Sandbox.sandboxed do |config|
- config.formatter = QA::Specs::Helpers::ContextFormatter
+ config.formatter = QA::Support::Formatters::ContextFormatter
# If there is an example-within-an-example, we want to make sure the inner example
# does not get a reference to the outer example (the real spec) if it calls
diff --git a/qa/spec/specs/helpers/quarantine_spec.rb b/qa/spec/specs/helpers/quarantine_spec.rb
index 548a8510988..8ea375cdb05 100644
--- a/qa/spec/specs/helpers/quarantine_spec.rb
+++ b/qa/spec/specs/helpers/quarantine_spec.rb
@@ -3,12 +3,12 @@
require 'rspec/core/sandbox'
RSpec.describe QA::Specs::Helpers::Quarantine do
- include Helpers::StubENV
+ include QA::Support::Helpers::StubEnv
include QA::Specs::Helpers::RSpec
around do |ex|
RSpec::Core::Sandbox.sandboxed do |config|
- config.formatter = QA::Specs::Helpers::QuarantineFormatter
+ config.formatter = QA::Support::Formatters::QuarantineFormatter
# If there is an example-within-an-example, we want to make sure the inner example
# does not get a reference to the outer example (the real spec) if it calls
diff --git a/qa/spec/specs/parallel_runner_spec.rb b/qa/spec/specs/parallel_runner_spec.rb
index c2d28bf81fb..d77b50fbe09 100644
--- a/qa/spec/specs/parallel_runner_spec.rb
+++ b/qa/spec/specs/parallel_runner_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
RSpec.describe QA::Specs::ParallelRunner do
- include Helpers::StubENV
+ include QA::Support::Helpers::StubEnv
before do
allow(QA::Runtime::Scenario).to receive(:attributes).and_return(parallel: true)
diff --git a/qa/spec/support/allure_metadata_formatter_spec.rb b/qa/spec/support/allure_metadata_formatter_spec.rb
deleted file mode 100644
index cb208642716..00000000000
--- a/qa/spec/support/allure_metadata_formatter_spec.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-# frozen_string_literal: true
-
-describe QA::Support::AllureMetadataFormatter do
- include Helpers::StubENV
-
- let(:formatter) { described_class.new(StringIO.new) }
-
- let(:rspec_example_notification) { double('RSpec::Core::Notifications::ExampleNotification', example: rspec_example) }
- let(:rspec_example) do
- double(
- 'RSpec::Core::Example',
- tms: nil,
- issue: nil,
- add_link: nil,
- attempts: 0,
- file_path: 'file/path/spec.rb',
- metadata: {
- testcase: 'testcase',
- quarantine: { issue: 'issue' }
- }
- )
- end
-
- let(:ci_job) { 'ee:relative 5' }
- let(:ci_job_url) { 'url' }
-
- before do
- stub_env('CI', 'true')
- stub_env('CI_JOB_NAME', ci_job)
- stub_env('CI_JOB_URL', ci_job_url)
- end
-
- it "adds additional data to report" do
- formatter.example_started(rspec_example_notification)
-
- aggregate_failures do
- expect(rspec_example).to have_received(:tms).with('Testcase', 'testcase')
- expect(rspec_example).to have_received(:issue).with('Quarantine issue', 'issue')
- expect(rspec_example).to have_received(:add_link).with(name: "Job(#{ci_job})", url: ci_job_url)
- expect(rspec_example).to have_received(:issue).with(
- 'Failure issues',
- 'https://gitlab.com/gitlab-org/gitlab/-/issues?scope=all&state=opened&search=spec.rb'
- )
- end
- end
-end
diff --git a/qa/spec/support/formatters/allure_metadata_formatter_spec.rb b/qa/spec/support/formatters/allure_metadata_formatter_spec.rb
new file mode 100644
index 00000000000..631d2eda54f
--- /dev/null
+++ b/qa/spec/support/formatters/allure_metadata_formatter_spec.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+describe QA::Support::Formatters::AllureMetadataFormatter do
+ include QA::Support::Helpers::StubEnv
+
+ let(:formatter) { described_class.new(StringIO.new) }
+
+ let(:rspec_example_notification) { double('RSpec::Core::Notifications::ExampleNotification', example: rspec_example) }
+ let(:rspec_example) do
+ double(
+ 'RSpec::Core::Example',
+ tms: nil,
+ issue: nil,
+ add_link: nil,
+ attempts: 0,
+ file_path: 'file/path/spec.rb',
+ metadata: {
+ testcase: 'testcase',
+ quarantine: { issue: 'issue' }
+ }
+ )
+ end
+
+ let(:ci_job) { 'ee:relative 5' }
+ let(:ci_job_url) { 'url' }
+
+ before do
+ stub_env('CI', 'true')
+ stub_env('CI_JOB_NAME', ci_job)
+ stub_env('CI_JOB_URL', ci_job_url)
+ end
+
+ it "adds additional data to report" do
+ formatter.example_started(rspec_example_notification)
+
+ aggregate_failures do
+ expect(rspec_example).to have_received(:issue).with('Quarantine issue', 'issue')
+ expect(rspec_example).to have_received(:add_link).with(name: "Job(#{ci_job})", url: ci_job_url)
+ expect(rspec_example).to have_received(:issue).with(
+ 'Failure issues',
+ 'https://gitlab.com/gitlab-org/gitlab/-/issues?scope=all&state=opened&search=spec.rb'
+ )
+ end
+ end
+end
diff --git a/qa/spec/support/formatters/test_stats_formatter_spec.rb b/qa/spec/support/formatters/test_stats_formatter_spec.rb
new file mode 100644
index 00000000000..fec7ec1c7c0
--- /dev/null
+++ b/qa/spec/support/formatters/test_stats_formatter_spec.rb
@@ -0,0 +1,171 @@
+# frozen_string_literal: true
+
+require 'rspec/core/sandbox'
+
+describe QA::Support::Formatters::TestStatsFormatter do
+ include QA::Support::Helpers::StubEnv
+ include QA::Specs::Helpers::RSpec
+
+ let(:url) { "http://influxdb.net" }
+ let(:token) { "token" }
+ let(:ci_timestamp) { "2021-02-23T20:58:41Z" }
+ let(:ci_job_name) { "test-job 1/5" }
+ let(:ci_job_url) { "url" }
+ let(:ci_pipeline_url) { "url" }
+ let(:ci_pipeline_id) { "123" }
+ let(:run_type) { 'staging-full' }
+ let(:reliable) { 'false' }
+ let(:quarantined) { 'false' }
+ let(:influx_client) { instance_double('InfluxDB2::Client', create_write_api: influx_write_api) }
+ let(:influx_write_api) { instance_double('InfluxDB2::WriteApi', write: nil) }
+
+ let(:influx_client_args) do
+ {
+ bucket: 'e2e-test-stats',
+ org: 'gitlab-qa',
+ use_ssl: false,
+ precision: InfluxDB2::WritePrecision::NANOSECOND
+ }
+ end
+
+ let(:data) do
+ {
+ name: 'test-stats',
+ time: DateTime.strptime(ci_timestamp).to_time,
+ tags: {
+ name: 'stats export spec',
+ file_path: './spec/support/formatters/test_stats_formatter_spec.rb',
+ status: :passed,
+ reliable: reliable,
+ quarantined: quarantined,
+ retried: "false",
+ job_name: "test-job",
+ merge_request: "false",
+ run_type: run_type
+ },
+ fields: {
+ id: './spec/support/formatters/test_stats_formatter_spec.rb[1:1]',
+ run_time: 0,
+ retry_attempts: 0,
+ job_url: ci_job_url,
+ pipeline_url: ci_pipeline_url,
+ pipeline_id: ci_pipeline_id
+ }
+ }
+ end
+
+ def run_spec(&spec)
+ spec ||= -> { it('spec') {} }
+
+ describe_successfully('stats export', &spec)
+ send_stop_notification
+ end
+
+ around do |example|
+ RSpec::Core::Sandbox.sandboxed do |config|
+ config.formatter = QA::Support::Formatters::TestStatsFormatter
+
+ config.before(:context) { RSpec.current_example = nil }
+
+ example.run
+ end
+ end
+
+ before do
+ allow(InfluxDB2::Client).to receive(:new).with(url, token, **influx_client_args) { influx_client }
+ end
+
+ context "without influxdb variables configured" do
+ it "skips export without influxdb url" do
+ stub_env('QA_INFLUXDB_URL', nil)
+ stub_env('QA_INFLUXDB_TOKEN', nil)
+
+ run_spec
+
+ expect(influx_client).not_to have_received(:create_write_api)
+ end
+
+ it "skips export without influxdb token" do
+ stub_env('QA_INFLUXDB_URL', url)
+ stub_env('QA_INFLUXDB_TOKEN', nil)
+
+ run_spec
+
+ expect(influx_client).not_to have_received(:create_write_api)
+ end
+ end
+
+ context 'with influxdb variables configured' do
+ let(:spec_name) { 'exports data' }
+ let(:run_type) { ci_job_name.gsub(%r{ \d{1,2}/\d{1,2}}, '') }
+
+ before do
+ stub_env('QA_INFLUXDB_URL', url)
+ stub_env('QA_INFLUXDB_TOKEN', token)
+ stub_env('CI_PIPELINE_CREATED_AT', ci_timestamp)
+ stub_env('CI_JOB_URL', ci_job_url)
+ stub_env('CI_JOB_NAME', ci_job_name)
+ stub_env('CI_PIPELINE_URL', ci_pipeline_url)
+ stub_env('CI_PIPELINE_ID', ci_pipeline_id)
+ stub_env('CI_MERGE_REQUEST_IID', nil)
+ stub_env('TOP_UPSTREAM_MERGE_REQUEST_IID', nil)
+ stub_env('QA_RUN_TYPE', run_type)
+ end
+
+ context 'with reliable spec' do
+ let(:reliable) { 'true' }
+
+ it 'exports data to influxdb with correct reliable tag' do
+ run_spec do
+ it('spec', :reliable) {}
+ end
+
+ expect(influx_write_api).to have_received(:write).with(data: [data])
+ end
+ end
+
+ context 'with quarantined spec' do
+ let(:quarantined) { 'true' }
+
+ it 'exports data to influxdb with correct quarantine tag' do
+ run_spec do
+ it('spec', :quarantine) {}
+ end
+
+ expect(influx_write_api).to have_received(:write).with(data: [data])
+ end
+ end
+
+ context 'with staging full run' do
+ let(:run_type) { 'staging-full' }
+
+ before do
+ stub_env('CI_PROJECT_NAME', 'staging')
+ stub_env('QA_RUN_TYPE', nil)
+ end
+
+ it 'exports data to influxdb with correct run type' do
+ run_spec
+
+ expect(influx_write_api).to have_received(:write).with(data: [data])
+ end
+ end
+
+ context 'with staging sanity no admin' do
+ let(:run_type) { 'staging-sanity-no-admin' }
+
+ before do
+ stub_env('CI_PROJECT_NAME', 'staging')
+ stub_env('NO_ADMIN', 'true')
+ stub_env('SMOKE_ONLY', 'true')
+ stub_env('QA_RUN_TYPE', nil)
+ end
+
+ it 'exports data to influxdb with correct run type' do
+ run_spec
+
+ expect(influx_write_api).to have_received(:write).with(data: [data])
+ end
+ end
+ end
+end
diff --git a/qa/spec/support/helpers/stub_env.rb b/qa/spec/support/helpers/stub_env.rb
deleted file mode 100644
index de8d2f47adf..00000000000
--- a/qa/spec/support/helpers/stub_env.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-# frozen_string_literal: true
-
-# Inspired by https://github.com/ljkbennett/stub_env/blob/master/lib/stub_env/helpers.rb
-module Helpers
- module StubENV
- def stub_env(key_or_hash, value = nil)
- init_stub unless env_stubbed?
-
- if key_or_hash.is_a? Hash
- key_or_hash.each { |k, v| add_stubbed_value(k, v) }
- else
- add_stubbed_value key_or_hash, value
- end
- end
-
- private
-
- STUBBED_KEY = '__STUBBED__'
-
- def add_stubbed_value(key, value)
- allow(ENV).to receive(:[]).with(key).and_return(value)
- allow(ENV).to receive(:key?).with(key).and_return(true)
- allow(ENV).to receive(:fetch).with(key).and_return(value)
- allow(ENV).to receive(:fetch).with(key, anything) do |_, default_val|
- value || default_val
- end
- end
-
- def env_stubbed?
- ENV[STUBBED_KEY]
- end
-
- def init_stub
- allow(ENV).to receive(:[]).and_call_original
- allow(ENV).to receive(:key?).and_call_original
- allow(ENV).to receive(:fetch).and_call_original
- # Prevent secrets from leaking in CI
- allow(ENV).to receive(:inspect).and_return([])
- add_stubbed_value(STUBBED_KEY, true)
- end
- end
-end
diff --git a/qa/spec/support/matchers/eventually_matcher.rb b/qa/spec/support/matchers/eventually_matcher.rb
deleted file mode 100644
index 7a35a3165ae..00000000000
--- a/qa/spec/support/matchers/eventually_matcher.rb
+++ /dev/null
@@ -1,133 +0,0 @@
-# frozen_string_literal: true
-
-# Rspec matcher with build in retry logic
-#
-# USAGE:
-#
-# Basic
-# expect { Something.that.takes.time.to_appear }.to eventually_eq(expected_result)
-# expect { Something.that.takes.time.to_appear }.not_to eventually_eq(expected_result)
-#
-# With duration and attempts override
-# expect { Something.that.takes.time.to_appear }.to eventually_eq(expected_result).within(max_duration: 10, max_attempts: 5)
-
-module Matchers
- %w[
- eq
- be
- include
- be_truthy
- be_falsey
- be_empty
- ].each do |op|
- RSpec::Matchers.define(:"eventually_#{op}") do |*expected|
- chain(:within) do |kwargs = {}|
- @retry_args = kwargs
- @retry_args[:sleep_interval] = 0.5 unless @retry_args[:sleep_interval]
- end
-
- def supports_block_expectations?
- true
- end
-
- match { |actual| wait_and_check(actual, :default_expectation) }
-
- match_when_negated { |actual| wait_and_check(actual, :when_negated_expectation) }
-
- description do
- "eventually #{operator_msg} #{expected.inspect}"
- end
-
- failure_message do
- "#{e}:\nexpected to #{description}, last attempt was #{@result.nil? ? 'nil' : @result}"
- end
-
- failure_message_when_negated do
- "#{e}:\nexpected not to #{description}, last attempt was #{@result.nil? ? 'nil' : @result}"
- end
-
- # Execute rspec expectation within retrier
- #
- # @param [Proc] actual
- # @param [Symbol] expectation_name
- # @return [Boolean]
- def wait_and_check(actual, expectation_name)
- attempt = 0
-
- QA::Runtime::Logger.debug("Running eventually matcher with '#{operator_msg}' operator")
- QA::Support::Retrier.retry_until(**@retry_args) do
- QA::Runtime::Logger.debug("evaluating expectation, attempt: #{attempt += 1}")
-
- public_send(expectation_name, actual)
- rescue RSpec::Expectations::ExpectationNotMetError, QA::Resource::ApiFabricator::ResourceNotFoundError
- false
- end
- rescue QA::Support::Repeater::RetriesExceededError, QA::Support::Repeater::WaitExceededError => e
- @e = e
- false
- end
-
- # Execute rspec expectation
- #
- # @param [Proc] actual
- # @return [void]
- def default_expectation(actual)
- expect(result(&actual)).to public_send(*expectation_args)
- end
-
- # Execute negated rspec expectation
- #
- # @param [Proc] actual
- # @return [void]
- def when_negated_expectation(actual)
- expect(result(&actual)).not_to public_send(*expectation_args)
- end
-
- # Result of actual block
- #
- # @return [Object]
- def result
- @result = yield
- end
-
- # Error message placeholder to indicate waiter did not fail properly
- # This message should not appear under normal circumstances since it should
- # always be assigned from repeater
- #
- # @return [String]
- def e
- @e ||= 'Waiter did not fail!'
- end
-
- # Operator message
- #
- # @return [String]
- def operator_msg
- case operator
- when 'eq' then 'equal'
- else operator
- end
- end
-
- # Expect operator
- #
- # @return [String]
- def operator
- @operator ||= name.to_s.match(/eventually_(.+?)$/).to_a[1].to_s
- end
-
- # Expectation args
- #
- # @return [String, Array]
- def expectation_args
- if operator.include?('truthy') || operator.include?('falsey') || operator.include?('empty')
- operator
- elsif operator == "include" && expected.is_a?(Array)
- [operator, *expected]
- else
- [operator, expected]
- end
- end
- end
- end
-end
diff --git a/qa/spec/support/matchers/have_matcher.rb b/qa/spec/support/matchers/have_matcher.rb
deleted file mode 100644
index 81288b97e6f..00000000000
--- a/qa/spec/support/matchers/have_matcher.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-module Matchers
- PREDICATE_TARGETS = %w[
- element
- file_content
- assignee
- child_pipeline
- content
- design
- file
- issue
- job
- package
- pipeline
- related_issue_item
- snippet_description
- tag
- ].each do |predicate|
- RSpec::Matchers.define "have_#{predicate}" do |*args, **kwargs|
- match do |page_object|
- page_object.public_send("has_#{predicate}?", *args, **kwargs) # rubocop:disable GitlabSecurity/PublicSend
- end
-
- match_when_negated do |page_object|
- page_object.public_send("has_no_#{predicate}?", *args, **kwargs) # rubocop:disable GitlabSecurity/PublicSend
- end
- end
- end
-end
diff --git a/qa/spec/support/matchers/have_text.rb b/qa/spec/support/matchers/have_text.rb
deleted file mode 100644
index 4e6fbf1f6d6..00000000000
--- a/qa/spec/support/matchers/have_text.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-# frozen_string_literal: true
-
-module Matchers
- class HaveText
- def initialize(expected_text, **kwargs)
- @expected_text = expected_text
- @kwargs = kwargs
- end
-
- def matches?(actual)
- @actual = wrap(actual)
- @actual.has_text?(@expected_text, **@kwargs)
- end
-
- def does_not_match?(actual)
- @actual = wrap(actual)
- @actual.has_no_text?(@expected_text, **@kwargs)
- end
-
- def failure_message
- "expected to find text \"#{@expected_text}\" in \"#{normalized_actual_text}\""
- end
-
- def failure_message_when_negated
- "expected not to find text \"#{@expected_text}\" in \"#{normalized_actual_text}\""
- end
-
- def normalized_actual_text
- @actual.text.gsub(/\s+/, " ")
- end
-
- # From https://github.com/teamcapybara/capybara/blob/fe5940c6afbfe32152df936ce03ad1371ae05354/lib/capybara/rspec/matchers/base.rb#L66
- def wrap(actual)
- actual = actual.to_capybara_node if actual.respond_to?(:to_capybara_node)
- @context_el = if actual.respond_to?(:has_selector?)
- actual
- else
- Capybara.string(actual.to_s)
- end
- end
- end
-
- def have_text(text, **kwargs) # rubocop:disable Naming/PredicateName
- HaveText.new(text, **kwargs)
- end
-
- alias_method :have_content, :have_text
-end
diff --git a/qa/spec/support/repeater_spec.rb b/qa/spec/support/repeater_spec.rb
index 18ccbf250cb..da8d6b18fb0 100644
--- a/qa/spec/support/repeater_spec.rb
+++ b/qa/spec/support/repeater_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'logger'
-require 'timecop'
require 'active_support/core_ext/integer/time'
RSpec.describe QA::Support::Repeater do
diff --git a/qa/spec/support/retrier_spec.rb b/qa/spec/support/retrier_spec.rb
index 4e27915553c..9ad3e85fea9 100644
--- a/qa/spec/support/retrier_spec.rb
+++ b/qa/spec/support/retrier_spec.rb
@@ -1,8 +1,5 @@
# frozen_string_literal: true
-require 'logger'
-require 'timecop'
-
RSpec.describe QA::Support::Retrier do
before do
logger = ::Logger.new $stdout
diff --git a/qa/spec/support/waiter_spec.rb b/qa/spec/support/waiter_spec.rb
index 5b0c2c95d0d..d0b216b5dc1 100644
--- a/qa/spec/support/waiter_spec.rb
+++ b/qa/spec/support/waiter_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'logger'
-
RSpec.describe QA::Support::Waiter do
before do
logger = ::Logger.new $stdout
diff --git a/rubocop/cop/gitlab/mark_used_feature_flags.rb b/rubocop/cop/gitlab/mark_used_feature_flags.rb
index a0de43abe85..03ee4805f4e 100644
--- a/rubocop/cop/gitlab/mark_used_feature_flags.rb
+++ b/rubocop/cop/gitlab/mark_used_feature_flags.rb
@@ -47,10 +47,21 @@ module RuboCop
:usage_data_static_site_editor_merge_requests # https://gitlab.com/gitlab-org/gitlab/-/issues/284083
].freeze
+ class << self
+ # We track feature flags in `on_new_investigation` only once per
+ # rubocop whole run instead once per file.
+ attr_accessor :feature_flags_already_tracked
+ end
+
# Called before all on_... have been called
# When refining this method, always call `super`
def on_new_investigation
super
+
+ return if self.class.feature_flags_already_tracked
+
+ self.class.feature_flags_already_tracked = true
+
track_dynamic_feature_flags!
track_usage_data_counters_known_events!
end
@@ -69,7 +80,7 @@ module RuboCop
flag_value = flag_value(node)
return unless flag_value
- if flag_arg_is_str_or_sym?(node)
+ if flag_arg_is_str_or_sym?(flag_arg)
if caller_is_feature_gitaly?(node)
save_used_feature_flag("gitaly_#{flag_value}")
else
@@ -84,9 +95,9 @@ module RuboCop
save_used_feature_flag(matching_feature_flag)
end
end
- elsif flag_arg_is_send_type?(node)
+ elsif flag_arg_is_send_type?(flag_arg)
puts_if_ci(node, "Feature flag is dynamic: '#{flag_value}.")
- elsif flag_arg_is_dstr_or_dsym?(node)
+ elsif flag_arg_is_dstr_or_dsym?(flag_arg)
str_prefix = flag_arg.children[0]
rest_children = flag_arg.children[1..]
@@ -159,18 +170,16 @@ module RuboCop
end.to_s.tr("\n/", ' _')
end
- def flag_arg_is_str_or_sym?(node)
- flag_arg = flag_arg(node)
+ def flag_arg_is_str_or_sym?(flag_arg)
flag_arg.str_type? || flag_arg.sym_type?
end
- def flag_arg_is_send_type?(node)
- flag_arg(node).send_type?
+ def flag_arg_is_send_type?(flag_arg)
+ flag_arg.send_type?
end
- def flag_arg_is_dstr_or_dsym?(node)
- flag = flag_arg(node)
- (flag.dstr_type? || flag.dsym_type?) && flag.children[0].str_type?
+ def flag_arg_is_dstr_or_dsym?(flag_arg)
+ (flag_arg.dstr_type? || flag_arg.dsym_type?) && flag_arg.children[0].str_type?
end
def caller_is_feature?(node)
diff --git a/rubocop/cop/migration/add_limit_to_text_columns.rb b/rubocop/cop/migration/add_limit_to_text_columns.rb
index f45551e60a4..b5780e87c19 100644
--- a/rubocop/cop/migration/add_limit_to_text_columns.rb
+++ b/rubocop/cop/migration/add_limit_to_text_columns.rb
@@ -13,8 +13,13 @@ module RuboCop
class AddLimitToTextColumns < RuboCop::Cop::Cop
include MigrationHelpers
+ TEXT_LIMIT_ATTRIBUTE_ALLOWED_SINCE = 2021_09_10_00_00_00
+
MSG = 'Text columns should always have a limit set (255 is suggested). ' \
- 'You can add a limit to a `text` column by using `add_text_limit`'
+ 'You can add a limit to a `text` column by using `add_text_limit` or by using `.text... limit: 255` inside `create_table`'
+
+ TEXT_LIMIT_ATTRIBUTE_NOT_ALLOWED = 'Text columns should always have a limit set (255 is suggested). Using limit: is not supported in this version. ' \
+ 'You can add a limit to a `text` column by using `add_text_limit` or `.text_limit` inside `create_table`'
def_node_matcher :reverting?, <<~PATTERN
(def :down ...)
@@ -37,15 +42,29 @@ module RuboCop
node.each_descendant(:send) do |send_node|
next unless text_operation?(send_node)
- # We require a limit for the same table and attribute name
- if text_limit_missing?(node, *table_and_attribute_name(send_node))
- add_offense(send_node, location: :selector)
+ if text_operation_with_limit?(send_node)
+ add_offense(send_node, location: :selector, message: TEXT_LIMIT_ATTRIBUTE_NOT_ALLOWED) if version(node) < TEXT_LIMIT_ATTRIBUTE_ALLOWED_SINCE
+ else
+ # We require a limit for the same table and attribute name
+ if text_limit_missing?(node, *table_and_attribute_name(send_node))
+ add_offense(send_node, location: :selector)
+ end
end
end
end
private
+ def text_operation_with_limit?(node)
+ migration_method = node.children[1]
+
+ return unless migration_method == :text
+
+ if attributes = node.children[3]
+ attributes.pairs.find { |pair| pair.key.value == :limit }.present?
+ end
+ end
+
def text_operation?(node)
# Don't complain about text arrays
return false if array_column?(node)
diff --git a/rubocop/cop/migration/prevent_index_creation.rb b/rubocop/cop/migration/prevent_index_creation.rb
index c90f911d24e..c383466f73b 100644
--- a/rubocop/cop/migration/prevent_index_creation.rb
+++ b/rubocop/cop/migration/prevent_index_creation.rb
@@ -12,16 +12,29 @@ module RuboCop
MSG = "Adding new index to #{FORBIDDEN_TABLES.join(", ")} is forbidden, see https://gitlab.com/gitlab-org/gitlab/-/issues/332886"
+ def on_new_investigation
+ super
+ @forbidden_tables_used = false
+ end
+
def_node_matcher :add_index?, <<~PATTERN
- (send nil? :add_index (sym #forbidden_tables?) ...)
+ (send nil? :add_index ({sym|str} #forbidden_tables?) ...)
PATTERN
def_node_matcher :add_concurrent_index?, <<~PATTERN
- (send nil? :add_concurrent_index (sym #forbidden_tables?) ...)
+ (send nil? :add_concurrent_index ({sym|str} #forbidden_tables?) ...)
PATTERN
- def forbidden_tables?(node)
- FORBIDDEN_TABLES.include?(node)
+ def_node_matcher :forbidden_constant_defined?, <<~PATTERN
+ (casgn nil? _ ({sym|str} #forbidden_tables?))
+ PATTERN
+
+ def_node_matcher :add_concurrent_index_with_constant?, <<~PATTERN
+ (send nil? :add_concurrent_index (const nil? _) ...)
+ PATTERN
+
+ def on_casgn(node)
+ @forbidden_tables_used = !!forbidden_constant_defined?(node)
end
def on_def(node)
@@ -32,8 +45,18 @@ module RuboCop
end
end
+ private
+
+ def forbidden_tables?(node)
+ FORBIDDEN_TABLES.include?(node.to_sym)
+ end
+
def offense?(node)
- add_index?(node) || add_concurrent_index?(node)
+ add_index?(node) || add_concurrent_index?(node) || any_constant_used_with_forbidden_tables?(node)
+ end
+
+ def any_constant_used_with_forbidden_tables?(node)
+ add_concurrent_index_with_constant?(node) && @forbidden_tables_used
end
end
end
diff --git a/rubocop/cop/migration/versioned_migration_class.rb b/rubocop/cop/migration/versioned_migration_class.rb
new file mode 100644
index 00000000000..f2e4550c691
--- /dev/null
+++ b/rubocop/cop/migration/versioned_migration_class.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+require_relative '../../migration_helpers'
+
+module RuboCop
+ module Cop
+ module Migration
+ class VersionedMigrationClass < RuboCop::Cop::Cop
+ include MigrationHelpers
+
+ ENFORCED_SINCE = 2021_09_02_00_00_00
+
+ MSG_INHERIT = 'Don\'t inherit from ActiveRecord::Migration but use Gitlab::Database::Migration[1.0] instead. See https://docs.gitlab.com/ee/development/migration_style_guide.html#migration-helpers-and-versioning.'
+ MSG_INCLUDE = 'Don\'t include migration helper modules directly. Inherit from Gitlab::Database::Migration[1.0] instead. See https://docs.gitlab.com/ee/development/migration_style_guide.html#migration-helpers-and-versioning.'
+
+ ACTIVERECORD_MIGRATION_CLASS = 'ActiveRecord::Migration'
+
+ def_node_search :includes_helpers?, <<~PATTERN
+ (send nil? :include
+ (const
+ (const
+ (const nil? :Gitlab) :Database) :MigrationHelpers))
+ PATTERN
+
+ def on_class(node)
+ return unless relevant_migration?(node)
+ return unless activerecord_migration_class?(node)
+
+ add_offense(node, location: :expression, message: MSG_INHERIT)
+ end
+
+ def on_send(node)
+ return unless relevant_migration?(node)
+
+ add_offense(node, location: :expression, message: MSG_INCLUDE) if includes_helpers?(node)
+ end
+
+ private
+
+ def relevant_migration?(node)
+ in_migration?(node) && version(node) >= ENFORCED_SINCE
+ end
+
+ def activerecord_migration_class?(node)
+ superclass(node) == ACTIVERECORD_MIGRATION_CLASS
+ end
+
+ def superclass(class_node)
+ _, *others = class_node.descendants
+
+ others.find { |node| node.const_type? && node&.const_name != 'Types' }&.const_name
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/cop/performance/active_record_subtransaction_methods.rb b/rubocop/cop/performance/active_record_subtransaction_methods.rb
new file mode 100644
index 00000000000..3b89d3ab858
--- /dev/null
+++ b/rubocop/cop/performance/active_record_subtransaction_methods.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module RuboCop
+ module Cop
+ module Performance
+ # Cop that disallows certain methods that rely on subtransactions in their implementation.
+ # Companion to Performance/ActiveRecordSubtransactions, which bans direct usage of subtransactions.
+ class ActiveRecordSubtransactionMethods < RuboCop::Cop::Cop
+ MSG = 'Methods that rely on subtransactions should not be used. ' \
+ 'For more information see: https://gitlab.com/gitlab-org/gitlab/-/issues/338346'
+
+ DISALLOWED_METHODS = %i[
+ safe_ensure_unique
+ safe_find_or_create_by
+ safe_find_or_create_by!
+ with_fast_read_statement_timeout
+ create_or_find_by
+ create_or_find_by!
+ ].to_set.freeze
+
+ def on_send(node)
+ return unless DISALLOWED_METHODS.include?(node.method_name)
+
+ add_offense(node, location: :selector)
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/cop/performance/active_record_subtransactions.rb b/rubocop/cop/performance/active_record_subtransactions.rb
new file mode 100644
index 00000000000..a550b558e52
--- /dev/null
+++ b/rubocop/cop/performance/active_record_subtransactions.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module RuboCop
+ module Cop
+ module Performance
+ class ActiveRecordSubtransactions < RuboCop::Cop::Cop
+ MSG = 'Subtransactions should not be used. ' \
+ 'For more information see: https://gitlab.com/gitlab-org/gitlab/-/issues/338346'
+
+ def_node_matcher :match_transaction_with_options, <<~PATTERN
+ (send _ :transaction (hash $...))
+ PATTERN
+
+ def_node_matcher :subtransaction_option?, <<~PATTERN
+ (pair (:sym :requires_new) (true))
+ PATTERN
+
+ def on_send(node)
+ match_transaction_with_options(node) do |option_nodes|
+ option_nodes.each do |option_node|
+ next unless subtransaction_option?(option_node)
+
+ add_offense(option_node)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/cop/sidekiq_load_balancing/worker_data_consistency.rb b/rubocop/cop/sidekiq_load_balancing/worker_data_consistency.rb
new file mode 100644
index 00000000000..7a2e7ee00b4
--- /dev/null
+++ b/rubocop/cop/sidekiq_load_balancing/worker_data_consistency.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+require_relative '../../code_reuse_helpers'
+
+module RuboCop
+ module Cop
+ module SidekiqLoadBalancing
+ # This cop checks for a call to `data_consistency` to exist in Sidekiq workers.
+ #
+ # @example
+ #
+ # # bad
+ # class BadWorker
+ # def perform
+ # end
+ # end
+ #
+ # # good
+ # class GoodWorker
+ # data_consistency :delayed
+ #
+ # def perform
+ # end
+ # end
+ #
+ class WorkerDataConsistency < RuboCop::Cop::Cop
+ include CodeReuseHelpers
+
+ HELP_LINK = 'https://docs.gitlab.com/ee/development/sidekiq_style_guide.html#job-data-consistency-strategies'
+
+ MSG = <<~MSG
+ Should define data_consistency expectation.
+
+ It is encouraged for workers to use database replicas as much as possible by declaring
+ data_consistency to use the :delayed or :sticky modes. Mode :always will result in the
+ worker always hitting the primary database node for both reads and writes, which limits
+ scalability.
+
+ Some guidelines:
+
+ 1. If your worker mostly writes or reads its own writes, use mode :always. TRY TO AVOID THIS.
+ 2. If your worker performs mostly reads and can tolerate small delays, use mode :delayed.
+ 3. If your worker performs mostly reads but cannot tolerate any delays, use mode :sticky.
+
+ See #{HELP_LINK} for a more detailed explanation of these settings.
+ MSG
+
+ def_node_search :application_worker?, <<~PATTERN
+ `(send nil? :include (const nil? :ApplicationWorker))
+ PATTERN
+
+ def_node_search :data_consistency_defined?, <<~PATTERN
+ `(send nil? :data_consistency ...)
+ PATTERN
+
+ def on_class(node)
+ return unless in_worker?(node) && application_worker?(node)
+ return if data_consistency_defined?(node)
+
+ add_offense(node, location: :expression)
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_with_deduplication.rb b/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_with_deduplication.rb
new file mode 100644
index 00000000000..e8b4b513a23
--- /dev/null
+++ b/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_with_deduplication.rb
@@ -0,0 +1,154 @@
+# frozen_string_literal: true
+
+require_relative '../../code_reuse_helpers'
+
+module RuboCop
+ module Cop
+ module SidekiqLoadBalancing
+ # This cop checks for including_scheduled: true option in idempotent Sidekiq workers that utilize load balancing capabilities.
+ #
+ # @example
+ #
+ # # bad
+ # class BadWorker
+ # include ApplicationWorker
+ #
+ # data_consistency :delayed
+ # idempotent!
+ #
+ # def perform
+ # end
+ # end
+ #
+ # # bad
+ # class BadWorker
+ # include ApplicationWorker
+ #
+ # data_consistency :delayed
+ #
+ # deduplicate :until_executing
+ # idempotent!
+ #
+ # def perform
+ # end
+ # end
+ #
+ # # good
+ # class GoodWorker
+ # include ApplicationWorker
+ #
+ # data_consistency :delayed
+ #
+ # deduplicate :until_executing, including_scheduled: true
+ # idempotent!
+ #
+ # def perform
+ # end
+ # end
+ #
+ class WorkerDataConsistencyWithDeduplication < RuboCop::Cop::Base
+ include CodeReuseHelpers
+ extend AutoCorrector
+
+ HELP_LINK = 'https://docs.gitlab.com/ee/development/sidekiq_style_guide.html#scheduling-jobs-in-the-future'
+ REPLACEMENT = ', including_scheduled: true'
+ DEFAULT_STRATEGY = ':until_executing'
+
+ MSG = <<~MSG
+ Workers that declare either `:sticky` or `:delayed` data consistency become eligible for database load-balancing.
+ In both cases, jobs are enqueued with a short delay.
+
+ If you do want to deduplicate jobs that utilize load-balancing, you need to specify including_scheduled: true
+ argument when defining deduplication strategy.
+
+ See #{HELP_LINK} for a more detailed explanation of these settings.
+ MSG
+
+ def_node_search :application_worker?, <<~PATTERN
+ `(send nil? :include (const nil? :ApplicationWorker))
+ PATTERN
+
+ def_node_search :idempotent_worker?, <<~PATTERN
+ `(send nil? :idempotent!)
+ PATTERN
+
+ def_node_search :data_consistency_defined?, <<~PATTERN
+ `(send nil? :data_consistency (sym {:sticky :delayed }))
+ PATTERN
+
+ def_node_matcher :including_scheduled?, <<~PATTERN
+ `(hash <(pair (sym :including_scheduled) (%1)) ...>)
+ PATTERN
+
+ def_node_matcher :deduplicate_strategy?, <<~PATTERN
+ `(send nil? :deduplicate (sym $_) $(...)?)
+ PATTERN
+
+ def on_class(node)
+ return unless in_worker?(node)
+ return unless application_worker?(node)
+ return unless idempotent_worker?(node)
+ return unless data_consistency_defined?(node)
+
+ @strategy, options = deduplicate_strategy?(node)
+ including_scheduled = false
+ if options
+ @deduplicate_options = options[0]
+ including_scheduled = including_scheduled?(@deduplicate_options, :true) # rubocop:disable Lint/BooleanSymbol
+ end
+
+ @offense = !(including_scheduled || @strategy == :none)
+ end
+
+ def on_send(node)
+ return unless offense
+
+ if node.children[1] == :deduplicate
+ add_offense(node.loc.expression) do |corrector|
+ autocorrect_deduplicate_strategy(node, corrector)
+ end
+ elsif node.children[1] == :idempotent! && !strategy
+ add_offense(node.loc.expression) do |corrector|
+ autocorrect_missing_deduplicate_strategy(node, corrector)
+ end
+ end
+ end
+
+ private
+
+ attr_reader :offense, :deduplicate_options, :strategy
+
+ def autocorrect_deduplicate_with_options(corrector)
+ if including_scheduled?(deduplicate_options, :false) # rubocop:disable Lint/BooleanSymbol
+ replacement = deduplicate_options.source.sub("including_scheduled: false", "including_scheduled: true")
+ corrector.replace(deduplicate_options.loc.expression, replacement)
+ else
+ corrector.insert_after(deduplicate_options.loc.expression, REPLACEMENT)
+ end
+ end
+
+ def autocorrect_deduplicate_without_options(node, corrector)
+ corrector.insert_after(node.loc.expression, REPLACEMENT)
+ end
+
+ def autocorrect_missing_deduplicate_strategy(node, corrector)
+ indent_found = node.source_range.source_line =~ /^( +)/
+ # Get indentation size
+ whitespaces = Regexp.last_match(1).size if indent_found
+ replacement = "deduplicate #{DEFAULT_STRATEGY}#{REPLACEMENT}\n"
+ # Add indentation in the end since we are inserting a whole line before idempotent!
+ replacement += ' ' * whitespaces.to_i
+ corrector.insert_before(node.source_range, replacement)
+ end
+
+ def autocorrect_deduplicate_strategy(node, corrector)
+ if deduplicate_options
+ autocorrect_deduplicate_with_options(corrector)
+ else
+ autocorrect_deduplicate_without_options(node, corrector)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/cop/worker_data_consistency.rb b/rubocop/cop/worker_data_consistency.rb
deleted file mode 100644
index e9047750f3e..00000000000
--- a/rubocop/cop/worker_data_consistency.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-# frozen_string_literal: true
-
-require_relative '../code_reuse_helpers'
-
-module RuboCop
- module Cop
- # This cop checks for a call to `data_consistency` to exist in Sidekiq workers.
- #
- # @example
- #
- # # bad
- # class BadWorker
- # def perform
- # end
- # end
- #
- # # good
- # class GoodWorker
- # data_consistency :delayed
- #
- # def perform
- # end
- # end
- #
- class WorkerDataConsistency < RuboCop::Cop::Cop
- include CodeReuseHelpers
-
- HELP_LINK = 'https://docs.gitlab.com/ee/development/sidekiq_style_guide.html#job-data-consistency-strategies'
-
- MSG = <<~MSG
- Should define data_consistency expectation.
-
- It is encouraged for workers to use database replicas as much as possible by declaring
- data_consistency to use the :delayed or :sticky modes. Mode :always will result in the
- worker always hitting the primary database node for both reads and writes, which limits
- scalability.
-
- Some guidelines:
-
- 1. If your worker mostly writes or reads its own writes, use mode :always. TRY TO AVOID THIS.
- 2. If your worker performs mostly reads and can tolerate small delays, use mode :delayed.
- 3. If your worker performs mostly reads but cannot tolerate any delays, use mode :sticky.
-
- See #{HELP_LINK} for a more detailed explanation of these settings.
- MSG
-
- def_node_search :application_worker?, <<~PATTERN
- `(send nil? :include (const nil? :ApplicationWorker))
- PATTERN
-
- def_node_search :data_consistency_defined?, <<~PATTERN
- `(send nil? :data_consistency ...)
- PATTERN
-
- def on_class(node)
- return unless in_worker?(node) && application_worker?(node)
- return if data_consistency_defined?(node)
-
- add_offense(node, location: :expression)
- end
- end
- end
-end
diff --git a/rubocop/rubocop-migrations.yml b/rubocop/rubocop-migrations.yml
index 979b0fa2936..a98a059df1d 100644
--- a/rubocop/rubocop-migrations.yml
+++ b/rubocop/rubocop-migrations.yml
@@ -14,6 +14,7 @@ Migration/UpdateLargeTable:
- :events
- :gitlab_subscriptions
- :issues
+ - :members
- :merge_request_diff_commits
- :merge_request_diff_files
- :merge_request_diffs
diff --git a/scripts/frontend/check_no_partial_karma_jest.sh b/scripts/frontend/check_no_partial_karma_jest.sh
deleted file mode 100755
index c5fffa5900b..00000000000
--- a/scripts/frontend/check_no_partial_karma_jest.sh
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env bash
-
-karma_directory=spec/javascripts
-
-if [ -d ee ]; then
- karma_directory="$karma_directory ee/$karma_directory"
-fi
-
-karma_files=$(find $karma_directory -type f -name '*_spec.js' -not -path '*/helpers/*')
-violations=""
-
-for karma_file in $karma_files; do
- jest_file=${karma_file/spec\/javascripts/"spec/frontend"}
-
- if [ -f $jest_file ]; then
- violations="$violations $jest_file"
- fi
-done
-
-if [[ -z "$violations" ]]; then
- echo "All good!"
- exit 0
-else
- echo "Danger! The following Jest specs have corresponding files in the Karma spec directory (i.e. spec/javascripts):"
- echo ""
- echo "------------------------------"
- for file in $violations; do
- echo $file
- done
- echo "------------------------------"
- echo ""
- echo "For each of these files, please either:"
- echo ""
- echo "1. Fully migrate the file to Jest and remove the corresponding Karma file."
- echo "2. Remove the Jest file for now, make any relevant changes in the corresponding Karma file, and handle the migration to Jest in a separate MR."
- echo ""
- echo "Why is this a problem?"
- echo ""
- echo "- It's nice to have a single source of truth for the unit tests of a subject."
- echo "- This will cause conflicts if the remaining Karma spec is migrated using our automated tool."
- echo " https://gitlab.com/gitlab-org/frontend/playground/migrate-karma-to-jest"
- echo ""
- exit 1
-fi
diff --git a/scripts/frontend/file_test_coverage.js b/scripts/frontend/file_test_coverage.js
index 04a9035fce2..3ad92a5abbe 100755
--- a/scripts/frontend/file_test_coverage.js
+++ b/scripts/frontend/file_test_coverage.js
@@ -14,7 +14,7 @@ const fs = require('fs');
const path = require('path');
const sourceDirectories = ['app/assets/javascripts'];
-const testDirectories = ['spec/javascripts', 'spec/frontend'];
+const testDirectories = ['spec/frontend'];
if (fs.existsSync('ee')) {
sourceDirectories.forEach((dir) => {
diff --git a/scripts/frontend/startup_css/constants.js b/scripts/frontend/startup_css/constants.js
index 8f183e63659..83f43143e1b 100644
--- a/scripts/frontend/startup_css/constants.js
+++ b/scripts/frontend/startup_css/constants.js
@@ -50,6 +50,7 @@ const createMainOutput = ({ outFile, cssKeys, type }) => ({
htmlPaths: [
path.join(FIXTURES_ROOT, `startup_css/project-${type}.html`),
path.join(FIXTURES_ROOT, `startup_css/project-${type}-signed-out.html`),
+ path.join(FIXTURES_ROOT, `startup_css/project-${type}-search-ff-on.html`),
],
cssKeys,
purgeOptions: {
diff --git a/scripts/prepare_build.sh b/scripts/prepare_build.sh
index e0be80d429f..f3b9ac56082 100644
--- a/scripts/prepare_build.sh
+++ b/scripts/prepare_build.sh
@@ -10,7 +10,12 @@ fi
cp config/gitlab.yml.example config/gitlab.yml
sed -i 's/bin_path: \/usr\/bin\/git/bin_path: \/usr\/local\/bin\/git/' config/gitlab.yml
-cp config/database.yml.postgresql config/database.yml
+if [ "$DECOMPOSED_DB" == "true" ]; then
+ echo "Using decomposed database config (config/database.yml.decomposed-postgresql)"
+ cp config/database.yml.decomposed-postgresql config/database.yml
+else
+ cp config/database.yml.postgresql config/database.yml
+fi
if [ -f config/database_geo.yml.postgresql ]; then
cp config/database_geo.yml.postgresql config/database_geo.yml
diff --git a/scripts/review_apps/automated_cleanup.rb b/scripts/review_apps/automated_cleanup.rb
index 5707f02d3f0..90dc0fd418e 100755
--- a/scripts/review_apps/automated_cleanup.rb
+++ b/scripts/review_apps/automated_cleanup.rb
@@ -95,6 +95,42 @@ class AutomatedCleanup
delete_helm_releases(releases_to_delete)
end
+ def perform_gitlab_docs_environment_cleanup!(days_for_stop:, days_for_delete:)
+ puts "Checking for Docs Review Apps not updated in the last #{days_for_stop} days..."
+
+ checked_environments = []
+ stop_threshold = threshold_time(days: days_for_stop)
+ delete_threshold = threshold_time(days: days_for_delete)
+
+ max_delete_count = 1000
+ delete_count = 0
+
+ gitlab.deployments(project_path, per_page: DEPLOYMENTS_PER_PAGE, sort: 'desc').auto_paginate do |deployment|
+ environment = deployment.environment
+
+ next unless environment
+ next unless environment.name.start_with?('review-docs/')
+ next if checked_environments.include?(environment.slug)
+
+ last_deploy = deployment.created_at
+ deployed_at = Time.parse(last_deploy)
+
+ if deployed_at < stop_threshold
+ environment_state = fetch_environment(environment)&.state
+ stop_environment(environment, deployment) if environment_state && environment_state != 'stopped'
+ end
+
+ if deployed_at < delete_threshold
+ delete_environment(environment, deployment)
+ delete_count += 1
+
+ break if delete_count > max_delete_count
+ end
+
+ checked_environments << environment.slug
+ end
+ end
+
def perform_helm_releases_cleanup!(days:)
puts "Checking for Helm releases that are failed or not updated in the last #{days} days..."
@@ -203,6 +239,10 @@ timed('Review Apps cleanup') do
automated_cleanup.perform_gitlab_environment_cleanup!(days_for_stop: 5, days_for_delete: 6)
end
+timed('Docs Review Apps cleanup') do
+ automated_cleanup.perform_gitlab_docs_environment_cleanup!(days_for_stop: 20, days_for_delete: 30)
+end
+
puts
timed('Helm releases cleanup') do
diff --git a/scripts/review_apps/base-config.yaml b/scripts/review_apps/base-config.yaml
index 3480b7e8bec..7bb9c010016 100644
--- a/scripts/review_apps/base-config.yaml
+++ b/scripts/review_apps/base-config.yaml
@@ -1,7 +1,8 @@
global:
appConfig:
enableUsagePing: false
- imagePullPolicy: Always
+ image:
+ pullPolicy: Always
ingress:
annotations:
external-dns.alpha.kubernetes.io/ttl: 10
diff --git a/scripts/review_apps/review-apps.sh b/scripts/review_apps/review-apps.sh
index 641bf6a5d10..8ec26e7ba89 100755
--- a/scripts/review_apps/review-apps.sh
+++ b/scripts/review_apps/review-apps.sh
@@ -244,10 +244,9 @@ function deploy() {
echoinfo "Deploying ${release} to ${CI_ENVIRONMENT_URL} ..." true
IMAGE_REPOSITORY="registry.gitlab.com/gitlab-org/build/cng-mirror"
- gitlab_migrations_image_repository="${IMAGE_REPOSITORY}/gitlab-rails-ee"
+ gitlab_toolbox_image_repository="${IMAGE_REPOSITORY}/gitlab-toolbox-ee"
gitlab_sidekiq_image_repository="${IMAGE_REPOSITORY}/gitlab-sidekiq-ee"
gitlab_webservice_image_repository="${IMAGE_REPOSITORY}/gitlab-webservice-ee"
- gitlab_task_runner_image_repository="${IMAGE_REPOSITORY}/gitlab-toolbox-ee"
gitlab_gitaly_image_repository="${IMAGE_REPOSITORY}/gitaly"
gitaly_image_tag=$(parse_gitaly_image_tag)
gitlab_shell_image_repository="${IMAGE_REPOSITORY}/gitlab-shell"
@@ -272,7 +271,7 @@ HELM_CMD=$(cat << EOF
--set releaseOverride="${release}" \
--set global.hosts.hostSuffix="${HOST_SUFFIX}" \
--set global.hosts.domain="${REVIEW_APPS_DOMAIN}" \
- --set gitlab.migrations.image.repository="${gitlab_migrations_image_repository}" \
+ --set gitlab.migrations.image.repository="${gitlab_toolbox_image_repository}" \
--set gitlab.migrations.image.tag="${CI_COMMIT_REF_SLUG}" \
--set gitlab.gitaly.image.repository="${gitlab_gitaly_image_repository}" \
--set gitlab.gitaly.image.tag="${gitaly_image_tag}" \
@@ -286,7 +285,7 @@ HELM_CMD=$(cat << EOF
--set gitlab.webservice.image.tag="${CI_COMMIT_REF_SLUG}" \
--set gitlab.webservice.workhorse.image="${gitlab_workhorse_image_repository}" \
--set gitlab.webservice.workhorse.tag="${CI_COMMIT_REF_SLUG}" \
- --set gitlab.task-runner.image.repository="${gitlab_task_runner_image_repository}" \
+ --set gitlab.task-runner.image.repository="${gitlab_toolbox_image_repository}" \
--set gitlab.task-runner.image.tag="${CI_COMMIT_REF_SLUG}"
EOF
)
diff --git a/scripts/rspec_helpers.sh b/scripts/rspec_helpers.sh
index 0714ecfce80..797d9188f81 100644
--- a/scripts/rspec_helpers.sh
+++ b/scripts/rspec_helpers.sh
@@ -1,23 +1,33 @@
#!/usr/bin/env bash
function retrieve_tests_metadata() {
- mkdir -p knapsack/ rspec_flaky/ rspec_profiling/
+ mkdir -p $(dirname "$KNAPSACK_RSPEC_SUITE_REPORT_PATH") $(dirname "$FLAKY_RSPEC_SUITE_REPORT_PATH") rspec_profiling/
- # ${CI_DEFAULT_BRANCH} might not be master in other forks but we want to
- # always target the canonical project here, so the branch must be hardcoded
- local project_path="gitlab-org/gitlab"
- local artifact_branch="master"
- local test_metadata_job_id
+ if [[ -n "${RETRIEVE_TESTS_METADATA_FROM_PAGES}" ]]; then
+ if [[ ! -f "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" ]]; then
+ curl --location -o "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" "https://gitlab-org.gitlab.io/gitlab/${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" || echo "{}" > "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}"
+ fi
- # Ruby
- test_metadata_job_id=$(scripts/api/get_job_id.rb --endpoint "https://gitlab.com/api/v4" --project "${project_path}" -q "status=success" -q "ref=${artifact_branch}" -q "username=gitlab-bot" -Q "scope=success" --job-name "update-tests-metadata")
+ if [[ ! -f "${FLAKY_RSPEC_SUITE_REPORT_PATH}" ]]; then
+ curl --location -o "${FLAKY_RSPEC_SUITE_REPORT_PATH}" "https://gitlab-org.gitlab.io/gitlab/${FLAKY_RSPEC_SUITE_REPORT_PATH}" || echo "{}" > "${FLAKY_RSPEC_SUITE_REPORT_PATH}"
+ fi
+ else
+ # ${CI_DEFAULT_BRANCH} might not be master in other forks but we want to
+ # always target the canonical project here, so the branch must be hardcoded
+ local project_path="gitlab-org/gitlab"
+ local artifact_branch="master"
+ local test_metadata_job_id
- if [[ ! -f "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" ]]; then
- scripts/api/download_job_artifact.rb --endpoint "https://gitlab.com/api/v4" --project "${project_path}" --job-id "${test_metadata_job_id}" --artifact-path "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" || echo "{}" > "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}"
- fi
+ # Ruby
+ test_metadata_job_id=$(scripts/api/get_job_id.rb --endpoint "https://gitlab.com/api/v4" --project "${project_path}" -q "status=success" -q "ref=${artifact_branch}" -q "username=gitlab-bot" -Q "scope=success" --job-name "update-tests-metadata")
- if [[ ! -f "${FLAKY_RSPEC_SUITE_REPORT_PATH}" ]]; then
- scripts/api/download_job_artifact.rb --endpoint "https://gitlab.com/api/v4" --project "${project_path}" --job-id "${test_metadata_job_id}" --artifact-path "${FLAKY_RSPEC_SUITE_REPORT_PATH}" || echo "{}" > "${FLAKY_RSPEC_SUITE_REPORT_PATH}"
+ if [[ ! -f "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" ]]; then
+ scripts/api/download_job_artifact.rb --endpoint "https://gitlab.com/api/v4" --project "${project_path}" --job-id "${test_metadata_job_id}" --artifact-path "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" || echo "{}" > "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}"
+ fi
+
+ if [[ ! -f "${FLAKY_RSPEC_SUITE_REPORT_PATH}" ]]; then
+ scripts/api/download_job_artifact.rb --endpoint "https://gitlab.com/api/v4" --project "${project_path}" --job-id "${test_metadata_job_id}" --artifact-path "${FLAKY_RSPEC_SUITE_REPORT_PATH}" || echo "{}" > "${FLAKY_RSPEC_SUITE_REPORT_PATH}"
+ fi
fi
}
@@ -40,18 +50,24 @@ function update_tests_metadata() {
}
function retrieve_tests_mapping() {
- mkdir -p crystalball/
+ mkdir -p $(dirname "$RSPEC_PACKED_TESTS_MAPPING_PATH")
- # ${CI_DEFAULT_BRANCH} might not be master in other forks but we want to
- # always target the canonical project here, so the branch must be hardcoded
- local project_path="gitlab-org/gitlab"
- local artifact_branch="master"
- local test_metadata_with_mapping_job_id
+ if [[ -n "${RETRIEVE_TESTS_METADATA_FROM_PAGES}" ]]; then
+ if [[ ! -f "${RSPEC_PACKED_TESTS_MAPPING_PATH}" ]]; then
+ (curl --location -o "${RSPEC_PACKED_TESTS_MAPPING_PATH}.gz" "https://gitlab-org.gitlab.io/gitlab/${RSPEC_PACKED_TESTS_MAPPING_PATH}.gz" && gzip -d "${RSPEC_PACKED_TESTS_MAPPING_PATH}.gz") || echo "{}" > "${RSPEC_PACKED_TESTS_MAPPING_PATH}"
+ fi
+ else
+ # ${CI_DEFAULT_BRANCH} might not be master in other forks but we want to
+ # always target the canonical project here, so the branch must be hardcoded
+ local project_path="gitlab-org/gitlab"
+ local artifact_branch="master"
+ local test_metadata_with_mapping_job_id
- test_metadata_with_mapping_job_id=$(scripts/api/get_job_id.rb --endpoint "https://gitlab.com/api/v4" --project "${project_path}" -q "status=success" -q "ref=${artifact_branch}" -q "username=gitlab-bot" -Q "scope=success" --job-name "update-tests-metadata" --artifact-path "${RSPEC_PACKED_TESTS_MAPPING_PATH}.gz")
+ test_metadata_with_mapping_job_id=$(scripts/api/get_job_id.rb --endpoint "https://gitlab.com/api/v4" --project "${project_path}" -q "status=success" -q "ref=${artifact_branch}" -q "username=gitlab-bot" -Q "scope=success" --job-name "update-tests-metadata" --artifact-path "${RSPEC_PACKED_TESTS_MAPPING_PATH}.gz")
- if [[ ! -f "${RSPEC_PACKED_TESTS_MAPPING_PATH}" ]]; then
- (scripts/api/download_job_artifact.rb --endpoint "https://gitlab.com/api/v4" --project "${project_path}" --job-id "${test_metadata_with_mapping_job_id}" --artifact-path "${RSPEC_PACKED_TESTS_MAPPING_PATH}.gz" && gzip -d "${RSPEC_PACKED_TESTS_MAPPING_PATH}.gz") || echo "{}" > "${RSPEC_PACKED_TESTS_MAPPING_PATH}"
+ if [[ ! -f "${RSPEC_PACKED_TESTS_MAPPING_PATH}" ]]; then
+ (scripts/api/download_job_artifact.rb --endpoint "https://gitlab.com/api/v4" --project "${project_path}" --job-id "${test_metadata_with_mapping_job_id}" --artifact-path "${RSPEC_PACKED_TESTS_MAPPING_PATH}.gz" && gzip -d "${RSPEC_PACKED_TESTS_MAPPING_PATH}.gz") || echo "{}" > "${RSPEC_PACKED_TESTS_MAPPING_PATH}"
+ fi
fi
scripts/unpack-test-mapping "${RSPEC_PACKED_TESTS_MAPPING_PATH}" "${RSPEC_TESTS_MAPPING_PATH}"
@@ -184,7 +200,7 @@ function rspec_matched_foss_tests() {
echo "This job is intentionally failed because there are more than ${test_file_count_threshold} FOSS test files matched,"
echo "which would take too long to run in this job."
echo "To reduce the likelihood of breaking FOSS pipelines,"
- echo "please add [RUN AS-IF-FOSS] to the MR title and restart the pipeline."
+ echo "please add ~\"pipeline:run-as-if-foss\" label to the merge request and trigger a new pipeline."
echo "This would run all as-if-foss jobs in this merge request"
echo "and remove this failing job from the pipeline."
exit 1
diff --git a/scripts/setup-test-env b/scripts/setup-test-env
index ebd3a48ae15..a81aaa5cda3 100755
--- a/scripts/setup-test-env
+++ b/scripts/setup-test-env
@@ -2,7 +2,7 @@
# frozen_string_literal: true
-require 'bundler/setup'
+require_relative '../config/bundler_setup'
require 'request_store'
require 'rake'
diff --git a/scripts/static-analysis b/scripts/static-analysis
index a1859254459..de5a1b407f9 100755
--- a/scripts/static-analysis
+++ b/scripts/static-analysis
@@ -14,51 +14,80 @@ class StaticAnalysis
"Browserslist: caniuse-lite is outdated. Please run next command `yarn upgrade`"
].freeze
+ Task = Struct.new(:command, :duration) do
+ def cmd
+ command.join(' ')
+ end
+ end
+ NodeAssignment = Struct.new(:index, :tasks) do
+ def total_duration
+ return 0 if tasks.empty?
+
+ tasks.sum(&:duration)
+ end
+ end
+
+ def self.project_path
+ project_root = File.expand_path('..', __dir__)
+
+ if Gitlab.jh?
+ "#{project_root}/jh"
+ else
+ project_root
+ end
+ end
+
# `gettext:updated_check` and `gitlab:sidekiq:sidekiq_queues_yml:check` will fail on FOSS installations
# (e.g. gitlab-org/gitlab-foss) since they test against a single
# file that is generated by an EE installation, which can
# contain values that a FOSS installation won't find. To work
# around this we will only enable this task on EE installations.
- TASKS_BY_DURATIONS_SECONDS_DESC = {
- %w[bin/rake lint:haml] => 800,
+ TASKS_WITH_DURATIONS_SECONDS = [
+ Task.new(%w[bin/rake lint:haml], 562),
# We need to disable the cache for this cop since it creates files under tmp/feature_flags/*.used,
# the cache would prevent these files from being created.
- %w[bundle exec rubocop --only Gitlab/MarkUsedFeatureFlags --cache false] => 600,
- (Gitlab.ee? ? %w[bin/rake gettext:updated_check] : nil) => 360,
- %w[yarn run lint:eslint:all] => 312,
- %w[yarn run lint:prettier] => 162,
- %w[bin/rake gettext:lint] => 65,
- %w[bundle exec license_finder] => 61,
- %w[bin/rake lint:static_verification] => 45,
- %w[bundle exec rubocop --parallel] => 40,
- %w[bin/rake config_lint] => 26,
- %w[bin/rake gitlab:sidekiq:all_queues_yml:check] => 15,
- (Gitlab.ee? ? %w[bin/rake gitlab:sidekiq:sidekiq_queues_yml:check] : nil) => 11,
- %w[yarn run internal:stylelint] => 8,
- %w[scripts/lint-conflicts.sh] => 1,
- %w[yarn run block-dependencies] => 1,
- %w[scripts/lint-rugged] => 1,
- %w[scripts/gemfile_lock_changed.sh] => 1,
- %w[scripts/frontend/check_no_partial_karma_jest.sh] => 1
- }.reject { |k| k.nil? }.sort_by { |a| -a[1] }.to_h.keys.freeze
-
- def run_tasks!
- tasks = tasks_to_run((ENV['CI_NODE_INDEX'] || 1).to_i, (ENV['CI_NODE_TOTAL'] || 1).to_i)
+ Task.new(%w[bundle exec rubocop --only Gitlab/MarkUsedFeatureFlags --cache false], 400),
+ (Gitlab.ee? ? Task.new(%w[bin/rake gettext:updated_check], 360) : nil),
+ Task.new(%w[yarn run lint:eslint:all], 312),
+ Task.new(%w[bundle exec rubocop --parallel], 60),
+ Task.new(%w[yarn run lint:prettier], 160),
+ Task.new(%w[bin/rake gettext:lint], 85),
+ Task.new(%W[bundle exec license_finder --decisions-file config/dependency_decisions.yml --project-path #{project_path}], 20),
+ Task.new(%w[bin/rake lint:static_verification], 35),
+ Task.new(%w[bin/rake config_lint], 10),
+ Task.new(%w[bin/rake gitlab:sidekiq:all_queues_yml:check], 15),
+ (Gitlab.ee? ? Task.new(%w[bin/rake gitlab:sidekiq:sidekiq_queues_yml:check], 11) : nil),
+ Task.new(%w[yarn run internal:stylelint], 8),
+ Task.new(%w[scripts/lint-conflicts.sh], 1),
+ Task.new(%w[yarn run block-dependencies], 1),
+ Task.new(%w[scripts/lint-rugged], 1),
+ Task.new(%w[scripts/gemfile_lock_changed.sh], 1)
+ ].compact.freeze
+
+ def run_tasks!(options = {})
+ node_assignment = tasks_to_run((ENV['CI_NODE_TOTAL'] || 1).to_i)[(ENV['CI_NODE_INDEX'] || 1).to_i - 1]
+
+ if options[:dry_run]
+ puts "Dry-run mode!"
+ return
+ end
static_analysis = Gitlab::Popen::Runner.new
-
- static_analysis.run(tasks) do |cmd, &run|
+ start_time = Time.now
+ static_analysis.run(node_assignment.tasks.map(&:command)) do |command, &run|
+ task = node_assignment.tasks.find { |task| task.command == command }
puts
- puts "$ #{cmd.join(' ')}"
+ puts "$ #{task.cmd}"
result = run.call
- puts "==> Finished in #{result.duration} seconds"
+ puts "==> Finished in #{result.duration} seconds (expected #{task.duration} seconds)"
puts
end
puts
puts '==================================================='
+ puts "Node finished running all tasks in #{Time.now - start_time} seconds (expected #{node_assignment.total_duration})"
puts
puts
@@ -107,16 +136,66 @@ class StaticAnalysis
.count { |result| !ALLOWED_WARNINGS.include?(result.stderr.strip) }
end
- def tasks_to_run(node_index, node_total)
- tasks = []
- TASKS_BY_DURATIONS_SECONDS_DESC.each_with_index do |task, i|
- tasks << task if i % node_total == (node_index - 1)
+ def tasks_to_run(node_total)
+ total_time = TASKS_WITH_DURATIONS_SECONDS.sum(&:duration).to_f
+ ideal_time_per_node = total_time / node_total
+ tasks_by_duration_desc = TASKS_WITH_DURATIONS_SECONDS.sort_by { |a| -a.duration }
+ nodes = Array.new(node_total) { |i| NodeAssignment.new(i + 1, []) }
+
+ puts "Total expected time: #{total_time}; ideal time per job: #{ideal_time_per_node}.\n\n"
+ puts "Tasks to distribute:"
+ tasks_by_duration_desc.each { |task| puts "* #{task.cmd} (#{task.duration}s)" }
+
+ # Distribute tasks optimally first
+ puts "\nAssigning tasks optimally."
+ distribute_tasks(tasks_by_duration_desc, nodes, ideal_time_per_node: ideal_time_per_node)
+
+ # Distribute remaining tasks, ordered by ascending duration
+ leftover_tasks = tasks_by_duration_desc - nodes.flat_map(&:tasks)
+
+ if leftover_tasks.any?
+ puts "\n\nAssigning remaining tasks: #{leftover_tasks.flat_map(&:cmd)}"
+ distribute_tasks(leftover_tasks, nodes.sort_by { |node| node.total_duration })
end
- tasks
+ nodes.each do |node|
+ puts "\nExpected duration for node #{node.index}: #{node.total_duration} seconds"
+ node.tasks.each { |task| puts "* #{task.cmd} (#{task.duration}s)" }
+ end
+
+ nodes
+ end
+
+ def distribute_tasks(tasks, nodes, ideal_time_per_node: nil)
+ condition =
+ if ideal_time_per_node
+ ->(task, node, ideal_time_per_node) { (task.duration + node.total_duration) <= ideal_time_per_node }
+ else
+ ->(*) { true }
+ end
+
+ tasks.each do |task|
+ nodes.each do |node|
+ if condition.call(task, node, ideal_time_per_node)
+ assign_task_to_node(tasks, node, task)
+ break
+ end
+ end
+ end
+ end
+
+ def assign_task_to_node(remaining_tasks, node, task)
+ node.tasks << task
+ puts "Assigning #{task.command} (#{task.duration}s) to node ##{node.index}. Node total duration: #{node.total_duration}s."
end
end
if $0 == __FILE__
- StaticAnalysis.new.run_tasks!
+ options = {}
+
+ if ARGV.include?('--dry-run')
+ options[:dry_run] = true
+ end
+
+ StaticAnalysis.new.run_tasks!(options)
end
diff --git a/scripts/used-feature-flags b/scripts/used-feature-flags
index 07c022a4c1a..e6a8149da71 100755
--- a/scripts/used-feature-flags
+++ b/scripts/used-feature-flags
@@ -2,6 +2,7 @@
# frozen_string_literal: true
require 'set'
+require 'fileutils'
class String
def red
diff --git a/scripts/utils.sh b/scripts/utils.sh
index 700dad58779..d2e8c151438 100644
--- a/scripts/utils.sh
+++ b/scripts/utils.sh
@@ -37,8 +37,9 @@ function bundle_install_script() {
fi;
bundle --version
- bundle config set path 'vendor'
+ bundle config set path "$(pwd)/vendor"
bundle config set clean 'true'
+ test -d jh && bundle config set gemfile 'jh/Gemfile'
echo "${BUNDLE_WITHOUT}"
bundle config
diff --git a/spec/bin/sidekiq_cluster_spec.rb b/spec/bin/sidekiq_cluster_spec.rb
index 1bba048a27c..eb014c511e3 100644
--- a/spec/bin/sidekiq_cluster_spec.rb
+++ b/spec/bin/sidekiq_cluster_spec.rb
@@ -1,11 +1,14 @@
# frozen_string_literal: true
-require 'spec_helper'
+require 'fast_spec_helper'
require 'shellwords'
+require 'rspec-parameterized'
-RSpec.describe 'bin/sidekiq-cluster' do
+RSpec.describe 'bin/sidekiq-cluster', :aggregate_failures do
using RSpec::Parameterized::TableSyntax
+ let(:root) { File.expand_path('../..', __dir__) }
+
context 'when selecting some queues and excluding others' do
where(:args, :included, :excluded) do
%w[--negate cronjob] | '-qdefault,1' | '-qcronjob,1'
@@ -13,10 +16,10 @@ RSpec.describe 'bin/sidekiq-cluster' do
end
with_them do
- it 'runs successfully', :aggregate_failures do
+ it 'runs successfully' do
cmd = %w[bin/sidekiq-cluster --dryrun] + args
- output, status = Gitlab::Popen.popen(cmd, Rails.root.to_s)
+ output, status = Gitlab::Popen.popen(cmd, root)
expect(status).to be(0)
expect(output).to include('bundle exec sidekiq')
@@ -31,10 +34,10 @@ RSpec.describe 'bin/sidekiq-cluster' do
%w[*],
%w[--queue-selector *]
].each do |args|
- it "runs successfully with `#{args}`", :aggregate_failures do
+ it "runs successfully with `#{args}`" do
cmd = %w[bin/sidekiq-cluster --dryrun] + args
- output, status = Gitlab::Popen.popen(cmd, Rails.root.to_s)
+ output, status = Gitlab::Popen.popen(cmd, root)
expect(status).to be(0)
expect(output).to include('bundle exec sidekiq')
@@ -43,4 +46,20 @@ RSpec.describe 'bin/sidekiq-cluster' do
end
end
end
+
+ context 'when arguments contain newlines' do
+ it 'raises an error' do
+ [
+ ["default\n"],
+ ["defaul\nt"]
+ ].each do |args|
+ cmd = %w[bin/sidekiq-cluster --dryrun] + args
+
+ output, status = Gitlab::Popen.popen(cmd, root)
+
+ expect(status).to be(1)
+ expect(output).to include('cannot contain newlines')
+ end
+ end
+ end
end
diff --git a/spec/config/grape_entity_patch_spec.rb b/spec/config/grape_entity_patch_spec.rb
new file mode 100644
index 00000000000..7334f270ca1
--- /dev/null
+++ b/spec/config/grape_entity_patch_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Grape::Entity patch' do
+ let(:entity_class) { Class.new(Grape::Entity) }
+
+ describe 'NameError in block exposure with argument' do
+ subject(:represent) { entity_class.represent({}, serializable: true) }
+
+ before do
+ entity_class.expose :raise_no_method_error do |_|
+ foo
+ end
+ end
+
+ it 'propagates the error to the caller' do
+ expect { represent }.to raise_error(NameError)
+ end
+ end
+end
diff --git a/spec/controllers/admin/integrations_controller_spec.rb b/spec/controllers/admin/integrations_controller_spec.rb
index 64ae2a95b4e..1793b3a86d1 100644
--- a/spec/controllers/admin/integrations_controller_spec.rb
+++ b/spec/controllers/admin/integrations_controller_spec.rb
@@ -9,6 +9,14 @@ RSpec.describe Admin::IntegrationsController do
sign_in(admin)
end
+ it_behaves_like IntegrationsActions do
+ let(:integration_attributes) { { instance: true, project: nil } }
+
+ let(:routing_params) do
+ { id: integration.to_param }
+ end
+ end
+
describe '#edit' do
Integration.available_integration_names.each do |integration_name|
context "#{integration_name}" do
diff --git a/spec/controllers/admin/runners_controller_spec.rb b/spec/controllers/admin/runners_controller_spec.rb
index 8e57b4f03a7..996964fdcf0 100644
--- a/spec/controllers/admin/runners_controller_spec.rb
+++ b/spec/controllers/admin/runners_controller_spec.rb
@@ -23,10 +23,6 @@ RSpec.describe Admin::RunnersController do
describe '#show' do
render_views
- before do
- stub_feature_flags(runner_detailed_view_vue_ui: false)
- end
-
let_it_be(:project) { create(:project) }
let_it_be(:project_two) { create(:project) }
@@ -61,30 +57,6 @@ RSpec.describe Admin::RunnersController do
expect(response).to have_gitlab_http_status(:ok)
end
-
- describe 'Cost factors values' do
- context 'when it is Gitlab.com' do
- before do
- expect(Gitlab).to receive(:com?).at_least(:once) { true }
- end
-
- it 'renders cost factors fields' do
- get :show, params: { id: runner.id }
-
- expect(response.body).to match /Private projects Minutes cost factor/
- expect(response.body).to match /Public projects Minutes cost factor/
- end
- end
-
- context 'when it is not Gitlab.com' do
- it 'does not show cost factor fields' do
- get :show, params: { id: runner.id }
-
- expect(response.body).not_to match /Private projects Minutes cost factor/
- expect(response.body).not_to match /Public projects Minutes cost factor/
- end
- end
- end
end
describe '#update' do
diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb
index 6e172f53257..015c36c9335 100644
--- a/spec/controllers/admin/users_controller_spec.rb
+++ b/spec/controllers/admin/users_controller_spec.rb
@@ -146,7 +146,7 @@ RSpec.describe Admin::UsersController do
it 'sends the user a rejection email' do
expect_next_instance_of(NotificationService) do |notification|
- allow(notification).to receive(:user_admin_rejection).with(user.name, user.notification_email)
+ allow(notification).to receive(:user_admin_rejection).with(user.name, user.notification_email_or_default)
end
subject
@@ -165,7 +165,7 @@ RSpec.describe Admin::UsersController do
it 'displays the error' do
subject
- expect(flash[:alert]).to eq('This user does not have a pending request')
+ expect(flash[:alert]).to eq('User does not have a pending request')
end
it 'does not email the user' do
diff --git a/spec/controllers/boards/issues_controller_spec.rb b/spec/controllers/boards/issues_controller_spec.rb
index 48000284264..cc60ab16d2e 100644
--- a/spec/controllers/boards/issues_controller_spec.rb
+++ b/spec/controllers/boards/issues_controller_spec.rb
@@ -428,17 +428,21 @@ RSpec.describe Boards::IssuesController do
describe 'POST create' do
context 'with valid params' do
- it 'returns a successful 200 response' do
+ before do
create_issue user: user, board: board, list: list1, title: 'New issue'
+ end
+ it 'returns a successful 200 response' do
expect(response).to have_gitlab_http_status(:ok)
end
it 'returns the created issue' do
- create_issue user: user, board: board, list: list1, title: 'New issue'
-
expect(response).to match_response_schema('entities/issue_board')
end
+
+ it 'sets the default work_item_type' do
+ expect(Issue.last.work_item_type.base_type).to eq('issue')
+ end
end
context 'with invalid params' do
diff --git a/spec/controllers/explore/projects_controller_spec.rb b/spec/controllers/explore/projects_controller_spec.rb
index a2b62aa49d2..2297198878d 100644
--- a/spec/controllers/explore/projects_controller_spec.rb
+++ b/spec/controllers/explore/projects_controller_spec.rb
@@ -200,6 +200,24 @@ RSpec.describe Explore::ProjectsController do
let(:sorting_param) { 'created_asc' }
end
end
+
+ describe 'GET #index' do
+ let(:controller_action) { :index }
+ let(:params_with_name) { { name: 'some project' } }
+
+ context 'when disable_anonymous_project_search is enabled' do
+ before do
+ stub_feature_flags(disable_anonymous_project_search: true)
+ end
+
+ it 'does not show a flash message' do
+ sign_in(create(:user))
+ get controller_action, params: params_with_name
+
+ expect(flash.now[:notice]).to be_nil
+ end
+ end
+ end
end
context 'when user is not signed in' do
@@ -229,5 +247,50 @@ RSpec.describe Explore::ProjectsController do
expect(response).to redirect_to new_user_session_path
end
end
+
+ describe 'GET #index' do
+ let(:controller_action) { :index }
+ let(:params_with_name) { { name: 'some project' } }
+
+ context 'when disable_anonymous_project_search is enabled' do
+ before do
+ stub_feature_flags(disable_anonymous_project_search: true)
+ end
+
+ it 'shows a flash message' do
+ get controller_action, params: params_with_name
+
+ expect(flash.now[:notice]).to eq('You must sign in to search for specific projects.')
+ end
+
+ context 'when search param is not given' do
+ it 'does not show a flash message' do
+ get controller_action
+
+ expect(flash.now[:notice]).to be_nil
+ end
+ end
+
+ context 'when format is not HTML' do
+ it 'does not show a flash message' do
+ get controller_action, params: params_with_name.merge(format: :atom)
+
+ expect(flash.now[:notice]).to be_nil
+ end
+ end
+ end
+
+ context 'when disable_anonymous_project_search is disabled' do
+ before do
+ stub_feature_flags(disable_anonymous_project_search: false)
+ end
+
+ it 'does not show a flash message' do
+ get controller_action, params: params_with_name
+
+ expect(flash.now[:notice]).to be_nil
+ end
+ end
+ end
end
end
diff --git a/spec/controllers/groups/children_controller_spec.rb b/spec/controllers/groups/children_controller_spec.rb
index e97fe50c468..04cf7785f1e 100644
--- a/spec/controllers/groups/children_controller_spec.rb
+++ b/spec/controllers/groups/children_controller_spec.rb
@@ -227,8 +227,8 @@ RSpec.describe Groups::ChildrenController do
context 'when rendering hierarchies' do
# When loading hierarchies we load the all the ancestors for matched projects
- # in 1 separate query
- let(:extra_queries_for_hierarchies) { 1 }
+ # in 2 separate queries
+ let(:extra_queries_for_hierarchies) { 2 }
def get_filtered_list
get :index, params: { group_id: group.to_param, filter: 'filter' }, format: :json
diff --git a/spec/controllers/groups/runners_controller_spec.rb b/spec/controllers/groups/runners_controller_spec.rb
index 1808969cd60..a8830efe653 100644
--- a/spec/controllers/groups/runners_controller_spec.rb
+++ b/spec/controllers/groups/runners_controller_spec.rb
@@ -3,11 +3,13 @@
require 'spec_helper'
RSpec.describe Groups::RunnersController do
- let(:user) { create(:user) }
- let(:group) { create(:group) }
- let(:runner) { create(:ci_runner, :group, groups: [group]) }
- let(:project) { create(:project, group: group) }
- let(:runner_project) { create(:ci_runner, :project, projects: [project]) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, group: group) }
+
+ let!(:runner) { create(:ci_runner, :group, groups: [group]) }
+ let!(:runner_project) { create(:ci_runner, :project, projects: [project]) }
+
let(:params_runner_project) { { group_id: group, id: runner_project } }
let(:params) { { group_id: group, id: runner } }
@@ -26,6 +28,7 @@ RSpec.describe Groups::RunnersController do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:index)
+ expect(assigns(:group_runners_limited_count)).to be(2)
end
end
diff --git a/spec/controllers/groups/settings/integrations_controller_spec.rb b/spec/controllers/groups/settings/integrations_controller_spec.rb
index 931e726850a..31d1946652d 100644
--- a/spec/controllers/groups/settings/integrations_controller_spec.rb
+++ b/spec/controllers/groups/settings/integrations_controller_spec.rb
@@ -10,6 +10,21 @@ RSpec.describe Groups::Settings::IntegrationsController do
sign_in(user)
end
+ it_behaves_like IntegrationsActions do
+ let(:integration_attributes) { { group: group, project: nil } }
+
+ let(:routing_params) do
+ {
+ group_id: group,
+ id: integration.to_param
+ }
+ end
+
+ before do
+ group.add_owner(user)
+ end
+ end
+
describe '#index' do
context 'when user is not owner' do
it 'renders not_found' do
diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb
index 91b11cd46c5..a7625e65603 100644
--- a/spec/controllers/groups_controller_spec.rb
+++ b/spec/controllers/groups_controller_spec.rb
@@ -370,6 +370,57 @@ RSpec.describe GroupsController, factory_default: :keep do
end
end
end
+
+ context 'when creating a group with the `role` attribute present' do
+ it 'changes the users role' do
+ sign_in(user)
+
+ expect do
+ post :create, params: { group: { name: 'new_group', path: 'new_group' }, user: { role: 'devops_engineer' } }
+ end.to change { user.reload.role }.to('devops_engineer')
+ end
+ end
+
+ context 'when creating a group with the `setup_for_company` attribute present' do
+ before do
+ sign_in(user)
+ end
+
+ subject do
+ post :create, params: { group: { name: 'new_group', path: 'new_group', setup_for_company: 'false' } }
+ end
+
+ it 'sets the groups `setup_for_company` value' do
+ subject
+ expect(Group.last.setup_for_company).to be(false)
+ end
+
+ context 'when the user already has a value for `setup_for_company`' do
+ before do
+ user.update_attribute(:setup_for_company, true)
+ end
+
+ it 'does not change the users `setup_for_company` value' do
+ expect(Users::UpdateService).not_to receive(:new)
+ expect { subject }.not_to change { user.reload.setup_for_company }.from(true)
+ end
+ end
+
+ context 'when the user has no value for `setup_for_company`' do
+ it 'changes the users `setup_for_company` value' do
+ expect(Users::UpdateService).to receive(:new).and_call_original
+ expect { subject }.to change { user.reload.setup_for_company }.to(false)
+ end
+ end
+ end
+
+ context 'when creating a group with the `jobs_to_be_done` attribute present' do
+ it 'sets the groups `jobs_to_be_done` value' do
+ sign_in(user)
+ post :create, params: { group: { name: 'new_group', path: 'new_group', jobs_to_be_done: 'other' } }
+ expect(Group.last.jobs_to_be_done).to eq('other')
+ end
+ end
end
describe 'GET #index' do
diff --git a/spec/controllers/import/manifest_controller_spec.rb b/spec/controllers/import/manifest_controller_spec.rb
index d5a498e80d9..0111ad9501f 100644
--- a/spec/controllers/import/manifest_controller_spec.rb
+++ b/spec/controllers/import/manifest_controller_spec.rb
@@ -75,16 +75,6 @@ RSpec.describe Import::ManifestController, :clean_gitlab_redis_shared_state do
expect(json_response.dig("provider_repos", 0, "id")).to eq(repo1[:id])
expect(json_response.dig("provider_repos", 1, "id")).to eq(repo2[:id])
end
-
- it "does not show already added project" do
- project = create(:project, import_type: 'manifest', namespace: user.namespace, import_status: :finished, import_url: repo1[:url])
-
- get :status, format: :json
-
- expect(json_response.dig("imported_projects", 0, "id")).to eq(project.id)
- expect(json_response.dig("provider_repos").length).to eq(1)
- expect(json_response.dig("provider_repos", 0, "id")).not_to eq(repo1[:id])
- end
end
context 'when the data is stored via Gitlab::ManifestImport::Metadata' do
diff --git a/spec/controllers/invites_controller_spec.rb b/spec/controllers/invites_controller_spec.rb
index dc1fb0454df..d4091461062 100644
--- a/spec/controllers/invites_controller_spec.rb
+++ b/spec/controllers/invites_controller_spec.rb
@@ -120,6 +120,29 @@ RSpec.describe InvitesController do
end
end
+ context 'when it is part of the invite_email_from experiment' do
+ let(:extra_params) { { invite_type: 'initial_email', experiment_name: 'invite_email_from' } }
+
+ it 'tracks the initial join click from email' do
+ experiment = double(track: true)
+ allow(controller).to receive(:experiment).with(:invite_email_from, actor: member).and_return(experiment)
+
+ request
+
+ expect(experiment).to have_received(:track).with(:join_clicked)
+ end
+
+ context 'when member does not exist' do
+ let(:raw_invite_token) { '_bogus_token_' }
+
+ it 'does not track the experiment' do
+ expect(controller).not_to receive(:experiment).with(:invite_email_from, actor: member)
+
+ request
+ end
+ end
+ end
+
context 'when member does not exist' do
let(:raw_invite_token) { '_bogus_token_' }
@@ -147,8 +170,9 @@ RSpec.describe InvitesController do
end
context 'when it is not part of our invite email experiment' do
- it 'does not track via experiment' do
+ it 'does not track via experiment', :aggregate_failures do
expect(controller).not_to receive(:experiment).with(:invite_email_preview_text, actor: member)
+ expect(controller).not_to receive(:experiment).with(:invite_email_from, actor: member)
request
end
diff --git a/spec/controllers/omniauth_callbacks_controller_spec.rb b/spec/controllers/omniauth_callbacks_controller_spec.rb
index 9a142559fca..8c8de2f79a3 100644
--- a/spec/controllers/omniauth_callbacks_controller_spec.rb
+++ b/spec/controllers/omniauth_callbacks_controller_spec.rb
@@ -317,7 +317,7 @@ RSpec.describe OmniauthCallbacksController, type: :controller do
it 'denies sign-in if sign-up is enabled, but block_auto_created_users is set' do
post :atlassian_oauth2
- expect(flash[:alert]).to start_with 'Your account has been blocked.'
+ expect(flash[:alert]).to start_with 'Your account is pending approval'
end
it 'accepts sign-in if sign-up is enabled' do
@@ -399,7 +399,7 @@ RSpec.describe OmniauthCallbacksController, type: :controller do
it 'denies login if sign up is enabled, but block_auto_created_users is set' do
post :saml, params: { SAMLResponse: mock_saml_response }
- expect(flash[:alert]).to start_with 'Your account has been blocked.'
+ expect(flash[:alert]).to start_with 'Your account is pending approval'
end
it 'accepts login if sign up is enabled' do
diff --git a/spec/controllers/profiles/two_factor_auths_controller_spec.rb b/spec/controllers/profiles/two_factor_auths_controller_spec.rb
index 818bf2a4ae6..073180cbafd 100644
--- a/spec/controllers/profiles/two_factor_auths_controller_spec.rb
+++ b/spec/controllers/profiles/two_factor_auths_controller_spec.rb
@@ -10,8 +10,33 @@ RSpec.describe Profiles::TwoFactorAuthsController do
allow(subject).to receive(:current_user).and_return(user)
end
+ shared_examples 'user must first verify their primary email address' do
+ before do
+ allow(user).to receive(:primary_email_verified?).and_return(false)
+ end
+
+ it 'redirects to profile_emails_path' do
+ go
+
+ expect(response).to redirect_to(profile_emails_path)
+ end
+
+ it 'displays a notice' do
+ go
+
+ expect(flash[:notice])
+ .to eq _('You need to verify your primary email first before enabling Two-Factor Authentication.')
+ end
+
+ it 'does not redirect when the `ensure_verified_primary_email_for_2fa` feature flag is disabled' do
+ stub_feature_flags(ensure_verified_primary_email_for_2fa: false)
+
+ expect(response).not_to redirect_to(profile_emails_path)
+ end
+ end
+
describe 'GET show' do
- let(:user) { create(:user) }
+ let_it_be_with_reload(:user) { create(:user) }
it 'generates otp_secret for user' do
expect(User).to receive(:generate_otp_secret).with(32).and_call_original.once
@@ -34,11 +59,16 @@ RSpec.describe Profiles::TwoFactorAuthsController do
get :show
end
end
+
+ it_behaves_like 'user must first verify their primary email address' do
+ let(:go) { get :show }
+ end
end
describe 'POST create' do
- let(:user) { create(:user) }
- let(:pin) { 'pin-code' }
+ let_it_be_with_reload(:user) { create(:user) }
+
+ let(:pin) { 'pin-code' }
def go
post :create, params: { pin_code: pin }
@@ -70,8 +100,8 @@ RSpec.describe Profiles::TwoFactorAuthsController do
go
end
- it 'dismisses the `ACCOUNT_RECOVERY_REGULAR_CHECK` callout' do
- expect(controller.helpers).to receive(:dismiss_account_recovery_regular_check)
+ it 'dismisses the `TWO_FACTOR_AUTH_RECOVERY_SETTINGS_CHECK` callout' do
+ expect(controller.helpers).to receive(:dismiss_two_factor_auth_recovery_settings_check)
go
end
@@ -105,10 +135,12 @@ RSpec.describe Profiles::TwoFactorAuthsController do
expect(response).to render_template(:show)
end
end
+
+ it_behaves_like 'user must first verify their primary email address'
end
describe 'POST codes' do
- let(:user) { create(:user, :two_factor) }
+ let_it_be_with_reload(:user) { create(:user, :two_factor) }
it 'presents plaintext codes for the user to save' do
expect(user).to receive(:generate_otp_backup_codes!).and_return(%w(a b c))
@@ -124,8 +156,8 @@ RSpec.describe Profiles::TwoFactorAuthsController do
expect(user.otp_backup_codes).not_to be_empty
end
- it 'dismisses the `ACCOUNT_RECOVERY_REGULAR_CHECK` callout' do
- expect(controller.helpers).to receive(:dismiss_account_recovery_regular_check)
+ it 'dismisses the `TWO_FACTOR_AUTH_RECOVERY_SETTINGS_CHECK` callout' do
+ expect(controller.helpers).to receive(:dismiss_two_factor_auth_recovery_settings_check)
post :codes
end
@@ -135,7 +167,7 @@ RSpec.describe Profiles::TwoFactorAuthsController do
subject { delete :destroy }
context 'for a user that has 2FA enabled' do
- let(:user) { create(:user, :two_factor) }
+ let_it_be_with_reload(:user) { create(:user, :two_factor) }
it 'disables two factor' do
subject
@@ -158,7 +190,7 @@ RSpec.describe Profiles::TwoFactorAuthsController do
end
context 'for a user that does not have 2FA enabled' do
- let(:user) { create(:user) }
+ let_it_be_with_reload(:user) { create(:user) }
it 'redirects to profile_account_path' do
subject
diff --git a/spec/controllers/projects/analytics/cycle_analytics/summary_controller_spec.rb b/spec/controllers/projects/analytics/cycle_analytics/summary_controller_spec.rb
index 1832b84ab6e..a366b2583d4 100644
--- a/spec/controllers/projects/analytics/cycle_analytics/summary_controller_spec.rb
+++ b/spec/controllers/projects/analytics/cycle_analytics/summary_controller_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Projects::Analytics::CycleAnalytics::SummaryController do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
- let(:params) { { namespace_id: project.namespace.to_param, project_id: project.to_param, created_after: '2010-01-01', created_before: '2010-01-02' } }
+ let(:params) { { namespace_id: project.namespace.to_param, project_id: project.to_param, created_after: '2010-01-01', created_before: '2010-02-01' } }
before do
sign_in(user)
@@ -42,5 +42,39 @@ RSpec.describe Projects::Analytics::CycleAnalytics::SummaryController do
expect(response).to have_gitlab_http_status(:not_found)
end
end
+
+ context 'when filters are applied' do
+ let_it_be(:author) { create(:user) }
+ let_it_be(:milestone) { create(:milestone, title: 'milestone 1', project: project) }
+ let_it_be(:issue_with_author) { create(:issue, project: project, author: author, created_at: Date.new(2010, 1, 15)) }
+ let_it_be(:issue_with_other_author) { create(:issue, project: project, author: user, created_at: Date.new(2010, 1, 15)) }
+ let_it_be(:issue_with_milestone) { create(:issue, project: project, milestone: milestone, created_at: Date.new(2010, 1, 15)) }
+
+ before do
+ project.add_reporter(user)
+ end
+
+ it 'filters by author username' do
+ params[:author_username] = author.username
+
+ subject
+
+ expect(response).to be_successful
+
+ issue_count = json_response.first
+ expect(issue_count['value']).to eq('1')
+ end
+
+ it 'filters by milestone title' do
+ params[:milestone_title] = milestone.title
+
+ subject
+
+ expect(response).to be_successful
+
+ issue_count = json_response.first
+ expect(issue_count['value']).to eq('1')
+ end
+ end
end
end
diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb
index 7103d7df5c5..0fcdeb2edde 100644
--- a/spec/controllers/projects/environments_controller_spec.rb
+++ b/spec/controllers/projects/environments_controller_spec.rb
@@ -222,6 +222,16 @@ RSpec.describe Projects::EnvironmentsController do
expect(response).to have_gitlab_http_status(:bad_request)
end
end
+
+ context 'when name is passed' do
+ let(:params) { environment_params.merge(environment: { name: "new name" }) }
+
+ it 'ignores name' do
+ expect do
+ subject
+ end.not_to change { environment.reload.name }
+ end
+ end
end
describe 'PATCH #stop' do
diff --git a/spec/controllers/projects/feature_flags_controller_spec.rb b/spec/controllers/projects/feature_flags_controller_spec.rb
index e038b247eff..fd95aa44568 100644
--- a/spec/controllers/projects/feature_flags_controller_spec.rb
+++ b/spec/controllers/projects/feature_flags_controller_spec.rb
@@ -94,20 +94,6 @@ RSpec.describe Projects::FeatureFlagsController do
is_expected.to match_response_schema('feature_flags')
end
- it 'returns false for active when the feature flag is inactive even if it has an active scope' do
- create(:operations_feature_flag_scope,
- feature_flag: feature_flag_inactive,
- environment_scope: 'production',
- active: true)
-
- subject
-
- expect(response).to have_gitlab_http_status(:ok)
- feature_flag_json = json_response['feature_flags'].second
-
- expect(feature_flag_json['active']).to eq(false)
- end
-
it 'returns the feature flag iid' do
subject
@@ -181,7 +167,7 @@ RSpec.describe Projects::FeatureFlagsController do
subject { get(:show, params: params, format: :json) }
let!(:feature_flag) do
- create(:operations_feature_flag, :legacy_flag, project: project)
+ create(:operations_feature_flag, project: project)
end
let(:params) do
@@ -197,7 +183,7 @@ RSpec.describe Projects::FeatureFlagsController do
expect(json_response['name']).to eq(feature_flag.name)
expect(json_response['active']).to eq(feature_flag.active)
- expect(json_response['version']).to eq('legacy_flag')
+ expect(json_response['version']).to eq('new_version_flag')
end
it 'matches json schema' do
@@ -245,46 +231,6 @@ RSpec.describe Projects::FeatureFlagsController do
end
end
- context 'when feature flags have additional scopes' do
- context 'when there is at least one active scope' do
- let!(:feature_flag) do
- create(:operations_feature_flag, project: project, active: false)
- end
-
- let!(:feature_flag_scope_production) do
- create(:operations_feature_flag_scope,
- feature_flag: feature_flag,
- environment_scope: 'review/*',
- active: true)
- end
-
- it 'returns false for active' do
- subject
-
- expect(json_response['active']).to eq(false)
- end
- end
-
- context 'when all scopes are inactive' do
- let!(:feature_flag) do
- create(:operations_feature_flag, project: project, active: false)
- end
-
- let!(:feature_flag_scope_production) do
- create(:operations_feature_flag_scope,
- feature_flag: feature_flag,
- environment_scope: 'production',
- active: false)
- end
-
- it 'recognizes the feature flag as inactive' do
- subject
-
- expect(json_response['active']).to be_falsy
- end
- end
- end
-
context 'with a version 2 feature flag' do
let!(:new_version_feature_flag) do
create(:operations_feature_flag, :new_version_flag, project: project)
@@ -320,22 +266,6 @@ RSpec.describe Projects::FeatureFlagsController do
describe 'GET edit' do
subject { get(:edit, params: params) }
- context 'with legacy flags' do
- let!(:feature_flag) { create(:operations_feature_flag, :legacy_flag, project: project) }
-
- let(:params) do
- {
- namespace_id: project.namespace,
- project_id: project,
- iid: feature_flag.iid
- }
- end
-
- it 'returns not found' do
- is_expected.to have_gitlab_http_status(:not_found)
- end
- end
-
context 'with new version flags' do
let!(:feature_flag) { create(:operations_feature_flag, project: project) }
@@ -378,14 +308,6 @@ RSpec.describe Projects::FeatureFlagsController do
expect(json_response['active']).to be_truthy
end
- it 'creates a default scope' do
- subject
-
- expect(json_response['scopes'].count).to eq(1)
- expect(json_response['scopes'].first['environment_scope']).to eq('*')
- expect(json_response['scopes'].first['active']).to be_truthy
- end
-
it 'matches json schema' do
is_expected.to match_response_schema('feature_flag')
end
@@ -435,119 +357,6 @@ RSpec.describe Projects::FeatureFlagsController do
end
end
- context 'when creates additional scope' do
- let(:params) do
- view_params.merge({
- operations_feature_flag: {
- name: 'my_feature_flag',
- active: true,
- scopes_attributes: [{ environment_scope: '*', active: true },
- { environment_scope: 'production', active: false }]
- }
- })
- end
-
- it 'creates feature flag scopes successfully' do
- expect { subject }.to change { Operations::FeatureFlagScope.count }.by(2)
-
- expect(response).to have_gitlab_http_status(:ok)
- end
-
- it 'creates feature flag scopes in a correct order' do
- subject
-
- expect(json_response['scopes'].first['environment_scope']).to eq('*')
- expect(json_response['scopes'].second['environment_scope']).to eq('production')
- end
-
- context 'when default scope is not placed first' do
- let(:params) do
- view_params.merge({
- operations_feature_flag: {
- name: 'my_feature_flag',
- active: true,
- scopes_attributes: [{ environment_scope: 'production', active: false },
- { environment_scope: '*', active: true }]
- }
- })
- end
-
- it 'returns 400' do
- subject
-
- expect(response).to have_gitlab_http_status(:bad_request)
- expect(json_response['message'])
- .to include('Default scope has to be the first element')
- end
- end
- end
-
- context 'when creates additional scope with a percentage rollout' do
- it 'creates a strategy for the scope' do
- params = view_params.merge({
- operations_feature_flag: {
- name: 'my_feature_flag',
- active: true,
- scopes_attributes: [{ environment_scope: '*', active: true },
- { environment_scope: 'production', active: false,
- strategies: [{ name: 'gradualRolloutUserId',
- parameters: { groupId: 'default', percentage: '42' } }] }]
- }
- })
-
- post(:create, params: params, format: :json)
-
- expect(response).to have_gitlab_http_status(:ok)
- production_strategies_json = json_response['scopes'].second['strategies']
- expect(production_strategies_json).to eq([{
- 'name' => 'gradualRolloutUserId',
- 'parameters' => { "groupId" => "default", "percentage" => "42" }
- }])
- end
- end
-
- context 'when creates additional scope with a userWithId strategy' do
- it 'creates a strategy for the scope' do
- params = view_params.merge({
- operations_feature_flag: {
- name: 'my_feature_flag',
- active: true,
- scopes_attributes: [{ environment_scope: '*', active: true },
- { environment_scope: 'production', active: false,
- strategies: [{ name: 'userWithId',
- parameters: { userIds: '123,4,6722' } }] }]
- }
- })
-
- post(:create, params: params, format: :json)
-
- expect(response).to have_gitlab_http_status(:ok)
- production_strategies_json = json_response['scopes'].second['strategies']
- expect(production_strategies_json).to eq([{
- 'name' => 'userWithId',
- 'parameters' => { "userIds" => "123,4,6722" }
- }])
- end
- end
-
- context 'when creates an additional scope without a strategy' do
- it 'creates a default strategy' do
- params = view_params.merge({
- operations_feature_flag: {
- name: 'my_feature_flag',
- active: true,
- scopes_attributes: [{ environment_scope: '*', active: true }]
- }
- })
-
- post(:create, params: params, format: :json)
-
- expect(response).to have_gitlab_http_status(:ok)
- default_strategies_json = json_response['scopes'].first['strategies']
- expect(default_strategies_json).to eq([{ "name" => "default", "parameters" => {} }])
- end
- end
-
context 'when creating a version 2 feature flag' do
let(:params) do
{
@@ -744,7 +553,7 @@ RSpec.describe Projects::FeatureFlagsController do
describe 'DELETE destroy.json' do
subject { delete(:destroy, params: params, format: :json) }
- let!(:feature_flag) { create(:operations_feature_flag, :legacy_flag, project: project) }
+ let!(:feature_flag) { create(:operations_feature_flag, project: project) }
let(:params) do
{
@@ -762,10 +571,6 @@ RSpec.describe Projects::FeatureFlagsController do
expect { subject }.to change { Operations::FeatureFlag.count }.by(-1)
end
- it 'destroys the default scope' do
- expect { subject }.to change { Operations::FeatureFlagScope.count }.by(-1)
- end
-
it 'matches json schema' do
is_expected.to match_response_schema('feature_flag')
end
@@ -792,14 +597,6 @@ RSpec.describe Projects::FeatureFlagsController do
end
end
- context 'when there is an additional scope' do
- let!(:scope) { create_scope(feature_flag, 'production', false) }
-
- it 'destroys the default scope and production scope' do
- expect { subject }.to change { Operations::FeatureFlagScope.count }.by(-2)
- end
- end
-
context 'with a version 2 flag' do
let!(:new_version_flag) { create(:operations_feature_flag, :new_version_flag, project: project) }
let(:params) do
@@ -828,70 +625,9 @@ RSpec.describe Projects::FeatureFlagsController do
put(:update, params: params, format: :json, as: :json)
end
- context 'with a legacy feature flag' do
- subject { put(:update, params: params, format: :json) }
-
- let!(:feature_flag) do
- create(:operations_feature_flag,
- :legacy_flag,
- name: 'ci_live_trace',
- active: true,
- project: project)
- end
-
- let(:params) do
- {
- namespace_id: project.namespace,
- project_id: project,
- iid: feature_flag.iid,
- operations_feature_flag: {
- name: 'ci_new_live_trace'
- }
- }
- end
-
- context 'when user is reporter' do
- let(:user) { reporter }
-
- it 'returns 404' do
- is_expected.to have_gitlab_http_status(:not_found)
- end
- end
-
- context "when changing default scope's spec" do
- let(:params) do
- {
- namespace_id: project.namespace,
- project_id: project,
- iid: feature_flag.iid,
- operations_feature_flag: {
- scopes_attributes: [
- {
- id: feature_flag.default_scope.id,
- environment_scope: 'review/*'
- }
- ]
- }
- }
- end
-
- it 'returns 400' do
- is_expected.to have_gitlab_http_status(:bad_request)
- end
- end
-
- it 'does not update a legacy feature flag' do
- put_request(feature_flag, name: 'ci_new_live_trace')
-
- expect(response).to have_gitlab_http_status(:bad_request)
- expect(json_response['message']).to eq(["Legacy feature flags are read-only"])
- end
- end
-
context 'with a version 2 feature flag' do
let!(:new_version_flag) do
create(:operations_feature_flag,
- :new_version_flag,
name: 'new-feature',
active: true,
project: project)
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index 0c29280316a..977879b453c 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -109,6 +109,14 @@ RSpec.describe Projects::IssuesController do
end
end
+ it_behaves_like 'issuable list with anonymous search disabled' do
+ let(:params) { { namespace_id: project.namespace, project_id: project } }
+
+ before do
+ project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
+ end
+ end
+
it_behaves_like 'paginated collection' do
let!(:issue_list) { create_list(:issue, 2, project: project) }
let(:collection) { project.issues }
@@ -301,6 +309,8 @@ RSpec.describe Projects::IssuesController do
it 'fills in an issue for a discussion' do
note = create(:note_on_merge_request, project: project)
+ expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter).to receive(:track_resolve_thread_in_issue_action).with(user: user)
+
get :new, params: { namespace_id: project.namespace.path, project_id: project, merge_request_to_resolve_discussions_of: note.noteable.iid, discussion_to_resolve: note.discussion_id }
expect(assigns(:issue).title).not_to be_empty
@@ -1176,12 +1186,22 @@ RSpec.describe Projects::IssuesController do
project.issues.first
end
+ context 'when creating an incident' do
+ it 'sets the correct issue_type' do
+ issue = post_new_issue(issue_type: 'incident')
+
+ expect(issue.issue_type).to eq('incident')
+ expect(issue.work_item_type.base_type).to eq('incident')
+ end
+ end
+
it 'creates the issue successfully', :aggregate_failures do
issue = post_new_issue
expect(issue).to be_a(Issue)
expect(issue.persisted?).to eq(true)
expect(issue.issue_type).to eq('issue')
+ expect(issue.work_item_type.base_type).to eq('issue')
end
context 'resolving discussions in MergeRequest' do
diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb
index e9e7c3c3bb3..06c29e767ad 100644
--- a/spec/controllers/projects/jobs_controller_spec.rb
+++ b/spec/controllers/projects/jobs_controller_spec.rb
@@ -755,23 +755,52 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do
before do
project.add_developer(user)
sign_in(user)
-
- post_retry
end
context 'when job is retryable' do
let(:job) { create(:ci_build, :retryable, pipeline: pipeline) }
it 'redirects to the retried job page' do
+ post_retry
+
expect(response).to have_gitlab_http_status(:found)
expect(response).to redirect_to(namespace_project_job_path(id: Ci::Build.last.id))
end
+
+ shared_examples_for 'retried job has the same attributes' do
+ it 'creates a new build has the same attributes from the previous build' do
+ expect { post_retry }.to change { Ci::Build.count }.by(1)
+
+ retried_build = Ci::Build.last
+
+ Ci::RetryBuildService.clone_accessors.each do |accessor|
+ expect(job.read_attribute(accessor))
+ .to eq(retried_build.read_attribute(accessor)),
+ "Mismatched attribute on \"#{accessor}\". " \
+ "It was \"#{job.read_attribute(accessor)}\" but changed to \"#{retried_build.read_attribute(accessor)}\""
+ end
+ end
+ end
+
+ context 'with branch pipeline' do
+ let!(:job) { create(:ci_build, :retryable, tag: true, when: 'on_success', pipeline: pipeline) }
+
+ it_behaves_like 'retried job has the same attributes'
+ end
+
+ context 'with tag pipeline' do
+ let!(:job) { create(:ci_build, :retryable, tag: false, when: 'on_success', pipeline: pipeline) }
+
+ it_behaves_like 'retried job has the same attributes'
+ end
end
context 'when job is not retryable' do
let(:job) { create(:ci_build, pipeline: pipeline) }
it 'renders unprocessable_entity' do
+ post_retry
+
expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
end
diff --git a/spec/controllers/projects/learn_gitlab_controller_spec.rb b/spec/controllers/projects/learn_gitlab_controller_spec.rb
index f633f7aa246..620982f73be 100644
--- a/spec/controllers/projects/learn_gitlab_controller_spec.rb
+++ b/spec/controllers/projects/learn_gitlab_controller_spec.rb
@@ -7,13 +7,13 @@ RSpec.describe Projects::LearnGitlabController do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, namespace: user.namespace) }
- let(:learn_gitlab_experiment_enabled) { true }
+ let(:learn_gitlab_enabled) { true }
let(:params) { { namespace_id: project.namespace.to_param, project_id: project } }
subject { get :index, params: params }
before do
- allow(controller.helpers).to receive(:learn_gitlab_experiment_enabled?).and_return(learn_gitlab_experiment_enabled)
+ allow(controller.helpers).to receive(:learn_gitlab_enabled?).and_return(learn_gitlab_enabled)
end
context 'unauthenticated user' do
@@ -27,15 +27,8 @@ RSpec.describe Projects::LearnGitlabController do
it { is_expected.to render_template(:index) }
- it 'pushes experiment to frontend' do
- expect(controller).to receive(:push_frontend_experiment).with(:learn_gitlab_a, subject: user)
- expect(controller).to receive(:push_frontend_experiment).with(:learn_gitlab_b, subject: user)
-
- subject
- end
-
context 'learn_gitlab experiment not enabled' do
- let(:learn_gitlab_experiment_enabled) { false }
+ let(:learn_gitlab_enabled) { false }
it { is_expected.to have_gitlab_http_status(:not_found) }
end
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index 7b5a58fe2e5..0da8a30611c 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -349,6 +349,15 @@ RSpec.describe Projects::MergeRequestsController do
end
end
end
+
+ it_behaves_like 'issuable list with anonymous search disabled' do
+ let(:params) { { namespace_id: project.namespace, project_id: project } }
+
+ before do
+ sign_out(user)
+ project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
+ end
+ end
end
describe 'PUT update' do
diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb
index 65a563fac7c..1354e894872 100644
--- a/spec/controllers/projects/pipelines_controller_spec.rb
+++ b/spec/controllers/projects/pipelines_controller_spec.rb
@@ -311,23 +311,42 @@ RSpec.describe Projects::PipelinesController do
let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
- def create_build_with_artifacts(stage, stage_idx, name)
- create(:ci_build, :artifacts, :tags, pipeline: pipeline, stage: stage, stage_idx: stage_idx, name: name)
+ def create_build_with_artifacts(stage, stage_idx, name, status)
+ create(:ci_build, :artifacts, :tags, status, user: user, pipeline: pipeline, stage: stage, stage_idx: stage_idx, name: name)
+ end
+
+ def create_bridge(stage, stage_idx, name, status)
+ create(:ci_bridge, status, pipeline: pipeline, stage: stage, stage_idx: stage_idx, name: name)
end
before do
- create_build_with_artifacts('build', 0, 'job1')
- create_build_with_artifacts('build', 0, 'job2')
+ create_build_with_artifacts('build', 0, 'job1', :failed)
+ create_build_with_artifacts('build', 0, 'job2', :running)
+ create_build_with_artifacts('build', 0, 'job3', :pending)
+ create_bridge('deploy', 1, 'deploy-a', :failed)
+ create_bridge('deploy', 1, 'deploy-b', :created)
end
- it 'avoids N+1 database queries', :request_store do
- control_count = ActiveRecord::QueryRecorder.new { get_pipeline_html }.count
+ it 'avoids N+1 database queries', :request_store, :use_sql_query_cache do
+ # warm up
+ get_pipeline_html
expect(response).to have_gitlab_http_status(:ok)
- create_build_with_artifacts('build', 0, 'job3')
+ control = ActiveRecord::QueryRecorder.new(skip_cached: false) do
+ get_pipeline_html
+ expect(response).to have_gitlab_http_status(:ok)
+ end
- expect { get_pipeline_html }.not_to exceed_query_limit(control_count)
- expect(response).to have_gitlab_http_status(:ok)
+ create_build_with_artifacts('build', 0, 'job4', :failed)
+ create_build_with_artifacts('build', 0, 'job5', :running)
+ create_build_with_artifacts('build', 0, 'job6', :pending)
+ create_bridge('deploy', 1, 'deploy-c', :failed)
+ create_bridge('deploy', 1, 'deploy-d', :created)
+
+ expect do
+ get_pipeline_html
+ expect(response).to have_gitlab_http_status(:ok)
+ end.not_to exceed_all_query_limit(control)
end
end
@@ -1273,6 +1292,38 @@ RSpec.describe Projects::PipelinesController do
end
end
+ context 'when project uses external project ci config' do
+ let(:other_project) { create(:project) }
+ let(:sha) { 'master' }
+ let(:service) { ::Ci::ListConfigVariablesService.new(other_project, user) }
+
+ let(:ci_config) do
+ {
+ variables: {
+ KEY1: { value: 'val 1', description: 'description 1' }
+ },
+ test: {
+ stage: 'test',
+ script: 'echo'
+ }
+ }
+ end
+
+ before do
+ project.update!(ci_config_path: ".gitlab-ci.yml@#{other_project.full_path}")
+ synchronous_reactive_cache(service)
+ end
+
+ it 'returns other project config variables' do
+ expect(::Ci::ListConfigVariablesService).to receive(:new).with(other_project, anything).and_return(service)
+
+ get_config_variables
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['KEY1']).to eq({ 'value' => 'val 1', 'description' => 'description 1' })
+ end
+ end
+
private
def stub_gitlab_ci_yml_for_sha(sha, result)
diff --git a/spec/controllers/projects/services_controller_spec.rb b/spec/controllers/projects/services_controller_spec.rb
index 419b5c7e101..482ba552f8f 100644
--- a/spec/controllers/projects/services_controller_spec.rb
+++ b/spec/controllers/projects/services_controller_spec.rb
@@ -18,6 +18,18 @@ RSpec.describe Projects::ServicesController do
project.add_maintainer(user)
end
+ it_behaves_like IntegrationsActions do
+ let(:integration_attributes) { { project: project } }
+
+ let(:routing_params) do
+ {
+ namespace_id: project.namespace,
+ project_id: project,
+ id: integration.to_param
+ }
+ end
+ end
+
describe '#test' do
context 'when the integration is not testable' do
it 'renders 404' do
diff --git a/spec/controllers/registrations/experience_levels_controller_spec.rb b/spec/controllers/registrations/experience_levels_controller_spec.rb
deleted file mode 100644
index ad145264bb8..00000000000
--- a/spec/controllers/registrations/experience_levels_controller_spec.rb
+++ /dev/null
@@ -1,159 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Registrations::ExperienceLevelsController do
- include AfterNextHelpers
-
- let_it_be(:namespace) { create(:group, path: 'group-path' ) }
- let_it_be(:user) { create(:user) }
-
- let(:params) { { namespace_path: namespace.to_param } }
-
- describe 'GET #show' do
- subject { get :show, params: params }
-
- context 'with an unauthenticated user' do
- it { is_expected.to have_gitlab_http_status(:redirect) }
- it { is_expected.to redirect_to(new_user_session_path) }
- end
-
- context 'with an authenticated user' do
- before do
- sign_in(user)
- end
-
- it { is_expected.to have_gitlab_http_status(:ok) }
- it { is_expected.to render_template('layouts/minimal') }
- it { is_expected.to render_template(:show) }
- end
- end
-
- describe 'PUT/PATCH #update' do
- subject { patch :update, params: params }
-
- context 'with an unauthenticated user' do
- it { is_expected.to have_gitlab_http_status(:redirect) }
- it { is_expected.to redirect_to(new_user_session_path) }
- end
-
- context 'with an authenticated user' do
- let_it_be(:project) { build(:project, namespace: namespace, creator: user, path: 'project-path') }
- let_it_be(:issues_board) { build(:board, id: 123, project: project) }
-
- before do
- sign_in(user)
- end
-
- context 'when user is successfully updated' do
- context 'when no experience_level is sent' do
- before do
- user.user_preference.update_attribute(:experience_level, :novice)
- end
-
- it 'will unset the user’s experience level' do
- expect { subject }.to change { user.reload.experience_level }.to(nil)
- end
- end
-
- context 'when an expected experience level is sent' do
- let(:params) { super().merge(experience_level: :novice) }
-
- it 'sets the user’s experience level' do
- expect { subject }.to change { user.reload.experience_level }.from(nil).to('novice')
- end
- end
-
- context 'when an unexpected experience level is sent' do
- let(:params) { super().merge(experience_level: :nonexistent) }
-
- it 'raises an exception' do
- expect { subject }.to raise_error(ArgumentError, "'nonexistent' is not a valid experience_level")
- end
- end
-
- context 'when "Learn GitLab" project exists' do
- let(:learn_gitlab_available?) { true }
-
- before do
- allow_next_instance_of(LearnGitlab::Project) do |learn_gitlab|
- allow(learn_gitlab).to receive(:available?).and_return(learn_gitlab_available?)
- allow(learn_gitlab).to receive(:project).and_return(project)
- allow(learn_gitlab).to receive(:board).and_return(issues_board)
- allow(learn_gitlab).to receive(:label).and_return(double(id: 1))
- end
- end
-
- context 'redirection' do
- context 'when namespace_path param is missing' do
- let(:params) { super().merge(namespace_path: nil) }
-
- where(
- learn_gitlab_available?: [true, false]
- )
-
- with_them do
- it { is_expected.to redirect_to('/') }
- end
- end
-
- context 'when we have a namespace_path param' do
- using RSpec::Parameterized::TableSyntax
-
- where(:learn_gitlab_available?, :path) do
- true | '/group-path/project-path/-/boards/123'
- false | '/group-path'
- end
-
- with_them do
- it { is_expected.to redirect_to(path) }
- end
- end
- end
-
- context 'when novice' do
- let(:params) { super().merge(experience_level: :novice) }
-
- it 'adds a BoardLabel' do
- expect_next(Boards::UpdateService).to receive(:execute)
-
- subject
- end
- end
-
- context 'when experienced' do
- let(:params) { super().merge(experience_level: :experienced) }
-
- it 'does not add a BoardLabel' do
- expect(Boards::UpdateService).not_to receive(:new)
-
- subject
- end
- end
- end
-
- context 'when no "Learn GitLab" project exists' do
- let(:params) { super().merge(experience_level: :novice) }
-
- before do
- allow_next(LearnGitlab::Project).to receive(:available?).and_return(false)
- end
-
- it 'does not add a BoardLabel' do
- expect(Boards::UpdateService).not_to receive(:new)
-
- subject
- end
- end
- end
-
- context 'when user update fails' do
- before do
- allow_any_instance_of(User).to receive(:save).and_return(false)
- end
-
- it { is_expected.to render_template(:show) }
- end
- end
- end
-end
diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb
index 301c60e89c8..5edd60ebc79 100644
--- a/spec/controllers/registrations_controller_spec.rb
+++ b/spec/controllers/registrations_controller_spec.rb
@@ -227,6 +227,40 @@ RSpec.describe RegistrationsController do
end
end
end
+
+ context 'with the invite_email_preview_text experiment', :experiment do
+ let(:extra_session_params) { { invite_email_experiment_name: 'invite_email_from' } }
+
+ context 'when member and invite_email_experiment_name exists from the session key value' do
+ it 'tracks the invite acceptance' do
+ expect(experiment(:invite_email_from)).to track(:accepted)
+ .with_context(actor: member)
+ .on_next_instance
+
+ subject
+ end
+ end
+
+ context 'when member does not exist from the session key value' do
+ let(:originating_member_id) { -1 }
+
+ it 'does not track invite acceptance' do
+ expect(experiment(:invite_email_from)).not_to track(:accepted)
+
+ subject
+ end
+ end
+
+ context 'when invite_email_experiment_name does not exist from the session key value' do
+ let(:extra_session_params) { {} }
+
+ it 'does not track invite acceptance' do
+ expect(experiment(:invite_email_from)).not_to track(:accepted)
+
+ subject
+ end
+ end
+ end
end
context 'when invite email matches email used on registration' do
@@ -249,6 +283,26 @@ RSpec.describe RegistrationsController do
end
end
+ context 'when the registration fails' do
+ let_it_be(:member) { create(:project_member, :invited) }
+ let_it_be(:missing_user_params) do
+ { username: '', email: member.invite_email, password: 'Any_password' }
+ end
+
+ let_it_be(:user_params) { { user: missing_user_params } }
+
+ let(:session_params) { { invite_email: member.invite_email } }
+
+ subject { post(:create, params: user_params, session: session_params) }
+
+ it 'does not delete the invitation or register the new user' do
+ subject
+
+ expect(member.invite_token).not_to be_nil
+ expect(controller.current_user).to be_nil
+ end
+ end
+
context 'when soft email confirmation is enabled' do
before do
stub_feature_flags(soft_email_confirmation: true)
diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb
index e0870e17d99..4e87a9fc1ba 100644
--- a/spec/controllers/search_controller_spec.rb
+++ b/spec/controllers/search_controller_spec.rb
@@ -182,6 +182,37 @@ RSpec.describe SearchController do
end
end
end
+
+ context 'tab feature flags' do
+ subject { get :show, params: { scope: scope, search: 'term' }, format: :html }
+
+ where(:feature_flag, :scope) do
+ :global_search_code_tab | 'blobs'
+ :global_search_issues_tab | 'issues'
+ :global_search_merge_requests_tab | 'merge_requests'
+ :global_search_wiki_tab | 'wiki_blobs'
+ :global_search_commits_tab | 'commits'
+ end
+
+ with_them do
+ it 'returns 200 if flag is enabled' do
+ stub_feature_flags(feature_flag => true)
+
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ it 'redirects with alert if flag is disabled' do
+ stub_feature_flags(feature_flag => false)
+
+ subject
+
+ expect(response).to redirect_to search_path
+ expect(controller).to set_flash[:alert].to(/Global Search is disabled for this scope/)
+ end
+ end
+ end
end
it 'finds issue comments' do
diff --git a/spec/controllers/user_callouts_controller_spec.rb b/spec/controllers/user_callouts_controller_spec.rb
index 279f825e40f..3bb8d78a6b0 100644
--- a/spec/controllers/user_callouts_controller_spec.rb
+++ b/spec/controllers/user_callouts_controller_spec.rb
@@ -3,14 +3,16 @@
require 'spec_helper'
RSpec.describe UserCalloutsController do
- let(:user) { create(:user) }
+ let_it_be(:user) { create(:user) }
before do
sign_in(user)
end
describe "POST #create" do
- subject { post :create, params: { feature_name: feature_name }, format: :json }
+ let(:params) { { feature_name: feature_name } }
+
+ subject { post :create, params: params, format: :json }
context 'with valid feature name' do
let(:feature_name) { UserCallout.feature_names.each_key.first }
@@ -30,9 +32,8 @@ RSpec.describe UserCalloutsController do
context 'when callout entry already exists' do
let!(:callout) { create(:user_callout, feature_name: UserCallout.feature_names.each_key.first, user: user) }
- it 'returns success' do
- subject
-
+ it 'returns success', :aggregate_failures do
+ expect { subject }.not_to change { UserCallout.count }
expect(response).to have_gitlab_http_status(:ok)
end
end
diff --git a/spec/db/development/create_base_work_item_types_spec.rb b/spec/db/development/create_base_work_item_types_spec.rb
new file mode 100644
index 00000000000..914b84d8668
--- /dev/null
+++ b/spec/db/development/create_base_work_item_types_spec.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Create base work item types in development' do
+ subject { load Rails.root.join('db', 'fixtures', 'development', '001_create_base_work_item_types.rb') }
+
+ it_behaves_like 'work item base types importer'
+end
diff --git a/spec/db/production/create_base_work_item_types_spec.rb b/spec/db/production/create_base_work_item_types_spec.rb
new file mode 100644
index 00000000000..81d80104bb4
--- /dev/null
+++ b/spec/db/production/create_base_work_item_types_spec.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Create base work item types in production' do
+ subject { load Rails.root.join('db', 'fixtures', 'production', '003_create_base_work_item_types.rb') }
+
+ it_behaves_like 'work item base types importer'
+end
diff --git a/spec/db/schema_spec.rb b/spec/db/schema_spec.rb
index 7e4b8c53885..c7739e2ff5f 100644
--- a/spec/db/schema_spec.rb
+++ b/spec/db/schema_spec.rb
@@ -18,6 +18,8 @@ RSpec.describe 'Database schema' do
approvals: %w[user_id],
approver_groups: %w[target_id],
approvers: %w[target_id user_id],
+ analytics_cycle_analytics_merge_request_stage_events: %w[author_id group_id merge_request_id milestone_id project_id stage_event_hash_id],
+ analytics_cycle_analytics_issue_stage_events: %w[author_id group_id issue_id milestone_id project_id stage_event_hash_id],
audit_events: %w[author_id entity_id target_id],
award_emoji: %w[awardable_id user_id],
aws_roles: %w[role_external_id],
@@ -33,6 +35,7 @@ RSpec.describe 'Database schema' do
cluster_providers_gcp: %w[gcp_project_id operation_id],
compliance_management_frameworks: %w[group_id],
commit_user_mentions: %w[commit_id],
+ dep_ci_build_trace_sections: %w[build_id],
deploy_keys_projects: %w[deploy_key_id],
deployments: %w[deployable_id user_id],
draft_notes: %w[discussion_id commit_id],
diff --git a/spec/deprecation_toolkit_env.rb b/spec/deprecation_toolkit_env.rb
index f4db2c30094..5e7ff34463c 100644
--- a/spec/deprecation_toolkit_env.rb
+++ b/spec/deprecation_toolkit_env.rb
@@ -60,13 +60,12 @@ module DeprecationToolkitEnv
# - ruby/lib/grpc/generic/interceptors.rb: https://gitlab.com/gitlab-org/gitlab/-/issues/339305
def self.allowed_kwarg_warning_paths
%w[
- actionpack-6.1.3.2/lib/action_dispatch/routing/route_set.rb
- ruby/lib/grpc/generic/interceptors.rb
- ]
+ ruby/lib/grpc/generic/interceptors.rb
+ ]
end
def self.configure!
- # Enable ruby deprecations for keywords, it's suppressed by default in Ruby 2.7.2
+ # Enable ruby deprecations for keywords, it's suppressed by default in Ruby 2.7
Warning[:deprecated] = true
DeprecationToolkit::Configuration.test_runner = :rspec
diff --git a/spec/experiments/security_reports_mr_widget_prompt_experiment_spec.rb b/spec/experiments/security_reports_mr_widget_prompt_experiment_spec.rb
new file mode 100644
index 00000000000..4328ff12d42
--- /dev/null
+++ b/spec/experiments/security_reports_mr_widget_prompt_experiment_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe SecurityReportsMrWidgetPromptExperiment do
+ it "defines a control and candidate" do
+ expect(subject.behaviors.keys).to match_array(%w[control candidate])
+ end
+
+ it "publishes to the database" do
+ expect(subject).to receive(:publish_to_database)
+
+ subject.publish
+ end
+end
diff --git a/spec/factories/ci/build_trace_metadata.rb b/spec/factories/ci/build_trace_metadata.rb
new file mode 100644
index 00000000000..e5f8ae40cc5
--- /dev/null
+++ b/spec/factories/ci/build_trace_metadata.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :ci_build_trace_metadata, class: 'Ci::BuildTraceMetadata' do
+ build factory: :ci_build
+ end
+end
diff --git a/spec/factories/ci/builds.rb b/spec/factories/ci/builds.rb
index f3500301e22..1108c606df3 100644
--- a/spec/factories/ci/builds.rb
+++ b/spec/factories/ci/builds.rb
@@ -534,6 +534,14 @@ FactoryBot.define do
end
end
+ trait :coverage_fuzzing do
+ options do
+ {
+ artifacts: { reports: { coverage_fuzzing: 'gl-coverage-fuzzing-report.json' } }
+ }
+ end
+ end
+
trait :license_scanning do
options do
{
diff --git a/spec/factories/ci/pending_builds.rb b/spec/factories/ci/pending_builds.rb
index fbd76e07d8e..31e42e1bc9e 100644
--- a/spec/factories/ci/pending_builds.rb
+++ b/spec/factories/ci/pending_builds.rb
@@ -8,5 +8,6 @@ FactoryBot.define do
instance_runners_enabled { true }
namespace { project.namespace }
minutes_exceeded { false }
+ tag_ids { build.tags_ids }
end
end
diff --git a/spec/factories/ci/reports/security/flags.rb b/spec/factories/ci/reports/security/flags.rb
new file mode 100644
index 00000000000..7efe72276c9
--- /dev/null
+++ b/spec/factories/ci/reports/security/flags.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :ci_reports_security_flag, class: '::Gitlab::Ci::Reports::Security::Flag' do
+ type { 'flagged-as-likely-false-positive' }
+ origin { 'post analyzer X' }
+ description { 'static string to sink' }
+
+ skip_create
+
+ initialize_with do
+ ::Gitlab::Ci::Reports::Security::Flag.new(**attributes)
+ end
+ end
+end
diff --git a/spec/factories/clusters/agents.rb b/spec/factories/clusters/agents.rb
index 334671f69f0..4dc82f91bab 100644
--- a/spec/factories/clusters/agents.rb
+++ b/spec/factories/clusters/agents.rb
@@ -3,6 +3,7 @@
FactoryBot.define do
factory :cluster_agent, class: 'Clusters::Agent' do
project
+ association :created_by_user, factory: :user
sequence(:name) { |n| "agent-#{n}" }
end
diff --git a/spec/factories/clusters/agents/group_authorizations.rb b/spec/factories/clusters/agents/group_authorizations.rb
new file mode 100644
index 00000000000..6ea3668dc66
--- /dev/null
+++ b/spec/factories/clusters/agents/group_authorizations.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :agent_group_authorization, class: 'Clusters::Agents::GroupAuthorization' do
+ association :agent, factory: :cluster_agent
+ group
+
+ config { { default_namespace: 'production' } }
+ end
+end
diff --git a/spec/factories/clusters/agents/project_authorizations.rb b/spec/factories/clusters/agents/project_authorizations.rb
new file mode 100644
index 00000000000..176ecc3b517
--- /dev/null
+++ b/spec/factories/clusters/agents/project_authorizations.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :agent_project_authorization, class: 'Clusters::Agents::ProjectAuthorization' do
+ association :agent, factory: :cluster_agent
+ project
+
+ config { { default_namespace: 'production' } }
+ end
+end
diff --git a/spec/factories/compares.rb b/spec/factories/compares.rb
new file mode 100644
index 00000000000..4dd94b93049
--- /dev/null
+++ b/spec/factories/compares.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :compare do
+ skip_create # No persistence
+
+ start_project { association(:project, :repository) }
+ target_project { start_project }
+
+ start_ref { 'master' }
+ target_ref { 'feature' }
+
+ base_sha { nil }
+ straight { false }
+
+ initialize_with do
+ CompareService
+ .new(start_project, start_ref)
+ .execute(target_project, target_ref, base_sha: base_sha, straight: straight)
+ end
+ end
+end
diff --git a/spec/factories/customer_relations/contacts.rb b/spec/factories/customer_relations/contacts.rb
new file mode 100644
index 00000000000..437f8feea48
--- /dev/null
+++ b/spec/factories/customer_relations/contacts.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :contact, class: 'CustomerRelations::Contact' do
+ group
+
+ first_name { generate(:name) }
+ last_name { generate(:name) }
+
+ trait :with_organization do
+ organization
+ end
+ end
+end
diff --git a/spec/factories/dependency_proxy.rb b/spec/factories/dependency_proxy.rb
index 94a7986a8fa..c2873ce9b5e 100644
--- a/spec/factories/dependency_proxy.rb
+++ b/spec/factories/dependency_proxy.rb
@@ -3,12 +3,14 @@
FactoryBot.define do
factory :dependency_proxy_blob, class: 'DependencyProxy::Blob' do
group
+ size { 1234 }
file { fixture_file_upload('spec/fixtures/dependency_proxy/a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4.gz') }
file_name { 'a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4.gz' }
end
factory :dependency_proxy_manifest, class: 'DependencyProxy::Manifest' do
group
+ size { 1234 }
file { fixture_file_upload('spec/fixtures/dependency_proxy/manifest') }
digest { 'sha256:d0710affa17fad5f466a70159cc458227bd25d4afb39514ef662ead3e6c99515' }
file_name { 'alpine:latest.json' }
diff --git a/spec/factories/dependency_proxy/image_ttl_group_policies.rb b/spec/factories/dependency_proxy/image_ttl_group_policies.rb
new file mode 100644
index 00000000000..21e5dd44cf5
--- /dev/null
+++ b/spec/factories/dependency_proxy/image_ttl_group_policies.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :image_ttl_group_policy, class: 'DependencyProxy::ImageTtlGroupPolicy' do
+ group
+
+ enabled { true }
+ ttl { 90 }
+ end
+end
diff --git a/spec/factories/integration_data.rb b/spec/factories/integration_data.rb
index a7406794437..4d0892556f8 100644
--- a/spec/factories/integration_data.rb
+++ b/spec/factories/integration_data.rb
@@ -7,13 +7,21 @@ FactoryBot.define do
integration factory: :jira_integration
end
+ factory :zentao_tracker_data, class: 'Integrations::ZentaoTrackerData' do
+ integration factory: :zentao_integration
+ url { 'https://jihudemo.zentao.net' }
+ api_url { '' }
+ api_token { 'ZENTAO_TOKEN' }
+ zentao_product_xid { '3' }
+ end
+
factory :issue_tracker_data, class: 'Integrations::IssueTrackerData' do
integration
end
factory :open_project_tracker_data, class: 'Integrations::OpenProjectTrackerData' do
integration factory: :open_project_service
- url { 'http://openproject.example.com'}
+ url { 'http://openproject.example.com' }
token { 'supersecret' }
project_identifier_code { 'PRJ-1' }
closed_status_id { '15' }
diff --git a/spec/factories/integrations.rb b/spec/factories/integrations.rb
index a5a17ca4058..cb1c94c25c1 100644
--- a/spec/factories/integrations.rb
+++ b/spec/factories/integrations.rb
@@ -12,6 +12,12 @@ FactoryBot.define do
issue_tracker
end
+ factory :datadog_integration, class: 'Integrations::Datadog' do
+ project
+ active { true }
+ api_key { 'secret' }
+ end
+
factory :emails_on_push_integration, class: 'Integrations::EmailsOnPush' do
project
type { 'EmailsOnPushService' }
@@ -79,6 +85,32 @@ FactoryBot.define do
end
end
+ factory :zentao_integration, class: 'Integrations::Zentao' do
+ project
+ active { true }
+ type { 'ZentaoService' }
+
+ transient do
+ create_data { true }
+ url { 'https://jihudemo.zentao.net' }
+ api_url { '' }
+ api_token { 'ZENTAO_TOKEN' }
+ zentao_product_xid { '3' }
+ end
+
+ after(:build) do |integration, evaluator|
+ if evaluator.create_data
+ integration.zentao_tracker_data = build(:zentao_tracker_data,
+ integration: integration,
+ url: evaluator.url,
+ api_url: evaluator.api_url,
+ api_token: evaluator.api_token,
+ zentao_product_xid: evaluator.zentao_product_xid
+ )
+ end
+ end
+ end
+
factory :confluence_integration, class: 'Integrations::Confluence' do
project
active { true }
diff --git a/spec/factories/issues.rb b/spec/factories/issues.rb
index 2d52747dece..8b53732a3c1 100644
--- a/spec/factories/issues.rb
+++ b/spec/factories/issues.rb
@@ -8,6 +8,7 @@ FactoryBot.define do
updated_by { author }
relative_position { RelativePositioning::START_POSITION }
issue_type { :issue }
+ association :work_item_type, :default
trait :confidential do
confidential { true }
@@ -59,6 +60,7 @@ FactoryBot.define do
factory :incident do
issue_type { :incident }
+ association :work_item_type, :default, :incident
end
end
end
diff --git a/spec/factories/namespaces/project_namespaces.rb b/spec/factories/namespaces/project_namespaces.rb
new file mode 100644
index 00000000000..10b86f48090
--- /dev/null
+++ b/spec/factories/namespaces/project_namespaces.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :project_namespace, class: 'Namespaces::ProjectNamespace' do
+ project
+ name { project.name }
+ path { project.path }
+ type { Namespaces::ProjectNamespace.sti_name }
+ owner { nil }
+ parent factory: :group
+ end
+end
diff --git a/spec/factories/operations/feature_flag_scopes.rb b/spec/factories/operations/feature_flag_scopes.rb
deleted file mode 100644
index 4ca9b53f320..00000000000
--- a/spec/factories/operations/feature_flag_scopes.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-# frozen_string_literal: true
-
-FactoryBot.define do
- factory :operations_feature_flag_scope, class: 'Operations::FeatureFlagScope' do
- association :feature_flag, factory: [:operations_feature_flag, :legacy_flag]
- active { true }
- strategies { [{ name: "default", parameters: {} }] }
- sequence(:environment_scope) { |n| "review/patch-#{n}" }
- end
-end
diff --git a/spec/factories/operations/feature_flags.rb b/spec/factories/operations/feature_flags.rb
index 32e5ec9fb26..33c13a62445 100644
--- a/spec/factories/operations/feature_flags.rb
+++ b/spec/factories/operations/feature_flags.rb
@@ -6,13 +6,5 @@ FactoryBot.define do
project
active { true }
version { :new_version_flag }
-
- trait :legacy_flag do
- version { Operations::FeatureFlag.versions['legacy_flag'] }
- end
-
- trait :new_version_flag do
- version { Operations::FeatureFlag.versions['new_version_flag'] }
- end
end
end
diff --git a/spec/factories/packages.rb b/spec/factories/packages.rb
index cd9c8a8bfbb..b04b7e691fe 100644
--- a/spec/factories/packages.rb
+++ b/spec/factories/packages.rb
@@ -112,7 +112,7 @@ FactoryBot.define do
factory :npm_package do
sequence(:name) { |n| "@#{project.root_namespace.path}/package-#{n}"}
- version { '1.0.0' }
+ sequence(:version) { |n| "1.0.#{n}" }
package_type { :npm }
after :create do |package|
@@ -354,4 +354,12 @@ FactoryBot.define do
package
sequence(:name) { |n| "tag-#{n}"}
end
+
+ factory :packages_build_info, class: 'Packages::BuildInfo' do
+ package
+
+ trait :with_pipeline do
+ association :pipeline, factory: [:ci_pipeline, :with_job]
+ end
+ end
end
diff --git a/spec/factories/packages/helm/file_metadatum.rb b/spec/factories/packages/helm/file_metadatum.rb
index cbc7e114ef6..3f599b5d5c0 100644
--- a/spec/factories/packages/helm/file_metadatum.rb
+++ b/spec/factories/packages/helm/file_metadatum.rb
@@ -2,8 +2,16 @@
FactoryBot.define do
factory :helm_file_metadatum, class: 'Packages::Helm::FileMetadatum' do
+ transient do
+ description { nil }
+ end
+
package_file { association(:helm_package_file, without_loaded_metadatum: true) }
sequence(:channel) { |n| "#{FFaker::Lorem.word}-#{n}" }
- metadata { { 'name': package_file.package.name, 'version': package_file.package.version, 'apiVersion': 'v2' } }
+ metadata do
+ { 'name': package_file.package.name, 'version': package_file.package.version, 'apiVersion': 'v2' }.tap do |defaults|
+ defaults['description'] = description if description
+ end
+ end
end
end
diff --git a/spec/factories/packages/package_file.rb b/spec/factories/packages/package_file.rb
index ac121da432c..d9afbac1048 100644
--- a/spec/factories/packages/package_file.rb
+++ b/spec/factories/packages/package_file.rb
@@ -212,11 +212,12 @@ FactoryBot.define do
package_name { package&.name || 'foo' }
sequence(:package_version) { |n| package&.version || "v#{n}" }
channel { 'stable' }
+ description { nil }
end
after :create do |package_file, evaluator|
unless evaluator.without_loaded_metadatum
- create :helm_file_metadatum, package_file: package_file, channel: evaluator.channel
+ create :helm_file_metadatum, package_file: package_file, channel: evaluator.channel, description: evaluator.description
end
end
end
diff --git a/spec/factories/plan_limits.rb b/spec/factories/plan_limits.rb
index ae892307193..b5921c1b311 100644
--- a/spec/factories/plan_limits.rb
+++ b/spec/factories/plan_limits.rb
@@ -4,6 +4,8 @@ FactoryBot.define do
factory :plan_limits do
plan
+ dast_profile_schedules { 50 }
+
trait :default_plan do
plan factory: :default_plan
end
diff --git a/spec/factories/project_topics.rb b/spec/factories/project_topics.rb
new file mode 100644
index 00000000000..60f5357d129
--- /dev/null
+++ b/spec/factories/project_topics.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :project_topic, class: 'Projects::ProjectTopic' do
+ association :project, factory: :project
+ association :topic, factory: :topic
+ end
+end
diff --git a/spec/factories/topics.rb b/spec/factories/topics.rb
new file mode 100644
index 00000000000..e77441d9eae
--- /dev/null
+++ b/spec/factories/topics.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :topic, class: 'Projects::Topic' do
+ name { generate(:name) }
+ end
+end
diff --git a/spec/factories/users.rb b/spec/factories/users.rb
index 476c57f2d80..04bacbe14e7 100644
--- a/spec/factories/users.rb
+++ b/spec/factories/users.rb
@@ -11,10 +11,6 @@ FactoryBot.define do
confirmation_token { nil }
can_create_group { true }
- after(:stub) do |user|
- user.notification_email = user.email
- end
-
trait :admin do
admin { true }
end
diff --git a/spec/factories/users/group_user_callouts.rb b/spec/factories/users/group_user_callouts.rb
new file mode 100644
index 00000000000..de8a6d3ee77
--- /dev/null
+++ b/spec/factories/users/group_user_callouts.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :group_callout, class: 'Users::GroupCallout' do
+ feature_name { :invite_members_banner }
+
+ user
+ group
+ end
+end
diff --git a/spec/factories/work_item/work_item_types.rb b/spec/factories/work_item/work_item_types.rb
index 07d6d685c57..1c586aab59b 100644
--- a/spec/factories/work_item/work_item_types.rb
+++ b/spec/factories/work_item/work_item_types.rb
@@ -8,6 +8,17 @@ FactoryBot.define do
base_type { WorkItem::Type.base_types[:issue] }
icon_name { 'issue-type-issue' }
+ initialize_with do
+ type_base_attributes = attributes.with_indifferent_access.slice(:base_type, :namespace, :namespace_id)
+
+ # Expect base_types to exist on the DB
+ if type_base_attributes.slice(:namespace, :namespace_id).compact.empty?
+ WorkItem::Type.find_or_initialize_by(type_base_attributes).tap { |type| type.assign_attributes(attributes) }
+ else
+ WorkItem::Type.new(attributes)
+ end
+ end
+
trait :default do
namespace { nil }
end
diff --git a/spec/factories_spec.rb b/spec/factories_spec.rb
index 2b308c9080e..6c7c3776c4a 100644
--- a/spec/factories_spec.rb
+++ b/spec/factories_spec.rb
@@ -74,6 +74,7 @@ RSpec.describe 'factories' do
milestone_release
namespace
project_broken_repo
+ project_namespace
project_repository
prometheus_alert
prometheus_alert_event
diff --git a/spec/fast_spec_helper.rb b/spec/fast_spec_helper.rb
index b06ebba3f6c..1485edcd97d 100644
--- a/spec/fast_spec_helper.rb
+++ b/spec/fast_spec_helper.rb
@@ -7,7 +7,7 @@ if $".include?(File.expand_path('spec_helper.rb', __dir__))
return
end
-require 'bundler/setup'
+require_relative '../config/bundler_setup'
ENV['GITLAB_ENV'] = 'test'
ENV['IN_MEMORY_APPLICATION_SETTINGS'] = 'true'
diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb
index 54c07985a21..8053be89ffc 100644
--- a/spec/features/admin/admin_runners_spec.rb
+++ b/spec/features/admin/admin_runners_spec.rb
@@ -356,6 +356,7 @@ RSpec.describe "Admin Runners" do
assigned_project = page.find('[data-testid="assigned-projects"]')
+ expect(page).to have_content('Runner assigned to project.')
expect(assigned_project).to have_content(@project2.path)
end
end
@@ -399,13 +400,14 @@ RSpec.describe "Admin Runners" do
visit admin_runner_path(runner)
end
- it 'enables specific runner for project' do
+ it 'removed specific runner from project' do
within '[data-testid="assigned-projects"]' do
click_on 'Disable'
end
new_runner_project = page.find('[data-testid="unassigned-projects"]')
+ expect(page).to have_content('Runner unassigned from project.')
expect(new_runner_project).to have_content(@project1.path)
end
end
diff --git a/spec/features/admin/admin_sees_background_migrations_spec.rb b/spec/features/admin/admin_sees_background_migrations_spec.rb
index 11823195310..94fb3a0314f 100644
--- a/spec/features/admin/admin_sees_background_migrations_spec.rb
+++ b/spec/features/admin/admin_sees_background_migrations_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe "Admin > Admin sees background migrations" do
let_it_be(:finished_migration) { create(:batched_background_migration, table_name: 'finished', status: :finished) }
before_all do
- create(:batched_background_migration_job, batched_migration: failed_migration, batch_size: 30, status: :succeeded)
+ create(:batched_background_migration_job, batched_migration: failed_migration, batch_size: 10, min_value: 6, max_value: 15, status: :failed, attempts: 3)
end
before do
@@ -53,22 +53,35 @@ RSpec.describe "Admin > Admin sees background migrations" do
end
end
- it 'can view failed migrations' do
- visit admin_background_migrations_path
+ context 'when there are failed migrations' do
+ before do
+ allow_next_instance_of(Gitlab::BackgroundMigration::BatchingStrategies::PrimaryKeyBatchingStrategy) do |batch_class|
+ allow(batch_class).to receive(:next_batch).with(anything, anything, batch_min_value: 6, batch_size: 5).and_return([6, 10])
+ end
+ end
- within '#content-body' do
- tab = find_link 'Failed'
- tab.click
+ it 'can view and retry them' do
+ visit admin_background_migrations_path
- expect(page).to have_current_path(admin_background_migrations_path(tab: 'failed'))
- expect(tab[:class]).to include('gl-tab-nav-item-active', 'gl-tab-nav-item-active-indigo')
+ within '#content-body' do
+ tab = find_link 'Failed'
+ tab.click
- expect(page).to have_selector('tbody tr', count: 1)
+ expect(page).to have_current_path(admin_background_migrations_path(tab: 'failed'))
+ expect(tab[:class]).to include('gl-tab-nav-item-active', 'gl-tab-nav-item-active-indigo')
+
+ expect(page).to have_selector('tbody tr', count: 1)
+
+ expect(page).to have_content(failed_migration.job_class_name)
+ expect(page).to have_content(failed_migration.table_name)
+ expect(page).to have_content('0.00%')
+ expect(page).to have_content(failed_migration.status.humanize)
- expect(page).to have_content(failed_migration.job_class_name)
- expect(page).to have_content(failed_migration.table_name)
- expect(page).to have_content('30.00%')
- expect(page).to have_content(failed_migration.status.humanize)
+ click_button('Retry')
+ expect(page).not_to have_content(failed_migration.job_class_name)
+ expect(page).not_to have_content(failed_migration.table_name)
+ expect(page).not_to have_content('0.00%')
+ end
end
end
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index 4a0f7ccbb0a..b25fc9f257a 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -269,10 +269,7 @@ RSpec.describe 'Admin updates settings' do
end
context 'Integrations page' do
- let(:mailgun_events_receiver_enabled) { true }
-
before do
- stub_feature_flags(mailgun_events_receiver: mailgun_events_receiver_enabled)
visit general_admin_application_settings_path
end
@@ -286,26 +283,16 @@ RSpec.describe 'Admin updates settings' do
expect(current_settings.hide_third_party_offers).to be true
end
- context 'when mailgun_events_receiver feature flag is enabled' do
- it 'enabling Mailgun events', :aggregate_failures do
- page.within('.as-mailgun') do
- check 'Enable Mailgun event receiver'
- fill_in 'Mailgun HTTP webhook signing key', with: 'MAILGUN_SIGNING_KEY'
- click_button 'Save changes'
- end
-
- expect(page).to have_content 'Application settings saved successfully'
- expect(current_settings.mailgun_events_enabled).to be true
- expect(current_settings.mailgun_signing_key).to eq 'MAILGUN_SIGNING_KEY'
+ it 'enabling Mailgun events', :aggregate_failures do
+ page.within('.as-mailgun') do
+ check 'Enable Mailgun event receiver'
+ fill_in 'Mailgun HTTP webhook signing key', with: 'MAILGUN_SIGNING_KEY'
+ click_button 'Save changes'
end
- end
-
- context 'when mailgun_events_receiver feature flag is disabled' do
- let(:mailgun_events_receiver_enabled) { false }
- it 'does not have mailgun' do
- expect(page).not_to have_selector('.as-mailgun')
- end
+ expect(page).to have_content 'Application settings saved successfully'
+ expect(current_settings.mailgun_events_enabled).to be true
+ expect(current_settings.mailgun_signing_key).to eq 'MAILGUN_SIGNING_KEY'
end
end
@@ -559,6 +546,50 @@ RSpec.describe 'Admin updates settings' do
expect(current_settings.dns_rebinding_protection_enabled).to be false
end
+ it 'changes User and IP Rate Limits settings' do
+ visit network_admin_application_settings_path
+
+ page.within('.as-ip-limits') do
+ check 'Enable unauthenticated API request rate limit'
+ fill_in 'Maximum unauthenticated API requests per rate limit period per IP', with: 100
+ fill_in 'Unauthenticated API rate limit period in seconds', with: 200
+
+ check 'Enable unauthenticated web request rate limit'
+ fill_in 'Maximum unauthenticated web requests per rate limit period per IP', with: 300
+ fill_in 'Unauthenticated web rate limit period in seconds', with: 400
+
+ check 'Enable authenticated API request rate limit'
+ fill_in 'Maximum authenticated API requests per rate limit period per user', with: 500
+ fill_in 'Authenticated API rate limit period in seconds', with: 600
+
+ check 'Enable authenticated web request rate limit'
+ fill_in 'Maximum authenticated web requests per rate limit period per user', with: 700
+ fill_in 'Authenticated web rate limit period in seconds', with: 800
+
+ fill_in 'Plain-text response to send to clients that hit a rate limit', with: 'Custom message'
+
+ click_button 'Save changes'
+ end
+
+ expect(page).to have_content "Application settings saved successfully"
+
+ expect(current_settings).to have_attributes(
+ throttle_unauthenticated_api_enabled: true,
+ throttle_unauthenticated_api_requests_per_period: 100,
+ throttle_unauthenticated_api_period_in_seconds: 200,
+ throttle_unauthenticated_enabled: true,
+ throttle_unauthenticated_requests_per_period: 300,
+ throttle_unauthenticated_period_in_seconds: 400,
+ throttle_authenticated_api_enabled: true,
+ throttle_authenticated_api_requests_per_period: 500,
+ throttle_authenticated_api_period_in_seconds: 600,
+ throttle_authenticated_web_enabled: true,
+ throttle_authenticated_web_requests_per_period: 700,
+ throttle_authenticated_web_period_in_seconds: 800,
+ rate_limiting_response_text: 'Custom message'
+ )
+ end
+
it 'changes Issues rate limits settings' do
visit network_admin_application_settings_path
@@ -570,6 +601,20 @@ RSpec.describe 'Admin updates settings' do
expect(page).to have_content "Application settings saved successfully"
expect(current_settings.issues_create_limit).to eq(0)
end
+
+ it 'changes Files API rate limits settings' do
+ visit network_admin_application_settings_path
+
+ page.within('[data-testid="files-limits-settings"]') do
+ check 'Enable unauthenticated API request rate limit'
+ fill_in 'Max unauthenticated API requests per period per IP', with: 10
+ click_button 'Save changes'
+ end
+
+ expect(page).to have_content "Application settings saved successfully"
+ expect(current_settings.throttle_unauthenticated_files_api_enabled).to be true
+ expect(current_settings.throttle_unauthenticated_files_api_requests_per_period).to eq(10)
+ end
end
context 'Preferences page' do
diff --git a/spec/features/admin/admin_users_impersonation_tokens_spec.rb b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
index 7466150addf..0966032ff37 100644
--- a/spec/features/admin/admin_users_impersonation_tokens_spec.rb
+++ b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
@@ -42,7 +42,7 @@ RSpec.describe 'Admin > Users > Impersonation Tokens', :js do
click_on "Create impersonation token"
expect(active_impersonation_tokens).to have_text(name)
- expect(active_impersonation_tokens).to have_text('In')
+ expect(active_impersonation_tokens).to have_text('in')
expect(active_impersonation_tokens).to have_text('api')
expect(active_impersonation_tokens).to have_text('read_user')
expect(PersonalAccessTokensFinder.new(impersonation: true).execute.count).to equal(1)
@@ -59,6 +59,14 @@ RSpec.describe 'Admin > Users > Impersonation Tokens', :js do
expect(active_impersonation_tokens).to have_text(impersonation_token.name)
expect(active_impersonation_tokens).not_to have_text(personal_access_token.name)
+ expect(active_impersonation_tokens).to have_text('in')
+ end
+
+ it 'shows absolute times' do
+ admin.update!(time_display_relative: false)
+ visit admin_user_impersonation_tokens_path(user_id: user.username)
+
+ expect(active_impersonation_tokens).to have_text(personal_access_token.expires_at.strftime('%b %d'))
end
end
diff --git a/spec/features/atom/dashboard_issues_spec.rb b/spec/features/atom/dashboard_issues_spec.rb
index 511cdcc2940..855c91f70d7 100644
--- a/spec/features/atom/dashboard_issues_spec.rb
+++ b/spec/features/atom/dashboard_issues_spec.rb
@@ -4,8 +4,20 @@ require 'spec_helper'
RSpec.describe "Dashboard Issues Feed" do
describe "GET /issues" do
- let!(:user) { create(:user, email: 'private1@example.com', public_email: 'public1@example.com') }
- let!(:assignee) { create(:user, email: 'private2@example.com', public_email: 'public2@example.com') }
+ let!(:user) do
+ user = create(:user, email: 'private1@example.com')
+ public_email = create(:email, :confirmed, user: user, email: 'public1@example.com')
+ user.update!(public_email: public_email.email)
+ user
+ end
+
+ let!(:assignee) do
+ user = create(:user, email: 'private2@example.com')
+ public_email = create(:email, :confirmed, user: user, email: 'public2@example.com')
+ user.update!(public_email: public_email.email)
+ user
+ end
+
let!(:project1) { create(:project) }
let!(:project2) { create(:project) }
diff --git a/spec/features/atom/issues_spec.rb b/spec/features/atom/issues_spec.rb
index 13798a94fe9..913f5a7bcf3 100644
--- a/spec/features/atom/issues_spec.rb
+++ b/spec/features/atom/issues_spec.rb
@@ -4,61 +4,87 @@ require 'spec_helper'
RSpec.describe 'Issues Feed' do
describe 'GET /issues' do
- let!(:user) { create(:user, email: 'private1@example.com', public_email: 'public1@example.com') }
- let!(:assignee) { create(:user, email: 'private2@example.com', public_email: 'public2@example.com') }
- let!(:group) { create(:group) }
- let!(:project) { create(:project) }
- let!(:issue) { create(:issue, author: user, assignees: [assignee], project: project) }
+ let_it_be_with_reload(:user) do
+ user = create(:user, email: 'private1@example.com')
+ public_email = create(:email, :confirmed, user: user, email: 'public1@example.com')
+ user.update!(public_email: public_email.email)
+ user
+ end
+
+ let_it_be(:assignee) do
+ user = create(:user, email: 'private2@example.com')
+ public_email = create(:email, :confirmed, user: user, email: 'public2@example.com')
+ user.update!(public_email: public_email.email)
+ user
+ end
- before do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:issue) { create(:issue, author: user, assignees: [assignee], project: project, due_date: Date.today) }
+ let_it_be(:issuable) { issue } # "alias" for shared examples
+
+ before_all do
project.add_developer(user)
group.add_developer(user)
end
+ RSpec.shared_examples 'an authenticated issue atom feed' do
+ it 'renders atom feed with additional issue information' do
+ expect(body).to have_selector('title', text: "#{project.name} issues")
+ expect(body).to have_selector('due_date', text: issue.due_date)
+ end
+ end
+
context 'when authenticated' do
- it 'renders atom feed' do
+ before do
sign_in user
visit project_issues_path(project, :atom)
-
- expect(response_headers['Content-Type'])
- .to have_content('application/atom+xml')
- expect(body).to have_selector('title', text: "#{project.name} issues")
- expect(body).to have_selector('author email', text: issue.author_public_email)
- expect(body).to have_selector('assignees assignee email', text: issue.assignees.first.public_email)
- expect(body).to have_selector('assignee email', text: issue.assignees.first.public_email)
- expect(body).to have_selector('entry summary', text: issue.title)
end
+
+ it_behaves_like 'an authenticated issuable atom feed'
+ it_behaves_like 'an authenticated issue atom feed'
end
context 'when authenticated via personal access token' do
- it 'renders atom feed' do
+ before do
personal_access_token = create(:personal_access_token, user: user)
visit project_issues_path(project, :atom,
- private_token: personal_access_token.token)
-
- expect(response_headers['Content-Type'])
- .to have_content('application/atom+xml')
- expect(body).to have_selector('title', text: "#{project.name} issues")
- expect(body).to have_selector('author email', text: issue.author_public_email)
- expect(body).to have_selector('assignees assignee email', text: issue.assignees.first.public_email)
- expect(body).to have_selector('assignee email', text: issue.assignees.first.public_email)
- expect(body).to have_selector('entry summary', text: issue.title)
+ private_token: personal_access_token.token)
end
+
+ it_behaves_like 'an authenticated issuable atom feed'
+ it_behaves_like 'an authenticated issue atom feed'
end
context 'when authenticated via feed token' do
- it 'renders atom feed' do
+ before do
visit project_issues_path(project, :atom,
- feed_token: user.feed_token)
+ feed_token: user.feed_token)
+ end
- expect(response_headers['Content-Type'])
- .to have_content('application/atom+xml')
- expect(body).to have_selector('title', text: "#{project.name} issues")
- expect(body).to have_selector('author email', text: issue.author_public_email)
- expect(body).to have_selector('assignees assignee email', text: issue.assignees.first.public_email)
- expect(body).to have_selector('assignee email', text: issue.assignees.first.public_email)
- expect(body).to have_selector('entry summary', text: issue.title)
+ it_behaves_like 'an authenticated issuable atom feed'
+ it_behaves_like 'an authenticated issue atom feed'
+ end
+
+ context 'when not authenticated' do
+ before do
+ visit project_issues_path(project, :atom)
+ end
+
+ context 'and the project is private' do
+ it 'redirects to login page' do
+ expect(page).to have_current_path(new_user_session_path)
+ end
+ end
+
+ context 'and the project is public' do
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:issue) { create(:issue, author: user, assignees: [assignee], project: project, due_date: Date.today) }
+ let_it_be(:issuable) { issue } # "alias" for shared examples
+
+ it_behaves_like 'an authenticated issuable atom feed'
+ it_behaves_like 'an authenticated issue atom feed'
end
end
diff --git a/spec/features/atom/merge_requests_spec.rb b/spec/features/atom/merge_requests_spec.rb
new file mode 100644
index 00000000000..48db8fcbf1e
--- /dev/null
+++ b/spec/features/atom/merge_requests_spec.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Merge Requests Feed' do
+ describe 'GET /merge_requests' do
+ let_it_be_with_reload(:user) { create(:user, email: 'private1@example.com') }
+ let_it_be(:assignee) { create(:user, email: 'private2@example.com') }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:merge_request) { create(:merge_request, source_project: project, assignees: [assignee]) }
+ let_it_be(:issuable) { merge_request } # "alias" for shared examples
+
+ before_all do
+ project.add_developer(user)
+ group.add_developer(user)
+ end
+
+ RSpec.shared_examples 'an authenticated merge request atom feed' do
+ it 'renders atom feed with additional merge request information' do
+ expect(body).to have_selector('title', text: "#{project.name} merge requests")
+ end
+ end
+
+ context 'when authenticated' do
+ before do
+ sign_in user
+ visit project_merge_requests_path(project, :atom)
+ end
+
+ it_behaves_like 'an authenticated issuable atom feed'
+ it_behaves_like 'an authenticated merge request atom feed'
+
+ context 'but the use can not see the project' do
+ let_it_be(:other_project) { create(:project) }
+
+ it 'renders 404 page' do
+ visit project_issues_path(other_project, :atom)
+
+ expect(page).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ context 'when authenticated via personal access token' do
+ before do
+ personal_access_token = create(:personal_access_token, user: user)
+
+ visit project_merge_requests_path(project, :atom,
+ private_token: personal_access_token.token)
+ end
+
+ it_behaves_like 'an authenticated issuable atom feed'
+ it_behaves_like 'an authenticated merge request atom feed'
+ end
+
+ context 'when authenticated via feed token' do
+ before do
+ visit project_merge_requests_path(project, :atom,
+ feed_token: user.feed_token)
+ end
+
+ it_behaves_like 'an authenticated issuable atom feed'
+ it_behaves_like 'an authenticated merge request atom feed'
+ end
+
+ context 'when not authenticated' do
+ before do
+ visit project_merge_requests_path(project, :atom)
+ end
+
+ context 'and the project is private' do
+ it 'redirects to login page' do
+ expect(page).to have_current_path(new_user_session_path)
+ end
+ end
+
+ context 'and the project is public' do
+ let_it_be(:project) { create(:project, :public, :repository) }
+ let_it_be(:merge_request) { create(:merge_request, source_project: project, assignees: [assignee]) }
+ let_it_be(:issuable) { merge_request } # "alias" for shared examples
+
+ it_behaves_like 'an authenticated issuable atom feed'
+ it_behaves_like 'an authenticated merge request atom feed'
+ end
+ end
+ end
+end
diff --git a/spec/features/boards/multi_select_spec.rb b/spec/features/boards/multi_select_spec.rb
index 057464326fa..9148fb23214 100644
--- a/spec/features/boards/multi_select_spec.rb
+++ b/spec/features/boards/multi_select_spec.rb
@@ -43,12 +43,12 @@ RSpec.describe 'Multi Select Issue', :js do
# Multi select drag&drop support is temporarily disabled
# https://gitlab.com/gitlab-org/gitlab/-/issues/289797
- stub_feature_flags(graphql_board_lists: false, board_multi_select: project)
+ stub_feature_flags(board_multi_select: project)
sign_in(user)
end
- context 'with lists' do
+ xcontext 'with lists' do
let(:label1) { create(:label, project: project, name: 'Label 1', description: 'Test') }
let(:label2) { create(:label, project: project, name: 'Label 2', description: 'Test') }
let!(:list1) { create(:list, board: board, label: label1, position: 0) }
diff --git a/spec/features/boards/sidebar_labels_spec.rb b/spec/features/boards/sidebar_labels_spec.rb
index 2f0230c61d8..fa16f47f69a 100644
--- a/spec/features/boards/sidebar_labels_spec.rb
+++ b/spec/features/boards/sidebar_labels_spec.rb
@@ -5,8 +5,9 @@ require 'spec_helper'
RSpec.describe 'Project issue boards sidebar labels', :js do
include BoardHelpers
+ let_it_be(:group) { create(:group, :public) }
let_it_be(:user) { create(:user) }
- let_it_be(:project) { create(:project, :public) }
+ let_it_be(:project) { create(:project, :public, namespace: group) }
let_it_be(:development) { create(:label, project: project, name: 'Development') }
let_it_be(:bug) { create(:label, project: project, name: 'Bug') }
let_it_be(:regression) { create(:label, project: project, name: 'Regression') }
diff --git a/spec/features/boards/user_adds_lists_to_board_spec.rb b/spec/features/boards/user_adds_lists_to_board_spec.rb
index 5128fc4004e..26c310a6f56 100644
--- a/spec/features/boards/user_adds_lists_to_board_spec.rb
+++ b/spec/features/boards/user_adds_lists_to_board_spec.rb
@@ -3,8 +3,6 @@
require 'spec_helper'
RSpec.describe 'User adds lists', :js do
- using RSpec::Parameterized::TableSyntax
-
let_it_be(:group) { create(:group, :nested) }
let_it_be(:project) { create(:project, :public, namespace: group) }
let_it_be(:group_board) { create(:board, group: group) }
@@ -17,6 +15,8 @@ RSpec.describe 'User adds lists', :js do
let_it_be(:project_label) { create(:label, project: project) }
let_it_be(:group_backlog_list) { create(:backlog_list, board: group_board) }
let_it_be(:project_backlog_list) { create(:backlog_list, board: project_board) }
+ let_it_be(:backlog) { create(:group_label, group: group, name: 'Backlog') }
+ let_it_be(:closed) { create(:group_label, group: group, name: 'Closed') }
let_it_be(:issue) { create(:labeled_issue, project: project, labels: [group_label, project_label]) }
@@ -25,15 +25,8 @@ RSpec.describe 'User adds lists', :js do
group.add_owner(user)
end
- where(:board_type, :graphql_board_lists_enabled, :board_new_list_enabled) do
- :project | true | true
- :project | false | true
- :project | true | false
- :project | false | false
- :group | true | true
- :group | false | true
- :group | true | false
- :group | false | false
+ where(:board_type) do
+ [[:project], [:group]]
end
with_them do
@@ -42,11 +35,6 @@ RSpec.describe 'User adds lists', :js do
set_cookie('sidebar_collapsed', 'true')
- stub_feature_flags(
- graphql_board_lists: graphql_board_lists_enabled,
- board_new_list: board_new_list_enabled
- )
-
if board_type == :project
visit project_board_path(project, project_board)
elsif board_type == :group
@@ -56,40 +44,43 @@ RSpec.describe 'User adds lists', :js do
wait_for_all_requests
end
- it 'creates new column for label containing labeled issue' do
- click_button button_text(board_new_list_enabled)
+ it 'creates new column for label containing labeled issue', :aggregate_failures do
+ click_button 'Create list'
wait_for_all_requests
- select_label(board_new_list_enabled, group_label)
-
- wait_for_all_requests
+ select_label(group_label)
expect(page).to have_selector('.board', text: group_label.title)
expect(find('.board:nth-child(2) .board-card')).to have_content(issue.title)
end
- end
- def select_label(board_new_list_enabled, label)
- if board_new_list_enabled
- click_button 'Select a label'
+ it 'creates new list for Backlog and closed labels' do
+ click_button 'Create list'
+ wait_for_requests
- find('label', text: label.title).click
+ select_label(backlog)
- click_button 'Add to board'
+ click_button 'Create list'
+ wait_for_requests
- wait_for_all_requests
- else
- page.within('.dropdown-menu-issues-board-new') do
- click_link label.title
- end
+ select_label(closed)
+
+ wait_for_requests
+
+ expect(page).to have_selector('.board', text: closed.title)
+ expect(find('.board:nth-child(2) .board-header')).to have_content(backlog.title)
+ expect(find('.board:nth-child(3) .board-header')).to have_content(closed.title)
+ expect(find('.board:nth-child(4) .board-header')).to have_content('Closed')
end
end
- def button_text(board_new_list_enabled)
- if board_new_list_enabled
- 'Create list'
- else
- 'Add list'
- end
+ def select_label(label)
+ click_button 'Select a label'
+
+ find('label', text: label.title).click
+
+ click_button 'Add to board'
+
+ wait_for_all_requests
end
end
diff --git a/spec/features/clusters/cluster_health_dashboard_spec.rb b/spec/features/clusters/cluster_health_dashboard_spec.rb
index e4a36f654e5..88d6976c2be 100644
--- a/spec/features/clusters/cluster_health_dashboard_spec.rb
+++ b/spec/features/clusters/cluster_health_dashboard_spec.rb
@@ -80,8 +80,8 @@ RSpec.describe 'Cluster Health board', :js, :kubeclient, :use_clean_rails_memory
expect(page).to have_content('Avg')
end
- it 'focuses the single panel on toggle', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338341' do
- click_button('More actions')
+ it 'focuses the single panel on toggle' do
+ click_button('More actions', match: :first)
click_button('Expand panel')
expect(page).to have_css('.prometheus-graph', count: 1)
diff --git a/spec/features/commit_spec.rb b/spec/features/commit_spec.rb
index 80a30ab01b2..3fd613ce393 100644
--- a/spec/features/commit_spec.rb
+++ b/spec/features/commit_spec.rb
@@ -42,7 +42,7 @@ RSpec.describe 'Commit' do
visit project_commit_path(project, commit)
end
- it "shows an adjusted count for changed files on this page" do
+ it "shows an adjusted count for changed files on this page", :js do
expect(page).to have_content("Showing 1 changed file")
end
diff --git a/spec/features/cycle_analytics_spec.rb b/spec/features/cycle_analytics_spec.rb
index de6cb53fdfa..bec474f6cfe 100644
--- a/spec/features/cycle_analytics_spec.rb
+++ b/spec/features/cycle_analytics_spec.rb
@@ -5,35 +5,40 @@ require 'spec_helper'
RSpec.describe 'Value Stream Analytics', :js do
let_it_be(:user) { create(:user) }
let_it_be(:guest) { create(:user) }
- let_it_be(:project) { create(:project, :repository) }
let_it_be(:stage_table_selector) { '[data-testid="vsa-stage-table"]' }
+ let_it_be(:stage_table_event_selector) { '[data-testid="vsa-stage-event"]' }
let_it_be(:metrics_selector) { "[data-testid='vsa-time-metrics']" }
+ let_it_be(:metric_value_selector) { "[data-testid='displayValue']" }
+ let(:stage_table) { page.find(stage_table_selector) }
+ let(:project) { create(:project, :repository) }
let(:issue) { create(:issue, project: project, created_at: 2.days.ago) }
let(:milestone) { create(:milestone, project: project) }
let(:mr) { create_merge_request_closing_issue(user, project, issue, commit_message: "References #{issue.to_reference}") }
let(:pipeline) { create(:ci_empty_pipeline, status: 'created', project: project, ref: mr.source_branch, sha: mr.source_branch_sha, head_pipeline_of: mr) }
+ def metrics_values
+ page.find(metrics_selector).all(metric_value_selector).collect(&:text)
+ end
+
+ def set_daterange(from_date, to_date)
+ page.find(".js-daterange-picker-from input").set(from_date)
+ page.find(".js-daterange-picker-to input").set(to_date)
+ wait_for_all_requests
+ end
+
context 'as an allowed user' do
context 'when project is new' do
- before(:all) do
- project.add_maintainer(user)
- end
-
before do
+ project.add_maintainer(user)
sign_in(user)
visit project_cycle_analytics_path(project)
wait_for_requests
end
- it 'displays metrics' do
- aggregate_failures 'with relevant values' do
- expect(new_issues_counter).to have_content('-')
- expect(commits_counter).to have_content('-')
- expect(deploys_counter).to have_content('-')
- expect(deployment_frequency_counter).to have_content('-')
- end
+ it 'displays metrics with relevant values' do
+ expect(metrics_values).to eq(['-'] * 4)
end
it 'shows active stage with empty message' do
@@ -43,24 +48,37 @@ RSpec.describe 'Value Stream Analytics', :js do
end
context "when there's value stream analytics data" do
+ # NOTE: in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68595 travel back
+ # 5 days in time before we create data for these specs, to mitigate some flakiness
+ # So setting the date range to be the last 2 days should skip past the existing data
+ from = 2.days.ago.strftime("%Y-%m-%d")
+ to = 1.day.ago.strftime("%Y-%m-%d")
+
+ around do |example|
+ travel_to(5.days.ago) { example.run }
+ end
+
before do
project.add_maintainer(user)
+ create_list(:issue, 2, project: project, created_at: 2.weeks.ago, milestone: milestone)
- @build = create_cycle(user, project, issue, mr, milestone, pipeline)
+ create_cycle(user, project, issue, mr, milestone, pipeline)
deploy_master(user, project)
issue.metrics.update!(first_mentioned_in_commit_at: issue.metrics.first_associated_with_milestone_at + 1.hour)
merge_request = issue.merge_requests_closing_issues.first.merge_request
merge_request.update!(created_at: issue.metrics.first_associated_with_milestone_at + 1.hour)
merge_request.metrics.update!(
- latest_build_started_at: 4.hours.ago,
- latest_build_finished_at: 3.hours.ago,
- merged_at: merge_request.created_at + 1.hour,
- first_deployed_to_production_at: merge_request.created_at + 2.hours
+ latest_build_started_at: merge_request.created_at + 3.hours,
+ latest_build_finished_at: merge_request.created_at + 4.hours,
+ merged_at: merge_request.created_at + 4.hours,
+ first_deployed_to_production_at: merge_request.created_at + 5.hours
)
sign_in(user)
visit project_cycle_analytics_path(project)
+
+ wait_for_requests
end
it 'displays metrics' do
@@ -93,18 +111,20 @@ RSpec.describe 'Value Stream Analytics', :js do
expect_merge_request_to_be_present
end
- context "when I change the time period observed" do
- before do
- _two_weeks_old_issue = create(:issue, project: project, created_at: 2.weeks.ago)
+ it 'can filter the issues by date' do
+ expect(stage_table.all(stage_table_event_selector).length).to eq(3)
- click_button('Last 30 days')
- click_link('Last 7 days')
- wait_for_requests
- end
+ set_daterange(from, to)
- it 'shows only relevant data' do
- expect(new_issue_counter).to have_content('1')
- end
+ expect(stage_table.all(stage_table_event_selector).length).to eq(0)
+ end
+
+ it 'can filter the metrics by date' do
+ expect(metrics_values).to eq(["3.0", "2.0", "1.0", "0.0"])
+
+ set_daterange(from, to)
+
+ expect(metrics_values).to eq(['-'] * 4)
end
end
end
@@ -137,31 +157,6 @@ RSpec.describe 'Value Stream Analytics', :js do
end
end
- def find_metric_tile(sel)
- page.find("#{metrics_selector} #{sel}")
- end
-
- # When now use proper pluralization for the metric names, which affects the id
- def new_issue_counter
- find_metric_tile("#new-issue")
- end
-
- def new_issues_counter
- find_metric_tile("#new-issues")
- end
-
- def commits_counter
- find_metric_tile("#commits")
- end
-
- def deploys_counter
- find_metric_tile("#deploys")
- end
-
- def deployment_frequency_counter
- find_metric_tile("#deployment-frequency")
- end
-
def expect_issue_to_be_present
expect(find(stage_table_selector)).to have_content(issue.title)
expect(find(stage_table_selector)).to have_content(issue.author.name)
diff --git a/spec/features/global_search_spec.rb b/spec/features/global_search_spec.rb
index 19fb8e5f52c..a380edff3a4 100644
--- a/spec/features/global_search_spec.rb
+++ b/spec/features/global_search_spec.rb
@@ -11,40 +11,64 @@ RSpec.describe 'Global search' do
before do
project.add_maintainer(user)
sign_in(user)
-
- visit dashboard_projects_path
end
- it 'increases usage ping searches counter' do
- expect(Gitlab::UsageDataCounters::SearchCounter).to receive(:count).with(:navbar_searches)
- expect(Gitlab::UsageDataCounters::SearchCounter).to receive(:count).with(:all_searches)
+ describe 'when new_header_search feature is disabled' do
+ before do
+ # TODO: Remove this along with feature flag #339348
+ stub_feature_flags(new_header_search: false)
+ visit dashboard_projects_path
+ end
- submit_search('foobar')
- end
+ it 'increases usage ping searches counter' do
+ expect(Gitlab::UsageDataCounters::SearchCounter).to receive(:count).with(:navbar_searches)
+ expect(Gitlab::UsageDataCounters::SearchCounter).to receive(:count).with(:all_searches)
- describe 'I search through the issues and I see pagination' do
- before do
- allow_next(SearchService).to receive(:per_page).and_return(1)
- create_list(:issue, 2, project: project, title: 'initial')
+ submit_search('foobar')
end
- it "has a pagination" do
- submit_search('initial')
- select_search_scope('Issues')
+ describe 'I search through the issues and I see pagination' do
+ before do
+ allow_next(SearchService).to receive(:per_page).and_return(1)
+ create_list(:issue, 2, project: project, title: 'initial')
+ end
+
+ it "has a pagination" do
+ submit_search('initial')
+ select_search_scope('Issues')
- expect(page).to have_selector('.gl-pagination .next')
+ expect(page).to have_selector('.gl-pagination .next')
+ end
end
- end
- it 'closes the dropdown on blur', :js do
- find('#search').click
- fill_in 'search', with: "a"
+ it 'closes the dropdown on blur', :js do
+ find('#search').click
+ fill_in 'search', with: "a"
+
+ expect(page).to have_selector("div[data-testid='dashboard-search-options'].show")
- expect(page).to have_selector("div[data-testid='dashboard-search-options'].show")
+ find('#search').send_keys(:backspace)
+ find('body').click
- find('#search').send_keys(:backspace)
- find('body').click
+ expect(page).to have_no_selector("div[data-testid='dashboard-search-options'].show")
+ end
+
+ it 'renders legacy search bar' do
+ expect(page).to have_selector('.search-form')
+ expect(page).to have_no_selector('#js-header-search')
+ end
+ end
- expect(page).to have_no_selector("div[data-testid='dashboard-search-options'].show")
+ describe 'when new_header_search feature is enabled' do
+ before do
+ # TODO: Remove this along with feature flag #339348
+ stub_feature_flags(new_header_search: true)
+ visit dashboard_projects_path
+ end
+
+ it 'renders updated search bar' do
+ expect(page).to have_no_selector('.search-form')
+ expect(page).to have_selector('#js-header-search')
+ end
end
end
diff --git a/spec/features/groups/board_sidebar_spec.rb b/spec/features/groups/board_sidebar_spec.rb
index e2dd2fecab7..69a6788e438 100644
--- a/spec/features/groups/board_sidebar_spec.rb
+++ b/spec/features/groups/board_sidebar_spec.rb
@@ -42,30 +42,4 @@ RSpec.describe 'Group Issue Boards', :js do
end
end
end
-
- context 'when graphql_board_lists FF disabled' do
- before do
- stub_feature_flags(graphql_board_lists: false)
- sign_in(user)
-
- visit group_board_path(group, board)
- wait_for_requests
- end
-
- it 'only shows valid labels for the issue project and group' do
- click_card(card)
-
- page.within('.labels') do
- click_link 'Edit'
-
- wait_for_requests
-
- page.within('.selectbox') do
- expect(page).to have_content(project_1_label.title)
- expect(page).to have_content(group_label.title)
- expect(page).not_to have_content(project_2_label.title)
- end
- end
- end
- end
end
diff --git a/spec/features/groups/issues_spec.rb b/spec/features/groups/issues_spec.rb
index 21b39d2da46..489beb70ab3 100644
--- a/spec/features/groups/issues_spec.rb
+++ b/spec/features/groups/issues_spec.rb
@@ -33,7 +33,7 @@ RSpec.describe 'Group issues page' do
# However,`:js` option forces Capybara to use Selenium that doesn't support`:has`
context "it has an RSS button with current_user's feed token" do
it "shows the RSS button with current_user's feed token" do
- expect(find('[data-testid="rss-feed-link"]')['href']).to have_content(user.feed_token)
+ expect(page).to have_link 'Subscribe to RSS feed', href: /feed_token=#{user.feed_token}/
end
end
end
@@ -46,7 +46,7 @@ RSpec.describe 'Group issues page' do
# Note: please see the above
context "it has an RSS button without a feed token" do
it "shows the RSS button without a feed token" do
- expect(find('[data-testid="rss-feed-link"]')['href']).not_to have_content('feed_token')
+ expect(page).not_to have_link 'Subscribe to RSS feed', href: /feed_token/
end
end
end
@@ -94,6 +94,41 @@ RSpec.describe 'Group issues page' do
expect(page).not_to have_content issue.title[0..80]
end
end
+
+ context 'when cached issues state count is enabled', :clean_gitlab_redis_cache do
+ before do
+ stub_feature_flags(cached_issues_state_count: true)
+ end
+
+ it 'truncates issue counts if over the threshold' do
+ allow(Rails.cache).to receive(:read).and_call_original
+ allow(Rails.cache).to receive(:read).with(
+ ['group', group.id, 'issues'],
+ { expires_in: Gitlab::IssuablesCountForState::CACHE_EXPIRES_IN }
+ ).and_return({ opened: 1050, closed: 500, all: 1550 })
+
+ visit issues_group_path(group)
+
+ expect(page).to have_text('Open 1.1k Closed 500 All 1.6k')
+ end
+ end
+
+ context 'when cached issues state count is disabled', :clean_gitlab_redis_cache do
+ before do
+ stub_feature_flags(cached_issues_state_count: false)
+ end
+
+ it 'does not truncate counts if they are over the threshold' do
+ allow_next_instance_of(IssuesFinder) do |finder|
+ allow(finder).to receive(:count_by_state).and_return(true)
+ .and_return({ opened: 1050, closed: 500, all: 1550 })
+ end
+
+ visit issues_group_path(group)
+
+ expect(page).to have_text('Open 1,050 Closed 500 All 1,550')
+ end
+ end
end
context 'projects with issues disabled' do
diff --git a/spec/features/groups/members/request_access_spec.rb b/spec/features/groups/members/request_access_spec.rb
index 827962fee61..f806c7d3704 100644
--- a/spec/features/groups/members/request_access_spec.rb
+++ b/spec/features/groups/members/request_access_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe 'Groups > Members > Request access' do
it 'user can request access to a group' do
perform_enqueued_jobs { click_link 'Request Access' }
- expect(ActionMailer::Base.deliveries.last.to).to eq [owner.notification_email]
+ expect(ActionMailer::Base.deliveries.last.to).to eq [owner.notification_email_or_default]
expect(ActionMailer::Base.deliveries.last.subject).to match "Request to join the #{group.name} group"
expect(group.requesters.exists?(user_id: user)).to be_truthy
diff --git a/spec/features/groups/packages_spec.rb b/spec/features/groups/packages_spec.rb
index 9a7950266a5..3c2ade6b274 100644
--- a/spec/features/groups/packages_spec.rb
+++ b/spec/features/groups/packages_spec.rb
@@ -44,14 +44,6 @@ RSpec.describe 'Group Packages' do
it_behaves_like 'packages list', check_project_name: true
- context 'when package_details_apollo feature flag is off' do
- before do
- stub_feature_flags(package_details_apollo: false)
- end
-
- it_behaves_like 'package details link'
- end
-
it_behaves_like 'package details link'
it 'allows you to navigate to the project page' do
diff --git a/spec/features/groups/settings/packages_and_registries_spec.rb b/spec/features/groups/settings/packages_and_registries_spec.rb
index 835555480dd..d3141da9160 100644
--- a/spec/features/groups/settings/packages_and_registries_spec.rb
+++ b/spec/features/groups/settings/packages_and_registries_spec.rb
@@ -90,9 +90,10 @@ RSpec.describe 'Group Packages & Registries settings' do
expect(page).to have_content('Do not allow duplicates')
fill_in 'Exceptions', with: ')'
+
+ # simulate blur event
+ find('#maven-duplicated-settings-regex-input').native.send_keys(:tab)
end
- # simulate blur event
- find('body').click
expect(page).to have_content('is an invalid regexp')
end
diff --git a/spec/features/groups/settings/repository_spec.rb b/spec/features/groups/settings/repository_spec.rb
index 7082b2b20bd..d95eaf3c92c 100644
--- a/spec/features/groups/settings/repository_spec.rb
+++ b/spec/features/groups/settings/repository_spec.rb
@@ -18,11 +18,11 @@ RSpec.describe 'Group Repository settings' do
before do
stub_container_registry_config(enabled: true)
- visit group_settings_repository_path(group)
end
it_behaves_like 'a deploy token in settings' do
let(:entity_type) { 'group' }
+ let(:page_path) { group_settings_repository_path(group) }
end
end
diff --git a/spec/features/groups/show_spec.rb b/spec/features/groups/show_spec.rb
index 79226facad4..eb62b6fa8ee 100644
--- a/spec/features/groups/show_spec.rb
+++ b/spec/features/groups/show_spec.rb
@@ -3,25 +3,74 @@
require 'spec_helper'
RSpec.describe 'Group show page' do
- let(:group) { create(:group) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+
let(:path) { group_path(group) }
context 'when signed in' do
- let(:user) do
- create(:group_member, :developer, user: create(:user), group: group ).user
- end
+ context 'with non-admin group concerns' do
+ before do
+ group.add_developer(user)
+ sign_in(user)
+ visit path
+ end
- before do
- sign_in(user)
- visit path
+ it_behaves_like "an autodiscoverable RSS feed with current_user's feed token"
+
+ context 'when group does not exist' do
+ let(:path) { group_path('not-exist') }
+
+ it { expect(status_code).to eq(404) }
+ end
end
- it_behaves_like "an autodiscoverable RSS feed with current_user's feed token"
+ context 'when user is an owner' do
+ before do
+ group.add_owner(user)
+ sign_in(user)
+ end
+
+ it 'shows the invite banner and persists dismissal', :js do
+ visit path
+
+ expect(page).to have_content('Collaborate with your team')
- context 'when group does not exist' do
- let(:path) { group_path('not-exist') }
+ page.within(find('[data-testid="invite-members-banner"]')) do
+ find('[data-testid="close-icon"]').click
+ end
+
+ expect(page).not_to have_content('Collaborate with your team')
+
+ visit path
+
+ expect(page).not_to have_content('Collaborate with your team')
+ end
+
+ context 'when group has a project with emoji in description', :js do
+ let!(:project) { create(:project, description: ':smile:', namespace: group) }
+
+ it 'shows the project info', :aggregate_failures do
+ visit path
+
+ expect(page).to have_content(project.title)
+ expect(page).to have_emoji('smile')
+ end
+ end
- it { expect(status_code).to eq(404) }
+ context 'when group has projects' do
+ it 'allows users to sorts projects by most stars', :js do
+ project1 = create(:project, namespace: group, star_count: 2)
+ project2 = create(:project, namespace: group, star_count: 3)
+ project3 = create(:project, namespace: group, star_count: 0)
+
+ visit group_path(group, sort: :stars_desc)
+
+ expect(find('.group-row:nth-child(1) .namespace-title > a')).to have_content(project2.title)
+ expect(find('.group-row:nth-child(2) .namespace-title > a')).to have_content(project1.title)
+ expect(find('.group-row:nth-child(3) .namespace-title > a')).to have_content(project3.title)
+ end
+ end
end
end
@@ -37,7 +86,7 @@ RSpec.describe 'Group show page' do
context 'when group has a public project', :js do
let!(:project) { create(:project, :public, namespace: group) }
- it 'renders public project' do
+ it 'renders public project', :aggregate_failures do
visit path
expect(page).to have_link group.name
@@ -48,7 +97,7 @@ RSpec.describe 'Group show page' do
context 'when group has a private project', :js do
let!(:project) { create(:project, :private, namespace: group) }
- it 'does not render private project' do
+ it 'does not render private project', :aggregate_failures do
visit path
expect(page).to have_link group.name
@@ -58,28 +107,19 @@ RSpec.describe 'Group show page' do
end
context 'subgroup support' do
- let(:restricted_group) do
+ let_it_be(:restricted_group) do
create(:group, subgroup_creation_level: ::Gitlab::Access::OWNER_SUBGROUP_ACCESS)
end
- let(:relaxed_group) do
- create(:group, subgroup_creation_level: ::Gitlab::Access::MAINTAINER_SUBGROUP_ACCESS)
- end
-
- let(:owner) { create(:user) }
- let(:maintainer) { create(:user) }
-
context 'for owners' do
- let(:path) { group_path(restricted_group) }
-
before do
- restricted_group.add_owner(owner)
- sign_in(owner)
+ restricted_group.add_owner(user)
+ sign_in(user)
end
context 'when subgroups are supported' do
it 'allows creating subgroups' do
- visit path
+ visit group_path(restricted_group)
expect(page).to have_link('New subgroup')
end
@@ -88,18 +128,21 @@ RSpec.describe 'Group show page' do
context 'for maintainers' do
before do
- sign_in(maintainer)
+ sign_in(user)
end
context 'when subgroups are supported' do
context 'when subgroup_creation_level is set to maintainers' do
+ let(:relaxed_group) do
+ create(:group, subgroup_creation_level: ::Gitlab::Access::MAINTAINER_SUBGROUP_ACCESS)
+ end
+
before do
- relaxed_group.add_maintainer(maintainer)
+ relaxed_group.add_maintainer(user)
end
it 'allows creating subgroups' do
- path = group_path(relaxed_group)
- visit path
+ visit group_path(relaxed_group)
expect(page).to have_link('New subgroup')
end
@@ -107,12 +150,11 @@ RSpec.describe 'Group show page' do
context 'when subgroup_creation_level is set to owners' do
before do
- restricted_group.add_maintainer(maintainer)
+ restricted_group.add_maintainer(user)
end
it 'does not allow creating subgroups' do
- path = group_path(restricted_group)
- visit path
+ visit group_path(restricted_group)
expect(page).not_to have_link('New subgroup')
end
@@ -121,50 +163,10 @@ RSpec.describe 'Group show page' do
end
end
- context 'group has a project with emoji in description', :js do
- let(:user) { create(:user) }
- let!(:project) { create(:project, description: ':smile:', namespace: group) }
-
- before do
- group.add_owner(user)
- sign_in(user)
- visit path
- end
-
- it 'shows the project info' do
- expect(page).to have_content(project.title)
- expect(page).to have_emoji('smile')
- end
- end
-
- context 'where group has projects' do
- let(:user) { create(:user) }
-
- before do
- group.add_owner(user)
- sign_in(user)
- end
-
- it 'allows users to sorts projects by most stars', :js do
- project1 = create(:project, namespace: group, star_count: 2)
- project2 = create(:project, namespace: group, star_count: 3)
- project3 = create(:project, namespace: group, star_count: 0)
-
- visit group_path(group, sort: :stars_desc)
-
- expect(find('.group-row:nth-child(1) .namespace-title > a')).to have_content(project2.title)
- expect(find('.group-row:nth-child(2) .namespace-title > a')).to have_content(project1.title)
- expect(find('.group-row:nth-child(3) .namespace-title > a')).to have_content(project3.title)
- end
- end
-
context 'notification button', :js do
- let(:maintainer) { create(:user) }
- let!(:project) { create(:project, namespace: group) }
-
before do
- group.add_maintainer(maintainer)
- sign_in(maintainer)
+ group.add_maintainer(user)
+ sign_in(user)
end
it 'is enabled by default' do
@@ -174,7 +176,8 @@ RSpec.describe 'Group show page' do
end
it 'is disabled if emails are disabled' do
- group.update_attribute(:emails_disabled, true)
+ group.update!(emails_disabled: true)
+
visit path
expect(page).to have_selector('[data-testid="notification-dropdown"] .disabled')
@@ -182,12 +185,10 @@ RSpec.describe 'Group show page' do
end
context 'page og:description' do
- let(:group) { create(:group, description: '**Lorem** _ipsum_ dolor sit [amet](https://example.com)') }
- let(:maintainer) { create(:user) }
-
before do
- group.add_maintainer(maintainer)
- sign_in(maintainer)
+ group.update!(description: '**Lorem** _ipsum_ dolor sit [amet](https://example.com)')
+ group.add_maintainer(user)
+ sign_in(user)
visit path
end
@@ -237,7 +238,7 @@ RSpec.describe 'Group show page' do
end
end
- it 'does not include structured markup in shared projects tab', :js do
+ it 'does not include structured markup in shared projects tab', :aggregate_failures, :js do
other_project = create(:project, :public)
other_project.project_group_links.create!(group: group)
@@ -248,7 +249,7 @@ RSpec.describe 'Group show page' do
expect(page).not_to have_selector('[itemprop="owns"][itemtype="https://schema.org/SoftwareSourceCode"]')
end
- it 'does not include structured markup in archived projects tab', :js do
+ it 'does not include structured markup in archived projects tab', :aggregate_failures, :js do
project.update!(archived: true)
visit group_archived_path(group)
diff --git a/spec/features/ics/dashboard_issues_spec.rb b/spec/features/ics/dashboard_issues_spec.rb
index 4a93a4b490a..1d0ea495757 100644
--- a/spec/features/ics/dashboard_issues_spec.rb
+++ b/spec/features/ics/dashboard_issues_spec.rb
@@ -4,8 +4,20 @@ require 'spec_helper'
RSpec.describe 'Dashboard Issues Calendar Feed' do
describe 'GET /issues' do
- let!(:user) { create(:user, email: 'private1@example.com', public_email: 'public1@example.com') }
- let!(:assignee) { create(:user, email: 'private2@example.com', public_email: 'public2@example.com') }
+ let!(:user) do
+ user = create(:user, email: 'private1@example.com')
+ public_email = create(:email, :confirmed, user: user, email: 'public1@example.com')
+ user.update!(public_email: public_email.email)
+ user
+ end
+
+ let!(:assignee) do
+ user = create(:user, email: 'private2@example.com')
+ public_email = create(:email, :confirmed, user: user, email: 'public2@example.com')
+ user.update!(public_email: public_email.email)
+ user
+ end
+
let!(:project) { create(:project) }
let(:milestone) { create(:milestone, project_id: project.id, title: 'v1.0') }
diff --git a/spec/features/ics/group_issues_spec.rb b/spec/features/ics/group_issues_spec.rb
index 05caca4b5a8..f29c39ad4ef 100644
--- a/spec/features/ics/group_issues_spec.rb
+++ b/spec/features/ics/group_issues_spec.rb
@@ -4,8 +4,20 @@ require 'spec_helper'
RSpec.describe 'Group Issues Calendar Feed' do
describe 'GET /issues' do
- let!(:user) { create(:user, email: 'private1@example.com', public_email: 'public1@example.com') }
- let!(:assignee) { create(:user, email: 'private2@example.com', public_email: 'public2@example.com') }
+ let!(:user) do
+ user = create(:user, email: 'private1@example.com')
+ public_email = create(:email, :confirmed, user: user, email: 'public1@example.com')
+ user.update!(public_email: public_email.email)
+ user
+ end
+
+ let!(:assignee) do
+ user = create(:user, email: 'private2@example.com')
+ public_email = create(:email, :confirmed, user: user, email: 'public2@example.com')
+ user.update!(public_email: public_email.email)
+ user
+ end
+
let!(:group) { create(:group) }
let!(:project) { create(:project, group: group) }
diff --git a/spec/features/ics/project_issues_spec.rb b/spec/features/ics/project_issues_spec.rb
index 58a1a32eac2..771748060bb 100644
--- a/spec/features/ics/project_issues_spec.rb
+++ b/spec/features/ics/project_issues_spec.rb
@@ -4,8 +4,20 @@ require 'spec_helper'
RSpec.describe 'Project Issues Calendar Feed' do
describe 'GET /issues' do
- let!(:user) { create(:user, email: 'private1@example.com', public_email: 'public1@example.com') }
- let!(:assignee) { create(:user, email: 'private2@example.com', public_email: 'public2@example.com') }
+ let!(:user) do
+ user = create(:user, email: 'private1@example.com')
+ public_email = create(:email, :confirmed, user: user, email: 'public1@example.com')
+ user.update!(public_email: public_email.email)
+ user
+ end
+
+ let!(:assignee) do
+ user = create(:user, email: 'private2@example.com')
+ public_email = create(:email, :confirmed, user: user, email: 'public2@example.com')
+ user.update!(public_email: public_email.email)
+ user
+ end
+
let!(:project) { create(:project) }
let!(:issue) { create(:issue, author: user, assignees: [assignee], project: project) }
diff --git a/spec/features/incidents/user_views_incident_spec.rb b/spec/features/incidents/user_views_incident_spec.rb
index b94ce3cd06f..244b66f7a9a 100644
--- a/spec/features/incidents/user_views_incident_spec.rb
+++ b/spec/features/incidents/user_views_incident_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe "User views incident" do
it 'shows the merge request and incident actions', :js, :aggregate_failures do
click_button 'Incident actions'
- expect(page).to have_link('New incident', href: new_project_issue_path(project, { issuable_template: 'incident', issue: { issue_type: 'incident' } }))
+ expect(page).to have_link('New incident', href: new_project_issue_path(project, { issuable_template: 'incident', issue: { issue_type: 'incident', description: "Related to \##{incident.iid}.\n\n" } }))
expect(page).to have_button('Create merge request')
expect(page).to have_button('Close incident')
end
diff --git a/spec/features/invites_spec.rb b/spec/features/invites_spec.rb
index d56bedd4852..87fb8955dcc 100644
--- a/spec/features/invites_spec.rb
+++ b/spec/features/invites_spec.rb
@@ -189,6 +189,16 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
end
context 'email confirmation enabled' do
+ context 'when user is not valid in sign up form' do
+ let(:new_user) { build_stubbed(:user, first_name: '', last_name: '') }
+
+ it 'fails sign up and redirects back to sign up', :aggregate_failures do
+ expect { fill_in_sign_up_form(new_user) }.not_to change { User.count }
+ expect(page).to have_content('prohibited this user from being saved')
+ expect(current_path).to eq(user_registration_path)
+ end
+ end
+
context 'with invite email acceptance', :snowplow do
it 'tracks the accepted invite' do
fill_in_sign_up_form(new_user)
@@ -216,6 +226,20 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
end
end
+ context 'with invite email acceptance for the invite_email_from experiment', :experiment do
+ let(:extra_params) do
+ { invite_type: Emails::Members::INITIAL_INVITE, experiment_name: 'invite_email_from' }
+ end
+
+ it 'tracks the accepted invite' do
+ expect(experiment(:invite_email_from)).to track(:accepted)
+ .with_context(actor: group_invite)
+ .on_next_instance
+
+ fill_in_sign_up_form(new_user)
+ end
+ end
+
it 'signs up and redirects to the group activity page with all the project/groups invitation automatically accepted' do
fill_in_sign_up_form(new_user)
fill_in_welcome_form
diff --git a/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb b/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb
index 077c363f78b..507d427bf0b 100644
--- a/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb
+++ b/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb
@@ -27,7 +27,7 @@ RSpec.describe 'Resolving all open threads in a merge request from an issue', :j
it 'shows a button to resolve all threads by creating a new issue' do
within('.line-resolve-all-container') do
- expect(page).to have_selector resolve_all_discussions_link_selector( title: "Resolve all threads in new issue" )
+ expect(page).to have_selector resolve_all_discussions_link_selector( title: "Create issue to resolve all threads" )
end
end
@@ -38,7 +38,7 @@ RSpec.describe 'Resolving all open threads in a merge request from an issue', :j
it 'hides the link for creating a new issue' do
expect(page).not_to have_selector resolve_all_discussions_link_selector
- expect(page).not_to have_content "Resolve all threads in new issue"
+ expect(page).not_to have_content "Create issue to resolve all threads"
end
end
@@ -62,7 +62,7 @@ RSpec.describe 'Resolving all open threads in a merge request from an issue', :j
end
it 'does not show a link to create a new issue' do
- expect(page).not_to have_link 'Resolve all threads in new issue'
+ expect(page).not_to have_link 'Create issue to resolve all threads'
end
end
@@ -77,14 +77,14 @@ RSpec.describe 'Resolving all open threads in a merge request from an issue', :j
it 'has a link to resolve all threads by creating an issue' do
page.within '.mr-widget-body' do
- expect(page).to have_link 'Resolve all threads in new issue', href: new_project_issue_path(project, merge_request_to_resolve_discussions_of: merge_request.iid)
+ expect(page).to have_link 'Create issue to resolve all threads', href: new_project_issue_path(project, merge_request_to_resolve_discussions_of: merge_request.iid)
end
end
context 'creating an issue for threads' do
before do
page.within '.mr-widget-body' do
- page.click_link 'Resolve all threads in new issue', href: new_project_issue_path(project, merge_request_to_resolve_discussions_of: merge_request.iid)
+ page.click_link 'Create issue to resolve all threads', href: new_project_issue_path(project, merge_request_to_resolve_discussions_of: merge_request.iid)
wait_for_all_requests
end
diff --git a/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb b/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb
index 3ff8fc5ecca..0de15d3d304 100644
--- a/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb
+++ b/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe 'Resolve an open thread in a merge request by creating an issue',
let!(:discussion) { create(:diff_note_on_merge_request, noteable: merge_request, project: project).to_discussion }
def resolve_discussion_selector
- title = 'Resolve this thread in a new issue'
+ title = 'Create issue to resolve thread'
url = new_project_issue_path(project, discussion_to_resolve: discussion.id, merge_request_to_resolve_discussions_of: merge_request.iid)
"a[title=\"#{title}\"][href=\"#{url}\"]"
end
diff --git a/spec/features/issues/csv_spec.rb b/spec/features/issues/csv_spec.rb
index 51e0d54ca5e..b4c737495b4 100644
--- a/spec/features/issues/csv_spec.rb
+++ b/spec/features/issues/csv_spec.rb
@@ -44,7 +44,7 @@ RSpec.describe 'Issues csv', :js do
request_csv
expect(page).to have_content 'CSV export has started'
- expect(page).to have_content "emailed to #{user.notification_email}"
+ expect(page).to have_content "emailed to #{user.notification_email_or_default}"
end
it 'includes a csv attachment', :sidekiq_might_not_need_inline do
diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb
index 88a7b890daa..edf3df7c16e 100644
--- a/spec/features/issues/filtered_search/filter_issues_spec.rb
+++ b/spec/features/issues/filtered_search/filter_issues_spec.rb
@@ -565,21 +565,18 @@ RSpec.describe 'Filter issues', :js do
end
it 'maintains filter' do
- # Closed
- find('.issues-state-filters [data-state="closed"]').click
+ click_link 'Closed'
wait_for_requests
expect(page).to have_selector('.issues-list .issue', count: 1)
expect(page).to have_link(closed_issue.title)
- # Opened
- find('.issues-state-filters [data-state="opened"]').click
+ click_link 'Open'
wait_for_requests
expect(page).to have_selector('.issues-list .issue', count: 4)
- # All
- find('.issues-state-filters [data-state="all"]').click
+ click_link 'All'
wait_for_requests
expect(page).to have_selector('.issues-list .issue', count: 5)
diff --git a/spec/features/issues/filtered_search/search_bar_spec.rb b/spec/features/issues/filtered_search/search_bar_spec.rb
index 1efcc329e32..60963d95ae5 100644
--- a/spec/features/issues/filtered_search/search_bar_spec.rb
+++ b/spec/features/issues/filtered_search/search_bar_spec.rb
@@ -89,7 +89,7 @@ RSpec.describe 'Search bar', :js do
expect(find('#js-dropdown-hint')).to have_selector('.filter-dropdown .filter-dropdown-item', count: original_size)
end
- it 'resets the dropdown filters', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/9985' do
+ it 'resets the dropdown filters' do
filtered_search.click
hint_offset = get_left_style(find('#js-dropdown-hint')['style'])
@@ -103,7 +103,7 @@ RSpec.describe 'Search bar', :js do
find('.filtered-search-box .clear-search').click
filtered_search.click
- expect(find('#js-dropdown-hint')).to have_selector('.filter-dropdown .filter-dropdown-item', count: 6)
+ expect(find('#js-dropdown-hint')).to have_selector('.filter-dropdown .filter-dropdown-item', minimum: 6)
expect(get_left_style(find('#js-dropdown-hint')['style'])).to eq(hint_offset)
end
end
diff --git a/spec/features/issues/filtered_search/visual_tokens_spec.rb b/spec/features/issues/filtered_search/visual_tokens_spec.rb
index 644d7cc4611..2d8587d886f 100644
--- a/spec/features/issues/filtered_search/visual_tokens_spec.rb
+++ b/spec/features/issues/filtered_search/visual_tokens_spec.rb
@@ -16,9 +16,6 @@ RSpec.describe 'Visual tokens', :js do
let(:filtered_search) { find('.filtered-search') }
let(:filter_author_dropdown) { find("#js-dropdown-author .filter-dropdown") }
- let(:filter_assignee_dropdown) { find("#js-dropdown-assignee .filter-dropdown") }
- let(:filter_milestone_dropdown) { find("#js-dropdown-milestone .filter-dropdown") }
- let(:filter_label_dropdown) { find("#js-dropdown-label .filter-dropdown") }
def is_input_focused
page.evaluate_script("document.activeElement.classList.contains('filtered-search')")
diff --git a/spec/features/issues/issue_detail_spec.rb b/spec/features/issues/issue_detail_spec.rb
index a942a1a44f6..531c3634b5e 100644
--- a/spec/features/issues/issue_detail_spec.rb
+++ b/spec/features/issues/issue_detail_spec.rb
@@ -32,6 +32,21 @@ RSpec.describe 'Issue Detail', :js do
end
end
+ context 'when issue description has emojis' do
+ let(:issue) { create(:issue, project: project, author: user, description: 'hello world :100:') }
+
+ before do
+ sign_in(user)
+ visit project_issue_path(project, issue)
+ end
+
+ it 'renders gl-emoji tag' do
+ page.within('.description') do
+ expect(page).to have_selector('gl-emoji', count: 1)
+ end
+ end
+ end
+
context 'when issue description has xss snippet' do
before do
issue.update!(description: '![xss" onload=alert(1);//](a)')
diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb
index e198d9d4ebb..bd4be755a92 100644
--- a/spec/features/issues/issue_sidebar_spec.rb
+++ b/spec/features/issues/issue_sidebar_spec.rb
@@ -117,7 +117,7 @@ RSpec.describe 'Issue Sidebar' do
page.within '.dropdown-menu-user' do
expect(page).to have_link('Invite members')
- expect(page).to have_selector('[data-track-event="click_invite_members"]')
+ expect(page).to have_selector('[data-track-action="click_invite_members"]')
expect(page).to have_selector('[data-track-label="edit_assignee"]')
end
diff --git a/spec/features/issues/resource_label_events_spec.rb b/spec/features/issues/resource_label_events_spec.rb
index 33edf2f0b63..e08410efc0b 100644
--- a/spec/features/issues/resource_label_events_spec.rb
+++ b/spec/features/issues/resource_label_events_spec.rb
@@ -38,7 +38,7 @@ RSpec.describe 'List issue resource label events', :js do
click_on 'Edit'
wait_for_requests
- labels.each { |label| click_link label }
+ labels.each { |label| click_on label }
send_keys(:escape)
wait_for_requests
diff --git a/spec/features/issues/rss_spec.rb b/spec/features/issues/rss_spec.rb
index 6c4498ea711..b20502ecc25 100644
--- a/spec/features/issues/rss_spec.rb
+++ b/spec/features/issues/rss_spec.rb
@@ -3,21 +3,24 @@
require 'spec_helper'
RSpec.describe 'Project Issues RSS' do
- let!(:user) { create(:user) }
- let(:group) { create(:group) }
- let(:project) { create(:project, group: group, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
- let(:path) { project_issues_path(project) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, group: group, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
+ let_it_be(:path) { project_issues_path(project) }
+ let_it_be(:issue) { create(:issue, project: project, assignees: [user]) }
- before do
- create(:issue, project: project, assignees: [user])
+ before_all do
group.add_developer(user)
end
context 'when signed in' do
- let(:user) { create(:user) }
+ let_it_be(:user) { create(:user) }
- before do
+ before_all do
project.add_developer(user)
+ end
+
+ before do
sign_in(user)
visit path
end
@@ -36,26 +39,6 @@ RSpec.describe 'Project Issues RSS' do
end
describe 'feeds' do
- shared_examples 'updates atom feed link' do |type|
- it "for #{type}" do
- sign_in(user)
- visit path
-
- link = find_link('Subscribe to RSS feed')
- params = CGI.parse(URI.parse(link[:href]).query)
- auto_discovery_link = find('link[type="application/atom+xml"]', visible: false)
- auto_discovery_params = CGI.parse(URI.parse(auto_discovery_link[:href]).query)
-
- expected = {
- 'feed_token' => [user.feed_token],
- 'assignee_id' => [user.id.to_s]
- }
-
- expect(params).to include(expected)
- expect(auto_discovery_params).to include(expected)
- end
- end
-
it_behaves_like 'updates atom feed link', :project do
let(:path) { project_issues_path(project, assignee_id: user.id) }
end
diff --git a/spec/features/issues/user_edits_issue_spec.rb b/spec/features/issues/user_edits_issue_spec.rb
index e4bba706453..63c36a20adc 100644
--- a/spec/features/issues/user_edits_issue_spec.rb
+++ b/spec/features/issues/user_edits_issue_spec.rb
@@ -15,6 +15,7 @@ RSpec.describe "Issues > User edits issue", :js do
context 'with authorized user' do
before do
+ stub_feature_flags(labels_widget: false)
project.add_developer(user)
project_with_milestones.add_developer(user)
sign_in(user)
diff --git a/spec/features/issues/user_views_issue_spec.rb b/spec/features/issues/user_views_issue_spec.rb
index 8792d76981f..31bf7649470 100644
--- a/spec/features/issues/user_views_issue_spec.rb
+++ b/spec/features/issues/user_views_issue_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe "User views issue" do
it 'shows the merge request and issue actions', :js, :aggregate_failures do
click_button 'Issue actions'
- expect(page).to have_link('New issue', href: new_project_issue_path(project))
+ expect(page).to have_link('New issue', href: new_project_issue_path(project, { issue: { description: "Related to \##{issue.iid}.\n\n" } }))
expect(page).to have_button('Create merge request')
expect(page).to have_button('Close issue')
end
diff --git a/spec/features/issues/user_views_issues_spec.rb b/spec/features/issues/user_views_issues_spec.rb
index 165f4b10cff..56afa7eb6ba 100644
--- a/spec/features/issues/user_views_issues_spec.rb
+++ b/spec/features/issues/user_views_issues_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe "User views issues" do
.and have_content(open_issue2.title)
.and have_no_content(closed_issue.title)
.and have_content(moved_open_issue.title)
- .and have_no_selector(".js-new-board-list")
+ .and have_no_content('Create list')
end
it "opens issues by label" do
@@ -65,7 +65,7 @@ RSpec.describe "User views issues" do
.and have_no_content(open_issue1.title)
.and have_no_content(open_issue2.title)
.and have_no_content(moved_open_issue.title)
- .and have_no_selector(".js-new-board-list")
+ .and have_no_content('Create list')
end
include_examples "opens issue from list" do
@@ -87,7 +87,7 @@ RSpec.describe "User views issues" do
.and have_content(open_issue2.title)
.and have_content(moved_open_issue.title)
.and have_no_content('CLOSED (MOVED)')
- .and have_no_selector(".js-new-board-list")
+ .and have_no_content('Create list')
end
include_examples "opens issue from list" do
diff --git a/spec/features/labels_hierarchy_spec.rb b/spec/features/labels_hierarchy_spec.rb
index fca5e946d0c..25c315f2d16 100644
--- a/spec/features/labels_hierarchy_spec.rb
+++ b/spec/features/labels_hierarchy_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe 'Labels Hierarchy', :js do
let!(:project_label_1) { create(:label, project: project_1, title: 'Label_4') }
before do
- stub_feature_flags(board_new_list: false)
+ stub_feature_flags(labels_widget: false)
grandparent.add_owner(user)
sign_in(user)
@@ -215,44 +215,6 @@ RSpec.describe 'Labels Hierarchy', :js do
end
end
- context 'issuable sidebar when graphql_board_lists FF disabled' do
- let!(:issue) { create(:issue, project: project_1) }
-
- before do
- stub_feature_flags(graphql_board_lists: false)
- end
-
- context 'on project board issue sidebar' do
- before do
- project_1.add_developer(user)
- board = create(:board, project: project_1)
-
- visit project_board_path(project_1, board)
-
- wait_for_requests
-
- find('.board-card').click
- end
-
- it_behaves_like 'assigning labels from sidebar'
- end
-
- context 'on group board issue sidebar' do
- before do
- parent.add_developer(user)
- board = create(:board, group: parent)
-
- visit group_board_path(parent, board)
-
- wait_for_requests
-
- find('.board-card').click
- end
-
- it_behaves_like 'assigning labels from sidebar'
- end
- end
-
context 'issuable filtering' do
let!(:labeled_issue) { create(:labeled_issue, project: project_1, labels: [grandparent_group_label, parent_group_label, project_label_1]) }
let!(:issue) { create(:issue, project: project_1) }
@@ -307,88 +269,4 @@ RSpec.describe 'Labels Hierarchy', :js do
it_behaves_like 'filtering by ancestor labels for groups', true
end
end
-
- context 'creating boards lists' do
- before do
- stub_feature_flags(board_new_list: false)
- end
-
- context 'on project boards' do
- let(:board) { create(:board, project: project_1) }
-
- before do
- project_1.add_developer(user)
- visit project_board_path(project_1, board)
- find('.js-new-board-list').click
- wait_for_requests
- end
-
- it 'creates lists from all ancestor labels' do
- [grandparent_group_label, parent_group_label, project_label_1].each do |label|
- find('a', text: label.title).click
- end
-
- wait_for_requests
-
- expect(page).to have_selector('.board-title-text', text: grandparent_group_label.title)
- expect(page).to have_selector('.board-title-text', text: parent_group_label.title)
- expect(page).to have_selector('.board-title-text', text: project_label_1.title)
- end
- end
-
- context 'on group boards' do
- let(:board) { create(:board, group: parent) }
-
- before do
- parent.add_developer(user)
- visit group_board_path(parent, board)
- find('.js-new-board-list').click
- wait_for_requests
- end
-
- context 'when graphql_board_lists FF enabled' do
- it 'creates lists from all ancestor group labels' do
- [grandparent_group_label, parent_group_label].each do |label|
- find('a', text: label.title).click
- end
-
- wait_for_requests
-
- expect(page).to have_selector('.board-title-text', text: grandparent_group_label.title)
- expect(page).to have_selector('.board-title-text', text: parent_group_label.title)
- end
-
- it 'does not create lists from descendant groups' do
- expect(page).not_to have_selector('a', text: child_group_label.title)
- end
- end
- end
-
- context 'when graphql_board_lists FF disabled' do
- let(:board) { create(:board, group: parent) }
-
- before do
- stub_feature_flags(graphql_board_lists: false)
- parent.add_developer(user)
- visit group_board_path(parent, board)
- find('.js-new-board-list').click
- wait_for_requests
- end
-
- it 'creates lists from all ancestor group labels' do
- [grandparent_group_label, parent_group_label].each do |label|
- find('a', text: label.title).click
- end
-
- wait_for_requests
-
- expect(page).to have_selector('.board-title-text', text: grandparent_group_label.title)
- expect(page).to have_selector('.board-title-text', text: parent_group_label.title)
- end
-
- it 'does not create lists from descendant groups' do
- expect(page).not_to have_selector('a', text: child_group_label.title)
- end
- end
- end
end
diff --git a/spec/features/merge_request/batch_comments_spec.rb b/spec/features/merge_request/batch_comments_spec.rb
index c646698219b..f695b225915 100644
--- a/spec/features/merge_request/batch_comments_spec.rb
+++ b/spec/features/merge_request/batch_comments_spec.rb
@@ -25,10 +25,6 @@ RSpec.describe 'Merge request > Batch comments', :js do
visit_diffs
end
- it 'has review bar' do
- expect(page).to have_selector('[data-testid="review_bar_component"]', visible: false)
- end
-
it 'adds draft note' do
write_diff_comment
diff --git a/spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb b/spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb
index 45ee914de9d..caf0c609f64 100644
--- a/spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb
+++ b/spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb
@@ -26,7 +26,7 @@ RSpec.describe 'Merge request > User edits reviewers sidebar', :js do
page.within '.dropdown-menu-user' do
expect(page).to have_link('Invite Members')
- expect(page).to have_selector('[data-track-event="click_invite_members"]')
+ expect(page).to have_selector('[data-track-action="click_invite_members"]')
expect(page).to have_selector('[data-track-label="edit_reviewer"]')
end
diff --git a/spec/features/merge_requests/rss_spec.rb b/spec/features/merge_requests/rss_spec.rb
new file mode 100644
index 00000000000..9fc3d3d6ae1
--- /dev/null
+++ b/spec/features/merge_requests/rss_spec.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Project Merge Requests RSS' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, :repository, group: group, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
+ let_it_be(:merge_request) { create(:merge_request, source_project: project, assignees: [user]) }
+ let_it_be(:path) { project_merge_requests_path(project) }
+
+ before_all do
+ group.add_developer(user)
+ end
+
+ context 'when signed in' do
+ let_it_be(:user) { create(:user) }
+
+ before_all do
+ project.add_developer(user)
+ end
+
+ before do
+ sign_in(user)
+ visit path
+ end
+
+ it_behaves_like "it has an RSS button with current_user's feed token"
+ it_behaves_like "an autodiscoverable RSS feed with current_user's feed token"
+ end
+
+ context 'when signed out' do
+ before do
+ visit path
+ end
+
+ it_behaves_like "it has an RSS button without a feed token"
+ it_behaves_like "an autodiscoverable RSS feed without a feed token"
+ end
+
+ describe 'feeds' do
+ it_behaves_like 'updates atom feed link', :project do
+ let(:path) { project_merge_requests_path(project, assignee_id: user.id) }
+ end
+ end
+end
diff --git a/spec/features/merge_requests/user_sees_empty_state_spec.rb b/spec/features/merge_requests/user_sees_empty_state_spec.rb
index ac07b31731d..056da53c47b 100644
--- a/spec/features/merge_requests/user_sees_empty_state_spec.rb
+++ b/spec/features/merge_requests/user_sees_empty_state_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'Merge request > User sees empty state' do
+ include ProjectForksHelper
+
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
@@ -37,4 +39,23 @@ RSpec.describe 'Merge request > User sees empty state' do
expect(page).to have_content('To widen your search, change or remove filters above')
end
end
+
+ context 'as member of a fork' do
+ let(:fork_user) { create(:user) }
+ let(:forked_project) { fork_project(project, fork_user, namespace: fork_user.namespace, repository: true) }
+
+ before do
+ forked_project.add_maintainer(fork_user)
+ sign_in(fork_user)
+ end
+
+ it 'shows an empty state and a "New merge request" button' do
+ visit project_merge_requests_path(project, search: 'foo')
+
+ expect(page).to have_selector('.empty-state')
+ within('.empty-state') do
+ expect(page).to have_link 'New merge request', href: project_new_merge_request_path(forked_project)
+ end
+ end
+ end
end
diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb
index de511e99182..8025db9f86d 100644
--- a/spec/features/profiles/personal_access_tokens_spec.rb
+++ b/spec/features/profiles/personal_access_tokens_spec.rb
@@ -56,7 +56,7 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
click_on "Create personal access token"
expect(active_personal_access_tokens).to have_text(name)
- expect(active_personal_access_tokens).to have_text('In')
+ expect(active_personal_access_tokens).to have_text('in')
expect(active_personal_access_tokens).to have_text('api')
expect(active_personal_access_tokens).to have_text('read_user')
expect(created_personal_access_token).not_to be_empty
@@ -85,6 +85,18 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
expect(active_personal_access_tokens).to have_text(personal_access_token.name)
expect(active_personal_access_tokens).not_to have_text(impersonation_token.name)
end
+
+ context 'when User#time_display_relative is false' do
+ before do
+ user.update!(time_display_relative: false)
+ end
+
+ it 'shows absolute times for expires_at' do
+ visit profile_personal_access_tokens_path
+
+ expect(active_personal_access_tokens).to have_text(PersonalAccessToken.last.expires_at.strftime('%b %d'))
+ end
+ end
end
describe "inactive tokens" do
diff --git a/spec/features/profiles/user_edit_profile_spec.rb b/spec/features/profiles/user_edit_profile_spec.rb
index d941988d12f..af085b63155 100644
--- a/spec/features/profiles/user_edit_profile_spec.rb
+++ b/spec/features/profiles/user_edit_profile_spec.rb
@@ -32,7 +32,7 @@ RSpec.describe 'User edit profile' do
fill_in 'user_skype', with: 'testskype'
fill_in 'user_linkedin', with: 'testlinkedin'
fill_in 'user_twitter', with: 'testtwitter'
- fill_in 'user_website_url', with: 'testurl'
+ fill_in 'user_website_url', with: 'http://testurl.com'
fill_in 'user_location', with: 'Ukraine'
fill_in 'user_bio', with: 'I <3 GitLab :tada:'
fill_in 'user_job_title', with: 'Frontend Engineer'
@@ -43,9 +43,8 @@ RSpec.describe 'User edit profile' do
skype: 'testskype',
linkedin: 'testlinkedin',
twitter: 'testtwitter',
- website_url: 'testurl',
+ website_url: 'http://testurl.com',
bio: 'I <3 GitLab :tada:',
- bio_html: '<p data-sourcepos="1:1-1:18" dir="auto">I &lt;3 GitLab <gl-emoji title="party popper" data-name="tada" data-unicode-version="6.0">🎉</gl-emoji></p>',
job_title: 'Frontend Engineer',
organization: 'GitLab'
)
@@ -54,6 +53,19 @@ RSpec.describe 'User edit profile' do
expect(page).to have_content('Profile was successfully updated')
end
+ it 'does not set secondary emails without user input' do
+ fill_in 'user_organization', with: 'GitLab'
+ submit_settings
+
+ user.reload
+ expect(page).to have_field('user_commit_email', with: '')
+ expect(page).to have_field('user_public_email', with: '')
+
+ User::SECONDARY_EMAIL_ATTRIBUTES.each do |attribute|
+ expect(user.read_attribute(attribute)).to be_blank
+ end
+ end
+
it 'shows an error if the full name contains an emoji', :js do
simulate_input('#user_name', 'Martin 😀')
submit_settings
@@ -65,6 +77,17 @@ RSpec.describe 'User edit profile' do
end
end
+ it 'shows an error if the website url is not valid' do
+ fill_in 'user_website_url', with: 'admin@gitlab.com'
+ submit_settings
+
+ expect(user.reload).to have_attributes(
+ website_url: ''
+ )
+
+ expect(page).to have_content('Website url is not a valid URL')
+ end
+
describe 'when I change my email' do
before do
user.send_reset_password_instructions
diff --git a/spec/features/projects/ci/editor_spec.rb b/spec/features/projects/ci/editor_spec.rb
index 192bccd6f6e..7fe1c63f490 100644
--- a/spec/features/projects/ci/editor_spec.rb
+++ b/spec/features/projects/ci/editor_spec.rb
@@ -27,10 +27,6 @@ RSpec.describe 'Pipeline Editor', :js do
end
context 'branch switcher' do
- before do
- stub_feature_flags(pipeline_editor_branch_switcher: true)
- end
-
def switch_to_branch(branch)
find('[data-testid="branch-selector"]').click
diff --git a/spec/features/projects/commits/user_browses_commits_spec.rb b/spec/features/projects/commits/user_browses_commits_spec.rb
index 76162fb800a..863fdbdadaa 100644
--- a/spec/features/projects/commits/user_browses_commits_spec.rb
+++ b/spec/features/projects/commits/user_browses_commits_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe 'User browses commits' do
sign_in(user)
end
- it 'renders commit' do
+ it 'renders commit', :js do
visit project_commit_path(project, sample_commit.id)
expect(page).to have_content(sample_commit.message.gsub(/\s+/, ' '))
@@ -103,7 +103,7 @@ RSpec.describe 'User browses commits' do
context 'when the blob does not exist' do
let(:commit) { create(:commit, project: project) }
- it 'renders successfully' do
+ it 'renders successfully', :js do
allow_next_instance_of(Gitlab::Diff::File) do |instance|
allow(instance).to receive(:blob).and_return(nil)
end
@@ -113,7 +113,9 @@ RSpec.describe 'User browses commits' do
visit(project_commit_path(project, commit))
- expect(find('.diff-file-changes', visible: false)).to have_content('files/ruby/popen.rb')
+ click_button '2 changed files'
+
+ expect(find('[data-testid="diff-stats-dropdown"]')).to have_content('files/ruby/popen.rb')
end
end
diff --git a/spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb b/spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb
index f6330491886..71c9d89fbde 100644
--- a/spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb
+++ b/spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb
@@ -66,20 +66,4 @@ RSpec.describe 'User updates feature flag', :js do
end
end
end
-
- context 'with a legacy feature flag' do
- let!(:feature_flag) do
- create_flag(project, 'ci_live_trace', true,
- description: 'For live trace feature',
- version: :legacy_flag)
- end
-
- let!(:scope) { create_scope(feature_flag, 'review/*', true) }
-
- it 'shows not found error' do
- visit(edit_project_feature_flag_path(project, feature_flag))
-
- expect(page).to have_text 'Page Not Found'
- end
- end
end
diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb
index 302187917b7..00e85a215b8 100644
--- a/spec/features/projects/import_export/import_file_spec.rb
+++ b/spec/features/projects/import_export/import_file_spec.rb
@@ -10,6 +10,7 @@ RSpec.describe 'Import/Export - project import integration test', :js do
let(:export_path) { "#{Dir.tmpdir}/import_file_spec" }
before do
+ stub_feature_flags(paginatable_namespace_drop_down_for_project_creation: false)
stub_uploads_object_storage(FileUploader)
allow_next_instance_of(Gitlab::ImportExport) do |instance|
allow(instance).to receive(:storage_path).and_return(export_path)
diff --git a/spec/features/projects/jobs/permissions_spec.rb b/spec/features/projects/jobs/permissions_spec.rb
index 140d5dee270..a904ba770dd 100644
--- a/spec/features/projects/jobs/permissions_spec.rb
+++ b/spec/features/projects/jobs/permissions_spec.rb
@@ -90,7 +90,7 @@ RSpec.describe 'Project Jobs Permissions' do
it_behaves_like 'recent job page details responds with status', 200 do
it 'renders job details', :js do
- expect(page).to have_content "Job ##{job.id}"
+ expect(page).to have_content "Job #{job.name}"
expect(page).to have_css '.log-line'
end
end
diff --git a/spec/features/projects/jobs/user_browses_job_spec.rb b/spec/features/projects/jobs/user_browses_job_spec.rb
index 9b199157d79..060b7ffbfc9 100644
--- a/spec/features/projects/jobs/user_browses_job_spec.rb
+++ b/spec/features/projects/jobs/user_browses_job_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe 'User browses a job', :js do
it 'erases the job log', :js do
wait_for_requests
- expect(page).to have_content("Job ##{build.id}")
+ expect(page).to have_content("Job #{build.name}")
expect(page).to have_css('.job-log')
# scroll to the top of the page first
diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb
index 94543290050..113ba692497 100644
--- a/spec/features/projects/members/user_requests_access_spec.rb
+++ b/spec/features/projects/members/user_requests_access_spec.rb
@@ -23,7 +23,7 @@ RSpec.describe 'Projects > Members > User requests access', :js do
it 'user can request access to a project' do
perform_enqueued_jobs { click_link 'Request Access' }
- expect(ActionMailer::Base.deliveries.last.to).to eq [maintainer.notification_email]
+ expect(ActionMailer::Base.deliveries.last.to).to eq [maintainer.notification_email_or_default]
expect(ActionMailer::Base.deliveries.last.subject).to eq "Request to join the #{project.full_name} project"
expect(project.requesters.exists?(user_id: user)).to be_truthy
diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb
index 0b293970703..39f9d3b331b 100644
--- a/spec/features/projects/new_project_spec.rb
+++ b/spec/features/projects/new_project_spec.rb
@@ -6,6 +6,10 @@ RSpec.describe 'New project', :js do
include Select2Helper
include Spec::Support::Helpers::Features::TopNavSpecHelpers
+ before do
+ stub_feature_flags(paginatable_namespace_drop_down_for_project_creation: false)
+ end
+
context 'as a user' do
let(:user) { create(:user) }
diff --git a/spec/features/projects/package_files_spec.rb b/spec/features/projects/package_files_spec.rb
index c5c03396d71..6dc0294bb9e 100644
--- a/spec/features/projects/package_files_spec.rb
+++ b/spec/features/projects/package_files_spec.rb
@@ -23,20 +23,6 @@ RSpec.describe 'PackageFiles' do
expect(status_code).to eq(200)
end
- context 'when package_details_apollo feature flag is off' do
- before do
- stub_feature_flags(package_details_apollo: false)
- end
-
- it 'renders the download link with the correct url', :js do
- visit project_package_path(project, package)
-
- download_url = download_project_package_file_path(project, package_file)
-
- expect(page).to have_link(package_file.file_name, href: download_url)
- end
- end
-
it 'does not allow download of package belonging to different project' do
another_package = create(:maven_package)
another_file = another_package.package_files.first
diff --git a/spec/features/projects/packages_spec.rb b/spec/features/projects/packages_spec.rb
index 30298f79312..7fcc8200b1c 100644
--- a/spec/features/projects/packages_spec.rb
+++ b/spec/features/projects/packages_spec.rb
@@ -37,14 +37,6 @@ RSpec.describe 'Packages' do
it_behaves_like 'packages list'
- context 'when package_details_apollo feature flag is off' do
- before do
- stub_feature_flags(package_details_apollo: false)
- end
-
- it_behaves_like 'package details link'
- end
-
it_behaves_like 'package details link'
context 'deleting a package' do
diff --git a/spec/features/projects/services/user_activates_slack_slash_command_spec.rb b/spec/features/projects/services/user_activates_slack_slash_command_spec.rb
index 4dfd4416eeb..bc84ccaa432 100644
--- a/spec/features/projects/services/user_activates_slack_slash_command_spec.rb
+++ b/spec/features/projects/services/user_activates_slack_slash_command_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe 'Slack slash commands', :js do
end
it 'shows a help message' do
- expect(page).to have_content('This service allows users to perform common')
+ expect(page).to have_content('Perform common operations in this project')
end
it 'redirects to the integrations page after saving but not activating' do
@@ -42,6 +42,6 @@ RSpec.describe 'Slack slash commands', :js do
end
it 'shows help content' do
- expect(page).to have_content('This service allows users to perform common operations on this project by entering slash commands in Slack.')
+ expect(page).to have_content('Perform common operations in this project by entering slash commands in Slack.')
end
end
diff --git a/spec/features/projects/settings/access_tokens_spec.rb b/spec/features/projects/settings/access_tokens_spec.rb
index 33e2623522e..deeab084c5f 100644
--- a/spec/features/projects/settings/access_tokens_spec.rb
+++ b/spec/features/projects/settings/access_tokens_spec.rb
@@ -65,7 +65,7 @@ RSpec.describe 'Project > Settings > Access Tokens', :js do
click_on 'Create project access token'
expect(active_project_access_tokens).to have_text(name)
- expect(active_project_access_tokens).to have_text('In')
+ expect(active_project_access_tokens).to have_text('in')
expect(active_project_access_tokens).to have_text('api')
expect(active_project_access_tokens).to have_text('read_api')
expect(active_project_access_tokens).to have_text('Maintainer')
@@ -156,6 +156,18 @@ RSpec.describe 'Project > Settings > Access Tokens', :js do
expect(active_project_access_tokens).to have_text(project_access_token.name)
end
+
+ context 'when User#time_display_relative is false' do
+ before do
+ user.update!(time_display_relative: false)
+ end
+
+ it 'shows absolute times for expires_at' do
+ visit project_settings_access_tokens_path(project)
+
+ expect(active_project_access_tokens).to have_text(PersonalAccessToken.last.expires_at.strftime('%b %d'))
+ end
+ end
end
describe 'inactive tokens' do
diff --git a/spec/features/projects/settings/monitor_settings_spec.rb b/spec/features/projects/settings/monitor_settings_spec.rb
index 2d8c418b7d0..e3d75c30e5e 100644
--- a/spec/features/projects/settings/monitor_settings_spec.rb
+++ b/spec/features/projects/settings/monitor_settings_spec.rb
@@ -150,6 +150,33 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do
assert_text('Connection failed. Check Auth Token and try again.')
end
end
+
+ context 'integrated error tracking backend' do
+ it 'successfully fills and submits the form' do
+ visit project_settings_operations_path(project)
+
+ wait_for_requests
+
+ within '.js-error-tracking-settings' do
+ click_button('Expand')
+ end
+
+ expect(page).to have_content('Error tracking backend')
+
+ within '.js-error-tracking-settings' do
+ check('Active')
+ choose('GitLab')
+ end
+
+ expect(page).not_to have_content('Sentry API URL')
+
+ click_button('Save changes')
+
+ wait_for_requests
+
+ assert_text('Your changes have been saved')
+ end
+ end
end
context 'grafana integration settings form' do
diff --git a/spec/features/projects/settings/repository_settings_spec.rb b/spec/features/projects/settings/repository_settings_spec.rb
index f420a8a76b9..4e1b55d3d70 100644
--- a/spec/features/projects/settings/repository_settings_spec.rb
+++ b/spec/features/projects/settings/repository_settings_spec.rb
@@ -31,11 +31,11 @@ RSpec.describe 'Projects > Settings > Repository settings' do
before do
stub_container_registry_config(enabled: true)
stub_feature_flags(ajax_new_deploy_token: project)
- visit project_settings_repository_path(project)
end
it_behaves_like 'a deploy token in settings' do
let(:entity_type) { 'project' }
+ let(:page_path) { project_settings_repository_path(project) }
end
end
diff --git a/spec/features/projects/settings/service_desk_setting_spec.rb b/spec/features/projects/settings/service_desk_setting_spec.rb
index 91355d8f625..0924f8320e1 100644
--- a/spec/features/projects/settings/service_desk_setting_spec.rb
+++ b/spec/features/projects/settings/service_desk_setting_spec.rb
@@ -38,7 +38,6 @@ RSpec.describe 'Service Desk Setting', :js, :clean_gitlab_redis_cache do
expect(project.service_desk_enabled).to be_truthy
expect(project.service_desk_address).to be_present
expect(find('[data-testid="incoming-email"]').value).to eq(project.service_desk_incoming_address)
- expect(page).not_to have_selector('#service-desk-project-suffix')
end
end
diff --git a/spec/features/projects/settings/user_manages_project_members_spec.rb b/spec/features/projects/settings/user_manages_project_members_spec.rb
index be4b6d6b82d..02a634a0fcc 100644
--- a/spec/features/projects/settings/user_manages_project_members_spec.rb
+++ b/spec/features/projects/settings/user_manages_project_members_spec.rb
@@ -43,10 +43,15 @@ RSpec.describe 'Projects > Settings > User manages project members' do
visit(project_project_members_path(project))
- click_link('Import a project')
+ click_on 'Import from a project'
+ click_on 'Select a project'
+ wait_for_requests
- select2(project2.id, from: '#source_project_id')
- click_button('Import project members')
+ click_button project2.name
+ click_button 'Import project members'
+ wait_for_requests
+
+ page.refresh
expect(find_member_row(user_mike)).to have_content('Reporter')
end
diff --git a/spec/features/projects/user_creates_project_spec.rb b/spec/features/projects/user_creates_project_spec.rb
index 2dc2f168896..9f08759603e 100644
--- a/spec/features/projects/user_creates_project_spec.rb
+++ b/spec/features/projects/user_creates_project_spec.rb
@@ -6,6 +6,7 @@ RSpec.describe 'User creates a project', :js do
let(:user) { create(:user) }
before do
+ stub_feature_flags(paginatable_namespace_drop_down_for_project_creation: false)
sign_in(user)
create(:personal_key, user: user)
end
diff --git a/spec/features/registrations/experience_level_spec.rb b/spec/features/registrations/experience_level_spec.rb
deleted file mode 100644
index f432215d4a8..00000000000
--- a/spec/features/registrations/experience_level_spec.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'Experience level screen' do
- let_it_be(:user) { create(:user, :unconfirmed) }
- let_it_be(:group) { create(:group) }
-
- before do
- group.add_owner(user)
- gitlab_sign_in(user)
- visit users_sign_up_experience_level_path(namespace_path: group.to_param)
- end
-
- subject { page }
-
- it 'shows the intro content' do
- is_expected.to have_content('Hello there')
- is_expected.to have_content('Welcome to the guided GitLab tour')
- is_expected.to have_content('What describes you best?')
- end
-
- it 'shows the option for novice' do
- is_expected.to have_content('Novice')
- is_expected.to have_content('I’m not familiar with the basics of DevOps')
- is_expected.to have_content('Show me the basics')
- end
-
- it 'shows the option for experienced' do
- is_expected.to have_content('Experienced')
- is_expected.to have_content('I’m familiar with the basics of DevOps')
- is_expected.to have_content('Show me advanced features')
- end
-
- it 'does not display any flash messages' do
- is_expected.not_to have_selector('.flash-container')
- is_expected.not_to have_content("Please check your email (#{user.email}) to verify that you own this address and unlock the power of CI/CD")
- end
-
- it 'does not include the footer links' do
- is_expected.not_to have_link('Help')
- is_expected.not_to have_link('About GitLab')
- end
-end
diff --git a/spec/features/users/anonymous_sessions_spec.rb b/spec/features/users/anonymous_sessions_spec.rb
index 273d3aa346f..6b21412ae3d 100644
--- a/spec/features/users/anonymous_sessions_spec.rb
+++ b/spec/features/users/anonymous_sessions_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'Session TTLs', :clean_gitlab_redis_shared_state do
+ include SessionHelpers
+
it 'creates a session with a short TTL when login fails' do
visit new_user_session_path
# The session key only gets created after a post
@@ -12,7 +14,7 @@ RSpec.describe 'Session TTLs', :clean_gitlab_redis_shared_state do
expect(page).to have_content('Invalid login or password')
- expect_single_session_with_expiration(Settings.gitlab['unauthenticated_session_expire_delay'])
+ expect_single_session_with_short_ttl
end
it 'increases the TTL when the login succeeds' do
@@ -21,21 +23,17 @@ RSpec.describe 'Session TTLs', :clean_gitlab_redis_shared_state do
expect(page).to have_content(user.name)
- expect_single_session_with_expiration(Settings.gitlab['session_expire_delay'] * 60)
+ expect_single_session_with_authenticated_ttl
end
- def expect_single_session_with_expiration(expiration)
- session_keys = get_session_keys
-
- expect(session_keys.size).to eq(1)
- expect(get_ttl(session_keys.first)).to eq expiration
- end
+ context 'with an unauthorized project' do
+ let_it_be(:project) { create(:project, :repository) }
- def get_session_keys
- Gitlab::Redis::SharedState.with { |redis| redis.scan_each(match: 'session:gitlab:*').to_a }
- end
+ it 'creates a session with a short TTL' do
+ visit project_raw_path(project, 'master/README.md')
- def get_ttl(key)
- Gitlab::Redis::SharedState.with { |redis| redis.ttl(key) }
+ expect_single_session_with_short_ttl
+ expect(page).to have_current_path(new_user_session_path)
+ end
end
end
diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb
index 6c38d5d8b24..afd750d02eb 100644
--- a/spec/features/users/login_spec.rb
+++ b/spec/features/users/login_spec.rb
@@ -2,9 +2,10 @@
require 'spec_helper'
-RSpec.describe 'Login' do
+RSpec.describe 'Login', :clean_gitlab_redis_shared_state do
include TermsHelper
include UserLoginHelper
+ include SessionHelpers
before do
stub_authentication_activity_metrics(debug: true)
@@ -59,6 +60,7 @@ RSpec.describe 'Login' do
fill_in 'user_password', with: 'password'
click_button 'Sign in'
+ expect_single_session_with_authenticated_ttl
expect(current_path).to eq root_path
end
@@ -192,6 +194,7 @@ RSpec.describe 'Login' do
enter_code(user.current_otp)
expect(page).not_to have_content(I18n.t('devise.failure.already_authenticated'))
+ expect_single_session_with_authenticated_ttl
end
it 'does not allow sign-in if the user password is updated before entering a one-time code' do
@@ -210,6 +213,7 @@ RSpec.describe 'Login' do
enter_code(user.current_otp)
+ expect_single_session_with_authenticated_ttl
expect(current_path).to eq root_path
end
@@ -237,6 +241,8 @@ RSpec.describe 'Login' do
expect(page).to have_content('Invalid two-factor code')
enter_code(user.current_otp)
+
+ expect_single_session_with_authenticated_ttl
expect(current_path).to eq root_path
end
@@ -353,6 +359,7 @@ RSpec.describe 'Login' do
sign_in_using_saml!
+ expect_single_session_with_authenticated_ttl
expect(page).not_to have_content('Two-Factor Authentication')
expect(current_path).to eq root_path
end
@@ -371,6 +378,7 @@ RSpec.describe 'Login' do
enter_code(user.current_otp)
+ expect_single_session_with_authenticated_ttl
expect(current_path).to eq root_path
end
end
@@ -391,6 +399,7 @@ RSpec.describe 'Login' do
gitlab_sign_in(user)
+ expect_single_session_with_authenticated_ttl
expect(current_path).to eq root_path
expect(page).not_to have_content(I18n.t('devise.failure.already_authenticated'))
end
@@ -402,6 +411,7 @@ RSpec.describe 'Login' do
gitlab_sign_in(user)
visit new_user_session_path
+ expect_single_session_with_authenticated_ttl
expect(page).not_to have_content(I18n.t('devise.failure.already_authenticated'))
end
@@ -443,6 +453,7 @@ RSpec.describe 'Login' do
gitlab_sign_in(user)
+ expect_single_session_with_short_ttl
expect(page).to have_content('Invalid login or password.')
end
end
diff --git a/spec/features/users/show_spec.rb b/spec/features/users/show_spec.rb
index fb2873f1c96..e629d329033 100644
--- a/spec/features/users/show_spec.rb
+++ b/spec/features/users/show_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe 'User page' do
include ExternalAuthorizationServiceHelpers
- let_it_be(:user) { create(:user, bio: '**Lorem** _ipsum_ dolor sit [amet](https://example.com)') }
+ let_it_be(:user) { create(:user, bio: '<b>Lorem</b> <i>ipsum</i> dolor sit <a href="https://example.com">amet</a>') }
subject(:visit_profile) { visit(user_path(user)) }
@@ -186,7 +186,17 @@ RSpec.describe 'User page' do
end
context 'with blocked profile' do
- let_it_be(:user) { create(:user, state: :blocked) }
+ let_it_be(:user) do
+ create(
+ :user,
+ state: :blocked,
+ organization: 'GitLab - work info test',
+ job_title: 'Frontend Engineer',
+ pronunciation: 'pruh-nuhn-see-ay-shn'
+ )
+ end
+
+ let_it_be(:status) { create(:user_status, user: user, message: "Working hard!") }
it 'shows no tab' do
subject
@@ -211,7 +221,10 @@ RSpec.describe 'User page' do
subject
expect(page).not_to have_css(".profile-user-bio")
- expect(page).not_to have_css(".profile-link-holder")
+ expect(page).not_to have_content('GitLab - work info test')
+ expect(page).not_to have_content('Frontend Engineer')
+ expect(page).not_to have_content('Working hard!')
+ expect(page).not_to have_content("Pronounced as: pruh-nuhn-see-ay-shn")
end
it 'shows username' do
@@ -222,7 +235,17 @@ RSpec.describe 'User page' do
end
context 'with unconfirmed user' do
- let_it_be(:user) { create(:user, :unconfirmed) }
+ let_it_be(:user) do
+ create(
+ :user,
+ :unconfirmed,
+ organization: 'GitLab - work info test',
+ job_title: 'Frontend Engineer',
+ pronunciation: 'pruh-nuhn-see-ay-shn'
+ )
+ end
+
+ let_it_be(:status) { create(:user_status, user: user, message: "Working hard!") }
shared_examples 'unconfirmed user profile' do
before do
@@ -240,7 +263,10 @@ RSpec.describe 'User page' do
it 'shows no additional fields' do
expect(page).not_to have_css(".profile-user-bio")
- expect(page).not_to have_css(".profile-link-holder")
+ expect(page).not_to have_content('GitLab - work info test')
+ expect(page).not_to have_content('Frontend Engineer')
+ expect(page).not_to have_content('Working hard!')
+ expect(page).not_to have_content("Pronounced as: pruh-nuhn-see-ay-shn")
end
it 'shows private profile message' do
@@ -403,4 +429,27 @@ RSpec.describe 'User page' do
end
end
end
+
+ context 'GPG keys' do
+ context 'when user has verified GPG keys' do
+ let_it_be(:user) { create(:user, email: GpgHelpers::User1.emails.first) }
+ let_it_be(:gpg_key) { create(:gpg_key, user: user, key: GpgHelpers::User1.public_key) }
+ let_it_be(:gpg_key2) { create(:gpg_key, user: user, key: GpgHelpers::User1.public_key2) }
+
+ it 'shows link to public GPG keys' do
+ subject
+
+ expect(page).to have_link('View public GPG keys', href: user_gpg_keys_path(user))
+ end
+ end
+
+ context 'when user does not have verified GPG keys' do
+ it 'does not show link to public GPG keys' do
+ subject
+
+ expect(page).not_to have_link('View public GPG key', href: user_gpg_keys_path(user))
+ expect(page).not_to have_link('View public GPG keys', href: user_gpg_keys_path(user))
+ end
+ end
+ end
end
diff --git a/spec/finders/branches_finder_spec.rb b/spec/finders/branches_finder_spec.rb
index a62dd3842db..f9d525c33a4 100644
--- a/spec/finders/branches_finder_spec.rb
+++ b/spec/finders/branches_finder_spec.rb
@@ -259,4 +259,11 @@ RSpec.describe BranchesFinder do
end
end
end
+
+ describe '#total' do
+ subject { branch_finder.total }
+
+ it { is_expected.to be_an(Integer) }
+ it { is_expected.to eq(repository.branch_count) }
+ end
end
diff --git a/spec/finders/ci/pipelines_finder_spec.rb b/spec/finders/ci/pipelines_finder_spec.rb
index c7bd52576e8..908210e0296 100644
--- a/spec/finders/ci/pipelines_finder_spec.rb
+++ b/spec/finders/ci/pipelines_finder_spec.rb
@@ -113,27 +113,6 @@ RSpec.describe Ci::PipelinesFinder do
end
end
- context 'when name is specified' do
- let(:user) { create(:user) }
- let!(:pipeline) { create(:ci_pipeline, project: project, user: user) }
-
- context 'when name exists' do
- let(:params) { { name: user.name } }
-
- it 'returns matched pipelines' do
- is_expected.to eq([pipeline])
- end
- end
-
- context 'when name does not exist' do
- let(:params) { { name: 'invalid-name' } }
-
- it 'returns empty' do
- is_expected.to be_empty
- end
- end
- end
-
context 'when username is specified' do
let(:user) { create(:user) }
let!(:pipeline) { create(:ci_pipeline, project: project, user: user) }
@@ -258,20 +237,8 @@ RSpec.describe Ci::PipelinesFinder do
let!(:push_pipeline) { create(:ci_pipeline, project: project, source: 'push') }
let!(:api_pipeline) { create(:ci_pipeline, project: project, source: 'api') }
- context 'when `pipeline_source_filter` feature flag is disabled' do
- before do
- stub_feature_flags(pipeline_source_filter: false)
- end
-
- it 'returns all the pipelines' do
- is_expected.to contain_exactly(web_pipeline, push_pipeline, api_pipeline)
- end
- end
-
- context 'when `pipeline_source_filter` feature flag is enabled' do
- it 'returns only the matched pipeline' do
- is_expected.to eq([web_pipeline])
- end
+ it 'returns only the matched pipeline' do
+ is_expected.to eq([web_pipeline])
end
end
diff --git a/spec/finders/ci/runners_finder_spec.rb b/spec/finders/ci/runners_finder_spec.rb
index 599b4ffb804..10d3f641e02 100644
--- a/spec/finders/ci/runners_finder_spec.rb
+++ b/spec/finders/ci/runners_finder_spec.rb
@@ -18,6 +18,13 @@ RSpec.describe Ci::RunnersFinder do
end
end
+ context 'with nil group' do
+ it 'returns all runners' do
+ expect(Ci::Runner).to receive(:with_tags).and_call_original
+ expect(described_class.new(current_user: admin, params: { group: nil }).execute).to match_array [runner1, runner2]
+ end
+ end
+
context 'with preload param set to :tag_name true' do
it 'requests tags' do
expect(Ci::Runner).to receive(:with_tags).and_call_original
@@ -158,6 +165,7 @@ RSpec.describe Ci::RunnersFinder do
let_it_be(:project_4) { create(:project, group: sub_group_2) }
let_it_be(:project_5) { create(:project, group: sub_group_3) }
let_it_be(:project_6) { create(:project, group: sub_group_4) }
+ let_it_be(:runner_instance) { create(:ci_runner, :instance, contacted_at: 13.minutes.ago) }
let_it_be(:runner_group) { create(:ci_runner, :group, contacted_at: 12.minutes.ago) }
let_it_be(:runner_sub_group_1) { create(:ci_runner, :group, active: false, contacted_at: 11.minutes.ago) }
let_it_be(:runner_sub_group_2) { create(:ci_runner, :group, contacted_at: 10.minutes.ago) }
@@ -171,7 +179,10 @@ RSpec.describe Ci::RunnersFinder do
let_it_be(:runner_project_6) { create(:ci_runner, :project, contacted_at: 2.minutes.ago, projects: [project_5])}
let_it_be(:runner_project_7) { create(:ci_runner, :project, contacted_at: 1.minute.ago, projects: [project_6])}
- let(:params) { {} }
+ let(:target_group) { nil }
+ let(:membership) { nil }
+ let(:extra_params) { {} }
+ let(:params) { { group: target_group, membership: membership }.merge(extra_params).reject { |_, v| v.nil? } }
before do
group.runners << runner_group
@@ -182,65 +193,104 @@ RSpec.describe Ci::RunnersFinder do
end
describe '#execute' do
- subject { described_class.new(current_user: user, group: group, params: params).execute }
+ subject { described_class.new(current_user: user, params: params).execute }
+
+ shared_examples 'membership equal to :descendants' do
+ it 'returns all descendant runners' do
+ expect(subject).to eq([runner_project_7, runner_project_6, runner_project_5,
+ runner_project_4, runner_project_3, runner_project_2,
+ runner_project_1, runner_sub_group_4, runner_sub_group_3,
+ runner_sub_group_2, runner_sub_group_1, runner_group])
+ end
+ end
context 'with user as group owner' do
before do
group.add_owner(user)
end
- context 'passing no params' do
- it 'returns all descendant runners' do
- expect(subject).to eq([runner_project_7, runner_project_6, runner_project_5,
- runner_project_4, runner_project_3, runner_project_2,
- runner_project_1, runner_sub_group_4, runner_sub_group_3,
- runner_sub_group_2, runner_sub_group_1, runner_group])
+ context 'with :group as target group' do
+ let(:target_group) { group }
+
+ context 'passing no params' do
+ it_behaves_like 'membership equal to :descendants'
end
- end
- context 'with sort param' do
- let(:params) { { sort: 'contacted_asc' } }
+ context 'with :descendants membership' do
+ let(:membership) { :descendants }
- it 'sorts by specified attribute' do
- expect(subject).to eq([runner_group, runner_sub_group_1, runner_sub_group_2,
- runner_sub_group_3, runner_sub_group_4, runner_project_1,
- runner_project_2, runner_project_3, runner_project_4,
- runner_project_5, runner_project_6, runner_project_7])
+ it_behaves_like 'membership equal to :descendants'
end
- end
- context 'filtering' do
- context 'by search term' do
- let(:params) { { search: 'runner_project_search' } }
+ context 'with :direct membership' do
+ let(:membership) { :direct }
+
+ it 'returns runners belonging to group' do
+ expect(subject).to eq([runner_group])
+ end
+ end
+
+ context 'with unknown membership' do
+ let(:membership) { :unsupported }
- it 'returns correct runner' do
- expect(subject).to eq([runner_project_3])
+ it 'raises an error' do
+ expect { subject }.to raise_error(ArgumentError, 'Invalid membership filter')
end
end
- context 'by status' do
- let(:params) { { status_status: 'paused' } }
+ context 'with nil group' do
+ let(:target_group) { nil }
- it 'returns correct runner' do
- expect(subject).to eq([runner_sub_group_1])
+ it 'returns no runners' do
+ # Query should run against all runners, however since user is not admin, query returns no results
+ expect(subject).to eq([])
end
end
- context 'by tag_name' do
- let(:params) { { tag_name: %w[runner_tag] } }
+ context 'with sort param' do
+ let(:extra_params) { { sort: 'contacted_asc' } }
- it 'returns correct runner' do
- expect(subject).to eq([runner_project_5])
+ it 'sorts by specified attribute' do
+ expect(subject).to eq([runner_group, runner_sub_group_1, runner_sub_group_2,
+ runner_sub_group_3, runner_sub_group_4, runner_project_1,
+ runner_project_2, runner_project_3, runner_project_4,
+ runner_project_5, runner_project_6, runner_project_7])
end
end
- context 'by runner type' do
- let(:params) { { type_type: 'project_type' } }
+ context 'filtering' do
+ context 'by search term' do
+ let(:extra_params) { { search: 'runner_project_search' } }
+
+ it 'returns correct runner' do
+ expect(subject).to eq([runner_project_3])
+ end
+ end
+
+ context 'by status' do
+ let(:extra_params) { { status_status: 'paused' } }
+
+ it 'returns correct runner' do
+ expect(subject).to eq([runner_sub_group_1])
+ end
+ end
+
+ context 'by tag_name' do
+ let(:extra_params) { { tag_name: %w[runner_tag] } }
+
+ it 'returns correct runner' do
+ expect(subject).to eq([runner_project_5])
+ end
+ end
+
+ context 'by runner type' do
+ let(:extra_params) { { type_type: 'project_type' } }
- it 'returns correct runners' do
- expect(subject).to eq([runner_project_7, runner_project_6,
- runner_project_5, runner_project_4,
- runner_project_3, runner_project_2, runner_project_1])
+ it 'returns correct runners' do
+ expect(subject).to eq([runner_project_7, runner_project_6,
+ runner_project_5, runner_project_4,
+ runner_project_3, runner_project_2, runner_project_1])
+ end
end
end
end
@@ -278,7 +328,7 @@ RSpec.describe Ci::RunnersFinder do
end
describe '#sort_key' do
- subject { described_class.new(current_user: user, group: group, params: params).sort_key }
+ subject { described_class.new(current_user: user, params: params.merge(group: group)).sort_key }
context 'without params' do
it 'returns created_at_desc' do
@@ -287,7 +337,7 @@ RSpec.describe Ci::RunnersFinder do
end
context 'with params' do
- let(:params) { { sort: 'contacted_asc' } }
+ let(:extra_params) { { sort: 'contacted_asc' } }
it 'returns contacted_asc' do
expect(subject).to eq('contacted_asc')
diff --git a/spec/finders/error_tracking/errors_finder_spec.rb b/spec/finders/error_tracking/errors_finder_spec.rb
index 2df5f1653e0..29053054f9d 100644
--- a/spec/finders/error_tracking/errors_finder_spec.rb
+++ b/spec/finders/error_tracking/errors_finder_spec.rb
@@ -6,7 +6,8 @@ RSpec.describe ErrorTracking::ErrorsFinder do
let_it_be(:project) { create(:project) }
let_it_be(:user) { project.creator }
let_it_be(:error) { create(:error_tracking_error, project: project) }
- let_it_be(:error_resolved) { create(:error_tracking_error, :resolved, project: project) }
+ let_it_be(:error_resolved) { create(:error_tracking_error, :resolved, project: project, first_seen_at: 2.hours.ago) }
+ let_it_be(:error_yesterday) { create(:error_tracking_error, project: project, first_seen_at: Time.zone.now.yesterday) }
before do
project.add_maintainer(user)
@@ -17,12 +18,25 @@ RSpec.describe ErrorTracking::ErrorsFinder do
subject { described_class.new(user, project, params).execute }
- it { is_expected.to contain_exactly(error, error_resolved) }
+ it { is_expected.to contain_exactly(error, error_resolved, error_yesterday) }
context 'with status parameter' do
let(:params) { { status: 'resolved' } }
it { is_expected.to contain_exactly(error_resolved) }
end
+
+ context 'with sort parameter' do
+ let(:params) { { status: 'unresolved', sort: 'first_seen' } }
+
+ it { is_expected.to eq([error, error_yesterday]) }
+ end
+
+ context 'with limit parameter' do
+ let(:params) { { limit: '1', sort: 'first_seen' } }
+
+ # Sort by first_seen is DESC by default, so the most recent error is `error`
+ it { is_expected.to contain_exactly(error) }
+ end
end
end
diff --git a/spec/finders/feature_flags_finder_spec.rb b/spec/finders/feature_flags_finder_spec.rb
index 4faa6a62a1f..1b3c71b143f 100644
--- a/spec/finders/feature_flags_finder_spec.rb
+++ b/spec/finders/feature_flags_finder_spec.rb
@@ -72,13 +72,5 @@ RSpec.describe FeatureFlagsFinder do
subject
end
end
-
- context 'with a legacy flag' do
- let!(:feature_flag_3) { create(:operations_feature_flag, :legacy_flag, name: 'flag-c', project: project) }
-
- it 'returns new flags' do
- is_expected.to eq([feature_flag_1, feature_flag_2])
- end
- end
end
end
diff --git a/spec/finders/groups/user_groups_finder_spec.rb b/spec/finders/groups/user_groups_finder_spec.rb
new file mode 100644
index 00000000000..4cce3ab72eb
--- /dev/null
+++ b/spec/finders/groups/user_groups_finder_spec.rb
@@ -0,0 +1,106 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Groups::UserGroupsFinder do
+ describe '#execute' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:guest_group) { create(:group, name: 'public guest', path: 'public-guest') }
+ let_it_be(:private_maintainer_group) { create(:group, :private, name: 'b private maintainer', path: 'b-private-maintainer') }
+ let_it_be(:public_developer_group) { create(:group, project_creation_level: nil, name: 'c public developer', path: 'c-public-developer') }
+ let_it_be(:public_maintainer_group) { create(:group, name: 'a public maintainer', path: 'a-public-maintainer') }
+
+ subject { described_class.new(current_user, target_user, arguments).execute }
+
+ let(:arguments) { {} }
+ let(:current_user) { user }
+ let(:target_user) { user }
+
+ before_all do
+ guest_group.add_guest(user)
+ private_maintainer_group.add_maintainer(user)
+ public_developer_group.add_developer(user)
+ public_maintainer_group.add_maintainer(user)
+ end
+
+ it 'returns all groups where the user is a direct member' do
+ is_expected.to match(
+ [
+ public_maintainer_group,
+ private_maintainer_group,
+ public_developer_group,
+ guest_group
+ ]
+ )
+ end
+
+ context 'when target_user is nil' do
+ let(:target_user) { nil }
+
+ it { is_expected.to be_empty }
+ end
+
+ context 'when current_user is nil' do
+ let(:current_user) { nil }
+
+ it { is_expected.to be_empty }
+ end
+
+ context 'when permission is :create_projects' do
+ let(:arguments) { { permission_scope: :create_projects } }
+
+ specify do
+ is_expected.to match(
+ [
+ public_maintainer_group,
+ private_maintainer_group,
+ public_developer_group
+ ]
+ )
+ end
+
+ context 'when paginatable_namespace_drop_down_for_project_creation feature flag is disabled' do
+ before do
+ stub_feature_flags(paginatable_namespace_drop_down_for_project_creation: false)
+ end
+
+ it 'ignores project creation scope and returns all groups where the user is a direct member' do
+ is_expected.to match(
+ [
+ public_maintainer_group,
+ private_maintainer_group,
+ public_developer_group,
+ guest_group
+ ]
+ )
+ end
+ end
+
+ context 'when search is provided' do
+ let(:arguments) { { permission_scope: :create_projects, search: 'maintainer' } }
+
+ specify do
+ is_expected.to match(
+ [
+ public_maintainer_group,
+ private_maintainer_group
+ ]
+ )
+ end
+ end
+ end
+
+ context 'when search is provided' do
+ let(:arguments) { { search: 'maintainer' } }
+
+ specify do
+ is_expected.to match(
+ [
+ public_maintainer_group,
+ private_maintainer_group
+ ]
+ )
+ end
+ end
+ end
+end
diff --git a/spec/finders/issues_finder/params_spec.rb b/spec/finders/issues_finder/params_spec.rb
new file mode 100644
index 00000000000..879ecc364a2
--- /dev/null
+++ b/spec/finders/issues_finder/params_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe IssuesFinder::Params do
+ describe '#include_hidden' do
+ subject { described_class.new(params, user, IssuesFinder) }
+
+ context 'when param is not set' do
+ let(:params) { {} }
+
+ context 'with an admin', :enable_admin_mode do
+ let(:user) { create(:user, :admin) }
+
+ it 'returns true' do
+ expect(subject.include_hidden?).to be_truthy
+ end
+ end
+
+ context 'with a regular user' do
+ let(:user) { create(:user) }
+
+ it 'returns false' do
+ expect(subject.include_hidden?).to be_falsey
+ end
+ end
+ end
+
+ context 'when param is set' do
+ let(:params) { { include_hidden: true } }
+
+ context 'with an admin', :enable_admin_mode do
+ let(:user) { create(:user, :admin) }
+
+ it 'returns true' do
+ expect(subject.include_hidden?).to be_truthy
+ end
+ end
+
+ context 'with a regular user' do
+ let(:user) { create(:user) }
+
+ it 'returns false' do
+ expect(subject.include_hidden?).to be_falsey
+ end
+ end
+ end
+ end
+end
diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb
index 0cb73f3da6d..ed35d75720c 100644
--- a/spec/finders/issues_finder_spec.rb
+++ b/spec/finders/issues_finder_spec.rb
@@ -12,8 +12,52 @@ RSpec.describe IssuesFinder do
context 'scope: all' do
let(:scope) { 'all' }
- it 'returns all issues' do
- expect(issues).to contain_exactly(issue1, issue2, issue3, issue4, issue5)
+ context 'include_hidden and public_only params' do
+ let_it_be(:banned_user) { create(:user, :banned) }
+ let_it_be(:hidden_issue) { create(:issue, project: project1, author: banned_user) }
+ let_it_be(:confidential_issue) { create(:issue, project: project1, confidential: true) }
+
+ context 'when user is an admin', :enable_admin_mode do
+ let(:user) { create(:user, :admin) }
+
+ it 'returns all issues' do
+ expect(issues).to contain_exactly(issue1, issue2, issue3, issue4, issue5, hidden_issue, confidential_issue)
+ end
+ end
+
+ context 'when user is not an admin' do
+ context 'when public_only is true' do
+ let(:params) { { public_only: true } }
+
+ it 'returns public issues' do
+ expect(issues).to contain_exactly(issue1, issue2, issue3, issue4, issue5)
+ end
+ end
+
+ context 'when public_only is false' do
+ let(:params) { { public_only: false } }
+
+ it 'returns public and confidential issues' do
+ expect(issues).to contain_exactly(issue1, issue2, issue3, issue4, issue5, confidential_issue)
+ end
+ end
+
+ context 'when public_only is not set' do
+ it 'returns public and confidential issue' do
+ expect(issues).to contain_exactly(issue1, issue2, issue3, issue4, issue5, confidential_issue)
+ end
+ end
+
+ context 'when ban_user_feature_flag is false' do
+ before do
+ stub_feature_flags(ban_user_feature_flag: false)
+ end
+
+ it 'returns all issues' do
+ expect(issues).to contain_exactly(issue1, issue2, issue3, issue4, issue5, hidden_issue, confidential_issue)
+ end
+ end
+ end
end
context 'user does not have read permissions' do
@@ -426,139 +470,121 @@ RSpec.describe IssuesFinder do
end
end
- shared_examples ':label_name parameter' do
- context 'filtering by label' do
- let(:params) { { label_name: label.title } }
+ context 'filtering by label' do
+ let(:params) { { label_name: label.title } }
- it 'returns issues with that label' do
- expect(issues).to contain_exactly(issue2)
- end
+ it 'returns issues with that label' do
+ expect(issues).to contain_exactly(issue2)
+ end
- context 'using NOT' do
- let(:params) { { not: { label_name: label.title } } }
+ context 'using NOT' do
+ let(:params) { { not: { label_name: label.title } } }
- it 'returns issues that do not have that label' do
- expect(issues).to contain_exactly(issue1, issue3, issue4, issue5)
- end
+ it 'returns issues that do not have that label' do
+ expect(issues).to contain_exactly(issue1, issue3, issue4, issue5)
+ end
- # IssuableFinder first filters using the outer params (the ones not inside the `not` key.)
- # Afterwards, it applies the `not` params to that resultset. This means that things inside the `not` param
- # do not take precedence over the outer params with the same name.
- context 'shadowing the same outside param' do
- let(:params) { { label_name: label2.title, not: { label_name: label.title } } }
+ # IssuableFinder first filters using the outer params (the ones not inside the `not` key.)
+ # Afterwards, it applies the `not` params to that resultset. This means that things inside the `not` param
+ # do not take precedence over the outer params with the same name.
+ context 'shadowing the same outside param' do
+ let(:params) { { label_name: label2.title, not: { label_name: label.title } } }
- it 'does not take precedence over labels outside NOT' do
- expect(issues).to contain_exactly(issue3)
- end
+ it 'does not take precedence over labels outside NOT' do
+ expect(issues).to contain_exactly(issue3)
end
+ end
- context 'further filtering outside params' do
- let(:params) { { label_name: label2.title, not: { assignee_username: user2.username } } }
+ context 'further filtering outside params' do
+ let(:params) { { label_name: label2.title, not: { assignee_username: user2.username } } }
- it 'further filters on the returned resultset' do
- expect(issues).to be_empty
- end
+ it 'further filters on the returned resultset' do
+ expect(issues).to be_empty
end
end
end
+ end
- context 'filtering by multiple labels' do
- let(:params) { { label_name: [label.title, label2.title].join(',') } }
- let(:label2) { create(:label, project: project2) }
-
- before do
- create(:label_link, label: label2, target: issue2)
- end
+ context 'filtering by multiple labels' do
+ let(:params) { { label_name: [label.title, label2.title].join(',') } }
+ let(:label2) { create(:label, project: project2) }
- it 'returns the unique issues with all those labels' do
- expect(issues).to contain_exactly(issue2)
- end
-
- context 'using NOT' do
- let(:params) { { not: { label_name: [label.title, label2.title].join(',') } } }
+ before do
+ create(:label_link, label: label2, target: issue2)
+ end
- it 'returns issues that do not have any of the labels provided' do
- expect(issues).to contain_exactly(issue1, issue4, issue5)
- end
- end
+ it 'returns the unique issues with all those labels' do
+ expect(issues).to contain_exactly(issue2)
end
- context 'filtering by a label that includes any or none in the title' do
- let(:params) { { label_name: [label.title, label2.title].join(',') } }
- let(:label) { create(:label, title: 'any foo', project: project2) }
- let(:label2) { create(:label, title: 'bar none', project: project2) }
+ context 'using NOT' do
+ let(:params) { { not: { label_name: [label.title, label2.title].join(',') } } }
- before do
- create(:label_link, label: label2, target: issue2)
+ it 'returns issues that do not have any of the labels provided' do
+ expect(issues).to contain_exactly(issue1, issue4, issue5)
end
+ end
+ end
- it 'returns the unique issues with all those labels' do
- expect(issues).to contain_exactly(issue2)
- end
+ context 'filtering by a label that includes any or none in the title' do
+ let(:params) { { label_name: [label.title, label2.title].join(',') } }
+ let(:label) { create(:label, title: 'any foo', project: project2) }
+ let(:label2) { create(:label, title: 'bar none', project: project2) }
- context 'using NOT' do
- let(:params) { { not: { label_name: [label.title, label2.title].join(',') } } }
+ before do
+ create(:label_link, label: label2, target: issue2)
+ end
- it 'returns issues that do not have ANY ONE of the labels provided' do
- expect(issues).to contain_exactly(issue1, issue4, issue5)
- end
- end
+ it 'returns the unique issues with all those labels' do
+ expect(issues).to contain_exactly(issue2)
end
- context 'filtering by no label' do
- let(:params) { { label_name: described_class::Params::FILTER_NONE } }
+ context 'using NOT' do
+ let(:params) { { not: { label_name: [label.title, label2.title].join(',') } } }
- it 'returns issues with no labels' do
+ it 'returns issues that do not have ANY ONE of the labels provided' do
expect(issues).to contain_exactly(issue1, issue4, issue5)
end
end
+ end
- context 'filtering by any label' do
- let(:params) { { label_name: described_class::Params::FILTER_ANY } }
-
- it 'returns issues that have one or more label' do
- create_list(:label_link, 2, label: create(:label, project: project2), target: issue3)
+ context 'filtering by no label' do
+ let(:params) { { label_name: described_class::Params::FILTER_NONE } }
- expect(issues).to contain_exactly(issue2, issue3)
- end
+ it 'returns issues with no labels' do
+ expect(issues).to contain_exactly(issue1, issue4, issue5)
end
+ end
- context 'when the same label exists on project and group levels' do
- let(:issue1) { create(:issue, project: project1) }
- let(:issue2) { create(:issue, project: project1) }
-
- # Skipping validation to reproduce a "real-word" scenario.
- # We still have legacy labels on PRD that have the same title on the group and project levels, example: `bug`
- let(:project_label) { build(:label, title: 'somelabel', project: project1).tap { |r| r.save!(validate: false) } }
- let(:group_label) { create(:group_label, title: 'somelabel', group: project1.group) }
-
- let(:params) { { label_name: 'somelabel' } }
+ context 'filtering by any label' do
+ let(:params) { { label_name: described_class::Params::FILTER_ANY } }
- before do
- create(:label_link, label: group_label, target: issue1)
- create(:label_link, label: project_label, target: issue2)
- end
+ it 'returns issues that have one or more label' do
+ create_list(:label_link, 2, label: create(:label, project: project2), target: issue3)
- it 'finds both issue records' do
- expect(issues).to contain_exactly(issue1, issue2)
- end
+ expect(issues).to contain_exactly(issue2, issue3)
end
end
- context 'when `optimized_issuable_label_filter` feature flag is off' do
- before do
- stub_feature_flags(optimized_issuable_label_filter: false)
- end
+ context 'when the same label exists on project and group levels' do
+ let(:issue1) { create(:issue, project: project1) }
+ let(:issue2) { create(:issue, project: project1) }
- it_behaves_like ':label_name parameter'
- end
+ # Skipping validation to reproduce a "real-word" scenario.
+ # We still have legacy labels on PRD that have the same title on the group and project levels, example: `bug`
+ let(:project_label) { build(:label, title: 'somelabel', project: project1).tap { |r| r.save!(validate: false) } }
+ let(:group_label) { create(:group_label, title: 'somelabel', group: project1.group) }
+
+ let(:params) { { label_name: 'somelabel' } }
- context 'when `optimized_issuable_label_filter` feature flag is on' do
before do
- stub_feature_flags(optimized_issuable_label_filter: true)
+ create(:label_link, label: group_label, target: issue1)
+ create(:label_link, label: project_label, target: issue2)
end
- it_behaves_like ':label_name parameter'
+ it 'finds both issue records' do
+ expect(issues).to contain_exactly(issue1, issue2)
+ end
end
context 'filtering by issue term' do
@@ -567,6 +593,35 @@ RSpec.describe IssuesFinder do
it 'returns issues with title and description match for search term' do
expect(issues).to contain_exactly(issue1, issue2)
end
+
+ context 'with anonymous user' do
+ let_it_be(:public_project) { create(:project, :public, group: subgroup) }
+ let_it_be(:issue6) { create(:issue, project: public_project, title: 'tanuki') }
+ let_it_be(:issue7) { create(:issue, project: public_project, title: 'ikunat') }
+
+ let(:search_user) { nil }
+ let(:params) { { search: 'tanuki' } }
+
+ context 'with disable_anonymous_search feature flag enabled' do
+ before do
+ stub_feature_flags(disable_anonymous_search: true)
+ end
+
+ it 'does not perform search' do
+ expect(issues).to contain_exactly(issue6, issue7)
+ end
+ end
+
+ context 'with disable_anonymous_search feature flag disabled' do
+ before do
+ stub_feature_flags(disable_anonymous_search: false)
+ end
+
+ it 'finds one public issue' do
+ expect(issues).to contain_exactly(issue6)
+ end
+ end
+ end
end
context 'filtering by issue term in title' do
@@ -1001,132 +1056,64 @@ RSpec.describe IssuesFinder do
end
describe '#with_confidentiality_access_check' do
- let(:guest) { create(:user) }
+ let(:user) { create(:user) }
let_it_be(:authorized_user) { create(:user) }
- let_it_be(:banned_user) { create(:user, :banned) }
let_it_be(:project) { create(:project, namespace: authorized_user.namespace) }
let_it_be(:public_issue) { create(:issue, project: project) }
let_it_be(:confidential_issue) { create(:issue, project: project, confidential: true) }
- let_it_be(:hidden_issue) { create(:issue, project: project, author: banned_user) }
- shared_examples 'returns public, does not return hidden or confidential' do
+ shared_examples 'returns public, does not return confidential' do
it 'returns only public issues' do
expect(subject).to include(public_issue)
- expect(subject).not_to include(confidential_issue, hidden_issue)
+ expect(subject).not_to include(confidential_issue)
end
end
- shared_examples 'returns public and confidential, does not return hidden' do
- it 'returns only public and confidential issues' do
+ shared_examples 'returns public and confidential' do
+ it 'returns public and confidential issues' do
expect(subject).to include(public_issue, confidential_issue)
- expect(subject).not_to include(hidden_issue)
- end
- end
-
- shared_examples 'returns public and hidden, does not return confidential' do
- it 'returns only public and hidden issues' do
- expect(subject).to include(public_issue, hidden_issue)
- expect(subject).not_to include(confidential_issue)
end
end
- shared_examples 'returns public, confidential, and hidden' do
- it 'returns all issues' do
- expect(subject).to include(public_issue, confidential_issue, hidden_issue)
- end
- end
+ subject { described_class.new(user, params).with_confidentiality_access_check }
context 'when no project filter is given' do
let(:params) { {} }
context 'for an anonymous user' do
- subject { described_class.new(nil, params).with_confidentiality_access_check }
-
- it_behaves_like 'returns public, does not return hidden or confidential'
-
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(ban_user_feature_flag: false)
- end
-
- it_behaves_like 'returns public and hidden, does not return confidential'
- end
+ it_behaves_like 'returns public, does not return confidential'
end
context 'for a user without project membership' do
- subject { described_class.new(user, params).with_confidentiality_access_check }
-
- it_behaves_like 'returns public, does not return hidden or confidential'
-
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(ban_user_feature_flag: false)
- end
-
- it_behaves_like 'returns public and hidden, does not return confidential'
- end
+ it_behaves_like 'returns public, does not return confidential'
end
context 'for a guest user' do
- subject { described_class.new(guest, params).with_confidentiality_access_check }
-
before do
- project.add_guest(guest)
+ project.add_guest(user)
end
- it_behaves_like 'returns public, does not return hidden or confidential'
-
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(ban_user_feature_flag: false)
- end
-
- it_behaves_like 'returns public and hidden, does not return confidential'
- end
+ it_behaves_like 'returns public, does not return confidential'
end
context 'for a project member with access to view confidential issues' do
- subject { described_class.new(authorized_user, params).with_confidentiality_access_check }
-
- it_behaves_like 'returns public and confidential, does not return hidden'
-
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(ban_user_feature_flag: false)
- end
-
- it_behaves_like 'returns public, confidential, and hidden'
+ before do
+ project.add_reporter(user)
end
+
+ it_behaves_like 'returns public and confidential'
end
context 'for an admin' do
- let(:admin_user) { create(:user, :admin) }
-
- subject { described_class.new(admin_user, params).with_confidentiality_access_check }
+ let(:user) { create(:user, :admin) }
context 'when admin mode is enabled', :enable_admin_mode do
- it_behaves_like 'returns public, confidential, and hidden'
-
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(ban_user_feature_flag: false)
- end
-
- it_behaves_like 'returns public, confidential, and hidden'
- end
+ it_behaves_like 'returns public and confidential'
end
context 'when admin mode is disabled' do
- it_behaves_like 'returns public, does not return hidden or confidential'
-
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(ban_user_feature_flag: false)
- end
-
- it_behaves_like 'returns public and hidden, does not return confidential'
- end
+ it_behaves_like 'returns public, does not return confidential'
end
end
end
@@ -1135,17 +1122,9 @@ RSpec.describe IssuesFinder do
let(:params) { { project_id: project.id } }
context 'for an anonymous user' do
- subject { described_class.new(nil, params).with_confidentiality_access_check }
-
- it_behaves_like 'returns public, does not return hidden or confidential'
-
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(ban_user_feature_flag: false)
- end
+ let(:user) { nil }
- it_behaves_like 'returns public and hidden, does not return confidential'
- end
+ it_behaves_like 'returns public, does not return confidential'
it 'does not filter by confidentiality' do
expect(Issue).not_to receive(:where).with(a_string_matching('confidential'), anything)
@@ -1154,17 +1133,7 @@ RSpec.describe IssuesFinder do
end
context 'for a user without project membership' do
- subject { described_class.new(user, params).with_confidentiality_access_check }
-
- it_behaves_like 'returns public, does not return hidden or confidential'
-
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(ban_user_feature_flag: false)
- end
-
- it_behaves_like 'returns public and hidden, does not return confidential'
- end
+ it_behaves_like 'returns public, does not return confidential'
it 'filters by confidentiality' do
expect(subject.to_sql).to match("issues.confidential")
@@ -1172,21 +1141,11 @@ RSpec.describe IssuesFinder do
end
context 'for a guest user' do
- subject { described_class.new(guest, params).with_confidentiality_access_check }
-
before do
- project.add_guest(guest)
+ project.add_guest(user)
end
- it_behaves_like 'returns public, does not return hidden or confidential'
-
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(ban_user_feature_flag: false)
- end
-
- it_behaves_like 'returns public and hidden, does not return confidential'
- end
+ it_behaves_like 'returns public, does not return confidential'
it 'filters by confidentiality' do
expect(subject.to_sql).to match("issues.confidential")
@@ -1194,40 +1153,18 @@ RSpec.describe IssuesFinder do
end
context 'for a project member with access to view confidential issues' do
- subject { described_class.new(authorized_user, params).with_confidentiality_access_check }
-
- it_behaves_like 'returns public and confidential, does not return hidden'
-
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(ban_user_feature_flag: false)
- end
-
- it_behaves_like 'returns public, confidential, and hidden'
+ before do
+ project.add_reporter(user)
end
- it 'does not filter by confidentiality' do
- expect(Issue).not_to receive(:where).with(a_string_matching('confidential'), anything)
-
- subject
- end
+ it_behaves_like 'returns public and confidential'
end
context 'for an admin' do
- let(:admin_user) { create(:user, :admin) }
-
- subject { described_class.new(admin_user, params).with_confidentiality_access_check }
+ let(:user) { create(:user, :admin) }
context 'when admin mode is enabled', :enable_admin_mode do
- it_behaves_like 'returns public, confidential, and hidden'
-
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(ban_user_feature_flag: false)
- end
-
- it_behaves_like 'returns public, confidential, and hidden'
- end
+ it_behaves_like 'returns public and confidential'
it 'does not filter by confidentiality' do
expect(Issue).not_to receive(:where).with(a_string_matching('confidential'), anything)
@@ -1237,19 +1174,7 @@ RSpec.describe IssuesFinder do
end
context 'when admin mode is disabled' do
- it_behaves_like 'returns public, does not return hidden or confidential'
-
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(ban_user_feature_flag: false)
- end
-
- it_behaves_like 'returns public and hidden, does not return confidential'
- end
-
- it 'filters by confidentiality' do
- expect(subject.to_sql).to match("issues.confidential")
- end
+ it_behaves_like 'returns public, does not return confidential'
end
end
end
diff --git a/spec/finders/merge_requests_finder_spec.rb b/spec/finders/merge_requests_finder_spec.rb
index 49b29cefb9b..42197a6b103 100644
--- a/spec/finders/merge_requests_finder_spec.rb
+++ b/spec/finders/merge_requests_finder_spec.rb
@@ -227,56 +227,38 @@ RSpec.describe MergeRequestsFinder do
end
end
- shared_examples ':label_name parameter' do
- describe ':label_name parameter' do
- let(:common_labels) { create_list(:label, 3) }
- let(:distinct_labels) { create_list(:label, 3) }
- let(:merge_requests) do
- common_attrs = {
- source_project: project1, target_project: project1, author: user
- }
- distinct_labels.map do |label|
- labels = [label, *common_labels]
- create(:labeled_merge_request, :closed, labels: labels, **common_attrs)
- end
- end
-
- def find(label_name)
- described_class.new(user, label_name: label_name).execute
- end
-
- it 'accepts a single label' do
- found = find(distinct_labels.first.title)
- common = find(common_labels.first.title)
-
- expect(found).to contain_exactly(merge_requests.first)
- expect(common).to match_array(merge_requests)
- end
-
- it 'accepts an array of labels, all of which must match' do
- all_distinct = find(distinct_labels.pluck(:title))
- all_common = find(common_labels.pluck(:title))
-
- expect(all_distinct).to be_empty
- expect(all_common).to match_array(merge_requests)
+ describe ':label_name parameter' do
+ let(:common_labels) { create_list(:label, 3) }
+ let(:distinct_labels) { create_list(:label, 3) }
+ let(:merge_requests) do
+ common_attrs = {
+ source_project: project1, target_project: project1, author: user
+ }
+ distinct_labels.map do |label|
+ labels = [label, *common_labels]
+ create(:labeled_merge_request, :closed, labels: labels, **common_attrs)
end
end
- end
- context 'when `optimized_issuable_label_filter` feature flag is off' do
- before do
- stub_feature_flags(optimized_issuable_label_filter: false)
+ def find(label_name)
+ described_class.new(user, label_name: label_name).execute
end
- it_behaves_like ':label_name parameter'
- end
+ it 'accepts a single label' do
+ found = find(distinct_labels.first.title)
+ common = find(common_labels.first.title)
- context 'when `optimized_issuable_label_filter` feature flag is on' do
- before do
- stub_feature_flags(optimized_issuable_label_filter: true)
+ expect(found).to contain_exactly(merge_requests.first)
+ expect(common).to match_array(merge_requests)
end
- it_behaves_like ':label_name parameter'
+ it 'accepts an array of labels, all of which must match' do
+ all_distinct = find(distinct_labels.pluck(:title))
+ all_common = find(common_labels.pluck(:title))
+
+ expect(all_distinct).to be_empty
+ expect(all_common).to match_array(merge_requests)
+ end
end
it 'filters by source project id' do
@@ -729,6 +711,36 @@ RSpec.describe MergeRequestsFinder do
merge_requests = described_class.new(user, params).execute
expect { merge_requests.load }.not_to raise_error
end
+
+ context 'filtering by search text' do
+ let!(:merge_request6) { create(:merge_request, source_project: project1, target_project: project1, source_branch: 'tanuki-branch', title: 'tanuki') }
+
+ let(:params) { { project_id: project1.id, search: 'tanuki' } }
+
+ context 'with anonymous user' do
+ let(:merge_requests) { described_class.new(nil, params).execute }
+
+ context 'with disable_anonymous_search feature flag enabled' do
+ before do
+ stub_feature_flags(disable_anonymous_search: true)
+ end
+
+ it 'does not perform search' do
+ expect(merge_requests).to contain_exactly(merge_request1, merge_request2, merge_request6)
+ end
+ end
+
+ context 'with disable_anonymous_search feature flag disabled' do
+ before do
+ stub_feature_flags(disable_anonymous_search: false)
+ end
+
+ it 'returns matching merge requests' do
+ expect(merge_requests).to contain_exactly(merge_request6)
+ end
+ end
+ end
+ end
end
describe '#row_count', :request_store do
diff --git a/spec/finders/packages/helm/package_files_finder_spec.rb b/spec/finders/packages/helm/package_files_finder_spec.rb
index 2b84fd2b2d2..5f1378f837d 100644
--- a/spec/finders/packages/helm/package_files_finder_spec.rb
+++ b/spec/finders/packages/helm/package_files_finder_spec.rb
@@ -6,42 +6,51 @@ RSpec.describe ::Packages::Helm::PackageFilesFinder do
let_it_be(:project1) { create(:project) }
let_it_be(:project2) { create(:project) }
let_it_be(:helm_package) { create(:helm_package, project: project1) }
- let_it_be(:helm_package_file) { helm_package.package_files.first }
+ let_it_be(:helm_package_file1) { helm_package.package_files.first }
+ let_it_be(:helm_package_file2) { create(:helm_package_file, package: helm_package) }
let_it_be(:debian_package) { create(:debian_package, project: project1) }
- describe '#execute' do
- let(:project) { project1 }
- let(:channel) { 'stable' }
- let(:params) { {} }
+ let(:project) { project1 }
+ let(:channel) { 'stable' }
+ let(:params) { {} }
+
+ let(:service) { described_class.new(project, channel, params) }
- subject { described_class.new(project, channel, params).execute }
+ describe '#execute' do
+ subject { service.execute }
context 'with empty params' do
- it { is_expected.to match_array([helm_package_file]) }
+ it { is_expected.to eq([helm_package_file2, helm_package_file1]) }
end
context 'with another project' do
let(:project) { project2 }
- it { is_expected.to match_array([]) }
+ it { is_expected.to eq([]) }
end
context 'with another channel' do
let(:channel) { 'staging' }
- it { is_expected.to match_array([]) }
+ it { is_expected.to eq([]) }
end
- context 'with file_name' do
- let(:params) { { file_name: helm_package_file.file_name } }
+ context 'with matching file_name' do
+ let(:params) { { file_name: helm_package_file1.file_name } }
- it { is_expected.to match_array([helm_package_file]) }
+ it { is_expected.to eq([helm_package_file2, helm_package_file1]) }
end
context 'with another file_name' do
let(:params) { { file_name: 'foobar.tgz' } }
- it { is_expected.to match_array([]) }
+ it { is_expected.to eq([]) }
end
end
+
+ describe '#most_recent!' do
+ subject { service.most_recent! }
+
+ it { is_expected.to eq(helm_package_file2) }
+ end
end
diff --git a/spec/finders/packages/helm/packages_finder_spec.rb b/spec/finders/packages/helm/packages_finder_spec.rb
new file mode 100644
index 00000000000..5037a9e6205
--- /dev/null
+++ b/spec/finders/packages/helm/packages_finder_spec.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Packages::Helm::PackagesFinder do
+ let_it_be(:project1) { create(:project) }
+ let_it_be(:project2) { create(:project) }
+ let_it_be(:helm_package) { create(:helm_package, project: project1) }
+ let_it_be(:npm_package) { create(:npm_package, project: project1) }
+ let_it_be(:npm_package) { create(:npm_package, project: project2) }
+
+ let(:project) { project1 }
+ let(:channel) { 'stable' }
+ let(:finder) { described_class.new(project, channel) }
+
+ describe '#execute' do
+ subject { finder.execute }
+
+ context 'with project' do
+ context 'with channel' do
+ it { is_expected.to eq([helm_package]) }
+
+ context 'ignores duplicate package files' do
+ let_it_be(:package_file1) { create(:helm_package_file, package: helm_package) }
+ let_it_be(:package_file2) { create(:helm_package_file, package: helm_package) }
+
+ it { is_expected.to eq([helm_package]) }
+
+ context 'let clients use select id' do
+ subject { finder.execute.pluck_primary_key }
+
+ it { is_expected.to eq([helm_package.id]) }
+ end
+ end
+ end
+
+ context 'with not existing channel' do
+ let(:channel) { 'alpha' }
+
+ it { is_expected.to be_empty }
+ end
+
+ context 'with no channel' do
+ let(:channel) { nil }
+
+ it { is_expected.to be_empty }
+ end
+
+ context 'with no helm packages' do
+ let(:project) { project2 }
+
+ it { is_expected.to be_empty }
+ end
+ end
+
+ context 'with no project' do
+ let(:project) { nil }
+
+ it { is_expected.to be_empty }
+ end
+
+ context 'when the limit is hit' do
+ let_it_be(:helm_package2) { create(:helm_package, project: project1) }
+ let_it_be(:helm_package3) { create(:helm_package, project: project1) }
+ let_it_be(:helm_package4) { create(:helm_package, project: project1) }
+
+ before do
+ stub_const("#{described_class}::MAX_PACKAGES_COUNT", 2)
+ end
+
+ it { is_expected.to eq([helm_package4, helm_package3]) }
+ end
+ end
+end
diff --git a/spec/finders/packages/npm/package_finder_spec.rb b/spec/finders/packages/npm/package_finder_spec.rb
index a995f3b96c4..230d267e508 100644
--- a/spec/finders/packages/npm/package_finder_spec.rb
+++ b/spec/finders/packages/npm/package_finder_spec.rb
@@ -7,6 +7,7 @@ RSpec.describe ::Packages::Npm::PackageFinder do
let(:project) { package.project }
let(:package_name) { package.name }
+ let(:last_of_each_version) { true }
shared_examples 'accepting a namespace for' do |example_name|
before do
@@ -38,6 +39,8 @@ RSpec.describe ::Packages::Npm::PackageFinder do
end
describe '#execute' do
+ subject { finder.execute }
+
shared_examples 'finding packages by name' do
it { is_expected.to eq([package]) }
@@ -56,13 +59,27 @@ RSpec.describe ::Packages::Npm::PackageFinder do
end
end
- subject { finder.execute }
+ shared_examples 'handling last_of_each_version' do
+ include_context 'last_of_each_version setup context'
+
+ context 'disabled' do
+ let(:last_of_each_version) { false }
+
+ it { is_expected.to contain_exactly(package1, package2) }
+ end
+
+ context 'enabled' do
+ it { is_expected.to contain_exactly(package2) }
+ end
+ end
context 'with a project' do
- let(:finder) { described_class.new(package_name, project: project) }
+ let(:finder) { described_class.new(package_name, project: project, last_of_each_version: last_of_each_version) }
it_behaves_like 'finding packages by name'
+ it_behaves_like 'handling last_of_each_version'
+
context 'set to nil' do
let(:project) { nil }
@@ -71,10 +88,12 @@ RSpec.describe ::Packages::Npm::PackageFinder do
end
context 'with a namespace' do
- let(:finder) { described_class.new(package_name, namespace: namespace) }
+ let(:finder) { described_class.new(package_name, namespace: namespace, last_of_each_version: last_of_each_version) }
it_behaves_like 'accepting a namespace for', 'finding packages by name'
+ it_behaves_like 'accepting a namespace for', 'handling last_of_each_version'
+
context 'set to nil' do
let_it_be(:namespace) { nil }
@@ -98,16 +117,28 @@ RSpec.describe ::Packages::Npm::PackageFinder do
end
end
+ shared_examples 'handling last_of_each_version' do
+ include_context 'last_of_each_version setup context'
+
+ context 'enabled' do
+ it { is_expected.to eq(package2) }
+ end
+ end
+
context 'with a project' do
- let(:finder) { described_class.new(package_name, project: project) }
+ let(:finder) { described_class.new(package_name, project: project, last_of_each_version: last_of_each_version) }
it_behaves_like 'finding packages by version'
+
+ it_behaves_like 'handling last_of_each_version'
end
context 'with a namespace' do
- let(:finder) { described_class.new(package_name, namespace: namespace) }
+ let(:finder) { described_class.new(package_name, namespace: namespace, last_of_each_version: last_of_each_version) }
it_behaves_like 'accepting a namespace for', 'finding packages by version'
+
+ it_behaves_like 'accepting a namespace for', 'handling last_of_each_version'
end
end
@@ -118,10 +149,26 @@ RSpec.describe ::Packages::Npm::PackageFinder do
it { is_expected.to eq(package) }
end
+ shared_examples 'handling last_of_each_version' do
+ include_context 'last_of_each_version setup context'
+
+ context 'disabled' do
+ let(:last_of_each_version) { false }
+
+ it { is_expected.to eq(package2) }
+ end
+
+ context 'enabled' do
+ it { is_expected.to eq(package2) }
+ end
+ end
+
context 'with a project' do
- let(:finder) { described_class.new(package_name, project: project) }
+ let(:finder) { described_class.new(package_name, project: project, last_of_each_version: last_of_each_version) }
it_behaves_like 'finding package by last'
+
+ it_behaves_like 'handling last_of_each_version'
end
context 'with a namespace' do
@@ -129,6 +176,8 @@ RSpec.describe ::Packages::Npm::PackageFinder do
it_behaves_like 'accepting a namespace for', 'finding package by last'
+ it_behaves_like 'accepting a namespace for', 'handling last_of_each_version'
+
context 'with duplicate packages' do
let_it_be(:namespace) { create(:group) }
let_it_be(:subgroup1) { create(:group, parent: namespace) }
diff --git a/spec/finders/projects_finder_spec.rb b/spec/finders/projects_finder_spec.rb
index 21b5b2f6130..d26180bbf94 100644
--- a/spec/finders/projects_finder_spec.rb
+++ b/spec/finders/projects_finder_spec.rb
@@ -135,6 +135,7 @@ RSpec.describe ProjectsFinder do
describe 'filter by tags (deprecated)' do
before do
+ public_project.reload
public_project.topic_list = 'foo'
public_project.save!
end
@@ -146,6 +147,7 @@ RSpec.describe ProjectsFinder do
describe 'filter by topics' do
before do
+ public_project.reload
public_project.topic_list = 'foo, bar'
public_project.save!
end
@@ -188,6 +190,32 @@ RSpec.describe ProjectsFinder do
it { is_expected.to eq([public_project]) }
end
+ context 'with anonymous user' do
+ let(:public_project_2) { create(:project, :public, group: group, name: 'E', path: 'E') }
+ let(:current_user) { nil }
+ let(:params) { { search: 'C' } }
+
+ context 'with disable_anonymous_project_search feature flag enabled' do
+ before do
+ stub_feature_flags(disable_anonymous_project_search: true)
+ end
+
+ it 'does not perform search' do
+ is_expected.to eq([public_project_2, public_project])
+ end
+ end
+
+ context 'with disable_anonymous_project_search feature flag disabled' do
+ before do
+ stub_feature_flags(disable_anonymous_project_search: false)
+ end
+
+ it 'finds one public project' do
+ is_expected.to eq([public_project])
+ end
+ end
+ end
+
describe 'filter by name for backward compatibility' do
let(:params) { { name: 'C' } }
diff --git a/spec/finders/repositories/tree_finder_spec.rb b/spec/finders/repositories/tree_finder_spec.rb
new file mode 100644
index 00000000000..0d70d5f92d3
--- /dev/null
+++ b/spec/finders/repositories/tree_finder_spec.rb
@@ -0,0 +1,95 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe Repositories::TreeFinder do
+ include RepoHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :repository, creator: user) }
+
+ let(:repository) { project.repository }
+ let(:tree_finder) { described_class.new(project, params) }
+ let(:params) { {} }
+ let(:first_page_ids) { tree_finder.execute.map(&:id) }
+ let(:second_page_token) { first_page_ids.last }
+
+ describe "#execute" do
+ subject { tree_finder.execute(gitaly_pagination: true) }
+
+ it "returns an array" do
+ is_expected.to be_an(Array)
+ end
+
+ it "includes 20 items by default" do
+ expect(subject.size).to eq(20)
+ end
+
+ it "accepts a gitaly_pagination argument" do
+ expect(repository).to receive(:tree).with(anything, anything, recursive: nil, pagination_params: { limit: 20, page_token: nil }).and_call_original
+ expect(tree_finder.execute(gitaly_pagination: true)).to be_an(Array)
+
+ expect(repository).to receive(:tree).with(anything, anything, recursive: nil).and_call_original
+ expect(tree_finder.execute(gitaly_pagination: false)).to be_an(Array)
+ end
+
+ context "commit doesn't exist" do
+ let(:params) do
+ { ref: "nonesuchref" }
+ end
+
+ it "raises an error" do
+ expect { subject }.to raise_error(described_class::CommitMissingError)
+ end
+ end
+
+ describe "pagination_params" do
+ let(:params) do
+ { per_page: 5, page_token: nil }
+ end
+
+ it "has the per_page number of items" do
+ expect(subject.size).to eq(5)
+ end
+
+ it "doesn't include any of the first page records" do
+ first_page_ids = subject.map(&:id)
+ second_page = described_class.new(project, { per_page: 5, page_token: first_page_ids.last }).execute(gitaly_pagination: true)
+
+ expect(second_page.map(&:id)).not_to include(*first_page_ids)
+ end
+ end
+ end
+
+ describe "#total", :use_clean_rails_memory_store_caching do
+ subject { tree_finder.total }
+
+ it { is_expected.to be_an(Integer) }
+
+ it "only calculates the total once" do
+ expect(repository).to receive(:tree).once.and_call_original
+
+ 2.times { tree_finder.total }
+ end
+ end
+
+ describe "#commit_exists?" do
+ subject { tree_finder.commit_exists? }
+
+ context "ref exists" do
+ let(:params) do
+ { ref: project.default_branch }
+ end
+
+ it { is_expected.to be(true) }
+ end
+
+ context "ref is missing" do
+ let(:params) do
+ { ref: "nonesuchref" }
+ end
+
+ it { is_expected.to be(false) }
+ end
+ end
+end
diff --git a/spec/fixtures/api/schemas/feature_flag.json b/spec/fixtures/api/schemas/feature_flag.json
index 45b704e4b84..47f86a9f92b 100644
--- a/spec/fixtures/api/schemas/feature_flag.json
+++ b/spec/fixtures/api/schemas/feature_flag.json
@@ -1,10 +1,7 @@
{
"type": "object",
- "required" : [
- "id",
- "name"
- ],
- "properties" : {
+ "required": ["id", "name"],
+ "properties": {
"id": { "type": "integer" },
"iid": { "type": ["integer", "null"] },
"version": { "type": "string" },
diff --git a/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric.yml b/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric.yml
index 8495d983d10..16ca71f24ae 100644
--- a/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric.yml
+++ b/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric.yml
@@ -7,7 +7,7 @@ product_stage:
product_group:
product_category:
value_type: number
-status: implemented
+status: active
milestone: "13.9"
introduced_by_url:
time_frame: 7d
diff --git a/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_ee.yml b/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_ee.yml
index 82e9af5b04f..060ab7baccf 100644
--- a/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_ee.yml
+++ b/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_ee.yml
@@ -7,7 +7,7 @@ product_stage:
product_group:
product_category:
value_type: number
-status: implemented
+status: active
milestone: "13.9"
introduced_by_url:
time_frame: 7d
diff --git a/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_name_suggestions.yml b/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_name_suggestions.yml
index aad7dc76290..e373d6a9e45 100644
--- a/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_name_suggestions.yml
+++ b/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_name_suggestions.yml
@@ -8,7 +8,7 @@ product_stage:
product_group:
product_category:
value_type: number
-status: implemented
+status: active
milestone: "13.9"
introduced_by_url:
time_frame: 7d
diff --git a/spec/frontend/__helpers__/emoji.js b/spec/frontend/__helpers__/emoji.js
index 9f9134f6f63..a64135601ae 100644
--- a/spec/frontend/__helpers__/emoji.js
+++ b/spec/frontend/__helpers__/emoji.js
@@ -49,6 +49,11 @@ export const emojiFixtureMap = {
unicodeVersion: '5.1',
description: 'white medium star',
},
+ xss: {
+ moji: '<img src=x onerror=prompt(1)>',
+ unicodeVersion: '5.1',
+ description: 'xss',
+ },
};
export const mockEmojiData = Object.keys(emojiFixtureMap).reduce((acc, k) => {
diff --git a/spec/frontend/__helpers__/local_storage_helper.js b/spec/frontend/__helpers__/local_storage_helper.js
index 21749fd8070..cf75b0b53fe 100644
--- a/spec/frontend/__helpers__/local_storage_helper.js
+++ b/spec/frontend/__helpers__/local_storage_helper.js
@@ -2,9 +2,7 @@
* Manage the instance of a custom `window.localStorage`
*
* This only encapsulates the setup / teardown logic so that it can easily be
- * reused with different implementations (i.e. a spy or a [fake][1])
- *
- * [1]: https://stackoverflow.com/a/41434763/1708147
+ * reused with different implementations (i.e. a spy or a fake)
*
* @param {() => any} fn Function that returns the object to use for localStorage
*/
diff --git a/spec/frontend/__helpers__/mock_window_location_helper.js b/spec/frontend/__helpers__/mock_window_location_helper.js
index 3755778e5c1..14082857053 100644
--- a/spec/frontend/__helpers__/mock_window_location_helper.js
+++ b/spec/frontend/__helpers__/mock_window_location_helper.js
@@ -2,9 +2,7 @@
* Manage the instance of a custom `window.location`
*
* This only encapsulates the setup / teardown logic so that it can easily be
- * reused with different implementations (i.e. a spy or a [fake][1])
- *
- * [1]: https://stackoverflow.com/a/41434763/1708147
+ * reused with different implementations (i.e. a spy or a fake)
*
* @param {() => any} fn Function that returns the object to use for window.location
*/
diff --git a/spec/frontend/__helpers__/test_apollo_link.js b/spec/frontend/__helpers__/test_apollo_link.js
new file mode 100644
index 00000000000..dde3a4e99bb
--- /dev/null
+++ b/spec/frontend/__helpers__/test_apollo_link.js
@@ -0,0 +1,46 @@
+import { InMemoryCache } from 'apollo-cache-inmemory';
+import { ApolloClient } from 'apollo-client';
+import { ApolloLink } from 'apollo-link';
+import gql from 'graphql-tag';
+
+const FOO_QUERY = gql`
+ query {
+ foo
+ }
+`;
+
+/**
+ * This function returns a promise that resolves to the final operation after
+ * running an ApolloClient query with the given ApolloLink
+ *
+ * @typedef {Object} TestApolloLinkOptions
+ * @property {Object} context the default context object sent along the ApolloLink chain
+ *
+ * @param {ApolloLink} subjectLink the ApolloLink which is under test
+ * @param {TestApolloLinkOptions} options contains options to send a long with the query
+ *
+ * @returns Promise resolving to the resulting operation after running the subjectLink
+ */
+export const testApolloLink = (subjectLink, options = {}) =>
+ new Promise((resolve) => {
+ const { context = {} } = options;
+
+ // Use the terminating link to capture the final operation and resolve with this.
+ const terminatingLink = new ApolloLink((operation) => {
+ resolve(operation);
+
+ return null;
+ });
+
+ const client = new ApolloClient({
+ link: ApolloLink.from([subjectLink, terminatingLink]),
+ // cache is a required option
+ cache: new InMemoryCache(),
+ });
+
+ // Trigger a query so the ApolloLink chain will be executed.
+ client.query({
+ context,
+ query: FOO_QUERY,
+ });
+ });
diff --git a/spec/frontend/alerts_settings/components/__snapshots__/alerts_form_spec.js.snap b/spec/frontend/alerts_settings/components/__snapshots__/alerts_form_spec.js.snap
index 3a374084dbc..ddb188edb10 100644
--- a/spec/frontend/alerts_settings/components/__snapshots__/alerts_form_spec.js.snap
+++ b/spec/frontend/alerts_settings/components/__snapshots__/alerts_form_spec.js.snap
@@ -51,10 +51,14 @@ exports[`Alert integration settings form default state should match the default
<gl-dropdown-stub
block="true"
category="primary"
+ clearalltext="Clear all"
data-qa-selector="incident_templates_dropdown"
headertext=""
hideheaderborder="true"
+ highlighteditemstitle="Selected"
+ highlighteditemstitleclass="gl-px-5"
id="alert-integration-settings-issue-template"
+ showhighlighteditemstitle="true"
size="medium"
text="selecte_tmpl"
variant="default"
diff --git a/spec/frontend/api/projects_api_spec.js b/spec/frontend/api/projects_api_spec.js
new file mode 100644
index 00000000000..8f40b557e1f
--- /dev/null
+++ b/spec/frontend/api/projects_api_spec.js
@@ -0,0 +1,62 @@
+import MockAdapter from 'axios-mock-adapter';
+import * as projectsApi from '~/api/projects_api';
+import axios from '~/lib/utils/axios_utils';
+
+describe('~/api/projects_api.js', () => {
+ let mock;
+ let originalGon;
+
+ const projectId = 1;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+
+ originalGon = window.gon;
+ window.gon = { api_version: 'v7' };
+ });
+
+ afterEach(() => {
+ mock.restore();
+ window.gon = originalGon;
+ });
+
+ describe('getProjects', () => {
+ beforeEach(() => {
+ jest.spyOn(axios, 'get');
+ });
+
+ it('retrieves projects from the correct URL and returns them in the response data', () => {
+ const expectedUrl = '/api/v7/projects.json';
+ const expectedParams = { params: { per_page: 20, search: '', simple: true } };
+ const expectedProjects = [{ name: 'project 1' }];
+ const query = '';
+ const options = {};
+
+ mock.onGet(expectedUrl).reply(200, { data: expectedProjects });
+
+ return projectsApi.getProjects(query, options).then(({ data }) => {
+ expect(axios.get).toHaveBeenCalledWith(expectedUrl, expectedParams);
+ expect(data.data).toEqual(expectedProjects);
+ });
+ });
+ });
+
+ describe('importProjectMembers', () => {
+ beforeEach(() => {
+ jest.spyOn(axios, 'post');
+ });
+
+ it('posts to the correct URL and returns the response message', () => {
+ const targetId = 2;
+ const expectedUrl = '/api/v7/projects/1/import_project_members/2';
+ const expectedMessage = 'Successfully imported';
+
+ mock.onPost(expectedUrl).replyOnce(200, expectedMessage);
+
+ return projectsApi.importProjectMembers(projectId, targetId).then(({ data }) => {
+ expect(axios.post).toHaveBeenCalledWith(expectedUrl);
+ expect(data).toEqual(expectedMessage);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/authentication/two_factor_auth/components/recovery_codes_spec.js b/spec/frontend/authentication/two_factor_auth/components/recovery_codes_spec.js
index b77def195b6..2dcc537809f 100644
--- a/spec/frontend/authentication/two_factor_auth/components/recovery_codes_spec.js
+++ b/spec/frontend/authentication/two_factor_auth/components/recovery_codes_spec.js
@@ -78,7 +78,7 @@ describe('RecoveryCodes', () => {
it('fires Snowplow event', () => {
expect(findProceedButton().attributes()).toMatchObject({
- 'data-track-event': 'click_button',
+ 'data-track-action': 'click_button',
'data-track-label': '2fa_recovery_codes_proceed_button',
});
});
diff --git a/spec/frontend/autosave_spec.js b/spec/frontend/autosave_spec.js
index bbdf3c6f91d..c881e0f9794 100644
--- a/spec/frontend/autosave_spec.js
+++ b/spec/frontend/autosave_spec.js
@@ -15,28 +15,28 @@ describe('Autosave', () => {
describe('class constructor', () => {
beforeEach(() => {
- jest.spyOn(AccessorUtilities, 'isLocalStorageAccessSafe').mockReturnValue(true);
+ jest.spyOn(AccessorUtilities, 'canUseLocalStorage').mockReturnValue(true);
jest.spyOn(Autosave.prototype, 'restore').mockImplementation(() => {});
});
it('should set .isLocalStorageAvailable', () => {
autosave = new Autosave(field, key);
- expect(AccessorUtilities.isLocalStorageAccessSafe).toHaveBeenCalled();
+ expect(AccessorUtilities.canUseLocalStorage).toHaveBeenCalled();
expect(autosave.isLocalStorageAvailable).toBe(true);
});
it('should set .isLocalStorageAvailable if fallbackKey is passed', () => {
autosave = new Autosave(field, key, fallbackKey);
- expect(AccessorUtilities.isLocalStorageAccessSafe).toHaveBeenCalled();
+ expect(AccessorUtilities.canUseLocalStorage).toHaveBeenCalled();
expect(autosave.isLocalStorageAvailable).toBe(true);
});
it('should set .isLocalStorageAvailable if lockVersion is passed', () => {
autosave = new Autosave(field, key, null, lockVersion);
- expect(AccessorUtilities.isLocalStorageAccessSafe).toHaveBeenCalled();
+ expect(AccessorUtilities.canUseLocalStorage).toHaveBeenCalled();
expect(autosave.isLocalStorageAvailable).toBe(true);
});
});
diff --git a/spec/frontend/batch_comments/components/review_bar_spec.js b/spec/frontend/batch_comments/components/review_bar_spec.js
new file mode 100644
index 00000000000..f50db6ab210
--- /dev/null
+++ b/spec/frontend/batch_comments/components/review_bar_spec.js
@@ -0,0 +1,42 @@
+import { shallowMount } from '@vue/test-utils';
+import ReviewBar from '~/batch_comments/components/review_bar.vue';
+import { REVIEW_BAR_VISIBLE_CLASS_NAME } from '~/batch_comments/constants';
+import createStore from '../create_batch_comments_store';
+
+describe('Batch comments review bar component', () => {
+ let store;
+ let wrapper;
+
+ const createComponent = (propsData = {}) => {
+ store = createStore();
+
+ wrapper = shallowMount(ReviewBar, {
+ store,
+ propsData,
+ });
+ };
+
+ beforeEach(() => {
+ document.body.className = '';
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('it adds review-bar-visible class to body when review bar is mounted', async () => {
+ expect(document.body.classList.contains(REVIEW_BAR_VISIBLE_CLASS_NAME)).toBe(false);
+
+ createComponent();
+
+ expect(document.body.classList.contains(REVIEW_BAR_VISIBLE_CLASS_NAME)).toBe(true);
+ });
+
+ it('it removes review-bar-visible class to body when review bar is destroyed', async () => {
+ createComponent();
+
+ wrapper.destroy();
+
+ expect(document.body.classList.contains(REVIEW_BAR_VISIBLE_CLASS_NAME)).toBe(false);
+ });
+});
diff --git a/spec/frontend/batch_comments/create_batch_comments_store.js b/spec/frontend/batch_comments/create_batch_comments_store.js
new file mode 100644
index 00000000000..10dc6fe196e
--- /dev/null
+++ b/spec/frontend/batch_comments/create_batch_comments_store.js
@@ -0,0 +1,15 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import batchCommentsModule from '~/batch_comments/stores/modules/batch_comments';
+import notesModule from '~/notes/stores/modules';
+
+Vue.use(Vuex);
+
+export default function createDiffsStore() {
+ return new Vuex.Store({
+ modules: {
+ notes: notesModule(),
+ batchComments: batchCommentsModule(),
+ },
+ });
+}
diff --git a/spec/frontend/blob/notebook/notebook_viever_spec.js b/spec/frontend/blob/notebook/notebook_viever_spec.js
index 604104bb31f..93406db2675 100644
--- a/spec/frontend/blob/notebook/notebook_viever_spec.js
+++ b/spec/frontend/blob/notebook/notebook_viever_spec.js
@@ -11,6 +11,7 @@ describe('iPython notebook renderer', () => {
let mock;
const endpoint = 'test';
+ const relativeRawPath = '';
const mockNotebook = {
cells: [
{
@@ -27,7 +28,7 @@ describe('iPython notebook renderer', () => {
};
const mountComponent = () => {
- wrapper = shallowMount(component, { propsData: { endpoint } });
+ wrapper = shallowMount(component, { propsData: { endpoint, relativeRawPath } });
};
const findLoading = () => wrapper.find(GlLoadingIcon);
diff --git a/spec/frontend/boards/board_card_inner_spec.js b/spec/frontend/boards/board_card_inner_spec.js
index 7d3ecc773a6..e0446811f64 100644
--- a/spec/frontend/boards/board_card_inner_spec.js
+++ b/spec/frontend/boards/board_card_inner_spec.js
@@ -2,6 +2,7 @@ import { GlLabel, GlLoadingIcon, GlTooltip } from '@gitlab/ui';
import { range } from 'lodash';
import Vuex from 'vuex';
import setWindowLocation from 'helpers/set_window_location_helper';
+import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import BoardBlockedIcon from '~/boards/components/board_blocked_icon.vue';
import BoardCardInner from '~/boards/components/board_card_inner.vue';
@@ -44,6 +45,7 @@ describe('Board card component', () => {
const findEpicBadgeProgress = () => wrapper.findByTestId('epic-progress');
const findEpicCountablesTotalWeight = () => wrapper.findByTestId('epic-countables-total-weight');
const findEpicProgressTooltip = () => wrapper.findByTestId('epic-progress-tooltip-content');
+ const findHiddenIssueIcon = () => wrapper.findByTestId('hidden-icon');
const createStore = ({ isEpicBoard = false, isProjectBoard = false } = {}) => {
store = new Vuex.Store({
@@ -72,6 +74,9 @@ describe('Board card component', () => {
GlLabel: true,
GlLoadingIcon: true,
},
+ directives: {
+ GlTooltip: createMockDirective(),
+ },
mocks: {
$apollo: {
queries: {
@@ -122,6 +127,10 @@ describe('Board card component', () => {
expect(wrapper.find('.confidential-icon').exists()).toBe(false);
});
+ it('does not render hidden issue icon', () => {
+ expect(findHiddenIssueIcon().exists()).toBe(false);
+ });
+
it('renders issue ID with #', () => {
expect(wrapper.find('.board-card-number').text()).toContain(`#${issue.iid}`);
});
@@ -184,6 +193,30 @@ describe('Board card component', () => {
});
});
+ describe('hidden issue', () => {
+ beforeEach(() => {
+ wrapper.setProps({
+ item: {
+ ...wrapper.props('item'),
+ hidden: true,
+ },
+ });
+ });
+
+ it('renders hidden issue icon', () => {
+ expect(findHiddenIssueIcon().exists()).toBe(true);
+ });
+
+ it('displays a tooltip which explains the meaning of the icon', () => {
+ const tooltip = getBinding(findHiddenIssueIcon().element, 'gl-tooltip');
+
+ expect(tooltip).toBeDefined();
+ expect(findHiddenIssueIcon().attributes('title')).toBe(
+ 'This issue is hidden because its author has been banned',
+ );
+ });
+ });
+
describe('with assignee', () => {
describe('with avatar', () => {
beforeEach(() => {
diff --git a/spec/frontend/boards/board_list_deprecated_spec.js b/spec/frontend/boards/board_list_deprecated_spec.js
deleted file mode 100644
index b71564f7858..00000000000
--- a/spec/frontend/boards/board_list_deprecated_spec.js
+++ /dev/null
@@ -1,274 +0,0 @@
-/* global List */
-/* global ListIssue */
-import MockAdapter from 'axios-mock-adapter';
-import Vue from 'vue';
-import waitForPromises from 'helpers/wait_for_promises';
-import BoardList from '~/boards/components/board_list_deprecated.vue';
-import eventHub from '~/boards/eventhub';
-import store from '~/boards/stores';
-import boardsStore from '~/boards/stores/boards_store';
-import axios from '~/lib/utils/axios_utils';
-import '~/boards/models/issue';
-import '~/boards/models/list';
-import { listObj, boardsMockInterceptor } from './mock_data';
-
-const createComponent = ({ done, listIssueProps = {}, componentProps = {}, listProps = {} }) => {
- const el = document.createElement('div');
-
- document.body.appendChild(el);
- const mock = new MockAdapter(axios);
- mock.onAny().reply(boardsMockInterceptor);
- boardsStore.create();
-
- const BoardListComp = Vue.extend(BoardList);
- const list = new List({ ...listObj, ...listProps });
- const issue = new ListIssue({
- title: 'Testing',
- id: 1,
- iid: 1,
- confidential: false,
- labels: [],
- assignees: [],
- ...listIssueProps,
- });
- if (!Object.prototype.hasOwnProperty.call(listProps, 'issuesSize')) {
- list.issuesSize = 1;
- }
- list.issues.push(issue);
-
- const component = new BoardListComp({
- el,
- store,
- propsData: {
- disabled: false,
- list,
- issues: list.issues,
- ...componentProps,
- },
- provide: {
- groupId: null,
- rootPath: '/',
- },
- }).$mount();
-
- Vue.nextTick(() => {
- done();
- });
-
- return { component, mock };
-};
-
-describe('Board list component', () => {
- let mock;
- let component;
- let getIssues;
- function generateIssues(compWrapper) {
- for (let i = 1; i < 20; i += 1) {
- const issue = { ...compWrapper.list.issues[0] };
- issue.id += i;
- compWrapper.list.issues.push(issue);
- }
- }
-
- describe('When Expanded', () => {
- beforeEach((done) => {
- getIssues = jest.spyOn(List.prototype, 'getIssues').mockReturnValue(new Promise(() => {}));
- ({ mock, component } = createComponent({ done }));
- });
-
- afterEach(() => {
- mock.restore();
- component.$destroy();
- });
-
- it('loads first page of issues', () => {
- return waitForPromises().then(() => {
- expect(getIssues).toHaveBeenCalled();
- });
- });
-
- it('renders component', () => {
- expect(component.$el.classList.contains('board-list-component')).toBe(true);
- });
-
- it('renders loading icon', () => {
- component.list.loading = true;
-
- return Vue.nextTick().then(() => {
- expect(component.$el.querySelector('.board-list-loading')).not.toBeNull();
- });
- });
-
- it('renders issues', () => {
- expect(component.$el.querySelectorAll('.board-card').length).toBe(1);
- });
-
- it('sets data attribute with issue id', () => {
- expect(component.$el.querySelector('.board-card').getAttribute('data-issue-id')).toBe('1');
- });
-
- it('shows new issue form', () => {
- component.toggleForm();
-
- return Vue.nextTick().then(() => {
- expect(component.$el.querySelector('.board-new-issue-form')).not.toBeNull();
-
- expect(component.$el.querySelector('.is-smaller')).not.toBeNull();
- });
- });
-
- it('shows new issue form after eventhub event', () => {
- eventHub.$emit(`toggle-issue-form-${component.list.id}`);
-
- return Vue.nextTick().then(() => {
- expect(component.$el.querySelector('.board-new-issue-form')).not.toBeNull();
-
- expect(component.$el.querySelector('.is-smaller')).not.toBeNull();
- });
- });
-
- it('does not show new issue form for closed list', () => {
- component.list.type = 'closed';
- component.toggleForm();
-
- return Vue.nextTick().then(() => {
- expect(component.$el.querySelector('.board-new-issue-form')).toBeNull();
- });
- });
-
- it('shows count list item', () => {
- component.showCount = true;
-
- return Vue.nextTick().then(() => {
- expect(component.$el.querySelector('.board-list-count')).not.toBeNull();
-
- expect(component.$el.querySelector('.board-list-count').textContent.trim()).toBe(
- 'Showing all issues',
- );
- });
- });
-
- it('sets data attribute with invalid id', () => {
- component.showCount = true;
-
- return Vue.nextTick().then(() => {
- expect(component.$el.querySelector('.board-list-count').getAttribute('data-issue-id')).toBe(
- '-1',
- );
- });
- });
-
- it('shows how many more issues to load', () => {
- component.showCount = true;
- component.list.issuesSize = 20;
-
- return Vue.nextTick().then(() => {
- expect(component.$el.querySelector('.board-list-count').textContent.trim()).toBe(
- 'Showing 1 of 20 issues',
- );
- });
- });
-
- it('loads more issues after scrolling', () => {
- jest.spyOn(component.list, 'nextPage').mockImplementation(() => {});
- generateIssues(component);
- component.$refs.list.dispatchEvent(new Event('scroll'));
-
- return waitForPromises().then(() => {
- expect(component.list.nextPage).toHaveBeenCalled();
- });
- });
-
- it('does not load issues if already loading', () => {
- component.list.nextPage = jest
- .spyOn(component.list, 'nextPage')
- .mockReturnValue(new Promise(() => {}));
-
- component.onScroll();
- component.onScroll();
-
- return waitForPromises().then(() => {
- expect(component.list.nextPage).toHaveBeenCalledTimes(1);
- });
- });
-
- it('shows loading more spinner', () => {
- component.showCount = true;
- component.list.loadingMore = true;
-
- return Vue.nextTick().then(() => {
- expect(component.$el.querySelector('.board-list-count .gl-spinner')).not.toBeNull();
- });
- });
- });
-
- describe('When Collapsed', () => {
- beforeEach((done) => {
- getIssues = jest.spyOn(List.prototype, 'getIssues').mockReturnValue(new Promise(() => {}));
- ({ mock, component } = createComponent({
- done,
- listProps: { type: 'closed', collapsed: true, issuesSize: 50 },
- }));
- generateIssues(component);
- component.scrollHeight = jest.spyOn(component, 'scrollHeight').mockReturnValue(0);
- });
-
- afterEach(() => {
- mock.restore();
- component.$destroy();
- });
-
- it('does not load all issues', () => {
- return waitForPromises().then(() => {
- // Initial getIssues from list constructor
- expect(getIssues).toHaveBeenCalledTimes(1);
- });
- });
- });
-
- describe('max issue count warning', () => {
- beforeEach((done) => {
- ({ mock, component } = createComponent({
- done,
- listProps: { type: 'closed', collapsed: true, issuesSize: 50 },
- }));
- });
-
- afterEach(() => {
- mock.restore();
- component.$destroy();
- });
-
- describe('when issue count exceeds max issue count', () => {
- it('sets background to bg-danger-100', () => {
- component.list.issuesSize = 4;
- component.list.maxIssueCount = 3;
-
- return Vue.nextTick().then(() => {
- expect(component.$el.querySelector('.bg-danger-100')).not.toBeNull();
- });
- });
- });
-
- describe('when list issue count does NOT exceed list max issue count', () => {
- it('does not sets background to bg-danger-100', () => {
- component.list.issuesSize = 2;
- component.list.maxIssueCount = 3;
-
- return Vue.nextTick().then(() => {
- expect(component.$el.querySelector('.bg-danger-100')).toBeNull();
- });
- });
- });
-
- describe('when list max issue count is 0', () => {
- it('does not sets background to bg-danger-100', () => {
- component.list.maxIssueCount = 0;
-
- return Vue.nextTick().then(() => {
- expect(component.$el.querySelector('.bg-danger-100')).toBeNull();
- });
- });
- });
- });
-});
diff --git a/spec/frontend/boards/board_new_issue_deprecated_spec.js b/spec/frontend/boards/board_new_issue_deprecated_spec.js
deleted file mode 100644
index 3beaf870bf5..00000000000
--- a/spec/frontend/boards/board_new_issue_deprecated_spec.js
+++ /dev/null
@@ -1,211 +0,0 @@
-/* global List */
-
-import { mount } from '@vue/test-utils';
-import MockAdapter from 'axios-mock-adapter';
-import Vue from 'vue';
-import Vuex from 'vuex';
-import boardNewIssue from '~/boards/components/board_new_issue_deprecated.vue';
-import boardsStore from '~/boards/stores/boards_store';
-import axios from '~/lib/utils/axios_utils';
-
-import '~/boards/models/list';
-import { listObj, boardsMockInterceptor } from './mock_data';
-
-Vue.use(Vuex);
-
-describe('Issue boards new issue form', () => {
- let wrapper;
- let vm;
- let list;
- let mock;
- let newIssueMock;
- const promiseReturn = {
- data: {
- iid: 100,
- },
- };
-
- const submitIssue = () => {
- const dummySubmitEvent = {
- preventDefault() {},
- };
- wrapper.vm.$refs.submitButton = wrapper.find({ ref: 'submitButton' });
- return wrapper.vm.submit(dummySubmitEvent);
- };
-
- beforeEach(() => {
- const BoardNewIssueComp = Vue.extend(boardNewIssue);
-
- mock = new MockAdapter(axios);
- mock.onAny().reply(boardsMockInterceptor);
-
- boardsStore.create();
-
- list = new List(listObj);
-
- newIssueMock = Promise.resolve(promiseReturn);
- jest.spyOn(list, 'newIssue').mockImplementation(() => newIssueMock);
-
- const store = new Vuex.Store({
- getters: { isGroupBoard: () => false },
- });
-
- wrapper = mount(BoardNewIssueComp, {
- propsData: {
- disabled: false,
- list,
- },
- store,
- provide: {
- groupId: null,
- },
- });
-
- vm = wrapper.vm;
-
- return Vue.nextTick();
- });
-
- afterEach(() => {
- wrapper.destroy();
- mock.restore();
- });
-
- it('calls submit if submit button is clicked', () => {
- jest.spyOn(wrapper.vm, 'submit').mockImplementation();
- vm.title = 'Testing Title';
-
- return Vue.nextTick()
- .then(submitIssue)
- .then(() => {
- expect(wrapper.vm.submit).toHaveBeenCalled();
- });
- });
-
- it('disables submit button if title is empty', () => {
- expect(wrapper.find({ ref: 'submitButton' }).props().disabled).toBe(true);
- });
-
- it('enables submit button if title is not empty', () => {
- wrapper.setData({ title: 'Testing Title' });
-
- return Vue.nextTick().then(() => {
- expect(wrapper.find({ ref: 'input' }).element.value).toBe('Testing Title');
- expect(wrapper.find({ ref: 'submitButton' }).props().disabled).toBe(false);
- });
- });
-
- it('clears title after clicking cancel', () => {
- wrapper.find({ ref: 'cancelButton' }).trigger('click');
-
- return Vue.nextTick().then(() => {
- expect(vm.title).toBe('');
- });
- });
-
- it('does not create new issue if title is empty', () => {
- return submitIssue().then(() => {
- expect(list.newIssue).not.toHaveBeenCalled();
- });
- });
-
- describe('submit success', () => {
- it('creates new issue', () => {
- wrapper.setData({ title: 'create issue' });
-
- return Vue.nextTick()
- .then(submitIssue)
- .then(() => {
- expect(list.newIssue).toHaveBeenCalled();
- });
- });
-
- it('enables button after submit', () => {
- jest.spyOn(wrapper.vm, 'submit').mockImplementation();
- wrapper.setData({ title: 'create issue' });
-
- return Vue.nextTick()
- .then(submitIssue)
- .then(() => {
- expect(wrapper.vm.$refs.submitButton.props().disabled).toBe(false);
- });
- });
-
- it('clears title after submit', () => {
- wrapper.setData({ title: 'create issue' });
-
- return Vue.nextTick()
- .then(submitIssue)
- .then(() => {
- expect(vm.title).toBe('');
- });
- });
-
- it('sets detail issue after submit', () => {
- expect(boardsStore.detail.issue.title).toBe(undefined);
- wrapper.setData({ title: 'create issue' });
-
- return Vue.nextTick()
- .then(submitIssue)
- .then(() => {
- expect(boardsStore.detail.issue.title).toBe('create issue');
- });
- });
-
- it('sets detail list after submit', () => {
- wrapper.setData({ title: 'create issue' });
-
- return Vue.nextTick()
- .then(submitIssue)
- .then(() => {
- expect(boardsStore.detail.list.id).toBe(list.id);
- });
- });
-
- it('sets detail weight after submit', () => {
- boardsStore.weightFeatureAvailable = true;
- wrapper.setData({ title: 'create issue' });
-
- return Vue.nextTick()
- .then(submitIssue)
- .then(() => {
- expect(boardsStore.detail.list.weight).toBe(list.weight);
- });
- });
-
- it('does not set detail weight after submit', () => {
- boardsStore.weightFeatureAvailable = false;
- wrapper.setData({ title: 'create issue' });
-
- return Vue.nextTick()
- .then(submitIssue)
- .then(() => {
- expect(boardsStore.detail.list.weight).toBe(list.weight);
- });
- });
- });
-
- describe('submit error', () => {
- beforeEach(() => {
- newIssueMock = Promise.reject(new Error('My hovercraft is full of eels!'));
- vm.title = 'error';
- });
-
- it('removes issue', () => {
- const lengthBefore = list.issues.length;
- return Vue.nextTick()
- .then(submitIssue)
- .then(() => {
- expect(list.issues.length).toBe(lengthBefore);
- });
- });
-
- it('shows error', () => {
- return Vue.nextTick()
- .then(submitIssue)
- .then(() => {
- expect(vm.error).toBe(true);
- });
- });
- });
-});
diff --git a/spec/frontend/boards/boards_store_spec.js b/spec/frontend/boards/boards_store_spec.js
deleted file mode 100644
index 02881333273..00000000000
--- a/spec/frontend/boards/boards_store_spec.js
+++ /dev/null
@@ -1,1013 +0,0 @@
-import AxiosMockAdapter from 'axios-mock-adapter';
-import { TEST_HOST } from 'helpers/test_constants';
-import eventHub from '~/boards/eventhub';
-
-import ListIssue from '~/boards/models/issue';
-import List from '~/boards/models/list';
-import boardsStore from '~/boards/stores/boards_store';
-import axios from '~/lib/utils/axios_utils';
-import { listObj, listObjDuplicate } from './mock_data';
-
-jest.mock('js-cookie');
-
-const createTestIssue = () => ({
- title: 'Testing',
- id: 1,
- iid: 1,
- confidential: false,
- labels: [],
- assignees: [],
-});
-
-describe('boardsStore', () => {
- const dummyResponse = "without type checking this doesn't matter";
- const boardId = 'dummy-board-id';
- const endpoints = {
- boardsEndpoint: `${TEST_HOST}/boards`,
- listsEndpoint: `${TEST_HOST}/lists`,
- bulkUpdatePath: `${TEST_HOST}/bulk/update`,
- recentBoardsEndpoint: `${TEST_HOST}/recent/boards`,
- };
-
- let axiosMock;
-
- beforeEach(() => {
- axiosMock = new AxiosMockAdapter(axios);
- boardsStore.setEndpoints({
- ...endpoints,
- boardId,
- });
- });
-
- afterEach(() => {
- axiosMock.restore();
- });
-
- const setupDefaultResponses = () => {
- axiosMock
- .onGet(`${endpoints.listsEndpoint}/${listObj.id}/issues?id=${listObj.id}&page=1`)
- .reply(200, { issues: [createTestIssue()] });
- axiosMock.onPost(endpoints.listsEndpoint).reply(200, listObj);
- axiosMock.onPut();
- };
-
- describe('all', () => {
- it('makes a request to fetch lists', () => {
- axiosMock.onGet(endpoints.listsEndpoint).replyOnce(200, dummyResponse);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.all()).resolves.toEqual(expectedResponse);
- });
-
- it('fails for error response', () => {
- axiosMock.onGet(endpoints.listsEndpoint).replyOnce(500);
-
- return expect(boardsStore.all()).rejects.toThrow();
- });
- });
-
- describe('createList', () => {
- const entityType = 'moorhen';
- const entityId = 'quack';
- const expectedRequest = expect.objectContaining({
- data: JSON.stringify({ list: { [entityType]: entityId } }),
- });
-
- let requestSpy;
-
- beforeEach(() => {
- requestSpy = jest.fn();
- axiosMock.onPost(endpoints.listsEndpoint).replyOnce((config) => requestSpy(config));
- });
-
- it('makes a request to create a list', () => {
- requestSpy.mockReturnValue([200, dummyResponse]);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.createList(entityId, entityType))
- .resolves.toEqual(expectedResponse)
- .then(() => {
- expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
- });
- });
-
- it('fails for error response', () => {
- requestSpy.mockReturnValue([500]);
-
- return expect(boardsStore.createList(entityId, entityType))
- .rejects.toThrow()
- .then(() => {
- expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
- });
- });
- });
-
- describe('updateList', () => {
- const id = 'David Webb';
- const position = 'unknown';
- const collapsed = false;
- const expectedRequest = expect.objectContaining({
- data: JSON.stringify({ list: { position, collapsed } }),
- });
-
- let requestSpy;
-
- beforeEach(() => {
- requestSpy = jest.fn();
- axiosMock.onPut(`${endpoints.listsEndpoint}/${id}`).replyOnce((config) => requestSpy(config));
- });
-
- it('makes a request to update a list position', () => {
- requestSpy.mockReturnValue([200, dummyResponse]);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.updateList(id, position, collapsed))
- .resolves.toEqual(expectedResponse)
- .then(() => {
- expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
- });
- });
-
- it('fails for error response', () => {
- requestSpy.mockReturnValue([500]);
-
- return expect(boardsStore.updateList(id, position, collapsed))
- .rejects.toThrow()
- .then(() => {
- expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
- });
- });
- });
-
- describe('destroyList', () => {
- const id = '-42';
-
- let requestSpy;
-
- beforeEach(() => {
- requestSpy = jest.fn();
- axiosMock
- .onDelete(`${endpoints.listsEndpoint}/${id}`)
- .replyOnce((config) => requestSpy(config));
- });
-
- it('makes a request to delete a list', () => {
- requestSpy.mockReturnValue([200, dummyResponse]);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.destroyList(id))
- .resolves.toEqual(expectedResponse)
- .then(() => {
- expect(requestSpy).toHaveBeenCalled();
- });
- });
-
- it('fails for error response', () => {
- requestSpy.mockReturnValue([500]);
-
- return expect(boardsStore.destroyList(id))
- .rejects.toThrow()
- .then(() => {
- expect(requestSpy).toHaveBeenCalled();
- });
- });
- });
-
- describe('saveList', () => {
- let list;
-
- beforeEach(() => {
- list = new List(listObj);
- setupDefaultResponses();
- });
-
- it('makes a request to save a list', () => {
- const expectedResponse = expect.objectContaining({ issues: [createTestIssue()] });
- const expectedListValue = {
- id: listObj.id,
- position: listObj.position,
- type: listObj.list_type,
- label: listObj.label,
- };
- expect(list.id).toBe(listObj.id);
- expect(list.position).toBe(listObj.position);
- expect(list).toMatchObject(expectedListValue);
-
- return expect(boardsStore.saveList(list)).resolves.toEqual(expectedResponse);
- });
- });
-
- describe('getListIssues', () => {
- let list;
-
- beforeEach(() => {
- list = new List(listObj);
- setupDefaultResponses();
- });
-
- it('makes a request to get issues', () => {
- const expectedResponse = expect.objectContaining({ issues: [createTestIssue()] });
- expect(list.issues).toEqual([]);
-
- return expect(boardsStore.getListIssues(list, true)).resolves.toEqual(expectedResponse);
- });
- });
-
- describe('getIssuesForList', () => {
- const id = 'TOO-MUCH';
- const url = `${endpoints.listsEndpoint}/${id}/issues?id=${id}`;
-
- it('makes a request to fetch list issues', () => {
- axiosMock.onGet(url).replyOnce(200, dummyResponse);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.getIssuesForList(id)).resolves.toEqual(expectedResponse);
- });
-
- it('makes a request to fetch list issues with filter', () => {
- const filter = { algal: 'scrubber' };
- axiosMock.onGet(`${url}&algal=scrubber`).replyOnce(200, dummyResponse);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.getIssuesForList(id, filter)).resolves.toEqual(expectedResponse);
- });
-
- it('fails for error response', () => {
- axiosMock.onGet(url).replyOnce(500);
-
- return expect(boardsStore.getIssuesForList(id)).rejects.toThrow();
- });
- });
-
- describe('moveIssue', () => {
- const urlRoot = 'potato';
- const id = 'over 9000';
- const fromListId = 'left';
- const toListId = 'right';
- const moveBeforeId = 'up';
- const moveAfterId = 'down';
- const expectedRequest = expect.objectContaining({
- data: JSON.stringify({
- from_list_id: fromListId,
- to_list_id: toListId,
- move_before_id: moveBeforeId,
- move_after_id: moveAfterId,
- }),
- });
-
- let requestSpy;
-
- beforeAll(() => {
- global.gon.relative_url_root = urlRoot;
- });
-
- afterAll(() => {
- delete global.gon.relative_url_root;
- });
-
- beforeEach(() => {
- requestSpy = jest.fn();
- axiosMock
- .onPut(`${urlRoot}/-/boards/${boardId}/issues/${id}`)
- .replyOnce((config) => requestSpy(config));
- });
-
- it('makes a request to move an issue between lists', () => {
- requestSpy.mockReturnValue([200, dummyResponse]);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.moveIssue(id, fromListId, toListId, moveBeforeId, moveAfterId))
- .resolves.toEqual(expectedResponse)
- .then(() => {
- expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
- });
- });
-
- it('fails for error response', () => {
- requestSpy.mockReturnValue([500]);
-
- return expect(boardsStore.moveIssue(id, fromListId, toListId, moveBeforeId, moveAfterId))
- .rejects.toThrow()
- .then(() => {
- expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
- });
- });
- });
-
- describe('newIssue', () => {
- const id = 1;
- const issue = { some: 'issue data' };
- const url = `${endpoints.listsEndpoint}/${id}/issues`;
- const expectedRequest = expect.objectContaining({
- data: JSON.stringify({
- issue,
- }),
- });
-
- let requestSpy;
-
- beforeEach(() => {
- requestSpy = jest.fn();
- axiosMock.onPost(url).replyOnce((config) => requestSpy(config));
- });
-
- it('makes a request to create a new issue', () => {
- requestSpy.mockReturnValue([200, dummyResponse]);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.newIssue(id, issue))
- .resolves.toEqual(expectedResponse)
- .then(() => {
- expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
- });
- });
-
- it('fails for error response', () => {
- requestSpy.mockReturnValue([500]);
-
- return expect(boardsStore.newIssue(id, issue))
- .rejects.toThrow()
- .then(() => {
- expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
- });
- });
- });
-
- describe('getBacklog', () => {
- const urlRoot = 'deep';
- const url = `${urlRoot}/-/boards/${boardId}/issues.json?not=relevant`;
- const requestParams = {
- not: 'relevant',
- };
-
- beforeAll(() => {
- global.gon.relative_url_root = urlRoot;
- });
-
- afterAll(() => {
- delete global.gon.relative_url_root;
- });
-
- it('makes a request to fetch backlog', () => {
- axiosMock.onGet(url).replyOnce(200, dummyResponse);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.getBacklog(requestParams)).resolves.toEqual(expectedResponse);
- });
-
- it('fails for error response', () => {
- axiosMock.onGet(url).replyOnce(500);
-
- return expect(boardsStore.getBacklog(requestParams)).rejects.toThrow();
- });
- });
-
- describe('bulkUpdate', () => {
- const issueIds = [1, 2, 3];
- const extraData = { moar: 'data' };
- const expectedRequest = expect.objectContaining({
- data: JSON.stringify({
- update: {
- ...extraData,
- issuable_ids: '1,2,3',
- },
- }),
- });
-
- let requestSpy;
-
- beforeEach(() => {
- requestSpy = jest.fn();
- axiosMock.onPost(endpoints.bulkUpdatePath).replyOnce((config) => requestSpy(config));
- });
-
- it('makes a request to create a list', () => {
- requestSpy.mockReturnValue([200, dummyResponse]);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.bulkUpdate(issueIds, extraData))
- .resolves.toEqual(expectedResponse)
- .then(() => {
- expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
- });
- });
-
- it('fails for error response', () => {
- requestSpy.mockReturnValue([500]);
-
- return expect(boardsStore.bulkUpdate(issueIds, extraData))
- .rejects.toThrow()
- .then(() => {
- expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
- });
- });
- });
-
- describe('getIssueInfo', () => {
- const dummyEndpoint = `${TEST_HOST}/some/where`;
-
- it('makes a request to the given endpoint', () => {
- axiosMock.onGet(dummyEndpoint).replyOnce(200, dummyResponse);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.getIssueInfo(dummyEndpoint)).resolves.toEqual(expectedResponse);
- });
-
- it('fails for error response', () => {
- axiosMock.onGet(dummyEndpoint).replyOnce(500);
-
- return expect(boardsStore.getIssueInfo(dummyEndpoint)).rejects.toThrow();
- });
- });
-
- describe('toggleIssueSubscription', () => {
- const dummyEndpoint = `${TEST_HOST}/some/where`;
-
- it('makes a request to the given endpoint', () => {
- axiosMock.onPost(dummyEndpoint).replyOnce(200, dummyResponse);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.toggleIssueSubscription(dummyEndpoint)).resolves.toEqual(
- expectedResponse,
- );
- });
-
- it('fails for error response', () => {
- axiosMock.onPost(dummyEndpoint).replyOnce(500);
-
- return expect(boardsStore.toggleIssueSubscription(dummyEndpoint)).rejects.toThrow();
- });
- });
-
- describe('recentBoards', () => {
- const url = `${endpoints.recentBoardsEndpoint}.json`;
-
- it('makes a request to fetch all boards', () => {
- axiosMock.onGet(url).replyOnce(200, dummyResponse);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.recentBoards()).resolves.toEqual(expectedResponse);
- });
-
- it('fails for error response', () => {
- axiosMock.onGet(url).replyOnce(500);
-
- return expect(boardsStore.recentBoards()).rejects.toThrow();
- });
- });
-
- describe('when created', () => {
- beforeEach(() => {
- setupDefaultResponses();
-
- jest.spyOn(boardsStore, 'moveIssue').mockReturnValue(Promise.resolve());
- jest.spyOn(boardsStore, 'moveMultipleIssues').mockReturnValue(Promise.resolve());
-
- boardsStore.create();
- });
-
- it('starts with a blank state', () => {
- expect(boardsStore.state.lists.length).toBe(0);
- });
-
- describe('addList', () => {
- it('sorts by position', () => {
- boardsStore.addList({ position: 2 });
- boardsStore.addList({ position: 1 });
-
- expect(boardsStore.state.lists.map(({ position }) => position)).toEqual([1, 2]);
- });
- });
-
- describe('toggleFilter', () => {
- const dummyFilter = 'x=42';
- let updateTokensSpy;
-
- beforeEach(() => {
- updateTokensSpy = jest.fn();
- eventHub.$once('updateTokens', updateTokensSpy);
-
- // prevent using window.history
- jest.spyOn(boardsStore, 'updateFiltersUrl').mockReturnValue();
- });
-
- it('adds the filter if it is not present', () => {
- boardsStore.filter.path = 'something';
-
- boardsStore.toggleFilter(dummyFilter);
-
- expect(boardsStore.filter.path).toEqual(`something&${dummyFilter}`);
- expect(updateTokensSpy).toHaveBeenCalled();
- expect(boardsStore.updateFiltersUrl).toHaveBeenCalled();
- });
-
- it('removes the filter if it is present', () => {
- boardsStore.filter.path = `something&${dummyFilter}`;
-
- boardsStore.toggleFilter(dummyFilter);
-
- expect(boardsStore.filter.path).toEqual('something');
- expect(updateTokensSpy).toHaveBeenCalled();
- expect(boardsStore.updateFiltersUrl).toHaveBeenCalled();
- });
- });
-
- describe('lists', () => {
- it('creates new list without persisting to DB', () => {
- expect(boardsStore.state.lists.length).toBe(0);
-
- boardsStore.addList(listObj);
-
- expect(boardsStore.state.lists.length).toBe(1);
- });
-
- it('finds list by ID', () => {
- boardsStore.addList(listObj);
- const list = boardsStore.findList('id', listObj.id);
-
- expect(list.id).toBe(listObj.id);
- });
-
- it('finds list by type', () => {
- boardsStore.addList(listObj);
- const list = boardsStore.findList('type', 'label');
-
- expect(list).toBeDefined();
- });
-
- it('finds list by label ID', () => {
- boardsStore.addList(listObj);
- const list = boardsStore.findListByLabelId(listObj.label.id);
-
- expect(list.id).toBe(listObj.id);
- });
-
- it('gets issue when new list added', () => {
- boardsStore.addList(listObj);
- const list = boardsStore.findList('id', listObj.id);
-
- expect(boardsStore.state.lists.length).toBe(1);
-
- return axios.waitForAll().then(() => {
- expect(list.issues.length).toBe(1);
- expect(list.issues[0].id).toBe(1);
- });
- });
-
- it('persists new list', () => {
- boardsStore.new({
- title: 'Test',
- list_type: 'label',
- label: {
- id: 1,
- title: 'Testing',
- color: 'red',
- description: 'testing;',
- },
- });
-
- expect(boardsStore.state.lists.length).toBe(1);
-
- return axios.waitForAll().then(() => {
- const list = boardsStore.findList('id', listObj.id);
-
- expect(list).toEqual(
- expect.objectContaining({
- id: listObj.id,
- position: 0,
- }),
- );
- });
- });
-
- it('removes list from state', () => {
- boardsStore.addList(listObj);
-
- expect(boardsStore.state.lists.length).toBe(1);
-
- boardsStore.removeList(listObj.id);
-
- expect(boardsStore.state.lists.length).toBe(0);
- });
-
- it('moves the position of lists', () => {
- const listOne = boardsStore.addList(listObj);
- boardsStore.addList(listObjDuplicate);
-
- expect(boardsStore.state.lists.length).toBe(2);
-
- boardsStore.moveList(listOne, [listObjDuplicate.id, listObj.id]);
-
- expect(listOne.position).toBe(1);
- });
-
- it('moves an issue from one list to another', () => {
- const listOne = boardsStore.addList(listObj);
- const listTwo = boardsStore.addList(listObjDuplicate);
-
- expect(boardsStore.state.lists.length).toBe(2);
-
- return axios.waitForAll().then(() => {
- expect(listOne.issues.length).toBe(1);
- expect(listTwo.issues.length).toBe(1);
-
- boardsStore.moveIssueToList(listOne, listTwo, listOne.findIssue(1));
-
- expect(listOne.issues.length).toBe(0);
- expect(listTwo.issues.length).toBe(1);
- });
- });
-
- it('moves an issue from backlog to a list', () => {
- const backlog = boardsStore.addList({
- ...listObj,
- list_type: 'backlog',
- });
- const listTwo = boardsStore.addList(listObjDuplicate);
-
- expect(boardsStore.state.lists.length).toBe(2);
-
- return axios.waitForAll().then(() => {
- expect(backlog.issues.length).toBe(1);
- expect(listTwo.issues.length).toBe(1);
-
- boardsStore.moveIssueToList(backlog, listTwo, backlog.findIssue(1));
-
- expect(backlog.issues.length).toBe(0);
- expect(listTwo.issues.length).toBe(1);
- });
- });
-
- it('moves issue to top of another list', () => {
- const listOne = boardsStore.addList(listObj);
- const listTwo = boardsStore.addList(listObjDuplicate);
-
- expect(boardsStore.state.lists.length).toBe(2);
-
- return axios.waitForAll().then(() => {
- listOne.issues[0].id = 2;
-
- expect(listOne.issues.length).toBe(1);
- expect(listTwo.issues.length).toBe(1);
-
- boardsStore.moveIssueToList(listOne, listTwo, listOne.findIssue(2), 0);
-
- expect(listOne.issues.length).toBe(0);
- expect(listTwo.issues.length).toBe(2);
- expect(listTwo.issues[0].id).toBe(2);
- expect(boardsStore.moveIssue).toHaveBeenCalledWith(2, listOne.id, listTwo.id, null, 1);
- });
- });
-
- it('moves issue to bottom of another list', () => {
- const listOne = boardsStore.addList(listObj);
- const listTwo = boardsStore.addList(listObjDuplicate);
-
- expect(boardsStore.state.lists.length).toBe(2);
-
- return axios.waitForAll().then(() => {
- listOne.issues[0].id = 2;
-
- expect(listOne.issues.length).toBe(1);
- expect(listTwo.issues.length).toBe(1);
-
- boardsStore.moveIssueToList(listOne, listTwo, listOne.findIssue(2), 1);
-
- expect(listOne.issues.length).toBe(0);
- expect(listTwo.issues.length).toBe(2);
- expect(listTwo.issues[1].id).toBe(2);
- expect(boardsStore.moveIssue).toHaveBeenCalledWith(2, listOne.id, listTwo.id, 1, null);
- });
- });
-
- it('moves issue in list', () => {
- const issue = new ListIssue({
- title: 'Testing',
- id: 2,
- iid: 2,
- confidential: false,
- labels: [],
- assignees: [],
- });
- const list = boardsStore.addList(listObj);
-
- return axios.waitForAll().then(() => {
- list.addIssue(issue);
-
- expect(list.issues.length).toBe(2);
-
- boardsStore.moveIssueInList(list, issue, 0, 1, [1, 2]);
-
- expect(list.issues[0].id).toBe(2);
- expect(boardsStore.moveIssue).toHaveBeenCalledWith(2, null, null, 1, null);
- });
- });
- });
-
- describe('setListDetail', () => {
- it('sets the list detail', () => {
- boardsStore.detail.list = 'not a list';
-
- const dummyValue = 'new list';
- boardsStore.setListDetail(dummyValue);
-
- expect(boardsStore.detail.list).toEqual(dummyValue);
- });
- });
-
- describe('clearDetailIssue', () => {
- it('resets issue details', () => {
- boardsStore.detail.issue = 'something';
-
- boardsStore.clearDetailIssue();
-
- expect(boardsStore.detail.issue).toEqual({});
- });
- });
-
- describe('setIssueDetail', () => {
- it('sets issue details', () => {
- boardsStore.detail.issue = 'some details';
-
- const dummyValue = 'new details';
- boardsStore.setIssueDetail(dummyValue);
-
- expect(boardsStore.detail.issue).toEqual(dummyValue);
- });
- });
-
- describe('startMoving', () => {
- it('stores list and issue', () => {
- const dummyIssue = 'some issue';
- const dummyList = 'some list';
-
- boardsStore.startMoving(dummyList, dummyIssue);
-
- expect(boardsStore.moving.issue).toEqual(dummyIssue);
- expect(boardsStore.moving.list).toEqual(dummyList);
- });
- });
-
- describe('setTimeTrackingLimitToHours', () => {
- it('sets the timeTracking.LimitToHours option', () => {
- boardsStore.timeTracking.limitToHours = false;
-
- boardsStore.setTimeTrackingLimitToHours('true');
-
- expect(boardsStore.timeTracking.limitToHours).toEqual(true);
- });
- });
-
- describe('setCurrentBoard', () => {
- const dummyBoard = 'hoverboard';
-
- it('sets the current board', () => {
- const { state } = boardsStore;
- state.currentBoard = null;
-
- boardsStore.setCurrentBoard(dummyBoard);
-
- expect(state.currentBoard).toEqual(dummyBoard);
- });
- });
-
- describe('toggleMultiSelect', () => {
- let basicIssueObj;
-
- beforeAll(() => {
- basicIssueObj = { id: 987654 };
- });
-
- afterEach(() => {
- boardsStore.clearMultiSelect();
- });
-
- it('adds issue when not present', () => {
- boardsStore.toggleMultiSelect(basicIssueObj);
-
- const selectedIds = boardsStore.multiSelect.list.map(({ id }) => id);
-
- expect(selectedIds.includes(basicIssueObj.id)).toEqual(true);
- });
-
- it('removes issue when issue is present', () => {
- boardsStore.toggleMultiSelect(basicIssueObj);
- let selectedIds = boardsStore.multiSelect.list.map(({ id }) => id);
-
- expect(selectedIds.includes(basicIssueObj.id)).toEqual(true);
-
- boardsStore.toggleMultiSelect(basicIssueObj);
- selectedIds = boardsStore.multiSelect.list.map(({ id }) => id);
-
- expect(selectedIds.includes(basicIssueObj.id)).toEqual(false);
- });
- });
-
- describe('clearMultiSelect', () => {
- it('clears all the multi selected issues', () => {
- const issue1 = { id: 12345 };
- const issue2 = { id: 12346 };
-
- boardsStore.toggleMultiSelect(issue1);
- boardsStore.toggleMultiSelect(issue2);
-
- expect(boardsStore.multiSelect.list.length).toEqual(2);
-
- boardsStore.clearMultiSelect();
-
- expect(boardsStore.multiSelect.list.length).toEqual(0);
- });
- });
-
- describe('moveMultipleIssuesToList', () => {
- it('move issues on the new index', () => {
- const listOne = boardsStore.addList(listObj);
- const listTwo = boardsStore.addList(listObjDuplicate);
-
- expect(boardsStore.state.lists.length).toBe(2);
-
- return axios.waitForAll().then(() => {
- expect(listOne.issues.length).toBe(1);
- expect(listTwo.issues.length).toBe(1);
-
- boardsStore.moveMultipleIssuesToList({
- listFrom: listOne,
- listTo: listTwo,
- issues: listOne.issues,
- newIndex: 0,
- });
-
- expect(listTwo.issues.length).toBe(1);
- });
- });
- });
-
- describe('moveMultipleIssuesInList', () => {
- it('moves multiple issues in list', () => {
- const issueObj = {
- title: 'Issue #1',
- id: 12345,
- iid: 2,
- confidential: false,
- labels: [],
- assignees: [],
- };
- const issue1 = new ListIssue(issueObj);
- const issue2 = new ListIssue({
- ...issueObj,
- title: 'Issue #2',
- id: 12346,
- });
-
- const list = boardsStore.addList(listObj);
-
- return axios.waitForAll().then(() => {
- list.addIssue(issue1);
- list.addIssue(issue2);
-
- expect(list.issues.length).toBe(3);
- expect(list.issues[0].id).not.toBe(issue2.id);
-
- boardsStore.moveMultipleIssuesInList({
- list,
- issues: [issue1, issue2],
- oldIndicies: [0],
- newIndex: 1,
- idArray: [1, 12345, 12346],
- });
-
- expect(list.issues[0].id).toBe(issue1.id);
-
- expect(boardsStore.moveMultipleIssues).toHaveBeenCalledWith({
- ids: [issue1.id, issue2.id],
- fromListId: null,
- toListId: null,
- moveBeforeId: 1,
- moveAfterId: null,
- });
- });
- });
- });
-
- describe('addListIssue', () => {
- let list;
- const issue1 = new ListIssue({
- title: 'Testing',
- id: 2,
- iid: 2,
- confidential: false,
- labels: [
- {
- color: '#ff0000',
- description: 'testing;',
- id: 5000,
- priority: undefined,
- textColor: 'white',
- title: 'Test',
- },
- ],
- assignees: [],
- });
- const issue2 = new ListIssue({
- title: 'Testing',
- id: 1,
- iid: 1,
- confidential: false,
- labels: [
- {
- id: 1,
- title: 'test',
- color: 'red',
- description: 'testing',
- },
- ],
- assignees: [
- {
- id: 1,
- name: 'name',
- username: 'username',
- avatar_url: 'http://avatar_url',
- },
- ],
- real_path: 'path/to/issue',
- });
-
- beforeEach(() => {
- list = new List(listObj);
- list.addIssue(issue1);
- setupDefaultResponses();
- });
-
- it('adds issues that are not already on the list', () => {
- expect(list.findIssue(issue2.id)).toBe(undefined);
- expect(list.issues).toEqual([issue1]);
-
- boardsStore.addListIssue(list, issue2);
- expect(list.findIssue(issue2.id)).toBe(issue2);
- expect(list.issues.length).toBe(2);
- expect(list.issues).toEqual([issue1, issue2]);
- });
- });
-
- describe('updateIssue', () => {
- let issue;
- let patchSpy;
-
- beforeEach(() => {
- issue = new ListIssue({
- title: 'Testing',
- id: 1,
- iid: 1,
- confidential: false,
- labels: [
- {
- id: 1,
- title: 'test',
- color: 'red',
- description: 'testing',
- },
- ],
- assignees: [
- {
- id: 1,
- name: 'name',
- username: 'username',
- avatar_url: 'http://avatar_url',
- },
- ],
- real_path: 'path/to/issue',
- });
-
- patchSpy = jest.fn().mockReturnValue([200, { labels: [] }]);
- axiosMock.onPatch(`path/to/issue.json`).reply(({ data }) => patchSpy(JSON.parse(data)));
- });
-
- it('passes assignee ids when there are assignees', () => {
- boardsStore.updateIssue(issue);
- return boardsStore.updateIssue(issue).then(() => {
- expect(patchSpy).toHaveBeenCalledWith({
- issue: {
- milestone_id: null,
- assignee_ids: [1],
- label_ids: [1],
- },
- });
- });
- });
-
- it('passes assignee ids of [0] when there are no assignees', () => {
- issue.removeAllAssignees();
-
- return boardsStore.updateIssue(issue).then(() => {
- expect(patchSpy).toHaveBeenCalledWith({
- issue: {
- milestone_id: null,
- assignee_ids: [0],
- label_ids: [1],
- },
- });
- });
- });
- });
- });
-});
diff --git a/spec/frontend/boards/components/board_add_new_column_spec.js b/spec/frontend/boards/components/board_add_new_column_spec.js
index 61f210f566b..5fae1c4359f 100644
--- a/spec/frontend/boards/components/board_add_new_column_spec.js
+++ b/spec/frontend/boards/components/board_add_new_column_spec.js
@@ -48,7 +48,6 @@ describe('Board card layout', () => {
...actions,
},
getters: {
- shouldUseGraphQL: () => true,
getListByLabelId: () => getListByLabelId,
},
state: {
diff --git a/spec/frontend/boards/components/board_app_spec.js b/spec/frontend/boards/components/board_app_spec.js
new file mode 100644
index 00000000000..dee097bfb08
--- /dev/null
+++ b/spec/frontend/boards/components/board_app_spec.js
@@ -0,0 +1,54 @@
+import { shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
+import Vuex from 'vuex';
+
+import BoardApp from '~/boards/components/board_app.vue';
+
+describe('BoardApp', () => {
+ let wrapper;
+ let store;
+
+ Vue.use(Vuex);
+
+ const createStore = ({ mockGetters = {} } = {}) => {
+ store = new Vuex.Store({
+ state: {},
+ actions: {
+ performSearch: jest.fn(),
+ },
+ getters: {
+ isSidebarOpen: () => true,
+ ...mockGetters,
+ },
+ });
+ };
+
+ const createComponent = ({ provide = { disabled: true } } = {}) => {
+ wrapper = shallowMount(BoardApp, {
+ store,
+ provide: {
+ ...provide,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ store = null;
+ });
+
+ it("should have 'is-compact' class when sidebar is open", () => {
+ createStore();
+ createComponent();
+
+ expect(wrapper.classes()).toContain('is-compact');
+ });
+
+ it("should not have 'is-compact' class when sidebar is closed", () => {
+ createStore({ mockGetters: { isSidebarOpen: () => false } });
+ createComponent();
+
+ expect(wrapper.classes()).not.toContain('is-compact');
+ });
+});
diff --git a/spec/frontend/boards/components/board_card_deprecated_spec.js b/spec/frontend/boards/components/board_card_deprecated_spec.js
deleted file mode 100644
index 266cbc7106d..00000000000
--- a/spec/frontend/boards/components/board_card_deprecated_spec.js
+++ /dev/null
@@ -1,219 +0,0 @@
-/* global List */
-/* global ListAssignee */
-/* global ListLabel */
-
-import { mount } from '@vue/test-utils';
-
-import MockAdapter from 'axios-mock-adapter';
-import waitForPromises from 'helpers/wait_for_promises';
-import BoardCardDeprecated from '~/boards/components/board_card_deprecated.vue';
-import issueCardInner from '~/boards/components/issue_card_inner_deprecated.vue';
-import eventHub from '~/boards/eventhub';
-import store from '~/boards/stores';
-import boardsStore from '~/boards/stores/boards_store';
-import axios from '~/lib/utils/axios_utils';
-
-import sidebarEventHub from '~/sidebar/event_hub';
-import '~/boards/models/label';
-import '~/boards/models/assignee';
-import '~/boards/models/list';
-import userAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
-import { listObj, boardsMockInterceptor, setMockEndpoints } from '../mock_data';
-
-describe('BoardCard', () => {
- let wrapper;
- let mock;
- let list;
-
- const findIssueCardInner = () => wrapper.find(issueCardInner);
- const findUserAvatarLink = () => wrapper.find(userAvatarLink);
-
- // this particular mount component needs to be used after the root beforeEach because it depends on list being initialized
- const mountComponent = (propsData) => {
- wrapper = mount(BoardCardDeprecated, {
- stubs: {
- issueCardInner,
- },
- store,
- propsData: {
- list,
- issue: list.issues[0],
- disabled: false,
- index: 0,
- ...propsData,
- },
- provide: {
- groupId: null,
- rootPath: '/',
- scopedLabelsAvailable: false,
- },
- });
- };
-
- const setupData = async () => {
- list = new List(listObj);
- boardsStore.create();
- boardsStore.detail.issue = {};
- const label1 = new ListLabel({
- id: 3,
- title: 'testing 123',
- color: '#000cff',
- text_color: 'white',
- description: 'test',
- });
- await waitForPromises();
-
- list.issues[0].labels.push(label1);
- };
-
- beforeEach(() => {
- mock = new MockAdapter(axios);
- mock.onAny().reply(boardsMockInterceptor);
- setMockEndpoints();
- return setupData();
- });
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- list = null;
- mock.restore();
- });
-
- it('when details issue is empty does not show the element', () => {
- mountComponent();
- expect(wrapper.find('[data-testid="board_card"').classes()).not.toContain('is-active');
- });
-
- it('when detailIssue is equal to card issue shows the element', () => {
- [boardsStore.detail.issue] = list.issues;
- mountComponent();
-
- expect(wrapper.classes()).toContain('is-active');
- });
-
- it('when multiSelect does not contain issue removes multi select class', () => {
- mountComponent();
- expect(wrapper.classes()).not.toContain('multi-select');
- });
-
- it('when multiSelect contain issue add multi select class', () => {
- boardsStore.multiSelect.list = [list.issues[0]];
- mountComponent();
-
- expect(wrapper.classes()).toContain('multi-select');
- });
-
- it('adds user-can-drag class if not disabled', () => {
- mountComponent();
- expect(wrapper.classes()).toContain('user-can-drag');
- });
-
- it('does not add user-can-drag class disabled', () => {
- mountComponent({ disabled: true });
-
- expect(wrapper.classes()).not.toContain('user-can-drag');
- });
-
- it('does not add disabled class', () => {
- mountComponent();
- expect(wrapper.classes()).not.toContain('is-disabled');
- });
-
- it('adds disabled class is disabled is true', () => {
- mountComponent({ disabled: true });
-
- expect(wrapper.classes()).toContain('is-disabled');
- });
-
- describe('mouse events', () => {
- it('does not set detail issue if showDetail is false', () => {
- mountComponent();
- expect(boardsStore.detail.issue).toEqual({});
- });
-
- it('does not set detail issue if link is clicked', () => {
- mountComponent();
- findIssueCardInner().find('a').trigger('mouseup');
-
- expect(boardsStore.detail.issue).toEqual({});
- });
-
- it('does not set detail issue if img is clicked', () => {
- mountComponent({
- issue: {
- ...list.issues[0],
- assignees: [
- new ListAssignee({
- id: 1,
- name: 'testing 123',
- username: 'test',
- avatar: 'test_image',
- }),
- ],
- },
- });
-
- findUserAvatarLink().trigger('mouseup');
-
- expect(boardsStore.detail.issue).toEqual({});
- });
-
- it('does not set detail issue if showDetail is false after mouseup', () => {
- mountComponent();
- wrapper.trigger('mouseup');
-
- expect(boardsStore.detail.issue).toEqual({});
- });
-
- it('sets detail issue to card issue on mouse up', () => {
- jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
-
- mountComponent();
-
- wrapper.trigger('mousedown');
- wrapper.trigger('mouseup');
-
- expect(eventHub.$emit).toHaveBeenCalledWith('newDetailIssue', wrapper.vm.issue, false);
- expect(boardsStore.detail.list).toEqual(wrapper.vm.list);
- });
-
- it('resets detail issue to empty if already set', () => {
- jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
- const [issue] = list.issues;
- boardsStore.detail.issue = issue;
- mountComponent();
-
- wrapper.trigger('mousedown');
- wrapper.trigger('mouseup');
-
- expect(eventHub.$emit).toHaveBeenCalledWith('clearDetailIssue', false);
- });
- });
-
- describe('sidebarHub events', () => {
- it('closes all sidebars before showing an issue if no issues are opened', () => {
- jest.spyOn(sidebarEventHub, '$emit').mockImplementation(() => {});
- boardsStore.detail.issue = {};
- mountComponent();
-
- // sets conditional so that event is emitted.
- wrapper.trigger('mousedown');
-
- wrapper.trigger('mouseup');
-
- expect(sidebarEventHub.$emit).toHaveBeenCalledWith('sidebar.closeAll');
- });
-
- it('it does not closes all sidebars before showing an issue if an issue is opened', () => {
- jest.spyOn(sidebarEventHub, '$emit').mockImplementation(() => {});
- const [issue] = list.issues;
- boardsStore.detail.issue = issue;
- mountComponent();
-
- wrapper.trigger('mousedown');
-
- expect(sidebarEventHub.$emit).not.toHaveBeenCalledWith('sidebar.closeAll');
- });
- });
-});
diff --git a/spec/frontend/boards/components/board_card_layout_deprecated_spec.js b/spec/frontend/boards/components/board_card_layout_deprecated_spec.js
deleted file mode 100644
index 9853c9f434f..00000000000
--- a/spec/frontend/boards/components/board_card_layout_deprecated_spec.js
+++ /dev/null
@@ -1,158 +0,0 @@
-/* global List */
-/* global ListLabel */
-
-import { createLocalVue, shallowMount } from '@vue/test-utils';
-
-import MockAdapter from 'axios-mock-adapter';
-import Vuex from 'vuex';
-import waitForPromises from 'helpers/wait_for_promises';
-
-import '~/boards/models/label';
-import '~/boards/models/assignee';
-import '~/boards/models/list';
-import BoardCardLayout from '~/boards/components/board_card_layout_deprecated.vue';
-import issueCardInner from '~/boards/components/issue_card_inner_deprecated.vue';
-import { ISSUABLE } from '~/boards/constants';
-import boardsVuexStore from '~/boards/stores';
-import boardsStore from '~/boards/stores/boards_store';
-import axios from '~/lib/utils/axios_utils';
-import { listObj, boardsMockInterceptor, setMockEndpoints } from '../mock_data';
-
-describe('Board card layout', () => {
- let wrapper;
- let mock;
- let list;
- let store;
-
- const localVue = createLocalVue();
- localVue.use(Vuex);
-
- const createStore = ({ getters = {}, actions = {} } = {}) => {
- store = new Vuex.Store({
- ...boardsVuexStore,
- actions,
- getters,
- });
- };
-
- // this particular mount component needs to be used after the root beforeEach because it depends on list being initialized
- const mountComponent = ({ propsData = {}, provide = {} } = {}) => {
- wrapper = shallowMount(BoardCardLayout, {
- localVue,
- stubs: {
- issueCardInner,
- },
- store,
- propsData: {
- list,
- issue: list.issues[0],
- disabled: false,
- index: 0,
- ...propsData,
- },
- provide: {
- groupId: null,
- rootPath: '/',
- scopedLabelsAvailable: false,
- ...provide,
- },
- });
- };
-
- const setupData = () => {
- list = new List(listObj);
- boardsStore.create();
- boardsStore.detail.issue = {};
- const label1 = new ListLabel({
- id: 3,
- title: 'testing 123',
- color: '#000cff',
- text_color: 'white',
- description: 'test',
- });
- return waitForPromises().then(() => {
- list.issues[0].labels.push(label1);
- });
- };
-
- beforeEach(() => {
- mock = new MockAdapter(axios);
- mock.onAny().reply(boardsMockInterceptor);
- setMockEndpoints();
- return setupData();
- });
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- list = null;
- mock.restore();
- });
-
- describe('mouse events', () => {
- it('sets showDetail to true on mousedown', async () => {
- createStore();
- mountComponent();
-
- wrapper.trigger('mousedown');
- await wrapper.vm.$nextTick();
-
- expect(wrapper.vm.showDetail).toBe(true);
- });
-
- it('sets showDetail to false on mousemove', async () => {
- createStore();
- mountComponent();
- wrapper.trigger('mousedown');
- await wrapper.vm.$nextTick();
- expect(wrapper.vm.showDetail).toBe(true);
- wrapper.trigger('mousemove');
- await wrapper.vm.$nextTick();
- expect(wrapper.vm.showDetail).toBe(false);
- });
-
- it("calls 'setActiveId' when 'graphqlBoardLists' feature flag is turned on", async () => {
- const setActiveId = jest.fn();
- createStore({
- actions: {
- setActiveId,
- },
- });
- mountComponent({
- provide: {
- glFeatures: { graphqlBoardLists: true },
- },
- });
-
- wrapper.trigger('mouseup');
- await wrapper.vm.$nextTick();
-
- expect(setActiveId).toHaveBeenCalledTimes(1);
- expect(setActiveId).toHaveBeenCalledWith(expect.any(Object), {
- id: list.issues[0].id,
- sidebarType: ISSUABLE,
- });
- });
-
- it("calls 'setActiveId' when epic swimlanes is active", async () => {
- const setActiveId = jest.fn();
- const isSwimlanesOn = () => true;
- createStore({
- getters: { isSwimlanesOn },
- actions: {
- setActiveId,
- },
- });
- mountComponent();
-
- wrapper.trigger('mouseup');
- await wrapper.vm.$nextTick();
-
- expect(setActiveId).toHaveBeenCalledTimes(1);
- expect(setActiveId).toHaveBeenCalledWith(expect.any(Object), {
- id: list.issues[0].id,
- sidebarType: ISSUABLE,
- });
- });
- });
-});
diff --git a/spec/frontend/boards/components/board_column_deprecated_spec.js b/spec/frontend/boards/components/board_column_deprecated_spec.js
deleted file mode 100644
index e6d65e48c3f..00000000000
--- a/spec/frontend/boards/components/board_column_deprecated_spec.js
+++ /dev/null
@@ -1,106 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import AxiosMockAdapter from 'axios-mock-adapter';
-import Vue, { nextTick } from 'vue';
-
-import { TEST_HOST } from 'helpers/test_constants';
-import { listObj } from 'jest/boards/mock_data';
-import Board from '~/boards/components/board_column_deprecated.vue';
-import { ListType } from '~/boards/constants';
-import List from '~/boards/models/list';
-import axios from '~/lib/utils/axios_utils';
-
-describe('Board Column Component', () => {
- let wrapper;
- let axiosMock;
-
- beforeEach(() => {
- window.gon = {};
- axiosMock = new AxiosMockAdapter(axios);
- axiosMock.onGet(`${TEST_HOST}/lists/1/issues`).reply(200, { issues: [] });
- });
-
- afterEach(() => {
- axiosMock.restore();
-
- wrapper.destroy();
-
- localStorage.clear();
- });
-
- const createComponent = ({
- listType = ListType.backlog,
- collapsed = false,
- highlighted = false,
- withLocalStorage = true,
- } = {}) => {
- const boardId = '1';
-
- const listMock = {
- ...listObj,
- list_type: listType,
- highlighted,
- collapsed,
- };
-
- if (listType === ListType.assignee) {
- delete listMock.label;
- listMock.user = {};
- }
-
- // Making List reactive
- const list = Vue.observable(new List(listMock));
-
- if (withLocalStorage) {
- localStorage.setItem(
- `boards.${boardId}.${list.type}.${list.id}.expanded`,
- (!collapsed).toString(),
- );
- }
-
- wrapper = shallowMount(Board, {
- propsData: {
- boardId,
- disabled: false,
- list,
- },
- provide: {
- boardId,
- },
- });
- };
-
- const isExpandable = () => wrapper.classes('is-expandable');
- const isCollapsed = () => wrapper.classes('is-collapsed');
-
- describe('Given different list types', () => {
- it('is expandable when List Type is `backlog`', () => {
- createComponent({ listType: ListType.backlog });
-
- expect(isExpandable()).toBe(true);
- });
- });
-
- describe('expanded / collapsed column', () => {
- it('has class is-collapsed when list is collapsed', () => {
- createComponent({ collapsed: false });
-
- expect(wrapper.vm.list.isExpanded).toBe(true);
- });
-
- it('does not have class is-collapsed when list is expanded', () => {
- createComponent({ collapsed: true });
-
- expect(isCollapsed()).toBe(true);
- });
- });
-
- describe('highlighting', () => {
- it('scrolls to column when highlighted', async () => {
- createComponent({ highlighted: true });
-
- await nextTick();
-
- expect(wrapper.element.scrollIntoView).toHaveBeenCalled();
- });
- });
-});
diff --git a/spec/frontend/boards/components/board_content_spec.js b/spec/frontend/boards/components/board_content_spec.js
index 5a799b6388e..f535679b8a0 100644
--- a/spec/frontend/boards/components/board_content_spec.js
+++ b/spec/frontend/boards/components/board_content_spec.js
@@ -5,9 +5,10 @@ import Draggable from 'vuedraggable';
import Vuex from 'vuex';
import EpicsSwimlanes from 'ee_component/boards/components/epics_swimlanes.vue';
import getters from 'ee_else_ce/boards/stores/getters';
-import BoardColumnDeprecated from '~/boards/components/board_column_deprecated.vue';
+import BoardColumn from '~/boards/components/board_column.vue';
import BoardContent from '~/boards/components/board_content.vue';
-import { mockLists, mockListsWithModel } from '../mock_data';
+import BoardContentSidebar from '~/boards/components/board_content_sidebar.vue';
+import { mockLists } from '../mock_data';
Vue.use(Vuex);
@@ -23,6 +24,7 @@ describe('BoardContent', () => {
isShowingEpicsSwimlanes: false,
boardLists: mockLists,
error: undefined,
+ issuableType: 'issue',
};
const createStore = (state = defaultState) => {
@@ -33,25 +35,19 @@ describe('BoardContent', () => {
});
};
- const createComponent = ({
- state,
- props = {},
- graphqlBoardListsEnabled = false,
- canAdminList = true,
- } = {}) => {
+ const createComponent = ({ state, props = {}, canAdminList = true } = {}) => {
const store = createStore({
...defaultState,
...state,
});
wrapper = shallowMount(BoardContent, {
propsData: {
- lists: mockListsWithModel,
+ lists: mockLists,
disabled: false,
...props,
},
provide: {
canAdminList,
- glFeatures: { graphqlBoardLists: graphqlBoardListsEnabled },
},
store,
});
@@ -61,53 +57,48 @@ describe('BoardContent', () => {
wrapper.destroy();
});
- it('renders a BoardColumnDeprecated component per list', () => {
- createComponent();
+ describe('default', () => {
+ beforeEach(() => {
+ createComponent();
+ });
- expect(wrapper.findAllComponents(BoardColumnDeprecated)).toHaveLength(
- mockListsWithModel.length,
- );
- });
+ it('renders a BoardColumn component per list', () => {
+ expect(wrapper.findAllComponents(BoardColumn)).toHaveLength(mockLists.length);
+ });
- it('does not display EpicsSwimlanes component', () => {
- createComponent();
+ it('renders BoardContentSidebar', () => {
+ expect(wrapper.find(BoardContentSidebar).exists()).toBe(true);
+ });
- expect(wrapper.find(EpicsSwimlanes).exists()).toBe(false);
- expect(wrapper.find(GlAlert).exists()).toBe(false);
+ it('does not display EpicsSwimlanes component', () => {
+ expect(wrapper.find(EpicsSwimlanes).exists()).toBe(false);
+ expect(wrapper.find(GlAlert).exists()).toBe(false);
+ });
});
- describe('graphqlBoardLists feature flag enabled', () => {
+ describe('when issuableType is not issue', () => {
beforeEach(() => {
- createComponent({ graphqlBoardListsEnabled: true });
- gon.features = {
- graphqlBoardLists: true,
- };
+ createComponent({ state: { issuableType: 'foo' } });
});
- describe('can admin list', () => {
- beforeEach(() => {
- createComponent({ graphqlBoardListsEnabled: true, canAdminList: true });
- });
-
- it('renders draggable component', () => {
- expect(wrapper.find(Draggable).exists()).toBe(true);
- });
+ it('does not render BoardContentSidebar', () => {
+ expect(wrapper.find(BoardContentSidebar).exists()).toBe(false);
});
+ });
- describe('can not admin list', () => {
- beforeEach(() => {
- createComponent({ graphqlBoardListsEnabled: true, canAdminList: false });
- });
+ describe('can admin list', () => {
+ beforeEach(() => {
+ createComponent({ canAdminList: true });
+ });
- it('does not render draggable component', () => {
- expect(wrapper.find(Draggable).exists()).toBe(false);
- });
+ it('renders draggable component', () => {
+ expect(wrapper.find(Draggable).exists()).toBe(true);
});
});
- describe('graphqlBoardLists feature flag disabled', () => {
+ describe('can not admin list', () => {
beforeEach(() => {
- createComponent({ graphqlBoardListsEnabled: false });
+ createComponent({ canAdminList: false });
});
it('does not render draggable component', () => {
diff --git a/spec/frontend/boards/components/board_filtered_search_spec.js b/spec/frontend/boards/components/board_filtered_search_spec.js
index 50f86e92adb..dc93890f27a 100644
--- a/spec/frontend/boards/components/board_filtered_search_spec.js
+++ b/spec/frontend/boards/components/board_filtered_search_spec.js
@@ -2,7 +2,6 @@ import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vuex from 'vuex';
import BoardFilteredSearch from '~/boards/components/board_filtered_search.vue';
-import { createStore } from '~/boards/stores';
import * as urlUtility from '~/lib/utils/url_utility';
import { __ } from '~/locale';
import FilteredSearchBarRoot from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
@@ -44,6 +43,12 @@ describe('BoardFilteredSearch', () => {
];
const createComponent = ({ initialFilterParams = {} } = {}) => {
+ store = new Vuex.Store({
+ actions: {
+ performSearch: jest.fn(),
+ },
+ });
+
wrapper = shallowMount(BoardFilteredSearch, {
provide: { initialFilterParams, fullPath: '' },
store,
@@ -55,22 +60,15 @@ describe('BoardFilteredSearch', () => {
const findFilteredSearch = () => wrapper.findComponent(FilteredSearchBarRoot);
- beforeEach(() => {
- // this needed for actions call for performSearch
- window.gon = { features: {} };
- });
-
afterEach(() => {
wrapper.destroy();
});
describe('default', () => {
beforeEach(() => {
- store = createStore();
+ createComponent();
jest.spyOn(store, 'dispatch');
-
- createComponent();
});
it('renders FilteredSearch', () => {
@@ -103,8 +101,6 @@ describe('BoardFilteredSearch', () => {
describe('when searching', () => {
beforeEach(() => {
- store = createStore();
-
createComponent();
jest.spyOn(wrapper.vm, 'performSearch').mockImplementation();
@@ -133,11 +129,9 @@ describe('BoardFilteredSearch', () => {
describe('when url params are already set', () => {
beforeEach(() => {
- store = createStore();
+ createComponent({ initialFilterParams: { authorUsername: 'root', labelName: ['label'] } });
jest.spyOn(store, 'dispatch');
-
- createComponent({ initialFilterParams: { authorUsername: 'root', labelName: ['label'] } });
});
it('passes the correct props to FilterSearchBar', () => {
diff --git a/spec/frontend/boards/components/board_list_header_deprecated_spec.js b/spec/frontend/boards/components/board_list_header_deprecated_spec.js
deleted file mode 100644
index db79e67fe78..00000000000
--- a/spec/frontend/boards/components/board_list_header_deprecated_spec.js
+++ /dev/null
@@ -1,174 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import AxiosMockAdapter from 'axios-mock-adapter';
-import Vue from 'vue';
-
-import { TEST_HOST } from 'helpers/test_constants';
-import { listObj } from 'jest/boards/mock_data';
-import BoardListHeader from '~/boards/components/board_list_header_deprecated.vue';
-import { ListType } from '~/boards/constants';
-import List from '~/boards/models/list';
-import axios from '~/lib/utils/axios_utils';
-
-describe('Board List Header Component', () => {
- let wrapper;
- let axiosMock;
-
- beforeEach(() => {
- window.gon = {};
- axiosMock = new AxiosMockAdapter(axios);
- axiosMock.onGet(`${TEST_HOST}/lists/1/issues`).reply(200, { issues: [] });
- });
-
- afterEach(() => {
- axiosMock.restore();
-
- wrapper.destroy();
-
- localStorage.clear();
- });
-
- const createComponent = ({
- listType = ListType.backlog,
- collapsed = false,
- withLocalStorage = true,
- currentUserId = 1,
- } = {}) => {
- const boardId = '1';
-
- const listMock = {
- ...listObj,
- list_type: listType,
- collapsed,
- };
-
- if (listType === ListType.assignee) {
- delete listMock.label;
- listMock.user = {};
- }
-
- // Making List reactive
- const list = Vue.observable(new List(listMock));
-
- if (withLocalStorage) {
- localStorage.setItem(
- `boards.${boardId}.${list.type}.${list.id}.expanded`,
- (!collapsed).toString(),
- );
- }
-
- wrapper = shallowMount(BoardListHeader, {
- propsData: {
- disabled: false,
- list,
- },
- provide: {
- boardId,
- currentUserId,
- },
- });
- };
-
- const isCollapsed = () => !wrapper.props().list.isExpanded;
- const isExpanded = () => wrapper.vm.list.isExpanded;
-
- const findAddIssueButton = () => wrapper.find({ ref: 'newIssueBtn' });
- const findCaret = () => wrapper.find('.board-title-caret');
-
- describe('Add issue button', () => {
- const hasNoAddButton = [ListType.closed];
- const hasAddButton = [
- ListType.backlog,
- ListType.label,
- ListType.milestone,
- ListType.iteration,
- ListType.assignee,
- ];
-
- it.each(hasNoAddButton)('does not render when List Type is `%s`', (listType) => {
- createComponent({ listType });
-
- expect(findAddIssueButton().exists()).toBe(false);
- });
-
- it.each(hasAddButton)('does render when List Type is `%s`', (listType) => {
- createComponent({ listType });
-
- expect(findAddIssueButton().exists()).toBe(true);
- });
-
- it('has a test for each list type', () => {
- Object.values(ListType).forEach((value) => {
- expect([...hasAddButton, ...hasNoAddButton]).toContain(value);
- });
- });
-
- it('does not render when logged out', () => {
- createComponent({
- currentUserId: null,
- });
-
- expect(findAddIssueButton().exists()).toBe(false);
- });
- });
-
- describe('expanding / collapsing the column', () => {
- it('does not collapse when clicking the header', () => {
- createComponent();
-
- expect(isCollapsed()).toBe(false);
- wrapper.find('[data-testid="board-list-header"]').trigger('click');
-
- return wrapper.vm.$nextTick().then(() => {
- expect(isCollapsed()).toBe(false);
- });
- });
-
- it('collapses expanded Column when clicking the collapse icon', () => {
- createComponent();
-
- expect(isExpanded()).toBe(true);
- findCaret().vm.$emit('click');
-
- return wrapper.vm.$nextTick().then(() => {
- expect(isCollapsed()).toBe(true);
- });
- });
-
- it('expands collapsed Column when clicking the expand icon', () => {
- createComponent({ collapsed: true });
-
- expect(isCollapsed()).toBe(true);
- findCaret().vm.$emit('click');
-
- return wrapper.vm.$nextTick().then(() => {
- expect(isCollapsed()).toBe(false);
- });
- });
-
- it("when logged in it calls list update and doesn't set localStorage", () => {
- jest.spyOn(List.prototype, 'update');
-
- createComponent({ withLocalStorage: false });
-
- findCaret().vm.$emit('click');
-
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.vm.list.update).toHaveBeenCalledTimes(1);
- expect(localStorage.getItem(`${wrapper.vm.uniqueKey}.expanded`)).toBe(null);
- });
- });
-
- it("when logged out it doesn't call list update and sets localStorage", () => {
- jest.spyOn(List.prototype, 'update');
-
- createComponent({ currentUserId: null });
-
- findCaret().vm.$emit('click');
-
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.vm.list.update).not.toHaveBeenCalled();
- expect(localStorage.getItem(`${wrapper.vm.uniqueKey}.expanded`)).toBe(String(isExpanded()));
- });
- });
- });
-});
diff --git a/spec/frontend/boards/components/board_settings_sidebar_spec.js b/spec/frontend/boards/components/board_settings_sidebar_spec.js
index 20a08be6c19..46dd109ffb1 100644
--- a/spec/frontend/boards/components/board_settings_sidebar_spec.js
+++ b/spec/frontend/boards/components/board_settings_sidebar_spec.js
@@ -1,38 +1,55 @@
-import '~/boards/models/list';
import { GlDrawer, GlLabel } from '@gitlab/ui';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import axios from 'axios';
-import MockAdapter from 'axios-mock-adapter';
+import { shallowMount } from '@vue/test-utils';
import { MountingPortal } from 'portal-vue';
+import Vue from 'vue';
import Vuex from 'vuex';
+import { stubComponent } from 'helpers/stub_component';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import BoardSettingsSidebar from '~/boards/components/board_settings_sidebar.vue';
import { inactiveId, LIST } from '~/boards/constants';
-import { createStore } from '~/boards/stores';
-import boardsStore from '~/boards/stores/boards_store';
+import actions from '~/boards/stores/actions';
+import getters from '~/boards/stores/getters';
+import mutations from '~/boards/stores/mutations';
import sidebarEventHub from '~/sidebar/event_hub';
+import { mockLabelList } from '../mock_data';
-const localVue = createLocalVue();
-
-localVue.use(Vuex);
+Vue.use(Vuex);
describe('BoardSettingsSidebar', () => {
let wrapper;
- let mock;
- let store;
- const labelTitle = 'test';
- const labelColor = '#FFFF';
- const listId = 1;
+ const labelTitle = mockLabelList.label.title;
+ const labelColor = mockLabelList.label.color;
+ const listId = mockLabelList.id;
const findRemoveButton = () => wrapper.findByTestId('remove-list');
- const createComponent = ({ canAdminList = false } = {}) => {
+ const createComponent = ({
+ canAdminList = false,
+ list = {},
+ sidebarType = LIST,
+ activeId = inactiveId,
+ } = {}) => {
+ const boardLists = {
+ [listId]: list,
+ };
+ const store = new Vuex.Store({
+ state: { sidebarType, activeId, boardLists },
+ getters,
+ mutations,
+ actions,
+ });
+
wrapper = extendedWrapper(
shallowMount(BoardSettingsSidebar, {
store,
- localVue,
provide: {
canAdminList,
+ scopedLabelsAvailable: false,
+ },
+ stubs: {
+ GlDrawer: stubComponent(GlDrawer, {
+ template: '<div><slot name="header"></slot><slot></slot></div>',
+ }),
},
}),
);
@@ -40,16 +57,10 @@ describe('BoardSettingsSidebar', () => {
const findLabel = () => wrapper.find(GlLabel);
const findDrawer = () => wrapper.find(GlDrawer);
- beforeEach(() => {
- store = createStore();
- store.state.activeId = inactiveId;
- store.state.sidebarType = LIST;
- boardsStore.create();
- });
-
afterEach(() => {
jest.restoreAllMocks();
wrapper.destroy();
+ wrapper = null;
});
it('finds a MountingPortal component', () => {
@@ -100,86 +111,40 @@ describe('BoardSettingsSidebar', () => {
});
describe('when activeId is greater than zero', () => {
- beforeEach(() => {
- mock = new MockAdapter(axios);
-
- boardsStore.addList({
- id: listId,
- label: { title: labelTitle, color: labelColor },
- list_type: 'label',
- });
- store.state.activeId = 1;
- store.state.sidebarType = LIST;
- });
-
- afterEach(() => {
- boardsStore.removeList(listId);
- });
-
- it('renders GlDrawer with open false', () => {
- createComponent();
+ it('renders GlDrawer with open true', () => {
+ createComponent({ list: mockLabelList, activeId: listId });
expect(findDrawer().props('open')).toBe(true);
});
});
- describe('when activeId is in boardsStore', () => {
- beforeEach(() => {
- mock = new MockAdapter(axios);
-
- boardsStore.addList({
- id: listId,
- label: { title: labelTitle, color: labelColor },
- list_type: 'label',
- });
-
- store.state.activeId = listId;
- store.state.sidebarType = LIST;
-
- createComponent();
- });
-
- afterEach(() => {
- mock.restore();
- });
-
+ describe('when activeId is in state', () => {
it('renders label title', () => {
+ createComponent({ list: mockLabelList, activeId: listId });
+
expect(findLabel().props('title')).toBe(labelTitle);
});
it('renders label background color', () => {
+ createComponent({ list: mockLabelList, activeId: listId });
+
expect(findLabel().props('backgroundColor')).toBe(labelColor);
});
});
- describe('when activeId is not in boardsStore', () => {
- beforeEach(() => {
- mock = new MockAdapter(axios);
-
- boardsStore.addList({ id: listId, label: { title: labelTitle, color: labelColor } });
-
- store.state.activeId = inactiveId;
-
- createComponent();
- });
-
- afterEach(() => {
- mock.restore();
- });
-
+ describe('when activeId is not in state', () => {
it('does not render GlLabel', () => {
+ createComponent({ list: mockLabelList });
+
expect(findLabel().exists()).toBe(false);
});
});
});
describe('when sidebarType is not List', () => {
- beforeEach(() => {
- store.state.sidebarType = '';
- createComponent();
- });
-
it('does not render GlDrawer', () => {
+ createComponent({ sidebarType: '' });
+
expect(findDrawer().exists()).toBe(false);
});
});
@@ -191,20 +156,9 @@ describe('BoardSettingsSidebar', () => {
});
describe('when user can admin the boards list', () => {
- beforeEach(() => {
- store.state.activeId = listId;
- store.state.sidebarType = LIST;
-
- boardsStore.addList({
- id: listId,
- label: { title: labelTitle, color: labelColor },
- list_type: 'label',
- });
-
- createComponent({ canAdminList: true });
- });
-
it('renders "Remove list" button', () => {
+ createComponent({ canAdminList: true, activeId: listId, list: mockLabelList });
+
expect(findRemoveButton().exists()).toBe(true);
});
});
diff --git a/spec/frontend/boards/components/boards_selector_deprecated_spec.js b/spec/frontend/boards/components/boards_selector_deprecated_spec.js
deleted file mode 100644
index cc078861d75..00000000000
--- a/spec/frontend/boards/components/boards_selector_deprecated_spec.js
+++ /dev/null
@@ -1,214 +0,0 @@
-import { GlDropdown, GlLoadingIcon, GlDropdownSectionHeader } from '@gitlab/ui';
-import { mount } from '@vue/test-utils';
-import { nextTick } from 'vue';
-import { TEST_HOST } from 'spec/test_constants';
-import BoardsSelector from '~/boards/components/boards_selector_deprecated.vue';
-import boardsStore from '~/boards/stores/boards_store';
-
-const throttleDuration = 1;
-
-function boardGenerator(n) {
- return new Array(n).fill().map((board, index) => {
- const id = `${index}`;
- const name = `board${id}`;
-
- return {
- id,
- name,
- };
- });
-}
-
-describe('BoardsSelector', () => {
- let wrapper;
- let allBoardsResponse;
- let recentBoardsResponse;
- const boards = boardGenerator(20);
- const recentBoards = boardGenerator(5);
-
- const fillSearchBox = (filterTerm) => {
- const searchBox = wrapper.find({ ref: 'searchBox' });
- const searchBoxInput = searchBox.find('input');
- searchBoxInput.setValue(filterTerm);
- searchBoxInput.trigger('input');
- };
-
- const getDropdownItems = () => wrapper.findAll('.js-dropdown-item');
- const getDropdownHeaders = () => wrapper.findAll(GlDropdownSectionHeader);
- const getLoadingIcon = () => wrapper.find(GlLoadingIcon);
- const findDropdown = () => wrapper.find(GlDropdown);
-
- beforeEach(() => {
- const $apollo = {
- queries: {
- boards: {
- loading: false,
- },
- },
- };
-
- boardsStore.setEndpoints({
- boardsEndpoint: '',
- recentBoardsEndpoint: '',
- listsEndpoint: '',
- bulkUpdatePath: '',
- boardId: '',
- });
-
- allBoardsResponse = Promise.resolve({
- data: {
- group: {
- boards: {
- edges: boards.map((board) => ({ node: board })),
- },
- },
- },
- });
- recentBoardsResponse = Promise.resolve({
- data: recentBoards,
- });
-
- boardsStore.allBoards = jest.fn(() => allBoardsResponse);
- boardsStore.recentBoards = jest.fn(() => recentBoardsResponse);
-
- wrapper = mount(BoardsSelector, {
- propsData: {
- throttleDuration,
- currentBoard: {
- id: 1,
- name: 'Development',
- milestone_id: null,
- weight: null,
- assignee_id: null,
- labels: [],
- },
- boardBaseUrl: `${TEST_HOST}/board/base/url`,
- hasMissingBoards: false,
- canAdminBoard: true,
- multipleIssueBoardsAvailable: true,
- labelsPath: `${TEST_HOST}/labels/path`,
- labelsWebUrl: `${TEST_HOST}/labels`,
- projectId: 42,
- groupId: 19,
- scopedIssueBoardFeatureEnabled: true,
- weights: [],
- },
- mocks: { $apollo },
- attachTo: document.body,
- });
-
- wrapper.vm.$apollo.addSmartQuery = jest.fn((_, options) => {
- wrapper.setData({
- [options.loadingKey]: true,
- });
- });
-
- // Emits gl-dropdown show event to simulate the dropdown is opened at initialization time
- findDropdown().vm.$emit('show');
- });
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- describe('loading', () => {
- // we are testing loading state, so don't resolve responses until after the tests
- afterEach(() => {
- return Promise.all([allBoardsResponse, recentBoardsResponse]).then(() => nextTick());
- });
-
- it('shows loading spinner', () => {
- expect(getDropdownHeaders()).toHaveLength(0);
- expect(getDropdownItems()).toHaveLength(0);
- expect(getLoadingIcon().exists()).toBe(true);
- });
- });
-
- describe('loaded', () => {
- beforeEach(async () => {
- await wrapper.setData({
- loadingBoards: false,
- });
- return Promise.all([allBoardsResponse, recentBoardsResponse]).then(() => nextTick());
- });
-
- it('hides loading spinner', () => {
- expect(getLoadingIcon().exists()).toBe(false);
- });
-
- describe('filtering', () => {
- beforeEach(() => {
- wrapper.setData({
- boards,
- });
-
- return nextTick();
- });
-
- it('shows all boards without filtering', () => {
- expect(getDropdownItems()).toHaveLength(boards.length + recentBoards.length);
- });
-
- it('shows only matching boards when filtering', () => {
- const filterTerm = 'board1';
- const expectedCount = boards.filter((board) => board.name.includes(filterTerm)).length;
-
- fillSearchBox(filterTerm);
-
- return nextTick().then(() => {
- expect(getDropdownItems()).toHaveLength(expectedCount);
- });
- });
-
- it('shows message if there are no matching boards', () => {
- fillSearchBox('does not exist');
-
- return nextTick().then(() => {
- expect(getDropdownItems()).toHaveLength(0);
- expect(wrapper.text().includes('No matching boards found')).toBe(true);
- });
- });
- });
-
- describe('recent boards section', () => {
- it('shows only when boards are greater than 10', () => {
- wrapper.setData({
- boards,
- });
-
- return nextTick().then(() => {
- expect(getDropdownHeaders()).toHaveLength(2);
- });
- });
-
- it('does not show when boards are less than 10', () => {
- wrapper.setData({
- boards: boards.slice(0, 5),
- });
-
- return nextTick().then(() => {
- expect(getDropdownHeaders()).toHaveLength(0);
- });
- });
-
- it('does not show when recentBoards api returns empty array', () => {
- wrapper.setData({
- recentBoards: [],
- });
-
- return nextTick().then(() => {
- expect(getDropdownHeaders()).toHaveLength(0);
- });
- });
-
- it('does not show when search is active', () => {
- fillSearchBox('Random string');
-
- return nextTick().then(() => {
- expect(getDropdownHeaders()).toHaveLength(0);
- });
- });
- });
- });
-});
diff --git a/spec/frontend/boards/components/issue_time_estimate_deprecated_spec.js b/spec/frontend/boards/components/issue_time_estimate_deprecated_spec.js
deleted file mode 100644
index fafebaf3a4e..00000000000
--- a/spec/frontend/boards/components/issue_time_estimate_deprecated_spec.js
+++ /dev/null
@@ -1,64 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import IssueTimeEstimate from '~/boards/components/issue_time_estimate_deprecated.vue';
-import boardsStore from '~/boards/stores/boards_store';
-
-describe('Issue Time Estimate component', () => {
- let wrapper;
-
- beforeEach(() => {
- boardsStore.create();
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- describe('when limitToHours is false', () => {
- beforeEach(() => {
- boardsStore.timeTracking.limitToHours = false;
- wrapper = shallowMount(IssueTimeEstimate, {
- propsData: {
- estimate: 374460,
- },
- });
- });
-
- it('renders the correct time estimate', () => {
- expect(wrapper.find('time').text().trim()).toEqual('2w 3d 1m');
- });
-
- it('renders expanded time estimate in tooltip', () => {
- expect(wrapper.find('.js-issue-time-estimate').text()).toContain('2 weeks 3 days 1 minute');
- });
-
- it('prevents tooltip xss', (done) => {
- const alertSpy = jest.spyOn(window, 'alert');
- wrapper.setProps({ estimate: 'Foo <script>alert("XSS")</script>' });
- wrapper.vm.$nextTick(() => {
- expect(alertSpy).not.toHaveBeenCalled();
- expect(wrapper.find('time').text().trim()).toEqual('0m');
- expect(wrapper.find('.js-issue-time-estimate').text()).toContain('0m');
- done();
- });
- });
- });
-
- describe('when limitToHours is true', () => {
- beforeEach(() => {
- boardsStore.timeTracking.limitToHours = true;
- wrapper = shallowMount(IssueTimeEstimate, {
- propsData: {
- estimate: 374460,
- },
- });
- });
-
- it('renders the correct time estimate', () => {
- expect(wrapper.find('time').text().trim()).toEqual('104h 1m');
- });
-
- it('renders expanded time estimate in tooltip', () => {
- expect(wrapper.find('.js-issue-time-estimate').text()).toContain('104 hours 1 minute');
- });
- });
-});
diff --git a/spec/frontend/boards/issue_card_deprecated_spec.js b/spec/frontend/boards/issue_card_deprecated_spec.js
deleted file mode 100644
index 909be275030..00000000000
--- a/spec/frontend/boards/issue_card_deprecated_spec.js
+++ /dev/null
@@ -1,332 +0,0 @@
-/* global ListAssignee, ListLabel, ListIssue */
-import { GlLabel } from '@gitlab/ui';
-import { mount } from '@vue/test-utils';
-import { range } from 'lodash';
-import '~/boards/models/label';
-import '~/boards/models/assignee';
-import '~/boards/models/issue';
-import '~/boards/models/list';
-import IssueCardInner from '~/boards/components/issue_card_inner_deprecated.vue';
-import store from '~/boards/stores';
-import { listObj } from './mock_data';
-
-describe('Issue card component', () => {
- const user = new ListAssignee({
- id: 1,
- name: 'testing 123',
- username: 'test',
- avatar: 'test_image',
- });
-
- const label1 = new ListLabel({
- id: 3,
- title: 'testing 123',
- color: '#000CFF',
- text_color: 'white',
- description: 'test',
- });
-
- let wrapper;
- let issue;
- let list;
-
- beforeEach(() => {
- list = { ...listObj, type: 'label' };
- issue = new ListIssue({
- title: 'Testing',
- id: 1,
- iid: 1,
- confidential: false,
- labels: [list.label],
- assignees: [],
- reference_path: '#1',
- real_path: '/test/1',
- weight: 1,
- });
- wrapper = mount(IssueCardInner, {
- propsData: {
- list,
- issue,
- },
- store,
- stubs: {
- GlLabel: true,
- },
- provide: {
- groupId: null,
- rootPath: '/',
- },
- });
- });
-
- it('renders issue title', () => {
- expect(wrapper.find('.board-card-title').text()).toContain(issue.title);
- });
-
- it('includes issue base in link', () => {
- expect(wrapper.find('.board-card-title a').attributes('href')).toContain('/test');
- });
-
- it('includes issue title on link', () => {
- expect(wrapper.find('.board-card-title a').attributes('title')).toBe(issue.title);
- });
-
- it('does not render confidential icon', () => {
- expect(wrapper.find('.confidential-icon').exists()).toBe(false);
- });
-
- it('does not render blocked icon', () => {
- expect(wrapper.find('.issue-blocked-icon').exists()).toBe(false);
- });
-
- it('renders confidential icon', (done) => {
- wrapper.setProps({
- issue: {
- ...wrapper.props('issue'),
- confidential: true,
- },
- });
- wrapper.vm.$nextTick(() => {
- expect(wrapper.find('.confidential-icon').exists()).toBe(true);
- done();
- });
- });
-
- it('renders issue ID with #', () => {
- expect(wrapper.find('.board-card-number').text()).toContain(`#${issue.id}`);
- });
-
- describe('assignee', () => {
- it('does not render assignee', () => {
- expect(wrapper.find('.board-card-assignee .avatar').exists()).toBe(false);
- });
-
- describe('exists', () => {
- beforeEach((done) => {
- wrapper.setProps({
- issue: {
- ...wrapper.props('issue'),
- assignees: [user],
- updateData(newData) {
- Object.assign(this, newData);
- },
- },
- });
-
- wrapper.vm.$nextTick(done);
- });
-
- it('renders assignee', () => {
- expect(wrapper.find('.board-card-assignee .avatar').exists()).toBe(true);
- });
-
- it('sets title', () => {
- expect(wrapper.find('.js-assignee-tooltip').text()).toContain(`${user.name}`);
- });
-
- it('sets users path', () => {
- expect(wrapper.find('.board-card-assignee a').attributes('href')).toBe('/test');
- });
-
- it('renders avatar', () => {
- expect(wrapper.find('.board-card-assignee img').exists()).toBe(true);
- });
-
- it('renders the avatar using avatar_url property', (done) => {
- wrapper.props('issue').updateData({
- ...wrapper.props('issue'),
- assignees: [
- {
- id: '1',
- name: 'test',
- state: 'active',
- username: 'test_name',
- avatar_url: 'test_image_from_avatar_url',
- },
- ],
- });
-
- wrapper.vm.$nextTick(() => {
- expect(wrapper.find('.board-card-assignee img').attributes('src')).toBe(
- 'test_image_from_avatar_url?width=24',
- );
- done();
- });
- });
- });
-
- describe('assignee default avatar', () => {
- beforeEach((done) => {
- global.gon.default_avatar_url = 'default_avatar';
-
- wrapper.setProps({
- issue: {
- ...wrapper.props('issue'),
- assignees: [
- new ListAssignee({
- id: 1,
- name: 'testing 123',
- username: 'test',
- }),
- ],
- },
- });
-
- wrapper.vm.$nextTick(done);
- });
-
- afterEach(() => {
- global.gon.default_avatar_url = null;
- });
-
- it('displays defaults avatar if users avatar is null', () => {
- expect(wrapper.find('.board-card-assignee img').exists()).toBe(true);
- expect(wrapper.find('.board-card-assignee img').attributes('src')).toBe(
- 'default_avatar?width=24',
- );
- });
- });
- });
-
- describe('multiple assignees', () => {
- beforeEach((done) => {
- wrapper.setProps({
- issue: {
- ...wrapper.props('issue'),
- assignees: [
- new ListAssignee({
- id: 2,
- name: 'user2',
- username: 'user2',
- avatar: 'test_image',
- }),
- new ListAssignee({
- id: 3,
- name: 'user3',
- username: 'user3',
- avatar: 'test_image',
- }),
- new ListAssignee({
- id: 4,
- name: 'user4',
- username: 'user4',
- avatar: 'test_image',
- }),
- ],
- },
- });
-
- wrapper.vm.$nextTick(done);
- });
-
- it('renders all three assignees', () => {
- expect(wrapper.findAll('.board-card-assignee .avatar').length).toEqual(3);
- });
-
- describe('more than three assignees', () => {
- beforeEach((done) => {
- const { assignees } = wrapper.props('issue');
- assignees.push(
- new ListAssignee({
- id: 5,
- name: 'user5',
- username: 'user5',
- avatar: 'test_image',
- }),
- );
-
- wrapper.setProps({
- issue: {
- ...wrapper.props('issue'),
- assignees,
- },
- });
- wrapper.vm.$nextTick(done);
- });
-
- it('renders more avatar counter', () => {
- expect(wrapper.find('.board-card-assignee .avatar-counter').text().trim()).toEqual('+2');
- });
-
- it('renders two assignees', () => {
- expect(wrapper.findAll('.board-card-assignee .avatar').length).toEqual(2);
- });
-
- it('renders 99+ avatar counter', (done) => {
- const assignees = [
- ...wrapper.props('issue').assignees,
- ...range(5, 103).map(
- (i) =>
- new ListAssignee({
- id: i,
- name: 'name',
- username: 'username',
- avatar: 'test_image',
- }),
- ),
- ];
- wrapper.setProps({
- issue: {
- ...wrapper.props('issue'),
- assignees,
- },
- });
-
- wrapper.vm.$nextTick(() => {
- expect(wrapper.find('.board-card-assignee .avatar-counter').text().trim()).toEqual('99+');
- done();
- });
- });
- });
- });
-
- describe('labels', () => {
- beforeEach((done) => {
- issue.addLabel(label1);
- wrapper.setProps({ issue: { ...issue } });
-
- wrapper.vm.$nextTick(done);
- });
-
- it('does not render list label but renders all other labels', () => {
- expect(wrapper.findAll(GlLabel).length).toBe(1);
- const label = wrapper.find(GlLabel);
- expect(label.props('title')).toEqual(label1.title);
- expect(label.props('description')).toEqual(label1.description);
- expect(label.props('backgroundColor')).toEqual(label1.color);
- });
-
- it('does not render label if label does not have an ID', (done) => {
- issue.addLabel(
- new ListLabel({
- title: 'closed',
- }),
- );
- wrapper.setProps({ issue: { ...issue } });
- wrapper.vm
- .$nextTick()
- .then(() => {
- expect(wrapper.findAll(GlLabel).length).toBe(1);
- expect(wrapper.text()).not.toContain('closed');
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('blocked', () => {
- beforeEach((done) => {
- wrapper.setProps({
- issue: {
- ...wrapper.props('issue'),
- blocked: true,
- },
- });
- wrapper.vm.$nextTick(done);
- });
-
- it('renders blocked icon if issue is blocked', () => {
- expect(wrapper.find('.issue-blocked-icon').exists()).toBe(true);
- });
- });
-});
diff --git a/spec/frontend/boards/issue_spec.js b/spec/frontend/boards/issue_spec.js
deleted file mode 100644
index 1f354fb04db..00000000000
--- a/spec/frontend/boards/issue_spec.js
+++ /dev/null
@@ -1,162 +0,0 @@
-/* global ListIssue */
-
-import '~/boards/models/label';
-import '~/boards/models/assignee';
-import '~/boards/models/issue';
-import '~/boards/models/list';
-import boardsStore from '~/boards/stores/boards_store';
-import { setMockEndpoints, mockIssue } from './mock_data';
-
-describe('Issue model', () => {
- let issue;
-
- beforeEach(() => {
- setMockEndpoints();
- boardsStore.create();
-
- issue = new ListIssue(mockIssue);
- });
-
- it('has label', () => {
- expect(issue.labels.length).toBe(1);
- });
-
- it('add new label', () => {
- issue.addLabel({
- id: 2,
- title: 'bug',
- color: 'blue',
- description: 'bugs!',
- });
-
- expect(issue.labels.length).toBe(2);
- });
-
- it('does not add label if label id exists', () => {
- issue.addLabel({
- id: 1,
- title: 'test 2',
- color: 'blue',
- description: 'testing',
- });
-
- expect(issue.labels.length).toBe(1);
- expect(issue.labels[0].color).toBe('#F0AD4E');
- });
-
- it('adds other label with same title', () => {
- issue.addLabel({
- id: 2,
- title: 'test',
- color: 'blue',
- description: 'other test',
- });
-
- expect(issue.labels.length).toBe(2);
- });
-
- it('finds label', () => {
- const label = issue.findLabel(issue.labels[0]);
-
- expect(label).toBeDefined();
- });
-
- it('removes label', () => {
- const label = issue.findLabel(issue.labels[0]);
- issue.removeLabel(label);
-
- expect(issue.labels.length).toBe(0);
- });
-
- it('removes multiple labels', () => {
- issue.addLabel({
- id: 2,
- title: 'bug',
- color: 'blue',
- description: 'bugs!',
- });
-
- expect(issue.labels.length).toBe(2);
-
- issue.removeLabels([issue.labels[0], issue.labels[1]]);
-
- expect(issue.labels.length).toBe(0);
- });
-
- it('adds assignee', () => {
- issue.addAssignee({
- id: 2,
- name: 'Bruce Wayne',
- username: 'batman',
- avatar_url: 'http://batman',
- });
-
- expect(issue.assignees.length).toBe(2);
- });
-
- it('finds assignee', () => {
- const assignee = issue.findAssignee(issue.assignees[0]);
-
- expect(assignee).toBeDefined();
- });
-
- it('removes assignee', () => {
- const assignee = issue.findAssignee(issue.assignees[0]);
- issue.removeAssignee(assignee);
-
- expect(issue.assignees.length).toBe(0);
- });
-
- it('removes all assignees', () => {
- issue.removeAllAssignees();
-
- expect(issue.assignees.length).toBe(0);
- });
-
- it('sets position to infinity if no position is stored', () => {
- expect(issue.position).toBe(Infinity);
- });
-
- it('sets position', () => {
- const relativePositionIssue = new ListIssue({
- title: 'Testing',
- iid: 1,
- confidential: false,
- relative_position: 1,
- labels: [],
- assignees: [],
- });
-
- expect(relativePositionIssue.position).toBe(1);
- });
-
- it('updates data', () => {
- issue.updateData({ subscribed: true });
-
- expect(issue.subscribed).toBe(true);
- });
-
- it('sets fetching state', () => {
- expect(issue.isFetching.subscriptions).toBe(true);
-
- issue.setFetchingState('subscriptions', false);
-
- expect(issue.isFetching.subscriptions).toBe(false);
- });
-
- it('sets loading state', () => {
- issue.setLoadingState('foo', true);
-
- expect(issue.isLoading.foo).toBe(true);
- });
-
- describe('update', () => {
- it('passes update to boardsStore', () => {
- jest.spyOn(boardsStore, 'updateIssue').mockImplementation();
-
- issue.update();
-
- expect(boardsStore.updateIssue).toHaveBeenCalledWith(issue);
- });
- });
-});
diff --git a/spec/frontend/boards/list_spec.js b/spec/frontend/boards/list_spec.js
deleted file mode 100644
index 4d6a82bdff0..00000000000
--- a/spec/frontend/boards/list_spec.js
+++ /dev/null
@@ -1,230 +0,0 @@
-/* global List */
-/* global ListAssignee */
-/* global ListIssue */
-/* global ListLabel */
-import MockAdapter from 'axios-mock-adapter';
-import waitForPromises from 'helpers/wait_for_promises';
-import '~/boards/models/label';
-import '~/boards/models/assignee';
-import '~/boards/models/issue';
-import '~/boards/models/list';
-import { ListType } from '~/boards/constants';
-import boardsStore from '~/boards/stores/boards_store';
-import axios from '~/lib/utils/axios_utils';
-import { listObj, listObjDuplicate, boardsMockInterceptor } from './mock_data';
-
-describe('List model', () => {
- let list;
- let mock;
-
- beforeEach(() => {
- mock = new MockAdapter(axios);
- mock.onAny().reply(boardsMockInterceptor);
- boardsStore.create();
- boardsStore.setEndpoints({
- listsEndpoint: '/test/-/boards/1/lists',
- });
-
- list = new List(listObj);
- return waitForPromises();
- });
-
- afterEach(() => {
- mock.restore();
- });
-
- describe('list type', () => {
- const notExpandableList = ['blank'];
-
- const table = Object.keys(ListType).map((k) => {
- const value = ListType[k];
- return [value, !notExpandableList.includes(value)];
- });
- it.each(table)(`when list_type is %s boards isExpandable is %p`, (type, result) => {
- expect(new List({ id: 1, list_type: type }).isExpandable).toBe(result);
- });
- });
-
- it('gets issues when created', () => {
- expect(list.issues.length).toBe(1);
- });
-
- it('saves list and returns ID', () => {
- list = new List({
- title: 'test',
- label: {
- id: 1,
- title: 'test',
- color: '#ff0000',
- text_color: 'white',
- },
- });
- return list.save().then(() => {
- expect(list.id).toBe(listObj.id);
- expect(list.type).toBe('label');
- expect(list.position).toBe(0);
- expect(list.label).toEqual(listObj.label);
- });
- });
-
- it('destroys the list', () => {
- boardsStore.addList(listObj);
- list = boardsStore.findList('id', listObj.id);
-
- expect(boardsStore.state.lists.length).toBe(1);
- list.destroy();
-
- return waitForPromises().then(() => {
- expect(boardsStore.state.lists.length).toBe(0);
- });
- });
-
- it('gets issue from list', () => {
- const issue = list.findIssue(1);
-
- expect(issue).toBeDefined();
- });
-
- it('removes issue', () => {
- const issue = list.findIssue(1);
-
- expect(list.issues.length).toBe(1);
- list.removeIssue(issue);
-
- expect(list.issues.length).toBe(0);
- });
-
- it('sends service request to update issue label', () => {
- const listDup = new List(listObjDuplicate);
- const issue = new ListIssue({
- title: 'Testing',
- id: 1,
- iid: 1,
- confidential: false,
- labels: [list.label, listDup.label],
- assignees: [],
- });
-
- list.issues.push(issue);
- listDup.issues.push(issue);
-
- jest.spyOn(boardsStore, 'moveIssue');
-
- listDup.updateIssueLabel(issue, list);
-
- expect(boardsStore.moveIssue).toHaveBeenCalledWith(
- issue.id,
- list.id,
- listDup.id,
- undefined,
- undefined,
- );
- });
-
- describe('page number', () => {
- beforeEach(() => {
- jest.spyOn(list, 'getIssues').mockImplementation(() => {});
- list.issues = [];
- });
-
- it('increase page number if current issue count is more than the page size', () => {
- for (let i = 0; i < 30; i += 1) {
- list.issues.push(
- new ListIssue({
- title: 'Testing',
- id: i,
- iid: i,
- confidential: false,
- labels: [list.label],
- assignees: [],
- }),
- );
- }
- list.issuesSize = 50;
-
- expect(list.issues.length).toBe(30);
-
- list.nextPage();
-
- expect(list.page).toBe(2);
- expect(list.getIssues).toHaveBeenCalled();
- });
-
- it('does not increase page number if issue count is less than the page size', () => {
- list.issues.push(
- new ListIssue({
- title: 'Testing',
- id: 1,
- confidential: false,
- labels: [list.label],
- assignees: [],
- }),
- );
- list.issuesSize = 2;
-
- list.nextPage();
-
- expect(list.page).toBe(1);
- expect(list.getIssues).toHaveBeenCalled();
- });
- });
-
- describe('newIssue', () => {
- beforeEach(() => {
- jest.spyOn(boardsStore, 'newIssue').mockReturnValue(
- Promise.resolve({
- data: {
- id: 42,
- subscribed: false,
- assignable_labels_endpoint: '/issue/42/labels',
- toggle_subscription_endpoint: '/issue/42/subscriptions',
- issue_sidebar_endpoint: '/issue/42/sidebar_info',
- },
- }),
- );
- list.issues = [];
- });
-
- it('adds new issue to top of list', (done) => {
- const user = new ListAssignee({
- id: 1,
- name: 'testing 123',
- username: 'test',
- avatar: 'test_image',
- });
-
- list.issues.push(
- new ListIssue({
- title: 'Testing',
- id: 1,
- confidential: false,
- labels: [new ListLabel(list.label)],
- assignees: [],
- }),
- );
- const dummyIssue = new ListIssue({
- title: 'new issue',
- id: 2,
- confidential: false,
- labels: [new ListLabel(list.label)],
- assignees: [user],
- subscribed: false,
- });
-
- list
- .newIssue(dummyIssue)
- .then(() => {
- expect(list.issues.length).toBe(2);
- expect(list.issues[0]).toBe(dummyIssue);
- expect(list.issues[0].subscribed).toBe(false);
- expect(list.issues[0].assignableLabelsEndpoint).toBe('/issue/42/labels');
- expect(list.issues[0].toggleSubscriptionEndpoint).toBe('/issue/42/subscriptions');
- expect(list.issues[0].sidebarInfoEndpoint).toBe('/issue/42/sidebar_info');
- expect(list.issues[0].labels).toBe(dummyIssue.labels);
- expect(list.issues[0].assignees).toBe(dummyIssue.assignees);
- })
- .then(done)
- .catch(done.fail);
- });
- });
-});
diff --git a/spec/frontend/boards/mock_data.js b/spec/frontend/boards/mock_data.js
index 106f7b04c4b..6a4f344bbfb 100644
--- a/spec/frontend/boards/mock_data.js
+++ b/spec/frontend/boards/mock_data.js
@@ -1,12 +1,8 @@
-/* global List */
-
import { GlFilteredSearchToken } from '@gitlab/ui';
import { keyBy } from 'lodash';
-import Vue from 'vue';
-import '~/boards/models/list';
import { ListType } from '~/boards/constants';
-import boardsStore from '~/boards/stores/boards_store';
import { __ } from '~/locale';
+import { DEFAULT_MILESTONES_GRAPHQL } from '~/vue_shared/components/filtered_search_bar/constants';
import AuthorToken from '~/vue_shared/components/filtered_search_bar/tokens/author_token.vue';
import LabelToken from '~/vue_shared/components/filtered_search_bar/tokens/label_token.vue';
import MilestoneToken from '~/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue';
@@ -196,8 +192,7 @@ export const mockIssue = {
export const mockActiveIssue = {
...mockIssue,
- fullId: 'gid://gitlab/Issue/436',
- id: 436,
+ id: 'gid://gitlab/Issue/436',
iid: '27',
subscribed: false,
emailsDisabled: false,
@@ -289,20 +284,6 @@ export const boardsMockInterceptor = (config) => {
return [200, body];
};
-export const setMockEndpoints = (opts = {}) => {
- const boardsEndpoint = opts.boardsEndpoint || '/test/issue-boards/-/boards.json';
- const listsEndpoint = opts.listsEndpoint || '/test/-/boards/1/lists';
- const bulkUpdatePath = opts.bulkUpdatePath || '';
- const boardId = opts.boardId || '1';
-
- boardsStore.setEndpoints({
- boardsEndpoint,
- listsEndpoint,
- bulkUpdatePath,
- boardId,
- });
-};
-
export const mockList = {
id: 'gid://gitlab/List/1',
title: 'Open',
@@ -335,14 +316,26 @@ export const mockLabelList = {
issuesCount: 0,
};
+export const mockMilestoneList = {
+ id: 'gid://gitlab/List/3',
+ title: 'To Do',
+ position: 0,
+ listType: 'milestone',
+ collapsed: false,
+ label: null,
+ assignee: null,
+ milestone: {
+ webUrl: 'https://gitlab.com/h5bp/html5-boilerplate/-/milestones/1',
+ title: 'Backlog',
+ },
+ loading: false,
+ issuesCount: 0,
+};
+
export const mockLists = [mockList, mockLabelList];
export const mockListsById = keyBy(mockLists, 'id');
-export const mockListsWithModel = mockLists.map((listMock) =>
- Vue.observable(new List({ ...listMock, doNotFetchIssues: true })),
-);
-
export const mockIssuesByListId = {
'gid://gitlab/List/1': [mockIssue.id, mockIssue3.id, mockIssue4.id],
'gid://gitlab/List/2': mockIssues.map(({ id }) => id),
@@ -547,17 +540,17 @@ export const mockMoveData = {
export const mockTokens = (fetchLabels, fetchAuthors, fetchMilestones) => [
{
- icon: 'labels',
- title: __('Label'),
- type: 'label_name',
+ icon: 'user',
+ title: __('Assignee'),
+ type: 'assignee_username',
operators: [
{ value: '=', description: 'is' },
{ value: '!=', description: 'is not' },
],
- token: LabelToken,
- unique: false,
- symbol: '~',
- fetchLabels,
+ token: AuthorToken,
+ unique: true,
+ fetchAuthors,
+ preloadedAuthors: [],
},
{
icon: 'pencil',
@@ -574,17 +567,27 @@ export const mockTokens = (fetchLabels, fetchAuthors, fetchMilestones) => [
preloadedAuthors: [],
},
{
- icon: 'user',
- title: __('Assignee'),
- type: 'assignee_username',
+ icon: 'labels',
+ title: __('Label'),
+ type: 'label_name',
operators: [
{ value: '=', description: 'is' },
{ value: '!=', description: 'is not' },
],
- token: AuthorToken,
+ token: LabelToken,
+ unique: false,
+ symbol: '~',
+ fetchLabels,
+ },
+ {
+ icon: 'clock',
+ title: __('Milestone'),
+ symbol: '%',
+ type: 'milestone_title',
+ token: MilestoneToken,
unique: true,
- fetchAuthors,
- preloadedAuthors: [],
+ defaultMilestones: DEFAULT_MILESTONES_GRAPHQL,
+ fetchMilestones,
},
{
icon: 'issues',
@@ -599,16 +602,6 @@ export const mockTokens = (fetchLabels, fetchAuthors, fetchMilestones) => [
],
},
{
- icon: 'clock',
- title: __('Milestone'),
- symbol: '%',
- type: 'milestone_title',
- token: MilestoneToken,
- unique: true,
- defaultMilestones: [],
- fetchMilestones,
- },
- {
icon: 'weight',
title: __('Weight'),
type: 'weight',
diff --git a/spec/frontend/boards/project_select_deprecated_spec.js b/spec/frontend/boards/project_select_deprecated_spec.js
deleted file mode 100644
index 4494de43083..00000000000
--- a/spec/frontend/boards/project_select_deprecated_spec.js
+++ /dev/null
@@ -1,263 +0,0 @@
-import { GlDropdown, GlDropdownItem, GlSearchBoxByType, GlLoadingIcon } from '@gitlab/ui';
-import { mount } from '@vue/test-utils';
-import axios from 'axios';
-import AxiosMockAdapter from 'axios-mock-adapter';
-import ProjectSelect from '~/boards/components/project_select_deprecated.vue';
-import { ListType } from '~/boards/constants';
-import eventHub from '~/boards/eventhub';
-import createFlash from '~/flash';
-import httpStatus from '~/lib/utils/http_status';
-import { featureAccessLevel } from '~/pages/projects/shared/permissions/constants';
-
-import { listObj, mockRawGroupProjects } from './mock_data';
-
-jest.mock('~/boards/eventhub');
-jest.mock('~/flash');
-
-const dummyGon = {
- api_version: 'v4',
- relative_url_root: '/gitlab',
-};
-
-const mockGroupId = 1;
-const mockProjectsList1 = mockRawGroupProjects.slice(0, 1);
-const mockProjectsList2 = mockRawGroupProjects.slice(1);
-const mockDefaultFetchOptions = {
- with_issues_enabled: true,
- with_shared: false,
- include_subgroups: true,
- order_by: 'similarity',
- archived: false,
-};
-
-const itemsPerPage = 20;
-
-describe('ProjectSelect component', () => {
- let wrapper;
- let axiosMock;
-
- const findLabel = () => wrapper.find("[data-testid='header-label']");
- const findGlDropdown = () => wrapper.find(GlDropdown);
- const findGlDropdownLoadingIcon = () =>
- findGlDropdown().find('button:first-child').find(GlLoadingIcon);
- const findGlSearchBoxByType = () => wrapper.find(GlSearchBoxByType);
- const findGlDropdownItems = () => wrapper.findAll(GlDropdownItem);
- const findFirstGlDropdownItem = () => findGlDropdownItems().at(0);
- const findInMenuLoadingIcon = () => wrapper.find("[data-testid='dropdown-text-loading-icon']");
- const findEmptySearchMessage = () => wrapper.find("[data-testid='empty-result-message']");
-
- const mockGetRequest = (data = [], statusCode = httpStatus.OK) => {
- axiosMock
- .onGet(`/gitlab/api/v4/groups/${mockGroupId}/projects.json`)
- .replyOnce(statusCode, data);
- };
-
- const searchForProject = async (keyword, waitForAll = true) => {
- findGlSearchBoxByType().vm.$emit('input', keyword);
-
- if (waitForAll) {
- await axios.waitForAll();
- }
- };
-
- const createWrapper = async ({ list = listObj } = {}, waitForAll = true) => {
- wrapper = mount(ProjectSelect, {
- propsData: {
- list,
- },
- provide: {
- groupId: 1,
- },
- });
-
- if (waitForAll) {
- await axios.waitForAll();
- }
- };
-
- beforeEach(() => {
- axiosMock = new AxiosMockAdapter(axios);
- window.gon = dummyGon;
- });
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- axiosMock.restore();
- jest.clearAllMocks();
- });
-
- it('displays a header title', async () => {
- createWrapper({});
-
- expect(findLabel().text()).toBe('Projects');
- });
-
- it('renders a default dropdown text', async () => {
- createWrapper({});
-
- expect(findGlDropdown().exists()).toBe(true);
- expect(findGlDropdown().text()).toContain('Select a project');
- });
-
- describe('when mounted', () => {
- it('displays a loading icon while projects are being fetched', async () => {
- mockGetRequest([]);
-
- createWrapper({}, false);
-
- expect(findGlDropdownLoadingIcon().exists()).toBe(true);
-
- await axios.waitForAll();
-
- expect(axiosMock.history.get[0].params).toMatchObject({ search: '' });
- expect(axiosMock.history.get[0].url).toBe(
- `/gitlab/api/v4/groups/${mockGroupId}/projects.json`,
- );
-
- expect(findGlDropdownLoadingIcon().exists()).toBe(false);
- });
- });
-
- describe('when dropdown menu is open', () => {
- describe('by default', () => {
- beforeEach(async () => {
- mockGetRequest(mockProjectsList1);
-
- await createWrapper();
- });
-
- it('shows GlSearchBoxByType with default attributes', () => {
- expect(findGlSearchBoxByType().exists()).toBe(true);
- expect(findGlSearchBoxByType().vm.$attrs).toMatchObject({
- placeholder: 'Search projects',
- debounce: '250',
- });
- });
-
- it("displays the fetched project's name", () => {
- expect(findFirstGlDropdownItem().exists()).toBe(true);
- expect(findFirstGlDropdownItem().text()).toContain(mockProjectsList1[0].name);
- });
-
- it("doesn't render loading icon in the menu", () => {
- expect(findInMenuLoadingIcon().isVisible()).toBe(false);
- });
-
- it('renders empty search result message', async () => {
- await createWrapper();
-
- expect(findEmptySearchMessage().exists()).toBe(true);
- });
- });
-
- describe('when a project is selected', () => {
- beforeEach(async () => {
- mockGetRequest(mockProjectsList1);
-
- await createWrapper();
-
- await findFirstGlDropdownItem().find('button').trigger('click');
- });
-
- it('emits setSelectedProject with correct project metadata', () => {
- expect(eventHub.$emit).toHaveBeenCalledWith('setSelectedProject', {
- id: mockProjectsList1[0].id,
- path: mockProjectsList1[0].path_with_namespace,
- name: mockProjectsList1[0].name,
- namespacedName: mockProjectsList1[0].name_with_namespace,
- });
- });
-
- it('renders the name of the selected project', () => {
- expect(findGlDropdown().find('.gl-new-dropdown-button-text').text()).toBe(
- mockProjectsList1[0].name,
- );
- });
- });
-
- describe('when user searches for a project', () => {
- beforeEach(async () => {
- mockGetRequest(mockProjectsList1);
-
- await createWrapper();
- });
-
- it('calls API with correct parameters with default fetch options', async () => {
- await searchForProject('foobar');
-
- const expectedApiParams = {
- search: 'foobar',
- per_page: itemsPerPage,
- ...mockDefaultFetchOptions,
- };
-
- expect(axiosMock.history.get[1].params).toMatchObject(expectedApiParams);
- expect(axiosMock.history.get[1].url).toBe(
- `/gitlab/api/v4/groups/${mockGroupId}/projects.json`,
- );
- });
-
- describe("when list type is defined and isn't backlog", () => {
- it('calls API with an additional fetch option (min_access_level)', async () => {
- axiosMock.reset();
-
- await createWrapper({ list: { ...listObj, type: ListType.label } });
-
- await searchForProject('foobar');
-
- const expectedApiParams = {
- search: 'foobar',
- per_page: itemsPerPage,
- ...mockDefaultFetchOptions,
- min_access_level: featureAccessLevel.EVERYONE,
- };
-
- expect(axiosMock.history.get[1].params).toMatchObject(expectedApiParams);
- expect(axiosMock.history.get[1].url).toBe(
- `/gitlab/api/v4/groups/${mockGroupId}/projects.json`,
- );
- });
- });
-
- it('displays and hides gl-loading-icon while and after fetching data', async () => {
- await searchForProject('some keyword', false);
-
- await wrapper.vm.$nextTick();
-
- expect(findInMenuLoadingIcon().isVisible()).toBe(true);
-
- await axios.waitForAll();
-
- expect(findInMenuLoadingIcon().isVisible()).toBe(false);
- });
-
- it('flashes an error message when fetching fails', async () => {
- mockGetRequest([], httpStatus.INTERNAL_SERVER_ERROR);
-
- await searchForProject('foobar');
-
- expect(createFlash).toHaveBeenCalledTimes(1);
- expect(createFlash).toHaveBeenCalledWith({
- message: 'Something went wrong while fetching projects',
- });
- });
-
- describe('with non-empty search result', () => {
- beforeEach(async () => {
- mockGetRequest(mockProjectsList2);
-
- await searchForProject('foobar');
- });
-
- it('displays the retrieved list of projects', async () => {
- expect(findFirstGlDropdownItem().text()).toContain(mockProjectsList2[0].name);
- });
-
- it('does not render empty search result message', async () => {
- expect(findEmptySearchMessage().exists()).toBe(false);
- });
- });
- });
- });
-});
diff --git a/spec/frontend/boards/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js
index 1272a573d2f..62e0fa7a68a 100644
--- a/spec/frontend/boards/stores/actions_spec.js
+++ b/spec/frontend/boards/stores/actions_spec.js
@@ -26,7 +26,6 @@ import issueCreateMutation from '~/boards/graphql/issue_create.mutation.graphql'
import actions, { gqlClient } from '~/boards/stores/actions';
import * as types from '~/boards/stores/mutation_types';
import mutations from '~/boards/stores/mutations';
-import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import {
mockLists,
@@ -107,12 +106,7 @@ describe('setFilters', () => {
});
describe('performSearch', () => {
- it('should dispatch setFilters action', (done) => {
- testAction(actions.performSearch, {}, {}, [], [{ type: 'setFilters', payload: {} }], done);
- });
-
- it('should dispatch setFilters, fetchLists and resetIssues action when graphqlBoardLists FF is on', (done) => {
- window.gon = { features: { graphqlBoardLists: true } };
+ it('should dispatch setFilters, fetchLists and resetIssues action', (done) => {
testAction(
actions.performSearch,
{},
@@ -496,12 +490,9 @@ describe('fetchLabels', () => {
jest.spyOn(gqlClient, 'query').mockResolvedValue(queryResponse);
const commit = jest.fn();
- const getters = {
- shouldUseGraphQL: () => true,
- };
const state = { boardType: 'group' };
- await actions.fetchLabels({ getters, state, commit });
+ await actions.fetchLabels({ state, commit });
expect(commit).toHaveBeenCalledWith(types.RECEIVE_LABELS_SUCCESS, labels);
});
@@ -954,7 +945,7 @@ describe('moveIssue', () => {
});
describe('moveIssueCard and undoMoveIssueCard', () => {
- describe('card should move without clonning', () => {
+ describe('card should move without cloning', () => {
let state;
let params;
let moveMutations;
@@ -1221,8 +1212,8 @@ describe('updateMovedIssueCard', () => {
describe('updateIssueOrder', () => {
const issues = {
- 436: mockIssue,
- 437: mockIssue2,
+ [mockIssue.id]: mockIssue,
+ [mockIssue2.id]: mockIssue2,
};
const state = {
@@ -1231,7 +1222,7 @@ describe('updateIssueOrder', () => {
};
const moveData = {
- itemId: 436,
+ itemId: mockIssue.id,
fromListId: 'gid://gitlab/List/1',
toListId: 'gid://gitlab/List/2',
};
@@ -1490,7 +1481,7 @@ describe('addListNewIssue', () => {
type: 'addListItem',
payload: {
list: fakeList,
- item: formatIssue({ ...mockIssue, id: getIdFromGraphQLId(mockIssue.id) }),
+ item: formatIssue(mockIssue),
position: 0,
},
},
diff --git a/spec/frontend/boards/stores/getters_spec.js b/spec/frontend/boards/stores/getters_spec.js
index c0774dd3ae1..b30968c45d7 100644
--- a/spec/frontend/boards/stores/getters_spec.js
+++ b/spec/frontend/boards/stores/getters_spec.js
@@ -77,12 +77,12 @@ describe('Boards - Getters', () => {
});
describe('getBoardItemById', () => {
- const state = { boardItems: { 1: 'issue' } };
+ const state = { boardItems: { 'gid://gitlab/Issue/1': 'issue' } };
it.each`
- id | expected
- ${'1'} | ${'issue'}
- ${''} | ${{}}
+ id | expected
+ ${'gid://gitlab/Issue/1'} | ${'issue'}
+ ${''} | ${{}}
`('returns $expected when $id is passed to state', ({ id, expected }) => {
expect(getters.getBoardItemById(state)(id)).toEqual(expected);
});
@@ -90,11 +90,11 @@ describe('Boards - Getters', () => {
describe('activeBoardItem', () => {
it.each`
- id | expected
- ${'1'} | ${'issue'}
- ${''} | ${{ id: '', iid: '', fullId: '' }}
+ id | expected
+ ${'gid://gitlab/Issue/1'} | ${'issue'}
+ ${''} | ${{ id: '', iid: '' }}
`('returns $expected when $id is passed to state', ({ id, expected }) => {
- const state = { boardItems: { 1: 'issue' }, activeId: id };
+ const state = { boardItems: { 'gid://gitlab/Issue/1': 'issue' }, activeId: id };
expect(getters.activeBoardItem(state)).toEqual(expected);
});
diff --git a/spec/frontend/boards/stores/mutations_spec.js b/spec/frontend/boards/stores/mutations_spec.js
index a2ba1e9eb5e..0e830258327 100644
--- a/spec/frontend/boards/stores/mutations_spec.js
+++ b/spec/frontend/boards/stores/mutations_spec.js
@@ -407,7 +407,7 @@ describe('Board Store Mutations', () => {
describe('MUTATE_ISSUE_SUCCESS', () => {
it('updates issue in issues state', () => {
const issues = {
- 436: { id: rawIssue.id },
+ [rawIssue.id]: { id: rawIssue.id },
};
state = {
@@ -419,7 +419,7 @@ describe('Board Store Mutations', () => {
issue: rawIssue,
});
- expect(state.boardItems).toEqual({ 436: { ...mockIssue, id: 436 } });
+ expect(state.boardItems).toEqual({ [mockIssue.id]: mockIssue });
});
});
@@ -545,7 +545,7 @@ describe('Board Store Mutations', () => {
expect(state.groupProjectsFlags.isLoading).toBe(true);
});
- it('Should set isLoading in groupProjectsFlags to true in state when fetchNext is true', () => {
+ it('Should set isLoadingMore in groupProjectsFlags to true in state when fetchNext is true', () => {
mutations[types.REQUEST_GROUP_PROJECTS](state, true);
expect(state.groupProjectsFlags.isLoadingMore).toBe(true);
diff --git a/spec/frontend/clusters/components/__snapshots__/remove_cluster_confirmation_spec.js.snap b/spec/frontend/clusters/components/__snapshots__/remove_cluster_confirmation_spec.js.snap
index 0e1fe790771..b34265b7234 100644
--- a/spec/frontend/clusters/components/__snapshots__/remove_cluster_confirmation_spec.js.snap
+++ b/spec/frontend/clusters/components/__snapshots__/remove_cluster_confirmation_spec.js.snap
@@ -47,8 +47,26 @@ exports[`Remove cluster confirmation modal renders splitbutton with modal includ
<!---->
<div
+ class="gl-display-flex gl-flex-direction-row gl-justify-content-space-between gl-align-items-center gl-px-5"
+ >
+ <div
+ class="gl-display-flex"
+ >
+ <!---->
+ </div>
+
+ <div
+ class="gl-display-flex"
+ >
+ <!---->
+ </div>
+ </div>
+
+ <div
class="gl-new-dropdown-contents"
>
+ <!---->
+
<li
class="gl-new-dropdown-item"
role="presentation"
diff --git a/spec/frontend/confidential_merge_request/components/__snapshots__/project_form_group_spec.js.snap b/spec/frontend/confidential_merge_request/components/__snapshots__/project_form_group_spec.js.snap
index 271c6356f7e..c2fa6556847 100644
--- a/spec/frontend/confidential_merge_request/components/__snapshots__/project_form_group_spec.js.snap
+++ b/spec/frontend/confidential_merge_request/components/__snapshots__/project_form_group_spec.js.snap
@@ -17,11 +17,15 @@ exports[`Confidential merge request project form group component renders empty s
No forks are available to you.
<br />
-
- <gl-sprintf-stub
- message="To protect this issue's confidentiality, %{forkLink} and set the fork's visibility to private."
- />
-
+ To protect this issue's confidentiality,
+ <a
+ class="help-link"
+ href="https://test.com"
+ target="_blank"
+ >
+ fork this project
+ </a>
+ and set the fork's visibility to private.
<gl-link-stub
class="w-auto p-0 d-inline-block text-primary bg-transparent"
href="/help"
@@ -52,18 +56,16 @@ exports[`Confidential merge request project form group component renders fork dr
</label>
<div>
- <!---->
+ <dropdown-stub
+ projects="[object Object],[object Object]"
+ selectedproject="[object Object]"
+ />
<p
class="text-muted mt-1 mb-0"
>
- No forks are available to you.
- <br />
-
- <gl-sprintf-stub
- message="To protect this issue's confidentiality, %{forkLink} and set the fork's visibility to private."
- />
+ To protect this issue's confidentiality, a private fork of this project was selected.
<gl-link-stub
class="w-auto p-0 d-inline-block text-primary bg-transparent"
diff --git a/spec/frontend/confidential_merge_request/components/project_form_group_spec.js b/spec/frontend/confidential_merge_request/components/project_form_group_spec.js
index 67f6d360f52..0e73d50fdb5 100644
--- a/spec/frontend/confidential_merge_request/components/project_form_group_spec.js
+++ b/spec/frontend/confidential_merge_request/components/project_form_group_spec.js
@@ -1,3 +1,4 @@
+import { GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import ProjectFormGroup from '~/confidential_merge_request/components/project_form_group.vue';
@@ -21,55 +22,52 @@ const mockData = [
},
},
];
-let vm;
+let wrapper;
let mock;
function factory(projects = mockData) {
mock = new MockAdapter(axios);
mock.onGet(/api\/(.*)\/projects\/gitlab-org%2Fgitlab-ce\/forks/).reply(200, projects);
- vm = shallowMount(ProjectFormGroup, {
+ wrapper = shallowMount(ProjectFormGroup, {
propsData: {
namespacePath: 'gitlab-org',
projectPath: 'gitlab-org/gitlab-ce',
newForkPath: 'https://test.com',
helpPagePath: '/help',
},
+ stubs: { GlSprintf },
});
+
+ return axios.waitForAll();
}
describe('Confidential merge request project form group component', () => {
afterEach(() => {
mock.restore();
- vm.destroy();
+ wrapper.destroy();
});
- it('renders fork dropdown', () => {
- factory();
+ it('renders fork dropdown', async () => {
+ await factory();
- return vm.vm.$nextTick(() => {
- expect(vm.element).toMatchSnapshot();
- });
+ expect(wrapper.element).toMatchSnapshot();
});
- it('sets selected project as first fork', () => {
- factory();
+ it('sets selected project as first fork', async () => {
+ await factory();
- return vm.vm.$nextTick(() => {
- expect(vm.vm.selectedProject).toEqual({
- id: 1,
- name: 'root / gitlab-ce',
- pathWithNamespace: 'root/gitlab-ce',
- namespaceFullpath: 'root',
- });
+ expect(wrapper.vm.selectedProject).toEqual({
+ id: 1,
+ name: 'root / gitlab-ce',
+ pathWithNamespace: 'root/gitlab-ce',
+ namespaceFullpath: 'root',
});
});
- it('renders empty state when response is empty', () => {
- factory([]);
+ it('renders empty state when response is empty', async () => {
+ await factory([]);
- return vm.vm.$nextTick(() => {
- expect(vm.element).toMatchSnapshot();
- });
+ expect(wrapper.element).toMatchSnapshot();
});
});
diff --git a/spec/frontend/content_editor/components/__snapshots__/toolbar_link_button_spec.js.snap b/spec/frontend/content_editor/components/__snapshots__/toolbar_link_button_spec.js.snap
index 3c88c05a4b4..8f5516545eb 100644
--- a/spec/frontend/content_editor/components/__snapshots__/toolbar_link_button_spec.js.snap
+++ b/spec/frontend/content_editor/components/__snapshots__/toolbar_link_button_spec.js.snap
@@ -11,7 +11,16 @@ exports[`content_editor/components/toolbar_link_button renders dropdown componen
<ul role=\\"menu\\" tabindex=\\"-1\\" class=\\"dropdown-menu\\">
<div class=\\"gl-new-dropdown-inner\\">
<!---->
+ <div class=\\"gl-display-flex gl-flex-direction-row gl-justify-content-space-between gl-align-items-center gl-px-5\\">
+ <div class=\\"gl-display-flex\\">
+ <!---->
+ </div>
+ <div class=\\"gl-display-flex\\">
+ <!---->
+ </div>
+ </div>
<div class=\\"gl-new-dropdown-contents\\">
+ <!---->
<li role=\\"presentation\\" class=\\"gl-px-3!\\">
<form tabindex=\\"-1\\" class=\\"b-dropdown-form gl-p-0\\">
<div placeholder=\\"Link URL\\">
diff --git a/spec/frontend/content_editor/components/content_editor_spec.js b/spec/frontend/content_editor/components/content_editor_spec.js
index d516baf6f0f..3d1ef03083d 100644
--- a/spec/frontend/content_editor/components/content_editor_spec.js
+++ b/spec/frontend/content_editor/components/content_editor_spec.js
@@ -6,6 +6,7 @@ import ContentEditor from '~/content_editor/components/content_editor.vue';
import ContentEditorError from '~/content_editor/components/content_editor_error.vue';
import ContentEditorProvider from '~/content_editor/components/content_editor_provider.vue';
import EditorStateObserver from '~/content_editor/components/editor_state_observer.vue';
+import FormattingBubbleMenu from '~/content_editor/components/formatting_bubble_menu.vue';
import TopToolbar from '~/content_editor/components/top_toolbar.vue';
import {
LOADING_CONTENT_EVENT,
@@ -25,6 +26,7 @@ describe('ContentEditor', () => {
const findEditorElement = () => wrapper.findByTestId('content-editor');
const findEditorContent = () => wrapper.findComponent(EditorContent);
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
+ const findBubbleMenu = () => wrapper.findComponent(FormattingBubbleMenu);
const createWrapper = (propsData = {}) => {
renderMarkdown = jest.fn();
@@ -131,6 +133,10 @@ describe('ContentEditor', () => {
it('hides EditorContent component', () => {
expect(findEditorContent().exists()).toBe(false);
});
+
+ it('hides formatting bubble menu', () => {
+ expect(findBubbleMenu().exists()).toBe(false);
+ });
});
describe('when loading content succeeds', () => {
@@ -171,5 +177,9 @@ describe('ContentEditor', () => {
it('displays EditorContent component', () => {
expect(findEditorContent().exists()).toBe(true);
});
+
+ it('displays formatting bubble menu', () => {
+ expect(findBubbleMenu().exists()).toBe(true);
+ });
});
});
diff --git a/spec/frontend/content_editor/components/wrappers/table_cell_base_spec.js b/spec/frontend/content_editor/components/wrappers/table_cell_base_spec.js
new file mode 100644
index 00000000000..e48f59f6d9c
--- /dev/null
+++ b/spec/frontend/content_editor/components/wrappers/table_cell_base_spec.js
@@ -0,0 +1,193 @@
+import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
+import { NodeViewWrapper } from '@tiptap/vue-2';
+import { selectedRect as getSelectedRect } from 'prosemirror-tables';
+import { nextTick } from 'vue';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import TableCellBaseWrapper from '~/content_editor/components/wrappers/table_cell_base.vue';
+import { createTestEditor, mockChainedCommands, emitEditorEvent } from '../../test_utils';
+
+jest.mock('prosemirror-tables');
+
+describe('content/components/wrappers/table_cell_base', () => {
+ let wrapper;
+ let editor;
+ let getPos;
+
+ const createWrapper = async (propsData = { cellType: 'td' }) => {
+ wrapper = shallowMountExtended(TableCellBaseWrapper, {
+ propsData: {
+ editor,
+ getPos,
+ ...propsData,
+ },
+ });
+ };
+
+ const findDropdown = () => wrapper.findComponent(GlDropdown);
+ const findDropdownItemWithLabel = (name) =>
+ wrapper
+ .findAllComponents(GlDropdownItem)
+ .filter((dropdownItem) => dropdownItem.text().includes(name))
+ .at(0);
+ const findDropdownItemWithLabelExists = (name) =>
+ wrapper
+ .findAllComponents(GlDropdownItem)
+ .filter((dropdownItem) => dropdownItem.text().includes(name)).length > 0;
+ const setCurrentPositionInCell = () => {
+ const { $cursor } = editor.state.selection;
+
+ getPos.mockReturnValue($cursor.pos - $cursor.parentOffset - 1);
+ };
+ const mockDropdownHide = () => {
+ /*
+ * TODO: Replace this method with using the scoped hide function
+ * provided by BootstrapVue https://bootstrap-vue.org/docs/components/dropdown.
+ * GitLab UI is not exposing it in the default scope
+ */
+ findDropdown().vm.hide = jest.fn();
+ };
+
+ beforeEach(() => {
+ getPos = jest.fn();
+ editor = createTestEditor({});
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders a td node-view-wrapper with relative position', () => {
+ createWrapper();
+ expect(wrapper.findComponent(NodeViewWrapper).classes()).toContain('gl-relative');
+ expect(wrapper.findComponent(NodeViewWrapper).props().as).toBe('td');
+ });
+
+ it('displays dropdown when selection cursor is on the cell', async () => {
+ setCurrentPositionInCell();
+ createWrapper();
+
+ await nextTick();
+
+ expect(findDropdown().props()).toMatchObject({
+ category: 'tertiary',
+ icon: 'chevron-down',
+ size: 'small',
+ split: false,
+ });
+ expect(findDropdown().attributes()).toMatchObject({
+ boundary: 'viewport',
+ 'no-caret': '',
+ });
+ });
+
+ it('does not display dropdown when selection cursor is not on the cell', async () => {
+ createWrapper();
+
+ await nextTick();
+
+ expect(findDropdown().exists()).toBe(false);
+ });
+
+ describe('when dropdown is visible', () => {
+ beforeEach(async () => {
+ setCurrentPositionInCell();
+ getSelectedRect.mockReturnValue({
+ map: {
+ height: 1,
+ width: 1,
+ },
+ });
+
+ createWrapper();
+ await nextTick();
+
+ mockDropdownHide();
+ });
+
+ it.each`
+ dropdownItemLabel | commandName
+ ${'Insert column before'} | ${'addColumnBefore'}
+ ${'Insert column after'} | ${'addColumnAfter'}
+ ${'Insert row before'} | ${'addRowBefore'}
+ ${'Insert row after'} | ${'addRowAfter'}
+ ${'Delete table'} | ${'deleteTable'}
+ `(
+ 'executes $commandName when $dropdownItemLabel button is clicked',
+ ({ commandName, dropdownItemLabel }) => {
+ const mocks = mockChainedCommands(editor, [commandName, 'run']);
+
+ findDropdownItemWithLabel(dropdownItemLabel).vm.$emit('click');
+
+ expect(mocks[commandName]).toHaveBeenCalled();
+ },
+ );
+
+ it('does not allow deleting rows and columns', async () => {
+ expect(findDropdownItemWithLabelExists('Delete row')).toBe(false);
+ expect(findDropdownItemWithLabelExists('Delete column')).toBe(false);
+ });
+
+ it('allows deleting rows when there are more than 2 rows in the table', async () => {
+ const mocks = mockChainedCommands(editor, ['deleteRow', 'run']);
+
+ getSelectedRect.mockReturnValue({
+ map: {
+ height: 3,
+ },
+ });
+
+ emitEditorEvent({ tiptapEditor: editor, event: 'selectionUpdate' });
+
+ await nextTick();
+
+ findDropdownItemWithLabel('Delete row').vm.$emit('click');
+
+ expect(mocks.deleteRow).toHaveBeenCalled();
+ });
+
+ it('allows deleting columns when there are more than 1 column in the table', async () => {
+ const mocks = mockChainedCommands(editor, ['deleteColumn', 'run']);
+
+ getSelectedRect.mockReturnValue({
+ map: {
+ width: 2,
+ },
+ });
+
+ emitEditorEvent({ tiptapEditor: editor, event: 'selectionUpdate' });
+
+ await nextTick();
+
+ findDropdownItemWithLabel('Delete column').vm.$emit('click');
+
+ expect(mocks.deleteColumn).toHaveBeenCalled();
+ });
+
+ describe('when current row is the table’s header', () => {
+ beforeEach(async () => {
+ // Remove 2 rows condition
+ getSelectedRect.mockReturnValue({
+ map: {
+ height: 3,
+ },
+ });
+
+ createWrapper({ cellType: 'th' });
+
+ await nextTick();
+ });
+
+ it('does not allow adding a row before the header', async () => {
+ expect(findDropdownItemWithLabelExists('Insert row before')).toBe(false);
+ });
+
+ it('does not allow removing the header row', async () => {
+ createWrapper({ cellType: 'th' });
+
+ await nextTick();
+
+ expect(findDropdownItemWithLabelExists('Delete row')).toBe(false);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/content_editor/components/wrappers/table_cell_body_spec.js b/spec/frontend/content_editor/components/wrappers/table_cell_body_spec.js
new file mode 100644
index 00000000000..5d26c44ba03
--- /dev/null
+++ b/spec/frontend/content_editor/components/wrappers/table_cell_body_spec.js
@@ -0,0 +1,37 @@
+import { shallowMount } from '@vue/test-utils';
+import TableCellBaseWrapper from '~/content_editor/components/wrappers/table_cell_base.vue';
+import TableCellBodyWrapper from '~/content_editor/components/wrappers/table_cell_body.vue';
+import { createTestEditor } from '../../test_utils';
+
+describe('content/components/wrappers/table_cell_body', () => {
+ let wrapper;
+ let editor;
+ let getPos;
+
+ const createWrapper = async () => {
+ wrapper = shallowMount(TableCellBodyWrapper, {
+ propsData: {
+ editor,
+ getPos,
+ },
+ });
+ };
+
+ beforeEach(() => {
+ getPos = jest.fn();
+ editor = createTestEditor({});
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders a TableCellBase component', () => {
+ createWrapper();
+ expect(wrapper.findComponent(TableCellBaseWrapper).props()).toEqual({
+ editor,
+ getPos,
+ cellType: 'td',
+ });
+ });
+});
diff --git a/spec/frontend/content_editor/components/wrappers/table_cell_header_spec.js b/spec/frontend/content_editor/components/wrappers/table_cell_header_spec.js
new file mode 100644
index 00000000000..e561191418d
--- /dev/null
+++ b/spec/frontend/content_editor/components/wrappers/table_cell_header_spec.js
@@ -0,0 +1,37 @@
+import { shallowMount } from '@vue/test-utils';
+import TableCellBaseWrapper from '~/content_editor/components/wrappers/table_cell_base.vue';
+import TableCellHeaderWrapper from '~/content_editor/components/wrappers/table_cell_header.vue';
+import { createTestEditor } from '../../test_utils';
+
+describe('content/components/wrappers/table_cell_header', () => {
+ let wrapper;
+ let editor;
+ let getPos;
+
+ const createWrapper = async () => {
+ wrapper = shallowMount(TableCellHeaderWrapper, {
+ propsData: {
+ editor,
+ getPos,
+ },
+ });
+ };
+
+ beforeEach(() => {
+ getPos = jest.fn();
+ editor = createTestEditor({});
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders a TableCellBase component', () => {
+ createWrapper();
+ expect(wrapper.findComponent(TableCellBaseWrapper).props()).toEqual({
+ editor,
+ getPos,
+ cellType: 'th',
+ });
+ });
+});
diff --git a/spec/frontend/content_editor/extensions/attachment_spec.js b/spec/frontend/content_editor/extensions/attachment_spec.js
index 1334b1ddaad..d4f05a25bd6 100644
--- a/spec/frontend/content_editor/extensions/attachment_spec.js
+++ b/spec/frontend/content_editor/extensions/attachment_spec.js
@@ -1,18 +1,23 @@
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
-import { once } from 'lodash';
-import waitForPromises from 'helpers/wait_for_promises';
import Attachment from '~/content_editor/extensions/attachment';
import Image from '~/content_editor/extensions/image';
import Link from '~/content_editor/extensions/link';
import Loading from '~/content_editor/extensions/loading';
import httpStatus from '~/lib/utils/http_status';
-import { loadMarkdownApiResult } from '../markdown_processing_examples';
import { createTestEditor, createDocBuilder } from '../test_utils';
+const PROJECT_WIKI_ATTACHMENT_IMAGE_HTML = `<p data-sourcepos="1:1-1:27" dir="auto">
+ <a class="no-attachment-icon" href="/group1/project1/-/wikis/test-file.png" target="_blank" rel="noopener noreferrer" data-canonical-src="test-file.png">
+ <img alt="test-file" class="lazy" data-src="/group1/project1/-/wikis/test-file.png" data-canonical-src="test-file.png">
+ </a>
+</p>`;
+const PROJECT_WIKI_ATTACHMENT_LINK_HTML = `<p data-sourcepos="1:1-1:26" dir="auto">
+ <a href="/group1/project1/-/wikis/test-file.zip" data-canonical-src="test-file.zip">test-file</a>
+</p>`;
+
describe('content_editor/extensions/attachment', () => {
let tiptapEditor;
- let eq;
let doc;
let p;
let image;
@@ -25,6 +30,24 @@ describe('content_editor/extensions/attachment', () => {
const imageFile = new File(['foo'], 'test-file.png', { type: 'image/png' });
const attachmentFile = new File(['foo'], 'test-file.zip', { type: 'application/zip' });
+ const expectDocumentAfterTransaction = ({ number, expectedDoc, action }) => {
+ return new Promise((resolve) => {
+ let counter = 1;
+ const handleTransaction = () => {
+ if (counter === number) {
+ expect(tiptapEditor.state.doc.toJSON()).toEqual(expectedDoc.toJSON());
+ tiptapEditor.off('update', handleTransaction);
+ resolve();
+ }
+
+ counter += 1;
+ };
+
+ tiptapEditor.on('update', handleTransaction);
+ action();
+ });
+ };
+
beforeEach(() => {
renderMarkdown = jest.fn();
@@ -34,7 +57,6 @@ describe('content_editor/extensions/attachment', () => {
({
builders: { doc, p, image, loading, link },
- eq,
} = createDocBuilder({
tiptapEditor,
names: {
@@ -76,9 +98,7 @@ describe('content_editor/extensions/attachment', () => {
const base64EncodedFile = 'data:image/png;base64,Zm9v';
beforeEach(() => {
- renderMarkdown.mockResolvedValue(
- loadMarkdownApiResult('project_wiki_attachment_image').body,
- );
+ renderMarkdown.mockResolvedValue(PROJECT_WIKI_ATTACHMENT_IMAGE_HTML);
});
describe('when uploading succeeds', () => {
@@ -92,18 +112,14 @@ describe('content_editor/extensions/attachment', () => {
mock.onPost().reply(httpStatus.OK, successResponse);
});
- it('inserts an image with src set to the encoded image file and uploading true', (done) => {
+ it('inserts an image with src set to the encoded image file and uploading true', async () => {
const expectedDoc = doc(p(image({ uploading: true, src: base64EncodedFile })));
- tiptapEditor.on(
- 'update',
- once(() => {
- expect(eq(tiptapEditor.state.doc, expectedDoc)).toBe(true);
- done();
- }),
- );
-
- tiptapEditor.commands.uploadAttachment({ file: imageFile });
+ await expectDocumentAfterTransaction({
+ number: 1,
+ expectedDoc,
+ action: () => tiptapEditor.commands.uploadAttachment({ file: imageFile }),
+ });
});
it('updates the inserted image with canonicalSrc when upload is successful', async () => {
@@ -118,11 +134,11 @@ describe('content_editor/extensions/attachment', () => {
),
);
- tiptapEditor.commands.uploadAttachment({ file: imageFile });
-
- await waitForPromises();
-
- expect(eq(tiptapEditor.state.doc, expectedDoc)).toBe(true);
+ await expectDocumentAfterTransaction({
+ number: 2,
+ expectedDoc,
+ action: () => tiptapEditor.commands.uploadAttachment({ file: imageFile }),
+ });
});
});
@@ -131,14 +147,14 @@ describe('content_editor/extensions/attachment', () => {
mock.onPost().reply(httpStatus.INTERNAL_SERVER_ERROR);
});
- it('resets the doc to orginal state', async () => {
+ it('resets the doc to original state', async () => {
const expectedDoc = doc(p(''));
- tiptapEditor.commands.uploadAttachment({ file: imageFile });
-
- await waitForPromises();
-
- expect(eq(tiptapEditor.state.doc, expectedDoc)).toBe(true);
+ await expectDocumentAfterTransaction({
+ number: 2,
+ expectedDoc,
+ action: () => tiptapEditor.commands.uploadAttachment({ file: imageFile }),
+ });
});
it('emits an error event that includes an error message', (done) => {
@@ -153,7 +169,7 @@ describe('content_editor/extensions/attachment', () => {
});
describe('when the file has a zip (or any other attachment) mime type', () => {
- const markdownApiResult = loadMarkdownApiResult('project_wiki_attachment_link').body;
+ const markdownApiResult = PROJECT_WIKI_ATTACHMENT_LINK_HTML;
beforeEach(() => {
renderMarkdown.mockResolvedValue(markdownApiResult);
@@ -170,18 +186,14 @@ describe('content_editor/extensions/attachment', () => {
mock.onPost().reply(httpStatus.OK, successResponse);
});
- it('inserts a loading mark', (done) => {
+ it('inserts a loading mark', async () => {
const expectedDoc = doc(p(loading({ label: 'test-file' })));
- tiptapEditor.on(
- 'update',
- once(() => {
- expect(eq(tiptapEditor.state.doc, expectedDoc)).toBe(true);
- done();
- }),
- );
-
- tiptapEditor.commands.uploadAttachment({ file: attachmentFile });
+ await expectDocumentAfterTransaction({
+ number: 1,
+ expectedDoc,
+ action: () => tiptapEditor.commands.uploadAttachment({ file: attachmentFile }),
+ });
});
it('updates the loading mark with a link with canonicalSrc and href attrs', async () => {
@@ -198,11 +210,11 @@ describe('content_editor/extensions/attachment', () => {
),
);
- tiptapEditor.commands.uploadAttachment({ file: attachmentFile });
-
- await waitForPromises();
-
- expect(eq(tiptapEditor.state.doc, expectedDoc)).toBe(true);
+ await expectDocumentAfterTransaction({
+ number: 2,
+ expectedDoc,
+ action: () => tiptapEditor.commands.uploadAttachment({ file: attachmentFile }),
+ });
});
});
@@ -214,11 +226,11 @@ describe('content_editor/extensions/attachment', () => {
it('resets the doc to orginal state', async () => {
const expectedDoc = doc(p(''));
- tiptapEditor.commands.uploadAttachment({ file: attachmentFile });
-
- await waitForPromises();
-
- expect(eq(tiptapEditor.state.doc, expectedDoc)).toBe(true);
+ await expectDocumentAfterTransaction({
+ number: 2,
+ expectedDoc,
+ action: () => tiptapEditor.commands.uploadAttachment({ file: attachmentFile }),
+ });
});
it('emits an error event that includes an error message', (done) => {
diff --git a/spec/frontend/content_editor/extensions/blockquote_spec.js b/spec/frontend/content_editor/extensions/blockquote_spec.js
new file mode 100644
index 00000000000..c5b5044352d
--- /dev/null
+++ b/spec/frontend/content_editor/extensions/blockquote_spec.js
@@ -0,0 +1,19 @@
+import { multilineInputRegex } from '~/content_editor/extensions/blockquote';
+
+describe('content_editor/extensions/blockquote', () => {
+ describe.each`
+ input | matches
+ ${'>>> '} | ${true}
+ ${' >>> '} | ${true}
+ ${'\t>>> '} | ${true}
+ ${'>> '} | ${false}
+ ${'>>>x '} | ${false}
+ ${'> '} | ${false}
+ `('multilineInputRegex', ({ input, matches }) => {
+ it(`${matches ? 'matches' : 'does not match'}: "${input}"`, () => {
+ const match = new RegExp(multilineInputRegex).test(input);
+
+ expect(match).toBe(matches);
+ });
+ });
+});
diff --git a/spec/frontend/content_editor/extensions/code_block_highlight_spec.js b/spec/frontend/content_editor/extensions/code_block_highlight_spec.js
index 188e6580dc6..6a0a0c76825 100644
--- a/spec/frontend/content_editor/extensions/code_block_highlight_spec.js
+++ b/spec/frontend/content_editor/extensions/code_block_highlight_spec.js
@@ -1,9 +1,15 @@
import CodeBlockHighlight from '~/content_editor/extensions/code_block_highlight';
-import { loadMarkdownApiResult } from '../markdown_processing_examples';
import { createTestEditor } from '../test_utils';
+const CODE_BLOCK_HTML = `<pre class="code highlight js-syntax-highlight language-javascript" lang="javascript" v-pre="true">
+ <code>
+ <span id="LC1" class="line" lang="javascript">
+ <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">hello world</span><span class="dl">'</span><span class="p">)</span>
+ </span>
+ </code>
+</pre>`;
+
describe('content_editor/extensions/code_block_highlight', () => {
- let codeBlockHtmlFixture;
let parsedCodeBlockHtmlFixture;
let tiptapEditor;
@@ -11,13 +17,10 @@ describe('content_editor/extensions/code_block_highlight', () => {
const preElement = () => parsedCodeBlockHtmlFixture.querySelector('pre');
beforeEach(() => {
- const { html } = loadMarkdownApiResult('code_block');
-
tiptapEditor = createTestEditor({ extensions: [CodeBlockHighlight] });
- codeBlockHtmlFixture = html;
- parsedCodeBlockHtmlFixture = parseHTML(codeBlockHtmlFixture);
+ parsedCodeBlockHtmlFixture = parseHTML(CODE_BLOCK_HTML);
- tiptapEditor.commands.setContent(codeBlockHtmlFixture);
+ tiptapEditor.commands.setContent(CODE_BLOCK_HTML);
});
it('extracts language and params attributes from Markdown API output', () => {
diff --git a/spec/frontend/content_editor/markdown_processing_examples.js b/spec/frontend/content_editor/markdown_processing_examples.js
index 12eed00f3c6..b3aabfeb145 100644
--- a/spec/frontend/content_editor/markdown_processing_examples.js
+++ b/spec/frontend/content_editor/markdown_processing_examples.js
@@ -6,7 +6,8 @@ import { getJSONFixture } from 'helpers/fixtures';
export const loadMarkdownApiResult = (testName) => {
const fixturePathPrefix = `api/markdown/${testName}.json`;
- return getJSONFixture(fixturePathPrefix);
+ const fixture = getJSONFixture(fixturePathPrefix);
+ return fixture.body || fixture.html;
};
export const loadMarkdownApiExamples = () => {
@@ -16,3 +17,9 @@ export const loadMarkdownApiExamples = () => {
return apiMarkdownExampleObjects.map(({ name, context, markdown }) => [name, context, markdown]);
};
+
+export const loadMarkdownApiExample = (testName) => {
+ return loadMarkdownApiExamples().find(([name, context]) => {
+ return (context ? `${context}_${name}` : name) === testName;
+ })[2];
+};
diff --git a/spec/frontend/content_editor/markdown_processing_spec.js b/spec/frontend/content_editor/markdown_processing_spec.js
index da3f6e64db8..71565768558 100644
--- a/spec/frontend/content_editor/markdown_processing_spec.js
+++ b/spec/frontend/content_editor/markdown_processing_spec.js
@@ -9,8 +9,9 @@ describe('markdown processing', () => {
'correctly handles %s (context: %s)',
async (name, context, markdown) => {
const testName = context ? `${context}_${name}` : name;
- const { html, body } = loadMarkdownApiResult(testName);
- const contentEditor = createContentEditor({ renderMarkdown: () => html || body });
+ const contentEditor = createContentEditor({
+ renderMarkdown: () => loadMarkdownApiResult(testName),
+ });
await contentEditor.setSerializedContent(markdown);
expect(contentEditor.getSerializedContent()).toBe(markdown);
diff --git a/spec/frontend/content_editor/services/mark_utils_spec.js b/spec/frontend/content_editor/services/mark_utils_spec.js
new file mode 100644
index 00000000000..bbfb8f26f99
--- /dev/null
+++ b/spec/frontend/content_editor/services/mark_utils_spec.js
@@ -0,0 +1,38 @@
+import {
+ markInputRegex,
+ extractMarkAttributesFromMatch,
+} from '~/content_editor/services/mark_utils';
+
+describe('content_editor/services/mark_utils', () => {
+ describe.each`
+ tag | input | matches
+ ${'tag'} | ${'<tag>hello</tag>'} | ${true}
+ ${'tag'} | ${'<tag title="tooltip">hello</tag>'} | ${true}
+ ${'kbd'} | ${'Hold <kbd>Ctrl</kbd>'} | ${true}
+ ${'time'} | ${'Lets meet at <time title="today" datetime="20:00">20:00</time>'} | ${true}
+ ${'tag'} | ${'<tag width=30 height=30>attrs not quoted</tag>'} | ${false}
+ ${'tag'} | ${"<tag title='abc'>single quote attrs not supported</tag>"} | ${false}
+ ${'tag'} | ${'<tag title>attr has no value</tag>'} | ${false}
+ ${'tag'} | ${'<tag>tag opened but not closed'} | ${false}
+ ${'tag'} | ${'</tag>tag closed before opened<tag>'} | ${false}
+ `('inputRegex("$tag")', ({ tag, input, matches }) => {
+ it(`${matches ? 'matches' : 'does not match'}: "${input}"`, () => {
+ const match = markInputRegex(tag).test(input);
+
+ expect(match).toBe(matches);
+ });
+ });
+
+ describe.each`
+ tag | input | attrs
+ ${'kbd'} | ${'Hold <kbd>Ctrl</kbd>'} | ${{}}
+ ${'tag'} | ${'<tag title="tooltip">hello</tag>'} | ${{ title: 'tooltip' }}
+ ${'time'} | ${'Lets meet at <time title="today" datetime="20:00">20:00</time>'} | ${{ title: 'today', datetime: '20:00' }}
+ ${'abbr'} | ${'Sure, you can try it out but <abbr title="Your mileage may vary">YMMV</abbr>'} | ${{ title: 'Your mileage may vary' }}
+ `('extractAttributesFromMatch(inputRegex("$tag").exec(\'$input\'))', ({ tag, input, attrs }) => {
+ it(`returns: "${JSON.stringify(attrs)}"`, () => {
+ const matches = markInputRegex(tag).exec(input);
+ expect(extractMarkAttributesFromMatch(matches)).toEqual(attrs);
+ });
+ });
+});
diff --git a/spec/frontend/content_editor/services/markdown_serializer_spec.js b/spec/frontend/content_editor/services/markdown_serializer_spec.js
new file mode 100644
index 00000000000..6f2c908c289
--- /dev/null
+++ b/spec/frontend/content_editor/services/markdown_serializer_spec.js
@@ -0,0 +1,1008 @@
+import Blockquote from '~/content_editor/extensions/blockquote';
+import Bold from '~/content_editor/extensions/bold';
+import BulletList from '~/content_editor/extensions/bullet_list';
+import Code from '~/content_editor/extensions/code';
+import CodeBlockHighlight from '~/content_editor/extensions/code_block_highlight';
+import DescriptionItem from '~/content_editor/extensions/description_item';
+import DescriptionList from '~/content_editor/extensions/description_list';
+import Division from '~/content_editor/extensions/division';
+import Emoji from '~/content_editor/extensions/emoji';
+import Figure from '~/content_editor/extensions/figure';
+import FigureCaption from '~/content_editor/extensions/figure_caption';
+import HardBreak from '~/content_editor/extensions/hard_break';
+import Heading from '~/content_editor/extensions/heading';
+import HorizontalRule from '~/content_editor/extensions/horizontal_rule';
+import Image from '~/content_editor/extensions/image';
+import InlineDiff from '~/content_editor/extensions/inline_diff';
+import Italic from '~/content_editor/extensions/italic';
+import Link from '~/content_editor/extensions/link';
+import ListItem from '~/content_editor/extensions/list_item';
+import OrderedList from '~/content_editor/extensions/ordered_list';
+import Paragraph from '~/content_editor/extensions/paragraph';
+import Strike from '~/content_editor/extensions/strike';
+import Table from '~/content_editor/extensions/table';
+import TableCell from '~/content_editor/extensions/table_cell';
+import TableHeader from '~/content_editor/extensions/table_header';
+import TableRow from '~/content_editor/extensions/table_row';
+import TaskItem from '~/content_editor/extensions/task_item';
+import TaskList from '~/content_editor/extensions/task_list';
+import Text from '~/content_editor/extensions/text';
+import markdownSerializer from '~/content_editor/services/markdown_serializer';
+import { createTestEditor, createDocBuilder } from '../test_utils';
+
+jest.mock('~/emoji');
+
+jest.mock('~/content_editor/services/feature_flags', () => ({
+ isBlockTablesFeatureEnabled: jest.fn().mockReturnValue(true),
+}));
+
+const tiptapEditor = createTestEditor({
+ extensions: [
+ Blockquote,
+ Bold,
+ BulletList,
+ Code,
+ CodeBlockHighlight,
+ DescriptionItem,
+ DescriptionList,
+ Division,
+ Emoji,
+ Figure,
+ FigureCaption,
+ HardBreak,
+ Heading,
+ HorizontalRule,
+ Image,
+ InlineDiff,
+ Italic,
+ Link,
+ ListItem,
+ OrderedList,
+ Paragraph,
+ Strike,
+ Table,
+ TableCell,
+ TableHeader,
+ TableRow,
+ TaskItem,
+ TaskList,
+ Text,
+ ],
+});
+
+const {
+ builders: {
+ doc,
+ blockquote,
+ bold,
+ bulletList,
+ code,
+ codeBlock,
+ division,
+ descriptionItem,
+ descriptionList,
+ emoji,
+ figure,
+ figureCaption,
+ heading,
+ hardBreak,
+ horizontalRule,
+ image,
+ inlineDiff,
+ italic,
+ link,
+ listItem,
+ orderedList,
+ paragraph,
+ strike,
+ table,
+ tableCell,
+ tableHeader,
+ tableRow,
+ taskItem,
+ taskList,
+ },
+} = createDocBuilder({
+ tiptapEditor,
+ names: {
+ blockquote: { nodeType: Blockquote.name },
+ bold: { markType: Bold.name },
+ bulletList: { nodeType: BulletList.name },
+ code: { markType: Code.name },
+ codeBlock: { nodeType: CodeBlockHighlight.name },
+ division: { nodeType: Division.name },
+ descriptionItem: { nodeType: DescriptionItem.name },
+ descriptionList: { nodeType: DescriptionList.name },
+ emoji: { markType: Emoji.name },
+ figure: { nodeType: Figure.name },
+ figureCaption: { nodeType: FigureCaption.name },
+ hardBreak: { nodeType: HardBreak.name },
+ heading: { nodeType: Heading.name },
+ horizontalRule: { nodeType: HorizontalRule.name },
+ image: { nodeType: Image.name },
+ inlineDiff: { markType: InlineDiff.name },
+ italic: { nodeType: Italic.name },
+ link: { markType: Link.name },
+ listItem: { nodeType: ListItem.name },
+ orderedList: { nodeType: OrderedList.name },
+ paragraph: { nodeType: Paragraph.name },
+ strike: { markType: Strike.name },
+ table: { nodeType: Table.name },
+ tableCell: { nodeType: TableCell.name },
+ tableHeader: { nodeType: TableHeader.name },
+ tableRow: { nodeType: TableRow.name },
+ taskItem: { nodeType: TaskItem.name },
+ taskList: { nodeType: TaskList.name },
+ },
+});
+
+const serialize = (...content) =>
+ markdownSerializer({}).serialize({
+ schema: tiptapEditor.schema,
+ content: doc(...content).toJSON(),
+ });
+
+describe('markdownSerializer', () => {
+ it('correctly serializes bold', () => {
+ expect(serialize(paragraph(bold('bold')))).toBe('**bold**');
+ });
+
+ it('correctly serializes italics', () => {
+ expect(serialize(paragraph(italic('italics')))).toBe('_italics_');
+ });
+
+ it('correctly serializes inline diff', () => {
+ expect(
+ serialize(
+ paragraph(
+ inlineDiff({ type: 'addition' }, '+30 lines'),
+ inlineDiff({ type: 'deletion' }, '-10 lines'),
+ ),
+ ),
+ ).toBe('{++30 lines+}{--10 lines-}');
+ });
+
+ it('correctly serializes a line break', () => {
+ expect(serialize(paragraph('hello', hardBreak(), 'world'))).toBe('hello\\\nworld');
+ });
+
+ it('correctly serializes a link', () => {
+ expect(serialize(paragraph(link({ href: 'https://example.com' }, 'example url')))).toBe(
+ '[example url](https://example.com)',
+ );
+ });
+
+ it('correctly serializes a plain URL link', () => {
+ expect(serialize(paragraph(link({ href: 'https://example.com' }, 'https://example.com')))).toBe(
+ '<https://example.com>',
+ );
+ });
+
+ it('correctly serializes a link with a title', () => {
+ expect(
+ serialize(
+ paragraph(link({ href: 'https://example.com', title: 'click this link' }, 'example url')),
+ ),
+ ).toBe('[example url](https://example.com "click this link")');
+ });
+
+ it('correctly serializes a plain URL link with a title', () => {
+ expect(
+ serialize(
+ paragraph(
+ link({ href: 'https://example.com', title: 'link title' }, 'https://example.com'),
+ ),
+ ),
+ ).toBe('[https://example.com](https://example.com "link title")');
+ });
+
+ it('correctly serializes a link with a canonicalSrc', () => {
+ expect(
+ serialize(
+ paragraph(
+ link(
+ {
+ href: '/uploads/abcde/file.zip',
+ canonicalSrc: 'file.zip',
+ title: 'click here to download',
+ },
+ 'download file',
+ ),
+ ),
+ ),
+ ).toBe('[download file](file.zip "click here to download")');
+ });
+
+ it('correctly serializes strikethrough', () => {
+ expect(serialize(paragraph(strike('deleted content')))).toBe('~~deleted content~~');
+ });
+
+ it('correctly serializes blockquotes with hard breaks', () => {
+ expect(serialize(blockquote('some text', hardBreak(), hardBreak(), 'new line'))).toBe(
+ `
+> some text\\
+> \\
+> new line
+ `.trim(),
+ );
+ });
+
+ it('correctly serializes blockquote with multiple block nodes', () => {
+ expect(serialize(blockquote(paragraph('some paragraph'), codeBlock('var x = 10;')))).toBe(
+ `
+> some paragraph
+>
+> \`\`\`
+> var x = 10;
+> \`\`\`
+ `.trim(),
+ );
+ });
+
+ it('correctly serializes a multiline blockquote', () => {
+ expect(
+ serialize(
+ blockquote(
+ { multiline: true },
+ paragraph('some paragraph with ', bold('bold')),
+ codeBlock('var y = 10;'),
+ ),
+ ),
+ ).toBe(
+ `
+>>>
+some paragraph with **bold**
+
+\`\`\`
+var y = 10;
+\`\`\`
+
+>>>
+ `.trim(),
+ );
+ });
+
+ it('correctly serializes a code block with language', () => {
+ expect(
+ serialize(
+ codeBlock(
+ { language: 'json' },
+ 'this is not really json but just trying out whether this case works or not',
+ ),
+ ),
+ ).toBe(
+ `
+\`\`\`json
+this is not really json but just trying out whether this case works or not
+\`\`\`
+ `.trim(),
+ );
+ });
+
+ it('correctly serializes emoji', () => {
+ expect(serialize(paragraph(emoji({ name: 'dog' })))).toBe(':dog:');
+ });
+
+ it('correctly serializes headings', () => {
+ expect(
+ serialize(
+ heading({ level: 1 }, 'Heading 1'),
+ heading({ level: 2 }, 'Heading 2'),
+ heading({ level: 3 }, 'Heading 3'),
+ heading({ level: 4 }, 'Heading 4'),
+ heading({ level: 5 }, 'Heading 5'),
+ heading({ level: 6 }, 'Heading 6'),
+ ),
+ ).toBe(
+ `
+# Heading 1
+
+## Heading 2
+
+### Heading 3
+
+#### Heading 4
+
+##### Heading 5
+
+###### Heading 6
+ `.trim(),
+ );
+ });
+
+ it('correctly serializes horizontal rule', () => {
+ expect(serialize(horizontalRule(), horizontalRule(), horizontalRule())).toBe(
+ `
+---
+
+---
+
+---
+ `.trim(),
+ );
+ });
+
+ it('correctly serializes an image', () => {
+ expect(serialize(paragraph(image({ src: 'img.jpg', alt: 'foo bar' })))).toBe(
+ '![foo bar](img.jpg)',
+ );
+ });
+
+ it('correctly serializes an image with a title', () => {
+ expect(serialize(paragraph(image({ src: 'img.jpg', title: 'baz', alt: 'foo bar' })))).toBe(
+ '![foo bar](img.jpg "baz")',
+ );
+ });
+
+ it('correctly serializes an image with a canonicalSrc', () => {
+ expect(
+ serialize(
+ paragraph(
+ image({
+ src: '/uploads/abcde/file.png',
+ alt: 'this is an image',
+ canonicalSrc: 'file.png',
+ title: 'foo bar baz',
+ }),
+ ),
+ ),
+ ).toBe('![this is an image](file.png "foo bar baz")');
+ });
+
+ it('correctly serializes bullet list', () => {
+ expect(
+ serialize(
+ bulletList(
+ listItem(paragraph('list item 1')),
+ listItem(paragraph('list item 2')),
+ listItem(paragraph('list item 3')),
+ ),
+ ),
+ ).toBe(
+ `
+* list item 1
+* list item 2
+* list item 3
+ `.trim(),
+ );
+ });
+
+ it('correctly serializes bullet list with different bullet styles', () => {
+ expect(
+ serialize(
+ bulletList(
+ { bullet: '+' },
+ listItem(paragraph('list item 1')),
+ listItem(paragraph('list item 2')),
+ listItem(
+ paragraph('list item 3'),
+ bulletList(
+ { bullet: '-' },
+ listItem(paragraph('sub-list item 1')),
+ listItem(paragraph('sub-list item 2')),
+ ),
+ ),
+ ),
+ ),
+ ).toBe(
+ `
++ list item 1
++ list item 2
++ list item 3
+ - sub-list item 1
+ - sub-list item 2
+ `.trim(),
+ );
+ });
+
+ it('correctly serializes a numeric list', () => {
+ expect(
+ serialize(
+ orderedList(
+ listItem(paragraph('list item 1')),
+ listItem(paragraph('list item 2')),
+ listItem(paragraph('list item 3')),
+ ),
+ ),
+ ).toBe(
+ `
+1. list item 1
+2. list item 2
+3. list item 3
+ `.trim(),
+ );
+ });
+
+ it('correctly serializes a numeric list with parens', () => {
+ expect(
+ serialize(
+ orderedList(
+ { parens: true },
+ listItem(paragraph('list item 1')),
+ listItem(paragraph('list item 2')),
+ listItem(paragraph('list item 3')),
+ ),
+ ),
+ ).toBe(
+ `
+1) list item 1
+2) list item 2
+3) list item 3
+ `.trim(),
+ );
+ });
+
+ it('correctly serializes a numeric list with a different start order', () => {
+ expect(
+ serialize(
+ orderedList(
+ { start: 17 },
+ listItem(paragraph('list item 1')),
+ listItem(paragraph('list item 2')),
+ listItem(paragraph('list item 3')),
+ ),
+ ),
+ ).toBe(
+ `
+17. list item 1
+18. list item 2
+19. list item 3
+ `.trim(),
+ );
+ });
+
+ it('correctly serializes a numeric list with an invalid start order', () => {
+ expect(
+ serialize(
+ orderedList(
+ { start: NaN },
+ listItem(paragraph('list item 1')),
+ listItem(paragraph('list item 2')),
+ listItem(paragraph('list item 3')),
+ ),
+ ),
+ ).toBe(
+ `
+1. list item 1
+2. list item 2
+3. list item 3
+ `.trim(),
+ );
+ });
+
+ it('correctly serializes a bullet list inside an ordered list', () => {
+ expect(
+ serialize(
+ orderedList(
+ { start: 17 },
+ listItem(paragraph('list item 1')),
+ listItem(paragraph('list item 2')),
+ listItem(
+ paragraph('list item 3'),
+ bulletList(
+ listItem(paragraph('sub-list item 1')),
+ listItem(paragraph('sub-list item 2')),
+ ),
+ ),
+ ),
+ ),
+ ).toBe(
+ // notice that 4 space indent works fine in this case,
+ // when it usually wouldn't
+ `
+17. list item 1
+18. list item 2
+19. list item 3
+ * sub-list item 1
+ * sub-list item 2
+ `.trim(),
+ );
+ });
+
+ it('correctly serializes a task list', () => {
+ expect(
+ serialize(
+ taskList(
+ taskItem({ checked: true }, paragraph('list item 1')),
+ taskItem(paragraph('list item 2')),
+ taskItem(
+ paragraph('list item 3'),
+ taskList(
+ taskItem({ checked: true }, paragraph('sub-list item 1')),
+ taskItem(paragraph('sub-list item 2')),
+ ),
+ ),
+ ),
+ ),
+ ).toBe(
+ `
+* [x] list item 1
+* [ ] list item 2
+* [ ] list item 3
+ * [x] sub-list item 1
+ * [ ] sub-list item 2
+ `.trim(),
+ );
+ });
+
+ it('correctly serializes a numeric task list + with start order', () => {
+ expect(
+ serialize(
+ taskList(
+ { numeric: true },
+ taskItem({ checked: true }, paragraph('list item 1')),
+ taskItem(paragraph('list item 2')),
+ taskItem(
+ paragraph('list item 3'),
+ taskList(
+ { numeric: true, start: 1351, parens: true },
+ taskItem({ checked: true }, paragraph('sub-list item 1')),
+ taskItem(paragraph('sub-list item 2')),
+ ),
+ ),
+ ),
+ ),
+ ).toBe(
+ `
+1. [x] list item 1
+2. [ ] list item 2
+3. [ ] list item 3
+ 1351) [x] sub-list item 1
+ 1352) [ ] sub-list item 2
+ `.trim(),
+ );
+ });
+
+ it('correctly renders a description list', () => {
+ expect(
+ serialize(
+ descriptionList(
+ descriptionItem(paragraph('Beast of Bodmin')),
+ descriptionItem({ isTerm: false }, paragraph('A large feline inhabiting Bodmin Moor.')),
+
+ descriptionItem(paragraph('Morgawr')),
+ descriptionItem({ isTerm: false }, paragraph('A sea serpent.')),
+
+ descriptionItem(paragraph('Owlman')),
+ descriptionItem(
+ { isTerm: false },
+ paragraph('A giant ', italic('owl-like'), ' creature.'),
+ ),
+ ),
+ ),
+ ).toBe(
+ `
+<dl>
+<dt>Beast of Bodmin</dt>
+<dd>A large feline inhabiting Bodmin Moor.</dd>
+<dt>Morgawr</dt>
+<dd>A sea serpent.</dd>
+<dt>Owlman</dt>
+<dd>
+
+A giant _owl-like_ creature.
+
+</dd>
+</dl>
+ `.trim(),
+ );
+ });
+
+ it('correctly renders div', () => {
+ expect(
+ serialize(
+ division(paragraph('just a paragraph in a div')),
+ division(paragraph('just some ', bold('styled'), ' ', italic('content'), ' in a div')),
+ ),
+ ).toBe(
+ '<div>just a paragraph in a div</div>\n<div>\n\njust some **styled** _content_ in a div\n\n</div>',
+ );
+ });
+
+ it('correctly renders figure', () => {
+ expect(
+ serialize(
+ figure(
+ paragraph(image({ src: 'elephant.jpg', alt: 'An elephant at sunset' })),
+ figureCaption('An elephant at sunset'),
+ ),
+ ),
+ ).toBe(
+ `
+<figure>
+
+![An elephant at sunset](elephant.jpg)
+
+<figcaption>An elephant at sunset</figcaption>
+</figure>
+ `.trim(),
+ );
+ });
+
+ it('correctly renders figure with styled caption', () => {
+ expect(
+ serialize(
+ figure(
+ paragraph(image({ src: 'elephant.jpg', alt: 'An elephant at sunset' })),
+ figureCaption(italic('An elephant at sunset')),
+ ),
+ ),
+ ).toBe(
+ `
+<figure>
+
+![An elephant at sunset](elephant.jpg)
+
+<figcaption>
+
+_An elephant at sunset_
+
+</figcaption>
+</figure>
+ `.trim(),
+ );
+ });
+
+ it('correctly serializes a table with inline content', () => {
+ expect(
+ serialize(
+ table(
+ // each table cell must contain at least one paragraph
+ tableRow(
+ tableHeader(paragraph('header')),
+ tableHeader(paragraph('header')),
+ tableHeader(paragraph('header')),
+ ),
+ tableRow(
+ tableCell(paragraph('cell')),
+ tableCell(paragraph('cell')),
+ tableCell(paragraph('cell')),
+ ),
+ tableRow(
+ tableCell(paragraph('cell')),
+ tableCell(paragraph('cell')),
+ tableCell(paragraph('cell')),
+ ),
+ ),
+ ).trim(),
+ ).toBe(
+ `
+| header | header | header |
+|--------|--------|--------|
+| cell | cell | cell |
+| cell | cell | cell |
+ `.trim(),
+ );
+ });
+
+ it('correctly serializes a table with line breaks', () => {
+ expect(
+ serialize(
+ table(
+ tableRow(tableHeader(paragraph('header')), tableHeader(paragraph('header'))),
+ tableRow(
+ tableCell(paragraph('cell with', hardBreak(), 'line', hardBreak(), 'breaks')),
+ tableCell(paragraph('cell')),
+ ),
+ tableRow(tableCell(paragraph('cell')), tableCell(paragraph('cell'))),
+ ),
+ ).trim(),
+ ).toBe(
+ `
+| header | header |
+|--------|--------|
+| cell with<br>line<br>breaks | cell |
+| cell | cell |
+ `.trim(),
+ );
+ });
+
+ it('correctly serializes two consecutive tables', () => {
+ expect(
+ serialize(
+ table(
+ tableRow(tableHeader(paragraph('header')), tableHeader(paragraph('header'))),
+ tableRow(tableCell(paragraph('cell')), tableCell(paragraph('cell'))),
+ tableRow(tableCell(paragraph('cell')), tableCell(paragraph('cell'))),
+ ),
+ table(
+ tableRow(tableHeader(paragraph('header')), tableHeader(paragraph('header'))),
+ tableRow(tableCell(paragraph('cell')), tableCell(paragraph('cell'))),
+ tableRow(tableCell(paragraph('cell')), tableCell(paragraph('cell'))),
+ ),
+ ).trim(),
+ ).toBe(
+ `
+| header | header |
+|--------|--------|
+| cell | cell |
+| cell | cell |
+
+| header | header |
+|--------|--------|
+| cell | cell |
+| cell | cell |
+ `.trim(),
+ );
+ });
+
+ it('correctly serializes a table with block content', () => {
+ expect(
+ serialize(
+ table(
+ tableRow(
+ tableHeader(paragraph('examples of')),
+ tableHeader(paragraph('block content')),
+ tableHeader(paragraph('in tables')),
+ tableHeader(paragraph('in content editor')),
+ ),
+ tableRow(
+ tableCell(heading({ level: 1 }, 'heading 1')),
+ tableCell(heading({ level: 2 }, 'heading 2')),
+ tableCell(paragraph(bold('just bold'))),
+ tableCell(paragraph(bold('bold'), ' ', italic('italic'), ' ', code('code'))),
+ ),
+ tableRow(
+ tableCell(
+ paragraph('all marks in three paragraphs:'),
+ paragraph('the ', bold('quick'), ' ', italic('brown'), ' ', code('fox')),
+ paragraph(
+ link({ href: '/home' }, 'jumps'),
+ ' over the ',
+ strike('lazy'),
+ ' ',
+ emoji({ name: 'dog' }),
+ ),
+ ),
+ tableCell(
+ paragraph(image({ src: 'img.jpg', alt: 'some image' }), hardBreak(), 'image content'),
+ ),
+ tableCell(
+ blockquote('some text', hardBreak(), hardBreak(), 'in a multiline blockquote'),
+ ),
+ tableCell(
+ codeBlock(
+ { language: 'javascript' },
+ 'var a = 2;\nvar b = 3;\nvar c = a + d;\n\nconsole.log(c);',
+ ),
+ ),
+ ),
+ tableRow(
+ tableCell(bulletList(listItem('item 1'), listItem('item 2'), listItem('item 2'))),
+ tableCell(orderedList(listItem('item 1'), listItem('item 2'), listItem('item 2'))),
+ tableCell(
+ paragraph('paragraphs separated by'),
+ horizontalRule(),
+ paragraph('a horizontal rule'),
+ ),
+ tableCell(
+ table(
+ tableRow(tableHeader(paragraph('table')), tableHeader(paragraph('inside'))),
+ tableRow(tableCell(paragraph('another')), tableCell(paragraph('table'))),
+ ),
+ ),
+ ),
+ ),
+ ).trim(),
+ ).toBe(
+ `
+<table>
+<tr>
+<th>examples of</th>
+<th>block content</th>
+<th>in tables</th>
+<th>in content editor</th>
+</tr>
+<tr>
+<td>
+
+# heading 1
+</td>
+<td>
+
+## heading 2
+</td>
+<td>
+
+**just bold**
+</td>
+<td>
+
+**bold** _italic_ \`code\`
+</td>
+</tr>
+<tr>
+<td>
+
+all marks in three paragraphs:
+
+the **quick** _brown_ \`fox\`
+
+[jumps](/home) over the ~~lazy~~ :dog:
+</td>
+<td>
+
+![some image](img.jpg)<br>image content
+</td>
+<td>
+
+> some text\\
+> \\
+> in a multiline blockquote
+</td>
+<td>
+
+\`\`\`javascript
+var a = 2;
+var b = 3;
+var c = a + d;
+
+console.log(c);
+\`\`\`
+</td>
+</tr>
+<tr>
+<td>
+
+* item 1
+* item 2
+* item 2
+</td>
+<td>
+
+1. item 1
+2. item 2
+3. item 2
+</td>
+<td>
+
+paragraphs separated by
+
+---
+
+a horizontal rule
+</td>
+<td>
+
+| table | inside |
+|-------|--------|
+| another | table |
+
+</td>
+</tr>
+</table>
+ `.trim(),
+ );
+ });
+
+ it('correctly renders content after a markdown table', () => {
+ expect(
+ serialize(
+ table(tableRow(tableHeader(paragraph('header'))), tableRow(tableCell(paragraph('cell')))),
+ heading({ level: 1 }, 'this is a heading'),
+ ).trim(),
+ ).toBe(
+ `
+| header |
+|--------|
+| cell |
+
+# this is a heading
+ `.trim(),
+ );
+ });
+
+ it('correctly renders content after an html table', () => {
+ expect(
+ serialize(
+ table(
+ tableRow(tableHeader(paragraph('header'))),
+ tableRow(tableCell(blockquote('hi'), paragraph('there'))),
+ ),
+ heading({ level: 1 }, 'this is a heading'),
+ ).trim(),
+ ).toBe(
+ `
+<table>
+<tr>
+<th>header</th>
+</tr>
+<tr>
+<td>
+
+> hi
+
+there
+</td>
+</tr>
+</table>
+
+# this is a heading
+ `.trim(),
+ );
+ });
+
+ it('correctly serializes tables with misplaced header cells', () => {
+ expect(
+ serialize(
+ table(
+ tableRow(tableHeader(paragraph('cell')), tableCell(paragraph('cell'))),
+ tableRow(tableCell(paragraph('cell')), tableHeader(paragraph('cell'))),
+ ),
+ ).trim(),
+ ).toBe(
+ `
+<table>
+<tr>
+<th>cell</th>
+<td>cell</td>
+</tr>
+<tr>
+<td>cell</td>
+<th>cell</th>
+</tr>
+</table>
+ `.trim(),
+ );
+ });
+
+ it('correctly serializes table without any headers', () => {
+ expect(
+ serialize(
+ table(
+ tableRow(tableCell(paragraph('cell')), tableCell(paragraph('cell'))),
+ tableRow(tableCell(paragraph('cell')), tableCell(paragraph('cell'))),
+ ),
+ ).trim(),
+ ).toBe(
+ `
+<table>
+<tr>
+<td>cell</td>
+<td>cell</td>
+</tr>
+<tr>
+<td>cell</td>
+<td>cell</td>
+</tr>
+</table>
+ `.trim(),
+ );
+ });
+
+ it('correctly serializes table with rowspan and colspan', () => {
+ expect(
+ serialize(
+ table(
+ tableRow(
+ tableHeader(paragraph('header')),
+ tableHeader(paragraph('header')),
+ tableHeader(paragraph('header')),
+ ),
+ tableRow(
+ tableCell({ colspan: 2 }, paragraph('cell with rowspan: 2')),
+ tableCell({ rowspan: 2 }, paragraph('cell')),
+ ),
+ tableRow(tableCell({ colspan: 2 }, paragraph('cell with rowspan: 2'))),
+ ),
+ ).trim(),
+ ).toBe(
+ `
+<table>
+<tr>
+<th>header</th>
+<th>header</th>
+<th>header</th>
+</tr>
+<tr>
+<td colspan="2">cell with rowspan: 2</td>
+<td rowspan="2">cell</td>
+</tr>
+<tr>
+<td colspan="2">cell with rowspan: 2</td>
+</tr>
+</table>
+ `.trim(),
+ );
+ });
+});
diff --git a/spec/frontend/content_editor/services/markdown_sourcemap_spec.js b/spec/frontend/content_editor/services/markdown_sourcemap_spec.js
new file mode 100644
index 00000000000..6f908f468f6
--- /dev/null
+++ b/spec/frontend/content_editor/services/markdown_sourcemap_spec.js
@@ -0,0 +1,81 @@
+import { Extension } from '@tiptap/core';
+import BulletList from '~/content_editor/extensions/bullet_list';
+import ListItem from '~/content_editor/extensions/list_item';
+import Paragraph from '~/content_editor/extensions/paragraph';
+import markdownSerializer from '~/content_editor/services/markdown_serializer';
+import { getMarkdownSource } from '~/content_editor/services/markdown_sourcemap';
+import { createTestEditor, createDocBuilder } from '../test_utils';
+
+const BULLET_LIST_MARKDOWN = `+ list item 1
++ list item 2
+ - embedded list item 3`;
+const BULLET_LIST_HTML = `<ul data-sourcepos="1:1-3:24" dir="auto">
+ <li data-sourcepos="1:1-1:13">list item 1</li>
+ <li data-sourcepos="2:1-3:24">list item 2
+ <ul data-sourcepos="3:3-3:24">
+ <li data-sourcepos="3:3-3:24">embedded list item 3</li>
+ </ul>
+ </li>
+</ul>`;
+
+const SourcemapExtension = Extension.create({
+ // lets add `source` attribute to every element using `getMarkdownSource`
+ addGlobalAttributes() {
+ return [
+ {
+ types: [Paragraph.name, BulletList.name, ListItem.name],
+ attributes: {
+ source: {
+ parseHTML: (element) => {
+ const source = getMarkdownSource(element);
+ return source;
+ },
+ },
+ },
+ },
+ ];
+ },
+});
+
+const tiptapEditor = createTestEditor({
+ extensions: [BulletList, ListItem, SourcemapExtension],
+});
+
+const {
+ builders: { doc, bulletList, listItem, paragraph },
+} = createDocBuilder({
+ tiptapEditor,
+ names: {
+ bulletList: { nodeType: BulletList.name },
+ listItem: { nodeType: ListItem.name },
+ },
+});
+
+describe('content_editor/services/markdown_sourcemap', () => {
+ it('gets markdown source for a rendered HTML element', async () => {
+ const deserialized = await markdownSerializer({
+ render: () => BULLET_LIST_HTML,
+ serializerConfig: {},
+ }).deserialize({
+ schema: tiptapEditor.schema,
+ content: BULLET_LIST_MARKDOWN,
+ });
+
+ const expected = doc(
+ bulletList(
+ { bullet: '+', source: '+ list item 1\n+ list item 2' },
+ listItem({ source: '+ list item 1' }, paragraph('list item 1')),
+ listItem(
+ { source: '+ list item 2' },
+ paragraph('list item 2'),
+ bulletList(
+ { bullet: '-', source: '- embedded list item 3' },
+ listItem({ source: '- embedded list item 3' }, paragraph('embedded list item 3')),
+ ),
+ ),
+ ),
+ );
+
+ expect(deserialized).toEqual(expected.toJSON());
+ });
+});
diff --git a/spec/frontend/content_editor/test_utils.js b/spec/frontend/content_editor/test_utils.js
index b5a2abc2389..cf5aa3f2938 100644
--- a/spec/frontend/content_editor/test_utils.js
+++ b/spec/frontend/content_editor/test_utils.js
@@ -98,9 +98,7 @@ export const createTestContentEditorExtension = ({ commands = [] } = {}) => {
return {
labelName: {
default: null,
- parseHTML: (element) => {
- return { labelName: element.dataset.labelName };
- },
+ parseHTML: (element) => element.dataset.labelName,
},
};
},
diff --git a/spec/frontend/cycle_analytics/banner_spec.js b/spec/frontend/cycle_analytics/banner_spec.js
deleted file mode 100644
index ef7998c5ff5..00000000000
--- a/spec/frontend/cycle_analytics/banner_spec.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import Banner from '~/cycle_analytics/components/banner.vue';
-
-describe('Value Stream Analytics banner', () => {
- let wrapper;
-
- const createComponent = () => {
- wrapper = shallowMount(Banner, {
- propsData: {
- documentationLink: 'path',
- },
- });
- };
-
- beforeEach(() => {
- createComponent();
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- it('should render value stream analytics information', () => {
- expect(wrapper.find('h4').text().trim()).toBe('Introducing Value Stream Analytics');
-
- expect(
- wrapper
- .find('p')
- .text()
- .trim()
- .replace(/[\r\n]+/g, ' '),
- ).toContain(
- 'Value Stream Analytics gives an overview of how much time it takes to go from idea to production in your project.',
- );
-
- expect(wrapper.find('a').text().trim()).toBe('Read more');
- expect(wrapper.find('a').attributes('href')).toBe('path');
- });
-
- it('should emit an event when close button is clicked', async () => {
- jest.spyOn(wrapper.vm, '$emit').mockImplementation(() => {});
-
- await wrapper.find('.js-ca-dismiss-button').trigger('click');
-
- expect(wrapper.vm.$emit).toHaveBeenCalled();
- });
-});
diff --git a/spec/frontend/cycle_analytics/base_spec.js b/spec/frontend/cycle_analytics/base_spec.js
index 71830eed3ef..5d3361bfa35 100644
--- a/spec/frontend/cycle_analytics/base_spec.js
+++ b/spec/frontend/cycle_analytics/base_spec.js
@@ -6,6 +6,7 @@ import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import BaseComponent from '~/cycle_analytics/components/base.vue';
import PathNavigation from '~/cycle_analytics/components/path_navigation.vue';
import StageTable from '~/cycle_analytics/components/stage_table.vue';
+import ValueStreamFilters from '~/cycle_analytics/components/value_stream_filters.vue';
import ValueStreamMetrics from '~/cycle_analytics/components/value_stream_metrics.vue';
import { NOT_ENOUGH_DATA_ERROR } from '~/cycle_analytics/constants';
import initState from '~/cycle_analytics/store/state';
@@ -30,13 +31,14 @@ Vue.use(Vuex);
let wrapper;
+const { id: groupId, path: groupPath } = currentGroup;
const defaultState = {
permissions,
currentGroup,
createdBefore,
createdAfter,
stageCounts,
- endpoints: { fullPath },
+ endpoints: { fullPath, groupId, groupPath },
};
function createStore({ initialState = {}, initialGetters = {} }) {
@@ -74,6 +76,7 @@ function createComponent({ initialState, initialGetters } = {}) {
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findPathNavigation = () => wrapper.findComponent(PathNavigation);
+const findFilters = () => wrapper.findComponent(ValueStreamFilters);
const findOverviewMetrics = () => wrapper.findComponent(ValueStreamMetrics);
const findStageTable = () => wrapper.findComponent(StageTable);
const findStageEvents = () => findStageTable().props('stageEvents');
@@ -123,6 +126,29 @@ describe('Value stream analytics component', () => {
expect(findStageEvents()).toEqual(selectedStageEvents);
});
+ it('renders the filters', () => {
+ expect(findFilters().exists()).toBe(true);
+ });
+
+ it('displays the date range selector and hides the project selector', () => {
+ expect(findFilters().props()).toMatchObject({
+ hasProjectFilter: false,
+ hasDateRangeFilter: true,
+ });
+ });
+
+ it('passes the paths to the filter bar', () => {
+ expect(findFilters().props()).toEqual({
+ groupId,
+ groupPath,
+ endDate: createdBefore,
+ hasDateRangeFilter: true,
+ hasProjectFilter: false,
+ selectedProjects: [],
+ startDate: createdAfter,
+ });
+ });
+
it('does not render the loading icon', () => {
expect(findLoadingIcon().exists()).toBe(false);
});
diff --git a/spec/frontend/cycle_analytics/stage_table_spec.js b/spec/frontend/cycle_analytics/stage_table_spec.js
index 47a2ce4444b..3158446c37d 100644
--- a/spec/frontend/cycle_analytics/stage_table_spec.js
+++ b/spec/frontend/cycle_analytics/stage_table_spec.js
@@ -22,6 +22,7 @@ const findStageEvents = () => wrapper.findAllByTestId('vsa-stage-event');
const findPagination = () => wrapper.findByTestId('vsa-stage-pagination');
const findTable = () => wrapper.findComponent(GlTable);
const findTableHead = () => wrapper.find('thead');
+const findTableHeadColumns = () => findTableHead().findAll('th');
const findStageEventTitle = (ev) => extendedWrapper(ev).findByTestId('vsa-stage-event-title');
const findStageTime = () => wrapper.findByTestId('vsa-stage-event-time');
const findIcon = (name) => wrapper.findByTestId(`${name}-icon`);
@@ -244,6 +245,12 @@ describe('StageTable', () => {
wrapper.destroy();
});
+ it('can sort the table by each column', () => {
+ findTableHeadColumns().wrappers.forEach((w) => {
+ expect(w.attributes('aria-sort')).toBe('none');
+ });
+ });
+
it('clicking a table column will send tracking information', () => {
triggerTableSort();
@@ -275,5 +282,17 @@ describe('StageTable', () => {
},
]);
});
+
+ describe('with sortable=false', () => {
+ beforeEach(() => {
+ wrapper = createComponent({ sortable: false });
+ });
+
+ it('cannot sort the table', () => {
+ findTableHeadColumns().wrappers.forEach((w) => {
+ expect(w.attributes('aria-sort')).toBeUndefined();
+ });
+ });
+ });
});
});
diff --git a/spec/frontend/cycle_analytics/store/actions_spec.js b/spec/frontend/cycle_analytics/store/actions_spec.js
index 915a828ff19..97b5bd03e18 100644
--- a/spec/frontend/cycle_analytics/store/actions_spec.js
+++ b/spec/frontend/cycle_analytics/store/actions_spec.js
@@ -4,21 +4,41 @@ import testAction from 'helpers/vuex_action_helper';
import * as actions from '~/cycle_analytics/store/actions';
import * as getters from '~/cycle_analytics/store/getters';
import httpStatusCodes from '~/lib/utils/http_status';
-import { allowedStages, selectedStage, selectedValueStream } from '../mock_data';
-
+import {
+ allowedStages,
+ selectedStage,
+ selectedValueStream,
+ currentGroup,
+ createdAfter,
+ createdBefore,
+} from '../mock_data';
+
+const { id: groupId, path: groupPath } = currentGroup;
+const mockMilestonesPath = 'mock-milestones.json';
+const mockLabelsPath = 'mock-labels.json';
const mockRequestPath = 'some/cool/path';
const mockFullPath = '/namespace/-/analytics/value_stream_analytics/value_streams';
-const mockStartDate = 30;
-const mockEndpoints = { fullPath: mockFullPath, requestPath: mockRequestPath };
-const mockSetDateActionCommit = { payload: { startDate: mockStartDate }, type: 'SET_DATE_RANGE' };
-
-const defaultState = { ...getters, selectedValueStream };
+const mockEndpoints = {
+ fullPath: mockFullPath,
+ requestPath: mockRequestPath,
+ labelsPath: mockLabelsPath,
+ milestonesPath: mockMilestonesPath,
+ groupId,
+ groupPath,
+};
+const mockSetDateActionCommit = {
+ payload: { createdAfter, createdBefore },
+ type: 'SET_DATE_RANGE',
+};
+
+const defaultState = { ...getters, selectedValueStream, createdAfter, createdBefore };
describe('Project Value Stream Analytics actions', () => {
let state;
let mock;
beforeEach(() => {
+ state = { ...defaultState };
mock = new MockAdapter(axios);
});
@@ -34,16 +54,17 @@ describe('Project Value Stream Analytics actions', () => {
{ type: 'fetchCycleAnalyticsData' },
{ type: 'fetchStageData' },
{ type: 'fetchStageMedians' },
+ { type: 'fetchStageCountValues' },
{ type: 'setLoading', payload: false },
];
describe.each`
- action | payload | expectedActions | expectedMutations
- ${'setLoading'} | ${true} | ${[]} | ${[{ type: 'SET_LOADING', payload: true }]}
- ${'setDateRange'} | ${{ startDate: mockStartDate }} | ${mockFetchStageDataActions} | ${[mockSetDateActionCommit]}
- ${'setFilters'} | ${[]} | ${mockFetchStageDataActions} | ${[]}
- ${'setSelectedStage'} | ${{ selectedStage }} | ${[{ type: 'fetchStageData' }]} | ${[{ type: 'SET_SELECTED_STAGE', payload: { selectedStage } }]}
- ${'setSelectedValueStream'} | ${{ selectedValueStream }} | ${[{ type: 'fetchValueStreamStages' }, { type: 'fetchCycleAnalyticsData' }]} | ${[{ type: 'SET_SELECTED_VALUE_STREAM', payload: { selectedValueStream } }]}
+ action | payload | expectedActions | expectedMutations
+ ${'setLoading'} | ${true} | ${[]} | ${[{ type: 'SET_LOADING', payload: true }]}
+ ${'setDateRange'} | ${{ createdAfter, createdBefore }} | ${mockFetchStageDataActions} | ${[mockSetDateActionCommit]}
+ ${'setFilters'} | ${[]} | ${mockFetchStageDataActions} | ${[]}
+ ${'setSelectedStage'} | ${{ selectedStage }} | ${[{ type: 'fetchStageData' }]} | ${[{ type: 'SET_SELECTED_STAGE', payload: { selectedStage } }]}
+ ${'setSelectedValueStream'} | ${{ selectedValueStream }} | ${[{ type: 'fetchValueStreamStages' }, { type: 'fetchCycleAnalyticsData' }]} | ${[{ type: 'SET_SELECTED_VALUE_STREAM', payload: { selectedValueStream } }]}
`('$action', ({ action, payload, expectedActions, expectedMutations }) => {
const types = mutationTypes(expectedMutations);
it(`will dispatch ${expectedActions} and commit ${types}`, () =>
@@ -60,6 +81,12 @@ describe('Project Value Stream Analytics actions', () => {
let mockDispatch;
let mockCommit;
const payload = { endpoints: mockEndpoints };
+ const mockFilterEndpoints = {
+ groupEndpoint: 'foo',
+ labelsEndpoint: mockLabelsPath,
+ milestonesEndpoint: mockMilestonesPath,
+ projectEndpoint: '/namespace/-/analytics/value_stream_analytics/value_streams',
+ };
beforeEach(() => {
mockDispatch = jest.fn(() => Promise.resolve());
@@ -76,6 +103,9 @@ describe('Project Value Stream Analytics actions', () => {
payload,
);
expect(mockCommit).toHaveBeenCalledWith('INITIALIZE_VSA', { endpoints: mockEndpoints });
+
+ expect(mockDispatch).toHaveBeenCalledTimes(4);
+ expect(mockDispatch).toHaveBeenCalledWith('filters/setEndpoints', mockFilterEndpoints);
expect(mockDispatch).toHaveBeenCalledWith('setLoading', true);
expect(mockDispatch).toHaveBeenCalledWith('fetchValueStreams');
expect(mockDispatch).toHaveBeenCalledWith('setLoading', false);
@@ -84,7 +114,7 @@ describe('Project Value Stream Analytics actions', () => {
describe('fetchCycleAnalyticsData', () => {
beforeEach(() => {
- state = { endpoints: mockEndpoints };
+ state = { ...defaultState, endpoints: mockEndpoints };
mock = new MockAdapter(axios);
mock.onGet(mockRequestPath).reply(httpStatusCodes.OK);
});
@@ -129,7 +159,6 @@ describe('Project Value Stream Analytics actions', () => {
state = {
...defaultState,
endpoints: mockEndpoints,
- startDate: mockStartDate,
selectedStage,
};
mock = new MockAdapter(axios);
@@ -152,7 +181,6 @@ describe('Project Value Stream Analytics actions', () => {
state = {
...defaultState,
endpoints: mockEndpoints,
- startDate: mockStartDate,
selectedStage,
};
mock = new MockAdapter(axios);
@@ -177,7 +205,6 @@ describe('Project Value Stream Analytics actions', () => {
state = {
...defaultState,
endpoints: mockEndpoints,
- startDate: mockStartDate,
selectedStage,
};
mock = new MockAdapter(axios);
diff --git a/spec/frontend/cycle_analytics/store/mutations_spec.js b/spec/frontend/cycle_analytics/store/mutations_spec.js
index 7fcfef98547..628e2a4e7ae 100644
--- a/spec/frontend/cycle_analytics/store/mutations_spec.js
+++ b/spec/frontend/cycle_analytics/store/mutations_spec.js
@@ -1,5 +1,4 @@
import { useFakeDate } from 'helpers/fake_date';
-import { DEFAULT_DAYS_TO_DISPLAY } from '~/cycle_analytics/constants';
import * as types from '~/cycle_analytics/store/mutation_types';
import mutations from '~/cycle_analytics/store/mutations';
import {
@@ -65,15 +64,16 @@ describe('Project Value Stream Analytics mutations', () => {
expect(state).toMatchObject({ [stateKey]: value });
});
+ const mockSetDatePayload = { createdAfter: mockCreatedAfter, createdBefore: mockCreatedBefore };
const mockInitialPayload = {
endpoints: { requestPath: mockRequestPath },
currentGroup: { title: 'cool-group' },
id: 1337,
+ ...mockSetDatePayload,
};
const mockInitializedObj = {
endpoints: { requestPath: mockRequestPath },
- createdAfter: mockCreatedAfter,
- createdBefore: mockCreatedBefore,
+ ...mockSetDatePayload,
};
it.each`
@@ -89,9 +89,8 @@ describe('Project Value Stream Analytics mutations', () => {
it.each`
mutation | payload | stateKey | value
- ${types.SET_DATE_RANGE} | ${DEFAULT_DAYS_TO_DISPLAY} | ${'daysInPast'} | ${DEFAULT_DAYS_TO_DISPLAY}
- ${types.SET_DATE_RANGE} | ${DEFAULT_DAYS_TO_DISPLAY} | ${'createdAfter'} | ${mockCreatedAfter}
- ${types.SET_DATE_RANGE} | ${DEFAULT_DAYS_TO_DISPLAY} | ${'createdBefore'} | ${mockCreatedBefore}
+ ${types.SET_DATE_RANGE} | ${mockSetDatePayload} | ${'createdAfter'} | ${mockCreatedAfter}
+ ${types.SET_DATE_RANGE} | ${mockSetDatePayload} | ${'createdBefore'} | ${mockCreatedBefore}
${types.SET_LOADING} | ${true} | ${'isLoading'} | ${true}
${types.SET_LOADING} | ${false} | ${'isLoading'} | ${false}
${types.SET_SELECTED_VALUE_STREAM} | ${selectedValueStream} | ${'selectedValueStream'} | ${selectedValueStream}
diff --git a/spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js b/spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js
index 168ddcfeacc..403d0dce3fc 100644
--- a/spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js
+++ b/spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js
@@ -1,3 +1,4 @@
+import { GlModal } from '@gitlab/ui';
import { createLocalVue, mount } from '@vue/test-utils';
import Vuex from 'vuex';
import DeployFreezeTable from '~/deploy_freeze/components/deploy_freeze_table.vue';
@@ -29,6 +30,8 @@ describe('Deploy freeze table', () => {
const findAddDeployFreezeButton = () => wrapper.find('[data-testid="add-deploy-freeze"]');
const findEditDeployFreezeButton = () => wrapper.find('[data-testid="edit-deploy-freeze"]');
const findDeployFreezeTable = () => wrapper.find('[data-testid="deploy-freeze-table"]');
+ const findDeleteDeployFreezeButton = () => wrapper.find('[data-testid="delete-deploy-freeze"]');
+ const findDeleteDeployFreezeModal = () => wrapper.findComponent(GlModal);
beforeEach(() => {
createComponent();
@@ -73,6 +76,29 @@ describe('Deploy freeze table', () => {
store.state.freezePeriods[0],
);
});
+
+ it('displays delete deploy freeze button', () => {
+ expect(findDeleteDeployFreezeButton().exists()).toBe(true);
+ });
+
+ it('confirms a user wants to delete a deploy freeze', async () => {
+ const [{ freezeStart, freezeEnd, cronTimezone }] = store.state.freezePeriods;
+ await findDeleteDeployFreezeButton().trigger('click');
+ const modal = findDeleteDeployFreezeModal();
+ expect(modal.text()).toContain(
+ `Deploy freeze from ${freezeStart} to ${freezeEnd} in ${cronTimezone.formattedTimezone} will be removed.`,
+ );
+ });
+
+ it('deletes the freeze period on confirmation', async () => {
+ await findDeleteDeployFreezeButton().trigger('click');
+ const modal = findDeleteDeployFreezeModal();
+ modal.vm.$emit('primary');
+ expect(store.dispatch).toHaveBeenCalledWith(
+ 'deleteFreezePeriod',
+ store.state.freezePeriods[0],
+ );
+ });
});
});
diff --git a/spec/frontend/deploy_freeze/helpers.js b/spec/frontend/deploy_freeze/helpers.js
index bfb84142662..598f14d45f6 100644
--- a/spec/frontend/deploy_freeze/helpers.js
+++ b/spec/frontend/deploy_freeze/helpers.js
@@ -1,7 +1,7 @@
import { secondsToHours } from '~/lib/utils/datetime_utility';
export const freezePeriodsFixture = getJSONFixture('/api/freeze-periods/freeze_periods.json');
-export const timezoneDataFixture = getJSONFixture('/api/freeze-periods/timezone_data.json');
+export const timezoneDataFixture = getJSONFixture('/timezones/short.json');
export const findTzByName = (identifier = '') =>
timezoneDataFixture.find(({ name }) => name.toLowerCase() === identifier.toLowerCase());
diff --git a/spec/frontend/deploy_freeze/store/actions_spec.js b/spec/frontend/deploy_freeze/store/actions_spec.js
index 6bc9c4d374c..ad67afdce75 100644
--- a/spec/frontend/deploy_freeze/store/actions_spec.js
+++ b/spec/frontend/deploy_freeze/store/actions_spec.js
@@ -5,6 +5,7 @@ import * as actions from '~/deploy_freeze/store/actions';
import * as types from '~/deploy_freeze/store/mutation_types';
import getInitialState from '~/deploy_freeze/store/state';
import createFlash from '~/flash';
+import * as logger from '~/lib/logger';
import axios from '~/lib/utils/axios_utils';
import { freezePeriodsFixture, timezoneDataFixture } from '../helpers';
@@ -12,6 +13,7 @@ jest.mock('~/api.js');
jest.mock('~/flash.js');
describe('deploy freeze store actions', () => {
+ const freezePeriodFixture = freezePeriodsFixture[0];
let mock;
let state;
@@ -24,6 +26,7 @@ describe('deploy freeze store actions', () => {
Api.freezePeriods.mockResolvedValue({ data: freezePeriodsFixture });
Api.createFreezePeriod.mockResolvedValue();
Api.updateFreezePeriod.mockResolvedValue();
+ Api.deleteFreezePeriod.mockResolvedValue();
});
afterEach(() => {
@@ -195,4 +198,46 @@ describe('deploy freeze store actions', () => {
);
});
});
+
+ describe('deleteFreezePeriod', () => {
+ it('dispatch correct actions on deleting a freeze period', () => {
+ testAction(
+ actions.deleteFreezePeriod,
+ freezePeriodFixture,
+ state,
+ [
+ { type: 'REQUEST_DELETE_FREEZE_PERIOD', payload: freezePeriodFixture.id },
+ { type: 'RECEIVE_DELETE_FREEZE_PERIOD_SUCCESS', payload: freezePeriodFixture.id },
+ ],
+ [],
+ () =>
+ expect(Api.deleteFreezePeriod).toHaveBeenCalledWith(
+ state.projectId,
+ freezePeriodFixture.id,
+ ),
+ );
+ });
+
+ it('should show flash error and set error in state on delete failure', () => {
+ jest.spyOn(logger, 'logError').mockImplementation();
+ const error = new Error();
+ Api.deleteFreezePeriod.mockRejectedValue(error);
+
+ testAction(
+ actions.deleteFreezePeriod,
+ freezePeriodFixture,
+ state,
+ [
+ { type: 'REQUEST_DELETE_FREEZE_PERIOD', payload: freezePeriodFixture.id },
+ { type: 'RECEIVE_DELETE_FREEZE_PERIOD_ERROR', payload: freezePeriodFixture.id },
+ ],
+ [],
+ () => {
+ expect(createFlash).toHaveBeenCalled();
+
+ expect(logger.logError).toHaveBeenCalledWith('Unable to delete deploy freeze', error);
+ },
+ );
+ });
+ });
});
diff --git a/spec/frontend/deploy_freeze/store/mutations_spec.js b/spec/frontend/deploy_freeze/store/mutations_spec.js
index f8683489340..878a755088c 100644
--- a/spec/frontend/deploy_freeze/store/mutations_spec.js
+++ b/spec/frontend/deploy_freeze/store/mutations_spec.js
@@ -28,9 +28,9 @@ describe('Deploy freeze mutations', () => {
describe('RECEIVE_FREEZE_PERIODS_SUCCESS', () => {
it('should set freeze periods and format timezones from identifiers to names', () => {
const timezoneNames = {
- 'Europe/Berlin': 'Berlin',
- 'Etc/UTC': 'UTC',
- 'America/New_York': 'Eastern Time (US & Canada)',
+ 'Europe/Berlin': '[UTC 2] Berlin',
+ 'Etc/UTC': '[UTC 0] UTC',
+ 'America/New_York': '[UTC -4] Eastern Time (US & Canada)',
};
mutations[types.RECEIVE_FREEZE_PERIODS_SUCCESS](stateCopy, freezePeriodsFixture);
diff --git a/spec/frontend/deprecated_jquery_dropdown_spec.js b/spec/frontend/deprecated_jquery_dropdown_spec.js
index 7858f88f8c3..4a6dee31cd5 100644
--- a/spec/frontend/deprecated_jquery_dropdown_spec.js
+++ b/spec/frontend/deprecated_jquery_dropdown_spec.js
@@ -323,7 +323,7 @@ describe('deprecatedJQueryDropdown', () => {
const li = dropdown.renderItem(item, null, 3);
const link = li.querySelector('a');
- expect(link).toHaveAttr('data-track-event', 'click_text');
+ expect(link).toHaveAttr('data-track-action', 'click_text');
expect(link).toHaveAttr('data-track-label', 'some_value_for_label');
expect(link).toHaveAttr('data-track-value', '3');
expect(link).toHaveAttr('data-track-property', 'suggestion-category');
diff --git a/spec/frontend/design_management/components/design_notes/__snapshots__/design_reply_form_spec.js.snap b/spec/frontend/design_management/components/design_notes/__snapshots__/design_reply_form_spec.js.snap
index d9f5ba0bade..4dc8eaea174 100644
--- a/spec/frontend/design_management/components/design_notes/__snapshots__/design_reply_form_spec.js.snap
+++ b/spec/frontend/design_management/components/design_notes/__snapshots__/design_reply_form_spec.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Design reply form component renders button text as "Comment" when creating a comment 1`] = `
-"<button data-track-event=\\"click_button\\" data-qa-selector=\\"save_comment_button\\" type=\\"submit\\" disabled=\\"disabled\\" class=\\"btn gl-mr-3 gl-w-auto! btn-confirm btn-md disabled gl-button\\">
+"<button data-track-action=\\"click_button\\" data-qa-selector=\\"save_comment_button\\" type=\\"submit\\" disabled=\\"disabled\\" class=\\"btn gl-mr-3 gl-w-auto! btn-confirm btn-md disabled gl-button\\">
<!---->
<!----> <span class=\\"gl-button-text\\">
Comment
@@ -9,7 +9,7 @@ exports[`Design reply form component renders button text as "Comment" when creat
`;
exports[`Design reply form component renders button text as "Save comment" when creating a comment 1`] = `
-"<button data-track-event=\\"click_button\\" data-qa-selector=\\"save_comment_button\\" type=\\"submit\\" disabled=\\"disabled\\" class=\\"btn gl-mr-3 gl-w-auto! btn-confirm btn-md disabled gl-button\\">
+"<button data-track-action=\\"click_button\\" data-qa-selector=\\"save_comment_button\\" type=\\"submit\\" disabled=\\"disabled\\" class=\\"btn gl-mr-3 gl-w-auto! btn-confirm btn-md disabled gl-button\\">
<!---->
<!----> <span class=\\"gl-button-text\\">
Save comment
diff --git a/spec/frontend/design_management/components/design_scaler_spec.js b/spec/frontend/design_management/components/design_scaler_spec.js
index 8a123b2d1e5..095c070e5e8 100644
--- a/spec/frontend/design_management/components/design_scaler_spec.js
+++ b/spec/frontend/design_management/components/design_scaler_spec.js
@@ -13,7 +13,11 @@ describe('Design management design scaler component', () => {
const setScale = (scale) => wrapper.vm.setScale(scale);
const createComponent = () => {
- wrapper = shallowMount(DesignScaler);
+ wrapper = shallowMount(DesignScaler, {
+ propsData: {
+ maxScale: 2,
+ },
+ });
};
beforeEach(() => {
@@ -61,6 +65,18 @@ describe('Design management design scaler component', () => {
expect(wrapper.emitted('scale')).toEqual([[1.2]]);
});
+ it('computes & increments correct stepSize based on maxScale', async () => {
+ wrapper.setProps({ maxScale: 11 });
+
+ await wrapper.vm.$nextTick();
+
+ getIncreaseScaleButton().vm.$emit('click');
+
+ await wrapper.vm.$nextTick();
+
+ expect(wrapper.emitted().scale[0][0]).toBe(3);
+ });
+
describe('when `scale` value is 1', () => {
it('disables the "reset" button', () => {
const resetButton = getResetScaleButton();
@@ -77,7 +93,7 @@ describe('Design management design scaler component', () => {
});
});
- describe('when `scale` value is 2 (maximum)', () => {
+ describe('when `scale` value is maximum', () => {
beforeEach(async () => {
setScale(2);
await wrapper.vm.$nextTick();
diff --git a/spec/frontend/design_management/components/upload/__snapshots__/design_version_dropdown_spec.js.snap b/spec/frontend/design_management/components/upload/__snapshots__/design_version_dropdown_spec.js.snap
index 637f22457c4..67e4a82787c 100644
--- a/spec/frontend/design_management/components/upload/__snapshots__/design_version_dropdown_spec.js.snap
+++ b/spec/frontend/design_management/components/upload/__snapshots__/design_version_dropdown_spec.js.snap
@@ -3,10 +3,14 @@
exports[`Design management design version dropdown component renders design version dropdown button 1`] = `
<gl-dropdown-stub
category="primary"
+ clearalltext="Clear all"
headertext=""
hideheaderborder="true"
+ highlighteditemstitle="Selected"
+ highlighteditemstitleclass="gl-px-5"
issueiid=""
projectpath=""
+ showhighlighteditemstitle="true"
size="small"
text="Showing latest version"
variant="default"
@@ -80,10 +84,14 @@ exports[`Design management design version dropdown component renders design vers
exports[`Design management design version dropdown component renders design version list 1`] = `
<gl-dropdown-stub
category="primary"
+ clearalltext="Clear all"
headertext=""
hideheaderborder="true"
+ highlighteditemstitle="Selected"
+ highlighteditemstitleclass="gl-px-5"
issueiid=""
projectpath=""
+ showhighlighteditemstitle="true"
size="small"
text="Showing latest version"
variant="default"
diff --git a/spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap b/spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap
index 57023c55878..3d04840b1f8 100644
--- a/spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap
+++ b/spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap
@@ -25,7 +25,9 @@ exports[`Design management design index page renders design index 1`] = `
<div
class="design-scaler-wrapper gl-absolute gl-mb-6 gl-display-flex gl-justify-content-center gl-align-items-center"
>
- <design-scaler-stub />
+ <design-scaler-stub
+ maxscale="2"
+ />
</div>
</div>
@@ -186,7 +188,9 @@ exports[`Design management design index page with error GlAlert is rendered in c
<div
class="design-scaler-wrapper gl-absolute gl-mb-6 gl-display-flex gl-justify-content-center gl-align-items-center"
>
- <design-scaler-stub />
+ <design-scaler-stub
+ maxscale="2"
+ />
</div>
</div>
diff --git a/spec/frontend/design_management/pages/design/index_spec.js b/spec/frontend/design_management/pages/design/index_spec.js
index 1332e872246..6ce384b4869 100644
--- a/spec/frontend/design_management/pages/design/index_spec.js
+++ b/spec/frontend/design_management/pages/design/index_spec.js
@@ -390,28 +390,13 @@ describe('Design management design index page', () => {
);
});
- describe('with usage_data_design_action enabled', () => {
- it('tracks design view service ping', () => {
- createComponent(
- { loading: true },
- {
- provide: {
- glFeatures: { usageDataDesignAction: true },
- },
- },
- );
- expect(Api.trackRedisHllUserEvent).toHaveBeenCalledTimes(1);
- expect(Api.trackRedisHllUserEvent).toHaveBeenCalledWith(
- DESIGN_SERVICE_PING_EVENT_TYPES.DESIGN_ACTION,
- );
- });
- });
+ it('tracks design view service ping', () => {
+ createComponent({ loading: true });
- describe('with usage_data_design_action disabled', () => {
- it("doesn't track design view service ping", () => {
- createComponent({ loading: true });
- expect(Api.trackRedisHllUserEvent).toHaveBeenCalledTimes(0);
- });
+ expect(Api.trackRedisHllUserEvent).toHaveBeenCalledTimes(1);
+ expect(Api.trackRedisHllUserEvent).toHaveBeenCalledWith(
+ DESIGN_SERVICE_PING_EVENT_TYPES.DESIGN_ACTION,
+ );
});
});
});
diff --git a/spec/frontend/design_management/pages/index_spec.js b/spec/frontend/design_management/pages/index_spec.js
index 95cb1ac943c..ce79feae2e7 100644
--- a/spec/frontend/design_management/pages/index_spec.js
+++ b/spec/frontend/design_management/pages/index_spec.js
@@ -338,6 +338,13 @@ describe('Design management index page', () => {
__typename: 'DesignVersion',
id: expect.anything(),
sha: expect.anything(),
+ createdAt: '',
+ author: {
+ __typename: 'UserCore',
+ id: expect.anything(),
+ name: '',
+ avatarUrl: '',
+ },
},
},
},
@@ -623,6 +630,16 @@ describe('Design management index page', () => {
expect(mockMutate).not.toHaveBeenCalled();
});
+ it('does not upload designs if designs wrapper is destroyed', () => {
+ findDesignsWrapper().trigger('mouseenter');
+
+ wrapper.destroy();
+
+ document.dispatchEvent(event);
+
+ expect(mockMutate).not.toHaveBeenCalled();
+ });
+
describe('when designs wrapper is hovered', () => {
let realDateNow;
const today = () => new Date('2020-12-25');
diff --git a/spec/frontend/design_management/utils/design_management_utils_spec.js b/spec/frontend/design_management/utils/design_management_utils_spec.js
index 5b7f99e9d96..dc6056badb9 100644
--- a/spec/frontend/design_management/utils/design_management_utils_spec.js
+++ b/spec/frontend/design_management/utils/design_management_utils_spec.js
@@ -101,7 +101,13 @@ describe('optimistic responses', () => {
discussions: { __typename: 'DesignDiscussion', nodes: [] },
versions: {
__typename: 'DesignVersionConnection',
- nodes: { __typename: 'DesignVersion', id: -1, sha: -1 },
+ nodes: {
+ __typename: 'DesignVersion',
+ id: expect.anything(),
+ sha: expect.anything(),
+ createdAt: '',
+ author: { __typename: 'UserCore', avatarUrl: '', name: '', id: expect.anything() },
+ },
},
},
],
diff --git a/spec/frontend/diffs/components/app_spec.js b/spec/frontend/diffs/components/app_spec.js
index 1464dd84666..9dc82bbdc93 100644
--- a/spec/frontend/diffs/components/app_spec.js
+++ b/spec/frontend/diffs/components/app_spec.js
@@ -183,7 +183,7 @@ describe('diffs/components/app', () => {
it('displays loading icon on batch loading', () => {
createComponent({}, ({ state }) => {
- state.diffs.isBatchLoading = true;
+ state.diffs.batchLoadingState = 'loading';
});
expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
@@ -705,24 +705,4 @@ describe('diffs/components/app', () => {
);
});
});
-
- describe('diff file tree is aware of review bar', () => {
- it('it does not have review-bar-visible class when review bar is not visible', () => {
- createComponent({}, ({ state }) => {
- state.diffs.diffFiles = [{ file_hash: '111', file_path: '111.js' }];
- });
-
- expect(wrapper.find('.js-diff-tree-list').exists()).toBe(true);
- expect(wrapper.find('.js-diff-tree-list.review-bar-visible').exists()).toBe(false);
- });
-
- it('it does have review-bar-visible class when review bar is visible', () => {
- createComponent({}, ({ state }) => {
- state.diffs.diffFiles = [{ file_hash: '111', file_path: '111.js' }];
- state.batchComments.drafts = ['draft message'];
- });
-
- expect(wrapper.find('.js-diff-tree-list.review-bar-visible').exists()).toBe(true);
- });
- });
});
diff --git a/spec/frontend/diffs/components/diff_file_spec.js b/spec/frontend/diffs/components/diff_file_spec.js
index 3dec56f2fe3..feb7118744b 100644
--- a/spec/frontend/diffs/components/diff_file_spec.js
+++ b/spec/frontend/diffs/components/diff_file_spec.js
@@ -242,32 +242,20 @@ describe('DiffFile', () => {
});
it.each`
- loggedIn | featureOn | bool
- ${true} | ${true} | ${true}
- ${false} | ${true} | ${false}
- ${true} | ${false} | ${false}
- ${false} | ${false} | ${false}
- `(
- 'should be $bool when { userIsLoggedIn: $loggedIn, featureEnabled: $featureOn }',
- ({ loggedIn, featureOn, bool }) => {
- setLoggedIn(loggedIn);
-
- ({ wrapper } = createComponent({
- options: {
- provide: {
- glFeatures: {
- localFileReviews: featureOn,
- },
- },
- },
- props: {
- file: store.state.diffs.diffFiles[0],
- },
- }));
+ loggedIn | bool
+ ${true} | ${true}
+ ${false} | ${false}
+ `('should be $bool when { userIsLoggedIn: $loggedIn }', ({ loggedIn, bool }) => {
+ setLoggedIn(loggedIn);
+
+ ({ wrapper } = createComponent({
+ props: {
+ file: store.state.diffs.diffFiles[0],
+ },
+ }));
- expect(wrapper.vm.showLocalFileReviews).toBe(bool);
- },
- );
+ expect(wrapper.vm.showLocalFileReviews).toBe(bool);
+ });
});
});
diff --git a/spec/frontend/diffs/create_diffs_store.js b/spec/frontend/diffs/create_diffs_store.js
index e6a8b7a72ae..307ebdaa4ac 100644
--- a/spec/frontend/diffs/create_diffs_store.js
+++ b/spec/frontend/diffs/create_diffs_store.js
@@ -9,6 +9,12 @@ Vue.use(Vuex);
export default function createDiffsStore() {
return new Vuex.Store({
modules: {
+ page: {
+ namespaced: true,
+ state: {
+ activeTab: 'notes',
+ },
+ },
diffs: diffsModule(),
notes: notesModule(),
batchComments: batchCommentsModule(),
diff --git a/spec/frontend/diffs/store/actions_spec.js b/spec/frontend/diffs/store/actions_spec.js
index 6d005b868a9..b35abc9da02 100644
--- a/spec/frontend/diffs/store/actions_spec.js
+++ b/spec/frontend/diffs/store/actions_spec.js
@@ -186,15 +186,16 @@ describe('DiffsStoreActions', () => {
{},
{ endpointBatch, diffViewType: 'inline' },
[
- { type: types.SET_BATCH_LOADING, payload: true },
+ { type: types.SET_BATCH_LOADING_STATE, payload: 'loading' },
{ type: types.SET_RETRIEVING_BATCHES, payload: true },
{ type: types.SET_DIFF_DATA_BATCH, payload: { diff_files: res1.diff_files } },
- { type: types.SET_BATCH_LOADING, payload: false },
+ { type: types.SET_BATCH_LOADING_STATE, payload: 'loaded' },
{ type: types.VIEW_DIFF_FILE, payload: 'test' },
{ type: types.SET_DIFF_DATA_BATCH, payload: { diff_files: res2.diff_files } },
- { type: types.SET_BATCH_LOADING, payload: false },
+ { type: types.SET_BATCH_LOADING_STATE, payload: 'loaded' },
{ type: types.VIEW_DIFF_FILE, payload: 'test2' },
{ type: types.SET_RETRIEVING_BATCHES, payload: false },
+ { type: types.SET_BATCH_LOADING_STATE, payload: 'error' },
],
[{ type: 'startRenderDiffsQueue' }, { type: 'startRenderDiffsQueue' }],
done,
diff --git a/spec/frontend/diffs/store/mutations_spec.js b/spec/frontend/diffs/store/mutations_spec.js
index b549ca42634..fc9ba223d5a 100644
--- a/spec/frontend/diffs/store/mutations_spec.js
+++ b/spec/frontend/diffs/store/mutations_spec.js
@@ -31,13 +31,13 @@ describe('DiffsStoreMutations', () => {
});
});
- describe('SET_BATCH_LOADING', () => {
+ describe('SET_BATCH_LOADING_STATE', () => {
it('should set loading state', () => {
const state = {};
- mutations[types.SET_BATCH_LOADING](state, false);
+ mutations[types.SET_BATCH_LOADING_STATE](state, false);
- expect(state.isBatchLoading).toEqual(false);
+ expect(state.batchLoadingState).toEqual(false);
});
});
diff --git a/spec/frontend/diffs/utils/preferences_spec.js b/spec/frontend/diffs/utils/preferences_spec.js
deleted file mode 100644
index 2dcc71dc188..00000000000
--- a/spec/frontend/diffs/utils/preferences_spec.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import Cookies from 'js-cookie';
-import {
- DIFF_FILE_BY_FILE_COOKIE_NAME,
- DIFF_VIEW_FILE_BY_FILE,
- DIFF_VIEW_ALL_FILES,
-} from '~/diffs/constants';
-import { fileByFile } from '~/diffs/utils/preferences';
-
-describe('diffs preferences', () => {
- describe('fileByFile', () => {
- afterEach(() => {
- Cookies.remove(DIFF_FILE_BY_FILE_COOKIE_NAME);
- });
-
- it.each`
- result | preference | cookie
- ${true} | ${false} | ${DIFF_VIEW_FILE_BY_FILE}
- ${false} | ${true} | ${DIFF_VIEW_ALL_FILES}
- ${true} | ${false} | ${DIFF_VIEW_FILE_BY_FILE}
- ${false} | ${true} | ${DIFF_VIEW_ALL_FILES}
- ${false} | ${false} | ${DIFF_VIEW_ALL_FILES}
- ${true} | ${true} | ${DIFF_VIEW_FILE_BY_FILE}
- `(
- 'should return $result when { preference: $preference, cookie: $cookie }',
- ({ result, preference, cookie }) => {
- Cookies.set(DIFF_FILE_BY_FILE_COOKIE_NAME, cookie);
-
- expect(fileByFile(preference)).toBe(result);
- },
- );
- });
-});
diff --git a/spec/frontend/dropzone_input_spec.js b/spec/frontend/dropzone_input_spec.js
index 5e6ccbd7cda..acf7d0780cd 100644
--- a/spec/frontend/dropzone_input_spec.js
+++ b/spec/frontend/dropzone_input_spec.js
@@ -1,9 +1,12 @@
+import MockAdapter from 'axios-mock-adapter';
import $ from 'jquery';
import mock from 'xhr-mock';
import waitForPromises from 'helpers/wait_for_promises';
import { TEST_HOST } from 'spec/test_constants';
import PasteMarkdownTable from '~/behaviors/markdown/paste_markdown_table';
import dropzoneInput from '~/dropzone_input';
+import axios from '~/lib/utils/axios_utils';
+import httpStatusCodes from '~/lib/utils/http_status';
const TEST_FILE = new File([], 'somefile.jpg');
TEST_FILE.upload = {};
@@ -29,6 +32,16 @@ describe('dropzone_input', () => {
});
describe('handlePaste', () => {
+ const triggerPasteEvent = (clipboardData = {}) => {
+ const event = $.Event('paste');
+ const origEvent = new Event('paste');
+
+ origEvent.clipboardData = clipboardData;
+ event.originalEvent = origEvent;
+
+ $('.js-gfm-input').trigger(event);
+ };
+
beforeEach(() => {
loadFixtures('issues/new-issue.html');
@@ -38,24 +51,39 @@ describe('dropzone_input', () => {
});
it('pastes Markdown tables', () => {
- const event = $.Event('paste');
- const origEvent = new Event('paste');
+ jest.spyOn(PasteMarkdownTable.prototype, 'isTable');
+ jest.spyOn(PasteMarkdownTable.prototype, 'convertToTableMarkdown');
- origEvent.clipboardData = {
+ triggerPasteEvent({
types: ['text/plain', 'text/html'],
getData: () => '<table><tr><td>Hello World</td></tr></table>',
items: [],
- };
- event.originalEvent = origEvent;
-
- jest.spyOn(PasteMarkdownTable.prototype, 'isTable');
- jest.spyOn(PasteMarkdownTable.prototype, 'convertToTableMarkdown');
-
- $('.js-gfm-input').trigger(event);
+ });
expect(PasteMarkdownTable.prototype.isTable).toHaveBeenCalled();
expect(PasteMarkdownTable.prototype.convertToTableMarkdown).toHaveBeenCalled();
});
+
+ it('passes truncated long filename to post request', async () => {
+ const axiosMock = new MockAdapter(axios);
+ const longFileName = 'a'.repeat(300);
+
+ triggerPasteEvent({
+ types: ['text/plain', 'text/html', 'text/rtf', 'Files'],
+ getData: () => longFileName,
+ items: [
+ {
+ kind: 'file',
+ type: 'image/png',
+ getAsFile: () => new Blob(),
+ },
+ ],
+ });
+
+ axiosMock.onPost().reply(httpStatusCodes.OK, { link: { markdown: 'foo' } });
+ await waitForPromises();
+ expect(axiosMock.history.post[0].data.get('file').name).toHaveLength(246);
+ });
});
describe('shows error message', () => {
diff --git a/spec/frontend/emoji/index_spec.js b/spec/frontend/emoji/index_spec.js
index 1e6f5483160..9652c513671 100644
--- a/spec/frontend/emoji/index_spec.js
+++ b/spec/frontend/emoji/index_spec.js
@@ -9,6 +9,7 @@ import isEmojiUnicodeSupported, {
isHorceRacingSkinToneComboEmoji,
isPersonZwjEmoji,
} from '~/emoji/support/is_emoji_unicode_supported';
+import { sanitize } from '~/lib/dompurify';
const emptySupportMap = {
personZwj: false,
@@ -379,7 +380,7 @@ describe('emoji', () => {
describe('searchEmoji', () => {
const emojiFixture = Object.keys(mockEmojiData).reduce((acc, k) => {
const { name, e, u, d } = mockEmojiData[k];
- acc[k] = { name, e, u, d };
+ acc[k] = { name, e: sanitize(e), u, d };
return acc;
}, {});
@@ -397,6 +398,7 @@ describe('emoji', () => {
'heart',
'custard',
'star',
+ 'xss',
].map((name) => {
return {
emoji: emojiFixture[name],
@@ -620,4 +622,13 @@ describe('emoji', () => {
expect(sortEmoji(scoredItems)).toEqual(expected);
});
});
+
+ describe('sanitize emojis', () => {
+ it('should return sanitized emoji', () => {
+ expect(getEmojiInfo('xss')).toEqual({
+ ...mockEmojiData.xss,
+ e: '<img src="x">',
+ });
+ });
+ });
});
diff --git a/spec/frontend/emoji/support/unicode_support_map_spec.js b/spec/frontend/emoji/support/unicode_support_map_spec.js
index 945e804a9fa..37f74db30b5 100644
--- a/spec/frontend/emoji/support/unicode_support_map_spec.js
+++ b/spec/frontend/emoji/support/unicode_support_map_spec.js
@@ -8,14 +8,14 @@ describe('Unicode Support Map', () => {
const stringSupportMap = 'stringSupportMap';
beforeEach(() => {
- jest.spyOn(AccessorUtilities, 'isLocalStorageAccessSafe').mockImplementation(() => {});
+ jest.spyOn(AccessorUtilities, 'canUseLocalStorage').mockImplementation(() => {});
jest.spyOn(JSON, 'parse').mockImplementation(() => {});
jest.spyOn(JSON, 'stringify').mockReturnValue(stringSupportMap);
});
describe('if isLocalStorageAvailable is `true`', () => {
beforeEach(() => {
- jest.spyOn(AccessorUtilities, 'isLocalStorageAccessSafe').mockReturnValue(true);
+ jest.spyOn(AccessorUtilities, 'canUseLocalStorage').mockReturnValue(true);
getUnicodeSupportMap();
});
@@ -38,7 +38,7 @@ describe('Unicode Support Map', () => {
describe('if isLocalStorageAvailable is `false`', () => {
beforeEach(() => {
- jest.spyOn(AccessorUtilities, 'isLocalStorageAccessSafe').mockReturnValue(false);
+ jest.spyOn(AccessorUtilities, 'canUseLocalStorage').mockReturnValue(false);
getUnicodeSupportMap();
});
diff --git a/spec/frontend/environments/edit_environment_spec.js b/spec/frontend/environments/edit_environment_spec.js
index 3e7f5dd5ff4..2c8c054ccbd 100644
--- a/spec/frontend/environments/edit_environment_spec.js
+++ b/spec/frontend/environments/edit_environment_spec.js
@@ -15,15 +15,12 @@ const DEFAULT_OPTS = {
projectEnvironmentsPath: '/projects/environments',
updateEnvironmentPath: '/proejcts/environments/1',
},
- propsData: { environment: { name: 'foo', externalUrl: 'https://foo.example.com' } },
+ propsData: { environment: { id: '0', name: 'foo', external_url: 'https://foo.example.com' } },
};
describe('~/environments/components/edit.vue', () => {
let wrapper;
let mock;
- let name;
- let url;
- let form;
const createWrapper = (opts = {}) =>
mountExtended(EditEnvironment, {
@@ -34,9 +31,6 @@ describe('~/environments/components/edit.vue', () => {
beforeEach(() => {
mock = new MockAdapter(axios);
wrapper = createWrapper();
- name = wrapper.findByLabelText('Name');
- url = wrapper.findByLabelText('External URL');
- form = wrapper.findByRole('form', { name: 'Edit environment' });
});
afterEach(() => {
@@ -44,19 +38,22 @@ describe('~/environments/components/edit.vue', () => {
wrapper.destroy();
});
+ const findNameInput = () => wrapper.findByLabelText('Name');
+ const findExternalUrlInput = () => wrapper.findByLabelText('External URL');
+ const findForm = () => wrapper.findByRole('form', { name: 'Edit environment' });
+
const showsLoading = () => wrapper.find(GlLoadingIcon).exists();
const submitForm = async (expected, response) => {
mock
.onPut(DEFAULT_OPTS.provide.updateEnvironmentPath, {
- name: expected.name,
external_url: expected.url,
+ id: '0',
})
.reply(...response);
- await name.setValue(expected.name);
- await url.setValue(expected.url);
+ await findExternalUrlInput().setValue(expected.url);
- await form.trigger('submit');
+ await findForm().trigger('submit');
await waitForPromises();
};
@@ -65,18 +62,8 @@ describe('~/environments/components/edit.vue', () => {
expect(header.exists()).toBe(true);
});
- it.each`
- input | value
- ${() => name} | ${'test'}
- ${() => url} | ${'https://example.org'}
- `('it changes the value of the input to $value', async ({ input, value }) => {
- await input().setValue(value);
-
- expect(input().element.value).toBe(value);
- });
-
it('shows loader after form is submitted', async () => {
- const expected = { name: 'test', url: 'https://google.ca' };
+ const expected = { url: 'https://google.ca' };
expect(showsLoading()).toBe(false);
@@ -86,7 +73,7 @@ describe('~/environments/components/edit.vue', () => {
});
it('submits the updated environment on submit', async () => {
- const expected = { name: 'test', url: 'https://google.ca' };
+ const expected = { url: 'https://google.ca' };
await submitForm(expected, [200, { path: '/test' }]);
@@ -94,11 +81,24 @@ describe('~/environments/components/edit.vue', () => {
});
it('shows errors on error', async () => {
- const expected = { name: 'test', url: 'https://google.ca' };
+ const expected = { url: 'https://google.ca' };
- await submitForm(expected, [400, { message: ['name taken'] }]);
+ await submitForm(expected, [400, { message: ['uh oh!'] }]);
- expect(createFlash).toHaveBeenCalledWith({ message: 'name taken' });
+ expect(createFlash).toHaveBeenCalledWith({ message: 'uh oh!' });
expect(showsLoading()).toBe(false);
});
+
+ it('renders a disabled "Name" field', () => {
+ const nameInput = findNameInput();
+
+ expect(nameInput.attributes().disabled).toBe('disabled');
+ expect(nameInput.element.value).toBe('foo');
+ });
+
+ it('renders an "External URL" field', () => {
+ const urlInput = findExternalUrlInput();
+
+ expect(urlInput.element.value).toBe('https://foo.example.com');
+ });
});
diff --git a/spec/frontend/environments/environment_form_spec.js b/spec/frontend/environments/environment_form_spec.js
index ed8fda71dab..f1af08bcf32 100644
--- a/spec/frontend/environments/environment_form_spec.js
+++ b/spec/frontend/environments/environment_form_spec.js
@@ -102,4 +102,52 @@ describe('~/environments/components/form.vue', () => {
wrapper = createWrapper({ loading: true });
expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true);
});
+ describe('when a new environment is being created', () => {
+ beforeEach(() => {
+ wrapper = createWrapper({
+ environment: {
+ name: '',
+ externalUrl: '',
+ },
+ });
+ });
+
+ it('renders an enabled "Name" field', () => {
+ const nameInput = wrapper.findByLabelText('Name');
+
+ expect(nameInput.attributes().disabled).toBeUndefined();
+ expect(nameInput.element.value).toBe('');
+ });
+
+ it('renders an "External URL" field', () => {
+ const urlInput = wrapper.findByLabelText('External URL');
+
+ expect(urlInput.element.value).toBe('');
+ });
+ });
+
+ describe('when an existing environment is being edited', () => {
+ beforeEach(() => {
+ wrapper = createWrapper({
+ environment: {
+ id: 1,
+ name: 'test',
+ externalUrl: 'https://example.com',
+ },
+ });
+ });
+
+ it('renders a disabled "Name" field', () => {
+ const nameInput = wrapper.findByLabelText('Name');
+
+ expect(nameInput.attributes().disabled).toBe('disabled');
+ expect(nameInput.element.value).toBe('test');
+ });
+
+ it('renders an "External URL" field', () => {
+ const urlInput = wrapper.findByLabelText('External URL');
+
+ expect(urlInput.element.value).toBe('https://example.com');
+ });
+ });
});
diff --git a/spec/frontend/environments/environment_item_spec.js b/spec/frontend/environments/environment_item_spec.js
index a568a7d5396..b930259149f 100644
--- a/spec/frontend/environments/environment_item_spec.js
+++ b/spec/frontend/environments/environment_item_spec.js
@@ -31,7 +31,6 @@ describe('Environment item', () => {
factory({
propsData: {
model: environment,
- canReadEnvironment: true,
tableData,
},
});
@@ -135,7 +134,6 @@ describe('Environment item', () => {
factory({
propsData: {
model: environmentWithoutDeployable,
- canReadEnvironment: true,
tableData,
},
});
@@ -161,7 +159,6 @@ describe('Environment item', () => {
factory({
propsData: {
model: environmentWithoutUpcomingDeployment,
- canReadEnvironment: true,
tableData,
},
});
@@ -177,7 +174,6 @@ describe('Environment item', () => {
factory({
propsData: {
model: environment,
- canReadEnvironment: true,
tableData,
shouldShowAutoStopDate: true,
},
@@ -205,7 +201,6 @@ describe('Environment item', () => {
...environment,
auto_stop_at: futureDate,
},
- canReadEnvironment: true,
tableData,
shouldShowAutoStopDate: true,
},
@@ -241,7 +236,6 @@ describe('Environment item', () => {
...environment,
auto_stop_at: pastDate,
},
- canReadEnvironment: true,
tableData,
shouldShowAutoStopDate: true,
},
@@ -360,7 +354,6 @@ describe('Environment item', () => {
factory({
propsData: {
model: folder,
- canReadEnvironment: true,
tableData,
},
});
diff --git a/spec/frontend/environments/environment_table_spec.js b/spec/frontend/environments/environment_table_spec.js
index 71426ee5170..1851163ac68 100644
--- a/spec/frontend/environments/environment_table_spec.js
+++ b/spec/frontend/environments/environment_table_spec.js
@@ -28,7 +28,6 @@ describe('Environment table', () => {
factory({
propsData: {
environments: [folder],
- canReadEnvironment: true,
...eeOnlyProps,
},
});
@@ -50,7 +49,6 @@ describe('Environment table', () => {
await factory({
propsData: {
environments: [mockItem],
- canReadEnvironment: true,
userCalloutsPath: '/callouts',
lockPromotionSvgPath: '/assets/illustrations/lock-promotion.svg',
helpCanaryDeploymentsPath: 'help/canary-deployments',
@@ -78,7 +76,6 @@ describe('Environment table', () => {
propsData: {
environments: [mockItem],
canCreateDeployment: false,
- canReadEnvironment: true,
userCalloutsPath: '/callouts',
lockPromotionSvgPath: '/assets/illustrations/lock-promotion.svg',
helpCanaryDeploymentsPath: 'help/canary-deployments',
@@ -114,7 +111,6 @@ describe('Environment table', () => {
propsData: {
environments: [mockItem],
canCreateDeployment: false,
- canReadEnvironment: true,
userCalloutsPath: '/callouts',
lockPromotionSvgPath: '/assets/illustrations/lock-promotion.svg',
helpCanaryDeploymentsPath: 'help/canary-deployments',
@@ -151,7 +147,6 @@ describe('Environment table', () => {
factory({
propsData: {
environments: [mockItem],
- canReadEnvironment: true,
userCalloutsPath: '/callouts',
lockPromotionSvgPath: '/assets/illustrations/lock-promotion.svg',
helpCanaryDeploymentsPath: 'help/canary-deployments',
@@ -179,7 +174,6 @@ describe('Environment table', () => {
propsData: {
environments: [mockItem],
canCreateDeployment: false,
- canReadEnvironment: true,
userCalloutsPath: '/callouts',
lockPromotionSvgPath: '/assets/illustrations/lock-promotion.svg',
helpCanaryDeploymentsPath: 'help/canary-deployments',
@@ -230,7 +224,6 @@ describe('Environment table', () => {
factory({
propsData: {
environments: mockItems,
- canReadEnvironment: true,
...eeOnlyProps,
},
});
@@ -296,7 +289,6 @@ describe('Environment table', () => {
factory({
propsData: {
environments: mockItems,
- canReadEnvironment: true,
...eeOnlyProps,
},
});
@@ -335,7 +327,6 @@ describe('Environment table', () => {
factory({
propsData: {
environments: mockItems,
- canReadEnvironment: true,
...eeOnlyProps,
},
});
@@ -364,7 +355,6 @@ describe('Environment table', () => {
factory({
propsData: {
environments: mockItems,
- canReadEnvironment: true,
...eeOnlyProps,
},
});
@@ -415,7 +405,6 @@ describe('Environment table', () => {
factory({
propsData: {
environments: mockItems,
- canReadEnvironment: true,
...eeOnlyProps,
},
});
diff --git a/spec/frontend/environments/environments_app_spec.js b/spec/frontend/environments/environments_app_spec.js
index dc176001943..cd05ecbfb53 100644
--- a/spec/frontend/environments/environments_app_spec.js
+++ b/spec/frontend/environments/environments_app_spec.js
@@ -1,4 +1,4 @@
-import { GlTabs, GlAlert } from '@gitlab/ui';
+import { GlTabs } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
@@ -7,9 +7,7 @@ import DeployBoard from '~/environments/components/deploy_board.vue';
import EmptyState from '~/environments/components/empty_state.vue';
import EnableReviewAppModal from '~/environments/components/enable_review_app_modal.vue';
import EnvironmentsApp from '~/environments/components/environments_app.vue';
-import { ENVIRONMENTS_SURVEY_DISMISSED_COOKIE_NAME } from '~/environments/constants';
import axios from '~/lib/utils/axios_utils';
-import { setCookie, getCookie, removeCookie } from '~/lib/utils/common_utils';
import * as urlUtils from '~/lib/utils/url_utility';
import { environment, folder } from './mock_data';
@@ -20,7 +18,6 @@ describe('Environment', () => {
const mockData = {
endpoint: 'environments.json',
canCreateEnvironment: true,
- canReadEnvironment: true,
newEnvironmentPath: 'environments/new',
helpPagePath: 'help',
userCalloutsPath: '/callouts',
@@ -50,7 +47,6 @@ describe('Environment', () => {
const findNewEnvironmentButton = () => wrapper.findByTestId('new-environment');
const findEnvironmentsTabAvailable = () => wrapper.find('.js-environments-tab-available > a');
const findEnvironmentsTabStopped = () => wrapper.find('.js-environments-tab-stopped > a');
- const findSurveyAlert = () => wrapper.find(GlAlert);
beforeEach(() => {
mock = new MockAdapter(axios);
@@ -283,49 +279,4 @@ describe('Environment', () => {
expect(wrapper.findComponent(GlTabs).attributes('value')).toBe('1');
});
});
-
- describe('survey alert', () => {
- beforeEach(async () => {
- mockRequest(200, { environments: [] });
- await createWrapper(true);
- });
-
- afterEach(() => {
- removeCookie(ENVIRONMENTS_SURVEY_DISMISSED_COOKIE_NAME);
- });
-
- describe('when the user has not dismissed the alert', () => {
- it('shows the alert', () => {
- expect(findSurveyAlert().exists()).toBe(true);
- });
-
- describe('when the user dismisses the alert', () => {
- beforeEach(() => {
- findSurveyAlert().vm.$emit('dismiss');
- });
-
- it('hides the alert', () => {
- expect(findSurveyAlert().exists()).toBe(false);
- });
-
- it('persists the dismisal using a cookie', () => {
- const cookieValue = getCookie(ENVIRONMENTS_SURVEY_DISMISSED_COOKIE_NAME);
-
- expect(cookieValue).toBe('true');
- });
- });
- });
-
- describe('when the user has previously dismissed the alert', () => {
- beforeEach(async () => {
- setCookie(ENVIRONMENTS_SURVEY_DISMISSED_COOKIE_NAME, 'true');
-
- await createWrapper(true);
- });
-
- it('does not show the alert', () => {
- expect(findSurveyAlert().exists()).toBe(false);
- });
- });
- });
});
diff --git a/spec/frontend/environments/environments_detail_header_spec.js b/spec/frontend/environments/environments_detail_header_spec.js
index 6334060c736..305e7385b43 100644
--- a/spec/frontend/environments/environments_detail_header_spec.js
+++ b/spec/frontend/environments/environments_detail_header_spec.js
@@ -44,7 +44,6 @@ describe('Environments detail header component', () => {
TimeAgo,
},
propsData: {
- canReadEnvironment: false,
canAdminEnvironment: false,
canUpdateEnvironment: false,
canStopEnvironment: false,
@@ -60,7 +59,7 @@ describe('Environments detail header component', () => {
describe('default state with minimal access', () => {
beforeEach(() => {
- createWrapper({ props: { environment: createEnvironment() } });
+ createWrapper({ props: { environment: createEnvironment({ externalUrl: null }) } });
});
it('displays the environment name', () => {
@@ -164,7 +163,6 @@ describe('Environments detail header component', () => {
createWrapper({
props: {
environment: createEnvironment({ hasTerminals: true, externalUrl }),
- canReadEnvironment: true,
},
});
});
@@ -178,8 +176,7 @@ describe('Environments detail header component', () => {
beforeEach(() => {
createWrapper({
props: {
- environment: createEnvironment(),
- canReadEnvironment: true,
+ environment: createEnvironment({ metricsUrl: 'my metrics url' }),
metricsPath,
},
});
@@ -195,7 +192,6 @@ describe('Environments detail header component', () => {
createWrapper({
props: {
environment: createEnvironment(),
- canReadEnvironment: true,
canAdminEnvironment: true,
canStopEnvironment: true,
canUpdateEnvironment: true,
diff --git a/spec/frontend/environments/environments_folder_view_spec.js b/spec/frontend/environments/environments_folder_view_spec.js
index e4661d27872..72a7449f24e 100644
--- a/spec/frontend/environments/environments_folder_view_spec.js
+++ b/spec/frontend/environments/environments_folder_view_spec.js
@@ -11,7 +11,6 @@ describe('Environments Folder View', () => {
const mockData = {
endpoint: 'environments.json',
folderName: 'review',
- canReadEnvironment: true,
cssContainerClass: 'container',
userCalloutsPath: '/callouts',
lockPromotionSvgPath: '/assets/illustrations/lock-promotion.svg',
diff --git a/spec/frontend/environments/folder/environments_folder_view_spec.js b/spec/frontend/environments/folder/environments_folder_view_spec.js
index d02ed8688c6..9eb57b2682f 100644
--- a/spec/frontend/environments/folder/environments_folder_view_spec.js
+++ b/spec/frontend/environments/folder/environments_folder_view_spec.js
@@ -14,7 +14,6 @@ describe('Environments Folder View', () => {
const mockData = {
endpoint: 'environments.json',
folderName: 'review',
- canReadEnvironment: true,
cssContainerClass: 'container',
userCalloutsPath: '/callouts',
lockPromotionSvgPath: '/assets/illustrations/lock-promotion.svg',
diff --git a/spec/frontend/error_tracking_settings/components/app_spec.js b/spec/frontend/error_tracking_settings/components/app_spec.js
index e0be81b3899..30541ba68a5 100644
--- a/spec/frontend/error_tracking_settings/components/app_spec.js
+++ b/spec/frontend/error_tracking_settings/components/app_spec.js
@@ -1,6 +1,9 @@
+import { GlFormRadioGroup, GlFormRadio } from '@gitlab/ui';
import { createLocalVue, shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import Vuex from 'vuex';
import { TEST_HOST } from 'helpers/test_constants';
+import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import ErrorTrackingSettings from '~/error_tracking_settings/components/app.vue';
import ErrorTrackingForm from '~/error_tracking_settings/components/error_tracking_form.vue';
import ProjectDropdown from '~/error_tracking_settings/components/project_dropdown.vue';
@@ -14,20 +17,31 @@ describe('error tracking settings app', () => {
let wrapper;
function mountComponent() {
- wrapper = shallowMount(ErrorTrackingSettings, {
- localVue,
- store, // Override the imported store
- propsData: {
- initialEnabled: 'true',
- initialApiHost: TEST_HOST,
- initialToken: 'someToken',
- initialProject: null,
- listProjectsEndpoint: TEST_HOST,
- operationsSettingsEndpoint: TEST_HOST,
- },
- });
+ wrapper = extendedWrapper(
+ shallowMount(ErrorTrackingSettings, {
+ localVue,
+ store, // Override the imported store
+ propsData: {
+ initialEnabled: 'true',
+ initialIntegrated: 'false',
+ initialApiHost: TEST_HOST,
+ initialToken: 'someToken',
+ initialProject: null,
+ listProjectsEndpoint: TEST_HOST,
+ operationsSettingsEndpoint: TEST_HOST,
+ },
+ }),
+ );
}
+ const findBackendSettingsSection = () => wrapper.findByTestId('tracking-backend-settings');
+ const findBackendSettingsRadioGroup = () =>
+ findBackendSettingsSection().findComponent(GlFormRadioGroup);
+ const findBackendSettingsRadioButtons = () =>
+ findBackendSettingsRadioGroup().findAllComponents(GlFormRadio);
+ const findElementWithText = (wrappers, text) => wrappers.filter((item) => item.text() === text);
+ const findSentrySettings = () => wrapper.findByTestId('sentry-setting-form');
+
beforeEach(() => {
store = createStore();
@@ -62,4 +76,46 @@ describe('error tracking settings app', () => {
});
});
});
+
+ describe('tracking-backend settings', () => {
+ it('contains a form-group with the correct label', () => {
+ expect(findBackendSettingsSection().attributes('label')).toBe('Error tracking backend');
+ });
+
+ it('contains a radio group', () => {
+ expect(findBackendSettingsRadioGroup().exists()).toBe(true);
+ });
+
+ it('contains the correct radio buttons', () => {
+ expect(findBackendSettingsRadioButtons()).toHaveLength(2);
+
+ expect(findElementWithText(findBackendSettingsRadioButtons(), 'Sentry')).toHaveLength(1);
+ expect(findElementWithText(findBackendSettingsRadioButtons(), 'GitLab')).toHaveLength(1);
+ });
+
+ it('toggles the sentry-settings section when sentry is selected as a tracking-backend', async () => {
+ expect(findSentrySettings().exists()).toBe(true);
+
+ // set the "integrated" setting to "true"
+ findBackendSettingsRadioGroup().vm.$emit('change', true);
+
+ await nextTick();
+
+ expect(findSentrySettings().exists()).toBe(false);
+ });
+
+ it.each([true, false])(
+ 'calls the `updateIntegrated` action when the setting changes to `%s`',
+ (integrated) => {
+ jest.spyOn(store, 'dispatch').mockImplementation();
+
+ expect(store.dispatch).toHaveBeenCalledTimes(0);
+
+ findBackendSettingsRadioGroup().vm.$emit('change', integrated);
+
+ expect(store.dispatch).toHaveBeenCalledTimes(1);
+ expect(store.dispatch).toHaveBeenCalledWith('updateIntegrated', integrated);
+ },
+ );
+ });
});
diff --git a/spec/frontend/error_tracking_settings/mock.js b/spec/frontend/error_tracking_settings/mock.js
index e64a6d1fe14..b2d7a912518 100644
--- a/spec/frontend/error_tracking_settings/mock.js
+++ b/spec/frontend/error_tracking_settings/mock.js
@@ -42,6 +42,7 @@ export const sampleBackendProject = {
export const sampleFrontendSettings = {
apiHost: 'apiHost',
enabled: false,
+ integrated: false,
token: 'token',
selectedProject: {
slug: normalizedProject.slug,
@@ -54,6 +55,7 @@ export const sampleFrontendSettings = {
export const transformedSettings = {
api_host: 'apiHost',
enabled: false,
+ integrated: false,
token: 'token',
project: {
slug: normalizedProject.slug,
@@ -71,6 +73,7 @@ export const defaultProps = {
export const initialEmptyState = {
apiHost: '',
enabled: false,
+ integrated: false,
project: null,
token: '',
listProjectsEndpoint: TEST_HOST,
@@ -80,6 +83,7 @@ export const initialEmptyState = {
export const initialPopulatedState = {
apiHost: 'apiHost',
enabled: true,
+ integrated: true,
project: JSON.stringify(projectList[0]),
token: 'token',
listProjectsEndpoint: TEST_HOST,
diff --git a/spec/frontend/error_tracking_settings/store/actions_spec.js b/spec/frontend/error_tracking_settings/store/actions_spec.js
index 281db7d9686..1b9be042dd4 100644
--- a/spec/frontend/error_tracking_settings/store/actions_spec.js
+++ b/spec/frontend/error_tracking_settings/store/actions_spec.js
@@ -202,5 +202,11 @@ describe('error tracking settings actions', () => {
done,
);
});
+
+ it.each([true, false])('should set the `integrated` flag to `%s`', async (payload) => {
+ await testAction(actions.updateIntegrated, payload, state, [
+ { type: types.UPDATE_INTEGRATED, payload },
+ ]);
+ });
});
});
diff --git a/spec/frontend/error_tracking_settings/store/mutation_spec.js b/spec/frontend/error_tracking_settings/store/mutation_spec.js
index 78fd56904b3..ecf1c91c08a 100644
--- a/spec/frontend/error_tracking_settings/store/mutation_spec.js
+++ b/spec/frontend/error_tracking_settings/store/mutation_spec.js
@@ -25,6 +25,7 @@ describe('error tracking settings mutations', () => {
expect(state.apiHost).toEqual('');
expect(state.enabled).toEqual(false);
+ expect(state.integrated).toEqual(false);
expect(state.selectedProject).toEqual(null);
expect(state.token).toEqual('');
expect(state.listProjectsEndpoint).toEqual(TEST_HOST);
@@ -38,6 +39,7 @@ describe('error tracking settings mutations', () => {
expect(state.apiHost).toEqual('apiHost');
expect(state.enabled).toEqual(true);
+ expect(state.integrated).toEqual(true);
expect(state.selectedProject).toEqual(projectList[0]);
expect(state.token).toEqual('token');
expect(state.listProjectsEndpoint).toEqual(TEST_HOST);
@@ -78,5 +80,11 @@ describe('error tracking settings mutations', () => {
expect(state.connectSuccessful).toBe(false);
expect(state.connectError).toBe(false);
});
+
+ it.each([true, false])('should update `integrated` to `%s`', (integrated) => {
+ mutations[types.UPDATE_INTEGRATED](state, integrated);
+
+ expect(state.integrated).toBe(integrated);
+ });
});
});
diff --git a/spec/frontend/error_tracking_settings/utils_spec.js b/spec/frontend/error_tracking_settings/utils_spec.js
index 4b144f7daf1..61e75cdc45e 100644
--- a/spec/frontend/error_tracking_settings/utils_spec.js
+++ b/spec/frontend/error_tracking_settings/utils_spec.js
@@ -11,12 +11,14 @@ describe('error tracking settings utils', () => {
const emptyFrontendSettingsObject = {
apiHost: '',
enabled: false,
+ integrated: false,
token: '',
selectedProject: null,
};
const transformedEmptySettingsObject = {
api_host: null,
enabled: false,
+ integrated: false,
token: null,
project: null,
};
diff --git a/spec/frontend/experimentation/utils_spec.js b/spec/frontend/experimentation/utils_spec.js
index 2ba8c65a252..999bed1ffbd 100644
--- a/spec/frontend/experimentation/utils_spec.js
+++ b/spec/frontend/experimentation/utils_spec.js
@@ -37,6 +37,50 @@ describe('experiment Utilities', () => {
});
});
+ describe('getAllExperimentContexts', () => {
+ const schema = TRACKING_CONTEXT_SCHEMA;
+ let origGon;
+
+ beforeEach(() => {
+ origGon = window.gon;
+ });
+
+ afterEach(() => {
+ window.gon = origGon;
+ });
+
+ it('collects all of the experiment contexts into a single array', () => {
+ const experiments = [
+ { experiment: 'abc', variant: 'candidate' },
+ { experiment: 'def', variant: 'control' },
+ { experiment: 'ghi', variant: 'blue' },
+ ];
+ window.gon = {
+ experiment: experiments.reduce((collector, { experiment, variant }) => {
+ return { ...collector, [experiment]: { experiment, variant } };
+ }, {}),
+ };
+
+ expect(experimentUtils.getAllExperimentContexts()).toEqual(
+ experiments.map((data) => ({ schema, data })),
+ );
+ });
+
+ it('returns an empty array if there are no experiments', () => {
+ window.gon.experiment = {};
+
+ expect(experimentUtils.getAllExperimentContexts()).toEqual([]);
+ });
+
+ it('includes all additional experiment data', () => {
+ const experiment = 'experimentWithCustomData';
+ const data = { experiment, variant: 'control', color: 'blue', style: 'rounded' };
+ window.gon.experiment[experiment] = data;
+
+ expect(experimentUtils.getAllExperimentContexts()).toContainEqual({ schema, data });
+ });
+ });
+
describe('isExperimentVariant', () => {
describe.each`
gon | input | output
diff --git a/spec/frontend/filtered_search/services/recent_searches_service_spec.js b/spec/frontend/filtered_search/services/recent_searches_service_spec.js
index 6711ce03d40..dfa53652eb1 100644
--- a/spec/frontend/filtered_search/services/recent_searches_service_spec.js
+++ b/spec/frontend/filtered_search/services/recent_searches_service_spec.js
@@ -145,13 +145,13 @@ describe('RecentSearchesService', () => {
let isAvailable;
beforeEach(() => {
- jest.spyOn(AccessorUtilities, 'isLocalStorageAccessSafe');
+ jest.spyOn(AccessorUtilities, 'canUseLocalStorage');
isAvailable = RecentSearchesService.isAvailable();
});
- it('should call .isLocalStorageAccessSafe', () => {
- expect(AccessorUtilities.isLocalStorageAccessSafe).toHaveBeenCalled();
+ it('should call .canUseLocalStorage', () => {
+ expect(AccessorUtilities.canUseLocalStorage).toHaveBeenCalled();
});
it('should return a boolean', () => {
diff --git a/spec/frontend/fixtures/api_markdown.yml b/spec/frontend/fixtures/api_markdown.yml
index b581aac6aee..1edb8cb3f41 100644
--- a/spec/frontend/fixtures/api_markdown.yml
+++ b/spec/frontend/fixtures/api_markdown.yml
@@ -12,14 +12,71 @@
markdown: |-
* {-deleted-}
* {+added+}
-- name: subscript
- markdown: H<sub>2</sub>O
-- name: superscript
- markdown: 2<sup>8</sup> = 256
- name: strike
markdown: '~~del~~'
- name: horizontal_rule
markdown: '---'
+- name: html_marks
+ markdown: |-
+ * Content editor is ~~great~~<ins>amazing</ins>.
+ * If the changes <abbr title="Looks good to merge">LGTM</abbr>, please <abbr title="Merge when pipeline succeeds">MWPS</abbr>.
+ * The English song <q>Oh I do like to be beside the seaside</q> looks like this in Hebrew: <span dir="rtl">××”, ×× ×™ ×והב להיות ליד חוף ×”×™×</span>. In the computer's memory, this is stored as <bdo dir="ltr">××”, ×× ×™ ×והב להיות ליד חוף ×”×™×</bdo>.
+ * <cite>The Scream</cite> by Edvard Munch. Painted in 1893.
+ * <dfn>HTML</dfn> is the standard markup language for creating web pages.
+ * Do not forget to buy <mark>milk</mark> today.
+ * This is a paragraph and <small>smaller text goes here</small>.
+ * The concert starts at <time datetime="20:00">20:00</time> and you'll be able to enjoy the band for at least <time datetime="PT2H30M">2h 30m</time>.
+ * Press <kbd>Ctrl</kbd> + <kbd>C</kbd> to copy text (Windows).
+ * WWF's goal is to: <q>Build a future where people live in harmony with nature.</q> We hope they succeed.
+ * The error occured was: <samp>Keyboard not found. Press F1 to continue.</samp>
+ * The area of a triangle is: 1/2 x <var>b</var> x <var>h</var>, where <var>b</var> is the base, and <var>h</var> is the vertical height.
+ * <ruby>æ¼¢<rt>ã„ㄢˋ</rt></ruby>
+ * C<sub>7</sub>H<sub>16</sub> + O<sub>2</sub> → CO<sub>2</sub> + H<sub>2</sub>O
+ * The **Pythagorean theorem** is often expressed as <var>a<sup>2</sup></var> + <var>b<sup>2</sup></var> = <var>c<sup>2</sup></var>
+- name: div
+ markdown: |-
+ <div>plain text</div>
+ <div>
+
+ just a plain ol' div, not much to _expect_!
+
+ </div>
+- name: figure
+ markdown: |-
+ <figure>
+
+ ![Elephant at sunset](elephant-sunset.jpg)
+
+ <figcaption>An elephant at sunset</figcaption>
+ </figure>
+ <figure>
+
+ ![A crocodile wearing crocs](croc-crocs.jpg)
+
+ <figcaption>
+
+ A crocodile wearing _crocs_!
+
+ </figcaption>
+ </figure>
+- name: description_list
+ markdown: |-
+ <dl>
+ <dt>Frog</dt>
+ <dd>Wet green thing</dd>
+ <dt>Rabbit</dt>
+ <dd>Warm fluffy thing</dd>
+ <dt>Punt</dt>
+ <dd>Kick a ball</dd>
+ <dd>Take a bet</dd>
+ <dt>Color</dt>
+ <dt>Colour</dt>
+ <dd>
+
+ Any hue except _white_ or **black**
+
+ </dd>
+ </dl>
- name: link
markdown: '[GitLab](https://gitlab.com)'
- name: attachment_link
@@ -66,16 +123,31 @@
- name: thematic_break
markdown: |-
---
-- name: bullet_list
+- name: bullet_list_style_1
markdown: |-
* list item 1
* list item 2
* embedded list item 3
+- name: bullet_list_style_2
+ markdown: |-
+ - list item 1
+ - list item 2
+ * embedded list item 3
+- name: bullet_list_style_3
+ markdown: |-
+ + list item 1
+ + list item 2
+ - embedded list item 3
- name: ordered_list
markdown: |-
1. list item 1
2. list item 2
3. list item 3
+- name: ordered_list_with_start_order
+ markdown: |-
+ 134. list item 1
+ 135. list item 2
+ 136. list item 3
- name: task_list
markdown: |-
* [x] hello
@@ -92,6 +164,11 @@
1. [ ] of nested
1. [x] task list
2. [ ] items
+- name: ordered_task_list_with_order
+ markdown: |-
+ 4893. [x] hello
+ 4894. [x] world
+ 4895. [ ] example
- name: image
markdown: '![alt text](https://gitlab.com/logo.png)'
- name: hard_break
@@ -102,17 +179,28 @@
markdown: |-
| header | header |
|--------|--------|
- | cell | cell |
- | cell | cell |
-- name: table_with_alignment
- markdown: |-
- | header | : header : | header : |
- |--------|------------|----------|
- | cell | cell | cell |
- | cell | cell | cell |
+ | `code` | cell with **bold** |
+ | ~~strike~~ | cell with _italic_ |
+
+ # content after table
- name: emoji
markdown: ':sparkles: :heart: :100:'
- name: reference
context: project_wiki
markdown: |-
Hi @gitlab - thank you for reporting this ~bug (#1) we hope to fix it in %1.1 as part of !1
+- name: audio
+ markdown: '![Sample Audio](https://gitlab.com/gitlab.mp3)'
+- name: video
+ markdown: '![Sample Video](https://gitlab.com/gitlab.mp4)'
+- name: audio_and_video_in_lists
+ markdown: |-
+ * ![Sample Audio](https://gitlab.com/1.mp3)
+ * ![Sample Video](https://gitlab.com/2.mp4)
+
+ 1. ![Sample Video](https://gitlab.com/1.mp4)
+ 2. ![Sample Audio](https://gitlab.com/2.mp3)
+
+ * [x] ![Sample Audio](https://gitlab.com/1.mp3)
+ * [x] ![Sample Audio](https://gitlab.com/2.mp3)
+ * [x] ![Sample Video](https://gitlab.com/3.mp4)
diff --git a/spec/frontend/fixtures/freeze_period.rb b/spec/frontend/fixtures/freeze_period.rb
index 09e4f969e1d..42762fa56f9 100644
--- a/spec/frontend/fixtures/freeze_period.rb
+++ b/spec/frontend/fixtures/freeze_period.rb
@@ -39,13 +39,4 @@ RSpec.describe 'Freeze Periods (JavaScript fixtures)' do
expect(response).to be_successful
end
end
-
- describe TimeZoneHelper, '(JavaScript fixtures)' do
- let(:response) { timezone_data.to_json }
-
- it 'api/freeze-periods/timezone_data.json' do
- # Looks empty but does things
- # More info: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38525/diffs#note_391048415
- end
- end
end
diff --git a/spec/frontend/fixtures/runner.rb b/spec/frontend/fixtures/runner.rb
index e29a58f43b9..d5d6f534def 100644
--- a/spec/frontend/fixtures/runner.rb
+++ b/spec/frontend/fixtures/runner.rb
@@ -14,6 +14,7 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
let_it_be(:instance_runner) { create(:ci_runner, :instance, version: '1.0.0', revision: '123', description: 'Instance runner', ip_address: '127.0.0.1') }
let_it_be(:group_runner) { create(:ci_runner, :group, groups: [group], active: false, version: '2.0.0', revision: '456', description: 'Group runner', ip_address: '127.0.0.1') }
+ let_it_be(:group_runner_2) { create(:ci_runner, :group, groups: [group], active: false, version: '2.0.0', revision: '456', description: 'Group runner 2', ip_address: '127.0.0.1') }
let_it_be(:project_runner) { create(:ci_runner, :project, projects: [project], active: false, version: '2.0.0', revision: '456', description: 'Project runner', ip_address: '127.0.0.1') }
query_path = 'runner/graphql/'
@@ -27,14 +28,14 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
remove_repository(project)
end
- before do
- sign_in(admin)
- enable_admin_mode!(admin)
- end
-
describe GraphQL::Query, type: :request do
get_runners_query_name = 'get_runners.query.graphql'
+ before do
+ sign_in(admin)
+ enable_admin_mode!(admin)
+ end
+
let_it_be(:query) do
get_graphql_query_as_string("#{query_path}#{get_runners_query_name}")
end
@@ -55,6 +56,11 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
describe GraphQL::Query, type: :request do
get_runner_query_name = 'get_runner.query.graphql'
+ before do
+ sign_in(admin)
+ enable_admin_mode!(admin)
+ end
+
let_it_be(:query) do
get_graphql_query_as_string("#{query_path}#{get_runner_query_name}")
end
@@ -67,4 +73,35 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
expect_graphql_errors_to_be_empty
end
end
+
+ describe GraphQL::Query, type: :request do
+ get_group_runners_query_name = 'get_group_runners.query.graphql'
+
+ let_it_be(:group_owner) { create(:user) }
+
+ before do
+ group.add_owner(group_owner)
+ end
+
+ let_it_be(:query) do
+ get_graphql_query_as_string("#{query_path}#{get_group_runners_query_name}")
+ end
+
+ it "#{fixtures_path}#{get_group_runners_query_name}.json" do
+ post_graphql(query, current_user: group_owner, variables: {
+ groupFullPath: group.full_path
+ })
+
+ expect_graphql_errors_to_be_empty
+ end
+
+ it "#{fixtures_path}#{get_group_runners_query_name}.paginated.json" do
+ post_graphql(query, current_user: group_owner, variables: {
+ groupFullPath: group.full_path,
+ first: 1
+ })
+
+ expect_graphql_errors_to_be_empty
+ end
+ end
end
diff --git a/spec/frontend/fixtures/startup_css.rb b/spec/frontend/fixtures/startup_css.rb
index be2ead756cf..1bd99f5cd7f 100644
--- a/spec/frontend/fixtures/startup_css.rb
+++ b/spec/frontend/fixtures/startup_css.rb
@@ -40,6 +40,21 @@ RSpec.describe 'Startup CSS fixtures', type: :controller do
expect(response).to be_successful
end
+
+ # This Feature Flag is off by default
+ # This ensures that the correct css is generated
+ # When the feature flag is off, the general startup will capture it
+ # This will be removed as part of https://gitlab.com/gitlab-org/gitlab/-/issues/339348
+ it "startup_css/project-#{type}-search-ff-on.html" do
+ stub_feature_flags(new_header_search: true)
+
+ get :show, params: {
+ namespace_id: project.namespace.to_param,
+ id: project
+ }
+
+ expect(response).to be_successful
+ end
end
describe ProjectsController, '(Startup CSS fixtures)', type: :controller do
diff --git a/spec/frontend/fixtures/static/pipeline_graph.html b/spec/frontend/fixtures/static/pipeline_graph.html
deleted file mode 100644
index d2c30ff9211..00000000000
--- a/spec/frontend/fixtures/static/pipeline_graph.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<div class="pipeline-visualization js-pipeline-graph">
-<ul class="stage-column-list">
-<li class="stage-column">
-<div class="stage-name">
-<a href="/">
-Test
-<div class="builds-container">
-<ul>
-<li class="build">
-<div class="curve"></div>
-<a>
-<svg></svg>
-<div>
-stop_review
-</div>
-</a>
-</li>
-</ul>
-</div>
-</a>
-</div>
-</li>
-</ul>
-</div>
diff --git a/spec/frontend/fixtures/timezones.rb b/spec/frontend/fixtures/timezones.rb
new file mode 100644
index 00000000000..261dcf5e116
--- /dev/null
+++ b/spec/frontend/fixtures/timezones.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe TimeZoneHelper, '(JavaScript fixtures)' do
+ include JavaScriptFixturesHelpers
+ include TimeZoneHelper
+
+ let(:response) { @timezones.sort_by! { |tz| tz[:name] }.to_json }
+
+ before(:all) do
+ clean_frontend_fixtures('timezones/')
+ end
+
+ it 'timezones/short.json' do
+ @timezones = timezone_data(format: :short)
+ end
+
+ it 'timezones/full.json' do
+ @timezones = timezone_data(format: :full)
+ end
+end
diff --git a/spec/frontend/frequent_items/store/actions_spec.js b/spec/frontend/frequent_items/store/actions_spec.js
index dacfc7ce707..fb0321545c2 100644
--- a/spec/frontend/frequent_items/store/actions_spec.js
+++ b/spec/frontend/frequent_items/store/actions_spec.js
@@ -109,7 +109,7 @@ describe('Frequent Items Dropdown Store Actions', () => {
});
it('should dispatch `receiveFrequentItemsError`', (done) => {
- jest.spyOn(AccessorUtilities, 'isLocalStorageAccessSafe').mockReturnValue(false);
+ jest.spyOn(AccessorUtilities, 'canUseLocalStorage').mockReturnValue(false);
mockedState.namespace = mockNamespace;
mockedState.storageKey = mockStorageKey;
diff --git a/spec/frontend/groups/components/app_spec.js b/spec/frontend/groups/components/app_spec.js
index da0ff2a64ec..bc8c6460cf4 100644
--- a/spec/frontend/groups/components/app_spec.js
+++ b/spec/frontend/groups/components/app_spec.js
@@ -182,7 +182,12 @@ describe('AppComponent', () => {
jest.spyOn(window.history, 'replaceState').mockImplementation(() => {});
jest.spyOn(window, 'scrollTo').mockImplementation(() => {});
- const fetchPagePromise = vm.fetchPage(2, null, null, true);
+ const fetchPagePromise = vm.fetchPage({
+ page: 2,
+ filterGroupsBy: null,
+ sortBy: null,
+ archived: true,
+ });
expect(vm.isLoading).toBe(true);
expect(vm.fetchGroups).toHaveBeenCalledWith({
diff --git a/spec/frontend/groups/components/groups_spec.js b/spec/frontend/groups/components/groups_spec.js
index dc1a10639fc..0ec1ef5a49e 100644
--- a/spec/frontend/groups/components/groups_spec.js
+++ b/spec/frontend/groups/components/groups_spec.js
@@ -41,13 +41,12 @@ describe('GroupsComponent', () => {
vm.change(2);
- expect(eventHub.$emit).toHaveBeenCalledWith(
- 'fetchPage',
- 2,
- expect.any(Object),
- expect.any(Object),
- expect.any(Object),
- );
+ expect(eventHub.$emit).toHaveBeenCalledWith('fetchPage', {
+ page: 2,
+ archived: null,
+ filterGroupsBy: null,
+ sortBy: null,
+ });
});
});
});
diff --git a/spec/frontend/groups/components/invite_members_banner_spec.js b/spec/frontend/groups/components/invite_members_banner_spec.js
index 0da2f84f2a1..c81edad499c 100644
--- a/spec/frontend/groups/components/invite_members_banner_spec.js
+++ b/spec/frontend/groups/components/invite_members_banner_spec.js
@@ -1,29 +1,29 @@
-import { GlBanner, GlButton } from '@gitlab/ui';
+import { GlBanner } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import MockAdapter from 'axios-mock-adapter';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import InviteMembersBanner from '~/groups/components/invite_members_banner.vue';
import eventHub from '~/invite_members/event_hub';
-import { setCookie, parseBoolean } from '~/lib/utils/common_utils';
+import axios from '~/lib/utils/axios_utils';
jest.mock('~/lib/utils/common_utils');
-const isDismissedKey = 'invite_99_1';
const title = 'Collaborate with your team';
const body =
"We noticed that you haven't invited anyone to this group. Invite your colleagues so you can discuss issues, collaborate on merge requests, and share your knowledge";
-const svgPath = '/illustrations/background';
-const inviteMembersPath = 'groups/members';
const buttonText = 'Invite your colleagues';
-const trackLabel = 'invite_members_banner';
+const provide = {
+ svgPath: '/illustrations/background',
+ inviteMembersPath: 'groups/members',
+ trackLabel: 'invite_members_banner',
+ calloutsPath: 'call/out/path',
+ calloutsFeatureId: 'some-feature-id',
+ groupId: '1',
+};
const createComponent = (stubs = {}) => {
return shallowMount(InviteMembersBanner, {
- provide: {
- svgPath,
- inviteMembersPath,
- isDismissedKey,
- trackLabel,
- },
+ provide,
stubs,
});
};
@@ -31,8 +31,10 @@ const createComponent = (stubs = {}) => {
describe('InviteMembersBanner', () => {
let wrapper;
let trackingSpy;
+ let mockAxios;
beforeEach(() => {
+ mockAxios = new MockAdapter(axios);
document.body.dataset.page = 'any:page';
trackingSpy = mockTracking('_category_', undefined, jest.spyOn);
});
@@ -40,22 +42,28 @@ describe('InviteMembersBanner', () => {
afterEach(() => {
wrapper.destroy();
wrapper = null;
+ mockAxios.restore();
unmockTracking();
});
describe('tracking', () => {
+ const mockTrackingOnWrapper = () => {
+ unmockTracking();
+ trackingSpy = mockTracking('_category_', wrapper.element, jest.spyOn);
+ };
+
beforeEach(() => {
wrapper = createComponent({ GlBanner });
});
const trackCategory = undefined;
- const displayEvent = 'invite_members_banner_displayed';
const buttonClickEvent = 'invite_members_banner_button_clicked';
- const dismissEvent = 'invite_members_banner_dismissed';
it('sends the displayEvent when the banner is displayed', () => {
+ const displayEvent = 'invite_members_banner_displayed';
+
expect(trackingSpy).toHaveBeenCalledWith(trackCategory, displayEvent, {
- label: trackLabel,
+ label: provide.trackLabel,
});
});
@@ -74,16 +82,20 @@ describe('InviteMembersBanner', () => {
it('sends the buttonClickEvent with correct trackCategory and trackLabel', () => {
expect(trackingSpy).toHaveBeenCalledWith(trackCategory, buttonClickEvent, {
- label: trackLabel,
+ label: provide.trackLabel,
});
});
});
it('sends the dismissEvent when the banner is dismissed', () => {
+ mockTrackingOnWrapper();
+ mockAxios.onPost(provide.calloutsPath).replyOnce(200);
+ const dismissEvent = 'invite_members_banner_dismissed';
+
wrapper.find(GlBanner).vm.$emit('close');
expect(trackingSpy).toHaveBeenCalledWith(trackCategory, dismissEvent, {
- label: trackLabel,
+ label: provide.trackLabel,
});
});
});
@@ -98,7 +110,7 @@ describe('InviteMembersBanner', () => {
});
it('uses the svgPath for the banner svgpath', () => {
- expect(findBanner().attributes('svgpath')).toBe(svgPath);
+ expect(findBanner().attributes('svgpath')).toBe(provide.svgPath);
});
it('uses the title from options for title', () => {
@@ -115,35 +127,20 @@ describe('InviteMembersBanner', () => {
});
describe('dismissing', () => {
- const findButton = () => wrapper.findAll(GlButton).at(1);
-
beforeEach(() => {
wrapper = createComponent({ GlBanner });
-
- findButton().vm.$emit('click');
});
- it('sets iDismissed to true', () => {
- expect(wrapper.vm.isDismissed).toBe(true);
+ it('should render the banner when not dismissed', () => {
+ expect(wrapper.find(GlBanner).exists()).toBe(true);
});
- it('sets the cookie with the isDismissedKey', () => {
- expect(setCookie).toHaveBeenCalledWith(isDismissedKey, true);
- });
- });
-
- describe('when a dismiss cookie exists', () => {
- beforeEach(() => {
- parseBoolean.mockReturnValue(true);
-
- wrapper = createComponent({ GlBanner });
- });
-
- it('sets isDismissed to true', () => {
- expect(wrapper.vm.isDismissed).toBe(true);
- });
+ it('should close the banner when dismiss is clicked', async () => {
+ mockAxios.onPost(provide.calloutsPath).replyOnce(200);
+ expect(wrapper.find(GlBanner).exists()).toBe(true);
+ wrapper.find(GlBanner).vm.$emit('close');
- it('does not render the banner', () => {
+ await wrapper.vm.$nextTick();
expect(wrapper.find(GlBanner).exists()).toBe(false);
});
});
diff --git a/spec/frontend/groups/components/item_stats_spec.js b/spec/frontend/groups/components/item_stats_spec.js
index f350012ebed..49f3f5da43c 100644
--- a/spec/frontend/groups/components/item_stats_spec.js
+++ b/spec/frontend/groups/components/item_stats_spec.js
@@ -1,4 +1,4 @@
-import { shallowMount } from '@vue/test-utils';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import ItemStats from '~/groups/components/item_stats.vue';
import ItemStatsValue from '~/groups/components/item_stats_value.vue';
@@ -12,7 +12,7 @@ describe('ItemStats', () => {
};
const createComponent = (props = {}) => {
- wrapper = shallowMount(ItemStats, {
+ wrapper = shallowMountExtended(ItemStats, {
propsData: { ...defaultProps, ...props },
});
};
@@ -46,5 +46,31 @@ describe('ItemStats', () => {
expect(findItemStatsValue().props('cssClass')).toBe('project-stars');
expect(wrapper.find('.last-updated').exists()).toBe(true);
});
+
+ describe('group specific rendering', () => {
+ describe.each`
+ provided | state | data
+ ${true} | ${'displays'} | ${null}
+ ${false} | ${'does not display'} | ${{ subgroupCount: undefined, projectCount: undefined }}
+ `('when provided = $provided', ({ provided, state, data }) => {
+ beforeEach(() => {
+ const item = {
+ ...mockParentGroupItem,
+ ...data,
+ type: ITEM_TYPE.GROUP,
+ };
+
+ createComponent({ item });
+ });
+
+ it.each`
+ entity | testId
+ ${'subgroups'} | ${'subgroups-count'}
+ ${'projects'} | ${'projects-count'}
+ `(`${state} $entity count`, ({ testId }) => {
+ expect(wrapper.findByTestId(testId).exists()).toBe(provided);
+ });
+ });
+ });
});
});
diff --git a/spec/frontend/header_search/components/app_spec.js b/spec/frontend/header_search/components/app_spec.js
new file mode 100644
index 00000000000..2cbcb73ce5b
--- /dev/null
+++ b/spec/frontend/header_search/components/app_spec.js
@@ -0,0 +1,159 @@
+import { GlSearchBoxByType } from '@gitlab/ui';
+import Vue from 'vue';
+import Vuex from 'vuex';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import HeaderSearchApp from '~/header_search/components/app.vue';
+import HeaderSearchDefaultItems from '~/header_search/components/header_search_default_items.vue';
+import HeaderSearchScopedItems from '~/header_search/components/header_search_scoped_items.vue';
+import { ENTER_KEY, ESC_KEY } from '~/lib/utils/keys';
+import { visitUrl } from '~/lib/utils/url_utility';
+import { MOCK_SEARCH, MOCK_SEARCH_QUERY, MOCK_USERNAME } from '../mock_data';
+
+Vue.use(Vuex);
+
+jest.mock('~/lib/utils/url_utility', () => ({
+ visitUrl: jest.fn(),
+}));
+
+describe('HeaderSearchApp', () => {
+ let wrapper;
+
+ const actionSpies = {
+ setSearch: jest.fn(),
+ };
+
+ const createComponent = (initialState) => {
+ const store = new Vuex.Store({
+ state: {
+ ...initialState,
+ },
+ actions: actionSpies,
+ getters: {
+ searchQuery: () => MOCK_SEARCH_QUERY,
+ },
+ });
+
+ wrapper = shallowMountExtended(HeaderSearchApp, {
+ store,
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ const findHeaderSearchInput = () => wrapper.findComponent(GlSearchBoxByType);
+ const findHeaderSearchDropdown = () => wrapper.findByTestId('header-search-dropdown-menu');
+ const findHeaderSearchDefaultItems = () => wrapper.findComponent(HeaderSearchDefaultItems);
+ const findHeaderSearchScopedItems = () => wrapper.findComponent(HeaderSearchScopedItems);
+
+ describe('template', () => {
+ it('always renders Header Search Input', () => {
+ createComponent();
+ expect(findHeaderSearchInput().exists()).toBe(true);
+ });
+
+ describe.each`
+ showDropdown | username | showSearchDropdown
+ ${false} | ${null} | ${false}
+ ${false} | ${MOCK_USERNAME} | ${false}
+ ${true} | ${null} | ${false}
+ ${true} | ${MOCK_USERNAME} | ${true}
+ `('Header Search Dropdown', ({ showDropdown, username, showSearchDropdown }) => {
+ describe(`when showDropdown is ${showDropdown} and current_username is ${username}`, () => {
+ beforeEach(() => {
+ createComponent();
+ window.gon.current_username = username;
+ wrapper.setData({ showDropdown });
+ });
+
+ it(`should${showSearchDropdown ? '' : ' not'} render`, () => {
+ expect(findHeaderSearchDropdown().exists()).toBe(showSearchDropdown);
+ });
+ });
+ });
+
+ describe.each`
+ search | showDefault | showScoped
+ ${null} | ${true} | ${false}
+ ${''} | ${true} | ${false}
+ ${MOCK_SEARCH} | ${false} | ${true}
+ `('Header Search Dropdown Items', ({ search, showDefault, showScoped }) => {
+ describe(`when search is ${search}`, () => {
+ beforeEach(() => {
+ createComponent({ search });
+ window.gon.current_username = MOCK_USERNAME;
+ wrapper.setData({ showDropdown: true });
+ });
+
+ it(`should${showDefault ? '' : ' not'} render the Default Dropdown Items`, () => {
+ expect(findHeaderSearchDefaultItems().exists()).toBe(showDefault);
+ });
+
+ it(`should${showScoped ? '' : ' not'} render the Scoped Dropdown Items`, () => {
+ expect(findHeaderSearchScopedItems().exists()).toBe(showScoped);
+ });
+ });
+ });
+ });
+
+ describe('events', () => {
+ beforeEach(() => {
+ createComponent();
+ window.gon.current_username = MOCK_USERNAME;
+ });
+
+ describe('Header Search Input', () => {
+ describe('when dropdown is closed', () => {
+ it('onFocus opens dropdown', async () => {
+ expect(findHeaderSearchDropdown().exists()).toBe(false);
+ findHeaderSearchInput().vm.$emit('focus');
+
+ await wrapper.vm.$nextTick();
+
+ expect(findHeaderSearchDropdown().exists()).toBe(true);
+ });
+
+ it('onClick opens dropdown', async () => {
+ expect(findHeaderSearchDropdown().exists()).toBe(false);
+ findHeaderSearchInput().vm.$emit('click');
+
+ await wrapper.vm.$nextTick();
+
+ expect(findHeaderSearchDropdown().exists()).toBe(true);
+ });
+ });
+
+ describe('when dropdown is opened', () => {
+ beforeEach(() => {
+ wrapper.setData({ showDropdown: true });
+ });
+
+ it('onKey-Escape closes dropdown', async () => {
+ expect(findHeaderSearchDropdown().exists()).toBe(true);
+ findHeaderSearchInput().vm.$emit('keydown', new KeyboardEvent({ key: ESC_KEY }));
+
+ await wrapper.vm.$nextTick();
+
+ expect(findHeaderSearchDropdown().exists()).toBe(false);
+ });
+ });
+
+ it('calls setSearch when search input event is fired', async () => {
+ findHeaderSearchInput().vm.$emit('input', MOCK_SEARCH);
+
+ await wrapper.vm.$nextTick();
+
+ expect(actionSpies.setSearch).toHaveBeenCalledWith(expect.any(Object), MOCK_SEARCH);
+ });
+
+ it('submits a search onKey-Enter', async () => {
+ findHeaderSearchInput().vm.$emit('keydown', new KeyboardEvent({ key: ENTER_KEY }));
+
+ await wrapper.vm.$nextTick();
+
+ expect(visitUrl).toHaveBeenCalledWith(MOCK_SEARCH_QUERY);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/header_search/components/header_search_default_items_spec.js b/spec/frontend/header_search/components/header_search_default_items_spec.js
new file mode 100644
index 00000000000..ce083d0df72
--- /dev/null
+++ b/spec/frontend/header_search/components/header_search_default_items_spec.js
@@ -0,0 +1,81 @@
+import { GlDropdownItem, GlDropdownSectionHeader } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
+import Vuex from 'vuex';
+import HeaderSearchDefaultItems from '~/header_search/components/header_search_default_items.vue';
+import { MOCK_SEARCH_CONTEXT, MOCK_DEFAULT_SEARCH_OPTIONS } from '../mock_data';
+
+Vue.use(Vuex);
+
+describe('HeaderSearchDefaultItems', () => {
+ let wrapper;
+
+ const createComponent = (initialState) => {
+ const store = new Vuex.Store({
+ state: {
+ searchContext: MOCK_SEARCH_CONTEXT,
+ ...initialState,
+ },
+ getters: {
+ defaultSearchOptions: () => MOCK_DEFAULT_SEARCH_OPTIONS,
+ },
+ });
+
+ wrapper = shallowMount(HeaderSearchDefaultItems, {
+ store,
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ const findDropdownHeader = () => wrapper.findComponent(GlDropdownSectionHeader);
+ const findDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
+ const findDropdownItemTitles = () => findDropdownItems().wrappers.map((w) => w.text());
+ const findDropdownItemLinks = () => findDropdownItems().wrappers.map((w) => w.attributes('href'));
+
+ describe('template', () => {
+ describe('Dropdown items', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('renders item for each option in defaultSearchOptions', () => {
+ expect(findDropdownItems()).toHaveLength(MOCK_DEFAULT_SEARCH_OPTIONS.length);
+ });
+
+ it('renders titles correctly', () => {
+ const expectedTitles = MOCK_DEFAULT_SEARCH_OPTIONS.map((o) => o.title);
+ expect(findDropdownItemTitles()).toStrictEqual(expectedTitles);
+ });
+
+ it('renders links correctly', () => {
+ const expectedLinks = MOCK_DEFAULT_SEARCH_OPTIONS.map((o) => o.url);
+ expect(findDropdownItemLinks()).toStrictEqual(expectedLinks);
+ });
+ });
+
+ describe.each`
+ group | project | dropdownTitle
+ ${null} | ${null} | ${'All GitLab'}
+ ${{ name: 'Test Group' }} | ${null} | ${'Test Group'}
+ ${{ name: 'Test Group' }} | ${{ name: 'Test Project' }} | ${'Test Project'}
+ `('Dropdown Header', ({ group, project, dropdownTitle }) => {
+ describe(`when group is ${group?.name} and project is ${project?.name}`, () => {
+ beforeEach(() => {
+ createComponent({
+ searchContext: {
+ group,
+ project,
+ },
+ });
+ });
+
+ it(`should render as ${dropdownTitle}`, () => {
+ expect(findDropdownHeader().text()).toBe(dropdownTitle);
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/header_search/components/header_search_scoped_items_spec.js b/spec/frontend/header_search/components/header_search_scoped_items_spec.js
new file mode 100644
index 00000000000..f0e5e182ec4
--- /dev/null
+++ b/spec/frontend/header_search/components/header_search_scoped_items_spec.js
@@ -0,0 +1,61 @@
+import { GlDropdownItem } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
+import Vuex from 'vuex';
+import { trimText } from 'helpers/text_helper';
+import HeaderSearchScopedItems from '~/header_search/components/header_search_scoped_items.vue';
+import { MOCK_SEARCH, MOCK_SCOPED_SEARCH_OPTIONS } from '../mock_data';
+
+Vue.use(Vuex);
+
+describe('HeaderSearchScopedItems', () => {
+ let wrapper;
+
+ const createComponent = (initialState) => {
+ const store = new Vuex.Store({
+ state: {
+ search: MOCK_SEARCH,
+ ...initialState,
+ },
+ getters: {
+ scopedSearchOptions: () => MOCK_SCOPED_SEARCH_OPTIONS,
+ },
+ });
+
+ wrapper = shallowMount(HeaderSearchScopedItems, {
+ store,
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ const findDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
+ const findDropdownItemTitles = () => findDropdownItems().wrappers.map((w) => trimText(w.text()));
+ const findDropdownItemLinks = () => findDropdownItems().wrappers.map((w) => w.attributes('href'));
+
+ describe('template', () => {
+ describe('Dropdown items', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('renders item for each option in scopedSearchOptions', () => {
+ expect(findDropdownItems()).toHaveLength(MOCK_SCOPED_SEARCH_OPTIONS.length);
+ });
+
+ it('renders titles correctly', () => {
+ const expectedTitles = MOCK_SCOPED_SEARCH_OPTIONS.map((o) =>
+ trimText(`"${MOCK_SEARCH}" ${o.description} ${o.scope || ''}`),
+ );
+ expect(findDropdownItemTitles()).toStrictEqual(expectedTitles);
+ });
+
+ it('renders links correctly', () => {
+ const expectedLinks = MOCK_SCOPED_SEARCH_OPTIONS.map((o) => o.url);
+ expect(findDropdownItemLinks()).toStrictEqual(expectedLinks);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/header_search/mock_data.js b/spec/frontend/header_search/mock_data.js
new file mode 100644
index 00000000000..5963ad9c279
--- /dev/null
+++ b/spec/frontend/header_search/mock_data.js
@@ -0,0 +1,83 @@
+import {
+ MSG_ISSUES_ASSIGNED_TO_ME,
+ MSG_ISSUES_IVE_CREATED,
+ MSG_MR_ASSIGNED_TO_ME,
+ MSG_MR_IM_REVIEWER,
+ MSG_MR_IVE_CREATED,
+ MSG_IN_PROJECT,
+ MSG_IN_GROUP,
+ MSG_IN_ALL_GITLAB,
+} from '~/header_search/constants';
+
+export const MOCK_USERNAME = 'anyone';
+
+export const MOCK_SEARCH_PATH = '/search';
+
+export const MOCK_ISSUE_PATH = '/dashboard/issues';
+
+export const MOCK_MR_PATH = '/dashboard/merge_requests';
+
+export const MOCK_ALL_PATH = '/';
+
+export const MOCK_PROJECT = {
+ id: 123,
+ name: 'MockProject',
+ path: '/mock-project',
+};
+
+export const MOCK_GROUP = {
+ id: 321,
+ name: 'MockGroup',
+ path: '/mock-group',
+};
+
+export const MOCK_SEARCH_QUERY = 'http://gitlab.com/search?search=test';
+
+export const MOCK_SEARCH = 'test';
+
+export const MOCK_SEARCH_CONTEXT = {
+ project: null,
+ project_metadata: {},
+ group: null,
+ group_metadata: {},
+};
+
+export const MOCK_DEFAULT_SEARCH_OPTIONS = [
+ {
+ title: MSG_ISSUES_ASSIGNED_TO_ME,
+ url: `${MOCK_ISSUE_PATH}/?assignee_username=${MOCK_USERNAME}`,
+ },
+ {
+ title: MSG_ISSUES_IVE_CREATED,
+ url: `${MOCK_ISSUE_PATH}/?author_username=${MOCK_USERNAME}`,
+ },
+ {
+ title: MSG_MR_ASSIGNED_TO_ME,
+ url: `${MOCK_MR_PATH}/?assignee_username=${MOCK_USERNAME}`,
+ },
+ {
+ title: MSG_MR_IM_REVIEWER,
+ url: `${MOCK_MR_PATH}/?reviewer_username=${MOCK_USERNAME}`,
+ },
+ {
+ title: MSG_MR_IVE_CREATED,
+ url: `${MOCK_MR_PATH}/?author_username=${MOCK_USERNAME}`,
+ },
+];
+
+export const MOCK_SCOPED_SEARCH_OPTIONS = [
+ {
+ scope: MOCK_PROJECT.name,
+ description: MSG_IN_PROJECT,
+ url: MOCK_PROJECT.path,
+ },
+ {
+ scope: MOCK_GROUP.name,
+ description: MSG_IN_GROUP,
+ url: MOCK_GROUP.path,
+ },
+ {
+ description: MSG_IN_ALL_GITLAB,
+ url: MOCK_ALL_PATH,
+ },
+];
diff --git a/spec/frontend/header_search/store/actions_spec.js b/spec/frontend/header_search/store/actions_spec.js
new file mode 100644
index 00000000000..4530df0d91c
--- /dev/null
+++ b/spec/frontend/header_search/store/actions_spec.js
@@ -0,0 +1,28 @@
+import testAction from 'helpers/vuex_action_helper';
+import * as actions from '~/header_search/store/actions';
+import * as types from '~/header_search/store/mutation_types';
+import createState from '~/header_search/store/state';
+import { MOCK_SEARCH } from '../mock_data';
+
+describe('Header Search Store Actions', () => {
+ let state;
+
+ beforeEach(() => {
+ state = createState({});
+ });
+
+ afterEach(() => {
+ state = null;
+ });
+
+ describe('setSearch', () => {
+ it('calls the SET_SEARCH mutation', () => {
+ return testAction({
+ action: actions.setSearch,
+ payload: MOCK_SEARCH,
+ state,
+ expectedMutations: [{ type: types.SET_SEARCH, payload: MOCK_SEARCH }],
+ });
+ });
+ });
+});
diff --git a/spec/frontend/header_search/store/getters_spec.js b/spec/frontend/header_search/store/getters_spec.js
new file mode 100644
index 00000000000..2ad0a082f6a
--- /dev/null
+++ b/spec/frontend/header_search/store/getters_spec.js
@@ -0,0 +1,211 @@
+import * as getters from '~/header_search/store/getters';
+import initState from '~/header_search/store/state';
+import {
+ MOCK_USERNAME,
+ MOCK_SEARCH_PATH,
+ MOCK_ISSUE_PATH,
+ MOCK_MR_PATH,
+ MOCK_SEARCH_CONTEXT,
+ MOCK_DEFAULT_SEARCH_OPTIONS,
+ MOCK_SCOPED_SEARCH_OPTIONS,
+ MOCK_PROJECT,
+ MOCK_GROUP,
+ MOCK_ALL_PATH,
+ MOCK_SEARCH,
+} from '../mock_data';
+
+describe('Header Search Store Getters', () => {
+ let state;
+
+ const createState = (initialState) => {
+ state = initState({
+ searchPath: MOCK_SEARCH_PATH,
+ issuesPath: MOCK_ISSUE_PATH,
+ mrPath: MOCK_MR_PATH,
+ searchContext: MOCK_SEARCH_CONTEXT,
+ ...initialState,
+ });
+ };
+
+ afterEach(() => {
+ state = null;
+ });
+
+ describe.each`
+ group | project | expectedPath
+ ${null} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=undefined&group_id=undefined&scope=issues`}
+ ${MOCK_GROUP} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=undefined&group_id=${MOCK_GROUP.id}&scope=issues`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=${MOCK_PROJECT.id}&group_id=${MOCK_GROUP.id}&scope=issues`}
+ `('searchQuery', ({ group, project, expectedPath }) => {
+ describe(`when group is ${group?.name} and project is ${project?.name}`, () => {
+ beforeEach(() => {
+ createState({
+ searchContext: {
+ group,
+ project,
+ scope: 'issues',
+ },
+ });
+ state.search = MOCK_SEARCH;
+ });
+
+ it(`should return ${expectedPath}`, () => {
+ expect(getters.searchQuery(state)).toBe(expectedPath);
+ });
+ });
+ });
+
+ describe.each`
+ group | group_metadata | project | project_metadata | expectedPath
+ ${null} | ${null} | ${null} | ${null} | ${MOCK_ISSUE_PATH}
+ ${{ name: 'Test Group' }} | ${{ issues_path: 'group/path' }} | ${null} | ${null} | ${'group/path'}
+ ${{ name: 'Test Group' }} | ${{ issues_path: 'group/path' }} | ${{ name: 'Test Project' }} | ${{ issues_path: 'project/path' }} | ${'project/path'}
+ `('scopedIssuesPath', ({ group, group_metadata, project, project_metadata, expectedPath }) => {
+ describe(`when group is ${group?.name} and project is ${project?.name}`, () => {
+ beforeEach(() => {
+ createState({
+ searchContext: {
+ group,
+ group_metadata,
+ project,
+ project_metadata,
+ },
+ });
+ });
+
+ it(`should return ${expectedPath}`, () => {
+ expect(getters.scopedIssuesPath(state)).toBe(expectedPath);
+ });
+ });
+ });
+
+ describe.each`
+ group | group_metadata | project | project_metadata | expectedPath
+ ${null} | ${null} | ${null} | ${null} | ${MOCK_MR_PATH}
+ ${{ name: 'Test Group' }} | ${{ mr_path: 'group/path' }} | ${null} | ${null} | ${'group/path'}
+ ${{ name: 'Test Group' }} | ${{ mr_path: 'group/path' }} | ${{ name: 'Test Project' }} | ${{ mr_path: 'project/path' }} | ${'project/path'}
+ `('scopedMRPath', ({ group, group_metadata, project, project_metadata, expectedPath }) => {
+ describe(`when group is ${group?.name} and project is ${project?.name}`, () => {
+ beforeEach(() => {
+ createState({
+ searchContext: {
+ group,
+ group_metadata,
+ project,
+ project_metadata,
+ },
+ });
+ });
+
+ it(`should return ${expectedPath}`, () => {
+ expect(getters.scopedMRPath(state)).toBe(expectedPath);
+ });
+ });
+ });
+
+ describe.each`
+ group | project | expectedPath
+ ${null} | ${null} | ${null}
+ ${MOCK_GROUP} | ${null} | ${null}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=${MOCK_PROJECT.id}&group_id=${MOCK_GROUP.id}&scope=issues`}
+ `('projectUrl', ({ group, project, expectedPath }) => {
+ describe(`when group is ${group?.name} and project is ${project?.name}`, () => {
+ beforeEach(() => {
+ createState({
+ searchContext: {
+ group,
+ project,
+ scope: 'issues',
+ },
+ });
+ state.search = MOCK_SEARCH;
+ });
+
+ it(`should return ${expectedPath}`, () => {
+ expect(getters.projectUrl(state)).toBe(expectedPath);
+ });
+ });
+ });
+
+ describe.each`
+ group | project | expectedPath
+ ${null} | ${null} | ${null}
+ ${MOCK_GROUP} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&group_id=${MOCK_GROUP.id}&scope=issues`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&group_id=${MOCK_GROUP.id}&scope=issues`}
+ `('groupUrl', ({ group, project, expectedPath }) => {
+ describe(`when group is ${group?.name} and project is ${project?.name}`, () => {
+ beforeEach(() => {
+ createState({
+ searchContext: {
+ group,
+ project,
+ scope: 'issues',
+ },
+ });
+ state.search = MOCK_SEARCH;
+ });
+
+ it(`should return ${expectedPath}`, () => {
+ expect(getters.groupUrl(state)).toBe(expectedPath);
+ });
+ });
+ });
+
+ describe('allUrl', () => {
+ const expectedPath = `${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&scope=issues`;
+
+ beforeEach(() => {
+ createState({
+ searchContext: {
+ scope: 'issues',
+ },
+ });
+ state.search = MOCK_SEARCH;
+ });
+
+ it(`should return ${expectedPath}`, () => {
+ expect(getters.allUrl(state)).toBe(expectedPath);
+ });
+ });
+
+ describe('defaultSearchOptions', () => {
+ const mockGetters = {
+ scopedIssuesPath: MOCK_ISSUE_PATH,
+ scopedMRPath: MOCK_MR_PATH,
+ };
+
+ beforeEach(() => {
+ createState();
+ window.gon.current_username = MOCK_USERNAME;
+ });
+
+ it('returns the correct array', () => {
+ expect(getters.defaultSearchOptions(state, mockGetters)).toStrictEqual(
+ MOCK_DEFAULT_SEARCH_OPTIONS,
+ );
+ });
+ });
+
+ describe('scopedSearchOptions', () => {
+ const mockGetters = {
+ projectUrl: MOCK_PROJECT.path,
+ groupUrl: MOCK_GROUP.path,
+ allUrl: MOCK_ALL_PATH,
+ };
+
+ beforeEach(() => {
+ createState({
+ searchContext: {
+ project: MOCK_PROJECT,
+ group: MOCK_GROUP,
+ },
+ });
+ });
+
+ it('returns the correct array', () => {
+ expect(getters.scopedSearchOptions(state, mockGetters)).toStrictEqual(
+ MOCK_SCOPED_SEARCH_OPTIONS,
+ );
+ });
+ });
+});
diff --git a/spec/frontend/header_search/store/mutations_spec.js b/spec/frontend/header_search/store/mutations_spec.js
new file mode 100644
index 00000000000..8196c06099d
--- /dev/null
+++ b/spec/frontend/header_search/store/mutations_spec.js
@@ -0,0 +1,20 @@
+import * as types from '~/header_search/store/mutation_types';
+import mutations from '~/header_search/store/mutations';
+import createState from '~/header_search/store/state';
+import { MOCK_SEARCH } from '../mock_data';
+
+describe('Header Search Store Mutations', () => {
+ let state;
+
+ beforeEach(() => {
+ state = createState({});
+ });
+
+ describe('SET_SEARCH', () => {
+ it('sets search to value', () => {
+ mutations[types.SET_SEARCH](state, MOCK_SEARCH);
+
+ expect(state.search).toBe(MOCK_SEARCH);
+ });
+ });
+});
diff --git a/spec/frontend/header_spec.js b/spec/frontend/header_spec.js
index 4ca6d7259bd..0d43accb7e5 100644
--- a/spec/frontend/header_spec.js
+++ b/spec/frontend/header_spec.js
@@ -59,8 +59,8 @@ describe('Header', () => {
beforeEach(() => {
setFixtures(`
<li class="js-nav-user-dropdown">
- <a class="js-buy-pipeline-minutes-link" data-track-event="click_buy_ci_minutes" data-track-label="free" data-track-property="user_dropdown">Buy Pipeline minutes</a>
- <a class="js-upgrade-plan-link" data-track-event="click_upgrade_link" data-track-label="free" data-track-property="user_dropdown">Upgrade</a>
+ <a class="js-buy-pipeline-minutes-link" data-track-action="click_buy_ci_minutes" data-track-label="free" data-track-property="user_dropdown">Buy Pipeline minutes</a>
+ <a class="js-upgrade-plan-link" data-track-action="click_upgrade_link" data-track-label="free" data-track-property="user_dropdown">Upgrade</a>
</li>`);
trackingSpy = mockTracking('_category_', $('.js-nav-user-dropdown').element, jest.spyOn);
diff --git a/spec/frontend/ide/components/repo_editor_spec.js b/spec/frontend/ide/components/repo_editor_spec.js
index 47bcfb59a5f..c2212eea849 100644
--- a/spec/frontend/ide/components/repo_editor_spec.js
+++ b/spec/frontend/ide/components/repo_editor_spec.js
@@ -8,6 +8,7 @@ import waitForPromises from 'helpers/wait_for_promises';
import waitUsingRealTimer from 'helpers/wait_using_real_timer';
import { exampleConfigs, exampleFiles } from 'jest/ide/lib/editorconfig/mock_data';
import { EDITOR_CODE_INSTANCE_FN, EDITOR_DIFF_INSTANCE_FN } from '~/editor/constants';
+import { EditorMarkdownExtension } from '~/editor/extensions/source_editor_markdown_ext';
import { EditorWebIdeExtension } from '~/editor/extensions/source_editor_webide_ext';
import SourceEditor from '~/editor/source_editor';
import RepoEditor from '~/ide/components/repo_editor.vue';
@@ -25,6 +26,7 @@ import ContentViewer from '~/vue_shared/components/content_viewer/content_viewer
import { file } from '../helpers';
const PREVIEW_MARKDOWN_PATH = '/foo/bar/preview_markdown';
+const CURRENT_PROJECT_ID = 'gitlab-org/gitlab';
const defaultFileProps = {
...file('file.txt'),
@@ -63,7 +65,7 @@ const prepareStore = (state, activeFile) => {
const localState = {
openFiles: [activeFile],
projects: {
- 'gitlab-org/gitlab': {
+ [CURRENT_PROJECT_ID]: {
branches: {
main: {
name: 'main',
@@ -74,7 +76,7 @@ const prepareStore = (state, activeFile) => {
},
},
},
- currentProjectId: 'gitlab-org/gitlab',
+ currentProjectId: CURRENT_PROJECT_ID,
currentBranchId: 'main',
entries: {
[activeFile.path]: activeFile,
@@ -98,6 +100,7 @@ describe('RepoEditor', () => {
let createInstanceSpy;
let createDiffInstanceSpy;
let createModelSpy;
+ let applyExtensionSpy;
const waitForEditorSetup = () =>
new Promise((resolve) => {
@@ -124,11 +127,28 @@ describe('RepoEditor', () => {
const findEditor = () => wrapper.find('[data-testid="editor-container"]');
const findTabs = () => wrapper.findAll('.ide-mode-tabs .nav-links li');
const findPreviewTab = () => wrapper.find('[data-testid="preview-tab"]');
+ const expectEditorMarkdownExtension = (shouldHaveExtension) => {
+ if (shouldHaveExtension) {
+ expect(applyExtensionSpy).toHaveBeenCalledWith(
+ wrapper.vm.editor,
+ expect.any(EditorMarkdownExtension),
+ );
+ // TODO: spying on extensions causes Jest to blow up, so we have to assert on
+ // the public property the extension adds, as opposed to the args passed to the ctor
+ expect(wrapper.vm.editor.previewMarkdownPath).toBe(PREVIEW_MARKDOWN_PATH);
+ } else {
+ expect(applyExtensionSpy).not.toHaveBeenCalledWith(
+ wrapper.vm.editor,
+ expect.any(EditorMarkdownExtension),
+ );
+ }
+ };
beforeEach(() => {
createInstanceSpy = jest.spyOn(SourceEditor.prototype, EDITOR_CODE_INSTANCE_FN);
createDiffInstanceSpy = jest.spyOn(SourceEditor.prototype, EDITOR_DIFF_INSTANCE_FN);
createModelSpy = jest.spyOn(monacoEditor, 'createModel');
+ applyExtensionSpy = jest.spyOn(SourceEditor, 'instanceApplyExtension');
jest.spyOn(service, 'getFileData').mockResolvedValue();
jest.spyOn(service, 'getRawFileData').mockResolvedValue();
});
@@ -280,13 +300,8 @@ describe('RepoEditor', () => {
'$prefix install markdown extension for $activeFile.name in $viewer viewer',
async ({ activeFile, viewer, shouldHaveMarkdownExtension } = {}) => {
await createComponent({ state: { viewer }, activeFile });
- if (shouldHaveMarkdownExtension) {
- expect(vm.editor.previewMarkdownPath).toBe(PREVIEW_MARKDOWN_PATH);
- expect(vm.editor.togglePreview).toBeDefined();
- } else {
- expect(vm.editor.previewMarkdownPath).toBeUndefined();
- expect(vm.editor.togglePreview).toBeUndefined();
- }
+
+ expectEditorMarkdownExtension(shouldHaveMarkdownExtension);
},
);
});
diff --git a/spec/frontend/ide/services/terminals_spec.js b/spec/frontend/ide/services/terminals_spec.js
new file mode 100644
index 00000000000..788fdb6471c
--- /dev/null
+++ b/spec/frontend/ide/services/terminals_spec.js
@@ -0,0 +1,51 @@
+import MockAdapter from 'axios-mock-adapter';
+import * as terminalService from '~/ide/services/terminals';
+import axios from '~/lib/utils/axios_utils';
+
+const TEST_PROJECT_PATH = 'lorem/ipsum/dolar';
+const TEST_BRANCH = 'ref';
+
+describe('~/ide/services/terminals', () => {
+ let axiosSpy;
+ let mock;
+ const prevRelativeUrlRoot = gon.relative_url_root;
+
+ beforeEach(() => {
+ axiosSpy = jest.fn().mockReturnValue([200, {}]);
+
+ mock = new MockAdapter(axios);
+ mock.onPost(/.*/).reply((...args) => axiosSpy(...args));
+ });
+
+ afterEach(() => {
+ gon.relative_url_root = prevRelativeUrlRoot;
+ mock.restore();
+ });
+
+ it.each`
+ method | relativeUrlRoot | url
+ ${'checkConfig'} | ${''} | ${`/${TEST_PROJECT_PATH}/ide_terminals/check_config`}
+ ${'checkConfig'} | ${'/'} | ${`/${TEST_PROJECT_PATH}/ide_terminals/check_config`}
+ ${'checkConfig'} | ${'/gitlabbin'} | ${`/gitlabbin/${TEST_PROJECT_PATH}/ide_terminals/check_config`}
+ ${'create'} | ${''} | ${`/${TEST_PROJECT_PATH}/ide_terminals`}
+ ${'create'} | ${'/'} | ${`/${TEST_PROJECT_PATH}/ide_terminals`}
+ ${'create'} | ${'/gitlabbin'} | ${`/gitlabbin/${TEST_PROJECT_PATH}/ide_terminals`}
+ `(
+ 'when $method called, posts request to $url (relative_url_root=$relativeUrlRoot)',
+ async ({ method, url, relativeUrlRoot }) => {
+ gon.relative_url_root = relativeUrlRoot;
+
+ await terminalService[method](TEST_PROJECT_PATH, TEST_BRANCH);
+
+ expect(axiosSpy).toHaveBeenCalledWith(
+ expect.objectContaining({
+ data: JSON.stringify({
+ branch: TEST_BRANCH,
+ format: 'json',
+ }),
+ url,
+ }),
+ );
+ },
+ );
+});
diff --git a/spec/frontend/ide/utils_spec.js b/spec/frontend/ide/utils_spec.js
index 00733615f81..2f8447af518 100644
--- a/spec/frontend/ide/utils_spec.js
+++ b/spec/frontend/ide/utils_spec.js
@@ -86,6 +86,14 @@ describe('WebIDE utils', () => {
expect(isTextFile({ name: 'abc.dat', content: '' })).toBe(true);
expect(isTextFile({ name: 'abc.dat', content: ' ' })).toBe(true);
});
+
+ it('returns true if there is a `binary` property already set on the file object', () => {
+ expect(isTextFile({ name: 'abc.txt', content: '' })).toBe(true);
+ expect(isTextFile({ name: 'abc.txt', content: '', binary: true })).toBe(false);
+
+ expect(isTextFile({ name: 'abc.tex', content: 'éêė' })).toBe(false);
+ expect(isTextFile({ name: 'abc.tex', content: 'éêė', binary: false })).toBe(true);
+ });
});
describe('trimPathComponents', () => {
diff --git a/spec/frontend/import_entities/import_groups/components/import_actions_cell_spec.js b/spec/frontend/import_entities/import_groups/components/import_actions_cell_spec.js
new file mode 100644
index 00000000000..60f0780fdb3
--- /dev/null
+++ b/spec/frontend/import_entities/import_groups/components/import_actions_cell_spec.js
@@ -0,0 +1,90 @@
+import { GlButton, GlIcon } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import { STATUSES } from '~/import_entities/constants';
+import ImportActionsCell from '~/import_entities/import_groups/components/import_actions_cell.vue';
+import { generateFakeEntry } from '../graphql/fixtures';
+
+describe('import actions cell', () => {
+ let wrapper;
+
+ const createComponent = (props) => {
+ wrapper = shallowMount(ImportActionsCell, {
+ propsData: {
+ groupPathRegex: /^[a-zA-Z]+$/,
+ ...props,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('when import status is NONE', () => {
+ beforeEach(() => {
+ const group = generateFakeEntry({ id: 1, status: STATUSES.NONE });
+ createComponent({ group });
+ });
+
+ it('renders import button', () => {
+ const button = wrapper.findComponent(GlButton);
+ expect(button.exists()).toBe(true);
+ expect(button.text()).toBe('Import');
+ });
+
+ it('does not render icon with a hint', () => {
+ expect(wrapper.findComponent(GlIcon).exists()).toBe(false);
+ });
+ });
+
+ describe('when import status is FINISHED', () => {
+ beforeEach(() => {
+ const group = generateFakeEntry({ id: 1, status: STATUSES.FINISHED });
+ createComponent({ group });
+ });
+
+ it('renders re-import button', () => {
+ const button = wrapper.findComponent(GlButton);
+ expect(button.exists()).toBe(true);
+ expect(button.text()).toBe('Re-import');
+ });
+
+ it('renders icon with a hint', () => {
+ const icon = wrapper.findComponent(GlIcon);
+ expect(icon.exists()).toBe(true);
+ expect(icon.attributes().title).toBe(
+ 'Re-import creates a new group. It does not sync with the existing group.',
+ );
+ });
+ });
+
+ it('does not render import button when group import is in progress', () => {
+ const group = generateFakeEntry({ id: 1, status: STATUSES.STARTED });
+ createComponent({ group });
+
+ const button = wrapper.findComponent(GlButton);
+ expect(button.exists()).toBe(false);
+ });
+
+ it('renders import button as disabled when there are validation errors', () => {
+ const group = generateFakeEntry({
+ id: 1,
+ status: STATUSES.NONE,
+ validation_errors: [{ field: 'new_name', message: 'something ' }],
+ });
+ createComponent({ group });
+
+ const button = wrapper.findComponent(GlButton);
+ expect(button.props().disabled).toBe(true);
+ });
+
+ it('emits import-group event when import button is clicked', () => {
+ const group = generateFakeEntry({ id: 1, status: STATUSES.NONE });
+ createComponent({ group });
+
+ const button = wrapper.findComponent(GlButton);
+ button.vm.$emit('click');
+
+ expect(wrapper.emitted('import-group')).toHaveLength(1);
+ });
+});
diff --git a/spec/frontend/import_entities/import_groups/components/import_source_cell_spec.js b/spec/frontend/import_entities/import_groups/components/import_source_cell_spec.js
new file mode 100644
index 00000000000..2a56efd1cbb
--- /dev/null
+++ b/spec/frontend/import_entities/import_groups/components/import_source_cell_spec.js
@@ -0,0 +1,59 @@
+import { GlLink, GlSprintf } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import { STATUSES } from '~/import_entities/constants';
+import ImportSourceCell from '~/import_entities/import_groups/components/import_source_cell.vue';
+import { generateFakeEntry } from '../graphql/fixtures';
+
+describe('import source cell', () => {
+ let wrapper;
+ let group;
+
+ const createComponent = (props) => {
+ wrapper = shallowMount(ImportSourceCell, {
+ propsData: {
+ ...props,
+ },
+ stubs: { GlSprintf },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('when group status is NONE', () => {
+ beforeEach(() => {
+ group = generateFakeEntry({ id: 1, status: STATUSES.NONE });
+ createComponent({ group });
+ });
+
+ it('renders link to a group', () => {
+ const link = wrapper.findComponent(GlLink);
+ expect(link.attributes().href).toBe(group.web_url);
+ expect(link.text()).toContain(group.full_path);
+ });
+
+ it('does not render last imported line', () => {
+ expect(wrapper.text()).not.toContain('Last imported to');
+ });
+ });
+
+ describe('when group status is FINISHED', () => {
+ beforeEach(() => {
+ group = generateFakeEntry({ id: 1, status: STATUSES.FINISHED });
+ createComponent({ group });
+ });
+
+ it('renders link to a group', () => {
+ const link = wrapper.findComponent(GlLink);
+ expect(link.attributes().href).toBe(group.web_url);
+ expect(link.text()).toContain(group.full_path);
+ });
+
+ it('renders last imported line', () => {
+ expect(wrapper.text()).toMatchInterpolatedText(
+ 'fake_group_1 Last imported to root/last-group1',
+ );
+ });
+ });
+});
diff --git a/spec/frontend/import_entities/import_groups/components/import_table_spec.js b/spec/frontend/import_entities/import_groups/components/import_table_spec.js
index bbd8463e685..f43e545e049 100644
--- a/spec/frontend/import_entities/import_groups/components/import_table_spec.js
+++ b/spec/frontend/import_entities/import_groups/components/import_table_spec.js
@@ -15,6 +15,7 @@ import stubChildren from 'helpers/stub_children';
import { stubComponent } from 'helpers/stub_component';
import waitForPromises from 'helpers/wait_for_promises';
import { STATUSES } from '~/import_entities/constants';
+import ImportActionsCell from '~/import_entities/import_groups/components/import_actions_cell.vue';
import ImportTable from '~/import_entities/import_groups/components/import_table.vue';
import ImportTargetCell from '~/import_entities/import_groups/components/import_target_cell.vue';
import importGroupsMutation from '~/import_entities/import_groups/graphql/mutations/import_groups.mutation.graphql';
@@ -163,11 +164,8 @@ describe('import table', () => {
it('invokes importGroups mutation when row button is clicked', async () => {
jest.spyOn(apolloProvider.defaultClient, 'mutate');
- const triggerImportButton = wrapper
- .findAllComponents(GlButton)
- .wrappers.find((w) => w.text() === 'Import');
- triggerImportButton.vm.$emit('click');
+ wrapper.findComponent(ImportActionsCell).vm.$emit('import-group');
await waitForPromises();
expect(apolloProvider.defaultClient.mutate).toHaveBeenCalledWith({
mutation: importGroupsMutation,
@@ -329,7 +327,7 @@ describe('import table', () => {
});
it('does not allow selecting already started groups', async () => {
- const NEW_GROUPS = [generateFakeEntry({ id: 1, status: STATUSES.FINISHED })];
+ const NEW_GROUPS = [generateFakeEntry({ id: 1, status: STATUSES.STARTED })];
createComponent({
bulkImportSourceGroups: () => ({
diff --git a/spec/frontend/import_entities/import_groups/components/import_target_cell_spec.js b/spec/frontend/import_entities/import_groups/components/import_target_cell_spec.js
index 8231297e594..be83a61841f 100644
--- a/spec/frontend/import_entities/import_groups/components/import_target_cell_spec.js
+++ b/spec/frontend/import_entities/import_groups/components/import_target_cell_spec.js
@@ -1,14 +1,10 @@
-import { GlButton, GlDropdownItem, GlLink, GlFormInput } from '@gitlab/ui';
+import { GlDropdownItem, GlFormInput } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import Vue, { nextTick } from 'vue';
-import VueApollo from 'vue-apollo';
import ImportGroupDropdown from '~/import_entities/components/group_dropdown.vue';
import { STATUSES } from '~/import_entities/constants';
import ImportTargetCell from '~/import_entities/import_groups/components/import_target_cell.vue';
import { availableNamespacesFixture } from '../graphql/fixtures';
-Vue.use(VueApollo);
-
const getFakeGroup = (status) => ({
web_url: 'https://fake.host/',
full_path: 'fake_group_1',
@@ -26,9 +22,6 @@ describe('import target cell', () => {
let wrapper;
let group;
- const findByText = (cmp, text) => {
- return wrapper.findAll(cmp).wrappers.find((node) => node.text().indexOf(text) === 0);
- };
const findNameInput = () => wrapper.find(GlFormInput);
const findNamespaceDropdown = () => wrapper.find(ImportGroupDropdown);
@@ -117,10 +110,6 @@ describe('import target cell', () => {
createComponent({ group });
});
- it('does not render Import button', () => {
- expect(findByText(GlButton, 'Import')).toBe(undefined);
- });
-
it('renders namespace dropdown as disabled', () => {
expect(findNamespaceDropdown().attributes('disabled')).toBe('true');
});
@@ -132,17 +121,8 @@ describe('import target cell', () => {
createComponent({ group });
});
- it('does not render Import button', () => {
- expect(findByText(GlButton, 'Import')).toBe(undefined);
- });
-
- it('does not render namespace dropdown', () => {
- expect(findNamespaceDropdown().exists()).toBe(false);
- });
-
- it('renders target as link', () => {
- const TARGET_LINK = `${group.import_target.target_namespace}/${group.import_target.new_name}`;
- expect(findByText(GlLink, TARGET_LINK).exists()).toBe(true);
+ it('renders namespace dropdown as enabled', () => {
+ expect(findNamespaceDropdown().attributes('disabled')).toBe(undefined);
});
});
@@ -179,9 +159,6 @@ describe('import target cell', () => {
},
});
- jest.runOnlyPendingTimers();
- await nextTick();
-
expect(wrapper.text()).toContain(FAKE_ERROR_MESSAGE);
});
});
diff --git a/spec/frontend/import_entities/import_groups/graphql/client_factory_spec.js b/spec/frontend/import_entities/import_groups/graphql/client_factory_spec.js
index ec50dfd037f..e1d65095888 100644
--- a/spec/frontend/import_entities/import_groups/graphql/client_factory_spec.js
+++ b/spec/frontend/import_entities/import_groups/graphql/client_factory_spec.js
@@ -259,6 +259,10 @@ describe('Bulk import resolvers', () => {
target_namespace: 'root',
new_name: 'group1',
},
+ last_import_target: {
+ target_namespace: 'root',
+ new_name: 'group1',
+ },
validation_errors: [],
},
],
@@ -414,19 +418,32 @@ describe('Bulk import resolvers', () => {
});
});
- it('setImportProgress updates group progress', async () => {
+ it('setImportProgress updates group progress and sets import target', async () => {
const NEW_STATUS = 'dummy';
const FAKE_JOB_ID = 5;
+ const IMPORT_TARGET = {
+ __typename: 'ClientBulkImportTarget',
+ new_name: 'fake_name',
+ target_namespace: 'fake_target',
+ };
const {
data: {
- setImportProgress: { progress },
+ setImportProgress: { progress, last_import_target: lastImportTarget },
},
} = await client.mutate({
mutation: setImportProgressMutation,
- variables: { sourceGroupId: GROUP_ID, status: NEW_STATUS, jobId: FAKE_JOB_ID },
+ variables: {
+ sourceGroupId: GROUP_ID,
+ status: NEW_STATUS,
+ jobId: FAKE_JOB_ID,
+ importTarget: IMPORT_TARGET,
+ },
});
- expect(progress).toMatchObject({
+ expect(lastImportTarget).toStrictEqual(IMPORT_TARGET);
+
+ expect(progress).toStrictEqual({
+ __typename: clientTypenames.BulkImportProgress,
id: FAKE_JOB_ID,
status: NEW_STATUS,
});
@@ -442,7 +459,8 @@ describe('Bulk import resolvers', () => {
variables: { id: FAKE_JOB_ID, status: NEW_STATUS },
});
- expect(statusInResponse).toMatchObject({
+ expect(statusInResponse).toStrictEqual({
+ __typename: clientTypenames.BulkImportProgress,
id: FAKE_JOB_ID,
status: NEW_STATUS,
});
@@ -460,7 +478,13 @@ describe('Bulk import resolvers', () => {
variables: { sourceGroupId: GROUP_ID, field: FAKE_FIELD, message: FAKE_MESSAGE },
});
- expect(validationErrors).toMatchObject([{ field: FAKE_FIELD, message: FAKE_MESSAGE }]);
+ expect(validationErrors).toStrictEqual([
+ {
+ __typename: clientTypenames.BulkImportValidationError,
+ field: FAKE_FIELD,
+ message: FAKE_MESSAGE,
+ },
+ ]);
});
it('removeValidationError removes error from group', async () => {
@@ -481,7 +505,7 @@ describe('Bulk import resolvers', () => {
variables: { sourceGroupId: GROUP_ID, field: FAKE_FIELD },
});
- expect(validationErrors).toMatchObject([]);
+ expect(validationErrors).toStrictEqual([]);
});
});
});
diff --git a/spec/frontend/import_entities/import_groups/graphql/fixtures.js b/spec/frontend/import_entities/import_groups/graphql/fixtures.js
index 6f66066b312..d1bd52693b6 100644
--- a/spec/frontend/import_entities/import_groups/graphql/fixtures.js
+++ b/spec/frontend/import_entities/import_groups/graphql/fixtures.js
@@ -9,6 +9,10 @@ export const generateFakeEntry = ({ id, status, ...rest }) => ({
target_namespace: 'root',
new_name: `group${id}`,
},
+ last_import_target: {
+ target_namespace: 'root',
+ new_name: `last-group${id}`,
+ },
id,
progress: {
id: `test-${id}`,
diff --git a/spec/frontend/import_entities/import_groups/graphql/services/source_groups_manager_spec.js b/spec/frontend/import_entities/import_groups/graphql/services/source_groups_manager_spec.js
index bae715edac0..f06babcb149 100644
--- a/spec/frontend/import_entities/import_groups/graphql/services/source_groups_manager_spec.js
+++ b/spec/frontend/import_entities/import_groups/graphql/services/source_groups_manager_spec.js
@@ -20,7 +20,7 @@ describe('SourceGroupsManager', () => {
describe('storage management', () => {
const IMPORT_ID = 1;
- const IMPORT_TARGET = { destination_name: 'demo', destination_namespace: 'foo' };
+ const IMPORT_TARGET = { new_name: 'demo', target_namespace: 'foo' };
const STATUS = 'FAKE_STATUS';
const FAKE_GROUP = { id: 1, import_target: IMPORT_TARGET, status: STATUS };
diff --git a/spec/frontend/import_entities/import_projects/store/actions_spec.js b/spec/frontend/import_entities/import_projects/store/actions_spec.js
index f2bfc61381c..0ebe8525b5a 100644
--- a/spec/frontend/import_entities/import_projects/store/actions_spec.js
+++ b/spec/frontend/import_entities/import_projects/store/actions_spec.js
@@ -85,7 +85,7 @@ describe('import_projects store actions', () => {
afterEach(() => mock.restore());
- it('commits SET_PAGE, REQUEST_REPOS, RECEIVE_REPOS_SUCCESS mutations on a successful request', () => {
+ it('commits REQUEST_REPOS, SET_PAGE, RECEIVE_REPOS_SUCCESS mutations on a successful request', () => {
mock.onGet(MOCK_ENDPOINT).reply(200, payload);
return testAction(
@@ -93,8 +93,8 @@ describe('import_projects store actions', () => {
null,
localState,
[
- { type: SET_PAGE, payload: 1 },
{ type: REQUEST_REPOS },
+ { type: SET_PAGE, payload: 1 },
{
type: RECEIVE_REPOS_SUCCESS,
payload: convertObjectPropsToCamelCase(payload, { deep: true }),
@@ -104,19 +104,14 @@ describe('import_projects store actions', () => {
);
});
- it('commits SET_PAGE, REQUEST_REPOS, RECEIVE_REPOS_ERROR and SET_PAGE again mutations on an unsuccessful request', () => {
+ it('commits REQUEST_REPOS, RECEIVE_REPOS_ERROR mutations on an unsuccessful request', () => {
mock.onGet(MOCK_ENDPOINT).reply(500);
return testAction(
fetchRepos,
null,
localState,
- [
- { type: SET_PAGE, payload: 1 },
- { type: REQUEST_REPOS },
- { type: SET_PAGE, payload: 0 },
- { type: RECEIVE_REPOS_ERROR },
- ],
+ [{ type: REQUEST_REPOS }, { type: RECEIVE_REPOS_ERROR }],
[],
);
});
@@ -135,7 +130,7 @@ describe('import_projects store actions', () => {
expect(requestedUrl).toBe(`${MOCK_ENDPOINT}?page=${localStateWithPage.pageInfo.page + 1}`);
});
- it('correctly updates current page on an unsuccessful request', () => {
+ it('correctly keeps current page on an unsuccessful request', () => {
mock.onGet(MOCK_ENDPOINT).reply(500);
const CURRENT_PAGE = 5;
@@ -143,10 +138,7 @@ describe('import_projects store actions', () => {
fetchRepos,
null,
{ ...localState, pageInfo: { page: CURRENT_PAGE } },
- expect.arrayContaining([
- { type: SET_PAGE, payload: CURRENT_PAGE + 1 },
- { type: SET_PAGE, payload: CURRENT_PAGE },
- ]),
+ expect.arrayContaining([]),
[],
);
});
@@ -159,12 +151,7 @@ describe('import_projects store actions', () => {
fetchRepos,
null,
{ ...localState, filter: 'filter' },
- [
- { type: SET_PAGE, payload: 1 },
- { type: REQUEST_REPOS },
- { type: SET_PAGE, payload: 0 },
- { type: RECEIVE_REPOS_ERROR },
- ],
+ [{ type: REQUEST_REPOS }, { type: RECEIVE_REPOS_ERROR }],
[],
);
@@ -183,8 +170,8 @@ describe('import_projects store actions', () => {
null,
{ ...localState, filter: 'filter' },
[
- { type: SET_PAGE, payload: 1 },
{ type: REQUEST_REPOS },
+ { type: SET_PAGE, payload: 1 },
{
type: RECEIVE_REPOS_SUCCESS,
payload: convertObjectPropsToCamelCase(payload, { deep: true }),
diff --git a/spec/frontend/invite_members/components/import_a_project_modal_spec.js b/spec/frontend/invite_members/components/import_a_project_modal_spec.js
new file mode 100644
index 00000000000..fecbf84fb57
--- /dev/null
+++ b/spec/frontend/invite_members/components/import_a_project_modal_spec.js
@@ -0,0 +1,167 @@
+import { GlFormGroup, GlSprintf, GlModal } from '@gitlab/ui';
+import MockAdapter from 'axios-mock-adapter';
+import { stubComponent } from 'helpers/stub_component';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import * as ProjectsApi from '~/api/projects_api';
+import ImportAProjectModal from '~/invite_members/components/import_a_project_modal.vue';
+import ProjectSelect from '~/invite_members/components/project_select.vue';
+import axios from '~/lib/utils/axios_utils';
+
+let wrapper;
+let mock;
+
+const projectId = '1';
+const projectName = 'test name';
+const projectToBeImported = { id: '2' };
+const $toast = {
+ show: jest.fn(),
+};
+
+const createComponent = () => {
+ wrapper = shallowMountExtended(ImportAProjectModal, {
+ propsData: {
+ projectId,
+ projectName,
+ },
+ stubs: {
+ GlModal: stubComponent(GlModal, {
+ template:
+ '<div><slot name="modal-title"></slot><slot></slot><slot name="modal-footer"></slot></div>',
+ }),
+ GlSprintf,
+ GlFormGroup: stubComponent(GlFormGroup, {
+ props: ['state', 'invalidFeedback'],
+ }),
+ },
+ mocks: {
+ $toast,
+ },
+ });
+};
+
+beforeEach(() => {
+ gon.api_version = 'v4';
+ mock = new MockAdapter(axios);
+});
+
+afterEach(() => {
+ wrapper.destroy();
+ mock.restore();
+});
+
+describe('ImportAProjectModal', () => {
+ const findIntroText = () => wrapper.find({ ref: 'modalIntro' }).text();
+ const findCancelButton = () => wrapper.findByTestId('cancel-button');
+ const findImportButton = () => wrapper.findByTestId('import-button');
+ const clickImportButton = () => findImportButton().vm.$emit('click');
+ const clickCancelButton = () => findCancelButton().vm.$emit('click');
+ const findFormGroup = () => wrapper.findByTestId('form-group');
+ const formGroupInvalidFeedback = () => findFormGroup().props('invalidFeedback');
+ const formGroupErrorState = () => findFormGroup().props('state');
+ const findProjectSelect = () => wrapper.findComponent(ProjectSelect);
+
+ describe('rendering the modal', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('renders the modal with the correct title', () => {
+ expect(wrapper.findComponent(GlModal).props('title')).toBe(
+ 'Import members from another project',
+ );
+ });
+
+ it('renders the Cancel button text correctly', () => {
+ expect(findCancelButton().text()).toBe('Cancel');
+ });
+
+ it('renders the Import button text correctly', () => {
+ expect(findImportButton().text()).toBe('Import project members');
+ });
+
+ it('renders the modal intro text correctly', () => {
+ expect(findIntroText()).toBe("You're importing members to the test name project.");
+ });
+
+ it('renders the Import button modal without isLoading', () => {
+ expect(findImportButton().props('loading')).toBe(false);
+ });
+
+ it('sets isLoading to true when the Invite button is clicked', async () => {
+ clickImportButton();
+
+ await wrapper.vm.$nextTick();
+
+ expect(findImportButton().props('loading')).toBe(true);
+ });
+ });
+
+ describe('submitting the import form', () => {
+ describe('when the import is successful', () => {
+ beforeEach(() => {
+ createComponent();
+
+ findProjectSelect().vm.$emit('input', projectToBeImported);
+
+ jest.spyOn(ProjectsApi, 'importProjectMembers').mockResolvedValue();
+
+ clickImportButton();
+ });
+
+ it('calls Api importProjectMembers', () => {
+ expect(ProjectsApi.importProjectMembers).toHaveBeenCalledWith(
+ projectId,
+ projectToBeImported.id,
+ );
+ });
+
+ it('displays the successful toastMessage', () => {
+ expect($toast.show).toHaveBeenCalledWith(
+ 'Successfully imported',
+ wrapper.vm.$options.toastOptions,
+ );
+ });
+
+ it('sets isLoading to false after success', () => {
+ expect(findImportButton().props('loading')).toBe(false);
+ });
+ });
+
+ describe('when the import fails', () => {
+ beforeEach(async () => {
+ createComponent();
+
+ findProjectSelect().vm.$emit('input', projectToBeImported);
+
+ jest
+ .spyOn(ProjectsApi, 'importProjectMembers')
+ .mockRejectedValue({ response: { data: { success: false } } });
+
+ clickImportButton();
+ await waitForPromises();
+ });
+
+ it('displays the generic error message', () => {
+ expect(formGroupInvalidFeedback()).toBe('Unable to import project members');
+ expect(formGroupErrorState()).toBe(false);
+ });
+
+ it('sets isLoading to false after error', () => {
+ expect(findImportButton().props('loading')).toBe(false);
+ });
+
+ it('clears the error when the modal is closed with an error', async () => {
+ expect(formGroupInvalidFeedback()).toBe('Unable to import project members');
+ expect(formGroupErrorState()).toBe(false);
+
+ clickCancelButton();
+
+ await wrapper.vm.$nextTick();
+
+ expect(formGroupInvalidFeedback()).toBe('');
+ expect(formGroupErrorState()).not.toBe(false);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/invite_members/components/invite_members_trigger_spec.js b/spec/frontend/invite_members/components/invite_members_trigger_spec.js
index f57af61ad5b..b2ebb9e4a47 100644
--- a/spec/frontend/invite_members/components/invite_members_trigger_spec.js
+++ b/spec/frontend/invite_members/components/invite_members_trigger_spec.js
@@ -79,14 +79,14 @@ describe.each(['button', 'anchor'])('with triggerElement as %s', (triggerElement
it('does not add tracking attributes', () => {
createComponent();
- expect(findButton().attributes('data-track-event')).toBeUndefined();
+ expect(findButton().attributes('data-track-action')).toBeUndefined();
expect(findButton().attributes('data-track-label')).toBeUndefined();
});
it('adds tracking attributes', () => {
createComponent({ label: '_label_', event: '_event_' });
- expect(findButton().attributes('data-track-event')).toBe('_event_');
+ expect(findButton().attributes('data-track-action')).toBe('_event_');
expect(findButton().attributes('data-track-label')).toBe('_label_');
});
});
diff --git a/spec/frontend/invite_members/components/project_select_spec.js b/spec/frontend/invite_members/components/project_select_spec.js
new file mode 100644
index 00000000000..acc062b5fff
--- /dev/null
+++ b/spec/frontend/invite_members/components/project_select_spec.js
@@ -0,0 +1,105 @@
+import { GlSearchBoxByType, GlAvatarLabeled, GlDropdownItem } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import * as projectsApi from '~/api/projects_api';
+import ProjectSelect from '~/invite_members/components/project_select.vue';
+import { allProjects, project1 } from '../mock_data/api_response_data';
+
+describe('ProjectSelect', () => {
+ let wrapper;
+
+ const createComponent = () => {
+ wrapper = shallowMountExtended(ProjectSelect, {});
+ };
+
+ beforeEach(() => {
+ jest.spyOn(projectsApi, 'getProjects').mockResolvedValue(allProjects);
+
+ createComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ const findSearchBoxByType = () => wrapper.findComponent(GlSearchBoxByType);
+ const findDropdownItem = (index) => wrapper.findAllComponents(GlDropdownItem).at(index);
+ const findAvatarLabeled = (index) => findDropdownItem(index).findComponent(GlAvatarLabeled);
+ const findEmptyResultMessage = () => wrapper.findByTestId('empty-result-message');
+ const findErrorMessage = () => wrapper.findByTestId('error-message');
+
+ it('renders GlSearchBoxByType with default attributes', () => {
+ expect(findSearchBoxByType().exists()).toBe(true);
+ expect(findSearchBoxByType().vm.$attrs).toMatchObject({
+ placeholder: 'Search projects',
+ });
+ });
+
+ describe('when user types in the search input', () => {
+ let resolveApiRequest;
+ let rejectApiRequest;
+
+ beforeEach(() => {
+ jest.spyOn(projectsApi, 'getProjects').mockImplementation(
+ () =>
+ new Promise((resolve, reject) => {
+ resolveApiRequest = resolve;
+ rejectApiRequest = reject;
+ }),
+ );
+
+ findSearchBoxByType().vm.$emit('input', project1.name);
+ });
+
+ it('calls the API', () => {
+ resolveApiRequest({ data: allProjects });
+
+ expect(projectsApi.getProjects).toHaveBeenCalledWith(project1.name, {
+ active: true,
+ exclude_internal: true,
+ });
+ });
+
+ it('displays loading icon while waiting for API call to resolve and then sets loading false', async () => {
+ expect(findSearchBoxByType().props('isLoading')).toBe(true);
+
+ resolveApiRequest({ data: allProjects });
+ await waitForPromises();
+
+ expect(findSearchBoxByType().props('isLoading')).toBe(false);
+ expect(findEmptyResultMessage().exists()).toBe(false);
+ expect(findErrorMessage().exists()).toBe(false);
+ });
+
+ it('displays a dropdown item and avatar for each project fetched', async () => {
+ resolveApiRequest({ data: allProjects });
+ await waitForPromises();
+
+ allProjects.forEach((project, index) => {
+ expect(findDropdownItem(index).attributes('name')).toBe(project.name_with_namespace);
+ expect(findAvatarLabeled(index).attributes()).toMatchObject({
+ src: project.avatar_url,
+ 'entity-id': String(project.id),
+ 'entity-name': project.name_with_namespace,
+ });
+ expect(findAvatarLabeled(index).props('label')).toBe(project.name_with_namespace);
+ });
+ });
+
+ it('displays the empty message when the API results are empty', async () => {
+ resolveApiRequest({ data: [] });
+ await waitForPromises();
+
+ expect(findEmptyResultMessage().text()).toBe('No matching results');
+ });
+
+ it('displays the error message when the fetch fails', async () => {
+ rejectApiRequest();
+ await waitForPromises();
+
+ expect(findErrorMessage().text()).toBe(
+ 'There was an error fetching the projects. Please try again.',
+ );
+ });
+ });
+});
diff --git a/spec/frontend/invite_members/mock_data/api_response_data.js b/spec/frontend/invite_members/mock_data/api_response_data.js
new file mode 100644
index 00000000000..9509422b603
--- /dev/null
+++ b/spec/frontend/invite_members/mock_data/api_response_data.js
@@ -0,0 +1,13 @@
+export const project1 = {
+ id: 1,
+ name: 'Project One',
+ name_with_namespace: 'Project One',
+ avatar_url: 'test1',
+};
+export const project2 = {
+ id: 2,
+ name: 'Project One',
+ name_with_namespace: 'Project Two',
+ avatar_url: 'test2',
+};
+export const allProjects = [project1, project2];
diff --git a/spec/frontend/issue_show/components/app_spec.js b/spec/frontend/issue_show/components/app_spec.js
index babe3a66578..bd05cb1ac5a 100644
--- a/spec/frontend/issue_show/components/app_spec.js
+++ b/spec/frontend/issue_show/components/app_spec.js
@@ -1,7 +1,8 @@
import { GlIntersectionObserver } from '@gitlab/ui';
-import { mount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import { nextTick } from 'vue';
+import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
+import { mountExtended } from 'helpers/vue_test_utils_helper';
import '~/behaviors/markdown/render_gfm';
import IssuableApp from '~/issue_show/components/app.vue';
import DescriptionComponent from '~/issue_show/components/description.vue';
@@ -33,13 +34,17 @@ describe('Issuable output', () => {
let realtimeRequestCount = 0;
let wrapper;
- const findStickyHeader = () => wrapper.find('[data-testid="issue-sticky-header"]');
- const findLockedBadge = () => wrapper.find('[data-testid="locked"]');
- const findConfidentialBadge = () => wrapper.find('[data-testid="confidential"]');
+ const findStickyHeader = () => wrapper.findByTestId('issue-sticky-header');
+ const findLockedBadge = () => wrapper.findByTestId('locked');
+ const findConfidentialBadge = () => wrapper.findByTestId('confidential');
+ const findHiddenBadge = () => wrapper.findByTestId('hidden');
const findAlert = () => wrapper.find('.alert');
const mountComponent = (props = {}, options = {}, data = {}) => {
- wrapper = mount(IssuableApp, {
+ wrapper = mountExtended(IssuableApp, {
+ directives: {
+ GlTooltip: createMockDirective(),
+ },
propsData: { ...appProps, ...props },
provide: {
fullPath: 'gitlab-org/incidents',
@@ -539,8 +544,8 @@ describe('Issuable output', () => {
it.each`
title | isConfidential
- ${'does not show confidential badge when issue is not confidential'} | ${true}
- ${'shows confidential badge when issue is confidential'} | ${false}
+ ${'does not show confidential badge when issue is not confidential'} | ${false}
+ ${'shows confidential badge when issue is confidential'} | ${true}
`('$title', async ({ isConfidential }) => {
wrapper.setProps({ isConfidential });
@@ -551,8 +556,8 @@ describe('Issuable output', () => {
it.each`
title | isLocked
- ${'does not show locked badge when issue is not locked'} | ${true}
- ${'shows locked badge when issue is locked'} | ${false}
+ ${'does not show locked badge when issue is not locked'} | ${false}
+ ${'shows locked badge when issue is locked'} | ${true}
`('$title', async ({ isLocked }) => {
wrapper.setProps({ isLocked });
@@ -560,6 +565,27 @@ describe('Issuable output', () => {
expect(findLockedBadge().exists()).toBe(isLocked);
});
+
+ it.each`
+ title | isHidden
+ ${'does not show hidden badge when issue is not hidden'} | ${false}
+ ${'shows hidden badge when issue is hidden'} | ${true}
+ `('$title', async ({ isHidden }) => {
+ wrapper.setProps({ isHidden });
+
+ await nextTick();
+
+ const hiddenBadge = findHiddenBadge();
+
+ expect(hiddenBadge.exists()).toBe(isHidden);
+
+ if (isHidden) {
+ expect(hiddenBadge.attributes('title')).toBe(
+ 'This issue is hidden because its author has been banned',
+ );
+ expect(getBinding(hiddenBadge.element, 'gl-tooltip')).not.toBeUndefined();
+ }
+ });
});
});
diff --git a/spec/frontend/issues_list/components/issues_list_app_spec.js b/spec/frontend/issues_list/components/issues_list_app_spec.js
index 0cb1092135f..8d79a5eed35 100644
--- a/spec/frontend/issues_list/components/issues_list_app_spec.js
+++ b/spec/frontend/issues_list/components/issues_list_app_spec.js
@@ -5,17 +5,17 @@ import { cloneDeep } from 'lodash';
import { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import getIssuesQuery from 'ee_else_ce/issues_list/queries/get_issues.query.graphql';
-import getIssuesCountQuery from 'ee_else_ce/issues_list/queries/get_issues_count.query.graphql';
+import getIssuesCountsQuery from 'ee_else_ce/issues_list/queries/get_issues_counts.query.graphql';
import createMockApollo from 'helpers/mock_apollo_helper';
import setWindowLocation from 'helpers/set_window_location_helper';
import { TEST_HOST } from 'helpers/test_constants';
import waitForPromises from 'helpers/wait_for_promises';
import {
+ getIssuesCountsQueryResponse,
getIssuesQueryResponse,
filteredTokens,
locationSearch,
urlParams,
- getIssuesCountQueryResponse,
} from 'jest/issues_list/mock_data';
import createFlash from '~/flash';
import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils';
@@ -63,15 +63,15 @@ describe('IssuesListApp component', () => {
canBulkUpdate: false,
emptyStateSvgPath: 'empty-state.svg',
exportCsvPath: 'export/csv/path',
+ fullPath: 'path/to/project',
+ hasAnyIssues: true,
hasBlockedIssuesFeature: true,
hasIssueWeightsFeature: true,
hasIterationsFeature: true,
- hasProjectIssues: true,
+ isProject: true,
isSignedIn: true,
- issuesPath: 'path/to/issues',
jiraIntegrationPath: 'jira/integration/path',
newIssuePath: 'new/issue/path',
- projectPath: 'path/to/project',
rssPath: 'rss/path',
showNewIssueLink: true,
signInPath: 'sign/in/path',
@@ -97,12 +97,12 @@ describe('IssuesListApp component', () => {
const mountComponent = ({
provide = {},
issuesQueryResponse = jest.fn().mockResolvedValue(defaultQueryResponse),
- issuesQueryCountResponse = jest.fn().mockResolvedValue(getIssuesCountQueryResponse),
+ issuesCountsQueryResponse = jest.fn().mockResolvedValue(getIssuesCountsQueryResponse),
mountFn = shallowMount,
} = {}) => {
const requestHandlers = [
[getIssuesQuery, issuesQueryResponse],
- [getIssuesCountQuery, issuesQueryCountResponse],
+ [getIssuesCountsQuery, issuesCountsQueryResponse],
];
const apolloProvider = createMockApollo(requestHandlers);
@@ -134,7 +134,7 @@ describe('IssuesListApp component', () => {
it('renders', () => {
expect(findIssuableList().props()).toMatchObject({
- namespace: defaultProvide.projectPath,
+ namespace: defaultProvide.fullPath,
recentSearchesStorageKey: 'issues',
searchInputPlaceholder: IssuesListApp.i18n.searchPlaceholder,
sortOptions: getSortOptions(true, true),
@@ -191,7 +191,7 @@ describe('IssuesListApp component', () => {
setWindowLocation(search);
wrapper = mountComponent({
- provide: { ...defaultProvide, isSignedIn: true },
+ provide: { isSignedIn: true },
mountFn: mount,
});
@@ -208,7 +208,15 @@ describe('IssuesListApp component', () => {
describe('when user is not signed in', () => {
it('does not render', () => {
- wrapper = mountComponent({ provide: { ...defaultProvide, isSignedIn: false } });
+ wrapper = mountComponent({ provide: { isSignedIn: false } });
+
+ expect(findCsvImportExportButtons().exists()).toBe(false);
+ });
+ });
+
+ describe('when in a group context', () => {
+ it('does not render', () => {
+ wrapper = mountComponent({ provide: { isProject: false } });
expect(findCsvImportExportButtons().exists()).toBe(false);
});
@@ -349,7 +357,7 @@ describe('IssuesListApp component', () => {
beforeEach(() => {
setWindowLocation(`?search=no+results`);
- wrapper = mountComponent({ provide: { hasProjectIssues: true }, mountFn: mount });
+ wrapper = mountComponent({ provide: { hasAnyIssues: true }, mountFn: mount });
});
it('shows empty state', () => {
@@ -363,7 +371,7 @@ describe('IssuesListApp component', () => {
describe('when "Open" tab has no issues', () => {
beforeEach(() => {
- wrapper = mountComponent({ provide: { hasProjectIssues: true }, mountFn: mount });
+ wrapper = mountComponent({ provide: { hasAnyIssues: true }, mountFn: mount });
});
it('shows empty state', () => {
@@ -379,7 +387,7 @@ describe('IssuesListApp component', () => {
beforeEach(() => {
setWindowLocation(`?state=${IssuableStates.Closed}`);
- wrapper = mountComponent({ provide: { hasProjectIssues: true }, mountFn: mount });
+ wrapper = mountComponent({ provide: { hasAnyIssues: true }, mountFn: mount });
});
it('shows empty state', () => {
@@ -395,7 +403,7 @@ describe('IssuesListApp component', () => {
describe('when user is logged in', () => {
beforeEach(() => {
wrapper = mountComponent({
- provide: { hasProjectIssues: false, isSignedIn: true },
+ provide: { hasAnyIssues: false, isSignedIn: true },
mountFn: mount,
});
});
@@ -434,7 +442,7 @@ describe('IssuesListApp component', () => {
describe('when user is logged out', () => {
beforeEach(() => {
wrapper = mountComponent({
- provide: { hasProjectIssues: false, isSignedIn: false },
+ provide: { hasAnyIssues: false, isSignedIn: false },
});
});
@@ -571,9 +579,9 @@ describe('IssuesListApp component', () => {
describe('errors', () => {
describe.each`
- error | mountOption | message
- ${'fetching issues'} | ${'issuesQueryResponse'} | ${IssuesListApp.i18n.errorFetchingIssues}
- ${'fetching issue counts'} | ${'issuesQueryCountResponse'} | ${IssuesListApp.i18n.errorFetchingCounts}
+ error | mountOption | message
+ ${'fetching issues'} | ${'issuesQueryResponse'} | ${IssuesListApp.i18n.errorFetchingIssues}
+ ${'fetching issue counts'} | ${'issuesCountsQueryResponse'} | ${IssuesListApp.i18n.errorFetchingCounts}
`('when there is an error $error', ({ mountOption, message }) => {
beforeEach(() => {
wrapper = mountComponent({
@@ -625,78 +633,99 @@ describe('IssuesListApp component', () => {
...defaultQueryResponse.data.project.issues.nodes[0],
id: 'gid://gitlab/Issue/1',
iid: '101',
- title: 'Issue one',
+ reference: 'group/project#1',
+ webPath: '/group/project/-/issues/1',
};
const issueTwo = {
...defaultQueryResponse.data.project.issues.nodes[0],
id: 'gid://gitlab/Issue/2',
iid: '102',
- title: 'Issue two',
+ reference: 'group/project#2',
+ webPath: '/group/project/-/issues/2',
};
const issueThree = {
...defaultQueryResponse.data.project.issues.nodes[0],
id: 'gid://gitlab/Issue/3',
iid: '103',
- title: 'Issue three',
+ reference: 'group/project#3',
+ webPath: '/group/project/-/issues/3',
};
const issueFour = {
...defaultQueryResponse.data.project.issues.nodes[0],
id: 'gid://gitlab/Issue/4',
iid: '104',
- title: 'Issue four',
+ reference: 'group/project#4',
+ webPath: '/group/project/-/issues/4',
};
- const response = {
+ const response = (isProject = true) => ({
data: {
- project: {
+ [isProject ? 'project' : 'group']: {
issues: {
...defaultQueryResponse.data.project.issues,
nodes: [issueOne, issueTwo, issueThree, issueFour],
},
},
},
- };
-
- beforeEach(() => {
- wrapper = mountComponent({ issuesQueryResponse: jest.fn().mockResolvedValue(response) });
- jest.runOnlyPendingTimers();
});
describe('when successful', () => {
- describe.each`
- description | issueToMove | oldIndex | newIndex | moveBeforeId | moveAfterId
- ${'to the beginning of the list'} | ${issueThree} | ${2} | ${0} | ${null} | ${issueOne.id}
- ${'down the list'} | ${issueOne} | ${0} | ${1} | ${issueTwo.id} | ${issueThree.id}
- ${'up the list'} | ${issueThree} | ${2} | ${1} | ${issueOne.id} | ${issueTwo.id}
- ${'to the end of the list'} | ${issueTwo} | ${1} | ${3} | ${issueFour.id} | ${null}
- `(
- 'when moving issue $description',
- ({ issueToMove, oldIndex, newIndex, moveBeforeId, moveAfterId }) => {
- it('makes API call to reorder the issue', async () => {
- findIssuableList().vm.$emit('reorder', { oldIndex, newIndex });
-
- await waitForPromises();
-
- expect(axiosMock.history.put[0]).toMatchObject({
- url: joinPaths(defaultProvide.issuesPath, issueToMove.iid, 'reorder'),
- data: JSON.stringify({
- move_before_id: getIdFromGraphQLId(moveBeforeId),
- move_after_id: getIdFromGraphQLId(moveAfterId),
- }),
+ describe.each([true, false])('when isProject=%s', (isProject) => {
+ describe.each`
+ description | issueToMove | oldIndex | newIndex | moveBeforeId | moveAfterId
+ ${'to the beginning of the list'} | ${issueThree} | ${2} | ${0} | ${null} | ${issueOne.id}
+ ${'down the list'} | ${issueOne} | ${0} | ${1} | ${issueTwo.id} | ${issueThree.id}
+ ${'up the list'} | ${issueThree} | ${2} | ${1} | ${issueOne.id} | ${issueTwo.id}
+ ${'to the end of the list'} | ${issueTwo} | ${1} | ${3} | ${issueFour.id} | ${null}
+ `(
+ 'when moving issue $description',
+ ({ issueToMove, oldIndex, newIndex, moveBeforeId, moveAfterId }) => {
+ beforeEach(() => {
+ wrapper = mountComponent({
+ provide: { isProject },
+ issuesQueryResponse: jest.fn().mockResolvedValue(response(isProject)),
+ });
+ jest.runOnlyPendingTimers();
});
- });
- },
- );
+
+ it('makes API call to reorder the issue', async () => {
+ findIssuableList().vm.$emit('reorder', { oldIndex, newIndex });
+
+ await waitForPromises();
+
+ expect(axiosMock.history.put[0]).toMatchObject({
+ url: joinPaths(issueToMove.webPath, 'reorder'),
+ data: JSON.stringify({
+ move_before_id: getIdFromGraphQLId(moveBeforeId),
+ move_after_id: getIdFromGraphQLId(moveAfterId),
+ group_full_path: isProject ? undefined : defaultProvide.fullPath,
+ }),
+ });
+ });
+ },
+ );
+ });
});
describe('when unsuccessful', () => {
+ beforeEach(() => {
+ wrapper = mountComponent({
+ issuesQueryResponse: jest.fn().mockResolvedValue(response()),
+ });
+ jest.runOnlyPendingTimers();
+ });
+
it('displays an error message', async () => {
- axiosMock.onPut(joinPaths(defaultProvide.issuesPath, issueOne.iid, 'reorder')).reply(500);
+ axiosMock.onPut(joinPaths(issueOne.webPath, 'reorder')).reply(500);
findIssuableList().vm.$emit('reorder', { oldIndex: 0, newIndex: 1 });
await waitForPromises();
- expect(createFlash).toHaveBeenCalledWith({ message: IssuesListApp.i18n.reorderError });
+ expect(createFlash).toHaveBeenCalledWith({
+ message: IssuesListApp.i18n.reorderError,
+ captureError: true,
+ error: new Error('Request failed with status code 500'),
+ });
});
});
});
diff --git a/spec/frontend/issues_list/mock_data.js b/spec/frontend/issues_list/mock_data.js
index d3f3f2f9f23..720f9cac986 100644
--- a/spec/frontend/issues_list/mock_data.js
+++ b/spec/frontend/issues_list/mock_data.js
@@ -29,6 +29,7 @@ export const getIssuesQueryResponse = {
updatedAt: '2021-05-22T04:08:01Z',
upvotes: 3,
userDiscussionsCount: 4,
+ webPath: 'project/-/issues/789',
webUrl: 'project/-/issues/789',
assignees: {
nodes: [
@@ -70,10 +71,16 @@ export const getIssuesQueryResponse = {
},
};
-export const getIssuesCountQueryResponse = {
+export const getIssuesCountsQueryResponse = {
data: {
project: {
- issues: {
+ openedIssues: {
+ count: 1,
+ },
+ closedIssues: {
+ count: 1,
+ },
+ allIssues: {
count: 1,
},
},
diff --git a/spec/frontend/jira_import/components/__snapshots__/jira_import_form_spec.js.snap b/spec/frontend/jira_import/components/__snapshots__/jira_import_form_spec.js.snap
index f2142ce1fcf..891ba9c223c 100644
--- a/spec/frontend/jira_import/components/__snapshots__/jira_import_form_spec.js.snap
+++ b/spec/frontend/jira_import/components/__snapshots__/jira_import_form_spec.js.snap
@@ -128,8 +128,26 @@ exports[`JiraImportForm table body shows correct information in each cell 1`] =
<!---->
<div
+ class="gl-display-flex gl-flex-direction-row gl-justify-content-space-between gl-align-items-center gl-px-5"
+ >
+ <div
+ class="gl-display-flex"
+ >
+ <!---->
+ </div>
+
+ <div
+ class="gl-display-flex"
+ >
+ <!---->
+ </div>
+ </div>
+
+ <div
class="gl-new-dropdown-contents"
>
+ <!---->
+
<div
class="gl-search-box-by-type"
>
@@ -255,8 +273,26 @@ exports[`JiraImportForm table body shows correct information in each cell 1`] =
<!---->
<div
+ class="gl-display-flex gl-flex-direction-row gl-justify-content-space-between gl-align-items-center gl-px-5"
+ >
+ <div
+ class="gl-display-flex"
+ >
+ <!---->
+ </div>
+
+ <div
+ class="gl-display-flex"
+ >
+ <!---->
+ </div>
+ </div>
+
+ <div
class="gl-new-dropdown-contents"
>
+ <!---->
+
<div
class="gl-search-box-by-type"
>
diff --git a/spec/frontend/jobs/components/job_app_spec.js b/spec/frontend/jobs/components/job_app_spec.js
index 1f4dd7d6216..f8a0059bf21 100644
--- a/spec/frontend/jobs/components/job_app_spec.js
+++ b/spec/frontend/jobs/components/job_app_spec.js
@@ -140,7 +140,7 @@ describe('Job App', () => {
it('should render provided job information', () => {
expect(wrapper.find('.header-main-content').text().replace(/\s+/g, ' ').trim()).toContain(
- 'passed Job #4757 triggered 1 year ago by Root',
+ 'passed Job test triggered 1 year ago by Root',
);
});
@@ -154,7 +154,7 @@ describe('Job App', () => {
setupAndMount().then(() => {
expect(
wrapper.find('.header-main-content').text().replace(/\s+/g, ' ').trim(),
- ).toContain('passed Job #4757 created 3 weeks ago by Root');
+ ).toContain('passed Job test created 3 weeks ago by Root');
}));
});
});
diff --git a/spec/frontend/jobs/components/table/cells/actions_cell_spec.js b/spec/frontend/jobs/components/table/cells/actions_cell_spec.js
new file mode 100644
index 00000000000..1b1e2d4df8f
--- /dev/null
+++ b/spec/frontend/jobs/components/table/cells/actions_cell_spec.js
@@ -0,0 +1,126 @@
+import { GlModal } from '@gitlab/ui';
+import { nextTick } from 'vue';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import ActionsCell from '~/jobs/components/table/cells/actions_cell.vue';
+import JobPlayMutation from '~/jobs/components/table/graphql/mutations/job_play.mutation.graphql';
+import JobRetryMutation from '~/jobs/components/table/graphql/mutations/job_retry.mutation.graphql';
+import JobUnscheduleMutation from '~/jobs/components/table/graphql/mutations/job_unschedule.mutation.graphql';
+import { playableJob, retryableJob, scheduledJob } from '../../../mock_data';
+
+describe('Job actions cell', () => {
+ let wrapper;
+ let mutate;
+
+ const findRetryButton = () => wrapper.findByTestId('retry');
+ const findPlayButton = () => wrapper.findByTestId('play');
+ const findDownloadArtifactsButton = () => wrapper.findByTestId('download-artifacts');
+ const findCountdownButton = () => wrapper.findByTestId('countdown');
+ const findPlayScheduledJobButton = () => wrapper.findByTestId('play-scheduled');
+ const findUnscheduleButton = () => wrapper.findByTestId('unschedule');
+
+ const findModal = () => wrapper.findComponent(GlModal);
+
+ const MUTATION_SUCCESS = { data: { JobRetryMutation: { jobId: retryableJob.id } } };
+ const MUTATION_SUCCESS_UNSCHEDULE = {
+ data: { JobUnscheduleMutation: { jobId: scheduledJob.id } },
+ };
+ const MUTATION_SUCCESS_PLAY = { data: { JobPlayMutation: { jobId: playableJob.id } } };
+
+ const $toast = {
+ show: jest.fn(),
+ };
+
+ const createComponent = (jobType, mutationType = MUTATION_SUCCESS, props = {}) => {
+ mutate = jest.fn().mockResolvedValue(mutationType);
+
+ wrapper = shallowMountExtended(ActionsCell, {
+ propsData: {
+ job: jobType,
+ ...props,
+ },
+ mocks: {
+ $apollo: {
+ mutate,
+ },
+ $toast,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('does not display an artifacts download button', () => {
+ createComponent(retryableJob);
+
+ expect(findDownloadArtifactsButton().exists()).toBe(false);
+ });
+
+ it.each`
+ button | action | jobType
+ ${findPlayButton} | ${'play'} | ${playableJob}
+ ${findRetryButton} | ${'retry'} | ${retryableJob}
+ ${findDownloadArtifactsButton} | ${'download artifacts'} | ${playableJob}
+ `('displays the $action button', ({ button, jobType }) => {
+ createComponent(jobType);
+
+ expect(button().exists()).toBe(true);
+ });
+
+ it.each`
+ button | mutationResult | action | jobType | mutationFile
+ ${findPlayButton} | ${MUTATION_SUCCESS_PLAY} | ${'play'} | ${playableJob} | ${JobPlayMutation}
+ ${findRetryButton} | ${MUTATION_SUCCESS} | ${'retry'} | ${retryableJob} | ${JobRetryMutation}
+ `('performs the $action mutation', ({ button, mutationResult, jobType, mutationFile }) => {
+ createComponent(jobType, mutationResult);
+
+ button().vm.$emit('click');
+
+ expect(mutate).toHaveBeenCalledWith({
+ mutation: mutationFile,
+ variables: {
+ id: jobType.id,
+ },
+ });
+ });
+
+ describe('Scheduled Jobs', () => {
+ const today = () => new Date('2021-08-31');
+
+ beforeEach(() => {
+ jest.spyOn(Date, 'now').mockImplementation(today);
+ });
+
+ it('displays the countdown, play and unschedule buttons', () => {
+ createComponent(scheduledJob);
+
+ expect(findCountdownButton().exists()).toBe(true);
+ expect(findPlayScheduledJobButton().exists()).toBe(true);
+ expect(findUnscheduleButton().exists()).toBe(true);
+ });
+
+ it('unschedules a job', () => {
+ createComponent(scheduledJob, MUTATION_SUCCESS_UNSCHEDULE);
+
+ findUnscheduleButton().vm.$emit('click');
+
+ expect(mutate).toHaveBeenCalledWith({
+ mutation: JobUnscheduleMutation,
+ variables: {
+ id: scheduledJob.id,
+ },
+ });
+ });
+
+ it('shows the play job confirmation modal', async () => {
+ createComponent(scheduledJob, MUTATION_SUCCESS);
+
+ findPlayScheduledJobButton().vm.$emit('click');
+
+ await nextTick();
+
+ expect(findModal().exists()).toBe(true);
+ });
+ });
+});
diff --git a/spec/frontend/jobs/components/table/cells.vue/duration_cell_spec.js b/spec/frontend/jobs/components/table/cells/duration_cell_spec.js
index 763a4b0eaa2..763a4b0eaa2 100644
--- a/spec/frontend/jobs/components/table/cells.vue/duration_cell_spec.js
+++ b/spec/frontend/jobs/components/table/cells/duration_cell_spec.js
diff --git a/spec/frontend/jobs/components/table/cells.vue/job_cell_spec.js b/spec/frontend/jobs/components/table/cells/job_cell_spec.js
index fc4e5586349..fc4e5586349 100644
--- a/spec/frontend/jobs/components/table/cells.vue/job_cell_spec.js
+++ b/spec/frontend/jobs/components/table/cells/job_cell_spec.js
diff --git a/spec/frontend/jobs/components/table/cells.vue/pipeline_cell_spec.js b/spec/frontend/jobs/components/table/cells/pipeline_cell_spec.js
index 1f5e0a7aa21..1f5e0a7aa21 100644
--- a/spec/frontend/jobs/components/table/cells.vue/pipeline_cell_spec.js
+++ b/spec/frontend/jobs/components/table/cells/pipeline_cell_spec.js
diff --git a/spec/frontend/jobs/mock_data.js b/spec/frontend/jobs/mock_data.js
index 57f0b852ff8..43755b46bc9 100644
--- a/spec/frontend/jobs/mock_data.js
+++ b/spec/frontend/jobs/mock_data.js
@@ -1555,7 +1555,11 @@ export const mockJobsQueryResponse = {
cancelable: false,
active: false,
stuck: false,
- userPermissions: { readBuild: true, __typename: 'JobPermissions' },
+ userPermissions: {
+ readBuild: true,
+ readJobArtifacts: true,
+ __typename: 'JobPermissions',
+ },
__typename: 'CiJob',
},
],
@@ -1573,3 +1577,179 @@ export const mockJobsQueryEmptyResponse = {
},
},
};
+
+export const retryableJob = {
+ artifacts: { nodes: [], __typename: 'CiJobArtifactConnection' },
+ allowFailure: false,
+ status: 'SUCCESS',
+ scheduledAt: null,
+ manualJob: false,
+ triggered: null,
+ createdByTag: false,
+ detailedStatus: {
+ detailsPath: '/root/test-job-artifacts/-/jobs/1981',
+ group: 'success',
+ icon: 'status_success',
+ label: 'passed',
+ text: 'passed',
+ tooltip: 'passed',
+ action: {
+ buttonTitle: 'Retry this job',
+ icon: 'retry',
+ method: 'post',
+ path: '/root/test-job-artifacts/-/jobs/1981/retry',
+ title: 'Retry',
+ __typename: 'StatusAction',
+ },
+ __typename: 'DetailedStatus',
+ },
+ id: 'gid://gitlab/Ci::Build/1981',
+ refName: 'main',
+ refPath: '/root/test-job-artifacts/-/commits/main',
+ tags: [],
+ shortSha: '75daf01b',
+ commitPath: '/root/test-job-artifacts/-/commit/75daf01b465e7eab5a04a315e44660c9a17c8055',
+ pipeline: {
+ id: 'gid://gitlab/Ci::Pipeline/288',
+ path: '/root/test-job-artifacts/-/pipelines/288',
+ user: {
+ webPath: '/root',
+ avatarUrl:
+ 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ __typename: 'UserCore',
+ },
+ __typename: 'Pipeline',
+ },
+ stage: { name: 'test', __typename: 'CiStage' },
+ name: 'hello_world',
+ duration: 7,
+ finishedAt: '2021-08-30T20:33:56Z',
+ coverage: null,
+ retryable: true,
+ playable: false,
+ cancelable: false,
+ active: false,
+ stuck: false,
+ userPermissions: { readBuild: true, __typename: 'JobPermissions' },
+ __typename: 'CiJob',
+};
+
+export const playableJob = {
+ artifacts: {
+ nodes: [
+ {
+ downloadPath: '/root/test-job-artifacts/-/jobs/1982/artifacts/download?file_type=trace',
+ __typename: 'CiJobArtifact',
+ },
+ ],
+ __typename: 'CiJobArtifactConnection',
+ },
+ allowFailure: false,
+ status: 'SUCCESS',
+ scheduledAt: null,
+ manualJob: true,
+ triggered: null,
+ createdByTag: false,
+ detailedStatus: {
+ detailsPath: '/root/test-job-artifacts/-/jobs/1982',
+ group: 'success',
+ icon: 'status_success',
+ label: 'manual play action',
+ text: 'passed',
+ tooltip: 'passed',
+ action: {
+ buttonTitle: 'Trigger this manual action',
+ icon: 'play',
+ method: 'post',
+ path: '/root/test-job-artifacts/-/jobs/1982/play',
+ title: 'Play',
+ __typename: 'StatusAction',
+ },
+ __typename: 'DetailedStatus',
+ },
+ id: 'gid://gitlab/Ci::Build/1982',
+ refName: 'main',
+ refPath: '/root/test-job-artifacts/-/commits/main',
+ tags: [],
+ shortSha: '75daf01b',
+ commitPath: '/root/test-job-artifacts/-/commit/75daf01b465e7eab5a04a315e44660c9a17c8055',
+ pipeline: {
+ id: 'gid://gitlab/Ci::Pipeline/288',
+ path: '/root/test-job-artifacts/-/pipelines/288',
+ user: {
+ webPath: '/root',
+ avatarUrl:
+ 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ __typename: 'UserCore',
+ },
+ __typename: 'Pipeline',
+ },
+ stage: { name: 'test', __typename: 'CiStage' },
+ name: 'hello_world_delayed',
+ duration: 6,
+ finishedAt: '2021-08-30T20:36:12Z',
+ coverage: null,
+ retryable: true,
+ playable: true,
+ cancelable: false,
+ active: false,
+ stuck: false,
+ userPermissions: { readBuild: true, readJobArtifacts: true, __typename: 'JobPermissions' },
+ __typename: 'CiJob',
+};
+
+export const scheduledJob = {
+ artifacts: { nodes: [], __typename: 'CiJobArtifactConnection' },
+ allowFailure: false,
+ status: 'SCHEDULED',
+ scheduledAt: '2021-08-31T22:36:05Z',
+ manualJob: true,
+ triggered: null,
+ createdByTag: false,
+ detailedStatus: {
+ detailsPath: '/root/test-job-artifacts/-/jobs/1986',
+ group: 'scheduled',
+ icon: 'status_scheduled',
+ label: 'unschedule action',
+ text: 'delayed',
+ tooltip: 'delayed manual action (%{remainingTime})',
+ action: {
+ buttonTitle: 'Unschedule job',
+ icon: 'time-out',
+ method: 'post',
+ path: '/root/test-job-artifacts/-/jobs/1986/unschedule',
+ title: 'Unschedule',
+ __typename: 'StatusAction',
+ },
+ __typename: 'DetailedStatus',
+ },
+ id: 'gid://gitlab/Ci::Build/1986',
+ refName: 'main',
+ refPath: '/root/test-job-artifacts/-/commits/main',
+ tags: [],
+ shortSha: '75daf01b',
+ commitPath: '/root/test-job-artifacts/-/commit/75daf01b465e7eab5a04a315e44660c9a17c8055',
+ pipeline: {
+ id: 'gid://gitlab/Ci::Pipeline/290',
+ path: '/root/test-job-artifacts/-/pipelines/290',
+ user: {
+ webPath: '/root',
+ avatarUrl:
+ 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ __typename: 'UserCore',
+ },
+ __typename: 'Pipeline',
+ },
+ stage: { name: 'test', __typename: 'CiStage' },
+ name: 'hello_world_delayed',
+ duration: null,
+ finishedAt: null,
+ coverage: null,
+ retryable: false,
+ playable: true,
+ cancelable: false,
+ active: false,
+ stuck: false,
+ userPermissions: { readBuild: true, __typename: 'JobPermissions' },
+ __typename: 'CiJob',
+};
diff --git a/spec/frontend/learn_gitlab/track_learn_gitlab_spec.js b/spec/frontend/learn_gitlab/track_learn_gitlab_spec.js
deleted file mode 100644
index 3fb38a74c70..00000000000
--- a/spec/frontend/learn_gitlab/track_learn_gitlab_spec.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import { mockTracking } from 'helpers/tracking_helper';
-import trackLearnGitlab from '~/learn_gitlab/track_learn_gitlab';
-
-describe('trackTrialUserErrors', () => {
- let spy;
-
- describe('when an error is present', () => {
- beforeEach(() => {
- spy = mockTracking('projects:learn_gitlab_index', document.body, jest.spyOn);
- });
-
- it('tracks the error message', () => {
- trackLearnGitlab();
-
- expect(spy).toHaveBeenCalledWith('projects:learn_gitlab:index', 'page_init', {
- label: 'learn_gitlab',
- property: 'Growth::Activation::Experiment::LearnGitLabB',
- });
- });
- });
-});
diff --git a/spec/frontend/lib/apollo/instrumentation_link_spec.js b/spec/frontend/lib/apollo/instrumentation_link_spec.js
new file mode 100644
index 00000000000..ef686129257
--- /dev/null
+++ b/spec/frontend/lib/apollo/instrumentation_link_spec.js
@@ -0,0 +1,54 @@
+import { testApolloLink } from 'helpers/test_apollo_link';
+import { getInstrumentationLink, FEATURE_CATEGORY_HEADER } from '~/lib/apollo/instrumentation_link';
+
+const TEST_FEATURE_CATEGORY = 'foo_feature';
+
+describe('~/lib/apollo/instrumentation_link', () => {
+ const setFeatureCategory = (val) => {
+ window.gon.feature_category = val;
+ };
+
+ afterEach(() => {
+ getInstrumentationLink.cache.clear();
+ });
+
+ describe('getInstrumentationLink', () => {
+ describe('with no gon.feature_category', () => {
+ beforeEach(() => {
+ setFeatureCategory(null);
+ });
+
+ it('returns null', () => {
+ expect(getInstrumentationLink()).toBe(null);
+ });
+ });
+
+ describe('with gon.feature_category', () => {
+ beforeEach(() => {
+ setFeatureCategory(TEST_FEATURE_CATEGORY);
+ });
+
+ it('returns memoized apollo link', () => {
+ const result = getInstrumentationLink();
+
+ // expect.any(ApolloLink) doesn't work for some reason...
+ expect(result).toHaveProp('request');
+ expect(result).toBe(getInstrumentationLink());
+ });
+
+ it('adds a feature category header from the returned apollo link', async () => {
+ const defaultHeaders = { Authorization: 'foo' };
+ const operation = await testApolloLink(getInstrumentationLink(), {
+ context: { headers: defaultHeaders },
+ });
+
+ const { headers } = operation.getContext();
+
+ expect(headers).toEqual({
+ ...defaultHeaders,
+ [FEATURE_CATEGORY_HEADER]: TEST_FEATURE_CATEGORY,
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/lib/dompurify_spec.js b/spec/frontend/lib/dompurify_spec.js
index fa8dbb12a08..324441fa2c9 100644
--- a/spec/frontend/lib/dompurify_spec.js
+++ b/spec/frontend/lib/dompurify_spec.js
@@ -44,6 +44,31 @@ describe('~/lib/dompurify', () => {
expect(sanitize('<strong></strong>', { ALLOWED_TAGS: [] })).toBe('');
});
+ describe('includes default configuration', () => {
+ it('with empty config', () => {
+ const svgIcon = '<svg width="100"><use></use></svg>';
+ expect(sanitize(svgIcon, {})).toBe(svgIcon);
+ });
+
+ it('with valid config', () => {
+ expect(sanitize('<a href="#" data-remote="true"></a>', { ALLOWED_TAGS: ['a'] })).toBe(
+ '<a href="#"></a>',
+ );
+ });
+ });
+
+ it("doesn't sanitize local references", () => {
+ const htmlHref = `<svg><use href="#some-element"></use></svg>`;
+ const htmlXlink = `<svg><use xlink:href="#some-element"></use></svg>`;
+
+ expect(sanitize(htmlHref)).toBe(htmlHref);
+ expect(sanitize(htmlXlink)).toBe(htmlXlink);
+ });
+
+ it("doesn't sanitize gl-emoji", () => {
+ expect(sanitize('<p><gl-emoji>💯</gl-emoji></p>')).toBe('<p><gl-emoji>💯</gl-emoji></p>');
+ });
+
describe.each`
type | gon
${'root'} | ${rootGon}
diff --git a/spec/frontend/lib/logger/__snapshots__/hello_spec.js.snap b/spec/frontend/lib/logger/__snapshots__/hello_spec.js.snap
new file mode 100644
index 00000000000..791ec05befd
--- /dev/null
+++ b/spec/frontend/lib/logger/__snapshots__/hello_spec.js.snap
@@ -0,0 +1,16 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`~/lib/logger/hello logHello console logs a friendly hello message 1`] = `
+Array [
+ Array [
+ "%cWelcome to GitLab!%c
+
+Does this page need fixes or improvements? Open an issue or contribute a merge request to help make GitLab more lovable. At GitLab, everyone can contribute!
+
+🤠Contribute to GitLab: https://about.gitlab.com/community/contribute/
+🔎 Create a new GitLab issue: https://gitlab.com/gitlab-org/gitlab/-/issues/new",
+ "padding-top: 0.5em; font-size: 2em;",
+ "padding-bottom: 0.5em;",
+ ],
+]
+`;
diff --git a/spec/frontend/lib/logger/hello_deferred_spec.js b/spec/frontend/lib/logger/hello_deferred_spec.js
new file mode 100644
index 00000000000..3233cbff0dc
--- /dev/null
+++ b/spec/frontend/lib/logger/hello_deferred_spec.js
@@ -0,0 +1,17 @@
+import waitForPromises from 'helpers/wait_for_promises';
+import { logHello } from '~/lib/logger/hello';
+import { logHelloDeferred } from '~/lib/logger/hello_deferred';
+
+jest.mock('~/lib/logger/hello');
+
+describe('~/lib/logger/hello_deferred', () => {
+ it('dynamically imports and calls logHello', async () => {
+ logHelloDeferred();
+
+ expect(logHello).not.toHaveBeenCalled();
+
+ await waitForPromises();
+
+ expect(logHello).toHaveBeenCalled();
+ });
+});
diff --git a/spec/frontend/lib/logger/hello_spec.js b/spec/frontend/lib/logger/hello_spec.js
new file mode 100644
index 00000000000..39abe0e0dd0
--- /dev/null
+++ b/spec/frontend/lib/logger/hello_spec.js
@@ -0,0 +1,20 @@
+import { logHello } from '~/lib/logger/hello';
+
+describe('~/lib/logger/hello', () => {
+ let consoleLogSpy;
+
+ beforeEach(() => {
+ // We don't `mockImplementation` so we can validate there's no errors thrown
+ consoleLogSpy = jest.spyOn(console, 'log');
+ });
+
+ describe('logHello', () => {
+ it('console logs a friendly hello message', () => {
+ expect(consoleLogSpy).not.toHaveBeenCalled();
+
+ logHello();
+
+ expect(consoleLogSpy.mock.calls).toMatchSnapshot();
+ });
+ });
+});
diff --git a/spec/frontend/lib/logger/index_spec.js b/spec/frontend/lib/logger/index_spec.js
new file mode 100644
index 00000000000..9382fafe4de
--- /dev/null
+++ b/spec/frontend/lib/logger/index_spec.js
@@ -0,0 +1,23 @@
+import { logError, LOG_PREFIX } from '~/lib/logger';
+
+describe('~/lib/logger', () => {
+ let consoleErrorSpy;
+
+ beforeEach(() => {
+ consoleErrorSpy = jest.spyOn(console, 'error');
+ consoleErrorSpy.mockImplementation();
+ });
+
+ describe('logError', () => {
+ it('sends given message to console.error', () => {
+ const message = 'Lorem ipsum dolar sit amit';
+ const error = new Error('lorem ipsum');
+
+ expect(consoleErrorSpy).not.toHaveBeenCalled();
+
+ logError(message, error);
+
+ expect(consoleErrorSpy).toHaveBeenCalledWith(LOG_PREFIX, `${message}\n`, error);
+ });
+ });
+});
diff --git a/spec/frontend/lib/utils/accessor_spec.js b/spec/frontend/lib/utils/accessor_spec.js
index 752a88296e6..63497d795ce 100644
--- a/spec/frontend/lib/utils/accessor_spec.js
+++ b/spec/frontend/lib/utils/accessor_spec.js
@@ -6,60 +6,9 @@ describe('AccessorUtilities', () => {
const testError = new Error('test error');
- describe('isPropertyAccessSafe', () => {
- let base;
-
- it('should return `true` if access is safe', () => {
- base = {
- testProp: 'testProp',
- };
- expect(AccessorUtilities.isPropertyAccessSafe(base, 'testProp')).toBe(true);
- });
-
- it('should return `false` if access throws an error', () => {
- base = {
- get testProp() {
- throw testError;
- },
- };
-
- expect(AccessorUtilities.isPropertyAccessSafe(base, 'testProp')).toBe(false);
- });
-
- it('should return `false` if property is undefined', () => {
- base = {};
-
- expect(AccessorUtilities.isPropertyAccessSafe(base, 'testProp')).toBe(false);
- });
- });
-
- describe('isFunctionCallSafe', () => {
- const base = {};
-
- it('should return `true` if calling is safe', () => {
- base.func = () => {};
-
- expect(AccessorUtilities.isFunctionCallSafe(base, 'func')).toBe(true);
- });
-
- it('should return `false` if calling throws an error', () => {
- base.func = () => {
- throw new Error('test error');
- };
-
- expect(AccessorUtilities.isFunctionCallSafe(base, 'func')).toBe(false);
- });
-
- it('should return `false` if function is undefined', () => {
- base.func = undefined;
-
- expect(AccessorUtilities.isFunctionCallSafe(base, 'func')).toBe(false);
- });
- });
-
- describe('isLocalStorageAccessSafe', () => {
+ describe('canUseLocalStorage', () => {
it('should return `true` if access is safe', () => {
- expect(AccessorUtilities.isLocalStorageAccessSafe()).toBe(true);
+ expect(AccessorUtilities.canUseLocalStorage()).toBe(true);
});
it('should return `false` if access to .setItem isnt safe', () => {
@@ -67,19 +16,19 @@ describe('AccessorUtilities', () => {
throw testError;
});
- expect(AccessorUtilities.isLocalStorageAccessSafe()).toBe(false);
+ expect(AccessorUtilities.canUseLocalStorage()).toBe(false);
});
it('should set a test item if access is safe', () => {
- AccessorUtilities.isLocalStorageAccessSafe();
+ AccessorUtilities.canUseLocalStorage();
- expect(window.localStorage.setItem).toHaveBeenCalledWith('isLocalStorageAccessSafe', 'true');
+ expect(window.localStorage.setItem).toHaveBeenCalledWith('canUseLocalStorage', 'true');
});
it('should remove the test item if access is safe', () => {
- AccessorUtilities.isLocalStorageAccessSafe();
+ AccessorUtilities.canUseLocalStorage();
- expect(window.localStorage.removeItem).toHaveBeenCalledWith('isLocalStorageAccessSafe');
+ expect(window.localStorage.removeItem).toHaveBeenCalledWith('canUseLocalStorage');
});
});
});
diff --git a/spec/frontend/lib/utils/datetime/date_format_utility_spec.js b/spec/frontend/lib/utils/datetime/date_format_utility_spec.js
new file mode 100644
index 00000000000..942ba56196e
--- /dev/null
+++ b/spec/frontend/lib/utils/datetime/date_format_utility_spec.js
@@ -0,0 +1,120 @@
+import * as utils from '~/lib/utils/datetime/date_format_utility';
+
+describe('date_format_utility.js', () => {
+ describe('padWithZeros', () => {
+ it.each`
+ input | output
+ ${0} | ${'00'}
+ ${'1'} | ${'01'}
+ ${'10'} | ${'10'}
+ ${'100'} | ${'100'}
+ ${100} | ${'100'}
+ ${'a'} | ${'0a'}
+ ${'foo'} | ${'foo'}
+ `('properly pads $input to match $output', ({ input, output }) => {
+ expect(utils.padWithZeros(input)).toEqual([output]);
+ });
+
+ it('accepts multiple arguments', () => {
+ expect(utils.padWithZeros(1, '2', 3)).toEqual(['01', '02', '03']);
+ });
+
+ it('returns an empty array provided no argument', () => {
+ expect(utils.padWithZeros()).toEqual([]);
+ });
+ });
+
+ describe('stripTimezoneFromISODate', () => {
+ it.each`
+ input | expectedOutput
+ ${'2021-08-16T00:00:00Z'} | ${'2021-08-16T00:00:00'}
+ ${'2021-08-16T10:30:00+02:00'} | ${'2021-08-16T10:30:00'}
+ ${'2021-08-16T10:30:00-05:30'} | ${'2021-08-16T10:30:00'}
+ `('returns $expectedOutput when given $input', ({ input, expectedOutput }) => {
+ expect(utils.stripTimezoneFromISODate(input)).toBe(expectedOutput);
+ });
+
+ it('returns null if date is invalid', () => {
+ expect(utils.stripTimezoneFromISODate('Invalid date')).toBe(null);
+ });
+ });
+
+ describe('dateToYearMonthDate', () => {
+ it.each`
+ date | expectedOutput
+ ${new Date('2021-08-05')} | ${{ year: '2021', month: '08', day: '05' }}
+ ${new Date('2021-12-24')} | ${{ year: '2021', month: '12', day: '24' }}
+ `('returns $expectedOutput provided $date', ({ date, expectedOutput }) => {
+ expect(utils.dateToYearMonthDate(date)).toEqual(expectedOutput);
+ });
+
+ it('throws provided an invalid date', () => {
+ expect(() => utils.dateToYearMonthDate('Invalid date')).toThrow(
+ 'Argument should be a Date instance',
+ );
+ });
+ });
+
+ describe('timeToHoursMinutes', () => {
+ it.each`
+ time | expectedOutput
+ ${'23:12'} | ${{ hours: '23', minutes: '12' }}
+ ${'23:12'} | ${{ hours: '23', minutes: '12' }}
+ `('returns $expectedOutput provided $time', ({ time, expectedOutput }) => {
+ expect(utils.timeToHoursMinutes(time)).toEqual(expectedOutput);
+ });
+
+ it('throws provided an invalid time', () => {
+ expect(() => utils.timeToHoursMinutes('Invalid time')).toThrow('Invalid time provided');
+ });
+ });
+
+ describe('dateAndTimeToISOString', () => {
+ it('computes the date properly', () => {
+ expect(utils.dateAndTimeToISOString(new Date('2021-08-16'), '10:00')).toBe(
+ '2021-08-16T10:00:00.000Z',
+ );
+ });
+
+ it('computes the date properly with an offset', () => {
+ expect(utils.dateAndTimeToISOString(new Date('2021-08-16'), '10:00', '-04:00')).toBe(
+ '2021-08-16T10:00:00.000-04:00',
+ );
+ });
+
+ it('throws if date in invalid', () => {
+ expect(() => utils.dateAndTimeToISOString('Invalid date', '10:00')).toThrow(
+ 'Argument should be a Date instance',
+ );
+ });
+
+ it('throws if time in invalid', () => {
+ expect(() => utils.dateAndTimeToISOString(new Date('2021-08-16'), '')).toThrow(
+ 'Invalid time provided',
+ );
+ });
+
+ it('throws if offset is invalid', () => {
+ expect(() =>
+ utils.dateAndTimeToISOString(new Date('2021-08-16'), '10:00', 'not an offset'),
+ ).toThrow('Could not initialize date');
+ });
+ });
+
+ describe('dateToTimeInputValue', () => {
+ it.each`
+ input | expectedOutput
+ ${new Date('2021-08-16T10:00:00.000Z')} | ${'10:00'}
+ ${new Date('2021-08-16T22:30:00.000Z')} | ${'22:30'}
+ ${new Date('2021-08-16T22:30:00.000-03:00')} | ${'01:30'}
+ `('extracts $expectedOutput out of $input', ({ input, expectedOutput }) => {
+ expect(utils.dateToTimeInputValue(input)).toBe(expectedOutput);
+ });
+
+ it('throws if date is invalid', () => {
+ expect(() => utils.dateToTimeInputValue('Invalid date')).toThrow(
+ 'Argument should be a Date instance',
+ );
+ });
+ });
+});
diff --git a/spec/frontend/lib/utils/dom_utils_spec.js b/spec/frontend/lib/utils/dom_utils_spec.js
index 7c4c20e651f..cb8b1c7ca9a 100644
--- a/spec/frontend/lib/utils/dom_utils_spec.js
+++ b/spec/frontend/lib/utils/dom_utils_spec.js
@@ -5,6 +5,7 @@ import {
parseBooleanDataAttributes,
isElementVisible,
isElementHidden,
+ getParents,
} from '~/lib/utils/dom_utils';
const TEST_MARGIN = 5;
@@ -193,4 +194,18 @@ describe('DOM Utils', () => {
});
},
);
+
+ describe('getParents', () => {
+ it('gets all parents of an element', () => {
+ const el = document.createElement('div');
+ el.innerHTML = '<p><span><strong><mark>hello world';
+
+ expect(getParents(el.querySelector('mark'))).toEqual([
+ el.querySelector('strong'),
+ el.querySelector('span'),
+ el.querySelector('p'),
+ el,
+ ]);
+ });
+ });
});
diff --git a/spec/frontend/lib/utils/text_markdown_spec.js b/spec/frontend/lib/utils/text_markdown_spec.js
index beedb9b2eba..acbf1a975b8 100644
--- a/spec/frontend/lib/utils/text_markdown_spec.js
+++ b/spec/frontend/lib/utils/text_markdown_spec.js
@@ -88,6 +88,25 @@ describe('init markdown', () => {
expect(textArea.value).toEqual(`${initialValue}\n- `);
});
+ it('unescapes new line characters', () => {
+ const initialValue = '';
+
+ textArea.value = initialValue;
+ textArea.selectionStart = 0;
+ textArea.selectionEnd = 0;
+
+ insertMarkdownText({
+ textArea,
+ text: textArea.value,
+ tag: '```suggestion:-0+0\n{text}\n```',
+ blockTag: true,
+ selected: '# Does not parse the %br currently.',
+ wrap: false,
+ });
+
+ expect(textArea.value).toContain('# Does not parse the \\n currently.');
+ });
+
it('inserts the tag on the same line if the current line only contains spaces', () => {
const initialValue = ' ';
diff --git a/spec/frontend/lib/utils/url_utility_spec.js b/spec/frontend/lib/utils/url_utility_spec.js
index c8ac7ffc9d9..6f186ba3227 100644
--- a/spec/frontend/lib/utils/url_utility_spec.js
+++ b/spec/frontend/lib/utils/url_utility_spec.js
@@ -645,29 +645,6 @@ describe('URL utility', () => {
});
});
- describe('urlParamsToObject', () => {
- it('parses path for label with trailing +', () => {
- // eslint-disable-next-line import/no-deprecated
- expect(urlUtils.urlParamsToObject('label_name[]=label%2B', {})).toEqual({
- label_name: ['label+'],
- });
- });
-
- it('parses path for milestone with trailing +', () => {
- // eslint-disable-next-line import/no-deprecated
- expect(urlUtils.urlParamsToObject('milestone_title=A%2B', {})).toEqual({
- milestone_title: 'A+',
- });
- });
-
- it('parses path for search terms with spaces', () => {
- // eslint-disable-next-line import/no-deprecated
- expect(urlUtils.urlParamsToObject('search=two+words', {})).toEqual({
- search: 'two words',
- });
- });
- });
-
describe('queryToObject', () => {
it.each`
case | query | options | result
diff --git a/spec/frontend/members/components/modals/leave_modal_spec.js b/spec/frontend/members/components/modals/leave_modal_spec.js
index ea9eb7bf923..1dc913e5c78 100644
--- a/spec/frontend/members/components/modals/leave_modal_spec.js
+++ b/spec/frontend/members/components/modals/leave_modal_spec.js
@@ -99,10 +99,14 @@ describe('LeaveModal', () => {
});
});
- it("does NOT display oncall schedules list when member's user is NOT a part of on-call schedules ", () => {
+ it("does NOT display oncall schedules list when member's user is NOT a part of on-call schedules ", async () => {
+ wrapper.destroy();
+
const memberWithoutOncallSchedules = cloneDeep(member);
- delete (memberWithoutOncallSchedules, 'user.oncallSchedules');
+ delete memberWithoutOncallSchedules.user.oncallSchedules;
createComponent({ member: memberWithoutOncallSchedules });
+ await nextTick();
+
expect(findOncallSchedulesList().exists()).toBe(false);
});
});
diff --git a/spec/frontend/merge_request_tabs_spec.js b/spec/frontend/merge_request_tabs_spec.js
index 23e9bf8b447..ced9b71125b 100644
--- a/spec/frontend/merge_request_tabs_spec.js
+++ b/spec/frontend/merge_request_tabs_spec.js
@@ -34,6 +34,44 @@ describe('MergeRequestTabs', () => {
gl.mrWidget = {};
});
+ describe('clickTab', () => {
+ let params;
+
+ beforeEach(() => {
+ document.documentElement.scrollTop = 100;
+
+ params = {
+ metaKey: false,
+ ctrlKey: false,
+ which: 1,
+ stopImmediatePropagation() {},
+ preventDefault() {},
+ currentTarget: {
+ getAttribute(attr) {
+ return attr === 'href' ? 'a/tab/url' : null;
+ },
+ },
+ };
+ });
+
+ it("stores the current scroll position if there's an active tab", () => {
+ testContext.class.currentTab = 'someTab';
+
+ testContext.class.clickTab(params);
+
+ expect(testContext.class.scrollPositions.someTab).toBe(100);
+ });
+
+ it("doesn't store a scroll position if there's no active tab", () => {
+ // this happens on first load, and we just don't want to store empty values in the `null` property
+ testContext.class.currentTab = null;
+
+ testContext.class.clickTab(params);
+
+ expect(testContext.class.scrollPositions).toEqual({});
+ });
+ });
+
describe('opensInNewTab', () => {
const windowTarget = '_blank';
let clickTabParams;
@@ -258,6 +296,7 @@ describe('MergeRequestTabs', () => {
beforeEach(() => {
jest.spyOn(mainContent, 'getBoundingClientRect').mockReturnValue({ top: 10 });
jest.spyOn(tabContent, 'getBoundingClientRect').mockReturnValue({ top: 100 });
+ jest.spyOn(window, 'scrollTo').mockImplementation(() => {});
jest.spyOn(document, 'querySelector').mockImplementation((selector) => {
return selector === '.content-wrapper' ? mainContent : tabContent;
});
@@ -267,8 +306,6 @@ describe('MergeRequestTabs', () => {
it('calls window scrollTo with options if document has scrollBehavior', () => {
document.documentElement.style.scrollBehavior = '';
- jest.spyOn(window, 'scrollTo').mockImplementation(() => {});
-
testContext.class.tabShown('commits', 'foobar');
expect(window.scrollTo.mock.calls[0][0]).toEqual({ top: 39, behavior: 'smooth' });
@@ -276,11 +313,50 @@ describe('MergeRequestTabs', () => {
it('calls window scrollTo with two args if document does not have scrollBehavior', () => {
jest.spyOn(document.documentElement, 'style', 'get').mockReturnValue({});
- jest.spyOn(window, 'scrollTo').mockImplementation(() => {});
testContext.class.tabShown('commits', 'foobar');
expect(window.scrollTo.mock.calls[0]).toEqual([0, 39]);
});
+
+ describe('when switching tabs', () => {
+ const SCROLL_TOP = 100;
+
+ beforeAll(() => {
+ jest.useFakeTimers();
+ });
+
+ beforeEach(() => {
+ jest.spyOn(window, 'scrollTo').mockImplementation(() => {});
+ testContext.class.mergeRequestTabs = document.createElement('div');
+ testContext.class.mergeRequestTabPanes = document.createElement('div');
+ testContext.class.currentTab = 'tab';
+ testContext.class.scrollPositions = { newTab: SCROLL_TOP };
+ });
+
+ afterAll(() => {
+ jest.useRealTimers();
+ });
+
+ it('scrolls to the stored position, if one is stored', () => {
+ testContext.class.tabShown('newTab');
+
+ jest.advanceTimersByTime(250);
+
+ expect(window.scrollTo.mock.calls[0][0]).toEqual({
+ top: SCROLL_TOP,
+ left: 0,
+ behavior: 'auto',
+ });
+ });
+
+ it('scrolls to 0, if no position is stored', () => {
+ testContext.class.tabShown('unknownTab');
+
+ jest.advanceTimersByTime(250);
+
+ expect(window.scrollTo.mock.calls[0][0]).toEqual({ top: 0, left: 0, behavior: 'auto' });
+ });
+ });
});
});
diff --git a/spec/frontend/milestones/stores/mutations_spec.js b/spec/frontend/milestones/stores/mutations_spec.js
index 91b2acf23c5..a53d6ca5de1 100644
--- a/spec/frontend/milestones/stores/mutations_spec.js
+++ b/spec/frontend/milestones/stores/mutations_spec.js
@@ -174,6 +174,35 @@ describe('Milestones combobox Vuex store mutations', () => {
});
});
+ it('falls back to the length of list if pagination headers are missing', () => {
+ const response = {
+ data: [
+ {
+ title: 'v0.1',
+ },
+ {
+ title: 'v0.2',
+ },
+ ],
+ headers: {},
+ };
+
+ mutations[types.RECEIVE_PROJECT_MILESTONES_SUCCESS](state, response);
+
+ expect(state.matches.projectMilestones).toEqual({
+ list: [
+ {
+ title: 'v0.1',
+ },
+ {
+ title: 'v0.2',
+ },
+ ],
+ error: null,
+ totalCount: 2,
+ });
+ });
+
describe(`${types.RECEIVE_PROJECT_MILESTONES_ERROR}`, () => {
it('updates state.matches.projectMilestones to an empty state with the error object', () => {
const error = new Error('Something went wrong!');
@@ -227,6 +256,35 @@ describe('Milestones combobox Vuex store mutations', () => {
});
});
+ it('falls back to the length of data received if pagination headers are missing', () => {
+ const response = {
+ data: [
+ {
+ title: 'group-0.1',
+ },
+ {
+ title: 'group-0.2',
+ },
+ ],
+ headers: {},
+ };
+
+ mutations[types.RECEIVE_GROUP_MILESTONES_SUCCESS](state, response);
+
+ expect(state.matches.groupMilestones).toEqual({
+ list: [
+ {
+ title: 'group-0.1',
+ },
+ {
+ title: 'group-0.2',
+ },
+ ],
+ error: null,
+ totalCount: 2,
+ });
+ });
+
describe(`${types.RECEIVE_GROUP_MILESTONES_ERROR}`, () => {
it('updates state.matches.groupMilestones to an empty state with the error object', () => {
const error = new Error('Something went wrong!');
diff --git a/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap b/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap
index 08f9e07244f..05538dbaeee 100644
--- a/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap
+++ b/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap
@@ -36,11 +36,15 @@ exports[`Dashboard template matches the default snapshot 1`] = `
<gl-dropdown-stub
category="primary"
class="flex-grow-1"
+ clearalltext="Clear all"
data-qa-selector="environments_dropdown"
headertext=""
hideheaderborder="true"
+ highlighteditemstitle="Selected"
+ highlighteditemstitleclass="gl-px-5"
id="monitor-environments-dropdown"
menu-class="monitor-environment-dropdown-menu"
+ showhighlighteditemstitle="true"
size="medium"
text="production"
toggleclass="dropdown-menu-toggle"
diff --git a/spec/frontend/notebook/cells/markdown_spec.js b/spec/frontend/notebook/cells/markdown_spec.js
index deeee5d6589..707efa21528 100644
--- a/spec/frontend/notebook/cells/markdown_spec.js
+++ b/spec/frontend/notebook/cells/markdown_spec.js
@@ -1,3 +1,4 @@
+import { mount } from '@vue/test-utils';
import katex from 'katex';
import Vue from 'vue';
import MarkdownComponent from '~/notebook/cells/markdown.vue';
@@ -6,6 +7,28 @@ const Component = Vue.extend(MarkdownComponent);
window.katex = katex;
+function buildCellComponent(cell, relativePath = '') {
+ return mount(Component, {
+ propsData: {
+ cell,
+ },
+ provide: {
+ relativeRawPath: relativePath,
+ },
+ }).vm;
+}
+
+function buildMarkdownComponent(markdownContent, relativePath = '') {
+ return buildCellComponent(
+ {
+ cell_type: 'markdown',
+ metadata: {},
+ source: markdownContent,
+ },
+ relativePath,
+ );
+}
+
describe('Markdown component', () => {
let vm;
let cell;
@@ -17,12 +40,7 @@ describe('Markdown component', () => {
// eslint-disable-next-line prefer-destructuring
cell = json.cells[1];
- vm = new Component({
- propsData: {
- cell,
- },
- });
- vm.$mount();
+ vm = buildCellComponent(cell);
return vm.$nextTick();
});
@@ -61,17 +79,36 @@ describe('Markdown component', () => {
expect(findLink().getAttribute('data-type')).toBe(null);
});
+ describe('When parsing images', () => {
+ it.each([
+ [
+ 'for relative images in root folder, it does',
+ '![](local_image.png)\n',
+ 'src="/raw/local_image',
+ ],
+ [
+ 'for relative images in child folders, it does',
+ '![](data/local_image.png)\n',
+ 'src="/raw/data',
+ ],
+ ["for embedded images, it doesn't", '![](data:image/jpeg;base64)\n', 'src="data:'],
+ ["for images urls, it doesn't", '![](http://image.png)\n', 'src="http:'],
+ ])('%s', async ([testMd, mustContain]) => {
+ vm = buildMarkdownComponent([testMd], '/raw/');
+
+ await vm.$nextTick();
+
+ expect(vm.$el.innerHTML).toContain(mustContain);
+ });
+ });
+
describe('tables', () => {
beforeEach(() => {
json = getJSONFixture('blob/notebook/markdown-table.json');
});
it('renders images and text', () => {
- vm = new Component({
- propsData: {
- cell: json.cells[0],
- },
- }).$mount();
+ vm = buildCellComponent(json.cells[0]);
return vm.$nextTick().then(() => {
const images = vm.$el.querySelectorAll('img');
@@ -102,48 +139,28 @@ describe('Markdown component', () => {
});
it('renders multi-line katex', async () => {
- vm = new Component({
- propsData: {
- cell: json.cells[0],
- },
- }).$mount();
+ vm = buildCellComponent(json.cells[0]);
await vm.$nextTick();
expect(vm.$el.querySelector('.katex')).not.toBeNull();
});
it('renders inline katex', async () => {
- vm = new Component({
- propsData: {
- cell: json.cells[1],
- },
- }).$mount();
+ vm = buildCellComponent(json.cells[1]);
await vm.$nextTick();
expect(vm.$el.querySelector('p:first-child .katex')).not.toBeNull();
});
it('renders multiple inline katex', async () => {
- vm = new Component({
- propsData: {
- cell: json.cells[1],
- },
- }).$mount();
+ vm = buildCellComponent(json.cells[1]);
await vm.$nextTick();
expect(vm.$el.querySelectorAll('p:nth-child(2) .katex')).toHaveLength(4);
});
it('output cell in case of katex error', async () => {
- vm = new Component({
- propsData: {
- cell: {
- cell_type: 'markdown',
- metadata: {},
- source: ['Some invalid $a & b$ inline formula $b & c$\n', '\n'],
- },
- },
- }).$mount();
+ vm = buildMarkdownComponent(['Some invalid $a & b$ inline formula $b & c$\n', '\n']);
await vm.$nextTick();
// expect one paragraph with no katex formula in it
@@ -152,15 +169,10 @@ describe('Markdown component', () => {
});
it('output cell and render remaining formula in case of katex error', async () => {
- vm = new Component({
- propsData: {
- cell: {
- cell_type: 'markdown',
- metadata: {},
- source: ['An invalid $a & b$ inline formula and a vaild one $b = c$\n', '\n'],
- },
- },
- }).$mount();
+ vm = buildMarkdownComponent([
+ 'An invalid $a & b$ inline formula and a vaild one $b = c$\n',
+ '\n',
+ ]);
await vm.$nextTick();
// expect one paragraph with no katex formula in it
@@ -169,15 +181,7 @@ describe('Markdown component', () => {
});
it('renders math formula in list object', async () => {
- vm = new Component({
- propsData: {
- cell: {
- cell_type: 'markdown',
- metadata: {},
- source: ["- list with inline $a=2$ inline formula $a' + b = c$\n", '\n'],
- },
- },
- }).$mount();
+ vm = buildMarkdownComponent(["- list with inline $a=2$ inline formula $a' + b = c$\n", '\n']);
await vm.$nextTick();
// expect one list with a katex formula in it
@@ -186,15 +190,7 @@ describe('Markdown component', () => {
});
it("renders math formula with tick ' in it", async () => {
- vm = new Component({
- propsData: {
- cell: {
- cell_type: 'markdown',
- metadata: {},
- source: ["- list with inline $a=2$ inline formula $a' + b = c$\n", '\n'],
- },
- },
- }).$mount();
+ vm = buildMarkdownComponent(["- list with inline $a=2$ inline formula $a' + b = c$\n", '\n']);
await vm.$nextTick();
// expect one list with a katex formula in it
@@ -203,15 +199,7 @@ describe('Markdown component', () => {
});
it('renders math formula with less-than-operator < in it', async () => {
- vm = new Component({
- propsData: {
- cell: {
- cell_type: 'markdown',
- metadata: {},
- source: ['- list with inline $a=2$ inline formula $a + b < c$\n', '\n'],
- },
- },
- }).$mount();
+ vm = buildMarkdownComponent(['- list with inline $a=2$ inline formula $a + b < c$\n', '\n']);
await vm.$nextTick();
// expect one list with a katex formula in it
@@ -220,15 +208,7 @@ describe('Markdown component', () => {
});
it('renders math formula with greater-than-operator > in it', async () => {
- vm = new Component({
- propsData: {
- cell: {
- cell_type: 'markdown',
- metadata: {},
- source: ['- list with inline $a=2$ inline formula $a + b > c$\n', '\n'],
- },
- },
- }).$mount();
+ vm = buildMarkdownComponent(['- list with inline $a=2$ inline formula $a + b > c$\n', '\n']);
await vm.$nextTick();
// expect one list with a katex formula in it
diff --git a/spec/frontend/notebook/cells/output/html_sanitize_fixtures.js b/spec/frontend/notebook/cells/output/html_sanitize_fixtures.js
index 0b585ab860b..803ac4a219d 100644
--- a/spec/frontend/notebook/cells/output/html_sanitize_fixtures.js
+++ b/spec/frontend/notebook/cells/output/html_sanitize_fixtures.js
@@ -90,7 +90,8 @@ export default [
' </g>\n',
'</svg>',
].join(),
- output: '<svg height="115.02pt" id="svg2"',
+ output:
+ '<svg xmlns="http://www.w3.org/2000/svg" width="388.84pt" version="1.0" id="svg2" height="115.02pt">',
},
],
];
diff --git a/spec/frontend/notebook/index_spec.js b/spec/frontend/notebook/index_spec.js
index 945af08e4d5..4d0dacaf37e 100644
--- a/spec/frontend/notebook/index_spec.js
+++ b/spec/frontend/notebook/index_spec.js
@@ -1,3 +1,4 @@
+import { mount } from '@vue/test-utils';
import Vue from 'vue';
import Notebook from '~/notebook/index.vue';
@@ -13,14 +14,16 @@ describe('Notebook component', () => {
jsonWithWorksheet = getJSONFixture('blob/notebook/worksheets.json');
});
+ function buildComponent(notebook) {
+ return mount(Component, {
+ propsData: { notebook, codeCssClass: 'js-code-class' },
+ provide: { relativeRawPath: '' },
+ }).vm;
+ }
+
describe('without JSON', () => {
beforeEach((done) => {
- vm = new Component({
- propsData: {
- notebook: {},
- },
- });
- vm.$mount();
+ vm = buildComponent({});
setImmediate(() => {
done();
@@ -34,13 +37,7 @@ describe('Notebook component', () => {
describe('with JSON', () => {
beforeEach((done) => {
- vm = new Component({
- propsData: {
- notebook: json,
- codeCssClass: 'js-code-class',
- },
- });
- vm.$mount();
+ vm = buildComponent(json);
setImmediate(() => {
done();
@@ -66,13 +63,7 @@ describe('Notebook component', () => {
describe('with worksheets', () => {
beforeEach((done) => {
- vm = new Component({
- propsData: {
- notebook: jsonWithWorksheet,
- codeCssClass: 'js-code-class',
- },
- });
- vm.$mount();
+ vm = buildComponent(jsonWithWorksheet);
setImmediate(() => {
done();
diff --git a/spec/frontend/notes/components/comment_form_spec.js b/spec/frontend/notes/components/comment_form_spec.js
index bb79b43205b..c3a51c51de0 100644
--- a/spec/frontend/notes/components/comment_form_spec.js
+++ b/spec/frontend/notes/components/comment_form_spec.js
@@ -10,6 +10,7 @@ import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
import CommentForm from '~/notes/components/comment_form.vue';
+import CommentTypeDropdown from '~/notes/components/comment_type_dropdown.vue';
import * as constants from '~/notes/constants';
import eventHub from '~/notes/event_hub';
import { COMMENT_FORM } from '~/notes/i18n';
@@ -33,8 +34,8 @@ describe('issue_comment_form component', () => {
const findAddToReviewButton = () => wrapper.findByTestId('add-to-review-button');
const findAddCommentNowButton = () => wrapper.findByTestId('add-comment-now-button');
const findConfidentialNoteCheckbox = () => wrapper.findByTestId('confidential-note-checkbox');
- const findCommentGlDropdown = () => wrapper.findByTestId('comment-button');
- const findCommentButton = () => findCommentGlDropdown().find('button');
+ const findCommentTypeDropdown = () => wrapper.findComponent(CommentTypeDropdown);
+ const findCommentButton = () => findCommentTypeDropdown().find('button');
const findErrorAlerts = () => wrapper.findAllComponents(GlAlert).wrappers;
async function clickCommentButton({ waitForComponent = true, waitForNetwork = true } = {}) {
@@ -381,7 +382,7 @@ describe('issue_comment_form component', () => {
it('should render comment button as disabled', () => {
mountComponent();
- expect(findCommentGlDropdown().props('disabled')).toBe(true);
+ expect(findCommentTypeDropdown().props('disabled')).toBe(true);
});
it('should enable comment button if it has note', async () => {
@@ -389,7 +390,7 @@ describe('issue_comment_form component', () => {
await wrapper.setData({ note: 'Foo' });
- expect(findCommentGlDropdown().props('disabled')).toBe(false);
+ expect(findCommentTypeDropdown().props('disabled')).toBe(false);
});
it('should update buttons texts when it has note', () => {
@@ -624,7 +625,7 @@ describe('issue_comment_form component', () => {
it('when no drafts exist, should not render', () => {
mountComponent();
- expect(findCommentGlDropdown().exists()).toBe(true);
+ expect(findCommentTypeDropdown().exists()).toBe(true);
expect(findAddToReviewButton().exists()).toBe(false);
expect(findAddCommentNowButton().exists()).toBe(false);
});
@@ -637,7 +638,7 @@ describe('issue_comment_form component', () => {
it('should render', () => {
mountComponent();
- expect(findCommentGlDropdown().exists()).toBe(false);
+ expect(findCommentTypeDropdown().exists()).toBe(false);
expect(findAddToReviewButton().exists()).toBe(true);
expect(findAddCommentNowButton().exists()).toBe(true);
});
diff --git a/spec/frontend/notes/components/comment_type_dropdown_spec.js b/spec/frontend/notes/components/comment_type_dropdown_spec.js
new file mode 100644
index 00000000000..5e1cb813369
--- /dev/null
+++ b/spec/frontend/notes/components/comment_type_dropdown_spec.js
@@ -0,0 +1,64 @@
+import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
+import { mount } from '@vue/test-utils';
+import { extendedWrapper } from 'helpers/vue_test_utils_helper';
+import CommentTypeDropdown from '~/notes/components/comment_type_dropdown.vue';
+import * as constants from '~/notes/constants';
+import { COMMENT_FORM } from '~/notes/i18n';
+
+describe('CommentTypeDropdown component', () => {
+ let wrapper;
+
+ const findCommentGlDropdown = () => wrapper.findComponent(GlDropdown);
+ const findCommentDropdownOption = () => wrapper.findAllComponents(GlDropdownItem).at(0);
+ const findDiscussionDropdownOption = () => wrapper.findAllComponents(GlDropdownItem).at(1);
+
+ const mountComponent = ({ props = {} } = {}) => {
+ wrapper = extendedWrapper(
+ mount(CommentTypeDropdown, {
+ propsData: {
+ noteableDisplayName: 'issue',
+ noteType: constants.COMMENT,
+ ...props,
+ },
+ }),
+ );
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('Should label action button "Comment" and correct dropdown item checked when selected', () => {
+ mountComponent({ props: { noteType: constants.COMMENT } });
+
+ expect(findCommentGlDropdown().props()).toMatchObject({ text: COMMENT_FORM.comment });
+ expect(findCommentDropdownOption().props()).toMatchObject({ isChecked: true });
+ expect(findDiscussionDropdownOption().props()).toMatchObject({ isChecked: false });
+ });
+
+ it('Should label action button "Start Thread" and correct dropdown item option checked when selected', () => {
+ mountComponent({ props: { noteType: constants.DISCUSSION } });
+
+ expect(findCommentGlDropdown().props()).toMatchObject({ text: COMMENT_FORM.startThread });
+ expect(findCommentDropdownOption().props()).toMatchObject({ isChecked: false });
+ expect(findDiscussionDropdownOption().props()).toMatchObject({ isChecked: true });
+ });
+
+ it('Should emit `change` event when clicking on an alternate dropdown option', () => {
+ mountComponent({ props: { noteType: constants.DISCUSSION } });
+
+ findCommentDropdownOption().vm.$emit('click');
+ findDiscussionDropdownOption().vm.$emit('click');
+
+ expect(wrapper.emitted('change')[0]).toEqual([constants.COMMENT]);
+ expect(wrapper.emitted('change').length).toEqual(1);
+ });
+
+ it('Should emit `click` event when clicking on the action button', () => {
+ mountComponent({ props: { noteType: constants.DISCUSSION } });
+
+ findCommentGlDropdown().vm.$emit('click');
+
+ expect(wrapper.emitted('click').length > 0).toBe(true);
+ });
+});
diff --git a/spec/frontend/notes/deprecated_notes_spec.js b/spec/frontend/notes/deprecated_notes_spec.js
new file mode 100644
index 00000000000..34623f8aa13
--- /dev/null
+++ b/spec/frontend/notes/deprecated_notes_spec.js
@@ -0,0 +1,997 @@
+/* eslint-disable import/no-commonjs, no-new */
+
+import MockAdapter from 'axios-mock-adapter';
+import $ from 'jquery';
+import '~/behaviors/markdown/render_gfm';
+import { createSpyObj } from 'helpers/jest_helpers';
+import { TEST_HOST } from 'helpers/test_constants';
+import { setTestTimeoutOnce } from 'helpers/timeout';
+import axios from '~/lib/utils/axios_utils';
+import * as urlUtility from '~/lib/utils/url_utility';
+
+// These must be imported synchronously because they pull dependencies
+// from the DOM.
+window.jQuery = $;
+require('autosize');
+require('~/commons');
+const Notes = require('~/deprecated_notes').default;
+
+const FLASH_TYPE_ALERT = 'alert';
+const NOTES_POST_PATH = /(.*)\/notes\?html=true$/;
+const fixture = 'snippets/show.html';
+let mockAxios;
+
+window.project_uploads_path = `${TEST_HOST}/uploads`;
+window.gon = window.gon || {};
+window.gl = window.gl || {};
+gl.utils = gl.utils || {};
+gl.utils.disableButtonIfEmptyField = () => {};
+
+// the following test is unreliable and failing in main 2-3 times a day
+// see https://gitlab.com/gitlab-org/gitlab/issues/206906#note_290602581
+// eslint-disable-next-line jest/no-disabled-tests
+describe.skip('Old Notes (~/deprecated_notes.js)', () => {
+ beforeEach(() => {
+ loadFixtures(fixture);
+
+ // Re-declare this here so that test_setup.js#beforeEach() doesn't
+ // overwrite it.
+ mockAxios = new MockAdapter(axios);
+
+ $.ajax = () => {
+ throw new Error('$.ajax should not be called through!');
+ };
+
+ // These jQuery+DOM tests are super flaky so increase the timeout to avoid
+ // random failures.
+ // It seems that running tests in parallel increases failure rate.
+ jest.setTimeout(4000);
+ setTestTimeoutOnce(4000);
+ });
+
+ afterEach(() => {
+ // The Notes component sets a polling interval. Clear it after every run.
+ // Make sure to use jest.runOnlyPendingTimers() instead of runAllTimers().
+ jest.clearAllTimers();
+
+ return axios.waitForAll().finally(() => mockAxios.restore());
+ });
+
+ it('loads the Notes class into the DOM', () => {
+ expect(Notes).toBeDefined();
+ expect(Notes.name).toBe('Notes');
+ });
+
+ describe('addBinding', () => {
+ it('calls postComment when comment button is clicked', () => {
+ jest.spyOn(Notes.prototype, 'postComment');
+
+ new Notes('', []);
+ $('.js-comment-button').click();
+ expect(Notes.prototype.postComment).toHaveBeenCalled();
+ });
+ });
+
+ describe('task lists', () => {
+ beforeEach(() => {
+ mockAxios.onAny().reply(200, {});
+ new Notes('', []);
+ });
+
+ it('modifies the Markdown field', () => {
+ const changeEvent = document.createEvent('HTMLEvents');
+ changeEvent.initEvent('change', true, true);
+ $('input[type=checkbox]').attr('checked', true)[0].dispatchEvent(changeEvent);
+
+ expect($('.js-task-list-field.original-task-list').val()).toBe('- [x] Task List Item');
+ });
+
+ it('submits an ajax request on tasklist:changed', () => {
+ jest.spyOn(axios, 'patch');
+
+ const lineNumber = 8;
+ const lineSource = '- [ ] item 8';
+ const index = 3;
+ const checked = true;
+
+ $('.js-task-list-container').trigger({
+ type: 'tasklist:changed',
+ detail: { lineNumber, lineSource, index, checked },
+ });
+
+ expect(axios.patch).toHaveBeenCalledWith(undefined, {
+ note: {
+ note: '',
+ lock_version: undefined,
+ update_task: { index, checked, line_number: lineNumber, line_source: lineSource },
+ },
+ });
+ });
+ });
+
+ describe('comments', () => {
+ let notes;
+ let autosizeSpy;
+ let textarea;
+
+ beforeEach(() => {
+ notes = new Notes('', []);
+
+ textarea = $('.js-note-text');
+ textarea.data('autosave', {
+ reset: () => {},
+ });
+ autosizeSpy = jest.fn();
+ $(textarea).on('autosize:update', autosizeSpy);
+
+ jest.spyOn(notes, 'renderNote');
+
+ $('.js-comment-button').on('click', (e) => {
+ const $form = $(this);
+ e.preventDefault();
+ notes.addNote($form, {});
+ notes.reenableTargetFormSubmitButton(e);
+ notes.resetMainTargetForm(e);
+ });
+ });
+
+ it('autosizes after comment submission', () => {
+ textarea.text('This is an example comment note');
+ expect(autosizeSpy).not.toHaveBeenCalled();
+ $('.js-comment-button').click();
+ expect(autosizeSpy).toHaveBeenCalled();
+ });
+
+ it('should not place escaped text in the comment box in case of error', () => {
+ const deferred = $.Deferred();
+ jest.spyOn($, 'ajax').mockReturnValueOnce(deferred);
+ $(textarea).text('A comment with `markup`.');
+
+ deferred.reject();
+ $('.js-comment-button').click();
+
+ expect($(textarea).val()).toBe('A comment with `markup`.');
+
+ $.ajax.mockRestore();
+ expect($.ajax.mock).toBeUndefined();
+ });
+ });
+
+ describe('updateNote', () => {
+ let notes;
+ let noteEntity;
+ let $notesContainer;
+
+ beforeEach(() => {
+ notes = new Notes('', []);
+ window.gon.current_username = 'root';
+ window.gon.current_user_fullname = 'Administrator';
+ const sampleComment = 'foo';
+ noteEntity = {
+ id: 1234,
+ html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
+ <div class="note-text">${sampleComment}</div>
+ </li>`,
+ note: sampleComment,
+ valid: true,
+ };
+
+ $notesContainer = $('ul.main-notes-list');
+ const $form = $('form.js-main-target-form');
+ $form.find('textarea.js-note-text').val(sampleComment);
+
+ mockAxios.onPost(NOTES_POST_PATH).reply(200, noteEntity);
+ });
+
+ it('updates note and resets edit form', () => {
+ jest.spyOn(notes, 'revertNoteEditForm');
+ jest.spyOn(notes, 'setupNewNote');
+
+ $('.js-comment-button').click();
+
+ const $targetNote = $notesContainer.find(`#note_${noteEntity.id}`);
+ const updatedNote = { ...noteEntity };
+ updatedNote.note = 'bar';
+ notes.updateNote(updatedNote, $targetNote);
+
+ expect(notes.revertNoteEditForm).toHaveBeenCalledWith($targetNote);
+ expect(notes.setupNewNote).toHaveBeenCalled();
+ });
+ });
+
+ describe('updateNoteTargetSelector', () => {
+ const hash = 'note_foo';
+ let $note;
+
+ beforeEach(() => {
+ $note = $(`<div id="${hash}"></div>`);
+ jest.spyOn($note, 'filter');
+ jest.spyOn($note, 'toggleClass');
+ });
+
+ // urlUtility is a dependency of the notes module. Its getLocatinHash() method should be called internally.
+
+ it('sets target when hash matches', () => {
+ jest.spyOn(urlUtility, 'getLocationHash').mockReturnValueOnce(hash);
+
+ Notes.updateNoteTargetSelector($note);
+
+ expect(urlUtility.getLocationHash).toHaveBeenCalled();
+ expect($note.filter).toHaveBeenCalledWith(`#${hash}`);
+ expect($note.toggleClass).toHaveBeenCalledWith('target', true);
+ });
+
+ it('unsets target when hash does not match', () => {
+ jest.spyOn(urlUtility, 'getLocationHash').mockReturnValueOnce('note_doesnotexist');
+
+ Notes.updateNoteTargetSelector($note);
+
+ expect(urlUtility.getLocationHash).toHaveBeenCalled();
+ expect($note.toggleClass).toHaveBeenCalledWith('target', false);
+ });
+
+ it('unsets target when there is not a hash fragment anymore', () => {
+ jest.spyOn(urlUtility, 'getLocationHash').mockReturnValueOnce(null);
+
+ Notes.updateNoteTargetSelector($note);
+
+ expect(urlUtility.getLocationHash).toHaveBeenCalled();
+ expect($note.toggleClass).toHaveBeenCalledWith('target', false);
+ });
+ });
+
+ describe('renderNote', () => {
+ let notes;
+ let note;
+ let $notesList;
+
+ beforeEach(() => {
+ note = {
+ id: 1,
+ valid: true,
+ note: 'heya',
+ html: '<div>heya</div>',
+ };
+ $notesList = createSpyObj('$notesList', ['find', 'append']);
+
+ notes = createSpyObj('notes', [
+ 'setupNewNote',
+ 'refresh',
+ 'collapseLongCommitList',
+ 'updateNotesCount',
+ 'putConflictEditWarningInPlace',
+ ]);
+ notes.taskList = createSpyObj('tasklist', ['init']);
+ notes.note_ids = [];
+ notes.updatedNotesTrackingMap = {};
+
+ jest.spyOn(Notes, 'isNewNote');
+ jest.spyOn(Notes, 'isUpdatedNote');
+ jest.spyOn(Notes, 'animateAppendNote');
+ jest.spyOn(Notes, 'animateUpdateNote');
+ });
+
+ describe('when adding note', () => {
+ it('should call .animateAppendNote', () => {
+ Notes.isNewNote.mockReturnValueOnce(true);
+ Notes.prototype.renderNote.call(notes, note, null, $notesList);
+
+ expect(Notes.animateAppendNote).toHaveBeenCalledWith(note.html, $notesList);
+ });
+ });
+
+ describe('when note was edited', () => {
+ it('should call .animateUpdateNote', () => {
+ Notes.isNewNote.mockReturnValueOnce(false);
+ Notes.isUpdatedNote.mockReturnValueOnce(true);
+ const $note = $('<div>');
+ $notesList.find.mockReturnValueOnce($note);
+ const $newNote = $(note.html);
+ Notes.animateUpdateNote.mockReturnValueOnce($newNote);
+
+ Notes.prototype.renderNote.call(notes, note, null, $notesList);
+
+ expect(Notes.animateUpdateNote).toHaveBeenCalledWith(note.html, $note);
+ expect(notes.setupNewNote).toHaveBeenCalledWith($newNote);
+ });
+
+ describe('while editing', () => {
+ it('should update textarea if nothing has been touched', () => {
+ Notes.isNewNote.mockReturnValueOnce(false);
+ Notes.isUpdatedNote.mockReturnValueOnce(true);
+ const $note = $(`<div class="is-editing">
+ <div class="original-note-content">initial</div>
+ <textarea class="js-note-text">initial</textarea>
+ </div>`);
+ $notesList.find.mockReturnValueOnce($note);
+ Notes.prototype.renderNote.call(notes, note, null, $notesList);
+
+ expect($note.find('.js-note-text').val()).toEqual(note.note);
+ });
+
+ it('should call .putConflictEditWarningInPlace', () => {
+ Notes.isNewNote.mockReturnValueOnce(false);
+ Notes.isUpdatedNote.mockReturnValueOnce(true);
+ const $note = $(`<div class="is-editing">
+ <div class="original-note-content">initial</div>
+ <textarea class="js-note-text">different</textarea>
+ </div>`);
+ $notesList.find.mockReturnValueOnce($note);
+ Notes.prototype.renderNote.call(notes, note, null, $notesList);
+
+ expect(notes.putConflictEditWarningInPlace).toHaveBeenCalledWith(note, $note);
+ });
+ });
+ });
+ });
+
+ describe('isUpdatedNote', () => {
+ it('should consider same note text as the same', () => {
+ const result = Notes.isUpdatedNote(
+ {
+ note: 'initial',
+ },
+ $(`<div>
+ <div class="original-note-content">initial</div>
+ </div>`),
+ );
+
+ expect(result).toEqual(false);
+ });
+
+ it('should consider same note with trailing newline as the same', () => {
+ const result = Notes.isUpdatedNote(
+ {
+ note: 'initial\n',
+ },
+ $(`<div>
+ <div class="original-note-content">initial\n</div>
+ </div>`),
+ );
+
+ expect(result).toEqual(false);
+ });
+
+ it('should consider different notes as different', () => {
+ const result = Notes.isUpdatedNote(
+ {
+ note: 'foo',
+ },
+ $(`<div>
+ <div class="original-note-content">bar</div>
+ </div>`),
+ );
+
+ expect(result).toEqual(true);
+ });
+ });
+
+ describe('renderDiscussionNote', () => {
+ let discussionContainer;
+ let note;
+ let notes;
+ let $form;
+ let row;
+
+ beforeEach(() => {
+ note = {
+ html: '<li></li>',
+ discussion_html: '<div></div>',
+ discussion_id: 1,
+ discussion_resolvable: false,
+ diff_discussion_html: false,
+ };
+ $form = createSpyObj('$form', ['closest', 'find']);
+ $form.length = 1;
+ row = createSpyObj('row', ['prevAll', 'first', 'find']);
+
+ notes = createSpyObj('notes', ['isParallelView', 'updateNotesCount']);
+ notes.note_ids = [];
+
+ jest.spyOn(Notes, 'isNewNote');
+ jest.spyOn(Notes, 'animateAppendNote').mockImplementation();
+ Notes.isNewNote.mockReturnValue(true);
+ notes.isParallelView.mockReturnValue(false);
+ row.prevAll.mockReturnValue(row);
+ row.first.mockReturnValue(row);
+ row.find.mockReturnValue(row);
+ });
+
+ describe('Discussion root note', () => {
+ let body;
+
+ beforeEach(() => {
+ body = createSpyObj('body', ['attr']);
+ discussionContainer = { length: 0 };
+
+ $form.closest.mockReturnValueOnce(row).mockReturnValue($form);
+ $form.find.mockReturnValue(discussionContainer);
+ body.attr.mockReturnValue('');
+ });
+
+ it('should call Notes.animateAppendNote', () => {
+ Notes.prototype.renderDiscussionNote.call(notes, note, $form);
+
+ expect(Notes.animateAppendNote).toHaveBeenCalledWith(
+ note.discussion_html,
+ $('.main-notes-list'),
+ );
+ });
+
+ it('should append to row selected with line_code', () => {
+ $form.length = 0;
+ note.discussion_line_code = 'line_code';
+ note.diff_discussion_html = '<tr></tr>';
+
+ const line = document.createElement('div');
+ line.id = note.discussion_line_code;
+ document.body.appendChild(line);
+
+ // Override mocks for this single test
+ $form.closest.mockReset();
+ $form.closest.mockReturnValue($form);
+
+ Notes.prototype.renderDiscussionNote.call(notes, note, $form);
+
+ expect(line.nextSibling.outerHTML).toEqual(note.diff_discussion_html);
+ });
+ });
+
+ describe('Discussion sub note', () => {
+ beforeEach(() => {
+ discussionContainer = { length: 1 };
+
+ $form.closest.mockReturnValueOnce(row).mockReturnValueOnce($form);
+ $form.find.mockReturnValue(discussionContainer);
+
+ Notes.prototype.renderDiscussionNote.call(notes, note, $form);
+ });
+
+ it('should call Notes.animateAppendNote', () => {
+ expect(Notes.animateAppendNote).toHaveBeenCalledWith(note.html, discussionContainer);
+ });
+ });
+ });
+
+ describe('animateAppendNote', () => {
+ let noteHTML;
+ let $notesList;
+ let $resultantNote;
+
+ beforeEach(() => {
+ noteHTML = '<div></div>';
+ $notesList = createSpyObj('$notesList', ['append']);
+
+ $resultantNote = Notes.animateAppendNote(noteHTML, $notesList);
+ });
+
+ it('should have `fade-in-full` class', () => {
+ expect($resultantNote.hasClass('fade-in-full')).toEqual(true);
+ });
+
+ it('should append note to the notes list', () => {
+ expect($notesList.append).toHaveBeenCalledWith($resultantNote);
+ });
+ });
+
+ describe('animateUpdateNote', () => {
+ let noteHTML;
+ let $note;
+ let $updatedNote;
+
+ beforeEach(() => {
+ noteHTML = '<div></div>';
+ $note = createSpyObj('$note', ['replaceWith']);
+
+ $updatedNote = Notes.animateUpdateNote(noteHTML, $note);
+ });
+
+ it('should have `fade-in` class', () => {
+ expect($updatedNote.hasClass('fade-in')).toEqual(true);
+ });
+
+ it('should call replaceWith on $note', () => {
+ expect($note.replaceWith).toHaveBeenCalledWith($updatedNote);
+ });
+ });
+
+ describe('putEditFormInPlace', () => {
+ it('should call GLForm with GFM parameter passed through', () => {
+ const notes = new Notes('', []);
+ const $el = $(`
+ <div>
+ <form></form>
+ </div>
+ `);
+
+ notes.putEditFormInPlace($el);
+
+ expect(notes.glForm.enableGFM).toBeTruthy();
+ });
+ });
+
+ describe('postComment & updateComment', () => {
+ const sampleComment = 'foo';
+ const note = {
+ id: 1234,
+ html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
+ <div class="note-text">${sampleComment}</div>
+ </li>`,
+ note: sampleComment,
+ valid: true,
+ };
+ let notes;
+ let $form;
+ let $notesContainer;
+
+ function mockNotesPost() {
+ mockAxios.onPost(NOTES_POST_PATH).reply(200, note);
+ }
+
+ function mockNotesPostError() {
+ mockAxios.onPost(NOTES_POST_PATH).networkError();
+ }
+
+ beforeEach(() => {
+ notes = new Notes('', []);
+ window.gon.current_username = 'root';
+ window.gon.current_user_fullname = 'Administrator';
+ $form = $('form.js-main-target-form');
+ $notesContainer = $('ul.main-notes-list');
+ $form.find('textarea.js-note-text').val(sampleComment);
+ });
+
+ it('should show placeholder note while new comment is being posted', () => {
+ mockNotesPost();
+
+ $('.js-comment-button').click();
+
+ expect($notesContainer.find('.note.being-posted').length).toBeGreaterThan(0);
+ });
+
+ it('should remove placeholder note when new comment is done posting', (done) => {
+ mockNotesPost();
+
+ $('.js-comment-button').click();
+
+ setImmediate(() => {
+ expect($notesContainer.find('.note.being-posted').length).toEqual(0);
+ done();
+ });
+ });
+
+ describe('postComment', () => {
+ it('disables the submit button', (done) => {
+ const $submitButton = $form.find('.js-comment-submit-button');
+
+ expect($submitButton).not.toBeDisabled();
+ const dummyEvent = {
+ preventDefault() {},
+ target: $submitButton,
+ };
+ mockAxios.onPost(NOTES_POST_PATH).replyOnce(() => {
+ expect($submitButton).toBeDisabled();
+ return [200, note];
+ });
+
+ notes
+ .postComment(dummyEvent)
+ .then(() => {
+ expect($submitButton).not.toBeDisabled();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ it('should show actual note element when new comment is done posting', (done) => {
+ mockNotesPost();
+
+ $('.js-comment-button').click();
+
+ setImmediate(() => {
+ expect($notesContainer.find(`#note_${note.id}`).length).toBeGreaterThan(0);
+ done();
+ });
+ });
+
+ it('should reset Form when new comment is done posting', (done) => {
+ mockNotesPost();
+
+ $('.js-comment-button').click();
+
+ setImmediate(() => {
+ expect($form.find('textarea.js-note-text').val()).toEqual('');
+ done();
+ });
+ });
+
+ it('should show flash error message when new comment failed to be posted', (done) => {
+ mockNotesPostError();
+ jest.spyOn(notes, 'addFlash');
+
+ $('.js-comment-button').click();
+
+ setImmediate(() => {
+ expect(notes.addFlash).toHaveBeenCalled();
+ // JSDom doesn't support the :visible selector yet
+ expect(notes.flashContainer.style.display).not.toBe('none');
+ done();
+ });
+ });
+ });
+
+ describe('postComment with quick actions', () => {
+ const sampleComment = '/assign @root\n/award :100:';
+ const note = {
+ commands_changes: {
+ assignee_id: 1,
+ emoji_award: '100',
+ },
+ errors: {
+ commands_only: ['Commands applied'],
+ },
+ valid: false,
+ };
+ let $form;
+ let $notesContainer;
+
+ beforeEach(() => {
+ loadFixtures('commit/show.html');
+ mockAxios.onPost(NOTES_POST_PATH).reply(200, note);
+
+ new Notes('', []);
+ window.gon.current_username = 'root';
+ window.gon.current_user_fullname = 'Administrator';
+ gl.awardsHandler = {
+ addAwardToEmojiBar: () => {},
+ scrollToAwards: () => {},
+ };
+ gl.GfmAutoComplete = {
+ dataSources: {
+ commands: '/root/test-project/autocomplete_sources/commands',
+ },
+ };
+ $form = $('form.js-main-target-form');
+ $notesContainer = $('ul.main-notes-list');
+ $form.find('textarea.js-note-text').val(sampleComment);
+ });
+
+ it('should remove quick action placeholder when comment with quick actions is done posting', (done) => {
+ jest.spyOn(gl.awardsHandler, 'addAwardToEmojiBar');
+ $('.js-comment-button').click();
+
+ expect($notesContainer.find('.note.being-posted').length).toEqual(1); // Placeholder shown
+
+ setImmediate(() => {
+ expect($notesContainer.find('.note.being-posted').length).toEqual(0); // Placeholder removed
+ done();
+ });
+ });
+ });
+
+ describe('postComment with slash when quick actions are not supported', () => {
+ const sampleComment = '/assign @root';
+ let $form;
+ let $notesContainer;
+
+ beforeEach(() => {
+ const note = {
+ id: 1234,
+ html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
+ <div class="note-text">${sampleComment}</div>
+ </li>`,
+ note: sampleComment,
+ valid: true,
+ };
+ mockAxios.onPost(NOTES_POST_PATH).reply(200, note);
+
+ new Notes('', []);
+ $form = $('form.js-main-target-form');
+ $notesContainer = $('ul.main-notes-list');
+ $form.find('textarea.js-note-text').val(sampleComment);
+ });
+
+ it('should show message placeholder including lines starting with slash', (done) => {
+ $('.js-comment-button').click();
+
+ expect($notesContainer.find('.note.being-posted').length).toEqual(1); // Placeholder shown
+ expect($notesContainer.find('.note-body p').text()).toEqual(sampleComment); // No quick action processing
+
+ setImmediate(() => {
+ expect($notesContainer.find('.note.being-posted').length).toEqual(0); // Placeholder removed
+ done();
+ });
+ });
+ });
+
+ describe('update comment with script tags', () => {
+ const sampleComment = '<script></script>';
+ const updatedComment = '<script></script>';
+ const note = {
+ id: 1234,
+ html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
+ <div class="note-text">${sampleComment}</div>
+ </li>`,
+ note: sampleComment,
+ valid: true,
+ };
+ let $form;
+ let $notesContainer;
+
+ beforeEach(() => {
+ mockAxios.onPost(NOTES_POST_PATH).reply(200, note);
+
+ new Notes('', []);
+ window.gon.current_username = 'root';
+ window.gon.current_user_fullname = 'Administrator';
+ $form = $('form.js-main-target-form');
+ $notesContainer = $('ul.main-notes-list');
+ $form.find('textarea.js-note-text').html(sampleComment);
+ });
+
+ it('should not render a script tag', (done) => {
+ $('.js-comment-button').click();
+
+ setImmediate(() => {
+ const $noteEl = $notesContainer.find(`#note_${note.id}`);
+ $noteEl.find('.js-note-edit').click();
+ $noteEl.find('textarea.js-note-text').html(updatedComment);
+ $noteEl.find('.js-comment-save-button').click();
+
+ const $updatedNoteEl = $notesContainer
+ .find(`#note_${note.id}`)
+ .find('.js-task-list-container');
+
+ expect($updatedNoteEl.find('.note-text').text().trim()).toEqual('');
+
+ done();
+ });
+ });
+ });
+
+ describe('getFormData', () => {
+ let $form;
+ let sampleComment;
+ let notes;
+
+ beforeEach(() => {
+ notes = new Notes('', []);
+
+ $form = $('form');
+ sampleComment = 'foobar';
+ });
+
+ it('should return form metadata object from form reference', () => {
+ $form.find('textarea.js-note-text').val(sampleComment);
+ const { formData, formContent, formAction } = notes.getFormData($form);
+
+ expect(formData.indexOf(sampleComment)).toBeGreaterThan(-1);
+ expect(formContent).toEqual(sampleComment);
+ expect(formAction).toEqual($form.attr('action'));
+ });
+
+ it('should return form metadata with sanitized formContent from form reference', () => {
+ sampleComment = '<script>alert("Boom!");</script>';
+ $form.find('textarea.js-note-text').val(sampleComment);
+
+ const { formContent } = notes.getFormData($form);
+
+ expect(formContent).toEqual('&lt;script&gt;alert(&quot;Boom!&quot;);&lt;/script&gt;');
+ });
+ });
+
+ describe('hasQuickActions', () => {
+ let notes;
+
+ beforeEach(() => {
+ notes = new Notes('', []);
+ });
+
+ it('should return true when comment begins with a quick action', () => {
+ const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign Merging this';
+ const hasQuickActions = notes.hasQuickActions(sampleComment);
+
+ expect(hasQuickActions).toBeTruthy();
+ });
+
+ it('should return false when comment does NOT begin with a quick action', () => {
+ const sampleComment = 'Hey, /unassign Merging this';
+ const hasQuickActions = notes.hasQuickActions(sampleComment);
+
+ expect(hasQuickActions).toBeFalsy();
+ });
+
+ it('should return false when comment does NOT have any quick actions', () => {
+ const sampleComment = 'Looking good, Awesome!';
+ const hasQuickActions = notes.hasQuickActions(sampleComment);
+
+ expect(hasQuickActions).toBeFalsy();
+ });
+ });
+
+ describe('stripQuickActions', () => {
+ it('should strip quick actions from the comment which begins with a quick action', () => {
+ const notes = new Notes();
+ const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign Merging this';
+ const stripedComment = notes.stripQuickActions(sampleComment);
+
+ expect(stripedComment).toBe('');
+ });
+
+ it('should strip quick actions from the comment but leaves plain comment if it is present', () => {
+ const notes = new Notes();
+ const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign\nMerging this';
+ const stripedComment = notes.stripQuickActions(sampleComment);
+
+ expect(stripedComment).toBe('Merging this');
+ });
+
+ it('should NOT strip string that has slashes within', () => {
+ const notes = new Notes();
+ const sampleComment = 'http://127.0.0.1:3000/root/gitlab-shell/issues/1';
+ const stripedComment = notes.stripQuickActions(sampleComment);
+
+ expect(stripedComment).toBe(sampleComment);
+ });
+ });
+
+ describe('getQuickActionDescription', () => {
+ const availableQuickActions = [
+ { name: 'close', description: 'Close this issue', params: [] },
+ { name: 'title', description: 'Change title', params: [{}] },
+ { name: 'estimate', description: 'Set time estimate', params: [{}] },
+ ];
+ let notes;
+
+ beforeEach(() => {
+ notes = new Notes();
+ });
+
+ it('should return executing quick action description when note has single quick action', () => {
+ const sampleComment = '/close';
+
+ expect(notes.getQuickActionDescription(sampleComment, availableQuickActions)).toBe(
+ 'Applying command to close this issue',
+ );
+ });
+
+ it('should return generic multiple quick action description when note has multiple quick actions', () => {
+ const sampleComment = '/close\n/title [Duplicate] Issue foobar';
+
+ expect(notes.getQuickActionDescription(sampleComment, availableQuickActions)).toBe(
+ 'Applying multiple commands',
+ );
+ });
+
+ it('should return generic quick action description when available quick actions list is not populated', () => {
+ const sampleComment = '/close\n/title [Duplicate] Issue foobar';
+
+ expect(notes.getQuickActionDescription(sampleComment)).toBe('Applying command');
+ });
+ });
+
+ describe('createPlaceholderNote', () => {
+ const sampleComment = 'foobar';
+ const uniqueId = 'b1234-a4567';
+ const currentUsername = 'root';
+ const currentUserFullname = 'Administrator';
+ const currentUserAvatar = 'avatar_url';
+ let notes;
+
+ beforeEach(() => {
+ notes = new Notes('', []);
+ });
+
+ it('should return constructed placeholder element for regular note based on form contents', () => {
+ const $tempNote = notes.createPlaceholderNote({
+ formContent: sampleComment,
+ uniqueId,
+ isDiscussionNote: false,
+ currentUsername,
+ currentUserFullname,
+ currentUserAvatar,
+ });
+ const $tempNoteHeader = $tempNote.find('.note-header');
+
+ expect($tempNote.prop('nodeName')).toEqual('LI');
+ expect($tempNote.attr('id')).toEqual(uniqueId);
+ expect($tempNote.hasClass('being-posted')).toBeTruthy();
+ expect($tempNote.hasClass('fade-in-half')).toBeTruthy();
+ $tempNote.find('.timeline-icon > a, .note-header-info > a').each((i, el) => {
+ expect(el.getAttribute('href')).toEqual(`/${currentUsername}`);
+ });
+
+ expect($tempNote.find('.timeline-icon .avatar').attr('src')).toEqual(currentUserAvatar);
+ expect($tempNote.find('.timeline-content').hasClass('discussion')).toBeFalsy();
+ expect($tempNoteHeader.find('.d-none.d-sm-inline-block').text().trim()).toEqual(
+ currentUserFullname,
+ );
+
+ expect($tempNoteHeader.find('.note-headline-light').text().trim()).toEqual(
+ `@${currentUsername}`,
+ );
+
+ expect($tempNote.find('.note-body .note-text p').text().trim()).toEqual(sampleComment);
+ });
+
+ it('should return constructed placeholder element for discussion note based on form contents', () => {
+ const $tempNote = notes.createPlaceholderNote({
+ formContent: sampleComment,
+ uniqueId,
+ isDiscussionNote: true,
+ currentUsername,
+ currentUserFullname,
+ });
+
+ expect($tempNote.prop('nodeName')).toEqual('LI');
+ expect($tempNote.find('.timeline-content').hasClass('discussion')).toBeTruthy();
+ });
+
+ it('should return a escaped user name', () => {
+ const currentUserFullnameXSS = 'Foo <script>alert("XSS")</script>';
+ const $tempNote = notes.createPlaceholderNote({
+ formContent: sampleComment,
+ uniqueId,
+ isDiscussionNote: false,
+ currentUsername,
+ currentUserFullname: currentUserFullnameXSS,
+ currentUserAvatar,
+ });
+ const $tempNoteHeader = $tempNote.find('.note-header');
+
+ expect($tempNoteHeader.find('.d-none.d-sm-inline-block').text().trim()).toEqual(
+ 'Foo &lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;',
+ );
+ });
+ });
+
+ describe('createPlaceholderSystemNote', () => {
+ const sampleCommandDescription = 'Applying command to close this issue';
+ const uniqueId = 'b1234-a4567';
+ let notes;
+
+ beforeEach(() => {
+ notes = new Notes('', []);
+ });
+
+ it('should return constructed placeholder element for system note based on form contents', () => {
+ const $tempNote = notes.createPlaceholderSystemNote({
+ formContent: sampleCommandDescription,
+ uniqueId,
+ });
+
+ expect($tempNote.prop('nodeName')).toEqual('LI');
+ expect($tempNote.attr('id')).toEqual(uniqueId);
+ expect($tempNote.hasClass('being-posted')).toBeTruthy();
+ expect($tempNote.hasClass('fade-in-half')).toBeTruthy();
+ expect($tempNote.find('.timeline-content i').text().trim()).toEqual(sampleCommandDescription);
+ });
+ });
+
+ describe('appendFlash', () => {
+ it('shows a flash message', () => {
+ const notes = new Notes('', []);
+ notes.addFlash('Error message', FLASH_TYPE_ALERT, notes.parentTimeline.get(0));
+
+ const flash = $('.flash-alert')[0];
+ expect(document.contains(flash)).toBe(true);
+ expect(flash.parentNode.style.display).toBe('block');
+ });
+ });
+
+ describe('clearFlash', () => {
+ beforeEach(() => {
+ $(document).off('ajax:success');
+ });
+
+ it('hides visible flash message', () => {
+ const notes = new Notes('', []);
+ notes.addFlash('Error message 1', FLASH_TYPE_ALERT, notes.parentTimeline.get(0));
+ const flash = $('.flash-alert')[0];
+ notes.clearFlash();
+ expect(flash.parentNode.style.display).toBe('none');
+ expect(notes.flashContainer).toBeNull();
+ });
+ });
+});
diff --git a/spec/frontend/notes/old_notes_spec.js b/spec/frontend/notes/old_notes_spec.js
deleted file mode 100644
index 0cf43b8fd97..00000000000
--- a/spec/frontend/notes/old_notes_spec.js
+++ /dev/null
@@ -1,998 +0,0 @@
-/* eslint-disable import/no-commonjs, no-new */
-
-import MockAdapter from 'axios-mock-adapter';
-import $ from 'jquery';
-import '~/behaviors/markdown/render_gfm';
-import { createSpyObj } from 'helpers/jest_helpers';
-import { TEST_HOST } from 'helpers/test_constants';
-import { setTestTimeoutOnce } from 'helpers/timeout';
-import axios from '~/lib/utils/axios_utils';
-import * as urlUtility from '~/lib/utils/url_utility';
-
-// These must be imported synchronously because they pull dependencies
-// from the DOM.
-window.jQuery = $;
-require('autosize');
-require('~/commons');
-require('~/notes');
-
-const { Notes } = window;
-const FLASH_TYPE_ALERT = 'alert';
-const NOTES_POST_PATH = /(.*)\/notes\?html=true$/;
-const fixture = 'snippets/show.html';
-let mockAxios;
-
-window.project_uploads_path = `${TEST_HOST}/uploads`;
-window.gon = window.gon || {};
-window.gl = window.gl || {};
-gl.utils = gl.utils || {};
-gl.utils.disableButtonIfEmptyField = () => {};
-
-// the following test is unreliable and failing in main 2-3 times a day
-// see https://gitlab.com/gitlab-org/gitlab/issues/206906#note_290602581
-// eslint-disable-next-line jest/no-disabled-tests
-describe.skip('Old Notes (~/notes.js)', () => {
- beforeEach(() => {
- loadFixtures(fixture);
-
- // Re-declare this here so that test_setup.js#beforeEach() doesn't
- // overwrite it.
- mockAxios = new MockAdapter(axios);
-
- $.ajax = () => {
- throw new Error('$.ajax should not be called through!');
- };
-
- // These jQuery+DOM tests are super flaky so increase the timeout to avoid
- // random failures.
- // It seems that running tests in parallel increases failure rate.
- jest.setTimeout(4000);
- setTestTimeoutOnce(4000);
- });
-
- afterEach(() => {
- // The Notes component sets a polling interval. Clear it after every run.
- // Make sure to use jest.runOnlyPendingTimers() instead of runAllTimers().
- jest.clearAllTimers();
-
- return axios.waitForAll().finally(() => mockAxios.restore());
- });
-
- it('loads the Notes class into the DOM', () => {
- expect(Notes).toBeDefined();
- expect(Notes.name).toBe('Notes');
- });
-
- describe('addBinding', () => {
- it('calls postComment when comment button is clicked', () => {
- jest.spyOn(Notes.prototype, 'postComment');
-
- new window.Notes('', []);
- $('.js-comment-button').click();
- expect(Notes.prototype.postComment).toHaveBeenCalled();
- });
- });
-
- describe('task lists', () => {
- beforeEach(() => {
- mockAxios.onAny().reply(200, {});
- new Notes('', []);
- });
-
- it('modifies the Markdown field', () => {
- const changeEvent = document.createEvent('HTMLEvents');
- changeEvent.initEvent('change', true, true);
- $('input[type=checkbox]').attr('checked', true)[0].dispatchEvent(changeEvent);
-
- expect($('.js-task-list-field.original-task-list').val()).toBe('- [x] Task List Item');
- });
-
- it('submits an ajax request on tasklist:changed', () => {
- jest.spyOn(axios, 'patch');
-
- const lineNumber = 8;
- const lineSource = '- [ ] item 8';
- const index = 3;
- const checked = true;
-
- $('.js-task-list-container').trigger({
- type: 'tasklist:changed',
- detail: { lineNumber, lineSource, index, checked },
- });
-
- expect(axios.patch).toHaveBeenCalledWith(undefined, {
- note: {
- note: '',
- lock_version: undefined,
- update_task: { index, checked, line_number: lineNumber, line_source: lineSource },
- },
- });
- });
- });
-
- describe('comments', () => {
- let notes;
- let autosizeSpy;
- let textarea;
-
- beforeEach(() => {
- notes = new Notes('', []);
-
- textarea = $('.js-note-text');
- textarea.data('autosave', {
- reset: () => {},
- });
- autosizeSpy = jest.fn();
- $(textarea).on('autosize:update', autosizeSpy);
-
- jest.spyOn(notes, 'renderNote');
-
- $('.js-comment-button').on('click', (e) => {
- const $form = $(this);
- e.preventDefault();
- notes.addNote($form, {});
- notes.reenableTargetFormSubmitButton(e);
- notes.resetMainTargetForm(e);
- });
- });
-
- it('autosizes after comment submission', () => {
- textarea.text('This is an example comment note');
- expect(autosizeSpy).not.toHaveBeenCalled();
- $('.js-comment-button').click();
- expect(autosizeSpy).toHaveBeenCalled();
- });
-
- it('should not place escaped text in the comment box in case of error', () => {
- const deferred = $.Deferred();
- jest.spyOn($, 'ajax').mockReturnValueOnce(deferred);
- $(textarea).text('A comment with `markup`.');
-
- deferred.reject();
- $('.js-comment-button').click();
-
- expect($(textarea).val()).toBe('A comment with `markup`.');
-
- $.ajax.mockRestore();
- expect($.ajax.mock).toBeUndefined();
- });
- });
-
- describe('updateNote', () => {
- let notes;
- let noteEntity;
- let $notesContainer;
-
- beforeEach(() => {
- notes = new Notes('', []);
- window.gon.current_username = 'root';
- window.gon.current_user_fullname = 'Administrator';
- const sampleComment = 'foo';
- noteEntity = {
- id: 1234,
- html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
- <div class="note-text">${sampleComment}</div>
- </li>`,
- note: sampleComment,
- valid: true,
- };
-
- $notesContainer = $('ul.main-notes-list');
- const $form = $('form.js-main-target-form');
- $form.find('textarea.js-note-text').val(sampleComment);
-
- mockAxios.onPost(NOTES_POST_PATH).reply(200, noteEntity);
- });
-
- it('updates note and resets edit form', () => {
- jest.spyOn(notes, 'revertNoteEditForm');
- jest.spyOn(notes, 'setupNewNote');
-
- $('.js-comment-button').click();
-
- const $targetNote = $notesContainer.find(`#note_${noteEntity.id}`);
- const updatedNote = { ...noteEntity };
- updatedNote.note = 'bar';
- notes.updateNote(updatedNote, $targetNote);
-
- expect(notes.revertNoteEditForm).toHaveBeenCalledWith($targetNote);
- expect(notes.setupNewNote).toHaveBeenCalled();
- });
- });
-
- describe('updateNoteTargetSelector', () => {
- const hash = 'note_foo';
- let $note;
-
- beforeEach(() => {
- $note = $(`<div id="${hash}"></div>`);
- jest.spyOn($note, 'filter');
- jest.spyOn($note, 'toggleClass');
- });
-
- // urlUtility is a dependency of the notes module. Its getLocatinHash() method should be called internally.
-
- it('sets target when hash matches', () => {
- jest.spyOn(urlUtility, 'getLocationHash').mockReturnValueOnce(hash);
-
- Notes.updateNoteTargetSelector($note);
-
- expect(urlUtility.getLocationHash).toHaveBeenCalled();
- expect($note.filter).toHaveBeenCalledWith(`#${hash}`);
- expect($note.toggleClass).toHaveBeenCalledWith('target', true);
- });
-
- it('unsets target when hash does not match', () => {
- jest.spyOn(urlUtility, 'getLocationHash').mockReturnValueOnce('note_doesnotexist');
-
- Notes.updateNoteTargetSelector($note);
-
- expect(urlUtility.getLocationHash).toHaveBeenCalled();
- expect($note.toggleClass).toHaveBeenCalledWith('target', false);
- });
-
- it('unsets target when there is not a hash fragment anymore', () => {
- jest.spyOn(urlUtility, 'getLocationHash').mockReturnValueOnce(null);
-
- Notes.updateNoteTargetSelector($note);
-
- expect(urlUtility.getLocationHash).toHaveBeenCalled();
- expect($note.toggleClass).toHaveBeenCalledWith('target', false);
- });
- });
-
- describe('renderNote', () => {
- let notes;
- let note;
- let $notesList;
-
- beforeEach(() => {
- note = {
- id: 1,
- valid: true,
- note: 'heya',
- html: '<div>heya</div>',
- };
- $notesList = createSpyObj('$notesList', ['find', 'append']);
-
- notes = createSpyObj('notes', [
- 'setupNewNote',
- 'refresh',
- 'collapseLongCommitList',
- 'updateNotesCount',
- 'putConflictEditWarningInPlace',
- ]);
- notes.taskList = createSpyObj('tasklist', ['init']);
- notes.note_ids = [];
- notes.updatedNotesTrackingMap = {};
-
- jest.spyOn(Notes, 'isNewNote');
- jest.spyOn(Notes, 'isUpdatedNote');
- jest.spyOn(Notes, 'animateAppendNote');
- jest.spyOn(Notes, 'animateUpdateNote');
- });
-
- describe('when adding note', () => {
- it('should call .animateAppendNote', () => {
- Notes.isNewNote.mockReturnValueOnce(true);
- Notes.prototype.renderNote.call(notes, note, null, $notesList);
-
- expect(Notes.animateAppendNote).toHaveBeenCalledWith(note.html, $notesList);
- });
- });
-
- describe('when note was edited', () => {
- it('should call .animateUpdateNote', () => {
- Notes.isNewNote.mockReturnValueOnce(false);
- Notes.isUpdatedNote.mockReturnValueOnce(true);
- const $note = $('<div>');
- $notesList.find.mockReturnValueOnce($note);
- const $newNote = $(note.html);
- Notes.animateUpdateNote.mockReturnValueOnce($newNote);
-
- Notes.prototype.renderNote.call(notes, note, null, $notesList);
-
- expect(Notes.animateUpdateNote).toHaveBeenCalledWith(note.html, $note);
- expect(notes.setupNewNote).toHaveBeenCalledWith($newNote);
- });
-
- describe('while editing', () => {
- it('should update textarea if nothing has been touched', () => {
- Notes.isNewNote.mockReturnValueOnce(false);
- Notes.isUpdatedNote.mockReturnValueOnce(true);
- const $note = $(`<div class="is-editing">
- <div class="original-note-content">initial</div>
- <textarea class="js-note-text">initial</textarea>
- </div>`);
- $notesList.find.mockReturnValueOnce($note);
- Notes.prototype.renderNote.call(notes, note, null, $notesList);
-
- expect($note.find('.js-note-text').val()).toEqual(note.note);
- });
-
- it('should call .putConflictEditWarningInPlace', () => {
- Notes.isNewNote.mockReturnValueOnce(false);
- Notes.isUpdatedNote.mockReturnValueOnce(true);
- const $note = $(`<div class="is-editing">
- <div class="original-note-content">initial</div>
- <textarea class="js-note-text">different</textarea>
- </div>`);
- $notesList.find.mockReturnValueOnce($note);
- Notes.prototype.renderNote.call(notes, note, null, $notesList);
-
- expect(notes.putConflictEditWarningInPlace).toHaveBeenCalledWith(note, $note);
- });
- });
- });
- });
-
- describe('isUpdatedNote', () => {
- it('should consider same note text as the same', () => {
- const result = Notes.isUpdatedNote(
- {
- note: 'initial',
- },
- $(`<div>
- <div class="original-note-content">initial</div>
- </div>`),
- );
-
- expect(result).toEqual(false);
- });
-
- it('should consider same note with trailing newline as the same', () => {
- const result = Notes.isUpdatedNote(
- {
- note: 'initial\n',
- },
- $(`<div>
- <div class="original-note-content">initial\n</div>
- </div>`),
- );
-
- expect(result).toEqual(false);
- });
-
- it('should consider different notes as different', () => {
- const result = Notes.isUpdatedNote(
- {
- note: 'foo',
- },
- $(`<div>
- <div class="original-note-content">bar</div>
- </div>`),
- );
-
- expect(result).toEqual(true);
- });
- });
-
- describe('renderDiscussionNote', () => {
- let discussionContainer;
- let note;
- let notes;
- let $form;
- let row;
-
- beforeEach(() => {
- note = {
- html: '<li></li>',
- discussion_html: '<div></div>',
- discussion_id: 1,
- discussion_resolvable: false,
- diff_discussion_html: false,
- };
- $form = createSpyObj('$form', ['closest', 'find']);
- $form.length = 1;
- row = createSpyObj('row', ['prevAll', 'first', 'find']);
-
- notes = createSpyObj('notes', ['isParallelView', 'updateNotesCount']);
- notes.note_ids = [];
-
- jest.spyOn(Notes, 'isNewNote');
- jest.spyOn(Notes, 'animateAppendNote').mockImplementation();
- Notes.isNewNote.mockReturnValue(true);
- notes.isParallelView.mockReturnValue(false);
- row.prevAll.mockReturnValue(row);
- row.first.mockReturnValue(row);
- row.find.mockReturnValue(row);
- });
-
- describe('Discussion root note', () => {
- let body;
-
- beforeEach(() => {
- body = createSpyObj('body', ['attr']);
- discussionContainer = { length: 0 };
-
- $form.closest.mockReturnValueOnce(row).mockReturnValue($form);
- $form.find.mockReturnValue(discussionContainer);
- body.attr.mockReturnValue('');
- });
-
- it('should call Notes.animateAppendNote', () => {
- Notes.prototype.renderDiscussionNote.call(notes, note, $form);
-
- expect(Notes.animateAppendNote).toHaveBeenCalledWith(
- note.discussion_html,
- $('.main-notes-list'),
- );
- });
-
- it('should append to row selected with line_code', () => {
- $form.length = 0;
- note.discussion_line_code = 'line_code';
- note.diff_discussion_html = '<tr></tr>';
-
- const line = document.createElement('div');
- line.id = note.discussion_line_code;
- document.body.appendChild(line);
-
- // Override mocks for this single test
- $form.closest.mockReset();
- $form.closest.mockReturnValue($form);
-
- Notes.prototype.renderDiscussionNote.call(notes, note, $form);
-
- expect(line.nextSibling.outerHTML).toEqual(note.diff_discussion_html);
- });
- });
-
- describe('Discussion sub note', () => {
- beforeEach(() => {
- discussionContainer = { length: 1 };
-
- $form.closest.mockReturnValueOnce(row).mockReturnValueOnce($form);
- $form.find.mockReturnValue(discussionContainer);
-
- Notes.prototype.renderDiscussionNote.call(notes, note, $form);
- });
-
- it('should call Notes.animateAppendNote', () => {
- expect(Notes.animateAppendNote).toHaveBeenCalledWith(note.html, discussionContainer);
- });
- });
- });
-
- describe('animateAppendNote', () => {
- let noteHTML;
- let $notesList;
- let $resultantNote;
-
- beforeEach(() => {
- noteHTML = '<div></div>';
- $notesList = createSpyObj('$notesList', ['append']);
-
- $resultantNote = Notes.animateAppendNote(noteHTML, $notesList);
- });
-
- it('should have `fade-in-full` class', () => {
- expect($resultantNote.hasClass('fade-in-full')).toEqual(true);
- });
-
- it('should append note to the notes list', () => {
- expect($notesList.append).toHaveBeenCalledWith($resultantNote);
- });
- });
-
- describe('animateUpdateNote', () => {
- let noteHTML;
- let $note;
- let $updatedNote;
-
- beforeEach(() => {
- noteHTML = '<div></div>';
- $note = createSpyObj('$note', ['replaceWith']);
-
- $updatedNote = Notes.animateUpdateNote(noteHTML, $note);
- });
-
- it('should have `fade-in` class', () => {
- expect($updatedNote.hasClass('fade-in')).toEqual(true);
- });
-
- it('should call replaceWith on $note', () => {
- expect($note.replaceWith).toHaveBeenCalledWith($updatedNote);
- });
- });
-
- describe('putEditFormInPlace', () => {
- it('should call GLForm with GFM parameter passed through', () => {
- const notes = new Notes('', []);
- const $el = $(`
- <div>
- <form></form>
- </div>
- `);
-
- notes.putEditFormInPlace($el);
-
- expect(notes.glForm.enableGFM).toBeTruthy();
- });
- });
-
- describe('postComment & updateComment', () => {
- const sampleComment = 'foo';
- const note = {
- id: 1234,
- html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
- <div class="note-text">${sampleComment}</div>
- </li>`,
- note: sampleComment,
- valid: true,
- };
- let notes;
- let $form;
- let $notesContainer;
-
- function mockNotesPost() {
- mockAxios.onPost(NOTES_POST_PATH).reply(200, note);
- }
-
- function mockNotesPostError() {
- mockAxios.onPost(NOTES_POST_PATH).networkError();
- }
-
- beforeEach(() => {
- notes = new Notes('', []);
- window.gon.current_username = 'root';
- window.gon.current_user_fullname = 'Administrator';
- $form = $('form.js-main-target-form');
- $notesContainer = $('ul.main-notes-list');
- $form.find('textarea.js-note-text').val(sampleComment);
- });
-
- it('should show placeholder note while new comment is being posted', () => {
- mockNotesPost();
-
- $('.js-comment-button').click();
-
- expect($notesContainer.find('.note.being-posted').length).toBeGreaterThan(0);
- });
-
- it('should remove placeholder note when new comment is done posting', (done) => {
- mockNotesPost();
-
- $('.js-comment-button').click();
-
- setImmediate(() => {
- expect($notesContainer.find('.note.being-posted').length).toEqual(0);
- done();
- });
- });
-
- describe('postComment', () => {
- it('disables the submit button', (done) => {
- const $submitButton = $form.find('.js-comment-submit-button');
-
- expect($submitButton).not.toBeDisabled();
- const dummyEvent = {
- preventDefault() {},
- target: $submitButton,
- };
- mockAxios.onPost(NOTES_POST_PATH).replyOnce(() => {
- expect($submitButton).toBeDisabled();
- return [200, note];
- });
-
- notes
- .postComment(dummyEvent)
- .then(() => {
- expect($submitButton).not.toBeDisabled();
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- it('should show actual note element when new comment is done posting', (done) => {
- mockNotesPost();
-
- $('.js-comment-button').click();
-
- setImmediate(() => {
- expect($notesContainer.find(`#note_${note.id}`).length).toBeGreaterThan(0);
- done();
- });
- });
-
- it('should reset Form when new comment is done posting', (done) => {
- mockNotesPost();
-
- $('.js-comment-button').click();
-
- setImmediate(() => {
- expect($form.find('textarea.js-note-text').val()).toEqual('');
- done();
- });
- });
-
- it('should show flash error message when new comment failed to be posted', (done) => {
- mockNotesPostError();
- jest.spyOn(notes, 'addFlash');
-
- $('.js-comment-button').click();
-
- setImmediate(() => {
- expect(notes.addFlash).toHaveBeenCalled();
- // JSDom doesn't support the :visible selector yet
- expect(notes.flashContainer.style.display).not.toBe('none');
- done();
- });
- });
- });
-
- describe('postComment with quick actions', () => {
- const sampleComment = '/assign @root\n/award :100:';
- const note = {
- commands_changes: {
- assignee_id: 1,
- emoji_award: '100',
- },
- errors: {
- commands_only: ['Commands applied'],
- },
- valid: false,
- };
- let $form;
- let $notesContainer;
-
- beforeEach(() => {
- loadFixtures('commit/show.html');
- mockAxios.onPost(NOTES_POST_PATH).reply(200, note);
-
- new Notes('', []);
- window.gon.current_username = 'root';
- window.gon.current_user_fullname = 'Administrator';
- gl.awardsHandler = {
- addAwardToEmojiBar: () => {},
- scrollToAwards: () => {},
- };
- gl.GfmAutoComplete = {
- dataSources: {
- commands: '/root/test-project/autocomplete_sources/commands',
- },
- };
- $form = $('form.js-main-target-form');
- $notesContainer = $('ul.main-notes-list');
- $form.find('textarea.js-note-text').val(sampleComment);
- });
-
- it('should remove quick action placeholder when comment with quick actions is done posting', (done) => {
- jest.spyOn(gl.awardsHandler, 'addAwardToEmojiBar');
- $('.js-comment-button').click();
-
- expect($notesContainer.find('.note.being-posted').length).toEqual(1); // Placeholder shown
-
- setImmediate(() => {
- expect($notesContainer.find('.note.being-posted').length).toEqual(0); // Placeholder removed
- done();
- });
- });
- });
-
- describe('postComment with slash when quick actions are not supported', () => {
- const sampleComment = '/assign @root';
- let $form;
- let $notesContainer;
-
- beforeEach(() => {
- const note = {
- id: 1234,
- html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
- <div class="note-text">${sampleComment}</div>
- </li>`,
- note: sampleComment,
- valid: true,
- };
- mockAxios.onPost(NOTES_POST_PATH).reply(200, note);
-
- new Notes('', []);
- $form = $('form.js-main-target-form');
- $notesContainer = $('ul.main-notes-list');
- $form.find('textarea.js-note-text').val(sampleComment);
- });
-
- it('should show message placeholder including lines starting with slash', (done) => {
- $('.js-comment-button').click();
-
- expect($notesContainer.find('.note.being-posted').length).toEqual(1); // Placeholder shown
- expect($notesContainer.find('.note-body p').text()).toEqual(sampleComment); // No quick action processing
-
- setImmediate(() => {
- expect($notesContainer.find('.note.being-posted').length).toEqual(0); // Placeholder removed
- done();
- });
- });
- });
-
- describe('update comment with script tags', () => {
- const sampleComment = '<script></script>';
- const updatedComment = '<script></script>';
- const note = {
- id: 1234,
- html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
- <div class="note-text">${sampleComment}</div>
- </li>`,
- note: sampleComment,
- valid: true,
- };
- let $form;
- let $notesContainer;
-
- beforeEach(() => {
- mockAxios.onPost(NOTES_POST_PATH).reply(200, note);
-
- new Notes('', []);
- window.gon.current_username = 'root';
- window.gon.current_user_fullname = 'Administrator';
- $form = $('form.js-main-target-form');
- $notesContainer = $('ul.main-notes-list');
- $form.find('textarea.js-note-text').html(sampleComment);
- });
-
- it('should not render a script tag', (done) => {
- $('.js-comment-button').click();
-
- setImmediate(() => {
- const $noteEl = $notesContainer.find(`#note_${note.id}`);
- $noteEl.find('.js-note-edit').click();
- $noteEl.find('textarea.js-note-text').html(updatedComment);
- $noteEl.find('.js-comment-save-button').click();
-
- const $updatedNoteEl = $notesContainer
- .find(`#note_${note.id}`)
- .find('.js-task-list-container');
-
- expect($updatedNoteEl.find('.note-text').text().trim()).toEqual('');
-
- done();
- });
- });
- });
-
- describe('getFormData', () => {
- let $form;
- let sampleComment;
- let notes;
-
- beforeEach(() => {
- notes = new Notes('', []);
-
- $form = $('form');
- sampleComment = 'foobar';
- });
-
- it('should return form metadata object from form reference', () => {
- $form.find('textarea.js-note-text').val(sampleComment);
- const { formData, formContent, formAction } = notes.getFormData($form);
-
- expect(formData.indexOf(sampleComment)).toBeGreaterThan(-1);
- expect(formContent).toEqual(sampleComment);
- expect(formAction).toEqual($form.attr('action'));
- });
-
- it('should return form metadata with sanitized formContent from form reference', () => {
- sampleComment = '<script>alert("Boom!");</script>';
- $form.find('textarea.js-note-text').val(sampleComment);
-
- const { formContent } = notes.getFormData($form);
-
- expect(formContent).toEqual('&lt;script&gt;alert(&quot;Boom!&quot;);&lt;/script&gt;');
- });
- });
-
- describe('hasQuickActions', () => {
- let notes;
-
- beforeEach(() => {
- notes = new Notes('', []);
- });
-
- it('should return true when comment begins with a quick action', () => {
- const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign Merging this';
- const hasQuickActions = notes.hasQuickActions(sampleComment);
-
- expect(hasQuickActions).toBeTruthy();
- });
-
- it('should return false when comment does NOT begin with a quick action', () => {
- const sampleComment = 'Hey, /unassign Merging this';
- const hasQuickActions = notes.hasQuickActions(sampleComment);
-
- expect(hasQuickActions).toBeFalsy();
- });
-
- it('should return false when comment does NOT have any quick actions', () => {
- const sampleComment = 'Looking good, Awesome!';
- const hasQuickActions = notes.hasQuickActions(sampleComment);
-
- expect(hasQuickActions).toBeFalsy();
- });
- });
-
- describe('stripQuickActions', () => {
- it('should strip quick actions from the comment which begins with a quick action', () => {
- const notes = new Notes();
- const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign Merging this';
- const stripedComment = notes.stripQuickActions(sampleComment);
-
- expect(stripedComment).toBe('');
- });
-
- it('should strip quick actions from the comment but leaves plain comment if it is present', () => {
- const notes = new Notes();
- const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign\nMerging this';
- const stripedComment = notes.stripQuickActions(sampleComment);
-
- expect(stripedComment).toBe('Merging this');
- });
-
- it('should NOT strip string that has slashes within', () => {
- const notes = new Notes();
- const sampleComment = 'http://127.0.0.1:3000/root/gitlab-shell/issues/1';
- const stripedComment = notes.stripQuickActions(sampleComment);
-
- expect(stripedComment).toBe(sampleComment);
- });
- });
-
- describe('getQuickActionDescription', () => {
- const availableQuickActions = [
- { name: 'close', description: 'Close this issue', params: [] },
- { name: 'title', description: 'Change title', params: [{}] },
- { name: 'estimate', description: 'Set time estimate', params: [{}] },
- ];
- let notes;
-
- beforeEach(() => {
- notes = new Notes();
- });
-
- it('should return executing quick action description when note has single quick action', () => {
- const sampleComment = '/close';
-
- expect(notes.getQuickActionDescription(sampleComment, availableQuickActions)).toBe(
- 'Applying command to close this issue',
- );
- });
-
- it('should return generic multiple quick action description when note has multiple quick actions', () => {
- const sampleComment = '/close\n/title [Duplicate] Issue foobar';
-
- expect(notes.getQuickActionDescription(sampleComment, availableQuickActions)).toBe(
- 'Applying multiple commands',
- );
- });
-
- it('should return generic quick action description when available quick actions list is not populated', () => {
- const sampleComment = '/close\n/title [Duplicate] Issue foobar';
-
- expect(notes.getQuickActionDescription(sampleComment)).toBe('Applying command');
- });
- });
-
- describe('createPlaceholderNote', () => {
- const sampleComment = 'foobar';
- const uniqueId = 'b1234-a4567';
- const currentUsername = 'root';
- const currentUserFullname = 'Administrator';
- const currentUserAvatar = 'avatar_url';
- let notes;
-
- beforeEach(() => {
- notes = new Notes('', []);
- });
-
- it('should return constructed placeholder element for regular note based on form contents', () => {
- const $tempNote = notes.createPlaceholderNote({
- formContent: sampleComment,
- uniqueId,
- isDiscussionNote: false,
- currentUsername,
- currentUserFullname,
- currentUserAvatar,
- });
- const $tempNoteHeader = $tempNote.find('.note-header');
-
- expect($tempNote.prop('nodeName')).toEqual('LI');
- expect($tempNote.attr('id')).toEqual(uniqueId);
- expect($tempNote.hasClass('being-posted')).toBeTruthy();
- expect($tempNote.hasClass('fade-in-half')).toBeTruthy();
- $tempNote.find('.timeline-icon > a, .note-header-info > a').each((i, el) => {
- expect(el.getAttribute('href')).toEqual(`/${currentUsername}`);
- });
-
- expect($tempNote.find('.timeline-icon .avatar').attr('src')).toEqual(currentUserAvatar);
- expect($tempNote.find('.timeline-content').hasClass('discussion')).toBeFalsy();
- expect($tempNoteHeader.find('.d-none.d-sm-inline-block').text().trim()).toEqual(
- currentUserFullname,
- );
-
- expect($tempNoteHeader.find('.note-headline-light').text().trim()).toEqual(
- `@${currentUsername}`,
- );
-
- expect($tempNote.find('.note-body .note-text p').text().trim()).toEqual(sampleComment);
- });
-
- it('should return constructed placeholder element for discussion note based on form contents', () => {
- const $tempNote = notes.createPlaceholderNote({
- formContent: sampleComment,
- uniqueId,
- isDiscussionNote: true,
- currentUsername,
- currentUserFullname,
- });
-
- expect($tempNote.prop('nodeName')).toEqual('LI');
- expect($tempNote.find('.timeline-content').hasClass('discussion')).toBeTruthy();
- });
-
- it('should return a escaped user name', () => {
- const currentUserFullnameXSS = 'Foo <script>alert("XSS")</script>';
- const $tempNote = notes.createPlaceholderNote({
- formContent: sampleComment,
- uniqueId,
- isDiscussionNote: false,
- currentUsername,
- currentUserFullname: currentUserFullnameXSS,
- currentUserAvatar,
- });
- const $tempNoteHeader = $tempNote.find('.note-header');
-
- expect($tempNoteHeader.find('.d-none.d-sm-inline-block').text().trim()).toEqual(
- 'Foo &lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;',
- );
- });
- });
-
- describe('createPlaceholderSystemNote', () => {
- const sampleCommandDescription = 'Applying command to close this issue';
- const uniqueId = 'b1234-a4567';
- let notes;
-
- beforeEach(() => {
- notes = new Notes('', []);
- });
-
- it('should return constructed placeholder element for system note based on form contents', () => {
- const $tempNote = notes.createPlaceholderSystemNote({
- formContent: sampleCommandDescription,
- uniqueId,
- });
-
- expect($tempNote.prop('nodeName')).toEqual('LI');
- expect($tempNote.attr('id')).toEqual(uniqueId);
- expect($tempNote.hasClass('being-posted')).toBeTruthy();
- expect($tempNote.hasClass('fade-in-half')).toBeTruthy();
- expect($tempNote.find('.timeline-content i').text().trim()).toEqual(sampleCommandDescription);
- });
- });
-
- describe('appendFlash', () => {
- it('shows a flash message', () => {
- const notes = new Notes('', []);
- notes.addFlash('Error message', FLASH_TYPE_ALERT, notes.parentTimeline.get(0));
-
- const flash = $('.flash-alert')[0];
- expect(document.contains(flash)).toBe(true);
- expect(flash.parentNode.style.display).toBe('block');
- });
- });
-
- describe('clearFlash', () => {
- beforeEach(() => {
- $(document).off('ajax:success');
- });
-
- it('hides visible flash message', () => {
- const notes = new Notes('', []);
- notes.addFlash('Error message 1', FLASH_TYPE_ALERT, notes.parentTimeline.get(0));
- const flash = $('.flash-alert')[0];
- notes.clearFlash();
- expect(flash.parentNode.style.display).toBe('none');
- expect(notes.flashContainer).toBeNull();
- });
- });
-});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/package_title_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/package_title_spec.js.snap
index 45d261625b4..451cf743e35 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/package_title_spec.js.snap
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/package_title_spec.js.snap
@@ -177,15 +177,6 @@ exports[`PackageTitle renders without tags 1`] = `
texttooltip=""
/>
</div>
- <div
- class="gl-display-flex gl-align-items-center gl-mr-5"
- >
- <package-tags-stub
- hidelabel="true"
- tagdisplaylimit="2"
- tags="[object Object],[object Object],[object Object]"
- />
- </div>
</div>
</div>
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/additional_metadata_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/additional_metadata_spec.js
index 0504a42dfcf..7a71a1cea0f 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/additional_metadata_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/additional_metadata_spec.js
@@ -1,10 +1,11 @@
-import { GlLink, GlSprintf } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import {
conanMetadata,
mavenMetadata,
nugetMetadata,
packageData,
+ composerMetadata,
+ pypiMetadata,
} from 'jest/packages_and_registries/package_registry/mock_data';
import component from '~/packages_and_registries/package_registry/components/details/additional_metadata.vue';
import {
@@ -12,12 +13,15 @@ import {
PACKAGE_TYPE_CONAN,
PACKAGE_TYPE_MAVEN,
PACKAGE_TYPE_NPM,
+ PACKAGE_TYPE_COMPOSER,
+ PACKAGE_TYPE_PYPI,
} from '~/packages_and_registries/package_registry/constants';
-import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
const mavenPackage = { packageType: PACKAGE_TYPE_MAVEN, metadata: mavenMetadata() };
const conanPackage = { packageType: PACKAGE_TYPE_CONAN, metadata: conanMetadata() };
const nugetPackage = { packageType: PACKAGE_TYPE_NUGET, metadata: nugetMetadata() };
+const composerPackage = { packageType: PACKAGE_TYPE_COMPOSER, metadata: composerMetadata() };
+const pypiPackage = { packageType: PACKAGE_TYPE_PYPI, metadata: pypiMetadata() };
const npmPackage = { packageType: PACKAGE_TYPE_NPM, metadata: {} };
describe('Package Additional Metadata', () => {
@@ -32,8 +36,7 @@ describe('Package Additional Metadata', () => {
wrapper = shallowMountExtended(component, {
propsData: { ...defaultProps, ...props },
stubs: {
- DetailsRow,
- GlSprintf,
+ component: { template: '<div data-testid="component-is"></div>' },
},
});
};
@@ -45,12 +48,7 @@ describe('Package Additional Metadata', () => {
const findTitle = () => wrapper.findByTestId('title');
const findMainArea = () => wrapper.findByTestId('main');
- const findNugetSource = () => wrapper.findByTestId('nuget-source');
- const findNugetLicense = () => wrapper.findByTestId('nuget-license');
- const findConanRecipe = () => wrapper.findByTestId('conan-recipe');
- const findMavenApp = () => wrapper.findByTestId('maven-app');
- const findMavenGroup = () => wrapper.findByTestId('maven-group');
- const findElementLink = (container) => container.findComponent(GlLink);
+ const findComponentIs = () => wrapper.findByTestId('component-is');
it('has the correct title', () => {
mountComponent();
@@ -62,11 +60,13 @@ describe('Package Additional Metadata', () => {
});
it.each`
- packageEntity | visible | packageType
- ${mavenPackage} | ${true} | ${PACKAGE_TYPE_MAVEN}
- ${conanPackage} | ${true} | ${PACKAGE_TYPE_CONAN}
- ${nugetPackage} | ${true} | ${PACKAGE_TYPE_NUGET}
- ${npmPackage} | ${false} | ${PACKAGE_TYPE_NPM}
+ packageEntity | visible | packageType
+ ${mavenPackage} | ${true} | ${PACKAGE_TYPE_MAVEN}
+ ${conanPackage} | ${true} | ${PACKAGE_TYPE_CONAN}
+ ${nugetPackage} | ${true} | ${PACKAGE_TYPE_NUGET}
+ ${composerPackage} | ${true} | ${PACKAGE_TYPE_COMPOSER}
+ ${pypiPackage} | ${true} | ${PACKAGE_TYPE_PYPI}
+ ${npmPackage} | ${false} | ${PACKAGE_TYPE_NPM}
`(
`It is $visible that the component is visible when the package is $packageType`,
({ packageEntity, visible }) => {
@@ -74,57 +74,11 @@ describe('Package Additional Metadata', () => {
expect(findTitle().exists()).toBe(visible);
expect(findMainArea().exists()).toBe(visible);
+ expect(findComponentIs().exists()).toBe(visible);
+
+ if (visible) {
+ expect(findComponentIs().props('packageEntity')).toEqual(packageEntity);
+ }
},
);
-
- describe('nuget metadata', () => {
- beforeEach(() => {
- mountComponent({ packageEntity: nugetPackage });
- });
-
- it.each`
- name | finderFunction | text | link | icon
- ${'source'} | ${findNugetSource} | ${'Source project located at projectUrl'} | ${'projectUrl'} | ${'project'}
- ${'license'} | ${findNugetLicense} | ${'License information located at licenseUrl'} | ${'licenseUrl'} | ${'license'}
- `('$name element', ({ finderFunction, text, link, icon }) => {
- const element = finderFunction();
- expect(element.exists()).toBe(true);
- expect(element.text()).toBe(text);
- expect(element.props('icon')).toBe(icon);
- expect(findElementLink(element).attributes('href')).toBe(nugetPackage.metadata[link]);
- });
- });
-
- describe('conan metadata', () => {
- beforeEach(() => {
- mountComponent({ packageEntity: conanPackage });
- });
-
- it.each`
- name | finderFunction | text | icon
- ${'recipe'} | ${findConanRecipe} | ${'Recipe: package-8/1.0.0@gitlab-org+gitlab-test/stable'} | ${'information-o'}
- `('$name element', ({ finderFunction, text, icon }) => {
- const element = finderFunction();
- expect(element.exists()).toBe(true);
- expect(element.text()).toBe(text);
- expect(element.props('icon')).toBe(icon);
- });
- });
-
- describe('maven metadata', () => {
- beforeEach(() => {
- mountComponent();
- });
-
- it.each`
- name | finderFunction | text | icon
- ${'app'} | ${findMavenApp} | ${'App name: appName'} | ${'information-o'}
- ${'group'} | ${findMavenGroup} | ${'App group: appGroup'} | ${'information-o'}
- `('$name element', ({ finderFunction, text, icon }) => {
- const element = finderFunction();
- expect(element.exists()).toBe(true);
- expect(element.text()).toBe(text);
- expect(element.props('icon')).toBe(icon);
- });
- });
});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/metadata/composer_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/metadata/composer_spec.js
new file mode 100644
index 00000000000..e744680cb9a
--- /dev/null
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/metadata/composer_spec.js
@@ -0,0 +1,58 @@
+import { GlSprintf } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import {
+ packageData,
+ composerMetadata,
+} from 'jest/packages_and_registries/package_registry/mock_data';
+import component from '~/packages_and_registries/package_registry/components/details/metadata/composer.vue';
+import { PACKAGE_TYPE_COMPOSER } from '~/packages_and_registries/package_registry/constants';
+import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
+import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
+
+const composerPackage = { packageType: PACKAGE_TYPE_COMPOSER, metadata: composerMetadata() };
+
+describe('Composer Metadata', () => {
+ let wrapper;
+
+ const mountComponent = () => {
+ wrapper = shallowMountExtended(component, {
+ propsData: { packageEntity: packageData(composerPackage) },
+ stubs: {
+ DetailsRow,
+ GlSprintf,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ const findComposerTargetSha = () => wrapper.findByTestId('composer-target-sha');
+ const findComposerTargetShaCopyButton = () => wrapper.findComponent(ClipboardButton);
+ const findComposerJson = () => wrapper.findByTestId('composer-json');
+
+ beforeEach(() => {
+ mountComponent();
+ });
+
+ it.each`
+ name | finderFunction | text | icon
+ ${'target-sha'} | ${findComposerTargetSha} | ${'Target SHA: b83d6e391c22777fca1ed3012fce84f633d7fed0'} | ${'information-o'}
+ ${'composer-json'} | ${findComposerJson} | ${'Composer.json with license: MIT and version: 1.0.0'} | ${'information-o'}
+ `('$name element', ({ finderFunction, text, icon }) => {
+ const element = finderFunction();
+ expect(element.exists()).toBe(true);
+ expect(element.text()).toBe(text);
+ expect(element.props('icon')).toBe(icon);
+ });
+
+ it('target-sha has a copy button', () => {
+ expect(findComposerTargetShaCopyButton().exists()).toBe(true);
+ expect(findComposerTargetShaCopyButton().props()).toMatchObject({
+ text: 'b83d6e391c22777fca1ed3012fce84f633d7fed0',
+ title: 'Copy target SHA',
+ });
+ });
+});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/metadata/conan_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/metadata/conan_spec.js
new file mode 100644
index 00000000000..46593047f1f
--- /dev/null
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/metadata/conan_spec.js
@@ -0,0 +1,48 @@
+import { GlSprintf } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import {
+ conanMetadata,
+ packageData,
+} from 'jest/packages_and_registries/package_registry/mock_data';
+import component from '~/packages_and_registries/package_registry/components/details/metadata/conan.vue';
+import { PACKAGE_TYPE_CONAN } from '~/packages_and_registries/package_registry/constants';
+import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
+
+const conanPackage = { packageType: PACKAGE_TYPE_CONAN, metadata: conanMetadata() };
+
+describe('Conan Metadata', () => {
+ let wrapper;
+
+ const mountComponent = () => {
+ wrapper = shallowMountExtended(component, {
+ propsData: {
+ packageEntity: packageData(conanPackage),
+ },
+ stubs: {
+ DetailsRow,
+ GlSprintf,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ const findConanRecipe = () => wrapper.findByTestId('conan-recipe');
+
+ beforeEach(() => {
+ mountComponent();
+ });
+
+ it.each`
+ name | finderFunction | text | icon
+ ${'recipe'} | ${findConanRecipe} | ${'Recipe: package-8/1.0.0@gitlab-org+gitlab-test/stable'} | ${'information-o'}
+ `('$name element', ({ finderFunction, text, icon }) => {
+ const element = finderFunction();
+ expect(element.exists()).toBe(true);
+ expect(element.text()).toBe(text);
+ expect(element.props('icon')).toBe(icon);
+ });
+});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/metadata/maven_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/metadata/maven_spec.js
new file mode 100644
index 00000000000..bc54cf1cb98
--- /dev/null
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/metadata/maven_spec.js
@@ -0,0 +1,52 @@
+import { GlSprintf } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import {
+ mavenMetadata,
+ packageData,
+} from 'jest/packages_and_registries/package_registry/mock_data';
+import component from '~/packages_and_registries/package_registry/components/details/metadata/maven.vue';
+import { PACKAGE_TYPE_MAVEN } from '~/packages_and_registries/package_registry/constants';
+import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
+
+const mavenPackage = { packageType: PACKAGE_TYPE_MAVEN, metadata: mavenMetadata() };
+
+describe('Maven Metadata', () => {
+ let wrapper;
+
+ const mountComponent = () => {
+ wrapper = shallowMountExtended(component, {
+ propsData: {
+ packageEntity: {
+ ...packageData(mavenPackage),
+ },
+ },
+ stubs: {
+ DetailsRow,
+ GlSprintf,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ const findMavenApp = () => wrapper.findByTestId('maven-app');
+ const findMavenGroup = () => wrapper.findByTestId('maven-group');
+
+ beforeEach(() => {
+ mountComponent();
+ });
+
+ it.each`
+ name | finderFunction | text | icon
+ ${'app'} | ${findMavenApp} | ${'App name: appName'} | ${'information-o'}
+ ${'group'} | ${findMavenGroup} | ${'App group: appGroup'} | ${'information-o'}
+ `('$name element', ({ finderFunction, text, icon }) => {
+ const element = finderFunction();
+ expect(element.exists()).toBe(true);
+ expect(element.text()).toBe(text);
+ expect(element.props('icon')).toBe(icon);
+ });
+});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/metadata/nuget_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/metadata/nuget_spec.js
new file mode 100644
index 00000000000..279900edff2
--- /dev/null
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/metadata/nuget_spec.js
@@ -0,0 +1,55 @@
+import { GlLink, GlSprintf } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import {
+ nugetMetadata,
+ packageData,
+} from 'jest/packages_and_registries/package_registry/mock_data';
+import component from '~/packages_and_registries/package_registry/components/details/metadata/nuget.vue';
+import { PACKAGE_TYPE_NUGET } from '~/packages_and_registries/package_registry/constants';
+
+import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
+
+const nugetPackage = { packageType: PACKAGE_TYPE_NUGET, metadata: nugetMetadata() };
+
+describe('Nuget Metadata', () => {
+ let wrapper;
+
+ const mountComponent = () => {
+ wrapper = shallowMountExtended(component, {
+ propsData: {
+ packageEntity: {
+ ...packageData(nugetPackage),
+ },
+ },
+ stubs: {
+ DetailsRow,
+ GlSprintf,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ const findNugetSource = () => wrapper.findByTestId('nuget-source');
+ const findNugetLicense = () => wrapper.findByTestId('nuget-license');
+ const findElementLink = (container) => container.findComponent(GlLink);
+
+ beforeEach(() => {
+ mountComponent({ packageEntity: nugetPackage });
+ });
+
+ it.each`
+ name | finderFunction | text | link | icon
+ ${'source'} | ${findNugetSource} | ${'Source project located at projectUrl'} | ${'projectUrl'} | ${'project'}
+ ${'license'} | ${findNugetLicense} | ${'License information located at licenseUrl'} | ${'licenseUrl'} | ${'license'}
+ `('$name element', ({ finderFunction, text, link, icon }) => {
+ const element = finderFunction();
+ expect(element.exists()).toBe(true);
+ expect(element.text()).toBe(text);
+ expect(element.props('icon')).toBe(icon);
+ expect(findElementLink(element).attributes('href')).toBe(nugetPackage.metadata[link]);
+ });
+});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/metadata/pypi_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/metadata/pypi_spec.js
new file mode 100644
index 00000000000..c4481c3f20b
--- /dev/null
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/metadata/pypi_spec.js
@@ -0,0 +1,48 @@
+import { GlSprintf } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import { packageData, pypiMetadata } from 'jest/packages_and_registries/package_registry/mock_data';
+import component from '~/packages_and_registries/package_registry/components/details/metadata/pypi.vue';
+import { PACKAGE_TYPE_PYPI } from '~/packages_and_registries/package_registry/constants';
+
+import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
+
+const pypiPackage = { packageType: PACKAGE_TYPE_PYPI, metadata: pypiMetadata() };
+
+describe('Package Additional Metadata', () => {
+ let wrapper;
+
+ const mountComponent = () => {
+ wrapper = shallowMountExtended(component, {
+ propsData: {
+ packageEntity: {
+ ...packageData(pypiPackage),
+ },
+ },
+ stubs: {
+ DetailsRow,
+ GlSprintf,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ const findPypiRequiredPython = () => wrapper.findByTestId('pypi-required-python');
+
+ beforeEach(() => {
+ mountComponent();
+ });
+
+ it.each`
+ name | finderFunction | text | icon
+ ${'pypi-required-python'} | ${findPypiRequiredPython} | ${'Required Python: 1.0.0'} | ${'information-o'}
+ `('$name element', ({ finderFunction, text, icon }) => {
+ const element = finderFunction();
+ expect(element.exists()).toBe(true);
+ expect(element.text()).toBe(text);
+ expect(element.props('icon')).toBe(icon);
+ });
+});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/package_title_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/package_title_spec.js
index 327f6d81905..d59c3184e4e 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/package_title_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/package_title_spec.js
@@ -1,5 +1,6 @@
import { GlIcon, GlSprintf } from '@gitlab/ui';
import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
+import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import PackageTags from '~/packages/shared/components/package_tags.vue';
import PackageTitle from '~/packages_and_registries/package_registry/components/details/package_title.vue';
@@ -30,6 +31,9 @@ describe('PackageTitle', () => {
TitleArea,
GlSprintf,
},
+ directives: {
+ GlResizeObserver: createMockDirective(),
+ },
});
return wrapper.vm.$nextTick();
}
@@ -51,7 +55,7 @@ describe('PackageTitle', () => {
describe('renders', () => {
it('without tags', async () => {
- await createComponent();
+ await createComponent({ ...packageData(), packageFiles: { nodes: packageFiles() } });
expect(wrapper.element).toMatchSnapshot();
});
@@ -64,12 +68,26 @@ describe('PackageTitle', () => {
it('with tags on mobile', async () => {
jest.spyOn(GlBreakpointInstance, 'isDesktop').mockReturnValue(false);
+
await createComponent();
await wrapper.vm.$nextTick();
expect(findPackageBadges()).toHaveLength(packageTags().length);
});
+
+ it('when the page is resized', async () => {
+ await createComponent();
+
+ expect(findPackageBadges()).toHaveLength(0);
+
+ jest.spyOn(GlBreakpointInstance, 'isDesktop').mockReturnValue(false);
+ const { value } = getBinding(wrapper.element, 'gl-resize-observer');
+ value();
+
+ await wrapper.vm.$nextTick();
+ expect(findPackageBadges()).toHaveLength(packageTags().length);
+ });
});
describe('package title', () => {
diff --git a/spec/frontend/packages_and_registries/package_registry/components/list/__snapshots__/packages_list_app_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/components/list/__snapshots__/packages_list_app_spec.js.snap
new file mode 100644
index 00000000000..dbebdeeb452
--- /dev/null
+++ b/spec/frontend/packages_and_registries/package_registry/components/list/__snapshots__/packages_list_app_spec.js.snap
@@ -0,0 +1,68 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`packages_list_app renders 1`] = `
+<div>
+ <div
+ help-url="foo"
+ />
+
+ <div />
+
+ <div>
+ <section
+ class="row empty-state text-center"
+ >
+ <div
+ class="col-12"
+ >
+ <div
+ class="svg-250 svg-content"
+ >
+ <img
+ alt=""
+ class="gl-max-w-full"
+ role="img"
+ src="helpSvg"
+ />
+ </div>
+ </div>
+
+ <div
+ class="col-12"
+ >
+ <div
+ class="text-content gl-mx-auto gl-my-0 gl-p-5"
+ >
+ <h1
+ class="h4"
+ >
+ There are no packages yet
+ </h1>
+
+ <p>
+ Learn how to
+ <b-link-stub
+ class="gl-link"
+ event="click"
+ href="helpUrl"
+ routertag="a"
+ target="_blank"
+ >
+ publish and share your packages
+ </b-link-stub>
+ with GitLab.
+ </p>
+
+ <div
+ class="gl-display-flex gl-flex-wrap gl-justify-content-center"
+ >
+ <!---->
+
+ <!---->
+ </div>
+ </div>
+ </div>
+ </section>
+ </div>
+</div>
+`;
diff --git a/spec/frontend/packages_and_registries/package_registry/components/list/packages_list_app_spec.js b/spec/frontend/packages_and_registries/package_registry/components/list/packages_list_app_spec.js
new file mode 100644
index 00000000000..6c871a34d50
--- /dev/null
+++ b/spec/frontend/packages_and_registries/package_registry/components/list/packages_list_app_spec.js
@@ -0,0 +1,273 @@
+import { GlEmptyState, GlSprintf, GlLink } from '@gitlab/ui';
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import Vuex from 'vuex';
+import setWindowLocation from 'helpers/set_window_location_helper';
+import createFlash from '~/flash';
+import * as commonUtils from '~/lib/utils/common_utils';
+import { DELETE_PACKAGE_SUCCESS_MESSAGE } from '~/packages/list/constants';
+import { SHOW_DELETE_SUCCESS_ALERT } from '~/packages/shared/constants';
+import PackageListApp from '~/packages_and_registries/package_registry/components/list/packages_list_app.vue';
+import { FILTERED_SEARCH_TERM } from '~/packages_and_registries/shared/constants';
+import * as packageUtils from '~/packages_and_registries/shared/utils';
+
+jest.mock('~/lib/utils/common_utils');
+jest.mock('~/flash');
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('packages_list_app', () => {
+ let wrapper;
+ let store;
+
+ const PackageList = {
+ name: 'package-list',
+ template: '<div><slot name="empty-state"></slot></div>',
+ };
+ const GlLoadingIcon = { name: 'gl-loading-icon', template: '<div>loading</div>' };
+
+ // we need to manually stub dynamic imported components because shallowMount is not able to stub them automatically. See: https://github.com/vuejs/vue-test-utils/issues/1279
+ const PackageSearch = { name: 'PackageSearch', template: '<div></div>' };
+ const PackageTitle = { name: 'PackageTitle', template: '<div></div>' };
+ const InfrastructureTitle = { name: 'InfrastructureTitle', template: '<div></div>' };
+ const InfrastructureSearch = { name: 'InfrastructureSearch', template: '<div></div>' };
+
+ const emptyListHelpUrl = 'helpUrl';
+ const findEmptyState = () => wrapper.find(GlEmptyState);
+ const findListComponent = () => wrapper.find(PackageList);
+ const findPackageSearch = () => wrapper.find(PackageSearch);
+ const findPackageTitle = () => wrapper.find(PackageTitle);
+ const findInfrastructureTitle = () => wrapper.find(InfrastructureTitle);
+ const findInfrastructureSearch = () => wrapper.find(InfrastructureSearch);
+
+ const createStore = (filter = []) => {
+ store = new Vuex.Store({
+ state: {
+ isLoading: false,
+ config: {
+ resourceId: 'project_id',
+ emptyListIllustration: 'helpSvg',
+ emptyListHelpUrl,
+ packageHelpUrl: 'foo',
+ },
+ filter,
+ },
+ });
+ store.dispatch = jest.fn();
+ };
+
+ const mountComponent = (provide) => {
+ wrapper = shallowMount(PackageListApp, {
+ localVue,
+ store,
+ stubs: {
+ GlEmptyState,
+ GlLoadingIcon,
+ PackageList,
+ GlSprintf,
+ GlLink,
+ PackageSearch,
+ PackageTitle,
+ InfrastructureTitle,
+ InfrastructureSearch,
+ },
+ provide,
+ });
+ };
+
+ beforeEach(() => {
+ createStore();
+ jest.spyOn(packageUtils, 'getQueryParams').mockReturnValue({});
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders', () => {
+ mountComponent();
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ it('call requestPackagesList on page:changed', () => {
+ mountComponent();
+ store.dispatch.mockClear();
+
+ const list = findListComponent();
+ list.vm.$emit('page:changed', 1);
+ expect(store.dispatch).toHaveBeenCalledWith('requestPackagesList', { page: 1 });
+ });
+
+ it('call requestDeletePackage on package:delete', () => {
+ mountComponent();
+
+ const list = findListComponent();
+ list.vm.$emit('package:delete', 'foo');
+ expect(store.dispatch).toHaveBeenCalledWith('requestDeletePackage', 'foo');
+ });
+
+ it('does call requestPackagesList only one time on render', () => {
+ mountComponent();
+
+ expect(store.dispatch).toHaveBeenCalledTimes(3);
+ expect(store.dispatch).toHaveBeenNthCalledWith(1, 'setSorting', expect.any(Object));
+ expect(store.dispatch).toHaveBeenNthCalledWith(2, 'setFilter', expect.any(Array));
+ expect(store.dispatch).toHaveBeenNthCalledWith(3, 'requestPackagesList');
+ });
+
+ describe('url query string handling', () => {
+ const defaultQueryParamsMock = {
+ search: [1, 2],
+ type: 'npm',
+ sort: 'asc',
+ orderBy: 'created',
+ };
+
+ it('calls setSorting with the query string based sorting', () => {
+ jest.spyOn(packageUtils, 'getQueryParams').mockReturnValue(defaultQueryParamsMock);
+
+ mountComponent();
+
+ expect(store.dispatch).toHaveBeenNthCalledWith(1, 'setSorting', {
+ orderBy: defaultQueryParamsMock.orderBy,
+ sort: defaultQueryParamsMock.sort,
+ });
+ });
+
+ it('calls setFilter with the query string based filters', () => {
+ jest.spyOn(packageUtils, 'getQueryParams').mockReturnValue(defaultQueryParamsMock);
+
+ mountComponent();
+
+ expect(store.dispatch).toHaveBeenNthCalledWith(2, 'setFilter', [
+ { type: 'type', value: { data: defaultQueryParamsMock.type } },
+ { type: FILTERED_SEARCH_TERM, value: { data: defaultQueryParamsMock.search[0] } },
+ { type: FILTERED_SEARCH_TERM, value: { data: defaultQueryParamsMock.search[1] } },
+ ]);
+ });
+
+ it('calls setSorting and setFilters with the results of extractFilterAndSorting', () => {
+ jest
+ .spyOn(packageUtils, 'extractFilterAndSorting')
+ .mockReturnValue({ filters: ['foo'], sorting: { sort: 'desc' } });
+
+ mountComponent();
+
+ expect(store.dispatch).toHaveBeenNthCalledWith(1, 'setSorting', { sort: 'desc' });
+ expect(store.dispatch).toHaveBeenNthCalledWith(2, 'setFilter', ['foo']);
+ });
+ });
+
+ describe('empty state', () => {
+ it('generate the correct empty list link', () => {
+ mountComponent();
+
+ const link = findListComponent().find(GlLink);
+
+ expect(link.attributes('href')).toBe(emptyListHelpUrl);
+ expect(link.text()).toBe('publish and share your packages');
+ });
+
+ it('includes the right content on the default tab', () => {
+ mountComponent();
+
+ const heading = findEmptyState().find('h1');
+
+ expect(heading.text()).toBe('There are no packages yet');
+ });
+ });
+
+ describe('filter without results', () => {
+ beforeEach(() => {
+ createStore([{ type: 'something' }]);
+ mountComponent();
+ });
+
+ it('should show specific empty message', () => {
+ expect(findEmptyState().text()).toContain('Sorry, your filter produced no results');
+ expect(findEmptyState().text()).toContain(
+ 'To widen your search, change or remove the filters above',
+ );
+ });
+ });
+
+ describe('Package Search', () => {
+ it('exists', () => {
+ mountComponent();
+
+ expect(findPackageSearch().exists()).toBe(true);
+ });
+
+ it('on update fetches data from the store', () => {
+ mountComponent();
+ store.dispatch.mockClear();
+
+ findPackageSearch().vm.$emit('update');
+
+ expect(store.dispatch).toHaveBeenCalledWith('requestPackagesList');
+ });
+ });
+
+ describe('Infrastructure config', () => {
+ it('defaults to package registry components', () => {
+ mountComponent();
+
+ expect(findPackageSearch().exists()).toBe(true);
+ expect(findPackageTitle().exists()).toBe(true);
+
+ expect(findInfrastructureTitle().exists()).toBe(false);
+ expect(findInfrastructureSearch().exists()).toBe(false);
+ });
+
+ it('mount different component based on the provided values', () => {
+ mountComponent({
+ titleComponent: 'InfrastructureTitle',
+ searchComponent: 'InfrastructureSearch',
+ });
+
+ expect(findPackageSearch().exists()).toBe(false);
+ expect(findPackageTitle().exists()).toBe(false);
+
+ expect(findInfrastructureTitle().exists()).toBe(true);
+ expect(findInfrastructureSearch().exists()).toBe(true);
+ });
+ });
+
+ describe('delete alert handling', () => {
+ const originalLocation = window.location.href;
+ const search = `?${SHOW_DELETE_SUCCESS_ALERT}=true`;
+
+ beforeEach(() => {
+ createStore();
+ jest.spyOn(commonUtils, 'historyReplaceState').mockImplementation(() => {});
+ setWindowLocation(search);
+ });
+
+ afterEach(() => {
+ setWindowLocation(originalLocation);
+ });
+
+ it(`creates a flash if the query string contains ${SHOW_DELETE_SUCCESS_ALERT}`, () => {
+ mountComponent();
+
+ expect(createFlash).toHaveBeenCalledWith({
+ message: DELETE_PACKAGE_SUCCESS_MESSAGE,
+ type: 'notice',
+ });
+ });
+
+ it('calls historyReplaceState with a clean url', () => {
+ mountComponent();
+
+ expect(commonUtils.historyReplaceState).toHaveBeenCalledWith(originalLocation);
+ });
+
+ it(`does nothing if the query string does not contain ${SHOW_DELETE_SUCCESS_ALERT}`, () => {
+ setWindowLocation('?');
+ mountComponent();
+
+ expect(createFlash).not.toHaveBeenCalled();
+ expect(commonUtils.historyReplaceState).not.toHaveBeenCalled();
+ });
+ });
+});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/list/packages_list_spec.js b/spec/frontend/packages_and_registries/package_registry/components/list/packages_list_spec.js
new file mode 100644
index 00000000000..b624e66482d
--- /dev/null
+++ b/spec/frontend/packages_and_registries/package_registry/components/list/packages_list_spec.js
@@ -0,0 +1,217 @@
+import { GlTable, GlPagination, GlModal } from '@gitlab/ui';
+import { mount, createLocalVue } from '@vue/test-utils';
+import { last } from 'lodash';
+import Vuex from 'vuex';
+import stubChildren from 'helpers/stub_children';
+import { packageList } from 'jest/packages/mock_data';
+import PackagesListRow from '~/packages/shared/components/package_list_row.vue';
+import PackagesListLoader from '~/packages/shared/components/packages_list_loader.vue';
+import { TrackingActions } from '~/packages/shared/constants';
+import * as SharedUtils from '~/packages/shared/utils';
+import PackagesList from '~/packages_and_registries/package_registry/components/list/packages_list.vue';
+import Tracking from '~/tracking';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('packages_list', () => {
+ let wrapper;
+ let store;
+
+ const EmptySlotStub = { name: 'empty-slot-stub', template: '<div>bar</div>' };
+
+ const findPackagesListLoader = () => wrapper.find(PackagesListLoader);
+ const findPackageListPagination = () => wrapper.find(GlPagination);
+ const findPackageListDeleteModal = () => wrapper.find(GlModal);
+ const findEmptySlot = () => wrapper.find(EmptySlotStub);
+ const findPackagesListRow = () => wrapper.find(PackagesListRow);
+
+ const createStore = (isGroupPage, packages, isLoading) => {
+ const state = {
+ isLoading,
+ packages,
+ pagination: {
+ perPage: 1,
+ total: 1,
+ page: 1,
+ },
+ config: {
+ isGroupPage,
+ },
+ sorting: {
+ orderBy: 'version',
+ sort: 'desc',
+ },
+ };
+ store = new Vuex.Store({
+ state,
+ getters: {
+ getList: () => packages,
+ },
+ });
+ store.dispatch = jest.fn();
+ };
+
+ const mountComponent = ({
+ isGroupPage = false,
+ packages = packageList,
+ isLoading = false,
+ ...options
+ } = {}) => {
+ createStore(isGroupPage, packages, isLoading);
+
+ wrapper = mount(PackagesList, {
+ localVue,
+ store,
+ stubs: {
+ ...stubChildren(PackagesList),
+ GlTable,
+ GlModal,
+ },
+ ...options,
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ describe('when is loading', () => {
+ beforeEach(() => {
+ mountComponent({
+ packages: [],
+ isLoading: true,
+ });
+ });
+
+ it('shows skeleton loader when loading', () => {
+ expect(findPackagesListLoader().exists()).toBe(true);
+ });
+ });
+
+ describe('when is not loading', () => {
+ beforeEach(() => {
+ mountComponent();
+ });
+
+ it('does not show skeleton loader when not loading', () => {
+ expect(findPackagesListLoader().exists()).toBe(false);
+ });
+ });
+
+ describe('layout', () => {
+ beforeEach(() => {
+ mountComponent();
+ });
+
+ it('contains a pagination component', () => {
+ const sorting = findPackageListPagination();
+ expect(sorting.exists()).toBe(true);
+ });
+
+ it('contains a modal component', () => {
+ const sorting = findPackageListDeleteModal();
+ expect(sorting.exists()).toBe(true);
+ });
+ });
+
+ describe('when the user can destroy the package', () => {
+ beforeEach(() => {
+ mountComponent();
+ });
+
+ it('setItemToBeDeleted sets itemToBeDeleted and open the modal', () => {
+ const mockModalShow = jest.spyOn(wrapper.vm.$refs.packageListDeleteModal, 'show');
+ const item = last(wrapper.vm.list);
+
+ findPackagesListRow().vm.$emit('packageToDelete', item);
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.vm.itemToBeDeleted).toEqual(item);
+ expect(mockModalShow).toHaveBeenCalled();
+ });
+ });
+
+ it('deleteItemConfirmation resets itemToBeDeleted', () => {
+ wrapper.setData({ itemToBeDeleted: 1 });
+ wrapper.vm.deleteItemConfirmation();
+ expect(wrapper.vm.itemToBeDeleted).toEqual(null);
+ });
+
+ it('deleteItemConfirmation emit package:delete', () => {
+ const itemToBeDeleted = { id: 2 };
+ wrapper.setData({ itemToBeDeleted });
+ wrapper.vm.deleteItemConfirmation();
+ return wrapper.vm.$nextTick(() => {
+ expect(wrapper.emitted('package:delete')[0]).toEqual([itemToBeDeleted]);
+ });
+ });
+
+ it('deleteItemCanceled resets itemToBeDeleted', () => {
+ wrapper.setData({ itemToBeDeleted: 1 });
+ wrapper.vm.deleteItemCanceled();
+ expect(wrapper.vm.itemToBeDeleted).toEqual(null);
+ });
+ });
+
+ describe('when the list is empty', () => {
+ beforeEach(() => {
+ mountComponent({
+ packages: [],
+ slots: {
+ 'empty-state': EmptySlotStub,
+ },
+ });
+ });
+
+ it('show the empty slot', () => {
+ const emptySlot = findEmptySlot();
+ expect(emptySlot.exists()).toBe(true);
+ });
+ });
+
+ describe('pagination component', () => {
+ let pagination;
+ let modelEvent;
+
+ beforeEach(() => {
+ mountComponent();
+ pagination = findPackageListPagination();
+ // retrieve the event used by v-model, a more sturdy approach than hardcoding it
+ modelEvent = pagination.vm.$options.model.event;
+ });
+
+ it('emits page:changed events when the page changes', () => {
+ pagination.vm.$emit(modelEvent, 2);
+ expect(wrapper.emitted('page:changed')).toEqual([[2]]);
+ });
+ });
+
+ describe('tracking', () => {
+ let eventSpy;
+ let utilSpy;
+ const category = 'foo';
+
+ beforeEach(() => {
+ mountComponent();
+ eventSpy = jest.spyOn(Tracking, 'event');
+ utilSpy = jest.spyOn(SharedUtils, 'packageTypeToTrackCategory').mockReturnValue(category);
+ wrapper.setData({ itemToBeDeleted: { package_type: 'conan' } });
+ });
+
+ it('tracking category calls packageTypeToTrackCategory', () => {
+ expect(wrapper.vm.tracking.category).toBe(category);
+ expect(utilSpy).toHaveBeenCalledWith('conan');
+ });
+
+ it('deleteItemConfirmation calls event', () => {
+ wrapper.vm.deleteItemConfirmation();
+ expect(eventSpy).toHaveBeenCalledWith(
+ category,
+ TrackingActions.DELETE_PACKAGE,
+ expect.any(Object),
+ );
+ });
+ });
+});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/list/packages_search_spec.js b/spec/frontend/packages_and_registries/package_registry/components/list/packages_search_spec.js
new file mode 100644
index 00000000000..42bc9fa3a9e
--- /dev/null
+++ b/spec/frontend/packages_and_registries/package_registry/components/list/packages_search_spec.js
@@ -0,0 +1,128 @@
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import Vuex from 'vuex';
+import { sortableFields } from '~/packages/list/utils';
+import component from '~/packages_and_registries/package_registry/components/list/package_search.vue';
+import PackageTypeToken from '~/packages_and_registries/package_registry/components/list/tokens/package_type_token.vue';
+import RegistrySearch from '~/vue_shared/components/registry/registry_search.vue';
+import UrlSync from '~/vue_shared/components/url_sync.vue';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('Package Search', () => {
+ let wrapper;
+ let store;
+
+ const findRegistrySearch = () => wrapper.findComponent(RegistrySearch);
+ const findUrlSync = () => wrapper.findComponent(UrlSync);
+
+ const createStore = (isGroupPage) => {
+ const state = {
+ config: {
+ isGroupPage,
+ },
+ sorting: {
+ orderBy: 'version',
+ sort: 'desc',
+ },
+ filter: [],
+ };
+ store = new Vuex.Store({
+ state,
+ });
+ store.dispatch = jest.fn();
+ };
+
+ const mountComponent = (isGroupPage = false) => {
+ createStore(isGroupPage);
+
+ wrapper = shallowMount(component, {
+ localVue,
+ store,
+ stubs: {
+ UrlSync,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('has a registry search component', () => {
+ mountComponent();
+
+ expect(findRegistrySearch().exists()).toBe(true);
+ expect(findRegistrySearch().props()).toMatchObject({
+ filter: store.state.filter,
+ sorting: store.state.sorting,
+ tokens: expect.arrayContaining([
+ expect.objectContaining({ token: PackageTypeToken, type: 'type', icon: 'package' }),
+ ]),
+ sortableFields: sortableFields(),
+ });
+ });
+
+ it.each`
+ isGroupPage | page
+ ${false} | ${'project'}
+ ${true} | ${'group'}
+ `('in a $page page binds the right props', ({ isGroupPage }) => {
+ mountComponent(isGroupPage);
+
+ expect(findRegistrySearch().props()).toMatchObject({
+ filter: store.state.filter,
+ sorting: store.state.sorting,
+ tokens: expect.arrayContaining([
+ expect.objectContaining({ token: PackageTypeToken, type: 'type', icon: 'package' }),
+ ]),
+ sortableFields: sortableFields(isGroupPage),
+ });
+ });
+
+ it('on sorting:changed emits update event and calls vuex setSorting', () => {
+ const payload = { sort: 'foo' };
+
+ mountComponent();
+
+ findRegistrySearch().vm.$emit('sorting:changed', payload);
+
+ expect(store.dispatch).toHaveBeenCalledWith('setSorting', payload);
+ expect(wrapper.emitted('update')).toEqual([[]]);
+ });
+
+ it('on filter:changed calls vuex setFilter', () => {
+ const payload = ['foo'];
+
+ mountComponent();
+
+ findRegistrySearch().vm.$emit('filter:changed', payload);
+
+ expect(store.dispatch).toHaveBeenCalledWith('setFilter', payload);
+ });
+
+ it('on filter:submit emits update event', () => {
+ mountComponent();
+
+ findRegistrySearch().vm.$emit('filter:submit');
+
+ expect(wrapper.emitted('update')).toEqual([[]]);
+ });
+
+ it('has a UrlSync component', () => {
+ mountComponent();
+
+ expect(findUrlSync().exists()).toBe(true);
+ });
+
+ it('on query:changed calls updateQuery from UrlSync', () => {
+ jest.spyOn(UrlSync.methods, 'updateQuery').mockImplementation(() => {});
+
+ mountComponent();
+
+ findRegistrySearch().vm.$emit('query:changed');
+
+ expect(UrlSync.methods.updateQuery).toHaveBeenCalled();
+ });
+});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/list/packages_title_spec.js b/spec/frontend/packages_and_registries/package_registry/components/list/packages_title_spec.js
new file mode 100644
index 00000000000..3fa96ce1d29
--- /dev/null
+++ b/spec/frontend/packages_and_registries/package_registry/components/list/packages_title_spec.js
@@ -0,0 +1,71 @@
+import { shallowMount } from '@vue/test-utils';
+import { LIST_INTRO_TEXT, LIST_TITLE_TEXT } from '~/packages/list/constants';
+import PackageTitle from '~/packages_and_registries/package_registry/components/list/package_title.vue';
+import MetadataItem from '~/vue_shared/components/registry/metadata_item.vue';
+import TitleArea from '~/vue_shared/components/registry/title_area.vue';
+
+describe('PackageTitle', () => {
+ let wrapper;
+ let store;
+
+ const findTitleArea = () => wrapper.find(TitleArea);
+ const findMetadataItem = () => wrapper.find(MetadataItem);
+
+ const mountComponent = (propsData = { helpUrl: 'foo' }) => {
+ wrapper = shallowMount(PackageTitle, {
+ store,
+ propsData,
+ stubs: {
+ TitleArea,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ describe('title area', () => {
+ it('exists', () => {
+ mountComponent();
+
+ expect(findTitleArea().exists()).toBe(true);
+ });
+
+ it('has the correct props', () => {
+ mountComponent();
+
+ expect(findTitleArea().props()).toMatchObject({
+ title: LIST_TITLE_TEXT,
+ infoMessages: [{ text: LIST_INTRO_TEXT, link: 'foo' }],
+ });
+ });
+ });
+
+ describe.each`
+ count | exist | text
+ ${null} | ${false} | ${''}
+ ${undefined} | ${false} | ${''}
+ ${0} | ${true} | ${'0 Packages'}
+ ${1} | ${true} | ${'1 Package'}
+ ${2} | ${true} | ${'2 Packages'}
+ `('when count is $count metadata item', ({ count, exist, text }) => {
+ beforeEach(() => {
+ mountComponent({ count, helpUrl: 'foo' });
+ });
+
+ it(`is ${exist} that it exists`, () => {
+ expect(findMetadataItem().exists()).toBe(exist);
+ });
+
+ if (exist) {
+ it('has the correct props', () => {
+ expect(findMetadataItem().props()).toMatchObject({
+ icon: 'package',
+ text,
+ });
+ });
+ }
+ });
+});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/list/tokens/package_type_token_spec.js b/spec/frontend/packages_and_registries/package_registry/components/list/tokens/package_type_token_spec.js
new file mode 100644
index 00000000000..b0cbe34f0b9
--- /dev/null
+++ b/spec/frontend/packages_and_registries/package_registry/components/list/tokens/package_type_token_spec.js
@@ -0,0 +1,48 @@
+import { GlFilteredSearchToken, GlFilteredSearchSuggestion } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import component from '~/packages/list/components/tokens/package_type_token.vue';
+import { PACKAGE_TYPES } from '~/packages/list/constants';
+
+describe('packages_filter', () => {
+ let wrapper;
+
+ const findFilteredSearchToken = () => wrapper.find(GlFilteredSearchToken);
+ const findFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
+
+ const mountComponent = ({ attrs, listeners } = {}) => {
+ wrapper = shallowMount(component, {
+ attrs,
+ listeners,
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('it binds all of his attrs to filtered search token', () => {
+ mountComponent({ attrs: { foo: 'bar' } });
+
+ expect(findFilteredSearchToken().attributes('foo')).toBe('bar');
+ });
+
+ it('it binds all of his events to filtered search token', () => {
+ const clickListener = jest.fn();
+ mountComponent({ listeners: { click: clickListener } });
+
+ findFilteredSearchToken().vm.$emit('click');
+
+ expect(clickListener).toHaveBeenCalled();
+ });
+
+ it.each(PACKAGE_TYPES.map((p, index) => [p, index]))(
+ 'displays a suggestion for %p',
+ (packageType, index) => {
+ mountComponent();
+ const item = findFilteredSearchSuggestions().at(index);
+ expect(item.text()).toBe(packageType.title);
+ expect(item.props('value')).toBe(packageType.type);
+ },
+ );
+});
diff --git a/spec/frontend/packages_and_registries/package_registry/mock_data.js b/spec/frontend/packages_and_registries/package_registry/mock_data.js
index 98ff29ef728..9438a2d2d72 100644
--- a/spec/frontend/packages_and_registries/package_registry/mock_data.js
+++ b/spec/frontend/packages_and_registries/package_registry/mock_data.js
@@ -133,7 +133,7 @@ export const composerMetadata = () => ({
},
});
-export const pypyMetadata = () => ({
+export const pypiMetadata = () => ({
requiredPython: '1.0.0',
});
@@ -157,7 +157,7 @@ export const packageDetailsQuery = (extendPackage) => ({
metadata: {
...conanMetadata(),
...composerMetadata(),
- ...pypyMetadata(),
+ ...pypiMetadata(),
...mavenMetadata(),
...nugetMetadata(),
},
diff --git a/spec/frontend/pages/dashboard/projects/index/components/customize_homepage_banner_spec.js b/spec/frontend/pages/dashboard/projects/index/components/customize_homepage_banner_spec.js
index 63c1260560b..f84800d8266 100644
--- a/spec/frontend/pages/dashboard/projects/index/components/customize_homepage_banner_spec.js
+++ b/spec/frontend/pages/dashboard/projects/index/components/customize_homepage_banner_spec.js
@@ -65,7 +65,7 @@ describe('CustomizeHomepageBanner', () => {
await wrapper.vm.$nextTick();
const button = wrapper.find(`[href='${wrapper.vm.preferencesBehaviorPath}']`);
- expect(button.attributes('data-track-event')).toEqual(preferencesTrackingEvent);
+ expect(button.attributes('data-track-action')).toEqual(preferencesTrackingEvent);
expect(button.attributes('data-track-label')).toEqual(provide.trackLabel);
});
diff --git a/spec/frontend/pages/projects/graphs/__snapshots__/code_coverage_spec.js.snap b/spec/frontend/pages/projects/graphs/__snapshots__/code_coverage_spec.js.snap
index 4ba9120d196..417567c9f4c 100644
--- a/spec/frontend/pages/projects/graphs/__snapshots__/code_coverage_spec.js.snap
+++ b/spec/frontend/pages/projects/graphs/__snapshots__/code_coverage_spec.js.snap
@@ -11,8 +11,12 @@ exports[`Code Coverage when fetching data is successful matches the snapshot 1`]
<gl-dropdown-stub
category="primary"
+ clearalltext="Clear all"
headertext=""
hideheaderborder="true"
+ highlighteditemstitle="Selected"
+ highlighteditemstitleclass="gl-px-5"
+ showhighlighteditemstitle="true"
size="medium"
text="rspec"
variant="default"
diff --git a/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_a_spec.js.snap b/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_a_spec.js.snap
deleted file mode 100644
index 59b42de2485..00000000000
--- a/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_a_spec.js.snap
+++ /dev/null
@@ -1,371 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Learn GitLab Design A renders correctly 1`] = `
-<div>
- <div
- class="row"
- >
- <div
- class="gl-mb-7 gl-ml-5"
- >
- <h1
- class="gl-font-size-h1"
- >
- Learn GitLab
- </h1>
-
- <p
- class="gl-text-gray-700 gl-mb-0"
- >
- Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project.
- </p>
- </div>
- </div>
-
- <div
- class="gl-mb-3"
- >
- <p
- class="gl-text-gray-500 gl-mb-2"
- data-testid="completion-percentage"
- >
- 22% completed
- </p>
-
- <div
- class="progress"
- max="9"
- value="2"
- >
- <div
- aria-valuemax="9"
- aria-valuemin="0"
- aria-valuenow="2"
- class="progress-bar"
- role="progressbar"
- style="width: 22.22222222222222%;"
- />
- </div>
- </div>
-
- <div
- class="row row-cols-1 row-cols-md-3 gl-mt-5"
- >
- <div
- class="col gl-mb-6"
- >
- <div
- class="gl-card gl-pt-0 learn-gitlab-section-card"
- >
- <!---->
-
- <div
- class="gl-card-body"
- >
- <div
- class="learn-gitlab-section-card-header"
- >
- <img
- src="workspace.svg"
- />
-
- <h2
- class="gl-font-lg gl-mb-3"
- >
- Set up your workspace
- </h2>
-
- <p
- class="gl-text-gray-700 gl-mb-6"
- >
- Complete these tasks first so you can enjoy GitLab's features to their fullest:
- </p>
- </div>
-
- <div
- class="gl-mb-4"
- >
- <span
- class="gl-text-green-500"
- >
- <svg
- aria-hidden="true"
- class="gl-icon s16"
- data-testid="completed-icon"
- role="img"
- >
- <use
- href="#check-circle-filled"
- />
- </svg>
-
- Invite your colleagues
-
- </span>
-
- <!---->
- </div>
- <div
- class="gl-mb-4"
- >
- <span
- class="gl-text-green-500"
- >
- <svg
- aria-hidden="true"
- class="gl-icon s16"
- data-testid="completed-icon"
- role="img"
- >
- <use
- href="#check-circle-filled"
- />
- </svg>
-
- Create or import a repository
-
- </span>
-
- <!---->
- </div>
- <div
- class="gl-mb-4"
- >
- <span>
- <a
- class="gl-link"
- data-track-action="click_link"
- data-track-label="Set up CI/CD"
- data-track-property="Growth::Conversion::Experiment::LearnGitLabA"
- href="http://example.com/"
- rel="noopener noreferrer"
- target="_blank"
- >
-
- Set up CI/CD
-
- </a>
- </span>
-
- <!---->
- </div>
- <div
- class="gl-mb-4"
- >
- <span>
- <a
- class="gl-link"
- data-track-action="click_link"
- data-track-label="Start a free Ultimate trial"
- data-track-property="Growth::Conversion::Experiment::LearnGitLabA"
- href="http://example.com/"
- rel="noopener noreferrer"
- target="_blank"
- >
-
- Start a free Ultimate trial
-
- </a>
- </span>
-
- <!---->
- </div>
- <div
- class="gl-mb-4"
- >
- <span>
- <a
- class="gl-link"
- data-track-action="click_link"
- data-track-label="Add code owners"
- data-track-property="Growth::Conversion::Experiment::LearnGitLabA"
- href="http://example.com/"
- rel="noopener noreferrer"
- target="_blank"
- >
-
- Add code owners
-
- </a>
- </span>
-
- <span
- class="gl-font-style-italic gl-text-gray-500"
- data-testid="trial-only"
- >
-
- - Trial only
-
- </span>
- </div>
- <div
- class="gl-mb-4"
- >
- <span>
- <a
- class="gl-link"
- data-track-action="click_link"
- data-track-label="Add merge request approval"
- data-track-property="Growth::Conversion::Experiment::LearnGitLabA"
- href="http://example.com/"
- rel="noopener noreferrer"
- target="_blank"
- >
-
- Add merge request approval
-
- </a>
- </span>
-
- <span
- class="gl-font-style-italic gl-text-gray-500"
- data-testid="trial-only"
- >
-
- - Trial only
-
- </span>
- </div>
- </div>
-
- <!---->
- </div>
- </div>
- <div
- class="col gl-mb-6"
- >
- <div
- class="gl-card gl-pt-0 learn-gitlab-section-card"
- >
- <!---->
-
- <div
- class="gl-card-body"
- >
- <div
- class="learn-gitlab-section-card-header"
- >
- <img
- src="plan.svg"
- />
-
- <h2
- class="gl-font-lg gl-mb-3"
- >
- Plan and execute
- </h2>
-
- <p
- class="gl-text-gray-700 gl-mb-6"
- >
- Create a workflow for your new workspace, and learn how GitLab features work together:
- </p>
- </div>
-
- <div
- class="gl-mb-4"
- >
- <span>
- <a
- class="gl-link"
- data-track-action="click_link"
- data-track-label="Create an issue"
- data-track-property="Growth::Conversion::Experiment::LearnGitLabA"
- href="http://example.com/"
- rel="noopener noreferrer"
- target="_blank"
- >
-
- Create an issue
-
- </a>
- </span>
-
- <!---->
- </div>
- <div
- class="gl-mb-4"
- >
- <span>
- <a
- class="gl-link"
- data-track-action="click_link"
- data-track-label="Submit a merge request"
- data-track-property="Growth::Conversion::Experiment::LearnGitLabA"
- href="http://example.com/"
- rel="noopener noreferrer"
- target="_blank"
- >
-
- Submit a merge request
-
- </a>
- </span>
-
- <!---->
- </div>
- </div>
-
- <!---->
- </div>
- </div>
- <div
- class="col gl-mb-6"
- >
- <div
- class="gl-card gl-pt-0 learn-gitlab-section-card"
- >
- <!---->
-
- <div
- class="gl-card-body"
- >
- <div
- class="learn-gitlab-section-card-header"
- >
- <img
- src="deploy.svg"
- />
-
- <h2
- class="gl-font-lg gl-mb-3"
- >
- Deploy
- </h2>
-
- <p
- class="gl-text-gray-700 gl-mb-6"
- >
- Use your new GitLab workflow to deploy your application, monitor its health, and keep it secure:
- </p>
- </div>
-
- <div
- class="gl-mb-4"
- >
- <span>
- <a
- class="gl-link"
- data-track-action="click_link"
- data-track-label="Run a Security scan using CI/CD"
- data-track-property="Growth::Conversion::Experiment::LearnGitLabA"
- href="http://example.com/"
- rel="noopener noreferrer"
- target="_blank"
- >
-
- Run a Security scan using CI/CD
-
- </a>
- </span>
-
- <!---->
- </div>
- </div>
-
- <!---->
- </div>
- </div>
- </div>
-</div>
-`;
diff --git a/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_b_spec.js.snap b/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_b_spec.js.snap
deleted file mode 100644
index 091edc7505c..00000000000
--- a/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_b_spec.js.snap
+++ /dev/null
@@ -1,604 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Learn GitLab Design B renders correctly 1`] = `
-<div>
- <div
- class="row"
- >
- <div
- class="gl-mb-7 col-md-8 col-lg-7"
- >
- <h1
- class="gl-font-size-h1"
- >
- Learn GitLab
- </h1>
-
- <p
- class="gl-text-gray-700 gl-mb-0"
- >
- Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project.
- </p>
- </div>
- </div>
-
- <div
- class="gl-mb-3"
- >
- <p
- class="gl-text-gray-500 gl-mb-2"
- data-testid="completion-percentage"
- >
- 22% completed
- </p>
-
- <div
- class="progress"
- max="9"
- value="2"
- >
- <div
- aria-valuemax="9"
- aria-valuemin="0"
- aria-valuenow="2"
- class="progress-bar"
- role="progressbar"
- style="width: 22.22222222222222%;"
- />
- </div>
- </div>
-
- <h2
- class="gl-font-lg gl-mb-3"
- >
- Set up your workspace
- </h2>
-
- <p
- class="gl-text-gray-700 gl-mb-6"
- >
- Complete these tasks first so you can enjoy GitLab's features to their fullest:
- </p>
-
- <div
- class="row row-cols-2 row-cols-md-3 row-cols-lg-4"
- >
- <div
- class="col gl-mb-6"
- >
- <div
- class="gl-card gl-pt-0"
- >
- <!---->
-
- <div
- class="gl-card-body"
- >
- <div
- class="gl-text-right gl-h-5"
- >
- <svg
- aria-hidden="true"
- class="gl-text-green-500 gl-icon s16"
- data-testid="completed-icon"
- role="img"
- >
- <use
- href="#check-circle-filled"
- />
- </svg>
- </div>
-
- <div
- class="gl-text-center gl-display-flex gl-justify-content-center gl-align-items-center gl-flex-direction-column learn-gitlab-info-card-content"
- >
- <img
- alt="Invite your colleagues"
- src="http://example.com/images/illustration.svg"
- />
-
- <h6>
- Invite your colleagues
- </h6>
-
- <p
- class="gl-font-sm gl-text-gray-700"
- >
- GitLab works best as a team. Invite your colleague to enjoy all features.
- </p>
-
- <a
- class="gl-link"
- data-track-action="click_link"
- data-track-label="Invite your colleagues"
- data-track-property="Growth::Activation::Experiment::LearnGitLabB"
- href="http://example.com/"
- rel="noopener noreferrer"
- target="_blank"
- >
- Invite your colleagues
- </a>
- </div>
- </div>
-
- <!---->
- </div>
- </div>
-
- <div
- class="col gl-mb-6"
- >
- <div
- class="gl-card gl-pt-0"
- >
- <!---->
-
- <div
- class="gl-card-body"
- >
- <div
- class="gl-text-right gl-h-5"
- >
- <svg
- aria-hidden="true"
- class="gl-text-green-500 gl-icon s16"
- data-testid="completed-icon"
- role="img"
- >
- <use
- href="#check-circle-filled"
- />
- </svg>
- </div>
-
- <div
- class="gl-text-center gl-display-flex gl-justify-content-center gl-align-items-center gl-flex-direction-column learn-gitlab-info-card-content"
- >
- <img
- alt="Create or import a repository"
- src="http://example.com/images/illustration.svg"
- />
-
- <h6>
- Create or import a repository
- </h6>
-
- <p
- class="gl-font-sm gl-text-gray-700"
- >
- Create or import your first repository into your new project.
- </p>
-
- <a
- class="gl-link"
- data-track-action="click_link"
- data-track-label="Create or import a repository"
- data-track-property="Growth::Activation::Experiment::LearnGitLabB"
- href="http://example.com/"
- rel="noopener noreferrer"
- target="_blank"
- >
- Create or import a repository
- </a>
- </div>
- </div>
-
- <!---->
- </div>
- </div>
-
- <div
- class="col gl-mb-6"
- >
- <div
- class="gl-card gl-pt-0"
- >
- <!---->
-
- <div
- class="gl-card-body"
- >
- <div
- class="gl-text-right gl-h-5"
- >
- <!---->
- </div>
-
- <div
- class="gl-text-center gl-display-flex gl-justify-content-center gl-align-items-center gl-flex-direction-column learn-gitlab-info-card-content"
- >
- <img
- alt="Set-up CI/CD"
- src="http://example.com/images/illustration.svg"
- />
-
- <h6>
- Set up CI/CD
- </h6>
-
- <p
- class="gl-font-sm gl-text-gray-700"
- >
- Save time by automating your integration and deployment tasks.
- </p>
-
- <a
- class="gl-link"
- data-track-action="click_link"
- data-track-label="Set-up CI/CD"
- data-track-property="Growth::Activation::Experiment::LearnGitLabB"
- href="http://example.com/"
- rel="noopener noreferrer"
- target="_blank"
- >
- Set-up CI/CD
- </a>
- </div>
- </div>
-
- <!---->
- </div>
- </div>
-
- <div
- class="col gl-mb-6"
- >
- <div
- class="gl-card gl-pt-0"
- >
- <!---->
-
- <div
- class="gl-card-body"
- >
- <div
- class="gl-text-right gl-h-5"
- >
- <!---->
- </div>
-
- <div
- class="gl-text-center gl-display-flex gl-justify-content-center gl-align-items-center gl-flex-direction-column learn-gitlab-info-card-content"
- >
- <img
- alt="Try GitLab Ultimate for free"
- src="http://example.com/images/illustration.svg"
- />
-
- <h6>
- Start a free Ultimate trial
- </h6>
-
- <p
- class="gl-font-sm gl-text-gray-700"
- >
- Try all GitLab features for 30 days, no credit card required.
- </p>
-
- <a
- class="gl-link"
- data-track-action="click_link"
- data-track-label="Try GitLab Ultimate for free"
- data-track-property="Growth::Activation::Experiment::LearnGitLabB"
- href="http://example.com/"
- rel="noopener noreferrer"
- target="_blank"
- >
- Try GitLab Ultimate for free
- </a>
- </div>
- </div>
-
- <!---->
- </div>
- </div>
-
- <div
- class="col gl-mb-6"
- >
- <div
- class="gl-card gl-pt-0"
- >
- <!---->
-
- <div
- class="gl-card-body"
- >
- <div
- class="gl-text-right gl-h-5"
- >
- <span
- class="gl-text-gray-500 gl-font-sm gl-font-style-italic"
- data-testid="trial-only"
- >
- Trial only
- </span>
- </div>
-
- <div
- class="gl-text-center gl-display-flex gl-justify-content-center gl-align-items-center gl-flex-direction-column learn-gitlab-info-card-content"
- >
- <img
- alt="Add code owners"
- src="http://example.com/images/illustration.svg"
- />
-
- <h6>
- Add code owners
- </h6>
-
- <p
- class="gl-font-sm gl-text-gray-700"
- >
- Prevent unexpected changes to important assets by assigning ownership of files and paths.
- </p>
-
- <a
- class="gl-link"
- data-track-action="click_link"
- data-track-label="Add code owners"
- data-track-property="Growth::Activation::Experiment::LearnGitLabB"
- href="http://example.com/"
- rel="noopener noreferrer"
- target="_blank"
- >
- Add code owners
- </a>
- </div>
- </div>
-
- <!---->
- </div>
- </div>
-
- <div
- class="col gl-mb-6"
- >
- <div
- class="gl-card gl-pt-0"
- >
- <!---->
-
- <div
- class="gl-card-body"
- >
- <div
- class="gl-text-right gl-h-5"
- >
- <span
- class="gl-text-gray-500 gl-font-sm gl-font-style-italic"
- data-testid="trial-only"
- >
- Trial only
- </span>
- </div>
-
- <div
- class="gl-text-center gl-display-flex gl-justify-content-center gl-align-items-center gl-flex-direction-column learn-gitlab-info-card-content"
- >
- <img
- alt="Enable require merge approvals"
- src="http://example.com/images/illustration.svg"
- />
-
- <h6>
- Add merge request approval
- </h6>
-
- <p
- class="gl-font-sm gl-text-gray-700"
- >
- Route code reviews to the right reviewers, every time.
- </p>
-
- <a
- class="gl-link"
- data-track-action="click_link"
- data-track-label="Enable require merge approvals"
- data-track-property="Growth::Activation::Experiment::LearnGitLabB"
- href="http://example.com/"
- rel="noopener noreferrer"
- target="_blank"
- >
- Enable require merge approvals
- </a>
- </div>
- </div>
-
- <!---->
- </div>
- </div>
- </div>
-
- <h2
- class="gl-font-lg gl-mb-3"
- >
- Plan and execute
- </h2>
-
- <p
- class="gl-text-gray-700 gl-mb-6"
- >
- Create a workflow for your new workspace, and learn how GitLab features work together:
- </p>
-
- <div
- class="row row-cols-2 row-cols-md-3 row-cols-lg-4"
- >
- <div
- class="col gl-mb-6"
- >
- <div
- class="gl-card gl-pt-0"
- >
- <!---->
-
- <div
- class="gl-card-body"
- >
- <div
- class="gl-text-right gl-h-5"
- >
- <!---->
- </div>
-
- <div
- class="gl-text-center gl-display-flex gl-justify-content-center gl-align-items-center gl-flex-direction-column learn-gitlab-info-card-content"
- >
- <img
- alt="Create an issue"
- src="http://example.com/images/illustration.svg"
- />
-
- <h6>
- Create an issue
- </h6>
-
- <p
- class="gl-font-sm gl-text-gray-700"
- >
- Create/import issues (tickets) to collaborate on ideas and plan work.
- </p>
-
- <a
- class="gl-link"
- data-track-action="click_link"
- data-track-label="Create an issue"
- data-track-property="Growth::Activation::Experiment::LearnGitLabB"
- href="http://example.com/"
- rel="noopener noreferrer"
- target="_blank"
- >
- Create an issue
- </a>
- </div>
- </div>
-
- <!---->
- </div>
- </div>
-
- <div
- class="col gl-mb-6"
- >
- <div
- class="gl-card gl-pt-0"
- >
- <!---->
-
- <div
- class="gl-card-body"
- >
- <div
- class="gl-text-right gl-h-5"
- >
- <!---->
- </div>
-
- <div
- class="gl-text-center gl-display-flex gl-justify-content-center gl-align-items-center gl-flex-direction-column learn-gitlab-info-card-content"
- >
- <img
- alt="Submit a merge request (MR)"
- src="http://example.com/images/illustration.svg"
- />
-
- <h6>
- Submit a merge request
- </h6>
-
- <p
- class="gl-font-sm gl-text-gray-700"
- >
- Review and edit proposed changes to source code.
- </p>
-
- <a
- class="gl-link"
- data-track-action="click_link"
- data-track-label="Submit a merge request (MR)"
- data-track-property="Growth::Activation::Experiment::LearnGitLabB"
- href="http://example.com/"
- rel="noopener noreferrer"
- target="_blank"
- >
- Submit a merge request (MR)
- </a>
- </div>
- </div>
-
- <!---->
- </div>
- </div>
- </div>
-
- <h2
- class="gl-font-lg gl-mb-3"
- >
- Deploy
- </h2>
-
- <p
- class="gl-text-gray-700 gl-mb-6"
- >
- Use your new GitLab workflow to deploy your application, monitor its health, and keep it secure:
- </p>
-
- <div
- class="row row-cols-2 row-cols-lg-4 g-2 g-lg-3"
- >
- <div
- class="col gl-mb-6"
- >
- <div
- class="gl-card gl-pt-0"
- >
- <!---->
-
- <div
- class="gl-card-body"
- >
- <div
- class="gl-text-right gl-h-5"
- >
- <!---->
- </div>
-
- <div
- class="gl-text-center gl-display-flex gl-justify-content-center gl-align-items-center gl-flex-direction-column learn-gitlab-info-card-content"
- >
- <img
- alt="Run a Security scan using CI/CD"
- src="http://example.com/images/illustration.svg"
- />
-
- <h6>
- Run a Security scan using CI/CD
- </h6>
-
- <p
- class="gl-font-sm gl-text-gray-700"
- >
- Scan your code to uncover vulnerabilities before deploying.
- </p>
-
- <a
- class="gl-link"
- data-track-action="click_link"
- data-track-label="Run a Security scan using CI/CD"
- data-track-property="Growth::Activation::Experiment::LearnGitLabB"
- href="http://example.com/"
- rel="noopener noreferrer"
- target="_blank"
- >
- Run a Security scan using CI/CD
- </a>
- </div>
- </div>
-
- <!---->
- </div>
- </div>
- </div>
-</div>
-`;
diff --git a/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_spec.js.snap b/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_spec.js.snap
new file mode 100644
index 00000000000..3aa0e99a858
--- /dev/null
+++ b/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_spec.js.snap
@@ -0,0 +1,371 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Learn GitLab renders correctly 1`] = `
+<div>
+ <div
+ class="row"
+ >
+ <div
+ class="gl-mb-7 gl-ml-5"
+ >
+ <h1
+ class="gl-font-size-h1"
+ >
+ Learn GitLab
+ </h1>
+
+ <p
+ class="gl-text-gray-700 gl-mb-0"
+ >
+ Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project.
+ </p>
+ </div>
+ </div>
+
+ <div
+ class="gl-mb-3"
+ >
+ <p
+ class="gl-text-gray-500 gl-mb-2"
+ data-testid="completion-percentage"
+ >
+ 22% completed
+ </p>
+
+ <div
+ class="progress"
+ max="9"
+ value="2"
+ >
+ <div
+ aria-valuemax="9"
+ aria-valuemin="0"
+ aria-valuenow="2"
+ class="progress-bar"
+ role="progressbar"
+ style="width: 22.22222222222222%;"
+ />
+ </div>
+ </div>
+
+ <div
+ class="row row-cols-1 row-cols-md-3 gl-mt-5"
+ >
+ <div
+ class="col gl-mb-6"
+ >
+ <div
+ class="gl-card gl-pt-0 learn-gitlab-section-card"
+ >
+ <!---->
+
+ <div
+ class="gl-card-body"
+ >
+ <div
+ class="learn-gitlab-section-card-header"
+ >
+ <img
+ src="workspace.svg"
+ />
+
+ <h2
+ class="gl-font-lg gl-mb-3"
+ >
+ Set up your workspace
+ </h2>
+
+ <p
+ class="gl-text-gray-700 gl-mb-6"
+ >
+ Complete these tasks first so you can enjoy GitLab's features to their fullest:
+ </p>
+ </div>
+
+ <div
+ class="gl-mb-4"
+ >
+ <span
+ class="gl-text-green-500"
+ >
+ <svg
+ aria-hidden="true"
+ class="gl-icon s16"
+ data-testid="completed-icon"
+ role="img"
+ >
+ <use
+ href="#check-circle-filled"
+ />
+ </svg>
+
+ Invite your colleagues
+
+ </span>
+
+ <!---->
+ </div>
+ <div
+ class="gl-mb-4"
+ >
+ <span
+ class="gl-text-green-500"
+ >
+ <svg
+ aria-hidden="true"
+ class="gl-icon s16"
+ data-testid="completed-icon"
+ role="img"
+ >
+ <use
+ href="#check-circle-filled"
+ />
+ </svg>
+
+ Create or import a repository
+
+ </span>
+
+ <!---->
+ </div>
+ <div
+ class="gl-mb-4"
+ >
+ <span>
+ <a
+ class="gl-link"
+ data-track-action="click_link"
+ data-track-label="Set up CI/CD"
+ data-track-property="Growth::Conversion::Experiment::LearnGitLab"
+ href="http://example.com/"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+
+ Set up CI/CD
+
+ </a>
+ </span>
+
+ <!---->
+ </div>
+ <div
+ class="gl-mb-4"
+ >
+ <span>
+ <a
+ class="gl-link"
+ data-track-action="click_link"
+ data-track-label="Start a free Ultimate trial"
+ data-track-property="Growth::Conversion::Experiment::LearnGitLab"
+ href="http://example.com/"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+
+ Start a free Ultimate trial
+
+ </a>
+ </span>
+
+ <!---->
+ </div>
+ <div
+ class="gl-mb-4"
+ >
+ <span>
+ <a
+ class="gl-link"
+ data-track-action="click_link"
+ data-track-label="Add code owners"
+ data-track-property="Growth::Conversion::Experiment::LearnGitLab"
+ href="http://example.com/"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+
+ Add code owners
+
+ </a>
+ </span>
+
+ <span
+ class="gl-font-style-italic gl-text-gray-500"
+ data-testid="trial-only"
+ >
+
+ - Trial only
+
+ </span>
+ </div>
+ <div
+ class="gl-mb-4"
+ >
+ <span>
+ <a
+ class="gl-link"
+ data-track-action="click_link"
+ data-track-label="Add merge request approval"
+ data-track-property="Growth::Conversion::Experiment::LearnGitLab"
+ href="http://example.com/"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+
+ Add merge request approval
+
+ </a>
+ </span>
+
+ <span
+ class="gl-font-style-italic gl-text-gray-500"
+ data-testid="trial-only"
+ >
+
+ - Trial only
+
+ </span>
+ </div>
+ </div>
+
+ <!---->
+ </div>
+ </div>
+ <div
+ class="col gl-mb-6"
+ >
+ <div
+ class="gl-card gl-pt-0 learn-gitlab-section-card"
+ >
+ <!---->
+
+ <div
+ class="gl-card-body"
+ >
+ <div
+ class="learn-gitlab-section-card-header"
+ >
+ <img
+ src="plan.svg"
+ />
+
+ <h2
+ class="gl-font-lg gl-mb-3"
+ >
+ Plan and execute
+ </h2>
+
+ <p
+ class="gl-text-gray-700 gl-mb-6"
+ >
+ Create a workflow for your new workspace, and learn how GitLab features work together:
+ </p>
+ </div>
+
+ <div
+ class="gl-mb-4"
+ >
+ <span>
+ <a
+ class="gl-link"
+ data-track-action="click_link"
+ data-track-label="Create an issue"
+ data-track-property="Growth::Conversion::Experiment::LearnGitLab"
+ href="http://example.com/"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+
+ Create an issue
+
+ </a>
+ </span>
+
+ <!---->
+ </div>
+ <div
+ class="gl-mb-4"
+ >
+ <span>
+ <a
+ class="gl-link"
+ data-track-action="click_link"
+ data-track-label="Submit a merge request"
+ data-track-property="Growth::Conversion::Experiment::LearnGitLab"
+ href="http://example.com/"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+
+ Submit a merge request
+
+ </a>
+ </span>
+
+ <!---->
+ </div>
+ </div>
+
+ <!---->
+ </div>
+ </div>
+ <div
+ class="col gl-mb-6"
+ >
+ <div
+ class="gl-card gl-pt-0 learn-gitlab-section-card"
+ >
+ <!---->
+
+ <div
+ class="gl-card-body"
+ >
+ <div
+ class="learn-gitlab-section-card-header"
+ >
+ <img
+ src="deploy.svg"
+ />
+
+ <h2
+ class="gl-font-lg gl-mb-3"
+ >
+ Deploy
+ </h2>
+
+ <p
+ class="gl-text-gray-700 gl-mb-6"
+ >
+ Use your new GitLab workflow to deploy your application, monitor its health, and keep it secure:
+ </p>
+ </div>
+
+ <div
+ class="gl-mb-4"
+ >
+ <span>
+ <a
+ class="gl-link"
+ data-track-action="click_link"
+ data-track-label="Run a Security scan using CI/CD"
+ data-track-property="Growth::Conversion::Experiment::LearnGitLab"
+ href="http://example.com/"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+
+ Run a Security scan using CI/CD
+
+ </a>
+ </span>
+
+ <!---->
+ </div>
+ </div>
+
+ <!---->
+ </div>
+ </div>
+ </div>
+</div>
+`;
diff --git a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_a_spec.js b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_a_spec.js
deleted file mode 100644
index ac997c1f237..00000000000
--- a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_a_spec.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import { GlProgressBar } from '@gitlab/ui';
-import { mount } from '@vue/test-utils';
-import LearnGitlabA from '~/pages/projects/learn_gitlab/components/learn_gitlab_a.vue';
-import { testActions, testSections } from './mock_data';
-
-describe('Learn GitLab Design A', () => {
- let wrapper;
-
- const createWrapper = () => {
- wrapper = mount(LearnGitlabA, { propsData: { actions: testActions, sections: testSections } });
- };
-
- beforeEach(() => {
- createWrapper();
- });
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- it('renders correctly', () => {
- expect(wrapper.element).toMatchSnapshot();
- });
-
- it('renders the progress percentage', () => {
- const text = wrapper.find('[data-testid="completion-percentage"]').text();
-
- expect(text).toBe('22% completed');
- });
-
- it('renders the progress bar with correct values', () => {
- const progressBar = wrapper.findComponent(GlProgressBar);
-
- expect(progressBar.attributes('value')).toBe('2');
- expect(progressBar.attributes('max')).toBe('9');
- });
-});
diff --git a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_b_spec.js b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_b_spec.js
deleted file mode 100644
index 207944bfa1f..00000000000
--- a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_b_spec.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import { GlProgressBar } from '@gitlab/ui';
-import { mount } from '@vue/test-utils';
-import LearnGitlabB from '~/pages/projects/learn_gitlab/components/learn_gitlab_b.vue';
-import { testActions } from './mock_data';
-
-describe('Learn GitLab Design B', () => {
- let wrapper;
-
- const createWrapper = () => {
- wrapper = mount(LearnGitlabB, { propsData: { actions: testActions } });
- };
-
- beforeEach(() => {
- createWrapper();
- });
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- it('renders correctly', () => {
- expect(wrapper.element).toMatchSnapshot();
- });
-
- it('renders the progress percentage', () => {
- const text = wrapper.find('[data-testid="completion-percentage"]').text();
-
- expect(text).toBe('22% completed');
- });
-
- it('renders the progress bar with correct values', () => {
- const progressBar = wrapper.findComponent(GlProgressBar);
-
- expect(progressBar.attributes('value')).toBe('2');
- expect(progressBar.attributes('max')).toBe('9');
- });
-});
diff --git a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js
new file mode 100644
index 00000000000..f8099d7e95a
--- /dev/null
+++ b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js
@@ -0,0 +1,38 @@
+import { GlProgressBar } from '@gitlab/ui';
+import { mount } from '@vue/test-utils';
+import LearnGitlab from '~/pages/projects/learn_gitlab/components/learn_gitlab.vue';
+import { testActions, testSections } from './mock_data';
+
+describe('Learn GitLab', () => {
+ let wrapper;
+
+ const createWrapper = () => {
+ wrapper = mount(LearnGitlab, { propsData: { actions: testActions, sections: testSections } });
+ };
+
+ beforeEach(() => {
+ createWrapper();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('renders correctly', () => {
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ it('renders the progress percentage', () => {
+ const text = wrapper.find('[data-testid="completion-percentage"]').text();
+
+ expect(text).toBe('22% completed');
+ });
+
+ it('renders the progress bar with correct values', () => {
+ const progressBar = wrapper.findComponent(GlProgressBar);
+
+ expect(progressBar.attributes('value')).toBe('2');
+ expect(progressBar.attributes('max')).toBe('9');
+ });
+});
diff --git a/spec/frontend/pages/projects/new/components/new_project_url_select_spec.js b/spec/frontend/pages/projects/new/components/new_project_url_select_spec.js
new file mode 100644
index 00000000000..8a7f9229503
--- /dev/null
+++ b/spec/frontend/pages/projects/new/components/new_project_url_select_spec.js
@@ -0,0 +1,122 @@
+import { GlButton, GlDropdown, GlDropdownItem, GlDropdownSectionHeader } from '@gitlab/ui';
+import { createLocalVue, mount, shallowMount } from '@vue/test-utils';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
+import { getIdFromGraphQLId } from '~/graphql_shared/utils';
+import NewProjectUrlSelect from '~/pages/projects/new/components/new_project_url_select.vue';
+import searchQuery from '~/pages/projects/new/queries/search_namespaces_where_user_can_create_projects.query.graphql';
+
+describe('NewProjectUrlSelect component', () => {
+ let wrapper;
+
+ const data = {
+ currentUser: {
+ groups: {
+ nodes: [
+ {
+ id: 'gid://gitlab/Group/26',
+ fullPath: 'flightjs',
+ },
+ {
+ id: 'gid://gitlab/Group/28',
+ fullPath: 'h5bp',
+ },
+ ],
+ },
+ namespace: {
+ id: 'gid://gitlab/Namespace/1',
+ fullPath: 'root',
+ },
+ },
+ };
+
+ const localVue = createLocalVue();
+ localVue.use(VueApollo);
+
+ const requestHandlers = [[searchQuery, jest.fn().mockResolvedValue({ data })]];
+ const apolloProvider = createMockApollo(requestHandlers);
+
+ const provide = {
+ namespaceFullPath: 'h5bp',
+ namespaceId: '28',
+ rootUrl: 'https://gitlab.com/',
+ trackLabel: 'blank_project',
+ };
+
+ const mountComponent = ({ mountFn = shallowMount } = {}) =>
+ mountFn(NewProjectUrlSelect, { localVue, apolloProvider, provide });
+
+ const findButtonLabel = () => wrapper.findComponent(GlButton);
+ const findDropdown = () => wrapper.findComponent(GlDropdown);
+ const findHiddenInput = () => wrapper.find('input');
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders the root url as a label', () => {
+ wrapper = mountComponent();
+
+ expect(findButtonLabel().text()).toBe(provide.rootUrl);
+ expect(findButtonLabel().props('label')).toBe(true);
+ });
+
+ it('renders a dropdown with the initial namespace full path as the text', () => {
+ wrapper = mountComponent();
+
+ expect(findDropdown().props('text')).toBe(provide.namespaceFullPath);
+ });
+
+ it('renders a dropdown with the initial namespace id in the hidden input', () => {
+ wrapper = mountComponent();
+
+ expect(findHiddenInput().attributes('value')).toBe(provide.namespaceId);
+ });
+
+ it('renders expected dropdown items', async () => {
+ wrapper = mountComponent({ mountFn: mount });
+
+ jest.runOnlyPendingTimers();
+ await wrapper.vm.$nextTick();
+
+ const listItems = wrapper.findAll('li');
+
+ expect(listItems.at(0).findComponent(GlDropdownSectionHeader).text()).toBe('Groups');
+ expect(listItems.at(1).text()).toBe(data.currentUser.groups.nodes[0].fullPath);
+ expect(listItems.at(2).text()).toBe(data.currentUser.groups.nodes[1].fullPath);
+ expect(listItems.at(3).findComponent(GlDropdownSectionHeader).text()).toBe('Users');
+ expect(listItems.at(4).text()).toBe(data.currentUser.namespace.fullPath);
+ });
+
+ it('updates hidden input with selected namespace', async () => {
+ wrapper = mountComponent();
+
+ jest.runOnlyPendingTimers();
+ await wrapper.vm.$nextTick();
+
+ wrapper.findComponent(GlDropdownItem).vm.$emit('click');
+
+ await wrapper.vm.$nextTick();
+
+ expect(findHiddenInput().attributes()).toMatchObject({
+ name: 'project[namespace_id]',
+ value: getIdFromGraphQLId(data.currentUser.groups.nodes[0].id).toString(),
+ });
+ });
+
+ it('tracks clicking on the dropdown', () => {
+ wrapper = mountComponent();
+
+ const trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
+
+ findDropdown().vm.$emit('show');
+
+ expect(trackingSpy).toHaveBeenCalledWith(undefined, 'activate_form_input', {
+ label: provide.trackLabel,
+ property: 'project_path',
+ });
+
+ unmockTracking();
+ });
+});
diff --git a/spec/frontend/pages/projects/pipeline_schedules/shared/components/interval_pattern_input_spec.js b/spec/frontend/pages/projects/pipeline_schedules/shared/components/interval_pattern_input_spec.js
index de0d70a07d7..f3d76ca2c1b 100644
--- a/spec/frontend/pages/projects/pipeline_schedules/shared/components/interval_pattern_input_spec.js
+++ b/spec/frontend/pages/projects/pipeline_schedules/shared/components/interval_pattern_input_spec.js
@@ -42,11 +42,6 @@ describe('Interval Pattern Input Component', () => {
wrapper = mount(IntervalPatternInput, {
propsData: { ...props },
- provide: {
- glFeatures: {
- ciDailyLimitForPipelineSchedules: true,
- },
- },
data() {
return {
randomHour: data?.hour || mockHour,
diff --git a/spec/frontend/pages/sessions/new/signin_tabs_memoizer_spec.js b/spec/frontend/pages/sessions/new/signin_tabs_memoizer_spec.js
index 6aa725fbd7d..601fcfedbe0 100644
--- a/spec/frontend/pages/sessions/new/signin_tabs_memoizer_spec.js
+++ b/spec/frontend/pages/sessions/new/signin_tabs_memoizer_spec.js
@@ -21,7 +21,7 @@ describe('SigninTabsMemoizer', () => {
beforeEach(() => {
loadFixtures(fixtureTemplate);
- jest.spyOn(AccessorUtilities, 'isLocalStorageAccessSafe').mockReturnValue(true);
+ jest.spyOn(AccessorUtilities, 'canUseLocalStorage').mockReturnValue(true);
});
it('does nothing if no tab was previously selected', () => {
@@ -90,7 +90,7 @@ describe('SigninTabsMemoizer', () => {
});
it('should set .isLocalStorageAvailable', () => {
- expect(AccessorUtilities.isLocalStorageAccessSafe).toHaveBeenCalled();
+ expect(AccessorUtilities.canUseLocalStorage).toHaveBeenCalled();
expect(memo.isLocalStorageAvailable).toBe(true);
});
});
diff --git a/spec/frontend/pipeline_editor/components/commit/commit_section_spec.js b/spec/frontend/pipeline_editor/components/commit/commit_section_spec.js
index 39081e07e52..2f934898ef1 100644
--- a/spec/frontend/pipeline_editor/components/commit/commit_section_spec.js
+++ b/spec/frontend/pipeline_editor/components/commit/commit_section_spec.js
@@ -1,5 +1,6 @@
import { GlFormTextarea, GlFormInput, GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
+import waitForPromises from 'helpers/wait_for_promises';
import { objectToQuery, redirectTo } from '~/lib/utils/url_utility';
import CommitForm from '~/pipeline_editor/components/commit/commit_form.vue';
import CommitSection from '~/pipeline_editor/components/commit/commit_section.vue';
@@ -48,7 +49,10 @@ describe('Pipeline Editor | Commit section', () => {
let wrapper;
let mockMutate;
- const defaultProps = { ciFileContent: mockCiYml };
+ const defaultProps = {
+ ciFileContent: mockCiYml,
+ commitSha: mockCommitSha,
+ };
const createComponent = ({ props = {}, options = {}, provide = {} } = {}) => {
mockMutate = jest.fn().mockResolvedValue({
@@ -67,7 +71,6 @@ describe('Pipeline Editor | Commit section', () => {
provide: { ...mockProvide, ...provide },
data() {
return {
- commitSha: mockCommitSha,
currentBranch: mockDefaultBranch,
isNewCiConfigFile: Boolean(options?.isNewCiConfigfile),
};
@@ -97,8 +100,7 @@ describe('Pipeline Editor | Commit section', () => {
await findCommitForm().find('[data-testid="new-mr-checkbox"]').setChecked(openMergeRequest);
}
await findCommitForm().find('[type="submit"]').trigger('click');
- // Simulate the write to local cache that occurs after a commit
- await wrapper.setData({ commitSha: mockCommitNextSha });
+ await waitForPromises();
};
const cancelCommitForm = async () => {
@@ -175,6 +177,10 @@ describe('Pipeline Editor | Commit section', () => {
expect(wrapper.emitted('commit')[0]).toEqual([{ type: COMMIT_SUCCESS }]);
});
+ it('emits an event to refetch the commit sha', () => {
+ expect(wrapper.emitted('updateCommitSha')).toHaveLength(1);
+ });
+
it('shows no saving state', () => {
expect(findCommitBtnLoadingIcon().exists()).toBe(false);
});
@@ -188,7 +194,6 @@ describe('Pipeline Editor | Commit section', () => {
update: expect.any(Function),
variables: {
...mockVariables,
- lastCommitId: mockCommitNextSha,
branch: mockDefaultBranch,
},
});
@@ -215,6 +220,10 @@ describe('Pipeline Editor | Commit section', () => {
},
});
});
+
+ it('does not emit an event to refetch the commit sha', () => {
+ expect(wrapper.emitted('updateCommitSha')).toBeUndefined();
+ });
});
describe('when the user commits changes to open a new merge request', () => {
diff --git a/spec/frontend/pipeline_editor/components/editor/text_editor_spec.js b/spec/frontend/pipeline_editor/components/editor/text_editor_spec.js
index c6c7f593cc5..85222f2ecbb 100644
--- a/spec/frontend/pipeline_editor/components/editor/text_editor_spec.js
+++ b/spec/frontend/pipeline_editor/components/editor/text_editor_spec.js
@@ -42,15 +42,12 @@ describe('Pipeline Editor | Text editor component', () => {
defaultBranch: mockDefaultBranch,
glFeatures,
},
+ propsData: {
+ commitSha: mockCommitSha,
+ },
attrs: {
value: mockCiYml,
},
- // Simulate graphQL client query result
- data() {
- return {
- commitSha: mockCommitSha,
- };
- },
listeners: {
[EDITOR_READY_EVENT]: editorReadyListener,
},
diff --git a/spec/frontend/pipeline_editor/components/file-nav/branch_switcher_spec.js b/spec/frontend/pipeline_editor/components/file-nav/branch_switcher_spec.js
index 85b51d08f88..b5881790b0b 100644
--- a/spec/frontend/pipeline_editor/components/file-nav/branch_switcher_spec.js
+++ b/spec/frontend/pipeline_editor/components/file-nav/branch_switcher_spec.js
@@ -247,15 +247,6 @@ describe('Pipeline editor branch switcher', () => {
expect(wrapper.emitted('refetchContent')).toBeUndefined();
});
-
- it('emits the updateCommitSha event when selecting a different branch', async () => {
- expect(wrapper.emitted('updateCommitSha')).toBeUndefined();
-
- const branch = findDropdownItems().at(1);
- branch.vm.$emit('click');
-
- expect(wrapper.emitted('updateCommitSha')).toHaveLength(1);
- });
});
describe('when searching', () => {
diff --git a/spec/frontend/pipeline_editor/components/file-nav/pipeline_editor_file_nav_spec.js b/spec/frontend/pipeline_editor/components/file-nav/pipeline_editor_file_nav_spec.js
index 94a0a7d14ee..e24de832d6d 100644
--- a/spec/frontend/pipeline_editor/components/file-nav/pipeline_editor_file_nav_spec.js
+++ b/spec/frontend/pipeline_editor/components/file-nav/pipeline_editor_file_nav_spec.js
@@ -4,16 +4,10 @@ import PipelineEditorFileNav from '~/pipeline_editor/components/file_nav/pipelin
describe('Pipeline editor file nav', () => {
let wrapper;
- const mockProvide = {
- glFeatures: {
- pipelineEditorBranchSwitcher: true,
- },
- };
const createComponent = ({ provide = {} } = {}) => {
wrapper = shallowMount(PipelineEditorFileNav, {
provide: {
- ...mockProvide,
...provide,
},
});
@@ -34,16 +28,4 @@ describe('Pipeline editor file nav', () => {
expect(findBranchSwitcher().exists()).toBe(true);
});
});
-
- describe('with branch switcher feature flag OFF', () => {
- it('does not render the branch switcher', () => {
- createComponent({
- provide: {
- glFeatures: { pipelineEditorBranchSwitcher: false },
- },
- });
-
- expect(findBranchSwitcher().exists()).toBe(false);
- });
- });
});
diff --git a/spec/frontend/pipeline_editor/components/header/pipeline_status_spec.js b/spec/frontend/pipeline_editor/components/header/pipeline_status_spec.js
index a95921359cc..753682d438b 100644
--- a/spec/frontend/pipeline_editor/components/header/pipeline_status_spec.js
+++ b/spec/frontend/pipeline_editor/components/header/pipeline_status_spec.js
@@ -27,13 +27,11 @@ describe('Pipeline Status', () => {
wrapper = shallowMount(PipelineStatus, {
localVue,
apolloProvider: mockApollo,
+ propsData: {
+ commitSha: mockCommitSha,
+ },
provide: mockProvide,
stubs: { GlLink, GlSprintf },
- data() {
- return {
- commitSha: mockCommitSha,
- };
- },
});
};
diff --git a/spec/frontend/pipeline_editor/components/ui/pipeline_editor_empty_state_spec.js b/spec/frontend/pipeline_editor/components/ui/pipeline_editor_empty_state_spec.js
index 76c68e21180..b019bae886c 100644
--- a/spec/frontend/pipeline_editor/components/ui/pipeline_editor_empty_state_spec.js
+++ b/spec/frontend/pipeline_editor/components/ui/pipeline_editor_empty_state_spec.js
@@ -7,7 +7,6 @@ describe('Pipeline editor empty state', () => {
let wrapper;
const defaultProvide = {
glFeatures: {
- pipelineEditorBranchSwitcher: true,
pipelineEditorEmptyStateAction: false,
},
emptyStateIllustrationPath: 'my/svg/path',
@@ -82,17 +81,5 @@ describe('Pipeline editor empty state', () => {
await findConfirmButton().vm.$emit('click');
expect(wrapper.emitted(expectedEvent)).toHaveLength(1);
});
-
- describe('with branch switcher feature flag OFF', () => {
- it('does not render the file nav', () => {
- createComponent({
- provide: {
- glFeatures: { pipelineEditorBranchSwitcher: false },
- },
- });
-
- expect(findFileNav().exists()).toBe(false);
- });
- });
});
});
diff --git a/spec/frontend/pipeline_editor/mock_data.js b/spec/frontend/pipeline_editor/mock_data.js
index 4d4a8c21d78..f2104f25324 100644
--- a/spec/frontend/pipeline_editor/mock_data.js
+++ b/spec/frontend/pipeline_editor/mock_data.js
@@ -156,30 +156,43 @@ export const mergeUnwrappedCiConfig = (mergedConfig) => {
};
};
-export const mockNewCommitShaResults = {
+export const mockCommitShaResults = {
data: {
project: {
- pipelines: {
- nodes: [
- {
- id: 'gid://gitlab/Ci::Pipeline/1',
- sha: 'd0d56d363d8a3f67a8ab9fc00207d468f30032ca',
- path: `/${mockProjectFullPath}/-/pipelines/488`,
- commitPath: `/${mockProjectFullPath}/-/commit/d0d56d363d8a3f67a8ab9fc00207d468f30032ca`,
+ repository: {
+ tree: {
+ lastCommit: {
+ sha: mockCommitSha,
},
- {
- id: 'gid://gitlab/Ci::Pipeline/2',
- sha: 'fcab2ece40b26f428dfa3aa288b12c3c5bdb06aa',
- path: `/${mockProjectFullPath}/-/pipelines/487`,
- commitPath: `/${mockProjectFullPath}/-/commit/fcab2ece40b26f428dfa3aa288b12c3c5bdb06aa`,
+ },
+ },
+ },
+ },
+};
+
+export const mockNewCommitShaResults = {
+ data: {
+ project: {
+ repository: {
+ tree: {
+ lastCommit: {
+ sha: 'eeff1122',
},
- {
- id: 'gid://gitlab/Ci::Pipeline/3',
- sha: '6c16b17c7f94a438ae19a96c285bb49e3c632cf4',
- path: `/${mockProjectFullPath}/-/pipelines/433`,
- commitPath: `/${mockProjectFullPath}/-/commit/6c16b17c7f94a438ae19a96c285bb49e3c632cf4`,
+ },
+ },
+ },
+ },
+};
+
+export const mockEmptyCommitShaResults = {
+ data: {
+ project: {
+ repository: {
+ tree: {
+ lastCommit: {
+ sha: '',
},
- ],
+ },
},
},
},
diff --git a/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js b/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js
index 0c5c08d7190..393cad0546b 100644
--- a/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js
+++ b/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js
@@ -26,9 +26,11 @@ import {
mockBlobContentQueryResponseNoCiFile,
mockCiYml,
mockCommitSha,
+ mockCommitShaResults,
mockDefaultBranch,
- mockProjectFullPath,
+ mockEmptyCommitShaResults,
mockNewCommitShaResults,
+ mockProjectFullPath,
} from './mock_data';
const localVue = createLocalVue();
@@ -54,7 +56,6 @@ describe('Pipeline editor app component', () => {
let mockBlobContentData;
let mockCiConfigData;
let mockGetTemplate;
- let mockUpdateCommitSha;
let mockLatestCommitShaQuery;
let mockPipelineQuery;
@@ -71,6 +72,11 @@ describe('Pipeline editor app component', () => {
SourceEditor: MockSourceEditor,
PipelineEditorEmptyState,
},
+ data() {
+ return {
+ commitSha: '',
+ };
+ },
mocks: {
$apollo: {
queries: {
@@ -96,18 +102,7 @@ describe('Pipeline editor app component', () => {
[getPipelineQuery, mockPipelineQuery],
];
- const resolvers = {
- Query: {
- commitSha() {
- return mockCommitSha;
- },
- },
- Mutation: {
- updateCommitSha: mockUpdateCommitSha,
- },
- };
-
- mockApollo = createMockApollo(handlers, resolvers);
+ mockApollo = createMockApollo(handlers);
const options = {
localVue,
@@ -137,7 +132,6 @@ describe('Pipeline editor app component', () => {
mockBlobContentData = jest.fn();
mockCiConfigData = jest.fn();
mockGetTemplate = jest.fn();
- mockUpdateCommitSha = jest.fn();
mockLatestCommitShaQuery = jest.fn();
mockPipelineQuery = jest.fn();
});
@@ -159,11 +153,16 @@ describe('Pipeline editor app component', () => {
beforeEach(() => {
mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponse);
mockCiConfigData.mockResolvedValue(mockCiConfigQueryResponse);
+ mockLatestCommitShaQuery.mockResolvedValue(mockCommitShaResults);
});
describe('when file exists', () => {
beforeEach(async () => {
await createComponentWithApollo();
+
+ jest
+ .spyOn(wrapper.vm.$apollo.queries.commitSha, 'startPolling')
+ .mockImplementation(jest.fn());
});
it('shows pipeline editor home component', () => {
@@ -181,18 +180,32 @@ describe('Pipeline editor app component', () => {
sha: mockCommitSha,
});
});
+
+ it('does not poll for the commit sha', () => {
+ expect(wrapper.vm.$apollo.queries.commitSha.startPolling).toHaveBeenCalledTimes(0);
+ });
});
describe('when no CI config file exists', () => {
- it('shows an empty state and does not show editor home component', async () => {
+ beforeEach(async () => {
mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponseNoCiFile);
await createComponentWithApollo();
+ jest
+ .spyOn(wrapper.vm.$apollo.queries.commitSha, 'startPolling')
+ .mockImplementation(jest.fn());
+ });
+
+ it('shows an empty state and does not show editor home component', async () => {
expect(findEmptyState().exists()).toBe(true);
expect(findAlert().exists()).toBe(false);
expect(findEditorHome().exists()).toBe(false);
});
+ it('does not poll for the commit sha', () => {
+ expect(wrapper.vm.$apollo.queries.commitSha.startPolling).toHaveBeenCalledTimes(0);
+ });
+
describe('because of a fetching error', () => {
it('shows a unkown error message', async () => {
const loadUnknownFailureText = 'The CI configuration was not loaded, please try again.';
@@ -230,6 +243,7 @@ describe('Pipeline editor app component', () => {
describe('when landing on the empty state with feature flag on', () => {
it('user can click on CTA button and see an empty editor', async () => {
mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponseNoCiFile);
+ mockLatestCommitShaQuery.mockResolvedValue(mockEmptyCommitShaResults);
await createComponentWithApollo({
provide: {
@@ -254,9 +268,9 @@ describe('Pipeline editor app component', () => {
const updateSuccessMessage = 'Your changes have been successfully committed.';
describe('and the commit mutation succeeds', () => {
- beforeEach(() => {
+ beforeEach(async () => {
window.scrollTo = jest.fn();
- createComponent();
+ await createComponentWithApollo();
findEditorHome().vm.$emit('commit', { type: COMMIT_SUCCESS });
});
@@ -268,7 +282,43 @@ describe('Pipeline editor app component', () => {
it('scrolls to the top of the page to bring attention to the confirmation message', () => {
expect(window.scrollTo).toHaveBeenCalledWith({ top: 0, behavior: 'smooth' });
});
+
+ it('polls for commit sha while pipeline data is not yet available for current branch', async () => {
+ jest
+ .spyOn(wrapper.vm.$apollo.queries.commitSha, 'startPolling')
+ .mockImplementation(jest.fn());
+
+ // simulate a commit to the current branch
+ findEditorHome().vm.$emit('updateCommitSha');
+ await waitForPromises();
+
+ expect(wrapper.vm.$apollo.queries.commitSha.startPolling).toHaveBeenCalledTimes(1);
+ });
+
+ it('stops polling for commit sha when pipeline data is available for newly committed branch', async () => {
+ jest
+ .spyOn(wrapper.vm.$apollo.queries.commitSha, 'stopPolling')
+ .mockImplementation(jest.fn());
+
+ mockLatestCommitShaQuery.mockResolvedValue(mockCommitShaResults);
+ await wrapper.vm.$apollo.queries.commitSha.refetch();
+
+ expect(wrapper.vm.$apollo.queries.commitSha.stopPolling).toHaveBeenCalledTimes(1);
+ });
+
+ it('stops polling for commit sha when pipeline data is available for current branch', async () => {
+ jest
+ .spyOn(wrapper.vm.$apollo.queries.commitSha, 'stopPolling')
+ .mockImplementation(jest.fn());
+
+ mockLatestCommitShaQuery.mockResolvedValue(mockNewCommitShaResults);
+ findEditorHome().vm.$emit('updateCommitSha');
+ await waitForPromises();
+
+ expect(wrapper.vm.$apollo.queries.commitSha.stopPolling).toHaveBeenCalledTimes(1);
+ });
});
+
describe('and the commit mutation fails', () => {
const commitFailedReasons = ['Commit failed'];
@@ -320,6 +370,10 @@ describe('Pipeline editor app component', () => {
});
describe('when refetching content', () => {
+ beforeEach(() => {
+ mockLatestCommitShaQuery.mockResolvedValue(mockCommitShaResults);
+ });
+
it('refetches blob content', async () => {
await createComponentWithApollo();
jest
@@ -352,6 +406,7 @@ describe('Pipeline editor app component', () => {
const originalLocation = window.location.href;
beforeEach(() => {
+ mockLatestCommitShaQuery.mockResolvedValue(mockCommitShaResults);
setWindowLocation('?template=Android');
});
@@ -371,45 +426,4 @@ describe('Pipeline editor app component', () => {
expect(findTextEditor().exists()).toBe(true);
});
});
-
- describe('when updating commit sha', () => {
- const newCommitSha = mockNewCommitShaResults.data.project.pipelines.nodes[0].sha;
-
- beforeEach(async () => {
- mockUpdateCommitSha.mockResolvedValue(newCommitSha);
- mockLatestCommitShaQuery.mockResolvedValue(mockNewCommitShaResults);
- await createComponentWithApollo();
- });
-
- it('fetches updated commit sha for the new branch', async () => {
- expect(mockLatestCommitShaQuery).not.toHaveBeenCalled();
-
- wrapper
- .findComponent(PipelineEditorHome)
- .vm.$emit('updateCommitSha', { newBranch: 'new-branch' });
- await waitForPromises();
-
- expect(mockLatestCommitShaQuery).toHaveBeenCalledWith({
- projectPath: mockProjectFullPath,
- ref: 'new-branch',
- });
- });
-
- it('updates commit sha with the newly fetched commit sha', async () => {
- expect(mockUpdateCommitSha).not.toHaveBeenCalled();
-
- wrapper
- .findComponent(PipelineEditorHome)
- .vm.$emit('updateCommitSha', { newBranch: 'new-branch' });
- await waitForPromises();
-
- expect(mockUpdateCommitSha).toHaveBeenCalled();
- expect(mockUpdateCommitSha).toHaveBeenCalledWith(
- expect.any(Object),
- { commitSha: mockNewCommitShaResults.data.project.pipelines.nodes[0].sha },
- expect.any(Object),
- expect.any(Object),
- );
- });
- });
});
diff --git a/spec/frontend/pipeline_new/components/pipeline_new_form_spec.js b/spec/frontend/pipeline_new/components/pipeline_new_form_spec.js
index 2a3f4f56f36..9e2bf1bd367 100644
--- a/spec/frontend/pipeline_new/components/pipeline_new_form_spec.js
+++ b/spec/frontend/pipeline_new/components/pipeline_new_form_spec.js
@@ -45,6 +45,7 @@ describe('Pipeline New Form', () => {
const findWarningAlertSummary = () => findWarningAlert().find(GlSprintf);
const findWarnings = () => wrapper.findAll('[data-testid="run-pipeline-warning"]');
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
+ const findCCAlert = () => wrapper.findComponent(CreditCardValidationRequiredAlert);
const getFormPostParams = () => JSON.parse(mock.history.post[0].data);
const selectBranch = (branch) => {
@@ -387,7 +388,7 @@ describe('Pipeline New Form', () => {
});
it('does not show the credit card validation required alert', () => {
- expect(wrapper.findComponent(CreditCardValidationRequiredAlert).exists()).toBe(false);
+ expect(findCCAlert().exists()).toBe(false);
});
describe('when the error response is credit card validation required', () => {
@@ -408,7 +409,19 @@ describe('Pipeline New Form', () => {
it('shows credit card validation required alert', () => {
expect(findErrorAlert().exists()).toBe(false);
- expect(wrapper.findComponent(CreditCardValidationRequiredAlert).exists()).toBe(true);
+ expect(findCCAlert().exists()).toBe(true);
+ });
+
+ it('clears error and hides the alert on dismiss', async () => {
+ expect(findCCAlert().exists()).toBe(true);
+ expect(wrapper.vm.$data.error).toBe(mockCreditCardValidationRequiredError.errors[0]);
+
+ findCCAlert().vm.$emit('dismiss');
+
+ await wrapper.vm.$nextTick();
+
+ expect(findCCAlert().exists()).toBe(false);
+ expect(wrapper.vm.$data.error).toBe(null);
});
});
});
diff --git a/spec/frontend/pipelines/__snapshots__/parsing_utils_spec.js.snap b/spec/frontend/pipelines/__snapshots__/utils_spec.js.snap
index 60625d301c0..60625d301c0 100644
--- a/spec/frontend/pipelines/__snapshots__/parsing_utils_spec.js.snap
+++ b/spec/frontend/pipelines/__snapshots__/utils_spec.js.snap
diff --git a/spec/frontend/pipelines/components/pipelines_filtered_search_spec.js b/spec/frontend/pipelines/components/pipelines_filtered_search_spec.js
index e0ba6b2e8da..661c8d99477 100644
--- a/spec/frontend/pipelines/components/pipelines_filtered_search_spec.js
+++ b/spec/frontend/pipelines/components/pipelines_filtered_search_spec.js
@@ -33,8 +33,6 @@ describe('Pipelines filtered search', () => {
};
beforeEach(() => {
- window.gon = { features: { pipelineSourceFilter: true } };
-
mock = new MockAdapter(axios);
jest.spyOn(Api, 'projectUsers').mockResolvedValue(users);
diff --git a/spec/frontend/pipelines/graph/graph_component_spec.js b/spec/frontend/pipelines/graph/graph_component_spec.js
index 1fba3823161..4b2b61c8edd 100644
--- a/spec/frontend/pipelines/graph/graph_component_spec.js
+++ b/spec/frontend/pipelines/graph/graph_component_spec.js
@@ -1,5 +1,5 @@
import { mount, shallowMount } from '@vue/test-utils';
-import { GRAPHQL, LAYER_VIEW, STAGE_VIEW } from '~/pipelines/components/graph/constants';
+import { LAYER_VIEW, STAGE_VIEW } from '~/pipelines/components/graph/constants';
import PipelineGraph from '~/pipelines/components/graph/graph_component.vue';
import JobItem from '~/pipelines/components/graph/job_item.vue';
import LinkedPipelinesColumn from '~/pipelines/components/graph/linked_pipelines_column.vue';
@@ -54,9 +54,6 @@ describe('graph component', () => {
...data,
};
},
- provide: {
- dataMethod: GRAPHQL,
- },
stubs: {
'links-inner': true,
'linked-pipeline': true,
diff --git a/spec/frontend/pipelines/graph/job_item_spec.js b/spec/frontend/pipelines/graph/job_item_spec.js
index 4c7ea5edda9..cbc5d11403e 100644
--- a/spec/frontend/pipelines/graph/job_item_spec.js
+++ b/spec/frontend/pipelines/graph/job_item_spec.js
@@ -14,7 +14,29 @@ describe('pipeline graph job item', () => {
};
const triggerActiveClass = 'gl-shadow-x0-y0-b3-s1-blue-500';
- const delayedJobFixture = getJSONFixture('jobs/delayed.json');
+
+ const delayedJob = {
+ __typename: 'CiJob',
+ name: 'delayed job',
+ scheduledAt: '2015-07-03T10:01:00.000Z',
+ needs: [],
+ status: {
+ __typename: 'DetailedStatus',
+ icon: 'status_scheduled',
+ tooltip: 'delayed manual action (%{remainingTime})',
+ hasDetails: true,
+ detailsPath: '/root/kinder-pipe/-/jobs/5339',
+ group: 'scheduled',
+ action: {
+ __typename: 'StatusAction',
+ icon: 'time-out',
+ title: 'Unschedule',
+ path: '/frontend-fixtures/builds-project/-/jobs/142/unschedule',
+ buttonTitle: 'Unschedule job',
+ },
+ },
+ };
+
const mockJob = {
id: 4256,
name: 'test',
@@ -24,8 +46,8 @@ describe('pipeline graph job item', () => {
label: 'passed',
tooltip: 'passed',
group: 'success',
- details_path: '/root/ci-mock/builds/4256',
- has_details: true,
+ detailsPath: '/root/ci-mock/builds/4256',
+ hasDetails: true,
action: {
icon: 'retry',
title: 'Retry',
@@ -42,8 +64,8 @@ describe('pipeline graph job item', () => {
text: 'passed',
label: 'passed',
group: 'success',
- details_path: '/root/ci-mock/builds/4257',
- has_details: false,
+ detailsPath: '/root/ci-mock/builds/4257',
+ hasDetails: false,
},
};
@@ -58,7 +80,7 @@ describe('pipeline graph job item', () => {
wrapper.vm.$nextTick(() => {
const link = wrapper.find('a');
- expect(link.attributes('href')).toBe(mockJob.status.details_path);
+ expect(link.attributes('href')).toBe(mockJob.status.detailsPath);
expect(link.attributes('title')).toBe(`${mockJob.name} - ${mockJob.status.label}`);
@@ -145,7 +167,7 @@ describe('pipeline graph job item', () => {
describe('for delayed job', () => {
it('displays remaining time in tooltip', () => {
createWrapper({
- job: delayedJobFixture,
+ job: delayedJob,
});
expect(findJobWithLink().attributes('title')).toBe(
diff --git a/spec/frontend/pipelines/graph/linked_pipeline_spec.js b/spec/frontend/pipelines/graph/linked_pipeline_spec.js
index c7d95526a0c..af5cd907dd8 100644
--- a/spec/frontend/pipelines/graph/linked_pipeline_spec.js
+++ b/spec/frontend/pipelines/graph/linked_pipeline_spec.js
@@ -4,11 +4,7 @@ import { BV_HIDE_TOOLTIP } from '~/lib/utils/constants';
import { UPSTREAM, DOWNSTREAM } from '~/pipelines/components/graph/constants';
import LinkedPipelineComponent from '~/pipelines/components/graph/linked_pipeline.vue';
import CiStatus from '~/vue_shared/components/ci_icon.vue';
-import mockData from './linked_pipelines_mock_data';
-
-const mockPipeline = mockData.triggered[0];
-const validTriggeredPipelineId = mockPipeline.project.id;
-const invalidTriggeredPipelineId = mockPipeline.project.id + 5;
+import mockPipeline from './linked_pipelines_mock_data';
describe('Linked pipeline', () => {
let wrapper;
@@ -39,10 +35,10 @@ describe('Linked pipeline', () => {
describe('rendered output', () => {
const props = {
pipeline: mockPipeline,
- projectId: invalidTriggeredPipelineId,
columnTitle: 'Downstream',
type: DOWNSTREAM,
expanded: false,
+ isLoading: false,
};
beforeEach(() => {
@@ -60,7 +56,7 @@ describe('Linked pipeline', () => {
});
it('should render the pipeline status icon svg', () => {
- expect(wrapper.find('.ci-status-icon-failed svg').exists()).toBe(true);
+ expect(wrapper.find('.ci-status-icon-success svg').exists()).toBe(true);
});
it('should have a ci-status child component', () => {
@@ -73,8 +69,8 @@ describe('Linked pipeline', () => {
it('should correctly compute the tooltip text', () => {
expect(wrapper.vm.tooltipText).toContain(mockPipeline.project.name);
- expect(wrapper.vm.tooltipText).toContain(mockPipeline.details.status.label);
- expect(wrapper.vm.tooltipText).toContain(mockPipeline.source_job.name);
+ expect(wrapper.vm.tooltipText).toContain(mockPipeline.status.label);
+ expect(wrapper.vm.tooltipText).toContain(mockPipeline.sourceJob.name);
expect(wrapper.vm.tooltipText).toContain(mockPipeline.id);
});
@@ -82,11 +78,7 @@ describe('Linked pipeline', () => {
const titleAttr = findLinkedPipeline().attributes('title');
expect(titleAttr).toContain(mockPipeline.project.name);
- expect(titleAttr).toContain(mockPipeline.details.status.label);
- });
-
- it('sets the loading prop to false', () => {
- expect(findButton().props('loading')).toBe(false);
+ expect(titleAttr).toContain(mockPipeline.status.label);
});
it('should display multi-project label when pipeline project id is not the same as triggered pipeline project id', () => {
@@ -96,18 +88,20 @@ describe('Linked pipeline', () => {
describe('parent/child', () => {
const downstreamProps = {
- pipeline: mockPipeline,
- projectId: validTriggeredPipelineId,
+ pipeline: {
+ ...mockPipeline,
+ multiproject: false,
+ },
columnTitle: 'Downstream',
type: DOWNSTREAM,
expanded: false,
+ isLoading: false,
};
const upstreamProps = {
...downstreamProps,
columnTitle: 'Upstream',
type: UPSTREAM,
- expanded: false,
};
it('parent/child label container should exist', () => {
@@ -122,7 +116,7 @@ describe('Linked pipeline', () => {
it('should have the name of the trigger job on the card when it is a child pipeline', () => {
createWrapper(downstreamProps);
- expect(findDownstreamPipelineTitle().text()).toBe(mockPipeline.source_job.name);
+ expect(findDownstreamPipelineTitle().text()).toBe(mockPipeline.sourceJob.name);
});
it('should display parent label when pipeline project id is the same as triggered_by pipeline project id', () => {
@@ -132,12 +126,12 @@ describe('Linked pipeline', () => {
it('downstream pipeline should contain the correct link', () => {
createWrapper(downstreamProps);
- expect(findPipelineLink().attributes('href')).toBe(mockData.triggered_by.path);
+ expect(findPipelineLink().attributes('href')).toBe(downstreamProps.pipeline.path);
});
it('upstream pipeline should contain the correct link', () => {
createWrapper(upstreamProps);
- expect(findPipelineLink().attributes('href')).toBe(mockData.triggered_by.path);
+ expect(findPipelineLink().attributes('href')).toBe(upstreamProps.pipeline.path);
});
it.each`
@@ -183,11 +177,11 @@ describe('Linked pipeline', () => {
describe('when isLoading is true', () => {
const props = {
- pipeline: { ...mockPipeline, isLoading: true },
- projectId: invalidTriggeredPipelineId,
+ pipeline: mockPipeline,
columnTitle: 'Downstream',
type: DOWNSTREAM,
expanded: false,
+ isLoading: true,
};
beforeEach(() => {
@@ -202,10 +196,10 @@ describe('Linked pipeline', () => {
describe('on click/hover', () => {
const props = {
pipeline: mockPipeline,
- projectId: validTriggeredPipelineId,
columnTitle: 'Downstream',
type: DOWNSTREAM,
expanded: false,
+ isLoading: false,
};
beforeEach(() => {
@@ -228,7 +222,7 @@ describe('Linked pipeline', () => {
it('should emit downstreamHovered with job name on mouseover', () => {
findLinkedPipeline().trigger('mouseover');
- expect(wrapper.emitted().downstreamHovered).toStrictEqual([['trigger_job']]);
+ expect(wrapper.emitted().downstreamHovered).toStrictEqual([['test_c']]);
});
it('should emit downstreamHovered with empty string on mouseleave', () => {
@@ -238,7 +232,7 @@ describe('Linked pipeline', () => {
it('should emit pipelineExpanded with job name and expanded state on click', () => {
findExpandButton().trigger('click');
- expect(wrapper.emitted().pipelineExpandToggle).toStrictEqual([['trigger_job', true]]);
+ expect(wrapper.emitted().pipelineExpandToggle).toStrictEqual([['test_c', true]]);
});
});
});
diff --git a/spec/frontend/pipelines/graph/linked_pipelines_column_spec.js b/spec/frontend/pipelines/graph/linked_pipelines_column_spec.js
index 24cc6e76098..2f03b846525 100644
--- a/spec/frontend/pipelines/graph/linked_pipelines_column_spec.js
+++ b/spec/frontend/pipelines/graph/linked_pipelines_column_spec.js
@@ -4,7 +4,6 @@ import createMockApollo from 'helpers/mock_apollo_helper';
import getPipelineDetails from 'shared_queries/pipelines/get_pipeline_details.query.graphql';
import {
DOWNSTREAM,
- GRAPHQL,
UPSTREAM,
LAYER_VIEW,
STAGE_VIEW,
@@ -52,9 +51,6 @@ describe('Linked Pipelines Column', () => {
...defaultProps,
...props,
},
- provide: {
- dataMethod: GRAPHQL,
- },
});
};
diff --git a/spec/frontend/pipelines/graph/linked_pipelines_mock_data.js b/spec/frontend/pipelines/graph/linked_pipelines_mock_data.js
index eb05669463b..955b70cbd3b 100644
--- a/spec/frontend/pipelines/graph/linked_pipelines_mock_data.js
+++ b/spec/frontend/pipelines/graph/linked_pipelines_mock_data.js
@@ -1,3800 +1,22 @@
export default {
- id: 23211253,
- user: {
- id: 3585,
- name: 'Achilleas Pipinellis',
- username: 'axil',
- state: 'active',
- avatar_url: 'https://assets.gitlab-static.net/uploads/-/system/user/avatar/3585/avatar.png',
- web_url: 'https://gitlab.com/axil',
- status_tooltip_html:
- '\u003cspan class="user-status-emoji has-tooltip" title="I like pizza" data-html="true" data-placement="top"\u003e\u003cgl-emoji title="slice of pizza" data-name="pizza" data-unicode-version="6.0"\u003eðŸ•\u003c/gl-emoji\u003e\u003c/span\u003e',
- path: '/axil',
+ __typename: 'Pipeline',
+ id: 195,
+ iid: '5',
+ path: '/root/elemenohpee/-/pipelines/195',
+ status: {
+ __typename: 'DetailedStatus',
+ group: 'success',
+ label: 'passed',
+ icon: 'status_success',
},
- active: false,
- coverage: null,
- source: 'push',
- source_job: {
- name: 'trigger_job',
+ sourceJob: {
+ __typename: 'CiJob',
+ name: 'test_c',
},
- created_at: '2018-06-05T11:31:30.452Z',
- updated_at: '2018-10-31T16:35:31.305Z',
- path: '/gitlab-org/gitlab-runner/pipelines/23211253',
- flags: {
- latest: false,
- stuck: false,
- auto_devops: false,
- merge_request: false,
- yaml_errors: false,
- retryable: false,
- cancelable: false,
- failure_reason: false,
+ project: {
+ __typename: 'Project',
+ name: 'elemenohpee',
+ fullPath: 'root/elemenohpee',
},
- details: {
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/gitlab-org/gitlab-runner/pipelines/23211253',
- illustration: null,
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- },
- duration: 53,
- finished_at: '2018-10-31T16:35:31.299Z',
- stages: [
- {
- name: 'prebuild',
- title: 'prebuild: passed',
- groups: [
- {
- name: 'review-docs-deploy',
- size: 1,
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'manual play action',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/gitlab-org/gitlab-runner/-/jobs/72469032',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-org/gitlab-runner/-/jobs/72469032/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- jobs: [
- {
- id: 72469032,
- name: 'review-docs-deploy',
- started: '2018-10-31T16:34:58.778Z',
- archived: false,
- build_path: '/gitlab-org/gitlab-runner/-/jobs/72469032',
- retry_path: '/gitlab-org/gitlab-runner/-/jobs/72469032/retry',
- play_path: '/gitlab-org/gitlab-runner/-/jobs/72469032/play',
- playable: true,
- scheduled: false,
- created_at: '2018-06-05T11:31:30.495Z',
- updated_at: '2018-10-31T16:35:31.251Z',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'manual play action',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/gitlab-org/gitlab-runner/-/jobs/72469032',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-org/gitlab-runner/-/jobs/72469032/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- },
- ],
- },
- ],
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/gitlab-org/gitlab-runner/pipelines/23211253#prebuild',
- illustration: null,
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- },
- path: '/gitlab-org/gitlab-runner/pipelines/23211253#prebuild',
- dropdown_path: '/gitlab-org/gitlab-runner/pipelines/23211253/stage.json?stage=prebuild',
- },
- {
- name: 'test',
- title: 'test: passed',
- groups: [
- {
- name: 'docs check links',
- size: 1,
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/gitlab-org/gitlab-runner/-/jobs/72469033',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/gitlab-org/gitlab-runner/-/jobs/72469033/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- jobs: [
- {
- id: 72469033,
- name: 'docs check links',
- started: '2018-06-05T11:31:33.240Z',
- archived: false,
- build_path: '/gitlab-org/gitlab-runner/-/jobs/72469033',
- retry_path: '/gitlab-org/gitlab-runner/-/jobs/72469033/retry',
- playable: false,
- scheduled: false,
- created_at: '2018-06-05T11:31:30.627Z',
- updated_at: '2018-06-05T11:31:54.363Z',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/gitlab-org/gitlab-runner/-/jobs/72469033',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/gitlab-org/gitlab-runner/-/jobs/72469033/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- },
- ],
- },
- ],
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/gitlab-org/gitlab-runner/pipelines/23211253#test',
- illustration: null,
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- },
- path: '/gitlab-org/gitlab-runner/pipelines/23211253#test',
- dropdown_path: '/gitlab-org/gitlab-runner/pipelines/23211253/stage.json?stage=test',
- },
- {
- name: 'cleanup',
- title: 'cleanup: skipped',
- groups: [
- {
- name: 'review-docs-cleanup',
- size: 1,
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual stop action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-org/gitlab-runner/-/jobs/72469034',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'stop',
- title: 'Stop',
- path: '/gitlab-org/gitlab-runner/-/jobs/72469034/play',
- method: 'post',
- button_title: 'Stop this environment',
- },
- },
- jobs: [
- {
- id: 72469034,
- name: 'review-docs-cleanup',
- started: null,
- archived: false,
- build_path: '/gitlab-org/gitlab-runner/-/jobs/72469034',
- play_path: '/gitlab-org/gitlab-runner/-/jobs/72469034/play',
- playable: true,
- scheduled: false,
- created_at: '2018-06-05T11:31:30.760Z',
- updated_at: '2018-06-05T11:31:56.037Z',
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual stop action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-org/gitlab-runner/-/jobs/72469034',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'stop',
- title: 'Stop',
- path: '/gitlab-org/gitlab-runner/-/jobs/72469034/play',
- method: 'post',
- button_title: 'Stop this environment',
- },
- },
- },
- ],
- },
- ],
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-org/gitlab-runner/pipelines/23211253#cleanup',
- illustration: null,
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- path: '/gitlab-org/gitlab-runner/pipelines/23211253#cleanup',
- dropdown_path: '/gitlab-org/gitlab-runner/pipelines/23211253/stage.json?stage=cleanup',
- },
- ],
- artifacts: [],
- manual_actions: [
- {
- name: 'review-docs-cleanup',
- path: '/gitlab-org/gitlab-runner/-/jobs/72469034/play',
- playable: true,
- scheduled: false,
- },
- {
- name: 'review-docs-deploy',
- path: '/gitlab-org/gitlab-runner/-/jobs/72469032/play',
- playable: true,
- scheduled: false,
- },
- ],
- scheduled_actions: [],
- },
- ref: {
- name: 'docs/add-development-guide-to-readme',
- path: '/gitlab-org/gitlab-runner/commits/docs/add-development-guide-to-readme',
- tag: false,
- branch: true,
- merge_request: false,
- },
- commit: {
- id: '8083eb0a920572214d0dccedd7981f05d535ad46',
- short_id: '8083eb0a',
- title: 'Add link to development guide in readme',
- created_at: '2018-06-05T11:30:48.000Z',
- parent_ids: ['1d7cf79b5a1a2121b9474ac20d61c1b8f621289d'],
- message:
- 'Add link to development guide in readme\n\nCloses https://gitlab.com/gitlab-org/gitlab-runner/issues/3122\n',
- author_name: 'Achilleas Pipinellis',
- author_email: 'axil@gitlab.com',
- authored_date: '2018-06-05T11:30:48.000Z',
- committer_name: 'Achilleas Pipinellis',
- committer_email: 'axil@gitlab.com',
- committed_date: '2018-06-05T11:30:48.000Z',
- author: {
- id: 3585,
- name: 'Achilleas Pipinellis',
- username: 'axil',
- state: 'active',
- avatar_url: 'https://assets.gitlab-static.net/uploads/-/system/user/avatar/3585/avatar.png',
- web_url: 'https://gitlab.com/axil',
- status_tooltip_html: null,
- path: '/axil',
- },
- author_gravatar_url:
- 'https://secure.gravatar.com/avatar/1d37af00eec153a8333a4ce18e9aea41?s=80\u0026d=identicon',
- commit_url:
- 'https://gitlab.com/gitlab-org/gitlab-runner/commit/8083eb0a920572214d0dccedd7981f05d535ad46',
- commit_path: '/gitlab-org/gitlab-runner/commit/8083eb0a920572214d0dccedd7981f05d535ad46',
- },
- project: { id: 20 },
- triggered_by: {
- id: 12,
- user: {
- id: 376774,
- name: 'Alessio Caiazza',
- username: 'nolith',
- state: 'active',
- avatar_url: 'https://assets.gitlab-static.net/uploads/-/system/user/avatar/376774/avatar.png',
- web_url: 'https://gitlab.com/nolith',
- status_tooltip_html: null,
- path: '/nolith',
- },
- active: false,
- coverage: null,
- source: 'pipeline',
- source_job: {
- name: 'trigger_job',
- },
- path: '/gitlab-com/gitlab-docs/pipelines/34993051',
- details: {
- status: {
- icon: 'status_failed',
- text: 'failed',
- label: 'failed',
- group: 'failed',
- tooltip: 'failed',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/pipelines/34993051',
- illustration: null,
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_failed-41304d7f7e3828808b0c26771f0309e55296819a9beea3ea9fbf6689d9857c12.png',
- },
- duration: 118,
- finished_at: '2018-10-31T16:41:40.615Z',
- stages: [
- {
- name: 'build-images',
- title: 'build-images: skipped',
- groups: [
- {
- name: 'image:bootstrap',
- size: 1,
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982853',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982853/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- jobs: [
- {
- id: 11421321982853,
- name: 'image:bootstrap',
- started: null,
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114982853',
- play_path: '/gitlab-com/gitlab-docs/-/jobs/114982853/play',
- playable: true,
- scheduled: false,
- created_at: '2018-10-31T16:35:23.704Z',
- updated_at: '2018-10-31T16:35:24.118Z',
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982853',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982853/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- },
- ],
- },
- {
- name: 'image:builder-onbuild',
- size: 1,
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982854',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982854/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- jobs: [
- {
- id: 1149822131854,
- name: 'image:builder-onbuild',
- started: null,
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114982854',
- play_path: '/gitlab-com/gitlab-docs/-/jobs/114982854/play',
- playable: true,
- scheduled: false,
- created_at: '2018-10-31T16:35:23.728Z',
- updated_at: '2018-10-31T16:35:24.070Z',
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982854',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982854/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- },
- ],
- },
- {
- name: 'image:nginx-onbuild',
- size: 1,
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982855',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982855/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- jobs: [
- {
- id: 11498285523424,
- name: 'image:nginx-onbuild',
- started: null,
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114982855',
- play_path: '/gitlab-com/gitlab-docs/-/jobs/114982855/play',
- playable: true,
- scheduled: false,
- created_at: '2018-10-31T16:35:23.753Z',
- updated_at: '2018-10-31T16:35:24.033Z',
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982855',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982855/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- },
- ],
- },
- ],
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/pipelines/34993051#build-images',
- illustration: null,
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- path: '/gitlab-com/gitlab-docs/pipelines/34993051#build-images',
- dropdown_path: '/gitlab-com/gitlab-docs/pipelines/34993051/stage.json?stage=build-images',
- },
- {
- name: 'build',
- title: 'build: failed',
- groups: [
- {
- name: 'compile_dev',
- size: 1,
- status: {
- icon: 'status_failed',
- text: 'failed',
- label: 'failed',
- group: 'failed',
- tooltip: 'failed - (script failure)',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114984694',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_failed-41304d7f7e3828808b0c26771f0309e55296819a9beea3ea9fbf6689d9857c12.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/528/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- jobs: [
- {
- id: 1149846949786,
- name: 'compile_dev',
- started: '2018-10-31T16:39:41.598Z',
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114984694',
- retry_path: '/gitlab-com/gitlab-docs/-/jobs/114984694/retry',
- playable: false,
- scheduled: false,
- created_at: '2018-10-31T16:39:41.138Z',
- updated_at: '2018-10-31T16:41:40.072Z',
- status: {
- icon: 'status_failed',
- text: 'failed',
- label: 'failed',
- group: 'failed',
- tooltip: 'failed - (script failure)',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114984694',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_failed-41304d7f7e3828808b0c26771f0309e55296819a9beea3ea9fbf6689d9857c12.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/528/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- recoverable: false,
- },
- ],
- },
- ],
- status: {
- icon: 'status_failed',
- text: 'failed',
- label: 'failed',
- group: 'failed',
- tooltip: 'failed',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/pipelines/34993051#build',
- illustration: null,
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_failed-41304d7f7e3828808b0c26771f0309e55296819a9beea3ea9fbf6689d9857c12.png',
- },
- path: '/gitlab-com/gitlab-docs/pipelines/34993051#build',
- dropdown_path: '/gitlab-com/gitlab-docs/pipelines/34993051/stage.json?stage=build',
- },
- {
- name: 'deploy',
- title: 'deploy: skipped',
- groups: [
- {
- name: 'review',
- size: 1,
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982857',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job has been skipped',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- jobs: [
- {
- id: 11498282342357,
- name: 'review',
- started: null,
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114982857',
- playable: false,
- scheduled: false,
- created_at: '2018-10-31T16:35:23.805Z',
- updated_at: '2018-10-31T16:41:40.569Z',
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982857',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job has been skipped',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- },
- ],
- },
- {
- name: 'review_stop',
- size: 1,
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982858',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job has been skipped',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- jobs: [
- {
- id: 114982858,
- name: 'review_stop',
- started: null,
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114982858',
- playable: false,
- scheduled: false,
- created_at: '2018-10-31T16:35:23.840Z',
- updated_at: '2018-10-31T16:41:40.480Z',
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982858',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job has been skipped',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- },
- ],
- },
- ],
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/pipelines/34993051#deploy',
- illustration: null,
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- path: '/gitlab-com/gitlab-docs/pipelines/34993051#deploy',
- dropdown_path: '/gitlab-com/gitlab-docs/pipelines/34993051/stage.json?stage=deploy',
- },
- ],
- artifacts: [],
- manual_actions: [
- {
- name: 'image:bootstrap',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982853/play',
- playable: true,
- scheduled: false,
- },
- {
- name: 'image:builder-onbuild',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982854/play',
- playable: true,
- scheduled: false,
- },
- {
- name: 'image:nginx-onbuild',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982855/play',
- playable: true,
- scheduled: false,
- },
- {
- name: 'review_stop',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982858/play',
- playable: false,
- scheduled: false,
- },
- ],
- scheduled_actions: [],
- },
- project: {
- id: 20,
- name: 'Test',
- full_path: '/gitlab-com/gitlab-docs',
- full_name: 'GitLab.com / GitLab Docs',
- },
- triggered_by: {
- id: 349932310342451,
- user: {
- id: 376774,
- name: 'Alessio Caiazza',
- username: 'nolith',
- state: 'active',
- avatar_url:
- 'https://assets.gitlab-static.net/uploads/-/system/user/avatar/376774/avatar.png',
- web_url: 'https://gitlab.com/nolith',
- status_tooltip_html: null,
- path: '/nolith',
- },
- active: false,
- coverage: null,
- source: 'pipeline',
- source_job: {
- name: 'trigger_job',
- },
- path: '/gitlab-com/gitlab-docs/pipelines/34993051',
- details: {
- status: {
- icon: 'status_failed',
- text: 'failed',
- label: 'failed',
- group: 'failed',
- tooltip: 'failed',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/pipelines/34993051',
- illustration: null,
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_failed-41304d7f7e3828808b0c26771f0309e55296819a9beea3ea9fbf6689d9857c12.png',
- },
- duration: 118,
- finished_at: '2018-10-31T16:41:40.615Z',
- stages: [
- {
- name: 'build-images',
- title: 'build-images: skipped',
- groups: [
- {
- name: 'image:bootstrap',
- size: 1,
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982853',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982853/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- jobs: [
- {
- id: 11421321982853,
- name: 'image:bootstrap',
- started: null,
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114982853',
- play_path: '/gitlab-com/gitlab-docs/-/jobs/114982853/play',
- playable: true,
- scheduled: false,
- created_at: '2018-10-31T16:35:23.704Z',
- updated_at: '2018-10-31T16:35:24.118Z',
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982853',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982853/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- },
- ],
- },
- {
- name: 'image:builder-onbuild',
- size: 1,
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982854',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982854/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- jobs: [
- {
- id: 1149822131854,
- name: 'image:builder-onbuild',
- started: null,
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114982854',
- play_path: '/gitlab-com/gitlab-docs/-/jobs/114982854/play',
- playable: true,
- scheduled: false,
- created_at: '2018-10-31T16:35:23.728Z',
- updated_at: '2018-10-31T16:35:24.070Z',
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982854',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982854/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- },
- ],
- },
- {
- name: 'image:nginx-onbuild',
- size: 1,
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982855',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982855/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- jobs: [
- {
- id: 11498285523424,
- name: 'image:nginx-onbuild',
- started: null,
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114982855',
- play_path: '/gitlab-com/gitlab-docs/-/jobs/114982855/play',
- playable: true,
- scheduled: false,
- created_at: '2018-10-31T16:35:23.753Z',
- updated_at: '2018-10-31T16:35:24.033Z',
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982855',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982855/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- },
- ],
- },
- ],
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/pipelines/34993051#build-images',
- illustration: null,
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- path: '/gitlab-com/gitlab-docs/pipelines/34993051#build-images',
- dropdown_path:
- '/gitlab-com/gitlab-docs/pipelines/34993051/stage.json?stage=build-images',
- },
- {
- name: 'build',
- title: 'build: failed',
- groups: [
- {
- name: 'compile_dev',
- size: 1,
- status: {
- icon: 'status_failed',
- text: 'failed',
- label: 'failed',
- group: 'failed',
- tooltip: 'failed - (script failure)',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114984694',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_failed-41304d7f7e3828808b0c26771f0309e55296819a9beea3ea9fbf6689d9857c12.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/gitlab-com/gitlab-docs/-/jobs/114984694/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- jobs: [
- {
- id: 1149846949786,
- name: 'compile_dev',
- started: '2018-10-31T16:39:41.598Z',
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114984694',
- retry_path: '/gitlab-com/gitlab-docs/-/jobs/114984694/retry',
- playable: false,
- scheduled: false,
- created_at: '2018-10-31T16:39:41.138Z',
- updated_at: '2018-10-31T16:41:40.072Z',
- status: {
- icon: 'status_failed',
- text: 'failed',
- label: 'failed',
- group: 'failed',
- tooltip: 'failed - (script failure)',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114984694',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_failed-41304d7f7e3828808b0c26771f0309e55296819a9beea3ea9fbf6689d9857c12.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/gitlab-com/gitlab-docs/-/jobs/114984694/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- recoverable: false,
- },
- ],
- },
- ],
- status: {
- icon: 'status_failed',
- text: 'failed',
- label: 'failed',
- group: 'failed',
- tooltip: 'failed',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/pipelines/34993051#build',
- illustration: null,
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_failed-41304d7f7e3828808b0c26771f0309e55296819a9beea3ea9fbf6689d9857c12.png',
- },
- path: '/gitlab-com/gitlab-docs/pipelines/34993051#build',
- dropdown_path: '/gitlab-com/gitlab-docs/pipelines/34993051/stage.json?stage=build',
- },
- {
- name: 'deploy',
- title: 'deploy: skipped',
- groups: [
- {
- name: 'review',
- size: 1,
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982857',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job has been skipped',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- jobs: [
- {
- id: 11498282342357,
- name: 'review',
- started: null,
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114982857',
- playable: false,
- scheduled: false,
- created_at: '2018-10-31T16:35:23.805Z',
- updated_at: '2018-10-31T16:41:40.569Z',
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982857',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job has been skipped',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- },
- ],
- },
- {
- name: 'review_stop',
- size: 1,
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982858',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job has been skipped',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- jobs: [
- {
- id: 114982858,
- name: 'review_stop',
- started: null,
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114982858',
- playable: false,
- scheduled: false,
- created_at: '2018-10-31T16:35:23.840Z',
- updated_at: '2018-10-31T16:41:40.480Z',
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982858',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job has been skipped',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- },
- ],
- },
- ],
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/pipelines/34993051#deploy',
- illustration: null,
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- path: '/gitlab-com/gitlab-docs/pipelines/34993051#deploy',
- dropdown_path: '/gitlab-com/gitlab-docs/pipelines/34993051/stage.json?stage=deploy',
- },
- ],
- artifacts: [],
- manual_actions: [
- {
- name: 'image:bootstrap',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982853/play',
- playable: true,
- scheduled: false,
- },
- {
- name: 'image:builder-onbuild',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982854/play',
- playable: true,
- scheduled: false,
- },
- {
- name: 'image:nginx-onbuild',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982855/play',
- playable: true,
- scheduled: false,
- },
- {
- name: 'review_stop',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982858/play',
- playable: false,
- scheduled: false,
- },
- ],
- scheduled_actions: [],
- },
- project: {
- id: 20,
- name: 'GitLab Docs',
- full_path: '/gitlab-com/gitlab-docs',
- full_name: 'GitLab.com / GitLab Docs',
- },
- },
- triggered: [],
- },
- triggered: [
- {
- id: 34993051,
- user: {
- id: 376774,
- name: 'Alessio Caiazza',
- username: 'nolith',
- state: 'active',
- avatar_url:
- 'https://assets.gitlab-static.net/uploads/-/system/user/avatar/376774/avatar.png',
- web_url: 'https://gitlab.com/nolith',
- status_tooltip_html: null,
- path: '/nolith',
- },
- active: false,
- coverage: null,
- source: 'pipeline',
- source_job: {
- name: 'trigger_job',
- },
- path: '/gitlab-com/gitlab-docs/pipelines/34993051',
- details: {
- status: {
- icon: 'status_failed',
- text: 'failed',
- label: 'failed',
- group: 'failed',
- tooltip: 'failed',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/pipelines/34993051',
- illustration: null,
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_failed-41304d7f7e3828808b0c26771f0309e55296819a9beea3ea9fbf6689d9857c12.png',
- },
- duration: 118,
- finished_at: '2018-10-31T16:41:40.615Z',
- stages: [
- {
- name: 'build-images',
- title: 'build-images: skipped',
- groups: [
- {
- name: 'image:bootstrap',
- size: 1,
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982853',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982853/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- jobs: [
- {
- id: 114982853,
- name: 'image:bootstrap',
- started: null,
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114982853',
- play_path: '/gitlab-com/gitlab-docs/-/jobs/114982853/play',
- playable: true,
- scheduled: false,
- created_at: '2018-10-31T16:35:23.704Z',
- updated_at: '2018-10-31T16:35:24.118Z',
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982853',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982853/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- },
- ],
- },
- {
- name: 'image:builder-onbuild',
- size: 1,
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982854',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982854/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- jobs: [
- {
- id: 114982854,
- name: 'image:builder-onbuild',
- started: null,
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114982854',
- play_path: '/gitlab-com/gitlab-docs/-/jobs/114982854/play',
- playable: true,
- scheduled: false,
- created_at: '2018-10-31T16:35:23.728Z',
- updated_at: '2018-10-31T16:35:24.070Z',
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982854',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982854/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- },
- ],
- },
- {
- name: 'image:nginx-onbuild',
- size: 1,
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982855',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982855/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- jobs: [
- {
- id: 114982855,
- name: 'image:nginx-onbuild',
- started: null,
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114982855',
- play_path: '/gitlab-com/gitlab-docs/-/jobs/114982855/play',
- playable: true,
- scheduled: false,
- created_at: '2018-10-31T16:35:23.753Z',
- updated_at: '2018-10-31T16:35:24.033Z',
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982855',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982855/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- },
- ],
- },
- ],
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/pipelines/34993051#build-images',
- illustration: null,
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- path: '/gitlab-com/gitlab-docs/pipelines/34993051#build-images',
- dropdown_path:
- '/gitlab-com/gitlab-docs/pipelines/34993051/stage.json?stage=build-images',
- },
- {
- name: 'build',
- title: 'build: failed',
- groups: [
- {
- name: 'compile_dev',
- size: 1,
- status: {
- icon: 'status_failed',
- text: 'failed',
- label: 'failed',
- group: 'failed',
- tooltip: 'failed - (script failure)',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114984694',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_failed-41304d7f7e3828808b0c26771f0309e55296819a9beea3ea9fbf6689d9857c12.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/528/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- jobs: [
- {
- id: 114984694,
- name: 'compile_dev',
- started: '2018-10-31T16:39:41.598Z',
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114984694',
- retry_path: '/gitlab-com/gitlab-docs/-/jobs/114984694/retry',
- playable: false,
- scheduled: false,
- created_at: '2018-10-31T16:39:41.138Z',
- updated_at: '2018-10-31T16:41:40.072Z',
- status: {
- icon: 'status_failed',
- text: 'failed',
- label: 'failed',
- group: 'failed',
- tooltip: 'failed - (script failure)',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114984694',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_failed-41304d7f7e3828808b0c26771f0309e55296819a9beea3ea9fbf6689d9857c12.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/528/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- recoverable: false,
- },
- ],
- },
- ],
- status: {
- icon: 'status_failed',
- text: 'failed',
- label: 'failed',
- group: 'failed',
- tooltip: 'failed',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/pipelines/34993051#build',
- illustration: null,
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_failed-41304d7f7e3828808b0c26771f0309e55296819a9beea3ea9fbf6689d9857c12.png',
- },
- path: '/gitlab-com/gitlab-docs/pipelines/34993051#build',
- dropdown_path: '/gitlab-com/gitlab-docs/pipelines/34993051/stage.json?stage=build',
- },
- {
- name: 'deploy',
- title: 'deploy: skipped',
- groups: [
- {
- name: 'review',
- size: 1,
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982857',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job has been skipped',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- jobs: [
- {
- id: 114982857,
- name: 'review',
- started: null,
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114982857',
- playable: false,
- scheduled: false,
- created_at: '2018-10-31T16:35:23.805Z',
- updated_at: '2018-10-31T16:41:40.569Z',
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982857',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job has been skipped',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- },
- ],
- },
- {
- name: 'review_stop',
- size: 1,
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982858',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job has been skipped',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- jobs: [
- {
- id: 114982858,
- name: 'review_stop',
- started: null,
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114982858',
- playable: false,
- scheduled: false,
- created_at: '2018-10-31T16:35:23.840Z',
- updated_at: '2018-10-31T16:41:40.480Z',
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982858',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job has been skipped',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- },
- ],
- },
- ],
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/pipelines/34993051#deploy',
- illustration: null,
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- path: '/gitlab-com/gitlab-docs/pipelines/34993051#deploy',
- dropdown_path: '/gitlab-com/gitlab-docs/pipelines/34993051/stage.json?stage=deploy',
- },
- ],
- artifacts: [],
- manual_actions: [
- {
- name: 'image:bootstrap',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982853/play',
- playable: true,
- scheduled: false,
- },
- {
- name: 'image:builder-onbuild',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982854/play',
- playable: true,
- scheduled: false,
- },
- {
- name: 'image:nginx-onbuild',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982855/play',
- playable: true,
- scheduled: false,
- },
- {
- name: 'review_stop',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982858/play',
- playable: false,
- scheduled: false,
- },
- ],
- scheduled_actions: [],
- },
- project: {
- id: 20,
- name: 'GitLab Docs',
- full_path: '/gitlab-com/gitlab-docs',
- full_name: 'GitLab.com / GitLab Docs',
- },
- },
- {
- id: 34993052,
- user: {
- id: 376774,
- name: 'Alessio Caiazza',
- username: 'nolith',
- state: 'active',
- avatar_url:
- 'https://assets.gitlab-static.net/uploads/-/system/user/avatar/376774/avatar.png',
- web_url: 'https://gitlab.com/nolith',
- status_tooltip_html: null,
- path: '/nolith',
- },
- active: false,
- coverage: null,
- source: 'pipeline',
- source_job: {
- name: 'trigger_job',
- },
- path: '/gitlab-com/gitlab-docs/pipelines/34993051',
- details: {
- status: {
- icon: 'status_failed',
- text: 'failed',
- label: 'failed',
- group: 'failed',
- tooltip: 'failed',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/pipelines/34993051',
- illustration: null,
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_failed-41304d7f7e3828808b0c26771f0309e55296819a9beea3ea9fbf6689d9857c12.png',
- },
- duration: 118,
- finished_at: '2018-10-31T16:41:40.615Z',
- stages: [
- {
- name: 'build-images',
- title: 'build-images: skipped',
- groups: [
- {
- name: 'image:bootstrap',
- size: 1,
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982853',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982853/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- jobs: [
- {
- id: 114982853,
- name: 'image:bootstrap',
- started: null,
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114982853',
- play_path: '/gitlab-com/gitlab-docs/-/jobs/114982853/play',
- playable: true,
- scheduled: false,
- created_at: '2018-10-31T16:35:23.704Z',
- updated_at: '2018-10-31T16:35:24.118Z',
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982853',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982853/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- },
- ],
- },
- {
- name: 'image:builder-onbuild',
- size: 1,
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982854',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982854/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- jobs: [
- {
- id: 114982854,
- name: 'image:builder-onbuild',
- started: null,
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114982854',
- play_path: '/gitlab-com/gitlab-docs/-/jobs/114982854/play',
- playable: true,
- scheduled: false,
- created_at: '2018-10-31T16:35:23.728Z',
- updated_at: '2018-10-31T16:35:24.070Z',
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982854',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982854/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- },
- ],
- },
- {
- name: 'image:nginx-onbuild',
- size: 1,
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982855',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982855/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- jobs: [
- {
- id: 1224982855,
- name: 'image:nginx-onbuild',
- started: null,
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114982855',
- play_path: '/gitlab-com/gitlab-docs/-/jobs/114982855/play',
- playable: true,
- scheduled: false,
- created_at: '2018-10-31T16:35:23.753Z',
- updated_at: '2018-10-31T16:35:24.033Z',
- status: {
- icon: 'status_manual',
- text: 'manual',
- label: 'manual play action',
- group: 'manual',
- tooltip: 'manual action',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982855',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982855/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- },
- ],
- },
- ],
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/pipelines/34993051#build-images',
- illustration: null,
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- path: '/gitlab-com/gitlab-docs/pipelines/34993051#build-images',
- dropdown_path:
- '/gitlab-com/gitlab-docs/pipelines/34993051/stage.json?stage=build-images',
- },
- {
- name: 'build',
- title: 'build: failed',
- groups: [
- {
- name: 'compile_dev',
- size: 1,
- status: {
- icon: 'status_failed',
- text: 'failed',
- label: 'failed',
- group: 'failed',
- tooltip: 'failed - (script failure)',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114984694',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_failed-41304d7f7e3828808b0c26771f0309e55296819a9beea3ea9fbf6689d9857c12.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/gitlab-com/gitlab-docs/-/jobs/114984694/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- jobs: [
- {
- id: 1123984694,
- name: 'compile_dev',
- started: '2018-10-31T16:39:41.598Z',
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114984694',
- retry_path: '/gitlab-com/gitlab-docs/-/jobs/114984694/retry',
- playable: false,
- scheduled: false,
- created_at: '2018-10-31T16:39:41.138Z',
- updated_at: '2018-10-31T16:41:40.072Z',
- status: {
- icon: 'status_failed',
- text: 'failed',
- label: 'failed',
- group: 'failed',
- tooltip: 'failed - (script failure)',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114984694',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_failed-41304d7f7e3828808b0c26771f0309e55296819a9beea3ea9fbf6689d9857c12.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/gitlab-com/gitlab-docs/-/jobs/114984694/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- recoverable: false,
- },
- ],
- },
- ],
- status: {
- icon: 'status_failed',
- text: 'failed',
- label: 'failed',
- group: 'failed',
- tooltip: 'failed',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/pipelines/34993051#build',
- illustration: null,
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_failed-41304d7f7e3828808b0c26771f0309e55296819a9beea3ea9fbf6689d9857c12.png',
- },
- path: '/gitlab-com/gitlab-docs/pipelines/34993051#build',
- dropdown_path: '/gitlab-com/gitlab-docs/pipelines/34993051/stage.json?stage=build',
- },
- {
- name: 'deploy',
- title: 'deploy: skipped',
- groups: [
- {
- name: 'review',
- size: 1,
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982857',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job has been skipped',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- jobs: [
- {
- id: 1143232982857,
- name: 'review',
- started: null,
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114982857',
- playable: false,
- scheduled: false,
- created_at: '2018-10-31T16:35:23.805Z',
- updated_at: '2018-10-31T16:41:40.569Z',
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982857',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job has been skipped',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- },
- ],
- },
- {
- name: 'review_stop',
- size: 1,
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982858',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job has been skipped',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- jobs: [
- {
- id: 114921313182858,
- name: 'review_stop',
- started: null,
- archived: false,
- build_path: '/gitlab-com/gitlab-docs/-/jobs/114982858',
- playable: false,
- scheduled: false,
- created_at: '2018-10-31T16:35:23.840Z',
- updated_at: '2018-10-31T16:41:40.480Z',
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/-/jobs/114982858',
- illustration: {
- image:
- 'https://assets.gitlab-static.net/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job has been skipped',
- },
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- },
- ],
- },
- ],
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/gitlab-com/gitlab-docs/pipelines/34993051#deploy',
- illustration: null,
- favicon:
- 'https://gitlab.com/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- path: '/gitlab-com/gitlab-docs/pipelines/34993051#deploy',
- dropdown_path: '/gitlab-com/gitlab-docs/pipelines/34993051/stage.json?stage=deploy',
- },
- ],
- artifacts: [],
- manual_actions: [
- {
- name: 'image:bootstrap',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982853/play',
- playable: true,
- scheduled: false,
- },
- {
- name: 'image:builder-onbuild',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982854/play',
- playable: true,
- scheduled: false,
- },
- {
- name: 'image:nginx-onbuild',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982855/play',
- playable: true,
- scheduled: false,
- },
- {
- name: 'review_stop',
- path: '/gitlab-com/gitlab-docs/-/jobs/114982858/play',
- playable: false,
- scheduled: false,
- },
- ],
- scheduled_actions: [],
- },
- project: {
- id: 20,
- name: 'GitLab Docs',
- full_path: '/gitlab-com/gitlab-docs',
- full_name: 'GitLab.com / GitLab Docs',
- },
- triggered: [
- {
- id: 26,
- user: null,
- active: false,
- coverage: null,
- source: 'push',
- source_job: {
- name: 'trigger_job',
- },
- created_at: '2019-01-06T17:48:37.599Z',
- updated_at: '2019-01-06T17:48:38.371Z',
- path: '/h5bp/html5-boilerplate/pipelines/26',
- flags: {
- latest: true,
- stuck: false,
- auto_devops: false,
- merge_request: false,
- yaml_errors: false,
- retryable: true,
- cancelable: false,
- failure_reason: false,
- },
- details: {
- status: {
- icon: 'status_warning',
- text: 'passed',
- label: 'passed with warnings',
- group: 'success-with-warnings',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/pipelines/26',
- illustration: null,
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- },
- duration: null,
- finished_at: '2019-01-06T17:48:38.370Z',
- stages: [
- {
- name: 'build',
- title: 'build: passed',
- groups: [
- {
- name: 'build:linux',
- size: 1,
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/526',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/526/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- jobs: [
- {
- id: 526,
- name: 'build:linux',
- started: '2019-01-06T08:48:20.236Z',
- archived: false,
- build_path: '/h5bp/html5-boilerplate/-/jobs/526',
- retry_path: '/h5bp/html5-boilerplate/-/jobs/526/retry',
- playable: false,
- scheduled: false,
- created_at: '2019-01-06T17:48:37.806Z',
- updated_at: '2019-01-06T17:48:37.806Z',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/526',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/526/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- },
- ],
- },
- {
- name: 'build:osx',
- size: 1,
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/527',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/527/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- jobs: [
- {
- id: 527,
- name: 'build:osx',
- started: '2019-01-06T07:48:20.237Z',
- archived: false,
- build_path: '/h5bp/html5-boilerplate/-/jobs/527',
- retry_path: '/h5bp/html5-boilerplate/-/jobs/527/retry',
- playable: false,
- scheduled: false,
- created_at: '2019-01-06T17:48:37.846Z',
- updated_at: '2019-01-06T17:48:37.846Z',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/527',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/527/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- },
- ],
- },
- ],
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/pipelines/26#build',
- illustration: null,
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- },
- path: '/h5bp/html5-boilerplate/pipelines/26#build',
- dropdown_path: '/h5bp/html5-boilerplate/pipelines/26/stage.json?stage=build',
- },
- {
- name: 'test',
- title: 'test: passed with warnings',
- groups: [
- {
- name: 'jenkins',
- size: 1,
- status: {
- icon: 'status_success',
- text: 'passed',
- label: null,
- group: 'success',
- tooltip: null,
- has_details: false,
- details_path: null,
- illustration: null,
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- },
- jobs: [
- {
- id: 546,
- name: 'jenkins',
- started: '2019-01-06T11:48:20.237Z',
- archived: false,
- build_path: '/h5bp/html5-boilerplate/-/jobs/546',
- playable: false,
- scheduled: false,
- created_at: '2019-01-06T17:48:38.359Z',
- updated_at: '2019-01-06T17:48:38.359Z',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: null,
- group: 'success',
- tooltip: null,
- has_details: false,
- details_path: null,
- illustration: null,
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- },
- },
- ],
- },
- {
- name: 'rspec:linux',
- size: 3,
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: false,
- details_path: null,
- illustration: null,
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- },
- jobs: [
- {
- id: 528,
- name: 'rspec:linux 0 3',
- started: '2019-01-06T09:48:20.237Z',
- archived: false,
- build_path: '/h5bp/html5-boilerplate/-/jobs/528',
- retry_path: '/h5bp/html5-boilerplate/-/jobs/528/retry',
- playable: false,
- scheduled: false,
- created_at: '2019-01-06T17:48:37.885Z',
- updated_at: '2019-01-06T17:48:37.885Z',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/528',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/528/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- },
- {
- id: 529,
- name: 'rspec:linux 1 3',
- started: '2019-01-06T09:48:20.237Z',
- archived: false,
- build_path: '/h5bp/html5-boilerplate/-/jobs/529',
- retry_path: '/h5bp/html5-boilerplate/-/jobs/529/retry',
- playable: false,
- scheduled: false,
- created_at: '2019-01-06T17:48:37.907Z',
- updated_at: '2019-01-06T17:48:37.907Z',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/529',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/529/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- },
- {
- id: 530,
- name: 'rspec:linux 2 3',
- started: '2019-01-06T09:48:20.237Z',
- archived: false,
- build_path: '/h5bp/html5-boilerplate/-/jobs/530',
- retry_path: '/h5bp/html5-boilerplate/-/jobs/530/retry',
- playable: false,
- scheduled: false,
- created_at: '2019-01-06T17:48:37.927Z',
- updated_at: '2019-01-06T17:48:37.927Z',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/530',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/530/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- },
- ],
- },
- {
- name: 'rspec:osx',
- size: 1,
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/535',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/535/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- jobs: [
- {
- id: 535,
- name: 'rspec:osx',
- started: '2019-01-06T09:48:20.237Z',
- archived: false,
- build_path: '/h5bp/html5-boilerplate/-/jobs/535',
- retry_path: '/h5bp/html5-boilerplate/-/jobs/535/retry',
- playable: false,
- scheduled: false,
- created_at: '2019-01-06T17:48:38.018Z',
- updated_at: '2019-01-06T17:48:38.018Z',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/535',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/535/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- },
- ],
- },
- {
- name: 'rspec:windows',
- size: 3,
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: false,
- details_path: null,
- illustration: null,
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- },
- jobs: [
- {
- id: 531,
- name: 'rspec:windows 0 3',
- started: '2019-01-06T09:48:20.237Z',
- archived: false,
- build_path: '/h5bp/html5-boilerplate/-/jobs/531',
- retry_path: '/h5bp/html5-boilerplate/-/jobs/531/retry',
- playable: false,
- scheduled: false,
- created_at: '2019-01-06T17:48:37.944Z',
- updated_at: '2019-01-06T17:48:37.944Z',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/531',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/531/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- },
- {
- id: 532,
- name: 'rspec:windows 1 3',
- started: '2019-01-06T09:48:20.237Z',
- archived: false,
- build_path: '/h5bp/html5-boilerplate/-/jobs/532',
- retry_path: '/h5bp/html5-boilerplate/-/jobs/532/retry',
- playable: false,
- scheduled: false,
- created_at: '2019-01-06T17:48:37.962Z',
- updated_at: '2019-01-06T17:48:37.962Z',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/532',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/532/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- },
- {
- id: 534,
- name: 'rspec:windows 2 3',
- started: '2019-01-06T09:48:20.237Z',
- archived: false,
- build_path: '/h5bp/html5-boilerplate/-/jobs/534',
- retry_path: '/h5bp/html5-boilerplate/-/jobs/534/retry',
- playable: false,
- scheduled: false,
- created_at: '2019-01-06T17:48:37.999Z',
- updated_at: '2019-01-06T17:48:37.999Z',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/534',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/534/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- },
- ],
- },
- {
- name: 'spinach:linux',
- size: 1,
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/536',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/536/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- jobs: [
- {
- id: 536,
- name: 'spinach:linux',
- started: '2019-01-06T09:48:20.237Z',
- archived: false,
- build_path: '/h5bp/html5-boilerplate/-/jobs/536',
- retry_path: '/h5bp/html5-boilerplate/-/jobs/536/retry',
- playable: false,
- scheduled: false,
- created_at: '2019-01-06T17:48:38.050Z',
- updated_at: '2019-01-06T17:48:38.050Z',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/536',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/536/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- },
- ],
- },
- {
- name: 'spinach:osx',
- size: 1,
- status: {
- icon: 'status_warning',
- text: 'failed',
- label: 'failed (allowed to fail)',
- group: 'failed-with-warnings',
- tooltip: 'failed - (unknown failure) (allowed to fail)',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/537',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_failed-41304d7f7e3828808b0c26771f0309e55296819a9beea3ea9fbf6689d9857c12.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/537/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- jobs: [
- {
- id: 537,
- name: 'spinach:osx',
- started: '2019-01-06T09:48:20.237Z',
- archived: false,
- build_path: '/h5bp/html5-boilerplate/-/jobs/537',
- retry_path: '/h5bp/html5-boilerplate/-/jobs/537/retry',
- playable: false,
- scheduled: false,
- created_at: '2019-01-06T17:48:38.069Z',
- updated_at: '2019-01-06T17:48:38.069Z',
- status: {
- icon: 'status_warning',
- text: 'failed',
- label: 'failed (allowed to fail)',
- group: 'failed-with-warnings',
- tooltip: 'failed - (unknown failure) (allowed to fail)',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/537',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_failed-41304d7f7e3828808b0c26771f0309e55296819a9beea3ea9fbf6689d9857c12.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/537/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- callout_message: 'There is an unknown failure, please try again',
- recoverable: true,
- },
- ],
- },
- ],
- status: {
- icon: 'status_warning',
- text: 'passed',
- label: 'passed with warnings',
- group: 'success-with-warnings',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/pipelines/26#test',
- illustration: null,
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- },
- path: '/h5bp/html5-boilerplate/pipelines/26#test',
- dropdown_path: '/h5bp/html5-boilerplate/pipelines/26/stage.json?stage=test',
- },
- {
- name: 'security',
- title: 'security: passed',
- groups: [
- {
- name: 'container_scanning',
- size: 1,
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/541',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/541/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- jobs: [
- {
- id: 541,
- name: 'container_scanning',
- started: '2019-01-06T09:48:20.237Z',
- archived: false,
- build_path: '/h5bp/html5-boilerplate/-/jobs/541',
- retry_path: '/h5bp/html5-boilerplate/-/jobs/541/retry',
- playable: false,
- scheduled: false,
- created_at: '2019-01-06T17:48:38.186Z',
- updated_at: '2019-01-06T17:48:38.186Z',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/541',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/541/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- },
- ],
- },
- {
- name: 'dast',
- size: 1,
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/538',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/538/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- jobs: [
- {
- id: 538,
- name: 'dast',
- started: '2019-01-06T09:48:20.237Z',
- archived: false,
- build_path: '/h5bp/html5-boilerplate/-/jobs/538',
- retry_path: '/h5bp/html5-boilerplate/-/jobs/538/retry',
- playable: false,
- scheduled: false,
- created_at: '2019-01-06T17:48:38.087Z',
- updated_at: '2019-01-06T17:48:38.087Z',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/538',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/538/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- },
- ],
- },
- {
- name: 'dependency_scanning',
- size: 1,
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/540',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/540/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- jobs: [
- {
- id: 540,
- name: 'dependency_scanning',
- started: '2019-01-06T09:48:20.237Z',
- archived: false,
- build_path: '/h5bp/html5-boilerplate/-/jobs/540',
- retry_path: '/h5bp/html5-boilerplate/-/jobs/540/retry',
- playable: false,
- scheduled: false,
- created_at: '2019-01-06T17:48:38.153Z',
- updated_at: '2019-01-06T17:48:38.153Z',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/540',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/540/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- },
- ],
- },
- {
- name: 'sast',
- size: 1,
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/539',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/539/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- jobs: [
- {
- id: 539,
- name: 'sast',
- started: '2019-01-06T09:48:20.237Z',
- archived: false,
- build_path: '/h5bp/html5-boilerplate/-/jobs/539',
- retry_path: '/h5bp/html5-boilerplate/-/jobs/539/retry',
- playable: false,
- scheduled: false,
- created_at: '2019-01-06T17:48:38.121Z',
- updated_at: '2019-01-06T17:48:38.121Z',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/539',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/539/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- },
- ],
- },
- ],
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/pipelines/26#security',
- illustration: null,
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- },
- path: '/h5bp/html5-boilerplate/pipelines/26#security',
- dropdown_path: '/h5bp/html5-boilerplate/pipelines/26/stage.json?stage=security',
- },
- {
- name: 'deploy',
- title: 'deploy: passed',
- groups: [
- {
- name: 'production',
- size: 1,
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/544',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job has been skipped',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- jobs: [
- {
- id: 544,
- name: 'production',
- started: null,
- archived: false,
- build_path: '/h5bp/html5-boilerplate/-/jobs/544',
- playable: false,
- scheduled: false,
- created_at: '2019-01-06T17:48:38.313Z',
- updated_at: '2019-01-06T17:48:38.313Z',
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/544',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job has been skipped',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- },
- ],
- },
- {
- name: 'staging',
- size: 1,
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/542',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/542/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- jobs: [
- {
- id: 542,
- name: 'staging',
- started: '2019-01-06T11:48:20.237Z',
- archived: false,
- build_path: '/h5bp/html5-boilerplate/-/jobs/542',
- retry_path: '/h5bp/html5-boilerplate/-/jobs/542/retry',
- playable: false,
- scheduled: false,
- created_at: '2019-01-06T17:48:38.219Z',
- updated_at: '2019-01-06T17:48:38.219Z',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/542',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job does not have a trace.',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/h5bp/html5-boilerplate/-/jobs/542/retry',
- method: 'post',
- button_title: 'Retry this job',
- },
- },
- },
- ],
- },
- {
- name: 'stop staging',
- size: 1,
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/543',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job has been skipped',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- jobs: [
- {
- id: 543,
- name: 'stop staging',
- started: null,
- archived: false,
- build_path: '/h5bp/html5-boilerplate/-/jobs/543',
- playable: false,
- scheduled: false,
- created_at: '2019-01-06T17:48:38.283Z',
- updated_at: '2019-01-06T17:48:38.283Z',
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- tooltip: 'skipped',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/543',
- illustration: {
- image:
- '/assets/illustrations/skipped-job_empty-8b877955fbf175e42ae65b6cb95346e15282c6fc5b682756c329af3a0055225e.svg',
- size: 'svg-430',
- title: 'This job has been skipped',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_skipped-0b9c5e543588945e8c4ca57786bbf2d0c56631959c9f853300392d0315be829b.png',
- },
- },
- ],
- },
- ],
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/pipelines/26#deploy',
- illustration: null,
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- },
- path: '/h5bp/html5-boilerplate/pipelines/26#deploy',
- dropdown_path: '/h5bp/html5-boilerplate/pipelines/26/stage.json?stage=deploy',
- },
- {
- name: 'notify',
- title: 'notify: passed',
- groups: [
- {
- name: 'slack',
- size: 1,
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'manual play action',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/545',
- illustration: {
- image:
- '/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/h5bp/html5-boilerplate/-/jobs/545/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- jobs: [
- {
- id: 545,
- name: 'slack',
- started: null,
- archived: false,
- build_path: '/h5bp/html5-boilerplate/-/jobs/545',
- retry_path: '/h5bp/html5-boilerplate/-/jobs/545/retry',
- play_path: '/h5bp/html5-boilerplate/-/jobs/545/play',
- playable: true,
- scheduled: false,
- created_at: '2019-01-06T17:48:38.341Z',
- updated_at: '2019-01-06T17:48:38.341Z',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'manual play action',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/-/jobs/545',
- illustration: {
- image:
- '/assets/illustrations/manual_action-2b4ca0d1bcfd92aebf33d484e36cbf7a102d007f76b5a0cfea636033a629d601.svg',
- size: 'svg-394',
- title: 'This job requires a manual action',
- content:
- 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
- },
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/h5bp/html5-boilerplate/-/jobs/545/play',
- method: 'post',
- button_title: 'Trigger this manual action',
- },
- },
- },
- ],
- },
- ],
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/h5bp/html5-boilerplate/pipelines/26#notify',
- illustration: null,
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- },
- path: '/h5bp/html5-boilerplate/pipelines/26#notify',
- dropdown_path: '/h5bp/html5-boilerplate/pipelines/26/stage.json?stage=notify',
- },
- ],
- artifacts: [
- {
- name: 'build:linux',
- expired: null,
- expire_at: null,
- path: '/h5bp/html5-boilerplate/-/jobs/526/artifacts/download',
- browse_path: '/h5bp/html5-boilerplate/-/jobs/526/artifacts/browse',
- },
- {
- name: 'build:osx',
- expired: null,
- expire_at: null,
- path: '/h5bp/html5-boilerplate/-/jobs/527/artifacts/download',
- browse_path: '/h5bp/html5-boilerplate/-/jobs/527/artifacts/browse',
- },
- ],
- manual_actions: [
- {
- name: 'stop staging',
- path: '/h5bp/html5-boilerplate/-/jobs/543/play',
- playable: false,
- scheduled: false,
- },
- {
- name: 'production',
- path: '/h5bp/html5-boilerplate/-/jobs/544/play',
- playable: false,
- scheduled: false,
- },
- {
- name: 'slack',
- path: '/h5bp/html5-boilerplate/-/jobs/545/play',
- playable: true,
- scheduled: false,
- },
- ],
- scheduled_actions: [],
- },
- ref: {
- name: 'main',
- path: '/h5bp/html5-boilerplate/commits/main',
- tag: false,
- branch: true,
- merge_request: false,
- },
- commit: {
- id: 'bad98c453eab56d20057f3929989251d45cd1a8b',
- short_id: 'bad98c45',
- title: 'remove instances of shrink-to-fit=no (#2103)',
- created_at: '2018-12-17T20:52:18.000Z',
- parent_ids: ['49130f6cfe9ff1f749015d735649a2bc6f66cf3a'],
- message:
- 'remove instances of shrink-to-fit=no (#2103)\n\ncloses #2102\r\n\r\nPer my findings, the need for it as a default was rectified with the release of iOS 9.3, where the viewport no longer shrunk to accommodate overflow, as was introduced in iOS 9.',
- author_name: "Scott O'Hara",
- author_email: 'scottaohara@users.noreply.github.com',
- authored_date: '2018-12-17T20:52:18.000Z',
- committer_name: 'Rob Larsen',
- committer_email: 'rob@drunkenfist.com',
- committed_date: '2018-12-17T20:52:18.000Z',
- author: null,
- author_gravatar_url:
- 'https://www.gravatar.com/avatar/6d597df7cf998d16cbe00ccac063b31e?s=80\u0026d=identicon',
- commit_url:
- 'http://localhost:3001/h5bp/html5-boilerplate/commit/bad98c453eab56d20057f3929989251d45cd1a8b',
- commit_path: '/h5bp/html5-boilerplate/commit/bad98c453eab56d20057f3929989251d45cd1a8b',
- },
- retry_path: '/h5bp/html5-boilerplate/pipelines/26/retry',
- triggered_by: {
- id: 4,
- user: null,
- active: false,
- coverage: null,
- source: 'push',
- source_job: {
- name: 'trigger_job',
- },
- path: '/gitlab-org/gitlab-test/pipelines/4',
- details: {
- status: {
- icon: 'status_warning',
- text: 'passed',
- label: 'passed with warnings',
- group: 'success-with-warnings',
- tooltip: 'passed',
- has_details: true,
- details_path: '/gitlab-org/gitlab-test/pipelines/4',
- illustration: null,
- favicon:
- '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
- },
- },
- project: {
- id: 1,
- name: 'Gitlab Test',
- full_path: '/gitlab-org/gitlab-test',
- full_name: 'Gitlab Org / Gitlab Test',
- },
- },
- triggered: [],
- project: {
- id: 20,
- name: 'GitLab Docs',
- full_path: '/gitlab-com/gitlab-docs',
- full_name: 'GitLab.com / GitLab Docs',
- },
- },
- ],
- },
- ],
+ multiproject: true,
};
diff --git a/spec/frontend/pipelines/header_component_spec.js b/spec/frontend/pipelines/header_component_spec.js
index e531e26a858..9e51003da66 100644
--- a/spec/frontend/pipelines/header_component_spec.js
+++ b/spec/frontend/pipelines/header_component_spec.js
@@ -24,7 +24,7 @@ describe('Pipeline details header', () => {
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
const defaultProvideOptions = {
- pipelineId: 14,
+ pipelineId: '14',
pipelineIid: 1,
paths: {
pipelinesPath: '/namespace/my-project/-/pipelines',
diff --git a/spec/frontend/pipelines/parsing_utils_spec.js b/spec/frontend/pipelines/parsing_utils_spec.js
deleted file mode 100644
index 3a270c1c1b5..00000000000
--- a/spec/frontend/pipelines/parsing_utils_spec.js
+++ /dev/null
@@ -1,161 +0,0 @@
-import { createSankey } from '~/pipelines/components/dag/drawing_utils';
-import {
- createNodeDict,
- makeLinksFromNodes,
- filterByAncestors,
- generateColumnsFromLayersListBare,
- listByLayers,
- parseData,
- removeOrphanNodes,
- getMaxNodes,
-} from '~/pipelines/components/parsing_utils';
-
-import { mockParsedGraphQLNodes, missingJob } from './components/dag/mock_data';
-import { generateResponse, mockPipelineResponse } from './graph/mock_data';
-
-describe('DAG visualization parsing utilities', () => {
- const nodeDict = createNodeDict(mockParsedGraphQLNodes);
- const unfilteredLinks = makeLinksFromNodes(mockParsedGraphQLNodes, nodeDict);
- const parsed = parseData(mockParsedGraphQLNodes);
-
- describe('makeLinksFromNodes', () => {
- it('returns the expected link structure', () => {
- expect(unfilteredLinks[0]).toHaveProperty('source', 'build_a');
- expect(unfilteredLinks[0]).toHaveProperty('target', 'test_a');
- expect(unfilteredLinks[0]).toHaveProperty('value', 10);
- });
-
- it('does not generate a link for non-existing jobs', () => {
- const sources = unfilteredLinks.map(({ source }) => source);
-
- expect(sources.includes(missingJob)).toBe(false);
- });
- });
-
- describe('filterByAncestors', () => {
- const allLinks = [
- { source: 'job1', target: 'job4' },
- { source: 'job1', target: 'job2' },
- { source: 'job2', target: 'job4' },
- ];
-
- const dedupedLinks = [
- { source: 'job1', target: 'job2' },
- { source: 'job2', target: 'job4' },
- ];
-
- const nodeLookup = {
- job1: {
- name: 'job1',
- },
- job2: {
- name: 'job2',
- needs: ['job1'],
- },
- job4: {
- name: 'job4',
- needs: ['job1', 'job2'],
- category: 'build',
- },
- };
-
- it('dedupes links', () => {
- expect(filterByAncestors(allLinks, nodeLookup)).toMatchObject(dedupedLinks);
- });
- });
-
- describe('parseData parent function', () => {
- it('returns an object containing a list of nodes and links', () => {
- // an array of nodes exist and the values are defined
- expect(parsed).toHaveProperty('nodes');
- expect(Array.isArray(parsed.nodes)).toBe(true);
- expect(parsed.nodes.filter(Boolean)).not.toHaveLength(0);
-
- // an array of links exist and the values are defined
- expect(parsed).toHaveProperty('links');
- expect(Array.isArray(parsed.links)).toBe(true);
- expect(parsed.links.filter(Boolean)).not.toHaveLength(0);
- });
- });
-
- describe('removeOrphanNodes', () => {
- it('removes sankey nodes that have no needs and are not needed', () => {
- const layoutSettings = {
- width: 200,
- height: 200,
- nodeWidth: 10,
- nodePadding: 20,
- paddingForLabels: 100,
- };
-
- const sankeyLayout = createSankey(layoutSettings)(parsed);
- const cleanedNodes = removeOrphanNodes(sankeyLayout.nodes);
- /*
- These lengths are determined by the mock data.
- If the data changes, the numbers may also change.
- */
- expect(parsed.nodes).toHaveLength(mockParsedGraphQLNodes.length);
- expect(cleanedNodes).toHaveLength(12);
- });
- });
-
- describe('getMaxNodes', () => {
- it('returns the number of nodes in the most populous generation', () => {
- const layerNodes = [
- { layer: 0 },
- { layer: 0 },
- { layer: 1 },
- { layer: 1 },
- { layer: 0 },
- { layer: 3 },
- { layer: 2 },
- { layer: 4 },
- { layer: 1 },
- { layer: 3 },
- { layer: 4 },
- ];
- expect(getMaxNodes(layerNodes)).toBe(3);
- });
- });
-
- describe('generateColumnsFromLayersList', () => {
- const pipeline = generateResponse(mockPipelineResponse, 'root/fungi-xoxo');
- const { pipelineLayers } = listByLayers(pipeline);
- const columns = generateColumnsFromLayersListBare(pipeline, pipelineLayers);
-
- it('returns stage-like objects with default name, id, and status', () => {
- columns.forEach((col, idx) => {
- expect(col).toMatchObject({
- name: '',
- status: { action: null },
- id: `layer-${idx}`,
- });
- });
- });
-
- it('creates groups that match the list created in listByLayers', () => {
- columns.forEach((col, idx) => {
- const groupNames = col.groups.map(({ name }) => name);
- expect(groupNames).toEqual(pipelineLayers[idx]);
- });
- });
-
- it('looks up the correct group object', () => {
- columns.forEach((col) => {
- col.groups.forEach((group) => {
- const groupStage = pipeline.stages.find((el) => el.name === group.stageName);
- const groupObject = groupStage.groups.find((el) => el.name === group.name);
- expect(group).toBe(groupObject);
- });
- });
- });
-
- /*
- Just as a fallback in case multiple functions change, so tests pass
- but the implementation moves away from case.
- */
- it('matches the snapshot', () => {
- expect(columns).toMatchSnapshot();
- });
- });
-});
diff --git a/spec/frontend/pipelines/pipeline_multi_actions_spec.js b/spec/frontend/pipelines/pipeline_multi_actions_spec.js
index ce33b6011bf..a606595b37d 100644
--- a/spec/frontend/pipelines/pipeline_multi_actions_spec.js
+++ b/spec/frontend/pipelines/pipeline_multi_actions_spec.js
@@ -1,4 +1,4 @@
-import { GlAlert, GlDropdown, GlSprintf } from '@gitlab/ui';
+import { GlAlert, GlDropdown, GlSprintf, GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
@@ -51,6 +51,7 @@ describe('Pipeline Multi Actions Dropdown', () => {
const findAlert = () => wrapper.findComponent(GlAlert);
const findDropdown = () => wrapper.findComponent(GlDropdown);
+ const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findAllArtifactItems = () => wrapper.findAllByTestId(artifactItemTestId);
const findFirstArtifactItem = () => wrapper.findByTestId(artifactItemTestId);
const findEmptyMessage = () => wrapper.findByTestId('artifacts-empty-message');
@@ -103,6 +104,15 @@ describe('Pipeline Multi Actions Dropdown', () => {
expect(findEmptyMessage().exists()).toBe(true);
});
+ describe('while loading artifacts', () => {
+ it('should render a loading spinner and no empty message', () => {
+ createComponent({ mockData: { isLoading: true, artifacts: [] } });
+
+ expect(findLoadingIcon().exists()).toBe(true);
+ expect(findEmptyMessage().exists()).toBe(false);
+ });
+ });
+
describe('with a failing request', () => {
it('should render an error message', async () => {
const endpoint = artifactsEndpoint.replace(artifactsEndpointPlaceholder, pipelineId);
diff --git a/spec/frontend/pipelines/pipelines_spec.js b/spec/frontend/pipelines/pipelines_spec.js
index 76feaaad1ec..aa30062c987 100644
--- a/spec/frontend/pipelines/pipelines_spec.js
+++ b/spec/frontend/pipelines/pipelines_spec.js
@@ -105,8 +105,6 @@ describe('Pipelines', () => {
});
beforeEach(() => {
- window.gon = { features: { pipelineSourceFilter: true } };
-
mock = new MockAdapter(axios);
jest.spyOn(window.history, 'pushState');
diff --git a/spec/frontend/pipelines/tokens/pipeline_source_token_spec.js b/spec/frontend/pipelines/tokens/pipeline_source_token_spec.js
index 5d15f0a3c55..684d2d0664a 100644
--- a/spec/frontend/pipelines/tokens/pipeline_source_token_spec.js
+++ b/spec/frontend/pipelines/tokens/pipeline_source_token_spec.js
@@ -1,5 +1,6 @@
import { GlFilteredSearchToken, GlFilteredSearchSuggestion } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { PIPELINE_SOURCES } from 'ee_else_ce/pipelines/components/pipelines_list/tokens/constants';
import { stubComponent } from 'helpers/stub_component';
import PipelineSourceToken from '~/pipelines/components/pipelines_list/tokens/pipeline_source_token.vue';
@@ -44,7 +45,7 @@ describe('Pipeline Source Token', () => {
describe('shows sources correctly', () => {
it('renders all pipeline sources available', () => {
- expect(findAllFilteredSearchSuggestions()).toHaveLength(wrapper.vm.sources.length);
+ expect(findAllFilteredSearchSuggestions()).toHaveLength(PIPELINE_SOURCES.length);
});
});
});
diff --git a/spec/frontend/pipelines/utils_spec.js b/spec/frontend/pipelines/utils_spec.js
new file mode 100644
index 00000000000..1c23a7e4fcf
--- /dev/null
+++ b/spec/frontend/pipelines/utils_spec.js
@@ -0,0 +1,161 @@
+import { createSankey } from '~/pipelines/components/dag/drawing_utils';
+import {
+ makeLinksFromNodes,
+ filterByAncestors,
+ generateColumnsFromLayersListBare,
+ listByLayers,
+ parseData,
+ removeOrphanNodes,
+ getMaxNodes,
+} from '~/pipelines/components/parsing_utils';
+import { createNodeDict } from '~/pipelines/utils';
+
+import { mockParsedGraphQLNodes, missingJob } from './components/dag/mock_data';
+import { generateResponse, mockPipelineResponse } from './graph/mock_data';
+
+describe('DAG visualization parsing utilities', () => {
+ const nodeDict = createNodeDict(mockParsedGraphQLNodes);
+ const unfilteredLinks = makeLinksFromNodes(mockParsedGraphQLNodes, nodeDict);
+ const parsed = parseData(mockParsedGraphQLNodes);
+
+ describe('makeLinksFromNodes', () => {
+ it('returns the expected link structure', () => {
+ expect(unfilteredLinks[0]).toHaveProperty('source', 'build_a');
+ expect(unfilteredLinks[0]).toHaveProperty('target', 'test_a');
+ expect(unfilteredLinks[0]).toHaveProperty('value', 10);
+ });
+
+ it('does not generate a link for non-existing jobs', () => {
+ const sources = unfilteredLinks.map(({ source }) => source);
+
+ expect(sources.includes(missingJob)).toBe(false);
+ });
+ });
+
+ describe('filterByAncestors', () => {
+ const allLinks = [
+ { source: 'job1', target: 'job4' },
+ { source: 'job1', target: 'job2' },
+ { source: 'job2', target: 'job4' },
+ ];
+
+ const dedupedLinks = [
+ { source: 'job1', target: 'job2' },
+ { source: 'job2', target: 'job4' },
+ ];
+
+ const nodeLookup = {
+ job1: {
+ name: 'job1',
+ },
+ job2: {
+ name: 'job2',
+ needs: ['job1'],
+ },
+ job4: {
+ name: 'job4',
+ needs: ['job1', 'job2'],
+ category: 'build',
+ },
+ };
+
+ it('dedupes links', () => {
+ expect(filterByAncestors(allLinks, nodeLookup)).toMatchObject(dedupedLinks);
+ });
+ });
+
+ describe('parseData parent function', () => {
+ it('returns an object containing a list of nodes and links', () => {
+ // an array of nodes exist and the values are defined
+ expect(parsed).toHaveProperty('nodes');
+ expect(Array.isArray(parsed.nodes)).toBe(true);
+ expect(parsed.nodes.filter(Boolean)).not.toHaveLength(0);
+
+ // an array of links exist and the values are defined
+ expect(parsed).toHaveProperty('links');
+ expect(Array.isArray(parsed.links)).toBe(true);
+ expect(parsed.links.filter(Boolean)).not.toHaveLength(0);
+ });
+ });
+
+ describe('removeOrphanNodes', () => {
+ it('removes sankey nodes that have no needs and are not needed', () => {
+ const layoutSettings = {
+ width: 200,
+ height: 200,
+ nodeWidth: 10,
+ nodePadding: 20,
+ paddingForLabels: 100,
+ };
+
+ const sankeyLayout = createSankey(layoutSettings)(parsed);
+ const cleanedNodes = removeOrphanNodes(sankeyLayout.nodes);
+ /*
+ These lengths are determined by the mock data.
+ If the data changes, the numbers may also change.
+ */
+ expect(parsed.nodes).toHaveLength(mockParsedGraphQLNodes.length);
+ expect(cleanedNodes).toHaveLength(12);
+ });
+ });
+
+ describe('getMaxNodes', () => {
+ it('returns the number of nodes in the most populous generation', () => {
+ const layerNodes = [
+ { layer: 0 },
+ { layer: 0 },
+ { layer: 1 },
+ { layer: 1 },
+ { layer: 0 },
+ { layer: 3 },
+ { layer: 2 },
+ { layer: 4 },
+ { layer: 1 },
+ { layer: 3 },
+ { layer: 4 },
+ ];
+ expect(getMaxNodes(layerNodes)).toBe(3);
+ });
+ });
+
+ describe('generateColumnsFromLayersList', () => {
+ const pipeline = generateResponse(mockPipelineResponse, 'root/fungi-xoxo');
+ const { pipelineLayers } = listByLayers(pipeline);
+ const columns = generateColumnsFromLayersListBare(pipeline, pipelineLayers);
+
+ it('returns stage-like objects with default name, id, and status', () => {
+ columns.forEach((col, idx) => {
+ expect(col).toMatchObject({
+ name: '',
+ status: { action: null },
+ id: `layer-${idx}`,
+ });
+ });
+ });
+
+ it('creates groups that match the list created in listByLayers', () => {
+ columns.forEach((col, idx) => {
+ const groupNames = col.groups.map(({ name }) => name);
+ expect(groupNames).toEqual(pipelineLayers[idx]);
+ });
+ });
+
+ it('looks up the correct group object', () => {
+ columns.forEach((col) => {
+ col.groups.forEach((group) => {
+ const groupStage = pipeline.stages.find((el) => el.name === group.stageName);
+ const groupObject = groupStage.groups.find((el) => el.name === group.name);
+ expect(group).toBe(groupObject);
+ });
+ });
+ });
+
+ /*
+ Just as a fallback in case multiple functions change, so tests pass
+ but the implementation moves away from case.
+ */
+ it('matches the snapshot', () => {
+ expect(columns).toMatchSnapshot();
+ });
+ });
+});
diff --git a/spec/frontend/pipelines_spec.js b/spec/frontend/pipelines_spec.js
deleted file mode 100644
index add91fbcc23..00000000000
--- a/spec/frontend/pipelines_spec.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import Pipelines from '~/pipelines';
-
-describe('Pipelines', () => {
- beforeEach(() => {
- loadFixtures('static/pipeline_graph.html');
- });
-
- it('should be defined', () => {
- expect(Pipelines).toBeDefined();
- });
-
- it('should create a `Pipelines` instance without options', () => {
- expect(() => {
- new Pipelines(); // eslint-disable-line no-new
- }).not.toThrow();
- });
-});
diff --git a/spec/frontend/popovers/components/popovers_spec.js b/spec/frontend/popovers/components/popovers_spec.js
index 25c509346d1..2751a878e51 100644
--- a/spec/frontend/popovers/components/popovers_spec.js
+++ b/spec/frontend/popovers/components/popovers_spec.js
@@ -54,17 +54,20 @@ describe('popovers/components/popovers.vue', () => {
expect(wrapper.findAll(GlPopover)).toHaveLength(1);
});
- it('supports HTML content', async () => {
- const content = 'content with <b>HTML</b>';
- await buildWrapper(
- createPopoverTarget({
- content,
- html: true,
- }),
- );
- const html = wrapper.find(GlPopover).html();
-
- expect(html).toContain(content);
+ describe('supports HTML content', () => {
+ const svgIcon = '<svg><use xlink:href="icons.svg#test"></use></svg>';
+
+ it.each`
+ description | content | render
+ ${'renders html content correctly'} | ${'<b>HTML</b>'} | ${'<b>HTML</b>'}
+ ${'removes any unsafe content'} | ${'<script>alert(XSS)</script>'} | ${''}
+ ${'renders svg icons correctly'} | ${svgIcon} | ${svgIcon}
+ `('$description', async ({ content, render }) => {
+ await buildWrapper(createPopoverTarget({ content, html: true }));
+
+ const html = wrapper.find(GlPopover).html();
+ expect(html).toContain(render);
+ });
});
it.each`
diff --git a/spec/frontend/projects/pipelines/charts/components/pipeline_charts_spec.js b/spec/frontend/projects/pipelines/charts/components/pipeline_charts_spec.js
index b5ee62f2042..6ef49390c47 100644
--- a/spec/frontend/projects/pipelines/charts/components/pipeline_charts_spec.js
+++ b/spec/frontend/projects/pipelines/charts/components/pipeline_charts_spec.js
@@ -60,7 +60,7 @@ describe('~/projects/pipelines/charts/components/pipeline_charts.vue', () => {
expect(chart.props('yAxisTitle')).toBe('Minutes');
expect(chart.props('xAxisTitle')).toBe('Commit');
expect(chart.props('bars')).toBe(wrapper.vm.timesChartTransformedData);
- expect(chart.props('option')).toBe(wrapper.vm.$options.timesChartOptions);
+ expect(chart.props('option')).toBe(wrapper.vm.chartOptions);
});
});
diff --git a/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js b/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js
index 5323c1afbb5..eacf858f22c 100644
--- a/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js
+++ b/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js
@@ -107,6 +107,29 @@ describe('ServiceDeskSetting', () => {
});
});
+ describe('project suffix', () => {
+ it('input is hidden', () => {
+ wrapper = createComponent({
+ props: { customEmailEnabled: false },
+ });
+
+ const input = wrapper.findByTestId('project-suffix');
+
+ expect(input.exists()).toBe(false);
+ });
+
+ it('input is enabled', () => {
+ wrapper = createComponent({
+ props: { customEmailEnabled: true },
+ });
+
+ const input = wrapper.findByTestId('project-suffix');
+
+ expect(input.exists()).toBe(true);
+ expect(input.attributes('disabled')).toBeUndefined();
+ });
+ });
+
describe('customEmail is the same as incomingEmail', () => {
const email = 'foo@bar.com';
diff --git a/spec/frontend/projects/storage_counter/components/app_spec.js b/spec/frontend/projects/storage_counter/components/app_spec.js
new file mode 100644
index 00000000000..f3da01e0602
--- /dev/null
+++ b/spec/frontend/projects/storage_counter/components/app_spec.js
@@ -0,0 +1,150 @@
+import { GlAlert, GlLoadingIcon } from '@gitlab/ui';
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import { extendedWrapper } from 'helpers/vue_test_utils_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import StorageCounterApp from '~/projects/storage_counter/components/app.vue';
+import { TOTAL_USAGE_DEFAULT_TEXT } from '~/projects/storage_counter/constants';
+import getProjectStorageCount from '~/projects/storage_counter/queries/project_storage.query.graphql';
+import UsageGraph from '~/vue_shared/components/storage_counter/usage_graph.vue';
+import {
+ mockGetProjectStorageCountGraphQLResponse,
+ mockEmptyResponse,
+ projectData,
+ defaultProvideValues,
+} from '../mock_data';
+
+const localVue = createLocalVue();
+localVue.use(VueApollo);
+
+describe('Storage counter app', () => {
+ let wrapper;
+
+ const createMockApolloProvider = ({ reject = false, mockedValue } = {}) => {
+ let response;
+
+ if (reject) {
+ response = jest.fn().mockRejectedValue(mockedValue || new Error('GraphQL error'));
+ } else {
+ response = jest.fn().mockResolvedValue(mockedValue);
+ }
+
+ const requestHandlers = [[getProjectStorageCount, response]];
+
+ return createMockApollo(requestHandlers);
+ };
+
+ const createComponent = ({ provide = {}, mockApollo } = {}) => {
+ wrapper = extendedWrapper(
+ shallowMount(StorageCounterApp, {
+ localVue,
+ apolloProvider: mockApollo,
+ provide: {
+ ...defaultProvideValues,
+ ...provide,
+ },
+ }),
+ );
+ };
+
+ const findAlert = () => wrapper.findComponent(GlAlert);
+ const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
+ const findUsagePercentage = () => wrapper.findByTestId('total-usage');
+ const findUsageQuotasHelpLink = () => wrapper.findByTestId('usage-quotas-help-link');
+ const findUsageGraph = () => wrapper.findComponent(UsageGraph);
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('with apollo fetching successful', () => {
+ let mockApollo;
+
+ beforeEach(async () => {
+ mockApollo = createMockApolloProvider({
+ mockedValue: mockGetProjectStorageCountGraphQLResponse,
+ });
+ createComponent({ mockApollo });
+ await waitForPromises();
+ });
+
+ it('renders correct total usage', () => {
+ expect(findUsagePercentage().text()).toBe(projectData.storage.totalUsage);
+ });
+
+ it('renders correct usage quotas help link', () => {
+ expect(findUsageQuotasHelpLink().attributes('href')).toBe(
+ defaultProvideValues.helpLinks.usageQuotasHelpPagePath,
+ );
+ });
+ });
+
+ describe('with apollo loading', () => {
+ let mockApollo;
+
+ beforeEach(() => {
+ mockApollo = createMockApolloProvider({
+ mockedValue: new Promise(() => {}),
+ });
+ createComponent({ mockApollo });
+ });
+
+ it('should show loading icon', () => {
+ expect(findLoadingIcon().exists()).toBe(true);
+ });
+ });
+
+ describe('with apollo returning empty data', () => {
+ let mockApollo;
+
+ beforeEach(async () => {
+ mockApollo = createMockApolloProvider({
+ mockedValue: mockEmptyResponse,
+ });
+ createComponent({ mockApollo });
+ await waitForPromises();
+ });
+
+ it('shows default text for total usage', () => {
+ expect(findUsagePercentage().text()).toBe(TOTAL_USAGE_DEFAULT_TEXT);
+ });
+ });
+
+ describe('with apollo fetching error', () => {
+ let mockApollo;
+
+ beforeEach(() => {
+ mockApollo = createMockApolloProvider();
+ createComponent({ mockApollo, reject: true });
+ });
+
+ it('renders gl-alert', () => {
+ expect(findAlert().exists()).toBe(true);
+ });
+ });
+
+ describe('rendering <usage-graph />', () => {
+ let mockApollo;
+
+ beforeEach(async () => {
+ mockApollo = createMockApolloProvider({
+ mockedValue: mockGetProjectStorageCountGraphQLResponse,
+ });
+ createComponent({ mockApollo });
+ await waitForPromises();
+ });
+
+ it('renders usage-graph component if project.statistics exists', () => {
+ expect(findUsageGraph().exists()).toBe(true);
+ });
+
+ it('passes project.statistics to usage-graph component', () => {
+ const {
+ __typename,
+ ...statistics
+ } = mockGetProjectStorageCountGraphQLResponse.data.project.statistics;
+ expect(findUsageGraph().props('rootStorageStatistics')).toMatchObject(statistics);
+ });
+ });
+});
diff --git a/spec/frontend/projects/storage_counter/components/storage_table_spec.js b/spec/frontend/projects/storage_counter/components/storage_table_spec.js
new file mode 100644
index 00000000000..14298318fff
--- /dev/null
+++ b/spec/frontend/projects/storage_counter/components/storage_table_spec.js
@@ -0,0 +1,62 @@
+import { GlTable } from '@gitlab/ui';
+import { mount } from '@vue/test-utils';
+import { extendedWrapper } from 'helpers/vue_test_utils_helper';
+import StorageTable from '~/projects/storage_counter/components/storage_table.vue';
+import { projectData, defaultProvideValues } from '../mock_data';
+
+describe('StorageTable', () => {
+ let wrapper;
+
+ const defaultProps = {
+ storageTypes: projectData.storage.storageTypes,
+ };
+
+ const createComponent = (props = {}) => {
+ wrapper = extendedWrapper(
+ mount(StorageTable, {
+ propsData: {
+ ...defaultProps,
+ ...props,
+ },
+ }),
+ );
+ };
+
+ const findTable = () => wrapper.findComponent(GlTable);
+
+ beforeEach(() => {
+ createComponent();
+ });
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('with storage types', () => {
+ it.each(projectData.storage.storageTypes)(
+ 'renders table row correctly %o',
+ ({ storageType: { id, name, description } }) => {
+ expect(wrapper.findByTestId(`${id}-name`).text()).toBe(name);
+ expect(wrapper.findByTestId(`${id}-description`).text()).toBe(description);
+ expect(wrapper.findByTestId(`${id}-help-link`).attributes('href')).toBe(
+ defaultProvideValues.helpLinks[id.replace(`Size`, `HelpPagePath`)]
+ .replace(`Size`, ``)
+ .replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`),
+ );
+ },
+ );
+ });
+
+ describe('without storage types', () => {
+ beforeEach(() => {
+ createComponent({ storageTypes: [] });
+ });
+
+ it('should render the table header <th>', () => {
+ expect(findTable().find('th').exists()).toBe(true);
+ });
+
+ it('should not render any table data <td>', () => {
+ expect(findTable().find('td').exists()).toBe(false);
+ });
+ });
+});
diff --git a/spec/frontend/projects/storage_counter/mock_data.js b/spec/frontend/projects/storage_counter/mock_data.js
new file mode 100644
index 00000000000..b9fa68b3ec7
--- /dev/null
+++ b/spec/frontend/projects/storage_counter/mock_data.js
@@ -0,0 +1,109 @@
+export const mockGetProjectStorageCountGraphQLResponse = {
+ data: {
+ project: {
+ id: 'gid://gitlab/Project/20',
+ statistics: {
+ buildArtifactsSize: 400000.0,
+ pipelineArtifactsSize: 25000.0,
+ lfsObjectsSize: 4800000.0,
+ packagesSize: 3800000.0,
+ repositorySize: 3900000.0,
+ snippetsSize: 1200000.0,
+ storageSize: 15300000.0,
+ uploadsSize: 900000.0,
+ wikiSize: 300000.0,
+ __typename: 'ProjectStatistics',
+ },
+ __typename: 'Project',
+ },
+ },
+};
+
+export const mockEmptyResponse = { data: { project: null } };
+
+export const defaultProvideValues = {
+ projectPath: '/project-path',
+ helpLinks: {
+ usageQuotasHelpPagePath: '/usage-quotas',
+ buildArtifactsHelpPagePath: '/build-artifacts',
+ lfsObjectsHelpPagePath: '/lsf-objects',
+ packagesHelpPagePath: '/packages',
+ repositoryHelpPagePath: '/repository',
+ snippetsHelpPagePath: '/snippets',
+ uploadsHelpPagePath: '/uploads',
+ wikiHelpPagePath: '/wiki',
+ },
+};
+
+export const projectData = {
+ storage: {
+ totalUsage: '14.6 MiB',
+ storageTypes: [
+ {
+ storageType: {
+ id: 'buildArtifactsSize',
+ name: 'Artifacts',
+ description: 'Pipeline artifacts and job artifacts, created with CI/CD.',
+ warningMessage:
+ 'There is a known issue with Artifact storage where the total could be incorrect for some projects. More details and progress are available in %{warningLinkStart}the epic%{warningLinkEnd}.',
+ helpPath: '/build-artifacts',
+ },
+ value: 400000,
+ },
+ {
+ storageType: {
+ id: 'lfsObjectsSize',
+ name: 'LFS Storage',
+ description: 'Audio samples, videos, datasets, and graphics.',
+ helpPath: '/lsf-objects',
+ },
+ value: 4800000,
+ },
+ {
+ storageType: {
+ id: 'packagesSize',
+ name: 'Packages',
+ description: 'Code packages and container images.',
+ helpPath: '/packages',
+ },
+ value: 3800000,
+ },
+ {
+ storageType: {
+ id: 'repositorySize',
+ name: 'Repository',
+ description: 'Git repository, managed by the Gitaly service.',
+ helpPath: '/repository',
+ },
+ value: 3900000,
+ },
+ {
+ storageType: {
+ id: 'snippetsSize',
+ name: 'Snippets',
+ description: 'Shared bits of code and text.',
+ helpPath: '/snippets',
+ },
+ value: 1200000,
+ },
+ {
+ storageType: {
+ id: 'uploadsSize',
+ name: 'Uploads',
+ description: 'File attachments and smaller design graphics.',
+ helpPath: '/uploads',
+ },
+ value: 900000,
+ },
+ {
+ storageType: {
+ id: 'wikiSize',
+ name: 'Wiki',
+ description: 'Wiki content.',
+ helpPath: '/wiki',
+ },
+ value: 300000,
+ },
+ ],
+ },
+};
diff --git a/spec/frontend/projects/storage_counter/utils_spec.js b/spec/frontend/projects/storage_counter/utils_spec.js
new file mode 100644
index 00000000000..57c755266a0
--- /dev/null
+++ b/spec/frontend/projects/storage_counter/utils_spec.js
@@ -0,0 +1,17 @@
+import { parseGetProjectStorageResults } from '~/projects/storage_counter/utils';
+import {
+ mockGetProjectStorageCountGraphQLResponse,
+ projectData,
+ defaultProvideValues,
+} from './mock_data';
+
+describe('parseGetProjectStorageResults', () => {
+ it('parses project statistics correctly', () => {
+ expect(
+ parseGetProjectStorageResults(
+ mockGetProjectStorageCountGraphQLResponse.data,
+ defaultProvideValues.helpLinks,
+ ),
+ ).toMatchObject(projectData);
+ });
+});
diff --git a/spec/frontend/projects/terraform_notification/terraform_notification_spec.js b/spec/frontend/projects/terraform_notification/terraform_notification_spec.js
index 71c22998b08..6576ce70d60 100644
--- a/spec/frontend/projects/terraform_notification/terraform_notification_spec.js
+++ b/spec/frontend/projects/terraform_notification/terraform_notification_spec.js
@@ -1,51 +1,91 @@
import { GlBanner } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import { setCookie, parseBoolean } from '~/lib/utils/common_utils';
+import { makeMockUserCalloutDismisser } from 'helpers/mock_user_callout_dismisser';
+import { mockTracking } from 'helpers/tracking_helper';
import TerraformNotification from '~/projects/terraform_notification/components/terraform_notification.vue';
-
-jest.mock('~/lib/utils/common_utils');
+import {
+ EVENT_LABEL,
+ DISMISS_EVENT,
+ CLICK_EVENT,
+} from '~/projects/terraform_notification/constants';
const terraformImagePath = '/path/to/image';
-const bannerDismissedKey = 'terraform_notification_dismissed';
describe('TerraformNotificationBanner', () => {
let wrapper;
+ let trackingSpy;
+ let userCalloutDismissSpy;
const provideData = {
terraformImagePath,
- bannerDismissedKey,
};
const findBanner = () => wrapper.findComponent(GlBanner);
- beforeEach(() => {
+ const createComponent = ({ shouldShowCallout = true } = {}) => {
+ userCalloutDismissSpy = jest.fn();
+
wrapper = shallowMount(TerraformNotification, {
provide: provideData,
- stubs: { GlBanner },
+ stubs: {
+ GlBanner,
+ UserCalloutDismisser: makeMockUserCalloutDismisser({
+ dismiss: userCalloutDismissSpy,
+ shouldShowCallout,
+ }),
+ },
});
+ };
+
+ beforeEach(() => {
+ createComponent();
+ trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
});
afterEach(() => {
wrapper.destroy();
- parseBoolean.mockReturnValue(false);
});
- describe('when the dismiss cookie is not set', () => {
+ describe('when user has already dismissed the banner', () => {
+ beforeEach(() => {
+ createComponent({
+ shouldShowCallout: false,
+ });
+ });
+ it('should not render the banner', () => {
+ expect(findBanner().exists()).toBe(false);
+ });
+ });
+
+ describe("when user hasn't yet dismissed the banner", () => {
it('should render the banner', () => {
expect(findBanner().exists()).toBe(true);
});
});
describe('when close button is clicked', () => {
- beforeEach(async () => {
- await findBanner().vm.$emit('close');
+ beforeEach(() => {
+ wrapper.vm.$refs.calloutDismisser.dismiss = userCalloutDismissSpy;
+ findBanner().vm.$emit('close');
+ });
+ it('should send the dismiss event', () => {
+ expect(trackingSpy).toHaveBeenCalledWith(undefined, DISMISS_EVENT, {
+ label: EVENT_LABEL,
+ });
});
+ it('should call the dismiss callback', () => {
+ expect(userCalloutDismissSpy).toHaveBeenCalledTimes(1);
+ });
+ });
- it('should set the cookie with the bannerDismissedKey', () => {
- expect(setCookie).toHaveBeenCalledWith(bannerDismissedKey, true);
+ describe('when docs link is clicked', () => {
+ beforeEach(() => {
+ findBanner().vm.$emit('primary');
});
- it('should remove the banner', () => {
- expect(findBanner().exists()).toBe(false);
+ it('should send button click event', () => {
+ expect(trackingSpy).toHaveBeenCalledWith(undefined, CLICK_EVENT, {
+ label: EVENT_LABEL,
+ });
});
});
});
diff --git a/spec/frontend/repository/components/blob_content_viewer_spec.js b/spec/frontend/repository/components/blob_content_viewer_spec.js
index d462995328b..8331adcdfc2 100644
--- a/spec/frontend/repository/components/blob_content_viewer_spec.js
+++ b/spec/frontend/repository/components/blob_content_viewer_spec.js
@@ -375,6 +375,30 @@ describe('Blob content viewer component', () => {
expect(findBlobHeader().props('isBinary')).toBe(true);
},
);
+
+ it('passes the correct header props when viewing a non-text file', async () => {
+ fullFactory({
+ mockData: {
+ blobInfo: {
+ ...simpleMockData,
+ simpleViewer: {
+ ...simpleMockData.simpleViewer,
+ fileType: 'image',
+ },
+ },
+ },
+ stubs: {
+ BlobContent: true,
+ BlobReplace: true,
+ },
+ });
+
+ await nextTick();
+
+ expect(findBlobHeader().props('hideViewerSwitcher')).toBe(true);
+ expect(findBlobHeader().props('isBinary')).toBe(true);
+ expect(findBlobEdit().props('showEditButton')).toBe(false);
+ });
});
describe('BlobButtonGroup', () => {
diff --git a/spec/frontend/repository/components/blob_viewers/image_viewer_spec.js b/spec/frontend/repository/components/blob_viewers/image_viewer_spec.js
new file mode 100644
index 00000000000..6735dddf51e
--- /dev/null
+++ b/spec/frontend/repository/components/blob_viewers/image_viewer_spec.js
@@ -0,0 +1,25 @@
+import { shallowMount } from '@vue/test-utils';
+import ImageViewer from '~/repository/components/blob_viewers/image_viewer.vue';
+
+describe('Image Viewer', () => {
+ let wrapper;
+
+ const propsData = {
+ url: 'some/image.png',
+ alt: 'image.png',
+ };
+
+ const createComponent = () => {
+ wrapper = shallowMount(ImageViewer, { propsData });
+ };
+
+ const findImage = () => wrapper.find('[data-testid="image"]');
+
+ it('renders a Source Editor component', () => {
+ createComponent();
+
+ expect(findImage().exists()).toBe(true);
+ expect(findImage().attributes('src')).toBe(propsData.url);
+ expect(findImage().attributes('alt')).toBe(propsData.alt);
+ });
+});
diff --git a/spec/frontend/repository/components/tree_content_spec.js b/spec/frontend/repository/components/tree_content_spec.js
index 1d1ec58100f..e36287eff29 100644
--- a/spec/frontend/repository/components/tree_content_spec.js
+++ b/spec/frontend/repository/components/tree_content_spec.js
@@ -1,5 +1,5 @@
import { shallowMount } from '@vue/test-utils';
-import filesQuery from 'shared_queries/repository/files.query.graphql';
+import paginatedTreeQuery from 'shared_queries/repository/paginated_tree.query.graphql';
import FilePreview from '~/repository/components/preview/index.vue';
import FileTable from '~/repository/components/table/index.vue';
import TreeContent from '~/repository/components/tree_content.vue';
@@ -22,6 +22,7 @@ function factory(path, data = () => ({})) {
provide: {
glFeatures: {
increasePageSizeExponentially: true,
+ paginatedTreeGraphqlQuery: true,
},
},
});
@@ -58,7 +59,7 @@ describe('Repository table component', () => {
it('normalizes edge nodes', () => {
factory('/');
- const output = vm.vm.normalizeData('blobs', [{ node: '1' }, { node: '2' }]);
+ const output = vm.vm.normalizeData('blobs', { nodes: ['1', '2'] });
expect(output).toEqual(['1', '2']);
});
@@ -168,7 +169,7 @@ describe('Repository table component', () => {
vm.vm.fetchFiles();
expect($apollo.query).toHaveBeenCalledWith({
- query: filesQuery,
+ query: paginatedTreeQuery,
variables: {
pageSize,
nextPageCursor: '',
diff --git a/spec/frontend/runner/admin_runners/admin_runners_app_spec.js b/spec/frontend/runner/admin_runners/admin_runners_app_spec.js
index c1596711be7..3292f635f6b 100644
--- a/spec/frontend/runner/admin_runners/admin_runners_app_spec.js
+++ b/spec/frontend/runner/admin_runners/admin_runners_app_spec.js
@@ -2,6 +2,7 @@ import { createLocalVue, mount, shallowMount } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import setWindowLocation from 'helpers/set_window_location_helper';
+import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import createFlash from '~/flash';
import { updateHistory } from '~/lib/utils/url_utility';
@@ -14,16 +15,20 @@ import RunnerPagination from '~/runner/components/runner_pagination.vue';
import RunnerTypeHelp from '~/runner/components/runner_type_help.vue';
import {
+ ADMIN_FILTERED_SEARCH_NAMESPACE,
CREATED_ASC,
CREATED_DESC,
DEFAULT_SORT,
INSTANCE_TYPE,
PARAM_KEY_STATUS,
+ PARAM_KEY_RUNNER_TYPE,
+ PARAM_KEY_TAG,
STATUS_ACTIVE,
RUNNER_PAGE_SIZE,
} from '~/runner/constants';
import getRunnersQuery from '~/runner/graphql/get_runners.query.graphql';
import { captureException } from '~/runner/sentry_utils';
+import FilteredSearch from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
import { runnersData, runnersDataPaginated } from '../mock_data';
@@ -47,10 +52,14 @@ describe('AdminRunnersApp', () => {
const findRunnerTypeHelp = () => wrapper.findComponent(RunnerTypeHelp);
const findRunnerManualSetupHelp = () => wrapper.findComponent(RunnerManualSetupHelp);
const findRunnerList = () => wrapper.findComponent(RunnerList);
- const findRunnerPagination = () => wrapper.findComponent(RunnerPagination);
+ const findRunnerPagination = () => extendedWrapper(wrapper.findComponent(RunnerPagination));
+ const findRunnerPaginationPrev = () =>
+ findRunnerPagination().findByLabelText('Go to previous page');
+ const findRunnerPaginationNext = () => findRunnerPagination().findByLabelText('Go to next page');
const findRunnerFilteredSearchBar = () => wrapper.findComponent(RunnerFilteredSearchBar);
+ const findFilteredSearch = () => wrapper.findComponent(FilteredSearch);
- const createComponentWithApollo = ({ props = {}, mountFn = shallowMount } = {}) => {
+ const createComponent = ({ props = {}, mountFn = shallowMount } = {}) => {
const handlers = [[getRunnersQuery, mockRunnersQuery]];
wrapper = mountFn(AdminRunnersApp, {
@@ -68,7 +77,7 @@ describe('AdminRunnersApp', () => {
setWindowLocation('/admin/runners');
mockRunnersQuery = jest.fn().mockResolvedValue(runnersData);
- createComponentWithApollo();
+ createComponent();
await waitForPromises();
});
@@ -77,8 +86,16 @@ describe('AdminRunnersApp', () => {
wrapper.destroy();
});
+ it('shows the runner type help', () => {
+ expect(findRunnerTypeHelp().exists()).toBe(true);
+ });
+
+ it('shows the runner setup instructions', () => {
+ expect(findRunnerManualSetupHelp().props('registrationToken')).toBe(mockRegistrationToken);
+ });
+
it('shows the runners list', () => {
- expect(runnersData.data.runners.nodes).toMatchObject(findRunnerList().props('runners'));
+ expect(findRunnerList().props('runners')).toEqual(runnersData.data.runners.nodes);
});
it('requests the runners with no filters', () => {
@@ -90,20 +107,38 @@ describe('AdminRunnersApp', () => {
});
});
- it('shows the runner type help', () => {
- expect(findRunnerTypeHelp().exists()).toBe(true);
+ it('sets tokens in the filtered search', () => {
+ createComponent({ mountFn: mount });
+
+ expect(findFilteredSearch().props('tokens')).toEqual([
+ expect.objectContaining({
+ type: PARAM_KEY_STATUS,
+ options: expect.any(Array),
+ }),
+ expect.objectContaining({
+ type: PARAM_KEY_RUNNER_TYPE,
+ options: expect.any(Array),
+ }),
+ expect.objectContaining({
+ type: PARAM_KEY_TAG,
+ recentTokenValuesStorageKey: `${ADMIN_FILTERED_SEARCH_NAMESPACE}-recent-tags`,
+ }),
+ ]);
});
- it('shows the runner setup instructions', () => {
- expect(findRunnerManualSetupHelp().exists()).toBe(true);
- expect(findRunnerManualSetupHelp().props('registrationToken')).toBe(mockRegistrationToken);
+ it('shows the active runner count', () => {
+ createComponent({ mountFn: mount });
+
+ expect(findRunnerFilteredSearchBar().text()).toMatch(
+ `Runners currently online: ${mockActiveRunnersCount}`,
+ );
});
describe('when a filter is preselected', () => {
beforeEach(async () => {
setWindowLocation(`?status[]=${STATUS_ACTIVE}&runner_type[]=${INSTANCE_TYPE}&tag[]=tag1`);
- createComponentWithApollo();
+ createComponent();
await waitForPromises();
});
@@ -133,7 +168,7 @@ describe('AdminRunnersApp', () => {
describe('when a filter is selected by the user', () => {
beforeEach(() => {
findRunnerFilteredSearchBar().vm.$emit('input', {
- filters: [{ type: PARAM_KEY_STATUS, value: { data: 'ACTIVE', operator: '=' } }],
+ filters: [{ type: PARAM_KEY_STATUS, value: { data: STATUS_ACTIVE, operator: '=' } }],
sort: CREATED_ASC,
});
});
@@ -154,11 +189,19 @@ describe('AdminRunnersApp', () => {
});
});
+ it('when runners have not loaded, shows a loading state', () => {
+ createComponent();
+ expect(findRunnerList().props('loading')).toBe(true);
+ });
+
describe('when no runners are found', () => {
beforeEach(async () => {
- mockRunnersQuery = jest.fn().mockResolvedValue({ data: { runners: { nodes: [] } } });
- createComponentWithApollo();
- await waitForPromises();
+ mockRunnersQuery = jest.fn().mockResolvedValue({
+ data: {
+ runners: { nodes: [] },
+ },
+ });
+ createComponent();
});
it('shows a message for no results', async () => {
@@ -166,17 +209,14 @@ describe('AdminRunnersApp', () => {
});
});
- it('when runners have not loaded, shows a loading state', () => {
- createComponentWithApollo();
- expect(findRunnerList().props('loading')).toBe(true);
- });
-
describe('when runners query fails', () => {
- beforeEach(async () => {
+ beforeEach(() => {
mockRunnersQuery = jest.fn().mockRejectedValue(new Error('Error!'));
- createComponentWithApollo();
+ createComponent();
+ });
- await waitForPromises();
+ it('error is shown to the user', async () => {
+ expect(createFlash).toHaveBeenCalledTimes(1);
});
it('error is reported to sentry', async () => {
@@ -185,17 +225,13 @@ describe('AdminRunnersApp', () => {
component: 'AdminRunnersApp',
});
});
-
- it('error is shown to the user', async () => {
- expect(createFlash).toHaveBeenCalledTimes(1);
- });
});
describe('Pagination', () => {
beforeEach(() => {
mockRunnersQuery = jest.fn().mockResolvedValue(runnersDataPaginated);
- createComponentWithApollo({ mountFn: mount });
+ createComponent({ mountFn: mount });
});
it('more pages can be selected', () => {
@@ -203,14 +239,11 @@ describe('AdminRunnersApp', () => {
});
it('cannot navigate to the previous page', () => {
- expect(findRunnerPagination().find('[aria-disabled]').text()).toBe('Prev');
+ expect(findRunnerPaginationPrev().attributes('aria-disabled')).toBe('true');
});
it('navigates to the next page', async () => {
- const nextPageBtn = findRunnerPagination().find('a');
- expect(nextPageBtn.text()).toBe('Next');
-
- await nextPageBtn.trigger('click');
+ await findRunnerPaginationNext().trigger('click');
expect(mockRunnersQuery).toHaveBeenLastCalledWith({
sort: CREATED_DESC,
diff --git a/spec/frontend/runner/components/runner_filtered_search_bar_spec.js b/spec/frontend/runner/components/runner_filtered_search_bar_spec.js
index 85cf7ea92df..46948af1f28 100644
--- a/spec/frontend/runner/components/runner_filtered_search_bar_spec.js
+++ b/spec/frontend/runner/components/runner_filtered_search_bar_spec.js
@@ -2,8 +2,16 @@ import { GlFilteredSearch, GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import RunnerFilteredSearchBar from '~/runner/components/runner_filtered_search_bar.vue';
+import { statusTokenConfig } from '~/runner/components/search_tokens/status_token_config';
import TagToken from '~/runner/components/search_tokens/tag_token.vue';
-import { PARAM_KEY_STATUS, PARAM_KEY_RUNNER_TYPE, PARAM_KEY_TAG } from '~/runner/constants';
+import { tagTokenConfig } from '~/runner/components/search_tokens/tag_token_config';
+import { typeTokenConfig } from '~/runner/components/search_tokens/type_token_config';
+import {
+ PARAM_KEY_STATUS,
+ PARAM_KEY_RUNNER_TYPE,
+ PARAM_KEY_TAG,
+ STATUS_ACTIVE,
+} from '~/runner/constants';
import FilteredSearch from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue';
@@ -13,12 +21,12 @@ describe('RunnerList', () => {
const findFilteredSearch = () => wrapper.findComponent(FilteredSearch);
const findGlFilteredSearch = () => wrapper.findComponent(GlFilteredSearch);
const findSortOptions = () => wrapper.findAllComponents(GlDropdownItem);
- const findActiveRunnersMessage = () => wrapper.findByTestId('active-runners-message');
+ const findActiveRunnersMessage = () => wrapper.findByTestId('runner-count');
const mockDefaultSort = 'CREATED_DESC';
const mockOtherSort = 'CONTACTED_DESC';
const mockFilters = [
- { type: PARAM_KEY_STATUS, value: { data: 'ACTIVE', operator: '=' } },
+ { type: PARAM_KEY_STATUS, value: { data: STATUS_ACTIVE, operator: '=' } },
{ type: 'filtered-search-term', value: { data: '' } },
];
const mockActiveRunnersCount = 2;
@@ -28,13 +36,16 @@ describe('RunnerList', () => {
shallowMount(RunnerFilteredSearchBar, {
propsData: {
namespace: 'runners',
+ tokens: [],
value: {
filters: [],
sort: mockDefaultSort,
},
- activeRunnersCount: mockActiveRunnersCount,
...props,
},
+ slots: {
+ 'runner-count': `Runners currently online: ${mockActiveRunnersCount}`,
+ },
stubs: {
FilteredSearch,
GlFilteredSearch,
@@ -64,12 +75,6 @@ describe('RunnerList', () => {
);
});
- it('Displays a large active runner count', () => {
- createComponent({ props: { activeRunnersCount: 2000 } });
-
- expect(findActiveRunnersMessage().text()).toBe('Runners currently online: 2,000');
- });
-
it('sets sorting options', () => {
const SORT_OPTIONS_COUNT = 2;
@@ -78,7 +83,13 @@ describe('RunnerList', () => {
expect(findSortOptions().at(1).text()).toBe('Last contact');
});
- it('sets tokens', () => {
+ it('sets tokens to the filtered search', () => {
+ createComponent({
+ props: {
+ tokens: [statusTokenConfig, typeTokenConfig, tagTokenConfig],
+ },
+ });
+
expect(findFilteredSearch().props('tokens')).toEqual([
expect.objectContaining({
type: PARAM_KEY_STATUS,
diff --git a/spec/frontend/runner/components/runner_list_spec.js b/spec/frontend/runner/components/runner_list_spec.js
index 5fff3581e39..344d1e5c150 100644
--- a/spec/frontend/runner/components/runner_list_spec.js
+++ b/spec/frontend/runner/components/runner_list_spec.js
@@ -56,7 +56,7 @@ describe('RunnerList', () => {
});
it('Displays a list of runners', () => {
- expect(findRows()).toHaveLength(3);
+ expect(findRows()).toHaveLength(4);
expect(findSkeletonLoader().exists()).toBe(false);
});
diff --git a/spec/frontend/runner/components/runner_update_form_spec.js b/spec/frontend/runner/components/runner_update_form_spec.js
index 15029d7a911..0e0844a785b 100644
--- a/spec/frontend/runner/components/runner_update_form_spec.js
+++ b/spec/frontend/runner/components/runner_update_form_spec.js
@@ -54,7 +54,7 @@ describe('RunnerUpdateForm', () => {
? ACCESS_LEVEL_REF_PROTECTED
: ACCESS_LEVEL_NOT_PROTECTED,
runUntagged: findRunUntaggedCheckbox().element.checked,
- locked: findLockedCheckbox().element.checked,
+ locked: findLockedCheckbox().element?.checked || false,
ipAddress: findIpInput().element.value,
maximumTimeout: findMaxJobTimeoutInput().element.value || null,
tagList: findTagsInput().element.value.split(',').filter(Boolean),
@@ -153,15 +153,15 @@ describe('RunnerUpdateForm', () => {
});
it.each`
- runnerType | attrDisabled | outcome
- ${INSTANCE_TYPE} | ${'disabled'} | ${'disabled'}
- ${GROUP_TYPE} | ${'disabled'} | ${'disabled'}
- ${PROJECT_TYPE} | ${undefined} | ${'enabled'}
- `(`When runner is $runnerType, locked field is $outcome`, ({ runnerType, attrDisabled }) => {
+ runnerType | exists | outcome
+ ${INSTANCE_TYPE} | ${false} | ${'hidden'}
+ ${GROUP_TYPE} | ${false} | ${'hidden'}
+ ${PROJECT_TYPE} | ${true} | ${'shown'}
+ `(`When runner is $runnerType, locked field is $outcome`, ({ runnerType, exists }) => {
const runner = { ...mockRunner, runnerType };
createComponent({ props: { runner } });
- expect(findLockedCheckbox().attributes('disabled')).toBe(attrDisabled);
+ expect(findLockedCheckbox().exists()).toBe(exists);
});
describe('On submit, runner gets updated', () => {
diff --git a/spec/frontend/runner/group_runners/group_runners_app_spec.js b/spec/frontend/runner/group_runners/group_runners_app_spec.js
index 6a0863e92b4..e80da40e3bd 100644
--- a/spec/frontend/runner/group_runners/group_runners_app_spec.js
+++ b/spec/frontend/runner/group_runners/group_runners_app_spec.js
@@ -1,26 +1,85 @@
-import { shallowMount } from '@vue/test-utils';
+import { createLocalVue, shallowMount, mount } from '@vue/test-utils';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import setWindowLocation from 'helpers/set_window_location_helper';
+import { extendedWrapper } from 'helpers/vue_test_utils_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import createFlash from '~/flash';
+import { updateHistory } from '~/lib/utils/url_utility';
+
+import RunnerFilteredSearchBar from '~/runner/components/runner_filtered_search_bar.vue';
+import RunnerList from '~/runner/components/runner_list.vue';
import RunnerManualSetupHelp from '~/runner/components/runner_manual_setup_help.vue';
+import RunnerPagination from '~/runner/components/runner_pagination.vue';
import RunnerTypeHelp from '~/runner/components/runner_type_help.vue';
+
+import {
+ CREATED_ASC,
+ CREATED_DESC,
+ DEFAULT_SORT,
+ INSTANCE_TYPE,
+ PARAM_KEY_STATUS,
+ PARAM_KEY_RUNNER_TYPE,
+ STATUS_ACTIVE,
+ RUNNER_PAGE_SIZE,
+} from '~/runner/constants';
+import getGroupRunnersQuery from '~/runner/graphql/get_group_runners.query.graphql';
import GroupRunnersApp from '~/runner/group_runners/group_runners_app.vue';
+import { captureException } from '~/runner/sentry_utils';
+import FilteredSearch from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
+import { groupRunnersData, groupRunnersDataPaginated } from '../mock_data';
+
+const localVue = createLocalVue();
+localVue.use(VueApollo);
+const mockGroupFullPath = 'group1';
const mockRegistrationToken = 'AABBCC';
+const mockRunners = groupRunnersData.data.group.runners.nodes;
+const mockGroupRunnersLimitedCount = mockRunners.length;
+
+jest.mock('~/flash');
+jest.mock('~/runner/sentry_utils');
+jest.mock('~/lib/utils/url_utility', () => ({
+ ...jest.requireActual('~/lib/utils/url_utility'),
+ updateHistory: jest.fn(),
+}));
describe('GroupRunnersApp', () => {
let wrapper;
+ let mockGroupRunnersQuery;
const findRunnerTypeHelp = () => wrapper.findComponent(RunnerTypeHelp);
const findRunnerManualSetupHelp = () => wrapper.findComponent(RunnerManualSetupHelp);
+ const findRunnerList = () => wrapper.findComponent(RunnerList);
+ const findRunnerPagination = () => extendedWrapper(wrapper.findComponent(RunnerPagination));
+ const findRunnerPaginationPrev = () =>
+ findRunnerPagination().findByLabelText('Go to previous page');
+ const findRunnerPaginationNext = () => findRunnerPagination().findByLabelText('Go to next page');
+ const findRunnerFilteredSearchBar = () => wrapper.findComponent(RunnerFilteredSearchBar);
+ const findFilteredSearch = () => wrapper.findComponent(FilteredSearch);
+
+ const createComponent = ({ props = {}, mountFn = shallowMount } = {}) => {
+ const handlers = [[getGroupRunnersQuery, mockGroupRunnersQuery]];
- const createComponent = ({ mountFn = shallowMount } = {}) => {
wrapper = mountFn(GroupRunnersApp, {
+ localVue,
+ apolloProvider: createMockApollo(handlers),
propsData: {
registrationToken: mockRegistrationToken,
+ groupFullPath: mockGroupFullPath,
+ groupRunnersLimitedCount: mockGroupRunnersLimitedCount,
+ ...props,
},
});
};
- beforeEach(() => {
+ beforeEach(async () => {
+ setWindowLocation(`/groups/${mockGroupFullPath}/-/runners`);
+
+ mockGroupRunnersQuery = jest.fn().mockResolvedValue(groupRunnersData);
+
createComponent();
+ await waitForPromises();
});
it('shows the runner type help', () => {
@@ -28,7 +87,179 @@ describe('GroupRunnersApp', () => {
});
it('shows the runner setup instructions', () => {
- expect(findRunnerManualSetupHelp().exists()).toBe(true);
expect(findRunnerManualSetupHelp().props('registrationToken')).toBe(mockRegistrationToken);
});
+
+ it('shows the runners list', () => {
+ expect(findRunnerList().props('runners')).toEqual(groupRunnersData.data.group.runners.nodes);
+ });
+
+ it('requests the runners with group path and no other filters', () => {
+ expect(mockGroupRunnersQuery).toHaveBeenLastCalledWith({
+ groupFullPath: mockGroupFullPath,
+ status: undefined,
+ type: undefined,
+ sort: DEFAULT_SORT,
+ first: RUNNER_PAGE_SIZE,
+ });
+ });
+
+ it('sets tokens in the filtered search', () => {
+ createComponent({ mountFn: mount });
+
+ expect(findFilteredSearch().props('tokens')).toEqual([
+ expect.objectContaining({
+ type: PARAM_KEY_STATUS,
+ options: expect.any(Array),
+ }),
+ expect.objectContaining({
+ type: PARAM_KEY_RUNNER_TYPE,
+ options: expect.any(Array),
+ }),
+ ]);
+ });
+
+ describe('shows the active runner count', () => {
+ it('with a regular value', () => {
+ createComponent({ mountFn: mount });
+
+ expect(findRunnerFilteredSearchBar().text()).toMatch(
+ `Runners in this group: ${mockGroupRunnersLimitedCount}`,
+ );
+ });
+
+ it('at the limit', () => {
+ createComponent({ props: { groupRunnersLimitedCount: 1000 }, mountFn: mount });
+
+ expect(findRunnerFilteredSearchBar().text()).toMatch(`Runners in this group: 1,000`);
+ });
+
+ it('over the limit', () => {
+ createComponent({ props: { groupRunnersLimitedCount: 1001 }, mountFn: mount });
+
+ expect(findRunnerFilteredSearchBar().text()).toMatch(`Runners in this group: 1,000+`);
+ });
+ });
+
+ describe('when a filter is preselected', () => {
+ beforeEach(async () => {
+ setWindowLocation(`?status[]=${STATUS_ACTIVE}&runner_type[]=${INSTANCE_TYPE}`);
+
+ createComponent();
+ await waitForPromises();
+ });
+
+ it('sets the filters in the search bar', () => {
+ expect(findRunnerFilteredSearchBar().props('value')).toEqual({
+ filters: [
+ { type: 'status', value: { data: STATUS_ACTIVE, operator: '=' } },
+ { type: 'runner_type', value: { data: INSTANCE_TYPE, operator: '=' } },
+ ],
+ sort: 'CREATED_DESC',
+ pagination: { page: 1 },
+ });
+ });
+
+ it('requests the runners with filter parameters', () => {
+ expect(mockGroupRunnersQuery).toHaveBeenLastCalledWith({
+ groupFullPath: mockGroupFullPath,
+ status: STATUS_ACTIVE,
+ type: INSTANCE_TYPE,
+ sort: DEFAULT_SORT,
+ first: RUNNER_PAGE_SIZE,
+ });
+ });
+ });
+
+ describe('when a filter is selected by the user', () => {
+ beforeEach(() => {
+ findRunnerFilteredSearchBar().vm.$emit('input', {
+ filters: [{ type: PARAM_KEY_STATUS, value: { data: STATUS_ACTIVE, operator: '=' } }],
+ sort: CREATED_ASC,
+ });
+ });
+
+ it('updates the browser url', () => {
+ expect(updateHistory).toHaveBeenLastCalledWith({
+ title: expect.any(String),
+ url: 'http://test.host/groups/group1/-/runners?status[]=ACTIVE&sort=CREATED_ASC',
+ });
+ });
+
+ it('requests the runners with filters', () => {
+ expect(mockGroupRunnersQuery).toHaveBeenLastCalledWith({
+ groupFullPath: mockGroupFullPath,
+ status: STATUS_ACTIVE,
+ sort: CREATED_ASC,
+ first: RUNNER_PAGE_SIZE,
+ });
+ });
+ });
+
+ it('when runners have not loaded, shows a loading state', () => {
+ createComponent();
+ expect(findRunnerList().props('loading')).toBe(true);
+ });
+
+ describe('when no runners are found', () => {
+ beforeEach(async () => {
+ mockGroupRunnersQuery = jest.fn().mockResolvedValue({
+ data: {
+ group: {
+ runners: { nodes: [] },
+ },
+ },
+ });
+ createComponent();
+ });
+
+ it('shows a message for no results', async () => {
+ expect(wrapper.text()).toContain('No runners found');
+ });
+ });
+
+ describe('when runners query fails', () => {
+ beforeEach(() => {
+ mockGroupRunnersQuery = jest.fn().mockRejectedValue(new Error('Error!'));
+ createComponent();
+ });
+
+ it('error is shown to the user', async () => {
+ expect(createFlash).toHaveBeenCalledTimes(1);
+ });
+
+ it('error is reported to sentry', async () => {
+ expect(captureException).toHaveBeenCalledWith({
+ error: new Error('Network error: Error!'),
+ component: 'GroupRunnersApp',
+ });
+ });
+ });
+
+ describe('Pagination', () => {
+ beforeEach(() => {
+ mockGroupRunnersQuery = jest.fn().mockResolvedValue(groupRunnersDataPaginated);
+
+ createComponent({ mountFn: mount });
+ });
+
+ it('more pages can be selected', () => {
+ expect(findRunnerPagination().text()).toMatchInterpolatedText('Prev Next');
+ });
+
+ it('cannot navigate to the previous page', () => {
+ expect(findRunnerPaginationPrev().attributes('aria-disabled')).toBe('true');
+ });
+
+ it('navigates to the next page', async () => {
+ await findRunnerPaginationNext().trigger('click');
+
+ expect(mockGroupRunnersQuery).toHaveBeenLastCalledWith({
+ groupFullPath: mockGroupFullPath,
+ sort: CREATED_DESC,
+ first: RUNNER_PAGE_SIZE,
+ after: groupRunnersDataPaginated.data.group.runners.pageInfo.endCursor,
+ });
+ });
+ });
});
diff --git a/spec/frontend/runner/mock_data.js b/spec/frontend/runner/mock_data.js
index 8f551feca6e..c90b9a4c426 100644
--- a/spec/frontend/runner/mock_data.js
+++ b/spec/frontend/runner/mock_data.js
@@ -1,6 +1,14 @@
+const runnerFixture = (filename) => getJSONFixture(`graphql/runner/${filename}`);
+
// Fixtures generated by: spec/frontend/fixtures/runner.rb
-export const runnersData = getJSONFixture('graphql/runner/get_runners.query.graphql.json');
-export const runnersDataPaginated = getJSONFixture(
- 'graphql/runner/get_runners.query.graphql.paginated.json',
+
+// Admin queries
+export const runnersData = runnerFixture('get_runners.query.graphql.json');
+export const runnersDataPaginated = runnerFixture('get_runners.query.graphql.paginated.json');
+export const runnerData = runnerFixture('get_runner.query.graphql.json');
+
+// Group queries
+export const groupRunnersData = runnerFixture('get_group_runners.query.graphql.json');
+export const groupRunnersDataPaginated = runnerFixture(
+ 'get_group_runners.query.graphql.paginated.json',
);
-export const runnerData = getJSONFixture('graphql/runner/get_runner.query.graphql.json');
diff --git a/spec/frontend/search/highlight_blob_search_result_spec.js b/spec/frontend/search/highlight_blob_search_result_spec.js
index 6908bcbd283..9fa3bfc1f9a 100644
--- a/spec/frontend/search/highlight_blob_search_result_spec.js
+++ b/spec/frontend/search/highlight_blob_search_result_spec.js
@@ -9,6 +9,6 @@ describe('search/highlight_blob_search_result', () => {
it('highlights lines with search term occurrence', () => {
setHighlightClass(searchKeyword);
- expect(document.querySelectorAll('.blob-result .hll').length).toBe(4);
+ expect(document.querySelectorAll('.js-blob-result .hll').length).toBe(4);
});
});
diff --git a/spec/frontend/search/store/actions_spec.js b/spec/frontend/search/store/actions_spec.js
index 9f8c83f2873..b50248bb295 100644
--- a/spec/frontend/search/store/actions_spec.js
+++ b/spec/frontend/search/store/actions_spec.js
@@ -142,7 +142,13 @@ describe('Global Search Store Actions', () => {
actions.fetchProjects({ commit: mockCommit, state });
expect(Api.groupProjects).not.toHaveBeenCalled();
- expect(Api.projects).toHaveBeenCalled();
+ expect(Api.projects).toHaveBeenCalledWith(
+ state.query.search,
+ {
+ order_by: 'similarity',
+ },
+ expect.any(Function),
+ );
});
});
});
diff --git a/spec/frontend/search/store/utils_spec.js b/spec/frontend/search/store/utils_spec.js
index cd7f7dc3b5f..bcdad9f89dd 100644
--- a/spec/frontend/search/store/utils_spec.js
+++ b/spec/frontend/search/store/utils_spec.js
@@ -14,7 +14,7 @@ const CURRENT_TIME = new Date().getTime();
useLocalStorageSpy();
jest.mock('~/lib/utils/accessor', () => ({
- isLocalStorageAccessSafe: jest.fn().mockReturnValue(true),
+ canUseLocalStorage: jest.fn().mockReturnValue(true),
}));
describe('Global Search Store Utils', () => {
diff --git a/spec/frontend/shortcuts_spec.js b/spec/frontend/shortcuts_spec.js
index fc5eeee9687..455db325066 100644
--- a/spec/frontend/shortcuts_spec.js
+++ b/spec/frontend/shortcuts_spec.js
@@ -70,8 +70,7 @@ describe('Shortcuts', () => {
const mdShortcuts = $(this).data('md-shortcuts');
// jQuery.map() automatically unwraps arrays, so we
- // have to double wrap the array to counteract this:
- // https://stackoverflow.com/a/4875669/1063392
+ // have to double wrap the array to counteract this
return mdShortcuts ? [mdShortcuts] : undefined;
})
.get();
diff --git a/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js b/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js
index 8504684d23a..39f63b2a9f4 100644
--- a/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js
+++ b/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js
@@ -206,7 +206,7 @@ describe('Sidebar assignees widget', () => {
status: null,
},
],
- id: 1,
+ id: 'gid://gitlab/Issue/1',
},
],
]);
diff --git a/spec/frontend/sidebar/components/participants/sidebar_participants_widget_spec.js b/spec/frontend/sidebar/components/participants/sidebar_participants_widget_spec.js
index 57b9a10b23e..859e63b3df6 100644
--- a/spec/frontend/sidebar/components/participants/sidebar_participants_widget_spec.js
+++ b/spec/frontend/sidebar/components/participants/sidebar_participants_widget_spec.js
@@ -1,5 +1,5 @@
import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -45,6 +45,14 @@ describe('Sidebar Participants Widget', () => {
expect(findParticipants().props('loading')).toBe(true);
});
+ it('emits toggleSidebar event when participants child component emits toggleSidebar', async () => {
+ createComponent();
+ findParticipants().vm.$emit('toggleSidebar');
+
+ await nextTick();
+ expect(wrapper.emitted('toggleSidebar')).toEqual([[]]);
+ });
+
describe('when participants are loaded', () => {
beforeEach(() => {
createComponent({
diff --git a/spec/frontend/sidebar/sidebar_labels_spec.js b/spec/frontend/sidebar/sidebar_labels_spec.js
index ab08a1e65e2..7455f684380 100644
--- a/spec/frontend/sidebar/sidebar_labels_spec.js
+++ b/spec/frontend/sidebar/sidebar_labels_spec.js
@@ -156,7 +156,7 @@ describe('sidebar labels', () => {
variables: {
input: {
iid: defaultProps.iid,
- labelIds: [toLabelGid(27), toLabelGid(28), toLabelGid(29), toLabelGid(40)],
+ labelIds: [toLabelGid(29), toLabelGid(28), toLabelGid(27), toLabelGid(40)],
operationMode: MutationOperationMode.Replace,
projectPath: defaultProps.projectPath,
},
diff --git a/spec/frontend/sidebar/sidebar_mediator_spec.js b/spec/frontend/sidebar/sidebar_mediator_spec.js
index 019ded87093..cb84c142d55 100644
--- a/spec/frontend/sidebar/sidebar_mediator_spec.js
+++ b/spec/frontend/sidebar/sidebar_mediator_spec.js
@@ -63,8 +63,6 @@ describe('Sidebar mediator', () => {
expect(mediator.store.assignees).toEqual(mockData.assignees);
expect(mediator.store.humanTimeEstimate).toEqual(mockData.human_time_estimate);
expect(mediator.store.humanTotalTimeSpent).toEqual(mockData.human_total_time_spent);
- expect(mediator.store.participants).toEqual(mockData.participants);
- expect(mediator.store.subscribed).toEqual(mockData.subscribed);
expect(mediator.store.timeEstimate).toEqual(mockData.time_estimate);
expect(mediator.store.totalTimeSpent).toEqual(mockData.total_time_spent);
});
@@ -117,19 +115,4 @@ describe('Sidebar mediator', () => {
urlSpy.mockRestore();
});
});
-
- it('toggle subscription', () => {
- mediator.store.setSubscribedState(false);
- mock.onPost(mediatorMockData.toggleSubscriptionEndpoint).reply(200, {});
- const spy = jest
- .spyOn(mediator.service, 'toggleSubscription')
- .mockReturnValue(Promise.resolve());
-
- return mediator.toggleSubscription().then(() => {
- expect(spy).toHaveBeenCalled();
- expect(mediator.store.subscribed).toEqual(true);
-
- spy.mockRestore();
- });
- });
});
diff --git a/spec/frontend/sidebar/sidebar_store_spec.js b/spec/frontend/sidebar/sidebar_store_spec.js
index 7b73dc868b7..3930dabfcfa 100644
--- a/spec/frontend/sidebar/sidebar_store_spec.js
+++ b/spec/frontend/sidebar/sidebar_store_spec.js
@@ -16,17 +16,6 @@ const ANOTHER_ASSINEE = {
avatar_url: 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
};
-const PARTICIPANT = {
- id: 1,
- state: 'active',
- username: 'marcene',
- name: 'Allie Will',
- web_url: 'foo.com',
- avatar_url: 'gravatar.com/avatar/xxx',
-};
-
-const PARTICIPANT_LIST = [PARTICIPANT, { ...PARTICIPANT, id: 2 }, { ...PARTICIPANT, id: 3 }];
-
describe('Sidebar store', () => {
let testContext;
@@ -113,28 +102,6 @@ describe('Sidebar store', () => {
expect(testContext.store.changing).toBe(true);
});
- it('sets participants data', () => {
- expect(testContext.store.participants.length).toEqual(0);
-
- testContext.store.setParticipantsData({
- participants: PARTICIPANT_LIST,
- });
-
- expect(testContext.store.isFetching.participants).toEqual(false);
- expect(testContext.store.participants.length).toEqual(PARTICIPANT_LIST.length);
- });
-
- it('sets subcriptions data', () => {
- expect(testContext.store.subscribed).toEqual(null);
-
- testContext.store.setSubscriptionsData({
- subscribed: true,
- });
-
- expect(testContext.store.isFetching.subscriptions).toEqual(false);
- expect(testContext.store.subscribed).toEqual(true);
- });
-
it('set assigned data', () => {
const users = {
assignees: UsersMockHelper.createNumberRandomUsers(3),
@@ -147,11 +114,11 @@ describe('Sidebar store', () => {
});
it('sets fetching state', () => {
- expect(testContext.store.isFetching.participants).toEqual(true);
+ expect(testContext.store.isFetching.assignees).toEqual(true);
- testContext.store.setFetchingState('participants', false);
+ testContext.store.setFetchingState('assignees', false);
- expect(testContext.store.isFetching.participants).toEqual(false);
+ expect(testContext.store.isFetching.assignees).toEqual(false);
});
it('sets loading state', () => {
diff --git a/spec/frontend/sidebar/track_invite_members_spec.js b/spec/frontend/sidebar/track_invite_members_spec.js
index 6c96e4cfc76..5946e3320c4 100644
--- a/spec/frontend/sidebar/track_invite_members_spec.js
+++ b/spec/frontend/sidebar/track_invite_members_spec.js
@@ -10,7 +10,7 @@ describe('Track user dropdown open', () => {
document.body.innerHTML = `
<div id="dummy-wrapper-element">
<div class="js-sidebar-assignee-dropdown">
- <div class="js-invite-members-track" data-track-event="_track_event_" data-track-label="_track_label_">
+ <div class="js-invite-members-track" data-track-action="_track_event_" data-track-label="_track_label_">
</div>
</div>
</div>
diff --git a/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap b/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap
index 22e206bb483..40bc6fe6aa5 100644
--- a/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap
+++ b/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap
@@ -28,6 +28,7 @@ exports[`Snippet Description Edit component rendering matches the snapshot 1`] =
data-uploads-path=""
>
<markdown-header-stub
+ data-testid="markdownHeader"
linecontent=""
suggestionstartindex="0"
/>
diff --git a/spec/frontend/tracking_spec.js b/spec/frontend/tracking_spec.js
index a17efdd61a9..21fed51ff10 100644
--- a/spec/frontend/tracking_spec.js
+++ b/spec/frontend/tracking_spec.js
@@ -1,10 +1,15 @@
import { setHTMLFixture } from 'helpers/fixtures';
+import { TEST_HOST } from 'helpers/test_constants';
import { TRACKING_CONTEXT_SCHEMA } from '~/experimentation/constants';
-import { getExperimentData } from '~/experimentation/utils';
+import { getExperimentData, getAllExperimentContexts } from '~/experimentation/utils';
import Tracking, { initUserTracking, initDefaultTrackers } from '~/tracking';
+import { REFERRER_TTL, URLS_CACHE_STORAGE_KEY } from '~/tracking/constants';
import getStandardContext from '~/tracking/get_standard_context';
-jest.mock('~/experimentation/utils', () => ({ getExperimentData: jest.fn() }));
+jest.mock('~/experimentation/utils', () => ({
+ getExperimentData: jest.fn(),
+ getAllExperimentContexts: jest.fn(),
+}));
describe('Tracking', () => {
let standardContext;
@@ -12,9 +17,11 @@ describe('Tracking', () => {
let bindDocumentSpy;
let trackLoadEventsSpy;
let enableFormTracking;
+ let setAnonymousUrlsSpy;
beforeAll(() => {
window.gl = window.gl || {};
+ window.gl.snowplowUrls = {};
window.gl.snowplowStandardContext = {
schema: 'iglu:com.gitlab/gitlab_standard',
data: {
@@ -29,6 +36,7 @@ describe('Tracking', () => {
beforeEach(() => {
getExperimentData.mockReturnValue(undefined);
+ getAllExperimentContexts.mockReturnValue([]);
window.snowplow = window.snowplow || (() => {});
window.snowplowOptions = {
@@ -70,6 +78,7 @@ describe('Tracking', () => {
enableFormTracking = jest
.spyOn(Tracking, 'enableFormTracking')
.mockImplementation(() => null);
+ setAnonymousUrlsSpy = jest.spyOn(Tracking, 'setAnonymousUrls').mockImplementation(() => null);
});
it('should activate features based on what has been enabled', () => {
@@ -100,6 +109,36 @@ describe('Tracking', () => {
initDefaultTrackers();
expect(trackLoadEventsSpy).toHaveBeenCalled();
});
+
+ it('calls the anonymized URLs method', () => {
+ initDefaultTrackers();
+ expect(setAnonymousUrlsSpy).toHaveBeenCalled();
+ });
+
+ describe('when there are experiment contexts', () => {
+ const experimentContexts = [
+ {
+ schema: TRACKING_CONTEXT_SCHEMA,
+ data: { experiment: 'experiment1', variant: 'control' },
+ },
+ {
+ schema: TRACKING_CONTEXT_SCHEMA,
+ data: { experiment: 'experiment_two', variant: 'candidate' },
+ },
+ ];
+
+ beforeEach(() => {
+ getAllExperimentContexts.mockReturnValue(experimentContexts);
+ });
+
+ it('includes those contexts alongside the standard context', () => {
+ initDefaultTrackers();
+ expect(snowplowSpy).toHaveBeenCalledWith('trackPageView', null, [
+ standardContext,
+ ...experimentContexts,
+ ]);
+ });
+ });
});
describe('.event', () => {
@@ -266,6 +305,110 @@ describe('Tracking', () => {
});
});
+ describe('.setAnonymousUrls', () => {
+ afterEach(() => {
+ window.gl.snowplowPseudonymizedPageUrl = '';
+ localStorage.removeItem(URLS_CACHE_STORAGE_KEY);
+ });
+
+ it('does nothing if URLs are not provided', () => {
+ Tracking.setAnonymousUrls();
+
+ expect(snowplowSpy).not.toHaveBeenCalled();
+ expect(localStorage.getItem(URLS_CACHE_STORAGE_KEY)).toBe(null);
+ });
+
+ it('sets the page URL when provided and populates the cache', () => {
+ window.gl.snowplowPseudonymizedPageUrl = TEST_HOST;
+
+ Tracking.setAnonymousUrls();
+
+ expect(snowplowSpy).toHaveBeenCalledWith('setCustomUrl', TEST_HOST);
+ expect(JSON.parse(localStorage.getItem(URLS_CACHE_STORAGE_KEY))[0]).toStrictEqual({
+ url: TEST_HOST,
+ referrer: '',
+ originalUrl: window.location.href,
+ timestamp: Date.now(),
+ });
+ });
+
+ it('appends the hash/fragment to the pseudonymized URL', () => {
+ const hash = 'first-heading';
+ window.gl.snowplowPseudonymizedPageUrl = TEST_HOST;
+ window.location.hash = hash;
+
+ Tracking.setAnonymousUrls();
+
+ expect(snowplowSpy).toHaveBeenCalledWith('setCustomUrl', `${TEST_HOST}#${hash}`);
+ });
+
+ it('does not set the referrer URL by default', () => {
+ window.gl.snowplowPseudonymizedPageUrl = TEST_HOST;
+
+ Tracking.setAnonymousUrls();
+
+ expect(snowplowSpy).not.toHaveBeenCalledWith('setReferrerUrl', expect.any(String));
+ });
+
+ describe('with referrers cache', () => {
+ const testUrl = '/namespace:1/project:2/-/merge_requests/5';
+ const testOriginalUrl = '/my-namespace/my-project/-/merge_requests/';
+ const setUrlsCache = (data) =>
+ localStorage.setItem(URLS_CACHE_STORAGE_KEY, JSON.stringify(data));
+
+ beforeEach(() => {
+ window.gl.snowplowPseudonymizedPageUrl = TEST_HOST;
+ Object.defineProperty(document, 'referrer', { value: '', configurable: true });
+ });
+
+ it('does nothing if a referrer can not be found', () => {
+ setUrlsCache([
+ {
+ url: testUrl,
+ originalUrl: TEST_HOST,
+ timestamp: Date.now(),
+ },
+ ]);
+
+ Tracking.setAnonymousUrls();
+
+ expect(snowplowSpy).not.toHaveBeenCalledWith('setReferrerUrl', expect.any(String));
+ });
+
+ it('sets referrer URL from the page URL found in cache', () => {
+ Object.defineProperty(document, 'referrer', { value: testOriginalUrl });
+ setUrlsCache([
+ {
+ url: testUrl,
+ originalUrl: testOriginalUrl,
+ timestamp: Date.now(),
+ },
+ ]);
+
+ Tracking.setAnonymousUrls();
+
+ expect(snowplowSpy).toHaveBeenCalledWith('setReferrerUrl', testUrl);
+ });
+
+ it('ignores and removes old entries from the cache', () => {
+ const oldTimestamp = Date.now() - (REFERRER_TTL + 1);
+ Object.defineProperty(document, 'referrer', { value: testOriginalUrl });
+ setUrlsCache([
+ {
+ url: testUrl,
+ originalUrl: testOriginalUrl,
+ timestamp: oldTimestamp,
+ },
+ ]);
+
+ Tracking.setAnonymousUrls();
+
+ expect(snowplowSpy).not.toHaveBeenCalledWith('setReferrerUrl', testUrl);
+ expect(localStorage.getItem(URLS_CACHE_STORAGE_KEY)).not.toContain(oldTimestamp);
+ });
+ });
+ });
+
describe.each`
term
${'event'}
@@ -349,7 +492,7 @@ describe('Tracking', () => {
it('includes experiment data if linked to an experiment', () => {
const mockExperimentData = {
variant: 'candidate',
- experiment: 'repo_integrations_link',
+ experiment: 'example',
key: '2bff73f6bb8cc11156c50a8ba66b9b8b',
};
getExperimentData.mockReturnValue(mockExperimentData);
diff --git a/spec/frontend/vue_mr_widget/components/states/__snapshots__/new_ready_to_merge_spec.js.snap b/spec/frontend/vue_mr_widget/components/states/__snapshots__/new_ready_to_merge_spec.js.snap
new file mode 100644
index 00000000000..a6c36764c41
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/states/__snapshots__/new_ready_to_merge_spec.js.snap
@@ -0,0 +1,37 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`New ready to merge state component renders permission text if canMerge (false) is false 1`] = `
+<div
+ class="mr-widget-body media"
+>
+ <status-icon-stub
+ status="success"
+ />
+
+ <p
+ class="media-body gl-m-0! gl-font-weight-bold"
+ >
+
+ Ready to merge by members who can write to the target branch.
+
+ </p>
+</div>
+`;
+
+exports[`New ready to merge state component renders permission text if canMerge (true) is false 1`] = `
+<div
+ class="mr-widget-body media"
+>
+ <status-icon-stub
+ status="success"
+ />
+
+ <p
+ class="media-body gl-m-0! gl-font-weight-bold"
+ >
+
+ Ready to merge!
+
+ </p>
+</div>
+`;
diff --git a/spec/frontend/vue_mr_widget/components/states/merge_checks_failed_spec.js b/spec/frontend/vue_mr_widget/components/states/merge_checks_failed_spec.js
new file mode 100644
index 00000000000..bdad0bada5f
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/states/merge_checks_failed_spec.js
@@ -0,0 +1,49 @@
+import { shallowMount } from '@vue/test-utils';
+import MergeChecksFailed from '~/vue_merge_request_widget/components/states/merge_checks_failed.vue';
+
+let wrapper;
+
+function factory(propsData = {}) {
+ wrapper = shallowMount(MergeChecksFailed, {
+ propsData,
+ });
+}
+
+describe('Merge request widget merge checks failed state component', () => {
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it.each`
+ mrState | displayText
+ ${{ isPipelineFailed: true }} | ${'pipelineFailed'}
+ ${{ approvals: true, isApproved: false }} | ${'approvalNeeded'}
+ ${{ hasMergeableDiscussionsState: true }} | ${'unresolvedDiscussions'}
+ `('display $displayText text for $mrState', ({ mrState, displayText }) => {
+ factory({ mr: mrState });
+
+ expect(wrapper.text()).toContain(MergeChecksFailed.i18n[displayText]);
+ });
+
+ describe('unresolved discussions', () => {
+ it('renders jump to button', () => {
+ factory({ mr: { hasMergeableDiscussionsState: true } });
+
+ expect(wrapper.find('[data-testid="jumpToUnresolved"]').exists()).toBe(true);
+ });
+
+ it('renders resolve thread button', () => {
+ factory({
+ mr: {
+ hasMergeableDiscussionsState: true,
+ createIssueToResolveDiscussionsPath: 'https://gitlab.com',
+ },
+ });
+
+ expect(wrapper.find('[data-testid="resolveIssue"]').exists()).toBe(true);
+ expect(wrapper.find('[data-testid="resolveIssue"]').attributes('href')).toBe(
+ 'https://gitlab.com',
+ );
+ });
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_unresolved_discussions_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_unresolved_discussions_spec.js
index c6bfca4516f..e2d79c61b9b 100644
--- a/spec/frontend/vue_mr_widget/components/states/mr_widget_unresolved_discussions_spec.js
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_unresolved_discussions_spec.js
@@ -45,7 +45,7 @@ describe('UnresolvedDiscussions', () => {
expect(wrapper.element.innerText).toContain(`Merge blocked: all threads must be resolved.`);
expect(wrapper.element.innerText).toContain('Jump to first unresolved thread');
- expect(wrapper.element.innerText).toContain('Resolve all threads in new issue');
+ expect(wrapper.element.innerText).toContain('Create issue to resolve all threads');
expect(wrapper.element.querySelector('.js-create-issue').getAttribute('href')).toEqual(
TEST_HOST,
);
@@ -57,7 +57,7 @@ describe('UnresolvedDiscussions', () => {
expect(wrapper.element.innerText).toContain(`Merge blocked: all threads must be resolved.`);
expect(wrapper.element.innerText).toContain('Jump to first unresolved thread');
- expect(wrapper.element.innerText).not.toContain('Resolve all threads in new issue');
+ expect(wrapper.element.innerText).not.toContain('Create issue to resolve all threads');
expect(wrapper.element.querySelector('.js-create-issue')).toEqual(null);
});
});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_wip_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_wip_spec.js
index 0609086997b..61e44140efc 100644
--- a/spec/frontend/vue_mr_widget/components/states/mr_widget_wip_spec.js
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_wip_spec.js
@@ -64,7 +64,7 @@ describe('Wip', () => {
expect(vm.isMakingRequest).toBeTruthy();
expect(eventHub.$emit).toHaveBeenCalledWith('UpdateWidgetData', mrObj);
expect(createFlash).toHaveBeenCalledWith({
- message: 'The merge request can now be merged.',
+ message: 'Marked as ready. Merging is now allowed.',
type: 'notice',
});
done();
diff --git a/spec/frontend/vue_mr_widget/components/states/new_ready_to_merge_spec.js b/spec/frontend/vue_mr_widget/components/states/new_ready_to_merge_spec.js
new file mode 100644
index 00000000000..5ec9654a4af
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/states/new_ready_to_merge_spec.js
@@ -0,0 +1,31 @@
+import { shallowMount } from '@vue/test-utils';
+import ReadyToMerge from '~/vue_merge_request_widget/components/states/new_ready_to_merge.vue';
+
+let wrapper;
+
+function factory({ canMerge }) {
+ wrapper = shallowMount(ReadyToMerge, {
+ propsData: {
+ mr: {},
+ },
+ data() {
+ return { canMerge };
+ },
+ });
+}
+
+describe('New ready to merge state component', () => {
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it.each`
+ canMerge
+ ${true}
+ ${false}
+ `('renders permission text if canMerge ($canMerge) is false', ({ canMerge }) => {
+ factory({ canMerge });
+
+ expect(wrapper.element).toMatchSnapshot();
+ });
+});
diff --git a/spec/frontend/vue_shared/components/__snapshots__/clone_dropdown_spec.js.snap b/spec/frontend/vue_shared/components/__snapshots__/clone_dropdown_spec.js.snap
index bab928318ce..c7758b0faef 100644
--- a/spec/frontend/vue_shared/components/__snapshots__/clone_dropdown_spec.js.snap
+++ b/spec/frontend/vue_shared/components/__snapshots__/clone_dropdown_spec.js.snap
@@ -3,9 +3,13 @@
exports[`Clone Dropdown Button rendering matches the snapshot 1`] = `
<gl-dropdown-stub
category="primary"
+ clearalltext="Clear all"
headertext=""
hideheaderborder="true"
+ highlighteditemstitle="Selected"
+ highlighteditemstitleclass="gl-px-5"
right="true"
+ showhighlighteditemstitle="true"
size="medium"
text="Clone"
variant="info"
diff --git a/spec/frontend/vue_shared/components/__snapshots__/code_block_spec.js.snap b/spec/frontend/vue_shared/components/__snapshots__/code_block_spec.js.snap
index db174346729..7f655d67ae8 100644
--- a/spec/frontend/vue_shared/components/__snapshots__/code_block_spec.js.snap
+++ b/spec/frontend/vue_shared/components/__snapshots__/code_block_spec.js.snap
@@ -2,7 +2,7 @@
exports[`Code Block with default props renders correctly 1`] = `
<pre
- class="code-block rounded"
+ class="code-block rounded code"
>
<code
class="d-block"
@@ -14,7 +14,7 @@ exports[`Code Block with default props renders correctly 1`] = `
exports[`Code Block with maxHeight set to "200px" renders correctly 1`] = `
<pre
- class="code-block rounded"
+ class="code-block rounded code"
style="max-height: 200px; overflow-y: auto;"
>
<code
diff --git a/spec/frontend/vue_shared/components/__snapshots__/memory_graph_spec.js.snap b/spec/frontend/vue_shared/components/__snapshots__/memory_graph_spec.js.snap
index f4f9cc288f9..87eaabf4e98 100644
--- a/spec/frontend/vue_shared/components/__snapshots__/memory_graph_spec.js.snap
+++ b/spec/frontend/vue_shared/components/__snapshots__/memory_graph_spec.js.snap
@@ -9,7 +9,6 @@ exports[`MemoryGraph Render chart should draw container with chart 1`] = `
data="Nov 12 2019 19:17:33,2.87,Nov 12 2019 19:18:33,2.78,Nov 12 2019 19:19:33,2.78,Nov 12 2019 19:20:33,3.01"
height="25"
tooltiplabel="MB"
- variant="gray900"
/>
</div>
`;
diff --git a/spec/frontend/vue_shared/components/__snapshots__/split_button_spec.js.snap b/spec/frontend/vue_shared/components/__snapshots__/split_button_spec.js.snap
index c4f351eb58d..f2ff12b2acd 100644
--- a/spec/frontend/vue_shared/components/__snapshots__/split_button_spec.js.snap
+++ b/spec/frontend/vue_shared/components/__snapshots__/split_button_spec.js.snap
@@ -3,9 +3,13 @@
exports[`SplitButton renders actionItems 1`] = `
<gl-dropdown-stub
category="primary"
+ clearalltext="Clear all"
headertext=""
hideheaderborder="true"
+ highlighteditemstitle="Selected"
+ highlighteditemstitleclass="gl-px-5"
menu-class=""
+ showhighlighteditemstitle="true"
size="medium"
split="true"
text="professor"
diff --git a/spec/frontend/vue_shared/components/commit_spec.js b/spec/frontend/vue_shared/components/commit_spec.js
index 6a31742141b..d91853e7b79 100644
--- a/spec/frontend/vue_shared/components/commit_spec.js
+++ b/spec/frontend/vue_shared/components/commit_spec.js
@@ -162,8 +162,6 @@ describe('Commit component', () => {
expect(refEl.attributes('href')).toBe(props.commitRef.ref_url);
- expect(refEl.attributes('title')).toBe(props.commitRef.name);
-
expect(findIcon('branch').exists()).toBe(true);
});
});
@@ -195,8 +193,6 @@ describe('Commit component', () => {
expect(refEl.attributes('href')).toBe(props.mergeRequestRef.path);
- expect(refEl.attributes('title')).toBe(props.mergeRequestRef.title);
-
expect(findIcon('git-merge').exists()).toBe(true);
});
});
diff --git a/spec/frontend/vue_shared/components/diff_stats_dropdown_spec.js b/spec/frontend/vue_shared/components/diff_stats_dropdown_spec.js
new file mode 100644
index 00000000000..04f63b4bd45
--- /dev/null
+++ b/spec/frontend/vue_shared/components/diff_stats_dropdown_spec.js
@@ -0,0 +1,176 @@
+import {
+ GlSprintf,
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownText,
+ GlSearchBoxByType,
+} from '@gitlab/ui';
+import fuzzaldrinPlus from 'fuzzaldrin-plus';
+import { nextTick } from 'vue';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import DiffStatsDropdown, { i18n } from '~/vue_shared/components/diff_stats_dropdown.vue';
+
+jest.mock('fuzzaldrin-plus', () => ({
+ filter: jest.fn().mockReturnValue([]),
+}));
+
+const mockFiles = [
+ {
+ added: 0,
+ href: '#a5cc2925ca8258af241be7e5b0381edf30266302',
+ icon: 'file-modified',
+ iconColor: '',
+ name: '',
+ path: '.gitignore',
+ removed: 3,
+ title: '.gitignore',
+ },
+ {
+ added: 1,
+ href: '#fa288d1472d29beccb489a676f68739ad365fc47',
+ icon: 'file-modified',
+ iconColor: 'danger',
+ name: 'package-lock.json',
+ path: 'lock/file/path',
+ removed: 1,
+ },
+];
+
+describe('Diff Stats Dropdown', () => {
+ let wrapper;
+
+ const createComponent = ({ changed = 0, added = 0, deleted = 0, files = [] } = {}) => {
+ wrapper = shallowMountExtended(DiffStatsDropdown, {
+ propsData: {
+ changed,
+ added,
+ deleted,
+ files,
+ },
+ stubs: {
+ GlSprintf,
+ GlDropdown,
+ },
+ });
+ };
+
+ const findChanged = () => wrapper.findComponent(GlDropdown);
+ const findChangedFiles = () => findChanged().findAllComponents(GlDropdownItem);
+ const findNoFilesText = () => findChanged().findComponent(GlDropdownText);
+ const findCollapsed = () => wrapper.findByTestId('diff-stats-additions-deletions-expanded');
+ const findExpanded = () => wrapper.findByTestId('diff-stats-additions-deletions-collapsed');
+ const findSearchBox = () => wrapper.findComponent(GlSearchBoxByType);
+
+ describe('file item', () => {
+ beforeEach(() => {
+ createComponent({ files: mockFiles });
+ });
+
+ it('when no file name provided ', () => {
+ expect(findChangedFiles().at(0).text()).toContain(i18n.noFileNameAvailable);
+ });
+
+ it('when all file data is available', () => {
+ const fileData = findChangedFiles().at(1);
+ const fileText = findChangedFiles().at(1).text();
+ expect(fileText).toContain(mockFiles[1].name);
+ expect(fileText).toContain(mockFiles[1].path);
+ expect(fileData.props()).toMatchObject({
+ iconName: mockFiles[1].icon,
+ iconColor: mockFiles[1].iconColor,
+ });
+ });
+
+ it('when no files changed', () => {
+ createComponent({ files: [] });
+ expect(findNoFilesText().text()).toContain(i18n.noFilesFound);
+ });
+ });
+
+ describe.each`
+ changed | added | deleted | expectedDropdownHeader | expectedAddedDeletedExpanded | expectedAddedDeletedCollapsed
+ ${0} | ${0} | ${0} | ${'0 changed files'} | ${'+0 -0'} | ${'with 0 additions and 0 deletions'}
+ ${2} | ${0} | ${2} | ${'2 changed files'} | ${'+0 -2'} | ${'with 0 additions and 2 deletions'}
+ ${2} | ${2} | ${0} | ${'2 changed files'} | ${'+2 -0'} | ${'with 2 additions and 0 deletions'}
+ ${2} | ${1} | ${1} | ${'2 changed files'} | ${'+1 -1'} | ${'with 1 addition and 1 deletion'}
+ ${1} | ${0} | ${1} | ${'1 changed file'} | ${'+0 -1'} | ${'with 0 additions and 1 deletion'}
+ ${1} | ${1} | ${0} | ${'1 changed file'} | ${'+1 -0'} | ${'with 1 addition and 0 deletions'}
+ ${4} | ${2} | ${2} | ${'4 changed files'} | ${'+2 -2'} | ${'with 2 additions and 2 deletions'}
+ `(
+ 'when there are $changed changed file(s), $added added and $deleted deleted file(s)',
+ ({
+ changed,
+ added,
+ deleted,
+ expectedDropdownHeader,
+ expectedAddedDeletedExpanded,
+ expectedAddedDeletedCollapsed,
+ }) => {
+ beforeAll(() => {
+ createComponent({ changed, added, deleted });
+ });
+
+ afterAll(() => {
+ wrapper.destroy();
+ });
+
+ it(`dropdown header should be '${expectedDropdownHeader}'`, () => {
+ expect(findChanged().props('text')).toBe(expectedDropdownHeader);
+ });
+
+ it(`added and deleted count in expanded section should be '${expectedAddedDeletedExpanded}'`, () => {
+ expect(findExpanded().text()).toBe(expectedAddedDeletedExpanded);
+ });
+
+ it(`added and deleted count in collapsed section should be '${expectedAddedDeletedCollapsed}'`, () => {
+ expect(findCollapsed().text()).toBe(expectedAddedDeletedCollapsed);
+ });
+ },
+ );
+
+ describe('fuzzy file search', () => {
+ beforeEach(() => {
+ createComponent({ files: mockFiles });
+ });
+
+ it('should call `fuzzaldrinPlus.filter` to search for files when the search query is NOT empty', async () => {
+ const searchStr = 'file name';
+ findSearchBox().vm.$emit('input', searchStr);
+ await nextTick();
+ expect(fuzzaldrinPlus.filter).toHaveBeenCalledWith(mockFiles, searchStr, { key: 'name' });
+ });
+
+ it('should NOT call `fuzzaldrinPlus.filter` to search for files when the search query is empty', async () => {
+ const searchStr = '';
+ findSearchBox().vm.$emit('input', searchStr);
+ await nextTick();
+ expect(fuzzaldrinPlus.filter).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('selecting file dropdown item', () => {
+ beforeEach(() => {
+ createComponent({ files: mockFiles });
+ });
+
+ it('updates the URL ', () => {
+ findChangedFiles().at(0).vm.$emit('click');
+ expect(window.location.hash).toBe(mockFiles[0].href);
+ findChangedFiles().at(1).vm.$emit('click');
+ expect(window.location.hash).toBe(mockFiles[1].href);
+ });
+ });
+
+ describe('on dropdown open', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('should set the search input focus', () => {
+ wrapper.vm.$refs.search.focusInput = jest.fn();
+ findChanged().vm.$emit('shown');
+
+ expect(wrapper.vm.$refs.search.focusInput).toHaveBeenCalled();
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_utils_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_utils_spec.js
index 1b97011bf7f..d85b6e6d115 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_utils_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_utils_spec.js
@@ -25,7 +25,7 @@ import {
const mockStorageKey = 'recent-tokens';
function setLocalStorageAvailability(isAvailable) {
- jest.spyOn(AccessorUtilities, 'isLocalStorageAccessSafe').mockReturnValue(isAvailable);
+ jest.spyOn(AccessorUtilities, 'canUseLocalStorage').mockReturnValue(isAvailable);
}
describe('Filtered Search Utils', () => {
@@ -309,7 +309,7 @@ describe('urlQueryToFilter', () => {
{
[FILTERED_SEARCH_TERM]: [{ value: 'my' }, { value: 'terms' }],
},
- { filteredSearchTermKey: 'search', legacySpacesDecode: false },
+ { filteredSearchTermKey: 'search' },
],
[
'search=my terms&foo=bar&nop=xxx',
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/milestone_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/milestone_token_spec.js
index 529844817d3..bfb593bf82d 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/milestone_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/milestone_token_spec.js
@@ -11,7 +11,10 @@ import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { sortMilestonesByDueDate } from '~/milestones/milestone_utils';
-import { DEFAULT_MILESTONES } from '~/vue_shared/components/filtered_search_bar/constants';
+import {
+ DEFAULT_MILESTONES,
+ DEFAULT_MILESTONES_GRAPHQL,
+} from '~/vue_shared/components/filtered_search_bar/constants';
import MilestoneToken from '~/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue';
import { mockMilestoneToken, mockMilestones, mockRegularMilestone } from '../mock_data';
@@ -191,5 +194,22 @@ describe('MilestoneToken', () => {
expect(suggestions.at(index).text()).toBe(milestone.text);
});
});
+
+ describe('when getActiveMilestones is called and milestones is empty', () => {
+ beforeEach(() => {
+ wrapper = createComponent({
+ active: true,
+ config: { ...mockMilestoneToken, defaultMilestones: DEFAULT_MILESTONES_GRAPHQL },
+ });
+ });
+
+ it('finds the correct value from the activeToken', () => {
+ DEFAULT_MILESTONES_GRAPHQL.forEach(({ value, title }) => {
+ const activeToken = wrapper.vm.getActiveMilestone([], value);
+
+ expect(activeToken.title).toEqual(title);
+ });
+ });
+ });
});
});
diff --git a/spec/frontend/vue_shared/components/header_ci_component_spec.js b/spec/frontend/vue_shared/components/header_ci_component_spec.js
index b54d120b55b..42f4439df51 100644
--- a/spec/frontend/vue_shared/components/header_ci_component_spec.js
+++ b/spec/frontend/vue_shared/components/header_ci_component_spec.js
@@ -16,8 +16,6 @@ describe('Header CI Component', () => {
text: 'failed',
details_path: 'path',
},
- itemName: 'job',
- itemId: 123,
time: '2017-05-08T14:57:39.781Z',
user: {
web_url: 'path',
@@ -55,17 +53,13 @@ describe('Header CI Component', () => {
describe('render', () => {
beforeEach(() => {
- createComponent();
+ createComponent({ itemName: 'Pipeline' });
});
it('should render status badge', () => {
expect(findIconBadge().exists()).toBe(true);
});
- it('should render item name and id', () => {
- expect(findHeaderItemText().text()).toBe('job #123');
- });
-
it('should render timeago date', () => {
expect(findTimeAgo().exists()).toBe(true);
});
@@ -83,9 +77,29 @@ describe('Header CI Component', () => {
});
});
+ describe('with item id', () => {
+ beforeEach(() => {
+ createComponent({ itemName: 'Pipeline', itemId: '123' });
+ });
+
+ it('should render item name and id', () => {
+ expect(findHeaderItemText().text()).toBe('Pipeline #123');
+ });
+ });
+
+ describe('without item id', () => {
+ beforeEach(() => {
+ createComponent({ itemName: 'Job build_job' });
+ });
+
+ it('should render item name', () => {
+ expect(findHeaderItemText().text()).toBe('Job build_job');
+ });
+ });
+
describe('slot', () => {
it('should render header action buttons', () => {
- createComponent({}, { slots: { default: 'Test Actions' } });
+ createComponent({ itemName: 'Job build_job' }, { slots: { default: 'Test Actions' } });
expect(findActionButtons().exists()).toBe(true);
expect(findActionButtons().text()).toBe('Test Actions');
@@ -94,7 +108,7 @@ describe('Header CI Component', () => {
describe('shouldRenderTriggeredLabel', () => {
it('should render created keyword when the shouldRenderTriggeredLabel is false', () => {
- createComponent({ shouldRenderTriggeredLabel: false });
+ createComponent({ shouldRenderTriggeredLabel: false, itemName: 'Job build_job' });
expect(wrapper.text()).toContain('created');
expect(wrapper.text()).not.toContain('triggered');
diff --git a/spec/frontend/vue_shared/components/issuable/issuable_header_warnings_spec.js b/spec/frontend/vue_shared/components/issuable/issuable_header_warnings_spec.js
index 573501233b9..ad8331afcff 100644
--- a/spec/frontend/vue_shared/components/issuable/issuable_header_warnings_spec.js
+++ b/spec/frontend/vue_shared/components/issuable/issuable_header_warnings_spec.js
@@ -1,5 +1,7 @@
-import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
+import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { createStore as createMrStore } from '~/mr_notes/stores';
import createIssueStore from '~/notes/stores';
import IssuableHeaderWarnings from '~/vue_shared/components/issuable/issuable_header_warnings.vue';
@@ -12,52 +14,53 @@ localVue.use(Vuex);
describe('IssuableHeaderWarnings', () => {
let wrapper;
- let store;
- const findConfidentialIcon = () => wrapper.find('[data-testid="confidential"]');
- const findLockedIcon = () => wrapper.find('[data-testid="locked"]');
+ const findConfidentialIcon = () => wrapper.findByTestId('confidential');
+ const findLockedIcon = () => wrapper.findByTestId('locked');
+ const findHiddenIcon = () => wrapper.findByTestId('hidden');
const renderTestMessage = (renders) => (renders ? 'renders' : 'does not render');
- const setLock = (locked) => {
- store.getters.getNoteableData.discussion_locked = locked;
- };
-
- const setConfidential = (confidential) => {
- store.getters.getNoteableData.confidential = confidential;
- };
-
- const createComponent = () => {
- wrapper = shallowMount(IssuableHeaderWarnings, { store, localVue });
+ const createComponent = ({ store, provide }) => {
+ wrapper = shallowMountExtended(IssuableHeaderWarnings, {
+ store,
+ localVue,
+ provide,
+ directives: {
+ GlTooltip: createMockDirective(),
+ },
+ });
};
afterEach(() => {
wrapper.destroy();
wrapper = null;
- store = null;
});
describe.each`
issuableType
${ISSUABLE_TYPE_ISSUE} | ${ISSUABLE_TYPE_MR}
`(`when issuableType=$issuableType`, ({ issuableType }) => {
- beforeEach(() => {
- store = issuableType === ISSUABLE_TYPE_ISSUE ? createIssueStore() : createMrStore();
- createComponent();
- });
-
describe.each`
- lockStatus | confidentialStatus
- ${true} | ${true}
- ${true} | ${false}
- ${false} | ${true}
- ${false} | ${false}
+ lockStatus | confidentialStatus | hiddenStatus
+ ${true} | ${true} | ${false}
+ ${true} | ${false} | ${false}
+ ${false} | ${true} | ${false}
+ ${false} | ${false} | ${false}
+ ${true} | ${true} | ${true}
+ ${true} | ${false} | ${true}
+ ${false} | ${true} | ${true}
+ ${false} | ${false} | ${true}
`(
- `when locked=$lockStatus and confidential=$confidentialStatus`,
- ({ lockStatus, confidentialStatus }) => {
+ `when locked=$lockStatus, confidential=$confidentialStatus, and hidden=$hiddenStatus`,
+ ({ lockStatus, confidentialStatus, hiddenStatus }) => {
+ const store = issuableType === ISSUABLE_TYPE_ISSUE ? createIssueStore() : createMrStore();
+
beforeEach(() => {
- setLock(lockStatus);
- setConfidential(confidentialStatus);
+ store.getters.getNoteableData.confidential = confidentialStatus;
+ store.getters.getNoteableData.discussion_locked = lockStatus;
+
+ createComponent({ store, provide: { hidden: hiddenStatus } });
});
it(`${renderTestMessage(lockStatus)} the locked icon`, () => {
@@ -67,6 +70,19 @@ describe('IssuableHeaderWarnings', () => {
it(`${renderTestMessage(confidentialStatus)} the confidential icon`, () => {
expect(findConfidentialIcon().exists()).toBe(confidentialStatus);
});
+
+ it(`${renderTestMessage(confidentialStatus)} the hidden icon`, () => {
+ const hiddenIcon = findHiddenIcon();
+
+ expect(hiddenIcon.exists()).toBe(hiddenStatus);
+
+ if (hiddenStatus) {
+ expect(hiddenIcon.attributes('title')).toBe(
+ 'This issue is hidden because its author has been banned',
+ );
+ expect(getBinding(hiddenIcon.element, 'gl-tooltip')).not.toBeUndefined();
+ }
+ });
},
);
});
diff --git a/spec/frontend/vue_shared/components/markdown/field_spec.js b/spec/frontend/vue_shared/components/markdown/field_spec.js
index 442032840e1..76e1a1162ad 100644
--- a/spec/frontend/vue_shared/components/markdown/field_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/field_spec.js
@@ -32,7 +32,7 @@ describe('Markdown field component', () => {
axiosMock.restore();
});
- function createSubject() {
+ function createSubject(lines = []) {
// We actually mount a wrapper component so that we can force Vue to rerender classes in order to test a regression
// caused by mixing Vanilla JS and Vue.
subject = mount(
@@ -60,6 +60,7 @@ describe('Markdown field component', () => {
markdownPreviewPath,
isSubmitting: false,
textareaValue,
+ lines,
},
},
);
@@ -243,4 +244,14 @@ describe('Markdown field component', () => {
});
});
});
+
+ describe('suggestions', () => {
+ it('escapes new line characters', () => {
+ createSubject([{ rich_text: 'hello world\\n' }]);
+
+ expect(subject.find('[data-testid="markdownHeader"]').props('lineContent')).toBe(
+ 'hello world%br',
+ );
+ });
+ });
});
diff --git a/spec/frontend/vue_shared/components/registry/title_area_spec.js b/spec/frontend/vue_shared/components/registry/title_area_spec.js
index fb0009ebb8d..75aa3bc7096 100644
--- a/spec/frontend/vue_shared/components/registry/title_area_spec.js
+++ b/spec/frontend/vue_shared/components/registry/title_area_spec.js
@@ -135,15 +135,16 @@ describe('title area', () => {
},
});
};
+
it('shows dynamic slots', async () => {
mountComponent();
// we manually add a new slot to simulate dynamic slots being evaluated after the initial mount
wrapper.vm.$slots[DYNAMIC_SLOT] = createDynamicSlot();
+ // updating the slots like we do on line 141 does not cause the updated lifecycle-hook to be triggered
+ wrapper.vm.$forceUpdate();
await wrapper.vm.$nextTick();
- expect(findDynamicSlot().exists()).toBe(false);
- await wrapper.vm.$nextTick();
expect(findDynamicSlot().exists()).toBe(true);
});
@@ -160,10 +161,8 @@ describe('title area', () => {
'metadata-foo': wrapper.vm.$slots['metadata-foo'],
};
- await wrapper.vm.$nextTick();
- expect(findDynamicSlot().exists()).toBe(false);
- expect(findMetadataSlot('metadata-foo').exists()).toBe(true);
-
+ // updating the slots like we do on line 159 does not cause the updated lifecycle-hook to be triggered
+ wrapper.vm.$forceUpdate();
await wrapper.vm.$nextTick();
expect(findSlotOrderElements().at(0).attributes('data-testid')).toBe(DYNAMIC_SLOT);
diff --git a/spec/frontend/vue_shared/components/runner_aws_deployments/runner_aws_deployments_modal_spec.js b/spec/frontend/vue_shared/components/runner_aws_deployments/runner_aws_deployments_modal_spec.js
index 69db3ec7132..ad692a38e65 100644
--- a/spec/frontend/vue_shared/components/runner_aws_deployments/runner_aws_deployments_modal_spec.js
+++ b/spec/frontend/vue_shared/components/runner_aws_deployments/runner_aws_deployments_modal_spec.js
@@ -21,6 +21,7 @@ describe('RunnerAwsDeploymentsModal', () => {
wrapper = shallowMount(RunnerAwsDeploymentsModal, {
propsData: {
modalId: 'runner-aws-deployments-modal',
+ imgSrc: '/assets/aws-cloud-formation.png',
},
});
};
diff --git a/spec/frontend/vue_shared/components/settings/__snapshots__/settings_block_spec.js.snap b/spec/frontend/vue_shared/components/settings/__snapshots__/settings_block_spec.js.snap
index ed085fb66dc..165caea2751 100644
--- a/spec/frontend/vue_shared/components/settings/__snapshots__/settings_block_spec.js.snap
+++ b/spec/frontend/vue_shared/components/settings/__snapshots__/settings_block_spec.js.snap
@@ -8,12 +8,25 @@ exports[`Settings Block renders the correct markup 1`] = `
class="settings-header"
>
<h4>
- <div
- data-testid="title-slot"
- />
+ <span
+ aria-controls="settings_content_3"
+ aria-expanded="false"
+ class="gl-cursor-pointer"
+ data-testid="section-title-button"
+ id="settings_label_2"
+ role="button"
+ tabindex="0"
+ >
+ <div
+ data-testid="title-slot"
+ />
+ </span>
</h4>
<gl-button-stub
+ aria-controls="settings_content_3"
+ aria-expanded="false"
+ aria-label="Expand settings section"
buttontextclasses=""
category="primary"
icon=""
@@ -33,7 +46,11 @@ exports[`Settings Block renders the correct markup 1`] = `
</div>
<div
+ aria-labelledby="settings_label_2"
class="settings-content"
+ id="settings_content_3"
+ role="region"
+ tabindex="-1"
>
<div
data-testid="default-slot"
diff --git a/spec/frontend/vue_shared/components/settings/settings_block_spec.js b/spec/frontend/vue_shared/components/settings/settings_block_spec.js
index be5a15631eb..528dfd89690 100644
--- a/spec/frontend/vue_shared/components/settings/settings_block_spec.js
+++ b/spec/frontend/vue_shared/components/settings/settings_block_spec.js
@@ -1,12 +1,12 @@
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import component from '~/vue_shared/components/settings/settings_block.vue';
+import SettingsBlock from '~/vue_shared/components/settings/settings_block.vue';
describe('Settings Block', () => {
let wrapper;
const mountComponent = (propsData) => {
- wrapper = shallowMount(component, {
+ wrapper = shallowMount(SettingsBlock, {
propsData,
slots: {
title: '<div data-testid="title-slot"></div>',
@@ -18,13 +18,25 @@ describe('Settings Block', () => {
afterEach(() => {
wrapper.destroy();
- wrapper = null;
});
const findDefaultSlot = () => wrapper.find('[data-testid="default-slot"]');
const findTitleSlot = () => wrapper.find('[data-testid="title-slot"]');
const findDescriptionSlot = () => wrapper.find('[data-testid="description-slot"]');
- const findExpandButton = () => wrapper.find(GlButton);
+ const findExpandButton = () => wrapper.findComponent(GlButton);
+ const findSectionTitleButton = () => wrapper.find('[data-testid="section-title-button"]');
+
+ const expectExpandedState = ({ expanded = true } = {}) => {
+ const settingsExpandButton = findExpandButton();
+
+ expect(wrapper.classes('expanded')).toBe(expanded);
+ expect(settingsExpandButton.text()).toBe(
+ expanded ? SettingsBlock.i18n.collapseText : SettingsBlock.i18n.expandText,
+ );
+ expect(settingsExpandButton.attributes('aria-label')).toBe(
+ expanded ? SettingsBlock.i18n.collapseAriaLabel : SettingsBlock.i18n.expandAriaLabel,
+ );
+ };
it('renders the correct markup', () => {
mountComponent();
@@ -75,33 +87,41 @@ describe('Settings Block', () => {
it('is collapsed by default', () => {
mountComponent();
- expect(wrapper.classes('expanded')).toBe(false);
+ expectExpandedState({ expanded: false });
});
it('adds expanded class when the expand button is clicked', async () => {
mountComponent();
- expect(wrapper.classes('expanded')).toBe(false);
- expect(findExpandButton().text()).toBe('Expand');
-
await findExpandButton().vm.$emit('click');
- expect(wrapper.classes('expanded')).toBe(true);
- expect(findExpandButton().text()).toBe('Collapse');
+ expectExpandedState({ expanded: true });
});
- it('is expanded when `defaultExpanded` is true no matter what', async () => {
- mountComponent({ defaultExpanded: true });
+ it('adds expanded class when the section title is clicked', async () => {
+ mountComponent();
- expect(wrapper.classes('expanded')).toBe(true);
+ await findSectionTitleButton().trigger('click');
- await findExpandButton().vm.$emit('click');
+ expectExpandedState({ expanded: true });
+ });
- expect(wrapper.classes('expanded')).toBe(true);
+ describe('when `collapsible` is `false`', () => {
+ beforeEach(() => {
+ mountComponent({ collapsible: false });
+ });
- await findExpandButton().vm.$emit('click');
+ it('does not render clickable section title', () => {
+ expect(findSectionTitleButton().exists()).toBe(false);
+ });
+
+ it('contains expanded class', () => {
+ expect(wrapper.classes('expanded')).toBe(true);
+ });
- expect(wrapper.classes('expanded')).toBe(true);
+ it('does not render expand toggle button', () => {
+ expect(findExpandButton().exists()).toBe(false);
+ });
});
});
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js
index a1942e59571..e39e8794fdd 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js
@@ -124,7 +124,7 @@ describe('DropdownContentsLabelsView', () => {
});
it('returns false when provided `label` param is not one of the selected labels', () => {
- expect(wrapper.vm.isLabelSelected(mockLabels[2])).toBe(false);
+ expect(wrapper.vm.isLabelSelected(mockLabels[1])).toBe(false);
});
});
@@ -203,7 +203,7 @@ describe('DropdownContentsLabelsView', () => {
it('calls action `updateSelectedLabels` with currently highlighted label when Enter key is pressed', () => {
jest.spyOn(wrapper.vm, 'updateSelectedLabels').mockImplementation();
wrapper.setData({
- currentHighlightItem: 1,
+ currentHighlightItem: 2,
});
wrapper.vm.handleKeyDown({
@@ -213,7 +213,7 @@ describe('DropdownContentsLabelsView', () => {
expect(wrapper.vm.updateSelectedLabels).toHaveBeenCalledWith([
{
- ...mockLabels[1],
+ ...mockLabels[2],
set: true,
},
]);
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_value_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_value_spec.js
index c90e63313b2..960ea77cb6e 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_value_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_value_spec.js
@@ -6,7 +6,7 @@ import DropdownValue from '~/vue_shared/components/sidebar/labels_select_vue/dro
import labelsSelectModule from '~/vue_shared/components/sidebar/labels_select_vue/store';
-import { mockConfig, mockRegularLabel, mockScopedLabel } from './mock_data';
+import { mockConfig, mockLabels, mockRegularLabel, mockScopedLabel } from './mock_data';
const localVue = createLocalVue();
localVue.use(Vuex);
@@ -14,6 +14,9 @@ localVue.use(Vuex);
describe('DropdownValue', () => {
let wrapper;
+ const findAllLabels = () => wrapper.findAllComponents(GlLabel);
+ const findLabel = (index) => findAllLabels().at(index).props('title');
+
const createComponent = (initialState = {}, slots = {}) => {
const store = new Vuex.Store(labelsSelectModule());
@@ -28,7 +31,6 @@ describe('DropdownValue', () => {
afterEach(() => {
wrapper.destroy();
- wrapper = null;
});
describe('methods', () => {
@@ -82,7 +84,17 @@ describe('DropdownValue', () => {
it('renders labels when `selectedLabels` is not empty', () => {
createComponent();
- expect(wrapper.findAll(GlLabel).length).toBe(2);
+ expect(findAllLabels()).toHaveLength(2);
+ });
+
+ it('orders scoped labels first', () => {
+ createComponent({ selectedLabels: mockLabels });
+
+ expect(findAllLabels()).toHaveLength(mockLabels.length);
+ expect(findLabel(0)).toBe('Foo::Bar');
+ expect(findLabel(1)).toBe('Boog');
+ expect(findLabel(2)).toBe('Bug');
+ expect(findLabel(3)).toBe('Foo Label');
});
});
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/mock_data.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/mock_data.js
index 730afcbecab..1faa3b0af1d 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/mock_data.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/mock_data.js
@@ -15,22 +15,22 @@ export const mockScopedLabel = {
};
export const mockLabels = [
- mockRegularLabel,
- mockScopedLabel,
{
- id: 28,
- title: 'Bug',
+ id: 29,
+ title: 'Boog',
description: 'Label for bugs',
color: '#FF0000',
textColor: '#FFFFFF',
},
{
- id: 29,
- title: 'Boog',
+ id: 28,
+ title: 'Bug',
description: 'Label for bugs',
color: '#FF0000',
textColor: '#FFFFFF',
},
+ mockRegularLabel,
+ mockScopedLabel,
];
export const mockCollapsedLabels = [
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_button_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_button_spec.js
deleted file mode 100644
index 0a42d389b67..00000000000
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_button_spec.js
+++ /dev/null
@@ -1,91 +0,0 @@
-import { GlIcon, GlButton } from '@gitlab/ui';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import Vuex from 'vuex';
-
-import DropdownButton from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_button.vue';
-
-import labelSelectModule from '~/vue_shared/components/sidebar/labels_select_widget/store';
-
-import { mockConfig } from './mock_data';
-
-let store;
-const localVue = createLocalVue();
-localVue.use(Vuex);
-
-const createComponent = (initialState = mockConfig) => {
- store = new Vuex.Store(labelSelectModule());
-
- store.dispatch('setInitialState', initialState);
-
- return shallowMount(DropdownButton, {
- localVue,
- store,
- });
-};
-
-describe('DropdownButton', () => {
- let wrapper;
-
- beforeEach(() => {
- wrapper = createComponent();
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- const findDropdownButton = () => wrapper.find(GlButton);
- const findDropdownText = () => wrapper.find('.dropdown-toggle-text');
- const findDropdownIcon = () => wrapper.find(GlIcon);
-
- describe('methods', () => {
- describe('handleButtonClick', () => {
- it.each`
- variant | expectPropagationStopped
- ${'standalone'} | ${true}
- ${'embedded'} | ${false}
- `(
- 'toggles dropdown content and handles event propagation when `state.variant` is "$variant"',
- ({ variant, expectPropagationStopped }) => {
- const event = { stopPropagation: jest.fn() };
-
- wrapper = createComponent({ ...mockConfig, variant });
-
- findDropdownButton().vm.$emit('click', event);
-
- expect(store.state.showDropdownContents).toBe(true);
- expect(event.stopPropagation).toHaveBeenCalledTimes(expectPropagationStopped ? 1 : 0);
- },
- );
- });
- });
-
- describe('template', () => {
- it('renders component container element', () => {
- expect(wrapper.find(GlButton).element).toBe(wrapper.element);
- });
-
- it('renders default button text element', () => {
- const dropdownTextEl = findDropdownText();
-
- expect(dropdownTextEl.exists()).toBe(true);
- expect(dropdownTextEl.text()).toBe('Label');
- });
-
- it('renders provided button text element', () => {
- store.state.dropdownButtonText = 'Custom label';
- const dropdownTextEl = findDropdownText();
-
- return wrapper.vm.$nextTick().then(() => {
- expect(dropdownTextEl.text()).toBe('Custom label');
- });
- });
-
- it('renders chevron icon element', () => {
- const iconEl = findDropdownIcon();
-
- expect(iconEl.exists()).toBe(true);
- expect(iconEl.props('name')).toBe('chevron-down');
- });
- });
-});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js
index 90bc1980ac3..843298a1406 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js
@@ -7,7 +7,12 @@ import waitForPromises from 'helpers/wait_for_promises';
import createFlash from '~/flash';
import DropdownContentsCreateView from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue';
import createLabelMutation from '~/vue_shared/components/sidebar/labels_select_widget/graphql/create_label.mutation.graphql';
-import { mockSuggestedColors, createLabelSuccessfulResponse } from './mock_data';
+import projectLabelsQuery from '~/vue_shared/components/sidebar/labels_select_widget/graphql/project_labels.query.graphql';
+import {
+ mockSuggestedColors,
+ createLabelSuccessfulResponse,
+ labelsQueryResponse,
+} from './mock_data';
jest.mock('~/flash');
@@ -44,6 +49,14 @@ describe('DropdownContentsCreateView', () => {
const createComponent = ({ mutationHandler = createLabelSuccessHandler } = {}) => {
const mockApollo = createMockApollo([[createLabelMutation, mutationHandler]]);
+ mockApollo.clients.defaultClient.cache.writeQuery({
+ query: projectLabelsQuery,
+ data: labelsQueryResponse.data,
+ variables: {
+ fullPath: '',
+ searchTerm: '',
+ },
+ });
wrapper = shallowMount(DropdownContentsCreateView, {
localVue,
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js
index 8bd944a3d54..537bbc8e71e 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js
@@ -45,8 +45,6 @@ describe('DropdownContentsLabelsView', () => {
provide: {
projectPath: 'test',
iid: 1,
- allowLabelCreate: true,
- labelsManagePath: '/gitlab-org/my-project/-/labels',
variant: DropdownVariant.Sidebar,
...injected,
},
@@ -69,10 +67,7 @@ describe('DropdownContentsLabelsView', () => {
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findLabelsList = () => wrapper.find('[data-testid="labels-list"]');
- const findDropdownWrapper = () => wrapper.find('[data-testid="dropdown-wrapper"]');
- const findDropdownFooter = () => wrapper.find('[data-testid="dropdown-footer"]');
const findNoResultsMessage = () => wrapper.find('[data-testid="no-results"]');
- const findCreateLabelButton = () => wrapper.find('[data-testid="create-label-button"]');
describe('when loading labels', () => {
it('renders disabled search input field', async () => {
@@ -109,40 +104,6 @@ describe('DropdownContentsLabelsView', () => {
expect(findLabelsList().exists()).toBe(true);
expect(findLabels()).toHaveLength(2);
});
-
- it('changes highlighted label correctly on pressing down button', async () => {
- expect(findLabels().at(0).attributes('highlight')).toBeUndefined();
-
- await findDropdownWrapper().trigger('keydown.down');
- expect(findLabels().at(0).attributes('highlight')).toBe('true');
-
- await findDropdownWrapper().trigger('keydown.down');
- expect(findLabels().at(1).attributes('highlight')).toBe('true');
- expect(findLabels().at(0).attributes('highlight')).toBeUndefined();
- });
-
- it('changes highlighted label correctly on pressing up button', async () => {
- await findDropdownWrapper().trigger('keydown.down');
- await findDropdownWrapper().trigger('keydown.down');
- expect(findLabels().at(1).attributes('highlight')).toBe('true');
-
- await findDropdownWrapper().trigger('keydown.up');
- expect(findLabels().at(0).attributes('highlight')).toBe('true');
- });
-
- it('changes label selected state when Enter is pressed', async () => {
- expect(findLabels().at(0).attributes('islabelset')).toBeUndefined();
- await findDropdownWrapper().trigger('keydown.down');
- await findDropdownWrapper().trigger('keydown.enter');
-
- expect(findLabels().at(0).attributes('islabelset')).toBe('true');
- });
-
- it('emits `closeDropdown event` when Esc button is pressed', () => {
- findDropdownWrapper().trigger('keydown.esc');
-
- expect(wrapper.emitted('closeDropdown')).toEqual([[selectedLabels]]);
- });
});
it('when search returns 0 results', async () => {
@@ -170,44 +131,4 @@ describe('DropdownContentsLabelsView', () => {
await waitForPromises();
expect(createFlash).toHaveBeenCalled();
});
-
- it('does not render footer on standalone dropdown', () => {
- createComponent({ injected: { variant: DropdownVariant.Standalone } });
-
- expect(findDropdownFooter().exists()).toBe(false);
- });
-
- it('renders footer on sidebar dropdown', () => {
- createComponent();
-
- expect(findDropdownFooter().exists()).toBe(true);
- });
-
- it('renders footer on embedded dropdown', () => {
- createComponent({ injected: { variant: DropdownVariant.Embedded } });
-
- expect(findDropdownFooter().exists()).toBe(true);
- });
-
- it('does not render create label button if `allowLabelCreate` is false', () => {
- createComponent({ injected: { allowLabelCreate: false } });
-
- expect(findCreateLabelButton().exists()).toBe(false);
- });
-
- describe('when `allowLabelCreate` is true', () => {
- beforeEach(() => {
- createComponent();
- });
-
- it('renders create label button', () => {
- expect(findCreateLabelButton().exists()).toBe(true);
- });
-
- it('emits `toggleDropdownContentsCreateView` event on create label button click', () => {
- findCreateLabelButton().vm.$emit('click');
-
- expect(wrapper.emitted('toggleDropdownContentsCreateView')).toEqual([[]]);
- });
- });
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js
index 3c2fd0c5acc..a1b40a891ec 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js
@@ -1,77 +1,127 @@
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import Vuex from 'vuex';
+import { GlDropdown } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
import { DropdownVariant } from '~/vue_shared/components/sidebar/labels_select_widget/constants';
import DropdownContents from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue';
-import labelsSelectModule from '~/vue_shared/components/sidebar/labels_select_widget/store';
-
-import { mockConfig, mockLabels } from './mock_data';
-
-const localVue = createLocalVue();
-localVue.use(Vuex);
-
-const createComponent = (initialState = mockConfig, defaultProps = {}) => {
- const store = new Vuex.Store(labelsSelectModule());
-
- store.dispatch('setInitialState', initialState);
-
- return shallowMount(DropdownContents, {
- propsData: {
- ...defaultProps,
- labelsCreateTitle: 'test',
- selectedLabels: mockLabels,
- allowMultiselect: true,
- labelsListTitle: 'Assign labels',
- footerCreateLabelTitle: 'create',
- footerManageLabelTitle: 'manage',
- },
- localVue,
- store,
- });
-};
+import DropdownContentsCreateView from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue';
+import DropdownContentsLabelsView from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue';
+
+import { mockLabels } from './mock_data';
describe('DropdownContent', () => {
let wrapper;
+ const createComponent = ({ props = {}, injected = {} } = {}) => {
+ wrapper = shallowMount(DropdownContents, {
+ propsData: {
+ labelsCreateTitle: 'test',
+ selectedLabels: mockLabels,
+ allowMultiselect: true,
+ labelsListTitle: 'Assign labels',
+ footerCreateLabelTitle: 'create',
+ footerManageLabelTitle: 'manage',
+ dropdownButtonText: 'Labels',
+ variant: 'sidebar',
+ ...props,
+ },
+ provide: {
+ allowLabelCreate: true,
+ labelsManagePath: 'foo/bar',
+ ...injected,
+ },
+ stubs: {
+ GlDropdown,
+ },
+ });
+ };
+
beforeEach(() => {
- wrapper = createComponent();
+ createComponent();
});
afterEach(() => {
wrapper.destroy();
});
- describe('computed', () => {
- describe('dropdownContentsView', () => {
- it('returns string "dropdown-contents-create-view" when `showDropdownContentsCreateView` prop is `true`', () => {
- wrapper.vm.$store.dispatch('toggleDropdownContentsCreateView');
+ const findDropdownFooter = () => wrapper.find('[data-testid="dropdown-footer"]');
+ const findCreateLabelButton = () => wrapper.find('[data-testid="create-label-button"]');
+ const findGoBackButton = () => wrapper.find('[data-testid="go-back-button"]');
- expect(wrapper.vm.dropdownContentsView).toBe('dropdown-contents-create-view');
- });
+ describe('Create view', () => {
+ beforeEach(() => {
+ wrapper.vm.toggleDropdownContentsCreateView();
+ });
- it('returns string "dropdown-contents-labels-view" when `showDropdownContentsCreateView` prop is `false`', () => {
- expect(wrapper.vm.dropdownContentsView).toBe('dropdown-contents-labels-view');
- });
+ it('renders create view when `showDropdownContentsCreateView` prop is `true`', () => {
+ expect(wrapper.findComponent(DropdownContentsCreateView).exists()).toBe(true);
+ });
+
+ it('does not render footer', () => {
+ expect(findDropdownFooter().exists()).toBe(false);
+ });
+
+ it('does not render create label button', () => {
+ expect(findCreateLabelButton().exists()).toBe(false);
+ });
+
+ it('renders go back button', () => {
+ expect(findGoBackButton().exists()).toBe(true);
});
});
- describe('template', () => {
- it('renders component container element with class `labels-select-dropdown-contents` and no styles', () => {
- expect(wrapper.attributes('class')).toContain('labels-select-dropdown-contents');
- expect(wrapper.attributes('style')).toBeUndefined();
+ describe('Labels view', () => {
+ it('renders labels view when `showDropdownContentsCreateView` when `showDropdownContentsCreateView` prop is `false`', () => {
+ expect(wrapper.findComponent(DropdownContentsLabelsView).exists()).toBe(true);
});
- describe('when `renderOnTop` is true', () => {
- it.each`
- variant | expected
- ${DropdownVariant.Sidebar} | ${'bottom: 3rem'}
- ${DropdownVariant.Standalone} | ${'bottom: 2rem'}
- ${DropdownVariant.Embedded} | ${'bottom: 2rem'}
- `('renders upward for $variant variant', ({ variant, expected }) => {
- wrapper = createComponent({ ...mockConfig, variant }, { renderOnTop: true });
+ it('renders footer on sidebar dropdown', () => {
+ expect(findDropdownFooter().exists()).toBe(true);
+ });
+
+ it('does not render footer on standalone dropdown', () => {
+ createComponent({ props: { variant: DropdownVariant.Standalone } });
+
+ expect(findDropdownFooter().exists()).toBe(false);
+ });
- expect(wrapper.attributes('style')).toContain(expected);
+ it('renders footer on embedded dropdown', () => {
+ createComponent({ props: { variant: DropdownVariant.Embedded } });
+
+ expect(findDropdownFooter().exists()).toBe(true);
+ });
+
+ it('does not render go back button', () => {
+ expect(findGoBackButton().exists()).toBe(false);
+ });
+
+ it('does not render create label button if `allowLabelCreate` is false', () => {
+ createComponent({ injected: { allowLabelCreate: false } });
+
+ expect(findCreateLabelButton().exists()).toBe(false);
+ });
+
+ describe('when `allowLabelCreate` is true', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('renders create label button', () => {
+ expect(findCreateLabelButton().exists()).toBe(true);
});
+
+ it('triggers `toggleDropdownContent` method on create label button click', () => {
+ jest.spyOn(wrapper.vm, 'toggleDropdownContent').mockImplementation(() => {});
+ findCreateLabelButton().trigger('click');
+
+ expect(wrapper.vm.toggleDropdownContent).toHaveBeenCalled();
+ });
+ });
+ });
+
+ describe('template', () => {
+ it('renders component container element with classes `gl-w-full gl-mt-2` and no styles', () => {
+ expect(wrapper.attributes('class')).toContain('gl-w-full gl-mt-2');
+ expect(wrapper.attributes('style')).toBeUndefined();
});
});
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_title_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_title_spec.js
deleted file mode 100644
index d2401a1f725..00000000000
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_title_spec.js
+++ /dev/null
@@ -1,61 +0,0 @@
-import { GlButton, GlLoadingIcon } from '@gitlab/ui';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import Vuex from 'vuex';
-
-import DropdownTitle from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_title.vue';
-
-import labelsSelectModule from '~/vue_shared/components/sidebar/labels_select_widget/store';
-
-import { mockConfig } from './mock_data';
-
-const localVue = createLocalVue();
-localVue.use(Vuex);
-
-const createComponent = (initialState = mockConfig) => {
- const store = new Vuex.Store(labelsSelectModule());
-
- store.dispatch('setInitialState', initialState);
-
- return shallowMount(DropdownTitle, {
- localVue,
- store,
- propsData: {
- labelsSelectInProgress: false,
- },
- });
-};
-
-describe('DropdownTitle', () => {
- let wrapper;
-
- beforeEach(() => {
- wrapper = createComponent();
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- describe('template', () => {
- it('renders component container element with string "Labels"', () => {
- expect(wrapper.text()).toContain('Labels');
- });
-
- it('renders edit link', () => {
- const editBtnEl = wrapper.find(GlButton);
-
- expect(editBtnEl.exists()).toBe(true);
- expect(editBtnEl.text()).toBe('Edit');
- });
-
- it('renders loading icon element when `labelsSelectInProgress` prop is true', () => {
- wrapper.setProps({
- labelsSelectInProgress: true,
- });
-
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.find(GlLoadingIcon).isVisible()).toBe(true);
- });
- });
- });
-});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_value_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_value_spec.js
index b3ffee2d020..e7e78cd7a33 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_value_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_value_spec.js
@@ -9,8 +9,8 @@ describe('DropdownValue', () => {
let wrapper;
const findAllLabels = () => wrapper.findAllComponents(GlLabel);
- const findRegularLabel = () => findAllLabels().at(0);
- const findScopedLabel = () => findAllLabels().at(1);
+ const findRegularLabel = () => findAllLabels().at(1);
+ const findScopedLabel = () => findAllLabels().at(0);
const findWrapper = () => wrapper.find('[data-testid="value-wrapper"]');
const findEmptyPlaceholder = () => wrapper.find('[data-testid="empty-placeholder"]');
@@ -20,11 +20,13 @@ describe('DropdownValue', () => {
propsData: {
selectedLabels: [mockRegularLabel, mockScopedLabel],
allowLabelRemove: true,
- allowScopedLabels: true,
labelsFilterBasePath: '/gitlab-org/my-project/issues',
labelsFilterParam: 'label_name',
...props,
},
+ provide: {
+ allowScopedLabels: true,
+ },
});
};
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/label_item_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/label_item_spec.js
index 23810339833..6e8841411a2 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/label_item_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/label_item_spec.js
@@ -1,4 +1,3 @@
-import { GlIcon, GlLink } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import LabelItem from '~/vue_shared/components/sidebar/labels_select_widget/label_item.vue';
@@ -6,16 +5,10 @@ import { mockRegularLabel } from './mock_data';
const mockLabel = { ...mockRegularLabel, set: true };
-const createComponent = ({
- label = mockLabel,
- isLabelSet = mockLabel.set,
- highlight = true,
-} = {}) =>
+const createComponent = ({ label = mockLabel } = {}) =>
shallowMount(LabelItem, {
propsData: {
label,
- isLabelSet,
- highlight,
},
});
@@ -31,45 +24,6 @@ describe('LabelItem', () => {
});
describe('template', () => {
- it('renders gl-link component', () => {
- expect(wrapper.find(GlLink).exists()).toBe(true);
- });
-
- it('renders component root with class `is-focused` when `highlight` prop is true', () => {
- const wrapperTemp = createComponent({
- highlight: true,
- });
-
- expect(wrapperTemp.classes()).toContain('is-focused');
-
- wrapperTemp.destroy();
- });
-
- it('renders visible gl-icon component when `isLabelSet` prop is true', () => {
- const wrapperTemp = createComponent({
- isLabelSet: true,
- });
-
- const iconEl = wrapperTemp.find(GlIcon);
-
- expect(iconEl.isVisible()).toBe(true);
- expect(iconEl.props('name')).toBe('mobile-issue-close');
-
- wrapperTemp.destroy();
- });
-
- it('renders visible span element as placeholder instead of gl-icon when `isLabelSet` prop is false', () => {
- const wrapperTemp = createComponent({
- isLabelSet: false,
- });
-
- const placeholderEl = wrapperTemp.find('[data-testid="no-icon"]');
-
- expect(placeholderEl.isVisible()).toBe(true);
-
- wrapperTemp.destroy();
- });
-
it('renders label color element', () => {
const colorEl = wrapper.find('[data-testid="label-color-box"]');
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js
index e17dfd93efc..a18511fa21d 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js
@@ -1,193 +1,74 @@
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import Vuex from 'vuex';
-
-import { isInViewport } from '~/lib/utils/common_utils';
-import { DropdownVariant } from '~/vue_shared/components/sidebar/labels_select_widget/constants';
-import DropdownButton from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_button.vue';
+import { shallowMount } from '@vue/test-utils';
+import SidebarEditableItem from '~/sidebar/components/sidebar_editable_item.vue';
import DropdownContents from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue';
-import DropdownTitle from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_title.vue';
import DropdownValue from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_value.vue';
import DropdownValueCollapsed from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_value_collapsed.vue';
import LabelsSelectRoot from '~/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue';
-import labelsSelectModule from '~/vue_shared/components/sidebar/labels_select_widget/store';
-
import { mockConfig } from './mock_data';
-jest.mock('~/lib/utils/common_utils', () => ({
- isInViewport: jest.fn().mockReturnValue(true),
-}));
-
-const localVue = createLocalVue();
-localVue.use(Vuex);
-
describe('LabelsSelectRoot', () => {
let wrapper;
- let store;
const createComponent = (config = mockConfig, slots = {}) => {
wrapper = shallowMount(LabelsSelectRoot, {
- localVue,
slots,
- store,
propsData: config,
stubs: {
- 'dropdown-contents': DropdownContents,
+ DropdownContents,
+ SidebarEditableItem,
},
provide: {
iid: '1',
projectPath: 'test',
+ canUpdate: true,
+ allowLabelEdit: true,
},
});
};
- beforeEach(() => {
- store = new Vuex.Store(labelsSelectModule());
- });
-
afterEach(() => {
wrapper.destroy();
});
- describe('methods', () => {
- describe('handleDropdownClose', () => {
- beforeEach(() => {
- createComponent();
- });
-
- it('emits `updateSelectedLabels` & `onDropdownClose` events on component when provided `labels` param is not empty', () => {
- wrapper.vm.handleDropdownClose([{ id: 1 }, { id: 2 }]);
-
- expect(wrapper.emitted().updateSelectedLabels).toBeTruthy();
- expect(wrapper.emitted().onDropdownClose).toBeTruthy();
- });
-
- it('emits only `onDropdownClose` event on component when provided `labels` param is empty', () => {
- wrapper.vm.handleDropdownClose([]);
-
- expect(wrapper.emitted().updateSelectedLabels).toBeFalsy();
- expect(wrapper.emitted().onDropdownClose).toBeTruthy();
- });
- });
-
- describe('handleCollapsedValueClick', () => {
- it('emits `toggleCollapse` event on component', () => {
- createComponent();
- wrapper.vm.handleCollapsedValueClick();
-
- expect(wrapper.emitted().toggleCollapse).toBeTruthy();
- });
- });
+ it('renders component with classes `labels-select-wrapper position-relative`', () => {
+ createComponent();
+ expect(wrapper.classes()).toEqual(['labels-select-wrapper', 'position-relative']);
});
- describe('template', () => {
- it('renders component with classes `labels-select-wrapper position-relative`', () => {
- createComponent();
- expect(wrapper.attributes('class')).toContain('labels-select-wrapper position-relative');
- });
-
- it.each`
- variant | cssClass
- ${'standalone'} | ${'is-standalone'}
- ${'embedded'} | ${'is-embedded'}
- `(
- 'renders component root element with CSS class `$cssClass` when `state.variant` is "$variant"',
- ({ variant, cssClass }) => {
- createComponent({
- ...mockConfig,
- variant,
- });
-
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.classes()).toContain(cssClass);
- });
- },
- );
-
- it('renders `dropdown-value-collapsed` component when `allowLabelCreate` prop is `true`', async () => {
- createComponent();
- await wrapper.vm.$nextTick;
- expect(wrapper.find(DropdownValueCollapsed).exists()).toBe(true);
- });
-
- it('renders `dropdown-title` component', async () => {
- createComponent();
- await wrapper.vm.$nextTick;
- expect(wrapper.find(DropdownTitle).exists()).toBe(true);
- });
-
- it('renders `dropdown-value` component', async () => {
- createComponent(mockConfig, {
- default: 'None',
+ it.each`
+ variant | cssClass
+ ${'standalone'} | ${'is-standalone'}
+ ${'embedded'} | ${'is-embedded'}
+ `(
+ 'renders component root element with CSS class `$cssClass` when `state.variant` is "$variant"',
+ ({ variant, cssClass }) => {
+ createComponent({
+ ...mockConfig,
+ variant,
});
- await wrapper.vm.$nextTick;
-
- const valueComp = wrapper.find(DropdownValue);
-
- expect(valueComp.exists()).toBe(true);
- expect(valueComp.text()).toBe('None');
- });
-
- it('renders `dropdown-button` component when `showDropdownButton` prop is `true`', async () => {
- createComponent();
- wrapper.vm.$store.dispatch('toggleDropdownButton');
- await wrapper.vm.$nextTick;
- expect(wrapper.find(DropdownButton).exists()).toBe(true);
- });
-
- it('renders `dropdown-contents` component when `showDropdownButton` & `showDropdownContents` prop is `true`', async () => {
- createComponent();
- wrapper.vm.$store.dispatch('toggleDropdownContents');
- await wrapper.vm.$nextTick;
- expect(wrapper.find(DropdownContents).exists()).toBe(true);
- });
- describe('sets content direction based on viewport', () => {
- describe.each(Object.values(DropdownVariant))(
- 'when labels variant is "%s"',
- ({ variant }) => {
- beforeEach(() => {
- createComponent({ ...mockConfig, variant });
- wrapper.vm.$store.dispatch('toggleDropdownContents');
- });
-
- it('set direction when out of viewport', () => {
- isInViewport.mockImplementation(() => false);
- wrapper.vm.setContentIsOnViewport(wrapper.vm.$store.state);
-
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.find(DropdownContents).props('renderOnTop')).toBe(true);
- });
- });
-
- it('does not set direction when inside of viewport', () => {
- isInViewport.mockImplementation(() => true);
- wrapper.vm.setContentIsOnViewport(wrapper.vm.$store.state);
-
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.find(DropdownContents).props('renderOnTop')).toBe(false);
- });
- });
- },
- );
- });
- });
+ return wrapper.vm.$nextTick(() => {
+ expect(wrapper.classes()).toContain(cssClass);
+ });
+ },
+ );
- it('calls toggleDropdownContents action when isEditing prop is changing to true', async () => {
+ it('renders `dropdown-value-collapsed` component when `allowLabelCreate` prop is `true`', async () => {
createComponent();
-
- jest.spyOn(store, 'dispatch').mockResolvedValue();
- await wrapper.setProps({ isEditing: true });
-
- expect(store.dispatch).toHaveBeenCalledWith('toggleDropdownContents');
+ await wrapper.vm.$nextTick;
+ expect(wrapper.find(DropdownValueCollapsed).exists()).toBe(true);
});
- it('does not call toggleDropdownContents action when isEditing prop is changing to false', async () => {
- createComponent();
+ it('renders `dropdown-value` component', async () => {
+ createComponent(mockConfig, {
+ default: 'None',
+ });
+ await wrapper.vm.$nextTick;
- jest.spyOn(store, 'dispatch').mockResolvedValue();
- await wrapper.setProps({ isEditing: false });
+ const valueComp = wrapper.find(DropdownValue);
- expect(store.dispatch).not.toHaveBeenCalled();
+ expect(valueComp.exists()).toBe(true);
+ expect(valueComp.text()).toBe('None');
});
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js
index 5dd8fc1b8b2..fceaabec2d0 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js
@@ -34,18 +34,12 @@ export const mockLabels = [
];
export const mockConfig = {
- allowLabelEdit: true,
- allowLabelCreate: true,
- allowScopedLabels: true,
allowMultiselect: true,
labelsListTitle: 'Assign labels',
labelsCreateTitle: 'Create label',
variant: 'sidebar',
- dropdownOnly: false,
selectedLabels: [mockRegularLabel, mockScopedLabel],
labelsSelectInProgress: false,
- labelsFetchPath: '/gitlab-org/my-project/-/labels.json',
- labelsManagePath: '/gitlab-org/my-project/-/labels',
labelsFilterBasePath: '/gitlab-org/my-project/issues',
labelsFilterParam: 'label_name',
footerCreateLabelTitle: 'create',
@@ -83,9 +77,7 @@ export const createLabelSuccessfulResponse = {
id: 'gid://gitlab/ProjectLabel/126',
color: '#dc143c',
description: null,
- descriptionHtml: '',
title: 'ewrwrwer',
- textColor: '#FFFFFF',
__typename: 'Label',
},
errors: [],
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/actions_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/actions_spec.js
deleted file mode 100644
index ee905410ffa..00000000000
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/actions_spec.js
+++ /dev/null
@@ -1,85 +0,0 @@
-import testAction from 'helpers/vuex_action_helper';
-import * as actions from '~/vue_shared/components/sidebar/labels_select_widget/store/actions';
-import * as types from '~/vue_shared/components/sidebar/labels_select_widget/store/mutation_types';
-import defaultState from '~/vue_shared/components/sidebar/labels_select_widget/store/state';
-
-jest.mock('~/flash');
-
-describe('LabelsSelect Actions', () => {
- let state;
- const mockInitialState = {
- labels: [],
- selectedLabels: [],
- };
-
- beforeEach(() => {
- state = { ...defaultState() };
- });
-
- describe('setInitialState', () => {
- it('sets initial store state', (done) => {
- testAction(
- actions.setInitialState,
- mockInitialState,
- state,
- [{ type: types.SET_INITIAL_STATE, payload: mockInitialState }],
- [],
- done,
- );
- });
- });
-
- describe('toggleDropdownButton', () => {
- it('toggles dropdown button', (done) => {
- testAction(
- actions.toggleDropdownButton,
- {},
- state,
- [{ type: types.TOGGLE_DROPDOWN_BUTTON }],
- [],
- done,
- );
- });
- });
-
- describe('toggleDropdownContents', () => {
- it('toggles dropdown contents', (done) => {
- testAction(
- actions.toggleDropdownContents,
- {},
- state,
- [{ type: types.TOGGLE_DROPDOWN_CONTENTS }],
- [],
- done,
- );
- });
- });
-
- describe('toggleDropdownContentsCreateView', () => {
- it('toggles dropdown create view', (done) => {
- testAction(
- actions.toggleDropdownContentsCreateView,
- {},
- state,
- [{ type: types.TOGGLE_DROPDOWN_CONTENTS_CREATE_VIEW }],
- [],
- done,
- );
- });
- });
-
- describe('updateSelectedLabels', () => {
- it('updates `state.labels` based on provided `labels` param', (done) => {
- const labels = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }];
-
- testAction(
- actions.updateSelectedLabels,
- labels,
- state,
- [{ type: types.UPDATE_SELECTED_LABELS, payload: { labels } }],
- [],
- done,
- );
- });
- });
-});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/getters_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/getters_spec.js
deleted file mode 100644
index 40eb0323146..00000000000
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/getters_spec.js
+++ /dev/null
@@ -1,59 +0,0 @@
-import * as getters from '~/vue_shared/components/sidebar/labels_select_widget/store/getters';
-
-describe('LabelsSelect Getters', () => {
- describe('dropdownButtonText', () => {
- it.each`
- labelType | dropdownButtonText | expected
- ${'default'} | ${''} | ${'Label'}
- ${'custom'} | ${'Custom label'} | ${'Custom label'}
- `(
- 'returns $labelType text when state.labels has no selected labels',
- ({ dropdownButtonText, expected }) => {
- const labels = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }];
- const selectedLabels = [];
- const state = { labels, selectedLabels, dropdownButtonText };
-
- expect(getters.dropdownButtonText(state, {})).toBe(expected);
- },
- );
-
- it('returns label title when state.labels has only 1 label', () => {
- const labels = [{ id: 1, title: 'Foobar', set: true }];
-
- expect(getters.dropdownButtonText({ labels }, { isDropdownVariantSidebar: true })).toBe(
- 'Foobar',
- );
- });
-
- it('returns first label title and remaining labels count when state.labels has more than 1 label', () => {
- const labels = [
- { id: 1, title: 'Foo', set: true },
- { id: 2, title: 'Bar', set: true },
- ];
-
- expect(getters.dropdownButtonText({ labels }, { isDropdownVariantSidebar: true })).toBe(
- 'Foo +1 more',
- );
- });
- });
-
- describe('selectedLabelsList', () => {
- it('returns array of IDs of all labels within `state.selectedLabels`', () => {
- const selectedLabels = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }];
-
- expect(getters.selectedLabelsList({ selectedLabels })).toEqual([1, 2, 3, 4]);
- });
- });
-
- describe('isDropdownVariantSidebar', () => {
- it('returns `true` when `state.variant` is "sidebar"', () => {
- expect(getters.isDropdownVariantSidebar({ variant: 'sidebar' })).toBe(true);
- });
- });
-
- describe('isDropdownVariantStandalone', () => {
- it('returns `true` when `state.variant` is "standalone"', () => {
- expect(getters.isDropdownVariantStandalone({ variant: 'standalone' })).toBe(true);
- });
- });
-});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/mutations_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/mutations_spec.js
deleted file mode 100644
index 1f0e0eee420..00000000000
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/mutations_spec.js
+++ /dev/null
@@ -1,115 +0,0 @@
-import * as types from '~/vue_shared/components/sidebar/labels_select_widget/store/mutation_types';
-import mutations from '~/vue_shared/components/sidebar/labels_select_widget/store/mutations';
-
-describe('LabelsSelect Mutations', () => {
- describe(`${types.SET_INITIAL_STATE}`, () => {
- it('initializes provided props to store state', () => {
- const state = {};
- mutations[types.SET_INITIAL_STATE](state, {
- labels: 'foo',
- });
-
- expect(state.labels).toEqual('foo');
- });
- });
-
- describe(`${types.TOGGLE_DROPDOWN_BUTTON}`, () => {
- it('toggles value of `state.showDropdownButton`', () => {
- const state = {
- showDropdownButton: false,
- };
- mutations[types.TOGGLE_DROPDOWN_BUTTON](state);
-
- expect(state.showDropdownButton).toBe(true);
- });
- });
-
- describe(`${types.TOGGLE_DROPDOWN_CONTENTS}`, () => {
- it('toggles value of `state.showDropdownButton` when `state.dropdownOnly` is false', () => {
- const state = {
- dropdownOnly: false,
- showDropdownButton: false,
- variant: 'sidebar',
- };
- mutations[types.TOGGLE_DROPDOWN_CONTENTS](state);
-
- expect(state.showDropdownButton).toBe(true);
- });
-
- it('toggles value of `state.showDropdownContents`', () => {
- const state = {
- showDropdownContents: false,
- };
- mutations[types.TOGGLE_DROPDOWN_CONTENTS](state);
-
- expect(state.showDropdownContents).toBe(true);
- });
-
- it('sets value of `state.showDropdownContentsCreateView` to `false` when `showDropdownContents` is true', () => {
- const state = {
- showDropdownContents: false,
- showDropdownContentsCreateView: true,
- };
- mutations[types.TOGGLE_DROPDOWN_CONTENTS](state);
-
- expect(state.showDropdownContentsCreateView).toBe(false);
- });
- });
-
- describe(`${types.TOGGLE_DROPDOWN_CONTENTS_CREATE_VIEW}`, () => {
- it('toggles value of `state.showDropdownContentsCreateView`', () => {
- const state = {
- showDropdownContentsCreateView: false,
- };
- mutations[types.TOGGLE_DROPDOWN_CONTENTS_CREATE_VIEW](state);
-
- expect(state.showDropdownContentsCreateView).toBe(true);
- });
- });
-
- describe(`${types.UPDATE_SELECTED_LABELS}`, () => {
- let labels;
-
- beforeEach(() => {
- labels = [
- { id: 1, title: 'scoped::test', set: true },
- { id: 2, set: false, title: 'scoped::one' },
- { id: 3, title: '' },
- { id: 4, title: '' },
- ];
- });
-
- it('updates `state.labels` to include `touched` and `set` props based on provided `labels` param', () => {
- const updatedLabelIds = [2];
- const state = {
- labels,
- };
- mutations[types.UPDATE_SELECTED_LABELS](state, { labels: [{ id: 2 }] });
-
- state.labels.forEach((label) => {
- if (updatedLabelIds.includes(label.id)) {
- expect(label.touched).toBe(true);
- expect(label.set).toBe(true);
- }
- });
- });
-
- describe('when label is scoped', () => {
- it('unsets the currently selected scoped label and sets the current label', () => {
- const state = {
- labels,
- };
- mutations[types.UPDATE_SELECTED_LABELS](state, {
- labels: [{ id: 2, title: 'scoped::one' }],
- });
-
- expect(state.labels).toEqual([
- { id: 1, title: 'scoped::test', set: false },
- { id: 2, set: true, title: 'scoped::one', touched: true },
- { id: 3, title: '' },
- { id: 4, title: '' },
- ]);
- });
- });
- });
-});
diff --git a/spec/frontend/vue_shared/components/storage_counter/usage_graph_spec.js b/spec/frontend/vue_shared/components/storage_counter/usage_graph_spec.js
new file mode 100644
index 00000000000..103eee4b9a8
--- /dev/null
+++ b/spec/frontend/vue_shared/components/storage_counter/usage_graph_spec.js
@@ -0,0 +1,137 @@
+import { shallowMount } from '@vue/test-utils';
+import { numberToHumanSize } from '~/lib/utils/number_utils';
+import UsageGraph from '~/vue_shared/components/storage_counter/usage_graph.vue';
+
+let data;
+let wrapper;
+
+function mountComponent({ rootStorageStatistics, limit }) {
+ wrapper = shallowMount(UsageGraph, {
+ propsData: {
+ rootStorageStatistics,
+ limit,
+ },
+ });
+}
+function findStorageTypeUsagesSerialized() {
+ return wrapper
+ .findAll('[data-testid="storage-type-usage"]')
+ .wrappers.map((wp) => wp.element.style.flex);
+}
+
+describe('Storage Counter usage graph component', () => {
+ beforeEach(() => {
+ data = {
+ rootStorageStatistics: {
+ wikiSize: 5000,
+ repositorySize: 4000,
+ packagesSize: 3000,
+ lfsObjectsSize: 2000,
+ buildArtifactsSize: 500,
+ pipelineArtifactsSize: 500,
+ snippetsSize: 2000,
+ storageSize: 17000,
+ uploadsSize: 1000,
+ },
+ limit: 2000,
+ };
+ mountComponent(data);
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders the legend in order', () => {
+ const types = wrapper.findAll('[data-testid="storage-type-legend"]');
+
+ const {
+ buildArtifactsSize,
+ pipelineArtifactsSize,
+ lfsObjectsSize,
+ packagesSize,
+ repositorySize,
+ wikiSize,
+ snippetsSize,
+ uploadsSize,
+ } = data.rootStorageStatistics;
+
+ expect(types.at(0).text()).toMatchInterpolatedText(`Wikis ${numberToHumanSize(wikiSize)}`);
+ expect(types.at(1).text()).toMatchInterpolatedText(
+ `Repositories ${numberToHumanSize(repositorySize)}`,
+ );
+ expect(types.at(2).text()).toMatchInterpolatedText(
+ `Packages ${numberToHumanSize(packagesSize)}`,
+ );
+ expect(types.at(3).text()).toMatchInterpolatedText(
+ `LFS Objects ${numberToHumanSize(lfsObjectsSize)}`,
+ );
+ expect(types.at(4).text()).toMatchInterpolatedText(
+ `Snippets ${numberToHumanSize(snippetsSize)}`,
+ );
+ expect(types.at(5).text()).toMatchInterpolatedText(
+ `Artifacts ${numberToHumanSize(buildArtifactsSize + pipelineArtifactsSize)}`,
+ );
+ expect(types.at(6).text()).toMatchInterpolatedText(`Uploads ${numberToHumanSize(uploadsSize)}`);
+ });
+
+ describe('when storage type is not used', () => {
+ beforeEach(() => {
+ data.rootStorageStatistics.wikiSize = 0;
+ mountComponent(data);
+ });
+
+ it('filters the storage type', () => {
+ expect(wrapper.text()).not.toContain('Wikis');
+ });
+ });
+
+ describe('when there is no storage usage', () => {
+ beforeEach(() => {
+ data.rootStorageStatistics.storageSize = 0;
+ mountComponent(data);
+ });
+
+ it('it does not render', () => {
+ expect(wrapper.html()).toEqual('');
+ });
+ });
+
+ describe('when limit is 0', () => {
+ beforeEach(() => {
+ data.limit = 0;
+ mountComponent(data);
+ });
+
+ it('sets correct flex values', () => {
+ expect(findStorageTypeUsagesSerialized()).toStrictEqual([
+ '0.29411764705882354',
+ '0.23529411764705882',
+ '0.17647058823529413',
+ '0.11764705882352941',
+ '0.11764705882352941',
+ '0.058823529411764705',
+ '0.058823529411764705',
+ ]);
+ });
+ });
+
+ describe('when storage exceeds limit', () => {
+ beforeEach(() => {
+ data.limit = data.rootStorageStatistics.storageSize - 1;
+ mountComponent(data);
+ });
+
+ it('it does render correclty', () => {
+ expect(findStorageTypeUsagesSerialized()).toStrictEqual([
+ '0.29411764705882354',
+ '0.23529411764705882',
+ '0.17647058823529413',
+ '0.11764705882352941',
+ '0.11764705882352941',
+ '0.058823529411764705',
+ '0.058823529411764705',
+ ]);
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js b/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js
index 538e67ef354..926223e0670 100644
--- a/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js
+++ b/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js
@@ -94,7 +94,7 @@ describe('User Popover Component', () => {
const bio = 'My super interesting bio';
it('should show only bio if work information is not available', () => {
- const user = { ...DEFAULT_PROPS.user, bio, bioHtml: bio };
+ const user = { ...DEFAULT_PROPS.user, bio };
createWrapper({ user });
@@ -117,7 +117,6 @@ describe('User Popover Component', () => {
const user = {
...DEFAULT_PROPS.user,
bio,
- bioHtml: bio,
workInformation: 'Frontend Engineer at GitLab',
};
@@ -127,16 +126,15 @@ describe('User Popover Component', () => {
expect(findWorkInformation().text()).toBe('Frontend Engineer at GitLab');
});
- it('should not encode special characters in bio', () => {
+ it('should encode special characters in bio', () => {
const user = {
...DEFAULT_PROPS.user,
- bio: 'I like CSS',
- bioHtml: 'I like <b>CSS</b>',
+ bio: 'I like <b>CSS</b>',
};
createWrapper({ user });
- expect(findBio().html()).toContain('I like <b>CSS</b>');
+ expect(findBio().html()).toContain('I like &lt;b&gt;CSS&lt;/b&gt;');
});
it('shows icon for bio', () => {
@@ -250,6 +248,13 @@ describe('User Popover Component', () => {
const securityBotDocsLink = findSecurityBotDocsLink();
expect(securityBotDocsLink.exists()).toBe(true);
expect(securityBotDocsLink.attributes('href')).toBe(SECURITY_BOT_USER.websiteUrl);
+ expect(securityBotDocsLink.text()).toBe('Learn more about GitLab Security Bot');
+ });
+
+ it("doesn't escape user's name", () => {
+ createWrapper({ user: { ...SECURITY_BOT_USER, name: '%<>\';"' } });
+ const securityBotDocsLink = findSecurityBotDocsLink();
+ expect(securityBotDocsLink.text()).toBe('Learn more about %<>\';"');
});
});
});
diff --git a/spec/frontend/zen_mode_spec.js b/spec/frontend/zen_mode_spec.js
index bf4b57d8afb..13f221fd9d9 100644
--- a/spec/frontend/zen_mode_spec.js
+++ b/spec/frontend/zen_mode_spec.js
@@ -3,7 +3,7 @@ import MockAdapter from 'axios-mock-adapter';
import Dropzone from 'dropzone';
import $ from 'jquery';
import Mousetrap from 'mousetrap';
-import initNotes from '~/init_notes';
+import GLForm from '~/gl_form';
import * as utils from '~/lib/utils/common_utils';
import ZenMode from '~/zen_mode';
@@ -34,7 +34,9 @@ describe('ZenMode', () => {
mock.onGet().reply(200);
loadFixtures(fixtureName);
- initNotes();
+
+ const form = $('.js-new-note-form');
+ new GLForm(form); // eslint-disable-line no-new
dropzoneForElementSpy = jest.spyOn(Dropzone, 'forElement').mockImplementation(() => ({
enable: () => true,
diff --git a/spec/frontend_integration/README.md b/spec/frontend_integration/README.md
index 573a385d81e..377294fb19f 100644
--- a/spec/frontend_integration/README.md
+++ b/spec/frontend_integration/README.md
@@ -11,6 +11,33 @@ Frontend integration specs:
As a result, they deserve their own special place.
+## Run frontend integration tests locally
+
+The frontend integration specs are all about testing integration frontend bundles against a
+mock backend. The mock backend is built using the fixtures and GraphQL schema.
+
+We can generate the necessary fixtures and GraphQL schema by running:
+
+```shell
+bundle exec rake frontend:fixtures gitlab:graphql:schema:dump
+```
+
+Then we can use [Jest](https://jestjs.io/) to run the frontend integration tests:
+
+```shell
+yarn jest:integration <path-to-integration-test>
+```
+
+If you'd like to run the frontend integration specs **without** setting up the fixtures first, then you
+can set `GL_IGNORE_WARNINGS=1`:
+
+```shell
+GL_IGNORE_WARNINGS=1 yarn jest:integration <path-to-integration-test>
+```
+
+The `jest-integration` job executes the frontend integration tests in our
+CI/CD pipelines.
+
## References
- https://docs.gitlab.com/ee/development/testing_guide/testing_levels.html#frontend-integration-tests
diff --git a/spec/frontend_integration/fly_out_nav_browser_spec.js b/spec/frontend_integration/fly_out_nav_browser_spec.js
new file mode 100644
index 00000000000..ef2afa20528
--- /dev/null
+++ b/spec/frontend_integration/fly_out_nav_browser_spec.js
@@ -0,0 +1,363 @@
+import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
+import { SIDEBAR_COLLAPSED_CLASS } from '~/contextual_sidebar';
+import {
+ calculateTop,
+ showSubLevelItems,
+ canShowSubItems,
+ canShowActiveSubItems,
+ mouseEnterTopItems,
+ mouseLeaveTopItem,
+ getOpenMenu,
+ setOpenMenu,
+ mousePos,
+ getHideSubItemsInterval,
+ documentMouseMove,
+ getHeaderHeight,
+ setSidebar,
+ subItemsMouseLeave,
+} from '~/fly_out_nav';
+
+describe('Fly out sidebar navigation', () => {
+ let el;
+ let breakpointSize = 'lg';
+
+ const OLD_SIDEBAR_WIDTH = 200;
+ const CONTAINER_INITIAL_BOUNDING_RECT = {
+ x: 8,
+ y: 8,
+ width: 769,
+ height: 0,
+ top: 8,
+ right: 777,
+ bottom: 8,
+ left: 8,
+ };
+ const SUB_ITEMS_INITIAL_BOUNDING_RECT = {
+ x: 148,
+ y: 8,
+ width: 0,
+ height: 150,
+ top: 8,
+ right: 148,
+ bottom: 158,
+ left: 148,
+ };
+ const mockBoundingClientRect = (elem, rect) => {
+ jest.spyOn(elem, 'getBoundingClientRect').mockReturnValue(rect);
+ };
+
+ const findSubItems = () => document.querySelector('.sidebar-sub-level-items');
+ const mockBoundingRects = () => {
+ const subItems = findSubItems();
+ mockBoundingClientRect(el, CONTAINER_INITIAL_BOUNDING_RECT);
+ mockBoundingClientRect(subItems, SUB_ITEMS_INITIAL_BOUNDING_RECT);
+ };
+ const mockSidebarFragment = (styleProps = '') =>
+ `<div class="sidebar-sub-level-items" style="${styleProps}"></div>`;
+
+ beforeEach(() => {
+ el = document.createElement('div');
+ el.style.position = 'relative';
+ document.body.appendChild(el);
+
+ jest.spyOn(GlBreakpointInstance, 'getBreakpointSize').mockImplementation(() => breakpointSize);
+ });
+
+ afterEach(() => {
+ document.body.innerHTML = '';
+ breakpointSize = 'lg';
+ mousePos.length = 0;
+
+ setSidebar(null);
+ });
+
+ describe('calculateTop', () => {
+ it('returns boundingRect top', () => {
+ const boundingRect = {
+ top: 100,
+ height: 100,
+ };
+
+ expect(calculateTop(boundingRect, 100)).toBe(100);
+ });
+ });
+
+ describe('getHideSubItemsInterval', () => {
+ beforeEach(() => {
+ el.innerHTML = mockSidebarFragment('position: fixed; top: 0; left: 100px; height: 150px;');
+ mockBoundingRects();
+ });
+
+ it('returns 0 if currentOpenMenu is nil', () => {
+ setOpenMenu(null);
+ expect(getHideSubItemsInterval()).toBe(0);
+ });
+
+ it('returns 0 if mousePos is empty', () => {
+ expect(getHideSubItemsInterval()).toBe(0);
+ });
+
+ it('returns 0 when mouse above sub-items', () => {
+ showSubLevelItems(el);
+ documentMouseMove({
+ clientX: el.getBoundingClientRect().left,
+ clientY: el.getBoundingClientRect().top,
+ });
+ documentMouseMove({
+ clientX: el.getBoundingClientRect().left,
+ clientY: el.getBoundingClientRect().top - 50,
+ });
+
+ expect(getHideSubItemsInterval()).toBe(0);
+ });
+
+ it('returns 0 when mouse is below sub-items', () => {
+ const subItems = findSubItems();
+
+ showSubLevelItems(el);
+ documentMouseMove({
+ clientX: el.getBoundingClientRect().left,
+ clientY: el.getBoundingClientRect().top,
+ });
+ documentMouseMove({
+ clientX: el.getBoundingClientRect().left,
+ clientY: el.getBoundingClientRect().top - subItems.getBoundingClientRect().height + 50,
+ });
+
+ expect(getHideSubItemsInterval()).toBe(0);
+ });
+
+ it('returns 300 when mouse is moved towards sub-items', () => {
+ documentMouseMove({
+ clientX: el.getBoundingClientRect().left,
+ clientY: el.getBoundingClientRect().top,
+ });
+
+ showSubLevelItems(el);
+ documentMouseMove({
+ clientX: el.getBoundingClientRect().left + 20,
+ clientY: el.getBoundingClientRect().top + 10,
+ });
+
+ expect(getHideSubItemsInterval()).toBe(300);
+ });
+ });
+
+ describe('mouseLeaveTopItem', () => {
+ beforeEach(() => {
+ jest.spyOn(el.classList, 'remove');
+ });
+
+ it('removes is-over class if currentOpenMenu is null', () => {
+ setOpenMenu(null);
+
+ mouseLeaveTopItem(el);
+
+ expect(el.classList.remove).toHaveBeenCalledWith('is-over');
+ });
+
+ it('removes is-over class if currentOpenMenu is null & there are sub-items', () => {
+ setOpenMenu(null);
+ el.innerHTML = mockSidebarFragment('position: absolute');
+
+ mouseLeaveTopItem(el);
+
+ expect(el.classList.remove).toHaveBeenCalledWith('is-over');
+ });
+
+ it('does not remove is-over class if currentOpenMenu is the passed in sub-items', () => {
+ setOpenMenu(null);
+ el.innerHTML = mockSidebarFragment('position: absolute');
+
+ setOpenMenu(findSubItems());
+ mouseLeaveTopItem(el);
+
+ expect(el.classList.remove).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('mouseEnterTopItems', () => {
+ beforeEach(() => {
+ el.innerHTML = mockSidebarFragment(
+ `position: absolute; top: 0; left: 100px; height: ${OLD_SIDEBAR_WIDTH}px;`,
+ );
+ mockBoundingRects();
+ });
+
+ it('shows sub-items after 0ms if no menu is open', (done) => {
+ const subItems = findSubItems();
+ mouseEnterTopItems(el);
+
+ expect(getHideSubItemsInterval()).toBe(0);
+
+ setTimeout(() => {
+ expect(subItems.style.display).toBe('block');
+ done();
+ });
+ });
+
+ it('shows sub-items after 300ms if a menu is currently open', (done) => {
+ const subItems = findSubItems();
+
+ documentMouseMove({
+ clientX: el.getBoundingClientRect().left,
+ clientY: el.getBoundingClientRect().top,
+ });
+
+ setOpenMenu(subItems);
+
+ documentMouseMove({
+ clientX: el.getBoundingClientRect().left + 20,
+ clientY: el.getBoundingClientRect().top + 10,
+ });
+
+ mouseEnterTopItems(el, 0);
+
+ setTimeout(() => {
+ expect(subItems.style.display).toBe('block');
+
+ done();
+ });
+ });
+ });
+
+ describe('showSubLevelItems', () => {
+ beforeEach(() => {
+ el.innerHTML = mockSidebarFragment('position: absolute');
+ });
+
+ it('adds is-over class to el', () => {
+ jest.spyOn(el.classList, 'add');
+
+ showSubLevelItems(el);
+
+ expect(el.classList.add).toHaveBeenCalledWith('is-over');
+ });
+
+ it('does not show sub-items on mobile', () => {
+ breakpointSize = 'xs';
+
+ showSubLevelItems(el);
+
+ expect(findSubItems().style.display).not.toBe('block');
+ });
+
+ it('shows sub-items', () => {
+ showSubLevelItems(el);
+
+ expect(findSubItems().style.display).toBe('block');
+ });
+
+ it('shows collapsed only sub-items if icon only sidebar', () => {
+ const subItems = findSubItems();
+ const sidebar = document.createElement('div');
+ sidebar.classList.add(SIDEBAR_COLLAPSED_CLASS);
+ subItems.classList.add('is-fly-out-only');
+
+ setSidebar(sidebar);
+
+ showSubLevelItems(el);
+
+ expect(findSubItems().style.display).toBe('block');
+ });
+
+ it('does not show collapsed only sub-items if icon only sidebar', () => {
+ const subItems = findSubItems();
+ subItems.classList.add('is-fly-out-only');
+
+ showSubLevelItems(el);
+
+ expect(subItems.style.display).not.toBe('block');
+ });
+
+ it('sets transform of sub-items', () => {
+ const sidebar = document.createElement('div');
+ const subItems = findSubItems();
+
+ sidebar.style.width = `${OLD_SIDEBAR_WIDTH}px`;
+
+ document.body.appendChild(sidebar);
+
+ setSidebar(sidebar);
+ showSubLevelItems(el);
+
+ expect(subItems.style.transform).toBe(
+ `translate3d(${OLD_SIDEBAR_WIDTH}px, ${
+ Math.floor(el.getBoundingClientRect().top) - getHeaderHeight()
+ }px, 0)`,
+ );
+ });
+
+ it('sets is-above when element is above', () => {
+ const subItems = findSubItems();
+ mockBoundingRects();
+
+ subItems.style.height = `${window.innerHeight + el.offsetHeight}px`;
+ el.style.top = `${window.innerHeight - el.offsetHeight}px`;
+
+ jest.spyOn(subItems.classList, 'add');
+
+ showSubLevelItems(el);
+
+ expect(subItems.classList.add).toHaveBeenCalledWith('is-above');
+ });
+ });
+
+ describe('canShowSubItems', () => {
+ it('returns true if on desktop size', () => {
+ expect(canShowSubItems()).toBeTruthy();
+ });
+
+ it('returns false if on mobile size', () => {
+ breakpointSize = 'xs';
+
+ expect(canShowSubItems()).toBeFalsy();
+ });
+ });
+
+ describe('canShowActiveSubItems', () => {
+ it('returns true by default', () => {
+ expect(canShowActiveSubItems(el)).toBeTruthy();
+ });
+
+ it('returns false when active & expanded sidebar', () => {
+ const sidebar = document.createElement('div');
+ el.classList.add('active');
+
+ setSidebar(sidebar);
+
+ expect(canShowActiveSubItems(el)).toBeFalsy();
+ });
+
+ it('returns true when active & collapsed sidebar', () => {
+ const sidebar = document.createElement('div');
+ sidebar.classList.add(SIDEBAR_COLLAPSED_CLASS);
+ el.classList.add('active');
+
+ setSidebar(sidebar);
+
+ expect(canShowActiveSubItems(el)).toBeTruthy();
+ });
+ });
+
+ describe('subItemsMouseLeave', () => {
+ beforeEach(() => {
+ el.innerHTML = mockSidebarFragment('position: absolute');
+
+ setOpenMenu(findSubItems());
+ });
+
+ it('hides subMenu if element is not hovered', () => {
+ subItemsMouseLeave(el);
+
+ expect(getOpenMenu()).toBeNull();
+ });
+
+ it('does not hide subMenu if element is hovered', () => {
+ el.classList.add('is-over');
+ subItemsMouseLeave(el);
+
+ expect(getOpenMenu()).not.toBeNull();
+ });
+ });
+});
diff --git a/spec/frontend_integration/lib/utils/browser_spec.js b/spec/frontend_integration/lib/utils/browser_spec.js
new file mode 100644
index 00000000000..6c72e29076d
--- /dev/null
+++ b/spec/frontend_integration/lib/utils/browser_spec.js
@@ -0,0 +1,94 @@
+import { GlBreakpointInstance as breakpointInstance } from '@gitlab/ui/dist/utils';
+import * as commonUtils from '~/lib/utils/common_utils';
+
+describe('common_utils browser specific specs', () => {
+ const mockOffsetHeight = (elem, offsetHeight) => {
+ Object.defineProperty(elem, 'offsetHeight', { value: offsetHeight });
+ };
+
+ const mockBoundingClientRect = (elem, rect) => {
+ jest.spyOn(elem, 'getBoundingClientRect').mockReturnValue(rect);
+ };
+
+ describe('contentTop', () => {
+ it('does not add height for fileTitle or compareVersionsHeader if screen is too small', () => {
+ jest.spyOn(breakpointInstance, 'isDesktop').mockReturnValue(false);
+
+ setFixtures(`
+ <div class="diff-file file-title-flex-parent">
+ blah blah blah
+ </div>
+ <div class="mr-version-controls">
+ more blah blah blah
+ </div>
+ `);
+
+ expect(commonUtils.contentTop()).toBe(0);
+ });
+
+ it('adds height for fileTitle and compareVersionsHeader screen is large enough', () => {
+ jest.spyOn(breakpointInstance, 'isDesktop').mockReturnValue(true);
+
+ setFixtures(`
+ <div class="diff-file file-title-flex-parent">
+ blah blah blah
+ </div>
+ <div class="mr-version-controls">
+ more blah blah blah
+ </div>
+ `);
+
+ mockOffsetHeight(document.querySelector('.diff-file'), 100);
+ mockOffsetHeight(document.querySelector('.mr-version-controls'), 18);
+ expect(commonUtils.contentTop()).toBe(18);
+ });
+ });
+
+ describe('isInViewport', () => {
+ let el;
+
+ beforeEach(() => {
+ el = document.createElement('div');
+ });
+
+ afterEach(() => {
+ document.body.removeChild(el);
+ });
+
+ it('returns true when provided `el` is in viewport', () => {
+ el.setAttribute('style', `position: absolute; right: ${window.innerWidth + 0.2};`);
+ mockBoundingClientRect(el, {
+ x: 8,
+ y: 8,
+ width: 0,
+ height: 0,
+ top: 8,
+ right: 8,
+ bottom: 8,
+ left: 8,
+ });
+
+ document.body.appendChild(el);
+
+ expect(commonUtils.isInViewport(el)).toBe(true);
+ });
+
+ it('returns false when provided `el` is not in viewport', () => {
+ el.setAttribute('style', 'position: absolute; top: -1000px; left: -1000px;');
+ mockBoundingClientRect(el, {
+ x: -1000,
+ y: -1000,
+ width: 0,
+ height: 0,
+ top: -1000,
+ right: -1000,
+ bottom: -1000,
+ left: -1000,
+ });
+
+ document.body.appendChild(el);
+
+ expect(commonUtils.isInViewport(el)).toBe(false);
+ });
+ });
+});
diff --git a/spec/graphql/mutations/custom_emoji/destroy_spec.rb b/spec/graphql/mutations/custom_emoji/destroy_spec.rb
new file mode 100644
index 00000000000..4667812cc80
--- /dev/null
+++ b/spec/graphql/mutations/custom_emoji/destroy_spec.rb
@@ -0,0 +1,79 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Mutations::CustomEmoji::Destroy do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:user) { create(:user) }
+ let_it_be_with_reload(:custom_emoji) { create(:custom_emoji, group: group) }
+
+ let(:args) { { id: custom_emoji.to_global_id } }
+ let(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
+
+ context 'field tests' do
+ subject { described_class }
+
+ it { is_expected.to have_graphql_arguments(:id) }
+ it { is_expected.to have_graphql_field(:custom_emoji) }
+ end
+
+ shared_examples 'does not delete custom emoji' do
+ it 'raises exception' do
+ expect { subject }
+ .to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ shared_examples 'deletes custom emoji' do
+ it 'returns deleted custom emoji' do
+ result = subject
+
+ expect(result[:custom_emoji][:name]).to eq(custom_emoji.name)
+ end
+ end
+
+ describe '#resolve' do
+ subject { mutation.resolve(**args) }
+
+ context 'when the user' do
+ context 'has no permissions' do
+ it_behaves_like 'does not delete custom emoji'
+ end
+
+ context 'when the user is developer and not the owner of custom emoji' do
+ before do
+ group.add_developer(user)
+ end
+
+ it_behaves_like 'does not delete custom emoji'
+ end
+ end
+
+ context 'when user' do
+ context 'is maintainer' do
+ before do
+ group.add_maintainer(user)
+ end
+
+ it_behaves_like 'deletes custom emoji'
+ end
+
+ context 'is owner' do
+ before do
+ group.add_owner(user)
+ end
+
+ it_behaves_like 'deletes custom emoji'
+ end
+
+ context 'is developer and creator of the emoji' do
+ before do
+ group.add_developer(user)
+ custom_emoji.update_attribute(:creator, user)
+ end
+
+ it_behaves_like 'deletes custom emoji'
+ end
+ end
+ end
+end
diff --git a/spec/graphql/mutations/customer_relations/organizations/create_spec.rb b/spec/graphql/mutations/customer_relations/organizations/create_spec.rb
new file mode 100644
index 00000000000..ab430b9240b
--- /dev/null
+++ b/spec/graphql/mutations/customer_relations/organizations/create_spec.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Mutations::CustomerRelations::Organizations::Create do
+ let_it_be(:user) { create(:user) }
+
+ let(:valid_params) do
+ attributes_for(:organization,
+ group: group,
+ description: 'This company is super important!',
+ default_rate: 1_000
+ )
+ end
+
+ describe 'create organizations mutation' do
+ describe '#resolve' do
+ subject(:resolve_mutation) do
+ described_class.new(object: nil, context: { current_user: user }, field: nil).resolve(
+ **valid_params,
+ group_id: group.to_global_id
+ )
+ end
+
+ context 'when the user does not have permission' do
+ let_it_be(:group) { create(:group) }
+
+ before do
+ group.add_guest(user)
+ end
+
+ it 'raises an error' do
+ expect { resolve_mutation }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ context 'when the user has permission' do
+ let_it_be(:group) { create(:group) }
+
+ before_all do
+ group.add_reporter(user)
+ end
+
+ context 'when the feature is disabled' do
+ before do
+ stub_feature_flags(customer_relations: false)
+ end
+
+ it 'raises an error' do
+ expect { resolve_mutation }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ context 'when the params are invalid' do
+ before do
+ valid_params[:name] = nil
+ end
+
+ it 'returns the validation error' do
+ expect(resolve_mutation[:errors]).to eq(["Name can't be blank"])
+ end
+ end
+
+ context 'when the user has permission to create an organization' do
+ it 'creates organization with correct values' do
+ expect(resolve_mutation[:organization]).to have_attributes(valid_params)
+ end
+ end
+ end
+ end
+ end
+
+ specify { expect(described_class).to require_graphql_authorizations(:admin_organization) }
+end
diff --git a/spec/graphql/mutations/customer_relations/organizations/update_spec.rb b/spec/graphql/mutations/customer_relations/organizations/update_spec.rb
new file mode 100644
index 00000000000..f5aa6c00301
--- /dev/null
+++ b/spec/graphql/mutations/customer_relations/organizations/update_spec.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Mutations::CustomerRelations::Organizations::Update do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:name) { 'GitLab' }
+ let_it_be(:default_rate) { 1000.to_f }
+ let_it_be(:description) { 'VIP' }
+
+ let(:organization) { create(:organization, group: group) }
+ let(:attributes) do
+ {
+ id: organization.to_global_id,
+ name: name,
+ default_rate: default_rate,
+ description: description
+ }
+ end
+
+ describe '#resolve' do
+ subject(:resolve_mutation) do
+ described_class.new(object: nil, context: { current_user: user }, field: nil).resolve(
+ attributes
+ )
+ end
+
+ context 'when the user does not have permission to update an organization' do
+ let_it_be(:group) { create(:group) }
+
+ before do
+ group.add_guest(user)
+ end
+
+ it 'raises an error' do
+ expect { resolve_mutation }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ context 'when the organization does not exist' do
+ let_it_be(:group) { create(:group) }
+
+ it 'raises an error' do
+ attributes[:id] = 'gid://gitlab/CustomerRelations::Organization/999'
+
+ expect { resolve_mutation }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ context 'when the user has permission to update an organization' do
+ let_it_be(:group) { create(:group) }
+
+ before_all do
+ group.add_reporter(user)
+ end
+
+ it 'updates the organization with correct values' do
+ expect(resolve_mutation[:organization]).to have_attributes(attributes)
+ end
+
+ context 'when the feature is disabled' do
+ before do
+ stub_feature_flags(customer_relations: false)
+ end
+
+ it 'raises an error' do
+ expect { resolve_mutation }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+ end
+ end
+
+ specify { expect(described_class).to require_graphql_authorizations(:admin_organization) }
+end
diff --git a/spec/graphql/mutations/dependency_proxy/image_ttl_group_policy/update_spec.rb b/spec/graphql/mutations/dependency_proxy/image_ttl_group_policy/update_spec.rb
new file mode 100644
index 00000000000..792e87f0d25
--- /dev/null
+++ b/spec/graphql/mutations/dependency_proxy/image_ttl_group_policy/update_spec.rb
@@ -0,0 +1,110 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Mutations::DependencyProxy::ImageTtlGroupPolicy::Update do
+ using RSpec::Parameterized::TableSyntax
+
+ let_it_be_with_reload(:group) { create(:group) }
+ let_it_be(:user) { create(:user) }
+
+ let(:params) { { group_path: group.full_path } }
+
+ specify { expect(described_class).to require_graphql_authorizations(:admin_dependency_proxy) }
+
+ describe '#resolve' do
+ subject { described_class.new(object: group, context: { current_user: user }, field: nil).resolve(**params) }
+
+ shared_examples 'returning a success' do
+ it 'returns the dependency proxy image ttl group policy with no errors' do
+ expect(subject).to eq(
+ dependency_proxy_image_ttl_policy: ttl_policy,
+ errors: []
+ )
+ end
+ end
+
+ shared_examples 'updating the dependency proxy image ttl policy' do
+ it_behaves_like 'updating the dependency proxy image ttl policy attributes',
+ from: { enabled: true, ttl: 90 },
+ to: { enabled: false, ttl: 2 }
+
+ it_behaves_like 'returning a success'
+
+ context 'with invalid params' do
+ let_it_be(:params) { { group_path: group.full_path, enabled: nil } }
+
+ it "doesn't create the dependency proxy image ttl policy" do
+ expect { subject }.not_to change { DependencyProxy::ImageTtlGroupPolicy.count }
+ end
+
+ it 'does not update' do
+ expect { subject }
+ .not_to change { ttl_policy.reload.enabled }
+ end
+
+ it 'returns an error' do
+ expect(subject).to eq(
+ dependency_proxy_image_ttl_policy: nil,
+ errors: ['Enabled is not included in the list']
+ )
+ end
+ end
+ end
+
+ shared_examples 'denying access to dependency proxy image ttl policy' do
+ it 'raises Gitlab::Graphql::Errors::ResourceNotAvailable' do
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ before do
+ stub_config(dependency_proxy: { enabled: true })
+ end
+
+ context 'with existing dependency proxy image ttl policy' do
+ let_it_be(:ttl_policy) { create(:image_ttl_group_policy, group: group) }
+ let_it_be(:params) do
+ { group_path: group.full_path,
+ enabled: false,
+ ttl: 2 }
+ end
+
+ where(:user_role, :shared_examples_name) do
+ :maintainer | 'updating the dependency proxy image ttl policy'
+ :developer | 'updating the dependency proxy image ttl policy'
+ :reporter | 'denying access to dependency proxy image ttl policy'
+ :guest | 'denying access to dependency proxy image ttl policy'
+ :anonymous | 'denying access to dependency proxy image ttl policy'
+ end
+
+ with_them do
+ before do
+ group.send("add_#{user_role}", user) unless user_role == :anonymous
+ end
+
+ it_behaves_like params[:shared_examples_name]
+ end
+ end
+
+ context 'without existing dependency proxy image ttl policy' do
+ let_it_be(:ttl_policy) { group.dependency_proxy_image_ttl_policy }
+
+ where(:user_role, :shared_examples_name) do
+ :maintainer | 'creating the dependency proxy image ttl policy'
+ :developer | 'creating the dependency proxy image ttl policy'
+ :reporter | 'denying access to dependency proxy image ttl policy'
+ :guest | 'denying access to dependency proxy image ttl policy'
+ :anonymous | 'denying access to dependency proxy image ttl policy'
+ end
+
+ with_them do
+ before do
+ group.send("add_#{user_role}", user) unless user_role == :anonymous
+ end
+
+ it_behaves_like params[:shared_examples_name]
+ end
+ end
+ end
+end
diff --git a/spec/graphql/resolvers/board_list_issues_resolver_spec.rb b/spec/graphql/resolvers/board_list_issues_resolver_spec.rb
index 6ffc8b045e9..26040f4ec1a 100644
--- a/spec/graphql/resolvers/board_list_issues_resolver_spec.rb
+++ b/spec/graphql/resolvers/board_list_issues_resolver_spec.rb
@@ -17,21 +17,38 @@ RSpec.describe Resolvers::BoardListIssuesResolver do
# auth is handled by the parent object
context 'when authorized' do
- let!(:issue1) { create(:issue, project: project, labels: [label], relative_position: 10) }
- let!(:issue2) { create(:issue, project: project, labels: [label, label2], relative_position: 12) }
- let!(:issue3) { create(:issue, project: project, labels: [label, label3], relative_position: 10) }
+ let!(:issue1) { create(:issue, project: project, labels: [label], relative_position: 10, milestone: started_milestone) }
+ let!(:issue2) { create(:issue, project: project, labels: [label, label2], relative_position: 12, milestone: started_milestone) }
+ let!(:issue3) { create(:issue, project: project, labels: [label, label3], relative_position: 10, milestone: future_milestone) }
+ let!(:issue4) { create(:issue, project: project, labels: [label], relative_position: nil) }
- it 'returns the issues in the correct order' do
+ let(:wildcard_started) { 'STARTED' }
+ let(:filters) { { milestone_title: ["started"], milestone_wildcard_id: wildcard_started } }
+
+ it 'raises a mutually exclusive filter error when milstone wildcard and title are provided' do
+ expect do
+ resolve_board_list_issues(args: { filters: filters })
+ end.to raise_error(Gitlab::Graphql::Errors::ArgumentError)
+ end
+
+ it 'returns issues in the correct order with non-nil relative positions', :aggregate_failures do
# by relative_position and then ID
- issues = resolve_board_list_issues
+ result = resolve_board_list_issues
- expect(issues.map(&:id)).to eq [issue3.id, issue1.id, issue2.id]
+ expect(result.map(&:id)).to eq [issue3.id, issue1.id, issue2.id, issue4.id]
+ expect(result.map(&:relative_position)).not_to include(nil)
end
it 'finds only issues matching filters' do
result = resolve_board_list_issues(args: { filters: { label_name: [label.title], not: { label_name: [label2.title] } } })
- expect(result).to match_array([issue1, issue3])
+ expect(result).to match_array([issue1, issue3, issue4])
+ end
+
+ it 'finds only issues filtered by milestone wildcard' do
+ result = resolve_board_list_issues(args: { filters: { milestone_wildcard_id: wildcard_started } })
+
+ expect(result).to match_array([issue1, issue2])
end
it 'finds only issues matching search param' do
@@ -49,7 +66,7 @@ RSpec.describe Resolvers::BoardListIssuesResolver do
it 'accepts assignee wildcard id NONE' do
result = resolve_board_list_issues(args: { filters: { assignee_wildcard_id: 'NONE' } })
- expect(result).to match_array([issue1, issue2, issue3])
+ expect(result).to match_array([issue1, issue2, issue3, issue4])
end
it 'accepts assignee wildcard id ANY' do
@@ -71,6 +88,9 @@ RSpec.describe Resolvers::BoardListIssuesResolver do
let(:board_parent) { user_project }
let(:project) { user_project }
+ let_it_be(:started_milestone) { create(:milestone, project: user_project, title: 'started milestone', start_date: 1.day.ago, due_date: 1.day.from_now) }
+ let_it_be(:future_milestone) { create(:milestone, project: user_project, title: 'future milestone', start_date: 1.day.from_now) }
+
it_behaves_like 'group and project board list issues resolver'
end
@@ -84,11 +104,14 @@ RSpec.describe Resolvers::BoardListIssuesResolver do
let(:board_parent) { group }
let!(:project) { create(:project, :private, group: group) }
+ let_it_be(:started_milestone) { create(:milestone, group: group, title: 'started milestone', start_date: 1.day.ago, due_date: 1.day.from_now) }
+ let_it_be(:future_milestone) { create(:milestone, group: group, title: 'future milestone', start_date: 1.day.from_now) }
+
it_behaves_like 'group and project board list issues resolver'
end
end
def resolve_board_list_issues(args: {}, current_user: user)
- resolve(described_class, obj: list, args: args, ctx: { current_user: current_user })
+ resolve(described_class, obj: list, args: args, ctx: { current_user: current_user }).items
end
end
diff --git a/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb b/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb
new file mode 100644
index 00000000000..89a2437a189
--- /dev/null
+++ b/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb
@@ -0,0 +1,94 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Resolvers::Ci::GroupRunnersResolver do
+ include GraphqlHelpers
+
+ describe '#resolve' do
+ subject { resolve(described_class, obj: obj, ctx: { current_user: user }, args: args) }
+
+ include_context 'runners resolver setup'
+
+ let(:obj) { group }
+ let(:args) { {} }
+
+ # First, we can do a couple of basic real tests to verify common cases. That ensures that the code works.
+ context 'when user cannot see runners' do
+ it 'returns no runners' do
+ expect(subject.items.to_a).to eq([])
+ end
+ end
+
+ context 'with user as group owner' do
+ before do
+ group.add_owner(user)
+ end
+
+ it 'returns all the runners' do
+ expect(subject.items.to_a).to contain_exactly(inactive_project_runner, offline_project_runner, group_runner, subgroup_runner)
+ end
+
+ context 'with membership direct' do
+ let(:args) { { membership: :direct } }
+
+ it 'returns only direct runners' do
+ expect(subject.items.to_a).to contain_exactly(group_runner)
+ end
+ end
+ end
+
+ # Then, we can check specific edge cases for this resolver
+ context 'with obj set to nil' do
+ let(:obj) { nil }
+
+ it 'raises an error' do
+ expect { subject }.to raise_error('Expected group missing')
+ end
+ end
+
+ context 'with obj not set to group' do
+ let(:obj) { build(:project) }
+
+ it 'raises an error' do
+ expect { subject }.to raise_error('Expected group missing')
+ end
+ end
+
+ # Here we have a mocked part. We assume that all possible edge cases are covered in RunnersFinder spec. So we don't need to test them twice.
+ # Only thing we can do is to verify that args from the resolver is correctly transformed to params of the Finder and we return the Finder's result back.
+ describe 'Allowed query arguments' do
+ let(:finder) { instance_double(::Ci::RunnersFinder) }
+ let(:args) do
+ {
+ status: 'active',
+ type: :group_type,
+ tag_list: ['active_runner'],
+ search: 'abc',
+ sort: :contacted_asc,
+ membership: :descendants
+ }
+ end
+
+ let(:expected_params) do
+ {
+ status_status: 'active',
+ type_type: :group_type,
+ tag_name: ['active_runner'],
+ preload: { tag_name: nil },
+ search: 'abc',
+ sort: 'contacted_asc',
+ membership: :descendants,
+ group: group
+ }
+ end
+
+ it 'calls RunnersFinder with expected arguments' do
+ allow(::Ci::RunnersFinder).to receive(:new).with(current_user: user, params: expected_params).once.and_return(finder)
+ allow(finder).to receive(:execute).once.and_return([:execute_return_value])
+
+ expect(subject.items.to_a).to eq([:execute_return_value])
+ end
+ end
+ end
+end
diff --git a/spec/graphql/resolvers/ci/runners_resolver_spec.rb b/spec/graphql/resolvers/ci/runners_resolver_spec.rb
index 5ac15d5729f..bb8dadeca40 100644
--- a/spec/graphql/resolvers/ci/runners_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/runners_resolver_spec.rb
@@ -5,185 +5,70 @@ require 'spec_helper'
RSpec.describe Resolvers::Ci::RunnersResolver do
include GraphqlHelpers
- let_it_be(:user) { create_default(:user, :admin) }
- let_it_be(:group) { create(:group, :public) }
- let_it_be(:project) { create(:project, :repository, :public) }
-
- let_it_be(:inactive_project_runner) do
- create(:ci_runner, :project, projects: [project], description: 'inactive project runner', token: 'abcdef', active: false, contacted_at: 1.minute.ago, tag_list: %w(project_runner))
- end
-
- let_it_be(:offline_project_runner) do
- create(:ci_runner, :project, projects: [project], description: 'offline project runner', token: 'defghi', contacted_at: 1.day.ago, tag_list: %w(project_runner active_runner))
- end
-
- let_it_be(:group_runner) { create(:ci_runner, :group, groups: [group], token: 'mnopqr', description: 'group runner', contacted_at: 1.second.ago) }
- let_it_be(:instance_runner) { create(:ci_runner, :instance, description: 'shared runner', token: 'stuvxz', contacted_at: 2.minutes.ago, tag_list: %w(instance_runner active_runner)) }
-
describe '#resolve' do
- subject { resolve(described_class, ctx: { current_user: user }, args: args).items.to_a }
-
- let(:args) do
- {}
- end
-
- context 'when the user cannot see runners' do
- let(:user) { create(:user) }
-
- it 'returns no runners' do
- is_expected.to be_empty
- end
- end
-
- context 'without sort' do
- it 'returns all the runners' do
- is_expected.to contain_exactly(inactive_project_runner, offline_project_runner, group_runner, instance_runner)
- end
- end
-
- context 'with a sort argument' do
- context "set to :contacted_asc" do
- let(:args) do
- { sort: :contacted_asc }
- end
-
- it { is_expected.to eq([offline_project_runner, instance_runner, inactive_project_runner, group_runner]) }
- end
-
- context "set to :contacted_desc" do
- let(:args) do
- { sort: :contacted_desc }
- end
-
- it { is_expected.to eq([offline_project_runner, instance_runner, inactive_project_runner, group_runner].reverse) }
- end
-
- context "set to :created_at_desc" do
- let(:args) do
- { sort: :created_at_desc }
- end
+ let(:obj) { nil }
+ let(:args) { {} }
- it { is_expected.to eq([instance_runner, group_runner, offline_project_runner, inactive_project_runner]) }
- end
-
- context "set to :created_at_asc" do
- let(:args) do
- { sort: :created_at_asc }
- end
-
- it { is_expected.to eq([instance_runner, group_runner, offline_project_runner, inactive_project_runner].reverse) }
- end
- end
+ subject { resolve(described_class, obj: obj, ctx: { current_user: user }, args: args) }
- context 'when type is filtered' do
- let(:args) do
- { type: runner_type.to_s }
- end
+ include_context 'runners resolver setup'
- context 'to instance runners' do
- let(:runner_type) { :instance_type }
+ # First, we can do a couple of basic real tests to verify common cases. That ensures that the code works.
+ context 'when user cannot see runners' do
+ let(:user) { build(:user) }
- it 'returns the instance runner' do
- is_expected.to contain_exactly(instance_runner)
- end
- end
-
- context 'to group runners' do
- let(:runner_type) { :group_type }
-
- it 'returns the group runner' do
- is_expected.to contain_exactly(group_runner)
- end
- end
-
- context 'to project runners' do
- let(:runner_type) { :project_type }
-
- it 'returns the project runner' do
- is_expected.to contain_exactly(inactive_project_runner, offline_project_runner)
- end
+ it 'returns no runners' do
+ expect(subject.items.to_a).to eq([])
end
end
- context 'when status is filtered' do
- let(:args) do
- { status: runner_status.to_s }
- end
-
- context 'to active runners' do
- let(:runner_status) { :active }
-
- it 'returns the instance and group runners' do
- is_expected.to contain_exactly(offline_project_runner, group_runner, instance_runner)
- end
- end
-
- context 'to offline runners' do
- let(:runner_status) { :offline }
+ context 'when user can see runners' do
+ let(:obj) { nil }
- it 'returns the offline project runner' do
- is_expected.to contain_exactly(offline_project_runner)
- end
+ it 'returns all the runners' do
+ expect(subject.items.to_a).to contain_exactly(inactive_project_runner, offline_project_runner, group_runner, subgroup_runner, instance_runner)
end
end
- context 'when tag list is filtered' do
- let(:args) do
- { tag_list: tag_list }
- end
-
- context 'with "project_runner" tag' do
- let(:tag_list) { ['project_runner'] }
+ # Then, we can check specific edge cases for this resolver
+ context 'with obj not set to nil' do
+ let(:obj) { build(:project) }
- it 'returns the project_runner runners' do
- is_expected.to contain_exactly(offline_project_runner, inactive_project_runner)
- end
- end
-
- context 'with "project_runner" and "active_runner" tags as comma-separated string' do
- let(:tag_list) { ['project_runner,active_runner'] }
-
- it 'returns the offline_project_runner runner' do
- is_expected.to contain_exactly(offline_project_runner)
- end
- end
-
- context 'with "active_runner" and "instance_runner" tags as array' do
- let(:tag_list) { %w[instance_runner active_runner] }
-
- it 'returns the offline_project_runner runner' do
- is_expected.to contain_exactly(instance_runner)
- end
+ it 'raises an error' do
+ expect { subject }.to raise_error(a_string_including('Unexpected parent type'))
end
end
- context 'when text is filtered' do
+ # Here we have a mocked part. We assume that all possible edge cases are covered in RunnersFinder spec. So we don't need to test them twice.
+ # Only thing we can do is to verify that args from the resolver is correctly transformed to params of the Finder and we return the Finder's result back.
+ describe 'Allowed query arguments' do
+ let(:finder) { instance_double(::Ci::RunnersFinder) }
let(:args) do
- { search: search_term }
- end
-
- context 'to "project"' do
- let(:search_term) { 'project' }
-
- it 'returns both project runners' do
- is_expected.to contain_exactly(inactive_project_runner, offline_project_runner)
- end
- end
-
- context 'to "group"' do
- let(:search_term) { 'group' }
-
- it 'returns group runner' do
- is_expected.to contain_exactly(group_runner)
- end
- end
-
- context 'to "defghi"' do
- let(:search_term) { 'defghi' }
-
- it 'returns runners containing term in token' do
- is_expected.to contain_exactly(offline_project_runner)
- end
+ {
+ status: 'active',
+ type: :instance_type,
+ tag_list: ['active_runner'],
+ search: 'abc',
+ sort: :contacted_asc
+ }
+ end
+
+ let(:expected_params) do
+ {
+ status_status: 'active',
+ type_type: :instance_type,
+ tag_name: ['active_runner'],
+ preload: { tag_name: nil },
+ search: 'abc',
+ sort: 'contacted_asc'
+ }
+ end
+
+ it 'calls RunnersFinder with expected arguments' do
+ allow(::Ci::RunnersFinder).to receive(:new).with(current_user: user, params: expected_params).once.and_return(finder)
+ allow(finder).to receive(:execute).once.and_return([:execute_return_value])
+
+ expect(subject.items.to_a).to eq([:execute_return_value])
end
end
end
diff --git a/spec/graphql/resolvers/concerns/resolves_pipelines_spec.rb b/spec/graphql/resolvers/concerns/resolves_pipelines_spec.rb
index 6f6855c8f84..865e892b12d 100644
--- a/spec/graphql/resolvers/concerns/resolves_pipelines_spec.rb
+++ b/spec/graphql/resolvers/concerns/resolves_pipelines_spec.rb
@@ -27,7 +27,7 @@ RSpec.describe ResolvesPipelines do
project.add_developer(current_user)
end
- it { is_expected.to have_graphql_arguments(:status, :ref, :sha) }
+ it { is_expected.to have_graphql_arguments(:status, :ref, :sha, :source) }
it 'finds all pipelines' do
expect(resolve_pipelines).to contain_exactly(pipeline, failed_pipeline, ref_pipeline, sha_pipeline)
@@ -45,6 +45,30 @@ RSpec.describe ResolvesPipelines do
expect(resolve_pipelines(sha: 'deadbeef')).to contain_exactly(sha_pipeline)
end
+ context 'filtering by source' do
+ let_it_be(:source_pipeline) { create(:ci_pipeline, project: project, source: 'web') }
+
+ context 'when `dast_view_scans` feature flag is disabled' do
+ before do
+ stub_feature_flags(dast_view_scans: false)
+ end
+
+ it 'does not filter by source' do
+ expect(resolve_pipelines(source: 'web')).to contain_exactly(pipeline, failed_pipeline, ref_pipeline, sha_pipeline, source_pipeline)
+ end
+ end
+
+ context 'when `dast_view_scans` feature flag is enabled' do
+ it 'does filter by source' do
+ expect(resolve_pipelines(source: 'web')).to contain_exactly(source_pipeline)
+ end
+
+ it 'returns all the pipelines' do
+ expect(resolve_pipelines).to contain_exactly(pipeline, failed_pipeline, ref_pipeline, sha_pipeline, source_pipeline)
+ end
+ end
+ end
+
it 'does not return any pipelines if the user does not have access' do
expect(resolve_pipelines({}, {})).to be_empty
end
diff --git a/spec/graphql/resolvers/group_resolver_spec.rb b/spec/graphql/resolvers/group_resolver_spec.rb
index a03e7854177..ed406d14772 100644
--- a/spec/graphql/resolvers/group_resolver_spec.rb
+++ b/spec/graphql/resolvers/group_resolver_spec.rb
@@ -20,10 +20,15 @@ RSpec.describe Resolvers::GroupResolver do
end
it 'resolves an unknown full_path to nil' do
- result = batch_sync { resolve_group('unknown/project') }
+ result = batch_sync { resolve_group('unknown/group') }
expect(result).to be_nil
end
+
+ it 'treats group full path as case insensitive' do
+ result = batch_sync { resolve_group(group1.full_path.upcase) }
+ expect(result).to eq group1
+ end
end
def resolve_group(full_path)
diff --git a/spec/graphql/resolvers/issues_resolver_spec.rb b/spec/graphql/resolvers/issues_resolver_spec.rb
index 6e187e57729..e992b2b04ae 100644
--- a/spec/graphql/resolvers/issues_resolver_spec.rb
+++ b/spec/graphql/resolvers/issues_resolver_spec.rb
@@ -6,6 +6,7 @@ RSpec.describe Resolvers::IssuesResolver do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
+ let_it_be(:reporter) { create(:user) }
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, group: group) }
@@ -19,6 +20,7 @@ RSpec.describe Resolvers::IssuesResolver do
let_it_be(:issue4) { create(:issue) }
let_it_be(:label1) { create(:label, project: project) }
let_it_be(:label2) { create(:label, project: project) }
+ let_it_be(:upvote_award) { create(:award_emoji, :upvote, user: current_user, awardable: issue1) }
specify do
expect(described_class).to have_nullable_graphql_type(Types::IssueType.connection_type)
@@ -27,6 +29,7 @@ RSpec.describe Resolvers::IssuesResolver do
context "with a project" do
before_all do
project.add_developer(current_user)
+ project.add_reporter(reporter)
create(:label_link, label: label1, target: issue1)
create(:label_link, label: label1, target: issue2)
create(:label_link, label: label2, target: issue2)
@@ -198,6 +201,27 @@ RSpec.describe Resolvers::IssuesResolver do
end
end
+ context 'filtering by reaction emoji' do
+ let_it_be(:downvoted_issue) { create(:issue, project: project) }
+ let_it_be(:downvote_award) { create(:award_emoji, :downvote, user: current_user, awardable: downvoted_issue) }
+
+ it 'filters by reaction emoji' do
+ expect(resolve_issues(my_reaction_emoji: upvote_award.name)).to contain_exactly(issue1)
+ end
+
+ it 'filters by reaction emoji wildcard "none"' do
+ expect(resolve_issues(my_reaction_emoji: 'none')).to contain_exactly(issue2)
+ end
+
+ it 'filters by reaction emoji wildcard "any"' do
+ expect(resolve_issues(my_reaction_emoji: 'any')).to contain_exactly(issue1, downvoted_issue)
+ end
+
+ it 'filters by negated reaction emoji' do
+ expect(resolve_issues(not: { my_reaction_emoji: downvote_award.name })).to contain_exactly(issue1, issue2)
+ end
+ end
+
context 'when searching issues' do
it 'returns correct issues' do
expect(resolve_issues(search: 'foo')).to contain_exactly(issue2)
@@ -235,6 +259,14 @@ RSpec.describe Resolvers::IssuesResolver do
it 'returns issues without the specified assignee_id' do
expect(resolve_issues(not: { assignee_id: [assignee.id] })).to contain_exactly(issue1)
end
+
+ context 'when filtering by negated author' do
+ let_it_be(:issue_by_reporter) { create(:issue, author: reporter, project: project, state: :opened) }
+
+ it 'returns issues without the specified author_username' do
+ expect(resolve_issues(not: { author_username: issue1.author.username })).to contain_exactly(issue_by_reporter)
+ end
+ end
end
describe 'sorting' do
@@ -382,6 +414,22 @@ RSpec.describe Resolvers::IssuesResolver do
end
end
end
+
+ context 'when sorting by title' do
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:issue1) { create(:issue, project: project, title: 'foo') }
+ let_it_be(:issue2) { create(:issue, project: project, title: 'bar') }
+ let_it_be(:issue3) { create(:issue, project: project, title: 'baz') }
+ let_it_be(:issue4) { create(:issue, project: project, title: 'Baz 2') }
+
+ it 'sorts issues ascending' do
+ expect(resolve_issues(sort: :title_asc).to_a).to eq [issue2, issue3, issue4, issue1]
+ end
+
+ it 'sorts issues descending' do
+ expect(resolve_issues(sort: :title_desc).to_a).to eq [issue1, issue4, issue3, issue2]
+ end
+ end
end
it 'returns issues user can see' do
diff --git a/spec/graphql/resolvers/merge_requests_resolver_spec.rb b/spec/graphql/resolvers/merge_requests_resolver_spec.rb
index 64ee0d4f9cc..a897acf7eba 100644
--- a/spec/graphql/resolvers/merge_requests_resolver_spec.rb
+++ b/spec/graphql/resolvers/merge_requests_resolver_spec.rb
@@ -294,16 +294,6 @@ RSpec.describe Resolvers::MergeRequestsResolver do
nils_last(mr.metrics.merged_at)
end
- context 'when label filter is given and the optimized_issuable_label_filter feature flag is off' do
- before do
- stub_feature_flags(optimized_issuable_label_filter: false)
- end
-
- it 'does not raise PG::GroupingError' do
- expect { resolve_mr(project, sort: :merged_at_desc, labels: %w[a b]) }.not_to raise_error
- end
- end
-
context 'when sorting by closed at' do
before do
merge_request_1.metrics.update!(latest_closed_at: 10.days.ago)
diff --git a/spec/graphql/resolvers/project_resolver_spec.rb b/spec/graphql/resolvers/project_resolver_spec.rb
index d0661c27b95..cd3fdc788e6 100644
--- a/spec/graphql/resolvers/project_resolver_spec.rb
+++ b/spec/graphql/resolvers/project_resolver_spec.rb
@@ -25,6 +25,11 @@ RSpec.describe Resolvers::ProjectResolver do
expect(result).to be_nil
end
+
+ it 'treats project full path as case insensitive' do
+ result = batch_sync { resolve_project(project1.full_path.upcase) }
+ expect(result).to eq project1
+ end
end
it 'does not increase complexity depending on number of load limits' do
diff --git a/spec/graphql/resolvers/users/groups_resolver_spec.rb b/spec/graphql/resolvers/users/groups_resolver_spec.rb
new file mode 100644
index 00000000000..0fdb6da5ae9
--- /dev/null
+++ b/spec/graphql/resolvers/users/groups_resolver_spec.rb
@@ -0,0 +1,106 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Resolvers::Users::GroupsResolver do
+ include GraphqlHelpers
+ include AdminModeHelper
+
+ describe '#resolve' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:guest_group) { create(:group, name: 'public guest', path: 'public-guest') }
+ let_it_be(:private_maintainer_group) { create(:group, :private, name: 'b private maintainer', path: 'b-private-maintainer') }
+ let_it_be(:public_developer_group) { create(:group, project_creation_level: nil, name: 'c public developer', path: 'c-public-developer') }
+ let_it_be(:public_maintainer_group) { create(:group, name: 'a public maintainer', path: 'a-public-maintainer') }
+
+ subject(:resolved_items) { resolve_groups(args: group_arguments, current_user: current_user, obj: resolver_object) }
+
+ let(:group_arguments) { {} }
+ let(:current_user) { user }
+ let(:resolver_object) { user }
+
+ before_all do
+ guest_group.add_guest(user)
+ private_maintainer_group.add_maintainer(user)
+ public_developer_group.add_developer(user)
+ public_maintainer_group.add_maintainer(user)
+ end
+
+ context 'when paginatable_namespace_drop_down_for_project_creation feature flag is disabled' do
+ before do
+ stub_feature_flags(paginatable_namespace_drop_down_for_project_creation: false)
+ end
+
+ it { is_expected.to be_nil }
+ end
+
+ context 'when resolver object is current user' do
+ context 'when permission is :create_projects' do
+ let(:group_arguments) { { permission_scope: :create_projects } }
+
+ specify do
+ is_expected.to match(
+ [
+ public_maintainer_group,
+ private_maintainer_group,
+ public_developer_group
+ ]
+ )
+ end
+ end
+
+ specify do
+ is_expected.to match(
+ [
+ public_maintainer_group,
+ private_maintainer_group,
+ public_developer_group,
+ guest_group
+ ]
+ )
+ end
+
+ context 'when search is provided' do
+ let(:group_arguments) { { search: 'maintainer' } }
+
+ specify do
+ is_expected.to match(
+ [
+ public_maintainer_group,
+ private_maintainer_group
+ ]
+ )
+ end
+ end
+ end
+
+ context 'when resolver object is different from current user' do
+ let(:current_user) { create(:user) }
+
+ it { is_expected.to be_nil }
+
+ context 'when current_user is admin' do
+ let(:current_user) { create(:user, :admin) }
+
+ before do
+ enable_admin_mode!(current_user)
+ end
+
+ specify do
+ is_expected.to match(
+ [
+ public_maintainer_group,
+ private_maintainer_group,
+ public_developer_group,
+ guest_group
+ ]
+ )
+ end
+ end
+ end
+ end
+
+ def resolve_groups(args:, current_user:, obj:)
+ resolve(described_class, args: args, ctx: { current_user: current_user }, obj: obj)&.items
+ end
+end
diff --git a/spec/graphql/types/ci/job_type_spec.rb b/spec/graphql/types/ci/job_type_spec.rb
index 54fe0c4b707..e95a7da4fe5 100644
--- a/spec/graphql/types/ci/job_type_spec.rb
+++ b/spec/graphql/types/ci/job_type_spec.rb
@@ -4,7 +4,6 @@ require 'spec_helper'
RSpec.describe Types::Ci::JobType do
specify { expect(described_class.graphql_name).to eq('CiJob') }
- specify { expect(described_class).to require_graphql_authorizations(:read_commit_status) }
specify { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Ci::Job) }
it 'exposes the expected fields' do
diff --git a/spec/graphql/types/customer_relations/contact_type_spec.rb b/spec/graphql/types/customer_relations/contact_type_spec.rb
new file mode 100644
index 00000000000..a51ee705fb0
--- /dev/null
+++ b/spec/graphql/types/customer_relations/contact_type_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['CustomerRelationsContact'] do
+ let(:fields) { %i[id organization first_name last_name phone email description created_at updated_at] }
+
+ it { expect(described_class.graphql_name).to eq('CustomerRelationsContact') }
+ it { expect(described_class).to have_graphql_fields(fields) }
+ it { expect(described_class).to require_graphql_authorizations(:read_contact) }
+end
diff --git a/spec/graphql/types/customer_relations/organization_type_spec.rb b/spec/graphql/types/customer_relations/organization_type_spec.rb
new file mode 100644
index 00000000000..2562748477c
--- /dev/null
+++ b/spec/graphql/types/customer_relations/organization_type_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['CustomerRelationsOrganization'] do
+ let(:fields) { %i[id name default_rate description created_at updated_at] }
+
+ it { expect(described_class.graphql_name).to eq('CustomerRelationsOrganization') }
+ it { expect(described_class).to have_graphql_fields(fields) }
+ it { expect(described_class).to require_graphql_authorizations(:read_organization) }
+end
diff --git a/spec/graphql/types/dependency_proxy/blob_type_spec.rb b/spec/graphql/types/dependency_proxy/blob_type_spec.rb
new file mode 100644
index 00000000000..e1c8471975e
--- /dev/null
+++ b/spec/graphql/types/dependency_proxy/blob_type_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['DependencyProxyBlob'] do
+ it 'includes dependency proxy blob fields' do
+ expected_fields = %w[
+ file_name size created_at updated_at
+ ]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/dependency_proxy/group_setting_type_spec.rb b/spec/graphql/types/dependency_proxy/group_setting_type_spec.rb
new file mode 100644
index 00000000000..7c6d7b8aece
--- /dev/null
+++ b/spec/graphql/types/dependency_proxy/group_setting_type_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['DependencyProxySetting'] do
+ it 'includes dependency proxy blob fields' do
+ expected_fields = %w[
+ enabled
+ ]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/dependency_proxy/image_ttl_group_policy_type_spec.rb b/spec/graphql/types/dependency_proxy/image_ttl_group_policy_type_spec.rb
new file mode 100644
index 00000000000..46347e0434f
--- /dev/null
+++ b/spec/graphql/types/dependency_proxy/image_ttl_group_policy_type_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['DependencyProxyImageTtlGroupPolicy'] do
+ it { expect(described_class.graphql_name).to eq('DependencyProxyImageTtlGroupPolicy') }
+
+ it { expect(described_class.description).to eq('Group-level Dependency Proxy TTL policy settings') }
+
+ it { expect(described_class).to require_graphql_authorizations(:read_dependency_proxy) }
+
+ it 'includes dependency proxy image ttl policy fields' do
+ expected_fields = %w[enabled ttl created_at updated_at]
+
+ expect(described_class).to have_graphql_fields(*expected_fields).only
+ end
+end
diff --git a/spec/graphql/types/dependency_proxy/manifest_type_spec.rb b/spec/graphql/types/dependency_proxy/manifest_type_spec.rb
new file mode 100644
index 00000000000..18cc89adfcb
--- /dev/null
+++ b/spec/graphql/types/dependency_proxy/manifest_type_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['DependencyProxyManifest'] do
+ it 'includes dependency proxy manifest fields' do
+ expected_fields = %w[
+ file_name image_name size created_at updated_at digest
+ ]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/group_type_spec.rb b/spec/graphql/types/group_type_spec.rb
index 33250f8e6af..dca2c930eea 100644
--- a/spec/graphql/types/group_type_spec.rb
+++ b/spec/graphql/types/group_type_spec.rb
@@ -18,7 +18,11 @@ RSpec.describe GitlabSchema.types['Group'] do
two_factor_grace_period auto_devops_enabled emails_disabled
mentions_disabled parent boards milestones group_members
merge_requests container_repositories container_repositories_count
- packages shared_runners_setting timelogs
+ packages dependency_proxy_setting dependency_proxy_manifests
+ dependency_proxy_blobs dependency_proxy_image_count
+ dependency_proxy_blob_count dependency_proxy_total_size
+ dependency_proxy_image_prefix dependency_proxy_image_ttl_policy
+ shared_runners_setting timelogs organizations contacts
]
expect(described_class).to include_graphql_fields(*expected_fields)
diff --git a/spec/graphql/types/issue_type_spec.rb b/spec/graphql/types/issue_type_spec.rb
index b0aa11ee5ad..559f347810b 100644
--- a/spec/graphql/types/issue_type_spec.rb
+++ b/spec/graphql/types/issue_type_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe GitlabSchema.types['Issue'] do
it 'has specific fields' do
fields = %i[id iid title description state reference author assignees updated_by participants labels milestone due_date
- confidential discussion_locked upvotes downvotes merge_requests_count user_notes_count user_discussions_count web_path web_url relative_position
+ confidential hidden discussion_locked upvotes downvotes merge_requests_count user_notes_count user_discussions_count web_path web_url relative_position
emails_disabled subscribed time_estimate total_time_spent human_time_estimate human_total_time_spent closed_at created_at updated_at task_completion_status
design_collection alert_management_alert severity current_user_todos moved moved_to
create_note_email timelogs project_id]
@@ -201,4 +201,54 @@ RSpec.describe GitlabSchema.types['Issue'] do
end
end
end
+
+ describe 'hidden', :enable_admin_mode do
+ let_it_be(:admin) { create(:user, :admin)}
+ let_it_be(:banned_user) { create(:user, :banned) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:hidden_issue) { create(:issue, project: project, author: banned_user) }
+ let_it_be(:visible_issue) { create(:issue, project: project, author: user) }
+
+ let(:issue) { hidden_issue }
+ let(:query) do
+ %(
+ query {
+ project(fullPath: "#{project.full_path}") {
+ issue(iid: "#{issue.iid}") {
+ hidden
+ }
+ }
+ }
+ )
+ end
+
+ subject { GitlabSchema.execute(query, context: { current_user: admin }).as_json }
+
+ context 'when `ban_user_feature_flag` is enabled' do
+ context 'when issue is hidden' do
+ it 'returns `true`' do
+ expect(subject.dig('data', 'project', 'issue', 'hidden')).to eq(true)
+ end
+ end
+
+ context 'when issue is visible' do
+ let(:issue) { visible_issue }
+
+ it 'returns `false`' do
+ expect(subject.dig('data', 'project', 'issue', 'hidden')).to eq(false)
+ end
+ end
+ end
+
+ context 'when `ban_user_feature_flag` is disabled' do
+ before do
+ stub_feature_flags(ban_user_feature_flag: false)
+ end
+
+ it 'returns `nil`' do
+ expect(subject.dig('data', 'project', 'issue', 'hidden')).to be_nil
+ end
+ end
+ end
end
diff --git a/spec/graphql/types/merge_requests/reviewer_type_spec.rb b/spec/graphql/types/merge_requests/reviewer_type_spec.rb
index 4ede8e5788f..4d357a922f8 100644
--- a/spec/graphql/types/merge_requests/reviewer_type_spec.rb
+++ b/spec/graphql/types/merge_requests/reviewer_type_spec.rb
@@ -33,6 +33,7 @@ RSpec.describe GitlabSchema.types['MergeRequestReviewer'] do
merge_request_interaction
namespace
timelogs
+ groups
]
expect(described_class).to have_graphql_fields(*expected_fields)
diff --git a/spec/graphql/types/project_statistics_type_spec.rb b/spec/graphql/types/project_statistics_type_spec.rb
index 407ce82e73a..f515907b6a8 100644
--- a/spec/graphql/types/project_statistics_type_spec.rb
+++ b/spec/graphql/types/project_statistics_type_spec.rb
@@ -6,6 +6,6 @@ RSpec.describe GitlabSchema.types['ProjectStatistics'] do
it 'has all the required fields' do
expect(described_class).to have_graphql_fields(:storage_size, :repository_size, :lfs_objects_size,
:build_artifacts_size, :packages_size, :commit_count,
- :wiki_size, :snippets_size, :uploads_size)
+ :wiki_size, :snippets_size, :pipeline_artifacts_size, :uploads_size)
end
end
diff --git a/spec/graphql/types/terraform/state_version_type_spec.rb b/spec/graphql/types/terraform/state_version_type_spec.rb
index 18f869e4f1f..b015a2045da 100644
--- a/spec/graphql/types/terraform/state_version_type_spec.rb
+++ b/spec/graphql/types/terraform/state_version_type_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe GitlabSchema.types['TerraformStateVersion'] do
+ include GraphqlHelpers
+
it { expect(described_class.graphql_name).to eq('TerraformStateVersion') }
it { expect(described_class).to require_graphql_authorizations(:read_terraform_state) }
@@ -19,4 +21,60 @@ RSpec.describe GitlabSchema.types['TerraformStateVersion'] do
it { expect(described_class.fields['createdAt'].type).to be_non_null }
it { expect(described_class.fields['updatedAt'].type).to be_non_null }
end
+
+ describe 'query' do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:terraform_state) { create(:terraform_state, :with_version, :locked, project: project) }
+
+ before do
+ project.add_developer(user)
+ end
+
+ let(:query) do
+ <<~GRAPHQL
+ query {
+ project(fullPath: "#{project.full_path}") {
+ terraformState(name: "#{terraform_state.name}") {
+ latestVersion {
+ id
+ job {
+ name
+ }
+ }
+ }
+ }
+ }
+ GRAPHQL
+ end
+
+ subject(:execute) { GitlabSchema.execute(query, context: { current_user: user }).as_json }
+
+ shared_examples 'returning latest version' do
+ it 'returns latest version of terraform state' do
+ expect(execute.dig('data', 'project', 'terraformState', 'latestVersion', 'id')).to eq(
+ global_id_of(terraform_state.latest_version)
+ )
+ end
+ end
+
+ it_behaves_like 'returning latest version'
+
+ it 'returns job of the latest version' do
+ expect(execute.dig('data', 'project', 'terraformState', 'latestVersion', 'job')).to be_present
+ end
+
+ context 'when user cannot read jobs' do
+ before do
+ allow(Ability).to receive(:allowed?).and_call_original
+ allow(Ability).to receive(:allowed?).with(user, :read_commit_status, terraform_state.latest_version).and_return(false)
+ end
+
+ it_behaves_like 'returning latest version'
+
+ it 'does not return job of the latest version' do
+ expect(execute.dig('data', 'project', 'terraformState', 'latestVersion', 'job')).not_to be_present
+ end
+ end
+ end
end
diff --git a/spec/graphql/types/user_type_spec.rb b/spec/graphql/types/user_type_spec.rb
index 363ccdf88b7..0bad8c95ba2 100644
--- a/spec/graphql/types/user_type_spec.rb
+++ b/spec/graphql/types/user_type_spec.rb
@@ -38,6 +38,7 @@ RSpec.describe GitlabSchema.types['User'] do
callouts
namespace
timelogs
+ groups
]
expect(described_class).to have_graphql_fields(*expected_fields)
diff --git a/spec/helpers/analytics/cycle_analytics_helper_spec.rb b/spec/helpers/analytics/cycle_analytics_helper_spec.rb
new file mode 100644
index 00000000000..d906646e25c
--- /dev/null
+++ b/spec/helpers/analytics/cycle_analytics_helper_spec.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+require "spec_helper"
+
+RSpec.describe Analytics::CycleAnalyticsHelper do
+ describe '#cycle_analytics_initial_data' do
+ let(:user) { create(:user, name: 'fake user', username: 'fake_user') }
+ let(:image_path_keys) { [:empty_state_svg_path, :no_data_svg_path, :no_access_svg_path] }
+ let(:api_path_keys) { [:milestones_path, :labels_path] }
+ let(:additional_data_keys) { [:full_path, :group_id, :group_path, :project_id, :request_path] }
+ let(:group) { create(:group) }
+
+ subject(:cycle_analytics_data) { helper.cycle_analytics_initial_data(project, group) }
+
+ before do
+ project.add_maintainer(user)
+ end
+
+ context 'when a group is present' do
+ let(:project) { create(:project, group: group) }
+
+ it "sets the correct data keys" do
+ expect(cycle_analytics_data.keys)
+ .to match_array(api_path_keys + image_path_keys + additional_data_keys)
+ end
+
+ it "sets group paths" do
+ expect(cycle_analytics_data)
+ .to include({
+ full_path: project.full_path,
+ group_path: "/#{project.namespace.name}",
+ group_id: project.namespace.id,
+ request_path: "/#{project.full_path}/-/value_stream_analytics",
+ milestones_path: "/groups/#{group.name}/-/milestones.json",
+ labels_path: "/groups/#{group.name}/-/labels.json"
+ })
+ end
+ end
+
+ context 'when a group is not present' do
+ let(:group) { nil }
+ let(:project) { create(:project) }
+
+ it "sets the correct data keys" do
+ expect(cycle_analytics_data.keys)
+ .to match_array(image_path_keys + api_path_keys + additional_data_keys)
+ end
+
+ it "sets project name space paths" do
+ expect(cycle_analytics_data)
+ .to include({
+ full_path: project.full_path,
+ group_path: project.namespace.path,
+ group_id: project.namespace.id,
+ request_path: "/#{project.full_path}/-/value_stream_analytics",
+ milestones_path: "/#{project.full_path}/-/milestones.json",
+ labels_path: "/#{project.full_path}/-/labels.json"
+ })
+ end
+ end
+ end
+end
diff --git a/spec/helpers/application_settings_helper_spec.rb b/spec/helpers/application_settings_helper_spec.rb
index 6d51d85fd64..ef5f6931d02 100644
--- a/spec/helpers/application_settings_helper_spec.rb
+++ b/spec/helpers/application_settings_helper_spec.rb
@@ -284,4 +284,10 @@ RSpec.describe ApplicationSettingsHelper do
end
end
end
+
+ describe '#sidekiq_job_limiter_modes_for_select' do
+ subject { helper.sidekiq_job_limiter_modes_for_select }
+
+ it { is_expected.to eq([%w(Track track), %w(Compress compress)]) }
+ end
end
diff --git a/spec/helpers/blob_helper_spec.rb b/spec/helpers/blob_helper_spec.rb
index c48d609836d..efcb8125f68 100644
--- a/spec/helpers/blob_helper_spec.rb
+++ b/spec/helpers/blob_helper_spec.rb
@@ -92,6 +92,30 @@ RSpec.describe BlobHelper do
end
end
+ describe "#relative_raw_path" do
+ include FakeBlobHelpers
+
+ let_it_be(:project) { create(:project) }
+
+ before do
+ assign(:project, project)
+ end
+
+ [
+ %w[/file.md /-/raw/main/],
+ %w[/test/file.md /-/raw/main/test/],
+ %w[/another/test/file.md /-/raw/main/another/test/]
+ ].each do |file_path, expected_path|
+ it "pointing from '#{file_path}' to '#{expected_path}'" do
+ blob = fake_blob(path: file_path)
+ assign(:blob, blob)
+ assign(:id, "main#{blob.path}")
+ assign(:path, blob.path)
+
+ expect(helper.parent_dir_raw_path).to eq "/#{project.full_path}#{expected_path}"
+ end
+ end
+ end
context 'viewer related' do
include FakeBlobHelpers
diff --git a/spec/helpers/ci/pipeline_editor_helper_spec.rb b/spec/helpers/ci/pipeline_editor_helper_spec.rb
index 3183a0a2394..874937bc4ce 100644
--- a/spec/helpers/ci/pipeline_editor_helper_spec.rb
+++ b/spec/helpers/ci/pipeline_editor_helper_spec.rb
@@ -42,7 +42,6 @@ RSpec.describe Ci::PipelineEditorHelper do
"ci-config-path": project.ci_config_path_or_default,
"ci-examples-help-page-path" => help_page_path('ci/examples/index'),
"ci-help-page-path" => help_page_path('ci/index'),
- "commit-sha" => project.commit.sha,
"default-branch" => project.default_branch_or_main,
"empty-state-illustration-path" => 'foo',
"initial-branch-name" => nil,
@@ -69,7 +68,6 @@ RSpec.describe Ci::PipelineEditorHelper do
"ci-config-path": project.ci_config_path_or_default,
"ci-examples-help-page-path" => help_page_path('ci/examples/index'),
"ci-help-page-path" => help_page_path('ci/index'),
- "commit-sha" => '',
"default-branch" => project.default_branch_or_main,
"empty-state-illustration-path" => 'foo',
"initial-branch-name" => nil,
@@ -97,10 +95,7 @@ RSpec.describe Ci::PipelineEditorHelper do
end
it 'returns correct values' do
- latest_feature_sha = project.repository.commit('feature').sha
-
expect(pipeline_editor_data['initial-branch-name']).to eq('feature')
- expect(pipeline_editor_data['commit-sha']).to eq(latest_feature_sha)
end
end
end
diff --git a/spec/helpers/ci/runners_helper_spec.rb b/spec/helpers/ci/runners_helper_spec.rb
index 40927d44e24..0f15f8be0a9 100644
--- a/spec/helpers/ci/runners_helper_spec.rb
+++ b/spec/helpers/ci/runners_helper_spec.rb
@@ -88,6 +88,19 @@ RSpec.describe Ci::RunnersHelper do
end
end
+ describe '#group_runners_data_attributes' do
+ let(:group) { create(:group) }
+
+ it 'returns group data to render a runner list' do
+ data = group_runners_data_attributes(group)
+
+ expect(data[:registration_token]).to eq(group.runners_token)
+ expect(data[:group_id]).to eq(group.id)
+ expect(data[:group_full_path]).to eq(group.full_path)
+ expect(data[:runner_install_help_page]).to eq('https://docs.gitlab.com/runner/install/')
+ end
+ end
+
describe '#toggle_shared_runners_settings_data' do
let_it_be(:group) { create(:group) }
diff --git a/spec/helpers/environment_helper_spec.rb b/spec/helpers/environment_helper_spec.rb
index 0eecae32cc1..49937a3b53a 100644
--- a/spec/helpers/environment_helper_spec.rb
+++ b/spec/helpers/environment_helper_spec.rb
@@ -43,7 +43,6 @@ RSpec.describe EnvironmentHelper do
external_url: environment.external_url,
can_update_environment: true,
can_destroy_environment: true,
- can_read_environment: true,
can_stop_environment: true,
can_admin_environment: true,
environment_metrics_path: environment_metrics_path(environment),
diff --git a/spec/helpers/groups_helper_spec.rb b/spec/helpers/groups_helper_spec.rb
index 42da1cb71f1..825d5236b5d 100644
--- a/spec/helpers/groups_helper_spec.rb
+++ b/spec/helpers/groups_helper_spec.rb
@@ -19,18 +19,6 @@ RSpec.describe GroupsHelper do
end
end
- describe '#group_dependency_proxy_image_prefix' do
- let_it_be(:group) { build_stubbed(:group, path: 'GroupWithUPPERcaseLetters') }
-
- it 'converts uppercase letters to lowercase' do
- expect(group_dependency_proxy_image_prefix(group)).to end_with("/groupwithuppercaseletters#{DependencyProxy::URL_SUFFIX}")
- end
-
- it 'removes the protocol' do
- expect(group_dependency_proxy_image_prefix(group)).not_to include('http')
- end
- end
-
describe '#group_lfs_status' do
let_it_be_with_reload(:group) { create(:group) }
let_it_be_with_reload(:project) { create(:project, namespace_id: group.id) }
@@ -267,61 +255,6 @@ RSpec.describe GroupsHelper do
end
end
- describe '#group_sidebar_links' do
- let_it_be(:group) { create(:group, :public) }
- let_it_be(:user) { create(:user) }
-
- before do
- group.add_owner(user)
- allow(helper).to receive(:current_user) { user }
- allow(helper).to receive(:can?) { |*args| Ability.allowed?(*args) }
- helper.instance_variable_set(:@group, group)
- end
-
- it 'returns all the expected links' do
- links = [
- :overview, :activity, :issues, :labels, :milestones, :merge_requests,
- :runners, :group_members, :settings
- ]
-
- expect(helper.group_sidebar_links).to include(*links)
- end
-
- it 'excludes runners when the user cannot admin the group' do
- expect(helper).to receive(:current_user) { user }
- # TODO Proper policies, such as `read_group_runners, should be implemented per
- # See https://gitlab.com/gitlab-org/gitlab/-/issues/334802
- expect(helper).to receive(:can?).twice.with(user, :admin_group, group) { false }
-
- expect(helper.group_sidebar_links).not_to include(:runners)
- end
-
- it 'excludes runners when the feature "runner_list_group_view_vue_ui" is disabled' do
- stub_feature_flags(runner_list_group_view_vue_ui: false)
-
- expect(helper.group_sidebar_links).not_to include(:runners)
- end
-
- it 'excludes settings when the user can admin the group' do
- expect(helper).to receive(:current_user) { user }
- expect(helper).to receive(:can?).twice.with(user, :admin_group, group) { false }
-
- expect(helper.group_sidebar_links).not_to include(:settings)
- end
-
- it 'excludes cross project features when the user cannot read cross project' do
- cross_project_features = [:activity, :issues, :labels, :milestones,
- :merge_requests]
-
- allow(Ability).to receive(:allowed?).and_call_original
- cross_project_features.each do |feature|
- expect(Ability).to receive(:allowed?).with(user, "read_group_#{feature}".to_sym, group) { false }
- end
-
- expect(helper.group_sidebar_links).not_to include(*cross_project_features)
- end
- end
-
describe '#parent_group_options' do
let_it_be(:current_user) { create(:user) }
let_it_be(:group) { create(:group, name: 'group') }
@@ -442,67 +375,6 @@ RSpec.describe GroupsHelper do
end
end
- describe '#show_invite_banner?' do
- let_it_be(:current_user) { create(:user) }
- let_it_be_with_refind(:group) { create(:group) }
- let_it_be(:subgroup) { create(:group, parent: group) }
- let_it_be(:users) { [current_user, create(:user)] }
-
- before do
- allow(helper).to receive(:current_user) { current_user }
- allow(helper).to receive(:can?).with(current_user, :admin_group, group).and_return(can_admin_group)
- allow(helper).to receive(:can?).with(current_user, :admin_group, subgroup).and_return(can_admin_group)
- users.take(group_members_count).each { |user| group.add_guest(user) }
- end
-
- using RSpec::Parameterized::TableSyntax
-
- where(:can_admin_group, :group_members_count, :expected_result) do
- true | 1 | true
- false | 1 | false
- true | 2 | false
- false | 2 | false
- end
-
- with_them do
- context 'for a parent group' do
- subject { helper.show_invite_banner?(group) }
-
- context 'when the group was just created' do
- before do
- flash[:notice] = "Group #{group.name} was successfully created"
- end
-
- it { is_expected.to be_falsey }
- end
-
- context 'when no flash message' do
- it 'returns the expected result' do
- expect(subject).to eq(expected_result)
- end
- end
- end
-
- context 'for a subgroup' do
- subject { helper.show_invite_banner?(subgroup) }
-
- context 'when the subgroup was just created' do
- before do
- flash[:notice] = "Group #{subgroup.name} was successfully created"
- end
-
- it { is_expected.to be_falsey }
- end
-
- context 'when no flash message' do
- it 'returns the expected result' do
- expect(subject).to eq(expected_result)
- end
- end
- end
- end
- end
-
describe '#render_setting_to_allow_project_access_token_creation?' do
let_it_be(:current_user) { create(:user) }
let_it_be(:parent) { create(:group) }
@@ -541,4 +413,10 @@ RSpec.describe GroupsHelper do
expect(helper.can_admin_group_member?(group)).to be(false)
end
end
+
+ describe '#localized_jobs_to_be_done_choices' do
+ it 'has a translation for all `jobs_to_be_done` values' do
+ expect(localized_jobs_to_be_done_choices.keys).to match_array(NamespaceSetting.jobs_to_be_dones.keys)
+ end
+ end
end
diff --git a/spec/helpers/issuables_description_templates_helper_spec.rb b/spec/helpers/issuables_description_templates_helper_spec.rb
index 638dd201fc8..55649e9087a 100644
--- a/spec/helpers/issuables_description_templates_helper_spec.rb
+++ b/spec/helpers/issuables_description_templates_helper_spec.rb
@@ -56,32 +56,17 @@ RSpec.describe IssuablesDescriptionTemplatesHelper, :clean_gitlab_redis_cache do
let(:templates) do
{
"" => [
- { name: "another_issue_template", id: "another_issue_template" },
- { name: "custom_issue_template", id: "custom_issue_template" }
+ { name: "another_issue_template", id: "another_issue_template", project_id: project.id },
+ { name: "custom_issue_template", id: "custom_issue_template", project_id: project.id }
]
}
end
- it 'returns project templates only' do
+ it 'returns project templates' do
expect(helper.issuable_templates_names(Issue.new)).to eq(%w[another_issue_template custom_issue_template])
end
end
- context 'without matching project templates' do
- let(:templates) do
- {
- "Project Templates" => [
- { name: "another_issue_template", id: "another_issue_template", project_id: non_existing_record_id },
- { name: "custom_issue_template", id: "custom_issue_template", project_id: non_existing_record_id }
- ]
- }
- end
-
- it 'returns empty array' do
- expect(helper.issuable_templates_names(Issue.new)).to eq([])
- end
- end
-
context 'when there are not templates in the project' do
let(:templates) { {} }
diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb
index ecaee03eeea..3eb3c73cfcc 100644
--- a/spec/helpers/issuables_helper_spec.rb
+++ b/spec/helpers/issuables_helper_spec.rb
@@ -123,7 +123,7 @@ RSpec.describe IssuablesHelper do
end
describe '#issuables_state_counter_text' do
- let(:user) { create(:user) }
+ let_it_be(:user) { create(:user) }
describe 'state text' do
context 'when number of issuables can be generated' do
@@ -159,6 +159,38 @@ RSpec.describe IssuablesHelper do
.to eq('<span>All</span>')
end
end
+
+ context 'when count is over the threshold' do
+ let_it_be(:group) { create(:group) }
+
+ before do
+ allow(helper).to receive(:issuables_count_for_state).and_return(1100)
+ allow(helper).to receive(:parent).and_return(group)
+ stub_const("Gitlab::IssuablesCountForState::THRESHOLD", 1000)
+ end
+
+ context 'when feature flag cached_issues_state_count is disabled' do
+ before do
+ stub_feature_flags(cached_issues_state_count: false)
+ end
+
+ it 'returns complete count' do
+ expect(helper.issuables_state_counter_text(:issues, :opened, true))
+ .to eq('<span>Open</span> <span class="badge badge-muted badge-pill gl-badge gl-tab-counter-badge sm">1,100</span>')
+ end
+ end
+
+ context 'when feature flag cached_issues_state_count is enabled' do
+ before do
+ stub_feature_flags(cached_issues_state_count: true)
+ end
+
+ it 'returns truncated count' do
+ expect(helper.issuables_state_counter_text(:issues, :opened, true))
+ .to eq('<span>Open</span> <span class="badge badge-muted badge-pill gl-badge gl-tab-counter-badge sm">1.1k</span>')
+ end
+ end
+ end
end
end
@@ -285,7 +317,8 @@ RSpec.describe IssuablesHelper do
initialDescriptionText: 'issue text',
initialTaskStatus: '0 of 0 tasks completed',
issueType: 'issue',
- iid: issue.iid.to_s
+ iid: issue.iid.to_s,
+ isHidden: false
}
expect(helper.issuable_initial_data(issue)).to match(hash_including(expected_data))
end
diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb
index 9cf3808ab72..f5f26d306fb 100644
--- a/spec/helpers/issues_helper_spec.rb
+++ b/spec/helpers/issues_helper_spec.rb
@@ -284,7 +284,7 @@ RSpec.describe IssuesHelper do
iid: issue.iid,
is_issue_author: 'false',
issue_type: 'issue',
- new_issue_path: new_project_issue_path(project),
+ new_issue_path: new_project_issue_path(project, { issue: { description: "Related to \##{issue.iid}.\n\n" } }),
project_path: project.full_path,
report_abuse_path: new_abuse_report_path(user_id: issue.author.id, ref_url: issue_url(issue)),
submit_as_spam_path: mark_as_spam_project_issue_path(project, issue)
@@ -310,21 +310,21 @@ RSpec.describe IssuesHelper do
can_bulk_update: 'true',
can_edit: 'true',
can_import_issues: 'true',
- email: current_user&.notification_email,
+ email: current_user&.notification_email_or_default,
emails_help_page_path: help_page_path('development/emails', anchor: 'email-namespace'),
empty_state_svg_path: '#',
export_csv_path: export_csv_project_issues_path(project),
- has_project_issues: project_issues(project).exists?.to_s,
+ full_path: project.full_path,
+ has_any_issues: project_issues(project).exists?.to_s,
import_csv_issues_path: '#',
initial_email: project.new_issuable_address(current_user, 'issue'),
+ is_project: 'true',
is_signed_in: current_user.present?.to_s,
- issues_path: project_issues_path(project),
jira_integration_path: help_page_url('integration/jira/issues', anchor: 'view-jira-issues'),
markdown_help_path: help_page_path('user/markdown'),
max_attachment_size: number_to_human_size(Gitlab::CurrentSettings.max_attachment_size.megabytes),
new_issue_path: new_project_issue_path(project, issue: { milestone_id: finder.milestones.first.id }),
project_import_jira_path: project_import_jira_path(project),
- project_path: project.full_path,
quick_actions_help_path: help_page_path('user/project/quick_actions'),
reset_path: new_issuable_address_project_path(project, issuable_type: 'issue'),
rss_path: '#',
@@ -332,11 +332,11 @@ RSpec.describe IssuesHelper do
sign_in_path: new_user_session_path
}
- expect(helper.issues_list_data(project, current_user, finder)).to include(expected)
+ expect(helper.project_issues_list_data(project, current_user, finder)).to include(expected)
end
end
- describe '#issues_list_data' do
+ describe '#project_issues_list_data' do
context 'when user is signed in' do
it_behaves_like 'issues list data' do
let(:current_user) { double.as_null_object }
@@ -350,6 +350,33 @@ RSpec.describe IssuesHelper do
end
end
+ describe '#group_issues_list_data' do
+ let(:group) { create(:group) }
+ let(:current_user) { double.as_null_object }
+ let(:issues) { [] }
+
+ it 'returns expected result' do
+ allow(helper).to receive(:current_user).and_return(current_user)
+ allow(helper).to receive(:can?).and_return(true)
+ allow(helper).to receive(:image_path).and_return('#')
+ allow(helper).to receive(:url_for).and_return('#')
+
+ expected = {
+ autocomplete_award_emojis_path: autocomplete_award_emojis_path,
+ calendar_path: '#',
+ empty_state_svg_path: '#',
+ full_path: group.full_path,
+ has_any_issues: issues.to_a.any?.to_s,
+ is_signed_in: current_user.present?.to_s,
+ jira_integration_path: help_page_url('integration/jira/issues', anchor: 'view-jira-issues'),
+ rss_path: '#',
+ sign_in_path: new_user_session_path
+ }
+
+ expect(helper.group_issues_list_data(group, current_user, issues)).to include(expected)
+ end
+ end
+
describe '#issue_manual_ordering_class' do
context 'when sorting by relative position' do
before do
@@ -410,4 +437,55 @@ RSpec.describe IssuesHelper do
end
end
end
+
+ describe '#issue_hidden?' do
+ context 'when issue is hidden' do
+ let_it_be(:banned_user) { build(:user, :banned) }
+ let_it_be(:hidden_issue) { build(:issue, author: banned_user) }
+
+ context 'when `ban_user_feature_flag` feature flag is enabled' do
+ it 'returns `true`' do
+ expect(helper.issue_hidden?(hidden_issue)).to eq(true)
+ end
+ end
+
+ context 'when `ban_user_feature_flag` feature flag is disabled' do
+ before do
+ stub_feature_flags(ban_user_feature_flag: false)
+ end
+
+ it 'returns `false`' do
+ expect(helper.issue_hidden?(hidden_issue)).to eq(false)
+ end
+ end
+ end
+
+ context 'when issue is not hidden' do
+ it 'returns `false`' do
+ expect(helper.issue_hidden?(issue)).to eq(false)
+ end
+ end
+ end
+
+ describe '#hidden_issue_icon' do
+ let_it_be(:banned_user) { build(:user, :banned) }
+ let_it_be(:hidden_issue) { build(:issue, author: banned_user) }
+ let_it_be(:mock_svg) { '<svg></svg>'.html_safe }
+
+ before do
+ allow(helper).to receive(:sprite_icon).and_return(mock_svg)
+ end
+
+ context 'when issue is hidden' do
+ it 'returns icon with tooltip' do
+ expect(helper.hidden_issue_icon(hidden_issue)).to eq("<span class=\"has-tooltip\" title=\"This issue is hidden because its author has been banned\">#{mock_svg}</span>")
+ end
+ end
+
+ context 'when issue is not hidden' do
+ it 'returns `nil`' do
+ expect(helper.hidden_issue_icon(issue)).to be_nil
+ end
+ end
+ end
end
diff --git a/spec/helpers/learn_gitlab_helper_spec.rb b/spec/helpers/learn_gitlab_helper_spec.rb
index cf0d329c36f..1159fd96d59 100644
--- a/spec/helpers/learn_gitlab_helper_spec.rb
+++ b/spec/helpers/learn_gitlab_helper_spec.rb
@@ -53,7 +53,7 @@ RSpec.describe LearnGitlabHelper do
end
end
- describe '.learn_gitlab_experiment_enabled?' do
+ describe '.learn_gitlab_enabled?' do
using RSpec::Parameterized::TableSyntax
let_it_be(:user) { create(:user) }
@@ -61,19 +61,16 @@ RSpec.describe LearnGitlabHelper do
let(:params) { { namespace_id: project.namespace.to_param, project_id: project } }
- subject { helper.learn_gitlab_experiment_enabled?(project) }
+ subject { helper.learn_gitlab_enabled?(project) }
- where(:experiment_a, :experiment_b, :onboarding, :learn_gitlab_available, :result) do
- true | false | true | true | true
- false | true | true | true | true
- false | false | true | true | false
- true | true | true | false | false
- true | true | false | true | false
+ where(:onboarding, :learn_gitlab_available, :result) do
+ true | true | true
+ true | false | false
+ false | true | false
end
with_them do
before do
- stub_experiment_for_subject(learn_gitlab_a: experiment_a, learn_gitlab_b: experiment_b)
allow(OnboardingProgress).to receive(:onboarding?).with(project.namespace).and_return(onboarding)
allow_next(LearnGitlab::Project, user).to receive(:available?).and_return(learn_gitlab_available)
end
@@ -88,10 +85,6 @@ RSpec.describe LearnGitlabHelper do
end
context 'when not signed in' do
- before do
- stub_experiment_for_subject(learn_gitlab_a: true, learn_gitlab_b: true)
- end
-
it { is_expected.to eq(false) }
end
end
@@ -106,41 +99,4 @@ RSpec.describe LearnGitlabHelper do
expect(sections.values.map { |section| section.keys }).to eq([[:svg]] * 3)
end
end
-
- describe '.learn_gitlab_experiment_tracking_category' do
- using RSpec::Parameterized::TableSyntax
-
- let_it_be(:user) { create(:user) }
-
- subject { helper.learn_gitlab_experiment_tracking_category }
-
- where(:experiment_a, :experiment_b, :result) do
- false | false | nil
- false | true | 'Growth::Activation::Experiment::LearnGitLabB'
- true | false | 'Growth::Conversion::Experiment::LearnGitLabA'
- true | true | 'Growth::Conversion::Experiment::LearnGitLabA'
- end
-
- with_them do
- before do
- stub_experiment_for_subject(learn_gitlab_a: experiment_a, learn_gitlab_b: experiment_b)
- end
-
- context 'when signed in' do
- before do
- sign_in(user)
- end
-
- it { is_expected.to eq(result) }
- end
- end
-
- context 'when not signed in' do
- before do
- stub_experiment_for_subject(learn_gitlab_a: true, learn_gitlab_b: true)
- end
-
- it { is_expected.to eq(nil) }
- end
- end
end
diff --git a/spec/helpers/nav/new_dropdown_helper_spec.rb b/spec/helpers/nav/new_dropdown_helper_spec.rb
index 03b9c538225..64f4d5ff797 100644
--- a/spec/helpers/nav/new_dropdown_helper_spec.rb
+++ b/spec/helpers/nav/new_dropdown_helper_spec.rb
@@ -51,7 +51,7 @@ RSpec.describe Nav::NewDropdownHelper do
title: 'Invite members',
href: expected_href,
data: {
- track_event: 'click_link',
+ track_action: 'click_link',
track_label: 'test_tracking_label',
track_property: :invite_members_new_dropdown
}
@@ -99,12 +99,12 @@ RSpec.describe Nav::NewDropdownHelper do
it 'has project menu item' do
expect(subject[:menu_sections]).to eq(
expected_menu_section(
- title: 'GitLab',
+ title: _('GitLab'),
menu_item: ::Gitlab::Nav::TopNavMenuItem.build(
id: 'general_new_project',
title: 'New project/repository',
href: '/projects/new',
- data: { track_event: 'click_link_new_project', track_label: 'plus_menu_dropdown', qa_selector: 'global_new_project_link' }
+ data: { track_action: 'click_link_new_project', track_label: 'plus_menu_dropdown', qa_selector: 'global_new_project_link' }
)
)
)
@@ -117,12 +117,12 @@ RSpec.describe Nav::NewDropdownHelper do
it 'has group menu item' do
expect(subject[:menu_sections]).to eq(
expected_menu_section(
- title: 'GitLab',
+ title: _('GitLab'),
menu_item: ::Gitlab::Nav::TopNavMenuItem.build(
id: 'general_new_group',
title: 'New group',
href: '/groups/new',
- data: { track_event: 'click_link_new_group', track_label: 'plus_menu_dropdown' }
+ data: { track_action: 'click_link_new_group', track_label: 'plus_menu_dropdown' }
)
)
)
@@ -135,12 +135,12 @@ RSpec.describe Nav::NewDropdownHelper do
it 'has new snippet menu item' do
expect(subject[:menu_sections]).to eq(
expected_menu_section(
- title: 'GitLab',
+ title: _('GitLab'),
menu_item: ::Gitlab::Nav::TopNavMenuItem.build(
id: 'general_new_snippet',
title: 'New snippet',
href: '/-/snippets/new',
- data: { track_event: 'click_link_new_snippet_parent', track_label: 'plus_menu_dropdown', qa_selector: 'global_new_snippet_link' }
+ data: { track_action: 'click_link_new_snippet_parent', track_label: 'plus_menu_dropdown', qa_selector: 'global_new_snippet_link' }
)
)
)
@@ -178,7 +178,7 @@ RSpec.describe Nav::NewDropdownHelper do
id: 'new_project',
title: 'New project/repository',
href: "/projects/new?namespace_id=#{group.id}",
- data: { track_event: 'click_link_new_project_group', track_label: 'plus_menu_dropdown' }
+ data: { track_action: 'click_link_new_project_group', track_label: 'plus_menu_dropdown' }
)
)
)
@@ -196,7 +196,7 @@ RSpec.describe Nav::NewDropdownHelper do
id: 'new_subgroup',
title: 'New subgroup',
href: "/groups/new?parent_id=#{group.id}",
- data: { track_event: 'click_link_new_subgroup', track_label: 'plus_menu_dropdown' }
+ data: { track_action: 'click_link_new_subgroup', track_label: 'plus_menu_dropdown' }
)
)
)
@@ -245,7 +245,7 @@ RSpec.describe Nav::NewDropdownHelper do
id: 'new_issue',
title: 'New issue',
href: "/#{project.path_with_namespace}/-/issues/new",
- data: { track_event: 'click_link_new_issue', track_label: 'plus_menu_dropdown', qa_selector: 'new_issue_link' }
+ data: { track_action: 'click_link_new_issue', track_label: 'plus_menu_dropdown', qa_selector: 'new_issue_link' }
)
)
)
@@ -263,7 +263,7 @@ RSpec.describe Nav::NewDropdownHelper do
id: 'new_mr',
title: 'New merge request',
href: "/#{merge_project.path_with_namespace}/-/merge_requests/new",
- data: { track_event: 'click_link_new_mr', track_label: 'plus_menu_dropdown' }
+ data: { track_action: 'click_link_new_mr', track_label: 'plus_menu_dropdown' }
)
)
)
@@ -281,7 +281,7 @@ RSpec.describe Nav::NewDropdownHelper do
id: 'new_snippet',
title: 'New snippet',
href: "/#{project.path_with_namespace}/-/snippets/new",
- data: { track_event: 'click_link_new_snippet_project', track_label: 'plus_menu_dropdown' }
+ data: { track_action: 'click_link_new_snippet_project', track_label: 'plus_menu_dropdown' }
)
)
)
diff --git a/spec/helpers/nav/top_nav_helper_spec.rb b/spec/helpers/nav/top_nav_helper_spec.rb
index 4d6da258536..da7e5d5dce2 100644
--- a/spec/helpers/nav/top_nav_helper_spec.rb
+++ b/spec/helpers/nav/top_nav_helper_spec.rb
@@ -142,7 +142,7 @@ RSpec.describe Nav::TopNavHelper do
expected_primary = ::Gitlab::Nav::TopNavMenuItem.build(
css_class: 'qa-projects-dropdown',
data: {
- track_event: 'click_dropdown',
+ track_action: 'click_dropdown',
track_label: 'projects_dropdown'
},
icon: 'project',
@@ -248,7 +248,7 @@ RSpec.describe Nav::TopNavHelper do
expected_primary = ::Gitlab::Nav::TopNavMenuItem.build(
css_class: 'qa-groups-dropdown',
data: {
- track_event: 'click_dropdown',
+ track_action: 'click_dropdown',
track_label: 'groups_dropdown'
},
icon: 'group',
diff --git a/spec/helpers/notify_helper_spec.rb b/spec/helpers/notify_helper_spec.rb
index e2a7a212b1b..a4193444528 100644
--- a/spec/helpers/notify_helper_spec.rb
+++ b/spec/helpers/notify_helper_spec.rb
@@ -55,4 +55,53 @@ RSpec.describe NotifyHelper do
def reference_link(entity, url)
"<a href=\"#{url}\">#{entity.to_reference}</a>"
end
+
+ describe '#invited_join_url' do
+ let_it_be(:member) { create(:project_member) }
+
+ let(:token) { '_token_' }
+
+ context 'when invite_email_preview_text is enabled', :experiment do
+ before do
+ stub_experiments(invite_email_preview_text: :control)
+ end
+
+ it 'has correct params' do
+ expect(helper.invited_join_url(token, member))
+ .to eq("http://test.host/-/invites/#{token}?experiment_name=invite_email_preview_text&invite_type=initial_email")
+ end
+
+ context 'when invite_email_from is enabled' do
+ before do
+ stub_experiments(invite_email_from: :control)
+ end
+
+ it 'has correct params' do
+ expect(helper.invited_join_url(token, member))
+ .to eq("http://test.host/-/invites/#{token}?experiment_name=invite_email_from&invite_type=initial_email")
+ end
+ end
+ end
+
+ context 'when invite_email_from is enabled' do
+ before do
+ stub_experiments(invite_email_from: :control)
+ end
+
+ it 'has correct params' do
+ expect(helper.invited_join_url(token, member))
+ .to eq("http://test.host/-/invites/#{token}?experiment_name=invite_email_from&invite_type=initial_email")
+ end
+ end
+
+ context 'when invite_email_preview_text is disabled' do
+ before do
+ stub_feature_flags(invite_email_preview_text: false)
+ end
+
+ it 'has correct params' do
+ expect(helper.invited_join_url(token, member)).to eq("http://test.host/-/invites/#{token}?invite_type=initial_email")
+ end
+ end
+ end
end
diff --git a/spec/helpers/packages_helper_spec.rb b/spec/helpers/packages_helper_spec.rb
index bc60c582ff8..06c6cccd488 100644
--- a/spec/helpers/packages_helper_spec.rb
+++ b/spec/helpers/packages_helper_spec.rb
@@ -223,21 +223,41 @@ RSpec.describe PackagesHelper do
describe '#package_details_data' do
let_it_be(:package) { create(:package) }
+ let(:expected_result) do
+ {
+ package_id: package.id,
+ can_delete: 'true',
+ project_name: project.name,
+ group_list_url: ''
+ }
+ end
+
before do
allow(helper).to receive(:current_user) { project.owner }
allow(helper).to receive(:can?) { true }
end
- it 'when use_presenter is true populate the package key' do
- result = helper.package_details_data(project, package, true)
+ context 'in a project without a group' do
+ it 'populates presenter data' do
+ result = helper.package_details_data(project, package)
- expect(result[:package]).not_to be_nil
+ expect(result).to match(hash_including(expected_result))
+ end
end
- it 'when use_presenter is false the package key is nil' do
- result = helper.package_details_data(project, package, false)
+ context 'in a project with a group' do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project_with_group) { create(:project, group: group) }
- expect(result[:package]).to be_nil
+ it 'populates presenter data' do
+ result = helper.package_details_data(project_with_group, package)
+ expected = expected_result.merge({
+ group_list_url: group_packages_path(project_with_group.group),
+ project_name: project_with_group.name
+ })
+
+ expect(result).to match(hash_including(expected))
+ end
end
end
end
diff --git a/spec/helpers/profiles_helper_spec.rb b/spec/helpers/profiles_helper_spec.rb
index 2ea832f95dc..c3a3c2a0178 100644
--- a/spec/helpers/profiles_helper_spec.rb
+++ b/spec/helpers/profiles_helper_spec.rb
@@ -13,7 +13,8 @@ RSpec.describe ProfilesHelper do
private_email = user.private_commit_email
emails = [
- ["Use a private email - #{private_email}", Gitlab::PrivateCommitEmail::TOKEN],
+ [s_('Use primary email (%{email})') % { email: user.email }, ''],
+ [s_("Profiles|Use a private email - %{email}").html_safe % { email: private_email }, Gitlab::PrivateCommitEmail::TOKEN],
user.email,
confirmed_email1.email,
confirmed_email2.email
@@ -23,20 +24,6 @@ RSpec.describe ProfilesHelper do
end
end
- describe '#selected_commit_email' do
- let(:user) { create(:user) }
-
- it 'returns main email when commit email attribute is nil' do
- expect(helper.selected_commit_email(user)).to eq(user.email)
- end
-
- it 'returns DB stored commit_email' do
- user.update!(commit_email: Gitlab::PrivateCommitEmail::TOKEN)
-
- expect(helper.selected_commit_email(user)).to eq(Gitlab::PrivateCommitEmail::TOKEN)
- end
- end
-
describe '#email_provider_label' do
it "returns nil for users without external email" do
user = create(:user)
@@ -152,6 +139,22 @@ RSpec.describe ProfilesHelper do
end
end
+ describe '#middle_dot_divider_classes' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:stacking, :breakpoint, :expected) do
+ nil | nil | %w(gl-mb-3 gl-display-inline-block middle-dot-divider)
+ true | nil | %w(gl-mb-3 middle-dot-divider-sm gl-display-block gl-sm-display-inline-block)
+ nil | :sm | %w(gl-mb-3 gl-display-inline-block middle-dot-divider-sm)
+ end
+
+ with_them do
+ it 'returns CSS classes needed to render the middle dot divider' do
+ expect(helper.middle_dot_divider_classes(stacking, breakpoint)).to eq expected
+ end
+ end
+ end
+
def stub_cas_omniauth_provider
provider = OpenStruct.new(
'name' => 'cas3',
diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb
index 4dac4403f70..85b572d3f68 100644
--- a/spec/helpers/projects_helper_spec.rb
+++ b/spec/helpers/projects_helper_spec.rb
@@ -498,7 +498,7 @@ RSpec.describe ProjectsHelper do
context 'user has a configured commit email' do
before do
confirmed_email = create(:email, :confirmed, user: user)
- user.update!(commit_email: confirmed_email)
+ user.update!(commit_email: confirmed_email.email)
end
it 'returns the commit email' do
diff --git a/spec/helpers/recaptcha_helper_spec.rb b/spec/helpers/recaptcha_helper_spec.rb
index e7f9ba5b73a..8ad91a0a217 100644
--- a/spec/helpers/recaptcha_helper_spec.rb
+++ b/spec/helpers/recaptcha_helper_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe RecaptchaHelper, type: :helper do
it 'returns false' do
stub_application_setting(recaptcha_enabled: false)
- expect(helper.show_recaptcha_sign_up?).to be(false)
+ expect(helper.show_recaptcha_sign_up?).to be_falsey
end
end
@@ -22,7 +22,7 @@ RSpec.describe RecaptchaHelper, type: :helper do
it 'returns true' do
stub_application_setting(recaptcha_enabled: true)
- expect(helper.show_recaptcha_sign_up?).to be(true)
+ expect(helper.show_recaptcha_sign_up?).to be_truthy
end
end
end
diff --git a/spec/helpers/routing/pseudonymization_helper_spec.rb b/spec/helpers/routing/pseudonymization_helper_spec.rb
new file mode 100644
index 00000000000..10563502555
--- /dev/null
+++ b/spec/helpers/routing/pseudonymization_helper_spec.rb
@@ -0,0 +1,141 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Routing::PseudonymizationHelper do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:subgroup) { create(:group, parent: group) }
+ let_it_be(:project) { create(:project, group: group) }
+ let_it_be(:issue) { create(:issue, project: project) }
+
+ let(:merge_request) { create(:merge_request, source_project: project) }
+
+ before do
+ stub_feature_flags(mask_page_urls: true)
+ allow(helper).to receive(:group).and_return(group)
+ allow(helper).to receive(:project).and_return(project)
+ end
+
+ shared_examples 'masked url' do
+ it 'generates masked page url' do
+ expect(helper.masked_page_url).to eq(masked_url)
+ end
+ end
+
+ describe 'when url has params to mask' do
+ context 'with controller for MR' do
+ let(:masked_url) { "http://test.host/namespace:#{group.id}/project:#{project.id}/-/merge_requests/#{merge_request.id}" }
+
+ before do
+ allow(Rails.application.routes).to receive(:recognize_path).and_return({
+ controller: "projects/merge_requests",
+ action: "show",
+ namespace_id: group.name,
+ project_id: project.name,
+ id: merge_request.id.to_s
+ })
+ end
+
+ it_behaves_like 'masked url'
+ end
+
+ context 'with controller for issue' do
+ let(:masked_url) { "http://test.host/namespace:#{group.id}/project:#{project.id}/-/issues/#{issue.id}" }
+
+ before do
+ allow(Rails.application.routes).to receive(:recognize_path).and_return({
+ controller: "projects/issues",
+ action: "show",
+ namespace_id: group.name,
+ project_id: project.name,
+ id: issue.id.to_s
+ })
+ end
+
+ it_behaves_like 'masked url'
+ end
+
+ context 'with controller for groups with subgroups and project' do
+ let(:masked_url) { "http://test.host/namespace:#{subgroup.id}/project:#{project.id}"}
+
+ before do
+ allow(helper).to receive(:group).and_return(subgroup)
+ allow(helper.project).to receive(:namespace).and_return(subgroup)
+ allow(Rails.application.routes).to receive(:recognize_path).and_return({
+ controller: 'projects',
+ action: 'show',
+ namespace_id: subgroup.name,
+ id: project.name
+ })
+ end
+
+ it_behaves_like 'masked url'
+ end
+
+ context 'with controller for groups and subgroups' do
+ let(:masked_url) { "http://test.host/namespace:#{subgroup.id}"}
+
+ before do
+ allow(helper).to receive(:group).and_return(subgroup)
+ allow(Rails.application.routes).to receive(:recognize_path).and_return({
+ controller: 'groups',
+ action: 'show',
+ id: subgroup.name
+ })
+ end
+
+ it_behaves_like 'masked url'
+ end
+
+ context 'with controller for blob with file path' do
+ let(:masked_url) { "http://test.host/namespace:#{group.id}/project:#{project.id}/-/blob/:repository_path" }
+
+ before do
+ allow(Rails.application.routes).to receive(:recognize_path).and_return({
+ controller: 'projects/blob',
+ action: 'show',
+ namespace_id: group.name,
+ project_id: project.name,
+ id: 'master/README.md'
+ })
+ end
+
+ it_behaves_like 'masked url'
+ end
+
+ context 'with non identifiable controller' do
+ let(:masked_url) { "http://test.host/dashboard/issues?assignee_username=root" }
+
+ before do
+ controller.request.path = '/dashboard/issues'
+ controller.request.query_string = 'assignee_username=root'
+ allow(Rails.application.routes).to receive(:recognize_path).and_return({
+ controller: 'dashboard',
+ action: 'issues'
+ })
+ end
+
+ it_behaves_like 'masked url'
+ end
+ end
+
+ describe 'when url has no params to mask' do
+ let(:root_url) { 'http://test.host' }
+
+ context 'returns root url' do
+ it 'masked_page_url' do
+ expect(helper.masked_page_url).to eq(root_url)
+ end
+ end
+ end
+
+ describe 'when feature flag is disabled' do
+ before do
+ stub_feature_flags(mask_page_urls: false)
+ end
+
+ it 'returns nil' do
+ expect(helper.masked_page_url).to be_nil
+ end
+ end
+end
diff --git a/spec/helpers/user_callouts_helper_spec.rb b/spec/helpers/user_callouts_helper_spec.rb
index 5ef1e9d4daf..794ff5ee945 100644
--- a/spec/helpers/user_callouts_helper_spec.rb
+++ b/spec/helpers/user_callouts_helper_spec.rb
@@ -3,7 +3,7 @@
require "spec_helper"
RSpec.describe UserCalloutsHelper do
- let_it_be(:user) { create(:user) }
+ let_it_be(:user, refind: true) { create(:user) }
before do
allow(helper).to receive(:current_user).and_return(user)
@@ -202,4 +202,95 @@ RSpec.describe UserCalloutsHelper do
it { is_expected.to be false }
end
end
+
+ describe '.show_invite_banner?' do
+ let_it_be(:group) { create(:group) }
+
+ subject { helper.show_invite_banner?(group) }
+
+ context 'when user has the admin ability for the group' do
+ before do
+ group.add_owner(user)
+ end
+
+ context 'when the invite_members_banner has not been dismissed' do
+ it { is_expected.to eq(true) }
+
+ context 'when a user has dismissed this banner via cookies already' do
+ before do
+ helper.request.cookies["invite_#{group.id}_#{user.id}"] = 'true'
+ end
+
+ it { is_expected.to eq(false) }
+
+ it 'creates the callout from cookie', :aggregate_failures do
+ expect { subject }.to change { Users::GroupCallout.count }.by(1)
+ expect(Users::GroupCallout.last).to have_attributes(group_id: group.id,
+ feature_name: described_class::INVITE_MEMBERS_BANNER)
+ end
+ end
+
+ context 'when the group was just created' do
+ before do
+ flash[:notice] = "Group #{group.name} was successfully created"
+ end
+
+ it { is_expected.to eq(false) }
+ end
+
+ context 'with concerning multiple members' do
+ let_it_be(:user_2) { create(:user) }
+
+ context 'on current group' do
+ before do
+ group.add_guest(user_2)
+ end
+
+ it { is_expected.to eq(false) }
+ end
+
+ context 'on current group that is a subgroup' do
+ let_it_be(:subgroup) { create(:group, parent: group) }
+
+ subject { helper.show_invite_banner?(subgroup) }
+
+ context 'with only one user on parent and this group' do
+ it { is_expected.to eq(true) }
+ end
+
+ context 'when another user is on this group' do
+ before do
+ subgroup.add_guest(user_2)
+ end
+
+ it { is_expected.to eq(false) }
+ end
+
+ context 'when another user is on the parent group' do
+ before do
+ group.add_guest(user_2)
+ end
+
+ it { is_expected.to eq(false) }
+ end
+ end
+ end
+ end
+
+ context 'when the invite_members_banner has been dismissed' do
+ before do
+ create(:group_callout,
+ user: user,
+ group: group,
+ feature_name: described_class::INVITE_MEMBERS_BANNER)
+ end
+
+ it { is_expected.to eq(false) }
+ end
+ end
+
+ context 'when user does not have admin ability for the group' do
+ it { is_expected.to eq(false) }
+ end
+ end
end
diff --git a/spec/initializers/validate_database_config_spec.rb b/spec/initializers/validate_database_config_spec.rb
new file mode 100644
index 00000000000..99e4a4b36ee
--- /dev/null
+++ b/spec/initializers/validate_database_config_spec.rb
@@ -0,0 +1,166 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'validate database config' do
+ include RakeHelpers
+ include StubENV
+
+ let(:rails_configuration) { Rails::Application::Configuration.new(Rails.root) }
+ let(:ar_configurations) { ActiveRecord::DatabaseConfigurations.new(rails_configuration.database_configuration) }
+
+ subject do
+ load Rails.root.join('config/initializers/validate_database_config.rb')
+ end
+
+ before do
+ # The `AS::ConfigurationFile` calls `read` in `def initialize`
+ # thus we cannot use `expect_next_instance_of`
+ # rubocop:disable RSpec/AnyInstanceOf
+ expect_any_instance_of(ActiveSupport::ConfigurationFile)
+ .to receive(:read).with(Rails.root.join('config/database.yml')).and_return(database_yml)
+ # rubocop:enable RSpec/AnyInstanceOf
+
+ allow(Rails.application).to receive(:config).and_return(rails_configuration)
+ allow(ActiveRecord::Base).to receive(:configurations).and_return(ar_configurations)
+ end
+
+ shared_examples 'with SKIP_DATABASE_CONFIG_VALIDATION=true' do
+ before do
+ stub_env('SKIP_DATABASE_CONFIG_VALIDATION', 'true')
+ end
+
+ it 'does not raise exception' do
+ expect { subject }.not_to raise_error
+ end
+ end
+
+ context 'when config/database.yml is valid' do
+ context 'uses legacy syntax' do
+ let(:database_yml) do
+ <<-EOS
+ production:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_production
+ username: git
+ password: "secure password"
+ host: localhost
+ EOS
+ end
+
+ it 'validates configuration with a warning' do
+ expect(main_object).to receive(:warn).with /uses a deprecated syntax for/
+
+ expect { subject }.not_to raise_error
+ end
+
+ it_behaves_like 'with SKIP_DATABASE_CONFIG_VALIDATION=true'
+ end
+
+ context 'uses new syntax' do
+ let(:database_yml) do
+ <<-EOS
+ production:
+ main:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_production
+ username: git
+ password: "secure password"
+ host: localhost
+ EOS
+ end
+
+ it 'validates configuration without errors and warnings' do
+ expect(main_object).not_to receive(:warn)
+
+ expect { subject }.not_to raise_error
+ end
+ end
+ end
+
+ context 'when config/database.yml is invalid' do
+ context 'uses unknown connection name' do
+ let(:database_yml) do
+ <<-EOS
+ production:
+ main:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_production
+ username: git
+ password: "secure password"
+ host: localhost
+
+ another:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_production
+ username: git
+ password: "secure password"
+ host: localhost
+ EOS
+ end
+
+ it 'raises exception' do
+ expect { subject }.to raise_error /This installation of GitLab uses unsupported database names/
+ end
+
+ it_behaves_like 'with SKIP_DATABASE_CONFIG_VALIDATION=true'
+ end
+
+ context 'uses replica configuration' do
+ let(:database_yml) do
+ <<-EOS
+ production:
+ main:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_production
+ username: git
+ password: "secure password"
+ host: localhost
+ replica: true
+ EOS
+ end
+
+ it 'raises exception' do
+ expect { subject }.to raise_error /with 'replica: true' parameter in/
+ end
+
+ it_behaves_like 'with SKIP_DATABASE_CONFIG_VALIDATION=true'
+ end
+
+ context 'main is not a first entry' do
+ let(:database_yml) do
+ <<-EOS
+ production:
+ ci:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_production_ci
+ username: git
+ password: "secure password"
+ host: localhost
+ replica: true
+
+ main:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_production
+ username: git
+ password: "secure password"
+ host: localhost
+ replica: true
+ EOS
+ end
+
+ it 'raises exception' do
+ expect { subject }.to raise_error /The `main:` database needs to be defined as a first configuration item/
+ end
+
+ it_behaves_like 'with SKIP_DATABASE_CONFIG_VALIDATION=true'
+ end
+ end
+end
diff --git a/spec/javascripts/.eslintrc.yml b/spec/javascripts/.eslintrc.yml
deleted file mode 100644
index b863156b57c..00000000000
--- a/spec/javascripts/.eslintrc.yml
+++ /dev/null
@@ -1,39 +0,0 @@
----
-env:
- jasmine: true
-extends: plugin:jasmine/recommended
-globals:
- appendLoadFixtures: false
- appendLoadStyleFixtures: false
- appendSetFixtures: false
- appendSetStyleFixtures: false
- getJSONFixture: false
- loadFixtures: false
- loadJSONFixtures: false
- loadStyleFixtures: false
- preloadFixtures: false
- preloadStyleFixtures: false
- readFixtures: false
- sandbox: false
- setFixtures: false
- setStyleFixtures: false
- spyOnDependency: false
- spyOnEvent: false
- ClassSpecHelper: false
-plugins:
- - jasmine
-rules:
- func-names: off
- jasmine/no-suite-dupes:
- - warn
- - branch
- jasmine/no-spec-dupes:
- - warn
- - branch
- prefer-arrow-callback: off
- import/no-unresolved:
- - error
- - ignore:
- - 'fixtures/blob'
- # Temporarily disabled to facilitate an upgrade to eslint-plugin-jasmine
- jasmine/prefer-toHaveBeenCalledWith: off
diff --git a/spec/javascripts/fixtures/.gitignore b/spec/javascripts/fixtures/.gitignore
deleted file mode 100644
index d6b7ef32c84..00000000000
--- a/spec/javascripts/fixtures/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*
-!.gitignore
diff --git a/spec/javascripts/fly_out_nav_browser_spec.js b/spec/javascripts/fly_out_nav_browser_spec.js
deleted file mode 100644
index 12ea0e262bc..00000000000
--- a/spec/javascripts/fly_out_nav_browser_spec.js
+++ /dev/null
@@ -1,334 +0,0 @@
-// this file can't be migrated to jest because it relies on the browser to perform integration tests:
-// (specifically getClientBoundingRect and mouse movements)
-// see: https://gitlab.com/groups/gitlab-org/-/epics/895#what-if-theres-a-karma-spec-which-is-simply-unmovable-to-jest-ie-it-is-dependent-on-a-running-browser-environment
-
-import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
-import { SIDEBAR_COLLAPSED_CLASS } from '~/contextual_sidebar';
-import {
- calculateTop,
- showSubLevelItems,
- canShowSubItems,
- canShowActiveSubItems,
- mouseEnterTopItems,
- mouseLeaveTopItem,
- getOpenMenu,
- setOpenMenu,
- mousePos,
- getHideSubItemsInterval,
- documentMouseMove,
- getHeaderHeight,
- setSidebar,
- subItemsMouseLeave,
-} from '~/fly_out_nav';
-
-describe('Fly out sidebar navigation', () => {
- let el;
- let breakpointSize = 'lg';
-
- beforeEach(() => {
- el = document.createElement('div');
- el.style.position = 'relative';
- document.body.appendChild(el);
-
- spyOn(GlBreakpointInstance, 'getBreakpointSize').and.callFake(() => breakpointSize);
-
- setOpenMenu(null);
- });
-
- afterEach(() => {
- document.body.innerHTML = '';
- breakpointSize = 'lg';
- mousePos.length = 0;
-
- setSidebar(null);
- });
-
- describe('calculateTop', () => {
- it('returns boundingRect top', () => {
- const boundingRect = {
- top: 100,
- height: 100,
- };
-
- expect(calculateTop(boundingRect, 100)).toBe(100);
- });
-
- it('returns boundingRect - bottomOverflow', () => {
- const boundingRect = {
- top: window.innerHeight - 50,
- height: 100,
- };
-
- expect(calculateTop(boundingRect, 100)).toBe(window.innerHeight - 50);
- });
- });
-
- describe('getHideSubItemsInterval', () => {
- beforeEach(() => {
- el.innerHTML =
- '<div class="sidebar-sub-level-items" style="position: fixed; top: 0; left: 100px; height: 150px;"></div>';
- });
-
- it('returns 0 if currentOpenMenu is nil', () => {
- expect(getHideSubItemsInterval()).toBe(0);
- });
-
- it('returns 0 if mousePos is empty', () => {
- expect(getHideSubItemsInterval()).toBe(0);
- });
-
- it('returns 0 when mouse above sub-items', () => {
- showSubLevelItems(el);
- documentMouseMove({
- clientX: el.getBoundingClientRect().left,
- clientY: el.getBoundingClientRect().top,
- });
- documentMouseMove({
- clientX: el.getBoundingClientRect().left,
- clientY: el.getBoundingClientRect().top - 50,
- });
-
- expect(getHideSubItemsInterval()).toBe(0);
- });
-
- it('returns 0 when mouse is below sub-items', () => {
- const subItems = el.querySelector('.sidebar-sub-level-items');
-
- showSubLevelItems(el);
- documentMouseMove({
- clientX: el.getBoundingClientRect().left,
- clientY: el.getBoundingClientRect().top,
- });
- documentMouseMove({
- clientX: el.getBoundingClientRect().left,
- clientY: el.getBoundingClientRect().top - subItems.getBoundingClientRect().height + 50,
- });
-
- expect(getHideSubItemsInterval()).toBe(0);
- });
-
- it('returns 300 when mouse is moved towards sub-items', () => {
- documentMouseMove({
- clientX: el.getBoundingClientRect().left,
- clientY: el.getBoundingClientRect().top,
- });
- showSubLevelItems(el);
- documentMouseMove({
- clientX: el.getBoundingClientRect().left + 20,
- clientY: el.getBoundingClientRect().top + 10,
- });
-
- expect(getHideSubItemsInterval()).toBe(300);
- });
- });
-
- describe('mouseLeaveTopItem', () => {
- beforeEach(() => {
- spyOn(el.classList, 'remove');
- });
-
- it('removes is-over class if currentOpenMenu is null', () => {
- mouseLeaveTopItem(el);
-
- expect(el.classList.remove).toHaveBeenCalledWith('is-over');
- });
-
- it('removes is-over class if currentOpenMenu is null & there are sub-items', () => {
- el.innerHTML = '<div class="sidebar-sub-level-items" style="position: absolute;"></div>';
-
- mouseLeaveTopItem(el);
-
- expect(el.classList.remove).toHaveBeenCalledWith('is-over');
- });
-
- it('does not remove is-over class if currentOpenMenu is the passed in sub-items', () => {
- el.innerHTML = '<div class="sidebar-sub-level-items" style="position: absolute;"></div>';
-
- setOpenMenu(el.querySelector('.sidebar-sub-level-items'));
- mouseLeaveTopItem(el);
-
- expect(el.classList.remove).not.toHaveBeenCalled();
- });
- });
-
- describe('mouseEnterTopItems', () => {
- beforeEach(() => {
- el.innerHTML =
- '<div class="sidebar-sub-level-items" style="position: absolute; top: 0; left: 100px; height: 200px;"></div>';
- });
-
- it('shows sub-items after 0ms if no menu is open', (done) => {
- mouseEnterTopItems(el);
-
- expect(getHideSubItemsInterval()).toBe(0);
-
- setTimeout(() => {
- expect(el.querySelector('.sidebar-sub-level-items').style.display).toBe('block');
-
- done();
- });
- });
-
- it('shows sub-items after 300ms if a menu is currently open', (done) => {
- documentMouseMove({
- clientX: el.getBoundingClientRect().left,
- clientY: el.getBoundingClientRect().top,
- });
-
- setOpenMenu(el.querySelector('.sidebar-sub-level-items'));
-
- documentMouseMove({
- clientX: el.getBoundingClientRect().left + 20,
- clientY: el.getBoundingClientRect().top + 10,
- });
-
- mouseEnterTopItems(el, 0);
-
- expect(getHideSubItemsInterval()).toBe(300);
-
- setTimeout(() => {
- expect(el.querySelector('.sidebar-sub-level-items').style.display).toBe('block');
-
- done();
- });
- });
- });
-
- describe('showSubLevelItems', () => {
- beforeEach(() => {
- el.innerHTML = '<div class="sidebar-sub-level-items" style="position: absolute;"></div>';
- });
-
- it('adds is-over class to el', () => {
- spyOn(el.classList, 'add');
-
- showSubLevelItems(el);
-
- expect(el.classList.add).toHaveBeenCalledWith('is-over');
- });
-
- it('does not show sub-items on mobile', () => {
- breakpointSize = 'xs';
-
- showSubLevelItems(el);
-
- expect(el.querySelector('.sidebar-sub-level-items').style.display).not.toBe('block');
- });
-
- it('shows sub-items', () => {
- showSubLevelItems(el);
-
- expect(el.querySelector('.sidebar-sub-level-items').style.display).toBe('block');
- });
-
- it('shows collapsed only sub-items if icon only sidebar', () => {
- const subItems = el.querySelector('.sidebar-sub-level-items');
- const sidebar = document.createElement('div');
- sidebar.classList.add(SIDEBAR_COLLAPSED_CLASS);
- subItems.classList.add('is-fly-out-only');
-
- setSidebar(sidebar);
-
- showSubLevelItems(el);
-
- expect(el.querySelector('.sidebar-sub-level-items').style.display).toBe('block');
- });
-
- it('does not show collapsed only sub-items if icon only sidebar', () => {
- const subItems = el.querySelector('.sidebar-sub-level-items');
- subItems.classList.add('is-fly-out-only');
-
- showSubLevelItems(el);
-
- expect(subItems.style.display).not.toBe('block');
- });
-
- it('sets transform of sub-items', () => {
- const sidebar = document.createElement('div');
- const subItems = el.querySelector('.sidebar-sub-level-items');
-
- sidebar.style.width = '200px';
-
- document.body.appendChild(sidebar);
-
- setSidebar(sidebar);
- showSubLevelItems(el);
-
- expect(subItems.style.transform).toBe(
- `translate3d(200px, ${
- Math.floor(el.getBoundingClientRect().top) - getHeaderHeight()
- }px, 0px)`,
- );
- });
-
- it('sets is-above when element is above', () => {
- const subItems = el.querySelector('.sidebar-sub-level-items');
- subItems.style.height = `${window.innerHeight + el.offsetHeight}px`;
- el.style.top = `${window.innerHeight - el.offsetHeight}px`;
-
- spyOn(subItems.classList, 'add');
-
- showSubLevelItems(el);
-
- expect(subItems.classList.add).toHaveBeenCalledWith('is-above');
- });
- });
-
- describe('canShowSubItems', () => {
- it('returns true if on desktop size', () => {
- expect(canShowSubItems()).toBeTruthy();
- });
-
- it('returns false if on mobile size', () => {
- breakpointSize = 'xs';
-
- expect(canShowSubItems()).toBeFalsy();
- });
- });
-
- describe('canShowActiveSubItems', () => {
- it('returns true by default', () => {
- expect(canShowActiveSubItems(el)).toBeTruthy();
- });
-
- it('returns false when active & expanded sidebar', () => {
- const sidebar = document.createElement('div');
- el.classList.add('active');
-
- setSidebar(sidebar);
-
- expect(canShowActiveSubItems(el)).toBeFalsy();
- });
-
- it('returns true when active & collapsed sidebar', () => {
- const sidebar = document.createElement('div');
- sidebar.classList.add(SIDEBAR_COLLAPSED_CLASS);
- el.classList.add('active');
-
- setSidebar(sidebar);
-
- expect(canShowActiveSubItems(el)).toBeTruthy();
- });
- });
-
- describe('subItemsMouseLeave', () => {
- beforeEach(() => {
- el.innerHTML = '<div class="sidebar-sub-level-items" style="position: absolute;"></div>';
-
- setOpenMenu(el.querySelector('.sidebar-sub-level-items'));
- });
-
- it('hides subMenu if element is not hovered', () => {
- subItemsMouseLeave(el);
-
- expect(getOpenMenu()).toBeNull();
- });
-
- it('does not hide subMenu if element is hovered', () => {
- el.classList.add('is-over');
- subItemsMouseLeave(el);
-
- expect(getOpenMenu()).not.toBeNull();
- });
- });
-});
diff --git a/spec/javascripts/lib/utils/browser_spec.js b/spec/javascripts/lib/utils/browser_spec.js
deleted file mode 100644
index f41fa2503b1..00000000000
--- a/spec/javascripts/lib/utils/browser_spec.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * This file should only contain browser specific specs.
- * If you need to add or update a spec, please see spec/frontend/lib/utils/*.js
- * https://gitlab.com/gitlab-org/gitlab/issues/194242#note_292137135
- * https://gitlab.com/groups/gitlab-org/-/epics/895#what-if-theres-a-karma-spec-which-is-simply-unmovable-to-jest-ie-it-is-dependent-on-a-running-browser-environment
- */
-
-import { GlBreakpointInstance as breakpointInstance } from '@gitlab/ui/dist/utils';
-import * as commonUtils from '~/lib/utils/common_utils';
-
-describe('common_utils browser specific specs', () => {
- describe('contentTop', () => {
- it('does not add height for fileTitle or compareVersionsHeader if screen is too small', () => {
- spyOn(breakpointInstance, 'isDesktop').and.returnValue(false);
-
- setFixtures(`
- <div class="diff-file file-title-flex-parent">
- blah blah blah
- </div>
- <div class="mr-version-controls">
- more blah blah blah
- </div>
- `);
-
- expect(commonUtils.contentTop()).toBe(0);
- });
-
- it('adds height for fileTitle and compareVersionsHeader screen is large enough', () => {
- spyOn(breakpointInstance, 'isDesktop').and.returnValue(true);
-
- setFixtures(`
- <div class="diff-file file-title-flex-parent">
- blah blah blah
- </div>
- <div class="mr-version-controls">
- more blah blah blah
- </div>
- `);
-
- expect(commonUtils.contentTop()).toBe(18);
- });
- });
-
- describe('isInViewport', () => {
- let el;
-
- beforeEach(() => {
- el = document.createElement('div');
- });
-
- afterEach(() => {
- document.body.removeChild(el);
- });
-
- it('returns true when provided `el` is in viewport', () => {
- el.setAttribute('style', `position: absolute; right: ${window.innerWidth + 0.2};`);
- document.body.appendChild(el);
-
- expect(commonUtils.isInViewport(el)).toBe(true);
- });
-
- it('returns false when provided `el` is not in viewport', () => {
- el.setAttribute('style', 'position: absolute; top: -1000px; left: -1000px;');
- document.body.appendChild(el);
-
- expect(commonUtils.isInViewport(el)).toBe(false);
- });
- });
-});
diff --git a/spec/javascripts/lib/utils/mock_data.js b/spec/javascripts/lib/utils/mock_data.js
deleted file mode 100644
index f1358986f2a..00000000000
--- a/spec/javascripts/lib/utils/mock_data.js
+++ /dev/null
@@ -1 +0,0 @@
-export * from '../../../frontend/lib/utils/mock_data';
diff --git a/spec/javascripts/test_bundle.js b/spec/javascripts/test_bundle.js
deleted file mode 100644
index be14d2ee7e7..00000000000
--- a/spec/javascripts/test_bundle.js
+++ /dev/null
@@ -1,145 +0,0 @@
-/* eslint-disable
- jasmine/no-global-setup, no-underscore-dangle, no-console
-*/
-
-import { config as testUtilsConfig } from '@vue/test-utils';
-import jasmineDiff from 'jasmine-diff';
-import $ from 'jquery';
-import 'core-js/features/set-immediate';
-import 'vendor/jasmine-jquery';
-import '~/commons';
-import Vue from 'vue';
-import { getDefaultAdapter } from '~/lib/utils/axios_utils';
-import Translate from '~/vue_shared/translate';
-
-import { FIXTURES_PATH, TEST_HOST } from './test_constants';
-
-// Tech debt issue TBD
-testUtilsConfig.logModifiedComponents = false;
-
-const isHeadlessChrome = /\bHeadlessChrome\//.test(navigator.userAgent);
-Vue.config.devtools = !isHeadlessChrome;
-Vue.config.productionTip = false;
-
-let hasVueWarnings = false;
-Vue.config.warnHandler = (msg, vm, trace) => {
- // The following workaround is necessary, so we are able to use setProps from Vue test utils
- // see https://github.com/vuejs/vue-test-utils/issues/631#issuecomment-421108344
- const currentStack = new Error().stack;
- const isInVueTestUtils = currentStack
- .split('\n')
- .some((line) => line.startsWith(' at VueWrapper.setProps ('));
- if (isInVueTestUtils) {
- return;
- }
-
- hasVueWarnings = true;
- fail(`${msg}${trace}`);
-};
-
-let hasVueErrors = false;
-Vue.config.errorHandler = function (err) {
- hasVueErrors = true;
- fail(err);
-};
-
-Vue.use(Translate);
-
-// enable test fixtures
-jasmine.getFixtures().fixturesPath = FIXTURES_PATH;
-jasmine.getJSONFixtures().fixturesPath = FIXTURES_PATH;
-
-beforeAll(() => {
- jasmine.addMatchers(
- jasmineDiff(jasmine, {
- colors: window.__karma__.config.color,
- inline: window.__karma__.config.color,
- }),
- );
-});
-
-// globalize common libraries
-window.$ = $;
-window.jQuery = window.$;
-
-// stub expected globals
-window.gl = window.gl || {};
-window.gl.TEST_HOST = TEST_HOST;
-window.gon = window.gon || {};
-window.gon.test_env = true;
-window.gon.ee = process.env.IS_EE;
-gon.relative_url_root = '';
-
-let hasUnhandledPromiseRejections = false;
-
-window.addEventListener('unhandledrejection', (event) => {
- hasUnhandledPromiseRejections = true;
- console.error('Unhandled promise rejection:');
- console.error(event.reason.stack || event.reason);
-});
-
-let longRunningTestTimeoutHandle;
-
-beforeEach((done) => {
- longRunningTestTimeoutHandle = setTimeout(() => {
- done.fail('Test is running too long!');
- }, 4000);
- done();
-});
-
-afterEach(() => {
- clearTimeout(longRunningTestTimeoutHandle);
-});
-
-const axiosDefaultAdapter = getDefaultAdapter();
-
-// render all of our tests
-const testContexts = [require.context('spec', true, /_spec$/)];
-
-if (process.env.IS_EE) {
- testContexts.push(require.context('ee_spec', true, /_spec$/));
-}
-
-testContexts.forEach((context) => {
- context.keys().forEach((path) => {
- try {
- context(path);
- } catch (err) {
- console.log(err);
- console.error('[GL SPEC RUNNER ERROR] Unable to load spec: ', path);
- describe('Test bundle', function () {
- it(`includes '${path}'`, function () {
- expect(err).toBeNull();
- });
- });
- }
- });
-});
-
-describe('test errors', () => {
- beforeAll((done) => {
- if (hasUnhandledPromiseRejections || hasVueWarnings || hasVueErrors) {
- setTimeout(done, 1000);
- } else {
- done();
- }
- });
-
- it('has no unhandled Promise rejections', () => {
- expect(hasUnhandledPromiseRejections).toBe(false);
- });
-
- it('has no Vue warnings', () => {
- expect(hasVueWarnings).toBe(false);
- });
-
- it('has no Vue error', () => {
- expect(hasVueErrors).toBe(false);
- });
-
- it('restores axios adapter after mocking', () => {
- if (getDefaultAdapter() !== axiosDefaultAdapter) {
- fail('axios adapter is not restored! Did you forget a restore() on MockAdapter?');
- }
- });
-});
diff --git a/spec/javascripts/test_constants.js b/spec/javascripts/test_constants.js
deleted file mode 100644
index de7b3a0e80c..00000000000
--- a/spec/javascripts/test_constants.js
+++ /dev/null
@@ -1 +0,0 @@
-export * from '../frontend/__helpers__/test_constants';
diff --git a/spec/lib/api/entities/clusters/agent_authorization_spec.rb b/spec/lib/api/entities/clusters/agent_authorization_spec.rb
new file mode 100644
index 00000000000..101a8af4ac4
--- /dev/null
+++ b/spec/lib/api/entities/clusters/agent_authorization_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::Entities::Clusters::AgentAuthorization do
+ let_it_be(:authorization) { create(:agent_group_authorization) }
+
+ subject { described_class.new(authorization).as_json }
+
+ it 'includes basic fields' do
+ expect(subject).to include(
+ id: authorization.agent_id,
+ config_project: a_hash_including(id: authorization.agent.project_id),
+ configuration: authorization.config
+ )
+ end
+end
diff --git a/spec/lib/backup/gitaly_backup_spec.rb b/spec/lib/backup/gitaly_backup_spec.rb
index a48a1752eff..7797bd12f0e 100644
--- a/spec/lib/backup/gitaly_backup_spec.rb
+++ b/spec/lib/backup/gitaly_backup_spec.rb
@@ -131,8 +131,19 @@ RSpec.describe Backup::GitalyBackup do
context 'parallel option set' do
let(:parallel) { 3 }
- it 'does not pass parallel option through' do
- expect(Open3).to receive(:popen2).with(ENV, anything, 'restore', '-path', anything).and_call_original
+ it 'passes parallel option through' do
+ expect(Open3).to receive(:popen2).with(ENV, anything, 'restore', '-path', anything, '-parallel', '3').and_call_original
+
+ subject.start(:restore)
+ subject.wait
+ end
+ end
+
+ context 'parallel_storage option set' do
+ let(:parallel_storage) { 3 }
+
+ it 'passes parallel option through' do
+ expect(Open3).to receive(:popen2).with(ENV, anything, 'restore', '-path', anything, '-parallel-storage', '3').and_call_original
subject.start(:restore)
subject.wait
diff --git a/spec/lib/backup/manager_spec.rb b/spec/lib/backup/manager_spec.rb
index 2cc1bf41d18..32eea82cfdf 100644
--- a/spec/lib/backup/manager_spec.rb
+++ b/spec/lib/backup/manager_spec.rb
@@ -432,6 +432,77 @@ RSpec.describe Backup::Manager do
end
end
+ context 'with AWS with server side encryption' do
+ let(:connection) { ::Fog::Storage.new(Gitlab.config.backup.upload.connection.symbolize_keys) }
+ let(:encryption_key) { nil }
+ let(:encryption) { nil }
+ let(:storage_options) { nil }
+
+ before do
+ stub_backup_setting(
+ upload: {
+ connection: {
+ provider: 'AWS',
+ aws_access_key_id: 'AWS_ACCESS_KEY_ID',
+ aws_secret_access_key: 'AWS_SECRET_ACCESS_KEY'
+ },
+ remote_directory: 'directory',
+ multipart_chunk_size: Gitlab.config.backup.upload.multipart_chunk_size,
+ encryption: encryption,
+ encryption_key: encryption_key,
+ storage_options: storage_options,
+ storage_class: nil
+ }
+ )
+
+ connection.directories.create(key: Gitlab.config.backup.upload.remote_directory)
+ end
+
+ context 'with SSE-S3 without using storage_options' do
+ let(:encryption) { 'AES256' }
+
+ it 'sets encryption attributes' do
+ result = subject.upload
+
+ expect(result.key).to be_present
+ expect(result.encryption).to eq('AES256')
+ expect(result.encryption_key).to be_nil
+ expect(result.kms_key_id).to be_nil
+ end
+ end
+
+ context 'with SSE-C (customer-provided keys) options' do
+ let(:encryption) { 'AES256' }
+ let(:encryption_key) { SecureRandom.hex }
+
+ it 'sets encryption attributes' do
+ result = subject.upload
+
+ expect(result.key).to be_present
+ expect(result.encryption).to eq(encryption)
+ expect(result.encryption_key).to eq(encryption_key)
+ expect(result.kms_key_id).to be_nil
+ end
+ end
+
+ context 'with SSE-KMS options' do
+ let(:storage_options) do
+ {
+ server_side_encryption: 'aws:kms',
+ server_side_encryption_kms_key_id: 'arn:aws:kms:12345'
+ }
+ end
+
+ it 'sets encryption attributes' do
+ result = subject.upload
+
+ expect(result.key).to be_present
+ expect(result.encryption).to eq('aws:kms')
+ expect(result.kms_key_id).to eq('arn:aws:kms:12345')
+ end
+ end
+ end
+
context 'with Google provider' do
before do
stub_backup_setting(
diff --git a/spec/lib/banzai/filter/audio_link_filter_spec.rb b/spec/lib/banzai/filter/audio_link_filter_spec.rb
index 4198a50e980..71e069eb29f 100644
--- a/spec/lib/banzai/filter/audio_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/audio_link_filter_spec.rb
@@ -25,18 +25,14 @@ RSpec.describe Banzai::Filter::AudioLinkFilter do
it 'replaces the image tag with an audio tag' do
container = filter(image).children.first
- expect(container.name).to eq 'div'
- expect(container['class']).to eq 'audio-container'
+ expect(container.name).to eq 'span'
+ expect(container['class']).to eq 'media-container audio-container'
- audio, paragraph = container.children
+ audio, link = container.children
expect(audio.name).to eq 'audio'
expect(audio['src']).to eq src
- expect(paragraph.name).to eq 'p'
-
- link = paragraph.children.first
-
expect(link.name).to eq 'a'
expect(link['href']).to eq src
expect(link['target']).to eq '_blank'
@@ -105,15 +101,13 @@ RSpec.describe Banzai::Filter::AudioLinkFilter do
image = %(<img src="#{proxy_src}" data-canonical-src="#{canonical_src}"/>)
container = filter(image).children.first
- expect(container['class']).to eq 'audio-container'
+ expect(container['class']).to eq 'media-container audio-container'
- audio, paragraph = container.children
+ audio, link = container.children
expect(audio['src']).to eq proxy_src
expect(audio['data-canonical-src']).to eq canonical_src
- link = paragraph.children.first
-
expect(link['href']).to eq proxy_src
end
end
diff --git a/spec/lib/banzai/filter/video_link_filter_spec.rb b/spec/lib/banzai/filter/video_link_filter_spec.rb
index ec954aa9163..a0b0ba309f5 100644
--- a/spec/lib/banzai/filter/video_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/video_link_filter_spec.rb
@@ -25,20 +25,16 @@ RSpec.describe Banzai::Filter::VideoLinkFilter do
it 'replaces the image tag with a video tag' do
container = filter(image).children.first
- expect(container.name).to eq 'div'
- expect(container['class']).to eq 'video-container'
+ expect(container.name).to eq 'span'
+ expect(container['class']).to eq 'media-container video-container'
- video, paragraph = container.children
+ video, link = container.children
expect(video.name).to eq 'video'
expect(video['src']).to eq src
expect(video['width']).to eq "400"
expect(video['preload']).to eq 'metadata'
- expect(paragraph.name).to eq 'p'
-
- link = paragraph.children.first
-
expect(link.name).to eq 'a'
expect(link['href']).to eq src
expect(link['target']).to eq '_blank'
@@ -107,15 +103,13 @@ RSpec.describe Banzai::Filter::VideoLinkFilter do
image = %(<img src="#{proxy_src}" data-canonical-src="#{canonical_src}"/>)
container = filter(image).children.first
- expect(container['class']).to eq 'video-container'
+ expect(container['class']).to eq 'media-container video-container'
- video, paragraph = container.children
+ video, link = container.children
expect(video['src']).to eq proxy_src
expect(video['data-canonical-src']).to eq canonical_src
- link = paragraph.children.first
-
expect(link['href']).to eq proxy_src
end
end
diff --git a/spec/lib/banzai/reference_parser/base_parser_spec.rb b/spec/lib/banzai/reference_parser/base_parser_spec.rb
index 095500cdc53..4701caa0667 100644
--- a/spec/lib/banzai/reference_parser/base_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/base_parser_spec.rb
@@ -247,15 +247,15 @@ RSpec.describe Banzai::ReferenceParser::BaseParser do
end
end
- it 'returns referenceable and visible objects, alongside nodes that are referenceable but not visible' do
- expect(subject.gather_references(nodes)).to match(
- visible: contain_exactly(6, 8, 10),
- not_visible: match_array(nodes.select { |n| n.id.even? && n.id <= 5 })
- )
+ it 'returns referenceable and visible objects, alongside all and visible nodes' do
+ referenceable = nodes.select { |n| n.id.even? }
+ visible = nodes.select { |n| [6, 8, 10].include?(n.id) }
+
+ expect_gathered_references(subject.gather_references(nodes), [6, 8, 10], referenceable, visible)
end
it 'is always empty if the input is empty' do
- expect(subject.gather_references([])) .to match(visible: be_empty, not_visible: be_empty)
+ expect_gathered_references(subject.gather_references([]), [], [], [])
end
end
diff --git a/spec/lib/banzai/reference_parser/mentioned_group_parser_spec.rb b/spec/lib/banzai/reference_parser/mentioned_group_parser_spec.rb
index 4610da7cbe6..576e629d271 100644
--- a/spec/lib/banzai/reference_parser/mentioned_group_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/mentioned_group_parser_spec.rb
@@ -19,7 +19,7 @@ RSpec.describe Banzai::ReferenceParser::MentionedGroupParser do
it 'returns empty array' do
link['data-group'] = project.group.id.to_s
- expect_gathered_references(subject.gather_references([link]), [], 1)
+ expect_gathered_references(subject.gather_references([link]), [], [link], [])
end
end
@@ -30,7 +30,7 @@ RSpec.describe Banzai::ReferenceParser::MentionedGroupParser do
end
it 'returns groups' do
- expect_gathered_references(subject.gather_references([link]), [group], 0)
+ expect_gathered_references(subject.gather_references([link]), [group], [link], [link])
end
end
@@ -38,7 +38,7 @@ RSpec.describe Banzai::ReferenceParser::MentionedGroupParser do
it 'returns an empty Array' do
link['data-group'] = 'test-non-existing'
- expect_gathered_references(subject.gather_references([link]), [], 1)
+ expect_gathered_references(subject.gather_references([link]), [], [link], [])
end
end
end
diff --git a/spec/lib/banzai/reference_parser/mentioned_project_parser_spec.rb b/spec/lib/banzai/reference_parser/mentioned_project_parser_spec.rb
index 7eb58ee40d3..983407addce 100644
--- a/spec/lib/banzai/reference_parser/mentioned_project_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/mentioned_project_parser_spec.rb
@@ -19,7 +19,7 @@ RSpec.describe Banzai::ReferenceParser::MentionedProjectParser do
it 'returns empty Array' do
link['data-project'] = project.id.to_s
- expect_gathered_references(subject.gather_references([link]), [], 1)
+ expect_gathered_references(subject.gather_references([link]), [], [link], [])
end
end
@@ -30,7 +30,7 @@ RSpec.describe Banzai::ReferenceParser::MentionedProjectParser do
end
it 'returns an Array of referenced projects' do
- expect_gathered_references(subject.gather_references([link]), [project], 0)
+ expect_gathered_references(subject.gather_references([link]), [project], [link], [link])
end
end
@@ -38,7 +38,7 @@ RSpec.describe Banzai::ReferenceParser::MentionedProjectParser do
it 'returns an empty Array' do
link['data-project'] = 'inexisting-project-id'
- expect_gathered_references(subject.gather_references([link]), [], 1)
+ expect_gathered_references(subject.gather_references([link]), [], [link], [])
end
end
end
diff --git a/spec/lib/banzai/reference_parser/mentioned_user_parser_spec.rb b/spec/lib/banzai/reference_parser/mentioned_user_parser_spec.rb
index 4be07866db1..f117d796dad 100644
--- a/spec/lib/banzai/reference_parser/mentioned_user_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/mentioned_user_parser_spec.rb
@@ -22,7 +22,7 @@ RSpec.describe Banzai::ReferenceParser::MentionedUserParser do
end
it 'returns empty list of users' do
- expect_gathered_references(subject.gather_references([link]), [], 0)
+ expect_gathered_references(subject.gather_references([link]), [], [link], [link])
end
end
end
@@ -35,7 +35,7 @@ RSpec.describe Banzai::ReferenceParser::MentionedUserParser do
end
it 'returns empty list of users' do
- expect_gathered_references(subject.gather_references([link]), [], 0)
+ expect_gathered_references(subject.gather_references([link]), [], [link], [link])
end
end
end
@@ -44,7 +44,7 @@ RSpec.describe Banzai::ReferenceParser::MentionedUserParser do
it 'returns an Array of users' do
link['data-user'] = user.id.to_s
- expect_gathered_references(subject.gather_references([link]), [user], 0)
+ expect_gathered_references(subject.gather_references([link]), [user], [link], [link])
end
end
end
diff --git a/spec/lib/banzai/reference_parser/project_parser_spec.rb b/spec/lib/banzai/reference_parser/project_parser_spec.rb
index 6358a04f12a..2c0b6c417b0 100644
--- a/spec/lib/banzai/reference_parser/project_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/project_parser_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe Banzai::ReferenceParser::ProjectParser do
it 'returns an Array of projects' do
link['data-project'] = project.id.to_s
- expect_gathered_references(subject.gather_references([link]), [project], 0)
+ expect_gathered_references(subject.gather_references([link]), [project], [link], [link])
end
end
@@ -25,7 +25,7 @@ RSpec.describe Banzai::ReferenceParser::ProjectParser do
it 'returns an empty Array' do
link['data-project'] = ''
- expect_gathered_references(subject.gather_references([link]), [], 1)
+ expect_gathered_references(subject.gather_references([link]), [], [link], [])
end
end
@@ -35,7 +35,7 @@ RSpec.describe Banzai::ReferenceParser::ProjectParser do
link['data-project'] = private_project.id.to_s
- expect_gathered_references(subject.gather_references([link]), [], 1)
+ expect_gathered_references(subject.gather_references([link]), [], [link], [])
end
it 'returns an Array when authorized' do
@@ -43,7 +43,7 @@ RSpec.describe Banzai::ReferenceParser::ProjectParser do
link['data-project'] = private_project.id.to_s
- expect_gathered_references(subject.gather_references([link]), [private_project], 0)
+ expect_gathered_references(subject.gather_references([link]), [private_project], [link], [link])
end
end
end
diff --git a/spec/lib/bulk_imports/common/pipelines/entity_finisher_spec.rb b/spec/lib/bulk_imports/common/pipelines/entity_finisher_spec.rb
new file mode 100644
index 00000000000..c1a9ea7b7e2
--- /dev/null
+++ b/spec/lib/bulk_imports/common/pipelines/entity_finisher_spec.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe BulkImports::Common::Pipelines::EntityFinisher do
+ it 'updates the entity status to finished' do
+ entity = create(:bulk_import_entity, :started)
+ pipeline_tracker = create(:bulk_import_tracker, entity: entity)
+ context = BulkImports::Pipeline::Context.new(pipeline_tracker)
+ subject = described_class.new(context)
+
+ expect_next_instance_of(Gitlab::Import::Logger) do |logger|
+ expect(logger)
+ .to receive(:info)
+ .with(
+ bulk_import_id: entity.bulk_import.id,
+ bulk_import_entity_id: entity.id,
+ bulk_import_entity_type: entity.source_type,
+ pipeline_class: described_class.name,
+ message: 'Entity finished'
+ )
+ end
+
+ expect { subject.run }
+ .to change(entity, :status_name).to(:finished)
+ end
+
+ context 'when entity is in a final finished or failed state' do
+ shared_examples 'performs no state update' do |entity_state|
+ it 'does nothing' do
+ entity = create(:bulk_import_entity, entity_state)
+ pipeline_tracker = create(:bulk_import_tracker, entity: entity)
+ context = BulkImports::Pipeline::Context.new(pipeline_tracker)
+ subject = described_class.new(context)
+
+ expect { subject.run }
+ .not_to change(entity, :status_name)
+ end
+ end
+
+ include_examples 'performs no state update', :finished
+ include_examples 'performs no state update', :failed
+ end
+
+ context 'when all entity trackers failed' do
+ it 'marks entity as failed' do
+ entity = create(:bulk_import_entity, :started)
+ create(:bulk_import_tracker, :failed, entity: entity)
+ pipeline_tracker = create(:bulk_import_tracker, entity: entity, relation: described_class)
+ context = BulkImports::Pipeline::Context.new(pipeline_tracker)
+
+ described_class.new(context).run
+
+ expect(entity.reload.failed?).to eq(true)
+ end
+ end
+end
diff --git a/spec/lib/bulk_imports/groups/graphql/get_projects_query_spec.rb b/spec/lib/bulk_imports/groups/graphql/get_projects_query_spec.rb
new file mode 100644
index 00000000000..1a7c5a4993c
--- /dev/null
+++ b/spec/lib/bulk_imports/groups/graphql/get_projects_query_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe BulkImports::Groups::Graphql::GetProjectsQuery do
+ describe '#variables' do
+ it 'returns valid variables based on entity information' do
+ tracker = create(:bulk_import_tracker)
+ context = BulkImports::Pipeline::Context.new(tracker)
+
+ query = GraphQL::Query.new(
+ GitlabSchema,
+ described_class.to_s,
+ variables: described_class.variables(context)
+ )
+ result = GitlabSchema.static_validator.validate(query)
+
+ expect(result[:errors]).to be_empty
+ end
+
+ context 'with invalid variables' do
+ it 'raises an error' do
+ expect { GraphQL::Query.new(GitlabSchema, described_class.to_s, variables: 'invalid') }.to raise_error(ArgumentError)
+ end
+ end
+ end
+
+ describe '#data_path' do
+ it 'returns data path' do
+ expected = %w[data group projects nodes]
+
+ expect(described_class.data_path).to eq(expected)
+ end
+ end
+
+ describe '#page_info_path' do
+ it 'returns pagination information path' do
+ expected = %w[data group projects page_info]
+
+ expect(described_class.page_info_path).to eq(expected)
+ end
+ end
+end
diff --git a/spec/lib/bulk_imports/groups/pipelines/entity_finisher_spec.rb b/spec/lib/bulk_imports/groups/pipelines/entity_finisher_spec.rb
deleted file mode 100644
index b97aeb435b9..00000000000
--- a/spec/lib/bulk_imports/groups/pipelines/entity_finisher_spec.rb
+++ /dev/null
@@ -1,57 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe BulkImports::Groups::Pipelines::EntityFinisher do
- it 'updates the entity status to finished' do
- entity = create(:bulk_import_entity, :started)
- pipeline_tracker = create(:bulk_import_tracker, entity: entity)
- context = BulkImports::Pipeline::Context.new(pipeline_tracker)
- subject = described_class.new(context)
-
- expect_next_instance_of(Gitlab::Import::Logger) do |logger|
- expect(logger)
- .to receive(:info)
- .with(
- bulk_import_id: entity.bulk_import.id,
- bulk_import_entity_id: entity.id,
- bulk_import_entity_type: entity.source_type,
- pipeline_class: described_class.name,
- message: 'Entity finished'
- )
- end
-
- expect { subject.run }
- .to change(entity, :status_name).to(:finished)
- end
-
- context 'when entity is in a final finished or failed state' do
- shared_examples 'performs no state update' do |entity_state|
- it 'does nothing' do
- entity = create(:bulk_import_entity, entity_state)
- pipeline_tracker = create(:bulk_import_tracker, entity: entity)
- context = BulkImports::Pipeline::Context.new(pipeline_tracker)
- subject = described_class.new(context)
-
- expect { subject.run }
- .not_to change(entity, :status_name)
- end
- end
-
- include_examples 'performs no state update', :finished
- include_examples 'performs no state update', :failed
- end
-
- context 'when all entity trackers failed' do
- it 'marks entity as failed' do
- entity = create(:bulk_import_entity, :started)
- create(:bulk_import_tracker, :failed, entity: entity)
- pipeline_tracker = create(:bulk_import_tracker, entity: entity, relation: described_class)
- context = BulkImports::Pipeline::Context.new(pipeline_tracker)
-
- described_class.new(context).run
-
- expect(entity.reload.failed?).to eq(true)
- end
- end
-end
diff --git a/spec/lib/bulk_imports/groups/pipelines/project_entities_pipeline_spec.rb b/spec/lib/bulk_imports/groups/pipelines/project_entities_pipeline_spec.rb
new file mode 100644
index 00000000000..5b6c93e695f
--- /dev/null
+++ b/spec/lib/bulk_imports/groups/pipelines/project_entities_pipeline_spec.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe BulkImports::Groups::Pipelines::ProjectEntitiesPipeline do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:destination_group) { create(:group) }
+
+ let_it_be(:entity) do
+ create(
+ :bulk_import_entity,
+ group: destination_group,
+ destination_namespace: destination_group.full_path
+ )
+ end
+
+ let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) }
+ let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) }
+
+ let(:extracted_data) do
+ BulkImports::Pipeline::ExtractedData.new(data: {
+ 'name' => 'project',
+ 'full_path' => 'group/project'
+ })
+ end
+
+ subject { described_class.new(context) }
+
+ describe '#run' do
+ before do
+ allow_next_instance_of(BulkImports::Common::Extractors::GraphqlExtractor) do |extractor|
+ allow(extractor).to receive(:extract).and_return(extracted_data)
+ end
+
+ destination_group.add_owner(user)
+ end
+
+ it 'creates project entity' do
+ expect { subject.run }.to change(BulkImports::Entity, :count).by(1)
+
+ project_entity = BulkImports::Entity.last
+
+ expect(project_entity.source_type).to eq('project_entity')
+ expect(project_entity.source_full_path).to eq('group/project')
+ expect(project_entity.destination_name).to eq('project')
+ expect(project_entity.destination_namespace).to eq(destination_group.full_path)
+ end
+ end
+
+ describe 'pipeline parts' do
+ it { expect(described_class).to include_module(BulkImports::Pipeline) }
+ it { expect(described_class).to include_module(BulkImports::Pipeline::Runner) }
+
+ it 'has extractors' do
+ expect(described_class.get_extractor).to eq(
+ klass: BulkImports::Common::Extractors::GraphqlExtractor,
+ options: {
+ query: BulkImports::Groups::Graphql::GetProjectsQuery
+ }
+ )
+ end
+
+ it 'has transformers' do
+ expect(described_class.transformers).to contain_exactly(
+ { klass: BulkImports::Common::Transformers::ProhibitedAttributesTransformer, options: nil }
+ )
+ end
+ end
+end
diff --git a/spec/lib/bulk_imports/groups/stage_spec.rb b/spec/lib/bulk_imports/groups/stage_spec.rb
new file mode 100644
index 00000000000..81c0ffc14d4
--- /dev/null
+++ b/spec/lib/bulk_imports/groups/stage_spec.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe BulkImports::Groups::Stage do
+ let(:pipelines) do
+ [
+ [0, BulkImports::Groups::Pipelines::GroupPipeline],
+ [1, BulkImports::Groups::Pipelines::GroupAvatarPipeline],
+ [1, BulkImports::Groups::Pipelines::SubgroupEntitiesPipeline],
+ [1, BulkImports::Groups::Pipelines::MembersPipeline],
+ [1, BulkImports::Groups::Pipelines::LabelsPipeline],
+ [1, BulkImports::Groups::Pipelines::MilestonesPipeline],
+ [1, BulkImports::Groups::Pipelines::BadgesPipeline],
+ [2, BulkImports::Groups::Pipelines::BoardsPipeline]
+ ]
+ end
+
+ describe '.pipelines' do
+ it 'list all the pipelines with their stage number, ordered by stage' do
+ expect(described_class.pipelines & pipelines).to eq(pipelines)
+ expect(described_class.pipelines.last.last).to eq(BulkImports::Common::Pipelines::EntityFinisher)
+ end
+
+ it 'includes project entities pipeline' do
+ stub_feature_flags(bulk_import_projects: true)
+
+ expect(described_class.pipelines).to include([1, BulkImports::Groups::Pipelines::ProjectEntitiesPipeline])
+ end
+
+ context 'when bulk_import_projects feature flag is disabled' do
+ it 'does not include project entities pipeline' do
+ stub_feature_flags(bulk_import_projects: false)
+
+ expect(described_class.pipelines.flatten).not_to include(BulkImports::Groups::Pipelines::ProjectEntitiesPipeline)
+ end
+ end
+ end
+end
diff --git a/spec/lib/bulk_imports/projects/pipelines/project_pipeline_spec.rb b/spec/lib/bulk_imports/projects/pipelines/project_pipeline_spec.rb
new file mode 100644
index 00000000000..c53c0849931
--- /dev/null
+++ b/spec/lib/bulk_imports/projects/pipelines/project_pipeline_spec.rb
@@ -0,0 +1,95 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe BulkImports::Projects::Pipelines::ProjectPipeline do
+ describe '#run' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:bulk_import) { create(:bulk_import, user: user) }
+
+ let_it_be(:entity) do
+ create(
+ :bulk_import_entity,
+ source_type: :project_entity,
+ bulk_import: bulk_import,
+ source_full_path: 'source/full/path',
+ destination_name: 'My Destination Project',
+ destination_namespace: group.full_path
+ )
+ end
+
+ let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) }
+ let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) }
+
+ let(:project_data) do
+ {
+ 'visibility' => 'private',
+ 'created_at' => 10.days.ago,
+ 'archived' => false,
+ 'shared_runners_enabled' => true,
+ 'container_registry_enabled' => true,
+ 'only_allow_merge_if_pipeline_succeeds' => true,
+ 'only_allow_merge_if_all_discussions_are_resolved' => true,
+ 'request_access_enabled' => true,
+ 'printing_merge_request_link_enabled' => true,
+ 'remove_source_branch_after_merge' => true,
+ 'autoclose_referenced_issues' => true,
+ 'suggestion_commit_message' => 'message',
+ 'wiki_enabled' => true
+ }
+ end
+
+ subject(:project_pipeline) { described_class.new(context) }
+
+ before do
+ allow_next_instance_of(BulkImports::Common::Extractors::GraphqlExtractor) do |extractor|
+ allow(extractor).to receive(:extract).and_return(BulkImports::Pipeline::ExtractedData.new(data: project_data))
+ end
+
+ group.add_owner(user)
+ end
+
+ it 'imports new project into destination group', :aggregate_failures do
+ expect { project_pipeline.run }.to change { Project.count }.by(1)
+
+ project_path = 'my-destination-project'
+ imported_project = Project.find_by_path(project_path)
+
+ expect(imported_project).not_to be_nil
+ expect(imported_project.group).to eq(group)
+ expect(imported_project.suggestion_commit_message).to eq('message')
+ expect(imported_project.archived?).to eq(project_data['archived'])
+ expect(imported_project.shared_runners_enabled?).to eq(project_data['shared_runners_enabled'])
+ expect(imported_project.container_registry_enabled?).to eq(project_data['container_registry_enabled'])
+ expect(imported_project.only_allow_merge_if_pipeline_succeeds?).to eq(project_data['only_allow_merge_if_pipeline_succeeds'])
+ expect(imported_project.only_allow_merge_if_all_discussions_are_resolved?).to eq(project_data['only_allow_merge_if_all_discussions_are_resolved'])
+ expect(imported_project.request_access_enabled?).to eq(project_data['request_access_enabled'])
+ expect(imported_project.printing_merge_request_link_enabled?).to eq(project_data['printing_merge_request_link_enabled'])
+ expect(imported_project.remove_source_branch_after_merge?).to eq(project_data['remove_source_branch_after_merge'])
+ expect(imported_project.autoclose_referenced_issues?).to eq(project_data['autoclose_referenced_issues'])
+ expect(imported_project.wiki_enabled?).to eq(project_data['wiki_enabled'])
+ end
+ end
+
+ describe 'pipeline parts' do
+ it { expect(described_class).to include_module(BulkImports::Pipeline) }
+ it { expect(described_class).to include_module(BulkImports::Pipeline::Runner) }
+
+ it 'has extractors' do
+ expect(described_class.get_extractor)
+ .to eq(
+ klass: BulkImports::Common::Extractors::GraphqlExtractor,
+ options: { query: BulkImports::Projects::Graphql::GetProjectQuery }
+ )
+ end
+
+ it 'has transformers' do
+ expect(described_class.transformers)
+ .to contain_exactly(
+ { klass: BulkImports::Common::Transformers::ProhibitedAttributesTransformer, options: nil },
+ { klass: BulkImports::Projects::Transformers::ProjectAttributesTransformer, options: nil }
+ )
+ end
+ end
+end
diff --git a/spec/lib/bulk_imports/projects/stage_spec.rb b/spec/lib/bulk_imports/projects/stage_spec.rb
new file mode 100644
index 00000000000..428812a34ef
--- /dev/null
+++ b/spec/lib/bulk_imports/projects/stage_spec.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe BulkImports::Projects::Stage do
+ let(:pipelines) do
+ [
+ [0, BulkImports::Projects::Pipelines::ProjectPipeline],
+ [1, BulkImports::Common::Pipelines::EntityFinisher]
+ ]
+ end
+
+ describe '.pipelines' do
+ it 'list all the pipelines with their stage number, ordered by stage' do
+ expect(described_class.pipelines).to eq(pipelines)
+ end
+ end
+end
diff --git a/spec/lib/bulk_imports/projects/transformers/project_attributes_transformer_spec.rb b/spec/lib/bulk_imports/projects/transformers/project_attributes_transformer_spec.rb
new file mode 100644
index 00000000000..822bb9a5605
--- /dev/null
+++ b/spec/lib/bulk_imports/projects/transformers/project_attributes_transformer_spec.rb
@@ -0,0 +1,83 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe BulkImports::Projects::Transformers::ProjectAttributesTransformer do
+ describe '#transform' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:destination_group) { create(:group) }
+ let_it_be(:project) { create(:project, name: 'My Source Project') }
+ let_it_be(:bulk_import) { create(:bulk_import, user: user) }
+
+ let_it_be(:entity) do
+ create(
+ :bulk_import_entity,
+ source_type: :project_entity,
+ bulk_import: bulk_import,
+ source_full_path: 'source/full/path',
+ destination_name: 'Destination Project Name',
+ destination_namespace: destination_group.full_path
+ )
+ end
+
+ let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) }
+ let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) }
+
+ let(:data) do
+ {
+ 'name' => 'source_name',
+ 'visibility' => 'private'
+ }
+ end
+
+ subject(:transformed_data) { described_class.new.transform(context, data) }
+
+ it 'transforms name to destination name' do
+ expect(transformed_data[:name]).to eq(entity.destination_name)
+ end
+
+ it 'adds path as parameterized name' do
+ expect(transformed_data[:path]).to eq(entity.destination_name.parameterize)
+ end
+
+ it 'transforms visibility level' do
+ visibility = data['visibility']
+
+ expect(transformed_data).not_to have_key(:visibility)
+ expect(transformed_data[:visibility_level]).to eq(Gitlab::VisibilityLevel.string_options[visibility])
+ end
+
+ it 'adds import type' do
+ expect(transformed_data[:import_type]).to eq(described_class::PROJECT_IMPORT_TYPE)
+ end
+
+ describe 'namespace_id' do
+ context 'when destination namespace is present' do
+ it 'adds namespace_id' do
+ expect(transformed_data[:namespace_id]).to eq(destination_group.id)
+ end
+ end
+
+ context 'when destination namespace is blank' do
+ it 'does not add namespace_id key' do
+ entity = create(
+ :bulk_import_entity,
+ source_type: :project_entity,
+ bulk_import: bulk_import,
+ source_full_path: 'source/full/path',
+ destination_name: 'Destination Project Name',
+ destination_namespace: ''
+ )
+
+ context = double(entity: entity)
+
+ expect(described_class.new.transform(context, data)).not_to have_key(:namespace_id)
+ end
+ end
+ end
+
+ it 'converts all keys to symbols' do
+ expect(transformed_data.keys).to contain_exactly(:name, :path, :import_type, :visibility_level, :namespace_id)
+ end
+ end
+end
diff --git a/spec/lib/bulk_imports/stage_spec.rb b/spec/lib/bulk_imports/stage_spec.rb
deleted file mode 100644
index 4398b00e7e9..00000000000
--- a/spec/lib/bulk_imports/stage_spec.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-# frozen_string_literal: true
-
-require 'fast_spec_helper'
-
-RSpec.describe BulkImports::Stage do
- let(:pipelines) do
- [
- [0, BulkImports::Groups::Pipelines::GroupPipeline],
- [1, BulkImports::Groups::Pipelines::GroupAvatarPipeline],
- [1, BulkImports::Groups::Pipelines::SubgroupEntitiesPipeline],
- [1, BulkImports::Groups::Pipelines::MembersPipeline],
- [1, BulkImports::Groups::Pipelines::LabelsPipeline],
- [1, BulkImports::Groups::Pipelines::MilestonesPipeline],
- [1, BulkImports::Groups::Pipelines::BadgesPipeline],
- [2, BulkImports::Groups::Pipelines::BoardsPipeline]
- ]
- end
-
- describe '.pipelines' do
- it 'list all the pipelines with their stage number, ordered by stage' do
- expect(described_class.pipelines & pipelines).to eq(pipelines)
- expect(described_class.pipelines.last.last).to eq(BulkImports::Groups::Pipelines::EntityFinisher)
- end
- end
-
- describe '.pipeline_exists?' do
- it 'returns true when the given pipeline name exists in the pipelines list' do
- expect(described_class.pipeline_exists?(BulkImports::Groups::Pipelines::GroupPipeline)).to eq(true)
- expect(described_class.pipeline_exists?('BulkImports::Groups::Pipelines::GroupPipeline')).to eq(true)
- end
-
- it 'returns false when the given pipeline name exists in the pipelines list' do
- expect(described_class.pipeline_exists?('BulkImports::Groups::Pipelines::InexistentPipeline')).to eq(false)
- end
- end
-end
diff --git a/spec/lib/error_tracking/collector/dsn_spec.rb b/spec/lib/error_tracking/collector/dsn_spec.rb
new file mode 100644
index 00000000000..af55e6f20ec
--- /dev/null
+++ b/spec/lib/error_tracking/collector/dsn_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ErrorTracking::Collector::Dsn do
+ describe '.build__url' do
+ let(:gitlab) do
+ double(
+ protocol: 'https',
+ https: true,
+ host: 'gitlab.example.com',
+ port: '4567',
+ relative_url_root: nil
+ )
+ end
+
+ subject { described_class.build_url('abcdef1234567890', 778) }
+
+ it 'returns a valid URL' do
+ allow(Settings).to receive(:gitlab).and_return(gitlab)
+ allow(Settings).to receive(:gitlab_on_standard_port?).and_return(false)
+
+ is_expected.to eq('https://abcdef1234567890@gitlab.example.com:4567/api/v4/error_tracking/collector/778')
+ end
+ end
+end
diff --git a/spec/lib/gitlab/action_cable/request_store_callbacks_spec.rb b/spec/lib/gitlab/action_cable/request_store_callbacks_spec.rb
new file mode 100644
index 00000000000..3b73252709c
--- /dev/null
+++ b/spec/lib/gitlab/action_cable/request_store_callbacks_spec.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::ActionCable::RequestStoreCallbacks do
+ describe '.wrapper' do
+ it 'enables RequestStore in the inner block' do
+ expect(RequestStore.active?).to eq(false)
+
+ described_class.wrapper.call(
+ nil,
+ lambda do
+ expect(RequestStore.active?).to eq(true)
+ end
+ )
+
+ expect(RequestStore.active?).to eq(false)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/backfill_projects_with_coverage_spec.rb b/spec/lib/gitlab/background_migration/backfill_projects_with_coverage_spec.rb
new file mode 100644
index 00000000000..49056154744
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/backfill_projects_with_coverage_spec.rb
@@ -0,0 +1,94 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::BackfillProjectsWithCoverage, schema: 20210818185845 do
+ let(:projects) { table(:projects) }
+ let(:project_ci_feature_usages) { table(:project_ci_feature_usages) }
+ let(:ci_pipelines) { table(:ci_pipelines) }
+ let(:ci_daily_build_group_report_results) { table(:ci_daily_build_group_report_results) }
+ let(:group) { table(:namespaces).create!(name: 'user', path: 'user') }
+ let(:project_1) { projects.create!(namespace_id: group.id) }
+ let(:project_2) { projects.create!(namespace_id: group.id) }
+ let(:pipeline_1) { ci_pipelines.create!(project_id: project_1.id, source: 13) }
+ let(:pipeline_2) { ci_pipelines.create!(project_id: project_1.id, source: 13) }
+ let(:pipeline_3) { ci_pipelines.create!(project_id: project_2.id, source: 13) }
+ let(:pipeline_4) { ci_pipelines.create!(project_id: project_2.id, source: 13) }
+
+ subject { described_class.new }
+
+ describe '#perform' do
+ before do
+ ci_daily_build_group_report_results.create!(
+ id: 1,
+ project_id: project_1.id,
+ date: 4.days.ago,
+ last_pipeline_id: pipeline_1.id,
+ ref_path: 'main',
+ group_name: 'rspec',
+ data: { coverage: 95.0 },
+ default_branch: true,
+ group_id: group.id
+ )
+
+ ci_daily_build_group_report_results.create!(
+ id: 2,
+ project_id: project_1.id,
+ date: 3.days.ago,
+ last_pipeline_id: pipeline_2.id,
+ ref_path: 'main',
+ group_name: 'rspec',
+ data: { coverage: 95.0 },
+ default_branch: true,
+ group_id: group.id
+ )
+
+ ci_daily_build_group_report_results.create!(
+ id: 3,
+ project_id: project_2.id,
+ date: 2.days.ago,
+ last_pipeline_id: pipeline_3.id,
+ ref_path: 'main',
+ group_name: 'rspec',
+ data: { coverage: 95.0 },
+ default_branch: true,
+ group_id: group.id
+ )
+
+ ci_daily_build_group_report_results.create!(
+ id: 4,
+ project_id: project_2.id,
+ date: 1.day.ago,
+ last_pipeline_id: pipeline_4.id,
+ ref_path: 'test_branch',
+ group_name: 'rspec',
+ data: { coverage: 95.0 },
+ default_branch: false,
+ group_id: group.id
+ )
+
+ stub_const("#{described_class}::INSERT_DELAY_SECONDS", 0)
+ end
+
+ it 'creates entries per project and default_branch combination in the given range', :aggregate_failures do
+ subject.perform(1, 4, 2)
+
+ entries = project_ci_feature_usages.order('project_id ASC, default_branch DESC')
+
+ expect(entries.count).to eq(3)
+ expect(entries[0]).to have_attributes(project_id: project_1.id, feature: 1, default_branch: true)
+ expect(entries[1]).to have_attributes(project_id: project_2.id, feature: 1, default_branch: true)
+ expect(entries[2]).to have_attributes(project_id: project_2.id, feature: 1, default_branch: false)
+ end
+
+ context 'when an entry for the project and default branch combination already exists' do
+ before do
+ subject.perform(1, 4, 2)
+ end
+
+ it 'does not create a new entry' do
+ expect { subject.perform(1, 4, 2) }.not_to change { project_ci_feature_usages.count }
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/extract_project_topics_into_separate_table_spec.rb b/spec/lib/gitlab/background_migration/extract_project_topics_into_separate_table_spec.rb
new file mode 100644
index 00000000000..a111007a984
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/extract_project_topics_into_separate_table_spec.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::ExtractProjectTopicsIntoSeparateTable, schema: 20210730104800 do
+ it 'correctly extracts project topics into separate table' do
+ namespaces = table(:namespaces)
+ projects = table(:projects)
+ taggings = table(:taggings)
+ tags = table(:tags)
+ project_topics = table(:project_topics)
+ topics = table(:topics)
+
+ namespace = namespaces.create!(name: 'foo', path: 'foo')
+ project = projects.create!(namespace_id: namespace.id)
+ tag_1 = tags.create!(name: 'Topic1')
+ tag_2 = tags.create!(name: 'Topic2')
+ tag_3 = tags.create!(name: 'Topic3')
+ topic_3 = topics.create!(name: 'Topic3')
+ tagging_1 = taggings.create!(taggable_type: 'Project', taggable_id: project.id, context: 'topics', tag_id: tag_1.id)
+ tagging_2 = taggings.create!(taggable_type: 'Project', taggable_id: project.id, context: 'topics', tag_id: tag_2.id)
+ other_tagging = taggings.create!(taggable_type: 'Other', taggable_id: project.id, context: 'topics', tag_id: tag_1.id)
+ tagging_3 = taggings.create!(taggable_type: 'Project', taggable_id: project.id, context: 'topics', tag_id: tag_3.id)
+ tagging_4 = taggings.create!(taggable_type: 'Project', taggable_id: -1, context: 'topics', tag_id: tag_1.id)
+ tagging_5 = taggings.create!(taggable_type: 'Project', taggable_id: project.id, context: 'topics', tag_id: -1)
+
+ subject.perform(tagging_1.id, tagging_5.id)
+
+ # Tagging records
+ expect { tagging_1.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ expect { tagging_2.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ expect { other_tagging.reload }.not_to raise_error(ActiveRecord::RecordNotFound)
+ expect { tagging_3.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ expect { tagging_4.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ expect { tagging_5.reload }.to raise_error(ActiveRecord::RecordNotFound)
+
+ # Topic records
+ topic_1 = topics.find_by(name: 'Topic1')
+ topic_2 = topics.find_by(name: 'Topic2')
+ expect(topics.all).to contain_exactly(topic_1, topic_2, topic_3)
+
+ # ProjectTopic records
+ expect(project_topics.all.map(&:topic_id)).to contain_exactly(topic_1.id, topic_2.id, topic_3.id)
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/migrate_merge_request_diff_commit_users_spec.rb b/spec/lib/gitlab/background_migration/migrate_merge_request_diff_commit_users_spec.rb
index 496ce151032..91e8dcdf880 100644
--- a/spec/lib/gitlab/background_migration/migrate_merge_request_diff_commit_users_spec.rb
+++ b/spec/lib/gitlab/background_migration/migrate_merge_request_diff_commit_users_spec.rb
@@ -91,6 +91,18 @@ RSpec.describe Gitlab::BackgroundMigration::MigrateMergeRequestDiffCommitUsers d
end
describe '#perform' do
+ it 'skips jobs that have already been completed' do
+ Gitlab::Database::BackgroundMigrationJob.create!(
+ class_name: 'MigrateMergeRequestDiffCommitUsers',
+ arguments: [1, 10],
+ status: :succeeded
+ )
+
+ expect(migration).not_to receive(:get_data_to_update)
+
+ migration.perform(1, 10)
+ end
+
it 'migrates the data in the range' do
commits.create!(
merge_request_diff_id: diff.id,
diff --git a/spec/lib/gitlab/background_migration/migrate_pages_metadata_spec.rb b/spec/lib/gitlab/background_migration/migrate_pages_metadata_spec.rb
index 906a6a747c9..815dc2e73e5 100644
--- a/spec/lib/gitlab/background_migration/migrate_pages_metadata_spec.rb
+++ b/spec/lib/gitlab/background_migration/migrate_pages_metadata_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Gitlab::BackgroundMigration::MigratePagesMetadata, schema: 201909
subject(:migrate_pages_metadata) { described_class.new }
- describe '#perform_on_relation' do
+ describe '#perform' do
let(:namespaces) { table(:namespaces) }
let(:builds) { table(:ci_builds) }
let(:pages_metadata) { table(:project_pages_metadata) }
@@ -23,9 +23,9 @@ RSpec.describe Gitlab::BackgroundMigration::MigratePagesMetadata, schema: 201909
not_migrated_no_pages = projects.create!(namespace_id: namespace.id, name: 'Not Migrated No Pages')
project_not_in_relation_scope = projects.create!(namespace_id: namespace.id, name: 'Other')
- projects_relation = projects.where(id: [not_migrated_with_pages, not_migrated_no_pages, migrated])
+ ids = [not_migrated_no_pages.id, not_migrated_with_pages.id, migrated.id]
- migrate_pages_metadata.perform_on_relation(projects_relation)
+ migrate_pages_metadata.perform(ids.min, ids.max)
expect(pages_metadata.find_by_project_id(not_migrated_with_pages.id).deployed).to eq(true)
expect(pages_metadata.find_by_project_id(not_migrated_no_pages.id).deployed).to eq(false)
@@ -33,12 +33,4 @@ RSpec.describe Gitlab::BackgroundMigration::MigratePagesMetadata, schema: 201909
expect(pages_metadata.find_by_project_id(project_not_in_relation_scope.id)).to be_nil
end
end
-
- describe '#perform' do
- it 'creates relation and delegates to #perform_on_relation' do
- expect(migrate_pages_metadata).to receive(:perform_on_relation).with(projects.where(id: 3..5))
-
- migrate_pages_metadata.perform(3, 5)
- end
- end
end
diff --git a/spec/lib/gitlab/background_migration/steal_migrate_merge_request_diff_commit_users_spec.rb b/spec/lib/gitlab/background_migration/steal_migrate_merge_request_diff_commit_users_spec.rb
new file mode 100644
index 00000000000..f2fb2ab6b6e
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/steal_migrate_merge_request_diff_commit_users_spec.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::StealMigrateMergeRequestDiffCommitUsers do
+ let(:migration) { described_class.new }
+
+ describe '#perform' do
+ it 'processes the background migration' do
+ spy = instance_spy(
+ Gitlab::BackgroundMigration::MigrateMergeRequestDiffCommitUsers
+ )
+
+ allow(Gitlab::BackgroundMigration::MigrateMergeRequestDiffCommitUsers)
+ .to receive(:new)
+ .and_return(spy)
+
+ expect(spy).to receive(:perform).with(1, 4)
+ expect(migration).to receive(:schedule_next_job)
+
+ migration.perform(1, 4)
+ end
+ end
+
+ describe '#schedule_next_job' do
+ it 'schedules the next job in ascending order' do
+ Gitlab::Database::BackgroundMigrationJob.create!(
+ class_name: 'MigrateMergeRequestDiffCommitUsers',
+ arguments: [10, 20]
+ )
+
+ Gitlab::Database::BackgroundMigrationJob.create!(
+ class_name: 'MigrateMergeRequestDiffCommitUsers',
+ arguments: [40, 50]
+ )
+
+ expect(BackgroundMigrationWorker)
+ .to receive(:perform_in)
+ .with(5.minutes, 'StealMigrateMergeRequestDiffCommitUsers', [10, 20])
+
+ migration.schedule_next_job
+ end
+
+ it 'does not schedule any new jobs when there are none' do
+ expect(BackgroundMigrationWorker).not_to receive(:perform_in)
+
+ migration.schedule_next_job
+ end
+ end
+end
diff --git a/spec/lib/gitlab/changelog/config_spec.rb b/spec/lib/gitlab/changelog/config_spec.rb
index a464c1e57e5..c410ba4d116 100644
--- a/spec/lib/gitlab/changelog/config_spec.rb
+++ b/spec/lib/gitlab/changelog/config_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe Gitlab::Changelog::Config do
+ include ProjectForksHelper
+
let(:project) { build_stubbed(:project) }
describe '.from_git' do
@@ -13,7 +15,7 @@ RSpec.describe Gitlab::Changelog::Config do
expect(described_class)
.to receive(:from_hash)
- .with(project, 'date_format' => '%Y')
+ .with(project, { 'date_format' => '%Y' }, nil)
described_class.from_git(project)
end
@@ -33,12 +35,25 @@ RSpec.describe Gitlab::Changelog::Config do
describe '.from_hash' do
it 'sets the configuration according to a Hash' do
+ user1 = create(:user)
+ user2 = create(:user)
+ user3 = create(:user)
+ group = create(:group, path: 'group')
+ group2 = create(:group, path: 'group-path')
+ group.add_developer(user1)
+ group.add_developer(user2)
+ group2.add_developer(user3)
+
config = described_class.from_hash(
project,
- 'date_format' => 'foo',
- 'template' => 'bar',
- 'categories' => { 'foo' => 'bar' },
- 'tag_regex' => 'foo'
+ {
+ 'date_format' => 'foo',
+ 'template' => 'bar',
+ 'categories' => { 'foo' => 'bar' },
+ 'tag_regex' => 'foo',
+ 'include_groups' => %w[group group-path non-existent-group]
+ },
+ user1
)
expect(config.date_format).to eq('foo')
@@ -47,6 +62,7 @@ RSpec.describe Gitlab::Changelog::Config do
expect(config.categories).to eq({ 'foo' => 'bar' })
expect(config.tag_regex).to eq('foo')
+ expect(config.always_credit_user_ids).to match_array([user1.id, user2.id, user3.id])
end
it 'raises Error when the categories are not a Hash' do
@@ -66,20 +82,33 @@ RSpec.describe Gitlab::Changelog::Config do
end
describe '#contributor?' do
- it 'returns true if a user is a contributor' do
- user = build_stubbed(:author)
+ let(:project) { create(:project, :public, :repository) }
- allow(project.team).to receive(:contributor?).with(user).and_return(true)
-
- expect(described_class.new(project).contributor?(user)).to eq(true)
- end
+ context 'when user is a member of project' do
+ let(:user) { create(:user) }
- it "returns true if a user isn't a contributor" do
- user = build_stubbed(:author)
+ before do
+ project.add_developer(user)
+ end
- allow(project.team).to receive(:contributor?).with(user).and_return(false)
+ it { expect(described_class.new(project).contributor?(user)).to eq(false) }
+ end
- expect(described_class.new(project).contributor?(user)).to eq(false)
+ context 'when user has at least one merge request merged into default_branch' do
+ let(:contributor) { create(:user) }
+ let(:user_without_access) { create(:user) }
+ let(:user_fork) { fork_project(project, contributor, repository: true) }
+
+ before do
+ create(:merge_request, :merged,
+ author: contributor,
+ target_project: project,
+ source_project: user_fork,
+ target_branch: project.default_branch.to_s)
+ end
+
+ it { expect(described_class.new(project).contributor?(contributor)).to eq(true) }
+ it { expect(described_class.new(project).contributor?(user_without_access)).to eq(false) }
end
end
@@ -107,4 +136,55 @@ RSpec.describe Gitlab::Changelog::Config do
expect(config.format_date(time)).to eq('2021-01-05')
end
end
+
+ describe '#always_credit_author?' do
+ let_it_be(:group_member) { create(:user) }
+ let_it_be(:non_group_member) { create(:user) }
+ let_it_be(:group) { create(:group, :private, path: 'group') }
+
+ before do
+ group.add_developer(group_member)
+ end
+
+ context 'when include_groups is defined' do
+ context 'when user generating changelog has access to group' do
+ it 'returns whether author should always be credited' do
+ config = described_class.from_hash(
+ project,
+ { 'include_groups' => ['group'] },
+ group_member
+ )
+
+ expect(config.always_credit_author?(group_member)).to eq(true)
+ expect(config.always_credit_author?(non_group_member)).to eq(false)
+ end
+ end
+
+ context 'when user generating changelog has no access to group' do
+ it 'always returns false' do
+ config = described_class.from_hash(
+ project,
+ { 'include_groups' => ['group'] },
+ non_group_member
+ )
+
+ expect(config.always_credit_author?(group_member)).to eq(false)
+ expect(config.always_credit_author?(non_group_member)).to eq(false)
+ end
+ end
+ end
+
+ context 'when include_groups is not defined' do
+ it 'always returns false' do
+ config = described_class.from_hash(
+ project,
+ {},
+ group_member
+ )
+
+ expect(config.always_credit_author?(group_member)).to eq(false)
+ expect(config.always_credit_author?(non_group_member)).to eq(false)
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/changelog/release_spec.rb b/spec/lib/gitlab/changelog/release_spec.rb
index f95244d6750..d8434821640 100644
--- a/spec/lib/gitlab/changelog/release_spec.rb
+++ b/spec/lib/gitlab/changelog/release_spec.rb
@@ -94,6 +94,30 @@ RSpec.describe Gitlab::Changelog::Release do
end
end
+ context 'when the author should always be credited' do
+ it 'includes the author' do
+ allow(config).to receive(:contributor?).with(author).and_return(false)
+ allow(config).to receive(:always_credit_author?).with(author).and_return(true)
+
+ release.add_entry(
+ title: 'Entry title',
+ commit: commit,
+ category: 'fixed',
+ author: author
+ )
+
+ expect(release.to_markdown).to eq(<<~OUT)
+ ## 1.0.0 (2021-01-05)
+
+ ### fixed (1 change)
+
+ - [Entry title](#{commit.to_reference(full: true)}) \
+ by #{author.to_reference(full: true)}
+
+ OUT
+ end
+ end
+
context 'when a category has no entries' do
it "isn't included in the output" do
config.categories['kittens'] = 'Kittens'
diff --git a/spec/lib/gitlab/chat/command_spec.rb b/spec/lib/gitlab/chat/command_spec.rb
index 89c693daaa0..d99c07d1fa3 100644
--- a/spec/lib/gitlab/chat/command_spec.rb
+++ b/spec/lib/gitlab/chat/command_spec.rb
@@ -44,7 +44,7 @@ RSpec.describe Gitlab::Chat::Command do
let(:pipeline) { command.create_pipeline }
before do
- stub_ci_pipeline_yaml_file(gitlab_ci_yaml)
+ stub_ci_pipeline_to_return_yaml_file
project.add_developer(chat_name.user)
end
diff --git a/spec/lib/gitlab/checks/changes_access_spec.rb b/spec/lib/gitlab/checks/changes_access_spec.rb
index 4a74dfcec34..633c4baa931 100644
--- a/spec/lib/gitlab/checks/changes_access_spec.rb
+++ b/spec/lib/gitlab/checks/changes_access_spec.rb
@@ -8,53 +8,35 @@ RSpec.describe Gitlab::Checks::ChangesAccess do
subject { changes_access }
describe '#validate!' do
- shared_examples '#validate!' do
- before do
- allow(project).to receive(:lfs_enabled?).and_return(true)
- end
-
- context 'without failed checks' do
- it "doesn't raise an error" do
- expect { subject.validate! }.not_to raise_error
- end
-
- it 'calls lfs checks' do
- expect_next_instance_of(Gitlab::Checks::LfsCheck) do |instance|
- expect(instance).to receive(:validate!)
- end
+ before do
+ allow(project).to receive(:lfs_enabled?).and_return(true)
+ end
- subject.validate!
- end
+ context 'without failed checks' do
+ it "doesn't raise an error" do
+ expect { subject.validate! }.not_to raise_error
end
- context 'when time limit was reached' do
- it 'raises a TimeoutError' do
- logger = Gitlab::Checks::TimedLogger.new(start_time: timeout.ago, timeout: timeout)
- access = described_class.new(changes,
- project: project,
- user_access: user_access,
- protocol: protocol,
- logger: logger)
-
- expect { access.validate! }.to raise_error(Gitlab::Checks::TimedLogger::TimeoutError)
+ it 'calls lfs checks' do
+ expect_next_instance_of(Gitlab::Checks::LfsCheck) do |instance|
+ expect(instance).to receive(:validate!)
end
- end
- end
- context 'with batched commits enabled' do
- before do
- stub_feature_flags(changes_batch_commits: true)
+ subject.validate!
end
-
- it_behaves_like '#validate!'
end
- context 'with batched commits disabled' do
- before do
- stub_feature_flags(changes_batch_commits: false)
- end
+ context 'when time limit was reached' do
+ it 'raises a TimeoutError' do
+ logger = Gitlab::Checks::TimedLogger.new(start_time: timeout.ago, timeout: timeout)
+ access = described_class.new(changes,
+ project: project,
+ user_access: user_access,
+ protocol: protocol,
+ logger: logger)
- it_behaves_like '#validate!'
+ expect { access.validate! }.to raise_error(Gitlab::Checks::TimedLogger::TimeoutError)
+ end
end
end
@@ -192,6 +174,101 @@ RSpec.describe Gitlab::Checks::ChangesAccess do
end
end
+ describe '#single_change_accesses' do
+ let(:commits_for) { {} }
+ let(:expected_accesses) { [] }
+
+ shared_examples '#single_change_access' do
+ before do
+ commits_for.each do |id, commits|
+ expect(subject)
+ .to receive(:commits_for)
+ .with(id)
+ .and_return(commits)
+ end
+ end
+
+ it 'returns an array of SingleChangeAccess' do
+ # Commits are wrapped in a Gitlab::Lazy and thus need to be resolved
+ # first such that we can directly compare types.
+ actual_accesses = subject.single_change_accesses
+ .each { |access| access.instance_variable_set(:@commits, access.commits.to_a) }
+
+ expect(actual_accesses).to match_array(expected_accesses)
+ end
+ end
+
+ context 'with no changes' do
+ let(:changes) { [] }
+
+ it_behaves_like '#single_change_access'
+ end
+
+ context 'with a single change and no new commits' do
+ let(:commits_for) { { 'new' => [] } }
+ let(:changes) do
+ [
+ { oldrev: 'old', newrev: 'new', ref: 'refs/heads/branch' }
+ ]
+ end
+
+ let(:expected_accesses) do
+ [
+ have_attributes(oldrev: 'old', newrev: 'new', ref: 'refs/heads/branch', commits: [])
+ ]
+ end
+
+ it_behaves_like '#single_change_access'
+ end
+
+ context 'with a single change and new commits' do
+ let(:commits_for) { { 'new' => [create_commit('new', [])] } }
+ let(:changes) do
+ [
+ { oldrev: 'old', newrev: 'new', ref: 'refs/heads/branch' }
+ ]
+ end
+
+ let(:expected_accesses) do
+ [
+ have_attributes(oldrev: 'old', newrev: 'new', ref: 'refs/heads/branch', commits: [create_commit('new', [])])
+ ]
+ end
+
+ it_behaves_like '#single_change_access'
+ end
+
+ context 'with multiple changes' do
+ let(:commits_for) do
+ {
+ 'a' => [create_commit('a', [])],
+ 'c' => [create_commit('c', [])],
+ 'd' => []
+ }
+ end
+
+ let(:changes) do
+ [
+ { newrev: 'a', ref: 'refs/heads/a' },
+ { oldrev: 'b', ref: 'refs/heads/b' },
+ { oldrev: 'a', newrev: 'c', ref: 'refs/heads/c' },
+ { newrev: 'd', ref: 'refs/heads/d' }
+ ]
+ end
+
+ let(:expected_accesses) do
+ [
+ have_attributes(newrev: 'a', ref: 'refs/heads/a', commits: [create_commit('a', [])]),
+ have_attributes(oldrev: 'b', ref: 'refs/heads/b', commits: []),
+ have_attributes(oldrev: 'a', newrev: 'c', ref: 'refs/heads/c', commits: [create_commit('c', [])]),
+ have_attributes(newrev: 'd', ref: 'refs/heads/d', commits: [])
+ ]
+ end
+
+ it_behaves_like '#single_change_access'
+ end
+ end
+
def create_commit(id, parent_ids)
Gitlab::Git::Commit.new(project.repository, {
id: id,
diff --git a/spec/lib/gitlab/ci/config/entry/job_spec.rb b/spec/lib/gitlab/ci/config/entry/job_spec.rb
index 5b47d3a3922..0bb26babfc0 100644
--- a/spec/lib/gitlab/ci/config/entry/job_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/job_spec.rb
@@ -169,6 +169,22 @@ RSpec.describe Gitlab::Ci::Config::Entry::Job do
it { expect(entry).to be_valid }
end
end
+
+ context 'when rules are used' do
+ let(:config) { { script: 'ls', cache: { key: 'test' }, rules: rules } }
+
+ let(:rules) do
+ [
+ { if: '$CI_PIPELINE_SOURCE == "schedule"', when: 'never' },
+ [
+ { if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' },
+ { if: '$CI_PIPELINE_SOURCE == "merge_request_event"' }
+ ]
+ ]
+ end
+
+ it { expect(entry).to be_valid }
+ end
end
context 'when entry value is not correct' do
@@ -485,6 +501,70 @@ RSpec.describe Gitlab::Ci::Config::Entry::Job do
end
end
end
+
+ context 'when invalid rules are used' do
+ let(:config) { { script: 'ls', cache: { key: 'test' }, rules: rules } }
+
+ context 'with rules nested more than max allowed levels' do
+ let(:sample_rule) { { if: '$THIS == "other"', when: 'always' } }
+
+ let(:rules) do
+ [
+ { if: '$THIS == "that"', when: 'always' },
+ [
+ { if: '$SKIP', when: 'never' },
+ [
+ sample_rule,
+ [
+ sample_rule,
+ [
+ sample_rule,
+ [
+ sample_rule,
+ [
+ sample_rule,
+ [
+ sample_rule,
+ [
+ sample_rule,
+ [
+ sample_rule,
+ [
+ sample_rule,
+ [
+ sample_rule,
+ [sample_rule]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ end
+
+ it { expect(entry).not_to be_valid }
+ end
+
+ context 'with rules with invalid keys' do
+ let(:rules) do
+ [
+ { invalid_key: 'invalid' },
+ [
+ { if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' },
+ { if: '$CI_PIPELINE_SOURCE == "merge_request_event"' }
+ ]
+ ]
+ end
+
+ it { expect(entry).not_to be_valid }
+ end
+ end
end
end
@@ -618,6 +698,29 @@ RSpec.describe Gitlab::Ci::Config::Entry::Job do
end
end
end
+
+ context 'when job is using tags' do
+ context 'when limit is reached' do
+ let(:tags) { Array.new(100) { |i| "tag-#{i}" } }
+ let(:config) { { tags: tags, script: 'test' } }
+
+ it 'returns error', :aggregate_failures do
+ expect(entry).not_to be_valid
+ expect(entry.errors)
+ .to include "tags config must be less than the limit of #{Gitlab::Ci::Config::Entry::Tags::TAGS_LIMIT} tags"
+ end
+ end
+
+ context 'when limit is not reached' do
+ let(:config) { { tags: %w[tag1 tag2], script: 'test' } }
+
+ it 'returns a valid entry', :aggregate_failures do
+ expect(entry).to be_valid
+ expect(entry.errors).to be_empty
+ expect(entry.tags).to eq(%w[tag1 tag2])
+ end
+ end
+ end
end
describe '#manual_action?' do
diff --git a/spec/lib/gitlab/ci/config/entry/rules_spec.rb b/spec/lib/gitlab/ci/config/entry/rules_spec.rb
index 91252378541..cfec33003e4 100644
--- a/spec/lib/gitlab/ci/config/entry/rules_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/rules_spec.rb
@@ -53,7 +53,7 @@ RSpec.describe Gitlab::Ci::Config::Entry::Rules do
let(:config) do
[
{ if: '$THIS == "that"', when: 'always' },
- [{ if: '$SKIP', when: 'never' }]
+ [{ if: '$SKIP', when: 'never' }, { if: '$THIS == "other"', when: 'always' }]
]
end
@@ -64,11 +64,11 @@ RSpec.describe Gitlab::Ci::Config::Entry::Rules do
let(:config) do
[
{ if: '$THIS == "that"', when: 'always' },
- [{ if: '$SKIP', when: 'never' }, [{ if: '$THIS == "other"', when: 'aways' }]]
+ [{ if: '$SKIP', when: 'never' }, [{ if: '$THIS == "other"', when: 'always' }]]
]
end
- it { is_expected.not_to be_valid }
+ it { is_expected.to be_valid }
end
end
@@ -119,7 +119,7 @@ RSpec.describe Gitlab::Ci::Config::Entry::Rules do
context 'with rules nested more than one level' do
let(:first_rule) { { if: '$THIS == "that"', when: 'always' } }
let(:second_rule) { { if: '$SKIP', when: 'never' } }
- let(:third_rule) { { if: '$THIS == "other"', when: 'aways' } }
+ let(:third_rule) { { if: '$THIS == "other"', when: 'always' } }
let(:config) do
[
diff --git a/spec/lib/gitlab/ci/config/entry/tags_spec.rb b/spec/lib/gitlab/ci/config/entry/tags_spec.rb
new file mode 100644
index 00000000000..79317de373b
--- /dev/null
+++ b/spec/lib/gitlab/ci/config/entry/tags_spec.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Ci::Config::Entry::Tags do
+ let(:entry) { described_class.new(config) }
+
+ describe 'validation' do
+ context 'when tags config value is correct' do
+ let(:config) { %w[tag1 tag2] }
+
+ describe '#value' do
+ it 'returns tags configuration' do
+ expect(entry.value).to eq config
+ end
+ end
+
+ describe '#valid?' do
+ it 'is valid' do
+ expect(entry).to be_valid
+ end
+ end
+ end
+
+ context 'when entry value is not correct' do
+ describe '#errors' do
+ context 'when tags config is not an array of strings' do
+ let(:config) { [1, 2] }
+
+ it 'reports error' do
+ expect(entry.errors)
+ .to include 'tags config should be an array of strings'
+ end
+ end
+
+ context 'when tags limit is reached' do
+ let(:config) { Array.new(50) {|i| "tag-#{i}" } }
+
+ context 'when ci_build_tags_limit is enabled' do
+ before do
+ stub_feature_flags(ci_build_tags_limit: true)
+ end
+
+ it 'reports error' do
+ expect(entry.errors)
+ .to include "tags config must be less than the limit of #{described_class::TAGS_LIMIT} tags"
+ end
+ end
+
+ context 'when ci_build_tags_limit is disabled' do
+ before do
+ stub_feature_flags(ci_build_tags_limit: false)
+ end
+
+ it 'does not report an error' do
+ expect(entry.errors).to be_empty
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/cron_parser_spec.rb b/spec/lib/gitlab/ci/cron_parser_spec.rb
index 15293429354..4017accb462 100644
--- a/spec/lib/gitlab/ci/cron_parser_spec.rb
+++ b/spec/lib/gitlab/ci/cron_parser_spec.rb
@@ -297,4 +297,65 @@ RSpec.describe Gitlab::Ci::CronParser do
it { is_expected.to eq(true) }
end
end
+
+ describe '.parse_natural', :aggregate_failures do
+ let(:cron_line) { described_class.parse_natural_with_timestamp(time, { unit: 'day', duration: 1 }) }
+ let(:time) { Time.parse('Mon, 30 Aug 2021 06:29:44.067132000 UTC +00:00') }
+ let(:hours) { Fugit::Cron.parse(cron_line).hours }
+ let(:minutes) { Fugit::Cron.parse(cron_line).minutes }
+ let(:weekdays) { Fugit::Cron.parse(cron_line).weekdays.first }
+ let(:months) { Fugit::Cron.parse(cron_line).months }
+
+ context 'when repeat cycle is day' do
+ it 'generates daily cron expression', :aggregate_failures do
+ expect(hours).to include time.hour
+ expect(minutes).to include time.min
+ end
+ end
+
+ context 'when repeat cycle is week' do
+ let(:cron_line) { described_class.parse_natural_with_timestamp(time, { unit: 'week', duration: 1 }) }
+
+ it 'generates weekly cron expression', :aggregate_failures do
+ expect(hours).to include time.hour
+ expect(minutes).to include time.min
+ expect(weekdays).to include time.wday
+ end
+ end
+
+ context 'when repeat cycle is month' do
+ let(:cron_line) { described_class.parse_natural_with_timestamp(time, { unit: 'month', duration: 3 }) }
+
+ it 'generates monthly cron expression', :aggregate_failures do
+ expect(minutes).to include time.min
+ expect(months).to include time.month
+ end
+
+ context 'when an unsupported duration is specified' do
+ subject { described_class.parse_natural_with_timestamp(time, { unit: 'month', duration: 7 }) }
+
+ it 'raises an exception' do
+ expect { subject }.to raise_error(NotImplementedError, 'The cadence {:unit=>"month", :duration=>7} is not supported')
+ end
+ end
+ end
+
+ context 'when repeat cycle is year' do
+ let(:cron_line) { described_class.parse_natural_with_timestamp(time, { unit: 'year', duration: 1 }) }
+
+ it 'generates yearly cron expression', :aggregate_failures do
+ expect(hours).to include time.hour
+ expect(minutes).to include time.min
+ expect(months).to include time.month
+ end
+ end
+
+ context 'when the repeat cycle is not implemented' do
+ subject { described_class.parse_natural_with_timestamp(time, { unit: 'quarterly', duration: 1 }) }
+
+ it 'raises an exception' do
+ expect { subject }.to raise_error(NotImplementedError, 'The cadence unit quarterly is not implemented')
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/ci/parsers/security/common_spec.rb b/spec/lib/gitlab/ci/parsers/security/common_spec.rb
index c6387bf615b..c49673f5a4a 100644
--- a/spec/lib/gitlab/ci/parsers/security/common_spec.rb
+++ b/spec/lib/gitlab/ci/parsers/security/common_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-# TODO remove duplication from spec/lib/gitlab/ci/parsers/security/common_spec.rb and spec/lib/gitlab/ci/parsers/security/common_spec.rb
-# See https://gitlab.com/gitlab-org/gitlab/-/issues/336589
require 'spec_helper'
RSpec.describe Gitlab::Ci::Parsers::Security::Common do
@@ -15,11 +13,18 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do
# The path 'yarn.lock' was initially used by DependencyScanning, it is okay for SAST locations to use it, but this could be made better
let(:location) { ::Gitlab::Ci::Reports::Security::Locations::Sast.new(file_path: 'yarn.lock', start_line: 1, end_line: 1) }
let(:tracking_data) { nil }
+ let(:vulnerability_flags_data) do
+ [
+ ::Gitlab::Ci::Reports::Security::Flag.new(type: 'flagged-as-likely-false-positive', origin: 'post analyzer X', description: 'static string to sink'),
+ ::Gitlab::Ci::Reports::Security::Flag.new(type: 'flagged-as-likely-false-positive', origin: 'post analyzer Y', description: 'integer to sink')
+ ]
+ end
before do
allow_next_instance_of(described_class) do |parser|
allow(parser).to receive(:create_location).and_return(location)
allow(parser).to receive(:tracking_data).and_return(tracking_data)
+ allow(parser).to receive(:create_flags).and_return(vulnerability_flags_data)
end
artifact.each_blob { |blob| described_class.parse!(blob, report, vulnerability_finding_signatures_enabled) }
@@ -233,6 +238,17 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do
end
end
+ describe 'parsing flags' do
+ it 'returns flags object for each finding' do
+ flags = report.findings.first.flags
+
+ expect(flags).to contain_exactly(
+ have_attributes(type: 'flagged-as-likely-false-positive', origin: 'post analyzer X', description: 'static string to sink'),
+ have_attributes(type: 'flagged-as-likely-false-positive', origin: 'post analyzer Y', description: 'integer to sink')
+ )
+ end
+ end
+
describe 'parsing links' do
it 'returns links object for each finding', :aggregate_failures do
links = report.findings.flat_map(&:links)
diff --git a/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb b/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb
index f434ffd12bf..951e0576a58 100644
--- a/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb
+++ b/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb
@@ -6,7 +6,8 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
using RSpec::Parameterized::TableSyntax
where(:report_type, :expected_errors, :valid_data) do
- :sast | ['root is missing required keys: vulnerabilities'] | { 'version' => '10.0.0', 'vulnerabilities' => [] }
+ 'sast' | ['root is missing required keys: vulnerabilities'] | { 'version' => '10.0.0', 'vulnerabilities' => [] }
+ :sast | ['root is missing required keys: vulnerabilities'] | { 'version' => '10.0.0', 'vulnerabilities' => [] }
:secret_detection | ['root is missing required keys: vulnerabilities'] | { 'version' => '10.0.0', 'vulnerabilities' => [] }
end
diff --git a/spec/lib/gitlab/ci/pipeline/chain/build/associations_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/build/associations_spec.rb
index 5fa414f5bd1..32c92724f62 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/build/associations_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/build/associations_spec.rb
@@ -3,10 +3,16 @@
require 'spec_helper'
RSpec.describe Gitlab::Ci::Pipeline::Chain::Build::Associations do
- let(:project) { create(:project, :repository) }
- let(:user) { create(:user, developer_projects: [project]) }
+ let_it_be_with_reload(:project) { create(:project, :repository) }
+ let_it_be(:user) { create(:user, developer_projects: [project]) }
+
let(:pipeline) { Ci::Pipeline.new }
- let(:step) { described_class.new(pipeline, command) }
+ let(:bridge) { nil }
+
+ let(:variables_attributes) do
+ [{ key: 'first', secret_value: 'world' },
+ { key: 'second', secret_value: 'second_world' }]
+ end
let(:command) do
Gitlab::Ci::Pipeline::Chain::Command.new(
@@ -20,7 +26,26 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Build::Associations do
merge_request: nil,
project: project,
current_user: user,
- bridge: bridge)
+ bridge: bridge,
+ variables_attributes: variables_attributes)
+ end
+
+ let(:step) { described_class.new(pipeline, command) }
+
+ shared_examples 'breaks the chain' do
+ it 'returns true' do
+ step.perform!
+
+ expect(step.break?).to be true
+ end
+ end
+
+ shared_examples 'does not break the chain' do
+ it 'returns false' do
+ step.perform!
+
+ expect(step.break?).to be false
+ end
end
context 'when a bridge is passed in to the pipeline creation' do
@@ -37,26 +62,83 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Build::Associations do
)
end
- it 'never breaks the chain' do
- step.perform!
-
- expect(step.break?).to eq(false)
- end
+ it_behaves_like 'does not break the chain'
end
context 'when a bridge is not passed in to the pipeline creation' do
- let(:bridge) { nil }
-
it 'leaves the source pipeline empty' do
step.perform!
expect(pipeline.source_pipeline).to be_nil
end
- it 'never breaks the chain' do
+ it_behaves_like 'does not break the chain'
+ end
+
+ it 'sets pipeline variables' do
+ step.perform!
+
+ expect(pipeline.variables.map { |var| var.slice(:key, :secret_value) })
+ .to eq variables_attributes.map(&:with_indifferent_access)
+ end
+
+ context 'when project setting restrict_user_defined_variables is enabled' do
+ before do
+ project.update!(restrict_user_defined_variables: true)
+ end
+
+ context 'when user is developer' do
+ it_behaves_like 'breaks the chain'
+
+ it 'returns an error on variables_attributes', :aggregate_failures do
+ step.perform!
+
+ expect(pipeline.errors.full_messages).to eq(['Insufficient permissions to set pipeline variables'])
+ expect(pipeline.variables).to be_empty
+ end
+
+ context 'when variables_attributes is not specified' do
+ let(:variables_attributes) { nil }
+
+ it_behaves_like 'does not break the chain'
+
+ it 'assigns empty variables' do
+ step.perform!
+
+ expect(pipeline.variables).to be_empty
+ end
+ end
+ end
+
+ context 'when user is maintainer' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ it_behaves_like 'does not break the chain'
+
+ it 'assigns variables_attributes' do
+ step.perform!
+
+ expect(pipeline.variables.map { |var| var.slice(:key, :secret_value) })
+ .to eq variables_attributes.map(&:with_indifferent_access)
+ end
+ end
+ end
+
+ context 'with duplicate pipeline variables' do
+ let(:variables_attributes) do
+ [{ key: 'first', secret_value: 'world' },
+ { key: 'first', secret_value: 'second_world' }]
+ end
+
+ it_behaves_like 'breaks the chain'
+
+ it 'returns an error for variables_attributes' do
step.perform!
- expect(step.break?).to eq(false)
+ expect(pipeline.errors.full_messages).to eq(['Duplicate variable name: first'])
+ expect(pipeline.variables).to be_empty
end
end
end
diff --git a/spec/lib/gitlab/ci/pipeline/chain/build_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/build_spec.rb
index 7771289abe6..dca2204f544 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/build_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/build_spec.rb
@@ -8,11 +8,6 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Build do
let(:pipeline) { Ci::Pipeline.new }
- let(:variables_attributes) do
- [{ key: 'first', secret_value: 'world' },
- { key: 'second', secret_value: 'second_world' }]
- end
-
let(:command) do
Gitlab::Ci::Pipeline::Chain::Command.new(
source: :push,
@@ -24,100 +19,26 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Build do
schedule: nil,
merge_request: nil,
project: project,
- current_user: user,
- variables_attributes: variables_attributes)
+ current_user: user)
end
let(:step) { described_class.new(pipeline, command) }
- shared_examples 'builds pipeline' do
- it 'builds a pipeline with the expected attributes' do
- step.perform!
-
- expect(pipeline.sha).not_to be_empty
- expect(pipeline.sha).to eq project.commit.id
- expect(pipeline.ref).to eq 'master'
- expect(pipeline.tag).to be false
- expect(pipeline.user).to eq user
- expect(pipeline.project).to eq project
- end
- end
-
- shared_examples 'breaks the chain' do
- it 'returns true' do
- step.perform!
-
- expect(step.break?).to be true
- end
- end
-
- shared_examples 'does not break the chain' do
- it 'returns false' do
- step.perform!
-
- expect(step.break?).to be false
- end
- end
-
- before do
- stub_ci_pipeline_yaml_file(gitlab_ci_yaml)
- end
-
- it_behaves_like 'does not break the chain'
- it_behaves_like 'builds pipeline'
-
- it 'sets pipeline variables' do
+ it 'does not break the chain' do
step.perform!
- expect(pipeline.variables.map { |var| var.slice(:key, :secret_value) })
- .to eq variables_attributes.map(&:with_indifferent_access)
+ expect(step.break?).to be false
end
- context 'when project setting restrict_user_defined_variables is enabled' do
- before do
- project.update!(restrict_user_defined_variables: true)
- end
-
- context 'when user is developer' do
- it_behaves_like 'breaks the chain'
- it_behaves_like 'builds pipeline'
-
- it 'returns an error on variables_attributes', :aggregate_failures do
- step.perform!
-
- expect(pipeline.errors.full_messages).to eq(['Insufficient permissions to set pipeline variables'])
- expect(pipeline.variables).to be_empty
- end
-
- context 'when variables_attributes is not specified' do
- let(:variables_attributes) { nil }
-
- it_behaves_like 'does not break the chain'
- it_behaves_like 'builds pipeline'
-
- it 'assigns empty variables' do
- step.perform!
-
- expect(pipeline.variables).to be_empty
- end
- end
- end
-
- context 'when user is maintainer' do
- before do
- project.add_maintainer(user)
- end
-
- it_behaves_like 'does not break the chain'
- it_behaves_like 'builds pipeline'
-
- it 'assigns variables_attributes' do
- step.perform!
+ it 'builds a pipeline with the expected attributes' do
+ step.perform!
- expect(pipeline.variables.map { |var| var.slice(:key, :secret_value) })
- .to eq variables_attributes.map(&:with_indifferent_access)
- end
- end
+ expect(pipeline.sha).not_to be_empty
+ expect(pipeline.sha).to eq project.commit.id
+ expect(pipeline.ref).to eq 'master'
+ expect(pipeline.tag).to be false
+ expect(pipeline.user).to eq user
+ expect(pipeline.project).to eq project
end
it 'returns a valid pipeline' do
diff --git a/spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb
index 2727f2603cd..27a5abf988c 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb
@@ -44,6 +44,14 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::CancelPendingPipelines do
expect(build_statuses(pipeline)).to contain_exactly('pending')
end
+ it 'cancels the builds with 2 queries to avoid query timeout' do
+ second_query_regex = /WHERE "ci_pipelines"\."id" = \d+ AND \(NOT EXISTS/
+ recorder = ActiveRecord::QueryRecorder.new { perform }
+ second_query = recorder.occurrences.keys.filter { |occ| occ =~ second_query_regex }
+
+ expect(second_query).to be_one
+ end
+
context 'when the previous pipeline has a child pipeline' do
let(:child_pipeline) { create(:ci_pipeline, child_of: prev_pipeline) }
diff --git a/spec/lib/gitlab/ci/pipeline/chain/command_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/command_spec.rb
index c22a0e23794..0d78ce3440a 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/command_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/command_spec.rb
@@ -341,4 +341,40 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Command do
end
end
end
+
+ describe '#observe_step_duration' do
+ context 'when ci_pipeline_creation_step_duration_tracking is enabled' do
+ it 'adds the duration to the step duration histogram' do
+ histogram = double(:histogram)
+ duration = 1.hour
+
+ expect(::Gitlab::Ci::Pipeline::Metrics).to receive(:pipeline_creation_step_duration_histogram)
+ .and_return(histogram)
+ expect(histogram).to receive(:observe)
+ .with({ step: 'Gitlab::Ci::Pipeline::Chain::Build' }, duration.seconds)
+
+ described_class.new.observe_step_duration(
+ Gitlab::Ci::Pipeline::Chain::Build,
+ duration
+ )
+ end
+ end
+
+ context 'when ci_pipeline_creation_step_duration_tracking is disabled' do
+ before do
+ stub_feature_flags(ci_pipeline_creation_step_duration_tracking: false)
+ end
+
+ it 'does nothing' do
+ duration = 1.hour
+
+ expect(::Gitlab::Ci::Pipeline::Metrics).not_to receive(:pipeline_creation_step_duration_histogram)
+
+ described_class.new.observe_step_duration(
+ Gitlab::Ci::Pipeline::Chain::Build,
+ duration
+ )
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb
index 42ec9ab6f5d..e0d656f456e 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb
@@ -92,6 +92,27 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Config::Content do
expect(pipeline.pipeline_config.content).to eq(config_content_result)
expect(command.config_content).to eq(config_content_result)
end
+
+ context 'when path specifies a refname' do
+ let(:ci_config_path) { 'path/to/.gitlab-ci.yml@another-group/another-repo:refname' }
+ let(:config_content_result) do
+ <<~EOY
+ ---
+ include:
+ - project: another-group/another-repo
+ file: path/to/.gitlab-ci.yml
+ ref: refname
+ EOY
+ end
+
+ it 'builds root config including the path and refname to another repository' do
+ subject.perform!
+
+ expect(pipeline.config_source).to eq 'external_project_source'
+ expect(pipeline.pipeline_config.content).to eq(config_content_result)
+ expect(command.config_content).to eq(config_content_result)
+ end
+ end
end
context 'when config is defined in the default .gitlab-ci.yml' do
diff --git a/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb
index 83d47ae6819..e8eb3333b88 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb
@@ -8,8 +8,8 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Sequence do
let(:pipeline) { build_stubbed(:ci_pipeline) }
let(:command) { Gitlab::Ci::Pipeline::Chain::Command.new(project: project) }
- let(:first_step) { spy('first step') }
- let(:second_step) { spy('second step') }
+ let(:first_step) { spy('first step', name: 'FirstStep') }
+ let(:second_step) { spy('second step', name: 'SecondStep') }
let(:sequence) { [first_step, second_step] }
let(:histogram) { spy('prometheus metric') }
@@ -61,6 +61,17 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Sequence do
expect(histogram).to have_received(:observe)
end
+ it 'adds step sequence duration to duration histogram' do
+ expect(command.metrics)
+ .to receive(:pipeline_creation_step_duration_histogram)
+ .twice
+ .and_return(histogram)
+ expect(histogram).to receive(:observe).with({ step: 'FirstStep' }, any_args).ordered
+ expect(histogram).to receive(:observe).with({ step: 'SecondStep' }, any_args).ordered
+
+ subject.build!
+ end
+
it 'records pipeline size by pipeline source in a histogram' do
allow(command.metrics)
.to receive(:pipeline_size_histogram)
diff --git a/spec/lib/gitlab/ci/pipeline/metrics_spec.rb b/spec/lib/gitlab/ci/pipeline/metrics_spec.rb
new file mode 100644
index 00000000000..83b969ff3c4
--- /dev/null
+++ b/spec/lib/gitlab/ci/pipeline/metrics_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Gitlab::Ci::Pipeline::Metrics do
+ describe '.pipeline_creation_step_duration_histogram' do
+ around do |example|
+ described_class.clear_memoization(:pipeline_creation_step_histogram)
+
+ example.run
+
+ described_class.clear_memoization(:pipeline_creation_step_histogram)
+ end
+
+ it 'adds the step to the step duration histogram' do
+ expect(::Gitlab::Metrics).to receive(:histogram)
+ .with(
+ :gitlab_ci_pipeline_creation_step_duration_seconds,
+ 'Duration of each pipeline creation step',
+ { step: nil },
+ [0.01, 0.05, 0.1, 0.5, 1.0, 2.0, 5.0, 10.0, 15.0, 20.0, 50.0, 240.0]
+ )
+
+ described_class.pipeline_creation_step_duration_histogram
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb b/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
index 58938251ca1..0c28515b574 100644
--- a/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
@@ -490,12 +490,21 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Build do
end
context 'when job belongs to a resource group' do
- let(:attributes) { { name: 'rspec', ref: 'master', resource_group_key: 'iOS' } }
+ let(:resource_group) { 'iOS' }
+ let(:attributes) { { name: 'rspec', ref: 'master', resource_group_key: resource_group, environment: 'production' }}
it 'returns a job with resource group' do
expect(subject.resource_group).not_to be_nil
expect(subject.resource_group.key).to eq('iOS')
end
+
+ context 'when resource group has $CI_ENVIRONMENT_NAME in it' do
+ let(:resource_group) { 'test/$CI_ENVIRONMENT_NAME' }
+
+ it 'expands environment name' do
+ expect(subject.resource_group.key).to eq('test/production')
+ end
+ end
end
end
@@ -1140,16 +1149,6 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Build do
it 'does not have errors' do
expect(subject.errors).to be_empty
end
-
- context 'when ci_same_stage_job_needs FF is disabled' do
- before do
- stub_feature_flags(ci_same_stage_job_needs: false)
- end
-
- it 'has errors' do
- expect(subject.errors).to contain_exactly("'rspec' job needs 'build' job, but 'build' is not in any previous stage")
- end
- end
end
context 'when using 101 needs' do
diff --git a/spec/lib/gitlab/ci/pipeline/seed/pipeline_spec.rb b/spec/lib/gitlab/ci/pipeline/seed/pipeline_spec.rb
index 3424e7d03a3..5d8a9358e10 100644
--- a/spec/lib/gitlab/ci/pipeline/seed/pipeline_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/seed/pipeline_spec.rb
@@ -34,10 +34,6 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Pipeline do
described_class.new(seed_context, stages_attributes)
end
- before do
- stub_feature_flags(ci_same_stage_job_needs: false)
- end
-
describe '#stages' do
it 'returns the stage resources' do
stages = seed.stages
diff --git a/spec/lib/gitlab/ci/reports/security/flag_spec.rb b/spec/lib/gitlab/ci/reports/security/flag_spec.rb
new file mode 100644
index 00000000000..27f83694ac2
--- /dev/null
+++ b/spec/lib/gitlab/ci/reports/security/flag_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Ci::Reports::Security::Flag do
+ subject(:security_flag) { described_class.new(type: 'flagged-as-likely-false-positive', origin: 'post analyzer X', description: 'static string to sink') }
+
+ describe '#initialize' do
+ context 'when all params are given' do
+ it 'initializes an instance' do
+ expect { subject }.not_to raise_error
+
+ expect(subject).to have_attributes(
+ type: 'flagged-as-likely-false-positive',
+ origin: 'post analyzer X',
+ description: 'static string to sink'
+ )
+ end
+ end
+
+ describe '#to_hash' do
+ it 'returns expected hash' do
+ expect(security_flag.to_hash).to eq(
+ {
+ flag_type: :false_positive,
+ origin: 'post analyzer X',
+ description: 'static string to sink'
+ }
+ )
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/trace/backoff_spec.rb b/spec/lib/gitlab/ci/trace/backoff_spec.rb
new file mode 100644
index 00000000000..0fb7e81c6c5
--- /dev/null
+++ b/spec/lib/gitlab/ci/trace/backoff_spec.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Ci::Trace::Backoff do
+ using RSpec::Parameterized::TableSyntax
+
+ subject(:backoff) { described_class.new(archival_attempts) }
+
+ it 'keeps the MAX_ATTEMPTS limit in sync' do
+ expect(Ci::BuildTraceMetadata::MAX_ATTEMPTS).to eq(5)
+ end
+
+ it 'keeps the Redis TTL limit in sync' do
+ expect(Ci::BuildTraceChunks::RedisBase::CHUNK_REDIS_TTL).to eq(7.days)
+ end
+
+ describe '#value' do
+ where(:archival_attempts, :result) do
+ 1 | 9.6
+ 2 | 19.2
+ 3 | 28.8
+ 4 | 38.4
+ 5 | 48.0
+ end
+
+ with_them do
+ subject { backoff.value }
+
+ it { is_expected.to eq(result.hours) }
+ end
+ end
+
+ describe '#value_with_jitter' do
+ where(:archival_attempts, :min_value, :max_value) do
+ 1 | 9.6 | 13.6
+ 2 | 19.2 | 23.2
+ 3 | 28.8 | 32.8
+ 4 | 38.4 | 42.4
+ 5 | 48.0 | 52.0
+ end
+
+ with_them do
+ subject { backoff.value_with_jitter }
+
+ it { is_expected.to be_in(min_value.hours..max_value.hours) }
+ end
+ end
+
+ it 'all retries are happening under the 7 days limit' do
+ backoff_total = 1.upto(Ci::BuildTraceMetadata::MAX_ATTEMPTS).sum do |attempt|
+ backoff = described_class.new(attempt)
+ expect(backoff).to receive(:rand)
+ .with(described_class::MAX_JITTER_VALUE)
+ .and_return(described_class::MAX_JITTER_VALUE)
+
+ backoff.value_with_jitter
+ end
+
+ expect(backoff_total).to be < Ci::BuildTraceChunks::RedisBase::CHUNK_REDIS_TTL
+ end
+end
diff --git a/spec/lib/gitlab/ci/trace_spec.rb b/spec/lib/gitlab/ci/trace_spec.rb
index 69f56871740..1a31b2dad56 100644
--- a/spec/lib/gitlab/ci/trace_spec.rb
+++ b/spec/lib/gitlab/ci/trace_spec.rb
@@ -130,4 +130,18 @@ RSpec.describe Gitlab::Ci::Trace, :clean_gitlab_redis_shared_state, factory_defa
end
end
end
+
+ describe '#can_attempt_archival_now?' do
+ it 'creates the record and returns true' do
+ expect(trace.can_attempt_archival_now?).to be_truthy
+ end
+ end
+
+ describe '#increment_archival_attempts!' do
+ it 'creates the record and increments its value' do
+ expect { trace.increment_archival_attempts! }
+ .to change { build.reload.trace_metadata&.archival_attempts }.from(nil).to(1)
+ .and change { build.reload.trace_metadata&.last_archival_attempt_at }
+ end
+ end
end
diff --git a/spec/lib/gitlab/ci/variables/collection/sort_spec.rb b/spec/lib/gitlab/ci/variables/collection/sort_spec.rb
index 01eef673c35..7e4e9602a92 100644
--- a/spec/lib/gitlab/ci/variables/collection/sort_spec.rb
+++ b/spec/lib/gitlab/ci/variables/collection/sort_spec.rb
@@ -5,20 +5,10 @@ require 'rspec-parameterized'
RSpec.describe Gitlab::Ci::Variables::Collection::Sort do
describe '#initialize with non-Collection value' do
- context 'when FF :variable_inside_variable is disabled' do
- subject { Gitlab::Ci::Variables::Collection::Sort.new([]) }
+ subject { Gitlab::Ci::Variables::Collection::Sort.new([]) }
- it 'raises ArgumentError' do
- expect { subject }.to raise_error(ArgumentError, /Collection object was expected/)
- end
- end
-
- context 'when FF :variable_inside_variable is enabled' do
- subject { Gitlab::Ci::Variables::Collection::Sort.new([]) }
-
- it 'raises ArgumentError' do
- expect { subject }.to raise_error(ArgumentError, /Collection object was expected/)
- end
+ it 'raises ArgumentError' do
+ expect { subject }.to raise_error(ArgumentError, /Collection object was expected/)
end
end
@@ -182,5 +172,33 @@ RSpec.describe Gitlab::Ci::Variables::Collection::Sort do
expect { subject }.to raise_error(TSort::Cyclic)
end
end
+
+ context 'with overridden variables' do
+ let(:variables) do
+ [
+ { key: 'PROJECT_VAR', value: '$SUBGROUP_VAR' },
+ { key: 'SUBGROUP_VAR', value: '$TOP_LEVEL_GROUP_NAME' },
+ { key: 'SUBGROUP_VAR', value: '$SUB_GROUP_NAME' },
+ { key: 'TOP_LEVEL_GROUP_NAME', value: 'top-level-group' },
+ { key: 'SUB_GROUP_NAME', value: 'vars-in-vars-subgroup' }
+ ]
+ end
+
+ let(:collection) { Gitlab::Ci::Variables::Collection.new(variables) }
+
+ subject do
+ Gitlab::Ci::Variables::Collection::Sort.new(collection).tsort.map { |v| { v[:key] => v.value } }
+ end
+
+ it 'preserves relative order of overridden variables' do
+ is_expected.to eq([
+ { 'TOP_LEVEL_GROUP_NAME' => 'top-level-group' },
+ { 'SUBGROUP_VAR' => '$TOP_LEVEL_GROUP_NAME' },
+ { 'SUB_GROUP_NAME' => 'vars-in-vars-subgroup' },
+ { 'SUBGROUP_VAR' => '$SUB_GROUP_NAME' },
+ { 'PROJECT_VAR' => '$SUBGROUP_VAR' }
+ ])
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/ci/variables/collection_spec.rb b/spec/lib/gitlab/ci/variables/collection_spec.rb
index abda27f0d6e..7ba98380986 100644
--- a/spec/lib/gitlab/ci/variables/collection_spec.rb
+++ b/spec/lib/gitlab/ci/variables/collection_spec.rb
@@ -123,17 +123,102 @@ RSpec.describe Gitlab::Ci::Variables::Collection do
end
describe '#[]' do
- variable = { key: 'VAR', value: 'value', public: true, masked: false }
+ subject { Gitlab::Ci::Variables::Collection.new(variables)[var_name] }
- collection = described_class.new([variable])
+ shared_examples 'an array access operator' do
+ context 'for a non-existent variable name' do
+ let(:var_name) { 'UNKNOWN_VAR' }
- it 'returns nil for a non-existent variable name' do
- expect(collection['UNKNOWN_VAR']).to be_nil
+ it 'returns nil' do
+ is_expected.to be_nil
+ end
+ end
+
+ context 'for an existent variable name' do
+ let(:var_name) { 'VAR' }
+
+ it 'returns the last Item' do
+ is_expected.to be_an_instance_of(Gitlab::Ci::Variables::Collection::Item)
+ expect(subject.to_runner_variable).to eq(variables.last)
+ end
+ end
+ end
+
+ context 'with variable key with single entry' do
+ let(:variables) do
+ [
+ { key: 'VAR', value: 'value', public: true, masked: false }
+ ]
+ end
+
+ it_behaves_like 'an array access operator'
+ end
+
+ context 'with variable key with multiple entries' do
+ let(:variables) do
+ [
+ { key: 'VAR', value: 'value', public: true, masked: false },
+ { key: 'VAR', value: 'override value', public: true, masked: false }
+ ]
+ end
+
+ it_behaves_like 'an array access operator'
end
+ end
+
+ describe '#all' do
+ subject { described_class.new(variables).all(var_name) }
- it 'returns Item for an existent variable name' do
- expect(collection['VAR']).to be_an_instance_of(Gitlab::Ci::Variables::Collection::Item)
- expect(collection['VAR'].to_runner_variable).to eq(variable)
+ shared_examples 'a method returning all known variables or nil' do
+ context 'for a non-existent variable name' do
+ let(:var_name) { 'UNKNOWN_VAR' }
+
+ it 'returns nil' do
+ is_expected.to be_nil
+ end
+ end
+
+ context 'for an existing variable name' do
+ let(:var_name) { 'VAR' }
+
+ it 'returns all expected Items' do
+ is_expected.to eq(expected_variables.map { |v| Gitlab::Ci::Variables::Collection::Item.fabricate(v) })
+ end
+ end
+ end
+
+ context 'with variable key with single entry' do
+ let(:variables) do
+ [
+ { key: 'VAR', value: 'value', public: true, masked: false }
+ ]
+ end
+
+ it_behaves_like 'a method returning all known variables or nil' do
+ let(:expected_variables) do
+ [
+ { key: 'VAR', value: 'value', public: true, masked: false }
+ ]
+ end
+ end
+ end
+
+ context 'with variable key with multiple entries' do
+ let(:variables) do
+ [
+ { key: 'VAR', value: 'value', public: true, masked: false },
+ { key: 'VAR', value: 'override value', public: true, masked: false }
+ ]
+ end
+
+ it_behaves_like 'a method returning all known variables or nil' do
+ let(:expected_variables) do
+ [
+ { key: 'VAR', value: 'value', public: true, masked: false },
+ { key: 'VAR', value: 'override value', public: true, masked: false }
+ ]
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/ci/yaml_processor_spec.rb b/spec/lib/gitlab/ci/yaml_processor_spec.rb
index 49a470f9e01..1591c2e6b60 100644
--- a/spec/lib/gitlab/ci/yaml_processor_spec.rb
+++ b/spec/lib/gitlab/ci/yaml_processor_spec.rb
@@ -590,14 +590,6 @@ module Gitlab
end
it_behaves_like 'has warnings and expected error', /build job: need test is not defined in current or prior stages/
-
- context 'with ci_same_stage_job_needs FF disabled' do
- before do
- stub_feature_flags(ci_same_stage_job_needs: false)
- end
-
- it_behaves_like 'has warnings and expected error', /build job: need test is not defined in prior stages/
- end
end
end
end
@@ -1809,14 +1801,6 @@ module Gitlab
let(:dependencies) { ['deploy'] }
it_behaves_like 'returns errors', 'test1 job: dependency deploy is not defined in current or prior stages'
-
- context 'with ci_same_stage_job_needs FF disabled' do
- before do
- stub_feature_flags(ci_same_stage_job_needs: false)
- end
-
- it_behaves_like 'returns errors', 'test1 job: dependency deploy is not defined in prior stages'
- end
end
context 'when a job depends on another job that references a not-yet defined stage' do
@@ -2053,14 +2037,6 @@ module Gitlab
let(:needs) { ['deploy'] }
it_behaves_like 'returns errors', 'test1 job: need deploy is not defined in current or prior stages'
-
- context 'with ci_same_stage_job_needs FF disabled' do
- before do
- stub_feature_flags(ci_same_stage_job_needs: false)
- end
-
- it_behaves_like 'returns errors', 'test1 job: need deploy is not defined in prior stages'
- end
end
context 'needs and dependencies that are mismatching' do
diff --git a/spec/lib/gitlab/config/loader/yaml_spec.rb b/spec/lib/gitlab/config/loader/yaml_spec.rb
index 731ee12d7f4..be568a8e5f9 100644
--- a/spec/lib/gitlab/config/loader/yaml_spec.rb
+++ b/spec/lib/gitlab/config/loader/yaml_spec.rb
@@ -15,6 +15,24 @@ RSpec.describe Gitlab::Config::Loader::Yaml do
YAML
end
+ context 'when max yaml size and depth are set in ApplicationSetting' do
+ let(:yaml_size) { 2.megabytes }
+ let(:yaml_depth) { 200 }
+
+ before do
+ stub_application_setting(max_yaml_size_bytes: yaml_size, max_yaml_depth: yaml_depth)
+ end
+
+ it 'uses ApplicationSetting values rather than the defaults' do
+ expect(Gitlab::Utils::DeepSize)
+ .to receive(:new)
+ .with(any_args, { max_size: yaml_size, max_depth: yaml_depth })
+ .and_call_original
+
+ loader.load!
+ end
+ end
+
context 'when yaml syntax is correct' do
let(:yml) { 'image: ruby:2.7' }
diff --git a/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb b/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
index b9e0132badb..8053f5261c0 100644
--- a/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
@@ -3,7 +3,8 @@
require 'spec_helper'
RSpec.describe Gitlab::CycleAnalytics::StageSummary do
- let(:project) { create(:project, :repository) }
+ let_it_be(:project) { create(:project, :repository) }
+
let(:options) { { from: 1.day.ago } }
let(:args) { { options: options, current_user: user } }
let(:user) { create(:user, :admin) }
@@ -62,6 +63,8 @@ RSpec.describe Gitlab::CycleAnalytics::StageSummary do
end
describe "#commits" do
+ let!(:project) { create(:project, :repository) }
+
subject { stage_summary.second }
context 'when from date is given' do
@@ -132,115 +135,5 @@ RSpec.describe Gitlab::CycleAnalytics::StageSummary do
end
end
- describe "#deploys" do
- subject { stage_summary.third }
-
- context 'when from date is given' do
- before do
- Timecop.freeze(5.days.ago) { create(:deployment, :success, project: project) }
- Timecop.freeze(5.days.from_now) { create(:deployment, :success, project: project) }
- end
-
- it "finds the number of deploys made created after the 'from date'" do
- expect(subject[:value]).to eq('1')
- end
-
- it 'returns the localized title' do
- Gitlab::I18n.with_locale(:ru) do
- expect(subject[:title]).to eq(n_('Deploy', 'Deploys', 1))
- end
- end
- end
-
- it "doesn't find commits from other projects" do
- Timecop.freeze(5.days.from_now) do
- create(:deployment, :success, project: create(:project, :repository))
- end
-
- expect(subject[:value]).to eq('-')
- end
-
- context 'when `to` parameter is given' do
- before do
- Timecop.freeze(5.days.ago) { create(:deployment, :success, project: project) }
- Timecop.freeze(5.days.from_now) { create(:deployment, :success, project: project) }
- end
-
- it "doesn't find any record" do
- options[:to] = Time.now
-
- expect(subject[:value]).to eq('-')
- end
-
- it "finds records created between `from` and `to` range" do
- options[:from] = 10.days.ago
- options[:to] = 10.days.from_now
-
- expect(subject[:value]).to eq('2')
- end
- end
- end
-
- describe '#deployment_frequency' do
- subject { stage_summary.fourth[:value] }
-
- it 'includes the unit: `per day`' do
- expect(stage_summary.fourth[:unit]).to eq _('per day')
- end
-
- before do
- Timecop.freeze(5.days.ago) { create(:deployment, :success, project: project) }
- end
-
- it 'returns 0.0 when there were deploys but the frequency was too low' do
- options[:from] = 30.days.ago
-
- # 1 deployment over 30 days
- # frequency of 0.03, rounded off to 0.0
- expect(subject).to eq('0')
- end
-
- it 'returns `-` when there were no deploys' do
- options[:from] = 4.days.ago
-
- # 0 deployment in the last 4 days
- expect(subject).to eq('-')
- end
-
- context 'when `to` is nil' do
- it 'includes range until now' do
- options[:from] = 6.days.ago
- options[:to] = nil
-
- # 1 deployment over 7 days
- expect(subject).to eq('0.1')
- end
- end
-
- context 'when `to` is given' do
- before do
- Timecop.freeze(5.days.from_now) { create(:deployment, :success, project: project, finished_at: Time.zone.now) }
- end
-
- it 'finds records created between `from` and `to` range' do
- options[:from] = 10.days.ago
- options[:to] = 10.days.from_now
-
- # 2 deployments over 20 days
- expect(subject).to eq('0.1')
- end
-
- context 'when `from` and `to` are within a day' do
- it 'returns the number of deployments made on that day' do
- freeze_time do
- create(:deployment, :success, project: project, finished_at: Time.zone.now)
- options[:from] = Time.zone.now.at_beginning_of_day
- options[:to] = Time.zone.now.at_end_of_day
-
- expect(subject).to eq('1')
- end
- end
- end
- end
- end
+ it_behaves_like 'deployment metrics examples'
end
diff --git a/spec/lib/gitlab/database/async_indexes/migration_helpers_spec.rb b/spec/lib/gitlab/database/async_indexes/migration_helpers_spec.rb
index ed15951dfb0..eb16a8ccfa5 100644
--- a/spec/lib/gitlab/database/async_indexes/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/async_indexes/migration_helpers_spec.rb
@@ -150,6 +150,23 @@ RSpec.describe Gitlab::Database::AsyncIndexes::MigrationHelpers do
migration.prepare_async_index(table_name, 'id')
end.not_to change { index_model.where(name: index_name).count }
end
+
+ it 'updates definition if changed' do
+ index = create(:postgres_async_index, table_name: table_name, name: index_name, definition: '...')
+
+ expect do
+ migration.prepare_async_index(table_name, 'id', name: index_name)
+ end.to change { index.reload.definition }
+ end
+
+ it 'does not update definition if not changed' do
+ definition = "CREATE INDEX CONCURRENTLY \"index_#{table_name}_on_id\" ON \"#{table_name}\" (\"id\")"
+ index = create(:postgres_async_index, table_name: table_name, name: index_name, definition: definition)
+
+ expect do
+ migration.prepare_async_index(table_name, 'id', name: index_name)
+ end.not_to change { index.reload.updated_at }
+ end
end
context 'when the async index table does not exist' do
diff --git a/spec/lib/gitlab/database/background_migration/batched_migration_spec.rb b/spec/lib/gitlab/database/background_migration/batched_migration_spec.rb
index 3207e97a639..a1c2634f59c 100644
--- a/spec/lib/gitlab/database/background_migration/batched_migration_spec.rb
+++ b/spec/lib/gitlab/database/background_migration/batched_migration_spec.rb
@@ -234,6 +234,42 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigration, type: :m
end
end
+ describe '#retry_failed_jobs!' do
+ let(:batched_migration) { create(:batched_background_migration, status: 'failed') }
+
+ subject(:retry_failed_jobs) { batched_migration.retry_failed_jobs! }
+
+ context 'when there are failed migration jobs' do
+ let!(:batched_background_migration_job) { create(:batched_background_migration_job, batched_migration: batched_migration, batch_size: 10, min_value: 6, max_value: 15, status: :failed, attempts: 3) }
+
+ before do
+ allow_next_instance_of(Gitlab::BackgroundMigration::BatchingStrategies::PrimaryKeyBatchingStrategy) do |batch_class|
+ allow(batch_class).to receive(:next_batch).with(anything, anything, batch_min_value: 6, batch_size: 5).and_return([6, 10])
+ end
+ end
+
+ it 'moves the status of the migration to active' do
+ retry_failed_jobs
+
+ expect(batched_migration.status).to eql 'active'
+ end
+
+ it 'changes the number of attempts to 0' do
+ retry_failed_jobs
+
+ expect(batched_background_migration_job.reload.attempts).to be_zero
+ end
+ end
+
+ context 'when there are no failed migration jobs' do
+ it 'moves the status of the migration to active' do
+ retry_failed_jobs
+
+ expect(batched_migration.status).to eql 'active'
+ end
+ end
+ end
+
describe '#job_class_name=' do
it_behaves_like 'an attr_writer that demodulizes assigned class names', :job_class_name
end
diff --git a/spec/lib/gitlab/database/connection_spec.rb b/spec/lib/gitlab/database/connection_spec.rb
index 5e0e6039afc..7f94d7af4a9 100644
--- a/spec/lib/gitlab/database/connection_spec.rb
+++ b/spec/lib/gitlab/database/connection_spec.rb
@@ -5,29 +5,14 @@ require 'spec_helper'
RSpec.describe Gitlab::Database::Connection do
let(:connection) { described_class.new }
- describe '#default_pool_size' do
- before do
- allow(Gitlab::Runtime).to receive(:max_threads).and_return(7)
- end
-
- it 'returns the max thread size plus a fixed headroom of 10' do
- expect(connection.default_pool_size).to eq(17)
- end
-
- it 'returns the max thread size plus a DB_POOL_HEADROOM if this env var is present' do
- stub_env('DB_POOL_HEADROOM', '7')
-
- expect(connection.default_pool_size).to eq(14)
- end
- end
-
describe '#config' do
it 'returns a HashWithIndifferentAccess' do
expect(connection.config).to be_an_instance_of(HashWithIndifferentAccess)
end
it 'returns a default pool size' do
- expect(connection.config).to include(pool: connection.default_pool_size)
+ expect(connection.config)
+ .to include(pool: Gitlab::Database.default_pool_size)
end
it 'does not cache its results' do
@@ -43,7 +28,7 @@ RSpec.describe Gitlab::Database::Connection do
it 'returns the default pool size' do
expect(connection).to receive(:config).and_return({ pool: nil })
- expect(connection.pool_size).to eq(connection.default_pool_size)
+ expect(connection.pool_size).to eq(Gitlab::Database.default_pool_size)
end
end
@@ -129,7 +114,7 @@ RSpec.describe Gitlab::Database::Connection do
describe '#db_config_with_default_pool_size' do
it 'returns db_config with our default pool size' do
- allow(connection).to receive(:default_pool_size).and_return(9)
+ allow(Gitlab::Database).to receive(:default_pool_size).and_return(9)
expect(connection.db_config_with_default_pool_size.pool).to eq(9)
end
@@ -143,7 +128,7 @@ RSpec.describe Gitlab::Database::Connection do
describe '#disable_prepared_statements' do
around do |example|
- original_config = ::Gitlab::Database.main.config
+ original_config = connection.scope.connection.pool.db_config
example.run
@@ -162,6 +147,12 @@ RSpec.describe Gitlab::Database::Connection do
expect(connection.scope.connection.prepared_statements).to eq(false)
end
+ it 'retains the connection name' do
+ connection.disable_prepared_statements
+
+ expect(connection.scope.connection_db_config.name).to eq('main')
+ end
+
context 'with dynamic connection pool size' do
before do
connection.scope.establish_connection(connection.config.merge(pool: 7))
@@ -393,34 +384,28 @@ RSpec.describe Gitlab::Database::Connection do
end
describe '#cached_column_exists?' do
- it 'only retrieves data once' do
- expect(connection.scope.connection)
- .to receive(:columns)
- .once.and_call_original
-
- 2.times do
- expect(connection.cached_column_exists?(:projects, :id)).to be_truthy
- expect(connection.cached_column_exists?(:projects, :bogus_column)).to be_falsey
+ it 'only retrieves the data from the schema cache' do
+ queries = ActiveRecord::QueryRecorder.new do
+ 2.times do
+ expect(connection.cached_column_exists?(:projects, :id)).to be_truthy
+ expect(connection.cached_column_exists?(:projects, :bogus_column)).to be_falsey
+ end
end
+
+ expect(queries.count).to eq(0)
end
end
describe '#cached_table_exists?' do
- it 'only retrieves data once per table' do
- expect(connection.scope.connection)
- .to receive(:data_source_exists?)
- .with(:projects)
- .once.and_call_original
-
- expect(connection.scope.connection)
- .to receive(:data_source_exists?)
- .with(:bogus_table_name)
- .once.and_call_original
-
- 2.times do
- expect(connection.cached_table_exists?(:projects)).to be_truthy
- expect(connection.cached_table_exists?(:bogus_table_name)).to be_falsey
+ it 'only retrieves the data from the schema cache' do
+ queries = ActiveRecord::QueryRecorder.new do
+ 2.times do
+ expect(connection.cached_table_exists?(:projects)).to be_truthy
+ expect(connection.cached_table_exists?(:bogus_table_name)).to be_falsey
+ end
end
+
+ expect(queries.count).to eq(0)
end
it 'returns false when database does not exist' do
@@ -433,16 +418,14 @@ RSpec.describe Gitlab::Database::Connection do
end
describe '#exists?' do
- it 'returns true if `ActiveRecord::Base.connection` succeeds' do
- expect(connection.scope).to receive(:connection)
-
+ it 'returns true if the database exists' do
expect(connection.exists?).to be(true)
end
- it 'returns false if `ActiveRecord::Base.connection` fails' do
- expect(connection.scope).to receive(:connection) do
- raise ActiveRecord::NoDatabaseError, 'broken'
- end
+ it "returns false if the database doesn't exist" do
+ expect(connection.scope.connection.schema_cache)
+ .to receive(:database_version)
+ .and_raise(ActiveRecord::NoDatabaseError)
expect(connection.exists?).to be(false)
end
diff --git a/spec/lib/gitlab/database/load_balancing/action_cable_callbacks_spec.rb b/spec/lib/gitlab/database/load_balancing/action_cable_callbacks_spec.rb
new file mode 100644
index 00000000000..ebbbafb855f
--- /dev/null
+++ b/spec/lib/gitlab/database/load_balancing/action_cable_callbacks_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Database::LoadBalancing::ActionCableCallbacks, :request_store do
+ describe '.wrapper' do
+ it 'uses primary and then releases the connection and clears the session' do
+ expect(Gitlab::Database::LoadBalancing).to receive_message_chain(:proxy, :load_balancer, :release_host)
+ expect(Gitlab::Database::LoadBalancing::Session).to receive(:clear_session)
+
+ described_class.wrapper.call(
+ nil,
+ lambda do
+ expect(Gitlab::Database::LoadBalancing::Session.current.use_primary?).to eq(true)
+ end
+ )
+ end
+
+ context 'with an exception' do
+ it 'releases the connection and clears the session' do
+ expect(Gitlab::Database::LoadBalancing).to receive_message_chain(:proxy, :load_balancer, :release_host)
+ expect(Gitlab::Database::LoadBalancing::Session).to receive(:clear_session)
+
+ expect do
+ described_class.wrapper.call(nil, lambda { raise 'test_exception' })
+ end.to raise_error('test_exception')
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/database/load_balancing/configuration_spec.rb b/spec/lib/gitlab/database/load_balancing/configuration_spec.rb
new file mode 100644
index 00000000000..6621e6276a5
--- /dev/null
+++ b/spec/lib/gitlab/database/load_balancing/configuration_spec.rb
@@ -0,0 +1,175 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Database::LoadBalancing::Configuration do
+ let(:model) do
+ config = ActiveRecord::DatabaseConfigurations::HashConfig
+ .new('main', 'test', configuration_hash)
+
+ double(:model, connection_db_config: config)
+ end
+
+ describe '.for_model' do
+ context 'when load balancing is not configured' do
+ let(:configuration_hash) { {} }
+
+ it 'uses the default settings' do
+ config = described_class.for_model(model)
+
+ expect(config.hosts).to eq([])
+ expect(config.max_replication_difference).to eq(8.megabytes)
+ expect(config.max_replication_lag_time).to eq(60.0)
+ expect(config.replica_check_interval).to eq(60.0)
+ expect(config.service_discovery).to eq(
+ nameserver: 'localhost',
+ port: 8600,
+ record: nil,
+ record_type: 'A',
+ interval: 60,
+ disconnect_timeout: 120,
+ use_tcp: false
+ )
+ expect(config.pool_size).to eq(Gitlab::Database.default_pool_size)
+ end
+ end
+
+ context 'when load balancing is configured' do
+ let(:configuration_hash) do
+ {
+ pool: 4,
+ load_balancing: {
+ max_replication_difference: 1,
+ max_replication_lag_time: 2,
+ replica_check_interval: 3,
+ hosts: %w[foo bar],
+ discover: {
+ 'record' => 'foo.example.com'
+ }
+ }
+ }
+ end
+
+ it 'uses the custom configuration settings' do
+ config = described_class.for_model(model)
+
+ expect(config.hosts).to eq(%w[foo bar])
+ expect(config.max_replication_difference).to eq(1)
+ expect(config.max_replication_lag_time).to eq(2.0)
+ expect(config.replica_check_interval).to eq(3.0)
+ expect(config.service_discovery).to eq(
+ nameserver: 'localhost',
+ port: 8600,
+ record: 'foo.example.com',
+ record_type: 'A',
+ interval: 60,
+ disconnect_timeout: 120,
+ use_tcp: false
+ )
+ expect(config.pool_size).to eq(4)
+ end
+ end
+
+ context 'when the load balancing configuration uses strings as the keys' do
+ let(:configuration_hash) do
+ {
+ pool: 4,
+ load_balancing: {
+ 'max_replication_difference' => 1,
+ 'max_replication_lag_time' => 2,
+ 'replica_check_interval' => 3,
+ 'hosts' => %w[foo bar],
+ 'discover' => {
+ 'record' => 'foo.example.com'
+ }
+ }
+ }
+ end
+
+ it 'uses the custom configuration settings' do
+ config = described_class.for_model(model)
+
+ expect(config.hosts).to eq(%w[foo bar])
+ expect(config.max_replication_difference).to eq(1)
+ expect(config.max_replication_lag_time).to eq(2.0)
+ expect(config.replica_check_interval).to eq(3.0)
+ expect(config.service_discovery).to eq(
+ nameserver: 'localhost',
+ port: 8600,
+ record: 'foo.example.com',
+ record_type: 'A',
+ interval: 60,
+ disconnect_timeout: 120,
+ use_tcp: false
+ )
+ expect(config.pool_size).to eq(4)
+ end
+ end
+ end
+
+ describe '#load_balancing_enabled?' do
+ it 'returns true when hosts are configured' do
+ config = described_class.new(ActiveRecord::Base, %w[foo bar])
+
+ expect(config.load_balancing_enabled?).to eq(true)
+ end
+
+ it 'returns true when a service discovery record is configured' do
+ config = described_class.new(ActiveRecord::Base)
+ config.service_discovery[:record] = 'foo'
+
+ expect(config.load_balancing_enabled?).to eq(true)
+ end
+
+ it 'returns false when no hosts are configured and service discovery is disabled' do
+ config = described_class.new(ActiveRecord::Base)
+
+ expect(config.load_balancing_enabled?).to eq(false)
+ end
+ end
+
+ describe '#service_discovery_enabled?' do
+ it 'returns true when a record is configured' do
+ config = described_class.new(ActiveRecord::Base)
+ config.service_discovery[:record] = 'foo'
+
+ expect(config.service_discovery_enabled?).to eq(true)
+ end
+
+ it 'returns false when no record is configured' do
+ config = described_class.new(ActiveRecord::Base)
+
+ expect(config.service_discovery_enabled?).to eq(false)
+ end
+ end
+
+ describe '#pool_size' do
+ context 'when a custom pool size is used' do
+ let(:configuration_hash) { { pool: 4 } }
+
+ it 'always reads the value from the model configuration' do
+ config = described_class.new(model)
+
+ expect(config.pool_size).to eq(4)
+
+ # We can't modify `configuration_hash` as it's only used to populate the
+ # internal hash used by ActiveRecord; instead of it being used as-is.
+ allow(model.connection_db_config)
+ .to receive(:configuration_hash)
+ .and_return({ pool: 42 })
+
+ expect(config.pool_size).to eq(42)
+ end
+ end
+
+ context 'when the pool size is nil' do
+ let(:configuration_hash) { {} }
+
+ it 'returns the default pool size' do
+ config = described_class.new(model)
+
+ expect(config.pool_size).to eq(Gitlab::Database.default_pool_size)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/database/load_balancing/connection_proxy_spec.rb b/spec/lib/gitlab/database/load_balancing/connection_proxy_spec.rb
index 0ca99ec9acf..ba2f9485066 100644
--- a/spec/lib/gitlab/database/load_balancing/connection_proxy_spec.rb
+++ b/spec/lib/gitlab/database/load_balancing/connection_proxy_spec.rb
@@ -3,7 +3,12 @@
require 'spec_helper'
RSpec.describe Gitlab::Database::LoadBalancing::ConnectionProxy do
- let(:proxy) { described_class.new }
+ let(:proxy) do
+ config = Gitlab::Database::LoadBalancing::Configuration
+ .new(ActiveRecord::Base)
+
+ described_class.new(Gitlab::Database::LoadBalancing::LoadBalancer.new(config))
+ end
describe '#select' do
it 'performs a read' do
@@ -35,9 +40,15 @@ RSpec.describe Gitlab::Database::LoadBalancing::ConnectionProxy do
describe 'using a SELECT FOR UPDATE query' do
it 'runs the query on the primary and sticks to it' do
arel = double(:arel, locked: true)
+ session = Gitlab::Database::LoadBalancing::Session.new
+
+ allow(Gitlab::Database::LoadBalancing::Session).to receive(:current)
+ .and_return(session)
+
+ expect(session).to receive(:write!)
expect(proxy).to receive(:write_using_load_balancer)
- .with(:select_all, arel, 'foo', [], sticky: true)
+ .with(:select_all, arel, 'foo', [])
proxy.select_all(arel, 'foo')
end
@@ -58,8 +69,13 @@ RSpec.describe Gitlab::Database::LoadBalancing::ConnectionProxy do
Gitlab::Database::LoadBalancing::ConnectionProxy::STICKY_WRITES.each do |name|
describe "#{name}" do
it 'runs the query on the primary and sticks to it' do
- expect(proxy).to receive(:write_using_load_balancer)
- .with(name, 'foo', sticky: true)
+ session = Gitlab::Database::LoadBalancing::Session.new
+
+ allow(Gitlab::Database::LoadBalancing::Session).to receive(:current)
+ .and_return(session)
+
+ expect(session).to receive(:write!)
+ expect(proxy).to receive(:write_using_load_balancer).with(name, 'foo')
proxy.send(name, 'foo')
end
@@ -108,7 +124,7 @@ RSpec.describe Gitlab::Database::LoadBalancing::ConnectionProxy do
# We have an extra test for #transaction here to make sure that nested queries
# are also sent to a primary.
describe '#transaction' do
- let(:session) { double(:session) }
+ let(:session) { Gitlab::Database::LoadBalancing::Session.new }
before do
allow(Gitlab::Database::LoadBalancing::Session).to receive(:current)
@@ -192,7 +208,7 @@ RSpec.describe Gitlab::Database::LoadBalancing::ConnectionProxy do
proxy.foo('foo')
end
- it 'properly forwards trailing hash arguments' do
+ it 'properly forwards keyword arguments' do
allow(proxy.load_balancer).to receive(:read_write)
expect(proxy).to receive(:write_using_load_balancer).and_call_original
@@ -217,7 +233,7 @@ RSpec.describe Gitlab::Database::LoadBalancing::ConnectionProxy do
proxy.foo('foo')
end
- it 'properly forwards trailing hash arguments' do
+ it 'properly forwards keyword arguments' do
allow(proxy.load_balancer).to receive(:read)
expect(proxy).to receive(:read_using_load_balancer).and_call_original
@@ -297,20 +313,12 @@ RSpec.describe Gitlab::Database::LoadBalancing::ConnectionProxy do
.and_return(session)
end
- it 'uses but does not stick to the primary when sticking is disabled' do
+ it 'uses but does not stick to the primary' do
expect(proxy.load_balancer).to receive(:read_write).and_yield(connection)
expect(connection).to receive(:foo).with('foo')
expect(session).not_to receive(:write!)
proxy.write_using_load_balancer(:foo, 'foo')
end
-
- it 'sticks to the primary when sticking is enabled' do
- expect(proxy.load_balancer).to receive(:read_write).and_yield(connection)
- expect(connection).to receive(:foo).with('foo')
- expect(session).to receive(:write!)
-
- proxy.write_using_load_balancer(:foo, 'foo', sticky: true)
- end
end
end
diff --git a/spec/lib/gitlab/database/load_balancing/host_list_spec.rb b/spec/lib/gitlab/database/load_balancing/host_list_spec.rb
index ad4ca18d5e6..9bb8116c434 100644
--- a/spec/lib/gitlab/database/load_balancing/host_list_spec.rb
+++ b/spec/lib/gitlab/database/load_balancing/host_list_spec.rb
@@ -4,7 +4,12 @@ require 'spec_helper'
RSpec.describe Gitlab::Database::LoadBalancing::HostList do
let(:db_host) { ActiveRecord::Base.connection_pool.db_config.host }
- let(:load_balancer) { double(:load_balancer) }
+ let(:load_balancer) do
+ Gitlab::Database::LoadBalancing::LoadBalancer.new(
+ Gitlab::Database::LoadBalancing::Configuration.new(ActiveRecord::Base)
+ )
+ end
+
let(:host_count) { 2 }
let(:hosts) { Array.new(host_count) { Gitlab::Database::LoadBalancing::Host.new(db_host, load_balancer, port: 5432) } }
let(:host_list) { described_class.new(hosts) }
diff --git a/spec/lib/gitlab/database/load_balancing/host_spec.rb b/spec/lib/gitlab/database/load_balancing/host_spec.rb
index f42ac8be1bb..e2011692228 100644
--- a/spec/lib/gitlab/database/load_balancing/host_spec.rb
+++ b/spec/lib/gitlab/database/load_balancing/host_spec.rb
@@ -3,7 +3,10 @@
require 'spec_helper'
RSpec.describe Gitlab::Database::LoadBalancing::Host do
- let(:load_balancer) { Gitlab::Database::LoadBalancing::LoadBalancer.new }
+ let(:load_balancer) do
+ Gitlab::Database::LoadBalancing::LoadBalancer
+ .new(Gitlab::Database::LoadBalancing::Configuration.new(ActiveRecord::Base))
+ end
let(:host) do
Gitlab::Database::LoadBalancing::Host.new('localhost', load_balancer)
@@ -274,7 +277,7 @@ RSpec.describe Gitlab::Database::LoadBalancing::Host do
end
it 'returns false when the data is not recent enough' do
- diff = Gitlab::Database::LoadBalancing.max_replication_difference * 2
+ diff = load_balancer.configuration.max_replication_difference * 2
expect(host)
.to receive(:query_and_release)
diff --git a/spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb b/spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb
index c647f5a8f5d..86fae14b961 100644
--- a/spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb
+++ b/spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb
@@ -5,7 +5,12 @@ require 'spec_helper'
RSpec.describe Gitlab::Database::LoadBalancing::LoadBalancer, :request_store do
let(:conflict_error) { Class.new(RuntimeError) }
let(:db_host) { ActiveRecord::Base.connection_pool.db_config.host }
- let(:lb) { described_class.new([db_host, db_host]) }
+ let(:config) do
+ Gitlab::Database::LoadBalancing::Configuration
+ .new(ActiveRecord::Base, [db_host, db_host])
+ end
+
+ let(:lb) { described_class.new(config) }
let(:request_cache) { lb.send(:request_cache) }
before do
@@ -41,6 +46,19 @@ RSpec.describe Gitlab::Database::LoadBalancing::LoadBalancer, :request_store do
top_error
end
+ describe '#initialize' do
+ it 'ignores the hosts when the primary_only option is enabled' do
+ config = Gitlab::Database::LoadBalancing::Configuration
+ .new(ActiveRecord::Base, [db_host])
+ lb = described_class.new(config, primary_only: true)
+ hosts = lb.host_list.hosts
+
+ expect(hosts.length).to eq(1)
+ expect(hosts.first)
+ .to be_instance_of(Gitlab::Database::LoadBalancing::PrimaryHost)
+ end
+ end
+
describe '#read' do
it 'yields a connection for a read' do
connection = double(:connection)
@@ -121,6 +139,19 @@ RSpec.describe Gitlab::Database::LoadBalancing::LoadBalancer, :request_store do
expect { |b| lb.read(&b) }
.to yield_with_args(ActiveRecord::Base.retrieve_connection)
end
+
+ it 'uses the primary when the primary_only option is enabled' do
+ config = Gitlab::Database::LoadBalancing::Configuration
+ .new(ActiveRecord::Base)
+ lb = described_class.new(config, primary_only: true)
+
+ # When no hosts are configured, we don't want to produce any warnings, as
+ # they aren't useful/too noisy.
+ expect(Gitlab::Database::LoadBalancing::Logger).not_to receive(:warn)
+
+ expect { |b| lb.read(&b) }
+ .to yield_with_args(ActiveRecord::Base.retrieve_connection)
+ end
end
describe '#read_write' do
@@ -152,8 +183,11 @@ RSpec.describe Gitlab::Database::LoadBalancing::LoadBalancer, :request_store do
end
it 'does not create conflicts with other load balancers when caching hosts' do
- lb1 = described_class.new([db_host, db_host], ActiveRecord::Base)
- lb2 = described_class.new([db_host, db_host], Ci::CiDatabaseRecord)
+ ci_config = Gitlab::Database::LoadBalancing::Configuration
+ .new(Ci::CiDatabaseRecord, [db_host, db_host])
+
+ lb1 = described_class.new(config)
+ lb2 = described_class.new(ci_config)
host1 = lb1.host
host2 = lb2.host
@@ -283,6 +317,12 @@ RSpec.describe Gitlab::Database::LoadBalancing::LoadBalancer, :request_store do
expect(lb.connection_error?(error)).to eq(false)
end
+
+ it 'returns false for ActiveRecord errors without a cause' do
+ error = ActiveRecord::RecordNotUnique.new
+
+ expect(lb.connection_error?(error)).to eq(false)
+ end
end
describe '#serialization_failure?' do
diff --git a/spec/lib/gitlab/database/load_balancing/primary_host_spec.rb b/spec/lib/gitlab/database/load_balancing/primary_host_spec.rb
new file mode 100644
index 00000000000..a0e63a7ee4e
--- /dev/null
+++ b/spec/lib/gitlab/database/load_balancing/primary_host_spec.rb
@@ -0,0 +1,126 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Database::LoadBalancing::PrimaryHost do
+ let(:load_balancer) do
+ Gitlab::Database::LoadBalancing::LoadBalancer.new(
+ Gitlab::Database::LoadBalancing::Configuration.new(ActiveRecord::Base)
+ )
+ end
+
+ let(:host) { Gitlab::Database::LoadBalancing::PrimaryHost.new(load_balancer) }
+
+ describe '#connection' do
+ it 'returns a connection from the pool' do
+ expect(load_balancer.pool).to receive(:connection)
+
+ host.connection
+ end
+ end
+
+ describe '#release_connection' do
+ it 'does nothing' do
+ expect(host.release_connection).to be_nil
+ end
+ end
+
+ describe '#enable_query_cache!' do
+ it 'does nothing' do
+ expect(host.enable_query_cache!).to be_nil
+ end
+ end
+
+ describe '#disable_query_cache!' do
+ it 'does nothing' do
+ expect(host.disable_query_cache!).to be_nil
+ end
+ end
+
+ describe '#query_cache_enabled' do
+ it 'delegates to the primary connection pool' do
+ expect(host.query_cache_enabled)
+ .to eq(load_balancer.pool.query_cache_enabled)
+ end
+ end
+
+ describe '#disconnect!' do
+ it 'does nothing' do
+ expect(host.disconnect!).to be_nil
+ end
+ end
+
+ describe '#offline!' do
+ it 'does nothing' do
+ expect(host.offline!).to be_nil
+ end
+ end
+
+ describe '#online?' do
+ it 'returns true' do
+ expect(host.online?).to eq(true)
+ end
+ end
+
+ describe '#primary_write_location' do
+ it 'returns the write location of the primary' do
+ expect(host.primary_write_location).to be_an_instance_of(String)
+ expect(host.primary_write_location).not_to be_empty
+ end
+ end
+
+ describe '#caught_up?' do
+ it 'returns true' do
+ expect(host.caught_up?('foo')).to eq(true)
+ end
+ end
+
+ describe '#database_replica_location' do
+ let(:connection) { double(:connection) }
+
+ it 'returns the write ahead location of the replica', :aggregate_failures do
+ expect(host)
+ .to receive(:query_and_release)
+ .and_return({ 'location' => '0/D525E3A8' })
+
+ expect(host.database_replica_location).to be_an_instance_of(String)
+ end
+
+ it 'returns nil when the database query returned no rows' do
+ expect(host).to receive(:query_and_release).and_return({})
+
+ expect(host.database_replica_location).to be_nil
+ end
+
+ it 'returns nil when the database connection fails' do
+ allow(host).to receive(:connection).and_raise(PG::Error)
+
+ expect(host.database_replica_location).to be_nil
+ end
+ end
+
+ describe '#query_and_release' do
+ it 'executes a SQL query' do
+ results = host.query_and_release('SELECT 10 AS number')
+
+ expect(results).to be_an_instance_of(Hash)
+ expect(results['number'].to_i).to eq(10)
+ end
+
+ it 'releases the connection after running the query' do
+ expect(host)
+ .to receive(:release_connection)
+ .once
+
+ host.query_and_release('SELECT 10 AS number')
+ end
+
+ it 'returns an empty Hash in the event of an error' do
+ expect(host.connection)
+ .to receive(:select_all)
+ .and_raise(RuntimeError, 'kittens')
+
+ expect(host.query_and_release('SELECT 10 AS number')).to eq({})
+ end
+ end
+end
diff --git a/spec/lib/gitlab/database/load_balancing/service_discovery_spec.rb b/spec/lib/gitlab/database/load_balancing/service_discovery_spec.rb
index a27341a3324..e9bc465b1c7 100644
--- a/spec/lib/gitlab/database/load_balancing/service_discovery_spec.rb
+++ b/spec/lib/gitlab/database/load_balancing/service_discovery_spec.rb
@@ -3,13 +3,18 @@
require 'spec_helper'
RSpec.describe Gitlab::Database::LoadBalancing::ServiceDiscovery do
- let(:load_balancer) { Gitlab::Database::LoadBalancing::LoadBalancer.new([]) }
+ let(:load_balancer) do
+ Gitlab::Database::LoadBalancing::LoadBalancer.new(
+ Gitlab::Database::LoadBalancing::Configuration.new(ActiveRecord::Base)
+ )
+ end
+
let(:service) do
described_class.new(
+ load_balancer,
nameserver: 'localhost',
port: 8600,
- record: 'foo',
- load_balancer: load_balancer
+ record: 'foo'
)
end
@@ -26,11 +31,11 @@ RSpec.describe Gitlab::Database::LoadBalancing::ServiceDiscovery do
describe ':record_type' do
subject do
described_class.new(
+ load_balancer,
nameserver: 'localhost',
port: 8600,
record: 'foo',
- record_type: record_type,
- load_balancer: load_balancer
+ record_type: record_type
)
end
@@ -69,18 +74,69 @@ RSpec.describe Gitlab::Database::LoadBalancing::ServiceDiscovery do
end
describe '#perform_service_discovery' do
- it 'reports exceptions to Sentry' do
- error = StandardError.new
+ context 'without any failures' do
+ it 'runs once' do
+ expect(service)
+ .to receive(:refresh_if_necessary).once
+
+ expect(service).not_to receive(:sleep)
+
+ expect(Gitlab::ErrorTracking).not_to receive(:track_exception)
+
+ service.perform_service_discovery
+ end
+ end
+ context 'with failures' do
+ before do
+ allow(Gitlab::ErrorTracking).to receive(:track_exception)
+ allow(service).to receive(:sleep)
+ end
+
+ let(:valid_retry_sleep_duration) { satisfy { |val| described_class::RETRY_DELAY_RANGE.include?(val) } }
+
+ it 'retries service discovery when under the retry limit' do
+ error = StandardError.new
+
+ expect(service)
+ .to receive(:refresh_if_necessary)
+ .and_raise(error).exactly(described_class::MAX_DISCOVERY_RETRIES - 1).times.ordered
+
+ expect(service)
+ .to receive(:sleep).with(valid_retry_sleep_duration)
+ .exactly(described_class::MAX_DISCOVERY_RETRIES - 1).times
+
+ expect(service).to receive(:refresh_if_necessary).and_return(45).ordered
+
+ expect(service.perform_service_discovery).to eq(45)
+ end
+
+ it 'does not retry service discovery after exceeding the limit' do
+ error = StandardError.new
+
+ expect(service)
+ .to receive(:refresh_if_necessary)
+ .and_raise(error).exactly(described_class::MAX_DISCOVERY_RETRIES).times
+
+ expect(service)
+ .to receive(:sleep).with(valid_retry_sleep_duration)
+ .exactly(described_class::MAX_DISCOVERY_RETRIES).times
+
+ service.perform_service_discovery
+ end
- expect(service)
- .to receive(:refresh_if_necessary)
- .and_raise(error)
+ it 'reports exceptions to Sentry' do
+ error = StandardError.new
+
+ expect(service)
+ .to receive(:refresh_if_necessary)
+ .and_raise(error).exactly(described_class::MAX_DISCOVERY_RETRIES).times
- expect(Gitlab::ErrorTracking)
- .to receive(:track_exception)
- .with(error)
+ expect(Gitlab::ErrorTracking)
+ .to receive(:track_exception)
+ .with(error).exactly(described_class::MAX_DISCOVERY_RETRIES).times
- service.perform_service_discovery
+ service.perform_service_discovery
+ end
end
end
@@ -133,7 +189,10 @@ RSpec.describe Gitlab::Database::LoadBalancing::ServiceDiscovery do
let(:address_bar) { described_class::Address.new('bar') }
let(:load_balancer) do
- Gitlab::Database::LoadBalancing::LoadBalancer.new([address_foo])
+ Gitlab::Database::LoadBalancing::LoadBalancer.new(
+ Gitlab::Database::LoadBalancing::Configuration
+ .new(ActiveRecord::Base, [address_foo])
+ )
end
before do
@@ -166,11 +225,11 @@ RSpec.describe Gitlab::Database::LoadBalancing::ServiceDiscovery do
describe '#addresses_from_dns' do
let(:service) do
described_class.new(
+ load_balancer,
nameserver: 'localhost',
port: 8600,
record: 'foo',
- record_type: record_type,
- load_balancer: load_balancer
+ record_type: record_type
)
end
@@ -224,6 +283,16 @@ RSpec.describe Gitlab::Database::LoadBalancing::ServiceDiscovery do
expect(service.addresses_from_dns).to eq([90, addresses])
end
end
+
+ context 'when the resolver returns an empty response' do
+ let(:packet) { double(:packet, answer: []) }
+
+ let(:record_type) { 'A' }
+
+ it 'raises EmptyDnsResponse' do
+ expect { service.addresses_from_dns }.to raise_error(Gitlab::Database::LoadBalancing::ServiceDiscovery::EmptyDnsResponse)
+ end
+ end
end
describe '#new_wait_time_for' do
@@ -246,7 +315,10 @@ RSpec.describe Gitlab::Database::LoadBalancing::ServiceDiscovery do
describe '#addresses_from_load_balancer' do
let(:load_balancer) do
- Gitlab::Database::LoadBalancing::LoadBalancer.new(%w[b a])
+ Gitlab::Database::LoadBalancing::LoadBalancer.new(
+ Gitlab::Database::LoadBalancing::Configuration
+ .new(ActiveRecord::Base, %w[b a])
+ )
end
it 'returns the ordered host names of the load balancer' do
diff --git a/spec/lib/gitlab/database/load_balancing/sidekiq_client_middleware_spec.rb b/spec/lib/gitlab/database/load_balancing/sidekiq_client_middleware_spec.rb
index 54050a87af0..f683ade978a 100644
--- a/spec/lib/gitlab/database/load_balancing/sidekiq_client_middleware_spec.rb
+++ b/spec/lib/gitlab/database/load_balancing/sidekiq_client_middleware_spec.rb
@@ -58,8 +58,7 @@ RSpec.describe Gitlab::Database::LoadBalancing::SidekiqClientMiddleware do
it 'does not pass database locations', :aggregate_failures do
run_middleware
- expect(job['database_replica_location']).to be_nil
- expect(job['database_write_location']).to be_nil
+ expect(job['wal_locations']).to be_nil
end
include_examples 'job data consistency'
@@ -86,11 +85,13 @@ RSpec.describe Gitlab::Database::LoadBalancing::SidekiqClientMiddleware do
end
it 'passes database_replica_location' do
+ expected_location = { Gitlab::Database::MAIN_DATABASE_NAME.to_sym => location }
+
expect(load_balancer).to receive_message_chain(:host, "database_replica_location").and_return(location)
run_middleware
- expect(job['database_replica_location']).to eq(location)
+ expect(job['wal_locations']).to eq(expected_location)
end
include_examples 'job data consistency'
@@ -102,40 +103,56 @@ RSpec.describe Gitlab::Database::LoadBalancing::SidekiqClientMiddleware do
end
it 'passes primary write location', :aggregate_failures do
+ expected_location = { Gitlab::Database::MAIN_DATABASE_NAME.to_sym => location }
+
expect(load_balancer).to receive(:primary_write_location).and_return(location)
run_middleware
- expect(job['database_write_location']).to eq(location)
+ expect(job['wal_locations']).to eq(expected_location)
end
include_examples 'job data consistency'
end
end
- shared_examples_for 'database location was already provided' do |provided_database_location, other_location|
- shared_examples_for 'does not set database location again' do |use_primary|
- before do
- allow(Gitlab::Database::LoadBalancing::Session.current).to receive(:use_primary?).and_return(use_primary)
- end
+ context 'when worker cannot be constantized' do
+ let(:worker_class) { 'ActionMailer::MailDeliveryJob' }
+ let(:expected_consistency) { :always }
- it 'does not set database locations again' do
- run_middleware
+ include_examples 'does not pass database locations'
+ end
- expect(job[provided_database_location]).to eq(old_location)
- expect(job[other_location]).to be_nil
- end
- end
+ context 'when worker class does not include ApplicationWorker' do
+ let(:worker_class) { ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper }
+ let(:expected_consistency) { :always }
+
+ include_examples 'does not pass database locations'
+ end
+ context 'database wal location was already provided' do
let(:old_location) { '0/D525E3A8' }
let(:new_location) { 'AB/12345' }
- let(:job) { { "job_id" => "a180b47c-3fd6-41b8-81e9-34da61c3400e", provided_database_location => old_location } }
+ let(:wal_locations) { { Gitlab::Database::MAIN_DATABASE_NAME.to_sym => old_location } }
+ let(:job) { { "job_id" => "a180b47c-3fd6-41b8-81e9-34da61c3400e", 'wal_locations' => wal_locations } }
before do
allow(load_balancer).to receive(:primary_write_location).and_return(new_location)
allow(load_balancer).to receive(:database_replica_location).and_return(new_location)
end
+ shared_examples_for 'does not set database location again' do |use_primary|
+ before do
+ allow(Gitlab::Database::LoadBalancing::Session.current).to receive(:use_primary?).and_return(use_primary)
+ end
+
+ it 'does not set database locations again' do
+ run_middleware
+
+ expect(job['wal_locations']).to eq(wal_locations)
+ end
+ end
+
context "when write was performed" do
include_examples 'does not set database location again', true
end
@@ -145,28 +162,6 @@ RSpec.describe Gitlab::Database::LoadBalancing::SidekiqClientMiddleware do
end
end
- context 'when worker cannot be constantized' do
- let(:worker_class) { 'ActionMailer::MailDeliveryJob' }
- let(:expected_consistency) { :always }
-
- include_examples 'does not pass database locations'
- end
-
- context 'when worker class does not include ApplicationWorker' do
- let(:worker_class) { ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper }
- let(:expected_consistency) { :always }
-
- include_examples 'does not pass database locations'
- end
-
- context 'database write location was already provided' do
- include_examples 'database location was already provided', 'database_write_location', 'database_replica_location'
- end
-
- context 'database replica location was already provided' do
- include_examples 'database location was already provided', 'database_replica_location', 'database_write_location'
- end
-
context 'when worker data consistency is :always' do
include_context 'data consistency worker class', :always, :load_balancing_for_test_data_consistency_worker
diff --git a/spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb b/spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb
index 14f240cd159..9f23eb0094f 100644
--- a/spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb
+++ b/spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb
@@ -62,9 +62,12 @@ RSpec.describe Gitlab::Database::LoadBalancing::SidekiqServerMiddleware do
include_examples 'load balancing strategy', expected_strategy
end
- shared_examples_for 'replica is up to date' do |location, expected_strategy|
+ shared_examples_for 'replica is up to date' do |expected_strategy|
+ let(:location) {'0/D525E3A8' }
+ let(:wal_locations) { { Gitlab::Database::MAIN_DATABASE_NAME.to_sym => location } }
+
it 'does not stick to the primary', :aggregate_failures do
- expect(middleware).to receive(:replica_caught_up?).with(location).and_return(true)
+ expect(load_balancer).to receive(:select_up_to_date_host).with(location).and_return(true)
run_middleware do
expect(Gitlab::Database::LoadBalancing::Session.current.use_primary?).not_to be_truthy
@@ -85,30 +88,40 @@ RSpec.describe Gitlab::Database::LoadBalancing::SidekiqServerMiddleware do
include_examples 'stick to the primary', 'primary'
end
- context 'when database replica location is set' do
- let(:job) { { 'job_id' => 'a180b47c-3fd6-41b8-81e9-34da61c3400e', 'database_replica_location' => '0/D525E3A8' } }
+ context 'when database wal location is set' do
+ let(:job) { { 'job_id' => 'a180b47c-3fd6-41b8-81e9-34da61c3400e', 'wal_locations' => wal_locations } }
+
+ before do
+ allow(load_balancer).to receive(:select_up_to_date_host).with(location).and_return(true)
+ end
+
+ it_behaves_like 'replica is up to date', 'replica'
+ end
+
+ context 'when deduplication wal location is set' do
+ let(:job) { { 'job_id' => 'a180b47c-3fd6-41b8-81e9-34da61c3400e', 'dedup_wal_locations' => wal_locations } }
before do
- allow(middleware).to receive(:replica_caught_up?).and_return(true)
+ allow(load_balancer).to receive(:select_up_to_date_host).with(wal_locations[:main]).and_return(true)
end
- it_behaves_like 'replica is up to date', '0/D525E3A8', 'replica'
+ it_behaves_like 'replica is up to date', 'replica'
end
- context 'when database primary location is set' do
+ context 'when legacy wal location is set' do
let(:job) { { 'job_id' => 'a180b47c-3fd6-41b8-81e9-34da61c3400e', 'database_write_location' => '0/D525E3A8' } }
before do
- allow(middleware).to receive(:replica_caught_up?).and_return(true)
+ allow(load_balancer).to receive(:select_up_to_date_host).with('0/D525E3A8').and_return(true)
end
- it_behaves_like 'replica is up to date', '0/D525E3A8', 'replica'
+ it_behaves_like 'replica is up to date', 'replica'
end
context 'when database location is not set' do
let(:job) { { 'job_id' => 'a180b47c-3fd6-41b8-81e9-34da61c3400e' } }
- it_behaves_like 'stick to the primary', 'primary_no_wal'
+ include_examples 'stick to the primary', 'primary_no_wal'
end
end
@@ -167,7 +180,7 @@ RSpec.describe Gitlab::Database::LoadBalancing::SidekiqServerMiddleware do
replication_lag!(false)
end
- it_behaves_like 'replica is up to date', '0/D525E3A8', 'replica_retried'
+ include_examples 'replica is up to date', 'replica_retried'
end
end
end
@@ -178,7 +191,7 @@ RSpec.describe Gitlab::Database::LoadBalancing::SidekiqServerMiddleware do
context 'when replica is not up to date' do
before do
- allow(middleware).to receive(:replica_caught_up?).and_return(false)
+ allow(load_balancer).to receive(:select_up_to_date_host).and_return(false)
end
include_examples 'stick to the primary', 'primary'
diff --git a/spec/lib/gitlab/database/load_balancing_spec.rb b/spec/lib/gitlab/database/load_balancing_spec.rb
index 6ec8e0516f6..f40ad444081 100644
--- a/spec/lib/gitlab/database/load_balancing_spec.rb
+++ b/spec/lib/gitlab/database/load_balancing_spec.rb
@@ -40,106 +40,25 @@ RSpec.describe Gitlab::Database::LoadBalancing do
end
describe '.configuration' do
- it 'returns a Hash' do
- lb_config = { 'hosts' => %w(foo) }
+ it 'returns the configuration for the load balancer' do
+ raw = ActiveRecord::Base.connection_db_config.configuration_hash
+ cfg = described_class.configuration
- original_db_config = Gitlab::Database.main.config
- modified_db_config = original_db_config.merge(load_balancing: lb_config)
- expect(Gitlab::Database.main).to receive(:config).and_return(modified_db_config)
-
- expect(described_class.configuration).to eq(lb_config)
- end
- end
-
- describe '.max_replication_difference' do
- context 'without an explicitly configured value' do
- it 'returns the default value' do
- allow(described_class)
- .to receive(:configuration)
- .and_return({})
-
- expect(described_class.max_replication_difference).to eq(8.megabytes)
- end
- end
-
- context 'with an explicitly configured value' do
- it 'returns the configured value' do
- allow(described_class)
- .to receive(:configuration)
- .and_return({ 'max_replication_difference' => 4 })
-
- expect(described_class.max_replication_difference).to eq(4)
- end
- end
- end
-
- describe '.max_replication_lag_time' do
- context 'without an explicitly configured value' do
- it 'returns the default value' do
- allow(described_class)
- .to receive(:configuration)
- .and_return({})
-
- expect(described_class.max_replication_lag_time).to eq(60)
- end
- end
-
- context 'with an explicitly configured value' do
- it 'returns the configured value' do
- allow(described_class)
- .to receive(:configuration)
- .and_return({ 'max_replication_lag_time' => 4 })
-
- expect(described_class.max_replication_lag_time).to eq(4)
- end
- end
- end
-
- describe '.replica_check_interval' do
- context 'without an explicitly configured value' do
- it 'returns the default value' do
- allow(described_class)
- .to receive(:configuration)
- .and_return({})
-
- expect(described_class.replica_check_interval).to eq(60)
- end
- end
-
- context 'with an explicitly configured value' do
- it 'returns the configured value' do
- allow(described_class)
- .to receive(:configuration)
- .and_return({ 'replica_check_interval' => 4 })
-
- expect(described_class.replica_check_interval).to eq(4)
- end
- end
- end
-
- describe '.hosts' do
- it 'returns a list of hosts' do
- allow(described_class)
- .to receive(:configuration)
- .and_return({ 'hosts' => %w(foo bar baz) })
-
- expect(described_class.hosts).to eq(%w(foo bar baz))
- end
- end
-
- describe '.pool_size' do
- it 'returns a Fixnum' do
- expect(described_class.pool_size).to be_a_kind_of(Integer)
+ # There isn't much to test here as the load balancing settings might not
+ # (and likely aren't) set when running tests.
+ expect(cfg.pool_size).to eq(raw[:pool])
end
end
describe '.enable?' do
before do
- allow(described_class).to receive(:hosts).and_return(%w(foo))
+ allow(described_class.configuration)
+ .to receive(:hosts)
+ .and_return(%w(foo))
end
it 'returns false when no hosts are specified' do
- allow(described_class).to receive(:hosts).and_return([])
+ allow(described_class.configuration).to receive(:hosts).and_return([])
expect(described_class.enable?).to eq(false)
end
@@ -163,10 +82,10 @@ RSpec.describe Gitlab::Database::LoadBalancing do
end
it 'returns true when service discovery is enabled' do
- allow(described_class).to receive(:hosts).and_return([])
+ allow(described_class.configuration).to receive(:hosts).and_return([])
allow(Gitlab::Runtime).to receive(:sidekiq?).and_return(false)
- allow(described_class)
+ allow(described_class.configuration)
.to receive(:service_discovery_enabled?)
.and_return(true)
@@ -175,17 +94,17 @@ RSpec.describe Gitlab::Database::LoadBalancing do
end
describe '.configured?' do
- it 'returns true when Sidekiq is being used' do
- allow(described_class).to receive(:hosts).and_return(%w(foo))
- allow(Gitlab::Runtime).to receive(:sidekiq?).and_return(true)
+ it 'returns true when hosts are configured' do
+ allow(described_class.configuration)
+ .to receive(:hosts)
+ .and_return(%w[foo])
+
expect(described_class.configured?).to eq(true)
end
- it 'returns true when service discovery is enabled in Sidekiq' do
- allow(described_class).to receive(:hosts).and_return([])
- allow(Gitlab::Runtime).to receive(:sidekiq?).and_return(true)
-
- allow(described_class)
+ it 'returns true when service discovery is enabled' do
+ allow(described_class.configuration).to receive(:hosts).and_return([])
+ allow(described_class.configuration)
.to receive(:service_discovery_enabled?)
.and_return(true)
@@ -193,9 +112,8 @@ RSpec.describe Gitlab::Database::LoadBalancing do
end
it 'returns false when neither service discovery nor hosts are configured' do
- allow(described_class).to receive(:hosts).and_return([])
-
- allow(described_class)
+ allow(described_class.configuration).to receive(:hosts).and_return([])
+ allow(described_class.configuration)
.to receive(:service_discovery_enabled?)
.and_return(false)
@@ -204,9 +122,11 @@ RSpec.describe Gitlab::Database::LoadBalancing do
end
describe '.configure_proxy' do
- it 'configures the connection proxy' do
+ before do
allow(ActiveRecord::Base).to receive(:load_balancing_proxy=)
+ end
+ it 'configures the connection proxy' do
described_class.configure_proxy
expect(ActiveRecord::Base).to have_received(:load_balancing_proxy=)
@@ -214,71 +134,24 @@ RSpec.describe Gitlab::Database::LoadBalancing do
end
context 'when service discovery is enabled' do
- let(:service_discovery) { double(Gitlab::Database::LoadBalancing::ServiceDiscovery) }
-
it 'runs initial service discovery when configuring the connection proxy' do
- allow(described_class)
- .to receive(:configuration)
- .and_return('discover' => { 'record' => 'foo' })
-
- expect(Gitlab::Database::LoadBalancing::ServiceDiscovery).to receive(:new).and_return(service_discovery)
- expect(service_discovery).to receive(:perform_service_discovery)
-
- described_class.configure_proxy
- end
- end
- end
+ discover = instance_spy(Gitlab::Database::LoadBalancing::ServiceDiscovery)
- describe '.active_record_models' do
- it 'returns an Array' do
- expect(described_class.active_record_models).to be_an_instance_of(Array)
- end
- end
+ allow(described_class.configuration)
+ .to receive(:service_discovery)
+ .and_return({ record: 'foo' })
- describe '.service_discovery_enabled?' do
- it 'returns true if service discovery is enabled' do
- allow(described_class)
- .to receive(:configuration)
- .and_return('discover' => { 'record' => 'foo' })
-
- expect(described_class.service_discovery_enabled?).to eq(true)
- end
+ expect(Gitlab::Database::LoadBalancing::ServiceDiscovery)
+ .to receive(:new)
+ .with(
+ an_instance_of(Gitlab::Database::LoadBalancing::LoadBalancer),
+ an_instance_of(Hash)
+ )
+ .and_return(discover)
- it 'returns false if service discovery is disabled' do
- expect(described_class.service_discovery_enabled?).to eq(false)
- end
- end
+ expect(discover).to receive(:perform_service_discovery)
- describe '.service_discovery_configuration' do
- context 'when no configuration is provided' do
- it 'returns a default configuration Hash' do
- expect(described_class.service_discovery_configuration).to eq(
- nameserver: 'localhost',
- port: 8600,
- record: nil,
- record_type: 'A',
- interval: 60,
- disconnect_timeout: 120,
- use_tcp: false
- )
- end
- end
-
- context 'when configuration is provided' do
- it 'returns a Hash including the custom configuration' do
- allow(described_class)
- .to receive(:configuration)
- .and_return('discover' => { 'record' => 'foo', 'record_type' => 'SRV' })
-
- expect(described_class.service_discovery_configuration).to eq(
- nameserver: 'localhost',
- port: 8600,
- record: 'foo',
- record_type: 'SRV',
- interval: 60,
- disconnect_timeout: 120,
- use_tcp: false
- )
+ described_class.configure_proxy
end
end
end
@@ -292,15 +165,23 @@ RSpec.describe Gitlab::Database::LoadBalancing do
end
it 'starts service discovery if enabled' do
- allow(described_class)
+ allow(described_class.configuration)
.to receive(:service_discovery_enabled?)
.and_return(true)
instance = double(:instance)
+ config = Gitlab::Database::LoadBalancing::Configuration
+ .new(ActiveRecord::Base)
+ lb = Gitlab::Database::LoadBalancing::LoadBalancer.new(config)
+ proxy = Gitlab::Database::LoadBalancing::ConnectionProxy.new(lb)
+
+ allow(described_class)
+ .to receive(:proxy)
+ .and_return(proxy)
expect(Gitlab::Database::LoadBalancing::ServiceDiscovery)
.to receive(:new)
- .with(an_instance_of(Hash))
+ .with(lb, an_instance_of(Hash))
.and_return(instance)
expect(instance)
@@ -330,7 +211,13 @@ RSpec.describe Gitlab::Database::LoadBalancing do
context 'when the load balancing is configured' do
let(:db_host) { ActiveRecord::Base.connection_pool.db_config.host }
- let(:proxy) { described_class::ConnectionProxy.new([db_host]) }
+ let(:config) do
+ Gitlab::Database::LoadBalancing::Configuration
+ .new(ActiveRecord::Base, [db_host])
+ end
+
+ let(:load_balancer) { described_class::LoadBalancer.new(config) }
+ let(:proxy) { described_class::ConnectionProxy.new(load_balancer) }
context 'when a proxy connection is used' do
it 'returns :unknown' do
@@ -770,6 +657,16 @@ RSpec.describe Gitlab::Database::LoadBalancing do
it 'redirects queries to the right roles' do
roles = []
+ # If we don't run any queries, the pool may be a NullPool. This can
+ # result in some tests reporting a role as `:unknown`, even though the
+ # tests themselves are correct.
+ #
+ # To prevent this from happening we simply run a simple query to
+ # ensure the proper pool type is put in place. The exact query doesn't
+ # matter, provided it actually runs a query and thus creates a proper
+ # connection pool.
+ model.count
+
subscriber = ActiveSupport::Notifications.subscribe('sql.active_record') do |event|
role = ::Gitlab::Database::LoadBalancing.db_role_for_connection(event.payload[:connection])
roles << role if role.present?
diff --git a/spec/lib/gitlab/database/migration_helpers/loose_foreign_key_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers/loose_foreign_key_helpers_spec.rb
new file mode 100644
index 00000000000..708d1be6e00
--- /dev/null
+++ b/spec/lib/gitlab/database/migration_helpers/loose_foreign_key_helpers_spec.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers do
+ let_it_be(:migration) do
+ ActiveRecord::Migration.new.extend(described_class)
+ end
+
+ let(:model) do
+ Class.new(ApplicationRecord) do
+ self.table_name = 'loose_fk_test_table'
+ end
+ end
+
+ before(:all) do
+ migration.create_table :loose_fk_test_table do |t|
+ t.timestamps
+ end
+ end
+
+ before do
+ 3.times { model.create! }
+ end
+
+ context 'when the record deletion tracker trigger is not installed' do
+ it 'does store record deletions' do
+ model.delete_all
+
+ expect(LooseForeignKeys::DeletedRecord.count).to eq(0)
+ end
+ end
+
+ context 'when the record deletion tracker trigger is installed' do
+ before do
+ migration.track_record_deletions(:loose_fk_test_table)
+ end
+
+ it 'stores the record deletion' do
+ records = model.all
+ record_to_be_deleted = records.last
+
+ record_to_be_deleted.delete
+
+ expect(LooseForeignKeys::DeletedRecord.count).to eq(1)
+ deleted_record = LooseForeignKeys::DeletedRecord.all.first
+
+ expect(deleted_record.deleted_table_primary_key_value).to eq(record_to_be_deleted.id)
+ expect(deleted_record.deleted_table_name).to eq('loose_fk_test_table')
+ end
+
+ it 'stores multiple record deletions' do
+ model.delete_all
+
+ expect(LooseForeignKeys::DeletedRecord.count).to eq(3)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/database/migration_helpers/v2_spec.rb b/spec/lib/gitlab/database/migration_helpers/v2_spec.rb
index f132ecbf13b..854e97ef897 100644
--- a/spec/lib/gitlab/database/migration_helpers/v2_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers/v2_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe Gitlab::Database::MigrationHelpers::V2 do
include Database::TriggerHelpers
+ include Database::TableSchemaHelpers
let(:migration) do
ActiveRecord::Migration.new.extend(described_class)
@@ -11,6 +12,8 @@ RSpec.describe Gitlab::Database::MigrationHelpers::V2 do
before do
allow(migration).to receive(:puts)
+
+ allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false)
end
shared_examples_for 'Setting up to rename a column' do
@@ -218,4 +221,105 @@ RSpec.describe Gitlab::Database::MigrationHelpers::V2 do
let(:added_column) { :original }
end
end
+
+ describe '#create_table' do
+ let(:table_name) { :test_table }
+ let(:column_attributes) do
+ [
+ { name: 'id', sql_type: 'bigint', null: false, default: nil },
+ { name: 'created_at', sql_type: 'timestamp with time zone', null: false, default: nil },
+ { name: 'updated_at', sql_type: 'timestamp with time zone', null: false, default: nil },
+ { name: 'some_id', sql_type: 'integer', null: false, default: nil },
+ { name: 'active', sql_type: 'boolean', null: false, default: 'true' },
+ { name: 'name', sql_type: 'text', null: true, default: nil }
+ ]
+ end
+
+ context 'using a limit: attribute on .text' do
+ it 'creates the table as expected' do
+ migration.create_table table_name do |t|
+ t.timestamps_with_timezone
+ t.integer :some_id, null: false
+ t.boolean :active, null: false, default: true
+ t.text :name, limit: 100
+ end
+
+ expect_table_columns_to_match(column_attributes, table_name)
+ expect_check_constraint(table_name, 'check_cda6f69506', 'char_length(name) <= 100')
+ end
+ end
+ end
+
+ describe '#with_lock_retries' do
+ let(:model) do
+ ActiveRecord::Migration.new.extend(described_class)
+ end
+
+ let(:buffer) { StringIO.new }
+ let(:in_memory_logger) { Gitlab::JsonLogger.new(buffer) }
+ let(:env) { { 'DISABLE_LOCK_RETRIES' => 'true' } }
+
+ it 'sets the migration class name in the logs' do
+ model.with_lock_retries(env: env, logger: in_memory_logger) { }
+
+ buffer.rewind
+ expect(buffer.read).to include("\"class\":\"#{model.class}\"")
+ end
+
+ where(raise_on_exhaustion: [true, false])
+
+ with_them do
+ it 'sets raise_on_exhaustion as requested' do
+ with_lock_retries = double
+ expect(Gitlab::Database::WithLockRetries).to receive(:new).and_return(with_lock_retries)
+ expect(with_lock_retries).to receive(:run).with(raise_on_exhaustion: raise_on_exhaustion)
+
+ model.with_lock_retries(env: env, logger: in_memory_logger, raise_on_exhaustion: raise_on_exhaustion) { }
+ end
+ end
+
+ it 'does not raise on exhaustion by default' do
+ with_lock_retries = double
+ expect(Gitlab::Database::WithLockRetries).to receive(:new).and_return(with_lock_retries)
+ expect(with_lock_retries).to receive(:run).with(raise_on_exhaustion: false)
+
+ model.with_lock_retries(env: env, logger: in_memory_logger) { }
+ end
+
+ it 'defaults to disallowing subtransactions' do
+ with_lock_retries = double
+ expect(Gitlab::Database::WithLockRetries).to receive(:new).with(hash_including(allow_savepoints: false)).and_return(with_lock_retries)
+ expect(with_lock_retries).to receive(:run).with(raise_on_exhaustion: false)
+
+ model.with_lock_retries(env: env, logger: in_memory_logger) { }
+ end
+
+ context 'when in transaction' do
+ before do
+ allow(model).to receive(:transaction_open?).and_return(true)
+ end
+
+ context 'when lock retries are enabled' do
+ before do
+ allow(model).to receive(:enable_lock_retries?).and_return(true)
+ end
+
+ it 'does not use Gitlab::Database::WithLockRetries and executes the provided block directly' do
+ expect(Gitlab::Database::WithLockRetries).not_to receive(:new)
+
+ expect(model.with_lock_retries(env: env, logger: in_memory_logger) { :block_result }).to eq(:block_result)
+ end
+ end
+
+ context 'when lock retries are not enabled' do
+ before do
+ allow(model).to receive(:enable_lock_retries?).and_return(false)
+ end
+
+ it 'raises an error' do
+ expect { model.with_lock_retries(env: env, logger: in_memory_logger) { } }.to raise_error /can not be run inside an already open transaction/
+ end
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb
index 9f9aef77de7..006f8a39f9c 100644
--- a/spec/lib/gitlab/database/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers_spec.rb
@@ -798,13 +798,13 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
# This spec runs without an enclosing transaction (:delete truncation method for db_cleaner)
context 'when the statement_timeout is already disabled', :delete do
before do
- ActiveRecord::Base.connection.execute('SET statement_timeout TO 0')
+ ActiveRecord::Migration.connection.execute('SET statement_timeout TO 0')
end
after do
- # Use ActiveRecord::Base.connection instead of model.execute
+ # Use ActiveRecord::Migration.connection instead of model.execute
# so that this call is not counted below
- ActiveRecord::Base.connection.execute('RESET statement_timeout')
+ ActiveRecord::Migration.connection.execute('RESET statement_timeout')
end
it 'yields control without disabling the timeout or resetting' do
@@ -954,10 +954,11 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
let(:trigger_name) { model.rename_trigger_name(:users, :id, :new) }
let(:user) { create(:user) }
let(:copy_trigger) { double('copy trigger') }
+ let(:connection) { ActiveRecord::Migration.connection }
before do
expect(Gitlab::Database::UnidirectionalCopyTrigger).to receive(:on_table)
- .with(:users).and_return(copy_trigger)
+ .with(:users, connection: connection).and_return(copy_trigger)
end
it 'copies the value to the new column using the type_cast_function', :aggregate_failures do
@@ -1300,11 +1301,13 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
end
describe '#install_rename_triggers' do
+ let(:connection) { ActiveRecord::Migration.connection }
+
it 'installs the triggers' do
copy_trigger = double('copy trigger')
expect(Gitlab::Database::UnidirectionalCopyTrigger).to receive(:on_table)
- .with(:users).and_return(copy_trigger)
+ .with(:users, connection: connection).and_return(copy_trigger)
expect(copy_trigger).to receive(:create).with(:old, :new, trigger_name: 'foo')
@@ -1313,11 +1316,13 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
end
describe '#remove_rename_triggers' do
+ let(:connection) { ActiveRecord::Migration.connection }
+
it 'removes the function and trigger' do
copy_trigger = double('copy trigger')
expect(Gitlab::Database::UnidirectionalCopyTrigger).to receive(:on_table)
- .with('bar').and_return(copy_trigger)
+ .with('bar', connection: connection).and_return(copy_trigger)
expect(copy_trigger).to receive(:drop).with('foo')
@@ -1886,6 +1891,61 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
end
end
+ describe '#restore_conversion_of_integer_to_bigint' do
+ let(:table) { :test_table }
+ let(:column) { :id }
+ let(:tmp_column) { model.convert_to_bigint_column(column) }
+
+ before do
+ model.create_table table, id: false do |t|
+ t.bigint :id, primary_key: true
+ t.bigint :build_id, null: false
+ t.timestamps
+ end
+ end
+
+ context 'when the target table does not exist' do
+ it 'raises an error' do
+ expect { model.restore_conversion_of_integer_to_bigint(:this_table_is_not_real, column) }
+ .to raise_error('Table this_table_is_not_real does not exist')
+ end
+ end
+
+ context 'when the column to migrate does not exist' do
+ it 'raises an error' do
+ expect { model.restore_conversion_of_integer_to_bigint(table, :this_column_is_not_real) }
+ .to raise_error(ArgumentError, "Column this_column_is_not_real does not exist on #{table}")
+ end
+ end
+
+ context 'when a single column is given' do
+ let(:column_to_convert) { 'id' }
+ let(:temporary_column) { model.convert_to_bigint_column(column_to_convert) }
+
+ it 'creates the correct columns and installs the trigger' do
+ expect(model).to receive(:add_column).with(table, temporary_column, :int, default: 0, null: false)
+
+ expect(model).to receive(:install_rename_triggers).with(table, [column_to_convert], [temporary_column])
+
+ model.restore_conversion_of_integer_to_bigint(table, column_to_convert)
+ end
+ end
+
+ context 'when multiple columns are given' do
+ let(:columns_to_convert) { %i[id build_id] }
+ let(:temporary_columns) { columns_to_convert.map { |column| model.convert_to_bigint_column(column) } }
+
+ it 'creates the correct columns and installs the trigger' do
+ expect(model).to receive(:add_column).with(table, temporary_columns[0], :int, default: 0, null: false)
+ expect(model).to receive(:add_column).with(table, temporary_columns[1], :int, default: 0, null: false)
+
+ expect(model).to receive(:install_rename_triggers).with(table, columns_to_convert, temporary_columns)
+
+ model.restore_conversion_of_integer_to_bigint(table, columns_to_convert)
+ end
+ end
+ end
+
describe '#revert_initialize_conversion_of_integer_to_bigint' do
let(:table) { :test_table }
@@ -2139,7 +2199,7 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
describe '#index_exists_by_name?' do
it 'returns true if an index exists' do
- ActiveRecord::Base.connection.execute(
+ ActiveRecord::Migration.connection.execute(
'CREATE INDEX test_index_for_index_exists ON projects (path);'
)
@@ -2154,7 +2214,7 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
context 'when an index with a function exists' do
before do
- ActiveRecord::Base.connection.execute(
+ ActiveRecord::Migration.connection.execute(
'CREATE INDEX test_index ON projects (LOWER(path));'
)
end
@@ -2167,15 +2227,15 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
context 'when an index exists for a table with the same name in another schema' do
before do
- ActiveRecord::Base.connection.execute(
+ ActiveRecord::Migration.connection.execute(
'CREATE SCHEMA new_test_schema'
)
- ActiveRecord::Base.connection.execute(
+ ActiveRecord::Migration.connection.execute(
'CREATE TABLE new_test_schema.projects (id integer, name character varying)'
)
- ActiveRecord::Base.connection.execute(
+ ActiveRecord::Migration.connection.execute(
'CREATE INDEX test_index_on_name ON new_test_schema.projects (LOWER(name));'
)
end
@@ -2255,8 +2315,6 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
expect(buffer.read).to include("\"class\":\"#{model.class}\"")
end
- using RSpec::Parameterized::TableSyntax
-
where(raise_on_exhaustion: [true, false])
with_them do
@@ -2276,6 +2334,15 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
model.with_lock_retries(env: env, logger: in_memory_logger) { }
end
+
+ it 'defaults to allowing subtransactions' do
+ with_lock_retries = double
+
+ expect(Gitlab::Database::WithLockRetries).to receive(:new).with(hash_including(allow_savepoints: true)).and_return(with_lock_retries)
+ expect(with_lock_retries).to receive(:run).with(raise_on_exhaustion: false)
+
+ model.with_lock_retries(env: env, logger: in_memory_logger) { }
+ end
end
describe '#backfill_iids' do
@@ -2401,19 +2468,19 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
describe '#check_constraint_exists?' do
before do
- ActiveRecord::Base.connection.execute(
+ ActiveRecord::Migration.connection.execute(
'ALTER TABLE projects ADD CONSTRAINT check_1 CHECK (char_length(path) <= 5) NOT VALID'
)
- ActiveRecord::Base.connection.execute(
+ ActiveRecord::Migration.connection.execute(
'CREATE SCHEMA new_test_schema'
)
- ActiveRecord::Base.connection.execute(
+ ActiveRecord::Migration.connection.execute(
'CREATE TABLE new_test_schema.projects (id integer, name character varying)'
)
- ActiveRecord::Base.connection.execute(
+ ActiveRecord::Migration.connection.execute(
'ALTER TABLE new_test_schema.projects ADD CONSTRAINT check_2 CHECK (char_length(name) <= 5)'
)
end
@@ -2628,6 +2695,10 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
end
describe '#remove_check_constraint' do
+ before do
+ allow(model).to receive(:transaction_open?).and_return(false)
+ end
+
it 'removes the constraint' do
drop_sql = /ALTER TABLE test_table\s+DROP CONSTRAINT IF EXISTS check_name/
diff --git a/spec/lib/gitlab/database/migration_spec.rb b/spec/lib/gitlab/database/migration_spec.rb
new file mode 100644
index 00000000000..287e738c24e
--- /dev/null
+++ b/spec/lib/gitlab/database/migration_spec.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Database::Migration do
+ describe '.[]' do
+ context 'version: 1.0' do
+ subject { described_class[1.0] }
+
+ it 'inherits from ActiveRecord::Migration[6.1]' do
+ expect(subject.superclass).to eq(ActiveRecord::Migration[6.1])
+ end
+
+ it 'includes migration helpers version 2' do
+ expect(subject.included_modules).to include(Gitlab::Database::MigrationHelpers::V2)
+ end
+
+ it 'includes LockRetriesConcern' do
+ expect(subject.included_modules).to include(Gitlab::Database::Migration::LockRetriesConcern)
+ end
+ end
+
+ context 'unknown version' do
+ it 'raises an error' do
+ expect { described_class[0] }.to raise_error(ArgumentError, /Unknown migration version/)
+ end
+ end
+ end
+
+ describe '.current_version' do
+ it 'includes current ActiveRecord migration class' do
+ # This breaks upon Rails upgrade. In that case, we'll add a new version in Gitlab::Database::Migration::MIGRATION_CLASSES,
+ # bump .current_version and leave existing migrations and already defined versions of Gitlab::Database::Migration
+ # untouched.
+ expect(described_class[described_class.current_version].superclass).to eq(ActiveRecord::Migration::Current)
+ end
+ end
+
+ describe Gitlab::Database::Migration::LockRetriesConcern do
+ subject { class_def.new }
+
+ context 'when not explicitly called' do
+ let(:class_def) do
+ Class.new do
+ include Gitlab::Database::Migration::LockRetriesConcern
+ end
+ end
+
+ it 'does not disable lock retries by default' do
+ expect(subject.enable_lock_retries?).not_to be_truthy
+ end
+ end
+
+ context 'when explicitly disabled' do
+ let(:class_def) do
+ Class.new do
+ include Gitlab::Database::Migration::LockRetriesConcern
+
+ enable_lock_retries!
+ end
+ end
+
+ it 'does not disable lock retries by default' do
+ expect(subject.enable_lock_retries?).to be_truthy
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/database/migrations/lock_retry_mixin_spec.rb b/spec/lib/gitlab/database/migrations/lock_retry_mixin_spec.rb
new file mode 100644
index 00000000000..076fb9e8215
--- /dev/null
+++ b/spec/lib/gitlab/database/migrations/lock_retry_mixin_spec.rb
@@ -0,0 +1,129 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Gitlab::Database::Migrations::LockRetryMixin do
+ describe Gitlab::Database::Migrations::LockRetryMixin::ActiveRecordMigrationProxyLockRetries do
+ let(:migration) { double }
+ let(:return_value) { double }
+ let(:class_def) do
+ Class.new do
+ include Gitlab::Database::Migrations::LockRetryMixin::ActiveRecordMigrationProxyLockRetries
+
+ attr_reader :migration
+
+ def initialize(migration)
+ @migration = migration
+ end
+ end
+ end
+
+ describe '#enable_lock_retries?' do
+ subject { class_def.new(migration).enable_lock_retries? }
+
+ it 'delegates to #migration' do
+ expect(migration).to receive(:enable_lock_retries?).and_return(return_value)
+
+ result = subject
+
+ expect(result).to eq(return_value)
+ end
+ end
+
+ describe '#migration_class' do
+ subject { class_def.new(migration).migration_class }
+
+ it 'retrieves actual migration class from #migration' do
+ expect(migration).to receive(:class).and_return(return_value)
+
+ result = subject
+
+ expect(result).to eq(return_value)
+ end
+ end
+ end
+
+ describe Gitlab::Database::Migrations::LockRetryMixin::ActiveRecordMigratorLockRetries do
+ let(:class_def) do
+ Class.new do
+ attr_reader :receiver
+
+ def initialize(receiver)
+ @receiver = receiver
+ end
+
+ def ddl_transaction(migration, &block)
+ receiver.ddl_transaction(migration, &block)
+ end
+
+ def use_transaction?(migration)
+ receiver.use_transaction?(migration)
+ end
+ end.prepend(Gitlab::Database::Migrations::LockRetryMixin::ActiveRecordMigratorLockRetries)
+ end
+
+ subject { class_def.new(receiver) }
+
+ before do
+ allow(migration).to receive(:migration_class).and_return('TestClass')
+ allow(receiver).to receive(:ddl_transaction)
+ end
+
+ context 'with transactions disabled' do
+ let(:migration) { double('migration', enable_lock_retries?: false) }
+ let(:receiver) { double('receiver', use_transaction?: false)}
+
+ it 'calls super method' do
+ p = proc { }
+
+ expect(receiver).to receive(:ddl_transaction).with(migration, &p)
+
+ subject.ddl_transaction(migration, &p)
+ end
+ end
+
+ context 'with transactions enabled, but lock retries disabled' do
+ let(:receiver) { double('receiver', use_transaction?: true)}
+ let(:migration) { double('migration', enable_lock_retries?: false) }
+
+ it 'calls super method' do
+ p = proc { }
+
+ expect(receiver).to receive(:ddl_transaction).with(migration, &p)
+
+ subject.ddl_transaction(migration, &p)
+ end
+ end
+
+ context 'with transactions enabled and lock retries enabled' do
+ let(:receiver) { double('receiver', use_transaction?: true)}
+ let(:migration) { double('migration', enable_lock_retries?: true) }
+
+ it 'calls super method' do
+ p = proc { }
+
+ expect(receiver).not_to receive(:ddl_transaction)
+ expect_next_instance_of(Gitlab::Database::WithLockRetries) do |retries|
+ expect(retries).to receive(:run).with(raise_on_exhaustion: false, &p)
+ end
+
+ subject.ddl_transaction(migration, &p)
+ end
+ end
+ end
+
+ describe '.patch!' do
+ subject { described_class.patch! }
+
+ it 'patches MigrationProxy' do
+ expect(ActiveRecord::MigrationProxy).to receive(:prepend).with(Gitlab::Database::Migrations::LockRetryMixin::ActiveRecordMigrationProxyLockRetries)
+
+ subject
+ end
+
+ it 'patches Migrator' do
+ expect(ActiveRecord::Migrator).to receive(:prepend).with(Gitlab::Database::Migrations::LockRetryMixin::ActiveRecordMigratorLockRetries)
+
+ subject
+ end
+ end
+end
diff --git a/spec/lib/gitlab/database/partitioning/monthly_strategy_spec.rb b/spec/lib/gitlab/database/partitioning/monthly_strategy_spec.rb
index c4fbf53d1c2..27ada12b067 100644
--- a/spec/lib/gitlab/database/partitioning/monthly_strategy_spec.rb
+++ b/spec/lib/gitlab/database/partitioning/monthly_strategy_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe Gitlab::Database::Partitioning::MonthlyStrategy do
+ let(:connection) { ActiveRecord::Base.connection }
+
describe '#current_partitions' do
subject { described_class.new(model, partitioning_key).current_partitions }
@@ -11,7 +13,7 @@ RSpec.describe Gitlab::Database::Partitioning::MonthlyStrategy do
let(:table_name) { :partitioned_test }
before do
- ActiveRecord::Base.connection.execute(<<~SQL)
+ connection.execute(<<~SQL)
CREATE TABLE #{table_name}
(id serial not null, created_at timestamptz not null, PRIMARY KEY (id, created_at))
PARTITION BY RANGE (created_at);
@@ -52,7 +54,7 @@ RSpec.describe Gitlab::Database::Partitioning::MonthlyStrategy do
context 'with existing partitions' do
before do
- ActiveRecord::Base.connection.execute(<<~SQL)
+ connection.execute(<<~SQL)
CREATE TABLE #{model.table_name}
(id serial not null, created_at timestamptz not null, PRIMARY KEY (id, created_at))
PARTITION BY RANGE (created_at);
@@ -113,7 +115,7 @@ RSpec.describe Gitlab::Database::Partitioning::MonthlyStrategy do
context 'without existing partitions' do
before do
- ActiveRecord::Base.connection.execute(<<~SQL)
+ connection.execute(<<~SQL)
CREATE TABLE #{model.table_name}
(id serial not null, created_at timestamptz not null, PRIMARY KEY (id, created_at))
PARTITION BY RANGE (created_at);
@@ -159,7 +161,7 @@ RSpec.describe Gitlab::Database::Partitioning::MonthlyStrategy do
context 'with a regular partition but no catchall (MINVALUE, to) partition' do
before do
- ActiveRecord::Base.connection.execute(<<~SQL)
+ connection.execute(<<~SQL)
CREATE TABLE #{model.table_name}
(id serial not null, created_at timestamptz not null, PRIMARY KEY (id, created_at))
PARTITION BY RANGE (created_at);
@@ -248,6 +250,25 @@ RSpec.describe Gitlab::Database::Partitioning::MonthlyStrategy do
Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-05-01', '2020-06-01', partition_name: 'partitioned_test_202005')
)
end
+
+ context 'when the retain_non_empty_partitions is true' do
+ subject { described_class.new(model, partitioning_key, retain_for: 2.months, retain_non_empty_partitions: true).extra_partitions }
+
+ it 'prunes empty partitions' do
+ expect(subject).to contain_exactly(
+ Gitlab::Database::Partitioning::TimePartition.new(model.table_name, nil, '2020-05-01', partition_name: 'partitioned_test_000000'),
+ Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-05-01', '2020-06-01', partition_name: 'partitioned_test_202005')
+ )
+ end
+
+ it 'does not prune non-empty partitions' do
+ connection.execute("INSERT INTO #{table_name} (created_at) VALUES (('2020-05-15'))") # inserting one record into partitioned_test_202005
+
+ expect(subject).to contain_exactly(
+ Gitlab::Database::Partitioning::TimePartition.new(model.table_name, nil, '2020-05-01', partition_name: 'partitioned_test_000000')
+ )
+ end
+ end
end
end
end
diff --git a/spec/lib/gitlab/database/partitioning/multi_database_partition_manager_spec.rb b/spec/lib/gitlab/database/partitioning/multi_database_partition_manager_spec.rb
new file mode 100644
index 00000000000..3c94c1bf4ea
--- /dev/null
+++ b/spec/lib/gitlab/database/partitioning/multi_database_partition_manager_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Database::Partitioning::MultiDatabasePartitionManager, '#sync_partitions' do
+ subject(:sync_partitions) { manager.sync_partitions }
+
+ let(:manager) { described_class.new(models) }
+ let(:models) { [model1, model2] }
+
+ let(:model1) { double('model1', connection: connection1, table_name: 'table1') }
+ let(:model2) { double('model2', connection: connection1, table_name: 'table2') }
+
+ let(:connection1) { double('connection1') }
+ let(:connection2) { double('connection2') }
+
+ let(:target_manager_class) { Gitlab::Database::Partitioning::PartitionManager }
+ let(:target_manager1) { double('partition manager') }
+ let(:target_manager2) { double('partition manager') }
+
+ before do
+ allow(manager).to receive(:connection_name).and_return('name')
+ end
+
+ it 'syncs model partitions, setting up the appropriate connection for each', :aggregate_failures do
+ expect(Gitlab::Database::SharedModel).to receive(:using_connection).with(model1.connection).and_yield.ordered
+ expect(target_manager_class).to receive(:new).with(model1).and_return(target_manager1).ordered
+ expect(target_manager1).to receive(:sync_partitions)
+
+ expect(Gitlab::Database::SharedModel).to receive(:using_connection).with(model2.connection).and_yield.ordered
+ expect(target_manager_class).to receive(:new).with(model2).and_return(target_manager2).ordered
+ expect(target_manager2).to receive(:sync_partitions)
+
+ sync_partitions
+ end
+end
diff --git a/spec/lib/gitlab/database/partitioning/partition_manager_spec.rb b/spec/lib/gitlab/database/partitioning/partition_manager_spec.rb
index 3d60457c3a9..8f1f5b5ba1b 100644
--- a/spec/lib/gitlab/database/partitioning/partition_manager_spec.rb
+++ b/spec/lib/gitlab/database/partitioning/partition_manager_spec.rb
@@ -12,26 +12,18 @@ RSpec.describe Gitlab::Database::Partitioning::PartitionManager do
end
end
- describe '.register' do
- let(:model) { double(partitioning_strategy: nil) }
-
- it 'remembers registered models' do
- expect { described_class.register(model) }.to change { described_class.models }.to include(model)
- end
- end
-
context 'creating partitions (mocked)' do
- subject(:sync_partitions) { described_class.new(models).sync_partitions }
+ subject(:sync_partitions) { described_class.new(model).sync_partitions }
- let(:models) { [model] }
- let(:model) { double(partitioning_strategy: partitioning_strategy, table_name: table) }
+ let(:model) { double(partitioning_strategy: partitioning_strategy, table_name: table, connection: connection) }
let(:partitioning_strategy) { double(missing_partitions: partitions, extra_partitions: []) }
+ let(:connection) { ActiveRecord::Base.connection }
let(:table) { "some_table" }
before do
- allow(ActiveRecord::Base.connection).to receive(:table_exists?).and_call_original
- allow(ActiveRecord::Base.connection).to receive(:table_exists?).with(table).and_return(true)
- allow(ActiveRecord::Base.connection).to receive(:execute).and_call_original
+ allow(connection).to receive(:table_exists?).and_call_original
+ allow(connection).to receive(:table_exists?).with(table).and_return(true)
+ allow(connection).to receive(:execute).and_call_original
stub_exclusive_lease(described_class::MANAGEMENT_LEASE_KEY % table, timeout: described_class::LEASE_TIMEOUT)
end
@@ -44,35 +36,23 @@ RSpec.describe Gitlab::Database::Partitioning::PartitionManager do
end
it 'creates the partition' do
- expect(ActiveRecord::Base.connection).to receive(:execute).with(partitions.first.to_sql)
- expect(ActiveRecord::Base.connection).to receive(:execute).with(partitions.second.to_sql)
+ expect(connection).to receive(:execute).with(partitions.first.to_sql)
+ expect(connection).to receive(:execute).with(partitions.second.to_sql)
sync_partitions
end
- context 'error handling with 2 models' do
- let(:models) do
- [
- double(partitioning_strategy: strategy1, table_name: table),
- double(partitioning_strategy: strategy2, table_name: table)
- ]
- end
-
- let(:strategy1) { double('strategy1', missing_partitions: nil, extra_partitions: []) }
- let(:strategy2) { double('strategy2', missing_partitions: partitions, extra_partitions: []) }
+ context 'when an error occurs during partition management' do
+ it 'does not raise an error' do
+ expect(partitioning_strategy).to receive(:missing_partitions).and_raise('this should never happen (tm)')
- it 'still creates partitions for the second table' do
- expect(strategy1).to receive(:missing_partitions).and_raise('this should never happen (tm)')
- expect(ActiveRecord::Base.connection).to receive(:execute).with(partitions.first.to_sql)
- expect(ActiveRecord::Base.connection).to receive(:execute).with(partitions.second.to_sql)
-
- sync_partitions
+ expect { sync_partitions }.not_to raise_error
end
end
end
context 'creating partitions' do
- subject(:sync_partitions) { described_class.new([my_model]).sync_partitions }
+ subject(:sync_partitions) { described_class.new(my_model).sync_partitions }
let(:connection) { ActiveRecord::Base.connection }
let(:my_model) do
@@ -101,15 +81,15 @@ RSpec.describe Gitlab::Database::Partitioning::PartitionManager do
context 'detaching partitions (mocked)' do
subject(:sync_partitions) { manager.sync_partitions }
- let(:manager) { described_class.new(models) }
- let(:models) { [model] }
- let(:model) { double(partitioning_strategy: partitioning_strategy, table_name: table)}
+ let(:manager) { described_class.new(model) }
+ let(:model) { double(partitioning_strategy: partitioning_strategy, table_name: table, connection: connection) }
let(:partitioning_strategy) { double(extra_partitions: extra_partitions, missing_partitions: []) }
+ let(:connection) { ActiveRecord::Base.connection }
let(:table) { "foo" }
before do
- allow(ActiveRecord::Base.connection).to receive(:table_exists?).and_call_original
- allow(ActiveRecord::Base.connection).to receive(:table_exists?).with(table).and_return(true)
+ allow(connection).to receive(:table_exists?).and_call_original
+ allow(connection).to receive(:table_exists?).with(table).and_return(true)
stub_exclusive_lease(described_class::MANAGEMENT_LEASE_KEY % table, timeout: described_class::LEASE_TIMEOUT)
end
@@ -131,24 +111,6 @@ RSpec.describe Gitlab::Database::Partitioning::PartitionManager do
sync_partitions
end
-
- context 'error handling' do
- let(:models) do
- [
- double(partitioning_strategy: error_strategy, table_name: table),
- model
- ]
- end
-
- let(:error_strategy) { double(extra_partitions: nil, missing_partitions: []) }
-
- it 'still drops partitions for the other model' do
- expect(error_strategy).to receive(:extra_partitions).and_raise('injected error!')
- extra_partitions.each { |p| expect(manager).to receive(:detach_one_partition).with(p) }
-
- sync_partitions
- end
- end
end
context 'with the partition_pruning feature flag disabled' do
@@ -171,7 +133,7 @@ RSpec.describe Gitlab::Database::Partitioning::PartitionManager do
end
end
- subject { described_class.new([my_model]).sync_partitions }
+ subject { described_class.new(my_model).sync_partitions }
let(:connection) { ActiveRecord::Base.connection }
let(:my_model) do
@@ -280,11 +242,11 @@ RSpec.describe Gitlab::Database::Partitioning::PartitionManager do
it 'creates partitions for the future then drops the oldest one after a month' do
# 1 month for the current month, 1 month for the old month that we're retaining data for, headroom
expected_num_partitions = (Gitlab::Database::Partitioning::MonthlyStrategy::HEADROOM + 2.months) / 1.month
- expect { described_class.new([my_model]).sync_partitions }.to change { num_partitions(my_model) }.from(0).to(expected_num_partitions)
+ expect { described_class.new(my_model).sync_partitions }.to change { num_partitions(my_model) }.from(0).to(expected_num_partitions)
travel 1.month
- expect { described_class.new([my_model]).sync_partitions }.to change { has_partition(my_model, 2.months.ago.beginning_of_month) }.from(true).to(false).and(change { num_partitions(my_model) }.by(0))
+ expect { described_class.new(my_model).sync_partitions }.to change { has_partition(my_model, 2.months.ago.beginning_of_month) }.from(true).to(false).and(change { num_partitions(my_model) }.by(0))
end
end
end
diff --git a/spec/lib/gitlab/database/partitioning_migration_helpers/foreign_key_helpers_spec.rb b/spec/lib/gitlab/database/partitioning_migration_helpers/foreign_key_helpers_spec.rb
index a524fe681e9..f0e34476cf2 100644
--- a/spec/lib/gitlab/database/partitioning_migration_helpers/foreign_key_helpers_spec.rb
+++ b/spec/lib/gitlab/database/partitioning_migration_helpers/foreign_key_helpers_spec.rb
@@ -27,6 +27,7 @@ RSpec.describe Gitlab::Database::PartitioningMigrationHelpers::ForeignKeyHelpers
before do
allow(migration).to receive(:puts)
+ allow(migration).to receive(:transaction_open?).and_return(false)
connection.execute(<<~SQL)
CREATE TABLE #{target_table_name} (
@@ -141,5 +142,15 @@ RSpec.describe Gitlab::Database::PartitioningMigrationHelpers::ForeignKeyHelpers
.with(source_table_name, target_table_name, options)
end
end
+
+ context 'when run inside a transaction block' do
+ it 'raises an error' do
+ expect(migration).to receive(:transaction_open?).and_return(true)
+
+ expect do
+ migration.add_concurrent_partitioned_foreign_key(source_table_name, target_table_name, column: column_name)
+ end.to raise_error(/can not be run inside a transaction/)
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/database/partitioning_migration_helpers/index_helpers_spec.rb b/spec/lib/gitlab/database/partitioning_migration_helpers/index_helpers_spec.rb
index c3edc3a0c87..8ab3816529b 100644
--- a/spec/lib/gitlab/database/partitioning_migration_helpers/index_helpers_spec.rb
+++ b/spec/lib/gitlab/database/partitioning_migration_helpers/index_helpers_spec.rb
@@ -20,6 +20,7 @@ RSpec.describe Gitlab::Database::PartitioningMigrationHelpers::IndexHelpers do
before do
allow(migration).to receive(:puts)
+ allow(migration).to receive(:transaction_open?).and_return(false)
connection.execute(<<~SQL)
CREATE TABLE #{table_name} (
@@ -127,6 +128,16 @@ RSpec.describe Gitlab::Database::PartitioningMigrationHelpers::IndexHelpers do
end.to raise_error(ArgumentError, /#{table_name} is not a partitioned table/)
end
end
+
+ context 'when run inside a transaction block' do
+ it 'raises an error' do
+ expect(migration).to receive(:transaction_open?).and_return(true)
+
+ expect do
+ migration.add_concurrent_partitioned_index(table_name, column_name)
+ end.to raise_error(/can not be run inside a transaction/)
+ end
+ end
end
describe '#remove_concurrent_partitioned_index_by_name' do
@@ -182,5 +193,15 @@ RSpec.describe Gitlab::Database::PartitioningMigrationHelpers::IndexHelpers do
end.to raise_error(ArgumentError, /#{table_name} is not a partitioned table/)
end
end
+
+ context 'when run inside a transaction block' do
+ it 'raises an error' do
+ expect(migration).to receive(:transaction_open?).and_return(true)
+
+ expect do
+ migration.remove_concurrent_partitioned_index_by_name(table_name, index_name)
+ end.to raise_error(/can not be run inside a transaction/)
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/database/partitioning_spec.rb b/spec/lib/gitlab/database/partitioning_spec.rb
new file mode 100644
index 00000000000..f163b45e01e
--- /dev/null
+++ b/spec/lib/gitlab/database/partitioning_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Database::Partitioning do
+ describe '.sync_partitions' do
+ let(:partition_manager_class) { described_class::MultiDatabasePartitionManager }
+ let(:partition_manager) { double('partition manager') }
+
+ context 'when no partitioned models are given' do
+ it 'calls the partition manager with the registered models' do
+ expect(partition_manager_class).to receive(:new)
+ .with(described_class.registered_models)
+ .and_return(partition_manager)
+
+ expect(partition_manager).to receive(:sync_partitions)
+
+ described_class.sync_partitions
+ end
+ end
+
+ context 'when partitioned models are given' do
+ it 'calls the partition manager with the given models' do
+ models = ['my special model']
+
+ expect(partition_manager_class).to receive(:new)
+ .with(models)
+ .and_return(partition_manager)
+
+ expect(partition_manager).to receive(:sync_partitions)
+
+ described_class.sync_partitions(models)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/database/postgresql_adapter/dump_schema_versions_mixin_spec.rb b/spec/lib/gitlab/database/postgresql_adapter/dump_schema_versions_mixin_spec.rb
index 40e36bc02e9..8b06f068503 100644
--- a/spec/lib/gitlab/database/postgresql_adapter/dump_schema_versions_mixin_spec.rb
+++ b/spec/lib/gitlab/database/postgresql_adapter/dump_schema_versions_mixin_spec.rb
@@ -26,4 +26,12 @@ RSpec.describe Gitlab::Database::PostgresqlAdapter::DumpSchemaVersionsMixin do
instance.dump_schema_information
end
+
+ it 'does not call touch_all in production' do
+ allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new('production'))
+
+ expect(Gitlab::Database::SchemaMigrations).not_to receive(:touch_all)
+
+ instance.dump_schema_information
+ end
end
diff --git a/spec/lib/gitlab/database/schema_migrations/context_spec.rb b/spec/lib/gitlab/database/schema_migrations/context_spec.rb
index 1f1943d00a3..a79e6706149 100644
--- a/spec/lib/gitlab/database/schema_migrations/context_spec.rb
+++ b/spec/lib/gitlab/database/schema_migrations/context_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe Gitlab::Database::SchemaMigrations::Context do
describe '#schema_directory' do
it 'returns db/schema_migrations' do
- expect(context.schema_directory).to eq(File.join(Rails.root, 'db/schema_migrations'))
+ expect(context.schema_directory).to eq(File.join(Rails.root, described_class.default_schema_migrations_path))
end
context 'CI database' do
@@ -19,7 +19,7 @@ RSpec.describe Gitlab::Database::SchemaMigrations::Context do
it 'returns a directory path that is database specific' do
skip_if_multiple_databases_not_setup
- expect(context.schema_directory).to eq(File.join(Rails.root, 'db/schema_migrations'))
+ expect(context.schema_directory).to eq(File.join(Rails.root, described_class.default_schema_migrations_path))
end
end
@@ -124,8 +124,4 @@ RSpec.describe Gitlab::Database::SchemaMigrations::Context do
end
end
end
-
- def skip_if_multiple_databases_not_setup
- skip 'Skipping because multiple databases not set up' unless Gitlab::Database.has_config?(:ci)
- end
end
diff --git a/spec/lib/gitlab/database/shared_model_spec.rb b/spec/lib/gitlab/database/shared_model_spec.rb
new file mode 100644
index 00000000000..5d616aeb05f
--- /dev/null
+++ b/spec/lib/gitlab/database/shared_model_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Database::SharedModel do
+ describe 'using an external connection' do
+ let!(:original_connection) { described_class.connection }
+ let(:new_connection) { double('connection') }
+
+ it 'overrides the connection for the duration of the block', :aggregate_failures do
+ expect_original_connection_around do
+ described_class.using_connection(new_connection) do
+ expect(described_class.connection).to be(new_connection)
+ end
+ end
+ end
+
+ it 'does not affect connections in other threads', :aggregate_failures do
+ expect_original_connection_around do
+ described_class.using_connection(new_connection) do
+ expect(described_class.connection).to be(new_connection)
+
+ Thread.new do
+ expect(described_class.connection).not_to be(new_connection)
+ end.join
+ end
+ end
+ end
+
+ context 'when the block raises an error', :aggregate_failures do
+ it 're-raises the error, removing the overridden connection' do
+ expect_original_connection_around do
+ expect do
+ described_class.using_connection(new_connection) do
+ expect(described_class.connection).to be(new_connection)
+
+ raise 'here comes an error!'
+ end
+ end.to raise_error(RuntimeError, 'here comes an error!')
+ end
+ end
+ end
+
+ def expect_original_connection_around
+ # For safety, ensure our original connection is distinct from our double
+ # This should be the case, but in case of something leaking we should verify
+ expect(original_connection).not_to be(new_connection)
+ expect(described_class.connection).to be(original_connection)
+
+ yield
+
+ expect(described_class.connection).to be(original_connection)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/database/transaction/context_spec.rb b/spec/lib/gitlab/database/transaction/context_spec.rb
index 65d52b4d099..37cfc841d48 100644
--- a/spec/lib/gitlab/database/transaction/context_spec.rb
+++ b/spec/lib/gitlab/database/transaction/context_spec.rb
@@ -62,30 +62,32 @@ RSpec.describe Gitlab::Database::Transaction::Context do
it { expect(data[:queries]).to eq(['SELECT 1', 'SELECT * FROM users']) }
end
- describe '#duration' do
+ describe '#track_backtrace' do
before do
- subject.set_start_time
+ subject.track_backtrace(caller)
end
- it { expect(subject.duration).to be >= 0 }
- end
+ it { expect(data[:backtraces]).to be_a(Array) }
+ it { expect(data[:backtraces]).to all(be_a(Array)) }
+ it { expect(data[:backtraces].length).to eq(1) }
+ it { expect(data[:backtraces][0][0]).to be_a(String) }
- context 'when depth is low' do
- it 'does not log data upon COMMIT' do
- expect(subject).not_to receive(:application_info)
+ it 'appends the backtrace' do
+ subject.track_backtrace(caller)
- subject.commit
+ expect(data[:backtraces].length).to eq(2)
+ expect(subject.backtraces).to be_a(Array)
+ expect(subject.backtraces).to all(be_a(Array))
+ expect(subject.backtraces[1][0]).to be_a(String)
end
+ end
- it 'does not log data upon ROLLBACK' do
- expect(subject).not_to receive(:application_info)
-
- subject.rollback
+ describe '#duration' do
+ before do
+ subject.set_start_time
end
- it '#should_log? returns false' do
- expect(subject.should_log?).to be false
- end
+ it { expect(subject.duration).to be >= 0 }
end
shared_examples 'logs transaction data' do
@@ -116,17 +118,9 @@ RSpec.describe Gitlab::Database::Transaction::Context do
end
end
- context 'when depth exceeds threshold' do
- before do
- subject.set_depth(described_class::LOG_DEPTH_THRESHOLD + 1)
- end
-
- it_behaves_like 'logs transaction data'
- end
-
context 'when savepoints count exceeds threshold' do
before do
- data[:savepoints] = described_class::LOG_SAVEPOINTS_THRESHOLD + 1
+ data[:savepoints] = 1
end
it_behaves_like 'logs transaction data'
diff --git a/spec/lib/gitlab/database/transaction/observer_spec.rb b/spec/lib/gitlab/database/transaction/observer_spec.rb
index 7aa24217dc3..e5cc0106c9b 100644
--- a/spec/lib/gitlab/database/transaction/observer_spec.rb
+++ b/spec/lib/gitlab/database/transaction/observer_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe Gitlab::Database::Transaction::Observer do
User.first
expect(transaction_context).to be_a(::Gitlab::Database::Transaction::Context)
- expect(context.keys).to match_array(%i(start_time depth savepoints queries))
+ expect(context.keys).to match_array(%i(start_time depth savepoints queries backtraces))
expect(context[:depth]).to eq(2)
expect(context[:savepoints]).to eq(1)
expect(context[:queries].length).to eq(1)
@@ -35,6 +35,7 @@ RSpec.describe Gitlab::Database::Transaction::Observer do
expect(context[:depth]).to eq(2)
expect(context[:savepoints]).to eq(1)
expect(context[:releases]).to eq(1)
+ expect(context[:backtraces].length).to eq(1)
end
describe '.extract_sql_command' do
diff --git a/spec/lib/gitlab/database/with_lock_retries_spec.rb b/spec/lib/gitlab/database/with_lock_retries_spec.rb
index 72074f06210..0b960830d89 100644
--- a/spec/lib/gitlab/database/with_lock_retries_spec.rb
+++ b/spec/lib/gitlab/database/with_lock_retries_spec.rb
@@ -5,7 +5,9 @@ require 'spec_helper'
RSpec.describe Gitlab::Database::WithLockRetries do
let(:env) { {} }
let(:logger) { Gitlab::Database::WithLockRetries::NULL_LOGGER }
- let(:subject) { described_class.new(env: env, logger: logger, timing_configuration: timing_configuration) }
+ let(:subject) { described_class.new(env: env, logger: logger, allow_savepoints: allow_savepoints, timing_configuration: timing_configuration) }
+ let(:allow_savepoints) { true }
+ let(:connection) { ActiveRecord::Base.connection }
let(:timing_configuration) do
[
@@ -66,7 +68,7 @@ RSpec.describe Gitlab::Database::WithLockRetries do
WHERE t.relkind = 'r' AND l.mode = 'ExclusiveLock' AND t.relname = '#{Project.table_name}'
"""
- expect(ActiveRecord::Base.connection.execute(check_exclusive_lock_query).to_a).to be_present
+ expect(connection.execute(check_exclusive_lock_query).to_a).to be_present
end
end
@@ -95,8 +97,8 @@ RSpec.describe Gitlab::Database::WithLockRetries do
lock_fiber.resume
end
- ActiveRecord::Base.transaction do
- ActiveRecord::Base.connection.execute("LOCK TABLE #{Project.table_name} in exclusive mode")
+ connection.transaction do
+ connection.execute("LOCK TABLE #{Project.table_name} in exclusive mode")
lock_acquired = true
end
end
@@ -114,7 +116,7 @@ RSpec.describe Gitlab::Database::WithLockRetries do
context 'setting the idle transaction timeout' do
context 'when there is no outer transaction: disable_ddl_transaction! is set in the migration' do
it 'does not disable the idle transaction timeout' do
- allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false)
+ allow(connection).to receive(:transaction_open?).and_return(false)
allow(subject).to receive(:run_block_with_lock_timeout).once.and_raise(ActiveRecord::LockWaitTimeout)
allow(subject).to receive(:run_block_with_lock_timeout).once
@@ -126,7 +128,7 @@ RSpec.describe Gitlab::Database::WithLockRetries do
context 'when there is outer transaction: disable_ddl_transaction! is not set in the migration' do
it 'disables the idle transaction timeout so the code can sleep and retry' do
- allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(true)
+ allow(connection).to receive(:transaction_open?).and_return(true)
n = 0
allow(subject).to receive(:run_block_with_lock_timeout).twice do
@@ -151,7 +153,7 @@ RSpec.describe Gitlab::Database::WithLockRetries do
context 'when there is no outer transaction: disable_ddl_transaction! is set in the migration' do
it 'does not disable the lock_timeout' do
- allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false)
+ allow(connection).to receive(:transaction_open?).and_return(false)
allow(subject).to receive(:run_block_with_lock_timeout).once.and_raise(ActiveRecord::LockWaitTimeout)
expect(subject).not_to receive(:disable_lock_timeout)
@@ -162,7 +164,7 @@ RSpec.describe Gitlab::Database::WithLockRetries do
context 'when there is outer transaction: disable_ddl_transaction! is not set in the migration' do
it 'disables the lock_timeout' do
- allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(true)
+ allow(connection).to receive(:transaction_open?).and_return(true)
allow(subject).to receive(:run_block_with_lock_timeout).once.and_raise(ActiveRecord::LockWaitTimeout)
expect(subject).to receive(:disable_lock_timeout)
@@ -197,8 +199,8 @@ RSpec.describe Gitlab::Database::WithLockRetries do
subject.run(raise_on_exhaustion: true) do
lock_attempts += 1
- ActiveRecord::Base.transaction do
- ActiveRecord::Base.connection.execute("LOCK TABLE #{Project.table_name} in exclusive mode")
+ connection.transaction do
+ connection.execute("LOCK TABLE #{Project.table_name} in exclusive mode")
lock_acquired = true
end
end
@@ -212,11 +214,11 @@ RSpec.describe Gitlab::Database::WithLockRetries do
context 'when statement timeout is reached' do
it 'raises QueryCanceled error' do
lock_acquired = false
- ActiveRecord::Base.connection.execute("SET LOCAL statement_timeout='100ms'")
+ connection.execute("SET LOCAL statement_timeout='100ms'")
expect do
subject.run do
- ActiveRecord::Base.connection.execute("SELECT 1 FROM pg_sleep(0.11)") # 110ms
+ connection.execute("SELECT 1 FROM pg_sleep(0.11)") # 110ms
lock_acquired = true
end
end.to raise_error(ActiveRecord::QueryCanceled)
@@ -229,11 +231,11 @@ RSpec.describe Gitlab::Database::WithLockRetries do
context 'restore local database variables' do
it do
- expect { subject.run {} }.not_to change { ActiveRecord::Base.connection.execute("SHOW lock_timeout").to_a }
+ expect { subject.run {} }.not_to change { connection.execute("SHOW lock_timeout").to_a }
end
it do
- expect { subject.run {} }.not_to change { ActiveRecord::Base.connection.execute("SHOW idle_in_transaction_session_timeout").to_a }
+ expect { subject.run {} }.not_to change { connection.execute("SHOW idle_in_transaction_session_timeout").to_a }
end
end
@@ -241,10 +243,10 @@ RSpec.describe Gitlab::Database::WithLockRetries do
let(:timing_configuration) { [[0.015.seconds, 0.025.seconds], [0.015.seconds, 0.025.seconds]] } # 15ms, 25ms
it 'executes `SET LOCAL lock_timeout` using the configured timeout value in milliseconds' do
- expect(ActiveRecord::Base.connection).to receive(:execute).with("RESET idle_in_transaction_session_timeout; RESET lock_timeout").and_call_original
- expect(ActiveRecord::Base.connection).to receive(:execute).with("SAVEPOINT active_record_1", "TRANSACTION").and_call_original
- expect(ActiveRecord::Base.connection).to receive(:execute).with("SET LOCAL lock_timeout TO '15ms'").and_call_original
- expect(ActiveRecord::Base.connection).to receive(:execute).with("RELEASE SAVEPOINT active_record_1", "TRANSACTION").and_call_original
+ expect(connection).to receive(:execute).with("RESET idle_in_transaction_session_timeout; RESET lock_timeout").and_call_original
+ expect(connection).to receive(:execute).with("SAVEPOINT active_record_1", "TRANSACTION").and_call_original
+ expect(connection).to receive(:execute).with("SET LOCAL lock_timeout TO '15ms'").and_call_original
+ expect(connection).to receive(:execute).with("RELEASE SAVEPOINT active_record_1", "TRANSACTION").and_call_original
subject.run { }
end
@@ -256,4 +258,20 @@ RSpec.describe Gitlab::Database::WithLockRetries do
subject.run { }
end
end
+
+ context 'Stop using subtransactions - allow_savepoints: false' do
+ let(:allow_savepoints) { false }
+
+ it 'prevents running inside already open transaction' do
+ allow(connection).to receive(:transaction_open?).and_return(true)
+
+ expect { subject.run { } }.to raise_error(/should not run inside already open transaction/)
+ end
+
+ it 'does not raise the error if not inside open transaction' do
+ allow(connection).to receive(:transaction_open?).and_return(false)
+
+ expect { subject.run { } }.not_to raise_error
+ end
+ end
end
diff --git a/spec/lib/gitlab/database_importers/work_items/base_type_importer_spec.rb b/spec/lib/gitlab/database_importers/work_items/base_type_importer_spec.rb
new file mode 100644
index 00000000000..8c3d372cc55
--- /dev/null
+++ b/spec/lib/gitlab/database_importers/work_items/base_type_importer_spec.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::DatabaseImporters::WorkItems::BaseTypeImporter do
+ subject { described_class.import }
+
+ it_behaves_like 'work item base types importer'
+end
diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb
index c67b5af5e3c..a9a8d5e6314 100644
--- a/spec/lib/gitlab/database_spec.rb
+++ b/spec/lib/gitlab/database_spec.rb
@@ -15,6 +15,22 @@ RSpec.describe Gitlab::Database do
end
end
+ describe '.default_pool_size' do
+ before do
+ allow(Gitlab::Runtime).to receive(:max_threads).and_return(7)
+ end
+
+ it 'returns the max thread size plus a fixed headroom of 10' do
+ expect(described_class.default_pool_size).to eq(17)
+ end
+
+ it 'returns the max thread size plus a DB_POOL_HEADROOM if this env var is present' do
+ stub_env('DB_POOL_HEADROOM', '7')
+
+ expect(described_class.default_pool_size).to eq(14)
+ end
+ end
+
describe '.has_config?' do
context 'two tier database config' do
before do
@@ -139,23 +155,43 @@ RSpec.describe Gitlab::Database do
it { expect(described_class.nulls_first_order('column', 'DESC')).to eq 'column DESC NULLS FIRST'}
end
- describe '.db_config_name' do
- it 'returns the db_config name for the connection' do
- connection = ActiveRecord::Base.connection
+ describe '.db_config_for_connection' do
+ context 'when the regular connection is used' do
+ it 'returns db_config' do
+ connection = ActiveRecord::Base.retrieve_connection
- expect(described_class.db_config_name(connection)).to be_a(String)
- expect(described_class.db_config_name(connection)).to eq(connection.pool.db_config.name)
+ expect(described_class.db_config_for_connection(connection)).to eq(connection.pool.db_config)
+ end
+ end
+
+ context 'when the connection is LoadBalancing::ConnectionProxy' do
+ it 'returns nil' do
+ lb_config = ::Gitlab::Database::LoadBalancing::Configuration.new(ActiveRecord::Base)
+ lb = ::Gitlab::Database::LoadBalancing::LoadBalancer.new(lb_config)
+ proxy = ::Gitlab::Database::LoadBalancing::ConnectionProxy.new(lb)
+
+ expect(described_class.db_config_for_connection(proxy)).to be_nil
+ end
end
context 'when the pool is a NullPool' do
- it 'returns unknown' do
+ it 'returns nil' do
connection = double(:active_record_connection, pool: ActiveRecord::ConnectionAdapters::NullPool.new)
- expect(described_class.db_config_name(connection)).to eq('unknown')
+ expect(described_class.db_config_for_connection(connection)).to be_nil
end
end
end
+ describe '.db_config_name' do
+ it 'returns the db_config name for the connection' do
+ connection = ActiveRecord::Base.connection
+
+ expect(described_class.db_config_name(connection)).to be_a(String)
+ expect(described_class.db_config_name(connection)).to eq(connection.pool.db_config.name)
+ end
+ end
+
describe '#true_value' do
it 'returns correct value' do
expect(described_class.true_value).to eq "'t'"
diff --git a/spec/lib/gitlab/devise_failure_spec.rb b/spec/lib/gitlab/devise_failure_spec.rb
deleted file mode 100644
index a452de59795..00000000000
--- a/spec/lib/gitlab/devise_failure_spec.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::DeviseFailure do
- let(:env) do
- {
- 'REQUEST_URI' => 'http://test.host/',
- 'HTTP_HOST' => 'test.host',
- 'REQUEST_METHOD' => 'GET',
- 'warden.options' => { scope: :user },
- 'rack.session' => {},
- 'rack.session.options' => {},
- 'rack.input' => "",
- 'warden' => OpenStruct.new(message: nil)
- }
- end
-
- let(:response) { described_class.call(env).to_a }
- let(:request) { ActionDispatch::Request.new(env) }
-
- context 'When redirecting' do
- it 'sets the expire_after key' do
- response
-
- expect(env['rack.session.options']).to have_key(:expire_after)
- end
-
- it 'returns to the default redirect location' do
- expect(response.first).to eq(302)
- expect(request.flash[:alert]).to eq('You need to sign in or sign up before continuing.')
- expect(response.second['Location']).to eq('http://test.host/users/sign_in')
- end
- end
-end
diff --git a/spec/lib/gitlab/diff/highlight_cache_spec.rb b/spec/lib/gitlab/diff/highlight_cache_spec.rb
index 9e94a63ea4b..e643b58ee32 100644
--- a/spec/lib/gitlab/diff/highlight_cache_spec.rb
+++ b/spec/lib/gitlab/diff/highlight_cache_spec.rb
@@ -185,6 +185,15 @@ RSpec.describe Gitlab::Diff::HighlightCache, :clean_gitlab_redis_cache do
expect { cache.send(:write_to_redis_hash, diff_hash) }
.to change { Gitlab::Redis::Cache.with { |r| r.hgetall(cache_key) } }
end
+
+ context 'when diff contains unsupported characters' do
+ let(:diff_hash) { { 'README' => [{ line_code: nil, rich_text: nil, text: [0xff, 0xfe, 0x0, 0x23].pack("c*"), type: "match", index: 0, old_pos: 17, new_pos: 17 }] } }
+
+ it 'does not update the cache' do
+ expect { cache.send(:write_to_redis_hash, diff_hash) }
+ .not_to change { Gitlab::Redis::Cache.with { |r| r.hgetall(cache_key) } }
+ end
+ end
end
describe '#clear' do
diff --git a/spec/lib/gitlab/email/handler/service_desk_handler_spec.rb b/spec/lib/gitlab/email/handler/service_desk_handler_spec.rb
index 2ef3b324db8..2916e65528f 100644
--- a/spec/lib/gitlab/email/handler/service_desk_handler_spec.rb
+++ b/spec/lib/gitlab/email/handler/service_desk_handler_spec.rb
@@ -353,13 +353,4 @@ RSpec.describe Gitlab::Email::Handler::ServiceDeskHandler do
expect { receiver.execute rescue nil }.not_to change { Issue.count }
end
end
-
- def email_fixture(path)
- fixture_file(path).gsub('project_id', project.project_id.to_s)
- end
-
- def service_desk_fixture(path, slug: nil, key: 'mykey')
- slug ||= project.full_path_slug.to_s
- fixture_file(path).gsub('project_slug', slug).gsub('project_key', key)
- end
end
diff --git a/spec/lib/gitlab/encoding_helper_spec.rb b/spec/lib/gitlab/encoding_helper_spec.rb
index 268ac5dcc21..98170ef437c 100644
--- a/spec/lib/gitlab/encoding_helper_spec.rb
+++ b/spec/lib/gitlab/encoding_helper_spec.rb
@@ -241,7 +241,7 @@ RSpec.describe Gitlab::EncodingHelper do
let(:data) { binary_string }
let(:kwargs) { {} }
- shared_examples 'detects encoding' do
+ context 'detects encoding' do
it { is_expected.to be_a(Hash) }
it 'correctly detects the binary' do
@@ -264,33 +264,5 @@ RSpec.describe Gitlab::EncodingHelper do
end
end
end
-
- context 'cached_encoding_detection is enabled' do
- before do
- stub_feature_flags(cached_encoding_detection: true)
- end
-
- it_behaves_like 'detects encoding'
-
- context 'cache_key is provided' do
- let(:kwargs) do
- { cache_key: %w(foo bar) }
- end
-
- it 'uses that cache_key to serve from the cache' do
- expect(Rails.cache).to receive(:fetch).with([:detect_binary, CharlockHolmes::VERSION, %w(foo bar)], expires_in: 1.week).and_call_original
-
- expect(subject[:type]).to eq(:binary)
- end
- end
- end
-
- context 'cached_encoding_detection is disabled' do
- before do
- stub_feature_flags(cached_encoding_detection: false)
- end
-
- it_behaves_like 'detects encoding'
- end
end
end
diff --git a/spec/lib/gitlab/experimentation/controller_concern_spec.rb b/spec/lib/gitlab/experimentation/controller_concern_spec.rb
index 8535d72a61f..1f7b7b90467 100644
--- a/spec/lib/gitlab/experimentation/controller_concern_spec.rb
+++ b/spec/lib/gitlab/experimentation/controller_concern_spec.rb
@@ -7,10 +7,6 @@ RSpec.describe Gitlab::Experimentation::ControllerConcern, type: :controller do
before do
stub_const('Gitlab::Experimentation::EXPERIMENTS', {
- backwards_compatible_test_experiment: {
- tracking_category: 'Team',
- use_backwards_compatible_subject_index: true
- },
test_experiment: {
tracking_category: 'Team',
rollout_strategy: rollout_strategy
@@ -23,7 +19,6 @@ RSpec.describe Gitlab::Experimentation::ControllerConcern, type: :controller do
allow(Gitlab).to receive(:dev_env_or_com?).and_return(is_gitlab_com)
- Feature.enable_percentage_of_time(:backwards_compatible_test_experiment_experiment_percentage, enabled_percentage)
Feature.enable_percentage_of_time(:test_experiment_experiment_percentage, enabled_percentage)
end
@@ -124,24 +119,15 @@ RSpec.describe Gitlab::Experimentation::ControllerConcern, type: :controller do
end
context 'cookie is present' do
- using RSpec::Parameterized::TableSyntax
-
before do
cookies.permanent.signed[:experimentation_subject_id] = 'abcd-1234'
get :index
end
- where(:experiment_key, :index_value) do
- :test_experiment | 'abcd-1234'
- :backwards_compatible_test_experiment | 'abcd1234'
- end
-
- with_them do
- it 'calls Gitlab::Experimentation.in_experiment_group?? with the name of the experiment and the calculated experimentation_subject_index based on the uuid' do
- expect(Gitlab::Experimentation).to receive(:in_experiment_group?).with(experiment_key, subject: index_value)
+ it 'calls Gitlab::Experimentation.in_experiment_group? with the name of the experiment and the calculated experimentation_subject_index based on the uuid' do
+ expect(Gitlab::Experimentation).to receive(:in_experiment_group?).with(:test_experiment, subject: 'abcd-1234')
- check_experiment(experiment_key)
- end
+ check_experiment(:test_experiment)
end
context 'when subject is given' do
diff --git a/spec/lib/gitlab/experimentation/experiment_spec.rb b/spec/lib/gitlab/experimentation/experiment_spec.rb
index 94dbf1d7e4b..d52ab3a8983 100644
--- a/spec/lib/gitlab/experimentation/experiment_spec.rb
+++ b/spec/lib/gitlab/experimentation/experiment_spec.rb
@@ -9,7 +9,6 @@ RSpec.describe Gitlab::Experimentation::Experiment do
let(:params) do
{
tracking_category: 'Category1',
- use_backwards_compatible_subject_index: true,
rollout_strategy: nil
}
end
diff --git a/spec/lib/gitlab/experimentation_spec.rb b/spec/lib/gitlab/experimentation_spec.rb
index c486538a260..c482874b725 100644
--- a/spec/lib/gitlab/experimentation_spec.rb
+++ b/spec/lib/gitlab/experimentation_spec.rb
@@ -7,10 +7,6 @@ RSpec.describe Gitlab::Experimentation do
before do
stub_const('Gitlab::Experimentation::EXPERIMENTS', {
- backwards_compatible_test_experiment: {
- tracking_category: 'Team',
- use_backwards_compatible_subject_index: true
- },
test_experiment: {
tracking_category: 'Team'
},
@@ -22,7 +18,6 @@ RSpec.describe Gitlab::Experimentation do
skip_feature_flags_yaml_validation
skip_default_enabled_yaml_check
- Feature.enable_percentage_of_time(:backwards_compatible_test_experiment_experiment_percentage, enabled_percentage)
Feature.enable_percentage_of_time(:test_experiment_experiment_percentage, enabled_percentage)
allow(Gitlab).to receive(:com?).and_return(true)
end
@@ -65,97 +60,47 @@ RSpec.describe Gitlab::Experimentation do
end
describe '.in_experiment_group?' do
- context 'with new index calculation' do
- let(:enabled_percentage) { 50 }
- let(:experiment_subject) { 'z' } # Zlib.crc32('test_experimentz') % 100 = 33
-
- subject { described_class.in_experiment_group?(:test_experiment, subject: experiment_subject) }
-
- context 'when experiment is active' do
- context 'when subject is part of the experiment' do
- it { is_expected.to eq(true) }
- end
+ let(:enabled_percentage) { 50 }
+ let(:experiment_subject) { 'z' } # Zlib.crc32('test_experimentz') % 100 = 33
- context 'when subject is not part of the experiment' do
- let(:experiment_subject) { 'a' } # Zlib.crc32('test_experimenta') % 100 = 61
+ subject { described_class.in_experiment_group?(:test_experiment, subject: experiment_subject) }
- it { is_expected.to eq(false) }
- end
+ context 'when experiment is active' do
+ context 'when subject is part of the experiment' do
+ it { is_expected.to eq(true) }
+ end
- context 'when subject has a global_id' do
- let(:experiment_subject) { double(:subject, to_global_id: 'z') }
+ context 'when subject is not part of the experiment' do
+ let(:experiment_subject) { 'a' } # Zlib.crc32('test_experimenta') % 100 = 61
- it { is_expected.to eq(true) }
- end
+ it { is_expected.to eq(false) }
+ end
- context 'when subject is nil' do
- let(:experiment_subject) { nil }
+ context 'when subject has a global_id' do
+ let(:experiment_subject) { double(:subject, to_global_id: 'z') }
- it { is_expected.to eq(false) }
- end
+ it { is_expected.to eq(true) }
+ end
- context 'when subject is an empty string' do
- let(:experiment_subject) { '' }
+ context 'when subject is nil' do
+ let(:experiment_subject) { nil }
- it { is_expected.to eq(false) }
- end
+ it { is_expected.to eq(false) }
end
- context 'when experiment is not active' do
- before do
- allow(described_class).to receive(:active?).and_return(false)
- end
+ context 'when subject is an empty string' do
+ let(:experiment_subject) { '' }
it { is_expected.to eq(false) }
end
end
- context 'with backwards compatible index calculation' do
- let(:experiment_subject) { 'abcd' } # Digest::SHA1.hexdigest('abcd').hex % 100 = 7
-
- subject { described_class.in_experiment_group?(:backwards_compatible_test_experiment, subject: experiment_subject) }
-
- context 'when experiment is active' do
- before do
- allow(described_class).to receive(:active?).and_return(true)
- end
-
- context 'when subject is part of the experiment' do
- it { is_expected.to eq(true) }
- end
-
- context 'when subject is not part of the experiment' do
- let(:experiment_subject) { 'abc' } # Digest::SHA1.hexdigest('abc').hex % 100 = 17
-
- it { is_expected.to eq(false) }
- end
-
- context 'when subject has a global_id' do
- let(:experiment_subject) { double(:subject, to_global_id: 'abcd') }
-
- it { is_expected.to eq(true) }
- end
-
- context 'when subject is nil' do
- let(:experiment_subject) { nil }
-
- it { is_expected.to eq(false) }
- end
-
- context 'when subject is an empty string' do
- let(:experiment_subject) { '' }
-
- it { is_expected.to eq(false) }
- end
+ context 'when experiment is not active' do
+ before do
+ allow(described_class).to receive(:active?).and_return(false)
end
- context 'when experiment is not active' do
- before do
- allow(described_class).to receive(:active?).and_return(false)
- end
-
- it { is_expected.to eq(false) }
- end
+ it { is_expected.to eq(false) }
end
end
diff --git a/spec/lib/gitlab/git/commit_spec.rb b/spec/lib/gitlab/git/commit_spec.rb
index f58bab52cfa..f4dba5e8d58 100644
--- a/spec/lib/gitlab/git/commit_spec.rb
+++ b/spec/lib/gitlab/git/commit_spec.rb
@@ -364,19 +364,39 @@ RSpec.describe Gitlab::Git::Commit, :seed_helper do
end
describe '.between' do
- subject do
- commits = described_class.between(repository, SeedRepo::Commit::PARENT_ID, SeedRepo::Commit::ID)
- commits.map { |c| c.id }
+ let(:limit) { nil }
+ let(:commit_ids) { commits.map(&:id) }
+
+ subject(:commits) { described_class.between(repository, from, to, limit: limit) }
+
+ context 'requesting a single commit' do
+ let(:from) { SeedRepo::Commit::PARENT_ID }
+ let(:to) { SeedRepo::Commit::ID }
+
+ it { expect(commit_ids).to contain_exactly(to) }
end
- it { is_expected.to contain_exactly(SeedRepo::Commit::ID) }
+ context 'requesting a commit range' do
+ let(:from) { 'v1.0.0' }
+ let(:to) { 'v1.2.0' }
- context 'between_uses_list_commits FF disabled' do
- before do
- stub_feature_flags(between_uses_list_commits: false)
+ let(:commits_in_range) do
+ %w[
+ 570e7b2abdd848b95f2f578043fc23bd6f6fd24d
+ 5937ac0a7beb003549fc5fd26fc247adbce4a52e
+ eb49186cfa5c4338011f5f590fac11bd66c5c631
+ ]
end
- it { is_expected.to contain_exactly(SeedRepo::Commit::ID) }
+ context 'no limit' do
+ it { expect(commit_ids).to eq(commits_in_range) }
+ end
+
+ context 'limited' do
+ let(:limit) { 2 }
+
+ it { expect(commit_ids).to eq(commits_in_range.last(2)) }
+ end
end
end
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index 29e7a1dce1d..9ecd281cce0 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -109,6 +109,32 @@ RSpec.describe Gitlab::Git::Repository, :seed_helper do
it_behaves_like 'wrapping gRPC errors', Gitlab::GitalyClient::RefService, :tag_names
end
+ describe '#tags' do
+ subject { repository.tags }
+
+ it 'gets tags from GitalyClient' do
+ expect_next_instance_of(Gitlab::GitalyClient::RefService) do |service|
+ expect(service).to receive(:tags)
+ end
+
+ subject
+ end
+
+ context 'with sorting option' do
+ subject { repository.tags(sort_by: 'name_asc') }
+
+ it 'gets tags from GitalyClient' do
+ expect_next_instance_of(Gitlab::GitalyClient::RefService) do |service|
+ expect(service).to receive(:tags).with(sort_by: 'name_asc')
+ end
+
+ subject
+ end
+ end
+
+ it_behaves_like 'wrapping gRPC errors', Gitlab::GitalyClient::RefService, :tags
+ end
+
describe '#archive_metadata' do
let(:storage_path) { '/tmp' }
let(:cache_key) { File.join(repository.gl_repository, SeedRepo::LastCommit::ID) }
@@ -936,6 +962,159 @@ RSpec.describe Gitlab::Git::Repository, :seed_helper do
end
end
+ describe '#new_blobs' do
+ let(:repository) { mutable_repository }
+ let(:repository_rugged) { mutable_repository_rugged }
+ let(:blob) { create_blob('This is a new blob') }
+ let(:commit) { create_commit('nested/new-blob.txt' => blob) }
+
+ def create_blob(content)
+ repository_rugged.write(content, :blob)
+ end
+
+ def create_commit(blobs)
+ author = { name: 'Test User', email: 'mail@example.com', time: Time.now }
+
+ index = repository_rugged.index
+ blobs.each do |path, oid|
+ index.add(path: path, oid: oid, mode: 0100644)
+ end
+
+ Rugged::Commit.create(repository_rugged,
+ author: author,
+ committer: author,
+ message: "Message",
+ parents: [],
+ tree: index.write_tree(repository_rugged))
+ end
+
+ subject { repository.new_blobs(newrevs).to_a }
+
+ shared_examples '#new_blobs with revisions' do
+ before do
+ expect_next_instance_of(Gitlab::GitalyClient::BlobService) do |service|
+ expect(service)
+ .to receive(:list_blobs)
+ .with(expected_newrevs,
+ limit: Gitlab::Git::Repository::REV_LIST_COMMIT_LIMIT,
+ with_paths: true,
+ dynamic_timeout: nil)
+ .once
+ .and_call_original
+ end
+ end
+
+ it 'enumerates new blobs' do
+ expect(subject).to match_array(expected_blobs)
+ end
+
+ it 'memoizes results' do
+ expect(subject).to match_array(expected_blobs)
+ expect(subject).to match_array(expected_blobs)
+ end
+ end
+
+ context 'with a single revision' do
+ let(:newrevs) { commit }
+ let(:expected_newrevs) { ['--not', '--all', '--not', newrevs] }
+ let(:expected_blobs) do
+ [have_attributes(class: Gitlab::Git::Blob, id: blob, path: 'nested/new-blob.txt', size: 18)]
+ end
+
+ it_behaves_like '#new_blobs with revisions'
+ end
+
+ context 'with a single-entry array' do
+ let(:newrevs) { [commit] }
+ let(:expected_newrevs) { ['--not', '--all', '--not'] + newrevs }
+ let(:expected_blobs) do
+ [have_attributes(class: Gitlab::Git::Blob, id: blob, path: 'nested/new-blob.txt', size: 18)]
+ end
+
+ it_behaves_like '#new_blobs with revisions'
+ end
+
+ context 'with multiple revisions' do
+ let(:another_blob) { create_blob('Another blob') }
+ let(:newrevs) { [commit, create_commit('another_path.txt' => another_blob)] }
+ let(:expected_newrevs) { ['--not', '--all', '--not'] + newrevs.sort }
+ let(:expected_blobs) do
+ [
+ have_attributes(class: Gitlab::Git::Blob, id: blob, path: 'nested/new-blob.txt', size: 18),
+ have_attributes(class: Gitlab::Git::Blob, id: another_blob, path: 'another_path.txt', size: 12)
+ ]
+ end
+
+ it_behaves_like '#new_blobs with revisions'
+ end
+
+ context 'with partially blank revisions' do
+ let(:newrevs) { [nil, commit, Gitlab::Git::BLANK_SHA] }
+ let(:expected_newrevs) { ['--not', '--all', '--not', commit] }
+ let(:expected_blobs) do
+ [
+ have_attributes(class: Gitlab::Git::Blob, id: blob, path: 'nested/new-blob.txt', size: 18)
+ ]
+ end
+
+ it_behaves_like '#new_blobs with revisions'
+ end
+
+ context 'with repeated revisions' do
+ let(:newrevs) { [commit, commit, commit] }
+ let(:expected_newrevs) { ['--not', '--all', '--not', commit] }
+ let(:expected_blobs) do
+ [
+ have_attributes(class: Gitlab::Git::Blob, id: blob, path: 'nested/new-blob.txt', size: 18)
+ ]
+ end
+
+ it_behaves_like '#new_blobs with revisions'
+ end
+
+ context 'with preexisting commits' do
+ let(:newrevs) { ['refs/heads/master'] }
+ let(:expected_newrevs) { ['--not', '--all', '--not'] + newrevs }
+ let(:expected_blobs) { [] }
+
+ it_behaves_like '#new_blobs with revisions'
+ end
+
+ shared_examples '#new_blobs without revisions' do
+ before do
+ expect(Gitlab::GitalyClient::BlobService).not_to receive(:new)
+ end
+
+ it 'returns an empty array' do
+ expect(subject).to eq([])
+ end
+ end
+
+ context 'with a single nil newrev' do
+ let(:newrevs) { nil }
+
+ it_behaves_like '#new_blobs without revisions'
+ end
+
+ context 'with a single zero newrev' do
+ let(:newrevs) { Gitlab::Git::BLANK_SHA }
+
+ it_behaves_like '#new_blobs without revisions'
+ end
+
+ context 'with an empty array' do
+ let(:newrevs) { [] }
+
+ it_behaves_like '#new_blobs without revisions'
+ end
+
+ context 'with array containing only empty refs' do
+ let(:newrevs) { [nil, Gitlab::Git::BLANK_SHA] }
+
+ it_behaves_like '#new_blobs without revisions'
+ end
+ end
+
describe '#new_commits' do
let(:repository) { mutable_repository }
let(:new_commit) do
@@ -1132,28 +1311,6 @@ RSpec.describe Gitlab::Git::Repository, :seed_helper do
end
end
- describe '#ref_name_for_sha' do
- let(:ref_path) { 'refs/heads' }
- let(:sha) { repository.find_branch('master').dereferenced_target.id }
- let(:ref_name) { 'refs/heads/master' }
-
- it 'returns the ref name for the given sha' do
- expect(repository.ref_name_for_sha(ref_path, sha)).to eq(ref_name)
- end
-
- it "returns an empty name if the ref doesn't exist" do
- expect(repository.ref_name_for_sha(ref_path, "000000")).to eq("")
- end
-
- it "raise an exception if the ref is empty" do
- expect { repository.ref_name_for_sha(ref_path, "") }.to raise_error(ArgumentError)
- end
-
- it "raise an exception if the ref is nil" do
- expect { repository.ref_name_for_sha(ref_path, nil) }.to raise_error(ArgumentError)
- end
- end
-
describe '#branches' do
subject { repository.branches }
@@ -1732,83 +1889,42 @@ RSpec.describe Gitlab::Git::Repository, :seed_helper do
end
describe '#set_full_path' do
- shared_examples '#set_full_path' do
- before do
- repository_rugged.config["gitlab.fullpath"] = repository_path
- end
-
- context 'is given a path' do
- it 'writes it to disk' do
- repository.set_full_path(full_path: "not-the/real-path.git")
-
- config = File.read(File.join(repository_path, "config"))
-
- expect(config).to include("[gitlab]")
- expect(config).to include("fullpath = not-the/real-path.git")
- end
- end
-
- context 'it is given an empty path' do
- it 'does not write it to disk' do
- repository.set_full_path(full_path: "")
-
- config = File.read(File.join(repository_path, "config"))
-
- expect(config).to include("[gitlab]")
- expect(config).to include("fullpath = #{repository_path}")
- end
- end
+ before do
+ repository_rugged.config["gitlab.fullpath"] = repository_path
+ end
- context 'repository does not exist' do
- it 'raises NoRepository and does not call Gitaly WriteConfig' do
- repository = Gitlab::Git::Repository.new('default', 'does/not/exist.git', '', 'group/project')
+ context 'is given a path' do
+ it 'writes it to disk' do
+ repository.set_full_path(full_path: "not-the/real-path.git")
- expect(repository.gitaly_repository_client).not_to receive(:set_full_path)
+ config = File.read(File.join(repository_path, "config"))
- expect do
- repository.set_full_path(full_path: 'foo/bar.git')
- end.to raise_error(Gitlab::Git::Repository::NoRepository)
- end
+ expect(config).to include("[gitlab]")
+ expect(config).to include("fullpath = not-the/real-path.git")
end
end
- context 'with :set_full_path enabled' do
- before do
- stub_feature_flags(set_full_path: true)
- end
+ context 'it is given an empty path' do
+ it 'does not write it to disk' do
+ repository.set_full_path(full_path: "")
- it_behaves_like '#set_full_path'
- end
+ config = File.read(File.join(repository_path, "config"))
- context 'with :set_full_path disabled' do
- before do
- stub_feature_flags(set_full_path: false)
+ expect(config).to include("[gitlab]")
+ expect(config).to include("fullpath = #{repository_path}")
end
-
- it_behaves_like '#set_full_path'
end
- end
- describe '#set_config' do
- let(:repository) { mutable_repository }
- let(:entries) do
- {
- 'test.foo1' => 'bla bla',
- 'test.foo2' => 1234,
- 'test.foo3' => true
- }
- end
+ context 'repository does not exist' do
+ it 'raises NoRepository and does not call Gitaly WriteConfig' do
+ repository = Gitlab::Git::Repository.new('default', 'does/not/exist.git', '', 'group/project')
- it 'can set config settings' do
- expect(repository.set_config(entries)).to be_nil
+ expect(repository.gitaly_repository_client).not_to receive(:set_full_path)
- expect(repository_rugged.config['test.foo1']).to eq('bla bla')
- expect(repository_rugged.config['test.foo2']).to eq('1234')
- expect(repository_rugged.config['test.foo3']).to eq('true')
- end
-
- after do
- entries.keys.each { |k| repository_rugged.config.delete(k) }
+ expect do
+ repository.set_full_path(full_path: 'foo/bar.git')
+ end.to raise_error(Gitlab::Git::Repository::NoRepository)
+ end
end
end
diff --git a/spec/lib/gitlab/git/tag_spec.rb b/spec/lib/gitlab/git/tag_spec.rb
index 79ae47f8a7b..4f56595d7d2 100644
--- a/spec/lib/gitlab/git/tag_spec.rb
+++ b/spec/lib/gitlab/git/tag_spec.rb
@@ -38,7 +38,7 @@ RSpec.describe Gitlab::Git::Tag, :seed_helper do
it { expect(tag.tagger.timezone).to eq("+0200") }
end
- shared_examples 'signed tag' do
+ describe 'signed tag' do
let(:project) { create(:project, :repository) }
let(:tag) { project.repository.find_tag('v1.1.1') }
@@ -54,18 +54,6 @@ RSpec.describe Gitlab::Git::Tag, :seed_helper do
it { expect(tag.tagger.timezone).to eq("+0100") }
end
- context 'with :get_tag_signatures enabled' do
- it_behaves_like 'signed tag'
- end
-
- context 'with :get_tag_signatures disabled' do
- before do
- stub_feature_flags(get_tag_signatures: false)
- end
-
- it_behaves_like 'signed tag'
- end
-
it { expect(repository.tags.size).to eq(SeedRepo::Repo::TAGS.size) }
end
diff --git a/spec/lib/gitlab/git/tree_spec.rb b/spec/lib/gitlab/git/tree_spec.rb
index f11d84bd8d3..005f8ecaa3a 100644
--- a/spec/lib/gitlab/git/tree_spec.rb
+++ b/spec/lib/gitlab/git/tree_spec.rb
@@ -189,12 +189,109 @@ RSpec.describe Gitlab::Git::Tree, :seed_helper do
end
it_behaves_like :repo do
- context 'with pagination parameters' do
- let(:pagination_params) { { limit: 3, page_token: nil } }
+ describe 'Pagination' do
+ context 'with restrictive limit' do
+ let(:pagination_params) { { limit: 3, page_token: nil } }
+
+ it 'returns limited paginated list of tree objects' do
+ expect(entries.count).to eq(3)
+ expect(cursor.next_cursor).to be_present
+ end
+ end
+
+ context 'when limit is equal to number of entries' do
+ let(:entries_count) { entries.count }
+
+ it 'returns all entries without a cursor' do
+ result, cursor = Gitlab::Git::Tree.where(repository, sha, path, recursive, { limit: entries_count, page_token: nil })
+
+ expect(cursor).to be_nil
+ expect(result.entries.count).to eq(entries_count)
+ end
+ end
+
+ context 'when limit is 0' do
+ let(:pagination_params) { { limit: 0, page_token: nil } }
+
+ it 'returns empty result' do
+ expect(entries).to eq([])
+ expect(cursor).to be_nil
+ end
+ end
+
+ context 'when limit is missing' do
+ let(:pagination_params) { { limit: nil, page_token: nil } }
+
+ it 'returns empty result' do
+ expect(entries).to eq([])
+ expect(cursor).to be_nil
+ end
+ end
+
+ context 'when limit is negative' do
+ let(:entries_count) { entries.count }
+
+ it 'returns all entries' do
+ result, cursor = Gitlab::Git::Tree.where(repository, sha, path, recursive, { limit: -1, page_token: nil })
+
+ expect(result.count).to eq(entries_count)
+ expect(cursor).to be_nil
+ end
+
+ context 'when token is provided' do
+ let(:pagination_params) { { limit: 1000, page_token: nil } }
+ let(:token) { entries.second.id }
+
+ it 'returns all entries after token' do
+ result, cursor = Gitlab::Git::Tree.where(repository, sha, path, recursive, { limit: -1, page_token: token })
+
+ expect(result.count).to eq(entries.count - 2)
+ expect(cursor).to be_nil
+ end
+ end
+ end
+
+ context 'when token does not exist' do
+ let(:pagination_params) { { limit: 5, page_token: 'aabbccdd' } }
+
+ it 'raises a command error' do
+ expect { entries }.to raise_error(Gitlab::Git::CommandError, 'could not find starting OID: aabbccdd')
+ end
+ end
+
+ context 'when limit is bigger than number of entries' do
+ let(:pagination_params) { { limit: 1000, page_token: nil } }
+
+ it 'returns only available entries' do
+ expect(entries.count).to be < 20
+ expect(cursor).to be_nil
+ end
+ end
+
+ it 'returns all tree entries in specific order during cursor pagination' do
+ collected_entries = []
+ token = nil
+
+ expected_entries = entries
+
+ loop do
+ result, cursor = Gitlab::Git::Tree.where(repository, sha, path, recursive, { limit: 5, page_token: token })
+
+ collected_entries += result.entries
+ token = cursor&.next_cursor
+
+ break if token.blank?
+ end
+
+ expect(collected_entries.map(&:path)).to match_array(expected_entries.map(&:path))
+
+ expected_order = [
+ collected_entries.select(&:dir?).map(&:path),
+ collected_entries.select(&:file?).map(&:path),
+ collected_entries.select(&:submodule?).map(&:path)
+ ].flatten
- it 'does not support pagination' do
- expect(entries.count).to be >= 10
- expect(cursor).to be_nil
+ expect(collected_entries.map(&:path)).to eq(expected_order)
end
end
end
diff --git a/spec/lib/gitlab/gitaly_client/blob_service_spec.rb b/spec/lib/gitlab/gitaly_client/blob_service_spec.rb
index 50078d8c127..f869c66337e 100644
--- a/spec/lib/gitlab/gitaly_client/blob_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/blob_service_spec.rb
@@ -92,13 +92,14 @@ RSpec.describe Gitlab::GitalyClient::BlobService do
describe '#list_blobs' do
let(:limit) { 0 }
let(:bytes_limit) { 0 }
- let(:expected_params) { { revisions: revisions, limit: limit, bytes_limit: bytes_limit } }
+ let(:with_paths) { false }
+ let(:expected_params) { { revisions: revisions, limit: limit, bytes_limit: bytes_limit, with_paths: with_paths } }
before do
::Gitlab::GitalyClient.clear_stubs!
end
- subject { client.list_blobs(revisions, limit: limit, bytes_limit: bytes_limit) }
+ subject { client.list_blobs(revisions, limit: limit, bytes_limit: bytes_limit, with_paths: with_paths) }
context 'with a single revision' do
let(:revisions) { ['master'] }
@@ -147,6 +148,24 @@ RSpec.describe Gitlab::GitalyClient::BlobService do
end
end
+ context 'with paths' do
+ let(:revisions) { ['master'] }
+ let(:limit) { 10 }
+ let(:bytes_lmit) { 1024 }
+ let(:with_paths) { true }
+
+ it 'sends a list_blobs message' do
+ expect_next_instance_of(Gitaly::BlobService::Stub) do |service|
+ expect(service)
+ .to receive(:list_blobs)
+ .with(gitaly_request_with_params(expected_params), kind_of(Hash))
+ .and_return([])
+ end
+
+ subject
+ end
+ end
+
context 'with split contents' do
let(:revisions) { ['master'] }
diff --git a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
index a0e2d43cf45..554a91f2bc5 100644
--- a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
@@ -311,6 +311,10 @@ RSpec.describe Gitlab::GitalyClient::CommitService do
end
describe '#list_commits' do
+ let(:revisions) { 'master' }
+ let(:reverse) { false }
+ let(:pagination_params) { nil }
+
shared_examples 'a ListCommits request' do
before do
::Gitlab::GitalyClient.clear_stubs!
@@ -318,26 +322,35 @@ RSpec.describe Gitlab::GitalyClient::CommitService do
it 'sends a list_commits message' do
expect_next_instance_of(Gitaly::CommitService::Stub) do |service|
- expect(service)
- .to receive(:list_commits)
- .with(gitaly_request_with_params(expected_params), kind_of(Hash))
- .and_return([])
+ expected_request = gitaly_request_with_params(
+ Array.wrap(revisions),
+ reverse: reverse,
+ pagination_params: pagination_params
+ )
+
+ expect(service).to receive(:list_commits).with(expected_request, kind_of(Hash)).and_return([])
end
- client.list_commits(revisions)
+ client.list_commits(revisions, reverse: reverse, pagination_params: pagination_params)
end
end
- context 'with a single revision' do
- let(:revisions) { 'master' }
- let(:expected_params) { %w[master] }
+ it_behaves_like 'a ListCommits request'
+
+ context 'with multiple revisions' do
+ let(:revisions) { %w[master --not --all] }
+
+ it_behaves_like 'a ListCommits request'
+ end
+
+ context 'with reverse: true' do
+ let(:reverse) { true }
it_behaves_like 'a ListCommits request'
end
- context 'with multiple revisions' do
- let(:revisions) { %w[master --not --all] }
- let(:expected_params) { %w[master --not --all] }
+ context 'with pagination params' do
+ let(:pagination_params) { { limit: 1, page_token: 'foo' } }
it_behaves_like 'a ListCommits request'
end
diff --git a/spec/lib/gitlab/gitaly_client/ref_service_spec.rb b/spec/lib/gitlab/gitaly_client/ref_service_spec.rb
index e19be965e68..d308612ef31 100644
--- a/spec/lib/gitlab/gitaly_client/ref_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/ref_service_spec.rb
@@ -92,6 +92,36 @@ RSpec.describe Gitlab::GitalyClient::RefService do
end
end
+ describe '#find_branch' do
+ it 'sends a find_branch message' do
+ expect_any_instance_of(Gitaly::RefService::Stub)
+ .to receive(:find_branch)
+ .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
+ .and_return(double(branch: Gitaly::Branch.new(name: 'name', target_commit: build(:gitaly_commit))))
+
+ client.find_branch('name')
+ end
+ end
+
+ describe '#find_tag' do
+ it 'sends a find_tag message' do
+ expect_any_instance_of(Gitaly::RefService::Stub)
+ .to receive(:find_tag)
+ .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
+ .and_return(double(tag: Gitaly::Tag.new))
+
+ client.find_tag('name')
+ end
+
+ context 'when tag is empty' do
+ it 'does not send a fing_tag message' do
+ expect_any_instance_of(Gitaly::RefService::Stub).not_to receive(:find_tag)
+
+ expect(client.find_tag('')).to be_nil
+ end
+ end
+ end
+
describe '#default_branch_name' do
it 'sends a find_default_branch_name message' do
expect_any_instance_of(Gitaly::RefService::Stub)
@@ -103,16 +133,6 @@ RSpec.describe Gitlab::GitalyClient::RefService do
end
end
- describe '#list_new_blobs' do
- it 'raises DeadlineExceeded when timeout is too small' do
- newrev = '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51'
-
- expect do
- client.list_new_blobs(newrev, dynamic_timeout: 0.001)
- end.to raise_error(GRPC::DeadlineExceeded)
- end
- end
-
describe '#local_branches' do
it 'sends a find_local_branches message' do
expect_any_instance_of(Gitaly::RefService::Stub)
@@ -154,6 +174,22 @@ RSpec.describe Gitlab::GitalyClient::RefService do
client.tags
end
+
+ context 'with sorting option' do
+ it 'sends a correct find_all_tags message' do
+ expected_sort_by = Gitaly::FindAllTagsRequest::SortBy.new(
+ key: :REFNAME,
+ direction: :ASCENDING
+ )
+
+ expect_any_instance_of(Gitaly::RefService::Stub)
+ .to receive(:find_all_tags)
+ .with(gitaly_request_with_params(sort_by: expected_sort_by), kind_of(Hash))
+ .and_return([])
+
+ client.tags(sort_by: 'name_asc')
+ end
+ end
end
describe '#branch_names_contains_sha' do
@@ -189,13 +225,6 @@ RSpec.describe Gitlab::GitalyClient::RefService do
end
end
- describe '#find_ref_name', :seed_helper do
- subject { client.find_ref_name(SeedRepo::Commit::ID, 'refs/heads/master') }
-
- it { is_expected.to be_utf8 }
- it { is_expected.to eq('refs/heads/master') }
- end
-
describe '#ref_exists?', :seed_helper do
it 'finds the master branch ref' do
expect(client.ref_exists?('refs/heads/master')).to eq(true)
diff --git a/spec/lib/gitlab/gitaly_client/repository_service_spec.rb b/spec/lib/gitlab/gitaly_client/repository_service_spec.rb
index 4b037d3f836..e5502a883b5 100644
--- a/spec/lib/gitlab/gitaly_client/repository_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/repository_service_spec.rb
@@ -195,19 +195,6 @@ RSpec.describe Gitlab::GitalyClient::RepositoryService do
end
end
- describe '#squash_in_progress?' do
- let(:squash_id) { 1 }
-
- it 'sends a repository_squash_in_progress message' do
- expect_any_instance_of(Gitaly::RepositoryService::Stub)
- .to receive(:is_squash_in_progress)
- .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
- .and_return(double(in_progress: true))
-
- client.squash_in_progress?(squash_id)
- end
- end
-
describe '#calculate_checksum' do
it 'sends a calculate_checksum message' do
expect_any_instance_of(Gitaly::RepositoryService::Stub)
diff --git a/spec/lib/gitlab/github_import/importer/diff_note_importer_spec.rb b/spec/lib/gitlab/github_import/importer/diff_note_importer_spec.rb
index 0af840d2c10..3dc15c7c059 100644
--- a/spec/lib/gitlab/github_import/importer/diff_note_importer_spec.rb
+++ b/spec/lib/gitlab/github_import/importer/diff_note_importer_spec.rb
@@ -20,6 +20,7 @@ RSpec.describe Gitlab::GithubImport::Importer::DiffNoteImporter do
noteable_type: 'MergeRequest',
noteable_id: 1,
commit_id: '123abc',
+ original_commit_id: 'original123abc',
file_path: 'README.md',
diff_hunk: hunk,
author: Gitlab::GithubImport::Representation::User
@@ -64,13 +65,14 @@ RSpec.describe Gitlab::GithubImport::Importer::DiffNoteImporter do
LegacyDiffNote.table_name,
[
{
+ discussion_id: anything,
noteable_type: 'MergeRequest',
noteable_id: merge_request.id,
project_id: project.id,
author_id: user.id,
note: 'Hello',
system: false,
- commit_id: '123abc',
+ commit_id: 'original123abc',
line_code: note.line_code,
type: 'LegacyDiffNote',
created_at: created_at,
@@ -95,13 +97,14 @@ RSpec.describe Gitlab::GithubImport::Importer::DiffNoteImporter do
LegacyDiffNote.table_name,
[
{
+ discussion_id: anything,
noteable_type: 'MergeRequest',
noteable_id: merge_request.id,
project_id: project.id,
author_id: project.creator_id,
note: "*Created by: #{user.username}*\n\nHello",
system: false,
- commit_id: '123abc',
+ commit_id: 'original123abc',
line_code: note.line_code,
type: 'LegacyDiffNote',
created_at: created_at,
diff --git a/spec/lib/gitlab/github_import/importer/diff_notes_importer_spec.rb b/spec/lib/gitlab/github_import/importer/diff_notes_importer_spec.rb
index 7750e508713..46b9959ff64 100644
--- a/spec/lib/gitlab/github_import/importer/diff_notes_importer_spec.rb
+++ b/spec/lib/gitlab/github_import/importer/diff_notes_importer_spec.rb
@@ -12,6 +12,7 @@ RSpec.describe Gitlab::GithubImport::Importer::DiffNotesImporter do
html_url: 'https://github.com/foo/bar/pull/42',
path: 'README.md',
commit_id: '123abc',
+ original_commit_id: 'original123abc',
diff_hunk: "@@ -1 +1 @@\n-Hello\n+Hello world",
user: double(:user, id: 4, login: 'alice'),
body: 'Hello world',
diff --git a/spec/lib/gitlab/github_import/importer/single_endpoint_diff_notes_importer_spec.rb b/spec/lib/gitlab/github_import/importer/single_endpoint_diff_notes_importer_spec.rb
new file mode 100644
index 00000000000..8c71d7d0ed7
--- /dev/null
+++ b/spec/lib/gitlab/github_import/importer/single_endpoint_diff_notes_importer_spec.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::GithubImport::Importer::SingleEndpointDiffNotesImporter do
+ let(:client) { double }
+ let(:project) { create(:project, import_source: 'github/repo') }
+
+ subject { described_class.new(project, client) }
+
+ it { is_expected.to include_module(Gitlab::GithubImport::ParallelScheduling) }
+ it { is_expected.to include_module(Gitlab::GithubImport::SingleEndpointNotesImporting) }
+ it { expect(subject.representation_class).to eq(Gitlab::GithubImport::Representation::DiffNote) }
+ it { expect(subject.importer_class).to eq(Gitlab::GithubImport::Importer::DiffNoteImporter) }
+ it { expect(subject.collection_method).to eq(:pull_request_comments) }
+ it { expect(subject.object_type).to eq(:diff_note) }
+ it { expect(subject.id_for_already_imported_cache(double(id: 1))).to eq(1) }
+
+ describe '#each_object_to_import', :clean_gitlab_redis_cache do
+ let(:merge_request) do
+ create(
+ :merged_merge_request,
+ iid: 999,
+ source_project: project,
+ target_project: project
+ )
+ end
+
+ let(:note) { double(id: 1) }
+ let(:page) { double(objects: [note], number: 1) }
+
+ it 'fetches data' do
+ expect(client)
+ .to receive(:each_page)
+ .exactly(:once) # ensure to be cached on the second call
+ .with(:pull_request_comments, 'github/repo', merge_request.iid, page: 1)
+ .and_yield(page)
+
+ expect { |b| subject.each_object_to_import(&b) }.to yield_with_args(note)
+
+ subject.each_object_to_import {}
+
+ expect(
+ Gitlab::Cache::Import::Caching.set_includes?(
+ "github-importer/merge_request/diff_notes/already-imported/#{project.id}",
+ merge_request.iid
+ )
+ ).to eq(true)
+ end
+
+ it 'skips cached pages' do
+ Gitlab::GithubImport::PageCounter
+ .new(project, "merge_request/#{merge_request.id}/pull_request_comments")
+ .set(2)
+
+ expect(client)
+ .to receive(:each_page)
+ .exactly(:once) # ensure to be cached on the second call
+ .with(:pull_request_comments, 'github/repo', merge_request.iid, page: 2)
+
+ subject.each_object_to_import {}
+ end
+
+ it 'skips cached merge requests' do
+ Gitlab::Cache::Import::Caching.set_add(
+ "github-importer/merge_request/diff_notes/already-imported/#{project.id}",
+ merge_request.iid
+ )
+
+ expect(client).not_to receive(:each_page)
+
+ subject.each_object_to_import {}
+ end
+ end
+end
diff --git a/spec/lib/gitlab/github_import/importer/single_endpoint_issue_notes_importer_spec.rb b/spec/lib/gitlab/github_import/importer/single_endpoint_issue_notes_importer_spec.rb
new file mode 100644
index 00000000000..8d8f2730880
--- /dev/null
+++ b/spec/lib/gitlab/github_import/importer/single_endpoint_issue_notes_importer_spec.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::GithubImport::Importer::SingleEndpointIssueNotesImporter do
+ let(:client) { double }
+ let(:project) { create(:project, import_source: 'github/repo') }
+
+ subject { described_class.new(project, client) }
+
+ it { is_expected.to include_module(Gitlab::GithubImport::ParallelScheduling) }
+ it { is_expected.to include_module(Gitlab::GithubImport::SingleEndpointNotesImporting) }
+ it { expect(subject.representation_class).to eq(Gitlab::GithubImport::Representation::Note) }
+ it { expect(subject.importer_class).to eq(Gitlab::GithubImport::Importer::NoteImporter) }
+ it { expect(subject.collection_method).to eq(:issue_comments) }
+ it { expect(subject.object_type).to eq(:note) }
+ it { expect(subject.id_for_already_imported_cache(double(id: 1))).to eq(1) }
+
+ describe '#each_object_to_import', :clean_gitlab_redis_cache do
+ let(:issue) do
+ create(
+ :issue,
+ iid: 999,
+ project: project
+ )
+ end
+
+ let(:note) { double(id: 1) }
+ let(:page) { double(objects: [note], number: 1) }
+
+ it 'fetches data' do
+ expect(client)
+ .to receive(:each_page)
+ .exactly(:once) # ensure to be cached on the second call
+ .with(:issue_comments, 'github/repo', issue.iid, page: 1)
+ .and_yield(page)
+
+ expect { |b| subject.each_object_to_import(&b) }.to yield_with_args(note)
+
+ subject.each_object_to_import {}
+
+ expect(
+ Gitlab::Cache::Import::Caching.set_includes?(
+ "github-importer/issue/notes/already-imported/#{project.id}",
+ issue.iid
+ )
+ ).to eq(true)
+ end
+
+ it 'skips cached pages' do
+ Gitlab::GithubImport::PageCounter
+ .new(project, "issue/#{issue.id}/issue_comments")
+ .set(2)
+
+ expect(client)
+ .to receive(:each_page)
+ .exactly(:once) # ensure to be cached on the second call
+ .with(:issue_comments, 'github/repo', issue.iid, page: 2)
+
+ subject.each_object_to_import {}
+ end
+
+ it 'skips cached merge requests' do
+ Gitlab::Cache::Import::Caching.set_add(
+ "github-importer/issue/notes/already-imported/#{project.id}",
+ issue.iid
+ )
+
+ expect(client).not_to receive(:each_page)
+
+ subject.each_object_to_import {}
+ end
+ end
+end
diff --git a/spec/lib/gitlab/github_import/importer/single_endpoint_merge_request_notes_importer_spec.rb b/spec/lib/gitlab/github_import/importer/single_endpoint_merge_request_notes_importer_spec.rb
new file mode 100644
index 00000000000..b8282212a90
--- /dev/null
+++ b/spec/lib/gitlab/github_import/importer/single_endpoint_merge_request_notes_importer_spec.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::GithubImport::Importer::SingleEndpointMergeRequestNotesImporter do
+ let(:client) { double }
+ let(:project) { create(:project, import_source: 'github/repo') }
+
+ subject { described_class.new(project, client) }
+
+ it { is_expected.to include_module(Gitlab::GithubImport::ParallelScheduling) }
+ it { is_expected.to include_module(Gitlab::GithubImport::SingleEndpointNotesImporting) }
+ it { expect(subject.representation_class).to eq(Gitlab::GithubImport::Representation::Note) }
+ it { expect(subject.importer_class).to eq(Gitlab::GithubImport::Importer::NoteImporter) }
+ it { expect(subject.collection_method).to eq(:issue_comments) }
+ it { expect(subject.object_type).to eq(:note) }
+ it { expect(subject.id_for_already_imported_cache(double(id: 1))).to eq(1) }
+
+ describe '#each_object_to_import', :clean_gitlab_redis_cache do
+ let(:merge_request) do
+ create(
+ :merge_request,
+ iid: 999,
+ source_project: project,
+ target_project: project
+ )
+ end
+
+ let(:note) { double(id: 1) }
+ let(:page) { double(objects: [note], number: 1) }
+
+ it 'fetches data' do
+ expect(client)
+ .to receive(:each_page)
+ .exactly(:once) # ensure to be cached on the second call
+ .with(:issue_comments, 'github/repo', merge_request.iid, page: 1)
+ .and_yield(page)
+
+ expect { |b| subject.each_object_to_import(&b) }.to yield_with_args(note)
+
+ subject.each_object_to_import {}
+
+ expect(
+ Gitlab::Cache::Import::Caching.set_includes?(
+ "github-importer/merge_request/notes/already-imported/#{project.id}",
+ merge_request.iid
+ )
+ ).to eq(true)
+ end
+
+ it 'skips cached pages' do
+ Gitlab::GithubImport::PageCounter
+ .new(project, "merge_request/#{merge_request.id}/issue_comments")
+ .set(2)
+
+ expect(client)
+ .to receive(:each_page)
+ .exactly(:once) # ensure to be cached on the second call
+ .with(:issue_comments, 'github/repo', merge_request.iid, page: 2)
+
+ subject.each_object_to_import {}
+ end
+
+ it 'skips cached merge requests' do
+ Gitlab::Cache::Import::Caching.set_add(
+ "github-importer/merge_request/notes/already-imported/#{project.id}",
+ merge_request.iid
+ )
+
+ expect(client).not_to receive(:each_page)
+
+ subject.each_object_to_import {}
+ end
+ end
+end
diff --git a/spec/lib/gitlab/github_import/issuable_finder_spec.rb b/spec/lib/gitlab/github_import/issuable_finder_spec.rb
index f009b61ad89..3afd006109b 100644
--- a/spec/lib/gitlab/github_import/issuable_finder_spec.rb
+++ b/spec/lib/gitlab/github_import/issuable_finder_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Gitlab::GithubImport::IssuableFinder, :clean_gitlab_redis_cache do
- let(:project) { double(:project, id: 4) }
+ let(:project) { double(:project, id: 4, group: nil) }
let(:issue) do
double(:issue, issuable_type: MergeRequest, iid: 1)
end
@@ -26,15 +26,77 @@ RSpec.describe Gitlab::GithubImport::IssuableFinder, :clean_gitlab_redis_cache d
expect { finder.database_id }.to raise_error(TypeError)
end
+
+ context 'when group is present' do
+ context 'when github_importer_single_endpoint_notes_import feature flag is enabled' do
+ it 'reads cache value with longer timeout' do
+ project = create(:project, import_url: 'http://t0ken@github.com/user/repo.git')
+ group = create(:group, projects: [project])
+
+ stub_feature_flags(github_importer_single_endpoint_notes_import: group)
+
+ expect(Gitlab::Cache::Import::Caching)
+ .to receive(:read)
+ .with(anything, timeout: Gitlab::Cache::Import::Caching::LONGER_TIMEOUT)
+
+ described_class.new(project, issue).database_id
+ end
+ end
+
+ context 'when github_importer_single_endpoint_notes_import feature flag is disabled' do
+ it 'reads cache value with default timeout' do
+ project = double(:project, id: 4, group: create(:group))
+
+ stub_feature_flags(github_importer_single_endpoint_notes_import: false)
+
+ expect(Gitlab::Cache::Import::Caching)
+ .to receive(:read)
+ .with(anything, timeout: Gitlab::Cache::Import::Caching::TIMEOUT)
+
+ described_class.new(project, issue).database_id
+ end
+ end
+ end
end
describe '#cache_database_id' do
it 'caches the ID of a database row' do
expect(Gitlab::Cache::Import::Caching)
.to receive(:write)
- .with('github-import/issuable-finder/4/MergeRequest/1', 10)
+ .with('github-import/issuable-finder/4/MergeRequest/1', 10, timeout: 86400)
finder.cache_database_id(10)
end
+
+ context 'when group is present' do
+ context 'when github_importer_single_endpoint_notes_import feature flag is enabled' do
+ it 'caches value with longer timeout' do
+ project = create(:project, import_url: 'http://t0ken@github.com/user/repo.git')
+ group = create(:group, projects: [project])
+
+ stub_feature_flags(github_importer_single_endpoint_notes_import: group)
+
+ expect(Gitlab::Cache::Import::Caching)
+ .to receive(:write)
+ .with(anything, anything, timeout: Gitlab::Cache::Import::Caching::LONGER_TIMEOUT)
+
+ described_class.new(project, issue).cache_database_id(10)
+ end
+ end
+
+ context 'when github_importer_single_endpoint_notes_import feature flag is disabled' do
+ it 'caches value with default timeout' do
+ project = double(:project, id: 4, group: create(:group))
+
+ stub_feature_flags(github_importer_single_endpoint_notes_import: false)
+
+ expect(Gitlab::Cache::Import::Caching)
+ .to receive(:write)
+ .with(anything, anything, timeout: Gitlab::Cache::Import::Caching::TIMEOUT)
+
+ described_class.new(project, issue).cache_database_id(10)
+ end
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/github_import/representation/diff_note_spec.rb b/spec/lib/gitlab/github_import/representation/diff_note_spec.rb
index 7e540674258..7c24cd0a5db 100644
--- a/spec/lib/gitlab/github_import/representation/diff_note_spec.rb
+++ b/spec/lib/gitlab/github_import/representation/diff_note_spec.rb
@@ -67,6 +67,7 @@ RSpec.describe Gitlab::GithubImport::Representation::DiffNote do
html_url: 'https://github.com/foo/bar/pull/42',
path: 'README.md',
commit_id: '123abc',
+ original_commit_id: 'original123abc',
diff_hunk: hunk,
user: double(:user, id: 4, login: 'alice'),
body: 'Hello world',
@@ -99,6 +100,7 @@ RSpec.describe Gitlab::GithubImport::Representation::DiffNote do
'noteable_id' => 42,
'file_path' => 'README.md',
'commit_id' => '123abc',
+ 'original_commit_id' => 'original123abc',
'diff_hunk' => hunk,
'author' => { 'id' => 4, 'login' => 'alice' },
'note' => 'Hello world',
@@ -117,6 +119,7 @@ RSpec.describe Gitlab::GithubImport::Representation::DiffNote do
'noteable_id' => 42,
'file_path' => 'README.md',
'commit_id' => '123abc',
+ 'original_commit_id' => 'original123abc',
'diff_hunk' => hunk,
'note' => 'Hello world',
'created_at' => created_at.to_s,
@@ -145,6 +148,7 @@ RSpec.describe Gitlab::GithubImport::Representation::DiffNote do
'noteable_id' => 42,
'file_path' => 'README.md',
'commit_id' => '123abc',
+ 'original_commit_id' => 'original123abc',
'diff_hunk' => hunk,
'author' => { 'id' => 4, 'login' => 'alice' },
'note' => 'Hello world',
diff --git a/spec/lib/gitlab/github_import/sequential_importer_spec.rb b/spec/lib/gitlab/github_import/sequential_importer_spec.rb
index a5e89049ed9..3c3f8ff59d0 100644
--- a/spec/lib/gitlab/github_import/sequential_importer_spec.rb
+++ b/spec/lib/gitlab/github_import/sequential_importer_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Gitlab::GithubImport::SequentialImporter do
describe '#execute' do
it 'imports a project in sequence' do
repository = double(:repository)
- project = double(:project, id: 1, repository: repository, import_url: 'http://t0ken@github.another-domain.com/repo-org/repo.git')
+ project = double(:project, id: 1, repository: repository, import_url: 'http://t0ken@github.another-domain.com/repo-org/repo.git', group: nil)
importer = described_class.new(project, token: 'foo')
expect_next_instance_of(Gitlab::GithubImport::Importer::RepositoryImporter) do |instance|
diff --git a/spec/lib/gitlab/github_import/user_finder_spec.rb b/spec/lib/gitlab/github_import/user_finder_spec.rb
index f81fa3b1e2e..8eb6eedd72d 100644
--- a/spec/lib/gitlab/github_import/user_finder_spec.rb
+++ b/spec/lib/gitlab/github_import/user_finder_spec.rb
@@ -195,7 +195,7 @@ RSpec.describe Gitlab::GithubImport::UserFinder, :clean_gitlab_redis_cache do
expect(Gitlab::Cache::Import::Caching)
.to receive(:write)
- .with(an_instance_of(String), email)
+ .with(an_instance_of(String), email, timeout: Gitlab::Cache::Import::Caching::TIMEOUT)
finder.email_for_github_username('kittens')
end
@@ -211,6 +211,16 @@ RSpec.describe Gitlab::GithubImport::UserFinder, :clean_gitlab_redis_cache do
expect(finder.email_for_github_username('kittens')).to be_nil
end
+
+ it 'shortens the timeout for Email address in cache when an Email address is private/nil from GitHub' do
+ user = double(:user, email: nil)
+ expect(client).to receive(:user).with('kittens').and_return(user)
+
+ expect(Gitlab::Cache::Import::Caching)
+ .to receive(:write).with(an_instance_of(String), nil, timeout: Gitlab::Cache::Import::Caching::SHORTER_TIMEOUT)
+
+ expect(finder.email_for_github_username('kittens')).to be_nil
+ end
end
end
diff --git a/spec/lib/gitlab/github_import_spec.rb b/spec/lib/gitlab/github_import_spec.rb
index 662757f66ad..1ea9f003098 100644
--- a/spec/lib/gitlab/github_import_spec.rb
+++ b/spec/lib/gitlab/github_import_spec.rb
@@ -3,13 +3,17 @@
require 'spec_helper'
RSpec.describe Gitlab::GithubImport do
+ before do
+ stub_feature_flags(github_importer_lower_per_page_limit: false)
+ end
+
context 'github.com' do
- let(:project) { double(:project, import_url: 'http://t0ken@github.com/user/repo.git', id: 1) }
+ let(:project) { double(:project, import_url: 'http://t0ken@github.com/user/repo.git', id: 1, group: nil) }
it 'returns a new Client with a custom token' do
expect(described_class::Client)
.to receive(:new)
- .with('123', host: nil, parallel: true)
+ .with('123', host: nil, parallel: true, per_page: 100)
described_class.new_client_for(project, token: '123')
end
@@ -23,7 +27,7 @@ RSpec.describe Gitlab::GithubImport do
expect(described_class::Client)
.to receive(:new)
- .with('123', host: nil, parallel: true)
+ .with('123', host: nil, parallel: true, per_page: 100)
described_class.new_client_for(project)
end
@@ -45,12 +49,12 @@ RSpec.describe Gitlab::GithubImport do
end
context 'GitHub Enterprise' do
- let(:project) { double(:project, import_url: 'http://t0ken@github.another-domain.com/repo-org/repo.git') }
+ let(:project) { double(:project, import_url: 'http://t0ken@github.another-domain.com/repo-org/repo.git', group: nil) }
it 'returns a new Client with a custom token' do
expect(described_class::Client)
.to receive(:new)
- .with('123', host: 'http://github.another-domain.com/api/v3', parallel: true)
+ .with('123', host: 'http://github.another-domain.com/api/v3', parallel: true, per_page: 100)
described_class.new_client_for(project, token: '123')
end
@@ -64,7 +68,7 @@ RSpec.describe Gitlab::GithubImport do
expect(described_class::Client)
.to receive(:new)
- .with('123', host: 'http://github.another-domain.com/api/v3', parallel: true)
+ .with('123', host: 'http://github.another-domain.com/api/v3', parallel: true, per_page: 100)
described_class.new_client_for(project)
end
@@ -88,4 +92,37 @@ RSpec.describe Gitlab::GithubImport do
expect(described_class.formatted_import_url(project)).to eq('http://github.another-domain.com/api/v3')
end
end
+
+ describe '.per_page' do
+ context 'when project group is present' do
+ context 'when github_importer_lower_per_page_limit is enabled' do
+ it 'returns lower per page value' do
+ project = create(:project, import_url: 'http://t0ken@github.com/user/repo.git')
+ group = create(:group, projects: [project])
+
+ stub_feature_flags(github_importer_lower_per_page_limit: group)
+
+ expect(described_class.per_page(project)).to eq(Gitlab::GithubImport::Client::LOWER_PER_PAGE)
+ end
+ end
+
+ context 'when github_importer_lower_per_page_limit is disabled' do
+ it 'returns default per page value' do
+ project = double(:project, import_url: 'http://t0ken@github.com/user/repo.git', id: 1, group: create(:group))
+
+ stub_feature_flags(github_importer_lower_per_page_limit: false)
+
+ expect(described_class.per_page(project)).to eq(Gitlab::GithubImport::Client::DEFAULT_PER_PAGE)
+ end
+ end
+ end
+
+ context 'when project group is missing' do
+ it 'returns default per page value' do
+ project = double(:project, import_url: 'http://t0ken@github.com/user/repo.git', id: 1, group: nil)
+
+ expect(described_class.per_page(project)).to eq(Gitlab::GithubImport::Client::DEFAULT_PER_PAGE)
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index 2b7138a7a10..614aa55c3c5 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -58,6 +58,7 @@ issues:
- test_reports
- requirement
- incident_management_issuable_escalation_status
+- pending_escalations
work_item_type:
- issues
events:
@@ -223,6 +224,7 @@ ci_pipelines:
- builds
- bridges
- processables
+- generic_commit_statuses
- trigger_requests
- variables
- auto_canceled_by
@@ -318,6 +320,7 @@ integrations:
- project
- service_hook
- jira_tracker_data
+- zentao_tracker_data
- issue_tracker_data
- open_project_tracker_data
hooks:
@@ -354,6 +357,8 @@ project:
- taggings
- base_tags
- topic_taggings
+- topics_acts_as_taggable
+- project_topics
- topics
- chat_services
- cluster
@@ -365,6 +370,7 @@ project:
- value_streams
- group
- namespace
+- project_namespace
- management_clusters
- boards
- last_event
@@ -395,6 +401,7 @@ project:
- teamcity_integration
- pushover_integration
- jira_integration
+- zentao_integration
- redmine_integration
- youtrack_integration
- custom_issue_tracker_integration
@@ -583,6 +590,9 @@ project:
- timelogs
- error_tracking_errors
- error_tracking_client_keys
+- pending_builds
+- security_scans
+- ci_feature_usages
award_emoji:
- awardable
- user
@@ -673,6 +683,7 @@ boards:
- destroyable_lists
- milestone
- iteration
+- iteration_cadence
- board_labels
- board_assignee
- assignee
@@ -762,3 +773,5 @@ push_rule:
- group
bulk_import_export:
- group
+service_desk_setting:
+ - file_template_project
diff --git a/spec/lib/gitlab/import_export/attributes_permitter_spec.rb b/spec/lib/gitlab/import_export/attributes_permitter_spec.rb
index 0c1b1cd74bf..36a831a785c 100644
--- a/spec/lib/gitlab/import_export/attributes_permitter_spec.rb
+++ b/spec/lib/gitlab/import_export/attributes_permitter_spec.rb
@@ -74,4 +74,73 @@ RSpec.describe Gitlab::ImportExport::AttributesPermitter do
expect(subject.permitted_attributes_for(:labels)).to contain_exactly(:title, :description, :type, :priorities)
end
end
+
+ describe '#permitted_attributes_defined?' do
+ using RSpec::Parameterized::TableSyntax
+
+ let(:attributes_permitter) { described_class.new }
+
+ where(:relation_name, :permitted_attributes_defined) do
+ :user | false
+ :author | false
+ :ci_cd_settings | false
+ :issuable_sla | false
+ :push_rule | false
+ :metrics_setting | true
+ :project_badges | true
+ :pipeline_schedules | true
+ :error_tracking_setting | true
+ :auto_devops | true
+ end
+
+ with_them do
+ it { expect(attributes_permitter.permitted_attributes_defined?(relation_name)).to eq(permitted_attributes_defined) }
+ end
+ end
+
+ describe 'included_attributes for Project' do
+ let(:prohibited_attributes) { %i[remote_url my_attributes my_ids token my_id test] }
+
+ subject { described_class.new }
+
+ Gitlab::ImportExport::Config.new.to_h[:included_attributes].each do |relation_sym, permitted_attributes|
+ context "for #{relation_sym}" do
+ let(:import_export_config) { Gitlab::ImportExport::Config.new.to_h }
+ let(:project_relation_factory) { Gitlab::ImportExport::Project::RelationFactory }
+
+ let(:relation_hash) { (permitted_attributes + prohibited_attributes).map(&:to_s).zip([]).to_h }
+ let(:relation_name) { project_relation_factory.overrides[relation_sym]&.to_sym || relation_sym }
+ let(:relation_class) { project_relation_factory.relation_class(relation_name) }
+ let(:excluded_keys) { import_export_config.dig(:excluded_keys, relation_sym) || [] }
+
+ let(:cleaned_hash) do
+ Gitlab::ImportExport::AttributeCleaner.new(
+ relation_hash: relation_hash,
+ relation_class: relation_class,
+ excluded_keys: excluded_keys
+ ).clean
+ end
+
+ let(:permitted_hash) { subject.permit(relation_sym, relation_hash) }
+
+ if described_class.new.permitted_attributes_defined?(relation_sym)
+ it 'contains only attributes that are defined as permitted in the import/export config' do
+ expect(permitted_hash.keys).to contain_exactly(*permitted_attributes.map(&:to_s))
+ end
+
+ it 'does not contain attributes that would be cleaned with AttributeCleaner' do
+ expect(cleaned_hash.keys).to include(*permitted_hash.keys)
+ end
+
+ it 'does not contain prohibited attributes that are not related to given relation' do
+ expect(permitted_hash.keys).not_to include(*prohibited_attributes.map(&:to_s))
+ end
+ else
+ it 'is disabled' do
+ expect(subject).not_to be_permitted_attributes_defined(relation_sym)
+ end
+ end
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index 77d126e012e..a9efa32f986 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -167,6 +167,7 @@ ProjectMember:
- expires_at
- ldap
- override
+- invite_email_success
User:
- id
- username
@@ -761,6 +762,7 @@ Board:
- group_id
- milestone_id
- iteration_id
+- iteration_cadence_id
- weight
- name
- hide_backlog_list
diff --git a/spec/lib/gitlab/instrumentation/redis_interceptor_spec.rb b/spec/lib/gitlab/instrumentation/redis_interceptor_spec.rb
index cd1828791c3..b2a11353d0c 100644
--- a/spec/lib/gitlab/instrumentation/redis_interceptor_spec.rb
+++ b/spec/lib/gitlab/instrumentation/redis_interceptor_spec.rb
@@ -130,15 +130,25 @@ RSpec.describe Gitlab::Instrumentation::RedisInterceptor, :clean_gitlab_redis_sh
end
context 'when report_on_long_redis_durations is enabled' do
- it 'tracks an exception and continues' do
- expect(Gitlab::ErrorTracking)
- .to receive(:track_exception)
- .with(an_instance_of(described_class::MysteryRedisDurationError),
- command: 'mget',
- duration: be > threshold,
- timestamp: a_string_matching(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{5}/))
+ context 'for an instance other than SharedState' do
+ it 'does nothing' do
+ expect(Gitlab::ErrorTracking).not_to receive(:track_exception)
- Gitlab::Redis::SharedState.with { |r| r.mget('foo', 'foo') { sleep threshold + 0.1 } }
+ Gitlab::Redis::Queues.with { |r| r.mget('foo', 'foo') { sleep threshold + 0.1 } }
+ end
+ end
+
+ context 'for the SharedState instance' do
+ it 'tracks an exception and continues' do
+ expect(Gitlab::ErrorTracking)
+ .to receive(:track_exception)
+ .with(an_instance_of(described_class::MysteryRedisDurationError),
+ command: 'mget',
+ duration: be > threshold,
+ timestamp: a_string_matching(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{5}/))
+
+ Gitlab::Redis::SharedState.with { |r| r.mget('foo', 'foo') { sleep threshold + 0.1 } }
+ end
end
end
end
diff --git a/spec/lib/gitlab/instrumentation/redis_spec.rb b/spec/lib/gitlab/instrumentation/redis_spec.rb
index 6cddf958f2a..ebc2e92a0dd 100644
--- a/spec/lib/gitlab/instrumentation/redis_spec.rb
+++ b/spec/lib/gitlab/instrumentation/redis_spec.rb
@@ -28,6 +28,13 @@ RSpec.describe Gitlab::Instrumentation::Redis do
describe '.payload', :request_store do
before do
+ # If this is the first spec in a spec run that uses Redis, there
+ # will be an extra SELECT command to choose the right database. We
+ # don't want to make the spec less precise, so we force that to
+ # happen (if needed) first, then clear the counts.
+ Gitlab::Redis::Cache.with { |redis| redis.info }
+ RequestStore.clear!
+
Gitlab::Redis::Cache.with { |redis| redis.set('cache-test', 321) }
Gitlab::Redis::SharedState.with { |redis| redis.set('shared-state-test', 123) }
end
diff --git a/spec/lib/gitlab/issuables_count_for_state_spec.rb b/spec/lib/gitlab/issuables_count_for_state_spec.rb
index a6170c146ab..cc4ebba863d 100644
--- a/spec/lib/gitlab/issuables_count_for_state_spec.rb
+++ b/spec/lib/gitlab/issuables_count_for_state_spec.rb
@@ -66,4 +66,106 @@ RSpec.describe Gitlab::IssuablesCountForState do
end
end
end
+
+ context 'when store_in_redis_cache is `true`', :clean_gitlab_redis_cache do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+
+ let(:cache_options) { { expires_in: 1.hour } }
+ let(:cache_key) { ['group', group.id, 'issues'] }
+ let(:threshold) { described_class::THRESHOLD }
+ let(:states_count) { { opened: 1, closed: 1, all: 2 } }
+ let(:params) { {} }
+
+ subject { described_class.new(finder, fast_fail: true, store_in_redis_cache: true ) }
+
+ before do
+ allow(finder).to receive(:count_by_state).and_return(states_count)
+ allow_next_instance_of(described_class) do |counter|
+ allow(counter).to receive(:parent_group).and_return(group)
+ end
+ end
+
+ shared_examples 'calculating counts without caching' do
+ it 'does not store in redis store' do
+ expect(Rails.cache).not_to receive(:read)
+ expect(finder).to receive(:count_by_state)
+ expect(Rails.cache).not_to receive(:write)
+ expect(subject[:all]).to eq(states_count[:all])
+ end
+ end
+
+ context 'with Issues' do
+ let(:finder) { IssuesFinder.new(user, params) }
+
+ it 'returns -1 for the requested state' do
+ allow(finder).to receive(:count_by_state).and_raise(ActiveRecord::QueryCanceled)
+ expect(Rails.cache).not_to receive(:write)
+
+ expect(subject[:all]).to eq(-1)
+ end
+
+ context 'when parent group is not present' do
+ let(:group) { nil }
+
+ it_behaves_like 'calculating counts without caching'
+ end
+
+ context 'when params include search filters' do
+ let(:parent) { group }
+
+ before do
+ finder.params[:assignee_username] = [user.username, 'root']
+ end
+
+ it_behaves_like 'calculating counts without caching'
+ end
+
+ context 'when counts are stored in cache' do
+ before do
+ allow(Rails.cache).to receive(:read).with(cache_key, cache_options)
+ .and_return({ opened: 1000, closed: 1000, all: 2000 })
+ end
+
+ it 'does not call finder count_by_state' do
+ expect(finder).not_to receive(:count_by_state)
+
+ expect(subject[:all]).to eq(2000)
+ end
+ end
+
+ context 'when cache is empty' do
+ context 'when state counts are under threshold' do
+ let(:states_count) { { opened: 1, closed: 1, all: 2 } }
+
+ it 'does not store state counts in cache' do
+ expect(Rails.cache).to receive(:read).with(cache_key, cache_options)
+ expect(finder).to receive(:count_by_state)
+ expect(Rails.cache).not_to receive(:write)
+ expect(subject[:all]).to eq(states_count[:all])
+ end
+ end
+
+ context 'when state counts are over threshold' do
+ let(:states_count) do
+ { opened: threshold + 1, closed: threshold + 1, all: (threshold + 1) * 2 }
+ end
+
+ it 'stores state counts in cache' do
+ expect(Rails.cache).to receive(:read).with(cache_key, cache_options)
+ expect(finder).to receive(:count_by_state)
+ expect(Rails.cache).to receive(:write).with(cache_key, states_count, cache_options)
+
+ expect(subject[:all]).to eq((threshold + 1) * 2)
+ end
+ end
+ end
+ end
+
+ context 'with Merge Requests' do
+ let(:finder) { MergeRequestsFinder.new(user, params) }
+
+ it_behaves_like 'calculating counts without caching'
+ end
+ end
end
diff --git a/spec/lib/gitlab/issues/rebalancing/state_spec.rb b/spec/lib/gitlab/issues/rebalancing/state_spec.rb
new file mode 100644
index 00000000000..bdd0dbd365d
--- /dev/null
+++ b/spec/lib/gitlab/issues/rebalancing/state_spec.rb
@@ -0,0 +1,223 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Issues::Rebalancing::State, :clean_gitlab_redis_shared_state do
+ shared_examples 'issues rebalance caching' do
+ describe '#track_new_running_rebalance' do
+ it 'caches a project id to track caching in progress' do
+ expect { rebalance_caching.track_new_running_rebalance }.to change { rebalance_caching.concurrent_running_rebalances_count }.from(0).to(1)
+ end
+ end
+
+ describe '#set and get current_index' do
+ it 'returns zero as current index when index not cached' do
+ expect(rebalance_caching.get_current_index).to eq(0)
+ end
+
+ it 'returns cached current index' do
+ expect { rebalance_caching.cache_current_index(123) }.to change { rebalance_caching.get_current_index }.from(0).to(123)
+ end
+ end
+
+ describe '#set and get current_project' do
+ it 'returns nil if there is no project_id cached' do
+ expect(rebalance_caching.get_current_project_id).to be_nil
+ end
+
+ it 'returns cached current project_id' do
+ expect { rebalance_caching.cache_current_project_id(456) }.to change { rebalance_caching.get_current_project_id }.from(nil).to('456')
+ end
+ end
+
+ describe "#rebalance_in_progress?" do
+ it 'return zero if no re-balances are running' do
+ expect(rebalance_caching.concurrent_running_rebalances_count).to eq(0)
+ end
+
+ it 'return false if no re-balances are running' do
+ expect(rebalance_caching.rebalance_in_progress?).to be false
+ end
+
+ it 'return true a re-balance for given project/namespace is running' do
+ rebalance_caching.track_new_running_rebalance
+
+ expect(rebalance_caching.rebalance_in_progress?).to be true
+ end
+ end
+
+ context 'caching issue ids' do
+ context 'with no issue ids cached' do
+ it 'returns zero when there are no cached issue ids' do
+ expect(rebalance_caching.issue_count).to eq(0)
+ end
+
+ it 'returns empty array when there are no cached issue ids' do
+ expect(rebalance_caching.get_cached_issue_ids(0, 100)).to eq([])
+ end
+ end
+
+ context 'with cached issue ids' do
+ before do
+ generate_and_cache_issues_ids(count: 3)
+ end
+
+ it 'returns count of cached issue ids' do
+ expect(rebalance_caching.issue_count).to eq(3)
+ end
+
+ it 'returns array of issue ids' do
+ expect(rebalance_caching.get_cached_issue_ids(0, 100)).to eq(%w(1 2 3))
+ end
+
+ it 'limits returned values' do
+ expect(rebalance_caching.get_cached_issue_ids(0, 2)).to eq(%w(1 2))
+ end
+
+ context 'when caching duplicate issue_ids' do
+ before do
+ generate_and_cache_issues_ids(count: 3, position_offset: 3, position_direction: -1)
+ end
+
+ it 'does not cache duplicate issues' do
+ expect(rebalance_caching.issue_count).to eq(3)
+ end
+
+ it 'returns cached issues with latest scores' do
+ expect(rebalance_caching.get_cached_issue_ids(0, 100)).to eq(%w(3 2 1))
+ end
+ end
+ end
+ end
+
+ context 'when setting expiration' do
+ context 'when tracking new rebalance' do
+ it 'returns as expired for non existent key' do
+ ::Gitlab::Redis::SharedState.with do |redis|
+ expect(redis.ttl(rebalance_caching.send(:concurrent_running_rebalances_key))).to be < 0
+ end
+ end
+
+ it 'has expiration set' do
+ rebalance_caching.track_new_running_rebalance
+
+ ::Gitlab::Redis::SharedState.with do |redis|
+ expect(redis.ttl(rebalance_caching.send(:concurrent_running_rebalances_key))).to be_between(0, described_class::REDIS_EXPIRY_TIME.ago.to_i)
+ end
+ end
+ end
+
+ context 'when setting current index' do
+ it 'returns as expiring for non existent key' do
+ ::Gitlab::Redis::SharedState.with do |redis|
+ expect(redis.ttl(rebalance_caching.send(:current_index_key))).to be < 0
+ end
+ end
+
+ it 'has expiration set' do
+ rebalance_caching.cache_current_index(123)
+
+ ::Gitlab::Redis::SharedState.with do |redis|
+ expect(redis.ttl(rebalance_caching.send(:current_index_key))).to be_between(0, described_class::REDIS_EXPIRY_TIME.ago.to_i)
+ end
+ end
+ end
+
+ context 'when setting current project id' do
+ it 'returns as expired for non existent key' do
+ ::Gitlab::Redis::SharedState.with do |redis|
+ expect(redis.ttl(rebalance_caching.send(:current_project_key))).to be < 0
+ end
+ end
+
+ it 'has expiration set' do
+ rebalance_caching.cache_current_project_id(456)
+
+ ::Gitlab::Redis::SharedState.with do |redis|
+ expect(redis.ttl(rebalance_caching.send(:current_project_key))).to be_between(0, described_class::REDIS_EXPIRY_TIME.ago.to_i)
+ end
+ end
+ end
+
+ context 'when setting cached issue ids' do
+ it 'returns as expired for non existent key' do
+ ::Gitlab::Redis::SharedState.with do |redis|
+ expect(redis.ttl(rebalance_caching.send(:issue_ids_key))).to be < 0
+ end
+ end
+
+ it 'has expiration set' do
+ generate_and_cache_issues_ids(count: 3)
+
+ ::Gitlab::Redis::SharedState.with do |redis|
+ expect(redis.ttl(rebalance_caching.send(:issue_ids_key))).to be_between(0, described_class::REDIS_EXPIRY_TIME.ago.to_i)
+ end
+ end
+ end
+ end
+
+ context 'cleanup cache' do
+ before do
+ generate_and_cache_issues_ids(count: 3)
+ rebalance_caching.cache_current_index(123)
+ rebalance_caching.cache_current_project_id(456)
+ rebalance_caching.track_new_running_rebalance
+ end
+
+ it 'removes cache keys' do
+ expect(check_existing_keys).to eq(4)
+
+ rebalance_caching.cleanup_cache
+
+ expect(check_existing_keys).to eq(0)
+ end
+ end
+ end
+
+ context 'rebalancing issues in namespace' do
+ let_it_be(:group) { create(:group, :private) }
+ let_it_be(:project) { create(:project, namespace: group) }
+
+ subject(:rebalance_caching) { described_class.new(group, group.projects) }
+
+ it { expect(rebalance_caching.send(:rebalanced_container_type)).to eq(described_class::NAMESPACE) }
+
+ it_behaves_like 'issues rebalance caching'
+ end
+
+ context 'rebalancing issues in a project' do
+ let_it_be(:project) { create(:project) }
+
+ subject(:rebalance_caching) { described_class.new(project.namespace, Project.where(id: project)) }
+
+ it { expect(rebalance_caching.send(:rebalanced_container_type)).to eq(described_class::PROJECT) }
+
+ it_behaves_like 'issues rebalance caching'
+ end
+
+ # count - how many issue ids to generate, issue ids will start at 1
+ # position_offset - if you'd want to offset generated relative_position for the issue ids,
+ # relative_position is generated as = issue id * 10 + position_offset
+ # position_direction - (1) for positive relative_positions, (-1) for negative relative_positions
+ def generate_and_cache_issues_ids(count:, position_offset: 0, position_direction: 1)
+ issues = []
+
+ count.times do |idx|
+ id = idx + 1
+ issues << double(relative_position: position_direction * (id * 10 + position_offset), id: id)
+ end
+
+ rebalance_caching.cache_issue_ids(issues)
+ end
+
+ def check_existing_keys
+ index = 0
+
+ index += 1 if rebalance_caching.get_current_index > 0
+ index += 1 if rebalance_caching.get_current_project_id.present?
+ index += 1 if rebalance_caching.get_cached_issue_ids(0, 100).present?
+ index += 1 if rebalance_caching.rebalance_in_progress?
+
+ index
+ end
+end
diff --git a/spec/lib/gitlab/kas/client_spec.rb b/spec/lib/gitlab/kas/client_spec.rb
index 40e18f58ee4..5b89023cc13 100644
--- a/spec/lib/gitlab/kas/client_spec.rb
+++ b/spec/lib/gitlab/kas/client_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe Gitlab::Kas::Client do
let_it_be(:project) { create(:project) }
+ let_it_be(:agent) { create(:cluster_agent, project: project) }
describe '#initialize' do
context 'kas is not enabled' do
@@ -44,6 +45,32 @@ RSpec.describe Gitlab::Kas::Client do
expect(token).to receive(:audience=).with(described_class::JWT_AUDIENCE)
end
+ describe '#get_connected_agents' do
+ let(:stub) { instance_double(Gitlab::Agent::AgentTracker::Rpc::AgentTracker::Stub) }
+ let(:request) { instance_double(Gitlab::Agent::AgentTracker::Rpc::GetConnectedAgentsRequest) }
+ let(:response) { double(Gitlab::Agent::AgentTracker::Rpc::GetConnectedAgentsResponse, agents: connected_agents) }
+
+ let(:connected_agents) { [double] }
+
+ subject { described_class.new.get_connected_agents(project: project) }
+
+ before do
+ expect(Gitlab::Agent::AgentTracker::Rpc::AgentTracker::Stub).to receive(:new)
+ .with('example.kas.internal', :this_channel_is_insecure, timeout: described_class::TIMEOUT)
+ .and_return(stub)
+
+ expect(Gitlab::Agent::AgentTracker::Rpc::GetConnectedAgentsRequest).to receive(:new)
+ .with(project_id: project.id)
+ .and_return(request)
+
+ expect(stub).to receive(:get_connected_agents)
+ .with(request, metadata: { 'authorization' => 'bearer test-token' })
+ .and_return(response)
+ end
+
+ it { expect(subject).to eq(connected_agents) }
+ end
+
describe '#list_agent_config_files' do
let(:stub) { instance_double(Gitlab::Agent::ConfigurationProject::Rpc::ConfigurationProject::Stub) }
diff --git a/spec/lib/gitlab/middleware/sidekiq_web_static_spec.rb b/spec/lib/gitlab/middleware/sidekiq_web_static_spec.rb
new file mode 100644
index 00000000000..e6815a46a56
--- /dev/null
+++ b/spec/lib/gitlab/middleware/sidekiq_web_static_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Middleware::SidekiqWebStatic do
+ let(:app) { double(:app) }
+ let(:middleware) { described_class.new(app) }
+ let(:env) { {} }
+
+ describe '#call' do
+ before do
+ env['HTTP_X_SENDFILE_TYPE'] = 'X-Sendfile'
+ env['PATH_INFO'] = path
+ end
+
+ context 'with an /admin/sidekiq route' do
+ let(:path) { '/admin/sidekiq/javascripts/application.js'}
+
+ it 'deletes the HTTP_X_SENDFILE_TYPE header' do
+ expect(app).to receive(:call)
+
+ middleware.call(env)
+
+ expect(env['HTTP_X_SENDFILE_TYPE']).to be_nil
+ end
+ end
+
+ context 'with some static asset route' do
+ let(:path) { '/assets/test.png' }
+
+ it 'keeps the HTTP_X_SENDFILE_TYPE header' do
+ expect(app).to receive(:call)
+
+ middleware.call(env)
+
+ expect(env['HTTP_X_SENDFILE_TYPE']).to eq('X-Sendfile')
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/pagination/cursor_based_keyset_spec.rb b/spec/lib/gitlab/pagination/cursor_based_keyset_spec.rb
new file mode 100644
index 00000000000..ac2695977c4
--- /dev/null
+++ b/spec/lib/gitlab/pagination/cursor_based_keyset_spec.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Pagination::CursorBasedKeyset do
+ subject { described_class }
+
+ describe '.available_for_type?' do
+ it 'returns true for Group' do
+ expect(subject.available_for_type?(Group.all)).to be_truthy
+ end
+
+ it 'return false for other types of relations' do
+ expect(subject.available_for_type?(User.all)).to be_falsey
+ end
+ end
+
+ describe '.available?' do
+ let(:request_context) { double('request_context', params: { order_by: order_by, sort: sort }) }
+ let(:cursor_based_request_context) { Gitlab::Pagination::Keyset::CursorBasedRequestContext.new(request_context) }
+
+ context 'with order-by name asc' do
+ let(:order_by) { :name }
+ let(:sort) { :asc }
+
+ it 'returns true for Group' do
+ expect(subject.available?(cursor_based_request_context, Group.all)).to be_truthy
+ end
+
+ it 'return false for other types of relations' do
+ expect(subject.available?(cursor_based_request_context, User.all)).to be_falsey
+ end
+ end
+
+ context 'with other order-by columns' do
+ let(:order_by) { :path }
+ let(:sort) { :asc }
+
+ it 'returns false for Group' do
+ expect(subject.available?(cursor_based_request_context, Group.all)).to be_falsey
+ end
+
+ it 'return false for other types of relations' do
+ expect(subject.available?(cursor_based_request_context, User.all)).to be_falsey
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/pagination/gitaly_keyset_pager_spec.rb b/spec/lib/gitlab/pagination/gitaly_keyset_pager_spec.rb
index 8a26e153385..dcb8138bdde 100644
--- a/spec/lib/gitlab/pagination/gitaly_keyset_pager_spec.rb
+++ b/spec/lib/gitlab/pagination/gitaly_keyset_pager_spec.rb
@@ -74,7 +74,7 @@ RSpec.describe Gitlab::Pagination::GitalyKeysetPager do
allow(request_context).to receive(:request).and_return(fake_request)
allow(project.repository).to receive(:branch_count).and_return(branches.size)
- expect(finder).to receive(:execute).with(gitaly_pagination: true).and_return(branches)
+ expect(finder).to receive(:execute).and_return(branches)
expect(request_context).to receive(:header).with('X-Per-Page', '2')
expect(request_context).to receive(:header).with('X-Page', '1')
expect(request_context).to receive(:header).with('X-Next-Page', '2')
@@ -99,6 +99,7 @@ RSpec.describe Gitlab::Pagination::GitalyKeysetPager do
before do
allow(request_context).to receive(:request).and_return(fake_request)
+ allow(finder).to receive(:is_a?).with(BranchesFinder) { true }
expect(finder).to receive(:execute).with(gitaly_pagination: true).and_return(branches)
end
diff --git a/spec/lib/gitlab/pagination/keyset/column_order_definition_spec.rb b/spec/lib/gitlab/pagination/keyset/column_order_definition_spec.rb
index 6e9e987f90c..69384e0c501 100644
--- a/spec/lib/gitlab/pagination/keyset/column_order_definition_spec.rb
+++ b/spec/lib/gitlab/pagination/keyset/column_order_definition_spec.rb
@@ -185,4 +185,25 @@ RSpec.describe Gitlab::Pagination::Keyset::ColumnOrderDefinition do
end
end
end
+
+ describe "#order_direction_as_sql_string" do
+ let(:nulls_last_order) do
+ described_class.new(
+ attribute_name: :name,
+ column_expression: Project.arel_table[:name],
+ order_expression: Gitlab::Database.nulls_last_order('merge_request_metrics.merged_at', :desc),
+ reversed_order_expression: Gitlab::Database.nulls_first_order('merge_request_metrics.merged_at', :asc),
+ order_direction: :desc,
+ nullable: :nulls_last, # null values are always last
+ distinct: false
+ )
+ end
+
+ it { expect(project_name_column.order_direction_as_sql_string).to eq('ASC') }
+ it { expect(project_name_column.reverse.order_direction_as_sql_string).to eq('DESC') }
+ it { expect(project_name_lower_column.order_direction_as_sql_string).to eq('DESC') }
+ it { expect(project_name_lower_column.reverse.order_direction_as_sql_string).to eq('ASC') }
+ it { expect(nulls_last_order.order_direction_as_sql_string).to eq('DESC NULLS LAST') }
+ it { expect(nulls_last_order.reverse.order_direction_as_sql_string).to eq('ASC NULLS FIRST') }
+ end
end
diff --git a/spec/lib/gitlab/pagination/keyset/cursor_based_request_context_spec.rb b/spec/lib/gitlab/pagination/keyset/cursor_based_request_context_spec.rb
new file mode 100644
index 00000000000..79de6f230ec
--- /dev/null
+++ b/spec/lib/gitlab/pagination/keyset/cursor_based_request_context_spec.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Pagination::Keyset::CursorBasedRequestContext do
+ let(:params) { { per_page: 2, cursor: 'eyJuYW1lIjoiR2l0TGFiIEluc3RhbmNlIiwiaWQiOiI1MiIsIl9rZCI6Im4ifQ==', order_by: :name, sort: :asc } }
+ let(:request) { double('request', url: 'http://localhost') }
+ let(:request_context) { double('request_context', header: nil, params: params, request: request) }
+
+ describe '#per_page' do
+ subject(:per_page) { described_class.new(request_context).per_page }
+
+ it { is_expected.to eq 2 }
+ end
+
+ describe '#cursor' do
+ subject(:cursor) { described_class.new(request_context).cursor }
+
+ it { is_expected.to eq 'eyJuYW1lIjoiR2l0TGFiIEluc3RhbmNlIiwiaWQiOiI1MiIsIl9rZCI6Im4ifQ==' }
+ end
+
+ describe '#order_by' do
+ subject(:order_by) { described_class.new(request_context).order_by }
+
+ it { is_expected.to eq({ name: :asc }) }
+ end
+
+ describe '#apply_headers' do
+ let(:request) { double('request', url: "http://#{Gitlab.config.gitlab.host}/api/v4/projects?per_page=3") }
+ let(:params) { { per_page: 3 } }
+ let(:request_context) { double('request_context', header: nil, params: params, request: request) }
+ let(:cursor_for_next_page) { 'eyJuYW1lIjoiSDVicCIsImlkIjoiMjgiLCJfa2QiOiJuIn0=' }
+
+ subject(:apply_headers) { described_class.new(request_context).apply_headers(cursor_for_next_page) }
+
+ it 'sets Link header with same host/path as the original request' do
+ orig_uri = URI.parse(request_context.request.url)
+
+ expect(request_context).to receive(:header).once do |name, header|
+ first_link, _ = /<([^>]+)>; rel="next"/.match(header).captures
+
+ uri = URI.parse(first_link)
+
+ expect(name).to eq('Link')
+ expect(uri.host).to eq(orig_uri.host)
+ expect(uri.path).to eq(orig_uri.path)
+ end
+
+ apply_headers
+ end
+
+ it 'sets Link header with a cursor to the next page' do
+ orig_uri = URI.parse(request_context.request.url)
+
+ expect(request_context).to receive(:header).once do |name, header|
+ first_link, _ = /<([^>]+)>; rel="next"/.match(header).captures
+
+ query = CGI.parse(URI.parse(first_link).query)
+
+ expect(name).to eq('Link')
+ expect(query.except('cursor')).to eq(CGI.parse(orig_uri.query).except('cursor'))
+ expect(query['cursor']).to eq([cursor_for_next_page])
+ end
+
+ apply_headers
+ end
+ end
+end
diff --git a/spec/lib/gitlab/pagination/keyset/cursor_pager_spec.rb b/spec/lib/gitlab/pagination/keyset/cursor_pager_spec.rb
new file mode 100644
index 00000000000..783e728b34c
--- /dev/null
+++ b/spec/lib/gitlab/pagination/keyset/cursor_pager_spec.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Pagination::Keyset::CursorPager do
+ let(:relation) { Group.all.order(:name, :id) }
+ let(:per_page) { 3 }
+ let(:params) { { cursor: nil, per_page: per_page } }
+ let(:request_context) { double('request_context', params: params) }
+ let(:cursor_based_request_context) { Gitlab::Pagination::Keyset::CursorBasedRequestContext.new(request_context) }
+
+ before_all do
+ create_list(:group, 7)
+ end
+
+ describe '#paginate' do
+ subject(:paginated_result) { described_class.new(cursor_based_request_context).paginate(relation) }
+
+ it 'returns the limited relation' do
+ expect(paginated_result).to eq(relation.limit(per_page))
+ end
+ end
+
+ describe '#finalize' do
+ subject(:finalize) do
+ service = described_class.new(cursor_based_request_context)
+ # we need to do this because `finalize` can only be called
+ # after `paginate` is called. Otherwise the `paginator` object won't be set.
+ service.paginate(relation)
+ service.finalize
+ end
+
+ it 'passes information about next page to request' do
+ cursor_for_next_page = relation.keyset_paginate(**params).cursor_for_next_page
+
+ expect_next_instance_of(Gitlab::Pagination::Keyset::HeaderBuilder, request_context) do |builder|
+ expect(builder).to receive(:add_next_page_header).with({ cursor: cursor_for_next_page })
+ end
+
+ finalize
+ end
+
+ context 'when retrieving the last page' do
+ let(:relation) { Group.where('id > ?', Group.maximum(:id) - per_page).order(:name, :id) }
+
+ it 'does not build information about the next page' do
+ expect(Gitlab::Pagination::Keyset::HeaderBuilder).not_to receive(:new)
+
+ finalize
+ end
+ end
+
+ context 'when retrieving an empty page' do
+ let(:relation) { Group.where('id > ?', Group.maximum(:id) + 1).order(:name, :id) }
+
+ it 'does not build information about the next page' do
+ expect(Gitlab::Pagination::Keyset::HeaderBuilder).not_to receive(:new)
+
+ finalize
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/pagination/keyset/in_operator_optimization/array_scope_columns_spec.rb b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/array_scope_columns_spec.rb
new file mode 100644
index 00000000000..2cebf0d9473
--- /dev/null
+++ b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/array_scope_columns_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Pagination::Keyset::InOperatorOptimization::ArrayScopeColumns do
+ let(:columns) { [:relative_position, :id] }
+
+ subject(:array_scope_columns) { described_class.new(columns) }
+
+ it 'builds array column names' do
+ expect(array_scope_columns.array_aggregated_column_names).to eq(%w[array_cte_relative_position_array array_cte_id_array])
+ end
+
+ context 'when no columns are given' do
+ let(:columns) { [] }
+
+ it { expect { array_scope_columns }.to raise_error /No array columns were given/ }
+ end
+end
diff --git a/spec/lib/gitlab/pagination/keyset/in_operator_optimization/column_data_spec.rb b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/column_data_spec.rb
new file mode 100644
index 00000000000..4f200c9096f
--- /dev/null
+++ b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/column_data_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Pagination::Keyset::InOperatorOptimization::ColumnData do
+ subject(:column_data) { described_class.new('id', 'issue_id', Issue.arel_table) }
+
+ describe '#array_aggregated_column_name' do
+ it { expect(column_data.array_aggregated_column_name).to eq('issues_id_array') }
+ end
+
+ describe '#projection' do
+ it 'returns the Arel projection for the column with a new alias' do
+ expect(column_data.projection.to_sql).to eq('"issues"."id" AS issue_id')
+ end
+ end
+
+ it 'accepts symbols for original_column_name and as' do
+ column_data = described_class.new(:id, :issue_id, Issue.arel_table)
+
+ expect(column_data.projection.to_sql).to eq('"issues"."id" AS issue_id')
+ end
+end
diff --git a/spec/lib/gitlab/pagination/keyset/in_operator_optimization/order_by_columns_spec.rb b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/order_by_columns_spec.rb
new file mode 100644
index 00000000000..f4fa14e2261
--- /dev/null
+++ b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/order_by_columns_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Pagination::Keyset::InOperatorOptimization::OrderByColumns do
+ let(:columns) do
+ [
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: :relative_position,
+ order_expression: Issue.arel_table[:relative_position].desc
+ ),
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: :id,
+ order_expression: Issue.arel_table[:id].desc
+ )
+ ]
+ end
+
+ subject(:order_by_columns) { described_class.new(columns, Issue.arel_table) }
+
+ describe '#array_aggregated_column_names' do
+ it { expect(order_by_columns.array_aggregated_column_names).to eq(%w[issues_relative_position_array issues_id_array]) }
+ end
+
+ describe '#original_column_names' do
+ it { expect(order_by_columns.original_column_names).to eq(%w[relative_position id]) }
+ end
+
+ describe '#cursor_values' do
+ it 'returns the keyset pagination cursor values from the column arrays as SQL expression' do
+ expect(order_by_columns.cursor_values('tbl')).to eq({
+ "id" => "tbl.issues_id_array[position]",
+ "relative_position" => "tbl.issues_relative_position_array[position]"
+ })
+ end
+ end
+end
diff --git a/spec/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder_spec.rb b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder_spec.rb
new file mode 100644
index 00000000000..4ce51e37685
--- /dev/null
+++ b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder_spec.rb
@@ -0,0 +1,225 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Pagination::Keyset::InOperatorOptimization::QueryBuilder do
+ let_it_be(:two_weeks_ago) { 2.weeks.ago }
+ let_it_be(:three_weeks_ago) { 3.weeks.ago }
+ let_it_be(:four_weeks_ago) { 4.weeks.ago }
+ let_it_be(:five_weeks_ago) { 5.weeks.ago }
+
+ let_it_be(:top_level_group) { create(:group) }
+ let_it_be(:sub_group_1) { create(:group, parent: top_level_group) }
+ let_it_be(:sub_group_2) { create(:group, parent: top_level_group) }
+ let_it_be(:sub_sub_group_1) { create(:group, parent: sub_group_2) }
+
+ let_it_be(:project_1) { create(:project, group: top_level_group) }
+ let_it_be(:project_2) { create(:project, group: top_level_group) }
+
+ let_it_be(:project_3) { create(:project, group: sub_group_1) }
+ let_it_be(:project_4) { create(:project, group: sub_group_2) }
+
+ let_it_be(:project_5) { create(:project, group: sub_sub_group_1) }
+
+ let_it_be(:issues) do
+ [
+ create(:issue, project: project_1, created_at: three_weeks_ago, relative_position: 5),
+ create(:issue, project: project_1, created_at: two_weeks_ago),
+ create(:issue, project: project_2, created_at: two_weeks_ago, relative_position: 15),
+ create(:issue, project: project_2, created_at: two_weeks_ago),
+ create(:issue, project: project_3, created_at: four_weeks_ago),
+ create(:issue, project: project_4, created_at: five_weeks_ago, relative_position: 10),
+ create(:issue, project: project_5, created_at: four_weeks_ago)
+ ]
+ end
+
+ shared_examples 'correct ordering examples' do
+ let(:iterator) do
+ Gitlab::Pagination::Keyset::Iterator.new(
+ scope: scope.limit(batch_size),
+ in_operator_optimization_options: in_operator_optimization_options
+ )
+ end
+
+ it 'returns records in correct order' do
+ all_records = []
+ iterator.each_batch(of: batch_size) do |records|
+ all_records.concat(records)
+ end
+
+ expect(all_records).to eq(expected_order)
+ end
+ end
+
+ context 'when ordering by issues.id DESC' do
+ let(:scope) { Issue.order(id: :desc) }
+ let(:expected_order) { issues.sort_by(&:id).reverse }
+
+ let(:in_operator_optimization_options) do
+ {
+ array_scope: Project.where(namespace_id: top_level_group.self_and_descendants.select(:id)).select(:id),
+ array_mapping_scope: -> (id_expression) { Issue.where(Issue.arel_table[:project_id].eq(id_expression)) },
+ finder_query: -> (id_expression) { Issue.where(Issue.arel_table[:id].eq(id_expression)) }
+ }
+ end
+
+ context 'when iterating records one by one' do
+ let(:batch_size) { 1 }
+
+ it_behaves_like 'correct ordering examples'
+ end
+
+ context 'when iterating records with LIMIT 3' do
+ let(:batch_size) { 3 }
+
+ it_behaves_like 'correct ordering examples'
+ end
+
+ context 'when loading records at once' do
+ let(:batch_size) { issues.size + 1 }
+
+ it_behaves_like 'correct ordering examples'
+ end
+ end
+
+ context 'when ordering by issues.relative_position DESC NULLS LAST, id DESC' do
+ let(:scope) { Issue.order(order) }
+ let(:expected_order) { scope.to_a }
+
+ let(:order) do
+ # NULLS LAST ordering requires custom Order object for keyset pagination:
+ # https://docs.gitlab.com/ee/development/database/keyset_pagination.html#complex-order-configuration
+ Gitlab::Pagination::Keyset::Order.build([
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: :relative_position,
+ column_expression: Issue.arel_table[:relative_position],
+ order_expression: Gitlab::Database.nulls_last_order('relative_position', :desc),
+ reversed_order_expression: Gitlab::Database.nulls_first_order('relative_position', :asc),
+ order_direction: :desc,
+ nullable: :nulls_last,
+ distinct: false
+ ),
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: :id,
+ order_expression: Issue.arel_table[:id].desc,
+ nullable: :not_nullable,
+ distinct: true
+ )
+ ])
+ end
+
+ let(:in_operator_optimization_options) do
+ {
+ array_scope: Project.where(namespace_id: top_level_group.self_and_descendants.select(:id)).select(:id),
+ array_mapping_scope: -> (id_expression) { Issue.where(Issue.arel_table[:project_id].eq(id_expression)) },
+ finder_query: -> (_relative_position_expression, id_expression) { Issue.where(Issue.arel_table[:id].eq(id_expression)) }
+ }
+ end
+
+ context 'when iterating records one by one' do
+ let(:batch_size) { 1 }
+
+ it_behaves_like 'correct ordering examples'
+ end
+
+ context 'when iterating records with LIMIT 3' do
+ let(:batch_size) { 3 }
+
+ it_behaves_like 'correct ordering examples'
+ end
+ end
+
+ context 'when ordering by issues.created_at DESC, issues.id ASC' do
+ let(:scope) { Issue.order(created_at: :desc, id: :asc) }
+ let(:expected_order) { issues.sort_by { |issue| [issue.created_at.to_f * -1, issue.id] } }
+
+ let(:in_operator_optimization_options) do
+ {
+ array_scope: Project.where(namespace_id: top_level_group.self_and_descendants.select(:id)).select(:id),
+ array_mapping_scope: -> (id_expression) { Issue.where(Issue.arel_table[:project_id].eq(id_expression)) },
+ finder_query: -> (_created_at_expression, id_expression) { Issue.where(Issue.arel_table[:id].eq(id_expression)) }
+ }
+ end
+
+ context 'when iterating records one by one' do
+ let(:batch_size) { 1 }
+
+ it_behaves_like 'correct ordering examples'
+ end
+
+ context 'when iterating records with LIMIT 3' do
+ let(:batch_size) { 3 }
+
+ it_behaves_like 'correct ordering examples'
+ end
+
+ context 'when loading records at once' do
+ let(:batch_size) { issues.size + 1 }
+
+ it_behaves_like 'correct ordering examples'
+ end
+ end
+
+ context 'pagination support' do
+ let(:scope) { Issue.order(id: :desc) }
+ let(:expected_order) { issues.sort_by(&:id).reverse }
+
+ let(:options) do
+ {
+ scope: scope,
+ array_scope: Project.where(namespace_id: top_level_group.self_and_descendants.select(:id)).select(:id),
+ array_mapping_scope: -> (id_expression) { Issue.where(Issue.arel_table[:project_id].eq(id_expression)) },
+ finder_query: -> (id_expression) { Issue.where(Issue.arel_table[:id].eq(id_expression)) }
+ }
+ end
+
+ context 'offset pagination' do
+ subject(:optimized_scope) { described_class.new(**options).execute }
+
+ it 'paginates the scopes' do
+ first_page = optimized_scope.page(1).per(2)
+ expect(first_page).to eq(expected_order[0...2])
+
+ second_page = optimized_scope.page(2).per(2)
+ expect(second_page).to eq(expected_order[2...4])
+
+ third_page = optimized_scope.page(3).per(2)
+ expect(third_page).to eq(expected_order[4...6])
+ end
+ end
+
+ context 'keyset pagination' do
+ def paginator(cursor = nil)
+ scope.keyset_paginate(cursor: cursor, per_page: 2, keyset_order_options: options)
+ end
+
+ it 'paginates correctly' do
+ first_page = paginator.records
+ expect(first_page).to eq(expected_order[0...2])
+
+ cursor_for_page_2 = paginator.cursor_for_next_page
+
+ second_page = paginator(cursor_for_page_2).records
+ expect(second_page).to eq(expected_order[2...4])
+
+ cursor_for_page_3 = paginator(cursor_for_page_2).cursor_for_next_page
+
+ third_page = paginator(cursor_for_page_3).records
+ expect(third_page).to eq(expected_order[4...6])
+ end
+ end
+ end
+
+ it 'raises error when unsupported scope is passed' do
+ scope = Issue.order(Issue.arel_table[:id].lower.desc)
+
+ options = {
+ scope: scope,
+ array_scope: Project.where(namespace_id: top_level_group.self_and_descendants.select(:id)).select(:id),
+ array_mapping_scope: -> (id_expression) { Issue.where(Issue.arel_table[:project_id].eq(id_expression)) },
+ finder_query: -> (id_expression) { Issue.where(Issue.arel_table[:id].eq(id_expression)) }
+ }
+
+ expect { described_class.new(**options).execute }.to raise_error(/The order on the scope does not support keyset pagination/)
+ end
+end
diff --git a/spec/lib/gitlab/pagination/keyset/order_spec.rb b/spec/lib/gitlab/pagination/keyset/order_spec.rb
index b867dd533e0..3c14d91fdfd 100644
--- a/spec/lib/gitlab/pagination/keyset/order_spec.rb
+++ b/spec/lib/gitlab/pagination/keyset/order_spec.rb
@@ -538,6 +538,47 @@ RSpec.describe Gitlab::Pagination::Keyset::Order do
end
it_behaves_like 'cursor attribute examples'
+
+ context 'with projections' do
+ context 'when additional_projections is empty' do
+ let(:scope) { Project.select(:id, :namespace_id) }
+
+ subject(:sql) { order.apply_cursor_conditions(scope, { id: '100' }).to_sql }
+
+ it 'has correct projections' do
+ is_expected.to include('SELECT "projects"."id", "projects"."namespace_id" FROM "projects"')
+ end
+ end
+
+ context 'when there are additional_projections' do
+ let(:order) do
+ order = Gitlab::Pagination::Keyset::Order.build([
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: 'created_at_field',
+ column_expression: Project.arel_table[:created_at],
+ order_expression: Project.arel_table[:created_at].desc,
+ order_direction: :desc,
+ distinct: false,
+ add_to_projections: true
+ ),
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: 'id',
+ order_expression: Project.arel_table[:id].desc
+ )
+ ])
+
+ order
+ end
+
+ let(:scope) { Project.select(:id, :namespace_id).reorder(order) }
+
+ subject(:sql) { order.apply_cursor_conditions(scope).to_sql }
+
+ it 'has correct projections' do
+ is_expected.to include('SELECT "projects"."id", "projects"."namespace_id", "projects"."created_at" AS created_at_field FROM "projects"')
+ end
+ end
+ end
end
end
end
diff --git a/spec/lib/gitlab/pagination/offset_pagination_spec.rb b/spec/lib/gitlab/pagination/offset_pagination_spec.rb
index f8d50fbc517..ffecbb06ff8 100644
--- a/spec/lib/gitlab/pagination/offset_pagination_spec.rb
+++ b/spec/lib/gitlab/pagination/offset_pagination_spec.rb
@@ -82,7 +82,7 @@ RSpec.describe Gitlab::Pagination::OffsetPagination do
context 'when the api_kaminari_count_with_limit feature flag is enabled' do
before do
- stub_feature_flags(api_kaminari_count_with_limit: true)
+ stub_feature_flags(api_kaminari_count_with_limit: true, lower_relation_max_count_limit: false)
end
context 'when resources count is less than MAX_COUNT_LIMIT' do
@@ -120,6 +120,41 @@ RSpec.describe Gitlab::Pagination::OffsetPagination do
end
end
+ context 'when lower_relation_max_count_limit FF is enabled' do
+ before do
+ stub_feature_flags(lower_relation_max_count_limit: true)
+ end
+
+ it_behaves_like 'paginated response'
+ it_behaves_like 'response with pagination headers'
+
+ context 'when limit is met' do
+ before do
+ stub_const("::Kaminari::ActiveRecordRelationMethods::MAX_COUNT_NEW_LOWER_LIMIT", 2)
+ end
+
+ it_behaves_like 'paginated response'
+
+ it 'does not return the X-Total and X-Total-Pages headers' do
+ expect_no_header('X-Total')
+ expect_no_header('X-Total-Pages')
+ expect_header('X-Per-Page', '2')
+ expect_header('X-Page', '1')
+ expect_header('X-Next-Page', '2')
+ expect_header('X-Prev-Page', '')
+
+ expect_header('Link', anything) do |_key, val|
+ expect(val).to include(%Q(<#{incoming_api_projects_url}?#{query.merge(page: 1).to_query}>; rel="first"))
+ expect(val).to include(%Q(<#{incoming_api_projects_url}?#{query.merge(page: 2).to_query}>; rel="next"))
+ expect(val).not_to include('rel="last"')
+ expect(val).not_to include('rel="prev"')
+ end
+
+ subject.paginate(resource)
+ end
+ end
+ end
+
it 'does not return the total headers when excluding them' do
expect_no_header('X-Total')
expect_no_header('X-Total-Pages')
diff --git a/spec/lib/gitlab/patch/legacy_database_config_spec.rb b/spec/lib/gitlab/patch/legacy_database_config_spec.rb
new file mode 100644
index 00000000000..e6c0bdbf360
--- /dev/null
+++ b/spec/lib/gitlab/patch/legacy_database_config_spec.rb
@@ -0,0 +1,123 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Patch::LegacyDatabaseConfig do
+ it 'module is included' do
+ expect(Rails::Application::Configuration).to include(described_class)
+ end
+
+ describe 'config/database.yml' do
+ let(:configuration) { Rails::Application::Configuration.new(Rails.root) }
+
+ before do
+ # The `AS::ConfigurationFile` calls `read` in `def initialize`
+ # thus we cannot use `expect_next_instance_of`
+ # rubocop:disable RSpec/AnyInstanceOf
+ expect_any_instance_of(ActiveSupport::ConfigurationFile)
+ .to receive(:read).with(Rails.root.join('config/database.yml')).and_return(database_yml)
+ # rubocop:enable RSpec/AnyInstanceOf
+ end
+
+ shared_examples 'hash containing main: connection name' do
+ it 'returns a hash containing only main:' do
+ database_configuration = configuration.database_configuration
+
+ expect(database_configuration).to match(
+ "production" => { "main" => a_hash_including("adapter") },
+ "development" => { "main" => a_hash_including("adapter" => "postgresql") },
+ "test" => { "main" => a_hash_including("adapter" => "postgresql") }
+ )
+ end
+ end
+
+ context 'when a new syntax is used' do
+ let(:database_yml) do
+ <<-EOS
+ production:
+ main:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_production
+ username: git
+ password: "secure password"
+ host: localhost
+
+ development:
+ main:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_development
+ username: postgres
+ password: "secure password"
+ host: localhost
+ variables:
+ statement_timeout: 15s
+
+ test: &test
+ main:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_test
+ username: postgres
+ password:
+ host: localhost
+ prepared_statements: false
+ variables:
+ statement_timeout: 15s
+ EOS
+ end
+
+ include_examples 'hash containing main: connection name'
+
+ it 'configuration is not legacy one' do
+ configuration.database_configuration
+
+ expect(configuration.uses_legacy_database_config).to eq(false)
+ end
+ end
+
+ context 'when a legacy syntax is used' do
+ let(:database_yml) do
+ <<-EOS
+ production:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_production
+ username: git
+ password: "secure password"
+ host: localhost
+
+ development:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_development
+ username: postgres
+ password: "secure password"
+ host: localhost
+ variables:
+ statement_timeout: 15s
+
+ test: &test
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_test
+ username: postgres
+ password:
+ host: localhost
+ prepared_statements: false
+ variables:
+ statement_timeout: 15s
+ EOS
+ end
+
+ include_examples 'hash containing main: connection name'
+
+ it 'configuration is legacy' do
+ configuration.database_configuration
+
+ expect(configuration.uses_legacy_database_config).to eq(true)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/path_regex_spec.rb b/spec/lib/gitlab/path_regex_spec.rb
index d343634fb92..aa13660deb4 100644
--- a/spec/lib/gitlab/path_regex_spec.rb
+++ b/spec/lib/gitlab/path_regex_spec.rb
@@ -468,6 +468,7 @@ RSpec.describe Gitlab::PathRegex do
end
let_it_be(:git_paths) { container_paths.map { |path| path + '.git' } }
+ let_it_be(:git_lfs_paths) { git_paths.flat_map { |path| [path + '/info/lfs/', path + '/gitlab-lfs/'] } }
let_it_be(:snippet_paths) { container_paths.grep(%r{snippets/\d}) }
let_it_be(:wiki_git_paths) { (container_paths - snippet_paths).map { |path| path + '.wiki.git' } }
let_it_be(:invalid_git_paths) { invalid_paths.map { |path| path + '.git' } }
@@ -498,6 +499,15 @@ RSpec.describe Gitlab::PathRegex do
end
end
+ describe '.repository_git_lfs_route_regex' do
+ subject { %r{\A#{described_class.repository_git_lfs_route_regex}\z} }
+
+ it 'matches the expected paths' do
+ expect_route_match(git_lfs_paths)
+ expect_no_route_match(container_paths + invalid_paths + git_paths + invalid_git_paths)
+ end
+ end
+
describe '.repository_wiki_git_route_regex' do
subject { %r{\A#{described_class.repository_wiki_git_route_regex}\z} }
diff --git a/spec/lib/gitlab/rack_attack/request_spec.rb b/spec/lib/gitlab/rack_attack/request_spec.rb
new file mode 100644
index 00000000000..3be7ec17e45
--- /dev/null
+++ b/spec/lib/gitlab/rack_attack/request_spec.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::RackAttack::Request do
+ describe 'FILES_PATH_REGEX' do
+ subject { described_class::FILES_PATH_REGEX }
+
+ it { is_expected.to match('/api/v4/projects/1/repository/files/README') }
+ it { is_expected.to match('/api/v4/projects/1/repository/files/README?ref=master') }
+ it { is_expected.to match('/api/v4/projects/1/repository/files/README/blame') }
+ it { is_expected.to match('/api/v4/projects/1/repository/files/README/raw') }
+ it { is_expected.to match('/api/v4/projects/some%2Fnested%2Frepo/repository/files/README') }
+ it { is_expected.not_to match('/api/v4/projects/some/nested/repo/repository/files/README') }
+ end
+end
diff --git a/spec/lib/gitlab/rack_attack_spec.rb b/spec/lib/gitlab/rack_attack_spec.rb
index 788d2eac61f..8f03905e08d 100644
--- a/spec/lib/gitlab/rack_attack_spec.rb
+++ b/spec/lib/gitlab/rack_attack_spec.rb
@@ -10,12 +10,19 @@ RSpec.describe Gitlab::RackAttack, :aggregate_failures do
let(:throttles) do
{
- throttle_unauthenticated: Gitlab::Throttle.unauthenticated_options,
- throttle_authenticated_api: Gitlab::Throttle.authenticated_api_options,
+ throttle_unauthenticated_api: Gitlab::Throttle.options(:api, authenticated: false),
+ throttle_authenticated_api: Gitlab::Throttle.options(:api, authenticated: true),
+ throttle_unauthenticated_web: Gitlab::Throttle.unauthenticated_web_options,
+ throttle_authenticated_web: Gitlab::Throttle.authenticated_web_options,
throttle_product_analytics_collector: { limit: 100, period: 60 },
- throttle_unauthenticated_protected_paths: Gitlab::Throttle.unauthenticated_options,
- throttle_authenticated_protected_paths_api: Gitlab::Throttle.authenticated_api_options,
- throttle_authenticated_protected_paths_web: Gitlab::Throttle.authenticated_web_options
+ throttle_unauthenticated_protected_paths: Gitlab::Throttle.protected_paths_options,
+ throttle_authenticated_protected_paths_api: Gitlab::Throttle.protected_paths_options,
+ throttle_authenticated_protected_paths_web: Gitlab::Throttle.protected_paths_options,
+ throttle_unauthenticated_packages_api: Gitlab::Throttle.options(:packages_api, authenticated: false),
+ throttle_authenticated_packages_api: Gitlab::Throttle.options(:packages_api, authenticated: true),
+ throttle_authenticated_git_lfs: Gitlab::Throttle.throttle_authenticated_git_lfs_options,
+ throttle_unauthenticated_files_api: Gitlab::Throttle.options(:files_api, authenticated: false),
+ throttle_authenticated_files_api: Gitlab::Throttle.options(:files_api, authenticated: true)
}
end
@@ -84,6 +91,15 @@ RSpec.describe Gitlab::RackAttack, :aggregate_failures do
end
end
+ it 'enables dry-runs for `throttle_unauthenticated_api` and `throttle_unauthenticated_web` when selecting `throttle_unauthenticated`' do
+ stub_env('GITLAB_THROTTLE_DRY_RUN', 'throttle_unauthenticated')
+
+ described_class.configure(fake_rack_attack)
+
+ expect(fake_rack_attack).to have_received(:track).with('throttle_unauthenticated_api', throttles[:throttle_unauthenticated_api])
+ expect(fake_rack_attack).to have_received(:track).with('throttle_unauthenticated_web', throttles[:throttle_unauthenticated_web])
+ end
+
context 'user allowlist' do
subject { described_class.user_allowlist }
diff --git a/spec/lib/gitlab/reference_extractor_spec.rb b/spec/lib/gitlab/reference_extractor_spec.rb
index f6e69aa6533..177e9d346b6 100644
--- a/spec/lib/gitlab/reference_extractor_spec.rb
+++ b/spec/lib/gitlab/reference_extractor_spec.rb
@@ -332,14 +332,59 @@ RSpec.describe Gitlab::ReferenceExtractor do
it 'returns visible references of given type' do
expect(subject.references(:issue)).to eq([issue])
end
+ end
- it 'does not increase stateful_not_visible_counter' do
- expect { subject.references(:issue) }.not_to change { subject.stateful_not_visible_counter }
- end
+ it 'does not return any references' do
+ expect(subject.references(:issue)).to be_empty
+ end
+ end
+
+ describe '#all_visible?' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project2) { create(:project) }
+ let_it_be(:issue) { create(:issue, project: project) }
+ let_it_be(:issue2) { create(:issue, project: project2) }
+
+ let(:text) { "Ref. #{issue.to_reference} and #{issue2.to_reference(project)}" }
+
+ subject { described_class.new(project, user) }
+
+ before do
+ subject.analyze(text)
end
- it 'increases stateful_not_visible_counter' do
- expect { subject.references(:issue) }.to change { subject.stateful_not_visible_counter }.by(1)
+ it 'returns true if no references were parsed yet' do
+ expect(subject.all_visible?).to be_truthy
+ end
+
+ context 'when references was already called' do
+ let(:membership) { [] }
+
+ before do
+ membership.each { |p| p.add_developer(user) }
+
+ subject.references(:issue)
+ end
+
+ it 'returns false' do
+ expect(subject.all_visible?).to be_falsey
+ end
+
+ context 'when user can access only some references' do
+ let(:membership) { [project] }
+
+ it 'returns false' do
+ expect(subject.all_visible?).to be_falsey
+ end
+ end
+
+ context 'when user can access all references' do
+ let(:membership) { [project, project2] }
+
+ it 'returns true' do
+ expect(subject.all_visible?).to be_truthy
+ end
+ end
end
end
end
diff --git a/spec/lib/gitlab/regex_spec.rb b/spec/lib/gitlab/regex_spec.rb
index c1c97e87a4c..f1b4e50b1eb 100644
--- a/spec/lib/gitlab/regex_spec.rb
+++ b/spec/lib/gitlab/regex_spec.rb
@@ -924,4 +924,25 @@ RSpec.describe Gitlab::Regex do
it { is_expected.not_to match('/api/v4/groups/1234/packages/debian/dists/stable/Release.gpg') }
it { is_expected.not_to match('/api/v4/groups/1234/packages/debian/pool/compon/a/pkg/file.name') }
end
+
+ describe '.composer_package_version_regex' do
+ subject { described_class.composer_package_version_regex }
+
+ it { is_expected.to match('v1.2.3') }
+ it { is_expected.to match('v1.2.x') }
+ it { is_expected.to match('v1.2.X') }
+ it { is_expected.to match('1.2.3') }
+ it { is_expected.to match('1') }
+ it { is_expected.to match('v1') }
+ it { is_expected.to match('1.2') }
+ it { is_expected.to match('v1.2') }
+ it { is_expected.not_to match('1.2.3-beta') }
+ it { is_expected.not_to match('1.2.x-beta') }
+ it { is_expected.not_to match('1.2.X-beta') }
+ it { is_expected.not_to match('1.2.3-alpha.3') }
+ it { is_expected.not_to match('1./2.3') }
+ it { is_expected.not_to match('v1./2.3') }
+ it { is_expected.not_to match('../../../../../1.2.3') }
+ it { is_expected.not_to match('%2e%2e%2f1.2.3') }
+ end
end
diff --git a/spec/lib/gitlab/repository_cache/preloader_spec.rb b/spec/lib/gitlab/repository_cache/preloader_spec.rb
new file mode 100644
index 00000000000..8c6618c9f8f
--- /dev/null
+++ b/spec/lib/gitlab/repository_cache/preloader_spec.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::RepositoryCache::Preloader, :use_clean_rails_redis_caching do
+ let(:projects) { create_list(:project, 2, :repository) }
+ let(:repositories) { projects.map(&:repository) }
+
+ describe '#preload' do
+ context 'when the values are already cached' do
+ before do
+ # Warm the cache but use a different model so they are not memoized
+ repos = Project.id_in(projects).order(:id).map(&:repository)
+
+ allow(repos[0].head_tree).to receive(:readme_path).and_return('README.txt')
+ allow(repos[1].head_tree).to receive(:readme_path).and_return('README.md')
+
+ repos.map(&:exists?)
+ repos.map(&:readme_path)
+ end
+
+ it 'prevents individual cache reads for cached methods' do
+ expect(Rails.cache).to receive(:read_multi).once.and_call_original
+
+ described_class.new(repositories).preload(
+ %i[exists? readme_path]
+ )
+
+ expect(Rails.cache).not_to receive(:read)
+ expect(Rails.cache).not_to receive(:write)
+
+ expect(repositories[0].exists?).to eq(true)
+ expect(repositories[0].readme_path).to eq('README.txt')
+
+ expect(repositories[1].exists?).to eq(true)
+ expect(repositories[1].readme_path).to eq('README.md')
+ end
+ end
+
+ context 'when values are not cached' do
+ it 'reads and writes from cache individually' do
+ described_class.new(repositories).preload(
+ %i[exists? has_visible_content?]
+ )
+
+ expect(Rails.cache).to receive(:read).exactly(4).times
+ expect(Rails.cache).to receive(:write).exactly(4).times
+
+ repositories.each(&:exists?)
+ repositories.each(&:has_visible_content?)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/search_results_spec.rb b/spec/lib/gitlab/search_results_spec.rb
index b8972f28889..27d65e14347 100644
--- a/spec/lib/gitlab/search_results_spec.rb
+++ b/spec/lib/gitlab/search_results_spec.rb
@@ -148,13 +148,13 @@ RSpec.describe Gitlab::SearchResults do
end
end
- it 'includes merge requests from source and target projects' do
+ it 'does not include merge requests from source projects' do
forked_project = fork_project(project, user)
merge_request_2 = create(:merge_request, target_project: project, source_project: forked_project, title: 'foo')
results = described_class.new(user, 'foo', Project.where(id: forked_project.id))
- expect(results.objects('merge_requests')).to include merge_request_2
+ expect(results.objects('merge_requests')).not_to include merge_request_2
end
describe '#merge_requests' do
diff --git a/spec/lib/gitlab/seeder_spec.rb b/spec/lib/gitlab/seeder_spec.rb
new file mode 100644
index 00000000000..877461a7064
--- /dev/null
+++ b/spec/lib/gitlab/seeder_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Seeder do
+ describe '.quiet' do
+ it 'disables mail deliveries' do
+ expect(ActionMailer::Base.perform_deliveries).to eq(true)
+
+ described_class.quiet do
+ expect(ActionMailer::Base.perform_deliveries).to eq(false)
+ end
+
+ expect(ActionMailer::Base.perform_deliveries).to eq(true)
+ end
+
+ it 'disables new note notifications' do
+ note = create(:note_on_issue)
+
+ notification_service = NotificationService.new
+
+ expect(notification_service).to receive(:send_new_note_notifications).twice
+
+ notification_service.new_note(note)
+
+ described_class.quiet do
+ expect(notification_service.new_note(note)).to eq(nil)
+ end
+
+ notification_service.new_note(note)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/sidekiq_cluster/cli_spec.rb b/spec/lib/gitlab/sidekiq_cluster/cli_spec.rb
index 3dd5ac8ee6c..e818b03cf75 100644
--- a/spec/lib/gitlab/sidekiq_cluster/cli_spec.rb
+++ b/spec/lib/gitlab/sidekiq_cluster/cli_spec.rb
@@ -48,6 +48,18 @@ RSpec.describe Gitlab::SidekiqCluster::CLI do
cli.run(%w(*))
end
+ it 'raises an error when the arguments contain newlines' do
+ invalid_arguments = [
+ ["foo\n"],
+ ["foo\r"],
+ %W[foo b\nar]
+ ]
+
+ invalid_arguments.each do |arguments|
+ expect { cli.run(arguments) }.to raise_error(described_class::CommandError)
+ end
+ end
+
context 'with --negate flag' do
it 'starts Sidekiq workers for all queues in all_queues.yml except the ones in argv' do
expect(Gitlab::SidekiqConfig::CliMethods).to receive(:worker_queues).and_return(['baz'])
diff --git a/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job_spec.rb b/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job_spec.rb
index d67cb95f483..cc69a11f7f8 100644
--- a/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job_spec.rb
+++ b/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job_spec.rb
@@ -9,7 +9,14 @@ RSpec.describe Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob, :clean_gi
described_class.new(job, queue)
end
- let(:job) { { 'class' => 'AuthorizedProjectsWorker', 'args' => [1], 'jid' => '123' } }
+ let(:wal_locations) do
+ {
+ main: '0/D525E3A8',
+ ci: 'AB/12345'
+ }
+ end
+
+ let(:job) { { 'class' => 'AuthorizedProjectsWorker', 'args' => [1], 'jid' => '123', 'wal_locations' => wal_locations } }
let(:queue) { 'authorized_projects' }
let(:idempotency_key) do
@@ -74,13 +81,39 @@ RSpec.describe Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob, :clean_gi
context 'when there was no job in the queue yet' do
it { expect(duplicate_job.check!).to eq('123') }
- it "adds a key with ttl set to #{described_class::DUPLICATE_KEY_TTL}" do
+ it "adds a idempotency key with ttl set to #{described_class::DUPLICATE_KEY_TTL}" do
expect { duplicate_job.check! }
.to change { read_idempotency_key_with_ttl(idempotency_key) }
.from([nil, -2])
.to(['123', be_within(1).of(described_class::DUPLICATE_KEY_TTL)])
end
+ context 'when wal locations is not empty' do
+ it "adds a existing wal locations key with ttl set to #{described_class::DUPLICATE_KEY_TTL}" do
+ expect { duplicate_job.check! }
+ .to change { read_idempotency_key_with_ttl(existing_wal_location_key(idempotency_key, :main)) }
+ .from([nil, -2])
+ .to([wal_locations[:main], be_within(1).of(described_class::DUPLICATE_KEY_TTL)])
+ .and change { read_idempotency_key_with_ttl(existing_wal_location_key(idempotency_key, :ci)) }
+ .from([nil, -2])
+ .to([wal_locations[:ci], be_within(1).of(described_class::DUPLICATE_KEY_TTL)])
+ end
+ end
+
+ context 'when preserve_latest_wal_locations_for_idempotent_jobs feature flag is disabled' do
+ before do
+ stub_feature_flags(preserve_latest_wal_locations_for_idempotent_jobs: false)
+ end
+
+ it "does not change the existing wal locations key's TTL" do
+ expect { duplicate_job.check! }
+ .to not_change { read_idempotency_key_with_ttl(existing_wal_location_key(idempotency_key, :main)) }
+ .from([nil, -2])
+ .and not_change { read_idempotency_key_with_ttl(existing_wal_location_key(idempotency_key, :ci)) }
+ .from([nil, -2])
+ end
+ end
+
it "adds the idempotency key to the jobs payload" do
expect { duplicate_job.check! }.to change { job['idempotency_key'] }.from(nil).to(idempotency_key)
end
@@ -89,6 +122,9 @@ RSpec.describe Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob, :clean_gi
context 'when there was already a job with same arguments in the same queue' do
before do
set_idempotency_key(idempotency_key, 'existing-key')
+ wal_locations.each do |config_name, location|
+ set_idempotency_key(existing_wal_location_key(idempotency_key, config_name), location)
+ end
end
it { expect(duplicate_job.check!).to eq('existing-key') }
@@ -99,6 +135,14 @@ RSpec.describe Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob, :clean_gi
.from(['existing-key', -1])
end
+ it "does not change the existing wal locations key's TTL" do
+ expect { duplicate_job.check! }
+ .to not_change { read_idempotency_key_with_ttl(existing_wal_location_key(idempotency_key, :main)) }
+ .from([wal_locations[:main], -1])
+ .and not_change { read_idempotency_key_with_ttl(existing_wal_location_key(idempotency_key, :ci)) }
+ .from([wal_locations[:ci], -1])
+ end
+
it 'sets the existing jid' do
duplicate_job.check!
@@ -107,6 +151,117 @@ RSpec.describe Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob, :clean_gi
end
end
+ describe '#update_latest_wal_location!' do
+ let(:offset) { '1024' }
+
+ before do
+ allow(duplicate_job).to receive(:pg_wal_lsn_diff).with(:main).and_return(offset)
+ allow(duplicate_job).to receive(:pg_wal_lsn_diff).with(:ci).and_return(offset)
+ end
+
+ shared_examples 'updates wal location' do
+ it 'updates a wal location to redis with an offset' do
+ expect { duplicate_job.update_latest_wal_location! }
+ .to change { read_range_from_redis(wal_location_key(idempotency_key, :main)) }
+ .from(existing_wal_with_offset[:main])
+ .to(new_wal_with_offset[:main])
+ .and change { read_range_from_redis(wal_location_key(idempotency_key, :ci)) }
+ .from(existing_wal_with_offset[:ci])
+ .to(new_wal_with_offset[:ci])
+ end
+ end
+
+ context 'when preserve_latest_wal_locations_for_idempotent_jobs feature flag is disabled' do
+ before do
+ stub_feature_flags(preserve_latest_wal_locations_for_idempotent_jobs: false)
+ end
+
+ it "doesn't call Sidekiq.redis" do
+ expect(Sidekiq).not_to receive(:redis)
+
+ duplicate_job.update_latest_wal_location!
+ end
+
+ it "doesn't update a wal location to redis with an offset" do
+ expect { duplicate_job.update_latest_wal_location! }
+ .to not_change { read_range_from_redis(wal_location_key(idempotency_key, :main)) }
+ .from([])
+ .and not_change { read_range_from_redis(wal_location_key(idempotency_key, :ci)) }
+ .from([])
+ end
+ end
+
+ context "when the key doesn't exists in redis" do
+ include_examples 'updates wal location' do
+ let(:existing_wal_with_offset) { { main: [], ci: [] } }
+ let(:new_wal_with_offset) { wal_locations.transform_values { |v| [v, offset] } }
+ end
+ end
+
+ context "when the key exists in redis" do
+ let(:existing_offset) { '1023'}
+ let(:existing_wal_locations) do
+ {
+ main: '0/D525E3NM',
+ ci: 'AB/111112'
+ }
+ end
+
+ before do
+ rpush_to_redis_key(wal_location_key(idempotency_key, :main), existing_wal_locations[:main], existing_offset)
+ rpush_to_redis_key(wal_location_key(idempotency_key, :ci), existing_wal_locations[:ci], existing_offset)
+ end
+
+ context "when the new offset is bigger then the existing one" do
+ include_examples 'updates wal location' do
+ let(:existing_wal_with_offset) { existing_wal_locations.transform_values { |v| [v, existing_offset] } }
+ let(:new_wal_with_offset) { wal_locations.transform_values { |v| [v, offset] } }
+ end
+ end
+
+ context "when the old offset is not bigger then the existing one" do
+ let(:existing_offset) { offset }
+
+ it "does not update a wal location to redis with an offset" do
+ expect { duplicate_job.update_latest_wal_location! }
+ .to not_change { read_range_from_redis(wal_location_key(idempotency_key, :main)) }
+ .from([existing_wal_locations[:main], existing_offset])
+ .and not_change { read_range_from_redis(wal_location_key(idempotency_key, :ci)) }
+ .from([existing_wal_locations[:ci], existing_offset])
+ end
+ end
+ end
+ end
+
+ describe '#latest_wal_locations' do
+ context 'when job was deduplicated and wal locations were already persisted' do
+ before do
+ rpush_to_redis_key(wal_location_key(idempotency_key, :main), wal_locations[:main], 1024)
+ rpush_to_redis_key(wal_location_key(idempotency_key, :ci), wal_locations[:ci], 1024)
+ end
+
+ it { expect(duplicate_job.latest_wal_locations).to eq(wal_locations) }
+ end
+
+ context 'when job is not deduplication and wal locations were not persisted' do
+ it { expect(duplicate_job.latest_wal_locations).to be_empty }
+ end
+
+ context 'when preserve_latest_wal_locations_for_idempotent_jobs feature flag is disabled' do
+ before do
+ stub_feature_flags(preserve_latest_wal_locations_for_idempotent_jobs: false)
+ end
+
+ it "doesn't call Sidekiq.redis" do
+ expect(Sidekiq).not_to receive(:redis)
+
+ duplicate_job.latest_wal_locations
+ end
+
+ it { expect(duplicate_job.latest_wal_locations).to eq({}) }
+ end
+ end
+
describe '#delete!' do
context "when we didn't track the definition" do
it { expect { duplicate_job.delete! }.not_to raise_error }
@@ -115,14 +270,79 @@ RSpec.describe Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob, :clean_gi
context 'when the key exists in redis' do
before do
set_idempotency_key(idempotency_key, 'existing-jid')
+ wal_locations.each do |config_name, location|
+ set_idempotency_key(existing_wal_location_key(idempotency_key, config_name), location)
+ set_idempotency_key(wal_location_key(idempotency_key, config_name), location)
+ end
end
shared_examples 'deleting the duplicate job' do
- it 'removes the key from redis' do
- expect { duplicate_job.delete! }
- .to change { read_idempotency_key_with_ttl(idempotency_key) }
- .from(['existing-jid', -1])
- .to([nil, -2])
+ shared_examples 'deleting keys from redis' do |key_name|
+ it "removes the #{key_name} from redis" do
+ expect { duplicate_job.delete! }
+ .to change { read_idempotency_key_with_ttl(key) }
+ .from([from_value, -1])
+ .to([nil, -2])
+ end
+ end
+
+ shared_examples 'does not delete key from redis' do |key_name|
+ it "does not remove the #{key_name} from redis" do
+ expect { duplicate_job.delete! }
+ .to not_change { read_idempotency_key_with_ttl(key) }
+ .from([from_value, -1])
+ end
+ end
+
+ it_behaves_like 'deleting keys from redis', 'idempotent key' do
+ let(:key) { idempotency_key }
+ let(:from_value) { 'existing-jid' }
+ end
+
+ it_behaves_like 'deleting keys from redis', 'existing wal location keys for main database' do
+ let(:key) { existing_wal_location_key(idempotency_key, :main) }
+ let(:from_value) { wal_locations[:main] }
+ end
+
+ it_behaves_like 'deleting keys from redis', 'existing wal location keys for ci database' do
+ let(:key) { existing_wal_location_key(idempotency_key, :ci) }
+ let(:from_value) { wal_locations[:ci] }
+ end
+
+ it_behaves_like 'deleting keys from redis', 'latest wal location keys for main database' do
+ let(:key) { wal_location_key(idempotency_key, :main) }
+ let(:from_value) { wal_locations[:main] }
+ end
+
+ it_behaves_like 'deleting keys from redis', 'latest wal location keys for ci database' do
+ let(:key) { wal_location_key(idempotency_key, :ci) }
+ let(:from_value) { wal_locations[:ci] }
+ end
+
+ context 'when preserve_latest_wal_locations_for_idempotent_jobs feature flag is disabled' do
+ before do
+ stub_feature_flags(preserve_latest_wal_locations_for_idempotent_jobs: false)
+ end
+
+ it_behaves_like 'does not delete key from redis', 'latest wal location keys for main database' do
+ let(:key) { existing_wal_location_key(idempotency_key, :main) }
+ let(:from_value) { wal_locations[:main] }
+ end
+
+ it_behaves_like 'does not delete key from redis', 'latest wal location keys for ci database' do
+ let(:key) { existing_wal_location_key(idempotency_key, :ci) }
+ let(:from_value) { wal_locations[:ci] }
+ end
+
+ it_behaves_like 'does not delete key from redis', 'latest wal location keys for main database' do
+ let(:key) { wal_location_key(idempotency_key, :main) }
+ let(:from_value) { wal_locations[:main] }
+ end
+
+ it_behaves_like 'does not delete key from redis', 'latest wal location keys for ci database' do
+ let(:key) { wal_location_key(idempotency_key, :ci) }
+ let(:from_value) { wal_locations[:ci] }
+ end
end
end
@@ -254,10 +474,22 @@ RSpec.describe Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob, :clean_gi
end
end
+ def existing_wal_location_key(idempotency_key, config_name)
+ "#{idempotency_key}:#{config_name}:existing_wal_location"
+ end
+
+ def wal_location_key(idempotency_key, config_name)
+ "#{idempotency_key}:#{config_name}:wal_location"
+ end
+
def set_idempotency_key(key, value = '1')
Sidekiq.redis { |r| r.set(key, value) }
end
+ def rpush_to_redis_key(key, wal, offset)
+ Sidekiq.redis { |r| r.rpush(key, [wal, offset]) }
+ end
+
def read_idempotency_key_with_ttl(key)
Sidekiq.redis do |redis|
redis.pipelined do |p|
@@ -266,4 +498,10 @@ RSpec.describe Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob, :clean_gi
end
end
end
+
+ def read_range_from_redis(key)
+ Sidekiq.redis do |redis|
+ redis.lrange(key, 0, -1)
+ end
+ end
end
diff --git a/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executed_spec.rb b/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executed_spec.rb
index b3d463b6f6b..9772255fc50 100644
--- a/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executed_spec.rb
+++ b/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executed_spec.rb
@@ -7,6 +7,10 @@ RSpec.describe Gitlab::SidekiqMiddleware::DuplicateJobs::Strategies::UntilExecut
describe '#perform' do
let(:proc) { -> {} }
+ before do
+ allow(fake_duplicate_job).to receive(:latest_wal_locations).and_return( {} )
+ end
+
it 'deletes the lock after executing' do
expect(proc).to receive(:call).ordered
expect(fake_duplicate_job).to receive(:delete!).ordered
diff --git a/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing_spec.rb b/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing_spec.rb
index d45b6c5fcd1..c4045b8c63b 100644
--- a/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing_spec.rb
+++ b/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing_spec.rb
@@ -7,6 +7,10 @@ RSpec.describe Gitlab::SidekiqMiddleware::DuplicateJobs::Strategies::UntilExecut
describe '#perform' do
let(:proc) { -> {} }
+ before do
+ allow(fake_duplicate_job).to receive(:latest_wal_locations).and_return( {} )
+ end
+
it 'deletes the lock before executing' do
expect(fake_duplicate_job).to receive(:delete!).ordered
expect(proc).to receive(:call).ordered
diff --git a/spec/lib/gitlab/sidekiq_middleware/size_limiter/validator_spec.rb b/spec/lib/gitlab/sidekiq_middleware/size_limiter/validator_spec.rb
index 440eca10a88..abbfb9cd9fa 100644
--- a/spec/lib/gitlab/sidekiq_middleware/size_limiter/validator_spec.rb
+++ b/spec/lib/gitlab/sidekiq_middleware/size_limiter/validator_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::SidekiqMiddleware::SizeLimiter::Validator do
+RSpec.describe Gitlab::SidekiqMiddleware::SizeLimiter::Validator, :aggregate_failures do
let(:base_payload) do
{
"class" => "ARandomWorker",
@@ -31,10 +31,35 @@ RSpec.describe Gitlab::SidekiqMiddleware::SizeLimiter::Validator do
end
before do
+ # Settings aren't in the database in specs, but stored in memory, this is fine
+ # for these tests.
+ allow(Gitlab::CurrentSettings).to receive(:current_application_settings?).and_return(true)
stub_const("TestSizeLimiterWorker", worker_class)
end
describe '#initialize' do
+ context 'configuration from application settings' do
+ let(:validator) { described_class.new(worker_class, job_payload) }
+
+ it 'has the right defaults' do
+ expect(validator.mode).to eq(described_class::COMPRESS_MODE)
+ expect(validator.compression_threshold).to eq(described_class::DEFAULT_COMPRESSION_THRESHOLD_BYTES)
+ expect(validator.size_limit).to eq(described_class::DEFAULT_SIZE_LIMIT)
+ end
+
+ it 'allows configuration through application settings' do
+ stub_application_setting(
+ sidekiq_job_limiter_mode: 'track',
+ sidekiq_job_limiter_compression_threshold_bytes: 1,
+ sidekiq_job_limiter_limit_bytes: 2
+ )
+
+ expect(validator.mode).to eq(described_class::TRACK_MODE)
+ expect(validator.compression_threshold).to eq(1)
+ expect(validator.size_limit).to eq(2)
+ end
+ end
+
context 'when the input mode is valid' do
it 'does not log a warning message' do
expect(::Sidekiq.logger).not_to receive(:warn)
@@ -58,7 +83,7 @@ RSpec.describe Gitlab::SidekiqMiddleware::SizeLimiter::Validator do
it 'defaults to track mode' do
expect(::Sidekiq.logger).not_to receive(:warn)
- validator = described_class.new(TestSizeLimiterWorker, job_payload)
+ validator = described_class.new(TestSizeLimiterWorker, job_payload, mode: nil)
expect(validator.mode).to eql('track')
end
@@ -74,10 +99,12 @@ RSpec.describe Gitlab::SidekiqMiddleware::SizeLimiter::Validator do
end
context 'when the size input is invalid' do
- it 'defaults to 0 and logs a warning message' do
+ it 'logs a warning message' do
expect(::Sidekiq.logger).to receive(:warn).with('Invalid Sidekiq size limiter limit: -1')
- described_class.new(TestSizeLimiterWorker, job_payload, size_limit: -1)
+ validator = described_class.new(TestSizeLimiterWorker, job_payload, size_limit: -1)
+
+ expect(validator.size_limit).to be(0)
end
end
@@ -85,9 +112,9 @@ RSpec.describe Gitlab::SidekiqMiddleware::SizeLimiter::Validator do
it 'defaults to 0' do
expect(::Sidekiq.logger).not_to receive(:warn)
- validator = described_class.new(TestSizeLimiterWorker, job_payload)
+ validator = described_class.new(TestSizeLimiterWorker, job_payload, size_limit: nil)
- expect(validator.size_limit).to be(0)
+ expect(validator.size_limit).to be(described_class::DEFAULT_SIZE_LIMIT)
end
end
@@ -258,6 +285,22 @@ RSpec.describe Gitlab::SidekiqMiddleware::SizeLimiter::Validator do
end
end
+ context 'when job size is bigger than compression threshold and size limit is 0' do
+ let(:size_limit) { 0 }
+ let(:args) { { a: 'a' * 300 } }
+ let(:job) { job_payload(args) }
+
+ it 'does not raise an exception and compresses the arguments' do
+ expect(::Gitlab::SidekiqMiddleware::SizeLimiter::Compressor).to receive(:compress).with(
+ job, Sidekiq.dump_json(args)
+ ).and_return('a' * 40)
+
+ expect do
+ validate.call(TestSizeLimiterWorker, job)
+ end.not_to raise_error
+ end
+ end
+
context 'when the job was already compressed' do
let(:job) do
job_payload({ a: 'a' * 10 })
@@ -275,7 +318,7 @@ RSpec.describe Gitlab::SidekiqMiddleware::SizeLimiter::Validator do
let(:args) { { a: 'a' * 3000 } }
let(:job) { job_payload(args) }
- it 'does not raise an exception' do
+ it 'raises an exception' do
expect(::Gitlab::SidekiqMiddleware::SizeLimiter::Compressor).to receive(:compress).with(
job, Sidekiq.dump_json(args)
).and_return('a' * 60)
@@ -284,24 +327,46 @@ RSpec.describe Gitlab::SidekiqMiddleware::SizeLimiter::Validator do
validate.call(TestSizeLimiterWorker, job)
end.to raise_error(Gitlab::SidekiqMiddleware::SizeLimiter::ExceedLimitError)
end
+
+ it 'does not raise an exception when the worker allows big payloads' do
+ worker_class.big_payload!
+
+ expect(::Gitlab::SidekiqMiddleware::SizeLimiter::Compressor).to receive(:compress).with(
+ job, Sidekiq.dump_json(args)
+ ).and_return('a' * 60)
+
+ expect do
+ validate.call(TestSizeLimiterWorker, job)
+ end.not_to raise_error
+ end
end
end
end
- describe '#validate!' do
- context 'when calling SizeLimiter.validate!' do
- let(:validate) { ->(worker_clas, job) { described_class.validate!(worker_class, job) } }
+ describe '.validate!' do
+ let(:validate) { ->(worker_class, job) { described_class.validate!(worker_class, job) } }
+ it_behaves_like 'validate limit job payload size' do
before do
- stub_env('GITLAB_SIDEKIQ_SIZE_LIMITER_MODE', mode)
- stub_env('GITLAB_SIDEKIQ_SIZE_LIMITER_LIMIT_BYTES', size_limit)
- stub_env('GITLAB_SIDEKIQ_SIZE_LIMITER_COMPRESSION_THRESHOLD_BYTES', compression_threshold)
+ stub_application_setting(
+ sidekiq_job_limiter_mode: mode,
+ sidekiq_job_limiter_compression_threshold_bytes: compression_threshold,
+ sidekiq_job_limiter_limit_bytes: size_limit
+ )
end
+ end
- it_behaves_like 'validate limit job payload size'
+ it "skips background migrations" do
+ expect(described_class).not_to receive(:new)
+
+ described_class::EXEMPT_WORKER_NAMES.each do |class_name|
+ validate.call(class_name.constantize, job_payload)
+ end
end
+ end
- context 'when creating an instance with the related ENV variables' do
+ describe '#validate!' do
+ context 'when creating an instance with the related configuration variables' do
let(:validate) do
->(worker_clas, job) do
described_class.new(worker_class, job).validate!
@@ -309,9 +374,11 @@ RSpec.describe Gitlab::SidekiqMiddleware::SizeLimiter::Validator do
end
before do
- stub_env('GITLAB_SIDEKIQ_SIZE_LIMITER_MODE', mode)
- stub_env('GITLAB_SIDEKIQ_SIZE_LIMITER_LIMIT_BYTES', size_limit)
- stub_env('GITLAB_SIDEKIQ_SIZE_LIMITER_COMPRESSION_THRESHOLD_BYTES', compression_threshold)
+ stub_application_setting(
+ sidekiq_job_limiter_mode: mode,
+ sidekiq_job_limiter_compression_threshold_bytes: compression_threshold,
+ sidekiq_job_limiter_limit_bytes: size_limit
+ )
end
it_behaves_like 'validate limit job payload size'
diff --git a/spec/lib/gitlab/sidekiq_middleware_spec.rb b/spec/lib/gitlab/sidekiq_middleware_spec.rb
index 5e4e79e818e..8285cf960d2 100644
--- a/spec/lib/gitlab/sidekiq_middleware_spec.rb
+++ b/spec/lib/gitlab/sidekiq_middleware_spec.rb
@@ -66,12 +66,12 @@ RSpec.describe Gitlab::SidekiqMiddleware do
::Gitlab::SidekiqMiddleware::BatchLoader,
::Labkit::Middleware::Sidekiq::Server,
::Gitlab::SidekiqMiddleware::InstrumentationLogger,
- ::Gitlab::Database::LoadBalancing::SidekiqServerMiddleware,
::Gitlab::SidekiqMiddleware::AdminMode::Server,
::Gitlab::SidekiqVersioning::Middleware,
::Gitlab::SidekiqStatus::ServerMiddleware,
::Gitlab::SidekiqMiddleware::WorkerContext::Server,
- ::Gitlab::SidekiqMiddleware::DuplicateJobs::Server
+ ::Gitlab::SidekiqMiddleware::DuplicateJobs::Server,
+ ::Gitlab::Database::LoadBalancing::SidekiqServerMiddleware
]
end
@@ -177,12 +177,12 @@ RSpec.describe Gitlab::SidekiqMiddleware do
[
::Gitlab::SidekiqMiddleware::WorkerContext::Client,
::Labkit::Middleware::Sidekiq::Client,
+ ::Gitlab::Database::LoadBalancing::SidekiqClientMiddleware,
::Gitlab::SidekiqMiddleware::DuplicateJobs::Client,
::Gitlab::SidekiqStatus::ClientMiddleware,
::Gitlab::SidekiqMiddleware::AdminMode::Client,
::Gitlab::SidekiqMiddleware::SizeLimiter::Client,
- ::Gitlab::SidekiqMiddleware::ClientMetrics,
- ::Gitlab::Database::LoadBalancing::SidekiqClientMiddleware
+ ::Gitlab::SidekiqMiddleware::ClientMetrics
]
end
diff --git a/spec/lib/gitlab/sidekiq_queue_spec.rb b/spec/lib/gitlab/sidekiq_queue_spec.rb
index 2ab32657f0e..5e91282612e 100644
--- a/spec/lib/gitlab/sidekiq_queue_spec.rb
+++ b/spec/lib/gitlab/sidekiq_queue_spec.rb
@@ -4,15 +4,15 @@ require 'spec_helper'
RSpec.describe Gitlab::SidekiqQueue, :clean_gitlab_redis_queues do
around do |example|
- Sidekiq::Queue.new('authorized_projects').clear
+ Sidekiq::Queue.new('default').clear
Sidekiq::Testing.disable!(&example)
- Sidekiq::Queue.new('authorized_projects').clear
+ Sidekiq::Queue.new('default').clear
end
- def add_job(user, args)
+ def add_job(args, user:, klass: 'AuthorizedProjectsWorker')
Sidekiq::Client.push(
- 'class' => 'AuthorizedProjectsWorker',
- 'queue' => 'authorized_projects',
+ 'class' => klass,
+ 'queue' => 'default',
'args' => args,
'meta.user' => user.username
)
@@ -20,13 +20,13 @@ RSpec.describe Gitlab::SidekiqQueue, :clean_gitlab_redis_queues do
describe '#drop_jobs!' do
shared_examples 'queue processing' do
- let(:sidekiq_queue) { described_class.new('authorized_projects') }
+ let(:sidekiq_queue) { described_class.new('default') }
let_it_be(:sidekiq_queue_user) { create(:user) }
before do
- add_job(create(:user), [1])
- add_job(sidekiq_queue_user, [2])
- add_job(sidekiq_queue_user, [3])
+ add_job([1], user: create(:user))
+ add_job([2], user: sidekiq_queue_user, klass: 'MergeWorker')
+ add_job([3], user: sidekiq_queue_user)
end
context 'when the queue is not processed in time' do
@@ -68,11 +68,19 @@ RSpec.describe Gitlab::SidekiqQueue, :clean_gitlab_redis_queues do
end
end
+ context 'when there are jobs matching the class name' do
+ include_examples 'queue processing' do
+ let(:search_metadata) { { user: sidekiq_queue_user.username, worker_class: 'AuthorizedProjectsWorker' } }
+ let(:timeout_deleted) { 1 }
+ let(:no_timeout_deleted) { 1 }
+ end
+ end
+
context 'when there are no valid metadata keys passed' do
it 'raises NoMetadataError' do
- add_job(create(:user), [1])
+ add_job([1], user: create(:user))
- expect { described_class.new('authorized_projects').drop_jobs!({ username: 'sidekiq_queue_user' }, timeout: 1) }
+ expect { described_class.new('default').drop_jobs!({ username: 'sidekiq_queue_user' }, timeout: 1) }
.to raise_error(described_class::NoMetadataError)
end
end
diff --git a/spec/lib/gitlab/tracking/snowplow_schema_validation_spec.rb b/spec/lib/gitlab/tracking/snowplow_schema_validation_spec.rb
new file mode 100644
index 00000000000..32c601ae47d
--- /dev/null
+++ b/spec/lib/gitlab/tracking/snowplow_schema_validation_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Snowplow Schema Validation' do
+ context 'snowplow events definition' do
+ shared_examples 'matches schema' do
+ it 'conforms schema json' do
+ paths = Dir[Rails.root.join(yaml_path)]
+
+ events = paths.each_with_object([]) do |path, metrics|
+ metrics.push(
+ YAML.safe_load(File.read(path), aliases: true)
+ )
+ end
+
+ expect(events).to all match_schema(Rails.root.join('config/events/schema.json'))
+ end
+ end
+
+ describe 'matches the schema for CE' do
+ let(:yaml_path) { 'config/events/*.yml' }
+
+ it_behaves_like 'matches schema'
+ end
+
+ describe 'matches the schema for EE' do
+ let(:yaml_path) { 'ee/config/events/*.yml' }
+
+ it_behaves_like 'matches schema'
+ end
+ end
+end
diff --git a/spec/lib/gitlab/tracking/standard_context_spec.rb b/spec/lib/gitlab/tracking/standard_context_spec.rb
index a0fb6a270a5..ca7a6b6b1c3 100644
--- a/spec/lib/gitlab/tracking/standard_context_spec.rb
+++ b/spec/lib/gitlab/tracking/standard_context_spec.rb
@@ -87,8 +87,26 @@ RSpec.describe Gitlab::Tracking::StandardContext do
end
end
- it 'does not contain any ids' do
- expect(snowplow_context.to_json[:data].keys).not_to include(:user_id, :project_id, :namespace_id)
+ it 'does not contain user id' do
+ expect(snowplow_context.to_json[:data].keys).not_to include(:user_id)
+ end
+
+ it 'contains namespace and project ids' do
+ expect(snowplow_context.to_json[:data].keys).to include(:project_id, :namespace_id)
+ end
+
+ it 'accepts just project id as integer' do
+ expect { described_class.new(project: 1).to_context }.not_to raise_error
+ end
+
+ context 'without add_namespace_and_project_to_snowplow_tracking feature' do
+ before do
+ stub_feature_flags(add_namespace_and_project_to_snowplow_tracking: false)
+ end
+
+ it 'does not contain any ids' do
+ expect(snowplow_context.to_json[:data].keys).not_to include(:user_id, :project_id, :namespace_id)
+ end
end
end
end
diff --git a/spec/lib/gitlab/tracking_spec.rb b/spec/lib/gitlab/tracking_spec.rb
index 994316f38ee..02e66458f46 100644
--- a/spec/lib/gitlab/tracking_spec.rb
+++ b/spec/lib/gitlab/tracking_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe Gitlab::Tracking do
described_class.instance_variable_set("@snowplow", nil)
end
- describe '.snowplow_options' do
+ describe '.options' do
it 'returns useful client options' do
expected_fields = {
namespace: 'gl',
@@ -22,13 +22,13 @@ RSpec.describe Gitlab::Tracking do
linkClickTracking: true
}
- expect(subject.snowplow_options(nil)).to match(expected_fields)
+ expect(subject.options(nil)).to match(expected_fields)
end
it 'when feature flag is disabled' do
stub_feature_flags(additional_snowplow_tracking: false)
- expect(subject.snowplow_options(nil)).to include(
+ expect(subject.options(nil)).to include(
formTracking: false,
linkClickTracking: false
)
@@ -47,7 +47,7 @@ RSpec.describe Gitlab::Tracking do
it "delegates to #{klass} destination" do
other_context = double(:context)
- project = double(:project)
+ project = build_stubbed(:project)
user = double(:user)
expect(Gitlab::Tracking::StandardContext)
diff --git a/spec/lib/gitlab/url_builder_spec.rb b/spec/lib/gitlab/url_builder_spec.rb
index b359eb422d7..8e372ba795b 100644
--- a/spec/lib/gitlab/url_builder_spec.rb
+++ b/spec/lib/gitlab/url_builder_spec.rb
@@ -69,6 +69,27 @@ RSpec.describe Gitlab::UrlBuilder do
end
end
+ context 'when passing a compare' do
+ # NOTE: The Compare requires an actual repository, which isn't available
+ # with the `build_stubbed` strategy used by the table tests above
+ let_it_be(:compare) { create(:compare) }
+ let_it_be(:project) { compare.project }
+
+ it 'returns the full URL' do
+ expect(subject.build(compare)).to eq("#{Gitlab.config.gitlab.url}/#{project.full_path}/-/compare/#{compare.base_commit_sha}...#{compare.head_commit_sha}")
+ end
+
+ it 'returns only the path if only_path is given' do
+ expect(subject.build(compare, only_path: true)).to eq("/#{project.full_path}/-/compare/#{compare.base_commit_sha}...#{compare.head_commit_sha}")
+ end
+
+ it 'returns an empty string for missing project' do
+ expect(compare).to receive(:project).and_return(nil)
+
+ expect(subject.build(compare)).to eq('')
+ end
+ end
+
context 'when passing a commit without a project' do
let(:commit) { build_stubbed(:commit) }
diff --git a/spec/lib/gitlab/usage/metric_definition_spec.rb b/spec/lib/gitlab/usage/metric_definition_spec.rb
index 1ae8a0881ef..6406c0b5458 100644
--- a/spec/lib/gitlab/usage/metric_definition_spec.rb
+++ b/spec/lib/gitlab/usage/metric_definition_spec.rb
@@ -9,7 +9,8 @@ RSpec.describe Gitlab::Usage::MetricDefinition do
value_type: 'string',
product_category: 'collection',
product_stage: 'growth',
- status: 'data_available',
+ status: 'active',
+ milestone: '14.1',
default_generation: 'generation_1',
key_path: 'uuid',
product_group: 'group::product analytics',
@@ -64,6 +65,7 @@ RSpec.describe Gitlab::Usage::MetricDefinition do
:value_type | nil
:value_type | 'test'
:status | nil
+ :milestone | nil
:data_category | nil
:key_path | nil
:product_group | nil
@@ -127,9 +129,7 @@ RSpec.describe Gitlab::Usage::MetricDefinition do
where(:status, :skip_validation?) do
'deprecated' | true
'removed' | true
- 'data_available' | false
- 'implemented' | false
- 'not_used' | false
+ 'active' | false
end
with_them do
@@ -191,7 +191,8 @@ RSpec.describe Gitlab::Usage::MetricDefinition do
value_type: 'string',
product_category: 'collection',
product_stage: 'growth',
- status: 'data_available',
+ status: 'active',
+ milestone: '14.1',
default_generation: 'generation_1',
key_path: 'counter.category.event',
product_group: 'group::product analytics',
diff --git a/spec/lib/gitlab/usage/metric_spec.rb b/spec/lib/gitlab/usage/metric_spec.rb
index d83f59e4a7d..ea8d1a135a6 100644
--- a/spec/lib/gitlab/usage/metric_spec.rb
+++ b/spec/lib/gitlab/usage/metric_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe Gitlab::Usage::Metric do
product_group: "group::plan",
product_category: "issue_tracking",
value_type: "number",
- status: "data_available",
+ status: "active",
time_frame: "all",
data_source: "database",
instrumentation_class: "CountIssuesMetric",
diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/service_ping_features_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/service_ping_features_metric_spec.rb
new file mode 100644
index 00000000000..40e9b962878
--- /dev/null
+++ b/spec/lib/gitlab/usage/metrics/instrumentations/service_ping_features_metric_spec.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Usage::Metrics::Instrumentations::ServicePingFeaturesMetric do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:usage_ping_features_enabled, :expected_value) do
+ true | true
+ false | false
+ end
+
+ with_them do
+ before do
+ stub_application_setting(usage_ping_features_enabled: usage_ping_features_enabled)
+ end
+
+ it_behaves_like 'a correct instrumented metric value', { time_frame: 'none' }
+ end
+end
diff --git a/spec/lib/gitlab/usage_data_counters/ci_template_unique_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/ci_template_unique_counter_spec.rb
index d4148b57348..4996b0a0089 100644
--- a/spec/lib/gitlab/usage_data_counters/ci_template_unique_counter_spec.rb
+++ b/spec/lib/gitlab/usage_data_counters/ci_template_unique_counter_spec.rb
@@ -77,11 +77,22 @@ RSpec.describe Gitlab::UsageDataCounters::CiTemplateUniqueCounter do
let(:project_id) { 1 }
let(:config_source) { :repository_source }
- Dir.glob(File.join('lib', 'gitlab', 'ci', 'templates', '**'), base: Rails.root) do |template|
+ described_class.ci_templates.each do |template|
next if described_class::TEMPLATE_TO_EVENT.key?(template)
- it "does not track #{template}" do
- expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to(receive(:track_event))
+ it "has an event defined for #{template}" do
+ expect do
+ described_class.track_unique_project_event(
+ project_id: project_id,
+ template: template,
+ config_source: config_source
+ )
+ end.not_to raise_error
+ end
+
+ it "tracks #{template}" do
+ expected_template_event_name = described_class.ci_template_event_name(template, :repository_source)
+ expect(Gitlab::UsageDataCounters::HLLRedisCounter).to(receive(:track_event)).with(expected_template_event_name, values: project_id)
described_class.track_unique_project_event(project_id: project_id, template: template, config_source: config_source)
end
diff --git a/spec/lib/gitlab/usage_data_counters/code_review_events_spec.rb b/spec/lib/gitlab/usage_data_counters/code_review_events_spec.rb
index a1dee442131..c4a84445a01 100644
--- a/spec/lib/gitlab/usage_data_counters/code_review_events_spec.rb
+++ b/spec/lib/gitlab/usage_data_counters/code_review_events_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe 'Code review events' do
code_review_events = Gitlab::UsageDataCounters::HLLRedisCounter.events_for_category("code_review")
- exceptions = %w[i_code_review_mr_diffs i_code_review_mr_single_file_diffs]
+ exceptions = %w[i_code_review_mr_diffs i_code_review_mr_single_file_diffs i_code_review_total_suggestions_applied i_code_review_total_suggestions_added]
code_review_aggregated_events += exceptions
expect(code_review_events - code_review_aggregated_events).to be_empty
diff --git a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb
index 887759014f5..427dd4a205e 100644
--- a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb
+++ b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb
@@ -462,6 +462,8 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s
allow(described_class).to receive(:known_events).and_return(known_events)
allow(described_class).to receive(:categories).and_return(%w(category1 category2))
+ stub_const('Gitlab::UsageDataCounters::HLLRedisCounter::CATEGORIES_FOR_TOTALS', %w(category1 category2))
+
described_class.track_event('event1_slot', values: entity1, time: 2.days.ago)
described_class.track_event('event2_slot', values: entity2, time: 2.days.ago)
described_class.track_event('event2_slot', values: entity3, time: 2.weeks.ago)
diff --git a/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb
index 041fc2f20a8..cd3388701fe 100644
--- a/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb
+++ b/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb
@@ -206,18 +206,32 @@ RSpec.describe Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter, :cl
end
describe '.track_add_suggestion_action' do
- subject { described_class.track_add_suggestion_action(user: user) }
+ subject { described_class.track_add_suggestion_action(note: note) }
+
+ before do
+ note.suggestions << build(:suggestion, id: 1, note: note)
+ end
it_behaves_like 'a tracked merge request unique event' do
- let(:action) { described_class::MR_ADD_SUGGESTION_ACTION }
+ let(:action) { described_class::MR_USER_ADD_SUGGESTION_ACTION }
+ end
+
+ it_behaves_like 'a tracked merge request unique event' do
+ let(:action) { described_class::MR_TOTAL_ADD_SUGGESTION_ACTION }
end
end
describe '.track_apply_suggestion_action' do
- subject { described_class.track_apply_suggestion_action(user: user) }
+ subject { described_class.track_apply_suggestion_action(user: user, suggestions: suggestions) }
+
+ let(:suggestions) { [build(:suggestion, id: 1, note: note)] }
+
+ it_behaves_like 'a tracked merge request unique event' do
+ let(:action) { described_class::MR_USER_APPLY_SUGGESTION_ACTION }
+ end
it_behaves_like 'a tracked merge request unique event' do
- let(:action) { described_class::MR_APPLY_SUGGESTION_ACTION }
+ let(:action) { described_class::MR_TOTAL_APPLY_SUGGESTION_ACTION }
end
end
@@ -394,4 +408,12 @@ RSpec.describe Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter, :cl
let(:action) { described_class::MR_RESOLVE_CONFLICT_ACTION }
end
end
+
+ describe '.track_resolve_thread_in_issue_action' do
+ subject { described_class.track_resolve_thread_in_issue_action(user: user) }
+
+ it_behaves_like 'a tracked merge request unique event' do
+ let(:action) { described_class::MR_RESOLVE_THREAD_IN_ISSUE_ACTION }
+ end
+ end
end
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index 5d85ad5ad01..a70b68a181f 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -1089,6 +1089,10 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
expect(subject[:settings][:collected_data_categories]).to eq(expected_value)
end
+
+ it 'gathers service_ping_features_enabled' do
+ expect(subject[:settings][:service_ping_features_enabled]).to eq(Gitlab::CurrentSettings.usage_ping_features_enabled)
+ end
end
end
@@ -1279,9 +1283,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
subject { described_class.redis_hll_counters }
let(:categories) { ::Gitlab::UsageDataCounters::HLLRedisCounter.categories }
- let(:ineligible_total_categories) do
- %w[source_code ci_secrets_management incident_management_alerts snippets terraform incident_management_oncall secure network_policies]
- end
context 'with redis_hll_tracking feature enabled' do
it 'has all known_events' do
@@ -1296,7 +1297,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
metrics = keys.map { |key| "#{key}_weekly" } + keys.map { |key| "#{key}_monthly" }
- if ineligible_total_categories.exclude?(category)
+ if ::Gitlab::UsageDataCounters::HLLRedisCounter::CATEGORIES_FOR_TOTALS.include?(category)
metrics.append("#{category}_total_unique_counts_weekly", "#{category}_total_unique_counts_monthly")
end
diff --git a/spec/lib/gitlab/x509/tag_spec.rb b/spec/lib/gitlab/x509/tag_spec.rb
index be120aaf16a..f52880cfc52 100644
--- a/spec/lib/gitlab/x509/tag_spec.rb
+++ b/spec/lib/gitlab/x509/tag_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe Gitlab::X509::Tag do
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '', 'group/project') }
let(:project) { create(:project, :repository) }
- shared_examples 'signed tag' do
+ describe 'signed tag' do
let(:tag) { project.repository.find_tag('v1.1.1') }
let(:certificate_attributes) do
{
@@ -33,24 +33,10 @@ RSpec.describe Gitlab::X509::Tag do
it { expect(signature.x509_certificate.x509_issuer).to have_attributes(issuer_attributes) }
end
- shared_examples 'unsigned tag' do
+ describe 'unsigned tag' do
let(:tag) { project.repository.find_tag('v1.0.0') }
it { expect(signature).to be_nil }
end
-
- context 'with :get_tag_signatures enabled' do
- it_behaves_like 'signed tag'
- it_behaves_like 'unsigned tag'
- end
-
- context 'with :get_tag_signatures disabled' do
- before do
- stub_feature_flags(get_tag_signatures: false)
- end
-
- it_behaves_like 'signed tag'
- it_behaves_like 'unsigned tag'
- end
end
end
diff --git a/spec/lib/gitlab/zentao/client_spec.rb b/spec/lib/gitlab/zentao/client_spec.rb
new file mode 100644
index 00000000000..e3a335c1e89
--- /dev/null
+++ b/spec/lib/gitlab/zentao/client_spec.rb
@@ -0,0 +1,105 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Zentao::Client do
+ subject(:integration) { described_class.new(zentao_integration) }
+
+ let(:zentao_integration) { create(:zentao_integration) }
+ let(:mock_get_products_url) { integration.send(:url, "products/#{zentao_integration.zentao_product_xid}") }
+
+ describe '#new' do
+ context 'if integration is nil' do
+ let(:zentao_integration) { nil }
+
+ it 'raises ConfigError' do
+ expect { integration }.to raise_error(described_class::ConfigError)
+ end
+ end
+
+ context 'integration is provided' do
+ it 'is initialized successfully' do
+ expect { integration }.not_to raise_error
+ end
+ end
+ end
+
+ describe '#fetch_product' do
+ let(:mock_headers) do
+ {
+ headers: {
+ 'Content-Type' => 'application/json',
+ 'Token' => zentao_integration.api_token
+ }
+ }
+ end
+
+ context 'with valid product' do
+ let(:mock_response) { { 'id' => zentao_integration.zentao_product_xid } }
+
+ before do
+ WebMock.stub_request(:get, mock_get_products_url)
+ .with(mock_headers).to_return(status: 200, body: mock_response.to_json)
+ end
+
+ it 'fetches the product' do
+ expect(integration.fetch_product(zentao_integration.zentao_product_xid)).to eq mock_response
+ end
+ end
+
+ context 'with invalid product' do
+ before do
+ WebMock.stub_request(:get, mock_get_products_url)
+ .with(mock_headers).to_return(status: 404, body: {}.to_json)
+ end
+
+ it 'fetches the empty product' do
+ expect(integration.fetch_product(zentao_integration.zentao_product_xid)).to eq({})
+ end
+ end
+
+ context 'with invalid response' do
+ before do
+ WebMock.stub_request(:get, mock_get_products_url)
+ .with(mock_headers).to_return(status: 200, body: '[invalid json}')
+ end
+
+ it 'fetches the empty product' do
+ expect(integration.fetch_product(zentao_integration.zentao_product_xid)).to eq({})
+ end
+ end
+ end
+
+ describe '#ping' do
+ let(:mock_headers) do
+ {
+ headers: {
+ 'Content-Type' => 'application/json',
+ 'Token' => zentao_integration.api_token
+ }
+ }
+ end
+
+ context 'with valid resource' do
+ before do
+ WebMock.stub_request(:get, mock_get_products_url)
+ .with(mock_headers).to_return(status: 200, body: { 'deleted' => '0' }.to_json)
+ end
+
+ it 'responds with success' do
+ expect(integration.ping[:success]).to eq true
+ end
+ end
+
+ context 'with deleted resource' do
+ before do
+ WebMock.stub_request(:get, mock_get_products_url)
+ .with(mock_headers).to_return(status: 200, body: { 'deleted' => '1' }.to_json)
+ end
+
+ it 'responds with unsuccess' do
+ expect(integration.ping[:success]).to eq false
+ end
+ end
+ end
+end
diff --git a/spec/lib/marginalia_spec.rb b/spec/lib/marginalia_spec.rb
index dd57cd7980e..3f39d969dbd 100644
--- a/spec/lib/marginalia_spec.rb
+++ b/spec/lib/marginalia_spec.rb
@@ -42,7 +42,8 @@ RSpec.describe 'Marginalia spec' do
{
"application" => "test",
"endpoint_id" => "MarginaliaTestController#first_user",
- "correlation_id" => correlation_id
+ "correlation_id" => correlation_id,
+ "db_config_name" => "main"
}
end
@@ -51,6 +52,29 @@ RSpec.describe 'Marginalia spec' do
expect(recorded.log.last).to include("#{component}:#{value}")
end
end
+
+ context 'when using CI database' do
+ let(:component_map) do
+ {
+ "application" => "test",
+ "endpoint_id" => "MarginaliaTestController#first_user",
+ "correlation_id" => correlation_id,
+ "db_config_name" => "ci"
+ }
+ end
+
+ before do |example|
+ skip_if_multiple_databases_not_setup
+
+ allow(User).to receive(:connection) { Ci::CiDatabaseRecord.connection }
+ end
+
+ it 'generates a query that includes the component and value' do
+ component_map.each do |component, value|
+ expect(recorded.log.last).to include("#{component}:#{value}")
+ end
+ end
+ end
end
describe 'for Sidekiq worker jobs' do
@@ -79,7 +103,8 @@ RSpec.describe 'Marginalia spec' do
"application" => "sidekiq",
"endpoint_id" => "MarginaliaTestJob",
"correlation_id" => sidekiq_job['correlation_id'],
- "jid" => sidekiq_job['jid']
+ "jid" => sidekiq_job['jid'],
+ "db_config_name" => "main"
}
end
@@ -100,9 +125,10 @@ RSpec.describe 'Marginalia spec' do
let(:component_map) do
{
- "application" => "sidekiq",
- "endpoint_id" => "ActionMailer::MailDeliveryJob",
- "jid" => delivery_job.job_id
+ "application" => "sidekiq",
+ "endpoint_id" => "ActionMailer::MailDeliveryJob",
+ "jid" => delivery_job.job_id,
+ "db_config_name" => "main"
}
end
diff --git a/spec/lib/object_storage/config_spec.rb b/spec/lib/object_storage/config_spec.rb
index 0ead2a1d269..21b8a44b3d6 100644
--- a/spec/lib/object_storage/config_spec.rb
+++ b/spec/lib/object_storage/config_spec.rb
@@ -188,6 +188,7 @@ RSpec.describe ObjectStorage::Config do
end
context 'with SSE-KMS enabled' do
+ it { expect(subject.aws_server_side_encryption_enabled?).to be true }
it { expect(subject.server_side_encryption).to eq('AES256') }
it { expect(subject.server_side_encryption_kms_key_id).to eq('arn:aws:12345') }
it { expect(subject.fog_attributes.keys).to match_array(%w(x-amz-server-side-encryption x-amz-server-side-encryption-aws-kms-key-id)) }
@@ -196,6 +197,7 @@ RSpec.describe ObjectStorage::Config do
context 'with only server side encryption enabled' do
let(:storage_options) { { server_side_encryption: 'AES256' } }
+ it { expect(subject.aws_server_side_encryption_enabled?).to be true }
it { expect(subject.server_side_encryption).to eq('AES256') }
it { expect(subject.server_side_encryption_kms_key_id).to be_nil }
it { expect(subject.fog_attributes).to eq({ 'x-amz-server-side-encryption' => 'AES256' }) }
@@ -204,6 +206,7 @@ RSpec.describe ObjectStorage::Config do
context 'without encryption enabled' do
let(:storage_options) { {} }
+ it { expect(subject.aws_server_side_encryption_enabled?).to be false }
it { expect(subject.server_side_encryption).to be_nil }
it { expect(subject.server_side_encryption_kms_key_id).to be_nil }
it { expect(subject.fog_attributes).to eq({}) }
@@ -215,6 +218,5 @@ RSpec.describe ObjectStorage::Config do
end
it { expect(subject.enabled?).to be false }
- it { expect(subject.fog_attributes).to eq({}) }
end
end
diff --git a/spec/lib/sidebars/menu_spec.rb b/spec/lib/sidebars/menu_spec.rb
index 1db80351e45..eb6a68f1afd 100644
--- a/spec/lib/sidebars/menu_spec.rb
+++ b/spec/lib/sidebars/menu_spec.rb
@@ -198,4 +198,27 @@ RSpec.describe Sidebars::Menu do
end
end
end
+
+ describe '#link' do
+ let(:foo_path) { '/foo_path'}
+
+ let(:foo_menu) do
+ ::Sidebars::MenuItem.new(
+ title: 'foo',
+ link: foo_path,
+ active_routes: {},
+ item_id: :foo
+ )
+ end
+
+ it 'returns first visible menu item link' do
+ menu.add_item(foo_menu)
+
+ expect(menu.link).to eq foo_path
+ end
+
+ it 'returns nil if there are no visible menu items' do
+ expect(menu.link).to be_nil
+ end
+ end
end
diff --git a/spec/lib/sidebars/projects/menus/learn_gitlab_menu_spec.rb b/spec/lib/sidebars/projects/menus/learn_gitlab_menu_spec.rb
index 231e5a850c2..36a76e70a48 100644
--- a/spec/lib/sidebars/projects/menus/learn_gitlab_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/learn_gitlab_menu_spec.rb
@@ -4,15 +4,13 @@ require 'spec_helper'
RSpec.describe Sidebars::Projects::Menus::LearnGitlabMenu do
let_it_be(:project) { build(:project) }
- let_it_be(:experiment_enabled) { true }
- let_it_be(:tracking_category) { 'Growth::Activation::Experiment::LearnGitLabB' }
+ let_it_be(:learn_gitlab_enabled) { true }
let(:context) do
Sidebars::Projects::Context.new(
current_user: nil,
container: project,
- learn_gitlab_experiment_enabled: experiment_enabled,
- learn_gitlab_experiment_tracking_category: tracking_category
+ learn_gitlab_enabled: learn_gitlab_enabled
)
end
@@ -27,7 +25,6 @@ RSpec.describe Sidebars::Projects::Menus::LearnGitlabMenu do
{
class: 'home',
data: {
- track_property: tracking_category,
track_label: 'learn_gitlab'
}
}
@@ -46,7 +43,7 @@ RSpec.describe Sidebars::Projects::Menus::LearnGitlabMenu do
end
context 'when learn gitlab experiment is disabled' do
- let(:experiment_enabled) { false }
+ let(:learn_gitlab_enabled) { false }
it 'returns false' do
expect(subject.render?).to eq false
@@ -62,7 +59,7 @@ RSpec.describe Sidebars::Projects::Menus::LearnGitlabMenu do
end
context 'when learn gitlab experiment is disabled' do
- let(:experiment_enabled) { false }
+ let(:learn_gitlab_enabled) { false }
it 'returns false' do
expect(subject.has_pill?).to eq false
diff --git a/spec/lib/sidebars/projects/menus/monitor_menu_spec.rb b/spec/lib/sidebars/projects/menus/monitor_menu_spec.rb
index 381842be5ab..77efe99aaa9 100644
--- a/spec/lib/sidebars/projects/menus/monitor_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/monitor_menu_spec.rb
@@ -49,25 +49,6 @@ RSpec.describe Sidebars::Projects::Menus::MonitorMenu do
end
end
- describe '#link' do
- let(:foo_path) { '/foo_path'}
-
- let(:foo_menu) do
- ::Sidebars::MenuItem.new(
- title: 'foo',
- link: foo_path,
- active_routes: {},
- item_id: :foo
- )
- end
-
- it 'returns first visible item link' do
- subject.insert_element_before(subject.renderable_items, subject.renderable_items.first.item_id, foo_menu)
-
- expect(subject.link).to eq foo_path
- end
- end
-
context 'Menu items' do
subject { described_class.new(context).renderable_items.index { |e| e.item_id == item_id } }
diff --git a/spec/lib/sidebars/projects/menus/settings_menu_spec.rb b/spec/lib/sidebars/projects/menus/settings_menu_spec.rb
index 9b79614db20..3079c781d73 100644
--- a/spec/lib/sidebars/projects/menus/settings_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/settings_menu_spec.rb
@@ -158,5 +158,31 @@ RSpec.describe Sidebars::Projects::Menus::SettingsMenu do
end
end
end
+
+ describe 'Usage Quotas' do
+ let(:item_id) { :usage_quotas }
+
+ describe 'with project_storage_ui feature flag enabled' do
+ before do
+ stub_feature_flags(project_storage_ui: true)
+ end
+
+ specify { is_expected.not_to be_nil }
+
+ describe 'when the user does not have access' do
+ let(:user) { nil }
+
+ specify { is_expected.to be_nil }
+ end
+ end
+
+ describe 'with project_storage_ui feature flag disabled' do
+ before do
+ stub_feature_flags(project_storage_ui: false)
+ end
+
+ specify { is_expected.to be_nil }
+ end
+ end
end
end
diff --git a/spec/lib/system_check/incoming_email_check_spec.rb b/spec/lib/system_check/incoming_email_check_spec.rb
new file mode 100644
index 00000000000..710702b93fc
--- /dev/null
+++ b/spec/lib/system_check/incoming_email_check_spec.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe SystemCheck::IncomingEmailCheck do
+ before do
+ allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new('production'))
+ end
+
+ describe '#multi_check' do
+ context 'when incoming e-mail is disabled' do
+ before do
+ stub_incoming_email_setting(enabled: false)
+ end
+
+ it 'does not run any checks' do
+ expect(SystemCheck).not_to receive(:run)
+
+ subject.multi_check
+ end
+ end
+
+ context 'when incoming e-mail is enabled for IMAP' do
+ before do
+ stub_incoming_email_setting(enabled: true)
+ end
+
+ it 'runs IMAP and mailroom checks' do
+ expect(SystemCheck).to receive(:run).with('Reply by email', [
+ SystemCheck::IncomingEmail::ImapAuthenticationCheck,
+ SystemCheck::IncomingEmail::InitdConfiguredCheck,
+ SystemCheck::IncomingEmail::MailRoomRunningCheck
+ ])
+
+ subject.multi_check
+ end
+ end
+
+ context 'when incoming e-mail is enabled for Microsoft Graph' do
+ before do
+ stub_incoming_email_setting(enabled: true, inbox_method: 'microsoft_graph')
+ end
+
+ it 'runs mailroom checks' do
+ expect(SystemCheck).to receive(:run).with('Reply by email', [
+ SystemCheck::IncomingEmail::InitdConfiguredCheck,
+ SystemCheck::IncomingEmail::MailRoomRunningCheck
+ ])
+
+ subject.multi_check
+ end
+ end
+ end
+end
diff --git a/spec/mailers/emails/in_product_marketing_spec.rb b/spec/mailers/emails/in_product_marketing_spec.rb
index 74354630ade..99beef92dea 100644
--- a/spec/mailers/emails/in_product_marketing_spec.rb
+++ b/spec/mailers/emails/in_product_marketing_spec.rb
@@ -23,7 +23,7 @@ RSpec.describe Emails::InProductMarketing do
it 'sends to the right user with a link to unsubscribe' do
aggregate_failures do
- expect(subject).to deliver_to(user.notification_email)
+ expect(subject).to deliver_to(user.notification_email_or_default)
expect(subject).to have_body_text(profile_notifications_url)
end
end
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index 8272b5d64c1..f39037cf744 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -71,7 +71,7 @@ RSpec.describe Notify do
it 'is sent to the assignee as the author' do
aggregate_failures do
expect_sender(current_user)
- expect(subject).to deliver_to(recipient.notification_email)
+ expect(subject).to deliver_to(recipient.notification_email_or_default)
end
end
end
@@ -710,7 +710,7 @@ RSpec.describe Notify do
it 'contains all the useful information' do
to_emails = subject.header[:to].addrs.map(&:address)
- expect(to_emails).to eq([recipient.notification_email])
+ expect(to_emails).to eq([recipient.notification_email_or_default])
is_expected.to have_subject "Request to join the #{project.full_name} project"
is_expected.to have_body_text project.full_name
@@ -800,8 +800,7 @@ RSpec.describe Notify do
is_expected.to have_body_text project_member.invite_token
is_expected.to have_link('Join now',
href: invite_url(project_member.invite_token,
- invite_type: Emails::Members::INITIAL_INVITE,
- experiment_name: 'invite_email_preview_text'))
+ invite_type: Emails::Members::INITIAL_INVITE))
is_expected.to have_content("#{inviter.name} invited you to join the")
is_expected.to have_content('Project details')
is_expected.to have_content("What's it about?")
@@ -818,13 +817,54 @@ RSpec.describe Notify do
is_expected.to have_body_text project_member.invite_token
is_expected.to have_link('Join now',
href: invite_url(project_member.invite_token,
- invite_type: Emails::Members::INITIAL_INVITE,
- experiment_name: 'invite_email_preview_text'))
+ invite_type: Emails::Members::INITIAL_INVITE))
is_expected.to have_content('Project details')
is_expected.to have_content("What's it about?")
end
end
+ context 'with invite_email_preview_text enabled', :experiment do
+ before do
+ stub_experiments(invite_email_preview_text: :control)
+ end
+
+ it 'has the correct invite_url with params' do
+ is_expected.to have_link('Join now',
+ href: invite_url(project_member.invite_token,
+ invite_type: Emails::Members::INITIAL_INVITE,
+ experiment_name: 'invite_email_preview_text'))
+ end
+
+ it 'tracks the sent invite' do
+ expect(experiment(:invite_email_preview_text)).to track(:assignment)
+ .with_context(actor: project_member)
+ .on_next_instance
+
+ invite_email.deliver_now
+ end
+ end
+
+ context 'with invite_email_from enabled', :experiment do
+ before do
+ stub_experiments(invite_email_from: :control)
+ end
+
+ it 'has the correct invite_url with params' do
+ is_expected.to have_link('Join now',
+ href: invite_url(project_member.invite_token,
+ invite_type: Emails::Members::INITIAL_INVITE,
+ experiment_name: 'invite_email_from'))
+ end
+
+ it 'tracks the sent invite' do
+ expect(experiment(:invite_email_from)).to track(:assignment)
+ .with_context(actor: project_member)
+ .on_next_instance
+
+ invite_email.deliver_now
+ end
+ end
+
context 'when invite email sent is tracked', :snowplow do
it 'tracks the sent invite' do
invite_email.deliver_now
@@ -838,15 +878,15 @@ RSpec.describe Notify do
end
end
- context 'when on gitlab.com' do
+ context 'when mailgun events are enabled' do
before do
- allow(Gitlab).to receive(:dev_env_or_com?).and_return(true)
+ stub_application_setting(mailgun_events_enabled: true)
end
it 'has custom headers' do
aggregate_failures do
- expect(subject).to have_header('X-Mailgun-Tag', 'invite_email')
- expect(subject).to have_header('X-Mailgun-Variables', { 'invite_token' => project_member.invite_token }.to_json)
+ expect(subject).to have_header('X-Mailgun-Tag', ::Members::Mailgun::INVITE_EMAIL_TAG)
+ expect(subject).to have_header('X-Mailgun-Variables', { ::Members::Mailgun::INVITE_EMAIL_TOKEN_KEY => project_member.invite_token }.to_json)
end
end
end
@@ -1007,7 +1047,7 @@ RSpec.describe Notify do
it 'is sent to the given recipient as the author' do
aggregate_failures do
expect_sender(note_author)
- expect(subject).to deliver_to(recipient.notification_email)
+ expect(subject).to deliver_to(recipient.notification_email_or_default)
end
end
@@ -1164,7 +1204,7 @@ RSpec.describe Notify do
it 'is sent to the given recipient as the author' do
aggregate_failures do
expect_sender(note_author)
- expect(subject).to deliver_to(recipient.notification_email)
+ expect(subject).to deliver_to(recipient.notification_email_or_default)
end
end
@@ -1301,7 +1341,7 @@ RSpec.describe Notify do
it 'contains all the useful information' do
to_emails = subject.header[:to].addrs.map(&:address)
- expect(to_emails).to eq([recipient.notification_email])
+ expect(to_emails).to eq([recipient.notification_email_or_default])
is_expected.to have_subject "Request to join the #{group.name} group"
is_expected.to have_body_text group.name
diff --git a/spec/migrations/20210804150320_create_base_work_item_types_spec.rb b/spec/migrations/20210804150320_create_base_work_item_types_spec.rb
index 535472f5931..9ba29637e00 100644
--- a/spec/migrations/20210804150320_create_base_work_item_types_spec.rb
+++ b/spec/migrations/20210804150320_create_base_work_item_types_spec.rb
@@ -6,7 +6,17 @@ require_migration!('create_base_work_item_types')
RSpec.describe CreateBaseWorkItemTypes, :migration do
let!(:work_item_types) { table(:work_item_types) }
+ after(:all) do
+ # Make sure base types are recreated after running the migration
+ # because migration specs are not run in a transaction
+ WorkItem::Type.delete_all
+ Gitlab::DatabaseImporters::WorkItems::BaseTypeImporter.import
+ end
+
it 'creates default data' do
+ # Need to delete all as base types are seeded before entire test suite
+ WorkItem::Type.delete_all
+
reversible_migration do |migration|
migration.before -> {
# Depending on whether the migration has been run before,
diff --git a/spec/migrations/20210818185845_backfill_projects_with_coverage_spec.rb b/spec/migrations/20210818185845_backfill_projects_with_coverage_spec.rb
new file mode 100644
index 00000000000..d87f952b5da
--- /dev/null
+++ b/spec/migrations/20210818185845_backfill_projects_with_coverage_spec.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!('backfill_projects_with_coverage')
+
+RSpec.describe BackfillProjectsWithCoverage do
+ let(:projects) { table(:projects) }
+ let(:ci_pipelines) { table(:ci_pipelines) }
+ let(:ci_daily_build_group_report_results) { table(:ci_daily_build_group_report_results) }
+ let(:group) { table(:namespaces).create!(name: 'user', path: 'user') }
+ let(:project_1) { projects.create!(namespace_id: group.id) }
+ let(:project_2) { projects.create!(namespace_id: group.id) }
+ let(:pipeline_1) { ci_pipelines.create!(project_id: project_1.id) }
+ let(:pipeline_2) { ci_pipelines.create!(project_id: project_2.id) }
+ let(:pipeline_3) { ci_pipelines.create!(project_id: project_2.id) }
+
+ describe '#up' do
+ before do
+ stub_const("#{described_class}::BATCH_SIZE", 2)
+ stub_const("#{described_class}::SUB_BATCH_SIZE", 1)
+
+ ci_daily_build_group_report_results.create!(
+ id: 1,
+ project_id: project_1.id,
+ date: 3.days.ago,
+ last_pipeline_id: pipeline_1.id,
+ ref_path: 'main',
+ group_name: 'rspec',
+ data: { coverage: 95.0 },
+ default_branch: true,
+ group_id: group.id
+ )
+
+ ci_daily_build_group_report_results.create!(
+ id: 2,
+ project_id: project_2.id,
+ date: 2.days.ago,
+ last_pipeline_id: pipeline_2.id,
+ ref_path: 'main',
+ group_name: 'rspec',
+ data: { coverage: 95.0 },
+ default_branch: true,
+ group_id: group.id
+ )
+
+ ci_daily_build_group_report_results.create!(
+ id: 3,
+ project_id: project_2.id,
+ date: 1.day.ago,
+ last_pipeline_id: pipeline_3.id,
+ ref_path: 'test_branch',
+ group_name: 'rspec',
+ data: { coverage: 95.0 },
+ default_branch: false,
+ group_id: group.id
+ )
+ end
+
+ it 'schedules BackfillProjectsWithCoverage background jobs', :aggregate_failures do
+ Sidekiq::Testing.fake! do
+ freeze_time do
+ migrate!
+
+ expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, 1, 2, 1)
+ expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, 3, 3, 1)
+ expect(BackgroundMigrationWorker.jobs.size).to eq(2)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20210819145000_drop_temporary_columns_and_triggers_for_ci_builds_runner_session_spec.rb b/spec/migrations/20210819145000_drop_temporary_columns_and_triggers_for_ci_builds_runner_session_spec.rb
new file mode 100644
index 00000000000..b1751216732
--- /dev/null
+++ b/spec/migrations/20210819145000_drop_temporary_columns_and_triggers_for_ci_builds_runner_session_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!('drop_temporary_columns_and_triggers_for_ci_builds_runner_session')
+
+RSpec.describe DropTemporaryColumnsAndTriggersForCiBuildsRunnerSession, :migration do
+ let(:ci_builds_runner_session_table) { table(:ci_builds_runner_session) }
+
+ it 'correctly migrates up and down' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(ci_builds_runner_session_table.column_names).to include('build_id_convert_to_bigint')
+ }
+
+ migration.after -> {
+ ci_builds_runner_session_table.reset_column_information
+ expect(ci_builds_runner_session_table.column_names).not_to include('build_id_convert_to_bigint')
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20210831203408_upsert_base_work_item_types_spec.rb b/spec/migrations/20210831203408_upsert_base_work_item_types_spec.rb
new file mode 100644
index 00000000000..c23110750c3
--- /dev/null
+++ b/spec/migrations/20210831203408_upsert_base_work_item_types_spec.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!('upsert_base_work_item_types')
+
+RSpec.describe UpsertBaseWorkItemTypes, :migration do
+ let!(:work_item_types) { table(:work_item_types) }
+
+ after(:all) do
+ # Make sure base types are recreated after running the migration
+ # because migration specs are not run in a transaction
+ WorkItem::Type.delete_all
+ Gitlab::DatabaseImporters::WorkItems::BaseTypeImporter.import
+ end
+
+ context 'when no default types exist' do
+ it 'creates default data' do
+ # Need to delete all as base types are seeded before entire test suite
+ WorkItem::Type.delete_all
+
+ expect(work_item_types.count).to eq(0)
+
+ reversible_migration do |migration|
+ migration.before -> {
+ # Depending on whether the migration has been run before,
+ # the size could be 4, or 0, so we don't set any expectations
+ # as we don't delete base types on migration reverse
+ }
+
+ migration.after -> {
+ expect(work_item_types.count).to eq(4)
+ expect(work_item_types.all.pluck(:base_type)).to match_array(WorkItem::Type.base_types.values)
+ }
+ end
+ end
+ end
+
+ context 'when default types already exist' do
+ it 'does not create default types again' do
+ expect(work_item_types.all.pluck(:base_type)).to match_array(WorkItem::Type.base_types.values)
+
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(work_item_types.all.pluck(:base_type)).to match_array(WorkItem::Type.base_types.values)
+ }
+
+ migration.after -> {
+ expect(work_item_types.count).to eq(4)
+ expect(work_item_types.all.pluck(:base_type)).to match_array(WorkItem::Type.base_types.values)
+ }
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20210902144144_drop_temporary_columns_and_triggers_for_ci_build_needs_spec.rb b/spec/migrations/20210902144144_drop_temporary_columns_and_triggers_for_ci_build_needs_spec.rb
new file mode 100644
index 00000000000..1b35982c41d
--- /dev/null
+++ b/spec/migrations/20210902144144_drop_temporary_columns_and_triggers_for_ci_build_needs_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!('drop_temporary_columns_and_triggers_for_ci_build_needs')
+
+RSpec.describe DropTemporaryColumnsAndTriggersForCiBuildNeeds do
+ let(:ci_build_needs_table) { table(:ci_build_needs) }
+
+ it 'correctly migrates up and down' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(ci_build_needs_table.column_names).to include('build_id_convert_to_bigint')
+ }
+
+ migration.after -> {
+ ci_build_needs_table.reset_column_information
+ expect(ci_build_needs_table.column_names).not_to include('build_id_convert_to_bigint')
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20210906100316_drop_temporary_columns_and_triggers_for_ci_build_trace_chunks_spec.rb b/spec/migrations/20210906100316_drop_temporary_columns_and_triggers_for_ci_build_trace_chunks_spec.rb
new file mode 100644
index 00000000000..8d46ba7eb58
--- /dev/null
+++ b/spec/migrations/20210906100316_drop_temporary_columns_and_triggers_for_ci_build_trace_chunks_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!('drop_temporary_columns_and_triggers_for_ci_build_trace_chunks')
+
+RSpec.describe DropTemporaryColumnsAndTriggersForCiBuildTraceChunks do
+ let(:ci_build_trace_chunks_table) { table(:ci_build_trace_chunks) }
+
+ it 'correctly migrates up and down' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(ci_build_trace_chunks_table.column_names).to include('build_id_convert_to_bigint')
+ }
+
+ migration.after -> {
+ ci_build_trace_chunks_table.reset_column_information
+ expect(ci_build_trace_chunks_table.column_names).not_to include('build_id_convert_to_bigint')
+ }
+ end
+ end
+end
diff --git a/spec/migrations/active_record/schema_spec.rb b/spec/migrations/active_record/schema_spec.rb
index 4a505c51a16..042b5710dce 100644
--- a/spec/migrations/active_record/schema_spec.rb
+++ b/spec/migrations/active_record/schema_spec.rb
@@ -7,7 +7,7 @@ require 'spec_helper'
RSpec.describe ActiveRecord::Schema, schema: :latest do
let(:all_migrations) do
- migrations_directories = %w[db/migrate db/post_migrate].map { |path| Rails.root.join(path).to_s }
+ migrations_directories = Rails.application.paths["db/migrate"].paths.map(&:to_s)
migrations_paths = migrations_directories.map { |path| File.join(path, '*') }
migrations = Dir[*migrations_paths] - migrations_directories
diff --git a/spec/migrations/add_default_project_approval_rules_vuln_allowed_spec.rb b/spec/migrations/add_default_project_approval_rules_vuln_allowed_spec.rb
new file mode 100644
index 00000000000..057e95eb158
--- /dev/null
+++ b/spec/migrations/add_default_project_approval_rules_vuln_allowed_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe AddDefaultProjectApprovalRulesVulnAllowed do
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:namespace) { namespaces.create!(name: 'namespace', path: 'namespace') }
+ let(:project) { projects.create!(name: 'project', path: 'project', namespace_id: namespace.id) }
+ let(:approval_project_rules) { table(:approval_project_rules) }
+
+ it 'updates records when vulnerabilities_allowed is nil' do
+ records_to_migrate = 10
+
+ records_to_migrate.times do |i|
+ approval_project_rules.create!(name: "rule #{i}", project_id: project.id)
+ end
+
+ expect { migrate! }
+ .to change { approval_project_rules.where(vulnerabilities_allowed: nil).count }
+ .from(records_to_migrate)
+ .to(0)
+ end
+
+ it 'defaults vulnerabilities_allowed to 0' do
+ approval_project_rule = approval_project_rules.create!(name: "new rule", project_id: project.id)
+
+ expect(approval_project_rule.vulnerabilities_allowed).to be_nil
+
+ migrate!
+
+ expect(approval_project_rule.reload.vulnerabilities_allowed).to eq(0)
+ end
+end
diff --git a/spec/migrations/add_triggers_to_integrations_type_new_spec.rb b/spec/migrations/add_triggers_to_integrations_type_new_spec.rb
index 07845715a52..01af5884170 100644
--- a/spec/migrations/add_triggers_to_integrations_type_new_spec.rb
+++ b/spec/migrations/add_triggers_to_integrations_type_new_spec.rb
@@ -8,6 +8,18 @@ RSpec.describe AddTriggersToIntegrationsTypeNew do
let(:migration) { described_class.new }
let(:integrations) { table(:integrations) }
+ # This matches Gitlab::Integrations::StiType at the time the trigger was added
+ let(:namespaced_integrations) do
+ %w[
+ Asana Assembla Bamboo Bugzilla Buildkite Campfire Confluence CustomIssueTracker Datadog
+ Discord DroneCi EmailsOnPush Ewm ExternalWiki Flowdock HangoutsChat Irker Jenkins Jira Mattermost
+ MattermostSlashCommands MicrosoftTeams MockCi MockMonitoring Packagist PipelinesEmail Pivotaltracker
+ Prometheus Pushover Redmine Slack SlackSlashCommands Teamcity UnifyCircuit WebexTeams Youtrack
+
+ Github GitlabSlackApplication
+ ]
+ end
+
describe '#up' do
before do
migrate!
@@ -15,7 +27,7 @@ RSpec.describe AddTriggersToIntegrationsTypeNew do
describe 'INSERT trigger' do
it 'sets `type_new` to the transformed `type` class name' do
- Gitlab::Integrations::StiType.namespaced_integrations.each do |type|
+ namespaced_integrations.each do |type|
integration = integrations.create!(type: "#{type}Service")
expect(integration.reload).to have_attributes(
diff --git a/spec/migrations/backfill_cadence_id_for_boards_scoped_to_iteration_spec.rb b/spec/migrations/backfill_cadence_id_for_boards_scoped_to_iteration_spec.rb
new file mode 100644
index 00000000000..1a64de8d0db
--- /dev/null
+++ b/spec/migrations/backfill_cadence_id_for_boards_scoped_to_iteration_spec.rb
@@ -0,0 +1,109 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+# require Rails.root.join('db', 'post_migrate', '20210825193652_backfill_candence_id_for_boards_scoped_to_iteration.rb')
+
+RSpec.describe BackfillCadenceIdForBoardsScopedToIteration, :migration do
+ let(:projects) { table(:projects) }
+ let(:namespaces) { table(:namespaces) }
+ let(:iterations_cadences) { table(:iterations_cadences) }
+ let(:boards) { table(:boards) }
+
+ let!(:group) { namespaces.create!(name: 'group1', path: 'group1', type: 'Group') }
+ let!(:cadence) { iterations_cadences.create!(title: 'group cadence', group_id: group.id, start_date: Time.current) }
+ let!(:project) { projects.create!(name: 'gitlab1', path: 'gitlab1', namespace_id: group.id, visibility_level: 0) }
+ let!(:project_board1) { boards.create!(name: 'Project Dev1', project_id: project.id) }
+ let!(:project_board2) { boards.create!(name: 'Project Dev2', project_id: project.id, iteration_id: -4) }
+ let!(:project_board3) { boards.create!(name: 'Project Dev3', project_id: project.id, iteration_id: -4) }
+ let!(:project_board4) { boards.create!(name: 'Project Dev4', project_id: project.id, iteration_id: -4) }
+
+ let!(:group_board1) { boards.create!(name: 'Group Dev1', group_id: group.id) }
+ let!(:group_board2) { boards.create!(name: 'Group Dev2', group_id: group.id, iteration_id: -4) }
+ let!(:group_board3) { boards.create!(name: 'Group Dev3', group_id: group.id, iteration_id: -4) }
+ let!(:group_board4) { boards.create!(name: 'Group Dev4', group_id: group.id, iteration_id: -4) }
+
+ describe '#up' do
+ it 'schedules background migrations' do
+ Sidekiq::Testing.fake! do
+ freeze_time do
+ described_class.new.up
+
+ migration = described_class::MIGRATION
+
+ expect(migration).to be_scheduled_delayed_migration(2.minutes, 'group', 'up', group_board2.id, group_board4.id)
+ expect(migration).to be_scheduled_delayed_migration(2.minutes, 'project', 'up', project_board2.id, project_board4.id)
+ expect(BackgroundMigrationWorker.jobs.size).to eq 2
+ end
+ end
+ end
+
+ context 'in batches' do
+ before do
+ stub_const('BackfillCadenceIdForBoardsScopedToIteration::BATCH_SIZE', 2)
+ end
+
+ it 'schedules background migrations' do
+ Sidekiq::Testing.fake! do
+ freeze_time do
+ described_class.new.up
+
+ migration = described_class::MIGRATION
+
+ expect(migration).to be_scheduled_delayed_migration(2.minutes, 'group', 'up', group_board2.id, group_board3.id)
+ expect(migration).to be_scheduled_delayed_migration(4.minutes, 'group', 'up', group_board4.id, group_board4.id)
+ expect(migration).to be_scheduled_delayed_migration(2.minutes, 'project', 'up', project_board2.id, project_board3.id)
+ expect(migration).to be_scheduled_delayed_migration(4.minutes, 'project', 'up', project_board4.id, project_board4.id)
+ expect(BackgroundMigrationWorker.jobs.size).to eq 4
+ end
+ end
+ end
+ end
+ end
+
+ describe '#down' do
+ let!(:project_board1) { boards.create!(name: 'Project Dev1', project_id: project.id) }
+ let!(:project_board2) { boards.create!(name: 'Project Dev2', project_id: project.id, iteration_cadence_id: cadence.id) }
+ let!(:project_board3) { boards.create!(name: 'Project Dev3', project_id: project.id, iteration_id: -4, iteration_cadence_id: cadence.id) }
+ let!(:project_board4) { boards.create!(name: 'Project Dev4', project_id: project.id, iteration_id: -4, iteration_cadence_id: cadence.id) }
+
+ let!(:group_board1) { boards.create!(name: 'Group Dev1', group_id: group.id) }
+ let!(:group_board2) { boards.create!(name: 'Group Dev2', group_id: group.id, iteration_cadence_id: cadence.id) }
+ let!(:group_board3) { boards.create!(name: 'Group Dev3', group_id: group.id, iteration_id: -4, iteration_cadence_id: cadence.id) }
+ let!(:group_board4) { boards.create!(name: 'Group Dev4', group_id: group.id, iteration_id: -4, iteration_cadence_id: cadence.id) }
+
+ it 'schedules background migrations' do
+ Sidekiq::Testing.fake! do
+ freeze_time do
+ described_class.new.down
+
+ migration = described_class::MIGRATION
+
+ expect(migration).to be_scheduled_delayed_migration(2.minutes, 'none', 'down', project_board2.id, group_board4.id)
+ expect(BackgroundMigrationWorker.jobs.size).to eq 1
+ end
+ end
+ end
+
+ context 'in batches' do
+ before do
+ stub_const('BackfillCadenceIdForBoardsScopedToIteration::BATCH_SIZE', 2)
+ end
+
+ it 'schedules background migrations' do
+ Sidekiq::Testing.fake! do
+ freeze_time do
+ described_class.new.down
+
+ migration = described_class::MIGRATION
+
+ expect(migration).to be_scheduled_delayed_migration(2.minutes, 'none', 'down', project_board2.id, project_board3.id)
+ expect(migration).to be_scheduled_delayed_migration(4.minutes, 'none', 'down', project_board4.id, group_board2.id)
+ expect(migration).to be_scheduled_delayed_migration(6.minutes, 'none', 'down', group_board3.id, group_board4.id)
+ expect(BackgroundMigrationWorker.jobs.size).to eq 3
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/backfill_stage_event_hash_spec.rb b/spec/migrations/backfill_stage_event_hash_spec.rb
new file mode 100644
index 00000000000..cecaddcd3d4
--- /dev/null
+++ b/spec/migrations/backfill_stage_event_hash_spec.rb
@@ -0,0 +1,103 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe BackfillStageEventHash, schema: 20210730103808 do
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:labels) { table(:labels) }
+ let(:group_stages) { table(:analytics_cycle_analytics_group_stages) }
+ let(:project_stages) { table(:analytics_cycle_analytics_project_stages) }
+ let(:group_value_streams) { table(:analytics_cycle_analytics_group_value_streams) }
+ let(:project_value_streams) { table(:analytics_cycle_analytics_project_value_streams) }
+ let(:stage_event_hashes) { table(:analytics_cycle_analytics_stage_event_hashes) }
+
+ let(:issue_created) { 1 }
+ let(:issue_closed) { 3 }
+ let(:issue_label_removed) { 9 }
+ let(:unknown_stage_event) { -1 }
+
+ let(:namespace) { namespaces.create!(name: 'ns', path: 'ns', type: 'Group') }
+ let(:project) { projects.create!(name: 'project', path: 'project', namespace_id: namespace.id) }
+ let(:group_label) { labels.create!(title: 'label', type: 'GroupLabel', group_id: namespace.id) }
+ let(:group_value_stream) { group_value_streams.create!(name: 'group vs', group_id: namespace.id) }
+ let(:project_value_stream) { project_value_streams.create!(name: 'project vs', project_id: project.id) }
+
+ let(:group_stage_1) do
+ group_stages.create!(
+ name: 'stage 1',
+ group_id: namespace.id,
+ start_event_identifier: issue_created,
+ end_event_identifier: issue_closed,
+ group_value_stream_id: group_value_stream.id
+ )
+ end
+
+ let(:group_stage_2) do
+ group_stages.create!(
+ name: 'stage 2',
+ group_id: namespace.id,
+ start_event_identifier: issue_created,
+ end_event_identifier: issue_label_removed,
+ end_event_label_id: group_label.id,
+ group_value_stream_id: group_value_stream.id
+ )
+ end
+
+ let(:project_stage_1) do
+ project_stages.create!(
+ name: 'stage 1',
+ project_id: project.id,
+ start_event_identifier: issue_created,
+ end_event_identifier: issue_closed,
+ project_value_stream_id: project_value_stream.id
+ )
+ end
+
+ let(:invalid_group_stage) do
+ group_stages.create!(
+ name: 'stage 3',
+ group_id: namespace.id,
+ start_event_identifier: issue_created,
+ end_event_identifier: unknown_stage_event,
+ group_value_stream_id: group_value_stream.id
+ )
+ end
+
+ describe '#up' do
+ it 'populates stage_event_hash_id column' do
+ group_stage_1
+ group_stage_2
+ project_stage_1
+
+ migrate!
+
+ group_stage_1.reload
+ group_stage_2.reload
+ project_stage_1.reload
+
+ expect(group_stage_1.stage_event_hash_id).not_to be_nil
+ expect(group_stage_2.stage_event_hash_id).not_to be_nil
+ expect(project_stage_1.stage_event_hash_id).not_to be_nil
+
+ expect(stage_event_hashes.count).to eq(2) # group_stage_1 and project_stage_1 has the same hash
+ end
+
+ it 'runs without problem without stages' do
+ expect { migrate! }.not_to raise_error
+ end
+
+ context 'when invalid event identifier is discovered' do
+ it 'removes the stage' do
+ group_stage_1
+ invalid_group_stage
+
+ expect { migrate! }.not_to change { group_stage_1 }
+
+ expect(group_stages.find_by_id(invalid_group_stage.id)).to eq(nil)
+ end
+ end
+ end
+end
diff --git a/spec/migrations/cleanup_remaining_orphan_invites_spec.rb b/spec/migrations/cleanup_remaining_orphan_invites_spec.rb
new file mode 100644
index 00000000000..0eb1f5a578a
--- /dev/null
+++ b/spec/migrations/cleanup_remaining_orphan_invites_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration! 'cleanup_remaining_orphan_invites'
+
+RSpec.describe CleanupRemainingOrphanInvites, :migration do
+ def create_member(**extra_attributes)
+ defaults = {
+ access_level: 10,
+ source_id: 1,
+ source_type: "Project",
+ notification_level: 0,
+ type: 'ProjectMember'
+ }
+
+ table(:members).create!(defaults.merge(extra_attributes))
+ end
+
+ def create_user(**extra_attributes)
+ defaults = { projects_limit: 0 }
+ table(:users).create!(defaults.merge(extra_attributes))
+ end
+
+ describe '#up', :aggregate_failures do
+ it 'removes invite tokens for accepted records' do
+ record1 = create_member(invite_token: 'foo', user_id: nil)
+ record2 = create_member(invite_token: 'foo2', user_id: create_user(username: 'foo', email: 'foo@example.com').id)
+ record3 = create_member(invite_token: nil, user_id: create_user(username: 'bar', email: 'bar@example.com').id)
+
+ migrate!
+
+ expect(table(:members).find(record1.id).invite_token).to eq 'foo'
+ expect(table(:members).find(record2.id).invite_token).to eq nil
+ expect(table(:members).find(record3.id).invite_token).to eq nil
+ end
+ end
+end
diff --git a/spec/migrations/disable_job_token_scope_when_unused_spec.rb b/spec/migrations/disable_job_token_scope_when_unused_spec.rb
new file mode 100644
index 00000000000..d969c98aa0f
--- /dev/null
+++ b/spec/migrations/disable_job_token_scope_when_unused_spec.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe DisableJobTokenScopeWhenUnused do
+ let(:ci_cd_settings) { table(:project_ci_cd_settings) }
+ let(:links) { table(:ci_job_token_project_scope_links) }
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+
+ let(:namespace) { namespaces.create!(name: 'test', path: 'path', type: 'Group') }
+
+ let(:project_with_used_scope) { projects.create!(namespace_id: namespace.id) }
+ let!(:used_scope_settings) { ci_cd_settings.create!(project_id: project_with_used_scope.id, job_token_scope_enabled: true) }
+ let(:target_project) { projects.create!(namespace_id: namespace.id) }
+ let!(:link) { links.create!(source_project_id: project_with_used_scope.id, target_project_id: target_project.id) }
+
+ let(:project_with_unused_scope) { projects.create!(namespace_id: namespace.id) }
+ let!(:unused_scope_settings) { ci_cd_settings.create!(project_id: project_with_unused_scope.id, job_token_scope_enabled: true) }
+
+ let(:project_with_disabled_scope) { projects.create!(namespace_id: namespace.id) }
+ let!(:disabled_scope_settings) { ci_cd_settings.create!(project_id: project_with_disabled_scope.id, job_token_scope_enabled: false) }
+
+ describe '#up' do
+ it 'sets job_token_scope_enabled to false for projects not having job token scope configured' do
+ migrate!
+
+ expect(unused_scope_settings.reload.job_token_scope_enabled).to be_falsey
+ end
+
+ it 'keeps the scope enabled for projects that are using it' do
+ migrate!
+
+ expect(used_scope_settings.reload.job_token_scope_enabled).to be_truthy
+ end
+
+ it 'keeps the scope disabled for projects having it disabled' do
+ migrate!
+
+ expect(disabled_scope_settings.reload.job_token_scope_enabled).to be_falsey
+ end
+ end
+end
diff --git a/spec/migrations/remove_duplicate_dast_site_tokens_spec.rb b/spec/migrations/remove_duplicate_dast_site_tokens_spec.rb
new file mode 100644
index 00000000000..fed9941b2a4
--- /dev/null
+++ b/spec/migrations/remove_duplicate_dast_site_tokens_spec.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe RemoveDuplicateDastSiteTokens do
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:dast_site_tokens) { table(:dast_site_tokens) }
+ let!(:namespace) { namespaces.create!(id: 1, name: 'group', path: 'group') }
+ let!(:project1) { projects.create!(id: 1, namespace_id: namespace.id, path: 'project1') }
+ # create non duplicate dast site token
+ let!(:dast_site_token1) { dast_site_tokens.create!(project_id: project1.id, url: 'https://gitlab.com', token: SecureRandom.uuid) }
+
+ context 'when duplicate dast site tokens exists' do
+ # create duplicate dast site token
+ let_it_be(:duplicate_url) { 'https://about.gitlab.com' }
+
+ let!(:project2) { projects.create!(id: 2, namespace_id: namespace.id, path: 'project2') }
+ let!(:dast_site_token2) { dast_site_tokens.create!(project_id: project2.id, url: duplicate_url, token: SecureRandom.uuid) }
+ let!(:dast_site_token3) { dast_site_tokens.create!(project_id: project2.id, url: 'https://temp_url.com', token: SecureRandom.uuid) }
+ let!(:dast_site_token4) { dast_site_tokens.create!(project_id: project2.id, url: 'https://other_temp_url.com', token: SecureRandom.uuid) }
+
+ before 'update URL to bypass uniqueness validation' do
+ dast_site_tokens.where(project_id: 2).update_all(url: duplicate_url)
+ end
+
+ describe 'migration up' do
+ it 'does remove duplicated dast site tokens' do
+ expect(dast_site_tokens.count).to eq(4)
+ expect(dast_site_tokens.where(project_id: 2, url: duplicate_url).size).to eq(3)
+
+ migrate!
+
+ expect(dast_site_tokens.count).to eq(2)
+ expect(dast_site_tokens.where(project_id: 2, url: duplicate_url).size).to eq(1)
+ end
+ end
+ end
+
+ context 'when duplicate dast site tokens does not exists' do
+ before do
+ dast_site_tokens.create!(project_id: 1, url: 'https://about.gitlab.com/handbook', token: SecureRandom.uuid)
+ end
+
+ describe 'migration up' do
+ it 'does remove duplicated dast site tokens' do
+ expect { migrate! }.not_to change(dast_site_tokens, :count)
+ end
+ end
+ end
+end
diff --git a/spec/migrations/remove_duplicate_dast_site_tokens_with_same_token_spec.rb b/spec/migrations/remove_duplicate_dast_site_tokens_with_same_token_spec.rb
new file mode 100644
index 00000000000..57d677af5cf
--- /dev/null
+++ b/spec/migrations/remove_duplicate_dast_site_tokens_with_same_token_spec.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe RemoveDuplicateDastSiteTokensWithSameToken do
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:dast_site_tokens) { table(:dast_site_tokens) }
+ let!(:namespace) { namespaces.create!(id: 1, name: 'group', path: 'group') }
+ let!(:project1) { projects.create!(id: 1, namespace_id: namespace.id, path: 'project1') }
+ # create non duplicate dast site token
+ let!(:dast_site_token1) { dast_site_tokens.create!(project_id: project1.id, url: 'https://gitlab.com', token: SecureRandom.uuid) }
+
+ context 'when duplicate dast site tokens exists' do
+ # create duplicate dast site token
+ let_it_be(:duplicate_token) { 'duplicate_token' }
+ let_it_be(:other_duplicate_token) { 'other_duplicate_token' }
+
+ let!(:project2) { projects.create!(id: 2, namespace_id: namespace.id, path: 'project2') }
+ let!(:dast_site_token2) { dast_site_tokens.create!(project_id: project2.id, url: 'https://gitlab2.com', token: duplicate_token) }
+ let!(:dast_site_token3) { dast_site_tokens.create!(project_id: project2.id, url: 'https://gitlab3.com', token: duplicate_token) }
+ let!(:dast_site_token4) { dast_site_tokens.create!(project_id: project2.id, url: 'https://gitlab4.com', token: duplicate_token) }
+
+ let!(:project3) { projects.create!(id: 3, namespace_id: namespace.id, path: 'project3') }
+ let!(:dast_site_token5) { dast_site_tokens.create!(project_id: project3.id, url: 'https://gitlab2.com', token: other_duplicate_token) }
+ let!(:dast_site_token6) { dast_site_tokens.create!(project_id: project3.id, url: 'https://gitlab3.com', token: other_duplicate_token) }
+ let!(:dast_site_token7) { dast_site_tokens.create!(project_id: project3.id, url: 'https://gitlab4.com', token: other_duplicate_token) }
+
+ describe 'migration up' do
+ it 'does remove duplicated dast site tokens with the same token' do
+ expect(dast_site_tokens.count).to eq(7)
+ expect(dast_site_tokens.where(token: duplicate_token).size).to eq(3)
+
+ migrate!
+
+ expect(dast_site_tokens.count).to eq(3)
+ expect(dast_site_tokens.where(token: duplicate_token).size).to eq(1)
+ end
+ end
+ end
+
+ context 'when duplicate dast site tokens do not exist' do
+ let!(:dast_site_token5) { dast_site_tokens.create!(project_id: 1, url: 'https://gitlab5.com', token: SecureRandom.uuid) }
+
+ describe 'migration up' do
+ it 'does not remove any dast site tokens' do
+ expect { migrate! }.not_to change(dast_site_tokens, :count)
+ end
+ end
+ end
+end
diff --git a/spec/migrations/replace_external_wiki_triggers_spec.rb b/spec/migrations/replace_external_wiki_triggers_spec.rb
new file mode 100644
index 00000000000..392ef76c5ba
--- /dev/null
+++ b/spec/migrations/replace_external_wiki_triggers_spec.rb
@@ -0,0 +1,132 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe ReplaceExternalWikiTriggers do
+ let(:migration) { described_class.new }
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:integrations) { table(:integrations) }
+
+ before do
+ @namespace = namespaces.create!(name: 'foo', path: 'foo')
+ @project = projects.create!(namespace_id: @namespace.id)
+ end
+
+ def create_external_wiki_integration(**attrs)
+ attrs.merge!(type_info)
+
+ integrations.create!(**attrs)
+ end
+
+ def has_external_wiki
+ !!@project.reload.has_external_wiki
+ end
+
+ shared_examples 'external wiki triggers' do
+ describe 'INSERT trigger' do
+ it 'sets `has_external_wiki` to true when active external wiki integration is inserted' do
+ expect do
+ create_external_wiki_integration(active: true, project_id: @project.id)
+ end.to change { has_external_wiki }.to(true)
+ end
+
+ it 'does not set `has_external_wiki` to true when integration is for a different project' do
+ different_project = projects.create!(namespace_id: @namespace.id)
+
+ expect do
+ create_external_wiki_integration(active: true, project_id: different_project.id)
+ end.not_to change { has_external_wiki }
+ end
+
+ it 'does not set `has_external_wiki` to true when inactive external wiki integration is inserted' do
+ expect do
+ create_external_wiki_integration(active: false, project_id: @project.id)
+ end.not_to change { has_external_wiki }
+ end
+
+ it 'does not set `has_external_wiki` to true when active other service is inserted' do
+ expect do
+ integrations.create!(type_new: 'Integrations::MyService', type: 'MyService', active: true, project_id: @project.id)
+ end.not_to change { has_external_wiki }
+ end
+ end
+
+ describe 'UPDATE trigger' do
+ it 'sets `has_external_wiki` to true when `ExternalWikiService` is made active' do
+ service = create_external_wiki_integration(active: false, project_id: @project.id)
+
+ expect do
+ service.update!(active: true)
+ end.to change { has_external_wiki }.to(true)
+ end
+
+ it 'sets `has_external_wiki` to false when integration is made inactive' do
+ service = create_external_wiki_integration(active: true, project_id: @project.id)
+
+ expect do
+ service.update!(active: false)
+ end.to change { has_external_wiki }.to(false)
+ end
+
+ it 'does not change `has_external_wiki` when integration is for a different project' do
+ different_project = projects.create!(namespace_id: @namespace.id)
+ service = create_external_wiki_integration(active: false, project_id: different_project.id)
+
+ expect do
+ service.update!(active: true)
+ end.not_to change { has_external_wiki }
+ end
+ end
+
+ describe 'DELETE trigger' do
+ it 'sets `has_external_wiki` to false when integration is deleted' do
+ service = create_external_wiki_integration(active: true, project_id: @project.id)
+
+ expect do
+ service.delete
+ end.to change { has_external_wiki }.to(false)
+ end
+
+ it 'does not change `has_external_wiki` when integration is for a different project' do
+ different_project = projects.create!(namespace_id: @namespace.id)
+ service = create_external_wiki_integration(active: true, project_id: different_project.id)
+
+ expect do
+ service.delete
+ end.not_to change { has_external_wiki }
+ end
+ end
+ end
+
+ describe '#up' do
+ before do
+ migrate!
+ end
+
+ context 'when integrations are created with the new STI value' do
+ let(:type_info) { { type_new: 'Integrations::ExternalWiki' } }
+
+ it_behaves_like 'external wiki triggers'
+ end
+
+ context 'when integrations are created with the old STI value' do
+ let(:type_info) { { type: 'ExternalWikiService' } }
+
+ it_behaves_like 'external wiki triggers'
+ end
+ end
+
+ describe '#down' do
+ before do
+ migration.up
+ migration.down
+ end
+
+ let(:type_info) { { type: 'ExternalWikiService' } }
+
+ it_behaves_like 'external wiki triggers'
+ end
+end
diff --git a/spec/migrations/set_default_job_token_scope_true_spec.rb b/spec/migrations/set_default_job_token_scope_true_spec.rb
new file mode 100644
index 00000000000..e7c77357318
--- /dev/null
+++ b/spec/migrations/set_default_job_token_scope_true_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SetDefaultJobTokenScopeTrue, schema: 20210819153805 do
+ let(:ci_cd_settings) { table(:project_ci_cd_settings) }
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+
+ let(:namespace) { namespaces.create!(name: 'test', path: 'path', type: 'Group') }
+ let(:project) { projects.create!(namespace_id: namespace.id) }
+
+ describe '#up' do
+ it 'sets the job_token_scope_enabled default to true' do
+ described_class.new.up
+
+ settings = ci_cd_settings.create!(project_id: project.id)
+
+ expect(settings.job_token_scope_enabled).to be_truthy
+ end
+ end
+
+ describe '#down' do
+ it 'sets the job_token_scope_enabled default to false' do
+ described_class.new.down
+
+ settings = ci_cd_settings.create!(project_id: project.id)
+
+ expect(settings.job_token_scope_enabled).to be_falsey
+ end
+ end
+end
diff --git a/spec/migrations/slice_merge_request_diff_commit_migrations_spec.rb b/spec/migrations/slice_merge_request_diff_commit_migrations_spec.rb
new file mode 100644
index 00000000000..1fd19ee42b4
--- /dev/null
+++ b/spec/migrations/slice_merge_request_diff_commit_migrations_spec.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration! 'slice_merge_request_diff_commit_migrations'
+
+RSpec.describe SliceMergeRequestDiffCommitMigrations, :migration do
+ let(:migration) { described_class.new }
+
+ describe '#up' do
+ context 'when there are no jobs to process' do
+ it 'does nothing' do
+ expect(migration).not_to receive(:migrate_in)
+ expect(Gitlab::Database::BackgroundMigrationJob).not_to receive(:create!)
+
+ migration.up
+ end
+ end
+
+ context 'when there are pending jobs' do
+ let!(:job1) do
+ Gitlab::Database::BackgroundMigrationJob.create!(
+ class_name: described_class::MIGRATION_CLASS,
+ arguments: [1, 10_001]
+ )
+ end
+
+ let!(:job2) do
+ Gitlab::Database::BackgroundMigrationJob.create!(
+ class_name: described_class::MIGRATION_CLASS,
+ arguments: [10_001, 20_001]
+ )
+ end
+
+ it 'marks the old jobs as finished' do
+ migration.up
+
+ job1.reload
+ job2.reload
+
+ expect(job1).to be_succeeded
+ expect(job2).to be_succeeded
+ end
+
+ it 'the jobs are slices into smaller ranges' do
+ migration.up
+
+ new_jobs = Gitlab::Database::BackgroundMigrationJob
+ .for_migration_class(described_class::MIGRATION_CLASS)
+ .pending
+ .to_a
+
+ expect(new_jobs.map(&:arguments)).to eq([
+ [1, 5_001],
+ [5_001, 10_001],
+ [10_001, 15_001],
+ [15_001, 20_001]
+ ])
+ end
+
+ it 'schedules a background migration for the first job' do
+ expect(migration)
+ .to receive(:migrate_in)
+ .with(1.hour, described_class::STEAL_MIGRATION_CLASS, [1, 5_001])
+
+ migration.up
+ end
+ end
+ end
+end
diff --git a/spec/migrations/steal_merge_request_diff_commit_users_migration_spec.rb b/spec/migrations/steal_merge_request_diff_commit_users_migration_spec.rb
new file mode 100644
index 00000000000..3ad0b5a93c2
--- /dev/null
+++ b/spec/migrations/steal_merge_request_diff_commit_users_migration_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration! 'steal_merge_request_diff_commit_users_migration'
+
+RSpec.describe StealMergeRequestDiffCommitUsersMigration, :migration do
+ let(:migration) { described_class.new }
+
+ describe '#up' do
+ it 'schedules a job if there are pending jobs' do
+ Gitlab::Database::BackgroundMigrationJob.create!(
+ class_name: 'MigrateMergeRequestDiffCommitUsers',
+ arguments: [10, 20]
+ )
+
+ expect(migration)
+ .to receive(:migrate_in)
+ .with(1.hour, 'StealMigrateMergeRequestDiffCommitUsers', [10, 20])
+
+ migration.up
+ end
+
+ it 'does not schedule any jobs when all jobs have been completed' do
+ expect(migration).not_to receive(:migrate_in)
+
+ migration.up
+ end
+ end
+end
diff --git a/spec/migrations/update_integrations_trigger_type_new_on_insert_spec.rb b/spec/migrations/update_integrations_trigger_type_new_on_insert_spec.rb
new file mode 100644
index 00000000000..41cf35b40f4
--- /dev/null
+++ b/spec/migrations/update_integrations_trigger_type_new_on_insert_spec.rb
@@ -0,0 +1,102 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe UpdateIntegrationsTriggerTypeNewOnInsert do
+ let(:migration) { described_class.new }
+ let(:integrations) { table(:integrations) }
+
+ shared_examples 'transforms known types' do
+ # This matches Gitlab::Integrations::StiType at the time the original trigger
+ # was added in db/migrate/20210721135638_add_triggers_to_integrations_type_new.rb
+ let(:namespaced_integrations) do
+ %w[
+ Asana Assembla Bamboo Bugzilla Buildkite Campfire Confluence CustomIssueTracker Datadog
+ Discord DroneCi EmailsOnPush Ewm ExternalWiki Flowdock HangoutsChat Irker Jenkins Jira Mattermost
+ MattermostSlashCommands MicrosoftTeams MockCi MockMonitoring Packagist PipelinesEmail Pivotaltracker
+ Prometheus Pushover Redmine Slack SlackSlashCommands Teamcity UnifyCircuit WebexTeams Youtrack
+
+ Github GitlabSlackApplication
+ ]
+ end
+
+ it 'sets `type_new` to the transformed `type` class name' do
+ namespaced_integrations.each do |type|
+ integration = integrations.create!(type: "#{type}Service")
+
+ expect(integration.reload).to have_attributes(
+ type: "#{type}Service",
+ type_new: "Integrations::#{type}"
+ )
+ end
+ end
+ end
+
+ describe '#up' do
+ before do
+ migrate!
+ end
+
+ describe 'INSERT trigger with dynamic mapping' do
+ it_behaves_like 'transforms known types'
+
+ it 'transforms unknown types if it ends in "Service"' do
+ integration = integrations.create!(type: 'AcmeService')
+
+ expect(integration.reload).to have_attributes(
+ type: 'AcmeService',
+ type_new: 'Integrations::Acme'
+ )
+ end
+
+ it 'ignores "Service" occurring elsewhere in the type' do
+ integration = integrations.create!(type: 'ServiceAcmeService')
+
+ expect(integration.reload).to have_attributes(
+ type: 'ServiceAcmeService',
+ type_new: 'Integrations::ServiceAcme'
+ )
+ end
+
+ it 'copies unknown types if it does not end with "Service"' do
+ integration = integrations.create!(type: 'Integrations::Acme')
+
+ expect(integration.reload).to have_attributes(
+ type: 'Integrations::Acme',
+ type_new: 'Integrations::Acme'
+ )
+ end
+ end
+ end
+
+ describe '#down' do
+ before do
+ migration.up
+ migration.down
+ end
+
+ describe 'INSERT trigger with static mapping' do
+ it_behaves_like 'transforms known types'
+
+ it 'ignores types that are already namespaced' do
+ integration = integrations.create!(type: 'Integrations::Asana')
+
+ expect(integration.reload).to have_attributes(
+ type: 'Integrations::Asana',
+ type_new: nil
+ )
+ end
+
+ it 'ignores types that are unknown' do
+ integration = integrations.create!(type: 'FooBar')
+
+ expect(integration.reload).to have_attributes(
+ type: 'FooBar',
+ type_new: nil
+ )
+ end
+ end
+ end
+end
diff --git a/spec/migrations/update_minimum_password_length_spec.rb b/spec/migrations/update_minimum_password_length_spec.rb
index 02254ba1343..e40d090fd77 100644
--- a/spec/migrations/update_minimum_password_length_spec.rb
+++ b/spec/migrations/update_minimum_password_length_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe UpdateMinimumPasswordLength do
before do
stub_const('ApplicationSetting::DEFAULT_MINIMUM_PASSWORD_LENGTH', 10)
- allow(Devise.password_length).to receive(:min).and_return(12)
+ allow(Devise).to receive(:password_length).and_return(12..20)
end
it 'correctly migrates minimum_password_length' do
diff --git a/spec/models/analytics/cycle_analytics/issue_stage_event_spec.rb b/spec/models/analytics/cycle_analytics/issue_stage_event_spec.rb
new file mode 100644
index 00000000000..3e6d4ebd0a2
--- /dev/null
+++ b/spec/models/analytics/cycle_analytics/issue_stage_event_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Analytics::CycleAnalytics::IssueStageEvent do
+ it { is_expected.to validate_presence_of(:stage_event_hash_id) }
+ it { is_expected.to validate_presence_of(:issue_id) }
+ it { is_expected.to validate_presence_of(:group_id) }
+ it { is_expected.to validate_presence_of(:project_id) }
+ it { is_expected.to validate_presence_of(:start_event_timestamp) }
+end
diff --git a/spec/models/analytics/cycle_analytics/merge_request_stage_event_spec.rb b/spec/models/analytics/cycle_analytics/merge_request_stage_event_spec.rb
new file mode 100644
index 00000000000..244c5c70286
--- /dev/null
+++ b/spec/models/analytics/cycle_analytics/merge_request_stage_event_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Analytics::CycleAnalytics::MergeRequestStageEvent do
+ it { is_expected.to validate_presence_of(:stage_event_hash_id) }
+ it { is_expected.to validate_presence_of(:merge_request_id) }
+ it { is_expected.to validate_presence_of(:group_id) }
+ it { is_expected.to validate_presence_of(:project_id) }
+ it { is_expected.to validate_presence_of(:start_event_timestamp) }
+end
diff --git a/spec/models/application_record_spec.rb b/spec/models/application_record_spec.rb
index f9a05c720a3..efb92ddaea0 100644
--- a/spec/models/application_record_spec.rb
+++ b/spec/models/application_record_spec.rb
@@ -39,7 +39,7 @@ RSpec.describe ApplicationRecord do
let(:suggestion_attributes) { attributes_for(:suggestion).merge!(note_id: note.id) }
- shared_examples '.safe_find_or_create_by' do
+ describe '.safe_find_or_create_by' do
it 'creates the suggestion avoiding race conditions' do
existing_suggestion = double(:Suggestion)
@@ -63,7 +63,7 @@ RSpec.describe ApplicationRecord do
end
end
- shared_examples '.safe_find_or_create_by!' do
+ describe '.safe_find_or_create_by!' do
it 'creates a record using safe_find_or_create_by' do
expect(Suggestion.safe_find_or_create_by!(suggestion_attributes))
.to be_a(Suggestion)
@@ -88,24 +88,6 @@ RSpec.describe ApplicationRecord do
.to raise_error(ActiveRecord::RecordNotFound)
end
end
-
- context 'when optimized_safe_find_or_create_by is enabled' do
- before do
- stub_feature_flags(optimized_safe_find_or_create_by: true)
- end
-
- it_behaves_like '.safe_find_or_create_by'
- it_behaves_like '.safe_find_or_create_by!'
- end
-
- context 'when optimized_safe_find_or_create_by is disabled' do
- before do
- stub_feature_flags(optimized_safe_find_or_create_by: false)
- end
-
- it_behaves_like '.safe_find_or_create_by'
- it_behaves_like '.safe_find_or_create_by!'
- end
end
describe '.underscore' do
@@ -164,6 +146,23 @@ RSpec.describe ApplicationRecord do
end
end
end
+
+ # rubocop:disable Database/MultipleDatabases
+ it 'increments a counter when a transaction is created in ActiveRecord' do
+ expect(described_class.connection.transaction_open?).to be false
+
+ expect(::Gitlab::Database::Metrics)
+ .to receive(:subtransactions_increment)
+ .with('ActiveRecord::Base')
+ .once
+
+ ActiveRecord::Base.transaction do
+ ActiveRecord::Base.transaction(requires_new: true) do
+ expect(ActiveRecord::Base.connection.transaction_open?).to be true
+ end
+ end
+ end
+ # rubocop:enable Database/MultipleDatabases
end
describe '.with_fast_read_statement_timeout' do
@@ -236,4 +235,46 @@ RSpec.describe ApplicationRecord do
end
end
end
+
+ describe '.default_select_columns' do
+ shared_examples_for 'selects identically to the default' do
+ it 'generates the same sql as the default' do
+ expected_sql = test_model.all.to_sql
+ generated_sql = test_model.all.select(test_model.default_select_columns).to_sql
+
+ expect(expected_sql).to eq(generated_sql)
+ end
+ end
+
+ before do
+ ApplicationRecord.connection.execute(<<~SQL)
+ create table tests (
+ id bigserial primary key not null,
+ ignore_me text
+ )
+ SQL
+ end
+ context 'without an ignored column' do
+ let(:test_model) do
+ Class.new(ApplicationRecord) do
+ self.table_name = 'tests'
+ end
+ end
+
+ it_behaves_like 'selects identically to the default'
+ end
+
+ context 'with an ignored column' do
+ let(:test_model) do
+ Class.new(ApplicationRecord) do
+ include IgnorableColumns
+ self.table_name = 'tests'
+
+ ignore_columns :ignore_me, remove_after: '2100-01-01', remove_with: '99.12'
+ end
+ end
+
+ it_behaves_like 'selects identically to the default'
+ end
+ end
end
diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb
index e9c5ffef210..3e264867703 100644
--- a/spec/models/application_setting_spec.rb
+++ b/spec/models/application_setting_spec.rb
@@ -7,6 +7,8 @@ RSpec.describe ApplicationSetting do
subject(:setting) { described_class.create_from_defaults }
+ it_behaves_like 'sanitizable', :application_setting, %i[default_branch_name]
+
it { include(CacheableAttributes) }
it { include(ApplicationSettingImplementation) }
it { expect(described_class.current_without_cache).to eq(described_class.last) }
@@ -79,12 +81,19 @@ RSpec.describe ApplicationSetting do
it { is_expected.to validate_numericality_of(:wiki_page_max_content_bytes).only_integer.is_greater_than_or_equal_to(1024) }
it { is_expected.to validate_presence_of(:max_artifacts_size) }
it { is_expected.to validate_numericality_of(:max_artifacts_size).only_integer.is_greater_than(0) }
+ it { is_expected.to validate_presence_of(:max_yaml_size_bytes) }
+ it { is_expected.to validate_numericality_of(:max_yaml_size_bytes).only_integer.is_greater_than(0) }
+ it { is_expected.to validate_presence_of(:max_yaml_depth) }
+ it { is_expected.to validate_numericality_of(:max_yaml_depth).only_integer.is_greater_than(0) }
it { is_expected.to validate_presence_of(:max_pages_size) }
it 'ensures max_pages_size is an integer greater than 0 (or equal to 0 to indicate unlimited/maximum)' do
is_expected.to validate_numericality_of(:max_pages_size).only_integer.is_greater_than_or_equal_to(0)
.is_less_than(::Gitlab::Pages::MAX_SIZE / 1.megabyte)
end
+ it { is_expected.to validate_presence_of(:jobs_per_stage_page_size) }
+ it { is_expected.to validate_numericality_of(:jobs_per_stage_page_size).only_integer.is_greater_than_or_equal_to(0) }
+
it { is_expected.not_to allow_value(7).for(:minimum_password_length) }
it { is_expected.not_to allow_value(129).for(:minimum_password_length) }
it { is_expected.not_to allow_value(nil).for(:minimum_password_length) }
@@ -921,6 +930,8 @@ RSpec.describe ApplicationSetting do
context 'throttle_* settings' do
where(:throttle_setting) do
%i[
+ throttle_unauthenticated_api_requests_per_period
+ throttle_unauthenticated_api_period_in_seconds
throttle_unauthenticated_requests_per_period
throttle_unauthenticated_period_in_seconds
throttle_authenticated_api_requests_per_period
@@ -931,6 +942,12 @@ RSpec.describe ApplicationSetting do
throttle_unauthenticated_packages_api_period_in_seconds
throttle_authenticated_packages_api_requests_per_period
throttle_authenticated_packages_api_period_in_seconds
+ throttle_unauthenticated_files_api_requests_per_period
+ throttle_unauthenticated_files_api_period_in_seconds
+ throttle_authenticated_files_api_requests_per_period
+ throttle_authenticated_files_api_period_in_seconds
+ throttle_authenticated_git_lfs_requests_per_period
+ throttle_authenticated_git_lfs_period_in_seconds
]
end
@@ -942,6 +959,20 @@ RSpec.describe ApplicationSetting do
it { is_expected.not_to allow_value(nil).for(throttle_setting) }
end
end
+
+ context 'sidekiq job limiter settings' do
+ it 'has the right defaults', :aggregate_failures do
+ expect(setting.sidekiq_job_limiter_mode).to eq('compress')
+ expect(setting.sidekiq_job_limiter_compression_threshold_bytes)
+ .to eq(Gitlab::SidekiqMiddleware::SizeLimiter::Validator::DEFAULT_COMPRESSION_THRESHOLD_BYTES)
+ expect(setting.sidekiq_job_limiter_limit_bytes)
+ .to eq(Gitlab::SidekiqMiddleware::SizeLimiter::Validator::DEFAULT_SIZE_LIMIT)
+ end
+
+ it { is_expected.to allow_value('track').for(:sidekiq_job_limiter_mode) }
+ it { is_expected.to validate_numericality_of(:sidekiq_job_limiter_compression_threshold_bytes).only_integer.is_greater_than_or_equal_to(0) }
+ it { is_expected.to validate_numericality_of(:sidekiq_job_limiter_limit_bytes).only_integer.is_greater_than_or_equal_to(0) }
+ end
end
context 'restrict creating duplicates' do
diff --git a/spec/models/bulk_imports/entity_spec.rb b/spec/models/bulk_imports/entity_spec.rb
index 11a3e53dd16..c1cbe61885f 100644
--- a/spec/models/bulk_imports/entity_spec.rb
+++ b/spec/models/bulk_imports/entity_spec.rb
@@ -154,4 +154,57 @@ RSpec.describe BulkImports::Entity, type: :model do
expect(described_class.all_human_statuses).to contain_exactly('created', 'started', 'finished', 'failed')
end
end
+
+ describe '#pipelines' do
+ context 'when entity is group' do
+ it 'returns group pipelines' do
+ entity = build(:bulk_import_entity, :group_entity)
+
+ expect(entity.pipelines.flatten).to include(BulkImports::Groups::Pipelines::GroupPipeline)
+ end
+ end
+
+ context 'when entity is project' do
+ it 'returns project pipelines' do
+ entity = build(:bulk_import_entity, :project_entity)
+
+ expect(entity.pipelines.flatten).to include(BulkImports::Projects::Pipelines::ProjectPipeline)
+ end
+ end
+ end
+
+ describe '#create_pipeline_trackers!' do
+ context 'when entity is group' do
+ it 'creates trackers for group entity' do
+ entity = create(:bulk_import_entity, :group_entity)
+ entity.create_pipeline_trackers!
+
+ expect(entity.trackers.count).to eq(BulkImports::Groups::Stage.pipelines.count)
+ expect(entity.trackers.map(&:pipeline_name)).to include(BulkImports::Groups::Pipelines::GroupPipeline.to_s)
+ end
+ end
+
+ context 'when entity is project' do
+ it 'creates trackers for project entity' do
+ entity = create(:bulk_import_entity, :project_entity)
+ entity.create_pipeline_trackers!
+
+ expect(entity.trackers.count).to eq(BulkImports::Projects::Stage.pipelines.count)
+ expect(entity.trackers.map(&:pipeline_name)).to include(BulkImports::Projects::Pipelines::ProjectPipeline.to_s)
+ end
+ end
+ end
+
+ describe '#pipeline_exists?' do
+ let_it_be(:entity) { create(:bulk_import_entity, :group_entity) }
+
+ it 'returns true when the given pipeline name exists in the pipelines list' do
+ expect(entity.pipeline_exists?(BulkImports::Groups::Pipelines::GroupPipeline)).to eq(true)
+ expect(entity.pipeline_exists?('BulkImports::Groups::Pipelines::GroupPipeline')).to eq(true)
+ end
+
+ it 'returns false when the given pipeline name exists in the pipelines list' do
+ expect(entity.pipeline_exists?('BulkImports::Groups::Pipelines::InexistentPipeline')).to eq(false)
+ end
+ end
end
diff --git a/spec/models/bulk_imports/tracker_spec.rb b/spec/models/bulk_imports/tracker_spec.rb
index 0f00aeb9c1d..7f0a7d4f1ae 100644
--- a/spec/models/bulk_imports/tracker_spec.rb
+++ b/spec/models/bulk_imports/tracker_spec.rb
@@ -66,7 +66,7 @@ RSpec.describe BulkImports::Tracker, type: :model do
describe '#pipeline_class' do
it 'returns the pipeline class' do
- pipeline_class = BulkImports::Stage.pipelines.first[1]
+ pipeline_class = BulkImports::Groups::Stage.pipelines.first[1]
tracker = create(:bulk_import_tracker, pipeline_name: pipeline_class)
expect(tracker.pipeline_class).to eq(pipeline_class)
@@ -77,7 +77,7 @@ RSpec.describe BulkImports::Tracker, type: :model do
expect { tracker.pipeline_class }
.to raise_error(
- NameError,
+ BulkImports::Error,
"'InexistingPipeline' is not a valid BulkImport Pipeline"
)
end
diff --git a/spec/models/ci/bridge_spec.rb b/spec/models/ci/bridge_spec.rb
index db956b26b6b..6dd3c40f228 100644
--- a/spec/models/ci/bridge_spec.rb
+++ b/spec/models/ci/bridge_spec.rb
@@ -74,18 +74,18 @@ RSpec.describe Ci::Bridge do
it "schedules downstream pipeline creation when the status is #{status}" do
bridge.status = status
- expect(bridge).to receive(:schedule_downstream_pipeline!)
-
bridge.enqueue!
+
+ expect(::Ci::CreateCrossProjectPipelineWorker.jobs.last['args']).to eq([bridge.id])
end
end
it "schedules downstream pipeline creation when the status is waiting for resource" do
bridge.status = :waiting_for_resource
- expect(bridge).to receive(:schedule_downstream_pipeline!)
-
bridge.enqueue_waiting_for_resource!
+
+ expect(::Ci::CreateCrossProjectPipelineWorker.jobs.last['args']).to eq([bridge.id])
end
it 'raises error when the status is failed' do
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index 26abc98656e..1e06d566c80 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -1307,7 +1307,9 @@ RSpec.describe Ci::Build do
shared_examples_for 'avoid deadlock' do
it 'executes UPDATE in the right order' do
- recorded = ActiveRecord::QueryRecorder.new { subject }
+ recorded = with_cross_database_modification_prevented do
+ ActiveRecord::QueryRecorder.new { subject }
+ end
index_for_build = recorded.log.index { |l| l.include?("UPDATE \"ci_builds\"") }
index_for_deployment = recorded.log.index { |l| l.include?("UPDATE \"deployments\"") }
@@ -1322,7 +1324,9 @@ RSpec.describe Ci::Build do
it_behaves_like 'avoid deadlock'
it 'transits deployment status to running' do
- subject
+ with_cross_database_modification_prevented do
+ subject
+ end
expect(deployment).to be_running
end
@@ -1340,7 +1344,9 @@ RSpec.describe Ci::Build do
it_behaves_like 'calling proper BuildFinishedWorker'
it 'transits deployment status to success' do
- subject
+ with_cross_database_modification_prevented do
+ subject
+ end
expect(deployment).to be_success
end
@@ -1353,7 +1359,9 @@ RSpec.describe Ci::Build do
it_behaves_like 'calling proper BuildFinishedWorker'
it 'transits deployment status to failed' do
- subject
+ with_cross_database_modification_prevented do
+ subject
+ end
expect(deployment).to be_failed
end
@@ -1365,7 +1373,9 @@ RSpec.describe Ci::Build do
it_behaves_like 'avoid deadlock'
it 'transits deployment status to skipped' do
- subject
+ with_cross_database_modification_prevented do
+ subject
+ end
expect(deployment).to be_skipped
end
@@ -1378,7 +1388,9 @@ RSpec.describe Ci::Build do
it_behaves_like 'calling proper BuildFinishedWorker'
it 'transits deployment status to canceled' do
- subject
+ with_cross_database_modification_prevented do
+ subject
+ end
expect(deployment).to be_canceled
end
@@ -2632,6 +2644,10 @@ RSpec.describe Ci::Build do
value: "#{Gitlab.host_with_port}/#{project.namespace.root_ancestor.path.downcase}#{DependencyProxy::URL_SUFFIX}",
public: true,
masked: false },
+ { key: 'CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX',
+ value: "#{Gitlab.host_with_port}/#{project.namespace.full_path.downcase}#{DependencyProxy::URL_SUFFIX}",
+ public: true,
+ masked: false },
{ key: 'CI_API_V4_URL', value: 'http://localhost/api/v4', public: true, masked: false },
{ key: 'CI_PIPELINE_IID', value: pipeline.iid.to_s, public: true, masked: false },
{ key: 'CI_PIPELINE_SOURCE', value: pipeline.source, public: true, masked: false },
@@ -5243,4 +5259,33 @@ RSpec.describe Ci::Build do
expect(described_class.with_coverage_regex).to eq([build_with_coverage_regex])
end
end
+
+ describe '#ensure_trace_metadata!' do
+ it 'delegates to Ci::BuildTraceMetadata' do
+ expect(Ci::BuildTraceMetadata)
+ .to receive(:find_or_upsert_for!)
+ .with(build.id)
+
+ build.ensure_trace_metadata!
+ end
+ end
+
+ describe '#doom!' do
+ subject { build.doom! }
+
+ let_it_be(:build) { create(:ci_build, :queued) }
+
+ it 'updates status and failure_reason', :aggregate_failures do
+ subject
+
+ expect(build.status).to eq("failed")
+ expect(build.failure_reason).to eq("data_integrity_failure")
+ end
+
+ it 'drops associated pending build' do
+ subject
+
+ expect(build.reload.queuing_entry).not_to be_present
+ end
+ end
end
diff --git a/spec/models/ci/build_trace_chunks/fog_spec.rb b/spec/models/ci/build_trace_chunks/fog_spec.rb
index 21dab6fad60..bbf04ef9430 100644
--- a/spec/models/ci/build_trace_chunks/fog_spec.rb
+++ b/spec/models/ci/build_trace_chunks/fog_spec.rb
@@ -107,37 +107,22 @@ RSpec.describe Ci::BuildTraceChunks::Fog do
let(:model) { create(:ci_build_trace_chunk, :fog_with_data, initial_data: initial_data) }
let(:data) { data_store.data(model) }
- context 'when ci_job_trace_force_encode is enabled' do
- it 'appends ASCII data' do
- data_store.append_data(model, +'hello world', 4)
+ it 'appends ASCII data' do
+ data_store.append_data(model, +'hello world', 4)
- expect(data.encoding).to eq(Encoding::ASCII_8BIT)
- expect(data.force_encoding(Encoding::UTF_8)).to eq('😺hello world')
- end
-
- it 'appends UTF-8 data' do
- data_store.append_data(model, +'Résumé', 4)
-
- expect(data.encoding).to eq(Encoding::ASCII_8BIT)
- expect(data.force_encoding(Encoding::UTF_8)).to eq("😺Résumé")
- end
-
- context 'when initial data is UTF-8' do
- let(:initial_data) { +'😺' }
+ expect(data.encoding).to eq(Encoding::ASCII_8BIT)
+ expect(data.force_encoding(Encoding::UTF_8)).to eq('😺hello world')
+ end
- it 'appends ASCII data' do
- data_store.append_data(model, +'hello world', 4)
+ it 'appends UTF-8 data' do
+ data_store.append_data(model, +'Résumé', 4)
- expect(data.encoding).to eq(Encoding::ASCII_8BIT)
- expect(data.force_encoding(Encoding::UTF_8)).to eq('😺hello world')
- end
- end
+ expect(data.encoding).to eq(Encoding::ASCII_8BIT)
+ expect(data.force_encoding(Encoding::UTF_8)).to eq("😺Résumé")
end
- context 'when ci_job_trace_force_encode is disabled' do
- before do
- stub_feature_flags(ci_job_trace_force_encode: false)
- end
+ context 'when initial data is UTF-8' do
+ let(:initial_data) { +'😺' }
it 'appends ASCII data' do
data_store.append_data(model, +'hello world', 4)
@@ -145,11 +130,6 @@ RSpec.describe Ci::BuildTraceChunks::Fog do
expect(data.encoding).to eq(Encoding::ASCII_8BIT)
expect(data.force_encoding(Encoding::UTF_8)).to eq('😺hello world')
end
-
- it 'throws an exception when appending UTF-8 data' do
- expect(Gitlab::ErrorTracking).to receive(:track_and_raise_exception).and_call_original
- expect { data_store.append_data(model, +'Résumé', 4) }.to raise_exception(Encoding::CompatibilityError)
- end
end
end
diff --git a/spec/models/ci/build_trace_metadata_spec.rb b/spec/models/ci/build_trace_metadata_spec.rb
index 42b9d5d34b6..5e4645c5dc4 100644
--- a/spec/models/ci/build_trace_metadata_spec.rb
+++ b/spec/models/ci/build_trace_metadata_spec.rb
@@ -7,4 +7,128 @@ RSpec.describe Ci::BuildTraceMetadata do
it { is_expected.to belong_to(:trace_artifact) }
it { is_expected.to validate_presence_of(:build) }
+ it { is_expected.to validate_presence_of(:archival_attempts) }
+
+ describe '#can_attempt_archival_now?' do
+ let(:metadata) do
+ build(:ci_build_trace_metadata,
+ archival_attempts: archival_attempts,
+ last_archival_attempt_at: last_archival_attempt_at)
+ end
+
+ subject { metadata.can_attempt_archival_now? }
+
+ context 'when archival_attempts is over the limit' do
+ let(:archival_attempts) { described_class::MAX_ATTEMPTS + 1 }
+ let(:last_archival_attempt_at) {}
+
+ it { is_expected.to be_falsey }
+ end
+
+ context 'when last_archival_attempt_at is not set' do
+ let(:archival_attempts) { described_class::MAX_ATTEMPTS }
+ let(:last_archival_attempt_at) {}
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when last_archival_attempt_at is set' do
+ let(:archival_attempts) { described_class::MAX_ATTEMPTS }
+ let(:last_archival_attempt_at) { 6.days.ago }
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when last_archival_attempt_at is too close' do
+ let(:archival_attempts) { described_class::MAX_ATTEMPTS }
+ let(:last_archival_attempt_at) { 1.hour.ago }
+
+ it { is_expected.to be_falsey }
+ end
+ end
+
+ describe '#archival_attempts_available?' do
+ let(:metadata) do
+ build(:ci_build_trace_metadata, archival_attempts: archival_attempts)
+ end
+
+ subject { metadata.archival_attempts_available? }
+
+ context 'when archival_attempts is over the limit' do
+ let(:archival_attempts) { described_class::MAX_ATTEMPTS + 1 }
+
+ it { is_expected.to be_falsey }
+ end
+
+ context 'when archival_attempts is at the limit' do
+ let(:archival_attempts) { described_class::MAX_ATTEMPTS }
+
+ it { is_expected.to be_truthy }
+ end
+ end
+
+ describe '#increment_archival_attempts!' do
+ let_it_be(:metadata) do
+ create(:ci_build_trace_metadata,
+ archival_attempts: 2,
+ last_archival_attempt_at: 1.day.ago)
+ end
+
+ it 'increments the attempts' do
+ expect { metadata.increment_archival_attempts! }
+ .to change { metadata.reload.archival_attempts }
+ end
+
+ it 'updates the last_archival_attempt_at timestamp' do
+ expect { metadata.increment_archival_attempts! }
+ .to change { metadata.reload.last_archival_attempt_at }
+ end
+ end
+
+ describe '#track_archival!' do
+ let(:trace_artifact) { create(:ci_job_artifact) }
+ let(:metadata) { create(:ci_build_trace_metadata) }
+
+ it 'stores the artifact id and timestamp' do
+ expect(metadata.trace_artifact_id).to be_nil
+
+ metadata.track_archival!(trace_artifact.id)
+ metadata.reload
+
+ expect(metadata.trace_artifact_id).to eq(trace_artifact.id)
+ expect(metadata.archived_at).to be_like_time(Time.current)
+ end
+ end
+
+ describe '.find_or_upsert_for!' do
+ let_it_be(:build) { create(:ci_build) }
+
+ subject(:execute) do
+ described_class.find_or_upsert_for!(build.id)
+ end
+
+ it 'creates a new record' do
+ metadata = execute
+
+ expect(metadata).to be_a(described_class)
+ expect(metadata.id).to eq(build.id)
+ expect(metadata.archival_attempts).to eq(0)
+ end
+
+ context 'with existing records' do
+ before do
+ create(:ci_build_trace_metadata,
+ build: build,
+ archival_attempts: described_class::MAX_ATTEMPTS)
+ end
+
+ it 'returns the existing record' do
+ metadata = execute
+
+ expect(metadata).to be_a(described_class)
+ expect(metadata.id).to eq(build.id)
+ expect(metadata.archival_attempts).to eq(described_class::MAX_ATTEMPTS)
+ end
+ end
+ end
end
diff --git a/spec/models/ci/pending_build_spec.rb b/spec/models/ci/pending_build_spec.rb
index 0518c9a1652..ad711f5622f 100644
--- a/spec/models/ci/pending_build_spec.rb
+++ b/spec/models/ci/pending_build_spec.rb
@@ -34,6 +34,47 @@ RSpec.describe Ci::PendingBuild do
end
end
end
+
+ describe '.for_tags' do
+ subject(:pending_builds) { described_class.for_tags(tag_ids) }
+
+ let_it_be(:pending_build_with_tags) { create(:ci_pending_build, tag_ids: [1, 2]) }
+ let_it_be(:pending_build_without_tags) { create(:ci_pending_build) }
+
+ context 'when tag_ids match pending builds' do
+ let(:tag_ids) { [1, 2] }
+
+ it 'returns matching pending builds' do
+ expect(pending_builds).to contain_exactly(pending_build_with_tags, pending_build_without_tags)
+ end
+ end
+
+ context 'when tag_ids does not match pending builds' do
+ let(:tag_ids) { [non_existing_record_id] }
+
+ it 'returns matching pending builds without tags' do
+ expect(pending_builds).to contain_exactly(pending_build_without_tags)
+ end
+ end
+
+ context 'when tag_ids is not provided' do
+ context 'with a nil value' do
+ let(:tag_ids) { nil }
+
+ it 'returns matching pending builds without tags' do
+ expect(pending_builds).to contain_exactly(pending_build_without_tags)
+ end
+ end
+
+ context 'with an empty array' do
+ let(:tag_ids) { [] }
+
+ it 'returns matching pending builds without tags' do
+ expect(pending_builds).to contain_exactly(pending_build_without_tags)
+ end
+ end
+ end
+ end
end
describe '.upsert_from_build!' do
@@ -58,7 +99,11 @@ RSpec.describe Ci::PendingBuild do
end
end
- context 'when project does not have shared runner' do
+ context 'when project does not have shared runners enabled' do
+ before do
+ project.shared_runners_enabled = false
+ end
+
it 'sets instance_runners_enabled to false' do
described_class.upsert_from_build!(build)
@@ -69,6 +114,10 @@ RSpec.describe Ci::PendingBuild do
context 'when project has shared runner' do
let_it_be(:runner) { create(:ci_runner, :instance) }
+ before do
+ project.shared_runners_enabled = true
+ end
+
context 'when ci_pending_builds_maintain_shared_runners_data is enabled' do
it 'sets instance_runners_enabled to true' do
described_class.upsert_from_build!(build)
@@ -113,5 +162,65 @@ RSpec.describe Ci::PendingBuild do
end
end
end
+
+ context 'when build has tags' do
+ let!(:build) { create(:ci_build, :tags) }
+
+ subject(:ci_pending_build) { described_class.last }
+
+ context 'when ci_pending_builds_maintain_tags_data is enabled' do
+ it 'sets tag_ids' do
+ described_class.upsert_from_build!(build)
+
+ expect(ci_pending_build.tag_ids).to eq(build.tags_ids)
+ end
+ end
+
+ context 'when ci_pending_builds_maintain_tags_data is disabled' do
+ before do
+ stub_feature_flags(ci_pending_builds_maintain_tags_data: false)
+ end
+
+ it 'does not set tag_ids' do
+ described_class.upsert_from_build!(build)
+
+ expect(ci_pending_build.tag_ids).to be_empty
+ end
+ end
+ end
+
+ context 'when a build project is nested in a subgroup' do
+ let(:group) { create(:group, :with_hierarchy, depth: 2, children: 1) }
+ let(:project) { create(:project, namespace: group.descendants.first) }
+ let(:pipeline) { create(:ci_pipeline, project: project) }
+ let(:build) { create(:ci_build, :created, pipeline: pipeline) }
+
+ subject { described_class.last }
+
+ context 'when build can be picked by a group runner' do
+ before do
+ project.group_runners_enabled = true
+ end
+
+ it 'denormalizes namespace traversal ids' do
+ described_class.upsert_from_build!(build)
+
+ expect(subject.namespace_traversal_ids).not_to be_empty
+ expect(subject.namespace_traversal_ids).to eq [group.id, project.namespace.id]
+ end
+ end
+
+ context 'when build can not be picked by a group runner' do
+ before do
+ project.group_runners_enabled = false
+ end
+
+ it 'creates an empty namespace traversal ids array' do
+ described_class.upsert_from_build!(build)
+
+ expect(subject.namespace_traversal_ids).to be_empty
+ end
+ end
+ end
end
end
diff --git a/spec/models/ci/pipeline_schedule_spec.rb b/spec/models/ci/pipeline_schedule_spec.rb
index 8de3ebb18b9..c7e1fe91b1e 100644
--- a/spec/models/ci/pipeline_schedule_spec.rb
+++ b/spec/models/ci/pipeline_schedule_spec.rb
@@ -107,31 +107,24 @@ RSpec.describe Ci::PipelineSchedule do
describe '#set_next_run_at' do
using RSpec::Parameterized::TableSyntax
- where(:worker_cron, :schedule_cron, :plan_limit, :ff_enabled, :now, :result) do
- '0 1 2 3 *' | '0 1 * * *' | nil | true | Time.zone.local(2021, 3, 2, 1, 0) | Time.zone.local(2022, 3, 2, 1, 0)
- '0 1 2 3 *' | '0 1 * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | true | Time.zone.local(2021, 3, 2, 1, 0) | Time.zone.local(2022, 3, 2, 1, 0)
- '0 1 2 3 *' | '0 1 * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | false | Time.zone.local(2021, 3, 2, 1, 0) | Time.zone.local(2022, 3, 2, 1, 0)
- '*/5 * * * *' | '*/1 * * * *' | nil | true | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 11, 5)
- '*/5 * * * *' | '*/1 * * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | true | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 0)
- '*/5 * * * *' | '*/1 * * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | false | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 11, 5)
- '*/5 * * * *' | '*/1 * * * *' | (1.day.in_minutes / 10).to_i | true | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 11, 10)
- '*/5 * * * *' | '*/1 * * * *' | 200 | true | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 11, 10)
- '*/5 * * * *' | '*/1 * * * *' | 200 | false | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 11, 5)
- '*/5 * * * *' | '0 * * * *' | nil | true | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 5)
- '*/5 * * * *' | '0 * * * *' | (1.day.in_minutes / 10).to_i | true | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 0)
- '*/5 * * * *' | '0 * * * *' | (1.day.in_minutes / 10).to_i | false | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 5)
- '*/5 * * * *' | '0 * * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | true | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 0)
- '*/5 * * * *' | '0 * * * *' | (1.day.in_minutes / 2.hours.in_minutes).to_i | true | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 5)
- '*/5 * * * *' | '0 1 * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | true | Time.zone.local(2021, 5, 27, 1, 0) | Time.zone.local(2021, 5, 28, 1, 0)
- '*/5 * * * *' | '0 1 * * *' | (1.day.in_minutes / 10).to_i | true | Time.zone.local(2021, 5, 27, 1, 0) | Time.zone.local(2021, 5, 28, 1, 0)
- '*/5 * * * *' | '0 1 * * *' | (1.day.in_minutes / 8).to_i | true | Time.zone.local(2021, 5, 27, 1, 0) | Time.zone.local(2021, 5, 28, 1, 0)
- '*/5 * * * *' | '0 1 1 * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | true | Time.zone.local(2021, 5, 1, 1, 0) | Time.zone.local(2021, 6, 1, 1, 0)
- '*/9 * * * *' | '0 1 1 * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | true | Time.zone.local(2021, 5, 1, 1, 9) | Time.zone.local(2021, 6, 1, 1, 0)
- '*/9 * * * *' | '0 1 1 * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | false | Time.zone.local(2021, 5, 1, 1, 9) | Time.zone.local(2021, 6, 1, 1, 9)
- '*/5 * * * *' | '59 14 * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | true | Time.zone.local(2021, 5, 1, 15, 0) | Time.zone.local(2021, 5, 2, 15, 0)
- '*/5 * * * *' | '59 14 * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | false | Time.zone.local(2021, 5, 1, 15, 0) | Time.zone.local(2021, 5, 2, 15, 0)
- '*/5 * * * *' | '45 21 1 2 *' | (1.day.in_minutes / 5).to_i | true | Time.zone.local(2021, 2, 1, 21, 45) | Time.zone.local(2022, 2, 1, 21, 45)
- '*/5 * * * *' | '45 21 1 2 *' | (1.day.in_minutes / 5).to_i | false | Time.zone.local(2021, 2, 1, 21, 45) | Time.zone.local(2022, 2, 1, 21, 50)
+ where(:worker_cron, :schedule_cron, :plan_limit, :now, :result) do
+ '0 1 2 3 *' | '0 1 * * *' | nil | Time.zone.local(2021, 3, 2, 1, 0) | Time.zone.local(2022, 3, 2, 1, 0)
+ '0 1 2 3 *' | '0 1 * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | Time.zone.local(2021, 3, 2, 1, 0) | Time.zone.local(2022, 3, 2, 1, 0)
+ '*/5 * * * *' | '*/1 * * * *' | nil | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 11, 5)
+ '*/5 * * * *' | '*/1 * * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 0)
+ '*/5 * * * *' | '*/1 * * * *' | (1.day.in_minutes / 10).to_i | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 11, 10)
+ '*/5 * * * *' | '*/1 * * * *' | 200 | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 11, 10)
+ '*/5 * * * *' | '0 * * * *' | nil | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 5)
+ '*/5 * * * *' | '0 * * * *' | (1.day.in_minutes / 10).to_i | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 0)
+ '*/5 * * * *' | '0 * * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 0)
+ '*/5 * * * *' | '0 * * * *' | (1.day.in_minutes / 2.hours.in_minutes).to_i | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 5)
+ '*/5 * * * *' | '0 1 * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | Time.zone.local(2021, 5, 27, 1, 0) | Time.zone.local(2021, 5, 28, 1, 0)
+ '*/5 * * * *' | '0 1 * * *' | (1.day.in_minutes / 10).to_i | Time.zone.local(2021, 5, 27, 1, 0) | Time.zone.local(2021, 5, 28, 1, 0)
+ '*/5 * * * *' | '0 1 * * *' | (1.day.in_minutes / 8).to_i | Time.zone.local(2021, 5, 27, 1, 0) | Time.zone.local(2021, 5, 28, 1, 0)
+ '*/5 * * * *' | '0 1 1 * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | Time.zone.local(2021, 5, 1, 1, 0) | Time.zone.local(2021, 6, 1, 1, 0)
+ '*/9 * * * *' | '0 1 1 * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | Time.zone.local(2021, 5, 1, 1, 9) | Time.zone.local(2021, 6, 1, 1, 0)
+ '*/5 * * * *' | '59 14 * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | Time.zone.local(2021, 5, 1, 15, 0) | Time.zone.local(2021, 5, 2, 15, 0)
+ '*/5 * * * *' | '45 21 1 2 *' | (1.day.in_minutes / 5).to_i | Time.zone.local(2021, 2, 1, 21, 45) | Time.zone.local(2022, 2, 1, 21, 45)
end
with_them do
@@ -143,7 +136,6 @@ RSpec.describe Ci::PipelineSchedule do
end
create(:plan_limits, :default_plan, ci_daily_pipeline_schedule_triggers: plan_limit) if plan_limit
- stub_feature_flags(ci_daily_limit_for_pipeline_schedules: false) unless ff_enabled
# Setting this here to override initial save with the current time
pipeline_schedule.next_run_at = now
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index da89eccc3b2..1007d64438f 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -183,6 +183,28 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
end
end
+ describe '.where_not_sha' do
+ let_it_be(:pipeline) { create(:ci_pipeline, sha: 'abcx') }
+ let_it_be(:pipeline_2) { create(:ci_pipeline, sha: 'abc') }
+
+ let(:sha) { 'abc' }
+
+ subject { described_class.where_not_sha(sha) }
+
+ it 'returns the pipeline without the specified sha' do
+ is_expected.to contain_exactly(pipeline)
+ end
+
+ context 'when argument is array' do
+ let(:sha) { %w[abc abcx] }
+
+ it 'returns the pipelines without the specified shas' do
+ pipeline_3 = create(:ci_pipeline, sha: 'abcy')
+ is_expected.to contain_exactly(pipeline_3)
+ end
+ end
+ end
+
describe '.for_source_sha' do
subject { described_class.for_source_sha(source_sha) }
@@ -2015,16 +2037,6 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
it 'returns external pull request modified paths' do
expect(pipeline.modified_paths).to match(external_pull_request.modified_paths)
end
-
- context 'when the FF ci_modified_paths_of_external_prs is disabled' do
- before do
- stub_feature_flags(ci_modified_paths_of_external_prs: false)
- end
-
- it 'returns nil' do
- expect(pipeline.modified_paths).to be_nil
- end
- end
end
end
@@ -4524,51 +4536,6 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
subject(:reset_bridge) { pipeline.reset_source_bridge!(project.owner) }
- # This whole block will be removed by https://gitlab.com/gitlab-org/gitlab/-/issues/329194
- # It contains some duplicate checks.
- context 'when the FF ci_reset_bridge_with_subsequent_jobs is disabled' do
- before do
- stub_feature_flags(ci_reset_bridge_with_subsequent_jobs: false)
- end
-
- context 'when the pipeline is a child pipeline and the bridge is depended' do
- let!(:parent_pipeline) { create(:ci_pipeline) }
- let!(:bridge) { create_bridge(parent_pipeline, pipeline, true) }
-
- it 'marks source bridge as pending' do
- reset_bridge
-
- expect(bridge.reload).to be_pending
- end
-
- context 'when the parent pipeline has subsequent jobs after the bridge' do
- let!(:after_bridge_job) { create(:ci_build, :skipped, pipeline: parent_pipeline, stage_idx: bridge.stage_idx + 1) }
-
- it 'does not touch subsequent jobs of the bridge' do
- reset_bridge
-
- expect(after_bridge_job.reload).to be_skipped
- end
- end
-
- context 'when the parent pipeline has a dependent upstream pipeline' do
- let(:upstream_pipeline) { create(:ci_pipeline, project: create(:project)) }
- let!(:upstream_bridge) { create_bridge(upstream_pipeline, parent_pipeline, true) }
-
- let(:upstream_upstream_pipeline) { create(:ci_pipeline, project: create(:project)) }
- let!(:upstream_upstream_bridge) { create_bridge(upstream_upstream_pipeline, upstream_pipeline, true) }
-
- it 'marks all source bridges as pending' do
- reset_bridge
-
- expect(bridge.reload).to be_pending
- expect(upstream_bridge.reload).to be_pending
- expect(upstream_upstream_bridge.reload).to be_pending
- end
- end
- end
- end
-
context 'when the pipeline is a child pipeline and the bridge is depended' do
let!(:parent_pipeline) { create(:ci_pipeline) }
let!(:bridge) { create_bridge(parent_pipeline, pipeline, true) }
diff --git a/spec/models/ci/pipeline_variable_spec.rb b/spec/models/ci/pipeline_variable_spec.rb
index 04fcaab4c2d..4e8d49585d0 100644
--- a/spec/models/ci/pipeline_variable_spec.rb
+++ b/spec/models/ci/pipeline_variable_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Ci::PipelineVariable do
it_behaves_like "CI variable"
- it { is_expected.to validate_uniqueness_of(:key).scoped_to(:pipeline_id) }
+ it { is_expected.to validate_presence_of(:key) }
describe '#hook_attrs' do
let(:variable) { create(:ci_pipeline_variable, key: 'foo', value: 'bar') }
diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb
index ffc8ab4cf8b..31e854c852e 100644
--- a/spec/models/ci/runner_spec.rb
+++ b/spec/models/ci/runner_spec.rb
@@ -531,6 +531,10 @@ RSpec.describe Ci::Runner do
it 'can handle builds' do
expect(runner.can_pick?(build)).to be_truthy
end
+
+ it 'knows namespace id it is assigned to' do
+ expect(runner.namespace_ids).to eq [group.id]
+ end
end
end
diff --git a/spec/models/clusters/agent_spec.rb b/spec/models/clusters/agent_spec.rb
index ea7a55480a8..f9df84e8ff4 100644
--- a/spec/models/clusters/agent_spec.rb
+++ b/spec/models/clusters/agent_spec.rb
@@ -9,6 +9,10 @@ RSpec.describe Clusters::Agent do
it { is_expected.to belong_to(:project).class_name('::Project') }
it { is_expected.to have_many(:agent_tokens).class_name('Clusters::AgentToken') }
it { is_expected.to have_many(:last_used_agent_tokens).class_name('Clusters::AgentToken') }
+ it { is_expected.to have_many(:group_authorizations).class_name('Clusters::Agents::GroupAuthorization') }
+ it { is_expected.to have_many(:authorized_groups).through(:group_authorizations) }
+ it { is_expected.to have_many(:project_authorizations).class_name('Clusters::Agents::ProjectAuthorization') }
+ it { is_expected.to have_many(:authorized_projects).through(:project_authorizations).class_name('::Project') }
it { is_expected.to validate_presence_of(:name) }
it { is_expected.to validate_length_of(:name).is_at_most(63) }
diff --git a/spec/models/clusters/agents/group_authorization_spec.rb b/spec/models/clusters/agents/group_authorization_spec.rb
new file mode 100644
index 00000000000..2a99fb26e3f
--- /dev/null
+++ b/spec/models/clusters/agents/group_authorization_spec.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Clusters::Agents::GroupAuthorization do
+ it { is_expected.to belong_to(:agent).class_name('Clusters::Agent').required }
+ it { is_expected.to belong_to(:group).class_name('::Group').required }
+
+ it { expect(described_class).to validate_jsonb_schema(['config']) }
+end
diff --git a/spec/models/clusters/agents/implicit_authorization_spec.rb b/spec/models/clusters/agents/implicit_authorization_spec.rb
new file mode 100644
index 00000000000..69aa55a350e
--- /dev/null
+++ b/spec/models/clusters/agents/implicit_authorization_spec.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Clusters::Agents::ImplicitAuthorization do
+ let_it_be(:agent) { create(:cluster_agent) }
+
+ subject { described_class.new(agent: agent) }
+
+ it { expect(subject.agent).to eq(agent) }
+ it { expect(subject.agent_id).to eq(agent.id) }
+ it { expect(subject.project).to eq(agent.project) }
+ it { expect(subject.config).to be_nil }
+end
diff --git a/spec/models/clusters/agents/project_authorization_spec.rb b/spec/models/clusters/agents/project_authorization_spec.rb
new file mode 100644
index 00000000000..134c70739ac
--- /dev/null
+++ b/spec/models/clusters/agents/project_authorization_spec.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Clusters::Agents::ProjectAuthorization do
+ it { is_expected.to belong_to(:agent).class_name('Clusters::Agent').required }
+ it { is_expected.to belong_to(:project).class_name('Project').required }
+
+ it { expect(described_class).to validate_jsonb_schema(['config']) }
+end
diff --git a/spec/models/clusters/cluster_spec.rb b/spec/models/clusters/cluster_spec.rb
index 278e200b05c..9d305e31bad 100644
--- a/spec/models/clusters/cluster_spec.rb
+++ b/spec/models/clusters/cluster_spec.rb
@@ -268,6 +268,16 @@ RSpec.describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
it { is_expected.to contain_exactly(cluster) }
end
+ describe '.with_name' do
+ subject { described_class.with_name(name) }
+
+ let(:name) { 'this-cluster' }
+ let!(:cluster) { create(:cluster, :project, name: name) }
+ let!(:another_cluster) { create(:cluster, :project) }
+
+ it { is_expected.to contain_exactly(cluster) }
+ end
+
describe 'validations' do
subject { cluster.valid? }
@@ -902,8 +912,8 @@ RSpec.describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
subject { cluster.kubernetes_namespace_for(environment, deployable: build) }
let(:environment_name) { 'the-environment-name' }
- let(:environment) { create(:environment, name: environment_name, project: cluster.project, last_deployable: build) }
- let(:build) { create(:ci_build, environment: environment_name, project: cluster.project) }
+ let(:environment) { create(:environment, name: environment_name, project: cluster.project) }
+ let(:build) { create(:ci_build, environment: environment, project: cluster.project) }
let(:cluster) { create(:cluster, :project, managed: managed_cluster) }
let(:managed_cluster) { true }
let(:default_namespace) { Gitlab::Kubernetes::DefaultNamespace.new(cluster, project: cluster.project).from_environment_slug(environment.slug) }
diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb
index a951af4cc4f..7134a387e65 100644
--- a/spec/models/commit_status_spec.rb
+++ b/spec/models/commit_status_spec.rb
@@ -88,6 +88,15 @@ RSpec.describe CommitStatus do
end
end
+ describe '.created_at_before' do
+ it 'finds the relevant records' do
+ status = create(:commit_status, created_at: 1.day.ago, project: project)
+ create(:commit_status, created_at: 1.day.since, project: project)
+
+ expect(described_class.created_at_before(Time.current)).to eq([status])
+ end
+ end
+
describe '.updated_before' do
let!(:lookback) { 5.days.ago }
let!(:timeout) { 1.day.ago }
diff --git a/spec/models/concerns/approvable_base_spec.rb b/spec/models/concerns/approvable_base_spec.rb
index c7ea2631a24..79053e98db7 100644
--- a/spec/models/concerns/approvable_base_spec.rb
+++ b/spec/models/concerns/approvable_base_spec.rb
@@ -60,6 +60,34 @@ RSpec.describe ApprovableBase do
end
end
+ describe '#can_be_unapproved_by?' do
+ subject { merge_request.can_be_unapproved_by?(user) }
+
+ before do
+ merge_request.project.add_developer(user)
+ end
+
+ it 'returns false' do
+ is_expected.to be_falsy
+ end
+
+ context 'when a user has approved' do
+ let!(:approval) { create(:approval, merge_request: merge_request, user: user) }
+
+ it 'returns true' do
+ is_expected.to be_truthy
+ end
+ end
+
+ context 'when a user is nil' do
+ let(:user) { nil }
+
+ it 'returns false' do
+ is_expected.to be_falsy
+ end
+ end
+ end
+
describe '.not_approved_by_users_with_usernames' do
subject { MergeRequest.not_approved_by_users_with_usernames([user.username, user2.username]) }
diff --git a/spec/models/concerns/calloutable_spec.rb b/spec/models/concerns/calloutable_spec.rb
new file mode 100644
index 00000000000..d847413de88
--- /dev/null
+++ b/spec/models/concerns/calloutable_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Calloutable do
+ subject { build(:user_callout) }
+
+ describe "Associations" do
+ it { is_expected.to belong_to(:user) }
+ end
+
+ describe 'validations' do
+ it { is_expected.to validate_presence_of(:user) }
+ end
+
+ describe '#dismissed_after?' do
+ let(:some_feature_name) { UserCallout.feature_names.keys.second }
+ let(:callout_dismissed_month_ago) { create(:user_callout, feature_name: some_feature_name, dismissed_at: 1.month.ago )}
+ let(:callout_dismissed_day_ago) { create(:user_callout, feature_name: some_feature_name, dismissed_at: 1.day.ago )}
+
+ it 'returns whether a callout dismissed after specified date' do
+ expect(callout_dismissed_month_ago.dismissed_after?(15.days.ago)).to eq(false)
+ expect(callout_dismissed_day_ago.dismissed_after?(15.days.ago)).to eq(true)
+ end
+ end
+end
diff --git a/spec/models/concerns/featurable_spec.rb b/spec/models/concerns/featurable_spec.rb
index 295f3523dd5..453b6f7f29a 100644
--- a/spec/models/concerns/featurable_spec.rb
+++ b/spec/models/concerns/featurable_spec.rb
@@ -30,8 +30,11 @@ RSpec.describe Featurable do
describe '.set_available_features' do
let!(:klass) do
- Class.new do
+ Class.new(ApplicationRecord) do
include Featurable
+
+ self.table_name = 'project_features'
+
set_available_features %i(feature1 feature2)
def feature1_access_level
diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb
index 071e0dcba44..2a3f639a8ac 100644
--- a/spec/models/concerns/issuable_spec.rb
+++ b/spec/models/concerns/issuable_spec.rb
@@ -368,6 +368,23 @@ RSpec.describe Issuable do
expect(sorted_issue_ids).to eq(sorted_issue_ids.uniq)
end
end
+
+ context 'by title' do
+ let!(:issue1) { create(:issue, project: project, title: 'foo') }
+ let!(:issue2) { create(:issue, project: project, title: 'bar') }
+ let!(:issue3) { create(:issue, project: project, title: 'baz') }
+ let!(:issue4) { create(:issue, project: project, title: 'Baz 2') }
+
+ it 'sorts asc' do
+ issues = project.issues.sort_by_attribute('title_asc')
+ expect(issues).to eq([issue2, issue3, issue4, issue1])
+ end
+
+ it 'sorts desc' do
+ issues = project.issues.sort_by_attribute('title_desc')
+ expect(issues).to eq([issue1, issue4, issue3, issue2])
+ end
+ end
end
describe '#subscribed?' do
diff --git a/spec/models/concerns/loose_foreign_key_spec.rb b/spec/models/concerns/loose_foreign_key_spec.rb
new file mode 100644
index 00000000000..ce5e33261a9
--- /dev/null
+++ b/spec/models/concerns/loose_foreign_key_spec.rb
@@ -0,0 +1,83 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe LooseForeignKey do
+ let(:project_klass) do
+ Class.new(ApplicationRecord) do
+ include LooseForeignKey
+
+ self.table_name = 'projects'
+
+ loose_foreign_key :issues, :project_id, on_delete: :async_delete, gitlab_schema: :gitlab_main
+ loose_foreign_key 'merge_requests', 'project_id', 'on_delete' => 'async_nullify', 'gitlab_schema' => :gitlab_main
+ end
+ end
+
+ it 'exposes the loose foreign key definitions' do
+ definitions = project_klass.loose_foreign_key_definitions
+
+ tables = definitions.map(&:to_table)
+ expect(tables).to eq(%w[issues merge_requests])
+ end
+
+ it 'casts strings to symbol' do
+ definition = project_klass.loose_foreign_key_definitions.last
+
+ expect(definition.from_table).to eq('projects')
+ expect(definition.to_table).to eq('merge_requests')
+ expect(definition.column).to eq('project_id')
+ expect(definition.on_delete).to eq(:async_nullify)
+ expect(definition.options[:gitlab_schema]).to eq(:gitlab_main)
+ end
+
+ context 'validation' do
+ context 'on_delete validation' do
+ let(:invalid_class) do
+ Class.new(ApplicationRecord) do
+ include LooseForeignKey
+
+ self.table_name = 'projects'
+
+ loose_foreign_key :issues, :project_id, on_delete: :async_delete, gitlab_schema: :gitlab_main
+ loose_foreign_key :merge_requests, :project_id, on_delete: :async_nullify, gitlab_schema: :gitlab_main
+ loose_foreign_key :merge_requests, :project_id, on_delete: :destroy, gitlab_schema: :gitlab_main
+ end
+ end
+
+ it 'raises error when invalid `on_delete` option was given' do
+ expect { invalid_class }.to raise_error /Invalid on_delete option given: destroy/
+ end
+ end
+
+ context 'gitlab_schema validation' do
+ let(:invalid_class) do
+ Class.new(ApplicationRecord) do
+ include LooseForeignKey
+
+ self.table_name = 'projects'
+
+ loose_foreign_key :merge_requests, :project_id, on_delete: :async_nullify, gitlab_schema: :unknown
+ end
+ end
+
+ it 'raises error when invalid `gitlab_schema` option was given' do
+ expect { invalid_class }.to raise_error /Invalid gitlab_schema option given: unknown/
+ end
+ end
+
+ context 'inheritance validation' do
+ let(:inherited_project_class) do
+ Class.new(Project) do
+ include LooseForeignKey
+
+ loose_foreign_key :issues, :project_id, on_delete: :async_delete, gitlab_schema: :gitlab_main
+ end
+ end
+
+ it 'raises error when loose_foreign_key is defined in a child ActiveRecord model' do
+ expect { inherited_project_class }.to raise_error /Please define the loose_foreign_key on the Project class/
+ end
+ end
+ end
+end
diff --git a/spec/models/concerns/partitioned_table_spec.rb b/spec/models/concerns/partitioned_table_spec.rb
index c37fb81a1cf..714db4e21bd 100644
--- a/spec/models/concerns/partitioned_table_spec.rb
+++ b/spec/models/concerns/partitioned_table_spec.rb
@@ -35,11 +35,5 @@ RSpec.describe PartitionedTable do
expect(my_class.partitioning_strategy.partitioning_key).to eq(key)
end
-
- it 'registers itself with the PartitionCreator' do
- expect(Gitlab::Database::Partitioning::PartitionManager).to receive(:register).with(my_class)
-
- subject
- end
end
end
diff --git a/spec/models/concerns/sanitizable_spec.rb b/spec/models/concerns/sanitizable_spec.rb
new file mode 100644
index 00000000000..4a1d463d666
--- /dev/null
+++ b/spec/models/concerns/sanitizable_spec.rb
@@ -0,0 +1,101 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sanitizable do
+ let_it_be(:klass) do
+ Class.new do
+ include ActiveModel::Model
+ include ActiveModel::Attributes
+ include ActiveModel::Validations
+ include ActiveModel::Validations::Callbacks
+ include Sanitizable
+
+ attribute :id, :integer
+ attribute :name, :string
+ attribute :description, :string
+ attribute :html_body, :string
+
+ sanitizes! :name, :description
+
+ def self.model_name
+ ActiveModel::Name.new(self, nil, 'SomeModel')
+ end
+ end
+ end
+
+ shared_examples 'noop' do
+ it 'has no effect' do
+ expect(subject).to eq(input)
+ end
+ end
+
+ shared_examples 'a sanitizable field' do |field|
+ let(:record) { klass.new(id: 1, name: input, description: input, html_body: input) }
+
+ before do
+ record.valid?
+ end
+
+ subject { record.public_send(field) }
+
+ describe field do
+ context 'when input is nil' do
+ let_it_be(:input) { nil }
+
+ it_behaves_like 'noop'
+ end
+
+ context 'when input does not contain any html' do
+ let_it_be(:input) { 'hello, world!' }
+
+ it_behaves_like 'noop'
+ end
+
+ context 'when input contains html' do
+ let_it_be(:input) { 'hello<script>alert(1)</script>' }
+
+ it 'sanitizes the input' do
+ expect(subject).to eq('hello')
+ end
+
+ context 'when input includes html entities' do
+ let(:input) { '<div>hello&world</div>' }
+
+ it 'does not escape them' do
+ expect(subject).to eq(' hello&world ')
+ end
+ end
+ end
+
+ context 'when input contains pre-escaped html entities' do
+ let_it_be(:input) { '&lt;script&gt;alert(1)&lt;/script&gt;' }
+
+ it_behaves_like 'noop'
+
+ it 'is not valid', :aggregate_failures do
+ expect(record).not_to be_valid
+ expect(record.errors.full_messages).to include('Name cannot contain escaped HTML entities')
+ end
+ end
+ end
+ end
+
+ shared_examples 'a non-sanitizable field' do |field, input|
+ describe field do
+ subject { klass.new(field => input).valid? }
+
+ it 'has no effect' do
+ expect(Sanitize).not_to receive(:fragment)
+
+ subject
+ end
+ end
+ end
+
+ it_behaves_like 'a non-sanitizable field', :id, 1
+ it_behaves_like 'a non-sanitizable field', :html_body, 'hello<script>alert(1)</script>'
+
+ it_behaves_like 'a sanitizable field', :name
+ it_behaves_like 'a sanitizable field', :description
+end
diff --git a/spec/models/concerns/taggable_queries_spec.rb b/spec/models/concerns/taggable_queries_spec.rb
new file mode 100644
index 00000000000..0d248c4636e
--- /dev/null
+++ b/spec/models/concerns/taggable_queries_spec.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe TaggableQueries do
+ it 'keeps MAX_TAGS_IDS in sync with TAGS_LIMIT' do
+ expect(described_class::MAX_TAGS_IDS).to eq(Gitlab::Ci::Config::Entry::Tags::TAGS_LIMIT)
+ end
+end
diff --git a/spec/models/customer_relations/contact_spec.rb b/spec/models/customer_relations/contact_spec.rb
new file mode 100644
index 00000000000..b19554dd67e
--- /dev/null
+++ b/spec/models/customer_relations/contact_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe CustomerRelations::Contact, type: :model do
+ describe 'associations' do
+ it { is_expected.to belong_to(:group) }
+ it { is_expected.to belong_to(:organization).optional }
+ end
+
+ describe 'validations' do
+ subject { build(:contact) }
+
+ it { is_expected.to validate_presence_of(:group) }
+ it { is_expected.to validate_presence_of(:first_name) }
+ it { is_expected.to validate_presence_of(:last_name) }
+
+ it { is_expected.to validate_length_of(:phone).is_at_most(32) }
+ it { is_expected.to validate_length_of(:first_name).is_at_most(255) }
+ it { is_expected.to validate_length_of(:last_name).is_at_most(255) }
+ it { is_expected.to validate_length_of(:email).is_at_most(255) }
+ it { is_expected.to validate_length_of(:description).is_at_most(1024) }
+
+ it_behaves_like 'an object with RFC3696 compliant email-formatted attributes', :email
+ end
+
+ describe '#before_validation' do
+ it 'strips leading and trailing whitespace' do
+ contact = described_class.new(first_name: ' First ', last_name: ' Last ', phone: ' 123456 ')
+ contact.valid?
+
+ expect(contact.first_name).to eq('First')
+ expect(contact.last_name).to eq('Last')
+ expect(contact.phone).to eq('123456')
+ end
+ end
+end
diff --git a/spec/models/customer_relations/organization_spec.rb b/spec/models/customer_relations/organization_spec.rb
index b79b5748156..71b455ae8c8 100644
--- a/spec/models/customer_relations/organization_spec.rb
+++ b/spec/models/customer_relations/organization_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe CustomerRelations::Organization, type: :model do
end
describe 'validations' do
- subject { create(:organization) }
+ subject { build(:organization) }
it { is_expected.to validate_presence_of(:group) }
it { is_expected.to validate_presence_of(:name) }
diff --git a/spec/models/dependency_proxy/blob_spec.rb b/spec/models/dependency_proxy/blob_spec.rb
index 7c8a1eb95e8..3797f6184fe 100644
--- a/spec/models/dependency_proxy/blob_spec.rb
+++ b/spec/models/dependency_proxy/blob_spec.rb
@@ -6,10 +6,13 @@ RSpec.describe DependencyProxy::Blob, type: :model do
it { is_expected.to belong_to(:group) }
end
+ it_behaves_like 'having unique enum values'
+
describe 'validations' do
it { is_expected.to validate_presence_of(:group) }
it { is_expected.to validate_presence_of(:file) }
it { is_expected.to validate_presence_of(:file_name) }
+ it { is_expected.to validate_presence_of(:status) }
end
describe '.total_size' do
diff --git a/spec/models/dependency_proxy/image_ttl_group_policy_spec.rb b/spec/models/dependency_proxy/image_ttl_group_policy_spec.rb
new file mode 100644
index 00000000000..2906ea7b774
--- /dev/null
+++ b/spec/models/dependency_proxy/image_ttl_group_policy_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe DependencyProxy::ImageTtlGroupPolicy, type: :model do
+ describe 'relationships' do
+ it { is_expected.to belong_to(:group) }
+ end
+
+ describe 'validations' do
+ it { is_expected.to validate_presence_of(:group) }
+
+ describe '#enabled' do
+ it { is_expected.to allow_value(true).for(:enabled) }
+ it { is_expected.to allow_value(false).for(:enabled) }
+ it { is_expected.not_to allow_value(nil).for(:enabled) }
+ end
+
+ describe '#ttl' do
+ it { is_expected.to validate_numericality_of(:ttl).allow_nil.is_greater_than(0) }
+ end
+ end
+end
diff --git a/spec/models/dependency_proxy/manifest_spec.rb b/spec/models/dependency_proxy/manifest_spec.rb
index 4203644c003..2a085b3613b 100644
--- a/spec/models/dependency_proxy/manifest_spec.rb
+++ b/spec/models/dependency_proxy/manifest_spec.rb
@@ -6,11 +6,14 @@ RSpec.describe DependencyProxy::Manifest, type: :model do
it { is_expected.to belong_to(:group) }
end
+ it_behaves_like 'having unique enum values'
+
describe 'validations' do
it { is_expected.to validate_presence_of(:group) }
it { is_expected.to validate_presence_of(:file) }
it { is_expected.to validate_presence_of(:file_name) }
it { is_expected.to validate_presence_of(:digest) }
+ it { is_expected.to validate_presence_of(:status) }
end
describe 'file is being stored' do
diff --git a/spec/models/design_management/action_spec.rb b/spec/models/design_management/action_spec.rb
index 59c58191718..0a8bbc8d26e 100644
--- a/spec/models/design_management/action_spec.rb
+++ b/spec/models/design_management/action_spec.rb
@@ -8,37 +8,55 @@ RSpec.describe DesignManagement::Action do
end
describe 'scopes' do
- describe '.most_recent' do
- let_it_be(:design_a) { create(:design) }
- let_it_be(:design_b) { create(:design) }
- let_it_be(:design_c) { create(:design) }
+ let_it_be(:issue) { create(:issue) }
+ let_it_be(:design_a) { create(:design, issue: issue) }
+ let_it_be(:design_b) { create(:design, issue: issue) }
- let(:designs) { [design_a, design_b, design_c] }
+ context 'with 3 designs' do
+ let_it_be(:design_c) { create(:design, issue: issue) }
- before_all do
- create(:design_version, designs: [design_a, design_b, design_c])
- create(:design_version, designs: [design_a, design_b])
- create(:design_version, designs: [design_a])
- end
+ let_it_be(:action_a_1) { create(:design_action, design: design_a) }
+ let_it_be(:action_a_2) { create(:design_action, design: design_a, event: :deletion) }
+ let_it_be(:action_b) { create(:design_action, design: design_b) }
+ let_it_be(:action_c) { create(:design_action, design: design_c, event: :deletion) }
+
+ describe '.most_recent' do
+ let(:designs) { [design_a, design_b, design_c] }
+
+ before_all do
+ create(:design_version, designs: [design_a, design_b, design_c])
+ create(:design_version, designs: [design_a, design_b])
+ create(:design_version, designs: [design_a])
+ end
+
+ it 'finds the correct version for each design' do
+ dvs = described_class.where(design: designs)
+
+ expected = designs
+ .map(&:id)
+ .zip(dvs.order("version_id DESC").pluck(:version_id).uniq)
- it 'finds the correct version for each design' do
- dvs = described_class.where(design: designs)
+ actual = dvs.most_recent.map { |dv| [dv.design_id, dv.version_id] }
- expected = designs
- .map(&:id)
- .zip(dvs.order("version_id DESC").pluck(:version_id).uniq)
+ expect(actual).to eq(expected)
+ end
+ end
- actual = dvs.most_recent.map { |dv| [dv.design_id, dv.version_id] }
+ describe '.by_design' do
+ it 'returns the actions by design_id' do
+ expect(described_class.by_design([design_a.id, design_b.id]))
+ .to match_array([action_a_1, action_a_2, action_b])
+ end
+ end
- expect(actual).to eq(expected)
+ describe '.by_event' do
+ it 'returns the actions by event type' do
+ expect(described_class.by_event(:deletion)).to match_array([action_a_2, action_c])
+ end
end
end
describe '.up_to_version' do
- let_it_be(:issue) { create(:issue) }
- let_it_be(:design_a) { create(:design, issue: issue) }
- let_it_be(:design_b) { create(:design, issue: issue) }
-
# let bindings are not available in before(:all) contexts,
# so we need to redefine the array on each construction.
let_it_be(:oldest) { create(:design_version, designs: [design_a, design_b]) }
diff --git a/spec/models/diff_note_spec.rb b/spec/models/diff_note_spec.rb
index 11652d9841b..f377b34679c 100644
--- a/spec/models/diff_note_spec.rb
+++ b/spec/models/diff_note_spec.rb
@@ -558,4 +558,31 @@ RSpec.describe DiffNote do
it { is_expected.to eq('note') }
end
+
+ describe '#shas' do
+ it 'returns list of SHAs based on original_position' do
+ expect(subject.shas).to match_array([
+ position.base_sha,
+ position.start_sha,
+ position.head_sha
+ ])
+ end
+
+ context 'when position changes' do
+ before do
+ subject.position = new_position
+ end
+
+ it 'includes the new position SHAs' do
+ expect(subject.shas).to match_array([
+ position.base_sha,
+ position.start_sha,
+ position.head_sha,
+ new_position.base_sha,
+ new_position.start_sha,
+ new_position.head_sha
+ ])
+ end
+ end
+ end
end
diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb
index 53561586d61..e3e9d1f7a71 100644
--- a/spec/models/environment_spec.rb
+++ b/spec/models/environment_spec.rb
@@ -135,6 +135,20 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
environment.stop
end
+
+ context 'when environment has auto stop period' do
+ let!(:environment) { create(:environment, :available, :auto_stoppable, project: project) }
+
+ it 'clears auto stop period when the environment has stopped' do
+ environment.stop!
+
+ expect(environment.auto_stop_at).to be_nil
+ end
+
+ it 'does not clear auto stop period when the environment has not stopped' do
+ expect(environment.auto_stop_at).to be_present
+ end
+ end
end
describe '.for_name_like' do
@@ -233,55 +247,6 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
end
end
- describe '.stop_actions' do
- subject { environments.stop_actions }
-
- let_it_be(:project) { create(:project, :repository) }
- let_it_be(:user) { create(:user) }
-
- let(:environments) { Environment.all }
-
- before_all do
- project.add_developer(user)
- project.repository.add_branch(user, 'review/feature-1', 'master')
- project.repository.add_branch(user, 'review/feature-2', 'master')
- end
-
- shared_examples_for 'correct filtering' do
- it 'returns stop actions for available environments only' do
- expect(subject.count).to eq(1)
- expect(subject.first.name).to eq('stop_review_app')
- expect(subject.first.ref).to eq('review/feature-1')
- end
- end
-
- before do
- create_review_app(user, project, 'review/feature-1')
- create_review_app(user, project, 'review/feature-2')
- end
-
- it 'returns stop actions for environments' do
- expect(subject.count).to eq(2)
- expect(subject).to match_array(Ci::Build.where(name: 'stop_review_app'))
- end
-
- context 'when one of the stop actions has already been executed' do
- before do
- Ci::Build.where(ref: 'review/feature-2').find_by_name('stop_review_app').enqueue!
- end
-
- it_behaves_like 'correct filtering'
- end
-
- context 'when one of the deployments does not have stop action' do
- before do
- Deployment.where(ref: 'review/feature-2').update_all(on_stop: nil)
- end
-
- it_behaves_like 'correct filtering'
- end
- end
-
describe '.pluck_names' do
subject { described_class.pluck_names }
@@ -726,6 +691,28 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
end
end
+ describe '#last_deployable' do
+ subject { environment.last_deployable }
+
+ context 'does not join across databases' do
+ let(:pipeline_a) { create(:ci_pipeline, project: project) }
+ let(:pipeline_b) { create(:ci_pipeline, project: project) }
+ let(:ci_build_a) { create(:ci_build, project: project, pipeline: pipeline_a) }
+ let(:ci_build_b) { create(:ci_build, project: project, pipeline: pipeline_b) }
+
+ before do
+ create(:deployment, :success, project: project, environment: environment, deployable: ci_build_a)
+ create(:deployment, :failed, project: project, environment: environment, deployable: ci_build_b)
+ end
+
+ it 'when called' do
+ with_cross_joins_prevented do
+ expect(subject.id).to eq(ci_build_a.id)
+ end
+ end
+ end
+ end
+
describe '#last_visible_deployment' do
subject { environment.last_visible_deployment }
@@ -768,6 +755,86 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
end
end
+ describe '#last_visible_deployable' do
+ subject { environment.last_visible_deployable }
+
+ context 'does not join across databases' do
+ let(:pipeline_a) { create(:ci_pipeline, project: project) }
+ let(:pipeline_b) { create(:ci_pipeline, project: project) }
+ let(:ci_build_a) { create(:ci_build, project: project, pipeline: pipeline_a) }
+ let(:ci_build_b) { create(:ci_build, project: project, pipeline: pipeline_b) }
+
+ before do
+ create(:deployment, :success, project: project, environment: environment, deployable: ci_build_a)
+ create(:deployment, :failed, project: project, environment: environment, deployable: ci_build_b)
+ end
+
+ it 'for direct call' do
+ with_cross_joins_prevented do
+ expect(subject.id).to eq(ci_build_b.id)
+ end
+ end
+
+ it 'for preload' do
+ environment.reload
+
+ with_cross_joins_prevented do
+ ActiveRecord::Associations::Preloader.new.preload(environment, [last_visible_deployable: []])
+ expect(subject.id).to eq(ci_build_b.id)
+ end
+ end
+ end
+
+ context 'call after preload' do
+ it 'fetches from association cache' do
+ pipeline = create(:ci_pipeline, project: project)
+ ci_build = create(:ci_build, project: project, pipeline: pipeline)
+ create(:deployment, :failed, project: project, environment: environment, deployable: ci_build)
+
+ environment.reload
+ ActiveRecord::Associations::Preloader.new.preload(environment, [last_visible_deployable: []])
+
+ query_count = ActiveRecord::QueryRecorder.new do
+ expect(subject.id).to eq(ci_build.id)
+ end.count
+
+ expect(query_count).to eq(0)
+ end
+ end
+
+ context 'when the feature for disable_join is disabled' do
+ let(:pipeline) { create(:ci_pipeline, project: project) }
+ let(:ci_build) { create(:ci_build, project: project, pipeline: pipeline) }
+
+ before do
+ stub_feature_flags(environment_last_visible_pipeline_disable_joins: false)
+ create(:deployment, :failed, project: project, environment: environment, deployable: ci_build)
+ end
+
+ context 'for preload' do
+ it 'executes the original association instead of override' do
+ environment.reload
+ ActiveRecord::Associations::Preloader.new.preload(environment, [last_visible_deployable: []])
+
+ expect_any_instance_of(Deployment).not_to receive(:deployable)
+
+ query_count = ActiveRecord::QueryRecorder.new do
+ expect(subject.id).to eq(ci_build.id)
+ end.count
+
+ expect(query_count).to eq(0)
+ end
+ end
+
+ context 'for direct call' do
+ it 'executes the original association instead of override' do
+ expect_any_instance_of(Deployment).not_to receive(:deployable)
+ expect(subject.id).to eq(ci_build.id)
+ end
+ end
+ end
+ end
+
describe '#last_visible_pipeline' do
let(:user) { create(:user) }
let_it_be(:project) { create(:project, :repository) }
@@ -812,6 +879,35 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
expect(last_pipeline).to eq(failed_pipeline)
end
+ context 'does not join across databases' do
+ let(:pipeline_a) { create(:ci_pipeline, project: project) }
+ let(:pipeline_b) { create(:ci_pipeline, project: project) }
+ let(:ci_build_a) { create(:ci_build, project: project, pipeline: pipeline_a) }
+ let(:ci_build_b) { create(:ci_build, project: project, pipeline: pipeline_b) }
+
+ before do
+ create(:deployment, :success, project: project, environment: environment, deployable: ci_build_a)
+ create(:deployment, :failed, project: project, environment: environment, deployable: ci_build_b)
+ end
+
+ subject { environment.last_visible_pipeline }
+
+ it 'for direct call' do
+ with_cross_joins_prevented do
+ expect(subject.id).to eq(pipeline_b.id)
+ end
+ end
+
+ it 'for preload' do
+ environment.reload
+
+ with_cross_joins_prevented do
+ ActiveRecord::Associations::Preloader.new.preload(environment, [last_visible_pipeline: []])
+ expect(subject.id).to eq(pipeline_b.id)
+ end
+ end
+ end
+
context 'for the environment' do
it 'returns the last pipeline' do
pipeline = create(:ci_pipeline, project: project, user: user, sha: commit.sha)
@@ -850,6 +946,57 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
end
end
end
+
+ context 'call after preload' do
+ it 'fetches from association cache' do
+ pipeline = create(:ci_pipeline, project: project)
+ ci_build = create(:ci_build, project: project, pipeline: pipeline)
+ create(:deployment, :failed, project: project, environment: environment, deployable: ci_build)
+
+ environment.reload
+ ActiveRecord::Associations::Preloader.new.preload(environment, [last_visible_pipeline: []])
+
+ query_count = ActiveRecord::QueryRecorder.new do
+ expect(environment.last_visible_pipeline.id).to eq(pipeline.id)
+ end.count
+
+ expect(query_count).to eq(0)
+ end
+ end
+
+ context 'when the feature for disable_join is disabled' do
+ let(:pipeline) { create(:ci_pipeline, project: project) }
+ let(:ci_build) { create(:ci_build, project: project, pipeline: pipeline) }
+
+ before do
+ stub_feature_flags(environment_last_visible_pipeline_disable_joins: false)
+ create(:deployment, :failed, project: project, environment: environment, deployable: ci_build)
+ end
+
+ subject { environment.last_visible_pipeline }
+
+ context 'for preload' do
+ it 'executes the original association instead of override' do
+ environment.reload
+ ActiveRecord::Associations::Preloader.new.preload(environment, [last_visible_pipeline: []])
+
+ expect_any_instance_of(Ci::Build).not_to receive(:pipeline)
+
+ query_count = ActiveRecord::QueryRecorder.new do
+ expect(subject.id).to eq(pipeline.id)
+ end.count
+
+ expect(query_count).to eq(0)
+ end
+ end
+
+ context 'for direct call' do
+ it 'executes the original association instead of override' do
+ expect_any_instance_of(Ci::Build).not_to receive(:pipeline)
+ expect(subject.id).to eq(pipeline.id)
+ end
+ end
+ end
end
describe '#upcoming_deployment' do
diff --git a/spec/models/error_tracking/error_spec.rb b/spec/models/error_tracking/error_spec.rb
index 57899985daf..5543392b624 100644
--- a/spec/models/error_tracking/error_spec.rb
+++ b/spec/models/error_tracking/error_spec.rb
@@ -16,6 +16,62 @@ RSpec.describe ErrorTracking::Error, type: :model do
it { is_expected.to validate_presence_of(:actor) }
end
+ describe '.report_error' do
+ it 'updates existing record with a new timestamp' do
+ timestamp = Time.zone.now
+
+ reported_error = described_class.report_error(
+ name: error.name,
+ description: 'Lorem ipsum',
+ actor: error.actor,
+ platform: error.platform,
+ timestamp: timestamp
+ )
+
+ expect(reported_error.id).to eq(error.id)
+ expect(reported_error.last_seen_at).to eq(timestamp)
+ expect(reported_error.description).to eq('Lorem ipsum')
+ end
+ end
+
+ describe '.sort_by_attribute' do
+ let!(:error2) { create(:error_tracking_error, first_seen_at: Time.zone.now - 2.weeks, last_seen_at: Time.zone.now - 1.week) }
+ let!(:error3) { create(:error_tracking_error, first_seen_at: Time.zone.now - 3.weeks, last_seen_at: Time.zone.now.yesterday) }
+ let!(:errors) { [error, error2, error3] }
+
+ subject { described_class.where(id: errors).sort_by_attribute(sort) }
+
+ context 'id desc by default' do
+ let(:sort) { nil }
+
+ it { is_expected.to eq([error3, error2, error]) }
+ end
+
+ context 'first_seen' do
+ let(:sort) { 'first_seen' }
+
+ it { is_expected.to eq([error, error2, error3]) }
+ end
+
+ context 'last_seen' do
+ let(:sort) { 'last_seen' }
+
+ it { is_expected.to eq([error, error3, error2]) }
+ end
+
+ context 'frequency' do
+ let(:sort) { 'frequency' }
+
+ before do
+ create(:error_tracking_error_event, error: error2)
+ create(:error_tracking_error_event, error: error2)
+ create(:error_tracking_error_event, error: error3)
+ end
+
+ it { is_expected.to eq([error2, error3, error]) }
+ end
+ end
+
describe '#title' do
it { expect(error.title).to eq('ActionView::MissingTemplate Missing template posts/edit') }
end
diff --git a/spec/models/error_tracking/project_error_tracking_setting_spec.rb b/spec/models/error_tracking/project_error_tracking_setting_spec.rb
index 7be61f4950e..29255e53fcf 100644
--- a/spec/models/error_tracking/project_error_tracking_setting_spec.rb
+++ b/spec/models/error_tracking/project_error_tracking_setting_spec.rb
@@ -478,18 +478,17 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do
describe '#sentry_enabled' do
using RSpec::Parameterized::TableSyntax
- where(:enabled, :integrated, :feature_flag, :sentry_enabled) do
- true | false | false | true
- true | true | false | true
- true | true | true | false
- false | false | false | false
+ where(:enabled, :integrated, :sentry_enabled) do
+ true | false | true
+ true | true | false
+ true | true | false
+ false | false | false
end
with_them do
before do
subject.enabled = enabled
subject.integrated = integrated
- stub_feature_flags(integrated_error_tracking: feature_flag)
end
it { expect(subject.sentry_enabled).to eq(sentry_enabled) }
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index ddf12c8e4c4..d536a0783bc 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -30,10 +30,12 @@ RSpec.describe Group do
it { is_expected.to have_many(:group_deploy_keys) }
it { is_expected.to have_many(:integrations) }
it { is_expected.to have_one(:dependency_proxy_setting) }
+ it { is_expected.to have_one(:dependency_proxy_image_ttl_policy) }
it { is_expected.to have_many(:dependency_proxy_blobs) }
it { is_expected.to have_many(:dependency_proxy_manifests) }
it { is_expected.to have_many(:debian_distributions).class_name('Packages::Debian::GroupDistribution').dependent(:destroy) }
it { is_expected.to have_many(:daily_build_group_report_results).class_name('Ci::DailyBuildGroupReportResult') }
+ it { is_expected.to have_many(:group_callouts).class_name('Users::GroupCallout').with_foreign_key(:group_id) }
describe '#members & #requesters' do
let(:requester) { create(:user) }
@@ -80,7 +82,7 @@ RSpec.describe Group do
group = build(:group, parent: build(:namespace))
expect(group).not_to be_valid
- expect(group.errors[:parent_id].first).to eq('a group cannot have a user namespace as its parent')
+ expect(group.errors[:parent_id].first).to eq('user namespace cannot be the parent of another namespace')
end
it 'allows a group to have another group as its parent' do
@@ -2273,19 +2275,27 @@ RSpec.describe Group do
end
describe '.groups_including_descendants_by' do
- it 'returns the expected groups for a group and its descendants' do
- parent_group1 = create(:group)
- child_group1 = create(:group, parent: parent_group1)
- child_group2 = create(:group, parent: parent_group1)
+ let_it_be(:parent_group1) { create(:group) }
+ let_it_be(:parent_group2) { create(:group) }
+ let_it_be(:extra_group) { create(:group) }
+ let_it_be(:child_group1) { create(:group, parent: parent_group1) }
+ let_it_be(:child_group2) { create(:group, parent: parent_group1) }
+ let_it_be(:child_group3) { create(:group, parent: parent_group2) }
- parent_group2 = create(:group)
- child_group3 = create(:group, parent: parent_group2)
+ subject { described_class.groups_including_descendants_by([parent_group2.id, parent_group1.id]) }
- create(:group)
+ shared_examples 'returns the expected groups for a group and its descendants' do
+ specify { is_expected.to contain_exactly(parent_group1, parent_group2, child_group1, child_group2, child_group3) }
+ end
+
+ it_behaves_like 'returns the expected groups for a group and its descendants'
- groups = described_class.groups_including_descendants_by([parent_group2.id, parent_group1.id])
+ context 'when :linear_group_including_descendants_by feature flag is disabled' do
+ before do
+ stub_feature_flags(linear_group_including_descendants_by: false)
+ end
- expect(groups).to contain_exactly(parent_group1, parent_group2, child_group1, child_group2, child_group3)
+ it_behaves_like 'returns the expected groups for a group and its descendants'
end
end
@@ -2477,6 +2487,12 @@ RSpec.describe Group do
end
end
+ describe '#membership_locked?' do
+ it 'returns false' do
+ expect(build(:group)).not_to be_membership_locked
+ end
+ end
+
describe '#default_owner' do
let(:group) { build(:group) }
@@ -2619,6 +2635,26 @@ RSpec.describe Group do
end
end
+ describe '.organizations' do
+ it 'returns organizations belonging to the group' do
+ organization1 = create(:organization, group: group)
+ create(:organization)
+ organization3 = create(:organization, group: group)
+
+ expect(group.organizations).to contain_exactly(organization1, organization3)
+ end
+ end
+
+ describe '.contacts' do
+ it 'returns contacts belonging to the group' do
+ contact1 = create(:contact, group: group)
+ create(:contact)
+ contact3 = create(:contact, group: group)
+
+ expect(group.contacts).to contain_exactly(contact1, contact3)
+ end
+ end
+
describe '#to_ability_name' do
it 'returns group' do
group = build(:group)
@@ -2696,4 +2732,40 @@ RSpec.describe Group do
group.open_merge_requests_count
end
end
+
+ describe '#dependency_proxy_image_prefix' do
+ let_it_be(:group) { build_stubbed(:group, path: 'GroupWithUPPERcaseLetters') }
+
+ it 'converts uppercase letters to lowercase' do
+ expect(group.dependency_proxy_image_prefix).to end_with("/groupwithuppercaseletters#{DependencyProxy::URL_SUFFIX}")
+ end
+
+ it 'removes the protocol' do
+ expect(group.dependency_proxy_image_prefix).not_to include('http')
+ end
+ end
+
+ describe '#dependency_proxy_image_ttl_policy' do
+ subject(:ttl_policy) { group.dependency_proxy_image_ttl_policy }
+
+ it 'builds a new policy if one does not exist', :aggregate_failures do
+ expect(ttl_policy.ttl).to eq(90)
+ expect(ttl_policy.enabled).to eq(false)
+ expect(ttl_policy.created_at).to be_nil
+ expect(ttl_policy.updated_at).to be_nil
+ end
+
+ context 'with existing policy' do
+ before do
+ group.dependency_proxy_image_ttl_policy.update!(ttl: 30, enabled: true)
+ end
+
+ it 'returns the policy if it already exists', :aggregate_failures do
+ expect(ttl_policy.ttl).to eq(30)
+ expect(ttl_policy.enabled).to eq(true)
+ expect(ttl_policy.created_at).not_to be_nil
+ expect(ttl_policy.updated_at).not_to be_nil
+ end
+ end
+ end
end
diff --git a/spec/models/hooks/web_hook_spec.rb b/spec/models/hooks/web_hook_spec.rb
index c68ad3bf0c4..59f4533a6c1 100644
--- a/spec/models/hooks/web_hook_spec.rb
+++ b/spec/models/hooks/web_hook_spec.rb
@@ -10,7 +10,11 @@ RSpec.describe WebHook do
let(:hook) { build(:project_hook, project: project) }
around do |example|
- freeze_time { example.run }
+ if example.metadata[:skip_freeze_time]
+ example.run
+ else
+ freeze_time { example.run }
+ end
end
describe 'associations' do
@@ -326,10 +330,28 @@ RSpec.describe WebHook do
expect { hook.backoff! }.to change(hook, :backoff_count).by(1)
end
- it 'does not let the backoff count exceed the maximum failure count' do
- hook.backoff_count = described_class::MAX_FAILURES
+ context 'when we have backed off MAX_FAILURES times' do
+ before do
+ stub_const("#{described_class}::MAX_FAILURES", 5)
+ 5.times { hook.backoff! }
+ end
+
+ it 'does not let the backoff count exceed the maximum failure count' do
+ expect { hook.backoff! }.not_to change(hook, :backoff_count)
+ end
+
+ it 'does not change disabled_until', :skip_freeze_time do
+ travel_to(hook.disabled_until - 1.minute) do
+ expect { hook.backoff! }.not_to change(hook, :disabled_until)
+ end
+ end
- expect { hook.backoff! }.not_to change(hook, :backoff_count)
+ it 'changes disabled_until when it has elapsed', :skip_freeze_time do
+ travel_to(hook.disabled_until + 1.minute) do
+ expect { hook.backoff! }.to change { hook.disabled_until }
+ expect(hook.backoff_count).to eq(described_class::MAX_FAILURES)
+ end
+ end
end
include_examples 'is tolerant of invalid records' do
diff --git a/spec/models/instance_configuration_spec.rb b/spec/models/instance_configuration_spec.rb
index 9544f0fe6ec..551e6e7572c 100644
--- a/spec/models/instance_configuration_spec.rb
+++ b/spec/models/instance_configuration_spec.rb
@@ -76,24 +76,46 @@ RSpec.describe InstanceConfiguration do
end
end
- describe '#gitlab_ci' do
- let(:gitlab_ci) { subject.settings[:gitlab_ci] }
+ describe '#size_limits' do
+ before do
+ Gitlab::CurrentSettings.current_application_settings.update!(
+ max_attachment_size: 10,
+ receive_max_input_size: 20,
+ max_import_size: 30,
+ diff_max_patch_bytes: 409600,
+ max_artifacts_size: 50,
+ max_pages_size: 60,
+ snippet_size_limit: 70
+ )
+ end
- it 'returns Settings.gitalb_ci' do
- gitlab_ci.delete(:artifacts_max_size)
+ it 'returns size limits from application settings' do
+ size_limits = subject.settings[:size_limits]
- expect(gitlab_ci).to eq(Settings.gitlab_ci.symbolize_keys)
+ expect(size_limits[:max_attachment_size]).to eq(10.megabytes)
+ expect(size_limits[:receive_max_input_size]).to eq(20.megabytes)
+ expect(size_limits[:max_import_size]).to eq(30.megabytes)
+ expect(size_limits[:diff_max_patch_bytes]).to eq(400.kilobytes)
+ expect(size_limits[:max_artifacts_size]).to eq(50.megabytes)
+ expect(size_limits[:max_pages_size]).to eq(60.megabytes)
+ expect(size_limits[:snippet_size_limit]).to eq(70.bytes)
end
- it 'returns the key artifacts_max_size' do
- expect(gitlab_ci.keys).to include(:artifacts_max_size)
+ it 'returns nil if receive_max_input_size not set' do
+ Gitlab::CurrentSettings.current_application_settings.update!(receive_max_input_size: nil)
+
+ size_limits = subject.settings[:size_limits]
+
+ expect(size_limits[:receive_max_input_size]).to be_nil
end
- it 'returns the key artifacts_max_size with values' do
- stub_application_setting(max_artifacts_size: 200)
+ it 'returns nil if set to 0 (unlimited)' do
+ Gitlab::CurrentSettings.current_application_settings.update!(max_import_size: 0, max_pages_size: 0)
+
+ size_limits = subject.settings[:size_limits]
- expect(gitlab_ci[:artifacts_max_size][:default]).to eq(100.megabytes)
- expect(gitlab_ci[:artifacts_max_size][:value]).to eq(200.megabytes)
+ expect(size_limits[:max_import_size]).to be_nil
+ expect(size_limits[:max_pages_size]).to be_nil
end
end
diff --git a/spec/models/integration_spec.rb b/spec/models/integration_spec.rb
index f5f6a425fdd..8a06f7fac99 100644
--- a/spec/models/integration_spec.rb
+++ b/spec/models/integration_spec.rb
@@ -825,4 +825,20 @@ RSpec.describe Integration do
.to include(*described_class::PROJECT_SPECIFIC_INTEGRATION_NAMES)
end
end
+
+ describe '#password_fields' do
+ it 'returns all fields with type `password`' do
+ allow(subject).to receive(:fields).and_return([
+ { name: 'password', type: 'password' },
+ { name: 'secret', type: 'password' },
+ { name: 'public', type: 'text' }
+ ])
+
+ expect(subject.password_fields).to match_array(%w[password secret])
+ end
+
+ it 'returns an empty array if no password fields exist' do
+ expect(subject.password_fields).to eq([])
+ end
+ end
end
diff --git a/spec/models/integrations/datadog_spec.rb b/spec/models/integrations/datadog_spec.rb
index 7049e64c2ce..9c3ff7aa35b 100644
--- a/spec/models/integrations/datadog_spec.rb
+++ b/spec/models/integrations/datadog_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe Integrations::Datadog do
let(:active) { true }
let(:dd_site) { 'datadoghq.com' }
- let(:default_url) { 'https://webhooks-http-intake.logs.datadoghq.com/api/v2/webhook' }
+ let(:default_url) { 'https://webhook-intake.datadoghq.com/api/v2/webhook' }
let(:api_url) { '' }
let(:api_key) { SecureRandom.hex(32) }
let(:dd_env) { 'ci' }
@@ -66,7 +66,7 @@ RSpec.describe Integrations::Datadog do
context 'with custom api_url' do
let(:dd_site) { '' }
- let(:api_url) { 'https://webhooks-http-intake.logs.datad0g.com/api/v2/webhook' }
+ let(:api_url) { 'https://webhook-intake.datad0g.com/api/v2/webhook' }
it { is_expected.not_to validate_presence_of(:datadog_site) }
it { is_expected.to validate_presence_of(:api_url) }
@@ -108,7 +108,7 @@ RSpec.describe Integrations::Datadog do
end
context 'with custom URL' do
- let(:api_url) { 'https://webhooks-http-intake.logs.datad0g.com/api/v2/webhook' }
+ let(:api_url) { 'https://webhook-intake.datad0g.com/api/v2/webhook' }
it { is_expected.to eq(api_url + "?dd-api-key=#{api_key}&env=#{dd_env}&service=#{dd_service}") }
diff --git a/spec/models/integrations/pipelines_email_spec.rb b/spec/models/integrations/pipelines_email_spec.rb
index 761049f25fe..afd9d71ebc4 100644
--- a/spec/models/integrations/pipelines_email_spec.rb
+++ b/spec/models/integrations/pipelines_email_spec.rb
@@ -48,7 +48,7 @@ RSpec.describe Integrations::PipelinesEmail, :mailer do
end
it 'sends email' do
- emails = receivers.map { |r| double(notification_email: r) }
+ emails = receivers.map { |r| double(notification_email_or_default: r) }
should_only_email(*emails, kind: :bcc)
end
diff --git a/spec/models/integrations/prometheus_spec.rb b/spec/models/integrations/prometheus_spec.rb
index f6f242bf58e..76e20f20a00 100644
--- a/spec/models/integrations/prometheus_spec.rb
+++ b/spec/models/integrations/prometheus_spec.rb
@@ -516,7 +516,7 @@ RSpec.describe Integrations::Prometheus, :use_clean_rails_memory_store_caching,
name: 'google_iap_audience_client_id',
title: 'Google IAP Audience Client ID',
placeholder: s_('PrometheusService|IAP_CLIENT_ID.apps.googleusercontent.com'),
- help: s_('PrometheusService|PrometheusService|The ID of the IAP-secured resource.'),
+ help: s_('PrometheusService|The ID of the IAP-secured resource.'),
autocomplete: 'off',
required: false
},
diff --git a/spec/models/integrations/zentao_spec.rb b/spec/models/integrations/zentao_spec.rb
new file mode 100644
index 00000000000..a1503ecc092
--- /dev/null
+++ b/spec/models/integrations/zentao_spec.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Integrations::Zentao do
+ let(:url) { 'https://jihudemo.zentao.net' }
+ let(:api_url) { 'https://jihudemo.zentao.net' }
+ let(:api_token) { 'ZENTAO_TOKEN' }
+ let(:zentao_product_xid) { '3' }
+ let(:zentao_integration) { create(:zentao_integration) }
+
+ describe '#create' do
+ let(:project) { create(:project, :repository) }
+ let(:params) do
+ {
+ project: project,
+ url: url,
+ api_url: api_url,
+ api_token: api_token,
+ zentao_product_xid: zentao_product_xid
+ }
+ end
+
+ it 'stores data in data_fields correctly' do
+ tracker_data = described_class.create!(params).zentao_tracker_data
+
+ expect(tracker_data.url).to eq(url)
+ expect(tracker_data.api_url).to eq(api_url)
+ expect(tracker_data.api_token).to eq(api_token)
+ expect(tracker_data.zentao_product_xid).to eq(zentao_product_xid)
+ end
+ end
+
+ describe '#fields' do
+ it 'returns custom fields' do
+ expect(zentao_integration.fields.pluck(:name)).to eq(%w[url api_url api_token zentao_product_xid])
+ end
+ end
+
+ describe '#test' do
+ let(:test_response) { { success: true } }
+
+ before do
+ allow_next_instance_of(Gitlab::Zentao::Client) do |client|
+ allow(client).to receive(:ping).and_return(test_response)
+ end
+ end
+
+ it 'gets response from Gitlab::Zentao::Client#ping' do
+ expect(zentao_integration.test).to eq(test_response)
+ end
+ end
+end
diff --git a/spec/models/integrations/zentao_tracker_data_spec.rb b/spec/models/integrations/zentao_tracker_data_spec.rb
new file mode 100644
index 00000000000..b078c57830b
--- /dev/null
+++ b/spec/models/integrations/zentao_tracker_data_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Integrations::ZentaoTrackerData do
+ describe 'factory available' do
+ let(:zentao_tracker_data) { create(:zentao_tracker_data) }
+
+ it { expect(zentao_tracker_data.valid?).to eq true }
+ end
+
+ describe 'associations' do
+ it { is_expected.to belong_to(:integration) }
+ end
+
+ describe 'encrypted attributes' do
+ subject { described_class.encrypted_attributes.keys }
+
+ it { is_expected.to contain_exactly(:url, :api_url, :zentao_product_xid, :api_token) }
+ end
+end
diff --git a/spec/models/internal_id_spec.rb b/spec/models/internal_id_spec.rb
index 6aba91d9471..51b27151ba2 100644
--- a/spec/models/internal_id_spec.rb
+++ b/spec/models/internal_id_spec.rb
@@ -39,266 +39,199 @@ RSpec.describe InternalId do
end
end
- shared_examples_for 'a monotonically increasing id generator' do
- describe '.generate_next' do
- subject { described_class.generate_next(id_subject, scope, usage, init) }
+ describe '.generate_next' do
+ subject { described_class.generate_next(id_subject, scope, usage, init) }
- context 'in the absence of a record' do
- it 'creates a record if not yet present' do
- expect { subject }.to change { described_class.count }.from(0).to(1)
- end
-
- it 'stores record attributes' do
- subject
-
- described_class.first.tap do |record|
- expect(record.project).to eq(project)
- expect(record.usage).to eq(usage.to_s)
- end
- end
-
- context 'with existing issues' do
- before do
- create_list(:issue, 2, project: project)
- described_class.delete_all
- end
-
- it 'calculates last_value values automatically' do
- expect(subject).to eq(project.issues.size + 1)
- end
- end
- end
-
- it 'generates a strictly monotone, gapless sequence' do
- seq = Array.new(10).map do
- described_class.generate_next(issue, scope, usage, init)
- end
- normalized = seq.map { |i| i - seq.min }
-
- expect(normalized).to eq((0..seq.size - 1).to_a)
+ context 'in the absence of a record' do
+ it 'creates a record if not yet present' do
+ expect { subject }.to change { described_class.count }.from(0).to(1)
end
- context 'there are no instances to pass in' do
- let(:id_subject) { Issue }
+ it 'stores record attributes' do
+ subject
- it 'accepts classes instead' do
- expect(subject).to eq(1)
+ described_class.first.tap do |record|
+ expect(record.project).to eq(project)
+ expect(record.usage).to eq(usage.to_s)
end
end
- context 'when executed outside of transaction' do
- it 'increments counter with in_transaction: "false"' do
- allow(ActiveRecord::Base.connection).to receive(:transaction_open?) { false } # rubocop: disable Database/MultipleDatabases
-
- expect(InternalId.internal_id_transactions_total).to receive(:increment)
- .with(operation: :generate, usage: 'issues', in_transaction: 'false').and_call_original
-
- subject
+ context 'with existing issues' do
+ before do
+ create_list(:issue, 2, project: project)
+ described_class.delete_all
end
- end
- context 'when executed within transaction' do
- it 'increments counter with in_transaction: "true"' do
- expect(InternalId.internal_id_transactions_total).to receive(:increment)
- .with(operation: :generate, usage: 'issues', in_transaction: 'true').and_call_original
-
- InternalId.transaction { subject }
+ it 'calculates last_value values automatically' do
+ expect(subject).to eq(project.issues.size + 1)
end
end
end
- describe '.reset' do
- subject { described_class.reset(issue, scope, usage, value) }
-
- context 'in the absence of a record' do
- let(:value) { 2 }
-
- it 'does not revert back the value' do
- expect { subject }.not_to change { described_class.count }
- expect(subject).to be_falsey
- end
+ it 'generates a strictly monotone, gapless sequence' do
+ seq = Array.new(10).map do
+ described_class.generate_next(issue, scope, usage, init)
end
+ normalized = seq.map { |i| i - seq.min }
- context 'when valid iid is used to reset' do
- let!(:value) { generate_next }
-
- context 'and iid is a latest one' do
- it 'does rewind and next generated value is the same' do
- expect(subject).to be_truthy
- expect(generate_next).to eq(value)
- end
- end
+ expect(normalized).to eq((0..seq.size - 1).to_a)
+ end
- context 'and iid is not a latest one' do
- it 'does not rewind' do
- generate_next
+ context 'there are no instances to pass in' do
+ let(:id_subject) { Issue }
- expect(subject).to be_falsey
- expect(generate_next).to be > value
- end
- end
-
- def generate_next
- described_class.generate_next(issue, scope, usage, init)
- end
+ it 'accepts classes instead' do
+ expect(subject).to eq(1)
end
+ end
- context 'when executed outside of transaction' do
- let(:value) { 2 }
-
- it 'increments counter with in_transaction: "false"' do
- allow(ActiveRecord::Base.connection).to receive(:transaction_open?) { false } # rubocop: disable Database/MultipleDatabases
+ context 'when executed outside of transaction' do
+ it 'increments counter with in_transaction: "false"' do
+ allow(ActiveRecord::Base.connection).to receive(:transaction_open?) { false } # rubocop: disable Database/MultipleDatabases
- expect(InternalId.internal_id_transactions_total).to receive(:increment)
- .with(operation: :reset, usage: 'issues', in_transaction: 'false').and_call_original
+ expect(InternalId.internal_id_transactions_total).to receive(:increment)
+ .with(operation: :generate, usage: 'issues', in_transaction: 'false').and_call_original
- subject
- end
+ subject
end
+ end
- context 'when executed within transaction' do
- let(:value) { 2 }
-
- it 'increments counter with in_transaction: "true"' do
- expect(InternalId.internal_id_transactions_total).to receive(:increment)
- .with(operation: :reset, usage: 'issues', in_transaction: 'true').and_call_original
+ context 'when executed within transaction' do
+ it 'increments counter with in_transaction: "true"' do
+ expect(InternalId.internal_id_transactions_total).to receive(:increment)
+ .with(operation: :generate, usage: 'issues', in_transaction: 'true').and_call_original
- InternalId.transaction { subject }
- end
+ InternalId.transaction { subject }
end
end
+ end
- describe '.track_greatest' do
- let(:value) { 9001 }
-
- subject { described_class.track_greatest(id_subject, scope, usage, value, init) }
-
- context 'in the absence of a record' do
- it 'creates a record if not yet present' do
- expect { subject }.to change { described_class.count }.from(0).to(1)
- end
- end
+ describe '.reset' do
+ subject { described_class.reset(issue, scope, usage, value) }
- it 'stores record attributes' do
- subject
+ context 'in the absence of a record' do
+ let(:value) { 2 }
- described_class.first.tap do |record|
- expect(record.project).to eq(project)
- expect(record.usage).to eq(usage.to_s)
- expect(record.last_value).to eq(value)
- end
+ it 'does not revert back the value' do
+ expect { subject }.not_to change { described_class.count }
+ expect(subject).to be_falsey
end
+ end
- context 'with existing issues' do
- before do
- create(:issue, project: project)
- described_class.delete_all
- end
+ context 'when valid iid is used to reset' do
+ let!(:value) { generate_next }
- it 'still returns the last value to that of the given value' do
- expect(subject).to eq(value)
+ context 'and iid is a latest one' do
+ it 'does rewind and next generated value is the same' do
+ expect(subject).to be_truthy
+ expect(generate_next).to eq(value)
end
end
- context 'when value is less than the current last_value' do
- it 'returns the current last_value' do
- described_class.create!(**scope, usage: usage, last_value: 10_001)
+ context 'and iid is not a latest one' do
+ it 'does not rewind' do
+ generate_next
- expect(subject).to eq 10_001
+ expect(subject).to be_falsey
+ expect(generate_next).to be > value
end
end
- context 'there are no instances to pass in' do
- let(:id_subject) { Issue }
-
- it 'accepts classes instead' do
- expect(subject).to eq(value)
- end
+ def generate_next
+ described_class.generate_next(issue, scope, usage, init)
end
+ end
- context 'when executed outside of transaction' do
- it 'increments counter with in_transaction: "false"' do
- allow(ActiveRecord::Base.connection).to receive(:transaction_open?) { false } # rubocop: disable Database/MultipleDatabases
-
- expect(InternalId.internal_id_transactions_total).to receive(:increment)
- .with(operation: :track_greatest, usage: 'issues', in_transaction: 'false').and_call_original
+ context 'when executed outside of transaction' do
+ let(:value) { 2 }
- subject
- end
- end
+ it 'increments counter with in_transaction: "false"' do
+ allow(ActiveRecord::Base.connection).to receive(:transaction_open?) { false } # rubocop: disable Database/MultipleDatabases
- context 'when executed within transaction' do
- it 'increments counter with in_transaction: "true"' do
- expect(InternalId.internal_id_transactions_total).to receive(:increment)
- .with(operation: :track_greatest, usage: 'issues', in_transaction: 'true').and_call_original
+ expect(InternalId.internal_id_transactions_total).to receive(:increment)
+ .with(operation: :reset, usage: 'issues', in_transaction: 'false').and_call_original
- InternalId.transaction { subject }
- end
+ subject
end
end
- end
- context 'when the feature flag is disabled' do
- stub_feature_flags(generate_iids_without_explicit_locking: false)
+ context 'when executed within transaction' do
+ let(:value) { 2 }
- it_behaves_like 'a monotonically increasing id generator'
- end
-
- context 'when the feature flag is enabled' do
- stub_feature_flags(generate_iids_without_explicit_locking: true)
+ it 'increments counter with in_transaction: "true"' do
+ expect(InternalId.internal_id_transactions_total).to receive(:increment)
+ .with(operation: :reset, usage: 'issues', in_transaction: 'true').and_call_original
- it_behaves_like 'a monotonically increasing id generator'
+ InternalId.transaction { subject }
+ end
+ end
end
- describe '#increment_and_save!' do
- let(:id) { create(:internal_id) }
-
- subject { id.increment_and_save! }
+ describe '.track_greatest' do
+ let(:value) { 9001 }
- it 'returns incremented iid' do
- value = id.last_value
+ subject { described_class.track_greatest(id_subject, scope, usage, value, init) }
- expect(subject).to eq(value + 1)
+ context 'in the absence of a record' do
+ it 'creates a record if not yet present' do
+ expect { subject }.to change { described_class.count }.from(0).to(1)
+ end
end
- it 'saves the record' do
+ it 'stores record attributes' do
subject
- expect(id.changed?).to be_falsey
+ described_class.first.tap do |record|
+ expect(record.project).to eq(project)
+ expect(record.usage).to eq(usage.to_s)
+ expect(record.last_value).to eq(value)
+ end
end
- context 'with last_value=nil' do
- let(:id) { build(:internal_id, last_value: nil) }
+ context 'with existing issues' do
+ before do
+ create(:issue, project: project)
+ described_class.delete_all
+ end
- it 'returns 1' do
- expect(subject).to eq(1)
+ it 'still returns the last value to that of the given value' do
+ expect(subject).to eq(value)
end
end
- end
-
- describe '#track_greatest_and_save!' do
- let(:id) { create(:internal_id) }
- let(:new_last_value) { 9001 }
- subject { id.track_greatest_and_save!(new_last_value) }
+ context 'when value is less than the current last_value' do
+ it 'returns the current last_value' do
+ described_class.create!(**scope, usage: usage, last_value: 10_001)
- it 'returns new last value' do
- expect(subject).to eq new_last_value
+ expect(subject).to eq 10_001
+ end
end
- it 'saves the record' do
- subject
+ context 'there are no instances to pass in' do
+ let(:id_subject) { Issue }
- expect(id.changed?).to be_falsey
+ it 'accepts classes instead' do
+ expect(subject).to eq(value)
+ end
end
- context 'when new last value is lower than the max' do
- it 'does not update the last value' do
- id.update!(last_value: 10_001)
+ context 'when executed outside of transaction' do
+ it 'increments counter with in_transaction: "false"' do
+ allow(ActiveRecord::Base.connection).to receive(:transaction_open?) { false } # rubocop: disable Database/MultipleDatabases
+
+ expect(InternalId.internal_id_transactions_total).to receive(:increment)
+ .with(operation: :track_greatest, usage: 'issues', in_transaction: 'false').and_call_original
subject
+ end
+ end
+
+ context 'when executed within transaction' do
+ it 'increments counter with in_transaction: "true"' do
+ expect(InternalId.internal_id_transactions_total).to receive(:increment)
+ .with(operation: :track_greatest, usage: 'issues', in_transaction: 'true').and_call_original
- expect(id.reload.last_value).to eq 10_001
+ InternalId.transaction { subject }
end
end
end
diff --git a/spec/models/issue/metrics_spec.rb b/spec/models/issue/metrics_spec.rb
index 49c891c20da..2fdf1f09f80 100644
--- a/spec/models/issue/metrics_spec.rb
+++ b/spec/models/issue/metrics_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe Issue::Metrics do
end
end
- describe "when recording the default set of issue metrics on issue save" do
+ context "when recording the default set of issue metrics on issue save" do
context "milestones" do
it "records the first time an issue is associated with a milestone" do
time = Time.current
@@ -80,20 +80,5 @@ RSpec.describe Issue::Metrics do
expect(metrics.first_added_to_board_at).to be_like_time(time)
end
end
-
- describe "#record!" do
- it "does not cause an N+1 query" do
- label = create(:label)
- subject.update!(label_ids: [label.id])
-
- control_count = ActiveRecord::QueryRecorder.new { Issue::Metrics.find_by(issue: subject).record! }.count
-
- additional_labels = create_list(:label, 4)
-
- subject.update!(label_ids: additional_labels.map(&:id))
-
- expect { Issue::Metrics.find_by(issue: subject).record! }.not_to exceed_query_limit(control_count)
- end
- end
end
end
diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb
index 116bda7a18b..1747972e8ae 100644
--- a/spec/models/issue_spec.rb
+++ b/spec/models/issue_spec.rb
@@ -102,7 +102,7 @@ RSpec.describe Issue do
end
it 'records current metrics' do
- expect_any_instance_of(Issue::Metrics).to receive(:record!)
+ expect(Issue::Metrics).to receive(:record!)
create(:issue, project: reusable_project)
end
@@ -111,7 +111,6 @@ RSpec.describe Issue do
before do
subject.metrics.delete
subject.reload
- subject.metrics # make sure metrics association is cached (currently nil)
end
it 'creates the metrics record' do
@@ -166,8 +165,8 @@ RSpec.describe Issue do
expect(described_class.simple_sorts.keys).to include(
*%w(created_asc created_at_asc created_date created_desc created_at_desc
closest_future_date closest_future_date_asc due_date due_date_asc due_date_desc
- id_asc id_desc relative_position relative_position_asc
- updated_desc updated_asc updated_at_asc updated_at_desc))
+ id_asc id_desc relative_position relative_position_asc updated_desc updated_asc
+ updated_at_asc updated_at_desc title_asc title_desc))
end
end
@@ -204,6 +203,25 @@ RSpec.describe Issue do
end
end
+ describe '.order_title' do
+ let_it_be(:issue1) { create(:issue, title: 'foo') }
+ let_it_be(:issue2) { create(:issue, title: 'bar') }
+ let_it_be(:issue3) { create(:issue, title: 'baz') }
+ let_it_be(:issue4) { create(:issue, title: 'Baz 2') }
+
+ context 'sorting ascending' do
+ subject { described_class.order_title_asc }
+
+ it { is_expected.to eq([issue2, issue3, issue4, issue1]) }
+ end
+
+ context 'sorting descending' do
+ subject { described_class.order_title_desc }
+
+ it { is_expected.to eq([issue1, issue4, issue3, issue2]) }
+ end
+ end
+
describe '#order_by_position_and_priority' do
let(:project) { reusable_project }
let(:p1) { create(:label, title: 'P1', project: project, priority: 1) }
@@ -1177,18 +1195,33 @@ RSpec.describe Issue do
it 'refreshes the number of open issues of the project' do
project = subject.project
- expect { subject.destroy! }
- .to change { project.open_issues_count }.from(1).to(0)
+ expect do
+ subject.destroy!
+
+ BatchLoader::Executor.clear_current
+ end.to change { project.open_issues_count }.from(1).to(0)
end
end
describe '.public_only' do
- it 'only returns public issues' do
- public_issue = create(:issue, project: reusable_project)
- create(:issue, project: reusable_project, confidential: true)
+ let_it_be(:banned_user) { create(:user, :banned) }
+ let_it_be(:public_issue) { create(:issue, project: reusable_project) }
+ let_it_be(:confidential_issue) { create(:issue, project: reusable_project, confidential: true) }
+ let_it_be(:hidden_issue) { create(:issue, project: reusable_project, author: banned_user) }
+ it 'only returns public issues' do
expect(described_class.public_only).to eq([public_issue])
end
+
+ context 'when feature flag is disabled' do
+ before do
+ stub_feature_flags(ban_user_feature_flag: false)
+ end
+
+ it 'returns public and hidden issues' do
+ expect(described_class.public_only).to eq([public_issue, hidden_issue])
+ end
+ end
end
describe '.confidential_only' do
@@ -1402,19 +1435,19 @@ RSpec.describe Issue do
describe 'scheduling rebalancing' do
before do
allow_next_instance_of(RelativePositioning::Mover) do |mover|
- allow(mover).to receive(:move) { raise ActiveRecord::QueryCanceled }
+ allow(mover).to receive(:move) { raise RelativePositioning::NoSpaceLeft }
end
end
shared_examples 'schedules issues rebalancing' do
let(:issue) { build_stubbed(:issue, relative_position: 100, project: project) }
- it 'schedules rebalancing if we time-out when moving' do
+ it 'schedules rebalancing if there is no space left' do
lhs = build_stubbed(:issue, relative_position: 99, project: project)
to_move = build(:issue, project: project)
expect(IssueRebalancingWorker).to receive(:perform_async).with(nil, project_id, namespace_id)
- expect { to_move.move_between(lhs, issue) }.to raise_error(ActiveRecord::QueryCanceled)
+ expect { to_move.move_between(lhs, issue) }.to raise_error(RelativePositioning::NoSpaceLeft)
end
end
diff --git a/spec/models/loose_foreign_keys/deleted_record_spec.rb b/spec/models/loose_foreign_keys/deleted_record_spec.rb
new file mode 100644
index 00000000000..db2f8b4d2d3
--- /dev/null
+++ b/spec/models/loose_foreign_keys/deleted_record_spec.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe LooseForeignKeys::DeletedRecord do
+ let_it_be(:deleted_record_1) { described_class.create!(created_at: 1.day.ago, deleted_table_name: 'projects', deleted_table_primary_key_value: 5) }
+ let_it_be(:deleted_record_2) { described_class.create!(created_at: 3.days.ago, deleted_table_name: 'projects', deleted_table_primary_key_value: 1) }
+ let_it_be(:deleted_record_3) { described_class.create!(created_at: 5.days.ago, deleted_table_name: 'projects', deleted_table_primary_key_value: 3) }
+ let_it_be(:deleted_record_4) { described_class.create!(created_at: 10.days.ago, deleted_table_name: 'projects', deleted_table_primary_key_value: 1) } # duplicate
+
+ # skip created_at because it gets truncated after insert
+ def map_attributes(records)
+ records.pluck(:deleted_table_name, :deleted_table_primary_key_value)
+ end
+
+ describe 'partitioning strategy' do
+ it 'has retain_non_empty_partitions option' do
+ expect(described_class.partitioning_strategy.retain_non_empty_partitions).to eq(true)
+ end
+ end
+
+ describe '.load_batch' do
+ it 'loads records and orders them by creation date' do
+ records = described_class.load_batch(4)
+
+ expect(map_attributes(records)).to eq([['projects', 1], ['projects', 3], ['projects', 1], ['projects', 5]])
+ end
+
+ it 'supports configurable batch size' do
+ records = described_class.load_batch(2)
+
+ expect(map_attributes(records)).to eq([['projects', 1], ['projects', 3]])
+ end
+ end
+
+ describe '.delete_records' do
+ it 'deletes exactly one record' do
+ described_class.delete_records([deleted_record_2])
+
+ expect(described_class.count).to eq(3)
+ expect(described_class.find_by(created_at: deleted_record_2.created_at)).to eq(nil)
+ end
+
+ it 'deletes two records' do
+ described_class.delete_records([deleted_record_2, deleted_record_4])
+
+ expect(described_class.count).to eq(2)
+ end
+
+ it 'deletes all records' do
+ described_class.delete_records([deleted_record_1, deleted_record_2, deleted_record_3, deleted_record_4])
+
+ expect(described_class.count).to eq(0)
+ end
+ end
+end
diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb
index 067b3c25645..3f7f69ff34e 100644
--- a/spec/models/member_spec.rb
+++ b/spec/models/member_spec.rb
@@ -645,6 +645,16 @@ RSpec.describe Member do
expect(user.authorized_projects.reload).to include(project)
end
+
+ it 'does not accept the invite if saving a new user fails' do
+ invalid_user = User.new(first_name: '', last_name: '')
+
+ member.accept_invite! invalid_user
+
+ expect(member.invite_accepted_at).to be_nil
+ expect(member.invite_token).not_to be_nil
+ expect_any_instance_of(Member).not_to receive(:after_accept_invite)
+ end
end
describe "#decline_invite!" do
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index 4a8a2909891..06ca88644b7 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -151,43 +151,6 @@ RSpec.describe MergeRequest, factory_default: :keep do
end
end
- describe '#squash_in_progress?' do
- let(:repo_path) do
- Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- subject.source_project.repository.path
- end
- end
-
- let(:squash_path) { File.join(repo_path, "gitlab-worktree", "squash-#{subject.id}") }
-
- before do
- system(*%W(#{Gitlab.config.git.bin_path} -C #{repo_path} worktree add --detach #{squash_path} master))
- end
-
- it 'returns true when there is a current squash directory' do
- expect(subject.squash_in_progress?).to be_truthy
- end
-
- it 'returns false when there is no squash directory' do
- FileUtils.rm_rf(squash_path)
-
- expect(subject.squash_in_progress?).to be_falsey
- end
-
- it 'returns false when the squash directory has expired' do
- time = 20.minutes.ago.to_time
- File.utime(time, time, squash_path)
-
- expect(subject.squash_in_progress?).to be_falsey
- end
-
- it 'returns false when the source project has been removed' do
- allow(subject).to receive(:source_project).and_return(nil)
-
- expect(subject.squash_in_progress?).to be_falsey
- end
- end
-
describe '#squash?' do
let(:merge_request) { build(:merge_request, squash: squash) }
diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb
index f14b9c57eb1..bc592acc80f 100644
--- a/spec/models/milestone_spec.rb
+++ b/spec/models/milestone_spec.rb
@@ -538,15 +538,6 @@ RSpec.describe Milestone do
it { is_expected.to match('gitlab-org/gitlab-ce%123') }
it { is_expected.to match('gitlab-org/gitlab-ce%"my-milestone"') }
-
- context 'when milestone_reference_pattern feature flag is false' do
- before do
- stub_feature_flags(milestone_reference_pattern: false)
- end
-
- it { is_expected.to match('gitlab-org/gitlab-ce%123') }
- it { is_expected.to match('gitlab-org/gitlab-ce%"my-milestone"') }
- end
end
describe '.link_reference_pattern' do
diff --git a/spec/models/namespace_setting_spec.rb b/spec/models/namespace_setting_spec.rb
index e8ed6f1a460..c1cc8fc3e88 100644
--- a/spec/models/namespace_setting_spec.rb
+++ b/spec/models/namespace_setting_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe NamespaceSetting, type: :model do
+ it_behaves_like 'sanitizable', :namespace_settings, %i[default_branch_name]
+
# Relationships
#
describe "Associations" do
@@ -41,14 +43,6 @@ RSpec.describe NamespaceSetting, type: :model do
it_behaves_like "doesn't return an error"
end
-
- context "when it contains javascript tags" do
- it "gets sanitized properly" do
- namespace_settings.update!(default_branch_name: "hello<script>alert(1)</script>")
-
- expect(namespace_settings.default_branch_name).to eq('hello')
- end
- end
end
describe '#allow_mfa_for_group' do
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index e2700378f5f..51a26d82daa 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -36,27 +36,34 @@ RSpec.describe Namespace do
it { is_expected.to validate_numericality_of(:max_artifacts_size).only_integer.is_greater_than(0) }
context 'validating the parent of a namespace' do
- context 'when the namespace has no parent' do
- it 'allows a namespace to have no parent associated with it' do
- namespace = build(:namespace)
-
- expect(namespace).to be_valid
- end
+ using RSpec::Parameterized::TableSyntax
+
+ where(:parent_type, :child_type, :error) do
+ nil | 'User' | nil
+ nil | 'Group' | nil
+ nil | 'Project' | 'must be set for a project namespace'
+ 'Project' | 'User' | 'project namespace cannot be the parent of another namespace'
+ 'Project' | 'Group' | 'project namespace cannot be the parent of another namespace'
+ 'Project' | 'Project' | 'project namespace cannot be the parent of another namespace'
+ 'Group' | 'User' | 'cannot not be used for user namespace'
+ 'Group' | 'Group' | nil
+ 'Group' | 'Project' | nil
+ 'User' | 'User' | 'cannot not be used for user namespace'
+ 'User' | 'Group' | 'user namespace cannot be the parent of another namespace'
+ 'User' | 'Project' | nil
end
- context 'when the namespace has a parent' do
- it 'does not allow a namespace to have a group as its parent' do
- namespace = build(:namespace, parent: build(:group))
-
- expect(namespace).not_to be_valid
- expect(namespace.errors[:parent_id].first).to eq('a user namespace cannot have a parent')
- end
-
- it 'does not allow a namespace to have another namespace as its parent' do
- namespace = build(:namespace, parent: build(:namespace))
-
- expect(namespace).not_to be_valid
- expect(namespace.errors[:parent_id].first).to eq('a user namespace cannot have a parent')
+ with_them do
+ it 'validates namespace parent' do
+ parent = build(:namespace, type: parent_type) if parent_type
+ namespace = build(:namespace, type: child_type, parent: parent)
+
+ if error
+ expect(namespace).not_to be_valid
+ expect(namespace.errors[:parent_id].first).to eq(error)
+ else
+ expect(namespace).to be_valid
+ end
end
end
@@ -157,6 +164,65 @@ RSpec.describe Namespace do
end
end
+ describe 'handling STI', :aggregate_failures do
+ let(:namespace_type) { nil }
+ let(:parent) { nil }
+ let(:namespace) { Namespace.find(create(:namespace, type: namespace_type, parent: parent).id) }
+
+ context 'creating a Group' do
+ let(:namespace_type) { 'Group' }
+
+ it 'is valid' do
+ expect(namespace).to be_a(Group)
+ expect(namespace.kind).to eq('group')
+ expect(namespace.group?).to be_truthy
+ end
+ end
+
+ context 'creating a ProjectNamespace' do
+ let(:namespace_type) { 'Project' }
+ let(:parent) { create(:group) }
+
+ it 'is valid' do
+ expect(Namespace.find(namespace.id)).to be_a(Namespaces::ProjectNamespace)
+ expect(namespace.kind).to eq('project')
+ expect(namespace.project?).to be_truthy
+ end
+ end
+
+ context 'creating a UserNamespace' do
+ let(:namespace_type) { 'User' }
+
+ it 'is valid' do
+ # TODO: We create a normal Namespace until
+ # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68894 is ready
+ expect(Namespace.find(namespace.id)).to be_a(Namespace)
+ expect(namespace.kind).to eq('user')
+ expect(namespace.user?).to be_truthy
+ end
+ end
+
+ context 'creating a default Namespace' do
+ let(:namespace_type) { nil }
+
+ it 'is valid' do
+ expect(Namespace.find(namespace.id)).to be_a(Namespace)
+ expect(namespace.kind).to eq('user')
+ expect(namespace.user?).to be_truthy
+ end
+ end
+
+ context 'creating an unknown Namespace type' do
+ let(:namespace_type) { 'One' }
+
+ it 'defaults to a Namespace' do
+ expect(Namespace.find(namespace.id)).to be_a(Namespace)
+ expect(namespace.kind).to eq('user')
+ expect(namespace.user?).to be_truthy
+ end
+ end
+ end
+
describe 'scopes', :aggregate_failures do
let_it_be(:namespace1) { create(:group, name: 'Namespace 1', path: 'namespace-1') }
let_it_be(:namespace2) { create(:group, name: 'Namespace 2', path: 'namespace-2') }
@@ -287,6 +353,12 @@ RSpec.describe Namespace do
end
end
+ describe '#owner_required?' do
+ specify { expect(build(:project_namespace).owner_required?).to be_falsey }
+ specify { expect(build(:group).owner_required?).to be_falsey }
+ specify { expect(build(:namespace).owner_required?).to be_truthy }
+ end
+
describe '#visibility_level_field' do
it { expect(namespace.visibility_level_field).to eq(:visibility_level) }
end
@@ -1377,6 +1449,13 @@ RSpec.describe Namespace do
expect { root_group.root_ancestor }.not_to exceed_query_limit(0)
end
+ it 'returns root_ancestor for nested group with a single query' do
+ nested_group = create(:group, parent: root_group)
+ nested_group.reload
+
+ expect { nested_group.root_ancestor }.not_to exceed_query_limit(1)
+ end
+
it 'returns the top most ancestor' do
nested_group = create(:group, parent: root_group)
deep_nested_group = create(:group, parent: nested_group)
diff --git a/spec/models/namespaces/project_namespace_spec.rb b/spec/models/namespaces/project_namespace_spec.rb
new file mode 100644
index 00000000000..f38e8aa85d0
--- /dev/null
+++ b/spec/models/namespaces/project_namespace_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Namespaces::ProjectNamespace, type: :model do
+ describe 'relationships' do
+ it { is_expected.to have_one(:project).with_foreign_key(:project_namespace_id).inverse_of(:project_namespace) }
+ end
+
+ describe 'validations' do
+ it { is_expected.not_to validate_presence_of :owner }
+ end
+
+ context 'when deleting project namespace' do
+ # using delete rather than destroy due to `delete` skipping AR hooks/callbacks
+ # so it's ensured to work at the DB level. Uses ON DELETE CASCADE on foreign key
+ let_it_be(:project) { create(:project) }
+ let_it_be(:project_namespace) { create(:project_namespace, project: project) }
+
+ it 'also deletes the associated project' do
+ project_namespace.delete
+
+ expect { project_namespace.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ expect { project.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+ end
+end
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index 0afdae2fc93..5e3773513f1 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -500,15 +500,15 @@ RSpec.describe Note do
let_it_be(:ext_issue) { create(:issue, project: ext_proj) }
shared_examples "checks references" do
- it "returns true" do
+ it "returns false" do
expect(note.system_note_with_references_visible_for?(ext_issue.author)).to be_falsy
end
- it "returns false" do
+ it "returns true" do
expect(note.system_note_with_references_visible_for?(private_user)).to be_truthy
end
- it "returns false if user visible reference count set" do
+ it "returns true if user visible reference count set" do
note.user_visible_reference_count = 1
note.total_reference_count = 1
@@ -516,7 +516,15 @@ RSpec.describe Note do
expect(note.system_note_with_references_visible_for?(ext_issue.author)).to be_truthy
end
- it "returns true if ref count is 0" do
+ it "returns false if user visible reference count set but does not match total reference count" do
+ note.user_visible_reference_count = 1
+ note.total_reference_count = 2
+
+ expect(note).not_to receive(:reference_mentionables)
+ expect(note.system_note_with_references_visible_for?(ext_issue.author)).to be_falsy
+ end
+
+ it "returns false if ref count is 0" do
note.user_visible_reference_count = 0
expect(note).not_to receive(:reference_mentionables)
@@ -562,13 +570,35 @@ RSpec.describe Note do
end
it_behaves_like "checks references"
+ end
- it "returns true if user visible reference count set and there is a private reference" do
- note.user_visible_reference_count = 1
- note.total_reference_count = 2
+ context "when there is a private issue and user reference" do
+ let_it_be(:ext_issue2) { create(:issue, project: ext_proj) }
- expect(note).not_to receive(:reference_mentionables)
- expect(note.system_note_with_references_visible_for?(ext_issue.author)).to be_falsy
+ let(:note) do
+ create :note,
+ noteable: ext_issue2, project: ext_proj,
+ note: "mentioned in #{private_issue.to_reference(ext_proj)} and pinged user #{private_user.to_reference}",
+ system: true
+ end
+
+ it_behaves_like "checks references"
+ end
+
+ context "when there is a publicly visible user reference" do
+ let(:note) do
+ create :note,
+ noteable: ext_issue, project: ext_proj,
+ note: "mentioned in #{ext_proj.owner.to_reference}",
+ system: true
+ end
+
+ it "returns true for other users" do
+ expect(note.system_note_with_references_visible_for?(ext_issue.author)).to be_truthy
+ end
+
+ it "returns true for anonymous users" do
+ expect(note.system_note_with_references_visible_for?(nil)).to be_truthy
end
end
end
@@ -1543,7 +1573,15 @@ RSpec.describe Note do
let(:note) { build(:note) }
it 'returns cache key and author cache key by default' do
- expect(note.post_processed_cache_key).to eq("#{note.cache_key}:#{note.author.cache_key}")
+ expect(note.post_processed_cache_key).to eq("#{note.cache_key}:#{note.author.cache_key}:#{note.project.team.human_max_access(note.author_id)}")
+ end
+
+ context 'when note has no author' do
+ let(:note) { build(:note, author: nil) }
+
+ it 'returns cache key only' do
+ expect(note.post_processed_cache_key).to eq("#{note.cache_key}:")
+ end
end
context 'when note has redacted_note_html' do
@@ -1554,7 +1592,7 @@ RSpec.describe Note do
end
it 'returns cache key with redacted_note_html sha' do
- expect(note.post_processed_cache_key).to eq("#{note.cache_key}:#{note.author.cache_key}:#{Digest::SHA1.hexdigest(redacted_note_html)}")
+ expect(note.post_processed_cache_key).to eq("#{note.cache_key}:#{note.author.cache_key}:#{note.project.team.human_max_access(note.author_id)}:#{Digest::SHA1.hexdigest(redacted_note_html)}")
end
end
end
diff --git a/spec/models/operations/feature_flag_scope_spec.rb b/spec/models/operations/feature_flag_scope_spec.rb
deleted file mode 100644
index dc83789fade..00000000000
--- a/spec/models/operations/feature_flag_scope_spec.rb
+++ /dev/null
@@ -1,391 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Operations::FeatureFlagScope do
- describe 'associations' do
- it { is_expected.to belong_to(:feature_flag) }
- end
-
- describe 'validations' do
- context 'when duplicate environment scope is going to be created' do
- let!(:existing_feature_flag_scope) do
- create(:operations_feature_flag_scope)
- end
-
- let(:new_feature_flag_scope) do
- build(:operations_feature_flag_scope,
- feature_flag: existing_feature_flag_scope.feature_flag,
- environment_scope: existing_feature_flag_scope.environment_scope)
- end
-
- it 'validates uniqueness of environment scope' do
- new_feature_flag_scope.save
-
- expect(new_feature_flag_scope.errors[:environment_scope])
- .to include("(#{existing_feature_flag_scope.environment_scope})" \
- " has already been taken")
- end
- end
-
- context 'when environment scope of a default scope is updated' do
- let!(:feature_flag) { create(:operations_feature_flag, :legacy_flag) }
- let!(:scope_default) { feature_flag.default_scope }
-
- it 'keeps default scope intact' do
- scope_default.update(environment_scope: 'review/*')
-
- expect(scope_default.errors[:environment_scope])
- .to include("cannot be changed from default scope")
- end
- end
-
- context 'when a default scope is destroyed' do
- let!(:feature_flag) { create(:operations_feature_flag, :legacy_flag) }
- let!(:scope_default) { feature_flag.default_scope }
-
- it 'prevents from destroying the default scope' do
- expect { scope_default.destroy! }.to raise_error(ActiveRecord::ReadOnlyRecord)
- end
- end
-
- describe 'strategy validations' do
- it 'handles null strategies which can occur while adding the column during migration' do
- scope = create(:operations_feature_flag_scope, active: true)
- allow(scope).to receive(:strategies).and_return(nil)
-
- scope.active = false
- scope.save
-
- expect(scope.errors[:strategies]).to be_empty
- end
-
- it 'validates multiple strategies' do
- feature_flag = create(:operations_feature_flag)
- scope = described_class.create(feature_flag: feature_flag,
- environment_scope: 'production', active: true,
- strategies: [{ name: "default", parameters: {} },
- { name: "invalid", parameters: {} }])
-
- expect(scope.errors[:strategies]).not_to be_empty
- end
-
- where(:invalid_value) do
- [{}, 600, "bad", [{ name: 'default', parameters: {} }, 300]]
- end
- with_them do
- it 'must be an array of strategy hashes' do
- scope = create(:operations_feature_flag_scope)
-
- scope.strategies = invalid_value
- scope.save
-
- expect(scope.errors[:strategies]).to eq(['must be an array of strategy hashes'])
- end
- end
-
- describe 'name' do
- using RSpec::Parameterized::TableSyntax
-
- where(:name, :params, :expected) do
- 'default' | {} | []
- 'gradualRolloutUserId' | { groupId: 'mygroup', percentage: '50' } | []
- 'userWithId' | { userIds: 'sam' } | []
- 5 | nil | ['strategy name is invalid']
- nil | nil | ['strategy name is invalid']
- "nothing" | nil | ['strategy name is invalid']
- "" | nil | ['strategy name is invalid']
- 40.0 | nil | ['strategy name is invalid']
- {} | nil | ['strategy name is invalid']
- [] | nil | ['strategy name is invalid']
- end
- with_them do
- it 'must be one of "default", "gradualRolloutUserId", or "userWithId"' do
- feature_flag = create(:operations_feature_flag)
- scope = described_class.create(feature_flag: feature_flag,
- environment_scope: 'production', active: true,
- strategies: [{ name: name, parameters: params }])
-
- expect(scope.errors[:strategies]).to eq(expected)
- end
- end
- end
-
- describe 'parameters' do
- context 'when the strategy name is gradualRolloutUserId' do
- it 'must have parameters' do
- feature_flag = create(:operations_feature_flag)
- scope = described_class.create(feature_flag: feature_flag,
- environment_scope: 'production', active: true,
- strategies: [{ name: 'gradualRolloutUserId' }])
-
- expect(scope.errors[:strategies]).to eq(['parameters are invalid'])
- end
-
- where(:invalid_parameters) do
- [nil, {}, { percentage: '40', groupId: 'mygroup', userIds: '4' }, { percentage: '40' },
- { percentage: '40', groupId: 'mygroup', extra: nil }, { groupId: 'mygroup' }]
- end
- with_them do
- it 'must have valid parameters for the strategy' do
- feature_flag = create(:operations_feature_flag)
- scope = described_class.create(feature_flag: feature_flag,
- environment_scope: 'production', active: true,
- strategies: [{ name: 'gradualRolloutUserId',
- parameters: invalid_parameters }])
-
- expect(scope.errors[:strategies]).to eq(['parameters are invalid'])
- end
- end
-
- it 'allows the parameters in any order' do
- feature_flag = create(:operations_feature_flag)
- scope = described_class.create(feature_flag: feature_flag,
- environment_scope: 'production', active: true,
- strategies: [{ name: 'gradualRolloutUserId',
- parameters: { percentage: '10', groupId: 'mygroup' } }])
-
- expect(scope.errors[:strategies]).to be_empty
- end
-
- describe 'percentage' do
- where(:invalid_value) do
- [50, 40.0, { key: "value" }, "garbage", "00", "01", "101", "-1", "-10", "0100",
- "1000", "10.0", "5%", "25%", "100hi", "e100", "30m", " ", "\r\n", "\n", "\t",
- "\n10", "20\n", "\n100", "100\n", "\n ", nil]
- end
- with_them do
- it 'must be a string value between 0 and 100 inclusive and without a percentage sign' do
- feature_flag = create(:operations_feature_flag)
- scope = described_class.create(feature_flag: feature_flag,
- environment_scope: 'production', active: true,
- strategies: [{ name: 'gradualRolloutUserId',
- parameters: { groupId: 'mygroup', percentage: invalid_value } }])
-
- expect(scope.errors[:strategies]).to eq(['percentage must be a string between 0 and 100 inclusive'])
- end
- end
-
- where(:valid_value) do
- %w[0 1 10 38 100 93]
- end
- with_them do
- it 'must be a string value between 0 and 100 inclusive and without a percentage sign' do
- feature_flag = create(:operations_feature_flag)
- scope = described_class.create(feature_flag: feature_flag,
- environment_scope: 'production', active: true,
- strategies: [{ name: 'gradualRolloutUserId',
- parameters: { groupId: 'mygroup', percentage: valid_value } }])
-
- expect(scope.errors[:strategies]).to eq([])
- end
- end
- end
-
- describe 'groupId' do
- where(:invalid_value) do
- [nil, 4, 50.0, {}, 'spaces bad', 'bad$', '%bad', '<bad', 'bad>', '!bad',
- '.bad', 'Bad', 'bad1', "", " ", "b" * 33, "ba_d", "ba\nd"]
- end
- with_them do
- it 'must be a string value of up to 32 lowercase characters' do
- feature_flag = create(:operations_feature_flag)
- scope = described_class.create(feature_flag: feature_flag,
- environment_scope: 'production', active: true,
- strategies: [{ name: 'gradualRolloutUserId',
- parameters: { groupId: invalid_value, percentage: '40' } }])
-
- expect(scope.errors[:strategies]).to eq(['groupId parameter is invalid'])
- end
- end
-
- where(:valid_value) do
- ["somegroup", "anothergroup", "okay", "g", "a" * 32]
- end
- with_them do
- it 'must be a string value of up to 32 lowercase characters' do
- feature_flag = create(:operations_feature_flag)
- scope = described_class.create(feature_flag: feature_flag,
- environment_scope: 'production', active: true,
- strategies: [{ name: 'gradualRolloutUserId',
- parameters: { groupId: valid_value, percentage: '40' } }])
-
- expect(scope.errors[:strategies]).to eq([])
- end
- end
- end
- end
-
- context 'when the strategy name is userWithId' do
- it 'must have parameters' do
- feature_flag = create(:operations_feature_flag)
- scope = described_class.create(feature_flag: feature_flag,
- environment_scope: 'production', active: true,
- strategies: [{ name: 'userWithId' }])
-
- expect(scope.errors[:strategies]).to eq(['parameters are invalid'])
- end
-
- where(:invalid_parameters) do
- [nil, { userIds: 'sam', percentage: '40' }, { userIds: 'sam', some: 'param' }, { percentage: '40' }, {}]
- end
- with_them do
- it 'must have valid parameters for the strategy' do
- feature_flag = create(:operations_feature_flag)
- scope = described_class.create(feature_flag: feature_flag,
- environment_scope: 'production', active: true,
- strategies: [{ name: 'userWithId', parameters: invalid_parameters }])
-
- expect(scope.errors[:strategies]).to eq(['parameters are invalid'])
- end
- end
-
- describe 'userIds' do
- where(:valid_value) do
- ["", "sam", "1", "a", "uuid-of-some-kind", "sam,fred,tom,jane,joe,mike",
- "gitlab@example.com", "123,4", "UPPER,Case,charActeRS", "0",
- "$valid$email#2345#$%..{}+=-)?\\/@example.com", "spaces allowed",
- "a" * 256, "a,#{'b' * 256},ccc", "many spaces"]
- end
- with_them do
- it 'is valid with a string of comma separated values' do
- feature_flag = create(:operations_feature_flag)
- scope = described_class.create(feature_flag: feature_flag,
- environment_scope: 'production', active: true,
- strategies: [{ name: 'userWithId', parameters: { userIds: valid_value } }])
-
- expect(scope.errors[:strategies]).to be_empty
- end
- end
-
- where(:invalid_value) do
- [1, 2.5, {}, [], nil, "123\n456", "1,2,3,12\t3", "\n", "\n\r",
- "joe\r,sam", "1,2,2", "1,,2", "1,2,,,,", "b" * 257, "1, ,2", "tim, ,7", " ",
- " ", " ,1", "1, ", " leading,1", "1,trailing ", "1, both ,2"]
- end
- with_them do
- it 'is invalid' do
- feature_flag = create(:operations_feature_flag)
- scope = described_class.create(feature_flag: feature_flag,
- environment_scope: 'production', active: true,
- strategies: [{ name: 'userWithId', parameters: { userIds: invalid_value } }])
-
- expect(scope.errors[:strategies]).to include(
- 'userIds must be a string of unique comma separated values each 256 characters or less'
- )
- end
- end
- end
- end
-
- context 'when the strategy name is default' do
- it 'must have parameters' do
- feature_flag = create(:operations_feature_flag)
- scope = described_class.create(feature_flag: feature_flag,
- environment_scope: 'production', active: true,
- strategies: [{ name: 'default' }])
-
- expect(scope.errors[:strategies]).to eq(['parameters are invalid'])
- end
-
- where(:invalid_value) do
- [{ groupId: "hi", percentage: "7" }, "", "nothing", 7, nil, [], 2.5]
- end
- with_them do
- it 'must be empty' do
- feature_flag = create(:operations_feature_flag)
- scope = described_class.create(feature_flag: feature_flag,
- environment_scope: 'production', active: true,
- strategies: [{ name: 'default',
- parameters: invalid_value }])
-
- expect(scope.errors[:strategies]).to eq(['parameters are invalid'])
- end
- end
-
- it 'must be empty' do
- feature_flag = create(:operations_feature_flag)
- scope = described_class.create(feature_flag: feature_flag,
- environment_scope: 'production', active: true,
- strategies: [{ name: 'default',
- parameters: {} }])
-
- expect(scope.errors[:strategies]).to be_empty
- end
- end
- end
- end
- end
-
- describe '.enabled' do
- subject { described_class.enabled }
-
- let!(:feature_flag_scope) do
- create(:operations_feature_flag_scope, active: active)
- end
-
- context 'when scope is active' do
- let(:active) { true }
-
- it 'returns the scope' do
- is_expected.to include(feature_flag_scope)
- end
- end
-
- context 'when scope is inactive' do
- let(:active) { false }
-
- it 'returns an empty array' do
- is_expected.not_to include(feature_flag_scope)
- end
- end
- end
-
- describe '.disabled' do
- subject { described_class.disabled }
-
- let!(:feature_flag_scope) do
- create(:operations_feature_flag_scope, active: active)
- end
-
- context 'when scope is active' do
- let(:active) { true }
-
- it 'returns an empty array' do
- is_expected.not_to include(feature_flag_scope)
- end
- end
-
- context 'when scope is inactive' do
- let(:active) { false }
-
- it 'returns the scope' do
- is_expected.to include(feature_flag_scope)
- end
- end
- end
-
- describe '.for_unleash_client' do
- it 'returns scopes for the specified project' do
- project1 = create(:project)
- project2 = create(:project)
- expected_feature_flag = create(:operations_feature_flag, project: project1)
- create(:operations_feature_flag, project: project2)
-
- scopes = described_class.for_unleash_client(project1, 'sandbox').to_a
-
- expect(scopes).to contain_exactly(*expected_feature_flag.scopes)
- end
-
- it 'returns a scope that matches exactly over a match with a wild card' do
- project = create(:project)
- feature_flag = create(:operations_feature_flag, project: project)
- create(:operations_feature_flag_scope, feature_flag: feature_flag, environment_scope: 'production*')
- expected_scope = create(:operations_feature_flag_scope, feature_flag: feature_flag, environment_scope: 'production')
-
- scopes = described_class.for_unleash_client(project, 'production').to_a
-
- expect(scopes).to contain_exactly(expected_scope)
- end
- end
-end
diff --git a/spec/models/operations/feature_flag_spec.rb b/spec/models/operations/feature_flag_spec.rb
index cb9da2aea34..d689632e2b4 100644
--- a/spec/models/operations/feature_flag_spec.rb
+++ b/spec/models/operations/feature_flag_spec.rb
@@ -49,28 +49,7 @@ RSpec.describe Operations::FeatureFlag do
it { is_expected.to validate_presence_of(:project) }
it { is_expected.to validate_presence_of(:name) }
it { is_expected.to validate_uniqueness_of(:name).scoped_to(:project_id) }
- it { is_expected.to define_enum_for(:version).with_values(legacy_flag: 1, new_version_flag: 2) }
-
- context 'a version 1 feature flag' do
- it 'is valid if associated with Operations::FeatureFlagScope models' do
- project = create(:project)
- feature_flag = described_class.create!({ name: 'test', project: project, version: 1,
- scopes_attributes: [{ environment_scope: '*', active: false }] })
-
- expect(feature_flag).to be_valid
- end
-
- it 'is invalid if associated with Operations::FeatureFlags::Strategy models' do
- project = create(:project)
- feature_flag = described_class.new({ name: 'test', project: project, version: 1,
- strategies_attributes: [{ name: 'default', parameters: {} }] })
-
- expect(feature_flag.valid?).to eq(false)
- expect(feature_flag.errors.messages).to eq({
- version_associations: ["version 1 feature flags may not have strategies"]
- })
- end
- end
+ it { is_expected.to define_enum_for(:version).with_values(new_version_flag: 2) }
context 'a version 2 feature flag' do
it 'is invalid if associated with Operations::FeatureFlagScope models' do
@@ -102,64 +81,9 @@ RSpec.describe Operations::FeatureFlag do
end
end
- describe 'feature flag version' do
- it 'defaults to 1 if unspecified' do
- project = create(:project)
-
- feature_flag = described_class.create!(name: 'my_flag', project: project, active: true)
-
- expect(feature_flag).to be_valid
- expect(feature_flag.version_before_type_cast).to eq(1)
- end
- end
-
- describe 'Scope creation' do
- subject { described_class.new(**params) }
-
- let(:project) { create(:project) }
-
- let(:params) do
- { name: 'test', project: project, scopes_attributes: scopes_attributes }
- end
-
- let(:scopes_attributes) do
- [{ environment_scope: '*', active: false },
- { environment_scope: 'review/*', active: true }]
- end
-
- it { is_expected.to be_valid }
-
- context 'when the first scope is not wildcard' do
- let(:scopes_attributes) do
- [{ environment_scope: 'review/*', active: true },
- { environment_scope: '*', active: false }]
- end
-
- it { is_expected.not_to be_valid }
- end
- end
-
describe 'the default scope' do
let_it_be(:project) { create(:project) }
- context 'with a version 1 feature flag' do
- it 'creates a default scope' do
- feature_flag = described_class.create!({ name: 'test', project: project, scopes_attributes: [], version: 1 })
-
- expect(feature_flag.scopes.count).to eq(1)
- expect(feature_flag.scopes.first.environment_scope).to eq('*')
- end
-
- it 'allows specifying the default scope in the parameters' do
- feature_flag = described_class.create!({ name: 'test', project: project,
- scopes_attributes: [{ environment_scope: '*', active: false },
- { environment_scope: 'review/*', active: true }], version: 1 })
-
- expect(feature_flag.scopes.count).to eq(2)
- expect(feature_flag.scopes.first.environment_scope).to eq('*')
- end
- end
-
context 'with a version 2 feature flag' do
it 'does not create a default scope' do
feature_flag = described_class.create!({ name: 'test', project: project, scopes_attributes: [], version: 2 })
@@ -180,16 +104,6 @@ RSpec.describe Operations::FeatureFlag do
end
end
- context 'when the feature flag is active and all scopes are inactive' do
- let!(:feature_flag) { create(:operations_feature_flag, :legacy_flag, active: true) }
-
- it 'returns the flag' do
- feature_flag.default_scope.update!(active: false)
-
- is_expected.to eq([feature_flag])
- end
- end
-
context 'when the feature flag is inactive' do
let!(:feature_flag) { create(:operations_feature_flag, active: false) }
@@ -197,16 +111,6 @@ RSpec.describe Operations::FeatureFlag do
is_expected.to be_empty
end
end
-
- context 'when the feature flag is inactive and all scopes are active' do
- let!(:feature_flag) { create(:operations_feature_flag, :legacy_flag, active: false) }
-
- it 'does not return the flag' do
- feature_flag.default_scope.update!(active: true)
-
- is_expected.to be_empty
- end
- end
end
describe '.disabled' do
@@ -220,16 +124,6 @@ RSpec.describe Operations::FeatureFlag do
end
end
- context 'when the feature flag is active and all scopes are inactive' do
- let!(:feature_flag) { create(:operations_feature_flag, :legacy_flag, active: true) }
-
- it 'does not return the flag' do
- feature_flag.default_scope.update!(active: false)
-
- is_expected.to be_empty
- end
- end
-
context 'when the feature flag is inactive' do
let!(:feature_flag) { create(:operations_feature_flag, active: false) }
@@ -237,16 +131,6 @@ RSpec.describe Operations::FeatureFlag do
is_expected.to eq([feature_flag])
end
end
-
- context 'when the feature flag is inactive and all scopes are active' do
- let!(:feature_flag) { create(:operations_feature_flag, :legacy_flag, active: false) }
-
- it 'returns the flag' do
- feature_flag.default_scope.update!(active: true)
-
- is_expected.to eq([feature_flag])
- end
- end
end
describe '.for_unleash_client' do
diff --git a/spec/models/packages/package_file_spec.rb b/spec/models/packages/package_file_spec.rb
index 90910fcb7ce..450656e3e9c 100644
--- a/spec/models/packages/package_file_spec.rb
+++ b/spec/models/packages/package_file_spec.rb
@@ -2,6 +2,8 @@
require 'spec_helper'
RSpec.describe Packages::PackageFile, type: :model do
+ using RSpec::Parameterized::TableSyntax
+
let_it_be(:project) { create(:project) }
let_it_be(:package_file1) { create(:package_file, :xml, file_name: 'FooBar') }
let_it_be(:package_file2) { create(:package_file, :xml, file_name: 'ThisIsATest') }
@@ -139,6 +141,71 @@ RSpec.describe Packages::PackageFile, type: :model do
end
end
+ describe '.most_recent!' do
+ it { expect(described_class.most_recent!).to eq(debian_package.package_files.last) }
+ end
+
+ describe '.most_recent_for' do
+ let_it_be(:package1) { create(:npm_package) }
+ let_it_be(:package2) { create(:npm_package) }
+ let_it_be(:package3) { create(:npm_package) }
+ let_it_be(:package4) { create(:npm_package) }
+
+ let_it_be(:package_file2_2) { create(:package_file, :npm, package: package2) }
+
+ let_it_be(:package_file3_2) { create(:package_file, :npm, package: package3) }
+ let_it_be(:package_file3_3) { create(:package_file, :npm, package: package3) }
+
+ let_it_be(:package_file4_2) { create(:package_file, :npm, package: package2) }
+ let_it_be(:package_file4_3) { create(:package_file, :npm, package: package2) }
+ let_it_be(:package_file4_4) { create(:package_file, :npm, package: package2) }
+
+ let(:most_recent_package_file1) { package1.package_files.recent.first }
+ let(:most_recent_package_file2) { package2.package_files.recent.first }
+ let(:most_recent_package_file3) { package3.package_files.recent.first }
+ let(:most_recent_package_file4) { package4.package_files.recent.first }
+
+ subject { described_class.most_recent_for(packages) }
+
+ where(
+ package_input1: [1, nil],
+ package_input2: [2, nil],
+ package_input3: [3, nil],
+ package_input4: [4, nil]
+ )
+
+ with_them do
+ let(:compact_inputs) { [package_input1, package_input2, package_input3, package_input4].compact }
+ let(:packages) do
+ ::Packages::Package.id_in(
+ compact_inputs.map { |pkg_number| public_send("package#{pkg_number}") }
+ .map(&:id)
+ )
+ end
+
+ let(:expected_package_files) { compact_inputs.map { |pkg_number| public_send("most_recent_package_file#{pkg_number}") } }
+
+ it { is_expected.to contain_exactly(*expected_package_files) }
+ end
+
+ context 'extra join and extra where' do
+ let_it_be(:helm_package) { create(:helm_package, without_package_files: true) }
+ let_it_be(:helm_package_file1) { create(:helm_package_file, channel: 'alpha') }
+ let_it_be(:helm_package_file2) { create(:helm_package_file, channel: 'alpha', package: helm_package) }
+ let_it_be(:helm_package_file3) { create(:helm_package_file, channel: 'beta', package: helm_package) }
+ let_it_be(:helm_package_file4) { create(:helm_package_file, channel: 'beta', package: helm_package) }
+
+ let(:extra_join) { :helm_file_metadatum }
+ let(:extra_where) { { packages_helm_file_metadata: { channel: 'alpha' } } }
+
+ subject { described_class.most_recent_for(Packages::Package.id_in(helm_package.id), extra_join: extra_join, extra_where: extra_where) }
+
+ it 'returns the most recent package for the selected channel' do
+ expect(subject).to contain_exactly(helm_package_file2)
+ end
+ end
+ end
+
describe '#update_file_store callback' do
let_it_be(:package_file) { build(:package_file, :nuget, size: nil) }
diff --git a/spec/models/packages/package_spec.rb b/spec/models/packages/package_spec.rb
index 4d4d4ad4fa9..99e5769fc1f 100644
--- a/spec/models/packages/package_spec.rb
+++ b/spec/models/packages/package_spec.rb
@@ -1165,4 +1165,47 @@ RSpec.describe Packages::Package, type: :model do
it_behaves_like 'not enqueuing a sync worker job'
end
end
+
+ describe '#create_build_infos!' do
+ let_it_be(:package) { create(:package) }
+ let_it_be(:pipeline) { create(:ci_pipeline) }
+
+ let(:build) { double(pipeline: pipeline) }
+
+ subject { package.create_build_infos!(build) }
+
+ context 'with a valid build' do
+ it 'creates a build info' do
+ expect { subject }.to change { ::Packages::BuildInfo.count }.by(1)
+
+ last_build = ::Packages::BuildInfo.last
+ expect(last_build.package).to eq(package)
+ expect(last_build.pipeline).to eq(pipeline)
+ end
+
+ context 'with an already existing build info' do
+ let_it_be(:build_info) { create(:packages_build_info, package: package, pipeline: pipeline) }
+
+ it 'does not create a build info' do
+ expect { subject }.not_to change { ::Packages::BuildInfo.count }
+ end
+ end
+ end
+
+ context 'with a nil build' do
+ let(:build) { nil }
+
+ it 'does not create a build info' do
+ expect { subject }.not_to change { ::Packages::BuildInfo.count }
+ end
+ end
+
+ context 'with a build without a pipeline' do
+ let(:build) { double(pipeline: nil) }
+
+ it 'does not create a build info' do
+ expect { subject }.not_to change { ::Packages::BuildInfo.count }
+ end
+ end
+ end
end
diff --git a/spec/models/preloaders/commit_status_preloader_spec.rb b/spec/models/preloaders/commit_status_preloader_spec.rb
new file mode 100644
index 00000000000..85ea784335c
--- /dev/null
+++ b/spec/models/preloaders/commit_status_preloader_spec.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Preloaders::CommitStatusPreloader do
+ let_it_be(:pipeline) { create(:ci_pipeline) }
+
+ let_it_be(:build1) { create(:ci_build, :tags, pipeline: pipeline) }
+ let_it_be(:build2) { create(:ci_build, :tags, pipeline: pipeline) }
+ let_it_be(:bridge1) { create(:ci_bridge, pipeline: pipeline) }
+ let_it_be(:bridge2) { create(:ci_bridge, pipeline: pipeline) }
+ let_it_be(:generic_commit_status1) { create(:generic_commit_status, pipeline: pipeline) }
+ let_it_be(:generic_commit_status2) { create(:generic_commit_status, pipeline: pipeline) }
+
+ describe '#execute' do
+ let(:relations) { %i[pipeline metadata tags job_artifacts_archive downstream_pipeline] }
+ let(:statuses) { CommitStatus.where(commit_id: pipeline.id).all }
+
+ subject(:execute) { described_class.new(statuses).execute(relations) }
+
+ it 'prevents N+1 for specified relations', :use_sql_query_cache do
+ execute
+
+ control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do
+ call_each_relation(statuses.sample(3))
+ end
+
+ expect do
+ call_each_relation(statuses)
+ end.to issue_same_number_of_queries_as(control_count)
+ end
+
+ private
+
+ def call_each_relation(statuses)
+ statuses.each do |status|
+ relations.each { |relation| status.public_send(relation) if status.respond_to?(relation) }
+ end
+ end
+ end
+end
diff --git a/spec/models/preloaders/merge_requests_preloader_spec.rb b/spec/models/preloaders/merge_requests_preloader_spec.rb
new file mode 100644
index 00000000000..7108de2e491
--- /dev/null
+++ b/spec/models/preloaders/merge_requests_preloader_spec.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Preloaders::MergeRequestsPreloader do
+ describe '#execute' do
+ let_it_be_with_refind(:merge_requests) { create_list(:merge_request, 3) }
+ let_it_be(:upvotes) { merge_requests.each { |m| create(:award_emoji, :upvote, awardable: m) } }
+
+ it 'does not make n+1 queries' do
+ described_class.new(merge_requests).execute
+
+ control = ActiveRecord::QueryRecorder.new(skip_cached: false) do
+ # expectations make sure the queries execute
+ merge_requests.each do |m|
+ expect(m.target_project.project_feature).not_to be_nil
+ expect(m.lazy_upvotes_count).to eq(1)
+ end
+ end
+
+ # 1 query for BatchLoader to load all upvotes at once
+ expect(control.count).to eq(1)
+ end
+
+ it 'runs extra queries without preloading' do
+ control = ActiveRecord::QueryRecorder.new(skip_cached: false) do
+ # expectations make sure the queries execute
+ merge_requests.each do |m|
+ expect(m.target_project.project_feature).not_to be_nil
+ expect(m.lazy_upvotes_count).to eq(1)
+ end
+ end
+
+ # 4 queries per merge request =
+ # 1 to load merge request
+ # 1 to load project
+ # 1 to load project_feature
+ # 1 to load upvotes count
+ expect(control.count).to eq(4 * merge_requests.size)
+ end
+ end
+end
diff --git a/spec/models/preloaders/user_max_access_level_in_groups_preloader_spec.rb b/spec/models/preloaders/user_max_access_level_in_groups_preloader_spec.rb
new file mode 100644
index 00000000000..8144e1ad233
--- /dev/null
+++ b/spec/models/preloaders/user_max_access_level_in_groups_preloader_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Preloaders::UserMaxAccessLevelInGroupsPreloader do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group1) { create(:group, :private).tap { |g| g.add_developer(user) } }
+ let_it_be(:group2) { create(:group, :private).tap { |g| g.add_developer(user) } }
+ let_it_be(:group3) { create(:group, :private) }
+
+ let(:max_query_regex) { /SELECT MAX\("members"\."access_level"\).+/ }
+ let(:groups) { [group1, group2, group3] }
+
+ shared_examples 'executes N max member permission queries to the DB' do
+ it 'executes the specified max membership queries' do
+ queries = ActiveRecord::QueryRecorder.new do
+ groups.each { |group| user.can?(:read_group, group) }
+ end
+
+ max_queries = queries.log.grep(max_query_regex)
+
+ expect(max_queries.count).to eq(expected_query_count)
+ end
+ end
+
+ context 'when the preloader is used', :request_store do
+ before do
+ described_class.new(groups, user).execute
+ end
+
+ it_behaves_like 'executes N max member permission queries to the DB' do
+ # Will query all groups where the user is not already a member
+ let(:expected_query_count) { 1 }
+ end
+
+ context 'when user has access but is not a direct member of the group' do
+ let(:groups) { [group1, group2, group3, create(:group, :private, parent: group1)] }
+
+ it_behaves_like 'executes N max member permission queries to the DB' do
+ # One query for group with no access and another one where the user is not a direct member
+ let(:expected_query_count) { 2 }
+ end
+ end
+ end
+
+ context 'when the preloader is not used', :request_store do
+ it_behaves_like 'executes N max member permission queries to the DB' do
+ let(:expected_query_count) { groups.count }
+ end
+ end
+end
diff --git a/spec/models/project_ci_cd_setting_spec.rb b/spec/models/project_ci_cd_setting_spec.rb
index caab182cda8..406485d8cc8 100644
--- a/spec/models/project_ci_cd_setting_spec.rb
+++ b/spec/models/project_ci_cd_setting_spec.rb
@@ -21,12 +21,6 @@ RSpec.describe ProjectCiCdSetting do
end
end
- describe '#job_token_scope_enabled' do
- it 'is false by default' do
- expect(described_class.new.job_token_scope_enabled).to be_falsey
- end
- end
-
describe '#default_git_depth' do
let(:default_value) { described_class::DEFAULT_GIT_DEPTH }
diff --git a/spec/models/project_feature_spec.rb b/spec/models/project_feature_spec.rb
index 5f720f8c4f8..75e43ed9a67 100644
--- a/spec/models/project_feature_spec.rb
+++ b/spec/models/project_feature_spec.rb
@@ -41,18 +41,15 @@ RSpec.describe ProjectFeature do
end
end
- context 'public features' do
- features = ProjectFeature::FEATURES - %i(pages)
+ it_behaves_like 'access level validation', ProjectFeature::FEATURES - %i(pages) do
+ let(:container_features) { project.project_feature }
+ end
- features.each do |feature|
- it "does not allow public access level for #{feature}" do
- project_feature = project.project_feature
- field = "#{feature}_access_level".to_sym
- project_feature.update_attribute(field, ProjectFeature::PUBLIC)
+ it 'allows public access level for :pages feature' do
+ project_feature = project.project_feature
+ project_feature.pages_access_level = ProjectFeature::PUBLIC
- expect(project_feature.valid?).to be_falsy, "#{field} failed"
- end
- end
+ expect(project_feature.valid?).to be_truthy
end
describe 'default pages access level' do
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index d8f3a63d221..3989ddc31e8 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -16,6 +16,7 @@ RSpec.describe Project, factory_default: :keep do
describe 'associations' do
it { is_expected.to belong_to(:group) }
it { is_expected.to belong_to(:namespace) }
+ it { is_expected.to belong_to(:project_namespace).class_name('Namespaces::ProjectNamespace').with_foreign_key('project_namespace_id').inverse_of(:project) }
it { is_expected.to belong_to(:creator).class_name('User') }
it { is_expected.to belong_to(:pool_repository) }
it { is_expected.to have_many(:users) }
@@ -137,6 +138,8 @@ RSpec.describe Project, factory_default: :keep do
it { is_expected.to have_many(:timelogs) }
it { is_expected.to have_many(:error_tracking_errors).class_name('ErrorTracking::Error') }
it { is_expected.to have_many(:error_tracking_client_keys).class_name('ErrorTracking::ClientKey') }
+ it { is_expected.to have_many(:pending_builds).class_name('Ci::PendingBuild') }
+ it { is_expected.to have_many(:ci_feature_usages).class_name('Projects::CiFeatureUsage') }
# GitLab Pages
it { is_expected.to have_many(:pages_domains) }
@@ -183,6 +186,20 @@ RSpec.describe Project, factory_default: :keep do
end
end
+ context 'when deleting project' do
+ # using delete rather than destroy due to `delete` skipping AR hooks/callbacks
+ # so it's ensured to work at the DB level. Uses AFTER DELETE trigger.
+ let_it_be(:project) { create(:project) }
+ let_it_be(:project_namespace) { create(:project_namespace, project: project) }
+
+ it 'also deletes the associated ProjectNamespace' do
+ project.delete
+
+ expect { project.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ expect { project_namespace.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+ end
+
context 'when creating a new project' do
let_it_be(:project) { create(:project) }
@@ -602,6 +619,12 @@ RSpec.describe Project, factory_default: :keep do
end
end
+ describe '#membership_locked?' do
+ it 'returns false' do
+ expect(build(:project)).not_to be_membership_locked
+ end
+ end
+
describe '#autoclose_referenced_issues' do
context 'when DB entry is nil' do
let(:project) { build(:project, autoclose_referenced_issues: nil) }
@@ -1051,12 +1074,12 @@ RSpec.describe Project, factory_default: :keep do
project.open_issues_count(user)
end
- it 'invokes the count service with no current_user' do
- count_service = instance_double(Projects::OpenIssuesCountService)
- expect(Projects::OpenIssuesCountService).to receive(:new).with(project, nil).and_return(count_service)
- expect(count_service).to receive(:count)
+ it 'invokes the batch count service with no current_user' do
+ count_service = instance_double(Projects::BatchOpenIssuesCountService)
+ expect(Projects::BatchOpenIssuesCountService).to receive(:new).with([project]).and_return(count_service)
+ expect(count_service).to receive(:refresh_cache_and_retrieve_data).and_return({})
- project.open_issues_count
+ project.open_issues_count.to_s
end
end
@@ -1257,19 +1280,19 @@ RSpec.describe Project, factory_default: :keep do
end
it 'returns an active external wiki' do
- create(:service, project: project, type: 'ExternalWikiService', active: true)
+ create(:external_wiki_integration, project: project, active: true)
is_expected.to be_kind_of(Integrations::ExternalWiki)
end
it 'does not return an inactive external wiki' do
- create(:service, project: project, type: 'ExternalWikiService', active: false)
+ create(:external_wiki_integration, project: project, active: false)
is_expected.to eq(nil)
end
it 'sets Project#has_external_wiki when it is nil' do
- create(:service, project: project, type: 'ExternalWikiService', active: true)
+ create(:external_wiki_integration, project: project, active: true)
project.update_column(:has_external_wiki, nil)
expect { subject }.to change { project.has_external_wiki }.from(nil).to(true)
@@ -1279,36 +1302,40 @@ RSpec.describe Project, factory_default: :keep do
describe '#has_external_wiki' do
let_it_be(:project) { create(:project) }
- def subject
+ def has_external_wiki
project.reload.has_external_wiki
end
- specify { is_expected.to eq(false) }
+ specify { expect(has_external_wiki).to eq(false) }
- context 'when there is an active external wiki service' do
- let!(:service) do
- create(:service, project: project, type: 'ExternalWikiService', active: true)
+ context 'when there is an active external wiki integration' do
+ let(:active) { true }
+
+ let!(:integration) do
+ create(:external_wiki_integration, project: project, active: active)
end
- specify { is_expected.to eq(true) }
+ specify { expect(has_external_wiki).to eq(true) }
it 'becomes false if the external wiki service is destroyed' do
expect do
- Integration.find(service.id).delete
- end.to change { subject }.to(false)
+ Integration.find(integration.id).delete
+ end.to change { has_external_wiki }.to(false)
end
it 'becomes false if the external wiki service becomes inactive' do
expect do
- service.update_column(:active, false)
- end.to change { subject }.to(false)
+ integration.update_column(:active, false)
+ end.to change { has_external_wiki }.to(false)
end
- end
- it 'is false when external wiki service is not active' do
- create(:service, project: project, type: 'ExternalWikiService', active: false)
+ context 'when created as inactive' do
+ let(:active) { false }
- is_expected.to eq(false)
+ it 'is false' do
+ expect(has_external_wiki).to eq(false)
+ end
+ end
end
end
@@ -2536,7 +2563,7 @@ RSpec.describe Project, factory_default: :keep do
end
describe '#uses_default_ci_config?' do
- let(:project) { build(:project)}
+ let(:project) { build(:project) }
it 'has a custom ci config path' do
project.ci_config_path = 'something_custom'
@@ -2557,6 +2584,44 @@ RSpec.describe Project, factory_default: :keep do
end
end
+ describe '#uses_external_project_ci_config?' do
+ subject(:uses_external_project_ci_config) { project.uses_external_project_ci_config? }
+
+ let(:project) { build(:project) }
+
+ context 'when ci_config_path is configured with external project' do
+ before do
+ project.ci_config_path = '.gitlab-ci.yml@hello/world'
+ end
+
+ it { is_expected.to eq(true) }
+ end
+
+ context 'when ci_config_path is nil' do
+ before do
+ project.ci_config_path = nil
+ end
+
+ it { is_expected.to eq(false) }
+ end
+
+ context 'when ci_config_path is configured with a file in the project' do
+ before do
+ project.ci_config_path = 'hello/world/gitlab-ci.yml'
+ end
+
+ it { is_expected.to eq(false) }
+ end
+
+ context 'when ci_config_path is configured with remote file' do
+ before do
+ project.ci_config_path = 'https://example.org/file.yml'
+ end
+
+ it { is_expected.to eq(false) }
+ end
+ end
+
describe '#latest_successful_build_for_ref' do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:pipeline) { create_pipeline(project) }
@@ -3260,6 +3325,16 @@ RSpec.describe Project, factory_default: :keep do
end
end
+ describe '#after_change_head_branch_does_not_exist' do
+ let_it_be(:project) { create(:project) }
+
+ it 'adds an error to container if branch does not exist' do
+ expect do
+ project.after_change_head_branch_does_not_exist('unexisted-branch')
+ end.to change { project.errors.size }.from(0).to(1)
+ end
+ end
+
describe '#lfs_objects_for_repository_types' do
let(:project) { create(:project) }
@@ -4496,44 +4571,6 @@ RSpec.describe Project, factory_default: :keep do
end
end
- describe '#legacy_remove_pages' do
- let(:project) { create(:project).tap { |project| project.mark_pages_as_deployed } }
- let(:pages_metadatum) { project.pages_metadatum }
- let(:namespace) { project.namespace }
- let(:pages_path) { project.pages_path }
-
- around do |example|
- FileUtils.mkdir_p(pages_path)
- begin
- example.run
- ensure
- FileUtils.rm_rf(pages_path)
- end
- end
-
- it 'removes the pages directory and marks the project as not having pages deployed' do
- expect_any_instance_of(Gitlab::PagesTransfer).to receive(:rename_project).and_return(true)
- expect(PagesWorker).to receive(:perform_in).with(5.minutes, :remove, namespace.full_path, anything)
-
- expect { project.legacy_remove_pages }.to change { pages_metadatum.reload.deployed }.from(true).to(false)
- end
-
- it 'does nothing if updates on legacy storage are disabled' do
- allow(Settings.pages.local_store).to receive(:enabled).and_return(false)
-
- expect(Gitlab::PagesTransfer).not_to receive(:new)
- expect(PagesWorker).not_to receive(:perform_in)
-
- project.legacy_remove_pages
- end
-
- it 'is run when the project is destroyed' do
- expect(project).to receive(:legacy_remove_pages).and_call_original
-
- expect { project.destroy! }.not_to raise_error
- end
- end
-
describe '#remove_export' do
let(:project) { create(:project, :with_export) }
@@ -7037,6 +7074,15 @@ RSpec.describe Project, factory_default: :keep do
end
end
+ describe '#ci_config_external_project' do
+ subject(:ci_config_external_project) { project.ci_config_external_project }
+
+ let(:other_project) { create(:project) }
+ let(:project) { build(:project, ci_config_path: ".gitlab-ci.yml@#{other_project.full_path}") }
+
+ it { is_expected.to eq(other_project) }
+ end
+
describe '#enabled_group_deploy_keys' do
let_it_be(:project) { create(:project) }
@@ -7131,15 +7177,96 @@ RSpec.describe Project, factory_default: :keep do
end
describe 'topics' do
- let_it_be(:project) { create(:project, topic_list: 'topic1, topic2, topic3') }
+ let_it_be(:project) { create(:project, name: 'topic-project', topic_list: 'topic1, topic2, topic3') }
it 'topic_list returns correct string array' do
- expect(project.topic_list).to match_array(%w[topic1 topic2 topic3])
+ expect(project.topic_list).to eq(%w[topic1 topic2 topic3])
+ end
+
+ it 'topics returns correct topic records' do
+ expect(project.topics.first.class.name).to eq('Projects::Topic')
+ expect(project.topics.map(&:name)).to eq(%w[topic1 topic2 topic3])
+ end
+
+ context 'topic_list=' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:topic_list, :expected_result) do
+ ['topicA', 'topicB'] | %w[topicA topicB] # rubocop:disable Style/WordArray, Lint/BinaryOperatorWithIdenticalOperands
+ ['topicB', 'topicA'] | %w[topicB topicA] # rubocop:disable Style/WordArray, Lint/BinaryOperatorWithIdenticalOperands
+ [' topicC ', ' topicD '] | %w[topicC topicD]
+ ['topicE', 'topicF', 'topicE'] | %w[topicE topicF] # rubocop:disable Style/WordArray
+ ['topicE ', 'topicF', ' topicE'] | %w[topicE topicF]
+ 'topicA, topicB' | %w[topicA topicB]
+ 'topicB, topicA' | %w[topicB topicA]
+ ' topicC , topicD ' | %w[topicC topicD]
+ 'topicE, topicF, topicE' | %w[topicE topicF]
+ 'topicE , topicF, topicE' | %w[topicE topicF]
+ end
+
+ with_them do
+ it 'set topics' do
+ project.topic_list = topic_list
+ project.save!
+
+ expect(project.topics.map(&:name)).to eq(expected_result)
+ end
+ end
+
+ it 'set topics if only the order is changed' do
+ project.topic_list = 'topicA, topicB'
+ project.save!
+
+ expect(project.reload.topics.map(&:name)).to eq(%w[topicA topicB])
+
+ project.topic_list = 'topicB, topicA'
+ project.save!
+
+ expect(project.reload.topics.map(&:name)).to eq(%w[topicB topicA])
+ end
+
+ it 'does not persist topics before project is saved' do
+ project.topic_list = 'topicA, topicB'
+
+ expect(project.reload.topics.map(&:name)).to eq(%w[topic1 topic2 topic3])
+ end
+
+ it 'does not update topics if project is not valid' do
+ project.name = nil
+ project.topic_list = 'topicA, topicB'
+
+ expect(project.save).to be_falsy
+ expect(project.reload.topics.map(&:name)).to eq(%w[topic1 topic2 topic3])
+ end
end
- it 'topics returns correct tag records' do
- expect(project.topics.first.class.name).to eq('ActsAsTaggableOn::Tag')
- expect(project.topics.map(&:name)).to match_array(%w[topic1 topic2 topic3])
+ context 'during ExtractProjectTopicsIntoSeparateTable migration' do
+ before do
+ topic_a = ActsAsTaggableOn::Tag.find_or_create_by!(name: 'topicA')
+ topic_b = ActsAsTaggableOn::Tag.find_or_create_by!(name: 'topicB')
+
+ project.reload.topics_acts_as_taggable = [topic_a, topic_b]
+ project.save!
+ project.reload
+ end
+
+ it 'topic_list returns correct string array' do
+ expect(project.topic_list).to eq(%w[topicA topicB topic1 topic2 topic3])
+ end
+
+ it 'topics returns correct topic records' do
+ expect(project.topics.map(&:class)).to eq([ActsAsTaggableOn::Tag, ActsAsTaggableOn::Tag, Projects::Topic, Projects::Topic, Projects::Topic])
+ expect(project.topics.map(&:name)).to eq(%w[topicA topicB topic1 topic2 topic3])
+ end
+
+ it 'topic_list= sets new topics and removes old topics' do
+ project.topic_list = 'new-topic1, new-topic2'
+ project.save!
+ project.reload
+
+ expect(project.topics.map(&:class)).to eq([Projects::Topic, Projects::Topic])
+ expect(project.topics.map(&:name)).to eq(%w[new-topic1 new-topic2])
+ end
end
end
diff --git a/spec/models/projects/project_topic_spec.rb b/spec/models/projects/project_topic_spec.rb
new file mode 100644
index 00000000000..c7a989040c7
--- /dev/null
+++ b/spec/models/projects/project_topic_spec.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::ProjectTopic do
+ let_it_be(:project_topic, reload: true) { create(:project_topic) }
+
+ subject { project_topic }
+
+ it { expect(subject).to be_valid }
+
+ describe 'associations' do
+ it { is_expected.to belong_to(:project) }
+ it { is_expected.to belong_to(:topic) }
+ end
+end
diff --git a/spec/models/projects/topic_spec.rb b/spec/models/projects/topic_spec.rb
new file mode 100644
index 00000000000..409dc932709
--- /dev/null
+++ b/spec/models/projects/topic_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::Topic do
+ let_it_be(:topic, reload: true) { create(:topic) }
+
+ subject { topic }
+
+ it { expect(subject).to be_valid }
+
+ describe 'associations' do
+ it { is_expected.to have_many(:project_topics) }
+ it { is_expected.to have_many(:projects) }
+ end
+
+ describe 'validations' do
+ it { is_expected.to validate_presence_of(:name) }
+ it { is_expected.to validate_uniqueness_of(:name) }
+ it { is_expected.to validate_length_of(:name).is_at_most(255) }
+ end
+end
diff --git a/spec/models/protected_branch_spec.rb b/spec/models/protected_branch_spec.rb
index a173ab48f17..019c01af672 100644
--- a/spec/models/protected_branch_spec.rb
+++ b/spec/models/protected_branch_spec.rb
@@ -162,6 +162,30 @@ RSpec.describe ProtectedBranch do
expect(described_class.protected?(project, 'staging/some-branch')).to eq(false)
end
+
+ context 'with caching', :use_clean_rails_memory_store_caching do
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:protected_branch) { create(:protected_branch, project: project, name: "jawn") }
+
+ before do
+ allow(described_class).to receive(:matching).once.and_call_original
+ # the original call works and warms the cache
+ described_class.protected?(project, 'jawn')
+ end
+
+ it 'correctly invalidates a cache' do
+ expect(described_class).to receive(:matching).once.and_call_original
+
+ create(:protected_branch, project: project, name: "bar")
+ # the cache is invalidated because the project has been "updated"
+ expect(described_class.protected?(project, 'jawn')).to eq(true)
+ end
+
+ it 'correctly uses the cached version' do
+ expect(described_class).not_to receive(:matching)
+ expect(described_class.protected?(project, 'jawn')).to eq(true)
+ end
+ end
end
context 'new project' do
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index 211e448b6cf..dc55214c1dd 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -68,51 +68,69 @@ RSpec.describe Repository do
describe 'tags_sorted_by' do
let(:tags_to_compare) { %w[v1.0.0 v1.1.0] }
+ let(:feature_flag) { true }
+
+ before do
+ stub_feature_flags(gitaly_tags_finder: feature_flag)
+ end
context 'name_desc' do
subject { repository.tags_sorted_by('name_desc').map(&:name) & tags_to_compare }
it { is_expected.to eq(['v1.1.0', 'v1.0.0']) }
+
+ context 'when feature flag is disabled' do
+ let(:feature_flag) { false }
+
+ it { is_expected.to eq(['v1.1.0', 'v1.0.0']) }
+ end
end
context 'name_asc' do
subject { repository.tags_sorted_by('name_asc').map(&:name) & tags_to_compare }
it { is_expected.to eq(['v1.0.0', 'v1.1.0']) }
+
+ context 'when feature flag is disabled' do
+ let(:feature_flag) { false }
+
+ it { is_expected.to eq(['v1.0.0', 'v1.1.0']) }
+ end
end
context 'updated' do
- let(:tag_a) { repository.find_tag('v1.0.0') }
- let(:tag_b) { repository.find_tag('v1.1.0') }
+ let(:latest_tag) { 'v0.0.0' }
+
+ before do
+ rugged_repo(repository).tags.create(latest_tag, repository.commit.id)
+ end
+
+ after do
+ rugged_repo(repository).tags.delete(latest_tag)
+ end
context 'desc' do
- subject { repository.tags_sorted_by('updated_desc').map(&:name) }
+ subject { repository.tags_sorted_by('updated_desc').map(&:name) & (tags_to_compare + [latest_tag]) }
- before do
- double_first = double(committed_date: Time.current)
- double_last = double(committed_date: Time.current - 1.second)
+ it { is_expected.to eq([latest_tag, 'v1.1.0', 'v1.0.0']) }
- allow(tag_a).to receive(:dereferenced_target).and_return(double_first)
- allow(tag_b).to receive(:dereferenced_target).and_return(double_last)
- allow(repository).to receive(:tags).and_return([tag_a, tag_b])
- end
+ context 'when feature flag is disabled' do
+ let(:feature_flag) { false }
- it { is_expected.to eq(['v1.0.0', 'v1.1.0']) }
+ it { is_expected.to eq([latest_tag, 'v1.1.0', 'v1.0.0']) }
+ end
end
context 'asc' do
- subject { repository.tags_sorted_by('updated_asc').map(&:name) }
+ subject { repository.tags_sorted_by('updated_asc').map(&:name) & (tags_to_compare + [latest_tag]) }
- before do
- double_first = double(committed_date: Time.current - 1.second)
- double_last = double(committed_date: Time.current)
+ it { is_expected.to eq(['v1.0.0', 'v1.1.0', latest_tag]) }
- allow(tag_a).to receive(:dereferenced_target).and_return(double_last)
- allow(tag_b).to receive(:dereferenced_target).and_return(double_first)
- allow(repository).to receive(:tags).and_return([tag_a, tag_b])
- end
+ context 'when feature flag is disabled' do
+ let(:feature_flag) { false }
- it { is_expected.to eq(['v1.1.0', 'v1.0.0']) }
+ it { is_expected.to eq(['v1.0.0', 'v1.1.0', latest_tag]) }
+ end
end
context 'annotated tag pointing to a blob' do
@@ -125,29 +143,32 @@ RSpec.describe Repository do
tagger: { name: 'John Smith', email: 'john@gmail.com' } }
rugged_repo(repository).tags.create(annotated_tag_name, 'a48e4fc218069f68ef2e769dd8dfea3991362175', **options)
+ end
- double_first = double(committed_date: Time.current - 1.second)
- double_last = double(committed_date: Time.current)
+ it { is_expected.to eq(['v1.0.0', 'v1.1.0', annotated_tag_name]) }
- allow(tag_a).to receive(:dereferenced_target).and_return(double_last)
- allow(tag_b).to receive(:dereferenced_target).and_return(double_first)
- end
+ context 'when feature flag is disabled' do
+ let(:feature_flag) { false }
- it { is_expected.to eq(['v1.1.0', 'v1.0.0', annotated_tag_name]) }
+ it { is_expected.to eq(['v1.0.0', 'v1.1.0', annotated_tag_name]) }
+ end
after do
rugged_repo(repository).tags.delete(annotated_tag_name)
end
end
end
- end
- describe '#ref_name_for_sha' do
- it 'returns the ref' do
- allow(repository.raw_repository).to receive(:ref_name_for_sha)
- .and_return('refs/environments/production/77')
+ context 'unknown option' do
+ subject { repository.tags_sorted_by('unknown_desc').map(&:name) & tags_to_compare }
+
+ it { is_expected.to eq(['v1.0.0', 'v1.1.0']) }
- expect(repository.ref_name_for_sha('bla', '0' * 40)).to eq 'refs/environments/production/77'
+ context 'when feature flag is disabled' do
+ let(:feature_flag) { false }
+
+ it { is_expected.to eq(['v1.0.0', 'v1.1.0']) }
+ end
end
end
@@ -479,6 +500,29 @@ RSpec.describe Repository do
end
end
+ describe '#commits_between' do
+ let(:commit) { project.commit }
+
+ it 'delegates to Gitlab::Git::Commit#between, returning decorated commits' do
+ expect(Gitlab::Git::Commit)
+ .to receive(:between)
+ .with(repository.raw_repository, commit.parent_id, commit.id, limit: 5)
+ .and_call_original
+
+ result = repository.commits_between(commit.parent_id, commit.id, limit: 5)
+
+ expect(result).to contain_exactly(instance_of(Commit), instance_of(Commit))
+ end
+
+ it 'defaults to no limit' do
+ expect(Gitlab::Git::Commit)
+ .to receive(:between)
+ .with(repository.raw_repository, commit.parent_id, commit.id, limit: nil)
+
+ repository.commits_between(commit.parent_id, commit.id)
+ end
+ end
+
describe '#find_commits_by_message' do
it 'returns commits with messages containing a given string' do
commit_ids = repository.find_commits_by_message('submodule').map(&:id)
@@ -1294,6 +1338,15 @@ RSpec.describe Repository do
expect(repository.license).to be_nil
end
+ it 'returns nil when license_key is not recognized' do
+ expect(repository).to receive(:license_key).twice.and_return('not-recognized')
+ expect(Gitlab::ErrorTracking).to receive(:track_exception) do |ex|
+ expect(ex).to be_a(Licensee::InvalidLicense)
+ end
+
+ expect(repository.license).to be_nil
+ end
+
it 'returns other when the content is not recognizable' do
license = Licensee::License.new('other')
repository.create_file(user, 'LICENSE', 'Gitlab B.V.',
@@ -1773,7 +1826,7 @@ RSpec.describe Repository do
expect(merge_commit.message).to eq('Custom message')
expect(merge_commit.author_name).to eq(user.name)
- expect(merge_commit.author_email).to eq(user.commit_email)
+ expect(merge_commit.author_email).to eq(user.commit_email_or_default)
expect(repository.blob_at(merge_commit.id, 'files/ruby/feature.rb')).to be_present
end
end
@@ -2313,6 +2366,42 @@ RSpec.describe Repository do
end
end
+ describe '#find_tag' do
+ before do
+ allow(Gitlab::GitalyClient).to receive(:call).and_call_original
+ end
+
+ it 'finds a tag with specified name by performing FindTag request' do
+ expect(Gitlab::GitalyClient)
+ .to receive(:call).with(anything, :ref_service, :find_tag, anything, anything).and_call_original
+
+ expect(repository.find_tag('v1.1.0').name).to eq('v1.1.0')
+ end
+
+ it 'does not perform Gitaly call when tags are preloaded' do
+ repository.tags
+
+ expect(Gitlab::GitalyClient).not_to receive(:call)
+
+ expect(repository.find_tag('v1.1.0').name).to eq('v1.1.0')
+ end
+
+ it 'returns nil when tag does not exists' do
+ expect(repository.find_tag('does-not-exist')).to be_nil
+ end
+
+ context 'when find_tag_via_gitaly is disabled' do
+ it 'fetches all tags' do
+ stub_feature_flags(find_tag_via_gitaly: false)
+
+ expect(Gitlab::GitalyClient)
+ .to receive(:call).with(anything, :ref_service, :find_all_tags, anything, anything).and_call_original
+
+ expect(repository.find_tag('v1.1.0').name).to eq('v1.1.0')
+ end
+ end
+ end
+
describe '#avatar' do
it 'returns nil if repo does not exist' do
allow(repository).to receive(:root_ref).and_raise(Gitlab::Git::Repository::NoRepository)
@@ -3230,26 +3319,54 @@ RSpec.describe Repository do
describe '#change_head' do
let(:branch) { repository.container.default_branch }
- it 'adds an error to container if branch does not exist' do
- expect(repository.change_head('unexisted-branch')).to be false
- expect(repository.container.errors.size).to eq(1)
- end
+ context 'when the branch exists' do
+ it 'returns truthy' do
+ expect(repository.change_head(branch)).to be_truthy
+ end
- it 'calls the before_change_head and after_change_head methods' do
- expect(repository).to receive(:before_change_head)
- expect(repository).to receive(:after_change_head)
+ it 'does not call container.after_change_head_branch_does_not_exist' do
+ expect(repository.container).not_to receive(:after_change_head_branch_does_not_exist)
- repository.change_head(branch)
- end
+ repository.change_head(branch)
+ end
+
+ it 'calls repository hooks' do
+ expect(repository).to receive(:before_change_head)
+ expect(repository).to receive(:after_change_head)
- it 'copies the gitattributes' do
- expect(repository).to receive(:copy_gitattributes).with(branch)
- repository.change_head(branch)
+ repository.change_head(branch)
+ end
+
+ it 'copies the gitattributes' do
+ expect(repository).to receive(:copy_gitattributes).with(branch)
+ repository.change_head(branch)
+ end
+
+ it 'reloads the default branch' do
+ expect(repository.container).to receive(:reload_default_branch)
+ repository.change_head(branch)
+ end
end
- it 'reloads the default branch' do
- expect(repository.container).to receive(:reload_default_branch)
- repository.change_head(branch)
+ context 'when the branch does not exist' do
+ let(:branch) { 'non-existent-branch' }
+
+ it 'returns falsey' do
+ expect(repository.change_head(branch)).to be_falsey
+ end
+
+ it 'calls container.after_change_head_branch_does_not_exist' do
+ expect(repository.container).to receive(:after_change_head_branch_does_not_exist).with(branch)
+
+ repository.change_head(branch)
+ end
+
+ it 'does not call repository hooks' do
+ expect(repository).not_to receive(:before_change_head)
+ expect(repository).not_to receive(:after_change_head)
+
+ repository.change_head(branch)
+ end
end
end
end
diff --git a/spec/models/shard_spec.rb b/spec/models/shard_spec.rb
index a9d11f4290c..38729fa1758 100644
--- a/spec/models/shard_spec.rb
+++ b/spec/models/shard_spec.rb
@@ -33,19 +33,21 @@ RSpec.describe Shard do
expect(result.name).to eq('foo')
end
- it 'retries if creation races' do
+ it 'returns existing record if creation races' do
+ shard_created_by_others = double(described_class)
+
expect(described_class)
- .to receive(:find_or_create_by)
- .with(name: 'default')
- .and_raise(ActiveRecord::RecordNotUnique, 'fail')
- .once
+ .to receive(:find_by)
+ .with(name: 'new_shard')
+ .and_return(nil, shard_created_by_others)
expect(described_class)
- .to receive(:find_or_create_by)
- .with(name: 'default')
- .and_call_original
+ .to receive(:create)
+ .with(name: 'new_shard')
+ .and_raise(ActiveRecord::RecordNotUnique, 'fail')
+ .once
- expect(described_class.by_name('default')).to eq(default_shard)
+ expect(described_class.by_name('new_shard')).to eq(shard_created_by_others)
end
end
end
diff --git a/spec/models/user_callout_spec.rb b/spec/models/user_callout_spec.rb
index eb66f074293..5b36c8450ea 100644
--- a/spec/models/user_callout_spec.rb
+++ b/spec/models/user_callout_spec.rb
@@ -3,29 +3,12 @@
require 'spec_helper'
RSpec.describe UserCallout do
- let!(:callout) { create(:user_callout) }
+ let_it_be(:callout) { create(:user_callout) }
it_behaves_like 'having unique enum values'
- describe 'relationships' do
- it { is_expected.to belong_to(:user) }
- end
-
describe 'validations' do
- it { is_expected.to validate_presence_of(:user) }
-
it { is_expected.to validate_presence_of(:feature_name) }
it { is_expected.to validate_uniqueness_of(:feature_name).scoped_to(:user_id).ignoring_case_sensitivity }
end
-
- describe '#dismissed_after?' do
- let(:some_feature_name) { described_class.feature_names.keys.second }
- let(:callout_dismissed_month_ago) { create(:user_callout, feature_name: some_feature_name, dismissed_at: 1.month.ago )}
- let(:callout_dismissed_day_ago) { create(:user_callout, feature_name: some_feature_name, dismissed_at: 1.day.ago )}
-
- it 'returns whether a callout dismissed after specified date' do
- expect(callout_dismissed_month_ago.dismissed_after?(15.days.ago)).to eq(false)
- expect(callout_dismissed_day_ago.dismissed_after?(15.days.ago)).to eq(true)
- end
- end
end
diff --git a/spec/models/user_detail_spec.rb b/spec/models/user_detail_spec.rb
index 3c87dcdcbd9..ba7ea3f7ce2 100644
--- a/spec/models/user_detail_spec.rb
+++ b/spec/models/user_detail_spec.rb
@@ -25,29 +25,4 @@ RSpec.describe UserDetail do
it { is_expected.to validate_length_of(:bio).is_at_most(255) }
end
end
-
- describe '#bio_html' do
- let(:user) { create(:user, bio: 'some **bio**') }
-
- subject { user.user_detail.bio_html }
-
- it 'falls back to #bio when the html representation is missing' do
- user.user_detail.update!(bio_html: nil)
-
- expect(subject).to eq(user.user_detail.bio)
- end
-
- it 'stores rendered html' do
- expect(subject).to include('some <strong>bio</strong>')
- end
-
- it 'does not try to set the value when the column is not there' do
- without_bio_html_column = UserDetail.column_names - ['bio_html']
-
- expect(described_class).to receive(:column_names).at_least(:once).and_return(without_bio_html_column)
- expect(user.user_detail).not_to receive(:bio_html=)
-
- subject
- end
- end
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index d73bc95a2f2..334f9b4ae30 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -65,9 +65,6 @@ RSpec.describe User do
it { is_expected.to delegate_method(:render_whitespace_in_code).to(:user_preference) }
it { is_expected.to delegate_method(:render_whitespace_in_code=).to(:user_preference).with_arguments(:args) }
- it { is_expected.to delegate_method(:experience_level).to(:user_preference) }
- it { is_expected.to delegate_method(:experience_level=).to(:user_preference).with_arguments(:args) }
-
it { is_expected.to delegate_method(:markdown_surround_selection).to(:user_preference) }
it { is_expected.to delegate_method(:markdown_surround_selection=).to(:user_preference).with_arguments(:args) }
@@ -82,7 +79,6 @@ RSpec.describe User do
it { is_expected.to delegate_method(:bio).to(:user_detail).allow_nil }
it { is_expected.to delegate_method(:bio=).to(:user_detail).with_arguments(:args).allow_nil }
- it { is_expected.to delegate_method(:bio_html).to(:user_detail).allow_nil }
end
describe 'associations' do
@@ -110,7 +106,6 @@ RSpec.describe User do
it { is_expected.to have_many(:spam_logs).dependent(:destroy) }
it { is_expected.to have_many(:todos) }
it { is_expected.to have_many(:award_emoji).dependent(:destroy) }
- it { is_expected.to have_many(:triggers).dependent(:destroy) }
it { is_expected.to have_many(:builds).dependent(:nullify) }
it { is_expected.to have_many(:pipelines).dependent(:nullify) }
it { is_expected.to have_many(:chat_names).dependent(:destroy) }
@@ -125,6 +120,8 @@ RSpec.describe User do
it { is_expected.to have_many(:created_custom_emoji).inverse_of(:creator) }
it { is_expected.to have_many(:in_product_marketing_emails) }
it { is_expected.to have_many(:timelogs) }
+ it { is_expected.to have_many(:callouts).class_name('UserCallout') }
+ it { is_expected.to have_many(:group_callouts).class_name('Users::GroupCallout') }
describe "#user_detail" do
it 'does not persist `user_detail` by default' do
@@ -404,7 +401,7 @@ RSpec.describe User do
user = build(:user, username: "test.#{type}")
expect(user).not_to be_valid
- expect(user.errors.full_messages).to include('Username ending with MIME type format is not allowed.')
+ expect(user.errors.full_messages).to include('Username ending with a file extension is not allowed.')
expect(build(:user, username: "test#{type}")).to be_valid
end
end
@@ -438,12 +435,12 @@ RSpec.describe User do
subject { create(:user).tap { |user| user.emails << build(:email, email: email_value, confirmed_at: Time.current) } }
end
- describe '#commit_email' do
+ describe '#commit_email_or_default' do
subject(:user) { create(:user) }
it 'defaults to the primary email' do
expect(user.email).to be_present
- expect(user.commit_email).to eq(user.email)
+ expect(user.commit_email_or_default).to eq(user.email)
end
it 'defaults to the primary email when the column in the database is null' do
@@ -451,38 +448,37 @@ RSpec.describe User do
found_user = described_class.find_by(id: user.id)
- expect(found_user.commit_email).to eq(user.email)
+ expect(found_user.commit_email_or_default).to eq(user.email)
end
it 'returns the private commit email when commit_email has _private' do
user.update_column(:commit_email, Gitlab::PrivateCommitEmail::TOKEN)
- expect(user.commit_email).to eq(user.private_commit_email)
+ expect(user.commit_email_or_default).to eq(user.private_commit_email)
end
+ end
+
+ describe '#commit_email=' do
+ subject(:user) { create(:user) }
it 'can be set to a confirmed email' do
confirmed = create(:email, :confirmed, user: user)
user.commit_email = confirmed.email
expect(user).to be_valid
- expect(user.commit_email).to eq(confirmed.email)
end
it 'can not be set to an unconfirmed email' do
unconfirmed = create(:email, user: user)
user.commit_email = unconfirmed.email
- # This should set the commit_email attribute to the primary email
- expect(user).to be_valid
- expect(user.commit_email).to eq(user.email)
+ expect(user).not_to be_valid
end
it 'can not be set to a non-existent email' do
user.commit_email = 'non-existent-email@nonexistent.nonexistent'
- # This should set the commit_email attribute to the primary email
- expect(user).to be_valid
- expect(user.commit_email).to eq(user.email)
+ expect(user).not_to be_valid
end
it 'can not be set to an invalid email, even if confirmed' do
@@ -692,70 +688,26 @@ RSpec.describe User do
end
end
- context 'owns_notification_email' do
- it 'accepts temp_oauth_email emails' do
- user = build(:user, email: "temp-email-for-oauth@example.com")
- expect(user).to be_valid
- end
-
- it 'does not accept not verified emails' do
- email = create(:email)
- user = email.user
- user.notification_email = email.email
+ context 'when secondary email is same as primary' do
+ let(:user) { create(:user, email: 'user@example.com') }
- expect(user).to be_invalid
- expect(user.errors[:notification_email]).to include(_('must be an email you have verified'))
- end
- end
+ it 'lets user change primary email without failing validations' do
+ user.commit_email = user.email
+ user.notification_email = user.email
+ user.public_email = user.email
+ user.save!
- context 'owns_public_email' do
- it 'accepts verified emails' do
- email = create(:email, :confirmed, email: 'test@test.com')
- user = email.user
- user.notification_email = email.email
+ user.email = 'newemail@example.com'
+ user.confirm
expect(user).to be_valid
end
-
- it 'does not accept not verified emails' do
- email = create(:email)
- user = email.user
- user.public_email = email.email
-
- expect(user).to be_invalid
- expect(user.errors[:public_email]).to include(_('must be an email you have verified'))
- end
end
- context 'set_commit_email' do
- it 'keeps commit email when private commit email is being used' do
- user = create(:user, commit_email: Gitlab::PrivateCommitEmail::TOKEN)
-
- expect(user.read_attribute(:commit_email)).to eq(Gitlab::PrivateCommitEmail::TOKEN)
- end
-
- it 'keeps the commit email when nil' do
- user = create(:user, commit_email: nil)
-
- expect(user.read_attribute(:commit_email)).to be_nil
- end
-
- it 'reverts to nil when email is not verified' do
- user = create(:user, commit_email: "foo@bar.com")
-
- expect(user.read_attribute(:commit_email)).to be_nil
- end
- end
-
- context 'owns_commit_email' do
- it 'accepts private commit email' do
- user = build(:user, commit_email: Gitlab::PrivateCommitEmail::TOKEN)
-
- expect(user).to be_valid
- end
-
- it 'accepts nil commit email' do
- user = build(:user, commit_email: nil)
+ context 'when commit_email is changed to _private' do
+ it 'passes user validations' do
+ user = create(:user)
+ user.commit_email = '_private'
expect(user).to be_valid
end
@@ -931,12 +883,8 @@ RSpec.describe User do
end
context 'maximum value' do
- before do
- allow(Devise.password_length).to receive(:max).and_return(201)
- end
-
it 'is determined by the current value of `Devise.password_length.max`' do
- expect(password_length.max).to eq(201)
+ expect(password_length.max).to eq(Devise.password_length.max)
end
end
end
@@ -1311,53 +1259,57 @@ RSpec.describe User do
end
end
- describe '#update_notification_email' do
- # Regression: https://gitlab.com/gitlab-org/gitlab-foss/issues/22846
- context 'when changing :email' do
- let(:user) { create(:user) }
- let(:new_email) { 'new-email@example.com' }
+ describe 'when changing email' do
+ let(:user) { create(:user) }
+ let(:new_email) { 'new-email@example.com' }
+ context 'if notification_email was nil' do
it 'sets :unconfirmed_email' do
expect do
user.tap { |u| u.update!(email: new_email) }.reload
end.to change(user, :unconfirmed_email).to(new_email)
end
- it 'does not change :notification_email' do
+
+ it 'does not change notification_email or notification_email_or_default before email is confirmed' do
expect do
user.tap { |u| u.update!(email: new_email) }.reload
- end.not_to change(user, :notification_email)
+ end.not_to change(user, :notification_email_or_default)
+
+ expect(user.notification_email).to be_nil
end
- it 'updates :notification_email to the new email once confirmed' do
+ it 'updates notification_email_or_default to the new email once confirmed' do
user.update!(email: new_email)
expect do
user.tap(&:confirm).reload
- end.to change(user, :notification_email).to eq(new_email)
+ end.to change(user, :notification_email_or_default).to eq(new_email)
+
+ expect(user.notification_email).to be_nil
end
+ end
- context 'and :notification_email is set to a secondary email' do
- let!(:email_attrs) { attributes_for(:email, :confirmed, user: user) }
- let(:secondary) { create(:email, :confirmed, email: 'secondary@example.com', user: user) }
+ context 'when notification_email is set to a secondary email' do
+ let!(:email_attrs) { attributes_for(:email, :confirmed, user: user) }
+ let(:secondary) { create(:email, :confirmed, email: 'secondary@example.com', user: user) }
- before do
- user.emails.create!(email_attrs)
- user.tap { |u| u.update!(notification_email: email_attrs[:email]) }.reload
- end
+ before do
+ user.emails.create!(email_attrs)
+ user.tap { |u| u.update!(notification_email: email_attrs[:email]) }.reload
+ end
- it 'does not change :notification_email to :email' do
- expect do
- user.tap { |u| u.update!(email: new_email) }.reload
- end.not_to change(user, :notification_email)
- end
+ it 'does not change notification_email to email before email is confirmed' do
+ expect do
+ user.tap { |u| u.update!(email: new_email) }.reload
+ end.not_to change(user, :notification_email)
+ end
- it 'does not change :notification_email to :email once confirmed' do
- user.update!(email: new_email)
+ it 'does not change notification_email to email once confirmed' do
+ user.update!(email: new_email)
- expect do
- user.tap(&:confirm).reload
- end.not_to change(user, :notification_email)
- end
+ expect do
+ user.tap(&:confirm).reload
+ end.not_to change(user, :notification_email)
end
end
end
@@ -1833,14 +1785,26 @@ RSpec.describe User do
end
describe '#manageable_groups' do
- it 'includes all the namespaces the user can manage' do
- expect(user.manageable_groups).to contain_exactly(group, subgroup)
+ shared_examples 'manageable groups examples' do
+ it 'includes all the namespaces the user can manage' do
+ expect(user.manageable_groups).to contain_exactly(group, subgroup)
+ end
+
+ it 'does not include duplicates if a membership was added for the subgroup' do
+ subgroup.add_owner(user)
+
+ expect(user.manageable_groups).to contain_exactly(group, subgroup)
+ end
end
- it 'does not include duplicates if a membership was added for the subgroup' do
- subgroup.add_owner(user)
+ it_behaves_like 'manageable groups examples'
+
+ context 'when feature flag :linear_user_manageable_groups is disabled' do
+ before do
+ stub_feature_flags(linear_user_manageable_groups: false)
+ end
- expect(user.manageable_groups).to contain_exactly(group, subgroup)
+ it_behaves_like 'manageable groups examples'
end
end
@@ -1925,12 +1889,25 @@ RSpec.describe User do
expect(user.deactivated?).to be_truthy
end
- it 'sends deactivated user an email' do
- expect_next_instance_of(NotificationService) do |notification|
- allow(notification).to receive(:user_deactivated).with(user.name, user.notification_email)
+ context "when user deactivation emails are disabled" do
+ before do
+ stub_application_setting(user_deactivation_emails_enabled: false)
end
+ it 'does not send deactivated user an email' do
+ expect(NotificationService).not_to receive(:new)
- user.deactivate
+ user.deactivate
+ end
+ end
+
+ context "when user deactivation emails are enabled" do
+ it 'sends deactivated user an email' do
+ expect_next_instance_of(NotificationService) do |notification|
+ allow(notification).to receive(:user_deactivated).with(user.name, user.notification_email_or_default)
+ end
+
+ user.deactivate
+ end
end
end
@@ -1997,15 +1974,15 @@ RSpec.describe User do
user.ban!
end
- it 'activates the user' do
- user.activate
+ it 'unbans the user' do
+ user.unban
expect(user.banned?).to eq(false)
expect(user.active?).to eq(true)
end
it 'deletes the BannedUser record' do
- expect { user.activate }.to change { Users::BannedUser.count }.by(-1)
+ expect { user.unban }.to change { Users::BannedUser.count }.by(-1)
expect(Users::BannedUser.where(user_id: user.id)).not_to exist
end
end
@@ -3125,15 +3102,15 @@ RSpec.describe User do
end
end
- describe '#notification_email' do
+ describe '#notification_email_or_default' do
let(:email) { 'gonzo@muppets.com' }
context 'when the column in the database is null' do
subject { create(:user, email: email, notification_email: nil) }
it 'defaults to the primary email' do
- expect(subject.read_attribute(:notification_email)).to be nil
- expect(subject.notification_email).to eq(email)
+ expect(subject.notification_email).to be nil
+ expect(subject.notification_email_or_default).to eq(email)
end
end
end
@@ -3467,17 +3444,32 @@ RSpec.describe User do
end
describe '#membership_groups' do
- let!(:user) { create(:user) }
- let!(:parent_group) { create(:group) }
- let!(:child_group) { create(:group, parent: parent_group) }
+ let_it_be(:user) { create(:user) }
- before do
- parent_group.add_user(user, Gitlab::Access::MAINTAINER)
+ let_it_be(:parent_group) do
+ create(:group).tap do |g|
+ g.add_user(user, Gitlab::Access::MAINTAINER)
+ end
end
+ let_it_be(:child_group) { create(:group, parent: parent_group) }
+ let_it_be(:other_group) { create(:group) }
+
subject { user.membership_groups }
- it { is_expected.to contain_exactly parent_group, child_group }
+ shared_examples 'returns groups where the user is a member' do
+ specify { is_expected.to contain_exactly(parent_group, child_group) }
+ end
+
+ it_behaves_like 'returns groups where the user is a member'
+
+ context 'when feature flag :linear_user_membership_groups is disabled' do
+ before do
+ stub_feature_flags(linear_user_membership_groups: false)
+ end
+
+ it_behaves_like 'returns groups where the user is a member'
+ end
end
describe '#authorizations_for_projects' do
@@ -3686,6 +3678,11 @@ RSpec.describe User do
it 'loads all the runners in the tree of groups' do
expect(user.ci_owned_runners).to contain_exactly(runner, group_runner)
end
+
+ it 'returns true for owns_runner?' do
+ expect(user.owns_runner?(runner)).to eq(true)
+ expect(user.owns_runner?(group_runner)).to eq(true)
+ end
end
end
@@ -3698,6 +3695,10 @@ RSpec.describe User do
it 'loads the runners in the group' do
expect(user.ci_owned_runners).to contain_exactly(group_runner)
end
+
+ it 'returns true for owns_runner?' do
+ expect(user.owns_runner?(group_runner)).to eq(true)
+ end
end
end
@@ -3706,6 +3707,10 @@ RSpec.describe User do
it 'loads the runner belonging to the project' do
expect(user.ci_owned_runners).to contain_exactly(runner)
end
+
+ it 'returns true for owns_runner?' do
+ expect(user.owns_runner?(runner)).to eq(true)
+ end
end
end
@@ -3718,6 +3723,10 @@ RSpec.describe User do
it 'loads the runners of the project' do
expect(user.ci_owned_runners).to contain_exactly(project_runner)
end
+
+ it 'returns true for owns_runner?' do
+ expect(user.owns_runner?(project_runner)).to eq(true)
+ end
end
context 'when the user is a developer' do
@@ -3728,6 +3737,10 @@ RSpec.describe User do
it 'does not load any runner' do
expect(user.ci_owned_runners).to be_empty
end
+
+ it 'returns false for owns_runner?' do
+ expect(user.owns_runner?(project_runner)).to eq(false)
+ end
end
context 'when the user is a reporter' do
@@ -3738,6 +3751,10 @@ RSpec.describe User do
it 'does not load any runner' do
expect(user.ci_owned_runners).to be_empty
end
+
+ it 'returns false for owns_runner?' do
+ expect(user.owns_runner?(project_runner)).to eq(false)
+ end
end
context 'when the user is a guest' do
@@ -3748,6 +3765,10 @@ RSpec.describe User do
it 'does not load any runner' do
expect(user.ci_owned_runners).to be_empty
end
+
+ it 'returns false for owns_runner?' do
+ expect(user.owns_runner?(project_runner)).to eq(false)
+ end
end
end
@@ -3760,6 +3781,10 @@ RSpec.describe User do
it 'does not load the runners of the group' do
expect(user.ci_owned_runners).to be_empty
end
+
+ it 'returns false for owns_runner?' do
+ expect(user.owns_runner?(runner)).to eq(false)
+ end
end
context 'when the user is a developer' do
@@ -3770,6 +3795,10 @@ RSpec.describe User do
it 'does not load any runner' do
expect(user.ci_owned_runners).to be_empty
end
+
+ it 'returns false for owns_runner?' do
+ expect(user.owns_runner?(runner)).to eq(false)
+ end
end
context 'when the user is a reporter' do
@@ -3780,6 +3809,10 @@ RSpec.describe User do
it 'does not load any runner' do
expect(user.ci_owned_runners).to be_empty
end
+
+ it 'returns false for owns_runner?' do
+ expect(user.owns_runner?(runner)).to eq(false)
+ end
end
context 'when the user is a guest' do
@@ -3790,6 +3823,10 @@ RSpec.describe User do
it 'does not load any runner' do
expect(user.ci_owned_runners).to be_empty
end
+
+ it 'returns false for owns_runner?' do
+ expect(user.owns_runner?(runner)).to eq(false)
+ end
end
end
@@ -3797,6 +3834,10 @@ RSpec.describe User do
it 'does not load any runner' do
expect(user.ci_owned_runners).to be_empty
end
+
+ it 'returns false for owns_runner?' do
+ expect(user.owns_runner?(create(:ci_runner))).to eq(false)
+ end
end
context 'with runner in a personal project' do
@@ -5312,7 +5353,7 @@ RSpec.describe User do
let(:group) { nil }
it 'returns global notification email' do
- is_expected.to eq(user.notification_email)
+ is_expected.to eq(user.notification_email_or_default)
end
end
@@ -5320,7 +5361,7 @@ RSpec.describe User do
it 'returns global notification email' do
create(:notification_setting, user: user, source: group, notification_email: '')
- is_expected.to eq(user.notification_email)
+ is_expected.to eq(user.notification_email_or_default)
end
end
@@ -5521,22 +5562,17 @@ RSpec.describe User do
end
describe '#dismissed_callout?' do
- subject(:user) { create(:user) }
-
- let(:feature_name) { UserCallout.feature_names.each_key.first }
+ let_it_be(:user, refind: true) { create(:user) }
+ let_it_be(:feature_name) { UserCallout.feature_names.each_key.first }
context 'when no callout dismissal record exists' do
it 'returns false when no ignore_dismissal_earlier_than provided' do
expect(user.dismissed_callout?(feature_name: feature_name)).to eq false
end
-
- it 'returns false when ignore_dismissal_earlier_than provided' do
- expect(user.dismissed_callout?(feature_name: feature_name, ignore_dismissal_earlier_than: 3.months.ago)).to eq false
- end
end
context 'when dismissed callout exists' do
- before do
+ before_all do
create(:user_callout, user: user, feature_name: feature_name, dismissed_at: 4.months.ago)
end
@@ -5554,6 +5590,123 @@ RSpec.describe User do
end
end
+ describe '#find_or_initialize_callout' do
+ let_it_be(:user, refind: true) { create(:user) }
+ let_it_be(:feature_name) { UserCallout.feature_names.each_key.first }
+
+ subject(:find_or_initialize_callout) { user.find_or_initialize_callout(feature_name) }
+
+ context 'when callout exists' do
+ let!(:callout) { create(:user_callout, user: user, feature_name: feature_name) }
+
+ it 'returns existing callout' do
+ expect(find_or_initialize_callout).to eq(callout)
+ end
+ end
+
+ context 'when callout does not exist' do
+ context 'when feature name is valid' do
+ it 'initializes a new callout' do
+ expect(find_or_initialize_callout).to be_a_new(UserCallout)
+ end
+
+ it 'is valid' do
+ expect(find_or_initialize_callout).to be_valid
+ end
+ end
+
+ context 'when feature name is not valid' do
+ let(:feature_name) { 'notvalid' }
+
+ it 'initializes a new callout' do
+ expect(find_or_initialize_callout).to be_a_new(UserCallout)
+ end
+
+ it 'is not valid' do
+ expect(find_or_initialize_callout).not_to be_valid
+ end
+ end
+ end
+ end
+
+ describe '#dismissed_callout_for_group?' do
+ let_it_be(:user, refind: true) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:feature_name) { Users::GroupCallout.feature_names.each_key.first }
+
+ context 'when no callout dismissal record exists' do
+ it 'returns false when no ignore_dismissal_earlier_than provided' do
+ expect(user.dismissed_callout_for_group?(feature_name: feature_name, group: group)).to eq false
+ end
+ end
+
+ context 'when dismissed callout exists' do
+ before_all do
+ create(:group_callout,
+ user: user,
+ group_id: group.id,
+ feature_name: feature_name,
+ dismissed_at: 4.months.ago)
+ end
+
+ it 'returns true when no ignore_dismissal_earlier_than provided' do
+ expect(user.dismissed_callout_for_group?(feature_name: feature_name, group: group)).to eq true
+ end
+
+ it 'returns true when ignore_dismissal_earlier_than is earlier than dismissed_at' do
+ expect(user.dismissed_callout_for_group?(feature_name: feature_name, group: group, ignore_dismissal_earlier_than: 6.months.ago)).to eq true
+ end
+
+ it 'returns false when ignore_dismissal_earlier_than is later than dismissed_at' do
+ expect(user.dismissed_callout_for_group?(feature_name: feature_name, group: group, ignore_dismissal_earlier_than: 3.months.ago)).to eq false
+ end
+ end
+ end
+
+ describe '#find_or_initialize_group_callout' do
+ let_it_be(:user, refind: true) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:feature_name) { Users::GroupCallout.feature_names.each_key.first }
+
+ subject(:callout_with_source) do
+ user.find_or_initialize_group_callout(feature_name, group.id)
+ end
+
+ context 'when callout exists' do
+ let!(:callout) do
+ create(:group_callout, user: user, feature_name: feature_name, group_id: group.id)
+ end
+
+ it 'returns existing callout' do
+ expect(callout_with_source).to eq(callout)
+ end
+ end
+
+ context 'when callout does not exist' do
+ context 'when feature name is valid' do
+ it 'initializes a new callout' do
+ expect(callout_with_source).to be_a_new(Users::GroupCallout)
+ end
+
+ it 'is valid' do
+ expect(callout_with_source).to be_valid
+ end
+ end
+
+ context 'when feature name is not valid' do
+ let(:feature_name) { 'notvalid' }
+
+ it 'initializes a new callout' do
+ expect(callout_with_source).to be_a_new(Users::GroupCallout)
+ end
+
+ it 'is not valid' do
+ expect(callout_with_source).not_to be_valid
+ end
+ end
+ end
+ end
+
describe '#hook_attrs' do
it 'includes id, name, username, avatar_url, and email' do
user = create(:user)
@@ -5916,45 +6069,6 @@ RSpec.describe User do
end
end
- describe '#find_or_initialize_callout' do
- subject(:find_or_initialize_callout) { user.find_or_initialize_callout(feature_name) }
-
- let(:user) { create(:user) }
- let(:feature_name) { UserCallout.feature_names.each_key.first }
-
- context 'when callout exists' do
- let!(:callout) { create(:user_callout, user: user, feature_name: feature_name) }
-
- it 'returns existing callout' do
- expect(find_or_initialize_callout).to eq(callout)
- end
- end
-
- context 'when callout does not exist' do
- context 'when feature name is valid' do
- it 'initializes a new callout' do
- expect(find_or_initialize_callout).to be_a_new(UserCallout)
- end
-
- it 'is valid' do
- expect(find_or_initialize_callout).to be_valid
- end
- end
-
- context 'when feature name is not valid' do
- let(:feature_name) { 'notvalid' }
-
- it 'initializes a new callout' do
- expect(find_or_initialize_callout).to be_a_new(UserCallout)
- end
-
- it 'is not valid' do
- expect(find_or_initialize_callout).not_to be_valid
- end
- end
- end
- end
-
describe '#default_dashboard?' do
it 'is the default dashboard' do
user = build(:user)
@@ -6024,4 +6138,75 @@ RSpec.describe User do
expect(described_class.by_provider_and_extern_uid(:github, 'my_github_id')).to match_array([expected_user])
end
end
+
+ describe '#unset_secondary_emails_matching_deleted_email!' do
+ let(:deleted_email) { 'kermit@muppets.com' }
+
+ subject { build(:user, commit_email: commit_email) }
+
+ context 'when no secondary email matches the deleted email' do
+ let(:commit_email) { 'fozzie@muppets.com' }
+
+ it 'does nothing' do
+ expect(subject).not_to receive(:save)
+ subject.unset_secondary_emails_matching_deleted_email!(deleted_email)
+ expect(subject.commit_email).to eq commit_email
+ end
+ end
+
+ context 'when a secondary email matches the deleted_email' do
+ let(:commit_email) { deleted_email }
+
+ it 'un-sets the secondary email' do
+ expect(subject).to receive(:save)
+ subject.unset_secondary_emails_matching_deleted_email!(deleted_email)
+ expect(subject.commit_email).to be nil
+ end
+ end
+ end
+
+ describe '#groups_with_developer_maintainer_project_access' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group1) { create(:group) }
+
+ let_it_be(:developer_group1) do
+ create(:group).tap do |g|
+ g.add_developer(user)
+ end
+ end
+
+ let_it_be(:developer_group2) do
+ create(:group, project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS).tap do |g|
+ g.add_developer(user)
+ end
+ end
+
+ let_it_be(:guest_group1) do
+ create(:group, project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS).tap do |g|
+ g.add_guest(user)
+ end
+ end
+
+ let_it_be(:developer_group1) do
+ create(:group, project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS).tap do |g|
+ g.add_maintainer(user)
+ end
+ end
+
+ subject { user.send(:groups_with_developer_maintainer_project_access) }
+
+ shared_examples 'groups_with_developer_maintainer_project_access examples' do
+ specify { is_expected.to contain_exactly(developer_group2) }
+ end
+
+ it_behaves_like 'groups_with_developer_maintainer_project_access examples'
+
+ context 'when feature flag :linear_user_groups_with_developer_maintainer_project_access is disabled' do
+ before do
+ stub_feature_flags(linear_user_groups_with_developer_maintainer_project_access: false)
+ end
+
+ it_behaves_like 'groups_with_developer_maintainer_project_access examples'
+ end
+ end
end
diff --git a/spec/models/users/group_callout_spec.rb b/spec/models/users/group_callout_spec.rb
new file mode 100644
index 00000000000..461b5fd7715
--- /dev/null
+++ b/spec/models/users/group_callout_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Users::GroupCallout do
+ let_it_be(:user) { create_default(:user) }
+ let_it_be(:group) { create_default(:group) }
+ let_it_be(:callout) { create(:group_callout) }
+
+ it_behaves_like 'having unique enum values'
+
+ describe 'relationships' do
+ it { is_expected.to belong_to(:group) }
+ end
+
+ describe 'validations' do
+ it { is_expected.to validate_presence_of(:group) }
+ it { is_expected.to validate_presence_of(:feature_name) }
+ it { is_expected.to validate_uniqueness_of(:feature_name).scoped_to(:user_id, :group_id).ignoring_case_sensitivity }
+ end
+
+ describe '#source_feature_name' do
+ it 'provides string based off source and feature' do
+ expect(callout.source_feature_name).to eq "#{callout.feature_name}_#{callout.group_id}"
+ end
+ end
+end
diff --git a/spec/models/work_item/type_spec.rb b/spec/models/work_item/type_spec.rb
index 90f551b7d63..dd5324d63a0 100644
--- a/spec/models/work_item/type_spec.rb
+++ b/spec/models/work_item/type_spec.rb
@@ -19,8 +19,10 @@ RSpec.describe WorkItem::Type do
it 'deletes type but not unrelated issues' do
type = create(:work_item_type)
+ expect(WorkItem::Type.count).to eq(5)
+
expect { type.destroy! }.not_to change(Issue, :count)
- expect(WorkItem::Type.count).to eq 0
+ expect(WorkItem::Type.count).to eq(4)
end
end
@@ -28,7 +30,7 @@ RSpec.describe WorkItem::Type do
type = create(:work_item_type, work_items: [work_item])
expect { type.destroy! }.to raise_error(ActiveRecord::InvalidForeignKey)
- expect(Issue.count).to eq 1
+ expect(Issue.count).to eq(1)
end
end
diff --git a/spec/policies/custom_emoji_policy_spec.rb b/spec/policies/custom_emoji_policy_spec.rb
new file mode 100644
index 00000000000..9538ef9bb4a
--- /dev/null
+++ b/spec/policies/custom_emoji_policy_spec.rb
@@ -0,0 +1,73 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe CustomEmojiPolicy do
+ let(:user) { create(:user) }
+ let(:group) { create(:group) }
+ let(:custom_emoji) { create(:custom_emoji, group: group) }
+
+ let(:custom_emoji_permissions) do
+ [
+ :create_custom_emoji,
+ :delete_custom_emoji
+ ]
+ end
+
+ context 'custom emoji permissions' do
+ subject { described_class.new(user, custom_emoji) }
+
+ context 'when user is' do
+ context 'a developer' do
+ before do
+ group.add_developer(user)
+ end
+
+ it do
+ expect_allowed(:create_custom_emoji)
+ end
+ end
+
+ context 'is maintainer' do
+ before do
+ group.add_maintainer(user)
+ end
+
+ it do
+ expect_allowed(*custom_emoji_permissions)
+ end
+ end
+
+ context 'is owner' do
+ before do
+ group.add_owner(user)
+ end
+
+ it do
+ expect_allowed(*custom_emoji_permissions)
+ end
+ end
+
+ context 'is developer and emoji creator' do
+ before do
+ group.add_developer(user)
+ custom_emoji.update_attribute(:creator, user)
+ end
+
+ it do
+ expect_allowed(*custom_emoji_permissions)
+ end
+ end
+
+ context 'is emoji creator but not a member of the group' do
+ before do
+ custom_emoji.update_attribute(:creator, user)
+ end
+
+ it do
+ expect_disallowed(*custom_emoji_permissions)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb
index 9fac5521aa6..482e12c029d 100644
--- a/spec/policies/group_policy_spec.rb
+++ b/spec/policies/group_policy_spec.rb
@@ -11,6 +11,9 @@ RSpec.describe GroupPolicy do
it do
expect_allowed(:read_group)
+ expect_allowed(:read_organization)
+ expect_allowed(:read_contact)
+ expect_allowed(:read_counts)
expect_allowed(*read_group_permissions)
expect_disallowed(:upload_file)
expect_disallowed(*reporter_permissions)
@@ -30,6 +33,9 @@ RSpec.describe GroupPolicy do
end
it { expect_disallowed(:read_group) }
+ it { expect_disallowed(:read_organization) }
+ it { expect_disallowed(:read_contact) }
+ it { expect_disallowed(:read_counts) }
it { expect_disallowed(*read_group_permissions) }
end
@@ -42,6 +48,9 @@ RSpec.describe GroupPolicy do
end
it { expect_disallowed(:read_group) }
+ it { expect_disallowed(:read_organization) }
+ it { expect_disallowed(:read_contact) }
+ it { expect_disallowed(:read_counts) }
it { expect_disallowed(*read_group_permissions) }
end
@@ -245,6 +254,7 @@ RSpec.describe GroupPolicy do
let(:current_user) { nil }
it do
+ expect_disallowed(:read_counts)
expect_disallowed(*read_group_permissions)
expect_disallowed(*guest_permissions)
expect_disallowed(*reporter_permissions)
@@ -258,6 +268,7 @@ RSpec.describe GroupPolicy do
let(:current_user) { guest }
it do
+ expect_allowed(:read_counts)
expect_allowed(*read_group_permissions)
expect_allowed(*guest_permissions)
expect_disallowed(*reporter_permissions)
@@ -271,6 +282,7 @@ RSpec.describe GroupPolicy do
let(:current_user) { reporter }
it do
+ expect_allowed(:read_counts)
expect_allowed(*read_group_permissions)
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
@@ -284,6 +296,7 @@ RSpec.describe GroupPolicy do
let(:current_user) { developer }
it do
+ expect_allowed(:read_counts)
expect_allowed(*read_group_permissions)
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
@@ -297,6 +310,7 @@ RSpec.describe GroupPolicy do
let(:current_user) { maintainer }
it do
+ expect_allowed(:read_counts)
expect_allowed(*read_group_permissions)
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
@@ -310,6 +324,7 @@ RSpec.describe GroupPolicy do
let(:current_user) { owner }
it do
+ expect_allowed(:read_counts)
expect_allowed(*read_group_permissions)
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
@@ -878,6 +893,34 @@ RSpec.describe GroupPolicy do
end
end
+ describe 'dependency proxy' do
+ context 'feature disabled' do
+ let(:current_user) { owner }
+
+ it { is_expected.to be_disallowed(:read_dependency_proxy) }
+ it { is_expected.to be_disallowed(:admin_dependency_proxy) }
+ end
+
+ context 'feature enabled' do
+ before do
+ stub_config(dependency_proxy: { enabled: true })
+ group.create_dependency_proxy_setting!(enabled: true)
+ end
+
+ context 'reporter' do
+ let(:current_user) { reporter }
+
+ it { is_expected.to be_disallowed(:admin_dependency_proxy) }
+ end
+
+ context 'developer' do
+ let(:current_user) { developer }
+
+ it { is_expected.to be_allowed(:admin_dependency_proxy) }
+ end
+ end
+ end
+
context 'deploy token access' do
let!(:group_deploy_token) do
create(:group_deploy_token, group: group, deploy_token: deploy_token)
@@ -890,6 +933,8 @@ RSpec.describe GroupPolicy do
it { is_expected.to be_allowed(:read_package) }
it { is_expected.to be_allowed(:read_group) }
+ it { is_expected.to be_allowed(:read_organization) }
+ it { is_expected.to be_allowed(:read_contact) }
it { is_expected.to be_disallowed(:create_package) }
end
@@ -899,8 +944,22 @@ RSpec.describe GroupPolicy do
it { is_expected.to be_allowed(:create_package) }
it { is_expected.to be_allowed(:read_package) }
it { is_expected.to be_allowed(:read_group) }
+ it { is_expected.to be_allowed(:read_organization) }
+ it { is_expected.to be_allowed(:read_contact) }
it { is_expected.to be_disallowed(:destroy_package) }
end
+
+ context 'a deploy token with dependency proxy scopes' do
+ let_it_be(:deploy_token) { create(:deploy_token, :group, :dependency_proxy_scopes) }
+
+ before do
+ stub_config(dependency_proxy: { enabled: true })
+ group.create_dependency_proxy_setting!(enabled: true)
+ end
+
+ it { is_expected.to be_allowed(:read_dependency_proxy) }
+ it { is_expected.to be_disallowed(:admin_dependency_proxy) }
+ end
end
it_behaves_like 'Self-managed Core resource access tokens'
diff --git a/spec/policies/issue_policy_spec.rb b/spec/policies/issue_policy_spec.rb
index d62271eedf6..3805976b3e7 100644
--- a/spec/policies/issue_policy_spec.rb
+++ b/spec/policies/issue_policy_spec.rb
@@ -27,17 +27,17 @@ RSpec.describe IssuePolicy do
end
it 'allows support_bot to read issues, create and set metadata on new issues' do
- expect(permissions(support_bot, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
- expect(permissions(support_bot, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
- expect(permissions(support_bot, new_issue)).to be_allowed(:create_issue, :set_issue_metadata)
+ expect(permissions(support_bot, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
+ expect(permissions(support_bot, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
+ expect(permissions(support_bot, new_issue)).to be_allowed(:create_issue, :set_issue_metadata, :set_confidentiality)
end
end
shared_examples 'support bot with service desk disabled' do
- it 'allows support_bot to read issues, create and set metadata on new issues' do
- expect(permissions(support_bot, issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
- expect(permissions(support_bot, issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
- expect(permissions(support_bot, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata)
+ it 'does not allow support_bot to read issues, create and set metadata on new issues' do
+ expect(permissions(support_bot, issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
+ expect(permissions(support_bot, issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
+ expect(permissions(support_bot, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata, :set_confidentiality)
end
end
@@ -60,50 +60,50 @@ RSpec.describe IssuePolicy do
it 'allows guests to read issues' do
expect(permissions(guest, issue)).to be_allowed(:read_issue, :read_issue_iid)
- expect(permissions(guest, issue)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata)
+ expect(permissions(guest, issue)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
expect(permissions(guest, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid)
- expect(permissions(guest, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata)
+ expect(permissions(guest, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
- expect(permissions(guest, new_issue)).to be_allowed(:create_issue, :set_issue_metadata)
+ expect(permissions(guest, new_issue)).to be_allowed(:create_issue, :set_issue_metadata, :set_confidentiality)
end
it 'allows reporters to read, update, and admin issues' do
- expect(permissions(reporter, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
- expect(permissions(reporter, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
- expect(permissions(reporter, new_issue)).to be_allowed(:create_issue, :set_issue_metadata)
+ expect(permissions(reporter, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
+ expect(permissions(reporter, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
+ expect(permissions(reporter, new_issue)).to be_allowed(:create_issue, :set_issue_metadata, :set_confidentiality)
end
it 'allows reporters from group links to read, update, and admin issues' do
- expect(permissions(reporter_from_group_link, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
- expect(permissions(reporter_from_group_link, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
- expect(permissions(reporter_from_group_link, new_issue)).to be_allowed(:create_issue, :set_issue_metadata)
+ expect(permissions(reporter_from_group_link, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
+ expect(permissions(reporter_from_group_link, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
+ expect(permissions(reporter_from_group_link, new_issue)).to be_allowed(:create_issue, :set_issue_metadata, :set_confidentiality)
end
it 'allows issue authors to read and update their issues' do
expect(permissions(author, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue)
- expect(permissions(author, issue)).to be_disallowed(:admin_issue, :set_issue_metadata)
+ expect(permissions(author, issue)).to be_disallowed(:admin_issue, :set_issue_metadata, :set_confidentiality)
expect(permissions(author, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid)
- expect(permissions(author, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata)
+ expect(permissions(author, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
- expect(permissions(author, new_issue)).to be_allowed(:create_issue, :set_issue_metadata)
+ expect(permissions(author, new_issue)).to be_allowed(:create_issue, :set_issue_metadata, :set_confidentiality)
end
it 'allows issue assignees to read and update their issues' do
expect(permissions(assignee, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue)
- expect(permissions(assignee, issue)).to be_disallowed(:admin_issue, :set_issue_metadata)
+ expect(permissions(assignee, issue)).to be_disallowed(:admin_issue, :set_issue_metadata, :set_confidentiality)
expect(permissions(assignee, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid)
- expect(permissions(assignee, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata)
+ expect(permissions(assignee, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
- expect(permissions(assignee, new_issue)).to be_allowed(:create_issue, :set_issue_metadata)
+ expect(permissions(assignee, new_issue)).to be_allowed(:create_issue, :set_issue_metadata, :set_confidentiality)
end
it 'does not allow non-members to read, update or create issues' do
- expect(permissions(non_member, issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
- expect(permissions(non_member, issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
- expect(permissions(non_member, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata)
+ expect(permissions(non_member, issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
+ expect(permissions(non_member, issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
+ expect(permissions(non_member, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata, :set_confidentiality)
end
it_behaves_like 'support bot with service desk disabled'
@@ -115,49 +115,49 @@ RSpec.describe IssuePolicy do
it 'does not allow non-members to read confidential issues' do
expect(permissions(non_member, confidential_issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue)
- expect(permissions(non_member, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
+ expect(permissions(non_member, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
end
it 'does not allow guests to read confidential issues' do
expect(permissions(guest, confidential_issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue)
- expect(permissions(guest, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
+ expect(permissions(guest, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
end
it 'allows reporters to read, update, and admin confidential issues' do
- expect(permissions(reporter, confidential_issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
- expect(permissions(reporter, confidential_issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
+ expect(permissions(reporter, confidential_issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
+ expect(permissions(reporter, confidential_issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
end
it 'allows reporters from group links to read, update, and admin confidential issues' do
- expect(permissions(reporter_from_group_link, confidential_issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
- expect(permissions(reporter_from_group_link, confidential_issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
+ expect(permissions(reporter_from_group_link, confidential_issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
+ expect(permissions(reporter_from_group_link, confidential_issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
end
it 'allows issue authors to read and update their confidential issues' do
expect(permissions(author, confidential_issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue)
- expect(permissions(author, confidential_issue)).to be_disallowed(:admin_issue, :set_issue_metadata)
+ expect(permissions(author, confidential_issue)).to be_disallowed(:admin_issue, :set_issue_metadata, :set_confidentiality)
expect(permissions(author, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue)
- expect(permissions(author, confidential_issue_no_assignee)).to be_disallowed(:admin_issue, :set_issue_metadata)
+ expect(permissions(author, confidential_issue_no_assignee)).to be_disallowed(:admin_issue, :set_issue_metadata, :set_confidentiality)
end
it 'does not allow issue author to read or update confidential issue moved to an private project' do
confidential_issue.project = create(:project, :private)
- expect(permissions(author, confidential_issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :set_issue_metadata)
+ expect(permissions(author, confidential_issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :set_issue_metadata, :set_confidentiality)
end
it 'allows issue assignees to read and update their confidential issues' do
expect(permissions(assignee, confidential_issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue)
- expect(permissions(assignee, confidential_issue)).to be_disallowed(:admin_issue, :set_issue_metadata)
+ expect(permissions(assignee, confidential_issue)).to be_disallowed(:admin_issue, :set_issue_metadata, :set_confidentiality)
- expect(permissions(assignee, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
+ expect(permissions(assignee, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
end
it 'does not allow issue assignees to read or update confidential issue moved to an private project' do
confidential_issue.project = create(:project, :private)
- expect(permissions(assignee, confidential_issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :set_issue_metadata)
+ expect(permissions(assignee, confidential_issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :set_issue_metadata, :set_confidentiality)
end
end
end
@@ -180,48 +180,48 @@ RSpec.describe IssuePolicy do
it 'does not allow anonymous user to create todos' do
expect(permissions(nil, issue)).to be_allowed(:read_issue)
- expect(permissions(nil, issue)).to be_disallowed(:create_todo, :update_subscription, :set_issue_metadata)
- expect(permissions(nil, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata)
+ expect(permissions(nil, issue)).to be_disallowed(:create_todo, :update_subscription, :set_issue_metadata, :set_confidentiality)
+ expect(permissions(nil, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata, :set_confidentiality)
end
it 'allows guests to read issues' do
expect(permissions(guest, issue)).to be_allowed(:read_issue, :read_issue_iid, :create_todo, :update_subscription)
- expect(permissions(guest, issue)).to be_disallowed(:update_issue, :admin_issue, :reopen_issue, :set_issue_metadata)
+ expect(permissions(guest, issue)).to be_disallowed(:update_issue, :admin_issue, :reopen_issue, :set_issue_metadata, :set_confidentiality)
expect(permissions(guest, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid)
- expect(permissions(guest, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :reopen_issue, :set_issue_metadata)
+ expect(permissions(guest, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :reopen_issue, :set_issue_metadata, :set_confidentiality)
expect(permissions(guest, issue_locked)).to be_allowed(:read_issue, :read_issue_iid)
- expect(permissions(guest, issue_locked)).to be_disallowed(:update_issue, :admin_issue, :reopen_issue, :set_issue_metadata)
+ expect(permissions(guest, issue_locked)).to be_disallowed(:update_issue, :admin_issue, :reopen_issue, :set_issue_metadata, :set_confidentiality)
- expect(permissions(guest, new_issue)).to be_allowed(:create_issue, :set_issue_metadata)
+ expect(permissions(guest, new_issue)).to be_allowed(:create_issue, :set_issue_metadata, :set_confidentiality)
end
it 'allows reporters to read, update, reopen, and admin issues' do
- expect(permissions(reporter, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :reopen_issue, :set_issue_metadata)
- expect(permissions(reporter, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :reopen_issue, :set_issue_metadata)
- expect(permissions(reporter, issue_locked)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
+ expect(permissions(reporter, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :reopen_issue, :set_issue_metadata, :set_confidentiality)
+ expect(permissions(reporter, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :reopen_issue, :set_issue_metadata, :set_confidentiality)
+ expect(permissions(reporter, issue_locked)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
expect(permissions(reporter, issue_locked)).to be_disallowed(:reopen_issue)
- expect(permissions(reporter, new_issue)).to be_allowed(:create_issue, :set_issue_metadata)
+ expect(permissions(reporter, new_issue)).to be_allowed(:create_issue, :set_issue_metadata, :set_confidentiality)
end
it 'allows reporters from group links to read, update, reopen and admin issues' do
- expect(permissions(reporter_from_group_link, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :reopen_issue, :set_issue_metadata)
- expect(permissions(reporter_from_group_link, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :reopen_issue, :set_issue_metadata)
- expect(permissions(reporter_from_group_link, issue_locked)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
+ expect(permissions(reporter_from_group_link, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :reopen_issue, :set_issue_metadata, :set_confidentiality)
+ expect(permissions(reporter_from_group_link, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :reopen_issue, :set_issue_metadata, :set_confidentiality)
+ expect(permissions(reporter_from_group_link, issue_locked)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
expect(permissions(reporter_from_group_link, issue_locked)).to be_disallowed(:reopen_issue)
- expect(permissions(reporter, new_issue)).to be_allowed(:create_issue, :set_issue_metadata)
+ expect(permissions(reporter, new_issue)).to be_allowed(:create_issue, :set_issue_metadata, :set_confidentiality)
end
it 'allows issue authors to read, reopen and update their issues' do
expect(permissions(author, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :reopen_issue)
- expect(permissions(author, issue)).to be_disallowed(:admin_issue, :set_issue_metadata)
+ expect(permissions(author, issue)).to be_disallowed(:admin_issue, :set_issue_metadata, :set_confidentiality)
expect(permissions(author, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid)
- expect(permissions(author, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :reopen_issue, :set_issue_metadata)
+ expect(permissions(author, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :reopen_issue, :set_issue_metadata, :set_confidentiality)
expect(permissions(author, issue_locked)).to be_allowed(:read_issue, :read_issue_iid, :update_issue)
- expect(permissions(author, issue_locked)).to be_disallowed(:admin_issue, :reopen_issue, :set_issue_metadata)
+ expect(permissions(author, issue_locked)).to be_disallowed(:admin_issue, :reopen_issue, :set_issue_metadata, :set_confidentiality)
expect(permissions(author, new_issue)).to be_allowed(:create_issue)
expect(permissions(author, new_issue)).to be_disallowed(:set_issue_metadata)
@@ -229,13 +229,13 @@ RSpec.describe IssuePolicy do
it 'allows issue assignees to read, reopen and update their issues' do
expect(permissions(assignee, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :reopen_issue)
- expect(permissions(assignee, issue)).to be_disallowed(:admin_issue, :set_issue_metadata)
+ expect(permissions(assignee, issue)).to be_disallowed(:admin_issue, :set_issue_metadata, :set_confidentiality)
expect(permissions(assignee, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid)
- expect(permissions(assignee, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :reopen_issue, :set_issue_metadata)
+ expect(permissions(assignee, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :reopen_issue, :set_issue_metadata, :set_confidentiality)
expect(permissions(assignee, issue_locked)).to be_allowed(:read_issue, :read_issue_iid, :update_issue)
- expect(permissions(assignee, issue_locked)).to be_disallowed(:admin_issue, :reopen_issue, :set_issue_metadata)
+ expect(permissions(assignee, issue_locked)).to be_disallowed(:admin_issue, :reopen_issue, :set_issue_metadata, :set_confidentiality)
end
it 'allows non-members to read and create issues' do
@@ -249,22 +249,25 @@ RSpec.describe IssuePolicy do
expect(permissions(non_member, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid)
end
- it 'does not allow non-members to update, admin or set metadata' do
- expect(permissions(non_member, issue)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata)
- expect(permissions(non_member, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata)
+ it 'does not allow non-members to update, admin or set metadata except for set confidential flag' do
+ expect(permissions(non_member, issue)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
+ expect(permissions(non_member, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
expect(permissions(non_member, new_issue)).to be_disallowed(:set_issue_metadata)
+ # this is allowed for non-members in a public project, as we want to let users report security issues
+ # see https://gitlab.com/gitlab-org/gitlab/-/issues/337665
+ expect(permissions(non_member, new_issue)).to be_allowed(:set_confidentiality)
end
it 'allows support_bot to read issues' do
# support_bot is still allowed read access in public projects through :public_access permission,
# see project_policy public_access rules policy (rule { can?(:public_access) }.policy {...})
expect(permissions(support_bot, issue)).to be_allowed(:read_issue, :read_issue_iid)
- expect(permissions(support_bot, issue)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata)
+ expect(permissions(support_bot, issue)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
expect(permissions(support_bot, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid)
- expect(permissions(support_bot, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata)
+ expect(permissions(support_bot, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
- expect(permissions(support_bot, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata)
+ expect(permissions(support_bot, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata, :set_confidentiality)
end
it_behaves_like 'support bot with service desk enabled'
@@ -318,9 +321,9 @@ RSpec.describe IssuePolicy do
end
it 'does not allow non-members to update or create issues' do
- expect(permissions(non_member, issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
- expect(permissions(non_member, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata)
- expect(permissions(non_member, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata)
+ expect(permissions(non_member, issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
+ expect(permissions(non_member, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
+ expect(permissions(non_member, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata, :set_confidentiality)
end
it_behaves_like 'support bot with service desk disabled'
@@ -333,31 +336,31 @@ RSpec.describe IssuePolicy do
it 'does not allow guests to read confidential issues' do
expect(permissions(guest, confidential_issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue)
- expect(permissions(guest, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
+ expect(permissions(guest, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
end
it 'allows reporters to read, update, and admin confidential issues' do
expect(permissions(reporter, confidential_issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue)
- expect(permissions(reporter, confidential_issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
+ expect(permissions(reporter, confidential_issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
end
it 'allows reporter from group links to read, update, and admin confidential issues' do
expect(permissions(reporter_from_group_link, confidential_issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue)
- expect(permissions(reporter_from_group_link, confidential_issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
+ expect(permissions(reporter_from_group_link, confidential_issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
end
it 'allows issue authors to read and update their confidential issues' do
expect(permissions(author, confidential_issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue)
- expect(permissions(author, confidential_issue)).to be_disallowed(:admin_issue, :set_issue_metadata)
+ expect(permissions(author, confidential_issue)).to be_disallowed(:admin_issue, :set_issue_metadata, :set_confidentiality)
- expect(permissions(author, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
+ expect(permissions(author, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
end
it 'allows issue assignees to read and update their confidential issues' do
expect(permissions(assignee, confidential_issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue)
- expect(permissions(assignee, confidential_issue)).to be_disallowed(:admin_issue, :set_issue_metadata)
+ expect(permissions(assignee, confidential_issue)).to be_disallowed(:admin_issue, :set_issue_metadata, :set_confidentiality)
- expect(permissions(assignee, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata)
+ expect(permissions(assignee, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
end
end
diff --git a/spec/policies/user_policy_spec.rb b/spec/policies/user_policy_spec.rb
index 78212f06526..b800e7dbc43 100644
--- a/spec/policies/user_policy_spec.rb
+++ b/spec/policies/user_policy_spec.rb
@@ -3,8 +3,12 @@
require 'spec_helper'
RSpec.describe UserPolicy do
- let(:current_user) { create(:user) }
- let(:user) { create(:user) }
+ let_it_be(:admin) { create(:user, :admin) }
+ let_it_be(:regular_user) { create(:user) }
+ let_it_be(:subject_user) { create(:user) }
+
+ let(:current_user) { regular_user }
+ let(:user) { subject_user }
subject { described_class.new(current_user, user) }
@@ -16,7 +20,7 @@ RSpec.describe UserPolicy do
let(:token) { create(:personal_access_token, user: user) }
context 'when user is admin' do
- let(:current_user) { create(:user, :admin) }
+ let(:current_user) { admin }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed(:read_user_personal_access_tokens) }
@@ -42,7 +46,7 @@ RSpec.describe UserPolicy do
describe "creating a different user's Personal Access Tokens" do
context 'when current_user is admin' do
- let(:current_user) { create(:user, :admin) }
+ let(:current_user) { admin }
context 'when admin mode is enabled and current_user is not blocked', :enable_admin_mode do
it { is_expected.to be_allowed(:create_user_personal_access_token) }
@@ -92,7 +96,7 @@ RSpec.describe UserPolicy do
end
context "when an admin user tries to destroy a regular user" do
- let(:current_user) { create(:user, :admin) }
+ let(:current_user) { admin }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed(ability) }
@@ -104,7 +108,7 @@ RSpec.describe UserPolicy do
end
context "when an admin user tries to destroy a ghost user" do
- let(:current_user) { create(:user, :admin) }
+ let(:current_user) { admin }
let(:user) { create(:user, :ghost) }
it { is_expected.not_to be_allowed(ability) }
@@ -132,7 +136,7 @@ RSpec.describe UserPolicy do
context 'disabling the two-factor authentication of another user' do
context 'when the executor is an admin', :enable_admin_mode do
- let(:current_user) { create(:user, :admin) }
+ let(:current_user) { admin }
it { is_expected.to be_allowed(:disable_two_factor) }
end
@@ -145,7 +149,7 @@ RSpec.describe UserPolicy do
describe "reading a user's group count" do
context "when current_user is an admin", :enable_admin_mode do
- let(:current_user) { create(:user, :admin) }
+ let(:current_user) { admin }
it { is_expected.to be_allowed(:read_group_count) }
end
@@ -172,4 +176,30 @@ RSpec.describe UserPolicy do
it { is_expected.to be_allowed(:read_user_profile) }
end
end
+
+ describe ':read_user_groups' do
+ context 'when user is admin' do
+ let(:current_user) { admin }
+
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it { is_expected.to be_allowed(:read_user_groups) }
+ end
+
+ context 'when admin mode is disabled' do
+ it { is_expected.not_to be_allowed(:read_user_groups) }
+ end
+ end
+
+ context 'when user is not an admin' do
+ context 'requesting their own manageable groups' do
+ subject { described_class.new(current_user, current_user) }
+
+ it { is_expected.to be_allowed(:read_user_groups) }
+ end
+
+ context "requesting a different user's manageable groups" do
+ it { is_expected.not_to be_allowed(:read_user_groups) }
+ end
+ end
+ end
end
diff --git a/spec/presenters/packages/helm/index_presenter_spec.rb b/spec/presenters/packages/helm/index_presenter_spec.rb
new file mode 100644
index 00000000000..38e1dc17f49
--- /dev/null
+++ b/spec/presenters/packages/helm/index_presenter_spec.rb
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Packages::Helm::IndexPresenter do
+ include_context 'with expected presenters dependency groups'
+
+ let_it_be(:project) { create(:project) }
+ let_it_be(:packages) { create_list(:helm_package, 5, project: project) }
+ let_it_be(:package_files3_1) { create(:helm_package_file, package: packages[2], file_sha256: '3_1', file_name: 'file3_1') }
+ let_it_be(:package_files3_2) { create(:helm_package_file, package: packages[2], file_sha256: '3_2', file_name: 'file3_2') }
+ let_it_be(:package_files4_1) { create(:helm_package_file, package: packages[3], file_sha256: '4_1', file_name: 'file4_1') }
+ let_it_be(:package_files4_2) { create(:helm_package_file, package: packages[3], file_sha256: '4_2', file_name: 'file4_2') }
+ let_it_be(:package_files4_3) { create(:helm_package_file, package: packages[3], file_sha256: '4_3', file_name: 'file4_3') }
+
+ let(:project_id_param) { project.id }
+ let(:channel) { 'stable' }
+ let(:presenter) { described_class.new(project_id_param, channel, ::Packages::Package.id_in(packages.map(&:id))) }
+
+ describe('#entries') do
+ subject { presenter.entries }
+
+ it 'returns the correct hash' do
+ expect(subject.size).to eq(5)
+ expect(subject.keys).to eq(packages.map(&:name))
+ subject.values.zip(packages) do |raws, pkg|
+ expect(raws.size).to eq(1)
+
+ file = pkg.package_files.recent.first
+ raw = raws.first
+ expect(raw['name']).to eq(pkg.name)
+ expect(raw['version']).to eq(pkg.version)
+ expect(raw['apiVersion']).to eq("v2")
+ expect(raw['created']).to eq(file.created_at.utc.strftime('%Y-%m-%dT%H:%M:%S.%NZ'))
+ expect(raw['digest']).to eq(file.file_sha256)
+ expect(raw['urls']).to eq(["charts/#{file.file_name}"])
+ end
+ end
+
+ context 'with an unknown channel' do
+ let(:channel) { 'unknown' }
+
+ it { is_expected.to be_empty }
+ end
+
+ context 'with a nil channel' do
+ let(:channel) { nil }
+
+ it { is_expected.to be_empty }
+ end
+ end
+
+ describe('#api_version') do
+ subject { presenter.api_version }
+
+ it { is_expected.to eq(described_class::API_VERSION) }
+ end
+
+ describe('#generated') do
+ subject { presenter.generated }
+
+ it 'returns the expected format' do
+ freeze_time do
+ expect(subject).to eq(Time.zone.now.utc.strftime('%Y-%m-%dT%H:%M:%S.%NZ'))
+ end
+ end
+ end
+
+ describe('#server_info') do
+ subject { presenter.server_info }
+
+ it { is_expected.to eq({ 'contextPath' => "/api/v4/projects/#{project.id}/packages/helm" }) }
+
+ context 'with url encoded project id param' do
+ let_it_be(:project_id_param) { 'foo/bar' }
+
+ it { is_expected.to eq({ 'contextPath' => '/api/v4/projects/foo%2Fbar/packages/helm' }) }
+ end
+ end
+end
diff --git a/spec/presenters/packages/npm/package_presenter_spec.rb b/spec/presenters/packages/npm/package_presenter_spec.rb
index e524edaadc6..65f69d4056b 100644
--- a/spec/presenters/packages/npm/package_presenter_spec.rb
+++ b/spec/presenters/packages/npm/package_presenter_spec.rb
@@ -5,10 +5,10 @@ require 'spec_helper'
RSpec.describe ::Packages::Npm::PackagePresenter do
let_it_be(:project) { create(:project) }
let_it_be(:package_name) { "@#{project.root_namespace.path}/test" }
+ let_it_be(:package1) { create(:npm_package, version: '2.0.4', project: project, name: package_name) }
+ let_it_be(:package2) { create(:npm_package, version: '2.0.6', project: project, name: package_name) }
+ let_it_be(:latest_package) { create(:npm_package, version: '2.0.11', project: project, name: package_name) }
- let!(:package1) { create(:npm_package, version: '1.0.4', project: project, name: package_name) }
- let!(:package2) { create(:npm_package, version: '1.0.6', project: project, name: package_name) }
- let!(:latest_package) { create(:npm_package, version: '1.0.11', project: project, name: package_name) }
let(:packages) { project.packages.npm.with_name(package_name).last_of_each_version }
let(:presenter) { described_class.new(package_name, packages) }
@@ -20,23 +20,39 @@ RSpec.describe ::Packages::Npm::PackagePresenter do
it { expect(subject[package1.version].with_indifferent_access).to match_schema('public_api/v4/packages/npm_package_version') }
it { expect(subject[package2.version].with_indifferent_access).to match_schema('public_api/v4/packages/npm_package_version') }
- described_class::NPM_VALID_DEPENDENCY_TYPES.each do |dependency_type|
+ ::Packages::DependencyLink.dependency_types.keys.each do |dependency_type|
it { expect(subject.dig(package1.version, dependency_type)).to be nil }
it { expect(subject.dig(package2.version, dependency_type)).to be nil }
end
+
+ it 'avoids N+1 database queries' do
+ check_n_plus_one(:versions) do
+ create_list(:npm_package, 5, project: project, name: package_name)
+ end
+ end
end
context 'for packages with dependencies' do
- described_class::NPM_VALID_DEPENDENCY_TYPES.each do |dependency_type|
- let!("package_dependency_link_for_#{dependency_type}") { create(:packages_dependency_link, package: package1, dependency_type: dependency_type) }
+ ::Packages::DependencyLink.dependency_types.keys.each do |dependency_type|
+ let_it_be("package_dependency_link_for_#{dependency_type}") { create(:packages_dependency_link, package: package1, dependency_type: dependency_type) }
end
it { is_expected.to be_a(Hash) }
it { expect(subject[package1.version].with_indifferent_access).to match_schema('public_api/v4/packages/npm_package_version') }
it { expect(subject[package2.version].with_indifferent_access).to match_schema('public_api/v4/packages/npm_package_version') }
- described_class::NPM_VALID_DEPENDENCY_TYPES.each do |dependency_type|
+ ::Packages::DependencyLink.dependency_types.keys.each do |dependency_type|
it { expect(subject.dig(package1.version, dependency_type.to_s)).to be_any }
end
+
+ it 'avoids N+1 database queries' do
+ check_n_plus_one(:versions) do
+ create_list(:npm_package, 5, project: project, name: package_name).each do |npm_package|
+ ::Packages::DependencyLink.dependency_types.keys.each do |dependency_type|
+ create(:packages_dependency_link, package: npm_package, dependency_type: dependency_type)
+ end
+ end
+ end
+ end
end
end
@@ -46,14 +62,20 @@ RSpec.describe ::Packages::Npm::PackagePresenter do
context 'for packages without tags' do
it { is_expected.to be_a(Hash) }
it { expect(subject["latest"]).to eq(latest_package.version) }
+
+ it 'avoids N+1 database queries' do
+ check_n_plus_one(:dist_tags) do
+ create_list(:npm_package, 5, project: project, name: package_name)
+ end
+ end
end
context 'for packages with tags' do
- let!(:package_tag1) { create(:packages_tag, package: package1, name: 'release_a') }
- let!(:package_tag2) { create(:packages_tag, package: package1, name: 'test_release') }
- let!(:package_tag3) { create(:packages_tag, package: package2, name: 'release_b') }
- let!(:package_tag4) { create(:packages_tag, package: latest_package, name: 'release_c') }
- let!(:package_tag5) { create(:packages_tag, package: latest_package, name: 'latest') }
+ let_it_be(:package_tag1) { create(:packages_tag, package: package1, name: 'release_a') }
+ let_it_be(:package_tag2) { create(:packages_tag, package: package1, name: 'test_release') }
+ let_it_be(:package_tag3) { create(:packages_tag, package: package2, name: 'release_b') }
+ let_it_be(:package_tag4) { create(:packages_tag, package: latest_package, name: 'release_c') }
+ let_it_be(:package_tag5) { create(:packages_tag, package: latest_package, name: 'latest') }
it { is_expected.to be_a(Hash) }
it { expect(subject[package_tag1.name]).to eq(package1.version) }
@@ -61,6 +83,25 @@ RSpec.describe ::Packages::Npm::PackagePresenter do
it { expect(subject[package_tag3.name]).to eq(package2.version) }
it { expect(subject[package_tag4.name]).to eq(latest_package.version) }
it { expect(subject[package_tag5.name]).to eq(latest_package.version) }
+
+ it 'avoids N+1 database queries' do
+ check_n_plus_one(:dist_tags) do
+ create_list(:npm_package, 5, project: project, name: package_name).each_with_index do |npm_package, index|
+ create(:packages_tag, package: npm_package, name: "tag_#{index}")
+ end
+ end
+ end
end
end
+
+ def check_n_plus_one(field)
+ pkgs = project.packages.npm.with_name(package_name).last_of_each_version.preload_files
+ control = ActiveRecord::QueryRecorder.new { described_class.new(package_name, pkgs).public_send(field) }
+
+ yield
+
+ pkgs = project.packages.npm.with_name(package_name).last_of_each_version.preload_files
+
+ expect { described_class.new(package_name, pkgs).public_send(field) }.not_to exceed_query_limit(control)
+ end
end
diff --git a/spec/presenters/project_presenter_spec.rb b/spec/presenters/project_presenter_spec.rb
index fd75c8411d5..5f789f59908 100644
--- a/spec/presenters/project_presenter_spec.rb
+++ b/spec/presenters/project_presenter_spec.rb
@@ -649,36 +649,18 @@ RSpec.describe ProjectPresenter do
end
end
- describe 'experiment(:repo_integrations_link)' do
- context 'when enabled' do
- before do
- stub_experiments(repo_integrations_link: :candidate)
- end
-
- it 'includes a button to configure integrations for maintainers' do
- project.add_maintainer(user)
-
- expect(empty_repo_statistics_buttons.map(&:label)).to include(
- a_string_including('Configure Integration')
- )
- end
-
- it 'does not include a button if not a maintainer' do
- expect(empty_repo_statistics_buttons.map(&:label)).not_to include(
- a_string_including('Configure Integration')
- )
- end
- end
+ it 'includes a button to configure integrations for maintainers' do
+ project.add_maintainer(user)
- context 'when disabled' do
- it 'does not include a button' do
- project.add_maintainer(user)
+ expect(empty_repo_statistics_buttons.map(&:label)).to include(
+ a_string_including('Configure Integration')
+ )
+ end
- expect(empty_repo_statistics_buttons.map(&:label)).not_to include(
- a_string_including('Configure Integration')
- )
- end
- end
+ it 'does not include a button if not a maintainer' do
+ expect(empty_repo_statistics_buttons.map(&:label)).not_to include(
+ a_string_including('Configure Integration')
+ )
end
context 'for a developer' do
diff --git a/spec/presenters/snippet_blob_presenter_spec.rb b/spec/presenters/snippet_blob_presenter_spec.rb
index 1a5130dcdf6..d7f56c30b5e 100644
--- a/spec/presenters/snippet_blob_presenter_spec.rb
+++ b/spec/presenters/snippet_blob_presenter_spec.rb
@@ -10,6 +10,7 @@ RSpec.describe SnippetBlobPresenter do
describe '#rich_data' do
let(:data_endpoint_url) { "/-/snippets/#{snippet.id}/raw/#{branch}/#{file}" }
+ let(:data_raw_dir) { "/-/snippets/#{snippet.id}/raw/#{branch}/" }
before do
allow_next_instance_of(described_class) do |instance|
@@ -45,7 +46,7 @@ RSpec.describe SnippetBlobPresenter do
let(:file) { 'test.ipynb' }
it 'returns rich notebook content' do
- expect(subject.strip).to eq %Q(<div class="file-content" data-endpoint="#{data_endpoint_url}" id="js-notebook-viewer"></div>)
+ expect(subject.strip).to eq %Q(<div class="file-content" data-endpoint="#{data_endpoint_url}" data-relative-raw-path="#{data_raw_dir}" id="js-notebook-viewer"></div>)
end
end
diff --git a/spec/rake_helper.rb b/spec/rake_helper.rb
index 7df1cf7444f..ca5b4d8337c 100644
--- a/spec/rake_helper.rb
+++ b/spec/rake_helper.rb
@@ -12,6 +12,6 @@ RSpec.configure do |config|
end
config.after(:all) do
- delete_from_all_tables!
+ delete_from_all_tables!(except: deletion_except_tables)
end
end
diff --git a/spec/requests/admin/background_migrations_controller_spec.rb b/spec/requests/admin/background_migrations_controller_spec.rb
new file mode 100644
index 00000000000..c7d5d5cae08
--- /dev/null
+++ b/spec/requests/admin/background_migrations_controller_spec.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Admin::BackgroundMigrationsController, :enable_admin_mode do
+ let(:admin) { create(:admin) }
+
+ before do
+ sign_in(admin)
+ end
+
+ describe 'POST #retry' do
+ let(:migration) { create(:batched_background_migration, status: 'failed') }
+
+ before do
+ create(:batched_background_migration_job, batched_migration: migration, batch_size: 10, min_value: 6, max_value: 15, status: :failed, attempts: 3)
+
+ allow_next_instance_of(Gitlab::BackgroundMigration::BatchingStrategies::PrimaryKeyBatchingStrategy) do |batch_class|
+ allow(batch_class).to receive(:next_batch).with(anything, anything, batch_min_value: 6, batch_size: 5).and_return([6, 10])
+ end
+ end
+
+ subject(:retry_migration) { post retry_admin_background_migration_path(migration) }
+
+ it 'redirects the user to the admin migrations page' do
+ retry_migration
+
+ expect(response).to redirect_to(admin_background_migrations_path)
+ end
+
+ it 'retries the migration' do
+ retry_migration
+
+ expect(migration.reload.status).to eql 'active'
+ end
+
+ context 'when the migration is not failed' do
+ let(:migration) { create(:batched_background_migration, status: 'paused') }
+
+ it 'keeps the same migration status' do
+ expect { retry_migration }.not_to change { migration.reload.status }
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/admin/sidekiq_spec.rb b/spec/requests/api/admin/sidekiq_spec.rb
index 3c488816bed..1e626c90e7e 100644
--- a/spec/requests/api/admin/sidekiq_spec.rb
+++ b/spec/requests/api/admin/sidekiq_spec.rb
@@ -36,7 +36,7 @@ RSpec.describe API::Admin::Sidekiq, :clean_gitlab_redis_queues do
add_job(admin, [2])
add_job(create(:user), [3])
- delete api("/admin/sidekiq/queues/authorized_projects?user=#{admin.username}", admin)
+ delete api("/admin/sidekiq/queues/authorized_projects?user=#{admin.username}&worker_class=AuthorizedProjectsWorker", admin)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to eq('completed' => true,
diff --git a/spec/requests/api/ci/pipelines_spec.rb b/spec/requests/api/ci/pipelines_spec.rb
index 640e1ee6422..7ae350885f4 100644
--- a/spec/requests/api/ci/pipelines_spec.rb
+++ b/spec/requests/api/ci/pipelines_spec.rb
@@ -37,24 +37,10 @@ RSpec.describe API::Ci::Pipelines do
end
describe 'keys in the response' do
- context 'when `pipeline_source_filter` feature flag is disabled' do
- before do
- stub_feature_flags(pipeline_source_filter: false)
- end
+ it 'includes pipeline source' do
+ get api("/projects/#{project.id}/pipelines", user)
- it 'does not includes pipeline source' do
- get api("/projects/#{project.id}/pipelines", user)
-
- expect(json_response.first.keys).to contain_exactly(*%w[id project_id sha ref status web_url created_at updated_at])
- end
- end
-
- context 'when `pipeline_source_filter` feature flag is disabled' do
- it 'includes pipeline source' do
- get api("/projects/#{project.id}/pipelines", user)
-
- expect(json_response.first.keys).to contain_exactly(*%w[id project_id sha ref status web_url created_at updated_at source])
- end
+ expect(json_response.first.keys).to contain_exactly(*%w[id project_id sha ref status web_url created_at updated_at source])
end
end
@@ -182,30 +168,6 @@ RSpec.describe API::Ci::Pipelines do
end
end
- context 'when name is specified' do
- let_it_be(:pipeline) { create(:ci_pipeline, project: project, user: user) }
-
- context 'when name exists' do
- it 'returns matched pipelines' do
- get api("/projects/#{project.id}/pipelines", user), params: { name: user.name }
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(response).to include_pagination_headers
- expect(json_response.first['id']).to eq(pipeline.id)
- end
- end
-
- context 'when name does not exist' do
- it 'returns empty' do
- get api("/projects/#{project.id}/pipelines", user), params: { name: 'invalid-name' }
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(response).to include_pagination_headers
- expect(json_response).to be_empty
- end
- end
- end
-
context 'when username is specified' do
let_it_be(:pipeline) { create(:ci_pipeline, project: project, user: user) }
@@ -323,37 +285,20 @@ RSpec.describe API::Ci::Pipelines do
create(:ci_pipeline, project: project, source: :api)
end
- context 'when `pipeline_source_filter` feature flag is disabled' do
- before do
- stub_feature_flags(pipeline_source_filter: false)
- end
-
- it 'returns all pipelines' do
- get api("/projects/#{project.id}/pipelines", user), params: { source: 'web' }
+ it 'returns matched pipelines' do
+ get api("/projects/#{project.id}/pipelines", user), params: { source: 'web' }
- expect(response).to have_gitlab_http_status(:ok)
- expect(response).to include_pagination_headers
- expect(json_response).not_to be_empty
- expect(json_response.length).to be >= 3
- end
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to include_pagination_headers
+ expect(json_response).not_to be_empty
+ json_response.each { |r| expect(r['source']).to eq('web') }
end
- context 'when `pipeline_source_filter` feature flag is enabled' do
- it 'returns matched pipelines' do
- get api("/projects/#{project.id}/pipelines", user), params: { source: 'web' }
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(response).to include_pagination_headers
- expect(json_response).not_to be_empty
- json_response.each { |r| expect(r['source']).to eq('web') }
- end
-
- context 'when source is invalid' do
- it 'returns bad_request' do
- get api("/projects/#{project.id}/pipelines", user), params: { source: 'invalid-source' }
+ context 'when source is invalid' do
+ it 'returns bad_request' do
+ get api("/projects/#{project.id}/pipelines", user), params: { source: 'invalid-source' }
- expect(response).to have_gitlab_http_status(:bad_request)
- end
+ expect(response).to have_gitlab_http_status(:bad_request)
end
end
end
diff --git a/spec/requests/api/ci/runners_reset_registration_token_spec.rb b/spec/requests/api/ci/runners_reset_registration_token_spec.rb
new file mode 100644
index 00000000000..7623d3f1b17
--- /dev/null
+++ b/spec/requests/api/ci/runners_reset_registration_token_spec.rb
@@ -0,0 +1,149 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::Ci::Runners do
+ subject { post api("#{prefix}/runners/reset_registration_token", user) }
+
+ shared_examples 'bad request' do |result|
+ it 'returns 400 error' do
+ expect { subject }.not_to change { get_token }
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response).to eq(result)
+ end
+ end
+
+ shared_examples 'unauthenticated' do
+ it 'returns 401 error' do
+ expect { subject }.not_to change { get_token }
+
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
+ end
+
+ shared_examples 'unauthorized' do
+ it 'returns 403 error' do
+ expect { subject }.not_to change { get_token }
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
+ end
+
+ shared_examples 'not found' do |scope|
+ it 'returns 404 error' do
+ expect { subject }.not_to change { get_token }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(json_response).to eq({ 'message' => "404 #{scope.capitalize} Not Found" })
+ end
+ end
+
+ shared_context 'when unauthorized' do |scope|
+ context 'when unauthorized' do
+ let_it_be(:user) { create(:user) }
+
+ context "when not a #{scope} member" do
+ it_behaves_like 'not found', scope
+ end
+
+ context "with a non-admin #{scope} member" do
+ before do
+ target.add_developer(user)
+ end
+
+ it_behaves_like 'unauthorized'
+ end
+ end
+ end
+
+ shared_context 'when authorized' do |scope|
+ it 'resets runner registration token' do
+ expect { subject }.to change { get_token }
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(json_response).to eq({ 'token' => get_token })
+ end
+
+ if scope != 'instance'
+ context 'when malformed id is provided' do
+ let(:prefix) { "/#{scope.pluralize}/some%20string" }
+
+ it_behaves_like 'not found', scope
+ end
+ end
+ end
+
+ describe '/api/v4/runners/reset_registration_token' do
+ describe 'POST /api/v4/runners/reset_registration_token' do
+ before do
+ ApplicationSetting.create_from_defaults
+ stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
+ end
+
+ let(:prefix) { '' }
+
+ context 'when unauthenticated' do
+ let(:user) { nil }
+
+ it_behaves_like 'unauthenticated'
+ end
+
+ context 'when unauthorized' do
+ let(:user) { create(:user) }
+
+ context "with a non-admin instance member" do
+ it_behaves_like 'unauthorized'
+ end
+ end
+
+ include_context 'when authorized', 'instance' do
+ let_it_be(:user) { create(:user, :admin) }
+
+ def get_token
+ ApplicationSetting.current_without_cache.runners_registration_token
+ end
+ end
+ end
+ end
+
+ describe '/api/v4/groups/:id/runners/reset_registration_token' do
+ describe 'POST /api/v4/groups/:id/runners/reset_registration_token' do
+ let_it_be(:group) { create_default(:group, :private) }
+
+ let(:prefix) { "/groups/#{group.id}" }
+
+ include_context 'when unauthorized', 'group' do
+ let(:target) { group }
+ end
+
+ include_context 'when authorized', 'group' do
+ let_it_be(:user) { create_default(:group_member, :maintainer, user: create(:user), group: group ).user }
+
+ def get_token
+ group.reload.runners_token
+ end
+ end
+ end
+ end
+
+ describe '/api/v4/projects/:id/runners/reset_registration_token' do
+ describe 'POST /api/v4/projects/:id/runners/reset_registration_token' do
+ let_it_be(:project) { create_default(:project) }
+
+ let(:prefix) { "/projects/#{project.id}" }
+
+ include_context 'when unauthorized', 'project' do
+ let(:target) { project }
+ end
+
+ include_context 'when authorized', 'project' do
+ let_it_be(:user) { project.owner }
+
+ def get_token
+ project.reload.runners_token
+ end
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/commit_statuses_spec.rb b/spec/requests/api/commit_statuses_spec.rb
index ccc9f8c50c4..47bc3eb74a6 100644
--- a/spec/requests/api/commit_statuses_spec.rb
+++ b/spec/requests/api/commit_statuses_spec.rb
@@ -345,38 +345,12 @@ RSpec.describe API::CommitStatuses do
expect(json_response['status']).to eq('success')
end
- context 'feature flags' do
- using RSpec::Parameterized::TableSyntax
-
- where(:ci_fix_commit_status_retried, :ci_remove_update_retried_from_process_pipeline, :previous_statuses_retried) do
- true | true | true
- true | false | true
- false | true | false
- false | false | true
- end
-
- with_them do
- before do
- stub_feature_flags(
- ci_fix_commit_status_retried: ci_fix_commit_status_retried,
- ci_remove_update_retried_from_process_pipeline: ci_remove_update_retried_from_process_pipeline
- )
- end
-
- it 'retries a commit status', :sidekiq_might_not_need_inline do
- post_request
-
- expect(CommitStatus.count).to eq 2
+ it 'retries the commit status', :sidekiq_might_not_need_inline do
+ post_request
- if previous_statuses_retried
- expect(CommitStatus.first).to be_retried
- expect(CommitStatus.last.pipeline).to be_success
- else
- expect(CommitStatus.first).not_to be_retried
- expect(CommitStatus.last.pipeline).to be_failed
- end
- end
- end
+ expect(CommitStatus.count).to eq 2
+ expect(CommitStatus.first).to be_retried
+ expect(CommitStatus.last.pipeline).to be_success
end
end
diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb
index 1162ae76d15..1d76c281dee 100644
--- a/spec/requests/api/commits_spec.rb
+++ b/spec/requests/api/commits_spec.rb
@@ -1879,6 +1879,26 @@ RSpec.describe API::Commits do
expect(json_response['line_type']).to eq('new')
end
+ it 'correctly adds a note for the "old" line type' do
+ commit = project.repository.commit("markdown")
+ commit_id = commit.id
+ route = "/projects/#{project_id}/repository/commits/#{commit_id}/comments"
+
+ post api(route, current_user), params: {
+ note: 'My comment',
+ path: commit.raw_diffs.first.old_path,
+ line: 4,
+ line_type: 'old'
+ }
+
+ expect(response).to have_gitlab_http_status(:created)
+ expect(response).to match_response_schema('public_api/v4/commit_note')
+ expect(json_response['note']).to eq('My comment')
+ expect(json_response['path']).to eq(commit.raw_diffs.first.old_path)
+ expect(json_response['line']).to eq(4)
+ expect(json_response['line_type']).to eq('old')
+ end
+
context 'when ref does not exist' do
let(:commit_id) { 'unknown' }
diff --git a/spec/requests/api/dependency_proxy_spec.rb b/spec/requests/api/dependency_proxy_spec.rb
index d59f2bf06e3..2837d1c02c4 100644
--- a/spec/requests/api/dependency_proxy_spec.rb
+++ b/spec/requests/api/dependency_proxy_spec.rb
@@ -13,60 +13,74 @@ RSpec.describe API::DependencyProxy, api: true do
group.add_owner(user)
stub_config(dependency_proxy: { enabled: true })
stub_last_activity_update
- group.create_dependency_proxy_setting!(enabled: true)
end
describe 'DELETE /groups/:id/dependency_proxy/cache' do
- subject { delete api("/groups/#{group.id}/dependency_proxy/cache", user) }
+ subject { delete api("/groups/#{group_id}/dependency_proxy/cache", user) }
- context 'with feature available and enabled' do
- let_it_be(:lease_key) { "dependency_proxy:delete_group_blobs:#{group.id}" }
+ shared_examples 'responding to purge requests' do
+ context 'with feature available and enabled' do
+ let_it_be(:lease_key) { "dependency_proxy:delete_group_blobs:#{group.id}" }
- context 'an admin user' do
- it 'deletes the blobs and returns no content' do
- stub_exclusive_lease(lease_key, timeout: 1.hour)
- expect(PurgeDependencyProxyCacheWorker).to receive(:perform_async)
+ context 'an admin user' do
+ it 'deletes the blobs and returns no content' do
+ stub_exclusive_lease(lease_key, timeout: 1.hour)
+ expect(PurgeDependencyProxyCacheWorker).to receive(:perform_async)
- subject
+ subject
- expect(response).to have_gitlab_http_status(:no_content)
- end
+ expect(response).to have_gitlab_http_status(:accepted)
+ expect(response.body).to eq('202')
+ end
- context 'called multiple times in one hour', :clean_gitlab_redis_shared_state do
- it 'returns 409 with an error message' do
- stub_exclusive_lease_taken(lease_key, timeout: 1.hour)
+ context 'called multiple times in one hour', :clean_gitlab_redis_shared_state do
+ it 'returns 409 with an error message' do
+ stub_exclusive_lease_taken(lease_key, timeout: 1.hour)
- subject
+ subject
- expect(response).to have_gitlab_http_status(:conflict)
- expect(response.body).to include('This request has already been made.')
+ expect(response).to have_gitlab_http_status(:conflict)
+ expect(response.body).to include('This request has already been made.')
+ end
+
+ it 'executes service only for the first time' do
+ expect(PurgeDependencyProxyCacheWorker).to receive(:perform_async).once
+
+ 2.times { subject }
+ end
end
+ end
- it 'executes service only for the first time' do
- expect(PurgeDependencyProxyCacheWorker).to receive(:perform_async).once
+ context 'a non-admin' do
+ let(:user) { create(:user) }
- 2.times { subject }
+ before do
+ group.add_maintainer(user)
end
+
+ it_behaves_like 'returning response status', :forbidden
end
end
- context 'a non-admin' do
- let(:user) { create(:user) }
-
+ context 'depencency proxy is not enabled in the config' do
before do
- group.add_maintainer(user)
+ stub_config(dependency_proxy: { enabled: false })
end
- it_behaves_like 'returning response status', :forbidden
+ it_behaves_like 'returning response status', :not_found
end
end
- context 'depencency proxy is not enabled' do
- before do
- stub_config(dependency_proxy: { enabled: false })
- end
+ context 'with a group id' do
+ let(:group_id) { group.id }
+
+ it_behaves_like 'responding to purge requests'
+ end
+
+ context 'with an url encoded group id' do
+ let(:group_id) { ERB::Util.url_encode(group.full_path) }
- it_behaves_like 'returning response status', :not_found
+ it_behaves_like 'responding to purge requests'
end
end
end
diff --git a/spec/requests/api/error_tracking_client_keys_spec.rb b/spec/requests/api/error_tracking_client_keys_spec.rb
new file mode 100644
index 00000000000..886ec5ade3d
--- /dev/null
+++ b/spec/requests/api/error_tracking_client_keys_spec.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::ErrorTrackingClientKeys do
+ let_it_be(:guest) { create(:user) }
+ let_it_be(:maintainer) { create(:user) }
+ let_it_be(:setting) { create(:project_error_tracking_setting) }
+ let_it_be(:project) { setting.project }
+
+ let!(:client_key) { create(:error_tracking_client_key, project: project) }
+
+ before do
+ project.add_guest(guest)
+ project.add_maintainer(maintainer)
+ end
+
+ shared_examples 'endpoint with authorization' do
+ context 'when unauthenticated' do
+ let(:user) { nil }
+
+ it { expect(response).to have_gitlab_http_status(:unauthorized) }
+ end
+
+ context 'when authenticated as non-maintainer' do
+ let(:user) { guest }
+
+ it { expect(response).to have_gitlab_http_status(:forbidden) }
+ end
+ end
+
+ describe "GET /projects/:id/error_tracking/client_keys" do
+ before do
+ get api("/projects/#{project.id}/error_tracking/client_keys", user)
+ end
+
+ it_behaves_like 'endpoint with authorization'
+
+ context 'when authenticated as maintainer' do
+ let(:user) { maintainer }
+
+ it 'returns client keys' do
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to include_pagination_headers
+ expect(json_response.size).to eq(1)
+ expect(json_response.first['id']).to eq(client_key.id)
+ end
+ end
+ end
+
+ describe "POST /projects/:id/error_tracking/client_keys" do
+ before do
+ post api("/projects/#{project.id}/error_tracking/client_keys", user)
+ end
+
+ it_behaves_like 'endpoint with authorization'
+
+ context 'when authenticated as maintainer' do
+ let(:user) { maintainer }
+
+ it 'returns a newly created client key' do
+ new_key = project.error_tracking_client_keys.last
+
+ expect(json_response['id']).to eq(new_key.id)
+ expect(json_response['public_key']).to eq(new_key.public_key)
+ expect(json_response['sentry_dsn']).to eq(new_key.sentry_dsn)
+ end
+ end
+ end
+
+ describe "DELETE /projects/:id/error_tracking/client_keys/:key_id" do
+ before do
+ delete api("/projects/#{project.id}/error_tracking/client_keys/#{client_key.id}", user)
+ end
+
+ it_behaves_like 'endpoint with authorization'
+
+ context 'when authenticated as maintainer' do
+ let(:user) { maintainer }
+
+ it 'returns a correct status' do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/error_tracking_collector_spec.rb b/spec/requests/api/error_tracking_collector_spec.rb
index 4b186657c4a..35d3ea01f87 100644
--- a/spec/requests/api/error_tracking_collector_spec.rb
+++ b/spec/requests/api/error_tracking_collector_spec.rb
@@ -7,6 +7,30 @@ RSpec.describe API::ErrorTrackingCollector do
let_it_be(:setting) { create(:project_error_tracking_setting, :integrated, project: project) }
let_it_be(:client_key) { create(:error_tracking_client_key, project: project) }
+ RSpec.shared_examples 'not found' do
+ it 'reponds with 404' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ RSpec.shared_examples 'bad request' do
+ it 'responds with 400' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
+ end
+
+ RSpec.shared_examples 'successful request' do
+ it 'writes to the database and returns no content' do
+ expect { subject }.to change { ErrorTracking::ErrorEvent.count }.by(1)
+
+ expect(response).to have_gitlab_http_status(:no_content)
+ end
+ end
+
describe "POST /error_tracking/collector/api/:id/envelope" do
let_it_be(:raw_event) { fixture_file('error_tracking/event.txt') }
let_it_be(:url) { "/error_tracking/collector/api/#{project.id}/envelope" }
@@ -16,22 +40,6 @@ RSpec.describe API::ErrorTrackingCollector do
subject { post api(url), params: params, headers: headers }
- RSpec.shared_examples 'not found' do
- it 'reponds with 404' do
- subject
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
- RSpec.shared_examples 'bad request' do
- it 'responds with 400' do
- subject
-
- expect(response).to have_gitlab_http_status(:bad_request)
- end
- end
-
context 'error tracking feature is disabled' do
before do
setting.update!(enabled: false)
@@ -48,14 +56,6 @@ RSpec.describe API::ErrorTrackingCollector do
it_behaves_like 'not found'
end
- context 'feature flag is disabled' do
- before do
- stub_feature_flags(integrated_error_tracking: false)
- end
-
- it_behaves_like 'not found'
- end
-
context 'auth headers are missing' do
let(:headers) { {} }
@@ -96,10 +96,53 @@ RSpec.describe API::ErrorTrackingCollector do
end
end
- it 'writes to the database and returns no content' do
- expect { subject }.to change { ErrorTracking::ErrorEvent.count }.by(1)
+ it_behaves_like 'successful request'
+ end
- expect(response).to have_gitlab_http_status(:no_content)
+ describe "POST /error_tracking/collector/api/:id/store" do
+ let_it_be(:raw_event) { fixture_file('error_tracking/parsed_event.json') }
+ let_it_be(:url) { "/error_tracking/collector/api/#{project.id}/store" }
+
+ let(:params) { raw_event }
+ let(:headers) { { 'X-Sentry-Auth' => "Sentry sentry_key=#{client_key.public_key}" } }
+
+ subject { post api(url), params: params, headers: headers }
+
+ it_behaves_like 'successful request'
+
+ context 'empty headers' do
+ let(:headers) { {} }
+
+ it_behaves_like 'bad request'
+ end
+
+ context 'empty body' do
+ let(:params) { '' }
+
+ it_behaves_like 'bad request'
+ end
+
+ context 'sentry_key as param and empty headers' do
+ let(:url) { "/error_tracking/collector/api/#{project.id}/store?sentry_key=#{sentry_key}" }
+ let(:headers) { {} }
+
+ context 'key is wrong' do
+ let(:sentry_key) { 'glet_1fedb514e17f4b958435093deb02048c' }
+
+ it_behaves_like 'not found'
+ end
+
+ context 'key is empty' do
+ let(:sentry_key) { '' }
+
+ it_behaves_like 'bad request'
+ end
+
+ context 'key is correct' do
+ let(:sentry_key) { client_key.public_key }
+
+ it_behaves_like 'successful request'
+ end
end
end
end
diff --git a/spec/requests/api/feature_flags_spec.rb b/spec/requests/api/feature_flags_spec.rb
index 8c8c6803a38..a1aedc1d6b2 100644
--- a/spec/requests/api/feature_flags_spec.rb
+++ b/spec/requests/api/feature_flags_spec.rb
@@ -116,21 +116,6 @@ RSpec.describe API::FeatureFlags do
}])
end
end
-
- context 'with version 1 and 2 feature flags' do
- it 'returns both versions of flags ordered by name' do
- create(:operations_feature_flag, project: project, name: 'legacy_flag')
- feature_flag = create(:operations_feature_flag, :new_version_flag, project: project, name: 'new_version_flag')
- strategy = create(:operations_strategy, feature_flag: feature_flag, name: 'default', parameters: {})
- create(:operations_scope, strategy: strategy, environment_scope: 'production')
-
- subject
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(response).to match_response_schema('public_api/v4/feature_flags')
- expect(json_response.map { |f| f['name'] }).to eq(%w[legacy_flag new_version_flag])
- end
- end
end
describe 'GET /projects/:id/feature_flags/:name' do
@@ -185,22 +170,13 @@ RSpec.describe API::FeatureFlags do
end
describe 'POST /projects/:id/feature_flags' do
- def scope_default
- {
- environment_scope: '*',
- active: false,
- strategies: [{ name: 'default', parameters: {} }].to_json
- }
- end
-
subject do
post api("/projects/#{project.id}/feature_flags", user), params: params
end
let(:params) do
{
- name: 'awesome-feature',
- scopes: [scope_default]
+ name: 'awesome-feature'
}
end
@@ -215,14 +191,14 @@ RSpec.describe API::FeatureFlags do
expect(feature_flag.description).to eq(params[:description])
end
- it 'defaults to a version 1 (legacy) feature flag' do
+ it 'defaults to a version 2 (new) feature flag' do
subject
expect(response).to have_gitlab_http_status(:created)
expect(response).to match_response_schema('public_api/v4/feature_flag')
feature_flag = project.operations_feature_flags.last
- expect(feature_flag.version).to eq('legacy_flag')
+ expect(feature_flag.version).to eq('new_version_flag')
end
it_behaves_like 'check user permission'
@@ -232,38 +208,7 @@ RSpec.describe API::FeatureFlags do
expect(response).to have_gitlab_http_status(:created)
expect(response).to match_response_schema('public_api/v4/feature_flag')
- expect(json_response['version']).to eq('legacy_flag')
- end
-
- context 'with active set to false in the params for a legacy flag' do
- let(:params) do
- {
- name: 'awesome-feature',
- version: 'legacy_flag',
- active: 'false',
- scopes: [scope_default]
- }
- end
-
- it 'creates an inactive feature flag' do
- subject
-
- expect(response).to have_gitlab_http_status(:created)
- expect(response).to match_response_schema('public_api/v4/feature_flag')
- expect(json_response['active']).to eq(false)
- end
- end
-
- context 'when no scopes passed in parameters' do
- let(:params) { { name: 'awesome-feature' } }
-
- it 'creates a new feature flag with active default scope' do
- subject
-
- expect(response).to have_gitlab_http_status(:created)
- feature_flag = project.operations_feature_flags.last
- expect(feature_flag.default_scope).to be_active
- end
+ expect(json_response['version']).to eq('new_version_flag')
end
context 'when there is a feature flag with the same name already' do
@@ -278,43 +223,6 @@ RSpec.describe API::FeatureFlags do
end
end
- context 'when create a feature flag with two scopes' do
- let(:params) do
- {
- name: 'awesome-feature',
- description: 'this is awesome',
- scopes: [
- scope_default,
- scope_with_user_with_id
- ]
- }
- end
-
- let(:scope_with_user_with_id) do
- {
- environment_scope: 'production',
- active: true,
- strategies: [{
- name: 'userWithId',
- parameters: { userIds: 'user:1' }
- }].to_json
- }
- end
-
- it 'creates a new feature flag with two scopes' do
- subject
-
- expect(response).to have_gitlab_http_status(:created)
-
- feature_flag = project.operations_feature_flags.last
- feature_flag.scopes.ordered.each_with_index do |scope, index|
- expect(scope.environment_scope).to eq(params[:scopes][index][:environment_scope])
- expect(scope.active).to eq(params[:scopes][index][:active])
- expect(scope.strategies).to eq(Gitlab::Json.parse(params[:scopes][index][:strategies]))
- end
- end
- end
-
context 'when creating a version 2 feature flag' do
it 'creates a new feature flag' do
params = {
@@ -455,23 +363,6 @@ RSpec.describe API::FeatureFlags do
end
describe 'PUT /projects/:id/feature_flags/:name' do
- context 'with a legacy feature flag' do
- let!(:feature_flag) do
- create(:operations_feature_flag, :legacy_flag, project: project,
- name: 'feature1', description: 'old description')
- end
-
- it 'returns a 404' do
- params = { description: 'new description' }
-
- put api("/projects/#{project.id}/feature_flags/feature1", user), params: params
-
- expect(response).to have_gitlab_http_status(:not_found)
- expect(json_response).to eq({ 'message' => '404 Not Found' })
- expect(feature_flag.reload.description).to eq('old description')
- end
- end
-
context 'with a version 2 feature flag' do
let!(:feature_flag) do
create(:operations_feature_flag, :new_version_flag, project: project, active: true,
@@ -781,7 +672,7 @@ RSpec.describe API::FeatureFlags do
params: params
end
- let!(:feature_flag) { create(:operations_feature_flag, :legacy_flag, project: project) }
+ let!(:feature_flag) { create(:operations_feature_flag, project: project) }
let(:params) { {} }
it 'destroys the feature flag' do
@@ -794,7 +685,7 @@ RSpec.describe API::FeatureFlags do
subject
expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['version']).to eq('legacy_flag')
+ expect(json_response['version']).to eq('new_version_flag')
end
context 'with a version 2 feature flag' do
diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb
index 869df06b60c..0b898496dd6 100644
--- a/spec/requests/api/files_spec.rb
+++ b/spec/requests/api/files_spec.rb
@@ -95,6 +95,19 @@ RSpec.describe API::Files do
expect(response.headers['X-Gitlab-Content-Sha256']).to eq('c440cd09bae50c4632cc58638ad33c6aa375b6109d811e76a9cc3a613c1e8887')
end
+ it 'caches sha256 of the content', :use_clean_rails_redis_caching do
+ head api(route(file_path), current_user, **options), params: params
+
+ expect(Rails.cache.fetch("blob_content_sha256:#{project.full_path}:#{response.headers['X-Gitlab-Blob-Id']}"))
+ .to eq('c440cd09bae50c4632cc58638ad33c6aa375b6109d811e76a9cc3a613c1e8887')
+
+ expect_next_instance_of(Gitlab::Git::Blob) do |instance|
+ expect(instance).not_to receive(:load_all_data!)
+ end
+
+ head api(route(file_path), current_user, **options), params: params
+ end
+
it 'returns file by commit sha' do
# This file is deleted on HEAD
file_path = "files%2Fjs%2Fcommit%2Ejs%2Ecoffee"
diff --git a/spec/requests/api/generic_packages_spec.rb b/spec/requests/api/generic_packages_spec.rb
index 4091253fb54..7e439a22e4b 100644
--- a/spec/requests/api/generic_packages_spec.rb
+++ b/spec/requests/api/generic_packages_spec.rb
@@ -18,7 +18,7 @@ RSpec.describe API::GenericPackages do
let_it_be(:project_deploy_token_wo) { create(:project_deploy_token, deploy_token: deploy_token_wo, project: project) }
let(:user) { personal_access_token.user }
- let(:ci_build) { create(:ci_build, :running, user: user) }
+ let(:ci_build) { create(:ci_build, :running, user: user, project: project) }
let(:snowplow_standard_context_params) { { user: user, project: project, namespace: project.namespace } }
def auth_header
@@ -388,9 +388,11 @@ RSpec.describe API::GenericPackages do
end
context 'event tracking' do
+ let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace, user: user } }
+
subject { upload_file(params, workhorse_headers.merge(personal_access_token_header)) }
- it_behaves_like 'a gitlab tracking event', described_class.name, 'push_package'
+ it_behaves_like 'a package tracking event', described_class.name, 'push_package'
end
it 'rejects request without a file from workhorse' do
@@ -542,13 +544,15 @@ RSpec.describe API::GenericPackages do
end
context 'event tracking' do
+ let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace, user: user } }
+
before do
project.add_developer(user)
end
subject { download_file(personal_access_token_header) }
- it_behaves_like 'a gitlab tracking event', described_class.name, 'pull_package'
+ it_behaves_like 'a package tracking event', described_class.name, 'pull_package'
end
it 'rejects a malicious file name request' do
diff --git a/spec/requests/api/go_proxy_spec.rb b/spec/requests/api/go_proxy_spec.rb
index e678b6cf1c8..0143340de11 100644
--- a/spec/requests/api/go_proxy_spec.rb
+++ b/spec/requests/api/go_proxy_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe API::GoProxy do
let_it_be(:base) { "#{Settings.build_gitlab_go_url}/#{project.full_path}" }
let_it_be(:oauth) { create :oauth_access_token, scopes: 'api', resource_owner: user }
- let_it_be(:job) { create :ci_build, user: user, status: :running }
+ let_it_be(:job) { create :ci_build, user: user, status: :running, project: project }
let_it_be(:pa_token) { create :personal_access_token, user: user }
let_it_be(:modules) do
diff --git a/spec/requests/api/graphql/boards/board_list_issues_query_spec.rb b/spec/requests/api/graphql/boards/board_list_issues_query_spec.rb
index 3628171fcc1..008241b8055 100644
--- a/spec/requests/api/graphql/boards/board_list_issues_query_spec.rb
+++ b/spec/requests/api/graphql/boards/board_list_issues_query_spec.rb
@@ -48,13 +48,18 @@ RSpec.describe 'get board lists' do
issues_data.map { |i| i['title'] }
end
+ def issue_relative_positions
+ issues_data.map { |i| i['relativePosition'] }
+ end
+
shared_examples 'group and project board list issues query' do
let!(:board) { create(:board, resource_parent: board_parent) }
let!(:label_list) { create(:list, board: board, label: label, position: 10) }
let!(:issue1) { create(:issue, project: issue_project, labels: [label, label2], relative_position: 9) }
let!(:issue2) { create(:issue, project: issue_project, labels: [label, label2], relative_position: 2) }
- let!(:issue3) { create(:issue, project: issue_project, labels: [label], relative_position: 9) }
- let!(:issue4) { create(:issue, project: issue_project, labels: [label2], relative_position: 432) }
+ let!(:issue3) { create(:issue, project: issue_project, labels: [label, label2], relative_position: nil) }
+ let!(:issue4) { create(:issue, project: issue_project, labels: [label], relative_position: 9) }
+ let!(:issue5) { create(:issue, project: issue_project, labels: [label2], relative_position: 432) }
context 'when the user does not have access to the board' do
it 'returns nil' do
@@ -69,10 +74,11 @@ RSpec.describe 'get board lists' do
board_parent.add_reporter(user)
end
- it 'can access the issues' do
+ it 'can access the issues', :aggregate_failures do
post_graphql(query("id: \"#{global_id_of(label_list)}\""), current_user: user)
- expect(issue_titles).to eq([issue2.title, issue1.title])
+ expect(issue_titles).to eq([issue2.title, issue1.title, issue3.title])
+ expect(issue_relative_positions).not_to include(nil)
end
end
end
diff --git a/spec/requests/api/graphql/ci/stages_spec.rb b/spec/requests/api/graphql/ci/stages_spec.rb
index cd48a24b9c8..50d2cf75097 100644
--- a/spec/requests/api/graphql/ci/stages_spec.rb
+++ b/spec/requests/api/graphql/ci/stages_spec.rb
@@ -4,11 +4,13 @@ require 'spec_helper'
RSpec.describe 'Query.project.pipeline.stages' do
include GraphqlHelpers
- let(:project) { create(:project, :repository, :public) }
- let(:user) { create(:user) }
- let(:pipeline) { create(:ci_pipeline, project: project, user: user) }
- let(:stage_graphql_data) { graphql_data['project']['pipeline']['stages'] }
+ subject(:post_query) { post_graphql(query, current_user: user) }
+ let_it_be(:project) { create(:project, :repository, :public) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:pipeline) { create(:ci_pipeline, project: project, user: user) }
+
+ let(:stage_nodes) { graphql_data_at(:project, :pipeline, :stages, :nodes) }
let(:params) { {} }
let(:fields) do
@@ -33,14 +35,42 @@ RSpec.describe 'Query.project.pipeline.stages' do
)
end
- before do
+ before_all do
create(:ci_stage_entity, pipeline: pipeline, name: 'deploy')
- post_graphql(query, current_user: user)
+ create_list(:ci_build, 2, pipeline: pipeline, stage: 'deploy')
end
- it_behaves_like 'a working graphql query'
+ it_behaves_like 'a working graphql query' do
+ before do
+ post_query
+ end
+ end
it 'returns the stage of a pipeline' do
- expect(stage_graphql_data['nodes'].first['name']).to eq('deploy')
+ post_query
+
+ expect(stage_nodes.first['name']).to eq('deploy')
+ end
+
+ describe 'job pagination' do
+ let(:job_nodes) { graphql_dig_at(stage_nodes, :jobs, :nodes) }
+
+ it 'returns up to default limit jobs per stage' do
+ post_query
+
+ expect(job_nodes.count).to eq(2)
+ end
+
+ context 'when the limit is manually set' do
+ before do
+ stub_application_setting(jobs_per_stage_page_size: 1)
+ end
+
+ it 'returns up to custom limit jobs per stage' do
+ post_query
+
+ expect(job_nodes.count).to eq(1)
+ end
+ end
end
end
diff --git a/spec/requests/api/graphql/current_user/groups_query_spec.rb b/spec/requests/api/graphql/current_user/groups_query_spec.rb
new file mode 100644
index 00000000000..39f323b21a3
--- /dev/null
+++ b/spec/requests/api/graphql/current_user/groups_query_spec.rb
@@ -0,0 +1,112 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Query current user groups' do
+ include GraphqlHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:guest_group) { create(:group, name: 'public guest', path: 'public-guest') }
+ let_it_be(:private_maintainer_group) { create(:group, :private, name: 'b private maintainer', path: 'b-private-maintainer') }
+ let_it_be(:public_developer_group) { create(:group, :private, project_creation_level: nil, name: 'c public developer', path: 'c-public-developer') }
+ let_it_be(:public_maintainer_group) { create(:group, :private, name: 'a public maintainer', path: 'a-public-maintainer') }
+
+ let(:group_arguments) { {} }
+ let(:current_user) { user }
+
+ let(:fields) do
+ <<~GRAPHQL
+ nodes { id path fullPath name }
+ GRAPHQL
+ end
+
+ let(:query) do
+ graphql_query_for('currentUser', {}, query_graphql_field('groups', group_arguments, fields))
+ end
+
+ before_all do
+ guest_group.add_guest(user)
+ private_maintainer_group.add_maintainer(user)
+ public_developer_group.add_developer(user)
+ public_maintainer_group.add_maintainer(user)
+ end
+
+ subject { graphql_data.dig('currentUser', 'groups', 'nodes') }
+
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+
+ it_behaves_like 'a working graphql query'
+
+ it 'avoids N+1 queries', :request_store do
+ control = ActiveRecord::QueryRecorder.new { post_graphql(query, current_user: current_user) }
+
+ new_group = create(:group, :private)
+ new_group.add_maintainer(current_user)
+
+ expect { post_graphql(query, current_user: current_user) }.not_to exceed_query_limit(control)
+ end
+
+ it 'returns all groups where the user is a direct member' do
+ is_expected.to match(
+ expected_group_hash(
+ public_maintainer_group,
+ private_maintainer_group,
+ public_developer_group,
+ guest_group
+ )
+ )
+ end
+
+ context 'when permission_scope is CREATE_PROJECTS' do
+ let(:group_arguments) { { permission_scope: :CREATE_PROJECTS } }
+
+ specify do
+ is_expected.to match(
+ expected_group_hash(
+ public_maintainer_group,
+ private_maintainer_group,
+ public_developer_group
+ )
+ )
+ end
+
+ context 'when search is provided' do
+ let(:group_arguments) { { permission_scope: :CREATE_PROJECTS, search: 'maintainer' } }
+
+ specify do
+ is_expected.to match(
+ expected_group_hash(
+ public_maintainer_group,
+ private_maintainer_group
+ )
+ )
+ end
+ end
+ end
+
+ context 'when search is provided' do
+ let(:group_arguments) { { search: 'maintainer' } }
+
+ specify do
+ is_expected.to match(
+ expected_group_hash(
+ public_maintainer_group,
+ private_maintainer_group
+ )
+ )
+ end
+ end
+
+ def expected_group_hash(*groups)
+ groups.map do |group|
+ {
+ 'id' => group.to_global_id.to_s,
+ 'name' => group.name,
+ 'path' => group.path,
+ 'fullPath' => group.full_path
+ }
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/group/dependency_proxy_blobs_spec.rb b/spec/requests/api/graphql/group/dependency_proxy_blobs_spec.rb
new file mode 100644
index 00000000000..cdb21512894
--- /dev/null
+++ b/spec/requests/api/graphql/group/dependency_proxy_blobs_spec.rb
@@ -0,0 +1,127 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe 'getting dependency proxy blobs in a group' do
+ using RSpec::Parameterized::TableSyntax
+ include GraphqlHelpers
+
+ let_it_be(:owner) { create(:user) }
+ let_it_be_with_reload(:group) { create(:group) }
+ let_it_be(:blob) { create(:dependency_proxy_blob, group: group) }
+ let_it_be(:blob2) { create(:dependency_proxy_blob, file_name: 'blob2.json', group: group) }
+ let_it_be(:blobs) { [blob, blob2].flatten }
+
+ let(:dependency_proxy_blob_fields) do
+ <<~GQL
+ edges {
+ node {
+ #{all_graphql_fields_for('dependency_proxy_blobs'.classify, max_depth: 1)}
+ }
+ }
+ GQL
+ end
+
+ let(:fields) do
+ <<~GQL
+ #{query_graphql_field('dependency_proxy_blobs', {}, dependency_proxy_blob_fields)}
+ dependencyProxyBlobCount
+ dependencyProxyTotalSize
+ GQL
+ end
+
+ let(:query) do
+ graphql_query_for(
+ 'group',
+ { 'fullPath' => group.full_path },
+ fields
+ )
+ end
+
+ let(:user) { owner }
+ let(:variables) { {} }
+ let(:dependency_proxy_blobs_response) { graphql_data.dig('group', 'dependencyProxyBlobs', 'edges') }
+ let(:dependency_proxy_blob_count_response) { graphql_data.dig('group', 'dependencyProxyBlobCount') }
+ let(:dependency_proxy_total_size_response) { graphql_data.dig('group', 'dependencyProxyTotalSize') }
+
+ before do
+ stub_config(dependency_proxy: { enabled: true })
+ group.add_owner(owner)
+ end
+
+ subject { post_graphql(query, current_user: user, variables: variables) }
+
+ it_behaves_like 'a working graphql query' do
+ before do
+ subject
+ end
+ end
+
+ context 'with different permissions' do
+ let_it_be(:user) { create(:user) }
+
+ where(:group_visibility, :role, :access_granted) do
+ :private | :maintainer | true
+ :private | :developer | true
+ :private | :reporter | true
+ :private | :guest | true
+ :private | :anonymous | false
+ :public | :maintainer | true
+ :public | :developer | true
+ :public | :reporter | true
+ :public | :guest | true
+ :public | :anonymous | false
+ end
+
+ with_them do
+ before do
+ group.update_column(:visibility_level, Gitlab::VisibilityLevel.const_get(group_visibility.to_s.upcase, false))
+ group.add_user(user, role) unless role == :anonymous
+ end
+
+ it 'return the proper response' do
+ subject
+
+ if access_granted
+ expect(dependency_proxy_blobs_response.size).to eq(blobs.size)
+ else
+ expect(dependency_proxy_blobs_response).to be_blank
+ end
+ end
+ end
+ end
+
+ context 'limiting the number of blobs' do
+ let(:limit) { 1 }
+ let(:variables) do
+ { path: group.full_path, n: limit }
+ end
+
+ let(:query) do
+ <<~GQL
+ query($path: ID!, $n: Int) {
+ group(fullPath: $path) {
+ dependencyProxyBlobs(first: $n) { #{dependency_proxy_blob_fields} }
+ }
+ }
+ GQL
+ end
+
+ it 'only returns N blobs' do
+ subject
+
+ expect(dependency_proxy_blobs_response.size).to eq(limit)
+ end
+ end
+
+ it 'returns the total count of blobs' do
+ subject
+
+ expect(dependency_proxy_blob_count_response).to eq(blobs.size)
+ end
+
+ it 'returns the total size' do
+ subject
+ expected_size = blobs.inject(0) { |sum, blob| sum + blob.size }
+ expect(dependency_proxy_total_size_response).to eq(ActiveSupport::NumberHelper.number_to_human_size(expected_size))
+ end
+end
diff --git a/spec/requests/api/graphql/group/dependency_proxy_group_setting_spec.rb b/spec/requests/api/graphql/group/dependency_proxy_group_setting_spec.rb
new file mode 100644
index 00000000000..c5c6d85d1e6
--- /dev/null
+++ b/spec/requests/api/graphql/group/dependency_proxy_group_setting_spec.rb
@@ -0,0 +1,78 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe 'getting dependency proxy settings for a group' do
+ using RSpec::Parameterized::TableSyntax
+ include GraphqlHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be_with_reload(:group) { create(:group) }
+
+ let(:dependency_proxy_group_setting_fields) do
+ <<~GQL
+ #{all_graphql_fields_for('dependency_proxy_setting'.classify, max_depth: 1)}
+ GQL
+ end
+
+ let(:fields) do
+ <<~GQL
+ #{query_graphql_field('dependency_proxy_setting', {}, dependency_proxy_group_setting_fields)}
+ GQL
+ end
+
+ let(:query) do
+ graphql_query_for(
+ 'group',
+ { 'fullPath' => group.full_path },
+ fields
+ )
+ end
+
+ let(:variables) { {} }
+ let(:dependency_proxy_group_setting_response) { graphql_data.dig('group', 'dependencyProxySetting') }
+
+ before do
+ stub_config(dependency_proxy: { enabled: true })
+ group.create_dependency_proxy_setting!(enabled: true)
+ end
+
+ subject { post_graphql(query, current_user: user, variables: variables) }
+
+ it_behaves_like 'a working graphql query' do
+ before do
+ subject
+ end
+ end
+
+ context 'with different permissions' do
+ where(:group_visibility, :role, :access_granted) do
+ :private | :maintainer | true
+ :private | :developer | true
+ :private | :reporter | true
+ :private | :guest | true
+ :private | :anonymous | false
+ :public | :maintainer | true
+ :public | :developer | true
+ :public | :reporter | true
+ :public | :guest | true
+ :public | :anonymous | false
+ end
+
+ with_them do
+ before do
+ group.update_column(:visibility_level, Gitlab::VisibilityLevel.const_get(group_visibility.to_s.upcase, false))
+ group.add_user(user, role) unless role == :anonymous
+ end
+
+ it 'return the proper response' do
+ subject
+
+ if access_granted
+ expect(dependency_proxy_group_setting_response).to eq('enabled' => true)
+ else
+ expect(dependency_proxy_group_setting_response).to be_blank
+ end
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/group/dependency_proxy_image_ttl_policy_spec.rb b/spec/requests/api/graphql/group/dependency_proxy_image_ttl_policy_spec.rb
new file mode 100644
index 00000000000..c8797d84906
--- /dev/null
+++ b/spec/requests/api/graphql/group/dependency_proxy_image_ttl_policy_spec.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe 'getting dependency proxy image ttl policy for a group' do
+ using RSpec::Parameterized::TableSyntax
+ include GraphqlHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be_with_reload(:group) { create(:group) }
+
+ let(:dependency_proxy_image_ttl_policy_fields) do
+ <<~GQL
+ #{all_graphql_fields_for('dependency_proxy_image_ttl_group_policy'.classify, max_depth: 1)}
+ GQL
+ end
+
+ let(:fields) do
+ <<~GQL
+ #{query_graphql_field('dependency_proxy_image_ttl_policy', {}, dependency_proxy_image_ttl_policy_fields)}
+ GQL
+ end
+
+ let(:query) do
+ graphql_query_for(
+ 'group',
+ { 'fullPath' => group.full_path },
+ fields
+ )
+ end
+
+ let(:variables) { {} }
+ let(:dependency_proxy_image_ttl_policy_response) { graphql_data.dig('group', 'dependencyProxyImageTtlPolicy') }
+
+ before do
+ stub_config(dependency_proxy: { enabled: true })
+ end
+
+ subject { post_graphql(query, current_user: user, variables: variables) }
+
+ it_behaves_like 'a working graphql query' do
+ before do
+ subject
+ end
+ end
+
+ context 'with different permissions' do
+ where(:group_visibility, :role, :access_granted) do
+ :private | :maintainer | true
+ :private | :developer | true
+ :private | :reporter | true
+ :private | :guest | true
+ :private | :anonymous | false
+ :public | :maintainer | true
+ :public | :developer | true
+ :public | :reporter | true
+ :public | :guest | true
+ :public | :anonymous | false
+ end
+
+ with_them do
+ before do
+ group.update_column(:visibility_level, Gitlab::VisibilityLevel.const_get(group_visibility.to_s.upcase, false))
+ group.add_user(user, role) unless role == :anonymous
+ end
+
+ it 'return the proper response' do
+ subject
+
+ if access_granted
+ expect(dependency_proxy_image_ttl_policy_response).to eq("createdAt" => nil, "enabled" => false, "ttl" => 90, "updatedAt" => nil)
+ else
+ expect(dependency_proxy_image_ttl_policy_response).to be_blank
+ end
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb b/spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb
new file mode 100644
index 00000000000..30e704adb92
--- /dev/null
+++ b/spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb
@@ -0,0 +1,119 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe 'getting dependency proxy manifests in a group' do
+ using RSpec::Parameterized::TableSyntax
+ include GraphqlHelpers
+
+ let_it_be(:owner) { create(:user) }
+ let_it_be_with_reload(:group) { create(:group) }
+ let_it_be(:manifest) { create(:dependency_proxy_manifest, group: group) }
+ let_it_be(:manifest2) { create(:dependency_proxy_manifest, file_name: 'image2.json', group: group) }
+ let_it_be(:manifests) { [manifest, manifest2].flatten }
+
+ let(:dependency_proxy_manifest_fields) do
+ <<~GQL
+ edges {
+ node {
+ #{all_graphql_fields_for('dependency_proxy_manifests'.classify, max_depth: 1)}
+ }
+ }
+ GQL
+ end
+
+ let(:fields) do
+ <<~GQL
+ #{query_graphql_field('dependency_proxy_manifests', {}, dependency_proxy_manifest_fields)}
+ dependencyProxyImageCount
+ GQL
+ end
+
+ let(:query) do
+ graphql_query_for(
+ 'group',
+ { 'fullPath' => group.full_path },
+ fields
+ )
+ end
+
+ let(:user) { owner }
+ let(:variables) { {} }
+ let(:dependency_proxy_manifests_response) { graphql_data.dig('group', 'dependencyProxyManifests', 'edges') }
+ let(:dependency_proxy_image_count_response) { graphql_data.dig('group', 'dependencyProxyImageCount') }
+
+ before do
+ stub_config(dependency_proxy: { enabled: true })
+ group.add_owner(owner)
+ end
+
+ subject { post_graphql(query, current_user: user, variables: variables) }
+
+ it_behaves_like 'a working graphql query' do
+ before do
+ subject
+ end
+ end
+
+ context 'with different permissions' do
+ let_it_be(:user) { create(:user) }
+
+ where(:group_visibility, :role, :access_granted) do
+ :private | :maintainer | true
+ :private | :developer | true
+ :private | :reporter | true
+ :private | :guest | true
+ :private | :anonymous | false
+ :public | :maintainer | true
+ :public | :developer | true
+ :public | :reporter | true
+ :public | :guest | true
+ :public | :anonymous | false
+ end
+
+ with_them do
+ before do
+ group.update_column(:visibility_level, Gitlab::VisibilityLevel.const_get(group_visibility.to_s.upcase, false))
+ group.add_user(user, role) unless role == :anonymous
+ end
+
+ it 'return the proper response' do
+ subject
+
+ if access_granted
+ expect(dependency_proxy_manifests_response.size).to eq(manifests.size)
+ else
+ expect(dependency_proxy_manifests_response).to be_blank
+ end
+ end
+ end
+ end
+
+ context 'limiting the number of manifests' do
+ let(:limit) { 1 }
+ let(:variables) do
+ { path: group.full_path, n: limit }
+ end
+
+ let(:query) do
+ <<~GQL
+ query($path: ID!, $n: Int) {
+ group(fullPath: $path) {
+ dependencyProxyManifests(first: $n) { #{dependency_proxy_manifest_fields} }
+ }
+ }
+ GQL
+ end
+
+ it 'only returns N manifests' do
+ subject
+
+ expect(dependency_proxy_manifests_response.size).to eq(limit)
+ end
+ end
+
+ it 'returns the total count of manifests' do
+ subject
+
+ expect(dependency_proxy_image_count_response).to eq(manifests.size)
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/admin/sidekiq_queues/delete_jobs_spec.rb b/spec/requests/api/graphql/mutations/admin/sidekiq_queues/delete_jobs_spec.rb
index 1692cfbcf84..f992e46879f 100644
--- a/spec/requests/api/graphql/mutations/admin/sidekiq_queues/delete_jobs_spec.rb
+++ b/spec/requests/api/graphql/mutations/admin/sidekiq_queues/delete_jobs_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe 'Deleting Sidekiq jobs', :clean_gitlab_redis_queues do
let(:queue) { 'authorized_projects' }
- let(:variables) { { user: admin.username, queue_name: queue } }
+ let(:variables) { { user: admin.username, worker_class: 'AuthorizedProjectsWorker', queue_name: queue } }
let(:mutation) { graphql_mutation(:admin_sidekiq_queues_delete_jobs, variables) }
def mutation_response
diff --git a/spec/requests/api/graphql/mutations/custom_emoji/destroy_spec.rb b/spec/requests/api/graphql/mutations/custom_emoji/destroy_spec.rb
new file mode 100644
index 00000000000..07fd57a2cee
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/custom_emoji/destroy_spec.rb
@@ -0,0 +1,73 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Deletion of custom emoji' do
+ include GraphqlHelpers
+
+ let_it_be(:group) { create(:group) }
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:user2) { create(:user) }
+ let_it_be_with_reload(:custom_emoji) { create(:custom_emoji, group: group, creator: user2) }
+
+ let(:mutation) do
+ variables = {
+ id: GitlabSchema.id_from_object(custom_emoji).to_s
+ }
+
+ graphql_mutation(:destroy_custom_emoji, variables)
+ end
+
+ shared_examples 'does not delete custom emoji' do
+ it 'does not change count' do
+ expect { post_graphql_mutation(mutation, current_user: current_user) }.not_to change(CustomEmoji, :count)
+ end
+ end
+
+ shared_examples 'deletes custom emoji' do
+ it 'changes count' do
+ expect { post_graphql_mutation(mutation, current_user: current_user) }.to change(CustomEmoji, :count).by(-1)
+ end
+ end
+
+ context 'when the user' do
+ context 'has no permissions' do
+ it_behaves_like 'does not delete custom emoji'
+ end
+
+ context 'when the user is developer and not creator of custom emoji' do
+ before do
+ group.add_developer(current_user)
+ end
+
+ it_behaves_like 'does not delete custom emoji'
+ end
+ end
+
+ context 'when user' do
+ context 'is maintainer' do
+ before do
+ group.add_maintainer(current_user)
+ end
+
+ it_behaves_like 'deletes custom emoji'
+ end
+
+ context 'is owner' do
+ before do
+ group.add_owner(current_user)
+ end
+
+ it_behaves_like 'deletes custom emoji'
+ end
+
+ context 'is developer and creator of the emoji' do
+ before do
+ group.add_developer(current_user)
+ custom_emoji.update_attribute(:creator, current_user)
+ end
+
+ it_behaves_like 'deletes custom emoji'
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/dependency_proxy/image_ttl_group_policy/update_spec.rb b/spec/requests/api/graphql/mutations/dependency_proxy/image_ttl_group_policy/update_spec.rb
new file mode 100644
index 00000000000..c9e9a22ee0b
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/dependency_proxy/image_ttl_group_policy/update_spec.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Updating the dependency proxy image ttl policy' do
+ include GraphqlHelpers
+ using RSpec::Parameterized::TableSyntax
+
+ let_it_be(:user) { create(:user) }
+
+ let(:params) do
+ {
+ group_path: group.full_path,
+ enabled: false,
+ ttl: 2
+ }
+ end
+
+ let(:mutation) do
+ graphql_mutation(:update_dependency_proxy_image_ttl_group_policy, params) do
+ <<~QL
+ dependencyProxyImageTtlPolicy {
+ enabled
+ ttl
+ }
+ errors
+ QL
+ end
+ end
+
+ let(:mutation_response) { graphql_mutation_response(:update_dependency_proxy_image_ttl_group_policy) }
+ let(:ttl_policy_response) { mutation_response['dependencyProxyImageTtlPolicy'] }
+
+ before do
+ stub_config(dependency_proxy: { enabled: true })
+ end
+
+ describe 'post graphql mutation' do
+ subject { post_graphql_mutation(mutation, current_user: user) }
+
+ let_it_be(:ttl_policy, reload: true) { create(:image_ttl_group_policy) }
+ let_it_be(:group, reload: true) { ttl_policy.group }
+
+ context 'without permission' do
+ it 'returns no response' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(mutation_response).to be_nil
+ end
+ end
+
+ context 'with permission' do
+ before do
+ group.add_developer(user)
+ end
+
+ it 'returns the updated dependency proxy image ttl policy', :aggregate_failures do
+ subject
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(mutation_response['errors']).to be_empty
+ expect(ttl_policy_response).to include(
+ 'enabled' => params[:enabled],
+ 'ttl' => params[:ttl]
+ )
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/issues/create_spec.rb b/spec/requests/api/graphql/mutations/issues/create_spec.rb
index 66450f8c604..886f3140086 100644
--- a/spec/requests/api/graphql/mutations/issues/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/issues/create_spec.rb
@@ -39,11 +39,14 @@ RSpec.describe 'Create an issue' do
end
it 'creates the issue' do
- post_graphql_mutation(mutation, current_user: current_user)
+ expect do
+ post_graphql_mutation(mutation, current_user: current_user)
+ end.to change(Issue, :count).by(1)
expect(response).to have_gitlab_http_status(:success)
expect(mutation_response['issue']).to include(input)
expect(mutation_response['issue']).to include('discussionLocked' => true)
+ expect(Issue.last.work_item_type.base_type).to eq('issue')
end
end
end
diff --git a/spec/requests/api/graphql/mutations/issues/update_spec.rb b/spec/requests/api/graphql/mutations/issues/update_spec.rb
index c3aaf090703..0f2eeb90894 100644
--- a/spec/requests/api/graphql/mutations/issues/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/issues/update_spec.rb
@@ -44,6 +44,19 @@ RSpec.describe 'Update of an existing issue' do
expect(mutation_response['issue']).to include('discussionLocked' => true)
end
+ context 'when issue_type is updated' do
+ let(:input) { { 'iid' => issue.iid.to_s, 'type' => 'INCIDENT' } }
+
+ it 'updates issue_type and work_item_type' do
+ expect do
+ post_graphql_mutation(mutation, current_user: current_user)
+ issue.reload
+ end.to change { issue.work_item_type.base_type }.from('issue').to('incident').and(
+ change(issue, :issue_type).from('issue').to('incident')
+ )
+ end
+ end
+
context 'setting labels' do
let(:mutation) do
graphql_mutation(:update_issue, input_params) do
diff --git a/spec/requests/api/graphql/project/error_tracking/sentry_errors_request_spec.rb b/spec/requests/api/graphql/project/error_tracking/sentry_errors_request_spec.rb
index 80376f56ee8..a540386a9de 100644
--- a/spec/requests/api/graphql/project/error_tracking/sentry_errors_request_spec.rb
+++ b/spec/requests/api/graphql/project/error_tracking/sentry_errors_request_spec.rb
@@ -3,6 +3,7 @@ require 'spec_helper'
RSpec.describe 'sentry errors requests' do
include GraphqlHelpers
+
let_it_be(:project) { create(:project, :repository) }
let_it_be(:project_setting) { create(:project_error_tracking_setting, project: project) }
let_it_be(:current_user) { project.owner }
@@ -30,7 +31,7 @@ RSpec.describe 'sentry errors requests' do
let(:error_data) { graphql_data.dig('project', 'sentryErrors', 'detailedError') }
- it 'returns a successful response', :aggregate_failures, :quarantine do
+ it 'returns a successful response', :aggregate_failures do
post_graphql(query, current_user: current_user)
expect(response).to have_gitlab_http_status(:success)
@@ -48,11 +49,9 @@ RSpec.describe 'sentry errors requests' do
end
end
- context 'reactive cache returns data' do
+ context 'when reactive cache returns data' do
before do
- allow_any_instance_of(ErrorTracking::ProjectErrorTrackingSetting)
- .to receive(:issue_details)
- .and_return(issue: sentry_detailed_error)
+ stub_setting_for(:issue_details, issue: sentry_detailed_error)
post_graphql(query, current_user: current_user)
end
@@ -72,7 +71,7 @@ RSpec.describe 'sentry errors requests' do
end
end
- context 'user does not have permission' do
+ context 'when user does not have permission' do
let(:current_user) { create(:user) }
it 'is expected to return an empty error' do
@@ -81,11 +80,9 @@ RSpec.describe 'sentry errors requests' do
end
end
- context 'sentry api returns an error' do
+ context 'when sentry api returns an error' do
before do
- expect_any_instance_of(ErrorTracking::ProjectErrorTrackingSetting)
- .to receive(:issue_details)
- .and_return(error: 'error message')
+ stub_setting_for(:issue_details, error: 'error message')
post_graphql(query, current_user: current_user)
end
@@ -140,11 +137,11 @@ RSpec.describe 'sentry errors requests' do
end
end
- context 'reactive cache returns data' do
+ context 'when reactive cache returns data' do
before do
- expect_any_instance_of(ErrorTracking::ProjectErrorTrackingSetting)
- .to receive(:list_sentry_issues)
- .and_return(issues: [sentry_error], pagination: pagination)
+ stub_setting_for(:list_sentry_issues,
+ issues: [sentry_error],
+ pagination: pagination)
post_graphql(query, current_user: current_user)
end
@@ -177,11 +174,9 @@ RSpec.describe 'sentry errors requests' do
end
end
- context 'sentry api itself errors out' do
+ context 'when sentry api itself errors out' do
before do
- expect_any_instance_of(ErrorTracking::ProjectErrorTrackingSetting)
- .to receive(:list_sentry_issues)
- .and_return(error: 'error message')
+ stub_setting_for(:list_sentry_issues, error: 'error message')
post_graphql(query, current_user: current_user)
end
@@ -223,18 +218,16 @@ RSpec.describe 'sentry errors requests' do
end
end
- context 'reactive cache returns data' do
+ context 'when reactive cache returns data' do
before do
- allow_any_instance_of(ErrorTracking::ProjectErrorTrackingSetting)
- .to receive(:issue_latest_event)
- .and_return(latest_event: sentry_stack_trace)
+ stub_setting_for(:issue_latest_event, latest_event: sentry_stack_trace)
post_graphql(query, current_user: current_user)
end
it_behaves_like 'setting stack trace error'
- context 'user does not have permission' do
+ context 'when user does not have permission' do
let(:current_user) { create(:user) }
it 'is expected to return an empty error' do
@@ -243,11 +236,9 @@ RSpec.describe 'sentry errors requests' do
end
end
- context 'sentry api returns an error' do
+ context 'when sentry api returns an error' do
before do
- expect_any_instance_of(ErrorTracking::ProjectErrorTrackingSetting)
- .to receive(:issue_latest_event)
- .and_return(error: 'error message')
+ stub_setting_for(:issue_latest_event, error: 'error message')
post_graphql(query, current_user: current_user)
end
@@ -257,4 +248,12 @@ RSpec.describe 'sentry errors requests' do
end
end
end
+
+ private
+
+ def stub_setting_for(method, **return_value)
+ allow_next_found_instance_of(ErrorTracking::ProjectErrorTrackingSetting) do |setting|
+ allow(setting).to receive(method).and_return(**return_value)
+ end
+ end
end
diff --git a/spec/requests/api/graphql/project/issues_spec.rb b/spec/requests/api/graphql/project/issues_spec.rb
index ff0d7ecceb5..c6b4d82bf15 100644
--- a/spec/requests/api/graphql/project/issues_spec.rb
+++ b/spec/requests/api/graphql/project/issues_spec.rb
@@ -61,6 +61,34 @@ RSpec.describe 'getting an issue list for a project' do
end
end
+ context 'filtering by my_reaction_emoji' do
+ using RSpec::Parameterized::TableSyntax
+
+ let_it_be(:upvote_award) { create(:award_emoji, :upvote, user: current_user, awardable: issue_a) }
+
+ let(:issue_a_gid) { issue_a.to_global_id.to_s }
+ let(:issue_b_gid) { issue_b.to_global_id.to_s }
+
+ where(:value, :gids) do
+ 'thumbsup' | lazy { [issue_a_gid] }
+ 'ANY' | lazy { [issue_a_gid] }
+ 'any' | lazy { [issue_a_gid] }
+ 'AnY' | lazy { [issue_a_gid] }
+ 'NONE' | lazy { [issue_b_gid] }
+ 'thumbsdown' | lazy { [] }
+ end
+
+ with_them do
+ let(:issue_filter_params) { { my_reaction_emoji: value } }
+
+ it 'returns correctly filtered issues' do
+ post_graphql(query, current_user: current_user)
+
+ expect(graphql_dig_at(issues_data, :node, :id)).to eq(gids)
+ end
+ end
+ end
+
context 'when limiting the number of results' do
let(:query) do
<<~GQL
diff --git a/spec/requests/api/graphql/project/pipeline_spec.rb b/spec/requests/api/graphql/project/pipeline_spec.rb
index cb6755640a9..d46ef313563 100644
--- a/spec/requests/api/graphql/project/pipeline_spec.rb
+++ b/spec/requests/api/graphql/project/pipeline_spec.rb
@@ -311,6 +311,10 @@ RSpec.describe 'getting pipeline information nested in a project' do
end
it 'does not generate N+1 queries', :request_store, :use_sql_query_cache do
+ # create extra statuses
+ create(:generic_commit_status, :pending, name: 'generic-build-a', pipeline: pipeline, stage_idx: 0, stage: 'build')
+ create(:ci_bridge, :failed, name: 'deploy-a', pipeline: pipeline, stage_idx: 2, stage: 'deploy')
+
# warm up
post_graphql(query, current_user: current_user)
@@ -318,9 +322,11 @@ RSpec.describe 'getting pipeline information nested in a project' do
post_graphql(query, current_user: current_user)
end
- create(:ci_build, name: 'test-a', pipeline: pipeline, stage_idx: 1, stage: 'test')
- create(:ci_build, name: 'test-b', pipeline: pipeline, stage_idx: 1, stage: 'test')
- create(:ci_build, name: 'deploy-a', pipeline: pipeline, stage_idx: 2, stage: 'deploy')
+ create(:generic_commit_status, :pending, name: 'generic-build-b', pipeline: pipeline, stage_idx: 0, stage: 'build')
+ create(:ci_build, :failed, name: 'test-a', pipeline: pipeline, stage_idx: 1, stage: 'test')
+ create(:ci_build, :running, name: 'test-b', pipeline: pipeline, stage_idx: 1, stage: 'test')
+ create(:ci_build, :pending, name: 'deploy-b', pipeline: pipeline, stage_idx: 2, stage: 'deploy')
+ create(:ci_bridge, :failed, name: 'deploy-c', pipeline: pipeline, stage_idx: 2, stage: 'deploy')
expect do
post_graphql(query, current_user: current_user)
diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb
index 30df47ccc41..38abedde7da 100644
--- a/spec/requests/api/groups_spec.rb
+++ b/spec/requests/api/groups_spec.rb
@@ -158,6 +158,127 @@ RSpec.describe API::Groups do
end
end
+ context 'pagination strategies' do
+ let_it_be(:group_1) { create(:group, name: '1_group') }
+ let_it_be(:group_2) { create(:group, name: '2_group') }
+
+ context 'when the user is anonymous' do
+ context 'offset pagination' do
+ context 'on making requests beyond the allowed offset pagination threshold' do
+ it 'returns error and suggests to use keyset pagination' do
+ get api('/groups'), params: { page: 3000, per_page: 25 }
+
+ expect(response).to have_gitlab_http_status(:method_not_allowed)
+ expect(json_response['error']).to eq(
+ 'Offset pagination has a maximum allowed offset of 50000 for requests that return objects of type Group. '\
+ 'Remaining records can be retrieved using keyset pagination.'
+ )
+ end
+
+ context 'when the feature flag `keyset_pagination_for_groups_api` is disabled' do
+ before do
+ stub_feature_flags(keyset_pagination_for_groups_api: false)
+ end
+
+ it 'returns successful response' do
+ get api('/groups'), params: { page: 3000, per_page: 25 }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+ end
+
+ context 'on making requests below the allowed offset pagination threshold' do
+ it 'paginates the records' do
+ get api('/groups'), params: { page: 1, per_page: 1 }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ records = json_response
+ expect(records.size).to eq(1)
+ expect(records.first['id']).to eq(group_1.id)
+
+ # next page
+
+ get api('/groups'), params: { page: 2, per_page: 1 }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ records = Gitlab::Json.parse(response.body)
+ expect(records.size).to eq(1)
+ expect(records.first['id']).to eq(group_2.id)
+ end
+ end
+ end
+
+ context 'keyset pagination' do
+ def pagination_links(response)
+ link = response.headers['LINK']
+ return unless link
+
+ link.split(',').map do |link|
+ match = link.match(/<(?<url>.*)>; rel="(?<rel>\w+)"/)
+ break nil unless match
+
+ { url: match[:url], rel: match[:rel] }
+ end.compact
+ end
+
+ def params_for_next_page(response)
+ next_url = pagination_links(response).find { |link| link[:rel] == 'next' }[:url]
+ Rack::Utils.parse_query(URI.parse(next_url).query)
+ end
+
+ context 'on making requests with supported ordering structure' do
+ it 'paginates the records correctly' do
+ # first page
+ get api('/groups'), params: { pagination: 'keyset', per_page: 1 }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ records = json_response
+ expect(records.size).to eq(1)
+ expect(records.first['id']).to eq(group_1.id)
+
+ params_for_next_page = params_for_next_page(response)
+ expect(params_for_next_page).to include('cursor')
+
+ get api('/groups'), params: params_for_next_page
+
+ expect(response).to have_gitlab_http_status(:ok)
+ records = Gitlab::Json.parse(response.body)
+ expect(records.size).to eq(1)
+ expect(records.first['id']).to eq(group_2.id)
+ end
+
+ context 'when the feature flag `keyset_pagination_for_groups_api` is disabled' do
+ before do
+ stub_feature_flags(keyset_pagination_for_groups_api: false)
+ end
+
+ it 'ignores the keyset pagination params and performs offset pagination' do
+ get api('/groups'), params: { pagination: 'keyset', per_page: 1 }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ records = json_response
+ expect(records.size).to eq(1)
+ expect(records.first['id']).to eq(group_1.id)
+
+ params_for_next_page = params_for_next_page(response)
+ expect(params_for_next_page).not_to include('cursor')
+ end
+ end
+ end
+
+ context 'on making requests with unsupported ordering structure' do
+ it 'returns error' do
+ get api('/groups'), params: { pagination: 'keyset', per_page: 1, order_by: 'path', sort: 'desc' }
+
+ expect(response).to have_gitlab_http_status(:method_not_allowed)
+ expect(json_response['error']).to eq('Keyset pagination is not yet available for this type of request')
+ end
+ end
+ end
+ end
+ end
+
context "when authenticated as admin" do
it "admin: returns an array of all groups" do
get api("/groups", admin)
diff --git a/spec/requests/api/helm_packages_spec.rb b/spec/requests/api/helm_packages_spec.rb
index 08b4489a6e3..3236857c5fc 100644
--- a/spec/requests/api/helm_packages_spec.rb
+++ b/spec/requests/api/helm_packages_spec.rb
@@ -9,16 +9,32 @@ RSpec.describe API::HelmPackages do
let_it_be_with_reload(:project) { create(:project, :public) }
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
- let_it_be(:package) { create(:helm_package, project: project) }
+ let_it_be(:package) { create(:helm_package, project: project, without_package_files: true) }
+ let_it_be(:package_file1) { create(:helm_package_file, package: package) }
+ let_it_be(:package_file2) { create(:helm_package_file, package: package) }
+ let_it_be(:package2) { create(:helm_package, project: project, without_package_files: true) }
+ let_it_be(:package_file2_1) { create(:helm_package_file, package: package2, file_sha256: 'file2', file_name: 'filename2.tgz', description: 'hello from stable channel') }
+ let_it_be(:package_file2_2) { create(:helm_package_file, package: package2, file_sha256: 'file2', file_name: 'filename2.tgz', channel: 'test', description: 'hello from test channel') }
+ let_it_be(:other_package) { create(:npm_package, project: project) }
describe 'GET /api/v4/projects/:id/packages/helm/:channel/index.yaml' do
- it_behaves_like 'handling helm chart index requests' do
- let(:url) { "/projects/#{project.id}/packages/helm/#{package.package_files.first.helm_channel}/index.yaml" }
+ let(:url) { "/projects/#{project_id}/packages/helm/stable/index.yaml" }
+
+ context 'with a project id' do
+ let(:project_id) { project.id }
+
+ it_behaves_like 'handling helm chart index requests'
+ end
+
+ context 'with an url encoded project id' do
+ let(:project_id) { ERB::Util.url_encode(project.full_path) }
+
+ it_behaves_like 'handling helm chart index requests'
end
end
describe 'GET /api/v4/projects/:id/packages/helm/:channel/charts/:file_name.tgz' do
- let(:url) { "/projects/#{project.id}/packages/helm/#{package.package_files.first.helm_channel}/charts/#{package.name}-#{package.version}.tgz" }
+ let(:url) { "/projects/#{project.id}/packages/helm/stable/charts/#{package.name}-#{package.version}.tgz" }
subject { get api(url), headers: headers }
diff --git a/spec/requests/api/internal/kubernetes_spec.rb b/spec/requests/api/internal/kubernetes_spec.rb
index 2acf6951d50..24422f7b0dd 100644
--- a/spec/requests/api/internal/kubernetes_spec.rb
+++ b/spec/requests/api/internal/kubernetes_spec.rb
@@ -93,6 +93,48 @@ RSpec.describe API::Internal::Kubernetes do
end
end
+ describe 'POST /internal/kubernetes/agent_configuration' do
+ def send_request(headers: {}, params: {})
+ post api('/internal/kubernetes/agent_configuration'), params: params, headers: headers.reverse_merge(jwt_auth_headers)
+ end
+
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, namespace: group) }
+ let_it_be(:agent) { create(:cluster_agent, project: project) }
+ let_it_be(:config) do
+ {
+ ci_access: {
+ groups: [
+ { id: group.full_path, default_namespace: 'production' }
+ ],
+ projects: [
+ { id: project.full_path, default_namespace: 'staging' }
+ ]
+ }
+ }
+ end
+
+ include_examples 'authorization'
+
+ context 'agent exists' do
+ it 'configures the agent and returns a 204' do
+ send_request(params: { agent_id: agent.id, agent_config: config })
+
+ expect(response).to have_gitlab_http_status(:no_content)
+ expect(agent.authorized_groups).to contain_exactly(group)
+ expect(agent.authorized_projects).to contain_exactly(project)
+ end
+ end
+
+ context 'agent does not exist' do
+ it 'returns a 404' do
+ send_request(params: { agent_id: -1, agent_config: config })
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
describe 'GET /internal/kubernetes/agent_info' do
def send_request(headers: {}, params: {})
get api('/internal/kubernetes/agent_info'), params: params, headers: headers.reverse_merge(jwt_auth_headers)
diff --git a/spec/requests/api/issues/get_group_issues_spec.rb b/spec/requests/api/issues/get_group_issues_spec.rb
index cebde747210..3663a82891c 100644
--- a/spec/requests/api/issues/get_group_issues_spec.rb
+++ b/spec/requests/api/issues/get_group_issues_spec.rb
@@ -402,14 +402,7 @@ RSpec.describe API::Issues do
expect_paginated_array_response([group_closed_issue.id, group_issue.id])
end
- shared_examples 'labels parameter' do
- it 'returns an array of labeled group issues' do
- get api(base_url, user), params: { labels: group_label.title }
-
- expect_paginated_array_response(group_issue.id)
- expect(json_response.first['labels']).to eq([group_label.title])
- end
-
+ context 'labels parameter' do
it 'returns an array of labeled group issues' do
get api(base_url, user), params: { labels: group_label.title }
@@ -458,22 +451,6 @@ RSpec.describe API::Issues do
end
end
- context 'when `optimized_issuable_label_filter` feature flag is off' do
- before do
- stub_feature_flags(optimized_issuable_label_filter: false)
- end
-
- it_behaves_like 'labels parameter'
- end
-
- context 'when `optimized_issuable_label_filter` feature flag is on' do
- before do
- stub_feature_flags(optimized_issuable_label_filter: true)
- end
-
- it_behaves_like 'labels parameter'
- end
-
it 'returns issues matching given search string for title' do
get api(base_url, user), params: { search: group_issue.title }
diff --git a/spec/requests/api/issues/issues_spec.rb b/spec/requests/api/issues/issues_spec.rb
index 125db58ed69..8a33e63b80b 100644
--- a/spec/requests/api/issues/issues_spec.rb
+++ b/spec/requests/api/issues/issues_spec.rb
@@ -3,21 +3,25 @@
require 'spec_helper'
RSpec.describe API::Issues do
+ using RSpec::Parameterized::TableSyntax
+
let_it_be(:user) { create(:user) }
let_it_be(:project, reload: true) { create(:project, :public, :repository, creator_id: user.id, namespace: user.namespace) }
let_it_be(:private_mrs_project) do
create(:project, :public, :repository, creator_id: user.id, namespace: user.namespace, merge_requests_access_level: ProjectFeature::PRIVATE)
end
- let(:user2) { create(:user) }
- let(:non_member) { create(:user) }
+ let_it_be(:user2) { create(:user) }
+ let_it_be(:non_member) { create(:user) }
let_it_be(:guest) { create(:user) }
let_it_be(:author) { create(:author) }
let_it_be(:assignee) { create(:assignee) }
- let(:admin) { create(:user, :admin) }
- let(:issue_title) { 'foo' }
- let(:issue_description) { 'closed' }
- let!(:closed_issue) do
+ let_it_be(:admin) { create(:user, :admin) }
+
+ let_it_be(:milestone) { create(:milestone, title: '1.0.0', project: project) }
+ let_it_be(:empty_milestone) { create(:milestone, title: '2.0.0', project: project) }
+
+ let_it_be(:closed_issue) do
create :closed_issue,
author: user,
assignees: [user],
@@ -29,7 +33,7 @@ RSpec.describe API::Issues do
closed_at: 1.hour.ago
end
- let!(:confidential_issue) do
+ let_it_be(:confidential_issue) do
create :issue,
:confidential,
project: project,
@@ -39,7 +43,7 @@ RSpec.describe API::Issues do
updated_at: 2.hours.ago
end
- let!(:issue) do
+ let_it_be(:issue) do
create :issue,
author: user,
assignees: [user],
@@ -47,21 +51,16 @@ RSpec.describe API::Issues do
milestone: milestone,
created_at: generate(:past_time),
updated_at: 1.hour.ago,
- title: issue_title,
- description: issue_description
+ title: 'foo',
+ description: 'bar'
end
let_it_be(:label) do
create(:label, title: 'label', color: '#FFAABB', project: project)
end
- let!(:label_link) { create(:label_link, label: label, target: issue) }
- let(:milestone) { create(:milestone, title: '1.0.0', project: project) }
- let_it_be(:empty_milestone) do
- create(:milestone, title: '2.0.0', project: project)
- end
-
- let!(:note) { create(:note_on_issue, author: user, project: project, noteable: issue) }
+ let_it_be(:label_link) { create(:label_link, label: label, target: issue) }
+ let_it_be(:note) { create(:note_on_issue, author: user, project: project, noteable: issue) }
let(:no_milestone_title) { 'None' }
let(:any_milestone_title) { 'Any' }
@@ -683,6 +682,71 @@ RSpec.describe API::Issues do
end
end
+ context 'filtering by milestone_id' do
+ let_it_be(:upcoming_milestone) { create(:milestone, project: project, title: "upcoming milestone", start_date: 1.day.ago, due_date: 1.day.from_now) }
+ let_it_be(:started_milestone) { create(:milestone, project: project, title: "started milestone", start_date: 2.days.ago, due_date: 1.day.ago) }
+ let_it_be(:future_milestone) { create(:milestone, project: project, title: "future milestone", start_date: 7.days.from_now, due_date: 14.days.from_now) }
+ let_it_be(:issue_upcoming) { create(:issue, project: project, state: :opened, milestone: upcoming_milestone) }
+ let_it_be(:issue_started) { create(:issue, project: project, state: :opened, milestone: started_milestone) }
+ let_it_be(:issue_future) { create(:issue, project: project, state: :opened, milestone: future_milestone) }
+ let_it_be(:issue_none) { create(:issue, project: project, state: :opened) }
+
+ let(:wildcard_started) { 'Started' }
+ let(:wildcard_upcoming) { 'Upcoming' }
+ let(:wildcard_any) { 'Any' }
+ let(:wildcard_none) { 'None' }
+
+ where(:milestone_id, :not_milestone, :expected_issues) do
+ ref(:wildcard_none) | nil | lazy { [issue_none.id] }
+ ref(:wildcard_any) | nil | lazy { [issue_future.id, issue_started.id, issue_upcoming.id, issue.id, closed_issue.id] }
+ ref(:wildcard_started) | nil | lazy { [issue_started.id, issue_upcoming.id] }
+ ref(:wildcard_upcoming) | nil | lazy { [issue_upcoming.id] }
+ ref(:wildcard_any) | "upcoming milestone" | lazy { [issue_future.id, issue_started.id, issue.id, closed_issue.id] }
+ ref(:wildcard_upcoming) | "upcoming milestone" | []
+ end
+
+ with_them do
+ it "returns correct issues when filtering with 'milestone_id' and optionally negated 'milestone'" do
+ get api('/issues', user), params: { milestone_id: milestone_id, not: not_milestone ? { milestone: not_milestone } : {} }
+
+ expect_paginated_array_response(expected_issues)
+ end
+ end
+
+ context 'negated filtering' do
+ where(:not_milestone_id, :expected_issues) do
+ ref(:wildcard_started) | lazy { [issue_future.id] }
+ ref(:wildcard_upcoming) | lazy { [issue_started.id] }
+ end
+
+ with_them do
+ it "returns correct issues when filtering with negated 'milestone_id'" do
+ get api('/issues', user), params: { not: { milestone_id: not_milestone_id } }
+
+ expect_paginated_array_response(expected_issues)
+ end
+ end
+ end
+
+ context 'when mutually exclusive params are passed' do
+ where(:params) do
+ [
+ [lazy { { milestone: "foo", milestone_id: wildcard_any } }],
+ [lazy { { not: { milestone: "foo", milestone_id: wildcard_any } } }]
+ ]
+ end
+
+ with_them do
+ it "raises an error", :aggregate_failures do
+ get api('/issues', user), params: params
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response["error"]).to include("mutually exclusive")
+ end
+ end
+ end
+ end
+
it 'returns an array of issues found by iids' do
get api('/issues', user), params: { iids: [closed_issue.iid] }
@@ -711,8 +775,8 @@ RSpec.describe API::Issues do
milestone: milestone,
created_at: closed_issue.created_at,
updated_at: 1.hour.ago,
- title: issue_title,
- description: issue_description
+ title: 'foo',
+ description: 'bar'
end
it 'page breaks first page correctly' do
@@ -751,6 +815,18 @@ RSpec.describe API::Issues do
expect_paginated_array_response([closed_issue.id, issue.id])
end
+ it 'sorts by title asc when requested' do
+ get api('/issues', user), params: { order_by: :title, sort: :asc }
+
+ expect_paginated_array_response([issue.id, closed_issue.id])
+ end
+
+ it 'sorts by title desc when requested' do
+ get api('/issues', user), params: { order_by: :title, sort: :desc }
+
+ expect_paginated_array_response([closed_issue.id, issue.id])
+ end
+
context 'with issues list sort options' do
it 'accepts only predefined order by params' do
API::Helpers::IssuesHelpers.sort_options.each do |sort_opt|
@@ -760,7 +836,7 @@ RSpec.describe API::Issues do
end
it 'fails to sort with non predefined options' do
- %w(milestone title abracadabra).each do |sort_opt|
+ %w(milestone abracadabra).each do |sort_opt|
get api('/issues', user), params: { order_by: sort_opt, sort: 'asc' }
expect(response).to have_gitlab_http_status(:bad_request)
end
@@ -1001,13 +1077,15 @@ RSpec.describe API::Issues do
end
describe 'DELETE /projects/:id/issues/:issue_iid' do
+ let(:issue_for_deletion) { create(:issue, author: user, assignees: [user], project: project) }
+
it 'rejects a non member from deleting an issue' do
- delete api("/projects/#{project.id}/issues/#{issue.iid}", non_member)
+ delete api("/projects/#{project.id}/issues/#{issue_for_deletion.iid}", non_member)
expect(response).to have_gitlab_http_status(:forbidden)
end
it 'rejects a developer from deleting an issue' do
- delete api("/projects/#{project.id}/issues/#{issue.iid}", author)
+ delete api("/projects/#{project.id}/issues/#{issue_for_deletion.iid}", author)
expect(response).to have_gitlab_http_status(:forbidden)
end
@@ -1016,13 +1094,13 @@ RSpec.describe API::Issues do
let(:project) { create(:project, namespace: owner.namespace) }
it 'deletes the issue if an admin requests it' do
- delete api("/projects/#{project.id}/issues/#{issue.iid}", owner)
+ delete api("/projects/#{project.id}/issues/#{issue_for_deletion.iid}", owner)
expect(response).to have_gitlab_http_status(:no_content)
end
it_behaves_like '412 response' do
- let(:request) { api("/projects/#{project.id}/issues/#{issue.iid}", owner) }
+ let(:request) { api("/projects/#{project.id}/issues/#{issue_for_deletion.iid}", owner) }
end
end
@@ -1035,7 +1113,7 @@ RSpec.describe API::Issues do
end
it 'returns 404 when using the issue ID instead of IID' do
- delete api("/projects/#{project.id}/issues/#{issue.id}", user)
+ delete api("/projects/#{project.id}/issues/#{issue_for_deletion.id}", user)
expect(response).to have_gitlab_http_status(:not_found)
end
diff --git a/spec/requests/api/lint_spec.rb b/spec/requests/api/lint_spec.rb
index 7fe516d3daa..d7f22b9d619 100644
--- a/spec/requests/api/lint_spec.rb
+++ b/spec/requests/api/lint_spec.rb
@@ -113,7 +113,6 @@ RSpec.describe API::Lint do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['status']).to eq('valid')
expect(json_response['warnings']).not_to be_empty
- expect(json_response['status']).to eq('valid')
expect(json_response['errors']).to eq([])
end
end
diff --git a/spec/requests/api/maven_packages_spec.rb b/spec/requests/api/maven_packages_spec.rb
index c3fd02dad51..07111dd1d62 100644
--- a/spec/requests/api/maven_packages_spec.rb
+++ b/spec/requests/api/maven_packages_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe API::MavenPackages do
let_it_be(:package_file) { package.package_files.with_file_name_like('%.xml').first }
let_it_be(:jar_file) { package.package_files.with_file_name_like('%.jar').first }
let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
- let_it_be(:job, reload: true) { create(:ci_build, user: user, status: :running) }
+ let_it_be(:job, reload: true) { create(:ci_build, user: user, status: :running, project: project) }
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
let_it_be(:deploy_token_for_group) { create(:deploy_token, :group, read_package_registry: true, write_package_registry: true) }
diff --git a/spec/requests/api/members_spec.rb b/spec/requests/api/members_spec.rb
index 48ded93d85f..a1daf86de31 100644
--- a/spec/requests/api/members_spec.rb
+++ b/spec/requests/api/members_spec.rb
@@ -198,7 +198,7 @@ RSpec.describe API::Members do
# Member attributes
expect(json_response['access_level']).to eq(Member::DEVELOPER)
- expect(json_response['created_at'].to_time).to be_like_time(developer.created_at)
+ expect(json_response['created_at'].to_time).to be_present
end
end
end
@@ -311,36 +311,6 @@ RSpec.describe API::Members do
expect(json_response['status']).to eq('error')
expect(json_response['message']).to eq(error_message)
end
-
- context 'with invite_source considerations', :snowplow do
- let(:params) { { user_id: user_ids, access_level: Member::DEVELOPER } }
-
- it 'tracks the invite source as api' do
- post api("/#{source_type.pluralize}/#{source.id}/members", maintainer),
- params: params
-
- expect_snowplow_event(
- category: 'Members::CreateService',
- action: 'create_member',
- label: 'members-api',
- property: 'existing_user',
- user: maintainer
- )
- end
-
- it 'tracks the invite source from params' do
- post api("/#{source_type.pluralize}/#{source.id}/members", maintainer),
- params: params.merge(invite_source: '_invite_source_')
-
- expect_snowplow_event(
- category: 'Members::CreateService',
- action: 'create_member',
- label: '_invite_source_',
- property: 'existing_user',
- user: maintainer
- )
- end
- end
end
end
@@ -410,48 +380,28 @@ RSpec.describe API::Members do
end
context 'with areas_of_focus considerations', :snowplow do
- context 'when there is 1 user to add' do
- let(:user_id) { stranger.id }
+ let(:user_id) { stranger.id }
- context 'when areas_of_focus is present in params' do
- it 'tracks the areas_of_focus' do
- post api("/#{source_type.pluralize}/#{source.id}/members", maintainer),
- params: { user_id: user_id, access_level: Member::DEVELOPER, areas_of_focus: 'Other' }
-
- expect_snowplow_event(
- category: 'Members::CreateService',
- action: 'area_of_focus',
- label: 'Other',
- property: source.members.last.id.to_s
- )
- end
- end
-
- context 'when areas_of_focus is not present in params' do
- it 'does not track the areas_of_focus' do
- post api("/#{source_type.pluralize}/#{source.id}/members", maintainer),
- params: { user_id: user_id, access_level: Member::DEVELOPER }
+ context 'when areas_of_focus is present in params' do
+ it 'tracks the areas_of_focus' do
+ post api("/#{source_type.pluralize}/#{source.id}/members", maintainer),
+ params: { user_id: user_id, access_level: Member::DEVELOPER, areas_of_focus: 'Other' }
- expect_no_snowplow_event(category: 'Members::CreateService', action: 'area_of_focus')
- end
+ expect_snowplow_event(
+ category: 'Members::CreateService',
+ action: 'area_of_focus',
+ label: 'Other',
+ property: source.members.last.id.to_s
+ )
end
end
- context 'when there are multiple users to add' do
- let(:user_id) { [developer.id, stranger.id].join(',') }
+ context 'when areas_of_focus is not present in params' do
+ it 'does not track the areas_of_focus' do
+ post api("/#{source_type.pluralize}/#{source.id}/members", maintainer),
+ params: { user_id: user_id, access_level: Member::DEVELOPER }
- context 'when areas_of_focus is present in params' do
- it 'tracks the areas_of_focus' do
- post api("/#{source_type.pluralize}/#{source.id}/members", maintainer),
- params: { user_id: user_id, access_level: Member::DEVELOPER, areas_of_focus: 'Other' }
-
- expect_snowplow_event(
- category: 'Members::CreateService',
- action: 'area_of_focus',
- label: 'Other',
- property: source.members.last.id.to_s
- )
- end
+ expect_no_snowplow_event(category: 'Members::CreateService', action: 'area_of_focus')
end
end
end
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index 4b5fc57571b..7a587e82683 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -1072,7 +1072,7 @@ RSpec.describe API::MergeRequests do
end
describe "GET /groups/:id/merge_requests" do
- let_it_be(:group) { create(:group, :public) }
+ let_it_be(:group, reload: true) { create(:group, :public) }
let_it_be(:project) { create(:project, :public, :repository, creator: user, namespace: group, only_allow_merge_if_pipeline_succeeds: false) }
include_context 'with merge requests'
diff --git a/spec/requests/api/notification_settings_spec.rb b/spec/requests/api/notification_settings_spec.rb
index 7b4a58e63da..b5551c21738 100644
--- a/spec/requests/api/notification_settings_spec.rb
+++ b/spec/requests/api/notification_settings_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe API::NotificationSettings do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_a Hash
- expect(json_response['notification_email']).to eq(user.notification_email)
+ expect(json_response['notification_email']).to eq(user.notification_email_or_default)
expect(json_response['level']).to eq(user.global_notification_setting.level)
end
end
diff --git a/spec/requests/api/npm_project_packages_spec.rb b/spec/requests/api/npm_project_packages_spec.rb
index 8c35a1642e2..0d04c2cad5b 100644
--- a/spec/requests/api/npm_project_packages_spec.rb
+++ b/spec/requests/api/npm_project_packages_spec.rb
@@ -120,9 +120,11 @@ RSpec.describe API::NpmProjectPackages do
project.add_developer(user)
end
+ subject(:upload_package_with_token) { upload_with_token(package_name, params) }
+
shared_examples 'handling invalid record with 400 error' do
it 'handles an ActiveRecord::RecordInvalid exception with 400 error' do
- expect { upload_package_with_token(package_name, params) }
+ expect { upload_package_with_token }
.not_to change { project.packages.count }
expect(response).to have_gitlab_http_status(:bad_request)
@@ -136,6 +138,7 @@ RSpec.describe API::NpmProjectPackages do
let(:params) { upload_params(package_name: package_name) }
it_behaves_like 'handling invalid record with 400 error'
+ it_behaves_like 'not a package tracking event'
end
context 'invalid package version' do
@@ -157,6 +160,7 @@ RSpec.describe API::NpmProjectPackages do
let(:params) { upload_params(package_name: package_name, package_version: version) }
it_behaves_like 'handling invalid record with 400 error'
+ it_behaves_like 'not a package tracking event'
end
end
end
@@ -169,8 +173,6 @@ RSpec.describe API::NpmProjectPackages do
shared_examples 'handling upload with different authentications' do
context 'with access token' do
- subject { upload_package_with_token(package_name, params) }
-
it_behaves_like 'a package tracking event', 'API::NpmPackages', 'push_package'
it 'creates npm package with file' do
@@ -184,7 +186,7 @@ RSpec.describe API::NpmProjectPackages do
end
it 'creates npm package with file with job token' do
- expect { upload_package_with_job_token(package_name, params) }
+ expect { upload_with_job_token(package_name, params) }
.to change { project.packages.count }.by(1)
.and change { Packages::PackageFile.count }.by(1)
@@ -205,7 +207,7 @@ RSpec.describe API::NpmProjectPackages do
end
it 'creates the package metadata' do
- upload_package_with_token(package_name, params)
+ upload_package_with_token
expect(response).to have_gitlab_http_status(:ok)
expect(project.reload.packages.find(json_response['id']).original_build_info.pipeline).to eq job.pipeline
@@ -215,7 +217,7 @@ RSpec.describe API::NpmProjectPackages do
shared_examples 'uploading the package' do
it 'uploads the package' do
- expect { upload_package_with_token(package_name, params) }
+ expect { upload_package_with_token }
.to change { project.packages.count }.by(1)
expect(response).to have_gitlab_http_status(:ok)
@@ -249,6 +251,7 @@ RSpec.describe API::NpmProjectPackages do
let(:package_name) { "@#{group.path}/test" }
it_behaves_like 'handling invalid record with 400 error'
+ it_behaves_like 'not a package tracking event'
context 'with a new version' do
let_it_be(:version) { '4.5.6' }
@@ -271,9 +274,14 @@ RSpec.describe API::NpmProjectPackages do
let(:package_name) { "@#{group.path}/my_package_name" }
let(:params) { upload_params(package_name: package_name) }
- it 'returns an error if the package already exists' do
+ before do
create(:npm_package, project: project, version: '1.0.1', name: "@#{group.path}/my_package_name")
- expect { upload_package_with_token(package_name, params) }
+ end
+
+ it_behaves_like 'not a package tracking event'
+
+ it 'returns an error if the package already exists' do
+ expect { upload_package_with_token }
.not_to change { project.packages.count }
expect(response).to have_gitlab_http_status(:forbidden)
@@ -285,7 +293,7 @@ RSpec.describe API::NpmProjectPackages do
let(:params) { upload_params(package_name: package_name, file: 'npm/payload_with_duplicated_packages.json') }
it 'creates npm package with file and dependencies' do
- expect { upload_package_with_token(package_name, params) }
+ expect { upload_package_with_token }
.to change { project.packages.count }.by(1)
.and change { Packages::PackageFile.count }.by(1)
.and change { Packages::Dependency.count}.by(4)
@@ -297,11 +305,11 @@ RSpec.describe API::NpmProjectPackages do
context 'with existing dependencies' do
before do
name = "@#{group.path}/existing_package"
- upload_package_with_token(name, upload_params(package_name: name, file: 'npm/payload_with_duplicated_packages.json'))
+ upload_with_token(name, upload_params(package_name: name, file: 'npm/payload_with_duplicated_packages.json'))
end
it 'reuses them' do
- expect { upload_package_with_token(package_name, params) }
+ expect { upload_package_with_token }
.to change { project.packages.count }.by(1)
.and change { Packages::PackageFile.count }.by(1)
.and not_change { Packages::Dependency.count}
@@ -317,11 +325,11 @@ RSpec.describe API::NpmProjectPackages do
put api("/projects/#{project.id}/packages/npm/#{package_name.sub('/', '%2f')}"), params: params, headers: headers
end
- def upload_package_with_token(package_name, params = {})
+ def upload_with_token(package_name, params = {})
upload_package(package_name, params.merge(access_token: token.token))
end
- def upload_package_with_job_token(package_name, params = {})
+ def upload_with_job_token(package_name, params = {})
upload_package(package_name, params.merge(job_token: job.token))
end
diff --git a/spec/requests/api/pages/pages_spec.rb b/spec/requests/api/pages/pages_spec.rb
index f4c6de00e40..0eb2ae64f43 100644
--- a/spec/requests/api/pages/pages_spec.rb
+++ b/spec/requests/api/pages/pages_spec.rb
@@ -36,12 +36,7 @@ RSpec.describe API::Pages do
end
it 'removes the pages' do
- expect_any_instance_of(Gitlab::PagesTransfer).to receive(:rename_project).and_return true
- expect(PagesWorker).to receive(:perform_in).with(5.minutes, :remove, project.namespace.full_path, anything)
-
- Sidekiq::Testing.inline! do
- delete api("/projects/#{project.id}/pages", admin )
- end
+ delete api("/projects/#{project.id}/pages", admin )
expect(project.reload.pages_metadatum.deployed?).to be(false)
end
diff --git a/spec/requests/api/project_attributes.yml b/spec/requests/api/project_attributes.yml
index c5bcedd491a..9174356f123 100644
--- a/spec/requests/api/project_attributes.yml
+++ b/spec/requests/api/project_attributes.yml
@@ -32,6 +32,7 @@ itself: # project
- pages_https_only
- pending_delete
- pool_repository_id
+ - project_namespace_id
- pull_mirror_available_overridden
- pull_mirror_branch_prefix
- remote_mirror_available_overridden
@@ -55,6 +56,7 @@ itself: # project
- can_create_merge_request_in
- compliance_frameworks
- container_expiration_policy
+ - container_registry_enabled
- container_registry_image_prefix
- default_branch
- empty_repo
@@ -149,6 +151,7 @@ build_service_desk_setting: # service_desk_setting
unexposed_attributes:
- project_id
- issue_template_key
+ - file_template_project_id
- outgoing_name
remapped_attributes:
project_key: service_desk_address
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 3622eedfed5..80bccdfee0c 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -2616,6 +2616,23 @@ RSpec.describe API::Projects do
expect(json_response).to have_key 'service_desk_enabled'
expect(json_response).to have_key 'service_desk_address'
end
+
+ context 'when project is shared to multiple groups' do
+ it 'avoids N+1 queries' do
+ create(:project_group_link, project: project)
+ get api("/projects/#{project.id}", user)
+
+ control = ActiveRecord::QueryRecorder.new do
+ get api("/projects/#{project.id}", user)
+ end
+
+ create(:project_group_link, project: project)
+
+ expect do
+ get api("/projects/#{project.id}", user)
+ end.not_to exceed_query_limit(control)
+ end
+ end
end
describe 'GET /projects/:id/users' do
diff --git a/spec/requests/api/pypi_packages_spec.rb b/spec/requests/api/pypi_packages_spec.rb
index 8df2460a2b6..c17d0600aca 100644
--- a/spec/requests/api/pypi_packages_spec.rb
+++ b/spec/requests/api/pypi_packages_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe API::PypiPackages do
let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
- let_it_be(:job) { create(:ci_build, :running, user: user) }
+ let_it_be(:job) { create(:ci_build, :running, user: user, project: project) }
let(:headers) { {} }
diff --git a/spec/requests/api/releases_spec.rb b/spec/requests/api/releases_spec.rb
index 87b08587904..90b03a480a8 100644
--- a/spec/requests/api/releases_spec.rb
+++ b/spec/requests/api/releases_spec.rb
@@ -839,7 +839,7 @@ RSpec.describe API::Releases do
context 'when a valid token is provided' do
it 'creates the release for a running job' do
- job.update!(status: :running)
+ job.update!(status: :running, project: project)
post api("/projects/#{project.id}/releases"), params: params.merge(job_token: job.token)
expect(response).to have_gitlab_http_status(:created)
diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb
index d3262b8056b..a576e1ab1ee 100644
--- a/spec/requests/api/repositories_spec.rb
+++ b/spec/requests/api/repositories_spec.rb
@@ -22,7 +22,7 @@ RSpec.describe API::Repositories do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
- expect(json_response).to be_an Array
+ expect(json_response).to be_an(Array)
first_commit = json_response.first
expect(first_commit['name']).to eq('bar')
@@ -73,6 +73,25 @@ RSpec.describe API::Repositories do
end
end
end
+
+ context 'keyset pagination mode' do
+ let(:first_response) do
+ get api(route, current_user), params: { pagination: "keyset" }
+
+ Gitlab::Json.parse(response.body)
+ end
+
+ it 'paginates using keysets' do
+ page_token = first_response.last["id"]
+
+ get api(route, current_user), params: { pagination: "keyset", page_token: page_token }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to be_an(Array)
+ expect(json_response).not_to eq(first_response)
+ expect(json_response.map { |t| t["id"] }).not_to include(page_token)
+ end
+ end
end
context 'when unauthenticated', 'and project is public' do
@@ -354,6 +373,7 @@ RSpec.describe API::Repositories do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['commits']).to be_present
expect(json_response['diffs']).to be_present
+ expect(json_response['web_url']).to be_present
end
it "compares branches with explicit merge-base mode" do
@@ -365,6 +385,7 @@ RSpec.describe API::Repositories do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['commits']).to be_present
expect(json_response['diffs']).to be_present
+ expect(json_response['web_url']).to be_present
end
it "compares branches with explicit straight mode" do
@@ -376,6 +397,7 @@ RSpec.describe API::Repositories do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['commits']).to be_present
expect(json_response['diffs']).to be_present
+ expect(json_response['web_url']).to be_present
end
it "compares tags" do
@@ -384,6 +406,7 @@ RSpec.describe API::Repositories do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['commits']).to be_present
expect(json_response['diffs']).to be_present
+ expect(json_response['web_url']).to be_present
end
it "compares commits" do
@@ -393,6 +416,7 @@ RSpec.describe API::Repositories do
expect(json_response['commits']).to be_empty
expect(json_response['diffs']).to be_empty
expect(json_response['compare_same_ref']).to be_falsey
+ expect(json_response['web_url']).to be_present
end
it "compares commits in reverse order" do
@@ -401,6 +425,7 @@ RSpec.describe API::Repositories do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['commits']).to be_present
expect(json_response['diffs']).to be_present
+ expect(json_response['web_url']).to be_present
end
it "compare commits between different projects with non-forked relation" do
diff --git a/spec/requests/api/rubygem_packages_spec.rb b/spec/requests/api/rubygem_packages_spec.rb
index afa7adad80c..9b104520b52 100644
--- a/spec/requests/api/rubygem_packages_spec.rb
+++ b/spec/requests/api/rubygem_packages_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe API::RubygemPackages do
let_it_be_with_reload(:project) { create(:project) }
let_it_be(:personal_access_token) { create(:personal_access_token) }
let_it_be(:user) { personal_access_token.user }
- let_it_be(:job) { create(:ci_build, :running, user: user) }
+ let_it_be(:job) { create(:ci_build, :running, user: user, project: project) }
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
let_it_be(:headers) { {} }
diff --git a/spec/requests/api/settings_spec.rb b/spec/requests/api/settings_spec.rb
index 4008b57a1cf..f5d261ba4c6 100644
--- a/spec/requests/api/settings_spec.rb
+++ b/spec/requests/api/settings_spec.rb
@@ -47,6 +47,7 @@ RSpec.describe API::Settings, 'Settings', :do_not_mock_admin_mode_setting do
expect(json_response['personal_access_token_prefix']).to be_nil
expect(json_response['admin_mode']).to be(false)
expect(json_response['whats_new_variant']).to eq('all_tiers')
+ expect(json_response['user_deactivation_emails_enabled']).to be(true)
end
end
@@ -133,6 +134,7 @@ RSpec.describe API::Settings, 'Settings', :do_not_mock_admin_mode_setting do
import_sources: 'github,bitbucket',
wiki_page_max_content_bytes: 12345,
personal_access_token_prefix: "GL-",
+ user_deactivation_emails_enabled: false,
admin_mode: true
}
@@ -184,6 +186,7 @@ RSpec.describe API::Settings, 'Settings', :do_not_mock_admin_mode_setting do
expect(json_response['wiki_page_max_content_bytes']).to eq(12345)
expect(json_response['personal_access_token_prefix']).to eq("GL-")
expect(json_response['admin_mode']).to be(true)
+ expect(json_response['user_deactivation_emails_enabled']).to be(false)
end
end
@@ -222,6 +225,45 @@ RSpec.describe API::Settings, 'Settings', :do_not_mock_admin_mode_setting do
expect(json_response['asset_proxy_allowlist']).to eq(['example.com', '*.example.com', 'localhost'])
end
+ it 'supports the deprecated `throttle_unauthenticated_*` attributes' do
+ put api('/application/settings', admin), params: {
+ throttle_unauthenticated_enabled: true,
+ throttle_unauthenticated_period_in_seconds: 123,
+ throttle_unauthenticated_requests_per_period: 456
+ }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to include(
+ 'throttle_unauthenticated_enabled' => true,
+ 'throttle_unauthenticated_period_in_seconds' => 123,
+ 'throttle_unauthenticated_requests_per_period' => 456,
+ 'throttle_unauthenticated_web_enabled' => true,
+ 'throttle_unauthenticated_web_period_in_seconds' => 123,
+ 'throttle_unauthenticated_web_requests_per_period' => 456
+ )
+ end
+
+ it 'prefers the new `throttle_unauthenticated_web_*` attributes' do
+ put api('/application/settings', admin), params: {
+ throttle_unauthenticated_enabled: false,
+ throttle_unauthenticated_period_in_seconds: 0,
+ throttle_unauthenticated_requests_per_period: 0,
+ throttle_unauthenticated_web_enabled: true,
+ throttle_unauthenticated_web_period_in_seconds: 123,
+ throttle_unauthenticated_web_requests_per_period: 456
+ }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to include(
+ 'throttle_unauthenticated_enabled' => true,
+ 'throttle_unauthenticated_period_in_seconds' => 123,
+ 'throttle_unauthenticated_requests_per_period' => 456,
+ 'throttle_unauthenticated_web_enabled' => true,
+ 'throttle_unauthenticated_web_period_in_seconds' => 123,
+ 'throttle_unauthenticated_web_requests_per_period' => 456
+ )
+ end
+
it 'disables ability to switch to legacy storage' do
put api("/application/settings", admin),
params: { hashed_storage_enabled: false }
@@ -552,5 +594,20 @@ RSpec.describe API::Settings, 'Settings', :do_not_mock_admin_mode_setting do
expect(json_response['error']).to eq('whats_new_variant does not have a valid value')
end
end
+
+ context 'sidekiq job limit settings' do
+ it 'updates the settings' do
+ settings = {
+ sidekiq_job_limiter_mode: 'track',
+ sidekiq_job_limiter_compression_threshold_bytes: 1,
+ sidekiq_job_limiter_limit_bytes: 2
+ }.stringify_keys
+
+ put api("/application/settings", admin), params: settings
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response.slice(*settings.keys)).to eq(settings)
+ end
+ end
end
end
diff --git a/spec/requests/api/terraform/modules/v1/packages_spec.rb b/spec/requests/api/terraform/modules/v1/packages_spec.rb
index 6803c09b8c2..b04f5ad9a94 100644
--- a/spec/requests/api/terraform/modules/v1/packages_spec.rb
+++ b/spec/requests/api/terraform/modules/v1/packages_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe API::Terraform::Modules::V1::Packages do
let_it_be(:package) { create(:terraform_module_package, project: project) }
let_it_be(:personal_access_token) { create(:personal_access_token) }
let_it_be(:user) { personal_access_token.user }
- let_it_be(:job) { create(:ci_build, :running, user: user) }
+ let_it_be(:job) { create(:ci_build, :running, user: user, project: project) }
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
diff --git a/spec/requests/api/unleash_spec.rb b/spec/requests/api/unleash_spec.rb
index 0718710f15c..6cb801538c6 100644
--- a/spec/requests/api/unleash_spec.rb
+++ b/spec/requests/api/unleash_spec.rb
@@ -176,25 +176,6 @@ RSpec.describe API::Unleash do
it_behaves_like 'authenticated request'
- context 'with version 1 (legacy) feature flags' do
- let(:feature_flag) { create(:operations_feature_flag, :legacy_flag, project: project, name: 'feature1', active: true, version: 1) }
-
- it 'does not return a legacy feature flag' do
- create(:operations_feature_flag_scope,
- feature_flag: feature_flag,
- environment_scope: 'sandbox',
- active: true,
- strategies: [{ name: "gradualRolloutUserId",
- parameters: { groupId: "default", percentage: "50" } }])
- headers = { "UNLEASH-INSTANCEID" => client.token, "UNLEASH-APPNAME" => "sandbox" }
-
- get api(features_url), headers: headers
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['features']).to be_empty
- end
- end
-
context 'with version 2 feature flags' do
it 'does not return a flag without any strategies' do
create(:operations_feature_flag, project: project,
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index 383940ce34a..527e548ad19 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -9,9 +9,13 @@ RSpec.describe API::Users do
let_it_be(:gpg_key) { create(:gpg_key, user: user) }
let_it_be(:email) { create(:email, user: user) }
+ let(:blocked_user) { create(:user, :blocked) }
let(:omniauth_user) { create(:omniauth_user) }
let(:ldap_blocked_user) { create(:omniauth_user, provider: 'ldapmain', state: 'ldap_blocked') }
let(:private_user) { create(:user, private_profile: true) }
+ let(:deactivated_user) { create(:user, state: 'deactivated') }
+ let(:banned_user) { create(:user, :banned) }
+ let(:internal_user) { create(:user, :bot) }
context 'admin notes' do
let_it_be(:admin) { create(:admin, note: '2019-10-06 | 2FA added | user requested | www.gitlab.com') }
@@ -1199,7 +1203,7 @@ RSpec.describe API::Users do
it 'updates user with a new email' do
old_email = user.email
- old_notification_email = user.notification_email
+ old_notification_email = user.notification_email_or_default
put api("/users/#{user.id}", admin), params: { email: 'new@email.com' }
user.reload
@@ -1207,7 +1211,7 @@ RSpec.describe API::Users do
expect(response).to have_gitlab_http_status(:ok)
expect(user).to be_confirmed
expect(user.email).to eq(old_email)
- expect(user.notification_email).to eq(old_notification_email)
+ expect(user.notification_email_or_default).to eq(old_notification_email)
expect(user.unconfirmed_email).to eq('new@email.com')
end
@@ -2599,15 +2603,13 @@ RSpec.describe API::Users do
let(:api_user) { admin }
context 'for a deactivated user' do
- before do
- user.deactivate
- end
+ let(:user_id) { deactivated_user.id }
it 'activates a deactivated user' do
activate
expect(response).to have_gitlab_http_status(:created)
- expect(user.reload.state).to eq('active')
+ expect(deactivated_user.reload.state).to eq('active')
end
end
@@ -2625,16 +2627,14 @@ RSpec.describe API::Users do
end
context 'for a blocked user' do
- before do
- user.block
- end
+ let(:user_id) { blocked_user.id }
it 'returns 403' do
activate
expect(response).to have_gitlab_http_status(:forbidden)
expect(json_response['message']).to eq('403 Forbidden - A blocked user must be unblocked to be activated')
- expect(user.reload.state).to eq('blocked')
+ expect(blocked_user.reload.state).to eq('blocked')
end
end
@@ -2711,29 +2711,25 @@ RSpec.describe API::Users do
end
context 'for a deactivated user' do
- before do
- user.deactivate
- end
+ let(:user_id) { deactivated_user.id }
it 'returns 201' do
deactivate
expect(response).to have_gitlab_http_status(:created)
- expect(user.reload.state).to eq('deactivated')
+ expect(deactivated_user.reload.state).to eq('deactivated')
end
end
context 'for a blocked user' do
- before do
- user.block
- end
+ let(:user_id) { blocked_user.id }
it 'returns 403' do
deactivate
expect(response).to have_gitlab_http_status(:forbidden)
expect(json_response['message']).to eq('403 Forbidden - A blocked user cannot be deactivated by the API')
- expect(user.reload.state).to eq('blocked')
+ expect(blocked_user.reload.state).to eq('blocked')
end
end
@@ -2775,7 +2771,9 @@ RSpec.describe API::Users do
end
end
- context 'approve pending user' do
+ context 'approve and reject pending user' do
+ let(:pending_user) { create(:user, :blocked_pending_approval) }
+
shared_examples '404' do
it 'returns 404' do
expect(response).to have_gitlab_http_status(:not_found)
@@ -2786,10 +2784,6 @@ RSpec.describe API::Users do
describe 'POST /users/:id/approve' do
subject(:approve) { post api("/users/#{user_id}/approve", api_user) }
- let_it_be(:pending_user) { create(:user, :blocked_pending_approval) }
- let_it_be(:deactivated_user) { create(:user, :deactivated) }
- let_it_be(:blocked_user) { create(:user, :blocked) }
-
context 'performed by a non-admin user' do
let(:api_user) { user }
let(:user_id) { pending_user.id }
@@ -2865,102 +2859,403 @@ RSpec.describe API::Users do
end
end
end
- end
- describe 'POST /users/:id/block' do
- let(:blocked_user) { create(:user, state: 'blocked') }
+ describe 'POST /users/:id/reject', :aggregate_failures do
+ subject(:reject) { post api("/users/#{user_id}/reject", api_user) }
- it 'blocks existing user' do
- post api("/users/#{user.id}/block", admin)
+ shared_examples 'returns 409' do
+ it 'returns 409' do
+ reject
- aggregate_failures do
- expect(response).to have_gitlab_http_status(:created)
- expect(response.body).to eq('true')
- expect(user.reload.state).to eq('blocked')
+ expect(response).to have_gitlab_http_status(:conflict)
+ expect(json_response['message']).to eq('User does not have a pending request')
+ end
+ end
+
+ context 'performed by a non-admin user' do
+ let(:api_user) { user }
+ let(:user_id) { pending_user.id }
+
+ it 'returns 403' do
+ expect { reject }.not_to change { pending_user.reload.state }
+ expect(response).to have_gitlab_http_status(:forbidden)
+ expect(json_response['message']).to eq('You are not allowed to reject a user')
+ end
+ end
+
+ context 'performed by an admin user' do
+ let(:api_user) { admin }
+
+ context 'for an pending approval user' do
+ let(:user_id) { pending_user.id }
+
+ it 'returns 200' do
+ reject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['message']).to eq('Success')
+ end
+ end
+
+ context 'for a deactivated user' do
+ let(:user_id) { deactivated_user.id }
+
+ it 'does not reject a deactivated user' do
+ expect { reject }.not_to change { deactivated_user.reload.state }
+ end
+
+ it_behaves_like 'returns 409'
+ end
+
+ context 'for an active user' do
+ let(:user_id) { user.id }
+
+ it 'does not reject an active user' do
+ expect { reject }.not_to change { user.reload.state }
+ end
+
+ it_behaves_like 'returns 409'
+ end
+
+ context 'for a blocked user' do
+ let(:user_id) { blocked_user.id }
+
+ it 'does not reject a blocked user' do
+ expect { reject }.not_to change { blocked_user.reload.state }
+ end
+
+ it_behaves_like 'returns 409'
+ end
+
+ context 'for a ldap blocked user' do
+ let(:user_id) { ldap_blocked_user.id }
+
+ it 'does not reject a ldap blocked user' do
+ expect { reject }.not_to change { ldap_blocked_user.reload.state }
+ end
+
+ it_behaves_like 'returns 409'
+ end
+
+ context 'for a user that does not exist' do
+ let(:user_id) { non_existing_record_id }
+
+ before do
+ reject
+ end
+
+ it_behaves_like '404'
+ end
end
end
+ end
- it 'does not re-block ldap blocked users' do
- post api("/users/#{ldap_blocked_user.id}/block", admin)
- expect(response).to have_gitlab_http_status(:forbidden)
- expect(ldap_blocked_user.reload.state).to eq('ldap_blocked')
+ describe 'POST /users/:id/block', :aggregate_failures do
+ context 'when admin' do
+ subject(:block_user) { post api("/users/#{user_id}/block", admin) }
+
+ context 'with an existing user' do
+ let(:user_id) { user.id }
+
+ it 'blocks existing user' do
+ block_user
+
+ expect(response).to have_gitlab_http_status(:created)
+ expect(response.body).to eq('true')
+ expect(user.reload.state).to eq('blocked')
+ end
+ end
+
+ context 'with an ldap blocked user' do
+ let(:user_id) { ldap_blocked_user.id }
+
+ it 'does not re-block ldap blocked users' do
+ block_user
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ expect(ldap_blocked_user.reload.state).to eq('ldap_blocked')
+ end
+ end
+
+ context 'with a non existent user' do
+ let(:user_id) { non_existing_record_id }
+
+ it 'does not block non existent user, returns 404' do
+ block_user
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(json_response['message']).to eq('404 User Not Found')
+ end
+ end
+
+ context 'with an internal user' do
+ let(:user_id) { internal_user.id }
+
+ it 'does not block internal user, returns 403' do
+ block_user
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ expect(json_response['message']).to eq('An internal user cannot be blocked')
+ end
+ end
+
+ context 'with a blocked user' do
+ let(:user_id) { blocked_user.id }
+
+ it 'returns a 201 if user is already blocked' do
+ block_user
+
+ expect(response).to have_gitlab_http_status(:created)
+ expect(response.body).to eq('null')
+ end
+ end
end
- it 'does not be available for non admin users' do
+ it 'is not available for non admin users' do
post api("/users/#{user.id}/block", user)
+
expect(response).to have_gitlab_http_status(:forbidden)
expect(user.reload.state).to eq('active')
end
+ end
- it 'returns a 404 error if user id not found' do
- post api('/users/0/block', admin)
- expect(response).to have_gitlab_http_status(:not_found)
- expect(json_response['message']).to eq('404 User Not Found')
- end
+ describe 'POST /users/:id/unblock', :aggregate_failures do
+ context 'when admin' do
+ subject(:unblock_user) { post api("/users/#{user_id}/unblock", admin) }
- it 'returns a 403 error if user is internal' do
- internal_user = create(:user, :bot)
+ context 'with an existing user' do
+ let(:user_id) { user.id }
- post api("/users/#{internal_user.id}/block", admin)
+ it 'unblocks existing user' do
+ unblock_user
- expect(response).to have_gitlab_http_status(:forbidden)
- expect(json_response['message']).to eq('An internal user cannot be blocked')
- end
+ expect(response).to have_gitlab_http_status(:created)
+ expect(user.reload.state).to eq('active')
+ end
+ end
- it 'returns a 201 if user is already blocked' do
- post api("/users/#{blocked_user.id}/block", admin)
+ context 'with a blocked user' do
+ let(:user_id) { blocked_user.id }
- aggregate_failures do
- expect(response).to have_gitlab_http_status(:created)
- expect(response.body).to eq('null')
+ it 'unblocks a blocked user' do
+ unblock_user
+
+ expect(response).to have_gitlab_http_status(:created)
+ expect(blocked_user.reload.state).to eq('active')
+ end
end
- end
- end
- describe 'POST /users/:id/unblock' do
- let(:blocked_user) { create(:user, state: 'blocked') }
- let(:deactivated_user) { create(:user, state: 'deactivated') }
+ context 'with a ldap blocked user' do
+ let(:user_id) { ldap_blocked_user.id }
- it 'unblocks existing user' do
- post api("/users/#{user.id}/unblock", admin)
- expect(response).to have_gitlab_http_status(:created)
- expect(user.reload.state).to eq('active')
- end
+ it 'does not unblock ldap blocked users' do
+ unblock_user
- it 'unblocks a blocked user' do
- post api("/users/#{blocked_user.id}/unblock", admin)
- expect(response).to have_gitlab_http_status(:created)
- expect(blocked_user.reload.state).to eq('active')
+ expect(response).to have_gitlab_http_status(:forbidden)
+ expect(ldap_blocked_user.reload.state).to eq('ldap_blocked')
+ end
+ end
+
+ context 'with a deactivated user' do
+ let(:user_id) { deactivated_user.id }
+
+ it 'does not unblock deactivated users' do
+ unblock_user
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ expect(deactivated_user.reload.state).to eq('deactivated')
+ end
+ end
+
+ context 'with a non existent user' do
+ let(:user_id) { non_existing_record_id }
+
+ it 'returns a 404 error if user id not found' do
+ unblock_user
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(json_response['message']).to eq('404 User Not Found')
+ end
+ end
+
+ context 'with an invalid user id' do
+ let(:user_id) { 'ASDF' }
+
+ it 'returns a 404' do
+ unblock_user
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
end
- it 'does not unblock ldap blocked users' do
- post api("/users/#{ldap_blocked_user.id}/unblock", admin)
+ it 'is not available for non admin users' do
+ post api("/users/#{user.id}/unblock", user)
expect(response).to have_gitlab_http_status(:forbidden)
- expect(ldap_blocked_user.reload.state).to eq('ldap_blocked')
+ expect(user.reload.state).to eq('active')
end
+ end
- it 'does not unblock deactivated users' do
- post api("/users/#{deactivated_user.id}/unblock", admin)
- expect(response).to have_gitlab_http_status(:forbidden)
- expect(deactivated_user.reload.state).to eq('deactivated')
+ describe 'POST /users/:id/ban', :aggregate_failures do
+ context 'when admin' do
+ subject(:ban_user) { post api("/users/#{user_id}/ban", admin) }
+
+ context 'with an active user' do
+ let(:user_id) { user.id }
+
+ it 'bans an active user' do
+ ban_user
+
+ expect(response).to have_gitlab_http_status(:created)
+ expect(response.body).to eq('true')
+ expect(user.reload.state).to eq('banned')
+ end
+ end
+
+ context 'with an ldap blocked user' do
+ let(:user_id) { ldap_blocked_user.id }
+
+ it 'does not ban ldap blocked users' do
+ ban_user
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ expect(json_response['message']).to eq('You cannot ban ldap_blocked users.')
+ expect(ldap_blocked_user.reload.state).to eq('ldap_blocked')
+ end
+ end
+
+ context 'with a deactivated user' do
+ let(:user_id) { deactivated_user.id }
+
+ it 'does not ban deactivated users' do
+ ban_user
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ expect(json_response['message']).to eq('You cannot ban deactivated users.')
+ expect(deactivated_user.reload.state).to eq('deactivated')
+ end
+ end
+
+ context 'with a banned user' do
+ let(:user_id) { banned_user.id }
+
+ it 'does not ban banned users' do
+ ban_user
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ expect(json_response['message']).to eq('You cannot ban banned users.')
+ expect(banned_user.reload.state).to eq('banned')
+ end
+ end
+
+ context 'with a non existent user' do
+ let(:user_id) { non_existing_record_id }
+
+ it 'does not ban non existent users' do
+ ban_user
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(json_response['message']).to eq('404 User Not Found')
+ end
+ end
+
+ context 'with an invalid id' do
+ let(:user_id) { 'ASDF' }
+
+ it 'does not ban invalid id users' do
+ ban_user
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
end
- it 'is not available for non admin users' do
- post api("/users/#{user.id}/unblock", user)
+ it 'is not available for non-admin users' do
+ post api("/users/#{user.id}/ban", user)
+
expect(response).to have_gitlab_http_status(:forbidden)
expect(user.reload.state).to eq('active')
end
+ end
- it 'returns a 404 error if user id not found' do
- post api('/users/0/block', admin)
- expect(response).to have_gitlab_http_status(:not_found)
- expect(json_response['message']).to eq('404 User Not Found')
+ describe 'POST /users/:id/unban', :aggregate_failures do
+ context 'when admin' do
+ subject(:unban_user) { post api("/users/#{user_id}/unban", admin) }
+
+ context 'with a banned user' do
+ let(:user_id) { banned_user.id }
+
+ it 'activates a banned user' do
+ unban_user
+
+ expect(response).to have_gitlab_http_status(:created)
+ expect(banned_user.reload.state).to eq('active')
+ end
+ end
+
+ context 'with an ldap_blocked user' do
+ let(:user_id) { ldap_blocked_user.id }
+
+ it 'does not unban ldap_blocked users' do
+ unban_user
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ expect(json_response['message']).to eq('You cannot unban ldap_blocked users.')
+ expect(ldap_blocked_user.reload.state).to eq('ldap_blocked')
+ end
+ end
+
+ context 'with a deactivated user' do
+ let(:user_id) { deactivated_user.id }
+
+ it 'does not unban deactivated users' do
+ unban_user
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ expect(json_response['message']).to eq('You cannot unban deactivated users.')
+ expect(deactivated_user.reload.state).to eq('deactivated')
+ end
+ end
+
+ context 'with an active user' do
+ let(:user_id) { user.id }
+
+ it 'does not unban active users' do
+ unban_user
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ expect(json_response['message']).to eq('You cannot unban active users.')
+ expect(user.reload.state).to eq('active')
+ end
+ end
+
+ context 'with a non existent user' do
+ let(:user_id) { non_existing_record_id }
+
+ it 'does not unban non existent users' do
+ unban_user
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(json_response['message']).to eq('404 User Not Found')
+ end
+ end
+
+ context 'with an invalid id user' do
+ let(:user_id) { 'ASDF' }
+
+ it 'does not unban invalid id users' do
+ unban_user
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
end
- it "returns a 404 for invalid ID" do
- post api("/users/ASDF/block", admin)
+ it 'is not available for non admin users' do
+ post api("/users/#{banned_user.id}/unban", user)
- expect(response).to have_gitlab_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:forbidden)
+ expect(user.reload.state).to eq('active')
end
end
diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb
index e4a0c034b20..a16f5abf608 100644
--- a/spec/requests/git_http_spec.rb
+++ b/spec/requests/git_http_spec.rb
@@ -882,6 +882,10 @@ RSpec.describe 'Git HTTP requests' do
before do
build.update!(user: user)
project.add_reporter(user)
+ create(:ci_job_token_project_scope_link,
+ source_project: project,
+ target_project: other_project,
+ added_by: user)
end
shared_examples 'can download code only' do
@@ -1447,6 +1451,10 @@ RSpec.describe 'Git HTTP requests' do
before do
build.update!(project: project) # can't associate it on factory create
+ create(:ci_job_token_project_scope_link,
+ source_project: project,
+ target_project: other_project,
+ added_by: user)
end
context 'when build created by system is authenticated' do
diff --git a/spec/requests/jira_connect/installations_controller_spec.rb b/spec/requests/jira_connect/installations_controller_spec.rb
new file mode 100644
index 00000000000..6315c66a41a
--- /dev/null
+++ b/spec/requests/jira_connect/installations_controller_spec.rb
@@ -0,0 +1,95 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe JiraConnect::InstallationsController do
+ let_it_be(:installation) { create(:jira_connect_installation) }
+
+ describe 'GET /-/jira_connect/installations' do
+ before do
+ get '/-/jira_connect/installations', params: { jwt: jwt }
+ end
+
+ context 'without JWT' do
+ let(:jwt) { nil }
+
+ it 'returns 403' do
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
+ end
+
+ context 'with valid JWT' do
+ let(:qsh) { Atlassian::Jwt.create_query_string_hash('https://gitlab.test/installations', 'GET', 'https://gitlab.test') }
+ let(:jwt) { Atlassian::Jwt.encode({ iss: installation.client_key, qsh: qsh }, installation.shared_secret) }
+
+ it 'returns status ok' do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ it 'returns the installation as json' do
+ expect(json_response).to eq({
+ 'gitlab_com' => true,
+ 'instance_url' => nil
+ })
+ end
+
+ context 'with instance_url' do
+ let_it_be(:installation) { create(:jira_connect_installation, instance_url: 'https://example.com') }
+
+ it 'returns the installation as json' do
+ expect(json_response).to eq({
+ 'gitlab_com' => false,
+ 'instance_url' => 'https://example.com'
+ })
+ end
+ end
+ end
+ end
+
+ describe 'PUT /-/jira_connect/installations' do
+ before do
+ put '/-/jira_connect/installations', params: { jwt: jwt, installation: { instance_url: update_instance_url } }
+ end
+
+ let(:update_instance_url) { 'https://example.com' }
+
+ context 'without JWT' do
+ let(:jwt) { nil }
+
+ it 'returns 403' do
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
+ end
+
+ context 'with valid JWT' do
+ let(:qsh) { Atlassian::Jwt.create_query_string_hash('https://gitlab.test/subscriptions', 'GET', 'https://gitlab.test') }
+ let(:jwt) { Atlassian::Jwt.encode({ iss: installation.client_key, qsh: qsh }, installation.shared_secret) }
+
+ it 'returns 200' do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ it 'updates the instance_url' do
+ expect(json_response).to eq({
+ 'gitlab_com' => false,
+ 'instance_url' => 'https://example.com'
+ })
+ end
+
+ context 'invalid URL' do
+ let(:update_instance_url) { 'invalid url' }
+
+ it 'returns 422 and errors', :aggregate_failures do
+ expect(response).to have_gitlab_http_status(:unprocessable_entity)
+ expect(json_response).to eq({
+ 'errors' => {
+ 'instance_url' => [
+ 'is blocked: Only allowed schemes are http, https'
+ ]
+ }
+ })
+ end
+ end
+ end
+ end
+end
diff --git a/spec/requests/members/mailgun/permanent_failure_spec.rb b/spec/requests/members/mailgun/permanent_failure_spec.rb
new file mode 100644
index 00000000000..e47aedf8e94
--- /dev/null
+++ b/spec/requests/members/mailgun/permanent_failure_spec.rb
@@ -0,0 +1,128 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'receive a permanent failure' do
+ describe 'POST /members/mailgun/permanent_failures', :aggregate_failures do
+ let_it_be(:member) { create(:project_member, :invited) }
+
+ let(:raw_invite_token) { member.raw_invite_token }
+ let(:mailgun_events) { true }
+ let(:mailgun_signing_key) { 'abc123' }
+
+ subject(:post_request) { post members_mailgun_permanent_failures_path(standard_params) }
+
+ before do
+ stub_application_setting(mailgun_events_enabled: mailgun_events, mailgun_signing_key: mailgun_signing_key)
+ end
+
+ it 'marks the member invite email success as false' do
+ expect { post_request }.to change { member.reload.invite_email_success }.from(true).to(false)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ context 'when the change to a member is not made' do
+ context 'with incorrect signing key' do
+ context 'with incorrect signing key' do
+ let(:mailgun_signing_key) { '_foobar_' }
+
+ it 'does not change member status and responds as not_found' do
+ expect { post_request }.not_to change { member.reload.invite_email_success }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'with nil signing key' do
+ let(:mailgun_signing_key) { nil }
+
+ it 'does not change member status and responds as not_found' do
+ expect { post_request }.not_to change { member.reload.invite_email_success }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ context 'when the feature is not enabled' do
+ let(:mailgun_events) { false }
+
+ it 'does not change member status and responds as expected' do
+ expect { post_request }.not_to change { member.reload.invite_email_success }
+
+ expect(response).to have_gitlab_http_status(:not_acceptable)
+ end
+ end
+
+ context 'when it is not an invite email' do
+ before do
+ stub_const('::Members::Mailgun::INVITE_EMAIL_TAG', '_foobar_')
+ end
+
+ it 'does not change member status and responds as expected' do
+ expect { post_request }.not_to change { member.reload.invite_email_success }
+
+ expect(response).to have_gitlab_http_status(:not_acceptable)
+ end
+ end
+ end
+
+ def standard_params
+ {
+ "signature": {
+ "timestamp": "1625056677",
+ "token": "eb944d0ace7227667a1b97d2d07276ae51d2b849ed2cfa68f3",
+ "signature": "9790cc6686eb70f0b1f869180d906870cdfd496d27fee81da0aa86b9e539e790"
+ },
+ "event-data": {
+ "severity": "permanent",
+ "tags": ["invite_email"],
+ "timestamp": 1521233195.375624,
+ "storage": {
+ "url": "_anything_",
+ "key": "_anything_"
+ },
+ "log-level": "error",
+ "id": "_anything_",
+ "campaigns": [],
+ "reason": "suppress-bounce",
+ "user-variables": {
+ "invite_token": raw_invite_token
+ },
+ "flags": {
+ "is-routed": false,
+ "is-authenticated": true,
+ "is-system-test": false,
+ "is-test-mode": false
+ },
+ "recipient-domain": "example.com",
+ "envelope": {
+ "sender": "bob@mg.gitlab.com",
+ "transport": "smtp",
+ "targets": "alice@example.com"
+ },
+ "message": {
+ "headers": {
+ "to": "Alice <alice@example.com>",
+ "message-id": "20130503192659.13651.20287@mg.gitlab.com",
+ "from": "Bob <bob@mg.gitlab.com>",
+ "subject": "Test permanent_fail webhook"
+ },
+ "attachments": [],
+ "size": 111
+ },
+ "recipient": "alice@example.com",
+ "event": "failed",
+ "delivery-status": {
+ "attempt-no": 1,
+ "message": "",
+ "code": 605,
+ "description": "Not delivering to previously bounced address",
+ "session-seconds": 0
+ }
+ }
+ }
+ end
+ end
+end
diff --git a/spec/requests/oauth_tokens_spec.rb b/spec/requests/oauth_tokens_spec.rb
index 6d944bbc783..fdcc76f42cc 100644
--- a/spec/requests/oauth_tokens_spec.rb
+++ b/spec/requests/oauth_tokens_spec.rb
@@ -55,5 +55,29 @@ RSpec.describe 'OAuth Tokens requests' do
expect(json_response['access_token']).not_to be_nil
end
+
+ context 'when the application is configured to use expiring tokens' do
+ before do
+ application.update!(expire_access_tokens: true)
+ end
+
+ it 'generates an access token with an expiration' do
+ request_access_token(user)
+
+ expect(json_response['expires_in']).not_to be_nil
+ end
+ end
+
+ context 'when the application is configured not to use expiring tokens' do
+ before do
+ application.update!(expire_access_tokens: false)
+ end
+
+ it 'generates an access token without an expiration' do
+ request_access_token(user)
+
+ expect(json_response.key?('expires_in')).to eq(false)
+ end
+ end
end
end
diff --git a/spec/requests/openid_connect_spec.rb b/spec/requests/openid_connect_spec.rb
index 5bf786f2290..5ec23382698 100644
--- a/spec/requests/openid_connect_spec.rb
+++ b/spec/requests/openid_connect_spec.rb
@@ -149,7 +149,15 @@ RSpec.describe 'OpenID Connect requests' do
end
context 'ID token payload' do
+ let!(:group1) { create :group }
+ let!(:group2) { create :group }
+ let!(:group3) { create :group, parent: group2 }
+ let!(:group4) { create :group, parent: group3 }
+
before do
+ group1.add_user(user, Gitlab::Access::OWNER)
+ group3.add_user(user, Gitlab::Access::DEVELOPER)
+
request_access_token!
@payload = JSON::JWT.decode(json_response['id_token'], :skip_verification)
end
@@ -175,7 +183,12 @@ RSpec.describe 'OpenID Connect requests' do
end
it 'does not include any unknown properties' do
- expect(@payload.keys).to eq %w[iss sub aud exp iat auth_time sub_legacy email email_verified]
+ expect(@payload.keys).to eq %w[iss sub aud exp iat auth_time sub_legacy email email_verified groups_direct]
+ end
+
+ it 'does include groups' do
+ expected_groups = [group1.full_path, group3.full_path]
+ expect(@payload['groups_direct']).to match_array(expected_groups)
end
end
@@ -331,7 +344,15 @@ RSpec.describe 'OpenID Connect requests' do
end
context 'ID token payload' do
+ let!(:group1) { create :group }
+ let!(:group2) { create :group }
+ let!(:group3) { create :group, parent: group2 }
+ let!(:group4) { create :group, parent: group3 }
+
before do
+ group1.add_user(user, Gitlab::Access::OWNER)
+ group3.add_user(user, Gitlab::Access::DEVELOPER)
+
request_access_token!
@payload = JSON::JWT.decode(json_response['id_token'], :skip_verification)
end
@@ -343,6 +364,11 @@ RSpec.describe 'OpenID Connect requests' do
it 'has true in email_verified claim' do
expect(@payload['email_verified']).to eq(true)
end
+
+ it 'does include groups' do
+ expected_groups = [group1.full_path, group3.full_path]
+ expect(@payload['groups_direct']).to match_array(expected_groups)
+ end
end
end
end
diff --git a/spec/requests/projects/merge_requests_discussions_spec.rb b/spec/requests/projects/merge_requests_discussions_spec.rb
index c68745b9271..8057a091bba 100644
--- a/spec/requests/projects/merge_requests_discussions_spec.rb
+++ b/spec/requests/projects/merge_requests_discussions_spec.rb
@@ -59,6 +59,7 @@ RSpec.describe 'merge requests discussions' do
let!(:first_note) { create(:diff_note_on_merge_request, author: author, noteable: merge_request, project: project, note: "reference: #{reference.to_reference}") }
let!(:second_note) { create(:diff_note_on_merge_request, in_reply_to: first_note, noteable: merge_request, project: project) }
let!(:award_emoji) { create(:award_emoji, awardable: first_note) }
+ let!(:author_membership) { project.add_maintainer(author) }
before do
# Make a request to cache the discussions
@@ -229,6 +230,16 @@ RSpec.describe 'merge requests discussions' do
end
end
+ context 'when author role changes' do
+ before do
+ Members::UpdateService.new(user, access_level: Gitlab::Access::GUEST).execute(author_membership)
+ end
+
+ it_behaves_like 'cache miss' do
+ let(:changed_notes) { [first_note, second_note] }
+ end
+ end
+
context 'when merge_request_discussion_cache is disabled' do
before do
stub_feature_flags(merge_request_discussion_cache: false)
diff --git a/spec/requests/projects/usage_quotas_spec.rb b/spec/requests/projects/usage_quotas_spec.rb
new file mode 100644
index 00000000000..04e01da61ef
--- /dev/null
+++ b/spec/requests/projects/usage_quotas_spec.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Project Usage Quotas' do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:role) { :maintainer }
+ let_it_be(:user) { create(:user) }
+
+ before do
+ project.add_role(user, role)
+ login_as(user)
+ end
+
+ shared_examples 'response with 404 status' do
+ it 'renders :not_found' do
+ get project_usage_quotas_path(project)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(response.body).not_to include(project_usage_quotas_path(project))
+ end
+ end
+
+ describe 'GET /:namespace/:project/usage_quotas' do
+ context 'with project_storage_ui feature flag enabled' do
+ before do
+ stub_feature_flags(project_storage_ui: true)
+ end
+
+ it 'renders usage quotas path' do
+ mock_storage_app_data = {
+ project_path: project.full_path,
+ usage_quotas_help_page_path: help_page_path('user/usage_quotas'),
+ build_artifacts_help_page_path: help_page_path('ci/pipelines/job_artifacts', anchor: 'when-job-artifacts-are-deleted'),
+ packages_help_page_path: help_page_path('user/packages/package_registry/index.md', anchor: 'delete-a-package'),
+ repository_help_page_path: help_page_path('user/project/repository/reducing_the_repo_size_using_git'),
+ snippets_help_page_path: help_page_path('user/snippets', anchor: 'reduce-snippets-repository-size'),
+ wiki_help_page_path: help_page_path('administration/wikis/index.md', anchor: 'reduce-wiki-repository-size')
+ }
+ get project_usage_quotas_path(project)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.body).to include(project_usage_quotas_path(project))
+ expect(assigns[:storage_app_data]).to eq(mock_storage_app_data)
+ expect(response.body).to include("Usage of project resources across the <strong>#{project.name}</strong> project")
+ end
+
+ context 'renders :not_found for user without permission' do
+ let(:role) { :developer }
+
+ it_behaves_like 'response with 404 status'
+ end
+ end
+
+ context 'with project_storage_ui feature flag disabled' do
+ before do
+ stub_feature_flags(project_storage_ui: false)
+ end
+
+ it_behaves_like 'response with 404 status'
+ end
+ end
+end
diff --git a/spec/requests/rack_attack_global_spec.rb b/spec/requests/rack_attack_global_spec.rb
index a0f9d4c11ed..87ef6fa1a18 100644
--- a/spec/requests/rack_attack_global_spec.rb
+++ b/spec/requests/rack_attack_global_spec.rb
@@ -11,6 +11,8 @@ RSpec.describe 'Rack Attack global throttles', :use_clean_rails_memory_store_cac
# the right settings are being exercised
let(:settings_to_set) do
{
+ throttle_unauthenticated_api_requests_per_period: 100,
+ throttle_unauthenticated_api_period_in_seconds: 1,
throttle_unauthenticated_requests_per_period: 100,
throttle_unauthenticated_period_in_seconds: 1,
throttle_authenticated_api_requests_per_period: 100,
@@ -22,7 +24,13 @@ RSpec.describe 'Rack Attack global throttles', :use_clean_rails_memory_store_cac
throttle_unauthenticated_packages_api_requests_per_period: 100,
throttle_unauthenticated_packages_api_period_in_seconds: 1,
throttle_authenticated_packages_api_requests_per_period: 100,
- throttle_authenticated_packages_api_period_in_seconds: 1
+ throttle_authenticated_packages_api_period_in_seconds: 1,
+ throttle_authenticated_git_lfs_requests_per_period: 100,
+ throttle_authenticated_git_lfs_period_in_seconds: 1,
+ throttle_unauthenticated_files_api_requests_per_period: 100,
+ throttle_unauthenticated_files_api_period_in_seconds: 1,
+ throttle_authenticated_files_api_requests_per_period: 100,
+ throttle_authenticated_files_api_period_in_seconds: 1
}
end
@@ -33,186 +41,21 @@ RSpec.describe 'Rack Attack global throttles', :use_clean_rails_memory_store_cac
include_context 'rack attack cache store'
- describe 'unauthenticated requests' do
- let(:url_that_does_not_require_authentication) { '/users/sign_in' }
- let(:url_api_internal) { '/api/v4/internal/check' }
-
- before do
- # Disabling protected paths throttle, otherwise requests to
- # '/users/sign_in' are caught by this throttle.
- settings_to_set[:throttle_protected_paths_enabled] = false
-
- # Set low limits
- settings_to_set[:throttle_unauthenticated_requests_per_period] = requests_per_period
- settings_to_set[:throttle_unauthenticated_period_in_seconds] = period_in_seconds
- end
-
- context 'when the throttle is enabled' do
- before do
- settings_to_set[:throttle_unauthenticated_enabled] = true
- stub_application_setting(settings_to_set)
- end
-
- it 'rejects requests over the rate limit' do
- # At first, allow requests under the rate limit.
- requests_per_period.times do
- get url_that_does_not_require_authentication
- expect(response).to have_gitlab_http_status(:ok)
- end
-
- # the last straw
- expect_rejection { get url_that_does_not_require_authentication }
- end
-
- context 'with custom response text' do
- before do
- stub_application_setting(rate_limiting_response_text: 'Custom response')
- end
-
- it 'rejects requests over the rate limit' do
- # At first, allow requests under the rate limit.
- requests_per_period.times do
- get url_that_does_not_require_authentication
- expect(response).to have_gitlab_http_status(:ok)
- end
-
- # the last straw
- expect_rejection { get url_that_does_not_require_authentication }
- expect(response.body).to eq("Custom response\n")
- end
- end
-
- it 'allows requests after throttling and then waiting for the next period' do
- requests_per_period.times do
- get url_that_does_not_require_authentication
- expect(response).to have_gitlab_http_status(:ok)
- end
-
- expect_rejection { get url_that_does_not_require_authentication }
-
- travel_to(period.from_now) do
- requests_per_period.times do
- get url_that_does_not_require_authentication
- expect(response).to have_gitlab_http_status(:ok)
- end
-
- expect_rejection { get url_that_does_not_require_authentication }
- end
- end
-
- it 'counts requests from different IPs separately' do
- requests_per_period.times do
- get url_that_does_not_require_authentication
- expect(response).to have_gitlab_http_status(:ok)
- end
-
- expect_next_instance_of(Rack::Attack::Request) do |instance|
- expect(instance).to receive(:ip).at_least(:once).and_return('1.2.3.4')
- end
-
- # would be over limit for the same IP
- get url_that_does_not_require_authentication
- expect(response).to have_gitlab_http_status(:ok)
- end
-
- context 'when the request is to the api internal endpoints' do
- it 'allows requests over the rate limit' do
- (1 + requests_per_period).times do
- get url_api_internal, params: { secret_token: Gitlab::Shell.secret_token }
- expect(response).to have_gitlab_http_status(:ok)
- end
- end
- end
-
- context 'when the request is authenticated by a runner token' do
- let(:request_jobs_url) { '/api/v4/jobs/request' }
- let(:runner) { create(:ci_runner) }
-
- it 'does not count as unauthenticated' do
- (1 + requests_per_period).times do
- post request_jobs_url, params: { token: runner.token }
- expect(response).to have_gitlab_http_status(:no_content)
- end
- end
- end
-
- context 'when the request is to a health endpoint' do
- let(:health_endpoint) { '/-/metrics' }
-
- it 'does not throttle the requests' do
- (1 + requests_per_period).times do
- get health_endpoint
- expect(response).to have_gitlab_http_status(:ok)
- end
- end
- end
-
- context 'when the request is to a container registry notification endpoint' do
- let(:secret_token) { 'secret_token' }
- let(:events) { [{ action: 'push' }] }
- let(:registry_endpoint) { '/api/v4/container_registry_event/events' }
- let(:registry_headers) { { 'Content-Type' => ::API::ContainerRegistryEvent::DOCKER_DISTRIBUTION_EVENTS_V1_JSON } }
-
- before do
- allow(Gitlab.config.registry).to receive(:notification_secret) { secret_token }
-
- event = spy(:event)
- allow(::ContainerRegistry::Event).to receive(:new).and_return(event)
- allow(event).to receive(:supported?).and_return(true)
- end
-
- it 'does not throttle the requests' do
- (1 + requests_per_period).times do
- post registry_endpoint,
- params: { events: events }.to_json,
- headers: registry_headers.merge('Authorization' => secret_token)
-
- expect(response).to have_gitlab_http_status(:ok)
- end
- end
- end
-
- it 'logs RackAttack info into structured logs' do
- requests_per_period.times do
- get url_that_does_not_require_authentication
- expect(response).to have_gitlab_http_status(:ok)
- end
-
- arguments = a_hash_including({
- message: 'Rack_Attack',
- env: :throttle,
- remote_ip: '127.0.0.1',
- request_method: 'GET',
- path: '/users/sign_in',
- matched: 'throttle_unauthenticated'
- })
-
- expect(Gitlab::AuthLogger).to receive(:error).with(arguments)
-
- get url_that_does_not_require_authentication
- end
-
- it_behaves_like 'tracking when dry-run mode is set' do
- let(:throttle_name) { 'throttle_unauthenticated' }
-
- def do_request
- get url_that_does_not_require_authentication
- end
- end
+ describe 'unauthenticated API requests' do
+ it_behaves_like 'rate-limited unauthenticated requests' do
+ let(:throttle_name) { 'throttle_unauthenticated_api' }
+ let(:throttle_setting_prefix) { 'throttle_unauthenticated_api' }
+ let(:url_that_does_not_require_authentication) { '/api/v4/projects' }
+ let(:url_that_is_not_matched) { '/users/sign_in' }
end
+ end
- context 'when the throttle is disabled' do
- before do
- settings_to_set[:throttle_unauthenticated_enabled] = false
- stub_application_setting(settings_to_set)
- end
-
- it 'allows requests over the rate limit' do
- (1 + requests_per_period).times do
- get url_that_does_not_require_authentication
- expect(response).to have_gitlab_http_status(:ok)
- end
- end
+ describe 'unauthenticated web requests' do
+ it_behaves_like 'rate-limited unauthenticated requests' do
+ let(:throttle_name) { 'throttle_unauthenticated_web' }
+ let(:throttle_setting_prefix) { 'throttle_unauthenticated' }
+ let(:url_that_does_not_require_authentication) { '/users/sign_in' }
+ let(:url_that_is_not_matched) { '/api/v4/projects' }
end
end
@@ -473,9 +316,9 @@ RSpec.describe 'Rack Attack global throttles', :use_clean_rails_memory_store_cac
context 'when unauthenticated api throttle is enabled' do
before do
- settings_to_set[:throttle_unauthenticated_requests_per_period] = requests_per_period
- settings_to_set[:throttle_unauthenticated_period_in_seconds] = period_in_seconds
- settings_to_set[:throttle_unauthenticated_enabled] = true
+ settings_to_set[:throttle_unauthenticated_api_requests_per_period] = requests_per_period
+ settings_to_set[:throttle_unauthenticated_api_period_in_seconds] = period_in_seconds
+ settings_to_set[:throttle_unauthenticated_api_enabled] = true
stub_application_setting(settings_to_set)
end
@@ -488,6 +331,22 @@ RSpec.describe 'Rack Attack global throttles', :use_clean_rails_memory_store_cac
expect_rejection { do_request }
end
end
+
+ context 'when unauthenticated web throttle is enabled' do
+ before do
+ settings_to_set[:throttle_unauthenticated_web_requests_per_period] = requests_per_period
+ settings_to_set[:throttle_unauthenticated_web_period_in_seconds] = period_in_seconds
+ settings_to_set[:throttle_unauthenticated_web_enabled] = true
+ stub_application_setting(settings_to_set)
+ end
+
+ it 'ignores unauthenticated web throttle' do
+ (1 + requests_per_period).times do
+ do_request
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+ end
end
context 'when unauthenticated packages api throttle is enabled' do
@@ -509,9 +368,9 @@ RSpec.describe 'Rack Attack global throttles', :use_clean_rails_memory_store_cac
context 'when unauthenticated api throttle is lower' do
before do
- settings_to_set[:throttle_unauthenticated_requests_per_period] = 0
- settings_to_set[:throttle_unauthenticated_period_in_seconds] = period_in_seconds
- settings_to_set[:throttle_unauthenticated_enabled] = true
+ settings_to_set[:throttle_unauthenticated_api_requests_per_period] = 0
+ settings_to_set[:throttle_unauthenticated_api_period_in_seconds] = period_in_seconds
+ settings_to_set[:throttle_unauthenticated_api_enabled] = true
stub_application_setting(settings_to_set)
end
@@ -620,6 +479,317 @@ RSpec.describe 'Rack Attack global throttles', :use_clean_rails_memory_store_cac
end
end
+ describe 'authenticated git lfs requests', :api do
+ let_it_be(:project) { create(:project, :internal) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:token) { create(:personal_access_token, user: user) }
+ let_it_be(:other_user) { create(:user) }
+ let_it_be(:other_user_token) { create(:personal_access_token, user: other_user) }
+
+ let(:request_method) { 'GET' }
+ let(:throttle_setting_prefix) { 'throttle_authenticated_git_lfs' }
+ let(:git_lfs_url) { "/#{project.full_path}.git/info/lfs/locks" }
+
+ before do
+ allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
+ stub_application_setting(settings_to_set)
+ end
+
+ context 'with regular login' do
+ let(:url_that_requires_authentication) { git_lfs_url }
+
+ it_behaves_like 'rate-limited web authenticated requests'
+ end
+
+ context 'with the token in the headers' do
+ let(:request_args) { [git_lfs_url, { headers: basic_auth_headers(user, token) }] }
+ let(:other_user_request_args) { [git_lfs_url, { headers: basic_auth_headers(other_user, other_user_token) }] }
+
+ it_behaves_like 'rate-limited token-authenticated requests'
+ end
+
+ context 'precedence over authenticated web throttle' do
+ before do
+ settings_to_set[:throttle_authenticated_git_lfs_requests_per_period] = requests_per_period
+ settings_to_set[:throttle_authenticated_git_lfs_period_in_seconds] = period_in_seconds
+ end
+
+ def do_request
+ get git_lfs_url, headers: basic_auth_headers(user, token)
+ end
+
+ context 'when authenticated git lfs throttle is enabled' do
+ before do
+ settings_to_set[:throttle_authenticated_git_lfs_enabled] = true
+ end
+
+ context 'when authenticated web throttle is lower' do
+ before do
+ settings_to_set[:throttle_authenticated_web_requests_per_period] = 0
+ settings_to_set[:throttle_authenticated_web_period_in_seconds] = period_in_seconds
+ settings_to_set[:throttle_authenticated_web_enabled] = true
+ stub_application_setting(settings_to_set)
+ end
+
+ it 'ignores authenticated web throttle' do
+ requests_per_period.times do
+ do_request
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ expect_rejection { do_request }
+ end
+ end
+ end
+
+ context 'when authenticated git lfs throttle is disabled' do
+ before do
+ settings_to_set[:throttle_authenticated_git_lfs_enabled] = false
+ end
+
+ context 'when authenticated web throttle is enabled' do
+ before do
+ settings_to_set[:throttle_authenticated_web_requests_per_period] = requests_per_period
+ settings_to_set[:throttle_authenticated_web_period_in_seconds] = period_in_seconds
+ settings_to_set[:throttle_authenticated_web_enabled] = true
+ stub_application_setting(settings_to_set)
+ end
+
+ it 'rejects requests over the authenticated web rate limit' do
+ requests_per_period.times do
+ do_request
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ expect_rejection { do_request }
+ end
+ end
+ end
+ end
+ end
+
+ describe 'Files API' do
+ let(:request_method) { 'GET' }
+
+ context 'unauthenticated' do
+ let_it_be(:project) { create(:project, :public, :custom_repo, files: { 'README' => 'foo' }) }
+
+ let(:throttle_setting_prefix) { 'throttle_unauthenticated_files_api' }
+ let(:files_path_that_does_not_require_authentication) { "/api/v4/projects/#{project.id}/repository/files/README?ref=master" }
+
+ def do_request
+ get files_path_that_does_not_require_authentication
+ end
+
+ before do
+ settings_to_set[:throttle_unauthenticated_files_api_requests_per_period] = requests_per_period
+ settings_to_set[:throttle_unauthenticated_files_api_period_in_seconds] = period_in_seconds
+ end
+
+ context 'when unauthenticated files api throttle is disabled' do
+ before do
+ settings_to_set[:throttle_unauthenticated_files_api_enabled] = false
+ stub_application_setting(settings_to_set)
+ end
+
+ it 'allows requests over the rate limit' do
+ (1 + requests_per_period).times do
+ do_request
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'when unauthenticated api throttle is enabled' do
+ before do
+ settings_to_set[:throttle_unauthenticated_api_requests_per_period] = requests_per_period
+ settings_to_set[:throttle_unauthenticated_api_period_in_seconds] = period_in_seconds
+ settings_to_set[:throttle_unauthenticated_api_enabled] = true
+ stub_application_setting(settings_to_set)
+ end
+
+ it 'rejects requests over the unauthenticated api rate limit' do
+ requests_per_period.times do
+ do_request
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ expect_rejection { do_request }
+ end
+ end
+
+ context 'when unauthenticated web throttle is enabled' do
+ before do
+ settings_to_set[:throttle_unauthenticated_web_requests_per_period] = requests_per_period
+ settings_to_set[:throttle_unauthenticated_web_period_in_seconds] = period_in_seconds
+ settings_to_set[:throttle_unauthenticated_web_enabled] = true
+ stub_application_setting(settings_to_set)
+ end
+
+ it 'ignores unauthenticated web throttle' do
+ (1 + requests_per_period).times do
+ do_request
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+ end
+ end
+
+ context 'when unauthenticated files api throttle is enabled' do
+ before do
+ settings_to_set[:throttle_unauthenticated_files_api_requests_per_period] = requests_per_period # 1
+ settings_to_set[:throttle_unauthenticated_files_api_period_in_seconds] = period_in_seconds # 10_000
+ settings_to_set[:throttle_unauthenticated_files_api_enabled] = true
+ stub_application_setting(settings_to_set)
+ end
+
+ it 'rejects requests over the rate limit' do
+ requests_per_period.times do
+ do_request
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ expect_rejection { do_request }
+ end
+
+ context 'when feature flag is off' do
+ before do
+ stub_feature_flags(files_api_throttling: false)
+ end
+
+ it 'allows requests over the rate limit' do
+ (1 + requests_per_period).times do
+ do_request
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+ end
+
+ context 'when unauthenticated api throttle is lower' do
+ before do
+ settings_to_set[:throttle_unauthenticated_api_requests_per_period] = 0
+ settings_to_set[:throttle_unauthenticated_api_period_in_seconds] = period_in_seconds
+ settings_to_set[:throttle_unauthenticated_api_enabled] = true
+ stub_application_setting(settings_to_set)
+ end
+
+ it 'ignores unauthenticated api throttle' do
+ requests_per_period.times do
+ do_request
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ expect_rejection { do_request }
+ end
+ end
+
+ it_behaves_like 'tracking when dry-run mode is set' do
+ let(:throttle_name) { 'throttle_unauthenticated_files_api' }
+ end
+ end
+ end
+
+ context 'authenticated', :api do
+ let_it_be(:project) { create(:project, :internal, :custom_repo, files: { 'README' => 'foo' }) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:token) { create(:personal_access_token, user: user) }
+ let_it_be(:other_user) { create(:user) }
+ let_it_be(:other_user_token) { create(:personal_access_token, user: other_user) }
+
+ let(:throttle_setting_prefix) { 'throttle_authenticated_files_api' }
+ let(:api_partial_url) { "/projects/#{project.id}/repository/files/README?ref=master" }
+
+ before do
+ stub_application_setting(settings_to_set)
+ end
+
+ context 'with the token in the query string' do
+ let(:request_args) { [api(api_partial_url, personal_access_token: token), {}] }
+ let(:other_user_request_args) { [api(api_partial_url, personal_access_token: other_user_token), {}] }
+
+ it_behaves_like 'rate-limited token-authenticated requests'
+ end
+
+ context 'with the token in the headers' do
+ let(:request_args) { api_get_args_with_token_headers(api_partial_url, personal_access_token_headers(token)) }
+ let(:other_user_request_args) { api_get_args_with_token_headers(api_partial_url, personal_access_token_headers(other_user_token)) }
+
+ it_behaves_like 'rate-limited token-authenticated requests'
+ end
+
+ context 'precedence over authenticated api throttle' do
+ before do
+ settings_to_set[:throttle_authenticated_files_api_requests_per_period] = requests_per_period
+ settings_to_set[:throttle_authenticated_files_api_period_in_seconds] = period_in_seconds
+ end
+
+ def do_request
+ get api(api_partial_url, personal_access_token: token)
+ end
+
+ context 'when authenticated files api throttle is enabled' do
+ before do
+ settings_to_set[:throttle_authenticated_files_api_enabled] = true
+ end
+
+ context 'when authenticated api throttle is lower' do
+ before do
+ settings_to_set[:throttle_authenticated_api_requests_per_period] = 0
+ settings_to_set[:throttle_authenticated_api_period_in_seconds] = period_in_seconds
+ settings_to_set[:throttle_authenticated_api_enabled] = true
+ stub_application_setting(settings_to_set)
+ end
+
+ it 'ignores authenticated api throttle' do
+ requests_per_period.times do
+ do_request
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ expect_rejection { do_request }
+ end
+ end
+
+ context 'when feature flag is off' do
+ before do
+ stub_feature_flags(files_api_throttling: false)
+ end
+
+ it 'allows requests over the rate limit' do
+ (1 + requests_per_period).times do
+ do_request
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+ end
+ end
+
+ context 'when authenticated files api throttle is disabled' do
+ before do
+ settings_to_set[:throttle_authenticated_files_api_enabled] = false
+ end
+
+ context 'when authenticated api throttle is enabled' do
+ before do
+ settings_to_set[:throttle_authenticated_api_requests_per_period] = requests_per_period
+ settings_to_set[:throttle_authenticated_api_period_in_seconds] = period_in_seconds
+ settings_to_set[:throttle_authenticated_api_enabled] = true
+ stub_application_setting(settings_to_set)
+ end
+
+ it 'rejects requests over the authenticated api rate limit' do
+ requests_per_period.times do
+ do_request
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ expect_rejection { do_request }
+ end
+ end
+ end
+ end
+ end
+ end
+
describe 'throttle bypass header' do
let(:headers) { {} }
let(:bypass_header) { 'gitlab-bypass-rate-limiting' }
diff --git a/spec/requests/users/group_callouts_spec.rb b/spec/requests/users/group_callouts_spec.rb
new file mode 100644
index 00000000000..a8680c3add4
--- /dev/null
+++ b/spec/requests/users/group_callouts_spec.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Group callouts' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+
+ before do
+ sign_in(user)
+ end
+
+ describe 'POST /-/users/group_callouts' do
+ let(:params) { { feature_name: feature_name, group_id: group.id } }
+
+ subject { post group_callouts_path, params: params, headers: { 'ACCEPT' => 'application/json' } }
+
+ context 'with valid feature name and group' do
+ let(:feature_name) { Users::GroupCallout.feature_names.each_key.first }
+
+ context 'when callout entry does not exist' do
+ it 'creates a callout entry with dismissed state' do
+ expect { subject }.to change { Users::GroupCallout.count }.by(1)
+ end
+
+ it 'returns success' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'when callout entry already exists' do
+ let!(:callout) do
+ create(:group_callout,
+ feature_name: Users::GroupCallout.feature_names.each_key.first,
+ user: user,
+ group: group)
+ end
+
+ it 'returns success', :aggregate_failures do
+ expect { subject }.not_to change { Users::GroupCallout.count }
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+ end
+
+ context 'with invalid feature name' do
+ let(:feature_name) { 'bogus_feature_name' }
+
+ it 'returns bad request' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
+ end
+ end
+end
diff --git a/spec/rubocop/cop/gitlab/mark_used_feature_flags_spec.rb b/spec/rubocop/cop/gitlab/mark_used_feature_flags_spec.rb
index 35b21477d80..6b5b07fb357 100644
--- a/spec/rubocop/cop/gitlab/mark_used_feature_flags_spec.rb
+++ b/spec/rubocop/cop/gitlab/mark_used_feature_flags_spec.rb
@@ -16,6 +16,7 @@ RSpec.describe RuboCop::Cop::Gitlab::MarkUsedFeatureFlags do
stub_const("#{described_class}::DYNAMIC_FEATURE_FLAGS", [])
allow(cop).to receive(:defined_feature_flags).and_return(defined_feature_flags)
allow(cop).to receive(:usage_data_counters_known_event_feature_flags).and_return([])
+ described_class.feature_flags_already_tracked = false
end
def feature_flag_path(feature_flag_name)
diff --git a/spec/rubocop/cop/migration/add_limit_to_text_columns_spec.rb b/spec/rubocop/cop/migration/add_limit_to_text_columns_spec.rb
index 899872859a9..f6bed0d74fb 100644
--- a/spec/rubocop/cop/migration/add_limit_to_text_columns_spec.rb
+++ b/spec/rubocop/cop/migration/add_limit_to_text_columns_spec.rb
@@ -11,6 +11,7 @@ RSpec.describe RuboCop::Cop::Migration::AddLimitToTextColumns do
before do
allow(cop).to receive(:in_migration?).and_return(true)
+ allow(cop).to receive(:version).and_return(described_class::TEXT_LIMIT_ATTRIBUTE_ALLOWED_SINCE + 5)
end
context 'when text columns are defined without a limit' do
@@ -26,7 +27,7 @@ RSpec.describe RuboCop::Cop::Migration::AddLimitToTextColumns do
^^^^ #{msg}
end
- create_table_with_constraints :test_text_limits_create do |t|
+ create_table :test_text_limits_create do |t|
t.integer :test_id, null: false
t.text :title
t.text :description
@@ -61,13 +62,10 @@ RSpec.describe RuboCop::Cop::Migration::AddLimitToTextColumns do
t.text :name
end
- create_table_with_constraints :test_text_limits_create do |t|
+ create_table :test_text_limits_create do |t|
t.integer :test_id, null: false
- t.text :title
- t.text :description
-
- t.text_limit :title, 100
- t.text_limit :description, 255
+ t.text :title, limit: 100
+ t.text :description, limit: 255
end
add_column :test_text_limits, :email, :text
@@ -82,6 +80,30 @@ RSpec.describe RuboCop::Cop::Migration::AddLimitToTextColumns do
end
RUBY
end
+
+ context 'for migrations before 2021_09_10_00_00_00' do
+ it 'when limit: attribute is used (which is not supported yet for this version): registers an offense' do
+ allow(cop).to receive(:version).and_return(described_class::TEXT_LIMIT_ATTRIBUTE_ALLOWED_SINCE - 5)
+
+ expect_offense(<<~RUBY)
+ class TestTextLimits < ActiveRecord::Migration[6.0]
+ def up
+ create_table :test_text_limit_attribute do |t|
+ t.integer :test_id, null: false
+ t.text :name, limit: 100
+ ^^^^ Text columns should always have a limit set (255 is suggested). Using limit: is not supported in this version. You can add a limit to a `text` column by using `add_text_limit` or `.text_limit` inside `create_table`
+ end
+
+ create_table_with_constraints :test_text_limit_attribute do |t|
+ t.integer :test_id, null: false
+ t.text :name, limit: 100
+ ^^^^ Text columns should always have a limit set (255 is suggested). Using limit: is not supported in this version. You can add a limit to a `text` column by using `add_text_limit` or `.text_limit` inside `create_table`
+ end
+ end
+ end
+ RUBY
+ end
+ end
end
context 'when text array columns are defined without a limit' do
diff --git a/spec/rubocop/cop/migration/prevent_index_creation_spec.rb b/spec/rubocop/cop/migration/prevent_index_creation_spec.rb
index a3965f54bbd..ed7c8974d8d 100644
--- a/spec/rubocop/cop/migration/prevent_index_creation_spec.rb
+++ b/spec/rubocop/cop/migration/prevent_index_creation_spec.rb
@@ -6,28 +6,76 @@ require_relative '../../../../rubocop/cop/migration/prevent_index_creation'
RSpec.describe RuboCop::Cop::Migration::PreventIndexCreation do
subject(:cop) { described_class.new }
+ let(:forbidden_tables) { %w(ci_builds) }
+ let(:forbidden_tables_list) { forbidden_tables.join(', ') }
+
context 'when in migration' do
before do
allow(cop).to receive(:in_migration?).and_return(true)
end
context 'when adding an index to a forbidden table' do
- it 'registers an offense when add_index is used' do
- expect_offense(<<~RUBY)
- def change
- add_index :ci_builds, :protected
- ^^^^^^^^^ Adding new index to ci_builds is forbidden, see https://gitlab.com/gitlab-org/gitlab/-/issues/332886
+ context 'when table_name is a symbol' do
+ it "registers an offense when add_index is used", :aggregate_failures do
+ forbidden_tables.each do |table_name|
+ expect_offense(<<~RUBY)
+ def change
+ add_index :#{table_name}, :protected
+ ^^^^^^^^^ Adding new index to #{forbidden_tables_list} is forbidden, see https://gitlab.com/gitlab-org/gitlab/-/issues/332886
+ end
+ RUBY
end
- RUBY
+ end
+
+ it "registers an offense when add_concurrent_index is used", :aggregate_failures do
+ forbidden_tables.each do |table_name|
+ expect_offense(<<~RUBY)
+ def change
+ add_concurrent_index :#{table_name}, :protected
+ ^^^^^^^^^^^^^^^^^^^^ Adding new index to #{forbidden_tables_list} is forbidden, see https://gitlab.com/gitlab-org/gitlab/-/issues/332886
+ end
+ RUBY
+ end
+ end
end
- it 'registers an offense when add_concurrent_index is used' do
- expect_offense(<<~RUBY)
- def change
- add_concurrent_index :ci_builds, :protected
- ^^^^^^^^^^^^^^^^^^^^ Adding new index to ci_builds is forbidden, see https://gitlab.com/gitlab-org/gitlab/-/issues/332886
+ context 'when table_name is a string' do
+ it "registers an offense when add_index is used", :aggregate_failures do
+ forbidden_tables.each do |table_name|
+ expect_offense(<<~RUBY)
+ def change
+ add_index "#{table_name}", :protected
+ ^^^^^^^^^ Adding new index to #{forbidden_tables_list} is forbidden, see https://gitlab.com/gitlab-org/gitlab/-/issues/332886
+ end
+ RUBY
end
- RUBY
+ end
+
+ it "registers an offense when add_concurrent_index is used", :aggregate_failures do
+ forbidden_tables.each do |table_name|
+ expect_offense(<<~RUBY)
+ def change
+ add_concurrent_index "#{table_name}", :protected
+ ^^^^^^^^^^^^^^^^^^^^ Adding new index to #{forbidden_tables_list} is forbidden, see https://gitlab.com/gitlab-org/gitlab/-/issues/332886
+ end
+ RUBY
+ end
+ end
+ end
+
+ context 'when table_name is a constant' do
+ it "registers an offense when add_concurrent_index is used", :aggregate_failures do
+ expect_offense(<<~RUBY)
+ INDEX_NAME = "index_name"
+ TABLE_NAME = :ci_builds
+ disable_ddl_transaction!
+
+ def change
+ add_concurrent_index TABLE_NAME, :protected
+ ^^^^^^^^^^^^^^^^^^^^ Adding new index to #{forbidden_tables_list} is forbidden, see https://gitlab.com/gitlab-org/gitlab/-/issues/332886
+ end
+ RUBY
+ end
end
end
@@ -39,6 +87,20 @@ RSpec.describe RuboCop::Cop::Migration::PreventIndexCreation do
end
RUBY
end
+
+ context 'when using a constant' do
+ it 'does not register an offense' do
+ expect_no_offenses(<<~RUBY)
+ disable_ddl_transaction!
+
+ TABLE_NAME = "not_forbidden"
+
+ def up
+ add_concurrent_index TABLE_NAME, :protected
+ end
+ RUBY
+ end
+ end
end
end
diff --git a/spec/rubocop/cop/migration/versioned_migration_class_spec.rb b/spec/rubocop/cop/migration/versioned_migration_class_spec.rb
new file mode 100644
index 00000000000..d9b0cd4546c
--- /dev/null
+++ b/spec/rubocop/cop/migration/versioned_migration_class_spec.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require_relative '../../../../rubocop/cop/migration/versioned_migration_class'
+
+RSpec.describe RuboCop::Cop::Migration::VersionedMigrationClass do
+ subject(:cop) { described_class.new }
+
+ let(:migration) do
+ <<~SOURCE
+ class TestMigration < Gitlab::Database::Migration[1.0]
+ def up
+ execute 'select 1'
+ end
+
+ def down
+ execute 'select 1'
+ end
+ end
+ SOURCE
+ end
+
+ shared_examples 'a disabled cop' do
+ it 'does not register any offenses' do
+ expect_no_offenses(migration)
+ end
+ end
+
+ context 'outside of a migration' do
+ it_behaves_like 'a disabled cop'
+ end
+
+ context 'in migration' do
+ before do
+ allow(cop).to receive(:in_migration?).and_return(true)
+ end
+
+ context 'in an old migration' do
+ before do
+ allow(cop).to receive(:version).and_return(described_class::ENFORCED_SINCE - 5)
+ end
+
+ it_behaves_like 'a disabled cop'
+ end
+
+ context 'that is recent' do
+ before do
+ allow(cop).to receive(:version).and_return(described_class::ENFORCED_SINCE + 5)
+ end
+
+ it 'adds an offence if inheriting from ActiveRecord::Migration' do
+ expect_offense(<<~RUBY)
+ class MyMigration < ActiveRecord::Migration[6.1]
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Don't inherit from ActiveRecord::Migration but use Gitlab::Database::Migration[1.0] instead. See https://docs.gitlab.com/ee/development/migration_style_guide.html#migration-helpers-and-versioning.
+ end
+ RUBY
+ end
+
+ it 'adds an offence if including Gitlab::Database::MigrationHelpers directly' do
+ expect_offense(<<~RUBY)
+ class MyMigration < Gitlab::Database::Migration[1.0]
+ include Gitlab::Database::MigrationHelpers
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Don't include migration helper modules directly. Inherit from Gitlab::Database::Migration[1.0] instead. See https://docs.gitlab.com/ee/development/migration_style_guide.html#migration-helpers-and-versioning.
+ end
+ RUBY
+ end
+
+ it 'excludes ActiveRecord classes defined inside the migration' do
+ expect_no_offenses(<<~RUBY)
+ class TestMigration < Gitlab::Database::Migration[1.0]
+ class TestModel < ApplicationRecord
+ end
+
+ class AnotherTestModel < ActiveRecord::Base
+ end
+ end
+ RUBY
+ end
+ end
+ end
+end
diff --git a/spec/rubocop/cop/performance/active_record_subtransaction_methods_spec.rb b/spec/rubocop/cop/performance/active_record_subtransaction_methods_spec.rb
new file mode 100644
index 00000000000..df18121e2df
--- /dev/null
+++ b/spec/rubocop/cop/performance/active_record_subtransaction_methods_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require 'rspec-parameterized'
+
+require_relative '../../../../rubocop/cop/performance/active_record_subtransaction_methods'
+
+RSpec.describe RuboCop::Cop::Performance::ActiveRecordSubtransactionMethods do
+ subject(:cop) { described_class.new }
+
+ let(:message) { described_class::MSG }
+
+ shared_examples 'a method that uses a subtransaction' do |method_name|
+ it 'registers an offense' do
+ expect_offense(<<~RUBY, method_name: method_name, message: message)
+ Project.%{method_name}
+ ^{method_name} %{message}
+ RUBY
+ end
+ end
+
+ context 'when the method uses a subtransaction' do
+ where(:method) { described_class::DISALLOWED_METHODS.to_a }
+
+ with_them do
+ include_examples 'a method that uses a subtransaction', params[:method]
+ end
+ end
+end
diff --git a/spec/rubocop/cop/performance/active_record_subtransactions_spec.rb b/spec/rubocop/cop/performance/active_record_subtransactions_spec.rb
new file mode 100644
index 00000000000..0da2e30062a
--- /dev/null
+++ b/spec/rubocop/cop/performance/active_record_subtransactions_spec.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require_relative '../../../../rubocop/cop/performance/active_record_subtransactions'
+
+RSpec.describe RuboCop::Cop::Performance::ActiveRecordSubtransactions do
+ subject(:cop) { described_class.new }
+
+ let(:message) { described_class::MSG }
+
+ context 'when calling #transaction with only requires_new: true' do
+ it 'registers an offense' do
+ expect_offense(<<~RUBY)
+ ApplicationRecord.transaction(requires_new: true) do
+ ^^^^^^^^^^^^^^^^^^ #{message}
+ Project.create!(name: 'MyProject')
+ end
+ RUBY
+ end
+ end
+
+ context 'when passing multiple arguments to #transaction, including requires_new: true' do
+ it 'registers an offense' do
+ expect_offense(<<~RUBY)
+ ApplicationRecord.transaction(isolation: :read_committed, requires_new: true) do
+ ^^^^^^^^^^^^^^^^^^ #{message}
+ Project.create!(name: 'MyProject')
+ end
+ RUBY
+ end
+ end
+
+ context 'when calling #transaction with requires_new: false' do
+ it 'does not register an offense' do
+ expect_no_offenses(<<~RUBY)
+ ApplicationRecord.transaction(requires_new: false) do
+ Project.create!(name: 'MyProject')
+ end
+ RUBY
+ end
+ end
+
+ context 'when calling #transaction with other options' do
+ it 'does not register an offense' do
+ expect_no_offenses(<<~RUBY)
+ ApplicationRecord.transaction(isolation: :read_committed) do
+ Project.create!(name: 'MyProject')
+ end
+ RUBY
+ end
+ end
+
+ context 'when calling #transaction with no arguments' do
+ it 'does not register an offense' do
+ expect_no_offenses(<<~RUBY)
+ ApplicationRecord.transaction do
+ Project.create!(name: 'MyProject')
+ end
+ RUBY
+ end
+ end
+end
diff --git a/spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_spec.rb b/spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_spec.rb
new file mode 100644
index 00000000000..cf8d0d1b66f
--- /dev/null
+++ b/spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_spec.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require_relative '../../../../rubocop/cop/sidekiq_load_balancing/worker_data_consistency'
+
+RSpec.describe RuboCop::Cop::SidekiqLoadBalancing::WorkerDataConsistency do
+ subject(:cop) { described_class.new }
+
+ before do
+ allow(cop)
+ .to receive(:in_worker?)
+ .and_return(true)
+ end
+
+ it 'adds an offense when not defining data_consistency' do
+ expect_offense(<<~CODE)
+ class SomeWorker
+ ^^^^^^^^^^^^^^^^ Should define data_consistency expectation.[...]
+ include ApplicationWorker
+
+ queue_namespace :pipeline_hooks
+ feature_category :continuous_integration
+ urgency :high
+ end
+ CODE
+ end
+
+ it 'adds no offense when defining data_consistency' do
+ expect_no_offenses(<<~CODE)
+ class SomeWorker
+ include ApplicationWorker
+
+ queue_namespace :pipeline_hooks
+ feature_category :continuous_integration
+ data_consistency :delayed
+ urgency :high
+ end
+ CODE
+ end
+
+ it 'adds no offense when worker is not an ApplicationWorker' do
+ expect_no_offenses(<<~CODE)
+ class SomeWorker
+ queue_namespace :pipeline_hooks
+ feature_category :continuous_integration
+ urgency :high
+ end
+ CODE
+ end
+end
diff --git a/spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_with_deduplication_spec.rb b/spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_with_deduplication_spec.rb
new file mode 100644
index 00000000000..6e7212b1002
--- /dev/null
+++ b/spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_with_deduplication_spec.rb
@@ -0,0 +1,166 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require 'rspec-parameterized'
+require_relative '../../../../rubocop/cop/sidekiq_load_balancing/worker_data_consistency_with_deduplication'
+
+RSpec.describe RuboCop::Cop::SidekiqLoadBalancing::WorkerDataConsistencyWithDeduplication do
+ using RSpec::Parameterized::TableSyntax
+
+ subject(:cop) { described_class.new }
+
+ before do
+ allow(cop)
+ .to receive(:in_worker?)
+ .and_return(true)
+ end
+
+ where(:data_consistency) { %i[delayed sticky] }
+
+ with_them do
+ let(:strategy) { described_class::DEFAULT_STRATEGY }
+ let(:corrected) do
+ <<~CORRECTED
+ class SomeWorker
+ include ApplicationWorker
+
+ data_consistency :#{data_consistency}
+
+ deduplicate #{strategy}, including_scheduled: true
+ idempotent!
+ end
+ CORRECTED
+ end
+
+ context 'when deduplication strategy is not explicitly set' do
+ it 'registers an offense and corrects using default strategy' do
+ expect_offense(<<~CODE)
+ class SomeWorker
+ include ApplicationWorker
+
+ data_consistency :#{data_consistency}
+
+ idempotent!
+ ^^^^^^^^^^^ Workers that declare either `:sticky` or `:delayed` data consistency [...]
+ end
+ CODE
+
+ expect_correction(corrected)
+ end
+
+ context 'when identation is different' do
+ let(:corrected) do
+ <<~CORRECTED
+ class SomeWorker
+ include ApplicationWorker
+
+ data_consistency :#{data_consistency}
+
+ deduplicate #{strategy}, including_scheduled: true
+ idempotent!
+ end
+ CORRECTED
+ end
+
+ it 'registers an offense and corrects with correct identation' do
+ expect_offense(<<~CODE)
+ class SomeWorker
+ include ApplicationWorker
+
+ data_consistency :#{data_consistency}
+
+ idempotent!
+ ^^^^^^^^^^^ Workers that declare either `:sticky` or `:delayed` data consistency [...]
+ end
+ CODE
+
+ expect_correction(corrected)
+ end
+ end
+ end
+
+ context 'when deduplication strategy does not include including_scheduling option' do
+ let(:strategy) { ':until_executed' }
+
+ it 'registers an offense and corrects' do
+ expect_offense(<<~CODE)
+ class SomeWorker
+ include ApplicationWorker
+
+ data_consistency :#{data_consistency}
+
+ deduplicate :until_executed
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Workers that declare either `:sticky` or `:delayed` data consistency [...]
+ idempotent!
+ end
+ CODE
+
+ expect_correction(corrected)
+ end
+ end
+
+ context 'when deduplication strategy has including_scheduling option disabled' do
+ let(:strategy) { ':until_executed' }
+
+ it 'registers an offense and corrects' do
+ expect_offense(<<~CODE)
+ class SomeWorker
+ include ApplicationWorker
+
+ data_consistency :#{data_consistency}
+
+ deduplicate :until_executed, including_scheduled: false
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Workers that declare either `:sticky` or `:delayed` data consistency [...]
+ idempotent!
+ end
+ CODE
+
+ expect_correction(corrected)
+ end
+ end
+
+ context "when deduplication strategy is :none" do
+ it 'does not register an offense' do
+ expect_no_offenses(<<~CODE)
+ class SomeWorker
+ include ApplicationWorker
+
+ data_consistency :always
+
+ deduplicate :none
+ idempotent!
+ end
+ CODE
+ end
+ end
+
+ context "when deduplication strategy has including_scheduling option enabled" do
+ it 'does not register an offense' do
+ expect_no_offenses(<<~CODE)
+ class SomeWorker
+ include ApplicationWorker
+
+ data_consistency :always
+
+ deduplicate :until_executing, including_scheduled: true
+ idempotent!
+ end
+ CODE
+ end
+ end
+ end
+
+ context "data_consistency: :always" do
+ it 'does not register an offense' do
+ expect_no_offenses(<<~CODE)
+ class SomeWorker
+ include ApplicationWorker
+
+ data_consistency :always
+
+ idempotent!
+ end
+ CODE
+ end
+ end
+end
diff --git a/spec/rubocop/cop/worker_data_consistency_spec.rb b/spec/rubocop/cop/worker_data_consistency_spec.rb
deleted file mode 100644
index 5fa42bf2b87..00000000000
--- a/spec/rubocop/cop/worker_data_consistency_spec.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-# frozen_string_literal: true
-
-require 'fast_spec_helper'
-require_relative '../../../rubocop/cop/worker_data_consistency'
-
-RSpec.describe RuboCop::Cop::WorkerDataConsistency do
- subject(:cop) { described_class.new }
-
- before do
- allow(cop)
- .to receive(:in_worker?)
- .and_return(true)
- end
-
- it 'adds an offense when not defining data_consistency' do
- expect_offense(<<~CODE)
- class SomeWorker
- ^^^^^^^^^^^^^^^^ Should define data_consistency expectation.[...]
- include ApplicationWorker
-
- queue_namespace :pipeline_hooks
- feature_category :continuous_integration
- urgency :high
- end
- CODE
- end
-
- it 'adds no offense when defining data_consistency' do
- expect_no_offenses(<<~CODE)
- class SomeWorker
- include ApplicationWorker
-
- queue_namespace :pipeline_hooks
- feature_category :continuous_integration
- data_consistency :delayed
- urgency :high
- end
- CODE
- end
-
- it 'adds no offense when worker is not an ApplicationWorker' do
- expect_no_offenses(<<~CODE)
- class SomeWorker
- queue_namespace :pipeline_hooks
- feature_category :continuous_integration
- urgency :high
- end
- CODE
- end
-end
diff --git a/spec/serializers/group_child_entity_spec.rb b/spec/serializers/group_child_entity_spec.rb
index 7f330da44a7..e4844c25067 100644
--- a/spec/serializers/group_child_entity_spec.rb
+++ b/spec/serializers/group_child_entity_spec.rb
@@ -87,7 +87,7 @@ RSpec.describe GroupChildEntity do
expect(json[:children_count]).to eq(2)
end
- %w[children_count leave_path parent_id number_projects_with_delimiter number_users_with_delimiter project_count subgroup_count].each do |attribute|
+ %w[children_count leave_path parent_id number_users_with_delimiter project_count subgroup_count].each do |attribute|
it "includes #{attribute}" do
expect(json[attribute.to_sym]).to be_present
end
@@ -114,6 +114,40 @@ RSpec.describe GroupChildEntity do
it_behaves_like 'group child json'
end
+ describe 'for a private group' do
+ let(:object) do
+ create(:group, :private)
+ end
+
+ describe 'user is member of the group' do
+ before do
+ object.add_owner(user)
+ end
+
+ it 'includes the counts' do
+ expect(json.keys).to include(*%i(project_count subgroup_count))
+ end
+ end
+
+ describe 'user is not a member of the group' do
+ it 'does not include the counts' do
+ expect(json.keys).not_to include(*%i(project_count subgroup_count))
+ end
+ end
+
+ describe 'user is only a member of a project in the group' do
+ let(:project) { create(:project, namespace: object) }
+
+ before do
+ project.add_guest(user)
+ end
+
+ it 'does not include the counts' do
+ expect(json.keys).not_to include(*%i(project_count subgroup_count))
+ end
+ end
+ end
+
describe 'for a project with external authorization enabled' do
let(:object) do
create(:project, :with_avatar,
diff --git a/spec/serializers/issuable_sidebar_extras_entity_spec.rb b/spec/serializers/issuable_sidebar_extras_entity_spec.rb
index f49b9acfd5d..80c135cdc22 100644
--- a/spec/serializers/issuable_sidebar_extras_entity_spec.rb
+++ b/spec/serializers/issuable_sidebar_extras_entity_spec.rb
@@ -10,11 +10,7 @@ RSpec.describe IssuableSidebarExtrasEntity do
subject { described_class.new(resource, request: request).as_json }
- it 'have subscribe attributes' do
- expect(subject).to include(:participants,
- :project_emails_disabled,
- :subscribe_disabled_description,
- :subscribed,
- :assignees)
+ it 'have assignee attribute' do
+ expect(subject).to include(:assignees)
end
end
diff --git a/spec/serializers/pipeline_serializer_spec.rb b/spec/serializers/pipeline_serializer_spec.rb
index bcad9eb6e23..587d167520f 100644
--- a/spec/serializers/pipeline_serializer_spec.rb
+++ b/spec/serializers/pipeline_serializer_spec.rb
@@ -202,7 +202,7 @@ RSpec.describe PipelineSerializer do
# Existing numbers are high and require performance optimization
# Ongoing issue:
# https://gitlab.com/gitlab-org/gitlab/-/issues/225156
- expected_queries = Gitlab.ee? ? 77 : 70
+ expected_queries = Gitlab.ee? ? 74 : 70
expect(recorded.count).to be_within(2).of(expected_queries)
expect(recorded.cached_count).to eq(0)
diff --git a/spec/services/application_settings/update_service_spec.rb b/spec/services/application_settings/update_service_spec.rb
index 56c1284927d..a1fd89bcad7 100644
--- a/spec/services/application_settings/update_service_spec.rb
+++ b/spec/services/application_settings/update_service_spec.rb
@@ -336,6 +336,31 @@ RSpec.describe ApplicationSettings::UpdateService do
end
end
+ context 'when general rate limits are passed' do
+ let(:params) do
+ {
+ throttle_authenticated_api_enabled: true,
+ throttle_authenticated_api_period_in_seconds: 10,
+ throttle_authenticated_api_requests_per_period: 20,
+ throttle_authenticated_web_enabled: true,
+ throttle_authenticated_web_period_in_seconds: 30,
+ throttle_authenticated_web_requests_per_period: 40,
+ throttle_unauthenticated_api_enabled: true,
+ throttle_unauthenticated_api_period_in_seconds: 50,
+ throttle_unauthenticated_api_requests_per_period: 60,
+ throttle_unauthenticated_enabled: true,
+ throttle_unauthenticated_period_in_seconds: 50,
+ throttle_unauthenticated_requests_per_period: 60
+ }
+ end
+
+ it 'updates general throttle settings' do
+ subject.execute
+
+ expect(application_settings.reload).to have_attributes(params)
+ end
+ end
+
context 'when package registry rate limits are passed' do
let(:params) do
{
@@ -362,6 +387,52 @@ RSpec.describe ApplicationSettings::UpdateService do
end
end
+ context 'when files API rate limits are passed' do
+ let(:params) do
+ {
+ throttle_unauthenticated_files_api_enabled: 1,
+ throttle_unauthenticated_files_api_period_in_seconds: 500,
+ throttle_unauthenticated_files_api_requests_per_period: 20,
+ throttle_authenticated_files_api_enabled: 1,
+ throttle_authenticated_files_api_period_in_seconds: 600,
+ throttle_authenticated_files_api_requests_per_period: 10
+ }
+ end
+
+ it 'updates files API throttle settings' do
+ subject.execute
+
+ application_settings.reload
+
+ expect(application_settings.throttle_unauthenticated_files_api_enabled).to be_truthy
+ expect(application_settings.throttle_unauthenticated_files_api_period_in_seconds).to eq(500)
+ expect(application_settings.throttle_unauthenticated_files_api_requests_per_period).to eq(20)
+ expect(application_settings.throttle_authenticated_files_api_enabled).to be_truthy
+ expect(application_settings.throttle_authenticated_files_api_period_in_seconds).to eq(600)
+ expect(application_settings.throttle_authenticated_files_api_requests_per_period).to eq(10)
+ end
+ end
+
+ context 'when git lfs rate limits are passed' do
+ let(:params) do
+ {
+ throttle_authenticated_git_lfs_enabled: 1,
+ throttle_authenticated_git_lfs_period_in_seconds: 600,
+ throttle_authenticated_git_lfs_requests_per_period: 10
+ }
+ end
+
+ it 'updates git lfs throttle settings' do
+ subject.execute
+
+ application_settings.reload
+
+ expect(application_settings.throttle_authenticated_git_lfs_enabled).to be_truthy
+ expect(application_settings.throttle_authenticated_git_lfs_period_in_seconds).to eq(600)
+ expect(application_settings.throttle_authenticated_git_lfs_requests_per_period).to eq(10)
+ end
+ end
+
context 'when issues_create_limit is passed' do
let(:params) do
{
diff --git a/spec/services/auth/container_registry_authentication_service_spec.rb b/spec/services/auth/container_registry_authentication_service_spec.rb
index b456f7a2745..46cc027fcb3 100644
--- a/spec/services/auth/container_registry_authentication_service_spec.rb
+++ b/spec/services/auth/container_registry_authentication_service_spec.rb
@@ -84,5 +84,36 @@ RSpec.describe Auth::ContainerRegistryAuthenticationService do
it_behaves_like 'a modified token'
end
+
+ describe '#access_token' do
+ let(:token) { described_class.access_token(%w[push], [project.full_path]) }
+
+ subject { { token: token } }
+
+ it_behaves_like 'a modified token'
+ end
+ end
+
+ context 'when not in migration mode' do
+ include_context 'container registry auth service context'
+
+ let_it_be(:project) { create(:project) }
+
+ before do
+ stub_feature_flags(container_registry_migration_phase1: false)
+ end
+
+ shared_examples 'an unmodified token' do
+ it_behaves_like 'a valid token'
+ it { expect(payload['access']).not_to include(have_key('migration_eligible')) }
+ end
+
+ describe '#access_token' do
+ let(:token) { described_class.access_token(%w[push], [project.full_path]) }
+
+ subject { { token: token } }
+
+ it_behaves_like 'an unmodified token'
+ end
end
end
diff --git a/spec/services/boards/issues/list_service_spec.rb b/spec/services/boards/issues/list_service_spec.rb
index bbdc178b234..d1f854f72bc 100644
--- a/spec/services/boards/issues/list_service_spec.rb
+++ b/spec/services/boards/issues/list_service_spec.rb
@@ -139,4 +139,51 @@ RSpec.describe Boards::Issues::ListService do
end
# rubocop: enable RSpec/MultipleMemoizedHelpers
end
+
+ describe '.initialize_relative_positions' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :empty_repo) }
+ let_it_be(:board) { create(:board, project: project) }
+ let_it_be(:backlog) { create(:backlog_list, board: board) }
+
+ let(:issue) { create(:issue, project: project, relative_position: nil) }
+
+ context "when 'Gitlab::Database::read_write?' is true" do
+ before do
+ allow(Gitlab::Database).to receive(:read_write?).and_return(true)
+ end
+
+ context 'user cannot move issues' do
+ it 'does not initialize the relative positions of issues' do
+ described_class.initialize_relative_positions(board, user, [issue])
+
+ expect(issue.relative_position).to eq nil
+ end
+ end
+
+ context 'user can move issues' do
+ before do
+ project.add_developer(user)
+ end
+
+ it 'initializes the relative positions of issues' do
+ described_class.initialize_relative_positions(board, user, [issue])
+
+ expect(issue.relative_position).not_to eq nil
+ end
+ end
+ end
+
+ context "when 'Gitlab::Database::read_write?' is false" do
+ before do
+ allow(Gitlab::Database).to receive(:read_write?).and_return(false)
+ end
+
+ it 'does not initialize the relative positions of issues' do
+ described_class.initialize_relative_positions(board, user, [issue])
+
+ expect(issue.relative_position).to eq nil
+ end
+ end
+ end
end
diff --git a/spec/services/ci/after_requeue_job_service_spec.rb b/spec/services/ci/after_requeue_job_service_spec.rb
index df5ddcafb37..2a5a971fdac 100644
--- a/spec/services/ci/after_requeue_job_service_spec.rb
+++ b/spec/services/ci/after_requeue_job_service_spec.rb
@@ -44,16 +44,6 @@ RSpec.describe Ci::AfterRequeueJobService do
it 'marks subsequent skipped jobs as processable' do
expect { execute_service }.to change { test4.reload.status }.from('skipped').to('created')
end
-
- context 'with ci_same_stage_job_needs FF disabled' do
- before do
- stub_feature_flags(ci_same_stage_job_needs: false)
- end
-
- it 'does nothing with the build' do
- expect { execute_service }.not_to change { test4.reload.status }
- end
- end
end
context 'when the pipeline is a downstream pipeline and the bridge is depended' do
diff --git a/spec/services/ci/archive_trace_service_spec.rb b/spec/services/ci/archive_trace_service_spec.rb
index 12804efc28c..071b5c3b2f9 100644
--- a/spec/services/ci/archive_trace_service_spec.rb
+++ b/spec/services/ci/archive_trace_service_spec.rb
@@ -12,6 +12,7 @@ RSpec.describe Ci::ArchiveTraceService, '#execute' do
expect { subject }.not_to raise_error
expect(job.reload.job_artifacts_trace).to be_exist
+ expect(job.trace_metadata.trace_artifact).to eq(job.job_artifacts_trace)
end
context 'when trace is already archived' do
@@ -27,7 +28,7 @@ RSpec.describe Ci::ArchiveTraceService, '#execute' do
context 'when live trace chunks still exist' do
before do
- create(:ci_build_trace_chunk, build: job)
+ create(:ci_build_trace_chunk, build: job, chunk_index: 0)
end
it 'removes the trace chunks' do
@@ -39,8 +40,14 @@ RSpec.describe Ci::ArchiveTraceService, '#execute' do
job.job_artifacts_trace.file.remove!
end
- it 'removes the trace artifact' do
- expect { subject }.to change { job.reload.job_artifacts_trace }.to(nil)
+ it 'removes the trace artifact and builds a new one' do
+ existing_trace = job.job_artifacts_trace
+ expect(existing_trace).to receive(:destroy!).and_call_original
+
+ subject
+
+ expect(job.reload.job_artifacts_trace).to be_present
+ expect(job.reload.job_artifacts_trace.file.file).to be_present
end
end
end
@@ -59,6 +66,54 @@ RSpec.describe Ci::ArchiveTraceService, '#execute' do
end
end
+ context 'when the job is out of archival attempts' do
+ before do
+ create(:ci_build_trace_metadata,
+ build: job,
+ archival_attempts: Ci::BuildTraceMetadata::MAX_ATTEMPTS + 1,
+ last_archival_attempt_at: 1.week.ago)
+ end
+
+ it 'skips archiving' do
+ expect(job.trace).not_to receive(:archive!)
+
+ subject
+ end
+
+ it 'leaves a warning message in sidekiq log' do
+ expect(Sidekiq.logger).to receive(:warn).with(
+ class: Ci::ArchiveTraceWorker.name,
+ message: 'The job is out of archival attempts.',
+ job_id: job.id)
+
+ subject
+ end
+ end
+
+ context 'when the archival process is backed off' do
+ before do
+ create(:ci_build_trace_metadata,
+ build: job,
+ archival_attempts: Ci::BuildTraceMetadata::MAX_ATTEMPTS - 1,
+ last_archival_attempt_at: 1.hour.ago)
+ end
+
+ it 'skips archiving' do
+ expect(job.trace).not_to receive(:archive!)
+
+ subject
+ end
+
+ it 'leaves a warning message in sidekiq log' do
+ expect(Sidekiq.logger).to receive(:warn).with(
+ class: Ci::ArchiveTraceWorker.name,
+ message: 'The job can not be archived right now.',
+ job_id: job.id)
+
+ subject
+ end
+ end
+
context 'when job failed to archive trace but did not raise an exception' do
before do
allow_next_instance_of(Gitlab::Ci::Trace) do |instance|
@@ -98,6 +153,7 @@ RSpec.describe Ci::ArchiveTraceService, '#execute' do
.and_call_original
expect { subject }.not_to raise_error
+ expect(job.trace_metadata.archival_attempts).to eq(1)
end
end
end
diff --git a/spec/services/ci/create_pipeline_service/parent_child_pipeline_spec.rb b/spec/services/ci/create_pipeline_service/parent_child_pipeline_spec.rb
index 6eb1315fff4..4326fa5533f 100644
--- a/spec/services/ci/create_pipeline_service/parent_child_pipeline_spec.rb
+++ b/spec/services/ci/create_pipeline_service/parent_child_pipeline_spec.rb
@@ -127,6 +127,32 @@ RSpec.describe Ci::CreatePipelineService, '#execute' do
end
end
end
+
+ context 'when resource group key includes a variable' do
+ let(:config) do
+ <<~YAML
+ instrumentation_test:
+ stage: test
+ resource_group: $CI_ENVIRONMENT_NAME
+ trigger:
+ include: path/to/child.yml
+ strategy: depend
+ YAML
+ end
+
+ it 'ignores the resource group keyword because it fails to expand the variable', :aggregate_failures do
+ pipeline = create_pipeline!
+ Ci::InitialPipelineProcessWorker.new.perform(pipeline.id)
+
+ test = pipeline.statuses.find_by(name: 'instrumentation_test')
+ expect(pipeline).to be_created_successfully
+ expect(pipeline.triggered_pipelines).not_to be_exist
+ expect(project.resource_groups.count).to eq(0)
+ expect(test).to be_a Ci::Bridge
+ expect(test).to be_pending
+ expect(test.resource_group).to be_nil
+ end
+ end
end
end
diff --git a/spec/services/ci/create_pipeline_service/tags_spec.rb b/spec/services/ci/create_pipeline_service/tags_spec.rb
new file mode 100644
index 00000000000..335d35010c8
--- /dev/null
+++ b/spec/services/ci/create_pipeline_service/tags_spec.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Ci::CreatePipelineService do
+ describe 'tags:' do
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:user) { project.owner }
+
+ let(:ref) { 'refs/heads/master' }
+ let(:source) { :push }
+ let(:service) { described_class.new(project, user, { ref: ref }) }
+ let(:pipeline) { service.execute(source).payload }
+
+ before do
+ stub_ci_pipeline_yaml_file(config)
+ end
+
+ context 'with valid config' do
+ let(:config) { YAML.dump({ test: { script: 'ls', tags: %w[tag1 tag2] } }) }
+
+ it 'creates a pipeline', :aggregate_failures do
+ expect(pipeline).to be_created_successfully
+ expect(pipeline.builds.first.tag_list).to match_array(%w[tag1 tag2])
+ end
+ end
+
+ context 'with too many tags' do
+ let(:tags) { Array.new(50) {|i| "tag-#{i}" } }
+ let(:config) { YAML.dump({ test: { script: 'ls', tags: tags } }) }
+
+ it 'creates a pipeline without builds', :aggregate_failures do
+ expect(pipeline).not_to be_created_successfully
+ expect(pipeline.builds).to be_empty
+ expect(pipeline.yaml_errors).to eq("jobs:test:tags config must be less than the limit of #{Gitlab::Ci::Config::Entry::Tags::TAGS_LIMIT} tags")
+ end
+ end
+ end
+end
diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb
index 2fdb0ed3c0d..78646665539 100644
--- a/spec/services/ci/create_pipeline_service_spec.rb
+++ b/spec/services/ci/create_pipeline_service_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe Ci::CreatePipelineService do
let(:ref_name) { 'refs/heads/master' }
before do
- stub_ci_pipeline_yaml_file(gitlab_ci_yaml)
+ stub_ci_pipeline_to_return_yaml_file
end
describe '#execute' do
@@ -991,6 +991,58 @@ RSpec.describe Ci::CreatePipelineService do
end
end
+ context 'when resource group is defined for review app deployment' do
+ before do
+ config = YAML.dump(
+ review_app: {
+ stage: 'test',
+ script: 'deploy',
+ environment: {
+ name: 'review/$CI_COMMIT_REF_SLUG',
+ on_stop: 'stop_review_app'
+ },
+ resource_group: '$CI_ENVIRONMENT_NAME'
+ },
+ stop_review_app: {
+ stage: 'test',
+ script: 'stop',
+ when: 'manual',
+ environment: {
+ name: 'review/$CI_COMMIT_REF_SLUG',
+ action: 'stop'
+ },
+ resource_group: '$CI_ENVIRONMENT_NAME'
+ }
+ )
+
+ stub_ci_pipeline_yaml_file(config)
+ end
+
+ it 'persists the association correctly' do
+ result = execute_service.payload
+ deploy_job = result.builds.find_by_name!(:review_app)
+ stop_job = result.builds.find_by_name!(:stop_review_app)
+
+ expect(result).to be_persisted
+ expect(deploy_job.resource_group.key).to eq('review/master')
+ expect(stop_job.resource_group.key).to eq('review/master')
+ expect(project.resource_groups.count).to eq(1)
+ end
+
+ it 'initializes scoped variables only once for each build' do
+ # Bypassing `stub_build` hack because it distrubs the expectations below.
+ allow_next_instances_of(Gitlab::Ci::Build::Context::Build, 2) do |build_context|
+ allow(build_context).to receive(:variables) { Gitlab::Ci::Variables::Collection.new }
+ end
+
+ expect_next_instances_of(::Ci::Build, 2) do |ci_build|
+ expect(ci_build).to receive(:scoped_variables).once.and_call_original
+ end
+
+ expect(execute_service.payload).to be_created_successfully
+ end
+ end
+
context 'with timeout' do
context 'when builds with custom timeouts are configured' do
before do
@@ -1248,16 +1300,47 @@ RSpec.describe Ci::CreatePipelineService do
end
context 'when pipeline variables are specified' do
- let(:variables_attributes) do
- [{ key: 'first', secret_value: 'world' },
- { key: 'second', secret_value: 'second_world' }]
+ subject(:pipeline) { execute_service(variables_attributes: variables_attributes).payload }
+
+ context 'with valid pipeline variables' do
+ let(:variables_attributes) do
+ [{ key: 'first', secret_value: 'world' },
+ { key: 'second', secret_value: 'second_world' }]
+ end
+
+ it 'creates a pipeline with specified variables' do
+ expect(pipeline.variables.map { |var| var.slice(:key, :secret_value) })
+ .to eq variables_attributes.map(&:with_indifferent_access)
+ end
end
- subject(:pipeline) { execute_service(variables_attributes: variables_attributes).payload }
+ context 'with duplicate pipeline variables' do
+ let(:variables_attributes) do
+ [{ key: 'hello', secret_value: 'world' },
+ { key: 'hello', secret_value: 'second_world' }]
+ end
- it 'creates a pipeline with specified variables' do
- expect(pipeline.variables.map { |var| var.slice(:key, :secret_value) })
- .to eq variables_attributes.map(&:with_indifferent_access)
+ it 'fails to create the pipeline' do
+ expect(pipeline).to be_failed
+ expect(pipeline.variables).to be_empty
+ expect(pipeline.errors[:base]).to eq(['Duplicate variable name: hello'])
+ end
+ end
+
+ context 'with more than one duplicate pipeline variable' do
+ let(:variables_attributes) do
+ [{ key: 'hello', secret_value: 'world' },
+ { key: 'hello', secret_value: 'second_world' },
+ { key: 'single', secret_value: 'variable' },
+ { key: 'other', secret_value: 'value' },
+ { key: 'other', secret_value: 'other value' }]
+ end
+
+ it 'fails to create the pipeline' do
+ expect(pipeline).to be_failed
+ expect(pipeline.variables).to be_empty
+ expect(pipeline.errors[:base]).to eq(['Duplicate variable names: hello, other'])
+ end
end
end
diff --git a/spec/services/ci/external_pull_requests/create_pipeline_service_spec.rb b/spec/services/ci/external_pull_requests/create_pipeline_service_spec.rb
index 2b310443b37..04d75630295 100644
--- a/spec/services/ci/external_pull_requests/create_pipeline_service_spec.rb
+++ b/spec/services/ci/external_pull_requests/create_pipeline_service_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe Ci::ExternalPullRequests::CreatePipelineService do
project.add_maintainer(user)
end
- subject(:response) { described_class.new(project, user).execute(pull_request) }
+ subject(:execute) { described_class.new(project, user).execute(pull_request) }
context 'when pull request is open' do
before do
@@ -21,26 +21,43 @@ RSpec.describe Ci::ExternalPullRequests::CreatePipelineService do
context 'when source sha is the head of the source branch' do
let(:source_branch) { project.repository.branches.last }
- let(:create_pipeline_service) { instance_double(Ci::CreatePipelineService) }
before do
pull_request.update!(source_branch: source_branch.name, source_sha: source_branch.target)
end
- it 'creates a pipeline for external pull request', :aggregate_failures do
- pipeline = response.payload
-
- expect(response).to be_success
- expect(pipeline).to be_valid
- expect(pipeline).to be_persisted
- expect(pipeline).to be_external_pull_request_event
- expect(pipeline).to eq(project.ci_pipelines.last)
- expect(pipeline.external_pull_request).to eq(pull_request)
- expect(pipeline.user).to eq(user)
- expect(pipeline.status).to eq('created')
- expect(pipeline.ref).to eq(pull_request.source_branch)
- expect(pipeline.sha).to eq(pull_request.source_sha)
- expect(pipeline.source_sha).to eq(pull_request.source_sha)
+ context 'when the FF ci_create_external_pr_pipeline_async is disabled' do
+ before do
+ stub_feature_flags(ci_create_external_pr_pipeline_async: false)
+ end
+
+ it 'creates a pipeline for external pull request', :aggregate_failures do
+ pipeline = execute.payload
+
+ expect(execute).to be_success
+ expect(pipeline).to be_valid
+ expect(pipeline).to be_persisted
+ expect(pipeline).to be_external_pull_request_event
+ expect(pipeline).to eq(project.ci_pipelines.last)
+ expect(pipeline.external_pull_request).to eq(pull_request)
+ expect(pipeline.user).to eq(user)
+ expect(pipeline.status).to eq('created')
+ expect(pipeline.ref).to eq(pull_request.source_branch)
+ expect(pipeline.sha).to eq(pull_request.source_sha)
+ expect(pipeline.source_sha).to eq(pull_request.source_sha)
+ end
+ end
+
+ it 'enqueues Ci::ExternalPullRequests::CreatePipelineWorker' do
+ expect { execute }
+ .to change { ::Ci::ExternalPullRequests::CreatePipelineWorker.jobs.count }
+ .by(1)
+
+ args = ::Ci::ExternalPullRequests::CreatePipelineWorker.jobs.last['args']
+
+ expect(args[0]).to eq(project.id)
+ expect(args[1]).to eq(user.id)
+ expect(args[2]).to eq(pull_request.id)
end
end
@@ -53,11 +70,12 @@ RSpec.describe Ci::ExternalPullRequests::CreatePipelineService do
end
it 'does nothing', :aggregate_failures do
- expect(Ci::CreatePipelineService).not_to receive(:new)
+ expect { execute }
+ .not_to change { ::Ci::ExternalPullRequests::CreatePipelineWorker.jobs.count }
- expect(response).to be_error
- expect(response.message).to eq('The source sha is not the head of the source branch')
- expect(response.payload).to be_nil
+ expect(execute).to be_error
+ expect(execute.message).to eq('The source sha is not the head of the source branch')
+ expect(execute.payload).to be_nil
end
end
end
@@ -68,11 +86,12 @@ RSpec.describe Ci::ExternalPullRequests::CreatePipelineService do
end
it 'does nothing', :aggregate_failures do
- expect(Ci::CreatePipelineService).not_to receive(:new)
+ expect { execute }
+ .not_to change { ::Ci::ExternalPullRequests::CreatePipelineWorker.jobs.count }
- expect(response).to be_error
- expect(response.message).to eq('The pull request is not opened')
- expect(response.payload).to be_nil
+ expect(execute).to be_error
+ expect(execute.message).to eq('The pull request is not opened')
+ expect(execute.payload).to be_nil
end
end
end
diff --git a/spec/services/ci/job_artifacts/destroy_all_expired_service_spec.rb b/spec/services/ci/job_artifacts/destroy_all_expired_service_spec.rb
index 04fa55068f2..7a91ad9dcc1 100644
--- a/spec/services/ci/job_artifacts/destroy_all_expired_service_spec.rb
+++ b/spec/services/ci/job_artifacts/destroy_all_expired_service_spec.rb
@@ -10,20 +10,16 @@ RSpec.describe Ci::JobArtifacts::DestroyAllExpiredService, :clean_gitlab_redis_s
describe '.execute' do
subject { service.execute }
- let_it_be(:artifact, refind: true) do
- create(:ci_job_artifact, expire_at: 1.day.ago)
- end
-
- before(:all) do
- artifact.job.pipeline.unlocked!
- end
+ let_it_be(:locked_pipeline) { create(:ci_pipeline, :artifacts_locked) }
+ let_it_be(:pipeline) { create(:ci_pipeline, :unlocked) }
+ let_it_be(:locked_job) { create(:ci_build, :success, pipeline: locked_pipeline) }
+ let_it_be(:job) { create(:ci_build, :success, pipeline: pipeline) }
context 'when artifact is expired' do
+ let!(:artifact) { create(:ci_job_artifact, :expired, job: job) }
+
context 'with preloaded relationships' do
before do
- job = create(:ci_build, pipeline: artifact.job.pipeline)
- create(:ci_job_artifact, :archive, :expired, job: job)
-
stub_const("#{described_class}::LOOP_LIMIT", 1)
end
@@ -39,7 +35,7 @@ RSpec.describe Ci::JobArtifacts::DestroyAllExpiredService, :clean_gitlab_redis_s
# COMMIT
# SELECT next expired ci_job_artifacts
- expect(log.count).to be_within(1).of(11)
+ expect(log.count).to be_within(1).of(10)
end
end
@@ -48,7 +44,7 @@ RSpec.describe Ci::JobArtifacts::DestroyAllExpiredService, :clean_gitlab_redis_s
expect { subject }.to change { Ci::JobArtifact.count }.by(-1)
end
- context 'when the artifact does not a file attached to it' do
+ context 'when the artifact does not have a file attached to it' do
it 'does not create deleted objects' do
expect(artifact.exists?).to be_falsy # sanity check
@@ -57,10 +53,7 @@ RSpec.describe Ci::JobArtifacts::DestroyAllExpiredService, :clean_gitlab_redis_s
end
context 'when the artifact has a file attached to it' do
- before do
- artifact.file = fixture_file_upload(Rails.root.join('spec/fixtures/ci_build_artifacts.zip'), 'application/zip')
- artifact.save!
- end
+ let!(:artifact) { create(:ci_job_artifact, :expired, :zip, job: job) }
it 'creates a deleted object' do
expect { subject }.to change { Ci::DeletedObject.count }.by(1)
@@ -81,9 +74,7 @@ RSpec.describe Ci::JobArtifacts::DestroyAllExpiredService, :clean_gitlab_redis_s
end
context 'when artifact is locked' do
- before do
- artifact.job.pipeline.artifacts_locked!
- end
+ let!(:artifact) { create(:ci_job_artifact, :expired, job: locked_job) }
it 'does not destroy job artifact' do
expect { subject }.not_to change { Ci::JobArtifact.count }
@@ -92,9 +83,7 @@ RSpec.describe Ci::JobArtifacts::DestroyAllExpiredService, :clean_gitlab_redis_s
end
context 'when artifact is not expired' do
- before do
- artifact.update_column(:expire_at, 1.day.since)
- end
+ let!(:artifact) { create(:ci_job_artifact, job: job) }
it 'does not destroy expired job artifacts' do
expect { subject }.not_to change { Ci::JobArtifact.count }
@@ -102,9 +91,7 @@ RSpec.describe Ci::JobArtifacts::DestroyAllExpiredService, :clean_gitlab_redis_s
end
context 'when artifact is permanent' do
- before do
- artifact.update_column(:expire_at, nil)
- end
+ let!(:artifact) { create(:ci_job_artifact, expire_at: nil, job: job) }
it 'does not destroy expired job artifacts' do
expect { subject }.not_to change { Ci::JobArtifact.count }
@@ -112,6 +99,8 @@ RSpec.describe Ci::JobArtifacts::DestroyAllExpiredService, :clean_gitlab_redis_s
end
context 'when failed to destroy artifact' do
+ let!(:artifact) { create(:ci_job_artifact, :expired, job: job) }
+
before do
stub_const("#{described_class}::LOOP_LIMIT", 10)
end
@@ -146,58 +135,67 @@ RSpec.describe Ci::JobArtifacts::DestroyAllExpiredService, :clean_gitlab_redis_s
end
context 'when exclusive lease has already been taken by the other instance' do
+ let!(:artifact) { create(:ci_job_artifact, :expired, job: job) }
+
before do
stub_exclusive_lease_taken(described_class::EXCLUSIVE_LOCK_KEY, timeout: described_class::LOCK_TIMEOUT)
end
it 'raises an error and does not start destroying' do
expect { subject }.to raise_error(Gitlab::ExclusiveLeaseHelpers::FailedToObtainLockError)
+ .and not_change { Ci::JobArtifact.count }.from(1)
end
end
- context 'when timeout happens' do
- let!(:second_artifact) { create(:ci_job_artifact, expire_at: 1.day.ago) }
+ context 'with a second artifact and batch size of 1' do
+ let(:second_job) { create(:ci_build, :success, pipeline: pipeline) }
+ let!(:second_artifact) { create(:ci_job_artifact, :archive, expire_at: 1.day.ago, job: second_job) }
+ let!(:artifact) { create(:ci_job_artifact, :expired, job: job) }
before do
- stub_const("#{described_class}::LOOP_TIMEOUT", 0.seconds)
stub_const("#{described_class}::BATCH_SIZE", 1)
-
- second_artifact.job.pipeline.unlocked!
end
- it 'destroys one artifact' do
- expect { subject }.to change { Ci::JobArtifact.count }.by(-1)
- end
-
- it 'reports the number of destroyed artifacts' do
- is_expected.to eq(1)
- end
- end
+ context 'when timeout happens' do
+ before do
+ stub_const("#{described_class}::LOOP_TIMEOUT", 0.seconds)
+ end
- context 'when loop reached loop limit' do
- before do
- stub_const("#{described_class}::LOOP_LIMIT", 1)
- stub_const("#{described_class}::BATCH_SIZE", 1)
+ it 'destroys one artifact' do
+ expect { subject }.to change { Ci::JobArtifact.count }.by(-1)
+ end
- second_artifact.job.pipeline.unlocked!
+ it 'reports the number of destroyed artifacts' do
+ is_expected.to eq(1)
+ end
end
- let!(:second_artifact) { create(:ci_job_artifact, expire_at: 1.day.ago) }
+ context 'when loop reached loop limit' do
+ before do
+ stub_const("#{described_class}::LOOP_LIMIT", 1)
+ end
- it 'destroys one artifact' do
- expect { subject }.to change { Ci::JobArtifact.count }.by(-1)
+ it 'destroys one artifact' do
+ expect { subject }.to change { Ci::JobArtifact.count }.by(-1)
+ end
+
+ it 'reports the number of destroyed artifacts' do
+ is_expected.to eq(1)
+ end
end
- it 'reports the number of destroyed artifacts' do
- is_expected.to eq(1)
+ context 'when the number of artifacts is greater than than batch size' do
+ it 'destroys all expired artifacts' do
+ expect { subject }.to change { Ci::JobArtifact.count }.by(-2)
+ end
+
+ it 'reports the number of destroyed artifacts' do
+ is_expected.to eq(2)
+ end
end
end
context 'when there are no artifacts' do
- before do
- artifact.destroy!
- end
-
it 'does not raise error' do
expect { subject }.not_to raise_error
end
@@ -207,42 +205,18 @@ RSpec.describe Ci::JobArtifacts::DestroyAllExpiredService, :clean_gitlab_redis_s
end
end
- context 'when there are artifacts more than batch sizes' do
- before do
- stub_const("#{described_class}::BATCH_SIZE", 1)
-
- second_artifact.job.pipeline.unlocked!
- end
-
- let!(:second_artifact) { create(:ci_job_artifact, expire_at: 1.day.ago) }
-
- it 'destroys all expired artifacts' do
- expect { subject }.to change { Ci::JobArtifact.count }.by(-2)
- end
-
- it 'reports the number of destroyed artifacts' do
- is_expected.to eq(2)
- end
- end
-
context 'when some artifacts are locked' do
- before do
- pipeline = create(:ci_pipeline, locked: :artifacts_locked)
- job = create(:ci_build, pipeline: pipeline)
- create(:ci_job_artifact, expire_at: 1.day.ago, job: job)
- end
+ let!(:artifact) { create(:ci_job_artifact, :expired, job: job) }
+ let!(:locked_artifact) { create(:ci_job_artifact, :expired, job: locked_job) }
it 'destroys only unlocked artifacts' do
expect { subject }.to change { Ci::JobArtifact.count }.by(-1)
+ expect(locked_artifact).to be_persisted
end
end
context 'when all artifacts are locked' do
- before do
- pipeline = create(:ci_pipeline, locked: :artifacts_locked)
- job = create(:ci_build, pipeline: pipeline)
- artifact.update!(job: job)
- end
+ let!(:artifact) { create(:ci_job_artifact, :expired, job: locked_job) }
it 'destroys no artifacts' do
expect { subject }.to change { Ci::JobArtifact.count }.by(0)
diff --git a/spec/services/ci/pipeline_processing/shared_processing_service.rb b/spec/services/ci/pipeline_processing/shared_processing_service.rb
index a4bc8e68b2d..8de9b308429 100644
--- a/spec/services/ci/pipeline_processing/shared_processing_service.rb
+++ b/spec/services/ci/pipeline_processing/shared_processing_service.rb
@@ -908,6 +908,39 @@ RSpec.shared_examples 'Pipeline Processing Service' do
end
end
+ context 'when a bridge job has invalid downstream project', :sidekiq_inline do
+ let(:config) do
+ <<-EOY
+ test:
+ stage: test
+ script: echo test
+
+ deploy:
+ stage: deploy
+ trigger:
+ project: invalid-project
+ EOY
+ end
+
+ let(:pipeline) do
+ Ci::CreatePipelineService.new(project, user, { ref: 'master' }).execute(:push).payload
+ end
+
+ before do
+ stub_ci_pipeline_yaml_file(config)
+ end
+
+ it 'creates a pipeline, then fails the bridge job' do
+ expect(all_builds_names).to contain_exactly('test', 'deploy')
+ expect(all_builds_statuses).to contain_exactly('pending', 'created')
+
+ succeed_pending
+
+ expect(all_builds_names).to contain_exactly('test', 'deploy')
+ expect(all_builds_statuses).to contain_exactly('success', 'failed')
+ end
+ end
+
private
def all_builds
diff --git a/spec/services/ci/pipeline_trigger_service_spec.rb b/spec/services/ci/pipeline_trigger_service_spec.rb
index 2f93b1ecd3c..29d12b0dd0e 100644
--- a/spec/services/ci/pipeline_trigger_service_spec.rb
+++ b/spec/services/ci/pipeline_trigger_service_spec.rb
@@ -103,6 +103,17 @@ RSpec.describe Ci::PipelineTriggerService do
end
end
+ context 'when params have duplicate variables' do
+ let(:params) { { token: trigger.token, ref: 'master', variables: variables } }
+ let(:variables) { { 'TRIGGER_PAYLOAD' => 'duplicate value' } }
+
+ it 'creates a failed pipeline without variables' do
+ expect { result }.to change { Ci::Pipeline.count }
+ expect(result).to be_error
+ expect(result.message[:base]).to eq(['Duplicate variable name: TRIGGER_PAYLOAD'])
+ end
+ end
+
it_behaves_like 'detecting an unprocessable pipeline trigger'
end
@@ -201,6 +212,17 @@ RSpec.describe Ci::PipelineTriggerService do
end
end
+ context 'when params have duplicate variables' do
+ let(:params) { { token: job.token, ref: 'master', variables: variables } }
+ let(:variables) { { 'TRIGGER_PAYLOAD' => 'duplicate value' } }
+
+ it 'creates a failed pipeline without variables' do
+ expect { result }.to change { Ci::Pipeline.count }
+ expect(result).to be_error
+ expect(result.message[:base]).to eq(['Duplicate variable name: TRIGGER_PAYLOAD'])
+ end
+ end
+
it_behaves_like 'detecting an unprocessable pipeline trigger'
end
diff --git a/spec/services/ci/pipelines/add_job_service_spec.rb b/spec/services/ci/pipelines/add_job_service_spec.rb
index bdf7e577fa8..3a77d26dd9e 100644
--- a/spec/services/ci/pipelines/add_job_service_spec.rb
+++ b/spec/services/ci/pipelines/add_job_service_spec.rb
@@ -59,18 +59,6 @@ RSpec.describe Ci::Pipelines::AddJobService do
end
end
- context 'when the FF ci_fix_commit_status_retried is disabled' do
- before do
- stub_feature_flags(ci_fix_commit_status_retried: false)
- end
-
- it 'does not call update_older_statuses_retried!' do
- expect(job).not_to receive(:update_older_statuses_retried!)
-
- execute
- end
- end
-
context 'exclusive lock' do
let(:lock_uuid) { 'test' }
let(:lock_key) { "ci:pipelines:#{pipeline.id}:add-job" }
diff --git a/spec/services/ci/register_job_service_spec.rb b/spec/services/ci/register_job_service_spec.rb
index 2f37d0ea42d..73ff15ec393 100644
--- a/spec/services/ci/register_job_service_spec.rb
+++ b/spec/services/ci/register_job_service_spec.rb
@@ -40,12 +40,16 @@ module Ci
context 'runner follow tag list' do
it "picks build with the same tag" do
pending_job.update!(tag_list: ["linux"])
+ pending_job.reload
+ pending_job.create_queuing_entry!
specific_runner.update!(tag_list: ["linux"])
expect(execute(specific_runner)).to eq(pending_job)
end
it "does not pick build with different tag" do
pending_job.update!(tag_list: ["linux"])
+ pending_job.reload
+ pending_job.create_queuing_entry!
specific_runner.update!(tag_list: ["win32"])
expect(execute(specific_runner)).to be_falsey
end
@@ -56,6 +60,8 @@ module Ci
it "does not pick build with tag" do
pending_job.update!(tag_list: ["linux"])
+ pending_job.reload
+ pending_job.create_queuing_entry!
expect(execute(specific_runner)).to be_falsey
end
@@ -81,8 +87,30 @@ module Ci
end
context 'for specific runner' do
- it 'does not pick a build' do
- expect(execute(specific_runner)).to be_nil
+ context 'with FF disabled' do
+ before do
+ stub_feature_flags(
+ ci_pending_builds_project_runners_decoupling: false,
+ ci_queueing_builds_enabled_checks: false)
+ end
+
+ it 'does not pick a build' do
+ expect(execute(specific_runner)).to be_nil
+ end
+ end
+
+ context 'with FF enabled' do
+ before do
+ stub_feature_flags(
+ ci_pending_builds_project_runners_decoupling: true,
+ ci_queueing_builds_enabled_checks: true)
+ end
+
+ it 'does not pick a build' do
+ expect(execute(specific_runner)).to be_nil
+ expect(pending_job.reload).to be_failed
+ expect(pending_job.queuing_entry).to be_nil
+ end
end
end
end
@@ -219,6 +247,8 @@ module Ci
before do
project.update!(shared_runners_enabled: true, group_runners_enabled: true)
project.project_feature.update_attribute(:builds_access_level, ProjectFeature::DISABLED)
+
+ pending_job.reload.create_queuing_entry!
end
context 'and uses shared runner' do
@@ -236,7 +266,29 @@ module Ci
context 'and uses project runner' do
let(:build) { execute(specific_runner) }
- it { expect(build).to be_nil }
+ context 'with FF disabled' do
+ before do
+ stub_feature_flags(
+ ci_pending_builds_project_runners_decoupling: false,
+ ci_queueing_builds_enabled_checks: false)
+ end
+
+ it { expect(build).to be_nil }
+ end
+
+ context 'with FF enabled' do
+ before do
+ stub_feature_flags(
+ ci_pending_builds_project_runners_decoupling: true,
+ ci_queueing_builds_enabled_checks: true)
+ end
+
+ it 'does not pick a build' do
+ expect(build).to be_nil
+ expect(pending_job.reload).to be_failed
+ expect(pending_job.queuing_entry).to be_nil
+ end
+ end
end
end
@@ -304,6 +356,8 @@ module Ci
context 'disallow group runners' do
before do
project.update!(group_runners_enabled: false)
+
+ pending_job.reload.create_queuing_entry!
end
context 'group runner' do
@@ -739,6 +793,30 @@ module Ci
include_examples 'handles runner assignment'
end
+
+ context 'with ci_queueing_denormalize_tags_information enabled' do
+ before do
+ stub_feature_flags(ci_queueing_denormalize_tags_information: true)
+ end
+
+ include_examples 'handles runner assignment'
+ end
+
+ context 'with ci_queueing_denormalize_tags_information disabled' do
+ before do
+ stub_feature_flags(ci_queueing_denormalize_tags_information: false)
+ end
+
+ include_examples 'handles runner assignment'
+ end
+
+ context 'with ci_queueing_denormalize_namespace_traversal_ids disabled' do
+ before do
+ stub_feature_flags(ci_queueing_denormalize_namespace_traversal_ids: false)
+ end
+
+ include_examples 'handles runner assignment'
+ end
end
context 'when not using pending builds table' do
diff --git a/spec/services/ci/stuck_builds/drop_service_spec.rb b/spec/services/ci/stuck_builds/drop_service_spec.rb
new file mode 100644
index 00000000000..8dfd1bc1b3d
--- /dev/null
+++ b/spec/services/ci/stuck_builds/drop_service_spec.rb
@@ -0,0 +1,284 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::StuckBuilds::DropService do
+ let!(:runner) { create :ci_runner }
+ let!(:job) { create :ci_build, runner: runner }
+ let(:created_at) { }
+ let(:updated_at) { }
+
+ subject(:service) { described_class.new }
+
+ before do
+ job_attributes = { status: status }
+ job_attributes[:created_at] = created_at if created_at
+ job_attributes[:updated_at] = updated_at if updated_at
+ job.update!(job_attributes)
+ end
+
+ shared_examples 'job is dropped' do
+ it 'changes status' do
+ expect(service).to receive(:drop).exactly(3).times.and_call_original
+ expect(service).to receive(:drop_stuck).exactly(:once).and_call_original
+
+ service.execute
+ job.reload
+
+ expect(job).to be_failed
+ expect(job).to be_stuck_or_timeout_failure
+ end
+
+ context 'when job have data integrity problem' do
+ it "does drop the job and logs the reason" do
+ job.update_columns(yaml_variables: '[{"key" => "value"}]')
+
+ expect(Gitlab::ErrorTracking).to receive(:track_exception)
+ .with(anything, a_hash_including(build_id: job.id))
+ .once
+ .and_call_original
+
+ service.execute
+ job.reload
+
+ expect(job).to be_failed
+ expect(job).to be_data_integrity_failure
+ end
+ end
+ end
+
+ shared_examples 'job is unchanged' do
+ it 'does not change status' do
+ expect(service).to receive(:drop).exactly(3).times.and_call_original
+ expect(service).to receive(:drop_stuck).exactly(:once).and_call_original
+
+ service.execute
+ job.reload
+
+ expect(job.status).to eq(status)
+ end
+ end
+
+ context 'when job is pending' do
+ let(:status) { 'pending' }
+
+ context 'when job is not stuck' do
+ before do
+ allow_next_found_instance_of(Ci::Build) do |build|
+ allow(build).to receive(:stuck?).and_return(false)
+ end
+ end
+
+ context 'when job was updated_at more than 1 day ago' do
+ let(:updated_at) { 1.5.days.ago }
+
+ context 'when created_at is the same as updated_at' do
+ let(:created_at) { 1.5.days.ago }
+
+ it_behaves_like 'job is dropped'
+ end
+
+ context 'when created_at is before updated_at' do
+ let(:created_at) { 3.days.ago }
+
+ it_behaves_like 'job is dropped'
+ end
+
+ context 'when created_at is outside lookback window' do
+ let(:created_at) { described_class::BUILD_LOOKBACK - 1.day }
+
+ it_behaves_like 'job is unchanged'
+ end
+ end
+
+ context 'when job was updated less than 1 day ago' do
+ let(:updated_at) { 6.hours.ago }
+
+ context 'when created_at is the same as updated_at' do
+ let(:created_at) { 1.5.days.ago }
+
+ it_behaves_like 'job is unchanged'
+ end
+
+ context 'when created_at is before updated_at' do
+ let(:created_at) { 3.days.ago }
+
+ it_behaves_like 'job is unchanged'
+ end
+
+ context 'when created_at is outside lookback window' do
+ let(:created_at) { described_class::BUILD_LOOKBACK - 1.day }
+
+ it_behaves_like 'job is unchanged'
+ end
+ end
+
+ context 'when job was updated more than 1 hour ago' do
+ let(:updated_at) { 2.hours.ago }
+
+ context 'when created_at is the same as updated_at' do
+ let(:created_at) { 2.hours.ago }
+
+ it_behaves_like 'job is unchanged'
+ end
+
+ context 'when created_at is before updated_at' do
+ let(:created_at) { 3.days.ago }
+
+ it_behaves_like 'job is unchanged'
+ end
+
+ context 'when created_at is outside lookback window' do
+ let(:created_at) { described_class::BUILD_LOOKBACK - 1.day }
+
+ it_behaves_like 'job is unchanged'
+ end
+ end
+ end
+
+ context 'when job is stuck' do
+ before do
+ allow_next_found_instance_of(Ci::Build) do |build|
+ allow(build).to receive(:stuck?).and_return(true)
+ end
+ end
+
+ context 'when job was updated_at more than 1 hour ago' do
+ let(:updated_at) { 1.5.hours.ago }
+
+ context 'when created_at is the same as updated_at' do
+ let(:created_at) { 1.5.hours.ago }
+
+ it_behaves_like 'job is dropped'
+ end
+
+ context 'when created_at is before updated_at' do
+ let(:created_at) { 3.days.ago }
+
+ it_behaves_like 'job is dropped'
+ end
+
+ context 'when created_at is outside lookback window' do
+ let(:created_at) { described_class::BUILD_LOOKBACK - 1.day }
+
+ it_behaves_like 'job is unchanged'
+ end
+ end
+
+ context 'when job was updated in less than 1 hour ago' do
+ let(:updated_at) { 30.minutes.ago }
+
+ context 'when created_at is the same as updated_at' do
+ let(:created_at) { 30.minutes.ago }
+
+ it_behaves_like 'job is unchanged'
+ end
+
+ context 'when created_at is before updated_at' do
+ let(:created_at) { 2.days.ago }
+
+ it_behaves_like 'job is unchanged'
+ end
+
+ context 'when created_at is outside lookback window' do
+ let(:created_at) { described_class::BUILD_LOOKBACK - 1.day }
+
+ it_behaves_like 'job is unchanged'
+ end
+ end
+ end
+ end
+
+ context 'when job is running' do
+ let(:status) { 'running' }
+
+ context 'when job was updated_at more than an hour ago' do
+ let(:updated_at) { 2.hours.ago }
+
+ it_behaves_like 'job is dropped'
+ end
+
+ context 'when job was updated in less than 1 hour ago' do
+ let(:updated_at) { 30.minutes.ago }
+
+ it_behaves_like 'job is unchanged'
+ end
+ end
+
+ %w(success skipped failed canceled).each do |status|
+ context "when job is #{status}" do
+ let(:status) { status }
+ let(:updated_at) { 2.days.ago }
+
+ context 'when created_at is the same as updated_at' do
+ let(:created_at) { 2.days.ago }
+
+ it_behaves_like 'job is unchanged'
+ end
+
+ context 'when created_at is before updated_at' do
+ let(:created_at) { 3.days.ago }
+
+ it_behaves_like 'job is unchanged'
+ end
+
+ context 'when created_at is outside lookback window' do
+ let(:created_at) { described_class::BUILD_LOOKBACK - 1.day }
+
+ it_behaves_like 'job is unchanged'
+ end
+ end
+ end
+
+ context 'for deleted project' do
+ let(:status) { 'running' }
+ let(:updated_at) { 2.days.ago }
+
+ before do
+ job.project.update!(pending_delete: true)
+ end
+
+ it_behaves_like 'job is dropped'
+ end
+
+ describe 'drop stale scheduled builds' do
+ let(:status) { 'scheduled' }
+ let(:updated_at) { }
+
+ context 'when scheduled at 2 hours ago but it is not executed yet' do
+ let!(:job) { create(:ci_build, :scheduled, scheduled_at: 2.hours.ago) }
+
+ it 'drops the stale scheduled build' do
+ expect(Ci::Build.scheduled.count).to eq(1)
+ expect(job).to be_scheduled
+
+ service.execute
+ job.reload
+
+ expect(Ci::Build.scheduled.count).to eq(0)
+ expect(job).to be_failed
+ expect(job).to be_stale_schedule
+ end
+ end
+
+ context 'when scheduled at 30 minutes ago but it is not executed yet' do
+ let!(:job) { create(:ci_build, :scheduled, scheduled_at: 30.minutes.ago) }
+
+ it 'does not drop the stale scheduled build yet' do
+ expect(Ci::Build.scheduled.count).to eq(1)
+ expect(job).to be_scheduled
+
+ service.execute
+
+ expect(Ci::Build.scheduled.count).to eq(1)
+ expect(job).to be_scheduled
+ end
+ end
+
+ context 'when there are no stale scheduled builds' do
+ it 'does not drop the stale scheduled build yet' do
+ expect { service.execute }.not_to raise_error
+ end
+ end
+ end
+end
diff --git a/spec/services/ci/update_pending_build_service_spec.rb b/spec/services/ci/update_pending_build_service_spec.rb
new file mode 100644
index 00000000000..d842042de40
--- /dev/null
+++ b/spec/services/ci/update_pending_build_service_spec.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::UpdatePendingBuildService do
+ describe '#execute' do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, namespace: group) }
+ let_it_be(:pending_build_1) { create(:ci_pending_build, project: project, instance_runners_enabled: false) }
+ let_it_be(:pending_build_2) { create(:ci_pending_build, project: project, instance_runners_enabled: true) }
+ let_it_be(:update_params) { { instance_runners_enabled: true } }
+
+ subject(:service) { described_class.new(model, update_params).execute }
+
+ context 'validations' do
+ context 'when model is invalid' do
+ let(:model) { pending_build_1 }
+
+ it 'raises an error' do
+ expect { service }.to raise_error(described_class::InvalidModelError)
+ end
+ end
+
+ context 'when params is invalid' do
+ let(:model) { group }
+ let(:update_params) { { minutes_exceeded: true } }
+
+ it 'raises an error' do
+ expect { service }.to raise_error(described_class::InvalidParamsError)
+ end
+ end
+ end
+
+ context 'when model is a group with pending builds' do
+ let(:model) { group }
+
+ it 'updates all pending builds', :aggregate_failures do
+ service
+
+ expect(pending_build_1.reload.instance_runners_enabled).to be_truthy
+ expect(pending_build_2.reload.instance_runners_enabled).to be_truthy
+ end
+
+ context 'when ci_pending_builds_maintain_shared_runners_data is disabled' do
+ before do
+ stub_feature_flags(ci_pending_builds_maintain_shared_runners_data: false)
+ end
+
+ it 'does not update all pending builds', :aggregate_failures do
+ service
+
+ expect(pending_build_1.reload.instance_runners_enabled).to be_falsey
+ expect(pending_build_2.reload.instance_runners_enabled).to be_truthy
+ end
+ end
+ end
+
+ context 'when model is a project with pending builds' do
+ let(:model) { project }
+
+ it 'updates all pending builds', :aggregate_failures do
+ service
+
+ expect(pending_build_1.reload.instance_runners_enabled).to be_truthy
+ expect(pending_build_2.reload.instance_runners_enabled).to be_truthy
+ end
+
+ context 'when ci_pending_builds_maintain_shared_runners_data is disabled' do
+ before do
+ stub_feature_flags(ci_pending_builds_maintain_shared_runners_data: false)
+ end
+
+ it 'does not update all pending builds', :aggregate_failures do
+ service
+
+ expect(pending_build_1.reload.instance_runners_enabled).to be_falsey
+ expect(pending_build_2.reload.instance_runners_enabled).to be_truthy
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/clusters/agents/refresh_authorization_service_spec.rb b/spec/services/clusters/agents/refresh_authorization_service_spec.rb
new file mode 100644
index 00000000000..77ba81ea9c0
--- /dev/null
+++ b/spec/services/clusters/agents/refresh_authorization_service_spec.rb
@@ -0,0 +1,132 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Clusters::Agents::RefreshAuthorizationService do
+ describe '#execute' do
+ let_it_be(:root_ancestor) { create(:group) }
+
+ let_it_be(:removed_group) { create(:group, parent: root_ancestor) }
+ let_it_be(:modified_group) { create(:group, parent: root_ancestor) }
+ let_it_be(:added_group) { create(:group, parent: root_ancestor) }
+
+ let_it_be(:removed_project) { create(:project, namespace: root_ancestor) }
+ let_it_be(:modified_project) { create(:project, namespace: root_ancestor) }
+ let_it_be(:added_project) { create(:project, namespace: root_ancestor) }
+
+ let(:project) { create(:project, namespace: root_ancestor) }
+ let(:agent) { create(:cluster_agent, project: project) }
+
+ let(:config) do
+ {
+ ci_access: {
+ groups: [
+ { id: added_group.full_path, default_namespace: 'default' },
+ { id: modified_group.full_path, default_namespace: 'new-namespace' }
+ ],
+ projects: [
+ { id: added_project.full_path, default_namespace: 'default' },
+ { id: modified_project.full_path, default_namespace: 'new-namespace' }
+ ]
+ }
+ }.deep_stringify_keys
+ end
+
+ subject { described_class.new(agent, config: config).execute }
+
+ before do
+ default_config = { default_namespace: 'default' }
+
+ agent.group_authorizations.create!(group: removed_group, config: default_config)
+ agent.group_authorizations.create!(group: modified_group, config: default_config)
+
+ agent.project_authorizations.create!(project: removed_project, config: default_config)
+ agent.project_authorizations.create!(project: modified_project, config: default_config)
+ end
+
+ shared_examples 'removing authorization' do
+ context 'config contains no groups' do
+ let(:config) { {} }
+
+ it 'removes all authorizations' do
+ expect(subject).to be_truthy
+ expect(authorizations).to be_empty
+ end
+ end
+
+ context 'config contains groups outside of the configuration project hierarchy' do
+ let(:project) { create(:project, namespace: create(:group)) }
+
+ it 'removes all authorizations' do
+ expect(subject).to be_truthy
+ expect(authorizations).to be_empty
+ end
+ end
+
+ context 'configuration project does not belong to a group' do
+ let(:project) { create(:project) }
+
+ it 'removes all authorizations' do
+ expect(subject).to be_truthy
+ expect(authorizations).to be_empty
+ end
+ end
+ end
+
+ describe 'group authorization' do
+ it 'refreshes authorizations for the agent' do
+ expect(subject).to be_truthy
+ expect(agent.authorized_groups).to contain_exactly(added_group, modified_group)
+
+ added_authorization = agent.group_authorizations.find_by(group: added_group)
+ expect(added_authorization.config).to eq({ 'default_namespace' => 'default' })
+
+ modified_authorization = agent.group_authorizations.find_by(group: modified_group)
+ expect(modified_authorization.config).to eq({ 'default_namespace' => 'new-namespace' })
+ end
+
+ context 'config contains too many groups' do
+ before do
+ stub_const("#{described_class}::AUTHORIZED_ENTITY_LIMIT", 1)
+ end
+
+ it 'authorizes groups up to the limit' do
+ expect(subject).to be_truthy
+ expect(agent.authorized_groups).to contain_exactly(added_group)
+ end
+ end
+
+ include_examples 'removing authorization' do
+ let(:authorizations) { agent.authorized_groups }
+ end
+ end
+
+ describe 'project authorization' do
+ it 'refreshes authorizations for the agent' do
+ expect(subject).to be_truthy
+ expect(agent.authorized_projects).to contain_exactly(added_project, modified_project)
+
+ added_authorization = agent.project_authorizations.find_by(project: added_project)
+ expect(added_authorization.config).to eq({ 'default_namespace' => 'default' })
+
+ modified_authorization = agent.project_authorizations.find_by(project: modified_project)
+ expect(modified_authorization.config).to eq({ 'default_namespace' => 'new-namespace' })
+ end
+
+ context 'config contains too many projects' do
+ before do
+ stub_const("#{described_class}::AUTHORIZED_ENTITY_LIMIT", 1)
+ end
+
+ it 'authorizes projects up to the limit' do
+ expect(subject).to be_truthy
+ expect(agent.authorized_projects).to contain_exactly(added_project)
+ end
+ end
+
+ include_examples 'removing authorization' do
+ let(:authorizations) { agent.authorized_projects }
+ end
+ end
+ end
+end
diff --git a/spec/services/customer_relations/organizations/create_service_spec.rb b/spec/services/customer_relations/organizations/create_service_spec.rb
new file mode 100644
index 00000000000..b4764f6b97a
--- /dev/null
+++ b/spec/services/customer_relations/organizations/create_service_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe CustomerRelations::Organizations::CreateService do
+ describe '#execute' do
+ let_it_be(:user) { create(:user) }
+
+ let(:group) { create(:group) }
+ let(:params) { attributes_for(:organization, group: group) }
+
+ subject(:response) { described_class.new(group: group, current_user: user, params: params).execute }
+
+ it 'creates an organization' do
+ group.add_reporter(user)
+
+ expect(response).to be_success
+ end
+
+ it 'returns an error when user does not have permission' do
+ expect(response).to be_error
+ expect(response.message).to eq('You have insufficient permissions to create an organization for this group')
+ end
+
+ it 'returns an error when the organization is not persisted' do
+ group.add_reporter(user)
+ params[:name] = nil
+
+ expect(response).to be_error
+ expect(response.message).to eq(["Name can't be blank"])
+ end
+ end
+end
diff --git a/spec/services/customer_relations/organizations/update_service_spec.rb b/spec/services/customer_relations/organizations/update_service_spec.rb
new file mode 100644
index 00000000000..eb253540863
--- /dev/null
+++ b/spec/services/customer_relations/organizations/update_service_spec.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe CustomerRelations::Organizations::UpdateService do
+ let_it_be(:user) { create(:user) }
+
+ let(:organization) { create(:organization, name: 'Test', group: group) }
+
+ subject(:update) { described_class.new(group: group, current_user: user, params: params).execute(organization) }
+
+ describe '#execute' do
+ context 'when the user has no permission' do
+ let_it_be(:group) { create(:group) }
+
+ let(:params) { { name: 'GitLab' } }
+
+ it 'returns an error' do
+ response = update
+
+ expect(response).to be_error
+ expect(response.message).to eq('You have insufficient permissions to update an organization for this group')
+ end
+ end
+
+ context 'when user has permission' do
+ let_it_be(:group) { create(:group) }
+
+ before_all do
+ group.add_reporter(user)
+ end
+
+ context 'when name is changed' do
+ let(:params) { { name: 'GitLab' } }
+
+ it 'updates the organization' do
+ response = update
+
+ expect(response).to be_success
+ expect(response.payload.name).to eq('GitLab')
+ end
+ end
+
+ context 'when the organization is invalid' do
+ let(:params) { { name: nil } }
+
+ it 'returns an error' do
+ response = update
+
+ expect(response).to be_error
+ expect(response.message).to eq(["Name can't be blank"])
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/dependency_proxy/image_ttl_group_policies/update_service_spec.rb b/spec/services/dependency_proxy/image_ttl_group_policies/update_service_spec.rb
new file mode 100644
index 00000000000..ceac8985c8e
--- /dev/null
+++ b/spec/services/dependency_proxy/image_ttl_group_policies/update_service_spec.rb
@@ -0,0 +1,119 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::DependencyProxy::ImageTtlGroupPolicies::UpdateService do
+ using RSpec::Parameterized::TableSyntax
+
+ let_it_be_with_reload(:group) { create(:group) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:params) { {} }
+
+ describe '#execute' do
+ subject { described_class.new(container: group, current_user: user, params: params).execute }
+
+ shared_examples 'returning a success' do
+ it 'returns a success' do
+ result = subject
+
+ expect(result.payload[:dependency_proxy_image_ttl_policy]).to be_present
+ expect(result).to be_success
+ end
+ end
+
+ shared_examples 'returning an error' do |message, http_status|
+ it 'returns an error' do
+ result = subject
+
+ expect(result).to have_attributes(
+ message: message,
+ status: :error,
+ http_status: http_status
+ )
+ end
+ end
+
+ shared_examples 'updating the dependency proxy image ttl policy' do
+ it_behaves_like 'updating the dependency proxy image ttl policy attributes',
+ from: { enabled: true, ttl: 90 },
+ to: { enabled: false, ttl: 2 }
+
+ it_behaves_like 'returning a success'
+
+ context 'with invalid params' do
+ let_it_be(:params) { { enabled: nil } }
+
+ it_behaves_like 'not creating the dependency proxy image ttl policy'
+
+ it "doesn't update" do
+ expect { subject }
+ .not_to change { ttl_policy.reload.enabled }
+ end
+
+ it_behaves_like 'returning an error', 'Enabled is not included in the list', 400
+ end
+ end
+
+ shared_examples 'denying access to dependency proxy image ttl policy' do
+ context 'with existing dependency proxy image ttl policy' do
+ it_behaves_like 'not creating the dependency proxy image ttl policy'
+
+ it_behaves_like 'returning an error', 'Access Denied', 403
+ end
+ end
+
+ before do
+ stub_config(dependency_proxy: { enabled: true })
+ end
+
+ context 'with existing dependency proxy image ttl policy' do
+ let_it_be(:ttl_policy) { create(:image_ttl_group_policy, group: group) }
+ let_it_be(:params) { { enabled: false, ttl: 2 } }
+
+ where(:user_role, :shared_examples_name) do
+ :maintainer | 'updating the dependency proxy image ttl policy'
+ :developer | 'updating the dependency proxy image ttl policy'
+ :reporter | 'denying access to dependency proxy image ttl policy'
+ :guest | 'denying access to dependency proxy image ttl policy'
+ :anonymous | 'denying access to dependency proxy image ttl policy'
+ end
+
+ with_them do
+ before do
+ group.send("add_#{user_role}", user) unless user_role == :anonymous
+ end
+
+ it_behaves_like params[:shared_examples_name]
+ end
+ end
+
+ context 'without existing dependency proxy image ttl policy' do
+ let_it_be(:ttl_policy) { group.dependency_proxy_image_ttl_policy }
+
+ where(:user_role, :shared_examples_name) do
+ :maintainer | 'creating the dependency proxy image ttl policy'
+ :developer | 'creating the dependency proxy image ttl policy'
+ :reporter | 'denying access to dependency proxy image ttl policy'
+ :guest | 'denying access to dependency proxy image ttl policy'
+ :anonymous | 'denying access to dependency proxy image ttl policy'
+ end
+
+ with_them do
+ before do
+ group.send("add_#{user_role}", user) unless user_role == :anonymous
+ end
+
+ it_behaves_like params[:shared_examples_name]
+ end
+
+ context 'when the policy is not found' do
+ before do
+ group.add_developer(user)
+ expect(group).to receive(:dependency_proxy_image_ttl_policy).and_return nil
+ end
+
+ it_behaves_like 'returning an error', 'Dependency proxy image TTL Policy not found', 404
+ end
+ end
+ end
+end
diff --git a/spec/services/design_management/delete_designs_service_spec.rb b/spec/services/design_management/delete_designs_service_spec.rb
index 341f71fa62c..bc7625d7c28 100644
--- a/spec/services/design_management/delete_designs_service_spec.rb
+++ b/spec/services/design_management/delete_designs_service_spec.rb
@@ -149,6 +149,12 @@ RSpec.describe DesignManagement::DeleteDesignsService do
expect { run_service }
.to change { designs.first.deleted? }.from(false).to(true)
end
+
+ it 'schedules deleting todos for that design' do
+ expect(TodosDestroyer::DestroyedDesignsWorker).to receive(:perform_async).with([designs.first.id])
+
+ run_service
+ end
end
context 'more than one design is passed' do
@@ -168,6 +174,12 @@ RSpec.describe DesignManagement::DeleteDesignsService do
.and change { Event.destroyed_action.for_design.count }.by(2)
end
+ it 'schedules deleting todos for that design' do
+ expect(TodosDestroyer::DestroyedDesignsWorker).to receive(:perform_async).with(designs.map(&:id))
+
+ run_service
+ end
+
it_behaves_like "a success"
context 'after executing the service' do
diff --git a/spec/services/draft_notes/publish_service_spec.rb b/spec/services/draft_notes/publish_service_spec.rb
index 4f761454516..51ef30c91c0 100644
--- a/spec/services/draft_notes/publish_service_spec.rb
+++ b/spec/services/draft_notes/publish_service_spec.rb
@@ -33,7 +33,8 @@ RSpec.describe DraftNotes::PublishService do
end
it 'does not skip notification', :sidekiq_might_not_need_inline do
- expect(Notes::CreateService).to receive(:new).with(project, user, drafts.first.publish_params).and_call_original
+ note_params = drafts.first.publish_params.merge(skip_keep_around_commits: false)
+ expect(Notes::CreateService).to receive(:new).with(project, user, note_params).and_call_original
expect_next_instance_of(NotificationService) do |notification_service|
expect(notification_service).to receive(:new_note)
end
@@ -127,12 +128,17 @@ RSpec.describe DraftNotes::PublishService do
publish
end
- context 'capturing diff notes positions' do
+ context 'capturing diff notes positions and keeping around commits' do
before do
# Need to execute this to ensure that we'll be able to test creation of
# DiffNotePosition records as that only happens when the `MergeRequest#merge_ref_head`
# is present. This service creates that for the specified merge request.
MergeRequests::MergeToRefService.new(project: project, current_user: user).execute(merge_request)
+
+ # Need to re-stub this and call original as we are stubbing
+ # `Gitlab::Git::KeepAround#execute` in spec_helper for performance reason.
+ # Enabling it here so we can test the Gitaly calls it makes.
+ allow(Gitlab::Git::KeepAround).to receive(:execute).and_call_original
end
it 'creates diff_note_positions for diff notes' do
@@ -143,11 +149,26 @@ RSpec.describe DraftNotes::PublishService do
expect(notes.last.diff_note_positions).to be_any
end
+ it 'keeps around the commits of each published note' do
+ publish
+
+ repository = project.repository
+ notes = merge_request.notes.order(id: :asc)
+
+ notes.first.shas.each do |sha|
+ expect(repository.ref_exists?("refs/keep-around/#{sha}")).to be_truthy
+ end
+
+ notes.last.shas.each do |sha|
+ expect(repository.ref_exists?("refs/keep-around/#{sha}")).to be_truthy
+ end
+ end
+
it 'does not requests a lot from Gitaly', :request_store do
# NOTE: This should be reduced as we work on reducing Gitaly calls.
# Gitaly requests shouldn't go above this threshold as much as possible
# as it may add more to the Gitaly N+1 issue we are experiencing.
- expect { publish }.to change { Gitlab::GitalyClient.get_request_count }.by(11)
+ expect { publish }.to change { Gitlab::GitalyClient.get_request_count }.by(21)
end
end
diff --git a/spec/services/environments/auto_stop_service_spec.rb b/spec/services/environments/auto_stop_service_spec.rb
index 93b1596586f..8dad59cbefd 100644
--- a/spec/services/environments/auto_stop_service_spec.rb
+++ b/spec/services/environments/auto_stop_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Environments::AutoStopService, :clean_gitlab_redis_shared_state do
+RSpec.describe Environments::AutoStopService, :clean_gitlab_redis_shared_state, :sidekiq_inline do
include CreateEnvironmentsHelpers
include ExclusiveLeaseHelpers
@@ -42,6 +42,15 @@ RSpec.describe Environments::AutoStopService, :clean_gitlab_redis_shared_state d
expect(Ci::Build.where(name: 'stop_review_app').map(&:status).uniq).to eq(['pending'])
end
+ it 'schedules stop processes in bulk' do
+ args = [[Environment.find_by_name('review/feature-1').id], [Environment.find_by_name('review/feature-2').id]]
+
+ expect(Environments::AutoStopWorker)
+ .to receive(:bulk_perform_async).with(args).once.and_call_original
+
+ subject
+ end
+
context 'when the other sidekiq worker has already been running' do
before do
stub_exclusive_lease_taken(described_class::EXCLUSIVE_LOCK_KEY)
diff --git a/spec/services/environments/stop_service_spec.rb b/spec/services/environments/stop_service_spec.rb
index 52be512612d..acc9869002f 100644
--- a/spec/services/environments/stop_service_spec.rb
+++ b/spec/services/environments/stop_service_spec.rb
@@ -237,60 +237,6 @@ RSpec.describe Environments::StopService do
end
end
- describe '.execute_in_batch' do
- subject { described_class.execute_in_batch(environments) }
-
- let_it_be(:project) { create(:project, :repository) }
- let_it_be(:user) { create(:user) }
-
- let(:environments) { Environment.available }
-
- before_all do
- project.add_developer(user)
- project.repository.add_branch(user, 'review/feature-1', 'master')
- project.repository.add_branch(user, 'review/feature-2', 'master')
- end
-
- before do
- create_review_app(user, project, 'review/feature-1')
- create_review_app(user, project, 'review/feature-2')
- end
-
- it 'stops environments' do
- expect { subject }
- .to change { project.environments.all.map(&:state).uniq }
- .from(['available']).to(['stopped'])
-
- expect(project.environments.all.map(&:auto_stop_at).uniq).to eq([nil])
- end
-
- it 'plays stop actions' do
- expect { subject }
- .to change { Ci::Build.where(name: 'stop_review_app').map(&:status).uniq }
- .from(['manual']).to(['pending'])
- end
-
- context 'when user does not have a permission to play the stop action' do
- before do
- project.team.truncate
- end
-
- it 'tracks the exception' do
- expect(Gitlab::ErrorTracking)
- .to receive(:track_exception)
- .with(Gitlab::Access::AccessDeniedError, anything)
- .twice
- .and_call_original
-
- subject
- end
-
- after do
- project.add_developer(user)
- end
- end
- end
-
def expect_environment_stopped_on(branch)
expect { service.execute_for_branch(branch) }
.to change { Environment.last.state }.from('available').to('stopped')
diff --git a/spec/services/error_tracking/collect_error_service_spec.rb b/spec/services/error_tracking/collect_error_service_spec.rb
index 14cd588f40b..ee9d0813e64 100644
--- a/spec/services/error_tracking/collect_error_service_spec.rb
+++ b/spec/services/error_tracking/collect_error_service_spec.rb
@@ -34,11 +34,35 @@ RSpec.describe ErrorTracking::CollectErrorService do
expect(error.platform).to eq 'ruby'
expect(error.last_seen_at).to eq '2021-07-08T12:59:16Z'
- expect(event.description).to eq 'ActionView::MissingTemplate'
+ expect(event.description).to start_with 'Missing template posts/error2'
expect(event.occurred_at).to eq '2021-07-08T12:59:16Z'
expect(event.level).to eq 'error'
expect(event.environment).to eq 'development'
expect(event.payload).to eq parsed_event
end
+
+ context 'unusual payload' do
+ let(:modified_event) { parsed_event }
+
+ context 'missing transaction' do
+ it 'builds actor from stacktrace' do
+ modified_event.delete('transaction')
+
+ event = described_class.new(project, nil, event: modified_event).execute
+
+ expect(event.error.actor).to eq 'find()'
+ end
+ end
+
+ context 'timestamp is numeric' do
+ it 'parses timestamp' do
+ modified_event['timestamp'] = '1631015580.50'
+
+ event = described_class.new(project, nil, event: modified_event).execute
+
+ expect(event.occurred_at).to eq '2021-09-07T11:53:00.5'
+ end
+ end
+ end
end
end
diff --git a/spec/services/feature_flags/create_service_spec.rb b/spec/services/feature_flags/create_service_spec.rb
index 4eb2b25fb64..5a517ce6a64 100644
--- a/spec/services/feature_flags/create_service_spec.rb
+++ b/spec/services/feature_flags/create_service_spec.rb
@@ -48,8 +48,9 @@ RSpec.describe FeatureFlags::CreateService do
{
name: 'feature_flag',
description: 'description',
- scopes_attributes: [{ environment_scope: '*', active: true },
- { environment_scope: 'production', active: false }]
+ version: 'new_version_flag',
+ strategies_attributes: [{ name: 'default', scopes_attributes: [{ environment_scope: '*' }], parameters: {} },
+ { name: 'default', parameters: {}, scopes_attributes: [{ environment_scope: 'production' }] }]
}
end
@@ -68,15 +69,10 @@ RSpec.describe FeatureFlags::CreateService do
end
it 'creates audit event' do
- expected_message = 'Created feature flag feature_flag '\
- 'with description "description". '\
- 'Created rule * and set it as active '\
- 'with strategies [{"name"=&gt;"default", "parameters"=&gt;{}}]. '\
- 'Created rule production and set it as inactive '\
- 'with strategies [{"name"=&gt;"default", "parameters"=&gt;{}}].'
-
expect { subject }.to change { AuditEvent.count }.by(1)
- expect(AuditEvent.last.details[:custom_message]).to eq(expected_message)
+ expect(AuditEvent.last.details[:custom_message]).to start_with('Created feature flag feature_flag with description "description".')
+ expect(AuditEvent.last.details[:custom_message]).to include('Created strategy "default" with scopes "*".')
+ expect(AuditEvent.last.details[:custom_message]).to include('Created strategy "default" with scopes "production".')
end
context 'when user is reporter' do
diff --git a/spec/services/git/base_hooks_service_spec.rb b/spec/services/git/base_hooks_service_spec.rb
index 539c294a2e7..a8d753ff124 100644
--- a/spec/services/git/base_hooks_service_spec.rb
+++ b/spec/services/git/base_hooks_service_spec.rb
@@ -19,9 +19,13 @@ RSpec.describe Git::BaseHooksService do
:push_hooks
end
- def commits
+ def limited_commits
[]
end
+
+ def commits_count
+ 0
+ end
end
end
diff --git a/spec/services/git/branch_hooks_service_spec.rb b/spec/services/git/branch_hooks_service_spec.rb
index a93f594b360..79c2cb1fca3 100644
--- a/spec/services/git/branch_hooks_service_spec.rb
+++ b/spec/services/git/branch_hooks_service_spec.rb
@@ -362,6 +362,9 @@ RSpec.describe Git::BranchHooksService, :clean_gitlab_redis_shared_state do
end
end
+ let(:commits_count) { service.send(:commits_count) }
+ let(:threshold_limit) { described_class::PROCESS_COMMIT_LIMIT + 1 }
+
let(:oldrev) { project.commit(commit_ids.first).parent_id }
let(:newrev) { commit_ids.last }
@@ -373,17 +376,31 @@ RSpec.describe Git::BranchHooksService, :clean_gitlab_redis_shared_state do
let(:oldrev) { Gitlab::Git::BLANK_SHA }
it 'processes a limited number of commit messages' do
+ expect(project.repository)
+ .to receive(:commits)
+ .with(newrev, limit: threshold_limit)
+ .and_call_original
+
expect(ProcessCommitWorker).to receive(:perform_async).twice
service.execute
+
+ expect(commits_count).to eq(project.repository.commit_count_for_ref(newrev))
end
end
context 'updating the default branch' do
it 'processes a limited number of commit messages' do
+ expect(project.repository)
+ .to receive(:commits_between)
+ .with(oldrev, newrev, limit: threshold_limit)
+ .and_call_original
+
expect(ProcessCommitWorker).to receive(:perform_async).twice
service.execute
+
+ expect(commits_count).to eq(project.repository.count_commits_between(oldrev, newrev))
end
end
@@ -391,9 +408,13 @@ RSpec.describe Git::BranchHooksService, :clean_gitlab_redis_shared_state do
let(:newrev) { Gitlab::Git::BLANK_SHA }
it 'does not process commit messages' do
+ expect(project.repository).not_to receive(:commits)
+ expect(project.repository).not_to receive(:commits_between)
expect(ProcessCommitWorker).not_to receive(:perform_async)
service.execute
+
+ expect(commits_count).to eq(0)
end
end
@@ -402,9 +423,16 @@ RSpec.describe Git::BranchHooksService, :clean_gitlab_redis_shared_state do
let(:oldrev) { Gitlab::Git::BLANK_SHA }
it 'processes a limited number of commit messages' do
+ expect(project.repository)
+ .to receive(:commits_between)
+ .with(project.default_branch, newrev, limit: threshold_limit)
+ .and_call_original
+
expect(ProcessCommitWorker).to receive(:perform_async).twice
service.execute
+
+ expect(commits_count).to eq(project.repository.count_commits_between(project.default_branch, branch))
end
end
@@ -412,9 +440,15 @@ RSpec.describe Git::BranchHooksService, :clean_gitlab_redis_shared_state do
let(:branch) { 'fix' }
it 'processes a limited number of commit messages' do
+ expect(project.repository)
+ .to receive(:commits_between)
+ .with(oldrev, newrev, limit: threshold_limit)
+ .and_call_original
+
expect(ProcessCommitWorker).to receive(:perform_async).twice
service.execute
+ expect(commits_count).to eq(project.repository.count_commits_between(oldrev, newrev))
end
end
@@ -423,9 +457,13 @@ RSpec.describe Git::BranchHooksService, :clean_gitlab_redis_shared_state do
let(:newrev) { Gitlab::Git::BLANK_SHA }
it 'does not process commit messages' do
+ expect(project.repository).not_to receive(:commits)
+ expect(project.repository).not_to receive(:commits_between)
expect(ProcessCommitWorker).not_to receive(:perform_async)
service.execute
+
+ expect(commits_count).to eq(0)
end
end
diff --git a/spec/services/groups/group_links/create_service_spec.rb b/spec/services/groups/group_links/create_service_spec.rb
index b1bb9a8de23..03dac14be54 100644
--- a/spec/services/groups/group_links/create_service_spec.rb
+++ b/spec/services/groups/group_links/create_service_spec.rb
@@ -6,18 +6,20 @@ RSpec.describe Groups::GroupLinks::CreateService, '#execute' do
let(:parent_group_user) { create(:user) }
let(:group_user) { create(:user) }
let(:child_group_user) { create(:user) }
+ let(:prevent_sharing) { false }
let_it_be(:group_parent) { create(:group, :private) }
let_it_be(:group) { create(:group, :private, parent: group_parent) }
let_it_be(:group_child) { create(:group, :private, parent: group) }
- let_it_be(:shared_group_parent, refind: true) { create(:group, :private) }
- let_it_be(:shared_group, refind: true) { create(:group, :private, parent: shared_group_parent) }
- let_it_be(:shared_group_child) { create(:group, :private, parent: shared_group) }
+ let(:ns_for_parent) { create(:namespace_settings, prevent_sharing_groups_outside_hierarchy: prevent_sharing) }
+ let(:shared_group_parent) { create(:group, :private, namespace_settings: ns_for_parent) }
+ let(:shared_group) { create(:group, :private, parent: shared_group_parent) }
+ let(:shared_group_child) { create(:group, :private, parent: shared_group) }
- let_it_be(:project_parent) { create(:project, group: shared_group_parent) }
- let_it_be(:project) { create(:project, group: shared_group) }
- let_it_be(:project_child) { create(:project, group: shared_group_child) }
+ let(:project_parent) { create(:project, group: shared_group_parent) }
+ let(:project) { create(:project, group: shared_group) }
+ let(:project_child) { create(:project, group: shared_group_child) }
let(:opts) do
{
@@ -129,9 +131,7 @@ RSpec.describe Groups::GroupLinks::CreateService, '#execute' do
end
context 'sharing outside the hierarchy is disabled' do
- before do
- shared_group_parent.namespace_settings.update!(prevent_sharing_groups_outside_hierarchy: true)
- end
+ let(:prevent_sharing) { true }
it 'prevents sharing with a group outside the hierarchy' do
result = subject.execute
diff --git a/spec/services/groups/open_issues_count_service_spec.rb b/spec/services/groups/open_issues_count_service_spec.rb
index fca09bfdebe..7dd8c2a59a0 100644
--- a/spec/services/groups/open_issues_count_service_spec.rb
+++ b/spec/services/groups/open_issues_count_service_spec.rb
@@ -3,12 +3,18 @@
require 'spec_helper'
RSpec.describe Groups::OpenIssuesCountService, :use_clean_rails_memory_store_caching do
- let_it_be(:group) { create(:group, :public)}
+ let_it_be(:group) { create(:group, :public) }
let_it_be(:project) { create(:project, :public, namespace: group) }
+ let_it_be(:admin) { create(:user, :admin) }
let_it_be(:user) { create(:user) }
- let_it_be(:issue) { create(:issue, :opened, project: project) }
- let_it_be(:confidential) { create(:issue, :opened, confidential: true, project: project) }
- let_it_be(:closed) { create(:issue, :closed, project: project) }
+ let_it_be(:banned_user) { create(:user, :banned) }
+
+ before do
+ create(:issue, :opened, project: project)
+ create(:issue, :opened, confidential: true, project: project)
+ create(:issue, :opened, author: banned_user, project: project)
+ create(:issue, :closed, project: project)
+ end
subject { described_class.new(group, user) }
@@ -20,28 +26,42 @@ RSpec.describe Groups::OpenIssuesCountService, :use_clean_rails_memory_store_cac
it 'uses the IssuesFinder to scope issues' do
expect(IssuesFinder)
.to receive(:new)
- .with(user, group_id: group.id, state: 'opened', non_archived: true, include_subgroups: true, public_only: true)
+ .with(user, group_id: group.id, state: 'opened', non_archived: true, include_subgroups: true, public_only: true, include_hidden: false)
subject.count
end
end
describe '#count' do
- context 'when user is nil' do
- it 'does not include confidential issues in the issue count' do
- expect(described_class.new(group).count).to eq(1)
+ shared_examples 'counts public issues, does not count hidden or confidential' do
+ it 'counts only public issues' do
+ expect(subject.count).to eq(1)
+ end
+
+ it 'uses PUBLIC_COUNT_WITHOUT_HIDDEN_KEY cache key' do
+ expect(subject.cache_key).to include('group_open_public_issues_without_hidden_count')
end
end
+ context 'when user is nil' do
+ let(:user) { nil }
+
+ it_behaves_like 'counts public issues, does not count hidden or confidential'
+ end
+
context 'when user is provided' do
context 'when user can read confidential issues' do
before do
group.add_reporter(user)
end
- it 'returns the right count with confidential issues' do
+ it 'includes confidential issues and does not include hidden issues in count' do
expect(subject.count).to eq(2)
end
+
+ it 'uses TOTAL_COUNT_WITHOUT_HIDDEN_KEY cache key' do
+ expect(subject.cache_key).to include('group_open_issues_without_hidden_count')
+ end
end
context 'when user cannot read confidential issues' do
@@ -49,8 +69,24 @@ RSpec.describe Groups::OpenIssuesCountService, :use_clean_rails_memory_store_cac
group.add_guest(user)
end
- it 'does not include confidential issues' do
- expect(subject.count).to eq(1)
+ it_behaves_like 'counts public issues, does not count hidden or confidential'
+ end
+
+ context 'when user is an admin' do
+ let(:user) { admin }
+
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it 'includes confidential and hidden issues in count' do
+ expect(subject.count).to eq(3)
+ end
+
+ it 'uses TOTAL_COUNT_KEY cache key' do
+ expect(subject.cache_key).to include('group_open_issues_including_hidden_count')
+ end
+ end
+
+ context 'when admin mode is disabled' do
+ it_behaves_like 'counts public issues, does not count hidden or confidential'
end
end
@@ -61,11 +97,13 @@ RSpec.describe Groups::OpenIssuesCountService, :use_clean_rails_memory_store_cac
describe '#clear_all_cache_keys' do
it 'calls `Rails.cache.delete` with the correct keys' do
expect(Rails.cache).to receive(:delete)
- .with(['groups', 'open_issues_count_service', 1, group.id, described_class::PUBLIC_COUNT_KEY])
+ .with(['groups', 'open_issues_count_service', 1, group.id, described_class::PUBLIC_COUNT_WITHOUT_HIDDEN_KEY])
expect(Rails.cache).to receive(:delete)
.with(['groups', 'open_issues_count_service', 1, group.id, described_class::TOTAL_COUNT_KEY])
+ expect(Rails.cache).to receive(:delete)
+ .with(['groups', 'open_issues_count_service', 1, group.id, described_class::TOTAL_COUNT_WITHOUT_HIDDEN_KEY])
- subject.clear_all_cache_keys
+ described_class.new(group).clear_all_cache_keys
end
end
end
diff --git a/spec/services/groups/update_shared_runners_service_spec.rb b/spec/services/groups/update_shared_runners_service_spec.rb
index e941958eb8c..fe18277b5cd 100644
--- a/spec/services/groups/update_shared_runners_service_spec.rb
+++ b/spec/services/groups/update_shared_runners_service_spec.rb
@@ -55,6 +55,31 @@ RSpec.describe Groups::UpdateSharedRunnersService do
expect(subject[:status]).to eq(:success)
end
end
+
+ context 'when group has pending builds' do
+ let_it_be(:group) { create(:group, :shared_runners_disabled) }
+ let_it_be(:project) { create(:project, namespace: group, shared_runners_enabled: false) }
+ let_it_be(:pending_build_1) { create(:ci_pending_build, project: project, instance_runners_enabled: false) }
+ let_it_be(:pending_build_2) { create(:ci_pending_build, project: project, instance_runners_enabled: false) }
+
+ it 'updates pending builds for the group' do
+ subject
+
+ expect(pending_build_1.reload.instance_runners_enabled).to be_truthy
+ expect(pending_build_2.reload.instance_runners_enabled).to be_truthy
+ end
+
+ context 'when shared runners is not toggled' do
+ let(:params) { { shared_runners_setting: 'invalid_enabled' } }
+
+ it 'does not update pending builds for the group' do
+ subject
+
+ expect(pending_build_1.reload.instance_runners_enabled).to be_falsey
+ expect(pending_build_2.reload.instance_runners_enabled).to be_falsey
+ end
+ end
+ end
end
context 'disable shared Runners' do
@@ -67,6 +92,19 @@ RSpec.describe Groups::UpdateSharedRunnersService do
expect(subject[:status]).to eq(:success)
end
+
+ context 'when group has pending builds' do
+ let_it_be(:project) { create(:project, namespace: group) }
+ let_it_be(:pending_build_1) { create(:ci_pending_build, project: project, instance_runners_enabled: true) }
+ let_it_be(:pending_build_2) { create(:ci_pending_build, project: project, instance_runners_enabled: true) }
+
+ it 'updates pending builds for the group' do
+ subject
+
+ expect(pending_build_1.reload.instance_runners_enabled).to be_falsey
+ expect(pending_build_2.reload.instance_runners_enabled).to be_falsey
+ end
+ end
end
context 'allow descendants to override' do
diff --git a/spec/services/issue_rebalancing_service_spec.rb b/spec/services/issue_rebalancing_service_spec.rb
deleted file mode 100644
index 76ccb6d89ea..00000000000
--- a/spec/services/issue_rebalancing_service_spec.rb
+++ /dev/null
@@ -1,173 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe IssueRebalancingService do
- let_it_be(:project, reload: true) { create(:project) }
- let_it_be(:user) { project.creator }
- let_it_be(:start) { RelativePositioning::START_POSITION }
- let_it_be(:max_pos) { RelativePositioning::MAX_POSITION }
- let_it_be(:min_pos) { RelativePositioning::MIN_POSITION }
- let_it_be(:clump_size) { 300 }
-
- let_it_be(:unclumped, reload: true) do
- (1..clump_size).to_a.map do |i|
- create(:issue, project: project, author: user, relative_position: start + (1024 * i))
- end
- end
-
- let_it_be(:end_clump, reload: true) do
- (1..clump_size).to_a.map do |i|
- create(:issue, project: project, author: user, relative_position: max_pos - i)
- end
- end
-
- let_it_be(:start_clump, reload: true) do
- (1..clump_size).to_a.map do |i|
- create(:issue, project: project, author: user, relative_position: min_pos + i)
- end
- end
-
- before do
- stub_feature_flags(issue_rebalancing_with_retry: false)
- end
-
- def issues_in_position_order
- project.reload.issues.reorder(relative_position: :asc).to_a
- end
-
- shared_examples 'IssueRebalancingService shared examples' do
- it 'rebalances a set of issues with clumps at the end and start' do
- all_issues = start_clump + unclumped + end_clump.reverse
- service = described_class.new(Project.id_in([project.id]))
-
- expect { service.execute }.not_to change { issues_in_position_order.map(&:id) }
-
- all_issues.each(&:reset)
-
- gaps = all_issues.take(all_issues.count - 1).zip(all_issues.drop(1)).map do |a, b|
- b.relative_position - a.relative_position
- end
-
- expect(gaps).to all(be > RelativePositioning::MIN_GAP)
- expect(all_issues.first.relative_position).to be > (RelativePositioning::MIN_POSITION * 0.9999)
- expect(all_issues.last.relative_position).to be < (RelativePositioning::MAX_POSITION * 0.9999)
- end
-
- it 'is idempotent' do
- service = described_class.new(Project.id_in(project))
-
- expect do
- service.execute
- service.execute
- end.not_to change { issues_in_position_order.map(&:id) }
- end
-
- it 'does nothing if the feature flag is disabled' do
- stub_feature_flags(rebalance_issues: false)
- issue = project.issues.first
- issue.project
- issue.project.group
- old_pos = issue.relative_position
-
- service = described_class.new(Project.id_in(project))
-
- expect { service.execute }.not_to exceed_query_limit(0)
- expect(old_pos).to eq(issue.reload.relative_position)
- end
-
- it 'acts if the flag is enabled for the root namespace' do
- issue = create(:issue, project: project, author: user, relative_position: max_pos)
- stub_feature_flags(rebalance_issues: project.root_namespace)
-
- service = described_class.new(Project.id_in(project))
-
- expect { service.execute }.to change { issue.reload.relative_position }
- end
-
- it 'acts if the flag is enabled for the group' do
- issue = create(:issue, project: project, author: user, relative_position: max_pos)
- project.update!(group: create(:group))
- stub_feature_flags(rebalance_issues: issue.project.group)
-
- service = described_class.new(Project.id_in(project))
-
- expect { service.execute }.to change { issue.reload.relative_position }
- end
-
- it 'aborts if there are too many issues' do
- base = double(count: 10_001)
-
- allow(Issue).to receive(:in_projects).and_return(base)
-
- expect { described_class.new(Project.id_in(project)).execute }.to raise_error(described_class::TooManyIssues)
- end
- end
-
- shared_examples 'rebalancing is retried on statement timeout exceptions' do
- subject { described_class.new(Project.id_in(project)) }
-
- it 'retries update statement' do
- call_count = 0
- allow(subject).to receive(:run_update_query) do
- call_count += 1
- if call_count < 13
- raise(ActiveRecord::QueryCanceled)
- else
- call_count = 0 if call_count == 13 + 16 # 16 = 17 sub-batches - 1 call that succeeded as part of 5th batch
- true
- end
- end
-
- # call math:
- # batches start at 100 and are split in half after every 3 retries if ActiveRecord::StatementTimeout exception is raised.
- # We raise ActiveRecord::StatementTimeout exception for 13 calls:
- # 1. 100 => 3 calls
- # 2. 100/2=50 => 3 calls + 3 above = 6 calls, raise ActiveRecord::StatementTimeout
- # 3. 50/2=25 => 3 calls + 6 above = 9 calls, raise ActiveRecord::StatementTimeout
- # 4. 25/2=12 => 3 calls + 9 above = 12 calls, raise ActiveRecord::StatementTimeout
- # 5. 12/2=6 => 1 call + 12 above = 13 calls, run successfully
- #
- # so out of 100 elements we created batches of 6 items => 100/6 = 17 sub-batches of 6 or less elements
- #
- # project.issues.count: 900 issues, so 9 batches of 100 => 9 * (13+16) = 261
- expect(subject).to receive(:update_positions).exactly(261).times.and_call_original
-
- subject.execute
- end
- end
-
- context 'when issue_rebalancing_optimization feature flag is on' do
- before do
- stub_feature_flags(issue_rebalancing_optimization: true)
- end
-
- it_behaves_like 'IssueRebalancingService shared examples'
-
- context 'when issue_rebalancing_with_retry feature flag is on' do
- before do
- stub_feature_flags(issue_rebalancing_with_retry: true)
- end
-
- it_behaves_like 'IssueRebalancingService shared examples'
- it_behaves_like 'rebalancing is retried on statement timeout exceptions'
- end
- end
-
- context 'when issue_rebalancing_optimization feature flag is off' do
- before do
- stub_feature_flags(issue_rebalancing_optimization: false)
- end
-
- it_behaves_like 'IssueRebalancingService shared examples'
-
- context 'when issue_rebalancing_with_retry feature flag is on' do
- before do
- stub_feature_flags(issue_rebalancing_with_retry: true)
- end
-
- it_behaves_like 'IssueRebalancingService shared examples'
- it_behaves_like 'rebalancing is retried on statement timeout exceptions'
- end
- end
-end
diff --git a/spec/services/issues/build_service_spec.rb b/spec/services/issues/build_service_spec.rb
index 3f506ec58b0..b96dd981e0f 100644
--- a/spec/services/issues/build_service_spec.rb
+++ b/spec/services/issues/build_service_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe Issues::BuildService do
+ using RSpec::Parameterized::TableSyntax
+
let_it_be(:project) { create(:project, :repository) }
let_it_be(:developer) { create(:user) }
let_it_be(:guest) { create(:user) }
@@ -144,6 +146,8 @@ RSpec.describe Issues::BuildService do
issue = build_issue(milestone_id: milestone.id)
expect(issue.milestone).to eq(milestone)
+ expect(issue.issue_type).to eq('issue')
+ expect(issue.work_item_type.base_type).to eq('issue')
end
it 'sets milestone to nil if it is not available for the project' do
@@ -152,6 +156,15 @@ RSpec.describe Issues::BuildService do
expect(issue.milestone).to be_nil
end
+
+ context 'when issue_type is incident' do
+ it 'sets the correct issue type' do
+ issue = build_issue(issue_type: 'incident')
+
+ expect(issue.issue_type).to eq('incident')
+ expect(issue.work_item_type.base_type).to eq('incident')
+ end
+ end
end
context 'as guest' do
@@ -165,28 +178,37 @@ RSpec.describe Issues::BuildService do
end
context 'setting issue type' do
- it 'defaults to issue if issue_type not given' do
- issue = build_issue
+ shared_examples 'builds an issue' do
+ specify do
+ issue = build_issue(issue_type: issue_type)
- expect(issue).to be_issue
+ expect(issue.issue_type).to eq(resulting_issue_type)
+ expect(issue.work_item_type_id).to eq(work_item_type_id)
+ end
end
- it 'sets issue' do
- issue = build_issue(issue_type: 'issue')
+ it 'cannot set invalid issue type' do
+ issue = build_issue(issue_type: 'project')
expect(issue).to be_issue
end
- it 'sets incident' do
- issue = build_issue(issue_type: 'incident')
-
- expect(issue).to be_incident
- end
-
- it 'cannot set invalid type' do
- issue = build_issue(issue_type: 'invalid type')
-
- expect(issue).to be_issue
+ context 'with a corresponding WorkItem::Type' do
+ let_it_be(:type_issue_id) { WorkItem::Type.default_issue_type.id }
+ let_it_be(:type_incident_id) { WorkItem::Type.default_by_type(:incident).id }
+
+ where(:issue_type, :work_item_type_id, :resulting_issue_type) do
+ nil | ref(:type_issue_id) | 'issue'
+ 'issue' | ref(:type_issue_id) | 'issue'
+ 'incident' | ref(:type_incident_id) | 'incident'
+ 'test_case' | ref(:type_issue_id) | 'issue' # update once support for test_case is enabled
+ 'requirement' | ref(:type_issue_id) | 'issue' # update once support for requirement is enabled
+ 'invalid' | ref(:type_issue_id) | 'issue'
+ end
+
+ with_them do
+ it_behaves_like 'builds an issue'
+ end
end
end
end
diff --git a/spec/services/issues/close_service_spec.rb b/spec/services/issues/close_service_spec.rb
index b1d4877e138..14e6b44f7b0 100644
--- a/spec/services/issues/close_service_spec.rb
+++ b/spec/services/issues/close_service_spec.rb
@@ -58,8 +58,11 @@ RSpec.describe Issues::CloseService do
end
it 'refreshes the number of open issues', :use_clean_rails_memory_store_caching do
- expect { service.execute(issue) }
- .to change { project.open_issues_count }.from(1).to(0)
+ expect do
+ service.execute(issue)
+
+ BatchLoader::Executor.clear_current
+ end.to change { project.open_issues_count }.from(1).to(0)
end
it 'invalidates counter cache for assignees' do
@@ -222,7 +225,7 @@ RSpec.describe Issues::CloseService do
it 'verifies the number of queries' do
recorded = ActiveRecord::QueryRecorder.new { close_issue }
- expected_queries = 25
+ expected_queries = 27
expect(recorded.count).to be <= expected_queries
expect(recorded.cached_count).to eq(0)
diff --git a/spec/services/issues/create_service_spec.rb b/spec/services/issues/create_service_spec.rb
index 0e2b3b957a5..3988069d83a 100644
--- a/spec/services/issues/create_service_spec.rb
+++ b/spec/services/issues/create_service_spec.rb
@@ -43,10 +43,11 @@ RSpec.describe Issues::CreateService do
expect(issue).to be_persisted
expect(issue.title).to eq('Awesome issue')
- expect(issue.assignees).to eq [assignee]
- expect(issue.labels).to match_array labels
- expect(issue.milestone).to eq milestone
- expect(issue.due_date).to eq Date.tomorrow
+ expect(issue.assignees).to eq([assignee])
+ expect(issue.labels).to match_array(labels)
+ expect(issue.milestone).to eq(milestone)
+ expect(issue.due_date).to eq(Date.tomorrow)
+ expect(issue.work_item_type.base_type).to eq('issue')
end
context 'when skip_system_notes is true' do
@@ -91,7 +92,11 @@ RSpec.describe Issues::CreateService do
end
it 'refreshes the number of open issues', :use_clean_rails_memory_store_caching do
- expect { issue }.to change { project.open_issues_count }.from(0).to(1)
+ expect do
+ issue
+
+ BatchLoader::Executor.clear_current
+ end.to change { project.open_issues_count }.from(0).to(1)
end
context 'when current user cannot set issue metadata in the project' do
diff --git a/spec/services/issues/relative_position_rebalancing_service_spec.rb b/spec/services/issues/relative_position_rebalancing_service_spec.rb
new file mode 100644
index 00000000000..d5d81770817
--- /dev/null
+++ b/spec/services/issues/relative_position_rebalancing_service_spec.rb
@@ -0,0 +1,166 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Issues::RelativePositionRebalancingService, :clean_gitlab_redis_shared_state do
+ let_it_be(:project, reload: true) { create(:project) }
+ let_it_be(:user) { project.creator }
+ let_it_be(:start) { RelativePositioning::START_POSITION }
+ let_it_be(:max_pos) { RelativePositioning::MAX_POSITION }
+ let_it_be(:min_pos) { RelativePositioning::MIN_POSITION }
+ let_it_be(:clump_size) { 300 }
+
+ let_it_be(:unclumped, reload: true) do
+ (1..clump_size).to_a.map do |i|
+ create(:issue, project: project, author: user, relative_position: start + (1024 * i))
+ end
+ end
+
+ let_it_be(:end_clump, reload: true) do
+ (1..clump_size).to_a.map do |i|
+ create(:issue, project: project, author: user, relative_position: max_pos - i)
+ end
+ end
+
+ let_it_be(:start_clump, reload: true) do
+ (1..clump_size).to_a.map do |i|
+ create(:issue, project: project, author: user, relative_position: min_pos + i)
+ end
+ end
+
+ before do
+ stub_feature_flags(issue_rebalancing_with_retry: false)
+ end
+
+ def issues_in_position_order
+ project.reload.issues.reorder(relative_position: :asc).to_a
+ end
+
+ subject(:service) { described_class.new(Project.id_in(project)) }
+
+ context 'execute' do
+ it 're-balances a set of issues with clumps at the end and start' do
+ all_issues = start_clump + unclumped + end_clump.reverse
+
+ expect { service.execute }.not_to change { issues_in_position_order.map(&:id) }
+
+ all_issues.each(&:reset)
+
+ gaps = all_issues.take(all_issues.count - 1).zip(all_issues.drop(1)).map do |a, b|
+ b.relative_position - a.relative_position
+ end
+
+ expect(gaps).to all(be > RelativePositioning::MIN_GAP)
+ expect(all_issues.first.relative_position).to be > (RelativePositioning::MIN_POSITION * 0.9999)
+ expect(all_issues.last.relative_position).to be < (RelativePositioning::MAX_POSITION * 0.9999)
+ expect(project.root_namespace.issue_repositioning_disabled?).to be false
+ end
+
+ it 'is idempotent' do
+ expect do
+ service.execute
+ service.execute
+ end.not_to change { issues_in_position_order.map(&:id) }
+ end
+
+ it 'does nothing if the feature flag is disabled' do
+ stub_feature_flags(rebalance_issues: false)
+ issue = project.issues.first
+ issue.project
+ issue.project.group
+ old_pos = issue.relative_position
+
+ # fetching root namespace in the initializer triggers 2 queries:
+ # for fetching a random project from collection and fetching the root namespace.
+ expect { service.execute }.not_to exceed_query_limit(2)
+ expect(old_pos).to eq(issue.reload.relative_position)
+ end
+
+ it 'acts if the flag is enabled for the root namespace' do
+ issue = create(:issue, project: project, author: user, relative_position: max_pos)
+ stub_feature_flags(rebalance_issues: project.root_namespace)
+
+ expect { service.execute }.to change { issue.reload.relative_position }
+ end
+
+ it 'acts if the flag is enabled for the group' do
+ issue = create(:issue, project: project, author: user, relative_position: max_pos)
+ project.update!(group: create(:group))
+ stub_feature_flags(rebalance_issues: issue.project.group)
+
+ expect { service.execute }.to change { issue.reload.relative_position }
+ end
+
+ it 'aborts if there are too many rebalances running' do
+ caching = service.send(:caching)
+ allow(caching).to receive(:rebalance_in_progress?).and_return(false)
+ allow(caching).to receive(:concurrent_running_rebalances_count).and_return(10)
+ allow(service).to receive(:caching).and_return(caching)
+
+ expect { service.execute }.to raise_error(Issues::RelativePositionRebalancingService::TooManyConcurrentRebalances)
+ expect(project.root_namespace.issue_repositioning_disabled?).to be false
+ end
+
+ it 'resumes a started rebalance even if there are already too many rebalances running' do
+ Gitlab::Redis::SharedState.with do |redis|
+ redis.sadd("gitlab:issues-position-rebalances:running_rebalances", "#{::Gitlab::Issues::Rebalancing::State::PROJECT}/#{project.id}")
+ redis.sadd("gitlab:issues-position-rebalances:running_rebalances", "1/100")
+ end
+
+ caching = service.send(:caching)
+ allow(caching).to receive(:concurrent_running_rebalances_count).and_return(10)
+ allow(service).to receive(:caching).and_return(caching)
+
+ expect { service.execute }.not_to raise_error(Issues::RelativePositionRebalancingService::TooManyConcurrentRebalances)
+ end
+
+ context 're-balancing is retried on statement timeout exceptions' do
+ subject { service }
+
+ it 'retries update statement' do
+ call_count = 0
+ allow(subject).to receive(:run_update_query) do
+ call_count += 1
+ if call_count < 13
+ raise(ActiveRecord::QueryCanceled)
+ else
+ call_count = 0 if call_count == 13 + 16 # 16 = 17 sub-batches - 1 call that succeeded as part of 5th batch
+ true
+ end
+ end
+
+ # call math:
+ # batches start at 100 and are split in half after every 3 retries if ActiveRecord::StatementTimeout exception is raised.
+ # We raise ActiveRecord::StatementTimeout exception for 13 calls:
+ # 1. 100 => 3 calls
+ # 2. 100/2=50 => 3 calls + 3 above = 6 calls, raise ActiveRecord::StatementTimeout
+ # 3. 50/2=25 => 3 calls + 6 above = 9 calls, raise ActiveRecord::StatementTimeout
+ # 4. 25/2=12 => 3 calls + 9 above = 12 calls, raise ActiveRecord::StatementTimeout
+ # 5. 12/2=6 => 1 call + 12 above = 13 calls, run successfully
+ #
+ # so out of 100 elements we created batches of 6 items => 100/6 = 17 sub-batches of 6 or less elements
+ #
+ # project.issues.count: 900 issues, so 9 batches of 100 => 9 * (13+16) = 261
+ expect(subject).to receive(:update_positions).exactly(261).times.and_call_original
+
+ subject.execute
+ end
+ end
+
+ context 'when resuming a stopped rebalance' do
+ before do
+ service.send(:preload_issue_ids)
+ expect(service.send(:caching).get_cached_issue_ids(0, 300)).not_to be_empty
+ # simulate we already rebalanced half the issues
+ index = clump_size * 3 / 2 + 1
+ service.send(:caching).cache_current_index(index)
+ end
+
+ it 'rebalances the other half of issues' do
+ expect(subject).to receive(:update_positions_with_retry).exactly(5).and_call_original
+
+ subject.execute
+ end
+ end
+ end
+end
diff --git a/spec/services/issues/reopen_service_spec.rb b/spec/services/issues/reopen_service_spec.rb
index d58c27289c2..86190c4e475 100644
--- a/spec/services/issues/reopen_service_spec.rb
+++ b/spec/services/issues/reopen_service_spec.rb
@@ -39,8 +39,11 @@ RSpec.describe Issues::ReopenService do
it 'refreshes the number of opened issues' do
service = described_class.new(project: project, current_user: user)
- expect { service.execute(issue) }
- .to change { project.open_issues_count }.from(0).to(1)
+ expect do
+ service.execute(issue)
+
+ BatchLoader::Executor.clear_current
+ end.to change { project.open_issues_count }.from(0).to(1)
end
it 'deletes milestone issue counters cache' do
diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb
index 29ac7df88eb..331cf291f21 100644
--- a/spec/services/issues/update_service_spec.rb
+++ b/spec/services/issues/update_service_spec.rb
@@ -146,8 +146,11 @@ RSpec.describe Issues::UpdateService, :mailer do
it 'refreshes the number of open issues when the issue is made confidential', :use_clean_rails_memory_store_caching do
issue # make sure the issue is created first so our counts are correct.
- expect { update_issue(confidential: true) }
- .to change { project.open_issues_count }.from(1).to(0)
+ expect do
+ update_issue(confidential: true)
+
+ BatchLoader::Executor.clear_current
+ end.to change { project.open_issues_count }.from(1).to(0)
end
it 'enqueues ConfidentialIssueWorker when an issue is made confidential' do
@@ -189,6 +192,14 @@ RSpec.describe Issues::UpdateService, :mailer do
expect(issue.labels.pluck(:title)).to eq(['incident'])
end
+ it 'creates system note about issue type' do
+ update_issue(issue_type: 'incident')
+
+ note = find_note('changed issue type to incident')
+
+ expect(note).not_to eq(nil)
+ end
+
context 'for an issue with multiple labels' do
let(:issue) { create(:incident, project: project, labels: [label_1]) }
@@ -217,15 +228,19 @@ RSpec.describe Issues::UpdateService, :mailer do
context 'from incident to issue' do
let(:issue) { create(:incident, project: project) }
+ it 'changed from an incident to an issue type' do
+ expect { update_issue(issue_type: 'issue') }
+ .to change(issue, :issue_type).from('incident').to('issue')
+ .and(change { issue.work_item_type.base_type }.from('incident').to('issue'))
+ end
+
context 'for an incident with multiple labels' do
let(:issue) { create(:incident, project: project, labels: [label_1, label_2]) }
- before do
- update_issue(issue_type: 'issue')
- end
-
it 'removes an `incident` label if one exists on the incident' do
- expect(issue.labels).to eq([label_2])
+ expect { update_issue(issue_type: 'issue') }.to change(issue, :label_ids)
+ .from(containing_exactly(label_1.id, label_2.id))
+ .to([label_2.id])
end
end
@@ -233,12 +248,10 @@ RSpec.describe Issues::UpdateService, :mailer do
let(:issue) { create(:incident, project: project, labels: [label_1, label_2]) }
let(:params) { { label_ids: [label_1.id, label_2.id], remove_label_ids: [] } }
- before do
- update_issue(issue_type: 'issue')
- end
-
it 'adds an incident label id to remove_label_ids for it to be removed' do
- expect(issue.label_ids).to contain_exactly(label_2.id)
+ expect { update_issue(issue_type: 'issue') }.to change(issue, :label_ids)
+ .from(containing_exactly(label_1.id, label_2.id))
+ .to([label_2.id])
end
end
end
diff --git a/spec/services/members/groups/bulk_creator_service_spec.rb b/spec/services/members/groups/bulk_creator_service_spec.rb
new file mode 100644
index 00000000000..0623ae00080
--- /dev/null
+++ b/spec/services/members/groups/bulk_creator_service_spec.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Members::Groups::BulkCreatorService do
+ it_behaves_like 'bulk member creation' do
+ let_it_be(:source, reload: true) { create(:group, :public) }
+ let_it_be(:member_type) { GroupMember }
+ end
+end
diff --git a/spec/services/members/mailgun/process_webhook_service_spec.rb b/spec/services/members/mailgun/process_webhook_service_spec.rb
new file mode 100644
index 00000000000..d6a21183395
--- /dev/null
+++ b/spec/services/members/mailgun/process_webhook_service_spec.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Members::Mailgun::ProcessWebhookService do
+ describe '#execute', :aggregate_failures do
+ let_it_be(:member) { create(:project_member, :invited) }
+
+ let(:raw_invite_token) { member.raw_invite_token }
+ let(:payload) { { 'user-variables' => { ::Members::Mailgun::INVITE_EMAIL_TOKEN_KEY => raw_invite_token } } }
+
+ subject(:service) { described_class.new(payload).execute }
+
+ it 'marks the member invite email success as false' do
+ expect(Gitlab::AppLogger).to receive(:info).with(/^UPDATED MEMBER INVITE_EMAIL_SUCCESS/).and_call_original
+
+ expect { service }.to change { member.reload.invite_email_success }.from(true).to(false)
+ end
+
+ context 'when member can not be found' do
+ let(:raw_invite_token) { '_foobar_' }
+
+ it 'does not change member status' do
+ expect(Gitlab::AppLogger).not_to receive(:info).with(/^UPDATED MEMBER INVITE_EMAIL_SUCCESS/)
+
+ expect { service }.not_to change { member.reload.invite_email_success }
+ end
+ end
+
+ context 'when invite token is not found in payload' do
+ let(:payload) { {} }
+
+ it 'does not change member status and logs an error' do
+ expect(Gitlab::AppLogger).not_to receive(:info).with(/^UPDATED MEMBER INVITE_EMAIL_SUCCESS/)
+ expect(Gitlab::ErrorTracking).to receive(:track_exception).with(
+ an_instance_of(described_class::ProcessWebhookServiceError))
+
+ expect { service }.not_to change { member.reload.invite_email_success }
+ end
+ end
+ end
+end
diff --git a/spec/services/members/projects/bulk_creator_service_spec.rb b/spec/services/members/projects/bulk_creator_service_spec.rb
new file mode 100644
index 00000000000..7acb7d79fe7
--- /dev/null
+++ b/spec/services/members/projects/bulk_creator_service_spec.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Members::Projects::BulkCreatorService do
+ it_behaves_like 'bulk member creation' do
+ let_it_be(:source, reload: true) { create(:project, :public) }
+ let_it_be(:member_type) { ProjectMember }
+ end
+end
diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb
index b3af4d67896..e3f33304aab 100644
--- a/spec/services/merge_requests/merge_service_spec.rb
+++ b/spec/services/merge_requests/merge_service_spec.rb
@@ -402,21 +402,6 @@ RSpec.describe MergeRequests::MergeService do
expect(Gitlab::AppLogger).to have_received(:error).with(a_string_matching(error_message))
end
- it 'logs and saves error if there is a squash in progress' do
- error_message = 'another squash is already in progress'
-
- allow_any_instance_of(MergeRequest).to receive(:squash_in_progress?).and_return(true)
- merge_request.update!(squash: true)
-
- service.execute(merge_request)
-
- expect(merge_request).to be_open
- expect(merge_request.merge_commit_sha).to be_nil
- expect(merge_request.squash_commit_sha).to be_nil
- expect(merge_request.merge_error).to include(error_message)
- expect(Gitlab::AppLogger).to have_received(:error).with(a_string_matching(error_message))
- end
-
it 'logs and saves error if there is an PreReceiveError exception' do
error_message = 'error message'
diff --git a/spec/services/merge_requests/merge_to_ref_service_spec.rb b/spec/services/merge_requests/merge_to_ref_service_spec.rb
index 8fc12c6c2b1..0a781aee704 100644
--- a/spec/services/merge_requests/merge_to_ref_service_spec.rb
+++ b/spec/services/merge_requests/merge_to_ref_service_spec.rb
@@ -37,34 +37,26 @@ RSpec.describe MergeRequests::MergeToRefService do
expect(ref_head.id).to eq(result[:commit_id])
end
- context 'cache_merge_to_ref_calls flag enabled', :use_clean_rails_memory_store_caching do
+ context 'cache_merge_to_ref_calls parameter', :use_clean_rails_memory_store_caching do
before do
- stub_feature_flags(cache_merge_to_ref_calls: true)
-
# warm the cache
#
- service.execute(merge_request)
- end
-
- it 'caches the response', :request_store do
- expect { 3.times { service.execute(merge_request) } }
- .not_to change(Gitlab::GitalyClient, :get_request_count)
+ service.execute(merge_request, true)
end
- end
-
- context 'cache_merge_to_ref_calls flag disabled', :use_clean_rails_memory_store_caching do
- before do
- stub_feature_flags(cache_merge_to_ref_calls: false)
- # warm the cache
- #
- service.execute(merge_request)
+ context 'when true' do
+ it 'caches the response', :request_store do
+ expect { 3.times { service.execute(merge_request, true) } }
+ .not_to change(Gitlab::GitalyClient, :get_request_count)
+ end
end
- it 'does not cache the response', :request_store do
- expect(Gitlab::GitalyClient).to receive(:call).at_least(3).times.and_call_original
+ context 'when false' do
+ it 'does not cache the response', :request_store do
+ expect(Gitlab::GitalyClient).to receive(:call).at_least(3).times.and_call_original
- 3.times { service.execute(merge_request) }
+ 3.times { service.execute(merge_request, false) }
+ end
end
end
end
diff --git a/spec/services/merge_requests/mergeability_check_service_spec.rb b/spec/services/merge_requests/mergeability_check_service_spec.rb
index 65599b7e046..4f7be0f5965 100644
--- a/spec/services/merge_requests/mergeability_check_service_spec.rb
+++ b/spec/services/merge_requests/mergeability_check_service_spec.rb
@@ -132,6 +132,15 @@ RSpec.describe MergeRequests::MergeabilityCheckService, :clean_gitlab_redis_shar
it_behaves_like 'mergeable merge request'
+ it 'calls MergeToRefService with cache parameter' do
+ service = instance_double(MergeRequests::MergeToRefService)
+
+ expect(MergeRequests::MergeToRefService).to receive(:new).once { service }
+ expect(service).to receive(:execute).once.with(merge_request, true).and_return(success: true)
+
+ described_class.new(merge_request).execute(recheck: true)
+ end
+
context 'when concurrent calls' do
it 'waits first lock and returns "cached" result in subsequent calls' do
threads = execute_within_threads(amount: 3)
diff --git a/spec/services/merge_requests/squash_service_spec.rb b/spec/services/merge_requests/squash_service_spec.rb
index 149748cdabc..09f83624e05 100644
--- a/spec/services/merge_requests/squash_service_spec.rb
+++ b/spec/services/merge_requests/squash_service_spec.rb
@@ -194,23 +194,6 @@ RSpec.describe MergeRequests::SquashService do
expect(service.execute).to match(status: :error, message: a_string_including('squash'))
end
end
-
- context 'with an error in squash in progress check' do
- before do
- allow(repository).to receive(:squash_in_progress?)
- .and_raise(Gitlab::Git::Repository::GitError, error)
- end
-
- it 'logs the stage and output' do
- expect(service).to receive(:log_error).with(exception: an_instance_of(Gitlab::Git::Repository::GitError), message: 'Failed to check squash in progress')
-
- service.execute
- end
-
- it 'returns an error' do
- expect(service.execute).to match(status: :error, message: 'An error occurred while checking whether another squash is in progress.')
- end
- end
end
context 'when any other exception is thrown' do
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index 3c4d7d50002..a03f1f17b39 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -2623,7 +2623,7 @@ RSpec.describe NotificationService, :mailer do
let_it_be(:user) { create(:user) }
it 'sends the user an email' do
- notification.user_deactivated(user.name, user.notification_email)
+ notification.user_deactivated(user.name, user.notification_email_or_default)
should_only_email(user)
end
diff --git a/spec/services/packages/composer/version_parser_service_spec.rb b/spec/services/packages/composer/version_parser_service_spec.rb
index 1a2f653c042..69253ff934e 100644
--- a/spec/services/packages/composer/version_parser_service_spec.rb
+++ b/spec/services/packages/composer/version_parser_service_spec.rb
@@ -12,6 +12,7 @@ RSpec.describe Packages::Composer::VersionParserService do
where(:tagname, :branchname, :expected_version) do
nil | 'master' | 'dev-master'
nil | 'my-feature' | 'dev-my-feature'
+ nil | '12-feature' | 'dev-12-feature'
nil | 'v1' | '1.x-dev'
nil | 'v1.x' | '1.x-dev'
nil | 'v1.7.x' | '1.7.x-dev'
diff --git a/spec/services/packages/generic/create_package_file_service_spec.rb b/spec/services/packages/generic/create_package_file_service_spec.rb
index 1c9eb53cfc7..9d6784b7721 100644
--- a/spec/services/packages/generic/create_package_file_service_spec.rb
+++ b/spec/services/packages/generic/create_package_file_service_spec.rb
@@ -105,6 +105,37 @@ RSpec.describe Packages::Generic::CreatePackageFileService do
it { expect { execute_service }.to change { project.package_files.count }.by(1) }
end
end
+
+ context 'with multiple files for the same package and the same pipeline' do
+ let(:file_2_params) { params.merge(file_name: 'myfile.tar.gz.2', file: file2) }
+ let(:file_3_params) { params.merge(file_name: 'myfile.tar.gz.3', file: file3) }
+
+ let(:temp_file2) { Tempfile.new("test2") }
+ let(:temp_file3) { Tempfile.new("test3") }
+
+ let(:file2) { UploadedFile.new(temp_file2.path, sha256: sha256) }
+ let(:file3) { UploadedFile.new(temp_file3.path, sha256: sha256) }
+
+ before do
+ FileUtils.touch(temp_file2)
+ FileUtils.touch(temp_file3)
+ expect(::Packages::Generic::FindOrCreatePackageService).to receive(:new).with(project, user, package_params).and_return(package_service).twice
+ expect(package_service).to receive(:execute).and_return(package).twice
+ end
+
+ after do
+ FileUtils.rm_f(temp_file2)
+ FileUtils.rm_f(temp_file3)
+ end
+
+ it 'creates the build info only once' do
+ expect do
+ described_class.new(project, user, params).execute
+ described_class.new(project, user, file_2_params).execute
+ described_class.new(project, user, file_3_params).execute
+ end.to change { package.build_infos.count }.by(1)
+ end
+ end
end
end
end
diff --git a/spec/services/packages/maven/find_or_create_package_service_spec.rb b/spec/services/packages/maven/find_or_create_package_service_spec.rb
index d8b48af0121..59f5677f526 100644
--- a/spec/services/packages/maven/find_or_create_package_service_spec.rb
+++ b/spec/services/packages/maven/find_or_create_package_service_spec.rb
@@ -98,6 +98,19 @@ RSpec.describe Packages::Maven::FindOrCreatePackageService do
it 'creates a build_info' do
expect { subject }.to change { Packages::BuildInfo.count }.by(1)
end
+
+ context 'with multiple files for the same package and the same pipeline' do
+ let(:file_2_params) { params.merge(file_name: 'test2.jar') }
+ let(:file_3_params) { params.merge(file_name: 'test3.jar') }
+
+ it 'creates a single build info' do
+ expect do
+ described_class.new(project, user, params).execute
+ described_class.new(project, user, file_2_params).execute
+ described_class.new(project, user, file_3_params).execute
+ end.to change { ::Packages::BuildInfo.count }.by(1)
+ end
+ end
end
context 'when package duplicates are not allowed' do
diff --git a/spec/services/packages/nuget/update_package_from_metadata_service_spec.rb b/spec/services/packages/nuget/update_package_from_metadata_service_spec.rb
index 66ff6a8d03f..d682ee12ed5 100644
--- a/spec/services/packages/nuget/update_package_from_metadata_service_spec.rb
+++ b/spec/services/packages/nuget/update_package_from_metadata_service_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Packages::Nuget::UpdatePackageFromMetadataService, :clean_gitlab_redis_shared_state do
include ExclusiveLeaseHelpers
- let(:package) { create(:nuget_package, :processing, :with_symbol_package) }
+ let!(:package) { create(:nuget_package, :processing, :with_symbol_package) }
let(:package_file) { package.package_files.first }
let(:service) { described_class.new(package_file) }
let(:package_name) { 'DummyProject.DummyPackage' }
@@ -63,234 +63,213 @@ RSpec.describe Packages::Nuget::UpdatePackageFromMetadataService, :clean_gitlab_
end
end
- shared_examples 'handling all conditions' do
- context 'with no existing package' do
- let(:package_id) { package.id }
+ context 'with no existing package' do
+ let(:package_id) { package.id }
+
+ it 'updates package and package file', :aggregate_failures do
+ expect { subject }
+ .to not_change { ::Packages::Package.count }
+ .and change { Packages::Dependency.count }.by(1)
+ .and change { Packages::DependencyLink.count }.by(1)
+ .and change { ::Packages::Nuget::Metadatum.count }.by(0)
+
+ expect(package.reload.name).to eq(package_name)
+ expect(package.version).to eq(package_version)
+ expect(package).to be_default
+ expect(package_file.reload.file_name).to eq(package_file_name)
+ # hard reset needed to properly reload package_file.file
+ expect(Packages::PackageFile.find(package_file.id).file.size).not_to eq 0
+ end
- it 'updates package and package file', :aggregate_failures do
- expect { subject }
- .to not_change { ::Packages::Package.count }
- .and change { Packages::Dependency.count }.by(1)
- .and change { Packages::DependencyLink.count }.by(1)
- .and change { ::Packages::Nuget::Metadatum.count }.by(0)
+ it_behaves_like 'taking the lease'
- expect(package.reload.name).to eq(package_name)
- expect(package.version).to eq(package_version)
- expect(package).to be_default
- expect(package_file.reload.file_name).to eq(package_file_name)
- # hard reset needed to properly reload package_file.file
- expect(Packages::PackageFile.find(package_file.id).file.size).not_to eq 0
- end
+ it_behaves_like 'not updating the package if the lease is taken'
+ end
- it_behaves_like 'taking the lease'
+ context 'with existing package' do
+ let!(:existing_package) { create(:nuget_package, project: package.project, name: package_name, version: package_version) }
+ let(:package_id) { existing_package.id }
- it_behaves_like 'not updating the package if the lease is taken'
- end
+ it 'link existing package and updates package file', :aggregate_failures do
+ expect(service).to receive(:try_obtain_lease).and_call_original
- context 'with existing package' do
- let!(:existing_package) { create(:nuget_package, project: package.project, name: package_name, version: package_version) }
- let(:package_id) { existing_package.id }
+ expect { subject }
+ .to change { ::Packages::Package.count }.by(-1)
+ .and change { Packages::Dependency.count }.by(0)
+ .and change { Packages::DependencyLink.count }.by(0)
+ .and change { Packages::Nuget::DependencyLinkMetadatum.count }.by(0)
+ .and change { ::Packages::Nuget::Metadatum.count }.by(0)
+ expect(package_file.reload.file_name).to eq(package_file_name)
+ expect(package_file.package).to eq(existing_package)
+ end
- it 'link existing package and updates package file', :aggregate_failures do
- expect(service).to receive(:try_obtain_lease).and_call_original
+ it_behaves_like 'taking the lease'
- expect { subject }
- .to change { ::Packages::Package.count }.by(-1)
- .and change { Packages::Dependency.count }.by(0)
- .and change { Packages::DependencyLink.count }.by(0)
- .and change { Packages::Nuget::DependencyLinkMetadatum.count }.by(0)
- .and change { ::Packages::Nuget::Metadatum.count }.by(0)
- expect(package_file.reload.file_name).to eq(package_file_name)
- expect(package_file.package).to eq(existing_package)
- end
+ it_behaves_like 'not updating the package if the lease is taken'
+ end
- it_behaves_like 'taking the lease'
+ context 'with a nuspec file with metadata' do
+ let(:nuspec_filepath) { 'packages/nuget/with_metadata.nuspec' }
+ let(:expected_tags) { %w(foo bar test tag1 tag2 tag3 tag4 tag5) }
- it_behaves_like 'not updating the package if the lease is taken'
+ before do
+ allow_next_instance_of(Packages::Nuget::MetadataExtractionService) do |service|
+ allow(service)
+ .to receive(:nuspec_file_content).and_return(fixture_file(nuspec_filepath))
+ end
end
- context 'with a nuspec file with metadata' do
- let(:nuspec_filepath) { 'packages/nuget/with_metadata.nuspec' }
- let(:expected_tags) { %w(foo bar test tag1 tag2 tag3 tag4 tag5) }
+ it 'creates tags' do
+ expect(service).to receive(:try_obtain_lease).and_call_original
+ expect { subject }.to change { ::Packages::Tag.count }.by(8)
+ expect(package.reload.tags.map(&:name)).to contain_exactly(*expected_tags)
+ end
- before do
- allow_next_instance_of(Packages::Nuget::MetadataExtractionService) do |service|
- allow(service)
- .to receive(:nuspec_file_content).and_return(fixture_file(nuspec_filepath))
- end
- end
+ context 'with existing package and tags' do
+ let!(:existing_package) { create(:nuget_package, project: package.project, name: 'DummyProject.WithMetadata', version: '1.2.3') }
+ let!(:tag1) { create(:packages_tag, package: existing_package, name: 'tag1') }
+ let!(:tag2) { create(:packages_tag, package: existing_package, name: 'tag2') }
+ let!(:tag3) { create(:packages_tag, package: existing_package, name: 'tag_not_in_metadata') }
- it 'creates tags' do
+ it 'creates tags and deletes those not in metadata' do
expect(service).to receive(:try_obtain_lease).and_call_original
- expect { subject }.to change { ::Packages::Tag.count }.by(8)
- expect(package.reload.tags.map(&:name)).to contain_exactly(*expected_tags)
+ expect { subject }.to change { ::Packages::Tag.count }.by(5)
+ expect(existing_package.tags.map(&:name)).to contain_exactly(*expected_tags)
end
+ end
- context 'with existing package and tags' do
- let!(:existing_package) { create(:nuget_package, project: package.project, name: 'DummyProject.WithMetadata', version: '1.2.3') }
- let!(:tag1) { create(:packages_tag, package: existing_package, name: 'tag1') }
- let!(:tag2) { create(:packages_tag, package: existing_package, name: 'tag2') }
- let!(:tag3) { create(:packages_tag, package: existing_package, name: 'tag_not_in_metadata') }
-
- it 'creates tags and deletes those not in metadata' do
- expect(service).to receive(:try_obtain_lease).and_call_original
- expect { subject }.to change { ::Packages::Tag.count }.by(5)
- expect(existing_package.tags.map(&:name)).to contain_exactly(*expected_tags)
- end
- end
-
- it 'creates nuget metadatum', :aggregate_failures do
- expect { subject }
- .to not_change { ::Packages::Package.count }
- .and change { ::Packages::Nuget::Metadatum.count }.by(1)
-
- metadatum = package_file.reload.package.nuget_metadatum
- expect(metadatum.license_url).to eq('https://opensource.org/licenses/MIT')
- expect(metadatum.project_url).to eq('https://gitlab.com/gitlab-org/gitlab')
- expect(metadatum.icon_url).to eq('https://opensource.org/files/osi_keyhole_300X300_90ppi_0.png')
- end
+ it 'creates nuget metadatum', :aggregate_failures do
+ expect { subject }
+ .to not_change { ::Packages::Package.count }
+ .and change { ::Packages::Nuget::Metadatum.count }.by(1)
- context 'with too long url' do
- let_it_be(:too_long_url) { "http://localhost/#{'bananas' * 50}" }
+ metadatum = package_file.reload.package.nuget_metadatum
+ expect(metadatum.license_url).to eq('https://opensource.org/licenses/MIT')
+ expect(metadatum.project_url).to eq('https://gitlab.com/gitlab-org/gitlab')
+ expect(metadatum.icon_url).to eq('https://opensource.org/files/osi_keyhole_300X300_90ppi_0.png')
+ end
- let(:metadata) { { package_name: package_name, package_version: package_version, license_url: too_long_url } }
+ context 'with too long url' do
+ let_it_be(:too_long_url) { "http://localhost/#{'bananas' * 50}" }
- before do
- allow(service).to receive(:metadata).and_return(metadata)
- end
+ let(:metadata) { { package_name: package_name, package_version: package_version, license_url: too_long_url } }
- it_behaves_like 'raising an', ::Packages::Nuget::UpdatePackageFromMetadataService::InvalidMetadataError
+ before do
+ allow(service).to receive(:metadata).and_return(metadata)
end
+
+ it_behaves_like 'raising an', ::Packages::Nuget::UpdatePackageFromMetadataService::InvalidMetadataError
end
+ end
- context 'with nuspec file with dependencies' do
- let(:nuspec_filepath) { 'packages/nuget/with_dependencies.nuspec' }
- let(:package_name) { 'Test.Package' }
- let(:package_version) { '3.5.2' }
- let(:package_file_name) { 'test.package.3.5.2.nupkg' }
+ context 'with nuspec file with dependencies' do
+ let(:nuspec_filepath) { 'packages/nuget/with_dependencies.nuspec' }
+ let(:package_name) { 'Test.Package' }
+ let(:package_version) { '3.5.2' }
+ let(:package_file_name) { 'test.package.3.5.2.nupkg' }
- before do
- allow_next_instance_of(Packages::Nuget::MetadataExtractionService) do |service|
- allow(service)
- .to receive(:nuspec_file_content).and_return(fixture_file(nuspec_filepath))
- end
+ before do
+ allow_next_instance_of(Packages::Nuget::MetadataExtractionService) do |service|
+ allow(service)
+ .to receive(:nuspec_file_content).and_return(fixture_file(nuspec_filepath))
end
+ end
- it 'updates package and package file', :aggregate_failures do
- expect { subject }
- .to not_change { ::Packages::Package.count }
- .and change { Packages::Dependency.count }.by(4)
- .and change { Packages::DependencyLink.count }.by(4)
- .and change { Packages::Nuget::DependencyLinkMetadatum.count }.by(2)
-
- expect(package.reload.name).to eq(package_name)
- expect(package.version).to eq(package_version)
- expect(package).to be_default
- expect(package_file.reload.file_name).to eq(package_file_name)
- # hard reset needed to properly reload package_file.file
- expect(Packages::PackageFile.find(package_file.id).file.size).not_to eq 0
- end
+ it 'updates package and package file', :aggregate_failures do
+ expect { subject }
+ .to not_change { ::Packages::Package.count }
+ .and change { Packages::Dependency.count }.by(4)
+ .and change { Packages::DependencyLink.count }.by(4)
+ .and change { Packages::Nuget::DependencyLinkMetadatum.count }.by(2)
+
+ expect(package.reload.name).to eq(package_name)
+ expect(package.version).to eq(package_version)
+ expect(package).to be_default
+ expect(package_file.reload.file_name).to eq(package_file_name)
+ # hard reset needed to properly reload package_file.file
+ expect(Packages::PackageFile.find(package_file.id).file.size).not_to eq 0
end
+ end
- context 'with package file not containing a nuspec file' do
- before do
- allow_next_instance_of(Zip::File) do |file|
- allow(file).to receive(:glob).and_return([])
- end
+ context 'with package file not containing a nuspec file' do
+ before do
+ allow_next_instance_of(Zip::File) do |file|
+ allow(file).to receive(:glob).and_return([])
end
-
- it_behaves_like 'raising an', ::Packages::Nuget::MetadataExtractionService::ExtractionError
end
- context 'with a symbol package' do
- let(:package_file) { package.package_files.last }
- let(:package_file_name) { 'dummyproject.dummypackage.1.0.0.snupkg' }
+ it_behaves_like 'raising an', ::Packages::Nuget::MetadataExtractionService::ExtractionError
+ end
- context 'with no existing package' do
- let(:package_id) { package.id }
+ context 'with a symbol package' do
+ let(:package_file) { package.package_files.last }
+ let(:package_file_name) { 'dummyproject.dummypackage.1.0.0.snupkg' }
- it_behaves_like 'raising an', ::Packages::Nuget::UpdatePackageFromMetadataService::InvalidMetadataError
- end
-
- context 'with existing package' do
- let!(:existing_package) { create(:nuget_package, project: package.project, name: package_name, version: package_version) }
- let(:package_id) { existing_package.id }
+ context 'with no existing package' do
+ let(:package_id) { package.id }
- it 'link existing package and updates package file', :aggregate_failures do
- expect(service).to receive(:try_obtain_lease).and_call_original
- expect(::Packages::Nuget::SyncMetadatumService).not_to receive(:new)
- expect(::Packages::UpdateTagsService).not_to receive(:new)
+ it_behaves_like 'raising an', ::Packages::Nuget::UpdatePackageFromMetadataService::InvalidMetadataError
+ end
- expect { subject }
- .to change { ::Packages::Package.count }.by(-1)
- .and change { Packages::Dependency.count }.by(0)
- .and change { Packages::DependencyLink.count }.by(0)
- .and change { Packages::Nuget::DependencyLinkMetadatum.count }.by(0)
- .and change { ::Packages::Nuget::Metadatum.count }.by(0)
- expect(package_file.reload.file_name).to eq(package_file_name)
- expect(package_file.package).to eq(existing_package)
- end
+ context 'with existing package' do
+ let!(:existing_package) { create(:nuget_package, project: package.project, name: package_name, version: package_version) }
+ let(:package_id) { existing_package.id }
- it_behaves_like 'taking the lease'
+ it 'link existing package and updates package file', :aggregate_failures do
+ expect(service).to receive(:try_obtain_lease).and_call_original
+ expect(::Packages::Nuget::SyncMetadatumService).not_to receive(:new)
+ expect(::Packages::UpdateTagsService).not_to receive(:new)
- it_behaves_like 'not updating the package if the lease is taken'
+ expect { subject }
+ .to change { ::Packages::Package.count }.by(-1)
+ .and change { Packages::Dependency.count }.by(0)
+ .and change { Packages::DependencyLink.count }.by(0)
+ .and change { Packages::Nuget::DependencyLinkMetadatum.count }.by(0)
+ .and change { ::Packages::Nuget::Metadatum.count }.by(0)
+ expect(package_file.reload.file_name).to eq(package_file_name)
+ expect(package_file.package).to eq(existing_package)
end
- end
-
- context 'with an invalid package name' do
- invalid_names = [
- '',
- 'My/package',
- '../../../my_package',
- '%2e%2e%2fmy_package'
- ]
- invalid_names.each do |invalid_name|
- before do
- allow(service).to receive(:package_name).and_return(invalid_name)
- end
+ it_behaves_like 'taking the lease'
- it_behaves_like 'raising an', ::Packages::Nuget::UpdatePackageFromMetadataService::InvalidMetadataError
- end
+ it_behaves_like 'not updating the package if the lease is taken'
end
+ end
- context 'with an invalid package version' do
- invalid_versions = [
- '',
- '555',
- '1.2',
- '1./2.3',
- '../../../../../1.2.3',
- '%2e%2e%2f1.2.3'
- ]
-
- invalid_versions.each do |invalid_version|
- before do
- allow(service).to receive(:package_version).and_return(invalid_version)
- end
-
- it_behaves_like 'raising an', ::Packages::Nuget::UpdatePackageFromMetadataService::InvalidMetadataError
+ context 'with an invalid package name' do
+ invalid_names = [
+ '',
+ 'My/package',
+ '../../../my_package',
+ '%2e%2e%2fmy_package'
+ ]
+
+ invalid_names.each do |invalid_name|
+ before do
+ allow(service).to receive(:package_name).and_return(invalid_name)
end
- end
- end
- context 'with packages_nuget_new_package_file_updater enabled' do
- before do
- expect(service).not_to receive(:legacy_execute)
+ it_behaves_like 'raising an', ::Packages::Nuget::UpdatePackageFromMetadataService::InvalidMetadataError
end
-
- it_behaves_like 'handling all conditions'
end
- context 'with packages_nuget_new_package_file_updater disabled' do
- before do
- stub_feature_flags(packages_nuget_new_package_file_updater: false)
- expect(::Packages::UpdatePackageFileService)
- .not_to receive(:new).with(package_file, instance_of(Hash)).and_call_original
- expect(service).not_to receive(:new_execute)
- end
+ context 'with an invalid package version' do
+ invalid_versions = [
+ '',
+ '555',
+ '1.2',
+ '1./2.3',
+ '../../../../../1.2.3',
+ '%2e%2e%2f1.2.3'
+ ]
+
+ invalid_versions.each do |invalid_version|
+ before do
+ allow(service).to receive(:package_version).and_return(invalid_version)
+ end
- it_behaves_like 'handling all conditions'
+ it_behaves_like 'raising an', ::Packages::Nuget::UpdatePackageFromMetadataService::InvalidMetadataError
+ end
end
end
end
diff --git a/spec/services/pages/delete_service_spec.rb b/spec/services/pages/delete_service_spec.rb
index 295abe15bf0..e02e8e72e0b 100644
--- a/spec/services/pages/delete_service_spec.rb
+++ b/spec/services/pages/delete_service_spec.rb
@@ -12,27 +12,6 @@ RSpec.describe Pages::DeleteService do
project.mark_pages_as_deployed
end
- it 'deletes published pages', :sidekiq_inline do
- expect_next_instance_of(Gitlab::PagesTransfer) do |pages_transfer|
- expect(pages_transfer).to receive(:rename_project).and_return true
- end
-
- expect(PagesWorker).to receive(:perform_in).with(5.minutes, :remove, project.namespace.full_path, anything)
-
- service.execute
- end
-
- it "doesn't remove anything from the legacy storage if local_store is disabled", :sidekiq_inline do
- allow(Settings.pages.local_store).to receive(:enabled).and_return(false)
-
- expect(project.pages_deployed?).to be(true)
- expect(PagesWorker).not_to receive(:perform_in)
-
- service.execute
-
- expect(project.pages_deployed?).to be(false)
- end
-
it 'marks pages as not deployed' do
expect do
service.execute
diff --git a/spec/services/pages/legacy_storage_lease_spec.rb b/spec/services/pages/legacy_storage_lease_spec.rb
deleted file mode 100644
index 092dce093ff..00000000000
--- a/spec/services/pages/legacy_storage_lease_spec.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe ::Pages::LegacyStorageLease do
- let(:project) { create(:project) }
-
- let(:implementation) do
- Class.new do
- include ::Pages::LegacyStorageLease
-
- attr_reader :project
-
- def initialize(project)
- @project = project
- end
-
- def execute
- try_obtain_lease do
- execute_unsafe
- end
- end
-
- def execute_unsafe
- true
- end
- end
- end
-
- let(:service) { implementation.new(project) }
-
- it 'allows method to be executed' do
- expect(service).to receive(:execute_unsafe).and_call_original
-
- expect(service.execute).to eq(true)
- end
-
- context 'when another service holds the lease for the same project' do
- around do |example|
- implementation.new(project).try_obtain_lease do
- example.run
- end
- end
-
- it 'does not run guarded method' do
- expect(service).not_to receive(:execute_unsafe)
-
- expect(service.execute).to eq(nil)
- end
- end
-
- context 'when another service holds the lease for the different project' do
- around do |example|
- implementation.new(create(:project)).try_obtain_lease do
- example.run
- end
- end
-
- it 'allows method to be executed' do
- expect(service).to receive(:execute_unsafe).and_call_original
-
- expect(service.execute).to eq(true)
- end
- end
-end
diff --git a/spec/services/pages/migrate_legacy_storage_to_deployment_service_spec.rb b/spec/services/pages/migrate_legacy_storage_to_deployment_service_spec.rb
index 25f571a73d1..177467aac85 100644
--- a/spec/services/pages/migrate_legacy_storage_to_deployment_service_spec.rb
+++ b/spec/services/pages/migrate_legacy_storage_to_deployment_service_spec.rb
@@ -114,13 +114,5 @@ RSpec.describe Pages::MigrateLegacyStorageToDeploymentService do
described_class.new(project).execute
end.not_to change { project.pages_metadatum.reload.pages_deployment_id }.from(old_deployment.id)
end
-
- it 'raises exception if exclusive lease is taken' do
- described_class.new(project).try_obtain_lease do
- expect do
- described_class.new(project).execute
- end.to raise_error(described_class::ExclusiveLeaseTakenError)
- end
- end
end
end
diff --git a/spec/services/projects/batch_open_issues_count_service_spec.rb b/spec/services/projects/batch_open_issues_count_service_spec.rb
index 82d50604309..17bd5f7a37b 100644
--- a/spec/services/projects/batch_open_issues_count_service_spec.rb
+++ b/spec/services/projects/batch_open_issues_count_service_spec.rb
@@ -5,52 +5,49 @@ require 'spec_helper'
RSpec.describe Projects::BatchOpenIssuesCountService do
let!(:project_1) { create(:project) }
let!(:project_2) { create(:project) }
+ let!(:banned_user) { create(:user, :banned) }
let(:subject) { described_class.new([project_1, project_2]) }
- describe '#refresh_cache', :use_clean_rails_memory_store_caching do
+ describe '#refresh_cache_and_retrieve_data', :use_clean_rails_memory_store_caching do
before do
create(:issue, project: project_1)
create(:issue, project: project_1, confidential: true)
-
+ create(:issue, project: project_1, author: banned_user)
create(:issue, project: project_2)
create(:issue, project: project_2, confidential: true)
+ create(:issue, project: project_2, author: banned_user)
end
- context 'when cache is clean' do
+ context 'when cache is clean', :aggregate_failures do
it 'refreshes cache keys correctly' do
- subject.refresh_cache
+ expect(get_cache_key(project_1)).to eq(nil)
+ expect(get_cache_key(project_2)).to eq(nil)
- # It does not update total issues cache
- expect(Rails.cache.read(get_cache_key(subject, project_1))).to eq(nil)
- expect(Rails.cache.read(get_cache_key(subject, project_2))).to eq(nil)
+ subject.count_service.new(project_1).refresh_cache
+ subject.count_service.new(project_2).refresh_cache
- expect(Rails.cache.read(get_cache_key(subject, project_1, true))).to eq(1)
- expect(Rails.cache.read(get_cache_key(subject, project_1, true))).to eq(1)
- end
- end
-
- context 'when issues count is already cached' do
- before do
- create(:issue, project: project_2)
- subject.refresh_cache
- end
+ expect(get_cache_key(project_1)).to eq(1)
+ expect(get_cache_key(project_2)).to eq(1)
- it 'does update cache again' do
- expect(Rails.cache).not_to receive(:write)
+ expect(get_cache_key(project_1, true)).to eq(2)
+ expect(get_cache_key(project_2, true)).to eq(2)
- subject.refresh_cache
+ expect(get_cache_key(project_1, true, true)).to eq(3)
+ expect(get_cache_key(project_2, true, true)).to eq(3)
end
end
end
- def get_cache_key(subject, project, public_key = false)
+ def get_cache_key(project, with_confidential = false, with_hidden = false)
service = subject.count_service.new(project)
- if public_key
- service.cache_key(service.class::PUBLIC_COUNT_KEY)
+ if with_confidential && with_hidden
+ Rails.cache.read(service.cache_key(service.class::TOTAL_COUNT_KEY))
+ elsif with_confidential
+ Rails.cache.read(service.cache_key(service.class::TOTAL_COUNT_WITHOUT_HIDDEN_KEY))
else
- service.cache_key(service.class::TOTAL_COUNT_KEY)
+ Rails.cache.read(service.cache_key(service.class::PUBLIC_COUNT_WITHOUT_HIDDEN_KEY))
end
end
end
diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb
index c3928563125..e15d9341fd1 100644
--- a/spec/services/projects/create_service_spec.rb
+++ b/spec/services/projects/create_service_spec.rb
@@ -86,7 +86,7 @@ RSpec.describe Projects::CreateService, '#execute' do
subject(:project) { create_project(user, opts) }
context "with 'topics' parameter" do
- let(:opts) { { topics: 'topics' } }
+ let(:opts) { { name: 'topic-project', topics: 'topics' } }
it 'keeps them as specified' do
expect(project.topic_list).to eq(%w[topics])
@@ -94,7 +94,7 @@ RSpec.describe Projects::CreateService, '#execute' do
end
context "with 'topic_list' parameter" do
- let(:opts) { { topic_list: 'topic_list' } }
+ let(:opts) { { name: 'topic-project', topic_list: 'topic_list' } }
it 'keeps them as specified' do
expect(project.topic_list).to eq(%w[topic_list])
@@ -102,7 +102,7 @@ RSpec.describe Projects::CreateService, '#execute' do
end
context "with 'tag_list' parameter (deprecated)" do
- let(:opts) { { tag_list: 'tag_list' } }
+ let(:opts) { { name: 'topic-project', tag_list: 'tag_list' } }
it 'keeps them as specified' do
expect(project.topic_list).to eq(%w[tag_list])
@@ -346,6 +346,12 @@ RSpec.describe Projects::CreateService, '#execute' do
expect(imported_project.import_data.data).to eq(import_data[:data])
expect(imported_project.import_url).to eq('http://import-url')
end
+
+ it 'tracks for the combined_registration experiment', :experiment do
+ expect(experiment(:combined_registration)).to track(:import_project).on_next_instance
+
+ imported_project
+ end
end
context 'builds_enabled global setting' do
@@ -601,6 +607,18 @@ RSpec.describe Projects::CreateService, '#execute' do
MARKDOWN
end
end
+
+ context 'and readme_template is specified' do
+ before do
+ opts[:readme_template] = "# GitLab\nThis is customized template."
+ end
+
+ it_behaves_like 'creates README.md'
+
+ it 'creates README.md with specified template' do
+ expect(project.repository.readme.data).to include('This is customized template.')
+ end
+ end
end
end
diff --git a/spec/services/projects/fork_service_spec.rb b/spec/services/projects/fork_service_spec.rb
index d710e4a777f..3f58fa46806 100644
--- a/spec/services/projects/fork_service_spec.rb
+++ b/spec/services/projects/fork_service_spec.rb
@@ -28,7 +28,8 @@ RSpec.describe Projects::ForkService do
namespace: @from_namespace,
star_count: 107,
avatar: avatar,
- description: 'wow such project')
+ description: 'wow such project',
+ external_authorization_classification_label: 'classification-label')
@to_user = create(:user)
@to_namespace = @to_user.namespace
@from_project.add_user(@to_user, :developer)
@@ -66,6 +67,7 @@ RSpec.describe Projects::ForkService do
it { expect(to_project.description).to eq(@from_project.description) }
it { expect(to_project.avatar.file).to be_exists }
it { expect(to_project.ci_config_path).to eq(@from_project.ci_config_path) }
+ it { expect(to_project.external_authorization_classification_label).to eq(@from_project.external_authorization_classification_label) }
# This test is here because we had a bug where the from-project lost its
# avatar after being forked.
diff --git a/spec/services/projects/group_links/destroy_service_spec.rb b/spec/services/projects/group_links/destroy_service_spec.rb
index d65afb68bfe..5d07fd52230 100644
--- a/spec/services/projects/group_links/destroy_service_spec.rb
+++ b/spec/services/projects/group_links/destroy_service_spec.rb
@@ -20,54 +20,28 @@ RSpec.describe Projects::GroupLinks::DestroyService, '#execute' do
group.add_maintainer(user)
end
- context 'when the feature flag `use_specialized_worker_for_project_auth_recalculation` is enabled' do
- before do
- stub_feature_flags(use_specialized_worker_for_project_auth_recalculation: true)
- end
-
- it 'calls AuthorizedProjectUpdate::ProjectRecalculateWorker to update project authorizations' do
- expect(AuthorizedProjectUpdate::ProjectRecalculateWorker)
- .to receive(:perform_async).with(group_link.project.id)
-
- subject.execute(group_link)
- end
-
- it 'calls AuthorizedProjectUpdate::UserRefreshFromReplicaWorker with a delay to update project authorizations' do
- expect(AuthorizedProjectUpdate::UserRefreshFromReplicaWorker).to(
- receive(:bulk_perform_in)
- .with(1.hour,
- [[user.id]],
- batch_delay: 30.seconds, batch_size: 100)
- )
-
- subject.execute(group_link)
- end
+ it 'calls AuthorizedProjectUpdate::ProjectRecalculateWorker to update project authorizations' do
+ expect(AuthorizedProjectUpdate::ProjectRecalculateWorker)
+ .to receive(:perform_async).with(group_link.project.id)
- it 'updates project authorizations of users who had access to the project via the group share', :sidekiq_inline do
- expect { subject.execute(group_link) }.to(
- change { Ability.allowed?(user, :read_project, project) }
- .from(true).to(false))
- end
+ subject.execute(group_link)
end
- context 'when the feature flag `use_specialized_worker_for_project_auth_recalculation` is disabled' do
- before do
- stub_feature_flags(use_specialized_worker_for_project_auth_recalculation: false)
- end
-
- it 'calls UserProjectAccessChangedService to update project authorizations' do
- expect_next_instance_of(UserProjectAccessChangedService, [user.id]) do |service|
- expect(service).to receive(:execute)
- end
+ it 'calls AuthorizedProjectUpdate::UserRefreshFromReplicaWorker with a delay to update project authorizations' do
+ expect(AuthorizedProjectUpdate::UserRefreshFromReplicaWorker).to(
+ receive(:bulk_perform_in)
+ .with(1.hour,
+ [[user.id]],
+ batch_delay: 30.seconds, batch_size: 100)
+ )
- subject.execute(group_link)
- end
+ subject.execute(group_link)
+ end
- it 'updates project authorizations of users who had access to the project via the group share' do
- expect { subject.execute(group_link) }.to(
- change { Ability.allowed?(user, :read_project, project) }
- .from(true).to(false))
- end
+ it 'updates project authorizations of users who had access to the project via the group share', :sidekiq_inline do
+ expect { subject.execute(group_link) }.to(
+ change { Ability.allowed?(user, :read_project, project) }
+ .from(true).to(false))
end
end
diff --git a/spec/services/projects/open_issues_count_service_spec.rb b/spec/services/projects/open_issues_count_service_spec.rb
index c739fea5ecf..8710d0c0267 100644
--- a/spec/services/projects/open_issues_count_service_spec.rb
+++ b/spec/services/projects/open_issues_count_service_spec.rb
@@ -4,89 +4,102 @@ require 'spec_helper'
RSpec.describe Projects::OpenIssuesCountService, :use_clean_rails_memory_store_caching do
let(:project) { create(:project) }
+ let(:user) { create(:user) }
+ let(:banned_user) { create(:user, :banned) }
- subject { described_class.new(project) }
+ subject { described_class.new(project, user) }
it_behaves_like 'a counter caching service'
+ before do
+ create(:issue, :opened, project: project)
+ create(:issue, :opened, confidential: true, project: project)
+ create(:issue, :opened, author: banned_user, project: project)
+ create(:issue, :closed, project: project)
+
+ described_class.new(project).refresh_cache
+ end
+
describe '#count' do
- context 'when user is nil' do
- it 'does not include confidential issues in the issue count' do
- create(:issue, :opened, project: project)
- create(:issue, :opened, confidential: true, project: project)
+ shared_examples 'counts public issues, does not count hidden or confidential' do
+ it 'counts only public issues' do
+ expect(subject.count).to eq(1)
+ end
- expect(described_class.new(project).count).to eq(1)
+ it 'uses PUBLIC_COUNT_WITHOUT_HIDDEN_KEY cache key' do
+ expect(subject.cache_key).to include('project_open_public_issues_without_hidden_count')
end
end
- context 'when user is provided' do
- let(:user) { create(:user) }
+ context 'when user is nil' do
+ let(:user) { nil }
+
+ it_behaves_like 'counts public issues, does not count hidden or confidential'
+ end
+ context 'when user is provided' do
context 'when user can read confidential issues' do
before do
project.add_reporter(user)
end
- it 'returns the right count with confidential issues' do
- create(:issue, :opened, project: project)
- create(:issue, :opened, confidential: true, project: project)
-
- expect(described_class.new(project, user).count).to eq(2)
+ it 'includes confidential issues and does not include hidden issues in count' do
+ expect(subject.count).to eq(2)
end
- it 'uses total_open_issues_count cache key' do
- expect(described_class.new(project, user).cache_key_name).to eq('total_open_issues_count')
+ it 'uses TOTAL_COUNT_WITHOUT_HIDDEN_KEY cache key' do
+ expect(subject.cache_key).to include('project_open_issues_without_hidden_count')
end
end
- context 'when user cannot read confidential issues' do
+ context 'when user cannot read confidential or hidden issues' do
before do
project.add_guest(user)
end
- it 'does not include confidential issues' do
- create(:issue, :opened, project: project)
- create(:issue, :opened, confidential: true, project: project)
+ it_behaves_like 'counts public issues, does not count hidden or confidential'
+ end
+
+ context 'when user is an admin' do
+ let_it_be(:user) { create(:user, :admin) }
+
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it 'includes confidential and hidden issues in count' do
+ expect(subject.count).to eq(3)
+ end
- expect(described_class.new(project, user).count).to eq(1)
+ it 'uses TOTAL_COUNT_KEY cache key' do
+ expect(subject.cache_key).to include('project_open_issues_including_hidden_count')
+ end
end
- it 'uses public_open_issues_count cache key' do
- expect(described_class.new(project, user).cache_key_name).to eq('public_open_issues_count')
+ context 'when admin mode is disabled' do
+ it_behaves_like 'counts public issues, does not count hidden or confidential'
end
end
end
+ end
- describe '#refresh_cache' do
- before do
- create(:issue, :opened, project: project)
- create(:issue, :opened, project: project)
- create(:issue, :opened, confidential: true, project: project)
- end
-
- context 'when cache is empty' do
- it 'refreshes cache keys correctly' do
- subject.refresh_cache
-
- expect(Rails.cache.read(subject.cache_key(described_class::PUBLIC_COUNT_KEY))).to eq(2)
- expect(Rails.cache.read(subject.cache_key(described_class::TOTAL_COUNT_KEY))).to eq(3)
- end
+ describe '#refresh_cache', :aggregate_failures do
+ context 'when cache is empty' do
+ it 'refreshes cache keys correctly' do
+ expect(Rails.cache.read(described_class.new(project).cache_key(described_class::PUBLIC_COUNT_WITHOUT_HIDDEN_KEY))).to eq(1)
+ expect(Rails.cache.read(described_class.new(project).cache_key(described_class::TOTAL_COUNT_WITHOUT_HIDDEN_KEY))).to eq(2)
+ expect(Rails.cache.read(described_class.new(project).cache_key(described_class::TOTAL_COUNT_KEY))).to eq(3)
end
+ end
- context 'when cache is outdated' do
- before do
- subject.refresh_cache
- end
-
- it 'refreshes cache keys correctly' do
- create(:issue, :opened, project: project)
- create(:issue, :opened, confidential: true, project: project)
+ context 'when cache is outdated' do
+ it 'refreshes cache keys correctly' do
+ create(:issue, :opened, project: project)
+ create(:issue, :opened, confidential: true, project: project)
+ create(:issue, :opened, author: banned_user, project: project)
- subject.refresh_cache
+ described_class.new(project).refresh_cache
- expect(Rails.cache.read(subject.cache_key(described_class::PUBLIC_COUNT_KEY))).to eq(3)
- expect(Rails.cache.read(subject.cache_key(described_class::TOTAL_COUNT_KEY))).to eq(5)
- end
+ expect(Rails.cache.read(described_class.new(project).cache_key(described_class::PUBLIC_COUNT_WITHOUT_HIDDEN_KEY))).to eq(2)
+ expect(Rails.cache.read(described_class.new(project).cache_key(described_class::TOTAL_COUNT_WITHOUT_HIDDEN_KEY))).to eq(4)
+ expect(Rails.cache.read(described_class.new(project).cache_key(described_class::TOTAL_COUNT_KEY))).to eq(6)
end
end
end
diff --git a/spec/services/projects/operations/update_service_spec.rb b/spec/services/projects/operations/update_service_spec.rb
index 1d9d5f6e938..a71fafb2121 100644
--- a/spec/services/projects/operations/update_service_spec.rb
+++ b/spec/services/projects/operations/update_service_spec.rb
@@ -153,6 +153,7 @@ RSpec.describe Projects::Operations::UpdateService do
{
error_tracking_setting_attributes: {
enabled: false,
+ integrated: true,
api_host: 'http://gitlab.com/',
token: 'token',
project: {
@@ -174,6 +175,7 @@ RSpec.describe Projects::Operations::UpdateService do
project.reload
expect(project.error_tracking_setting).not_to be_enabled
+ expect(project.error_tracking_setting.integrated).to be_truthy
expect(project.error_tracking_setting.api_url).to eq(
'http://gitlab.com/api/0/projects/org/project/'
)
@@ -206,6 +208,7 @@ RSpec.describe Projects::Operations::UpdateService do
{
error_tracking_setting_attributes: {
enabled: true,
+ integrated: true,
api_host: 'http://gitlab.com/',
token: 'token',
project: {
@@ -222,6 +225,7 @@ RSpec.describe Projects::Operations::UpdateService do
expect(result[:status]).to eq(:success)
expect(project.error_tracking_setting).to be_enabled
+ expect(project.error_tracking_setting.integrated).to be_truthy
expect(project.error_tracking_setting.api_url).to eq(
'http://gitlab.com/api/0/projects/org/project/'
)
diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb
index b71677a5e8f..d96573e26af 100644
--- a/spec/services/projects/transfer_service_spec.rb
+++ b/spec/services/projects/transfer_service_spec.rb
@@ -292,10 +292,37 @@ RSpec.describe Projects::TransferService do
end
end
- context 'target namespace allows developers to create projects' do
+ context 'target namespace matches current namespace' do
+ let(:group) { user.namespace }
+
+ it 'does not allow project transfer' do
+ transfer_result = execute_transfer
+
+ expect(transfer_result).to eq false
+ expect(project.namespace).to eq(user.namespace)
+ expect(project.errors[:new_namespace]).to include('Project is already in this namespace.')
+ end
+ end
+
+ context 'when user does not own the project' do
+ let(:project) { create(:project, :repository, :legacy_storage) }
+
+ before do
+ project.add_developer(user)
+ end
+
+ it 'does not allow project transfer to the target namespace' do
+ transfer_result = execute_transfer
+
+ expect(transfer_result).to eq false
+ expect(project.errors[:new_namespace]).to include("You don't have permission to transfer this project.")
+ end
+ end
+
+ context 'when user can create projects in the target namespace' do
let(:group) { create(:group, project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS) }
- context 'the user is a member of the target namespace with developer permissions' do
+ context 'but has only developer permissions in the target namespace' do
before do
group.add_developer(user)
end
@@ -305,7 +332,7 @@ RSpec.describe Projects::TransferService do
expect(transfer_result).to eq false
expect(project.namespace).to eq(user.namespace)
- expect(project.errors[:new_namespace]).to include('Transfer failed, please contact an admin.')
+ expect(project.errors[:new_namespace]).to include("You don't have permission to transfer projects into that namespace.")
end
end
end
diff --git a/spec/services/projects/update_pages_service_spec.rb b/spec/services/projects/update_pages_service_spec.rb
index 0f21736eda0..6d0b75e0c95 100644
--- a/spec/services/projects/update_pages_service_spec.rb
+++ b/spec/services/projects/update_pages_service_spec.rb
@@ -18,17 +18,6 @@ RSpec.describe Projects::UpdatePagesService do
subject { described_class.new(project, build) }
- before do
- stub_feature_flags(skip_pages_deploy_to_legacy_storage: false)
- project.legacy_remove_pages
- end
-
- context '::TMP_EXTRACT_PATH' do
- subject { described_class::TMP_EXTRACT_PATH }
-
- it { is_expected.not_to match(Gitlab::PathRegex.namespace_format_regex) }
- end
-
context 'for new artifacts' do
context "for a valid job" do
let!(:artifacts_archive) { create(:ci_job_artifact, :correct_checksum, file: file, job: build) }
@@ -52,36 +41,6 @@ RSpec.describe Projects::UpdatePagesService do
expect(project.pages_metadatum).to be_deployed
expect(project.pages_metadatum.artifacts_archive).to eq(artifacts_archive)
expect(project.pages_deployed?).to be_truthy
-
- # Check that all expected files are extracted
- %w[index.html zero .hidden/file].each do |filename|
- expect(File.exist?(File.join(project.pages_path, 'public', filename))).to be_truthy
- end
- end
-
- it 'creates a temporary directory with the project and build ID' do
- expect(Dir).to receive(:mktmpdir).with("project-#{project.id}-build-#{build.id}-", anything).and_call_original
-
- subject.execute
- end
-
- it "doesn't deploy to legacy storage if it's disabled" do
- allow(Settings.pages.local_store).to receive(:enabled).and_return(false)
-
- expect(execute).to eq(:success)
- expect(project.pages_deployed?).to be_truthy
-
- expect(File.exist?(File.join(project.pages_path, 'public', 'index.html'))).to eq(false)
- end
-
- it "doesn't deploy to legacy storage if skip_pages_deploy_to_legacy_storage is enabled" do
- allow(Settings.pages.local_store).to receive(:enabled).and_return(true)
- stub_feature_flags(skip_pages_deploy_to_legacy_storage: true)
-
- expect(execute).to eq(:success)
- expect(project.pages_deployed?).to be_truthy
-
- expect(File.exist?(File.join(project.pages_path, 'public', 'index.html'))).to eq(false)
end
it 'creates pages_deployment and saves it in the metadata' do
@@ -99,16 +58,6 @@ RSpec.describe Projects::UpdatePagesService do
expect(deployment.ci_build_id).to eq(build.id)
end
- it 'fails if another deployment is in progress' do
- subject.try_obtain_lease do
- expect do
- execute
- end.to raise_error("Failed to deploy pages - other deployment is in progress")
-
- expect(GenericCommitStatus.last.description).to eq("Failed to deploy pages - other deployment is in progress")
- end
- end
-
it 'does not fail if pages_metadata is absent' do
project.pages_metadatum.destroy!
project.reload
@@ -156,47 +105,10 @@ RSpec.describe Projects::UpdatePagesService do
expect(GenericCommitStatus.last.description).to eq("pages site contains 3 file entries, while limit is set to 2")
end
- it 'removes pages after destroy' do
- expect(PagesWorker).to receive(:perform_in)
- expect(project.pages_deployed?).to be_falsey
- expect(Dir.exist?(File.join(project.pages_path))).to be_falsey
-
- expect(execute).to eq(:success)
-
- expect(project.pages_metadatum).to be_deployed
- expect(project.pages_deployed?).to be_truthy
- expect(Dir.exist?(File.join(project.pages_path))).to be_truthy
-
- project.destroy!
-
- expect(Dir.exist?(File.join(project.pages_path))).to be_falsey
- expect(ProjectPagesMetadatum.find_by_project_id(project)).to be_nil
- end
-
- context 'when using empty file' do
- let(:file) { empty_file }
-
- it 'fails to extract' do
- expect { execute }
- .to raise_error(Projects::UpdatePagesService::FailedToExtractError)
- end
- end
-
- context 'when using pages with non-writeable public' do
- let(:file) { fixture_file_upload("spec/fixtures/pages_non_writeable.zip") }
-
- context 'when using RubyZip' do
- it 'succeeds to extract' do
- expect(execute).to eq(:success)
- expect(project.pages_metadatum).to be_deployed
- end
- end
- end
-
context 'when timeout happens by DNS error' do
before do
allow_next_instance_of(described_class) do |instance|
- allow(instance).to receive(:extract_zip_archive!).and_raise(SocketError)
+ allow(instance).to receive(:create_pages_deployment).and_raise(SocketError)
end
end
@@ -209,24 +121,6 @@ RSpec.describe Projects::UpdatePagesService do
end
end
- context 'when failed to extract zip artifacts' do
- before do
- expect_next_instance_of(described_class) do |instance|
- expect(instance).to receive(:extract_zip_archive!)
- .and_raise(Projects::UpdatePagesService::FailedToExtractError)
- end
- end
-
- it 'raises an error' do
- expect { execute }
- .to raise_error(Projects::UpdatePagesService::FailedToExtractError)
-
- build.reload
- expect(deploy_status).to be_failed
- expect(project.pages_metadatum).not_to be_deployed
- end
- end
-
context 'when missing artifacts metadata' do
before do
expect(build).to receive(:artifacts_metadata?).and_return(false)
@@ -338,12 +232,6 @@ RSpec.describe Projects::UpdatePagesService do
end
end
- it 'fails to remove project pages when no pages is deployed' do
- expect(PagesWorker).not_to receive(:perform_in)
- expect(project.pages_deployed?).to be_falsey
- project.destroy!
- end
-
it 'fails if no artifacts' do
expect(execute).not_to eq(:success)
end
@@ -384,38 +272,6 @@ RSpec.describe Projects::UpdatePagesService do
end
end
- context 'when file size is spoofed' do
- let(:metadata) { spy('metadata') }
-
- include_context 'pages zip with spoofed size'
-
- before do
- file = fixture_file_upload(fake_zip_path, 'pages.zip')
- metafile = fixture_file_upload('spec/fixtures/pages.zip.meta')
-
- create(:ci_job_artifact, :archive, file: file, job: build)
- create(:ci_job_artifact, :metadata, file: metafile, job: build)
-
- allow(build).to receive(:artifacts_metadata_entry).with('public/', recursive: true)
- .and_return(metadata)
- allow(metadata).to receive(:total_size).and_return(100)
-
- # to pass entries count check
- root_metadata = double('root metadata')
- allow(build).to receive(:artifacts_metadata_entry).with('', recursive: true)
- .and_return(root_metadata)
- allow(root_metadata).to receive_message_chain(:entries, :count).and_return(10)
- end
-
- it 'raises an error' do
- expect do
- subject.execute
- end.to raise_error(Projects::UpdatePagesService::FailedToExtractError,
- 'Entry public/index.html should be 1B but is larger when inflated')
- expect(deploy_status).to be_script_failure
- end
- end
-
context 'when retrying the job' do
let!(:older_deploy_job) do
create(:generic_commit_status, :failed, pipeline: pipeline,
@@ -435,18 +291,6 @@ RSpec.describe Projects::UpdatePagesService do
expect(older_deploy_job.reload).to be_retried
end
-
- context 'when FF ci_fix_commit_status_retried is disabled' do
- before do
- stub_feature_flags(ci_fix_commit_status_retried: false)
- end
-
- it 'does not mark older pages:deploy jobs retried' do
- expect(execute).to eq(:success)
-
- expect(older_deploy_job.reload).not_to be_retried
- end
- end
end
private
diff --git a/spec/services/projects/update_service_spec.rb b/spec/services/projects/update_service_spec.rb
index c74a8295d0a..115f3098185 100644
--- a/spec/services/projects/update_service_spec.rb
+++ b/spec/services/projects/update_service_spec.rb
@@ -441,6 +441,30 @@ RSpec.describe Projects::UpdateService do
end
end
+ context 'when updating #shared_runners', :https_pages_enabled do
+ let!(:pending_build) { create(:ci_pending_build, project: project, instance_runners_enabled: true) }
+
+ subject(:call_service) do
+ update_project(project, admin, shared_runners_enabled: shared_runners_enabled)
+ end
+
+ context 'when shared runners is toggled' do
+ let(:shared_runners_enabled) { false }
+
+ it 'updates ci pending builds' do
+ expect { call_service }.to change { pending_build.reload.instance_runners_enabled }.to(false)
+ end
+ end
+
+ context 'when shared runners is not toggled' do
+ let(:shared_runners_enabled) { true }
+
+ it 'updates ci pending builds' do
+ expect { call_service }.to not_change { pending_build.reload.instance_runners_enabled }
+ end
+ end
+ end
+
context 'with external authorization enabled' do
before do
enable_external_authorization_service_check
diff --git a/spec/services/quick_actions/interpret_service_spec.rb b/spec/services/quick_actions/interpret_service_spec.rb
index a1b726071d6..02997096021 100644
--- a/spec/services/quick_actions/interpret_service_spec.rb
+++ b/spec/services/quick_actions/interpret_service_spec.rb
@@ -624,6 +624,18 @@ RSpec.describe QuickActions::InterpretService do
end
end
+ shared_examples 'approve command unavailable' do
+ it 'is not part of the available commands' do
+ expect(service.available_commands(issuable)).not_to include(a_hash_including(name: :approve))
+ end
+ end
+
+ shared_examples 'unapprove command unavailable' do
+ it 'is not part of the available commands' do
+ expect(service.available_commands(issuable)).not_to include(a_hash_including(name: :unapprove))
+ end
+ end
+
shared_examples 'shrug command' do
it 'appends ¯\_(ツ)_/¯ to the comment' do
new_content, _, _ = service.execute(content, issuable)
@@ -2135,6 +2147,66 @@ RSpec.describe QuickActions::InterpretService do
end
end
end
+
+ context 'approve command' do
+ let(:merge_request) { create(:merge_request, source_project: project) }
+ let(:content) { '/approve' }
+
+ it 'approves the current merge request' do
+ service.execute(content, merge_request)
+
+ expect(merge_request.approved_by_users).to eq([developer])
+ end
+
+ context "when the user can't approve" do
+ before do
+ project.team.truncate
+ project.add_guest(developer)
+ end
+
+ it 'does not approve the MR' do
+ service.execute(content, merge_request)
+
+ expect(merge_request.approved_by_users).to be_empty
+ end
+ end
+
+ it_behaves_like 'approve command unavailable' do
+ let(:issuable) { issue }
+ end
+ end
+
+ context 'unapprove command' do
+ let!(:merge_request) { create(:merge_request, source_project: project) }
+ let(:content) { '/unapprove' }
+
+ before do
+ service.execute('/approve', merge_request)
+ end
+
+ it 'unapproves the current merge request' do
+ service.execute(content, merge_request)
+
+ expect(merge_request.approved_by_users).to be_empty
+ end
+
+ context "when the user can't unapprove" do
+ before do
+ project.team.truncate
+ project.add_guest(developer)
+ end
+
+ it 'does not unapprove the MR' do
+ service.execute(content, merge_request)
+
+ expect(merge_request.approved_by_users).to eq([developer])
+ end
+
+ it_behaves_like 'unapprove command unavailable' do
+ let(:issuable) { issue }
+ end
+ end
+ end
end
describe '#explain' do
diff --git a/spec/services/repositories/changelog_service_spec.rb b/spec/services/repositories/changelog_service_spec.rb
index 02d60f076ca..b547ae17317 100644
--- a/spec/services/repositories/changelog_service_spec.rb
+++ b/spec/services/repositories/changelog_service_spec.rb
@@ -76,7 +76,7 @@ RSpec.describe Repositories::ChangelogService do
recorder = ActiveRecord::QueryRecorder.new { service.execute }
changelog = project.repository.blob_at('master', 'CHANGELOG.md')&.data
- expect(recorder.count).to eq(11)
+ expect(recorder.count).to eq(9)
expect(changelog).to include('Title 1', 'Title 2')
end
diff --git a/spec/services/service_ping/submit_service_ping_service_spec.rb b/spec/services/service_ping/submit_service_ping_service_spec.rb
index 05df4e49014..c2fe565938a 100644
--- a/spec/services/service_ping/submit_service_ping_service_spec.rb
+++ b/spec/services/service_ping/submit_service_ping_service_spec.rb
@@ -300,8 +300,32 @@ RSpec.describe ServicePing::SubmitService do
end
end
- def stub_response(body:, status: 201)
- stub_full_request(subject.send(:url), method: :post)
+ describe '#url' do
+ let(:url) { subject.url.to_s }
+
+ context 'when Rails.env is production' do
+ before do
+ stub_rails_env('production')
+ end
+
+ it 'points to the production Version app' do
+ expect(url).to eq("#{described_class::PRODUCTION_BASE_URL}/#{described_class::USAGE_DATA_PATH}")
+ end
+ end
+
+ context 'when Rails.env is not production' do
+ before do
+ stub_rails_env('development')
+ end
+
+ it 'points to the staging Version app' do
+ expect(url).to eq("#{described_class::STAGING_BASE_URL}/#{described_class::USAGE_DATA_PATH}")
+ end
+ end
+ end
+
+ def stub_response(url: subject.url, body:, status: 201)
+ stub_full_request(url, method: :post)
.to_return(
headers: { 'Content-Type' => 'application/json' },
body: body.to_json,
diff --git a/spec/services/suggestions/apply_service_spec.rb b/spec/services/suggestions/apply_service_spec.rb
index 9cf794cde7e..dc330a5546f 100644
--- a/spec/services/suggestions/apply_service_spec.rb
+++ b/spec/services/suggestions/apply_service_spec.rb
@@ -70,7 +70,7 @@ RSpec.describe Suggestions::ApplyService do
author = suggestions.first.note.author
expect(user.commit_email).not_to eq(user.email)
- expect(commit.author_email).to eq(author.commit_email)
+ expect(commit.author_email).to eq(author.commit_email_or_default)
expect(commit.committer_email).to eq(user.commit_email)
expect(commit.author_name).to eq(author.name)
expect(commit.committer_name).to eq(user.name)
@@ -79,7 +79,7 @@ RSpec.describe Suggestions::ApplyService do
it 'tracks apply suggestion event' do
expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter)
.to receive(:track_apply_suggestion_action)
- .with(user: user)
+ .with(user: user, suggestions: suggestions)
apply(suggestions)
end
@@ -333,9 +333,9 @@ RSpec.describe Suggestions::ApplyService do
end
it 'created commit by same author and committer' do
- expect(user.commit_email).to eq(author.commit_email)
+ expect(user.commit_email).to eq(author.commit_email_or_default)
expect(author).to eq(user)
- expect(commit.author_email).to eq(author.commit_email)
+ expect(commit.author_email).to eq(author.commit_email_or_default)
expect(commit.committer_email).to eq(user.commit_email)
expect(commit.author_name).to eq(author.name)
expect(commit.committer_name).to eq(user.name)
@@ -350,7 +350,7 @@ RSpec.describe Suggestions::ApplyService do
it 'created commit has authors info and commiters info' do
expect(user.commit_email).not_to eq(user.email)
expect(author).not_to eq(user)
- expect(commit.author_email).to eq(author.commit_email)
+ expect(commit.author_email).to eq(author.commit_email_or_default)
expect(commit.committer_email).to eq(user.commit_email)
expect(commit.author_name).to eq(author.name)
expect(commit.committer_name).to eq(user.name)
@@ -359,7 +359,7 @@ RSpec.describe Suggestions::ApplyService do
end
context 'multiple suggestions' do
- let(:author_emails) { suggestions.map {|s| s.note.author.commit_email } }
+ let(:author_emails) { suggestions.map {|s| s.note.author.commit_email_or_default } }
let(:first_author) { suggestion.note.author }
let(:commit) { project.repository.commit }
@@ -369,8 +369,8 @@ RSpec.describe Suggestions::ApplyService do
end
it 'uses first authors information' do
- expect(author_emails).to include(first_author.commit_email).exactly(3)
- expect(commit.author_email).to eq(first_author.commit_email)
+ expect(author_emails).to include(first_author.commit_email_or_default).exactly(3)
+ expect(commit.author_email).to eq(first_author.commit_email_or_default)
end
end
diff --git a/spec/services/suggestions/create_service_spec.rb b/spec/services/suggestions/create_service_spec.rb
index 5148d6756fc..a4e62431128 100644
--- a/spec/services/suggestions/create_service_spec.rb
+++ b/spec/services/suggestions/create_service_spec.rb
@@ -159,7 +159,7 @@ RSpec.describe Suggestions::CreateService do
it 'tracks add suggestion event' do
expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter)
.to receive(:track_add_suggestion_action)
- .with(user: note.author)
+ .with(note: note)
subject.execute
end
diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb
index 5aff5149dcf..1a421999ffb 100644
--- a/spec/services/system_note_service_spec.rb
+++ b/spec/services/system_note_service_spec.rb
@@ -793,4 +793,16 @@ RSpec.describe SystemNoteService do
described_class.log_resolving_alert(alert, monitoring_tool)
end
end
+
+ describe '.change_issue_type' do
+ let(:incident) { build(:incident) }
+
+ it 'calls IssuableService' do
+ expect_next_instance_of(::SystemNotes::IssuablesService) do |service|
+ expect(service).to receive(:change_issue_type)
+ end
+
+ described_class.change_issue_type(incident, author)
+ end
+ end
end
diff --git a/spec/services/system_notes/issuables_service_spec.rb b/spec/services/system_notes/issuables_service_spec.rb
index 1ea3c241d27..71a28a89cd8 100644
--- a/spec/services/system_notes/issuables_service_spec.rb
+++ b/spec/services/system_notes/issuables_service_spec.rb
@@ -773,4 +773,16 @@ RSpec.describe ::SystemNotes::IssuablesService do
expect(event.state).to eq('closed')
end
end
+
+ describe '#change_issue_type' do
+ let(:noteable) { create(:incident, project: project) }
+
+ subject { service.change_issue_type }
+
+ it_behaves_like 'a system note' do
+ let(:action) { 'issue_type' }
+ end
+
+ it { expect(subject.note).to eq "changed issue type to incident" }
+ end
end
diff --git a/spec/services/todos/destroy/design_service_spec.rb b/spec/services/todos/destroy/design_service_spec.rb
new file mode 100644
index 00000000000..61a6718dc9d
--- /dev/null
+++ b/spec/services/todos/destroy/design_service_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Todos::Destroy::DesignService do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:user_2) { create(:user) }
+ let_it_be(:design) { create(:design) }
+ let_it_be(:design_2) { create(:design) }
+ let_it_be(:design_3) { create(:design) }
+
+ let_it_be(:create_action) { create(:design_action, design: design)}
+ let_it_be(:create_action_2) { create(:design_action, design: design_2)}
+
+ describe '#execute' do
+ before do
+ create(:todo, user: user, target: design)
+ create(:todo, user: user_2, target: design)
+ create(:todo, user: user, target: design_2)
+ create(:todo, user: user, target: design_3)
+ end
+
+ subject { described_class.new([design.id, design_2.id, design_3.id]).execute }
+
+ context 'when the design has been archived' do
+ let_it_be(:archive_action) { create(:design_action, design: design, event: :deletion)}
+ let_it_be(:archive_action_2) { create(:design_action, design: design_3, event: :deletion)}
+
+ it 'removes todos for that design' do
+ expect { subject }.to change { Todo.count }.from(4).to(1)
+ end
+ end
+
+ context 'when no design has been archived' do
+ it 'does not remove any todos' do
+ expect { subject }.not_to change { Todo.count }.from(4)
+ end
+ end
+ end
+end
diff --git a/spec/services/users/ban_service_spec.rb b/spec/services/users/ban_service_spec.rb
index 6f49ee08782..79f3cbeb46d 100644
--- a/spec/services/users/ban_service_spec.rb
+++ b/spec/services/users/ban_service_spec.rb
@@ -50,7 +50,7 @@ RSpec.describe Users::BanService do
response = ban_user
expect(response[:status]).to eq(:error)
- expect(response[:message]).to match(/State cannot transition/)
+ expect(response[:message]).to match('You cannot ban blocked users.')
end
it_behaves_like 'does not modify the BannedUser record or user state'
diff --git a/spec/services/users/dismiss_group_callout_service_spec.rb b/spec/services/users/dismiss_group_callout_service_spec.rb
new file mode 100644
index 00000000000..d74602a7606
--- /dev/null
+++ b/spec/services/users/dismiss_group_callout_service_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Users::DismissGroupCalloutService do
+ describe '#execute' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+
+ let(:params) { { feature_name: feature_name, group_id: group.id } }
+ let(:feature_name) { Users::GroupCallout.feature_names.each_key.first }
+
+ subject(:execute) do
+ described_class.new(
+ container: nil, current_user: user, params: params
+ ).execute
+ end
+
+ it_behaves_like 'dismissing user callout', Users::GroupCallout
+
+ it 'sets the group_id' do
+ expect(execute.group_id).to eq(group.id)
+ end
+ end
+end
diff --git a/spec/services/users/dismiss_user_callout_service_spec.rb b/spec/services/users/dismiss_user_callout_service_spec.rb
index 22f84a939f7..6bf9961eb74 100644
--- a/spec/services/users/dismiss_user_callout_service_spec.rb
+++ b/spec/services/users/dismiss_user_callout_service_spec.rb
@@ -3,25 +3,18 @@
require 'spec_helper'
RSpec.describe Users::DismissUserCalloutService do
- let(:user) { create(:user) }
-
- let(:service) do
- described_class.new(
- container: nil, current_user: user, params: { feature_name: UserCallout.feature_names.each_key.first }
- )
- end
-
describe '#execute' do
- subject(:execute) { service.execute }
+ let_it_be(:user) { create(:user) }
- it 'returns a user callout' do
- expect(execute).to be_an_instance_of(UserCallout)
- end
+ let(:params) { { feature_name: feature_name } }
+ let(:feature_name) { UserCallout.feature_names.each_key.first }
- it 'sets the dismisse_at attribute to current time' do
- freeze_time do
- expect(execute).to have_attributes(dismissed_at: Time.current)
- end
+ subject(:execute) do
+ described_class.new(
+ container: nil, current_user: user, params: params
+ ).execute
end
+
+ it_behaves_like 'dismissing user callout', UserCallout
end
end
diff --git a/spec/services/users/migrate_to_ghost_user_service_spec.rb b/spec/services/users/migrate_to_ghost_user_service_spec.rb
index c9c8f9a74d3..c36889f20ec 100644
--- a/spec/services/users/migrate_to_ghost_user_service_spec.rb
+++ b/spec/services/users/migrate_to_ghost_user_service_spec.rb
@@ -92,23 +92,5 @@ RSpec.describe Users::MigrateToGhostUserService do
let(:created_record) { create(:review, author: user) }
end
end
-
- context "when record migration fails with a rollback exception" do
- before do
- expect_any_instance_of(ActiveRecord::Associations::CollectionProxy)
- .to receive(:update_all).and_raise(ActiveRecord::Rollback)
- end
-
- context "for records that were already migrated" do
- let!(:issue) { create(:issue, project: project, author: user) }
- let!(:merge_request) { create(:merge_request, source_project: project, author: user, target_branch: "first") }
-
- it "reverses the migration" do
- service.execute
-
- expect(issue.reload.author).to eq(user)
- end
- end
- end
end
end
diff --git a/spec/services/users/reject_service_spec.rb b/spec/services/users/reject_service_spec.rb
index b0094a7c47e..5a243e876ac 100644
--- a/spec/services/users/reject_service_spec.rb
+++ b/spec/services/users/reject_service_spec.rb
@@ -27,7 +27,7 @@ RSpec.describe Users::RejectService do
it 'returns error result' do
expect(subject[:status]).to eq(:error)
expect(subject[:message])
- .to match(/This user does not have a pending request/)
+ .to match(/User does not have a pending request/)
end
end
end
@@ -44,7 +44,7 @@ RSpec.describe Users::RejectService do
it 'emails the user on rejection' do
expect_next_instance_of(NotificationService) do |notification|
- allow(notification).to receive(:user_admin_rejection).with(user.name, user.notification_email)
+ allow(notification).to receive(:user_admin_rejection).with(user.name, user.notification_email_or_default)
end
subject
diff --git a/spec/services/users/unban_service_spec.rb b/spec/services/users/unban_service_spec.rb
index b2b3140ccb3..d536baafdcc 100644
--- a/spec/services/users/unban_service_spec.rb
+++ b/spec/services/users/unban_service_spec.rb
@@ -50,7 +50,7 @@ RSpec.describe Users::UnbanService do
response = unban_user
expect(response[:status]).to eq(:error)
- expect(response[:message]).to match(/State cannot transition/)
+ expect(response[:message]).to match('You cannot unban active users.')
end
it_behaves_like 'does not modify the BannedUser record or user state'
diff --git a/spec/services/wiki_pages/event_create_service_spec.rb b/spec/services/wiki_pages/event_create_service_spec.rb
index 6bc6a678189..8476f872e98 100644
--- a/spec/services/wiki_pages/event_create_service_spec.rb
+++ b/spec/services/wiki_pages/event_create_service_spec.rb
@@ -34,10 +34,6 @@ RSpec.describe WikiPages::EventCreateService do
it 'does not create an event' do
expect { response }.not_to change(Event, :count)
end
-
- it 'does not create a metadata record' do
- expect { response }.not_to change(WikiPage::Meta, :count)
- end
end
it 'returns a successful response' do
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index b95b7fad5a0..aa791d1d2e7 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -160,11 +160,11 @@ RSpec.configure do |config|
config.include GitlabRoutingHelper
config.include StubExperiments
config.include StubGitlabCalls
- config.include StubGitlabData
config.include NextFoundInstanceOf
config.include NextInstanceOf
config.include TestEnv
config.include FileReadHelpers
+ config.include Database::MultipleDatabases
config.include Devise::Test::ControllerHelpers, type: :controller
config.include Devise::Test::ControllerHelpers, type: :view
config.include Devise::Test::IntegrationHelpers, type: :feature
@@ -221,6 +221,8 @@ RSpec.configure do |config|
# Enable all features by default for testing
# Reset any changes in after hook.
stub_all_feature_flags
+
+ TestEnv.seed_db
end
config.after(:all) do
@@ -260,6 +262,9 @@ RSpec.configure do |config|
# tests, until we introduce it in user settings
stub_feature_flags(forti_token_cloud: false)
+ # Disable for now whilst we add more states
+ stub_feature_flags(restructured_mr_widget: false)
+
# These feature flag are by default disabled and used in disaster recovery mode
stub_feature_flags(ci_queueing_disaster_recovery_disable_fair_scheduling: false)
stub_feature_flags(ci_queueing_disaster_recovery_disable_quota: false)
@@ -301,6 +306,15 @@ RSpec.configure do |config|
# For more information check https://gitlab.com/gitlab-com/gl-infra/production/-/issues/4321
stub_feature_flags(block_issue_repositioning: false)
+ # These are ops feature flags that are disabled by default
+ stub_feature_flags(disable_anonymous_search: false)
+ stub_feature_flags(disable_anonymous_project_search: false)
+
+ # Disable the refactored top nav search until there is functionality
+ # Can be removed once all existing functionality has been replicated
+ # For more information check https://gitlab.com/gitlab-org/gitlab/-/issues/339348
+ stub_feature_flags(new_header_search: false)
+
allow(Gitlab::GitalyClient).to receive(:can_use_disk?).and_return(enable_rugged)
else
unstub_all_feature_flags
diff --git a/spec/support/database/ci_tables.rb b/spec/support/database/ci_tables.rb
deleted file mode 100644
index 99fc7ac2501..00000000000
--- a/spec/support/database/ci_tables.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-# This module stores the CI-related database tables which are
-# going to be moved to a separate database.
-module Database
- module CiTables
- def self.include?(name)
- ci_tables.include?(name)
- end
-
- def self.ci_tables
- @@ci_tables ||= Set.new.tap do |tables| # rubocop:disable Style/ClassVars
- tables.merge(Ci::ApplicationRecord.descendants.map(&:table_name).compact)
-
- # It was decided that taggings/tags are best placed with CI
- # https://gitlab.com/gitlab-org/gitlab/-/issues/333413
- tables.add('taggings')
- tables.add('tags')
- end
- end
- end
-end
diff --git a/spec/support/database/cross-join-allowlist.yml b/spec/support/database/cross-join-allowlist.yml
new file mode 100644
index 00000000000..2b4cfc6773a
--- /dev/null
+++ b/spec/support/database/cross-join-allowlist.yml
@@ -0,0 +1,196 @@
+- "./ee/spec/controllers/operations_controller_spec.rb"
+- "./ee/spec/controllers/projects/issues_controller_spec.rb"
+- "./ee/spec/controllers/projects/security/vulnerabilities_controller_spec.rb"
+- "./ee/spec/features/ci/ci_minutes_spec.rb"
+- "./ee/spec/features/merge_request/user_merges_immediately_spec.rb"
+- "./ee/spec/features/merge_request/user_sees_merge_widget_spec.rb"
+- "./ee/spec/features/merge_trains/two_merge_requests_on_train_spec.rb"
+- "./ee/spec/features/merge_trains/user_adds_merge_request_to_merge_train_spec.rb"
+- "./ee/spec/features/merge_trains/user_adds_to_merge_train_when_pipeline_succeeds_spec.rb"
+- "./ee/spec/features/projects/pipelines/pipeline_spec.rb"
+- "./ee/spec/features/projects/settings/auto_rollback_spec.rb"
+- "./ee/spec/features/projects/settings/pipeline_subscriptions_spec.rb"
+- "./ee/spec/features/projects/settings/protected_environments_spec.rb"
+- "./ee/spec/finders/ee/namespaces/projects_finder_spec.rb"
+- "./ee/spec/finders/group_projects_finder_spec.rb"
+- "./ee/spec/finders/security/findings_finder_spec.rb"
+- "./ee/spec/graphql/ee/resolvers/namespace_projects_resolver_spec.rb"
+- "./ee/spec/lib/analytics/devops_adoption/snapshot_calculator_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/migrate_approver_to_approval_rules_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/migrate_security_scans_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/populate_latest_pipeline_ids_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/populate_resolved_on_default_branch_column_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/populate_uuids_for_security_findings_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/populate_vulnerability_feedback_pipeline_id_spec.rb"
+- "./ee/spec/lib/ee/gitlab/usage_data_spec.rb"
+- "./ee/spec/migrations/schedule_populate_resolved_on_default_branch_column_spec.rb"
+- "./ee/spec/models/ci/build_spec.rb"
+- "./ee/spec/models/ci/minutes/project_monthly_usage_spec.rb"
+- "./ee/spec/models/ci/pipeline_spec.rb"
+- "./ee/spec/models/ee/vulnerability_spec.rb"
+- "./ee/spec/models/merge_request_spec.rb"
+- "./ee/spec/models/project_spec.rb"
+- "./ee/spec/models/security/finding_spec.rb"
+- "./ee/spec/models/security/scan_spec.rb"
+- "./ee/spec/presenters/ci/pipeline_presenter_spec.rb"
+- "./ee/spec/requests/api/ci/minutes_spec.rb"
+- "./ee/spec/requests/api/graphql/ci/minutes/usage_spec.rb"
+- "./ee/spec/requests/api/graphql/mutations/environments/canary_ingress/update_spec.rb"
+- "./ee/spec/requests/api/graphql/mutations/vulnerabilities/create_external_issue_link_spec.rb"
+- "./ee/spec/requests/api/graphql/project/pipeline/security_report_summary_spec.rb"
+- "./ee/spec/requests/api/graphql/vulnerabilities/location_spec.rb"
+- "./ee/spec/requests/api/groups_spec.rb"
+- "./ee/spec/requests/api/namespaces_spec.rb"
+- "./ee/spec/requests/api/vulnerability_findings_spec.rb"
+- "./ee/spec/serializers/dashboard_environment_entity_spec.rb"
+- "./ee/spec/serializers/dashboard_environments_serializer_spec.rb"
+- "./ee/spec/services/auto_merge/add_to_merge_train_when_pipeline_succeeds_service_spec.rb"
+- "./ee/spec/services/ci/create_pipeline_service/runnable_builds_spec.rb"
+- "./ee/spec/services/ci/minutes/additional_packs/change_namespace_service_spec.rb"
+- "./ee/spec/services/ci/minutes/additional_packs/create_service_spec.rb"
+- "./ee/spec/services/ci/minutes/refresh_cached_data_service_spec.rb"
+- "./ee/spec/services/ci/process_pipeline_service_spec.rb"
+- "./ee/spec/services/ci/trigger_downstream_subscription_service_spec.rb"
+- "./ee/spec/services/clear_namespace_shared_runners_minutes_service_spec.rb"
+- "./ee/spec/services/deployments/auto_rollback_service_spec.rb"
+- "./ee/spec/services/ee/ci/job_artifacts/destroy_all_expired_service_spec.rb"
+- "./ee/spec/services/ee/ci/job_artifacts/destroy_batch_service_spec.rb"
+- "./ee/spec/services/ee/issues/build_from_vulnerability_service_spec.rb"
+- "./ee/spec/services/ee/merge_requests/create_pipeline_service_spec.rb"
+- "./ee/spec/services/ee/merge_requests/refresh_service_spec.rb"
+- "./ee/spec/services/security/report_summary_service_spec.rb"
+- "./ee/spec/services/security/vulnerability_counting_service_spec.rb"
+- "./ee/spec/workers/scan_security_report_secrets_worker_spec.rb"
+- "./ee/spec/workers/security/store_scans_worker_spec.rb"
+- "./spec/controllers/admin/runners_controller_spec.rb"
+- "./spec/controllers/groups/runners_controller_spec.rb"
+- "./spec/controllers/groups/settings/ci_cd_controller_spec.rb"
+- "./spec/controllers/projects/logs_controller_spec.rb"
+- "./spec/controllers/projects/merge_requests_controller_spec.rb"
+- "./spec/controllers/projects/runners_controller_spec.rb"
+- "./spec/controllers/projects/serverless/functions_controller_spec.rb"
+- "./spec/controllers/projects/settings/ci_cd_controller_spec.rb"
+- "./spec/features/admin/admin_runners_spec.rb"
+- "./spec/features/groups/settings/ci_cd_spec.rb"
+- "./spec/features/ide/user_opens_merge_request_spec.rb"
+- "./spec/features/merge_request/user_merges_immediately_spec.rb"
+- "./spec/features/merge_request/user_merges_only_if_pipeline_succeeds_spec.rb"
+- "./spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb"
+- "./spec/features/merge_request/user_resolves_wip_mr_spec.rb"
+- "./spec/features/merge_request/user_sees_deployment_widget_spec.rb"
+- "./spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb"
+- "./spec/features/merge_request/user_sees_merge_widget_spec.rb"
+- "./spec/features/merge_request/user_sees_mini_pipeline_graph_spec.rb"
+- "./spec/features/merge_request/user_sees_pipelines_from_forked_project_spec.rb"
+- "./spec/features/merge_request/user_sees_pipelines_spec.rb"
+- "./spec/features/project_group_variables_spec.rb"
+- "./spec/features/project_variables_spec.rb"
+- "./spec/features/projects/badges/list_spec.rb"
+- "./spec/features/projects/environments_pod_logs_spec.rb"
+- "./spec/features/projects/infrastructure_registry_spec.rb"
+- "./spec/features/projects/jobs_spec.rb"
+- "./spec/features/projects/package_files_spec.rb"
+- "./spec/features/projects/pipelines/pipeline_spec.rb"
+- "./spec/features/projects/pipelines/pipelines_spec.rb"
+- "./spec/features/projects/serverless/functions_spec.rb"
+- "./spec/features/projects/settings/pipelines_settings_spec.rb"
+- "./spec/features/runners_spec.rb"
+- "./spec/features/security/project/internal_access_spec.rb"
+- "./spec/features/security/project/private_access_spec.rb"
+- "./spec/features/security/project/public_access_spec.rb"
+- "./spec/features/triggers_spec.rb"
+- "./spec/finders/ci/pipelines_finder_spec.rb"
+- "./spec/finders/ci/pipelines_for_merge_request_finder_spec.rb"
+- "./spec/finders/ci/runners_finder_spec.rb"
+- "./spec/finders/clusters/knative_services_finder_spec.rb"
+- "./spec/finders/projects/serverless/functions_finder_spec.rb"
+- "./spec/frontend/fixtures/runner.rb"
+- "./spec/graphql/mutations/ci/runner/delete_spec.rb"
+- "./spec/graphql/resolvers/ci/group_runners_resolver_spec.rb"
+- "./spec/graphql/resolvers/ci/job_token_scope_resolver_spec.rb"
+- "./spec/graphql/resolvers/merge_request_pipelines_resolver_spec.rb"
+- "./spec/graphql/types/ci/job_token_scope_type_spec.rb"
+- "./spec/helpers/packages_helper_spec.rb"
+- "./spec/lib/api/entities/package_spec.rb"
+- "./spec/lib/gitlab/background_migration/migrate_legacy_artifacts_spec.rb"
+- "./spec/lib/gitlab/prometheus/query_variables_spec.rb"
+- "./spec/mailers/emails/pipelines_spec.rb"
+- "./spec/migrations/cleanup_legacy_artifact_migration_spec.rb"
+- "./spec/migrations/migrate_protected_attribute_to_pending_builds_spec.rb"
+- "./spec/migrations/re_schedule_latest_pipeline_id_population_with_all_security_related_artifact_types_spec.rb"
+- "./spec/migrations/schedule_migrate_security_scans_spec.rb"
+- "./spec/models/ci/build_spec.rb"
+- "./spec/models/ci/job_artifact_spec.rb"
+- "./spec/models/ci/job_token/scope_spec.rb"
+- "./spec/models/ci/pipeline_spec.rb"
+- "./spec/models/ci/runner_spec.rb"
+- "./spec/models/clusters/applications/runner_spec.rb"
+- "./spec/models/deployment_spec.rb"
+- "./spec/models/environment_spec.rb"
+- "./spec/models/merge_request_spec.rb"
+- "./spec/models/project_spec.rb"
+- "./spec/models/user_spec.rb"
+- "./spec/presenters/ci/build_runner_presenter_spec.rb"
+- "./spec/presenters/ci/pipeline_presenter_spec.rb"
+- "./spec/presenters/packages/detail/package_presenter_spec.rb"
+- "./spec/requests/api/ci/pipelines_spec.rb"
+- "./spec/requests/api/ci/runner/jobs_request_post_spec.rb"
+- "./spec/requests/api/ci/runner/runners_post_spec.rb"
+- "./spec/requests/api/ci/runners_spec.rb"
+- "./spec/requests/api/commit_statuses_spec.rb"
+- "./spec/requests/api/graphql/group_query_spec.rb"
+- "./spec/requests/api/graphql/merge_request/merge_request_spec.rb"
+- "./spec/requests/api/graphql/mutations/ci/job_token_scope/add_project_spec.rb"
+- "./spec/requests/api/graphql/mutations/ci/job_token_scope/remove_project_spec.rb"
+- "./spec/requests/api/graphql/mutations/environments/canary_ingress/update_spec.rb"
+- "./spec/requests/api/graphql/mutations/merge_requests/create_spec.rb"
+- "./spec/requests/api/graphql/packages/composer_spec.rb"
+- "./spec/requests/api/graphql/packages/conan_spec.rb"
+- "./spec/requests/api/graphql/packages/maven_spec.rb"
+- "./spec/requests/api/graphql/packages/nuget_spec.rb"
+- "./spec/requests/api/graphql/packages/package_spec.rb"
+- "./spec/requests/api/graphql/packages/pypi_spec.rb"
+- "./spec/requests/api/graphql/project/merge_request/pipelines_spec.rb"
+- "./spec/requests/api/graphql/project/merge_request_spec.rb"
+- "./spec/requests/api/graphql/project/merge_requests_spec.rb"
+- "./spec/requests/api/graphql/project/pipeline_spec.rb"
+- "./spec/requests/api/merge_requests_spec.rb"
+- "./spec/requests/api/package_files_spec.rb"
+- "./spec/services/auto_merge/merge_when_pipeline_succeeds_service_spec.rb"
+- "./spec/services/ci/create_pipeline_service/cross_project_pipeline_spec.rb"
+- "./spec/services/ci/create_pipeline_service/needs_spec.rb"
+- "./spec/services/ci/create_pipeline_service_spec.rb"
+- "./spec/services/ci/destroy_pipeline_service_spec.rb"
+- "./spec/services/ci/expire_pipeline_cache_service_spec.rb"
+- "./spec/services/ci/job_artifacts/destroy_all_expired_service_spec.rb"
+- "./spec/services/ci/job_artifacts/destroy_associations_service_spec.rb"
+- "./spec/services/ci/job_artifacts/destroy_batch_service_spec.rb"
+- "./spec/services/ci/pipeline_processing/shared_processing_service.rb"
+- "./spec/services/ci/pipeline_processing/shared_processing_service_tests_with_yaml.rb"
+- "./spec/services/ci/register_job_service_spec.rb"
+- "./spec/services/clusters/applications/prometheus_config_service_spec.rb"
+- "./spec/services/deployments/older_deployments_drop_service_spec.rb"
+- "./spec/services/environments/auto_stop_service_spec.rb"
+- "./spec/services/environments/stop_service_spec.rb"
+- "./spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb"
+- "./spec/services/merge_requests/create_service_spec.rb"
+- "./spec/services/merge_requests/post_merge_service_spec.rb"
+- "./spec/services/merge_requests/refresh_service_spec.rb"
+- "./spec/support/prometheus/additional_metrics_shared_examples.rb"
+- "./spec/support/shared_examples/ci/pipeline_email_shared_examples.rb"
+- "./spec/support/shared_examples/features/packages_shared_examples.rb"
+- "./spec/support/shared_examples/features/search_settings_shared_examples.rb"
+- "./spec/support/shared_examples/features/variable_list_shared_examples.rb"
+- "./spec/support/shared_examples/models/concerns/limitable_shared_examples.rb"
+- "./spec/support/shared_examples/quick_actions/merge_request/merge_quick_action_shared_examples.rb"
+- "./spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb"
+- "./spec/support/shared_examples/requests/api/graphql/packages/package_details_shared_examples.rb"
+- "./spec/support/shared_examples/requests/api/logging_application_context_shared_examples.rb"
+- "./spec/support/shared_examples/requests/api/status_shared_examples.rb"
+- "./spec/support/shared_examples/requests/graphql_shared_examples.rb"
+- "./spec/support/shared_examples/services/onboarding_progress_shared_examples.rb"
+- "./spec/support/shared_examples/services/packages_shared_examples.rb"
+- "./spec/support/shared_examples/workers/idempotency_shared_examples.rb"
+- "./spec/tasks/gitlab/generate_sample_prometheus_data_spec.rb"
+- "./spec/workers/pipeline_process_worker_spec.rb"
+- "./spec/workers/pipeline_schedule_worker_spec.rb"
diff --git a/spec/support/database/gitlab_schema.rb b/spec/support/database/gitlab_schema.rb
new file mode 100644
index 00000000000..fe05fb998e6
--- /dev/null
+++ b/spec/support/database/gitlab_schema.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+# This module gathes information about table to schema mapping
+# to understand table affinity
+module Database
+ module GitlabSchema
+ def self.table_schemas(tables)
+ tables.map { |table| table_schema(table) }.to_set
+ end
+
+ def self.table_schema(name)
+ tables_to_schema[name] || :undefined
+ end
+
+ def self.tables_to_schema
+ @tables_to_schema ||= all_classes_with_schema.to_h do |klass|
+ [klass.table_name, klass.gitlab_schema]
+ end
+ end
+
+ def self.all_classes_with_schema
+ ActiveRecord::Base.descendants.reject(&:abstract_class?).select(&:gitlab_schema?) # rubocop:disable Database/MultipleDatabases
+ end
+ end
+end
diff --git a/spec/support/database/multiple_databases.rb b/spec/support/database/multiple_databases.rb
new file mode 100644
index 00000000000..8ce642a682c
--- /dev/null
+++ b/spec/support/database/multiple_databases.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+module Database
+ module MultipleDatabases
+ def skip_if_multiple_databases_not_setup
+ skip 'Skipping because multiple databases not set up' unless Gitlab::Database.has_config?(:ci)
+ end
+ end
+end
diff --git a/spec/support/database/prevent_cross_database_modification.rb b/spec/support/database/prevent_cross_database_modification.rb
index 460ee99391b..b4c968e3c41 100644
--- a/spec/support/database/prevent_cross_database_modification.rb
+++ b/spec/support/database/prevent_cross_database_modification.rb
@@ -74,18 +74,20 @@ module Database
return if cross_database_context[:transaction_depth_by_db].values.all?(&:zero?)
- tables = PgQuery.parse(sql).dml_tables
+ parsed_query = PgQuery.parse(sql)
+ tables = sql.downcase.include?(' for update') ? parsed_query.tables : parsed_query.dml_tables
return if tables.empty?
cross_database_context[:modified_tables_by_db][database].merge(tables)
all_tables = cross_database_context[:modified_tables_by_db].values.map(&:to_a).flatten
+ schemas = Database::GitlabSchema.table_schemas(all_tables)
- unless PreventCrossJoins.only_ci_or_only_main?(all_tables)
+ if schemas.many?
raise Database::PreventCrossDatabaseModification::CrossDatabaseModificationAcrossUnsupportedTablesError,
- "Cross-database data modification queries (CI and Main) were detected within " \
- "a transaction '#{all_tables.join(", ")}' discovered"
+ "Cross-database data modification of '#{schemas.to_a.join(", ")}' were detected within " \
+ "a transaction modifying the '#{all_tables.to_a.join(", ")}'"
end
end
end
diff --git a/spec/support/database/prevent_cross_joins.rb b/spec/support/database/prevent_cross_joins.rb
index 789721ccd38..4b78aa9014c 100644
--- a/spec/support/database/prevent_cross_joins.rb
+++ b/spec/support/database/prevent_cross_joins.rb
@@ -11,7 +11,7 @@
#
# class User
# def ci_owned_runners
-# ::Gitlab::Database.allow_cross_joins_across_databases!(url: link-to-issue-url)
+# ::Gitlab::Database.allow_cross_joins_across_databases(url: link-to-issue-url)
#
# ...
# end
@@ -21,33 +21,43 @@ module Database
module PreventCrossJoins
CrossJoinAcrossUnsupportedTablesError = Class.new(StandardError)
+ ALLOW_THREAD_KEY = :allow_cross_joins_across_databases
+
def self.validate_cross_joins!(sql)
- return if Thread.current[:allow_cross_joins_across_databases]
+ return if Thread.current[ALLOW_THREAD_KEY]
+
+ # Allow spec/support/database_cleaner.rb queries to disable/enable triggers for many tables
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/339396
+ return if sql.include?("DISABLE TRIGGER") || sql.include?("ENABLE TRIGGER")
# PgQuery might fail in some cases due to limited nesting:
# https://github.com/pganalyze/pg_query/issues/209
- tables = PgQuery.parse(sql).tables
+ #
+ # Also, we disable GC while parsing because of https://github.com/pganalyze/pg_query/issues/226
+ begin
+ GC.disable
+ tables = PgQuery.parse(sql).tables
+ ensure
+ GC.enable
+ end
- unless only_ci_or_only_main?(tables)
+ schemas = Database::GitlabSchema.table_schemas(tables)
+
+ if schemas.include?(:gitlab_ci) && schemas.include?(:gitlab_main)
+ Thread.current[:has_cross_join_exception] = true
raise CrossJoinAcrossUnsupportedTablesError,
- "Unsupported cross-join across '#{tables.join(", ")}' discovered " \
- "when executing query '#{sql}'"
+ "Unsupported cross-join across '#{tables.join(", ")}' modifying '#{schemas.to_a.join(", ")}' discovered " \
+ "when executing query '#{sql}'. Please refer to https://docs.gitlab.com/ee/development/database/multiple_databases.html#removing-joins-between-ci_-and-non-ci_-tables for details on how to resolve this exception."
end
end
- # Returns true if a set includes only CI tables, or includes only non-CI tables
- def self.only_ci_or_only_main?(tables)
- tables.all? { |table| CiTables.include?(table) } ||
- tables.none? { |table| CiTables.include?(table) }
- end
-
module SpecHelpers
def with_cross_joins_prevented
subscriber = ActiveSupport::Notifications.subscribe('sql.active_record') do |event|
::Database::PreventCrossJoins.validate_cross_joins!(event.payload[:sql])
end
- Thread.current[:allow_cross_joins_across_databases] = false
+ Thread.current[ALLOW_THREAD_KEY] = false
yield
ensure
@@ -57,8 +67,12 @@ module Database
module GitlabDatabaseMixin
def allow_cross_joins_across_databases(url:)
- Thread.current[:allow_cross_joins_across_databases] = true
- super
+ old_value = Thread.current[ALLOW_THREAD_KEY]
+ Thread.current[ALLOW_THREAD_KEY] = true
+
+ yield
+ ensure
+ Thread.current[ALLOW_THREAD_KEY] = old_value
end
end
end
@@ -67,11 +81,18 @@ end
Gitlab::Database.singleton_class.prepend(
Database::PreventCrossJoins::GitlabDatabaseMixin)
+ALLOW_LIST = Set.new(YAML.load_file(File.join(__dir__, 'cross-join-allowlist.yml'))).freeze
+
RSpec.configure do |config|
config.include(::Database::PreventCrossJoins::SpecHelpers)
- # TODO: remove `:prevent_cross_joins` to enable the check by default
- config.around(:each, :prevent_cross_joins) do |example|
- with_cross_joins_prevented { example.run }
+ config.around do |example|
+ Thread.current[:has_cross_join_exception] = false
+
+ if ALLOW_LIST.include?(example.file_path)
+ example.run
+ else
+ with_cross_joins_prevented { example.run }
+ end
end
end
diff --git a/spec/support/database_cleaner.rb b/spec/support/database_cleaner.rb
index 01bf390d9e9..b31881e3082 100644
--- a/spec/support/database_cleaner.rb
+++ b/spec/support/database_cleaner.rb
@@ -14,7 +14,7 @@ RSpec.configure do |config|
end
config.append_after(:context, :migration) do
- delete_from_all_tables!
+ delete_from_all_tables!(except: ['work_item_types'])
# Postgres maximum number of columns in a table is 1600 (https://github.com/postgres/postgres/blob/de41869b64d57160f58852eab20a27f248188135/src/include/access/htup_details.h#L23-L47).
# And since:
@@ -61,7 +61,7 @@ RSpec.configure do |config|
example.run
- delete_from_all_tables!
+ delete_from_all_tables!(except: ['work_item_types'])
self.class.use_transactional_tests = true
end
diff --git a/spec/support/database_load_balancing.rb b/spec/support/database_load_balancing.rb
index 03fa7886295..f22c69ea613 100644
--- a/spec/support/database_load_balancing.rb
+++ b/spec/support/database_load_balancing.rb
@@ -4,7 +4,10 @@ RSpec.configure do |config|
config.before(:each, :db_load_balancing) do
allow(Gitlab::Database::LoadBalancing).to receive(:enable?).and_return(true)
- proxy = ::Gitlab::Database::LoadBalancing::ConnectionProxy.new([Gitlab::Database.main.config['host']])
+ config = Gitlab::Database::LoadBalancing::Configuration
+ .new(ActiveRecord::Base, [Gitlab::Database.main.config['host']])
+ lb = ::Gitlab::Database::LoadBalancing::LoadBalancer.new(config)
+ proxy = ::Gitlab::Database::LoadBalancing::ConnectionProxy.new(lb)
allow(ActiveRecord::Base).to receive(:load_balancing_proxy).and_return(proxy)
diff --git a/spec/support/db_cleaner.rb b/spec/support/db_cleaner.rb
index 155dc3c17d9..940ff2751d3 100644
--- a/spec/support/db_cleaner.rb
+++ b/spec/support/db_cleaner.rb
@@ -12,7 +12,7 @@ module DbCleaner
end
def deletion_except_tables
- []
+ ['work_item_types']
end
def setup_database_cleaner
diff --git a/spec/support/helpers/bare_repo_operations.rb b/spec/support/helpers/bare_repo_operations.rb
index 98fa13db6c2..e29e12a15f6 100644
--- a/spec/support/helpers/bare_repo_operations.rb
+++ b/spec/support/helpers/bare_repo_operations.rb
@@ -17,26 +17,6 @@ class BareRepoOperations
commit_id[0]
end
- # Based on https://stackoverflow.com/a/25556917/1856239
- def commit_file(file, dst_path, branch = 'master')
- head_id = execute(['show', '--format=format:%H', '--no-patch', branch], allow_failure: true)[0] || Gitlab::Git::EMPTY_TREE_ID
-
- execute(['read-tree', '--empty'])
- execute(['read-tree', head_id])
-
- blob_id = execute(['hash-object', '--stdin', '-w']) do |stdin|
- stdin.write(file.read)
- end
-
- execute(['update-index', '--add', '--cacheinfo', '100644', blob_id[0], dst_path])
-
- tree_id = execute(['write-tree'])
-
- commit_id = commit_tree(tree_id[0], "Add #{dst_path}", parent: head_id)
-
- execute(['update-ref', "refs/heads/#{branch}", commit_id])
- end
-
private
def execute(args, allow_failure: false)
diff --git a/spec/support/helpers/cycle_analytics_helpers.rb b/spec/support/helpers/cycle_analytics_helpers.rb
index e48c8125d84..3ec52f8c832 100644
--- a/spec/support/helpers/cycle_analytics_helpers.rb
+++ b/spec/support/helpers/cycle_analytics_helpers.rb
@@ -23,12 +23,39 @@ module CycleAnalyticsHelpers
end
end
+ def select_event_label(sel)
+ page.within(sel) do
+ find('.dropdown-toggle').click
+ page.find(".dropdown-menu").all(".dropdown-item")[1].click
+ end
+ end
+
+ def fill_in_custom_label_stage_fields
+ index = page.all('[data-testid="value-stream-stage-fields"]').length
+ last_stage = page.all('[data-testid="value-stream-stage-fields"]').last
+
+ within last_stage do
+ find('[name*="custom-stage-name-"]').fill_in with: "Cool custom label stage - name #{index}"
+ select_dropdown_option_by_value "custom-stage-start-event-", :issue_label_added
+ select_dropdown_option_by_value "custom-stage-end-event-", :issue_label_removed
+
+ select_event_label("[data-testid*='custom-stage-start-event-label-']")
+ select_event_label("[data-testid*='custom-stage-end-event-label-']")
+ end
+ end
+
def add_custom_stage_to_form
page.find_button(s_('CreateValueStreamForm|Add another stage')).click
fill_in_custom_stage_fields
end
+ def add_custom_label_stage_to_form
+ page.find_button(s_('CreateValueStreamForm|Add another stage')).click
+
+ fill_in_custom_label_stage_fields
+ end
+
def save_value_stream(custom_value_stream_name)
fill_in 'create-value-stream-name', with: custom_value_stream_name
@@ -44,12 +71,12 @@ module CycleAnalyticsHelpers
save_value_stream(custom_value_stream_name)
end
- def wait_for_stages_to_load(selector = '.js-path-navigation')
+ def wait_for_stages_to_load(selector = '[data-testid="vsa-path-navigation"]')
expect(page).to have_selector selector
wait_for_requests
end
- def select_group(target_group, ready_selector = '.js-path-navigation')
+ def select_group(target_group, ready_selector = '[data-testid="vsa-path-navigation"]')
visit group_analytics_cycle_analytics_path(target_group)
wait_for_stages_to_load(ready_selector)
diff --git a/spec/support/helpers/email_helpers.rb b/spec/support/helpers/email_helpers.rb
index 6df33e68629..d0f6fd466d0 100644
--- a/spec/support/helpers/email_helpers.rb
+++ b/spec/support/helpers/email_helpers.rb
@@ -2,7 +2,7 @@
module EmailHelpers
def sent_to_user(user, recipients: email_recipients)
- recipients.count { |to| to == user.notification_email }
+ recipients.count { |to| to == user.notification_email_or_default }
end
def reset_delivered_emails!
@@ -45,7 +45,7 @@ module EmailHelpers
end
def find_email_for(user)
- ActionMailer::Base.deliveries.find { |d| d.to.include?(user.notification_email) }
+ ActionMailer::Base.deliveries.find { |d| d.to.include?(user.notification_email_or_default) }
end
def have_referable_subject(referable, include_project: true, reply: false)
diff --git a/spec/support/helpers/features/members_table_helpers.rb b/spec/support/helpers/features/members_helpers.rb
index 2e86e014a1b..2e86e014a1b 100644
--- a/spec/support/helpers/features/members_table_helpers.rb
+++ b/spec/support/helpers/features/members_helpers.rb
diff --git a/spec/support/helpers/javascript_fixtures_helpers.rb b/spec/support/helpers/javascript_fixtures_helpers.rb
index 4c90b907d2d..5174c145a93 100644
--- a/spec/support/helpers/javascript_fixtures_helpers.rb
+++ b/spec/support/helpers/javascript_fixtures_helpers.rb
@@ -42,9 +42,12 @@ module JavaScriptFixturesHelpers
# Public: Reads a GraphQL query from the filesystem as a string
#
- # query_path - file path to the GraphQL query, relative to `app/assets/javascripts`
- def get_graphql_query_as_string(query_path)
- path = Rails.root / 'app/assets/javascripts' / query_path
+ # query_path - file path to the GraphQL query, relative to `app/assets/javascripts`.
+ # ee - boolean, when true `query_path` will be looked up in `/ee`.
+ def get_graphql_query_as_string(query_path, ee: false)
+ base = (ee ? 'ee/' : '') + 'app/assets/javascripts'
+
+ path = Rails.root / base / query_path
queries = Gitlab::Graphql::Queries.find(path)
if queries.length == 1
queries.first.text(mode: Gitlab.ee? ? :ee : :ce )
diff --git a/spec/support/helpers/live_debugger.rb b/spec/support/helpers/live_debugger.rb
index f4199d518a3..d196a6dc746 100644
--- a/spec/support/helpers/live_debugger.rb
+++ b/spec/support/helpers/live_debugger.rb
@@ -16,7 +16,7 @@ module LiveDebugger
puts "The current user credentials are: #{@current_user.username} / #{@current_user.password}" if @current_user
puts "Press any key to resume the execution of the example!!"
- `open #{current_url}` if is_headless_disabled?
+ `open #{current_url}` unless is_headless_disabled?
loop until $stdin.getch
diff --git a/spec/support/helpers/migrations_helpers.rb b/spec/support/helpers/migrations_helpers.rb
index ef212938af5..7799e49d4c1 100644
--- a/spec/support/helpers/migrations_helpers.rb
+++ b/spec/support/helpers/migrations_helpers.rb
@@ -30,7 +30,7 @@ module MigrationsHelpers
end
end
- klass.tap { Gitlab::Database::Partitioning::PartitionManager.new.sync_partitions }
+ klass.tap { Gitlab::Database::Partitioning.sync_partitions([klass]) }
end
def migrations_paths
diff --git a/spec/support/helpers/reference_parser_helpers.rb b/spec/support/helpers/reference_parser_helpers.rb
index a6a7948d9d9..b9796ebbe62 100644
--- a/spec/support/helpers/reference_parser_helpers.rb
+++ b/spec/support/helpers/reference_parser_helpers.rb
@@ -5,9 +5,10 @@ module ReferenceParserHelpers
Nokogiri::HTML.fragment('<a></a>').children[0]
end
- def expect_gathered_references(result, visible, not_visible_count)
+ def expect_gathered_references(result, visible, nodes, visible_nodes)
expect(result[:visible]).to eq(visible)
- expect(result[:not_visible].count).to eq(not_visible_count)
+ expect(result[:nodes]).to eq(nodes)
+ expect(result[:visible_nodes]).to eq(visible_nodes)
end
RSpec.shared_examples 'no project N+1 queries' do
diff --git a/spec/support/helpers/session_helpers.rb b/spec/support/helpers/session_helpers.rb
new file mode 100644
index 00000000000..4ef099a393e
--- /dev/null
+++ b/spec/support/helpers/session_helpers.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module SessionHelpers
+ def expect_single_session_with_authenticated_ttl
+ expect_single_session_with_expiration(Settings.gitlab['session_expire_delay'] * 60)
+ end
+
+ def expect_single_session_with_short_ttl
+ expect_single_session_with_expiration(Settings.gitlab['unauthenticated_session_expire_delay'])
+ end
+
+ def expect_single_session_with_expiration(expiration)
+ session_keys = get_session_keys
+
+ expect(session_keys.size).to eq(1)
+ expect(get_ttl(session_keys.first)).to be_within(5).of(expiration)
+ end
+
+ def get_session_keys
+ Gitlab::Redis::SharedState.with { |redis| redis.scan_each(match: 'session:gitlab:*').to_a }
+ end
+
+ def get_ttl(key)
+ Gitlab::Redis::SharedState.with { |redis| redis.ttl(key) }
+ end
+end
diff --git a/spec/support/helpers/stub_gitlab_calls.rb b/spec/support/helpers/stub_gitlab_calls.rb
index 3824ff2b68d..5ab778c11cb 100644
--- a/spec/support/helpers/stub_gitlab_calls.rb
+++ b/spec/support/helpers/stub_gitlab_calls.rb
@@ -18,6 +18,10 @@ module StubGitlabCalls
stub_ci_pipeline_yaml_file(gitlab_ci_yaml)
end
+ def gitlab_ci_yaml
+ File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
+ end
+
def stub_ci_pipeline_yaml_file(ci_yaml_content)
allow_any_instance_of(Repository)
.to receive(:gitlab_ci_yml_for)
diff --git a/spec/support/helpers/stub_gitlab_data.rb b/spec/support/helpers/stub_gitlab_data.rb
deleted file mode 100644
index ed518393c03..00000000000
--- a/spec/support/helpers/stub_gitlab_data.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-module StubGitlabData
- def gitlab_ci_yaml
- File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
- end
-end
diff --git a/spec/support/helpers/test_env.rb b/spec/support/helpers/test_env.rb
index aa5fcf222f2..badd4e8212c 100644
--- a/spec/support/helpers/test_env.rb
+++ b/spec/support/helpers/test_env.rb
@@ -452,6 +452,10 @@ module TestEnv
example_group
end
+ def seed_db
+ Gitlab::DatabaseImporters::WorkItems::BaseTypeImporter.import
+ end
+
private
# These are directories that should be preserved at cleanup time
diff --git a/spec/support/services/migrate_to_ghost_user_service_shared_examples.rb b/spec/support/services/migrate_to_ghost_user_service_shared_examples.rb
index 8a88f0335a9..2fbc01a9195 100644
--- a/spec/support/services/migrate_to_ghost_user_service_shared_examples.rb
+++ b/spec/support/services/migrate_to_ghost_user_service_shared_examples.rb
@@ -32,7 +32,7 @@ RSpec.shared_examples "migrating a deleted user's associated records to the ghos
expect(user).to be_blocked
end
- it 'migrates all associated fields to te "Ghost user"' do
+ it 'migrates all associated fields to the "Ghost user"' do
service.execute
migrated_record = record_class.find_by_id(record.id)
@@ -46,40 +46,19 @@ RSpec.shared_examples "migrating a deleted user's associated records to the ghos
context "when #{record_class_name} migration fails and is rolled back" do
before do
expect_any_instance_of(ActiveRecord::Associations::CollectionProxy)
- .to receive(:update_all).and_raise(ActiveRecord::Rollback)
+ .to receive(:update_all).and_raise(ActiveRecord::StatementTimeout)
end
it 'rolls back the user block' do
- service.execute
+ expect { service.execute }.to raise_error(ActiveRecord::StatementTimeout)
expect(user.reload).not_to be_blocked
end
- it "doesn't unblock an previously-blocked user" do
+ it "doesn't unblock a previously-blocked user" do
user.block
- service.execute
-
- expect(user.reload).to be_blocked
- end
- end
-
- context "when #{record_class_name} migration fails with a non-rollback exception" do
- before do
- expect_any_instance_of(ActiveRecord::Associations::CollectionProxy)
- .to receive(:update_all).and_raise(ArgumentError)
- end
-
- it 'rolls back the user block' do
- service.execute rescue nil
-
- expect(user.reload).not_to be_blocked
- end
-
- it "doesn't unblock an previously-blocked user" do
- user.block
-
- service.execute rescue nil
+ expect { service.execute }.to raise_error(ActiveRecord::StatementTimeout)
expect(user.reload).to be_blocked
end
diff --git a/spec/support/shared_contexts/email_shared_context.rb b/spec/support/shared_contexts/email_shared_context.rb
index 14c6c85cc43..0dc66eeb2ee 100644
--- a/spec/support/shared_contexts/email_shared_context.rb
+++ b/spec/support/shared_contexts/email_shared_context.rb
@@ -18,6 +18,15 @@ RSpec.shared_context :email_shared_context do
end
end
+def email_fixture(path)
+ fixture_file(path).gsub('project_id', project.project_id.to_s)
+end
+
+def service_desk_fixture(path, slug: nil, key: 'mykey')
+ slug ||= project.full_path_slug.to_s
+ fixture_file(path).gsub('project_slug', slug).gsub('project_key', key)
+end
+
RSpec.shared_examples :reply_processing_shared_examples do
context 'when the user could not be found' do
before do
diff --git a/spec/support/shared_contexts/finders/packages/npm/package_finder_shared_context.rb b/spec/support/shared_contexts/finders/packages/npm/package_finder_shared_context.rb
new file mode 100644
index 00000000000..a2cb9d41f45
--- /dev/null
+++ b/spec/support/shared_contexts/finders/packages/npm/package_finder_shared_context.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+RSpec.shared_context 'last_of_each_version setup context' do
+ let_it_be(:package1) { create(:npm_package, name: 'test', version: '1.2.3', project: project) }
+ let_it_be(:package2) { create(:npm_package, name: 'test2', version: '1.2.3', project: project) }
+
+ let(:package_name) { 'test' }
+ let(:version) { '1.2.3' }
+
+ before do
+ # create a duplicated package without triggering model validation errors
+ package2.update_column(:name, 'test')
+ end
+end
diff --git a/spec/support/shared_contexts/graphql/resolvers/runners_resolver_shared_context.rb b/spec/support/shared_contexts/graphql/resolvers/runners_resolver_shared_context.rb
new file mode 100644
index 00000000000..aa857cfdb70
--- /dev/null
+++ b/spec/support/shared_contexts/graphql/resolvers/runners_resolver_shared_context.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.shared_context 'runners resolver setup' do
+ let_it_be(:user) { create_default(:user, :admin) }
+ let_it_be(:group) { create(:group, :public) }
+ let_it_be(:subgroup) { create(:group, :public, parent: group) }
+ let_it_be(:project) { create(:project, :public, group: group) }
+
+ let_it_be(:inactive_project_runner) do
+ create(:ci_runner, :project, projects: [project], description: 'inactive project runner', token: 'abcdef', active: false, contacted_at: 1.minute.ago, tag_list: %w(project_runner))
+ end
+
+ let_it_be(:offline_project_runner) do
+ create(:ci_runner, :project, projects: [project], description: 'offline project runner', token: 'defghi', contacted_at: 1.day.ago, tag_list: %w(project_runner active_runner))
+ end
+
+ let_it_be(:group_runner) { create(:ci_runner, :group, groups: [group], token: 'mnopqr', description: 'group runner', contacted_at: 2.seconds.ago) }
+ let_it_be(:subgroup_runner) { create(:ci_runner, :group, groups: [subgroup], token: 'mnopqr', description: 'subgroup runner', contacted_at: 1.second.ago) }
+ let_it_be(:instance_runner) { create(:ci_runner, :instance, description: 'shared runner', token: 'stuvxz', contacted_at: 2.minutes.ago, tag_list: %w(instance_runner active_runner)) }
+end
diff --git a/spec/support/shared_contexts/issuable/merge_request_shared_context.rb b/spec/support/shared_contexts/issuable/merge_request_shared_context.rb
index 2c56411ca4c..b9cde12c537 100644
--- a/spec/support/shared_contexts/issuable/merge_request_shared_context.rb
+++ b/spec/support/shared_contexts/issuable/merge_request_shared_context.rb
@@ -16,7 +16,7 @@ RSpec.shared_context 'merge request show action' do
assign(:merge_request, merge_request)
assign(:note, note)
assign(:noteable, merge_request)
- assign(:pipelines, [])
+ assign(:number_of_pipelines, 0)
assign(:issuable_sidebar, serialize_issuable_sidebar(user, project, merge_request))
preload_view_requirements(merge_request, note)
diff --git a/spec/support/shared_contexts/navbar_structure_context.rb b/spec/support/shared_contexts/navbar_structure_context.rb
index 8ae0885056e..2abc52fce85 100644
--- a/spec/support/shared_contexts/navbar_structure_context.rb
+++ b/spec/support/shared_contexts/navbar_structure_context.rb
@@ -118,7 +118,8 @@ RSpec.shared_context 'project navbar structure' do
_('Access Tokens'),
_('Repository'),
_('CI/CD'),
- _('Monitor')
+ _('Monitor'),
+ (s_('UsageQuota|Usage Quotas') if Feature.enabled?(:project_storage_ui, default_enabled: :yaml))
]
}
].compact
diff --git a/spec/support/shared_contexts/pages_zip_with_spoofed_size_shared_context.rb b/spec/support/shared_contexts/pages_zip_with_spoofed_size_shared_context.rb
deleted file mode 100644
index 4cec5ab3b74..00000000000
--- a/spec/support/shared_contexts/pages_zip_with_spoofed_size_shared_context.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-# frozen_string_literal: true
-
-# the idea of creating zip archive with spoofed size is borrowed from
-# https://github.com/rubyzip/rubyzip/pull/403/files#diff-118213fb4baa6404a40f89e1147661ebR88
-RSpec.shared_context 'pages zip with spoofed size' do
- let(:real_zip_path) { Tempfile.new(['real', '.zip']).path }
- let(:fake_zip_path) { Tempfile.new(['fake', '.zip']).path }
-
- before do
- full_file_name = 'public/index.html'
- true_size = 500_000
- fake_size = 1
-
- ::Zip::File.open(real_zip_path, ::Zip::File::CREATE) do |zf|
- zf.get_output_stream(full_file_name) do |os|
- os.write 'a' * true_size
- end
- end
-
- compressed_size = nil
- ::Zip::File.open(real_zip_path) do |zf|
- a_entry = zf.find_entry(full_file_name)
- compressed_size = a_entry.compressed_size
- end
-
- true_size_bytes = [compressed_size, true_size, full_file_name.size].pack('LLS')
- fake_size_bytes = [compressed_size, fake_size, full_file_name.size].pack('LLS')
-
- data = File.binread(real_zip_path)
- data.gsub! true_size_bytes, fake_size_bytes
-
- File.open(fake_zip_path, 'wb') do |file|
- file.write data
- end
- end
-
- after do
- File.delete(real_zip_path) if File.exist?(real_zip_path)
- File.delete(fake_zip_path) if File.exist?(fake_zip_path)
- end
-end
diff --git a/spec/support/shared_contexts/requests/api/npm_packages_shared_context.rb b/spec/support/shared_contexts/requests/api/npm_packages_shared_context.rb
index 815108be447..89f290d8d68 100644
--- a/spec/support/shared_contexts/requests/api/npm_packages_shared_context.rb
+++ b/spec/support/shared_contexts/requests/api/npm_packages_shared_context.rb
@@ -8,14 +8,20 @@ RSpec.shared_context 'npm api setup' do
let_it_be(:group) { create(:group, name: 'test-group') }
let_it_be(:namespace) { group }
let_it_be(:project, reload: true) { create(:project, :public, namespace: namespace) }
- let_it_be(:package, reload: true) { create(:npm_package, project: project, name: "@#{group.path}/scoped_package") }
+ let_it_be(:package1, reload: true) { create(:npm_package, project: project, name: "@#{group.path}/scoped_package", version: '1.2.4') }
+ let_it_be(:package, reload: true) { create(:npm_package, project: project, name: "@#{group.path}/scoped_package", version: '1.2.3') }
let_it_be(:token) { create(:oauth_access_token, scopes: 'api', resource_owner: user) }
let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
- let_it_be(:job, reload: true) { create(:ci_build, user: user, status: :running) }
+ let_it_be(:job, reload: true) { create(:ci_build, user: user, status: :running, project: project) }
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
let(:package_name) { package.name }
+
+ before do
+ # create a duplicated package without triggering model validation errors
+ package1.update_column(:version, '1.2.3')
+ end
end
RSpec.shared_context 'set package name from package name type' do
diff --git a/spec/support/shared_contexts/services/service_ping/stubbed_service_ping_metrics_definitions_shared_context.rb b/spec/support/shared_contexts/services/service_ping/stubbed_service_ping_metrics_definitions_shared_context.rb
index 6b49a415889..2b810e790f0 100644
--- a/spec/support/shared_contexts/services/service_ping/stubbed_service_ping_metrics_definitions_shared_context.rb
+++ b/spec/support/shared_contexts/services/service_ping/stubbed_service_ping_metrics_definitions_shared_context.rb
@@ -6,21 +6,25 @@ RSpec.shared_context 'stubbed service ping metrics definitions' do
let(:metrics_definitions) { standard_metrics + subscription_metrics + operational_metrics + optional_metrics }
let(:standard_metrics) do
[
- metric_attributes('uuid', "standard")
+ metric_attributes('uuid', 'standard'),
+ metric_attributes('recorded_at', 'standard'),
+ metric_attributes('settings.collected_data_categories', 'standard', 'object')
]
end
let(:operational_metrics) do
[
- metric_attributes('counts.merge_requests', "operational"),
+ metric_attributes('counts.merge_requests', 'operational'),
metric_attributes('counts.todos', "operational")
]
end
let(:optional_metrics) do
[
- metric_attributes('counts.boards', "optional"),
- metric_attributes('gitaly.filesystems', '').except('data_category')
+ metric_attributes('counts.boards', 'optional', 'number'),
+ metric_attributes('gitaly.filesystems', '').except('data_category'),
+ metric_attributes('usage_activity_by_stage.monitor.projects_with_enabled_alert_integrations_histogram', 'optional', 'object'),
+ metric_attributes('topology', 'optional', 'object')
]
end
@@ -34,10 +38,11 @@ RSpec.shared_context 'stubbed service ping metrics definitions' do
)
end
- def metric_attributes(key_path, category)
+ def metric_attributes(key_path, category, value_type = 'string')
{
'key_path' => key_path,
- 'data_category' => category
+ 'data_category' => category,
+ 'value_type' => value_type
}
end
end
diff --git a/spec/support/shared_examples/boards/multiple_issue_boards_shared_examples.rb b/spec/support/shared_examples/boards/multiple_issue_boards_shared_examples.rb
index cadc753513d..1e303197990 100644
--- a/spec/support/shared_examples/boards/multiple_issue_boards_shared_examples.rb
+++ b/spec/support/shared_examples/boards/multiple_issue_boards_shared_examples.rb
@@ -3,14 +3,10 @@
RSpec.shared_examples 'multiple issue boards' do
context 'authorized user' do
before do
- stub_feature_flags(board_new_list: false)
-
parent.add_maintainer(user)
login_as(user)
- stub_feature_flags(board_new_list: false)
-
visit boards_path
wait_for_requests
end
@@ -79,13 +75,13 @@ RSpec.shared_examples 'multiple issue boards' do
expect(page).to have_content(board2.name)
end
- click_button 'Add list'
+ click_button 'Create list'
- wait_for_requests
+ click_button 'Select a label'
- page.within '.dropdown-menu-issues-board-new' do
- click_link planning.title
- end
+ page.choose(planning.title)
+
+ click_button 'Add to board'
wait_for_requests
diff --git a/spec/support/shared_examples/controllers/concerns/integrations_actions_shared_examples.rb b/spec/support/shared_examples/controllers/concerns/integrations_actions_shared_examples.rb
new file mode 100644
index 00000000000..748a3acf17b
--- /dev/null
+++ b/spec/support/shared_examples/controllers/concerns/integrations_actions_shared_examples.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples IntegrationsActions do
+ let(:integration) do
+ create(:datadog_integration,
+ integration_attributes.merge(
+ api_url: 'http://example.com',
+ api_key: 'secret'
+ )
+ )
+ end
+
+ describe 'GET #edit' do
+ before do
+ get :edit, params: routing_params
+ end
+
+ it 'assigns the integration' do
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(assigns(:integration)).to eq(integration)
+ end
+ end
+
+ describe 'PUT #update' do
+ let(:params) do
+ {
+ datadog_env: 'env',
+ datadog_service: 'service'
+ }
+ end
+
+ before do
+ put :update, params: routing_params.merge(integration: params)
+ end
+
+ it 'updates the integration with the provided params and redirects to the form' do
+ expect(response).to redirect_to(routing_params.merge(action: :edit))
+ expect(integration.reload).to have_attributes(params)
+ end
+
+ context 'when sending a password field' do
+ let(:params) { super().merge(api_key: 'new') }
+
+ it 'updates the integration with the password and other params' do
+ expect(response).to be_redirect
+ expect(integration.reload).to have_attributes(params)
+ end
+ end
+
+ context 'when sending a blank password field' do
+ let(:params) { super().merge(api_key: '') }
+
+ it 'ignores the password field and saves the other params' do
+ expect(response).to be_redirect
+ expect(integration.reload).to have_attributes(params.merge(api_key: 'secret'))
+ end
+ end
+ end
+end
diff --git a/spec/support/shared_examples/controllers/githubish_import_controller_shared_examples.rb b/spec/support/shared_examples/controllers/githubish_import_controller_shared_examples.rb
index a9c6da7bc2b..0ffa32dec9e 100644
--- a/spec/support/shared_examples/controllers/githubish_import_controller_shared_examples.rb
+++ b/spec/support/shared_examples/controllers/githubish_import_controller_shared_examples.rb
@@ -82,16 +82,6 @@ RSpec.shared_examples 'a GitHub-ish import controller: GET status' do
expect(json_response.dig("provider_repos", 1, "id")).to eq(org_repo.id)
end
- it "does not show already added project" do
- project = create(:project, import_type: provider, namespace: user.namespace, import_status: :finished, import_source: 'asd/vim')
- stub_client(repos: [repo], orgs: [], each_page: [OpenStruct.new(objects: [repo])].to_enum)
-
- get :status, format: :json
-
- expect(json_response.dig("imported_projects", 0, "id")).to eq(project.id)
- expect(json_response.dig("provider_repos")).to eq([])
- end
-
it "touches the etag cache store" do
stub_client(repos: [], orgs: [], each_page: [])
diff --git a/spec/support/shared_examples/controllers/import_controller_status_shared_examples.rb b/spec/support/shared_examples/controllers/import_controller_status_shared_examples.rb
index b9ae0e23e26..44baadaaade 100644
--- a/spec/support/shared_examples/controllers/import_controller_status_shared_examples.rb
+++ b/spec/support/shared_examples/controllers/import_controller_status_shared_examples.rb
@@ -19,14 +19,4 @@ RSpec.shared_examples 'import controller status' do
expect(json_response.dig("imported_projects", 0, "id")).to eq(project.id)
expect(json_response.dig("provider_repos", 0, "id")).to eq(repo_id)
end
-
- it "does not show already added project" do
- project = create(:project, import_type: provider_name, namespace: user.namespace, import_status: :finished, import_source: import_source)
- stub_client(client_repos_field => [repo])
-
- get :status, format: :json
-
- expect(json_response.dig("imported_projects", 0, "id")).to eq(project.id)
- expect(json_response.dig("provider_repos")).to eq([])
- end
end
diff --git a/spec/support/shared_examples/controllers/issuable_anonymous_search_disabled_examples.rb b/spec/support/shared_examples/controllers/issuable_anonymous_search_disabled_examples.rb
new file mode 100644
index 00000000000..e77acb93798
--- /dev/null
+++ b/spec/support/shared_examples/controllers/issuable_anonymous_search_disabled_examples.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'issuable list with anonymous search disabled' do |action|
+ let(:controller_action) { :index }
+ let(:params_with_search) { params.merge(search: 'some search term') }
+
+ context 'when disable_anonymous_search is enabled' do
+ before do
+ stub_feature_flags(disable_anonymous_search: true)
+ end
+
+ it 'shows a flash message' do
+ get controller_action, params: params_with_search
+
+ expect(flash.now[:notice]).to eq('You must sign in to search for specific terms.')
+ end
+
+ context 'when search param is not given' do
+ it 'does not show a flash message' do
+ get controller_action, params: params
+
+ expect(flash.now[:notice]).to be_nil
+ end
+ end
+
+ context 'when user is signed-in' do
+ it 'does not show a flash message' do
+ sign_in(create(:user))
+ get controller_action, params: params_with_search
+
+ expect(flash.now[:notice]).to be_nil
+ end
+ end
+
+ context 'when format is not HTML' do
+ it 'does not show a flash message' do
+ get controller_action, params: params_with_search.merge(format: :atom)
+
+ expect(flash.now[:notice]).to be_nil
+ end
+ end
+ end
+
+ context 'when disable_anonymous_search is disabled' do
+ before do
+ stub_feature_flags(disable_anonymous_search: false)
+ end
+
+ it 'does not show a flash message' do
+ get controller_action, params: params_with_search
+
+ expect(flash.now[:notice]).to be_nil
+ end
+ end
+end
diff --git a/spec/support/shared_examples/features/atom/issuable_shared_examples.rb b/spec/support/shared_examples/features/atom/issuable_shared_examples.rb
new file mode 100644
index 00000000000..17993830f37
--- /dev/null
+++ b/spec/support/shared_examples/features/atom/issuable_shared_examples.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples "an authenticated issuable atom feed" do
+ it "renders atom feed with common issuable information" do
+ expect(response_headers['Content-Type'])
+ .to have_content('application/atom+xml')
+ expect(body).to have_selector('author email', text: issuable.author_public_email)
+ expect(body).to have_selector('assignees assignee email', text: issuable.assignees.first.public_email)
+ expect(body).to have_selector('assignee email', text: issuable.assignees.first.public_email)
+ expect(body).to have_selector('entry summary', text: issuable.title)
+ end
+end
diff --git a/spec/support/shared_examples/features/content_editor_shared_examples.rb b/spec/support/shared_examples/features/content_editor_shared_examples.rb
new file mode 100644
index 00000000000..2332285540a
--- /dev/null
+++ b/spec/support/shared_examples/features/content_editor_shared_examples.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'edits content using the content editor' do
+ it 'formats text as bold using bubble menu' do
+ content_editor_testid = '[data-testid="content-editor"] [contenteditable]'
+
+ expect(page).to have_css(content_editor_testid)
+
+ find(content_editor_testid).send_keys 'Typing text in the content editor'
+ find(content_editor_testid).send_keys [:shift, :left]
+
+ expect(page).to have_css('[data-testid="formatting-bubble-menu"]')
+ end
+end
diff --git a/spec/support/shared_examples/features/deploy_token_shared_examples.rb b/spec/support/shared_examples/features/deploy_token_shared_examples.rb
index fd77297a490..e70f9b52c09 100644
--- a/spec/support/shared_examples/features/deploy_token_shared_examples.rb
+++ b/spec/support/shared_examples/features/deploy_token_shared_examples.rb
@@ -1,15 +1,22 @@
# frozen_string_literal: true
RSpec.shared_examples 'a deploy token in settings' do
- it 'view deploy tokens' do
+ it 'view deploy tokens', :js do
+ user.update!(time_display_relative: true)
+
+ visit page_path
+
within('.deploy-tokens') do
expect(page).to have_content(deploy_token.name)
expect(page).to have_content('read_repository')
expect(page).to have_content('read_registry')
+ expect(page).to have_content('in 4 days')
end
end
it 'add a new deploy token' do
+ visit page_path
+
fill_in 'deploy_token_name', with: 'new_deploy_key'
fill_in 'deploy_token_expires_at', with: (Date.today + 1.month).to_s
fill_in 'deploy_token_username', with: 'deployer'
@@ -24,4 +31,18 @@ RSpec.shared_examples 'a deploy token in settings' do
expect(page).to have_selector("input[name='deploy-token'][readonly='readonly']")
end
end
+
+ context 'when User#time_display_relative is false', :js do
+ before do
+ user.update!(time_display_relative: false)
+ end
+
+ it 'shows absolute times for expires_at' do
+ visit page_path
+
+ within('.deploy-tokens') do
+ expect(page).to have_content(deploy_token.expires_at.strftime('%b %d'))
+ end
+ end
+ end
end
diff --git a/spec/support/shared_examples/features/discussion_comments_shared_example.rb b/spec/support/shared_examples/features/discussion_comments_shared_example.rb
index fb2e422559d..318ba67b9e9 100644
--- a/spec/support/shared_examples/features/discussion_comments_shared_example.rb
+++ b/spec/support/shared_examples/features/discussion_comments_shared_example.rb
@@ -7,7 +7,7 @@ RSpec.shared_examples 'thread comments for commit and snippet' do |resource_name
let(:menu_selector) { "#{dropdown_selector} .dropdown-menu" }
let(:submit_selector) { "#{form_selector} .js-comment-submit-button" }
let(:close_selector) { "#{form_selector} .btn-comment-and-close" }
- let(:comments_selector) { '.timeline > .note.timeline-entry' }
+ let(:comments_selector) { '.timeline > .note.timeline-entry:not(.being-posted)' }
let(:comment) { 'My comment' }
it 'clicking "Comment" will post a comment' do
@@ -187,7 +187,7 @@ RSpec.shared_examples 'thread comments for issue, epic and merge request' do |re
let(:toggle_selector) { "#{dropdown_selector} .dropdown-toggle-split" }
let(:menu_selector) { "#{dropdown_selector} .dropdown-menu" }
let(:close_selector) { "#{form_selector} .btn-comment-and-close" }
- let(:comments_selector) { '.timeline > .note.timeline-entry' }
+ let(:comments_selector) { '.timeline > .note.timeline-entry:not(.being-posted)' }
let(:comment) { 'My comment' }
it 'clicking "Comment" will post a comment' do
@@ -197,6 +197,8 @@ RSpec.shared_examples 'thread comments for issue, epic and merge request' do |re
find(submit_button_selector).click
+ wait_for_all_requests
+
expect(page).to have_content(comment)
new_comment = all(comments_selector).last
diff --git a/spec/support/shared_examples/features/issuable_invite_members_shared_examples.rb b/spec/support/shared_examples/features/issuable_invite_members_shared_examples.rb
index c0cfc27ceaf..149486320ae 100644
--- a/spec/support/shared_examples/features/issuable_invite_members_shared_examples.rb
+++ b/spec/support/shared_examples/features/issuable_invite_members_shared_examples.rb
@@ -15,7 +15,7 @@ RSpec.shared_examples 'issuable invite members' do
page.within '.dropdown-menu-user' do
expect(page).to have_link('Invite Members')
- expect(page).to have_selector('[data-track-event="click_invite_members"]')
+ expect(page).to have_selector('[data-track-action="click_invite_members"]')
expect(page).to have_selector('[data-track-label="edit_assignee"]')
end
diff --git a/spec/support/shared_examples/features/manage_applications_shared_examples.rb b/spec/support/shared_examples/features/manage_applications_shared_examples.rb
index 38bb87eaed2..0161899cb76 100644
--- a/spec/support/shared_examples/features/manage_applications_shared_examples.rb
+++ b/spec/support/shared_examples/features/manage_applications_shared_examples.rb
@@ -9,9 +9,11 @@ RSpec.shared_examples 'manage applications' do
visit new_application_path
expect(page).to have_content 'Add new application'
+ expect(find('#doorkeeper_application_expire_access_tokens')).to be_checked
fill_in :doorkeeper_application_name, with: application_name
fill_in :doorkeeper_application_redirect_uri, with: application_redirect_uri
+ uncheck :doorkeeper_application_expire_access_tokens
check :doorkeeper_application_scopes_read_user
click_on 'Save application'
@@ -22,6 +24,8 @@ RSpec.shared_examples 'manage applications' do
click_on 'Edit'
+ expect(find('#doorkeeper_application_expire_access_tokens')).not_to be_checked
+
application_name_changed = "#{application_name} changed"
fill_in :doorkeeper_application_name, with: application_name_changed
diff --git a/spec/support/shared_examples/features/rss_shared_examples.rb b/spec/support/shared_examples/features/rss_shared_examples.rb
index c7c2aeea358..0991de21d8d 100644
--- a/spec/support/shared_examples/features/rss_shared_examples.rb
+++ b/spec/support/shared_examples/features/rss_shared_examples.rb
@@ -25,3 +25,23 @@ RSpec.shared_examples "it has an RSS button without a feed token" do
.to have_css("a:has(.qa-rss-icon):not([href*='feed_token'])") # rubocop:disable QA/SelectorUsage
end
end
+
+RSpec.shared_examples "updates atom feed link" do |type|
+ it "for #{type}" do
+ sign_in(user)
+ visit path
+
+ link = find_link('Subscribe to RSS feed')
+ params = CGI.parse(URI.parse(link[:href]).query)
+ auto_discovery_link = find("link[type='application/atom+xml']", visible: false)
+ auto_discovery_params = CGI.parse(URI.parse(auto_discovery_link[:href]).query)
+
+ expected = {
+ 'feed_token' => [user.feed_token],
+ 'assignee_id' => [user.id.to_s]
+ }
+
+ expect(params).to include(expected)
+ expect(auto_discovery_params).to include(expected)
+ end
+end
diff --git a/spec/support/shared_examples/features/wiki/user_updates_wiki_page_shared_examples.rb b/spec/support/shared_examples/features/wiki/user_updates_wiki_page_shared_examples.rb
index 9587da0233e..7ced8508a31 100644
--- a/spec/support/shared_examples/features/wiki/user_updates_wiki_page_shared_examples.rb
+++ b/spec/support/shared_examples/features/wiki/user_updates_wiki_page_shared_examples.rb
@@ -136,6 +136,14 @@ RSpec.shared_examples 'User updates wiki page' do
expect(find('textarea#wiki_content').value).to eq('Updated Wiki Content')
end
end
+
+ context 'when using the content editor' do
+ before do
+ click_button 'Use the new editor'
+ end
+
+ it_behaves_like 'edits content using the content editor'
+ end
end
context 'when the page is in a subdir', :js do
diff --git a/spec/support/shared_examples/features/wiki/user_views_wiki_page_shared_examples.rb b/spec/support/shared_examples/features/wiki/user_views_wiki_page_shared_examples.rb
index 61feeff57bb..96df5a5f972 100644
--- a/spec/support/shared_examples/features/wiki/user_views_wiki_page_shared_examples.rb
+++ b/spec/support/shared_examples/features/wiki/user_views_wiki_page_shared_examples.rb
@@ -157,7 +157,7 @@ RSpec.shared_examples 'User views a wiki page' do
expect(page).to have_link('updated home', href: wiki_page_path(wiki, wiki_page, version_id: commit2, action: :diff))
end
- it 'between the current and the previous version of a page' do
+ it 'between the current and the previous version of a page', :js do
commit = wiki.commit
visit wiki_page_path(wiki, wiki_page, version_id: commit, action: :diff)
@@ -169,7 +169,7 @@ RSpec.shared_examples 'User views a wiki page' do
expect_diff_links(commit)
end
- it 'between two old versions of a page' do
+ it 'between two old versions of a page', :js do
wiki_page.update(message: 'latest home change', content: 'updated [another link](other-page)') # rubocop:disable Rails/SaveBang:
commit = wiki.commit('HEAD^')
visit wiki_page_path(wiki, wiki_page, version_id: commit, action: :diff)
@@ -184,7 +184,7 @@ RSpec.shared_examples 'User views a wiki page' do
expect_diff_links(commit)
end
- it 'for the oldest version of a page' do
+ it 'for the oldest version of a page', :js do
commit = wiki.commit('HEAD^')
visit wiki_page_path(wiki, wiki_page, version_id: commit, action: :diff)
diff --git a/spec/support/shared_examples/lib/gitlab/cycle_analytics/deployment_metrics.rb b/spec/support/shared_examples/lib/gitlab/cycle_analytics/deployment_metrics.rb
new file mode 100644
index 00000000000..6342064beb8
--- /dev/null
+++ b/spec/support/shared_examples/lib/gitlab/cycle_analytics/deployment_metrics.rb
@@ -0,0 +1,124 @@
+# frozen_string_literal: true
+
+shared_examples 'deployment metrics examples' do
+ def create_deployment(args)
+ project = args[:project]
+ environment = project.environments.production.first || create(:environment, :production, project: project)
+ create(:deployment, :success, args.merge(environment: environment))
+
+ # this is needed for the dora_deployment_frequency_in_vsa feature flag so we have aggregated data
+ ::Dora::DailyMetrics::RefreshWorker.new.perform(environment.id, Time.current.to_date.to_s) if Gitlab.ee?
+ end
+
+ describe "#deploys" do
+ subject { stage_summary.third }
+
+ context 'when from date is given' do
+ before do
+ travel_to(5.days.ago) { create_deployment(project: project) }
+ create_deployment(project: project)
+ end
+
+ it "finds the number of deploys made created after the 'from date'" do
+ expect(subject[:value]).to eq('1')
+ end
+
+ it 'returns the localized title' do
+ Gitlab::I18n.with_locale(:ru) do
+ expect(subject[:title]).to eq(n_('Deploy', 'Deploys', 1))
+ end
+ end
+ end
+
+ it "doesn't find commits from other projects" do
+ travel_to(5.days.from_now) do
+ create_deployment(project: create(:project, :repository))
+ end
+
+ expect(subject[:value]).to eq('-')
+ end
+
+ context 'when `to` parameter is given' do
+ before do
+ travel_to(5.days.ago) { create_deployment(project: project) }
+ travel_to(5.days.from_now) { create_deployment(project: project) }
+ end
+
+ it "doesn't find any record" do
+ options[:to] = Time.now
+
+ expect(subject[:value]).to eq('-')
+ end
+
+ it "finds records created between `from` and `to` range" do
+ options[:from] = 10.days.ago
+ options[:to] = 10.days.from_now
+
+ expect(subject[:value]).to eq('2')
+ end
+ end
+ end
+
+ describe '#deployment_frequency' do
+ subject { stage_summary.fourth[:value] }
+
+ it 'includes the unit: `per day`' do
+ expect(stage_summary.fourth[:unit]).to eq _('per day')
+ end
+
+ before do
+ travel_to(5.days.ago) { create_deployment(project: project) }
+ end
+
+ it 'returns 0.0 when there were deploys but the frequency was too low' do
+ options[:from] = 30.days.ago
+
+ # 1 deployment over 30 days
+ # frequency of 0.03, rounded off to 0.0
+ expect(subject).to eq('0')
+ end
+
+ it 'returns `-` when there were no deploys' do
+ options[:from] = 4.days.ago
+
+ # 0 deployment in the last 4 days
+ expect(subject).to eq('-')
+ end
+
+ context 'when `to` is nil' do
+ it 'includes range until now' do
+ options[:from] = 6.days.ago
+ options[:to] = nil
+
+ # 1 deployment over 7 days
+ expect(subject).to eq('0.1')
+ end
+ end
+
+ context 'when `to` is given' do
+ before do
+ travel_to(5.days.from_now) { create_deployment(project: project, finished_at: Time.zone.now) }
+ end
+
+ it 'finds records created between `from` and `to` range' do
+ options[:from] = 10.days.ago
+ options[:to] = 10.days.from_now
+
+ # 2 deployments over 20 days
+ expect(subject).to eq('0.1')
+ end
+
+ context 'when `from` and `to` are within a day' do
+ it 'returns the number of deployments made on that day' do
+ freeze_time do
+ create_deployment(project: project, finished_at: Time.current)
+ options[:from] = Time.current.yesterday.beginning_of_day
+ options[:to] = Time.current.end_of_day
+
+ expect(subject).to eq('0.5')
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/support/shared_examples/lib/gitlab/sidekiq_middleware/strategy_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/sidekiq_middleware/strategy_shared_examples.rb
index 89b793d5e16..708bc71ae96 100644
--- a/spec/support/shared_examples/lib/gitlab/sidekiq_middleware/strategy_shared_examples.rb
+++ b/spec/support/shared_examples/lib/gitlab/sidekiq_middleware/strategy_shared_examples.rb
@@ -39,6 +39,7 @@ RSpec.shared_examples 'deduplicating jobs when scheduling' do |strategy_name|
allow(fake_duplicate_job).to receive(:scheduled?).and_return(false)
allow(fake_duplicate_job).to receive(:check!).and_return('the jid')
allow(fake_duplicate_job).to receive(:idempotent?).and_return(true)
+ allow(fake_duplicate_job).to receive(:update_latest_wal_location!)
allow(fake_duplicate_job).to receive(:options).and_return({})
job_hash = {}
@@ -63,6 +64,7 @@ RSpec.shared_examples 'deduplicating jobs when scheduling' do |strategy_name|
.with(Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob::DUPLICATE_KEY_TTL)
.and_return('the jid'))
allow(fake_duplicate_job).to receive(:idempotent?).and_return(true)
+ allow(fake_duplicate_job).to receive(:update_latest_wal_location!)
job_hash = {}
expect(fake_duplicate_job).to receive(:duplicate?).and_return(true)
@@ -83,6 +85,7 @@ RSpec.shared_examples 'deduplicating jobs when scheduling' do |strategy_name|
allow(fake_duplicate_job).to(
receive(:check!).with(time_diff.to_i).and_return('the jid'))
allow(fake_duplicate_job).to receive(:idempotent?).and_return(true)
+ allow(fake_duplicate_job).to receive(:update_latest_wal_location!)
job_hash = {}
expect(fake_duplicate_job).to receive(:duplicate?).and_return(true)
@@ -105,6 +108,13 @@ RSpec.shared_examples 'deduplicating jobs when scheduling' do |strategy_name|
allow(fake_duplicate_job).to receive(:options).and_return({})
allow(fake_duplicate_job).to receive(:existing_jid).and_return('the jid')
allow(fake_duplicate_job).to receive(:idempotent?).and_return(true)
+ allow(fake_duplicate_job).to receive(:update_latest_wal_location!)
+ end
+
+ it 'updates latest wal location' do
+ expect(fake_duplicate_job).to receive(:update_latest_wal_location!)
+
+ strategy.schedule({ 'jid' => 'new jid' }) {}
end
it 'drops the job' do
@@ -136,4 +146,46 @@ RSpec.shared_examples 'deduplicating jobs when scheduling' do |strategy_name|
end
end
end
+
+ describe '#perform' do
+ let(:proc) { -> {} }
+ let(:job) { { 'jid' => 'new jid', 'wal_locations' => { 'main' => '0/1234', 'ci' => '0/1234' } } }
+ let(:wal_locations) do
+ {
+ main: '0/D525E3A8',
+ ci: 'AB/12345'
+ }
+ end
+
+ before do
+ allow(fake_duplicate_job).to receive(:delete!)
+ allow(fake_duplicate_job).to receive(:latest_wal_locations).and_return( wal_locations )
+ end
+
+ it 'updates job hash with dedup_wal_locations' do
+ strategy.perform(job) do
+ proc.call
+ end
+
+ expect(job['dedup_wal_locations']).to eq(wal_locations)
+ end
+
+ shared_examples 'does not update job hash' do
+ it 'does not update job hash with dedup_wal_locations' do
+ strategy.perform(job) do
+ proc.call
+ end
+
+ expect(job).not_to include('dedup_wal_locations')
+ end
+ end
+
+ context 'when latest_wal_location is empty' do
+ before do
+ allow(fake_duplicate_job).to receive(:latest_wal_locations).and_return( {} )
+ end
+
+ include_examples 'does not update job hash'
+ end
+ end
end
diff --git a/spec/support/shared_examples/mailers/notify_shared_examples.rb b/spec/support/shared_examples/mailers/notify_shared_examples.rb
index b10ebb4d2a3..e1f7a9030e2 100644
--- a/spec/support/shared_examples/mailers/notify_shared_examples.rb
+++ b/spec/support/shared_examples/mailers/notify_shared_examples.rb
@@ -2,7 +2,7 @@
RSpec.shared_examples 'a multiple recipients email' do
it 'is sent to the given recipient' do
- is_expected.to deliver_to recipient.notification_email
+ is_expected.to deliver_to recipient.notification_email_or_default
end
end
@@ -21,7 +21,7 @@ end
RSpec.shared_examples 'an email sent to a user' do
it 'is sent to user\'s global notification email address' do
- expect(subject).to deliver_to(recipient.notification_email)
+ expect(subject).to deliver_to(recipient.notification_email_or_default)
end
context 'with group notification email' do
@@ -227,7 +227,7 @@ RSpec.shared_examples 'a note email' do
aggregate_failures do
expect(sender.display_name).to eq("#{note_author.name} (@#{note_author.username})")
expect(sender.address).to eq(gitlab_sender)
- expect(subject).to deliver_to(recipient.notification_email)
+ expect(subject).to deliver_to(recipient.notification_email_or_default)
end
end
diff --git a/spec/support/shared_examples/models/concerns/featurable_shared_examples.rb b/spec/support/shared_examples/models/concerns/featurable_shared_examples.rb
new file mode 100644
index 00000000000..2f165ef604f
--- /dev/null
+++ b/spec/support/shared_examples/models/concerns/featurable_shared_examples.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'access level validation' do |features|
+ features.each do |feature|
+ it "does not allow public access level for #{feature}" do
+ field = "#{feature}_access_level".to_sym
+ container_features.update_attribute(field, ProjectFeature::PUBLIC)
+
+ expect(container_features.valid?).to be_falsy, "#{field} failed"
+ end
+ end
+end
diff --git a/spec/support/shared_examples/models/concerns/sanitizable_shared_examples.rb b/spec/support/shared_examples/models/concerns/sanitizable_shared_examples.rb
new file mode 100644
index 00000000000..ed94a71892d
--- /dev/null
+++ b/spec/support/shared_examples/models/concerns/sanitizable_shared_examples.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'sanitizable' do |factory, fields|
+ let(:attributes) { fields.to_h { |field| [field, input] } }
+
+ it 'includes Sanitizable' do
+ expect(described_class).to include(Sanitizable)
+ end
+
+ fields.each do |field|
+ subject do
+ record = build(factory, attributes)
+ record.valid?
+
+ record.public_send(field)
+ end
+
+ describe "##{field}" do
+ context 'when input includes javascript tags' do
+ let(:input) { 'hello<script>alert(1)</script>' }
+
+ it 'gets sanitized' do
+ expect(subject).to eq('hello')
+ end
+ end
+ end
+
+ describe "##{field} validation" do
+ context 'when input contains pre-escaped html entities' do
+ let_it_be(:input) { '&lt;script&gt;alert(1)&lt;/script&gt;' }
+
+ subject { build(factory, attributes) }
+
+ it 'is not valid', :aggregate_failures do
+ expect(subject).not_to be_valid
+ expect(subject.errors.details[field].flat_map(&:values)).to include('cannot contain escaped HTML entities')
+ end
+ end
+ end
+ end
+end
diff --git a/spec/support/shared_examples/models/member_shared_examples.rb b/spec/support/shared_examples/models/member_shared_examples.rb
index c111d250d34..56c202cb228 100644
--- a/spec/support/shared_examples/models/member_shared_examples.rb
+++ b/spec/support/shared_examples/models/member_shared_examples.rb
@@ -300,8 +300,21 @@ RSpec.shared_examples_for "member creation" do
end
end
end
+end
+
+RSpec.shared_examples_for "bulk member creation" do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:admin) { create(:admin) }
+
+ describe '#execute' do
+ it 'raises an error when exiting_members is not passed in the args hash' do
+ expect do
+ described_class.new(source, user, :maintainer, current_user: user).execute
+ end.to raise_error(ArgumentError, 'existing_members must be included in the args hash')
+ end
+ end
- describe '.add_users' do
+ describe '.add_users', :aggregate_failures do
let_it_be(:user1) { create(:user) }
let_it_be(:user2) { create(:user) }
@@ -310,8 +323,8 @@ RSpec.shared_examples_for "member creation" do
expect(members).to be_a Array
expect(members.size).to eq(2)
- expect(members.first).to be_a member_type
- expect(members.first).to be_persisted
+ expect(members).to all(be_a(member_type))
+ expect(members).to all(be_persisted)
end
it 'returns an empty array' do
@@ -329,5 +342,42 @@ RSpec.shared_examples_for "member creation" do
expect(members.size).to eq(4)
expect(members.first).to be_invite
end
+
+ context 'with de-duplication' do
+ it 'with the same user by id and user' do
+ members = described_class.add_users(source, [user1.id, user1, user1.id, user2, user2.id, user2], :maintainer)
+
+ expect(members).to be_a Array
+ expect(members.size).to eq(2)
+ expect(members).to all(be_a(member_type))
+ expect(members).to all(be_persisted)
+ end
+
+ it 'with the same user sent more than once' do
+ members = described_class.add_users(source, [user1, user1], :maintainer)
+
+ expect(members).to be_a Array
+ expect(members.size).to eq(1)
+ expect(members).to all(be_a(member_type))
+ expect(members).to all(be_persisted)
+ end
+ end
+
+ context 'when a member already exists' do
+ before do
+ source.add_user(user1, :developer)
+ end
+
+ it 'supports existing users as expected' do
+ user3 = create(:user)
+
+ members = described_class.add_users(source, [user1.id, user2, user3.id], :maintainer)
+
+ expect(members).to be_a Array
+ expect(members.size).to eq(3)
+ expect(members).to all(be_a(member_type))
+ expect(members).to all(be_persisted)
+ end
+ end
end
end
diff --git a/spec/support/shared_examples/models/mentionable_shared_examples.rb b/spec/support/shared_examples/models/mentionable_shared_examples.rb
index 07c5f730e95..e23658d1774 100644
--- a/spec/support/shared_examples/models/mentionable_shared_examples.rb
+++ b/spec/support/shared_examples/models/mentionable_shared_examples.rb
@@ -207,7 +207,7 @@ RSpec.shared_examples 'an editable mentionable' do
end
RSpec.shared_examples 'mentions in description' do |mentionable_type|
- shared_examples 'when storing user mentions' do
+ context 'when storing user mentions' do
before do
mentionable.store_mentions!
end
@@ -238,26 +238,10 @@ RSpec.shared_examples 'mentions in description' do |mentionable_type|
end
end
end
-
- context 'when store_mentions_without_subtransaction is enabled' do
- before do
- stub_feature_flags(store_mentions_without_subtransaction: true)
- end
-
- it_behaves_like 'when storing user mentions'
- end
-
- context 'when store_mentions_without_subtransaction is disabled' do
- before do
- stub_feature_flags(store_mentions_without_subtransaction: false)
- end
-
- it_behaves_like 'when storing user mentions'
- end
end
RSpec.shared_examples 'mentions in notes' do |mentionable_type|
- shared_examples 'when mentionable notes contain mentions' do
+ context 'when mentionable notes contain mentions' do
let(:user) { create(:user) }
let(:user2) { create(:user) }
let(:group) { create(:group) }
@@ -277,22 +261,6 @@ RSpec.shared_examples 'mentions in notes' do |mentionable_type|
expect(mentionable.referenced_groups(user)).to eq [group]
end
end
-
- context 'when store_mentions_without_subtransaction is enabled' do
- before do
- stub_feature_flags(store_mentions_without_subtransaction: true)
- end
-
- it_behaves_like 'when mentionable notes contain mentions'
- end
-
- context 'when store_mentions_without_subtransaction is disabled' do
- before do
- stub_feature_flags(store_mentions_without_subtransaction: false)
- end
-
- it_behaves_like 'when mentionable notes contain mentions'
- end
end
RSpec.shared_examples 'load mentions from DB' do |mentionable_type|
diff --git a/spec/support/shared_examples/namespaces/traversal_scope_examples.rb b/spec/support/shared_examples/namespaces/traversal_scope_examples.rb
index 4d328c03641..74b1bacc560 100644
--- a/spec/support/shared_examples/namespaces/traversal_scope_examples.rb
+++ b/spec/support/shared_examples/namespaces/traversal_scope_examples.rb
@@ -31,6 +31,131 @@ RSpec.shared_examples 'namespace traversal scopes' do
it { expect(subject.where_values_hash).not_to have_key(:type) }
end
+ describe '.order_by_depth' do
+ subject { described_class.where(id: [group_1, nested_group_1, deep_nested_group_1]).order_by_depth(direction) }
+
+ context 'ascending' do
+ let(:direction) { :asc }
+
+ it { is_expected.to eq [deep_nested_group_1, nested_group_1, group_1] }
+ end
+
+ context 'descending' do
+ let(:direction) { :desc }
+
+ it { is_expected.to eq [group_1, nested_group_1, deep_nested_group_1] }
+ end
+ end
+
+ describe '.normal_select' do
+ let(:query_result) { described_class.where(id: group_1).normal_select }
+
+ subject { query_result.column_names }
+
+ it { is_expected.to eq described_class.column_names }
+ end
+
+ shared_examples '.self_and_ancestors' do
+ subject { described_class.where(id: [nested_group_1, nested_group_2]).self_and_ancestors }
+
+ it { is_expected.to contain_exactly(group_1, nested_group_1, group_2, nested_group_2) }
+
+ context 'when include_self is false' do
+ subject { described_class.where(id: [nested_group_1, nested_group_2]).self_and_ancestors(include_self: false) }
+
+ it { is_expected.to contain_exactly(group_1, group_2) }
+ end
+
+ context 'when hierarchy_order is ascending' do
+ subject { described_class.where(id: [nested_group_1, nested_group_2]).self_and_ancestors(hierarchy_order: :asc) }
+
+ # Recursive order per level is not defined.
+ it { is_expected.to contain_exactly(nested_group_1, nested_group_2, group_1, group_2) }
+ it { expect(subject[0, 2]).to contain_exactly(nested_group_1, nested_group_2) }
+ it { expect(subject[2, 2]).to contain_exactly(group_1, group_2) }
+ end
+
+ context 'when hierarchy_order is descending' do
+ subject { described_class.where(id: [nested_group_1, nested_group_2]).self_and_ancestors(hierarchy_order: :desc) }
+
+ # Recursive order per level is not defined.
+ it { is_expected.to contain_exactly(nested_group_1, nested_group_2, group_1, group_2) }
+ it { expect(subject[0, 2]).to contain_exactly(group_1, group_2) }
+ it { expect(subject[2, 2]).to contain_exactly(nested_group_1, nested_group_2) }
+ end
+ end
+
+ describe '.self_and_ancestors' do
+ context "use_traversal_ids_ancestor_scopes feature flag is true" do
+ before do
+ stub_feature_flags(use_traversal_ids: true)
+ stub_feature_flags(use_traversal_ids_for_ancestor_scopes: true)
+ end
+
+ it_behaves_like '.self_and_ancestors'
+
+ it 'not make recursive queries' do
+ expect { described_class.where(id: [nested_group_1]).self_and_ancestors.load }.not_to make_queries_matching(/WITH RECURSIVE/)
+ end
+ end
+
+ context "use_traversal_ids_ancestor_scopes feature flag is false" do
+ before do
+ stub_feature_flags(use_traversal_ids_for_ancestor_scopes: false)
+ end
+
+ it_behaves_like '.self_and_ancestors'
+
+ it 'make recursive queries' do
+ expect { described_class.where(id: [nested_group_1]).self_and_ancestors.load }.to make_queries_matching(/WITH RECURSIVE/)
+ end
+ end
+ end
+
+ shared_examples '.self_and_ancestor_ids' do
+ subject { described_class.where(id: [nested_group_1, nested_group_2]).self_and_ancestor_ids.pluck(:id) }
+
+ it { is_expected.to contain_exactly(group_1.id, nested_group_1.id, group_2.id, nested_group_2.id) }
+
+ context 'when include_self is false' do
+ subject do
+ described_class
+ .where(id: [nested_group_1, nested_group_2])
+ .self_and_ancestor_ids(include_self: false)
+ .pluck(:id)
+ end
+
+ it { is_expected.to contain_exactly(group_1.id, group_2.id) }
+ end
+ end
+
+ describe '.self_and_ancestor_ids' do
+ context "use_traversal_ids_ancestor_scopes feature flag is true" do
+ before do
+ stub_feature_flags(use_traversal_ids: true)
+ stub_feature_flags(use_traversal_ids_for_ancestor_scopes: true)
+ end
+
+ it_behaves_like '.self_and_ancestor_ids'
+
+ it 'make recursive queries' do
+ expect { described_class.where(id: [nested_group_1]).self_and_ancestor_ids.load }.not_to make_queries_matching(/WITH RECURSIVE/)
+ end
+ end
+
+ context "use_traversal_ids_ancestor_scopes feature flag is false" do
+ before do
+ stub_feature_flags(use_traversal_ids_for_ancestor_scopes: false)
+ end
+
+ it_behaves_like '.self_and_ancestor_ids'
+
+ it 'make recursive queries' do
+ expect { described_class.where(id: [nested_group_1]).self_and_ancestor_ids.load }.to make_queries_matching(/WITH RECURSIVE/)
+ end
+ end
+ end
+
describe '.self_and_descendants' do
subject { described_class.where(id: [nested_group_1, nested_group_2]).self_and_descendants }
diff --git a/spec/support/shared_examples/requests/api/helm_packages_shared_examples.rb b/spec/support/shared_examples/requests/api/helm_packages_shared_examples.rb
index 1ad38a17f9c..acbcf4f7f3d 100644
--- a/spec/support/shared_examples/requests/api/helm_packages_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/helm_packages_shared_examples.rb
@@ -36,8 +36,8 @@ RSpec.shared_examples 'process helm service index request' do |user_type, status
expect(yaml_response.keys).to contain_exactly('apiVersion', 'entries', 'generated', 'serverInfo')
expect(yaml_response['entries']).to be_a(Hash)
- expect(yaml_response['entries'].keys).to contain_exactly(package.name)
- expect(yaml_response['serverInfo']).to eq({ 'contextPath' => "/api/v4/projects/#{project.id}/packages/helm" })
+ expect(yaml_response['entries'].keys).to contain_exactly(package.name, package2.name)
+ expect(yaml_response['serverInfo']).to eq({ 'contextPath' => "/api/v4/projects/#{project_id}/packages/helm" })
package_entry = yaml_response['entries'][package.name]
@@ -45,6 +45,14 @@ RSpec.shared_examples 'process helm service index request' do |user_type, status
expect(package_entry.first.keys).to contain_exactly('name', 'version', 'apiVersion', 'created', 'digest', 'urls')
expect(package_entry.first['digest']).to eq('fd2b2fa0329e80a2a602c2bb3b40608bcd6ee5cf96cf46fd0d2800a4c129c9db')
expect(package_entry.first['urls']).to eq(["charts/#{package.name}-#{package.version}.tgz"])
+
+ package_entry = yaml_response['entries'][package2.name]
+
+ expect(package_entry.length).to eq(1)
+ expect(package_entry.first.keys).to contain_exactly('name', 'version', 'apiVersion', 'created', 'digest', 'urls', 'description')
+ expect(package_entry.first['digest']).to eq('file2')
+ expect(package_entry.first['description']).to eq('hello from stable channel')
+ expect(package_entry.first['urls']).to eq(['charts/filename2.tgz'])
end
end
end
@@ -174,6 +182,13 @@ RSpec.shared_examples 'process helm download content request' do |user_type, sta
context "for user type #{user_type}" do
before do
project.send("add_#{user_type}", user) if user_type != :anonymous && user_type != :not_a_member
+
+ expect_next_found_instance_of(::Packages::PackageFile) do |package_file|
+ expect(package_file).to receive(:file).and_wrap_original do |m, *args|
+ expect(package_file.id).to eq(package_file2.id)
+ m.call(*args)
+ end
+ end
end
it_behaves_like 'a package tracking event', 'API::HelmPackages', 'pull_package'
@@ -189,7 +204,7 @@ end
RSpec.shared_examples 'rejects helm access with unknown project id' do
context 'with an unknown project' do
- let(:project) { OpenStruct.new(id: 1234567890) }
+ let(:project_id) { 1234567890 }
context 'as anonymous' do
it_behaves_like 'rejects helm packages access', :anonymous, :unauthorized
diff --git a/spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb b/spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb
index 0390e60747f..2af7b616659 100644
--- a/spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb
@@ -21,11 +21,24 @@ RSpec.shared_examples 'handling get metadata requests' do |scope: :project|
expect(response).to match_response_schema('public_api/v4/packages/npm_package')
expect(json_response['name']).to eq(package.name)
expect(json_response['versions'][package.version]).to match_schema('public_api/v4/packages/npm_package_version')
- ::Packages::Npm::PackagePresenter::NPM_VALID_DEPENDENCY_TYPES.each do |dependency_type|
+ ::Packages::DependencyLink.dependency_types.keys.each do |dependency_type|
expect(json_response.dig('versions', package.version, dependency_type.to_s)).to be_any
end
expect(json_response['dist-tags']).to match_schema('public_api/v4/packages/npm_package_tags')
end
+
+ it 'avoids N+1 database queries' do
+ control = ActiveRecord::QueryRecorder.new { get(url, headers: headers) }
+
+ create_list(:npm_package, 5, project: project, name: package_name).each do |npm_package|
+ ::Packages::DependencyLink.dependency_types.keys.each do |dependency_type|
+ create(:packages_dependency_link, package: package, dependency_type: dependency_type)
+ end
+ end
+
+ # query count can slightly change between the examples so we're using a custom threshold
+ expect { get(url, headers: headers) }.not_to exceed_query_limit(control).with_threshold(4)
+ end
end
shared_examples 'reject metadata request' do |status:|
diff --git a/spec/support/shared_examples/requests/api/packages_shared_examples.rb b/spec/support/shared_examples/requests/api/packages_shared_examples.rb
index ecde4ee8565..eb650b7a09f 100644
--- a/spec/support/shared_examples/requests/api/packages_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/packages_shared_examples.rb
@@ -153,3 +153,15 @@ RSpec.shared_examples 'a package tracking event' do |category, action|
expect_snowplow_event(category: category, action: action, **snowplow_gitlab_standard_context)
end
end
+
+RSpec.shared_examples 'not a package tracking event' do
+ before do
+ stub_feature_flags(collect_package_events: true)
+ end
+
+ it 'does not create a gitlab tracking event', :snowplow, :aggregate_failures do
+ expect { subject }.not_to change { Packages::Event.count }
+
+ expect_no_snowplow_event
+ end
+end
diff --git a/spec/support/shared_examples/requests/rack_attack_shared_examples.rb b/spec/support/shared_examples/requests/rack_attack_shared_examples.rb
index 95817624658..2a19ff6f590 100644
--- a/spec/support/shared_examples/requests/rack_attack_shared_examples.rb
+++ b/spec/support/shared_examples/requests/rack_attack_shared_examples.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
#
# Requires let variables:
-# * throttle_setting_prefix: "throttle_authenticated_api", "throttle_authenticated_web", "throttle_protected_paths", "throttle_authenticated_packages_api"
+# * throttle_setting_prefix: "throttle_authenticated_api", "throttle_authenticated_web", "throttle_protected_paths", "throttle_authenticated_packages_api", "throttle_authenticated_git_lfs", "throttle_authenticated_files_api"
# * request_method
# * request_args
# * other_user_request_args
@@ -14,7 +14,9 @@ RSpec.shared_examples 'rate-limited token-authenticated requests' do
"throttle_protected_paths" => "throttle_authenticated_protected_paths_api",
"throttle_authenticated_api" => "throttle_authenticated_api",
"throttle_authenticated_web" => "throttle_authenticated_web",
- "throttle_authenticated_packages_api" => "throttle_authenticated_packages_api"
+ "throttle_authenticated_packages_api" => "throttle_authenticated_packages_api",
+ "throttle_authenticated_git_lfs" => "throttle_authenticated_git_lfs",
+ "throttle_authenticated_files_api" => "throttle_authenticated_files_api"
}
end
@@ -165,7 +167,7 @@ RSpec.shared_examples 'rate-limited token-authenticated requests' do
end
# Requires let variables:
-# * throttle_setting_prefix: "throttle_authenticated_web" or "throttle_protected_paths"
+# * throttle_setting_prefix: "throttle_authenticated_web", "throttle_protected_paths", "throttle_authenticated_git_lfs"
# * user
# * url_that_requires_authentication
# * request_method
@@ -176,7 +178,8 @@ RSpec.shared_examples 'rate-limited web authenticated requests' do
let(:throttle_types) do
{
"throttle_protected_paths" => "throttle_authenticated_protected_paths_web",
- "throttle_authenticated_web" => "throttle_authenticated_web"
+ "throttle_authenticated_web" => "throttle_authenticated_web",
+ "throttle_authenticated_git_lfs" => "throttle_authenticated_git_lfs"
}
end
@@ -385,3 +388,194 @@ RSpec.shared_examples 'tracking when dry-run mode is set' do
end
end
end
+
+# Requires let variables:
+# * throttle_name: "throttle_unauthenticated_api", "throttle_unauthenticated_web"
+# * throttle_setting_prefix: "throttle_unauthenticated_api", "throttle_unauthenticated"
+# * url_that_does_not_require_authentication
+# * url_that_is_not_matched
+# * requests_per_period
+# * period_in_seconds
+# * period
+RSpec.shared_examples 'rate-limited unauthenticated requests' do
+ before do
+ # Set low limits
+ settings_to_set[:"#{throttle_setting_prefix}_requests_per_period"] = requests_per_period
+ settings_to_set[:"#{throttle_setting_prefix}_period_in_seconds"] = period_in_seconds
+ end
+
+ context 'when the throttle is enabled' do
+ before do
+ settings_to_set[:"#{throttle_setting_prefix}_enabled"] = true
+ stub_application_setting(settings_to_set)
+ end
+
+ it 'rejects requests over the rate limit' do
+ # At first, allow requests under the rate limit.
+ requests_per_period.times do
+ get url_that_does_not_require_authentication
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ # the last straw
+ expect_rejection { get url_that_does_not_require_authentication }
+ end
+
+ context 'with custom response text' do
+ before do
+ stub_application_setting(rate_limiting_response_text: 'Custom response')
+ end
+
+ it 'rejects requests over the rate limit' do
+ # At first, allow requests under the rate limit.
+ requests_per_period.times do
+ get url_that_does_not_require_authentication
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ # the last straw
+ expect_rejection { get url_that_does_not_require_authentication }
+ expect(response.body).to eq("Custom response\n")
+ end
+ end
+
+ it 'allows requests after throttling and then waiting for the next period' do
+ requests_per_period.times do
+ get url_that_does_not_require_authentication
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ expect_rejection { get url_that_does_not_require_authentication }
+
+ travel_to(period.from_now) do
+ requests_per_period.times do
+ get url_that_does_not_require_authentication
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ expect_rejection { get url_that_does_not_require_authentication }
+ end
+ end
+
+ it 'counts requests from different IPs separately' do
+ requests_per_period.times do
+ get url_that_does_not_require_authentication
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ expect_next_instance_of(Rack::Attack::Request) do |instance|
+ expect(instance).to receive(:ip).at_least(:once).and_return('1.2.3.4')
+ end
+
+ # would be over limit for the same IP
+ get url_that_does_not_require_authentication
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ context 'when the request is not matched by the throttle' do
+ it 'does not throttle the requests' do
+ (1 + requests_per_period).times do
+ get url_that_is_not_matched
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+ end
+
+ context 'when the request is to the api internal endpoints' do
+ it 'allows requests over the rate limit' do
+ (1 + requests_per_period).times do
+ get '/api/v4/internal/check', params: { secret_token: Gitlab::Shell.secret_token }
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+ end
+
+ context 'when the request is authenticated by a runner token' do
+ let(:request_jobs_url) { '/api/v4/jobs/request' }
+ let(:runner) { create(:ci_runner) }
+
+ it 'does not count as unauthenticated' do
+ (1 + requests_per_period).times do
+ post request_jobs_url, params: { token: runner.token }
+ expect(response).to have_gitlab_http_status(:no_content)
+ end
+ end
+ end
+
+ context 'when the request is to a health endpoint' do
+ let(:health_endpoint) { '/-/metrics' }
+
+ it 'does not throttle the requests' do
+ (1 + requests_per_period).times do
+ get health_endpoint
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+ end
+
+ context 'when the request is to a container registry notification endpoint' do
+ let(:secret_token) { 'secret_token' }
+ let(:events) { [{ action: 'push' }] }
+ let(:registry_endpoint) { '/api/v4/container_registry_event/events' }
+ let(:registry_headers) { { 'Content-Type' => ::API::ContainerRegistryEvent::DOCKER_DISTRIBUTION_EVENTS_V1_JSON } }
+
+ before do
+ allow(Gitlab.config.registry).to receive(:notification_secret) { secret_token }
+
+ event = spy(:event)
+ allow(::ContainerRegistry::Event).to receive(:new).and_return(event)
+ allow(event).to receive(:supported?).and_return(true)
+ end
+
+ it 'does not throttle the requests' do
+ (1 + requests_per_period).times do
+ post registry_endpoint,
+ params: { events: events }.to_json,
+ headers: registry_headers.merge('Authorization' => secret_token)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+ end
+
+ it 'logs RackAttack info into structured logs' do
+ requests_per_period.times do
+ get url_that_does_not_require_authentication
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ arguments = a_hash_including({
+ message: 'Rack_Attack',
+ env: :throttle,
+ remote_ip: '127.0.0.1',
+ request_method: 'GET',
+ path: url_that_does_not_require_authentication,
+ matched: throttle_name
+ })
+
+ expect(Gitlab::AuthLogger).to receive(:error).with(arguments)
+
+ get url_that_does_not_require_authentication
+ end
+
+ it_behaves_like 'tracking when dry-run mode is set' do
+ def do_request
+ get url_that_does_not_require_authentication
+ end
+ end
+ end
+
+ context 'when the throttle is disabled' do
+ before do
+ settings_to_set[:"#{throttle_setting_prefix}_enabled"] = false
+ stub_application_setting(settings_to_set)
+ end
+
+ it 'allows requests over the rate limit' do
+ (1 + requests_per_period).times do
+ get url_that_does_not_require_authentication
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+ end
+end
diff --git a/spec/support/shared_examples/services/dependency_proxy_ttl_policies_shared_examples.rb b/spec/support/shared_examples/services/dependency_proxy_ttl_policies_shared_examples.rb
new file mode 100644
index 00000000000..f6692646ca8
--- /dev/null
+++ b/spec/support/shared_examples/services/dependency_proxy_ttl_policies_shared_examples.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'updating the dependency proxy image ttl policy attributes' do |from: {}, to:|
+ it_behaves_like 'not creating the dependency proxy image ttl policy'
+
+ it 'updates the dependency proxy image ttl policy' do
+ expect { subject }
+ .to change { group.dependency_proxy_image_ttl_policy.reload.enabled }.from(from[:enabled]).to(to[:enabled])
+ .and change { group.dependency_proxy_image_ttl_policy.reload.ttl }.from(from[:ttl]).to(to[:ttl])
+ end
+end
+
+RSpec.shared_examples 'not creating the dependency proxy image ttl policy' do
+ it "doesn't create the dependency proxy image ttl policy" do
+ expect { subject }.not_to change { DependencyProxy::ImageTtlGroupPolicy.count }
+ end
+end
+
+RSpec.shared_examples 'creating the dependency proxy image ttl policy' do
+ it 'creates a new package setting' do
+ expect { subject }.to change { DependencyProxy::ImageTtlGroupPolicy.count }.by(1)
+ end
+
+ it 'saves the settings' do
+ subject
+
+ expect(group.dependency_proxy_image_ttl_policy).to have_attributes(
+ enabled: ttl_policy[:enabled],
+ ttl: ttl_policy[:ttl]
+ )
+ end
+
+ it_behaves_like 'returning a success'
+end
diff --git a/spec/support/shared_examples/services/incident_shared_examples.rb b/spec/support/shared_examples/services/incident_shared_examples.rb
index 9fced12b543..0277cce975a 100644
--- a/spec/support/shared_examples/services/incident_shared_examples.rb
+++ b/spec/support/shared_examples/services/incident_shared_examples.rb
@@ -13,6 +13,7 @@
RSpec.shared_examples 'incident issue' do
it 'has incident as issue type' do
expect(issue.issue_type).to eq('incident')
+ expect(issue.work_item_type.base_type).to eq('incident')
end
end
@@ -41,6 +42,7 @@ RSpec.shared_examples 'not an incident issue' do
it 'has not incident as issue type' do
expect(issue.issue_type).not_to eq('incident')
+ expect(issue.work_item_type.base_type).not_to eq('incident')
end
it 'has not an incident label' do
diff --git a/spec/support/shared_examples/services/users/dismiss_user_callout_service_shared_examples.rb b/spec/support/shared_examples/services/users/dismiss_user_callout_service_shared_examples.rb
new file mode 100644
index 00000000000..09820593cdb
--- /dev/null
+++ b/spec/support/shared_examples/services/users/dismiss_user_callout_service_shared_examples.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples_for 'dismissing user callout' do |model|
+ it 'creates a new user callout' do
+ expect { execute }.to change { model.count }.by(1)
+ end
+
+ it 'returns a user callout' do
+ expect(execute).to be_an_instance_of(model)
+ end
+
+ it 'sets the dismissed_at attribute to current time' do
+ freeze_time do
+ expect(execute).to have_attributes(dismissed_at: Time.current)
+ end
+ end
+
+ it 'updates an existing callout dismissed_at time' do
+ freeze_time do
+ old_time = 1.day.ago
+ new_time = Time.current
+ attributes = params.merge(dismissed_at: old_time, user: user)
+ existing_callout = create("#{model.name.split('::').last.underscore}".to_sym, attributes)
+
+ expect { execute }.to change { existing_callout.reload.dismissed_at }.from(old_time).to(new_time)
+ end
+ end
+
+ it 'does not update an invalid record with dismissed_at time', :aggregate_failures do
+ callout = described_class.new(
+ container: nil, current_user: user, params: { feature_name: nil }
+ ).execute
+
+ expect(callout.dismissed_at).to be_nil
+ expect(callout).to be_invalid
+ end
+end
diff --git a/spec/support/shared_examples/work_item_base_types_importer.rb b/spec/support/shared_examples/work_item_base_types_importer.rb
new file mode 100644
index 00000000000..7d652be8d05
--- /dev/null
+++ b/spec/support/shared_examples/work_item_base_types_importer.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'work item base types importer' do
+ it 'creates all base work item types' do
+ # Fixtures need to run on a pristine DB, but the test suite preloads the base types before(:suite)
+ WorkItem::Type.delete_all
+
+ expect { subject }.to change(WorkItem::Type, :count).from(0).to(WorkItem::Type::BASE_TYPES.count)
+ end
+end
diff --git a/spec/support_specs/database/prevent_cross_database_modification_spec.rb b/spec/support_specs/database/prevent_cross_database_modification_spec.rb
index 4fd55d59db0..e86559bb14a 100644
--- a/spec/support_specs/database/prevent_cross_database_modification_spec.rb
+++ b/spec/support_specs/database/prevent_cross_database_modification_spec.rb
@@ -66,7 +66,7 @@ RSpec.describe 'Database::PreventCrossDatabaseModification' do
pipeline.touch
end
end
- end.to raise_error /Cross-database data modification queries/
+ end.to raise_error /Cross-database data modification/
end
end
@@ -84,7 +84,7 @@ RSpec.describe 'Database::PreventCrossDatabaseModification' do
context 'when data modification happens in a transaction' do
it 'raises error' do
Project.transaction do
- expect { run_queries }.to raise_error /Cross-database data modification queries/
+ expect { run_queries }.to raise_error /Cross-database data modification/
end
end
@@ -93,12 +93,31 @@ RSpec.describe 'Database::PreventCrossDatabaseModification' do
Project.transaction(requires_new: true) do
project.touch
Project.transaction(requires_new: true) do
- expect { pipeline.touch }.to raise_error /Cross-database data modification queries/
+ expect { pipeline.touch }.to raise_error /Cross-database data modification/
end
end
end
end
end
+
+ context 'when executing a SELECT FOR UPDATE query' do
+ def run_queries
+ project.touch
+ pipeline.lock!
+ end
+
+ context 'outside transaction' do
+ it { expect { run_queries }.not_to raise_error }
+ end
+
+ context 'when data modification happens in a transaction' do
+ it 'raises error' do
+ Project.transaction do
+ expect { run_queries }.to raise_error /Cross-database data modification/
+ end
+ end
+ end
+ end
end
context 'when CI association is modified through project' do
@@ -127,7 +146,7 @@ RSpec.describe 'Database::PreventCrossDatabaseModification' do
ApplicationRecord.transaction do
create(:ci_pipeline)
end
- end.to raise_error /Cross-database data modification queries/
+ end.to raise_error /Cross-database data modification/
end
it 'skips raising error on factory creation' do
diff --git a/spec/support_specs/database/prevent_cross_joins_spec.rb b/spec/support_specs/database/prevent_cross_joins_spec.rb
index dd4ed9c40b8..e9a95fe77a5 100644
--- a/spec/support_specs/database/prevent_cross_joins_spec.rb
+++ b/spec/support_specs/database/prevent_cross_joins_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Database::PreventCrossJoins do
- context 'when running in :prevent_cross_joins scope', :prevent_cross_joins do
+ context 'when running in a default scope' do
context 'when only non-CI tables are used' do
it 'does not raise exception' do
expect { main_only_query }.not_to raise_error
@@ -24,23 +24,33 @@ RSpec.describe Database::PreventCrossJoins do
context 'when allow_cross_joins_across_databases is used' do
it 'does not raise exception' do
- Gitlab::Database.allow_cross_joins_across_databases(url: 'http://issue-url')
+ expect { main_and_ci_query_allowlisted }.not_to raise_error
+ end
+ end
- expect { main_and_ci_query }.not_to raise_error
+ context 'when allow_cross_joins_across_databases is used' do
+ it 'does not raise exception' do
+ expect { main_and_ci_query_allowlist_nested }.not_to raise_error
end
end
end
end
- context 'when running in a default scope' do
- context 'when CI and non-CI tables are used' do
- it 'does not raise exception' do
- expect { main_and_ci_query }.not_to raise_error
- end
+ private
+
+ def main_and_ci_query_allowlisted
+ Gitlab::Database.allow_cross_joins_across_databases(url: 'http://issue-url') do
+ main_and_ci_query
end
end
- private
+ def main_and_ci_query_allowlist_nested
+ Gitlab::Database.allow_cross_joins_across_databases(url: 'http://issue-url') do
+ main_and_ci_query_allowlisted
+
+ main_and_ci_query
+ end
+ end
def main_only_query
Issue.joins(:project).last
diff --git a/spec/tasks/gitlab/db_rake_spec.rb b/spec/tasks/gitlab/db_rake_spec.rb
index 8e98a42510e..91cd09fc6e6 100644
--- a/spec/tasks/gitlab/db_rake_spec.rb
+++ b/spec/tasks/gitlab/db_rake_spec.rb
@@ -129,13 +129,14 @@ RSpec.describe 'gitlab:db namespace rake task', :silence_stdout do
let(:output) { StringIO.new }
before do
- structure_files = %w[db/structure.sql db/ci_structure.sql]
+ structure_files = %w[structure.sql ci_structure.sql]
allow(File).to receive(:open).and_call_original
- structure_files.each do |structure_file|
+ structure_files.each do |structure_file_name|
+ structure_file = File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, structure_file_name)
stub_file_read(structure_file, content: input)
- allow(File).to receive(:open).with(Rails.root.join(structure_file).to_s, any_args).and_yield(output)
+ allow(File).to receive(:open).with(structure_file.to_s, any_args).and_yield(output)
end
end
diff --git a/spec/tasks/gitlab/product_intelligence_rake_spec.rb b/spec/tasks/gitlab/product_intelligence_rake_spec.rb
deleted file mode 100644
index 029e181ad06..00000000000
--- a/spec/tasks/gitlab/product_intelligence_rake_spec.rb
+++ /dev/null
@@ -1,80 +0,0 @@
-# frozen_string_literal: true
-
-require 'rake_helper'
-
-RSpec.describe 'gitlab:product_intelligence:activate_metrics', :silence_stdout do
- def fake_metric(key_path, milestone: 'test_milestone', status: 'implemented')
- Gitlab::Usage::MetricDefinition.new(key_path, { key_path: key_path, milestone: milestone, status: status })
- end
-
- before do
- Rake.application.rake_require 'tasks/gitlab/product_intelligence'
- stub_warn_user_is_not_gitlab
- end
-
- describe 'activate_metrics' do
- it 'fails if the MILESTONE env var is not set' do
- stub_env('MILESTONE' => nil)
-
- expect { run_rake_task('gitlab:product_intelligence:activate_metrics') }.to raise_error(RuntimeError, 'Please supply the MILESTONE env var')
- end
-
- context 'with MILESTONE env var' do
- subject do
- updated_metrics = []
-
- file = double('file')
- allow(file).to receive(:<<) { |contents| updated_metrics << YAML.safe_load(contents) }
- allow(File).to receive(:open).and_yield(file)
-
- stub_env('MILESTONE' => 'test_milestone')
- run_rake_task('gitlab:product_intelligence:activate_metrics')
-
- updated_metrics
- end
-
- let(:metric_definitions) do
- {
- matching_metric: fake_metric('matching_metric'),
- matching_metric2: fake_metric('matching_metric2'),
- other_status_metric: fake_metric('other_status_metric', status: 'deprecated'),
- other_milestone_metric: fake_metric('other_milestone_metric', milestone: 'other_milestone')
- }
- end
-
- before do
- allow(Gitlab::Usage::MetricDefinition).to receive(:definitions).and_return(metric_definitions)
- end
-
- context 'with metric matching status and milestone' do
- it 'updates matching_metric yaml file' do
- expect(subject).to eq([
- { 'key_path' => 'matching_metric', 'milestone' => 'test_milestone', 'status' => 'data_available' },
- { 'key_path' => 'matching_metric2', 'milestone' => 'test_milestone', 'status' => 'data_available' }
- ])
- end
- end
-
- context 'without metrics definitions' do
- let(:metric_definitions) { {} }
-
- it 'runs successfully with no updates' do
- expect(subject).to eq([])
- end
- end
-
- context 'without matching metrics' do
- let(:metric_definitions) do
- {
- other_status_metric: fake_metric('other_status_metric', status: 'deprecated'),
- other_milestone_metric: fake_metric('other_milestone_metric', milestone: 'other_milestone')
- }
- end
-
- it 'runs successfully with no updates' do
- expect(subject).to eq([])
- end
- end
- end
- end
-end
diff --git a/spec/tooling/danger/project_helper_spec.rb b/spec/tooling/danger/project_helper_spec.rb
index f52c5e02544..c7715eb43fc 100644
--- a/spec/tooling/danger/project_helper_spec.rb
+++ b/spec/tooling/danger/project_helper_spec.rb
@@ -60,7 +60,6 @@ RSpec.describe Tooling::Danger::ProjectHelper do
'app/views/foo' | [:frontend]
'public/foo' | [:frontend]
'scripts/frontend/foo' | [:frontend]
- 'spec/javascripts/foo' | [:frontend]
'spec/frontend/bar' | [:frontend]
'spec/frontend_integration/bar' | [:frontend]
'vendor/assets/foo' | [:frontend]
@@ -73,7 +72,6 @@ RSpec.describe Tooling::Danger::ProjectHelper do
'ee/app/assets/foo' | [:frontend]
'ee/app/views/foo' | [:frontend]
- 'ee/spec/javascripts/foo' | [:frontend]
'ee/spec/frontend/bar' | [:frontend]
'ee/spec/frontend_integration/bar' | [:frontend]
@@ -220,7 +218,7 @@ RSpec.describe Tooling::Danger::ProjectHelper do
describe '.local_warning_message' do
it 'returns an informational message with rules that can run' do
- expect(described_class.local_warning_message).to eq('==> Only the following Danger rules can be run locally: changelog, database, documentation, duplicate_yarn_dependencies, eslint, gitaly, karma, pajamas, pipeline, prettier, product_intelligence, utility_css, vue_shared_documentation')
+ expect(described_class.local_warning_message).to eq('==> Only the following Danger rules can be run locally: changelog, database, documentation, duplicate_yarn_dependencies, eslint, gitaly, pajamas, pipeline, prettier, product_intelligence, utility_css, vue_shared_documentation')
end
end
diff --git a/spec/tooling/graphql/docs/renderer_spec.rb b/spec/tooling/graphql/docs/renderer_spec.rb
index de5ec928921..1c9605304ff 100644
--- a/spec/tooling/graphql/docs/renderer_spec.rb
+++ b/spec/tooling/graphql/docs/renderer_spec.rb
@@ -535,8 +535,8 @@ RSpec.describe Tooling::Graphql::Docs::Renderer do
| Name | Type | Description |
| ---- | ---- | ----------- |
- | <a id="timeframeend"></a>`end` | [`Date!`](#date) | The end of the range. |
- | <a id="timeframestart"></a>`start` | [`Date!`](#date) | The start of the range. |
+ | <a id="timeframeend"></a>`end` | [`Date!`](#date) | End of the range. |
+ | <a id="timeframestart"></a>`start` | [`Date!`](#date) | Start of the range. |
DOC
end
diff --git a/spec/validators/gitlab/utils/zoom_url_validator_spec.rb b/spec/validators/gitlab/utils/zoom_url_validator_spec.rb
deleted file mode 100644
index 392d8b3a2fe..00000000000
--- a/spec/validators/gitlab/utils/zoom_url_validator_spec.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::Utils::ZoomUrlValidator do
- let(:zoom_meeting) { build(:zoom_meeting) }
-
- describe 'validations' do
- context 'when zoom link starts with https' do
- it 'passes validation' do
- zoom_meeting.url = 'https://zoom.us/j/123456789'
-
- expect(zoom_meeting.valid?).to eq(true)
- expect(zoom_meeting.errors).to be_empty
- end
- end
-
- shared_examples 'zoom link does not start with https' do |url|
- it 'fails validation' do
- zoom_meeting.url = url
- expect(zoom_meeting.valid?).to eq(false)
-
- expect(zoom_meeting.errors).to be_present
- expect(zoom_meeting.errors.added?(:url, 'must contain one valid Zoom URL')).to be true
- end
- end
-
- context 'when zoom link does not start with https' do
- include_examples 'zoom link does not start with https', 'http://zoom.us/j/123456789'
-
- context 'when zoom link does not start with a scheme' do
- include_examples 'zoom link does not start with https', 'testinghttp://zoom.us/j/123456789'
- end
- end
- end
-end
diff --git a/spec/validators/gitlab/zoom_url_validator_spec.rb b/spec/validators/gitlab/zoom_url_validator_spec.rb
new file mode 100644
index 00000000000..308a6be78eb
--- /dev/null
+++ b/spec/validators/gitlab/zoom_url_validator_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::ZoomUrlValidator do
+ let(:zoom_meeting) { build(:zoom_meeting) }
+
+ describe 'validations' do
+ context 'when zoom link starts with https' do
+ it 'passes validation' do
+ zoom_meeting.url = 'https://zoom.us/j/123456789'
+
+ expect(zoom_meeting.valid?).to eq(true)
+ expect(zoom_meeting.errors).to be_empty
+ end
+ end
+
+ shared_examples 'zoom link does not start with https' do |url|
+ it 'fails validation' do
+ zoom_meeting.url = url
+ expect(zoom_meeting.valid?).to eq(false)
+
+ expect(zoom_meeting.errors).to be_present
+ expect(zoom_meeting.errors.added?(:url, 'must contain one valid Zoom URL')).to be true
+ end
+ end
+
+ context 'when zoom link does not start with https' do
+ include_examples 'zoom link does not start with https', 'http://zoom.us/j/123456789'
+
+ context 'when zoom link does not start with a scheme' do
+ include_examples 'zoom link does not start with https', 'testinghttp://zoom.us/j/123456789'
+ end
+ end
+ end
+end
diff --git a/spec/views/groups/group_members/index.html.haml_spec.rb b/spec/views/groups/group_members/index.html.haml_spec.rb
new file mode 100644
index 00000000000..8e190c24495
--- /dev/null
+++ b/spec/views/groups/group_members/index.html.haml_spec.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'groups/group_members/index', :aggregate_failures do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+
+ before do
+ allow(view).to receive(:group_members_app_data).and_return({})
+ allow(view).to receive(:current_user).and_return(user)
+ assign(:group, group)
+ assign(:group_member, build(:group_member, group: group))
+ end
+
+ context 'when user can invite members for the group' do
+ before do
+ group.add_owner(user)
+ end
+
+ context 'when modal is enabled' do
+ it 'renders as expected' do
+ render
+
+ expect(rendered).to have_content('Group members')
+ expect(rendered).to have_content('You can invite a new member')
+
+ expect(rendered).to have_selector('.js-invite-group-trigger')
+ expect(rendered).to have_selector('.js-invite-members-trigger')
+ expect(response).to render_template(partial: 'groups/_invite_members_modal')
+
+ expect(rendered).not_to have_selector('#invite-member-tab')
+ expect(rendered).not_to have_selector('#invite-group-tab')
+ expect(response).not_to render_template(partial: 'shared/members/_invite_group')
+ end
+ end
+
+ context 'when modal is not enabled' do
+ before do
+ stub_feature_flags(invite_members_group_modal: false)
+ end
+
+ it 'renders as expected' do
+ render
+
+ expect(rendered).to have_content('Group members')
+ expect(rendered).to have_content('You can invite a new member')
+
+ expect(rendered).to have_selector('#invite-member-tab')
+ expect(rendered).to have_selector('#invite-group-tab')
+ expect(response).to render_template(partial: 'shared/members/_invite_group')
+
+ expect(rendered).not_to have_selector('.js-invite-group-trigger')
+ expect(rendered).not_to have_selector('.js-invite-members-trigger')
+ expect(response).not_to render_template(partial: 'groups/_invite_members_modal')
+ end
+ end
+ end
+
+ context 'when user can not invite members for the group' do
+ it 'renders as expected', :aggregate_failures do
+ render
+
+ expect(rendered).not_to have_content('Group members')
+ expect(rendered).not_to have_content('You can invite a new member')
+ end
+ end
+end
diff --git a/spec/views/help/instance_configuration.html.haml_spec.rb b/spec/views/help/instance_configuration.html.haml_spec.rb
index 7b431bb4180..c4542046a9d 100644
--- a/spec/views/help/instance_configuration.html.haml_spec.rb
+++ b/spec/views/help/instance_configuration.html.haml_spec.rb
@@ -9,6 +9,7 @@ RSpec.describe 'help/instance_configuration' do
let(:ssh_settings) { settings[:ssh_algorithms_hashes] }
before do
+ create(:plan, name: 'plan1', title: 'Plan 1')
assign(:instance_configuration, instance_configuration)
end
@@ -17,7 +18,9 @@ RSpec.describe 'help/instance_configuration' do
expect(rendered).to have_link(nil, href: '#ssh-host-keys-fingerprints') if ssh_settings.any?
expect(rendered).to have_link(nil, href: '#gitlab-pages')
- expect(rendered).to have_link(nil, href: '#gitlab-ci')
+ expect(rendered).to have_link(nil, href: '#size-limits')
+ expect(rendered).to have_link(nil, href: '#package-registry')
+ expect(rendered).to have_link(nil, href: '#rate-limits')
end
it 'has several sections' do
@@ -25,7 +28,9 @@ RSpec.describe 'help/instance_configuration' do
expect(rendered).to have_css('h2#ssh-host-keys-fingerprints') if ssh_settings.any?
expect(rendered).to have_css('h2#gitlab-pages')
- expect(rendered).to have_css('h2#gitlab-ci')
+ expect(rendered).to have_css('h2#size-limits')
+ expect(rendered).to have_css('h2#package-registry')
+ expect(rendered).to have_css('h2#rate-limits')
end
end
end
diff --git a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
index 3afebfbedab..adfe1cee6d6 100644
--- a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
+++ b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
@@ -68,8 +68,8 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
end
describe 'Learn GitLab' do
- it 'has a link to the learn GitLab experiment' do
- allow(view).to receive(:learn_gitlab_experiment_enabled?).and_return(true)
+ it 'has a link to the learn GitLab' do
+ allow(view).to receive(:learn_gitlab_enabled?).and_return(true)
allow_next_instance_of(LearnGitlab::Onboarding) do |onboarding|
expect(onboarding).to receive(:completed_percentage).and_return(20)
end
@@ -968,6 +968,32 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
end
end
end
+
+ describe 'Usage Quotas' do
+ context 'with project_storage_ui feature flag enabled' do
+ before do
+ stub_feature_flags(project_storage_ui: true)
+ end
+
+ it 'has a link to Usage Quotas' do
+ render
+
+ expect(rendered).to have_link('Usage Quotas', href: project_usage_quotas_path(project))
+ end
+ end
+
+ context 'with project_storage_ui feature flag disabled' do
+ before do
+ stub_feature_flags(project_storage_ui: false)
+ end
+
+ it 'does not have a link to Usage Quotas' do
+ render
+
+ expect(rendered).not_to have_link('Usage Quotas', href: project_usage_quotas_path(project))
+ end
+ end
+ end
end
describe 'Hidden menus' do
diff --git a/spec/views/profiles/notifications/show.html.haml_spec.rb b/spec/views/profiles/notifications/show.html.haml_spec.rb
new file mode 100644
index 00000000000..9cdf8124fcf
--- /dev/null
+++ b/spec/views/profiles/notifications/show.html.haml_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'profiles/notifications/show' do
+ let(:groups) { GroupsFinder.new(user).execute.page(1) }
+ let(:user) { create(:user) }
+
+ before do
+ assign(:group_notifications, [])
+ assign(:project_notifications, [])
+ assign(:user, user)
+ assign(:user_groups, groups)
+ allow(controller).to receive(:current_user).and_return(user)
+ allow(view).to receive(:experiment_enabled?)
+ end
+
+ context 'when there is no database value for User#notification_email' do
+ let(:option_default) { _('Use primary email (%{email})') % { email: user.email } }
+ let(:option_primary_email) { user.email }
+ let(:options) { [option_default, option_primary_email] }
+
+ it 'displays the correct elements' do
+ render
+
+ expect(rendered).to have_select('user_notification_email', options: options, selected: nil)
+ end
+ end
+end
diff --git a/spec/views/projects/diffs/_stats.html.haml_spec.rb b/spec/views/projects/diffs/_stats.html.haml_spec.rb
deleted file mode 100644
index f0580b50349..00000000000
--- a/spec/views/projects/diffs/_stats.html.haml_spec.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'projects/diffs/_stats.html.haml' do
- let(:project) { create(:project, :repository) }
- let(:commit) { project.commit('570e7b2abdd848b95f2f578043fc23bd6f6fd24d') }
-
- def render_view
- render partial: "projects/diffs/stats", locals: { diff_files: commit.diffs.diff_files }
- end
-
- context 'when the commit contains several changes' do
- it 'uses plural for additions' do
- render_view
-
- expect(rendered).to have_text('additions')
- end
-
- it 'uses plural for deletions' do
- render_view
- end
- end
-
- context 'when the commit contains no addition and no deletions' do
- let(:commit) { project.commit('4cd80ccab63c82b4bad16faa5193fbd2aa06df40') }
-
- it 'uses plural for additions' do
- render_view
-
- expect(rendered).to have_text('additions')
- end
-
- it 'uses plural for deletions' do
- render_view
-
- expect(rendered).to have_text('deletions')
- end
- end
-
- context 'when the commit contains exactly one addition and one deletion' do
- let(:commit) { project.commit('08f22f255f082689c0d7d39d19205085311542bc') }
-
- it 'uses singular for additions' do
- render_view
-
- expect(rendered).to have_text('addition')
- expect(rendered).not_to have_text('additions')
- end
-
- it 'uses singular for deletions' do
- render_view
-
- expect(rendered).to have_text('deletion')
- expect(rendered).not_to have_text('deletions')
- end
- end
-end
diff --git a/spec/views/projects/empty.html.haml_spec.rb b/spec/views/projects/empty.html.haml_spec.rb
index 70da4fc9e27..416dfc10174 100644
--- a/spec/views/projects/empty.html.haml_spec.rb
+++ b/spec/views/projects/empty.html.haml_spec.rb
@@ -53,7 +53,7 @@ RSpec.describe 'projects/empty' do
it 'shows invite members info', :aggregate_failures do
render
- expect(rendered).to have_selector('[data-track-event=render]')
+ expect(rendered).to have_selector('[data-track-action=render]')
expect(rendered).to have_selector('[data-track-label=invite_members_empty_project]')
expect(rendered).to have_content('Invite your team')
expect(rendered).to have_content('Add members to this project and start collaborating with your team.')
diff --git a/spec/views/projects/merge_requests/_commits.html.haml_spec.rb b/spec/views/projects/merge_requests/_commits.html.haml_spec.rb
index fd77c4eb372..f0273c1716f 100644
--- a/spec/views/projects/merge_requests/_commits.html.haml_spec.rb
+++ b/spec/views/projects/merge_requests/_commits.html.haml_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe 'projects/merge_requests/_commits.html.haml', :sidekiq_might_not_
controller.prepend_view_path('app/views/projects')
assign(:merge_request, merge_request)
- assign(:commits, merge_request.commits)
+ assign(:commits, merge_request.commits(load_from_gitaly: true))
assign(:hidden_commit_count, 0)
end
@@ -34,6 +34,12 @@ RSpec.describe 'projects/merge_requests/_commits.html.haml', :sidekiq_might_not_
expect(rendered).to have_link(href: href)
end
+ it 'shows signature verification badge' do
+ render
+
+ expect(rendered).to have_css('.gpg-status-box')
+ end
+
context 'when there are hidden commits' do
before do
assign(:hidden_commit_count, 1)
diff --git a/spec/views/projects/project_members/index.html.haml_spec.rb b/spec/views/projects/project_members/index.html.haml_spec.rb
new file mode 100644
index 00000000000..b9b0d57bcb5
--- /dev/null
+++ b/spec/views/projects/project_members/index.html.haml_spec.rb
@@ -0,0 +1,96 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'projects/project_members/index', :aggregate_failures do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:source) { create(:project, :empty_repo) }
+ let_it_be(:project) { ProjectPresenter.new(source, current_user: user) }
+
+ before do
+ allow(view).to receive(:project_members_app_data_json).and_return({})
+ allow(view).to receive(:current_user).and_return(user)
+ assign(:project, project)
+ assign(:project_member, build(:project_member, project: source))
+ end
+
+ context 'when user can invite members for the project' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ context 'when modal is enabled' do
+ it 'renders as expected' do
+ render
+
+ expect(rendered).to have_content('Project members')
+ expect(rendered).to have_content('You can invite a new member')
+ expect(rendered).to have_selector('.js-import-a-project-modal')
+ expect(rendered).to have_selector('.js-invite-group-trigger')
+ expect(rendered).to have_selector('.js-invite-members-trigger')
+ expect(rendered).not_to have_content('Members can be added by project')
+ expect(response).to render_template(partial: 'projects/_invite_members_modal')
+ end
+
+ context 'when project is not allowed to share with group' do
+ before do
+ project.namespace.share_with_group_lock = true
+ end
+
+ it 'renders as expected' do
+ render
+
+ expect(rendered).not_to have_selector('.js-invite-group-trigger')
+ end
+ end
+ end
+
+ context 'when modal is not enabled' do
+ before do
+ stub_feature_flags(invite_members_group_modal: false)
+ end
+
+ it 'renders as expected' do
+ render
+
+ expect(rendered).to have_content('Project members')
+ expect(rendered).to have_content('You can invite a new member')
+ expect(rendered).not_to have_selector('.js-invite-group-trigger')
+ expect(rendered).not_to have_selector('.js-invite-members-trigger')
+ expect(rendered).not_to have_content('Members can be added by project')
+ expect(response).not_to render_template(partial: 'projects/_invite_members_modal')
+ expect(response).to render_template(partial: 'shared/members/_invite_member')
+ end
+
+ context 'when project can not be shared' do
+ before do
+ project.namespace.share_with_group_lock = true
+ end
+
+ it 'renders as expected' do
+ render
+
+ expect(rendered).to have_content('Project members')
+ expect(rendered).to have_content('You can invite a new member')
+ expect(response).not_to render_template(partial: 'projects/_invite_members_modal')
+ end
+ end
+ end
+ end
+
+ context 'when user can not invite members or group for the project' do
+ context 'when project can be shared' do
+ it 'renders as expected', :aggregate_failures do
+ render
+
+ expect(rendered).to have_content('Project members')
+ expect(rendered).not_to have_content('You can invite a new member')
+ expect(rendered).not_to have_selector('.js-import-a-project-modal')
+ expect(rendered).not_to have_selector('.js-invite-group-trigger')
+ expect(rendered).not_to have_selector('.js-invite-members-trigger')
+ expect(rendered).to have_content('Members can be added by project')
+ expect(response).not_to render_template(partial: 'projects/_invite_members_modal')
+ end
+ end
+ end
+end
diff --git a/spec/views/search/_results.html.haml_spec.rb b/spec/views/search/_results.html.haml_spec.rb
index ecfcf74edc1..dcf1f46b46c 100644
--- a/spec/views/search/_results.html.haml_spec.rb
+++ b/spec/views/search/_results.html.haml_spec.rb
@@ -74,7 +74,7 @@ RSpec.describe 'search/_results' do
it 'renders the click text event tracking attributes' do
render
- expect(rendered).to have_selector('[data-track-event=click_text]')
+ expect(rendered).to have_selector('[data-track-action=click_text]')
expect(rendered).to have_selector('[data-track-property=search_result]')
end
end
@@ -83,7 +83,7 @@ RSpec.describe 'search/_results' do
it 'does not render the click text event tracking attributes' do
render
- expect(rendered).not_to have_selector('[data-track-event=click_text]')
+ expect(rendered).not_to have_selector('[data-track-action=click_text]')
expect(rendered).not_to have_selector('[data-track-property=search_result]')
end
end
@@ -105,7 +105,7 @@ RSpec.describe 'search/_results' do
it 'renders the click text event tracking attributes' do
render
- expect(rendered).to have_selector('[data-track-event=click_text]')
+ expect(rendered).to have_selector('[data-track-action=click_text]')
expect(rendered).to have_selector('[data-track-property=search_result]')
end
end
@@ -114,7 +114,7 @@ RSpec.describe 'search/_results' do
it 'does not render the click text event tracking attributes' do
render
- expect(rendered).not_to have_selector('[data-track-event=click_text]')
+ expect(rendered).not_to have_selector('[data-track-action=click_text]')
expect(rendered).not_to have_selector('[data-track-property=search_result]')
end
end
diff --git a/spec/views/shared/access_tokens/_table.html.haml_spec.rb b/spec/views/shared/access_tokens/_table.html.haml_spec.rb
index 489675b5683..0a23768b4f1 100644
--- a/spec/views/shared/access_tokens/_table.html.haml_spec.rb
+++ b/spec/views/shared/access_tokens/_table.html.haml_spec.rb
@@ -19,7 +19,6 @@ RSpec.describe 'shared/access_tokens/_table.html.haml' do
allow(view).to receive(:personal_access_token_expiration_enforced?).and_return(token_expiry_enforced?)
allow(view).to receive(:show_profile_token_expiry_notification?).and_return(true)
- allow(view).to receive(:distance_of_time_in_words_to_now).and_return('4 days')
if project
project.add_maintainer(user)
@@ -140,7 +139,6 @@ RSpec.describe 'shared/access_tokens/_table.html.haml' do
# Expiry
expect(rendered).to have_content 'Expired', count: 2
- expect(rendered).to have_content 'In 4 days'
# Revoke buttons
expect(rendered).to have_link 'Revoke', href: 'path/', class: 'btn-danger-secondary', count: 1
diff --git a/spec/workers/authorized_project_update/user_refresh_from_replica_worker_spec.rb b/spec/workers/authorized_project_update/user_refresh_from_replica_worker_spec.rb
index 027ce3b7f89..0da58343773 100644
--- a/spec/workers/authorized_project_update/user_refresh_from_replica_worker_spec.rb
+++ b/spec/workers/authorized_project_update/user_refresh_from_replica_worker_spec.rb
@@ -51,20 +51,5 @@ RSpec.describe AuthorizedProjectUpdate::UserRefreshFromReplicaWorker do
execute_worker
end
end
-
- context 'when the feature flag `user_refresh_from_replica_worker_uses_replica_db` is disabled' do
- before do
- stub_feature_flags(user_refresh_from_replica_worker_uses_replica_db: false)
- end
-
- it 'calls Users::RefreshAuthorizedProjectsService' do
- source = 'AuthorizedProjectUpdate::UserRefreshFromReplicaWorker'
- expect_next_instance_of(Users::RefreshAuthorizedProjectsService, user, { source: source }) do |service|
- expect(service).to receive(:execute)
- end
-
- execute_worker
- end
- end
end
end
diff --git a/spec/workers/background_migration_worker_spec.rb b/spec/workers/background_migration_worker_spec.rb
index 4575c270042..7892eb89e80 100644
--- a/spec/workers/background_migration_worker_spec.rb
+++ b/spec/workers/background_migration_worker_spec.rb
@@ -14,7 +14,17 @@ RSpec.describe BackgroundMigrationWorker, :clean_gitlab_redis_shared_state do
describe '#perform' do
before do
allow(worker).to receive(:jid).and_return(1)
- expect(worker).to receive(:always_perform?).and_return(false)
+ allow(worker).to receive(:always_perform?).and_return(false)
+ end
+
+ it 'can run scheduled job and retried job concurrently' do
+ expect(Gitlab::BackgroundMigration)
+ .to receive(:perform)
+ .with('Foo', [10, 20])
+ .exactly(2).time
+
+ worker.perform('Foo', [10, 20])
+ worker.perform('Foo', [10, 20], described_class::MAX_LEASE_ATTEMPTS - 1)
end
context 'when lease can be obtained' do
@@ -39,7 +49,7 @@ RSpec.describe BackgroundMigrationWorker, :clean_gitlab_redis_shared_state do
before do
expect(Gitlab::BackgroundMigration).not_to receive(:perform)
- worker.lease_for('Foo').try_obtain
+ worker.lease_for('Foo', false).try_obtain
end
it 'reschedules the migration and decrements the lease_attempts' do
@@ -51,6 +61,10 @@ RSpec.describe BackgroundMigrationWorker, :clean_gitlab_redis_shared_state do
end
context 'when lease_attempts is 1' do
+ before do
+ worker.lease_for('Foo', true).try_obtain
+ end
+
it 'reschedules the migration and decrements the lease_attempts' do
expect(described_class)
.to receive(:perform_in)
@@ -61,6 +75,10 @@ RSpec.describe BackgroundMigrationWorker, :clean_gitlab_redis_shared_state do
end
context 'when lease_attempts is 0' do
+ before do
+ worker.lease_for('Foo', true).try_obtain
+ end
+
it 'gives up performing the migration' do
expect(described_class).not_to receive(:perform_in)
expect(Sidekiq.logger).to receive(:warn).with(
diff --git a/spec/workers/bulk_import_worker_spec.rb b/spec/workers/bulk_import_worker_spec.rb
index 205bf23f36d..b67c5c62f76 100644
--- a/spec/workers/bulk_import_worker_spec.rb
+++ b/spec/workers/bulk_import_worker_spec.rb
@@ -84,17 +84,20 @@ RSpec.describe BulkImportWorker do
expect { subject.perform(bulk_import.id) }
.to change(BulkImports::Tracker, :count)
- .by(BulkImports::Stage.pipelines.size * 2)
+ .by(BulkImports::Groups::Stage.pipelines.size * 2)
expect(entity_1.trackers).not_to be_empty
expect(entity_2.trackers).not_to be_empty
end
context 'when there are created entities to process' do
- it 'marks a batch of entities as started, enqueues EntityWorker, ExportRequestWorker and reenqueues' do
+ let_it_be(:bulk_import) { create(:bulk_import, :created) }
+
+ before do
stub_const("#{described_class}::DEFAULT_BATCH_SIZE", 1)
+ end
- bulk_import = create(:bulk_import, :created)
+ it 'marks a batch of entities as started, enqueues EntityWorker, ExportRequestWorker and reenqueues' do
create(:bulk_import_entity, :created, bulk_import: bulk_import)
create(:bulk_import_entity, :created, bulk_import: bulk_import)
@@ -106,6 +109,16 @@ RSpec.describe BulkImportWorker do
expect(bulk_import.entities.map(&:status_name)).to contain_exactly(:created, :started)
end
+
+ context 'when there are project entities to process' do
+ it 'does not enqueue ExportRequestWorker' do
+ create(:bulk_import_entity, :created, :project_entity, bulk_import: bulk_import)
+
+ expect(BulkImports::ExportRequestWorker).not_to receive(:perform_async)
+
+ subject.perform(bulk_import.id)
+ end
+ end
end
context 'when exception occurs' do
diff --git a/spec/workers/bulk_imports/pipeline_worker_spec.rb b/spec/workers/bulk_imports/pipeline_worker_spec.rb
index 972a4158194..56f28654ac5 100644
--- a/spec/workers/bulk_imports/pipeline_worker_spec.rb
+++ b/spec/workers/bulk_imports/pipeline_worker_spec.rb
@@ -21,6 +21,10 @@ RSpec.describe BulkImports::PipelineWorker do
before do
stub_const('FakePipeline', pipeline_class)
+
+ allow(BulkImports::Groups::Stage)
+ .to receive(:pipelines)
+ .and_return([[0, pipeline_class]])
end
it 'runs the given pipeline successfully' do
@@ -30,12 +34,6 @@ RSpec.describe BulkImports::PipelineWorker do
pipeline_name: 'FakePipeline'
)
- expect(BulkImports::Stage)
- .to receive(:pipeline_exists?)
- .with('FakePipeline')
- .twice
- .and_return(true)
-
expect_next_instance_of(Gitlab::Import::Logger) do |logger|
expect(logger)
.to receive(:info)
@@ -110,7 +108,7 @@ RSpec.describe BulkImports::PipelineWorker do
expect(Gitlab::ErrorTracking)
.to receive(:track_exception)
.with(
- instance_of(NameError),
+ instance_of(BulkImports::Error),
entity_id: entity.id,
pipeline_name: pipeline_tracker.pipeline_name
)
@@ -157,10 +155,10 @@ RSpec.describe BulkImports::PipelineWorker do
before do
stub_const('NdjsonPipeline', ndjson_pipeline)
- allow(BulkImports::Stage)
- .to receive(:pipeline_exists?)
- .with('NdjsonPipeline')
- .and_return(true)
+
+ allow(BulkImports::Groups::Stage)
+ .to receive(:pipelines)
+ .and_return([[0, ndjson_pipeline]])
end
it 'runs the pipeline successfully' do
diff --git a/spec/workers/ci/external_pull_requests/create_pipeline_worker_spec.rb b/spec/workers/ci/external_pull_requests/create_pipeline_worker_spec.rb
new file mode 100644
index 00000000000..116a0e4d035
--- /dev/null
+++ b/spec/workers/ci/external_pull_requests/create_pipeline_worker_spec.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::ExternalPullRequests::CreatePipelineWorker do
+ let_it_be(:project) { create(:project, :auto_devops, :repository) }
+ let_it_be(:user) { project.owner }
+ let_it_be(:external_pull_request) do
+ branch = project.repository.branches.last
+ create(:external_pull_request, project: project, source_branch: branch.name, source_sha: branch.target)
+ end
+
+ let(:worker) { described_class.new }
+
+ describe '#perform' do
+ let(:project_id) { project.id }
+ let(:user_id) { user.id }
+ let(:external_pull_request_id) { external_pull_request.id }
+
+ subject(:perform) { worker.perform(project_id, user_id, external_pull_request_id) }
+
+ it 'creates the pipeline' do
+ pipeline = perform.payload
+
+ expect(pipeline).to be_valid
+ expect(pipeline).to be_persisted
+ expect(pipeline).to be_external_pull_request_event
+ expect(pipeline.project).to eq(project)
+ expect(pipeline.user).to eq(user)
+ expect(pipeline.external_pull_request).to eq(external_pull_request)
+ expect(pipeline.status).to eq('created')
+ expect(pipeline.ref).to eq(external_pull_request.source_branch)
+ expect(pipeline.sha).to eq(external_pull_request.source_sha)
+ expect(pipeline.source_sha).to eq(external_pull_request.source_sha)
+ expect(pipeline.target_sha).to eq(external_pull_request.target_sha)
+ end
+
+ shared_examples_for 'not calling service' do
+ it 'does not call the service' do
+ expect(Ci::CreatePipelineService).not_to receive(:new)
+ perform
+ end
+ end
+
+ context 'when the project not found' do
+ let(:project_id) { non_existing_record_id }
+
+ it_behaves_like 'not calling service'
+ end
+
+ context 'when the user not found' do
+ let(:user_id) { non_existing_record_id }
+
+ it_behaves_like 'not calling service'
+ end
+
+ context 'when the pull request not found' do
+ let(:external_pull_request_id) { non_existing_record_id }
+
+ it_behaves_like 'not calling service'
+ end
+
+ context 'when the pull request does not belong to the project' do
+ let(:external_pull_request_id) { create(:external_pull_request).id }
+
+ it_behaves_like 'not calling service'
+ end
+ end
+end
diff --git a/spec/workers/concerns/worker_attributes_spec.rb b/spec/workers/concerns/worker_attributes_spec.rb
index d4b17c65f46..ad9d5eeccbe 100644
--- a/spec/workers/concerns/worker_attributes_spec.rb
+++ b/spec/workers/concerns/worker_attributes_spec.rb
@@ -35,45 +35,17 @@ RSpec.describe WorkerAttributes do
end
end
- context 'when job is idempotent' do
- context 'when data_consistency is not :always' do
- it 'raise exception' do
- worker.idempotent!
-
- expect { worker.data_consistency(:sticky) }
- .to raise_error("Class can't be marked as idempotent if data_consistency is not set to :always")
- end
- end
-
- context 'when feature_flag is provided' do
- before do
- stub_feature_flags(test_feature_flag: false)
- skip_feature_flags_yaml_validation
- skip_default_enabled_yaml_check
- end
-
- it 'returns correct feature flag value' do
- worker.data_consistency(:sticky, feature_flag: :test_feature_flag)
-
- expect(worker.get_data_consistency_feature_flag_enabled?).not_to be_truthy
- end
+ context 'when feature_flag is provided' do
+ before do
+ stub_feature_flags(test_feature_flag: false)
+ skip_feature_flags_yaml_validation
+ skip_default_enabled_yaml_check
end
- end
- end
-
- describe '.idempotent!' do
- it 'sets `idempotent` attribute of the worker class to true' do
- worker.idempotent!
- expect(worker.send(:class_attributes)[:idempotent]).to eq(true)
- end
-
- context 'when data consistency is not :always' do
- it 'raise exception' do
- worker.data_consistency(:sticky)
+ it 'returns correct feature flag value' do
+ worker.data_consistency(:sticky, feature_flag: :test_feature_flag)
- expect { worker.idempotent! }
- .to raise_error("Class can't be marked as idempotent if data_consistency is not set to :always")
+ expect(worker.get_data_consistency_feature_flag_enabled?).not_to be_truthy
end
end
end
diff --git a/spec/workers/database/partition_management_worker_spec.rb b/spec/workers/database/partition_management_worker_spec.rb
index 01b7f209b2d..9ded36743a8 100644
--- a/spec/workers/database/partition_management_worker_spec.rb
+++ b/spec/workers/database/partition_management_worker_spec.rb
@@ -6,16 +6,14 @@ RSpec.describe Database::PartitionManagementWorker do
describe '#perform' do
subject { described_class.new.perform }
- let(:manager) { instance_double('PartitionManager', sync_partitions: nil) }
let(:monitoring) { instance_double('PartitionMonitoring', report_metrics: nil) }
before do
- allow(Gitlab::Database::Partitioning::PartitionManager).to receive(:new).and_return(manager)
allow(Gitlab::Database::Partitioning::PartitionMonitoring).to receive(:new).and_return(monitoring)
end
- it 'delegates to PartitionManager' do
- expect(manager).to receive(:sync_partitions)
+ it 'delegates to Partitioning' do
+ expect(Gitlab::Database::Partitioning).to receive(:sync_partitions)
subject
end
diff --git a/spec/workers/deployments/finished_worker_spec.rb b/spec/workers/deployments/finished_worker_spec.rb
deleted file mode 100644
index d0a26ae1547..00000000000
--- a/spec/workers/deployments/finished_worker_spec.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Deployments::FinishedWorker do
- let(:worker) { described_class.new }
-
- describe '#perform' do
- before do
- allow(ProjectServiceWorker).to receive(:perform_async)
- end
-
- it 'links merge requests to the deployment' do
- deployment = create(:deployment)
- service = instance_double(Deployments::LinkMergeRequestsService)
-
- expect(Deployments::LinkMergeRequestsService)
- .to receive(:new)
- .with(deployment)
- .and_return(service)
-
- expect(service).to receive(:execute)
-
- worker.perform(deployment.id)
- end
-
- it 'executes project services for deployment_hooks' do
- deployment = create(:deployment)
- project = deployment.project
- service = create(:service, type: 'SlackService', project: project, deployment_events: true, active: true)
-
- worker.perform(deployment.id)
-
- expect(ProjectServiceWorker).to have_received(:perform_async).with(service.id, an_instance_of(Hash))
- end
-
- it 'does not execute an inactive service' do
- deployment = create(:deployment)
- project = deployment.project
- create(:service, type: 'SlackService', project: project, deployment_events: true, active: false)
-
- worker.perform(deployment.id)
-
- expect(ProjectServiceWorker).not_to have_received(:perform_async)
- end
-
- it 'does nothing if a deployment with the given id does not exist' do
- worker.perform(0)
-
- expect(ProjectServiceWorker).not_to have_received(:perform_async)
- end
-
- it 'execute webhooks' do
- deployment = create(:deployment)
- project = deployment.project
- web_hook = create(:project_hook, deployment_events: true, project: project)
-
- expect_next_instance_of(WebHookService, web_hook, an_instance_of(Hash), "deployment_hooks") do |service|
- expect(service).to receive(:async_execute)
- end
-
- worker.perform(deployment.id)
- end
- end
-end
diff --git a/spec/workers/deployments/hooks_worker_spec.rb b/spec/workers/deployments/hooks_worker_spec.rb
index 5d8edf85dd9..b4a91cff2ac 100644
--- a/spec/workers/deployments/hooks_worker_spec.rb
+++ b/spec/workers/deployments/hooks_worker_spec.rb
@@ -52,7 +52,6 @@ RSpec.describe Deployments::HooksWorker do
it_behaves_like 'worker with data consistency',
described_class,
- feature_flag: :load_balancing_for_deployments_hooks_worker,
data_consistency: :delayed
end
end
diff --git a/spec/workers/deployments/success_worker_spec.rb b/spec/workers/deployments/success_worker_spec.rb
deleted file mode 100644
index d9996e66919..00000000000
--- a/spec/workers/deployments/success_worker_spec.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Deployments::SuccessWorker do
- subject { described_class.new.perform(deployment&.id) }
-
- context 'when successful deployment' do
- let(:deployment) { create(:deployment, :success) }
-
- it 'executes Deployments::UpdateEnvironmentService' do
- expect(Deployments::UpdateEnvironmentService)
- .to receive(:new).with(deployment).and_call_original
-
- subject
- end
- end
-
- context 'when canceled deployment' do
- let(:deployment) { create(:deployment, :canceled) }
-
- it 'does not execute Deployments::UpdateEnvironmentService' do
- expect(Deployments::UpdateEnvironmentService).not_to receive(:new)
-
- subject
- end
- end
-
- context 'when deploy record does not exist' do
- let(:deployment) { nil }
-
- it 'does not execute Deployments::UpdateEnvironmentService' do
- expect(Deployments::UpdateEnvironmentService).not_to receive(:new)
-
- subject
- end
- end
-end
diff --git a/spec/workers/environments/auto_stop_worker_spec.rb b/spec/workers/environments/auto_stop_worker_spec.rb
new file mode 100644
index 00000000000..1983cfa18ea
--- /dev/null
+++ b/spec/workers/environments/auto_stop_worker_spec.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Environments::AutoStopWorker do
+ include CreateEnvironmentsHelpers
+
+ subject { worker.perform(environment_id) }
+
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:developer) { create(:user).tap { |u| project.add_developer(u) } }
+ let_it_be(:reporter) { create(:user).tap { |u| project.add_reporter(u) } }
+
+ before_all do
+ project.repository.add_branch(developer, 'review/feature', 'master')
+ end
+
+ let!(:environment) { create_review_app(user, project, 'review/feature').environment }
+ let(:environment_id) { environment.id }
+ let(:worker) { described_class.new }
+ let(:user) { developer }
+
+ it 'stops the environment' do
+ expect { subject }
+ .to change { Environment.find_by_name('review/feature').state }
+ .from('available').to('stopped')
+ end
+
+ it 'executes the stop action' do
+ expect { subject }
+ .to change { Ci::Build.find_by_name('stop_review_app').status }
+ .from('manual').to('pending')
+ end
+
+ context 'when user does not have a permission to play the stop action' do
+ let(:user) { reporter }
+
+ it 'raises an error' do
+ expect { subject }.to raise_error(Gitlab::Access::AccessDeniedError)
+ end
+ end
+
+ context 'when the environment has already been stopped' do
+ before do
+ environment.stop!
+ end
+
+ it 'does not execute the stop action' do
+ expect { subject }
+ .not_to change { Ci::Build.find_by_name('stop_review_app').status }
+ end
+ end
+
+ context 'when there are no deployments and associted stop actions' do
+ let!(:environment) { create(:environment) }
+
+ it 'stops the environment' do
+ subject
+
+ expect(environment.reload).to be_stopped
+ end
+ end
+
+ context 'when there are no corresponding environment record' do
+ let!(:environment) { double(:environment, id: non_existing_record_id) }
+
+ it 'ignores the invalid record' do
+ expect { subject }.not_to raise_error
+ end
+ end
+end
diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb
index ea1f0153f83..235a1f6e3dd 100644
--- a/spec/workers/every_sidekiq_worker_spec.rb
+++ b/spec/workers/every_sidekiq_worker_spec.rb
@@ -436,6 +436,7 @@ RSpec.describe 'Every Sidekiq worker' do
'TodosDestroyer::ConfidentialEpicWorker' => 3,
'TodosDestroyer::ConfidentialIssueWorker' => 3,
'TodosDestroyer::DestroyedIssuableWorker' => 3,
+ 'TodosDestroyer::DestroyedDesignsWorker' => 3,
'TodosDestroyer::EntityLeaveWorker' => 3,
'TodosDestroyer::GroupPrivateWorker' => 3,
'TodosDestroyer::PrivateFeaturesWorker' => 3,
@@ -452,6 +453,7 @@ RSpec.describe 'Every Sidekiq worker' do
'WaitForClusterCreationWorker' => 3,
'WebHookWorker' => 4,
'WebHooks::DestroyWorker' => 3,
+ 'WebHooks::LogExecutionWorker' => 3,
'Wikis::GitGarbageCollectWorker' => false,
'X509CertificateRevokeWorker' => 3
}
diff --git a/spec/workers/expire_job_cache_worker_spec.rb b/spec/workers/expire_job_cache_worker_spec.rb
index cbd9dd39336..6b14ccea105 100644
--- a/spec/workers/expire_job_cache_worker_spec.rb
+++ b/spec/workers/expire_job_cache_worker_spec.rb
@@ -13,44 +13,9 @@ RSpec.describe ExpireJobCacheWorker do
let(:job_args) { job.id }
- include_examples 'an idempotent worker' do
- it 'invalidates Etag caching for the job path' do
- job_path = "/#{project.full_path}/builds/#{job.id}.json"
-
- spy_store = Gitlab::EtagCaching::Store.new
-
- allow(Gitlab::EtagCaching::Store).to receive(:new) { spy_store }
-
- expect(spy_store).to receive(:touch)
- .exactly(worker_exec_times).times
- .with(job_path)
- .and_call_original
-
- expect(ExpirePipelineCacheWorker).to receive(:perform_async)
- .with(pipeline.id)
- .exactly(worker_exec_times).times
-
- subject
- end
- end
-
- it 'does not perform extra queries', :aggregate_failures do
- worker = described_class.new
- recorder = ActiveRecord::QueryRecorder.new { worker.perform(job.id) }
-
- occurences = recorder.data.values.flat_map {|v| v[:occurrences]}
- project_queries = occurences.select {|s| s.include?('FROM "projects"')}
- namespace_queries = occurences.select {|s| s.include?('FROM "namespaces"')}
- route_queries = occurences.select {|s| s.include?('FROM "routes"')}
-
- # This worker is run 1 million times an hour, so we need to save as much
- # queries as possible.
- expect(recorder.count).to be <= 1
-
- expect(project_queries.size).to eq(0)
- expect(namespace_queries.size).to eq(0)
- expect(route_queries.size).to eq(0)
- end
+ it_behaves_like 'worker with data consistency',
+ described_class,
+ data_consistency: :delayed
end
context 'when there is no job in the pipeline' do
diff --git a/spec/workers/expire_pipeline_cache_worker_spec.rb b/spec/workers/expire_pipeline_cache_worker_spec.rb
index 8c24aaa985b..f4c4df2e752 100644
--- a/spec/workers/expire_pipeline_cache_worker_spec.rb
+++ b/spec/workers/expire_pipeline_cache_worker_spec.rb
@@ -18,23 +18,6 @@ RSpec.describe ExpirePipelineCacheWorker do
subject.perform(pipeline.id)
end
- it 'does not perform extra queries', :aggregate_failures do
- recorder = ActiveRecord::QueryRecorder.new { subject.perform(pipeline.id) }
-
- project_queries = recorder.data.values.flat_map {|v| v[:occurrences]}.select {|s| s.include?('FROM "projects"')}
- namespace_queries = recorder.data.values.flat_map {|v| v[:occurrences]}.select {|s| s.include?('FROM "namespaces"')}
- route_queries = recorder.data.values.flat_map {|v| v[:occurrences]}.select {|s| s.include?('FROM "routes"')}
-
- # This worker is run 1 million times an hour, so we need to save as much
- # queries as possible.
- expect(recorder.count).to be <= 6
-
- # These arises from #update_etag_cache
- expect(project_queries.size).to eq(1)
- expect(namespace_queries.size).to eq(1)
- expect(route_queries.size).to eq(1)
- end
-
it "doesn't do anything if the pipeline not exist" do
expect_any_instance_of(Ci::ExpirePipelineCacheService).not_to receive(:execute)
expect_any_instance_of(Gitlab::EtagCaching::Store).not_to receive(:touch)
diff --git a/spec/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker_spec.rb b/spec/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker_spec.rb
index f2a28ec40b8..c0dd4f488cc 100644
--- a/spec/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker_spec.rb
+++ b/spec/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe Gitlab::GithubImport::Stage::ImportIssuesAndDiffNotesWorker do
it 'imports the issues and diff notes' do
client = double(:client)
- described_class::IMPORTERS.each do |klass|
+ worker.importers(project).each do |klass|
importer = double(:importer)
waiter = Gitlab::JobWaiter.new(2, '123')
@@ -31,4 +31,45 @@ RSpec.describe Gitlab::GithubImport::Stage::ImportIssuesAndDiffNotesWorker do
worker.import(client, project)
end
end
+
+ describe '#importers' do
+ context 'when project group is present' do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:group) { create(:group, projects: [project]) }
+
+ context 'when feature flag github_importer_single_endpoint_notes_import is enabled' do
+ it 'includes single endpoint diff notes importer' do
+ project = create(:project)
+ group = create(:group, projects: [project])
+
+ stub_feature_flags(github_importer_single_endpoint_notes_import: group)
+
+ expect(worker.importers(project)).to contain_exactly(
+ Gitlab::GithubImport::Importer::IssuesImporter,
+ Gitlab::GithubImport::Importer::SingleEndpointDiffNotesImporter
+ )
+ end
+ end
+
+ context 'when feature flag github_importer_single_endpoint_notes_import is disabled' do
+ it 'includes default diff notes importer' do
+ stub_feature_flags(github_importer_single_endpoint_notes_import: false)
+
+ expect(worker.importers(project)).to contain_exactly(
+ Gitlab::GithubImport::Importer::IssuesImporter,
+ Gitlab::GithubImport::Importer::DiffNotesImporter
+ )
+ end
+ end
+ end
+
+ context 'when project group is missing' do
+ it 'includes default diff notes importer' do
+ expect(worker.importers(project)).to contain_exactly(
+ Gitlab::GithubImport::Importer::IssuesImporter,
+ Gitlab::GithubImport::Importer::DiffNotesImporter
+ )
+ end
+ end
+ end
end
diff --git a/spec/workers/gitlab/github_import/stage/import_notes_worker_spec.rb b/spec/workers/gitlab/github_import/stage/import_notes_worker_spec.rb
index 73b19239f4a..f9f21e4dfa2 100644
--- a/spec/workers/gitlab/github_import/stage/import_notes_worker_spec.rb
+++ b/spec/workers/gitlab/github_import/stage/import_notes_worker_spec.rb
@@ -8,18 +8,21 @@ RSpec.describe Gitlab::GithubImport::Stage::ImportNotesWorker do
describe '#import' do
it 'imports all the notes' do
- importer = double(:importer)
client = double(:client)
- waiter = Gitlab::JobWaiter.new(2, '123')
- expect(Gitlab::GithubImport::Importer::NotesImporter)
- .to receive(:new)
- .with(project, client)
- .and_return(importer)
+ worker.importers(project).each do |klass|
+ importer = double(:importer)
+ waiter = Gitlab::JobWaiter.new(2, '123')
- expect(importer)
- .to receive(:execute)
- .and_return(waiter)
+ expect(klass)
+ .to receive(:new)
+ .with(project, client)
+ .and_return(importer)
+
+ expect(importer)
+ .to receive(:execute)
+ .and_return(waiter)
+ end
expect(Gitlab::GithubImport::AdvanceStageWorker)
.to receive(:perform_async)
@@ -28,4 +31,43 @@ RSpec.describe Gitlab::GithubImport::Stage::ImportNotesWorker do
worker.import(client, project)
end
end
+
+ describe '#importers' do
+ context 'when project group is present' do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:group) { create(:group, projects: [project]) }
+
+ context 'when feature flag github_importer_single_endpoint_notes_import is enabled' do
+ it 'includes single endpoint mr and issue notes importers' do
+ project = create(:project)
+ group = create(:group, projects: [project])
+
+ stub_feature_flags(github_importer_single_endpoint_notes_import: group)
+
+ expect(worker.importers(project)).to contain_exactly(
+ Gitlab::GithubImport::Importer::SingleEndpointMergeRequestNotesImporter,
+ Gitlab::GithubImport::Importer::SingleEndpointIssueNotesImporter
+ )
+ end
+ end
+
+ context 'when feature flag github_importer_single_endpoint_notes_import is disabled' do
+ it 'includes default notes importer' do
+ stub_feature_flags(github_importer_single_endpoint_notes_import: false)
+
+ expect(worker.importers(project)).to contain_exactly(
+ Gitlab::GithubImport::Importer::NotesImporter
+ )
+ end
+ end
+ end
+
+ context 'when project group is missing' do
+ it 'includes default diff notes importer' do
+ expect(worker.importers(project)).to contain_exactly(
+ Gitlab::GithubImport::Importer::NotesImporter
+ )
+ end
+ end
+ end
end
diff --git a/spec/workers/issue_rebalancing_worker_spec.rb b/spec/workers/issue_rebalancing_worker_spec.rb
index b6e9429d78e..cba42a1577e 100644
--- a/spec/workers/issue_rebalancing_worker_spec.rb
+++ b/spec/workers/issue_rebalancing_worker_spec.rb
@@ -8,41 +8,29 @@ RSpec.describe IssueRebalancingWorker do
let_it_be(:project) { create(:project, group: group) }
let_it_be(:issue) { create(:issue, project: project) }
- context 'when block_issue_repositioning is enabled' do
- before do
- stub_feature_flags(block_issue_repositioning: group)
- end
-
- it 'does not run an instance of IssueRebalancingService' do
- expect(IssueRebalancingService).not_to receive(:new)
-
- described_class.new.perform(nil, issue.project_id)
- end
- end
-
shared_examples 'running the worker' do
- it 'runs an instance of IssueRebalancingService' do
+ it 'runs an instance of Issues::RelativePositionRebalancingService' do
service = double(execute: nil)
service_param = arguments.second.present? ? kind_of(Project.id_in([project]).class) : kind_of(group&.all_projects.class)
- expect(IssueRebalancingService).to receive(:new).with(service_param).and_return(service)
+ expect(Issues::RelativePositionRebalancingService).to receive(:new).with(service_param).and_return(service)
described_class.new.perform(*arguments)
end
- it 'anticipates there being too many issues' do
+ it 'anticipates there being too many concurent rebalances' do
service = double
service_param = arguments.second.present? ? kind_of(Project.id_in([project]).class) : kind_of(group&.all_projects.class)
- allow(service).to receive(:execute).and_raise(IssueRebalancingService::TooManyIssues)
- expect(IssueRebalancingService).to receive(:new).with(service_param).and_return(service)
- expect(Gitlab::ErrorTracking).to receive(:log_exception).with(IssueRebalancingService::TooManyIssues, include(project_id: arguments.second, root_namespace_id: arguments.third))
+ allow(service).to receive(:execute).and_raise(Issues::RelativePositionRebalancingService::TooManyConcurrentRebalances)
+ expect(Issues::RelativePositionRebalancingService).to receive(:new).with(service_param).and_return(service)
+ expect(Gitlab::ErrorTracking).to receive(:log_exception).with(Issues::RelativePositionRebalancingService::TooManyConcurrentRebalances, include(project_id: arguments.second, root_namespace_id: arguments.third))
described_class.new.perform(*arguments)
end
it 'takes no action if the value is nil' do
- expect(IssueRebalancingService).not_to receive(:new)
+ expect(Issues::RelativePositionRebalancingService).not_to receive(:new)
expect(Gitlab::ErrorTracking).not_to receive(:log_exception)
described_class.new.perform # all arguments are nil
@@ -52,7 +40,7 @@ RSpec.describe IssueRebalancingWorker do
shared_examples 'safely handles non-existent ids' do
it 'anticipates the inability to find the issue' do
expect(Gitlab::ErrorTracking).to receive(:log_exception).with(ArgumentError, include(project_id: arguments.second, root_namespace_id: arguments.third))
- expect(IssueRebalancingService).not_to receive(:new)
+ expect(Issues::RelativePositionRebalancingService).not_to receive(:new)
described_class.new.perform(*arguments)
end
diff --git a/spec/workers/namespaceless_project_destroy_worker_spec.rb b/spec/workers/namespaceless_project_destroy_worker_spec.rb
index cd66af82364..93e8415f3bb 100644
--- a/spec/workers/namespaceless_project_destroy_worker_spec.rb
+++ b/spec/workers/namespaceless_project_destroy_worker_spec.rb
@@ -48,12 +48,6 @@ RSpec.describe NamespacelessProjectDestroyWorker do
subject.perform(project.id)
end
-
- it 'does not do anything in Project#legacy_remove_pages method' do
- expect(Gitlab::PagesTransfer).not_to receive(:new)
-
- subject.perform(project.id)
- end
end
context 'project forked from another' do
diff --git a/spec/workers/packages/helm/extraction_worker_spec.rb b/spec/workers/packages/helm/extraction_worker_spec.rb
index 258413a3410..daebbda3077 100644
--- a/spec/workers/packages/helm/extraction_worker_spec.rb
+++ b/spec/workers/packages/helm/extraction_worker_spec.rb
@@ -23,10 +23,10 @@ RSpec.describe Packages::Helm::ExtractionWorker, type: :worker do
subject { described_class.new.perform(channel, package_file_id) }
- shared_examples 'handling error' do
+ shared_examples 'handling error' do |error_class = Packages::Helm::ExtractFileMetadataService::ExtractionError|
it 'mark the package as errored', :aggregate_failures do
expect(Gitlab::ErrorTracking).to receive(:log_exception).with(
- instance_of(Packages::Helm::ExtractFileMetadataService::ExtractionError),
+ instance_of(error_class),
project_id: package_file.package.project_id
)
expect { subject }
@@ -88,5 +88,15 @@ RSpec.describe Packages::Helm::ExtractionWorker, type: :worker do
it_behaves_like 'handling error'
end
+
+ context 'with an invalid Chart.yaml' do
+ before do
+ expect_next_instance_of(Gem::Package::TarReader::Entry) do |entry|
+ expect(entry).to receive(:read).and_return('{}')
+ end
+ end
+
+ it_behaves_like 'handling error', ActiveRecord::RecordInvalid
+ end
end
end
diff --git a/spec/workers/pages_remove_worker_spec.rb b/spec/workers/pages_remove_worker_spec.rb
index 864aa763fa9..9d49088b371 100644
--- a/spec/workers/pages_remove_worker_spec.rb
+++ b/spec/workers/pages_remove_worker_spec.rb
@@ -3,23 +3,9 @@
require 'spec_helper'
RSpec.describe PagesRemoveWorker do
- let(:project) { create(:project, path: "my.project")}
- let!(:domain) { create(:pages_domain, project: project) }
-
- subject { described_class.new.perform(project.id) }
-
- before do
- project.mark_pages_as_deployed
- end
-
- it 'deletes published pages' do
- expect(project.pages_deployed?).to be(true)
-
- expect_any_instance_of(Gitlab::PagesTransfer).to receive(:rename_project).and_return true
- expect(PagesWorker).to receive(:perform_in).with(5.minutes, :remove, project.namespace.full_path, anything)
-
- subject
-
- expect(project.reload.pages_deployed?).to be(false)
+ it 'does not raise error' do
+ expect do
+ described_class.new.perform(create(:project).id)
+ end.not_to raise_error
end
end
diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb
index c111c3164eb..ddd295215a1 100644
--- a/spec/workers/post_receive_spec.rb
+++ b/spec/workers/post_receive_spec.rb
@@ -22,6 +22,8 @@ RSpec.describe PostReceive do
create(:project, :repository, auto_cancel_pending_pipelines: 'disabled')
end
+ let(:job_args) { [gl_repository, key_id, base64_changes] }
+
def perform(changes: base64_changes)
described_class.new.perform(gl_repository, key_id, changes)
end
@@ -282,6 +284,8 @@ RSpec.describe PostReceive do
end
end
end
+
+ it_behaves_like 'an idempotent worker'
end
describe '#process_wiki_changes' do
@@ -352,6 +356,8 @@ RSpec.describe PostReceive do
perform
end
end
+
+ it_behaves_like 'an idempotent worker'
end
context 'webhook' do
@@ -458,6 +464,8 @@ RSpec.describe PostReceive do
end
end
end
+
+ it_behaves_like 'an idempotent worker'
end
context 'with PersonalSnippet' do
@@ -484,5 +492,7 @@ RSpec.describe PostReceive do
described_class.new.perform(gl_repository, key_id, base64_changes)
end
+
+ it_behaves_like 'an idempotent worker'
end
end
diff --git a/spec/workers/purge_dependency_proxy_cache_worker_spec.rb b/spec/workers/purge_dependency_proxy_cache_worker_spec.rb
index 53f8d1bf5ba..393745958be 100644
--- a/spec/workers/purge_dependency_proxy_cache_worker_spec.rb
+++ b/spec/workers/purge_dependency_proxy_cache_worker_spec.rb
@@ -11,14 +11,9 @@ RSpec.describe PurgeDependencyProxyCacheWorker do
subject { described_class.new.perform(user.id, group_id) }
- before do
- stub_config(dependency_proxy: { enabled: true })
- group.create_dependency_proxy_setting!(enabled: true)
- end
-
describe '#perform' do
- shared_examples 'returns nil' do
- it 'returns nil', :aggregate_failures do
+ shared_examples 'not removing blobs and manifests' do
+ it 'does not remove blobs and manifests', :aggregate_failures do
expect { subject }.not_to change { group.dependency_proxy_blobs.size }
expect { subject }.not_to change { group.dependency_proxy_manifests.size }
expect(subject).to be_nil
@@ -43,26 +38,26 @@ RSpec.describe PurgeDependencyProxyCacheWorker do
end
context 'when admin mode is disabled' do
- it_behaves_like 'returns nil'
+ it_behaves_like 'not removing blobs and manifests'
end
end
context 'a non-admin user' do
let(:user) { create(:user) }
- it_behaves_like 'returns nil'
+ it_behaves_like 'not removing blobs and manifests'
end
context 'an invalid user id' do
let(:user) { double('User', id: 99999 ) }
- it_behaves_like 'returns nil'
+ it_behaves_like 'not removing blobs and manifests'
end
context 'an invalid group' do
let(:group_id) { 99999 }
- it_behaves_like 'returns nil'
+ it_behaves_like 'not removing blobs and manifests'
end
end
end
diff --git a/spec/workers/stuck_ci_jobs_worker_spec.rb b/spec/workers/stuck_ci_jobs_worker_spec.rb
index 84b2d87494e..e0a5d3c6c1c 100644
--- a/spec/workers/stuck_ci_jobs_worker_spec.rb
+++ b/spec/workers/stuck_ci_jobs_worker_spec.rb
@@ -5,311 +5,50 @@ require 'spec_helper'
RSpec.describe StuckCiJobsWorker do
include ExclusiveLeaseHelpers
- let!(:runner) { create :ci_runner }
- let!(:job) { create :ci_build, runner: runner }
- let(:worker_lease_key) { StuckCiJobsWorker::EXCLUSIVE_LEASE_KEY }
+ let(:worker_lease_key) { StuckCiJobsWorker::EXCLUSIVE_LEASE_KEY }
let(:worker_lease_uuid) { SecureRandom.uuid }
- let(:created_at) { }
- let(:updated_at) { }
+ let(:worker2) { described_class.new }
subject(:worker) { described_class.new }
before do
stub_exclusive_lease(worker_lease_key, worker_lease_uuid)
- job_attributes = { status: status }
- job_attributes[:created_at] = created_at if created_at
- job_attributes[:updated_at] = updated_at if updated_at
- job.update!(job_attributes)
end
- shared_examples 'job is dropped' do
- it "changes status" do
- worker.perform
- job.reload
-
- expect(job).to be_failed
- expect(job).to be_stuck_or_timeout_failure
- end
-
- context 'when job have data integrity problem' do
- it "does drop the job and logs the reason" do
- job.update_columns(yaml_variables: '[{"key" => "value"}]')
-
- expect(Gitlab::ErrorTracking).to receive(:track_exception)
- .with(anything, a_hash_including(build_id: job.id))
- .once
- .and_call_original
-
- worker.perform
- job.reload
-
- expect(job).to be_failed
- expect(job).to be_data_integrity_failure
+ describe '#perform' do
+ it 'executes an instance of Ci::StuckBuildsDropService' do
+ expect_next_instance_of(Ci::StuckBuilds::DropService) do |service|
+ expect(service).to receive(:execute).exactly(:once)
end
- end
- end
- shared_examples 'job is unchanged' do
- before do
worker.perform
- job.reload
end
- it "doesn't change status" do
- expect(job.status).to eq(status)
- end
- end
-
- context 'when job is pending' do
- let(:status) { 'pending' }
-
- context 'when job is not stuck' do
- before do
- allow_any_instance_of(Ci::Build).to receive(:stuck?).and_return(false)
- end
-
- context 'when job was updated_at more than 1 day ago' do
- let(:updated_at) { 1.5.days.ago }
-
- context 'when created_at is the same as updated_at' do
- let(:created_at) { 1.5.days.ago }
-
- it_behaves_like 'job is dropped'
- end
-
- context 'when created_at is before updated_at' do
- let(:created_at) { 3.days.ago }
-
- it_behaves_like 'job is dropped'
- end
-
- context 'when created_at is outside lookback window' do
- let(:created_at) { described_class::BUILD_LOOKBACK - 1.day }
-
- it_behaves_like 'job is unchanged'
- end
- end
-
- context 'when job was updated less than 1 day ago' do
- let(:updated_at) { 6.hours.ago }
-
- context 'when created_at is the same as updated_at' do
- let(:created_at) { 1.5.days.ago }
-
- it_behaves_like 'job is unchanged'
- end
-
- context 'when created_at is before updated_at' do
- let(:created_at) { 3.days.ago }
-
- it_behaves_like 'job is unchanged'
- end
-
- context 'when created_at is outside lookback window' do
- let(:created_at) { described_class::BUILD_LOOKBACK - 1.day }
-
- it_behaves_like 'job is unchanged'
- end
- end
-
- context 'when job was updated more than 1 hour ago' do
- let(:updated_at) { 2.hours.ago }
-
- context 'when created_at is the same as updated_at' do
- let(:created_at) { 2.hours.ago }
-
- it_behaves_like 'job is unchanged'
- end
-
- context 'when created_at is before updated_at' do
- let(:created_at) { 3.days.ago }
-
- it_behaves_like 'job is unchanged'
- end
-
- context 'when created_at is outside lookback window' do
- let(:created_at) { described_class::BUILD_LOOKBACK - 1.day }
-
- it_behaves_like 'job is unchanged'
- end
- end
- end
-
- context 'when job is stuck' do
- before do
- allow_any_instance_of(Ci::Build).to receive(:stuck?).and_return(true)
- end
-
- context 'when job was updated_at more than 1 hour ago' do
- let(:updated_at) { 1.5.hours.ago }
-
- context 'when created_at is the same as updated_at' do
- let(:created_at) { 1.5.hours.ago }
-
- it_behaves_like 'job is dropped'
- end
-
- context 'when created_at is before updated_at' do
- let(:created_at) { 3.days.ago }
-
- it_behaves_like 'job is dropped'
- end
-
- context 'when created_at is outside lookback window' do
- let(:created_at) { described_class::BUILD_LOOKBACK - 1.day }
-
- it_behaves_like 'job is unchanged'
- end
- end
-
- context 'when job was updated in less than 1 hour ago' do
- let(:updated_at) { 30.minutes.ago }
-
- context 'when created_at is the same as updated_at' do
- let(:created_at) { 30.minutes.ago }
-
- it_behaves_like 'job is unchanged'
- end
-
- context 'when created_at is before updated_at' do
- let(:created_at) { 2.days.ago }
-
- it_behaves_like 'job is unchanged'
- end
+ context 'with an exclusive lease' do
+ it 'does not execute concurrently' do
+ expect(worker).to receive(:remove_lease).exactly(:once)
+ expect(worker2).not_to receive(:remove_lease)
- context 'when created_at is outside lookback window' do
- let(:created_at) { described_class::BUILD_LOOKBACK - 1.day }
-
- it_behaves_like 'job is unchanged'
- end
- end
- end
- end
-
- context 'when job is running' do
- let(:status) { 'running' }
-
- context 'when job was updated_at more than an hour ago' do
- let(:updated_at) { 2.hours.ago }
-
- it_behaves_like 'job is dropped'
- end
-
- context 'when job was updated in less than 1 hour ago' do
- let(:updated_at) { 30.minutes.ago }
-
- it_behaves_like 'job is unchanged'
- end
- end
-
- %w(success skipped failed canceled).each do |status|
- context "when job is #{status}" do
- let(:status) { status }
- let(:updated_at) { 2.days.ago }
-
- context 'when created_at is the same as updated_at' do
- let(:created_at) { 2.days.ago }
-
- it_behaves_like 'job is unchanged'
- end
-
- context 'when created_at is before updated_at' do
- let(:created_at) { 3.days.ago }
-
- it_behaves_like 'job is unchanged'
- end
+ worker.perform
- context 'when created_at is outside lookback window' do
- let(:created_at) { described_class::BUILD_LOOKBACK - 1.day }
+ stub_exclusive_lease_taken(worker_lease_key)
- it_behaves_like 'job is unchanged'
+ worker2.perform
end
- end
- end
-
- context 'for deleted project' do
- let(:status) { 'running' }
- let(:updated_at) { 2.days.ago }
-
- before do
- job.project.update!(pending_delete: true)
- end
-
- it 'does drop job' do
- expect_any_instance_of(Ci::Build).to receive(:drop).and_call_original
- worker.perform
- end
- end
-
- describe 'drop stale scheduled builds' do
- let(:status) { 'scheduled' }
- let(:updated_at) { }
-
- context 'when scheduled at 2 hours ago but it is not executed yet' do
- let!(:job) { create(:ci_build, :scheduled, scheduled_at: 2.hours.ago) }
- it 'drops the stale scheduled build' do
- expect(Ci::Build.scheduled.count).to eq(1)
- expect(job).to be_scheduled
+ it 'can execute in sequence' do
+ expect(worker).to receive(:remove_lease).at_least(:once)
+ expect(worker2).to receive(:remove_lease).at_least(:once)
worker.perform
- job.reload
-
- expect(Ci::Build.scheduled.count).to eq(0)
- expect(job).to be_failed
- expect(job).to be_stale_schedule
+ worker2.perform
end
- end
-
- context 'when scheduled at 30 minutes ago but it is not executed yet' do
- let!(:job) { create(:ci_build, :scheduled, scheduled_at: 30.minutes.ago) }
- it 'does not drop the stale scheduled build yet' do
- expect(Ci::Build.scheduled.count).to eq(1)
- expect(job).to be_scheduled
+ it 'cancels exclusive leases after worker perform' do
+ expect_to_cancel_exclusive_lease(worker_lease_key, worker_lease_uuid)
worker.perform
-
- expect(Ci::Build.scheduled.count).to eq(1)
- expect(job).to be_scheduled
- end
- end
-
- context 'when there are no stale scheduled builds' do
- it 'does not drop the stale scheduled build yet' do
- expect { worker.perform }.not_to raise_error
end
end
end
-
- describe 'exclusive lease' do
- let(:status) { 'running' }
- let(:updated_at) { 2.days.ago }
- let(:worker2) { described_class.new }
-
- it 'is guard by exclusive lease when executed concurrently' do
- expect(worker).to receive(:drop).at_least(:once).and_call_original
- expect(worker2).not_to receive(:drop)
-
- worker.perform
-
- stub_exclusive_lease_taken(worker_lease_key)
-
- worker2.perform
- end
-
- it 'can be executed in sequence' do
- expect(worker).to receive(:drop).at_least(:once).and_call_original
- expect(worker2).to receive(:drop).at_least(:once).and_call_original
-
- worker.perform
- worker2.perform
- end
-
- it 'cancels exclusive leases after worker perform' do
- expect_to_cancel_exclusive_lease(worker_lease_key, worker_lease_uuid)
-
- worker.perform
- end
- end
end
diff --git a/spec/workers/todos_destroyer/destroyed_designs_worker_spec.rb b/spec/workers/todos_destroyer/destroyed_designs_worker_spec.rb
new file mode 100644
index 00000000000..113faeb0d2f
--- /dev/null
+++ b/spec/workers/todos_destroyer/destroyed_designs_worker_spec.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe TodosDestroyer::DestroyedDesignsWorker do
+ let(:service) { double }
+
+ it 'calls the Todos::Destroy::DesignService with design_ids parameter' do
+ expect(::Todos::Destroy::DesignService).to receive(:new).with([1, 5]).and_return(service)
+ expect(service).to receive(:execute)
+
+ described_class.new.perform([1, 5])
+ end
+end
diff --git a/storybook/config/preview.js b/storybook/config/preview.js
index a372aea68ad..4f496665de6 100644
--- a/storybook/config/preview.js
+++ b/storybook/config/preview.js
@@ -1,7 +1,15 @@
+// eslint-disable-next-line import/no-extraneous-dependencies
+import Vue from 'vue';
+import translateMixin from '../../app/assets/javascripts/vue_shared/translate';
+
const stylesheetsRequireCtx = require.context(
'../../app/assets/stylesheets',
true,
- /application\.scss$/,
+ /(application|application_utilities)\.scss$/,
);
+window.gon = {};
+translateMixin(Vue);
+
stylesheetsRequireCtx('./application.scss');
+stylesheetsRequireCtx('./application_utilities.scss');
diff --git a/storybook/package.json b/storybook/package.json
index 028133dd5e3..4b922a4776c 100644
--- a/storybook/package.json
+++ b/storybook/package.json
@@ -5,7 +5,9 @@
"start": "start-storybook -p 9002 -c config",
"build": "build-storybook -c config -o public"
},
- "dependencies": {},
+ "blockedDependencies": {
+ "vue": "https://gitlab.com/gitlab-org/gitlab/-/issues/340511"
+ },
"devDependencies": {
"@storybook/addon-a11y": "^6.2.9",
"@storybook/addon-actions": "^6.2.9",
diff --git a/tooling/bin/find_changes b/tooling/bin/find_changes
new file mode 100755
index 00000000000..466510ccb19
--- /dev/null
+++ b/tooling/bin/find_changes
@@ -0,0 +1,21 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+require 'gitlab'
+
+gitlab_token = ENV.fetch('DANGER_GITLAB_API_TOKEN', '')
+gitlab_endpoint = ENV.fetch('CI_API_V4_URL')
+mr_project_path = ENV.fetch('CI_MERGE_REQUEST_PROJECT_PATH')
+mr_iid = ENV.fetch('CI_MERGE_REQUEST_IID')
+
+output_file = ARGV.shift
+
+Gitlab.configure do |config|
+ config.endpoint = gitlab_endpoint
+ config.private_token = gitlab_token
+end
+
+mr_changes = Gitlab.merge_request_changes(mr_project_path, mr_iid)
+file_changes = mr_changes.changes.map { |change| change['new_path'] }
+
+File.write(output_file, file_changes.join(' '))
diff --git a/tooling/bin/find_tests b/tooling/bin/find_tests
index 97fadf406fe..33834064f36 100755
--- a/tooling/bin/find_tests
+++ b/tooling/bin/find_tests
@@ -1,24 +1,12 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
-require 'gitlab'
require 'test_file_finder'
-gitlab_token = ENV.fetch('DANGER_GITLAB_API_TOKEN', '')
-gitlab_endpoint = ENV.fetch('CI_API_V4_URL')
-
-Gitlab.configure do |config|
- config.endpoint = gitlab_endpoint
- config.private_token = gitlab_token
-end
-
+changes = ARGV.shift
output_file = ARGV.shift
-mr_project_path = ENV.fetch('CI_MERGE_REQUEST_PROJECT_PATH')
-mr_iid = ENV.fetch('CI_MERGE_REQUEST_IID')
-
-mr_changes = Gitlab.merge_request_changes(mr_project_path, mr_iid)
-changed_files = mr_changes.changes.map { |change| change['new_path'] }
+changed_files = File.read(changes).split(' ')
tff = TestFileFinder::FileFinder.new(paths: changed_files).tap do |file_finder|
file_finder.use TestFileFinder::MappingStrategies::PatternMatching.load('tests.yml')
diff --git a/tooling/danger/product_intelligence.rb b/tooling/danger/product_intelligence.rb
index 9eab611ec68..30c961184f5 100644
--- a/tooling/danger/product_intelligence.rb
+++ b/tooling/danger/product_intelligence.rb
@@ -70,7 +70,7 @@ module Tooling
'data-track-action'
)
all_changed_files.select do |file|
- matching_files?(file, extension: '.rb', pattern: %r{Gitlab::Tracking\.(event|enabled\?|snowplow_options)$}) ||
+ matching_files?(file, extension: '.rb', pattern: %r{Gitlab::Tracking\.(event|enabled\?|options)$}) ||
matching_files?(file, extension: '.js', pattern: js_patterns) ||
matching_files?(file, extension: '.vue', pattern: js_patterns) ||
matching_files?(file, extension: '.haml', pattern: %r{data: \{ track})
diff --git a/tooling/danger/project_helper.rb b/tooling/danger/project_helper.rb
index 07daf249023..109f77ed4d1 100644
--- a/tooling/danger/project_helper.rb
+++ b/tooling/danger/project_helper.rb
@@ -10,7 +10,6 @@ module Tooling
duplicate_yarn_dependencies
eslint
gitaly
- karma
pajamas
pipeline
prettier
@@ -37,7 +36,7 @@ module Tooling
CATEGORIES = {
[%r{usage_data\.rb}, %r{^(\+|-).*\s+(count|distinct_count|estimate_batch_distinct_count)\(.*\)(.*)$}] => [:database, :backend, :product_intelligence],
- %r{\A(ee/)?config/feature_flags/} => :feature_flag,
+ %r{\A((ee|jh)/)?config/feature_flags/} => :feature_flag,
%r{\Adoc/.*(\.(md|png|gif|jpg|yml))\z} => :docs,
%r{\A(CONTRIBUTING|LICENSE|MAINTENANCE|PHILOSOPHY|PROCESS|README)(\.md)?\z} => :docs,
@@ -48,11 +47,11 @@ module Tooling
spec/frontend/tracking/.*\.js |
spec/frontend/tracking_spec\.js
)\z}x => [:frontend, :product_intelligence],
- %r{\A(ee/)?app/(assets|views)/} => :frontend,
- %r{\A(ee/)?public/} => :frontend,
- %r{\A(ee/)?spec/(javascripts|frontend|frontend_integration)/} => :frontend,
- %r{\A(ee/)?vendor/assets/} => :frontend,
- %r{\A(ee/)?scripts/frontend/} => :frontend,
+ %r{\A((ee|jh)/)?app/(assets|views)/} => :frontend,
+ %r{\A((ee|jh)/)?public/} => :frontend,
+ %r{\A((ee|jh)/)?spec/(javascripts|frontend|frontend_integration)/} => :frontend,
+ %r{\A((ee|jh)/)?vendor/assets/} => :frontend,
+ %r{\A((ee|jh)/)?scripts/frontend/} => :frontend,
%r{(\A|/)(
\.babelrc |
\.browserslistrc |
@@ -75,12 +74,12 @@ module Tooling
\.gitlab/ci/frontend\.gitlab-ci\.yml
)\z}x => %i[frontend tooling],
- %r{\A(ee/)?db/(geo/)?(migrate|post_migrate)/} => [:database, :migration],
- %r{\A(ee/)?db/(?!fixtures)[^/]+} => [:database],
- %r{\A(ee/)?lib/gitlab/(database|background_migration|sql|github_import)(/|\.rb)} => [:database, :backend],
+ %r{\A((ee|jh)/)?db/(geo/)?(migrate|post_migrate)/} => [:database, :migration],
+ %r{\A((ee|jh)/)?db/(?!fixtures)[^/]+} => [:database],
+ %r{\A((ee|jh)/)?lib/gitlab/(database|background_migration|sql|github_import)(/|\.rb)} => [:database, :backend],
%r{\A(app/services/authorized_project_update/find_records_due_for_refresh_service)(/|\.rb)} => [:database, :backend],
%r{\A(app/models/project_authorization|app/services/users/refresh_authorized_projects_service)(/|\.rb)} => [:database, :backend],
- %r{\A(ee/)?app/finders/} => [:database, :backend],
+ %r{\A((ee|jh)/)?app/finders/} => [:database, :backend],
%r{\Arubocop/cop/migration(/|\.rb)} => :database,
%r{\A(\.gitlab-ci\.yml\z|\.gitlab\/ci)} => :tooling,
@@ -88,22 +87,22 @@ module Tooling
%r{\Alefthook.yml\z} => :tooling,
%r{\A\.editorconfig\z} => :tooling,
%r{Dangerfile\z} => :tooling,
- %r{\A(ee/)?(danger/|tooling/danger/)} => :tooling,
- %r{\A(ee/)?scripts/} => :tooling,
+ %r{\A((ee|jh)/)?(danger/|tooling/danger/)} => :tooling,
+ %r{\A((ee|jh)/)?scripts/} => :tooling,
%r{\Atooling/} => :tooling,
%r{(CODEOWNERS)} => :tooling,
%r{(tests.yml)} => :tooling,
%r{\Alib/gitlab/ci/templates} => :ci_template,
- %r{\A(ee/)?spec/features/} => :test,
- %r{\A(ee/)?spec/support/shared_examples/features/} => :test,
- %r{\A(ee/)?spec/support/shared_contexts/features/} => :test,
- %r{\A(ee/)?spec/support/helpers/features/} => :test,
+ %r{\A((ee|jh)/)?spec/features/} => :test,
+ %r{\A((ee|jh)/)?spec/support/shared_examples/features/} => :test,
+ %r{\A((ee|jh)/)?spec/support/shared_contexts/features/} => :test,
+ %r{\A((ee|jh)/)?spec/support/helpers/features/} => :test,
- %r{\A(ee/)?lib/gitlab/usage_data_counters/.*\.yml\z} => [:product_intelligence],
- %r{\A(ee/)?config/metrics/((.*\.yml)|(schema\.json))\z} => [:product_intelligence],
- %r{\A(ee/)?lib/gitlab/usage_data(_counters)?(/|\.rb)} => [:backend, :product_intelligence],
+ %r{\A((ee|jh)/)?lib/gitlab/usage_data_counters/.*\.yml\z} => [:product_intelligence],
+ %r{\A((ee|jh)/)?config/metrics/((.*\.yml)|(schema\.json))\z} => [:product_intelligence],
+ %r{\A((ee|jh)/)?lib/gitlab/usage_data(_counters)?(/|\.rb)} => [:backend, :product_intelligence],
%r{\A(
lib/gitlab/tracking\.rb |
spec/lib/gitlab/tracking_spec\.rb |
@@ -112,21 +111,21 @@ module Tooling
lib/generators/rails/usage_metric_definition_generator\.rb |
spec/lib/generators/usage_metric_definition_generator_spec\.rb |
generator_templates/usage_metric_definition/metric_definition\.yml)\z}x => [:backend, :product_intelligence],
- %r{\A(ee/)?app/(?!assets|views)[^/]+} => :backend,
- %r{\A(ee/)?(bin|config|generator_templates|lib|rubocop)/} => :backend,
- %r{\A(ee/)?spec/} => :backend,
- %r{\A(ee/)?vendor/} => :backend,
+ %r{\A((ee|jh)/)?app/(?!assets|views)[^/]+} => :backend,
+ %r{\A((ee|jh)/)?(bin|config|generator_templates|lib|rubocop)/} => :backend,
+ %r{\A((ee|jh)/)?spec/} => :backend,
+ %r{\A((ee|jh)/)?vendor/} => :backend,
%r{\A(Gemfile|Gemfile.lock|Rakefile)\z} => :backend,
%r{\A[A-Z_]+_VERSION\z} => :backend,
%r{\A\.rubocop((_manual)?_todo)?\.yml\z} => :backend,
%r{\Afile_hooks/} => :backend,
- %r{\A(ee/)?qa/} => :qa,
+ %r{\A((ee|jh)/)?qa/} => :qa,
%r{\Aworkhorse/.*} => :workhorse,
# Files that don't fit into any category are marked with :none
- %r{\A(ee/)?changelogs/} => :none,
+ %r{\A((ee|jh)/)?changelogs/} => :none,
%r{\Alocale/gitlab\.pot\z} => :none,
# GraphQL auto generated doc files and schema
diff --git a/tooling/deprecations/docs.rb b/tooling/deprecations/docs.rb
new file mode 100644
index 00000000000..adc3e0edb10
--- /dev/null
+++ b/tooling/deprecations/docs.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+require 'erb'
+
+module Deprecations
+ module Docs
+ module_function
+
+ def path
+ Rails.root.join("doc/update/deprecations.md")
+ end
+
+ def render
+ deprecations_yaml_glob = Rails.root.join("data/deprecations/**/*.yml")
+
+ source_files = Rake::FileList.new(deprecations_yaml_glob) do |fl|
+ fl.exclude(/example\.yml$/)
+ end
+
+ deprecations = source_files.flat_map do |file|
+ YAML.load_file(file)
+ end
+
+ deprecations = VersionSorter.rsort(deprecations) { |d| d["removal_milestone"] }
+
+ milestones = deprecations.map { |d| d["removal_milestone"] }.uniq
+
+ template = Rails.root.join("data/deprecations/templates/_deprecation_template.md.erb")
+
+ load_template(template)
+ .result_with_hash(deprecations: deprecations, milestones: milestones)
+ end
+
+ def load_template(filename)
+ ERB.new(File.read(filename), trim_mode: '-')
+ end
+ end
+end
diff --git a/tooling/graphql/docs/helper.rb b/tooling/graphql/docs/helper.rb
index 4a41930df46..ca153c806c4 100644
--- a/tooling/graphql/docs/helper.rb
+++ b/tooling/graphql/docs/helper.rb
@@ -55,8 +55,8 @@ module Tooling
def auto_generated_comment
<<-MD.strip_heredoc
---
- stage: Plan
- group: Project Management
+ stage: Ecosystem
+ group: Integrations
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/#designated-technical-writers
---
diff --git a/vendor/assets/javascripts/jasmine-jquery.js b/vendor/assets/javascripts/jasmine-jquery.js
deleted file mode 100644
index a1f1e892c57..00000000000
--- a/vendor/assets/javascripts/jasmine-jquery.js
+++ /dev/null
@@ -1,854 +0,0 @@
-/* eslint-disable */
-/*
- Jasmine JQuery 3.0 patched version from this fork : https://github.com/cmrd-senya/jasmine-jquery/blob/jquery3/lib/jasmine-jquery.js
-*/
-/*!
-Jasmine-jQuery: a set of jQuery helpers for Jasmine tests.
-
-Version 2.1.1
-
-https://github.com/velesin/jasmine-jquery
-
-Copyright (c) 2010-2014 Wojciech Zawistowski, Travis Jeffery
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-(function (root, factory) {
- if (typeof module !== 'undefined' && module.exports) {
- // The line below is patched from jquery => jquery/dist/jquery
- // in order to load a jQuery with ajax, so that this testing library
- // doesn't break
- factory(root, root.jasmine, require('jquery/dist/jquery'));
- } else {
- factory(root, root.jasmine, root.jQuery);
- }
-}((function() {return this; })(), function (window, jasmine, $) { "use strict";
-
- jasmine.spiedEventsKey = function (selector, eventName) {
- for(var i = 0;; i++) {
- var key = [eventName, i].toString()
- if (data.spiedEvents[key] === undefined || data.spiedEvents[key].selector.is($(selector))) {
- return key
- }
- }
- }
-
- jasmine.getFixtures = function () {
- return jasmine.currentFixtures_ = jasmine.currentFixtures_ || new jasmine.Fixtures()
- }
-
- jasmine.getStyleFixtures = function () {
- return jasmine.currentStyleFixtures_ = jasmine.currentStyleFixtures_ || new jasmine.StyleFixtures()
- }
-
- jasmine.Fixtures = function () {
- this.containerId = 'jasmine-fixtures'
- this.fixturesCache_ = {}
- this.fixturesPath = 'spec/javascripts/fixtures'
- }
-
- jasmine.Fixtures.prototype.set = function (html) {
- this.cleanUp()
- return this.createContainer_(html)
- }
-
- jasmine.Fixtures.prototype.appendSet= function (html) {
- this.addToContainer_(html)
- }
-
- jasmine.Fixtures.prototype.preload = function () {
- this.read.apply(this, arguments)
- }
-
- jasmine.Fixtures.prototype.load = function () {
- this.cleanUp()
- this.createContainer_(this.read.apply(this, arguments))
- }
-
- jasmine.Fixtures.prototype.appendLoad = function () {
- this.addToContainer_(this.read.apply(this, arguments))
- }
-
- jasmine.Fixtures.prototype.read = function () {
- var htmlChunks = []
- , fixtureUrls = arguments
-
- for(var urlCount = fixtureUrls.length, urlIndex = 0; urlIndex < urlCount; urlIndex++) {
- htmlChunks.push(this.getFixtureHtml_(fixtureUrls[urlIndex]))
- }
-
- return htmlChunks.join('')
- }
-
- jasmine.Fixtures.prototype.clearCache = function () {
- this.fixturesCache_ = {}
- }
-
- jasmine.Fixtures.prototype.cleanUp = function () {
- $('#' + this.containerId).remove()
- }
-
- jasmine.Fixtures.prototype.sandbox = function (attributes) {
- var attributesToSet = attributes || {}
- return $('<div id="sandbox" />').attr(attributesToSet)
- }
-
- jasmine.Fixtures.prototype.createContainer_ = function (html) {
- var container = $('<div>')
- .attr('id', this.containerId)
- .html(html)
-
- $(document.body).append(container)
- return container
- }
-
- jasmine.Fixtures.prototype.addToContainer_ = function (html){
- var container = $(document.body).find('#'+this.containerId).append(html)
-
- if (!container.length) {
- this.createContainer_(html)
- }
- }
-
- jasmine.Fixtures.prototype.getFixtureHtml_ = function (url) {
- if (typeof this.fixturesCache_[url] === 'undefined') {
- this.loadFixtureIntoCache_(url)
- }
- return this.fixturesCache_[url]
- }
-
- jasmine.Fixtures.prototype.loadFixtureIntoCache_ = function (relativeUrl) {
- var self = this
- , url = this.makeFixtureUrl_(relativeUrl)
- , htmlText = ''
- , request = $.ajax({
- async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded
- cache: false,
- url: url,
- dataType: 'html',
- success: function (data, status, $xhr) {
- htmlText = $xhr.responseText
- }
- }).fail(function ($xhr, status, err) {
- throw new Error('Fixture could not be loaded: ' + url + ' (status: ' + status + ', message: ' + err.message + ')')
- })
-
- var scripts = $($.parseHTML(htmlText, true)).find('script[src]') || [];
-
- scripts.each(function(){
- $.ajax({
- async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded
- cache: false,
- dataType: 'script',
- url: $(this).attr('src'),
- success: function (data, status, $xhr) {
- htmlText += '<script>' + $xhr.responseText + '</script>'
- },
- error: function ($xhr, status, err) {
- throw new Error('Script could not be loaded: ' + url + ' (status: ' + status + ', message: ' + err.message + ')')
- }
- });
- })
-
- self.fixturesCache_[relativeUrl] = htmlText;
- }
-
- jasmine.Fixtures.prototype.makeFixtureUrl_ = function (relativeUrl){
- return this.fixturesPath.match('/$') ? this.fixturesPath + relativeUrl : this.fixturesPath + '/' + relativeUrl
- }
-
- jasmine.Fixtures.prototype.proxyCallTo_ = function (methodName, passedArguments) {
- return this[methodName].apply(this, passedArguments)
- }
-
-
- jasmine.StyleFixtures = function () {
- this.fixturesCache_ = {}
- this.fixturesNodes_ = []
- this.fixturesPath = 'spec/javascripts/fixtures'
- }
-
- jasmine.StyleFixtures.prototype.set = function (css) {
- this.cleanUp()
- this.createStyle_(css)
- }
-
- jasmine.StyleFixtures.prototype.appendSet = function (css) {
- this.createStyle_(css)
- }
-
- jasmine.StyleFixtures.prototype.preload = function () {
- this.read_.apply(this, arguments)
- }
-
- jasmine.StyleFixtures.prototype.load = function () {
- this.cleanUp()
- this.createStyle_(this.read_.apply(this, arguments))
- }
-
- jasmine.StyleFixtures.prototype.appendLoad = function () {
- this.createStyle_(this.read_.apply(this, arguments))
- }
-
- jasmine.StyleFixtures.prototype.cleanUp = function () {
- while(this.fixturesNodes_.length) {
- this.fixturesNodes_.pop().remove()
- }
- }
-
- jasmine.StyleFixtures.prototype.createStyle_ = function (html) {
- var styleText = $('<div></div>').html(html).text()
- , style = $('<style>' + styleText + '</style>')
-
- this.fixturesNodes_.push(style)
- $('head').append(style)
- }
-
- jasmine.StyleFixtures.prototype.clearCache = jasmine.Fixtures.prototype.clearCache
- jasmine.StyleFixtures.prototype.read_ = jasmine.Fixtures.prototype.read
- jasmine.StyleFixtures.prototype.getFixtureHtml_ = jasmine.Fixtures.prototype.getFixtureHtml_
- jasmine.StyleFixtures.prototype.loadFixtureIntoCache_ = jasmine.Fixtures.prototype.loadFixtureIntoCache_
- jasmine.StyleFixtures.prototype.makeFixtureUrl_ = jasmine.Fixtures.prototype.makeFixtureUrl_
- jasmine.StyleFixtures.prototype.proxyCallTo_ = jasmine.Fixtures.prototype.proxyCallTo_
-
- jasmine.getJSONFixtures = function () {
- return jasmine.currentJSONFixtures_ = jasmine.currentJSONFixtures_ || new jasmine.JSONFixtures()
- }
-
- jasmine.JSONFixtures = function () {
- this.fixturesCache_ = {}
- this.fixturesPath = 'spec/javascripts/fixtures/json'
- }
-
- jasmine.JSONFixtures.prototype.load = function () {
- this.read.apply(this, arguments)
- return this.fixturesCache_
- }
-
- jasmine.JSONFixtures.prototype.read = function () {
- var fixtureUrls = arguments
-
- for(var urlCount = fixtureUrls.length, urlIndex = 0; urlIndex < urlCount; urlIndex++) {
- this.getFixtureData_(fixtureUrls[urlIndex])
- }
-
- return this.fixturesCache_
- }
-
- jasmine.JSONFixtures.prototype.clearCache = function () {
- this.fixturesCache_ = {}
- }
-
- jasmine.JSONFixtures.prototype.getFixtureData_ = function (url) {
- if (!this.fixturesCache_[url]) this.loadFixtureIntoCache_(url)
- return this.fixturesCache_[url]
- }
-
- jasmine.JSONFixtures.prototype.loadFixtureIntoCache_ = function (relativeUrl) {
- var self = this
- , url = this.fixturesPath.match('/$') ? this.fixturesPath + relativeUrl : this.fixturesPath + '/' + relativeUrl
-
- $.ajax({
- async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded
- cache: false,
- dataType: 'json',
- url: url,
- success: function (data) {
- self.fixturesCache_[relativeUrl] = data
- },
- error: function ($xhr, status, err) {
- throw new Error('JSONFixture could not be loaded: ' + url + ' (status: ' + status + ', message: ' + err.message + ')')
- }
- })
- }
-
- jasmine.JSONFixtures.prototype.proxyCallTo_ = function (methodName, passedArguments) {
- return this[methodName].apply(this, passedArguments)
- }
-
- jasmine.jQuery = function () {}
-
- jasmine.jQuery.browserTagCaseIndependentHtml = function (html) {
- return $('<div/>').append(html).html()
- }
-
- jasmine.jQuery.elementToString = function (element) {
- return $(element).map(function () { return this.outerHTML; }).toArray().join(', ')
- }
-
- var data = {
- spiedEvents: {}
- , handlers: []
- }
-
- jasmine.jQuery.events = {
- spyOn: function (selector, eventName) {
- var handler = function (e) {
- var calls = (typeof data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] !== 'undefined') ? data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)].calls : 0
- data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] = {
- selector: $(selector),
- args: jasmine.util.argsToArray(arguments),
- calls: ++calls
- }
- }
-
- $(selector).on(eventName, handler)
- data.handlers.push(handler)
-
- return {
- selector: selector,
- eventName: eventName,
- handler: handler,
- reset: function (){
- delete data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)]
- },
- calls: {
- count: function () {
- return data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] ?
- data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)].calls : 0;
- },
- any: function () {
- return data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] ?
- !!data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)].calls : false;
- }
- }
- }
- },
-
- args: function (selector, eventName) {
- var actualArgs = data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)].args
-
- if (!actualArgs) {
- throw "There is no spy for " + eventName + " on " + selector.toString() + ". Make sure to create a spy using spyOnEvent."
- }
-
- return actualArgs
- },
-
- wasTriggered: function (selector, eventName) {
- return !!(data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)])
- },
-
- wasTriggeredWith: function (selector, eventName, expectedArgs, util, customEqualityTesters) {
- var actualArgs = jasmine.jQuery.events.args(selector, eventName).slice(1)
-
- if (Object.prototype.toString.call(expectedArgs) !== '[object Array]')
- actualArgs = actualArgs[0]
-
- return util.equals(actualArgs, expectedArgs, customEqualityTesters)
- },
-
- wasPrevented: function (selector, eventName) {
- var spiedEvent = data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)]
- , args = (jasmine.util.isUndefined(spiedEvent)) ? {} : spiedEvent.args
- , e = args ? args[0] : undefined
-
- return e && e.isDefaultPrevented()
- },
-
- wasStopped: function (selector, eventName) {
- var spiedEvent = data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)]
- , args = (jasmine.util.isUndefined(spiedEvent)) ? {} : spiedEvent.args
- , e = args ? args[0] : undefined
-
- return e && e.isPropagationStopped()
- },
-
- cleanUp: function () {
- data.spiedEvents = {}
- data.handlers = []
- }
- }
-
- var hasProperty = function (actualValue, expectedValue) {
- if (expectedValue === undefined)
- return actualValue !== undefined
-
- return actualValue === expectedValue
- }
-
- beforeEach(function () {
- jasmine.addMatchers({
- toHaveClass: function () {
- return {
- compare: function (actual, className) {
- return { pass: $(actual).hasClass(className) }
- }
- }
- },
-
- toHaveCss: function () {
- return {
- compare: function (actual, css) {
- var stripCharsRegex = /[\s;\"\']/g
- for (var prop in css) {
- var value = css[prop]
- // see issue #147 on gh
- ;if ((value === 'auto') && ($(actual).get(0).style[prop] === 'auto')) continue
- var actualStripped = $(actual).css(prop).replace(stripCharsRegex, '')
- var valueStripped = value.replace(stripCharsRegex, '')
- if (actualStripped !== valueStripped) return { pass: false }
- }
- return { pass: true }
- }
- }
- },
-
- toBeVisible: function () {
- return {
- compare: function (actual) {
- return { pass: $(actual).is(':visible') }
- }
- }
- },
-
- toBeHidden: function () {
- return {
- compare: function (actual) {
- return { pass: $(actual).is(':hidden') }
- }
- }
- },
-
- toBeSelected: function () {
- return {
- compare: function (actual) {
- return { pass: $(actual).is(':selected') }
- }
- }
- },
-
- toBeChecked: function () {
- return {
- compare: function (actual) {
- return { pass: $(actual).is(':checked') }
- }
- }
- },
-
- toBeEmpty: function () {
- return {
- compare: function (actual) {
- return { pass: $(actual).is(':empty') }
- }
- }
- },
-
- toBeInDOM: function () {
- return {
- compare: function (actual) {
- return { pass: $.contains(document.documentElement, $(actual)[0]) }
- }
- }
- },
-
- toExist: function () {
- return {
- compare: function (actual) {
- return { pass: $(actual).length }
- }
- }
- },
-
- toHaveLength: function () {
- return {
- compare: function (actual, length) {
- return { pass: $(actual).length === length }
- }
- }
- },
-
- toHaveAttr: function () {
- return {
- compare: function (actual, attributeName, expectedAttributeValue) {
- return { pass: hasProperty($(actual).attr(attributeName), expectedAttributeValue) }
- }
- }
- },
-
- toHaveProp: function () {
- return {
- compare: function (actual, propertyName, expectedPropertyValue) {
- return { pass: hasProperty($(actual).prop(propertyName), expectedPropertyValue) }
- }
- }
- },
-
- toHaveId: function () {
- return {
- compare: function (actual, id) {
- return { pass: $(actual).attr('id') == id }
- }
- }
- },
-
- toHaveHtml: function () {
- return {
- compare: function (actual, html) {
- return { pass: $(actual).html() == jasmine.jQuery.browserTagCaseIndependentHtml(html) }
- }
- }
- },
-
- toContainHtml: function () {
- return {
- compare: function (actual, html) {
- var actualHtml = $(actual).html()
- , expectedHtml = jasmine.jQuery.browserTagCaseIndependentHtml(html)
-
- return { pass: (actualHtml.indexOf(expectedHtml) >= 0) }
- }
- }
- },
-
- toHaveText: function () {
- return {
- compare: function (actual, text) {
- var actualText = $(actual).text()
- var trimmedText = $.trim(actualText)
-
- if (text && $.isFunction(text.test)) {
- return { pass: text.test(actualText) || text.test(trimmedText) }
- } else {
- return { pass: (actualText == text || trimmedText == text) }
- }
- }
- }
- },
-
- toContainText: function () {
- return {
- compare: function (actual, text) {
- var trimmedText = $.trim($(actual).text())
-
- if (text && $.isFunction(text.test)) {
- return { pass: text.test(trimmedText) }
- } else {
- return { pass: trimmedText.indexOf(text) != -1 }
- }
- }
- }
- },
-
- toHaveValue: function () {
- return {
- compare: function (actual, value) {
- return { pass: $(actual).val() === value }
- }
- }
- },
-
- toHaveData: function () {
- return {
- compare: function (actual, key, expectedValue) {
- return { pass: hasProperty($(actual).data(key), expectedValue) }
- }
- }
- },
-
- toContainElement: function () {
- return {
- compare: function (actual, selector) {
- return { pass: $(actual).find(selector).length }
- }
- }
- },
-
- toBeMatchedBy: function () {
- return {
- compare: function (actual, selector) {
- return { pass: $(actual).filter(selector).length }
- }
- }
- },
-
- toBeDisabled: function () {
- return {
- compare: function (actual, selector) {
- return { pass: $(actual).is(':disabled') }
- }
- }
- },
-
- toBeFocused: function (selector) {
- return {
- compare: function (actual, selector) {
- return { pass: $(actual)[0] === $(actual)[0].ownerDocument.activeElement }
- }
- }
- },
-
- toHandle: function () {
- return {
- compare: function (actual, event) {
- if ( !actual || actual.length === 0 ) return { pass: false };
- var events = $._data($(actual).get(0), "events")
-
- if (!events || !event || typeof event !== "string") {
- return { pass: false }
- }
-
- var namespaces = event.split(".")
- , eventType = namespaces.shift()
- , sortedNamespaces = namespaces.slice(0).sort()
- , namespaceRegExp = new RegExp("(^|\\.)" + sortedNamespaces.join("\\.(?:.*\\.)?") + "(\\.|$)")
-
- if (events[eventType] && namespaces.length) {
- for (var i = 0; i < events[eventType].length; i++) {
- var namespace = events[eventType][i].namespace
-
- if (namespaceRegExp.test(namespace))
- return { pass: true }
- }
- } else {
- return { pass: (events[eventType] && events[eventType].length > 0) }
- }
-
- return { pass: false }
- }
- }
- },
-
- toHandleWith: function () {
- return {
- compare: function (actual, eventName, eventHandler) {
- if ( !actual || actual.length === 0 ) return { pass: false };
- var normalizedEventName = eventName.split('.')[0]
- , stack = $._data($(actual).get(0), "events")[normalizedEventName]
-
- for (var i = 0; i < stack.length; i++) {
- if (stack[i].handler == eventHandler) return { pass: true }
- }
-
- return { pass: false }
- }
- }
- },
-
- toHaveBeenTriggeredOn: function () {
- return {
- compare: function (actual, selector) {
- var result = { pass: jasmine.jQuery.events.wasTriggered(selector, actual) }
-
- result.message = result.pass ?
- "Expected event " + $(actual) + " not to have been triggered on " + selector :
- "Expected event " + $(actual) + " to have been triggered on " + selector
-
- return result;
- }
- }
- },
-
- toHaveBeenTriggered: function (){
- return {
- compare: function (actual) {
- var eventName = actual.eventName
- , selector = actual.selector
- , result = { pass: jasmine.jQuery.events.wasTriggered(selector, eventName) }
-
- result.message = result.pass ?
- "Expected event " + eventName + " not to have been triggered on " + selector :
- "Expected event " + eventName + " to have been triggered on " + selector
-
- return result
- }
- }
- },
-
- toHaveBeenTriggeredOnAndWith: function (j$, customEqualityTesters) {
- return {
- compare: function (actual, selector, expectedArgs) {
- var wasTriggered = jasmine.jQuery.events.wasTriggered(selector, actual)
- , result = { pass: wasTriggered && jasmine.jQuery.events.wasTriggeredWith(selector, actual, expectedArgs, j$, customEqualityTesters) }
-
- if (wasTriggered) {
- var actualArgs = jasmine.jQuery.events.args(selector, actual, expectedArgs)[1]
- result.message = result.pass ?
- "Expected event " + actual + " not to have been triggered with " + jasmine.pp(expectedArgs) + " but it was triggered with " + jasmine.pp(actualArgs) :
- "Expected event " + actual + " to have been triggered with " + jasmine.pp(expectedArgs) + " but it was triggered with " + jasmine.pp(actualArgs)
-
- } else {
- // todo check on this
- result.message = result.pass ?
- "Expected event " + actual + " not to have been triggered on " + selector :
- "Expected event " + actual + " to have been triggered on " + selector
- }
-
- return result
- }
- }
- },
-
- toHaveBeenPreventedOn: function () {
- return {
- compare: function (actual, selector) {
- var result = { pass: jasmine.jQuery.events.wasPrevented(selector, actual) }
-
- result.message = result.pass ?
- "Expected event " + actual + " not to have been prevented on " + selector :
- "Expected event " + actual + " to have been prevented on " + selector
-
- return result
- }
- }
- },
-
- toHaveBeenPrevented: function () {
- return {
- compare: function (actual) {
- var eventName = actual.eventName
- , selector = actual.selector
- , result = { pass: jasmine.jQuery.events.wasPrevented(selector, eventName) }
-
- result.message = result.pass ?
- "Expected event " + eventName + " not to have been prevented on " + selector :
- "Expected event " + eventName + " to have been prevented on " + selector
-
- return result
- }
- }
- },
-
- toHaveBeenStoppedOn: function () {
- return {
- compare: function (actual, selector) {
- var result = { pass: jasmine.jQuery.events.wasStopped(selector, actual) }
-
- result.message = result.pass ?
- "Expected event " + actual + " not to have been stopped on " + selector :
- "Expected event " + actual + " to have been stopped on " + selector
-
- return result;
- }
- }
- },
-
- toHaveBeenStopped: function () {
- return {
- compare: function (actual) {
- var eventName = actual.eventName
- , selector = actual.selector
- , result = { pass: jasmine.jQuery.events.wasStopped(selector, eventName) }
-
- result.message = result.pass ?
- "Expected event " + eventName + " not to have been stopped on " + selector :
- "Expected event " + eventName + " to have been stopped on " + selector
-
- return result
- }
- }
- }
- })
-
- jasmine.getEnv().addCustomEqualityTester(function(a, b) {
- if (a && b) {
- if (a instanceof $ || jasmine.isDomNode(a)) {
- var $a = $(a)
-
- if (b instanceof $)
- return $a.length == b.length && a.is(b)
-
- return $a.is(b);
- }
-
- if (b instanceof $ || jasmine.isDomNode(b)) {
- var $b = $(b)
-
- if (a instanceof $)
- return a.length == $b.length && $b.is(a)
-
- return $(b).is(a);
- }
- }
- })
-
- jasmine.getEnv().addCustomEqualityTester(function (a, b) {
- if (a instanceof $ && b instanceof $ && a.size() == b.size())
- return a.is(b)
- })
- })
-
- afterEach(function () {
- jasmine.getFixtures().cleanUp()
- jasmine.getStyleFixtures().cleanUp()
- jasmine.jQuery.events.cleanUp()
- })
-
- window.readFixtures = function () {
- return jasmine.getFixtures().proxyCallTo_('read', arguments)
- }
-
- window.preloadFixtures = function () {
- jasmine.getFixtures().proxyCallTo_('preload', arguments)
- }
-
- window.loadFixtures = function () {
- jasmine.getFixtures().proxyCallTo_('load', arguments)
- }
-
- window.appendLoadFixtures = function () {
- jasmine.getFixtures().proxyCallTo_('appendLoad', arguments)
- }
-
- window.setFixtures = function (html) {
- return jasmine.getFixtures().proxyCallTo_('set', arguments)
- }
-
- window.appendSetFixtures = function () {
- jasmine.getFixtures().proxyCallTo_('appendSet', arguments)
- }
-
- window.sandbox = function (attributes) {
- return jasmine.getFixtures().sandbox(attributes)
- }
-
- window.spyOnEvent = function (selector, eventName) {
- return jasmine.jQuery.events.spyOn(selector, eventName)
- }
-
- window.preloadStyleFixtures = function () {
- jasmine.getStyleFixtures().proxyCallTo_('preload', arguments)
- }
-
- window.loadStyleFixtures = function () {
- jasmine.getStyleFixtures().proxyCallTo_('load', arguments)
- }
-
- window.appendLoadStyleFixtures = function () {
- jasmine.getStyleFixtures().proxyCallTo_('appendLoad', arguments)
- }
-
- window.setStyleFixtures = function (html) {
- jasmine.getStyleFixtures().proxyCallTo_('set', arguments)
- }
-
- window.appendSetStyleFixtures = function (html) {
- jasmine.getStyleFixtures().proxyCallTo_('appendSet', arguments)
- }
-
- window.loadJSONFixtures = function () {
- return jasmine.getJSONFixtures().proxyCallTo_('load', arguments)
- }
-
- window.getJSONFixture = function (url) {
- return jasmine.getJSONFixtures().proxyCallTo_('read', arguments)[url]
- }
-}));
diff --git a/vendor/aws/cloudformation/eks_cluster.yaml b/vendor/aws/cloudformation/eks_cluster.yaml
index 5ad25dcd533..8d93734fd46 100644
--- a/vendor/aws/cloudformation/eks_cluster.yaml
+++ b/vendor/aws/cloudformation/eks_cluster.yaml
@@ -7,13 +7,13 @@ Parameters:
KubernetesVersion:
Description: The Kubernetes version to install
Type: String
- Default: 1.19
+ Default: "1.20"
AllowedValues:
- - 1.15
- - 1.16
- - 1.17
- - 1.18
- - 1.19
+ - "1.16"
+ - "1.17"
+ - "1.18"
+ - "1.19"
+ - "1.20"
KeyName:
Description: The EC2 Key Pair to allow SSH access to the node instances
@@ -21,7 +21,7 @@ Parameters:
NodeImageIdSSMParam:
Type: "AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>"
- Default: /aws/service/eks/optimized-ami/1.15/amazon-linux-2/recommended/image_id
+ Default: /aws/service/eks/optimized-ami/1.17/amazon-linux-2/recommended/image_id
Description: AWS Systems Manager Parameter Store parameter of the AMI ID for the worker node instances.
NodeInstanceType:
diff --git a/vendor/project_templates/cluster_management.tar.gz b/vendor/project_templates/cluster_management.tar.gz
index a7ed11e7ce3..9b168724c79 100644
--- a/vendor/project_templates/cluster_management.tar.gz
+++ b/vendor/project_templates/cluster_management.tar.gz
Binary files differ
diff --git a/workhorse/Makefile b/workhorse/Makefile
index 2bfaf5913c6..0e8c47ae35c 100644
--- a/workhorse/Makefile
+++ b/workhorse/Makefile
@@ -6,7 +6,12 @@ VERSION_STRING := $(shell git describe)
ifeq ($(strip $(VERSION_STRING)),)
VERSION_STRING := v$(shell cat VERSION)
endif
-BUILD_TIME := $(shell date -u +%Y%m%d.%H%M%S)
+DATE_FMT = +%Y%m%d.%H%M%S
+ifdef SOURCE_DATE_EPOCH
+ BUILD_TIME := $(shell date -u -d "@$(SOURCE_DATE_EPOCH)" "$(DATE_FMT)" 2>/dev/null || date -u -r "$(SOURCE_DATE_EPOCH)" "$(DATE_FMT)" 2>/dev/null || date -u "$(DATE_FMT)")
+else
+ BUILD_TIME := $(shell date -u "$(DATE_FMT)")
+endif
GOBUILD := go build -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)"
EXE_ALL := gitlab-resize-image gitlab-zip-cat gitlab-zip-metadata gitlab-workhorse
INSTALL := install
diff --git a/workhorse/authorization_test.go b/workhorse/authorization_test.go
index f0a03779d5d..7c56ec171cc 100644
--- a/workhorse/authorization_test.go
+++ b/workhorse/authorization_test.go
@@ -10,7 +10,7 @@ import (
"gitlab.com/gitlab-org/labkit/correlation"
- "github.com/dgrijalva/jwt-go"
+ "github.com/golang-jwt/jwt/v4"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
diff --git a/workhorse/doc/architecture/channel.md b/workhorse/doc/architecture/channel.md
index 8423405a9cf..f7a72d0fd45 100644
--- a/workhorse/doc/architecture/channel.md
+++ b/workhorse/doc/architecture/channel.md
@@ -145,7 +145,7 @@ also upgraded.
Workhorse now has two websocket connections, albeit with
differing subprotocols. It decodes incoming frames from the
-browser, re-encodes them to the the channel's subprotocol, and
+browser, re-encodes them to the channel's subprotocol, and
sends them to the channel. Similarly, it decodes incoming
frames from the channel, re-encodes them to the browser's
subprotocol, and sends them to the browser.
diff --git a/workhorse/go.mod b/workhorse/go.mod
index 3ce279f2ccc..834ad382983 100644
--- a/workhorse/go.mod
+++ b/workhorse/go.mod
@@ -1,6 +1,6 @@
module gitlab.com/gitlab-org/gitlab/workhorse
-go 1.15
+go 1.16
require (
github.com/Azure/azure-storage-blob-go v0.11.1-0.20201209121048-6df5d9af221d
@@ -9,9 +9,9 @@ require (
github.com/alecthomas/chroma v0.7.3
github.com/aws/aws-sdk-go v1.37.0
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 // indirect
- github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/disintegration/imaging v1.6.2
github.com/getsentry/raven-go v0.2.0
+ github.com/golang-jwt/jwt/v4 v4.0.0
github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721
github.com/golang/protobuf v1.5.2
github.com/gomodule/redigo v2.0.0+incompatible
@@ -31,7 +31,6 @@ require (
gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1
gitlab.com/gitlab-org/labkit v1.6.0
gocloud.dev v0.21.1-0.20201223184910-5094f54ed8bb
- golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5 // indirect
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4
diff --git a/workhorse/go.sum b/workhorse/go.sum
index bb7f4f70fc4..f928b7f7a92 100644
--- a/workhorse/go.sum
+++ b/workhorse/go.sum
@@ -207,7 +207,6 @@ github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0/go.mod h1:xb
github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY=
github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
-github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
@@ -246,7 +245,6 @@ github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHqu
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
-github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
github.com/getsentry/raven-go v0.1.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
@@ -267,7 +265,6 @@ github.com/git-lfs/gitobj/v2 v2.0.1/go.mod h1:q6aqxl6Uu3gWsip5GEKpw+7459F97er8CO
github.com/git-lfs/go-netrc v0.0.0-20180525200031-e0e9ca483a18/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI=
github.com/git-lfs/wildmatch v1.0.4/go.mod h1:SdHAGnApDpnFYQ0vAxbniWR0sn7yLJ3QXo9RRfhn2ew=
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
-github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@@ -306,6 +303,8 @@ github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zV
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+github.com/golang-jwt/jwt/v4 v4.0.0 h1:RAqyYixv1p7uEnocuy8P1nru5wprCh/MH2BIlW5z5/o=
+github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721 h1:KRMr9A3qfbVM7iV/WcLY/rL5LICqwMHLhwRXKu99fXw=
@@ -373,7 +372,6 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi
github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible h1:xmapqc1AyLoB+ddYT6r04bD9lIjlOqGaREovi0SzFaE=
github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
-github.com/google/martian/v3 v3.1.0 h1:wCKgOCHuUEVfsaQLpPSJb7VdYCdTVZQAuOdYm1yc/60=
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
@@ -638,7 +636,6 @@ github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ=
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
-github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pkg/errors v0.0.0-20170505043639-c605e284fe17/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -850,8 +847,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
-golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5 h1:FR+oGxGfbQu1d+jglI3rCkjAjUnhRSZcUxr+DqlDLNo=
-golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
@@ -1123,9 +1118,7 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
-gonum.org/v1/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM=
gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
-gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc=
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
diff --git a/workhorse/internal/artifacts/artifacts_upload_test.go b/workhorse/internal/artifacts/artifacts_upload_test.go
index ce078c78559..2b11d56f4ee 100644
--- a/workhorse/internal/artifacts/artifacts_upload_test.go
+++ b/workhorse/internal/artifacts/artifacts_upload_test.go
@@ -14,7 +14,7 @@ import (
"os"
"testing"
- "github.com/dgrijalva/jwt-go"
+ "github.com/golang-jwt/jwt/v4"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/filestore"
diff --git a/workhorse/internal/filestore/file_handler.go b/workhorse/internal/filestore/file_handler.go
index 06948941c04..b4d7250fe0c 100644
--- a/workhorse/internal/filestore/file_handler.go
+++ b/workhorse/internal/filestore/file_handler.go
@@ -10,7 +10,7 @@ import (
"strconv"
"time"
- "github.com/dgrijalva/jwt-go"
+ "github.com/golang-jwt/jwt/v4"
"gitlab.com/gitlab-org/labkit/log"
diff --git a/workhorse/internal/filestore/file_handler_test.go b/workhorse/internal/filestore/file_handler_test.go
index b1d4e64b666..16af56dcf48 100644
--- a/workhorse/internal/filestore/file_handler_test.go
+++ b/workhorse/internal/filestore/file_handler_test.go
@@ -12,7 +12,7 @@ import (
"testing"
"time"
- "github.com/dgrijalva/jwt-go"
+ "github.com/golang-jwt/jwt/v4"
"github.com/stretchr/testify/require"
"gocloud.dev/blob"
diff --git a/workhorse/internal/imageresizer/image_resizer.go b/workhorse/internal/imageresizer/image_resizer.go
index a21d2838acb..cd0fa946530 100644
--- a/workhorse/internal/imageresizer/image_resizer.go
+++ b/workhorse/internal/imageresizer/image_resizer.go
@@ -186,12 +186,15 @@ func (r *Resizer) Inject(w http.ResponseWriter, req *http.Request, paramsData st
}
defer imageFile.reader.Close()
+ widthLabelVal := strconv.Itoa(int(params.Width))
+
outcome.originalFileSize = imageFile.contentLength
setLastModified(w, imageFile.lastModified)
// If the original file has not changed, then any cached resized versions have not changed either.
if checkNotModified(req, imageFile.lastModified) {
writeNotModified(w)
+ imageResizeDurations.WithLabelValues(params.ContentType, widthLabelVal).Observe(time.Since(start).Seconds())
outcome.ok(statusClientCache)
return
}
@@ -221,7 +224,6 @@ func (r *Resizer) Inject(w http.ResponseWriter, req *http.Request, paramsData st
return
}
- widthLabelVal := strconv.Itoa(int(params.Width))
imageResizeDurations.WithLabelValues(params.ContentType, widthLabelVal).Observe(time.Since(start).Seconds())
outcome.ok(statusSuccess)
diff --git a/workhorse/internal/secret/jwt.go b/workhorse/internal/secret/jwt.go
index 04335e58f76..804f3a9aba9 100644
--- a/workhorse/internal/secret/jwt.go
+++ b/workhorse/internal/secret/jwt.go
@@ -3,7 +3,7 @@ package secret
import (
"fmt"
- "github.com/dgrijalva/jwt-go"
+ "github.com/golang-jwt/jwt/v4"
)
var (
diff --git a/workhorse/internal/testhelper/testhelper.go b/workhorse/internal/testhelper/testhelper.go
index d94341cd2b6..7e66563e438 100644
--- a/workhorse/internal/testhelper/testhelper.go
+++ b/workhorse/internal/testhelper/testhelper.go
@@ -14,7 +14,7 @@ import (
"testing"
"time"
- "github.com/dgrijalva/jwt-go"
+ "github.com/golang-jwt/jwt/v4"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/labkit/log"
diff --git a/workhorse/internal/upload/accelerate.go b/workhorse/internal/upload/accelerate.go
index 08a84c6f670..81f44d33a82 100644
--- a/workhorse/internal/upload/accelerate.go
+++ b/workhorse/internal/upload/accelerate.go
@@ -4,7 +4,7 @@ import (
"fmt"
"net/http"
- "github.com/dgrijalva/jwt-go"
+ "github.com/golang-jwt/jwt/v4"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/helper"
diff --git a/workhorse/internal/upload/body_uploader_test.go b/workhorse/internal/upload/body_uploader_test.go
index 35509cb86c4..aeb366616ca 100644
--- a/workhorse/internal/upload/body_uploader_test.go
+++ b/workhorse/internal/upload/body_uploader_test.go
@@ -11,7 +11,7 @@ import (
"strings"
"testing"
- "github.com/dgrijalva/jwt-go"
+ "github.com/golang-jwt/jwt/v4"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
diff --git a/workhorse/internal/upload/saved_file_tracker_test.go b/workhorse/internal/upload/saved_file_tracker_test.go
index b294d04b216..b34dd9aed4f 100644
--- a/workhorse/internal/upload/saved_file_tracker_test.go
+++ b/workhorse/internal/upload/saved_file_tracker_test.go
@@ -3,7 +3,7 @@ package upload
import (
"context"
- "github.com/dgrijalva/jwt-go"
+ "github.com/golang-jwt/jwt/v4"
"net/http"
"testing"
diff --git a/workhorse/internal/upstream/roundtripper/roundtripper.go b/workhorse/internal/upstream/roundtripper/roundtripper.go
index 947b80ddcf6..fdbca5c0120 100644
--- a/workhorse/internal/upstream/roundtripper/roundtripper.go
+++ b/workhorse/internal/upstream/roundtripper/roundtripper.go
@@ -2,6 +2,7 @@ package roundtripper
import (
"context"
+ "crypto/tls"
"fmt"
"net"
"net/http"
@@ -15,10 +16,6 @@ import (
)
func mustParseAddress(address, scheme string) string {
- if scheme == "https" {
- panic("TLS is not supported for backend connections")
- }
-
for _, suffix := range []string{"", ":" + scheme} {
address += suffix
if host, port, err := net.SplitHostPort(address); err == nil && host != "" && port != "" {
@@ -31,9 +28,14 @@ func mustParseAddress(address, scheme string) string {
// NewBackendRoundTripper returns a new RoundTripper instance using the provided values
func NewBackendRoundTripper(backend *url.URL, socket string, proxyHeadersTimeout time.Duration, developmentMode bool) http.RoundTripper {
+ return newBackendRoundTripper(backend, socket, proxyHeadersTimeout, developmentMode, nil)
+}
+
+func newBackendRoundTripper(backend *url.URL, socket string, proxyHeadersTimeout time.Duration, developmentMode bool, tlsConf *tls.Config) http.RoundTripper {
// Copied from the definition of http.DefaultTransport. We can't literally copy http.DefaultTransport because of its hidden internal state.
transport, dialer := newBackendTransport()
transport.ResponseHeaderTimeout = proxyHeadersTimeout
+ transport.TLSClientConfig = tlsConf
if backend != nil && socket == "" {
address := mustParseAddress(backend.Host, backend.Scheme)
diff --git a/workhorse/internal/upstream/roundtripper/roundtripper_test.go b/workhorse/internal/upstream/roundtripper/roundtripper_test.go
index 79ffa244918..eed71cc5bae 100644
--- a/workhorse/internal/upstream/roundtripper/roundtripper_test.go
+++ b/workhorse/internal/upstream/roundtripper/roundtripper_test.go
@@ -1,6 +1,13 @@
package roundtripper
import (
+ "crypto/tls"
+ "crypto/x509"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "net/http/httptest"
+ "net/url"
"strconv"
"testing"
@@ -12,6 +19,7 @@ func TestMustParseAddress(t *testing.T) {
{"1.2.3.4:56", "http", "1.2.3.4:56"},
{"[::1]:23", "http", "::1:23"},
{"4.5.6.7", "http", "4.5.6.7:http"},
+ {"4.5.6.7", "https", "4.5.6.7:https"},
}
for i, example := range successExamples {
t.Run(strconv.Itoa(i), func(t *testing.T) {
@@ -23,7 +31,6 @@ func TestMustParseAddress(t *testing.T) {
func TestMustParseAddressPanic(t *testing.T) {
panicExamples := []struct{ address, scheme string }{
{"1.2.3.4", ""},
- {"1.2.3.4", "https"},
}
for i, panicExample := range panicExamples {
@@ -37,3 +44,50 @@ func TestMustParseAddressPanic(t *testing.T) {
})
}
}
+
+func TestSupportsHTTPBackend(t *testing.T) {
+ ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ w.WriteHeader(200)
+ fmt.Fprint(w, "successful response")
+ }))
+ defer ts.Close()
+
+ testNewBackendRoundTripper(t, ts, nil, "successful response")
+}
+
+func TestSupportsHTTPSBackend(t *testing.T) {
+ ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ w.WriteHeader(200)
+ fmt.Fprint(w, "successful response")
+ }))
+ defer ts.Close()
+
+ certpool := x509.NewCertPool()
+ certpool.AddCert(ts.Certificate())
+ tlsClientConfig := &tls.Config{
+ RootCAs: certpool,
+ }
+
+ testNewBackendRoundTripper(t, ts, tlsClientConfig, "successful response")
+}
+
+func testNewBackendRoundTripper(t *testing.T, ts *httptest.Server, tlsClientConfig *tls.Config, expectedResponseBody string) {
+ t.Helper()
+
+ backend, err := url.Parse(ts.URL)
+ require.NoError(t, err, "parse url")
+
+ rt := newBackendRoundTripper(backend, "", 0, true, tlsClientConfig)
+
+ req, err := http.NewRequest("GET", ts.URL+"/", nil)
+ require.NoError(t, err, "build request")
+
+ response, err := rt.RoundTrip(req)
+ require.NoError(t, err, "perform roundtrip")
+ defer response.Body.Close()
+
+ body, err := ioutil.ReadAll(response.Body)
+ require.NoError(t, err)
+
+ require.Equal(t, expectedResponseBody, string(body))
+}
diff --git a/workhorse/internal/upstream/routes.go b/workhorse/internal/upstream/routes.go
index a4b453f047d..8c85c5144e5 100644
--- a/workhorse/internal/upstream/routes.go
+++ b/workhorse/internal/upstream/routes.go
@@ -359,7 +359,7 @@ func configureRoutes(u *upstream) {
u.route("", "^/-/metrics$", defaultUpstream),
// Authentication routes
- u.route("", "^/users/(sign_in|sign_out)$", defaultUpstream),
+ u.route("", "^/users/auth/geo/(sign_in|sign_out)$", defaultUpstream),
u.route("", "^/oauth/geo/(auth|callback|logout)$", defaultUpstream),
// Admin Area > Geo routes
diff --git a/workhorse/upload_test.go b/workhorse/upload_test.go
index 0c4ac2357a3..24c14bb12aa 100644
--- a/workhorse/upload_test.go
+++ b/workhorse/upload_test.go
@@ -14,7 +14,7 @@ import (
"strings"
"testing"
- "github.com/dgrijalva/jwt-go"
+ "github.com/golang-jwt/jwt/v4"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
diff --git a/yarn.lock b/yarn.lock
index 0ae3bbf3205..b27026f47fd 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9,58 +9,54 @@
dependencies:
"@babel/highlight" "^7.10.4"
-"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658"
- integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==
- dependencies:
- "@babel/highlight" "^7.12.13"
-
-"@babel/compat-data@^7.10.1":
- version "7.10.1"
- resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.10.1.tgz#b1085ffe72cd17bf2c0ee790fc09f9626011b2db"
- integrity sha512-CHvCj7So7iCkGKPRFUfryXIkU2gSBw7VSZFYLsqVhrS47269VK2Hfi9S/YcublPMW8k1u2bQBlbDruoQEm4fgw==
- dependencies:
- browserslist "^4.12.0"
- invariant "^2.2.4"
- semver "^5.5.0"
-
-"@babel/core@>=7.9.0", "@babel/core@^7.1.0", "@babel/core@^7.10.1", "@babel/core@^7.7.5":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.13.tgz#b73a87a3a3e7d142a66248bf6ad88b9ceb093425"
- integrity sha512-BQKE9kXkPlXHPeqissfxo0lySWJcYdEP0hdtJOH/iJfDdhOCcgtNCjftCJg3qqauB4h+lz2N6ixM++b9DN1Tcw==
- dependencies:
- "@babel/code-frame" "^7.12.13"
- "@babel/generator" "^7.12.13"
- "@babel/helper-module-transforms" "^7.12.13"
- "@babel/helpers" "^7.12.13"
- "@babel/parser" "^7.12.13"
- "@babel/template" "^7.12.13"
- "@babel/traverse" "^7.12.13"
- "@babel/types" "^7.12.13"
+"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.14.5":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb"
+ integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==
+ dependencies:
+ "@babel/highlight" "^7.14.5"
+
+"@babel/compat-data@^7.10.1", "@babel/compat-data@^7.15.0":
+ version "7.15.0"
+ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.15.0.tgz#2dbaf8b85334796cafbb0f5793a90a2fc010b176"
+ integrity sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==
+
+"@babel/core@>=7.9.0", "@babel/core@^7.1.0", "@babel/core@^7.1.6", "@babel/core@^7.10.1", "@babel/core@^7.7.5":
+ version "7.15.0"
+ resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.15.0.tgz#749e57c68778b73ad8082775561f67f5196aafa8"
+ integrity sha512-tXtmTminrze5HEUPn/a0JtOzzfp0nk+UEXQ/tqIJo3WDGypl/2OFQEMll/zSFU8f/lfmfLXvTaORHF3cfXIQMw==
+ dependencies:
+ "@babel/code-frame" "^7.14.5"
+ "@babel/generator" "^7.15.0"
+ "@babel/helper-compilation-targets" "^7.15.0"
+ "@babel/helper-module-transforms" "^7.15.0"
+ "@babel/helpers" "^7.14.8"
+ "@babel/parser" "^7.15.0"
+ "@babel/template" "^7.14.5"
+ "@babel/traverse" "^7.15.0"
+ "@babel/types" "^7.15.0"
convert-source-map "^1.7.0"
debug "^4.1.0"
- gensync "^1.0.0-beta.1"
+ gensync "^1.0.0-beta.2"
json5 "^2.1.2"
- lodash "^4.17.19"
- semver "^5.4.1"
+ semver "^6.3.0"
source-map "^0.5.0"
-"@babel/generator@^7.12.13", "@babel/generator@^7.4.0":
- version "7.12.15"
- resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.15.tgz#4617b5d0b25cc572474cc1aafee1edeaf9b5368f"
- integrity sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==
+"@babel/generator@^7.15.0":
+ version "7.15.0"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.15.0.tgz#a7d0c172e0d814974bad5aa77ace543b97917f15"
+ integrity sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ==
dependencies:
- "@babel/types" "^7.12.13"
+ "@babel/types" "^7.15.0"
jsesc "^2.5.1"
source-map "^0.5.0"
-"@babel/helper-annotate-as-pure@^7.10.1":
- version "7.10.1"
- resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.1.tgz#f6d08acc6f70bbd59b436262553fb2e259a1a268"
- integrity sha512-ewp3rvJEwLaHgyWGe4wQssC2vjks3E80WiUe2BpMb0KhreTjMROCbxXcEovTrbeGVdQct5VjQfrv9EgC+xMzCw==
+"@babel/helper-annotate-as-pure@^7.10.1", "@babel/helper-annotate-as-pure@^7.14.5":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz#7bf478ec3b71726d56a8ca5775b046fc29879e61"
+ integrity sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA==
dependencies:
- "@babel/types" "^7.10.1"
+ "@babel/types" "^7.14.5"
"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.1":
version "7.10.1"
@@ -70,28 +66,27 @@
"@babel/helper-explode-assignable-expression" "^7.10.1"
"@babel/types" "^7.10.1"
-"@babel/helper-compilation-targets@^7.10.2":
- version "7.10.2"
- resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.2.tgz#a17d9723b6e2c750299d2a14d4637c76936d8285"
- integrity sha512-hYgOhF4To2UTB4LTaZepN/4Pl9LD4gfbJx8A34mqoluT8TLbof1mhUlYuNWTEebONa8+UlCC4X0TEXu7AOUyGA==
+"@babel/helper-compilation-targets@^7.10.2", "@babel/helper-compilation-targets@^7.15.0":
+ version "7.15.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.0.tgz#973df8cbd025515f3ff25db0c05efc704fa79818"
+ integrity sha512-h+/9t0ncd4jfZ8wsdAsoIxSa61qhBYlycXiHWqJaQBCXAhDCMbPRSMTGnZIkkmt1u4ag+UQmuqcILwqKzZ4N2A==
dependencies:
- "@babel/compat-data" "^7.10.1"
- browserslist "^4.12.0"
- invariant "^2.2.4"
- levenary "^1.1.1"
- semver "^5.5.0"
+ "@babel/compat-data" "^7.15.0"
+ "@babel/helper-validator-option" "^7.14.5"
+ browserslist "^4.16.6"
+ semver "^6.3.0"
-"@babel/helper-create-class-features-plugin@^7.10.1":
- version "7.10.2"
- resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.2.tgz#7474295770f217dbcf288bf7572eb213db46ee67"
- integrity sha512-5C/QhkGFh1vqcziq1vAL6SI9ymzUp8BCYjFpvYVhWP4DlATIb3u5q3iUd35mvlyGs8fO7hckkW7i0tmH+5+bvQ==
+"@babel/helper-create-class-features-plugin@^7.10.1", "@babel/helper-create-class-features-plugin@^7.14.5", "@babel/helper-create-class-features-plugin@^7.15.0":
+ version "7.15.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.0.tgz#c9a137a4d137b2d0e2c649acf536d7ba1a76c0f7"
+ integrity sha512-MdmDXgvTIi4heDVX/e9EFfeGpugqm9fobBVg/iioE8kueXrOHdRDe36FAY7SnE9xXLVeYCoJR/gdrBEIHRC83Q==
dependencies:
- "@babel/helper-function-name" "^7.10.1"
- "@babel/helper-member-expression-to-functions" "^7.10.1"
- "@babel/helper-optimise-call-expression" "^7.10.1"
- "@babel/helper-plugin-utils" "^7.10.1"
- "@babel/helper-replace-supers" "^7.10.1"
- "@babel/helper-split-export-declaration" "^7.10.1"
+ "@babel/helper-annotate-as-pure" "^7.14.5"
+ "@babel/helper-function-name" "^7.14.5"
+ "@babel/helper-member-expression-to-functions" "^7.15.0"
+ "@babel/helper-optimise-call-expression" "^7.14.5"
+ "@babel/helper-replace-supers" "^7.15.0"
+ "@babel/helper-split-export-declaration" "^7.14.5"
"@babel/helper-create-regexp-features-plugin@^7.10.1", "@babel/helper-create-regexp-features-plugin@^7.8.3":
version "7.10.1"
@@ -119,69 +114,68 @@
"@babel/traverse" "^7.10.1"
"@babel/types" "^7.10.1"
-"@babel/helper-function-name@^7.10.1", "@babel/helper-function-name@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz#93ad656db3c3c2232559fd7b2c3dbdcbe0eb377a"
- integrity sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==
+"@babel/helper-function-name@^7.10.1", "@babel/helper-function-name@^7.14.5":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz#89e2c474972f15d8e233b52ee8c480e2cfcd50c4"
+ integrity sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==
dependencies:
- "@babel/helper-get-function-arity" "^7.12.13"
- "@babel/template" "^7.12.13"
- "@babel/types" "^7.12.13"
+ "@babel/helper-get-function-arity" "^7.14.5"
+ "@babel/template" "^7.14.5"
+ "@babel/types" "^7.14.5"
-"@babel/helper-get-function-arity@^7.10.1", "@babel/helper-get-function-arity@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583"
- integrity sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==
+"@babel/helper-get-function-arity@^7.10.1", "@babel/helper-get-function-arity@^7.14.5":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz#25fbfa579b0937eee1f3b805ece4ce398c431815"
+ integrity sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==
dependencies:
- "@babel/types" "^7.12.13"
+ "@babel/types" "^7.14.5"
-"@babel/helper-hoist-variables@^7.10.1":
- version "7.10.1"
- resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.1.tgz#7e77c82e5dcae1ebf123174c385aaadbf787d077"
- integrity sha512-vLm5srkU8rI6X3+aQ1rQJyfjvCBLXP8cAGeuw04zeAM2ItKb1e7pmVmLyHb4sDaAYnLL13RHOZPLEtcGZ5xvjg==
+"@babel/helper-hoist-variables@^7.10.1", "@babel/helper-hoist-variables@^7.14.5":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz#e0dd27c33a78e577d7c8884916a3e7ef1f7c7f8d"
+ integrity sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==
dependencies:
- "@babel/types" "^7.10.1"
+ "@babel/types" "^7.14.5"
-"@babel/helper-member-expression-to-functions@^7.10.1", "@babel/helper-member-expression-to-functions@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.13.tgz#c5715695b4f8bab32660dbdcdc2341dec7e3df40"
- integrity sha512-B+7nN0gIL8FZ8SvMcF+EPyB21KnCcZHQZFczCxbiNGV/O0rsrSBlWGLzmtBJ3GMjSVMIm4lpFhR+VdVBuIsUcQ==
- dependencies:
- "@babel/types" "^7.12.13"
-
-"@babel/helper-module-imports@^7.0.0-beta.49", "@babel/helper-module-imports@^7.10.1", "@babel/helper-module-imports@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz#ec67e4404f41750463e455cc3203f6a32e93fcb0"
- integrity sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g==
- dependencies:
- "@babel/types" "^7.12.13"
-
-"@babel/helper-module-transforms@^7.10.1", "@babel/helper-module-transforms@^7.10.4", "@babel/helper-module-transforms@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.13.tgz#01afb052dcad2044289b7b20beb3fa8bd0265bea"
- integrity sha512-acKF7EjqOR67ASIlDTupwkKM1eUisNAjaSduo5Cz+793ikfnpe7p4Q7B7EWU2PCoSTPWsQkR7hRUWEIZPiVLGA==
- dependencies:
- "@babel/helper-module-imports" "^7.12.13"
- "@babel/helper-replace-supers" "^7.12.13"
- "@babel/helper-simple-access" "^7.12.13"
- "@babel/helper-split-export-declaration" "^7.12.13"
- "@babel/helper-validator-identifier" "^7.12.11"
- "@babel/template" "^7.12.13"
- "@babel/traverse" "^7.12.13"
- "@babel/types" "^7.12.13"
- lodash "^4.17.19"
+"@babel/helper-member-expression-to-functions@^7.15.0":
+ version "7.15.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.0.tgz#0ddaf5299c8179f27f37327936553e9bba60990b"
+ integrity sha512-Jq8H8U2kYiafuj2xMTPQwkTBnEEdGKpT35lJEQsRRjnG0LW3neucsaMWLgKcwu3OHKNeYugfw+Z20BXBSEs2Lg==
+ dependencies:
+ "@babel/types" "^7.15.0"
-"@babel/helper-optimise-call-expression@^7.10.1", "@babel/helper-optimise-call-expression@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz#5c02d171b4c8615b1e7163f888c1c81c30a2aaea"
- integrity sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==
+"@babel/helper-module-imports@^7.0.0-beta.49", "@babel/helper-module-imports@^7.10.1", "@babel/helper-module-imports@^7.14.5":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz#6d1a44df6a38c957aa7c312da076429f11b422f3"
+ integrity sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==
dependencies:
- "@babel/types" "^7.12.13"
+ "@babel/types" "^7.14.5"
-"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.1", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0":
- version "7.10.4"
- resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375"
- integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==
+"@babel/helper-module-transforms@^7.10.1", "@babel/helper-module-transforms@^7.15.0":
+ version "7.15.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.15.0.tgz#679275581ea056373eddbe360e1419ef23783b08"
+ integrity sha512-RkGiW5Rer7fpXv9m1B3iHIFDZdItnO2/BLfWVW/9q7+KqQSDY5kUfQEbzdXM1MVhJGcugKV7kRrNVzNxmk7NBg==
+ dependencies:
+ "@babel/helper-module-imports" "^7.14.5"
+ "@babel/helper-replace-supers" "^7.15.0"
+ "@babel/helper-simple-access" "^7.14.8"
+ "@babel/helper-split-export-declaration" "^7.14.5"
+ "@babel/helper-validator-identifier" "^7.14.9"
+ "@babel/template" "^7.14.5"
+ "@babel/traverse" "^7.15.0"
+ "@babel/types" "^7.15.0"
+
+"@babel/helper-optimise-call-expression@^7.10.1", "@babel/helper-optimise-call-expression@^7.14.5":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz#f27395a8619e0665b3f0364cddb41c25d71b499c"
+ integrity sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==
+ dependencies:
+ "@babel/types" "^7.14.5"
+
+"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.1", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9"
+ integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==
"@babel/helper-regex@^7.10.1":
version "7.10.1"
@@ -201,34 +195,46 @@
"@babel/traverse" "^7.10.1"
"@babel/types" "^7.10.1"
-"@babel/helper-replace-supers@^7.10.1", "@babel/helper-replace-supers@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.13.tgz#00ec4fb6862546bd3d0aff9aac56074277173121"
- integrity sha512-pctAOIAMVStI2TMLhozPKbf5yTEXc0OJa0eENheb4w09SrgOWEs+P4nTOZYJQCqs8JlErGLDPDJTiGIp3ygbLg==
+"@babel/helper-replace-supers@^7.10.1", "@babel/helper-replace-supers@^7.15.0":
+ version "7.15.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.15.0.tgz#ace07708f5bf746bf2e6ba99572cce79b5d4e7f4"
+ integrity sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA==
dependencies:
- "@babel/helper-member-expression-to-functions" "^7.12.13"
- "@babel/helper-optimise-call-expression" "^7.12.13"
- "@babel/traverse" "^7.12.13"
- "@babel/types" "^7.12.13"
+ "@babel/helper-member-expression-to-functions" "^7.15.0"
+ "@babel/helper-optimise-call-expression" "^7.14.5"
+ "@babel/traverse" "^7.15.0"
+ "@babel/types" "^7.15.0"
-"@babel/helper-simple-access@^7.10.4", "@babel/helper-simple-access@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.12.13.tgz#8478bcc5cacf6aa1672b251c1d2dde5ccd61a6c4"
- integrity sha512-0ski5dyYIHEfwpWGx5GPWhH35j342JaflmCeQmsPWcrOQDtCN6C1zKAVRFVbK53lPW2c9TsuLLSUDf0tIGJ5hA==
+"@babel/helper-simple-access@^7.14.8":
+ version "7.14.8"
+ resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.14.8.tgz#82e1fec0644a7e775c74d305f212c39f8fe73924"
+ integrity sha512-TrFN4RHh9gnWEU+s7JloIho2T76GPwRHhdzOWLqTrMnlas8T9O7ec+oEDNsRXndOmru9ymH9DFrEOxpzPoSbdg==
dependencies:
- "@babel/types" "^7.12.13"
+ "@babel/types" "^7.14.8"
-"@babel/helper-split-export-declaration@^7.10.1", "@babel/helper-split-export-declaration@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz#e9430be00baf3e88b0e13e6f9d4eaf2136372b05"
- integrity sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==
+"@babel/helper-skip-transparent-expression-wrappers@^7.14.5":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.14.5.tgz#96f486ac050ca9f44b009fbe5b7d394cab3a0ee4"
+ integrity sha512-dmqZB7mrb94PZSAOYtr+ZN5qt5owZIAgqtoTuqiFbHFtxgEcmQlRJVI+bO++fciBunXtB6MK7HrzrfcAzIz2NQ==
dependencies:
- "@babel/types" "^7.12.13"
+ "@babel/types" "^7.14.5"
-"@babel/helper-validator-identifier@^7.12.11":
- version "7.12.11"
- resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed"
- integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==
+"@babel/helper-split-export-declaration@^7.10.1", "@babel/helper-split-export-declaration@^7.14.5":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz#22b23a54ef51c2b7605d851930c1976dd0bc693a"
+ integrity sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==
+ dependencies:
+ "@babel/types" "^7.14.5"
+
+"@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9":
+ version "7.14.9"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz#6654d171b2024f6d8ee151bf2509699919131d48"
+ integrity sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==
+
+"@babel/helper-validator-option@^7.14.5":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3"
+ integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==
"@babel/helper-wrap-function@^7.10.1":
version "7.10.1"
@@ -240,28 +246,28 @@
"@babel/traverse" "^7.10.1"
"@babel/types" "^7.10.1"
-"@babel/helpers@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.13.tgz#3c75e993632e4dadc0274eae219c73eb7645ba47"
- integrity sha512-oohVzLRZ3GQEk4Cjhfs9YkJA4TdIDTObdBEZGrd6F/T0GPSnuV6l22eMcxlvcvzVIPH3VTtxbseudM1zIE+rPQ==
+"@babel/helpers@^7.14.8":
+ version "7.15.3"
+ resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.15.3.tgz#c96838b752b95dcd525b4e741ed40bb1dc2a1357"
+ integrity sha512-HwJiz52XaS96lX+28Tnbu31VeFSQJGOeKHJeaEPQlTl7PnlhFElWPj8tUXtqFIzeN86XxXoBr+WFAyK2PPVz6g==
dependencies:
- "@babel/template" "^7.12.13"
- "@babel/traverse" "^7.12.13"
- "@babel/types" "^7.12.13"
+ "@babel/template" "^7.14.5"
+ "@babel/traverse" "^7.15.0"
+ "@babel/types" "^7.15.0"
-"@babel/highlight@^7.10.4", "@babel/highlight@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.12.13.tgz#8ab538393e00370b26271b01fa08f7f27f2e795c"
- integrity sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==
+"@babel/highlight@^7.10.4", "@babel/highlight@^7.14.5":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9"
+ integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==
dependencies:
- "@babel/helper-validator-identifier" "^7.12.11"
+ "@babel/helper-validator-identifier" "^7.14.5"
chalk "^2.0.0"
js-tokens "^4.0.0"
-"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.4.3":
- version "7.12.15"
- resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.15.tgz#2b20de7f0b4b332d9b119dd9c33409c538b8aacf"
- integrity sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==
+"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.1.6", "@babel/parser@^7.14.5", "@babel/parser@^7.15.0":
+ version "7.15.3"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.3.tgz#3416d9bea748052cfcb63dbcc27368105b1ed862"
+ integrity sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA==
"@babel/plugin-proposal-async-generator-functions@^7.10.1":
version "7.10.1"
@@ -272,13 +278,13 @@
"@babel/helper-remap-async-to-generator" "^7.10.1"
"@babel/plugin-syntax-async-generators" "^7.8.0"
-"@babel/plugin-proposal-class-properties@^7.10.1":
- version "7.10.1"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.1.tgz#046bc7f6550bb08d9bd1d4f060f5f5a4f1087e01"
- integrity sha512-sqdGWgoXlnOdgMXU+9MbhzwFRgxVLeiGBqTrnuS7LC2IBU31wSsESbTUreT2O418obpfPdGUR2GbEufZF1bpqw==
+"@babel/plugin-proposal-class-properties@^7.1.0", "@babel/plugin-proposal-class-properties@^7.10.1":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz#40d1ee140c5b1e31a350f4f5eed945096559b42e"
+ integrity sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg==
dependencies:
- "@babel/helper-create-class-features-plugin" "^7.10.1"
- "@babel/helper-plugin-utils" "^7.10.1"
+ "@babel/helper-create-class-features-plugin" "^7.14.5"
+ "@babel/helper-plugin-utils" "^7.14.5"
"@babel/plugin-proposal-dynamic-import@^7.10.1":
version "7.10.1"
@@ -296,13 +302,13 @@
"@babel/helper-plugin-utils" "^7.10.1"
"@babel/plugin-syntax-json-strings" "^7.8.0"
-"@babel/plugin-proposal-nullish-coalescing-operator@^7.10.1":
- version "7.10.1"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.1.tgz#02dca21673842ff2fe763ac253777f235e9bbf78"
- integrity sha512-56cI/uHYgL2C8HVuHOuvVowihhX0sxb3nnfVRzUeVHTWmRHTZrKuAh/OBIMggGU/S1g/1D2CRCXqP+3u7vX7iA==
+"@babel/plugin-proposal-nullish-coalescing-operator@^7.1.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.10.1":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz#ee38589ce00e2cc59b299ec3ea406fcd3a0fdaf6"
+ integrity sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg==
dependencies:
- "@babel/helper-plugin-utils" "^7.10.1"
- "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0"
+ "@babel/helper-plugin-utils" "^7.14.5"
+ "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
"@babel/plugin-proposal-numeric-separator@^7.10.1":
version "7.10.1"
@@ -329,13 +335,14 @@
"@babel/helper-plugin-utils" "^7.10.1"
"@babel/plugin-syntax-optional-catch-binding" "^7.8.0"
-"@babel/plugin-proposal-optional-chaining@^7.10.1":
- version "7.10.1"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.1.tgz#15f5d6d22708629451a91be28f8facc55b0e818c"
- integrity sha512-dqQj475q8+/avvok72CF3AOSV/SGEcH29zT5hhohqqvvZ2+boQoOr7iGldBG5YXTO2qgCgc2B3WvVLUdbeMlGA==
+"@babel/plugin-proposal-optional-chaining@^7.1.0", "@babel/plugin-proposal-optional-chaining@^7.10.1":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz#fa83651e60a360e3f13797eef00b8d519695b603"
+ integrity sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ==
dependencies:
- "@babel/helper-plugin-utils" "^7.10.1"
- "@babel/plugin-syntax-optional-chaining" "^7.8.0"
+ "@babel/helper-plugin-utils" "^7.14.5"
+ "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5"
+ "@babel/plugin-syntax-optional-chaining" "^7.8.3"
"@babel/plugin-proposal-private-methods@^7.10.1":
version "7.10.1"
@@ -381,6 +388,13 @@
dependencies:
"@babel/helper-plugin-utils" "^7.8.0"
+"@babel/plugin-syntax-flow@^7.14.5":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.14.5.tgz#2ff654999497d7d7d142493260005263731da180"
+ integrity sha512-9WK5ZwKCdWHxVuU13XNT6X73FGmutAXeor5lGFq6qhOFtMFUF4jkbijuyUdZZlpYq6E2hZeZf/u3959X9wsv0Q==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.14.5"
+
"@babel/plugin-syntax-import-meta@^7.10.1", "@babel/plugin-syntax-import-meta@^7.8.3":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51"
@@ -444,6 +458,13 @@
dependencies:
"@babel/helper-plugin-utils" "^7.10.1"
+"@babel/plugin-syntax-typescript@^7.14.5":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz#b82c6ce471b165b5ce420cf92914d6fb46225716"
+ integrity sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.14.5"
+
"@babel/plugin-transform-arrow-functions@^7.10.1":
version "7.10.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.1.tgz#cb5ee3a36f0863c06ead0b409b4cc43a889b295b"
@@ -526,6 +547,14 @@
"@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.1"
"@babel/helper-plugin-utils" "^7.10.1"
+"@babel/plugin-transform-flow-strip-types@^7.14.5":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.14.5.tgz#0dc9c1d11dcdc873417903d6df4bed019ef0f85e"
+ integrity sha512-KhcolBKfXbvjwI3TV7r7TkYm8oNXHNBqGOy6JDVwtecFaRoKYsUUqJdS10q0YDKW1c6aZQgO+Ys3LfGkox8pXA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.14.5"
+ "@babel/plugin-syntax-flow" "^7.14.5"
+
"@babel/plugin-transform-for-of@^7.10.1":
version "7.10.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.1.tgz#ff01119784eb0ee32258e8646157ba2501fcfda5"
@@ -564,14 +593,14 @@
"@babel/helper-plugin-utils" "^7.10.1"
babel-plugin-dynamic-import-node "^2.3.3"
-"@babel/plugin-transform-modules-commonjs@^7.10.1", "@babel/plugin-transform-modules-commonjs@^7.2.0":
- version "7.10.4"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz#66667c3eeda1ebf7896d41f1f16b17105a2fbca0"
- integrity sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w==
+"@babel/plugin-transform-modules-commonjs@^7.1.0", "@babel/plugin-transform-modules-commonjs@^7.10.1", "@babel/plugin-transform-modules-commonjs@^7.2.0":
+ version "7.15.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.0.tgz#3305896e5835f953b5cdb363acd9e8c2219a5281"
+ integrity sha512-3H/R9s8cXcOGE8kgMlmjYYC9nqr5ELiPkJn4q0mypBrjhYQoc+5/Maq69vV4xRPWnkzZuwJPf5rArxpB/35Cig==
dependencies:
- "@babel/helper-module-transforms" "^7.10.4"
- "@babel/helper-plugin-utils" "^7.10.4"
- "@babel/helper-simple-access" "^7.10.4"
+ "@babel/helper-module-transforms" "^7.15.0"
+ "@babel/helper-plugin-utils" "^7.14.5"
+ "@babel/helper-simple-access" "^7.14.8"
babel-plugin-dynamic-import-node "^2.3.3"
"@babel/plugin-transform-modules-systemjs@^7.10.1":
@@ -680,6 +709,15 @@
dependencies:
"@babel/helper-plugin-utils" "^7.10.1"
+"@babel/plugin-transform-typescript@^7.15.0":
+ version "7.15.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.15.0.tgz#553f230b9d5385018716586fc48db10dd228eb7e"
+ integrity sha512-WIIEazmngMEEHDaPTx0IZY48SaAmjVWe3TRSX7cmJXn0bEv9midFzAjxiruOWYIVf5iQ10vFx7ASDpgEO08L5w==
+ dependencies:
+ "@babel/helper-create-class-features-plugin" "^7.15.0"
+ "@babel/helper-plugin-utils" "^7.14.5"
+ "@babel/plugin-syntax-typescript" "^7.14.5"
+
"@babel/plugin-transform-unicode-escapes@^7.10.1":
version "7.10.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.1.tgz#add0f8483dab60570d9e03cecef6c023aa8c9940"
@@ -765,6 +803,15 @@
levenary "^1.1.1"
semver "^5.5.0"
+"@babel/preset-flow@^7.0.0":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.14.5.tgz#a1810b0780c8b48ab0bece8e7ab8d0d37712751c"
+ integrity sha512-pP5QEb4qRUSVGzzKx9xqRuHUrM/jEzMqdrZpdMA+oUCRgd5zM1qGr5y5+ZgAL/1tVv1H0dyk5t4SKJntqyiVtg==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.14.5"
+ "@babel/helper-validator-option" "^7.14.5"
+ "@babel/plugin-transform-flow-strip-types" "^7.14.5"
+
"@babel/preset-modules@^0.1.3":
version "0.1.3"
resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.3.tgz#13242b53b5ef8c883c3cf7dddd55b36ce80fbc72"
@@ -776,6 +823,26 @@
"@babel/types" "^7.4.4"
esutils "^2.0.2"
+"@babel/preset-typescript@^7.1.0":
+ version "7.15.0"
+ resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.15.0.tgz#e8fca638a1a0f64f14e1119f7fe4500277840945"
+ integrity sha512-lt0Y/8V3y06Wq/8H/u0WakrqciZ7Fz7mwPDHWUJAXlABL5hiUG42BNlRXiELNjeWjO5rWmnNKlx+yzJvxezHow==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.14.5"
+ "@babel/helper-validator-option" "^7.14.5"
+ "@babel/plugin-transform-typescript" "^7.15.0"
+
+"@babel/register@^7.0.0":
+ version "7.15.3"
+ resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.15.3.tgz#6b40a549e06ec06c885b2ec42c3dd711f55fe752"
+ integrity sha512-mj4IY1ZJkorClxKTImccn4T81+UKTo4Ux0+OFSV9hME1ooqS9UV+pJ6BjD0qXPK4T3XW/KNa79XByjeEMZz+fw==
+ dependencies:
+ clone-deep "^4.0.1"
+ find-cache-dir "^2.0.0"
+ make-dir "^2.1.0"
+ pirates "^4.0.0"
+ source-map-support "^0.5.16"
+
"@babel/runtime-corejs3@^7.10.2":
version "7.10.2"
resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.10.2.tgz#3511797ddf9a3d6f3ce46b99cc835184817eaa4e"
@@ -796,37 +863,36 @@
resolved "https://registry.yarnpkg.com/@babel/standalone/-/standalone-7.10.2.tgz#49dbbadcbc4b199df064d7d8b3e21c915b84abdb"
integrity sha512-PNQuj9oQH6BL/3l9iiL8hJLQwX14woA2/FHcPtNIZAc7IgFZYJdtMBMXiy4xcefADHTSvoBnmc2AybrHRW1IKQ==
-"@babel/template@^7.10.1", "@babel/template@^7.12.13", "@babel/template@^7.3.3", "@babel/template@^7.4.0":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327"
- integrity sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==
- dependencies:
- "@babel/code-frame" "^7.12.13"
- "@babel/parser" "^7.12.13"
- "@babel/types" "^7.12.13"
-
-"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.10.1", "@babel/traverse@^7.12.13", "@babel/traverse@^7.4.3":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.13.tgz#689f0e4b4c08587ad26622832632735fb8c4e0c0"
- integrity sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==
- dependencies:
- "@babel/code-frame" "^7.12.13"
- "@babel/generator" "^7.12.13"
- "@babel/helper-function-name" "^7.12.13"
- "@babel/helper-split-export-declaration" "^7.12.13"
- "@babel/parser" "^7.12.13"
- "@babel/types" "^7.12.13"
+"@babel/template@^7.10.1", "@babel/template@^7.14.5", "@babel/template@^7.3.3":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4"
+ integrity sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==
+ dependencies:
+ "@babel/code-frame" "^7.14.5"
+ "@babel/parser" "^7.14.5"
+ "@babel/types" "^7.14.5"
+
+"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.10.1", "@babel/traverse@^7.15.0":
+ version "7.15.0"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.0.tgz#4cca838fd1b2a03283c1f38e141f639d60b3fc98"
+ integrity sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw==
+ dependencies:
+ "@babel/code-frame" "^7.14.5"
+ "@babel/generator" "^7.15.0"
+ "@babel/helper-function-name" "^7.14.5"
+ "@babel/helper-hoist-variables" "^7.14.5"
+ "@babel/helper-split-export-declaration" "^7.14.5"
+ "@babel/parser" "^7.15.0"
+ "@babel/types" "^7.15.0"
debug "^4.1.0"
globals "^11.1.0"
- lodash "^4.17.19"
-"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.10.1", "@babel/types@^7.10.2", "@babel/types@^7.12.13", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.0", "@babel/types@^7.4.4":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.13.tgz#8be1aa8f2c876da11a9cf650c0ecf656913ad611"
- integrity sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==
+"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.10.1", "@babel/types@^7.10.2", "@babel/types@^7.14.5", "@babel/types@^7.14.8", "@babel/types@^7.15.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
+ version "7.15.0"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.0.tgz#61af11f2286c4e9c69ca8deb5f4375a73c72dcbd"
+ integrity sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==
dependencies:
- "@babel/helper-validator-identifier" "^7.12.11"
- lodash "^4.17.19"
+ "@babel/helper-validator-identifier" "^7.14.9"
to-fast-properties "^2.0.0"
"@bcoe/v8-coverage@^0.2.3":
@@ -867,10 +933,10 @@
resolved "https://registry.yarnpkg.com/@gitlab/at.js/-/at.js-1.5.7.tgz#1ee6f838cc4410a1d797770934df91d90df8179e"
integrity sha512-c6ySRK/Ma7lxwpIVbSAF3P+xiTLrNTGTLRx4/pHK111AdFxwgUwrYF6aVZFXvmG65jHOJHoa0eQQ21RW6rm0Rg==
-"@gitlab/eslint-plugin@9.0.2":
- version "9.0.2"
- resolved "https://registry.yarnpkg.com/@gitlab/eslint-plugin/-/eslint-plugin-9.0.2.tgz#c7e0c8744001227d88624eb533047f3d5dd8d419"
- integrity sha512-ZnjXo3jrZJ3sYf/2CwXzFk8Jfh02kO5ntk0h1pothzCswb96x02eTxhcCoM/dQPMTqDa0R+N4n2n2SEDtnBTbw==
+"@gitlab/eslint-plugin@9.3.0":
+ version "9.3.0"
+ resolved "https://registry.yarnpkg.com/@gitlab/eslint-plugin/-/eslint-plugin-9.3.0.tgz#c1765b28d5a2a29143c0a556650fb7527cd9ab0d"
+ integrity sha512-c0bR9sgZuyHsC8xzYNrTl6koXBrLgBnVGG2UWwRbs8QnAF0Sf3LTPMjq0vulXZgKqPvMG++em0O5d6nN+oWvuQ==
dependencies:
babel-eslint "^10.0.3"
eslint-config-airbnb-base "^14.2.1"
@@ -898,25 +964,25 @@
stylelint-declaration-strict-value "1.7.7"
stylelint-scss "3.18.0"
-"@gitlab/svgs@1.211.0":
- version "1.211.0"
- resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.211.0.tgz#0351fa4cc008c4830f366aede535df0a8e63dda6"
- integrity sha512-fkHJfmKiy7lDwLFQ6z64sbGL+/hDDLzcMTj8O+VBC1xnlBVAIxe2eIs2DZLJcJwgLWncf4Uovp8+CeEfCY12sw==
+"@gitlab/svgs@1.212.0":
+ version "1.212.0"
+ resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.212.0.tgz#21a5df04c52b10cc1b8521cd8ff7c7d6d13716db"
+ integrity sha512-dv0bYTHA3hwi3mNU3bGMq1cd4HVKKFNwCNPgkF91JSp4Xt8DDtJ0Yq4X49ASsq4zCJ3odgkq2aPjEa/Sr5nINQ==
"@gitlab/tributejs@1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@gitlab/tributejs/-/tributejs-1.0.0.tgz#672befa222aeffc83e7d799b0500a7a4418e59b8"
integrity sha512-nmKw1+hB6MHvlmPz63yPwVs1qQkycHwsKgxpEbzmky16Y6mL4EJMk3w1b8QlOAF/AIAzjCERPhe/R4MJiohbZw==
-"@gitlab/ui@32.2.1":
- version "32.2.1"
- resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-32.2.1.tgz#e019124af981e8ceffd39f30cf08d315c53d4ac8"
- integrity sha512-19qe30gHtBG7g7wJy36bvS+ji1puJwVzAwqJOFXAh3axSa0Getyjyl9t5gmfwmZ2HehFTWLlThXppclnJVCEGA==
+"@gitlab/ui@32.11.0":
+ version "32.11.0"
+ resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-32.11.0.tgz#8c4a1724c1733a243f96e4a4813ae7f348502ba6"
+ integrity sha512-EqP5Ub/IWEi5ErX0txx5vsd6hF7d7dOT5GqaRX6rVaLsUhWLYQZ8ld2yEl5Hx7FLki1t3uag17KII5FcvRTDLg==
dependencies:
"@babel/standalone" "^7.0.0"
bootstrap-vue "2.18.1"
copy-to-clipboard "^3.0.8"
- dompurify "^2.3.1"
+ dompurify "^2.3.2"
echarts "^4.9.0"
highlight.js "^10.6.0"
js-beautify "^1.8.8"
@@ -1173,6 +1239,103 @@
consola "^2.15.0"
node-fetch "^2.6.1"
+"@oclif/command@^1.5.20", "@oclif/command@^1.8.0":
+ version "1.8.0"
+ resolved "https://registry.yarnpkg.com/@oclif/command/-/command-1.8.0.tgz#c1a499b10d26e9d1a611190a81005589accbb339"
+ integrity sha512-5vwpq6kbvwkQwKqAoOU3L72GZ3Ta8RRrewKj9OJRolx28KLJJ8Dg9Rf7obRwt5jQA9bkYd8gqzMTrI7H3xLfaw==
+ dependencies:
+ "@oclif/config" "^1.15.1"
+ "@oclif/errors" "^1.3.3"
+ "@oclif/parser" "^3.8.3"
+ "@oclif/plugin-help" "^3"
+ debug "^4.1.1"
+ semver "^7.3.2"
+
+"@oclif/config@^1.15.1", "@oclif/config@^1.17.0":
+ version "1.17.0"
+ resolved "https://registry.yarnpkg.com/@oclif/config/-/config-1.17.0.tgz#ba8639118633102a7e481760c50054623d09fcab"
+ integrity sha512-Lmfuf6ubjQ4ifC/9bz1fSCHc6F6E653oyaRXxg+lgT4+bYf9bk+nqrUpAbrXyABkCqgIBiFr3J4zR/kiFdE1PA==
+ dependencies:
+ "@oclif/errors" "^1.3.3"
+ "@oclif/parser" "^3.8.0"
+ debug "^4.1.1"
+ globby "^11.0.1"
+ is-wsl "^2.1.1"
+ tslib "^2.0.0"
+
+"@oclif/errors@^1.2.2", "@oclif/errors@^1.3.3":
+ version "1.3.5"
+ resolved "https://registry.yarnpkg.com/@oclif/errors/-/errors-1.3.5.tgz#a1e9694dbeccab10fe2fe15acb7113991bed636c"
+ integrity sha512-OivucXPH/eLLlOT7FkCMoZXiaVYf8I/w1eTAM1+gKzfhALwWTusxEx7wBmW0uzvkSg/9ovWLycPaBgJbM3LOCQ==
+ dependencies:
+ clean-stack "^3.0.0"
+ fs-extra "^8.1"
+ indent-string "^4.0.0"
+ strip-ansi "^6.0.0"
+ wrap-ansi "^7.0.0"
+
+"@oclif/linewrap@^1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@oclif/linewrap/-/linewrap-1.0.0.tgz#aedcb64b479d4db7be24196384897b5000901d91"
+ integrity sha512-Ups2dShK52xXa8w6iBWLgcjPJWjais6KPJQq3gQ/88AY6BXoTX+MIGFPrWQO1KLMiQfoTpcLnUwloN4brrVUHw==
+
+"@oclif/parser@^3.8.0", "@oclif/parser@^3.8.3":
+ version "3.8.5"
+ resolved "https://registry.yarnpkg.com/@oclif/parser/-/parser-3.8.5.tgz#c5161766a1efca7343e1f25d769efbefe09f639b"
+ integrity sha512-yojzeEfmSxjjkAvMRj0KzspXlMjCfBzNRPkWw8ZwOSoNWoJn+OCS/m/S+yfV6BvAM4u2lTzX9Y5rCbrFIgkJLg==
+ dependencies:
+ "@oclif/errors" "^1.2.2"
+ "@oclif/linewrap" "^1.0.0"
+ chalk "^2.4.2"
+ tslib "^1.9.3"
+
+"@oclif/plugin-help@^3", "@oclif/plugin-help@^3.2.0":
+ version "3.2.3"
+ resolved "https://registry.yarnpkg.com/@oclif/plugin-help/-/plugin-help-3.2.3.tgz#cd24010e7eb326782843d3aa6d6b5a4affebb2c3"
+ integrity sha512-l2Pd0lbOMq4u/7xsl9hqISFqyR9gWEz/8+05xmrXFr67jXyS6EUCQB+mFBa0wepltrmJu0sAFg9AvA2mLaMMqQ==
+ dependencies:
+ "@oclif/command" "^1.5.20"
+ "@oclif/config" "^1.15.1"
+ "@oclif/errors" "^1.2.2"
+ chalk "^4.1.0"
+ indent-string "^4.0.0"
+ lodash.template "^4.4.0"
+ string-width "^4.2.0"
+ strip-ansi "^6.0.0"
+ widest-line "^3.1.0"
+ wrap-ansi "^4.0.0"
+
+"@percy/config@^1.0.0-beta.36":
+ version "1.0.0-beta.65"
+ resolved "https://registry.yarnpkg.com/@percy/config/-/config-1.0.0-beta.65.tgz#8775d8d645c2b8a094850032d10810f654bb3f1e"
+ integrity sha512-q6mkrBq+nmDtIDj793lNIodEYmc5wVE7ZwsQ2kNRQIAq4aiIIrD8L5CfhEOSYQ5OzhFq+qUjcZK5GptmheF0sw==
+ dependencies:
+ "@percy/logger" "1.0.0-beta.65"
+ ajv "^8.6.2"
+ cosmiconfig "^7.0.0"
+ yaml "^1.10.0"
+
+"@percy/logger@1.0.0-beta.65", "@percy/logger@^1.0.0-beta.36":
+ version "1.0.0-beta.65"
+ resolved "https://registry.yarnpkg.com/@percy/logger/-/logger-1.0.0-beta.65.tgz#30a34797c935003334124e970f62914b0d124968"
+ integrity sha512-BJV0pjNlvcj4Y3nuMUGdb5RhjMduK40fRJJ9Lh/2qNk3pmnkGb9rH+GY+/0WY7quupNKxQjjyXcIP7I46/azNg==
+
+"@percy/migrate@^0.10.0":
+ version "0.10.0"
+ resolved "https://registry.yarnpkg.com/@percy/migrate/-/migrate-0.10.0.tgz#4157bd8ca1638f1cc072086074c8edec57978abc"
+ integrity sha512-3vOmOPmEeMlIZyCEDClZ2VER+4LH/Zp/YhvLkZeKH9RKxbktROF4Dnfs1u3m4YQ1gglerqK6VXFJfOjLJGyVuw==
+ dependencies:
+ "@oclif/command" "^1.8.0"
+ "@oclif/config" "^1.17.0"
+ "@oclif/plugin-help" "^3.2.0"
+ "@percy/config" "^1.0.0-beta.36"
+ "@percy/logger" "^1.0.0-beta.36"
+ cross-spawn "^7.0.3"
+ inquirer "^8.0.0"
+ inquirer-glob-prompt "^0.1.0"
+ jscodeshift "^0.11.0"
+ semver "^7.3.4"
+
"@polka/url@^1.0.0-next.9":
version "1.0.0-next.12"
resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.12.tgz#431ec342a7195622f86688bbda82e3166ce8cb28"
@@ -1193,56 +1356,56 @@
resolved "https://registry.yarnpkg.com/@rails/ujs/-/ujs-6.1.3-2.tgz#5d7e161e7061654e738a116a7ec8b58b51721a11"
integrity sha512-Nd0Im4cW8tIX8ZR3jE/dS3wnJrN46RJSdCfU59Cji2puctIWohq63LjKFMufUwm21bCasISNGoLdkr3S7nwONw==
-"@sentry/browser@5.26.0":
- version "5.26.0"
- resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.26.0.tgz#e90a197fb94c5f26c8e05d6a539c118f33c7d598"
- integrity sha512-52kNVpy10Zd3gJRGFkhnOQvr80WJg7+XBqjMOE0//Akh4PfvEK3IqmAjVqysz6aHdruwTTivKF4ZoAxL/pA7Rg==
+"@sentry/browser@5.30.0":
+ version "5.30.0"
+ resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.30.0.tgz#c28f49d551db3172080caef9f18791a7fd39e3b3"
+ integrity sha512-rOb58ZNVJWh1VuMuBG1mL9r54nZqKeaIlwSlvzJfc89vyfd7n6tQ1UXMN383QBz/MS5H5z44Hy5eE+7pCrYAfw==
dependencies:
- "@sentry/core" "5.26.0"
- "@sentry/types" "5.26.0"
- "@sentry/utils" "5.26.0"
+ "@sentry/core" "5.30.0"
+ "@sentry/types" "5.30.0"
+ "@sentry/utils" "5.30.0"
tslib "^1.9.3"
-"@sentry/core@5.26.0":
- version "5.26.0"
- resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.26.0.tgz#9b5fe4de8a869d733ebcc77f5ec9c619f8717a51"
- integrity sha512-Ubrw7K52orTVsaxpz8Su40FPXugKipoQC+zPrXcH+JIMB+o18kutF81Ae4WzuUqLfP7YB91eAlRrP608zw0EXA==
+"@sentry/core@5.30.0":
+ version "5.30.0"
+ resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3"
+ integrity sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==
dependencies:
- "@sentry/hub" "5.26.0"
- "@sentry/minimal" "5.26.0"
- "@sentry/types" "5.26.0"
- "@sentry/utils" "5.26.0"
+ "@sentry/hub" "5.30.0"
+ "@sentry/minimal" "5.30.0"
+ "@sentry/types" "5.30.0"
+ "@sentry/utils" "5.30.0"
tslib "^1.9.3"
-"@sentry/hub@5.26.0":
- version "5.26.0"
- resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.26.0.tgz#b2bbd8128cd5915f2ee59cbc29fff30272d74ec5"
- integrity sha512-lAYeWvvhGYS6eQ5d0VEojw0juxGc3v4aAu8VLvMKWcZ1jXD13Bhc46u9Nvf4qAY6BAQsJDQcpEZLpzJu1bk1Qw==
+"@sentry/hub@5.30.0":
+ version "5.30.0"
+ resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.30.0.tgz#2453be9b9cb903404366e198bd30c7ca74cdc100"
+ integrity sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==
dependencies:
- "@sentry/types" "5.26.0"
- "@sentry/utils" "5.26.0"
+ "@sentry/types" "5.30.0"
+ "@sentry/utils" "5.30.0"
tslib "^1.9.3"
-"@sentry/minimal@5.26.0":
- version "5.26.0"
- resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.26.0.tgz#851dea3644153ed3ac4837fa8ed5661d94e7a313"
- integrity sha512-mdFo3FYaI1W3KEd8EHATYx8mDOZIxeoUhcBLlH7Iej6rKvdM7p8GoECrmHPU1l6sCCPtBuz66QT5YeXc7WILsA==
+"@sentry/minimal@5.30.0":
+ version "5.30.0"
+ resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.30.0.tgz#ce3d3a6a273428e0084adcb800bc12e72d34637b"
+ integrity sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==
dependencies:
- "@sentry/hub" "5.26.0"
- "@sentry/types" "5.26.0"
+ "@sentry/hub" "5.30.0"
+ "@sentry/types" "5.30.0"
tslib "^1.9.3"
-"@sentry/types@5.26.0":
- version "5.26.0"
- resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.26.0.tgz#b0cbacb0b24cd86620fb296b46cf7277bb004a3e"
- integrity sha512-ugpa1ePOhK55pjsyutAsa2tiJVQEyGYCaOXzaheg/3+EvhMdoW+owiZ8wupfvPhtZFIU3+FPOVz0d5k9K5d1rw==
+"@sentry/types@5.30.0":
+ version "5.30.0"
+ resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.30.0.tgz#19709bbe12a1a0115bc790b8942917da5636f402"
+ integrity sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==
-"@sentry/utils@5.26.0":
- version "5.26.0"
- resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.26.0.tgz#09a3d01d91747f38f796cafeb24f8fd86e4fa05f"
- integrity sha512-F2gnHIAWbjiowcAgxz3VpKxY/NQ39NTujEd/NPnRTWlRynLFg3bAV+UvZFXljhYJeN3b/zRlScNDcpCWTrtZGw==
+"@sentry/utils@5.30.0":
+ version "5.30.0"
+ resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.30.0.tgz#9a5bd7ccff85ccfe7856d493bffa64cabc41e980"
+ integrity sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==
dependencies:
- "@sentry/types" "5.26.0"
+ "@sentry/types" "5.30.0"
tslib "^1.9.3"
"@sindresorhus/is@^0.14.0":
@@ -1264,10 +1427,10 @@
dependencies:
"@sinonjs/commons" "^1.7.0"
-"@sourcegraph/code-host-integration@0.0.59":
- version "0.0.59"
- resolved "https://registry.yarnpkg.com/@sourcegraph/code-host-integration/-/code-host-integration-0.0.59.tgz#ac64a9f90ff48363334407d12622542d0faa7720"
- integrity sha512-laZl6llJMr0OAYwihyhkVSrBmLSQy+X38HZKD590Sg+mgAp3C+Q9TXSYIEQjY2XrA3/ypuEbqoiTY8HyRl4b4g==
+"@sourcegraph/code-host-integration@0.0.60":
+ version "0.0.60"
+ resolved "https://registry.yarnpkg.com/@sourcegraph/code-host-integration/-/code-host-integration-0.0.60.tgz#2043877fabb7eb986fcb61b67ee480afbb29f4f0"
+ integrity sha512-T+MvM8SUF7daA279hyQgwmva3J5LvPqwgQ/mWwxdVshehOQIPLUd310I0c6x6nZ0F/x4UjDWgRWzAqy6NLwV1w==
"@stylelint/postcss-css-in-js@^0.37.2":
version "0.37.2"
@@ -1304,175 +1467,175 @@
dom-accessibility-api "^0.5.1"
pretty-format "^26.4.2"
-"@tiptap/core@^2.0.0-beta.86":
- version "2.0.0-beta.86"
- resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.0.0-beta.86.tgz#11b575aee4ad2f30f73114c786da5cd13dde30e0"
- integrity sha512-EeR6euRTJV9LhUog1PuiN1oLYRsz0SCEU5cQnGElzRzbd8dMnmFVc9cs81fbfjR8R1bfiarOJExrU2+OPHKXDw==
+"@tiptap/core@^2.0.0-beta.105":
+ version "2.0.0-beta.105"
+ resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.0.0-beta.105.tgz#3d758cbbf3e8c9b806d1017cd2e7444f192d8109"
+ integrity sha512-ut0ts9hrJXUJlSXZIN8iEt2TPbqYLFBanucUAr0ENLjIlpyyNVXz9IhS3bBEmo7vWExirZmY8O9oidQztesf2A==
dependencies:
"@types/prosemirror-commands" "^1.0.4"
"@types/prosemirror-inputrules" "^1.0.4"
"@types/prosemirror-keymap" "^1.0.4"
- "@types/prosemirror-model" "^1.13.1"
+ "@types/prosemirror-model" "^1.13.2"
"@types/prosemirror-schema-list" "^1.0.3"
"@types/prosemirror-state" "^1.2.7"
"@types/prosemirror-transform" "^1.1.4"
- "@types/prosemirror-view" "^1.17.2"
+ "@types/prosemirror-view" "^1.19.0"
prosemirror-commands "^1.1.10"
prosemirror-inputrules "^1.1.3"
prosemirror-keymap "^1.1.3"
- prosemirror-model "^1.14.2"
+ prosemirror-model "^1.14.3"
prosemirror-schema-list "^1.1.5"
prosemirror-state "^1.3.4"
prosemirror-transform "^1.3.2"
- prosemirror-view "^1.18.8"
+ prosemirror-view "^1.20.0"
-"@tiptap/extension-blockquote@^2.0.0-beta.14":
- version "2.0.0-beta.14"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-blockquote/-/extension-blockquote-2.0.0-beta.14.tgz#f49872981aecdd21341c4d5db32ab68cba945756"
- integrity sha512-1U/mJA1Yncl1Uvdv66oRhWrT7RZC/GdrZrvzU4EHdpRRwW4s71jvDVzqGX2tYwMO70TnwmkqMEWm0Csb1pOhMg==
+"@tiptap/extension-blockquote@^2.0.0-beta.15":
+ version "2.0.0-beta.15"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-blockquote/-/extension-blockquote-2.0.0-beta.15.tgz#40be203f7db47e027ea1a5ba42bbb0e33bb6c004"
+ integrity sha512-Cso44KsYsqKqaNveQmx5KVaLy9krq5AzE9WhGVDBSFqWhvuIJkQYrTRBbOTfUDs/st9VuwJrbjTDD65ow50wEw==
dependencies:
prosemirror-inputrules "^1.1.3"
-"@tiptap/extension-bold@^2.0.0-beta.14":
- version "2.0.0-beta.14"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-2.0.0-beta.14.tgz#6bf9ea70f7e24e6d674c7780471fcb6a7a4b91f4"
- integrity sha512-WhKB3GfXhIDISQE2jYIVYe0aVQCvQRJQZCRFeac7kMxHE2veHWpjqjbp7jSbvTQ7YVZxPZFvezVs+3HWz1K0xg==
+"@tiptap/extension-bold@^2.0.0-beta.15":
+ version "2.0.0-beta.15"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-2.0.0-beta.15.tgz#cf9ddb3fc316be9707753ad4e497bfb8a3ebb0c2"
+ integrity sha512-jKyV6iiwhxwa0+7uuKD74jNDVNLNOS1GmU14MgaA95pY5e1fyaRBPPX8Gtt89niz2CLOY711AV17RPZTe/e60w==
-"@tiptap/extension-bubble-menu@^2.0.0-beta.24":
- version "2.0.0-beta.24"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.0.0-beta.24.tgz#e6db5bc0386ccdbd483e57296b22eb6dd55914ba"
- integrity sha512-u1btwasgaidUr9JLQwFQwf9oeXUYPv9TyBzUn/soj9F8qKrWxQxTi/EQUsudvjumzsQOX+tZQIj/YtO5EzR+hA==
+"@tiptap/extension-bubble-menu@^2.0.0-beta.33":
+ version "2.0.0-beta.33"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.0.0-beta.33.tgz#50ee84c25118f7ee932385961211b64496355c74"
+ integrity sha512-EvXSXyeLFnOAEPvbVz9B4ppP+paDGyK/Fy9b36fkH0hacFLS/lKb/8HrfTXItc0uZIe6xY6RhXTdkx1eAPTdTA==
dependencies:
prosemirror-state "^1.3.4"
- prosemirror-view "^1.18.8"
+ prosemirror-view "^1.20.0"
tippy.js "^6.3.1"
-"@tiptap/extension-bullet-list@^2.0.0-beta.14":
- version "2.0.0-beta.14"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-bullet-list/-/extension-bullet-list-2.0.0-beta.14.tgz#29b9bfa2e908cdb01943242f75daf82115f5afd1"
- integrity sha512-PcyaTNk/aGaXVC98mPAq4TRjXG6dDNb0CAeBqFIo8hLywwwKTaLfLQJNHtm605MSoEo2f8XO6gfQhWgJQQ6qwA==
+"@tiptap/extension-bullet-list@^2.0.0-beta.15":
+ version "2.0.0-beta.15"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-bullet-list/-/extension-bullet-list-2.0.0-beta.15.tgz#74876851a8d227ba1a031d031631ed621c175e05"
+ integrity sha512-5i44JzsZOh8Ci6CuYRQy6W3jCpYgX0+VuJKeHvZ6Aomy4Qqrtc9Jk43PBmCj91lNUUtH6Io9l+kDrLCumEFnEg==
dependencies:
prosemirror-inputrules "^1.1.3"
-"@tiptap/extension-code-block-lowlight@2.0.0-beta.32":
- version "2.0.0-beta.32"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block-lowlight/-/extension-code-block-lowlight-2.0.0-beta.32.tgz#ef9ff6883f2d669e6be79c69f26749641462e1ea"
- integrity sha512-RnKAlE981k7VYIUUZ2jYZVGzZJalzrRw6dCf0rfgPvSY3T+ih9gVjKr+APGTuX3tsSR+s3UHs6YUI9+83pje3A==
+"@tiptap/extension-code-block-lowlight@2.0.0-beta.37":
+ version "2.0.0-beta.37"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block-lowlight/-/extension-code-block-lowlight-2.0.0-beta.37.tgz#672b2f21d49077285a507c2e204b07085df93906"
+ integrity sha512-EN8MoCZKB23nHNqgvB/wOS84ySUY9ahB6oao7wDpKAYqBkAF/hEXmDsylDySvyCKXf824lS/vztfaF0hHQbQ/g==
dependencies:
- "@tiptap/extension-code-block" "^2.0.0-beta.16"
+ "@tiptap/extension-code-block" "^2.0.0-beta.18"
"@types/lowlight" "^0.0.3"
lowlight "^1.20.0"
- prosemirror-model "^1.14.2"
+ prosemirror-model "^1.14.3"
prosemirror-state "^1.3.4"
- prosemirror-view "^1.18.8"
+ prosemirror-view "^1.20.0"
-"@tiptap/extension-code-block@^2.0.0-beta.16":
- version "2.0.0-beta.16"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block/-/extension-code-block-2.0.0-beta.16.tgz#7788ee1af04eb84fe194261bb1bb835dbe7ad59e"
- integrity sha512-FgKuobqybmkVidRsOSatgVYEyHldvGPBu7/nr5z131PHMqTe7Z35c4r2ts5DCZRsOoby17Nn4iLAENqtsmyyJQ==
+"@tiptap/extension-code-block@^2.0.0-beta.18":
+ version "2.0.0-beta.18"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block/-/extension-code-block-2.0.0-beta.18.tgz#3b43730cfca1ba26171530951b3cc324a500cb11"
+ integrity sha512-E2gz7ovl9nXLZzheqLyN3hi7A10fCaodDn4DvIl4wiEbKZpF7WFBNeb+FQetWNay9UWNeDO94SCX9+rT9H+yHA==
dependencies:
prosemirror-inputrules "^1.1.3"
-"@tiptap/extension-code@^2.0.0-beta.14":
- version "2.0.0-beta.14"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-code/-/extension-code-2.0.0-beta.14.tgz#679a741589d63006140605553be7c6148c000814"
- integrity sha512-Z67Ae2BPTAXG8VxHaw2SAS9HjUmfL1fUew5IUdaML8GOSaBYjzIffvN/+0MNdxkBEFxMJu4zm3o/WdWIoUckdQ==
+"@tiptap/extension-code@^2.0.0-beta.16":
+ version "2.0.0-beta.16"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-code/-/extension-code-2.0.0-beta.16.tgz#b258ff90ebe703a4d36ff0c650e6b2cab634028d"
+ integrity sha512-Kakg/RMiVrxjzIkLVDXtbCzRh/9W8dgSG04IhMZNOI8N9vWn8Z78jdUyxEEDTcL/JyWWcMxn9AsJw2U5ajO3pA==
-"@tiptap/extension-document@^2.0.0-beta.12":
- version "2.0.0-beta.12"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-document/-/extension-document-2.0.0-beta.12.tgz#dfbc7e686075a38662a43708903cd2047cf7f4b2"
- integrity sha512-i5anc2n98Jg1gi6WDLTaS76jLIUe41FHuMHgL4DCIDXv8m2q0qnktfmOvh9AMF7cPzJ2NVAR9xYw0Pxm3qXY4w==
+"@tiptap/extension-document@^2.0.0-beta.13":
+ version "2.0.0-beta.13"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-document/-/extension-document-2.0.0-beta.13.tgz#8cfb29d4de64bf4a790817f730c05b4f9b7167b2"
+ integrity sha512-nrufdKziA/wovaY4DjGkc8OGuIZi8CH8CW3+yYfeWbruwFKkyZHlZy9nplFWSEqBHPAeqD+px9r91yGMW3ontA==
-"@tiptap/extension-dropcursor@^2.0.0-beta.17":
- version "2.0.0-beta.17"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-dropcursor/-/extension-dropcursor-2.0.0-beta.17.tgz#3ca59c264b49a91c1a5b2ce8de3e898903d0a5bc"
- integrity sha512-f7hSA4e9xaVi1GAb6JJErVy2QtdpTxjJmtyV8nG7xGvoI0QH1IIiftD88FWGvUGN1CHBg83XpPpmIIFH7oKthw==
+"@tiptap/extension-dropcursor@^2.0.0-beta.19":
+ version "2.0.0-beta.19"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-dropcursor/-/extension-dropcursor-2.0.0-beta.19.tgz#8a37ffe27e484eb44dd18297830d1fd8ce0c50ce"
+ integrity sha512-rslIcVvD42NNh5sEbkCkG03DWMFBrS5KoK+lDOdIcC1DjmTtpVgcLvvE01btzaB3ljx+UVqI2Zaxa6VOiTeEMw==
dependencies:
- "@types/prosemirror-dropcursor" "^1.0.2"
+ "@types/prosemirror-dropcursor" "^1.0.3"
prosemirror-dropcursor "^1.3.5"
-"@tiptap/extension-floating-menu@^2.0.0-beta.18":
- version "2.0.0-beta.18"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.0.0-beta.18.tgz#4d9b7f58c73f6c718a74503c5ff514b06f615e27"
- integrity sha512-1fCRGdTxCiRm5DV91GwKYn9yu43oonq6iuRAlgcTZ2ON03MAAG55j+cDA2S3JSwbsA7Vr49ijmXBY/fEdU/fiQ==
+"@tiptap/extension-floating-menu@^2.0.0-beta.27":
+ version "2.0.0-beta.27"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.0.0-beta.27.tgz#692686854116823be624028fd8d73aa900cf71a9"
+ integrity sha512-PgoqO5OxBDMFZroXFD7mpwfDLxeG44xFHu6WK4Gf3O8jqGAQpEr4rMKyTnoNL9PYFhEwtNBzxUopumOT0Po/zQ==
dependencies:
prosemirror-state "^1.3.4"
- prosemirror-view "^1.18.8"
+ prosemirror-view "^1.20.0"
tippy.js "^6.3.1"
-"@tiptap/extension-gapcursor@^2.0.0-beta.18":
- version "2.0.0-beta.18"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-gapcursor/-/extension-gapcursor-2.0.0-beta.18.tgz#67c2266ec21c90f003e989862b709475f5427fea"
- integrity sha512-J75xnNrNWHILZviu5ikHtIKF5WFMmmAgkwyateNwgoMwRpyTrZI5Go2LpZ1VEw4AhEA2OcBEvPBEtxWefrBV5g==
+"@tiptap/extension-gapcursor@^2.0.0-beta.19":
+ version "2.0.0-beta.19"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-gapcursor/-/extension-gapcursor-2.0.0-beta.19.tgz#6d826c240496b1a77808999d51b8917adb372cc5"
+ integrity sha512-GZYMR+Z45bn87CMuOHyxzTJOFoCv58mNakIBdSGX+8A+ExBFeZr/qLqxDxN3wz+LRqy7pREe5K3UxJxpsYnCzA==
dependencies:
"@types/prosemirror-gapcursor" "^1.0.4"
prosemirror-gapcursor "^1.1.5"
-"@tiptap/extension-hard-break@^2.0.0-beta.14":
- version "2.0.0-beta.14"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-2.0.0-beta.14.tgz#dce00c49dc614caac82720b930501a59b38d5584"
- integrity sha512-PbGQJGvgYdsEzeHidlodVCaOkcPaib4A7i0MJlXIyzUnBz8Eiv5+Ks2UBG5JgfBB4GGopatZaLfz8VkG3qfGxw==
+"@tiptap/extension-hard-break@^2.0.0-beta.16":
+ version "2.0.0-beta.16"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-2.0.0-beta.16.tgz#1a55e901ce2deaaeaf53d77d254371955fe8fd99"
+ integrity sha512-vRw8OIJlvlr17Y7mtJGL/dWbotX9fjgmA/zYqL//UIXQjp1FWW5JMh5E1Z5+jlJpGWjsWGH8fHpGSM2JCZVPRw==
-"@tiptap/extension-heading@^2.0.0-beta.14":
- version "2.0.0-beta.14"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-heading/-/extension-heading-2.0.0-beta.14.tgz#63df6d7282afd3c2db2253af2e538c3bf2800751"
- integrity sha512-ezJRM5ikZK5bmzYCsvq6xCw1KlellSwHcmAVJsupHk3aPD3UF2IEXnKQYbtDjGN62sB2KwnNy6gKFJ5v48gpxA==
+"@tiptap/extension-heading@^2.0.0-beta.15":
+ version "2.0.0-beta.15"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-heading/-/extension-heading-2.0.0-beta.15.tgz#d62f32a2ec8ce5a6d4e716aa7a45dfb707283848"
+ integrity sha512-UoXDwEdCV9KiPh0wj0jj2Jt6VDqkoTaSU3d9bmEBLwg1Gjgbuv39JDst7oxSqbf9rgbl3txbeOy35wVBKe9CqA==
dependencies:
prosemirror-inputrules "^1.1.3"
-"@tiptap/extension-history@^2.0.0-beta.14":
- version "2.0.0-beta.14"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-history/-/extension-history-2.0.0-beta.14.tgz#7990a592a521ca4147e733eed78fcb738ed6ba95"
- integrity sha512-Uf9FKgp2/+Z1FD5R55huDvkBorZZMeOU3dfo8K4YL/lnSc4Yyk4huQu+6kK9XDrisIK68NlfYY1GFts49KbZmA==
+"@tiptap/extension-history@^2.0.0-beta.16":
+ version "2.0.0-beta.16"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-history/-/extension-history-2.0.0-beta.16.tgz#f40317bab795e2daf981aa1a01d6025f306be72c"
+ integrity sha512-nrNwV8a7zUt1t2I/kPX5Y6N9vZ8mrugimJIQmPGIp/4mmw1SEUzkaPpIsv6+ELmqMHSDktQ0ofb3pXeWDXWZvw==
dependencies:
"@types/prosemirror-history" "^1.0.3"
- prosemirror-history "^1.1.3"
+ prosemirror-history "^1.2.0"
-"@tiptap/extension-horizontal-rule@^2.0.0-beta.17":
- version "2.0.0-beta.17"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.0.0-beta.17.tgz#25c15bfab5794a3f1bcf6f4df03bef56ddac80aa"
- integrity sha512-JDjwRSEWFTgdx0ob4zKjfzKcRxkiQTyPEGEZ2uIcTeXTPD0B0j2ysuWIWnqgwtpFdYfv1wOCU59kNLQx+a5JmA==
+"@tiptap/extension-horizontal-rule@^2.0.0-beta.19":
+ version "2.0.0-beta.19"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.0.0-beta.19.tgz#d98d0070a2cead32a497b62586c0e259d31f3f2e"
+ integrity sha512-RrU7+inExgC+rRmFWoTxALbu/IgRGRik11LPhMhqrCB+n0XFRUMyVEb/jbfgHWVrPmTXq0MbSWW6LYw3iREzRA==
dependencies:
prosemirror-state "^1.3.4"
-"@tiptap/extension-image@^2.0.0-beta.14":
- version "2.0.0-beta.14"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-image/-/extension-image-2.0.0-beta.14.tgz#31eae69cce3d81af81a1c0fbd253beca3c253429"
- integrity sha512-OguktQVJ8D0wFm8jrnct16Pu+T5J0N+rzMNk5kguJJCMiFjhQZ4USZw5jHU6BIAKwulupXmZ/PUBIYCx02LhIA==
+"@tiptap/extension-image@^2.0.0-beta.15":
+ version "2.0.0-beta.15"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-image/-/extension-image-2.0.0-beta.15.tgz#07bdc23c9804c830a394f78242648dd7783a469e"
+ integrity sha512-iMwQ154RPefOxgqTTHjOA735YWesyjBhYvD9fFxRDctM2vLxEYYYFOENXEBCFLNAr94gfaxefCEdkuNYHl9H7g==
-"@tiptap/extension-italic@^2.0.0-beta.14":
- version "2.0.0-beta.14"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-2.0.0-beta.14.tgz#5b56a806ef6507dc2001eaeeeb234ee0b25d8544"
- integrity sha512-kDdHVHfHuQe3s0A+xrJm0OTE3MrCRWDFHiJ+rC5JnY3/b8GEzovOD6cslz6CeVSZAUDERmHKVPF+ioAct7HXtw==
+"@tiptap/extension-italic@^2.0.0-beta.15":
+ version "2.0.0-beta.15"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-2.0.0-beta.15.tgz#9a81f686cf221110478935596f0b47a76d4c2f45"
+ integrity sha512-ZCz1vCysLdvOUrwODuyBP0BDaemCLh6ib7qTYoSDKdive9kfn0Vc5Fg3o8xgHrtrUfwKIJz/sWOknjDEGIc9cw==
-"@tiptap/extension-link@^2.0.0-beta.18":
- version "2.0.0-beta.18"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-link/-/extension-link-2.0.0-beta.18.tgz#792c671daf3db79873b8425e68da43dd19af230b"
- integrity sha512-i87vd82hsBCw6ROR8qjffWMsm7pd/4kwqhytq3l8zrArWLZXxC6JwknYjVNcwiWs2JFr+xJNAnzNgr0oGXguTg==
+"@tiptap/extension-link@^2.0.0-beta.20":
+ version "2.0.0-beta.20"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-link/-/extension-link-2.0.0-beta.20.tgz#dbb2aa4f01212bbd0c3fb14b563e28f31140eae2"
+ integrity sha512-VljjF5Pmd8xeUxN+Wbypyh8zGEMBWJTwzHUVMbkAEU8IZTdk2gDDcAOiYPyU9+j0vAVbSXi1EAsBRIIlj0OaKQ==
dependencies:
prosemirror-state "^1.3.4"
-"@tiptap/extension-list-item@^2.0.0-beta.13":
- version "2.0.0-beta.13"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-list-item/-/extension-list-item-2.0.0-beta.13.tgz#49f32d70a554897ffa3b37b492ebaf5953f8a975"
- integrity sha512-5nvrCvcV35J6WjLd8xQCQWnj2HIDsfTalr0D57jMwym3ZCIEvLwf23DQQ1nNsOHhopmS/Emixh+RQpXUZjH8lQ==
-
-"@tiptap/extension-ordered-list@^2.0.0-beta.14":
+"@tiptap/extension-list-item@^2.0.0-beta.14":
version "2.0.0-beta.14"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-ordered-list/-/extension-ordered-list-2.0.0-beta.14.tgz#54487f8b9246226586d0190d07a449a97536436a"
- integrity sha512-7Tq8jotj7WSUIRlMhNWCv6u99Yu+lyuI8SLx7hRZbmUiGShCQX1J5YI+dti4qlrlhOjjqs1kV95Dgg0JaBtNQw==
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-list-item/-/extension-list-item-2.0.0-beta.14.tgz#65a9ff9daa11bc9ca8bc2989a891abe68081cfbd"
+ integrity sha512-t6xwEqP+d5443Ul2Jvqz9kXb3ro7bA7yY9HA0vskm3120WxxHW9jxgxZN+82Ot5Tm7nXOAlsN6vuqnt4idnxZQ==
+
+"@tiptap/extension-ordered-list@^2.0.0-beta.16":
+ version "2.0.0-beta.16"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-ordered-list/-/extension-ordered-list-2.0.0-beta.16.tgz#3ef25a8dd8ddbd2b1aa5ce89d5a2e5a3ecafcf4e"
+ integrity sha512-3n0h5FBfQqBrN/zqF/Ngoyd1bZxeIRLwWI7ak4KulpvOg5V/yw3sw5CSxr2f13ZI9AgGaTq8yOsTYs9dkCCnsQ==
dependencies:
prosemirror-inputrules "^1.1.3"
-"@tiptap/extension-paragraph@^2.0.0-beta.15":
- version "2.0.0-beta.15"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-2.0.0-beta.15.tgz#89483a2f438d8412287d441c890304985c2ac07f"
- integrity sha512-mYGjo85oyLVwgWc8+XZ0cvr5GSHSKvkj5t2t1PyHXDmt6Nhl5cJcHgXDztIUhyh0gbRVFKjwQMeUAZWg6DGxMg==
+"@tiptap/extension-paragraph@^2.0.0-beta.17":
+ version "2.0.0-beta.17"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-2.0.0-beta.17.tgz#f8f0263359b95dec9c10078699697908568d9be9"
+ integrity sha512-qCQVCf9c2hgaeIdfy22PaoZyW5Vare/1aGkOEAaZma5RjrUbV9hrRKwoW9LsDjnh1EN1fIeKdg02yEhnHWtG8A==
-"@tiptap/extension-strike@^2.0.0-beta.16":
- version "2.0.0-beta.16"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-2.0.0-beta.16.tgz#cccce9713824e05ebde895f84f747b8bbed45f7d"
- integrity sha512-SPSCUVzxFLKZzgMXYfeUZE+xy52CJckswo0dZ/8NcUthl3mkDS/TwzokpQ/wsyEsKaJNYt8vh2S9HpadSrLcug==
+"@tiptap/extension-strike@^2.0.0-beta.17":
+ version "2.0.0-beta.17"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-2.0.0-beta.17.tgz#2280ea4e8c50189c2729814d2ae484e58c712a36"
+ integrity sha512-+WRd0RuCK4+jFKNVN+4rHTa5VMqqGDO2uc+TknkqhFqWp/z96OAGlpHJOwPrnW1fLbpjEBBQIr1vVYSw6KgcZg==
"@tiptap/extension-subscript@^2.0.0-beta.4":
version "2.0.0-beta.4"
@@ -1484,33 +1647,33 @@
resolved "https://registry.yarnpkg.com/@tiptap/extension-superscript/-/extension-superscript-2.0.0-beta.4.tgz#16906d71dd8f9892101cf792f42005f8cd404516"
integrity sha512-rTQCnSnloSf6UN1y3zhu6j41MxrcCVWm5JIPX8VEt60WsOXJLAc/YJHLYi2FWhh/Psq8k78sPrmZbjYUrj3Dkw==
-"@tiptap/extension-table-cell@^2.0.0-beta.13":
- version "2.0.0-beta.13"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-table-cell/-/extension-table-cell-2.0.0-beta.13.tgz#c01eada4859d5ea487d61e68cc7fab7ed2e4842a"
- integrity sha512-dnPMsBySCbOLG9irQt+cle44y6RxNVwEdknpVocjME6wAgyLpyiShHpS4Tq1j6jAhTYcXR29lNCVMcsIwzSK0A==
-
-"@tiptap/extension-table-header@^2.0.0-beta.15":
+"@tiptap/extension-table-cell@^2.0.0-beta.15":
version "2.0.0-beta.15"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-table-header/-/extension-table-header-2.0.0-beta.15.tgz#884d16f104671ee672f1f629f4e4fef0b096bfbb"
- integrity sha512-8K0YXFG7bcM1iMZ1pAVcshXdchDQv17a1jGjKXC1+e1NjH1eb/Ya8eyFWlyxC0ZjAFNzQF4r3mGzmGTbWoI6cA==
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-table-cell/-/extension-table-cell-2.0.0-beta.15.tgz#2059946b1657f0f22415bda84cee77fb1eb232b1"
+ integrity sha512-MyZHJlFOF2z4Y1DQ/uuFbDPYQxSrl/PW8TEpAh2UQI/PGVsKkjzHItTvLtWSgo7t+tuPHbEOvIBDfpQKSyfbWg==
-"@tiptap/extension-table-row@^2.0.0-beta.13":
- version "2.0.0-beta.13"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-table-row/-/extension-table-row-2.0.0-beta.13.tgz#3f9a61112afcde750228f4437ae3cd7b82d02f74"
- integrity sha512-tGE3/ADBaVgpBYXgdx5YkAs7waYLKDRormUXKNnTpR+4qVHKUmXrDUTdJ2urXaANaB95F8R5Lj146h+EYiLxgw==
+"@tiptap/extension-table-header@^2.0.0-beta.17":
+ version "2.0.0-beta.17"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-table-header/-/extension-table-header-2.0.0-beta.17.tgz#1bd008825146e6f5fc607a1d8682b5d47ba08f25"
+ integrity sha512-HctO608QQEPe29QBtxXcDfBKfv+m9u2jBJ5AYpo7HjYGfUYRxv5uQpGXX3RW/c50+AhyTF0skF6Td1jiZcEPPw==
-"@tiptap/extension-table@^2.0.0-beta.25":
- version "2.0.0-beta.25"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-table/-/extension-table-2.0.0-beta.25.tgz#57accf19c07e96bd0db868eb791da20bd423af36"
- integrity sha512-mVUJL3FKX1vksmrnUcNqRzbAk4kJjKVxAf5RMuUQRcyp8sp3vJinR/C8v5nBrDgurXLB3wF0bD2/FRu7GWEqPA==
+"@tiptap/extension-table-row@^2.0.0-beta.14":
+ version "2.0.0-beta.14"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-table-row/-/extension-table-row-2.0.0-beta.14.tgz#9ec98c73e309ee966b71ccd140019874d179e0c8"
+ integrity sha512-mewdlTqgBCyzeZIZ6F08gfuzwsiYjQ7BvABo2UhDfr0+EN2UvfJj0bT3tGgeZhMxT5Js2DXL+c+ZOVJxWJ9faQ==
+
+"@tiptap/extension-table@^2.0.0-beta.30":
+ version "2.0.0-beta.30"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-table/-/extension-table-2.0.0-beta.30.tgz#f6ff97ea71b17ecf3371ddf80374df9f49042334"
+ integrity sha512-s6+HRo3sFv7SUprsUAAF27hg7inITpzl78If3XdrpscuzTVuRmd7GsFnY+aZGPVikekwCMjp/0klE92P4A7w0w==
dependencies:
prosemirror-tables "^1.1.1"
- prosemirror-view "^1.18.8"
+ prosemirror-view "^1.20.0"
-"@tiptap/extension-task-item@^2.0.0-beta.17":
- version "2.0.0-beta.17"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-task-item/-/extension-task-item-2.0.0-beta.17.tgz#e4e010c321b8f9aa5f49847c48e4e3a0695a47a9"
- integrity sha512-uV5f9rWo9NAZ+oyt/mkhFEZfcngr92pVL2sn291RiT0qw9NRvdIQ6PLH24il9zu+jjeWmh1cJnBuQos+MQqjyg==
+"@tiptap/extension-task-item@^2.0.0-beta.18":
+ version "2.0.0-beta.18"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-task-item/-/extension-task-item-2.0.0-beta.18.tgz#f109c15c997038d8099b64dba4cfc4e219b426e4"
+ integrity sha512-SmXWdfpDFIBGxWH4Xhb9d6jRSK7jJqsw0GqC5KAtIQ9gNvAQS1j5FqAtWfxlb8FkunIfV6MNnxDP2ZgbKvaEug==
dependencies:
prosemirror-inputrules "^1.1.3"
@@ -1519,19 +1682,19 @@
resolved "https://registry.yarnpkg.com/@tiptap/extension-task-list/-/extension-task-list-2.0.0-beta.17.tgz#c0f40325abf1b6a23868e72ab32f9724a8b42a7b"
integrity sha512-E17VBqW2lXF59hCQ/3/Kg0hYSDGvVC4B3W8miZwCXt5WTOl98Gk6qAiDXl+2mDKZvnsLty/YrgkD88OlZSIEbQ==
-"@tiptap/extension-text@^2.0.0-beta.12":
- version "2.0.0-beta.12"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-2.0.0-beta.12.tgz#b857f36dda5e8cedd350f9bad7115e4060f8d9c0"
- integrity sha512-JEWLYOJKSpmpaI0YTzj30uodpsrSYDGSvy5dT5bYvWovIvLmggKPHl0iKIPDWAM5xfd07CkP2+BFFRblMh96IA==
+"@tiptap/extension-text@^2.0.0-beta.13":
+ version "2.0.0-beta.13"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-2.0.0-beta.13.tgz#da0af8d9a3f149d20076e15d88c6af21fb6d940f"
+ integrity sha512-0EtAwuRldCAoFaL/iXgkRepEeOd55rPg5N4FQUN1xTwZT7PDofukP0DG/2jff/Uj17x4uTaJAa9qlFWuNnDvjw==
-"@tiptap/vue-2@^2.0.0-beta.39":
- version "2.0.0-beta.39"
- resolved "https://registry.yarnpkg.com/@tiptap/vue-2/-/vue-2-2.0.0-beta.39.tgz#f6d75af99b072848381f0c443b50ec09186eb43b"
- integrity sha512-O8hCzrAZTbjebcD3XWsbUieudnD7rvDFGmHSRmb0igg//ARO43IWe2xdu2Hlx1MT9b+83YjgDhRyMjHcsKRtzw==
+"@tiptap/vue-2@^2.0.0-beta.50":
+ version "2.0.0-beta.50"
+ resolved "https://registry.yarnpkg.com/@tiptap/vue-2/-/vue-2-2.0.0-beta.50.tgz#1c1c3e7d696aaa167fc776e11b393b182f1bfbb4"
+ integrity sha512-o325eQbSoxxd6QXc27Mjd+T+yj1CnSTo0IQkbjbzYure8E0ReYXzW2wx5oE6DZA43Ejss2KPXZDEgiUNYRyX1Q==
dependencies:
- "@tiptap/extension-bubble-menu" "^2.0.0-beta.24"
- "@tiptap/extension-floating-menu" "^2.0.0-beta.18"
- prosemirror-view "^1.18.8"
+ "@tiptap/extension-bubble-menu" "^2.0.0-beta.33"
+ "@tiptap/extension-floating-menu" "^2.0.0-beta.27"
+ prosemirror-view "^1.20.0"
"@toast-ui/editor@^2.5.2":
version "2.5.2"
@@ -1714,10 +1877,10 @@
"@types/prosemirror-state" "*"
"@types/prosemirror-view" "*"
-"@types/prosemirror-dropcursor@^1.0.2":
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/@types/prosemirror-dropcursor/-/prosemirror-dropcursor-1.0.2.tgz#476b90a661f32d6d6a21599f53fcd71e36c65a1f"
- integrity sha512-5Ez7yIAvHQgn5YJkuafEh0w4sHV7pksCX9LTPBFRjCuznamcKsnYCez4mR0PwIWq/WuPDvHkR+wqKb4l0t9/aQ==
+"@types/prosemirror-dropcursor@^1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@types/prosemirror-dropcursor/-/prosemirror-dropcursor-1.0.3.tgz#49250849b8a0b86e8c29eb1ba70a463e53e46947"
+ integrity sha512-b0/8njnJ4lwyHKcGuCMf3x7r1KjxyugB1R/c2iMCjplsJHSC7UY9+OysqgJR5uUXRekUSGniiLgBtac/lvH6wg==
dependencies:
"@types/prosemirror-state" "*"
@@ -1755,10 +1918,10 @@
"@types/prosemirror-state" "*"
"@types/prosemirror-view" "*"
-"@types/prosemirror-model@*", "@types/prosemirror-model@^1.13.1":
- version "1.13.1"
- resolved "https://registry.yarnpkg.com/@types/prosemirror-model/-/prosemirror-model-1.13.1.tgz#53df04ee174a7e1dc12747005b1b4c02565adcc4"
- integrity sha512-tA1AlI+YR2t3Ve5eeQVJnQm4yV4wVlNfeogHusD1X3OEqqMYTuPssThgIMR4PxPHtvV871Ix8a20bUiJvULDgw==
+"@types/prosemirror-model@*", "@types/prosemirror-model@^1.13.2":
+ version "1.13.2"
+ resolved "https://registry.yarnpkg.com/@types/prosemirror-model/-/prosemirror-model-1.13.2.tgz#2adad3ec478f83204f155d7fb94c9dfde2fc3296"
+ integrity sha512-a2rDB0aZ+7aIP7uBqQq1wLb4Hg4qqEvpkCqvhsgT/gG8IWC0peCAZfQ24sgTco0qSJLeDgIbtPeU6mgr869/kg==
dependencies:
"@types/orderedmap" "*"
@@ -1787,10 +1950,10 @@
dependencies:
"@types/prosemirror-model" "*"
-"@types/prosemirror-view@*", "@types/prosemirror-view@^1.17.2":
- version "1.17.2"
- resolved "https://registry.yarnpkg.com/@types/prosemirror-view/-/prosemirror-view-1.17.2.tgz#3aff71a0802bdfc310404db8a37ced2db69fd74f"
- integrity sha512-1yUTQZ3yx2YvJTHZdY/rmvSiJ8tJLhUmlNgbFdkFaFcKC6LTBntg5lQvOZ53Aytadab+M/xz7/TzGX8iYB/7gw==
+"@types/prosemirror-view@*", "@types/prosemirror-view@^1.19.0":
+ version "1.19.0"
+ resolved "https://registry.yarnpkg.com/@types/prosemirror-view/-/prosemirror-view-1.19.0.tgz#35320b6875ae7c750bce799cccf735e5da91af7a"
+ integrity sha512-Y8OX9L+Yni0HgXAN9wcNSf61IId13uqpURnRC5WkmCOlVDsr35vfGjj+tcaQL4dZzblsu3bRkXI/c0oGXp+xgw==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
@@ -2108,11 +2271,6 @@ acorn@^8.0.4:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.1.0.tgz#52311fd7037ae119cbb134309e901aa46295b3fe"
integrity sha512-LWCF/Wn0nfHOmJ9rzQApGnxnvgfROzGilS8936rqN/lfcYkY9MYZzdMqN+2NJ4SlTc+m5HiSa+kNfDtI64dwUA==
-after@0.8.2:
- version "0.8.2"
- resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f"
- integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=
-
agent-base@4, agent-base@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
@@ -2148,10 +2306,10 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5:
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
-ajv@^8.0.1:
- version "8.5.0"
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.5.0.tgz#695528274bcb5afc865446aa275484049a18ae4b"
- integrity sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ==
+ajv@^8.0.1, ajv@^8.6.2:
+ version "8.6.2"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.2.tgz#2fb45e0e5fcbc0813326c1c3da535d1881bb0571"
+ integrity sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==
dependencies:
fast-deep-equal "^3.1.1"
json-schema-traverse "^1.0.0"
@@ -2337,13 +2495,6 @@ apollo-utilities@1.3.4, apollo-utilities@^1.3.0, apollo-utilities@^1.3.4:
ts-invariant "^0.4.0"
tslib "^1.10.0"
-append-transform@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab"
- integrity sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==
- dependencies:
- default-require-extensions "^2.0.0"
-
aproba@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
@@ -2441,11 +2592,6 @@ array.prototype.flat@^1.2.3:
define-properties "^1.1.3"
es-abstract "^1.18.0-next.1"
-arraybuffer.slice@~0.0.7:
- version "0.0.7"
- resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675"
- integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==
-
arrify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
@@ -2484,6 +2630,13 @@ assign-symbols@^1.0.0:
resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=
+ast-types@0.14.2:
+ version "0.14.2"
+ resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.14.2.tgz#600b882df8583e3cd4f2df5fa20fa83759d4bdfd"
+ integrity sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==
+ dependencies:
+ tslib "^2.0.1"
+
astral-regex@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"
@@ -2568,6 +2721,11 @@ axios@^0.20.0:
dependencies:
follow-redirects "^1.10.0"
+babel-core@^7.0.0-bridge.0:
+ version "7.0.0-bridge.0"
+ resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece"
+ integrity sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==
+
babel-eslint@^10.0.3:
version "10.0.3"
resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.3.tgz#81a2c669be0f205e19462fed2482d33e4687a88a"
@@ -2673,11 +2831,6 @@ babylon@7.0.0-beta.19:
resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.19.tgz#e928c7e807e970e0536b078ab3e0c48f9e052503"
integrity sha512-Vg0C9s/REX6/WIXN37UKpv5ZhRi6A4pjHlpkE34+8/a6c2W1Q692n3hmc+SZG5lKRnaExLUbxtJ1SVT+KaCQ/A==
-backo2@1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947"
- integrity sha1-MasayLEpNjRj41s+u2n038+6eUc=
-
bail@^1.0.0:
version "1.0.5"
resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776"
@@ -2688,20 +2841,10 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
-base64-arraybuffer@0.1.5:
- version "0.1.5"
- resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8"
- integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg=
-
-base64-js@^1.0.2:
- version "1.2.3"
- resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.3.tgz#fb13668233d9614cf5fb4bce95a9ba4096cdf801"
- integrity sha512-MsAhsUW1GxCdgYSO6tAfZrNapmUKk7mWx/k5mFY/A1gBtkaCaNapTg+FExCw1r9yeaZhqx/xPg43xgTFH6KL5w==
-
-base64id@1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6"
- integrity sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=
+base64-js@^1.0.2, base64-js@^1.3.1:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
+ integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
base@^0.11.1:
version "0.11.2"
@@ -2728,13 +2871,6 @@ bcrypt-pbkdf@^1.0.0:
dependencies:
tweetnacl "^0.14.3"
-better-assert@~1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522"
- integrity sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=
- dependencies:
- callsite "1.0.0"
-
big.js@^5.2.2:
version "5.2.2"
resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
@@ -2750,12 +2886,16 @@ binaryextensions@2:
resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.1.1.tgz#3209a51ca4a4ad541a3b8d3d6a6d5b83a2485935"
integrity sha512-XBaoWE9RW8pPdPQNibZsW2zh8TW6gcarXp1FZPwT8Uop8ScSNldJEWf2k9l3HeTqdrEwsOsFcq74RiJECW34yA==
-blob@0.0.4:
- version "0.0.4"
- resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.4.tgz#bcf13052ca54463f30f9fc7e95b9a47630a94921"
- integrity sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=
+bl@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
+ integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==
+ dependencies:
+ buffer "^5.5.0"
+ inherits "^2.0.4"
+ readable-stream "^3.4.0"
-bluebird@^3.1.1, bluebird@^3.3.0, bluebird@^3.5.5, bluebird@~3.5.0:
+bluebird@^3.1.1, bluebird@^3.5.5, bluebird@~3.5.0:
version "3.5.5"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.5.tgz#a8d0afd73251effbbd5fe384a77d73003c17a71f"
integrity sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==
@@ -2765,7 +2905,7 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.9:
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828"
integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==
-body-parser@1.19.0, body-parser@^1.16.1:
+body-parser@1.19.0:
version "1.19.0"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==
@@ -2852,7 +2992,7 @@ braces@^2.3.1:
split-string "^3.0.2"
to-regex "^3.0.1"
-braces@^3.0.1, braces@^3.0.2, braces@~3.0.2:
+braces@^3.0.1, braces@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
@@ -2974,6 +3114,14 @@ buffer@4.9.1, buffer@^4.3.0:
ieee754 "^1.1.4"
isarray "^1.0.0"
+buffer@^5.5.0:
+ version "5.7.1"
+ resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
+ integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
+ dependencies:
+ base64-js "^1.3.1"
+ ieee754 "^1.1.13"
+
builtin-status-codes@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
@@ -3086,24 +3234,11 @@ call-me-maybe@^1.0.1:
resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b"
integrity sha1-JtII6onje1y95gJQoV8DHBak1ms=
-callsite@1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20"
- integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA=
-
callsites@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.0.0.tgz#fb7eb569b72ad7a45812f93fd9430a3e410b3dd3"
integrity sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw==
-camel-case@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73"
- integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=
- dependencies:
- no-case "^2.2.0"
- upper-case "^1.1.1"
-
camelcase-keys@^6.2.2:
version "6.2.2"
resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz#5e755d6ba51aa223ec7d3d52f25778210f9dc3c0"
@@ -3147,7 +3282,7 @@ catharsis@~0.8.9:
dependencies:
underscore-contrib "~0.3.0"
-chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2:
+chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
@@ -3164,10 +3299,10 @@ chalk@^3.0.0:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
-chalk@^4.0.0, chalk@^4.1.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a"
- integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==
+chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1:
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
+ integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
@@ -3192,6 +3327,11 @@ character-reference-invalid@^1.0.0:
resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560"
integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==
+chardet@^0.7.0:
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
+ integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
+
charenc@~0.0.1:
version "0.0.2"
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
@@ -3221,7 +3361,7 @@ cheerio@^1.0.0-rc.9:
parse5-htmlparser2-tree-adapter "^6.0.1"
tslib "^2.2.0"
-"chokidar@>=3.0.0 <4.0.0", chokidar@^2.1.8, chokidar@^3.0.0, chokidar@^3.2.2, chokidar@^3.4.0, chokidar@^3.4.1:
+"chokidar@>=3.0.0 <4.0.0", chokidar@^2.1.8, chokidar@^3.2.2, chokidar@^3.4.0, chokidar@^3.4.1:
version "3.4.0"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.0.tgz#b30611423ce376357c765b9b8f904b9fba3c0be8"
integrity sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==
@@ -3276,23 +3416,40 @@ class-utils@^0.3.5:
isobject "^3.0.0"
static-extend "^0.1.1"
-clean-css@^4.1.6, clean-css@^4.2.1:
- version "4.2.1"
- resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17"
- integrity sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==
- dependencies:
- source-map "~0.6.0"
-
clean-stack@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b"
integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==
+clean-stack@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-3.0.1.tgz#155bf0b2221bf5f4fba89528d24c5953f17fe3a8"
+ integrity sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==
+ dependencies:
+ escape-string-regexp "4.0.0"
+
cli-boxes@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.0.tgz#538ecae8f9c6ca508e3c3c95b453fe93cb4c168d"
integrity sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==
+cli-cursor@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307"
+ integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==
+ dependencies:
+ restore-cursor "^3.1.0"
+
+cli-spinners@^2.5.0:
+ version "2.6.0"
+ resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.0.tgz#36c7dc98fb6a9a76bd6238ec3f77e2425627e939"
+ integrity sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==
+
+cli-width@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6"
+ integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==
+
clipboard@^1.7.1:
version "1.7.1"
resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-1.7.1.tgz#360d6d6946e99a7a1fef395e42ba92b5e9b5a16b"
@@ -3352,6 +3509,11 @@ clone-response@^1.0.2:
dependencies:
mimic-response "^1.0.0"
+clone@^1.0.2:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
+ integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
+
co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
@@ -3428,10 +3590,10 @@ colorette@^1.2.1, colorette@^1.2.2:
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94"
integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==
-colors@^1.1.0:
- version "1.3.3"
- resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d"
- integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==
+colors@^1.1.2:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
+ integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
combined-stream@^1.0.6, combined-stream@~1.0.6:
version "1.0.8"
@@ -3440,7 +3602,7 @@ combined-stream@^1.0.6, combined-stream@~1.0.6:
dependencies:
delayed-stream "~1.0.0"
-commander@2, commander@^2.19.0, commander@^2.20.0, commander@^2.20.3, commander@~2.20.0:
+commander@2, commander@^2.19.0, commander@^2.20.0, commander@^2.20.3:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
@@ -3455,26 +3617,11 @@ commondir@^1.0.1:
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=
-compare-versions@^3.4.0:
- version "3.5.1"
- resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.5.1.tgz#26e1f5cf0d48a77eced5046b9f67b6b61075a393"
- integrity sha512-9fGPIB7C6AyM18CJJBHt5EnCZDG3oiTJYy0NjfIAGjKpzv0tkxWko7TNQHF5ymqm7IH03tqmeuBxtvD+Izh6mg==
-
-component-bind@1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1"
- integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=
-
-component-emitter@1.2.1, component-emitter@^1.2.1:
+component-emitter@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"
integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=
-component-inherit@0.0.3:
- version "0.0.3"
- resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143"
- integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=
-
compressible@~2.0.16:
version "2.0.17"
resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.17.tgz#6e8c108a16ad58384a977f3a482ca20bff2f38c1"
@@ -3560,16 +3707,6 @@ connect-history-api-fallback@^1.6.0:
resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc"
integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==
-connect@^3.6.0:
- version "3.6.6"
- resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.6.tgz#09eff6c55af7236e137135a72574858b6786f524"
- integrity sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=
- dependencies:
- debug "2.6.9"
- finalhandler "1.1.0"
- parseurl "~1.3.2"
- utils-merge "1.0.1"
-
consola@^2.15.0:
version "2.15.3"
resolved "https://registry.yarnpkg.com/consola/-/consola-2.15.3.tgz#2e11f98d6a4be71ff72e0bdf07bd23e12cb61550"
@@ -3623,11 +3760,6 @@ cookie-signature@1.0.6:
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw=
-cookie@0.3.1:
- version "0.3.1"
- resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
- integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=
-
cookie@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba"
@@ -3687,10 +3819,10 @@ core-js-pure@^3.0.0:
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.5.tgz#c79e75f5e38dbc85a662d91eea52b8256d53b813"
integrity sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==
-core-js@^3.1.3, core-js@^3.16.2:
- version "3.16.2"
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.16.2.tgz#3f485822889c7fc48ef463e35be5cc2a4a01a1f4"
- integrity sha512-P0KPukO6OjMpjBtHSceAZEWlDD1M2Cpzpg6dBbrjFqFhBHe/BwhxaP820xKOjRn/lZRQirrCusIpLS/n2sgXLQ==
+core-js@^3.17.3:
+ version "3.17.3"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.17.3.tgz#8e8bd20e91df9951e903cabe91f9af4a0895bc1e"
+ integrity sha512-lyvajs+wd8N1hXfzob1LdOCCHFU4bGMbqqmLn1Q4QlCpDqWPpGf+p0nj+LNrvDDG33j0hZXw2nsvvVpHysxyNw==
core-js@~2.3.0:
version "2.3.0"
@@ -3766,7 +3898,7 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5:
shebang-command "^1.2.0"
which "^1.2.9"
-cross-spawn@^7.0.0, cross-spawn@^7.0.2:
+cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
@@ -3802,11 +3934,6 @@ crypto-random-string@^2.0.0:
resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5"
integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==
-css-b64-images@~0.2.5:
- version "0.2.5"
- resolved "https://registry.yarnpkg.com/css-b64-images/-/css-b64-images-0.2.5.tgz#42005d83204b2b4a5d93b6b1a5644133b5927a02"
- integrity sha1-QgBdgyBLK0pdk7axpWRBM7WSegI=
-
css-color-names@0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0"
@@ -3901,11 +4028,6 @@ cssstyle@^2.2.0:
dependencies:
cssom "~0.3.6"
-custom-event@~1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425"
- integrity sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=
-
custom-jquery-matchers@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/custom-jquery-matchers/-/custom-jquery-matchers-2.1.0.tgz#e5988fa9715c416b0986b372563f872d9e91e024"
@@ -4182,7 +4304,7 @@ dagre-d3@^0.6.4:
graphlib "^2.1.8"
lodash "^4.17.15"
-dagre@^0.8.4, dagre@^0.8.5:
+dagre@^0.8.5:
version "0.8.5"
resolved "https://registry.yarnpkg.com/dagre/-/dagre-0.8.5.tgz#ba30b0055dac12b6c1fcc247817442777d06afee"
integrity sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==
@@ -4206,11 +4328,6 @@ data-urls@^2.0.0:
whatwg-mimetype "^2.3.0"
whatwg-url "^8.0.0"
-date-format@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/date-format/-/date-format-2.1.0.tgz#31d5b5ea211cf5fd764cd38baf9d033df7e125cf"
- integrity sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==
-
date-now@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
@@ -4233,7 +4350,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9:
dependencies:
ms "2.0.0"
-debug@3.1.0, debug@~3.1.0:
+debug@3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
@@ -4317,12 +4434,12 @@ default-gateway@^4.2.0:
execa "^1.0.0"
ip-regex "^2.1.0"
-default-require-extensions@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7"
- integrity sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=
+defaults@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d"
+ integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=
dependencies:
- strip-bom "^3.0.0"
+ clone "^1.0.2"
defer-to-connect@^1.0.1:
version "1.1.3"
@@ -4419,17 +4536,12 @@ detect-node@^2.0.4:
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c"
integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==
-di@^0.0.1:
- version "0.0.1"
- resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c"
- integrity sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=
-
diff-sequences@^26.5.0:
version "26.5.0"
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.5.0.tgz#ef766cf09d43ed40406611f11c6d8d9dd8b2fefd"
integrity sha512-ZXx86srb/iYy6jG71k++wBN9P9J05UNQ5hQHQd9MtMPvcqXPx/vKU69jfHV637D00Q2gSgPk2D+jSx3l1lDW/Q==
-diff@^3.2.0, diff@^3.4.0:
+diff@^3.4.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
@@ -4500,16 +4612,6 @@ dom-event-types@^1.0.0:
resolved "https://registry.yarnpkg.com/dom-event-types/-/dom-event-types-1.0.0.tgz#5830a0a29e1bf837fe50a70cd80a597232813cae"
integrity sha512-2G2Vwi2zXTHBGqXHsJ4+ak/iP0N8Ar+G8a7LiD2oup5o4sQWytwqqrZu/O6hIMV0KMID2PL69OhpshLO0n7UJQ==
-dom-serialize@^2.2.0:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b"
- integrity sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=
- dependencies:
- custom-event "~1.0.0"
- ent "~2.2.0"
- extend "^3.0.0"
- void-elements "^2.0.0"
-
dom-serializer@0:
version "0.2.2"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
@@ -4568,10 +4670,15 @@ domhandler@^4.0.0, domhandler@^4.2.0:
dependencies:
domelementtype "^2.2.0"
-dompurify@^2.3.1:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.1.tgz#a47059ca21fd1212d3c8f71fdea6943b8bfbdf6a"
- integrity sha512-xGWt+NHAQS+4tpgbOAI08yxW0Pr256Gu/FNE2frZVTbgrBUn8M7tz7/ktS/LZ2MHeGqz6topj0/xY+y8R5FBFw==
+dompurify@2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.0.tgz#07bb39515e491588e5756b1d3e8375b5964814e2"
+ integrity sha512-VV5C6Kr53YVHGOBKO/F86OYX6/iLTw2yVSI721gKetxpHCK/V5TaLEf9ODjRgl1KLSWRMY6cUhAbv/c+IUnwQw==
+
+dompurify@^2.3.2:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.2.tgz#c773efa410abb5c087c7caf44934fefa448f6e60"
+ integrity sha512-jXJnvWloI+scD+N5uBikpUMsYXZb0LCAXxLFAOLS5duCzKfXLqBCpuINvFOiI4eJgTLggrngljT18HNoakHUsA==
domutils@^1.5.1:
version "1.7.0"
@@ -4700,7 +4807,7 @@ emojis-list@^3.0.0:
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78"
integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
-encodeurl@~1.0.1, encodeurl@~1.0.2:
+encodeurl@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
@@ -4717,46 +4824,6 @@ ends-with@^0.2.0:
resolved "https://registry.yarnpkg.com/ends-with/-/ends-with-0.2.0.tgz#2f9da98d57a50cfda4571ce4339000500f4e6b8a"
integrity sha1-L52pjVelDP2kVxzkM5AAUA9Oa4o=
-engine.io-client@~3.2.0:
- version "3.2.1"
- resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.2.1.tgz#6f54c0475de487158a1a7c77d10178708b6add36"
- integrity sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==
- dependencies:
- component-emitter "1.2.1"
- component-inherit "0.0.3"
- debug "~3.1.0"
- engine.io-parser "~2.1.1"
- has-cors "1.1.0"
- indexof "0.0.1"
- parseqs "0.0.5"
- parseuri "0.0.5"
- ws "~3.3.1"
- xmlhttprequest-ssl "~1.5.4"
- yeast "0.1.2"
-
-engine.io-parser@~2.1.0, engine.io-parser@~2.1.1:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.1.2.tgz#4c0f4cff79aaeecbbdcfdea66a823c6085409196"
- integrity sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==
- dependencies:
- after "0.8.2"
- arraybuffer.slice "~0.0.7"
- base64-arraybuffer "0.1.5"
- blob "0.0.4"
- has-binary2 "~1.0.2"
-
-engine.io@~3.2.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.2.0.tgz#54332506f42f2edc71690d2f2a42349359f3bf7d"
- integrity sha512-mRbgmAtQ4GAlKwuPnnAvXXwdPhEx+jkc0OBCLrXuD/CRvwNK3AxRSnqK4FSqmAMRRHryVJP8TopOvmEaA64fKw==
- dependencies:
- accepts "~1.3.4"
- base64id "1.0.0"
- cookie "0.3.1"
- debug "~3.1.0"
- engine.io-parser "~2.1.0"
- ws "~3.3.1"
-
enhanced-resolve@^0.9.1:
version "0.9.1"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz#4d6e689b3725f86090927ccc86cd9f1635b89e2e"
@@ -4782,11 +4849,6 @@ enquirer@^2.3.5:
dependencies:
ansi-colors "^4.1.1"
-ent@~2.2.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d"
- integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0=
-
entities@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
@@ -4797,13 +4859,6 @@ entities@^2.0.0, entities@~2.0.0:
resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f"
integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==
-entity-decode@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/entity-decode/-/entity-decode-2.0.2.tgz#e4f807e52c3294246e9347d1f2b02b07fd5f92e7"
- integrity sha512-5CCY/3ci4MC1m2jlumNjWd7VBFt4VfFnmSqSNmVcXq4gxM3Vmarxtt+SvmBnzwLS669MWdVuXboNVj1qN2esVg==
- dependencies:
- he "^1.1.1"
-
errno@^0.1.3, errno@~0.1.7:
version "0.1.7"
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618"
@@ -4879,6 +4934,11 @@ escape-html@~1.0.3:
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
+escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
+ integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
+
escape-string-regexp@^1.0.5, escape-string-regexp@~1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
@@ -4889,11 +4949,6 @@ escape-string-regexp@^2.0.0:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344"
integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==
-escape-string-regexp@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
- integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
-
escodegen@^1.14.1:
version "1.14.3"
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503"
@@ -4999,11 +5054,6 @@ eslint-plugin-import@^2.22.1:
resolve "^1.17.0"
tsconfig-paths "^3.9.0"
-eslint-plugin-jasmine@4.1.2:
- version "4.1.2"
- resolved "https://registry.yarnpkg.com/eslint-plugin-jasmine/-/eslint-plugin-jasmine-4.1.2.tgz#50cc20d603b02b37727f8d174d4b83b9b8ef25a5"
- integrity sha512-Jr52EBi6Ql5WVDvRCKBID9kRD6/CaObvCWmgHpqobczX2Mzt8/QMu9vpgx6q/O5jyQ9CIGrKaEbPuEfHRf8guw==
-
eslint-plugin-jest@^23.8.2:
version "23.8.2"
resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-23.8.2.tgz#6f28b41c67ef635f803ebd9e168f6b73858eb8d4"
@@ -5069,10 +5119,10 @@ eslint-visitor-keys@^2.0.0:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8"
integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==
-eslint@7.31.0:
- version "7.31.0"
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.31.0.tgz#f972b539424bf2604907a970860732c5d99d3aca"
- integrity sha512-vafgJpSh2ia8tnTkNUkwxGmnumgckLh5aAbLa1xRmIn9+owi8qBNGKL+B881kNKNTy7FFqTEkpNkUvmw0n6PkA==
+eslint@7.32.0:
+ version "7.32.0"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d"
+ integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==
dependencies:
"@babel/code-frame" "7.12.11"
"@eslint/eslintrc" "^0.4.3"
@@ -5133,7 +5183,7 @@ espree@^7.3.0, espree@^7.3.1:
acorn-jsx "^5.3.1"
eslint-visitor-keys "^1.3.0"
-esprima@^4.0.0, esprima@^4.0.1:
+esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
@@ -5340,6 +5390,15 @@ extend@^3.0.0, extend@~3.0.2:
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
+external-editor@^3.0.3:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495"
+ integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==
+ dependencies:
+ chardet "^0.7.0"
+ iconv-lite "^0.4.24"
+ tmp "^0.0.33"
+
extglob@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543"
@@ -5446,6 +5505,13 @@ figgy-pudding@^3.5.1:
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==
+figures@^3.0.0, figures@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af"
+ integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==
+ dependencies:
+ escape-string-regexp "^1.0.5"
+
file-entry-cache@^6.0.0, file-entry-cache@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027"
@@ -5461,14 +5527,6 @@ file-loader@^6.2.0:
loader-utils "^2.0.0"
schema-utils "^3.0.0"
-fileset@^2.0.3:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0"
- integrity sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=
- dependencies:
- glob "^7.0.3"
- minimatch "^3.0.3"
-
fill-range@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7"
@@ -5486,19 +5544,6 @@ fill-range@^7.0.1:
dependencies:
to-regex-range "^5.0.1"
-finalhandler@1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5"
- integrity sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=
- dependencies:
- debug "2.6.9"
- encodeurl "~1.0.1"
- escape-html "~1.0.3"
- on-finished "~2.3.0"
- parseurl "~1.3.2"
- statuses "~1.3.1"
- unpipe "~1.0.0"
-
finalhandler@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d"
@@ -5512,7 +5557,7 @@ finalhandler@~1.1.2:
statuses "~1.5.0"
unpipe "~1.0.0"
-find-cache-dir@^2.1.0:
+find-cache-dir@^2.0.0, find-cache-dir@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7"
integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==
@@ -5575,16 +5620,16 @@ flat-cache@^3.0.4:
flatted "^3.1.0"
rimraf "^3.0.2"
-flatted@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.0.tgz#55122b6536ea496b4b44893ee2608141d10d9916"
- integrity sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==
-
flatted@^3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469"
integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==
+flow-parser@0.*:
+ version "0.157.0"
+ resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.157.0.tgz#8ef0a748a838a505820a3099690472757d39581c"
+ integrity sha512-p0vdtrM8oAMlscIXpX0e/eGWll5NPteVChNtlQncbIbivH+BdiwXHN5QO6myAfmebd027r9RiQKdUPsFAiEVgQ==
+
flush-write-stream@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8"
@@ -5647,12 +5692,12 @@ from2@^2.1.0:
inherits "^2.0.1"
readable-stream "^2.0.0"
-fs-extra@^7.0.1:
- version "7.0.1"
- resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9"
- integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==
+fs-extra@^8.1:
+ version "8.1.0"
+ resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
+ integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
dependencies:
- graceful-fs "^4.1.2"
+ graceful-fs "^4.2.0"
jsonfile "^4.0.0"
universalify "^0.1.0"
@@ -5698,10 +5743,10 @@ fuzzaldrin-plus@^0.6.0:
resolved "https://registry.yarnpkg.com/fuzzaldrin-plus/-/fuzzaldrin-plus-0.6.0.tgz#832f6489fbe876769459599c914a670ec22947ee"
integrity sha1-gy9kifvodnaUWVmckUpnDsIpR+4=
-gensync@^1.0.0-beta.1:
- version "1.0.0-beta.1"
- resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269"
- integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==
+gensync@^1.0.0-beta.2:
+ version "1.0.0-beta.2"
+ resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
+ integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
get-caller-file@^2.0.1:
version "2.0.5"
@@ -5865,10 +5910,10 @@ globals@^13.6.0, globals@^13.9.0:
dependencies:
type-fest "^0.20.2"
-globby@^11.0.1, globby@^11.0.2:
- version "11.0.3"
- resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb"
- integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==
+globby@^11.0.1, globby@^11.0.2, globby@^11.0.3:
+ version "11.0.4"
+ resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5"
+ integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==
dependencies:
array-union "^2.1.0"
dir-glob "^3.0.1"
@@ -5924,12 +5969,12 @@ got@^9.6.0:
to-readable-stream "^1.0.0"
url-parse-lax "^3.0.0"
-graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.4:
- version "4.2.4"
- resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
- integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
+graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4:
+ version "4.2.8"
+ resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
+ integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==
-graphlib@^2.1.7, graphlib@^2.1.8:
+graphlib@^2.1.8:
version "2.1.8"
resolved "https://registry.yarnpkg.com/graphlib/-/graphlib-2.1.8.tgz#5761d414737870084c92ec7b5dbcb0592c9d35da"
integrity sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==
@@ -5963,17 +6008,6 @@ handle-thing@^2.0.0:
resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754"
integrity sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==
-handlebars@^4.1.2:
- version "4.7.2"
- resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.2.tgz#01127b3840156a0927058779482031afe0e730d7"
- integrity sha512-4PwqDL2laXtTWZghzzCtunQUTLbo31pcCJrd/B/9JP8XbhVzpS5ZXuKqlOzsd1rtcaLo4KqAn8nl8mkknS4MHw==
- dependencies:
- neo-async "^2.6.0"
- optimist "^0.6.1"
- source-map "^0.6.1"
- optionalDependencies:
- uglify-js "^3.1.4"
-
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
@@ -5992,18 +6026,6 @@ hard-rejection@^2.1.0:
resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883"
integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==
-has-binary2@~1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.2.tgz#e83dba49f0b9be4d026d27365350d9f03f54be98"
- integrity sha1-6D26SfC5vk0CbSc2U1DZ8D9Uvpg=
- dependencies:
- isarray "2.0.1"
-
-has-cors@1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39"
- integrity sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=
-
has-flag@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
@@ -6090,7 +6112,7 @@ hash.js@^1.0.0, hash.js@^1.0.3:
inherits "^2.0.3"
minimalistic-assert "^1.0.0"
-he@^1.1.0, he@^1.1.1, he@^1.2.0:
+he@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
@@ -6155,19 +6177,6 @@ html-escaper@^2.0.0:
resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.0.tgz#71e87f931de3fe09e56661ab9a29aadec707b491"
integrity sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig==
-html-minifier@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-4.0.0.tgz#cca9aad8bce1175e02e17a8c33e46d8988889f56"
- integrity sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==
- dependencies:
- camel-case "^3.0.0"
- clean-css "^4.2.1"
- commander "^2.19.0"
- he "^1.2.0"
- param-case "^2.1.1"
- relateurl "^0.2.7"
- uglify-js "^3.5.1"
-
html-tags@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140"
@@ -6249,7 +6258,7 @@ http-proxy-middleware@0.19.1:
lodash "^4.17.11"
micromatch "^3.1.10"
-http-proxy@^1.13.0, http-proxy@^1.17.0:
+http-proxy@^1.17.0:
version "1.18.1"
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549"
integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==
@@ -6285,7 +6294,7 @@ human-signals@^1.1.1:
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==
-iconv-lite@0.4, iconv-lite@0.4.24:
+iconv-lite@0.4, iconv-lite@0.4.24, iconv-lite@^0.4.24:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
@@ -6304,7 +6313,7 @@ icss-utils@^4.1.0:
dependencies:
postcss "^7.0.14"
-ieee754@1.1.13, ieee754@^1.1.4:
+ieee754@1.1.13, ieee754@^1.1.13, ieee754@^1.1.4:
version "1.1.13"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84"
integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==
@@ -6388,11 +6397,6 @@ indexes-of@^1.0.1:
resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607"
integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc=
-indexof@0.0.1:
- version "0.0.1"
- resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d"
- integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=
-
infer-owner@^1.0.3, infer-owner@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467"
@@ -6431,6 +6435,36 @@ ini@^1.3.4, ini@^1.3.5, ini@~1.3.0:
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
+inquirer-glob-prompt@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/inquirer-glob-prompt/-/inquirer-glob-prompt-0.1.0.tgz#3676bc10bcdd31e17121146be9c6467a2d79fc85"
+ integrity sha512-Zw9XYJdrBBJ5TZjLH8Nu8PIa54huvkP0xeNOTtKh3bis0DNAJWMtdpT9PIJBkqheMUnwIPmv8jkjOr7aPKYFqg==
+ dependencies:
+ chalk "^4.1.0"
+ figures "^3.2.0"
+ globby "^11.0.3"
+ rxjs "^6.6.7"
+
+inquirer@^8.0.0:
+ version "8.1.2"
+ resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.1.2.tgz#65b204d2cd7fb63400edd925dfe428bafd422e3d"
+ integrity sha512-DHLKJwLPNgkfwNmsuEUKSejJFbkv0FMO9SMiQbjI3n5NQuCrSIBqP66ggqyz2a6t2qEolKrMjhQ3+W/xXgUQ+Q==
+ dependencies:
+ ansi-escapes "^4.2.1"
+ chalk "^4.1.1"
+ cli-cursor "^3.1.0"
+ cli-width "^3.0.0"
+ external-editor "^3.0.3"
+ figures "^3.0.0"
+ lodash "^4.17.21"
+ mute-stream "0.0.8"
+ ora "^5.3.0"
+ run-async "^2.4.0"
+ rxjs "^7.2.0"
+ string-width "^4.1.0"
+ strip-ansi "^6.0.0"
+ through "^2.3.6"
+
internal-ip@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907"
@@ -6444,7 +6478,7 @@ interpret@^1.4.0:
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
-invariant@^2.2.2, invariant@^2.2.4:
+invariant@^2.2.2:
version "2.2.4"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
@@ -6643,6 +6677,11 @@ is-installed-globally@^0.3.1:
global-dirs "^2.0.1"
is-path-inside "^3.0.1"
+is-interactive@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e"
+ integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==
+
is-negative-zero@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24"
@@ -6756,6 +6795,11 @@ is-typedarray@^1.0.0, is-typedarray@~1.0.0:
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
+is-unicode-supported@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7"
+ integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==
+
is-whitespace@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/is-whitespace/-/is-whitespace-0.3.0.tgz#1639ecb1be036aec69a54cbb401cfbed7114ab7f"
@@ -6771,7 +6815,7 @@ is-wsl@^1.1.0:
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d"
integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=
-is-wsl@^2.2.0:
+is-wsl@^2.1.1, is-wsl@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271"
integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==
@@ -6788,16 +6832,6 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
-isarray@2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e"
- integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=
-
-isbinaryfile@^3.0.0:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.2.tgz#4a3e974ec0cba9004d3fc6cde7209ea69368a621"
- integrity sha1-Sj6XTsDLqQBNP8bN5yCeppNopiE=
-
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
@@ -6820,55 +6854,11 @@ isstream@~0.1.2:
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
-istanbul-api@^2.1.6:
- version "2.1.6"
- resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-2.1.6.tgz#d61702a9d1c66ad89d92e66d401e16b0bda4a35f"
- integrity sha512-x0Eicp6KsShG1k1rMgBAi/1GgY7kFGEBwQpw3PXGEmu+rBcBNhqU8g2DgY9mlepAsLPzrzrbqSgCGANnki4POA==
- dependencies:
- async "^2.6.2"
- compare-versions "^3.4.0"
- fileset "^2.0.3"
- istanbul-lib-coverage "^2.0.5"
- istanbul-lib-hook "^2.0.7"
- istanbul-lib-instrument "^3.3.0"
- istanbul-lib-report "^2.0.8"
- istanbul-lib-source-maps "^3.0.6"
- istanbul-reports "^2.2.4"
- js-yaml "^3.13.1"
- make-dir "^2.1.0"
- minimatch "^3.0.4"
- once "^1.4.0"
-
-istanbul-lib-coverage@^2.0.5:
- version "2.0.5"
- resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49"
- integrity sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==
-
istanbul-lib-coverage@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec"
integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==
-istanbul-lib-hook@^2.0.7:
- version "2.0.7"
- resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz#c95695f383d4f8f60df1f04252a9550e15b5b133"
- integrity sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==
- dependencies:
- append-transform "^1.0.0"
-
-istanbul-lib-instrument@^3.3.0:
- version "3.3.0"
- resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz#a5f63d91f0bbc0c3e479ef4c5de027335ec6d630"
- integrity sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==
- dependencies:
- "@babel/generator" "^7.4.0"
- "@babel/parser" "^7.4.3"
- "@babel/template" "^7.4.0"
- "@babel/traverse" "^7.4.3"
- "@babel/types" "^7.4.0"
- istanbul-lib-coverage "^2.0.5"
- semver "^6.0.0"
-
istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d"
@@ -6879,15 +6869,6 @@ istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3:
istanbul-lib-coverage "^3.0.0"
semver "^6.3.0"
-istanbul-lib-report@^2.0.8:
- version "2.0.8"
- resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz#5a8113cd746d43c4889eba36ab10e7d50c9b4f33"
- integrity sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==
- dependencies:
- istanbul-lib-coverage "^2.0.5"
- make-dir "^2.1.0"
- supports-color "^6.1.0"
-
istanbul-lib-report@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6"
@@ -6897,17 +6878,6 @@ istanbul-lib-report@^3.0.0:
make-dir "^3.0.0"
supports-color "^7.1.0"
-istanbul-lib-source-maps@^3.0.6:
- version "3.0.6"
- resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz#284997c48211752ec486253da97e3879defba8c8"
- integrity sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==
- dependencies:
- debug "^4.1.1"
- istanbul-lib-coverage "^2.0.5"
- make-dir "^2.1.0"
- rimraf "^2.6.3"
- source-map "^0.6.1"
-
istanbul-lib-source-maps@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz#75743ce6d96bb86dc7ee4352cf6366a23f0b1ad9"
@@ -6917,13 +6887,6 @@ istanbul-lib-source-maps@^4.0.0:
istanbul-lib-coverage "^3.0.0"
source-map "^0.6.1"
-istanbul-reports@^2.2.4:
- version "2.2.6"
- resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.6.tgz#7b4f2660d82b29303a8fe6091f8ca4bf058da1af"
- integrity sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==
- dependencies:
- handlebars "^4.1.2"
-
istanbul-reports@^3.0.0, istanbul-reports@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.2.tgz#d593210e5000683750cb09fc0644e4b6e27fd53b"
@@ -6941,23 +6904,6 @@ istextorbinary@^2.2.1:
editions "^1.3.3"
textextensions "2"
-jasmine-core@^2.9.0:
- version "2.9.0"
- resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.9.0.tgz#bfbb56defcd30789adec5a3fbba8504233289c72"
- integrity sha1-v7tW3vzTB4mt7Fo/u6hQQjMonHI=
-
-jasmine-diff@^0.1.3:
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/jasmine-diff/-/jasmine-diff-0.1.3.tgz#93ccc2dcc41028c5ddd4606558074839f2deeaa8"
- integrity sha1-k8zC3MQQKMXd1GBlWAdIOfLe6qg=
- dependencies:
- diff "^3.2.0"
-
-jasmine-jquery@^2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/jasmine-jquery/-/jasmine-jquery-2.1.1.tgz#d4095e646944a26763235769ab018d9f30f0d47b"
- integrity sha1-1AleZGlEomdjI1dpqwGNnzDw1Hs=
-
jed@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/jed/-/jed-1.1.1.tgz#7a549bbd9ffe1585b0cd0a191e203055bee574b4"
@@ -7372,11 +7318,6 @@ jquery.caret@^0.3.1:
resolved "https://registry.yarnpkg.com/jquery.caret/-/jquery.caret-0.3.1.tgz#9c093318faf327eff322e826ca9f3241368bc7b8"
integrity sha1-nAkzGPrzJ+/zIugmyp8yQTaLx7g=
-jquery.waitforimages@^2.2.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/jquery.waitforimages/-/jquery.waitforimages-2.2.0.tgz#63f23131055a1b060dc913e6d874bcc9b9e6b16b"
- integrity sha1-Y/IxMQVaGwYNyRPm2HS8ybnmsWs=
-
"jquery@>= 1.9.1", jquery@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.0.tgz#c72a09f15c1bdce142f49dbf1170bdf8adac2470"
@@ -7423,6 +7364,31 @@ jsbn@~0.1.0:
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
+jscodeshift@^0.11.0:
+ version "0.11.0"
+ resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.11.0.tgz#4f95039408f3f06b0e39bb4d53bc3139f5330e2f"
+ integrity sha512-SdRK2C7jjs4k/kT2mwtO07KJN9RnjxtKn03d9JVj6c3j9WwaLcFYsICYDnLAzY0hp+wG2nxl+Cm2jWLiNVYb8g==
+ dependencies:
+ "@babel/core" "^7.1.6"
+ "@babel/parser" "^7.1.6"
+ "@babel/plugin-proposal-class-properties" "^7.1.0"
+ "@babel/plugin-proposal-nullish-coalescing-operator" "^7.1.0"
+ "@babel/plugin-proposal-optional-chaining" "^7.1.0"
+ "@babel/plugin-transform-modules-commonjs" "^7.1.0"
+ "@babel/preset-flow" "^7.0.0"
+ "@babel/preset-typescript" "^7.1.0"
+ "@babel/register" "^7.0.0"
+ babel-core "^7.0.0-bridge.0"
+ colors "^1.1.2"
+ flow-parser "0.*"
+ graceful-fs "^4.2.4"
+ micromatch "^3.1.10"
+ neo-async "^2.5.0"
+ node-dir "^0.1.17"
+ recast "^0.20.3"
+ temp "^0.8.1"
+ write-file-atomic "^2.3.0"
+
jsdoc-vue@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/jsdoc-vue/-/jsdoc-vue-1.0.0.tgz#ff3ac1ba6bc4a74079bb79058a7bf0066e346235"
@@ -7590,95 +7556,6 @@ jszip@^3.1.3:
pako "~1.0.2"
readable-stream "~2.0.6"
-karma-chrome-launcher@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.0.0.tgz#5c3a7f877a304e90781c28fcd9a49e334a890f42"
- integrity sha512-u/PnVgDOP97AUe/gJeABlC6Wa6aQ83MZsm0JgsJQ5bGQ9XcXON/7b2aRhl59A62Zom+q3PFveBkczc7E1RT7TA==
- dependencies:
- which "^1.2.1"
-
-karma-coverage-istanbul-reporter@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-2.1.0.tgz#5f1bcc13c5e14ee1d91821ee8946861674f54c75"
- integrity sha512-UH0mXPJFJyK5uiK7EkwGtQ8f30lCBAfqRResnZ4pzLJ04SOp4SPlYkmwbbZ6iVJ6sQFVzlDUXlntBEsLRdgZpg==
- dependencies:
- istanbul-api "^2.1.6"
- minimatch "^3.0.4"
-
-karma-jasmine@^1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/karma-jasmine/-/karma-jasmine-1.1.2.tgz#394f2b25ffb4a644b9ada6f22d443e2fd08886c3"
- integrity sha1-OU8rJf+0pkS5rabyLUQ+L9CIhsM=
-
-karma-junit-reporter@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/karma-junit-reporter/-/karma-junit-reporter-1.2.0.tgz#4f9c40cedfb1a395f8aef876abf96189917c6396"
- integrity sha1-T5xAzt+xo5X4rvh2q/lhiZF8Y5Y=
- dependencies:
- path-is-absolute "^1.0.0"
- xmlbuilder "8.2.2"
-
-karma-mocha-reporter@^2.2.5:
- version "2.2.5"
- resolved "https://registry.yarnpkg.com/karma-mocha-reporter/-/karma-mocha-reporter-2.2.5.tgz#15120095e8ed819186e47a0b012f3cd741895560"
- integrity sha1-FRIAlejtgZGG5HoLAS8810GJVWA=
- dependencies:
- chalk "^2.1.0"
- log-symbols "^2.1.0"
- strip-ansi "^4.0.0"
-
-karma-sourcemap-loader@^0.3.7:
- version "0.3.7"
- resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.7.tgz#91322c77f8f13d46fed062b042e1009d4c4505d8"
- integrity sha1-kTIsd/jxPUb+0GKwQuEAnUxFBdg=
- dependencies:
- graceful-fs "^4.1.2"
-
-karma-webpack@^4.0.2:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-4.0.2.tgz#23219bd95bdda853e3073d3874d34447c77bced0"
- integrity sha512-970/okAsdUOmiMOCY8sb17A2I8neS25Ad9uhyK3GHgmRSIFJbDcNEFE8dqqUhNe9OHiCC9k3DMrSmtd/0ymP1A==
- dependencies:
- clone-deep "^4.0.1"
- loader-utils "^1.1.0"
- neo-async "^2.6.1"
- schema-utils "^1.0.0"
- source-map "^0.7.3"
- webpack-dev-middleware "^3.7.0"
-
-karma@^4.2.0:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/karma/-/karma-4.2.0.tgz#27e88b310cde090d016980ff5444e3a239196fca"
- integrity sha512-fmCuxN1rwJxTdZfOXK5LjlmS4Ana/OvzNMpkyLL/TLE8hmgSkpVpMYQ7RTVa8TNKRVQDZNl5W1oF5cfKfgIMlA==
- dependencies:
- bluebird "^3.3.0"
- body-parser "^1.16.1"
- braces "^3.0.2"
- chokidar "^3.0.0"
- colors "^1.1.0"
- connect "^3.6.0"
- core-js "^3.1.3"
- di "^0.0.1"
- dom-serialize "^2.2.0"
- flatted "^2.0.0"
- glob "^7.1.1"
- graceful-fs "^4.1.2"
- http-proxy "^1.13.0"
- isbinaryfile "^3.0.0"
- lodash "^4.17.11"
- log4js "^4.0.0"
- mime "^2.3.1"
- minimatch "^3.0.2"
- optimist "^0.6.1"
- qjobs "^1.1.4"
- range-parser "^1.2.0"
- rimraf "^2.6.0"
- safe-buffer "^5.0.1"
- socket.io "2.1.1"
- source-map "^0.6.1"
- tmp "0.0.33"
- useragent "2.3.0"
-
katex@^0.13.2:
version "0.13.2"
resolved "https://registry.yarnpkg.com/katex/-/katex-0.13.2.tgz#4075b9144e6af992ec9a4b772fa3754763be5f26"
@@ -7693,10 +7570,10 @@ keyv@^3.0.0:
dependencies:
json-buffer "3.0.0"
-khroma@^1.1.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/khroma/-/khroma-1.2.0.tgz#46dcc9d7533923c228b51724db108f11fec108d8"
- integrity sha512-DlKk5y243dujy8fOH02aRnnewLfiHJV0s8aXaVrCohgBf3s7fEAn6gc6LLQ21agODlFZS8ufrn+juu70uCA9Tw==
+khroma@^1.4.1:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/khroma/-/khroma-1.4.1.tgz#ad6a5b6a972befc5112ce5129887a1a83af2c003"
+ integrity sha512-+GmxKvmiRuCcUYDgR7g5Ngo0JEDeOsGdNONdU2zsiBQaK4z19Y2NvXqfEDE0ZiIrg45GTZyAnPLVsLZZACYm3Q==
killable@^1.0.1:
version "1.0.1"
@@ -7792,9 +7669,9 @@ lines-and-columns@^1.1.6:
integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=
linkify-it@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.1.0.tgz#c4caf38a6cd7ac2212ef3c7d2bde30a91561f9db"
- integrity sha512-4REs8/062kV2DSHxNfq5183zrqXMl7WP0WzABH9IeJI+NLm429FgE1PDecltYfnOoFDFlZGh2T8PfZn0r+GTRg==
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf"
+ integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==
dependencies:
uc.micro "^1.0.1"
@@ -7861,6 +7738,11 @@ locate-path@^5.0.0:
dependencies:
p-locate "^4.1.0"
+lodash._reinterpolate@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
+ integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=
+
lodash.assign@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7"
@@ -7981,6 +7863,21 @@ lodash.sortby@^4.7.0:
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
+lodash.template@^4.4.0:
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab"
+ integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==
+ dependencies:
+ lodash._reinterpolate "^3.0.0"
+ lodash.templatesettings "^4.0.0"
+
+lodash.templatesettings@^4.0.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33"
+ integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==
+ dependencies:
+ lodash._reinterpolate "^3.0.0"
+
lodash.truncate@^4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
@@ -8011,30 +7908,13 @@ lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
-log-symbols@^2.1.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a"
- integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==
- dependencies:
- chalk "^2.0.1"
-
-log-symbols@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.0.0.tgz#69b3cc46d20f448eccdb75ea1fa733d9e821c920"
- integrity sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==
- dependencies:
- chalk "^4.0.0"
-
-log4js@^4.0.0:
- version "4.5.1"
- resolved "https://registry.yarnpkg.com/log4js/-/log4js-4.5.1.tgz#e543625e97d9e6f3e6e7c9fc196dd6ab2cae30b5"
- integrity sha512-EEEgFcE9bLgaYUKuozyFfytQM2wDHtXn4tAN41pkaxpNjAykv11GVdeI4tHtmPWW4Xrgh9R/2d7XYghDVjbKKw==
+log-symbols@^4.0.0, log-symbols@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503"
+ integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==
dependencies:
- date-format "^2.0.0"
- debug "^4.1.1"
- flatted "^2.0.0"
- rfdc "^1.1.4"
- streamroller "^1.0.6"
+ chalk "^4.1.0"
+ is-unicode-supported "^0.1.0"
loglevel@^1.6.8:
version "1.7.1"
@@ -8053,11 +7933,6 @@ loose-envify@^1.0.0:
dependencies:
js-tokens "^3.0.0 || ^4.0.0"
-lower-case@^1.1.1:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac"
- integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw=
-
lowercase-keys@^1.0.0, lowercase-keys@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
@@ -8076,7 +7951,7 @@ lowlight@^1.17.0, lowlight@^1.20.0:
fault "^1.0.0"
highlight.js "~10.7.0"
-lru-cache@4.1.x, lru-cache@^4.1.2, lru-cache@^4.1.5:
+lru-cache@^4.1.2, lru-cache@^4.1.5:
version "4.1.5"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd"
integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==
@@ -8332,22 +8207,21 @@ merge2@^1.3.0:
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
-mermaid@^8.10.2:
- version "8.10.2"
- resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-8.10.2.tgz#e039df2e42faba08743f167fff85bdccff241f76"
- integrity sha512-Za5MrbAOMbEsyY4ONgGjfYz06sbwF1iNGRzp1sQqpOtvXxjxGu/J1jRJ8QyE9kD/D9zj1/KlRrYegWEvA7eZ5Q==
+mermaid@^8.11.5:
+ version "8.11.5"
+ resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-8.11.5.tgz#a2a284d705abf145e0d0f27e8b913d6e11bbb92c"
+ integrity sha512-lbIaDQlFoIQLxnLy8hZgfS6L7gt2Wxlk83fudLslUEhj4yafHyVjzGOlojJQxgsLU5khEANhxLbo0xebtOrhXQ==
dependencies:
"@braintree/sanitize-url" "^3.1.0"
+ "@percy/migrate" "^0.10.0"
d3 "^5.7.0"
- dagre "^0.8.4"
+ dagre "^0.8.5"
dagre-d3 "^0.6.4"
- entity-decode "^2.0.2"
- graphlib "^2.1.7"
- he "^1.2.0"
- khroma "^1.1.0"
- minify "^4.1.1"
- moment-mini "^2.22.1"
- stylis "^3.5.2"
+ dompurify "2.3.0"
+ graphlib "^2.1.8"
+ khroma "^1.4.1"
+ moment-mini "^2.24.0"
+ stylis "^4.0.10"
methods@~1.1.2:
version "1.1.2"
@@ -8441,19 +8315,6 @@ min-indent@^1.0.0:
resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869"
integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==
-minify@^4.1.1:
- version "4.1.2"
- resolved "https://registry.yarnpkg.com/minify/-/minify-4.1.2.tgz#88755f4faa5f7ab6d0c64fdd659aa34ea658f180"
- integrity sha512-YY6b6VzV7AY2MTMt1GjoFqKthGWvAr2L7MrzmFyiEsvPX+XAvidHcKqu36LlDT1V4I80ncbV5bsdTnIJq4/Sdw==
- dependencies:
- clean-css "^4.1.6"
- css-b64-images "~0.2.5"
- debug "^4.1.0"
- html-minifier "^4.0.0"
- terser "^4.0.0"
- try-catch "^2.0.0"
- try-to-catch "^1.0.2"
-
minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
@@ -8464,7 +8325,7 @@ minimalistic-crypto-utils@^1.0.1:
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
-minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.4:
+minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
@@ -8485,11 +8346,6 @@ minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5, minimist@~1.2.5:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
-minimist@~0.0.1:
- version "0.0.8"
- resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
- integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
-
minipass-collect@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617"
@@ -8599,10 +8455,10 @@ mock-apollo-client@^0.7.0:
resolved "https://registry.yarnpkg.com/mock-apollo-client/-/mock-apollo-client-0.7.0.tgz#5f70e75c842a9f3b3da2252f68fd47f2d9955f77"
integrity sha512-r0ICU01m007W0MwMej0lzlg1REtepDZ15Fyj8Hz9tiW/1TPb0PyHryGykrg9YhfbB8/+ZF2ovz+88yMF75TDoA==
-moment-mini@^2.22.1:
- version "2.22.1"
- resolved "https://registry.yarnpkg.com/moment-mini/-/moment-mini-2.22.1.tgz#bc32d73e43a4505070be6b53494b17623183420d"
- integrity sha512-OUCkHOz7ehtNMYuZjNciXUfwTuz8vmF1MTbAy59ebf+ZBYZO5/tZKuChVWCX+uDo+4idJBpGltNfV8st+HwsGw==
+moment-mini@^2.24.0:
+ version "2.24.0"
+ resolved "https://registry.yarnpkg.com/moment-mini/-/moment-mini-2.24.0.tgz#fa68d98f7fe93ae65bf1262f6abb5fb6983d8d18"
+ integrity sha512-9ARkWHBs+6YJIvrIp0Ik5tyTTtP9PoV0Ssu2Ocq5y9v8+NOOpWiRshAp8c4rZVWTOe+157on/5G+zj5pwIQFEQ==
monaco-editor-webpack-plugin@^4.0.0:
version "4.0.0"
@@ -8668,6 +8524,11 @@ multicast-dns@^6.0.1:
dns-packet "^1.0.1"
thunky "^0.1.0"
+mute-stream@0.0.8:
+ version "0.0.8"
+ resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
+ integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
+
nanoid@^3.1.23:
version "3.1.23"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81"
@@ -8700,7 +8561,7 @@ negotiator@0.6.2:
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==
-neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1:
+neo-async@^2.5.0, neo-async@^2.6.1:
version "2.6.1"
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c"
integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==
@@ -8710,12 +8571,12 @@ nice-try@^1.0.4:
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
-no-case@^2.2.0:
- version "2.3.2"
- resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac"
- integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==
+node-dir@^0.1.17:
+ version "0.1.17"
+ resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5"
+ integrity sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU=
dependencies:
- lower-case "^1.1.1"
+ minimatch "^3.0.2"
node-ensure@^0.0.0:
version "0.0.0"
@@ -8907,11 +8768,6 @@ object-assign@^4.0.1:
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
-object-component@0.0.3:
- version "0.0.3"
- resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291"
- integrity sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=
-
object-copy@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c"
@@ -9025,14 +8881,6 @@ optimism@^0.10.0:
dependencies:
"@wry/context" "^0.4.0"
-optimist@^0.6.1:
- version "0.6.1"
- resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686"
- integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY=
- dependencies:
- minimist "~0.0.1"
- wordwrap "~0.0.2"
-
optionator@^0.8.1:
version "0.8.3"
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495"
@@ -9057,6 +8905,21 @@ optionator@^0.9.1:
type-check "^0.4.0"
word-wrap "^1.2.3"
+ora@^5.3.0:
+ version "5.4.1"
+ resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18"
+ integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==
+ dependencies:
+ bl "^4.1.0"
+ chalk "^4.1.0"
+ cli-cursor "^3.1.0"
+ cli-spinners "^2.5.0"
+ is-interactive "^1.0.0"
+ is-unicode-supported "^0.1.0"
+ log-symbols "^4.1.0"
+ strip-ansi "^6.0.0"
+ wcwidth "^1.0.1"
+
orderedmap@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/orderedmap/-/orderedmap-1.1.1.tgz#c618e77611b3b21d0fe3edc92586265e0059c789"
@@ -9207,13 +9070,6 @@ parallel-transform@^1.1.0:
inherits "^2.0.3"
readable-stream "^2.1.5"
-param-case@^2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247"
- integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc=
- dependencies:
- no-case "^2.2.0"
-
parent-module@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
@@ -9290,20 +9146,6 @@ parse5@5.1.1:
resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178"
integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==
-parseqs@0.0.5:
- version "0.0.5"
- resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d"
- integrity sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=
- dependencies:
- better-assert "~1.0.0"
-
-parseuri@0.0.5:
- version "0.0.5"
- resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a"
- integrity sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=
- dependencies:
- better-assert "~1.0.0"
-
parseurl@~1.3.2, parseurl@~1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
@@ -9427,7 +9269,7 @@ pinkie@^2.0.0:
resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
-pirates@^4.0.1:
+pirates@^4.0.0, pirates@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87"
integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==
@@ -9742,10 +9584,10 @@ prosemirror-gapcursor@^1.1.5:
prosemirror-state "^1.0.0"
prosemirror-view "^1.0.0"
-prosemirror-history@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/prosemirror-history/-/prosemirror-history-1.1.3.tgz#4f76a1e71db4ef7cdf0e13dec6d8da2aeaecd489"
- integrity sha512-zGDotijea+vnfnyyUGyiy1wfOQhf0B/b6zYcCouBV8yo6JmrE9X23M5q7Nf/nATywEZbgRLG70R4DmfSTC+gfg==
+prosemirror-history@^1.1.3, prosemirror-history@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/prosemirror-history/-/prosemirror-history-1.2.0.tgz#04cc4df8d2f7b2a46651a2780de191ada6d465ea"
+ integrity sha512-B9v9xtf4fYbKxQwIr+3wtTDNLDZcmMMmGiI3TAPShnUzvo+Rmv1GiUrsQChY1meetHl7rhML2cppF3FTs7f7UQ==
dependencies:
prosemirror-state "^1.2.2"
prosemirror-transform "^1.0.0"
@@ -9767,18 +9609,18 @@ prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.2, prosemirror-keymap@^1.1.3,
prosemirror-state "^1.0.0"
w3c-keyname "^2.2.0"
-prosemirror-markdown@^1.5.1:
- version "1.5.1"
- resolved "https://registry.yarnpkg.com/prosemirror-markdown/-/prosemirror-markdown-1.5.1.tgz#877c7faea2225d3c52e988599bbe4457bcb3190f"
- integrity sha512-QvucPHx+gKOQW1SETKUysrful9VBjKqpCFmPotgLfVZ3BdQEGy/NEIFhaXXo3TcuW316MMnKfA90K7GE5I7z8A==
+prosemirror-markdown@^1.5.2:
+ version "1.5.2"
+ resolved "https://registry.yarnpkg.com/prosemirror-markdown/-/prosemirror-markdown-1.5.2.tgz#f188ad14caa8c2f499b4d3eb6082e19f1d9d366e"
+ integrity sha512-e9rVnRULVACEjCvIBOj5P2dGTE/nz8kKspA/GWZXVgtQgqeJEvQ+tUNeZkeRZJ2/I3XPzuWjeoWnwJmkMnIKrg==
dependencies:
markdown-it "^10.0.0"
prosemirror-model "^1.0.0"
-prosemirror-model@^1.0.0, prosemirror-model@^1.1.0, prosemirror-model@^1.13.1, prosemirror-model@^1.13.3, prosemirror-model@^1.14.2, prosemirror-model@^1.2.0, prosemirror-model@^1.8.1:
- version "1.14.2"
- resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.14.2.tgz#4e8c39cfff4e097631af4495e125d9a8a9773116"
- integrity sha512-TwkACyEiSi8FJiRhg2ffbzmQRy5DR+aTwAr7trNQNZL24HJR8ouxy4qCkG99PnWK0xZ0AjSMtPXSU6hnxAiP7Q==
+prosemirror-model@^1.0.0, prosemirror-model@^1.13.1, prosemirror-model@^1.14.3, prosemirror-model@^1.2.0, prosemirror-model@^1.8.1:
+ version "1.14.3"
+ resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.14.3.tgz#a9c250d3c4023ddf10ecb41a0a7a130e9741d37e"
+ integrity sha512-yzZlBaSxfUPIIP6U5Edh5zKxJPZ5f7bwZRhiCuH3UYkWhj+P3d8swHsbuAMOu/iDatDc5J/Qs5Mb3++mZf+CvQ==
dependencies:
orderedmap "^1.1.0"
@@ -9828,12 +9670,12 @@ prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transfor
dependencies:
prosemirror-model "^1.0.0"
-prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.16.5, prosemirror-view@^1.18.8:
- version "1.18.9"
- resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.18.9.tgz#29bc11759438aecc5b7fadaa8520165c84c2144a"
- integrity sha512-AkknqYyt7QBJIfA993O5NNOXLyQji5vr0SnOk/eig18dr7hbe1CK9FKd4Cnh9/f0JSHhZwadHlc3w+wZkIdmIQ==
+prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.16.5, prosemirror-view@^1.20.0:
+ version "1.20.0"
+ resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.20.0.tgz#64198845f0d112c14a5594732c46a96ac3d9d828"
+ integrity sha512-OqU/bHUIiJhpyb2ytX4fLalYAJJOyZ0k5H0AibP/WPsdHq9CqmJFU676gO+N8WWhR5tVz1NxsqMZgEBy5Lc6GQ==
dependencies:
- prosemirror-model "^1.1.0"
+ prosemirror-model "^1.14.3"
prosemirror-state "^1.0.0"
prosemirror-transform "^1.1.0"
@@ -9941,11 +9783,6 @@ purgecss@^4.0.3:
postcss "^8.2.1"
postcss-selector-parser "^6.0.2"
-qjobs@^1.1.4:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071"
- integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==
-
qs@6.7.0:
version "6.7.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
@@ -9991,7 +9828,7 @@ randomfill@^1.0.3:
randombytes "^2.0.5"
safe-buffer "^5.1.0"
-range-parser@^1.2.0, range-parser@^1.2.1, range-parser@~1.2.1:
+range-parser@^1.2.1, range-parser@~1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
@@ -10085,7 +9922,7 @@ read-pkg@^5.2.0:
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
-readable-stream@^3.0.6, readable-stream@^3.1.1:
+readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
@@ -10121,6 +9958,16 @@ readdirp@~3.4.0:
dependencies:
picomatch "^2.2.1"
+recast@^0.20.3:
+ version "0.20.5"
+ resolved "https://registry.yarnpkg.com/recast/-/recast-0.20.5.tgz#8e2c6c96827a1b339c634dd232957d230553ceae"
+ integrity sha512-E5qICoPoNL4yU0H0NoBDntNB0Q5oMSNh9usFctYniLBluTthi3RsQVBXIJNbApOlvSwW/RGxIuokPcAc59J5fQ==
+ dependencies:
+ ast-types "0.14.2"
+ esprima "~4.0.0"
+ source-map "~0.6.1"
+ tslib "^2.0.1"
+
redent@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f"
@@ -10205,11 +10052,6 @@ regjsparser@^0.6.4:
dependencies:
jsesc "~0.5.0"
-relateurl@^0.2.7:
- version "0.2.7"
- resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
- integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=
-
remark-parse@^9.0.0:
version "9.0.0"
resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-9.0.0.tgz#4d20a299665880e4f4af5d90b7c7b8a935853640"
@@ -10388,6 +10230,14 @@ responselike@^1.0.2:
dependencies:
lowercase-keys "^1.0.0"
+restore-cursor@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e"
+ integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==
+ dependencies:
+ onetime "^5.1.0"
+ signal-exit "^3.0.2"
+
ret@~0.1.10:
version "0.1.15"
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
@@ -10403,12 +10253,7 @@ reusify@^1.0.4:
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
-rfdc@^1.1.4:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.1.4.tgz#ba72cc1367a0ccd9cf81a870b3b58bd3ad07f8c2"
- integrity sha512-5C9HXdzK8EAqN7JDif30jqsBzavB7wLpaubisuQIGHWf2gUXSpzy6ArX/+Da8RjFpagWsCn+pIgxTMAmKw9Zug==
-
-rimraf@^2.5.4, rimraf@^2.6.0, rimraf@^2.6.3:
+rimraf@^2.5.4, rimraf@^2.6.3, rimraf@~2.6.2:
version "2.6.3"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==
@@ -10445,6 +10290,11 @@ rsvp@^4.8.4:
resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.4.tgz#b50e6b34583f3dd89329a2f23a8a2be072845911"
integrity sha512-6FomvYPfs+Jy9TfXmBpBuMWNH94SgCsZmJKcanySzgNNP6LjWxBvyLTa9KaMfDDM5oxRfrKDB0r/qeRsLwnBfA==
+run-async@^2.4.0:
+ version "2.4.1"
+ resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455"
+ integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==
+
run-parallel@^1.1.9:
version "1.1.10"
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.10.tgz#60a51b2ae836636c81377df16cb107351bcd13ef"
@@ -10462,6 +10312,20 @@ rw@1:
resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4"
integrity sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=
+rxjs@^6.6.7:
+ version "6.6.7"
+ resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9"
+ integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==
+ dependencies:
+ tslib "^1.9.0"
+
+rxjs@^7.2.0:
+ version "7.3.0"
+ resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.3.0.tgz#39fe4f3461dc1e50be1475b2b85a0a88c1e938c6"
+ integrity sha512-p2yuGIg9S1epc3vrjKf6iVb3RCaAYjYskkO+jHIaV0IjOPlJop4UnodOoFb2xeNwlguqLYvGw1b1McillYb5Gw==
+ dependencies:
+ tslib "~2.1.0"
+
safe-buffer@5.1.2, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
@@ -10582,7 +10446,7 @@ semver-diff@^3.1.1:
dependencies:
semver "^6.3.0"
-"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1:
+"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0, semver@^5.7.1:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
@@ -10597,10 +10461,10 @@ semver@^6.0.0, semver@^6.2.0, semver@^6.3.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
-semver@^7.2.1, semver@^7.3.2:
- version "7.3.4"
- resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97"
- integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==
+semver@^7.2.1, semver@^7.3.2, semver@^7.3.4:
+ version "7.3.5"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
+ integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
dependencies:
lru-cache "^6.0.0"
@@ -10823,52 +10687,6 @@ snapdragon@^0.8.1:
source-map-resolve "^0.5.0"
use "^3.1.0"
-socket.io-adapter@~1.1.0:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz#2a805e8a14d6372124dd9159ad4502f8cb07f06b"
- integrity sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=
-
-socket.io-client@2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.1.1.tgz#dcb38103436ab4578ddb026638ae2f21b623671f"
- integrity sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==
- dependencies:
- backo2 "1.0.2"
- base64-arraybuffer "0.1.5"
- component-bind "1.0.0"
- component-emitter "1.2.1"
- debug "~3.1.0"
- engine.io-client "~3.2.0"
- has-binary2 "~1.0.2"
- has-cors "1.1.0"
- indexof "0.0.1"
- object-component "0.0.3"
- parseqs "0.0.5"
- parseuri "0.0.5"
- socket.io-parser "~3.2.0"
- to-array "0.1.4"
-
-socket.io-parser@~3.2.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.2.0.tgz#e7c6228b6aa1f814e6148aea325b51aa9499e077"
- integrity sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==
- dependencies:
- component-emitter "1.2.1"
- debug "~3.1.0"
- isarray "2.0.1"
-
-socket.io@2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.1.1.tgz#a069c5feabee3e6b214a75b40ce0652e1cfb9980"
- integrity sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==
- dependencies:
- debug "~3.1.0"
- engine.io "~3.2.0"
- has-binary2 "~1.0.2"
- socket.io-adapter "~1.1.0"
- socket.io-client "2.1.1"
- socket.io-parser "~3.2.0"
-
sockjs-client@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.5.0.tgz#2f8ff5d4b659e0d092f7aba0b7c386bd2aa20add"
@@ -10911,7 +10729,7 @@ source-map-resolve@^0.5.0, source-map-resolve@^0.5.2:
source-map-url "^0.4.0"
urix "^0.1.0"
-source-map-support@^0.5.6, source-map-support@~0.5.12:
+source-map-support@^0.5.16, source-map-support@^0.5.6, source-map-support@~0.5.12:
version "0.5.19"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
@@ -10929,7 +10747,7 @@ source-map@0.5.6, source-map@^0.5.0, source-map@^0.5.6:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
integrity sha1-dc449SvwczxafwwRjYEzSiu19BI=
-source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
+source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
@@ -11059,11 +10877,6 @@ static-extend@^0.1.1:
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
-statuses@~1.3.1:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e"
- integrity sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=
-
stealthy-require@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b"
@@ -11101,17 +10914,6 @@ stream-shift@^1.0.0:
resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952"
integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=
-streamroller@^1.0.6:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-1.0.6.tgz#8167d8496ed9f19f05ee4b158d9611321b8cacd9"
- integrity sha512-3QC47Mhv3/aZNFpDDVO44qQb9gwB9QggMEE0sQmkTAwBVYdBRWISdsywlkfm5II1Q5y/pmrHflti/IgmIzdDBg==
- dependencies:
- async "^2.6.2"
- date-format "^2.0.0"
- debug "^3.2.6"
- fs-extra "^7.0.1"
- lodash "^4.17.14"
-
string-hash@1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b"
@@ -11125,6 +10927,14 @@ string-length@^4.0.1:
char-regex "^1.0.2"
strip-ansi "^6.0.0"
+string-width@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
+ integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
+ dependencies:
+ is-fullwidth-code-point "^2.0.0"
+ strip-ansi "^4.0.0"
+
string-width@^3.0.0, string-width@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"
@@ -11322,10 +11132,10 @@ stylelint@13.9.0:
v8-compile-cache "^2.2.0"
write-file-atomic "^3.0.3"
-stylis@^3.5.2:
- version "3.5.4"
- resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe"
- integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==
+stylis@^4.0.10:
+ version "4.0.10"
+ resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.10.tgz#446512d1097197ab3f02fb3c258358c3f7a14240"
+ integrity sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg==
sugarss@^2.0.0:
version "2.0.0"
@@ -11422,6 +11232,13 @@ tar@^6.0.2:
mkdirp "^1.0.3"
yallist "^4.0.0"
+temp@^0.8.1:
+ version "0.8.4"
+ resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.4.tgz#8c97a33a4770072e0a05f919396c7665a7dd59f2"
+ integrity sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==
+ dependencies:
+ rimraf "~2.6.2"
+
term-size@^2.1.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.0.tgz#1f16adedfe9bdc18800e1776821734086fcc6753"
@@ -11450,7 +11267,7 @@ terser-webpack-plugin@^1.4.3:
webpack-sources "^1.4.0"
worker-farm "^1.7.0"
-terser@^4.0.0, terser@^4.1.2:
+terser@^4.1.2:
version "4.3.1"
resolved "https://registry.yarnpkg.com/terser/-/terser-4.3.1.tgz#09820bcb3398299c4b48d9a86aefc65127d0ed65"
integrity sha512-pnzH6dnFEsR2aa2SJaKb1uSCl3QmIsJ8dEkj0Fky+2AwMMcC9doMqLOQIH6wVTEKaVfKVvLSk5qxPBEZT9mywg==
@@ -11511,6 +11328,11 @@ through2@^2.0.0:
readable-stream "~2.3.6"
xtend "~4.0.1"
+through@^2.3.6:
+ version "2.3.8"
+ resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
+ integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
+
thunky@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/thunky/-/thunky-0.1.0.tgz#bf30146824e2b6e67b0f2d7a4ac8beb26908684e"
@@ -11558,7 +11380,7 @@ tiptap-commands@^1.17.1:
prosemirror-tables "^1.1.1"
tiptap-utils "^1.13.1"
-tiptap-extensions@^1.35.1:
+tiptap-extensions@^1.35.2:
version "1.35.2"
resolved "https://registry.yarnpkg.com/tiptap-extensions/-/tiptap-extensions-1.35.2.tgz#83dd6ee703ae8c83b58c7608f97253fcc4f1a94c"
integrity sha512-TIMbHVJe0/3aVeTeCmqGbatDkfxduPYFOffNCmuKR+h6oQNzTu6rLVhRzoNqktfxIoi/b44SiDPorTjSN72dCw==
@@ -11584,7 +11406,7 @@ tiptap-utils@^1.13.1:
prosemirror-state "^1.3.3"
prosemirror-tables "^1.1.1"
-tiptap@^1.32.1, tiptap@^1.32.2:
+tiptap@^1.32.2:
version "1.32.2"
resolved "https://registry.yarnpkg.com/tiptap/-/tiptap-1.32.2.tgz#cd6259e853652bfc6860758ff44ebb695d5edd1c"
integrity sha512-5IwVj8nGo8y5V3jbdtoEd7xNUsi8Q0N6WV2Nfs70olqz3fldXkiImBrDhZJ4Anx8vhyP6PIBttrg0prFVmwIvw==
@@ -11600,7 +11422,7 @@ tiptap@^1.32.1, tiptap@^1.32.2:
tiptap-commands "^1.17.1"
tiptap-utils "^1.13.1"
-tmp@0.0.33, tmp@0.0.x:
+tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==
@@ -11612,11 +11434,6 @@ tmpl@1.0.x:
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"
integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=
-to-array@0.1.4:
- version "0.1.4"
- resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890"
- integrity sha1-F+bBH3PdTz10zaek/zI46a2b+JA=
-
to-arraybuffer@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
@@ -11720,16 +11537,6 @@ trough@^1.0.0:
resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406"
integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==
-try-catch@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/try-catch/-/try-catch-2.0.0.tgz#a491141d597f8b72b46757fe1c47059341a16aed"
- integrity sha512-RPXpVjsbtWgymwGq5F/OWDFsjEzdvzwHFaMjWWW6f/p6+uk/N7YSKJHQfIfGqITfj8qH4cBqCLMnhKZBaKk7Kg==
-
-try-to-catch@^1.0.2:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/try-to-catch/-/try-to-catch-1.1.1.tgz#770162dd13b9a0e55da04db5b7f888956072038a"
- integrity sha512-ikUlS+/BcImLhNYyIgZcEmq4byc31QpC+46/6Jm5ECWkVFhf8SM2Fp/0pMVXPX6vk45SMCwrP4Taxucne8I0VA==
-
ts-invariant@^0.4.0:
version "0.4.4"
resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.4.4.tgz#97a523518688f93aafad01b0e80eb803eb2abd86"
@@ -11752,10 +11559,15 @@ tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043"
integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==
-tslib@^2.2.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c"
- integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==
+tslib@^2.0.0, tslib@^2.0.1, tslib@^2.2.0:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
+ integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
+
+tslib@~2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a"
+ integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==
tsutils@^3.17.1:
version "3.17.1"
@@ -11846,22 +11658,9 @@ typedarray@^0.0.6:
integrity sha512-6OSu9PTIzmn9TCDiovULTnET6BgXtDYL4Gg4szY+cGsc3JP1dQL8qvE8kShTRx1NIw4Q9IBHlwODjkjWEtMUyA==
uc.micro@^1.0.1, uc.micro@^1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.5.tgz#0c65f15f815aa08b560a61ce8b4db7ffc3f45376"
- integrity sha512-JoLI4g5zv5qNyT09f4YAvEZIIV1oOjqnewYg5D38dkQljIzpPT296dbIGvKro3digYI1bkb7W6EP1y4uDlmzLg==
-
-uglify-js@^3.1.4, uglify-js@^3.5.1:
- version "3.6.0"
- resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.0.tgz#704681345c53a8b2079fb6cec294b05ead242ff5"
- integrity sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==
- dependencies:
- commander "~2.20.0"
- source-map "~0.6.1"
-
-ultron@~1.1.0:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c"
- integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac"
+ integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==
undefsafe@^2.0.2:
version "2.0.2"
@@ -12014,11 +11813,6 @@ update-notifier@^4.0.0:
semver-diff "^3.1.1"
xdg-basedir "^4.0.0"
-upper-case@^1.1.1:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598"
- integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=
-
uri-js@^4.2.2:
version "4.4.0"
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.0.tgz#aa714261de793e8a82347a7bcc9ce74e86f28602"
@@ -12081,14 +11875,6 @@ use@^3.1.0:
resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==
-useragent@2.3.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.3.0.tgz#217f943ad540cb2128658ab23fc960f6a88c9972"
- integrity sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==
- dependencies:
- lru-cache "4.1.x"
- tmp "0.0.x"
-
util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
@@ -12197,11 +11983,6 @@ vm-browserify@^1.0.1:
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.0.tgz#bd76d6a23323e2ca8ffa12028dc04559c75f9019"
integrity sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==
-void-elements@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
- integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=
-
vscode-json-languageservice@^3.6.0:
version "3.9.1"
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.9.1.tgz#f72b581f8cd2bd9b47445ccf8b0ddcde6aba7483"
@@ -12443,6 +12224,13 @@ wbuf@^1.1.0, wbuf@^1.7.3:
dependencies:
minimalistic-assert "^1.0.0"
+wcwidth@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8"
+ integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=
+ dependencies:
+ defaults "^1.0.3"
+
web-vitals@^0.2.4:
version "0.2.4"
resolved "https://registry.yarnpkg.com/web-vitals/-/web-vitals-0.2.4.tgz#ec3df43c834a207fd7cdefd732b2987896e08511"
@@ -12490,7 +12278,7 @@ webpack-cli@^3.3.12:
v8-compile-cache "^2.1.1"
yargs "^13.3.2"
-webpack-dev-middleware@^3.7.0, webpack-dev-middleware@^3.7.2:
+webpack-dev-middleware@^3.7.2:
version "3.7.2"
resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz#0019c3db716e3fa5cecbf64f2ab88a74bab331f3"
integrity sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==
@@ -12630,7 +12418,7 @@ which-module@^2.0.0:
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
-which@^1.2.1, which@^1.2.14, which@^1.2.9, which@^1.3.1:
+which@^1.2.14, which@^1.2.9, which@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
@@ -12656,11 +12444,6 @@ word-wrap@^1.2.3, word-wrap@~1.2.3:
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
-wordwrap@~0.0.2:
- version "0.0.3"
- resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
- integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc=
-
worker-farm@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8"
@@ -12676,6 +12459,15 @@ worker-loader@^2.0.0:
loader-utils "^1.0.0"
schema-utils "^0.4.0"
+wrap-ansi@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-4.0.0.tgz#b3570d7c70156159a2d42be5cc942e957f7b1131"
+ integrity sha512-uMTsj9rDb0/7kk1PbcbCcwvHUxp60fGDB/NNXpVa0Q+ic/e7y5+BwTxKfQ33VYgDppSwi/FBzpetYzo8s6tfbg==
+ dependencies:
+ ansi-styles "^3.2.0"
+ string-width "^2.1.1"
+ strip-ansi "^4.0.0"
+
wrap-ansi@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09"
@@ -12694,11 +12486,29 @@ wrap-ansi@^6.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"
+wrap-ansi@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
+ integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
+ dependencies:
+ ansi-styles "^4.0.0"
+ string-width "^4.1.0"
+ strip-ansi "^6.0.0"
+
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
+write-file-atomic@^2.3.0:
+ version "2.4.3"
+ resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481"
+ integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==
+ dependencies:
+ graceful-fs "^4.1.11"
+ imurmurhash "^0.1.4"
+ signal-exit "^3.0.2"
+
write-file-atomic@^3.0.0, write-file-atomic@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8"
@@ -12721,15 +12531,6 @@ ws@^7.2.3, ws@^7.3.1:
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.4.tgz#383bc9742cb202292c9077ceab6f6047b17f2d59"
integrity sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==
-ws@~3.3.1:
- version "3.3.3"
- resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2"
- integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==
- dependencies:
- async-limiter "~1.0.0"
- safe-buffer "~5.1.0"
- ultron "~1.1.0"
-
xdg-basedir@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13"
@@ -12761,11 +12562,6 @@ xml@^1.0.1:
resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5"
integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=
-xmlbuilder@8.2.2:
- version "8.2.2"
- resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-8.2.2.tgz#69248673410b4ba42e1a6136551d2922335aa773"
- integrity sha1-aSSGc0ELS6QuGmE2VR0pIjNap3M=
-
xmlbuilder@~9.0.1:
version "9.0.7"
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"
@@ -12781,11 +12577,6 @@ xmlcreate@^1.0.1:
resolved "https://registry.yarnpkg.com/xmlcreate/-/xmlcreate-1.0.2.tgz#fa6bf762a60a413fb3dd8f4b03c5b269238d308f"
integrity sha1-+mv3YqYKQT+z3Y9LA8WyaSONMI8=
-xmlhttprequest-ssl@~1.5.4:
- version "1.5.5"
- resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e"
- integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=
-
xtend@^4.0.0, xtend@~4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
@@ -12913,11 +12704,6 @@ yarn-deduplicate@^3.1.0:
commander "^6.1.0"
semver "^7.3.2"
-yeast@0.1.2:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"
- integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk=
-
yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"